From 00b9de9c249f51f09c19aa41cbbb3e3eb4eea807 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 24 Jun 2009 17:53:33 +0900 Subject: serial: sh-sci: Move SCSCR_INIT in to platform data. This moves all of the SCSCR_INIT definitions in to the platform data, for future consolidation. Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/sh2/setup-sh7619.c | 3 +++ arch/sh/kernel/cpu/sh2a/setup-mxg.c | 1 + arch/sh/kernel/cpu/sh2a/setup-sh7201.c | 8 ++++++ arch/sh/kernel/cpu/sh2a/setup-sh7203.c | 4 +++ arch/sh/kernel/cpu/sh2a/setup-sh7206.c | 4 +++ arch/sh/kernel/cpu/sh3/setup-sh7705.c | 3 +++ arch/sh/kernel/cpu/sh3/setup-sh770x.c | 3 +++ arch/sh/kernel/cpu/sh3/setup-sh7710.c | 4 +++ arch/sh/kernel/cpu/sh3/setup-sh7720.c | 5 ++-- arch/sh/kernel/cpu/sh4/setup-sh4-202.c | 1 + arch/sh/kernel/cpu/sh4/setup-sh7750.c | 48 +++++++++++++++++++++------------- arch/sh/kernel/cpu/sh4/setup-sh7760.c | 4 +++ arch/sh/kernel/cpu/sh4a/setup-sh7343.c | 4 +++ arch/sh/kernel/cpu/sh4a/setup-sh7366.c | 1 + arch/sh/kernel/cpu/sh4a/setup-sh7722.c | 12 ++++----- arch/sh/kernel/cpu/sh4a/setup-sh7723.c | 6 +++++ arch/sh/kernel/cpu/sh4a/setup-sh7724.c | 6 +++++ arch/sh/kernel/cpu/sh4a/setup-sh7763.c | 3 +++ arch/sh/kernel/cpu/sh4a/setup-sh7770.c | 10 +++++++ arch/sh/kernel/cpu/sh4a/setup-sh7780.c | 2 ++ arch/sh/kernel/cpu/sh4a/setup-sh7785.c | 6 +++++ arch/sh/kernel/cpu/sh4a/setup-sh7786.c | 6 +++++ arch/sh/kernel/cpu/sh4a/setup-shx3.c | 4 +++ arch/sh/kernel/cpu/sh5/setup-sh5.c | 1 + drivers/serial/sh-sci.c | 7 ++++- drivers/serial/sh-sci.h | 32 ----------------------- include/linux/serial_sci.h | 11 ++++++++ 27 files changed, 140 insertions(+), 59 deletions(-) diff --git a/arch/sh/kernel/cpu/sh2/setup-sh7619.c b/arch/sh/kernel/cpu/sh2/setup-sh7619.c index 13798733f2db..ace016b17036 100644 --- a/arch/sh/kernel/cpu/sh2/setup-sh7619.c +++ b/arch/sh/kernel/cpu/sh2/setup-sh7619.c @@ -63,16 +63,19 @@ static struct plat_sci_port sci_platform_data[] = { { .mapbase = 0xf8400000, .flags = UPF_BOOT_AUTOCONF, + .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, .type = PORT_SCIF, .irqs = { 88, 88, 88, 88 }, }, { .mapbase = 0xf8410000, .flags = UPF_BOOT_AUTOCONF, + .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, .type = PORT_SCIF, .irqs = { 92, 92, 92, 92 }, }, { .mapbase = 0xf8420000, .flags = UPF_BOOT_AUTOCONF, + .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, .type = PORT_SCIF, .irqs = { 96, 96, 96, 96 }, }, { diff --git a/arch/sh/kernel/cpu/sh2a/setup-mxg.c b/arch/sh/kernel/cpu/sh2a/setup-mxg.c index 869c2da4820b..7ec658ce14f8 100644 --- a/arch/sh/kernel/cpu/sh2a/setup-mxg.c +++ b/arch/sh/kernel/cpu/sh2a/setup-mxg.c @@ -211,6 +211,7 @@ static struct plat_sci_port sci_platform_data[] = { { .mapbase = 0xff804000, .flags = UPF_BOOT_AUTOCONF, + .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, .type = PORT_SCIF, .irqs = { 220, 220, 220, 220 }, }, { diff --git a/arch/sh/kernel/cpu/sh2a/setup-sh7201.c b/arch/sh/kernel/cpu/sh2a/setup-sh7201.c index d8febe128066..2a2ac222f9c7 100644 --- a/arch/sh/kernel/cpu/sh2a/setup-sh7201.c +++ b/arch/sh/kernel/cpu/sh2a/setup-sh7201.c @@ -181,41 +181,49 @@ static struct plat_sci_port sci_platform_data[] = { { .mapbase = 0xfffe8000, .flags = UPF_BOOT_AUTOCONF, + .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, .type = PORT_SCIF, .irqs = { 180, 180, 180, 180 } }, { .mapbase = 0xfffe8800, .flags = UPF_BOOT_AUTOCONF, + .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, .type = PORT_SCIF, .irqs = { 184, 184, 184, 184 } }, { .mapbase = 0xfffe9000, .flags = UPF_BOOT_AUTOCONF, + .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, .type = PORT_SCIF, .irqs = { 188, 188, 188, 188 } }, { .mapbase = 0xfffe9800, .flags = UPF_BOOT_AUTOCONF, + .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, .type = PORT_SCIF, .irqs = { 192, 192, 192, 192 } }, { .mapbase = 0xfffea000, .flags = UPF_BOOT_AUTOCONF, + .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, .type = PORT_SCIF, .irqs = { 196, 196, 196, 196 } }, { .mapbase = 0xfffea800, .flags = UPF_BOOT_AUTOCONF, + .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, .type = PORT_SCIF, .irqs = { 200, 200, 200, 200 } }, { .mapbase = 0xfffeb000, .flags = UPF_BOOT_AUTOCONF, + .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, .type = PORT_SCIF, .irqs = { 204, 204, 204, 204 } }, { .mapbase = 0xfffeb800, .flags = UPF_BOOT_AUTOCONF, + .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, .type = PORT_SCIF, .irqs = { 208, 208, 208, 208 } }, { diff --git a/arch/sh/kernel/cpu/sh2a/setup-sh7203.c b/arch/sh/kernel/cpu/sh2a/setup-sh7203.c index 62e3039d2398..2c9f3ababfd7 100644 --- a/arch/sh/kernel/cpu/sh2a/setup-sh7203.c +++ b/arch/sh/kernel/cpu/sh2a/setup-sh7203.c @@ -177,21 +177,25 @@ static struct plat_sci_port sci_platform_data[] = { { .mapbase = 0xfffe8000, .flags = UPF_BOOT_AUTOCONF, + .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, .type = PORT_SCIF, .irqs = { 192, 192, 192, 192 }, }, { .mapbase = 0xfffe8800, .flags = UPF_BOOT_AUTOCONF, + .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, .type = PORT_SCIF, .irqs = { 196, 196, 196, 196 }, }, { .mapbase = 0xfffe9000, .flags = UPF_BOOT_AUTOCONF, + .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, .type = PORT_SCIF, .irqs = { 200, 200, 200, 200 }, }, { .mapbase = 0xfffe9800, .flags = UPF_BOOT_AUTOCONF, + .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, .type = PORT_SCIF, .irqs = { 204, 204, 204, 204 }, }, { diff --git a/arch/sh/kernel/cpu/sh2a/setup-sh7206.c b/arch/sh/kernel/cpu/sh2a/setup-sh7206.c index 3e6f3d7a58be..5a47987f3902 100644 --- a/arch/sh/kernel/cpu/sh2a/setup-sh7206.c +++ b/arch/sh/kernel/cpu/sh2a/setup-sh7206.c @@ -137,21 +137,25 @@ static struct plat_sci_port sci_platform_data[] = { { .mapbase = 0xfffe8000, .flags = UPF_BOOT_AUTOCONF, + .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, .type = PORT_SCIF, .irqs = { 240, 240, 240, 240 }, }, { .mapbase = 0xfffe8800, .flags = UPF_BOOT_AUTOCONF, + .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, .type = PORT_SCIF, .irqs = { 244, 244, 244, 244 }, }, { .mapbase = 0xfffe9000, .flags = UPF_BOOT_AUTOCONF, + .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, .type = PORT_SCIF, .irqs = { 248, 248, 248, 248 }, }, { .mapbase = 0xfffe9800, .flags = UPF_BOOT_AUTOCONF, + .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, .type = PORT_SCIF, .irqs = { 252, 252, 252, 252 }, }, { diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7705.c b/arch/sh/kernel/cpu/sh3/setup-sh7705.c index 88f742fed9ed..28de53b281f3 100644 --- a/arch/sh/kernel/cpu/sh3/setup-sh7705.c +++ b/arch/sh/kernel/cpu/sh3/setup-sh7705.c @@ -71,11 +71,14 @@ static struct plat_sci_port sci_platform_data[] = { { .mapbase = 0xa4410000, .flags = UPF_BOOT_AUTOCONF, + .scscr = SCSCR_TIE | SCSCR_RIE | SCSCR_TE | + SCSCR_RE | SCSCR_CKE1 | SCSCR_CKE0, .type = PORT_SCIF, .irqs = { 56, 56, 56 }, }, { .mapbase = 0xa4400000, .flags = UPF_BOOT_AUTOCONF, + .scscr = SCSCR_TIE | SCSCR_RIE | SCSCR_TE | SCSCR_RE, .type = PORT_SCIF, .irqs = { 52, 52, 52 }, }, { diff --git a/arch/sh/kernel/cpu/sh3/setup-sh770x.c b/arch/sh/kernel/cpu/sh3/setup-sh770x.c index c56306798584..50ac42836dc7 100644 --- a/arch/sh/kernel/cpu/sh3/setup-sh770x.c +++ b/arch/sh/kernel/cpu/sh3/setup-sh770x.c @@ -110,6 +110,7 @@ static struct plat_sci_port sci_platform_data[] = { { .mapbase = 0xfffffe80, .flags = UPF_BOOT_AUTOCONF, + .scscr = SCSCR_TE | SCSCR_RE, .type = PORT_SCI, .irqs = { 23, 23, 23, 0 }, }, @@ -119,6 +120,7 @@ static struct plat_sci_port sci_platform_data[] = { { .mapbase = 0xa4000150, .flags = UPF_BOOT_AUTOCONF, + .scscr = SCSCR_TE | SCSCR_RE, .type = PORT_SCIF, .irqs = { 56, 56, 56, 56 }, }, @@ -128,6 +130,7 @@ static struct plat_sci_port sci_platform_data[] = { { .mapbase = 0xa4000140, .flags = UPF_BOOT_AUTOCONF, + .scscr = SCSCR_TE | SCSCR_RE, .type = PORT_IRDA, .irqs = { 52, 52, 52, 52 }, }, diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7710.c b/arch/sh/kernel/cpu/sh3/setup-sh7710.c index efa76c8148f4..007627ecb7c8 100644 --- a/arch/sh/kernel/cpu/sh3/setup-sh7710.c +++ b/arch/sh/kernel/cpu/sh3/setup-sh7710.c @@ -100,11 +100,15 @@ static struct plat_sci_port sci_platform_data[] = { { .mapbase = 0xa4400000, .flags = UPF_BOOT_AUTOCONF, + .scscr = SCSCR_TE | SCSCR_RE | SCSCR_REIE | + SCSCR_CKE1 | SCSCR_CKE0, .type = PORT_SCIF, .irqs = { 52, 52, 52, 52 }, }, { .mapbase = 0xa4410000, .flags = UPF_BOOT_AUTOCONF, + .scscr = SCSCR_TE | SCSCR_RE | SCSCR_REIE | + SCSCR_CKE1 | SCSCR_CKE0, .type = PORT_SCIF, .irqs = { 56, 56, 56, 56 }, }, { diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7720.c b/arch/sh/kernel/cpu/sh3/setup-sh7720.c index 5b2107798edb..1fc3d9089199 100644 --- a/arch/sh/kernel/cpu/sh3/setup-sh7720.c +++ b/arch/sh/kernel/cpu/sh3/setup-sh7720.c @@ -1,5 +1,5 @@ /* - * SH7720 Setup + * Setup code for SH7720, SH7721. * * Copyright (C) 2007 Markus Brunner, Mark Jonas * Copyright (C) 2009 Paul Mundt @@ -52,15 +52,16 @@ static struct plat_sci_port sci_platform_data[] = { { .mapbase = 0xa4430000, .flags = UPF_BOOT_AUTOCONF, + .scscr = SCSCR_RE | SCSCR_TE, .type = PORT_SCIF, .irqs = { 80, 80, 80, 80 }, }, { .mapbase = 0xa4438000, .flags = UPF_BOOT_AUTOCONF, + .scscr = SCSCR_RE | SCSCR_TE, .type = PORT_SCIF, .irqs = { 81, 81, 81, 81 }, }, { - .flags = 0, } }; diff --git a/arch/sh/kernel/cpu/sh4/setup-sh4-202.c b/arch/sh/kernel/cpu/sh4/setup-sh4-202.c index 6d088d123591..9aa6fa3ca4e6 100644 --- a/arch/sh/kernel/cpu/sh4/setup-sh4-202.c +++ b/arch/sh/kernel/cpu/sh4/setup-sh4-202.c @@ -19,6 +19,7 @@ static struct plat_sci_port sci_platform_data[] = { { .mapbase = 0xffe80000, .flags = UPF_BOOT_AUTOCONF, + .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, .type = PORT_SCIF, .irqs = { 40, 41, 43, 42 }, }, { diff --git a/arch/sh/kernel/cpu/sh4/setup-sh7750.c b/arch/sh/kernel/cpu/sh4/setup-sh7750.c index 851672d15cf4..2159c439dce9 100644 --- a/arch/sh/kernel/cpu/sh4/setup-sh7750.c +++ b/arch/sh/kernel/cpu/sh4/setup-sh7750.c @@ -14,6 +14,7 @@ #include #include #include +#include static struct resource rtc_resources[] = { [0] = { @@ -35,32 +36,36 @@ static struct platform_device rtc_device = { .resource = rtc_resources, }; -static struct plat_sci_port sci_platform_data[] = { - { -#ifndef CONFIG_SH_RTS7751R2D - .mapbase = 0xffe00000, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCI, - .irqs = { 23, 23, 23, 0 }, - }, { -#endif - .mapbase = 0xffe80000, - .flags = UPF_BOOT_AUTOCONF, - .type = PORT_SCIF, - .irqs = { 40, 40, 40, 40 }, - }, { - .flags = 0, - } +static struct plat_sci_port sci_platform_data = { + .mapbase = 0xffe00000, + .flags = UPF_BOOT_AUTOCONF, + .type = PORT_SCI, + .scscr = SCSCR_TE | SCSCR_RE, + .irqs = { 23, 23, 23, 0 }, }; static struct platform_device sci_device = { .name = "sh-sci", - .id = -1, .dev = { .platform_data = sci_platform_data, }, }; +static struct plat_sci_port scif_platform_data = { + .mapbase = 0xffe80000, + .flags = UPF_BOOT_AUTOCONF, + .scscr = SCSCR_TE | SCSCR_RE | SCSCR_REIE, + .type = PORT_SCIF, + .irqs = { 40, 40, 40, 40 }, +}; + +static struct platform_device scif_device = { + .name = "sh-sci", + .dev = { + .platform_data = scif_platform_data, + }, +}; + static struct sh_timer_config tmu0_platform_data = { .name = "TMU0", .channel_offset = 0x04, @@ -222,7 +227,6 @@ static struct platform_device tmu4_device = { static struct platform_device *sh7750_devices[] __initdata = { &rtc_device, - &sci_device, &tmu0_device, &tmu1_device, &tmu2_device, @@ -236,6 +240,14 @@ static struct platform_device *sh7750_devices[] __initdata = { static int __init sh7750_devices_setup(void) { + if (mach_is_rts7751r2d()) { + scif_platform_data.scscr |= SCSCR_CKE1; + platform_register_device(&scif_device); + } else { + platform_register_device(&sci_device); + platform_register_device(&scif_device); + } + return platform_add_devices(sh7750_devices, ARRAY_SIZE(sh7750_devices)); } diff --git a/arch/sh/kernel/cpu/sh4/setup-sh7760.c b/arch/sh/kernel/cpu/sh4/setup-sh7760.c index 5b822519bd90..74b5e994724d 100644 --- a/arch/sh/kernel/cpu/sh4/setup-sh7760.c +++ b/arch/sh/kernel/cpu/sh4/setup-sh7760.c @@ -130,21 +130,25 @@ static struct plat_sci_port sci_platform_data[] = { { .mapbase = 0xfe600000, .flags = UPF_BOOT_AUTOCONF, + .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, .type = PORT_SCIF, .irqs = { 52, 53, 55, 54 }, }, { .mapbase = 0xfe610000, .flags = UPF_BOOT_AUTOCONF, + .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, .type = PORT_SCIF, .irqs = { 72, 73, 75, 74 }, }, { .mapbase = 0xfe620000, .flags = UPF_BOOT_AUTOCONF, + .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, .type = PORT_SCIF, .irqs = { 76, 77, 79, 78 }, }, { .mapbase = 0xfe480000, .flags = UPF_BOOT_AUTOCONF, + .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, .type = PORT_SCI, .irqs = { 80, 81, 82, 0 }, }, { diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7343.c b/arch/sh/kernel/cpu/sh4a/setup-sh7343.c index 6307e087c864..09fb5814d925 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7343.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7343.c @@ -269,24 +269,28 @@ static struct plat_sci_port sci_platform_data[] = { { .mapbase = 0xffe00000, .flags = UPF_BOOT_AUTOCONF, + .scscr = SCSCR_RE | SCSCR_TE | SCSCR_CKE1, .type = PORT_SCIF, .irqs = { 80, 80, 80, 80 }, .clk = "scif0", }, { .mapbase = 0xffe10000, .flags = UPF_BOOT_AUTOCONF, + .scscr = SCSCR_RE | SCSCR_TE | SCSCR_CKE1, .type = PORT_SCIF, .irqs = { 81, 81, 81, 81 }, .clk = "scif1", }, { .mapbase = 0xffe20000, .flags = UPF_BOOT_AUTOCONF, + .scscr = SCSCR_RE | SCSCR_TE | SCSCR_CKE1, .type = PORT_SCIF, .irqs = { 82, 82, 82, 82 }, .clk = "scif2", }, { .mapbase = 0xffe30000, .flags = UPF_BOOT_AUTOCONF, + .scscr = SCSCR_RE | SCSCR_TE | SCSCR_CKE1, .type = PORT_SCIF, .irqs = { 83, 83, 83, 83 }, .clk = "scif3", diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7366.c b/arch/sh/kernel/cpu/sh4a/setup-sh7366.c index c18f7d09281b..307777cf04cc 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7366.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7366.c @@ -280,6 +280,7 @@ static struct plat_sci_port sci_platform_data[] = { { .mapbase = 0xffe00000, .flags = UPF_BOOT_AUTOCONF, + .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, .type = PORT_SCIF, .irqs = { 80, 80, 80, 80 }, .clk = "scif0", diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c index ea524a2da3e4..ffc69bc95932 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c @@ -305,25 +305,25 @@ static struct plat_sci_port sci_platform_data[] = { { .mapbase = 0xffe00000, .flags = UPF_BOOT_AUTOCONF, + .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, .type = PORT_SCIF, .irqs = { 80, 80, 80, 80 }, .clk = "scif0", - }, - { + }, { .mapbase = 0xffe10000, .flags = UPF_BOOT_AUTOCONF, + .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, .type = PORT_SCIF, .irqs = { 81, 81, 81, 81 }, .clk = "scif1", - }, - { + }, { .mapbase = 0xffe20000, .flags = UPF_BOOT_AUTOCONF, + .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, .type = PORT_SCIF, .irqs = { 82, 82, 82, 82 }, .clk = "scif2", - }, - { + }, { .flags = 0, } }; diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7723.c b/arch/sh/kernel/cpu/sh4a/setup-sh7723.c index e1bb80b2a27b..6ce331a8f1bd 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7723.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7723.c @@ -321,36 +321,42 @@ static struct plat_sci_port sci_platform_data[] = { { .mapbase = 0xffe00000, .flags = UPF_BOOT_AUTOCONF, + .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, .type = PORT_SCIF, .irqs = { 80, 80, 80, 80 }, .clk = "scif0", },{ .mapbase = 0xffe10000, .flags = UPF_BOOT_AUTOCONF, + .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, .type = PORT_SCIF, .irqs = { 81, 81, 81, 81 }, .clk = "scif1", },{ .mapbase = 0xffe20000, .flags = UPF_BOOT_AUTOCONF, + .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, .type = PORT_SCIF, .irqs = { 82, 82, 82, 82 }, .clk = "scif2", },{ .mapbase = 0xa4e30000, .flags = UPF_BOOT_AUTOCONF, + .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, .type = PORT_SCIFA, .irqs = { 56, 56, 56, 56 }, .clk = "scif3", },{ .mapbase = 0xa4e40000, .flags = UPF_BOOT_AUTOCONF, + .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, .type = PORT_SCIFA, .irqs = { 88, 88, 88, 88 }, .clk = "scif4", },{ .mapbase = 0xa4e50000, .flags = UPF_BOOT_AUTOCONF, + .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, .type = PORT_SCIFA, .irqs = { 109, 109, 109, 109 }, .clk = "scif5", diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7724.c b/arch/sh/kernel/cpu/sh4a/setup-sh7724.c index e5ac9eb11c63..4bf03c1ec8d6 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7724.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7724.c @@ -28,36 +28,42 @@ static struct plat_sci_port sci_platform_data[] = { { .mapbase = 0xffe00000, .flags = UPF_BOOT_AUTOCONF, + .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, .type = PORT_SCIF, .irqs = { 80, 80, 80, 80 }, .clk = "scif0", }, { .mapbase = 0xffe10000, .flags = UPF_BOOT_AUTOCONF, + .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, .type = PORT_SCIF, .irqs = { 81, 81, 81, 81 }, .clk = "scif1", }, { .mapbase = 0xffe20000, .flags = UPF_BOOT_AUTOCONF, + .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, .type = PORT_SCIF, .irqs = { 82, 82, 82, 82 }, .clk = "scif2", }, { .mapbase = 0xa4e30000, .flags = UPF_BOOT_AUTOCONF, + .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, .type = PORT_SCIFA, .irqs = { 56, 56, 56, 56 }, .clk = "scif3", }, { .mapbase = 0xa4e40000, .flags = UPF_BOOT_AUTOCONF, + .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, .type = PORT_SCIFA, .irqs = { 88, 88, 88, 88 }, .clk = "scif4", }, { .mapbase = 0xa4e50000, .flags = UPF_BOOT_AUTOCONF, + .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, .type = PORT_SCIFA, .irqs = { 109, 109, 109, 109 }, .clk = "scif5", diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7763.c b/arch/sh/kernel/cpu/sh4a/setup-sh7763.c index f1e0c0d36da7..76339c6da01e 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7763.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7763.c @@ -40,16 +40,19 @@ static struct plat_sci_port sci_platform_data[] = { { .mapbase = 0xffe00000, .flags = UPF_BOOT_AUTOCONF, + .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, .type = PORT_SCIF, .irqs = { 40, 40, 40, 40 }, }, { .mapbase = 0xffe08000, .flags = UPF_BOOT_AUTOCONF, + .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, .type = PORT_SCIF, .irqs = { 76, 76, 76, 76 }, }, { .mapbase = 0xffe10000, .flags = UPF_BOOT_AUTOCONF, + .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, .type = PORT_SCIF, .irqs = { 104, 104, 104, 104 }, }, { diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7770.c b/arch/sh/kernel/cpu/sh4a/setup-sh7770.c index 1e86209db284..07a41ff20504 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7770.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7770.c @@ -18,51 +18,61 @@ static struct plat_sci_port sci_platform_data[] = { { .mapbase = 0xff923000, .flags = UPF_BOOT_AUTOCONF, + .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_TOIE, .type = PORT_SCIF, .irqs = { 61, 61, 61, 61 }, }, { .mapbase = 0xff924000, .flags = UPF_BOOT_AUTOCONF, + .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_TOIE, .type = PORT_SCIF, .irqs = { 62, 62, 62, 62 }, }, { .mapbase = 0xff925000, .flags = UPF_BOOT_AUTOCONF, + .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_TOIE, .type = PORT_SCIF, .irqs = { 63, 63, 63, 63 }, }, { .mapbase = 0xff926000, .flags = UPF_BOOT_AUTOCONF, + .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_TOIE, .type = PORT_SCIF, .irqs = { 64, 64, 64, 64 }, }, { .mapbase = 0xff927000, .flags = UPF_BOOT_AUTOCONF, + .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_TOIE, .type = PORT_SCIF, .irqs = { 65, 65, 65, 65 }, }, { .mapbase = 0xff928000, .flags = UPF_BOOT_AUTOCONF, + .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_TOIE, .type = PORT_SCIF, .irqs = { 66, 66, 66, 66 }, }, { .mapbase = 0xff929000, .flags = UPF_BOOT_AUTOCONF, + .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_TOIE, .type = PORT_SCIF, .irqs = { 67, 67, 67, 67 }, }, { .mapbase = 0xff92a000, .flags = UPF_BOOT_AUTOCONF, + .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_TOIE, .type = PORT_SCIF, .irqs = { 68, 68, 68, 68 }, }, { .mapbase = 0xff92b000, .flags = UPF_BOOT_AUTOCONF, + .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_TOIE, .type = PORT_SCIF, .irqs = { 69, 69, 69, 69 }, }, { .mapbase = 0xff92c000, .flags = UPF_BOOT_AUTOCONF, + .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_TOIE, .type = PORT_SCIF, .irqs = { 70, 70, 70, 70 }, }, { diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7780.c b/arch/sh/kernel/cpu/sh4a/setup-sh7780.c index 715e05b431e5..2b355b67a33d 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7780.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7780.c @@ -220,11 +220,13 @@ static struct plat_sci_port sci_platform_data[] = { { .mapbase = 0xffe00000, .flags = UPF_BOOT_AUTOCONF, + .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_CKE1, .type = PORT_SCIF, .irqs = { 40, 40, 40, 40 }, }, { .mapbase = 0xffe10000, .flags = UPF_BOOT_AUTOCONF, + .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_CKE1, .type = PORT_SCIF, .irqs = { 76, 76, 76, 76 }, }, { diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7785.c b/arch/sh/kernel/cpu/sh4a/setup-sh7785.c index af561402570b..acd4b1d1b813 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7785.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7785.c @@ -202,36 +202,42 @@ static struct plat_sci_port sci_platform_data[] = { { .mapbase = 0xffea0000, .flags = UPF_BOOT_AUTOCONF, + .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_CKE1, .type = PORT_SCIF, .irqs = { 40, 40, 40, 40 }, .clk = "scif_fck", }, { .mapbase = 0xffeb0000, .flags = UPF_BOOT_AUTOCONF, + .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_CKE1, .type = PORT_SCIF, .irqs = { 44, 44, 44, 44 }, .clk = "scif_fck", }, { .mapbase = 0xffec0000, .flags = UPF_BOOT_AUTOCONF, + .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_CKE1, .type = PORT_SCIF, .irqs = { 60, 60, 60, 60 }, .clk = "scif_fck", }, { .mapbase = 0xffed0000, .flags = UPF_BOOT_AUTOCONF, + .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_CKE1, .type = PORT_SCIF, .irqs = { 61, 61, 61, 61 }, .clk = "scif_fck", }, { .mapbase = 0xffee0000, .flags = UPF_BOOT_AUTOCONF, + .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_CKE1, .type = PORT_SCIF, .irqs = { 62, 62, 62, 62 }, .clk = "scif_fck", }, { .mapbase = 0xffef0000, .flags = UPF_BOOT_AUTOCONF, + .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_CKE1, .type = PORT_SCIF, .irqs = { 63, 63, 63, 63 }, .clk = "scif_fck", diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7786.c b/arch/sh/kernel/cpu/sh4a/setup-sh7786.c index b70049470a0b..347ce88de570 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7786.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7786.c @@ -27,6 +27,7 @@ static struct plat_sci_port sci_platform_data[] = { { .mapbase = 0xffea0000, .flags = UPF_BOOT_AUTOCONF, + .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_CKE1, .type = PORT_SCIF, .irqs = { 40, 41, 43, 42 }, }, @@ -36,26 +37,31 @@ static struct plat_sci_port sci_platform_data[] = { { .mapbase = 0xffeb0000, .flags = UPF_BOOT_AUTOCONF, + .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_CKE1, .type = PORT_SCIF, .irqs = { 44, 44, 44, 44 }, }, { .mapbase = 0xffec0000, .flags = UPF_BOOT_AUTOCONF, + .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_CKE1, .type = PORT_SCIF, .irqs = { 50, 50, 50, 50 }, }, { .mapbase = 0xffed0000, .flags = UPF_BOOT_AUTOCONF, + .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_CKE1, .type = PORT_SCIF, .irqs = { 51, 51, 51, 51 }, }, { .mapbase = 0xffee0000, .flags = UPF_BOOT_AUTOCONF, + .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_CKE1, .type = PORT_SCIF, .irqs = { 52, 52, 52, 52 }, }, { .mapbase = 0xffef0000, .flags = UPF_BOOT_AUTOCONF, + .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_CKE1, .type = PORT_SCIF, .irqs = { 53, 53, 53, 53 }, }, { diff --git a/arch/sh/kernel/cpu/sh4a/setup-shx3.c b/arch/sh/kernel/cpu/sh4a/setup-shx3.c index 53c65fd9ccef..eef94934f542 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-shx3.c +++ b/arch/sh/kernel/cpu/sh4a/setup-shx3.c @@ -19,21 +19,25 @@ static struct plat_sci_port sci_platform_data[] = { { .mapbase = 0xffc30000, .flags = UPF_BOOT_AUTOCONF, + .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, .type = PORT_SCIF, .irqs = { 40, 41, 43, 42 }, }, { .mapbase = 0xffc40000, .flags = UPF_BOOT_AUTOCONF, + .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, .type = PORT_SCIF, .irqs = { 44, 45, 47, 46 }, }, { .mapbase = 0xffc50000, .flags = UPF_BOOT_AUTOCONF, + .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, .type = PORT_SCIF, .irqs = { 48, 49, 51, 50 }, }, { .mapbase = 0xffc60000, .flags = UPF_BOOT_AUTOCONF, + .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, .type = PORT_SCIF, .irqs = { 52, 53, 55, 54 }, }, { diff --git a/arch/sh/kernel/cpu/sh5/setup-sh5.c b/arch/sh/kernel/cpu/sh5/setup-sh5.c index f5ff1ac57fc2..26fa10c560de 100644 --- a/arch/sh/kernel/cpu/sh5/setup-sh5.c +++ b/arch/sh/kernel/cpu/sh5/setup-sh5.c @@ -20,6 +20,7 @@ static struct plat_sci_port sci_platform_data[] = { { .mapbase = PHYS_PERIPHERAL_BLOCK + 0x01030000, .flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP, + .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, .type = PORT_SCIF, .irqs = { 39, 40, 42, 0 }, }, { diff --git a/drivers/serial/sh-sci.c b/drivers/serial/sh-sci.c index 66f52674ca0c..3a13e58e9c5d 100644 --- a/drivers/serial/sh-sci.c +++ b/drivers/serial/sh-sci.c @@ -79,6 +79,9 @@ struct sci_port { struct timer_list break_timer; int break_flag; + /* SCSCR initialization */ + unsigned int scscr; + #ifdef CONFIG_HAVE_CLK /* Interface clock */ struct clk *iclk; @@ -928,6 +931,7 @@ static void sci_shutdown(struct uart_port *port) static void sci_set_termios(struct uart_port *port, struct ktermios *termios, struct ktermios *old) { + struct sci_port *s = to_sci_port(port); unsigned int status, baud, smr_val; int t = -1; @@ -972,7 +976,7 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, sci_init_pins(port, termios->c_cflag); sci_out(port, SCFCR, (termios->c_cflag & CRTSCTS) ? SCFCR_MCE : 0); - sci_out(port, SCSCR, SCSCR_INIT(port)); + sci_out(port, SCSCR, s->scscr); if ((termios->c_cflag & CREAD) != 0) sci_start_rx(port, 0); @@ -1097,6 +1101,7 @@ static void __devinit sci_init_single(struct platform_device *dev, sci_port->port.mapbase = p->mapbase; sci_port->port.membase = p->membase; + sci_port->scscr = p->scscr; sci_port->port.irq = p->irqs[SCIx_TXI_IRQ]; sci_port->port.flags = p->flags; sci_port->port.dev = &dev->dev; diff --git a/drivers/serial/sh-sci.h b/drivers/serial/sh-sci.h index 38072c15b845..4aa0ac8e67dd 100644 --- a/drivers/serial/sh-sci.h +++ b/drivers/serial/sh-sci.h @@ -15,7 +15,6 @@ defined(CONFIG_CPU_SUBTYPE_SH7709) # define SCPCR 0xA4000116 /* 16 bit SCI and SCIF */ # define SCPDR 0xA4000136 /* 8 bit SCI and SCIF */ -# define SCSCR_INIT(port) 0x30 /* TIE=0,RIE=0,TE=1,RE=1 */ #elif defined(CONFIG_CPU_SUBTYPE_SH7705) # define SCIF0 0xA4400000 # define SCIF2 0xA4410000 @@ -23,15 +22,8 @@ # define IRDA_SCIF SCIF0 # define SCPCR 0xA4000116 # define SCPDR 0xA4000136 - -/* Set the clock source, - * SCIF2 (0xA4410000) -> External clock, SCK pin used as clock input - * SCIF0 (0xA4400000) -> Internal clock, SCK pin as serial clock output - */ -# define SCSCR_INIT(port) (port->mapbase == SCIF2) ? 0xF3 : 0xF0 #elif defined(CONFIG_CPU_SUBTYPE_SH7720) || \ defined(CONFIG_CPU_SUBTYPE_SH7721) -# define SCSCR_INIT(port) 0x0030 /* TIE=0,RIE=0,TE=1,RE=1 */ # define PORT_PTCR 0xA405011EUL # define PORT_PVCR 0xA4050122UL # define SCIF_ORER 0x0200 /* overrun error bit */ @@ -39,7 +31,6 @@ # define SCSPTR1 0xFFE0001C /* 8 bit SCIF */ # define SCSPTR2 0xFFE80020 /* 16 bit SCIF */ # define SCIF_ORER 0x0001 /* overrun error bit */ -# define SCSCR_INIT(port) 0x3a /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */ #elif defined(CONFIG_CPU_SUBTYPE_SH7750) || \ defined(CONFIG_CPU_SUBTYPE_SH7750R) || \ defined(CONFIG_CPU_SUBTYPE_SH7750S) || \ @@ -49,39 +40,31 @@ # define SCSPTR1 0xffe0001c /* 8 bit SCI */ # define SCSPTR2 0xFFE80020 /* 16 bit SCIF */ # define SCIF_ORER 0x0001 /* overrun error bit */ -# define SCSCR_INIT(port) (((port)->type == PORT_SCI) ? \ - 0x30 /* TIE=0,RIE=0,TE=1,RE=1 */ : \ - 0x38 /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */ ) #elif defined(CONFIG_CPU_SUBTYPE_SH7760) # define SCSPTR0 0xfe600024 /* 16 bit SCIF */ # define SCSPTR1 0xfe610024 /* 16 bit SCIF */ # define SCSPTR2 0xfe620024 /* 16 bit SCIF */ # define SCIF_ORER 0x0001 /* overrun error bit */ -# define SCSCR_INIT(port) 0x38 /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */ #elif defined(CONFIG_CPU_SUBTYPE_SH7710) || defined(CONFIG_CPU_SUBTYPE_SH7712) # define SCSPTR0 0xA4400000 /* 16 bit SCIF */ # define SCIF_ORER 0x0001 /* overrun error bit */ # define PACR 0xa4050100 # define PBCR 0xa4050102 -# define SCSCR_INIT(port) 0x3B #elif defined(CONFIG_CPU_SUBTYPE_SH7343) # define SCSPTR0 0xffe00010 /* 16 bit SCIF */ # define SCSPTR1 0xffe10010 /* 16 bit SCIF */ # define SCSPTR2 0xffe20010 /* 16 bit SCIF */ # define SCSPTR3 0xffe30010 /* 16 bit SCIF */ -# define SCSCR_INIT(port) 0x32 /* TIE=0,RIE=0,TE=1,RE=1,REIE=0,CKE=1 */ #elif defined(CONFIG_CPU_SUBTYPE_SH7722) # define PADR 0xA4050120 # define PSDR 0xA405013e # define PWDR 0xA4050166 # define PSCR 0xA405011E # define SCIF_ORER 0x0001 /* overrun error bit */ -# define SCSCR_INIT(port) 0x0038 /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */ #elif defined(CONFIG_CPU_SUBTYPE_SH7366) # define SCPDR0 0xA405013E /* 16 bit SCIF0 PSDR */ # define SCSPTR0 SCPDR0 # define SCIF_ORER 0x0001 /* overrun error bit */ -# define SCSCR_INIT(port) 0x0038 /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */ #elif defined(CONFIG_CPU_SUBTYPE_SH7723) # define SCSPTR0 0xa4050160 # define SCSPTR1 0xa405013e @@ -90,45 +73,34 @@ # define SCSPTR4 0xa4050128 # define SCSPTR5 0xa4050128 # define SCIF_ORER 0x0001 /* overrun error bit */ -# define SCSCR_INIT(port) 0x0038 /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */ #elif defined(CONFIG_CPU_SUBTYPE_SH7724) # define SCIF_ORER 0x0001 /* overrun error bit */ -# define SCSCR_INIT(port) 0x0038 /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */ #elif defined(CONFIG_CPU_SUBTYPE_SH4_202) # define SCSPTR2 0xffe80020 /* 16 bit SCIF */ # define SCIF_ORER 0x0001 /* overrun error bit */ -# define SCSCR_INIT(port) 0x38 /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */ #elif defined(CONFIG_CPU_SUBTYPE_SH5_101) || defined(CONFIG_CPU_SUBTYPE_SH5_103) -# define SCIF_BASE_ADDR 0x01030000 -# define SCIF_ADDR_SH5 PHYS_PERIPHERAL_BLOCK+SCIF_BASE_ADDR # define SCIF_PTR2_OFFS 0x0000020 # define SCIF_LSR2_OFFS 0x0000024 # define SCSPTR2 ((port->mapbase)+SCIF_PTR2_OFFS) /* 16 bit SCIF */ # define SCLSR2 ((port->mapbase)+SCIF_LSR2_OFFS) /* 16 bit SCIF */ -# define SCSCR_INIT(port) 0x38 /* TIE=0,RIE=0, TE=1,RE=1,REIE=1 */ #elif defined(CONFIG_H83007) || defined(CONFIG_H83068) -# define SCSCR_INIT(port) 0x30 /* TIE=0,RIE=0,TE=1,RE=1 */ # define H8300_SCI_DR(ch) *(volatile char *)(P1DR + h8300_sci_pins[ch].port) #elif defined(CONFIG_H8S2678) -# define SCSCR_INIT(port) 0x30 /* TIE=0,RIE=0,TE=1,RE=1 */ # define H8300_SCI_DR(ch) *(volatile char *)(P1DR + h8300_sci_pins[ch].port) #elif defined(CONFIG_CPU_SUBTYPE_SH7763) # define SCSPTR0 0xffe00024 /* 16 bit SCIF */ # define SCSPTR1 0xffe08024 /* 16 bit SCIF */ # define SCSPTR2 0xffe10020 /* 16 bit SCIF/IRDA */ # define SCIF_ORER 0x0001 /* overrun error bit */ -# define SCSCR_INIT(port) 0x38 /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */ #elif defined(CONFIG_CPU_SUBTYPE_SH7770) # define SCSPTR0 0xff923020 /* 16 bit SCIF */ # define SCSPTR1 0xff924020 /* 16 bit SCIF */ # define SCSPTR2 0xff925020 /* 16 bit SCIF */ # define SCIF_ORER 0x0001 /* overrun error bit */ -# define SCSCR_INIT(port) 0x3c /* TIE=0,RIE=0,TE=1,RE=1,REIE=1,cke=2 */ #elif defined(CONFIG_CPU_SUBTYPE_SH7780) # define SCSPTR0 0xffe00024 /* 16 bit SCIF */ # define SCSPTR1 0xffe10024 /* 16 bit SCIF */ # define SCIF_ORER 0x0001 /* Overrun error bit */ -# define SCSCR_INIT(port) 0x3a /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */ #elif defined(CONFIG_CPU_SUBTYPE_SH7785) || \ defined(CONFIG_CPU_SUBTYPE_SH7786) # define SCSPTR0 0xffea0024 /* 16 bit SCIF */ @@ -138,7 +110,6 @@ # define SCSPTR4 0xffee0024 /* 16 bit SCIF */ # define SCSPTR5 0xffef0024 /* 16 bit SCIF */ # define SCIF_ORER 0x0001 /* Overrun error bit */ -# define SCSCR_INIT(port) 0x3a /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */ #elif defined(CONFIG_CPU_SUBTYPE_SH7201) || \ defined(CONFIG_CPU_SUBTYPE_SH7203) || \ defined(CONFIG_CPU_SUBTYPE_SH7206) || \ @@ -153,20 +124,17 @@ # define SCSPTR6 0xfffeB020 /* 16 bit SCIF */ # define SCSPTR7 0xfffeB820 /* 16 bit SCIF */ # endif -# define SCSCR_INIT(port) 0x38 /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */ #elif defined(CONFIG_CPU_SUBTYPE_SH7619) # define SCSPTR0 0xf8400020 /* 16 bit SCIF */ # define SCSPTR1 0xf8410020 /* 16 bit SCIF */ # define SCSPTR2 0xf8420020 /* 16 bit SCIF */ # define SCIF_ORER 0x0001 /* overrun error bit */ -# define SCSCR_INIT(port) 0x38 /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */ #elif defined(CONFIG_CPU_SUBTYPE_SHX3) # define SCSPTR0 0xffc30020 /* 16 bit SCIF */ # define SCSPTR1 0xffc40020 /* 16 bit SCIF */ # define SCSPTR2 0xffc50020 /* 16 bit SCIF */ # define SCSPTR3 0xffc60020 /* 16 bit SCIF */ # define SCIF_ORER 0x0001 /* Overrun error bit */ -# define SCSCR_INIT(port) 0x38 /* TIE=0,RIE=0,TE=1,RE=1,REIE=1 */ #else # error CPU subtype not defined #endif diff --git a/include/linux/serial_sci.h b/include/linux/serial_sci.h index 1c297ddc9d5a..f722a2275add 100644 --- a/include/linux/serial_sci.h +++ b/include/linux/serial_sci.h @@ -7,6 +7,15 @@ * Generic header for SuperH SCI(F) (used by sh/sh64/h8300 and related parts) */ +#define SCSCR_TIE (1 << 7) +#define SCSCR_RIE (1 << 6) +#define SCSCR_TE (1 << 5) +#define SCSCR_RE (1 << 4) +#define SCSCR_REIE (1 << 3) +#define SCSCR_TOIE (1 << 2) /* not supported by all parts */ +#define SCSCR_CKE1 (1 << 1) +#define SCSCR_CKE0 (1 << 0) + /* Offsets into the sci_port->irqs array */ enum { SCIx_ERI_IRQ, @@ -26,6 +35,8 @@ struct plat_sci_port { unsigned int type; /* SCI / SCIF / IRDA */ upf_t flags; /* UPF_* flags */ char *clk; /* clock string */ + + unsigned int scscr; /* SCSCR initialization */ }; #endif /* __LINUX_SERIAL_SCI_H */ -- cgit v1.2.3 From 26c92f3728d738aaa7e4859d5581323cd68096dd Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 24 Jun 2009 18:23:52 +0900 Subject: serial: sh-sci: Move SCBRR calculation algo in to platform data. This permits each port to select its own SCBRR calculation algorithm, rather than having it all ifdef'ed in the header. There are presently only 5 different variations that all parts fall under. Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/sh2/setup-sh7619.c | 3 ++ arch/sh/kernel/cpu/sh2a/setup-mxg.c | 1 + arch/sh/kernel/cpu/sh2a/setup-sh7201.c | 8 +++++ arch/sh/kernel/cpu/sh2a/setup-sh7203.c | 4 +++ arch/sh/kernel/cpu/sh2a/setup-sh7206.c | 4 +++ arch/sh/kernel/cpu/sh3/setup-sh7705.c | 2 ++ arch/sh/kernel/cpu/sh3/setup-sh770x.c | 3 ++ arch/sh/kernel/cpu/sh3/setup-sh7710.c | 2 ++ arch/sh/kernel/cpu/sh3/setup-sh7720.c | 2 ++ arch/sh/kernel/cpu/sh4/setup-sh4-202.c | 1 + arch/sh/kernel/cpu/sh4/setup-sh7750.c | 2 ++ arch/sh/kernel/cpu/sh4/setup-sh7760.c | 4 +++ arch/sh/kernel/cpu/sh4a/setup-sh7343.c | 4 +++ arch/sh/kernel/cpu/sh4a/setup-sh7366.c | 1 + arch/sh/kernel/cpu/sh4a/setup-sh7722.c | 3 ++ arch/sh/kernel/cpu/sh4a/setup-sh7723.c | 6 ++++ arch/sh/kernel/cpu/sh4a/setup-sh7724.c | 6 ++++ arch/sh/kernel/cpu/sh4a/setup-sh7763.c | 3 ++ arch/sh/kernel/cpu/sh4a/setup-sh7770.c | 10 ++++++ arch/sh/kernel/cpu/sh4a/setup-sh7780.c | 2 ++ arch/sh/kernel/cpu/sh4a/setup-sh7785.c | 6 ++++ arch/sh/kernel/cpu/sh4a/setup-sh7786.c | 6 ++++ arch/sh/kernel/cpu/sh4a/setup-shx3.c | 4 +++ arch/sh/kernel/cpu/sh5/setup-sh5.c | 1 + drivers/serial/sh-sci.c | 27 ++++++++++++++-- drivers/serial/sh-sci.h | 56 ---------------------------------- include/linux/serial_sci.h | 9 ++++++ 27 files changed, 122 insertions(+), 58 deletions(-) diff --git a/arch/sh/kernel/cpu/sh2/setup-sh7619.c b/arch/sh/kernel/cpu/sh2/setup-sh7619.c index ace016b17036..86acede777b9 100644 --- a/arch/sh/kernel/cpu/sh2/setup-sh7619.c +++ b/arch/sh/kernel/cpu/sh2/setup-sh7619.c @@ -64,18 +64,21 @@ static struct plat_sci_port sci_platform_data[] = { .mapbase = 0xf8400000, .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, + .scbrr_algo_id = SCBRR_ALGO_2, .type = PORT_SCIF, .irqs = { 88, 88, 88, 88 }, }, { .mapbase = 0xf8410000, .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, + .scbrr_algo_id = SCBRR_ALGO_2, .type = PORT_SCIF, .irqs = { 92, 92, 92, 92 }, }, { .mapbase = 0xf8420000, .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, + .scbrr_algo_id = SCBRR_ALGO_2, .type = PORT_SCIF, .irqs = { 96, 96, 96, 96 }, }, { diff --git a/arch/sh/kernel/cpu/sh2a/setup-mxg.c b/arch/sh/kernel/cpu/sh2a/setup-mxg.c index 7ec658ce14f8..b2c3bcc01190 100644 --- a/arch/sh/kernel/cpu/sh2a/setup-mxg.c +++ b/arch/sh/kernel/cpu/sh2a/setup-mxg.c @@ -212,6 +212,7 @@ static struct plat_sci_port sci_platform_data[] = { .mapbase = 0xff804000, .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, + .scbrr_algo_id = SCBRR_ALGO_2, .type = PORT_SCIF, .irqs = { 220, 220, 220, 220 }, }, { diff --git a/arch/sh/kernel/cpu/sh2a/setup-sh7201.c b/arch/sh/kernel/cpu/sh2a/setup-sh7201.c index 2a2ac222f9c7..8d44917ce50b 100644 --- a/arch/sh/kernel/cpu/sh2a/setup-sh7201.c +++ b/arch/sh/kernel/cpu/sh2a/setup-sh7201.c @@ -182,48 +182,56 @@ static struct plat_sci_port sci_platform_data[] = { .mapbase = 0xfffe8000, .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, + .scbrr_algo_id = SCBRR_ALGO_2, .type = PORT_SCIF, .irqs = { 180, 180, 180, 180 } }, { .mapbase = 0xfffe8800, .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, + .scbrr_algo_id = SCBRR_ALGO_2, .type = PORT_SCIF, .irqs = { 184, 184, 184, 184 } }, { .mapbase = 0xfffe9000, .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, + .scbrr_algo_id = SCBRR_ALGO_2, .type = PORT_SCIF, .irqs = { 188, 188, 188, 188 } }, { .mapbase = 0xfffe9800, .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, + .scbrr_algo_id = SCBRR_ALGO_2, .type = PORT_SCIF, .irqs = { 192, 192, 192, 192 } }, { .mapbase = 0xfffea000, .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, + .scbrr_algo_id = SCBRR_ALGO_2, .type = PORT_SCIF, .irqs = { 196, 196, 196, 196 } }, { .mapbase = 0xfffea800, .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, + .scbrr_algo_id = SCBRR_ALGO_2, .type = PORT_SCIF, .irqs = { 200, 200, 200, 200 } }, { .mapbase = 0xfffeb000, .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, + .scbrr_algo_id = SCBRR_ALGO_2, .type = PORT_SCIF, .irqs = { 204, 204, 204, 204 } }, { .mapbase = 0xfffeb800, .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, + .scbrr_algo_id = SCBRR_ALGO_2, .type = PORT_SCIF, .irqs = { 208, 208, 208, 208 } }, { diff --git a/arch/sh/kernel/cpu/sh2a/setup-sh7203.c b/arch/sh/kernel/cpu/sh2a/setup-sh7203.c index 2c9f3ababfd7..a78d2a219f3b 100644 --- a/arch/sh/kernel/cpu/sh2a/setup-sh7203.c +++ b/arch/sh/kernel/cpu/sh2a/setup-sh7203.c @@ -178,24 +178,28 @@ static struct plat_sci_port sci_platform_data[] = { .mapbase = 0xfffe8000, .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, + .scbrr_algo_id = SCBRR_ALGO_2, .type = PORT_SCIF, .irqs = { 192, 192, 192, 192 }, }, { .mapbase = 0xfffe8800, .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, + .scbrr_algo_id = SCBRR_ALGO_2, .type = PORT_SCIF, .irqs = { 196, 196, 196, 196 }, }, { .mapbase = 0xfffe9000, .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, + .scbrr_algo_id = SCBRR_ALGO_2, .type = PORT_SCIF, .irqs = { 200, 200, 200, 200 }, }, { .mapbase = 0xfffe9800, .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, + .scbrr_algo_id = SCBRR_ALGO_2, .type = PORT_SCIF, .irqs = { 204, 204, 204, 204 }, }, { diff --git a/arch/sh/kernel/cpu/sh2a/setup-sh7206.c b/arch/sh/kernel/cpu/sh2a/setup-sh7206.c index 5a47987f3902..68b93ed44cc2 100644 --- a/arch/sh/kernel/cpu/sh2a/setup-sh7206.c +++ b/arch/sh/kernel/cpu/sh2a/setup-sh7206.c @@ -138,24 +138,28 @@ static struct plat_sci_port sci_platform_data[] = { .mapbase = 0xfffe8000, .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, + .scbrr_algo_id = SCBRR_ALGO_2, .type = PORT_SCIF, .irqs = { 240, 240, 240, 240 }, }, { .mapbase = 0xfffe8800, .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, + .scbrr_algo_id = SCBRR_ALGO_2, .type = PORT_SCIF, .irqs = { 244, 244, 244, 244 }, }, { .mapbase = 0xfffe9000, .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, + .scbrr_algo_id = SCBRR_ALGO_2, .type = PORT_SCIF, .irqs = { 248, 248, 248, 248 }, }, { .mapbase = 0xfffe9800, .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, + .scbrr_algo_id = SCBRR_ALGO_2, .type = PORT_SCIF, .irqs = { 252, 252, 252, 252 }, }, { diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7705.c b/arch/sh/kernel/cpu/sh3/setup-sh7705.c index 28de53b281f3..27d03d836056 100644 --- a/arch/sh/kernel/cpu/sh3/setup-sh7705.c +++ b/arch/sh/kernel/cpu/sh3/setup-sh7705.c @@ -73,12 +73,14 @@ static struct plat_sci_port sci_platform_data[] = { .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_TIE | SCSCR_RIE | SCSCR_TE | SCSCR_RE | SCSCR_CKE1 | SCSCR_CKE0, + .scbrr_algo_id = SCBRR_ALGO_4, .type = PORT_SCIF, .irqs = { 56, 56, 56 }, }, { .mapbase = 0xa4400000, .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_TIE | SCSCR_RIE | SCSCR_TE | SCSCR_RE, + .scbrr_algo_id = SCBRR_ALGO_4, .type = PORT_SCIF, .irqs = { 52, 52, 52 }, }, { diff --git a/arch/sh/kernel/cpu/sh3/setup-sh770x.c b/arch/sh/kernel/cpu/sh3/setup-sh770x.c index 50ac42836dc7..83c9a5a39685 100644 --- a/arch/sh/kernel/cpu/sh3/setup-sh770x.c +++ b/arch/sh/kernel/cpu/sh3/setup-sh770x.c @@ -111,6 +111,7 @@ static struct plat_sci_port sci_platform_data[] = { .mapbase = 0xfffffe80, .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_TE | SCSCR_RE, + .scbrr_algo_id = SCBRR_ALGO_2, .type = PORT_SCI, .irqs = { 23, 23, 23, 0 }, }, @@ -121,6 +122,7 @@ static struct plat_sci_port sci_platform_data[] = { .mapbase = 0xa4000150, .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_TE | SCSCR_RE, + .scbrr_algo_id = SCBRR_ALGO_2, .type = PORT_SCIF, .irqs = { 56, 56, 56, 56 }, }, @@ -131,6 +133,7 @@ static struct plat_sci_port sci_platform_data[] = { .mapbase = 0xa4000140, .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_TE | SCSCR_RE, + .scbrr_algo_id = SCBRR_ALGO_2, .type = PORT_IRDA, .irqs = { 52, 52, 52, 52 }, }, diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7710.c b/arch/sh/kernel/cpu/sh3/setup-sh7710.c index 007627ecb7c8..9a60ffd34a9f 100644 --- a/arch/sh/kernel/cpu/sh3/setup-sh7710.c +++ b/arch/sh/kernel/cpu/sh3/setup-sh7710.c @@ -102,6 +102,7 @@ static struct plat_sci_port sci_platform_data[] = { .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_TE | SCSCR_RE | SCSCR_REIE | SCSCR_CKE1 | SCSCR_CKE0, + .scbrr_algo_id = SCBRR_ALGO_2, .type = PORT_SCIF, .irqs = { 52, 52, 52, 52 }, }, { @@ -109,6 +110,7 @@ static struct plat_sci_port sci_platform_data[] = { .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_TE | SCSCR_RE | SCSCR_REIE | SCSCR_CKE1 | SCSCR_CKE0, + .scbrr_algo_id = SCBRR_ALGO_2, .type = PORT_SCIF, .irqs = { 56, 56, 56, 56 }, }, { diff --git a/arch/sh/kernel/cpu/sh3/setup-sh7720.c b/arch/sh/kernel/cpu/sh3/setup-sh7720.c index 1fc3d9089199..48d50a65db32 100644 --- a/arch/sh/kernel/cpu/sh3/setup-sh7720.c +++ b/arch/sh/kernel/cpu/sh3/setup-sh7720.c @@ -53,12 +53,14 @@ static struct plat_sci_port sci_platform_data[] = { .mapbase = 0xa4430000, .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_RE | SCSCR_TE, + .scbrr_algo_id = SCBRR_ALGO_4, .type = PORT_SCIF, .irqs = { 80, 80, 80, 80 }, }, { .mapbase = 0xa4438000, .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_RE | SCSCR_TE, + .scbrr_algo_id = SCBRR_ALGO_4, .type = PORT_SCIF, .irqs = { 81, 81, 81, 81 }, }, { diff --git a/arch/sh/kernel/cpu/sh4/setup-sh4-202.c b/arch/sh/kernel/cpu/sh4/setup-sh4-202.c index 9aa6fa3ca4e6..ec2104b49ef7 100644 --- a/arch/sh/kernel/cpu/sh4/setup-sh4-202.c +++ b/arch/sh/kernel/cpu/sh4/setup-sh4-202.c @@ -20,6 +20,7 @@ static struct plat_sci_port sci_platform_data[] = { .mapbase = 0xffe80000, .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, + .scbrr_algo_id = SCBRR_ALGO_2, .type = PORT_SCIF, .irqs = { 40, 41, 43, 42 }, }, { diff --git a/arch/sh/kernel/cpu/sh4/setup-sh7750.c b/arch/sh/kernel/cpu/sh4/setup-sh7750.c index 2159c439dce9..51a945e0d72c 100644 --- a/arch/sh/kernel/cpu/sh4/setup-sh7750.c +++ b/arch/sh/kernel/cpu/sh4/setup-sh7750.c @@ -41,6 +41,7 @@ static struct plat_sci_port sci_platform_data = { .flags = UPF_BOOT_AUTOCONF, .type = PORT_SCI, .scscr = SCSCR_TE | SCSCR_RE, + .scbrr_algo_id = SCBRR_ALGO_2, .irqs = { 23, 23, 23, 0 }, }; @@ -55,6 +56,7 @@ static struct plat_sci_port scif_platform_data = { .mapbase = 0xffe80000, .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_TE | SCSCR_RE | SCSCR_REIE, + .scbrr_algo_id = SCBRR_ALGO_2, .type = PORT_SCIF, .irqs = { 40, 40, 40, 40 }, }; diff --git a/arch/sh/kernel/cpu/sh4/setup-sh7760.c b/arch/sh/kernel/cpu/sh4/setup-sh7760.c index 74b5e994724d..cee660fe1d90 100644 --- a/arch/sh/kernel/cpu/sh4/setup-sh7760.c +++ b/arch/sh/kernel/cpu/sh4/setup-sh7760.c @@ -131,24 +131,28 @@ static struct plat_sci_port sci_platform_data[] = { .mapbase = 0xfe600000, .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, + .scbrr_algo_id = SCBRR_ALGO_2, .type = PORT_SCIF, .irqs = { 52, 53, 55, 54 }, }, { .mapbase = 0xfe610000, .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, + .scbrr_algo_id = SCBRR_ALGO_2, .type = PORT_SCIF, .irqs = { 72, 73, 75, 74 }, }, { .mapbase = 0xfe620000, .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, + .scbrr_algo_id = SCBRR_ALGO_2, .type = PORT_SCIF, .irqs = { 76, 77, 79, 78 }, }, { .mapbase = 0xfe480000, .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, + .scbrr_algo_id = SCBRR_ALGO_2, .type = PORT_SCI, .irqs = { 80, 81, 82, 0 }, }, { diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7343.c b/arch/sh/kernel/cpu/sh4a/setup-sh7343.c index 09fb5814d925..fbae06b1c98d 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7343.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7343.c @@ -270,6 +270,7 @@ static struct plat_sci_port sci_platform_data[] = { .mapbase = 0xffe00000, .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_RE | SCSCR_TE | SCSCR_CKE1, + .scbrr_algo_id = SCBRR_ALGO_2, .type = PORT_SCIF, .irqs = { 80, 80, 80, 80 }, .clk = "scif0", @@ -277,6 +278,7 @@ static struct plat_sci_port sci_platform_data[] = { .mapbase = 0xffe10000, .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_RE | SCSCR_TE | SCSCR_CKE1, + .scbrr_algo_id = SCBRR_ALGO_2, .type = PORT_SCIF, .irqs = { 81, 81, 81, 81 }, .clk = "scif1", @@ -284,6 +286,7 @@ static struct plat_sci_port sci_platform_data[] = { .mapbase = 0xffe20000, .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_RE | SCSCR_TE | SCSCR_CKE1, + .scbrr_algo_id = SCBRR_ALGO_2, .type = PORT_SCIF, .irqs = { 82, 82, 82, 82 }, .clk = "scif2", @@ -291,6 +294,7 @@ static struct plat_sci_port sci_platform_data[] = { .mapbase = 0xffe30000, .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_RE | SCSCR_TE | SCSCR_CKE1, + .scbrr_algo_id = SCBRR_ALGO_2, .type = PORT_SCIF, .irqs = { 83, 83, 83, 83 }, .clk = "scif3", diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7366.c b/arch/sh/kernel/cpu/sh4a/setup-sh7366.c index 307777cf04cc..d4ee429032b1 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7366.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7366.c @@ -281,6 +281,7 @@ static struct plat_sci_port sci_platform_data[] = { .mapbase = 0xffe00000, .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, + .scbrr_algo_id = SCBRR_ALGO_2, .type = PORT_SCIF, .irqs = { 80, 80, 80, 80 }, .clk = "scif0", diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c index ffc69bc95932..f7b0551bf104 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c @@ -306,6 +306,7 @@ static struct plat_sci_port sci_platform_data[] = { .mapbase = 0xffe00000, .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, + .scbrr_algo_id = SCBRR_ALGO_2, .type = PORT_SCIF, .irqs = { 80, 80, 80, 80 }, .clk = "scif0", @@ -313,6 +314,7 @@ static struct plat_sci_port sci_platform_data[] = { .mapbase = 0xffe10000, .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, + .scbrr_algo_id = SCBRR_ALGO_2, .type = PORT_SCIF, .irqs = { 81, 81, 81, 81 }, .clk = "scif1", @@ -320,6 +322,7 @@ static struct plat_sci_port sci_platform_data[] = { .mapbase = 0xffe20000, .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, + .scbrr_algo_id = SCBRR_ALGO_2, .type = PORT_SCIF, .irqs = { 82, 82, 82, 82 }, .clk = "scif2", diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7723.c b/arch/sh/kernel/cpu/sh4a/setup-sh7723.c index 6ce331a8f1bd..bb4837b9dcf4 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7723.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7723.c @@ -322,6 +322,7 @@ static struct plat_sci_port sci_platform_data[] = { .mapbase = 0xffe00000, .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, + .scbrr_algo_id = SCBRR_ALGO_2, .type = PORT_SCIF, .irqs = { 80, 80, 80, 80 }, .clk = "scif0", @@ -329,6 +330,7 @@ static struct plat_sci_port sci_platform_data[] = { .mapbase = 0xffe10000, .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, + .scbrr_algo_id = SCBRR_ALGO_2, .type = PORT_SCIF, .irqs = { 81, 81, 81, 81 }, .clk = "scif1", @@ -336,6 +338,7 @@ static struct plat_sci_port sci_platform_data[] = { .mapbase = 0xffe20000, .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, + .scbrr_algo_id = SCBRR_ALGO_2, .type = PORT_SCIF, .irqs = { 82, 82, 82, 82 }, .clk = "scif2", @@ -343,6 +346,7 @@ static struct plat_sci_port sci_platform_data[] = { .mapbase = 0xa4e30000, .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, + .scbrr_algo_id = SCBRR_ALGO_3, .type = PORT_SCIFA, .irqs = { 56, 56, 56, 56 }, .clk = "scif3", @@ -350,6 +354,7 @@ static struct plat_sci_port sci_platform_data[] = { .mapbase = 0xa4e40000, .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, + .scbrr_algo_id = SCBRR_ALGO_3, .type = PORT_SCIFA, .irqs = { 88, 88, 88, 88 }, .clk = "scif4", @@ -357,6 +362,7 @@ static struct plat_sci_port sci_platform_data[] = { .mapbase = 0xa4e50000, .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, + .scbrr_algo_id = SCBRR_ALGO_3, .type = PORT_SCIFA, .irqs = { 109, 109, 109, 109 }, .clk = "scif5", diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7724.c b/arch/sh/kernel/cpu/sh4a/setup-sh7724.c index 4bf03c1ec8d6..c934b78e5658 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7724.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7724.c @@ -29,6 +29,7 @@ static struct plat_sci_port sci_platform_data[] = { .mapbase = 0xffe00000, .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, + .scbrr_algo_id = SCBRR_ALGO_2, .type = PORT_SCIF, .irqs = { 80, 80, 80, 80 }, .clk = "scif0", @@ -36,6 +37,7 @@ static struct plat_sci_port sci_platform_data[] = { .mapbase = 0xffe10000, .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, + .scbrr_algo_id = SCBRR_ALGO_2, .type = PORT_SCIF, .irqs = { 81, 81, 81, 81 }, .clk = "scif1", @@ -43,6 +45,7 @@ static struct plat_sci_port sci_platform_data[] = { .mapbase = 0xffe20000, .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, + .scbrr_algo_id = SCBRR_ALGO_2, .type = PORT_SCIF, .irqs = { 82, 82, 82, 82 }, .clk = "scif2", @@ -50,6 +53,7 @@ static struct plat_sci_port sci_platform_data[] = { .mapbase = 0xa4e30000, .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, + .scbrr_algo_id = SCBRR_ALGO_3, .type = PORT_SCIFA, .irqs = { 56, 56, 56, 56 }, .clk = "scif3", @@ -57,6 +61,7 @@ static struct plat_sci_port sci_platform_data[] = { .mapbase = 0xa4e40000, .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, + .scbrr_algo_id = SCBRR_ALGO_3, .type = PORT_SCIFA, .irqs = { 88, 88, 88, 88 }, .clk = "scif4", @@ -64,6 +69,7 @@ static struct plat_sci_port sci_platform_data[] = { .mapbase = 0xa4e50000, .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, + .scbrr_algo_id = SCBRR_ALGO_3, .type = PORT_SCIFA, .irqs = { 109, 109, 109, 109 }, .clk = "scif5", diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7763.c b/arch/sh/kernel/cpu/sh4a/setup-sh7763.c index 76339c6da01e..ab02771ee888 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7763.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7763.c @@ -41,18 +41,21 @@ static struct plat_sci_port sci_platform_data[] = { .mapbase = 0xffe00000, .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, + .scbrr_algo_id = SCBRR_ALGO_2, .type = PORT_SCIF, .irqs = { 40, 40, 40, 40 }, }, { .mapbase = 0xffe08000, .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, + .scbrr_algo_id = SCBRR_ALGO_2, .type = PORT_SCIF, .irqs = { 76, 76, 76, 76 }, }, { .mapbase = 0xffe10000, .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, + .scbrr_algo_id = SCBRR_ALGO_2, .type = PORT_SCIF, .irqs = { 104, 104, 104, 104 }, }, { diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7770.c b/arch/sh/kernel/cpu/sh4a/setup-sh7770.c index 07a41ff20504..746f4fb9ccf0 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7770.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7770.c @@ -19,60 +19,70 @@ static struct plat_sci_port sci_platform_data[] = { .mapbase = 0xff923000, .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_TOIE, + .scbrr_algo_id = SCBRR_ALGO_2, .type = PORT_SCIF, .irqs = { 61, 61, 61, 61 }, }, { .mapbase = 0xff924000, .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_TOIE, + .scbrr_algo_id = SCBRR_ALGO_2, .type = PORT_SCIF, .irqs = { 62, 62, 62, 62 }, }, { .mapbase = 0xff925000, .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_TOIE, + .scbrr_algo_id = SCBRR_ALGO_2, .type = PORT_SCIF, .irqs = { 63, 63, 63, 63 }, }, { .mapbase = 0xff926000, .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_TOIE, + .scbrr_algo_id = SCBRR_ALGO_2, .type = PORT_SCIF, .irqs = { 64, 64, 64, 64 }, }, { .mapbase = 0xff927000, .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_TOIE, + .scbrr_algo_id = SCBRR_ALGO_2, .type = PORT_SCIF, .irqs = { 65, 65, 65, 65 }, }, { .mapbase = 0xff928000, .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_TOIE, + .scbrr_algo_id = SCBRR_ALGO_2, .type = PORT_SCIF, .irqs = { 66, 66, 66, 66 }, }, { .mapbase = 0xff929000, .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_TOIE, + .scbrr_algo_id = SCBRR_ALGO_2, .type = PORT_SCIF, .irqs = { 67, 67, 67, 67 }, }, { .mapbase = 0xff92a000, .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_TOIE, + .scbrr_algo_id = SCBRR_ALGO_2, .type = PORT_SCIF, .irqs = { 68, 68, 68, 68 }, }, { .mapbase = 0xff92b000, .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_TOIE, + .scbrr_algo_id = SCBRR_ALGO_2, .type = PORT_SCIF, .irqs = { 69, 69, 69, 69 }, }, { .mapbase = 0xff92c000, .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_TOIE, + .scbrr_algo_id = SCBRR_ALGO_2, .type = PORT_SCIF, .irqs = { 70, 70, 70, 70 }, }, { diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7780.c b/arch/sh/kernel/cpu/sh4a/setup-sh7780.c index 2b355b67a33d..bcd411eb9cb0 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7780.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7780.c @@ -221,12 +221,14 @@ static struct plat_sci_port sci_platform_data[] = { .mapbase = 0xffe00000, .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_CKE1, + .scbrr_algo_id = SCBRR_ALGO_1, .type = PORT_SCIF, .irqs = { 40, 40, 40, 40 }, }, { .mapbase = 0xffe10000, .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_CKE1, + .scbrr_algo_id = SCBRR_ALGO_1, .type = PORT_SCIF, .irqs = { 76, 76, 76, 76 }, }, { diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7785.c b/arch/sh/kernel/cpu/sh4a/setup-sh7785.c index acd4b1d1b813..3ae2e2071009 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7785.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7785.c @@ -203,6 +203,7 @@ static struct plat_sci_port sci_platform_data[] = { .mapbase = 0xffea0000, .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_CKE1, + .scbrr_algo_id = SCBRR_ALGO_1, .type = PORT_SCIF, .irqs = { 40, 40, 40, 40 }, .clk = "scif_fck", @@ -210,6 +211,7 @@ static struct plat_sci_port sci_platform_data[] = { .mapbase = 0xffeb0000, .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_CKE1, + .scbrr_algo_id = SCBRR_ALGO_1, .type = PORT_SCIF, .irqs = { 44, 44, 44, 44 }, .clk = "scif_fck", @@ -217,6 +219,7 @@ static struct plat_sci_port sci_platform_data[] = { .mapbase = 0xffec0000, .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_CKE1, + .scbrr_algo_id = SCBRR_ALGO_1, .type = PORT_SCIF, .irqs = { 60, 60, 60, 60 }, .clk = "scif_fck", @@ -224,6 +227,7 @@ static struct plat_sci_port sci_platform_data[] = { .mapbase = 0xffed0000, .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_CKE1, + .scbrr_algo_id = SCBRR_ALGO_1, .type = PORT_SCIF, .irqs = { 61, 61, 61, 61 }, .clk = "scif_fck", @@ -231,6 +235,7 @@ static struct plat_sci_port sci_platform_data[] = { .mapbase = 0xffee0000, .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_CKE1, + .scbrr_algo_id = SCBRR_ALGO_1, .type = PORT_SCIF, .irqs = { 62, 62, 62, 62 }, .clk = "scif_fck", @@ -238,6 +243,7 @@ static struct plat_sci_port sci_platform_data[] = { .mapbase = 0xffef0000, .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_CKE1, + .scbrr_algo_id = SCBRR_ALGO_1, .type = PORT_SCIF, .irqs = { 63, 63, 63, 63 }, .clk = "scif_fck", diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7786.c b/arch/sh/kernel/cpu/sh4a/setup-sh7786.c index 347ce88de570..8b7ea4bd965d 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7786.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7786.c @@ -28,6 +28,7 @@ static struct plat_sci_port sci_platform_data[] = { .mapbase = 0xffea0000, .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_CKE1, + .scbrr_algo_id = SCBRR_ALGO_1, .type = PORT_SCIF, .irqs = { 40, 41, 43, 42 }, }, @@ -38,30 +39,35 @@ static struct plat_sci_port sci_platform_data[] = { .mapbase = 0xffeb0000, .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_CKE1, + .scbrr_algo_id = SCBRR_ALGO_1, .type = PORT_SCIF, .irqs = { 44, 44, 44, 44 }, }, { .mapbase = 0xffec0000, .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_CKE1, + .scbrr_algo_id = SCBRR_ALGO_1, .type = PORT_SCIF, .irqs = { 50, 50, 50, 50 }, }, { .mapbase = 0xffed0000, .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_CKE1, + .scbrr_algo_id = SCBRR_ALGO_1, .type = PORT_SCIF, .irqs = { 51, 51, 51, 51 }, }, { .mapbase = 0xffee0000, .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_CKE1, + .scbrr_algo_id = SCBRR_ALGO_1, .type = PORT_SCIF, .irqs = { 52, 52, 52, 52 }, }, { .mapbase = 0xffef0000, .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE | SCSCR_CKE1, + .scbrr_algo_id = SCBRR_ALGO_1, .type = PORT_SCIF, .irqs = { 53, 53, 53, 53 }, }, { diff --git a/arch/sh/kernel/cpu/sh4a/setup-shx3.c b/arch/sh/kernel/cpu/sh4a/setup-shx3.c index eef94934f542..4a26cc304139 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-shx3.c +++ b/arch/sh/kernel/cpu/sh4a/setup-shx3.c @@ -20,24 +20,28 @@ static struct plat_sci_port sci_platform_data[] = { .mapbase = 0xffc30000, .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, + .scbrr_algo_id = SCBRR_ALGO_2, .type = PORT_SCIF, .irqs = { 40, 41, 43, 42 }, }, { .mapbase = 0xffc40000, .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, + .scbrr_algo_id = SCBRR_ALGO_2, .type = PORT_SCIF, .irqs = { 44, 45, 47, 46 }, }, { .mapbase = 0xffc50000, .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, + .scbrr_algo_id = SCBRR_ALGO_2, .type = PORT_SCIF, .irqs = { 48, 49, 51, 50 }, }, { .mapbase = 0xffc60000, .flags = UPF_BOOT_AUTOCONF, .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, + .scbrr_algo_id = SCBRR_ALGO_2, .type = PORT_SCIF, .irqs = { 52, 53, 55, 54 }, }, { diff --git a/arch/sh/kernel/cpu/sh5/setup-sh5.c b/arch/sh/kernel/cpu/sh5/setup-sh5.c index 26fa10c560de..72aa86ec7446 100644 --- a/arch/sh/kernel/cpu/sh5/setup-sh5.c +++ b/arch/sh/kernel/cpu/sh5/setup-sh5.c @@ -21,6 +21,7 @@ static struct plat_sci_port sci_platform_data[] = { .mapbase = PHYS_PERIPHERAL_BLOCK + 0x01030000, .flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP, .scscr = SCSCR_RE | SCSCR_TE | SCSCR_REIE, + .scbrr_algo_id = SCBRR_ALGO_2, .type = PORT_SCIF, .irqs = { 39, 40, 42, 0 }, }, { diff --git a/drivers/serial/sh-sci.c b/drivers/serial/sh-sci.c index 3a13e58e9c5d..386fb878680c 100644 --- a/drivers/serial/sh-sci.c +++ b/drivers/serial/sh-sci.c @@ -82,6 +82,9 @@ struct sci_port { /* SCSCR initialization */ unsigned int scscr; + /* SCBRR calculation algo */ + unsigned int scbrr_algo_id; + #ifdef CONFIG_HAVE_CLK /* Interface clock */ struct clk *iclk; @@ -928,6 +931,27 @@ static void sci_shutdown(struct uart_port *port) s->disable(port); } +static unsigned int sci_scbrr_calc(unsigned int algo_id, unsigned int bps, + unsigned long freq) +{ + switch (algo_id) { + case SCBRR_ALGO_1: + return ((freq + 16 * bps) / (16 * bps) - 1); + case SCBRR_ALGO_2: + return ((freq + 16 * bps) / (32 * bps) - 1); + case SCBRR_ALGO_3: + return (((freq * 2) + 16 * bps) / (16 * bps) - 1); + case SCBRR_ALGO_4: + return (((freq * 2) + 16 * bps) / (32 * bps) - 1); + case SCBRR_ALGO_5: + return (((freq * 1000 / 32) / bps) - 1); + } + + /* Warn, but use a safe default */ + WARN_ON(1); + return ((freq + 16 * bps) / (32 * bps) - 1); +} + static void sci_set_termios(struct uart_port *port, struct ktermios *termios, struct ktermios *old) { @@ -937,7 +961,7 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16); if (likely(baud)) - t = SCBRR_VALUE(baud, port->uartclk); + t = sci_scbrr_calc(s->scbrr_algo_id, baud, port->uartclk); do { status = sci_in(port, SCxSR); @@ -1108,7 +1132,6 @@ static void __devinit sci_init_single(struct platform_device *dev, sci_port->type = sci_port->port.type = p->type; memcpy(&sci_port->irqs, &p->irqs, sizeof(p->irqs)); - } #ifdef CONFIG_SERIAL_SH_SCI_CONSOLE diff --git a/drivers/serial/sh-sci.h b/drivers/serial/sh-sci.h index 4aa0ac8e67dd..81104777a0a6 100644 --- a/drivers/serial/sh-sci.h +++ b/drivers/serial/sh-sci.h @@ -713,59 +713,3 @@ static inline int sci_rxd_in(struct uart_port *port) return 1; } #endif - -/* - * Values for the BitRate Register (SCBRR) - * - * The values are actually divisors for a frequency which can - * be internal to the SH3 (14.7456MHz) or derived from an external - * clock source. This driver assumes the internal clock is used; - * to support using an external clock source, config options or - * possibly command-line options would need to be added. - * - * Also, to support speeds below 2400 (why?) the lower 2 bits of - * the SCSMR register would also need to be set to non-zero values. - * - * -- Greg Banks 27Feb2000 - * - * Answer: The SCBRR register is only eight bits, and the value in - * it gets larger with lower baud rates. At around 2400 (depending on - * the peripherial module clock) you run out of bits. However the - * lower two bits of SCSMR allow the module clock to be divided down, - * scaling the value which is needed in SCBRR. - * - * -- Stuart Menefy - 23 May 2000 - * - * I meant, why would anyone bother with bitrates below 2400. - * - * -- Greg Banks - 7Jul2000 - * - * You "speedist"! How will I use my 110bps ASR-33 teletype with paper - * tape reader as a console! - * - * -- Mitch Davis - 15 Jul 2000 - */ - -#if defined(CONFIG_CPU_SUBTYPE_SH7780) || \ - defined(CONFIG_CPU_SUBTYPE_SH7785) || \ - defined(CONFIG_CPU_SUBTYPE_SH7786) -#define SCBRR_VALUE(bps, clk) ((clk+16*bps)/(16*bps)-1) -#elif defined(CONFIG_CPU_SUBTYPE_SH7705) || \ - defined(CONFIG_CPU_SUBTYPE_SH7720) || \ - defined(CONFIG_CPU_SUBTYPE_SH7721) -#define SCBRR_VALUE(bps, clk) (((clk*2)+16*bps)/(32*bps)-1) -#elif defined(CONFIG_CPU_SUBTYPE_SH7723) ||\ - defined(CONFIG_CPU_SUBTYPE_SH7724) -static inline int scbrr_calc(struct uart_port *port, int bps, int clk) -{ - if (port->type == PORT_SCIF) - return (clk+16*bps)/(32*bps)-1; - else - return ((clk*2)+16*bps)/(16*bps)-1; -} -#define SCBRR_VALUE(bps, clk) scbrr_calc(port, bps, clk) -#elif defined(__H8300H__) || defined(__H8300S__) -#define SCBRR_VALUE(bps, clk) (((clk*1000/32)/bps)-1) -#else /* Generic SH */ -#define SCBRR_VALUE(bps, clk) ((clk+16*bps)/(32*bps)-1) -#endif diff --git a/include/linux/serial_sci.h b/include/linux/serial_sci.h index f722a2275add..ff856b5bd276 100644 --- a/include/linux/serial_sci.h +++ b/include/linux/serial_sci.h @@ -7,6 +7,14 @@ * Generic header for SuperH SCI(F) (used by sh/sh64/h8300 and related parts) */ +enum { + SCBRR_ALGO_1, /* ((clk + 16 * bps) / (16 * bps) - 1) */ + SCBRR_ALGO_2, /* ((clk + 16 * bps) / (32 * bps) - 1) */ + SCBRR_ALGO_3, /* (((clk * 2) + 16 * bps) / (16 * bps) - 1) */ + SCBRR_ALGO_4, /* (((clk * 2) + 16 * bps) / (32 * bps) - 1) */ + SCBRR_ALGO_5, /* (((clk * 1000 / 32) / bps) - 1) */ +}; + #define SCSCR_TIE (1 << 7) #define SCSCR_RIE (1 << 6) #define SCSCR_TE (1 << 5) @@ -36,6 +44,7 @@ struct plat_sci_port { upf_t flags; /* UPF_* flags */ char *clk; /* clock string */ + unsigned int scbrr_algo_id; /* SCBRR calculation algo */ unsigned int scscr; /* SCSCR initialization */ }; -- cgit v1.2.3 From 706622c920232bc79ca20eaca252d3eb9103ae96 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 24 Jun 2009 19:40:54 +0900 Subject: serial: sh-sci: Kill off unused register accessors. Several of these registers are defined but never used, kill them off in the interest of increased sanity. Signed-off-by: Paul Mundt --- drivers/serial/sh-sci.h | 6 ------ 1 file changed, 6 deletions(-) diff --git a/drivers/serial/sh-sci.h b/drivers/serial/sh-sci.h index 81104777a0a6..5366e780aaeb 100644 --- a/drivers/serial/sh-sci.h +++ b/drivers/serial/sh-sci.h @@ -82,7 +82,6 @@ # define SCIF_PTR2_OFFS 0x0000020 # define SCIF_LSR2_OFFS 0x0000024 # define SCSPTR2 ((port->mapbase)+SCIF_PTR2_OFFS) /* 16 bit SCIF */ -# define SCLSR2 ((port->mapbase)+SCIF_LSR2_OFFS) /* 16 bit SCIF */ #elif defined(CONFIG_H83007) || defined(CONFIG_H83068) # define H8300_SCI_DR(ch) *(volatile char *)(P1DR + h8300_sci_pins[ch].port) #elif defined(CONFIG_H8S2678) @@ -367,8 +366,6 @@ SCIF_FNS(SCSMR, 0x00, 16) SCIF_FNS(SCBRR, 0x04, 8) SCIF_FNS(SCSCR, 0x08, 16) -SCIF_FNS(SCTDSR, 0x0c, 8) -SCIF_FNS(SCFER, 0x10, 16) SCIF_FNS(SCxSR, 0x14, 16) SCIF_FNS(SCFCR, 0x18, 16) SCIF_FNS(SCFDR, 0x1c, 16) @@ -384,8 +381,6 @@ SCIx_FNS(SCxTDR, 0x20, 8, 0x0c, 8) SCIx_FNS(SCxSR, 0x14, 16, 0x10, 16) SCIx_FNS(SCxRDR, 0x24, 8, 0x14, 8) SCIx_FNS(SCSPTR, 0, 0, 0, 0) -SCIF_FNS(SCTDSR, 0x0c, 8) -SCIF_FNS(SCFER, 0x10, 16) SCIF_FNS(SCFCR, 0x18, 16) SCIF_FNS(SCFDR, 0x1c, 16) SCIF_FNS(SCLSR, 0x24, 16) @@ -411,7 +406,6 @@ SCIF_FNS(SCLSR, 0, 0, 0x28, 16) #elif defined(CONFIG_CPU_SUBTYPE_SH7763) SCIF_FNS(SCFDR, 0, 0, 0x1C, 16) SCIF_FNS(SCSPTR2, 0, 0, 0x20, 16) -SCIF_FNS(SCLSR2, 0, 0, 0x24, 16) SCIF_FNS(SCTFDR, 0x0e, 16, 0x1C, 16) SCIF_FNS(SCRFDR, 0x0e, 16, 0x20, 16) SCIF_FNS(SCSPTR, 0, 0, 0x24, 16) -- cgit v1.2.3 From 8e6986149129acc6528a7231350c31ce3e3dadc5 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 24 Jun 2009 19:44:32 +0900 Subject: serial: sh-sci: Convert from old SCSR control flags to common defines. Many of these flags were duplicated, and as we now need this visibility to set them from the platform code, we can just use the linux/serial_sci.h variants instead. Signed-off-by: Paul Mundt --- drivers/serial/sh-sci.c | 22 +++++++++++----------- drivers/serial/sh-sci.h | 26 -------------------------- 2 files changed, 11 insertions(+), 37 deletions(-) diff --git a/drivers/serial/sh-sci.c b/drivers/serial/sh-sci.c index 386fb878680c..403b01b382e2 100644 --- a/drivers/serial/sh-sci.c +++ b/drivers/serial/sh-sci.c @@ -376,9 +376,9 @@ static void sci_transmit_chars(struct uart_port *port) if (!(status & SCxSR_TDxE(port))) { ctrl = sci_in(port, SCSCR); if (uart_circ_empty(xmit)) - ctrl &= ~SCI_CTRL_FLAGS_TIE; + ctrl &= ~SCSCR_TIE; else - ctrl |= SCI_CTRL_FLAGS_TIE; + ctrl |= SCSCR_TIE; sci_out(port, SCSCR, ctrl); return; } @@ -420,7 +420,7 @@ static void sci_transmit_chars(struct uart_port *port) sci_out(port, SCxSR, SCxSR_TDxE_CLEAR(port)); } - ctrl |= SCI_CTRL_FLAGS_TIE; + ctrl |= SCSCR_TIE; sci_out(port, SCSCR, ctrl); } } @@ -721,16 +721,16 @@ static irqreturn_t sci_mpxed_interrupt(int irq, void *ptr) scr_status = sci_in(port, SCSCR); /* Tx Interrupt */ - if ((ssr_status & 0x0020) && (scr_status & SCI_CTRL_FLAGS_TIE)) + if ((ssr_status & 0x0020) && (scr_status & SCSCR_TIE)) ret = sci_tx_interrupt(irq, ptr); /* Rx Interrupt */ - if ((ssr_status & 0x0002) && (scr_status & SCI_CTRL_FLAGS_RIE)) + if ((ssr_status & 0x0002) && (scr_status & SCSCR_RIE)) ret = sci_rx_interrupt(irq, ptr); /* Error Interrupt */ - if ((ssr_status & 0x0080) && (scr_status & SCI_CTRL_FLAGS_REIE)) + if ((ssr_status & 0x0080) && (scr_status & SCSCR_REIE)) ret = sci_er_interrupt(irq, ptr); /* Break Interrupt */ - if ((ssr_status & 0x0010) && (scr_status & SCI_CTRL_FLAGS_REIE)) + if ((ssr_status & 0x0010) && (scr_status & SCSCR_REIE)) ret = sci_br_interrupt(irq, ptr); return ret; @@ -861,7 +861,7 @@ static void sci_start_tx(struct uart_port *port) /* Set TIE (Transmit Interrupt Enable) bit in SCSCR */ ctrl = sci_in(port, SCSCR); - ctrl |= SCI_CTRL_FLAGS_TIE; + ctrl |= SCSCR_TIE; sci_out(port, SCSCR, ctrl); } @@ -871,7 +871,7 @@ static void sci_stop_tx(struct uart_port *port) /* Clear TIE (Transmit Interrupt Enable) bit in SCSCR */ ctrl = sci_in(port, SCSCR); - ctrl &= ~SCI_CTRL_FLAGS_TIE; + ctrl &= ~SCSCR_TIE; sci_out(port, SCSCR, ctrl); } @@ -881,7 +881,7 @@ static void sci_start_rx(struct uart_port *port, unsigned int tty_start) /* Set RIE (Receive Interrupt Enable) bit in SCSCR */ ctrl = sci_in(port, SCSCR); - ctrl |= SCI_CTRL_FLAGS_RIE | SCI_CTRL_FLAGS_REIE; + ctrl |= SCSCR_RIE | SCSCR_REIE; sci_out(port, SCSCR, ctrl); } @@ -891,7 +891,7 @@ static void sci_stop_rx(struct uart_port *port) /* Clear RIE (Receive Interrupt Enable) bit in SCSCR */ ctrl = sci_in(port, SCSCR); - ctrl &= ~(SCI_CTRL_FLAGS_RIE | SCI_CTRL_FLAGS_REIE); + ctrl &= ~(SCSCR_RIE | SCSCR_REIE); sci_out(port, SCSCR, ctrl); } diff --git a/drivers/serial/sh-sci.h b/drivers/serial/sh-sci.h index 5366e780aaeb..def626307c33 100644 --- a/drivers/serial/sh-sci.h +++ b/drivers/serial/sh-sci.h @@ -138,32 +138,6 @@ # error CPU subtype not defined #endif -/* SCSCR */ -#define SCI_CTRL_FLAGS_TIE 0x80 /* all */ -#define SCI_CTRL_FLAGS_RIE 0x40 /* all */ -#define SCI_CTRL_FLAGS_TE 0x20 /* all */ -#define SCI_CTRL_FLAGS_RE 0x10 /* all */ -#if defined(CONFIG_CPU_SUBTYPE_SH7750) || \ - defined(CONFIG_CPU_SUBTYPE_SH7091) || \ - defined(CONFIG_CPU_SUBTYPE_SH7750R) || \ - defined(CONFIG_CPU_SUBTYPE_SH7722) || \ - defined(CONFIG_CPU_SUBTYPE_SH7750S) || \ - defined(CONFIG_CPU_SUBTYPE_SH7751) || \ - defined(CONFIG_CPU_SUBTYPE_SH7751R) || \ - defined(CONFIG_CPU_SUBTYPE_SH7763) || \ - defined(CONFIG_CPU_SUBTYPE_SH7780) || \ - defined(CONFIG_CPU_SUBTYPE_SH7785) || \ - defined(CONFIG_CPU_SUBTYPE_SH7786) || \ - defined(CONFIG_CPU_SUBTYPE_SHX3) -#define SCI_CTRL_FLAGS_REIE 0x08 /* 7750 SCIF */ -#else -#define SCI_CTRL_FLAGS_REIE 0 -#endif -/* SCI_CTRL_FLAGS_MPIE 0x08 * 7707 SCI, 7708 SCI, 7709 SCI, 7750 SCI */ -/* SCI_CTRL_FLAGS_TEIE 0x04 * 7707 SCI, 7708 SCI, 7709 SCI, 7750 SCI */ -/* SCI_CTRL_FLAGS_CKE1 0x02 * all */ -/* SCI_CTRL_FLAGS_CKE0 0x01 * 7707 SCI/SCIF, 7708 SCI, 7709 SCI/SCIF, 7750 SCI */ - /* SCxSR SCI */ #define SCI_TDRE 0x80 /* 7707 SCI, 7708 SCI, 7709 SCI, 7750 SCI */ #define SCI_RDRF 0x40 /* 7707 SCI, 7708 SCI, 7709 SCI, 7750 SCI */ -- cgit v1.2.3 From f8e53553f452dcbf67cb89c8cba63a1cd6eb4cc0 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Wed, 24 Jun 2009 19:54:48 +0900 Subject: serial: sh-sci: Kill off more unused defines. Signed-off-by: Paul Mundt --- drivers/serial/sh-sci.h | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/drivers/serial/sh-sci.h b/drivers/serial/sh-sci.h index def626307c33..1b2ce1546979 100644 --- a/drivers/serial/sh-sci.h +++ b/drivers/serial/sh-sci.h @@ -18,8 +18,6 @@ #elif defined(CONFIG_CPU_SUBTYPE_SH7705) # define SCIF0 0xA4400000 # define SCIF2 0xA4410000 -# define SCSMR_Ir 0xA44A0000 -# define IRDA_SCIF SCIF0 # define SCPCR 0xA4000116 # define SCPDR 0xA4000136 #elif defined(CONFIG_CPU_SUBTYPE_SH7720) || \ @@ -80,7 +78,6 @@ # define SCIF_ORER 0x0001 /* overrun error bit */ #elif defined(CONFIG_CPU_SUBTYPE_SH5_101) || defined(CONFIG_CPU_SUBTYPE_SH5_103) # define SCIF_PTR2_OFFS 0x0000020 -# define SCIF_LSR2_OFFS 0x0000024 # define SCSPTR2 ((port->mapbase)+SCIF_PTR2_OFFS) /* 16 bit SCIF */ #elif defined(CONFIG_H83007) || defined(CONFIG_H83068) # define H8300_SCI_DR(ch) *(volatile char *)(P1DR + h8300_sci_pins[ch].port) @@ -210,23 +207,11 @@ /* SCFCR */ #define SCFCR_RFRST 0x0002 #define SCFCR_TFRST 0x0004 -#define SCFCR_TCRST 0x4000 #define SCFCR_MCE 0x0008 #define SCI_MAJOR 204 #define SCI_MINOR_START 8 -/* Generic serial flags */ -#define SCI_RX_THROTTLE 0x0000001 - -#define SCI_MAGIC 0xbabeface - -/* - * Events are used to schedule things to happen at timer-interrupt - * time, instead of at rs interrupt time. - */ -#define SCI_EVENT_WRITE_WAKEUP 0 - #define SCI_IN(size, offset) \ if ((size) == 8) { \ return ioread8(port->membase + (offset)); \ -- cgit v1.2.3 From fb27cfbcbd2865b0e731c4aae47df71778da805e Mon Sep 17 00:00:00 2001 From: Jeremy Fitzhardinge Date: Wed, 25 Aug 2010 12:19:53 -0700 Subject: xenfs/xenbus: report partial reads/writes correctly copy_(to|from)_user return the number of uncopied bytes, so a successful return is 0, and any non-zero result indicates some degree of failure. Reported-by: "Jun Zhu (Intern)" Signed-off-by: Jeremy Fitzhardinge --- drivers/xen/xenfs/xenbus.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/xen/xenfs/xenbus.c b/drivers/xen/xenfs/xenbus.c index 9d5b519d2e4c..d2a905826804 100644 --- a/drivers/xen/xenfs/xenbus.c +++ b/drivers/xen/xenfs/xenbus.c @@ -142,7 +142,7 @@ static ssize_t xenbus_file_read(struct file *filp, i += sz - ret; rb->cons += sz - ret; - if (ret != sz) { + if (ret != 0) { if (i == 0) i = -EFAULT; goto out; @@ -453,7 +453,7 @@ static ssize_t xenbus_file_write(struct file *filp, ret = copy_from_user(u->u.buffer + u->len, ubuf, len); - if (ret == len) { + if (ret != 0) { rc = -EFAULT; goto out; } -- cgit v1.2.3 From 6d6df2e412297b8047c407b3abcd045a67c96744 Mon Sep 17 00:00:00 2001 From: Diego Ongaro Date: Wed, 1 Sep 2010 09:18:54 -0700 Subject: xenbus: allow any xenbus command over /proc/xen/xenbus When xenstored is in another domain, we need to be able to send any command over xenbus. This doesn't pose a security problem because its up to xenstored to determine whether a given client is allowed to use a particular command anyway. From linux-2.5.18-xen.hg 68d582b0ad05. Signed-off-by: Jeremy Fitzhardinge --- drivers/xen/xenfs/xenbus.c | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) diff --git a/drivers/xen/xenfs/xenbus.c b/drivers/xen/xenfs/xenbus.c index d2a905826804..46cf4048e60e 100644 --- a/drivers/xen/xenfs/xenbus.c +++ b/drivers/xen/xenfs/xenbus.c @@ -486,21 +486,6 @@ static ssize_t xenbus_file_write(struct file *filp, msg_type = u->u.msg.type; switch (msg_type) { - case XS_TRANSACTION_START: - case XS_TRANSACTION_END: - case XS_DIRECTORY: - case XS_READ: - case XS_GET_PERMS: - case XS_RELEASE: - case XS_GET_DOMAIN_PATH: - case XS_WRITE: - case XS_MKDIR: - case XS_RM: - case XS_SET_PERMS: - /* Send out a transaction */ - ret = xenbus_write_transaction(msg_type, u); - break; - case XS_WATCH: case XS_UNWATCH: /* (Un)Ask for some path to be watched for changes */ @@ -508,7 +493,8 @@ static ssize_t xenbus_file_write(struct file *filp, break; default: - ret = -EINVAL; + /* Send out a transaction */ + ret = xenbus_write_transaction(msg_type, u); break; } if (ret != 0) -- cgit v1.2.3 From 76ce7618f9a24f7b13958c67f7d5ccfcdab71475 Mon Sep 17 00:00:00 2001 From: Daniel De Graaf Date: Tue, 7 Sep 2010 11:42:18 -0400 Subject: xenbus: add missing wakeup in concurrent read/write If an application has a dedicated read thread watching xenbus and another thread writes an XS_WATCH message that generates a synthetic "OK" reply, this reply will be enqueued in the buffer without waking up the reader. This can cause a deadlock in the application if it then waits for the read thread to receive the queued message. Signed-off-by: Daniel De Graaf commit e752969f502a511e83f841aa01d6cd332e6d85a0 Author: Daniel De Graaf Date: Tue Sep 7 11:21:52 2010 -0400 xenbus: fix deadlock in concurrent read/write If an application has a dedicated read thread watching xenbus and another thread writes an XS_WATCH message that generates a synthetic "OK" reply, this reply will be enqueued in the buffer without waking up the reader. Signed-off-by: Jeremy Fitzhardinge --- drivers/xen/xenfs/xenbus.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/xen/xenfs/xenbus.c b/drivers/xen/xenfs/xenbus.c index 46cf4048e60e..c4c7db8363e7 100644 --- a/drivers/xen/xenfs/xenbus.c +++ b/drivers/xen/xenfs/xenbus.c @@ -405,6 +405,7 @@ static int xenbus_write_watch(unsigned msg_type, struct xenbus_file_priv *u) mutex_lock(&u->reply_mutex); rc = queue_reply(&u->read_buffers, &reply, sizeof(reply)); + wake_up(&u->read_waitq); mutex_unlock(&u->reply_mutex); } -- cgit v1.2.3 From 7808121b9a1e44ef12fecd49fa6c268f27a150fc Mon Sep 17 00:00:00 2001 From: Daniel De Graaf Date: Wed, 8 Sep 2010 18:10:42 -0400 Subject: xenbus: avoid zero returns from read() It is possible to get a zero return from read() in instances where the queue is not empty but has no elements with data to deliver to the user. Since a zero return from read is an error indicator, resume waiting or return -EAGAIN (for a nonblocking fd) in this case. Signed-off-by: Daniel De Graaf Signed-off-by: Jeremy Fitzhardinge --- drivers/xen/xenfs/xenbus.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/xen/xenfs/xenbus.c b/drivers/xen/xenfs/xenbus.c index c4c7db8363e7..55791dd1105f 100644 --- a/drivers/xen/xenfs/xenbus.c +++ b/drivers/xen/xenfs/xenbus.c @@ -120,6 +120,7 @@ static ssize_t xenbus_file_read(struct file *filp, int ret; mutex_lock(&u->reply_mutex); +again: while (list_empty(&u->read_buffers)) { mutex_unlock(&u->reply_mutex); if (filp->f_flags & O_NONBLOCK) @@ -158,6 +159,8 @@ static ssize_t xenbus_file_read(struct file *filp, struct read_buffer, list); } } + if (i == 0) + goto again; out: mutex_unlock(&u->reply_mutex); -- cgit v1.2.3 From e39d5ef678045d61812c1401f04fe8edb14d6359 Mon Sep 17 00:00:00 2001 From: Anatolij Gustschin Date: Mon, 9 Aug 2010 07:58:48 +0200 Subject: powerpc/5xxx: extend mpc8xxx_gpio driver to support mpc512x gpios The GPIO controller of MPC512x is slightly different from 8xxx GPIO controllers. The register interface is the same except the external interrupt control register. The MPC512x GPIO controller differentiates between four interrupt event types and therefore provides two interrupt control registers, GPICR1 and GPICR2. GPIO[0:15] interrupt event types are configured in GPICR1 register, GPIO[16:31] - in GPICR2 register. This patch adds MPC512x speciffic set_type() callback and updates config file and comments. Additionally the gpio chip registration function is changed to use for_each_matching_node() preventing multiple registration if a node claimes compatibility with another gpio controller type. Signed-off-by: Anatolij Gustschin Signed-off-by: Grant Likely --- arch/powerpc/platforms/Kconfig | 7 ++-- arch/powerpc/sysdev/mpc8xxx_gpio.c | 75 ++++++++++++++++++++++++++++++++++---- 2 files changed, 71 insertions(+), 11 deletions(-) diff --git a/arch/powerpc/platforms/Kconfig b/arch/powerpc/platforms/Kconfig index d1663db7810f..471115a13d1b 100644 --- a/arch/powerpc/platforms/Kconfig +++ b/arch/powerpc/platforms/Kconfig @@ -304,13 +304,14 @@ config OF_RTC source "arch/powerpc/sysdev/bestcomm/Kconfig" config MPC8xxx_GPIO - bool "MPC8xxx GPIO support" - depends on PPC_MPC831x || PPC_MPC834x || PPC_MPC837x || FSL_SOC_BOOKE || PPC_86xx + bool "MPC512x/MPC8xxx GPIO support" + depends on PPC_MPC512x || PPC_MPC831x || PPC_MPC834x || PPC_MPC837x || \ + FSL_SOC_BOOKE || PPC_86xx select GENERIC_GPIO select ARCH_REQUIRE_GPIOLIB help Say Y here if you're going to use hardware that connects to the - MPC831x/834x/837x/8572/8610 GPIOs. + MPC512x/831x/834x/837x/8572/8610 GPIOs. config SIMPLE_GPIO bool "Support for simple, memory-mapped GPIO controllers" diff --git a/arch/powerpc/sysdev/mpc8xxx_gpio.c b/arch/powerpc/sysdev/mpc8xxx_gpio.c index 2b69084d0f0c..36499394a161 100644 --- a/arch/powerpc/sysdev/mpc8xxx_gpio.c +++ b/arch/powerpc/sysdev/mpc8xxx_gpio.c @@ -1,5 +1,5 @@ /* - * GPIOs on MPC8349/8572/8610 and compatible + * GPIOs on MPC512x/8349/8572/8610 and compatible * * Copyright (C) 2008 Peter Korsgaard * @@ -26,6 +26,7 @@ #define GPIO_IER 0x0c #define GPIO_IMR 0x10 #define GPIO_ICR 0x14 +#define GPIO_ICR2 0x18 struct mpc8xxx_gpio_chip { struct of_mm_gpio_chip mm_gc; @@ -37,6 +38,7 @@ struct mpc8xxx_gpio_chip { */ u32 data; struct irq_host *irq; + void *of_dev_id_data; }; static inline u32 mpc8xxx_gpio2mask(unsigned int gpio) @@ -215,6 +217,51 @@ static int mpc8xxx_irq_set_type(unsigned int virq, unsigned int flow_type) return 0; } +static int mpc512x_irq_set_type(unsigned int virq, unsigned int flow_type) +{ + struct mpc8xxx_gpio_chip *mpc8xxx_gc = get_irq_chip_data(virq); + struct of_mm_gpio_chip *mm = &mpc8xxx_gc->mm_gc; + unsigned long gpio = virq_to_hw(virq); + void __iomem *reg; + unsigned int shift; + unsigned long flags; + + if (gpio < 16) { + reg = mm->regs + GPIO_ICR; + shift = (15 - gpio) * 2; + } else { + reg = mm->regs + GPIO_ICR2; + shift = (15 - (gpio % 16)) * 2; + } + + switch (flow_type) { + case IRQ_TYPE_EDGE_FALLING: + case IRQ_TYPE_LEVEL_LOW: + spin_lock_irqsave(&mpc8xxx_gc->lock, flags); + clrsetbits_be32(reg, 3 << shift, 2 << shift); + spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags); + break; + + case IRQ_TYPE_EDGE_RISING: + case IRQ_TYPE_LEVEL_HIGH: + spin_lock_irqsave(&mpc8xxx_gc->lock, flags); + clrsetbits_be32(reg, 3 << shift, 1 << shift); + spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags); + break; + + case IRQ_TYPE_EDGE_BOTH: + spin_lock_irqsave(&mpc8xxx_gc->lock, flags); + clrbits32(reg, 3 << shift); + spin_unlock_irqrestore(&mpc8xxx_gc->lock, flags); + break; + + default: + return -EINVAL; + } + + return 0; +} + static struct irq_chip mpc8xxx_irq_chip = { .name = "mpc8xxx-gpio", .unmask = mpc8xxx_irq_unmask, @@ -226,6 +273,11 @@ static struct irq_chip mpc8xxx_irq_chip = { static int mpc8xxx_gpio_irq_map(struct irq_host *h, unsigned int virq, irq_hw_number_t hw) { + struct mpc8xxx_gpio_chip *mpc8xxx_gc = h->host_data; + + if (mpc8xxx_gc->of_dev_id_data) + mpc8xxx_irq_chip.set_type = mpc8xxx_gc->of_dev_id_data; + set_irq_chip_data(virq, h->host_data); set_irq_chip_and_handler(virq, &mpc8xxx_irq_chip, handle_level_irq); set_irq_type(virq, IRQ_TYPE_NONE); @@ -253,11 +305,20 @@ static struct irq_host_ops mpc8xxx_gpio_irq_ops = { .xlate = mpc8xxx_gpio_irq_xlate, }; +static struct of_device_id mpc8xxx_gpio_ids[] __initdata = { + { .compatible = "fsl,mpc8349-gpio", }, + { .compatible = "fsl,mpc8572-gpio", }, + { .compatible = "fsl,mpc8610-gpio", }, + { .compatible = "fsl,mpc5121-gpio", .data = mpc512x_irq_set_type, }, + {} +}; + static void __init mpc8xxx_add_controller(struct device_node *np) { struct mpc8xxx_gpio_chip *mpc8xxx_gc; struct of_mm_gpio_chip *mm_gc; struct gpio_chip *gc; + const struct of_device_id *id; unsigned hwirq; int ret; @@ -297,6 +358,10 @@ static void __init mpc8xxx_add_controller(struct device_node *np) if (!mpc8xxx_gc->irq) goto skip_irq; + id = of_match_node(mpc8xxx_gpio_ids, np); + if (id) + mpc8xxx_gc->of_dev_id_data = id->data; + mpc8xxx_gc->irq->host_data = mpc8xxx_gc; /* ack and mask all irqs */ @@ -321,13 +386,7 @@ static int __init mpc8xxx_add_gpiochips(void) { struct device_node *np; - for_each_compatible_node(np, NULL, "fsl,mpc8349-gpio") - mpc8xxx_add_controller(np); - - for_each_compatible_node(np, NULL, "fsl,mpc8572-gpio") - mpc8xxx_add_controller(np); - - for_each_compatible_node(np, NULL, "fsl,mpc8610-gpio") + for_each_matching_node(np, mpc8xxx_gpio_ids) mpc8xxx_add_controller(np); return 0; -- cgit v1.2.3 From 6f4bc952c60b26ecfcb013fb9a7e9474023e046e Mon Sep 17 00:00:00 2001 From: "Arnaud Patard (Rtp)" Date: Thu, 21 Oct 2010 19:40:02 +0200 Subject: ASoC: add support for alc562[123] codecs This patch is adding support for alc562[123] codecs. It's based on the source code available in HP source code and other places. Signed-off-by: Arnaud Patard Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- include/sound/alc5623.h | 15 + sound/soc/codecs/Kconfig | 5 + sound/soc/codecs/Makefile | 2 + sound/soc/codecs/alc5623.c | 1118 ++++++++++++++++++++++++++++++++++++++++++++ sound/soc/codecs/alc5623.h | 161 +++++++ 5 files changed, 1301 insertions(+) create mode 100644 include/sound/alc5623.h create mode 100644 sound/soc/codecs/alc5623.c create mode 100644 sound/soc/codecs/alc5623.h diff --git a/include/sound/alc5623.h b/include/sound/alc5623.h new file mode 100644 index 000000000000..422c97d43df3 --- /dev/null +++ b/include/sound/alc5623.h @@ -0,0 +1,15 @@ +#ifndef _INCLUDE_SOUND_ALC5623_H +#define _INCLUDE_SOUND_ALC5623_H +struct alc5623_platform_data { + /* configure : */ + /* Lineout/Speaker Amps Vmid ratio control */ + /* enable/disable adc/dac high pass filters */ + unsigned int add_ctrl; + /* configure : */ + /* output to enable when jack is low */ + /* output to enable when jack is high */ + /* jack detect (gpio/nc/jack detect [12] */ + unsigned int jack_det_ctrl; +}; +#endif + diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index 94a9d06b9027..658cbe07fb72 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -22,6 +22,7 @@ config SND_SOC_ALL_CODECS select SND_SOC_AK4535 if I2C select SND_SOC_AK4642 if I2C select SND_SOC_AK4671 if I2C + select SND_SOC_ALC562 if I2C select SND_SOC_CQ0093VC if MFD_DAVINCI_VOICECODEC select SND_SOC_CS42L51 if I2C select SND_SOC_CS4270 if I2C @@ -129,6 +130,9 @@ config SND_SOC_AK4642 config SND_SOC_AK4671 tristate +config SND_SOC_ALC5623 + tristate + config SND_SOC_CQ0093VC tristate @@ -317,3 +321,4 @@ config SND_SOC_WM2000 config SND_SOC_WM9090 tristate + diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index f67a2d6f7a46..0dcaed3e73f3 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile @@ -17,6 +17,7 @@ snd-soc-da7210-objs := da7210.o snd-soc-l3-objs := l3.o snd-soc-max98088-objs := max98088.o snd-soc-pcm3008-objs := pcm3008.o +snd-soc-alc5623-objs := alc5623.o snd-soc-spdif-objs := spdif_transciever.o snd-soc-ssm2602-objs := ssm2602.o snd-soc-stac9766-objs := stac9766.o @@ -92,6 +93,7 @@ obj-$(CONFIG_SND_SOC_L3) += snd-soc-l3.o obj-$(CONFIG_SND_SOC_JZ4740_CODEC) += snd-soc-jz4740-codec.o obj-$(CONFIG_SND_SOC_MAX98088) += snd-soc-max98088.o obj-$(CONFIG_SND_SOC_PCM3008) += snd-soc-pcm3008.o +obj-$(CONFIG_SND_SOC_ALC5623) += snd-soc-alc5623.o obj-$(CONFIG_SND_SOC_SPDIF) += snd-soc-spdif.o obj-$(CONFIG_SND_SOC_SSM2602) += snd-soc-ssm2602.o obj-$(CONFIG_SND_SOC_STAC9766) += snd-soc-stac9766.o diff --git a/sound/soc/codecs/alc5623.c b/sound/soc/codecs/alc5623.c new file mode 100644 index 000000000000..fac61744f8c7 --- /dev/null +++ b/sound/soc/codecs/alc5623.c @@ -0,0 +1,1118 @@ +/* + * alc5623.c -- alc562[123] ALSA Soc Audio driver + * + * Copyright 2008 Realtek Microelectronics + * Author: flove Ethan + * + * Copyright 2010 Arnaud Patard + * + * + * Based on WM8753.c + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "alc5623.h" + +static int caps_charge = 2000; +module_param(caps_charge, int, 0); +MODULE_PARM_DESC(caps_charge, "ALC5623 cap charge time (msecs)"); + +/* codec private data */ +struct alc5623_priv { + enum snd_soc_control_type control_type; + void *control_data; + struct mutex mutex; + u8 id; + unsigned int sysclk; + u16 reg_cache[ALC5623_VENDOR_ID2+2]; + unsigned int add_ctrl; + unsigned int jack_det_ctrl; +}; + +static void alc5623_fill_cache(struct snd_soc_codec *codec) +{ + int i, step = codec->driver->reg_cache_step; + u16 *cache = codec->reg_cache; + + /* not really efficient ... */ + for (i = 0 ; i < codec->driver->reg_cache_size ; i += step) + cache[i] = codec->hw_read(codec, i); +} + +static inline int alc5623_reset(struct snd_soc_codec *codec) +{ + return snd_soc_write(codec, ALC5623_RESET, 0); +} + +static int amp_mixer_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + /* to power-on/off class-d amp generators/speaker */ + /* need to write to 'index-46h' register : */ + /* so write index num (here 0x46) to reg 0x6a */ + /* and then 0xffff/0 to reg 0x6c */ + snd_soc_write(w->codec, ALC5623_HID_CTRL_INDEX, 0x46); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + snd_soc_write(w->codec, ALC5623_HID_CTRL_DATA, 0xFFFF); + break; + case SND_SOC_DAPM_POST_PMD: + snd_soc_write(w->codec, ALC5623_HID_CTRL_DATA, 0); + break; + } + + return 0; +} + +/* + * ALC5623 Controls + */ + +static const DECLARE_TLV_DB_SCALE(vol_tlv, -3450, 150, 0); +static const DECLARE_TLV_DB_SCALE(hp_tlv, -4650, 150, 0); +static const DECLARE_TLV_DB_SCALE(adc_rec_tlv, -1650, 150, 0); +static const unsigned int boost_tlv[] = { + TLV_DB_RANGE_HEAD(3), + 0, 0, TLV_DB_SCALE_ITEM(0, 0, 0), + 1, 1, TLV_DB_SCALE_ITEM(2000, 0, 0), + 2, 2, TLV_DB_SCALE_ITEM(3000, 0, 0), +}; +static const DECLARE_TLV_DB_SCALE(dig_tlv, 0, 600, 0); + +static const struct snd_kcontrol_new rt5621_vol_snd_controls[] = { + SOC_DOUBLE_TLV("Speaker Playback Volume", + ALC5623_SPK_OUT_VOL, 8, 0, 31, 1, hp_tlv), + SOC_DOUBLE("Speaker Playback Switch", + ALC5623_SPK_OUT_VOL, 15, 7, 1, 1), + SOC_DOUBLE_TLV("Headphone Playback Volume", + ALC5623_HP_OUT_VOL, 8, 0, 31, 1, hp_tlv), + SOC_DOUBLE("Headphone Playback Switch", + ALC5623_HP_OUT_VOL, 15, 7, 1, 1), +}; + +static const struct snd_kcontrol_new rt5622_vol_snd_controls[] = { + SOC_DOUBLE_TLV("Speaker Playback Volume", + ALC5623_SPK_OUT_VOL, 8, 0, 31, 1, hp_tlv), + SOC_DOUBLE("Speaker Playback Switch", + ALC5623_SPK_OUT_VOL, 15, 7, 1, 1), + SOC_DOUBLE_TLV("Line Playback Volume", + ALC5623_HP_OUT_VOL, 8, 0, 31, 1, hp_tlv), + SOC_DOUBLE("Line Playback Switch", + ALC5623_HP_OUT_VOL, 15, 7, 1, 1), +}; + +static const struct snd_kcontrol_new alc5623_vol_snd_controls[] = { + SOC_DOUBLE_TLV("Line Playback Volume", + ALC5623_SPK_OUT_VOL, 8, 0, 31, 1, hp_tlv), + SOC_DOUBLE("Line Playback Switch", + ALC5623_SPK_OUT_VOL, 15, 7, 1, 1), + SOC_DOUBLE_TLV("Headphone Playback Volume", + ALC5623_HP_OUT_VOL, 8, 0, 31, 1, hp_tlv), + SOC_DOUBLE("Headphone Playback Switch", + ALC5623_HP_OUT_VOL, 15, 7, 1, 1), +}; + +static const struct snd_kcontrol_new alc5623_snd_controls[] = { + SOC_DOUBLE_TLV("Auxout Playback Volume", + ALC5623_MONO_AUX_OUT_VOL, 8, 0, 31, 1, hp_tlv), + SOC_DOUBLE("Auxout Playback Switch", + ALC5623_MONO_AUX_OUT_VOL, 15, 7, 1, 1), + SOC_DOUBLE_TLV("PCM Playback Volume", + ALC5623_STEREO_DAC_VOL, 8, 0, 31, 1, vol_tlv), + SOC_DOUBLE_TLV("AuxI Capture Volume", + ALC5623_AUXIN_VOL, 8, 0, 31, 1, vol_tlv), + SOC_DOUBLE_TLV("LineIn Capture Volume", + ALC5623_LINE_IN_VOL, 8, 0, 31, 1, vol_tlv), + SOC_SINGLE_TLV("Mic1 Capture Volume", + ALC5623_MIC_VOL, 8, 31, 1, vol_tlv), + SOC_SINGLE_TLV("Mic2 Capture Volume", + ALC5623_MIC_VOL, 0, 31, 1, vol_tlv), + SOC_DOUBLE_TLV("Rec Capture Volume", + ALC5623_ADC_REC_GAIN, 7, 0, 31, 0, adc_rec_tlv), + SOC_SINGLE_TLV("Mic 1 Boost Volume", + ALC5623_MIC_CTRL, 10, 2, 0, boost_tlv), + SOC_SINGLE_TLV("Mic 2 Boost Volume", + ALC5623_MIC_CTRL, 8, 2, 0, boost_tlv), + SOC_SINGLE_TLV("Digital Boost Volume", + ALC5623_ADD_CTRL_REG, 4, 3, 0, dig_tlv), +}; + +/* + * DAPM Controls + */ +static const struct snd_kcontrol_new alc5623_hp_mixer_controls[] = { +SOC_DAPM_SINGLE("LI2HP Playback Switch", ALC5623_LINE_IN_VOL, 15, 1, 1), +SOC_DAPM_SINGLE("AUXI2HP Playback Switch", ALC5623_AUXIN_VOL, 15, 1, 1), +SOC_DAPM_SINGLE("MIC12HP Playback Switch", ALC5623_MIC_ROUTING_CTRL, 15, 1, 1), +SOC_DAPM_SINGLE("MIC22HP Playback Switch", ALC5623_MIC_ROUTING_CTRL, 7, 1, 1), +SOC_DAPM_SINGLE("DAC2HP Playback Switch", ALC5623_STEREO_DAC_VOL, 15, 1, 1), +}; + +static const struct snd_kcontrol_new alc5623_hpl_mixer_controls[] = { +SOC_DAPM_SINGLE("ADC2HP_L Playback Switch", ALC5623_ADC_REC_GAIN, 15, 1, 1), +}; + +static const struct snd_kcontrol_new alc5623_hpr_mixer_controls[] = { +SOC_DAPM_SINGLE("ADC2HP_R Playback Switch", ALC5623_ADC_REC_GAIN, 14, 1, 1), +}; + +static const struct snd_kcontrol_new alc5623_mono_mixer_controls[] = { +SOC_DAPM_SINGLE("ADC2MONO_L Playback Switch", ALC5623_ADC_REC_GAIN, 13, 1, 1), +SOC_DAPM_SINGLE("ADC2MONO_R Playback Switch", ALC5623_ADC_REC_GAIN, 12, 1, 1), +SOC_DAPM_SINGLE("LI2MONO Playback Switch", ALC5623_LINE_IN_VOL, 13, 1, 1), +SOC_DAPM_SINGLE("AUXI2MONO Playback Switch", ALC5623_AUXIN_VOL, 13, 1, 1), +SOC_DAPM_SINGLE("MIC12MONO Playback Switch", ALC5623_MIC_ROUTING_CTRL, 13, 1, 1), +SOC_DAPM_SINGLE("MIC22MONO Playback Switch", ALC5623_MIC_ROUTING_CTRL, 5, 1, 1), +SOC_DAPM_SINGLE("DAC2MONO Playback Switch", ALC5623_STEREO_DAC_VOL, 13, 1, 1), +}; + +static const struct snd_kcontrol_new alc5623_speaker_mixer_controls[] = { +SOC_DAPM_SINGLE("LI2SPK Playback Switch", ALC5623_LINE_IN_VOL, 14, 1, 1), +SOC_DAPM_SINGLE("AUXI2SPK Playback Switch", ALC5623_AUXIN_VOL, 14, 1, 1), +SOC_DAPM_SINGLE("MIC12SPK Playback Switch", ALC5623_MIC_ROUTING_CTRL, 14, 1, 1), +SOC_DAPM_SINGLE("MIC22SPK Playback Switch", ALC5623_MIC_ROUTING_CTRL, 6, 1, 1), +SOC_DAPM_SINGLE("DAC2SPK Playback Switch", ALC5623_STEREO_DAC_VOL, 14, 1, 1), +}; + +/* Left Record Mixer */ +static const struct snd_kcontrol_new alc5623_captureL_mixer_controls[] = { +SOC_DAPM_SINGLE("Mic1 Capture Switch", ALC5623_ADC_REC_MIXER, 14, 1, 1), +SOC_DAPM_SINGLE("Mic2 Capture Switch", ALC5623_ADC_REC_MIXER, 13, 1, 1), +SOC_DAPM_SINGLE("LineInL Capture Switch", ALC5623_ADC_REC_MIXER, 12, 1, 1), +SOC_DAPM_SINGLE("Left AuxI Capture Switch", ALC5623_ADC_REC_MIXER, 11, 1, 1), +SOC_DAPM_SINGLE("HPMixerL Capture Switch", ALC5623_ADC_REC_MIXER, 10, 1, 1), +SOC_DAPM_SINGLE("SPKMixer Capture Switch", ALC5623_ADC_REC_MIXER, 9, 1, 1), +SOC_DAPM_SINGLE("MonoMixer Capture Switch", ALC5623_ADC_REC_MIXER, 8, 1, 1), +}; + +/* Right Record Mixer */ +static const struct snd_kcontrol_new alc5623_captureR_mixer_controls[] = { +SOC_DAPM_SINGLE("Mic1 Capture Switch", ALC5623_ADC_REC_MIXER, 6, 1, 1), +SOC_DAPM_SINGLE("Mic2 Capture Switch", ALC5623_ADC_REC_MIXER, 5, 1, 1), +SOC_DAPM_SINGLE("LineInR Capture Switch", ALC5623_ADC_REC_MIXER, 4, 1, 1), +SOC_DAPM_SINGLE("Right AuxI Capture Switch", ALC5623_ADC_REC_MIXER, 3, 1, 1), +SOC_DAPM_SINGLE("HPMixerR Capture Switch", ALC5623_ADC_REC_MIXER, 2, 1, 1), +SOC_DAPM_SINGLE("SPKMixer Capture Switch", ALC5623_ADC_REC_MIXER, 1, 1, 1), +SOC_DAPM_SINGLE("MonoMixer Capture Switch", ALC5623_ADC_REC_MIXER, 0, 1, 1), +}; + +static const char *alc5623_spk_n_sour_sel[] = { + "RN/-R", "RP/+R", "LN/-R", "Vmid" }; +static const char *alc5623_hpl_out_input_sel[] = { + "Vmid", "HP Left Mix"}; +static const char *alc5623_hpr_out_input_sel[] = { + "Vmid", "HP Right Mix"}; +static const char *alc5623_spkout_input_sel[] = { + "Vmid", "HPOut Mix", "Speaker Mix", "Mono Mix"}; +static const char *alc5623_aux_out_input_sel[] = { + "Vmid", "HPOut Mix", "Speaker Mix", "Mono Mix"}; + +/* auxout output mux */ +static const struct soc_enum alc5623_aux_out_input_enum = +SOC_ENUM_SINGLE(ALC5623_OUTPUT_MIXER_CTRL, 6, 4, alc5623_aux_out_input_sel); +static const struct snd_kcontrol_new alc5623_auxout_mux_controls = +SOC_DAPM_ENUM("Route", alc5623_aux_out_input_enum); + +/* speaker output mux */ +static const struct soc_enum alc5623_spkout_input_enum = +SOC_ENUM_SINGLE(ALC5623_OUTPUT_MIXER_CTRL, 10, 4, alc5623_spkout_input_sel); +static const struct snd_kcontrol_new alc5623_spkout_mux_controls = +SOC_DAPM_ENUM("Route", alc5623_spkout_input_enum); + +/* headphone left output mux */ +static const struct soc_enum alc5623_hpl_out_input_enum = +SOC_ENUM_SINGLE(ALC5623_OUTPUT_MIXER_CTRL, 9, 2, alc5623_hpl_out_input_sel); +static const struct snd_kcontrol_new alc5623_hpl_out_mux_controls = +SOC_DAPM_ENUM("Route", alc5623_hpl_out_input_enum); + +/* headphone right output mux */ +static const struct soc_enum alc5623_hpr_out_input_enum = +SOC_ENUM_SINGLE(ALC5623_OUTPUT_MIXER_CTRL, 8, 2, alc5623_hpr_out_input_sel); +static const struct snd_kcontrol_new alc5623_hpr_out_mux_controls = +SOC_DAPM_ENUM("Route", alc5623_hpr_out_input_enum); + +/* speaker output N select */ +static const struct soc_enum alc5623_spk_n_sour_enum = +SOC_ENUM_SINGLE(ALC5623_OUTPUT_MIXER_CTRL, 14, 4, alc5623_spk_n_sour_sel); +static const struct snd_kcontrol_new alc5623_spkoutn_mux_controls = +SOC_DAPM_ENUM("Route", alc5623_spk_n_sour_enum); + +static const struct snd_soc_dapm_widget alc5623_dapm_widgets[] = { +/* Muxes */ +SND_SOC_DAPM_MUX("AuxOut Mux", SND_SOC_NOPM, 0, 0, + &alc5623_auxout_mux_controls), +SND_SOC_DAPM_MUX("SpeakerOut Mux", SND_SOC_NOPM, 0, 0, + &alc5623_spkout_mux_controls), +SND_SOC_DAPM_MUX("Left Headphone Mux", SND_SOC_NOPM, 0, 0, + &alc5623_hpl_out_mux_controls), +SND_SOC_DAPM_MUX("Right Headphone Mux", SND_SOC_NOPM, 0, 0, + &alc5623_hpr_out_mux_controls), +SND_SOC_DAPM_MUX("SpeakerOut N Mux", SND_SOC_NOPM, 0, 0, + &alc5623_spkoutn_mux_controls), + +/* output mixers */ +SND_SOC_DAPM_MIXER("HP Mix", SND_SOC_NOPM, 0, 0, + &alc5623_hp_mixer_controls[0], + ARRAY_SIZE(alc5623_hp_mixer_controls)), +SND_SOC_DAPM_MIXER("HPR Mix", ALC5623_PWR_MANAG_ADD2, 4, 0, + &alc5623_hpr_mixer_controls[0], + ARRAY_SIZE(alc5623_hpr_mixer_controls)), +SND_SOC_DAPM_MIXER("HPL Mix", ALC5623_PWR_MANAG_ADD2, 5, 0, + &alc5623_hpl_mixer_controls[0], + ARRAY_SIZE(alc5623_hpl_mixer_controls)), +SND_SOC_DAPM_MIXER("HPOut Mix", SND_SOC_NOPM, 0, 0, NULL, 0), +SND_SOC_DAPM_MIXER("Mono Mix", ALC5623_PWR_MANAG_ADD2, 2, 0, + &alc5623_mono_mixer_controls[0], + ARRAY_SIZE(alc5623_mono_mixer_controls)), +SND_SOC_DAPM_MIXER("Speaker Mix", ALC5623_PWR_MANAG_ADD2, 3, 0, + &alc5623_speaker_mixer_controls[0], + ARRAY_SIZE(alc5623_speaker_mixer_controls)), + +/* input mixers */ +SND_SOC_DAPM_MIXER("Left Capture Mix", ALC5623_PWR_MANAG_ADD2, 1, 0, + &alc5623_captureL_mixer_controls[0], + ARRAY_SIZE(alc5623_captureL_mixer_controls)), +SND_SOC_DAPM_MIXER("Right Capture Mix", ALC5623_PWR_MANAG_ADD2, 0, 0, + &alc5623_captureR_mixer_controls[0], + ARRAY_SIZE(alc5623_captureR_mixer_controls)), + +SND_SOC_DAPM_DAC("Left DAC", "Left HiFi Playback", + ALC5623_PWR_MANAG_ADD2, 9, 0), +SND_SOC_DAPM_DAC("Right DAC", "Right HiFi Playback", + ALC5623_PWR_MANAG_ADD2, 8, 0), +SND_SOC_DAPM_MIXER("I2S Mix", ALC5623_PWR_MANAG_ADD1, 15, 0, NULL, 0), +SND_SOC_DAPM_MIXER("AuxI Mix", SND_SOC_NOPM, 0, 0, NULL, 0), +SND_SOC_DAPM_MIXER("Line Mix", SND_SOC_NOPM, 0, 0, NULL, 0), +SND_SOC_DAPM_ADC("Left ADC", "Left HiFi Capture", + ALC5623_PWR_MANAG_ADD2, 7, 0), +SND_SOC_DAPM_ADC("Right ADC", "Right HiFi Capture", + ALC5623_PWR_MANAG_ADD2, 6, 0), +SND_SOC_DAPM_PGA("Left Headphone", ALC5623_PWR_MANAG_ADD3, 10, 0, NULL, 0), +SND_SOC_DAPM_PGA("Right Headphone", ALC5623_PWR_MANAG_ADD3, 9, 0, NULL, 0), +SND_SOC_DAPM_PGA("SpeakerOut", ALC5623_PWR_MANAG_ADD3, 12, 0, NULL, 0), +SND_SOC_DAPM_PGA("Left AuxOut", ALC5623_PWR_MANAG_ADD3, 14, 0, NULL, 0), +SND_SOC_DAPM_PGA("Right AuxOut", ALC5623_PWR_MANAG_ADD3, 13, 0, NULL, 0), +SND_SOC_DAPM_PGA("Left LineIn", ALC5623_PWR_MANAG_ADD3, 7, 0, NULL, 0), +SND_SOC_DAPM_PGA("Right LineIn", ALC5623_PWR_MANAG_ADD3, 6, 0, NULL, 0), +SND_SOC_DAPM_PGA("Left AuxI", ALC5623_PWR_MANAG_ADD3, 5, 0, NULL, 0), +SND_SOC_DAPM_PGA("Right AuxI", ALC5623_PWR_MANAG_ADD3, 4, 0, NULL, 0), +SND_SOC_DAPM_PGA("MIC1 PGA", ALC5623_PWR_MANAG_ADD3, 3, 0, NULL, 0), +SND_SOC_DAPM_PGA("MIC2 PGA", ALC5623_PWR_MANAG_ADD3, 2, 0, NULL, 0), +SND_SOC_DAPM_PGA("MIC1 Pre Amp", ALC5623_PWR_MANAG_ADD3, 1, 0, NULL, 0), +SND_SOC_DAPM_PGA("MIC2 Pre Amp", ALC5623_PWR_MANAG_ADD3, 0, 0, NULL, 0), +SND_SOC_DAPM_MICBIAS("Mic Bias1", ALC5623_PWR_MANAG_ADD1, 11, 0), + +SND_SOC_DAPM_OUTPUT("AUXOUTL"), +SND_SOC_DAPM_OUTPUT("AUXOUTR"), +SND_SOC_DAPM_OUTPUT("HPL"), +SND_SOC_DAPM_OUTPUT("HPR"), +SND_SOC_DAPM_OUTPUT("SPKOUT"), +SND_SOC_DAPM_OUTPUT("SPKOUTN"), +SND_SOC_DAPM_INPUT("LINEINL"), +SND_SOC_DAPM_INPUT("LINEINR"), +SND_SOC_DAPM_INPUT("AUXINL"), +SND_SOC_DAPM_INPUT("AUXINR"), +SND_SOC_DAPM_INPUT("MIC1"), +SND_SOC_DAPM_INPUT("MIC2"), +SND_SOC_DAPM_VMID("Vmid"), +}; + +static const char *alc5623_amp_names[] = {"AB Amp", "D Amp"}; +static const struct soc_enum alc5623_amp_enum = + SOC_ENUM_SINGLE(ALC5623_OUTPUT_MIXER_CTRL, 13, 2, alc5623_amp_names); +static const struct snd_kcontrol_new alc5623_amp_mux_controls = + SOC_DAPM_ENUM("Route", alc5623_amp_enum); + +static const struct snd_soc_dapm_widget alc5623_dapm_amp_widgets[] = { +SND_SOC_DAPM_PGA_E("D Amp", ALC5623_PWR_MANAG_ADD2, 14, 0, NULL, 0, + amp_mixer_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), +SND_SOC_DAPM_PGA("AB Amp", ALC5623_PWR_MANAG_ADD2, 15, 0, NULL, 0), +SND_SOC_DAPM_MUX("AB-D Amp Mux", SND_SOC_NOPM, 0, 0, + &alc5623_amp_mux_controls), +}; + +static const struct snd_soc_dapm_route intercon[] = { + /* virtual mixer - mixes left & right channels */ + {"I2S Mix", NULL, "Left DAC"}, + {"I2S Mix", NULL, "Right DAC"}, + {"Line Mix", NULL, "Right LineIn"}, + {"Line Mix", NULL, "Left LineIn"}, + {"AuxI Mix", NULL, "Left AuxI"}, + {"AuxI Mix", NULL, "Right AuxI"}, + {"AUXOUTL", NULL, "Left AuxOut"}, + {"AUXOUTR", NULL, "Right AuxOut"}, + + /* HP mixer */ + {"HPL Mix", "ADC2HP_L Playback Switch", "Left Capture Mix"}, + {"HPL Mix", NULL, "HP Mix"}, + {"HPR Mix", "ADC2HP_R Playback Switch", "Right Capture Mix"}, + {"HPR Mix", NULL, "HP Mix"}, + {"HP Mix", "LI2HP Playback Switch", "Line Mix"}, + {"HP Mix", "AUXI2HP Playback Switch", "AuxI Mix"}, + {"HP Mix", "MIC12HP Playback Switch", "MIC1 PGA"}, + {"HP Mix", "MIC22HP Playback Switch", "MIC2 PGA"}, + {"HP Mix", "DAC2HP Playback Switch", "I2S Mix"}, + + /* speaker mixer */ + {"Speaker Mix", "LI2SPK Playback Switch", "Line Mix"}, + {"Speaker Mix", "AUXI2SPK Playback Switch", "AuxI Mix"}, + {"Speaker Mix", "MIC12SPK Playback Switch", "MIC1 PGA"}, + {"Speaker Mix", "MIC22SPK Playback Switch", "MIC2 PGA"}, + {"Speaker Mix", "DAC2SPK Playback Switch", "I2S Mix"}, + + /* mono mixer */ + {"Mono Mix", "ADC2MONO_L Playback Switch", "Left Capture Mix"}, + {"Mono Mix", "ADC2MONO_R Playback Switch", "Right Capture Mix"}, + {"Mono Mix", "LI2MONO Playback Switch", "Line Mix"}, + {"Mono Mix", "AUXI2MONO Playback Switch", "AuxI Mix"}, + {"Mono Mix", "MIC12MONO Playback Switch", "MIC1 PGA"}, + {"Mono Mix", "MIC22MONO Playback Switch", "MIC2 PGA"}, + {"Mono Mix", "DAC2MONO Playback Switch", "I2S Mix"}, + + /* Left record mixer */ + {"Left Capture Mix", "LineInL Capture Switch", "LINEINL"}, + {"Left Capture Mix", "Left AuxI Capture Switch", "AUXINL"}, + {"Left Capture Mix", "Mic1 Capture Switch", "MIC1 Pre Amp"}, + {"Left Capture Mix", "Mic2 Capture Switch", "MIC2 Pre Amp"}, + {"Left Capture Mix", "HPMixerL Capture Switch", "HPL Mix"}, + {"Left Capture Mix", "SPKMixer Capture Switch", "Speaker Mix"}, + {"Left Capture Mix", "MonoMixer Capture Switch", "Mono Mix"}, + + /*Right record mixer */ + {"Right Capture Mix", "LineInR Capture Switch", "LINEINR"}, + {"Right Capture Mix", "Right AuxI Capture Switch", "AUXINR"}, + {"Right Capture Mix", "Mic1 Capture Switch", "MIC1 Pre Amp"}, + {"Right Capture Mix", "Mic2 Capture Switch", "MIC2 Pre Amp"}, + {"Right Capture Mix", "HPMixerR Capture Switch", "HPR Mix"}, + {"Right Capture Mix", "SPKMixer Capture Switch", "Speaker Mix"}, + {"Right Capture Mix", "MonoMixer Capture Switch", "Mono Mix"}, + + /* headphone left mux */ + {"Left Headphone Mux", "HP Left Mix", "HPL Mix"}, + {"Left Headphone Mux", "Vmid", "Vmid"}, + + /* headphone right mux */ + {"Right Headphone Mux", "HP Right Mix", "HPR Mix"}, + {"Right Headphone Mux", "Vmid", "Vmid"}, + + /* speaker out mux */ + {"SpeakerOut Mux", "Vmid", "Vmid"}, + {"SpeakerOut Mux", "HPOut Mix", "HPOut Mix"}, + {"SpeakerOut Mux", "Speaker Mix", "Speaker Mix"}, + {"SpeakerOut Mux", "Mono Mix", "Mono Mix"}, + + /* Mono/Aux Out mux */ + {"AuxOut Mux", "Vmid", "Vmid"}, + {"AuxOut Mux", "HPOut Mix", "HPOut Mix"}, + {"AuxOut Mux", "Speaker Mix", "Speaker Mix"}, + {"AuxOut Mux", "Mono Mix", "Mono Mix"}, + + /* output pga */ + {"HPL", NULL, "Left Headphone"}, + {"Left Headphone", NULL, "Left Headphone Mux"}, + {"HPR", NULL, "Right Headphone"}, + {"Right Headphone", NULL, "Right Headphone Mux"}, + {"Left AuxOut", NULL, "AuxOut Mux"}, + {"Right AuxOut", NULL, "AuxOut Mux"}, + + /* input pga */ + {"Left LineIn", NULL, "LINEINL"}, + {"Right LineIn", NULL, "LINEINR"}, + {"Left AuxI", NULL, "AUXINL"}, + {"Right AuxI", NULL, "AUXINR"}, + {"MIC1 Pre Amp", NULL, "MIC1"}, + {"MIC2 Pre Amp", NULL, "MIC2"}, + {"MIC1 PGA", NULL, "MIC1 Pre Amp"}, + {"MIC2 PGA", NULL, "MIC2 Pre Amp"}, + + /* left ADC */ + {"Left ADC", NULL, "Left Capture Mix"}, + + /* right ADC */ + {"Right ADC", NULL, "Right Capture Mix"}, + + {"SpeakerOut N Mux", "RN/-R", "SpeakerOut"}, + {"SpeakerOut N Mux", "RP/+R", "SpeakerOut"}, + {"SpeakerOut N Mux", "LN/-R", "SpeakerOut"}, + {"SpeakerOut N Mux", "Vmid", "Vmid"}, + + {"SPKOUT", NULL, "SpeakerOut"}, + {"SPKOUTN", NULL, "SpeakerOut N Mux"}, +}; + +static const struct snd_soc_dapm_route intercon_spk[] = { + {"SpeakerOut", NULL, "SpeakerOut Mux"}, +}; + +static const struct snd_soc_dapm_route intercon_amp_spk[] = { + {"AB Amp", NULL, "SpeakerOut Mux"}, + {"D Amp", NULL, "SpeakerOut Mux"}, + {"AB-D Amp Mux", "AB Amp", "AB Amp"}, + {"AB-D Amp Mux", "D Amp", "D Amp"}, + {"SpeakerOut", NULL, "AB-D Amp Mux"}, +}; + +/* PLL divisors */ +struct _pll_div { + u32 pll_in; + u32 pll_out; + u16 regvalue; +}; + +/* Note : pll code from original alc5623 driver. Not sure of how good it is */ +/* usefull only for master mode */ +static const struct _pll_div codec_master_pll_div[] = { + + { 2048000, 8192000, 0x0ea0}, + { 3686400, 8192000, 0x4e27}, + { 12000000, 8192000, 0x456b}, + { 13000000, 8192000, 0x495f}, + { 13100000, 8192000, 0x0320}, + { 2048000, 11289600, 0xf637}, + { 3686400, 11289600, 0x2f22}, + { 12000000, 11289600, 0x3e2f}, + { 13000000, 11289600, 0x4d5b}, + { 13100000, 11289600, 0x363b}, + { 2048000, 16384000, 0x1ea0}, + { 3686400, 16384000, 0x9e27}, + { 12000000, 16384000, 0x452b}, + { 13000000, 16384000, 0x542f}, + { 13100000, 16384000, 0x03a0}, + { 2048000, 16934400, 0xe625}, + { 3686400, 16934400, 0x9126}, + { 12000000, 16934400, 0x4d2c}, + { 13000000, 16934400, 0x742f}, + { 13100000, 16934400, 0x3c27}, + { 2048000, 22579200, 0x2aa0}, + { 3686400, 22579200, 0x2f20}, + { 12000000, 22579200, 0x7e2f}, + { 13000000, 22579200, 0x742f}, + { 13100000, 22579200, 0x3c27}, + { 2048000, 24576000, 0x2ea0}, + { 3686400, 24576000, 0xee27}, + { 12000000, 24576000, 0x2915}, + { 13000000, 24576000, 0x772e}, + { 13100000, 24576000, 0x0d20}, +}; + +static const struct _pll_div codec_slave_pll_div[] = { + + { 1024000, 16384000, 0x3ea0}, + { 1411200, 22579200, 0x3ea0}, + { 1536000, 24576000, 0x3ea0}, + { 2048000, 16384000, 0x1ea0}, + { 2822400, 22579200, 0x1ea0}, + { 3072000, 24576000, 0x1ea0}, + +}; + +static int alc5623_set_dai_pll(struct snd_soc_dai *codec_dai, int pll_id, + int source, unsigned int freq_in, unsigned int freq_out) +{ + int i; + struct snd_soc_codec *codec = codec_dai->codec; + int gbl_clk = 0, pll_div = 0; + u16 reg; + + if (pll_id < ALC5623_PLL_FR_MCLK || pll_id > ALC5623_PLL_FR_BCK) + return -ENODEV; + + /* Disable PLL power */ + snd_soc_update_bits(codec, ALC5623_PWR_MANAG_ADD2, + ALC5623_PWR_ADD2_PLL, + 0); + + /* pll is not used in slave mode */ + reg = snd_soc_read(codec, ALC5623_DAI_CONTROL); + if (reg & ALC5623_DAI_SDP_SLAVE_MODE) + return 0; + + if (!freq_in || !freq_out) + return 0; + + switch (pll_id) { + case ALC5623_PLL_FR_MCLK: + for (i = 0; i < ARRAY_SIZE(codec_master_pll_div); i++) { + if (codec_master_pll_div[i].pll_in == freq_in + && codec_master_pll_div[i].pll_out == freq_out) { + /* PLL source from MCLK */ + pll_div = codec_master_pll_div[i].regvalue; + break; + } + } + break; + case ALC5623_PLL_FR_BCK: + for (i = 0; i < ARRAY_SIZE(codec_slave_pll_div); i++) { + if (codec_slave_pll_div[i].pll_in == freq_in + && codec_slave_pll_div[i].pll_out == freq_out) { + /* PLL source from Bitclk */ + gbl_clk = ALC5623_GBL_CLK_PLL_SOUR_SEL_BITCLK; + pll_div = codec_slave_pll_div[i].regvalue; + break; + } + } + break; + default: + return -EINVAL; + } + + if (!pll_div) + return -EINVAL; + + snd_soc_write(codec, ALC5623_GLOBAL_CLK_CTRL_REG, gbl_clk); + snd_soc_write(codec, ALC5623_PLL_CTRL, pll_div); + snd_soc_update_bits(codec, ALC5623_PWR_MANAG_ADD2, + ALC5623_PWR_ADD2_PLL, + ALC5623_PWR_ADD2_PLL); + gbl_clk |= ALC5623_GBL_CLK_SYS_SOUR_SEL_PLL; + snd_soc_write(codec, ALC5623_GLOBAL_CLK_CTRL_REG, gbl_clk); + + return 0; +} + +struct _coeff_div { + u16 fs; + u16 regvalue; +}; + +/* codec hifi mclk (after PLL) clock divider coefficients */ +/* values inspired from column BCLK=32Fs of Appendix A table */ +static const struct _coeff_div coeff_div[] = { + {256*8, 0x3a69}, + {384*8, 0x3c6b}, + {256*4, 0x2a69}, + {384*4, 0x2c6b}, + {256*2, 0x1a69}, + {384*2, 0x1c6b}, + {256*1, 0x0a69}, + {384*1, 0x0c6b}, +}; + +static int get_coeff(struct snd_soc_codec *codec, int rate) +{ + struct alc5623_priv *alc5623 = snd_soc_codec_get_drvdata(codec); + int i; + + for (i = 0; i < ARRAY_SIZE(coeff_div); i++) { + if (coeff_div[i].fs * rate == alc5623->sysclk) + return i; + } + return -EINVAL; +} + +/* + * Clock after PLL and dividers + */ +static int alc5623_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 alc5623_priv *alc5623 = snd_soc_codec_get_drvdata(codec); + + switch (freq) { + case 8192000: + case 11289600: + case 12288000: + case 16384000: + case 16934400: + case 18432000: + case 22579200: + case 24576000: + alc5623->sysclk = freq; + return 0; + } + return -EINVAL; +} + +static int alc5623_set_dai_fmt(struct snd_soc_dai *codec_dai, + unsigned int fmt) +{ + struct snd_soc_codec *codec = codec_dai->codec; + u16 iface = 0; + + /* set master/slave audio interface */ + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { + case SND_SOC_DAIFMT_CBM_CFM: + iface = ALC5623_DAI_SDP_MASTER_MODE; + break; + case SND_SOC_DAIFMT_CBS_CFS: + iface = ALC5623_DAI_SDP_SLAVE_MODE; + break; + default: + return -EINVAL; + } + + /* interface format */ + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { + case SND_SOC_DAIFMT_I2S: + iface |= ALC5623_DAI_I2S_DF_I2S; + break; + case SND_SOC_DAIFMT_RIGHT_J: + iface |= ALC5623_DAI_I2S_DF_RIGHT; + break; + case SND_SOC_DAIFMT_LEFT_J: + iface |= ALC5623_DAI_I2S_DF_LEFT; + break; + case SND_SOC_DAIFMT_DSP_A: + iface |= ALC5623_DAI_I2S_DF_PCM; + break; + case SND_SOC_DAIFMT_DSP_B: + iface |= ALC5623_DAI_I2S_DF_PCM | ALC5623_DAI_I2S_PCM_MODE; + break; + default: + return -EINVAL; + } + + /* clock inversion */ + switch (fmt & SND_SOC_DAIFMT_INV_MASK) { + case SND_SOC_DAIFMT_NB_NF: + break; + case SND_SOC_DAIFMT_IB_IF: + iface |= ALC5623_DAI_MAIN_I2S_BCLK_POL_CTRL; + break; + case SND_SOC_DAIFMT_IB_NF: + iface |= ALC5623_DAI_MAIN_I2S_BCLK_POL_CTRL; + break; + case SND_SOC_DAIFMT_NB_IF: + break; + default: + return -EINVAL; + } + + return snd_soc_write(codec, ALC5623_DAI_CONTROL, iface); +} + +static int alc5623_pcm_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_codec *codec = rtd->codec; + struct alc5623_priv *alc5623 = snd_soc_codec_get_drvdata(codec); + int coeff, rate; + u16 iface; + + iface = snd_soc_read(codec, ALC5623_DAI_CONTROL); + iface &= ~ALC5623_DAI_I2S_DL_MASK; + + /* bit size */ + switch (params_format(params)) { + case SNDRV_PCM_FORMAT_S16_LE: + iface |= ALC5623_DAI_I2S_DL_16; + break; + case SNDRV_PCM_FORMAT_S20_3LE: + iface |= ALC5623_DAI_I2S_DL_20; + break; + case SNDRV_PCM_FORMAT_S24_LE: + iface |= ALC5623_DAI_I2S_DL_24; + break; + case SNDRV_PCM_FORMAT_S32_LE: + iface |= ALC5623_DAI_I2S_DL_32; + break; + default: + return -EINVAL; + } + + /* set iface & srate */ + snd_soc_write(codec, ALC5623_DAI_CONTROL, iface); + rate = params_rate(params); + coeff = get_coeff(codec, rate); + if (coeff < 0) + return -EINVAL; + + coeff = coeff_div[coeff].regvalue; + dev_dbg(codec->dev, "%s: sysclk=%d,rate=%d,coeff=0x%04x\n", + __func__, alc5623->sysclk, rate, coeff); + snd_soc_write(codec, ALC5623_STEREO_AD_DA_CLK_CTRL, coeff); + + return 0; +} + +static int alc5623_mute(struct snd_soc_dai *dai, int mute) +{ + struct snd_soc_codec *codec = dai->codec; + u16 hp_mute = ALC5623_MISC_M_DAC_L_INPUT | ALC5623_MISC_M_DAC_R_INPUT; + u16 mute_reg = snd_soc_read(codec, ALC5623_MISC_CTRL) & ~hp_mute; + + if (mute) + mute_reg |= hp_mute; + + return snd_soc_write(codec, ALC5623_MISC_CTRL, mute_reg); +} + +#define ALC5623_ADD2_POWER_EN (ALC5623_PWR_ADD2_VREF \ + | ALC5623_PWR_ADD2_DAC_REF_CIR) + +#define ALC5623_ADD3_POWER_EN (ALC5623_PWR_ADD3_MAIN_BIAS \ + | ALC5623_PWR_ADD3_MIC1_BOOST_AD) + +#define ALC5623_ADD1_POWER_EN \ + (ALC5623_PWR_ADD1_SHORT_CURR_DET_EN | ALC5623_PWR_ADD1_SOFTGEN_EN \ + | ALC5623_PWR_ADD1_DEPOP_BUF_HP | ALC5623_PWR_ADD1_HP_OUT_AMP \ + | ALC5623_PWR_ADD1_HP_OUT_ENH_AMP) + +#define ALC5623_ADD1_POWER_EN_5622 \ + (ALC5623_PWR_ADD1_SHORT_CURR_DET_EN \ + | ALC5623_PWR_ADD1_HP_OUT_AMP) + +static void enable_power_depop(struct snd_soc_codec *codec) +{ + struct alc5623_priv *alc5623 = snd_soc_codec_get_drvdata(codec); + + snd_soc_update_bits(codec, ALC5623_PWR_MANAG_ADD1, + ALC5623_PWR_ADD1_SOFTGEN_EN, + ALC5623_PWR_ADD1_SOFTGEN_EN); + + snd_soc_write(codec, ALC5623_PWR_MANAG_ADD3, ALC5623_ADD3_POWER_EN); + + snd_soc_update_bits(codec, ALC5623_MISC_CTRL, + ALC5623_MISC_HP_DEPOP_MODE2_EN, + ALC5623_MISC_HP_DEPOP_MODE2_EN); + + msleep(500); + + snd_soc_write(codec, ALC5623_PWR_MANAG_ADD2, ALC5623_ADD2_POWER_EN); + + /* avoid writing '1' into 5622 reserved bits */ + if (alc5623->id == 0x22) + snd_soc_write(codec, ALC5623_PWR_MANAG_ADD1, + ALC5623_ADD1_POWER_EN_5622); + else + snd_soc_write(codec, ALC5623_PWR_MANAG_ADD1, + ALC5623_ADD1_POWER_EN); + + /* disable HP Depop2 */ + snd_soc_update_bits(codec, ALC5623_MISC_CTRL, + ALC5623_MISC_HP_DEPOP_MODE2_EN, + 0); + +} + +static int alc5623_set_bias_level(struct snd_soc_codec *codec, + enum snd_soc_bias_level level) +{ + switch (level) { + case SND_SOC_BIAS_ON: + enable_power_depop(codec); + break; + case SND_SOC_BIAS_PREPARE: + break; + case SND_SOC_BIAS_STANDBY: + /* everything off except vref/vmid, */ + snd_soc_write(codec, ALC5623_PWR_MANAG_ADD2, + ALC5623_PWR_ADD2_VREF); + snd_soc_write(codec, ALC5623_PWR_MANAG_ADD3, + ALC5623_PWR_ADD3_MAIN_BIAS); + break; + case SND_SOC_BIAS_OFF: + /* everything off, dac mute, inactive */ + snd_soc_write(codec, ALC5623_PWR_MANAG_ADD2, 0); + snd_soc_write(codec, ALC5623_PWR_MANAG_ADD3, 0); + snd_soc_write(codec, ALC5623_PWR_MANAG_ADD1, 0); + break; + } + codec->bias_level = level; + return 0; +} + +#define ALC5623_FORMATS (SNDRV_PCM_FMTBIT_S16_LE \ + | SNDRV_PCM_FMTBIT_S24_LE \ + | SNDRV_PCM_FMTBIT_S32_LE) + +static struct snd_soc_dai_ops alc5623_dai_ops = { + .hw_params = alc5623_pcm_hw_params, + .digital_mute = alc5623_mute, + .set_fmt = alc5623_set_dai_fmt, + .set_sysclk = alc5623_set_dai_sysclk, + .set_pll = alc5623_set_dai_pll, +}; + +static struct snd_soc_dai_driver alc5623_dai = { + .name = "alc5623-hifi", + .playback = { + .stream_name = "Playback", + .channels_min = 1, + .channels_max = 2, + .rate_min = 8000, + .rate_max = 48000, + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = ALC5623_FORMATS,}, + .capture = { + .stream_name = "Capture", + .channels_min = 1, + .channels_max = 2, + .rate_min = 8000, + .rate_max = 48000, + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = ALC5623_FORMATS,}, + + .ops = &alc5623_dai_ops, +}; + +static int alc5623_suspend(struct snd_soc_codec *codec, pm_message_t mesg) +{ + alc5623_set_bias_level(codec, SND_SOC_BIAS_OFF); + return 0; +} + +static int alc5623_resume(struct snd_soc_codec *codec) +{ + int i, step = codec->driver->reg_cache_step; + u16 *cache = codec->reg_cache; + + /* Sync reg_cache with the hardware */ + for (i = 2 ; i < codec->driver->reg_cache_size ; i += step) + snd_soc_write(codec, i, cache[i]); + + alc5623_set_bias_level(codec, SND_SOC_BIAS_STANDBY); + + /* charge alc5623 caps */ + if (codec->suspend_bias_level == SND_SOC_BIAS_ON) { + alc5623_set_bias_level(codec, SND_SOC_BIAS_STANDBY); + codec->bias_level = SND_SOC_BIAS_ON; + alc5623_set_bias_level(codec, codec->bias_level); + } + + return 0; +} + +static int alc5623_probe(struct snd_soc_codec *codec) +{ + struct alc5623_priv *alc5623 = snd_soc_codec_get_drvdata(codec); + int ret; + + ret = snd_soc_codec_set_cache_io(codec, 8, 16, alc5623->control_type); + if (ret < 0) { + dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); + return ret; + } + + alc5623_reset(codec); + alc5623_fill_cache(codec); + + /* power on device */ + alc5623_set_bias_level(codec, SND_SOC_BIAS_STANDBY); + + if (alc5623->add_ctrl) { + snd_soc_write(codec, ALC5623_ADD_CTRL_REG, + alc5623->add_ctrl); + } + + if (alc5623->jack_det_ctrl) { + snd_soc_write(codec, ALC5623_JACK_DET_CTRL, + alc5623->jack_det_ctrl); + } + + switch (alc5623->id) { + default: + case 0x21: + snd_soc_add_controls(codec, rt5621_vol_snd_controls, + ARRAY_SIZE(rt5621_vol_snd_controls)); + break; + case 0x22: + snd_soc_add_controls(codec, rt5622_vol_snd_controls, + ARRAY_SIZE(rt5622_vol_snd_controls)); + break; + case 0x23: + snd_soc_add_controls(codec, alc5623_vol_snd_controls, + ARRAY_SIZE(alc5623_vol_snd_controls)); + break; + } + + snd_soc_add_controls(codec, alc5623_snd_controls, + ARRAY_SIZE(alc5623_snd_controls)); + + snd_soc_dapm_new_controls(codec, alc5623_dapm_widgets, + ARRAY_SIZE(alc5623_dapm_widgets)); + + /* set up audio path interconnects */ + snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon)); + + switch (alc5623->id) { + default: + case 0x21: + case 0x22: + snd_soc_dapm_new_controls(codec, alc5623_dapm_amp_widgets, + ARRAY_SIZE(alc5623_dapm_amp_widgets)); + snd_soc_dapm_add_routes(codec, intercon_amp_spk, + ARRAY_SIZE(intercon_amp_spk)); + break; + case 0x23: + snd_soc_dapm_add_routes(codec, intercon_spk, + ARRAY_SIZE(intercon_spk)); + break; + } + + return ret; +} + +/* power down chip */ +static int alc5623_remove(struct snd_soc_codec *codec) +{ + alc5623_set_bias_level(codec, SND_SOC_BIAS_OFF); + return 0; +} + +static struct snd_soc_codec_driver soc_codec_device_alc5623 = { + .probe = alc5623_probe, + .remove = alc5623_remove, + .suspend = alc5623_suspend, + .resume = alc5623_resume, + .set_bias_level = alc5623_set_bias_level, + .reg_cache_size = ALC5623_VENDOR_ID2+2, + .reg_word_size = sizeof(u16), + .reg_cache_step = 2, +}; + +/* + * ALC5623 2 wire address is determined by A1 pin + * state during powerup. + * low = 0x1a + * high = 0x1b + */ +static int alc5623_i2c_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct alc5623_platform_data *pdata; + struct alc5623_priv *alc5623; + int ret, vid1, vid2; + + vid1 = i2c_smbus_read_word_data(client, ALC5623_VENDOR_ID1); + if (vid1 < 0) { + dev_err(&client->dev, "failed to read I2C\n"); + return -EIO; + } + vid1 = ((vid1 & 0xff) << 8) | (vid1 >> 8); + + vid2 = i2c_smbus_read_byte_data(client, ALC5623_VENDOR_ID2); + if (vid2 < 0) { + dev_err(&client->dev, "failed to read I2C\n"); + return -EIO; + } + + if ((vid1 != 0x10ec) || (vid2 != id->driver_data)) { + dev_err(&client->dev, "unknown or wrong codec\n"); + dev_err(&client->dev, "Expected %x:%lx, got %x:%x\n", + 0x10ec, id->driver_data, + vid1, vid2); + return -ENODEV; + } + + dev_dbg(&client->dev, "Found codec id : alc56%02x\n", vid2); + + alc5623 = kzalloc(sizeof(struct alc5623_priv), GFP_KERNEL); + if (alc5623 == NULL) { + ret = -ENOMEM; + goto err; + } + + pdata = client->dev.platform_data; + if (pdata) { + alc5623->add_ctrl = pdata->add_ctrl; + alc5623->jack_det_ctrl = pdata->jack_det_ctrl; + } + + alc5623->id = vid2; + switch (alc5623->id) { + case 0x21: + alc5623_dai.name = "alc5621-hifi"; + break; + case 0x22: + alc5623_dai.name = "alc5622-hifi"; + break; + default: + case 0x23: + alc5623_dai.name = "alc5623-hifi"; + break; + } + + i2c_set_clientdata(client, alc5623); + alc5623->control_data = client; + alc5623->control_type = SND_SOC_I2C; + mutex_init(&alc5623->mutex); + + ret = snd_soc_register_codec(&client->dev, + &soc_codec_device_alc5623, &alc5623_dai, 1); + if (ret != 0) { + dev_err(&client->dev, "Failed to register codec: %d\n", ret); + goto err; + } + + return 0; + +err: + return ret; +} + +static int alc5623_i2c_remove(struct i2c_client *client) +{ + struct alc5623_priv *alc5623 = i2c_get_clientdata(client); + + snd_soc_unregister_codec(&client->dev); + kfree(alc5623); + return 0; +} + +static const struct i2c_device_id alc5623_i2c_table[] = { + {"alc5621", 0x21}, + {"alc5622", 0x22}, + {"alc5623", 0x23}, + {} +}; +MODULE_DEVICE_TABLE(i2c, alc5623_i2c_table); + +/* i2c codec control layer */ +static struct i2c_driver alc5623_i2c_driver = { + .driver = { + .name = "alc562x-codec", + .owner = THIS_MODULE, + }, + .probe = alc5623_i2c_probe, + .remove = __devexit_p(alc5623_i2c_remove), + .id_table = alc5623_i2c_table, +}; + +static int __init alc5623_modinit(void) +{ + int ret; + + ret = i2c_add_driver(&alc5623_i2c_driver); + if (ret != 0) { + printk(KERN_ERR "%s: can't add i2c driver", __func__); + return ret; + } + + return ret; +} +module_init(alc5623_modinit); + +static void __exit alc5623_modexit(void) +{ + i2c_del_driver(&alc5623_i2c_driver); +} +module_exit(alc5623_modexit); + +MODULE_DESCRIPTION("ASoC alc5621/2/3 driver"); +MODULE_AUTHOR("Arnaud Patard "); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/codecs/alc5623.h b/sound/soc/codecs/alc5623.h new file mode 100644 index 000000000000..f3d68260d425 --- /dev/null +++ b/sound/soc/codecs/alc5623.h @@ -0,0 +1,161 @@ +/* + * alc5623.h -- alc562[123] ALSA Soc Audio driver + * + * Copyright 2008 Realtek Microelectronics + * Copyright 2010 Arnaud Patard + * + * Author: flove + * Arnaud Patard + * + * 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. + * + */ + +#ifndef _ALC5623_H +#define _ALC5623_H + +#define ALC5623_RESET 0x00 +/* 5621 5622 5623 */ +/* speaker output vol 2 2 */ +/* line output vol 4 2 */ +/* HP output vol 4 0 4 */ +#define ALC5623_SPK_OUT_VOL 0x02 +#define ALC5623_HP_OUT_VOL 0x04 +#define ALC5623_MONO_AUX_OUT_VOL 0x06 +#define ALC5623_AUXIN_VOL 0x08 +#define ALC5623_LINE_IN_VOL 0x0A +#define ALC5623_STEREO_DAC_VOL 0x0C +#define ALC5623_MIC_VOL 0x0E +#define ALC5623_MIC_ROUTING_CTRL 0x10 +#define ALC5623_ADC_REC_GAIN 0x12 +#define ALC5623_ADC_REC_MIXER 0x14 +#define ALC5623_SOFT_VOL_CTRL_TIME 0x16 +/* ALC5623_OUTPUT_MIXER_CTRL : */ +/* same remark as for reg 2 line vs speaker */ +#define ALC5623_OUTPUT_MIXER_CTRL 0x1C +#define ALC5623_MIC_CTRL 0x22 + +#define ALC5623_DAI_CONTROL 0x34 +#define ALC5623_DAI_SDP_MASTER_MODE (0 << 15) +#define ALC5623_DAI_SDP_SLAVE_MODE (1 << 15) +#define ALC5623_DAI_I2S_PCM_MODE (1 << 14) +#define ALC5623_DAI_MAIN_I2S_BCLK_POL_CTRL (1 << 7) +#define ALC5623_DAI_ADC_DATA_L_R_SWAP (1 << 5) +#define ALC5623_DAI_DAC_DATA_L_R_SWAP (1 << 4) +#define ALC5623_DAI_I2S_DL_MASK (3 << 2) +#define ALC5623_DAI_I2S_DL_32 (3 << 2) +#define ALC5623_DAI_I2S_DL_24 (2 << 2) +#define ALC5623_DAI_I2S_DL_20 (1 << 2) +#define ALC5623_DAI_I2S_DL_16 (0 << 2) +#define ALC5623_DAI_I2S_DF_PCM (3 << 0) +#define ALC5623_DAI_I2S_DF_LEFT (2 << 0) +#define ALC5623_DAI_I2S_DF_RIGHT (1 << 0) +#define ALC5623_DAI_I2S_DF_I2S (0 << 0) + +#define ALC5623_STEREO_AD_DA_CLK_CTRL 0x36 +#define ALC5623_COMPANDING_CTRL 0x38 + +#define ALC5623_PWR_MANAG_ADD1 0x3A +#define ALC5623_PWR_ADD1_MAIN_I2S_EN (1 << 15) +#define ALC5623_PWR_ADD1_ZC_DET_PD_EN (1 << 14) +#define ALC5623_PWR_ADD1_MIC1_BIAS_EN (1 << 11) +#define ALC5623_PWR_ADD1_SHORT_CURR_DET_EN (1 << 10) +#define ALC5623_PWR_ADD1_SOFTGEN_EN (1 << 8) /* rsvd on 5622 */ +#define ALC5623_PWR_ADD1_DEPOP_BUF_HP (1 << 6) /* rsvd on 5622 */ +#define ALC5623_PWR_ADD1_HP_OUT_AMP (1 << 5) +#define ALC5623_PWR_ADD1_HP_OUT_ENH_AMP (1 << 4) /* rsvd on 5622 */ +#define ALC5623_PWR_ADD1_DEPOP_BUF_AUX (1 << 2) +#define ALC5623_PWR_ADD1_AUX_OUT_AMP (1 << 1) +#define ALC5623_PWR_ADD1_AUX_OUT_ENH_AMP (1 << 0) /* rsvd on 5622 */ + +#define ALC5623_PWR_MANAG_ADD2 0x3C +#define ALC5623_PWR_ADD2_LINEOUT (1 << 15) /* rt5623 */ +#define ALC5623_PWR_ADD2_CLASS_AB (1 << 15) /* rt5621 */ +#define ALC5623_PWR_ADD2_CLASS_D (1 << 14) /* rt5621 */ +#define ALC5623_PWR_ADD2_VREF (1 << 13) +#define ALC5623_PWR_ADD2_PLL (1 << 12) +#define ALC5623_PWR_ADD2_DAC_REF_CIR (1 << 10) +#define ALC5623_PWR_ADD2_L_DAC_CLK (1 << 9) +#define ALC5623_PWR_ADD2_R_DAC_CLK (1 << 8) +#define ALC5623_PWR_ADD2_L_ADC_CLK_GAIN (1 << 7) +#define ALC5623_PWR_ADD2_R_ADC_CLK_GAIN (1 << 6) +#define ALC5623_PWR_ADD2_L_HP_MIXER (1 << 5) +#define ALC5623_PWR_ADD2_R_HP_MIXER (1 << 4) +#define ALC5623_PWR_ADD2_SPK_MIXER (1 << 3) +#define ALC5623_PWR_ADD2_MONO_MIXER (1 << 2) +#define ALC5623_PWR_ADD2_L_ADC_REC_MIXER (1 << 1) +#define ALC5623_PWR_ADD2_R_ADC_REC_MIXER (1 << 0) + +#define ALC5623_PWR_MANAG_ADD3 0x3E +#define ALC5623_PWR_ADD3_MAIN_BIAS (1 << 15) +#define ALC5623_PWR_ADD3_AUXOUT_L_VOL_AMP (1 << 14) +#define ALC5623_PWR_ADD3_AUXOUT_R_VOL_AMP (1 << 13) +#define ALC5623_PWR_ADD3_SPK_OUT (1 << 12) +#define ALC5623_PWR_ADD3_HP_L_OUT_VOL (1 << 10) +#define ALC5623_PWR_ADD3_HP_R_OUT_VOL (1 << 9) +#define ALC5623_PWR_ADD3_LINEIN_L_VOL (1 << 7) +#define ALC5623_PWR_ADD3_LINEIN_R_VOL (1 << 6) +#define ALC5623_PWR_ADD3_AUXIN_L_VOL (1 << 5) +#define ALC5623_PWR_ADD3_AUXIN_R_VOL (1 << 4) +#define ALC5623_PWR_ADD3_MIC1_FUN_CTRL (1 << 3) +#define ALC5623_PWR_ADD3_MIC2_FUN_CTRL (1 << 2) +#define ALC5623_PWR_ADD3_MIC1_BOOST_AD (1 << 1) +#define ALC5623_PWR_ADD3_MIC2_BOOST_AD (1 << 0) + +#define ALC5623_ADD_CTRL_REG 0x40 + +#define ALC5623_GLOBAL_CLK_CTRL_REG 0x42 +#define ALC5623_GBL_CLK_SYS_SOUR_SEL_PLL (1 << 15) +#define ALC5623_GBL_CLK_SYS_SOUR_SEL_MCLK (0 << 15) +#define ALC5623_GBL_CLK_PLL_SOUR_SEL_BITCLK (1 << 14) +#define ALC5623_GBL_CLK_PLL_SOUR_SEL_MCLK (0 << 14) +#define ALC5623_GBL_CLK_PLL_DIV_RATIO_DIV8 (3 << 1) +#define ALC5623_GBL_CLK_PLL_DIV_RATIO_DIV4 (2 << 1) +#define ALC5623_GBL_CLK_PLL_DIV_RATIO_DIV2 (1 << 1) +#define ALC5623_GBL_CLK_PLL_DIV_RATIO_DIV1 (0 << 1) +#define ALC5623_GBL_CLK_PLL_PRE_DIV2 (1 << 0) +#define ALC5623_GBL_CLK_PLL_PRE_DIV1 (0 << 0) + +#define ALC5623_PLL_CTRL 0x44 +#define ALC5623_PLL_CTRL_N_VAL(n) (((n)&0xff) << 8) +#define ALC5623_PLL_CTRL_K_VAL(k) (((k)&0x7) << 4) +#define ALC5623_PLL_CTRL_M_VAL(m) ((m)&0xf) + +#define ALC5623_GPIO_OUTPUT_PIN_CTRL 0x4A +#define ALC5623_GPIO_PIN_CONFIG 0x4C +#define ALC5623_GPIO_PIN_POLARITY 0x4E +#define ALC5623_GPIO_PIN_STICKY 0x50 +#define ALC5623_GPIO_PIN_WAKEUP 0x52 +#define ALC5623_GPIO_PIN_STATUS 0x54 +#define ALC5623_GPIO_PIN_SHARING 0x56 +#define ALC5623_OVER_CURR_STATUS 0x58 +#define ALC5623_JACK_DET_CTRL 0x5A + +#define ALC5623_MISC_CTRL 0x5E +#define ALC5623_MISC_DISABLE_FAST_VREG (1 << 15) +#define ALC5623_MISC_SPK_CLASS_AB_OC_PD (1 << 13) /* 5621 */ +#define ALC5623_MISC_SPK_CLASS_AB_OC_DET (1 << 12) /* 5621 */ +#define ALC5623_MISC_HP_DEPOP_MODE3_EN (1 << 10) +#define ALC5623_MISC_HP_DEPOP_MODE2_EN (1 << 9) +#define ALC5623_MISC_HP_DEPOP_MODE1_EN (1 << 8) +#define ALC5623_MISC_AUXOUT_DEPOP_MODE3_EN (1 << 6) +#define ALC5623_MISC_AUXOUT_DEPOP_MODE2_EN (1 << 5) +#define ALC5623_MISC_AUXOUT_DEPOP_MODE1_EN (1 << 4) +#define ALC5623_MISC_M_DAC_L_INPUT (1 << 3) +#define ALC5623_MISC_M_DAC_R_INPUT (1 << 2) +#define ALC5623_MISC_IRQOUT_INV_CTRL (1 << 0) + +#define ALC5623_PSEDUEO_SPATIAL_CTRL 0x60 +#define ALC5623_EQ_CTRL 0x62 +#define ALC5623_EQ_MODE_ENABLE 0x66 +#define ALC5623_AVC_CTRL 0x68 +#define ALC5623_HID_CTRL_INDEX 0x6A +#define ALC5623_HID_CTRL_DATA 0x6C +#define ALC5623_VENDOR_ID1 0x7C +#define ALC5623_VENDOR_ID2 0x7E + +#define ALC5623_PLL_FR_MCLK 0 +#define ALC5623_PLL_FR_BCK 1 +#endif -- cgit v1.2.3 From d906401114861585c990ff0290c002b5d22fc71a Mon Sep 17 00:00:00 2001 From: "Arnaud Patard (Rtp)" Date: Thu, 21 Oct 2010 19:40:03 +0200 Subject: ASoC: kirkwood: Add audio support to hp t5325 thin clients This patch is adding support for hp t5325 thin clients. There's a alc5623 codec connected to the i2s interface. Signed-off-by: Arnaud Patard Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/kirkwood/Kconfig | 9 +++ sound/soc/kirkwood/Makefile | 2 + sound/soc/kirkwood/kirkwood-t5325.c | 141 ++++++++++++++++++++++++++++++++++++ 3 files changed, 152 insertions(+) create mode 100644 sound/soc/kirkwood/kirkwood-t5325.c diff --git a/sound/soc/kirkwood/Kconfig b/sound/soc/kirkwood/Kconfig index 16ec2a2dba4d..54258fd9797f 100644 --- a/sound/soc/kirkwood/Kconfig +++ b/sound/soc/kirkwood/Kconfig @@ -18,3 +18,12 @@ config SND_KIRKWOOD_SOC_OPENRD Say Y if you want to add support for SoC audio on Openrd Client. +config SND_KIRKWOOD_SOC_T5325 + tristate "SoC Audio support for HP t5325" + depends on SND_KIRKWOOD_SOC && MACH_T5325 + select SND_KIRKWOOD_SOC_I2S + select SND_SOC_ALC5623 + help + Say Y if you want to add support for SoC audio on + the HP t5325 thin client. + diff --git a/sound/soc/kirkwood/Makefile b/sound/soc/kirkwood/Makefile index 33a16dcab5b5..3e62ae9e7bbe 100644 --- a/sound/soc/kirkwood/Makefile +++ b/sound/soc/kirkwood/Makefile @@ -5,5 +5,7 @@ obj-$(CONFIG_SND_KIRKWOOD_SOC) += snd-soc-kirkwood.o obj-$(CONFIG_SND_KIRKWOOD_SOC_I2S) += snd-soc-kirkwood-i2s.o snd-soc-openrd-objs := kirkwood-openrd.o +snd-soc-t5325-objs := kirkwood-t5325.o obj-$(CONFIG_SND_KIRKWOOD_SOC_OPENRD) += snd-soc-openrd.o +obj-$(CONFIG_SND_KIRKWOOD_SOC_T5325) += snd-soc-t5325.o diff --git a/sound/soc/kirkwood/kirkwood-t5325.c b/sound/soc/kirkwood/kirkwood-t5325.c new file mode 100644 index 000000000000..51b52e31cb0b --- /dev/null +++ b/sound/soc/kirkwood/kirkwood-t5325.c @@ -0,0 +1,141 @@ +/* + * kirkwood-t5325.c + * + * (c) 2010 Arnaud Patard + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "../codecs/alc5623.h" + +static int t5325_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *codec_dai = rtd->codec_dai; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + int ret; + unsigned int freq, fmt; + + fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS; + ret = snd_soc_dai_set_fmt(cpu_dai, fmt); + if (ret < 0) + return ret; + + ret = snd_soc_dai_set_fmt(codec_dai, fmt); + if (ret < 0) + return ret; + + freq = params_rate(params) * 256; + + return snd_soc_dai_set_sysclk(codec_dai, 0, freq, SND_SOC_CLOCK_IN); + +} + +static struct snd_soc_ops t5325_ops = { + .hw_params = t5325_hw_params, +}; + +static const struct snd_soc_dapm_widget t5325_dapm_widgets[] = { + SND_SOC_DAPM_HP("Headphone Jack", NULL), + SND_SOC_DAPM_SPK("Speaker", NULL), + SND_SOC_DAPM_MIC("Mic Jack", NULL), +}; + +static const struct snd_soc_dapm_route t5325_route[] = { + { "Headphone Jack", NULL, "HPL" }, + { "Headphone Jack", NULL, "HPR" }, + + {"Speaker", NULL, "SPKOUT"}, + {"Speaker", NULL, "SPKOUTN"}, + + { "MIC1", NULL, "Mic Jack" }, + { "MIC2", NULL, "Mic Jack" }, +}; + +static int t5325_dai_init(struct snd_soc_pcm_runtime *rtd) +{ + struct snd_soc_codec *codec = rtd->codec; + + snd_soc_dapm_new_controls(codec, t5325_dapm_widgets, + ARRAY_SIZE(t5325_dapm_widgets)); + + snd_soc_dapm_add_routes(codec, t5325_route, ARRAY_SIZE(t5325_route)); + + snd_soc_dapm_enable_pin(codec, "Mic Jack"); + snd_soc_dapm_enable_pin(codec, "Headphone Jack"); + snd_soc_dapm_enable_pin(codec, "Speaker"); + + snd_soc_dapm_sync(codec); + + return 0; +} + +static struct snd_soc_dai_link t5325_dai[] = { +{ + .name = "ALC5621", + .stream_name = "ALC5621 HiFi", + .cpu_dai_name = "kirkwood-i2s", + .platform_name = "kirkwood-pcm-audio", + .codec_dai_name = "alc5621-hifi", + .codec_name = "alc562x-codec.0-001a", + .ops = &t5325_ops, + .init = t5325_dai_init, +}, +}; + + +static struct snd_soc_card t5325 = { + .name = "t5325", + .dai_link = t5325_dai, + .num_links = ARRAY_SIZE(t5325_dai), +}; + +static struct platform_device *t5325_snd_device; + +static int __init t5325_init(void) +{ + int ret; + + if (!machine_is_t5325()) + return 0; + + t5325_snd_device = platform_device_alloc("soc-audio", -1); + if (!t5325_snd_device) + return -ENOMEM; + + platform_set_drvdata(t5325_snd_device, + &t5325); + + ret = platform_device_add(t5325_snd_device); + if (ret) { + printk(KERN_ERR "%s: platform_device_add failed\n", __func__); + platform_device_put(t5325_snd_device); + } + + return ret; +} +module_init(t5325_init); + +static void __exit t5325_exit(void) +{ + platform_device_unregister(t5325_snd_device); +} +module_exit(t5325_exit); + +MODULE_AUTHOR("Arnaud Patard "); +MODULE_DESCRIPTION("ALSA SoC t5325 audio client"); +MODULE_LICENSE("GPL"); -- cgit v1.2.3 From 7e6120c57cf92f005f72c6345c0961415099881e Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Mon, 25 Oct 2010 11:34:23 +0300 Subject: ASoC: TWL4030: Use usleep_range when appropriate Change the busy loop delays with usleep_range or msleep calls. Signed-off-by: Peter Ujfalusi Acked-by: Mark Brown Signed-off-by: Liam Girdwood --- sound/soc/codecs/twl4030.c | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c index cbebec6ba1ba..a6ceddb0bb7d 100644 --- a/sound/soc/codecs/twl4030.c +++ b/sound/soc/codecs/twl4030.c @@ -233,6 +233,16 @@ static int twl4030_write(struct snd_soc_codec *codec, return 0; } +static inline void twl4030_wait_ms(int time) +{ + if (time < 60) { + time *= 1000; + usleep_range(time, time + 500); + } else { + msleep(time); + } +} + static void twl4030_codec_enable(struct snd_soc_codec *codec, int enable) { struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); @@ -338,10 +348,14 @@ static void twl4030_init_chip(struct snd_soc_codec *codec) twl4030_write(codec, TWL4030_REG_ANAMICL, reg | TWL4030_CNCL_OFFSET_START); - /* wait for offset cancellation to complete */ + /* + * Wait for offset cancellation to complete. + * Since this takes a while, do not slam the i2c. + * Start polling the status after ~20ms. + */ + msleep(20); do { - /* this takes a little while, so don't slam i2c */ - udelay(2000); + usleep_range(1000, 2000); twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, &byte, TWL4030_REG_ANAMICL); } while ((i++ < 100) && @@ -725,9 +739,12 @@ static void headset_ramp(struct snd_soc_codec *codec, int ramp) /* Base values for ramp delay calculation: 2^19 - 2^26 */ unsigned int ramp_base[] = {524288, 1048576, 2097152, 4194304, 8388608, 16777216, 33554432, 67108864}; + unsigned int delay; hs_gain = twl4030_read_reg_cache(codec, TWL4030_REG_HS_GAIN_SET); hs_pop = twl4030_read_reg_cache(codec, TWL4030_REG_HS_POPN_SET); + delay = (ramp_base[(hs_pop & TWL4030_RAMP_DELAY) >> 2] / + twl4030->sysclk) + 1; /* Enable external mute control, this dramatically reduces * the pop-noise */ @@ -751,16 +768,14 @@ static void headset_ramp(struct snd_soc_codec *codec, int ramp) hs_pop |= TWL4030_RAMP_EN; twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop); /* Wait ramp delay time + 1, so the VMID can settle */ - mdelay((ramp_base[(hs_pop & TWL4030_RAMP_DELAY) >> 2] / - twl4030->sysclk) + 1); + twl4030_wait_ms(delay); } else { /* Headset ramp-down _not_ according to * the TRM, but in a way that it is working */ hs_pop &= ~TWL4030_RAMP_EN; twl4030_write(codec, TWL4030_REG_HS_POPN_SET, hs_pop); /* Wait ramp delay time + 1, so the VMID can settle */ - mdelay((ramp_base[(hs_pop & TWL4030_RAMP_DELAY) >> 2] / - twl4030->sysclk) + 1); + twl4030_wait_ms(delay); /* Bypass the reg_cache to mute the headset */ twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, hs_gain & (~0x0f), @@ -835,7 +850,7 @@ static int digimic_event(struct snd_soc_dapm_widget *w, struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(w->codec); if (twl4030->digimic_delay) - mdelay(twl4030->digimic_delay); + twl4030_wait_ms(twl4030->digimic_delay); return 0; } -- cgit v1.2.3 From 803711afdbea5c6a6dd2b46eca76097f6d50fb53 Mon Sep 17 00:00:00 2001 From: Thomas Renninger Date: Mon, 25 Oct 2010 21:11:15 +0200 Subject: PNP: Compile all pnp built-in stuff in one module namespace This is cleanup mostly, nothing urgent. I came up with it when looking at dynamic debug which can enable pr_debug messages at runtime or boot param for a specific module. Advantages: - Any pnp code can make use of the moduleparam.h interface, the modules will show up as pnp.param. - Passing pnp.ddebug as kernel boot param will enable all pnp debug messages with my previous patch and CONFIG_DYNAMIC_DEBUG enabled. Signed-off-by: Thomas Renninger Signed-off-by: Bjorn Helgaas Signed-off-by: Len Brown --- drivers/pnp/Makefile | 6 ++++-- drivers/pnp/isapnp/Makefile | 6 +++--- drivers/pnp/pnpacpi/Makefile | 3 ++- drivers/pnp/pnpbios/Makefile | 5 +++-- 4 files changed, 12 insertions(+), 8 deletions(-) diff --git a/drivers/pnp/Makefile b/drivers/pnp/Makefile index 8de3775ec242..bfba893cb321 100644 --- a/drivers/pnp/Makefile +++ b/drivers/pnp/Makefile @@ -2,11 +2,13 @@ # Makefile for the Linux Plug-and-Play Support. # -obj-y := core.o card.o driver.o resource.o manager.o support.o interface.o quirks.o +obj-y := pnp.o + +pnp-y := core.o card.o driver.o resource.o manager.o support.o interface.o quirks.o obj-$(CONFIG_PNPACPI) += pnpacpi/ obj-$(CONFIG_PNPBIOS) += pnpbios/ obj-$(CONFIG_ISAPNP) += isapnp/ # pnp_system_init goes after pnpacpi/pnpbios init -obj-y += system.o +pnp-y += system.o diff --git a/drivers/pnp/isapnp/Makefile b/drivers/pnp/isapnp/Makefile index cac18bbfb817..6e607aa33aa3 100644 --- a/drivers/pnp/isapnp/Makefile +++ b/drivers/pnp/isapnp/Makefile @@ -1,7 +1,7 @@ # # Makefile for the kernel ISAPNP driver. # +obj-y += pnp.o +pnp-y := core.o compat.o -isapnp-proc-$(CONFIG_PROC_FS) = proc.o - -obj-y := core.o compat.o $(isapnp-proc-y) +pnp-$(CONFIG_PROC_FS) += proc.o diff --git a/drivers/pnp/pnpacpi/Makefile b/drivers/pnp/pnpacpi/Makefile index 905326fcca85..40c93da18252 100644 --- a/drivers/pnp/pnpacpi/Makefile +++ b/drivers/pnp/pnpacpi/Makefile @@ -1,5 +1,6 @@ # # Makefile for the kernel PNPACPI driver. # +obj-y += pnp.o -obj-y := core.o rsparser.o +pnp-y := core.o rsparser.o diff --git a/drivers/pnp/pnpbios/Makefile b/drivers/pnp/pnpbios/Makefile index 3cd3ed760605..240b0ffb83ca 100644 --- a/drivers/pnp/pnpbios/Makefile +++ b/drivers/pnp/pnpbios/Makefile @@ -1,7 +1,8 @@ # # Makefile for the kernel PNPBIOS driver. # +obj-y := pnp.o -pnpbios-proc-$(CONFIG_PNPBIOS_PROC_FS) = proc.o +pnp-y := core.o bioscalls.o rsparser.o -obj-y := core.o bioscalls.o rsparser.o $(pnpbios-proc-y) +pnp-$(CONFIG_PNPBIOS_PROC_FS) += proc.o -- cgit v1.2.3 From cdefba03e44bd3b3311a3849a81ec7030dfa1519 Mon Sep 17 00:00:00 2001 From: Thomas Renninger Date: Mon, 25 Oct 2010 21:11:16 +0200 Subject: PNP: Set up pnp_debug via module and not via boot param. Cleanup only, no functional change (pnp.debug can be enabled and disabled at runtime, but that's not a real enhancement). This one depends on another PNP cleanup patch: PNP: Compile all pnp built-in stuff in one module namespace Signed-off-by: Thomas Renninger Signed-off-by: Bjorn Helgaas Signed-off-by: Len Brown --- drivers/pnp/core.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/drivers/pnp/core.c b/drivers/pnp/core.c index 88b3cde52596..9801918b2726 100644 --- a/drivers/pnp/core.c +++ b/drivers/pnp/core.c @@ -218,10 +218,5 @@ subsys_initcall(pnp_init); int pnp_debug; #if defined(CONFIG_PNP_DEBUG_MESSAGES) -static int __init pnp_debug_setup(char *__unused) -{ - pnp_debug = 1; - return 1; -} -__setup("pnp.debug", pnp_debug_setup); +module_param_named(debug, pnp_debug, int, 0644); #endif -- cgit v1.2.3 From 78501eac34f372bfbeb4e1d9de688c13efa916f6 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 27 Oct 2010 12:18:21 +0100 Subject: drm/i915/ringbuffer: Drop the redundant dev from the vfunc interface The ringbuffer keeps a pointer to the parent device, so we can use that instead of passing around the pointer on the stack. Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_debugfs.c | 4 +- drivers/gpu/drm/i915/i915_dma.c | 10 +- drivers/gpu/drm/i915/i915_drv.c | 2 +- drivers/gpu/drm/i915/i915_drv.h | 8 +- drivers/gpu/drm/i915/i915_gem.c | 55 +++-- drivers/gpu/drm/i915/i915_irq.c | 12 +- drivers/gpu/drm/i915/intel_ringbuffer.c | 378 +++++++++++++++----------------- drivers/gpu/drm/i915/intel_ringbuffer.h | 76 +++---- 8 files changed, 247 insertions(+), 298 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 1f4f3ceb63c7..c1b04b6056da 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -296,7 +296,7 @@ static int i915_gem_seqno_info(struct seq_file *m, void *data) if (dev_priv->render_ring.status_page.page_addr != NULL) { seq_printf(m, "Current sequence: %d\n", - dev_priv->render_ring.get_seqno(dev, &dev_priv->render_ring)); + dev_priv->render_ring.get_seqno(&dev_priv->render_ring)); } else { seq_printf(m, "Current sequence: hws uninitialized\n"); } @@ -356,7 +356,7 @@ static int i915_interrupt_info(struct seq_file *m, void *data) atomic_read(&dev_priv->irq_received)); if (dev_priv->render_ring.status_page.page_addr != NULL) { seq_printf(m, "Current sequence: %d\n", - dev_priv->render_ring.get_seqno(dev, &dev_priv->render_ring)); + dev_priv->render_ring.get_seqno(&dev_priv->render_ring)); } else { seq_printf(m, "Current sequence: hws uninitialized\n"); } diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 7a26f4dd21ae..8a171394a9cf 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -131,9 +131,9 @@ static int i915_dma_cleanup(struct drm_device * dev) drm_irq_uninstall(dev); mutex_lock(&dev->struct_mutex); - intel_cleanup_ring_buffer(dev, &dev_priv->render_ring); - intel_cleanup_ring_buffer(dev, &dev_priv->bsd_ring); - intel_cleanup_ring_buffer(dev, &dev_priv->blt_ring); + intel_cleanup_ring_buffer(&dev_priv->render_ring); + intel_cleanup_ring_buffer(&dev_priv->bsd_ring); + intel_cleanup_ring_buffer(&dev_priv->blt_ring); mutex_unlock(&dev->struct_mutex); /* Clear the HWS virtual address at teardown */ @@ -221,7 +221,7 @@ static int i915_dma_resume(struct drm_device * dev) DRM_DEBUG_DRIVER("hw status page @ %p\n", ring->status_page.page_addr); if (ring->status_page.gfx_addr != 0) - intel_ring_setup_status_page(dev, ring); + intel_ring_setup_status_page(ring); else I915_WRITE(HWS_PGA, dev_priv->dma_status_page); @@ -567,7 +567,7 @@ static int i915_quiescent(struct drm_device * dev) drm_i915_private_t *dev_priv = dev->dev_private; i915_kernel_lost_context(dev); - return intel_wait_ring_buffer(dev, &dev_priv->render_ring, + return intel_wait_ring_buffer(&dev_priv->render_ring, dev_priv->render_ring.size - 8); } diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 3467dd420760..82c19ab3e1e2 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -473,7 +473,7 @@ int i915_reset(struct drm_device *dev, u8 flags) !dev_priv->mm.suspended) { struct intel_ring_buffer *ring = &dev_priv->render_ring; dev_priv->mm.suspended = 0; - ring->init(dev, ring); + ring->init(ring); mutex_unlock(&dev->struct_mutex); drm_irq_uninstall(dev); drm_irq_install(dev); diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 2c2c19b6285e..6fb225f6b2c8 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1219,10 +1219,10 @@ static inline void i915_write(struct drm_i915_private *dev_priv, u32 reg, #define I915_VERBOSE 0 #define BEGIN_LP_RING(n) do { \ - drm_i915_private_t *dev_priv__ = dev->dev_private; \ + drm_i915_private_t *dev_priv__ = dev->dev_private; \ if (I915_VERBOSE) \ DRM_DEBUG(" BEGIN_LP_RING %x\n", (int)(n)); \ - intel_ring_begin(dev, &dev_priv__->render_ring, (n)); \ + intel_ring_begin(&dev_priv__->render_ring, (n)); \ } while (0) @@ -1230,7 +1230,7 @@ static inline void i915_write(struct drm_i915_private *dev_priv, u32 reg, drm_i915_private_t *dev_priv__ = dev->dev_private; \ if (I915_VERBOSE) \ DRM_DEBUG(" OUT_RING %x\n", (int)(x)); \ - intel_ring_emit(dev, &dev_priv__->render_ring, x); \ + intel_ring_emit(&dev_priv__->render_ring, x); \ } while (0) #define ADVANCE_LP_RING() do { \ @@ -1238,7 +1238,7 @@ static inline void i915_write(struct drm_i915_private *dev_priv, u32 reg, if (I915_VERBOSE) \ DRM_DEBUG("ADVANCE_LP_RING %x\n", \ dev_priv__->render_ring.tail); \ - intel_ring_advance(dev, &dev_priv__->render_ring); \ + intel_ring_advance(&dev_priv__->render_ring); \ } while(0) /** diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 8eb8453208b5..97bf7c87d857 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1703,7 +1703,7 @@ i915_add_request(struct drm_device *dev, return 0; } - seqno = ring->add_request(dev, ring, 0); + seqno = ring->add_request(ring, 0); ring->outstanding_lazy_request = false; request->seqno = seqno; @@ -1745,8 +1745,7 @@ i915_retire_commands(struct drm_device *dev, struct intel_ring_buffer *ring) if (INTEL_INFO(dev)->gen >= 4) flush_domains |= I915_GEM_DOMAIN_SAMPLER; - ring->flush(dev, ring, - I915_GEM_DOMAIN_COMMAND, flush_domains); + ring->flush(ring, I915_GEM_DOMAIN_COMMAND, flush_domains); } static inline void @@ -1853,7 +1852,7 @@ i915_gem_retire_requests_ring(struct drm_device *dev, WARN_ON(i915_verify_lists(dev)); - seqno = ring->get_seqno(dev, ring); + seqno = ring->get_seqno(ring); while (!list_empty(&ring->request_list)) { struct drm_i915_gem_request *request; @@ -1894,7 +1893,7 @@ i915_gem_retire_requests_ring(struct drm_device *dev, if (unlikely (dev_priv->trace_irq_seqno && i915_seqno_passed(dev_priv->trace_irq_seqno, seqno))) { - ring->user_irq_put(dev, ring); + ring->user_irq_put(ring); dev_priv->trace_irq_seqno = 0; } @@ -1971,7 +1970,7 @@ i915_do_wait_request(struct drm_device *dev, uint32_t seqno, } BUG_ON(seqno == dev_priv->next_seqno); - if (!i915_seqno_passed(ring->get_seqno(dev, ring), seqno)) { + if (!i915_seqno_passed(ring->get_seqno(ring), seqno)) { if (HAS_PCH_SPLIT(dev)) ier = I915_READ(DEIER) | I915_READ(GTIER); else @@ -1986,19 +1985,17 @@ i915_do_wait_request(struct drm_device *dev, uint32_t seqno, trace_i915_gem_request_wait_begin(dev, seqno); ring->waiting_gem_seqno = seqno; - ring->user_irq_get(dev, ring); + ring->user_irq_get(ring); if (interruptible) ret = wait_event_interruptible(ring->irq_queue, - i915_seqno_passed( - ring->get_seqno(dev, ring), seqno) + i915_seqno_passed(ring->get_seqno(ring), seqno) || atomic_read(&dev_priv->mm.wedged)); else wait_event(ring->irq_queue, - i915_seqno_passed( - ring->get_seqno(dev, ring), seqno) + i915_seqno_passed(ring->get_seqno(ring), seqno) || atomic_read(&dev_priv->mm.wedged)); - ring->user_irq_put(dev, ring); + ring->user_irq_put(ring); ring->waiting_gem_seqno = 0; trace_i915_gem_request_wait_end(dev, seqno); @@ -2008,7 +2005,7 @@ i915_do_wait_request(struct drm_device *dev, uint32_t seqno, if (ret && ret != -ERESTARTSYS) DRM_ERROR("%s returns %d (awaiting %d at %d, next %d)\n", - __func__, ret, seqno, ring->get_seqno(dev, ring), + __func__, ret, seqno, ring->get_seqno(ring), dev_priv->next_seqno); /* Directly dispatch request retiring. While we have the work queue @@ -2040,7 +2037,7 @@ i915_gem_flush_ring(struct drm_device *dev, uint32_t invalidate_domains, uint32_t flush_domains) { - ring->flush(dev, ring, invalidate_domains, flush_domains); + ring->flush(ring, invalidate_domains, flush_domains); i915_gem_process_flushing_list(dev, flush_domains, ring); } @@ -3532,17 +3529,17 @@ i915_gem_ring_throttle(struct drm_device *dev, struct drm_file *file) return 0; ret = 0; - if (!i915_seqno_passed(ring->get_seqno(dev, ring), seqno)) { + if (!i915_seqno_passed(ring->get_seqno(ring), seqno)) { /* And wait for the seqno passing without holding any locks and * causing extra latency for others. This is safe as the irq * generation is designed to be run atomically and so is * lockless. */ - ring->user_irq_get(dev, ring); + ring->user_irq_get(ring); ret = wait_event_interruptible(ring->irq_queue, - i915_seqno_passed(ring->get_seqno(dev, ring), seqno) + i915_seqno_passed(ring->get_seqno(ring), seqno) || atomic_read(&dev_priv->mm.wedged)); - ring->user_irq_put(dev, ring); + ring->user_irq_put(ring); if (ret == 0 && atomic_read(&dev_priv->mm.wedged)) ret = -EIO; @@ -3829,17 +3826,15 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, else flip_mask = MI_WAIT_FOR_PLANE_A_FLIP; - intel_ring_begin(dev, ring, 2); - intel_ring_emit(dev, ring, - MI_WAIT_FOR_EVENT | flip_mask); - intel_ring_emit(dev, ring, MI_NOOP); - intel_ring_advance(dev, ring); + intel_ring_begin(ring, 2); + intel_ring_emit(ring, MI_WAIT_FOR_EVENT | flip_mask); + intel_ring_emit(ring, MI_NOOP); + intel_ring_advance(ring); } } /* Exec the batchbuffer */ - ret = ring->dispatch_gem_execbuffer(dev, ring, args, - cliprects, exec_offset); + ret = ring->dispatch_execbuffer(ring, args, cliprects, exec_offset); if (ret) { DRM_ERROR("dispatch failed %d\n", ret); goto err; @@ -4520,9 +4515,9 @@ i915_gem_init_ringbuffer(struct drm_device *dev) return 0; cleanup_bsd_ring: - intel_cleanup_ring_buffer(dev, &dev_priv->bsd_ring); + intel_cleanup_ring_buffer(&dev_priv->bsd_ring); cleanup_render_ring: - intel_cleanup_ring_buffer(dev, &dev_priv->render_ring); + intel_cleanup_ring_buffer(&dev_priv->render_ring); cleanup_pipe_control: if (HAS_PIPE_CONTROL(dev)) i915_gem_cleanup_pipe_control(dev); @@ -4534,9 +4529,9 @@ i915_gem_cleanup_ringbuffer(struct drm_device *dev) { drm_i915_private_t *dev_priv = dev->dev_private; - intel_cleanup_ring_buffer(dev, &dev_priv->render_ring); - intel_cleanup_ring_buffer(dev, &dev_priv->bsd_ring); - intel_cleanup_ring_buffer(dev, &dev_priv->blt_ring); + intel_cleanup_ring_buffer(&dev_priv->render_ring); + intel_cleanup_ring_buffer(&dev_priv->bsd_ring); + intel_cleanup_ring_buffer(&dev_priv->blt_ring); if (HAS_PIPE_CONTROL(dev)) i915_gem_cleanup_pipe_control(dev); } diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 729fd0c91d7b..852a2d848bf4 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -297,7 +297,7 @@ static void notify_ring(struct drm_device *dev, struct intel_ring_buffer *ring) { struct drm_i915_private *dev_priv = dev->dev_private; - u32 seqno = ring->get_seqno(dev, ring); + u32 seqno = ring->get_seqno(ring); ring->irq_gem_seqno = seqno; trace_i915_gem_request_complete(dev, seqno); wake_up_all(&ring->irq_queue); @@ -586,7 +586,7 @@ static void i915_capture_error_state(struct drm_device *dev) DRM_DEBUG_DRIVER("generating error event\n"); error->seqno = - dev_priv->render_ring.get_seqno(dev, &dev_priv->render_ring); + dev_priv->render_ring.get_seqno(&dev_priv->render_ring); error->eir = I915_READ(EIR); error->pgtbl_er = I915_READ(PGTBL_ER); error->pipeastat = I915_READ(PIPEASTAT); @@ -1117,7 +1117,7 @@ void i915_trace_irq_get(struct drm_device *dev, u32 seqno) struct intel_ring_buffer *render_ring = &dev_priv->render_ring; if (dev_priv->trace_irq_seqno == 0) - render_ring->user_irq_get(dev, render_ring); + render_ring->user_irq_get(render_ring); dev_priv->trace_irq_seqno = seqno; } @@ -1141,10 +1141,10 @@ static int i915_wait_irq(struct drm_device * dev, int irq_nr) if (master_priv->sarea_priv) master_priv->sarea_priv->perf_boxes |= I915_BOX_WAIT; - render_ring->user_irq_get(dev, render_ring); + render_ring->user_irq_get(render_ring); DRM_WAIT_ON(ret, dev_priv->render_ring.irq_queue, 3 * DRM_HZ, READ_BREADCRUMB(dev_priv) >= irq_nr); - render_ring->user_irq_put(dev, render_ring); + render_ring->user_irq_put(render_ring); if (ret == -EBUSY) { DRM_ERROR("EBUSY -- rec: %d emitted: %d\n", @@ -1338,7 +1338,7 @@ void i915_hangcheck_elapsed(unsigned long data) /* If all work is done then ACTHD clearly hasn't advanced. */ if (list_empty(&dev_priv->render_ring.request_list) || - i915_seqno_passed(dev_priv->render_ring.get_seqno(dev, &dev_priv->render_ring), + i915_seqno_passed(dev_priv->render_ring.get_seqno(&dev_priv->render_ring), i915_get_tail_request(dev)->seqno)) { bool missed_wakeup = false; diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 09f2dc353ae2..d6eba661105f 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -49,11 +49,11 @@ static u32 i915_gem_get_seqno(struct drm_device *dev) } static void -render_ring_flush(struct drm_device *dev, - struct intel_ring_buffer *ring, +render_ring_flush(struct intel_ring_buffer *ring, u32 invalidate_domains, u32 flush_domains) { + struct drm_device *dev = ring->dev; drm_i915_private_t *dev_priv = dev->dev_private; u32 cmd; @@ -112,43 +112,39 @@ render_ring_flush(struct drm_device *dev, #if WATCH_EXEC DRM_INFO("%s: queue flush %08x to ring\n", __func__, cmd); #endif - intel_ring_begin(dev, ring, 2); - intel_ring_emit(dev, ring, cmd); - intel_ring_emit(dev, ring, MI_NOOP); - intel_ring_advance(dev, ring); + intel_ring_begin(ring, 2); + intel_ring_emit(ring, cmd); + intel_ring_emit(ring, MI_NOOP); + intel_ring_advance(ring); } } -static void ring_write_tail(struct drm_device *dev, - struct intel_ring_buffer *ring, +static void ring_write_tail(struct intel_ring_buffer *ring, u32 value) { - drm_i915_private_t *dev_priv = dev->dev_private; + drm_i915_private_t *dev_priv = ring->dev->dev_private; I915_WRITE_TAIL(ring, value); } -u32 intel_ring_get_active_head(struct drm_device *dev, - struct intel_ring_buffer *ring) +u32 intel_ring_get_active_head(struct intel_ring_buffer *ring) { - drm_i915_private_t *dev_priv = dev->dev_private; - u32 acthd_reg = INTEL_INFO(dev)->gen >= 4 ? + drm_i915_private_t *dev_priv = ring->dev->dev_private; + u32 acthd_reg = INTEL_INFO(ring->dev)->gen >= 4 ? RING_ACTHD(ring->mmio_base) : ACTHD; return I915_READ(acthd_reg); } -static int init_ring_common(struct drm_device *dev, - struct intel_ring_buffer *ring) +static int init_ring_common(struct intel_ring_buffer *ring) { + drm_i915_private_t *dev_priv = ring->dev->dev_private; + struct drm_i915_gem_object *obj_priv = to_intel_bo(ring->gem_object); u32 head; - drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_i915_gem_object *obj_priv; - obj_priv = to_intel_bo(ring->gem_object); /* Stop the ring if it's running. */ I915_WRITE_CTL(ring, 0); I915_WRITE_HEAD(ring, 0); - ring->write_tail(dev, ring, 0); + ring->write_tail(ring, 0); /* Initialize the ring. */ I915_WRITE_START(ring, obj_priv->gtt_offset); @@ -192,8 +188,8 @@ static int init_ring_common(struct drm_device *dev, return -EIO; } - if (!drm_core_check_feature(dev, DRIVER_MODESET)) - i915_kernel_lost_context(dev); + if (!drm_core_check_feature(ring->dev, DRIVER_MODESET)) + i915_kernel_lost_context(ring->dev); else { ring->head = I915_READ_HEAD(ring) & HEAD_ADDR; ring->tail = I915_READ_TAIL(ring) & TAIL_ADDR; @@ -204,29 +200,29 @@ static int init_ring_common(struct drm_device *dev, return 0; } -static int init_render_ring(struct drm_device *dev, - struct intel_ring_buffer *ring) +static int init_render_ring(struct intel_ring_buffer *ring) { - drm_i915_private_t *dev_priv = dev->dev_private; - int ret = init_ring_common(dev, ring); - int mode; + struct drm_device *dev = ring->dev; + int ret = init_ring_common(ring); if (INTEL_INFO(dev)->gen > 3) { - mode = VS_TIMER_DISPATCH << 16 | VS_TIMER_DISPATCH; + drm_i915_private_t *dev_priv = dev->dev_private; + int mode = VS_TIMER_DISPATCH << 16 | VS_TIMER_DISPATCH; if (IS_GEN6(dev)) mode |= MI_FLUSH_ENABLE << 16 | MI_FLUSH_ENABLE; I915_WRITE(MI_MODE, mode); } + return ret; } -#define PIPE_CONTROL_FLUSH(addr) \ +#define PIPE_CONTROL_FLUSH(ring__, addr__) \ do { \ - OUT_RING(GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE | \ + intel_ring_emit(ring__, GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE | \ PIPE_CONTROL_DEPTH_STALL | 2); \ - OUT_RING(addr | PIPE_CONTROL_GLOBAL_GTT); \ - OUT_RING(0); \ - OUT_RING(0); \ + intel_ring_emit(ring__, (addr__) | PIPE_CONTROL_GLOBAL_GTT); \ + intel_ring_emit(ring__, 0); \ + intel_ring_emit(ring__, 0); \ } while (0) /** @@ -238,26 +234,26 @@ do { \ * Returned sequence numbers are nonzero on success. */ static u32 -render_ring_add_request(struct drm_device *dev, - struct intel_ring_buffer *ring, +render_ring_add_request(struct intel_ring_buffer *ring, u32 flush_domains) { + struct drm_device *dev = ring->dev; drm_i915_private_t *dev_priv = dev->dev_private; u32 seqno; seqno = i915_gem_get_seqno(dev); if (IS_GEN6(dev)) { - BEGIN_LP_RING(6); - OUT_RING(GFX_OP_PIPE_CONTROL | 3); - OUT_RING(PIPE_CONTROL_QW_WRITE | + intel_ring_begin(ring, 6); + intel_ring_emit(ring, GFX_OP_PIPE_CONTROL | 3); + intel_ring_emit(ring, PIPE_CONTROL_QW_WRITE | PIPE_CONTROL_WC_FLUSH | PIPE_CONTROL_IS_FLUSH | PIPE_CONTROL_NOTIFY); - OUT_RING(dev_priv->seqno_gfx_addr | PIPE_CONTROL_GLOBAL_GTT); - OUT_RING(seqno); - OUT_RING(0); - OUT_RING(0); - ADVANCE_LP_RING(); + intel_ring_emit(ring, dev_priv->seqno_gfx_addr | PIPE_CONTROL_GLOBAL_GTT); + intel_ring_emit(ring, seqno); + intel_ring_emit(ring, 0); + intel_ring_emit(ring, 0); + intel_ring_advance(ring); } else if (HAS_PIPE_CONTROL(dev)) { u32 scratch_addr = dev_priv->seqno_gfx_addr + 128; @@ -266,46 +262,46 @@ render_ring_add_request(struct drm_device *dev, * PIPE_NOTIFY buffers out to memory before requesting * an interrupt. */ - BEGIN_LP_RING(32); - OUT_RING(GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE | + intel_ring_begin(ring, 32); + intel_ring_emit(ring, GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE | PIPE_CONTROL_WC_FLUSH | PIPE_CONTROL_TC_FLUSH); - OUT_RING(dev_priv->seqno_gfx_addr | PIPE_CONTROL_GLOBAL_GTT); - OUT_RING(seqno); - OUT_RING(0); - PIPE_CONTROL_FLUSH(scratch_addr); + intel_ring_emit(ring, dev_priv->seqno_gfx_addr | PIPE_CONTROL_GLOBAL_GTT); + intel_ring_emit(ring, seqno); + intel_ring_emit(ring, 0); + PIPE_CONTROL_FLUSH(ring, scratch_addr); scratch_addr += 128; /* write to separate cachelines */ - PIPE_CONTROL_FLUSH(scratch_addr); + PIPE_CONTROL_FLUSH(ring, scratch_addr); scratch_addr += 128; - PIPE_CONTROL_FLUSH(scratch_addr); + PIPE_CONTROL_FLUSH(ring, scratch_addr); scratch_addr += 128; - PIPE_CONTROL_FLUSH(scratch_addr); + PIPE_CONTROL_FLUSH(ring, scratch_addr); scratch_addr += 128; - PIPE_CONTROL_FLUSH(scratch_addr); + PIPE_CONTROL_FLUSH(ring, scratch_addr); scratch_addr += 128; - PIPE_CONTROL_FLUSH(scratch_addr); - OUT_RING(GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE | + PIPE_CONTROL_FLUSH(ring, scratch_addr); + intel_ring_emit(ring, GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE | PIPE_CONTROL_WC_FLUSH | PIPE_CONTROL_TC_FLUSH | PIPE_CONTROL_NOTIFY); - OUT_RING(dev_priv->seqno_gfx_addr | PIPE_CONTROL_GLOBAL_GTT); - OUT_RING(seqno); - OUT_RING(0); - ADVANCE_LP_RING(); + intel_ring_emit(ring, dev_priv->seqno_gfx_addr | PIPE_CONTROL_GLOBAL_GTT); + intel_ring_emit(ring, seqno); + intel_ring_emit(ring, 0); + intel_ring_advance(ring); } else { - BEGIN_LP_RING(4); - OUT_RING(MI_STORE_DWORD_INDEX); - OUT_RING(I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT); - OUT_RING(seqno); + intel_ring_begin(ring, 4); + intel_ring_emit(ring, MI_STORE_DWORD_INDEX); + intel_ring_emit(ring, I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT); + intel_ring_emit(ring, seqno); - OUT_RING(MI_USER_INTERRUPT); - ADVANCE_LP_RING(); + intel_ring_emit(ring, MI_USER_INTERRUPT); + intel_ring_advance(ring); } return seqno; } static u32 -render_ring_get_seqno(struct drm_device *dev, - struct intel_ring_buffer *ring) +render_ring_get_seqno(struct intel_ring_buffer *ring) { + struct drm_device *dev = ring->dev; drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; if (HAS_PIPE_CONTROL(dev)) return ((volatile u32 *)(dev_priv->seqno_page))[0]; @@ -314,9 +310,9 @@ render_ring_get_seqno(struct drm_device *dev, } static void -render_ring_get_user_irq(struct drm_device *dev, - struct intel_ring_buffer *ring) +render_ring_get_user_irq(struct intel_ring_buffer *ring) { + struct drm_device *dev = ring->dev; drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; unsigned long irqflags; @@ -331,9 +327,9 @@ render_ring_get_user_irq(struct drm_device *dev, } static void -render_ring_put_user_irq(struct drm_device *dev, - struct intel_ring_buffer *ring) +render_ring_put_user_irq(struct intel_ring_buffer *ring) { + struct drm_device *dev = ring->dev; drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; unsigned long irqflags; @@ -348,56 +344,41 @@ render_ring_put_user_irq(struct drm_device *dev, spin_unlock_irqrestore(&dev_priv->user_irq_lock, irqflags); } -void intel_ring_setup_status_page(struct drm_device *dev, - struct intel_ring_buffer *ring) +void intel_ring_setup_status_page(struct intel_ring_buffer *ring) { - drm_i915_private_t *dev_priv = dev->dev_private; - if (IS_GEN6(dev)) { - I915_WRITE(RING_HWS_PGA_GEN6(ring->mmio_base), - ring->status_page.gfx_addr); - I915_READ(RING_HWS_PGA_GEN6(ring->mmio_base)); /* posting read */ - } else { - I915_WRITE(RING_HWS_PGA(ring->mmio_base), - ring->status_page.gfx_addr); - I915_READ(RING_HWS_PGA(ring->mmio_base)); /* posting read */ - } - + drm_i915_private_t *dev_priv = ring->dev->dev_private; + u32 mmio = IS_GEN6(ring->dev) ? + RING_HWS_PGA_GEN6(ring->mmio_base) : + RING_HWS_PGA(ring->mmio_base); + I915_WRITE(mmio, (u32)ring->status_page.gfx_addr); + POSTING_READ(mmio); } static void -bsd_ring_flush(struct drm_device *dev, - struct intel_ring_buffer *ring, - u32 invalidate_domains, - u32 flush_domains) -{ - intel_ring_begin(dev, ring, 2); - intel_ring_emit(dev, ring, MI_FLUSH); - intel_ring_emit(dev, ring, MI_NOOP); - intel_ring_advance(dev, ring); -} - -static int init_bsd_ring(struct drm_device *dev, - struct intel_ring_buffer *ring) +bsd_ring_flush(struct intel_ring_buffer *ring, + u32 invalidate_domains, + u32 flush_domains) { - return init_ring_common(dev, ring); + intel_ring_begin(ring, 2); + intel_ring_emit(ring, MI_FLUSH); + intel_ring_emit(ring, MI_NOOP); + intel_ring_advance(ring); } static u32 -ring_add_request(struct drm_device *dev, - struct intel_ring_buffer *ring, +ring_add_request(struct intel_ring_buffer *ring, u32 flush_domains) { u32 seqno; - seqno = i915_gem_get_seqno(dev); + seqno = i915_gem_get_seqno(ring->dev); - intel_ring_begin(dev, ring, 4); - intel_ring_emit(dev, ring, MI_STORE_DWORD_INDEX); - intel_ring_emit(dev, ring, - I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT); - intel_ring_emit(dev, ring, seqno); - intel_ring_emit(dev, ring, MI_USER_INTERRUPT); - intel_ring_advance(dev, ring); + intel_ring_begin(ring, 4); + intel_ring_emit(ring, MI_STORE_DWORD_INDEX); + intel_ring_emit(ring, I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT); + intel_ring_emit(ring, seqno); + intel_ring_emit(ring, MI_USER_INTERRUPT); + intel_ring_advance(ring); DRM_DEBUG_DRIVER("%s %d\n", ring->name, seqno); @@ -405,53 +386,55 @@ ring_add_request(struct drm_device *dev, } static void -bsd_ring_get_user_irq(struct drm_device *dev, - struct intel_ring_buffer *ring) +bsd_ring_get_user_irq(struct intel_ring_buffer *ring) { /* do nothing */ } static void -bsd_ring_put_user_irq(struct drm_device *dev, - struct intel_ring_buffer *ring) +bsd_ring_put_user_irq(struct intel_ring_buffer *ring) { /* do nothing */ } static u32 -ring_status_page_get_seqno(struct drm_device *dev, - struct intel_ring_buffer *ring) +ring_status_page_get_seqno(struct intel_ring_buffer *ring) { return intel_read_status_page(ring, I915_GEM_HWS_INDEX); } static int -ring_dispatch_gem_execbuffer(struct drm_device *dev, - struct intel_ring_buffer *ring, - struct drm_i915_gem_execbuffer2 *exec, - struct drm_clip_rect *cliprects, - uint64_t exec_offset) +ring_dispatch_execbuffer(struct intel_ring_buffer *ring, + struct drm_i915_gem_execbuffer2 *exec, + struct drm_clip_rect *cliprects, + uint64_t exec_offset) { uint32_t exec_start; + exec_start = (uint32_t) exec_offset + exec->batch_start_offset; - intel_ring_begin(dev, ring, 2); - intel_ring_emit(dev, ring, MI_BATCH_BUFFER_START | - (2 << 6) | MI_BATCH_NON_SECURE_I965); - intel_ring_emit(dev, ring, exec_start); - intel_ring_advance(dev, ring); + + intel_ring_begin(ring, 2); + intel_ring_emit(ring, + MI_BATCH_BUFFER_START | + (2 << 6) | + MI_BATCH_NON_SECURE_I965); + intel_ring_emit(ring, exec_start); + intel_ring_advance(ring); + return 0; } static int -render_ring_dispatch_gem_execbuffer(struct drm_device *dev, - struct intel_ring_buffer *ring, - struct drm_i915_gem_execbuffer2 *exec, - struct drm_clip_rect *cliprects, - uint64_t exec_offset) +render_ring_dispatch_execbuffer(struct intel_ring_buffer *ring, + struct drm_i915_gem_execbuffer2 *exec, + struct drm_clip_rect *cliprects, + uint64_t exec_offset) { + struct drm_device *dev = ring->dev; drm_i915_private_t *dev_priv = dev->dev_private; int nbox = exec->num_cliprects; int i = 0, count; uint32_t exec_start, exec_len; + exec_start = (uint32_t) exec_offset + exec->batch_start_offset; exec_len = (uint32_t) exec->batch_len; @@ -468,46 +451,44 @@ render_ring_dispatch_gem_execbuffer(struct drm_device *dev, } if (IS_I830(dev) || IS_845G(dev)) { - intel_ring_begin(dev, ring, 4); - intel_ring_emit(dev, ring, MI_BATCH_BUFFER); - intel_ring_emit(dev, ring, - exec_start | MI_BATCH_NON_SECURE); - intel_ring_emit(dev, ring, exec_start + exec_len - 4); - intel_ring_emit(dev, ring, 0); + intel_ring_begin(ring, 4); + intel_ring_emit(ring, MI_BATCH_BUFFER); + intel_ring_emit(ring, exec_start | MI_BATCH_NON_SECURE); + intel_ring_emit(ring, exec_start + exec_len - 4); + intel_ring_emit(ring, 0); } else { - intel_ring_begin(dev, ring, 2); + intel_ring_begin(ring, 2); if (INTEL_INFO(dev)->gen >= 4) { - intel_ring_emit(dev, ring, + intel_ring_emit(ring, MI_BATCH_BUFFER_START | (2 << 6) | MI_BATCH_NON_SECURE_I965); - intel_ring_emit(dev, ring, exec_start); + intel_ring_emit(ring, exec_start); } else { - intel_ring_emit(dev, ring, MI_BATCH_BUFFER_START + intel_ring_emit(ring, MI_BATCH_BUFFER_START | (2 << 6)); - intel_ring_emit(dev, ring, exec_start | + intel_ring_emit(ring, exec_start | MI_BATCH_NON_SECURE); } } - intel_ring_advance(dev, ring); + intel_ring_advance(ring); } if (IS_G4X(dev) || IS_GEN5(dev)) { - intel_ring_begin(dev, ring, 2); - intel_ring_emit(dev, ring, MI_FLUSH | + intel_ring_begin(ring, 2); + intel_ring_emit(ring, MI_FLUSH | MI_NO_WRITE_FLUSH | MI_INVALIDATE_ISP ); - intel_ring_emit(dev, ring, MI_NOOP); - intel_ring_advance(dev, ring); + intel_ring_emit(ring, MI_NOOP); + intel_ring_advance(ring); } /* XXX breadcrumb */ return 0; } -static void cleanup_status_page(struct drm_device *dev, - struct intel_ring_buffer *ring) +static void cleanup_status_page(struct intel_ring_buffer *ring) { - drm_i915_private_t *dev_priv = dev->dev_private; + drm_i915_private_t *dev_priv = ring->dev->dev_private; struct drm_gem_object *obj; struct drm_i915_gem_object *obj_priv; @@ -524,9 +505,9 @@ static void cleanup_status_page(struct drm_device *dev, memset(&dev_priv->hws_map, 0, sizeof(dev_priv->hws_map)); } -static int init_status_page(struct drm_device *dev, - struct intel_ring_buffer *ring) +static int init_status_page(struct intel_ring_buffer *ring) { + struct drm_device *dev = ring->dev; drm_i915_private_t *dev_priv = dev->dev_private; struct drm_gem_object *obj; struct drm_i915_gem_object *obj_priv; @@ -555,7 +536,7 @@ static int init_status_page(struct drm_device *dev, ring->status_page.obj = obj; memset(ring->status_page.page_addr, 0, PAGE_SIZE); - intel_ring_setup_status_page(dev, ring); + intel_ring_setup_status_page(ring); DRM_DEBUG_DRIVER("%s hws offset: 0x%08x\n", ring->name, ring->status_page.gfx_addr); @@ -583,7 +564,7 @@ int intel_init_ring_buffer(struct drm_device *dev, INIT_LIST_HEAD(&ring->gpu_write_list); if (I915_NEED_GFX_HWS(dev)) { - ret = init_status_page(dev, ring); + ret = init_status_page(ring); if (ret) return ret; } @@ -616,7 +597,7 @@ int intel_init_ring_buffer(struct drm_device *dev, } ring->virtual_start = ring->map.handle; - ret = ring->init(dev, ring); + ret = ring->init(ring); if (ret) goto err_unmap; @@ -639,33 +620,32 @@ err_unref: drm_gem_object_unreference(obj); ring->gem_object = NULL; err_hws: - cleanup_status_page(dev, ring); + cleanup_status_page(ring); return ret; } -void intel_cleanup_ring_buffer(struct drm_device *dev, - struct intel_ring_buffer *ring) +void intel_cleanup_ring_buffer(struct intel_ring_buffer *ring) { if (ring->gem_object == NULL) return; - drm_core_ioremapfree(&ring->map, dev); + drm_core_ioremapfree(&ring->map, ring->dev); i915_gem_object_unpin(ring->gem_object); drm_gem_object_unreference(ring->gem_object); ring->gem_object = NULL; - cleanup_status_page(dev, ring); + + cleanup_status_page(ring); } -static int intel_wrap_ring_buffer(struct drm_device *dev, - struct intel_ring_buffer *ring) +static int intel_wrap_ring_buffer(struct intel_ring_buffer *ring) { unsigned int *virt; int rem; rem = ring->size - ring->tail; if (ring->space < rem) { - int ret = intel_wait_ring_buffer(dev, ring, rem); + int ret = intel_wait_ring_buffer(ring, rem); if (ret) return ret; } @@ -683,11 +663,11 @@ static int intel_wrap_ring_buffer(struct drm_device *dev, return 0; } -int intel_wait_ring_buffer(struct drm_device *dev, - struct intel_ring_buffer *ring, int n) +int intel_wait_ring_buffer(struct intel_ring_buffer *ring, int n) { - unsigned long end; + struct drm_device *dev = ring->dev; drm_i915_private_t *dev_priv = dev->dev_private; + unsigned long end; trace_i915_ring_wait_begin (dev); end = jiffies + 3 * HZ; @@ -697,7 +677,7 @@ int intel_wait_ring_buffer(struct drm_device *dev, if (ring->space < 0) ring->space += ring->size; if (ring->space >= n) { - trace_i915_ring_wait_end (dev); + trace_i915_ring_wait_end(dev); return 0; } @@ -713,24 +693,24 @@ int intel_wait_ring_buffer(struct drm_device *dev, return -EBUSY; } -void intel_ring_begin(struct drm_device *dev, - struct intel_ring_buffer *ring, +void intel_ring_begin(struct intel_ring_buffer *ring, int num_dwords) { int n = 4*num_dwords; + if (unlikely(ring->tail + n > ring->size)) - intel_wrap_ring_buffer(dev, ring); + intel_wrap_ring_buffer(ring); + if (unlikely(ring->space < n)) - intel_wait_ring_buffer(dev, ring, n); + intel_wait_ring_buffer(ring, n); ring->space -= n; } -void intel_ring_advance(struct drm_device *dev, - struct intel_ring_buffer *ring) +void intel_ring_advance(struct intel_ring_buffer *ring) { ring->tail &= ring->size - 1; - ring->write_tail(dev, ring, ring->tail); + ring->write_tail(ring, ring->tail); } static const struct intel_ring_buffer render_ring = { @@ -745,7 +725,7 @@ static const struct intel_ring_buffer render_ring = { .get_seqno = render_ring_get_seqno, .user_irq_get = render_ring_get_user_irq, .user_irq_put = render_ring_put_user_irq, - .dispatch_gem_execbuffer = render_ring_dispatch_gem_execbuffer, + .dispatch_execbuffer = render_ring_dispatch_execbuffer, }; /* ring buffer for bit-stream decoder */ @@ -755,22 +735,21 @@ static const struct intel_ring_buffer bsd_ring = { .id = RING_BSD, .mmio_base = BSD_RING_BASE, .size = 32 * PAGE_SIZE, - .init = init_bsd_ring, + .init = init_ring_common, .write_tail = ring_write_tail, .flush = bsd_ring_flush, .add_request = ring_add_request, .get_seqno = ring_status_page_get_seqno, .user_irq_get = bsd_ring_get_user_irq, .user_irq_put = bsd_ring_put_user_irq, - .dispatch_gem_execbuffer = ring_dispatch_gem_execbuffer, + .dispatch_execbuffer = ring_dispatch_execbuffer, }; -static void gen6_bsd_ring_write_tail(struct drm_device *dev, - struct intel_ring_buffer *ring, +static void gen6_bsd_ring_write_tail(struct intel_ring_buffer *ring, u32 value) { - drm_i915_private_t *dev_priv = dev->dev_private; + drm_i915_private_t *dev_priv = ring->dev->dev_private; /* Every tail move must follow the sequence below */ I915_WRITE(GEN6_BSD_SLEEP_PSMI_CONTROL, @@ -789,36 +768,33 @@ static void gen6_bsd_ring_write_tail(struct drm_device *dev, GEN6_BSD_SLEEP_PSMI_CONTROL_RC_ILDL_MESSAGE_ENABLE); } -static void gen6_ring_flush(struct drm_device *dev, - struct intel_ring_buffer *ring, +static void gen6_ring_flush(struct intel_ring_buffer *ring, u32 invalidate_domains, u32 flush_domains) { - intel_ring_begin(dev, ring, 4); - intel_ring_emit(dev, ring, MI_FLUSH_DW); - intel_ring_emit(dev, ring, 0); - intel_ring_emit(dev, ring, 0); - intel_ring_emit(dev, ring, 0); - intel_ring_advance(dev, ring); + intel_ring_begin(ring, 4); + intel_ring_emit(ring, MI_FLUSH_DW); + intel_ring_emit(ring, 0); + intel_ring_emit(ring, 0); + intel_ring_emit(ring, 0); + intel_ring_advance(ring); } static int -gen6_ring_dispatch_gem_execbuffer(struct drm_device *dev, - struct intel_ring_buffer *ring, - struct drm_i915_gem_execbuffer2 *exec, - struct drm_clip_rect *cliprects, - uint64_t exec_offset) +gen6_ring_dispatch_execbuffer(struct intel_ring_buffer *ring, + struct drm_i915_gem_execbuffer2 *exec, + struct drm_clip_rect *cliprects, + uint64_t exec_offset) { uint32_t exec_start; exec_start = (uint32_t) exec_offset + exec->batch_start_offset; - intel_ring_begin(dev, ring, 2); - intel_ring_emit(dev, ring, - MI_BATCH_BUFFER_START | MI_BATCH_NON_SECURE_I965); + intel_ring_begin(ring, 2); + intel_ring_emit(ring, MI_BATCH_BUFFER_START | MI_BATCH_NON_SECURE_I965); /* bit0-7 is the length on GEN6+ */ - intel_ring_emit(dev, ring, exec_start); - intel_ring_advance(dev, ring); + intel_ring_emit(ring, exec_start); + intel_ring_advance(ring); return 0; } @@ -829,27 +805,25 @@ static const struct intel_ring_buffer gen6_bsd_ring = { .id = RING_BSD, .mmio_base = GEN6_BSD_RING_BASE, .size = 32 * PAGE_SIZE, - .init = init_bsd_ring, + .init = init_ring_common, .write_tail = gen6_bsd_ring_write_tail, .flush = gen6_ring_flush, .add_request = ring_add_request, .get_seqno = ring_status_page_get_seqno, .user_irq_get = bsd_ring_get_user_irq, .user_irq_put = bsd_ring_put_user_irq, - .dispatch_gem_execbuffer = gen6_ring_dispatch_gem_execbuffer, + .dispatch_execbuffer = gen6_ring_dispatch_execbuffer, }; /* Blitter support (SandyBridge+) */ static void -blt_ring_get_user_irq(struct drm_device *dev, - struct intel_ring_buffer *ring) +blt_ring_get_user_irq(struct intel_ring_buffer *ring) { /* do nothing */ } static void -blt_ring_put_user_irq(struct drm_device *dev, - struct intel_ring_buffer *ring) +blt_ring_put_user_irq(struct intel_ring_buffer *ring) { /* do nothing */ } @@ -866,7 +840,7 @@ static const struct intel_ring_buffer gen6_blt_ring = { .get_seqno = ring_status_page_get_seqno, .user_irq_get = blt_ring_get_user_irq, .user_irq_put = blt_ring_put_user_irq, - .dispatch_gem_execbuffer = gen6_ring_dispatch_gem_execbuffer, + .dispatch_execbuffer = gen6_ring_dispatch_execbuffer, }; int intel_init_render_ring_buffer(struct drm_device *dev) diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index a05aff0e5764..ba4a393e6d16 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -2,7 +2,7 @@ #define _INTEL_RINGBUFFER_H_ struct intel_hw_status_page { - void *page_addr; + u32 __iomem *page_addr; unsigned int gfx_addr; struct drm_gem_object *obj; }; @@ -38,31 +38,23 @@ struct intel_ring_buffer { u32 irq_gem_seqno; /* last seq seem at irq time */ u32 waiting_gem_seqno; int user_irq_refcount; - void (*user_irq_get)(struct drm_device *dev, - struct intel_ring_buffer *ring); - void (*user_irq_put)(struct drm_device *dev, - struct intel_ring_buffer *ring); + void (*user_irq_get)(struct intel_ring_buffer *ring); + void (*user_irq_put)(struct intel_ring_buffer *ring); - int (*init)(struct drm_device *dev, - struct intel_ring_buffer *ring); + int (*init)(struct intel_ring_buffer *ring); - void (*write_tail)(struct drm_device *dev, - struct intel_ring_buffer *ring, + void (*write_tail)(struct intel_ring_buffer *ring, u32 value); - void (*flush)(struct drm_device *dev, - struct intel_ring_buffer *ring, - u32 invalidate_domains, - u32 flush_domains); - u32 (*add_request)(struct drm_device *dev, - struct intel_ring_buffer *ring, - u32 flush_domains); - u32 (*get_seqno)(struct drm_device *dev, - struct intel_ring_buffer *ring); - int (*dispatch_gem_execbuffer)(struct drm_device *dev, - struct intel_ring_buffer *ring, - struct drm_i915_gem_execbuffer2 *exec, - struct drm_clip_rect *cliprects, - uint64_t exec_offset); + void (*flush)(struct intel_ring_buffer *ring, + u32 invalidate_domains, + u32 flush_domains); + u32 (*add_request)(struct intel_ring_buffer *ring, + u32 flush_domains); + u32 (*get_seqno)(struct intel_ring_buffer *ring); + int (*dispatch_execbuffer)(struct intel_ring_buffer *ring, + struct drm_i915_gem_execbuffer2 *exec, + struct drm_clip_rect *cliprects, + uint64_t exec_offset); /** * List of objects currently involved in rendering from the @@ -102,43 +94,31 @@ struct intel_ring_buffer { static inline u32 intel_read_status_page(struct intel_ring_buffer *ring, - int reg) + int reg) { - u32 *regs = ring->status_page.page_addr; - return regs[reg]; + return ioread32(ring->status_page.page_addr + reg); } -int intel_init_ring_buffer(struct drm_device *dev, - struct intel_ring_buffer *ring); -void intel_cleanup_ring_buffer(struct drm_device *dev, - struct intel_ring_buffer *ring); -int intel_wait_ring_buffer(struct drm_device *dev, - struct intel_ring_buffer *ring, int n); -void intel_ring_begin(struct drm_device *dev, - struct intel_ring_buffer *ring, int n); - -static inline void intel_ring_emit(struct drm_device *dev, - struct intel_ring_buffer *ring, - unsigned int data) +void intel_cleanup_ring_buffer(struct intel_ring_buffer *ring); +int intel_wait_ring_buffer(struct intel_ring_buffer *ring, int n); +void intel_ring_begin(struct intel_ring_buffer *ring, int n); + +static inline void intel_ring_emit(struct intel_ring_buffer *ring, + u32 data) { - unsigned int *virt = ring->virtual_start + ring->tail; - *virt = data; + iowrite32(data, ring->virtual_start + ring->tail); ring->tail += 4; } -void intel_ring_advance(struct drm_device *dev, - struct intel_ring_buffer *ring); +void intel_ring_advance(struct intel_ring_buffer *ring); -u32 intel_ring_get_seqno(struct drm_device *dev, - struct intel_ring_buffer *ring); +u32 intel_ring_get_seqno(struct intel_ring_buffer *ring); int intel_init_render_ring_buffer(struct drm_device *dev); int intel_init_bsd_ring_buffer(struct drm_device *dev); int intel_init_blt_ring_buffer(struct drm_device *dev); -u32 intel_ring_get_active_head(struct drm_device *dev, - struct intel_ring_buffer *ring); -void intel_ring_setup_status_page(struct drm_device *dev, - struct intel_ring_buffer *ring); +u32 intel_ring_get_active_head(struct intel_ring_buffer *ring); +void intel_ring_setup_status_page(struct intel_ring_buffer *ring); #endif /* _INTEL_RINGBUFFER_H_ */ -- cgit v1.2.3 From e1f99ce6cac3b6a95551642be5ddb5d9c46bea76 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 27 Oct 2010 12:45:26 +0100 Subject: drm/i915: Propagate errors from writing to ringbuffer Preparing the ringbuffer for adding new commands can fail (a timeout whilst waiting for the GPU to catch up and free some space). So check for any potential error before overwriting HEAD with new commands, and propagate that error back to the user where possible. Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_dma.c | 119 ++++++++++---------- drivers/gpu/drm/i915/i915_drv.h | 28 +---- drivers/gpu/drm/i915/i915_gem.c | 5 +- drivers/gpu/drm/i915/i915_irq.c | 13 ++- drivers/gpu/drm/i915/intel_display.c | 51 +++++---- drivers/gpu/drm/i915/intel_overlay.c | 30 ++++- drivers/gpu/drm/i915/intel_ringbuffer.c | 189 ++++++++++++++++++-------------- drivers/gpu/drm/i915/intel_ringbuffer.h | 4 +- 8 files changed, 244 insertions(+), 195 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 8a171394a9cf..02daf4e5c8e6 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -263,7 +263,7 @@ static int i915_dma_init(struct drm_device *dev, void *data, * instruction detected will be given a size of zero, which is a * signal to abort the rest of the buffer. */ -static int do_validate_cmd(int cmd) +static int validate_cmd(int cmd) { switch (((cmd >> 29) & 0x7)) { case 0x0: @@ -321,40 +321,27 @@ static int do_validate_cmd(int cmd) return 0; } -static int validate_cmd(int cmd) -{ - int ret = do_validate_cmd(cmd); - -/* printk("validate_cmd( %x ): %d\n", cmd, ret); */ - - return ret; -} - static int i915_emit_cmds(struct drm_device * dev, int *buffer, int dwords) { drm_i915_private_t *dev_priv = dev->dev_private; - int i; + int i, ret; if ((dwords+1) * sizeof(int) >= dev_priv->render_ring.size - 8) return -EINVAL; - BEGIN_LP_RING((dwords+1)&~1); - for (i = 0; i < dwords;) { - int cmd, sz; - - cmd = buffer[i]; - - if ((sz = validate_cmd(cmd)) == 0 || i + sz > dwords) + int sz = validate_cmd(buffer[i]); + if (sz == 0 || i + sz > dwords) return -EINVAL; - - OUT_RING(cmd); - - while (++i, --sz) { - OUT_RING(buffer[i]); - } + i += sz; } + ret = BEGIN_LP_RING((dwords+1)&~1); + if (ret) + return ret; + + for (i = 0; i < dwords; i++) + OUT_RING(buffer[i]); if (dwords & 1) OUT_RING(0); @@ -368,7 +355,9 @@ i915_emit_box(struct drm_device *dev, struct drm_clip_rect *boxes, int i, int DR1, int DR4) { + struct drm_i915_private *dev_priv = dev->dev_private; struct drm_clip_rect box = boxes[i]; + int ret; if (box.y2 <= box.y1 || box.x2 <= box.x1 || box.y2 <= 0 || box.x2 <= 0) { DRM_ERROR("Bad box %d,%d..%d,%d\n", @@ -377,22 +366,27 @@ i915_emit_box(struct drm_device *dev, } if (INTEL_INFO(dev)->gen >= 4) { - BEGIN_LP_RING(4); + ret = BEGIN_LP_RING(4); + if (ret) + return ret; + OUT_RING(GFX_OP_DRAWRECT_INFO_I965); OUT_RING((box.x1 & 0xffff) | (box.y1 << 16)); OUT_RING(((box.x2 - 1) & 0xffff) | ((box.y2 - 1) << 16)); OUT_RING(DR4); - ADVANCE_LP_RING(); } else { - BEGIN_LP_RING(6); + ret = BEGIN_LP_RING(6); + if (ret) + return ret; + OUT_RING(GFX_OP_DRAWRECT_INFO); OUT_RING(DR1); OUT_RING((box.x1 & 0xffff) | (box.y1 << 16)); OUT_RING(((box.x2 - 1) & 0xffff) | ((box.y2 - 1) << 16)); OUT_RING(DR4); OUT_RING(0); - ADVANCE_LP_RING(); } + ADVANCE_LP_RING(); return 0; } @@ -412,12 +406,13 @@ static void i915_emit_breadcrumb(struct drm_device *dev) if (master_priv->sarea_priv) master_priv->sarea_priv->last_enqueue = dev_priv->counter; - BEGIN_LP_RING(4); - OUT_RING(MI_STORE_DWORD_INDEX); - OUT_RING(I915_BREADCRUMB_INDEX << MI_STORE_DWORD_INDEX_SHIFT); - OUT_RING(dev_priv->counter); - OUT_RING(0); - ADVANCE_LP_RING(); + if (BEGIN_LP_RING(4) == 0) { + OUT_RING(MI_STORE_DWORD_INDEX); + OUT_RING(I915_BREADCRUMB_INDEX << MI_STORE_DWORD_INDEX_SHIFT); + OUT_RING(dev_priv->counter); + OUT_RING(0); + ADVANCE_LP_RING(); + } } static int i915_dispatch_cmdbuffer(struct drm_device * dev, @@ -458,8 +453,9 @@ static int i915_dispatch_batchbuffer(struct drm_device * dev, drm_i915_batchbuffer_t * batch, struct drm_clip_rect *cliprects) { + struct drm_i915_private *dev_priv = dev->dev_private; int nbox = batch->num_cliprects; - int i = 0, count; + int i, count, ret; if ((batch->start | batch->used) & 0x7) { DRM_ERROR("alignment"); @@ -469,17 +465,19 @@ static int i915_dispatch_batchbuffer(struct drm_device * dev, i915_kernel_lost_context(dev); count = nbox ? nbox : 1; - for (i = 0; i < count; i++) { if (i < nbox) { - int ret = i915_emit_box(dev, cliprects, i, - batch->DR1, batch->DR4); + ret = i915_emit_box(dev, cliprects, i, + batch->DR1, batch->DR4); if (ret) return ret; } if (!IS_I830(dev) && !IS_845G(dev)) { - BEGIN_LP_RING(2); + ret = BEGIN_LP_RING(2); + if (ret) + return ret; + if (INTEL_INFO(dev)->gen >= 4) { OUT_RING(MI_BATCH_BUFFER_START | (2 << 6) | MI_BATCH_NON_SECURE_I965); OUT_RING(batch->start); @@ -487,26 +485,29 @@ static int i915_dispatch_batchbuffer(struct drm_device * dev, OUT_RING(MI_BATCH_BUFFER_START | (2 << 6)); OUT_RING(batch->start | MI_BATCH_NON_SECURE); } - ADVANCE_LP_RING(); } else { - BEGIN_LP_RING(4); + ret = BEGIN_LP_RING(4); + if (ret) + return ret; + OUT_RING(MI_BATCH_BUFFER); OUT_RING(batch->start | MI_BATCH_NON_SECURE); OUT_RING(batch->start + batch->used - 4); OUT_RING(0); - ADVANCE_LP_RING(); } + ADVANCE_LP_RING(); } if (IS_G4X(dev) || IS_GEN5(dev)) { - BEGIN_LP_RING(2); - OUT_RING(MI_FLUSH | MI_NO_WRITE_FLUSH | MI_INVALIDATE_ISP); - OUT_RING(MI_NOOP); - ADVANCE_LP_RING(); + if (BEGIN_LP_RING(2) == 0) { + OUT_RING(MI_FLUSH | MI_NO_WRITE_FLUSH | MI_INVALIDATE_ISP); + OUT_RING(MI_NOOP); + ADVANCE_LP_RING(); + } } - i915_emit_breadcrumb(dev); + i915_emit_breadcrumb(dev); return 0; } @@ -515,6 +516,7 @@ static int i915_dispatch_flip(struct drm_device * dev) drm_i915_private_t *dev_priv = dev->dev_private; struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv; + int ret; if (!master_priv->sarea_priv) return -EINVAL; @@ -526,12 +528,13 @@ static int i915_dispatch_flip(struct drm_device * dev) i915_kernel_lost_context(dev); - BEGIN_LP_RING(2); + ret = BEGIN_LP_RING(10); + if (ret) + return ret; + OUT_RING(MI_FLUSH | MI_READ_FLUSH); OUT_RING(0); - ADVANCE_LP_RING(); - BEGIN_LP_RING(6); OUT_RING(CMD_OP_DISPLAYBUFFER_INFO | ASYNC_FLIP); OUT_RING(0); if (dev_priv->current_page == 0) { @@ -542,21 +545,21 @@ static int i915_dispatch_flip(struct drm_device * dev) dev_priv->current_page = 0; } OUT_RING(0); - ADVANCE_LP_RING(); - BEGIN_LP_RING(2); OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_PLANE_A_FLIP); OUT_RING(0); + ADVANCE_LP_RING(); master_priv->sarea_priv->last_enqueue = dev_priv->counter++; - BEGIN_LP_RING(4); - OUT_RING(MI_STORE_DWORD_INDEX); - OUT_RING(I915_BREADCRUMB_INDEX << MI_STORE_DWORD_INDEX_SHIFT); - OUT_RING(dev_priv->counter); - OUT_RING(0); - ADVANCE_LP_RING(); + if (BEGIN_LP_RING(4) == 0) { + OUT_RING(MI_STORE_DWORD_INDEX); + OUT_RING(I915_BREADCRUMB_INDEX << MI_STORE_DWORD_INDEX_SHIFT); + OUT_RING(dev_priv->counter); + OUT_RING(0); + ADVANCE_LP_RING(); + } master_priv->sarea_priv->pf_current_page = dev_priv->current_page; return 0; diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 6fb225f6b2c8..c241468c632e 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1216,30 +1216,14 @@ static inline void i915_write(struct drm_i915_private *dev_priv, u32 reg, #define I915_DEBUG_DISABLE_IO() (dev_priv->debug_flags &= ~(I915_DEBUG_READ | \ I915_DEBUG_WRITE)) -#define I915_VERBOSE 0 +#define BEGIN_LP_RING(n) \ + intel_ring_begin(&dev_priv->render_ring, (n)) -#define BEGIN_LP_RING(n) do { \ - drm_i915_private_t *dev_priv__ = dev->dev_private; \ - if (I915_VERBOSE) \ - DRM_DEBUG(" BEGIN_LP_RING %x\n", (int)(n)); \ - intel_ring_begin(&dev_priv__->render_ring, (n)); \ -} while (0) - - -#define OUT_RING(x) do { \ - drm_i915_private_t *dev_priv__ = dev->dev_private; \ - if (I915_VERBOSE) \ - DRM_DEBUG(" OUT_RING %x\n", (int)(x)); \ - intel_ring_emit(&dev_priv__->render_ring, x); \ -} while (0) +#define OUT_RING(x) \ + intel_ring_emit(&dev_priv->render_ring, x) -#define ADVANCE_LP_RING() do { \ - drm_i915_private_t *dev_priv__ = dev->dev_private; \ - if (I915_VERBOSE) \ - DRM_DEBUG("ADVANCE_LP_RING %x\n", \ - dev_priv__->render_ring.tail); \ - intel_ring_advance(&dev_priv__->render_ring); \ -} while(0) +#define ADVANCE_LP_RING() \ + intel_ring_advance(&dev_priv->render_ring) /** * Reads a dword out of the status page, which is written to from the command diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 97bf7c87d857..00e901483ba5 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -3826,7 +3826,10 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, else flip_mask = MI_WAIT_FOR_PLANE_A_FLIP; - intel_ring_begin(ring, 2); + ret = intel_ring_begin(ring, 2); + if (ret) + goto err; + intel_ring_emit(ring, MI_WAIT_FOR_EVENT | flip_mask); intel_ring_emit(ring, MI_NOOP); intel_ring_advance(ring); diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 852a2d848bf4..8acdd6d857d3 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -1101,12 +1101,13 @@ static int i915_emit_irq(struct drm_device * dev) if (master_priv->sarea_priv) master_priv->sarea_priv->last_enqueue = dev_priv->counter; - BEGIN_LP_RING(4); - OUT_RING(MI_STORE_DWORD_INDEX); - OUT_RING(I915_BREADCRUMB_INDEX << MI_STORE_DWORD_INDEX_SHIFT); - OUT_RING(dev_priv->counter); - OUT_RING(MI_USER_INTERRUPT); - ADVANCE_LP_RING(); + if (BEGIN_LP_RING(4) == 0) { + OUT_RING(MI_STORE_DWORD_INDEX); + OUT_RING(I915_BREADCRUMB_INDEX << MI_STORE_DWORD_INDEX_SHIFT); + OUT_RING(dev_priv->counter); + OUT_RING(MI_USER_INTERRUPT); + ADVANCE_LP_RING(); + } return dev_priv->counter; } diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 990f065374b2..eb4c725e3069 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -5090,22 +5090,16 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, if (ret) goto cleanup_objs; - /* Block clients from rendering to the new back buffer until - * the flip occurs and the object is no longer visible. - */ - atomic_add(1 << intel_crtc->plane, - &to_intel_bo(work->old_fb_obj)->pending_flip); - - work->pending_flip_obj = obj; - obj_priv = to_intel_bo(obj); - if (IS_GEN3(dev) || IS_GEN2(dev)) { u32 flip_mask; /* Can't queue multiple flips, so wait for the previous * one to finish before executing the next. */ - BEGIN_LP_RING(2); + ret = BEGIN_LP_RING(2); + if (ret) + goto cleanup_objs; + if (intel_crtc->plane) flip_mask = MI_WAIT_FOR_PLANE_B_FLIP; else @@ -5115,13 +5109,25 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, ADVANCE_LP_RING(); } + work->pending_flip_obj = obj; + obj_priv = to_intel_bo(obj); + work->enable_stall_check = true; /* Offset into the new buffer for cases of shared fbs between CRTCs */ offset = crtc->y * fb->pitch + crtc->x * fb->bits_per_pixel/8; - BEGIN_LP_RING(4); - switch(INTEL_INFO(dev)->gen) { + ret = BEGIN_LP_RING(4); + if (ret) + goto cleanup_objs; + + /* Block clients from rendering to the new back buffer until + * the flip occurs and the object is no longer visible. + */ + atomic_add(1 << intel_crtc->plane, + &to_intel_bo(work->old_fb_obj)->pending_flip); + + switch (INTEL_INFO(dev)->gen) { case 2: OUT_RING(MI_DISPLAY_FLIP | MI_DISPLAY_FLIP_PLANE(intel_crtc->plane)); @@ -5850,16 +5856,17 @@ void intel_init_clock_gating(struct drm_device *dev) struct drm_i915_gem_object *obj_priv; obj_priv = to_intel_bo(dev_priv->renderctx); if (obj_priv) { - BEGIN_LP_RING(4); - OUT_RING(MI_SET_CONTEXT); - OUT_RING(obj_priv->gtt_offset | - MI_MM_SPACE_GTT | - MI_SAVE_EXT_STATE_EN | - MI_RESTORE_EXT_STATE_EN | - MI_RESTORE_INHIBIT); - OUT_RING(MI_NOOP); - OUT_RING(MI_FLUSH); - ADVANCE_LP_RING(); + if (BEGIN_LP_RING(4) == 0) { + OUT_RING(MI_SET_CONTEXT); + OUT_RING(obj_priv->gtt_offset | + MI_MM_SPACE_GTT | + MI_SAVE_EXT_STATE_EN | + MI_RESTORE_EXT_STATE_EN | + MI_RESTORE_INHIBIT); + OUT_RING(MI_NOOP); + OUT_RING(MI_FLUSH); + ADVANCE_LP_RING(); + } } } else DRM_DEBUG_KMS("Failed to allocate render context." diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c index afb96d25219a..78fa6a249964 100644 --- a/drivers/gpu/drm/i915/intel_overlay.c +++ b/drivers/gpu/drm/i915/intel_overlay.c @@ -289,6 +289,7 @@ i830_deactivate_pipe_a(struct drm_device *dev) static int intel_overlay_on(struct intel_overlay *overlay) { struct drm_device *dev = overlay->dev; + struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_gem_request *request; int pipe_a_quirk = 0; int ret; @@ -308,7 +309,12 @@ static int intel_overlay_on(struct intel_overlay *overlay) goto out; } - BEGIN_LP_RING(4); + ret = BEGIN_LP_RING(4); + if (ret) { + kfree(request); + goto out; + } + OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_ON); OUT_RING(overlay->flip_addr | OFC_UPDATE); OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP); @@ -332,6 +338,7 @@ static int intel_overlay_continue(struct intel_overlay *overlay, struct drm_i915_gem_request *request; u32 flip_addr = overlay->flip_addr; u32 tmp; + int ret; BUG_ON(!overlay->active); @@ -347,7 +354,11 @@ static int intel_overlay_continue(struct intel_overlay *overlay, if (tmp & (1 << 17)) DRM_DEBUG("overlay underrun, DOVSTA: %x\n", tmp); - BEGIN_LP_RING(2); + ret = BEGIN_LP_RING(2); + if (ret) { + kfree(request); + return ret; + } OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_CONTINUE); OUT_RING(flip_addr); ADVANCE_LP_RING(); @@ -389,8 +400,10 @@ static int intel_overlay_off(struct intel_overlay *overlay, bool interruptible) { struct drm_device *dev = overlay->dev; + struct drm_i915_private *dev_priv = dev->dev_private; u32 flip_addr = overlay->flip_addr; struct drm_i915_gem_request *request; + int ret; BUG_ON(!overlay->active); @@ -404,7 +417,11 @@ static int intel_overlay_off(struct intel_overlay *overlay, * of the hw. Do it in both cases */ flip_addr |= OFC_UPDATE; - BEGIN_LP_RING(6); + ret = BEGIN_LP_RING(6); + if (ret) { + kfree(request); + return ret; + } /* wait for overlay to go idle */ OUT_RING(MI_OVERLAY_FLIP | MI_OVERLAY_CONTINUE); OUT_RING(flip_addr); @@ -467,7 +484,12 @@ static int intel_overlay_release_old_vid(struct intel_overlay *overlay) if (request == NULL) return -ENOMEM; - BEGIN_LP_RING(2); + ret = BEGIN_LP_RING(2); + if (ret) { + kfree(request); + return ret; + } + OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP); OUT_RING(MI_NOOP); ADVANCE_LP_RING(); diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index d6eba661105f..6fe42c1f4ea9 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -112,10 +112,11 @@ render_ring_flush(struct intel_ring_buffer *ring, #if WATCH_EXEC DRM_INFO("%s: queue flush %08x to ring\n", __func__, cmd); #endif - intel_ring_begin(ring, 2); - intel_ring_emit(ring, cmd); - intel_ring_emit(ring, MI_NOOP); - intel_ring_advance(ring); + if (intel_ring_begin(ring, 2) == 0) { + intel_ring_emit(ring, cmd); + intel_ring_emit(ring, MI_NOOP); + intel_ring_advance(ring); + } } } @@ -244,16 +245,17 @@ render_ring_add_request(struct intel_ring_buffer *ring, seqno = i915_gem_get_seqno(dev); if (IS_GEN6(dev)) { - intel_ring_begin(ring, 6); - intel_ring_emit(ring, GFX_OP_PIPE_CONTROL | 3); - intel_ring_emit(ring, PIPE_CONTROL_QW_WRITE | - PIPE_CONTROL_WC_FLUSH | PIPE_CONTROL_IS_FLUSH | - PIPE_CONTROL_NOTIFY); - intel_ring_emit(ring, dev_priv->seqno_gfx_addr | PIPE_CONTROL_GLOBAL_GTT); - intel_ring_emit(ring, seqno); - intel_ring_emit(ring, 0); - intel_ring_emit(ring, 0); - intel_ring_advance(ring); + if (intel_ring_begin(ring, 6) == 0) { + intel_ring_emit(ring, GFX_OP_PIPE_CONTROL | 3); + intel_ring_emit(ring, PIPE_CONTROL_QW_WRITE | + PIPE_CONTROL_WC_FLUSH | PIPE_CONTROL_IS_FLUSH | + PIPE_CONTROL_NOTIFY); + intel_ring_emit(ring, dev_priv->seqno_gfx_addr | PIPE_CONTROL_GLOBAL_GTT); + intel_ring_emit(ring, seqno); + intel_ring_emit(ring, 0); + intel_ring_emit(ring, 0); + intel_ring_advance(ring); + } } else if (HAS_PIPE_CONTROL(dev)) { u32 scratch_addr = dev_priv->seqno_gfx_addr + 128; @@ -262,38 +264,40 @@ render_ring_add_request(struct intel_ring_buffer *ring, * PIPE_NOTIFY buffers out to memory before requesting * an interrupt. */ - intel_ring_begin(ring, 32); - intel_ring_emit(ring, GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE | - PIPE_CONTROL_WC_FLUSH | PIPE_CONTROL_TC_FLUSH); - intel_ring_emit(ring, dev_priv->seqno_gfx_addr | PIPE_CONTROL_GLOBAL_GTT); - intel_ring_emit(ring, seqno); - intel_ring_emit(ring, 0); - PIPE_CONTROL_FLUSH(ring, scratch_addr); - scratch_addr += 128; /* write to separate cachelines */ - PIPE_CONTROL_FLUSH(ring, scratch_addr); - scratch_addr += 128; - PIPE_CONTROL_FLUSH(ring, scratch_addr); - scratch_addr += 128; - PIPE_CONTROL_FLUSH(ring, scratch_addr); - scratch_addr += 128; - PIPE_CONTROL_FLUSH(ring, scratch_addr); - scratch_addr += 128; - PIPE_CONTROL_FLUSH(ring, scratch_addr); - intel_ring_emit(ring, GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE | - PIPE_CONTROL_WC_FLUSH | PIPE_CONTROL_TC_FLUSH | - PIPE_CONTROL_NOTIFY); - intel_ring_emit(ring, dev_priv->seqno_gfx_addr | PIPE_CONTROL_GLOBAL_GTT); - intel_ring_emit(ring, seqno); - intel_ring_emit(ring, 0); - intel_ring_advance(ring); + if (intel_ring_begin(ring, 32) == 0) { + intel_ring_emit(ring, GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE | + PIPE_CONTROL_WC_FLUSH | PIPE_CONTROL_TC_FLUSH); + intel_ring_emit(ring, dev_priv->seqno_gfx_addr | PIPE_CONTROL_GLOBAL_GTT); + intel_ring_emit(ring, seqno); + intel_ring_emit(ring, 0); + PIPE_CONTROL_FLUSH(ring, scratch_addr); + scratch_addr += 128; /* write to separate cachelines */ + PIPE_CONTROL_FLUSH(ring, scratch_addr); + scratch_addr += 128; + PIPE_CONTROL_FLUSH(ring, scratch_addr); + scratch_addr += 128; + PIPE_CONTROL_FLUSH(ring, scratch_addr); + scratch_addr += 128; + PIPE_CONTROL_FLUSH(ring, scratch_addr); + scratch_addr += 128; + PIPE_CONTROL_FLUSH(ring, scratch_addr); + intel_ring_emit(ring, GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE | + PIPE_CONTROL_WC_FLUSH | PIPE_CONTROL_TC_FLUSH | + PIPE_CONTROL_NOTIFY); + intel_ring_emit(ring, dev_priv->seqno_gfx_addr | PIPE_CONTROL_GLOBAL_GTT); + intel_ring_emit(ring, seqno); + intel_ring_emit(ring, 0); + intel_ring_advance(ring); + } } else { - intel_ring_begin(ring, 4); - intel_ring_emit(ring, MI_STORE_DWORD_INDEX); - intel_ring_emit(ring, I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT); - intel_ring_emit(ring, seqno); + if (intel_ring_begin(ring, 4) == 0) { + intel_ring_emit(ring, MI_STORE_DWORD_INDEX); + intel_ring_emit(ring, I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT); + intel_ring_emit(ring, seqno); - intel_ring_emit(ring, MI_USER_INTERRUPT); - intel_ring_advance(ring); + intel_ring_emit(ring, MI_USER_INTERRUPT); + intel_ring_advance(ring); + } } return seqno; } @@ -359,10 +363,11 @@ bsd_ring_flush(struct intel_ring_buffer *ring, u32 invalidate_domains, u32 flush_domains) { - intel_ring_begin(ring, 2); - intel_ring_emit(ring, MI_FLUSH); - intel_ring_emit(ring, MI_NOOP); - intel_ring_advance(ring); + if (intel_ring_begin(ring, 2) == 0) { + intel_ring_emit(ring, MI_FLUSH); + intel_ring_emit(ring, MI_NOOP); + intel_ring_advance(ring); + } } static u32 @@ -373,12 +378,13 @@ ring_add_request(struct intel_ring_buffer *ring, seqno = i915_gem_get_seqno(ring->dev); - intel_ring_begin(ring, 4); - intel_ring_emit(ring, MI_STORE_DWORD_INDEX); - intel_ring_emit(ring, I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT); - intel_ring_emit(ring, seqno); - intel_ring_emit(ring, MI_USER_INTERRUPT); - intel_ring_advance(ring); + if (intel_ring_begin(ring, 4) == 0) { + intel_ring_emit(ring, MI_STORE_DWORD_INDEX); + intel_ring_emit(ring, I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT); + intel_ring_emit(ring, seqno); + intel_ring_emit(ring, MI_USER_INTERRUPT); + intel_ring_advance(ring); + } DRM_DEBUG_DRIVER("%s %d\n", ring->name, seqno); @@ -409,10 +415,14 @@ ring_dispatch_execbuffer(struct intel_ring_buffer *ring, uint64_t exec_offset) { uint32_t exec_start; + int ret; exec_start = (uint32_t) exec_offset + exec->batch_start_offset; - intel_ring_begin(ring, 2); + ret = intel_ring_begin(ring, 2); + if (ret) + return ret; + intel_ring_emit(ring, MI_BATCH_BUFFER_START | (2 << 6) | @@ -432,8 +442,8 @@ render_ring_dispatch_execbuffer(struct intel_ring_buffer *ring, struct drm_device *dev = ring->dev; drm_i915_private_t *dev_priv = dev->dev_private; int nbox = exec->num_cliprects; - int i = 0, count; uint32_t exec_start, exec_len; + int i, count, ret; exec_start = (uint32_t) exec_offset + exec->batch_start_offset; exec_len = (uint32_t) exec->batch_len; @@ -441,23 +451,28 @@ render_ring_dispatch_execbuffer(struct intel_ring_buffer *ring, trace_i915_gem_request_submit(dev, dev_priv->next_seqno + 1); count = nbox ? nbox : 1; - for (i = 0; i < count; i++) { if (i < nbox) { - int ret = i915_emit_box(dev, cliprects, i, - exec->DR1, exec->DR4); + ret = i915_emit_box(dev, cliprects, i, + exec->DR1, exec->DR4); if (ret) return ret; } if (IS_I830(dev) || IS_845G(dev)) { - intel_ring_begin(ring, 4); + ret = intel_ring_begin(ring, 4); + if (ret) + return ret; + intel_ring_emit(ring, MI_BATCH_BUFFER); intel_ring_emit(ring, exec_start | MI_BATCH_NON_SECURE); intel_ring_emit(ring, exec_start + exec_len - 4); intel_ring_emit(ring, 0); } else { - intel_ring_begin(ring, 2); + ret = intel_ring_begin(ring, 2); + if (ret) + return ret; + if (INTEL_INFO(dev)->gen >= 4) { intel_ring_emit(ring, MI_BATCH_BUFFER_START | (2 << 6) @@ -474,12 +489,13 @@ render_ring_dispatch_execbuffer(struct intel_ring_buffer *ring, } if (IS_G4X(dev) || IS_GEN5(dev)) { - intel_ring_begin(ring, 2); - intel_ring_emit(ring, MI_FLUSH | - MI_NO_WRITE_FLUSH | - MI_INVALIDATE_ISP ); - intel_ring_emit(ring, MI_NOOP); - intel_ring_advance(ring); + if (intel_ring_begin(ring, 2) == 0) { + intel_ring_emit(ring, MI_FLUSH | + MI_NO_WRITE_FLUSH | + MI_INVALIDATE_ISP ); + intel_ring_emit(ring, MI_NOOP); + intel_ring_advance(ring); + } } /* XXX breadcrumb */ @@ -693,18 +709,26 @@ int intel_wait_ring_buffer(struct intel_ring_buffer *ring, int n) return -EBUSY; } -void intel_ring_begin(struct intel_ring_buffer *ring, - int num_dwords) +int intel_ring_begin(struct intel_ring_buffer *ring, + int num_dwords) { int n = 4*num_dwords; + int ret; - if (unlikely(ring->tail + n > ring->size)) - intel_wrap_ring_buffer(ring); + if (unlikely(ring->tail + n > ring->size)) { + ret = intel_wrap_ring_buffer(ring); + if (unlikely(ret)) + return ret; + } - if (unlikely(ring->space < n)) - intel_wait_ring_buffer(ring, n); + if (unlikely(ring->space < n)) { + ret = intel_wait_ring_buffer(ring, n); + if (unlikely(ret)) + return ret; + } ring->space -= n; + return 0; } void intel_ring_advance(struct intel_ring_buffer *ring) @@ -772,12 +796,13 @@ static void gen6_ring_flush(struct intel_ring_buffer *ring, u32 invalidate_domains, u32 flush_domains) { - intel_ring_begin(ring, 4); - intel_ring_emit(ring, MI_FLUSH_DW); - intel_ring_emit(ring, 0); - intel_ring_emit(ring, 0); - intel_ring_emit(ring, 0); - intel_ring_advance(ring); + if (intel_ring_begin(ring, 4) == 0) { + intel_ring_emit(ring, MI_FLUSH_DW); + intel_ring_emit(ring, 0); + intel_ring_emit(ring, 0); + intel_ring_emit(ring, 0); + intel_ring_advance(ring); + } } static int @@ -787,10 +812,14 @@ gen6_ring_dispatch_execbuffer(struct intel_ring_buffer *ring, uint64_t exec_offset) { uint32_t exec_start; + int ret; exec_start = (uint32_t) exec_offset + exec->batch_start_offset; - intel_ring_begin(ring, 2); + ret = intel_ring_begin(ring, 2); + if (ret) + return ret; + intel_ring_emit(ring, MI_BATCH_BUFFER_START | MI_BATCH_NON_SECURE_I965); /* bit0-7 is the length on GEN6+ */ intel_ring_emit(ring, exec_start); diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index ba4a393e6d16..35ece2b87b02 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -100,8 +100,8 @@ intel_read_status_page(struct intel_ring_buffer *ring, } void intel_cleanup_ring_buffer(struct intel_ring_buffer *ring); -int intel_wait_ring_buffer(struct intel_ring_buffer *ring, int n); -void intel_ring_begin(struct intel_ring_buffer *ring, int n); +int __must_check intel_wait_ring_buffer(struct intel_ring_buffer *ring, int n); +int __must_check intel_ring_begin(struct intel_ring_buffer *ring, int n); static inline void intel_ring_emit(struct intel_ring_buffer *ring, u32 data) -- cgit v1.2.3 From 7e318e18f248416a3d32a1649a9b4538e7f8b0eb Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 27 Oct 2010 13:43:39 +0100 Subject: drm/i915: Move object to GPU domains after dispatching execbuffer In the event that we fail to dispatch the execbuffer, for example if there is insufficient space on the ring, we were leaving the objects in an inconsistent state. Notably they were marked as being in the GPU write domain, but were not added to the ring or any list. This would lead to inevitable oops: [ 1010.522940] [drm:i915_gem_do_execbuffer] *ERROR* dispatch failed -16 [ 1010.523055] BUG: unable to handle kernel NULL pointer dereference at 0000000000000088 [ 1010.523097] IP: [] i915_gem_flush_ring+0x26/0x140 [ 1010.523120] PGD 14cf2f067 PUD 14ce04067 PMD 0 [ 1010.523140] Oops: 0000 [#1] SMP [ 1010.523154] last sysfs file: /sys/devices/virtual/vc/vcsa2/uevent [ 1010.523173] CPU 0 [ 1010.523183] Pid: 716, comm: X Not tainted 2.6.36+ #34 LosLunas CRB/SandyBridge Platform [ 1010.523206] RIP: 0010:[] [] i915_gem_flush_ring+0x26/0x140 [ 1010.523233] RSP: 0018:ffff88014bf97cd8 EFLAGS: 00010296 [ 1010.523249] RAX: ffff88014e2d1808 RBX: 0000000000000000 RCX: 0000000000000000 [ 1010.523270] RDX: 0000000000000002 RSI: 0000000000000000 RDI: 0000000000000000 [ 1010.523290] RBP: ffff88014e2d1000 R08: 0000000000000002 R09: 00000000400c645f [ 1010.523311] R10: 0000000000000001 R11: 0000000000000246 R12: 0000000000000002 [ 1010.523331] R13: ffff88014e29a000 R14: 00000000000000c8 R15: ffffffff8162eb28 [ 1010.523352] FS: 00007fc62379d700(0000) GS:ffff88001fc00000(0000) knlGS:0000000000000000 [ 1010.523375] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 1010.523392] CR2: 0000000000000088 CR3: 000000014bf87000 CR4: 00000000000406f0 [ 1010.523412] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [ 1010.523433] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400 [ 1010.523454] Process X (pid: 716, threadinfo ffff88014bf96000, task ffff88014cc1ee40) [ 1010.523475] Stack: [ 1010.523483] ffff88014d5199c0 0000000000000200 0000000000000000 ffff88014bcc6400 [ 1010.523509] <0> 0000000000000000 0000000000000001 ffff88014e29a000 ffff88014bcc6400 [ 1010.523537] <0> ffffffff8162eb28 ffffffff8122faa8 ffff88014e29a000 ffff88014bcc6400 [ 1010.523568] Call Trace: [ 1010.523578] [] ? i915_gem_object_flush_gpu_write_domain+0x48/0x80 [ 1010.523601] [] ? i915_gem_object_set_to_gtt_domain+0x2e/0xb0 [ 1010.523623] [] ? i915_gem_set_domain_ioctl+0xdb/0x1f0 [ 1010.523644] [] ? drm_ioctl+0x3d1/0x460 [ 1010.523660] [] ? i915_gem_set_domain_ioctl+0x0/0x1f0 [ 1010.523682] [] ? vma_prio_tree_insert+0x28/0x120 [ 1010.523701] [] ? vma_link+0x99/0xf0 [ 1010.523717] [] ? mmap_region+0x1ed/0x4f0 [ 1010.523734] [] ? do_vfs_ioctl+0x9f/0x580 [ 1010.523750] [] ? sys_ioctl+0x49/0x80 [ 1010.523767] [] ? system_call_fastpath+0x16/0x1b [ 1010.523785] Code: 00 00 00 00 00 41 57 89 ce 41 56 41 55 41 54 45 89 c4 55 48 89 fd 53 48 89 d3 44 89 c2 48 89 df 4c 8d b3 c8 00 00 00 48 83 ec 18 93 88 00 00 00 48 8b 83 c8 00 00 00 4c 8b bd 30 03 00 00 48 [ 1010.523946] RIP [] i915_gem_flush_ring+0x26/0x140 [ 1010.523966] RSP [ 1010.523977] CR2: 0000000000000088 Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_gem.c | 68 ++++++++++++++++------------------------- 1 file changed, 27 insertions(+), 41 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 00e901483ba5..580244c1e793 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -3085,9 +3085,6 @@ i915_gem_object_set_to_gpu_domain(struct drm_gem_object *obj, struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); uint32_t invalidate_domains = 0; uint32_t flush_domains = 0; - uint32_t old_read_domains; - - intel_mark_busy(dev, obj); /* * If the object isn't moving to a new write domain, @@ -3095,8 +3092,6 @@ i915_gem_object_set_to_gpu_domain(struct drm_gem_object *obj, */ if (obj->pending_write_domain == 0) obj->pending_read_domains |= obj->read_domains; - else - obj_priv->dirty = 1; /* * Flush the current write domain if @@ -3118,8 +3113,6 @@ i915_gem_object_set_to_gpu_domain(struct drm_gem_object *obj, if ((flush_domains | invalidate_domains) & I915_GEM_DOMAIN_CPU) i915_gem_clflush_object(obj); - old_read_domains = obj->read_domains; - /* The actual obj->write_domain will be updated with * pending_write_domain after we emit the accumulated flush for all * of our domain changes in execbuffers (which clears objects' @@ -3128,7 +3121,6 @@ i915_gem_object_set_to_gpu_domain(struct drm_gem_object *obj, */ if (flush_domains == 0 && obj->pending_write_domain == 0) obj->pending_write_domain = obj->write_domain; - obj->read_domains = obj->pending_read_domains; dev->invalidate_domains |= invalidate_domains; dev->flush_domains |= flush_domains; @@ -3136,10 +3128,6 @@ i915_gem_object_set_to_gpu_domain(struct drm_gem_object *obj, dev_priv->mm.flush_rings |= obj_priv->ring->id; if (invalidate_domains & I915_GEM_GPU_DOMAINS) dev_priv->mm.flush_rings |= ring->id; - - trace_i915_gem_object_change_domain(obj, - old_read_domains, - obj->write_domain); } /** @@ -3602,7 +3590,6 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, drm_i915_private_t *dev_priv = dev->dev_private; struct drm_gem_object **object_list = NULL; struct drm_gem_object *batch_obj; - struct drm_i915_gem_object *obj_priv; struct drm_clip_rect *cliprects = NULL; struct drm_i915_gem_request *request = NULL; int ret, i, flips; @@ -3697,6 +3684,8 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, /* Look up object handles */ for (i = 0; i < args->buffer_count; i++) { + struct drm_i915_gem_object *obj_priv; + object_list[i] = drm_gem_object_lookup(dev, file, exec_list[i].handle); if (object_list[i] == NULL) { @@ -3761,13 +3750,8 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, dev->invalidate_domains = 0; dev->flush_domains = 0; dev_priv->mm.flush_rings = 0; - - for (i = 0; i < args->buffer_count; i++) { - struct drm_gem_object *obj = object_list[i]; - - /* Compute new gpu domains and update invalidate/flush */ - i915_gem_object_set_to_gpu_domain(obj, ring); - } + for (i = 0; i < args->buffer_count; i++) + i915_gem_object_set_to_gpu_domain(object_list[i], ring); if (dev->invalidate_domains | dev->flush_domains) { #if WATCH_EXEC @@ -3782,15 +3766,6 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, dev_priv->mm.flush_rings); } - for (i = 0; i < args->buffer_count; i++) { - struct drm_gem_object *obj = object_list[i]; - uint32_t old_write_domain = obj->write_domain; - obj->write_domain = obj->pending_write_domain; - trace_i915_gem_object_change_domain(obj, - obj->read_domains, - old_write_domain); - } - #if WATCH_COHERENCY for (i = 0; i < args->buffer_count; i++) { i915_gem_object_check_coherency(object_list[i], @@ -3843,30 +3818,41 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, goto err; } - /* - * Ensure that the commands in the batch buffer are - * finished before the interrupt fires - */ - i915_retire_commands(dev, ring); - for (i = 0; i < args->buffer_count; i++) { struct drm_gem_object *obj = object_list[i]; + obj->read_domains = obj->pending_read_domains; + obj->write_domain = obj->pending_write_domain; + i915_gem_object_move_to_active(obj, ring); - if (obj->write_domain) - list_move_tail(&to_intel_bo(obj)->gpu_write_list, + if (obj->write_domain) { + struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); + obj_priv->dirty = 1; + list_move_tail(&obj_priv->gpu_write_list, &ring->gpu_write_list); + intel_mark_busy(dev, obj); + } + + trace_i915_gem_object_change_domain(obj, + obj->read_domains, + obj->write_domain); } + /* + * Ensure that the commands in the batch buffer are + * finished before the interrupt fires + */ + i915_retire_commands(dev, ring); + i915_add_request(dev, file, request, ring); request = NULL; err: for (i = 0; i < args->buffer_count; i++) { - if (object_list[i]) { - obj_priv = to_intel_bo(object_list[i]); - obj_priv->in_execbuffer = false; - } + if (object_list[i] == NULL) + break; + + to_intel_bo(object_list[i])->in_execbuffer = false; drm_gem_object_unreference(object_list[i]); } -- cgit v1.2.3 From 893eead092f14e42cac054a394a86e3c6e016b68 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 27 Oct 2010 14:44:35 +0100 Subject: drm/i915: Fix hangcheck to handle multiple rings Currently, we believe the GPU is idle if just the RENDER ring is idle. This is obviously wrong if we only using either the BLT or the BSD rings and so masking genuine hangs. Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_irq.c | 74 +++++++++++++++++++---------------------- 1 file changed, 35 insertions(+), 39 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 8acdd6d857d3..23b28528c642 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -1307,12 +1307,29 @@ int i915_vblank_swap(struct drm_device *dev, void *data, return -EINVAL; } -static struct drm_i915_gem_request * -i915_get_tail_request(struct drm_device *dev) +static u32 +ring_last_seqno(struct intel_ring_buffer *ring) { - drm_i915_private_t *dev_priv = dev->dev_private; - return list_entry(dev_priv->render_ring.request_list.prev, - struct drm_i915_gem_request, list); + return list_entry(ring->request_list.prev, + struct drm_i915_gem_request, list)->seqno; +} + +static bool i915_hangcheck_ring_idle(struct intel_ring_buffer *ring, bool *err) +{ + if (list_empty(&ring->request_list) || + i915_seqno_passed(ring->get_seqno(ring), ring_last_seqno(ring))) { + /* Issue a wake-up to catch stuck h/w. */ + if (ring->waiting_gem_seqno && waitqueue_active(&ring->irq_queue)) { + DRM_ERROR("Hangcheck timer elapsed... %s idle [waiting on %d, at %d], missed IRQ?\n", + ring->name, + ring->waiting_gem_seqno, + ring->get_seqno(ring)); + wake_up_all(&ring->irq_queue); + *err = true; + } + return true; + } + return false; } /** @@ -1326,6 +1343,17 @@ void i915_hangcheck_elapsed(unsigned long data) struct drm_device *dev = (struct drm_device *)data; drm_i915_private_t *dev_priv = dev->dev_private; uint32_t acthd, instdone, instdone1; + bool err = false; + + /* If all work is done then ACTHD clearly hasn't advanced. */ + if (i915_hangcheck_ring_idle(&dev_priv->render_ring, &err) && + i915_hangcheck_ring_idle(&dev_priv->bsd_ring, &err) && + i915_hangcheck_ring_idle(&dev_priv->blt_ring, &err)) { + dev_priv->hangcheck_count = 0; + if (err) + goto repeat; + return; + } if (INTEL_INFO(dev)->gen < 4) { acthd = I915_READ(ACTHD); @@ -1337,38 +1365,6 @@ void i915_hangcheck_elapsed(unsigned long data) instdone1 = I915_READ(INSTDONE1); } - /* If all work is done then ACTHD clearly hasn't advanced. */ - if (list_empty(&dev_priv->render_ring.request_list) || - i915_seqno_passed(dev_priv->render_ring.get_seqno(&dev_priv->render_ring), - i915_get_tail_request(dev)->seqno)) { - bool missed_wakeup = false; - - dev_priv->hangcheck_count = 0; - - /* Issue a wake-up to catch stuck h/w. */ - if (dev_priv->render_ring.waiting_gem_seqno && - waitqueue_active(&dev_priv->render_ring.irq_queue)) { - wake_up_all(&dev_priv->render_ring.irq_queue); - missed_wakeup = true; - } - - if (dev_priv->bsd_ring.waiting_gem_seqno && - waitqueue_active(&dev_priv->bsd_ring.irq_queue)) { - wake_up_all(&dev_priv->bsd_ring.irq_queue); - missed_wakeup = true; - } - - if (dev_priv->blt_ring.waiting_gem_seqno && - waitqueue_active(&dev_priv->blt_ring.irq_queue)) { - wake_up_all(&dev_priv->blt_ring.irq_queue); - missed_wakeup = true; - } - - if (missed_wakeup) - DRM_ERROR("Hangcheck timer elapsed... GPU idle, missed IRQ.\n"); - return; - } - if (dev_priv->last_acthd == acthd && dev_priv->last_instdone == instdone && dev_priv->last_instdone1 == instdone1) { @@ -1385,7 +1381,7 @@ void i915_hangcheck_elapsed(unsigned long data) if (tmp & RING_WAIT) { I915_WRITE(PRB0_CTL, tmp); POSTING_READ(PRB0_CTL); - goto out; + goto repeat; } } @@ -1400,7 +1396,7 @@ void i915_hangcheck_elapsed(unsigned long data) dev_priv->last_instdone1 = instdone1; } -out: +repeat: /* Reset timer case chip hangs without another request being added */ mod_timer(&dev_priv->hangcheck_timer, jiffies + msecs_to_jiffies(DRM_I915_HANGCHECK_PERIOD)); -- cgit v1.2.3 From c2c347a9eeda1b9b69c8fc393fd933747fbb2e11 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 27 Oct 2010 15:11:53 +0100 Subject: drm/i915/debugfs: Include info for the other rings The render ring is not alone any more! And the other rings are just as troublesome... Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_debugfs.c | 134 ++++++++++++++++++++++---------- drivers/gpu/drm/i915/intel_ringbuffer.h | 2 +- 2 files changed, 94 insertions(+), 42 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index c1b04b6056da..c5aa6bee3abb 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -48,6 +48,12 @@ enum { DEFERRED_FREE_LIST, }; +enum { + RENDER_RING, + BSD_RING, + BLT_RING, +}; + static const char *yesno(int v) { return v ? "yes" : "no"; @@ -265,21 +271,51 @@ static int i915_gem_request_info(struct seq_file *m, void *data) struct drm_device *dev = node->minor->dev; drm_i915_private_t *dev_priv = dev->dev_private; struct drm_i915_gem_request *gem_request; - int ret; + int ret, count; ret = mutex_lock_interruptible(&dev->struct_mutex); if (ret) return ret; - seq_printf(m, "Request:\n"); - list_for_each_entry(gem_request, &dev_priv->render_ring.request_list, - list) { - seq_printf(m, " %d @ %d\n", - gem_request->seqno, - (int) (jiffies - gem_request->emitted_jiffies)); + count = 0; + if (!list_empty(&dev_priv->render_ring.request_list)) { + seq_printf(m, "Render requests:\n"); + list_for_each_entry(gem_request, + &dev_priv->render_ring.request_list, + list) { + seq_printf(m, " %d @ %d\n", + gem_request->seqno, + (int) (jiffies - gem_request->emitted_jiffies)); + } + count++; + } + if (!list_empty(&dev_priv->bsd_ring.request_list)) { + seq_printf(m, "BSD requests:\n"); + list_for_each_entry(gem_request, + &dev_priv->bsd_ring.request_list, + list) { + seq_printf(m, " %d @ %d\n", + gem_request->seqno, + (int) (jiffies - gem_request->emitted_jiffies)); + } + count++; + } + if (!list_empty(&dev_priv->blt_ring.request_list)) { + seq_printf(m, "BLT requests:\n"); + list_for_each_entry(gem_request, + &dev_priv->blt_ring.request_list, + list) { + seq_printf(m, " %d @ %d\n", + gem_request->seqno, + (int) (jiffies - gem_request->emitted_jiffies)); + } + count++; } mutex_unlock(&dev->struct_mutex); + if (count == 0) + seq_printf(m, "No requests\n"); + return 0; } @@ -354,11 +390,17 @@ static int i915_interrupt_info(struct seq_file *m, void *data) } seq_printf(m, "Interrupts received: %d\n", atomic_read(&dev_priv->irq_received)); - if (dev_priv->render_ring.status_page.page_addr != NULL) { - seq_printf(m, "Current sequence: %d\n", + if (dev_priv->render_ring.get_seqno) { + seq_printf(m, "Current sequence (render): %d\n", dev_priv->render_ring.get_seqno(&dev_priv->render_ring)); - } else { - seq_printf(m, "Current sequence: hws uninitialized\n"); + } + if (dev_priv->bsd_ring.get_seqno) { + seq_printf(m, "Current sequence (BSD): %d\n", + dev_priv->bsd_ring.get_seqno(&dev_priv->bsd_ring)); + } + if (dev_priv->blt_ring.get_seqno) { + seq_printf(m, "Current sequence (BLT): %d\n", + dev_priv->blt_ring.get_seqno(&dev_priv->blt_ring)); } seq_printf(m, "Waiter sequence: %d\n", dev_priv->mm.waiting_gem_seqno); @@ -385,24 +427,12 @@ static int i915_gem_fence_regs_info(struct seq_file *m, void *data) for (i = 0; i < dev_priv->num_fence_regs; i++) { struct drm_gem_object *obj = dev_priv->fence_regs[i].obj; - if (obj == NULL) { - seq_printf(m, "Fenced object[%2d] = unused\n", i); - } else { - struct drm_i915_gem_object *obj_priv; - - obj_priv = to_intel_bo(obj); - seq_printf(m, "Fenced object[%2d] = %p: %s " - "%08x %08zx %08x %s %08x %08x %d", - i, obj, get_pin_flag(obj_priv), - obj_priv->gtt_offset, - obj->size, obj_priv->stride, - get_tiling_flag(obj_priv), - obj->read_domains, obj->write_domain, - obj_priv->last_rendering_seqno); - if (obj->name) - seq_printf(m, " (name: %d)", obj->name); - seq_printf(m, "\n"); - } + seq_printf(m, "Fenced object[%2d] = ", i); + if (obj == NULL) + seq_printf(m, "unused"); + else + describe_obj(m, to_intel_bo(obj)); + seq_printf(m, "\n"); } mutex_unlock(&dev->struct_mutex); @@ -477,19 +507,27 @@ static int i915_ringbuffer_data(struct seq_file *m, void *data) struct drm_info_node *node = (struct drm_info_node *) m->private; struct drm_device *dev = node->minor->dev; drm_i915_private_t *dev_priv = dev->dev_private; + struct intel_ring_buffer *ring; int ret; + switch ((uintptr_t)node->info_ent->data) { + case RENDER_RING: ring = &dev_priv->render_ring; break; + case BSD_RING: ring = &dev_priv->bsd_ring; break; + case BLT_RING: ring = &dev_priv->blt_ring; break; + default: return -EINVAL; + } + ret = mutex_lock_interruptible(&dev->struct_mutex); if (ret) return ret; - if (!dev_priv->render_ring.gem_object) { + if (!ring->gem_object) { seq_printf(m, "No ringbuffer setup\n"); } else { - u8 *virt = dev_priv->render_ring.virtual_start; + u8 *virt = ring->virtual_start; uint32_t off; - for (off = 0; off < dev_priv->render_ring.size; off += 4) { + for (off = 0; off < ring->size; off += 4) { uint32_t *ptr = (uint32_t *)(virt + off); seq_printf(m, "%08x : %08x\n", off, *ptr); } @@ -504,15 +542,25 @@ static int i915_ringbuffer_info(struct seq_file *m, void *data) struct drm_info_node *node = (struct drm_info_node *) m->private; struct drm_device *dev = node->minor->dev; drm_i915_private_t *dev_priv = dev->dev_private; - unsigned int head, tail; + struct intel_ring_buffer *ring; + + switch ((uintptr_t)node->info_ent->data) { + case RENDER_RING: ring = &dev_priv->render_ring; break; + case BSD_RING: ring = &dev_priv->bsd_ring; break; + case BLT_RING: ring = &dev_priv->blt_ring; break; + default: return -EINVAL; + } - head = I915_READ(PRB0_HEAD) & HEAD_ADDR; - tail = I915_READ(PRB0_TAIL) & TAIL_ADDR; + if (ring->size == 0) + return 0; - seq_printf(m, "RingHead : %08x\n", head); - seq_printf(m, "RingTail : %08x\n", tail); - seq_printf(m, "RingSize : %08lx\n", dev_priv->render_ring.size); - seq_printf(m, "Acthd : %08x\n", I915_READ(INTEL_INFO(dev)->gen >= 4 ? ACTHD_I965 : ACTHD)); + seq_printf(m, "Ring %s:\n", ring->name); + seq_printf(m, " Head : %08x\n", I915_READ_HEAD(ring) & HEAD_ADDR); + seq_printf(m, " Tail : %08x\n", I915_READ_TAIL(ring) & TAIL_ADDR); + seq_printf(m, " Size : %08x\n", ring->size); + seq_printf(m, " Active : %08x\n", intel_ring_get_active_head(ring)); + seq_printf(m, " Control : %08x\n", I915_READ_CTL(ring)); + seq_printf(m, " Start : %08x\n", I915_READ_START(ring)); return 0; } @@ -1029,8 +1077,12 @@ static struct drm_info_list i915_debugfs_list[] = { {"i915_gem_fence_regs", i915_gem_fence_regs_info, 0}, {"i915_gem_interrupt", i915_interrupt_info, 0}, {"i915_gem_hws", i915_hws_info, 0}, - {"i915_ringbuffer_data", i915_ringbuffer_data, 0}, - {"i915_ringbuffer_info", i915_ringbuffer_info, 0}, + {"i915_ringbuffer_data", i915_ringbuffer_data, 0, (void *)RENDER_RING}, + {"i915_ringbuffer_info", i915_ringbuffer_info, 0, (void *)RENDER_RING}, + {"i915_bsd_ringbuffer_data", i915_ringbuffer_data, 0, (void *)BSD_RING}, + {"i915_bsd_ringbuffer_info", i915_ringbuffer_info, 0, (void *)BSD_RING}, + {"i915_blt_ringbuffer_data", i915_ringbuffer_data, 0, (void *)BLT_RING}, + {"i915_blt_ringbuffer_info", i915_ringbuffer_info, 0, (void *)BLT_RING}, {"i915_batchbuffers", i915_batchbuffer_info, 0}, {"i915_error_state", i915_error_state, 0}, {"i915_rstdby_delays", i915_rstdby_delays, 0}, diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index 35ece2b87b02..84f6919de8e0 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -25,7 +25,6 @@ struct intel_ring_buffer { RING_BLT = 0x4, } id; u32 mmio_base; - unsigned long size; void *virtual_start; struct drm_device *dev; struct drm_gem_object *gem_object; @@ -33,6 +32,7 @@ struct intel_ring_buffer { unsigned int head; unsigned int tail; int space; + int size; struct intel_hw_status_page status_page; u32 irq_gem_seqno; /* last seq seem at irq time */ -- cgit v1.2.3 From b2223497b44a4701d1be873d1e9453d7f720043b Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 27 Oct 2010 15:27:33 +0100 Subject: drm/i915: Remove the confusing global waiting/irq seqno Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_debugfs.c | 44 ++++++++++++++------------------- drivers/gpu/drm/i915/i915_drv.h | 10 -------- drivers/gpu/drm/i915/i915_gem.c | 4 +-- drivers/gpu/drm/i915/i915_irq.c | 6 ++--- drivers/gpu/drm/i915/intel_ringbuffer.h | 4 +-- 5 files changed, 26 insertions(+), 42 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index c5aa6bee3abb..beb3de7921b5 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -319,6 +319,19 @@ static int i915_gem_request_info(struct seq_file *m, void *data) return 0; } +static void i915_ring_seqno_info(struct seq_file *m, + struct intel_ring_buffer *ring) +{ + if (ring->get_seqno) { + seq_printf(m, "Current sequence (%s): %d\n", + ring->name, ring->get_seqno(ring)); + seq_printf(m, "Waiter sequence (%s): %d\n", + ring->name, ring->waiting_seqno); + seq_printf(m, "IRQ sequence (%s): %d\n", + ring->name, ring->irq_seqno); + } +} + static int i915_gem_seqno_info(struct seq_file *m, void *data) { struct drm_info_node *node = (struct drm_info_node *) m->private; @@ -330,15 +343,9 @@ static int i915_gem_seqno_info(struct seq_file *m, void *data) if (ret) return ret; - if (dev_priv->render_ring.status_page.page_addr != NULL) { - seq_printf(m, "Current sequence: %d\n", - dev_priv->render_ring.get_seqno(&dev_priv->render_ring)); - } else { - seq_printf(m, "Current sequence: hws uninitialized\n"); - } - seq_printf(m, "Waiter sequence: %d\n", - dev_priv->mm.waiting_gem_seqno); - seq_printf(m, "IRQ sequence: %d\n", dev_priv->mm.irq_gem_seqno); + i915_ring_seqno_info(m, &dev_priv->render_ring); + i915_ring_seqno_info(m, &dev_priv->bsd_ring); + i915_ring_seqno_info(m, &dev_priv->blt_ring); mutex_unlock(&dev->struct_mutex); @@ -390,22 +397,9 @@ static int i915_interrupt_info(struct seq_file *m, void *data) } seq_printf(m, "Interrupts received: %d\n", atomic_read(&dev_priv->irq_received)); - if (dev_priv->render_ring.get_seqno) { - seq_printf(m, "Current sequence (render): %d\n", - dev_priv->render_ring.get_seqno(&dev_priv->render_ring)); - } - if (dev_priv->bsd_ring.get_seqno) { - seq_printf(m, "Current sequence (BSD): %d\n", - dev_priv->bsd_ring.get_seqno(&dev_priv->bsd_ring)); - } - if (dev_priv->blt_ring.get_seqno) { - seq_printf(m, "Current sequence (BLT): %d\n", - dev_priv->blt_ring.get_seqno(&dev_priv->blt_ring)); - } - seq_printf(m, "Waiter sequence: %d\n", - dev_priv->mm.waiting_gem_seqno); - seq_printf(m, "IRQ sequence: %d\n", - dev_priv->mm.irq_gem_seqno); + i915_ring_seqno_info(m, &dev_priv->render_ring); + i915_ring_seqno_info(m, &dev_priv->bsd_ring); + i915_ring_seqno_info(m, &dev_priv->blt_ring); mutex_unlock(&dev->struct_mutex); return 0; diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index c241468c632e..2af8e1604b44 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -608,16 +608,6 @@ typedef struct drm_i915_private { */ struct delayed_work retire_work; - /** - * Waiting sequence number, if any - */ - uint32_t waiting_gem_seqno; - - /** - * Last seq seen at irq time - */ - uint32_t irq_gem_seqno; - /** * Flag if the X Server, and thus DRM, is not currently in * control of the device. diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 580244c1e793..74f5525d156f 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1984,7 +1984,7 @@ i915_do_wait_request(struct drm_device *dev, uint32_t seqno, trace_i915_gem_request_wait_begin(dev, seqno); - ring->waiting_gem_seqno = seqno; + ring->waiting_seqno = seqno; ring->user_irq_get(ring); if (interruptible) ret = wait_event_interruptible(ring->irq_queue, @@ -1996,7 +1996,7 @@ i915_do_wait_request(struct drm_device *dev, uint32_t seqno, || atomic_read(&dev_priv->mm.wedged)); ring->user_irq_put(ring); - ring->waiting_gem_seqno = 0; + ring->waiting_seqno = 0; trace_i915_gem_request_wait_end(dev, seqno); } diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 23b28528c642..29cbcb33b92c 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -298,7 +298,7 @@ static void notify_ring(struct drm_device *dev, { struct drm_i915_private *dev_priv = dev->dev_private; u32 seqno = ring->get_seqno(ring); - ring->irq_gem_seqno = seqno; + ring->irq_seqno = seqno; trace_i915_gem_request_complete(dev, seqno); wake_up_all(&ring->irq_queue); dev_priv->hangcheck_count = 0; @@ -1319,10 +1319,10 @@ static bool i915_hangcheck_ring_idle(struct intel_ring_buffer *ring, bool *err) if (list_empty(&ring->request_list) || i915_seqno_passed(ring->get_seqno(ring), ring_last_seqno(ring))) { /* Issue a wake-up to catch stuck h/w. */ - if (ring->waiting_gem_seqno && waitqueue_active(&ring->irq_queue)) { + if (ring->waiting_seqno && waitqueue_active(&ring->irq_queue)) { DRM_ERROR("Hangcheck timer elapsed... %s idle [waiting on %d, at %d], missed IRQ?\n", ring->name, - ring->waiting_gem_seqno, + ring->waiting_seqno, ring->get_seqno(ring)); wake_up_all(&ring->irq_queue); *err = true; diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index 84f6919de8e0..7ad9e94220b4 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -35,8 +35,8 @@ struct intel_ring_buffer { int size; struct intel_hw_status_page status_page; - u32 irq_gem_seqno; /* last seq seem at irq time */ - u32 waiting_gem_seqno; + u32 irq_seqno; /* last seq seem at irq time */ + u32 waiting_seqno; int user_irq_refcount; void (*user_irq_get)(struct intel_ring_buffer *ring); void (*user_irq_put)(struct intel_ring_buffer *ring); -- cgit v1.2.3 From 3cce469cab880ef8990d2d16d745bf85443fc998 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 27 Oct 2010 16:11:02 +0100 Subject: drm/i915: Propagate error from failing to queue a request Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_drv.h | 8 +- drivers/gpu/drm/i915/i915_gem.c | 36 ++++++--- drivers/gpu/drm/i915/intel_overlay.c | 20 +++-- drivers/gpu/drm/i915/intel_ringbuffer.c | 128 +++++++++++++++++--------------- drivers/gpu/drm/i915/intel_ringbuffer.h | 4 +- 5 files changed, 111 insertions(+), 85 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 2af8e1604b44..f168e82c10aa 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1041,10 +1041,10 @@ int i915_gem_do_init(struct drm_device *dev, unsigned long start, unsigned long end); int i915_gpu_idle(struct drm_device *dev); int i915_gem_idle(struct drm_device *dev); -uint32_t i915_add_request(struct drm_device *dev, - struct drm_file *file_priv, - struct drm_i915_gem_request *request, - struct intel_ring_buffer *ring); +int i915_add_request(struct drm_device *dev, + struct drm_file *file_priv, + struct drm_i915_gem_request *request, + struct intel_ring_buffer *ring); int i915_do_wait_request(struct drm_device *dev, uint32_t seqno, bool interruptible, diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 74f5525d156f..d0aaf97ac6e0 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1683,7 +1683,7 @@ i915_gem_process_flushing_list(struct drm_device *dev, } } -uint32_t +int i915_add_request(struct drm_device *dev, struct drm_file *file, struct drm_i915_gem_request *request, @@ -1693,17 +1693,17 @@ i915_add_request(struct drm_device *dev, struct drm_i915_file_private *file_priv = NULL; uint32_t seqno; int was_empty; + int ret; + + BUG_ON(request == NULL); if (file != NULL) file_priv = file->driver_priv; - if (request == NULL) { - request = kzalloc(sizeof(*request), GFP_KERNEL); - if (request == NULL) - return 0; - } + ret = ring->add_request(ring, &seqno); + if (ret) + return ret; - seqno = ring->add_request(ring, 0); ring->outstanding_lazy_request = false; request->seqno = seqno; @@ -1727,7 +1727,7 @@ i915_add_request(struct drm_device *dev, queue_delayed_work(dev_priv->wq, &dev_priv->mm.retire_work, HZ); } - return seqno; + return 0; } /** @@ -1964,9 +1964,19 @@ i915_do_wait_request(struct drm_device *dev, uint32_t seqno, return -EAGAIN; if (ring->outstanding_lazy_request) { - seqno = i915_add_request(dev, NULL, NULL, ring); - if (seqno == 0) + struct drm_i915_gem_request *request; + + request = kzalloc(sizeof(*request), GFP_KERNEL); + if (request == NULL) return -ENOMEM; + + ret = i915_add_request(dev, NULL, request, ring); + if (ret) { + kfree(request); + return ret; + } + + seqno = request->seqno; } BUG_ON(seqno == dev_priv->next_seqno); @@ -3844,8 +3854,10 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, */ i915_retire_commands(dev, ring); - i915_add_request(dev, file, request, ring); - request = NULL; + if (i915_add_request(dev, file, request, ring)) + ring->outstanding_lazy_request = true; + else + request = NULL; err: for (i = 0; i < args->buffer_count; i++) { diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c index 78fa6a249964..2d4a6968cd76 100644 --- a/drivers/gpu/drm/i915/intel_overlay.c +++ b/drivers/gpu/drm/i915/intel_overlay.c @@ -221,11 +221,12 @@ static int intel_overlay_do_wait_request(struct intel_overlay *overlay, int ret; BUG_ON(overlay->last_flip_req); - overlay->last_flip_req = - i915_add_request(dev, NULL, request, &dev_priv->render_ring); - if (overlay->last_flip_req == 0) - return -ENOMEM; - + ret = i915_add_request(dev, NULL, request, &dev_priv->render_ring); + if (ret) { + kfree(request); + return ret; + } + overlay->last_flip_req = request->seqno; overlay->flip_tail = tail; ret = i915_do_wait_request(dev, overlay->last_flip_req, true, @@ -363,8 +364,13 @@ static int intel_overlay_continue(struct intel_overlay *overlay, OUT_RING(flip_addr); ADVANCE_LP_RING(); - overlay->last_flip_req = - i915_add_request(dev, NULL, request, &dev_priv->render_ring); + ret = i915_add_request(dev, NULL, request, &dev_priv->render_ring); + if (ret) { + kfree(request); + return ret; + } + + overlay->last_flip_req = request->seqno; return 0; } diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 6fe42c1f4ea9..4803b32f308f 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -234,28 +234,28 @@ do { \ * * Returned sequence numbers are nonzero on success. */ -static u32 +static int render_ring_add_request(struct intel_ring_buffer *ring, - u32 flush_domains) + u32 *result) { struct drm_device *dev = ring->dev; drm_i915_private_t *dev_priv = dev->dev_private; - u32 seqno; - - seqno = i915_gem_get_seqno(dev); + u32 seqno = i915_gem_get_seqno(dev); + int ret; if (IS_GEN6(dev)) { - if (intel_ring_begin(ring, 6) == 0) { - intel_ring_emit(ring, GFX_OP_PIPE_CONTROL | 3); - intel_ring_emit(ring, PIPE_CONTROL_QW_WRITE | - PIPE_CONTROL_WC_FLUSH | PIPE_CONTROL_IS_FLUSH | - PIPE_CONTROL_NOTIFY); - intel_ring_emit(ring, dev_priv->seqno_gfx_addr | PIPE_CONTROL_GLOBAL_GTT); - intel_ring_emit(ring, seqno); - intel_ring_emit(ring, 0); - intel_ring_emit(ring, 0); - intel_ring_advance(ring); - } + ret = intel_ring_begin(ring, 6); + if (ret) + return ret; + + intel_ring_emit(ring, GFX_OP_PIPE_CONTROL | 3); + intel_ring_emit(ring, PIPE_CONTROL_QW_WRITE | + PIPE_CONTROL_WC_FLUSH | PIPE_CONTROL_IS_FLUSH | + PIPE_CONTROL_NOTIFY); + intel_ring_emit(ring, dev_priv->seqno_gfx_addr | PIPE_CONTROL_GLOBAL_GTT); + intel_ring_emit(ring, seqno); + intel_ring_emit(ring, 0); + intel_ring_emit(ring, 0); } else if (HAS_PIPE_CONTROL(dev)) { u32 scratch_addr = dev_priv->seqno_gfx_addr + 128; @@ -264,42 +264,47 @@ render_ring_add_request(struct intel_ring_buffer *ring, * PIPE_NOTIFY buffers out to memory before requesting * an interrupt. */ - if (intel_ring_begin(ring, 32) == 0) { - intel_ring_emit(ring, GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE | - PIPE_CONTROL_WC_FLUSH | PIPE_CONTROL_TC_FLUSH); - intel_ring_emit(ring, dev_priv->seqno_gfx_addr | PIPE_CONTROL_GLOBAL_GTT); - intel_ring_emit(ring, seqno); - intel_ring_emit(ring, 0); - PIPE_CONTROL_FLUSH(ring, scratch_addr); - scratch_addr += 128; /* write to separate cachelines */ - PIPE_CONTROL_FLUSH(ring, scratch_addr); - scratch_addr += 128; - PIPE_CONTROL_FLUSH(ring, scratch_addr); - scratch_addr += 128; - PIPE_CONTROL_FLUSH(ring, scratch_addr); - scratch_addr += 128; - PIPE_CONTROL_FLUSH(ring, scratch_addr); - scratch_addr += 128; - PIPE_CONTROL_FLUSH(ring, scratch_addr); - intel_ring_emit(ring, GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE | - PIPE_CONTROL_WC_FLUSH | PIPE_CONTROL_TC_FLUSH | - PIPE_CONTROL_NOTIFY); - intel_ring_emit(ring, dev_priv->seqno_gfx_addr | PIPE_CONTROL_GLOBAL_GTT); - intel_ring_emit(ring, seqno); - intel_ring_emit(ring, 0); - intel_ring_advance(ring); - } + ret = intel_ring_begin(ring, 32); + if (ret) + return ret; + + intel_ring_emit(ring, GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE | + PIPE_CONTROL_WC_FLUSH | PIPE_CONTROL_TC_FLUSH); + intel_ring_emit(ring, dev_priv->seqno_gfx_addr | PIPE_CONTROL_GLOBAL_GTT); + intel_ring_emit(ring, seqno); + intel_ring_emit(ring, 0); + PIPE_CONTROL_FLUSH(ring, scratch_addr); + scratch_addr += 128; /* write to separate cachelines */ + PIPE_CONTROL_FLUSH(ring, scratch_addr); + scratch_addr += 128; + PIPE_CONTROL_FLUSH(ring, scratch_addr); + scratch_addr += 128; + PIPE_CONTROL_FLUSH(ring, scratch_addr); + scratch_addr += 128; + PIPE_CONTROL_FLUSH(ring, scratch_addr); + scratch_addr += 128; + PIPE_CONTROL_FLUSH(ring, scratch_addr); + intel_ring_emit(ring, GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE | + PIPE_CONTROL_WC_FLUSH | PIPE_CONTROL_TC_FLUSH | + PIPE_CONTROL_NOTIFY); + intel_ring_emit(ring, dev_priv->seqno_gfx_addr | PIPE_CONTROL_GLOBAL_GTT); + intel_ring_emit(ring, seqno); + intel_ring_emit(ring, 0); } else { - if (intel_ring_begin(ring, 4) == 0) { - intel_ring_emit(ring, MI_STORE_DWORD_INDEX); - intel_ring_emit(ring, I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT); - intel_ring_emit(ring, seqno); + ret = intel_ring_begin(ring, 4); + if (ret) + return ret; - intel_ring_emit(ring, MI_USER_INTERRUPT); - intel_ring_advance(ring); - } + intel_ring_emit(ring, MI_STORE_DWORD_INDEX); + intel_ring_emit(ring, I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT); + intel_ring_emit(ring, seqno); + + intel_ring_emit(ring, MI_USER_INTERRUPT); } - return seqno; + + intel_ring_advance(ring); + *result = seqno; + return 0; } static u32 @@ -370,25 +375,28 @@ bsd_ring_flush(struct intel_ring_buffer *ring, } } -static u32 +static int ring_add_request(struct intel_ring_buffer *ring, - u32 flush_domains) + u32 *result) { u32 seqno; + int ret; + + ret = intel_ring_begin(ring, 4); + if (ret) + return ret; seqno = i915_gem_get_seqno(ring->dev); - if (intel_ring_begin(ring, 4) == 0) { - intel_ring_emit(ring, MI_STORE_DWORD_INDEX); - intel_ring_emit(ring, I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT); - intel_ring_emit(ring, seqno); - intel_ring_emit(ring, MI_USER_INTERRUPT); - intel_ring_advance(ring); - } + intel_ring_emit(ring, MI_STORE_DWORD_INDEX); + intel_ring_emit(ring, I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT); + intel_ring_emit(ring, seqno); + intel_ring_emit(ring, MI_USER_INTERRUPT); + intel_ring_advance(ring); DRM_DEBUG_DRIVER("%s %d\n", ring->name, seqno); - - return seqno; + *result = seqno; + return 0; } static void diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index 7ad9e94220b4..acd23374fe89 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -48,8 +48,8 @@ struct intel_ring_buffer { void (*flush)(struct intel_ring_buffer *ring, u32 invalidate_domains, u32 flush_domains); - u32 (*add_request)(struct intel_ring_buffer *ring, - u32 flush_domains); + int (*add_request)(struct intel_ring_buffer *ring, + u32 *seqno); u32 (*get_seqno)(struct intel_ring_buffer *ring); int (*dispatch_execbuffer)(struct intel_ring_buffer *ring, struct drm_i915_gem_execbuffer2 *exec, -- cgit v1.2.3 From d935cc61d466f6cc7514032835f4fc379cb7e2ca Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Thu, 16 Sep 2010 15:13:11 +0200 Subject: drm_mm: add support for range-restricted fair-lru scans Signed-off-by: Daniel Vetter Signed-off-by: Chris Wilson --- drivers/gpu/drm/drm_mm.c | 40 +++++++++++++++++++++++++++++++++++++++- include/drm/drm_mm.h | 7 +++++++ 2 files changed, 46 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c index a6bfc302ed90..c59515ba7e69 100644 --- a/drivers/gpu/drm/drm_mm.c +++ b/drivers/gpu/drm/drm_mm.c @@ -392,9 +392,35 @@ void drm_mm_init_scan(struct drm_mm *mm, unsigned long size, mm->scanned_blocks = 0; mm->scan_hit_start = 0; mm->scan_hit_size = 0; + mm->scan_check_range = 0; } EXPORT_SYMBOL(drm_mm_init_scan); +/** + * Initializa lru scanning. + * + * This simply sets up the scanning routines with the parameters for the desired + * hole. This version is for range-restricted scans. + * + * Warning: As long as the scan list is non-empty, no other operations than + * adding/removing nodes to/from the scan list are allowed. + */ +void drm_mm_init_scan_with_range(struct drm_mm *mm, unsigned long size, + unsigned alignment, + unsigned long start, + unsigned long end) +{ + mm->scan_alignment = alignment; + mm->scan_size = size; + mm->scanned_blocks = 0; + mm->scan_hit_start = 0; + mm->scan_hit_size = 0; + mm->scan_start = start; + mm->scan_end = end; + mm->scan_check_range = 1; +} +EXPORT_SYMBOL(drm_mm_init_scan_with_range); + /** * Add a node to the scan list that might be freed to make space for the desired * hole. @@ -406,6 +432,8 @@ int drm_mm_scan_add_block(struct drm_mm_node *node) struct drm_mm *mm = node->mm; struct list_head *prev_free, *next_free; struct drm_mm_node *prev_node, *next_node; + unsigned long adj_start; + unsigned long adj_end; mm->scanned_blocks++; @@ -452,7 +480,17 @@ int drm_mm_scan_add_block(struct drm_mm_node *node) node->free_stack.prev = prev_free; node->free_stack.next = next_free; - if (check_free_hole(node->start, node->start + node->size, + if (mm->scan_check_range) { + adj_start = node->start < mm->scan_start ? + mm->scan_start : node->start; + adj_end = node->start + node->size > mm->scan_end ? + mm->scan_end : node->start + node->size; + } else { + adj_start = node->start; + adj_end = node->start + node->size; + } + + if (check_free_hole(adj_start , adj_end, mm->scan_size, mm->scan_alignment)) { mm->scan_hit_start = node->start; mm->scan_hit_size = node->size; diff --git a/include/drm/drm_mm.h b/include/drm/drm_mm.h index bf01531193d5..e39177778601 100644 --- a/include/drm/drm_mm.h +++ b/include/drm/drm_mm.h @@ -62,11 +62,14 @@ struct drm_mm { struct list_head unused_nodes; int num_unused; spinlock_t unused_lock; + unsigned int scan_check_range : 1; unsigned scan_alignment; unsigned long scan_size; unsigned long scan_hit_start; unsigned scan_hit_size; unsigned scanned_blocks; + unsigned long scan_start; + unsigned long scan_end; }; /* @@ -145,6 +148,10 @@ static inline struct drm_mm *drm_get_mm(struct drm_mm_node *block) void drm_mm_init_scan(struct drm_mm *mm, unsigned long size, unsigned alignment); +void drm_mm_init_scan_with_range(struct drm_mm *mm, unsigned long size, + unsigned alignment, + unsigned long start, + unsigned long end); int drm_mm_scan_add_block(struct drm_mm_node *node); int drm_mm_scan_remove_block(struct drm_mm_node *node); -- cgit v1.2.3 From a6e0aa421406dc4cfd736c6d07d26ed39ab4f7bc Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Thu, 16 Sep 2010 15:45:15 +0200 Subject: drm/i915: range-restricted eviction support Add a mappable parameter to i915_gem_evict_something to distinguish the two cases (non-restricted vs. mappable gtt allocations). No functional changes because the mappable limit is set to the end of the gtt currently. Signed-off-by: Daniel Vetter Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_drv.h | 5 ++++- drivers/gpu/drm/i915/i915_gem.c | 10 ++++++---- drivers/gpu/drm/i915/i915_gem_evict.c | 24 +++++++++++++++++++----- 3 files changed, 29 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index f168e82c10aa..dc0a21a3489b 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -535,6 +535,8 @@ typedef struct drm_i915_private { struct drm_mm vram; /** Memory allocator for GTT */ struct drm_mm gtt_space; + /** End of mappable part of GTT */ + unsigned long gtt_mappable_end; struct io_mapping *gtt_mapping; int gtt_mtrr; @@ -1067,7 +1069,8 @@ void i915_gem_shrinker_init(void); void i915_gem_shrinker_exit(void); /* i915_gem_evict.c */ -int i915_gem_evict_something(struct drm_device *dev, int min_size, unsigned alignment); +int i915_gem_evict_something(struct drm_device *dev, int min_size, + unsigned alignment, bool mappable); int i915_gem_evict_everything(struct drm_device *dev); int i915_gem_evict_inactive(struct drm_device *dev); diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index d0aaf97ac6e0..254eb0c46aeb 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -187,6 +187,7 @@ int i915_gem_do_init(struct drm_device *dev, end - start); dev_priv->mm.gtt_total = end - start; + dev_priv->mm.gtt_mappable_end = end; return 0; } @@ -413,7 +414,8 @@ i915_gem_object_get_pages_or_evict(struct drm_gem_object *obj) struct drm_device *dev = obj->dev; ret = i915_gem_evict_something(dev, obj->size, - i915_gem_get_gtt_alignment(obj)); + i915_gem_get_gtt_alignment(obj), + false); if (ret) return ret; @@ -2672,7 +2674,7 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment) /* If the gtt is empty and we're still having trouble * fitting our object in, we're out of memory. */ - ret = i915_gem_evict_something(dev, obj->size, alignment); + ret = i915_gem_evict_something(dev, obj->size, alignment, true); if (ret) return ret; @@ -2687,7 +2689,7 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment) if (ret == -ENOMEM) { /* first try to clear up some space from the GTT */ ret = i915_gem_evict_something(dev, obj->size, - alignment); + alignment, true); if (ret) { /* now try to shrink everyone else */ if (gfpmask) { @@ -2717,7 +2719,7 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment) drm_mm_put_block(obj_priv->gtt_space); obj_priv->gtt_space = NULL; - ret = i915_gem_evict_something(dev, obj->size, alignment); + ret = i915_gem_evict_something(dev, obj->size, alignment, true); if (ret) return ret; diff --git a/drivers/gpu/drm/i915/i915_gem_evict.c b/drivers/gpu/drm/i915/i915_gem_evict.c index 43a4013f53fa..3a4215f31652 100644 --- a/drivers/gpu/drm/i915/i915_gem_evict.c +++ b/drivers/gpu/drm/i915/i915_gem_evict.c @@ -41,7 +41,8 @@ mark_free(struct drm_i915_gem_object *obj_priv, } int -i915_gem_evict_something(struct drm_device *dev, int min_size, unsigned alignment) +i915_gem_evict_something(struct drm_device *dev, int min_size, + unsigned alignment, bool mappable) { drm_i915_private_t *dev_priv = dev->dev_private; struct list_head eviction_list, unwind_list; @@ -51,9 +52,17 @@ i915_gem_evict_something(struct drm_device *dev, int min_size, unsigned alignmen i915_gem_retire_requests(dev); /* Re-check for free space after retiring requests */ - if (drm_mm_search_free(&dev_priv->mm.gtt_space, - min_size, alignment, 0)) - return 0; + if (mappable) { + if (drm_mm_search_free_in_range(&dev_priv->mm.gtt_space, + min_size, alignment, 0, + dev_priv->mm.gtt_mappable_end, + 0)) + return 0; + } else { + if (drm_mm_search_free(&dev_priv->mm.gtt_space, + min_size, alignment, 0)) + return 0; + } /* * The goal is to evict objects and amalgamate space in LRU order. @@ -79,7 +88,12 @@ i915_gem_evict_something(struct drm_device *dev, int min_size, unsigned alignmen */ INIT_LIST_HEAD(&unwind_list); - drm_mm_init_scan(&dev_priv->mm.gtt_space, min_size, alignment); + if (mappable) + drm_mm_init_scan_with_range(&dev_priv->mm.gtt_space, min_size, + alignment, 0, + dev_priv->mm.gtt_mappable_end); + else + drm_mm_init_scan(&dev_priv->mm.gtt_space, min_size, alignment); /* First see if there is a large enough contiguous idle region... */ list_for_each_entry(obj_priv, &dev_priv->mm.inactive_list, mm_list) { -- cgit v1.2.3 From 920afa77ced7124c8bb7d0c4839885618a3b4a54 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Thu, 16 Sep 2010 17:54:23 +0200 Subject: drm/i915: range-restricted bind_to_gtt Like before add a parameter mappable (also to gem_object_pin) and set it depending upon the context. Only bos that are brought into the gtt due to an execbuffer call can be put into the unmappable part of the gtt, everything else (especially pinned objects) need to be put into the mappable part of the gtt. Signed-off-by: Daniel Vetter Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_drv.h | 3 +- drivers/gpu/drm/i915/i915_gem.c | 63 +++++++++++++++++++++++---------- drivers/gpu/drm/i915/intel_display.c | 6 ++-- drivers/gpu/drm/i915/intel_overlay.c | 4 +-- drivers/gpu/drm/i915/intel_ringbuffer.c | 4 +-- 5 files changed, 53 insertions(+), 27 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index dc0a21a3489b..263bb0506247 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1012,7 +1012,8 @@ int i915_gem_init_object(struct drm_gem_object *obj); struct drm_gem_object * i915_gem_alloc_object(struct drm_device *dev, size_t size); void i915_gem_free_object(struct drm_gem_object *obj); -int i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment); +int i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment, + bool mappable); void i915_gem_object_unpin(struct drm_gem_object *obj); int i915_gem_object_unbind(struct drm_gem_object *obj); void i915_gem_release_mmap(struct drm_gem_object *obj); diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 254eb0c46aeb..ef14546fc08d 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -51,7 +51,7 @@ static void i915_gem_object_set_to_full_cpu_read_domain(struct drm_gem_object *o static int i915_gem_object_wait_rendering(struct drm_gem_object *obj, bool interruptible); static int i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, - unsigned alignment); + unsigned alignment, bool mappable); static void i915_gem_clear_fence_reg(struct drm_gem_object *obj); static int i915_gem_phys_pwrite(struct drm_device *dev, struct drm_gem_object *obj, struct drm_i915_gem_pwrite *args, @@ -1031,7 +1031,7 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data, else if (obj_priv->tiling_mode == I915_TILING_NONE && obj_priv->gtt_space && obj->write_domain != I915_GEM_DOMAIN_CPU) { - ret = i915_gem_object_pin(obj, 0); + ret = i915_gem_object_pin(obj, 0, true); if (ret) goto out; @@ -1256,7 +1256,7 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) /* Now bind it into the GTT if needed */ mutex_lock(&dev->struct_mutex); if (!obj_priv->gtt_space) { - ret = i915_gem_object_bind_to_gtt(obj, 0); + ret = i915_gem_object_bind_to_gtt(obj, 0, true); if (ret) goto unlock; @@ -1506,7 +1506,7 @@ i915_gem_mmap_gtt_ioctl(struct drm_device *dev, void *data, * initial fault faster and any subsequent flushing possible). */ if (!obj_priv->agp_mem) { - ret = i915_gem_object_bind_to_gtt(obj, 0); + ret = i915_gem_object_bind_to_gtt(obj, 0, true); if (ret) goto out; } @@ -2635,7 +2635,9 @@ i915_gem_object_put_fence_reg(struct drm_gem_object *obj, * Finds free space in the GTT aperture and binds the object there. */ static int -i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment) +i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, + unsigned alignment, + bool mappable) { struct drm_device *dev = obj->dev; drm_i915_private_t *dev_priv = dev->dev_private; @@ -2659,22 +2661,42 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment) /* If the object is bigger than the entire aperture, reject it early * before evicting everything in a vain attempt to find space. */ - if (obj->size > dev_priv->mm.gtt_total) { + if (obj->size > + (mappable ? dev_priv->mm.gtt_mappable_end : dev_priv->mm.gtt_total)) { DRM_ERROR("Attempting to bind an object larger than the aperture\n"); return -E2BIG; } search_free: - free_space = drm_mm_search_free(&dev_priv->mm.gtt_space, - obj->size, alignment, 0); - if (free_space != NULL) - obj_priv->gtt_space = drm_mm_get_block(free_space, obj->size, - alignment); + if (mappable) + free_space = + drm_mm_search_free_in_range(&dev_priv->mm.gtt_space, + obj->size, alignment, 0, + dev_priv->mm.gtt_mappable_end, + 0); + else + free_space = drm_mm_search_free(&dev_priv->mm.gtt_space, + obj->size, alignment, 0); + + if (free_space != NULL) { + if (mappable) + obj_priv->gtt_space = + drm_mm_get_block_range_generic(free_space, + obj->size, + alignment, 0, + dev_priv->mm.gtt_mappable_end, + 0); + else + obj_priv->gtt_space = + drm_mm_get_block(free_space, obj->size, + alignment); + } if (obj_priv->gtt_space == NULL) { /* If the gtt is empty and we're still having trouble * fitting our object in, we're out of memory. */ - ret = i915_gem_evict_something(dev, obj->size, alignment, true); + ret = i915_gem_evict_something(dev, obj->size, alignment, + mappable); if (ret) return ret; @@ -2689,7 +2711,7 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment) if (ret == -ENOMEM) { /* first try to clear up some space from the GTT */ ret = i915_gem_evict_something(dev, obj->size, - alignment, true); + alignment, mappable); if (ret) { /* now try to shrink everyone else */ if (gfpmask) { @@ -2719,7 +2741,8 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment) drm_mm_put_block(obj_priv->gtt_space); obj_priv->gtt_space = NULL; - ret = i915_gem_evict_something(dev, obj->size, alignment, true); + ret = i915_gem_evict_something(dev, obj->size, alignment, + mappable); if (ret) return ret; @@ -3456,7 +3479,8 @@ i915_gem_execbuffer_pin(struct drm_device *dev, break; } - ret = i915_gem_object_pin(&obj->base, entry->alignment); + ret = i915_gem_object_pin(&obj->base, + entry->alignment, true); if (ret) break; @@ -4026,7 +4050,8 @@ i915_gem_execbuffer2(struct drm_device *dev, void *data, } int -i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment) +i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment, + bool mappable) { struct drm_device *dev = obj->dev; struct drm_i915_private *dev_priv = dev->dev_private; @@ -4051,7 +4076,7 @@ i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment) } if (obj_priv->gtt_space == NULL) { - ret = i915_gem_object_bind_to_gtt(obj, alignment); + ret = i915_gem_object_bind_to_gtt(obj, alignment, mappable); if (ret) return ret; } @@ -4133,7 +4158,7 @@ i915_gem_pin_ioctl(struct drm_device *dev, void *data, obj_priv->user_pin_count++; obj_priv->pin_filp = file_priv; if (obj_priv->user_pin_count == 1) { - ret = i915_gem_object_pin(obj, args->alignment); + ret = i915_gem_object_pin(obj, args->alignment, true); if (ret) goto out; } @@ -4445,7 +4470,7 @@ i915_gem_init_pipe_control(struct drm_device *dev) obj_priv = to_intel_bo(obj); obj_priv->agp_type = AGP_USER_CACHED_MEMORY; - ret = i915_gem_object_pin(obj, 4096); + ret = i915_gem_object_pin(obj, 4096, true); if (ret) goto err_unref; diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index eb4c725e3069..c9c4c707cf1a 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -1461,7 +1461,7 @@ intel_pin_and_fence_fb_obj(struct drm_device *dev, BUG(); } - ret = i915_gem_object_pin(obj, alignment); + ret = i915_gem_object_pin(obj, alignment, true); if (ret) return ret; @@ -4353,7 +4353,7 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc, /* we only need to pin inside GTT if cursor is non-phy */ mutex_lock(&dev->struct_mutex); if (!dev_priv->info->cursor_needs_physical) { - ret = i915_gem_object_pin(bo, PAGE_SIZE); + ret = i915_gem_object_pin(bo, PAGE_SIZE, true); if (ret) { DRM_ERROR("failed to pin cursor bo\n"); goto fail_locked; @@ -5517,7 +5517,7 @@ intel_alloc_context_page(struct drm_device *dev) } mutex_lock(&dev->struct_mutex); - ret = i915_gem_object_pin(ctx, 4096); + ret = i915_gem_object_pin(ctx, 4096, true); if (ret) { DRM_ERROR("failed to pin power context: %d\n", ret); goto err_unref; diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c index 2d4a6968cd76..beda2016eb16 100644 --- a/drivers/gpu/drm/i915/intel_overlay.c +++ b/drivers/gpu/drm/i915/intel_overlay.c @@ -781,7 +781,7 @@ static int intel_overlay_do_put_image(struct intel_overlay *overlay, if (ret != 0) return ret; - ret = i915_gem_object_pin(new_bo, PAGE_SIZE); + ret = i915_gem_object_pin(new_bo, PAGE_SIZE, true); if (ret != 0) return ret; @@ -1423,7 +1423,7 @@ void intel_setup_overlay(struct drm_device *dev) } overlay->flip_addr = overlay->reg_bo->phys_obj->handle->busaddr; } else { - ret = i915_gem_object_pin(reg_bo, PAGE_SIZE); + ret = i915_gem_object_pin(reg_bo, PAGE_SIZE, true); if (ret) { DRM_ERROR("failed to pin overlay register bo\n"); goto out_free_bo; diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 4803b32f308f..8eaa60cc5d25 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -546,7 +546,7 @@ static int init_status_page(struct intel_ring_buffer *ring) obj_priv = to_intel_bo(obj); obj_priv->agp_type = AGP_USER_CACHED_MEMORY; - ret = i915_gem_object_pin(obj, 4096); + ret = i915_gem_object_pin(obj, 4096, true); if (ret != 0) { goto err_unref; } @@ -602,7 +602,7 @@ int intel_init_ring_buffer(struct drm_device *dev, ring->gem_object = obj; - ret = i915_gem_object_pin(obj, PAGE_SIZE); + ret = i915_gem_object_pin(obj, PAGE_SIZE, true); if (ret) goto err_unref; -- cgit v1.2.3 From 16e809acc167c3ede231cafcdab1be93bab3e429 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Thu, 16 Sep 2010 19:37:04 +0200 Subject: drm/i915: unbind unmappable objects on fault/pin In i915_gem_object_pin obviously unbind only if mappable is true. This is the last part to enable gtt_mappable_end != gtt_size, which the next patch will do. v2: Fences on g33/pineview only work in the mappable part of the gtt. Signed-off-by: Daniel Vetter Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_gem.c | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index ef14546fc08d..7b0680714101 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -260,6 +260,16 @@ i915_gem_create_ioctl(struct drm_device *dev, void *data, return 0; } +static bool +i915_gem_object_cpu_accessible(struct drm_i915_gem_object *obj) +{ + struct drm_device *dev = obj->base.dev; + drm_i915_private_t *dev_priv = dev->dev_private; + + return obj->gtt_space == NULL || + obj->gtt_offset + obj->base.size <= dev_priv->mm.gtt_mappable_end; +} + static inline int fast_shmem_read(struct page **pages, loff_t page_base, int page_offset, @@ -1255,6 +1265,9 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) /* Now bind it into the GTT if needed */ mutex_lock(&dev->struct_mutex); + if (!i915_gem_object_cpu_accessible(obj_priv)) + i915_gem_object_unbind(obj); + if (!obj_priv->gtt_space) { ret = i915_gem_object_bind_to_gtt(obj, 0, true); if (ret) @@ -3465,11 +3478,15 @@ i915_gem_execbuffer_pin(struct drm_device *dev, ret = 0; for (i = 0; i < count; i++) { struct drm_i915_gem_exec_object2 *entry = &exec_list[i]; - struct drm_i915_gem_object *obj= to_intel_bo(object_list[i]); + struct drm_i915_gem_object *obj = to_intel_bo(object_list[i]); bool need_fence = entry->flags & EXEC_OBJECT_NEEDS_FENCE && obj->tiling_mode != I915_TILING_NONE; + /* g33/pnv can't fence buffers in the unmappable part */ + bool need_mappable = + entry->relocation_count ? true : need_fence; + /* Check fence reg constraints and rebind if necessary */ if (need_fence && !i915_gem_object_fence_offset_ok(&obj->base, @@ -3480,7 +3497,8 @@ i915_gem_execbuffer_pin(struct drm_device *dev, } ret = i915_gem_object_pin(&obj->base, - entry->alignment, true); + entry->alignment, + need_mappable); if (ret) break; @@ -4064,7 +4082,8 @@ i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment, if (obj_priv->gtt_space != NULL) { if (alignment == 0) alignment = i915_gem_get_gtt_alignment(obj); - if (obj_priv->gtt_offset & (alignment - 1)) { + if (obj_priv->gtt_offset & (alignment - 1) || + (mappable && !i915_gem_object_cpu_accessible(obj_priv))) { WARN(obj_priv->pin_count, "bo is already pinned with incorrect alignment:" " offset=%x, req.alignment=%x\n", -- cgit v1.2.3 From 53984635a659e360f206a81ada4ae813152d72f1 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Wed, 22 Sep 2010 23:44:24 +0200 Subject: drm/i915: use the complete gtt At least the part that's currently enabled by the BIOS. Signed-off-by: Daniel Vetter Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_dma.c | 14 +++++++++----- drivers/gpu/drm/i915/i915_drv.h | 2 +- drivers/gpu/drm/i915/i915_gem.c | 5 +++-- 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 02daf4e5c8e6..1bd37e34c77e 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -1195,13 +1195,17 @@ static bool i915_switcheroo_can_switch(struct pci_dev *pdev) return can_switch; } -static int i915_load_modeset_init(struct drm_device *dev, - unsigned long prealloc_size, - unsigned long agp_size) +static int i915_load_modeset_init(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; + unsigned long prealloc_size, gtt_size, mappable_size; int ret = 0; + prealloc_size = dev_priv->mm.gtt->gtt_stolen_entries << PAGE_SHIFT; + gtt_size = dev_priv->mm.gtt->gtt_total_entries << PAGE_SHIFT; + mappable_size = dev_priv->mm.gtt->gtt_mappable_entries << PAGE_SHIFT; + gtt_size -= PAGE_SIZE; + /* Basic memrange allocator for stolen space (aka mm.vram) */ drm_mm_init(&dev_priv->mm.vram, 0, prealloc_size); @@ -1214,7 +1218,7 @@ static int i915_load_modeset_init(struct drm_device *dev, * at the last page of the aperture. One page should be enough to * keep any prefetching inside of the aperture. */ - i915_gem_do_init(dev, prealloc_size, agp_size - 4096); + i915_gem_do_init(dev, prealloc_size, mappable_size, gtt_size); mutex_lock(&dev->struct_mutex); ret = i915_gem_init_ringbuffer(dev); @@ -2056,7 +2060,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) intel_detect_pch(dev); if (drm_core_check_feature(dev, DRIVER_MODESET)) { - ret = i915_load_modeset_init(dev, prealloc_size, agp_size); + ret = i915_load_modeset_init(dev); if (ret < 0) { DRM_ERROR("failed to init modeset\n"); goto out_workqueue_free; diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 263bb0506247..296ed38b292f 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1041,7 +1041,7 @@ int i915_gem_object_set_domain(struct drm_gem_object *obj, int i915_gem_init_ringbuffer(struct drm_device *dev); void i915_gem_cleanup_ringbuffer(struct drm_device *dev); int i915_gem_do_init(struct drm_device *dev, unsigned long start, - unsigned long end); + unsigned long mappable_end, unsigned long end); int i915_gpu_idle(struct drm_device *dev); int i915_gem_idle(struct drm_device *dev); int i915_add_request(struct drm_device *dev, diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 7b0680714101..6d9971f0ed92 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -173,6 +173,7 @@ i915_gem_object_is_inactive(struct drm_i915_gem_object *obj_priv) int i915_gem_do_init(struct drm_device *dev, unsigned long start, + unsigned long mappable_end, unsigned long end) { drm_i915_private_t *dev_priv = dev->dev_private; @@ -187,7 +188,7 @@ int i915_gem_do_init(struct drm_device *dev, end - start); dev_priv->mm.gtt_total = end - start; - dev_priv->mm.gtt_mappable_end = end; + dev_priv->mm.gtt_mappable_end = mappable_end; return 0; } @@ -200,7 +201,7 @@ i915_gem_init_ioctl(struct drm_device *dev, void *data, int ret; mutex_lock(&dev->struct_mutex); - ret = i915_gem_do_init(dev, args->gtt_start, args->gtt_end); + ret = i915_gem_do_init(dev, args->gtt_start, args->gtt_end, args->gtt_end); mutex_unlock(&dev->struct_mutex); return ret; -- cgit v1.2.3 From b3eafc5af02a799650757f2c5b2b0d4835dd0a5f Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Thu, 23 Sep 2010 20:04:17 +0200 Subject: intel-gtt: save PGETBL_CTL later in the setup process ... and switch to a more classical store-reg-on-suspend, restore-on-resume way of doing things. Obviously this is just preparation for the future, the code is not there at all, yet. This is needed because the next patch adjusts this register and everything in it (not just the pagetable address) needs to be restored on resume. Signed-off-by: Daniel Vetter Signed-off-by: Chris Wilson --- drivers/char/agp/intel-gtt.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/char/agp/intel-gtt.c b/drivers/char/agp/intel-gtt.c index 6b6760ea2435..fd3e94f8ab51 100644 --- a/drivers/char/agp/intel-gtt.c +++ b/drivers/char/agp/intel-gtt.c @@ -95,7 +95,7 @@ static struct _intel_private { u8 __iomem *registers; phys_addr_t gtt_bus_addr; phys_addr_t gma_bus_addr; - phys_addr_t pte_bus_addr; + u32 PGETBL_save; u32 __iomem *gtt; /* I915G */ int num_dcache_entries; union { @@ -755,6 +755,11 @@ static int intel_gtt_init(void) intel_private.base.gtt_mappable_entries = intel_gtt_mappable_entries(); intel_private.base.gtt_total_entries = intel_gtt_total_entries(); + /* save the PGETBL reg for resume */ + intel_private.PGETBL_save = + readl(intel_private.registers+I810_PGETBL_CTL) + & ~I810_PGETBL_ENABLED; + dev_info(&intel_private.bridge_dev->dev, "detected gtt size: %dK total, %dK mappable\n", intel_private.base.gtt_total_entries * 4, @@ -891,7 +896,7 @@ static void intel_enable_gtt(void) gmch_ctrl |= I830_GMCH_ENABLED; pci_write_config_word(intel_private.bridge_dev, I830_GMCH_CTRL, gmch_ctrl); - writel(intel_private.pte_bus_addr|I810_PGETBL_ENABLED, + writel(intel_private.PGETBL_save|I810_PGETBL_ENABLED, intel_private.registers+I810_PGETBL_CTL); readl(intel_private.registers+I810_PGETBL_CTL); /* PCI Posting. */ } @@ -908,8 +913,6 @@ static int i830_setup(void) return -ENOMEM; intel_private.gtt_bus_addr = reg_addr + I810_PTE_BASE; - intel_private.pte_bus_addr = - readl(intel_private.registers+I810_PGETBL_CTL) & 0xfffff000; intel_i830_setup_flush(); @@ -1265,9 +1268,6 @@ static int i9xx_setup(void) intel_private.gtt_bus_addr = reg_addr + gtt_offset; } - intel_private.pte_bus_addr = - readl(intel_private.registers+I810_PGETBL_CTL) & 0xfffff000; - intel_i9xx_setup_flush(); return 0; -- cgit v1.2.3 From 201728429d6cf336cfd7483fcd1bce47291b2901 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Fri, 24 Sep 2010 18:25:59 +0200 Subject: intel-gtt: maximize ggtt size on platforms that support this On VT-d supporting platforms the GGTT is allocated in a stolen mem section separate from graphcis stolen mem. The GMCH register contains a bitfield specifying the size of that region. Docs suggest that this region can only be used for GGTT and PPGTT. Hence ensure that the PPGTT is disabled and use the complete area for the GGTT. Unfortunately the graphics core on G33/Pineview can't cope with really large GTTs and the BIOS usually enables the maximum of 512MB. So don't bother with maximizing the GTT on these platforms. Signed-off-by: Daniel Vetter Signed-off-by: Chris Wilson --- drivers/char/agp/intel-agp.h | 14 +++++-- drivers/char/agp/intel-gtt.c | 96 ++++++++++++++++++++++++++++++++------------ 2 files changed, 81 insertions(+), 29 deletions(-) diff --git a/drivers/char/agp/intel-agp.h b/drivers/char/agp/intel-agp.h index 90539df02504..010e3defd6c3 100644 --- a/drivers/char/agp/intel-agp.h +++ b/drivers/char/agp/intel-agp.h @@ -75,6 +75,8 @@ #define I810_GMS_DISABLE 0x00000000 #define I810_PGETBL_CTL 0x2020 #define I810_PGETBL_ENABLED 0x00000001 +/* Note: PGETBL_CTL2 has a different offset on G33. */ +#define I965_PGETBL_CTL2 0x20c4 #define I965_PGETBL_SIZE_MASK 0x0000000e #define I965_PGETBL_SIZE_512KB (0 << 1) #define I965_PGETBL_SIZE_256KB (1 << 1) @@ -82,9 +84,15 @@ #define I965_PGETBL_SIZE_1MB (3 << 1) #define I965_PGETBL_SIZE_2MB (4 << 1) #define I965_PGETBL_SIZE_1_5MB (5 << 1) -#define G33_PGETBL_SIZE_MASK (3 << 8) -#define G33_PGETBL_SIZE_1M (1 << 8) -#define G33_PGETBL_SIZE_2M (2 << 8) +#define G33_GMCH_SIZE_MASK (3 << 8) +#define G33_GMCH_SIZE_1M (1 << 8) +#define G33_GMCH_SIZE_2M (2 << 8) +#define G4x_GMCH_SIZE_MASK (0xf << 8) +#define G4x_GMCH_SIZE_1M (0x1 << 8) +#define G4x_GMCH_SIZE_2M (0x3 << 8) +#define G4x_GMCH_SIZE_VT_1M (0x9 << 8) +#define G4x_GMCH_SIZE_VT_1_5M (0xa << 8) +#define G4x_GMCH_SIZE_VT_2M (0xc << 8) #define I810_DRAM_CTL 0x3000 #define I810_DRAM_ROW_0 0x00000001 diff --git a/drivers/char/agp/intel-gtt.c b/drivers/char/agp/intel-gtt.c index fd3e94f8ab51..5dc1f5db55a7 100644 --- a/drivers/char/agp/intel-gtt.c +++ b/drivers/char/agp/intel-gtt.c @@ -642,41 +642,85 @@ static unsigned int intel_gtt_stolen_entries(void) return stolen_entries; } -static unsigned int intel_gtt_total_entries(void) +static void i965_adjust_pgetbl_size(unsigned int size_flag) +{ + u32 pgetbl_ctl, pgetbl_ctl2; + + /* ensure that ppgtt is disabled */ + pgetbl_ctl2 = readl(intel_private.registers+I965_PGETBL_CTL2); + pgetbl_ctl2 &= ~I810_PGETBL_ENABLED; + writel(pgetbl_ctl2, intel_private.registers+I965_PGETBL_CTL2); + + /* write the new ggtt size */ + pgetbl_ctl = readl(intel_private.registers+I810_PGETBL_CTL); + pgetbl_ctl &= ~I965_PGETBL_SIZE_MASK; + pgetbl_ctl |= size_flag; + writel(pgetbl_ctl, intel_private.registers+I810_PGETBL_CTL); +} + +static unsigned int i965_gtt_total_entries(void) { int size; + u32 pgetbl_ctl; + u16 gmch_ctl; - if (IS_G33 || INTEL_GTT_GEN == 4 || INTEL_GTT_GEN == 5) { - u32 pgetbl_ctl; - pgetbl_ctl = readl(intel_private.registers+I810_PGETBL_CTL); + pci_read_config_word(intel_private.bridge_dev, + I830_GMCH_CTRL, &gmch_ctl); - switch (pgetbl_ctl & I965_PGETBL_SIZE_MASK) { - case I965_PGETBL_SIZE_128KB: - size = KB(128); - break; - case I965_PGETBL_SIZE_256KB: - size = KB(256); - break; - case I965_PGETBL_SIZE_512KB: - size = KB(512); - break; - case I965_PGETBL_SIZE_1MB: - size = KB(1024); + if (INTEL_GTT_GEN == 5) { + switch (gmch_ctl & G4x_GMCH_SIZE_MASK) { + case G4x_GMCH_SIZE_1M: + case G4x_GMCH_SIZE_VT_1M: + i965_adjust_pgetbl_size(I965_PGETBL_SIZE_1MB); break; - case I965_PGETBL_SIZE_2MB: - size = KB(2048); + case G4x_GMCH_SIZE_VT_1_5M: + i965_adjust_pgetbl_size(I965_PGETBL_SIZE_1_5MB); break; - case I965_PGETBL_SIZE_1_5MB: - size = KB(1024 + 512); + case G4x_GMCH_SIZE_2M: + case G4x_GMCH_SIZE_VT_2M: + i965_adjust_pgetbl_size(I965_PGETBL_SIZE_2MB); break; - default: - dev_info(&intel_private.pcidev->dev, - "unknown page table size, assuming 512KB\n"); - size = KB(512); } + } - return size/4; - } else if (INTEL_GTT_GEN == 6) { + pgetbl_ctl = readl(intel_private.registers+I810_PGETBL_CTL); + + switch (pgetbl_ctl & I965_PGETBL_SIZE_MASK) { + case I965_PGETBL_SIZE_128KB: + size = KB(128); + break; + case I965_PGETBL_SIZE_256KB: + size = KB(256); + break; + case I965_PGETBL_SIZE_512KB: + size = KB(512); + break; + /* GTT pagetable sizes bigger than 512KB are not possible on G33! */ + case I965_PGETBL_SIZE_1MB: + size = KB(1024); + break; + case I965_PGETBL_SIZE_2MB: + size = KB(2048); + break; + case I965_PGETBL_SIZE_1_5MB: + size = KB(1024 + 512); + break; + default: + dev_info(&intel_private.pcidev->dev, + "unknown page table size, assuming 512KB\n"); + size = KB(512); + } + + return size/4; +} + +static unsigned int intel_gtt_total_entries(void) +{ + int size; + + if (IS_G33 || INTEL_GTT_GEN == 4 || INTEL_GTT_GEN == 5) + return i965_gtt_total_entries(); + else if (INTEL_GTT_GEN == 6) { u16 snb_gmch_ctl; pci_read_config_word(intel_private.pcidev, SNB_GMCH_CTRL, &snb_gmch_ctl); -- cgit v1.2.3 From ec57d2602a985b54b53e53098f74fdefc24723af Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Thu, 30 Sep 2010 23:42:15 +0200 Subject: drm/i915: add mappable to gem_object_bind tracepoint This way we can make some more educated guesses as to why exactly we can't use 2G apertures to their full potential ;) Signed-off-by: Daniel Vetter Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_gem.c | 2 +- drivers/gpu/drm/i915/i915_trace.h | 11 +++++++---- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 6d9971f0ed92..bb5435ba01aa 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -2775,7 +2775,7 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, BUG_ON(obj->write_domain & I915_GEM_GPU_DOMAINS); obj_priv->gtt_offset = obj_priv->gtt_space->start; - trace_i915_gem_object_bind(obj, obj_priv->gtt_offset); + trace_i915_gem_object_bind(obj, obj_priv->gtt_offset, mappable); return 0; } diff --git a/drivers/gpu/drm/i915/i915_trace.h b/drivers/gpu/drm/i915/i915_trace.h index fea97a21cc14..0b1049ff72a3 100644 --- a/drivers/gpu/drm/i915/i915_trace.h +++ b/drivers/gpu/drm/i915/i915_trace.h @@ -35,22 +35,25 @@ TRACE_EVENT(i915_gem_object_create, TRACE_EVENT(i915_gem_object_bind, - TP_PROTO(struct drm_gem_object *obj, u32 gtt_offset), + TP_PROTO(struct drm_gem_object *obj, u32 gtt_offset, bool mappable), - TP_ARGS(obj, gtt_offset), + TP_ARGS(obj, gtt_offset, mappable), TP_STRUCT__entry( __field(struct drm_gem_object *, obj) __field(u32, gtt_offset) + __field(bool, mappable) ), TP_fast_assign( __entry->obj = obj; __entry->gtt_offset = gtt_offset; + __entry->mappable = mappable; ), - TP_printk("obj=%p, gtt_offset=%08x", - __entry->obj, __entry->gtt_offset) + TP_printk("obj=%p, gtt_offset=%08x%s", + __entry->obj, __entry->gtt_offset, + __entry->mappable ? ", mappable" : "") ); TRACE_EVENT(i915_gem_object_change_domain, -- cgit v1.2.3 From fb7d516af11837126eb1e4a44ab0653bf9b57702 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Fri, 1 Oct 2010 22:05:20 +0200 Subject: drm/i915: add accounting for mappable objects in gtt v2 More precisely: For those that _need_ to be mappable. Also add two BUG_ONs in fault and pin to check the consistency of the mappable flag. Changes in v2: - Add tracking of gtt mappable space (to notice mappable/unmappable balancing issues). - Improve the mappable working set tracking by tracking fault and pin separately. Signed-off-by: Daniel Vetter Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_debugfs.c | 6 +++ drivers/gpu/drm/i915/i915_drv.h | 12 +++++ drivers/gpu/drm/i915/i915_gem.c | 93 +++++++++++++++++++++++++++++++------ 3 files changed, 98 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index beb3de7921b5..2e5961139326 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -131,6 +131,8 @@ describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj) seq_printf(m, " (fence: %d)", obj->fence_reg); if (obj->gtt_space != NULL) seq_printf(m, " (gtt_offset: %08x)", obj->gtt_offset); + if (obj->pin_mappable || obj->fault_mappable) + seq_printf(m, " (mappable)"); if (obj->ring != NULL) seq_printf(m, " (%s)", obj->ring->name); } @@ -207,6 +209,10 @@ static int i915_gem_object_info(struct seq_file *m, void* data) seq_printf(m, "%zu object bytes\n", dev_priv->mm.object_memory); seq_printf(m, "%u pinned\n", dev_priv->mm.pin_count); seq_printf(m, "%zu pin bytes\n", dev_priv->mm.pin_memory); + seq_printf(m, "%u mappable objects in gtt\n", dev_priv->mm.gtt_mappable_count); + seq_printf(m, "%zu mappable gtt bytes\n", dev_priv->mm.gtt_mappable_memory); + seq_printf(m, "%zu mappable gtt used bytes\n", dev_priv->mm.mappable_gtt_used); + seq_printf(m, "%zu mappable gtt total\n", dev_priv->mm.mappable_gtt_total); seq_printf(m, "%u objects in gtt\n", dev_priv->mm.gtt_count); seq_printf(m, "%zu gtt bytes\n", dev_priv->mm.gtt_memory); seq_printf(m, "%zu gtt total\n", dev_priv->mm.gtt_total); diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 296ed38b292f..cdae5d189165 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -643,9 +643,13 @@ typedef struct drm_i915_private { size_t object_memory; size_t pin_memory; size_t gtt_memory; + size_t gtt_mappable_memory; + size_t mappable_gtt_used; + size_t mappable_gtt_total; size_t gtt_total; u32 object_count; u32 pin_count; + u32 gtt_mappable_count; u32 gtt_count; } mm; struct sdvo_device_mapping sdvo_mappings[2]; @@ -775,6 +779,14 @@ struct drm_i915_gem_object { unsigned int pin_count : 4; #define DRM_I915_GEM_OBJECT_MAX_PIN_COUNT 0xf + /** + * Whether the current gtt mapping needs to be mappable (and isn't just + * mappable by accident). Track pin and fault separate for a more + * accurate mappable working set. + */ + unsigned int fault_mappable : 1; + unsigned int pin_mappable : 1; + /** AGP memory structure for our GTT binding. */ DRM_AGP_MEM *agp_mem; diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index bb5435ba01aa..2eceb24bf54b 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -84,31 +84,83 @@ static void i915_gem_info_remove_obj(struct drm_i915_private *dev_priv, } static void i915_gem_info_add_gtt(struct drm_i915_private *dev_priv, - size_t size) + struct drm_gem_object *obj) { + struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); dev_priv->mm.gtt_count++; - dev_priv->mm.gtt_memory += size; + dev_priv->mm.gtt_memory += obj->size; + if (obj_priv->gtt_offset < dev_priv->mm.gtt_mappable_end) { + dev_priv->mm.mappable_gtt_used += + min_t(size_t, obj->size, + dev_priv->mm.gtt_mappable_end + - obj_priv->gtt_offset); + } } static void i915_gem_info_remove_gtt(struct drm_i915_private *dev_priv, - size_t size) + struct drm_gem_object *obj) { + struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); dev_priv->mm.gtt_count--; - dev_priv->mm.gtt_memory -= size; + dev_priv->mm.gtt_memory -= obj->size; + if (obj_priv->gtt_offset < dev_priv->mm.gtt_mappable_end) { + dev_priv->mm.mappable_gtt_used -= + min_t(size_t, obj->size, + dev_priv->mm.gtt_mappable_end + - obj_priv->gtt_offset); + } +} + +/** + * Update the mappable working set counters. Call _only_ when there is a change + * in one of (pin|fault)_mappable and update *_mappable _before_ calling. + * @mappable: new state the changed mappable flag (either pin_ or fault_). + */ +static void +i915_gem_info_update_mappable(struct drm_i915_private *dev_priv, + struct drm_gem_object *obj, + bool mappable) +{ + struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); + + if (mappable) { + if (obj_priv->pin_mappable && obj_priv->fault_mappable) + /* Combined state was already mappable. */ + return; + dev_priv->mm.gtt_mappable_count++; + dev_priv->mm.gtt_mappable_memory += obj->size; + } else { + if (obj_priv->pin_mappable || obj_priv->fault_mappable) + /* Combined state still mappable. */ + return; + dev_priv->mm.gtt_mappable_count--; + dev_priv->mm.gtt_mappable_memory -= obj->size; + } } static void i915_gem_info_add_pin(struct drm_i915_private *dev_priv, - size_t size) + struct drm_gem_object *obj, + bool mappable) { + struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); dev_priv->mm.pin_count++; - dev_priv->mm.pin_memory += size; + dev_priv->mm.pin_memory += obj->size; + if (mappable) { + obj_priv->pin_mappable = true; + i915_gem_info_update_mappable(dev_priv, obj, true); + } } static void i915_gem_info_remove_pin(struct drm_i915_private *dev_priv, - size_t size) + struct drm_gem_object *obj) { + struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); dev_priv->mm.pin_count--; - dev_priv->mm.pin_memory -= size; + dev_priv->mm.pin_memory -= obj->size; + if (obj_priv->pin_mappable) { + obj_priv->pin_mappable = false; + i915_gem_info_update_mappable(dev_priv, obj, false); + } } int @@ -188,6 +240,7 @@ int i915_gem_do_init(struct drm_device *dev, end - start); dev_priv->mm.gtt_total = end - start; + dev_priv->mm.mappable_gtt_total = min(end, mappable_end) - start; dev_priv->mm.gtt_mappable_end = mappable_end; return 0; @@ -1266,6 +1319,7 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) /* Now bind it into the GTT if needed */ mutex_lock(&dev->struct_mutex); + BUG_ON(obj_priv->pin_count && !obj_priv->pin_mappable); if (!i915_gem_object_cpu_accessible(obj_priv)) i915_gem_object_unbind(obj); @@ -1279,6 +1333,11 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) goto unlock; } + if (!obj_priv->fault_mappable) { + obj_priv->fault_mappable = true; + i915_gem_info_update_mappable(dev_priv, obj, true); + } + /* Need a new fence register? */ if (obj_priv->tiling_mode != I915_TILING_NONE) { ret = i915_gem_object_get_fence_reg(obj, true); @@ -1396,11 +1455,17 @@ void i915_gem_release_mmap(struct drm_gem_object *obj) { struct drm_device *dev = obj->dev; + struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); if (dev->dev_mapping) unmap_mapping_range(dev->dev_mapping, obj_priv->mmap_offset, obj->size, 1); + + if (obj_priv->fault_mappable) { + obj_priv->fault_mappable = false; + i915_gem_info_update_mappable(dev_priv, obj, false); + } } static void @@ -2177,7 +2242,7 @@ i915_gem_object_unbind(struct drm_gem_object *obj) i915_gem_object_put_pages(obj); BUG_ON(obj_priv->pages_refcount); - i915_gem_info_remove_gtt(dev_priv, obj->size); + i915_gem_info_remove_gtt(dev_priv, obj); list_del_init(&obj_priv->mm_list); drm_mm_put_block(obj_priv->gtt_space); @@ -2763,9 +2828,11 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, goto search_free; } + obj_priv->gtt_offset = obj_priv->gtt_space->start; + /* keep track of bounds object by adding it to the inactive list */ list_add_tail(&obj_priv->mm_list, &dev_priv->mm.inactive_list); - i915_gem_info_add_gtt(dev_priv, obj->size); + i915_gem_info_add_gtt(dev_priv, obj); /* Assert that the object is not currently in any GPU domain. As it * wasn't in the GTT, there shouldn't be any way it could have been in @@ -2774,7 +2841,6 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, BUG_ON(obj->read_domains & I915_GEM_GPU_DOMAINS); BUG_ON(obj->write_domain & I915_GEM_GPU_DOMAINS); - obj_priv->gtt_offset = obj_priv->gtt_space->start; trace_i915_gem_object_bind(obj, obj_priv->gtt_offset, mappable); return 0; @@ -4107,11 +4173,12 @@ i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment, * remove it from the inactive list */ if (obj_priv->pin_count == 1) { - i915_gem_info_add_pin(dev_priv, obj->size); + i915_gem_info_add_pin(dev_priv, obj, mappable); if (!obj_priv->active) list_move_tail(&obj_priv->mm_list, &dev_priv->mm.pinned_list); } + BUG_ON(!obj_priv->pin_mappable && mappable); WARN_ON(i915_verify_lists(dev)); return 0; @@ -4137,7 +4204,7 @@ i915_gem_object_unpin(struct drm_gem_object *obj) if (!obj_priv->active) list_move_tail(&obj_priv->mm_list, &dev_priv->mm.inactive_list); - i915_gem_info_remove_pin(dev_priv, obj->size); + i915_gem_info_remove_pin(dev_priv, obj); } WARN_ON(i915_verify_lists(dev)); } -- cgit v1.2.3 From da761a6edf5c12ba2e7566c5e6bc98899d46ff12 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 27 Oct 2010 17:37:08 +0100 Subject: drm/i915: Bail early if we try to mmap an object too large to be mapped. Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_gem.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 2eceb24bf54b..19ceb8cd0922 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1258,6 +1258,7 @@ int i915_gem_mmap_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv) { + struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_gem_mmap *args = data; struct drm_gem_object *obj; loff_t offset; @@ -1270,6 +1271,11 @@ i915_gem_mmap_ioctl(struct drm_device *dev, void *data, if (obj == NULL) return -ENOENT; + if (obj->size > dev_priv->mm.gtt_mappable_end) { + drm_gem_object_unreference_unlocked(obj); + return -E2BIG; + } + offset = args->offset; down_write(¤t->mm->mmap_sem); @@ -1547,6 +1553,7 @@ int i915_gem_mmap_gtt_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv) { + struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_gem_mmap_gtt *args = data; struct drm_gem_object *obj; struct drm_i915_gem_object *obj_priv; @@ -1566,6 +1573,11 @@ i915_gem_mmap_gtt_ioctl(struct drm_device *dev, void *data, } obj_priv = to_intel_bo(obj); + if (obj->size > dev_priv->mm.gtt_mappable_end) { + ret = -E2BIG; + goto unlock; + } + if (obj_priv->madv != I915_MADV_WILLNEED) { DRM_ERROR("Attempting to mmap a purgeable buffer\n"); ret = -EINVAL; -- cgit v1.2.3 From 71e9339c3389de6a685ecb26261a81b8a583aa1c Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 27 Oct 2010 18:46:52 +0100 Subject: drm/i915: Use the agp_size determined from the GTT This is the same value as before, but it just makes the code slightly more readable to use the local variable than converting the aperture size into bytes every time. Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_dma.c | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 1bd37e34c77e..d8def48242c8 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -1920,6 +1920,16 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) if (IS_GEN2(dev)) dma_set_coherent_mask(&dev->pdev->dev, DMA_BIT_MASK(30)); + dev_priv->mm.gtt = intel_gtt_get(); + if (!dev_priv->mm.gtt) { + DRM_ERROR("Failed to initialize GTT\n"); + ret = -ENODEV; + goto out_iomapfree; + } + + prealloc_size = dev_priv->mm.gtt->gtt_stolen_entries << PAGE_SHIFT; + agp_size = dev_priv->mm.gtt->gtt_mappable_entries << PAGE_SHIFT; + dev_priv->regs = ioremap(base, size); if (!dev_priv->regs) { DRM_ERROR("failed to map registers\n"); @@ -1928,8 +1938,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) } dev_priv->mm.gtt_mapping = - io_mapping_create_wc(dev->agp->base, - dev->agp->agp_info.aper_size * 1024*1024); + io_mapping_create_wc(dev->agp->base, agp_size); if (dev_priv->mm.gtt_mapping == NULL) { ret = -EIO; goto out_rmmap; @@ -1941,24 +1950,13 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) * MTRR if present. Even if a UC MTRR isn't present. */ dev_priv->mm.gtt_mtrr = mtrr_add(dev->agp->base, - dev->agp->agp_info.aper_size * - 1024 * 1024, + agp_size, MTRR_TYPE_WRCOMB, 1); if (dev_priv->mm.gtt_mtrr < 0) { DRM_INFO("MTRR allocation failed. Graphics " "performance may suffer.\n"); } - dev_priv->mm.gtt = intel_gtt_get(); - if (!dev_priv->mm.gtt) { - DRM_ERROR("Failed to initialize GTT\n"); - ret = -ENODEV; - goto out_iomapfree; - } - - prealloc_size = dev_priv->mm.gtt->gtt_stolen_entries << PAGE_SHIFT; - agp_size = dev_priv->mm.gtt->gtt_mappable_entries << PAGE_SHIFT; - /* The i915 workqueue is primarily used for batched retirement of * requests (and thus managing bo) once the task has been completed * by the GPU. i915_gem_retire_requests() is called directly when we -- cgit v1.2.3 From f406839f094ef24bb201c9574fdb9ce8e799a975 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 27 Oct 2010 20:36:41 +0100 Subject: drm/i915: Capture ERROR register on Sandybridge hangs This holds error state from the main graphics arbiter mainly involving the DMA engine and address translation. Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_debugfs.c | 3 +++ drivers/gpu/drm/i915/i915_drv.h | 1 + drivers/gpu/drm/i915/i915_irq.c | 18 +++++++++++------- drivers/gpu/drm/i915/i915_reg.h | 2 ++ 4 files changed, 17 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 2e5961139326..4fc1e05b769f 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -615,6 +615,9 @@ static int i915_error_state(struct seq_file *m, void *unused) seq_printf(m, "Time: %ld s %ld us\n", error->time.tv_sec, error->time.tv_usec); seq_printf(m, "PCI ID: 0x%04x\n", dev->pci_device); + if (INTEL_INFO(dev)->gen >= 6) { + seq_printf(m, "ERROR: 0x%08x\n", error->error); + } seq_printf(m, "EIR: 0x%08x\n", error->eir); seq_printf(m, " PGTBL_ER: 0x%08x\n", error->pgtbl_er); seq_printf(m, " INSTPM: 0x%08x\n", error->instpm); diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index cdae5d189165..895f9173de58 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -142,6 +142,7 @@ struct sdvo_device_mapping { struct drm_i915_error_state { u32 eir; u32 pgtbl_er; + u32 error; /* gen6+ */ u32 pipeastat; u32 pipebstat; u32 ipeir; diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 29cbcb33b92c..2a29497a4694 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -592,13 +592,11 @@ static void i915_capture_error_state(struct drm_device *dev) error->pipeastat = I915_READ(PIPEASTAT); error->pipebstat = I915_READ(PIPEBSTAT); error->instpm = I915_READ(INSTPM); - if (INTEL_INFO(dev)->gen < 4) { - error->ipeir = I915_READ(IPEIR); - error->ipehr = I915_READ(IPEHR); - error->instdone = I915_READ(INSTDONE); - error->acthd = I915_READ(ACTHD); - error->bbaddr = 0; - } else { + error->error = 0; + if (INTEL_INFO(dev)->gen >= 6) { + error->error = I915_READ(ERROR_GEN6); + } + if (INTEL_INFO(dev)->gen >= 4) { error->ipeir = I915_READ(IPEIR_I965); error->ipehr = I915_READ(IPEHR_I965); error->instdone = I915_READ(INSTDONE_I965); @@ -606,6 +604,12 @@ static void i915_capture_error_state(struct drm_device *dev) error->instdone1 = I915_READ(INSTDONE1); error->acthd = I915_READ(ACTHD_I965); error->bbaddr = I915_READ64(BB_ADDR); + } else { + error->ipeir = I915_READ(IPEIR); + error->ipehr = I915_READ(IPEHR); + error->instdone = I915_READ(INSTDONE); + error->acthd = I915_READ(ACTHD); + error->bbaddr = 0; } bbaddr = i915_ringbuffer_last_batch(dev); diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 25ed911a3112..fc161196da21 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -306,6 +306,8 @@ #define NOPID 0x02094 #define HWSTAM 0x02098 +#define ERROR_GEN6 0x040a0 + #define MI_MODE 0x0209c # define VS_TIMER_DISPATCH (1 << 6) # define MI_FLUSH_ENABLE (1 << 11) -- cgit v1.2.3 From b4ce0f85159f77f208a62930f67b4e548576a5a3 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 28 Oct 2010 11:26:06 +0100 Subject: drm/i915: Use pci_iomap for remapping the MMIO registers. Play safe and use the common routines which take care of the cachability of the memory when setting up the iomapping for the PCI registers. Whilst they should be cacheable for the current generations, actually honouring what the device requires is a better long term strategy. Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_dma.c | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index d8def48242c8..f8827c23a668 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -1888,7 +1888,6 @@ EXPORT_SYMBOL_GPL(i915_gpu_turbo_disable); int i915_driver_load(struct drm_device *dev, unsigned long flags) { struct drm_i915_private *dev_priv; - resource_size_t base, size; int ret = 0, mmio_bar; uint32_t agp_size, prealloc_size; /* i915 has 4 more counters */ @@ -1906,11 +1905,6 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) dev_priv->dev = dev; dev_priv->info = (struct intel_device_info *) flags; - /* Add register map (needed for suspend/resume) */ - mmio_bar = IS_GEN2(dev) ? 1 : 0; - base = pci_resource_start(dev->pdev, mmio_bar); - size = pci_resource_len(dev->pdev, mmio_bar); - if (i915_get_bridge_dev(dev)) { ret = -EIO; goto free_priv; @@ -1920,6 +1914,14 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) if (IS_GEN2(dev)) dma_set_coherent_mask(&dev->pdev->dev, DMA_BIT_MASK(30)); + mmio_bar = IS_GEN2(dev) ? 1 : 0; + dev_priv->regs = pci_iomap(dev->pdev, mmio_bar, 0); + if (!dev_priv->regs) { + DRM_ERROR("failed to map registers\n"); + ret = -EIO; + goto put_bridge; + } + dev_priv->mm.gtt = intel_gtt_get(); if (!dev_priv->mm.gtt) { DRM_ERROR("Failed to initialize GTT\n"); @@ -1930,13 +1932,6 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) prealloc_size = dev_priv->mm.gtt->gtt_stolen_entries << PAGE_SHIFT; agp_size = dev_priv->mm.gtt->gtt_mappable_entries << PAGE_SHIFT; - dev_priv->regs = ioremap(base, size); - if (!dev_priv->regs) { - DRM_ERROR("failed to map registers\n"); - ret = -EIO; - goto put_bridge; - } - dev_priv->mm.gtt_mapping = io_mapping_create_wc(dev->agp->base, agp_size); if (dev_priv->mm.gtt_mapping == NULL) { -- cgit v1.2.3 From 176f28ebf4303b4f7e3a5bd8be7842a8bbecd9c3 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 28 Oct 2010 11:18:07 +0100 Subject: drm/i915/ringbuffer: Check that we setup the ringbuffer Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/intel_ringbuffer.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 8eaa60cc5d25..e88214ef24b1 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -176,9 +176,10 @@ static int init_ring_common(struct intel_ring_buffer *ring) ((ring->gem_object->size - PAGE_SIZE) & RING_NR_PAGES) | RING_NO_REPORT | RING_VALID); - head = I915_READ_HEAD(ring) & HEAD_ADDR; /* If the head is still not zero, the ring is dead */ - if (head != 0) { + if ((I915_READ_CTL(ring) & RING_VALID) == 0 || + I915_READ_START(ring) != obj_priv->gtt_offset || + (I915_READ_HEAD(ring) & HEAD_ADDR) != 0) { DRM_ERROR("%s initialization failed " "ctl %08x head %08x tail %08x start %08x\n", ring->name, -- cgit v1.2.3 From fec6dd833e733b5d9588a1f1e4d81118b79b5774 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 27 Oct 2010 13:48:36 -0700 Subject: ASoC: Store DC offset correction for wm_hubs devices in class W mode Providing the analogue configuration of the output path remains the same the DC offset corrected by the DC servo will remain identical so we can skip the callibration, reducing the startup time for the headphone output. Implement this for the wm_hubs devices as has been done for several other CODECs. Don't do this if we have any analogue paths enabled since offsets may be being introduced by the analogue paths which could vary outside the control of the driver. Signed-off-by: Mark Brown Acked-by: Liam Girdwood --- sound/soc/codecs/wm8993.c | 2 ++ sound/soc/codecs/wm8994.c | 3 ++ sound/soc/codecs/wm_hubs.c | 69 ++++++++++++++++++++++++++++++---------------- sound/soc/codecs/wm_hubs.h | 3 ++ 4 files changed, 54 insertions(+), 23 deletions(-) diff --git a/sound/soc/codecs/wm8993.c b/sound/soc/codecs/wm8993.c index 589e3fa24734..67fe5ccc6082 100644 --- a/sound/soc/codecs/wm8993.c +++ b/sound/soc/codecs/wm8993.c @@ -735,6 +735,7 @@ static int class_w_put(struct snd_kcontrol *kcontrol, 0); } wm8993->class_w_users++; + wm8993->hubs_data.class_w = true; } /* Implement the change */ @@ -751,6 +752,7 @@ static int class_w_put(struct snd_kcontrol *kcontrol, WM8993_CP_DYN_V); } wm8993->class_w_users--; + wm8993->hubs_data.class_w = false; } dev_dbg(codec->dev, "Indirect DAC use count now %d\n", diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index 0db59c3aa5d4..3f70dee048b0 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c @@ -2228,6 +2228,7 @@ static int clk_sys_event(struct snd_soc_dapm_widget *w, static void wm8994_update_class_w(struct snd_soc_codec *codec) { + struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); int enable = 1; int source = 0; /* GCC flow analysis can't track enable */ int reg, reg_r; @@ -2278,11 +2279,13 @@ static void wm8994_update_class_w(struct snd_soc_codec *codec) WM8994_CP_DYN_PWR | WM8994_CP_DYN_SRC_SEL_MASK, source | WM8994_CP_DYN_PWR); + wm8994->hubs.class_w = true; } else { dev_dbg(codec->dev, "Class W disabled\n"); snd_soc_update_bits(codec, WM8994_CLASS_W_1, WM8994_CP_DYN_PWR, 0); + wm8994->hubs.class_w = false; } } diff --git a/sound/soc/codecs/wm_hubs.c b/sound/soc/codecs/wm_hubs.c index 2cb81538cd91..31c2a5724d85 100644 --- a/sound/soc/codecs/wm_hubs.c +++ b/sound/soc/codecs/wm_hubs.c @@ -94,6 +94,18 @@ static void calibrate_dc_servo(struct snd_soc_codec *codec) struct wm_hubs_data *hubs = snd_soc_codec_get_drvdata(codec); u16 reg, reg_l, reg_r, dcs_cfg; + /* If we're using a digital only path and have a previously + * callibrated DC servo offset stored then use that. */ + if (hubs->class_w && hubs->class_w_dcs) { + dev_dbg(codec->dev, "Using cached DC servo offset %x\n", + hubs->class_w_dcs); + snd_soc_write(codec, WM8993_DC_SERVO_3, hubs->class_w_dcs); + wait_for_dc_servo(codec, + WM8993_DCS_TRIG_DAC_WR_0 | + WM8993_DCS_TRIG_DAC_WR_1); + return; + } + /* Set for 32 series updates */ snd_soc_update_bits(codec, WM8993_DC_SERVO_1, WM8993_DCS_SERIES_NO_01_MASK, @@ -101,34 +113,34 @@ static void calibrate_dc_servo(struct snd_soc_codec *codec) wait_for_dc_servo(codec, WM8993_DCS_TRIG_SERIES_0 | WM8993_DCS_TRIG_SERIES_1); + /* Different chips in the family support different readback + * methods. + */ + switch (hubs->dcs_readback_mode) { + case 0: + reg_l = snd_soc_read(codec, WM8993_DC_SERVO_READBACK_1) + & WM8993_DCS_INTEG_CHAN_0_MASK;; + reg_r = snd_soc_read(codec, WM8993_DC_SERVO_READBACK_2) + & WM8993_DCS_INTEG_CHAN_1_MASK; + break; + case 1: + reg = snd_soc_read(codec, WM8993_DC_SERVO_3); + reg_l = (reg & WM8993_DCS_DAC_WR_VAL_1_MASK) + >> WM8993_DCS_DAC_WR_VAL_1_SHIFT; + reg_r = reg & WM8993_DCS_DAC_WR_VAL_0_MASK; + break; + default: + WARN(1, "Unknown DCS readback method"); + break; + } + + dev_dbg(codec->dev, "DCS input: %x %x\n", reg_l, reg_r); + /* Apply correction to DC servo result */ if (hubs->dcs_codes) { dev_dbg(codec->dev, "Applying %d code DC servo correction\n", hubs->dcs_codes); - /* Different chips in the family support different - * readback methods. - */ - switch (hubs->dcs_readback_mode) { - case 0: - reg_l = snd_soc_read(codec, WM8993_DC_SERVO_READBACK_1) - & WM8993_DCS_INTEG_CHAN_0_MASK;; - reg_r = snd_soc_read(codec, WM8993_DC_SERVO_READBACK_2) - & WM8993_DCS_INTEG_CHAN_1_MASK; - break; - case 1: - reg = snd_soc_read(codec, WM8993_DC_SERVO_3); - reg_l = (reg & WM8993_DCS_DAC_WR_VAL_1_MASK) - >> WM8993_DCS_DAC_WR_VAL_1_SHIFT; - reg_r = reg & WM8993_DCS_DAC_WR_VAL_0_MASK; - break; - default: - WARN(1, "Unknown DCS readback method"); - break; - } - - dev_dbg(codec->dev, "DCS input: %x %x\n", reg_l, reg_r); - /* HPOUT1L */ if (reg_l + hubs->dcs_codes > 0 && reg_l + hubs->dcs_codes < 0xff) @@ -148,7 +160,15 @@ static void calibrate_dc_servo(struct snd_soc_codec *codec) wait_for_dc_servo(codec, WM8993_DCS_TRIG_DAC_WR_0 | WM8993_DCS_TRIG_DAC_WR_1); + } else { + dcs_cfg = reg_l << WM8993_DCS_DAC_WR_VAL_1_SHIFT; + dcs_cfg |= reg_r; } + + /* Save the callibrated offset if we're in class W mode and + * therefore don't have any analogue signal mixed in. */ + if (hubs->class_w) + hubs->class_w_dcs = dcs_cfg; } /* @@ -163,6 +183,9 @@ static int wm8993_put_dc_servo(struct snd_kcontrol *kcontrol, ret = snd_soc_put_volsw_2r(kcontrol, ucontrol); + /* Updating the analogue gains invalidates the DC servo cache */ + hubs->class_w_dcs = 0; + /* If we're applying an offset correction then updating the * callibration would be likely to introduce further offsets. */ if (hubs->dcs_codes) diff --git a/sound/soc/codecs/wm_hubs.h b/sound/soc/codecs/wm_hubs.h index e51c16683589..f8a5e976b5e6 100644 --- a/sound/soc/codecs/wm_hubs.h +++ b/sound/soc/codecs/wm_hubs.h @@ -23,6 +23,9 @@ struct wm_hubs_data { int dcs_codes; int dcs_readback_mode; int hp_startup_mode; + + bool class_w; + u16 class_w_dcs; }; extern int wm_hubs_add_analogue_controls(struct snd_soc_codec *); -- cgit v1.2.3 From 17250b71553680bc6e927497aa619ab06ab1015b Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 28 Oct 2010 12:51:39 +0100 Subject: drm/i915: Make the inactive object shrinker per-device Eliminate the racy device unload by embedding a shrinker into each device. Smaller, simpler code. Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_dma.c | 3 + drivers/gpu/drm/i915/i915_drv.c | 3 - drivers/gpu/drm/i915/i915_drv.h | 12 +-- drivers/gpu/drm/i915/i915_gem.c | 179 ++++++++++++---------------------------- 4 files changed, 56 insertions(+), 141 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index f8827c23a668..dddca007912a 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -2096,6 +2096,9 @@ int i915_driver_unload(struct drm_device *dev) i915_mch_dev = NULL; spin_unlock(&mchdev_lock); + if (dev_priv->mm.inactive_shrinker.shrink) + unregister_shrinker(&dev_priv->mm.inactive_shrinker); + mutex_lock(&dev->struct_mutex); ret = i915_gpu_idle(dev); if (ret) diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 82c19ab3e1e2..d22aab94d645 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -660,8 +660,6 @@ static int __init i915_init(void) driver.num_ioctls = i915_max_ioctl; - i915_gem_shrinker_init(); - /* * If CONFIG_DRM_I915_KMS is set, default to KMS unless * explicitly disabled with the module pararmeter. @@ -693,7 +691,6 @@ static int __init i915_init(void) static void __exit i915_exit(void) { - i915_gem_shrinker_exit(); drm_exit(&driver); } diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 895f9173de58..29e8b7962edf 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -542,14 +542,7 @@ typedef struct drm_i915_private { struct io_mapping *gtt_mapping; int gtt_mtrr; - /** - * Membership on list of all loaded devices, used to evict - * inactive buffers under memory pressure. - * - * Modifications should only be done whilst holding the - * shrink_list_lock spinlock. - */ - struct list_head shrink_list; + struct shrinker inactive_shrinker; /** * List of objects currently involved in rendering. @@ -1079,9 +1072,6 @@ void i915_gem_detach_phys_object(struct drm_device *dev, void i915_gem_free_all_phys_object(struct drm_device *dev); void i915_gem_release(struct drm_device * dev, struct drm_file *file_priv); -void i915_gem_shrinker_init(void); -void i915_gem_shrinker_exit(void); - /* i915_gem_evict.c */ int i915_gem_evict_something(struct drm_device *dev, int min_size, unsigned alignment, bool mappable); diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 19ceb8cd0922..1af7285ca162 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -65,8 +65,10 @@ i915_gem_object_get_pages(struct drm_gem_object *obj, static void i915_gem_object_put_pages(struct drm_gem_object *obj); -static LIST_HEAD(shrink_list); -static DEFINE_SPINLOCK(shrink_list_lock); +static int i915_gem_inactive_shrink(struct shrinker *shrinker, + int nr_to_scan, + gfp_t gfp_mask); + /* some bookkeeping */ static void i915_gem_info_add_obj(struct drm_i915_private *dev_priv, @@ -4765,9 +4767,6 @@ i915_gem_load(struct drm_device *dev) INIT_DELAYED_WORK(&dev_priv->mm.retire_work, i915_gem_retire_work_handler); init_completion(&dev_priv->error_completion); - spin_lock(&shrink_list_lock); - list_add(&dev_priv->mm.shrink_list, &shrink_list); - spin_unlock(&shrink_list_lock); /* On GEN3 we really need to make sure the ARB C3 LP bit is set */ if (IS_GEN3(dev)) { @@ -4810,6 +4809,10 @@ i915_gem_load(struct drm_device *dev) } i915_gem_detect_bit_6_swizzle(dev); init_waitqueue_head(&dev_priv->pending_flip_queue); + + dev_priv->mm.inactive_shrinker.shrink = i915_gem_inactive_shrink; + dev_priv->mm.inactive_shrinker.seeks = DEFAULT_SEEKS; + register_shrinker(&dev_priv->mm.inactive_shrinker); } /* @@ -5022,152 +5025,74 @@ i915_gpu_is_active(struct drm_device *dev) int lists_empty; lists_empty = list_empty(&dev_priv->mm.flushing_list) && - list_empty(&dev_priv->render_ring.active_list) && - list_empty(&dev_priv->bsd_ring.active_list) && - list_empty(&dev_priv->blt_ring.active_list); + list_empty(&dev_priv->mm.active_list); return !lists_empty; } static int -i915_gem_shrink(struct shrinker *shrink, int nr_to_scan, gfp_t gfp_mask) +i915_gem_inactive_shrink(struct shrinker *shrinker, + int nr_to_scan, + gfp_t gfp_mask) { - drm_i915_private_t *dev_priv, *next_dev; - struct drm_i915_gem_object *obj_priv, *next_obj; - int cnt = 0; - int would_deadlock = 1; + struct drm_i915_private *dev_priv = + container_of(shrinker, + struct drm_i915_private, + mm.inactive_shrinker); + struct drm_device *dev = dev_priv->dev; + struct drm_i915_gem_object *obj, *next; + int cnt; + + if (!mutex_trylock(&dev->struct_mutex)) + return nr_to_scan ? 0 : -1; /* "fast-path" to count number of available objects */ if (nr_to_scan == 0) { - spin_lock(&shrink_list_lock); - list_for_each_entry(dev_priv, &shrink_list, mm.shrink_list) { - struct drm_device *dev = dev_priv->dev; - - if (mutex_trylock(&dev->struct_mutex)) { - list_for_each_entry(obj_priv, - &dev_priv->mm.inactive_list, - mm_list) - cnt++; - mutex_unlock(&dev->struct_mutex); - } - } - spin_unlock(&shrink_list_lock); - - return (cnt / 100) * sysctl_vfs_cache_pressure; + cnt = 0; + list_for_each_entry(obj, + &dev_priv->mm.inactive_list, + mm_list) + cnt++; + mutex_unlock(&dev->struct_mutex); + return cnt / 100 * sysctl_vfs_cache_pressure; } - spin_lock(&shrink_list_lock); - rescan: /* first scan for clean buffers */ - list_for_each_entry_safe(dev_priv, next_dev, - &shrink_list, mm.shrink_list) { - struct drm_device *dev = dev_priv->dev; - - if (! mutex_trylock(&dev->struct_mutex)) - continue; - - spin_unlock(&shrink_list_lock); - i915_gem_retire_requests(dev); + i915_gem_retire_requests(dev); - list_for_each_entry_safe(obj_priv, next_obj, - &dev_priv->mm.inactive_list, - mm_list) { - if (i915_gem_object_is_purgeable(obj_priv)) { - i915_gem_object_unbind(&obj_priv->base); - if (--nr_to_scan <= 0) - break; - } + list_for_each_entry_safe(obj, next, + &dev_priv->mm.inactive_list, + mm_list) { + if (i915_gem_object_is_purgeable(obj)) { + i915_gem_object_unbind(&obj->base); + if (--nr_to_scan == 0) + break; } - - spin_lock(&shrink_list_lock); - mutex_unlock(&dev->struct_mutex); - - would_deadlock = 0; - - if (nr_to_scan <= 0) - break; } /* second pass, evict/count anything still on the inactive list */ - list_for_each_entry_safe(dev_priv, next_dev, - &shrink_list, mm.shrink_list) { - struct drm_device *dev = dev_priv->dev; - - if (! mutex_trylock(&dev->struct_mutex)) - continue; - - spin_unlock(&shrink_list_lock); - - list_for_each_entry_safe(obj_priv, next_obj, - &dev_priv->mm.inactive_list, - mm_list) { - if (nr_to_scan > 0) { - i915_gem_object_unbind(&obj_priv->base); - nr_to_scan--; - } else - cnt++; - } - - spin_lock(&shrink_list_lock); - mutex_unlock(&dev->struct_mutex); - - would_deadlock = 0; - } - - if (nr_to_scan) { - int active = 0; - + cnt = 0; + list_for_each_entry_safe(obj, next, + &dev_priv->mm.inactive_list, + mm_list) { + if (nr_to_scan) { + i915_gem_object_unbind(&obj->base); + nr_to_scan--; + } else + cnt++; + } + + if (nr_to_scan && i915_gpu_is_active(dev)) { /* * We are desperate for pages, so as a last resort, wait * for the GPU to finish and discard whatever we can. * This has a dramatic impact to reduce the number of * OOM-killer events whilst running the GPU aggressively. */ - list_for_each_entry(dev_priv, &shrink_list, mm.shrink_list) { - struct drm_device *dev = dev_priv->dev; - - if (!mutex_trylock(&dev->struct_mutex)) - continue; - - spin_unlock(&shrink_list_lock); - - if (i915_gpu_is_active(dev)) { - i915_gpu_idle(dev); - active++; - } - - spin_lock(&shrink_list_lock); - mutex_unlock(&dev->struct_mutex); - } - - if (active) + if (i915_gpu_idle(dev) == 0) goto rescan; } - - spin_unlock(&shrink_list_lock); - - if (would_deadlock) - return -1; - else if (cnt > 0) - return (cnt / 100) * sysctl_vfs_cache_pressure; - else - return 0; -} - -static struct shrinker shrinker = { - .shrink = i915_gem_shrink, - .seeks = DEFAULT_SEEKS, -}; - -__init void -i915_gem_shrinker_init(void) -{ - register_shrinker(&shrinker); -} - -__exit void -i915_gem_shrinker_exit(void) -{ - unregister_shrinker(&shrinker); + mutex_unlock(&dev->struct_mutex); + return cnt / 100 * sysctl_vfs_cache_pressure; } -- cgit v1.2.3 From 39a01d1fb63cf8ebc1a8cf436f5c0ba9657b55c6 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 28 Oct 2010 13:03:06 +0100 Subject: drm/i915: Remove mmap_offset Since we rarely use the mmap_offset and it is easily computable from the obj->map_list.hash, remove it. Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_drv.h | 5 ----- drivers/gpu/drm/i915/i915_gem.c | 46 ++++++++++------------------------------- 2 files changed, 11 insertions(+), 40 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 29e8b7962edf..1f7e8b3c8df0 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -796,11 +796,6 @@ struct drm_i915_gem_object { /* Which ring is refering to is this object */ struct intel_ring_buffer *ring; - /** - * Fake offset for use by mmap(2) - */ - uint64_t mmap_offset; - /** Breadcrumb of last rendering to the buffer. */ uint32_t last_rendering_seqno; diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 1af7285ca162..4ade4e243379 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1392,7 +1392,6 @@ i915_gem_create_mmap_offset(struct drm_gem_object *obj) { struct drm_device *dev = obj->dev; struct drm_gem_mm *mm = dev->mm_private; - struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); struct drm_map_list *list; struct drm_local_map *map; int ret = 0; @@ -1431,16 +1430,13 @@ i915_gem_create_mmap_offset(struct drm_gem_object *obj) goto out_free_mm; } - /* By now we should be all set, any drm_mmap request on the offset - * below will get to our mmap & fault handler */ - obj_priv->mmap_offset = ((uint64_t) list->hash.key) << PAGE_SHIFT; - return 0; out_free_mm: drm_mm_put_block(list->file_offset_node); out_free_list: kfree(list->map); + list->map = NULL; return ret; } @@ -1466,9 +1462,10 @@ i915_gem_release_mmap(struct drm_gem_object *obj) struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); - if (dev->dev_mapping) + if (unlikely(obj->map_list.map && dev->dev_mapping)) unmap_mapping_range(dev->dev_mapping, - obj_priv->mmap_offset, obj->size, 1); + (loff_t)obj->map_list.hash.key<size, 1); if (obj_priv->fault_mappable) { obj_priv->fault_mappable = false; @@ -1480,24 +1477,13 @@ static void i915_gem_free_mmap_offset(struct drm_gem_object *obj) { struct drm_device *dev = obj->dev; - struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); struct drm_gem_mm *mm = dev->mm_private; - struct drm_map_list *list; + struct drm_map_list *list = &obj->map_list; - list = &obj->map_list; drm_ht_remove_item(&mm->offset_hash, &list->hash); - - if (list->file_offset_node) { - drm_mm_put_block(list->file_offset_node); - list->file_offset_node = NULL; - } - - if (list->map) { - kfree(list->map); - list->map = NULL; - } - - obj_priv->mmap_offset = 0; + drm_mm_put_block(list->file_offset_node); + kfree(list->map); + list->map = NULL; } /** @@ -1586,23 +1572,13 @@ i915_gem_mmap_gtt_ioctl(struct drm_device *dev, void *data, goto out; } - if (!obj_priv->mmap_offset) { + if (!obj->map_list.map) { ret = i915_gem_create_mmap_offset(obj); if (ret) goto out; } - args->offset = obj_priv->mmap_offset; - - /* - * Pull it into the GTT so that we have a page list (makes the - * initial fault faster and any subsequent flushing possible). - */ - if (!obj_priv->agp_mem) { - ret = i915_gem_object_bind_to_gtt(obj, 0, true); - if (ret) - goto out; - } + args->offset = (u64)obj->map_list.hash.key << PAGE_SHIFT; out: drm_gem_object_unreference(obj); @@ -4477,7 +4453,7 @@ static void i915_gem_free_object_tail(struct drm_gem_object *obj) return; } - if (obj_priv->mmap_offset) + if (obj->map_list.map) i915_gem_free_mmap_offset(obj); drm_gem_object_release(obj); -- cgit v1.2.3 From e5281ccd2e0049e2b9e8ce82449630d25082372d Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 28 Oct 2010 13:45:36 +0100 Subject: drm/i915: Eliminate nested get/put pages By using read_cache_page() for individual pages during pwrite/pread we can eliminate an unnecessary large allocation (and immediate free) of obj->pages. Also this eliminates any potential nesting of get/put pages, simplifying the code and preparing the path for greater things. Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_drv.h | 9 - drivers/gpu/drm/i915/i915_gem.c | 358 ++++++++++++++++++---------------------- 2 files changed, 163 insertions(+), 204 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 1f7e8b3c8df0..3df8a624ddc9 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -747,15 +747,6 @@ struct drm_i915_gem_object { */ unsigned int madv : 2; - /** - * Refcount for the pages array. With the current locking scheme, there - * are at most two concurrent users: Binding a bo to the gtt and - * pwrite/pread using physical addresses. So two bits for a maximum - * of two users are enough. - */ - unsigned int pages_refcount : 2; -#define DRM_I915_GEM_OBJECT_MAX_PAGES_REFCOUNT 0x3 - /** * Current tiling mode for the object. */ diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 4ade4e243379..abe6d901f95b 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -58,13 +58,6 @@ static int i915_gem_phys_pwrite(struct drm_device *dev, struct drm_gem_object *o struct drm_file *file_priv); static void i915_gem_free_object_tail(struct drm_gem_object *obj); -static int -i915_gem_object_get_pages(struct drm_gem_object *obj, - gfp_t gfpmask); - -static void -i915_gem_object_put_pages(struct drm_gem_object *obj); - static int i915_gem_inactive_shrink(struct shrinker *shrinker, int nr_to_scan, gfp_t gfp_mask); @@ -326,22 +319,6 @@ i915_gem_object_cpu_accessible(struct drm_i915_gem_object *obj) obj->gtt_offset + obj->base.size <= dev_priv->mm.gtt_mappable_end; } -static inline int -fast_shmem_read(struct page **pages, - loff_t page_base, int page_offset, - char __user *data, - int length) -{ - char *vaddr; - int ret; - - vaddr = kmap_atomic(pages[page_base >> PAGE_SHIFT]); - ret = __copy_to_user_inatomic(data, vaddr + page_offset, length); - kunmap_atomic(vaddr); - - return ret; -} - static int i915_gem_object_needs_bit17_swizzle(struct drm_gem_object *obj) { drm_i915_private_t *dev_priv = obj->dev->dev_private; @@ -429,8 +406,9 @@ i915_gem_shmem_pread_fast(struct drm_device *dev, struct drm_gem_object *obj, struct drm_file *file_priv) { struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); + struct address_space *mapping = obj->filp->f_path.dentry->d_inode->i_mapping; ssize_t remain; - loff_t offset, page_base; + loff_t offset; char __user *user_data; int page_offset, page_length; @@ -441,21 +419,34 @@ i915_gem_shmem_pread_fast(struct drm_device *dev, struct drm_gem_object *obj, offset = args->offset; while (remain > 0) { + struct page *page; + char *vaddr; + int ret; + /* Operation in this page * - * page_base = page offset within aperture * page_offset = offset within page * page_length = bytes to copy for this page */ - page_base = (offset & ~(PAGE_SIZE-1)); page_offset = offset & (PAGE_SIZE-1); page_length = remain; if ((page_offset + remain) > PAGE_SIZE) page_length = PAGE_SIZE - page_offset; - if (fast_shmem_read(obj_priv->pages, - page_base, page_offset, - user_data, page_length)) + page = read_cache_page_gfp(mapping, offset >> PAGE_SHIFT, + GFP_HIGHUSER | __GFP_RECLAIMABLE); + if (IS_ERR(page)) + return PTR_ERR(page); + + vaddr = kmap_atomic(page); + ret = __copy_to_user_inatomic(user_data, + vaddr + page_offset, + page_length); + kunmap_atomic(vaddr); + + mark_page_accessed(page); + page_cache_release(page); + if (ret) return -EFAULT; remain -= page_length; @@ -466,31 +457,6 @@ i915_gem_shmem_pread_fast(struct drm_device *dev, struct drm_gem_object *obj, return 0; } -static int -i915_gem_object_get_pages_or_evict(struct drm_gem_object *obj) -{ - int ret; - - ret = i915_gem_object_get_pages(obj, __GFP_NORETRY | __GFP_NOWARN); - - /* If we've insufficient memory to map in the pages, attempt - * to make some space by throwing out some old buffers. - */ - if (ret == -ENOMEM) { - struct drm_device *dev = obj->dev; - - ret = i915_gem_evict_something(dev, obj->size, - i915_gem_get_gtt_alignment(obj), - false); - if (ret) - return ret; - - ret = i915_gem_object_get_pages(obj, 0); - } - - return ret; -} - /** * This is the fallback shmem pread path, which allocates temporary storage * in kernel space to copy_to_user into outside of the struct_mutex, so we @@ -502,14 +468,15 @@ i915_gem_shmem_pread_slow(struct drm_device *dev, struct drm_gem_object *obj, struct drm_i915_gem_pread *args, struct drm_file *file_priv) { + struct address_space *mapping = obj->filp->f_path.dentry->d_inode->i_mapping; struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); struct mm_struct *mm = current->mm; struct page **user_pages; ssize_t remain; loff_t offset, pinned_pages, i; loff_t first_data_page, last_data_page, num_pages; - int shmem_page_index, shmem_page_offset; - int data_page_index, data_page_offset; + int shmem_page_offset; + int data_page_index, data_page_offset; int page_length; int ret; uint64_t data_ptr = args->data_ptr; @@ -552,15 +519,15 @@ i915_gem_shmem_pread_slow(struct drm_device *dev, struct drm_gem_object *obj, offset = args->offset; while (remain > 0) { + struct page *page; + /* Operation in this page * - * shmem_page_index = page number within shmem file * shmem_page_offset = offset within page in shmem file * data_page_index = page number in get_user_pages return * data_page_offset = offset with data_page_index page. * page_length = bytes to copy for this page */ - shmem_page_index = offset / PAGE_SIZE; shmem_page_offset = offset & ~PAGE_MASK; data_page_index = data_ptr / PAGE_SIZE - first_data_page; data_page_offset = data_ptr & ~PAGE_MASK; @@ -571,8 +538,13 @@ i915_gem_shmem_pread_slow(struct drm_device *dev, struct drm_gem_object *obj, if ((data_page_offset + page_length) > PAGE_SIZE) page_length = PAGE_SIZE - data_page_offset; + page = read_cache_page_gfp(mapping, offset >> PAGE_SHIFT, + GFP_HIGHUSER | __GFP_RECLAIMABLE); + if (IS_ERR(page)) + return PTR_ERR(page); + if (do_bit17_swizzling) { - slow_shmem_bit17_copy(obj_priv->pages[shmem_page_index], + slow_shmem_bit17_copy(page, shmem_page_offset, user_pages[data_page_index], data_page_offset, @@ -581,11 +553,14 @@ i915_gem_shmem_pread_slow(struct drm_device *dev, struct drm_gem_object *obj, } else { slow_shmem_copy(user_pages[data_page_index], data_page_offset, - obj_priv->pages[shmem_page_index], + page, shmem_page_offset, page_length); } + mark_page_accessed(page); + page_cache_release(page); + remain -= page_length; data_ptr += page_length; offset += page_length; @@ -594,6 +569,7 @@ i915_gem_shmem_pread_slow(struct drm_device *dev, struct drm_gem_object *obj, out: for (i = 0; i < pinned_pages; i++) { SetPageDirty(user_pages[i]); + mark_page_accessed(user_pages[i]); page_cache_release(user_pages[i]); } drm_free_large(user_pages); @@ -649,15 +625,11 @@ i915_gem_pread_ioctl(struct drm_device *dev, void *data, goto out; } - ret = i915_gem_object_get_pages_or_evict(obj); - if (ret) - goto out; - ret = i915_gem_object_set_cpu_read_domain_range(obj, args->offset, args->size); if (ret) - goto out_put; + goto out; ret = -EFAULT; if (!i915_gem_object_needs_bit17_swizzle(obj)) @@ -665,8 +637,6 @@ i915_gem_pread_ioctl(struct drm_device *dev, void *data, if (ret == -EFAULT) ret = i915_gem_shmem_pread_slow(dev, obj, args, file_priv); -out_put: - i915_gem_object_put_pages(obj); out: drm_gem_object_unreference(obj); unlock: @@ -718,22 +688,6 @@ slow_kernel_write(struct io_mapping *mapping, io_mapping_unmap(dst_vaddr); } -static inline int -fast_shmem_write(struct page **pages, - loff_t page_base, int page_offset, - char __user *data, - int length) -{ - char *vaddr; - int ret; - - vaddr = kmap_atomic(pages[page_base >> PAGE_SHIFT]); - ret = __copy_from_user_inatomic(vaddr + page_offset, data, length); - kunmap_atomic(vaddr); - - return ret; -} - /** * This is the fast pwrite path, where we copy the data directly from the * user into the GTT, uncached. @@ -890,9 +844,10 @@ i915_gem_shmem_pwrite_fast(struct drm_device *dev, struct drm_gem_object *obj, struct drm_i915_gem_pwrite *args, struct drm_file *file_priv) { + struct address_space *mapping = obj->filp->f_path.dentry->d_inode->i_mapping; struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); ssize_t remain; - loff_t offset, page_base; + loff_t offset; char __user *user_data; int page_offset, page_length; @@ -904,21 +859,40 @@ i915_gem_shmem_pwrite_fast(struct drm_device *dev, struct drm_gem_object *obj, obj_priv->dirty = 1; while (remain > 0) { + struct page *page; + char *vaddr; + int ret; + /* Operation in this page * - * page_base = page offset within aperture * page_offset = offset within page * page_length = bytes to copy for this page */ - page_base = (offset & ~(PAGE_SIZE-1)); page_offset = offset & (PAGE_SIZE-1); page_length = remain; if ((page_offset + remain) > PAGE_SIZE) page_length = PAGE_SIZE - page_offset; - if (fast_shmem_write(obj_priv->pages, - page_base, page_offset, - user_data, page_length)) + page = read_cache_page_gfp(mapping, offset >> PAGE_SHIFT, + GFP_HIGHUSER | __GFP_RECLAIMABLE); + if (IS_ERR(page)) + return PTR_ERR(page); + + vaddr = kmap_atomic(page, KM_USER0); + ret = __copy_from_user_inatomic(vaddr + page_offset, + user_data, + page_length); + kunmap_atomic(vaddr, KM_USER0); + + set_page_dirty(page); + mark_page_accessed(page); + page_cache_release(page); + + /* If we get a fault while copying data, then (presumably) our + * source page isn't available. Return the error and we'll + * retry in the slow path. + */ + if (ret) return -EFAULT; remain -= page_length; @@ -941,13 +915,14 @@ i915_gem_shmem_pwrite_slow(struct drm_device *dev, struct drm_gem_object *obj, struct drm_i915_gem_pwrite *args, struct drm_file *file_priv) { + struct address_space *mapping = obj->filp->f_path.dentry->d_inode->i_mapping; struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); struct mm_struct *mm = current->mm; struct page **user_pages; ssize_t remain; loff_t offset, pinned_pages, i; loff_t first_data_page, last_data_page, num_pages; - int shmem_page_index, shmem_page_offset; + int shmem_page_offset; int data_page_index, data_page_offset; int page_length; int ret; @@ -990,15 +965,15 @@ i915_gem_shmem_pwrite_slow(struct drm_device *dev, struct drm_gem_object *obj, obj_priv->dirty = 1; while (remain > 0) { + struct page *page; + /* Operation in this page * - * shmem_page_index = page number within shmem file * shmem_page_offset = offset within page in shmem file * data_page_index = page number in get_user_pages return * data_page_offset = offset with data_page_index page. * page_length = bytes to copy for this page */ - shmem_page_index = offset / PAGE_SIZE; shmem_page_offset = offset & ~PAGE_MASK; data_page_index = data_ptr / PAGE_SIZE - first_data_page; data_page_offset = data_ptr & ~PAGE_MASK; @@ -1009,21 +984,32 @@ i915_gem_shmem_pwrite_slow(struct drm_device *dev, struct drm_gem_object *obj, if ((data_page_offset + page_length) > PAGE_SIZE) page_length = PAGE_SIZE - data_page_offset; + page = read_cache_page_gfp(mapping, offset >> PAGE_SHIFT, + GFP_HIGHUSER | __GFP_RECLAIMABLE); + if (IS_ERR(page)) { + ret = PTR_ERR(page); + goto out; + } + if (do_bit17_swizzling) { - slow_shmem_bit17_copy(obj_priv->pages[shmem_page_index], + slow_shmem_bit17_copy(page, shmem_page_offset, user_pages[data_page_index], data_page_offset, page_length, 0); } else { - slow_shmem_copy(obj_priv->pages[shmem_page_index], + slow_shmem_copy(page, shmem_page_offset, user_pages[data_page_index], data_page_offset, page_length); } + set_page_dirty(page); + mark_page_accessed(page); + page_cache_release(page); + remain -= page_length; data_ptr += page_length; offset += page_length; @@ -1112,22 +1098,15 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data, out_unpin: i915_gem_object_unpin(obj); } else { - ret = i915_gem_object_get_pages_or_evict(obj); - if (ret) - goto out; - ret = i915_gem_object_set_to_cpu_domain(obj, 1); if (ret) - goto out_put; + goto out; ret = -EFAULT; if (!i915_gem_object_needs_bit17_swizzle(obj)) ret = i915_gem_shmem_pwrite_fast(dev, obj, args, file); if (ret == -EFAULT) ret = i915_gem_shmem_pwrite_slow(dev, obj, args, file); - -out_put: - i915_gem_object_put_pages(obj); } out: @@ -1587,19 +1566,62 @@ unlock: return ret; } +static int +i915_gem_object_get_pages_gtt(struct drm_gem_object *obj, + gfp_t gfpmask) +{ + struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); + int page_count, i; + struct address_space *mapping; + struct inode *inode; + struct page *page; + + /* Get the list of pages out of our struct file. They'll be pinned + * at this point until we release them. + */ + page_count = obj->size / PAGE_SIZE; + BUG_ON(obj_priv->pages != NULL); + obj_priv->pages = drm_malloc_ab(page_count, sizeof(struct page *)); + if (obj_priv->pages == NULL) + return -ENOMEM; + + inode = obj->filp->f_path.dentry->d_inode; + mapping = inode->i_mapping; + for (i = 0; i < page_count; i++) { + page = read_cache_page_gfp(mapping, i, + GFP_HIGHUSER | + __GFP_COLD | + __GFP_RECLAIMABLE | + gfpmask); + if (IS_ERR(page)) + goto err_pages; + + obj_priv->pages[i] = page; + } + + if (obj_priv->tiling_mode != I915_TILING_NONE) + i915_gem_object_do_bit_17_swizzle(obj); + + return 0; + +err_pages: + while (i--) + page_cache_release(obj_priv->pages[i]); + + drm_free_large(obj_priv->pages); + obj_priv->pages = NULL; + return PTR_ERR(page); +} + static void -i915_gem_object_put_pages(struct drm_gem_object *obj) +i915_gem_object_put_pages_gtt(struct drm_gem_object *obj) { struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); int page_count = obj->size / PAGE_SIZE; int i; - BUG_ON(obj_priv->pages_refcount == 0); BUG_ON(obj_priv->madv == __I915_MADV_PURGED); - if (--obj_priv->pages_refcount != 0) - return; - if (obj_priv->tiling_mode != I915_TILING_NONE) i915_gem_object_save_bit_17_swizzle(obj); @@ -2229,8 +2251,7 @@ i915_gem_object_unbind(struct drm_gem_object *obj) drm_unbind_agp(obj_priv->agp_mem); drm_free_agp(obj_priv->agp_mem, obj->size / PAGE_SIZE); - i915_gem_object_put_pages(obj); - BUG_ON(obj_priv->pages_refcount); + i915_gem_object_put_pages_gtt(obj); i915_gem_info_remove_gtt(dev_priv, obj); list_del_init(&obj_priv->mm_list); @@ -2290,62 +2311,6 @@ i915_gpu_idle(struct drm_device *dev) return 0; } -static int -i915_gem_object_get_pages(struct drm_gem_object *obj, - gfp_t gfpmask) -{ - struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); - int page_count, i; - struct address_space *mapping; - struct inode *inode; - struct page *page; - - BUG_ON(obj_priv->pages_refcount - == DRM_I915_GEM_OBJECT_MAX_PAGES_REFCOUNT); - - if (obj_priv->pages_refcount++ != 0) - return 0; - - /* Get the list of pages out of our struct file. They'll be pinned - * at this point until we release them. - */ - page_count = obj->size / PAGE_SIZE; - BUG_ON(obj_priv->pages != NULL); - obj_priv->pages = drm_calloc_large(page_count, sizeof(struct page *)); - if (obj_priv->pages == NULL) { - obj_priv->pages_refcount--; - return -ENOMEM; - } - - inode = obj->filp->f_path.dentry->d_inode; - mapping = inode->i_mapping; - for (i = 0; i < page_count; i++) { - page = read_cache_page_gfp(mapping, i, - GFP_HIGHUSER | - __GFP_COLD | - __GFP_RECLAIMABLE | - gfpmask); - if (IS_ERR(page)) - goto err_pages; - - obj_priv->pages[i] = page; - } - - if (obj_priv->tiling_mode != I915_TILING_NONE) - i915_gem_object_do_bit_17_swizzle(obj); - - return 0; - -err_pages: - while (i--) - page_cache_release(obj_priv->pages[i]); - - drm_free_large(obj_priv->pages); - obj_priv->pages = NULL; - obj_priv->pages_refcount--; - return PTR_ERR(page); -} - static void sandybridge_write_fence_reg(struct drm_i915_fence_reg *reg) { struct drm_gem_object *obj = reg->obj; @@ -2772,7 +2737,7 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, goto search_free; } - ret = i915_gem_object_get_pages(obj, gfpmask); + ret = i915_gem_object_get_pages_gtt(obj, gfpmask); if (ret) { drm_mm_put_block(obj_priv->gtt_space); obj_priv->gtt_space = NULL; @@ -2806,7 +2771,7 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, obj_priv->gtt_space->start, obj_priv->agp_type); if (obj_priv->agp_mem == NULL) { - i915_gem_object_put_pages(obj); + i915_gem_object_put_pages_gtt(obj); drm_mm_put_block(obj_priv->gtt_space); obj_priv->gtt_space = NULL; @@ -4860,33 +4825,35 @@ void i915_gem_free_all_phys_object(struct drm_device *dev) void i915_gem_detach_phys_object(struct drm_device *dev, struct drm_gem_object *obj) { - struct drm_i915_gem_object *obj_priv; + struct address_space *mapping = obj->filp->f_path.dentry->d_inode->i_mapping; + struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); + char *vaddr; int i; - int ret; int page_count; - obj_priv = to_intel_bo(obj); if (!obj_priv->phys_obj) return; - - ret = i915_gem_object_get_pages(obj, 0); - if (ret) - goto out; + vaddr = obj_priv->phys_obj->handle->vaddr; page_count = obj->size / PAGE_SIZE; for (i = 0; i < page_count; i++) { - char *dst = kmap_atomic(obj_priv->pages[i]); - char *src = obj_priv->phys_obj->handle->vaddr + (i * PAGE_SIZE); - - memcpy(dst, src, PAGE_SIZE); - kunmap_atomic(dst); + struct page *page = read_cache_page_gfp(mapping, i, + GFP_HIGHUSER | __GFP_RECLAIMABLE); + if (!IS_ERR(page)) { + char *dst = kmap_atomic(page); + memcpy(dst, vaddr + i*PAGE_SIZE, PAGE_SIZE); + kunmap_atomic(dst); + + drm_clflush_pages(&page, 1); + + set_page_dirty(page); + mark_page_accessed(page); + page_cache_release(page); + } } - drm_clflush_pages(obj_priv->pages, page_count); drm_agp_chipset_flush(dev); - i915_gem_object_put_pages(obj); -out: obj_priv->phys_obj->cur_obj = NULL; obj_priv->phys_obj = NULL; } @@ -4897,6 +4864,7 @@ i915_gem_attach_phys_object(struct drm_device *dev, int id, int align) { + struct address_space *mapping = obj->filp->f_path.dentry->d_inode->i_mapping; drm_i915_private_t *dev_priv = dev->dev_private; struct drm_i915_gem_object *obj_priv; int ret = 0; @@ -4920,7 +4888,7 @@ i915_gem_attach_phys_object(struct drm_device *dev, obj->size, align); if (ret) { DRM_ERROR("failed to init phys object %d size: %zu\n", id, obj->size); - goto out; + return ret; } } @@ -4928,27 +4896,27 @@ i915_gem_attach_phys_object(struct drm_device *dev, obj_priv->phys_obj = dev_priv->mm.phys_objs[id - 1]; obj_priv->phys_obj->cur_obj = obj; - ret = i915_gem_object_get_pages(obj, 0); - if (ret) { - DRM_ERROR("failed to get page list\n"); - goto out; - } - page_count = obj->size / PAGE_SIZE; for (i = 0; i < page_count; i++) { - char *src = kmap_atomic(obj_priv->pages[i]); - char *dst = obj_priv->phys_obj->handle->vaddr + (i * PAGE_SIZE); + struct page *page; + char *dst, *src; + + page = read_cache_page_gfp(mapping, i, + GFP_HIGHUSER | __GFP_RECLAIMABLE); + if (IS_ERR(page)) + return PTR_ERR(page); + src = kmap_atomic(obj_priv->pages[i]); + dst = obj_priv->phys_obj->handle->vaddr + (i * PAGE_SIZE); memcpy(dst, src, PAGE_SIZE); kunmap_atomic(src); - } - i915_gem_object_put_pages(obj); + mark_page_accessed(page); + page_cache_release(page); + } return 0; -out: - return ret; } static int -- cgit v1.2.3 From 4a684a4117abd756291969336af454e8a958802f Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 28 Oct 2010 14:44:08 +0100 Subject: drm/i915: Kill GTT mappings when moving from GTT domain In order to force a page-fault on a GTT mapping after we start using it from the GPU and so enforce correct CPU/GPU synchronisation, we need to invalidate the mapping. Pointed out by Owain G. Ainsworth. Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_gem.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index abe6d901f95b..d4d8f888db85 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1314,12 +1314,12 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) ret = i915_gem_object_bind_to_gtt(obj, 0, true); if (ret) goto unlock; - - ret = i915_gem_object_set_to_gtt_domain(obj, write); - if (ret) - goto unlock; } + ret = i915_gem_object_set_to_gtt_domain(obj, write); + if (ret) + goto unlock; + if (!obj_priv->fault_mappable) { obj_priv->fault_mappable = true; i915_gem_info_update_mappable(dev_priv, obj, true); @@ -2859,6 +2859,8 @@ i915_gem_object_flush_gtt_write_domain(struct drm_gem_object *obj) * to it immediately go to main memory as far as we know, so there's * no chipset flush. It also doesn't land in render cache. */ + i915_gem_release_mmap(obj); + old_write_domain = obj->write_domain; obj->write_domain = 0; @@ -3183,6 +3185,10 @@ i915_gem_object_set_to_gpu_domain(struct drm_gem_object *obj, if ((flush_domains | invalidate_domains) & I915_GEM_DOMAIN_CPU) i915_gem_clflush_object(obj); + /* blow away mappings if mapped through GTT */ + if ((flush_domains | invalidate_domains) & I915_GEM_DOMAIN_GTT) + i915_gem_release_mmap(obj); + /* The actual obj->write_domain will be updated with * pending_write_domain after we emit the accumulated flush for all * of our domain changes in execbuffers (which clears objects' -- cgit v1.2.3 From bbe2e11a4b683ead070ad5823cdf756e1525b903 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 28 Oct 2010 22:35:07 +0100 Subject: drm/i915: Do not return -1 from shrinker when nr_to_scan == 0 The error code is only expected during the actual pruning and not during the first measurement (nr_to_scan == 0) pass. Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_gem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index d4d8f888db85..7569b77fb403 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -4994,7 +4994,7 @@ i915_gem_inactive_shrink(struct shrinker *shrinker, int cnt; if (!mutex_trylock(&dev->struct_mutex)) - return nr_to_scan ? 0 : -1; + return 0; /* "fast-path" to count number of available objects */ if (nr_to_scan == 0) { -- cgit v1.2.3 From b0438a1b71955c425c304a2a483765ef24841766 Mon Sep 17 00:00:00 2001 From: Nicolas Kaiser Date: Fri, 29 Oct 2010 11:41:42 +0200 Subject: telephony: fix return value If copy_from_user fails, the return value gets overwritten. Signed-off-by: Nicolas Kaiser Signed-off-by: Jiri Kosina --- drivers/telephony/ixj.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/telephony/ixj.c b/drivers/telephony/ixj.c index 0d236f4bb8c2..2d1280a7a52b 100644 --- a/drivers/telephony/ixj.c +++ b/drivers/telephony/ixj.c @@ -6581,7 +6581,8 @@ static long do_ixj_ioctl(struct file *file_p, unsigned int cmd, unsigned long ar case IXJCTL_SET_FILTER: if (copy_from_user(&jf, argp, sizeof(jf))) retval = -EFAULT; - retval = ixj_init_filter(j, &jf); + else + retval = ixj_init_filter(j, &jf); break; case IXJCTL_SET_FILTER_RAW: if (copy_from_user(&jfr, argp, sizeof(jfr))) -- cgit v1.2.3 From 7465378fd7c681f6cf2b74b3494c4f0991d8c8ac Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 29 Oct 2010 10:41:23 +0100 Subject: drm/i915: Convert BUG_ON(pin_count) from an impossible condition Also spotted by Dan Carpenter. obj->pin_count is unsigned so the BUG_ON(obj->pin_count<0) will never trigger. Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_gem.c | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 7569b77fb403..08f57aedaf51 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -4128,12 +4128,7 @@ i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment, return ret; } - obj_priv->pin_count++; - - /* If the object is not active and not pending a flush, - * remove it from the inactive list - */ - if (obj_priv->pin_count == 1) { + if (obj_priv->pin_count++ == 0) { i915_gem_info_add_pin(dev_priv, obj, mappable); if (!obj_priv->active) list_move_tail(&obj_priv->mm_list, @@ -4153,15 +4148,10 @@ i915_gem_object_unpin(struct drm_gem_object *obj) struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); WARN_ON(i915_verify_lists(dev)); - obj_priv->pin_count--; - BUG_ON(obj_priv->pin_count < 0); + BUG_ON(obj_priv->pin_count == 0); BUG_ON(obj_priv->gtt_space == NULL); - /* If the object is no longer pinned, and is - * neither active nor being flushed, then stick it on - * the inactive list - */ - if (obj_priv->pin_count == 0) { + if (--obj_priv->pin_count == 0) { if (!obj_priv->active) list_move_tail(&obj_priv->mm_list, &dev_priv->mm.inactive_list); -- cgit v1.2.3 From a00b10c360b35d6431a94cbf130a4e162870d661 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 24 Sep 2010 21:15:47 +0100 Subject: drm/i915: Only enforce fence limits inside the GTT. So long as we adhere to the fence registers rules for alignment and no overlaps (including with unfenced accesses to linear memory) and account for the tiled access in our size allocation, we do not have to allocate the full fenced region for the object. This allows us to fight the bloat tiling imposed on pre-i965 chipsets and frees up RAM for real use. [Inside the GTT we still suffer the additional alignment constraints, so it doesn't magic allow us to render larger scenes without stalls -- we need the expanded GTT and fence pipelining to overcome those...] Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_debugfs.c | 3 +- drivers/gpu/drm/i915/i915_dma.c | 3 + drivers/gpu/drm/i915/i915_drv.h | 8 +- drivers/gpu/drm/i915/i915_gem.c | 290 +++++++++++++++++--------------- drivers/gpu/drm/i915/i915_gem_tiling.c | 32 ++-- drivers/gpu/drm/i915/intel_display.c | 7 +- drivers/gpu/drm/i915/intel_overlay.c | 4 +- drivers/gpu/drm/i915/intel_ringbuffer.c | 4 +- include/drm/i915_drm.h | 1 + 9 files changed, 197 insertions(+), 155 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 4fc1e05b769f..ba2af4e046ed 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -130,7 +130,8 @@ describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj) if (obj->fence_reg != I915_FENCE_REG_NONE) seq_printf(m, " (fence: %d)", obj->fence_reg); if (obj->gtt_space != NULL) - seq_printf(m, " (gtt_offset: %08x)", obj->gtt_offset); + seq_printf(m, " (gtt offset: %08x, size: %08x)", + obj->gtt_offset, (unsigned int)obj->gtt_space->size); if (obj->pin_mappable || obj->fault_mappable) seq_printf(m, " (mappable)"); if (obj->ring != NULL) diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index dddca007912a..00d8fb3e989f 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -770,6 +770,9 @@ static int i915_getparam(struct drm_device *dev, void *data, case I915_PARAM_HAS_BLT: value = HAS_BLT(dev); break; + case I915_PARAM_HAS_RELAXED_FENCING: + value = 1; + break; default: DRM_DEBUG_DRIVER("Unknown parameter %d\n", param->param); diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 3df8a624ddc9..7aa7f8abf892 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -746,6 +746,8 @@ struct drm_i915_gem_object { * Advice: are the backing pages purgeable? */ unsigned int madv : 2; + unsigned int fenceable : 1; + unsigned int mappable : 1; /** * Current tiling mode for the object. @@ -1005,7 +1007,7 @@ struct drm_gem_object * i915_gem_alloc_object(struct drm_device *dev, size_t size); void i915_gem_free_object(struct drm_gem_object *obj); int i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment, - bool mappable); + bool mappable, bool need_fence); void i915_gem_object_unpin(struct drm_gem_object *obj); int i915_gem_object_unbind(struct drm_gem_object *obj); void i915_gem_release_mmap(struct drm_gem_object *obj); @@ -1068,10 +1070,6 @@ int i915_gem_evict_inactive(struct drm_device *dev); void i915_gem_detect_bit_6_swizzle(struct drm_device *dev); void i915_gem_object_do_bit_17_swizzle(struct drm_gem_object *obj); void i915_gem_object_save_bit_17_swizzle(struct drm_gem_object *obj); -bool i915_tiling_ok(struct drm_device *dev, int stride, int size, - int tiling_mode); -bool i915_gem_object_fence_offset_ok(struct drm_gem_object *obj, - int tiling_mode); /* i915_gem_debug.c */ void i915_gem_dump_object(struct drm_gem_object *obj, int len, diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 08f57aedaf51..07ad1e354084 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -36,7 +36,8 @@ #include #include -static uint32_t i915_gem_get_gtt_alignment(struct drm_gem_object *obj); +static uint32_t i915_gem_get_gtt_alignment(struct drm_i915_gem_object *obj_priv); +static uint32_t i915_gem_get_gtt_size(struct drm_i915_gem_object *obj_priv); static int i915_gem_object_flush_gpu_write_domain(struct drm_gem_object *obj, bool pipelined); @@ -51,7 +52,9 @@ static void i915_gem_object_set_to_full_cpu_read_domain(struct drm_gem_object *o static int i915_gem_object_wait_rendering(struct drm_gem_object *obj, bool interruptible); static int i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, - unsigned alignment, bool mappable); + unsigned alignment, + bool mappable, + bool need_fence); static void i915_gem_clear_fence_reg(struct drm_gem_object *obj); static int i915_gem_phys_pwrite(struct drm_device *dev, struct drm_gem_object *obj, struct drm_i915_gem_pwrite *args, @@ -79,30 +82,26 @@ static void i915_gem_info_remove_obj(struct drm_i915_private *dev_priv, } static void i915_gem_info_add_gtt(struct drm_i915_private *dev_priv, - struct drm_gem_object *obj) + struct drm_i915_gem_object *obj) { - struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); dev_priv->mm.gtt_count++; - dev_priv->mm.gtt_memory += obj->size; - if (obj_priv->gtt_offset < dev_priv->mm.gtt_mappable_end) { + dev_priv->mm.gtt_memory += obj->gtt_space->size; + if (obj->gtt_offset < dev_priv->mm.gtt_mappable_end) { dev_priv->mm.mappable_gtt_used += - min_t(size_t, obj->size, - dev_priv->mm.gtt_mappable_end - - obj_priv->gtt_offset); + min_t(size_t, obj->gtt_space->size, + dev_priv->mm.gtt_mappable_end - obj->gtt_offset); } } static void i915_gem_info_remove_gtt(struct drm_i915_private *dev_priv, - struct drm_gem_object *obj) + struct drm_i915_gem_object *obj) { - struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); dev_priv->mm.gtt_count--; - dev_priv->mm.gtt_memory -= obj->size; - if (obj_priv->gtt_offset < dev_priv->mm.gtt_mappable_end) { + dev_priv->mm.gtt_memory -= obj->gtt_space->size; + if (obj->gtt_offset < dev_priv->mm.gtt_mappable_end) { dev_priv->mm.mappable_gtt_used -= - min_t(size_t, obj->size, - dev_priv->mm.gtt_mappable_end - - obj_priv->gtt_offset); + min_t(size_t, obj->gtt_space->size, + dev_priv->mm.gtt_mappable_end - obj->gtt_offset); } } @@ -113,47 +112,43 @@ static void i915_gem_info_remove_gtt(struct drm_i915_private *dev_priv, */ static void i915_gem_info_update_mappable(struct drm_i915_private *dev_priv, - struct drm_gem_object *obj, + struct drm_i915_gem_object *obj, bool mappable) { - struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); - if (mappable) { - if (obj_priv->pin_mappable && obj_priv->fault_mappable) + if (obj->pin_mappable && obj->fault_mappable) /* Combined state was already mappable. */ return; dev_priv->mm.gtt_mappable_count++; - dev_priv->mm.gtt_mappable_memory += obj->size; + dev_priv->mm.gtt_mappable_memory += obj->gtt_space->size; } else { - if (obj_priv->pin_mappable || obj_priv->fault_mappable) + if (obj->pin_mappable || obj->fault_mappable) /* Combined state still mappable. */ return; dev_priv->mm.gtt_mappable_count--; - dev_priv->mm.gtt_mappable_memory -= obj->size; + dev_priv->mm.gtt_mappable_memory -= obj->gtt_space->size; } } static void i915_gem_info_add_pin(struct drm_i915_private *dev_priv, - struct drm_gem_object *obj, + struct drm_i915_gem_object *obj, bool mappable) { - struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); dev_priv->mm.pin_count++; - dev_priv->mm.pin_memory += obj->size; + dev_priv->mm.pin_memory += obj->gtt_space->size; if (mappable) { - obj_priv->pin_mappable = true; + obj->pin_mappable = true; i915_gem_info_update_mappable(dev_priv, obj, true); } } static void i915_gem_info_remove_pin(struct drm_i915_private *dev_priv, - struct drm_gem_object *obj) + struct drm_i915_gem_object *obj) { - struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); dev_priv->mm.pin_count--; - dev_priv->mm.pin_memory -= obj->size; - if (obj_priv->pin_mappable) { - obj_priv->pin_mappable = false; + dev_priv->mm.pin_memory -= obj->gtt_space->size; + if (obj->pin_mappable) { + obj->pin_mappable = false; i915_gem_info_update_mappable(dev_priv, obj, false); } } @@ -309,16 +304,6 @@ i915_gem_create_ioctl(struct drm_device *dev, void *data, return 0; } -static bool -i915_gem_object_cpu_accessible(struct drm_i915_gem_object *obj) -{ - struct drm_device *dev = obj->base.dev; - drm_i915_private_t *dev_priv = dev->dev_private; - - return obj->gtt_space == NULL || - obj->gtt_offset + obj->base.size <= dev_priv->mm.gtt_mappable_end; -} - static int i915_gem_object_needs_bit17_swizzle(struct drm_gem_object *obj) { drm_i915_private_t *dev_priv = obj->dev->dev_private; @@ -1083,7 +1068,7 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data, else if (obj_priv->tiling_mode == I915_TILING_NONE && obj_priv->gtt_space && obj->write_domain != I915_GEM_DOMAIN_CPU) { - ret = i915_gem_object_pin(obj, 0, true); + ret = i915_gem_object_pin(obj, 0, true, false); if (ret) goto out; @@ -1307,11 +1292,19 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) /* Now bind it into the GTT if needed */ mutex_lock(&dev->struct_mutex); BUG_ON(obj_priv->pin_count && !obj_priv->pin_mappable); - if (!i915_gem_object_cpu_accessible(obj_priv)) - i915_gem_object_unbind(obj); + + if (obj_priv->gtt_space) { + if (!obj_priv->mappable || + (obj_priv->tiling_mode && !obj_priv->fenceable)) { + ret = i915_gem_object_unbind(obj); + if (ret) + goto unlock; + } + } if (!obj_priv->gtt_space) { - ret = i915_gem_object_bind_to_gtt(obj, 0, true); + ret = i915_gem_object_bind_to_gtt(obj, 0, + true, obj_priv->tiling_mode); if (ret) goto unlock; } @@ -1322,7 +1315,7 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) if (!obj_priv->fault_mappable) { obj_priv->fault_mappable = true; - i915_gem_info_update_mappable(dev_priv, obj, true); + i915_gem_info_update_mappable(dev_priv, obj_priv, true); } /* Need a new fence register? */ @@ -1448,7 +1441,7 @@ i915_gem_release_mmap(struct drm_gem_object *obj) if (obj_priv->fault_mappable) { obj_priv->fault_mappable = false; - i915_gem_info_update_mappable(dev_priv, obj, false); + i915_gem_info_update_mappable(dev_priv, obj_priv, false); } } @@ -1473,32 +1466,51 @@ i915_gem_free_mmap_offset(struct drm_gem_object *obj) * potential fence register mapping if needed. */ static uint32_t -i915_gem_get_gtt_alignment(struct drm_gem_object *obj) +i915_gem_get_gtt_alignment(struct drm_i915_gem_object *obj_priv) { - struct drm_device *dev = obj->dev; - struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); - int start, i; + struct drm_device *dev = obj_priv->base.dev; /* * Minimum alignment is 4k (GTT page size), but might be greater * if a fence register is needed for the object. */ - if (INTEL_INFO(dev)->gen >= 4 || obj_priv->tiling_mode == I915_TILING_NONE) + if (INTEL_INFO(dev)->gen >= 4 || + obj_priv->tiling_mode == I915_TILING_NONE) return 4096; + /* + * Previous chips need to be aligned to the size of the smallest + * fence register that can contain the object. + */ + return i915_gem_get_gtt_size(obj_priv); +} + +static uint32_t +i915_gem_get_gtt_size(struct drm_i915_gem_object *obj_priv) +{ + struct drm_device *dev = obj_priv->base.dev; + uint32_t size; + + /* + * Minimum alignment is 4k (GTT page size), but might be greater + * if a fence register is needed for the object. + */ + if (INTEL_INFO(dev)->gen >= 4) + return obj_priv->base.size; + /* * Previous chips need to be aligned to the size of the smallest * fence register that can contain the object. */ if (INTEL_INFO(dev)->gen == 3) - start = 1024*1024; + size = 1024*1024; else - start = 512*1024; + size = 512*1024; - for (i = start; i < obj->size; i <<= 1) - ; + while (size < obj_priv->base.size) + size <<= 1; - return i; + return size; } /** @@ -2253,8 +2265,10 @@ i915_gem_object_unbind(struct drm_gem_object *obj) i915_gem_object_put_pages_gtt(obj); - i915_gem_info_remove_gtt(dev_priv, obj); + i915_gem_info_remove_gtt(dev_priv, obj_priv); list_del_init(&obj_priv->mm_list); + obj_priv->fenceable = true; + obj_priv->mappable = true; drm_mm_put_block(obj_priv->gtt_space); obj_priv->gtt_space = NULL; @@ -2311,16 +2325,16 @@ i915_gpu_idle(struct drm_device *dev) return 0; } -static void sandybridge_write_fence_reg(struct drm_i915_fence_reg *reg) +static void sandybridge_write_fence_reg(struct drm_gem_object *obj) { - struct drm_gem_object *obj = reg->obj; struct drm_device *dev = obj->dev; drm_i915_private_t *dev_priv = dev->dev_private; struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); + u32 size = i915_gem_get_gtt_size(obj_priv); int regnum = obj_priv->fence_reg; uint64_t val; - val = (uint64_t)((obj_priv->gtt_offset + obj->size - 4096) & + val = (uint64_t)((obj_priv->gtt_offset + size - 4096) & 0xfffff000) << 32; val |= obj_priv->gtt_offset & 0xfffff000; val |= (uint64_t)((obj_priv->stride / 128) - 1) << @@ -2333,16 +2347,16 @@ static void sandybridge_write_fence_reg(struct drm_i915_fence_reg *reg) I915_WRITE64(FENCE_REG_SANDYBRIDGE_0 + (regnum * 8), val); } -static void i965_write_fence_reg(struct drm_i915_fence_reg *reg) +static void i965_write_fence_reg(struct drm_gem_object *obj) { - struct drm_gem_object *obj = reg->obj; struct drm_device *dev = obj->dev; drm_i915_private_t *dev_priv = dev->dev_private; struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); + u32 size = i915_gem_get_gtt_size(obj_priv); int regnum = obj_priv->fence_reg; uint64_t val; - val = (uint64_t)((obj_priv->gtt_offset + obj->size - 4096) & + val = (uint64_t)((obj_priv->gtt_offset + size - 4096) & 0xfffff000) << 32; val |= obj_priv->gtt_offset & 0xfffff000; val |= ((obj_priv->stride / 128) - 1) << I965_FENCE_PITCH_SHIFT; @@ -2353,21 +2367,20 @@ static void i965_write_fence_reg(struct drm_i915_fence_reg *reg) I915_WRITE64(FENCE_REG_965_0 + (regnum * 8), val); } -static void i915_write_fence_reg(struct drm_i915_fence_reg *reg) +static void i915_write_fence_reg(struct drm_gem_object *obj) { - struct drm_gem_object *obj = reg->obj; struct drm_device *dev = obj->dev; drm_i915_private_t *dev_priv = dev->dev_private; struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); - int regnum = obj_priv->fence_reg; + u32 size = i915_gem_get_gtt_size(obj_priv); + uint32_t fence_reg, val, pitch_val; int tile_width; - uint32_t fence_reg, val; - uint32_t pitch_val; if ((obj_priv->gtt_offset & ~I915_FENCE_START_MASK) || - (obj_priv->gtt_offset & (obj->size - 1))) { - WARN(1, "%s: object 0x%08x not 1M or size (0x%zx) aligned\n", - __func__, obj_priv->gtt_offset, obj->size); + (obj_priv->gtt_offset & (size - 1))) { + WARN(1, "%s: object 0x%08x [fenceable? %d] not 1M or size (0x%08x) aligned [gtt_space offset=%lx, size=%lx]\n", + __func__, obj_priv->gtt_offset, obj_priv->fenceable, size, + obj_priv->gtt_space->start, obj_priv->gtt_space->size); return; } @@ -2390,23 +2403,24 @@ static void i915_write_fence_reg(struct drm_i915_fence_reg *reg) val = obj_priv->gtt_offset; if (obj_priv->tiling_mode == I915_TILING_Y) val |= 1 << I830_FENCE_TILING_Y_SHIFT; - val |= I915_FENCE_SIZE_BITS(obj->size); + val |= I915_FENCE_SIZE_BITS(size); val |= pitch_val << I830_FENCE_PITCH_SHIFT; val |= I830_FENCE_REG_VALID; - if (regnum < 8) - fence_reg = FENCE_REG_830_0 + (regnum * 4); + fence_reg = obj_priv->fence_reg; + if (fence_reg < 8) + fence_reg = FENCE_REG_830_0 + fence_reg * 4; else - fence_reg = FENCE_REG_945_8 + ((regnum - 8) * 4); + fence_reg = FENCE_REG_945_8 + (fence_reg - 8) * 4; I915_WRITE(fence_reg, val); } -static void i830_write_fence_reg(struct drm_i915_fence_reg *reg) +static void i830_write_fence_reg(struct drm_gem_object *obj) { - struct drm_gem_object *obj = reg->obj; struct drm_device *dev = obj->dev; drm_i915_private_t *dev_priv = dev->dev_private; struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); + u32 size = i915_gem_get_gtt_size(obj_priv); int regnum = obj_priv->fence_reg; uint32_t val; uint32_t pitch_val; @@ -2426,7 +2440,7 @@ static void i830_write_fence_reg(struct drm_i915_fence_reg *reg) val = obj_priv->gtt_offset; if (obj_priv->tiling_mode == I915_TILING_Y) val |= 1 << I830_FENCE_TILING_Y_SHIFT; - fence_size_bits = I830_FENCE_SIZE_BITS(obj->size); + fence_size_bits = I830_FENCE_SIZE_BITS(size); WARN_ON(fence_size_bits & ~0x00000f00); val |= fence_size_bits; val |= pitch_val << I830_FENCE_PITCH_SHIFT; @@ -2438,10 +2452,9 @@ static void i830_write_fence_reg(struct drm_i915_fence_reg *reg) static int i915_find_fence_reg(struct drm_device *dev, bool interruptible) { - struct drm_i915_fence_reg *reg = NULL; - struct drm_i915_gem_object *obj_priv = NULL; struct drm_i915_private *dev_priv = dev->dev_private; - struct drm_gem_object *obj = NULL; + struct drm_i915_fence_reg *reg; + struct drm_i915_gem_object *obj_priv = NULL; int i, avail, ret; /* First try to find a free reg */ @@ -2460,33 +2473,31 @@ static int i915_find_fence_reg(struct drm_device *dev, return -ENOSPC; /* None available, try to steal one or wait for a user to finish */ - i = I915_FENCE_REG_NONE; + avail = I915_FENCE_REG_NONE; list_for_each_entry(reg, &dev_priv->mm.fence_list, lru_list) { - obj = reg->obj; - obj_priv = to_intel_bo(obj); - + obj_priv = to_intel_bo(reg->obj); if (obj_priv->pin_count) continue; /* found one! */ - i = obj_priv->fence_reg; + avail = obj_priv->fence_reg; break; } - BUG_ON(i == I915_FENCE_REG_NONE); + BUG_ON(avail == I915_FENCE_REG_NONE); /* We only have a reference on obj from the active list. put_fence_reg * might drop that one, causing a use-after-free in it. So hold a * private reference to obj like the other callers of put_fence_reg * (set_tiling ioctl) do. */ - drm_gem_object_reference(obj); - ret = i915_gem_object_put_fence_reg(obj, interruptible); - drm_gem_object_unreference(obj); + drm_gem_object_reference(&obj_priv->base); + ret = i915_gem_object_put_fence_reg(&obj_priv->base, interruptible); + drm_gem_object_unreference(&obj_priv->base); if (ret != 0) return ret; - return i; + return avail; } /** @@ -2551,22 +2562,23 @@ i915_gem_object_get_fence_reg(struct drm_gem_object *obj, switch (INTEL_INFO(dev)->gen) { case 6: - sandybridge_write_fence_reg(reg); + sandybridge_write_fence_reg(obj); break; case 5: case 4: - i965_write_fence_reg(reg); + i965_write_fence_reg(obj); break; case 3: - i915_write_fence_reg(reg); + i915_write_fence_reg(obj); break; case 2: - i830_write_fence_reg(reg); + i830_write_fence_reg(obj); break; } - trace_i915_gem_object_get_fence(obj, obj_priv->fence_reg, - obj_priv->tiling_mode); + trace_i915_gem_object_get_fence(obj, + obj_priv->fence_reg, + obj_priv->tiling_mode); return 0; } @@ -2671,13 +2683,15 @@ i915_gem_object_put_fence_reg(struct drm_gem_object *obj, static int i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment, - bool mappable) + bool mappable, + bool need_fence) { struct drm_device *dev = obj->dev; drm_i915_private_t *dev_priv = dev->dev_private; struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); struct drm_mm_node *free_space; - gfp_t gfpmask = __GFP_NORETRY | __GFP_NOWARN; + gfp_t gfpmask = __GFP_NORETRY | __GFP_NOWARN; + u32 size, fence_size, fence_alignment; int ret; if (obj_priv->madv != I915_MADV_WILLNEED) { @@ -2685,13 +2699,18 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, return -EINVAL; } + fence_size = i915_gem_get_gtt_size(obj_priv); + fence_alignment = i915_gem_get_gtt_alignment(obj_priv); + if (alignment == 0) - alignment = i915_gem_get_gtt_alignment(obj); - if (alignment & (i915_gem_get_gtt_alignment(obj) - 1)) { + alignment = need_fence ? fence_alignment : 4096; + if (need_fence && alignment & (fence_alignment - 1)) { DRM_ERROR("Invalid object alignment requested %u\n", alignment); return -EINVAL; } + size = need_fence ? fence_size : obj->size; + /* If the object is bigger than the entire aperture, reject it early * before evicting everything in a vain attempt to find space. */ @@ -2705,32 +2724,29 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, if (mappable) free_space = drm_mm_search_free_in_range(&dev_priv->mm.gtt_space, - obj->size, alignment, 0, + size, alignment, 0, dev_priv->mm.gtt_mappable_end, 0); else free_space = drm_mm_search_free(&dev_priv->mm.gtt_space, - obj->size, alignment, 0); + size, alignment, 0); if (free_space != NULL) { if (mappable) obj_priv->gtt_space = drm_mm_get_block_range_generic(free_space, - obj->size, - alignment, 0, + size, alignment, 0, dev_priv->mm.gtt_mappable_end, 0); else obj_priv->gtt_space = - drm_mm_get_block(free_space, obj->size, - alignment); + drm_mm_get_block(free_space, size, alignment); } if (obj_priv->gtt_space == NULL) { /* If the gtt is empty and we're still having trouble * fitting our object in, we're out of memory. */ - ret = i915_gem_evict_something(dev, obj->size, alignment, - mappable); + ret = i915_gem_evict_something(dev, size, alignment, mappable); if (ret) return ret; @@ -2744,7 +2760,7 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, if (ret == -ENOMEM) { /* first try to clear up some space from the GTT */ - ret = i915_gem_evict_something(dev, obj->size, + ret = i915_gem_evict_something(dev, size, alignment, mappable); if (ret) { /* now try to shrink everyone else */ @@ -2775,8 +2791,8 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, drm_mm_put_block(obj_priv->gtt_space); obj_priv->gtt_space = NULL; - ret = i915_gem_evict_something(dev, obj->size, alignment, - mappable); + ret = i915_gem_evict_something(dev, size, + alignment, mappable); if (ret) return ret; @@ -2787,7 +2803,7 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, /* keep track of bounds object by adding it to the inactive list */ list_add_tail(&obj_priv->mm_list, &dev_priv->mm.inactive_list); - i915_gem_info_add_gtt(dev_priv, obj); + i915_gem_info_add_gtt(dev_priv, obj_priv); /* Assert that the object is not currently in any GPU domain. As it * wasn't in the GTT, there shouldn't be any way it could have been in @@ -2798,6 +2814,13 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, trace_i915_gem_object_bind(obj, obj_priv->gtt_offset, mappable); + obj_priv->fenceable = + obj_priv->gtt_space->size == fence_size && + (obj_priv->gtt_space->start & (fence_alignment -1)) == 0; + + obj_priv->mappable = + obj_priv->gtt_offset + obj->size <= dev_priv->mm.gtt_mappable_end; + return 0; } @@ -3516,9 +3539,8 @@ i915_gem_execbuffer_pin(struct drm_device *dev, entry->relocation_count ? true : need_fence; /* Check fence reg constraints and rebind if necessary */ - if (need_fence && - !i915_gem_object_fence_offset_ok(&obj->base, - obj->tiling_mode)) { + if ((need_fence && !obj->fenceable) || + (need_mappable && !obj->mappable)) { ret = i915_gem_object_unbind(&obj->base); if (ret) break; @@ -3526,7 +3548,8 @@ i915_gem_execbuffer_pin(struct drm_device *dev, ret = i915_gem_object_pin(&obj->base, entry->alignment, - need_mappable); + need_mappable, + need_fence); if (ret) break; @@ -4097,7 +4120,7 @@ i915_gem_execbuffer2(struct drm_device *dev, void *data, int i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment, - bool mappable) + bool mappable, bool need_fence) { struct drm_device *dev = obj->dev; struct drm_i915_private *dev_priv = dev->dev_private; @@ -4108,14 +4131,15 @@ i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment, WARN_ON(i915_verify_lists(dev)); if (obj_priv->gtt_space != NULL) { - if (alignment == 0) - alignment = i915_gem_get_gtt_alignment(obj); - if (obj_priv->gtt_offset & (alignment - 1) || - (mappable && !i915_gem_object_cpu_accessible(obj_priv))) { + if ((alignment && obj_priv->gtt_offset & (alignment - 1)) || + (need_fence && !obj_priv->fenceable) || + (mappable && !obj_priv->mappable)) { WARN(obj_priv->pin_count, "bo is already pinned with incorrect alignment:" - " offset=%x, req.alignment=%x\n", - obj_priv->gtt_offset, alignment); + " offset=%x, req.alignment=%x, need_fence=%d, fenceable=%d, mappable=%d, cpu_accessible=%d\n", + obj_priv->gtt_offset, alignment, + need_fence, obj_priv->fenceable, + mappable, obj_priv->mappable); ret = i915_gem_object_unbind(obj); if (ret) return ret; @@ -4123,13 +4147,14 @@ i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment, } if (obj_priv->gtt_space == NULL) { - ret = i915_gem_object_bind_to_gtt(obj, alignment, mappable); + ret = i915_gem_object_bind_to_gtt(obj, alignment, + mappable, need_fence); if (ret) return ret; } if (obj_priv->pin_count++ == 0) { - i915_gem_info_add_pin(dev_priv, obj, mappable); + i915_gem_info_add_pin(dev_priv, obj_priv, mappable); if (!obj_priv->active) list_move_tail(&obj_priv->mm_list, &dev_priv->mm.pinned_list); @@ -4155,7 +4180,7 @@ i915_gem_object_unpin(struct drm_gem_object *obj) if (!obj_priv->active) list_move_tail(&obj_priv->mm_list, &dev_priv->mm.inactive_list); - i915_gem_info_remove_pin(dev_priv, obj); + i915_gem_info_remove_pin(dev_priv, obj_priv); } WARN_ON(i915_verify_lists(dev)); } @@ -4196,7 +4221,8 @@ i915_gem_pin_ioctl(struct drm_device *dev, void *data, obj_priv->user_pin_count++; obj_priv->pin_filp = file_priv; if (obj_priv->user_pin_count == 1) { - ret = i915_gem_object_pin(obj, args->alignment, true); + ret = i915_gem_object_pin(obj, args->alignment, + true, obj_priv->tiling_mode); if (ret) goto out; } @@ -4389,6 +4415,8 @@ struct drm_gem_object * i915_gem_alloc_object(struct drm_device *dev, INIT_LIST_HEAD(&obj->ring_list); INIT_LIST_HEAD(&obj->gpu_write_list); obj->madv = I915_MADV_WILLNEED; + obj->fenceable = true; + obj->mappable = true; return &obj->base; } @@ -4508,7 +4536,7 @@ i915_gem_init_pipe_control(struct drm_device *dev) obj_priv = to_intel_bo(obj); obj_priv->agp_type = AGP_USER_CACHED_MEMORY; - ret = i915_gem_object_pin(obj, 4096, true); + ret = i915_gem_object_pin(obj, 4096, true, false); if (ret) goto err_unref; diff --git a/drivers/gpu/drm/i915/i915_gem_tiling.c b/drivers/gpu/drm/i915/i915_gem_tiling.c index af352de70be1..0597a737ebad 100644 --- a/drivers/gpu/drm/i915/i915_gem_tiling.c +++ b/drivers/gpu/drm/i915/i915_gem_tiling.c @@ -181,7 +181,7 @@ i915_gem_detect_bit_6_swizzle(struct drm_device *dev) } /* Check pitch constriants for all chips & tiling formats */ -bool +static bool i915_tiling_ok(struct drm_device *dev, int stride, int size, int tiling_mode) { int tile_width; @@ -232,25 +232,35 @@ i915_tiling_ok(struct drm_device *dev, int stride, int size, int tiling_mode) return true; } -bool -i915_gem_object_fence_offset_ok(struct drm_gem_object *obj, int tiling_mode) +/* Is the current GTT allocation valid for the change in tiling? */ +static bool +i915_gem_object_fence_ok(struct drm_gem_object *obj, int tiling_mode) { - struct drm_device *dev = obj->dev; struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); - - if (obj_priv->gtt_space == NULL) - return true; + u32 size; if (tiling_mode == I915_TILING_NONE) return true; - if (INTEL_INFO(dev)->gen >= 4) + if (INTEL_INFO(obj->dev)->gen >= 4) return true; - if (obj_priv->gtt_offset & (obj->size - 1)) + /* + * Previous chips need to be aligned to the size of the smallest + * fence register that can contain the object. + */ + if (INTEL_INFO(obj->dev)->gen == 3) + size = 1024*1024; + else + size = 512*1024; + + while (size < obj_priv->base.size) + size <<= 1; + + if (obj_priv->gtt_offset & (size - 1)) return false; - if (IS_GEN3(dev)) { + if (INTEL_INFO(obj->dev)->gen == 3) { if (obj_priv->gtt_offset & ~I915_FENCE_START_MASK) return false; } else { @@ -331,7 +341,7 @@ i915_gem_set_tiling(struct drm_device *dev, void *data, * tiling mode. Otherwise we can just leave it alone, but * need to ensure that any fence register is cleared. */ - if (!i915_gem_object_fence_offset_ok(obj, args->tiling_mode)) + if (!i915_gem_object_fence_ok(obj, args->tiling_mode)) ret = i915_gem_object_unbind(obj); else if (obj_priv->fence_reg != I915_FENCE_REG_NONE) ret = i915_gem_object_put_fence_reg(obj, true); diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index c9c4c707cf1a..4954af23b7c8 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -1461,7 +1461,8 @@ intel_pin_and_fence_fb_obj(struct drm_device *dev, BUG(); } - ret = i915_gem_object_pin(obj, alignment, true); + ret = i915_gem_object_pin(obj, alignment, + !pipelined, obj_priv->tiling_mode); if (ret) return ret; @@ -4353,7 +4354,7 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc, /* we only need to pin inside GTT if cursor is non-phy */ mutex_lock(&dev->struct_mutex); if (!dev_priv->info->cursor_needs_physical) { - ret = i915_gem_object_pin(bo, PAGE_SIZE, true); + ret = i915_gem_object_pin(bo, PAGE_SIZE, true, false); if (ret) { DRM_ERROR("failed to pin cursor bo\n"); goto fail_locked; @@ -5517,7 +5518,7 @@ intel_alloc_context_page(struct drm_device *dev) } mutex_lock(&dev->struct_mutex); - ret = i915_gem_object_pin(ctx, 4096, true); + ret = i915_gem_object_pin(ctx, 4096, false, false); if (ret) { DRM_ERROR("failed to pin power context: %d\n", ret); goto err_unref; diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c index beda2016eb16..e62e1b3d243f 100644 --- a/drivers/gpu/drm/i915/intel_overlay.c +++ b/drivers/gpu/drm/i915/intel_overlay.c @@ -781,7 +781,7 @@ static int intel_overlay_do_put_image(struct intel_overlay *overlay, if (ret != 0) return ret; - ret = i915_gem_object_pin(new_bo, PAGE_SIZE, true); + ret = i915_gem_object_pin(new_bo, PAGE_SIZE, false, false); if (ret != 0) return ret; @@ -1423,7 +1423,7 @@ void intel_setup_overlay(struct drm_device *dev) } overlay->flip_addr = overlay->reg_bo->phys_obj->handle->busaddr; } else { - ret = i915_gem_object_pin(reg_bo, PAGE_SIZE, true); + ret = i915_gem_object_pin(reg_bo, PAGE_SIZE, true, false); if (ret) { DRM_ERROR("failed to pin overlay register bo\n"); goto out_free_bo; diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index e88214ef24b1..632a98e0ba5c 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -547,7 +547,7 @@ static int init_status_page(struct intel_ring_buffer *ring) obj_priv = to_intel_bo(obj); obj_priv->agp_type = AGP_USER_CACHED_MEMORY; - ret = i915_gem_object_pin(obj, 4096, true); + ret = i915_gem_object_pin(obj, 4096, true, false); if (ret != 0) { goto err_unref; } @@ -603,7 +603,7 @@ int intel_init_ring_buffer(struct drm_device *dev, ring->gem_object = obj; - ret = i915_gem_object_pin(obj, PAGE_SIZE, true); + ret = i915_gem_object_pin(obj, PAGE_SIZE, true, false); if (ret) goto err_unref; diff --git a/include/drm/i915_drm.h b/include/drm/i915_drm.h index 8c641bed9bbd..b20dbb2d7174 100644 --- a/include/drm/i915_drm.h +++ b/include/drm/i915_drm.h @@ -287,6 +287,7 @@ typedef struct drm_i915_irq_wait { #define I915_PARAM_HAS_EXECBUF2 9 #define I915_PARAM_HAS_BSD 10 #define I915_PARAM_HAS_BLT 11 +#define I915_PARAM_HAS_RELAXED_FENCING 12 typedef struct drm_i915_getparam { int param; -- cgit v1.2.3 From 872d860c85e30cdc97e7c91723257f4fcf04d5e9 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 28 Oct 2010 23:43:30 +0100 Subject: drm/i915: Remove the duplicate domain-change tracepoint for GPU flush Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_gem.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 07ad1e354084..936ddd83f8a2 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -2847,22 +2847,16 @@ i915_gem_object_flush_gpu_write_domain(struct drm_gem_object *obj, bool pipelined) { struct drm_device *dev = obj->dev; - uint32_t old_write_domain; if ((obj->write_domain & I915_GEM_GPU_DOMAINS) == 0) return 0; /* Queue the GPU write cache flushing we need. */ - old_write_domain = obj->write_domain; i915_gem_flush_ring(dev, NULL, to_intel_bo(obj)->ring, 0, obj->write_domain); BUG_ON(obj->write_domain); - trace_i915_gem_object_change_domain(obj, - obj->read_domains, - old_write_domain); - if (pipelined) return 0; -- cgit v1.2.3 From 33626e6a08669b1a5834e76363dcd5c8733a4278 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 29 Oct 2010 16:18:36 +0100 Subject: drm/i915/ringbuffer: Disable the ringbuffer on cleanup. It should be idle on cleanup anyway... Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/intel_ringbuffer.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 632a98e0ba5c..0f1693981ee6 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -651,9 +651,17 @@ err_hws: void intel_cleanup_ring_buffer(struct intel_ring_buffer *ring) { + struct drm_i915_private *dev_priv; + int ret; + if (ring->gem_object == NULL) return; + /* Disable the ring buffer. The ring must be idle at this point */ + dev_priv = ring->dev->dev_private; + ret = intel_wait_ring_buffer(ring, ring->size - 8); + I915_WRITE_CTL(ring, 0); + drm_core_ioremapfree(&ring->map, ring->dev); i915_gem_object_unpin(ring->gem_object); -- cgit v1.2.3 From 1d8f38f4e7146d22f7fbc94eef0508bd75463f54 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 29 Oct 2010 19:00:51 +0100 Subject: drm/i915: Record BLT engine error state Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_debugfs.c | 19 +++++++++++++------ drivers/gpu/drm/i915/i915_drv.h | 7 ++++++- drivers/gpu/drm/i915/i915_irq.c | 7 +++++++ drivers/gpu/drm/i915/i915_reg.h | 4 ++++ 4 files changed, 30 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index ba2af4e046ed..70eec5aceabe 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -616,21 +616,28 @@ static int i915_error_state(struct seq_file *m, void *unused) seq_printf(m, "Time: %ld s %ld us\n", error->time.tv_sec, error->time.tv_usec); seq_printf(m, "PCI ID: 0x%04x\n", dev->pci_device); + seq_printf(m, "EIR: 0x%08x\n", error->eir); + seq_printf(m, "PGTBL_ER: 0x%08x\n", error->pgtbl_er); if (INTEL_INFO(dev)->gen >= 6) { seq_printf(m, "ERROR: 0x%08x\n", error->error); + seq_printf(m, "Blitter command stream:\n"); + seq_printf(m, " ACTHD: 0x%08x\n", error->bcs_acthd); + seq_printf(m, " IPEHR: 0x%08x\n", error->bcs_ipehr); + seq_printf(m, " IPEIR: 0x%08x\n", error->bcs_ipeir); + seq_printf(m, " INSTDONE: 0x%08x\n", error->bcs_instdone); + seq_printf(m, " seqno: 0x%08x\n", error->bcs_seqno); } - seq_printf(m, "EIR: 0x%08x\n", error->eir); - seq_printf(m, " PGTBL_ER: 0x%08x\n", error->pgtbl_er); - seq_printf(m, " INSTPM: 0x%08x\n", error->instpm); + seq_printf(m, "Render command stream:\n"); + seq_printf(m, " ACTHD: 0x%08x\n", error->acthd); seq_printf(m, " IPEIR: 0x%08x\n", error->ipeir); seq_printf(m, " IPEHR: 0x%08x\n", error->ipehr); seq_printf(m, " INSTDONE: 0x%08x\n", error->instdone); - seq_printf(m, " ACTHD: 0x%08x\n", error->acthd); if (INTEL_INFO(dev)->gen >= 4) { - seq_printf(m, " INSTPS: 0x%08x\n", error->instps); seq_printf(m, " INSTDONE1: 0x%08x\n", error->instdone1); + seq_printf(m, " INSTPS: 0x%08x\n", error->instps); } - seq_printf(m, "seqno: 0x%08x\n", error->seqno); + seq_printf(m, " INSTPM: 0x%08x\n", error->instpm); + seq_printf(m, " seqno: 0x%08x\n", error->seqno); if (error->active_bo_count) { seq_printf(m, "Buffers [%d]:\n", error->active_bo_count); diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 7aa7f8abf892..05bff9e6a9cb 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -142,13 +142,18 @@ struct sdvo_device_mapping { struct drm_i915_error_state { u32 eir; u32 pgtbl_er; - u32 error; /* gen6+ */ u32 pipeastat; u32 pipebstat; u32 ipeir; u32 ipehr; u32 instdone; u32 acthd; + u32 error; /* gen6+ */ + u32 bcs_acthd; /* gen6+ blt engine */ + u32 bcs_ipehr; + u32 bcs_ipeir; + u32 bcs_instdone; + u32 bcs_seqno; u32 instpm; u32 instps; u32 instdone1; diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 2a29497a4694..4ff39dee7f1c 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -595,6 +595,13 @@ static void i915_capture_error_state(struct drm_device *dev) error->error = 0; if (INTEL_INFO(dev)->gen >= 6) { error->error = I915_READ(ERROR_GEN6); + error->bcs_acthd = I915_READ(BCS_ACTHD); + error->bcs_ipehr = I915_READ(BCS_IPEHR); + error->bcs_ipeir = I915_READ(BCS_IPEIR); + error->bcs_instdone = I915_READ(BCS_INSTDONE); + error->bcs_seqno = 0; + if (dev_priv->blt_ring.get_seqno) + error->bcs_seqno = dev_priv->blt_ring.get_seqno(&dev_priv->blt_ring); } if (INTEL_INFO(dev)->gen >= 4) { error->ipeir = I915_READ(IPEIR_I965); diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index fc161196da21..b173e5b77f96 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -305,6 +305,10 @@ #define INSTDONE 0x02090 #define NOPID 0x02094 #define HWSTAM 0x02098 +#define BCS_INSTDONE 0x2206C +#define BCS_IPEIR 0x22064 +#define BCS_IPEHR 0x22068 +#define BCS_ACTHD 0x22074 #define ERROR_GEN6 0x040a0 -- cgit v1.2.3 From c584fe47e4d92934c10e5d7f932ee042587dbcff Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 29 Oct 2010 18:15:52 +0100 Subject: drm/i915/ringbuffer: Remove duplicate initialisation of ring control Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/intel_ringbuffer.c | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 0f1693981ee6..4d00da97905f 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -578,7 +578,6 @@ err: int intel_init_ring_buffer(struct drm_device *dev, struct intel_ring_buffer *ring) { - struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_gem_object *obj_priv; struct drm_gem_object *obj; int ret; @@ -626,16 +625,7 @@ int intel_init_ring_buffer(struct drm_device *dev, if (ret) goto err_unmap; - if (!drm_core_check_feature(dev, DRIVER_MODESET)) - i915_kernel_lost_context(dev); - else { - ring->head = I915_READ_HEAD(ring) & HEAD_ADDR; - ring->tail = I915_READ_TAIL(ring) & TAIL_ADDR; - ring->space = ring->head - (ring->tail + 8); - if (ring->space < 0) - ring->space += ring->size; - } - return ret; + return 0; err_unmap: drm_core_ioremapfree(&ring->map, dev); -- cgit v1.2.3 From e380f60b22eddec7825224b8d788572c82b63161 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 29 Oct 2010 18:11:26 +0100 Subject: agp/intel: Sandybridge doesn't require GMCH enabling Signed-off-by: Chris Wilson --- drivers/char/agp/intel-gtt.c | 37 ++++++++++++++++++++++++++++++------- 1 file changed, 30 insertions(+), 7 deletions(-) diff --git a/drivers/char/agp/intel-gtt.c b/drivers/char/agp/intel-gtt.c index 5dc1f5db55a7..9c86dac41da7 100644 --- a/drivers/char/agp/intel-gtt.c +++ b/drivers/char/agp/intel-gtt.c @@ -922,10 +922,11 @@ static void i830_write_entry(dma_addr_t addr, unsigned int entry, writel(addr | pte_flags, intel_private.gtt + entry); } -static void intel_enable_gtt(void) +static bool intel_enable_gtt(void) { u32 gma_addr; u16 gmch_ctrl; + u8 __iomem *reg; if (INTEL_GTT_GEN == 2) pci_read_config_dword(intel_private.pcidev, I810_GMADDR, @@ -936,13 +937,34 @@ static void intel_enable_gtt(void) intel_private.gma_bus_addr = (gma_addr & PCI_BASE_ADDRESS_MEM_MASK); - pci_read_config_word(intel_private.bridge_dev, I830_GMCH_CTRL, &gmch_ctrl); + if (INTEL_GTT_GEN >= 6) + return true; + + pci_read_config_word(intel_private.bridge_dev, + I830_GMCH_CTRL, &gmch_ctrl); gmch_ctrl |= I830_GMCH_ENABLED; - pci_write_config_word(intel_private.bridge_dev, I830_GMCH_CTRL, gmch_ctrl); + pci_write_config_word(intel_private.bridge_dev, + I830_GMCH_CTRL, gmch_ctrl); - writel(intel_private.PGETBL_save|I810_PGETBL_ENABLED, - intel_private.registers+I810_PGETBL_CTL); - readl(intel_private.registers+I810_PGETBL_CTL); /* PCI Posting. */ + pci_read_config_word(intel_private.bridge_dev, + I830_GMCH_CTRL, &gmch_ctrl); + if ((gmch_ctrl & I830_GMCH_ENABLED) == 0) { + dev_err(&intel_private.pcidev->dev, + "failed to enable the GTT: GMCH_CTRL=%x\n", + gmch_ctrl); + return false; + } + + reg = intel_private.registers+I810_PGETBL_CTL; + writel(intel_private.PGETBL_save|I810_PGETBL_ENABLED, reg); + if ((readl(reg) & I810_PGETBL_ENABLED) == 0) { + dev_err(&intel_private.pcidev->dev, + "failed to enable the GTT: PGETBL=%x [expected %x|1]\n", + readl(reg), intel_private.PGETBL_save); + return false; + } + + return true; } static int i830_setup(void) @@ -981,7 +1003,8 @@ static int intel_fake_agp_configure(void) { int i; - intel_enable_gtt(); + if (!intel_enable_gtt()) + return -EIO; agp_bridge->gart_bus_addr = intel_private.gma_bus_addr; -- cgit v1.2.3 From 4066c0ae13a8388b9f2a29cad60da330b578eff2 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 29 Oct 2010 21:00:54 +0100 Subject: drm/i915/debugfs: Display the contents of the BLT and BSD status pages Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_debugfs.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 70eec5aceabe..58cf60d89f68 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -445,10 +445,18 @@ static int i915_hws_info(struct seq_file *m, void *data) struct drm_info_node *node = (struct drm_info_node *) m->private; struct drm_device *dev = node->minor->dev; drm_i915_private_t *dev_priv = dev->dev_private; - int i; + struct intel_ring_buffer *ring; volatile u32 *hws; + int i; + + switch ((uintptr_t)node->info_ent->data) { + case RENDER_RING: ring = &dev_priv->render_ring; break; + case BSD_RING: ring = &dev_priv->bsd_ring; break; + case BLT_RING: ring = &dev_priv->blt_ring; break; + default: return -EINVAL; + } - hws = (volatile u32 *)dev_priv->render_ring.status_page.page_addr; + hws = (volatile u32 *)ring->status_page.page_addr; if (hws == NULL) return 0; @@ -1087,7 +1095,9 @@ static struct drm_info_list i915_debugfs_list[] = { {"i915_gem_seqno", i915_gem_seqno_info, 0}, {"i915_gem_fence_regs", i915_gem_fence_regs_info, 0}, {"i915_gem_interrupt", i915_interrupt_info, 0}, - {"i915_gem_hws", i915_hws_info, 0}, + {"i915_gem_hws", i915_hws_info, 0, (void *)RENDER_RING}, + {"i915_gem_hws_blt", i915_hws_info, 0, (void *)BLT_RING}, + {"i915_gem_hws_bsd", i915_hws_info, 0, (void *)BSD_RING}, {"i915_ringbuffer_data", i915_ringbuffer_data, 0, (void *)RENDER_RING}, {"i915_ringbuffer_info", i915_ringbuffer_info, 0, (void *)RENDER_RING}, {"i915_bsd_ringbuffer_data", i915_ringbuffer_data, 0, (void *)BSD_RING}, -- cgit v1.2.3 From 6dda569fe0fb71a03e2a2e815761796f98232cdb Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 29 Oct 2010 21:02:18 +0100 Subject: drm/i915: Switch to using pci_iounmap in conjunction with pci_iomap After switching the MMIO registers to use pci_iomap, remember to dispose of the mapping with pci_iounmap (for symmetry). Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_dma.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 00d8fb3e989f..eee88cfcb3aa 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -2082,7 +2082,7 @@ out_workqueue_free: out_iomapfree: io_mapping_free(dev_priv->mm.gtt_mapping); out_rmmap: - iounmap(dev_priv->regs); + pci_iounmap(dev->pdev, dev_priv->regs); put_bridge: pci_dev_put(dev_priv->bridge_dev); free_priv: @@ -2168,7 +2168,7 @@ int i915_driver_unload(struct drm_device *dev) } if (dev_priv->regs != NULL) - iounmap(dev_priv->regs); + pci_iounmap(dev->pdev, dev_priv->regs); intel_teardown_gmbus(dev); intel_teardown_mchbar(dev); -- cgit v1.2.3 From f4e0b29bf23687ac16dc476bd90cd4d8b0eacd5c Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 29 Oct 2010 21:06:16 +0100 Subject: drm/i915: Check if the GPU hung whilst waiting for the ring to clear Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/intel_ringbuffer.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 4d00da97905f..2e72d3a0740f 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -711,6 +711,8 @@ int intel_wait_ring_buffer(struct intel_ring_buffer *ring, int n) } msleep(1); + if (atomic_read(&dev_priv->mm.wedged)) + return -EAGAIN; } while (!time_after(jiffies, end)); trace_i915_ring_wait_end (dev); return -EBUSY; -- cgit v1.2.3 From 6aa56062eaba67adfb247cded244fd877329588d Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 29 Oct 2010 21:44:37 +0100 Subject: drm/i915/ringbuffer: Use the HEAD auto-reporting mechanism My Sandybridge only reports 0 for the ring buffer registers, causing it to hang as soon as we exhaust the available ring. As a workaround, take advantage of our huge ring buffers and use the auto-reporting mechanism to update the status page with the HEAD location every 64 KiB. Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/intel_ringbuffer.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 2e72d3a0740f..390aa21edbe4 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -174,7 +174,7 @@ static int init_ring_common(struct intel_ring_buffer *ring) I915_WRITE_CTL(ring, ((ring->gem_object->size - PAGE_SIZE) & RING_NR_PAGES) - | RING_NO_REPORT | RING_VALID); + | RING_REPORT_64K | RING_VALID); /* If the head is still not zero, the ring is dead */ if ((I915_READ_CTL(ring) & RING_VALID) == 0 || @@ -691,6 +691,17 @@ int intel_wait_ring_buffer(struct intel_ring_buffer *ring, int n) struct drm_device *dev = ring->dev; drm_i915_private_t *dev_priv = dev->dev_private; unsigned long end; + u32 head; + + head = intel_read_status_page(ring, 4); + if (head) { + ring->head = head & HEAD_ADDR; + ring->space = ring->head - (ring->tail + 8); + if (ring->space < 0) + ring->space += ring->size; + if (ring->space >= n) + return 0; + } trace_i915_ring_wait_begin (dev); end = jiffies + 3 * HZ; -- cgit v1.2.3 From add354ddf62beac55ca3ba64835dd703a0649867 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 29 Oct 2010 19:00:51 +0100 Subject: drm/i915: Record BSD engine error state Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_debugfs.c | 6 ++++++ drivers/gpu/drm/i915/i915_drv.h | 5 +++++ drivers/gpu/drm/i915/i915_irq.c | 9 +++++++++ drivers/gpu/drm/i915/i915_reg.h | 4 ++++ 4 files changed, 24 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 58cf60d89f68..56f7ced16f1a 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -634,6 +634,12 @@ static int i915_error_state(struct seq_file *m, void *unused) seq_printf(m, " IPEIR: 0x%08x\n", error->bcs_ipeir); seq_printf(m, " INSTDONE: 0x%08x\n", error->bcs_instdone); seq_printf(m, " seqno: 0x%08x\n", error->bcs_seqno); + seq_printf(m, "Video (BSD) command stream:\n"); + seq_printf(m, " ACTHD: 0x%08x\n", error->vcs_acthd); + seq_printf(m, " IPEHR: 0x%08x\n", error->vcs_ipehr); + seq_printf(m, " IPEIR: 0x%08x\n", error->vcs_ipeir); + seq_printf(m, " INSTDONE: 0x%08x\n", error->vcs_instdone); + seq_printf(m, " seqno: 0x%08x\n", error->vcs_seqno); } seq_printf(m, "Render command stream:\n"); seq_printf(m, " ACTHD: 0x%08x\n", error->acthd); diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 05bff9e6a9cb..ec582b6d2113 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -154,6 +154,11 @@ struct drm_i915_error_state { u32 bcs_ipeir; u32 bcs_instdone; u32 bcs_seqno; + u32 vcs_acthd; /* gen6+ bsd engine */ + u32 vcs_ipehr; + u32 vcs_ipeir; + u32 vcs_instdone; + u32 vcs_seqno; u32 instpm; u32 instps; u32 instdone1; diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 4ff39dee7f1c..90c071d37748 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -595,6 +595,7 @@ static void i915_capture_error_state(struct drm_device *dev) error->error = 0; if (INTEL_INFO(dev)->gen >= 6) { error->error = I915_READ(ERROR_GEN6); + error->bcs_acthd = I915_READ(BCS_ACTHD); error->bcs_ipehr = I915_READ(BCS_IPEHR); error->bcs_ipeir = I915_READ(BCS_IPEIR); @@ -602,6 +603,14 @@ static void i915_capture_error_state(struct drm_device *dev) error->bcs_seqno = 0; if (dev_priv->blt_ring.get_seqno) error->bcs_seqno = dev_priv->blt_ring.get_seqno(&dev_priv->blt_ring); + + error->vcs_acthd = I915_READ(VCS_ACTHD); + error->vcs_ipehr = I915_READ(VCS_IPEHR); + error->vcs_ipeir = I915_READ(VCS_IPEIR); + error->vcs_instdone = I915_READ(VCS_INSTDONE); + error->vcs_seqno = 0; + if (dev_priv->bsd_ring.get_seqno) + error->vcs_seqno = dev_priv->bsd_ring.get_seqno(&dev_priv->bsd_ring); } if (INTEL_INFO(dev)->gen >= 4) { error->ipeir = I915_READ(IPEIR_I965); diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index b173e5b77f96..c79d4ba4fb12 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -305,6 +305,10 @@ #define INSTDONE 0x02090 #define NOPID 0x02094 #define HWSTAM 0x02098 +#define VCS_INSTDONE 0x1206C +#define VCS_IPEIR 0x12064 +#define VCS_IPEHR 0x12068 +#define VCS_ACTHD 0x12074 #define BCS_INSTDONE 0x2206C #define BCS_IPEIR 0x22064 #define BCS_IPEHR 0x22068 -- cgit v1.2.3 From 2e44f765dfd3a8592c2d6b6005be061eccdee137 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Fri, 29 Oct 2010 07:44:45 -0700 Subject: beceem: add module information Add description and version information to the driver. Make USB device table exported as alias so device will be autoloaded. Get rid of useless noise message on boot. Signed-off-by: Stephen Hemminger --- drivers/staging/bcm/Bcmnet.c | 25 +++++++++++-------------- drivers/staging/bcm/InterfaceInit.c | 13 +++++++------ 2 files changed, 18 insertions(+), 20 deletions(-) diff --git a/drivers/staging/bcm/Bcmnet.c b/drivers/staging/bcm/Bcmnet.c index bc2969821421..4d7d8cd4bf43 100644 --- a/drivers/staging/bcm/Bcmnet.c +++ b/drivers/staging/bcm/Bcmnet.c @@ -1,5 +1,9 @@ #include "headers.h" +#define DRV_DESCRIPTION "Beceem Communications Inc. WiMAX driver" +#define DRV_VERSION "5.2.7.3P1" +#define DRV_COPYRIGHT "Copyright 2010. Beceem Communications Inc" + static INT bcm_notify_event(struct notifier_block *nb, ULONG event, PVOID dev) { struct net_device *ndev = (struct net_device*)dev; @@ -236,29 +240,22 @@ void bcm_unregister_networkdev(PMINI_ADAPTER Adapter) static int bcm_init(void) { - int result; - result = InterfaceInitialize(); - if(result) - { - printk("Initialisation failed for usbbcm"); - } - else - { - printk("Initialised usbbcm"); - } - return result; + printk(KERN_INFO "%s, %s\n", DRV_DESCRIPTION, DRV_VERSION); + printk(KERN_INFO "%s\n", DRV_COPYRIGHT); + + return InterfaceInitialize(); } static void bcm_exit(void) { - printk("%s %s Calling InterfaceExit\n",__FILE__, __FUNCTION__); InterfaceExit(); - printk("%s %s InterfaceExit returned\n",__FILE__, __FUNCTION__); } module_init(bcm_init); module_exit(bcm_exit); -MODULE_LICENSE ("GPL"); +MODULE_DESCRIPTION(DRV_DESCRIPTION); +MODULE_VERSION(DRV_VERSION); +MODULE_LICENSE ("GPL"); diff --git a/drivers/staging/bcm/InterfaceInit.c b/drivers/staging/bcm/InterfaceInit.c index 824f9a45007a..e6d1dc0d3e43 100644 --- a/drivers/staging/bcm/InterfaceInit.c +++ b/drivers/staging/bcm/InterfaceInit.c @@ -2,12 +2,14 @@ static struct usb_device_id InterfaceUsbtable[] = { { USB_DEVICE(BCM_USB_VENDOR_ID_T3, BCM_USB_PRODUCT_ID_T3) }, - { USB_DEVICE(BCM_USB_VENDOR_ID_T3, BCM_USB_PRODUCT_ID_T3B) }, - { USB_DEVICE(BCM_USB_VENDOR_ID_T3, BCM_USB_PRODUCT_ID_T3L) }, - { USB_DEVICE(BCM_USB_VENDOR_ID_ZTE, BCM_USB_PRODUCT_ID_226) }, - { USB_DEVICE(BCM_USB_VENDOR_ID_FOXCONN, BCM_USB_PRODUCT_ID_1901) }, - {} + { USB_DEVICE(BCM_USB_VENDOR_ID_T3, BCM_USB_PRODUCT_ID_T3B) }, + { USB_DEVICE(BCM_USB_VENDOR_ID_T3, BCM_USB_PRODUCT_ID_T3L) }, + { USB_DEVICE(BCM_USB_VENDOR_ID_ZTE, BCM_USB_PRODUCT_ID_226) }, + { USB_DEVICE(BCM_USB_VENDOR_ID_FOXCONN, BCM_USB_PRODUCT_ID_1901) }, + + { } }; +MODULE_DEVICE_TABLE(usb, InterfaceUsbtable); VOID InterfaceAdapterFree(PS_INTERFACE_ADAPTER psIntfAdapter) { @@ -865,4 +867,3 @@ INT InterfaceExit(void) usb_deregister(&usbbcm_driver); return status; } -MODULE_LICENSE ("GPL"); -- cgit v1.2.3 From 91d29ee1a82fedcd7d1bbf24007b31a49c47e90a Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Fri, 29 Oct 2010 07:51:47 -0700 Subject: beceem: remove ifdef's There were a lot of ifdef's for driver options which have no configuration options. Choose the current value and remove the ifdef. Signed-off-by: Stephen Hemminger --- drivers/staging/bcm/Bcmchar.c | 6 - drivers/staging/bcm/Bcmnet.c | 22 --- drivers/staging/bcm/DDRInit.c | 2 - drivers/staging/bcm/Debug.h | 13 -- drivers/staging/bcm/InterfaceDld.c | 2 - drivers/staging/bcm/InterfaceInit.h | 4 - drivers/staging/bcm/InterfaceIsr.c | 2 - drivers/staging/bcm/InterfaceMisc.c | 2 - drivers/staging/bcm/InterfaceTx.c | 2 - drivers/staging/bcm/Macros.h | 5 - drivers/staging/bcm/Misc.c | 198 -------------------- drivers/staging/bcm/Prototypes.h | 5 - drivers/staging/bcm/Transmit.c | 116 ------------ drivers/staging/bcm/cntrl_SignalingInterface.h | 249 ------------------------- drivers/staging/bcm/headers.h | 28 --- drivers/staging/bcm/led_control.c | 7 - drivers/staging/bcm/nvm.c | 18 -- drivers/staging/bcm/nvm.h | 9 - 18 files changed, 690 deletions(-) diff --git a/drivers/staging/bcm/Bcmchar.c b/drivers/staging/bcm/Bcmchar.c index 77fdfe24d999..01f961d9c70c 100644 --- a/drivers/staging/bcm/Bcmchar.c +++ b/drivers/staging/bcm/Bcmchar.c @@ -329,9 +329,7 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) } if( -#if !defined(BCM_SHM_INTERFACE) (((ULONG)sRdmBuffer.Register & 0x0F000000) != 0x0F000000) || -#endif ((ULONG)sRdmBuffer.Register & 0x3) ) { @@ -385,10 +383,8 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) break; } if( -#if !defined(BCM_SHM_INTERFACE) (((ULONG)sWrmBuffer.Register & 0x0F000000) != 0x0F000000) || -#endif ((ULONG)sWrmBuffer.Register & 0x3) ) { @@ -823,7 +819,6 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) bcm_kfree(pvBuffer); break; } -#ifndef BCM_SHM_INTERFACE case IOCTL_BCM_BUFFER_DOWNLOAD_START: { INT NVMAccess = down_trylock(&Adapter->NVMRdmWrmLock) ; @@ -999,7 +994,6 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) up(&Adapter->NVMRdmWrmLock); break; } -#endif case IOCTL_BE_BUCKET_SIZE: Adapter->BEBucketSize = *(PULONG)arg; Status = STATUS_SUCCESS; diff --git a/drivers/staging/bcm/Bcmnet.c b/drivers/staging/bcm/Bcmnet.c index 4d7d8cd4bf43..3262aff8dd4a 100644 --- a/drivers/staging/bcm/Bcmnet.c +++ b/drivers/staging/bcm/Bcmnet.c @@ -50,9 +50,6 @@ static struct notifier_block bcm_notifier_block = struct net_device *gblpnetdev; /***************************************************************************************/ /* proto-type of lower function */ -#ifdef BCM_SHM_INTERFACE -const char *bcmVirtDeviceName="bcmeth"; -#endif static INT bcm_open(struct net_device *dev) { @@ -155,7 +152,6 @@ int register_networkdev(PMINI_ADAPTER Adapter) Adapter->dev->hard_header_len = ETH_HLEN + LEADER_SIZE; #endif -#ifndef BCM_SHM_INTERFACE Adapter->dev->mtu = MTU_SIZE; /* 1400 Bytes */ /* Read the MAC Address from EEPROM */ ReadMacAddressFromNVM(Adapter); @@ -176,24 +172,6 @@ int register_networkdev(PMINI_ADAPTER Adapter) Adapter->bNetdeviceNotifierRegistered = TRUE; } -#else - - Adapter->dev->mtu = CPE_MTU_SIZE; - -#if 0 - //for CPE - harcode the virtual mac address - Adapter->dev->dev_addr[0] = MII_WIMAX_MACADDRESS[0]; - Adapter->dev->dev_addr[1] = MII_WIMAX_MACADDRESS[1]; - Adapter->dev->dev_addr[2] = MII_WIMAX_MACADDRESS[2]; - Adapter->dev->dev_addr[3] = MII_WIMAX_MACADDRESS[3]; - Adapter->dev->dev_addr[4] = MII_WIMAX_MACADDRESS[4]; - Adapter->dev->dev_addr[5] = MII_WIMAX_MACADDRESS[5]; -#else - ReadMacAddressFromNVM(Adapter); -#endif - strcpy(Adapter->dev->name, bcmVirtDeviceName); //Copy the device name - -#endif result = register_netdev(Adapter->dev); if (!result) diff --git a/drivers/staging/bcm/DDRInit.c b/drivers/staging/bcm/DDRInit.c index 8907e211d483..454eb8d8992b 100644 --- a/drivers/staging/bcm/DDRInit.c +++ b/drivers/staging/bcm/DDRInit.c @@ -1,6 +1,5 @@ #include "headers.h" -#ifndef BCM_SHM_INTERFACE #define DDR_DUMP_INTERNAL_DEVICE_MEMORY 0xBFC02B00 @@ -1298,5 +1297,4 @@ int download_ddr_settings(PMINI_ADAPTER Adapter) return retval; } -#endif diff --git a/drivers/staging/bcm/Debug.h b/drivers/staging/bcm/Debug.h index 3d788b59ab57..b384115cab3a 100644 --- a/drivers/staging/bcm/Debug.h +++ b/drivers/staging/bcm/Debug.h @@ -21,19 +21,6 @@ typedef enum _BASE_TYPE int bcm_print_buffer( UINT debug_level, const char *function_name, char *file_name, int line_number, unsigned char *buffer, int bufferlen, BASE_TYPE base); -#ifdef BCM_SHM_INTERFACE -#define CPE_VIRTUAL_ERROR_CODE_BASE_ADDR (0xBFC02E00 + 0x4C) -// ERROR codes for debugging -extern unsigned char u32ErrorCounter ; -#define ERROR_DEVICE_REMOVED 0x1 -#define ERROR_LEADER_LENGTH_ZERO 0x2 -#define ERROR_LEADER_LENGTH_CORRUPTED 0x3 -#define ERROR_NO_SKBUFF 0x4 - -#define ERROR_DL_MODULE 0xaa000000 -extern void CPE_ERROR_LOG(unsigned int module,unsigned int code); - -#endif diff --git a/drivers/staging/bcm/InterfaceDld.c b/drivers/staging/bcm/InterfaceDld.c index 60c0f29f3eef..62770e042e51 100644 --- a/drivers/staging/bcm/InterfaceDld.c +++ b/drivers/staging/bcm/InterfaceDld.c @@ -1,6 +1,5 @@ #include "headers.h" -#ifndef BCM_SHM_INTERFACE int InterfaceFileDownload( PVOID arg, struct file *flp, @@ -506,5 +505,4 @@ error: return status; } -#endif diff --git a/drivers/staging/bcm/InterfaceInit.h b/drivers/staging/bcm/InterfaceInit.h index e7a96e5c5c50..a11af81d74d9 100644 --- a/drivers/staging/bcm/InterfaceInit.h +++ b/drivers/staging/bcm/InterfaceInit.h @@ -19,16 +19,12 @@ INT InterfaceInitialize(void); INT InterfaceExit(void); -#ifndef BCM_SHM_INTERFACE INT InterfaceAdapterInit(PS_INTERFACE_ADAPTER Adapter); INT usbbcm_worker_thread(PS_INTERFACE_ADAPTER psIntfAdapter); VOID InterfaceAdapterFree(PS_INTERFACE_ADAPTER psIntfAdapter); -#else -INT InterfaceAdapterInit(PMINI_ADAPTER Adapter); -#endif #if 0 diff --git a/drivers/staging/bcm/InterfaceIsr.c b/drivers/staging/bcm/InterfaceIsr.c index f928fe4d564d..c1f8e7aa05f7 100644 --- a/drivers/staging/bcm/InterfaceIsr.c +++ b/drivers/staging/bcm/InterfaceIsr.c @@ -1,6 +1,5 @@ #include "headers.h" -#ifndef BCM_SHM_INTERFACE static void read_int_callback(struct urb *urb/*, struct pt_regs *regs*/) { @@ -199,5 +198,4 @@ void InterfaceDisableInterrupt(PMINI_ADAPTER Adapter) } -#endif diff --git a/drivers/staging/bcm/InterfaceMisc.c b/drivers/staging/bcm/InterfaceMisc.c index 8fc893b37fe4..2d98b7e846c2 100644 --- a/drivers/staging/bcm/InterfaceMisc.c +++ b/drivers/staging/bcm/InterfaceMisc.c @@ -1,6 +1,5 @@ #include "headers.h" -#ifndef BCM_SHM_INTERFACE PS_INTERFACE_ADAPTER InterfaceAdapterGet(PMINI_ADAPTER psAdapter) @@ -287,4 +286,3 @@ VOID putUsbSuspend(struct work_struct *work) } -#endif diff --git a/drivers/staging/bcm/InterfaceTx.c b/drivers/staging/bcm/InterfaceTx.c index 771f7b34d2ec..826ed93c9b56 100644 --- a/drivers/staging/bcm/InterfaceTx.c +++ b/drivers/staging/bcm/InterfaceTx.c @@ -1,6 +1,5 @@ #include "headers.h" -#ifndef BCM_SHM_INTERFACE /* Function: InterfaceTxDataPacket @@ -255,5 +254,4 @@ int InterfaceTransmitPacket(PVOID arg, PVOID data, UINT len) return TransmitTcb(psIntfAdapter, pTcb, data, len); } -#endif diff --git a/drivers/staging/bcm/Macros.h b/drivers/staging/bcm/Macros.h index 0241234605f1..5485f574b917 100644 --- a/drivers/staging/bcm/Macros.h +++ b/drivers/staging/bcm/Macros.h @@ -300,12 +300,7 @@ typedef enum _E_PHS_DSC_ACTION /* Idle Mode Related Registers */ #define DEBUG_INTERRUPT_GENERATOR_REGISTOR 0x0F00007C -#ifdef BCM_SHM_INTERFACE -#define SW_ABORT_IDLEMODE_LOC 0xbfc02f9c -#define CPE_VIRTUAL_MAILBOX_REG 0xBFC02E58 -#else #define SW_ABORT_IDLEMODE_LOC 0x0FF01FFC -#endif #define SW_ABORT_IDLEMODE_PATTERN 0xd0ea1d1e #define DEVICE_INT_OUT_EP_REG0 0x0F011870 diff --git a/drivers/staging/bcm/Misc.c b/drivers/staging/bcm/Misc.c index 22550f745917..cedeb8c3723e 100644 --- a/drivers/staging/bcm/Misc.c +++ b/drivers/staging/bcm/Misc.c @@ -157,9 +157,7 @@ VOID AdapterFree(PMINI_ADAPTER Adapter) //Free the PHS Interface PhsCleanup(&Adapter->stBCMPhsContext); -#ifndef BCM_SHM_INTERFACE BcmDeAllocFlashCSStructure(Adapter); -#endif bcm_kfree (Adapter); BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "<========\n"); @@ -489,9 +487,6 @@ INT CopyBufferToControlPacket(PMINI_ADAPTER Adapter,/**index_wr_txcntrlpkt); BCM_DEBUG_PRINT( Adapter,DBG_TYPE_TX, TX_CONTROL,DBG_LVL_ALL, "Calling transmit_packets"); atomic_set(&Adapter->TxPktAvail, 1); -#ifdef BCM_SHM_INTERFACE - virtual_mail_box_interrupt(); -#endif wake_up(&Adapter->tx_packet_wait_queue); } else @@ -787,12 +782,10 @@ void SendIdleModeResponse(PMINI_ADAPTER Adapter) down(&Adapter->rdmwrmsync); Adapter->bPreparingForLowPowerMode = TRUE; up(&Adapter->rdmwrmsync); -#ifndef BCM_SHM_INTERFACE //Killing all URBS. if(Adapter->bDoSuspend == TRUE) Bcm_kill_all_URBs((PS_INTERFACE_ADAPTER)(Adapter->pvInterfaceAdapter)); -#endif } else { @@ -811,9 +804,7 @@ void SendIdleModeResponse(PMINI_ADAPTER Adapter) { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"fail to send the Idle mode Request \n"); Adapter->bPreparingForLowPowerMode = FALSE; -#ifndef BCM_SHM_INTERFACE StartInterruptUrb((PS_INTERFACE_ADAPTER)(Adapter->pvInterfaceAdapter)); -#endif } do_gettimeofday(&tv); BCM_DEBUG_PRINT(Adapter,DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "IdleMode Msg submitter to Q :%ld ms", tv.tv_sec *1000 + tv.tv_usec /1000); @@ -985,7 +976,6 @@ __inline int reset_card_proc(PMINI_ADAPTER ps_adapter) { int retval = STATUS_SUCCESS; -#ifndef BCM_SHM_INTERFACE PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); PS_INTERFACE_ADAPTER psIntfAdapter = NULL; unsigned int value = 0, uiResetValue = 0; @@ -1006,11 +996,9 @@ __inline int reset_card_proc(PMINI_ADAPTER ps_adapter) wrmalt(ps_adapter, SYS_CFG, &value, sizeof(value)); } -#ifndef BCM_SHM_INTERFACE //killing all submitted URBs. psIntfAdapter->psAdapter->StopAllXaction = TRUE ; Bcm_kill_all_URBs(psIntfAdapter); -#endif /* Reset the UMA-B Device */ if(ps_adapter->chip_id >= T3LPB) { @@ -1111,7 +1099,6 @@ __inline int reset_card_proc(PMINI_ADAPTER ps_adapter) err_exit : psIntfAdapter->psAdapter->StopAllXaction = FALSE ; -#endif return retval; } @@ -1148,9 +1135,6 @@ int InitCardAndDownloadFirmware(PMINI_ADAPTER ps_adapter) UINT status = STATUS_SUCCESS; UINT value = 0; -#ifdef BCM_SHM_INTERFACE - unsigned char *pConfigFileAddr = (unsigned char *)CPE_MACXVI_CFG_ADDR; -#endif /* * Create the threads first and then download the * Firm/DDR Settings.. @@ -1169,7 +1153,6 @@ int InitCardAndDownloadFirmware(PMINI_ADAPTER ps_adapter) return status; } -#ifndef BCM_SHM_INTERFACE if(ps_adapter->chip_id >= T3LPB) { rdmalt(ps_adapter, SYS_CFG, &value, sizeof (value)); @@ -1299,61 +1282,12 @@ OUT: wake_up(&ps_adapter->LEDInfo.notify_led_event); } -#else - - ps_adapter->bDDRInitDone = TRUE; - //Initializing the NVM. - BcmInitNVM(ps_adapter); - - //Propagating the cal param from Flash to DDR - value = 0; - wrmalt(ps_adapter, EEPROM_CAL_DATA_INTERNAL_LOC - 4, &value, sizeof(value)); - wrmalt(ps_adapter, EEPROM_CAL_DATA_INTERNAL_LOC - 8, &value, sizeof(value)); - - if(ps_adapter->eNVMType == NVM_FLASH) - { - status = PropagateCalParamsFromFlashToMemory(ps_adapter); - if(status) - { - printk("\nPropogation of Cal param from flash to DDR failed ..\n" ); - } - } - - //Copy config file param to DDR. - memcpy(pConfigFileAddr,ps_adapter->pstargetparams, sizeof(STARGETPARAMS)); - - if(register_networkdev(ps_adapter)) - { - BCM_DEBUG_PRINT(ps_adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Register Netdevice failed. Cleanup needs to be performed."); - return -EIO; - } - - - status = InitLedSettings (ps_adapter); - if(status) - { - BCM_DEBUG_PRINT(ps_adapter,DBG_TYPE_PRINTK, 0, 0,"INIT LED FAILED\n"); - return status; - } - - - if(register_control_device_interface(ps_adapter) < 0) - { - BCM_DEBUG_PRINT(ps_adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Register Control Device failed. Cleanup needs to be performed."); - return -EIO; - } - - ps_adapter->fw_download_done = TRUE; -#endif return status; } int bcm_parse_target_params(PMINI_ADAPTER Adapter) { -#ifdef BCM_SHM_INTERFACE - extern void read_cfg_file(PMINI_ADAPTER Adapter); -#endif struct file *flp=NULL; mm_segment_t oldfs={0}; char *buff = NULL; @@ -1401,10 +1335,6 @@ int bcm_parse_target_params(PMINI_ADAPTER Adapter) memcpy(Adapter->pstargetparams, buff, sizeof(STARGETPARAMS)); bcm_kfree (buff); beceem_parse_target_struct(Adapter); -#ifdef BCM_SHM_INTERFACE - read_cfg_file(Adapter); - -#endif return STATUS_SUCCESS; } @@ -1640,81 +1570,21 @@ int rdm(PMINI_ADAPTER Adapter, UINT uiAddress, PCHAR pucBuff, size_t sSize) { INT uiRetVal =0; -#ifndef BCM_SHM_INTERFACE uiRetVal = Adapter->interface_rdm(Adapter->pvInterfaceAdapter, uiAddress, pucBuff, sSize); if(uiRetVal < 0) return uiRetVal; -#else - int indx; - uiRetVal = STATUS_SUCCESS; - if(uiAddress & 0x10000000) { - // DDR Memory Access - uiAddress |= CACHE_ADDRESS_MASK; - memcpy(pucBuff,(unsigned char *)uiAddress ,sSize); - } - else { - // Register, SPRAM, Flash - uiAddress |= UNCACHE_ADDRESS_MASK; - if ((uiAddress & FLASH_ADDR_MASK) == (FLASH_CONTIGIOUS_START_ADDR_BCS350 & FLASH_ADDR_MASK)) - { - #if defined(FLASH_DIRECT_ACCESS) - memcpy(pucBuff,(unsigned char *)uiAddress ,sSize); - #else - printk("\nInvalid GSPI ACCESS :Addr :%#X", uiAddress); - uiRetVal = STATUS_FAILURE; - #endif - } - else if(((unsigned int )uiAddress & 0x3) || - ((unsigned int )pucBuff & 0x3) || - ((unsigned int )sSize & 0x3)) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"rdmalt :unalligned register access uiAddress = %x,pucBuff = %x size = %x\n",(unsigned int )uiAddress,(unsigned int )pucBuff,(unsigned int )sSize); - uiRetVal = STATUS_FAILURE; - } - else { - for (indx=0;indxinterface_wrm(Adapter->pvInterfaceAdapter, uiAddress, pucBuff, sSize); -#else - int indx; - if(uiAddress & 0x10000000) { - // DDR Memory Access - uiAddress |= CACHE_ADDRESS_MASK; - memcpy((unsigned char *)(uiAddress),pucBuff,sSize); - } - else { - // Register, SPRAM, Flash - uiAddress |= UNCACHE_ADDRESS_MASK; - - if(((unsigned int )uiAddress & 0x3) || - ((unsigned int )pucBuff & 0x3) || - ((unsigned int )sSize & 0x3)) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"wrmalt: unalligned register access uiAddress = %x,pucBuff = %x size = %x\n",(unsigned int )uiAddress,(unsigned int )pucBuff,(unsigned int )sSize); - iRetVal = STATUS_FAILURE; - } - else { - for (indx=0;indxbPreparingForLowPowerMode = TRUE; up(&Adapter->rdmwrmsync); //Killing all URBS. -#ifndef BCM_SHM_INTERFACE if(Adapter->bDoSuspend == TRUE) Bcm_kill_all_URBs((PS_INTERFACE_ADAPTER)(Adapter->pvInterfaceAdapter)); -#endif } else { @@ -1943,9 +1811,7 @@ static VOID SendShutModeResponse(PMINI_ADAPTER Adapter) BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, MP_SHUTDOWN, DBG_LVL_ALL,"fail to send the Idle mode Request \n"); Adapter->bPreparingForLowPowerMode = FALSE; -#ifndef BCM_SHM_INTERFACE StartInterruptUrb((PS_INTERFACE_ADAPTER)(Adapter->pvInterfaceAdapter)); -#endif } } @@ -2077,11 +1943,7 @@ void update_per_sf_desc_cnts( PMINI_ADAPTER Adapter) if(!atomic_read (&Adapter->uiMBupdate)) return; -#ifdef BCM_SHM_INTERFACE - if(rdmalt(Adapter, TARGET_SFID_TXDESC_MAP_LOC, (PUINT)uibuff, sizeof(UINT) * MAX_TARGET_DSX_BUFFERS)<0) -#else if(rdmaltWithLock(Adapter, TARGET_SFID_TXDESC_MAP_LOC, (PUINT)uibuff, sizeof(UINT) * MAX_TARGET_DSX_BUFFERS)<0) -#endif { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "rdm failed\n"); return; @@ -2179,65 +2041,5 @@ void beceem_protocol_reset (PMINI_ADAPTER Adapter) -#ifdef BCM_SHM_INTERFACE - - -#define GET_GTB_DIFF(start, end) \ -( (start) < (end) )? ( (end) - (start) ) : ( ~0x0 - ( (start) - (end)) +1 ) - -void usdelay ( unsigned int a) { - unsigned int start= *(unsigned int *)0xaf8051b4; - unsigned int end = start+1; - unsigned int diff = 0; - - while(1) { - end = *(unsigned int *)0xaf8051b4; - diff = (GET_GTB_DIFF(start,end))/80; - if (diff >= a) - break; - } -} -void read_cfg_file(PMINI_ADAPTER Adapter) { - - - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Config File Version = 0x%x \n",Adapter->pstargetparams->m_u32CfgVersion ); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Center Frequency = 0x%x \n",Adapter->pstargetparams->m_u32CenterFrequency ); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Band A Scan = 0x%x \n",Adapter->pstargetparams->m_u32BandAScan ); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Band B Scan = 0x%x \n",Adapter->pstargetparams->m_u32BandBScan ); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Band C Scan = 0x%x \n",Adapter->pstargetparams->m_u32BandCScan ); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"ERTPS Options = 0x%x \n",Adapter->pstargetparams->m_u32ErtpsOptions ); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"PHS Enable = 0x%x \n",Adapter->pstargetparams->m_u32PHSEnable ); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Handoff Enable = 0x%x \n",Adapter->pstargetparams->m_u32HoEnable ); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"HO Reserved1 = 0x%x \n",Adapter->pstargetparams->m_u32HoReserved1 ); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"HO Reserved2 = 0x%x \n",Adapter->pstargetparams->m_u32HoReserved2 ); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"MIMO Enable = 0x%x \n",Adapter->pstargetparams->m_u32MimoEnable ); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"PKMv2 Enable = 0x%x \n",Adapter->pstargetparams->m_u32SecurityEnable ); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Powersaving Modes Enable = 0x%x \n",Adapter->pstargetparams->m_u32PowerSavingModesEnable ); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Power Saving Mode Options = 0x%x \n",Adapter->pstargetparams->m_u32PowerSavingModeOptions ); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"ARQ Enable = 0x%x \n",Adapter->pstargetparams->m_u32ArqEnable ); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Harq Enable = 0x%x \n",Adapter->pstargetparams->m_u32HarqEnable ); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"EEPROM Flag = 0x%x \n",Adapter->pstargetparams->m_u32EEPROMFlag ); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Customize = 0x%x \n",Adapter->pstargetparams->m_u32Customize ); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Bandwidth = 0x%x \n",Adapter->pstargetparams->m_u32ConfigBW ); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"ShutDown Timer Value = 0x%x \n",Adapter->pstargetparams->m_u32ShutDownInitThresholdTimer ); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"RadioParameter = 0x%x \n",Adapter->pstargetparams->m_u32RadioParameter ); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"PhyParameter1 = 0x%x \n",Adapter->pstargetparams->m_u32PhyParameter1 ); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"PhyParameter2 = 0x%x \n",Adapter->pstargetparams->m_u32PhyParameter2 ); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"PhyParameter3 = 0x%x \n",Adapter->pstargetparams->m_u32PhyParameter3 ); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"m_u32TestOptions = 0x%x \n",Adapter->pstargetparams->m_u32TestOptions ); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"MaxMACDataperDLFrame = 0x%x \n",Adapter->pstargetparams->m_u32MaxMACDataperDLFrame ); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"MaxMACDataperULFrame = 0x%x \n",Adapter->pstargetparams->m_u32MaxMACDataperULFrame ); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Corr2MacFlags = 0x%x \n",Adapter->pstargetparams->m_u32Corr2MacFlags ); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"HostDrvrConfig1 = 0x%x \n",Adapter->pstargetparams->HostDrvrConfig1 ); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"HostDrvrConfig2 = 0x%x \n",Adapter->pstargetparams->HostDrvrConfig2 ); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"HostDrvrConfig3 = 0x%x \n",Adapter->pstargetparams->HostDrvrConfig3 ); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"HostDrvrConfig4 = 0x%x \n",Adapter->pstargetparams->HostDrvrConfig4 ); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"HostDrvrConfig5 = 0x%x \n",Adapter->pstargetparams->HostDrvrConfig5 ); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"HostDrvrConfig6 = 0x%x \n",Adapter->pstargetparams->HostDrvrConfig6 ); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Segmented PUSC Enable = 0x%x \n",Adapter->pstargetparams->m_u32SegmentedPUSCenable ); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"BamcEnable = 0x%x \n",Adapter->pstargetparams->m_u32BandAMCEnable ); -} - -#endif diff --git a/drivers/staging/bcm/Prototypes.h b/drivers/staging/bcm/Prototypes.h index 70ec8bcafd1e..82738be3ed48 100644 --- a/drivers/staging/bcm/Prototypes.h +++ b/drivers/staging/bcm/Prototypes.h @@ -309,11 +309,6 @@ INT buffDnldVerify(PMINI_ADAPTER Adapter, unsigned char *mappedbuffer, unsigned VOID putUsbSuspend(struct work_struct *work); BOOLEAN IsReqGpioIsLedInNVM(PMINI_ADAPTER Adapter, UINT gpios); -#ifdef BCM_SHM_INTERFACE -INT beceem_virtual_device_init(void); -VOID virtual_mail_box_interrupt(void); -INT beceem_virtual_device_exit(void); -#endif #endif diff --git a/drivers/staging/bcm/Transmit.c b/drivers/staging/bcm/Transmit.c index 12f9e13457db..597786a06785 100644 --- a/drivers/staging/bcm/Transmit.c +++ b/drivers/staging/bcm/Transmit.c @@ -146,18 +146,6 @@ INT bcm_transmit(struct sk_buff *skb, /**< skb */ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_OSAL_DBG, DBG_LVL_ALL, "Pkt Len = %d, sec: %ld, usec: %ld\n", (skb->len-ETH_HLEN), tv.tv_sec, tv.tv_usec); -#ifdef BCM_SHM_INTERFACE - spin_lock(&Adapter->txtransmitlock); - if(Adapter->txtransmit_running == 0) - { - Adapter->txtransmit_running = 1; - calltransmit = 1; - } - else - calltransmit = 0; - - spin_unlock(&Adapter->txtransmitlock); -#endif if(calltransmit == 1) transmit_packets(Adapter); else @@ -165,9 +153,6 @@ INT bcm_transmit(struct sk_buff *skb, /**< skb */ if(!atomic_read(&Adapter->TxPktAvail)) { atomic_set(&Adapter->TxPktAvail, 1); -#ifdef BCM_SHM_INTERFACE - virtual_mail_box_interrupt(); -#endif wake_up(&Adapter->tx_packet_wait_queue); } } @@ -224,44 +209,8 @@ INT SendControlPacket(PMINI_ADAPTER Adapter, /**PLength); if(Adapter->device_removed) return 0; -#ifndef BCM_SHM_INTERFACE Adapter->interface_transmit(Adapter->pvInterfaceAdapter, pControlPacket, (PLeader->PLength + LEADER_SIZE)); -#else - tx_pkts_to_firmware(pControlPacket,(PLeader->PLength + LEADER_SIZE),1); - - if(PLeader->Status==IDLE_MESSAGE) - { - if(((CONTROL_MESSAGE*)PLeader)->szData[0] == GO_TO_IDLE_MODE_PAYLOAD && - ((CONTROL_MESSAGE*)PLeader)->szData[1] == TARGET_CAN_GO_TO_IDLE_MODE) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Idle Mode Ack Sent to the Device\n"); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Host Entering into Idle Mode\n"); - do_gettimeofday(&tv); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "IdleMode Msg sent to f/w at time :%ld ms", tv.tv_sec *1000 + tv.tv_usec /1000); - if(Adapter->bDoSuspend != TRUE) - { - Adapter->IdleMode = TRUE; - Adapter->bPreparingForLowPowerMode = FALSE ; - } - } - } - if((PLeader->Status == LINK_UP_CONTROL_REQ) && - ((PUCHAR)pControlPacket)[sizeof(LEADER)] == LINK_UP_ACK && - ((PUCHAR)pControlPacket)[sizeof(LEADER)+1] == - LINK_SHUTDOWN_REQ_FROM_FIRMWARE && - ((PUCHAR)pControlPacket)[sizeof(LEADER)+2] == SHUTDOWN_ACK_FROM_DRIVER) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Shut Down ACK Sent and Host entering Shut State \n"); - if(Adapter->bDoSuspend != TRUE) - { - Adapter->bShutStatus = TRUE; - Adapter->bPreparingForLowPowerMode = FALSE; - Adapter->bTriedToWakeUpFromlowPowerMode = FALSE; - } - - } -#endif ((PLINUX_DEP_DATA)Adapter->pvOsDepData)->netstats.tx_packets++; ((PLINUX_DEP_DATA)Adapter->pvOsDepData)->netstats.tx_bytes+= @@ -282,9 +231,6 @@ INT SetupNextSend(PMINI_ADAPTER Adapter, /**len = %d", Packet->len); BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Vcid = %d", Vcid); -#ifndef BCM_SHM_INTERFACE status = Adapter->interface_transmit(Adapter->pvInterfaceAdapter, Packet->data, (Leader.PLength + LEADER_SIZE)); -#else - status = tx_pkts_to_firmware(Packet,Packet->len,0); -#endif if(status) { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Tx Failed..\n"); @@ -376,9 +318,6 @@ INT SetupNextSend(PMINI_ADAPTER Adapter, /**PackInfo[QueueIndex].uiTotalTxBytes += Leader.PLength; atomic_add(Leader.PLength, &Adapter->GoodTxByteCount); atomic_inc(&Adapter->TxTotalPacketCount); -#ifdef GDMA_INTERFACE - dontfree = 1; -#endif } atomic_dec(&Adapter->CurrNumFreeTxDesc); @@ -393,23 +332,11 @@ errExit: Adapter->PackInfo[QueueIndex].NumOfPacketsSent++; atomic_dec(&Adapter->PackInfo[QueueIndex].uiPerSFTxResourceCount); -#ifdef BCM_SHM_INTERFACE - if(atomic_read(&Adapter->PackInfo[QueueIndex].uiPerSFTxResourceCount) < 0) - { - atomic_set(&Adapter->PackInfo[QueueIndex].uiPerSFTxResourceCount, 0); - } -#endif Adapter->PackInfo[QueueIndex].uiThisPeriodSentBytes += Leader.PLength; } -#ifdef GDMA_INTERFACE - if(!dontfree){ bcm_kfree_skb(Packet); - } -#else - bcm_kfree_skb(Packet); -#endif return status; } @@ -420,9 +347,7 @@ Transmit thread int tx_pkt_handler(PMINI_ADAPTER Adapter /**< pointer to adapter object*/ ) { -#ifndef BCM_SHM_INTERFACE int status = 0; -#endif UINT calltransmit = 1; BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Entring to wait for signal from the interrupt service thread!Adapter = %p",Adapter); @@ -437,9 +362,7 @@ int tx_pkt_handler(PMINI_ADAPTER Adapter /**< pointer to adapter object*/ atomic_read(&Adapter->CurrNumFreeTxDesc)) && (Adapter->device_removed == FALSE))) || (1 == Adapter->downloadDDR) || kthread_should_stop() -#ifndef BCM_SHM_INTERFACE || (TRUE == Adapter->bEndPointHalted) -#endif , msecs_to_jiffies(10)); } else{ @@ -449,9 +372,7 @@ int tx_pkt_handler(PMINI_ADAPTER Adapter /**< pointer to adapter object*/ atomic_read(&Adapter->CurrNumFreeTxDesc)) && (Adapter->device_removed == FALSE))) || (1 == Adapter->downloadDDR) || kthread_should_stop() -#ifndef BCM_SHM_INTERFACE || (TRUE == Adapter->bEndPointHalted) -#endif ); } @@ -462,7 +383,6 @@ int tx_pkt_handler(PMINI_ADAPTER Adapter /**< pointer to adapter object*/ return 0; } -#ifndef BCM_SHM_INTERFACE if(Adapter->downloadDDR == 1) { @@ -489,7 +409,6 @@ int tx_pkt_handler(PMINI_ADAPTER Adapter /**< pointer to adapter object*/ update_per_sf_desc_cnts(Adapter); } } -#endif if( atomic_read(&Adapter->CurrNumFreeTxDesc) && Adapter->LinkStatus == SYNC_UP_REQUEST && @@ -507,17 +426,6 @@ int tx_pkt_handler(PMINI_ADAPTER Adapter /**< pointer to adapter object*/ wake_up(&Adapter->process_rx_cntrlpkt); } -#ifdef BCM_SHM_INTERFACE - spin_lock_bh(&Adapter->txtransmitlock); - if(Adapter->txtransmit_running == 0) - { - Adapter->txtransmit_running = 1; - calltransmit = 1; - } - else - calltransmit = 0; - spin_unlock_bh(&Adapter->txtransmitlock); -#endif if(calltransmit) transmit_packets(Adapter); @@ -527,29 +435,5 @@ int tx_pkt_handler(PMINI_ADAPTER Adapter /**< pointer to adapter object*/ return 0; } -#ifdef BCM_SHM_INTERFACE -extern PMINI_ADAPTER psAdaptertest; -void virtual_mail_box_interrupt(void) -{ - -#ifndef GDMA_INTERFACE - PUINT ptr = (PUINT)CPE_VIRTUAL_MAILBOX_REG; - UINT intval = (UINT)((*ptr & 0xFF00) >> 8); - if (intval != 0) - { - atomic_set(&psAdaptertest->CurrNumFreeTxDesc, intval); - atomic_set (&psAdaptertest->uiMBupdate, TRUE); - - //make it to 0 - *ptr = *ptr & 0xffff00ff; - } -#endif -} -unsigned int total_tx_pkts_pending(void) -{ - return atomic_read(&psAdaptertest->TotalPacketCount); -} - -#endif diff --git a/drivers/staging/bcm/cntrl_SignalingInterface.h b/drivers/staging/bcm/cntrl_SignalingInterface.h index 4cbe30022248..7c47af7729f6 100644 --- a/drivers/staging/bcm/cntrl_SignalingInterface.h +++ b/drivers/staging/bcm/cntrl_SignalingInterface.h @@ -2,19 +2,6 @@ #define CNTRL_SIGNALING_INTERFACE_ -#ifdef BECEEM_TARGET - -#include -#include -#include -#include -#include -using namespace Beceem; -#ifdef ENABLE_CORRIGENDUM2_UPDATE -extern B_UINT32 g_u32Corr2MacFlags; -#endif - -#else #define DSA_REQ 11 @@ -28,7 +15,6 @@ extern B_UINT32 g_u32Corr2MacFlags; #define DSD_ACK 19 #define MAX_CLASSIFIERS_IN_SF 4 -#endif #define MAX_STRING_LEN 20 #define MAX_PHS_LENGTHS 255 @@ -57,37 +43,7 @@ extern B_UINT32 g_u32Corr2MacFlags; ////////////////////////structure Definitions/////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// /// \brief class cCPacketClassificationRule -#ifdef BECEEM_TARGET -class CCPacketClassificationRuleSI{ - public: - /// \brief Constructor for the class - CCPacketClassificationRuleSI(): - u8ClassifierRulePriority(mClassifierRulePriority), - u8IPTypeOfServiceLength(mIPTypeOfService), - u8Protocol(mProtocol), - u8IPMaskedSourceAddressLength(0), - u8IPDestinationAddressLength(0), - u8ProtocolSourcePortRangeLength(0), - u8ProtocolDestPortRangeLength(0), - u8EthernetDestMacAddressLength(0), - u8EthernetSourceMACAddressLength(0), - u8EthertypeLength(0), - u16UserPriority(mUserPriority), - u16VLANID(mVLANID), - u8AssociatedPHSI(mAssociatedPHSI), - u16PacketClassificationRuleIndex(mPacketClassifierRuleIndex), - u8VendorSpecificClassifierParamLength(mVendorSpecificClassifierParamLength), - u8IPv6FlowLableLength(mIPv6FlowLableLength), - u8ClassifierActionRule(mClassifierActionRule) - - {} - void Reset() - { - CCPacketClassificationRuleSI(); - } -#else struct _stCPacketClassificationRuleSI{ -#endif /** 16bit UserPriority Of The Service Flow*/ B_UINT16 u16UserPriority; @@ -145,29 +101,10 @@ struct _stCPacketClassificationRuleSI{ B_UINT8 u8ClassifierActionRule; B_UINT16 u16ValidityBitMap; }; -#ifndef BECEEM_TARGET typedef struct _stCPacketClassificationRuleSI CCPacketClassificationRuleSI,stCPacketClassificationRuleSI, *pstCPacketClassificationRuleSI; -#endif /// \brief class CPhsRuleSI -#ifdef BECEEM_TARGET -class CPhsRuleSI{ - public: - /// \brief Constructor for the class - CPhsRuleSI(): - u8PHSI(mPHSI), - u8PHSFLength(0), - u8PHSMLength(0), - u8PHSS(mPHSS), - u8PHSV(mPHSV), - u8VendorSpecificPHSParamsLength(mVendorSpecificPHSParamLength){} - void Reset() - { - CPhsRuleSI(); - } -#else typedef struct _stPhsRuleSI { -#endif /** 8bit PHS Index Of The Service Flow*/ B_UINT8 u8PHSI; /** PHSF Length Of The Service Flow*/ @@ -188,31 +125,11 @@ typedef struct _stPhsRuleSI { B_UINT8 u8VendorSpecificPHSParams[VENDOR_PHS_PARAM_LENGTH]; B_UINT8 u8Padding[2]; -#ifdef BECEEM_TARGET -}; -#else }stPhsRuleSI,*pstPhsRuleSI; typedef stPhsRuleSI CPhsRuleSI; -#endif /// \brief structure cConvergenceSLTypes -#ifdef BECEEM_TARGET -class CConvergenceSLTypes{ - public: - /// \brief Constructor for the class - CConvergenceSLTypes(): - u8ClassfierDSCAction(mClassifierDSCAction), - u8PhsDSCAction (mPhsDSCAction) - {} - void Reset() - { - CConvergenceSLTypes(); - cCPacketClassificationRule.Reset(); - cPhsRule.Reset(); - } -#else struct _stConvergenceSLTypes{ -#endif /** 8bit Phs Classfier Action Of The Service Flow*/ B_UINT8 u8ClassfierDSCAction; /** 8bit Phs DSC Action Of The Service Flow*/ @@ -220,111 +137,15 @@ struct _stConvergenceSLTypes{ /** 16bit Padding */ B_UINT8 u8Padding[2]; /// \brief class cCPacketClassificationRule -#ifdef BECEEM_TARGET - CCPacketClassificationRuleSI cCPacketClassificationRule; -#else stCPacketClassificationRuleSI cCPacketClassificationRule; -#endif /// \brief class CPhsRuleSI -#ifdef BECEEM_TARGET - CPhsRuleSI cPhsRule; -#else struct _stPhsRuleSI cPhsRule; -#endif }; -#ifndef BECEEM_TARGET typedef struct _stConvergenceSLTypes stConvergenceSLTypes,CConvergenceSLTypes, *pstConvergenceSLTypes; -#endif /// \brief structure CServiceFlowParamSI -#ifdef BECEEM_TARGET -class CServiceFlowParamSI{ - public: - /// \brief Constructor for the class - CServiceFlowParamSI(): - u32SFID(mSFid), - u16CID(mCid), - u8ServiceClassNameLength(mServiceClassNameLength), - u8MBSService(mMBSService), - u8QosParamSet(mQosParamSetType), - u8TrafficPriority(mTrafficPriority), - u32MaxSustainedTrafficRate(mMaximumSustainedTrafficRate), - u32MaxTrafficBurst(mMaximumTrafficBurst), - u32MinReservedTrafficRate(mMinimumReservedTrafficRate), - u8ServiceFlowSchedulingType(mServiceFlowSchedulingType), - u8RequesttransmissionPolicy(mRequestTransmissionPolicy), - u32ToleratedJitter(mToleratedJitter), - u32MaximumLatency(mMaximumLatency), - u8FixedLengthVSVariableLengthSDUIndicator - (mFixedLengthVSVariableLength), - u8SDUSize(mSDUSize), - u16TargetSAID(mTargetSAID), - u8ARQEnable(mARQEnable), - u16ARQWindowSize(mARQWindowSize), - u16ARQBlockLifeTime(mARQBlockLifeTime), - u16ARQSyncLossTimeOut(mARQSyncLossTimeOut), - u8ARQDeliverInOrder(mARQDeliverInOrder), - u16ARQRxPurgeTimeOut(mARQRXPurgeTimeOut), - //Add ARQ BLOCK SIZE, ARQ TX and RX delay initializations here - //after we move to only CORR2 - u8RxARQAckProcessingTime(mRxARQAckProcessingTime), - u8CSSpecification(mCSSpecification), - u8TypeOfDataDeliveryService(mTypeOfDataDeliveryService), - u16SDUInterArrivalTime(mSDUInterArrivalTime), - u16TimeBase(mTimeBase), - u8PagingPreference(mPagingPreference), - u8MBSZoneIdentifierassignment(mMBSZoneIdentifierassignmentLength), - u8TrafficIndicationPreference(mTrafficIndicationPreference), - u8GlobalServicesClassNameLength(mGlobalServicesClassNameLength), - u8SNFeedbackEnabled(mSNFeedbackEnabled), - u8FSNSize(mFSNSize), - u8CIDAllocation4activeBSsLength(mCIDAllocation4activeBSsLength), - u16UnsolicitedGrantInterval(mUnsolicitedGrantInterval), - u16UnsolicitedPollingInterval(mUnsolicitedPollingInterval), - u8PDUSNExtendedSubheader4HarqReordering(mPDUSNExtendedSubheader4HarqReordering), - u8MBSContentsIDLength(mMBSContentsIDLength), - u8HARQServiceFlows(mHARQServiceFlows), - u8AuthTokenLength(mAuthTokenLength), - u8HarqChannelMappingLength(mHarqChannelMappingLength), - u8VendorSpecificQoSParamLength(mVendorSpecificQoSParamLength), - bValid(FALSE), - u8TotalClassifiers() -{ -//Remove the bolck after we move to Corr2 only code -#ifdef ENABLE_CORRIGENDUM2_UPDATE - if((g_u32Corr2MacFlags & CORR_2_DSX) || (g_u32Corr2MacFlags & CORR_2_ARQ)) - { - /* IEEE Comment #627 / MTG Comment #426 */ - u16ARQBlockSize = mARQBlockSize; - if(g_u32Corr2MacFlags & CORR_2_ARQ) { - u16ARQRetryTxTimeOut = mARQRetryTimeOutTxDelay; - if(g_u32VENDOR_TYPE == VENDOR_ALCATEL) { - u16ARQRetryRxTimeOut = mARQRetryTimeOutRxDelay_ALU; - } else { - u16ARQRetryRxTimeOut = mARQRetryTimeOutRxDelay; - } - } - else - { - u16ARQRetryTxTimeOut = mARQRetryTimeOutTxDelayCorr1; - u16ARQRetryRxTimeOut = mARQRetryTimeOutRxDelayCorr1; - } - } - else -#endif - { - u16ARQBlockSize = mARQBlockSizeCorr1; - u16ARQRetryTxTimeOut = mARQRetryTimeOutTxDelayCorr1; - u16ARQRetryRxTimeOut = mARQRetryTimeOutRxDelayCorr1; - } -} - - void ComputeMacOverhead(B_UINT8 u8SecOvrhead); - B_UINT16 GetMacOverhead() { return u16MacOverhead; } -#else typedef struct _stServiceFlowParamSI{ -#endif //end of ifdef BECEEM_TARGET /** 32bitSFID Of The Service Flow*/ B_UINT32 u32SFID; @@ -496,35 +317,18 @@ typedef struct _stServiceFlowParamSI{ B_UINT8 bValid; /**< Validity flag */ B_UINT8 u8Padding; /**< Padding byte*/ -#ifdef BECEEM_TARGET -/** -Structure for Convergence SubLayer Types with a maximum of 4 classifiers -*/ - CConvergenceSLTypes cConvergenceSLTypes[MAX_CLASSIFIERS_IN_SF]; -#else /** Structure for Convergence SubLayer Types with a maximum of 4 classifiers */ stConvergenceSLTypes cConvergenceSLTypes[MAX_CLASSIFIERS_IN_SF]; -#endif -#ifdef BECEEM_TARGET -}; -#else } stServiceFlowParamSI, *pstServiceFlowParamSI; typedef stServiceFlowParamSI CServiceFlowParamSI; -#endif /** structure stLocalSFAddRequest */ typedef struct _stLocalSFAddRequest{ -#ifdef BECEEM_TARGET - _stLocalSFAddRequest( ) : - u8Type(0x00), eConnectionDir(0x00), - u16TID(0x0000), u16CID(0x0000), u16VCID(0x0000) - {} -#endif B_UINT8 u8Type; /**< Type*/ B_UINT8 eConnectionDir; /**< Connection direction*/ @@ -535,19 +339,9 @@ typedef struct _stLocalSFAddRequest{ /// \brief 16bitVCID B_UINT16 u16VCID; /**< 16bit VCID*/ /// \brief structure ParameterSet -#ifdef BECEEM_SIGNALLING_INTERFACE_API - CServiceFlowParamSI sfParameterSet; -#endif -#ifdef BECEEM_TARGET - CServiceFlowParamSI *psfParameterSet; -#else stServiceFlowParamSI *psfParameterSet; /**< structure ParameterSet*/ -#endif -#ifdef USING_VXWORKS - USE_DATA_MEMORY_MANAGER(); -#endif }stLocalSFAddRequest, *pstLocalSFAddRequest; @@ -555,12 +349,6 @@ typedef struct _stLocalSFAddRequest{ structure stLocalSFAddIndication */ typedef struct _stLocalSFAddIndication{ -#ifdef BECEEM_TARGET - _stLocalSFAddIndication( ) : - u8Type(0x00), eConnectionDir(0x00), - u16TID(0x0000), u16CID(0x0000), u16VCID(0x0000) - {} -#endif B_UINT8 u8Type; /**< Type*/ B_UINT8 eConnectionDir; /**< Connection Direction*/ @@ -571,37 +359,19 @@ typedef struct _stLocalSFAddIndication{ /// \brief 16bitVCID B_UINT16 u16VCID; /**< 16bitVCID*/ -#ifdef BECEEM_SIGNALLING_INTERFACE_API - CServiceFlowParamSI sfAuthorizedSet; - /// \brief structure AdmittedSet - CServiceFlowParamSI sfAdmittedSet; - /// \brief structure ActiveSet - CServiceFlowParamSI sfActiveSet; -#endif /// \brief structure AuthorizedSet -#ifdef BECEEM_TARGET - CServiceFlowParamSI *psfAuthorizedSet; - /// \brief structure AdmittedSet - CServiceFlowParamSI *psfAdmittedSet; - /// \brief structure ActiveSet - CServiceFlowParamSI *psfActiveSet; -#else /// \brief structure AuthorizedSet stServiceFlowParamSI *psfAuthorizedSet; /**< AuthorizedSet of type stServiceFlowParamSI*/ /// \brief structure AdmittedSet stServiceFlowParamSI *psfAdmittedSet; /**< AdmittedSet of type stServiceFlowParamSI*/ /// \brief structure ActiveSet stServiceFlowParamSI *psfActiveSet; /**< sfActiveSet of type stServiceFlowParamSI*/ -#endif B_UINT8 u8CC; /**< Confirmation Code*/ B_UINT8 u8Padd; /**< 8-bit Padding */ B_UINT16 u16Padd; /**< 16 bit Padding */ -#ifdef USING_VXWORKS - USE_DATA_MEMORY_MANAGER(); -#endif }stLocalSFAddIndication; @@ -619,33 +389,17 @@ typedef struct _stLocalSFAddIndication stLocalSFChangeIndication, *pstLocalSFCha structure stLocalSFDeleteRequest */ typedef struct _stLocalSFDeleteRequest{ -#ifdef BECEEM_TARGET - _stLocalSFDeleteRequest( ) : - u8Type(0x00), u8Padding(0x00), - u16TID(0x0000), u32SFID (0x00000000) - {} -#endif B_UINT8 u8Type; /**< Type*/ B_UINT8 u8Padding; /**< Padding byte*/ B_UINT16 u16TID; /**< TID*/ /// \brief 32bitSFID B_UINT32 u32SFID; /**< SFID*/ -#ifdef USING_VXWORKS - USE_DATA_MEMORY_MANAGER(); -#endif }stLocalSFDeleteRequest, *pstLocalSFDeleteRequest; /** structure stLocalSFDeleteIndication */ typedef struct stLocalSFDeleteIndication{ -#ifdef BECEEM_TARGET - stLocalSFDeleteIndication( ) : - u8Type(0x00), u8Padding(0x00), - u16TID(0x0000), u16CID(0x0000), - u16VCID(0x0000),u32SFID (0x00000000) - {} -#endif B_UINT8 u8Type; /**< Type */ B_UINT8 u8Padding; /**< Padding */ B_UINT16 u16TID; /**< TID */ @@ -658,9 +412,6 @@ typedef struct stLocalSFDeleteIndication{ /// \brief 8bit Confirmation code B_UINT8 u8ConfirmationCode; /**< Confirmation code */ B_UINT8 u8Padding1[3]; /**< 3 byte Padding */ -#ifdef USING_VXWORKS - USE_DATA_MEMORY_MANAGER(); -#endif }stLocalSFDeleteIndication; typedef struct _stIM_SFHostNotify diff --git a/drivers/staging/bcm/headers.h b/drivers/staging/bcm/headers.h index 9d4e3aca1b34..5867db5d0074 100644 --- a/drivers/staging/bcm/headers.h +++ b/drivers/staging/bcm/headers.h @@ -41,21 +41,7 @@ #endif #include #include -#ifndef BCM_SHM_INTERFACE #include -#endif -#ifdef BECEEM_TARGET - -#include -#include -#include -#include -#include -using namespace Beceem; -#ifdef ENABLE_CORRIGENDUM2_UPDATE -extern B_UINT32 g_u32Corr2MacFlags; -#endif -#endif #include "Typedefs.h" #include "Version.h" @@ -80,7 +66,6 @@ extern B_UINT32 g_u32Corr2MacFlags; #include "Queue.h" #include "vendorspecificextn.h" -#ifndef BCM_SHM_INTERFACE #include "InterfaceMacros.h" #include "InterfaceAdapter.h" @@ -89,21 +74,8 @@ extern B_UINT32 g_u32Corr2MacFlags; #include "InterfaceMisc.h" #include "InterfaceRx.h" #include "InterfaceTx.h" -#endif #include "InterfaceIdleMode.h" #include "InterfaceInit.h" -#ifdef BCM_SHM_INTERFACE -#include - -#ifdef GDMA_INTERFACE -#include "GdmaInterface.h" -#include "symphony.h" -#else -#include "virtual_interface.h" - -#endif - -#endif #endif diff --git a/drivers/staging/bcm/led_control.c b/drivers/staging/bcm/led_control.c index 97adaae7dfc0..f2b6939f5178 100644 --- a/drivers/staging/bcm/led_control.c +++ b/drivers/staging/bcm/led_control.c @@ -497,12 +497,10 @@ static int ReadConfigFileStructure(PMINI_ADAPTER Adapter, BOOLEAN *bEnableThread { int Status = STATUS_SUCCESS; UCHAR GPIO_Array[NUM_OF_LEDS+1]; /*Array to store GPIO numbers from EEPROM*/ -#ifndef BCM_SHM_INTERFACE UINT uiIndex = 0; UINT uiNum_of_LED_Type = 0; PUCHAR puCFGData = NULL; UCHAR bData = 0; -#endif memset(GPIO_Array, DISABLE_GPIO_NUM, NUM_OF_LEDS+1); if(!Adapter->pstargetparams || IS_ERR(Adapter->pstargetparams)) @@ -524,10 +522,6 @@ static int ReadConfigFileStructure(PMINI_ADAPTER Adapter, BOOLEAN *bEnableThread *bEnableThread = FALSE; return Status; } -#ifdef BCM_SHM_INTERFACE - *bEnableThread = FALSE; - return Status ; -#else /* * CONFIG file read successfully. Deallocate the memory of * uiFileNameBufferSize @@ -578,7 +572,6 @@ static int ReadConfigFileStructure(PMINI_ADAPTER Adapter, BOOLEAN *bEnableThread } if(uiNum_of_LED_Type >= NUM_OF_LEDS) *bEnableThread = FALSE; -#endif #if 0 for(uiIndex=0; uiIndexeNVMType = NVM_FLASH; -#else BcmValidateNvmType(ps_adapter); BcmInitEEPROMQueues(ps_adapter); -#endif if(ps_adapter->eNVMType == NVM_AUTODETECT) { @@ -3070,7 +3058,6 @@ INT BcmGetFlashCSInfo(PMINI_ADAPTER Adapter) memset(Adapter->psFlashCSInfo, 0 ,sizeof(FLASH_CS_INFO)); memset(Adapter->psFlash2xCSInfo, 0 ,sizeof(FLASH2X_CS_INFO)); -#ifndef BCM_SHM_INTERFACE if(!Adapter->bDDRInitDone) { { @@ -3079,7 +3066,6 @@ INT BcmGetFlashCSInfo(PMINI_ADAPTER Adapter) } } -#endif // Reading first 8 Bytes to get the Flash Layout // MagicNumber(4 bytes) +FlashLayoutMinorVersion(2 Bytes) +FlashLayoutMajorVersion(2 Bytes) @@ -3147,9 +3133,7 @@ INT BcmGetFlashCSInfo(PMINI_ADAPTER Adapter) return STATUS_FAILURE; } ConvertEndianOf2XCSStructure(Adapter->psFlash2xCSInfo); -#ifndef BCM_SHM_INTERFACE BcmDumpFlash2XCSStructure(Adapter->psFlash2xCSInfo,Adapter); -#endif if((FLASH_CONTROL_STRUCT_SIGNATURE == Adapter->psFlash2xCSInfo->MagicNumber) && (SCSI_FIRMWARE_MINOR_VERSION <= MINOR_VERSION(Adapter->psFlash2xCSInfo->SCSIFirmwareVersion)) && (FLASH_SECTOR_SIZE_SIG == Adapter->psFlash2xCSInfo->FlashSectorSizeSig) && @@ -3181,9 +3165,7 @@ INT BcmGetFlashCSInfo(PMINI_ADAPTER Adapter) Concerns: what if CS sector size does not match with this sector size ??? what is the indication of AccessBitMap in CS in flash 2.x ???? */ -#ifndef BCM_SHM_INTERFACE Adapter->ulFlashID = BcmReadFlashRDID(Adapter); -#endif Adapter->uiFlashLayoutMajorVersion = uiFlashLayoutMajorVersion; diff --git a/drivers/staging/bcm/nvm.h b/drivers/staging/bcm/nvm.h index 6ec6ca85b501..88e394520b71 100644 --- a/drivers/staging/bcm/nvm.h +++ b/drivers/staging/bcm/nvm.h @@ -323,15 +323,6 @@ typedef struct _ISO_HEADER -#ifdef BCM_SHM_INTERFACE - -#define FLASH_ADDR_MASK 0x1F000000 -extern int bcmflash_raw_read(unsigned int flash_id, unsigned int offset, unsigned char *inbuf, unsigned int len); -extern int bcmflash_raw_write(unsigned int flash_id, unsigned int offset, unsigned char *outbuf, unsigned int len); -extern int bcmflash_raw_writenoerase(unsigned int flash_id, unsigned int offset, unsigned char *outbuf, unsigned int len); - - -#endif #define FLASH_CONTIGIOUS_START_ADDR_AFTER_INIT 0x1C000000 #define FLASH_CONTIGIOUS_START_ADDR_BEFORE_INIT 0x1F000000 -- cgit v1.2.3 From 5abe61ade9a137b35aa29919334dde7f3a30b248 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Fri, 29 Oct 2010 08:02:08 -0700 Subject: beceem: remove version ifdef's Remove code to support older kernel API's Signed-off-by: Stephen Hemminger --- drivers/staging/bcm/Macros.h | 31 +------------------------------ 1 file changed, 1 insertion(+), 30 deletions(-) diff --git a/drivers/staging/bcm/Macros.h b/drivers/staging/bcm/Macros.h index 5485f574b917..3868e5b94443 100644 --- a/drivers/staging/bcm/Macros.h +++ b/drivers/staging/bcm/Macros.h @@ -4,10 +4,6 @@ #ifndef __MACROS_H__ #define __MACROS_H__ -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) -#define kthread_run(threadfn,data,datafmt)(struct task_struct *)kernel_thread(threadfn,data,0) -#endif - #define TX_TIMER_PERIOD 10 //10 msec #define MAX_CLASSIFIERS 100 //#define MAX_CLASSIFIERS_PER_SF 20 @@ -350,12 +346,7 @@ typedef enum ePMU_MODES HYBRID_MODE_6 = 2 }PMU_MODE; -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,30) -#define MAX_RDM_WRM_RETIRES 16 -#else #define MAX_RDM_WRM_RETIRES 1 -#endif - enum eAbortPattern { ABORT_SHUTDOWN_MODE = 1, @@ -364,27 +355,7 @@ enum eAbortPattern { ABORT_IDLE_SYNCDOWN = 3 }; -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27) - #define GET_BCM_ADAPTER(net_dev) ({\ - PMINI_ADAPTER __Adapter = NULL; \ - if (net_dev) { \ - __Adapter = (PMINI_ADAPTER)(net_dev->priv); \ - } \ - else { \ - __Adapter = NULL; \ - }__Adapter;} ) -#else - #define GET_BCM_ADAPTER(net_dev) ({\ - PMINI_ADAPTER __Adapter = NULL; \ - if (net_dev) { \ - __Adapter = (PMINI_ADAPTER)(*((unsigned long *)netdev_priv(net_dev))); \ - } \ - else { \ - __Adapter = NULL; \ - }__Adapter;}) - - -#endif +#define GET_BCM_ADAPTER(net_dev) (net_dev ? netdev_priv(net_dev) : NULL) /* Offsets used by driver in skb cb variable */ #define SKB_CB_CLASSIFICATION_OFFSET 0 -- cgit v1.2.3 From 047a5f2b503d0ba17704c9714b296cbf06ec087e Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Fri, 29 Oct 2010 08:04:18 -0700 Subject: beceem: eliminate unused USB stubs USB layer does not require these reset function stubs Signed-off-by: Stephen Hemminger --- drivers/staging/bcm/InterfaceInit.c | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/drivers/staging/bcm/InterfaceInit.c b/drivers/staging/bcm/InterfaceInit.c index e6d1dc0d3e43..958d16ad5289 100644 --- a/drivers/staging/bcm/InterfaceInit.c +++ b/drivers/staging/bcm/InterfaceInit.c @@ -814,25 +814,12 @@ static int InterfaceResume (struct usb_interface *intf) return 0; } -static int InterfacePreReset(struct usb_interface *intf) -{ - printk("====================>"); - return STATUS_SUCCESS; -} - -static int InterfacePostReset(struct usb_interface *intf) -{ - printk("Do Post chip reset setting here if it is required"); - return STATUS_SUCCESS; -} static struct usb_driver usbbcm_driver = { .name = "usbbcm", .probe = usbbcm_device_probe, .disconnect = usbbcm_disconnect, .suspend = InterfaceSuspend, .resume = InterfaceResume, - .pre_reset=InterfacePreReset, - .post_reset=InterfacePostReset, .id_table = InterfaceUsbtable, .supports_autosuspend = 1, }; -- cgit v1.2.3 From 2564a148d5326f1d36202e497b3dd0a17422c636 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Fri, 29 Oct 2010 08:11:12 -0700 Subject: beceem: cleanup debug level infrastructure Add module parameter to control debug level and do code cleanup The whole debug stuff should eventually be removed. Signed-off-by: Stephen Hemminger --- drivers/staging/bcm/Debug.c | 59 ++++++++++++++++----------------- drivers/staging/bcm/Debug.h | 66 +++++++++++++++---------------------- drivers/staging/bcm/InterfaceInit.c | 7 +++- 3 files changed, 61 insertions(+), 71 deletions(-) diff --git a/drivers/staging/bcm/Debug.c b/drivers/staging/bcm/Debug.c index 2703f304756d..9f7f70ca1716 100644 --- a/drivers/staging/bcm/Debug.c +++ b/drivers/staging/bcm/Debug.c @@ -1,41 +1,40 @@ #include "headers.h" -static UINT current_debug_level=BCM_SCREAM; - -int bcm_print_buffer( UINT debug_level, const char *function_name, - char *file_name, int line_number, unsigned char *buffer, int bufferlen, enum _BASE_TYPE base) +void bcm_print_buffer(UINT debug_level, const char *function_name, + const char *file_name, int line_number, + const unsigned char *buffer, int bufferlen, + BASE_TYPE base) { + int i; static const char * const buff_dump_base[] = { "DEC", "HEX", "OCT", "BIN" }; - if(debug_level>=current_debug_level) - { - int i=0; - printk("\n%s:%s:%d:Buffer dump of size 0x%x in the %s:\n", file_name, function_name, line_number, bufferlen, buff_dump_base[1]); - for(;istDebugState.debug_level) && \ - ((Type & Adapter->stDebugState.type) && (SubType & Adapter->stDebugState.subtype[Type]))) { \ - if (dbg_level & DBG_NO_FUNC_PRINT) \ - printk (string, ##args); \ - else \ - { \ - printk ("%s:" string, __FUNCTION__, ##args); \ - printk("\n"); \ - } \ - } \ - } \ -} while (0) -#define BCM_DEBUG_PRINT_BUFFER(Adapter, Type, SubType, dbg_level, buffer, bufferlen) do { \ - if ((DBG_TYPE_PRINTK == Type) && (PRINTKS_ON)) { \ - bcm_print_buffer( dbg_level, __FUNCTION__, __FILE__, __LINE__, buffer, bufferlen, BCM_BASE_TYPE_HEX); \ - } else if (!Adapter) \ - ; \ - else { \ - if (((dbg_level & DBG_LVL_BITMASK) <= Adapter->stDebugState.debug_level) && \ - ((Type & Adapter->stDebugState.type) && (SubType & Adapter->stDebugState.subtype[Type]))) { \ - if (dbg_level & DBG_NO_FUNC_PRINT) \ - bcm_print_buffer( dbg_level, NULL, NULL, __LINE__, buffer, bufferlen, BCM_BASE_TYPE_HEX); \ - else \ - bcm_print_buffer( dbg_level, __FUNCTION__, __FILE__, __LINE__, buffer, bufferlen, BCM_BASE_TYPE_HEX); \ - } \ - } \ +#define BCM_DEBUG_PRINT(Adapter, Type, SubType, dbg_level, string, args...) \ + do { \ + if (DBG_TYPE_PRINTK == Type) \ + pr_info("%s:" string "\n", __func__, ##args); \ + else if (Adapter && \ + (dbg_level & DBG_LVL_BITMASK) <= Adapter->stDebugState.debug_level && \ + (Type & Adapter->stDebugState.type) && \ + (SubType & Adapter->stDebugState.subtype[Type])) { \ + if (dbg_level & DBG_NO_FUNC_PRINT) \ + printk(KERN_DEBUG string, ##args); \ + else \ + printk(KERN_DEBUG "%s:" string "\n", __func__, ##args); \ + } \ } while (0) +#define BCM_DEBUG_PRINT_BUFFER(Adapter, Type, SubType, dbg_level, buffer, bufferlen) do { \ + if (DBG_TYPE_PRINTK == Type || \ + (Adapter && \ + (dbg_level & DBG_LVL_BITMASK) <= Adapter->stDebugState.debug_level && \ + (Type & Adapter->stDebugState.type) && \ + (SubType & Adapter->stDebugState.subtype[Type]))) \ + bcm_print_buffer(dbg_level, __func__, __FILE__, __LINE__, \ + buffer, bufferlen, BCM_BASE_TYPE_HEX); \ +} while(0) + #define BCM_SHOW_DEBUG_BITMAP(Adapter) do { \ int i; \ diff --git a/drivers/staging/bcm/InterfaceInit.c b/drivers/staging/bcm/InterfaceInit.c index 958d16ad5289..f810bfd0b1a5 100644 --- a/drivers/staging/bcm/InterfaceInit.c +++ b/drivers/staging/bcm/InterfaceInit.c @@ -11,6 +11,11 @@ static struct usb_device_id InterfaceUsbtable[] = { }; MODULE_DEVICE_TABLE(usb, InterfaceUsbtable); +static unsigned int debug_level = DBG_LVL_CURR; +module_param(debug_level, uint, 0644); +MODULE_PARM_DESC(debug_level, "Debug level (0=none,...,7=all)"); + + VOID InterfaceAdapterFree(PS_INTERFACE_ADAPTER psIntfAdapter) { INT i = 0; @@ -198,7 +203,7 @@ usbbcm_device_probe(struct usb_interface *intf, const struct usb_device_id *id) /* Init default driver debug state */ - psAdapter->stDebugState.debug_level = DBG_LVL_CURR; + psAdapter->stDebugState.debug_level = debug_level; psAdapter->stDebugState.type = DBG_TYPE_INITEXIT; memset (psAdapter->stDebugState.subtype, 0, sizeof (psAdapter->stDebugState.subtype)); -- cgit v1.2.3 From 3705a843bd98b3ccb7c4b6addfc182fe805a73ed Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Fri, 29 Oct 2010 08:14:16 -0700 Subject: beceem: remove bogus network device notifier Network device should not be messing with refcounts directly. See Documentation/networking/netdevices.txt Signed-off-by: Stephen Hemminger --- drivers/staging/bcm/Adapter.h | 2 +- drivers/staging/bcm/Bcmnet.c | 64 ------------------------------------------- drivers/staging/bcm/Debug.c | 1 - drivers/staging/bcm/headers.h | 1 - 4 files changed, 1 insertion(+), 67 deletions(-) diff --git a/drivers/staging/bcm/Adapter.h b/drivers/staging/bcm/Adapter.h index 748460e898d8..eebb77f9413e 100644 --- a/drivers/staging/bcm/Adapter.h +++ b/drivers/staging/bcm/Adapter.h @@ -600,7 +600,7 @@ struct _MINI_ADAPTER struct semaphore NVMRdmWrmLock; BOOLEAN bNetworkInterfaceRegistered; - BOOLEAN bNetdeviceNotifierRegistered; + struct device *pstCreatedClassDevice; BOOLEAN bUsbClassDriverRegistered; // BOOLEAN InterfaceUpStatus; diff --git a/drivers/staging/bcm/Bcmnet.c b/drivers/staging/bcm/Bcmnet.c index 3262aff8dd4a..ce975d7f221f 100644 --- a/drivers/staging/bcm/Bcmnet.c +++ b/drivers/staging/bcm/Bcmnet.c @@ -4,48 +4,6 @@ #define DRV_VERSION "5.2.7.3P1" #define DRV_COPYRIGHT "Copyright 2010. Beceem Communications Inc" -static INT bcm_notify_event(struct notifier_block *nb, ULONG event, PVOID dev) -{ - struct net_device *ndev = (struct net_device*)dev; - PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); - //PMINI_ADAPTER Adapter = (PMINI_ADAPTER)ndev->priv; - if(strncmp(ndev->name,gblpnetdev->name,5)==0) - { - switch(event) - { - case NETDEV_CHANGEADDR: - case NETDEV_GOING_DOWN: - /*ignore this */ - break; - case NETDEV_DOWN: - break; - - case NETDEV_UP: - break; - - case NETDEV_REGISTER: - /* Increment the Reference Count for "veth0" */ - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Register RefCount: %x\n", - netdev_refcnt_read(ndev)); - dev_hold(ndev); - break; - - case NETDEV_UNREGISTER: - /* Decrement the Reference Count for "veth0" */ - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Unregister RefCnt: %x\n", - netdev_refcnt_read(ndev)); - dev_put(ndev); - break; - }; - } - return NOTIFY_DONE; -} - -/* Notifier block to receive netdevice events */ -static struct notifier_block bcm_notifier_block = -{ - .notifier_call = bcm_notify_event, -}; struct net_device *gblpnetdev; /***************************************************************************************/ @@ -156,23 +114,6 @@ int register_networkdev(PMINI_ADAPTER Adapter) /* Read the MAC Address from EEPROM */ ReadMacAddressFromNVM(Adapter); - - /* Register the notifier block for getting netdevice events */ - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Registering netdevice notifier\n"); - result = register_netdevice_notifier(&bcm_notifier_block); - if(result) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "BCM Notifier Block did not get registered"); - Adapter->bNetdeviceNotifierRegistered = FALSE; - return result; - } - else - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "BCM Notifier got Registered"); - Adapter->bNetdeviceNotifierRegistered = TRUE; - } - - result = register_netdev(Adapter->dev); if (!result) { @@ -209,11 +150,6 @@ void bcm_unregister_networkdev(PMINI_ADAPTER Adapter) if(Adapter->dev && !IS_ERR(Adapter->dev) && Adapter->bNetworkInterfaceRegistered) unregister_netdev(Adapter->dev); /* Unregister the notifier block */ - if(Adapter->bNetdeviceNotifierRegistered == TRUE) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Unregistering netdevice notifier\n"); - unregister_netdevice_notifier(&bcm_notifier_block); - } } static int bcm_init(void) diff --git a/drivers/staging/bcm/Debug.c b/drivers/staging/bcm/Debug.c index 9f7f70ca1716..b86d8456cf7d 100644 --- a/drivers/staging/bcm/Debug.c +++ b/drivers/staging/bcm/Debug.c @@ -37,4 +37,3 @@ void bcm_print_buffer(UINT debug_level, const char *function_name, printk("\n"); } } - diff --git a/drivers/staging/bcm/headers.h b/drivers/staging/bcm/headers.h index 5867db5d0074..1a9bdf697420 100644 --- a/drivers/staging/bcm/headers.h +++ b/drivers/staging/bcm/headers.h @@ -22,7 +22,6 @@ #include #include #include -#include #include #include -- cgit v1.2.3 From d52db0b4b34410019e1546e3ccbe761b9e4ddd76 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Fri, 29 Oct 2010 08:18:27 -0700 Subject: beceem: eliminate network registered state variable Just use presence of pointer Signed-off-by: Stephen Hemminger --- drivers/staging/bcm/Adapter.h | 1 - drivers/staging/bcm/Bcmnet.c | 34 +++++++--------------------------- 2 files changed, 7 insertions(+), 28 deletions(-) diff --git a/drivers/staging/bcm/Adapter.h b/drivers/staging/bcm/Adapter.h index eebb77f9413e..055ff1cb39d9 100644 --- a/drivers/staging/bcm/Adapter.h +++ b/drivers/staging/bcm/Adapter.h @@ -599,7 +599,6 @@ struct _MINI_ADAPTER struct semaphore NVMRdmWrmLock; - BOOLEAN bNetworkInterfaceRegistered; struct device *pstCreatedClassDevice; BOOLEAN bUsbClassDriverRegistered; diff --git a/drivers/staging/bcm/Bcmnet.c b/drivers/staging/bcm/Bcmnet.c index ce975d7f221f..4785d25874b9 100644 --- a/drivers/staging/bcm/Bcmnet.c +++ b/drivers/staging/bcm/Bcmnet.c @@ -115,41 +115,21 @@ int register_networkdev(PMINI_ADAPTER Adapter) ReadMacAddressFromNVM(Adapter); result = register_netdev(Adapter->dev); - if (!result) - { - Adapter->bNetworkInterfaceRegistered = TRUE ; - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Beceem Network device name is %s!", Adapter->dev->name); - } - else - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Network device can not be registered!"); - Adapter->bNetworkInterfaceRegistered = FALSE ; - return result; + if (!result) { + free_netdev(Adapter->dev); + Adapter->dev = NULL; } -#if 0 - Adapter->stDebugState.debug_level = DBG_LVL_CURR; - Adapter->stDebugState.type =(UINT)0xffffffff; - Adapter->stDebugState.subtype[DBG_TYPE_OTHERS] = 0xffffffff; - Adapter->stDebugState.subtype[DBG_TYPE_RX] = 0xffffffff; - Adapter->stDebugState.subtype[DBG_TYPE_TX] = 0xffffffff; - Adapter->stDebugState.subtype[DBG_TYPE_INITEXIT] = 0xffffffff; - - printk("-------ps_adapter->stDebugState.type=%x\n",Adapter->stDebugState.type); - printk("-------ps_adapter->stDebugState.subtype[DBG_TYPE_OTHERS]=%x\n",Adapter->stDebugState.subtype[DBG_TYPE_OTHERS]); - printk("-------ps_adapter->stDebugState.subtype[DBG_TYPE_RX]=%x\n",Adapter->stDebugState.subtype[DBG_TYPE_RX]); - printk("-------ps_adapter->stDebugState.subtype[DBG_TYPE_TX]=%x\n",Adapter->stDebugState.subtype[DBG_TYPE_TX]); -#endif - - return 0; + return result; } void bcm_unregister_networkdev(PMINI_ADAPTER Adapter) { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Unregistering the Net Dev...\n"); - if(Adapter->dev && !IS_ERR(Adapter->dev) && Adapter->bNetworkInterfaceRegistered) + if(Adapter->dev) { unregister_netdev(Adapter->dev); - /* Unregister the notifier block */ + Adapter->dev = NULL; + } } static int bcm_init(void) -- cgit v1.2.3 From 2b5e625882a7130c339e4ad2ac2b8f0422f11919 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Fri, 29 Oct 2010 08:20:11 -0700 Subject: beceem: eliminate dead code Get rid of empty header file and unused declarations Signed-off-by: Stephen Hemminger --- drivers/staging/bcm/InterfaceInit.h | 18 ------- drivers/staging/bcm/Interfacemain.h | 10 ---- drivers/staging/bcm/cntrl_SignalingInterface.h | 5 -- drivers/staging/bcm/headers.h | 1 - drivers/staging/bcm/nvm.h | 71 -------------------------- 5 files changed, 105 deletions(-) delete mode 100644 drivers/staging/bcm/Interfacemain.h diff --git a/drivers/staging/bcm/InterfaceInit.h b/drivers/staging/bcm/InterfaceInit.h index a11af81d74d9..71e629d29c79 100644 --- a/drivers/staging/bcm/InterfaceInit.h +++ b/drivers/staging/bcm/InterfaceInit.h @@ -25,23 +25,5 @@ INT usbbcm_worker_thread(PS_INTERFACE_ADAPTER psIntfAdapter); VOID InterfaceAdapterFree(PS_INTERFACE_ADAPTER psIntfAdapter); - - -#if 0 - -ULONG InterfaceClaimAdapter(PMINI_ADAPTER Adapter); - -VOID InterfaceDDRControllerInit(PMINI_ADAPTER Adapter); - -ULONG InterfaceReset(PMINI_ADAPTER Adapter); - -ULONG InterfaceRegisterResources(PMINI_ADAPTER Adapter); - -VOID InterfaceUnRegisterResources(PMINI_ADAPTER Adapter); - -ULONG InterfaceFirmwareDownload(PMINI_ADAPTER Adapter); - -#endif - #endif diff --git a/drivers/staging/bcm/Interfacemain.h b/drivers/staging/bcm/Interfacemain.h deleted file mode 100644 index e0db563c5e0f..000000000000 --- a/drivers/staging/bcm/Interfacemain.h +++ /dev/null @@ -1,10 +0,0 @@ -#ifndef _MAIN_ -#define _MAIN_ -#if 0 -typedef struct _MINI_ADAPTER -{ - S_INTERFACE_ADAPTER stInterfaceAdapter; -}MINI_ADAPTER,*PMINI_ADAPTER; - -#endif -#endif diff --git a/drivers/staging/bcm/cntrl_SignalingInterface.h b/drivers/staging/bcm/cntrl_SignalingInterface.h index 7c47af7729f6..890778450a86 100644 --- a/drivers/staging/bcm/cntrl_SignalingInterface.h +++ b/drivers/staging/bcm/cntrl_SignalingInterface.h @@ -188,11 +188,6 @@ typedef struct _stServiceFlowParamSI{ /** 16bit ARQ Purge timeout */ B_UINT16 u16ARQRxPurgeTimeOut; -#if 0 //def ENABLE_CORRIGENDUM2_UPDATE -/* IEEE Comment #627 / MTG Comment #426 */ - /// \brief Size of an ARQ block, changed from 2 bytes to 1 - B_UINT8 u8ARQBlockSize; -#endif //TODO::Remove this once we move to a new CORR2 driver /// \brief Size of an ARQ block B_UINT16 u16ARQBlockSize; diff --git a/drivers/staging/bcm/headers.h b/drivers/staging/bcm/headers.h index 1a9bdf697420..b90d8a3e879b 100644 --- a/drivers/staging/bcm/headers.h +++ b/drivers/staging/bcm/headers.h @@ -69,7 +69,6 @@ #include "InterfaceMacros.h" #include "InterfaceAdapter.h" #include "InterfaceIsr.h" -#include "Interfacemain.h" #include "InterfaceMisc.h" #include "InterfaceRx.h" #include "InterfaceTx.h" diff --git a/drivers/staging/bcm/nvm.h b/drivers/staging/bcm/nvm.h index 88e394520b71..651b5a455b32 100644 --- a/drivers/staging/bcm/nvm.h +++ b/drivers/staging/bcm/nvm.h @@ -405,76 +405,5 @@ typedef struct _ISO_HEADER #define FIELD_OFFSET_IN_HEADER(HeaderPointer,Field) ((PUCHAR)&((HeaderPointer)(NULL))->Field - (PUCHAR)(NULL)) -#if 0 -INT BeceemEEPROMBulkRead( - PMINI_ADAPTER Adapter, - PUINT pBuffer, - UINT uiOffset, - UINT uiNumBytes); - - -INT BeceemFlashBulkRead( - PMINI_ADAPTER Adapter, - PUINT pBuffer, - UINT uiOffset, - UINT uiNumBytes); - -UINT BcmGetEEPROMSize(PMINI_ADAPTER Adapter); - -UINT BcmGetFlashSize(PMINI_ADAPTER Adapter); - -UINT BcmGetFlashSectorSize(PMINI_ADAPTER Adapter); - - - -INT BeceemFlashBulkWrite( - PMINI_ADAPTER Adapter, - PUINT pBuffer, - UINT uiOffset, - UINT uiNumBytes, - BOOLEAN bVerify); - -INT PropagateCalParamsFromFlashToMemory(PMINI_ADAPTER Adapter); - -INT PropagateCalParamsFromEEPROMToMemory(PMINI_ADAPTER Adapter); - - -INT BeceemEEPROMBulkWrite( - PMINI_ADAPTER Adapter, - PUCHAR pBuffer, - UINT uiOffset, - UINT uiNumBytes, - BOOLEAN bVerify); - - -INT ReadBeceemEEPROM(PMINI_ADAPTER Adapter,UINT dwAddress, UINT *pdwData); - -NVM_TYPE BcmGetNvmType(PMINI_ADAPTER Adapter); - -INT BeceemNVMRead( - PMINI_ADAPTER Adapter, - PUINT pBuffer, - UINT uiOffset, - UINT uiNumBytes); - -INT BeceemNVMWrite( - PMINI_ADAPTER Adapter, - PUINT pBuffer, - UINT uiOffset, - UINT uiNumBytes, - BOOLEAN bVerify); - -INT ReadMacAddressFromEEPROM(PMINI_ADAPTER Adapter); - -INT BcmUpdateSectorSize(PMINI_ADAPTER Adapter,UINT uiSectorSize); - -INT BcmInitNVM(PMINI_ADAPTER Adapter); - -VOID BcmValidateNvmType(PMINI_ADAPTER Adapter); - -VOID BcmGetFlashCSInfo(PMINI_ADAPTER Adapter); - -#endif - #endif -- cgit v1.2.3 From 92bc60580e55d18494a23ba8ae642a464ebfd7a6 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Fri, 29 Oct 2010 08:22:10 -0700 Subject: beceem: get rid of OS dependent data structure The only part of this structure still used was the network device stats, and in recent kernel these are available in network device itself. Signed-off-by: Stephen Hemminger --- drivers/staging/bcm/Adapter.h | 14 ++----------- drivers/staging/bcm/Bcmnet.c | 33 ++++++++++++++----------------- drivers/staging/bcm/HandleControlPacket.c | 3 --- drivers/staging/bcm/Misc.c | 16 ++------------- drivers/staging/bcm/Qos.c | 10 ++++------ drivers/staging/bcm/Transmit.c | 3 --- 6 files changed, 23 insertions(+), 56 deletions(-) diff --git a/drivers/staging/bcm/Adapter.h b/drivers/staging/bcm/Adapter.h index 055ff1cb39d9..9c9dff3e0daa 100644 --- a/drivers/staging/bcm/Adapter.h +++ b/drivers/staging/bcm/Adapter.h @@ -43,17 +43,6 @@ typedef struct _BCM_CB BCM_CB,*PBCM_CB; typedef BCM_CB BCM_RCB, *PBCM_RCB; typedef BCM_CB BCM_TCB, *PBCM_TCB; -/* This is to be stored in the "pvOsDepData" of ADAPTER */ -typedef struct LINUX_DEP_DATA -{ - struct net_device *virtualdev; /* Our Interface (veth0) */ - struct net_device *actualdev; /* True Interface (eth0) */ - struct net_device_stats netstats; /* Net statistics */ - struct fasync_struct *async_queue; /* For asynchronus notification */ - -} LINUX_DEP_DATA, *PLINUX_DEP_DATA; - - struct _LEADER { USHORT Vcid; @@ -429,7 +418,7 @@ Driver adapter data structure struct _MINI_ADAPTER { struct _MINI_ADAPTER *next; - PVOID pvOsDepData; + CHAR *caDsxReqResp; atomic_t ApplicationRunning; volatile INT CtrlQueueLen; @@ -629,6 +618,7 @@ struct _MINI_ADAPTER struct semaphore LowPowerModeSync; ULONG liDrainCalculated; UINT gpioBitMap; + S_BCM_DEBUG_STATE stDebugState; }; diff --git a/drivers/staging/bcm/Bcmnet.c b/drivers/staging/bcm/Bcmnet.c index 4785d25874b9..670a7a4df364 100644 --- a/drivers/staging/bcm/Bcmnet.c +++ b/drivers/staging/bcm/Bcmnet.c @@ -44,24 +44,21 @@ static INT bcm_close(struct net_device *dev) static struct net_device_stats *bcm_get_stats(struct net_device *dev) { - PLINUX_DEP_DATA pLinuxData=NULL; - PMINI_ADAPTER Adapter = NULL ;// gpadapter ; - Adapter = GET_BCM_ADAPTER(dev); - pLinuxData = (PLINUX_DEP_DATA)(Adapter->pvOsDepData); - - //BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Dev = %p, pLinuxData = %p", dev, pLinuxData); - pLinuxData->netstats.rx_packets=atomic_read(&Adapter->RxRollOverCount)*64*1024+Adapter->PrevNumRecvDescs; - pLinuxData->netstats.rx_bytes=atomic_read(&Adapter->GoodRxByteCount)+atomic_read(&Adapter->BadRxByteCount); - pLinuxData->netstats.rx_dropped=atomic_read(&Adapter->RxPacketDroppedCount); - pLinuxData->netstats.rx_errors=atomic_read(&Adapter->RxPacketDroppedCount); - pLinuxData->netstats.rx_length_errors=0; - pLinuxData->netstats.rx_frame_errors=0; - pLinuxData->netstats.rx_crc_errors=0; - pLinuxData->netstats.tx_bytes=atomic_read(&Adapter->GoodTxByteCount); - pLinuxData->netstats.tx_packets=atomic_read(&Adapter->TxTotalPacketCount); - pLinuxData->netstats.tx_dropped=atomic_read(&Adapter->TxDroppedPacketCount); - - return &(pLinuxData->netstats); + PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(dev); + struct net_device_stats* netstats = &dev->stats; + + netstats->rx_packets = atomic_read(&Adapter->RxRollOverCount)*64*1024 + + Adapter->PrevNumRecvDescs; + netstats->rx_bytes = atomic_read(&Adapter->GoodRxByteCount) + + atomic_read(&Adapter->BadRxByteCount); + + netstats->rx_dropped = atomic_read(&Adapter->RxPacketDroppedCount); + netstats->rx_errors = atomic_read(&Adapter->RxPacketDroppedCount); + netstats->tx_bytes = atomic_read(&Adapter->GoodTxByteCount); + netstats->tx_packets = atomic_read(&Adapter->TxTotalPacketCount); + netstats->tx_dropped = atomic_read(&Adapter->TxDroppedPacketCount); + + return netstats; } /** @ingroup init_functions diff --git a/drivers/staging/bcm/HandleControlPacket.c b/drivers/staging/bcm/HandleControlPacket.c index 7b2ec28a4bc1..5dd88f98caa8 100644 --- a/drivers/staging/bcm/HandleControlPacket.c +++ b/drivers/staging/bcm/HandleControlPacket.c @@ -185,9 +185,6 @@ int control_packet_handler (PMINI_ADAPTER Adapter /**< pointer to adapter obje { DEQUEUEPACKET(Adapter->RxControlHead,Adapter->RxControlTail); // Adapter->RxControlHead=ctrl_packet->next; - ((PLINUX_DEP_DATA)Adapter->pvOsDepData)->netstats.rx_packets++; - ((PLINUX_DEP_DATA)Adapter->pvOsDepData)->netstats.rx_bytes+= - ((PLEADER)ctrl_packet->data)->PLength; } #if 0 //Idle mode debug profiling... if(*(PUSHORT)ctrl_packet->data == IDLE_MODE_STATUS) diff --git a/drivers/staging/bcm/Misc.c b/drivers/staging/bcm/Misc.c index cedeb8c3723e..351a8aee88fe 100644 --- a/drivers/staging/bcm/Misc.c +++ b/drivers/staging/bcm/Misc.c @@ -60,15 +60,6 @@ InitAdapter(PMINI_ADAPTER psAdapter) //init_waitqueue_head(&psAdapter->device_wake_queue); psAdapter->fw_download_done=FALSE; - psAdapter->pvOsDepData = (PLINUX_DEP_DATA) kmalloc(sizeof(LINUX_DEP_DATA), - GFP_KERNEL); - - if(psAdapter->pvOsDepData == NULL) - { - BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Linux Specific Data allocation failed"); - return -ENOMEM; - } - memset(psAdapter->pvOsDepData, 0, sizeof(LINUX_DEP_DATA)); default_wimax_protocol_initialize(psAdapter); for (i=0;itxctlpacket[count]); } FreeAdapterDsxBuffer(Adapter); - if(Adapter->pvOsDepData) - bcm_kfree (Adapter->pvOsDepData); + if(Adapter->pvInterfaceAdapter) bcm_kfree(Adapter->pvInterfaceAdapter); @@ -1969,9 +1959,7 @@ void update_per_sf_desc_cnts( PMINI_ADAPTER Adapter) void flush_queue(PMINI_ADAPTER Adapter, UINT iQIndex) { struct sk_buff* PacketToDrop=NULL; - struct net_device_stats* netstats=NULL; - - netstats = &((PLINUX_DEP_DATA)Adapter->pvOsDepData)->netstats; + struct net_device_stats* netstats = &Adapter->dev->stats; spin_lock_bh(&Adapter->PackInfo[iQIndex].SFQueueLock); diff --git a/drivers/staging/bcm/Qos.c b/drivers/staging/bcm/Qos.c index 75b2b879633f..a86a38c33f2e 100644 --- a/drivers/staging/bcm/Qos.c +++ b/drivers/staging/bcm/Qos.c @@ -362,18 +362,18 @@ VOID PruneQueue(PMINI_ADAPTER Adapter,/** Index %d",iIndex); if(iIndex == HiPriority) - return; + return; if(!Adapter || (iIndex < 0) || (iIndex > HiPriority)) return; /* To Store the netdevice statistic */ - netstats = &((PLINUX_DEP_DATA)Adapter->pvOsDepData)->netstats; + netstats = &Adapter->dev->stats; spin_lock_bh(&Adapter->PackInfo[iIndex].SFQueueLock); @@ -431,11 +431,9 @@ VOID flush_all_queues(PMINI_ADAPTER Adapter) INT iQIndex; UINT uiTotalPacketLength; struct sk_buff* PacketToDrop=NULL; - struct net_device_stats* netstats=NULL; + struct net_device_stats* netstats=&Adapter->dev->stats; BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "=====>"); - /* To Store the netdevice statistic */ - netstats = &((PLINUX_DEP_DATA)Adapter->pvOsDepData)->netstats; // down(&Adapter->data_packet_queue_lock); for(iQIndex=LowPriority; iQIndexinterface_transmit(Adapter->pvInterfaceAdapter, pControlPacket, (PLeader->PLength + LEADER_SIZE)); - ((PLINUX_DEP_DATA)Adapter->pvOsDepData)->netstats.tx_packets++; - ((PLINUX_DEP_DATA)Adapter->pvOsDepData)->netstats.tx_bytes+= - PLeader->PLength; atomic_dec(&Adapter->CurrNumFreeTxDesc); BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "<========="); return STATUS_SUCCESS; -- cgit v1.2.3 From 0ad008fcbc39572ab7078975cdf7e902fbc39ce6 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Fri, 29 Oct 2010 16:44:07 -0700 Subject: beceem: cleanup network device setup Change how network device is setup: * set pointer to device object so sysfs has eth0/device symlink * set network device type * eliminate all the compatiablity with older kernels. Signed-off-by: Stephen Hemminger --- drivers/staging/bcm/Bcmnet.c | 73 +++++++++++++++++++++----------------------- 1 file changed, 35 insertions(+), 38 deletions(-) diff --git a/drivers/staging/bcm/Bcmnet.c b/drivers/staging/bcm/Bcmnet.c index 670a7a4df364..b4e729b57e67 100644 --- a/drivers/staging/bcm/Bcmnet.c +++ b/drivers/staging/bcm/Bcmnet.c @@ -11,8 +11,8 @@ struct net_device *gblpnetdev; static INT bcm_open(struct net_device *dev) { - PMINI_ADAPTER Adapter = NULL ; //(PMINI_ADAPTER)dev->priv; - Adapter = GET_BCM_ADAPTER(dev); + PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(dev); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "======>"); if(Adapter->fw_download_done==FALSE) return -EINVAL; @@ -30,8 +30,8 @@ static INT bcm_open(struct net_device *dev) static INT bcm_close(struct net_device *dev) { - PMINI_ADAPTER Adapter = NULL ;//gpadapter ; - Adapter = GET_BCM_ADAPTER(dev); + PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(dev); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "=====>"); Adapter->if_up=0; if(!netif_queue_stopped(dev)) { @@ -60,12 +60,12 @@ static struct net_device_stats *bcm_get_stats(struct net_device *dev) return netstats; } + /** @ingroup init_functions Register other driver entry points with the kernel */ -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29) -static struct net_device_ops bcmNetDevOps = { +static const struct net_device_ops bcmNetDevOps = { .ndo_open = bcm_open, .ndo_stop = bcm_close, .ndo_get_stats = bcm_get_stats, @@ -74,47 +74,44 @@ static struct net_device_ops bcmNetDevOps = { .ndo_set_mac_address = eth_mac_addr, .ndo_validate_addr = eth_validate_addr, }; -#endif + +static struct device_type wimax_type = { + .name = "wimax", +}; int register_networkdev(PMINI_ADAPTER Adapter) { - int result=0; -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27) - void **temp = NULL; /* actually we're *allocating* the device in alloc_etherdev */ -#endif - Adapter->dev = alloc_etherdev(sizeof(PMINI_ADAPTER)); - if(!Adapter->dev) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "ERR: No Dev"); + struct net_device *net; + PMINI_ADAPTER *temp; + PS_INTERFACE_ADAPTER psIntfAdapter = Adapter->pvInterfaceAdapter; + struct usb_interface *uintf = psIntfAdapter->interface; + int result; + + net = alloc_etherdev(sizeof(PMINI_ADAPTER)); + if(!net) { + pr_notice("bcmnet: no memory for device\n"); return -ENOMEM; } - gblpnetdev = Adapter->dev; -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,27) - Adapter->dev->priv = Adapter; -#else - temp = netdev_priv(Adapter->dev); - *temp = (void *)Adapter; -#endif - //BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "init adapterptr: %x %x\n", (UINT)Adapter, temp); - -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 29) - Adapter->dev->netdev_ops = &bcmNetDevOps; -#else - Adapter->dev->open = bcm_open; - Adapter->dev->stop = bcm_close; - Adapter->dev->get_stats = bcm_get_stats; - Adapter->dev->hard_start_xmit = bcm_transmit; - Adapter->dev->hard_header_len = ETH_HLEN + LEADER_SIZE; -#endif - - Adapter->dev->mtu = MTU_SIZE; /* 1400 Bytes */ + + Adapter->dev = net; /* FIXME - only allows one adapter! */ + temp = netdev_priv(net); + *temp = Adapter; + + net->netdev_ops = &bcmNetDevOps; + net->mtu = MTU_SIZE; /* 1400 Bytes */ + + SET_NETDEV_DEV(net, &uintf->dev); + SET_NETDEV_DEVTYPE(net, &wimax_type); + /* Read the MAC Address from EEPROM */ ReadMacAddressFromNVM(Adapter); - result = register_netdev(Adapter->dev); - if (!result) { - free_netdev(Adapter->dev); + result = register_netdev(net); + if (result == 0) + gblpnetdev = Adapter->dev = net; + else { Adapter->dev = NULL; + free_netdev(net); } return result; -- cgit v1.2.3 From bf01ca1b35ff26a4c16c22b9ce7554f0d3a45ba7 Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Sat, 30 Oct 2010 15:32:32 +0200 Subject: VIA Chrome camera: remove duplicate includes The VIA Chrome integrated camera controller driver includes both 'linux/pci.h' and 'linux/device.h' twice. This gets rid of the duplicates. Signed-off-by: Jesper Juhl Acked-by: Jonathan Corbet Signed-off-by: Jiri Kosina --- drivers/media/video/via-camera.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/media/video/via-camera.c b/drivers/media/video/via-camera.c index 02a21bccae18..6f52818d5917 100644 --- a/drivers/media/video/via-camera.c +++ b/drivers/media/video/via-camera.c @@ -13,14 +13,12 @@ #include #include #include -#include #include #include #include #include #include #include -#include #include #include #include -- cgit v1.2.3 From ff75b9bc489710ff223bc0d805bf3b862dc347ea Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sat, 30 Oct 2010 22:52:31 +0100 Subject: drm/i915: Fix typo from e5281ccd in i915_gem_attach_phys_object() Accessing the uninitialised obj->pages instead of the local page lead to an OOPs. Reported-by: Xavier Chantry Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_gem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 936ddd83f8a2..e3fc333e2e57 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -4925,7 +4925,7 @@ i915_gem_attach_phys_object(struct drm_device *dev, if (IS_ERR(page)) return PTR_ERR(page); - src = kmap_atomic(obj_priv->pages[i]); + src = kmap_atomic(page); dst = obj_priv->phys_obj->handle->vaddr + (i * PAGE_SIZE); memcpy(dst, src, PAGE_SIZE); kunmap_atomic(src); -- cgit v1.2.3 From 5eac3ab45955b32f3a9d89e633918c4d6f133dfa Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sun, 31 Oct 2010 08:49:47 +0000 Subject: drm/i915: Evict just the purgeable GTT entries on the first pass Take two passes to evict everything whilst searching for sufficient free space to bind the batchbuffer. After searching for sufficient free space using LRU eviction, evict everything that is purgeable and try again. Only then if there is insufficient free space (or the GTT is too badly fragmented) evict everything from the aperture and try one last time. Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_drv.h | 4 ++-- drivers/gpu/drm/i915/i915_gem.c | 19 ++++++++-------- drivers/gpu/drm/i915/i915_gem_evict.c | 42 +++++++++++------------------------ 3 files changed, 25 insertions(+), 40 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index ec582b6d2113..54e5b2fa5fd4 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1073,8 +1073,8 @@ void i915_gem_release(struct drm_device * dev, struct drm_file *file_priv); /* i915_gem_evict.c */ int i915_gem_evict_something(struct drm_device *dev, int min_size, unsigned alignment, bool mappable); -int i915_gem_evict_everything(struct drm_device *dev); -int i915_gem_evict_inactive(struct drm_device *dev); +int i915_gem_evict_everything(struct drm_device *dev, bool purgeable_only); +int i915_gem_evict_inactive(struct drm_device *dev, bool purgeable_only); /* i915_gem_tiling.c */ void i915_gem_detect_bit_6_swizzle(struct drm_device *dev); diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index e3fc333e2e57..c8e516d3f8bc 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -3519,7 +3519,8 @@ i915_gem_execbuffer_pin(struct drm_device *dev, int ret, i, retry; /* attempt to pin all of the buffers into the GTT */ - for (retry = 0; retry < 2; retry++) { + retry = 0; + do { ret = 0; for (i = 0; i < count; i++) { struct drm_i915_gem_exec_object2 *entry = &exec_list[i]; @@ -3567,18 +3568,18 @@ i915_gem_execbuffer_pin(struct drm_device *dev, while (i--) i915_gem_object_unpin(object_list[i]); - if (ret == 0) - break; - - if (ret != -ENOSPC || retry) + if (ret != -ENOSPC || retry > 1) return ret; - ret = i915_gem_evict_everything(dev); + /* First attempt, just clear anything that is purgeable. + * Second attempt, clear the entire GTT. + */ + ret = i915_gem_evict_everything(dev, retry == 0); if (ret) return ret; - } - return 0; + retry++; + } while (1); } /* Throttle our rendering by waiting until the ring has completed our requests @@ -4484,7 +4485,7 @@ i915_gem_idle(struct drm_device *dev) /* Under UMS, be paranoid and evict. */ if (!drm_core_check_feature(dev, DRIVER_MODESET)) { - ret = i915_gem_evict_inactive(dev); + ret = i915_gem_evict_inactive(dev, false); if (ret) { mutex_unlock(&dev->struct_mutex); return ret; diff --git a/drivers/gpu/drm/i915/i915_gem_evict.c b/drivers/gpu/drm/i915/i915_gem_evict.c index 3a4215f31652..a2609c5542fd 100644 --- a/drivers/gpu/drm/i915/i915_gem_evict.c +++ b/drivers/gpu/drm/i915/i915_gem_evict.c @@ -42,7 +42,7 @@ mark_free(struct drm_i915_gem_object *obj_priv, int i915_gem_evict_something(struct drm_device *dev, int min_size, - unsigned alignment, bool mappable) + unsigned alignment, bool mappable) { drm_i915_private_t *dev_priv = dev->dev_private; struct list_head eviction_list, unwind_list; @@ -54,7 +54,7 @@ i915_gem_evict_something(struct drm_device *dev, int min_size, /* Re-check for free space after retiring requests */ if (mappable) { if (drm_mm_search_free_in_range(&dev_priv->mm.gtt_space, - min_size, alignment, 0, + min_size, alignment, 0, dev_priv->mm.gtt_mappable_end, 0)) return 0; @@ -171,7 +171,7 @@ found: } int -i915_gem_evict_everything(struct drm_device *dev) +i915_gem_evict_everything(struct drm_device *dev, bool purgeable_only) { drm_i915_private_t *dev_priv = dev->dev_private; int ret; @@ -192,38 +192,22 @@ i915_gem_evict_everything(struct drm_device *dev) BUG_ON(!list_empty(&dev_priv->mm.flushing_list)); - ret = i915_gem_evict_inactive(dev); - if (ret) - return ret; - - lists_empty = (list_empty(&dev_priv->mm.inactive_list) && - list_empty(&dev_priv->mm.flushing_list) && - list_empty(&dev_priv->render_ring.active_list) && - list_empty(&dev_priv->bsd_ring.active_list) && - list_empty(&dev_priv->blt_ring.active_list)); - BUG_ON(!lists_empty); - - return 0; + return i915_gem_evict_inactive(dev, purgeable_only); } /** Unbinds all inactive objects. */ int -i915_gem_evict_inactive(struct drm_device *dev) +i915_gem_evict_inactive(struct drm_device *dev, bool purgeable_only) { drm_i915_private_t *dev_priv = dev->dev_private; - - while (!list_empty(&dev_priv->mm.inactive_list)) { - struct drm_gem_object *obj; - int ret; - - obj = &list_first_entry(&dev_priv->mm.inactive_list, - struct drm_i915_gem_object, - mm_list)->base; - - ret = i915_gem_object_unbind(obj); - if (ret != 0) { - DRM_ERROR("Error unbinding object: %d\n", ret); - return ret; + struct drm_i915_gem_object *obj, *next; + + list_for_each_entry_safe(obj, next, + &dev_priv->mm.inactive_list, mm_list) { + if (!purgeable_only || obj->madv != I915_MADV_WILLNEED) { + int ret = i915_gem_object_unbind(&obj->base); + if (ret) + return ret; } } -- cgit v1.2.3 From 100519e2f1c20286158746f92f27c3aa14f5a893 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sun, 31 Oct 2010 10:37:02 +0000 Subject: agp/intel: the GMCH is always enabled for integrated processor graphics ... and trying to set the bit is ineffectual. Fixes the regression from e380f60 which detected that we were trying to do undefined operations on the I830_GMCH_CTRL. Reported-by: Alexey Fisher Signed-off-by: Chris Wilson --- drivers/char/agp/intel-gtt.c | 43 +++++++++++++++++++++++++++---------------- 1 file changed, 27 insertions(+), 16 deletions(-) diff --git a/drivers/char/agp/intel-gtt.c b/drivers/char/agp/intel-gtt.c index 9c86dac41da7..f800e9cfc368 100644 --- a/drivers/char/agp/intel-gtt.c +++ b/drivers/char/agp/intel-gtt.c @@ -73,6 +73,7 @@ struct intel_gtt_driver { unsigned int is_g33 : 1; unsigned int is_pineview : 1; unsigned int is_ironlake : 1; + unsigned int has_pgtbl_enable : 1; unsigned int dma_mask_size : 8; /* Chipset specific GTT setup */ int (*setup)(void); @@ -113,6 +114,7 @@ static struct _intel_private { #define IS_G33 intel_private.driver->is_g33 #define IS_PINEVIEW intel_private.driver->is_pineview #define IS_IRONLAKE intel_private.driver->is_ironlake +#define HAS_PGTBL_EN intel_private.driver->has_pgtbl_enable static void intel_agp_free_sglist(struct agp_memory *mem) { @@ -803,6 +805,9 @@ static int intel_gtt_init(void) intel_private.PGETBL_save = readl(intel_private.registers+I810_PGETBL_CTL) & ~I810_PGETBL_ENABLED; + /* we only ever restore the register when enabling the PGTBL... */ + if (HAS_PGTBL_EN) + intel_private.PGETBL_save |= I810_PGETBL_ENABLED; dev_info(&intel_private.bridge_dev->dev, "detected gtt size: %dK total, %dK mappable\n", @@ -925,7 +930,6 @@ static void i830_write_entry(dma_addr_t addr, unsigned int entry, static bool intel_enable_gtt(void) { u32 gma_addr; - u16 gmch_ctrl; u8 __iomem *reg; if (INTEL_GTT_GEN == 2) @@ -940,26 +944,30 @@ static bool intel_enable_gtt(void) if (INTEL_GTT_GEN >= 6) return true; - pci_read_config_word(intel_private.bridge_dev, - I830_GMCH_CTRL, &gmch_ctrl); - gmch_ctrl |= I830_GMCH_ENABLED; - pci_write_config_word(intel_private.bridge_dev, - I830_GMCH_CTRL, gmch_ctrl); + if (INTEL_GTT_GEN == 2) { + u16 gmch_ctrl; - pci_read_config_word(intel_private.bridge_dev, - I830_GMCH_CTRL, &gmch_ctrl); - if ((gmch_ctrl & I830_GMCH_ENABLED) == 0) { - dev_err(&intel_private.pcidev->dev, - "failed to enable the GTT: GMCH_CTRL=%x\n", - gmch_ctrl); - return false; + pci_read_config_word(intel_private.bridge_dev, + I830_GMCH_CTRL, &gmch_ctrl); + gmch_ctrl |= I830_GMCH_ENABLED; + pci_write_config_word(intel_private.bridge_dev, + I830_GMCH_CTRL, gmch_ctrl); + + pci_read_config_word(intel_private.bridge_dev, + I830_GMCH_CTRL, &gmch_ctrl); + if ((gmch_ctrl & I830_GMCH_ENABLED) == 0) { + dev_err(&intel_private.pcidev->dev, + "failed to enable the GTT: GMCH_CTRL=%x\n", + gmch_ctrl); + return false; + } } reg = intel_private.registers+I810_PGETBL_CTL; - writel(intel_private.PGETBL_save|I810_PGETBL_ENABLED, reg); - if ((readl(reg) & I810_PGETBL_ENABLED) == 0) { + writel(intel_private.PGETBL_save, reg); + if (HAS_PGTBL_EN && (readl(reg) & I810_PGETBL_ENABLED) == 0) { dev_err(&intel_private.pcidev->dev, - "failed to enable the GTT: PGETBL=%x [expected %x|1]\n", + "failed to enable the GTT: PGETBL=%x [expected %x]\n", readl(reg), intel_private.PGETBL_save); return false; } @@ -1395,6 +1403,7 @@ static const struct intel_gtt_driver i81x_gtt_driver = { }; static const struct intel_gtt_driver i8xx_gtt_driver = { .gen = 2, + .has_pgtbl_enable = 1, .setup = i830_setup, .cleanup = i830_cleanup, .write_entry = i830_write_entry, @@ -1404,6 +1413,7 @@ static const struct intel_gtt_driver i8xx_gtt_driver = { }; static const struct intel_gtt_driver i915_gtt_driver = { .gen = 3, + .has_pgtbl_enable = 1, .setup = i9xx_setup, .cleanup = i9xx_cleanup, /* i945 is the last gpu to need phys mem (for overlay and cursors). */ @@ -1434,6 +1444,7 @@ static const struct intel_gtt_driver pineview_gtt_driver = { }; static const struct intel_gtt_driver i965_gtt_driver = { .gen = 4, + .has_pgtbl_enable = 1, .setup = i9xx_setup, .cleanup = i9xx_cleanup, .write_entry = i965_write_entry, -- cgit v1.2.3 From 4b6ba8aacbb3185703b797286547d0f8f3859b02 Mon Sep 17 00:00:00 2001 From: David Daney Date: Tue, 26 Oct 2010 15:07:13 -0700 Subject: of/net: Move of_get_mac_address() to a common source file. There are two identical implementations of of_get_mac_address(), one each in arch/powerpc/kernel/prom_parse.c and arch/microblaze/kernel/prom_parse.c. Move this function to a new common file of_net.{c,h} and adjust all the callers to include the new header. Signed-off-by: David Daney [grant.likely@secretlab.ca: protect header with #ifdef] Signed-off-by: Grant Likely --- arch/microblaze/include/asm/prom.h | 3 --- arch/microblaze/kernel/prom_parse.c | 38 ----------------------------- arch/powerpc/include/asm/prom.h | 3 --- arch/powerpc/kernel/prom_parse.c | 38 ----------------------------- arch/powerpc/sysdev/mv64x60_dev.c | 1 + arch/powerpc/sysdev/tsi108_dev.c | 1 + drivers/net/fs_enet/fs_enet-main.c | 1 + drivers/net/gianfar.c | 1 + drivers/net/ucc_geth.c | 1 + drivers/net/xilinx_emaclite.c | 1 + drivers/of/Kconfig | 4 ++++ drivers/of/Makefile | 1 + drivers/of/of_net.c | 48 +++++++++++++++++++++++++++++++++++++ include/linux/of_net.h | 15 ++++++++++++ 14 files changed, 74 insertions(+), 82 deletions(-) create mode 100644 drivers/of/of_net.c create mode 100644 include/linux/of_net.h diff --git a/arch/microblaze/include/asm/prom.h b/arch/microblaze/include/asm/prom.h index bdc38312ae4a..2e72af078b05 100644 --- a/arch/microblaze/include/asm/prom.h +++ b/arch/microblaze/include/asm/prom.h @@ -64,9 +64,6 @@ extern void kdump_move_device_tree(void); /* CPU OF node matching */ struct device_node *of_get_cpu_node(int cpu, unsigned int *thread); -/* Get the MAC address */ -extern const void *of_get_mac_address(struct device_node *np); - /** * of_irq_map_pci - Resolve the interrupt for a PCI device * @pdev: the device whose interrupt is to be resolved diff --git a/arch/microblaze/kernel/prom_parse.c b/arch/microblaze/kernel/prom_parse.c index 99d9b61cccb5..9ae24f4b882b 100644 --- a/arch/microblaze/kernel/prom_parse.c +++ b/arch/microblaze/kernel/prom_parse.c @@ -110,41 +110,3 @@ void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop, cells = prop ? *(u32 *)prop : of_n_size_cells(dn); *size = of_read_number(dma_window, cells); } - -/** - * Search the device tree for the best MAC address to use. 'mac-address' is - * checked first, because that is supposed to contain to "most recent" MAC - * address. If that isn't set, then 'local-mac-address' is checked next, - * because that is the default address. If that isn't set, then the obsolete - * 'address' is checked, just in case we're using an old device tree. - * - * Note that the 'address' property is supposed to contain a virtual address of - * the register set, but some DTS files have redefined that property to be the - * MAC address. - * - * All-zero MAC addresses are rejected, because those could be properties that - * exist in the device tree, but were not set by U-Boot. For example, the - * DTS could define 'mac-address' and 'local-mac-address', with zero MAC - * addresses. Some older U-Boots only initialized 'local-mac-address'. In - * this case, the real MAC is in 'local-mac-address', and 'mac-address' exists - * but is all zeros. -*/ -const void *of_get_mac_address(struct device_node *np) -{ - struct property *pp; - - pp = of_find_property(np, "mac-address", NULL); - if (pp && (pp->length == 6) && is_valid_ether_addr(pp->value)) - return pp->value; - - pp = of_find_property(np, "local-mac-address", NULL); - if (pp && (pp->length == 6) && is_valid_ether_addr(pp->value)) - return pp->value; - - pp = of_find_property(np, "address", NULL); - if (pp && (pp->length == 6) && is_valid_ether_addr(pp->value)) - return pp->value; - - return NULL; -} -EXPORT_SYMBOL(of_get_mac_address); diff --git a/arch/powerpc/include/asm/prom.h b/arch/powerpc/include/asm/prom.h index ae26f2efd089..98264bf0a433 100644 --- a/arch/powerpc/include/asm/prom.h +++ b/arch/powerpc/include/asm/prom.h @@ -63,9 +63,6 @@ struct device_node *of_get_cpu_node(int cpu, unsigned int *thread); /* cache lookup */ struct device_node *of_find_next_cache_node(struct device_node *np); -/* Get the MAC address */ -extern const void *of_get_mac_address(struct device_node *np); - #ifdef CONFIG_NUMA extern int of_node_to_nid(struct device_node *device); #else diff --git a/arch/powerpc/kernel/prom_parse.c b/arch/powerpc/kernel/prom_parse.c index 88334af038e5..c2b7a07cc3d3 100644 --- a/arch/powerpc/kernel/prom_parse.c +++ b/arch/powerpc/kernel/prom_parse.c @@ -117,41 +117,3 @@ void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop, cells = prop ? *(u32 *)prop : of_n_size_cells(dn); *size = of_read_number(dma_window, cells); } - -/** - * Search the device tree for the best MAC address to use. 'mac-address' is - * checked first, because that is supposed to contain to "most recent" MAC - * address. If that isn't set, then 'local-mac-address' is checked next, - * because that is the default address. If that isn't set, then the obsolete - * 'address' is checked, just in case we're using an old device tree. - * - * Note that the 'address' property is supposed to contain a virtual address of - * the register set, but some DTS files have redefined that property to be the - * MAC address. - * - * All-zero MAC addresses are rejected, because those could be properties that - * exist in the device tree, but were not set by U-Boot. For example, the - * DTS could define 'mac-address' and 'local-mac-address', with zero MAC - * addresses. Some older U-Boots only initialized 'local-mac-address'. In - * this case, the real MAC is in 'local-mac-address', and 'mac-address' exists - * but is all zeros. -*/ -const void *of_get_mac_address(struct device_node *np) -{ - struct property *pp; - - pp = of_find_property(np, "mac-address", NULL); - if (pp && (pp->length == 6) && is_valid_ether_addr(pp->value)) - return pp->value; - - pp = of_find_property(np, "local-mac-address", NULL); - if (pp && (pp->length == 6) && is_valid_ether_addr(pp->value)) - return pp->value; - - pp = of_find_property(np, "address", NULL); - if (pp && (pp->length == 6) && is_valid_ether_addr(pp->value)) - return pp->value; - - return NULL; -} -EXPORT_SYMBOL(of_get_mac_address); diff --git a/arch/powerpc/sysdev/mv64x60_dev.c b/arch/powerpc/sysdev/mv64x60_dev.c index 1398bc454999..feaee402e2d6 100644 --- a/arch/powerpc/sysdev/mv64x60_dev.c +++ b/arch/powerpc/sysdev/mv64x60_dev.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include diff --git a/arch/powerpc/sysdev/tsi108_dev.c b/arch/powerpc/sysdev/tsi108_dev.c index d4d15aaf18fa..c2d675b6392c 100644 --- a/arch/powerpc/sysdev/tsi108_dev.c +++ b/arch/powerpc/sysdev/tsi108_dev.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include diff --git a/drivers/net/fs_enet/fs_enet-main.c b/drivers/net/fs_enet/fs_enet-main.c index d684f187de57..7a1f3d0ffa78 100644 --- a/drivers/net/fs_enet/fs_enet-main.c +++ b/drivers/net/fs_enet/fs_enet-main.c @@ -40,6 +40,7 @@ #include #include #include +#include #include #include diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c index 49e4ce1246a7..f860072e2f68 100644 --- a/drivers/net/gianfar.c +++ b/drivers/net/gianfar.c @@ -95,6 +95,7 @@ #include #include #include +#include #include "gianfar.h" #include "fsl_pq_mdio.h" diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c index a4c3f5708246..f7e370fd8ddc 100644 --- a/drivers/net/ucc_geth.c +++ b/drivers/net/ucc_geth.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include diff --git a/drivers/net/xilinx_emaclite.c b/drivers/net/xilinx_emaclite.c index 14f0955eca68..2a34b22ea26a 100644 --- a/drivers/net/xilinx_emaclite.c +++ b/drivers/net/xilinx_emaclite.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #define DRIVER_NAME "xilinx_emaclite" diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig index aa675ebd8eb3..e4b93a0a15d2 100644 --- a/drivers/of/Kconfig +++ b/drivers/of/Kconfig @@ -49,6 +49,10 @@ config OF_I2C help OpenFirmware I2C accessors +config OF_NET + depends on NETDEVICES + def_bool y + config OF_SPI def_tristate SPI depends on SPI && !SPARC diff --git a/drivers/of/Makefile b/drivers/of/Makefile index 7888155bea08..3ab21a0a4907 100644 --- a/drivers/of/Makefile +++ b/drivers/of/Makefile @@ -6,5 +6,6 @@ obj-$(CONFIG_OF_IRQ) += irq.o obj-$(CONFIG_OF_DEVICE) += device.o platform.o obj-$(CONFIG_OF_GPIO) += gpio.o obj-$(CONFIG_OF_I2C) += of_i2c.o +obj-$(CONFIG_OF_NET) += of_net.o obj-$(CONFIG_OF_SPI) += of_spi.o obj-$(CONFIG_OF_MDIO) += of_mdio.o diff --git a/drivers/of/of_net.c b/drivers/of/of_net.c new file mode 100644 index 000000000000..86f334a2769c --- /dev/null +++ b/drivers/of/of_net.c @@ -0,0 +1,48 @@ +/* + * OF helpers for network devices. + * + * This file is released under the GPLv2 + * + * Initially copied out of arch/powerpc/kernel/prom_parse.c + */ +#include +#include +#include + +/** + * Search the device tree for the best MAC address to use. 'mac-address' is + * checked first, because that is supposed to contain to "most recent" MAC + * address. If that isn't set, then 'local-mac-address' is checked next, + * because that is the default address. If that isn't set, then the obsolete + * 'address' is checked, just in case we're using an old device tree. + * + * Note that the 'address' property is supposed to contain a virtual address of + * the register set, but some DTS files have redefined that property to be the + * MAC address. + * + * All-zero MAC addresses are rejected, because those could be properties that + * exist in the device tree, but were not set by U-Boot. For example, the + * DTS could define 'mac-address' and 'local-mac-address', with zero MAC + * addresses. Some older U-Boots only initialized 'local-mac-address'. In + * this case, the real MAC is in 'local-mac-address', and 'mac-address' exists + * but is all zeros. +*/ +const void *of_get_mac_address(struct device_node *np) +{ + struct property *pp; + + pp = of_find_property(np, "mac-address", NULL); + if (pp && (pp->length == 6) && is_valid_ether_addr(pp->value)) + return pp->value; + + pp = of_find_property(np, "local-mac-address", NULL); + if (pp && (pp->length == 6) && is_valid_ether_addr(pp->value)) + return pp->value; + + pp = of_find_property(np, "address", NULL); + if (pp && (pp->length == 6) && is_valid_ether_addr(pp->value)) + return pp->value; + + return NULL; +} +EXPORT_SYMBOL(of_get_mac_address); diff --git a/include/linux/of_net.h b/include/linux/of_net.h new file mode 100644 index 000000000000..e913081fb52a --- /dev/null +++ b/include/linux/of_net.h @@ -0,0 +1,15 @@ +/* + * OF helpers for network devices. + * + * This file is released under the GPLv2 + */ + +#ifndef __LINUX_OF_NET_H +#define __LINUX_OF_NET_H + +#ifdef CONFIG_OF_NET +#include +extern const void *of_get_mac_address(struct device_node *np); +#endif + +#endif /* __LINUX_OF_NET_H */ -- cgit v1.2.3 From e5c652603680404683fd1f262b511340545179a2 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 1 Nov 2010 11:35:28 +0000 Subject: drm/i915/debugfs: Report ring in error state Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_debugfs.c | 62 ++++++++++++++++++++----------------- drivers/gpu/drm/i915/i915_drv.h | 1 + drivers/gpu/drm/i915/i915_irq.c | 1 + 3 files changed, 36 insertions(+), 28 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 56f7ced16f1a..9cb6061bf9d5 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -32,6 +32,7 @@ #include "drmP.h" #include "drm.h" #include "intel_drv.h" +#include "intel_ringbuffer.h" #include "i915_drm.h" #include "i915_drv.h" @@ -48,12 +49,6 @@ enum { DEFERRED_FREE_LIST, }; -enum { - RENDER_RING, - BSD_RING, - BLT_RING, -}; - static const char *yesno(int v) { return v ? "yes" : "no"; @@ -450,9 +445,9 @@ static int i915_hws_info(struct seq_file *m, void *data) int i; switch ((uintptr_t)node->info_ent->data) { - case RENDER_RING: ring = &dev_priv->render_ring; break; - case BSD_RING: ring = &dev_priv->bsd_ring; break; - case BLT_RING: ring = &dev_priv->blt_ring; break; + case RING_RENDER: ring = &dev_priv->render_ring; break; + case RING_BSD: ring = &dev_priv->bsd_ring; break; + case RING_BLT: ring = &dev_priv->blt_ring; break; default: return -EINVAL; } @@ -520,9 +515,9 @@ static int i915_ringbuffer_data(struct seq_file *m, void *data) int ret; switch ((uintptr_t)node->info_ent->data) { - case RENDER_RING: ring = &dev_priv->render_ring; break; - case BSD_RING: ring = &dev_priv->bsd_ring; break; - case BLT_RING: ring = &dev_priv->blt_ring; break; + case RING_RENDER: ring = &dev_priv->render_ring; break; + case RING_BSD: ring = &dev_priv->bsd_ring; break; + case RING_BLT: ring = &dev_priv->blt_ring; break; default: return -EINVAL; } @@ -554,9 +549,9 @@ static int i915_ringbuffer_info(struct seq_file *m, void *data) struct intel_ring_buffer *ring; switch ((uintptr_t)node->info_ent->data) { - case RENDER_RING: ring = &dev_priv->render_ring; break; - case BSD_RING: ring = &dev_priv->bsd_ring; break; - case BLT_RING: ring = &dev_priv->blt_ring; break; + case RING_RENDER: ring = &dev_priv->render_ring; break; + case RING_BSD: ring = &dev_priv->bsd_ring; break; + case RING_BLT: ring = &dev_priv->blt_ring; break; default: return -EINVAL; } @@ -574,6 +569,16 @@ static int i915_ringbuffer_info(struct seq_file *m, void *data) return 0; } +static const char *ring_str(int ring) +{ + switch (ring) { + case RING_RENDER: return "render"; + case RING_BSD: return "bsd"; + case RING_BLT: return "blt"; + default: return ""; + } +} + static const char *pin_flag(int pinned) { if (pinned > 0) @@ -630,14 +635,14 @@ static int i915_error_state(struct seq_file *m, void *unused) seq_printf(m, "ERROR: 0x%08x\n", error->error); seq_printf(m, "Blitter command stream:\n"); seq_printf(m, " ACTHD: 0x%08x\n", error->bcs_acthd); - seq_printf(m, " IPEHR: 0x%08x\n", error->bcs_ipehr); seq_printf(m, " IPEIR: 0x%08x\n", error->bcs_ipeir); + seq_printf(m, " IPEHR: 0x%08x\n", error->bcs_ipehr); seq_printf(m, " INSTDONE: 0x%08x\n", error->bcs_instdone); seq_printf(m, " seqno: 0x%08x\n", error->bcs_seqno); seq_printf(m, "Video (BSD) command stream:\n"); seq_printf(m, " ACTHD: 0x%08x\n", error->vcs_acthd); - seq_printf(m, " IPEHR: 0x%08x\n", error->vcs_ipehr); seq_printf(m, " IPEIR: 0x%08x\n", error->vcs_ipeir); + seq_printf(m, " IPEHR: 0x%08x\n", error->vcs_ipehr); seq_printf(m, " INSTDONE: 0x%08x\n", error->vcs_instdone); seq_printf(m, " seqno: 0x%08x\n", error->vcs_seqno); } @@ -657,7 +662,7 @@ static int i915_error_state(struct seq_file *m, void *unused) seq_printf(m, "Buffers [%d]:\n", error->active_bo_count); for (i = 0; i < error->active_bo_count; i++) { - seq_printf(m, " %08x %8zd %08x %08x %08x%s%s%s%s", + seq_printf(m, " %08x %8zd %08x %08x %08x%s%s%s%s %s", error->active_bo[i].gtt_offset, error->active_bo[i].size, error->active_bo[i].read_domains, @@ -666,7 +671,8 @@ static int i915_error_state(struct seq_file *m, void *unused) pin_flag(error->active_bo[i].pinned), tiling_flag(error->active_bo[i].tiling), dirty_flag(error->active_bo[i].dirty), - purgeable_flag(error->active_bo[i].purgeable)); + purgeable_flag(error->active_bo[i].purgeable), + ring_str(error->active_bo[i].ring)); if (error->active_bo[i].name) seq_printf(m, " (name: %d)", error->active_bo[i].name); @@ -1101,15 +1107,15 @@ static struct drm_info_list i915_debugfs_list[] = { {"i915_gem_seqno", i915_gem_seqno_info, 0}, {"i915_gem_fence_regs", i915_gem_fence_regs_info, 0}, {"i915_gem_interrupt", i915_interrupt_info, 0}, - {"i915_gem_hws", i915_hws_info, 0, (void *)RENDER_RING}, - {"i915_gem_hws_blt", i915_hws_info, 0, (void *)BLT_RING}, - {"i915_gem_hws_bsd", i915_hws_info, 0, (void *)BSD_RING}, - {"i915_ringbuffer_data", i915_ringbuffer_data, 0, (void *)RENDER_RING}, - {"i915_ringbuffer_info", i915_ringbuffer_info, 0, (void *)RENDER_RING}, - {"i915_bsd_ringbuffer_data", i915_ringbuffer_data, 0, (void *)BSD_RING}, - {"i915_bsd_ringbuffer_info", i915_ringbuffer_info, 0, (void *)BSD_RING}, - {"i915_blt_ringbuffer_data", i915_ringbuffer_data, 0, (void *)BLT_RING}, - {"i915_blt_ringbuffer_info", i915_ringbuffer_info, 0, (void *)BLT_RING}, + {"i915_gem_hws", i915_hws_info, 0, (void *)RING_RENDER}, + {"i915_gem_hws_blt", i915_hws_info, 0, (void *)RING_BLT}, + {"i915_gem_hws_bsd", i915_hws_info, 0, (void *)RING_BSD}, + {"i915_ringbuffer_data", i915_ringbuffer_data, 0, (void *)RING_RENDER}, + {"i915_ringbuffer_info", i915_ringbuffer_info, 0, (void *)RING_RENDER}, + {"i915_bsd_ringbuffer_data", i915_ringbuffer_data, 0, (void *)RING_BSD}, + {"i915_bsd_ringbuffer_info", i915_ringbuffer_info, 0, (void *)RING_BSD}, + {"i915_blt_ringbuffer_data", i915_ringbuffer_data, 0, (void *)RING_BLT}, + {"i915_blt_ringbuffer_info", i915_ringbuffer_info, 0, (void *)RING_BLT}, {"i915_batchbuffers", i915_batchbuffer_info, 0}, {"i915_error_state", i915_error_state, 0}, {"i915_rstdby_delays", i915_rstdby_delays, 0}, diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 54e5b2fa5fd4..3f8786049cb6 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -182,6 +182,7 @@ struct drm_i915_error_state { u32 tiling:2; u32 dirty:1; u32 purgeable:1; + u32 ring:4; } *active_bo; u32 active_bo_count; struct intel_overlay_error_state *overlay; diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 90c071d37748..3ec631f1129d 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -728,6 +728,7 @@ static void i915_capture_error_state(struct drm_device *dev) error->active_bo[i].tiling = obj_priv->tiling_mode; error->active_bo[i].dirty = obj_priv->dirty; error->active_bo[i].purgeable = obj_priv->madv != I915_MADV_WILLNEED; + error->active_bo[i].ring = obj_priv->ring->id; if (++i == count) break; -- cgit v1.2.3 From 13b2928933919c5344716d49620a52493a243f8c Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 1 Nov 2010 12:22:48 +0000 Subject: drm/i915: Apply big hammer to serialise buffer access between rings Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_gem.c | 75 ++++++++++++++++++++++++++++------------- 1 file changed, 52 insertions(+), 23 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index c8e516d3f8bc..c797d2b9b233 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -3189,7 +3189,8 @@ i915_gem_object_set_to_gpu_domain(struct drm_gem_object *obj, * write domain */ if (obj->write_domain && - obj->write_domain != obj->pending_read_domains) { + (obj->write_domain != obj->pending_read_domains || + obj_priv->ring != ring)) { flush_domains |= obj->write_domain; invalidate_domains |= obj->pending_read_domains & ~obj->write_domain; @@ -3582,6 +3583,52 @@ i915_gem_execbuffer_pin(struct drm_device *dev, } while (1); } +static int +i915_gem_execbuffer_move_to_gpu(struct drm_device *dev, + struct drm_file *file, + struct intel_ring_buffer *ring, + struct drm_gem_object **objects, + int count) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + int ret, i; + + /* Zero the global flush/invalidate flags. These + * will be modified as new domains are computed + * for each object + */ + dev->invalidate_domains = 0; + dev->flush_domains = 0; + dev_priv->mm.flush_rings = 0; + for (i = 0; i < count; i++) + i915_gem_object_set_to_gpu_domain(objects[i], ring); + + if (dev->invalidate_domains | dev->flush_domains) { +#if WATCH_EXEC + DRM_INFO("%s: invalidate_domains %08x flush_domains %08x\n", + __func__, + dev->invalidate_domains, + dev->flush_domains); +#endif + i915_gem_flush(dev, file, + dev->invalidate_domains, + dev->flush_domains, + dev_priv->mm.flush_rings); + } + + for (i = 0; i < count; i++) { + struct drm_i915_gem_object *obj = to_intel_bo(objects[i]); + /* XXX replace with semaphores */ + if (obj->ring && ring != obj->ring) { + ret = i915_gem_object_wait_rendering(&obj->base, true); + if (ret) + return ret; + } + } + + return 0; +} + /* Throttle our rendering by waiting until the ring has completed our requests * emitted over 20 msec ago. * @@ -3843,28 +3890,10 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, goto err; } - /* Zero the global flush/invalidate flags. These - * will be modified as new domains are computed - * for each object - */ - dev->invalidate_domains = 0; - dev->flush_domains = 0; - dev_priv->mm.flush_rings = 0; - for (i = 0; i < args->buffer_count; i++) - i915_gem_object_set_to_gpu_domain(object_list[i], ring); - - if (dev->invalidate_domains | dev->flush_domains) { -#if WATCH_EXEC - DRM_INFO("%s: invalidate_domains %08x flush_domains %08x\n", - __func__, - dev->invalidate_domains, - dev->flush_domains); -#endif - i915_gem_flush(dev, file, - dev->invalidate_domains, - dev->flush_domains, - dev_priv->mm.flush_rings); - } + ret = i915_gem_execbuffer_move_to_gpu(dev, file, ring, + object_list, args->buffer_count); + if (ret) + goto err; #if WATCH_COHERENCY for (i = 0; i < args->buffer_count; i++) { -- cgit v1.2.3 From 0f8c6d7ca9257d6a01671ab69b897860d3ae9bc0 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 1 Nov 2010 12:38:44 +0000 Subject: drm/i915: Move the invalidate|flush information out of the device struct ... and into a local structure scoped for the single function in which it is used. Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_drv.h | 2 -- drivers/gpu/drm/i915/i915_gem.c | 45 +++++++++++++++++++++-------------------- include/drm/drmP.h | 2 -- 3 files changed, 23 insertions(+), 26 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 3f8786049cb6..a0063f82fa33 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -642,8 +642,6 @@ typedef struct drm_i915_private { /* storage for physical objects */ struct drm_i915_gem_phys_object *phys_objs[I915_MAX_PHYS_OBJECT]; - uint32_t flush_rings; - /* accounting, useful for userland debugging */ size_t object_memory; size_t pin_memory; diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index c797d2b9b233..ffea847c8a0d 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -36,6 +36,12 @@ #include #include +struct change_domains { + uint32_t invalidate_domains; + uint32_t flush_domains; + uint32_t flush_rings; +}; + static uint32_t i915_gem_get_gtt_alignment(struct drm_i915_gem_object *obj_priv); static uint32_t i915_gem_get_gtt_size(struct drm_i915_gem_object *obj_priv); @@ -3167,10 +3173,9 @@ i915_gem_object_set_to_cpu_domain(struct drm_gem_object *obj, int write) */ static void i915_gem_object_set_to_gpu_domain(struct drm_gem_object *obj, - struct intel_ring_buffer *ring) + struct intel_ring_buffer *ring, + struct change_domains *cd) { - struct drm_device *dev = obj->dev; - struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); uint32_t invalidate_domains = 0; uint32_t flush_domains = 0; @@ -3216,12 +3221,12 @@ i915_gem_object_set_to_gpu_domain(struct drm_gem_object *obj, if (flush_domains == 0 && obj->pending_write_domain == 0) obj->pending_write_domain = obj->write_domain; - dev->invalidate_domains |= invalidate_domains; - dev->flush_domains |= flush_domains; + cd->invalidate_domains |= invalidate_domains; + cd->flush_domains |= flush_domains; if (flush_domains & I915_GEM_GPU_DOMAINS) - dev_priv->mm.flush_rings |= obj_priv->ring->id; + cd->flush_rings |= obj_priv->ring->id; if (invalidate_domains & I915_GEM_GPU_DOMAINS) - dev_priv->mm.flush_rings |= ring->id; + cd->flush_rings |= ring->id; } /** @@ -3590,30 +3595,26 @@ i915_gem_execbuffer_move_to_gpu(struct drm_device *dev, struct drm_gem_object **objects, int count) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct change_domains cd; int ret, i; - /* Zero the global flush/invalidate flags. These - * will be modified as new domains are computed - * for each object - */ - dev->invalidate_domains = 0; - dev->flush_domains = 0; - dev_priv->mm.flush_rings = 0; + cd.invalidate_domains = 0; + cd.flush_domains = 0; + cd.flush_rings = 0; for (i = 0; i < count; i++) - i915_gem_object_set_to_gpu_domain(objects[i], ring); + i915_gem_object_set_to_gpu_domain(objects[i], ring, &cd); - if (dev->invalidate_domains | dev->flush_domains) { + if (cd.invalidate_domains | cd.flush_domains) { #if WATCH_EXEC DRM_INFO("%s: invalidate_domains %08x flush_domains %08x\n", __func__, - dev->invalidate_domains, - dev->flush_domains); + cd.invalidate_domains, + cd.flush_domains); #endif i915_gem_flush(dev, file, - dev->invalidate_domains, - dev->flush_domains, - dev_priv->mm.flush_rings); + cd.invalidate_domains, + cd.flush_domains, + cd.flush_rings); } for (i = 0; i < count; i++) { diff --git a/include/drm/drmP.h b/include/drm/drmP.h index 274eaaa15c36..d4bc0f5cab8f 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -1041,8 +1041,6 @@ struct drm_device { /*@{ */ spinlock_t object_name_lock; struct idr object_name_idr; - uint32_t invalidate_domains; /* domains pending invalidation */ - uint32_t flush_domains; /* domains pending flush */ /*@} */ }; -- cgit v1.2.3 From c5113e3c111b03c8eaf3fb0ef39e33dc25171adc Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Fri, 29 Oct 2010 21:26:06 -0700 Subject: beceem: use kernel print_hex_dump function No longer need special hex dump routine Signed-off-by: Stephen Hemminger --- drivers/staging/bcm/Debug.c | 39 --------------------------------------- drivers/staging/bcm/Debug.h | 25 +++++++------------------ drivers/staging/bcm/Makefile | 2 +- 3 files changed, 8 insertions(+), 58 deletions(-) delete mode 100644 drivers/staging/bcm/Debug.c diff --git a/drivers/staging/bcm/Debug.c b/drivers/staging/bcm/Debug.c deleted file mode 100644 index b86d8456cf7d..000000000000 --- a/drivers/staging/bcm/Debug.c +++ /dev/null @@ -1,39 +0,0 @@ -#include "headers.h" - -void bcm_print_buffer(UINT debug_level, const char *function_name, - const char *file_name, int line_number, - const unsigned char *buffer, int bufferlen, - BASE_TYPE base) -{ - int i; - static const char * const buff_dump_base[] = { - "DEC", "HEX", "OCT", "BIN" - }; - - if(debug_level < BCM_SCREAM) - return; - - printk("\n" KERN_DEBUG "%s:%s:%d:Buffer dump of size 0x%x in the %s:\n", - file_name, function_name, line_number, bufferlen, buff_dump_base[1]); - - for(i = 0; i < bufferlen;i++) { - if(i && !(i%16) ) - printk("\n"); - switch(base) { - case BCM_BASE_TYPE_DEC: - printk("%03d ", buffer[i]); - break; - case BCM_BASE_TYPE_OCT: - printk("%0x03o ", buffer[i]); - break; - case BCM_BASE_TYPE_BIN: - printk("%02x ", buffer[i]); - break; - case BCM_BASE_TYPE_HEX: - default: - printk("%02X ", buffer[i]); - break; - } - printk("\n"); - } -} diff --git a/drivers/staging/bcm/Debug.h b/drivers/staging/bcm/Debug.h index 58e46a601dec..3138729cf34f 100644 --- a/drivers/staging/bcm/Debug.h +++ b/drivers/staging/bcm/Debug.h @@ -9,19 +9,6 @@ #include #define NONE 0xFFFF -typedef enum _BASE_TYPE -{ - BCM_BASE_TYPE_DEC, - BCM_BASE_TYPE_OCT, - BCM_BASE_TYPE_BIN, - BCM_BASE_TYPE_HEX, - BCM_BASE_TYPE_NONE, -} BASE_TYPE, *PBASE_TYPE; - -void bcm_print_buffer(UINT debug_level, const char *function_name, - const char *file_name, int line_number, - const unsigned char *buffer, int bufferlen, BASE_TYPE base); - //-------------------------------------------------------------------------------- @@ -231,7 +218,7 @@ typedef struct _S_BCM_DEBUG_STATE { #define BCM_DEBUG_PRINT(Adapter, Type, SubType, dbg_level, string, args...) \ do { \ if (DBG_TYPE_PRINTK == Type) \ - pr_info("%s:" string "\n", __func__, ##args); \ + pr_info("%s:" string, __func__, ##args); \ else if (Adapter && \ (dbg_level & DBG_LVL_BITMASK) <= Adapter->stDebugState.debug_level && \ (Type & Adapter->stDebugState.type) && \ @@ -239,7 +226,7 @@ typedef struct _S_BCM_DEBUG_STATE { if (dbg_level & DBG_NO_FUNC_PRINT) \ printk(KERN_DEBUG string, ##args); \ else \ - printk(KERN_DEBUG "%s:" string "\n", __func__, ##args); \ + printk(KERN_DEBUG "%s:" string, __func__, ##args); \ } \ } while (0) @@ -248,9 +235,11 @@ typedef struct _S_BCM_DEBUG_STATE { (Adapter && \ (dbg_level & DBG_LVL_BITMASK) <= Adapter->stDebugState.debug_level && \ (Type & Adapter->stDebugState.type) && \ - (SubType & Adapter->stDebugState.subtype[Type]))) \ - bcm_print_buffer(dbg_level, __func__, __FILE__, __LINE__, \ - buffer, bufferlen, BCM_BASE_TYPE_HEX); \ + (SubType & Adapter->stDebugState.subtype[Type]))) { \ + printk(KERN_DEBUG "%s:\n", __func__); \ + print_hex_dump(KERN_DEBUG, " ", DUMP_PREFIX_OFFSET, \ + 16, 1, buffer, bufferlen, false); \ + } \ } while(0) diff --git a/drivers/staging/bcm/Makefile b/drivers/staging/bcm/Makefile index c3ae25af670a..6f6fcee8e4a9 100644 --- a/drivers/staging/bcm/Makefile +++ b/drivers/staging/bcm/Makefile @@ -6,7 +6,7 @@ obj-$(CONFIG_BCM_WIMAX) += bcm_wimax.o bcm_wimax-y := InterfaceDld.o InterfaceIdleMode.o InterfaceInit.o InterfaceRx.o \ InterfaceIsr.o InterfaceMisc.o InterfaceTx.o \ - Arp.o CmHost.o Debug.o IPv6Protocol.o Qos.o Transmit.o\ + Arp.o CmHost.o IPv6Protocol.o Qos.o Transmit.o\ Bcmnet.o DDRInit.o HandleControlPacket.o\ LeakyBucket.o Misc.o sort.o Bcmchar.o hostmibs.o PHSModule.o\ Osal_Misc.o led_control.o nvm.o vendorspecificextn.o -- cgit v1.2.3 From 082e889b475c46e71be6e779f15ab095f888e03f Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Mon, 1 Nov 2010 09:35:21 -0400 Subject: beceem: remove OS wrapper library Use native kernel functions for kmalloc/kfree directly Signed-off-by: Stephen Hemminger --- drivers/staging/bcm/Arp.c | 2 +- drivers/staging/bcm/Bcmchar.c | 68 ++++++++-------- drivers/staging/bcm/CmHost.c | 24 +++--- drivers/staging/bcm/HandleControlPacket.c | 4 +- drivers/staging/bcm/InterfaceDld.c | 24 +++--- drivers/staging/bcm/InterfaceInit.c | 2 +- drivers/staging/bcm/InterfaceRx.c | 2 +- drivers/staging/bcm/Makefile | 2 +- drivers/staging/bcm/Misc.c | 51 ++++-------- drivers/staging/bcm/Osal_Misc.c | 27 ------ drivers/staging/bcm/PHSModule.c | 131 ++++++++++-------------------- drivers/staging/bcm/Prototypes.h | 4 - drivers/staging/bcm/Qos.c | 4 +- drivers/staging/bcm/Transmit.c | 8 +- drivers/staging/bcm/headers.h | 1 - drivers/staging/bcm/hostmibs.c | 4 +- drivers/staging/bcm/led_control.c | 7 +- drivers/staging/bcm/nvm.c | 105 +++++++++++------------- drivers/staging/bcm/osal_misc.h | 49 ----------- 19 files changed, 180 insertions(+), 339 deletions(-) delete mode 100644 drivers/staging/bcm/Osal_Misc.c delete mode 100644 drivers/staging/bcm/osal_misc.h diff --git a/drivers/staging/bcm/Arp.c b/drivers/staging/bcm/Arp.c index d60d8593d2ef..7cb25b30b5c1 100644 --- a/drivers/staging/bcm/Arp.c +++ b/drivers/staging/bcm/Arp.c @@ -50,7 +50,7 @@ reply_to_arp_request(struct sk_buff *skb) { if(memcmp(pethhdr->h_source, Adapter->dev->dev_addr, ETH_ALEN)) { - bcm_kfree_skb(skb); + dev_kfree_skb(skb); return; } } diff --git a/drivers/staging/bcm/Bcmchar.c b/drivers/staging/bcm/Bcmchar.c index 01f961d9c70c..f9979a87c42b 100644 --- a/drivers/staging/bcm/Bcmchar.c +++ b/drivers/staging/bcm/Bcmchar.c @@ -93,7 +93,7 @@ static int bcm_char_release(struct inode *inode, struct file *filp) /*Stop Queuing the control response Packets*/ atomic_dec(&Adapter->ApplicationRunning); - bcm_kfree(pTarang); + kfree(pTarang); /* remove this filp from the asynchronously notified filp's */ filp->private_data = NULL; @@ -141,12 +141,12 @@ static ssize_t bcm_char_read(struct file *filp, char __user *buf, size_t size, l PktLen = Packet->len; if(copy_to_user(buf, Packet->data, PktLen)) { - bcm_kfree_skb(Packet); + dev_kfree_skb(Packet); BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "\nReturning from copy to user failure \n"); return -EFAULT; } BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Read %d Bytes From Adapter packet = 0x%p by process %d!\n", PktLen, Packet, current->pid); - bcm_kfree_skb(Packet); + dev_kfree_skb(Packet); } BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "<====\n"); @@ -239,7 +239,7 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) (PUINT)temp_buff, Bufflen); if(Status != STATUS_SUCCESS) { - bcm_kfree(temp_buff); + kfree(temp_buff); return Status; } if(copy_to_user(IoBuffer.OutputBuffer, @@ -247,7 +247,7 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) { Status = -EFAULT; } - bcm_kfree(temp_buff); + kfree(temp_buff); break; } case IOCTL_BCM_REGISTER_WRITE_PRIVATE: @@ -344,7 +344,7 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) (PUINT)temp_buff, IoBuffer.OutputLength); if(Status != STATUS_SUCCESS) { - bcm_kfree(temp_buff); + kfree(temp_buff); return Status; } if(copy_to_user(IoBuffer.OutputBuffer, @@ -352,7 +352,7 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) { Status = -EFAULT; } - bcm_kfree(temp_buff); + kfree(temp_buff); break; } case IOCTL_BCM_REGISTER_WRITE: @@ -796,7 +796,7 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) IoBuffer.InputLength)) { Status = -EFAULT; - bcm_kfree(pvBuffer); + kfree(pvBuffer); break; } @@ -816,7 +816,7 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) Status = CopyBufferToControlPacket(Adapter, (PVOID)pvBuffer); cntrlEnd: up(&Adapter->LowPowerModeSync); - bcm_kfree(pvBuffer); + kfree(pvBuffer); break; } case IOCTL_BCM_BUFFER_DOWNLOAD_START: @@ -924,7 +924,7 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) if(Status != STATUS_SUCCESS) up(&Adapter->fw_download_sema); BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, OSAL_DBG, DBG_LVL_ALL, "IOCTL: Firmware File Uploaded\n"); - bcm_kfree(psFwInfo); + kfree(psFwInfo); break; } case IOCTL_BCM_BUFFER_DOWNLOAD_STOP: @@ -1193,11 +1193,11 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) sizeof(S_MIBS_HOST_STATS_MIBS))) { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy to user failed\n"); - bcm_kfree(temp_buff); + kfree(temp_buff); return -EFAULT; } - bcm_kfree(temp_buff); + kfree(temp_buff); break; } @@ -1246,7 +1246,7 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) /* Get WrmBuffer structure */ if(copy_from_user(pvBuffer, IoBuffer.InputBuffer, IoBuffer.InputLength)) { - bcm_kfree(pvBuffer); + kfree(pvBuffer); Status = -EFAULT; break; } @@ -1256,7 +1256,7 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) if(((ULONG)pBulkBuffer->Register & 0x0F000000) != 0x0F000000 || ((ULONG)pBulkBuffer->Register & 0x3)) { - bcm_kfree(pvBuffer); + kfree(pvBuffer); BCM_DEBUG_PRINT (Adapter, DBG_TYPE_PRINTK, 0, 0,"WRM Done On invalid Address : %x Access Denied.\n",(int)pBulkBuffer->Register); Status = -EINVAL; break; @@ -1271,7 +1271,7 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) (uiTempVar == EEPROM_REJECT_REG_4)) && (cmd == IOCTL_BCM_REGISTER_WRITE)) { - bcm_kfree(pvBuffer); + kfree(pvBuffer); BCM_DEBUG_PRINT (Adapter, DBG_TYPE_PRINTK, 0, 0,"EEPROM Access Denied, not in VSG Mode\n"); Status = -EFAULT; break; @@ -1287,7 +1287,7 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "WRM Failed\n"); } - bcm_kfree(pvBuffer); + kfree(pvBuffer); break; } @@ -1486,7 +1486,7 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) stNVMReadWrite.uiNumBytes)) { Status = -EFAULT; - bcm_kfree(pReadData); + kfree(pReadData); break; } @@ -1501,7 +1501,7 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Device is in Idle/Shutdown Mode\n"); up(&Adapter->NVMRdmWrmLock); - bcm_kfree(pReadData); + kfree(pReadData); return -EACCES; } @@ -1512,13 +1512,13 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) if(Status != STATUS_SUCCESS) { - bcm_kfree(pReadData); + kfree(pReadData); return Status; } if(copy_to_user(stNVMReadWrite.pBuffer, pReadData, (UINT)stNVMReadWrite.uiNumBytes)) { - bcm_kfree(pReadData); + kfree(pReadData); Status = -EFAULT; } } @@ -1533,7 +1533,7 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Device is in Idle/Shutdown Mode\n"); up(&Adapter->NVMRdmWrmLock); - bcm_kfree(pReadData); + kfree(pReadData); return -EACCES; } @@ -1561,7 +1561,7 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"DSD Sig is present neither in Flash nor User provided Input.."); up(&Adapter->NVMRdmWrmLock); - bcm_kfree(pReadData); + kfree(pReadData); return Status; } @@ -1570,7 +1570,7 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"DSD Sig is present neither in Flash nor User provided Input.."); up(&Adapter->NVMRdmWrmLock); - bcm_kfree(pReadData); + kfree(pReadData); return Status; } } @@ -1587,7 +1587,7 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) if(Status != STATUS_SUCCESS) { - bcm_kfree(pReadData); + kfree(pReadData); return Status; } } @@ -1595,7 +1595,7 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, " timetaken by Write/read :%ld msec\n",(tv1.tv_sec - tv0.tv_sec)*1000 +(tv1.tv_usec - tv0.tv_usec)/1000); - bcm_kfree(pReadData); + kfree(pReadData); Status = STATUS_SUCCESS; } break; @@ -1666,7 +1666,7 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Device is in Idle/Shutdown Mode\n"); up(&Adapter->NVMRdmWrmLock); - bcm_kfree(pReadBuff); + kfree(pReadBuff); return -EACCES; } @@ -1706,7 +1706,7 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) } up(&Adapter->NVMRdmWrmLock); - bcm_kfree(pReadBuff); + kfree(pReadBuff); } break ; @@ -1799,7 +1799,7 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Device is in Idle/Shutdown Mode\n"); up(&Adapter->NVMRdmWrmLock); - bcm_kfree(pWriteBuff); + kfree(pWriteBuff); return -EACCES; } @@ -1838,7 +1838,7 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) } while(NOB > 0); BcmFlash2xWriteSig(Adapter,sFlash2xWrite.Section); up(&Adapter->NVMRdmWrmLock); - bcm_kfree(pWriteBuff); + kfree(pWriteBuff); } break ; case IOCTL_BCM_GET_FLASH2X_SECTION_BITMAP : @@ -1874,7 +1874,7 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Device is in Idle/Shutdown Mode\n"); up(&Adapter->NVMRdmWrmLock); - bcm_kfree(psFlash2xBitMap); + kfree(psFlash2xBitMap); return -EACCES; } @@ -1884,10 +1884,10 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) if(Status) { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "copying Flash2x bitMap failed"); - bcm_kfree(psFlash2xBitMap); + kfree(psFlash2xBitMap); return -EFAULT; } - bcm_kfree(psFlash2xBitMap); + kfree(psFlash2xBitMap); } break ; case IOCTL_BCM_SET_ACTIVE_SECTION : @@ -2214,7 +2214,7 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) (Adapter->bPreparingForLowPowerMode ==TRUE)) { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Device is in Idle/Shutdown Mode\n"); - bcm_kfree(pReadBuff); + kfree(pReadBuff); up(&Adapter->NVMRdmWrmLock); return -EACCES; } @@ -2254,7 +2254,7 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) } Adapter->bFlashRawRead = FALSE ; up(&Adapter->NVMRdmWrmLock); - bcm_kfree(pReadBuff); + kfree(pReadBuff); break ; } diff --git a/drivers/staging/bcm/CmHost.c b/drivers/staging/bcm/CmHost.c index 6f388a374ddc..dadfff00f837 100644 --- a/drivers/staging/bcm/CmHost.c +++ b/drivers/staging/bcm/CmHost.c @@ -985,7 +985,7 @@ static VOID CopyToAdapter( register PMINI_ADAPTER Adapter, /**PackInfo[uiSearchRuleIndex].pstSFIndication) { - bcm_kfree(Adapter->PackInfo[uiSearchRuleIndex].pstSFIndication); + kfree(Adapter->PackInfo[uiSearchRuleIndex].pstSFIndication); Adapter->PackInfo[uiSearchRuleIndex].pstSFIndication = NULL; } Adapter->PackInfo[uiSearchRuleIndex].pstSFIndication = pstAddIndication; @@ -1844,7 +1844,7 @@ ULONG StoreCmControlResponseMessage(PMINI_ADAPTER Adapter,PVOID pvBuffer,UINT *p (*puBufferLength) = sizeof(stLocalSFAddIndication); *(stLocalSFAddIndication *)pvBuffer = *pstAddIndication; - bcm_kfree(pstAddIndication); + kfree(pstAddIndication); return 1; } @@ -1931,7 +1931,7 @@ static inline stLocalSFAddIndicationAlt BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "============================================================"); return pstAddIndicationDest; failed_restore_sf_param: - bcm_kfree(pstAddIndicationDest); + kfree(pstAddIndicationDest); BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "<=====" ); return NULL; } @@ -2049,7 +2049,7 @@ INT FreeAdapterDsxBuffer(PMINI_ADAPTER Adapter) { if(Adapter->caDsxReqResp) { - bcm_kfree(Adapter->caDsxReqResp); + kfree(Adapter->caDsxReqResp); } return 0; @@ -2102,7 +2102,7 @@ BOOLEAN CmControlResponseMessage(PMINI_ADAPTER Adapter, /**u16VCID)); CopyBufferToControlPacket(Adapter,(PVOID)Adapter->caDsxReqResp); - bcm_kfree(pstAddIndication); + kfree(pstAddIndication); } break; case DSA_RSP: @@ -2169,7 +2169,7 @@ BOOLEAN CmControlResponseMessage(PMINI_ADAPTER Adapter, /**PackInfo[uiSearchRuleIndex].bActive=FALSE; Adapter->PackInfo[uiSearchRuleIndex].bValid=FALSE; Adapter->PackInfo[uiSearchRuleIndex].usVCID_Value=0; - bcm_kfree(pstAddIndication); + kfree(pstAddIndication); } else if(psfLocalSet->bValid && (pstAddIndication->u8CC == 0)) @@ -2218,13 +2218,13 @@ BOOLEAN CmControlResponseMessage(PMINI_ADAPTER Adapter, /**PackInfo[uiSearchRuleIndex].bActive=FALSE; Adapter->PackInfo[uiSearchRuleIndex].bValid=FALSE; Adapter->PackInfo[uiSearchRuleIndex].usVCID_Value=0; - bcm_kfree(pstAddIndication); + kfree(pstAddIndication); } } else { BCM_DEBUG_PRINT( Adapter,DBG_TYPE_PRINTK, 0, 0, "DSA ACK did not get valid SFID"); - bcm_kfree(pstAddIndication); + kfree(pstAddIndication); return FALSE; } } @@ -2239,7 +2239,7 @@ BOOLEAN CmControlResponseMessage(PMINI_ADAPTER Adapter, /**caDsxReqResp[LEADER_SIZE]))->u8Type = DSC_RSP; CopyBufferToControlPacket(Adapter,(PVOID)Adapter->caDsxReqResp); - bcm_kfree(pstAddIndication); + kfree(pstAddIndication); } break; case DSC_RSP: @@ -2312,13 +2312,13 @@ BOOLEAN CmControlResponseMessage(PMINI_ADAPTER Adapter, /**u8CC == 6) { deleteSFBySfid(Adapter,uiSearchRuleIndex); - bcm_kfree(pstAddIndication); + kfree(pstAddIndication); } } else { BCM_DEBUG_PRINT( Adapter,DBG_TYPE_PRINTK, 0, 0, "DSC ACK did not get valid SFID"); - bcm_kfree(pstAddIndication); + kfree(pstAddIndication); return FALSE; } } @@ -2355,7 +2355,7 @@ BOOLEAN CmControlResponseMessage(PMINI_ADAPTER Adapter, /**RxAppControlQueuelock); wake_up(&Adapter->process_read_wait_queue); - bcm_kfree_skb(skb); + dev_kfree_skb(skb); BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CP_CTRL_PKT, DBG_LVL_ALL, "After wake_up_interruptible"); } @@ -231,7 +231,7 @@ INT flushAllAppQ(void) { PacketToDrop=pTarang->RxAppControlHead; DEQUEUEPACKET(pTarang->RxAppControlHead,pTarang->RxAppControlTail); - bcm_kfree_skb(PacketToDrop); + dev_kfree_skb(PacketToDrop); } pTarang->AppCtrlQueueLen = 0; //dropped contrl packet statistics also should be reset. diff --git a/drivers/staging/bcm/InterfaceDld.c b/drivers/staging/bcm/InterfaceDld.c index 62770e042e51..e640b75e7dc4 100644 --- a/drivers/staging/bcm/InterfaceDld.c +++ b/drivers/staging/bcm/InterfaceDld.c @@ -48,7 +48,7 @@ int InterfaceFileDownload( PVOID arg, on_chip_loc+=MAX_TRANSFER_CTRL_BYTE_USB; }/* End of for(;;)*/ - bcm_kfree(buff); + kfree(buff); return errno; } @@ -69,8 +69,8 @@ int InterfaceFileReadbackFromChip( PVOID arg, buff_readback=(PCHAR)kmalloc(MAX_TRANSFER_CTRL_BYTE_USB , GFP_DMA); if(!buff || !buff_readback) { - bcm_kfree(buff); - bcm_kfree(buff_readback); + kfree(buff); + kfree(buff_readback); return -ENOMEM; } @@ -137,8 +137,8 @@ int InterfaceFileReadbackFromChip( PVOID arg, on_chip_loc+=MAX_TRANSFER_CTRL_BYTE_USB; }/* End of while(1)*/ exit: - bcm_kfree(buff); - bcm_kfree(buff_readback); + kfree(buff); + kfree(buff_readback); return Status; } @@ -164,7 +164,7 @@ static int bcm_download_config_file(PMINI_ADAPTER Adapter, psFwInfo->pvMappedFirmwareAddress, psFwInfo->u32FirmwareLength); if(retval) { - bcm_kfree (Adapter->pstargetparams); + kfree(Adapter->pstargetparams); Adapter->pstargetparams = NULL; return -EFAULT; } @@ -261,7 +261,7 @@ static int bcm_download_buffer(PMINI_ADAPTER Adapter, u32FirmwareLength -= len; mappedbuffer +=len; } - bcm_kfree(buff); + kfree(buff); return retval; } #endif @@ -313,7 +313,7 @@ static int bcm_buffer_readback(PMINI_ADAPTER Adapter, GFP_KERNEL); if(NULL == readbackbuff) { - bcm_kfree(buff); + kfree(buff); return -ENOMEM; } while (u32FirmwareLength && !retval) @@ -343,8 +343,8 @@ static int bcm_buffer_readback(PMINI_ADAPTER Adapter, u32FirmwareLength -= len; mappedbuffer +=len; }/* end of while (u32FirmwareLength && !retval) */ - bcm_kfree(buff); - bcm_kfree(readbackbuff); + kfree(buff); + kfree(readbackbuff); return retval; } #endif @@ -416,7 +416,7 @@ int bcm_ioctl_fw_download(PMINI_ADAPTER Adapter, FIRMWARE_INFO *psFwInfo) } } error: - bcm_kfree(buff); + kfree(buff); return retval; } @@ -479,7 +479,7 @@ static INT buffRdbkVerify(PMINI_ADAPTER Adapter, u32FirmwareLength -= len; mappedbuffer +=len; }/* end of while (u32FirmwareLength && !retval) */ - bcm_kfree(readbackbuff); + kfree(readbackbuff); return retval; } diff --git a/drivers/staging/bcm/InterfaceInit.c b/drivers/staging/bcm/InterfaceInit.c index f810bfd0b1a5..014b06bfbc9f 100644 --- a/drivers/staging/bcm/InterfaceInit.c +++ b/drivers/staging/bcm/InterfaceInit.c @@ -55,7 +55,7 @@ VOID InterfaceAdapterFree(PS_INTERFACE_ADAPTER psIntfAdapter) { if (psIntfAdapter->asUsbRcb[i].urb != NULL) { - bcm_kfree(psIntfAdapter->asUsbRcb[i].urb->transfer_buffer); + kfree(psIntfAdapter->asUsbRcb[i].urb->transfer_buffer); usb_free_urb(psIntfAdapter->asUsbRcb[i].urb); psIntfAdapter->asUsbRcb[i].urb = NULL; } diff --git a/drivers/staging/bcm/InterfaceRx.c b/drivers/staging/bcm/InterfaceRx.c index 6fee9684f2ef..128aa91f7434 100644 --- a/drivers/staging/bcm/InterfaceRx.c +++ b/drivers/staging/bcm/InterfaceRx.c @@ -173,7 +173,7 @@ static void read_bulk_callback(struct urb *urb) else { BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_RX, RX_DATA, DBG_LVL_ALL, "i/f not up hance freeing SKB..."); - bcm_kfree_skb(skb); + dev_kfree_skb(skb); } atomic_inc(&Adapter->GoodRxPktCount); for(uiIndex = 0 ; uiIndex < MIBS_MAX_HIST_ENTRIES ; uiIndex++) diff --git a/drivers/staging/bcm/Makefile b/drivers/staging/bcm/Makefile index 6f6fcee8e4a9..0050206b0fc1 100644 --- a/drivers/staging/bcm/Makefile +++ b/drivers/staging/bcm/Makefile @@ -9,4 +9,4 @@ bcm_wimax-y := InterfaceDld.o InterfaceIdleMode.o InterfaceInit.o InterfaceRx.o Arp.o CmHost.o IPv6Protocol.o Qos.o Transmit.o\ Bcmnet.o DDRInit.o HandleControlPacket.o\ LeakyBucket.o Misc.o sort.o Bcmchar.o hostmibs.o PHSModule.o\ - Osal_Misc.o led_control.o nvm.o vendorspecificextn.o + led_control.o nvm.o vendorspecificextn.o diff --git a/drivers/staging/bcm/Misc.c b/drivers/staging/bcm/Misc.c index 351a8aee88fe..a5ce9593dcff 100644 --- a/drivers/staging/bcm/Misc.c +++ b/drivers/staging/bcm/Misc.c @@ -132,24 +132,24 @@ VOID AdapterFree(PMINI_ADAPTER Adapter) free_netdev(Adapter->dev); if(Adapter->pstargetparams != NULL) { - bcm_kfree(Adapter->pstargetparams); + kfree(Adapter->pstargetparams); } for (count =0;count < MAX_CNTRL_PKTS;count++) { if(Adapter->txctlpacket[count]) - bcm_kfree(Adapter->txctlpacket[count]); + kfree(Adapter->txctlpacket[count]); } FreeAdapterDsxBuffer(Adapter); if(Adapter->pvInterfaceAdapter) - bcm_kfree(Adapter->pvInterfaceAdapter); + kfree(Adapter->pvInterfaceAdapter); //Free the PHS Interface PhsCleanup(&Adapter->stBCMPhsContext); BcmDeAllocFlashCSStructure(Adapter); - bcm_kfree (Adapter); + kfree(Adapter); BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "<========\n"); } @@ -259,25 +259,6 @@ exit_download: return errorno; } - -void bcm_kfree_skb(struct sk_buff *skb) -{ - if(skb) - { - kfree_skb(skb); - } - skb = NULL ; -} - -VOID bcm_kfree(VOID *ptr) -{ - if(ptr) - { - kfree(ptr); - } - ptr = NULL ; -} - /** @ingroup ctrl_pkt_functions This function copies the contents of given buffer @@ -579,7 +560,7 @@ __inline VOID LinkMessage(PMINI_ADAPTER Adapter) { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LINK_UP_MSG, DBG_LVL_ALL, "Calling CopyBufferToControlPacket"); CopyBufferToControlPacket(Adapter, pstLinkRequest); - bcm_kfree(pstLinkRequest); + kfree(pstLinkRequest); } BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LINK_UP_MSG, DBG_LVL_ALL, "LinkMessage <====="); return; @@ -1292,14 +1273,14 @@ int bcm_parse_target_params(PMINI_ADAPTER Adapter) if((Adapter->pstargetparams = kmalloc(sizeof(STARGETPARAMS), GFP_KERNEL)) == NULL) { - bcm_kfree(buff); + kfree(buff); return -ENOMEM; } flp=open_firmware_file(Adapter, CFG_FILE); if(!flp) { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "NOT ABLE TO OPEN THE %s FILE \n", CFG_FILE); - bcm_kfree(buff); - bcm_kfree(Adapter->pstargetparams); + kfree(buff); + kfree(Adapter->pstargetparams); Adapter->pstargetparams = NULL; return -ENOENT; } @@ -1310,8 +1291,8 @@ int bcm_parse_target_params(PMINI_ADAPTER Adapter) if(len != sizeof(STARGETPARAMS)) { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL,"Mismatch in Target Param Structure!\n"); - bcm_kfree(buff); - bcm_kfree(Adapter->pstargetparams); + kfree(buff); + kfree(Adapter->pstargetparams); Adapter->pstargetparams = NULL; filp_close(flp, current->files); return -ENOENT; @@ -1323,7 +1304,7 @@ int bcm_parse_target_params(PMINI_ADAPTER Adapter) * Values in Adapter->pstargetparams are in network byte order */ memcpy(Adapter->pstargetparams, buff, sizeof(STARGETPARAMS)); - bcm_kfree (buff); + kfree (buff); beceem_parse_target_struct(Adapter); return STATUS_SUCCESS; } @@ -1478,7 +1459,7 @@ static unsigned char *ReadMacAddrEEPROM(PMINI_ADAPTER Adapter, ulong dwAddress) if(status != STATUS_SUCCESS) { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "wrm Failed..\n"); - bcm_kfree(pucmacaddr); + kfree(pucmacaddr); pucmacaddr = NULL; goto OUT; } @@ -1488,7 +1469,7 @@ static unsigned char *ReadMacAddrEEPROM(PMINI_ADAPTER Adapter, ulong dwAddress) if(status != STATUS_SUCCESS) { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "rdm Failed..\n"); - bcm_kfree(pucmacaddr); + kfree(pucmacaddr); pucmacaddr = NULL; goto OUT; } @@ -1522,7 +1503,7 @@ INT ReadMacAddressFromEEPROM(PMINI_ADAPTER Adapter) puMacAddr[4] == 0xFF && puMacAddr[5] == 0xFF)) { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Invalid Mac Address\n"); - bcm_kfree(puMacAddr); + kfree(puMacAddr); return STATUS_FAILURE; } BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "The Mac Address received is: \n"); @@ -1532,7 +1513,7 @@ INT ReadMacAddressFromEEPROM(PMINI_ADAPTER Adapter) BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"%02x ", Adapter->dev->dev_addr[i]); } BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"\n"); - bcm_kfree(puMacAddr); + kfree(puMacAddr); } return STATUS_SUCCESS; } @@ -1980,7 +1961,7 @@ void flush_queue(PMINI_ADAPTER Adapter, UINT iQIndex) Adapter->PackInfo[iQIndex].uiDroppedCountBytes += PacketToDrop->len; Adapter->PackInfo[iQIndex].uiDroppedCountPackets++; - bcm_kfree_skb(PacketToDrop); + dev_kfree_skb(PacketToDrop); atomic_dec(&Adapter->TotalPacketCount); atomic_inc(&Adapter->TxDroppedPacketCount); diff --git a/drivers/staging/bcm/Osal_Misc.c b/drivers/staging/bcm/Osal_Misc.c deleted file mode 100644 index feefd20a5291..000000000000 --- a/drivers/staging/bcm/Osal_Misc.c +++ /dev/null @@ -1,27 +0,0 @@ - /*++ - - Copyright (c) Beceem Communications Inc. - - Module Name: - WIN_Misc.c - - Abstract: - Implements the Miscelanneous OS Construts - Linked Lists - Dispatcher Objects(Events,Semaphores,Spin Locks and the like) - Files - - Revision History: - Who When What - -------- -------- ---------------------------------------------- - Name Date Created/reviewed/modified - Rajeev 24/1/08 Created - Notes: - - --*/ -#include "headers.h" - -bool OsalMemCompare(void *dest, void *src, UINT len) -{ - return (memcmp(src, dest, len)); -} diff --git a/drivers/staging/bcm/PHSModule.c b/drivers/staging/bcm/PHSModule.c index 8a38cf43e795..e0456b291d6c 100644 --- a/drivers/staging/bcm/PHSModule.c +++ b/drivers/staging/bcm/PHSModule.c @@ -120,15 +120,15 @@ int PHSTransmit(PMINI_ADAPTER Adapter, if(newPacket == NULL) return STATUS_FAILURE; - bcm_kfree_skb(Packet); + dev_kfree_skb(Packet); *pPacket = Packet = newPacket; pucPHSPktHdrInBuf = Packet->data + BytesToRemove; } numBytesCompressed = unPhsOldHdrSize - (unPHSNewPktHeaderLen+PHSI_LEN); - OsalMemMove(pucPHSPktHdrInBuf + numBytesCompressed, pucPHSPktHdrOutBuf, unPHSNewPktHeaderLen + PHSI_LEN); - OsalMemMove(Packet->data + numBytesCompressed, Packet->data, BytesToRemove); + memcpy(pucPHSPktHdrInBuf + numBytesCompressed, pucPHSPktHdrOutBuf, unPHSNewPktHeaderLen + PHSI_LEN); + memcpy(Packet->data + numBytesCompressed, Packet->data, BytesToRemove); skb_pull(Packet, numBytesCompressed); return STATUS_SUCCESS; @@ -223,7 +223,7 @@ int PHSRecieve(PMINI_ADAPTER Adapter, } } - OsalMemMove(packet->data, Adapter->ucaPHSPktRestoreBuf, nStandardPktHdrLen); + memcpy(packet->data, Adapter->ucaPHSPktRestoreBuf, nStandardPktHdrLen); } return STATUS_SUCCESS; @@ -270,15 +270,9 @@ int phs_init(PPHS_DEVICE_EXTENSION pPhsdeviceExtension,PMINI_ADAPTER Adapter) return -EINVAL; pPhsdeviceExtension->pstServiceFlowPhsRulesTable = - (S_SERVICEFLOW_TABLE*)OsalMemAlloc(sizeof(S_SERVICEFLOW_TABLE), - PHS_MEM_TAG); + kzalloc(sizeof(S_SERVICEFLOW_TABLE), GFP_KERNEL); - if(pPhsdeviceExtension->pstServiceFlowPhsRulesTable) - { - OsalZeroMemory(pPhsdeviceExtension->pstServiceFlowPhsRulesTable, - sizeof(S_SERVICEFLOW_TABLE)); - } - else + if(!pPhsdeviceExtension->pstServiceFlowPhsRulesTable) { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nAllocation ServiceFlowPhsRulesTable failed"); return -ENOMEM; @@ -288,14 +282,8 @@ int phs_init(PPHS_DEVICE_EXTENSION pPhsdeviceExtension,PMINI_ADAPTER Adapter) for(i=0;istSFList[i]; - sServiceFlow.pstClassifierTable = (S_CLASSIFIER_TABLE*)OsalMemAlloc( - sizeof(S_CLASSIFIER_TABLE), PHS_MEM_TAG); - if(sServiceFlow.pstClassifierTable) - { - OsalZeroMemory(sServiceFlow.pstClassifierTable,sizeof(S_CLASSIFIER_TABLE)); - pstServiceFlowTable->stSFList[i].pstClassifierTable = sServiceFlow.pstClassifierTable; - } - else + sServiceFlow.pstClassifierTable = kzalloc(sizeof(S_CLASSIFIER_TABLE), GFP_KERNEL); + if(!sServiceFlow.pstClassifierTable) { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nAllocation failed"); free_phs_serviceflow_rules(pPhsdeviceExtension-> @@ -305,9 +293,7 @@ int phs_init(PPHS_DEVICE_EXTENSION pPhsdeviceExtension,PMINI_ADAPTER Adapter) } } - - pPhsdeviceExtension->CompressedTxBuffer = - OsalMemAlloc(PHS_BUFFER_SIZE,PHS_MEM_TAG); + pPhsdeviceExtension->CompressedTxBuffer = kmalloc(PHS_BUFFER_SIZE, GFP_KERNEL); if(pPhsdeviceExtension->CompressedTxBuffer == NULL) { @@ -317,12 +303,11 @@ int phs_init(PPHS_DEVICE_EXTENSION pPhsdeviceExtension,PMINI_ADAPTER Adapter) return -ENOMEM; } - pPhsdeviceExtension->UnCompressedRxBuffer = - OsalMemAlloc(PHS_BUFFER_SIZE,PHS_MEM_TAG); + pPhsdeviceExtension->UnCompressedRxBuffer = kmalloc(PHS_BUFFER_SIZE, GFP_KERNEL); if(pPhsdeviceExtension->UnCompressedRxBuffer == NULL) { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nAllocation failed"); - OsalMemFree(pPhsdeviceExtension->CompressedTxBuffer,PHS_BUFFER_SIZE); + kfree(pPhsdeviceExtension->CompressedTxBuffer); free_phs_serviceflow_rules(pPhsdeviceExtension->pstServiceFlowPhsRulesTable); pPhsdeviceExtension->pstServiceFlowPhsRulesTable = NULL; return -ENOMEM; @@ -343,16 +328,11 @@ int PhsCleanup(IN PPHS_DEVICE_EXTENSION pPHSDeviceExt) pPHSDeviceExt->pstServiceFlowPhsRulesTable = NULL; } - if(pPHSDeviceExt->CompressedTxBuffer) - { - OsalMemFree(pPHSDeviceExt->CompressedTxBuffer,PHS_BUFFER_SIZE); - pPHSDeviceExt->CompressedTxBuffer = NULL; - } - if(pPHSDeviceExt->UnCompressedRxBuffer) - { - OsalMemFree(pPHSDeviceExt->UnCompressedRxBuffer,PHS_BUFFER_SIZE); - pPHSDeviceExt->UnCompressedRxBuffer = NULL; - } + kfree(pPHSDeviceExt->CompressedTxBuffer); + pPHSDeviceExt->CompressedTxBuffer = NULL; + + kfree(pPHSDeviceExt->UnCompressedRxBuffer); + pPHSDeviceExt->UnCompressedRxBuffer = NULL; return 0; } @@ -478,20 +458,12 @@ ULONG PhsDeletePHSRule(IN void* pvContext,IN B_UINT16 uiVcid,IN B_UINT8 u8PHSI) { if(pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].bUsed && pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule) { - if(pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex] - .pstPhsRule->u8PHSI == u8PHSI) - { - if(pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule - ->u8RefCnt) - pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule - ->u8RefCnt--; - if(0 == pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex] - .pstPhsRule->u8RefCnt) - OsalMemFree(pstClassifierRulesTable - ->stActivePhsRulesList[nClsidIndex].pstPhsRule, - sizeof(S_PHS_RULE)); - OsalZeroMemory(&pstClassifierRulesTable - ->stActivePhsRulesList[nClsidIndex], + if(pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule->u8PHSI == u8PHSI) { + if(pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule->u8RefCnt) + pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule->u8RefCnt--; + if(0 == pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule->u8RefCnt) + kfree(pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule); + memset(&pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex], 0, sizeof(S_CLASSIFIER_ENTRY)); } } @@ -548,10 +520,10 @@ ULONG PhsDeleteClassifierRule(IN void* pvContext,IN B_UINT16 uiVcid ,IN B_UINT16 if(pstClassifierEntry->pstPhsRule->u8RefCnt) pstClassifierEntry->pstPhsRule->u8RefCnt--; if(0==pstClassifierEntry->pstPhsRule->u8RefCnt) - OsalMemFree(pstClassifierEntry->pstPhsRule,sizeof(S_PHS_RULE)); + kfree(pstClassifierEntry->pstPhsRule); } - OsalZeroMemory(pstClassifierEntry,sizeof(S_CLASSIFIER_ENTRY)); + memset(pstClassifierEntry, 0, sizeof(S_CLASSIFIER_ENTRY)); } nClsidIndex = GetClassifierEntry(pstServiceFlowEntry->pstClassifierTable, @@ -559,10 +531,8 @@ ULONG PhsDeleteClassifierRule(IN void* pvContext,IN B_UINT16 uiVcid ,IN B_UINT16 if((nClsidIndex != PHS_INVALID_TABLE_INDEX) && (!pstClassifierEntry->bUnclassifiedPHSRule)) { - if(pstClassifierEntry->pstPhsRule) - //Delete the classifier entry - OsalMemFree(pstClassifierEntry->pstPhsRule,sizeof(S_PHS_RULE)); - OsalZeroMemory(pstClassifierEntry,sizeof(S_CLASSIFIER_ENTRY)); + kfree(pstClassifierEntry->pstPhsRule); + memset(pstClassifierEntry, 0, sizeof(S_CLASSIFIER_ENTRY)); } } return lStatus; @@ -619,14 +589,11 @@ ULONG PhsDeleteSFRules(IN void* pvContext,IN B_UINT16 uiVcid) .pstPhsRule->u8RefCnt--; if(0==pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex] .pstPhsRule->u8RefCnt) - OsalMemFree(pstClassifierRulesTable - ->stActivePhsRulesList[nClsidIndex].pstPhsRule, - sizeof(S_PHS_RULE)); + kfree(pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex].pstPhsRule); pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex] .pstPhsRule = NULL; } - OsalZeroMemory(&pstClassifierRulesTable - ->stActivePhsRulesList[nClsidIndex],sizeof(S_CLASSIFIER_ENTRY)); + memset(&pstClassifierRulesTable->stActivePhsRulesList[nClsidIndex], 0, sizeof(S_CLASSIFIER_ENTRY)); if(pstClassifierRulesTable->stOldPhsRulesList[nClsidIndex].pstPhsRule) { if(pstClassifierRulesTable->stOldPhsRulesList[nClsidIndex] @@ -635,15 +602,12 @@ ULONG PhsDeleteSFRules(IN void* pvContext,IN B_UINT16 uiVcid) .pstPhsRule->u8RefCnt--; if(0 == pstClassifierRulesTable->stOldPhsRulesList[nClsidIndex] .pstPhsRule->u8RefCnt) - OsalMemFree(pstClassifierRulesTable - ->stOldPhsRulesList[nClsidIndex].pstPhsRule, - sizeof(S_PHS_RULE)); + kfree(pstClassifierRulesTable + ->stOldPhsRulesList[nClsidIndex].pstPhsRule); pstClassifierRulesTable->stOldPhsRulesList[nClsidIndex] .pstPhsRule = NULL; } - OsalZeroMemory(&pstClassifierRulesTable - ->stOldPhsRulesList[nClsidIndex], - sizeof(S_CLASSIFIER_ENTRY)); + memset(&pstClassifierRulesTable->stOldPhsRulesList[nClsidIndex], 0, sizeof(S_CLASSIFIER_ENTRY)); } } pstServiceFlowEntry->bUsed = FALSE; @@ -876,8 +840,7 @@ void free_phs_serviceflow_rules(S_SERVICEFLOW_TABLE *psServiceFlowRulesTable) ->u8RefCnt--; if(0==pstClassifierRulesTable->stActivePhsRulesList[j].pstPhsRule ->u8RefCnt) - OsalMemFree(pstClassifierRulesTable->stActivePhsRulesList[j]. - pstPhsRule, sizeof(S_PHS_RULE)); + kfree(pstClassifierRulesTable->stActivePhsRulesList[j].pstPhsRule); pstClassifierRulesTable->stActivePhsRulesList[j].pstPhsRule = NULL; } if(pstClassifierRulesTable->stOldPhsRulesList[j].pstPhsRule) @@ -888,19 +851,18 @@ void free_phs_serviceflow_rules(S_SERVICEFLOW_TABLE *psServiceFlowRulesTable) ->u8RefCnt--; if(0==pstClassifierRulesTable->stOldPhsRulesList[j].pstPhsRule ->u8RefCnt) - OsalMemFree(pstClassifierRulesTable->stOldPhsRulesList[j] - .pstPhsRule,sizeof(S_PHS_RULE)); + kfree(pstClassifierRulesTable->stOldPhsRulesList[j].pstPhsRule); pstClassifierRulesTable->stOldPhsRulesList[j].pstPhsRule = NULL; } } - OsalMemFree(pstClassifierRulesTable,sizeof(S_CLASSIFIER_TABLE)); + kfree(pstClassifierRulesTable); stServiceFlowEntry.pstClassifierTable = pstClassifierRulesTable = NULL; } } } - OsalMemFree(psServiceFlowRulesTable,sizeof(S_SERVICEFLOW_TABLE)); - psServiceFlowRulesTable = NULL; + kfree(psServiceFlowRulesTable); + psServiceFlowRulesTable = NULL; } @@ -1102,7 +1064,7 @@ UINT CreateClassiferToPHSRuleMapping(IN B_UINT16 uiVcid, if(psPhsRule->u8PHSFLength) { //update PHSF - OsalMemMove(pstClassifierEntry->pstPhsRule->u8PHSF, + memcpy(pstClassifierEntry->pstPhsRule->u8PHSF, psPhsRule->u8PHSF , MAX_PHS_LENGTHS); } if(psPhsRule->u8PHSFLength) @@ -1114,7 +1076,7 @@ UINT CreateClassiferToPHSRuleMapping(IN B_UINT16 uiVcid, if(psPhsRule->u8PHSMLength) { //update PHSM - OsalMemMove(pstClassifierEntry->pstPhsRule->u8PHSM, + memcpy(pstClassifierEntry->pstPhsRule->u8PHSM, psPhsRule->u8PHSM, MAX_PHS_LENGTHS); } if(psPhsRule->u8PHSMLength) @@ -1234,8 +1196,7 @@ UINT CreateClassifierPHSRule(IN B_UINT16 uiClsId, { if(psClassifierRules->pstPhsRule == NULL) { - psClassifierRules->pstPhsRule = (S_PHS_RULE*)OsalMemAlloc - (sizeof(S_PHS_RULE),PHS_MEM_TAG); + psClassifierRules->pstPhsRule = kmalloc(sizeof(S_PHS_RULE),GFP_KERNEL); if(NULL == psClassifierRules->pstPhsRule) return ERR_PHSRULE_MEMALLOC_FAIL; @@ -1247,7 +1208,7 @@ UINT CreateClassifierPHSRule(IN B_UINT16 uiClsId, psClassifierRules->bUnclassifiedPHSRule = psPhsRule->bUnclassifiedPHSRule; /* Update The PHS rule */ - OsalMemMove(psClassifierRules->pstPhsRule, + memcpy(psClassifierRules->pstPhsRule, psPhsRule, sizeof(S_PHS_RULE)); } else @@ -1289,13 +1250,13 @@ UINT UpdateClassifierPHSRule(IN B_UINT16 uiClsId, //Step 2.a PHS Rule Does Not Exist .Create New PHS Rule for uiClsId if(FALSE == bPHSRuleOrphaned) { - pstClassifierEntry->pstPhsRule = (S_PHS_RULE*)OsalMemAlloc(sizeof(S_PHS_RULE),PHS_MEM_TAG); + pstClassifierEntry->pstPhsRule = kmalloc(sizeof(S_PHS_RULE), GFP_KERNEL); if(NULL == pstClassifierEntry->pstPhsRule) { return ERR_PHSRULE_MEMALLOC_FAIL; } } - OsalMemMove(pstClassifierEntry->pstPhsRule, psPhsRule, sizeof(S_PHS_RULE)); + memcpy(pstClassifierEntry->pstPhsRule, psPhsRule, sizeof(S_PHS_RULE)); } else @@ -1304,14 +1265,8 @@ UINT UpdateClassifierPHSRule(IN B_UINT16 uiClsId, BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\nTying Classifier to Existing PHS Rule"); if(bPHSRuleOrphaned) { - if(pstClassifierEntry->pstPhsRule) - { - //Just Free the PHS Rule as Ref Count is Zero - OsalMemFree(pstClassifierEntry->pstPhsRule,sizeof(S_PHS_RULE)); + kfree(pstClassifierEntry->pstPhsRule); pstClassifierEntry->pstPhsRule = NULL; - - } - } pstClassifierEntry->pstPhsRule = pstAddPhsRule; diff --git a/drivers/staging/bcm/Prototypes.h b/drivers/staging/bcm/Prototypes.h index 82738be3ed48..286ea46cd996 100644 --- a/drivers/staging/bcm/Prototypes.h +++ b/drivers/staging/bcm/Prototypes.h @@ -11,10 +11,6 @@ VOID StatisticsResponse(PMINI_ADAPTER Adapter,PVOID pvBuffer); VOID IdleModeResponse(PMINI_ADAPTER Adapter,PUINT puiBuffer); -void bcm_kfree_skb(struct sk_buff *skb); -VOID bcm_kfree(VOID *ptr); - - VOID handle_rx_control_packet(PMINI_ADAPTER Adapter, /**PackInfo[iIndex].uiDroppedCountBytes += PacketToDrop->len; Adapter->PackInfo[iIndex].uiDroppedCountPackets++; - bcm_kfree_skb(PacketToDrop); + dev_kfree_skb(PacketToDrop); } @@ -455,7 +455,7 @@ VOID flush_all_queues(PMINI_ADAPTER Adapter) Adapter->PackInfo[iQIndex].LastTxQueue); /* Free the skb */ - bcm_kfree_skb(PacketToDrop); + dev_kfree_skb(PacketToDrop); /// update current bytes and packets count Adapter->PackInfo[iQIndex].uiCurrentBytesOnHost -= uiTotalPacketLength; diff --git a/drivers/staging/bcm/Transmit.c b/drivers/staging/bcm/Transmit.c index 9848a6a95fb7..9932d71a6fe0 100644 --- a/drivers/staging/bcm/Transmit.c +++ b/drivers/staging/bcm/Transmit.c @@ -117,7 +117,7 @@ INT bcm_transmit(struct sk_buff *skb, /**< skb */ BCM_DEBUG_PRINT (Adapter, DBG_TYPE_TX, TX_OSAL_DBG, DBG_LVL_ALL, "Invalid queue index, dropping pkt\n"); - bcm_kfree_skb(skb); + dev_kfree_skb(skb); } return STATUS_SUCCESS; } @@ -125,7 +125,7 @@ INT bcm_transmit(struct sk_buff *skb, /**< skb */ if(Adapter->PackInfo[qindex].uiCurrentPacketsOnHost >= SF_MAX_ALLOWED_PACKETS_TO_BACKUP) { atomic_inc(&Adapter->TxDroppedPacketCount); - bcm_kfree_skb(skb); + dev_kfree_skb(skb); return STATUS_SUCCESS; } @@ -159,7 +159,7 @@ INT bcm_transmit(struct sk_buff *skb, /**< skb */ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_OSAL_DBG, DBG_LVL_ALL, "<===="); } else - bcm_kfree_skb(skb); + dev_kfree_skb(skb); return STATUS_SUCCESS; } @@ -333,7 +333,7 @@ errExit: } - bcm_kfree_skb(Packet); + dev_kfree_skb(Packet); return status; } diff --git a/drivers/staging/bcm/headers.h b/drivers/staging/bcm/headers.h index b90d8a3e879b..d4a200329bab 100644 --- a/drivers/staging/bcm/headers.h +++ b/drivers/staging/bcm/headers.h @@ -58,7 +58,6 @@ #include "Debug.h" #include "HostMibs.h" #include "IPv6ProtocolHdr.h" -#include "osal_misc.h" #include "PHSModule.h" #include "Protocol.h" #include "Prototypes.h" diff --git a/drivers/staging/bcm/hostmibs.c b/drivers/staging/bcm/hostmibs.c index e9da513b3c24..0d75ff7add75 100644 --- a/drivers/staging/bcm/hostmibs.c +++ b/drivers/staging/bcm/hostmibs.c @@ -54,7 +54,7 @@ INT ProcessGetHostMibs(PMINI_ADAPTER Adapter, { if(Adapter->PackInfo[nSfIndex].bValid) { - OsalMemMove((PVOID)&pstHostMibs->astSFtable[nSfIndex],(PVOID)&Adapter->PackInfo[nSfIndex],sizeof(S_MIBS_SERVICEFLOW_TABLE)); + memcpy((PVOID)&pstHostMibs->astSFtable[nSfIndex],(PVOID)&Adapter->PackInfo[nSfIndex],sizeof(S_MIBS_SERVICEFLOW_TABLE)); } else { @@ -83,7 +83,7 @@ INT ProcessGetHostMibs(PMINI_ADAPTER Adapter, pstHostMibs->astPhsRulesTable[nPhsTableIndex].ulSFID = Adapter->PackInfo[nSfIndex].ulSFID; - OsalMemMove(&pstHostMibs->astPhsRulesTable[nPhsTableIndex].u8PHSI, + memcpy(&pstHostMibs->astPhsRulesTable[nPhsTableIndex].u8PHSI, &pstPhsRule->u8PHSI, sizeof(S_PHS_RULE)); nPhsTableIndex++; diff --git a/drivers/staging/bcm/led_control.c b/drivers/staging/bcm/led_control.c index f2b6939f5178..79c7bd74804d 100644 --- a/drivers/staging/bcm/led_control.c +++ b/drivers/staging/bcm/led_control.c @@ -293,7 +293,7 @@ static INT ValidateDSDParamsChecksum( BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"LED Thread:ValidateDSDParamsChecksum: 0x%lx 0x%X",ulParamOffset, usParamLen); - puBuffer = OsalMemAlloc(usParamLen,"!MEM"); + puBuffer = kmalloc(usParamLen, GFP_KERNEL); if(!puBuffer) { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"LED Thread: ValidateDSDParamsChecksum Allocation failed"); @@ -341,10 +341,7 @@ static INT ValidateDSDParamsChecksum( } exit: - if(puBuffer) - { - OsalMemFree(puBuffer, usParamLen); - } + kfree(puBuffer); return Status; } diff --git a/drivers/staging/bcm/nvm.c b/drivers/staging/bcm/nvm.c index 95716f596e6c..4a0205334749 100644 --- a/drivers/staging/bcm/nvm.c +++ b/drivers/staging/bcm/nvm.c @@ -228,7 +228,7 @@ INT ReadBeceemEEPROM( PMINI_ADAPTER Adapter, ReadBeceemEEPROMBulk(Adapter, uiTempOffset + MAX_RW_SIZE, (PUINT)&uiData[4], 4); } - OsalMemMove( (PUCHAR) pBuffer, ( ((PUCHAR)&uiData[0]) + uiByteOffset ), 4); + memcpy( (PUCHAR) pBuffer, ( ((PUCHAR)&uiData[0]) + uiByteOffset ), 4); return STATUS_SUCCESS; } /* ReadBeceemEEPROM() */ @@ -476,7 +476,7 @@ INT BeceemEEPROMBulkRead( ReadBeceemEEPROMBulk(Adapter,uiTempOffset,(PUINT)&uiData[0],4); if(uiBytesRemaining >= (MAX_RW_SIZE - uiExtraBytes)) { - OsalMemMove(pBuffer,(((PUCHAR)&uiData[0])+uiExtraBytes),MAX_RW_SIZE - uiExtraBytes); + memcpy(pBuffer,(((PUCHAR)&uiData[0])+uiExtraBytes),MAX_RW_SIZE - uiExtraBytes); uiBytesRemaining -= (MAX_RW_SIZE - uiExtraBytes); uiIndex += (MAX_RW_SIZE - uiExtraBytes); @@ -484,7 +484,7 @@ INT BeceemEEPROMBulkRead( } else { - OsalMemMove(pBuffer,(((PUCHAR)&uiData[0])+uiExtraBytes),uiBytesRemaining); + memcpy(pBuffer,(((PUCHAR)&uiData[0])+uiExtraBytes),uiBytesRemaining); uiIndex += uiBytesRemaining; uiOffset += uiBytesRemaining; uiBytesRemaining = 0; @@ -508,7 +508,7 @@ INT BeceemEEPROMBulkRead( * We read 4 Dwords of data */ if(0 == ReadBeceemEEPROMBulk(Adapter,uiOffset,&uiData[0],4)) { - OsalMemMove(pcBuff+uiIndex,&uiData[0],MAX_RW_SIZE); + memcpy(pcBuff+uiIndex,&uiData[0],MAX_RW_SIZE); uiOffset += MAX_RW_SIZE; uiBytesRemaining -= MAX_RW_SIZE; uiIndex += MAX_RW_SIZE; @@ -523,7 +523,7 @@ INT BeceemEEPROMBulkRead( { if(0 == ReadBeceemEEPROM(Adapter,uiOffset,&uiData[0])) { - OsalMemMove(pcBuff+uiIndex,&uiData[0],4); + memcpy(pcBuff+uiIndex,&uiData[0],4); uiOffset += 4; uiBytesRemaining -= 4; uiIndex +=4; @@ -540,7 +540,7 @@ INT BeceemEEPROMBulkRead( pCharBuff += uiIndex; if(0 == ReadBeceemEEPROM(Adapter,uiOffset,&uiData[0])) { - OsalMemMove(pCharBuff,&uiData[0],uiBytesRemaining);//copy only bytes requested. + memcpy(pCharBuff,&uiData[0],uiBytesRemaining);//copy only bytes requested. uiBytesRemaining = 0; } else @@ -973,7 +973,7 @@ static INT flashWrite( // need not write 0xFFFFFFFF because write requires an erase and erase will // make whole sector 0xFFFFFFFF. // - if (!OsalMemCompare(pData, uiErasePattern, MAX_RW_SIZE)) + if (!memcmp(pData, uiErasePattern, MAX_RW_SIZE)) { return 0; } @@ -1138,7 +1138,7 @@ static INT flashWriteStatus( // need not write 0xFFFFFFFF because write requires an erase and erase will // make whole sector 0xFFFFFFFF. // - if (!OsalMemCompare(pData,uiErasePattern,MAX_RW_SIZE)) + if (!memcmp(pData,uiErasePattern,MAX_RW_SIZE)) { return 0; } @@ -1377,12 +1377,9 @@ INT BeceemFlashBulkWrite( uiCurrSectOffsetAddr = uiOffset & (Adapter->uiSectorSize - 1); uiSectBoundary = uiSectAlignAddr + Adapter->uiSectorSize; - //pTempBuff = OsalMemAlloc(MAX_SECTOR_SIZE,'!MVN'); - pTempBuff = OsalMemAlloc(Adapter->uiSectorSize ,"!MVN"); + pTempBuff = kmalloc(Adapter->uiSectorSize, GFP_KERNEL); if(NULL == pTempBuff) - { goto BeceemFlashBulkWrite_EXIT; - } // // check if the data to be written is overlapped accross sectors // @@ -1448,13 +1445,13 @@ INT BeceemFlashBulkWrite( if(uiNumSectTobeRead > 1) { - OsalMemMove(&pTempBuff[uiCurrSectOffsetAddr],pcBuffer,uiSectBoundary-(uiSectAlignAddr+uiCurrSectOffsetAddr)); + memcpy(&pTempBuff[uiCurrSectOffsetAddr],pcBuffer,uiSectBoundary-(uiSectAlignAddr+uiCurrSectOffsetAddr)); pcBuffer += ((uiSectBoundary-(uiSectAlignAddr+uiCurrSectOffsetAddr))); uiNumBytes -= (uiSectBoundary-(uiSectAlignAddr+uiCurrSectOffsetAddr)); } else { - OsalMemMove(&pTempBuff[uiCurrSectOffsetAddr],pcBuffer,uiNumBytes); + memcpy(&pTempBuff[uiCurrSectOffsetAddr],pcBuffer,uiNumBytes); } if(IsFlash2x(Adapter)) @@ -1503,7 +1500,7 @@ INT BeceemFlashBulkWrite( } else { - if(OsalMemCompare(ucReadBk,&pTempBuff[uiIndex],MAX_RW_SIZE)) + if(memcmp(ucReadBk,&pTempBuff[uiIndex],MAX_RW_SIZE)) { if(STATUS_SUCCESS != (*Adapter->fpFlashWriteWithStatusCheck)(Adapter,uiPartOffset+uiIndex,&pTempBuff[uiIndex])) { @@ -1541,10 +1538,8 @@ BeceemFlashBulkWrite_EXIT: { BcmRestoreBlockProtectStatus(Adapter,ulStatus); } - if(pTempBuff) - { - OsalMemFree(pTempBuff,Adapter->uiSectorSize); - } + + kfree(pTempBuff); Adapter->SelectedChip = RESET_CHIP_SELECT; return Status; @@ -1599,14 +1594,10 @@ static INT BeceemFlashBulkWriteStatus( uiCurrSectOffsetAddr = uiOffset & (Adapter->uiSectorSize - 1); uiSectBoundary = uiSectAlignAddr + Adapter->uiSectorSize; - - -// pTempBuff = OsalMemAlloc(MAX_SECTOR_SIZE,'!MVN'); - pTempBuff = OsalMemAlloc(Adapter->uiSectorSize,"!MVN"); + pTempBuff = kmalloc(Adapter->uiSectorSize, GFP_KERNEL); if(NULL == pTempBuff) - { goto BeceemFlashBulkWriteStatus_EXIT; - } + // // check if the data to be written is overlapped accross sectors // @@ -1662,13 +1653,13 @@ static INT BeceemFlashBulkWriteStatus( if(uiNumSectTobeRead > 1) { - OsalMemMove(&pTempBuff[uiCurrSectOffsetAddr],pcBuffer,uiSectBoundary-(uiSectAlignAddr+uiCurrSectOffsetAddr)); + memcpy(&pTempBuff[uiCurrSectOffsetAddr],pcBuffer,uiSectBoundary-(uiSectAlignAddr+uiCurrSectOffsetAddr)); pcBuffer += ((uiSectBoundary-(uiSectAlignAddr+uiCurrSectOffsetAddr))); uiNumBytes -= (uiSectBoundary-(uiSectAlignAddr+uiCurrSectOffsetAddr)); } else { - OsalMemMove(&pTempBuff[uiCurrSectOffsetAddr],pcBuffer,uiNumBytes); + memcpy(&pTempBuff[uiCurrSectOffsetAddr],pcBuffer,uiNumBytes); } if(IsFlash2x(Adapter)) @@ -1716,7 +1707,7 @@ static INT BeceemFlashBulkWriteStatus( if(STATUS_SUCCESS == BeceemFlashBulkRead(Adapter,(PUINT)ucReadBk,uiOffsetFromSectStart+uiIndex,MAX_RW_SIZE)) { - if(OsalMemCompare(ucReadBk,&pTempBuff[uiIndex],MAX_RW_SIZE)) + if(memcmp(ucReadBk,&pTempBuff[uiIndex],MAX_RW_SIZE)) { Status = STATUS_FAILURE; goto BeceemFlashBulkWriteStatus_EXIT; @@ -1747,10 +1738,8 @@ BeceemFlashBulkWriteStatus_EXIT: { BcmRestoreBlockProtectStatus(Adapter,ulStatus); } - if(pTempBuff) - { - OsalMemFree(pTempBuff,Adapter->uiSectorSize); - } + + kfree(pTempBuff); Adapter->SelectedChip = RESET_CHIP_SELECT; return Status; @@ -1771,7 +1760,7 @@ BeceemFlashBulkWriteStatus_EXIT: INT PropagateCalParamsFromEEPROMToMemory(PMINI_ADAPTER Adapter) { - PCHAR pBuff = OsalMemAlloc(BUFFER_4K,"3MVN"); + PCHAR pBuff = kmalloc(BUFFER_4K, GFP_KERNEL); UINT uiEepromSize = 0; UINT uiIndex = 0; UINT uiBytesToCopy = 0; @@ -1787,14 +1776,14 @@ INT PropagateCalParamsFromEEPROMToMemory(PMINI_ADAPTER Adapter) if(0 != BeceemEEPROMBulkRead(Adapter,&uiEepromSize,EEPROM_SIZE_OFFSET,4)) { - OsalMemFree(pBuff,BUFFER_4K); + kfree(pBuff); return -1; } uiEepromSize >>= 16; if(uiEepromSize > 1024*1024) { - OsalMemFree(pBuff,BUFFER_4K); + kfree(pBuff); return -1; } @@ -1820,7 +1809,7 @@ INT PropagateCalParamsFromEEPROMToMemory(PMINI_ADAPTER Adapter) wrmalt(Adapter, EEPROM_CAL_DATA_INTERNAL_LOC-4,&value, sizeof(value)); value = 0xbeadbead; wrmalt(Adapter, EEPROM_CAL_DATA_INTERNAL_LOC-8,&value, sizeof(value)); - OsalMemFree(pBuff,MAX_RW_SIZE); + kfree(pBuff); return Status; @@ -1873,7 +1862,7 @@ INT PropagateCalParamsFromFlashToMemory(PMINI_ADAPTER Adapter) return -1; } - pBuff = OsalMemAlloc(uiEepromSize, 0); + pBuff = kmalloc(uiEepromSize, GFP_KERNEL); if ( pBuff == NULL ) { @@ -1882,7 +1871,7 @@ INT PropagateCalParamsFromFlashToMemory(PMINI_ADAPTER Adapter) if(0 != BeceemNVMRead(Adapter,(PUINT)pBuff,uiCalStartAddr, uiEepromSize)) { - OsalMemFree(pBuff, 0); + kfree(pBuff); return -1; } @@ -1905,7 +1894,7 @@ INT PropagateCalParamsFromFlashToMemory(PMINI_ADAPTER Adapter) uiBytesToCopy = MIN(BUFFER_4K,uiEepromSize); } - OsalMemFree(pBuff, 0); + kfree(pBuff); return Status; } @@ -1947,14 +1936,14 @@ static INT BeceemEEPROMReadBackandVerify( {// for the requests more than or equal to MAX_RW_SIZE bytes, use bulk read function to make the access faster. BeceemEEPROMBulkRead(Adapter,&auiData[0],uiOffset,MAX_RW_SIZE); - if(OsalMemCompare(&pBuffer[uiIndex],&auiData[0],MAX_RW_SIZE)) + if(memcmp(&pBuffer[uiIndex],&auiData[0],MAX_RW_SIZE)) { // re-write BeceemEEPROMBulkWrite(Adapter,(PUCHAR)(pBuffer+uiIndex),uiOffset,MAX_RW_SIZE,FALSE); mdelay(3); BeceemEEPROMBulkRead(Adapter,&auiData[0],uiOffset,MAX_RW_SIZE); - if(OsalMemCompare(&pBuffer[uiIndex],&auiData[0],MAX_RW_SIZE)) + if(memcmp(&pBuffer[uiIndex],&auiData[0],MAX_RW_SIZE)) { return -1; } @@ -1986,7 +1975,7 @@ static INT BeceemEEPROMReadBackandVerify( else { // Handle the reads less than 4 bytes... uiData = 0; - OsalMemMove(&uiData,((PUCHAR)pBuffer)+(uiIndex*sizeof(UINT)),uiNumBytes); + memcpy(&uiData,((PUCHAR)pBuffer)+(uiIndex*sizeof(UINT)),uiNumBytes); BeceemEEPROMBulkRead(Adapter,&uiRdbk,uiOffset,4); if(memcmp(&uiData, &uiRdbk, uiNumBytes)) @@ -2186,7 +2175,7 @@ INT BeceemEEPROMBulkWrite( if(uiBytesToCopy >= (16 -uiExtraBytes)) { - OsalMemMove((((PUCHAR)&uiData[0])+uiExtraBytes),pBuffer,MAX_RW_SIZE- uiExtraBytes); + memcpy((((PUCHAR)&uiData[0])+uiExtraBytes),pBuffer,MAX_RW_SIZE- uiExtraBytes); if ( STATUS_FAILURE == BeceemEEPROMWritePage( Adapter, uiData, uiTempOffset ) ) return STATUS_FAILURE; @@ -2197,7 +2186,7 @@ INT BeceemEEPROMBulkWrite( } else { - OsalMemMove((((PUCHAR)&uiData[0])+uiExtraBytes),pBuffer,uiBytesToCopy); + memcpy((((PUCHAR)&uiData[0])+uiExtraBytes),pBuffer,uiBytesToCopy); if ( STATUS_FAILURE == BeceemEEPROMWritePage( Adapter, uiData, uiTempOffset ) ) return STATUS_FAILURE; @@ -2233,7 +2222,7 @@ INT BeceemEEPROMBulkWrite( // To program non 16byte aligned data, read 16byte and then update. // BeceemEEPROMBulkRead(Adapter,&uiData[0],uiOffset,16); - OsalMemMove(&uiData[0],pBuffer+uiIndex,uiBytesToCopy); + memcpy(&uiData[0],pBuffer+uiIndex,uiBytesToCopy); if ( STATUS_FAILURE == BeceemEEPROMWritePage( Adapter, uiData, uiOffset ) ) @@ -2763,7 +2752,7 @@ INT BcmAllocFlashCSStructure(PMINI_ADAPTER psAdapter) if(psAdapter->psFlash2xCSInfo == NULL) { BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_PRINTK, 0, 0,"Can't Allocate memory for Flash 2.x"); - bcm_kfree(psAdapter->psFlashCSInfo); + kfree(psAdapter->psFlashCSInfo); return -ENOMEM; } @@ -2771,8 +2760,8 @@ INT BcmAllocFlashCSStructure(PMINI_ADAPTER psAdapter) if(psAdapter->psFlash2xVendorInfo == NULL) { BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_PRINTK, 0, 0,"Can't Allocate Vendor Info Memory for Flash 2.x"); - bcm_kfree(psAdapter->psFlashCSInfo); - bcm_kfree(psAdapter->psFlash2xCSInfo); + kfree(psAdapter->psFlashCSInfo); + kfree(psAdapter->psFlash2xCSInfo); return -ENOMEM; } @@ -2786,9 +2775,9 @@ INT BcmDeAllocFlashCSStructure(PMINI_ADAPTER psAdapter) BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_PRINTK, 0, 0," Adapter structure point is NULL"); return -EINVAL; } - bcm_kfree(psAdapter->psFlashCSInfo); - bcm_kfree(psAdapter->psFlash2xCSInfo); - bcm_kfree(psAdapter->psFlash2xVendorInfo); + kfree(psAdapter->psFlashCSInfo); + kfree(psAdapter->psFlash2xCSInfo); + kfree(psAdapter->psFlash2xVendorInfo); return STATUS_SUCCESS ; } @@ -4570,7 +4559,7 @@ INT BcmCopyISO(PMINI_ADAPTER Adapter, FLASH2X_COPY_SECTION sCopySectStrut) } - bcm_kfree(Buff); + kfree(Buff); return Status; } @@ -4936,7 +4925,7 @@ INT BcmCopySection(PMINI_ADAPTER Adapter, BytesToBeCopied = numOfBytes; } }while(numOfBytes > 0) ; - bcm_kfree(pBuff); + kfree(pBuff); Adapter->bHeaderChangeAllowed = FALSE ; return Status; } @@ -5006,7 +4995,7 @@ INT SaveHeaderIfPresent(PMINI_ADAPTER Adapter, PUCHAR pBuff, UINT uiOffset) //Replace Buffer content with Header memcpy(pBuff +offsetToProtect,pTempBuff,HeaderSizeToProtect); - bcm_kfree(pTempBuff); + kfree(pTempBuff); } if(bHasHeader && Adapter->bSigCorrupted) { @@ -5525,11 +5514,11 @@ INT CorruptDSDSig(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal) else { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"BCM Signature is not present in header"); - bcm_kfree(pBuff); + kfree(pBuff); return STATUS_FAILURE; } - bcm_kfree(pBuff); + kfree(pBuff); BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Corrupted the signature"); return STATUS_SUCCESS ; } @@ -5575,14 +5564,14 @@ INT CorruptISOSig(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal) else { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"BCM Signature is not present in header"); - bcm_kfree(pBuff); + kfree(pBuff); return STATUS_FAILURE; } BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Corrupted the signature"); BCM_DEBUG_PRINT_BUFFER(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,pBuff,MAX_RW_SIZE); - bcm_kfree(pBuff); + kfree(pBuff); return STATUS_SUCCESS ; } diff --git a/drivers/staging/bcm/osal_misc.h b/drivers/staging/bcm/osal_misc.h deleted file mode 100644 index ff4adde17cd8..000000000000 --- a/drivers/staging/bcm/osal_misc.h +++ /dev/null @@ -1,49 +0,0 @@ - /*++ - - Copyright (c) Beceem Communications Inc. - - Module Name: - OSAL_Misc.h - - Abstract: - Provides the OS Abstracted macros to access: - Linked Lists - Dispatcher Objects(Events,Semaphores,Spin Locks and the like) - Files - - - Revision History: - Who When What - -------- -------- ---------------------------------------------- - Name Date Created/reviewed/modified - Rajeev 24/1/08 Created - Notes: - - --*/ -#ifndef _OSAL_MISC_H_ -#define _OSAL_MISC_H_ -//OSAL Macros -//OSAL Primitives -typedef PUCHAR POSAL_NW_PACKET ; //Nw packets - - -#define OsalMemAlloc(n,t) kmalloc(n,GFP_KERNEL) - -#define OsalMemFree(x,n) bcm_kfree(x) - -#define OsalMemMove(dest, src, len) \ -{ \ - memcpy(dest,src, len); \ -} - -#define OsalZeroMemory(pDest, Len) \ -{ \ - memset(pDest,0,Len); \ -} - -//#define OsalMemSet(pSrc,Char,Len) memset(pSrc,Char,Len) - -bool OsalMemCompare(void *dest, void *src, UINT len); - -#endif - -- cgit v1.2.3 From de85f9858969f50467bf39ee992ef871ae2492d3 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Fri, 29 Oct 2010 17:02:39 -0700 Subject: beceem: name threads with device name This is the convention used by Intel Wimax Signed-off-by: Stephen Hemminger --- drivers/staging/bcm/Misc.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/staging/bcm/Misc.c b/drivers/staging/bcm/Misc.c index a5ce9593dcff..eca75dbffe35 100644 --- a/drivers/staging/bcm/Misc.c +++ b/drivers/staging/bcm/Misc.c @@ -156,10 +156,12 @@ VOID AdapterFree(PMINI_ADAPTER Adapter) int create_worker_threads(PMINI_ADAPTER psAdapter) { + const char *name = psAdapter->dev->name; + BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Init Threads..."); // Rx Control Packets Processing psAdapter->control_packet_handler = kthread_run((int (*)(void *)) - control_packet_handler, psAdapter, "CtrlPktHdlr"); + control_packet_handler, psAdapter, "%s-rx", name); if(IS_ERR(psAdapter->control_packet_handler)) { BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "No Kernel Thread, but still returning success\n"); @@ -167,7 +169,7 @@ int create_worker_threads(PMINI_ADAPTER psAdapter) } // Tx Thread psAdapter->transmit_packet_thread = kthread_run((int (*)(void *)) - tx_pkt_handler, psAdapter, "TxPktThread"); + tx_pkt_handler, psAdapter, "%s-tx", name); if(IS_ERR (psAdapter->transmit_packet_thread)) { BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "No Kernel Thread, but still returning success"); -- cgit v1.2.3 From 71e253b1699fb777be68cb1028a90e21ea6ff8d8 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Mon, 1 Nov 2010 09:49:30 -0400 Subject: beceem: make transmit thread interruptible Kernel complains loudly if thread does long uninterruptible sleep. Also, dont wake up every 10ms even if no data present (wastes power). Signed-off-by: Stephen Hemminger --- drivers/staging/bcm/Transmit.c | 195 +++++++++++++---------------------------- 1 file changed, 61 insertions(+), 134 deletions(-) diff --git a/drivers/staging/bcm/Transmit.c b/drivers/staging/bcm/Transmit.c index 9932d71a6fe0..1f69625f241e 100644 --- a/drivers/staging/bcm/Transmit.c +++ b/drivers/staging/bcm/Transmit.c @@ -39,7 +39,7 @@ SendPacketFromQueue->SetupNextSend->bcm_cmd53 * Function - bcm_transmit() * * Description - This is the main transmit function for our virtual -* interface(veth0). It handles the ARP packets. It +* interface(eth0). It handles the ARP packets. It * clones this packet and then Queue it to a suitable * Queue. Then calls the transmit_packet(). * @@ -50,118 +50,59 @@ SendPacketFromQueue->SetupNextSend->bcm_cmd53 * *********************************************************************/ -INT bcm_transmit(struct sk_buff *skb, /**< skb */ - struct net_device *dev /**< net device pointer */ - ) +netdev_tx_t bcm_transmit(struct sk_buff *skb, struct net_device *dev) { - PMINI_ADAPTER Adapter = NULL; - USHORT qindex=0; - struct timeval tv; - UINT pkt_type = 0; - UINT calltransmit = 0; - - BCM_DEBUG_PRINT (Adapter, DBG_TYPE_TX, TX_OSAL_DBG, DBG_LVL_ALL, "\n%s====>\n",__FUNCTION__); + PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(dev); + SHORT qindex; - memset(&tv, 0, sizeof(tv)); - /* Check for valid parameters */ - if(skb == NULL || dev==NULL) - { - BCM_DEBUG_PRINT (Adapter, DBG_TYPE_TX,TX_OSAL_DBG, DBG_LVL_ALL, "Got NULL skb or dev\n"); - return -EINVAL; - } - - Adapter = GET_BCM_ADAPTER(dev); - if(!Adapter) - { - BCM_DEBUG_PRINT (Adapter, DBG_TYPE_TX, TX_OSAL_DBG, DBG_LVL_ALL, "Got Invalid Adapter\n"); - return -EINVAL; - } - if(Adapter->device_removed == TRUE || !Adapter->LinkUpStatus) - { - if(!netif_queue_stopped(dev)) { - netif_carrier_off(dev); - netif_stop_queue(dev); - } - return STATUS_FAILURE; - } - BCM_DEBUG_PRINT (Adapter, DBG_TYPE_TX, TX_OSAL_DBG, DBG_LVL_ALL, "Packet size : %d\n", skb->len); + if (Adapter->device_removed || !Adapter->LinkUpStatus) + goto drop; - /*Add Ethernet CS check here*/ - if(Adapter->TransferMode == IP_PACKET_ONLY_MODE ) - { - pkt_type = ntohs(*(PUSHORT)(skb->data + 12)); - /* Get the queue index where the packet is to be queued */ - BCM_DEBUG_PRINT (Adapter, DBG_TYPE_TX, TX_OSAL_DBG, DBG_LVL_ALL, "Getting the Queue Index....."); + if (Adapter->TransferMode != IP_PACKET_ONLY_MODE ) + goto drop; - qindex = GetPacketQueueIndex(Adapter,skb); + qindex = GetPacketQueueIndex(Adapter, skb); - if((SHORT)INVALID_QUEUE_INDEX==(SHORT)qindex) - { - if(pkt_type == ETH_ARP_FRAME) - { - /* - Reply directly to ARP request packet - ARP Spoofing only if NO ETH CS rule matches for it - */ - BCM_DEBUG_PRINT (Adapter,DBG_TYPE_TX, TX_OSAL_DBG, DBG_LVL_ALL,"ARP OPCODE = %02x", + if (INVALID_QUEUE_INDEX==qindex) { + if (ntohs(eth_hdr(skb)->h_proto) != ETH_ARP_FRAME) + goto drop; - (*(PUCHAR)(skb->data + 21))); + /* + Reply directly to ARP request packet + ARP Spoofing only if NO ETH CS rule matches for it + */ + reply_to_arp_request(skb); + return NETDEV_TX_OK; + } - reply_to_arp_request(skb); + if (Adapter->PackInfo[qindex].uiCurrentPacketsOnHost >= SF_MAX_ALLOWED_PACKETS_TO_BACKUP) + return NETDEV_TX_BUSY; - BCM_DEBUG_PRINT (Adapter, DBG_TYPE_TX,TX_OSAL_DBG, DBG_LVL_ALL,"After reply_to_arp_request \n"); + /* Now Enqueue the packet */ + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, + "bcm_transmit Enqueueing the Packet To Queue %d",qindex); + spin_lock(&Adapter->PackInfo[qindex].SFQueueLock); + Adapter->PackInfo[qindex].uiCurrentBytesOnHost += skb->len; + Adapter->PackInfo[qindex].uiCurrentPacketsOnHost++; - } - else - { - BCM_DEBUG_PRINT (Adapter, DBG_TYPE_TX, TX_OSAL_DBG, DBG_LVL_ALL, - "Invalid queue index, dropping pkt\n"); + *((B_UINT32 *)skb->cb + SKB_CB_LATENCY_OFFSET ) = jiffies; + ENQUEUEPACKET(Adapter->PackInfo[qindex].FirstTxQueue, + Adapter->PackInfo[qindex].LastTxQueue, skb); + atomic_inc(&Adapter->TotalPacketCount); + spin_unlock(&Adapter->PackInfo[qindex].SFQueueLock); - dev_kfree_skb(skb); - } - return STATUS_SUCCESS; - } + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_OSAL_DBG, DBG_LVL_ALL,"ENQ: \n"); - if(Adapter->PackInfo[qindex].uiCurrentPacketsOnHost >= SF_MAX_ALLOWED_PACKETS_TO_BACKUP) - { - atomic_inc(&Adapter->TxDroppedPacketCount); - dev_kfree_skb(skb); - return STATUS_SUCCESS; - } - - /* Now Enqueue the packet */ - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "bcm_transmit Enqueueing the Packet To Queue %d",qindex); - spin_lock(&Adapter->PackInfo[qindex].SFQueueLock); - Adapter->PackInfo[qindex].uiCurrentBytesOnHost += skb->len; - Adapter->PackInfo[qindex].uiCurrentPacketsOnHost++; - - *((B_UINT32 *)skb->cb + SKB_CB_LATENCY_OFFSET ) = jiffies; - ENQUEUEPACKET(Adapter->PackInfo[qindex].FirstTxQueue, - Adapter->PackInfo[qindex].LastTxQueue, skb); - atomic_inc(&Adapter->TotalPacketCount); - spin_unlock(&Adapter->PackInfo[qindex].SFQueueLock); - do_gettimeofday(&tv); - - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_OSAL_DBG, DBG_LVL_ALL,"ENQ: \n"); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_OSAL_DBG, DBG_LVL_ALL, "Pkt Len = %d, sec: %ld, usec: %ld\n", - (skb->len-ETH_HLEN), tv.tv_sec, tv.tv_usec); - - if(calltransmit == 1) - transmit_packets(Adapter); - else - { - if(!atomic_read(&Adapter->TxPktAvail)) - { - atomic_set(&Adapter->TxPktAvail, 1); - wake_up(&Adapter->tx_packet_wait_queue); - } - } - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_OSAL_DBG, DBG_LVL_ALL, "<===="); + /* FIXME - this is racy and incorrect, replace with work queue */ + if (!atomic_read(&Adapter->TxPktAvail)) { + atomic_set(&Adapter->TxPktAvail, 1); + wake_up(&Adapter->tx_packet_wait_queue); } - else - dev_kfree_skb(skb); + return NETDEV_TX_OK; - return STATUS_SUCCESS; + drop: + dev_kfree_skb(skb); + return NETDEV_TX_OK; } @@ -337,6 +278,13 @@ errExit: return status; } +static int tx_pending(PMINI_ADAPTER Adapter) +{ + return (atomic_read(&Adapter->TxPktAvail) + && MINIMUM_PENDING_DESCRIPTORS < atomic_read(&Adapter->CurrNumFreeTxDesc)) + || Adapter->device_removed || (1 == Adapter->downloadDDR); +} + /** @ingroup tx_functions Transmit thread @@ -346,40 +294,17 @@ int tx_pkt_handler(PMINI_ADAPTER Adapter /**< pointer to adapter object*/ { int status = 0; - UINT calltransmit = 1; - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Entring to wait for signal from the interrupt service thread!Adapter = %p",Adapter); - - - while(1) - { - if(Adapter->LinkUpStatus){ + while(! kthread_should_stop()) { + /* FIXME - the timeout looks like workaround for racey usage of TxPktAvail */ + if(Adapter->LinkUpStatus) wait_event_timeout(Adapter->tx_packet_wait_queue, - ((atomic_read(&Adapter->TxPktAvail) && - (MINIMUM_PENDING_DESCRIPTORS < - atomic_read(&Adapter->CurrNumFreeTxDesc)) && - (Adapter->device_removed == FALSE))) || - (1 == Adapter->downloadDDR) || kthread_should_stop() - || (TRUE == Adapter->bEndPointHalted) - , msecs_to_jiffies(10)); - } - else{ - wait_event(Adapter->tx_packet_wait_queue, - ((atomic_read(&Adapter->TxPktAvail) && - (MINIMUM_PENDING_DESCRIPTORS < - atomic_read(&Adapter->CurrNumFreeTxDesc)) && - (Adapter->device_removed == FALSE))) || - (1 == Adapter->downloadDDR) || kthread_should_stop() - || (TRUE == Adapter->bEndPointHalted) - ); - } - - if(kthread_should_stop() || Adapter->device_removed) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Exiting the tx thread..\n"); - Adapter->transmit_packet_thread = NULL; - return 0; - } + tx_pending(Adapter), msecs_to_jiffies(10)); + else + wait_event_interruptible(Adapter->tx_packet_wait_queue, + tx_pending(Adapter)); + if (Adapter->device_removed) + break; if(Adapter->downloadDDR == 1) { @@ -424,11 +349,13 @@ int tx_pkt_handler(PMINI_ADAPTER Adapter /**< pointer to adapter object*/ } - if(calltransmit) - transmit_packets(Adapter); + transmit_packets(Adapter); atomic_set(&Adapter->TxPktAvail, 0); } + + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Exiting the tx thread..\n"); + Adapter->transmit_packet_thread = NULL; return 0; } -- cgit v1.2.3 From d21d6dde0280f0897ce6de1948bfaa5633867b28 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Fri, 29 Oct 2010 17:12:37 -0700 Subject: beceem: add ethtool support This adds basic ethtool support to get driver info and settings Signed-off-by: Stephen Hemminger --- drivers/staging/bcm/Bcmnet.c | 47 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) diff --git a/drivers/staging/bcm/Bcmnet.c b/drivers/staging/bcm/Bcmnet.c index b4e729b57e67..f0549912c9ec 100644 --- a/drivers/staging/bcm/Bcmnet.c +++ b/drivers/staging/bcm/Bcmnet.c @@ -1,7 +1,8 @@ #include "headers.h" -#define DRV_DESCRIPTION "Beceem Communications Inc. WiMAX driver" +#define DRV_NAME "beceem" #define DRV_VERSION "5.2.7.3P1" +#define DRV_DESCRIPTION "Beceem Communications Inc. WiMAX driver" #define DRV_COPYRIGHT "Copyright 2010. Beceem Communications Inc" @@ -79,6 +80,49 @@ static struct device_type wimax_type = { .name = "wimax", }; +static int bcm_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) +{ + cmd->supported = 0; + cmd->advertising = 0; + cmd->speed = SPEED_10000; + cmd->duplex = DUPLEX_FULL; + cmd->port = PORT_TP; + cmd->phy_address = 0; + cmd->transceiver = XCVR_INTERNAL; + cmd->autoneg = AUTONEG_DISABLE; + cmd->maxtxpkt = 0; + cmd->maxrxpkt = 0; + return 0; +} + +static void bcm_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) +{ + PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(dev); + PS_INTERFACE_ADAPTER psIntfAdapter = Adapter->pvInterfaceAdapter; + struct usb_device *udev = interface_to_usbdev(psIntfAdapter->interface); + + strcpy(info->driver, DRV_NAME); + strcpy(info->version, DRV_VERSION); + snprintf(info->fw_version, sizeof(info->fw_version), "%u.%u", + Adapter->uiFlashLayoutMajorVersion, + Adapter->uiFlashLayoutMinorVersion); + + usb_make_path(udev, info->bus_info, sizeof(info->bus_info)); +} + +static u32 bcm_get_link(struct net_device *dev) +{ + PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(dev); + + return Adapter->LinkUpStatus; +} + +static const struct ethtool_ops bcm_ethtool_ops = { + .get_settings = bcm_get_settings, + .get_drvinfo = bcm_get_drvinfo, + .get_link = bcm_get_link, +}; + int register_networkdev(PMINI_ADAPTER Adapter) { struct net_device *net; @@ -98,6 +142,7 @@ int register_networkdev(PMINI_ADAPTER Adapter) *temp = Adapter; net->netdev_ops = &bcmNetDevOps; + net->ethtool_ops = &bcm_ethtool_ops; net->mtu = MTU_SIZE; /* 1400 Bytes */ SET_NETDEV_DEV(net, &uintf->dev); -- cgit v1.2.3 From 9c6e9aa830071a442fb72ab05c15e2b2609636e3 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Fri, 29 Oct 2010 17:13:52 -0700 Subject: beceem: remove dead code Signed-off-by: Stephen Hemminger --- drivers/staging/bcm/InterfaceTx.c | 44 --------------------------------------- drivers/staging/bcm/InterfaceTx.h | 6 ------ 2 files changed, 50 deletions(-) diff --git a/drivers/staging/bcm/InterfaceTx.c b/drivers/staging/bcm/InterfaceTx.c index 826ed93c9b56..e51db83d629e 100644 --- a/drivers/staging/bcm/InterfaceTx.c +++ b/drivers/staging/bcm/InterfaceTx.c @@ -1,49 +1,5 @@ #include "headers.h" - -/* -Function: InterfaceTxDataPacket - -Description: This is the hardware specific Function for Transmitting - data packet to the device. - -Input parameters: IN PMINI_ADAPTER Adapter - Miniport Adapter Context - PVOID Packet - Packet Containing the data to be transmitted - USHORT usVcid - VCID on which data packet is to be sent - - -Return: BCM_STATUS_SUCCESS - If Tx was successful. - Other - If an error occured. -*/ - -ULONG InterfaceTxDataPacket(PMINI_ADAPTER Adapter,PVOID Packet,USHORT usVcid) -{ - ULONG Status = 0; - return Status; -} - -/* -Function: InterfaceTxControlPacket - -Description: This is the hardware specific Function for Transmitting - control packet to the device. - -Input parameters: IN PMINI_ADAPTER Adapter - Miniport Adapter Context - PVOID pvBuffer - Buffer containg control packet - UINT uiBufferLength - Buffer Length - -Return: BCM_STATUS_SUCCESS - If control packet transmit was successful. - Other - If an error occured. -*/ - -ULONG InterfaceTxControlPacket(PMINI_ADAPTER Adapter,PVOID pvBuffer,UINT uiBufferLength) -{ - ULONG Status = 0; - - - - return Status; -} /*this is transmit call-back(BULK OUT)*/ static void write_bulk_callback(struct urb *urb/*, struct pt_regs *regs*/) { diff --git a/drivers/staging/bcm/InterfaceTx.h b/drivers/staging/bcm/InterfaceTx.h index 053f631e2042..273147577c17 100644 --- a/drivers/staging/bcm/InterfaceTx.h +++ b/drivers/staging/bcm/InterfaceTx.h @@ -3,11 +3,5 @@ INT InterfaceTransmitPacket(PVOID arg, PVOID data, UINT len); - -ULONG InterfaceTxDataPacket(PMINI_ADAPTER Adapter,PVOID Packet,USHORT usVcid); - -ULONG InterfaceTxControlPacket(PMINI_ADAPTER Adapter,PVOID pvBuffer,UINT uiBufferLength); - - #endif -- cgit v1.2.3 From d7affd0f58c9f68441b4ce631d07fad2e6a448db Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Fri, 29 Oct 2010 17:15:06 -0700 Subject: beceem: reduce transmit queue len Reduce transmit queue length to avoid excess buffering Signed-off-by: Stephen Hemminger --- drivers/staging/bcm/Bcmnet.c | 3 ++- drivers/staging/bcm/Macros.h | 3 +-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/bcm/Bcmnet.c b/drivers/staging/bcm/Bcmnet.c index f0549912c9ec..c77c1d1e6157 100644 --- a/drivers/staging/bcm/Bcmnet.c +++ b/drivers/staging/bcm/Bcmnet.c @@ -143,7 +143,8 @@ int register_networkdev(PMINI_ADAPTER Adapter) net->netdev_ops = &bcmNetDevOps; net->ethtool_ops = &bcm_ethtool_ops; - net->mtu = MTU_SIZE; /* 1400 Bytes */ + net->mtu = MTU_SIZE; /* 1400 Bytes */ + net->tx_queue_len = TX_QLEN; SET_NETDEV_DEV(net, &uintf->dev); SET_NETDEV_DEVTYPE(net, &wimax_type); diff --git a/drivers/staging/bcm/Macros.h b/drivers/staging/bcm/Macros.h index 3868e5b94443..338b61d5c133 100644 --- a/drivers/staging/bcm/Macros.h +++ b/drivers/staging/bcm/Macros.h @@ -13,10 +13,9 @@ #define MAX_DATA_PKTS 200 #define MAX_ETH_SIZE 1536 #define MAX_CNTL_PKT_SIZE 2048 -/* TIMER RELATED */ -#define JIFFIES_2_QUADPART() (ULONG)(jiffies * 10000) // jiffies(1msec) to Quadpart(100nsec) #define MTU_SIZE 1400 +#define TX_QLEN 5 #define MAC_ADDR_REGISTER 0xbf60d000 -- cgit v1.2.3 From 2515ab628f227b0711393993fe3228e167cc988f Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Fri, 29 Oct 2010 21:39:54 -0700 Subject: beceem: Add proper carrier and link management Start with carrier off. Don't track up/down status in driver private flag. Signed-off-by: Stephen Hemminger --- drivers/staging/bcm/Adapter.h | 1 - drivers/staging/bcm/Bcmnet.c | 3 +-- drivers/staging/bcm/InterfaceRx.c | 2 +- 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/staging/bcm/Adapter.h b/drivers/staging/bcm/Adapter.h index 9c9dff3e0daa..c679b71848ac 100644 --- a/drivers/staging/bcm/Adapter.h +++ b/drivers/staging/bcm/Adapter.h @@ -498,7 +498,6 @@ struct _MINI_ADAPTER int irq; unsigned long chip_id; unsigned int bFlashBoot; - unsigned int if_up; // spinlock_t sleeper_lock; atomic_t rdm_wrm_access; atomic_t tx_rx_access; diff --git a/drivers/staging/bcm/Bcmnet.c b/drivers/staging/bcm/Bcmnet.c index c77c1d1e6157..9518e388b054 100644 --- a/drivers/staging/bcm/Bcmnet.c +++ b/drivers/staging/bcm/Bcmnet.c @@ -17,7 +17,6 @@ static INT bcm_open(struct net_device *dev) BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "======>"); if(Adapter->fw_download_done==FALSE) return -EINVAL; - Adapter->if_up=1; if(Adapter->LinkUpStatus == 1){ if(netif_queue_stopped(Adapter->dev)){ netif_carrier_on(Adapter->dev); @@ -34,7 +33,6 @@ static INT bcm_close(struct net_device *dev) PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(dev); BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "=====>"); - Adapter->if_up=0; if(!netif_queue_stopped(dev)) { netif_carrier_off(dev); netif_stop_queue(dev); @@ -145,6 +143,7 @@ int register_networkdev(PMINI_ADAPTER Adapter) net->ethtool_ops = &bcm_ethtool_ops; net->mtu = MTU_SIZE; /* 1400 Bytes */ net->tx_queue_len = TX_QLEN; + netif_carrier_off(net); SET_NETDEV_DEV(net, &uintf->dev); SET_NETDEV_DEVTYPE(net, &wimax_type); diff --git a/drivers/staging/bcm/InterfaceRx.c b/drivers/staging/bcm/InterfaceRx.c index 128aa91f7434..ab33895bfe56 100644 --- a/drivers/staging/bcm/InterfaceRx.c +++ b/drivers/staging/bcm/InterfaceRx.c @@ -148,7 +148,7 @@ static void read_bulk_callback(struct urb *urb) atomic_add(pLeader->PLength, &Adapter->GoodRxByteCount); BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_RX, RX_DATA, DBG_LVL_ALL, "Recived Data pkt of len :0x%X", pLeader->PLength); - if(Adapter->if_up) + if(netif_running(Adapter->dev)) { /* Moving ahead by ETH_HLEN to the data ptr as received from FW */ skb_pull(skb, ETH_HLEN); -- cgit v1.2.3 From e614e28eac1afcdc3d1275f3e1478aa3e5acc500 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Mon, 1 Nov 2010 09:52:14 -0400 Subject: beceem: remove indirection to Adapter structure Allocate Adapter structure as part of network device. Signed-off-by: Stephen Hemminber --- drivers/staging/bcm/Adapter.h | 1 + drivers/staging/bcm/Bcmnet.c | 22 +------------------ drivers/staging/bcm/InterfaceInit.c | 43 ++++++++++++++++--------------------- drivers/staging/bcm/InterfaceMisc.c | 11 ---------- drivers/staging/bcm/InterfaceMisc.h | 3 --- drivers/staging/bcm/Macros.h | 1 - drivers/staging/bcm/Misc.c | 33 ++++++++++++++-------------- drivers/staging/bcm/headers.h | 6 ++++++ 8 files changed, 43 insertions(+), 77 deletions(-) diff --git a/drivers/staging/bcm/Adapter.h b/drivers/staging/bcm/Adapter.h index c679b71848ac..a411c03f5c71 100644 --- a/drivers/staging/bcm/Adapter.h +++ b/drivers/staging/bcm/Adapter.h @@ -623,6 +623,7 @@ struct _MINI_ADAPTER }; typedef struct _MINI_ADAPTER MINI_ADAPTER, *PMINI_ADAPTER; +#define GET_BCM_ADAPTER(net_dev) netdev_priv(net_dev) typedef struct _DEVICE_EXTENSION { diff --git a/drivers/staging/bcm/Bcmnet.c b/drivers/staging/bcm/Bcmnet.c index 9518e388b054..1f35cd3c2872 100644 --- a/drivers/staging/bcm/Bcmnet.c +++ b/drivers/staging/bcm/Bcmnet.c @@ -1,11 +1,5 @@ #include "headers.h" -#define DRV_NAME "beceem" -#define DRV_VERSION "5.2.7.3P1" -#define DRV_DESCRIPTION "Beceem Communications Inc. WiMAX driver" -#define DRV_COPYRIGHT "Copyright 2010. Beceem Communications Inc" - - struct net_device *gblpnetdev; /***************************************************************************************/ /* proto-type of lower function */ @@ -123,29 +117,15 @@ static const struct ethtool_ops bcm_ethtool_ops = { int register_networkdev(PMINI_ADAPTER Adapter) { - struct net_device *net; - PMINI_ADAPTER *temp; - PS_INTERFACE_ADAPTER psIntfAdapter = Adapter->pvInterfaceAdapter; - struct usb_interface *uintf = psIntfAdapter->interface; + struct net_device *net = Adapter->dev; int result; - net = alloc_etherdev(sizeof(PMINI_ADAPTER)); - if(!net) { - pr_notice("bcmnet: no memory for device\n"); - return -ENOMEM; - } - - Adapter->dev = net; /* FIXME - only allows one adapter! */ - temp = netdev_priv(net); - *temp = Adapter; - net->netdev_ops = &bcmNetDevOps; net->ethtool_ops = &bcm_ethtool_ops; net->mtu = MTU_SIZE; /* 1400 Bytes */ net->tx_queue_len = TX_QLEN; netif_carrier_off(net); - SET_NETDEV_DEV(net, &uintf->dev); SET_NETDEV_DEVTYPE(net, &wimax_type); /* Read the MAC Address from EEPROM */ diff --git a/drivers/staging/bcm/InterfaceInit.c b/drivers/staging/bcm/InterfaceInit.c index 014b06bfbc9f..e700fc768aed 100644 --- a/drivers/staging/bcm/InterfaceInit.c +++ b/drivers/staging/bcm/InterfaceInit.c @@ -182,30 +182,27 @@ static struct usb_class_driver usbbcm_class = { static int usbbcm_device_probe(struct usb_interface *intf, const struct usb_device_id *id) { - int retval =0 ; - PMINI_ADAPTER psAdapter = NULL; - PS_INTERFACE_ADAPTER psIntfAdapter = NULL; - struct usb_device *udev = NULL; - -// BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Usbbcm probe!!"); - if((intf == NULL) || (id == NULL)) - { - // BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "intf or id is NULL"); - return -EINVAL; - } - - /* Allocate Adapter structure */ - if((psAdapter = kzalloc(sizeof(MINI_ADAPTER), GFP_KERNEL)) == NULL) - { - BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_PRINTK, 0, 0, "Out of memory"); + struct usb_device *udev = interface_to_usbdev (intf); + int retval; + PMINI_ADAPTER psAdapter; + PS_INTERFACE_ADAPTER psIntfAdapter; + struct net_device *ndev; + + ndev = alloc_etherdev(sizeof(MINI_ADAPTER)); + if(ndev == NULL) { + dev_err(&udev->dev, DRV_NAME ": no memory for device\n"); return -ENOMEM; } + SET_NETDEV_DEV(ndev, &intf->dev); + + psAdapter = netdev_priv(ndev); + psAdapter->dev = ndev; + /* Init default driver debug state */ psAdapter->stDebugState.debug_level = debug_level; psAdapter->stDebugState.type = DBG_TYPE_INITEXIT; - memset (psAdapter->stDebugState.subtype, 0, sizeof (psAdapter->stDebugState.subtype)); /* Technically, one can start using BCM_DEBUG_PRINT after this point. * However, realize that by default the Type/Subtype bitmaps are all zero now; @@ -224,22 +221,21 @@ usbbcm_device_probe(struct usb_interface *intf, const struct usb_device_id *id) retval = InitAdapter(psAdapter); if(retval) { - BCM_DEBUG_PRINT (psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "InitAdapter Failed\n"); + dev_err(&udev->dev, DRV_NAME ": InitAdapter Failed\n"); AdapterFree(psAdapter); return retval; } /* Allocate interface adapter structure */ - if((psAdapter->pvInterfaceAdapter = - kmalloc(sizeof(S_INTERFACE_ADAPTER), GFP_KERNEL)) == NULL) + psIntfAdapter = kzalloc(sizeof(S_INTERFACE_ADAPTER), GFP_KERNEL); + if (psIntfAdapter == NULL) { - BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_PRINTK, 0, 0, "Out of memory"); + dev_err(&udev->dev, DRV_NAME ": no memory for Interface adapter\n"); AdapterFree (psAdapter); return -ENOMEM; } - memset(psAdapter->pvInterfaceAdapter, 0, sizeof(S_INTERFACE_ADAPTER)); - psIntfAdapter = InterfaceAdapterGet(psAdapter); + psAdapter->pvInterfaceAdapter = psIntfAdapter; psIntfAdapter->psAdapter = psAdapter; /* Store usb interface in Interface Adapter */ @@ -276,7 +272,6 @@ usbbcm_device_probe(struct usb_interface *intf, const struct usb_device_id *id) } } - udev = interface_to_usbdev (intf); /* Check whether the USB-Device Supports remote Wake-Up */ if(USB_CONFIG_ATT_WAKEUP & udev->actconfig->desc.bmAttributes) { diff --git a/drivers/staging/bcm/InterfaceMisc.c b/drivers/staging/bcm/InterfaceMisc.c index 2d98b7e846c2..6ee5dbb6154a 100644 --- a/drivers/staging/bcm/InterfaceMisc.c +++ b/drivers/staging/bcm/InterfaceMisc.c @@ -1,16 +1,5 @@ #include "headers.h" - -PS_INTERFACE_ADAPTER -InterfaceAdapterGet(PMINI_ADAPTER psAdapter) -{ - if(psAdapter == NULL) - { - return NULL; - } - return (PS_INTERFACE_ADAPTER)(psAdapter->pvInterfaceAdapter); -} - INT InterfaceRDM(PS_INTERFACE_ADAPTER psIntfAdapter, UINT addr, diff --git a/drivers/staging/bcm/InterfaceMisc.h b/drivers/staging/bcm/InterfaceMisc.h index 74c81d45cff4..6c9e39bf9889 100644 --- a/drivers/staging/bcm/InterfaceMisc.h +++ b/drivers/staging/bcm/InterfaceMisc.h @@ -1,9 +1,6 @@ #ifndef __INTERFACE_MISC_H #define __INTERFACE_MISC_H -PS_INTERFACE_ADAPTER -InterfaceAdapterGet(PMINI_ADAPTER psAdapter); - INT InterfaceRDM(PS_INTERFACE_ADAPTER psIntfAdapter, UINT addr, diff --git a/drivers/staging/bcm/Macros.h b/drivers/staging/bcm/Macros.h index 338b61d5c133..14df2f86b14e 100644 --- a/drivers/staging/bcm/Macros.h +++ b/drivers/staging/bcm/Macros.h @@ -354,7 +354,6 @@ enum eAbortPattern { ABORT_IDLE_SYNCDOWN = 3 }; -#define GET_BCM_ADAPTER(net_dev) (net_dev ? netdev_priv(net_dev) : NULL) /* Offsets used by driver in skb cb variable */ #define SKB_CB_CLASSIFICATION_OFFSET 0 diff --git a/drivers/staging/bcm/Misc.c b/drivers/staging/bcm/Misc.c index eca75dbffe35..ae9e88cf51fd 100644 --- a/drivers/staging/bcm/Misc.c +++ b/drivers/staging/bcm/Misc.c @@ -108,7 +108,7 @@ InitAdapter(PMINI_ADAPTER psAdapter) VOID AdapterFree(PMINI_ADAPTER Adapter) { - INT count = 0; + int count; beceem_protocol_reset(Adapter); @@ -116,41 +116,40 @@ VOID AdapterFree(PMINI_ADAPTER Adapter) if(Adapter->control_packet_handler && !IS_ERR(Adapter->control_packet_handler)) kthread_stop (Adapter->control_packet_handler); + if(Adapter->transmit_packet_thread && !IS_ERR(Adapter->transmit_packet_thread)) - kthread_stop (Adapter->transmit_packet_thread); - wake_up(&Adapter->process_read_wait_queue); + kthread_stop (Adapter->transmit_packet_thread); + + wake_up(&Adapter->process_read_wait_queue); + if(Adapter->LEDInfo.led_thread_running & (BCM_LED_THREAD_RUNNING_ACTIVELY | BCM_LED_THREAD_RUNNING_INACTIVELY)) kthread_stop (Adapter->LEDInfo.led_cntrl_threadid); + bcm_unregister_networkdev(Adapter); + + /* FIXME: use proper wait_event and refcounting */ while(atomic_read(&Adapter->ApplicationRunning)) { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Waiting for Application to close.. %d\n",atomic_read(&Adapter->ApplicationRunning)); msleep(100); } unregister_control_device_interface(Adapter); - if(Adapter->dev && !IS_ERR(Adapter->dev)) - free_netdev(Adapter->dev); - if(Adapter->pstargetparams != NULL) - { - kfree(Adapter->pstargetparams); - } + + kfree(Adapter->pstargetparams); + for (count =0;count < MAX_CNTRL_PKTS;count++) - { - if(Adapter->txctlpacket[count]) - kfree(Adapter->txctlpacket[count]); - } + kfree(Adapter->txctlpacket[count]); + FreeAdapterDsxBuffer(Adapter); - if(Adapter->pvInterfaceAdapter) - kfree(Adapter->pvInterfaceAdapter); + kfree(Adapter->pvInterfaceAdapter); //Free the PHS Interface PhsCleanup(&Adapter->stBCMPhsContext); BcmDeAllocFlashCSStructure(Adapter); - kfree(Adapter); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "<========\n"); + free_netdev(Adapter->dev); } diff --git a/drivers/staging/bcm/headers.h b/drivers/staging/bcm/headers.h index d4a200329bab..0fdee9528617 100644 --- a/drivers/staging/bcm/headers.h +++ b/drivers/staging/bcm/headers.h @@ -74,5 +74,11 @@ #include "InterfaceIdleMode.h" #include "InterfaceInit.h" +#define DRV_NAME "beceem" +#define DEV_NAME "tarang" +#define DRV_DESCRIPTION "Beceem Communications Inc. WiMAX driver" +#define DRV_COPYRIGHT "Copyright 2010. Beceem Communications Inc" +#define DRV_VERSION VER_FILEVERSION_STR +#define PFX DRV_NAME " " #endif -- cgit v1.2.3 From 6ba8fe77ddd3a25daa8409333295b90c26a43bae Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Sun, 31 Oct 2010 23:43:55 -0400 Subject: beceem: print better message on bad ioctl Signed-off-by: Stephen Hemminger --- drivers/staging/bcm/Bcmchar.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/staging/bcm/Bcmchar.c b/drivers/staging/bcm/Bcmchar.c index f9979a87c42b..5dbd96aab54e 100644 --- a/drivers/staging/bcm/Bcmchar.c +++ b/drivers/staging/bcm/Bcmchar.c @@ -2355,10 +2355,8 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) break; default: - BCM_DEBUG_PRINT (Adapter, DBG_TYPE_PRINTK, 0, 0, "wrong input %x",cmd); - BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "In default ioctl %d\n", cmd); - Status = STATUS_FAILURE; - + pr_info(DRV_NAME ": unknown ioctl cmd=%#x\n", cmd); + Status = STATUS_FAILURE; break; } return Status; -- cgit v1.2.3 From 7441698fe9eb0eb473cf1699d9cd8dd06dfeaf77 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Mon, 1 Nov 2010 09:53:58 -0400 Subject: beceem: remove ARP spoofing Linux support NOARP flag, so the whole Arp spoofing routines are not needed. Signed-off-by: Stephen Hemminger --- drivers/staging/bcm/Arp.c | 94 ------------------------------------------ drivers/staging/bcm/Bcmnet.c | 3 ++ drivers/staging/bcm/Makefile | 2 +- drivers/staging/bcm/Transmit.c | 15 ++----- 4 files changed, 7 insertions(+), 107 deletions(-) delete mode 100644 drivers/staging/bcm/Arp.c diff --git a/drivers/staging/bcm/Arp.c b/drivers/staging/bcm/Arp.c deleted file mode 100644 index 7cb25b30b5c1..000000000000 --- a/drivers/staging/bcm/Arp.c +++ /dev/null @@ -1,94 +0,0 @@ - -/* - * File Name: Arp.c - * Abstract: This file contains the routines for handling ARP PACKETS - */ -#include "headers.h" -#define ARP_PKT_SIZE 60 - -/* ========================================================================= - * Function - reply_to_arp_request() - * - * Description - When this host tries to broadcast ARP request packet through - * the virtual interface (veth0), reply directly to upper layer. - * This function allocates a new skb for ARP reply packet, - * fills in the fields of the packet and then sends it to - * upper layer. - * - * Parameters - skb: Pointer to sk_buff structure of the ARP request pkt. - * - * Returns - None - * =========================================================================*/ - -VOID -reply_to_arp_request(struct sk_buff *skb) -{ - PMINI_ADAPTER Adapter; - struct ArpHeader *pArpHdr = NULL; - struct ethhdr *pethhdr = NULL; - UCHAR uiIPHdr[4]; - /* Check for valid skb */ - if(skb == NULL) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Invalid skb: Cannot reply to ARP request\n"); - return; - } - - - Adapter = GET_BCM_ADAPTER(skb->dev); - /* Print the ARP Request Packet */ - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, ARP_RESP, DBG_LVL_ALL, "ARP Packet Dump :"); - BCM_DEBUG_PRINT_BUFFER(Adapter,DBG_TYPE_TX, ARP_RESP, DBG_LVL_ALL, (PUCHAR)(skb->data), skb->len); - - /* - * Extract the Ethernet Header and Arp Payload including Header - */ - pethhdr = (struct ethhdr *)skb->data; - pArpHdr = (struct ArpHeader *)(skb->data+ETH_HLEN); - - if(Adapter->bETHCSEnabled) - { - if(memcmp(pethhdr->h_source, Adapter->dev->dev_addr, ETH_ALEN)) - { - dev_kfree_skb(skb); - return; - } - } - - // Set the Ethernet Header First. - memcpy(pethhdr->h_dest, pethhdr->h_source, ETH_ALEN); - if(!memcmp(pethhdr->h_source, Adapter->dev->dev_addr, ETH_ALEN)) - { - pethhdr->h_source[5]++; - } - - /* Set the reply to ARP Reply */ - pArpHdr->arp.ar_op = ntohs(ARPOP_REPLY); - - /* Set the HW Address properly */ - memcpy(pArpHdr->ar_sha, pethhdr->h_source, ETH_ALEN); - memcpy(pArpHdr->ar_tha, pethhdr->h_dest, ETH_ALEN); - - // Swapping the IP Adddress - memcpy(uiIPHdr,pArpHdr->ar_sip,4); - memcpy(pArpHdr->ar_sip,pArpHdr->ar_tip,4); - memcpy(pArpHdr->ar_tip,uiIPHdr,4); - - /* Print the ARP Reply Packet */ - - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, ARP_RESP, DBG_LVL_ALL, "ARP REPLY PACKET: "); - - /* Send the Packet to upper layer */ - BCM_DEBUG_PRINT_BUFFER(Adapter,DBG_TYPE_TX, ARP_RESP, DBG_LVL_ALL, (PUCHAR)(skb->data), skb->len); - - skb->protocol = eth_type_trans(skb,skb->dev); - skb->pkt_type = PACKET_HOST; - -// skb->mac.raw=skb->data+LEADER_SIZE; - skb_set_mac_header (skb, LEADER_SIZE); - netif_rx(skb); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, ARP_RESP, DBG_LVL_ALL, "<=============\n"); - return; -} - - diff --git a/drivers/staging/bcm/Bcmnet.c b/drivers/staging/bcm/Bcmnet.c index 1f35cd3c2872..908711d0447d 100644 --- a/drivers/staging/bcm/Bcmnet.c +++ b/drivers/staging/bcm/Bcmnet.c @@ -124,6 +124,9 @@ int register_networkdev(PMINI_ADAPTER Adapter) net->ethtool_ops = &bcm_ethtool_ops; net->mtu = MTU_SIZE; /* 1400 Bytes */ net->tx_queue_len = TX_QLEN; + net->flags |= IFF_NOARP; + net->flags &= ~(IFF_BROADCAST|IFF_MULTICAST); + netif_carrier_off(net); SET_NETDEV_DEVTYPE(net, &wimax_type); diff --git a/drivers/staging/bcm/Makefile b/drivers/staging/bcm/Makefile index 0050206b0fc1..652b7f87737c 100644 --- a/drivers/staging/bcm/Makefile +++ b/drivers/staging/bcm/Makefile @@ -6,7 +6,7 @@ obj-$(CONFIG_BCM_WIMAX) += bcm_wimax.o bcm_wimax-y := InterfaceDld.o InterfaceIdleMode.o InterfaceInit.o InterfaceRx.o \ InterfaceIsr.o InterfaceMisc.o InterfaceTx.o \ - Arp.o CmHost.o IPv6Protocol.o Qos.o Transmit.o\ + CmHost.o IPv6Protocol.o Qos.o Transmit.o\ Bcmnet.o DDRInit.o HandleControlPacket.o\ LeakyBucket.o Misc.o sort.o Bcmchar.o hostmibs.o PHSModule.o\ led_control.o nvm.o vendorspecificextn.o diff --git a/drivers/staging/bcm/Transmit.c b/drivers/staging/bcm/Transmit.c index 1f69625f241e..4b94d822578c 100644 --- a/drivers/staging/bcm/Transmit.c +++ b/drivers/staging/bcm/Transmit.c @@ -6,7 +6,7 @@ digraph transmit1 { node[shape=box] edge[weight=5;color=red] -bcm_transmit->reply_to_arp_request[label="ARP"] + bcm_transmit->GetPacketQueueIndex[label="IP Packet"] GetPacketQueueIndex->IpVersion4[label="IPV4"] GetPacketQueueIndex->IpVersion6[label="IPV6"] @@ -63,17 +63,8 @@ netdev_tx_t bcm_transmit(struct sk_buff *skb, struct net_device *dev) qindex = GetPacketQueueIndex(Adapter, skb); - if (INVALID_QUEUE_INDEX==qindex) { - if (ntohs(eth_hdr(skb)->h_proto) != ETH_ARP_FRAME) - goto drop; - - /* - Reply directly to ARP request packet - ARP Spoofing only if NO ETH CS rule matches for it - */ - reply_to_arp_request(skb); - return NETDEV_TX_OK; - } + if (INVALID_QUEUE_INDEX==qindex) + goto drop; if (Adapter->PackInfo[qindex].uiCurrentPacketsOnHost >= SF_MAX_ALLOWED_PACKETS_TO_BACKUP) return NETDEV_TX_BUSY; -- cgit v1.2.3 From 26a0e39ac8ed1f38b31baeb901bc76501466d34e Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Sun, 31 Oct 2010 23:47:35 -0400 Subject: beceem: fold unregister_netdevice into AdapterFree The function unregister_netdevice only called unregister_netdev. Signed-off-by: Stephen Hemminger --- drivers/staging/bcm/Bcmnet.c | 9 --------- drivers/staging/bcm/Misc.c | 2 +- drivers/staging/bcm/Prototypes.h | 2 -- 3 files changed, 1 insertion(+), 12 deletions(-) diff --git a/drivers/staging/bcm/Bcmnet.c b/drivers/staging/bcm/Bcmnet.c index 908711d0447d..e3575ad65e91 100644 --- a/drivers/staging/bcm/Bcmnet.c +++ b/drivers/staging/bcm/Bcmnet.c @@ -145,15 +145,6 @@ int register_networkdev(PMINI_ADAPTER Adapter) return result; } -void bcm_unregister_networkdev(PMINI_ADAPTER Adapter) -{ - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Unregistering the Net Dev...\n"); - if(Adapter->dev) { - unregister_netdev(Adapter->dev); - Adapter->dev = NULL; - } -} - static int bcm_init(void) { printk(KERN_INFO "%s, %s\n", DRV_DESCRIPTION, DRV_VERSION); diff --git a/drivers/staging/bcm/Misc.c b/drivers/staging/bcm/Misc.c index ae9e88cf51fd..b982c7a6e9f2 100644 --- a/drivers/staging/bcm/Misc.c +++ b/drivers/staging/bcm/Misc.c @@ -125,7 +125,7 @@ VOID AdapterFree(PMINI_ADAPTER Adapter) if(Adapter->LEDInfo.led_thread_running & (BCM_LED_THREAD_RUNNING_ACTIVELY | BCM_LED_THREAD_RUNNING_INACTIVELY)) kthread_stop (Adapter->LEDInfo.led_cntrl_threadid); - bcm_unregister_networkdev(Adapter); + unregister_netdev(Adapter->dev); /* FIXME: use proper wait_event and refcounting */ while(atomic_read(&Adapter->ApplicationRunning)) diff --git a/drivers/staging/bcm/Prototypes.h b/drivers/staging/bcm/Prototypes.h index 286ea46cd996..8ca6b9eb4e34 100644 --- a/drivers/staging/bcm/Prototypes.h +++ b/drivers/staging/bcm/Prototypes.h @@ -122,8 +122,6 @@ void doPowerAutoCorrection(PMINI_ADAPTER psAdapter); int bcm_ioctl_fw_download(PMINI_ADAPTER Adapter, FIRMWARE_INFO *psFwInfo); -void bcm_unregister_networkdev(PMINI_ADAPTER Adapter); - int SearchVcid(PMINI_ADAPTER Adapter,unsigned short usVcid); void CopyMIBSExtendedSFParameters(PMINI_ADAPTER Adapter, -- cgit v1.2.3 From 20f48653fcf51f6d1246b5f3f86b40ed779385b2 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Sun, 31 Oct 2010 23:52:36 -0400 Subject: beceem: get rid of unnecessary inline usage Many routines were tagged with inline_ but GCC does a better job of deciding this. Signed-off-by: Stephen Hemminger --- drivers/staging/bcm/CmHost.c | 16 +++++++++------- drivers/staging/bcm/InterfaceInit.c | 2 +- drivers/staging/bcm/InterfaceTx.c | 4 ++-- drivers/staging/bcm/LeakyBucket.c | 35 +++++------------------------------ drivers/staging/bcm/Misc.c | 7 +++---- 5 files changed, 20 insertions(+), 44 deletions(-) diff --git a/drivers/staging/bcm/CmHost.c b/drivers/staging/bcm/CmHost.c index dadfff00f837..1c3ca1e49fee 100644 --- a/drivers/staging/bcm/CmHost.c +++ b/drivers/staging/bcm/CmHost.c @@ -28,7 +28,7 @@ typedef enum _E_CLASSIFIER_ACTION * Returns - Queue index for this SFID(If matched) Else Invalid Queue Index(If Not matched) ************************************************************/ -__inline INT SearchSfid(PMINI_ADAPTER Adapter,UINT uiSfid) +INT SearchSfid(PMINI_ADAPTER Adapter,UINT uiSfid) { INT iIndex=0; for(iIndex=(NO_OF_QUEUES-1); iIndex>=0; iIndex--) @@ -47,18 +47,20 @@ __inline INT SearchSfid(PMINI_ADAPTER Adapter,UINT uiSfid) * Returns - Queue index for the free SFID * Else returns Invalid Index. ****************************************************************/ -__inline INT SearchFreeSfid(PMINI_ADAPTER Adapter) +static INT SearchFreeSfid(PMINI_ADAPTER Adapter) { UINT uiIndex=0; + for(uiIndex=0; uiIndex < (NO_OF_QUEUES-1); uiIndex++) if(Adapter->PackInfo[uiIndex].ulSFID==0) return uiIndex; return NO_OF_QUEUES+1; } -__inline int SearchVcid(PMINI_ADAPTER Adapter,unsigned short usVcid) +int SearchVcid(PMINI_ADAPTER Adapter,unsigned short usVcid) { - int iIndex=0; + int iIndex=0; + for(iIndex=(NO_OF_QUEUES-1);iIndex>=0;iIndex--) if(Adapter->PackInfo[iIndex].usVCID_Value == usVcid) return iIndex; @@ -76,7 +78,7 @@ Input parameters: PMINI_ADAPTER Adapter - Adapter Context Return: int :Classifier table index of matching entry */ -__inline int SearchClsid(PMINI_ADAPTER Adapter,ULONG ulSFID,B_UINT16 uiClassifierID) +static int SearchClsid(PMINI_ADAPTER Adapter,ULONG ulSFID,B_UINT16 uiClassifierID) { unsigned int uiClassifierIndex = 0; for(uiClassifierIndex=0;uiClassifierIndexurb; diff --git a/drivers/staging/bcm/LeakyBucket.c b/drivers/staging/bcm/LeakyBucket.c index cae382313ce9..9c73862d5120 100644 --- a/drivers/staging/bcm/LeakyBucket.c +++ b/drivers/staging/bcm/LeakyBucket.c @@ -75,7 +75,7 @@ static VOID UpdateTokenCount(register PMINI_ADAPTER Adapter) * Returns - The number of bytes allowed for transmission. * ***********************************************************************/ -static __inline ULONG GetSFTokenCount(PMINI_ADAPTER Adapter, PacketInfo *psSF) +static ULONG GetSFTokenCount(PMINI_ADAPTER Adapter, PacketInfo *psSF) { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL, "IsPacketAllowedForFlow ===>"); /* Validate the parameters */ @@ -107,38 +107,14 @@ static __inline ULONG GetSFTokenCount(PMINI_ADAPTER Adapter, PacketInfo *psSF) return 0; } -static __inline void RemovePacketFromQueue(PacketInfo *pPackInfo , struct sk_buff *Packet) -{ - struct sk_buff *psQueueCurrent=NULL, *psLastQueueNode=NULL; - psQueueCurrent = pPackInfo->FirstTxQueue; - while(psQueueCurrent) - { - if(Packet == psQueueCurrent) - { - if(psQueueCurrent == pPackInfo->FirstTxQueue) - { - pPackInfo->FirstTxQueue=psQueueCurrent->next; - if(psQueueCurrent==pPackInfo->LastTxQueue) - pPackInfo->LastTxQueue=NULL; - } - else - { - psLastQueueNode->next=psQueueCurrent->next; - } - break; - } - psLastQueueNode = psQueueCurrent; - psQueueCurrent=psQueueCurrent->next; - } -} /** @ingroup tx_functions This function despatches packet from the specified queue. @return Zero(success) or Negative value(failure) */ -static __inline INT SendPacketFromQueue(PMINI_ADAPTER Adapter,/**"); @@ -943,8 +943,7 @@ VOID DumpPackInfo(PMINI_ADAPTER Adapter) } - -__inline int reset_card_proc(PMINI_ADAPTER ps_adapter) +int reset_card_proc(PMINI_ADAPTER ps_adapter) { int retval = STATUS_SUCCESS; @@ -1074,7 +1073,7 @@ err_exit : return retval; } -__inline int run_card_proc(PMINI_ADAPTER ps_adapter ) +int run_card_proc(PMINI_ADAPTER ps_adapter ) { unsigned int value=0; { -- cgit v1.2.3 From 937110581650eaa517f045fb7b86b9828ba693ad Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Sun, 31 Oct 2010 23:55:21 -0400 Subject: beceem: support multiple queues Current kernels have multi-queue support which can be used by this device. This has the advantage that a single type of traffic will not block other types. Signed-off-by: Stephen Hemminger --- drivers/staging/bcm/Bcmnet.c | 66 +++++++++++++++++++++++++++++++++++++ drivers/staging/bcm/InterfaceInit.c | 2 +- drivers/staging/bcm/Prototypes.h | 14 +++----- drivers/staging/bcm/Qos.c | 30 ----------------- drivers/staging/bcm/Transmit.c | 61 ---------------------------------- 5 files changed, 72 insertions(+), 101 deletions(-) diff --git a/drivers/staging/bcm/Bcmnet.c b/drivers/staging/bcm/Bcmnet.c index e3575ad65e91..5b466174a580 100644 --- a/drivers/staging/bcm/Bcmnet.c +++ b/drivers/staging/bcm/Bcmnet.c @@ -54,6 +54,71 @@ static struct net_device_stats *bcm_get_stats(struct net_device *dev) return netstats; } +static u16 bcm_select_queue(struct net_device *dev, struct sk_buff *skb) +{ + return ClassifyPacket(netdev_priv(dev), skb); +} + + +/******************************************************************* +* Function - bcm_transmit() +* +* Description - This is the main transmit function for our virtual +* interface(eth0). It handles the ARP packets. It +* clones this packet and then Queue it to a suitable +* Queue. Then calls the transmit_packet(). +* +* Parameter - skb - Pointer to the socket buffer structure +* dev - Pointer to the virtual net device structure +* +*********************************************************************/ + +static netdev_tx_t bcm_transmit(struct sk_buff *skb, struct net_device *dev) +{ + PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(dev); + u16 qindex = skb_get_queue_mapping(skb); + + if (Adapter->device_removed || !Adapter->LinkUpStatus) + goto drop; + + if (Adapter->TransferMode != IP_PACKET_ONLY_MODE ) + goto drop; + + if (INVALID_QUEUE_INDEX==qindex) + goto drop; + + if (Adapter->PackInfo[qindex].uiCurrentPacketsOnHost >= SF_MAX_ALLOWED_PACKETS_TO_BACKUP) + return NETDEV_TX_BUSY; + + /* Now Enqueue the packet */ + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, + "bcm_transmit Enqueueing the Packet To Queue %d",qindex); + spin_lock(&Adapter->PackInfo[qindex].SFQueueLock); + Adapter->PackInfo[qindex].uiCurrentBytesOnHost += skb->len; + Adapter->PackInfo[qindex].uiCurrentPacketsOnHost++; + + *((B_UINT32 *)skb->cb + SKB_CB_LATENCY_OFFSET ) = jiffies; + ENQUEUEPACKET(Adapter->PackInfo[qindex].FirstTxQueue, + Adapter->PackInfo[qindex].LastTxQueue, skb); + atomic_inc(&Adapter->TotalPacketCount); + spin_unlock(&Adapter->PackInfo[qindex].SFQueueLock); + + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_OSAL_DBG, DBG_LVL_ALL,"ENQ: \n"); + + /* FIXME - this is racy and incorrect, replace with work queue */ + if (!atomic_read(&Adapter->TxPktAvail)) { + atomic_set(&Adapter->TxPktAvail, 1); + wake_up(&Adapter->tx_packet_wait_queue); + } + return NETDEV_TX_OK; + + drop: + dev_kfree_skb(skb); + return NETDEV_TX_OK; +} + + + /** @ingroup init_functions Register other driver entry points with the kernel @@ -66,6 +131,7 @@ static const struct net_device_ops bcmNetDevOps = { .ndo_change_mtu = eth_change_mtu, .ndo_set_mac_address = eth_mac_addr, .ndo_validate_addr = eth_validate_addr, + .ndo_select_queue = bcm_select_queue, }; static struct device_type wimax_type = { diff --git a/drivers/staging/bcm/InterfaceInit.c b/drivers/staging/bcm/InterfaceInit.c index 14866e9c8cd2..845ced1670ee 100644 --- a/drivers/staging/bcm/InterfaceInit.c +++ b/drivers/staging/bcm/InterfaceInit.c @@ -188,7 +188,7 @@ usbbcm_device_probe(struct usb_interface *intf, const struct usb_device_id *id) PS_INTERFACE_ADAPTER psIntfAdapter; struct net_device *ndev; - ndev = alloc_etherdev(sizeof(MINI_ADAPTER)); + ndev = alloc_etherdev_mq(sizeof(MINI_ADAPTER), NO_OF_QUEUES); if(ndev == NULL) { dev_err(&udev->dev, DRV_NAME ": no memory for device\n"); return -ENOMEM; diff --git a/drivers/staging/bcm/Prototypes.h b/drivers/staging/bcm/Prototypes.h index 8ca6b9eb4e34..a4b57bb07fa1 100644 --- a/drivers/staging/bcm/Prototypes.h +++ b/drivers/staging/bcm/Prototypes.h @@ -46,13 +46,12 @@ VOID PruneQueueAllSF(PMINI_ADAPTER Adapter); INT SearchSfid(PMINI_ADAPTER Adapter,UINT uiSfid); -USHORT GetPacketQueueIndex(PMINI_ADAPTER Adapter, /**"); - - if(NULL==Adapter || NULL==Packet) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, QUEUE_INDEX, DBG_LVL_ALL, "Got NULL Values<======"); - return -1; - } - - usIndex = ClassifyPacket(Adapter,Packet); - - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, QUEUE_INDEX, DBG_LVL_ALL, "Got Queue Index %x",usIndex); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, QUEUE_INDEX, DBG_LVL_ALL, "GetPacketQueueIndex <=============="); - return usIndex; -} VOID PruneQueueAllSF(PMINI_ADAPTER Adapter) { diff --git a/drivers/staging/bcm/Transmit.c b/drivers/staging/bcm/Transmit.c index 4b94d822578c..734bbbd14e22 100644 --- a/drivers/staging/bcm/Transmit.c +++ b/drivers/staging/bcm/Transmit.c @@ -35,67 +35,6 @@ SendPacketFromQueue->SetupNextSend->bcm_cmd53 #include "headers.h" -/******************************************************************* -* Function - bcm_transmit() -* -* Description - This is the main transmit function for our virtual -* interface(eth0). It handles the ARP packets. It -* clones this packet and then Queue it to a suitable -* Queue. Then calls the transmit_packet(). -* -* Parameter - skb - Pointer to the socket buffer structure -* dev - Pointer to the virtual net device structure -* -* Returns - zero (success) or -ve value (failure) -* -*********************************************************************/ - -netdev_tx_t bcm_transmit(struct sk_buff *skb, struct net_device *dev) -{ - PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(dev); - SHORT qindex; - - if (Adapter->device_removed || !Adapter->LinkUpStatus) - goto drop; - - if (Adapter->TransferMode != IP_PACKET_ONLY_MODE ) - goto drop; - - qindex = GetPacketQueueIndex(Adapter, skb); - - if (INVALID_QUEUE_INDEX==qindex) - goto drop; - - if (Adapter->PackInfo[qindex].uiCurrentPacketsOnHost >= SF_MAX_ALLOWED_PACKETS_TO_BACKUP) - return NETDEV_TX_BUSY; - - /* Now Enqueue the packet */ - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, - "bcm_transmit Enqueueing the Packet To Queue %d",qindex); - spin_lock(&Adapter->PackInfo[qindex].SFQueueLock); - Adapter->PackInfo[qindex].uiCurrentBytesOnHost += skb->len; - Adapter->PackInfo[qindex].uiCurrentPacketsOnHost++; - - *((B_UINT32 *)skb->cb + SKB_CB_LATENCY_OFFSET ) = jiffies; - ENQUEUEPACKET(Adapter->PackInfo[qindex].FirstTxQueue, - Adapter->PackInfo[qindex].LastTxQueue, skb); - atomic_inc(&Adapter->TotalPacketCount); - spin_unlock(&Adapter->PackInfo[qindex].SFQueueLock); - - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_OSAL_DBG, DBG_LVL_ALL,"ENQ: \n"); - - /* FIXME - this is racy and incorrect, replace with work queue */ - if (!atomic_read(&Adapter->TxPktAvail)) { - atomic_set(&Adapter->TxPktAvail, 1); - wake_up(&Adapter->tx_packet_wait_queue); - } - return NETDEV_TX_OK; - - drop: - dev_kfree_skb(skb); - return NETDEV_TX_OK; -} - /** @ingroup ctrl_pkt_functions -- cgit v1.2.3 From 3644c1a2f12b15e1c8bfb9ebfaacbd177011a72d Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Mon, 1 Nov 2010 00:03:03 -0400 Subject: beceem: remove dead code Remove commented out with '#if 0' Signed-off-by: Stephen Hemminger --- drivers/staging/bcm/Adapter.h | 44 +---- drivers/staging/bcm/Bcmchar.c | 35 ---- drivers/staging/bcm/CmHost.c | 60 ------ drivers/staging/bcm/DDRInit.c | 11 -- drivers/staging/bcm/HandleControlPacket.c | 23 --- drivers/staging/bcm/InterfaceDld.c | 104 ---------- drivers/staging/bcm/InterfaceIdleMode.c | 8 - drivers/staging/bcm/InterfaceInit.c | 26 --- drivers/staging/bcm/InterfaceRx.c | 6 - drivers/staging/bcm/InterfaceTx.c | 9 - drivers/staging/bcm/LeakyBucket.c | 3 - drivers/staging/bcm/Misc.c | 60 ------ drivers/staging/bcm/Qos.c | 9 - drivers/staging/bcm/led_control.c | 111 ----------- drivers/staging/bcm/nvm.c | 314 ------------------------------ 15 files changed, 1 insertion(+), 822 deletions(-) diff --git a/drivers/staging/bcm/Adapter.h b/drivers/staging/bcm/Adapter.h index a411c03f5c71..9f8954bfd5bd 100644 --- a/drivers/staging/bcm/Adapter.h +++ b/drivers/staging/bcm/Adapter.h @@ -7,42 +7,6 @@ #define MAX_FRAGMENTEDIP_CLASSIFICATION_ENTRIES 256 #include "Debug.h" -typedef struct _LIST_ENTRY{ - struct _LIST_ENTRY *next; - struct _LIST_ENTRY *prev; -} LIST_ENTRY, *PLIST_ENTRY; - -typedef struct _BCM_LIST_ENTRY { - - LIST_ENTRY Link; - -} BCM_LIST_ENTRY, *PBCM_LIST_ENTRY; - -typedef enum _RCB_STATUS -{ - DRIVER_PROCESSED=1, - APPLICATION_PROCESSED -} RCB_STATUS, *PRCB_STATUS; - -#define fFILLED 1 -#define fEMPTY 0 - -struct _BCM_CB -{ - // The network packet that this RCB is receiving - PVOID pv_packet; - // Describes the length of the packet . - UINT ui_packet_length; - // Pointer to the first buffer in the packet (only one buffer for Rx) - PUCHAR buffer; - atomic_t status; - UINT filled; -} __attribute__((packed)); -typedef struct _BCM_CB BCM_CB,*PBCM_CB; - -typedef BCM_CB BCM_RCB, *PBCM_RCB; -typedef BCM_CB BCM_TCB, *PBCM_TCB; - struct _LEADER { USHORT Vcid; @@ -555,7 +519,7 @@ struct _MINI_ADAPTER unsigned int usIdleModePattern; //BOOLEAN bTriedToWakeUpFromShutdown; BOOLEAN bLinkDownRequested; - unsigned int check_for_hang; + int downloadDDR; PHS_DEVICE_EXTENSION stBCMPhsContext; S_HDR_SUPRESSION_CONTEXTINFO stPhsTxContextInfo; @@ -625,12 +589,6 @@ typedef struct _MINI_ADAPTER MINI_ADAPTER, *PMINI_ADAPTER; #define GET_BCM_ADAPTER(net_dev) netdev_priv(net_dev) -typedef struct _DEVICE_EXTENSION -{ - PMINI_ADAPTER pAdapt; -}DEVICE_EXTENSION,*PDEVICE_EXTENSION; - - struct _ETH_HEADER_STRUC { UCHAR au8DestinationAddress[6]; UCHAR au8SourceAddress[6]; diff --git a/drivers/staging/bcm/Bcmchar.c b/drivers/staging/bcm/Bcmchar.c index 5dbd96aab54e..6c9db7227ca2 100644 --- a/drivers/staging/bcm/Bcmchar.c +++ b/drivers/staging/bcm/Bcmchar.c @@ -1207,10 +1207,6 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) Adapter->usIdleModePattern = ABORT_IDLE_MODE; Adapter->bWakeUpDevice = TRUE; wake_up(&Adapter->process_rx_cntrlpkt); - #if 0 - Adapter->bTriedToWakeUpFromlowPowerMode = TRUE; - InterfaceAbortIdlemode (Adapter, Adapter->usIdleModePattern); - #endif } Status = STATUS_SUCCESS; break; @@ -1750,14 +1746,6 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"\nsFlash2xRead.offset :%d" ,sFlash2xWrite.offset); BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"\nsFlash2xRead.numOfBytes :%x" ,sFlash2xWrite.numOfBytes); BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"\nsFlash2xRead.bVerify :%x\n" ,sFlash2xWrite.bVerify); - #if 0 - if((sFlash2xWrite.Section == ISO_IMAGE1) ||(sFlash2xWrite.Section == ISO_IMAGE2) || - (sFlash2xWrite.Section == DSD0) || (sFlash2xWrite.Section == DSD1) || (sFlash2xWrite.Section == DSD2)) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"ISO/DSD Image write is not allowed.... "); - return STATUS_FAILURE ; - } - #endif if((sFlash2xWrite.Section != VSA0) && (sFlash2xWrite.Section != VSA1) && (sFlash2xWrite.Section != VSA2) ) { @@ -1940,29 +1928,6 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) Adapter->bAllDSDWriteAllow = FALSE ; BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"IOCTL_BCM_IDENTIFY_ACTIVE_SECTION called"); - #if 0 - SECTION_TYPE section = 0 ; - - - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "IOCTL_BCM_IDENTIFY_ACTIVE_SECTION Called"); - Status = copy_from_user((PCHAR)&IoBuffer, (PCHAR)arg, sizeof(IOCTL_BUFFER)); - if(Status) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Copy of IOCTL BUFFER failed"); - return -EFAULT; - } - Status = copy_from_user((PCHAR)section,(PCHAR)&IoBuffer, sizeof(INT)); - if(Status) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Copy of section type failed failed"); - return -EFAULT; - } - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Read Section :%d", section); - if(section == DSD) - Adapter->ulFlashCalStart = Adapter->uiActiveDSDOffsetAtFwDld ; - else - Status = STATUS_FAILURE ; - #endif Status = STATUS_SUCCESS ; } break ; diff --git a/drivers/staging/bcm/CmHost.c b/drivers/staging/bcm/CmHost.c index 1c3ca1e49fee..d0bfdbbeee3f 100644 --- a/drivers/staging/bcm/CmHost.c +++ b/drivers/staging/bcm/CmHost.c @@ -1063,12 +1063,6 @@ static VOID DumpCmControlPacket(PVOID pvBuffer) pstAddIndication->sfAuthorizedSet.u32MaxTrafficBurst); BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32MinReservedTrafficRate : 0x%X", pstAddIndication->sfAuthorizedSet.u32MinReservedTrafficRate); -#if 0 - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32MinimumTolerableTrafficRate : 0x%X", - pstAddIndication->sfAuthorizedSet.u32MinimumTolerableTrafficRate); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32RequesttransmissionPolicy : 0x%X", - pstAddIndication->sfAuthorizedSet.u32RequesttransmissionPolicy); -#endif BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8VendorSpecificQoSParamLength : 0x%X", pstAddIndication->sfAuthorizedSet.u8VendorSpecificQoSParamLength); BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8VendorSpecificQoSParam : 0x%X", @@ -1116,13 +1110,6 @@ static VOID DumpCmControlPacket(PVOID pvBuffer) pstAddIndication->sfAuthorizedSet.u8PagingPreference); BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u16UnsolicitedPollingInterval : 0x%X", pstAddIndication->sfAuthorizedSet.u16UnsolicitedPollingInterval); -#if 0 - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "MBSZoneIdentifierassignmentLength : 0x%X", - pstAddIndication->sfAuthorizedSet.MBSZoneIdentifierassignmentLength); - for(uiLoopIndex=0; uiLoopIndex < MAX_STRING_LEN; uiLoopIndex++) - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "MBSZoneIdentifierassignment : 0x%X", - pstAddIndication->sfAuthorizedSet.MBSZoneIdentifierassignment[uiLoopIndex]); -#endif BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "sfAuthorizedSet.u8HARQChannelMapping %x %x %x ", *(unsigned int*)pstAddIndication->sfAuthorizedSet.u8HARQChannelMapping, @@ -1160,11 +1147,6 @@ static VOID DumpCmControlPacket(PVOID pvBuffer) psfCSType->cCPacketClassificationRule.u8IPTypeOfService[0], psfCSType->cCPacketClassificationRule.u8IPTypeOfService[1], psfCSType->cCPacketClassificationRule.u8IPTypeOfService[2]); -#if 0 - - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "u8ProtocolLength :0x%X ", - psfCSType->cCPacketClassificationRule.u8ProtocolLength); -#endif for(uiLoopIndex=0; uiLoopIndex < 1; uiLoopIndex++) BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8Protocol : 0x%02X ", @@ -1280,14 +1262,6 @@ static VOID DumpCmControlPacket(PVOID pvBuffer) pstAddIndication->sfAdmittedSet.u8QosParamSet); BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8TrafficPriority : 0x%02X", pstAddIndication->sfAdmittedSet.u8TrafficPriority); -#if 0 - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "u32MaxSustainedTrafficRate : 0x%02X", - ntohl(pstAddIndication->sfAdmittedSet.u32MaxSustainedTrafficRate)); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "u32MinimumTolerableTrafficRate : 0x%X", - pstAddIndication->sfAdmittedSet.u32MinimumTolerableTrafficRate); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "u32RequesttransmissionPolicy : 0x%X", - pstAddIndication->sfAdmittedSet.u32RequesttransmissionPolicy); -#endif BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32MaxTrafficBurst : 0x%X", pstAddIndication->sfAdmittedSet.u32MaxTrafficBurst); BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32MinReservedTrafficRate : 0x%X", @@ -1341,13 +1315,6 @@ static VOID DumpCmControlPacket(PVOID pvBuffer) pstAddIndication->sfAdmittedSet.u16TimeBase); BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8PagingPreference : 0x%X", pstAddIndication->sfAdmittedSet.u8PagingPreference); -#if 0 - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "MBSZoneIdentifierassignmentLength : 0x%X", - pstAddIndication->sfAdmittedSet.MBSZoneIdentifierassignmentLength); - for(uiLoopIndex=0; uiLoopIndex < MAX_STRING_LEN; uiLoopIndex++) - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "MBSZoneIdentifierassignment : 0x%X", - pstAddIndication->sfAdmittedSet.MBSZoneIdentifierassignment[uiLoopIndex]); -#endif BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8TrafficIndicationPreference : 0x%02X", @@ -1380,11 +1347,6 @@ static VOID DumpCmControlPacket(PVOID pvBuffer) psfCSType->cCPacketClassificationRule.u8IPTypeOfService[0], psfCSType->cCPacketClassificationRule.u8IPTypeOfService[1], psfCSType->cCPacketClassificationRule.u8IPTypeOfService[2]); -#if 0 - - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8ProtocolLength :0x%02X ", - psfCSType->cCPacketClassificationRule.u8ProtocolLength); -#endif for(uiLoopIndex=0; uiLoopIndex < 1; uiLoopIndex++) BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8Protocol: 0x%02X ", psfCSType->cCPacketClassificationRule.u8Protocol); @@ -1499,20 +1461,10 @@ static VOID DumpCmControlPacket(PVOID pvBuffer) pstAddIndication->sfActiveSet.u8QosParamSet); BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8TrafficPriority : 0x%02X", pstAddIndication->sfActiveSet.u8TrafficPriority); -#if 0 - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "u32MaxSustainedTrafficRate : 0x%02X", - ntohl(pstAddIndication->sfActiveSet.u32MaxSustainedTrafficRate)); -#endif BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32MaxTrafficBurst : 0x%X", pstAddIndication->sfActiveSet.u32MaxTrafficBurst); BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u32MinReservedTrafficRate : 0x%X", pstAddIndication->sfActiveSet.u32MinReservedTrafficRate); -#if 0 - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "u32MinimumTolerableTrafficRate : 0x%X", - pstAddIndication->sfActiveSet.u32MinimumTolerableTrafficRate); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "u32RequesttransmissionPolicy : 0x%X", - pstAddIndication->sfActiveSet.u32RequesttransmissionPolicy); -#endif BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8VendorSpecificQoSParamLength : 0x%02X", pstAddIndication->sfActiveSet.u8VendorSpecificQoSParamLength); BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, "u8VendorSpecificQoSParam : 0x%02X", @@ -1560,13 +1512,6 @@ static VOID DumpCmControlPacket(PVOID pvBuffer) pstAddIndication->sfActiveSet.u16TimeBase); BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8PagingPreference : 0x%X", pstAddIndication->sfActiveSet.u8PagingPreference); -#if 0 - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " MBSZoneIdentifierassignmentLength : 0x%X", - pstAddIndication->sfActiveSet.MBSZoneIdentifierassignmentLength); - for(uiLoopIndex=0; uiLoopIndex < MAX_STRING_LEN; uiLoopIndex++) - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " MBSZoneIdentifierassignment : 0x%X", - pstAddIndication->sfActiveSet.MBSZoneIdentifierassignment[uiLoopIndex]); -#endif BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8TrafficIndicationPreference : 0x%X", @@ -1599,11 +1544,6 @@ static VOID DumpCmControlPacket(PVOID pvBuffer) psfCSType->cCPacketClassificationRule.u8IPTypeOfService[0], psfCSType->cCPacketClassificationRule.u8IPTypeOfService[1], psfCSType->cCPacketClassificationRule.u8IPTypeOfService[2]); -#if 0 - - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, " u8ProtocolLength :0x%X ", - psfCSType->cCPacketClassificationRule.u8ProtocolLength); -#endif for(uiLoopIndex=0; uiLoopIndex < 1; uiLoopIndex++) BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, DUMP_CONTROL, DBG_LVL_ALL, " u8Protocol : 0x%X ", psfCSType->cCPacketClassificationRule.u8Protocol); diff --git a/drivers/staging/bcm/DDRInit.c b/drivers/staging/bcm/DDRInit.c index 454eb8d8992b..411f02a6b6ea 100644 --- a/drivers/staging/bcm/DDRInit.c +++ b/drivers/staging/bcm/DDRInit.c @@ -187,17 +187,6 @@ static DDR_SET_NODE asDPLL_266MHZ[] = { {0x0f000840,0x0FFF1B00}, {0x0f000870,0x00000002} }; -#if 0 -static DDR_SET_NODE asDPLL_800MHZ[] = { - {0x0f000810,0x00000F95}, - {0x0f000810,0x00000F95}, - {0x0f000810,0x00000F95}, - {0x0f000820,0x03F1365B}, - {0x0f000840,0x0FFF0000}, - {0x0f000880,0x000003DD}, - {0x0f000860,0x00000000} - }; -#endif #define T3B_SKIP_CLOCK_PROGRAM_DUMP_133MHZ 11 //index for 0x0F007000 static DDR_SET_NODE asT3B_DDRSetting133MHz[] = {// # DPLL Clock Setting diff --git a/drivers/staging/bcm/HandleControlPacket.c b/drivers/staging/bcm/HandleControlPacket.c index 8cfccaa3803a..2d4dbcc215e3 100644 --- a/drivers/staging/bcm/HandleControlPacket.c +++ b/drivers/staging/bcm/HandleControlPacket.c @@ -186,29 +186,6 @@ int control_packet_handler (PMINI_ADAPTER Adapter /**< pointer to adapter obje DEQUEUEPACKET(Adapter->RxControlHead,Adapter->RxControlTail); // Adapter->RxControlHead=ctrl_packet->next; } - #if 0 //Idle mode debug profiling... - if(*(PUSHORT)ctrl_packet->data == IDLE_MODE_STATUS) - { - puiBuffer = (PUINT)(ctrl_packet->data +sizeof(USHORT)); - if((ntohl(*puiBuffer) == GO_TO_IDLE_MODE_PAYLOAD)) - { - memset(&tv, 0, sizeof(tv)); - do_gettimeofday(&tv); - if((ntohl(*(puiBuffer+1)) == 0)) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, CP_CTRL_PKT, DBG_LVL_ALL, "IdleMode Wake-up Msg from f/w at time :%ld ms", tv.tv_sec *1000 + tv.tv_usec /1000); - } - else - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, CP_CTRL_PKT, DBG_LVL_ALL, "IdleMode req Msg from f/w at time :%ld ms", tv.tv_sec *1000 + tv.tv_usec /1000); - } - } - else if((ntohl(*puiBuffer) == IDLE_MODE_SF_UPDATE_MSG)) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, CP_CTRL_PKT, DBG_LVL_ALL, "GOT IDLE_MODE_SF_UPDATE MSG at time :%ld ms", tv.tv_sec *1000 + tv.tv_usec /1000); - } - } - #endif spin_unlock_irqrestore (&Adapter->control_queue_lock, flags); handle_rx_control_packet(Adapter, ctrl_packet); diff --git a/drivers/staging/bcm/InterfaceDld.c b/drivers/staging/bcm/InterfaceDld.c index e640b75e7dc4..1fc36a15f187 100644 --- a/drivers/staging/bcm/InterfaceDld.c +++ b/drivers/staging/bcm/InterfaceDld.c @@ -230,41 +230,6 @@ static int bcm_download_config_file(PMINI_ADAPTER Adapter, return retval; } -#if 0 -static int bcm_download_buffer(PMINI_ADAPTER Adapter, - unsigned char *mappedbuffer, unsigned int u32FirmwareLength, - unsigned long u32StartingAddress) -{ - char *buff=NULL; - unsigned int len = 0; - int retval = STATUS_SUCCESS; - buff = kzalloc(MAX_TRANSFER_CTRL_BYTE_USB, GFP_KERNEL); - - len = u32FirmwareLength; - - while(u32FirmwareLength) - { - len = MIN_VAL (u32FirmwareLength, MAX_TRANSFER_CTRL_BYTE_USB); - if(STATUS_SUCCESS != (retval = copy_from_user(buff, - (unsigned char *)mappedbuffer, len))) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "copy_from_user failed\n"); - break; - } - retval = wrm (Adapter, u32StartingAddress, buff, len); - if(retval) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "wrm failed\n"); - break; - } - u32StartingAddress += len; - u32FirmwareLength -= len; - mappedbuffer +=len; - } - kfree(buff); - return retval; -} -#endif static int bcm_compare_buff_contents(unsigned char *readbackbuff, unsigned char *buff,unsigned int len) { @@ -296,58 +261,6 @@ static int bcm_compare_buff_contents(unsigned char *readbackbuff, } return retval; } -#if 0 -static int bcm_buffer_readback(PMINI_ADAPTER Adapter, - unsigned char *mappedbuffer, unsigned int u32FirmwareLength, - unsigned long u32StartingAddress) -{ - unsigned char *buff = NULL; - unsigned char *readbackbuff = NULL; - unsigned int len = u32FirmwareLength; - int retval = STATUS_SUCCESS; - - buff=(unsigned char *)kzalloc(MAX_TRANSFER_CTRL_BYTE_USB, GFP_KERNEL); - if(NULL == buff) - return -ENOMEM; - readbackbuff = (unsigned char *)kzalloc(MAX_TRANSFER_CTRL_BYTE_USB, - GFP_KERNEL); - if(NULL == readbackbuff) - { - kfree(buff); - return -ENOMEM; - } - while (u32FirmwareLength && !retval) - { - len = MIN_VAL (u32FirmwareLength, MAX_TRANSFER_CTRL_BYTE_USB); - - /* read from the appl buff and then read from the target, compare */ - if(STATUS_SUCCESS != (retval = copy_from_user(buff, - (unsigned char *)mappedbuffer, len))) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "copy_from_user failed\n"); - break; - } - retval = rdm (Adapter, u32StartingAddress, readbackbuff, len); - if(retval) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "rdm failed\n"); - break; - } - - if (STATUS_SUCCESS != - (retval = bcm_compare_buff_contents (readbackbuff, buff, len))) - { - break; - } - u32StartingAddress += len; - u32FirmwareLength -= len; - mappedbuffer +=len; - }/* end of while (u32FirmwareLength && !retval) */ - kfree(buff); - kfree(readbackbuff); - return retval; -} -#endif int bcm_ioctl_fw_download(PMINI_ADAPTER Adapter, FIRMWARE_INFO *psFwInfo) { int retval = STATUS_SUCCESS; @@ -388,23 +301,6 @@ int bcm_ioctl_fw_download(PMINI_ADAPTER Adapter, FIRMWARE_INFO *psFwInfo) goto error ; } - #if 0 - retval = bcm_download_buffer(Adapter, - (unsigned char *)psFwInfo->pvMappedFirmwareAddress, - psFwInfo->u32FirmwareLength, psFwInfo->u32StartingAddress); - if(retval != STATUS_SUCCESS) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "User space buffer download fails...."); - } - retval = bcm_buffer_readback (Adapter, - (unsigned char *)psFwInfo->pvMappedFirmwareAddress, - psFwInfo->u32FirmwareLength, psFwInfo->u32StartingAddress); - - if(retval != STATUS_SUCCESS) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "read back verifier failed ...."); - } - #endif retval = buffDnldVerify(Adapter, buff, psFwInfo->u32FirmwareLength, diff --git a/drivers/staging/bcm/InterfaceIdleMode.c b/drivers/staging/bcm/InterfaceIdleMode.c index 0750382733ff..3a7780be7fe4 100644 --- a/drivers/staging/bcm/InterfaceIdleMode.c +++ b/drivers/staging/bcm/InterfaceIdleMode.c @@ -98,14 +98,6 @@ int InterfaceIdleModeRespond(PMINI_ADAPTER Adapter, unsigned int* puiBuffer) Adapter->bTriedToWakeUpFromlowPowerMode = FALSE; wake_up(&Adapter->lowpower_mode_wait_queue); - #if 0 - if(Adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, IDLE_MODE, DBG_LVL_ALL,"LED Thread is Running. Hence Setting the LED Event as IDLEMODE_EXIT"); - Adapter->DriverState = IDLEMODE_EXIT; - wake_up(&Adapter->LEDInfo.notify_led_event); - } - #endif } else diff --git a/drivers/staging/bcm/InterfaceInit.c b/drivers/staging/bcm/InterfaceInit.c index 845ced1670ee..dddf34bb7c8b 100644 --- a/drivers/staging/bcm/InterfaceInit.c +++ b/drivers/staging/bcm/InterfaceInit.c @@ -419,32 +419,6 @@ static int device_run(PS_INTERFACE_ADAPTER psIntfAdapter) return 0; } -#if 0 -static void print_usb_interface_desc(struct usb_interface_descriptor *usb_intf_desc) -{ - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "**************** INTERFACE DESCRIPTOR *********************"); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "bLength: %x", usb_intf_desc->bLength); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "bDescriptorType: %x", usb_intf_desc->bDescriptorType); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "bInterfaceNumber: %x", usb_intf_desc->bInterfaceNumber); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "bAlternateSetting: %x", usb_intf_desc->bAlternateSetting); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "bNumEndpoints: %x", usb_intf_desc->bNumEndpoints); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "bInterfaceClass: %x", usb_intf_desc->bInterfaceClass); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "bInterfaceSubClass: %x", usb_intf_desc->bInterfaceSubClass); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "bInterfaceProtocol: %x", usb_intf_desc->bInterfaceProtocol); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "iInterface :%x\n",usb_intf_desc->iInterface); -} -static void print_usb_endpoint_descriptor(struct usb_endpoint_descriptor *usb_ep_desc) -{ - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "**************** ENDPOINT DESCRIPTOR *********************"); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "bLength :%x ", usb_ep_desc->bLength); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "bDescriptorType :%x ", usb_ep_desc->bDescriptorType); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "bEndpointAddress :%x ", usb_ep_desc->bEndpointAddress); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "bmAttributes :%x ", usb_ep_desc->bmAttributes); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "wMaxPacketSize :%x ",usb_ep_desc->wMaxPacketSize); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "bInterval :%x ",usb_ep_desc->bInterval); -} - -#endif static inline int bcm_usb_endpoint_num(const struct usb_endpoint_descriptor *epd) { diff --git a/drivers/staging/bcm/InterfaceRx.c b/drivers/staging/bcm/InterfaceRx.c index ab33895bfe56..6f1ed78c975b 100644 --- a/drivers/staging/bcm/InterfaceRx.c +++ b/drivers/staging/bcm/InterfaceRx.c @@ -39,12 +39,6 @@ static void read_bulk_callback(struct urb *urb) PLEADER pLeader = urb->transfer_buffer; - #if 0 - int *puiBuffer = NULL; - struct timeval tv; - memset(&tv, 0, sizeof(tv)); - do_gettimeofday(&tv); - #endif if((Adapter->device_removed == TRUE) || (TRUE == Adapter->bEndPointHalted) || diff --git a/drivers/staging/bcm/InterfaceTx.c b/drivers/staging/bcm/InterfaceTx.c index b53848b6fc00..a3dadf19538b 100644 --- a/drivers/staging/bcm/InterfaceTx.c +++ b/drivers/staging/bcm/InterfaceTx.c @@ -9,10 +9,6 @@ static void write_bulk_callback(struct urb *urb/*, struct pt_regs *regs*/) PMINI_ADAPTER psAdapter = psIntfAdapter->psAdapter ; BOOLEAN bpowerDownMsg = FALSE ; PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); -#if 0 - struct timeval tv; - UINT time_ms = 0; -#endif if(urb->status != STATUS_SUCCESS) { if(urb->status == -EPIPE) @@ -33,11 +29,6 @@ static void write_bulk_callback(struct urb *urb/*, struct pt_regs *regs*/) if(TRUE == psAdapter->bPreparingForLowPowerMode) { - #if 0 - do_gettimeofday(&tv); - time_ms = tv.tv_sec *1000 + tv.tv_usec/1000; - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, " %s Idle Mode ACK_Sent got from device at time :0x%x", __FUNCTION__, time_ms); - #endif if(((pControlMsg->szData[0] == GO_TO_IDLE_MODE_PAYLOAD) && (pControlMsg->szData[1] == TARGET_CAN_GO_TO_IDLE_MODE))) diff --git a/drivers/staging/bcm/LeakyBucket.c b/drivers/staging/bcm/LeakyBucket.c index 9c73862d5120..f9e8f2bb06d3 100644 --- a/drivers/staging/bcm/LeakyBucket.c +++ b/drivers/staging/bcm/LeakyBucket.c @@ -183,9 +183,6 @@ static VOID CheckAndSendPacketFromIndex(PMINI_ADAPTER Adapter, PacketInfo *psSF) return ; } -#if 0 - PruneQueue(Adapter,(psSF-Adapter->PackInfo)); -#endif spin_lock_bh(&psSF->SFQueueLock); QueuePacket=psSF->FirstTxQueue; diff --git a/drivers/staging/bcm/Misc.c b/drivers/staging/bcm/Misc.c index dfc4f3fff2b2..0ada848fe1e1 100644 --- a/drivers/staging/bcm/Misc.c +++ b/drivers/staging/bcm/Misc.c @@ -365,13 +365,6 @@ INT CopyBufferToControlPacket(PMINI_ADAPTER Adapter,/**LEDInfo.bIdleMode_tx_from_host = TRUE; -#if 0 - if(STATUS_SUCCESS != InterfaceIdleModeWakeup(Adapter)) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Idle Mode Wake up Failed\n"); - return STATUS_FAILURE; - } -#endif Adapter->bWakeUpDevice = TRUE; wake_up(&Adapter->process_rx_cntrlpkt); @@ -1220,12 +1213,6 @@ int InitCardAndDownloadFirmware(PMINI_ADAPTER ps_adapter) goto OUT; } } -#if 0 - else if(psAdapter->eNVMType == NVM_EEPROM) - { - PropagateCalParamsFromEEPROMToMemory(); - } -#endif /* Download Firmare */ if ((status = BcmFileDownload( ps_adapter, BIN_FILE, FIRMWARE_BEGIN_ADDR))) @@ -1405,16 +1392,6 @@ VOID doPowerAutoCorrection(PMINI_ADAPTER psAdapter) if (psAdapter->bIsAutoCorrectEnabled && (psAdapter->chip_id >= T3LPB)) { //If reporting mode is enable, switch PMU to PMC - #if 0 - if(reporting_mode == FALSE) - { - psAdapter->ulPowerSaveMode = DEVICE_POWERSAVE_MODE_AS_PMU_SHUTDOWN; - psAdapter->bDoSuspend = TRUE; - BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL,"PMU selected ...."); - - } - else - #endif { psAdapter->ulPowerSaveMode = DEVICE_POWERSAVE_MODE_AS_PMU_CLOCK_GATING; psAdapter->bDoSuspend =FALSE; @@ -1481,43 +1458,6 @@ OUT: } #endif -#if 0 -INT ReadMacAddressFromEEPROM(PMINI_ADAPTER Adapter) -{ - unsigned char *puMacAddr = NULL; - int i =0; - - puMacAddr = ReadMacAddrEEPROM(Adapter,0x200); - if(!puMacAddr) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Couldn't retrieve the Mac Address\n"); - return STATUS_FAILURE; - } - else - { - if((puMacAddr[0] == 0x0 && puMacAddr[1] == 0x0 && - puMacAddr[2] == 0x0 && puMacAddr[3] == 0x0 && - puMacAddr[4] == 0x0 && puMacAddr[5] == 0x0) || - (puMacAddr[0] == 0xFF && puMacAddr[1] == 0xFF && - puMacAddr[2] == 0xFF && puMacAddr[3] == 0xFF && - puMacAddr[4] == 0xFF && puMacAddr[5] == 0xFF)) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Invalid Mac Address\n"); - kfree(puMacAddr); - return STATUS_FAILURE; - } - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "The Mac Address received is: \n"); - memcpy(Adapter->dev->dev_addr, puMacAddr, MAC_ADDRESS_SIZE); - for(i=0;idev->dev_addr[i]); - } - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"\n"); - kfree(puMacAddr); - } - return STATUS_SUCCESS; -} -#endif static void convertEndian(B_UINT8 rwFlag, PUINT puiBuffer, UINT uiByteCount) { diff --git a/drivers/staging/bcm/Qos.c b/drivers/staging/bcm/Qos.c index f85a5a85ad5c..7e8013c105a2 100644 --- a/drivers/staging/bcm/Qos.c +++ b/drivers/staging/bcm/Qos.c @@ -254,15 +254,6 @@ USHORT IpVersion4(PMINI_ADAPTER Adapter, /**< Pointer to the driver control stru //if protocol is not TCP or UDP then no need of comparing source port and destination port if(iphd->protocol!=TCP && iphd->protocol!=UDP) break; -#if 0 - //check if memory is available of src and Dest port - if(ETH_AND_IP_HEADER_LEN + L4_SRC_PORT_LEN + L4_DEST_PORT_LEN > Packet->len) - { - //This is not an erroneous condition and pkt will be checked for next classification. - bClassificationSucceed = FALSE; - break; - } -#endif //******************Checking Transport Layer Header field if present *****************// BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "Source Port %04x", (iphd->protocol==UDP)?xprt_hdr->uhdr.source:xprt_hdr->thdr.source); diff --git a/drivers/staging/bcm/led_control.c b/drivers/staging/bcm/led_control.c index 79c7bd74804d..a21d219f428c 100644 --- a/drivers/staging/bcm/led_control.c +++ b/drivers/staging/bcm/led_control.c @@ -116,44 +116,7 @@ static INT LED_Proportional_Blink(PMINI_ADAPTER Adapter, UCHAR GPIO_Num_tx, while((Adapter->device_removed == FALSE)) { - #if 0 - if(0 == num_of_time_tx && 0 == num_of_time_rx) - { - timeout = 1000; - Status = wait_event_interruptible_timeout(Adapter->LEDInfo.notify_led_event, - currdriverstate!= Adapter->DriverState || kthread_should_stop(), - msecs_to_jiffies (timeout)); - if(kthread_should_stop()) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL, "Led thread got signal to exit..hence exiting"); - Adapter->LEDInfo.led_thread_running= BCM_LED_THREAD_DISABLED; - return EVENT_SIGNALED; - } - if(Status) - return EVENT_SIGNALED; - - } - #endif - timeout = 50; - #if 0 - /*Turn on LED if Tx is high bandwidth*/ - if(num_of_time_tx > MAX_NUM_OF_BLINKS) - { - TURN_ON_LED(1< MAX_NUM_OF_BLINKS) - { - TURN_ON_LED(1<= NUM_OF_LEDS) *bEnableThread = FALSE; -#if 0 - for(uiIndex=0; uiIndexLEDInfo.LEDState[uiIndex].LED_Type); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"LEDState[%d].LED_On_State = %x\n", uiIndex, - Adapter->LEDInfo.LEDState[uiIndex].LED_On_State); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"LEDState[%d].LED_Blink_State = %x\n", uiIndex, - Adapter->LEDInfo.LEDState[uiIndex].LED_Blink_State); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"LEDState[%d].GPIO_Num = %x\n", uiIndex, - Adapter->LEDInfo.LEDState[uiIndex].GPIO_Num); - } - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"LED Thread: Polarity = %d\n", - Adapter->LEDInfo.BitPolarty); -#endif return Status; } //-------------------------------------------------------------------------- @@ -711,20 +659,6 @@ static VOID LEDControlThread(PMINI_ADAPTER Adapter) TURN_OFF_LED(1<device_removed) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"Device removed hence exiting from Led Thread.."); - return ; //-ENODEV; - } - #endif - #if 0 - if((GPIO_num != DISABLE_GPIO_NUM) && - ((currdriverstate != FW_DOWNLOAD) && - (currdriverstate != NORMAL_OPERATION) && - (currdriverstate != IDLEMODE_EXIT))) - TURN_OFF_LED(1<DriverState; - #if 0 - LedGpioInit(Adapter); - Adapter->LEDInfo.bLedInitDone = TRUE; - #endif BcmGetGPIOPinInfo(Adapter, &GPIO_num, &dummyGPIONum, &uiLedIndex, &dummyIndex, currdriverstate); if(GPIO_num != DISABLE_GPIO_NUM) @@ -758,13 +688,6 @@ static VOID LEDControlThread(PMINI_ADAPTER Adapter) { //BCM_DEBUG_PRINT (Adapter,DBG_TYPE_OTHERS, LED_DUMP_INFO, DBG_LVL_ALL,"LED Thread: FW_DN_DONE called\n"); currdriverstate = FW_DOWNLOAD; - #if 0 - if(Adapter->LEDInfo.bLedInitDone == FALSE) - { - LedGpioInit(Adapter); - Adapter->LEDInfo.bLedInitDone = TRUE; - } - #endif BcmGetGPIOPinInfo(Adapter, &GPIO_num, &dummyGPIONum, &uiLedIndex, &dummyIndex, currdriverstate); if(GPIO_num != DISABLE_GPIO_NUM) @@ -786,12 +709,6 @@ static VOID LEDControlThread(PMINI_ADAPTER Adapter) break; case SHUTDOWN_EXIT: - #if 0 - if(Adapter->ulPowerSaveMode == DEVICE_POWERSAVE_MODE_AS_PMU_SHUTDOWN) - { - LedGpioInit(Adapter); - } - #endif //no break, continue to NO_NETWORK_ENTRY state as well. case NO_NETWORK_ENTRY: @@ -865,34 +782,6 @@ static VOID LEDControlThread(PMINI_ADAPTER Adapter) break; case IDLEMODE_EXIT: { -#if 0 - UCHAR GPIO_num_tx = DISABLE_GPIO_NUM; - UCHAR GPIO_num_rx = DISABLE_GPIO_NUM; - UCHAR uiTxLedIndex = 0; - UCHAR uiRxLedIndex = 0; - - currdriverstate = IDLEMODE_EXIT; - if(DEVICE_POWERSAVE_MODE_AS_PMU_SHUTDOWN == Adapter->ulPowerSaveMode) - { - LedGpioInit(Adapter); - } - BcmGetGPIOPinInfo(Adapter, &GPIO_num_tx, &GPIO_num_rx, &uiTxLedIndex,&uiRxLedIndex,currdriverstate); - - Adapter->LEDInfo.bIdle_led_off = FALSE; - - if((GPIO_num_tx == DISABLE_GPIO_NUM) && (GPIO_num_rx == DISABLE_GPIO_NUM)) - { - GPIO_num = DISABLE_GPIO_NUM ; - } - else - { - timeout = 50; - if(Adapter->LEDInfo.bIdleMode_tx_from_host) - LED_Blink(Adapter, 1<> 14) & 1) == 1) - { - // EEPROM_SPI_Q_STATUS1_REG will be cleared only if write back to that. - value = (0x1 << 14); - wrmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG,&value, sizeof(value)); - udelay(1000); - uiRetries--; - if(uiRetries == 0) - { - return FALSE; - } - value = 0; - rdmalt(Adapter, EEPROM_SPI_Q_STATUS1_REG, &value, sizeof(value)); - } - return TRUE; - - -} - - -//----------------------------------------------------------------------------- -// Procedure: ReadBeceemEEPROMBulk -// -// Description: This routine reads 16Byte data from EEPROM -// -// Arguments: -// Adapter - ptr to Adapter object instance -// dwAddress - EEPROM Offset to read the data from. -// pdwData - Pointer to double word where data needs to be stored in. -// -// Returns: -// OSAL_STATUS_CODE: -//----------------------------------------------------------------------------- - -INT ReadBeceemEEPROMBulk(PMINI_ADAPTER Adapter,DWORD dwAddress, DWORD *pdwData) -{ - DWORD dwRetries = 16; - DWORD dwIndex = 0; - UINT value, tmpVal; - - - value = 0; - rdmalt (Adapter, 0x0f003008, &value, sizeof(value)); - - //read 0x0f003020 untill bit 1 of 0x0f003008 is set. - while(((value >> 1) & 1) == 0) - { - - rdmalt (Adapter, 0x0f003020, &tmpVal, sizeof(tmpVal)); - dwRetries--; - if(dwRetries == 0) - { - return -1; - } - value = 0; - rdmalt (Adapter, 0x0f003008, &value, sizeof(value)); - } - - value = dwAddress | 0xfb000000; - wrmalt (Adapter, 0x0f003018, &value, sizeof(value)); - - udelay(1000); - value = 0; - for(dwIndex = 0;dwIndex < 4 ; dwIndex++) - { - value = 0; - rdmalt (Adapter, 0x0f003020, &value, sizeof(value)); - pdwData[dwIndex] = value; - - value = 0; - rdmalt (Adapter, 0x0f003020, &value, sizeof(value)); - pdwData[dwIndex] |= (value << 8); - - value = 0; - rdmalt (Adapter, 0x0f003020, &value, sizeof(value)); - pdwData[dwIndex] |= (value << 16); - - value = 0; - rdmalt (Adapter, 0x0f003020, &value, sizeof(value)); - pdwData[dwIndex] |= (value << 24); - - } - return 0; -} - -//----------------------------------------------------------------------------- -// Procedure: ReadBeceemEEPROM -// -// Description: This routine reads 4Byte data from EEPROM -// -// Arguments: -// Adapter - ptr to Adapter object instance -// dwAddress - EEPROM Offset to read the data from. -// pdwData - Pointer to double word where data needs to be stored in. -// -// Returns: -// OSAL_STATUS_CODE: -//----------------------------------------------------------------------------- - -INT ReadBeceemEEPROM(PMINI_ADAPTER Adapter,DWORD dwAddress, DWORD *pdwData) -{ - - DWORD dwReadValue = 0; - DWORD dwRetries = 16, dwCompleteWord = 0; - UINT value, tmpVal; - - rdmalt(Adapter, 0x0f003008, &value, sizeof(value)); - while (((value >> 1) & 1) == 0) { - rdmalt(Adapter, 0x0f003020, &tmpVal, sizeof(tmpVal)); - - if (dwRetries == 0) { - return -1; - } - rdmalt(Adapter, 0x0f003008, &value, sizeof(value)); - } - - - //wrm (0x0f003018, 0xNbXXXXXX) // N is the number of bytes u want to read (0 means 1, f means 16, b is the opcode for page read) - // Follow it up by N executions of rdm(0x0f003020) to read the rxed bytes from rx queue. - dwAddress |= 0x3b000000; - wrmalt(Adapter, 0x0f003018,&dwAddress,4); - mdelay(10); - rdmalt(Adapter, 0x0f003020,&dwReadValue,4); - dwCompleteWord=dwReadValue; - rdmalt(Adapter, 0x0f003020,&dwReadValue,4); - dwCompleteWord|=(dwReadValue<<8); - rdmalt(Adapter, 0x0f003020,&dwReadValue,4); - dwCompleteWord|=(dwReadValue<<16); - rdmalt(Adapter, 0x0f003020,&dwReadValue,4); - dwCompleteWord|=(dwReadValue<<24); - - *pdwData = dwCompleteWord; - - return 0; -} -#endif INT ReadMacAddressFromNVM(PMINI_ADAPTER Adapter) { @@ -655,14 +493,6 @@ INT BeceemFlashBulkRead( UINT BcmGetFlashSize(PMINI_ADAPTER Adapter) { -#if 0 - if(Adapter->bDDRInitDone) - { - return rdm(Adapter,FLASH_CONTIGIOUS_START_ADDR_AFTER_INIT|FLASH_SIZE_ADDR); - } - - return rdm(Adapter,FLASH_CONTIGIOUS_START_ADDR_BEFORE_INIT|FLASH_SIZE_ADDR); -#endif if(IsFlash2x(Adapter)) return (Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + sizeof(DSD_HEADER)); else @@ -733,60 +563,6 @@ UINT BcmGetEEPROMSize(PMINI_ADAPTER Adapter) return 0; } -#if 0 -/***********************************************************************************/ -// -// WriteBeceemEEPROM: Writes 4 byte data to EEPROM offset. -// -// uiEEPROMOffset - Offset to be written to. -// uiData - Data to be written. -// -/***********************************************************************************/ - -INT WriteBeceemEEPROM(PMINI_ADAPTER Adapter,UINT uiEEPROMOffset, UINT uiData) -{ - INT Status = 0; - ULONG ulRdBk = 0; - ULONG ulRetryCount = 3; - UINT value; - - if(uiEEPROMOffset > EEPROM_END) - { - - return -1; - } - - uiData = htonl(uiData); - while(ulRetryCount--) - { - value = 0x06000000; - wrmalt(Adapter, 0x0F003018,&value, sizeof(value));//flush the EEPROM FIFO. - wrmalt(Adapter, 0x0F00301C,&uiData, sizeof(uiData)); - value = 0x3A000000 | uiEEPROMOffset; - wrmalt(Adapter, 0x0F003018,&value, sizeof(value)); - __udelay(100000); - //read back and verify. - Status = ReadBeceemEEPROM(Adapter,uiEEPROMOffset,(UINT *)&ulRdBk); - if(Status == 0) - { - if(ulRdBk == uiData) - { - return Status; - } - else - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "WriteBeceemEEPROM: Readback does not match\n"); - } - } - else - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "WriteBeceemEEPROM: Readback failed\n"); - } - } - - return 0; -} -#endif //----------------------------------------------------------------------------- // Procedure: FlashSectorErase @@ -1353,15 +1129,6 @@ INT BeceemFlashBulkWrite( UINT uiTemp = 0; UINT index = 0; UINT uiPartOffset = 0; - #if 0 - struct timeval tv1 = {0}; - struct timeval tv2 = {0}; - - struct timeval tr = {0}; - struct timeval te = {0}; - struct timeval tw = {0}; - struct timeval twv = {0}; - #endif #if defined(BCM_SHM_INTERFACE) && !defined(FLASH_DIRECT_ACCESS) Status = bcmflash_raw_write((uiOffset/FLASH_PART_SIZE),(uiOffset % FLASH_PART_SIZE),( unsigned char *)pBuffer,uiNumBytes); @@ -1396,7 +1163,6 @@ INT BeceemFlashBulkWrite( uiNumSectTobeRead++; } } - #if 1 //Check whether Requested sector is writable or not in case of flash2x write. But if write call is // for DSD calibration, allow it without checking of sector permission @@ -1417,7 +1183,6 @@ INT BeceemFlashBulkWrite( index = index + 1 ; } } - #endif Adapter->SelectedChip = RESET_CHIP_SELECT; while(uiNumSectTobeRead) { @@ -1689,21 +1454,6 @@ static INT BeceemFlashBulkWriteStatus( { for(uiIndex = 0;uiIndex < Adapter->uiSectorSize;uiIndex += MAX_RW_SIZE) { -#if 0 - if(0 == BeceemFlashBulkRead(Adapter,uiReadBk,uiOffsetFromSectStart+uiIndex + Adapter->ulFlashCalStart ,MAX_RW_SIZE)) - { - for(uiReadIndex = 0;uiReadIndex < 4; uiReadIndex++) - { - if(*((PUINT)&pTempBuff[uiIndex+uiReadIndex*4]) != uiReadBk[uiReadIndex]) - { - Status = -1; - goto BeceemFlashBulkWriteStatus_EXIT; - - } - } - - } -#endif if(STATUS_SUCCESS == BeceemFlashBulkRead(Adapter,(PUINT)ucReadBk,uiOffsetFromSectStart+uiIndex,MAX_RW_SIZE)) { @@ -3158,15 +2908,6 @@ INT BcmGetFlashCSInfo(PMINI_ADAPTER Adapter) Adapter->uiFlashLayoutMajorVersion = uiFlashLayoutMajorVersion; - #if 0 - if(FLASH_PART_SST25VF080B == Adapter->ulFlashID) - { - // - // 1MB flash has been selected. we have to use 64K as sector size no matter what is kept in FLASH_CS. - // - Adapter->uiSectorSize = 0x10000; - } - #endif return STATUS_SUCCESS ; } @@ -4837,20 +4578,6 @@ INT BcmCopySection(PMINI_ADAPTER Adapter, return -EINVAL; } - #if 0 - else - { - if((SrcSection == VSA0) || (SrcSection == VSA1) || (SrcSection == VSA2)) - { - if((DstSection != VSA0) && (DstSection != VSA1) && (DstSection != VSA2)) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Source and Destion secton is not of same type"); - return -EINVAL; - } - } - - } - #endif //if offset zero means have to copy complete secton if(numOfBytes == 0) @@ -4950,14 +4677,6 @@ INT SaveHeaderIfPresent(PMINI_ADAPTER Adapter, PUCHAR pBuff, UINT uiOffset) UINT uiSectAlignAddr = 0; UINT sig = 0; - #if 0 - //if Chenges in Header is allowed, Return back - if(Adapter->bHeaderChangeAllowed == TRUE) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "Header Change is allowed"); - return STATUS_SUCCESS ; - } - #endif //making the offset sector alligned uiSectAlignAddr = uiOffset & ~(Adapter->uiSectorSize - 1); @@ -5336,39 +5055,6 @@ INT WriteToFlashWithoutSectorErase(PMINI_ADAPTER Adapter, return Status; } -#if 0 -UINT getNumOfSubSectionWithWRPermisson(PMINI_ADAPTER Adapter, SECTION_TYPE secType) -{ - - UINT numOfWRSubSec = 0; - switch(secType) - { - case ISO : - if(IsSectionWritable(Adapter,ISO_IMAGE1)) - numOfWRSubSec = numOfWRSubSec + 1; - if(IsSectionWritable(Adapter,ISO_IMAGE2)) - numOfWRSubSec = numOfWRSubSec + 1; - break; - - case DSD : - if(IsSectionWritable(Adapter,DSD2)) - numOfWRSubSec = numOfWRSubSec + 1; - if(IsSectionWritable(Adapter,DSD1)) - numOfWRSubSec = numOfWRSubSec + 1; - if(IsSectionWritable(Adapter,DSD0)) - numOfWRSubSec = numOfWRSubSec + 1; - break ; - - case VSA : - //for VSA Add code Here - default : - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Invalid secton<%d> is passed", secType);\ - numOfWRSubSec = 0; - - } - return numOfWRSubSec; -} -#endif BOOLEAN IsSectionExistInFlash(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL section) { -- cgit v1.2.3 From 0980f2e8144ea0021a09be41176b736d76ca3db7 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Mon, 1 Nov 2010 00:04:52 -0400 Subject: beceem: reserve one queue for bit-bucket This preserves the semantics of the original driver (unclassified packets are dropped), but does it in a clean way; and fixes crash when packet is sent to offline device. Signed-off-by: Stephen Hemminger --- drivers/staging/bcm/InterfaceInit.c | 3 ++- drivers/staging/bcm/Macros.h | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/staging/bcm/InterfaceInit.c b/drivers/staging/bcm/InterfaceInit.c index dddf34bb7c8b..801ba65e9785 100644 --- a/drivers/staging/bcm/InterfaceInit.c +++ b/drivers/staging/bcm/InterfaceInit.c @@ -188,7 +188,8 @@ usbbcm_device_probe(struct usb_interface *intf, const struct usb_device_id *id) PS_INTERFACE_ADAPTER psIntfAdapter; struct net_device *ndev; - ndev = alloc_etherdev_mq(sizeof(MINI_ADAPTER), NO_OF_QUEUES); + /* Reserve one extra queue for the bit-bucket */ + ndev = alloc_etherdev_mq(sizeof(MINI_ADAPTER), NO_OF_QUEUES+1); if(ndev == NULL) { dev_err(&udev->dev, DRV_NAME ": no memory for device\n"); return -ENOMEM; diff --git a/drivers/staging/bcm/Macros.h b/drivers/staging/bcm/Macros.h index 14df2f86b14e..f2fd60286a4c 100644 --- a/drivers/staging/bcm/Macros.h +++ b/drivers/staging/bcm/Macros.h @@ -261,7 +261,7 @@ typedef enum _E_PHS_DSC_ACTION #define FIRMWARE_BEGIN_ADDR 0xBFC00000 -#define INVALID_QUEUE_INDEX (USHORT)-1 +#define INVALID_QUEUE_INDEX (NO_OF_QUEUES+1) #define INVALID_PID (pid_t)-1 #define DDR_80_MHZ 0 -- cgit v1.2.3 From c5ebe2278ba600ff48663ec84c6e7f34d291503f Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Mon, 1 Nov 2010 08:42:44 -0400 Subject: beceem: fix printf format strings Signed-off-by: Stephen Hemminger --- drivers/staging/bcm/LeakyBucket.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/staging/bcm/LeakyBucket.c b/drivers/staging/bcm/LeakyBucket.c index f9e8f2bb06d3..669acc8d088b 100644 --- a/drivers/staging/bcm/LeakyBucket.c +++ b/drivers/staging/bcm/LeakyBucket.c @@ -82,7 +82,7 @@ static ULONG GetSFTokenCount(PMINI_ADAPTER Adapter, PacketInfo *psSF) if(NULL == Adapter || (psSF < Adapter->PackInfo && (uintptr_t)psSF > (uintptr_t) &Adapter->PackInfo[HiPriority])) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL, "IPAFF: Got wrong Parameters:Adapter: %p, QIndex: %ld\n", Adapter, (psSF-Adapter->PackInfo)); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL, "IPAFF: Got wrong Parameters:Adapter: %p, QIndex: %zd\n", Adapter, (psSF-Adapter->PackInfo)); return 0; } @@ -94,14 +94,14 @@ static ULONG GetSFTokenCount(PMINI_ADAPTER Adapter, PacketInfo *psSF) } else { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL, "Not enough tokens in queue %ld Available %u\n", + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL, "Not enough tokens in queue %zd Available %u\n", psSF-Adapter->PackInfo, psSF->uiCurrentTokenCount); psSF->uiPendedLast = 1; } } else { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL, "IPAFF: Queue %ld not valid\n", psSF-Adapter->PackInfo); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL, "IPAFF: Queue %zd not valid\n", psSF-Adapter->PackInfo); } BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TOKEN_COUNTS, DBG_LVL_ALL, "IsPacketAllowedForFlow <==="); return 0; @@ -164,7 +164,7 @@ static VOID CheckAndSendPacketFromIndex(PMINI_ADAPTER Adapter, PacketInfo *psSF) int iPacketLen=0; - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "%ld ====>", (psSF-Adapter->PackInfo)); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "%zd ====>", (psSF-Adapter->PackInfo)); if((psSF != &Adapter->PackInfo[HiPriority]) && Adapter->LinkUpStatus && atomic_read(&psSF->uiPerSFTxResourceCount))//Get data packet { if(!psSF->ucDirection ) @@ -212,7 +212,7 @@ static VOID CheckAndSendPacketFromIndex(PMINI_ADAPTER Adapter, PacketInfo *psSF) } else { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "For Queue: %ld\n", psSF-Adapter->PackInfo); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "For Queue: %zd\n", psSF-Adapter->PackInfo); BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "\nAvailable Tokens = %d required = %d\n", psSF->uiCurrentTokenCount, iPacketLen); //this part indicates that becuase of non-availability of the tokens -- cgit v1.2.3 From ada692b09f4707a8e06b087b1546d9f5b3f2d37d Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Mon, 1 Nov 2010 09:26:47 -0400 Subject: beceem: fix character device ioctl Sparse caught several places where ioctl interface was incorrectly using user memory. Fix all the ioctl cases for casting and __user annotation. Signed-off-by: Stephen Hemminger --- drivers/staging/bcm/Bcmchar.c | 796 ++++++++++++++------------------------- drivers/staging/bcm/HostMibs.h | 7 - drivers/staging/bcm/Prototypes.h | 6 +- drivers/staging/bcm/headers.h | 1 - drivers/staging/bcm/hostmibs.c | 24 +- 5 files changed, 282 insertions(+), 552 deletions(-) delete mode 100644 drivers/staging/bcm/HostMibs.h diff --git a/drivers/staging/bcm/Bcmchar.c b/drivers/staging/bcm/Bcmchar.c index 6c9db7227ca2..3a1b9903bf07 100644 --- a/drivers/staging/bcm/Bcmchar.c +++ b/drivers/staging/bcm/Bcmchar.c @@ -102,11 +102,11 @@ static int bcm_char_release(struct inode *inode, struct file *filp) static ssize_t bcm_char_read(struct file *filp, char __user *buf, size_t size, loff_t *f_pos) { - PPER_TARANG_DATA pTarang = (PPER_TARANG_DATA)filp->private_data; + PPER_TARANG_DATA pTarang = filp->private_data; PMINI_ADAPTER Adapter = pTarang->Adapter; - struct sk_buff* Packet = NULL; - UINT PktLen = 0; - int wait_ret_val=0; + struct sk_buff* Packet = NULL; + ssize_t PktLen = 0; + int wait_ret_val=0; wait_ret_val = wait_event_interruptible(Adapter->process_read_wait_queue, (pTarang->RxAppControlHead || Adapter->device_removed)); @@ -145,7 +145,9 @@ static ssize_t bcm_char_read(struct file *filp, char __user *buf, size_t size, l BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "\nReturning from copy to user failure \n"); return -EFAULT; } - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Read %d Bytes From Adapter packet = 0x%p by process %d!\n", PktLen, Packet, current->pid); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, + "Read %zd Bytes From Adapter packet = %p by process %d!\n", + PktLen, Packet, current->pid); dev_kfree_skb(Packet); } @@ -155,15 +157,12 @@ static ssize_t bcm_char_read(struct file *filp, char __user *buf, size_t size, l static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) { - PPER_TARANG_DATA pTarang = (PPER_TARANG_DATA)filp->private_data; - void __user *argp = (void __user *)argp; + PPER_TARANG_DATA pTarang = filp->private_data; + void __user *argp = (void __user *)arg; PMINI_ADAPTER Adapter = pTarang->Adapter; INT Status = STATUS_FAILURE; - IOCTL_BUFFER IoBuffer={}; -#ifndef BCM_SHM_INTERFACE - int timeout = 0; -#endif - + int timeout = 0; + IOCTL_BUFFER IoBuffer; BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Parameters Passed to control IOCTL cmd=0x%X arg=0x%lX", cmd, arg); @@ -204,49 +203,40 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) Status = vendorextnIoctl(Adapter, cmd, arg); if(Status != CONTINUE_COMMON_PATH ) - { return Status; - } switch(cmd){ // Rdms for Swin Idle... case IOCTL_BCM_REGISTER_READ_PRIVATE: { RDM_BUFFER sRdmBuffer = {0}; - PCHAR temp_buff = NULL; - UINT Bufflen = 0; + PCHAR temp_buff; + UINT Bufflen; + /* Copy Ioctl Buffer structure */ - if(copy_from_user((PCHAR)&IoBuffer, argp, - sizeof(IOCTL_BUFFER))) - { - Status = -EFAULT; - break; - } + if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) + return -EFAULT; + + if (IoBuffer.InputLength > sizeof(sRdmBuffer)) + return -EINVAL; + if(copy_from_user(&sRdmBuffer, IoBuffer.InputBuffer, IoBuffer.InputLength)) + return -EFAULT; + + /* FIXME: need to restrict BuffLen */ Bufflen = IoBuffer.OutputLength + (4 - IoBuffer.OutputLength%4)%4; - temp_buff = (PCHAR)kmalloc(Bufflen, GFP_KERNEL); + temp_buff = kmalloc(Bufflen, GFP_KERNEL); if(!temp_buff) - { - return STATUS_FAILURE; - } - if(copy_from_user(&sRdmBuffer, IoBuffer.InputBuffer, - IoBuffer.InputLength)) - { - Status = -EFAULT; - break; - } + return -ENOMEM; + Status = rdmalt(Adapter, (UINT)sRdmBuffer.Register, (PUINT)temp_buff, Bufflen); - if(Status != STATUS_SUCCESS) - { - kfree(temp_buff); - return Status; - } - if(copy_to_user(IoBuffer.OutputBuffer, - (PCHAR)temp_buff, (UINT)IoBuffer.OutputLength)) + if(Status == STATUS_SUCCESS) { - Status = -EFAULT; + if(copy_to_user(IoBuffer.OutputBuffer, temp_buff, IoBuffer.OutputLength)) + Status = -EFAULT; } + kfree(temp_buff); break; } @@ -256,19 +246,16 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) UINT uiTempVar=0; /* Copy Ioctl Buffer structure */ - if(copy_from_user(&IoBuffer, argp, - sizeof(IOCTL_BUFFER))) - { - Status = -EFAULT; - break; - } + if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) + return -EFAULT; + + if (IoBuffer.InputLength > sizeof(sWrmBuffer)) + return -EINVAL; + /* Get WrmBuffer structure */ - if(copy_from_user(&sWrmBuffer, IoBuffer.InputBuffer, - IoBuffer.InputLength)) - { - Status = -EFAULT; - break; - } + if(copy_from_user(&sWrmBuffer, IoBuffer.InputBuffer, IoBuffer.InputLength)) + return -EFAULT; + uiTempVar = sWrmBuffer.Register & EEPROM_REJECT_MASK; if(!((Adapter->pstargetparams->m_u32Customize) & VSG_MODE) && ((uiTempVar == EEPROM_REJECT_REG_1)|| @@ -277,8 +264,7 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) (uiTempVar == EEPROM_REJECT_REG_4))) { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "EEPROM Access Denied, not in VSG Mode\n"); - Status = -EFAULT; - break; + return -EFAULT; } Status = wrmalt(Adapter, (UINT)sWrmBuffer.Register, (PUINT)sWrmBuffer.Data, sizeof(ULONG)); @@ -305,53 +291,38 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) (Adapter->bPreparingForLowPowerMode ==TRUE)) { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Device in Idle Mode, Blocking Rdms\n"); - Status = -EACCES; - break; + return -EACCES; } /* Copy Ioctl Buffer structure */ - if(copy_from_user(&IoBuffer, argp, - sizeof(IOCTL_BUFFER))) - { - Status = -EFAULT; - break; - } + if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) + return -EFAULT; + + if (IoBuffer.InputLength > sizeof(sRdmBuffer)) + return -EINVAL; + + if(copy_from_user(&sRdmBuffer, IoBuffer.InputBuffer, IoBuffer.InputLength)) + return -EFAULT; - temp_buff = (PCHAR)kmalloc(IoBuffer.OutputLength, GFP_KERNEL); + /* FIXME: don't trust user supplied length */ + temp_buff = kmalloc(IoBuffer.OutputLength, GFP_KERNEL); if(!temp_buff) - { return STATUS_FAILURE; - } - if(copy_from_user(&sRdmBuffer, IoBuffer.InputBuffer, - IoBuffer.InputLength)) - { - Status = -EFAULT; - break; - } - if( - (((ULONG)sRdmBuffer.Register & 0x0F000000) != 0x0F000000) || - ((ULONG)sRdmBuffer.Register & 0x3) - ) + if((((ULONG)sRdmBuffer.Register & 0x0F000000) != 0x0F000000) || + ((ULONG)sRdmBuffer.Register & 0x3)) { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "RDM Done On invalid Address : %x Access Denied.\n", (int)sRdmBuffer.Register); - Status = -EINVAL; - break; + return -EINVAL; } uiTempVar = sRdmBuffer.Register & EEPROM_REJECT_MASK; Status = rdmaltWithLock(Adapter, (UINT)sRdmBuffer.Register, (PUINT)temp_buff, IoBuffer.OutputLength); - if(Status != STATUS_SUCCESS) - { - kfree(temp_buff); - return Status; - } - if(copy_to_user(IoBuffer.OutputBuffer, - (PCHAR)temp_buff, (UINT)IoBuffer.OutputLength)) - { - Status = -EFAULT; - } + if(Status == STATUS_SUCCESS) + if(copy_to_user(IoBuffer.OutputBuffer, temp_buff, IoBuffer.OutputLength)) + Status = -EFAULT; + kfree(temp_buff); break; } @@ -365,34 +336,28 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) (Adapter->bPreparingForLowPowerMode ==TRUE)) { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Device in Idle Mode, Blocking Wrms\n"); - Status = -EACCES; - break; + return -EACCES; } + /* Copy Ioctl Buffer structure */ - if(copy_from_user((PCHAR)&IoBuffer, argp, - sizeof(IOCTL_BUFFER))) - { - Status = -EFAULT; - break; - } + if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) + return -EFAULT; + + if (IoBuffer.InputLength > sizeof(sWrmBuffer)) + return -EINVAL; + /* Get WrmBuffer structure */ - if(copy_from_user(&sWrmBuffer, IoBuffer.InputBuffer, - IoBuffer.InputLength)) - { - Status = -EFAULT; - break; - } - if( + if(copy_from_user(&sWrmBuffer, IoBuffer.InputBuffer, IoBuffer.InputLength)) + return -EFAULT; - (((ULONG)sWrmBuffer.Register & 0x0F000000) != 0x0F000000) || - ((ULONG)sWrmBuffer.Register & 0x3) - ) + if( (((ULONG)sWrmBuffer.Register & 0x0F000000) != 0x0F000000) || + ((ULONG)sWrmBuffer.Register & 0x3) ) { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "WRM Done On invalid Address : %x Access Denied.\n", (int)sWrmBuffer.Register); - Status = -EINVAL; - break; + return -EINVAL; } + uiTempVar = sWrmBuffer.Register & EEPROM_REJECT_MASK; if(!((Adapter->pstargetparams->m_u32Customize) & VSG_MODE) && ((uiTempVar == EEPROM_REJECT_REG_1)|| @@ -402,8 +367,7 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) (cmd == IOCTL_BCM_REGISTER_WRITE)) { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "EEPROM Access Denied, not in VSG Mode\n"); - Status = -EFAULT; - break; + return -EFAULT; } Status = wrmaltWithLock(Adapter, (UINT)sWrmBuffer.Register, @@ -432,19 +396,14 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) (Adapter->bPreparingForLowPowerMode ==TRUE)) { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"GPIO Can't be set/clear in Low power Mode"); - Status = -EACCES; - break; + return -EACCES; } if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) - { - Status = -EFAULT; - break; - } + return -EFAULT; + if (IoBuffer.InputLength > sizeof(gpio_info)) + return -EINVAL; if(copy_from_user(&gpio_info, IoBuffer.InputBuffer, IoBuffer.InputLength)) - { - Status = -EFAULT; - break; - } + return -EFAULT; uiBit = gpio_info.uiGpioNumber; uiOperation = gpio_info.uiGpioValue; @@ -513,8 +472,7 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) break; case BCM_LED_THREAD_STATE_CHANGE_REQ: { - - USER_THREAD_REQ threadReq = {0}; + USER_THREAD_REQ threadReq = { 0 }; BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"User made LED thread InActive"); if((Adapter->IdleMode == TRUE) || @@ -525,21 +483,16 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) Status = -EACCES; break; } - Status =copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)); - if(Status) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Failed while copying the IOBufer from user space err:%d",Status); - Status = -EFAULT; - break; - } - Status= copy_from_user(&threadReq, IoBuffer.InputBuffer, IoBuffer.InputLength); - if(Status) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Failed while copying the InputBuffer from user space err:%d",Status); - Status = -EFAULT; - break; - } + if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) + return -EFAULT; + + if (IoBuffer.InputLength > sizeof(threadReq)) + return -EINVAL; + + if (copy_from_user(&threadReq, IoBuffer.InputBuffer, IoBuffer.InputLength)) + return -EFAULT; + //if LED thread is running(Actively or Inactively) set it state to make inactive if(Adapter->LEDInfo.led_thread_running) { @@ -568,19 +521,13 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) if((Adapter->IdleMode == TRUE) || (Adapter->bShutStatus ==TRUE) || (Adapter->bPreparingForLowPowerMode ==TRUE)) - { - Status = -EACCES; - break; - } - if(copy_from_user((PCHAR)&IoBuffer, argp, sizeof(IOCTL_BUFFER))) { - Status = -EFAULT; - break; - } - if(copy_from_user(&gpio_info, IoBuffer.InputBuffer, IoBuffer.InputLength)) - { - Status = -EFAULT; - break; - } + return -EACCES; + if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) + return -EFAULT; + if (IoBuffer.InputLength > sizeof(gpio_info)) + return -EINVAL; + if(copy_from_user(&gpio_info, IoBuffer.InputBuffer, IoBuffer.InputLength)) + return -EFAULT; uiBit = gpio_info.uiGpioNumber; //Set the gpio output register Status = rdmaltWithLock(Adapter, (UINT)GPIO_PIN_STATE_REGISTER, @@ -604,25 +551,14 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) if((Adapter->IdleMode == TRUE) || (Adapter->bShutStatus ==TRUE) || (Adapter->bPreparingForLowPowerMode ==TRUE)) - { - Status = -EINVAL; - break; - } - Status = copy_from_user( (PCHAR)&IoBuffer, argp, sizeof( IOCTL_BUFFER)); - if(Status) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Failed while copying the IOBufer from user space err:%d",Status); - Status = -EFAULT; - break; - } + return -EINVAL; + if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) + return -EFAULT; + if (IoBuffer.InputLength > sizeof(gpio_multi_info)) + return -EINVAL; + if (copy_from_user(&gpio_multi_info, IoBuffer.InputBuffer, IoBuffer.InputLength)) + return -EFAULT; - Status = copy_from_user( &gpio_multi_info, IoBuffer.InputBuffer, IoBuffer.InputLength); - if(Status) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Failed while copying the IOBufer Contents from user space err:%d",Status); - Status = -EFAULT; - break; - } if(IsReqGpioIsLedInNVM(Adapter,pgpio_multi_info[WIMAX_IDX].uiGPIOMask)== FALSE) { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Sorry, Requested GPIO<0x%X> is not correspond to NVM LED bit map<0x%X>!!!",pgpio_multi_info[WIMAX_IDX].uiGPIOMask,Adapter->gpioBitMap); @@ -682,7 +618,6 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) if(Status) { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Failed while copying Content to IOBufer for user space err:%d",Status); - Status = -EFAULT; break; } } @@ -696,25 +631,14 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) if((Adapter->IdleMode == TRUE) || (Adapter->bShutStatus ==TRUE) || (Adapter->bPreparingForLowPowerMode ==TRUE)) - { - Status = -EINVAL; - break; - } - Status = copy_from_user(&IoBuffer, argp, sizeof( IOCTL_BUFFER)); - if(Status) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Failed while copying the IOBufer from user space err:%d",Status); - Status = -EFAULT; - break; - } + return -EINVAL; - Status = copy_from_user( &gpio_multi_mode, IoBuffer.InputBuffer, IoBuffer.InputLength); - if(Status) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Failed while copying the IOBufer Contents from user space err:%d",Status); - Status = -EFAULT; - break; - } + if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) + return -EFAULT; + if (IoBuffer.InputLength > sizeof(gpio_multi_mode)) + return -EINVAL; + if (copy_from_user(&gpio_multi_mode, IoBuffer.InputBuffer, IoBuffer.InputLength)) + return -EFAULT; Status = rdmaltWithLock( Adapter, ( UINT) GPIO_MODE_REGISTER, ( PUINT) ucResetValue, sizeof( UINT)); if( STATUS_SUCCESS != Status) @@ -765,7 +689,6 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) if(Status) { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Failed while copying Content to IOBufer for user space err:%d",Status); - Status = -EFAULT; break; } } @@ -779,21 +702,17 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) case IOCTL_IDLE_REQ: { PVOID pvBuffer=NULL; + /* Copy Ioctl Buffer structure */ - if(copy_from_user(&IoBuffer, argp, - sizeof(IOCTL_BUFFER))) - { - Status = -EFAULT; - break; - } - pvBuffer=kmalloc(IoBuffer.InputLength, GFP_KERNEL); + if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) + return -EFAULT; + + /* FIXME: don't accept any length from user */ + pvBuffer = kmalloc(IoBuffer.InputLength, GFP_KERNEL); if(!pvBuffer) - { return -ENOMEM; - } - if(copy_from_user(pvBuffer, IoBuffer.InputBuffer, - IoBuffer.InputLength)) + if(copy_from_user(pvBuffer, IoBuffer.InputBuffer, IoBuffer.InputLength)) { Status = -EFAULT; kfree(pvBuffer); @@ -839,7 +758,7 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) Status = reset_card_proc(Adapter); if(Status) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "reset_card_proc Failed!\n"); + pr_err(PFX "%s: reset_card_proc Failed!\n", Adapter->dev->name); up(&Adapter->fw_download_sema); up(&Adapter->NVMRdmWrmLock); break; @@ -857,7 +776,7 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) } case IOCTL_BCM_BUFFER_DOWNLOAD: { - FIRMWARE_INFO *psFwInfo=NULL; + FIRMWARE_INFO *psFwInfo = NULL; BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Starting the firmware download PID =0x%x!!!!\n", current->pid); do{ if(!down_trylock(&Adapter->fw_download_sema)) @@ -866,29 +785,23 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) Status=-EINVAL; break; } + /* Copy Ioctl Buffer structure */ if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "copy_from_user 1 failed\n"); - Status = -EFAULT; - break; - } + return -EFAULT; + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Length for FW DLD is : %lx\n", IoBuffer.InputLength); - psFwInfo=kmalloc(sizeof(*psFwInfo), GFP_KERNEL); + + if (IoBuffer.InputLength > sizeof(FIRMWARE_INFO)) + return -EINVAL; + + psFwInfo = kmalloc(sizeof(*psFwInfo), GFP_KERNEL); if(!psFwInfo) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Failed to allocate buffer!!!!\n"); - Status = -ENOMEM; - break; - } - if(copy_from_user(psFwInfo, IoBuffer.InputBuffer, - IoBuffer.InputLength)) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy_from_user 2 failed\n"); - Status = -EFAULT; - break; - } + return -ENOMEM; + + if(copy_from_user(psFwInfo, IoBuffer.InputBuffer, IoBuffer.InputLength)) + return -EFAULT; if(!psFwInfo->pvMappedFirmwareAddress || (psFwInfo->u32FirmwareLength == 0)) @@ -941,7 +854,7 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) Adapter->bBinDownloaded=TRUE; Adapter->bCfgDownloaded=TRUE; atomic_set(&Adapter->CurrNumFreeTxDesc, 0); - atomic_set(&Adapter->RxRollOverCount, 0); + Adapter->CurrNumRecvDescs=0; Adapter->downloadDDR = 0; @@ -1038,22 +951,16 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) break; case IOCTL_GET_PACK_INFO: - if(copy_to_user(argp, &Adapter->PackInfo, - sizeof(PacketInfo)*NO_OF_QUEUES)) - { - Status = -EFAULT; - break; - } + if(copy_to_user(argp, &Adapter->PackInfo, sizeof(PacketInfo)*NO_OF_QUEUES)) + return -EFAULT; Status = STATUS_SUCCESS; break; case IOCTL_BCM_SWITCH_TRANSFER_MODE: { UINT uiData = 0; if(copy_from_user(&uiData, argp, sizeof(UINT))) - { - Status = -EFAULT; - break; - } + return -EFAULT; + if(uiData) /* Allow All Packets */ { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "IOCTL_BCM_SWITCH_TRANSFER_MODE: ETH_PACKET_TUNNELING_MODE\n"); @@ -1072,22 +979,17 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) { /* Copy Ioctl Buffer structure */ if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) - { - Status = -EFAULT; - break; - } - if(copy_to_user(IoBuffer.OutputBuffer, - VER_FILEVERSION_STR, (UINT)IoBuffer.OutputLength)) - { - Status = -EFAULT; - break; - } + return -EFAULT; + + if(copy_to_user(IoBuffer.OutputBuffer, VER_FILEVERSION_STR, IoBuffer.OutputLength)) + return -EFAULT; Status = STATUS_SUCCESS; break; } case IOCTL_BCM_GET_CURRENT_STATUS: { - LINK_STATE *plink_state = NULL; + LINK_STATE link_state; + /* Copy Ioctl Buffer structure */ if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) { @@ -1095,12 +997,15 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) Status = -EFAULT; break; } - plink_state = (LINK_STATE*)arg; - plink_state->bIdleMode = (UCHAR)Adapter->IdleMode; - plink_state->bShutdownMode = Adapter->bShutStatus; - plink_state->ucLinkStatus = (UCHAR)Adapter->LinkStatus; - if(copy_to_user(IoBuffer.OutputBuffer, - (PUCHAR)plink_state, (UINT)IoBuffer.OutputLength)) + + + memset(&link_state, 0, sizeof(link_state)); + link_state.bIdleMode = Adapter->IdleMode; + link_state.bShutdownMode = Adapter->bShutStatus; + link_state.ucLinkStatus = Adapter->LinkStatus; + + if (copy_to_user(IoBuffer.OutputBuffer, &link_state, + min_t(size_t, sizeof(link_state), IoBuffer.OutputLength))) { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy_to_user Failed..\n"); Status = -EFAULT; @@ -1112,17 +1017,14 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) case IOCTL_BCM_SET_MAC_TRACING: { UINT tracing_flag; + /* copy ioctl Buffer structure */ - if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) - { - Status = -EFAULT; - break; - } - if(copy_from_user(&tracing_flag, IoBuffer.InputBuffer,sizeof(UINT))) - { - Status = -EFAULT; - break; - } + if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) + return -EFAULT; + + if(copy_from_user(&tracing_flag,IoBuffer.InputBuffer,sizeof(UINT))) + return -EFAULT; + if (tracing_flag) Adapter->pTarangs->MacTracingEnabled = TRUE; else @@ -1132,70 +1034,51 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) case IOCTL_BCM_GET_DSX_INDICATION: { ULONG ulSFId=0; - if(copy_from_user((PCHAR)&IoBuffer, argp, - sizeof(IOCTL_BUFFER))) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Invalid IO buffer!!!" ); - Status = -EFAULT; - break; - } + if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) + return -EFAULT; + if(IoBuffer.OutputLength < sizeof(stLocalSFAddIndicationAlt)) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Mismatch req: %lx needed is =0x%zx!!!", - IoBuffer.OutputLength, sizeof(stLocalSFAddIndicationAlt)); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, + "Mismatch req: %lx needed is =0x%zx!!!", + IoBuffer.OutputLength, sizeof(stLocalSFAddIndicationAlt)); return -EINVAL; } - if(copy_from_user(&ulSFId, IoBuffer.InputBuffer, - sizeof(ulSFId))) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Invalid SFID!!! %lu", ulSFId ); - Status = -EFAULT; - break; - } + + if(copy_from_user(&ulSFId, IoBuffer.InputBuffer, sizeof(ulSFId))) + return -EFAULT; + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Get DSX Data SF ID is =%lx\n", ulSFId ); - get_dsx_sf_data_to_application(Adapter, ulSFId, - IoBuffer.OutputBuffer); + get_dsx_sf_data_to_application(Adapter, ulSFId, IoBuffer.OutputBuffer); Status=STATUS_SUCCESS; } break; case IOCTL_BCM_GET_HOST_MIBS: { - PCHAR temp_buff; + PVOID temp_buff; if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy_from user for IoBuff failed\n"); - Status = -EFAULT; - break; - } + return -EFAULT; if(IoBuffer.OutputLength != sizeof(S_MIBS_HOST_STATS_MIBS)) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Length Check failed %lu %zd\n", IoBuffer.OutputLength, - sizeof(S_MIBS_HOST_STATS_MIBS)); - return -EINVAL; + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, + "Length Check failed %lu %zd\n", + IoBuffer.OutputLength, sizeof(S_MIBS_HOST_STATS_MIBS)); + return -EINVAL; } - temp_buff = (PCHAR)kmalloc(IoBuffer.OutputLength, GFP_KERNEL); - + /* FIXME: HOST_STATS are too big for kmalloc (122048)! */ + temp_buff = kzalloc(sizeof(S_MIBS_HOST_STATS_MIBS), GFP_KERNEL); if(!temp_buff) - { return STATUS_FAILURE; - } - - Status = ProcessGetHostMibs(Adapter, - (PUCHAR)temp_buff, IoBuffer.OutputLength); - Status = GetDroppedAppCntrlPktMibs((PVOID)temp_buff, - (PPER_TARANG_DATA)filp->private_data); + Status = ProcessGetHostMibs(Adapter, temp_buff); + GetDroppedAppCntrlPktMibs(temp_buff, pTarang); - if(copy_to_user(IoBuffer.OutputBuffer,(PCHAR)temp_buff, - sizeof(S_MIBS_HOST_STATS_MIBS))) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy to user failed\n"); - kfree(temp_buff); - return -EFAULT; - } + if (Status != STATUS_FAILURE) + if(copy_to_user(IoBuffer.OutputBuffer, temp_buff, sizeof(S_MIBS_HOST_STATS_MIBS))) + Status = -EFAULT; kfree(temp_buff); break; @@ -1225,22 +1108,18 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) Status = -EACCES; break; } + /* Copy Ioctl Buffer structure */ - if(copy_from_user((PCHAR)&IoBuffer, argp, sizeof(IOCTL_BUFFER))) - { - Status = -EFAULT; - break; - } + if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) + return -EFAULT; - pvBuffer=kmalloc(IoBuffer.InputLength, GFP_KERNEL); + /* FIXME: restrict length */ + pvBuffer = kmalloc(IoBuffer.InputLength, GFP_KERNEL); if(!pvBuffer) - { return -ENOMEM; - break; - } /* Get WrmBuffer structure */ - if(copy_from_user(pvBuffer, IoBuffer.InputBuffer, IoBuffer.InputLength)) + if(copy_from_user(pvBuffer, IoBuffer.InputBuffer, IoBuffer.InputLength)) { kfree(pvBuffer); Status = -EFAULT; @@ -1288,25 +1167,14 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) } case IOCTL_BCM_GET_NVM_SIZE: - { - if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) - { - //IOLog("failed NVM first"); - Status = -EFAULT; - break; - } + return -EFAULT; + if(Adapter->eNVMType == NVM_EEPROM || Adapter->eNVMType == NVM_FLASH ) { - if(copy_to_user(IoBuffer.OutputBuffer, - (unsigned char *)&Adapter->uiNVMDSDSize, (UINT)sizeof(UINT))) - { - Status = -EFAULT; - return Status; - } + if(copy_to_user(IoBuffer.OutputBuffer, &Adapter->uiNVMDSDSize, sizeof(UINT))) + return -EFAULT; } - Status = STATUS_SUCCESS ; - } break; case IOCTL_BCM_CAL_INIT : @@ -1315,38 +1183,26 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) UINT uiSectorSize = 0 ; if(Adapter->eNVMType == NVM_FLASH) { - Status = copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)); - if(Status) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Copy From User space failed. status :%d", Status); + if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) return -EFAULT; - } - uiSectorSize = *((PUINT)(IoBuffer.InputBuffer)); /* FIXME: unchecked __user access */ + + if (copy_from_user(&uiSectorSize, IoBuffer.InputBuffer, sizeof(UINT))) + return -EFAULT; + if((uiSectorSize < MIN_SECTOR_SIZE) || (uiSectorSize > MAX_SECTOR_SIZE)) { - - Status = copy_to_user(IoBuffer.OutputBuffer, - (unsigned char *)&Adapter->uiSectorSize , - (UINT)sizeof(UINT)); - if(Status) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Coping the sector size to use space failed. status:%d",Status); - return -EFAULT; - } + if (copy_to_user(IoBuffer.OutputBuffer, &Adapter->uiSectorSize, + sizeof(UINT))) + return -EFAULT; } else { if(IsFlash2x(Adapter)) { - Status = copy_to_user(IoBuffer.OutputBuffer, - (unsigned char *)&Adapter->uiSectorSize , - (UINT)sizeof(UINT)); - if(Status) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Coping the sector size to use space failed. status:%d",Status); - return -EFAULT; - } - + if (copy_to_user(IoBuffer.OutputBuffer, + &Adapter->uiSectorSize , + sizeof(UINT))) + return -EFAULT; } else { @@ -1370,25 +1226,19 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) } break; case IOCTL_BCM_SET_DEBUG : +#ifdef DEBUG { USER_BCM_DBG_STATE sUserDebugState; // BCM_DEBUG_PRINT (Adapter, DBG_TYPE_PRINTK, 0, 0, "Entered the ioctl %x \n", IOCTL_BCM_SET_DEBUG ); BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "In SET_DEBUG ioctl\n"); - Status = copy_from_user((PCHAR)&IoBuffer, argp, sizeof(IOCTL_BUFFER)); - if(Status) - { - BCM_DEBUG_PRINT (Adapter, DBG_TYPE_PRINTK, 0, 0, "Copy from user failed\n"); - Status = -EFAULT; - break; - } - Status = copy_from_user(&sUserDebugState,IoBuffer.InputBuffer, sizeof(USER_BCM_DBG_STATE)); - if(Status) - { - BCM_DEBUG_PRINT (Adapter, DBG_TYPE_PRINTK, 0, 0, "Copy of IoBuffer.InputBuffer failed"); + if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) + return -EFAULT; + + if (copy_from_user(&sUserDebugState, IoBuffer.InputBuffer, sizeof(USER_BCM_DBG_STATE))) return -EFAULT; - } + BCM_DEBUG_PRINT (Adapter, DBG_TYPE_PRINTK, 0, 0, "IOCTL_BCM_SET_DEBUG: OnOff=%d Type = 0x%x ", sUserDebugState.OnOff, sUserDebugState.Type); @@ -1411,15 +1261,14 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) BCM_SHOW_DEBUG_BITMAP(Adapter); } +#endif break; case IOCTL_BCM_NVM_READ: case IOCTL_BCM_NVM_WRITE: { - - NVM_READWRITE stNVMReadWrite = {}; + NVM_READWRITE stNVMReadWrite; PUCHAR pReadData = NULL; - void __user * pBuffertobeCopied = NULL; - ULONG ulDSDMagicNumInUsrBuff = 0 ; + ULONG ulDSDMagicNumInUsrBuff = 0; struct timeval tv0, tv1; memset(&tv0,0,sizeof(struct timeval)); memset(&tv1,0,sizeof(struct timeval)); @@ -1444,21 +1293,12 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) /* Copy Ioctl Buffer structure */ if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"copy_from_user failed\n"); - Status = -EFAULT; - break; - } - if(IOCTL_BCM_NVM_READ == cmd) - pBuffertobeCopied = IoBuffer.OutputBuffer; - else - pBuffertobeCopied = IoBuffer.InputBuffer; + return -EFAULT; - if(copy_from_user(&stNVMReadWrite, pBuffertobeCopied,sizeof(NVM_READWRITE))) - { - Status = -EFAULT; - break; - } + if(copy_from_user(&stNVMReadWrite, + (IOCTL_BCM_NVM_READ == cmd) ? IoBuffer.OutputBuffer : IoBuffer.InputBuffer, + sizeof(NVM_READWRITE))) + return -EFAULT; // // Deny the access if the offset crosses the cal area limit. @@ -1471,13 +1311,10 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) break; } - pReadData =(PCHAR)kmalloc(stNVMReadWrite.uiNumBytes, GFP_KERNEL); - + pReadData = kzalloc(stNVMReadWrite.uiNumBytes, GFP_KERNEL); if(!pReadData) return -ENOMEM; - memset(pReadData,0,stNVMReadWrite.uiNumBytes); - if(copy_from_user(pReadData, stNVMReadWrite.pBuffer, stNVMReadWrite.uiNumBytes)) { @@ -1511,8 +1348,7 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) kfree(pReadData); return Status; } - if(copy_to_user(stNVMReadWrite.pBuffer, - pReadData, (UINT)stNVMReadWrite.uiNumBytes)) + if(copy_to_user(stNVMReadWrite.pBuffer,pReadData, stNVMReadWrite.uiNumBytes)) { kfree(pReadData); Status = -EFAULT; @@ -1604,7 +1440,7 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) UINT BuffSize = 0; UINT ReadBytes = 0; UINT ReadOffset = 0; - char __user *OutPutBuff = NULL; + void __user *OutPutBuff; if(IsFlash2x(Adapter) != TRUE) { @@ -1613,20 +1449,12 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) } BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "IOCTL_BCM_FLASH2X_SECTION_READ Called"); - Status = copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)); - if(Status) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy of IOCTL BUFFER failed"); + if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) return -EFAULT; - } //Reading FLASH 2.x READ structure - Status = copy_from_user(&sFlash2xRead, IoBuffer.InputBuffer,sizeof(FLASH2X_READWRITE)); - if(Status) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy of Input Buffer failed"); + if (copy_from_user(&sFlash2xRead, IoBuffer.InputBuffer,sizeof(FLASH2X_READWRITE))) return -EFAULT; - } BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"\nsFlash2xRead.Section :%x" ,sFlash2xRead.Section); @@ -1690,7 +1518,6 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) if(Status) { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Copy to use failed with status :%d", Status); - Status = -EFAULT; break; } NOB = NOB - ReadBytes; @@ -1709,8 +1536,8 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) case IOCTL_BCM_FLASH2X_SECTION_WRITE : { FLASH2X_READWRITE sFlash2xWrite = {0}; - PUCHAR pWriteBuff = NULL; - void __user *InputAddr = NULL; + PUCHAR pWriteBuff; + void __user *InputAddr; UINT NOB = 0; UINT BuffSize = 0; UINT WriteOffset = 0; @@ -1727,20 +1554,12 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, " IOCTL_BCM_FLASH2X_SECTION_WRITE Called"); - Status = copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)); - if(Status) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy of IOCTL BUFFER failed"); + if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) return -EFAULT; - } //Reading FLASH 2.x READ structure - Status = copy_from_user(&sFlash2xWrite, IoBuffer.InputBuffer, sizeof(FLASH2X_READWRITE)); - if(Status) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Reading of output Buffer from IOCTL buffer fails"); + if (copy_from_user(&sFlash2xWrite, IoBuffer.InputBuffer, sizeof(FLASH2X_READWRITE))) return -EFAULT; - } BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"\nsFlash2xRead.Section :%x" ,sFlash2xWrite.Section); BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"\nsFlash2xRead.offset :%d" ,sFlash2xWrite.offset); @@ -1765,12 +1584,10 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) else BuffSize = NOB ; - pWriteBuff = (PCHAR)kmalloc(BuffSize, GFP_KERNEL); + pWriteBuff = kmalloc(BuffSize, GFP_KERNEL); if(pWriteBuff == NULL) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Memory allocation failed for Flash 2.x Read Structure"); return -ENOMEM; - } + //extracting the remainder of the given offset. WriteBytes = Adapter->uiSectorSize ; @@ -1798,7 +1615,6 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) if(Status) { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Copy to user failed with status :%d", Status); - Status = -EFAULT; break ; } BCM_DEBUG_PRINT_BUFFER(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,pWriteBuff,WriteBytes); @@ -1832,22 +1648,16 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) case IOCTL_BCM_GET_FLASH2X_SECTION_BITMAP : { - PFLASH2X_BITMAP psFlash2xBitMap = NULL ; + PFLASH2X_BITMAP psFlash2xBitMap; BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "IOCTL_BCM_GET_FLASH2X_SECTION_BITMAP Called"); - Status = copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)); - if(Status) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy of IOCTL BUFFER failed"); + if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) return -EFAULT; - } + if(IoBuffer.OutputLength != sizeof(FLASH2X_BITMAP)) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Structure size mismatch Lib :0x%lx Driver :0x%zx ",IoBuffer.OutputLength, sizeof(FLASH2X_BITMAP)); - break; - } + return -EINVAL; - psFlash2xBitMap = (PFLASH2X_BITMAP)kzalloc(sizeof(FLASH2X_BITMAP), GFP_KERNEL); + psFlash2xBitMap = kzalloc(sizeof(FLASH2X_BITMAP), GFP_KERNEL); if(psFlash2xBitMap == NULL) { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Memory is not available"); @@ -1868,13 +1678,9 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) BcmGetFlash2xSectionalBitMap(Adapter, psFlash2xBitMap); up(&Adapter->NVMRdmWrmLock); - Status = copy_to_user(IoBuffer.OutputBuffer, psFlash2xBitMap, sizeof(FLASH2X_BITMAP)); - if(Status) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "copying Flash2x bitMap failed"); - kfree(psFlash2xBitMap); - return -EFAULT; - } + if (copy_to_user(IoBuffer.OutputBuffer, psFlash2xBitMap, sizeof(FLASH2X_BITMAP))) + Status = -EFAULT; + kfree(psFlash2xBitMap); } break ; @@ -1893,14 +1699,14 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) if(Status) { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy of IOCTL BUFFER failed"); - return -EFAULT; + return Status; } Status = copy_from_user(&eFlash2xSectionVal,IoBuffer.InputBuffer, sizeof(INT)); if(Status) { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy of flash section val failed"); - return -EFAULT; + return Status; } down(&Adapter->NVMRdmWrmLock); @@ -1948,14 +1754,14 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) if(Status) { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy of IOCTL BUFFER failed Status :%d", Status); - return -EFAULT; + return Status; } - Status = copy_from_user(&sCopySectStrut,IoBuffer.InputBuffer, sizeof(FLASH2X_COPY_SECTION)); + Status = copy_from_user(&sCopySectStrut, IoBuffer.InputBuffer, sizeof(FLASH2X_COPY_SECTION)); if(Status) { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy of Copy_Section_Struct failed with Status :%d", Status); - return -EFAULT; + return Status; } BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Source SEction :%x", sCopySectStrut.SrcSection); BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Destination SEction :%x", sCopySectStrut.DstSection); @@ -2026,7 +1832,6 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) if(Status) { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy of IOCTL BUFFER failed"); - Status = -EFAULT; break; } if(Adapter->eNVMType != NVM_FLASH) @@ -2039,35 +1844,18 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) { if(IoBuffer.OutputLength < sizeof(FLASH2X_CS_INFO)) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0," Passed buffer size:0x%lX is insufficient for the CS structure.. \nRequired size :0x%zx ",IoBuffer.OutputLength, sizeof(FLASH2X_CS_INFO)); - Status = -EINVAL; - break; - } + return -EINVAL; - Status = copy_to_user(IoBuffer.OutputBuffer, Adapter->psFlash2xCSInfo, sizeof(FLASH2X_CS_INFO)); - if(Status) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "copying Flash2x cs info failed"); - Status = -EFAULT; - break; - } + if (copy_to_user(IoBuffer.OutputBuffer, Adapter->psFlash2xCSInfo, sizeof(FLASH2X_CS_INFO))) + return -EFAULT; } else { if(IoBuffer.OutputLength < sizeof(FLASH_CS_INFO)) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0," Passed buffer size:0x%lX is insufficient for the CS structure.. Required size :0x%zx ",IoBuffer.OutputLength, sizeof(FLASH_CS_INFO)); - Status = -EINVAL; - break; - } - Status = copy_to_user(IoBuffer.OutputBuffer, Adapter->psFlashCSInfo, sizeof(FLASH_CS_INFO)); - if(Status) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "copying Flash CS info failed"); - Status = -EFAULT; - break; - } + return -EINVAL; + + if (copy_to_user(IoBuffer.OutputBuffer, Adapter->psFlashCSInfo, sizeof(FLASH_CS_INFO))) + return -EFAULT; } } @@ -2089,13 +1877,13 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) if(Status) { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy of IOCTL BUFFER failed"); - return -EFAULT; + return Status; } - Status = copy_from_user(&eFlash2xSectionVal,IoBuffer.InputBuffer, sizeof(INT)); + Status = copy_from_user(&eFlash2xSectionVal, IoBuffer.InputBuffer, sizeof(INT)); if(Status) { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy of flash section val failed"); - return -EFAULT; + return Status; } BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Read Section :%d", eFlash2xSectionVal); @@ -2125,13 +1913,13 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) case IOCTL_BCM_NVM_RAW_READ : { - NVM_READWRITE stNVMRead = {}; + NVM_READWRITE stNVMRead; INT NOB ; INT BuffSize ; INT ReadOffset = 0; UINT ReadBytes = 0 ; - PUCHAR pReadBuff = NULL ; - char __user *OutPutBuff = NULL ; + PUCHAR pReadBuff; + void __user *OutPutBuff; if(Adapter->eNVMType != NVM_FLASH) { @@ -2148,10 +1936,7 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) } if(copy_from_user(&stNVMRead, IoBuffer.OutputBuffer,sizeof(NVM_READWRITE))) - { - Status = -EFAULT; - break; - } + return -EFAULT; NOB = stNVMRead.uiNumBytes; //In Raw-Read max Buff size : 64MB @@ -2161,11 +1946,10 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) else BuffSize = NOB ; - ReadOffset = stNVMRead.uiOffset ; + ReadOffset = stNVMRead.uiOffset; OutPutBuff = stNVMRead.pBuffer; - - pReadBuff = (PCHAR)kzalloc(BuffSize , GFP_KERNEL); + pReadBuff = kzalloc(BuffSize , GFP_KERNEL); if(pReadBuff == NULL) { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Memory allocation failed for Flash 2.x Read Structure"); @@ -2200,13 +1984,12 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) break; } - BCM_DEBUG_PRINT_BUFFER(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,pReadBuff, ReadBytes); + BCM_DEBUG_PRINT_BUFFER(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,pReadBuff,ReadBytes); Status = copy_to_user(OutPutBuff, pReadBuff,ReadBytes); if(Status) { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Copy to use failed with status :%d", Status); - Status = -EFAULT; break; } NOB = NOB - ReadBytes; @@ -2232,7 +2015,6 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) if(Status) { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"copy of Ioctl buffer is failed from user space"); - Status = -EFAULT; break; } @@ -2240,7 +2022,6 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) if(Status) { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"copy of control bit mask failed from user space"); - Status = -EFAULT; break; } BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"\n Got user defined cntrl msg bit mask :%lx", RxCntrlMsgBitMask); @@ -2259,66 +2040,41 @@ static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg) DevInfo.u32NVMType = Adapter->eNVMType; DevInfo.u32InterfaceType = BCM_USB; - Status = copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)); - if(Status) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy of IOCTL BUFFER failed"); - Status = -EFAULT; - break; - } + if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) + return -EFAULT; + if(IoBuffer.OutputLength < sizeof(DevInfo)) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"User Passed buffer length is less than actural buffer size"); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"user passed buffer size :0x%lX, expected size :0x%zx",IoBuffer.OutputLength, sizeof(DevInfo)); - Status = -EINVAL; - break; - } - Status = copy_to_user(IoBuffer.OutputBuffer, &DevInfo, sizeof(DevInfo)); - if(Status) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"copying Dev info structure to user space buffer failed"); - Status = -EFAULT; - break; - } + return -EINVAL; + + if (copy_to_user(IoBuffer.OutputBuffer, &DevInfo, sizeof(DevInfo))) + return -EFAULT; } break ; case IOCTL_BCM_TIME_SINCE_NET_ENTRY: { ST_TIME_ELAPSED stTimeElapsedSinceNetEntry = {0}; - struct timeval tv = {0} ; BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"IOCTL_BCM_TIME_SINCE_NET_ENTRY called"); - Status = copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)); - if(Status) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy of IOCTL BUFFER failed"); - Status = -EFAULT; - break; - } + if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER))) + return -EFAULT; + if(IoBuffer.OutputLength < sizeof(ST_TIME_ELAPSED)) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"User Passed buffer length:0x%lx is less than expected buff size :0x%zX",IoBuffer.OutputLength,sizeof(ST_TIME_ELAPSED)); - Status = -EINVAL; - break; - } + return -EINVAL; - //stTimeElapsedSinceNetEntry.ul64TimeElapsedSinceNetEntry = Adapter->liTimeSinceLastNetEntry; - do_gettimeofday(&tv); - stTimeElapsedSinceNetEntry.ul64TimeElapsedSinceNetEntry = tv.tv_sec - Adapter->liTimeSinceLastNetEntry; + stTimeElapsedSinceNetEntry.ul64TimeElapsedSinceNetEntry = get_seconds() - Adapter->liTimeSinceLastNetEntry; - Status = copy_to_user(IoBuffer.OutputBuffer, &stTimeElapsedSinceNetEntry, sizeof(ST_TIME_ELAPSED)); - if(Status) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"copying ST_TIME_ELAPSED structure to user space buffer failed"); - Status = -EFAULT; - break; - } + if (copy_to_user(IoBuffer.OutputBuffer, &stTimeElapsedSinceNetEntry, sizeof(ST_TIME_ELAPSED))) + return -EFAULT; } break; + case IOCTL_CLOSE_NOTIFICATION: + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"IOCTL_CLOSE_NOTIFICATION"); + break; + default: pr_info(DRV_NAME ": unknown ioctl cmd=%#x\n", cmd); Status = STATUS_FAILURE; diff --git a/drivers/staging/bcm/HostMibs.h b/drivers/staging/bcm/HostMibs.h deleted file mode 100644 index 28a578311378..000000000000 --- a/drivers/staging/bcm/HostMibs.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef _HOST_MIBS_H -#define _HOST_MIBS_H - -INT ProcessGetHostMibs(PMINI_ADAPTER Adapter, - PVOID ioBuffer, - ULONG inputBufferLength); -#endif diff --git a/drivers/staging/bcm/Prototypes.h b/drivers/staging/bcm/Prototypes.h index a4b57bb07fa1..c9e1d61efe5f 100644 --- a/drivers/staging/bcm/Prototypes.h +++ b/drivers/staging/bcm/Prototypes.h @@ -108,10 +108,8 @@ void SendIdleModeResponse(PMINI_ADAPTER Adapter); void HandleShutDownModeRequest(PMINI_ADAPTER Adapter,PUCHAR pucBuffer); -int ProcessGetHostMibs(PMINI_ADAPTER Adapter, PVOID ioBuffer, - ULONG inputBufferLength); - -int GetDroppedAppCntrlPktMibs(PVOID ioBuffer, PPER_TARANG_DATA pTarang); +int ProcessGetHostMibs(PMINI_ADAPTER Adapter, S_MIBS_HOST_STATS_MIBS *buf); +void GetDroppedAppCntrlPktMibs(S_MIBS_HOST_STATS_MIBS *ioBuffer, PPER_TARANG_DATA pTarang); void beceem_parse_target_struct(PMINI_ADAPTER Adapter); void doPowerAutoCorrection(PMINI_ADAPTER psAdapter); diff --git a/drivers/staging/bcm/headers.h b/drivers/staging/bcm/headers.h index 0fdee9528617..473f11eebf7c 100644 --- a/drivers/staging/bcm/headers.h +++ b/drivers/staging/bcm/headers.h @@ -56,7 +56,6 @@ #include "CmHost.h" #include "DDRInit.h" #include "Debug.h" -#include "HostMibs.h" #include "IPv6ProtocolHdr.h" #include "PHSModule.h" #include "Protocol.h" diff --git a/drivers/staging/bcm/hostmibs.c b/drivers/staging/bcm/hostmibs.c index 0d75ff7add75..144590037b24 100644 --- a/drivers/staging/bcm/hostmibs.c +++ b/drivers/staging/bcm/hostmibs.c @@ -10,12 +10,8 @@ */ #include "headers.h" -INT ProcessGetHostMibs(PMINI_ADAPTER Adapter, - PVOID ioBuffer, - ULONG inputBufferLength) +INT ProcessGetHostMibs(PMINI_ADAPTER Adapter, S_MIBS_HOST_STATS_MIBS *pstHostMibs) { - - S_MIBS_HOST_STATS_MIBS *pstHostMibs = NULL; S_SERVICEFLOW_ENTRY *pstServiceFlowEntry = NULL; S_PHS_RULE *pstPhsRule = NULL; S_CLASSIFIER_TABLE *pstClassifierTable = NULL; @@ -30,15 +26,6 @@ INT ProcessGetHostMibs(PMINI_ADAPTER Adapter, return STATUS_FAILURE; } - if(ioBuffer == NULL) - { - return -EINVAL; - } - memset(ioBuffer,0,sizeof(S_MIBS_HOST_STATS_MIBS)); - - pstHostMibs = (S_MIBS_HOST_STATS_MIBS *)ioBuffer; - - //Copy the classifier Table for(nClassifierIndex=0; nClassifierIndex < MAX_CLASSIFIERS; nClassifierIndex++) @@ -115,13 +102,10 @@ INT ProcessGetHostMibs(PMINI_ADAPTER Adapter, } -INT GetDroppedAppCntrlPktMibs(PVOID ioBuffer, PPER_TARANG_DATA pTarang) +VOID GetDroppedAppCntrlPktMibs(S_MIBS_HOST_STATS_MIBS *pstHostMibs, const PPER_TARANG_DATA pTarang) { - S_MIBS_HOST_STATS_MIBS *pstHostMibs = (S_MIBS_HOST_STATS_MIBS *)ioBuffer; - - memcpy((PVOID)&(pstHostMibs->stDroppedAppCntrlMsgs),(PVOID)&(pTarang->stDroppedAppCntrlMsgs),sizeof(S_MIBS_DROPPED_APP_CNTRL_MESSAGES)); - - return STATUS_SUCCESS ; + memcpy(&(pstHostMibs->stDroppedAppCntrlMsgs), + &(pTarang->stDroppedAppCntrlMsgs),sizeof(S_MIBS_DROPPED_APP_CNTRL_MESSAGES)); } -- cgit v1.2.3 From 032100f65295d594fc0481e840efe8b6c1e398af Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Mon, 1 Nov 2010 10:03:29 -0400 Subject: beceem: remove unnecessary usb class Signed-off-by: Stephen Hemminger --- drivers/staging/bcm/Adapter.h | 2 +- drivers/staging/bcm/InterfaceInit.c | 63 +------------------------------------ 2 files changed, 2 insertions(+), 63 deletions(-) diff --git a/drivers/staging/bcm/Adapter.h b/drivers/staging/bcm/Adapter.h index 9f8954bfd5bd..69cac5c7f78f 100644 --- a/drivers/staging/bcm/Adapter.h +++ b/drivers/staging/bcm/Adapter.h @@ -553,7 +553,7 @@ struct _MINI_ADAPTER struct semaphore NVMRdmWrmLock; struct device *pstCreatedClassDevice; - BOOLEAN bUsbClassDriverRegistered; + // BOOLEAN InterfaceUpStatus; PFLASH2X_CS_INFO psFlash2xCSInfo; PFLASH_CS_INFO psFlashCSInfo ; diff --git a/drivers/staging/bcm/InterfaceInit.c b/drivers/staging/bcm/InterfaceInit.c index 801ba65e9785..6d62a50a2f48 100644 --- a/drivers/staging/bcm/InterfaceInit.c +++ b/drivers/staging/bcm/InterfaceInit.c @@ -63,29 +63,6 @@ VOID InterfaceAdapterFree(PS_INTERFACE_ADAPTER psIntfAdapter) AdapterFree(psIntfAdapter->psAdapter); } - - -static int usbbcm_open(struct inode *inode, struct file *file) -{ - return 0; -} - -static int usbbcm_release(struct inode *inode, struct file *file) -{ - return 0; -} - -static ssize_t usbbcm_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos) -{ - return 0; -} - -static ssize_t usbbcm_write(struct file *file, const char __user *user_buffer, size_t count, loff_t *ppos) -{ - return 0; -} - - VOID ConfigureEndPointTypesThroughEEPROM(PMINI_ADAPTER Adapter) { ULONG ulReg = 0; @@ -164,21 +141,6 @@ VOID ConfigureEndPointTypesThroughEEPROM(PMINI_ADAPTER Adapter) } -static struct file_operations usbbcm_fops = { - .open = usbbcm_open, - .release = usbbcm_release, - .read = usbbcm_read, - .write = usbbcm_write, - .owner = THIS_MODULE, - .llseek = no_llseek, -}; - -static struct usb_class_driver usbbcm_class = { - .name = "usbbcm", - .fops = &usbbcm_fops, - .minor_base = BCM_USB_MINOR_BASE, -}; - static int usbbcm_device_probe(struct usb_interface *intf, const struct usb_device_id *id) { @@ -259,8 +221,6 @@ usbbcm_device_probe(struct usb_interface *intf, const struct usb_device_id *id) usb_set_intfdata(intf, NULL); udev = interface_to_usbdev (intf); usb_put_dev(udev); - if(psAdapter->bUsbClassDriverRegistered == TRUE) - usb_deregister_dev (intf, &usbbcm_class); InterfaceAdapterFree(psIntfAdapter); return retval ; } @@ -339,10 +299,8 @@ static void usbbcm_disconnect (struct usb_interface *intf) InterfaceAdapterFree(psIntfAdapter); udev = interface_to_usbdev (intf); usb_put_dev(udev); - usb_deregister_dev (intf, &usbbcm_class); } - static int AllocUsbCb(PS_INTERFACE_ADAPTER psIntfAdapter) { int i = 0; @@ -701,18 +659,6 @@ INT InterfaceAdapterInit(PS_INTERFACE_ADAPTER psIntfAdapter) } } usb_set_intfdata(psIntfAdapter->interface, psIntfAdapter); - retval = usb_register_dev(psIntfAdapter->interface, &usbbcm_class); - if(retval) - { - BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0, "usb register dev failed = %d", retval); - psIntfAdapter->psAdapter->bUsbClassDriverRegistered = FALSE; - return retval; - } - else - { - psIntfAdapter->psAdapter->bUsbClassDriverRegistered = TRUE; - BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0, "usb dev registered"); - } psIntfAdapter->psAdapter->bcm_file_download = InterfaceFileDownload; psIntfAdapter->psAdapter->bcm_file_readback_from_chip = @@ -734,14 +680,7 @@ INT InterfaceAdapterInit(PS_INTERFACE_ADAPTER psIntfAdapter) } - retval = device_run(psIntfAdapter); - if(retval) - { - return retval; - } - - - return 0; + return device_run(psIntfAdapter); } static int InterfaceSuspend (struct usb_interface *intf, pm_message_t message) -- cgit v1.2.3 From 957ea3b57056e79c945d8bc39fd6eeb3c2a7ed9e Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Mon, 1 Nov 2010 10:05:34 -0400 Subject: beceem: remove problematic debug print messages Not worth bothering to change printf format of messages which are basically noise. Signed-off-by: Stephen Hemminger --- drivers/staging/bcm/CmHost.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/drivers/staging/bcm/CmHost.c b/drivers/staging/bcm/CmHost.c index d0bfdbbeee3f..c8d73d524852 100644 --- a/drivers/staging/bcm/CmHost.c +++ b/drivers/staging/bcm/CmHost.c @@ -1648,12 +1648,8 @@ static inline ULONG RestoreSFParam(PMINI_ADAPTER Adapter, ULONG ulAddrSFParamSet return 0; } ulAddrSFParamSet = ntohl(ulAddrSFParamSet); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, " RestoreSFParam: Total Words of DSX Message To Read: 0x%zx From Target At : 0x%lx ", - nBytesToRead/sizeof(ULONG),ulAddrSFParamSet); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "sizeof(stServiceFlowParamSI) = %zx", sizeof(stServiceFlowParamSI)); //Read out the SF Param Set At the indicated Location - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "nBytesToRead = %x", nBytesToRead); if(rdm(Adapter, ulAddrSFParamSet, (PUCHAR)pucDestBuffer, nBytesToRead) < 0) return STATUS_FAILURE; @@ -1670,9 +1666,6 @@ static ULONG StoreSFParam(PMINI_ADAPTER Adapter,PUCHAR pucSrcBuffer,ULONG ulAdd { return 0; } - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, " StoreSFParam: Total Words of DSX Message To Write: 0x%zX To Target At : 0x%lX ",(nBytesToWrite/sizeof(ULONG)),ulAddrSFParamSet); - - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "WRM with %x bytes",nBytesToWrite); uiRetVal = wrm(Adapter,ulAddrSFParamSet,(PUCHAR)pucSrcBuffer, nBytesToWrite); if(uiRetVal < 0) { -- cgit v1.2.3 From 5afb5145a13ac26f3c7ab273140a83958bc038f0 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Mon, 1 Nov 2010 10:07:20 -0400 Subject: beceem: remove useless debug function entry messages Signed-off-by: Stephen Hemminger --- drivers/staging/bcm/Bcmnet.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/staging/bcm/Bcmnet.c b/drivers/staging/bcm/Bcmnet.c index 5b466174a580..9e3b872621be 100644 --- a/drivers/staging/bcm/Bcmnet.c +++ b/drivers/staging/bcm/Bcmnet.c @@ -8,7 +8,6 @@ static INT bcm_open(struct net_device *dev) { PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(dev); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "======>"); if(Adapter->fw_download_done==FALSE) return -EINVAL; if(Adapter->LinkUpStatus == 1){ @@ -18,7 +17,6 @@ static INT bcm_open(struct net_device *dev) } } - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "<======"); return 0; } @@ -26,12 +24,10 @@ static INT bcm_close(struct net_device *dev) { PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(dev); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "=====>"); if(!netif_queue_stopped(dev)) { netif_carrier_off(dev); netif_stop_queue(dev); } - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL,"<====="); return 0; } -- cgit v1.2.3 From 46c3790eb523931a803bb3c28c5bf8bbfc8acf48 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Mon, 1 Nov 2010 10:16:29 -0400 Subject: beceem: convert to kernel coding style Change indentation etc, to conform to acceptable kernel style Signed-off-by: Stephen Hemminger --- drivers/staging/bcm/Bcmnet.c | 57 +++++++++++++++++++++----------------------- 1 file changed, 27 insertions(+), 30 deletions(-) diff --git a/drivers/staging/bcm/Bcmnet.c b/drivers/staging/bcm/Bcmnet.c index 9e3b872621be..3525f5cf5358 100644 --- a/drivers/staging/bcm/Bcmnet.c +++ b/drivers/staging/bcm/Bcmnet.c @@ -1,34 +1,31 @@ #include "headers.h" struct net_device *gblpnetdev; -/***************************************************************************************/ -/* proto-type of lower function */ static INT bcm_open(struct net_device *dev) { - PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(dev); + PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(dev); + + if (Adapter->fw_download_done == FALSE) + return -EINVAL; - if(Adapter->fw_download_done==FALSE) - return -EINVAL; - if(Adapter->LinkUpStatus == 1){ - if(netif_queue_stopped(Adapter->dev)){ + if (Adapter->LinkUpStatus == 1) { + if (netif_queue_stopped(Adapter->dev)) { netif_carrier_on(Adapter->dev); netif_start_queue(Adapter->dev); } } - return 0; + return 0; } static INT bcm_close(struct net_device *dev) { - PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(dev); - - if(!netif_queue_stopped(dev)) { + if (!netif_queue_stopped(dev)) { netif_carrier_off(dev); - netif_stop_queue(dev); + netif_stop_queue(dev); } - return 0; + return 0; } static struct net_device_stats *bcm_get_stats(struct net_device *dev) @@ -55,52 +52,52 @@ static u16 bcm_select_queue(struct net_device *dev, struct sk_buff *skb) return ClassifyPacket(netdev_priv(dev), skb); } - /******************************************************************* * Function - bcm_transmit() * * Description - This is the main transmit function for our virtual -* interface(eth0). It handles the ARP packets. It -* clones this packet and then Queue it to a suitable -* Queue. Then calls the transmit_packet(). +* interface(eth0). It handles the ARP packets. It +* clones this packet and then Queue it to a suitable +* Queue. Then calls the transmit_packet(). * * Parameter - skb - Pointer to the socket buffer structure -* dev - Pointer to the virtual net device structure +* dev - Pointer to the virtual net device structure * *********************************************************************/ static netdev_tx_t bcm_transmit(struct sk_buff *skb, struct net_device *dev) { - PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(dev); + PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(dev); u16 qindex = skb_get_queue_mapping(skb); if (Adapter->device_removed || !Adapter->LinkUpStatus) goto drop; - if (Adapter->TransferMode != IP_PACKET_ONLY_MODE ) + if (Adapter->TransferMode != IP_PACKET_ONLY_MODE) goto drop; - if (INVALID_QUEUE_INDEX==qindex) + if (INVALID_QUEUE_INDEX == qindex) goto drop; - if (Adapter->PackInfo[qindex].uiCurrentPacketsOnHost >= SF_MAX_ALLOWED_PACKETS_TO_BACKUP) + if (Adapter->PackInfo[qindex].uiCurrentPacketsOnHost >= + SF_MAX_ALLOWED_PACKETS_TO_BACKUP) return NETDEV_TX_BUSY; /* Now Enqueue the packet */ - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, - "bcm_transmit Enqueueing the Packet To Queue %d",qindex); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, + "bcm_transmit Enqueueing the Packet To Queue %d", + qindex); + spin_lock(&Adapter->PackInfo[qindex].SFQueueLock); Adapter->PackInfo[qindex].uiCurrentBytesOnHost += skb->len; Adapter->PackInfo[qindex].uiCurrentPacketsOnHost++; - *((B_UINT32 *)skb->cb + SKB_CB_LATENCY_OFFSET ) = jiffies; + *((B_UINT32 *) skb->cb + SKB_CB_LATENCY_OFFSET) = jiffies; ENQUEUEPACKET(Adapter->PackInfo[qindex].FirstTxQueue, Adapter->PackInfo[qindex].LastTxQueue, skb); atomic_inc(&Adapter->TotalPacketCount); spin_unlock(&Adapter->PackInfo[qindex].SFQueueLock); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_OSAL_DBG, DBG_LVL_ALL,"ENQ: \n"); - /* FIXME - this is racy and incorrect, replace with work queue */ if (!atomic_read(&Adapter->TxPktAvail)) { atomic_set(&Adapter->TxPktAvail, 1); @@ -182,12 +179,12 @@ int register_networkdev(PMINI_ADAPTER Adapter) struct net_device *net = Adapter->dev; int result; - net->netdev_ops = &bcmNetDevOps; + net->netdev_ops = &bcmNetDevOps; net->ethtool_ops = &bcm_ethtool_ops; - net->mtu = MTU_SIZE; /* 1400 Bytes */ + net->mtu = MTU_SIZE; /* 1400 Bytes */ net->tx_queue_len = TX_QLEN; net->flags |= IFF_NOARP; - net->flags &= ~(IFF_BROADCAST|IFF_MULTICAST); + net->flags &= ~(IFF_BROADCAST | IFF_MULTICAST); netif_carrier_off(net); -- cgit v1.2.3 From 9e0a3169a34ba5fd04bde058a63fa0a36f2d7ed3 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Mon, 1 Nov 2010 10:17:54 -0400 Subject: beceem: create class on module installation First step to supporting multiple devices, create device class when module is initialized. Signed-off-by: Stephen Hemminger --- drivers/staging/bcm/Bcmchar.c | 62 ++++++++++++------------------------- drivers/staging/bcm/InterfaceInit.c | 14 +++++---- 2 files changed, 28 insertions(+), 48 deletions(-) diff --git a/drivers/staging/bcm/Bcmchar.c b/drivers/staging/bcm/Bcmchar.c index 3a1b9903bf07..1a255609aeda 100644 --- a/drivers/staging/bcm/Bcmchar.c +++ b/drivers/staging/bcm/Bcmchar.c @@ -12,7 +12,7 @@ * * Returns - Zero(Success) ****************************************************************/ -static struct class *bcm_class = NULL; + static int bcm_char_open(struct inode *inode, struct file * filp) { PMINI_ADAPTER Adapter = NULL; @@ -2093,59 +2093,37 @@ static struct file_operations bcm_fops = { .llseek = no_llseek, }; +extern struct class *bcm_class; int register_control_device_interface(PMINI_ADAPTER Adapter) { + if(Adapter->major>0) - return Adapter->major; - Adapter->major = register_chrdev(0, "tarang", &bcm_fops); - if(Adapter->major < 0) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "register_chrdev:Failed to registering WiMax control char device!"); - return Adapter->major; - } - - bcm_class = NULL; - bcm_class = class_create (THIS_MODULE, "tarang"); - if(IS_ERR (bcm_class)) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Unable to create class\n"); - unregister_chrdev(Adapter->major, "tarang"); - Adapter->major = 0; - return -ENODEV; + return Adapter->major; + + Adapter->major = register_chrdev(0, DEV_NAME, &bcm_fops); + if(Adapter->major < 0) { + pr_err(DRV_NAME ": could not created character device\n"); + return Adapter->major; } + Adapter->pstCreatedClassDevice = device_create (bcm_class, NULL, - MKDEV(Adapter->major, 0), -#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,26) - NULL , -#endif - "tarang"); + MKDEV(Adapter->major, 0), Adapter, + DEV_NAME); - if(IS_ERR(Adapter->pstCreatedClassDevice)) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "class device did not get created : %ld", PTR_ERR(Adapter->pstCreatedClassDevice) ); + if(IS_ERR(Adapter->pstCreatedClassDevice)) { + pr_err(DRV_NAME ": class device create failed\n"); + unregister_chrdev(Adapter->major, DEV_NAME); + return PTR_ERR(Adapter->pstCreatedClassDevice); } - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Got Major No: %d", Adapter->major); - return 0; + + return 0; } void unregister_control_device_interface(PMINI_ADAPTER Adapter) { - if(Adapter->major > 0) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "destroying class device"); + if(Adapter->major > 0) { device_destroy (bcm_class, MKDEV(Adapter->major, 0)); + unregister_chrdev(Adapter->major, DEV_NAME); } - if(!IS_ERR(bcm_class)) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "destroying created class "); - class_destroy (bcm_class); - bcm_class = NULL; - } - if(Adapter->major > 0) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL,"unregistering character interface"); - unregister_chrdev(Adapter->major, "tarang"); - } - } diff --git a/drivers/staging/bcm/InterfaceInit.c b/drivers/staging/bcm/InterfaceInit.c index 6d62a50a2f48..161141d14565 100644 --- a/drivers/staging/bcm/InterfaceInit.c +++ b/drivers/staging/bcm/InterfaceInit.c @@ -738,6 +738,7 @@ static struct usb_driver usbbcm_driver = { .supports_autosuspend = 1, }; +struct class *bcm_class; /* Function: InterfaceInitialize @@ -755,16 +756,17 @@ Return: BCM_STATUS_SUCCESS - If Initialization of the */ INT InterfaceInitialize(void) { -// BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Registering Usb driver!!"); + bcm_class = class_create(THIS_MODULE, DRV_NAME); + if (IS_ERR(bcm_class)) { + printk(KERN_ERR DRV_NAME ": could not create class\n"); + return PTR_ERR(bcm_class); + } return usb_register(&usbbcm_driver); } INT InterfaceExit(void) { - //PMINI_ADAPTER psAdapter = NULL; - int status = 0; - - //BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Deregistering Usb driver!!"); + class_destroy (bcm_class); usb_deregister(&usbbcm_driver); - return status; + return 0; } -- cgit v1.2.3 From 3349d95b3f8c3becb9e6dbe0be978bf663174fef Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Mon, 1 Nov 2010 11:12:56 -0400 Subject: beceem: clean up adapter structure Remove dead fields, change fields that only have true/false to boolean; and rearrange to save space. Signed-off-by: Stephen Hemminger --- drivers/staging/bcm/Adapter.h | 54 ++++++++++++++++++++----------------------- 1 file changed, 25 insertions(+), 29 deletions(-) diff --git a/drivers/staging/bcm/Adapter.h b/drivers/staging/bcm/Adapter.h index 69cac5c7f78f..c2161036d5ac 100644 --- a/drivers/staging/bcm/Adapter.h +++ b/drivers/staging/bcm/Adapter.h @@ -384,17 +384,18 @@ struct _MINI_ADAPTER struct _MINI_ADAPTER *next; CHAR *caDsxReqResp; - atomic_t ApplicationRunning; + atomic_t ApplicationRunning; volatile INT CtrlQueueLen; - atomic_t AppCtrlQueueLen; - BOOLEAN AppCtrlQueueOverFlow; - atomic_t CurrentApplicationCount; - atomic_t RegisteredApplicationCount; - BOOLEAN TimerActive; - ULONG StatisticsPointer; + atomic_t AppCtrlQueueLen; + BOOLEAN AppCtrlQueueOverFlow; + atomic_t CurrentApplicationCount; + atomic_t RegisteredApplicationCount; + BOOLEAN LinkUpStatus; + BOOLEAN TimerActive; + u32 StatisticsPointer; struct sk_buff *RxControlHead; struct sk_buff *RxControlTail; -// spinlock_t RxControlQueuelock; + struct semaphore RxAppControlQueuelock; struct semaphore fw_download_sema; @@ -421,14 +422,14 @@ struct _MINI_ADAPTER atomic_t GoodTxByteCount; atomic_t TxTotalPacketCount; atomic_t TxDroppedPacketCount; - ULONG LinkUpStatus; - BOOLEAN TransferMode; + UINT u32TotalDSD; PacketInfo PackInfo[NO_OF_QUEUES]; S_CLASSIFIER_RULE astClassifierTable[MAX_CLASSIFIERS]; + BOOLEAN TransferMode; /*************** qos ******************/ - UINT bETHCSEnabled; + BOOLEAN bETHCSEnabled; ULONG BEBucketSize; ULONG rtPSBucketSize; @@ -444,8 +445,6 @@ struct _MINI_ADAPTER atomic_t process_waiting; BOOLEAN fw_download_done; - unsigned int ctrlpkt_present; - BOOLEAN packets_given_to_all; char *txctlpacket[MAX_CNTRL_PKTS]; atomic_t cntrlpktCnt ; atomic_t index_app_read_cntrlpkt; @@ -455,33 +454,30 @@ struct _MINI_ADAPTER struct semaphore rdmwrmsync; STTARGETDSXBUFFER astTargetDsxBuffer[MAX_TARGET_DSX_BUFFERS]; - ULONG ulFreeTargetBufferCnt; + ULONG ulFreeTargetBufferCnt; ULONG ulCurrentTargetBuffer; ULONG ulTotalTargetBuffersAvailable; - unsigned int timeout; - int irq; + unsigned long chip_id; - unsigned int bFlashBoot; -// spinlock_t sleeper_lock; - atomic_t rdm_wrm_access; - atomic_t tx_rx_access; + wait_queue_head_t lowpower_mode_wait_queue; - atomic_t bAbortedByHost; - BOOLEAN bBinDownloaded; - BOOLEAN bCfgDownloaded; - USHORT usBestEffortQueueIndex; - BOOLEAN bSyncUpRequestSent; -// struct semaphore data_packet_queue_lock; + + BOOLEAN bFlashBoot; + BOOLEAN bBinDownloaded; + BOOLEAN bCfgDownloaded; + BOOLEAN bSyncUpRequestSent; + USHORT usBestEffortQueueIndex; + wait_queue_head_t ioctl_fw_dnld_wait_queue; BOOLEAN waiting_to_fw_download_done; pid_t fw_download_process_pid; PSTARGETPARAMS pstargetparams; BOOLEAN device_removed; BOOLEAN DeviceAccess; - INT DDRSetting; + BOOLEAN bIsAutoCorrectEnabled; BOOLEAN bDDRInitDone; + INT DDRSetting; ULONG ulPowerSaveMode; - BOOLEAN bIsAutoCorrectEnabled; spinlock_t txtransmitlock; B_UINT8 txtransmit_running; /* Thread for control packet handling */ @@ -525,7 +521,7 @@ struct _MINI_ADAPTER S_HDR_SUPRESSION_CONTEXTINFO stPhsTxContextInfo; uint8_t ucaPHSPktRestoreBuf[2048]; uint8_t bPHSEnabled; - int AutoFirmDld; + BOOLEAN AutoFirmDld; BOOLEAN bMipsConfig; BOOLEAN bDPLLConfig; UINT32 aTxPktSizeHist[MIBS_MAX_HIST_ENTRIES]; -- cgit v1.2.3 From e39e3be66eed17f27a9de322e5220d33e70a90a6 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Mon, 1 Nov 2010 11:14:29 -0400 Subject: beceem: change format of debug message Statistic point is now u32 (like it has to be). Signed-off-by: Stephen Hemminger --- drivers/staging/bcm/Misc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/bcm/Misc.c b/drivers/staging/bcm/Misc.c index 0ada848fe1e1..11e78eccb2ee 100644 --- a/drivers/staging/bcm/Misc.c +++ b/drivers/staging/bcm/Misc.c @@ -574,8 +574,8 @@ VOID LinkMessage(PMINI_ADAPTER Adapter) VOID StatisticsResponse(PMINI_ADAPTER Adapter,PVOID pvBuffer) { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "%s====>",__FUNCTION__); - Adapter->StatisticsPointer = ntohl(*(PULONG)pvBuffer); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "Stats at %lx", Adapter->StatisticsPointer); + Adapter->StatisticsPointer = ntohl(*(__be32 *)pvBuffer); + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "Stats at %x", (UINT)Adapter->StatisticsPointer); BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "%s <====",__FUNCTION__); return; } -- cgit v1.2.3 From 4fd64dd0c1b9317ffe6fdaf3de788e14df880d8d Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Mon, 1 Nov 2010 12:12:31 -0400 Subject: beceem: add network device message level control Provide standard interface to control verbosity of debug messages Signed-off-by: Stephen Hemminger --- drivers/staging/bcm/Adapter.h | 3 +- drivers/staging/bcm/Bcmnet.c | 66 +++++++++++++++++++++++++++++-------- drivers/staging/bcm/CmHost.c | 4 ++- drivers/staging/bcm/InterfaceInit.c | 7 +--- drivers/staging/bcm/Misc.c | 18 +++++----- 5 files changed, 67 insertions(+), 31 deletions(-) diff --git a/drivers/staging/bcm/Adapter.h b/drivers/staging/bcm/Adapter.h index c2161036d5ac..e5aaec508bf9 100644 --- a/drivers/staging/bcm/Adapter.h +++ b/drivers/staging/bcm/Adapter.h @@ -382,6 +382,8 @@ Driver adapter data structure struct _MINI_ADAPTER { struct _MINI_ADAPTER *next; + struct net_device *dev; + u32 msg_enable; CHAR *caDsxReqResp; atomic_t ApplicationRunning; @@ -437,7 +439,6 @@ struct _MINI_ADAPTER BOOLEAN AutoLinkUp; BOOLEAN AutoSyncup; - struct net_device *dev; int major; int minor; wait_queue_head_t tx_packet_wait_queue; diff --git a/drivers/staging/bcm/Bcmnet.c b/drivers/staging/bcm/Bcmnet.c index 3525f5cf5358..641f3c88a2d9 100644 --- a/drivers/staging/bcm/Bcmnet.c +++ b/drivers/staging/bcm/Bcmnet.c @@ -1,19 +1,35 @@ #include "headers.h" +static int debug = -1; +module_param(debug, uint, 0600); +MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)"); + +static const u32 default_msg = + NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_LINK + | NETIF_MSG_TIMER | NETIF_MSG_TX_ERR | NETIF_MSG_RX_ERR + | NETIF_MSG_IFUP | NETIF_MSG_IFDOWN; + struct net_device *gblpnetdev; static INT bcm_open(struct net_device *dev) { PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(dev); - if (Adapter->fw_download_done == FALSE) - return -EINVAL; + if (Adapter->fw_download_done == FALSE) { + pr_notice(DRV_NAME "%s: link up failed (download in progress)\n", + dev->name); + return -EBUSY; + } + + if (netif_msg_ifup(Adapter)) + pr_info(DRV_NAME "%s: enabling interface\n", dev->name); + + if (Adapter->LinkUpStatus) { + if (netif_msg_link(Adapter)) + pr_info(DRV_NAME "%s: link up\n", dev->name); - if (Adapter->LinkUpStatus == 1) { - if (netif_queue_stopped(Adapter->dev)) { - netif_carrier_on(Adapter->dev); - netif_start_queue(Adapter->dev); - } + netif_carrier_on(Adapter->dev); + netif_start_queue(Adapter->dev); } return 0; @@ -21,10 +37,14 @@ static INT bcm_open(struct net_device *dev) static INT bcm_close(struct net_device *dev) { - if (!netif_queue_stopped(dev)) { - netif_carrier_off(dev); - netif_stop_queue(dev); - } + PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(dev); + + if (netif_msg_ifdown(Adapter)) + pr_info(DRV_NAME "%s: disabling interface\n", dev->name); + + netif_carrier_off(dev); + netif_stop_queue(dev); + return 0; } @@ -70,6 +90,7 @@ static netdev_tx_t bcm_transmit(struct sk_buff *skb, struct net_device *dev) PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(dev); u16 qindex = skb_get_queue_mapping(skb); + if (Adapter->device_removed || !Adapter->LinkUpStatus) goto drop; @@ -84,9 +105,9 @@ static netdev_tx_t bcm_transmit(struct sk_buff *skb, struct net_device *dev) return NETDEV_TX_BUSY; /* Now Enqueue the packet */ - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, - "bcm_transmit Enqueueing the Packet To Queue %d", - qindex); + if (netif_msg_tx_queued(Adapter)) + pr_info(DRV_NAME "%s: enqueueing packet to queue %d\n", + dev->name, qindex); spin_lock(&Adapter->PackInfo[qindex].SFQueueLock); Adapter->PackInfo[qindex].uiCurrentBytesOnHost += skb->len; @@ -168,10 +189,26 @@ static u32 bcm_get_link(struct net_device *dev) return Adapter->LinkUpStatus; } +static u32 bcm_get_msglevel (struct net_device *dev) +{ + PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(dev); + + return Adapter->msg_enable; +} + +static void bcm_set_msglevel (struct net_device *dev, u32 level) +{ + PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(dev); + + Adapter->msg_enable = level; +} + static const struct ethtool_ops bcm_ethtool_ops = { .get_settings = bcm_get_settings, .get_drvinfo = bcm_get_drvinfo, .get_link = bcm_get_link, + .get_msglevel = bcm_get_msglevel, + .set_msglevel = bcm_set_msglevel, }; int register_networkdev(PMINI_ADAPTER Adapter) @@ -185,6 +222,7 @@ int register_networkdev(PMINI_ADAPTER Adapter) net->tx_queue_len = TX_QLEN; net->flags |= IFF_NOARP; net->flags &= ~(IFF_BROADCAST | IFF_MULTICAST); + Adapter->msg_enable = netif_msg_init(debug, default_msg); netif_carrier_off(net); diff --git a/drivers/staging/bcm/CmHost.c b/drivers/staging/bcm/CmHost.c index c8d73d524852..e19f7936d6f0 100644 --- a/drivers/staging/bcm/CmHost.c +++ b/drivers/staging/bcm/CmHost.c @@ -2135,8 +2135,10 @@ BOOLEAN CmControlResponseMessage(PMINI_ADAPTER Adapter, /**LinkUpStatus) { netif_carrier_on(Adapter->dev); - netif_start_queue(Adapter->dev); + netif_start_queue(Adapter->dev); Adapter->LinkUpStatus = 1; + if (netif_msg_link(Adapter)) + pr_info(DRV_NAME "%s: link up\n", Adapter->dev->name); do_gettimeofday(&tv); atomic_set(&Adapter->TxPktAvail, 1); diff --git a/drivers/staging/bcm/InterfaceInit.c b/drivers/staging/bcm/InterfaceInit.c index 161141d14565..3529ea517dab 100644 --- a/drivers/staging/bcm/InterfaceInit.c +++ b/drivers/staging/bcm/InterfaceInit.c @@ -11,11 +11,6 @@ static struct usb_device_id InterfaceUsbtable[] = { }; MODULE_DEVICE_TABLE(usb, InterfaceUsbtable); -static unsigned int debug_level = DBG_LVL_CURR; -module_param(debug_level, uint, 0644); -MODULE_PARM_DESC(debug_level, "Debug level (0=none,...,7=all)"); - - VOID InterfaceAdapterFree(PS_INTERFACE_ADAPTER psIntfAdapter) { INT i = 0; @@ -164,7 +159,7 @@ usbbcm_device_probe(struct usb_interface *intf, const struct usb_device_id *id) /* Init default driver debug state */ - psAdapter->stDebugState.debug_level = debug_level; + psAdapter->stDebugState.debug_level = DBG_LVL_CURR; psAdapter->stDebugState.type = DBG_TYPE_INITEXIT; /* Technically, one can start using BCM_DEBUG_PRINT after this point. diff --git a/drivers/staging/bcm/Misc.c b/drivers/staging/bcm/Misc.c index 11e78eccb2ee..1b29744e4cab 100644 --- a/drivers/staging/bcm/Misc.c +++ b/drivers/staging/bcm/Misc.c @@ -1913,13 +1913,13 @@ void flush_queue(PMINI_ADAPTER Adapter, UINT iQIndex) void beceem_protocol_reset (PMINI_ADAPTER Adapter) { - int i =0; + int i; - if(NULL != Adapter->dev) - { - netif_carrier_off(Adapter->dev); - netif_stop_queue(Adapter->dev); - } + if (netif_msg_link(Adapter)) + pr_notice(DRV_NAME "%s: protocol reset\n", Adapter->dev->name); + + netif_carrier_off(Adapter->dev); + netif_stop_queue(Adapter->dev); Adapter->IdleMode = FALSE; Adapter->LinkUpStatus = FALSE; @@ -1937,14 +1937,14 @@ void beceem_protocol_reset (PMINI_ADAPTER Adapter) Adapter->TimerActive = FALSE; memset(Adapter->astFragmentedPktClassifierTable, 0, - sizeof(S_FRAGMENTED_PACKET_INFO) * - MAX_FRAGMENTEDIP_CLASSIFICATION_ENTRIES); + sizeof(S_FRAGMENTED_PACKET_INFO) * MAX_FRAGMENTEDIP_CLASSIFICATION_ENTRIES); for(i = 0;iPackInfo[i],0,sizeof(S_MIBS_SERVICEFLOW_TABLE)); + memset(&Adapter->PackInfo[i].stMibsExtServiceFlowTable, + 0, sizeof(S_MIBS_EXTSERVICEFLOW_PARAMETERS)); } } -- cgit v1.2.3 From 2d08748ae53bf07fe6fcaf4f3d40449b471ce351 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Mon, 1 Nov 2010 12:14:01 -0400 Subject: beceem: module initialization Get rid of boot messages and put in correct place. Signed-off-by: Stephen Hemminger --- drivers/staging/bcm/Bcmnet.c | 22 -------- drivers/staging/bcm/InterfaceInit.c | 105 ++++++++++++++---------------------- drivers/staging/bcm/InterfaceMisc.c | 14 +---- drivers/staging/bcm/Misc.c | 86 ++++++++++++----------------- drivers/staging/bcm/Prototypes.h | 2 - 5 files changed, 75 insertions(+), 154 deletions(-) diff --git a/drivers/staging/bcm/Bcmnet.c b/drivers/staging/bcm/Bcmnet.c index 641f3c88a2d9..bf3a04dca234 100644 --- a/drivers/staging/bcm/Bcmnet.c +++ b/drivers/staging/bcm/Bcmnet.c @@ -241,25 +241,3 @@ int register_networkdev(PMINI_ADAPTER Adapter) return result; } - -static int bcm_init(void) -{ - printk(KERN_INFO "%s, %s\n", DRV_DESCRIPTION, DRV_VERSION); - printk(KERN_INFO "%s\n", DRV_COPYRIGHT); - - return InterfaceInitialize(); -} - - -static void bcm_exit(void) -{ - InterfaceExit(); -} - -module_init(bcm_init); -module_exit(bcm_exit); - -MODULE_DESCRIPTION(DRV_DESCRIPTION); -MODULE_VERSION(DRV_VERSION); -MODULE_LICENSE ("GPL"); - diff --git a/drivers/staging/bcm/InterfaceInit.c b/drivers/staging/bcm/InterfaceInit.c index 3529ea517dab..43e5c9cea717 100644 --- a/drivers/staging/bcm/InterfaceInit.c +++ b/drivers/staging/bcm/InterfaceInit.c @@ -338,13 +338,11 @@ static int device_run(PS_INTERFACE_ADAPTER psIntfAdapter) status = InitCardAndDownloadFirmware(psIntfAdapter->psAdapter); if(status != STATUS_SUCCESS) { - BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0, "InitCardAndDownloadFirmware failed.\n"); + pr_err(DRV_NAME "InitCardAndDownloadFirmware failed.\n"); return status; } if(TRUE == psIntfAdapter->psAdapter->fw_download_done) { - - BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Sending first interrupt URB down......"); if(StartInterruptUrb(psIntfAdapter)) { BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Cannot send interrupt in URB"); @@ -357,16 +355,11 @@ static int device_run(PS_INTERFACE_ADAPTER psIntfAdapter) psIntfAdapter->psAdapter->waiting_to_fw_download_done, 5*HZ); if(value == 0) - { - BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL,"Mailbox Interrupt has not reached to Driver.."); - } - else - { - BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL,"Got the mailbox interrupt ...Registering control interface...\n "); - } + pr_err(DRV_NAME ": Mailbox Interrupt has not reached to Driver..\n"); + if(register_control_device_interface(psIntfAdapter->psAdapter) < 0) { - BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0, "Register Control Device failed..."); + pr_err(DRV_NAME ": Register Control Device failed...\n"); return -EIO; } } @@ -460,20 +453,9 @@ INT InterfaceAdapterInit(PS_INTERFACE_ADAPTER psIntfAdapter) UINT uiData = 0; /* Store the usb dev into interface adapter */ - psIntfAdapter->udev = usb_get_dev(interface_to_usbdev( - psIntfAdapter->interface)); - - if((psIntfAdapter->udev->speed == USB_SPEED_HIGH)) - { - psIntfAdapter->bHighSpeedDevice = TRUE ; - BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "MODEM IS CONFIGURED TO HIGH_SPEED "); - } - else - { - psIntfAdapter->bHighSpeedDevice = FALSE ; - BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "MODEM IS CONFIGURED TO FULL_SPEED "); - } + psIntfAdapter->udev = usb_get_dev(interface_to_usbdev(psIntfAdapter->interface)); + psIntfAdapter->bHighSpeedDevice = (psIntfAdapter->udev->speed == USB_SPEED_HIGH); psIntfAdapter->psAdapter->interface_rdm = BcmRDM; psIntfAdapter->psAdapter->interface_wrm = BcmWRM; @@ -482,28 +464,27 @@ INT InterfaceAdapterInit(PS_INTERFACE_ADAPTER psIntfAdapter) BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0, "CHIP ID Read Failed\n"); return STATUS_FAILURE; } - if(0xbece3200==(psIntfAdapter->psAdapter->chip_id&~(0xF0))) - { - psIntfAdapter->psAdapter->chip_id=(psIntfAdapter->psAdapter->chip_id&~(0xF0)); - } - BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "First RDM Chip ID 0x%lx\n", psIntfAdapter->psAdapter->chip_id); + if(0xbece3200==(psIntfAdapter->psAdapter->chip_id&~(0xF0))) + psIntfAdapter->psAdapter->chip_id &= ~0xF0; - iface_desc = psIntfAdapter->interface->cur_altsetting; - //print_usb_interface_desc(&(iface_desc->desc)); + dev_info(&psIntfAdapter->udev->dev, "RDM Chip ID 0x%lx\n", + psIntfAdapter->psAdapter->chip_id); + + iface_desc = psIntfAdapter->interface->cur_altsetting; if(psIntfAdapter->psAdapter->chip_id == T3B) { - // //T3B device will have EEPROM,check if EEPROM is proper and BCM16 can be done or not. // BeceemEEPROMBulkRead(psIntfAdapter->psAdapter,&uiData,0x0,4); if(uiData == BECM) - { bBcm16 = TRUE; - } - BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Number of Altsetting aviailable for This Modem 0x%x\n", psIntfAdapter->interface->num_altsetting); + + dev_info(&psIntfAdapter->udev->dev, "number of alternate setting %d\n", + psIntfAdapter->interface->num_altsetting); + if(bBcm16 == TRUE) { //selecting alternate setting one as a default setting for High Speed modem. @@ -574,12 +555,10 @@ INT InterfaceAdapterInit(PS_INTERFACE_ADAPTER psIntfAdapter) } iface_desc = psIntfAdapter->interface->cur_altsetting; - //print_usb_interface_desc(&(iface_desc->desc)); - BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0, "Current number of endpoints :%x \n", iface_desc->desc.bNumEndpoints); - for (value = 0; value < iface_desc->desc.bNumEndpoints; ++value) + + for (value = 0; value < iface_desc->desc.bNumEndpoints; ++value) { - endpoint = &iface_desc->endpoint[value].desc; - //print_usb_endpoint_descriptor(endpoint); + endpoint = &iface_desc->endpoint[value].desc; if (!psIntfAdapter->sBulkIn.bulk_in_endpointAddr && bcm_usb_endpoint_is_bulk_in(endpoint)) { @@ -612,10 +591,10 @@ INT InterfaceAdapterInit(PS_INTERFACE_ADAPTER psIntfAdapter) psIntfAdapter->sIntrIn.int_in_buffer = kmalloc(buffer_size, GFP_KERNEL); if (!psIntfAdapter->sIntrIn.int_in_buffer) { - BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Could not allocate interrupt_in_buffer"); + dev_err(&psIntfAdapter->udev->dev, + "could not allocate interrupt_in_buffer\n"); return -EINVAL; } - //psIntfAdapter->sIntrIn.int_in_pipe = } if (!psIntfAdapter->sIntrOut.int_out_endpointAddr && bcm_usb_endpoint_is_int_out(endpoint)) @@ -646,10 +625,11 @@ INT InterfaceAdapterInit(PS_INTERFACE_ADAPTER psIntfAdapter) psIntfAdapter->sIntrOut.int_out_buffer= kmalloc(buffer_size, GFP_KERNEL); if (!psIntfAdapter->sIntrOut.int_out_buffer) - { - BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Could not allocate interrupt_out_buffer"); - return -EINVAL; - } + { + dev_err(&psIntfAdapter->udev->dev, + "could not allocate interrupt_out_buffer\n"); + return -EINVAL; + } } } } @@ -681,8 +661,7 @@ INT InterfaceAdapterInit(PS_INTERFACE_ADAPTER psIntfAdapter) static int InterfaceSuspend (struct usb_interface *intf, pm_message_t message) { PS_INTERFACE_ADAPTER psIntfAdapter = usb_get_intfdata(intf); - BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "=================================\n"); - //Bcm_kill_all_URBs(psIntfAdapter); + psIntfAdapter->bSuspended = TRUE; if(TRUE == psIntfAdapter->bPreparingForBusSuspend) @@ -735,33 +714,31 @@ static struct usb_driver usbbcm_driver = { struct class *bcm_class; -/* -Function: InterfaceInitialize -Description: This is the hardware specific initialization Function. - Registering the driver with NDIS , other device specific NDIS - and hardware initializations are done here. - -Input parameters: IN PMINI_ADAPTER Adapter - Miniport Adapter Context - - -Return: BCM_STATUS_SUCCESS - If Initialization of the - HW Interface was successful. - Other - If an error occured. -*/ -INT InterfaceInitialize(void) +static __init int bcm_init(void) { + printk(KERN_INFO "%s: %s, %s\n", DRV_NAME, DRV_DESCRIPTION, DRV_VERSION); + printk(KERN_INFO "%s\n", DRV_COPYRIGHT); + bcm_class = class_create(THIS_MODULE, DRV_NAME); if (IS_ERR(bcm_class)) { printk(KERN_ERR DRV_NAME ": could not create class\n"); return PTR_ERR(bcm_class); } + return usb_register(&usbbcm_driver); } -INT InterfaceExit(void) +static __exit void bcm_exit(void) { class_destroy (bcm_class); + usb_deregister(&usbbcm_driver); - return 0; } + +module_init(bcm_init); +module_exit(bcm_exit); + +MODULE_DESCRIPTION(DRV_DESCRIPTION); +MODULE_VERSION(DRV_VERSION); +MODULE_LICENSE ("GPL"); diff --git a/drivers/staging/bcm/InterfaceMisc.c b/drivers/staging/bcm/InterfaceMisc.c index 6ee5dbb6154a..b7d6e7a414a9 100644 --- a/drivers/staging/bcm/InterfaceMisc.c +++ b/drivers/staging/bcm/InterfaceMisc.c @@ -224,9 +224,7 @@ VOID Bcm_kill_all_URBs(PS_INTERFACE_ADAPTER psIntfAdapter) } /* Cancel All submitted TX URB's */ - BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0, "Cancelling All Submitted TX Urbs \n"); - - for(i = 0; i < MAXIMUM_USB_TCB; i++) + for(i = 0; i < MAXIMUM_USB_TCB; i++) { tempUrb = psIntfAdapter->asUsbTcb[i].urb; if(tempUrb) @@ -236,9 +234,6 @@ VOID Bcm_kill_all_URBs(PS_INTERFACE_ADAPTER psIntfAdapter) } } - - BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0, "Cancelling All submitted Rx Urbs \n"); - for(i = 0; i < MAXIMUM_USB_RCB; i++) { tempUrb = psIntfAdapter->asUsbRcb[i].urb; @@ -249,16 +244,11 @@ VOID Bcm_kill_all_URBs(PS_INTERFACE_ADAPTER psIntfAdapter) } } - atomic_set(&psIntfAdapter->uNumTcbUsed, 0); atomic_set(&psIntfAdapter->uCurrTcb, 0); atomic_set(&psIntfAdapter->uNumRcbUsed, 0); atomic_set(&psIntfAdapter->uCurrRcb, 0); - - BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0, "TCB: used- %d cur-%d\n", atomic_read(&psIntfAdapter->uNumTcbUsed), atomic_read(&psIntfAdapter->uCurrTcb)); - BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0, "RCB: used- %d cur-%d\n", atomic_read(&psIntfAdapter->uNumRcbUsed), atomic_read(&psIntfAdapter->uCurrRcb)); - } VOID putUsbSuspend(struct work_struct *work) @@ -270,8 +260,6 @@ VOID putUsbSuspend(struct work_struct *work) if(psIntfAdapter->bSuspended == FALSE) usb_autopm_put_interface(intf); - else - BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Interface Resumed Completely\n"); } diff --git a/drivers/staging/bcm/Misc.c b/drivers/staging/bcm/Misc.c index 1b29744e4cab..7f3a936529c5 100644 --- a/drivers/staging/bcm/Misc.c +++ b/drivers/staging/bcm/Misc.c @@ -152,34 +152,30 @@ VOID AdapterFree(PMINI_ADAPTER Adapter) free_netdev(Adapter->dev); } - -int create_worker_threads(PMINI_ADAPTER psAdapter) +static int create_worker_threads(PMINI_ADAPTER psAdapter) { - const char *name = psAdapter->dev->name; - - BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Init Threads..."); // Rx Control Packets Processing psAdapter->control_packet_handler = kthread_run((int (*)(void *)) - control_packet_handler, psAdapter, "%s-rx", name); + control_packet_handler, psAdapter, "%s-rx", DRV_NAME); if(IS_ERR(psAdapter->control_packet_handler)) { - BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "No Kernel Thread, but still returning success\n"); + pr_notice(DRV_NAME ": could not create control thread\n"); return PTR_ERR(psAdapter->control_packet_handler); } + // Tx Thread psAdapter->transmit_packet_thread = kthread_run((int (*)(void *)) - tx_pkt_handler, psAdapter, "%s-tx", name); + tx_pkt_handler, psAdapter, "%s-tx", DRV_NAME); if(IS_ERR (psAdapter->transmit_packet_thread)) { - BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "No Kernel Thread, but still returning success"); + pr_notice(DRV_NAME ": could not creat transmit thread\n"); kthread_stop(psAdapter->control_packet_handler); return PTR_ERR(psAdapter->transmit_packet_thread); } return 0; } - -static inline struct file *open_firmware_file(PMINI_ADAPTER Adapter, char *path) +static struct file *open_firmware_file(PMINI_ADAPTER Adapter, char *path) { struct file *flp=NULL; mm_segment_t oldfs; @@ -189,19 +185,13 @@ static inline struct file *open_firmware_file(PMINI_ADAPTER Adapter, char *path) set_fs(oldfs); if(IS_ERR(flp)) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Unable To Open File %s, err %lx", - path, PTR_ERR(flp)); - flp = NULL; - } - else - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Got file descriptor pointer of %s!", - path); + pr_err(DRV_NAME "Unable To Open File %s, err %ld", + path, PTR_ERR(flp)); + flp = NULL; } - if(Adapter->device_removed) - { - flp = NULL; - } + + if(Adapter->device_removed) + flp = NULL; return flp; } @@ -254,9 +244,7 @@ exit_download: if(flp && !(IS_ERR(flp))) filp_close(flp, current->files); set_fs(oldfs); - do_gettimeofday(&tv); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "file download done at %lx", ((tv.tv_sec * 1000) + - (tv.tv_usec/1000))); + return errorno; } @@ -1104,11 +1092,10 @@ int InitCardAndDownloadFirmware(PMINI_ADAPTER ps_adapter) * Firm/DDR Settings.. */ - if((status = create_worker_threads(ps_adapter))<0) - { - BCM_DEBUG_PRINT(ps_adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Cannot create thread"); + status = create_worker_threads(ps_adapter); + if (status<0) return status; - } + /* * For Downloading the Firm, parse the cfg file first. */ @@ -1134,7 +1121,7 @@ int InitCardAndDownloadFirmware(PMINI_ADAPTER ps_adapter) status = ddr_init(ps_adapter); if(status) { - BCM_DEBUG_PRINT (ps_adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "ddr_init Failed\n"); + pr_err(DRV_NAME "ddr_init Failed\n"); return status; } @@ -1148,7 +1135,6 @@ int InitCardAndDownloadFirmware(PMINI_ADAPTER ps_adapter) BCM_DEBUG_PRINT(ps_adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Error downloading CFG file"); goto OUT; } - BCM_DEBUG_PRINT(ps_adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "CFG file downloaded"); if(register_networkdev(ps_adapter)) { @@ -1221,7 +1207,6 @@ int InitCardAndDownloadFirmware(PMINI_ADAPTER ps_adapter) goto OUT; } - BCM_DEBUG_PRINT(ps_adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "BIN file downloaded"); status = run_card_proc(ps_adapter); if(status) { @@ -1302,22 +1287,23 @@ void beceem_parse_target_struct(PMINI_ADAPTER Adapter) if(ntohl(Adapter->pstargetparams->m_u32PhyParameter2) & AUTO_SYNC_DISABLE) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "AutoSyncup is Disabled\n"); + pr_info(DRV_NAME ": AutoSyncup is Disabled\n"); Adapter->AutoSyncup = FALSE; } else { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "AutoSyncup is Enabled\n"); + pr_info(DRV_NAME ": AutoSyncup is Enabled\n"); Adapter->AutoSyncup = TRUE; } + if(ntohl(Adapter->pstargetparams->HostDrvrConfig6) & AUTO_LINKUP_ENABLE) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Enabling autolink up"); + pr_info(DRV_NAME ": Enabling autolink up"); Adapter->AutoLinkUp = TRUE; } else { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Disabling autolink up"); + pr_info(DRV_NAME ": Disabling autolink up"); Adapter->AutoLinkUp = FALSE; } // Setting the DDR Setting.. @@ -1326,51 +1312,46 @@ void beceem_parse_target_struct(PMINI_ADAPTER Adapter) Adapter->ulPowerSaveMode = (ntohl(Adapter->pstargetparams->HostDrvrConfig6)>>12)&0x0F; - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "DDR Setting: %x\n", Adapter->DDRSetting); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT,DBG_LVL_ALL, "Power Save Mode: %lx\n", - Adapter->ulPowerSaveMode); + pr_info(DRV_NAME ": DDR Setting: %x\n", Adapter->DDRSetting); + pr_info(DRV_NAME ": Power Save Mode: %lx\n", Adapter->ulPowerSaveMode); if(ntohl(Adapter->pstargetparams->HostDrvrConfig6) & AUTO_FIRM_DOWNLOAD) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Enabling Auto Firmware Download\n"); + pr_info(DRV_NAME ": Enabling Auto Firmware Download\n"); Adapter->AutoFirmDld = TRUE; } else { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Disabling Auto Firmware Download\n"); + pr_info(DRV_NAME ": Disabling Auto Firmware Download\n"); Adapter->AutoFirmDld = FALSE; } uiHostDrvrCfg6 = ntohl(Adapter->pstargetparams->HostDrvrConfig6); Adapter->bMipsConfig = (uiHostDrvrCfg6>>20)&0x01; - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL,"MIPSConfig : 0x%X\n",Adapter->bMipsConfig); + pr_info(DRV_NAME ": MIPSConfig : 0x%X\n",Adapter->bMipsConfig); //used for backward compatibility. Adapter->bDPLLConfig = (uiHostDrvrCfg6>>19)&0x01; Adapter->PmuMode= (uiHostDrvrCfg6 >> 24 ) & 0x03; - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "PMU MODE: %x", Adapter->PmuMode); + pr_info(DRV_NAME ": PMU MODE: %x", Adapter->PmuMode); if((uiHostDrvrCfg6 >> HOST_BUS_SUSPEND_BIT ) & (0x01)) { Adapter->bDoSuspend = TRUE; - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Making DoSuspend TRUE as per configFile"); + pr_info(DRV_NAME ": Making DoSuspend TRUE as per configFile"); } uiEEPROMFlag = ntohl(Adapter->pstargetparams->m_u32EEPROMFlag); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "uiEEPROMFlag : 0x%X\n",uiEEPROMFlag); + pr_info(DRV_NAME ": uiEEPROMFlag : 0x%X\n",uiEEPROMFlag); Adapter->eNVMType = (NVM_TYPE)((uiEEPROMFlag>>4)&0x3); - Adapter->bStatusWrite = (uiEEPROMFlag>>6)&0x1; - //printk(("bStatusWrite : 0x%X\n", Adapter->bStatusWrite)); Adapter->uiSectorSizeInCFG = 1024*(0xFFFF & ntohl(Adapter->pstargetparams->HostDrvrConfig4)); - //printk(("uiSectorSize : 0x%X\n", Adapter->uiSectorSizeInCFG)); Adapter->bSectorSizeOverride =(bool) ((ntohl(Adapter->pstargetparams->HostDrvrConfig4))>>16)&0x1; - //printk(MP_INIT,("bSectorSizeOverride : 0x%X\n",Adapter->bSectorSizeOverride)); if(ntohl(Adapter->pstargetparams->m_u32PowerSavingModeOptions) &0x01) Adapter->ulPowerSaveMode = DEVICE_POWERSAVE_MODE_AS_PROTOCOL_IDLE_MODE; - //autocorrection part + if(Adapter->ulPowerSaveMode != DEVICE_POWERSAVE_MODE_AS_PROTOCOL_IDLE_MODE) doPowerAutoCorrection(Adapter); @@ -1378,7 +1359,7 @@ void beceem_parse_target_struct(PMINI_ADAPTER Adapter) VOID doPowerAutoCorrection(PMINI_ADAPTER psAdapter) { - UINT reporting_mode = 0; + UINT reporting_mode; reporting_mode = ntohl(psAdapter->pstargetparams->m_u32PowerSavingModeOptions) &0x02 ; psAdapter->bIsAutoCorrectEnabled = !((char)(psAdapter->ulPowerSaveMode >> 3) & 0x1); @@ -1395,7 +1376,6 @@ VOID doPowerAutoCorrection(PMINI_ADAPTER psAdapter) { psAdapter->ulPowerSaveMode = DEVICE_POWERSAVE_MODE_AS_PMU_CLOCK_GATING; psAdapter->bDoSuspend =FALSE; - BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL,"PMC selected.."); } diff --git a/drivers/staging/bcm/Prototypes.h b/drivers/staging/bcm/Prototypes.h index c9e1d61efe5f..920e9882ccd1 100644 --- a/drivers/staging/bcm/Prototypes.h +++ b/drivers/staging/bcm/Prototypes.h @@ -74,8 +74,6 @@ VOID AdapterFree(PMINI_ADAPTER Adapter); INT FreeAdapterDsxBuffer(PMINI_ADAPTER Adapter); -int create_worker_threads(PMINI_ADAPTER psAdapter); - int tx_pkt_handler(PMINI_ADAPTER Adapter); int reset_card_proc(PMINI_ADAPTER Adapter ); -- cgit v1.2.3 From e4d46254da76106e48b7cadc59fb410291e2da4b Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Mon, 1 Nov 2010 11:39:05 -0400 Subject: beceem: use get_seconds for elapsed time get_seconds is lower overhead and fine if all driver wants to do is keep track of seconds. Signed-off-by: Stephen Hemminger --- drivers/staging/bcm/CmHost.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/staging/bcm/CmHost.c b/drivers/staging/bcm/CmHost.c index e19f7936d6f0..949aaa3b3191 100644 --- a/drivers/staging/bcm/CmHost.c +++ b/drivers/staging/bcm/CmHost.c @@ -2053,7 +2053,7 @@ BOOLEAN CmControlResponseMessage(PMINI_ADAPTER Adapter, /**u16VCID)); uiSearchRuleIndex=SearchFreeSfid(Adapter); @@ -2139,12 +2139,9 @@ BOOLEAN CmControlResponseMessage(PMINI_ADAPTER Adapter, /**LinkUpStatus = 1; if (netif_msg_link(Adapter)) pr_info(DRV_NAME "%s: link up\n", Adapter->dev->name); - do_gettimeofday(&tv); - atomic_set(&Adapter->TxPktAvail, 1); wake_up(&Adapter->tx_packet_wait_queue); - Adapter->liTimeSinceLastNetEntry = tv.tv_sec; - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "============Tx Service Flow Created!"); + Adapter->liTimeSinceLastNetEntry = get_seconds(); } } } -- cgit v1.2.3 From 9ec4475bf10bb2c30cd5e927bc453aa307f58123 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Mon, 1 Nov 2010 12:18:36 -0400 Subject: beceem: debug message format changes Add more debug messages and make them similar to other drivers Signed-off-by: Stephen Hemminger --- drivers/staging/bcm/Bcmnet.c | 12 ++++++------ drivers/staging/bcm/CmHost.c | 2 +- drivers/staging/bcm/InterfaceIsr.c | 4 ++++ drivers/staging/bcm/InterfaceRx.c | 9 ++++++--- drivers/staging/bcm/InterfaceTx.c | 4 ++++ drivers/staging/bcm/Misc.c | 2 +- drivers/staging/bcm/Qos.c | 7 +++++-- 7 files changed, 27 insertions(+), 13 deletions(-) diff --git a/drivers/staging/bcm/Bcmnet.c b/drivers/staging/bcm/Bcmnet.c index bf3a04dca234..fbaf73a2e42c 100644 --- a/drivers/staging/bcm/Bcmnet.c +++ b/drivers/staging/bcm/Bcmnet.c @@ -16,17 +16,17 @@ static INT bcm_open(struct net_device *dev) PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(dev); if (Adapter->fw_download_done == FALSE) { - pr_notice(DRV_NAME "%s: link up failed (download in progress)\n", - dev->name); + pr_notice(PFX "%s: link up failed (download in progress)\n", + dev->name); return -EBUSY; } if (netif_msg_ifup(Adapter)) - pr_info(DRV_NAME "%s: enabling interface\n", dev->name); + pr_info(PFX "%s: enabling interface\n", dev->name); if (Adapter->LinkUpStatus) { if (netif_msg_link(Adapter)) - pr_info(DRV_NAME "%s: link up\n", dev->name); + pr_info(PFX "%s: link up\n", dev->name); netif_carrier_on(Adapter->dev); netif_start_queue(Adapter->dev); @@ -40,7 +40,7 @@ static INT bcm_close(struct net_device *dev) PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(dev); if (netif_msg_ifdown(Adapter)) - pr_info(DRV_NAME "%s: disabling interface\n", dev->name); + pr_info(PFX "%s: disabling interface\n", dev->name); netif_carrier_off(dev); netif_stop_queue(dev); @@ -106,7 +106,7 @@ static netdev_tx_t bcm_transmit(struct sk_buff *skb, struct net_device *dev) /* Now Enqueue the packet */ if (netif_msg_tx_queued(Adapter)) - pr_info(DRV_NAME "%s: enqueueing packet to queue %d\n", + pr_info(PFX "%s: enqueueing packet to queue %d\n", dev->name, qindex); spin_lock(&Adapter->PackInfo[qindex].SFQueueLock); diff --git a/drivers/staging/bcm/CmHost.c b/drivers/staging/bcm/CmHost.c index 949aaa3b3191..1aa962fedb91 100644 --- a/drivers/staging/bcm/CmHost.c +++ b/drivers/staging/bcm/CmHost.c @@ -2138,7 +2138,7 @@ BOOLEAN CmControlResponseMessage(PMINI_ADAPTER Adapter, /**dev); Adapter->LinkUpStatus = 1; if (netif_msg_link(Adapter)) - pr_info(DRV_NAME "%s: link up\n", Adapter->dev->name); + pr_info(PFX "%s: link up\n", Adapter->dev->name); atomic_set(&Adapter->TxPktAvail, 1); wake_up(&Adapter->tx_packet_wait_queue); Adapter->liTimeSinceLastNetEntry = get_seconds(); diff --git a/drivers/staging/bcm/InterfaceIsr.c b/drivers/staging/bcm/InterfaceIsr.c index c1f8e7aa05f7..2d26e2ed38d9 100644 --- a/drivers/staging/bcm/InterfaceIsr.c +++ b/drivers/staging/bcm/InterfaceIsr.c @@ -7,6 +7,10 @@ static void read_int_callback(struct urb *urb/*, struct pt_regs *regs*/) PS_INTERFACE_ADAPTER psIntfAdapter = (PS_INTERFACE_ADAPTER)urb->context; PMINI_ADAPTER Adapter = psIntfAdapter->psAdapter ; + if (netif_msg_intr(Adapter)) + pr_info(PFX "%s: interrupt status %d\n", + Adapter->dev->name, status); + if(Adapter->device_removed == TRUE) { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, INTF_INIT, DBG_LVL_ALL,"Device has Got Removed."); diff --git a/drivers/staging/bcm/InterfaceRx.c b/drivers/staging/bcm/InterfaceRx.c index 6f1ed78c975b..07326a97c4a2 100644 --- a/drivers/staging/bcm/InterfaceRx.c +++ b/drivers/staging/bcm/InterfaceRx.c @@ -38,7 +38,9 @@ static void read_bulk_callback(struct urb *urb) PMINI_ADAPTER Adapter = psIntfAdapter->psAdapter; PLEADER pLeader = urb->transfer_buffer; - + if (unlikely(netif_msg_rx_status(Adapter))) + pr_info(PFX "%s: rx urb status %d length %d\n", + Adapter->dev->name, urb->status, urb->actual_length); if((Adapter->device_removed == TRUE) || (TRUE == Adapter->bEndPointHalted) || @@ -83,8 +85,9 @@ static void read_bulk_callback(struct urb *urb) BCM_DEBUG_PRINT(Adapter,DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL, "Leader Status:0x%hX, Length:0x%hX, VCID:0x%hX", pLeader->Status,pLeader->PLength,pLeader->Vcid); if(MAX_CNTL_PKT_SIZE < pLeader->PLength) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Corrupted leader length...%d\n", - pLeader->PLength); + if (netif_msg_rx_err(Adapter)) + pr_info(PFX "%s: corrupted leader length...%d\n", + Adapter->dev->name, pLeader->PLength); atomic_inc(&Adapter->RxPacketDroppedCount); atomic_add(pLeader->PLength, &Adapter->BadRxByteCount); atomic_dec(&psIntfAdapter->uNumRcbUsed); diff --git a/drivers/staging/bcm/InterfaceTx.c b/drivers/staging/bcm/InterfaceTx.c index a3dadf19538b..f434b899a0d0 100644 --- a/drivers/staging/bcm/InterfaceTx.c +++ b/drivers/staging/bcm/InterfaceTx.c @@ -9,6 +9,10 @@ static void write_bulk_callback(struct urb *urb/*, struct pt_regs *regs*/) PMINI_ADAPTER psAdapter = psIntfAdapter->psAdapter ; BOOLEAN bpowerDownMsg = FALSE ; PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); + + if (unlikely(netif_msg_tx_done(Adapter))) + pr_info(PFX "%s: transmit status %d\n", Adapter->dev->name, urb->status); + if(urb->status != STATUS_SUCCESS) { if(urb->status == -EPIPE) diff --git a/drivers/staging/bcm/Misc.c b/drivers/staging/bcm/Misc.c index 7f3a936529c5..8212af3ecf90 100644 --- a/drivers/staging/bcm/Misc.c +++ b/drivers/staging/bcm/Misc.c @@ -1896,7 +1896,7 @@ void beceem_protocol_reset (PMINI_ADAPTER Adapter) int i; if (netif_msg_link(Adapter)) - pr_notice(DRV_NAME "%s: protocol reset\n", Adapter->dev->name); + pr_notice(PFX "%s: protocol reset\n", Adapter->dev->name); netif_carrier_off(Adapter->dev); netif_stop_queue(Adapter->dev); diff --git a/drivers/staging/bcm/Qos.c b/drivers/staging/bcm/Qos.c index 7e8013c105a2..21b611c68d37 100644 --- a/drivers/staging/bcm/Qos.c +++ b/drivers/staging/bcm/Qos.c @@ -356,8 +356,11 @@ VOID PruneQueue(PMINI_ADAPTER Adapter,/**tx_dropped++; + if (netif_msg_tx_err(Adapter)) + pr_info(PFX "%s: tx queue %d overlimit\n", + Adapter->dev->name, iIndex); + + netstats->tx_dropped++; atomic_inc(&Adapter->TxDroppedPacketCount); DEQUEUEPACKET(Adapter->PackInfo[iIndex].FirstTxQueue, Adapter->PackInfo[iIndex].LastTxQueue); -- cgit v1.2.3 From 1da9badcf02dd6532df9bde8fc05648e74982f2c Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Mon, 1 Nov 2010 11:58:01 -0400 Subject: beceem: allow multicast/broadcast Even though wimax isn't really a broadcast medium, pretend it is. Signed-off-by: Stephen Hemminger --- drivers/staging/bcm/Bcmnet.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/staging/bcm/Bcmnet.c b/drivers/staging/bcm/Bcmnet.c index fbaf73a2e42c..82270c18c6ac 100644 --- a/drivers/staging/bcm/Bcmnet.c +++ b/drivers/staging/bcm/Bcmnet.c @@ -221,7 +221,6 @@ int register_networkdev(PMINI_ADAPTER Adapter) net->mtu = MTU_SIZE; /* 1400 Bytes */ net->tx_queue_len = TX_QLEN; net->flags |= IFF_NOARP; - net->flags &= ~(IFF_BROADCAST | IFF_MULTICAST); Adapter->msg_enable = netif_msg_init(debug, default_msg); netif_carrier_off(net); -- cgit v1.2.3 From ac1b1ae7f84dcde6d6fefc7f8ca27c4e5bd92c22 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Mon, 1 Nov 2010 12:20:09 -0400 Subject: beceem: transmit code cleanup Eliminate global variable in transmit path The Leader can be on the stack, and get rid of unnecessary timeval. Signed-off-by: Stephen Hemminger --- drivers/staging/bcm/Transmit.c | 63 +++++++++++------------------------------- 1 file changed, 16 insertions(+), 47 deletions(-) diff --git a/drivers/staging/bcm/Transmit.c b/drivers/staging/bcm/Transmit.c index 734bbbd14e22..b924a6a4dd78 100644 --- a/drivers/staging/bcm/Transmit.c +++ b/drivers/staging/bcm/Transmit.c @@ -41,19 +41,10 @@ SendPacketFromQueue->SetupNextSend->bcm_cmd53 This function dispatches control packet to the h/w interface @return zero(success) or -ve value(failure) */ -INT SendControlPacket(PMINI_ADAPTER Adapter, /**"); - - PLeader=(PLEADER)pControlPacket; BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Tx"); if(!pControlPacket || !Adapter) { @@ -87,27 +78,21 @@ INT SendControlPacket(PMINI_ADAPTER Adapter, /**len > MAX_DEVICE_DESC_SIZE) { status = STATUS_FAILURE; @@ -141,15 +126,10 @@ INT SetupNextSend(PMINI_ADAPTER Adapter, /**cb) + SKB_CB_TCPACK_OFFSET )) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Sending TCP ACK\n"); + if(TCP_ACK == *((UINT32*) (Packet->cb) + SKB_CB_TCPACK_OFFSET )) Leader.Status = LEADER_STATUS_TCP_ACK; - } else - { Leader.Status = LEADER_STATUS; - } if(Adapter->PackInfo[QueueIndex].bEthCSSupport) { @@ -165,35 +145,26 @@ INT SetupNextSend(PMINI_ADAPTER Adapter, /**data, &Leader, LEADER_SIZE); } - else { Leader.PLength = Packet->len - ETH_HLEN; memcpy((LEADER*)skb_pull(Packet, (ETH_HLEN - LEADER_SIZE)), &Leader, LEADER_SIZE); } - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Packet->len = %d", Packet->len); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Vcid = %d", Vcid); - status = Adapter->interface_transmit(Adapter->pvInterfaceAdapter, Packet->data, (Leader.PLength + LEADER_SIZE)); if(status) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, NEXT_SEND, DBG_LVL_ALL, "Tx Failed..\n"); + ++Adapter->dev->stats.tx_errors; + if (netif_msg_tx_err(Adapter)) + pr_info(PFX "%s: transmit error %d\n", Adapter->dev->name, + status); } else { Adapter->PackInfo[QueueIndex].uiTotalTxBytes += Leader.PLength; - atomic_add(Leader.PLength, &Adapter->GoodTxByteCount); - atomic_inc(&Adapter->TxTotalPacketCount); - } - - atomic_dec(&Adapter->CurrNumFreeTxDesc); - -errExit: - - if(STATUS_SUCCESS == status) - { + Adapter->dev->stats.tx_bytes += Leader.PLength; + ++Adapter->dev->stats.tx_packets; Adapter->PackInfo[QueueIndex].uiCurrentTokenCount -= Leader.PLength << 3; Adapter->PackInfo[QueueIndex].uiSentBytes += (Packet->len); Adapter->PackInfo[QueueIndex].uiSentPackets++; @@ -203,6 +174,9 @@ errExit: Adapter->PackInfo[QueueIndex].uiThisPeriodSentBytes += Leader.PLength; } + atomic_dec(&Adapter->CurrNumFreeTxDesc); + +errExit: dev_kfree_skb(Packet); return status; @@ -238,11 +212,10 @@ int tx_pkt_handler(PMINI_ADAPTER Adapter /**< pointer to adapter object*/ if(Adapter->downloadDDR == 1) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "Downloading DDR Settings\n"); Adapter->downloadDDR +=1; status = download_ddr_settings(Adapter); if(status) - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "DDR DOWNLOAD FAILED!\n"); + pr_err(PFX "DDR DOWNLOAD FAILED! %d\n", status); continue; } @@ -278,7 +251,6 @@ int tx_pkt_handler(PMINI_ADAPTER Adapter /**< pointer to adapter object*/ wake_up(&Adapter->process_rx_cntrlpkt); } - transmit_packets(Adapter); atomic_set(&Adapter->TxPktAvail, 0); @@ -288,6 +260,3 @@ int tx_pkt_handler(PMINI_ADAPTER Adapter /**< pointer to adapter object*/ Adapter->transmit_packet_thread = NULL; return 0; } - - - -- cgit v1.2.3 From 45400554923867c8479621e55a76e0612192dafb Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Mon, 1 Nov 2010 12:21:32 -0400 Subject: beceem: remove unused code to dump header Signed-off-by: Stephen Hemminger --- drivers/staging/bcm/PHSModule.c | 31 ------------------------------- 1 file changed, 31 deletions(-) diff --git a/drivers/staging/bcm/PHSModule.c b/drivers/staging/bcm/PHSModule.c index e0456b291d6c..44ddb59c2ecc 100644 --- a/drivers/staging/bcm/PHSModule.c +++ b/drivers/staging/bcm/PHSModule.c @@ -3,8 +3,6 @@ #define IN #define OUT -void DumpDataPacketHeader(PUCHAR pPkt); - /* Function: PHSTransmit @@ -81,8 +79,6 @@ int PHSTransmit(PMINI_ADAPTER Adapter, { - //DumpDataPacketHeader(pucPHSPktHdrInBuf); - // Step 2 Supress Header using PHS and fill into intermediate ucaPHSPktHdrOutBuf. // Suppress only if IP Header and PHS Enabled For the Service Flow if(((usPacketType == ETHERNET_FRAMETYPE_IPV4) || @@ -229,17 +225,6 @@ int PHSRecieve(PMINI_ADAPTER Adapter, return STATUS_SUCCESS; } -void DumpDataPacketHeader(PUCHAR pPkt) -{ - struct iphdr *iphd = (struct iphdr*)pPkt; - PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"Phs Send/Recieve : IP Packet Hdr \n"); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"TOS : %x \n",iphd->tos); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"Src IP : %x \n",iphd->saddr); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_SEND, DBG_LVL_ALL,"Dest IP : %x \n \n",iphd->daddr); - -} - void DumpFullPacket(UCHAR *pBuf,UINT nPktLen) { PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); @@ -1300,22 +1285,6 @@ BOOLEAN DerefPhsRule(IN B_UINT16 uiClsId,S_CLASSIFIER_TABLE *psaClassifiertable } } -static void DumpBuffer(PVOID BuffVAddress, int xferSize) -{ - int i; - int iPrintLength; - PUCHAR temp=(PUCHAR)BuffVAddress; - PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); - iPrintLength=(xferSize<32?xferSize:32); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\n"); - - for (i=0;i < iPrintLength;i++) { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "%x|",temp[i]); - } - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, PHS_DISPATCH, DBG_LVL_ALL, "\n"); -} - - void DumpPhsRules(PPHS_DEVICE_EXTENSION pDeviceExtension) { int i,j,k,l; -- cgit v1.2.3 From 9dd47ee7dd535649a2c32d509631c7a3d793f2e1 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Mon, 1 Nov 2010 12:24:00 -0400 Subject: beceem: make local functions static Use namespace tool from kernel scripts to identify dead code and functions that should be static. Signed-off-by: Stephen Hemminger --- drivers/staging/bcm/CmHost.c | 5 +- drivers/staging/bcm/CmHost.h | 3 - drivers/staging/bcm/HandleControlPacket.c | 3 +- drivers/staging/bcm/IPv6Protocol.c | 10 +- drivers/staging/bcm/IPv6ProtocolHdr.h | 3 - drivers/staging/bcm/InterfaceIdleMode.c | 12 +-- drivers/staging/bcm/InterfaceIdleMode.h | 2 - drivers/staging/bcm/InterfaceInit.c | 8 +- drivers/staging/bcm/InterfaceInit.h | 4 - drivers/staging/bcm/InterfaceIsr.c | 36 ------- drivers/staging/bcm/Misc.c | 52 +++------ drivers/staging/bcm/PHSModule.c | 72 ++++++++++--- drivers/staging/bcm/PHSModule.h | 45 -------- drivers/staging/bcm/Prototypes.h | 86 +-------------- drivers/staging/bcm/Qos.c | 30 ++++-- drivers/staging/bcm/nvm.c | 173 ++++++++++++------------------ 16 files changed, 178 insertions(+), 366 deletions(-) diff --git a/drivers/staging/bcm/CmHost.c b/drivers/staging/bcm/CmHost.c index 1aa962fedb91..553da135c828 100644 --- a/drivers/staging/bcm/CmHost.c +++ b/drivers/staging/bcm/CmHost.c @@ -15,6 +15,7 @@ typedef enum _E_CLASSIFIER_ACTION eDeleteClassifier }E_CLASSIFIER_ACTION; +static ULONG GetNextTargetBufferLocation(PMINI_ADAPTER Adapter,B_UINT16 tid); /************************************************************ * Function - SearchSfid @@ -108,7 +109,7 @@ static int SearchFreeClsid(PMINI_ADAPTER Adapter /**Adapter Context*/ return MAX_CLASSIFIERS+1; } -VOID deleteSFBySfid(PMINI_ADAPTER Adapter, UINT uiSearchRuleIndex) +static VOID deleteSFBySfid(PMINI_ADAPTER Adapter, UINT uiSearchRuleIndex) { //deleting all the packet held in the SF flush_queue(Adapter,uiSearchRuleIndex); @@ -1923,7 +1924,7 @@ ULONG SetUpTargetDsxBuffers(PMINI_ADAPTER Adapter) return 1; } -ULONG GetNextTargetBufferLocation(PMINI_ADAPTER Adapter,B_UINT16 tid) +static ULONG GetNextTargetBufferLocation(PMINI_ADAPTER Adapter,B_UINT16 tid) { ULONG ulTargetDSXBufferAddress; ULONG ulTargetDsxBufferIndexToUse,ulMaxTry; diff --git a/drivers/staging/bcm/CmHost.h b/drivers/staging/bcm/CmHost.h index 847782c3765b..8f689769b4ba 100644 --- a/drivers/staging/bcm/CmHost.h +++ b/drivers/staging/bcm/CmHost.h @@ -150,8 +150,6 @@ typedef struct stLocalSFChangeIndicationAlt{ ULONG StoreCmControlResponseMessage(PMINI_ADAPTER Adapter,PVOID pvBuffer,UINT *puBufferLength); -ULONG GetNextTargetBufferLocation(PMINI_ADAPTER Adapter,B_UINT16 tid); - INT AllocAdapterDsxBuffer(PMINI_ADAPTER Adapter); INT FreeAdapterDsxBuffer(PMINI_ADAPTER Adapter); @@ -159,7 +157,6 @@ ULONG SetUpTargetDsxBuffers(PMINI_ADAPTER Adapter); BOOLEAN CmControlResponseMessage(PMINI_ADAPTER Adapter,PVOID pvBuffer); -VOID deleteSFBySfid(PMINI_ADAPTER Adapter, UINT uiSearchRuleIndex); #pragma pack (pop) diff --git a/drivers/staging/bcm/HandleControlPacket.c b/drivers/staging/bcm/HandleControlPacket.c index 2d4dbcc215e3..e7afa56c0dcf 100644 --- a/drivers/staging/bcm/HandleControlPacket.c +++ b/drivers/staging/bcm/HandleControlPacket.c @@ -11,8 +11,7 @@ When a control packet is received, analyze the Enqueue the control packet for Application. @return None */ -VOID handle_rx_control_packet(PMINI_ADAPTER Adapter, /**psAdapter); } -VOID ConfigureEndPointTypesThroughEEPROM(PMINI_ADAPTER Adapter) +static VOID ConfigureEndPointTypesThroughEEPROM(PMINI_ADAPTER Adapter) { ULONG ulReg = 0; @@ -441,7 +443,7 @@ static inline int bcm_usb_endpoint_is_isoc_out(const struct usb_endpoint_descrip return (bcm_usb_endpoint_xfer_isoc(epd) && bcm_usb_endpoint_dir_out(epd)); } -INT InterfaceAdapterInit(PS_INTERFACE_ADAPTER psIntfAdapter) +static INT InterfaceAdapterInit(PS_INTERFACE_ADAPTER psIntfAdapter) { struct usb_host_interface *iface_desc; struct usb_endpoint_descriptor *endpoint; diff --git a/drivers/staging/bcm/InterfaceInit.h b/drivers/staging/bcm/InterfaceInit.h index 71e629d29c79..3b8e17b619ba 100644 --- a/drivers/staging/bcm/InterfaceInit.h +++ b/drivers/staging/bcm/InterfaceInit.h @@ -19,11 +19,7 @@ INT InterfaceInitialize(void); INT InterfaceExit(void); -INT InterfaceAdapterInit(PS_INTERFACE_ADAPTER Adapter); - INT usbbcm_worker_thread(PS_INTERFACE_ADAPTER psIntfAdapter); -VOID InterfaceAdapterFree(PS_INTERFACE_ADAPTER psIntfAdapter); - #endif diff --git a/drivers/staging/bcm/InterfaceIsr.c b/drivers/staging/bcm/InterfaceIsr.c index 2d26e2ed38d9..423464765e59 100644 --- a/drivers/staging/bcm/InterfaceIsr.c +++ b/drivers/staging/bcm/InterfaceIsr.c @@ -167,39 +167,3 @@ INT StartInterruptUrb(PS_INTERFACE_ADAPTER psIntfAdapter) return status; } -/* -Function: InterfaceEnableInterrupt - -Description: This is the hardware specific Function for configuring - and enabling the interrupts on the device. - -Input parameters: IN PMINI_ADAPTER Adapter - Miniport Adapter Context - - -Return: BCM_STATUS_SUCCESS - If configuring the interrupts was successful. - Other - If an error occured. -*/ - -void InterfaceEnableInterrupt(PMINI_ADAPTER Adapter) -{ - -} - -/* -Function: InterfaceDisableInterrupt - -Description: This is the hardware specific Function for disabling the interrupts on the device. - -Input parameters: IN PMINI_ADAPTER Adapter - Miniport Adapter Context - - -Return: BCM_STATUS_SUCCESS - If disabling the interrupts was successful. - Other - If an error occured. -*/ - -void InterfaceDisableInterrupt(PMINI_ADAPTER Adapter) -{ - -} - - diff --git a/drivers/staging/bcm/Misc.c b/drivers/staging/bcm/Misc.c index 8212af3ecf90..2f849b2a1275 100644 --- a/drivers/staging/bcm/Misc.c +++ b/drivers/staging/bcm/Misc.c @@ -1,5 +1,12 @@ #include "headers.h" +static int BcmFileDownload(PMINI_ADAPTER Adapter, const char *path, + unsigned int loc); +static VOID doPowerAutoCorrection(PMINI_ADAPTER psAdapter); +static void HandleShutDownModeRequest(PMINI_ADAPTER Adapter,PUCHAR pucBuffer); +static int bcm_parse_target_params(PMINI_ADAPTER Adapter); +static void beceem_protocol_reset (PMINI_ADAPTER Adapter); + static VOID default_wimax_protocol_initialize(PMINI_ADAPTER Adapter) { @@ -175,7 +182,7 @@ static int create_worker_threads(PMINI_ADAPTER psAdapter) return 0; } -static struct file *open_firmware_file(PMINI_ADAPTER Adapter, char *path) +static struct file *open_firmware_file(PMINI_ADAPTER Adapter, const char *path) { struct file *flp=NULL; mm_segment_t oldfs; @@ -197,8 +204,8 @@ static struct file *open_firmware_file(PMINI_ADAPTER Adapter, char *path) } -int BcmFileDownload(PMINI_ADAPTER Adapter,/**< Logical Adapter */ - char *path, /**< path to image file */ +static int BcmFileDownload(PMINI_ADAPTER Adapter,/**< Logical Adapter */ + const char *path, /**< path to image file */ unsigned int loc /**< Download Address on the chip*/ ) { @@ -478,18 +485,6 @@ static VOID SendStatisticsPointerRequest(PMINI_ADAPTER Adapter, #endif -void SendLinkDown(PMINI_ADAPTER Adapter) -{ - LINK_REQUEST stLinkDownRequest; - memset(&stLinkDownRequest, 0, sizeof(LINK_REQUEST)); - stLinkDownRequest.Leader.Status=LINK_UP_CONTROL_REQ; - stLinkDownRequest.Leader.PLength=sizeof(ULONG);//minimum 4 bytes - stLinkDownRequest.szData[0]=LINK_DOWN_REQ_PAYLOAD; - Adapter->bLinkDownRequested = TRUE; - - CopyBufferToControlPacket(Adapter,&stLinkDownRequest); -} - /****************************************************************** * Function - LinkMessage() * @@ -1229,7 +1224,7 @@ OUT: } -int bcm_parse_target_params(PMINI_ADAPTER Adapter) +static int bcm_parse_target_params(PMINI_ADAPTER Adapter) { struct file *flp=NULL; mm_segment_t oldfs={0}; @@ -1357,7 +1352,7 @@ void beceem_parse_target_struct(PMINI_ADAPTER Adapter) } -VOID doPowerAutoCorrection(PMINI_ADAPTER psAdapter) +static VOID doPowerAutoCorrection(PMINI_ADAPTER psAdapter) { UINT reporting_mode; @@ -1496,26 +1491,7 @@ int rdmalt (PMINI_ADAPTER Adapter, UINT uiAddress, PUINT pucBuff, size_t size) return uiRetVal; } -int rdmWithLock(PMINI_ADAPTER Adapter, UINT uiAddress, PCHAR pucBuff, size_t sSize) -{ - INT status = STATUS_SUCCESS ; - down(&Adapter->rdmwrmsync); - - if((Adapter->IdleMode == TRUE) || - (Adapter->bShutStatus ==TRUE) || - (Adapter->bPreparingForLowPowerMode ==TRUE)) - { - status = -EACCES; - goto exit; - } - - status = rdm(Adapter, uiAddress, pucBuff, sSize); - -exit: - up(&Adapter->rdmwrmsync); - return status ; -} int wrmWithLock(PMINI_ADAPTER Adapter, UINT uiAddress, PCHAR pucBuff, size_t sSize) { INT status = STATUS_SUCCESS ; @@ -1707,7 +1683,7 @@ static VOID SendShutModeResponse(PMINI_ADAPTER Adapter) } -void HandleShutDownModeRequest(PMINI_ADAPTER Adapter,PUCHAR pucBuffer) +static void HandleShutDownModeRequest(PMINI_ADAPTER Adapter,PUCHAR pucBuffer) { B_UINT32 uiResetValue = 0; @@ -1891,7 +1867,7 @@ void flush_queue(PMINI_ADAPTER Adapter, UINT iQIndex) } -void beceem_protocol_reset (PMINI_ADAPTER Adapter) +static void beceem_protocol_reset (PMINI_ADAPTER Adapter) { int i; diff --git a/drivers/staging/bcm/PHSModule.c b/drivers/staging/bcm/PHSModule.c index 44ddb59c2ecc..d1ca1912a74b 100644 --- a/drivers/staging/bcm/PHSModule.c +++ b/drivers/staging/bcm/PHSModule.c @@ -1,5 +1,51 @@ #include "headers.h" +static UINT CreateSFToClassifierRuleMapping(B_UINT16 uiVcid,B_UINT16 uiClsId,S_SERVICEFLOW_TABLE *psServiceFlowTable,S_PHS_RULE *psPhsRule,B_UINT8 u8AssociatedPHSI); + +static UINT CreateClassiferToPHSRuleMapping(B_UINT16 uiVcid,B_UINT16 uiClsId,S_SERVICEFLOW_ENTRY *pstServiceFlowEntry,S_PHS_RULE *psPhsRule,B_UINT8 u8AssociatedPHSI); + +static UINT CreateClassifierPHSRule(B_UINT16 uiClsId,S_CLASSIFIER_TABLE *psaClassifiertable ,S_PHS_RULE *psPhsRule,E_CLASSIFIER_ENTRY_CONTEXT eClsContext,B_UINT8 u8AssociatedPHSI); + +static UINT UpdateClassifierPHSRule(B_UINT16 uiClsId,S_CLASSIFIER_ENTRY *pstClassifierEntry,S_CLASSIFIER_TABLE *psaClassifiertable ,S_PHS_RULE *psPhsRule,B_UINT8 u8AssociatedPHSI); + +static BOOLEAN ValidatePHSRuleComplete(S_PHS_RULE *psPhsRule); + +static BOOLEAN DerefPhsRule(B_UINT16 uiClsId,S_CLASSIFIER_TABLE *psaClassifiertable,S_PHS_RULE *pstPhsRule); + +static UINT GetClassifierEntry(S_CLASSIFIER_TABLE *pstClassifierTable,B_UINT32 uiClsid,E_CLASSIFIER_ENTRY_CONTEXT eClsContext, S_CLASSIFIER_ENTRY **ppstClassifierEntry); + +static UINT GetPhsRuleEntry(S_CLASSIFIER_TABLE *pstClassifierTable,B_UINT32 uiPHSI,E_CLASSIFIER_ENTRY_CONTEXT eClsContext,S_PHS_RULE **ppstPhsRule); + +static void free_phs_serviceflow_rules(S_SERVICEFLOW_TABLE *psServiceFlowRulesTable); + +static int phs_compress(S_PHS_RULE *phs_members,unsigned char *in_buf, + unsigned char *out_buf,unsigned int *header_size,UINT *new_header_size ); + + +static int verify_suppress_phsf(unsigned char *in_buffer,unsigned char *out_buffer, + unsigned char *phsf,unsigned char *phsm,unsigned int phss,unsigned int phsv,UINT *new_header_size ); + +static int phs_decompress(unsigned char *in_buf,unsigned char *out_buf,\ + S_PHS_RULE *phs_rules,UINT *header_size); + + +static ULONG PhsCompress(void* pvContext, + B_UINT16 uiVcid, + B_UINT16 uiClsId, + void *pvInputBuffer, + void *pvOutputBuffer, + UINT *pOldHeaderSize, + UINT *pNewHeaderSize ); + +static ULONG PhsDeCompress(void* pvContext, + B_UINT16 uiVcid, + void *pvInputBuffer, + void *pvOutputBuffer, + UINT *pInHeaderSize, + UINT *pOutHeaderSize); + + + #define IN #define OUT @@ -798,7 +844,7 @@ ULONG PhsDeCompress(IN void* pvContext, // Does not return any value. //----------------------------------------------------------------------------- -void free_phs_serviceflow_rules(S_SERVICEFLOW_TABLE *psServiceFlowRulesTable) +static void free_phs_serviceflow_rules(S_SERVICEFLOW_TABLE *psServiceFlowRulesTable) { int i,j; PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); @@ -852,7 +898,7 @@ void free_phs_serviceflow_rules(S_SERVICEFLOW_TABLE *psServiceFlowRulesTable) -BOOLEAN ValidatePHSRuleComplete(IN S_PHS_RULE *psPhsRule) +static BOOLEAN ValidatePHSRuleComplete(IN S_PHS_RULE *psPhsRule) { if(psPhsRule) { @@ -935,9 +981,9 @@ UINT GetClassifierEntry(IN S_CLASSIFIER_TABLE *pstClassifierTable, return PHS_INVALID_TABLE_INDEX; } -UINT GetPhsRuleEntry(IN S_CLASSIFIER_TABLE *pstClassifierTable, - IN B_UINT32 uiPHSI,E_CLASSIFIER_ENTRY_CONTEXT eClsContext, - OUT S_PHS_RULE **ppstPhsRule) +static UINT GetPhsRuleEntry(IN S_CLASSIFIER_TABLE *pstClassifierTable, + IN B_UINT32 uiPHSI,E_CLASSIFIER_ENTRY_CONTEXT eClsContext, + OUT S_PHS_RULE **ppstPhsRule) { int i; S_CLASSIFIER_ENTRY *pstClassifierRule = NULL; @@ -1094,7 +1140,7 @@ UINT CreateClassiferToPHSRuleMapping(IN B_UINT16 uiVcid, return uiStatus; } -UINT CreateClassifierPHSRule(IN B_UINT16 uiClsId, +static UINT CreateClassifierPHSRule(IN B_UINT16 uiClsId, S_CLASSIFIER_TABLE *psaClassifiertable ,S_PHS_RULE *psPhsRule, E_CLASSIFIER_ENTRY_CONTEXT eClsContext,B_UINT8 u8AssociatedPHSI) { @@ -1205,7 +1251,7 @@ UINT CreateClassifierPHSRule(IN B_UINT16 uiClsId, } -UINT UpdateClassifierPHSRule(IN B_UINT16 uiClsId, +static UINT UpdateClassifierPHSRule(IN B_UINT16 uiClsId, IN S_CLASSIFIER_ENTRY *pstClassifierEntry, S_CLASSIFIER_TABLE *psaClassifiertable ,S_PHS_RULE *psPhsRule, B_UINT8 u8AssociatedPHSI) @@ -1266,7 +1312,7 @@ UINT UpdateClassifierPHSRule(IN B_UINT16 uiClsId, } -BOOLEAN DerefPhsRule(IN B_UINT16 uiClsId,S_CLASSIFIER_TABLE *psaClassifiertable,S_PHS_RULE *pstPhsRule) +static BOOLEAN DerefPhsRule(IN B_UINT16 uiClsId,S_CLASSIFIER_TABLE *psaClassifiertable,S_PHS_RULE *pstPhsRule) { if(pstPhsRule==NULL) return FALSE; @@ -1444,8 +1490,8 @@ int phs_decompress(unsigned char *in_buf,unsigned char *out_buf, // size-The number of bytes copied into the output buffer i.e dynamic fields // 0 -If PHS rule is NULL.If PHSV field is not set.If the verification fails. //----------------------------------------------------------------------------- -int phs_compress(S_PHS_RULE *phs_rule,unsigned char *in_buf - ,unsigned char *out_buf,UINT *header_size,UINT *new_header_size) +static int phs_compress(S_PHS_RULE *phs_rule,unsigned char *in_buf + ,unsigned char *out_buf,UINT *header_size,UINT *new_header_size) { unsigned char *old_addr = out_buf; int supress = 0; @@ -1505,9 +1551,9 @@ int phs_compress(S_PHS_RULE *phs_rule,unsigned char *in_buf // 0 -Packet has failed the verification. //----------------------------------------------------------------------------- - int verify_suppress_phsf(unsigned char *in_buffer,unsigned char *out_buffer, - unsigned char *phsf,unsigned char *phsm,unsigned int phss, - unsigned int phsv,UINT* new_header_size) +static int verify_suppress_phsf(unsigned char *in_buffer,unsigned char *out_buffer, + unsigned char *phsf,unsigned char *phsm,unsigned int phss, + unsigned int phsv,UINT* new_header_size) { unsigned int size=0; int bit,i=0; diff --git a/drivers/staging/bcm/PHSModule.h b/drivers/staging/bcm/PHSModule.h index bf2b5763252c..0dd05a7c55d9 100644 --- a/drivers/staging/bcm/PHSModule.h +++ b/drivers/staging/bcm/PHSModule.h @@ -27,19 +27,6 @@ void DumpPhsRules(PPHS_DEVICE_EXTENSION pDeviceExtension); int phs_init(PPHS_DEVICE_EXTENSION pPhsdeviceExtension,PMINI_ADAPTER Adapter); -void free_phs_serviceflow_rules(S_SERVICEFLOW_TABLE *psServiceFlowRulesTable); - -int phs_compress(S_PHS_RULE *phs_members,unsigned char *in_buf, - unsigned char *out_buf,unsigned int *header_size,UINT *new_header_size ); - - -int verify_suppress_phsf(unsigned char *in_buffer,unsigned char *out_buffer, - unsigned char *phsf,unsigned char *phsm,unsigned int phss,unsigned int phsv,UINT *new_header_size ); - -int phs_decompress(unsigned char *in_buf,unsigned char *out_buf,\ - S_PHS_RULE *phs_rules,UINT *header_size); - - int PhsCleanup(PPHS_DEVICE_EXTENSION pPHSDeviceExt); //Utility Functions @@ -52,42 +39,10 @@ ULONG PhsDeleteClassifierRule(void* pvContext, B_UINT16 uiVcid ,B_UINT16 uiClsI ULONG PhsDeleteSFRules(void* pvContext,B_UINT16 uiVcid) ; -ULONG PhsCompress(void* pvContext, - B_UINT16 uiVcid, - B_UINT16 uiClsId, - void *pvInputBuffer, - void *pvOutputBuffer, - UINT *pOldHeaderSize, - UINT *pNewHeaderSize ); - -ULONG PhsDeCompress(void* pvContext, - B_UINT16 uiVcid, - void *pvInputBuffer, - void *pvOutputBuffer, - UINT *pInHeaderSize, - UINT *pOutHeaderSize); - - BOOLEAN ValidatePHSRule(S_PHS_RULE *psPhsRule); -BOOLEAN ValidatePHSRuleComplete(S_PHS_RULE *psPhsRule); - UINT GetServiceFlowEntry(S_SERVICEFLOW_TABLE *psServiceFlowTable,B_UINT16 uiVcid,S_SERVICEFLOW_ENTRY **ppstServiceFlowEntry); -UINT GetClassifierEntry(S_CLASSIFIER_TABLE *pstClassifierTable,B_UINT32 uiClsid,E_CLASSIFIER_ENTRY_CONTEXT eClsContext, S_CLASSIFIER_ENTRY **ppstClassifierEntry); - -UINT GetPhsRuleEntry(S_CLASSIFIER_TABLE *pstClassifierTable,B_UINT32 uiPHSI,E_CLASSIFIER_ENTRY_CONTEXT eClsContext,S_PHS_RULE **ppstPhsRule); - - -UINT CreateSFToClassifierRuleMapping(B_UINT16 uiVcid,B_UINT16 uiClsId,S_SERVICEFLOW_TABLE *psServiceFlowTable,S_PHS_RULE *psPhsRule,B_UINT8 u8AssociatedPHSI); - -UINT CreateClassiferToPHSRuleMapping(B_UINT16 uiVcid,B_UINT16 uiClsId,S_SERVICEFLOW_ENTRY *pstServiceFlowEntry,S_PHS_RULE *psPhsRule,B_UINT8 u8AssociatedPHSI); - -UINT CreateClassifierPHSRule(B_UINT16 uiClsId,S_CLASSIFIER_TABLE *psaClassifiertable ,S_PHS_RULE *psPhsRule,E_CLASSIFIER_ENTRY_CONTEXT eClsContext,B_UINT8 u8AssociatedPHSI); - -UINT UpdateClassifierPHSRule(B_UINT16 uiClsId,S_CLASSIFIER_ENTRY *pstClassifierEntry,S_CLASSIFIER_TABLE *psaClassifiertable ,S_PHS_RULE *psPhsRule,B_UINT8 u8AssociatedPHSI); - -BOOLEAN DerefPhsRule(B_UINT16 uiClsId,S_CLASSIFIER_TABLE *psaClassifiertable,S_PHS_RULE *pstPhsRule); void DumpPhsRules(PPHS_DEVICE_EXTENSION pDeviceExtension); diff --git a/drivers/staging/bcm/Prototypes.h b/drivers/staging/bcm/Prototypes.h index 920e9882ccd1..c27fce875be7 100644 --- a/drivers/staging/bcm/Prototypes.h +++ b/drivers/staging/bcm/Prototypes.h @@ -1,19 +1,12 @@ #ifndef _PROTOTYPES_H_ #define _PROTOTYPES_H_ -int BcmFileDownload(PMINI_ADAPTER Adapter,/**< Logical Adapter */ - char *path, /**< path to image file */ - unsigned int loc /**< Download Address on the chip*/ - ); VOID LinkControlResponseMessage(PMINI_ADAPTER Adapter, PUCHAR pucBuffer); VOID StatisticsResponse(PMINI_ADAPTER Adapter,PVOID pvBuffer); VOID IdleModeResponse(PMINI_ADAPTER Adapter,PUINT puiBuffer); -VOID handle_rx_control_packet(PMINI_ADAPTER Adapter, /**data))->au8SourceAddress); @@ -802,9 +808,11 @@ BOOLEAN EThCSClassifyPkt(PMINI_ADAPTER Adapter,struct sk_buff* skb,PS_ETHCS_PKT_ return bClassificationSucceed; } -void EThCSGetPktInfo(PMINI_ADAPTER Adapter,PVOID pvEthPayload,PS_ETHCS_PKT_INFO pstEthCsPktInfo) +static void EThCSGetPktInfo(PMINI_ADAPTER Adapter,PVOID pvEthPayload, + PS_ETHCS_PKT_INFO pstEthCsPktInfo) { USHORT u16Etype = ntohs(((ETH_HEADER_STRUC*)pvEthPayload)->u16Etype); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_TX, IPV4_DBG, DBG_LVL_ALL, "EthCSGetPktInfo : Eth Hdr Type : %X\n",u16Etype); if(u16Etype > 0x5dc) { diff --git a/drivers/staging/bcm/nvm.c b/drivers/staging/bcm/nvm.c index 4f1b35a68b7f..5c10769abb55 100644 --- a/drivers/staging/bcm/nvm.c +++ b/drivers/staging/bcm/nvm.c @@ -1,6 +1,56 @@ #include "headers.h" #define DWORD unsigned int + +static INT BcmDoChipSelect(PMINI_ADAPTER Adapter, UINT offset); +static INT BcmGetActiveDSD(PMINI_ADAPTER Adapter); +static INT BcmGetActiveISO(PMINI_ADAPTER Adapter); +static UINT BcmGetEEPROMSize(PMINI_ADAPTER Adapter); +static INT BcmGetFlashCSInfo(PMINI_ADAPTER Adapter); +static UINT BcmGetFlashSectorSize(PMINI_ADAPTER Adapter, UINT FlashSectorSizeSig, UINT FlashSectorSize); + +static VOID BcmValidateNvmType(PMINI_ADAPTER Adapter); +static INT BcmGetNvmSize(PMINI_ADAPTER Adapter); +static UINT BcmGetFlashSize(PMINI_ADAPTER Adapter); +static NVM_TYPE BcmGetNvmType(PMINI_ADAPTER Adapter); + +static INT BcmGetSectionValEndOffset(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal); + +static B_UINT8 IsOffsetWritable(PMINI_ADAPTER Adapter, UINT uiOffset); +static INT IsSectionWritable(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL Section); +static INT IsSectionExistInVendorInfo(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL section); + +static INT ReadDSDPriority(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL dsd); +static INT ReadDSDSignature(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL dsd); +static INT ReadISOPriority(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL iso); +static INT ReadISOSignature(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL iso); + +static INT CorruptDSDSig(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal); +static INT CorruptISOSig(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal); +static INT SaveHeaderIfPresent(PMINI_ADAPTER Adapter, PUCHAR pBuff, UINT uiSectAlignAddr); +static INT WriteToFlashWithoutSectorErase(PMINI_ADAPTER Adapter, PUINT pBuff, + FLASH2X_SECTION_VAL eFlash2xSectionVal, + UINT uiOffset, UINT uiNumBytes); +static FLASH2X_SECTION_VAL getHighestPriDSD(PMINI_ADAPTER Adapter); +static FLASH2X_SECTION_VAL getHighestPriISO(PMINI_ADAPTER Adapter); + +static INT BeceemFlashBulkRead( + PMINI_ADAPTER Adapter, + PUINT pBuffer, + UINT uiOffset, + UINT uiNumBytes); + +static INT BeceemFlashBulkWrite( + PMINI_ADAPTER Adapter, + PUINT pBuffer, + UINT uiOffset, + UINT uiNumBytes, + BOOLEAN bVerify); + +static INT GetFlashBaseAddr(PMINI_ADAPTER Adapter); + +static INT ReadBeceemEEPROMBulk(PMINI_ADAPTER Adapter,UINT dwAddress, UINT *pdwData, UINT dwNumData); + // Procedure: ReadEEPROMStatusRegister // // Description: Reads the standard EEPROM Status Register. @@ -409,7 +459,7 @@ INT BeceemEEPROMBulkRead( // - if failed. //----------------------------------------------------------------------------- -INT BeceemFlashBulkRead( +static INT BeceemFlashBulkRead( PMINI_ADAPTER Adapter, PUINT pBuffer, UINT uiOffset, @@ -491,7 +541,7 @@ INT BeceemFlashBulkRead( // //----------------------------------------------------------------------------- -UINT BcmGetFlashSize(PMINI_ADAPTER Adapter) +static UINT BcmGetFlashSize(PMINI_ADAPTER Adapter) { if(IsFlash2x(Adapter)) return (Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader + sizeof(DSD_HEADER)); @@ -514,7 +564,7 @@ UINT BcmGetFlashSize(PMINI_ADAPTER Adapter) // //----------------------------------------------------------------------------- -UINT BcmGetEEPROMSize(PMINI_ADAPTER Adapter) +static UINT BcmGetEEPROMSize(PMINI_ADAPTER Adapter) { UINT uiData = 0; UINT uiIndex = 0; @@ -1108,7 +1158,7 @@ static ULONG BcmFlashUnProtectBlock(PMINI_ADAPTER Adapter,UINT uiOffset, UINT ui // //----------------------------------------------------------------------------- -INT BeceemFlashBulkWrite( +static INT BeceemFlashBulkWrite( PMINI_ADAPTER Adapter, PUINT pBuffer, UINT uiOffset, @@ -1613,11 +1663,8 @@ INT PropagateCalParamsFromFlashToMemory(PMINI_ADAPTER Adapter) } pBuff = kmalloc(uiEepromSize, GFP_KERNEL); - if ( pBuff == NULL ) - { return -1; - } if(0 != BeceemNVMRead(Adapter,(PUINT)pBuff,uiCalStartAddr, uiEepromSize)) { @@ -2274,7 +2321,7 @@ INT BcmUpdateSectorSize(PMINI_ADAPTER Adapter,UINT uiSectorSize) // //----------------------------------------------------------------------------- -UINT BcmGetFlashSectorSize(PMINI_ADAPTER Adapter, UINT FlashSectorSizeSig, UINT FlashSectorSize) +static UINT BcmGetFlashSectorSize(PMINI_ADAPTER Adapter, UINT FlashSectorSizeSig, UINT FlashSectorSize) { UINT uiSectorSize = 0; UINT uiSectorSig = 0; @@ -2411,7 +2458,7 @@ INT BcmInitNVM(PMINI_ADAPTER ps_adapter) */ /***************************************************************************/ -INT BcmGetNvmSize(PMINI_ADAPTER Adapter) +static INT BcmGetNvmSize(PMINI_ADAPTER Adapter) { if(Adapter->eNVMType == NVM_EEPROM) { @@ -2435,7 +2482,7 @@ INT BcmGetNvmSize(PMINI_ADAPTER Adapter) // Returns: // //----------------------------------------------------------------------------- -VOID BcmValidateNvmType(PMINI_ADAPTER Adapter) +static VOID BcmValidateNvmType(PMINI_ADAPTER Adapter) { // @@ -2681,7 +2728,7 @@ static INT ConvertEndianOfCSStructure(PFLASH_CS_INFO psFlashCSInfo) return STATUS_SUCCESS; } -INT IsSectionExistInVendorInfo(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL section) +static INT IsSectionExistInVendorInfo(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL section) { return ( Adapter->uiVendorExtnFlag && (Adapter->psFlash2xVendorInfo->VendorSection[section].AccessFlags & FLASH2X_SECTION_PRESENT) && @@ -2779,7 +2826,7 @@ static VOID UpdateVendorInfo(PMINI_ADAPTER Adapter) // //----------------------------------------------------------------------------- -INT BcmGetFlashCSInfo(PMINI_ADAPTER Adapter) +static INT BcmGetFlashCSInfo(PMINI_ADAPTER Adapter) { //FLASH_CS_INFO sFlashCsInfo = {0}; @@ -2926,7 +2973,7 @@ INT BcmGetFlashCSInfo(PMINI_ADAPTER Adapter) // //----------------------------------------------------------------------------- -NVM_TYPE BcmGetNvmType(PMINI_ADAPTER Adapter) +static NVM_TYPE BcmGetNvmType(PMINI_ADAPTER Adapter) { UINT uiData = 0; @@ -3280,39 +3327,6 @@ INT BcmFlash2xBulkWrite( } -/** -* ReadDSDHeader : Read the DSD map for the DSD Section val provided in Argument. -* @Adapter : Beceem Private Data Structure -* @psDSDHeader :Pointer of the buffer where header has to be read -* @dsd :value of the Dyanmic DSD like DSD0 of DSD1 or DSD2 -* -* Return Value:- -* if suceeds return STATUS_SUCCESS or negative error code. -**/ -INT ReadDSDHeader(PMINI_ADAPTER Adapter, PDSD_HEADER psDSDHeader, FLASH2X_SECTION_VAL dsd) -{ - INT Status = STATUS_SUCCESS; - - Status =BcmFlash2xBulkRead(Adapter, - (PUINT)psDSDHeader, - dsd, - Adapter->psFlash2xCSInfo->OffsetFromDSDStartForDSDHeader, - sizeof(DSD_HEADER)); - if(Status == STATUS_SUCCESS) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "DSDImageMagicNumber :0X%x", ntohl(psDSDHeader->DSDImageMagicNumber)); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "DSDImageSize :0X%x ",ntohl(psDSDHeader->DSDImageSize)); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "DSDImageCRC :0X%x",ntohl(psDSDHeader->DSDImageCRC)); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "DSDImagePriority :0X%x",ntohl(psDSDHeader->DSDImagePriority)); - } - else - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"DSD Header read is failed with status :%d", Status); - } - - return Status; -} - /** * BcmGetActiveDSD : Set the Active DSD in Adapter Structure which has to be dumped in DDR * @Adapter :-Drivers private Data Structure @@ -3321,7 +3335,7 @@ INT ReadDSDHeader(PMINI_ADAPTER Adapter, PDSD_HEADER psDSDHeader, FLASH2X_SECTIO * Return STATUS_SUCESS if get sucess in setting the right DSD else negaive error code * **/ -INT BcmGetActiveDSD(PMINI_ADAPTER Adapter) +static INT BcmGetActiveDSD(PMINI_ADAPTER Adapter) { FLASH2X_SECTION_VAL uiHighestPriDSD = 0 ; @@ -3359,39 +3373,6 @@ INT BcmGetActiveDSD(PMINI_ADAPTER Adapter) return STATUS_SUCCESS; } -/** -* ReadISOUnReservedBytes : Read the ISO map for the ISO Section val provided in Argument. -* @Adapter : Driver Private Data Structure -* @psISOHeader :Pointer of the location where header has to be read -* @IsoImage :value of the Dyanmic ISO like ISO_IMAGE1 of ISO_IMAGE2 -* -* Return Value:- -* if suceeds return STATUS_SUCCESS or negative error code. -**/ - -INT ReadISOHeader(PMINI_ADAPTER Adapter, PISO_HEADER psISOHeader, FLASH2X_SECTION_VAL IsoImage) -{ - INT Status = STATUS_SUCCESS; - - Status = BcmFlash2xBulkRead(Adapter, - (PUINT)psISOHeader, - IsoImage, - 0, - sizeof(ISO_HEADER)); - - if(Status == STATUS_SUCCESS) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "ISOImageMagicNumber :0X%x", ntohl(psISOHeader->ISOImageMagicNumber)); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "ISOImageSize :0X%x ",ntohl(psISOHeader->ISOImageSize)); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "ISOImageCRC :0X%x",ntohl(psISOHeader->ISOImageCRC)); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL, "ISOImagePriority :0X%x",ntohl(psISOHeader->ISOImagePriority)); - } - else - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "ISO Header Read failed"); - } - return Status; -} /** * BcmGetActiveISO :- Set the Active ISO in Adapter Data Structue @@ -3403,7 +3384,7 @@ INT ReadISOHeader(PMINI_ADAPTER Adapter, PISO_HEADER psISOHeader, FLASH2X_SECTIO * **/ -INT BcmGetActiveISO(PMINI_ADAPTER Adapter) +static INT BcmGetActiveISO(PMINI_ADAPTER Adapter) { INT HighestPriISO = 0 ; @@ -4501,7 +4482,7 @@ Return Value:- Success :- Base Address of the Flash **/ -INT GetFlashBaseAddr(PMINI_ADAPTER Adapter) +static INT GetFlashBaseAddr(PMINI_ADAPTER Adapter) { UINT uiBaseAddr = 0; @@ -4734,29 +4715,7 @@ INT SaveHeaderIfPresent(PMINI_ADAPTER Adapter, PUCHAR pBuff, UINT uiOffset) return STATUS_SUCCESS ; } -INT BcmMakeFlashCSActive(PMINI_ADAPTER Adapter, UINT offset) -{ - UINT GPIOConfig = 0 ; - - - if(Adapter->bFlashRawRead == FALSE) - { - //Applicable for Flash2.x - if(IsFlash2x(Adapter) == FALSE) - return STATUS_SUCCESS; - } - if(offset/FLASH_PART_SIZE) - { - //bit[14..12] -> will select make Active CS1, CS2 or CS3 - // Select CS1, CS2 and CS3 (CS0 is dedicated pin) - rdmalt(Adapter,FLASH_GPIO_CONFIG_REG, &GPIOConfig, 4); - GPIOConfig |= (7 << 12); - wrmalt(Adapter,FLASH_GPIO_CONFIG_REG, &GPIOConfig, 4); - } - - return STATUS_SUCCESS ; -} /** BcmDoChipSelect : This will selcet the appropriate chip for writing. @Adapater :- Bcm Driver Private Data Structure @@ -4764,7 +4723,7 @@ BcmDoChipSelect : This will selcet the appropriate chip for writing. OutPut:- Select the Appropriate chip and retrn status Sucess **/ -INT BcmDoChipSelect(PMINI_ADAPTER Adapter, UINT offset) +static INT BcmDoChipSelect(PMINI_ADAPTER Adapter, UINT offset) { UINT FlashConfig = 0; INT ChipNum = 0; @@ -5136,7 +5095,7 @@ INT IsSectionWritable(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL Section) return Status ; } -INT CorruptDSDSig(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal) +static INT CorruptDSDSig(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal) { PUCHAR pBuff = NULL; @@ -5209,7 +5168,7 @@ INT CorruptDSDSig(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal) return STATUS_SUCCESS ; } -INT CorruptISOSig(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal) +static INT CorruptISOSig(PMINI_ADAPTER Adapter, FLASH2X_SECTION_VAL eFlash2xSectionVal) { PUCHAR pBuff = NULL; -- cgit v1.2.3 From 429a5908fe3bc4d9ca2512b94cd10b69d50bf91f Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Mon, 1 Nov 2010 12:27:20 -0400 Subject: beceem: off by one on queue index The driver allocates 18 queues (0..16) are for traffic, and 17 is a bit bucket. Signed-off-by: Stephen Hemminger --- drivers/staging/bcm/Macros.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/bcm/Macros.h b/drivers/staging/bcm/Macros.h index f2fd60286a4c..feb351578c8b 100644 --- a/drivers/staging/bcm/Macros.h +++ b/drivers/staging/bcm/Macros.h @@ -261,7 +261,7 @@ typedef enum _E_PHS_DSC_ACTION #define FIRMWARE_BEGIN_ADDR 0xBFC00000 -#define INVALID_QUEUE_INDEX (NO_OF_QUEUES+1) +#define INVALID_QUEUE_INDEX NO_OF_QUEUES #define INVALID_PID (pid_t)-1 #define DDR_80_MHZ 0 -- cgit v1.2.3 From b5ebd85b2bcc0c0a2171e4cc74c61debdc903ddf Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Mon, 1 Nov 2010 12:28:39 -0400 Subject: beceem: do classification even if device is offline Since classification and queue control are separate, allow classification even if device is down now; this avoids races on startup/shutdown. Signed-off-by: Stephen Hemminger --- drivers/staging/bcm/Qos.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/drivers/staging/bcm/Qos.c b/drivers/staging/bcm/Qos.c index 54e9a490e6f9..e4d5a67c8c6b 100644 --- a/drivers/staging/bcm/Qos.c +++ b/drivers/staging/bcm/Qos.c @@ -524,12 +524,6 @@ USHORT ClassifyPacket(PMINI_ADAPTER Adapter,struct sk_buff* skb) for(uiLoopIndex = MAX_CLASSIFIERS - 1; uiLoopIndex >= 0; uiLoopIndex--) { - if (Adapter->device_removed) - { - bClassificationSucceed = FALSE; - break; - } - if(bClassificationSucceed) break; //Iterate through all classifiers which are already in order of priority -- cgit v1.2.3 From cacd92222dd4e04424fa532cf1a222e67c30709b Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Mon, 1 Nov 2010 13:34:35 -0400 Subject: beceem: statistics and transmit queue changes Use standard network statistics variables and routines. Transmit counters are per queue, and skb mapping is already in skb and does not need to be recomputed. Move SearchVcId to only place it is used. Signed-off-by: Stephen Hemminger --- drivers/staging/bcm/Adapter.h | 9 --------- drivers/staging/bcm/Bcmnet.c | 20 -------------------- drivers/staging/bcm/CmHost.c | 12 ------------ drivers/staging/bcm/InterfaceRx.c | 21 ++++++++++++++++----- drivers/staging/bcm/Misc.c | 2 -- drivers/staging/bcm/Prototypes.h | 2 -- drivers/staging/bcm/Qos.c | 13 +++++++------ drivers/staging/bcm/Transmit.c | 21 ++++++++++----------- drivers/staging/bcm/hostmibs.c | 7 ++----- drivers/staging/bcm/led_control.c | 10 ++++++---- 10 files changed, 41 insertions(+), 76 deletions(-) diff --git a/drivers/staging/bcm/Adapter.h b/drivers/staging/bcm/Adapter.h index e5aaec508bf9..5e97cbeb58ec 100644 --- a/drivers/staging/bcm/Adapter.h +++ b/drivers/staging/bcm/Adapter.h @@ -414,17 +414,8 @@ struct _MINI_ADAPTER // this to keep track of the Tx and Rx MailBox Registers. atomic_t CurrNumFreeTxDesc; // to keep track the no of byte recieved - atomic_t RxRollOverCount; USHORT PrevNumRecvDescs; USHORT CurrNumRecvDescs; - atomic_t GoodRxByteCount; - atomic_t GoodRxPktCount; - atomic_t BadRxByteCount; - atomic_t RxPacketDroppedCount; - atomic_t GoodTxByteCount; - atomic_t TxTotalPacketCount; - atomic_t TxDroppedPacketCount; - UINT u32TotalDSD; PacketInfo PackInfo[NO_OF_QUEUES]; S_CLASSIFIER_RULE astClassifierTable[MAX_CLASSIFIERS]; diff --git a/drivers/staging/bcm/Bcmnet.c b/drivers/staging/bcm/Bcmnet.c index 82270c18c6ac..eb224a9dafab 100644 --- a/drivers/staging/bcm/Bcmnet.c +++ b/drivers/staging/bcm/Bcmnet.c @@ -48,25 +48,6 @@ static INT bcm_close(struct net_device *dev) return 0; } -static struct net_device_stats *bcm_get_stats(struct net_device *dev) -{ - PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(dev); - struct net_device_stats* netstats = &dev->stats; - - netstats->rx_packets = atomic_read(&Adapter->RxRollOverCount)*64*1024 - + Adapter->PrevNumRecvDescs; - netstats->rx_bytes = atomic_read(&Adapter->GoodRxByteCount) - + atomic_read(&Adapter->BadRxByteCount); - - netstats->rx_dropped = atomic_read(&Adapter->RxPacketDroppedCount); - netstats->rx_errors = atomic_read(&Adapter->RxPacketDroppedCount); - netstats->tx_bytes = atomic_read(&Adapter->GoodTxByteCount); - netstats->tx_packets = atomic_read(&Adapter->TxTotalPacketCount); - netstats->tx_dropped = atomic_read(&Adapter->TxDroppedPacketCount); - - return netstats; -} - static u16 bcm_select_queue(struct net_device *dev, struct sk_buff *skb) { return ClassifyPacket(netdev_priv(dev), skb); @@ -140,7 +121,6 @@ Register other driver entry points with the kernel static const struct net_device_ops bcmNetDevOps = { .ndo_open = bcm_open, .ndo_stop = bcm_close, - .ndo_get_stats = bcm_get_stats, .ndo_start_xmit = bcm_transmit, .ndo_change_mtu = eth_change_mtu, .ndo_set_mac_address = eth_mac_addr, diff --git a/drivers/staging/bcm/CmHost.c b/drivers/staging/bcm/CmHost.c index 553da135c828..38b64e69d81a 100644 --- a/drivers/staging/bcm/CmHost.c +++ b/drivers/staging/bcm/CmHost.c @@ -58,18 +58,6 @@ static INT SearchFreeSfid(PMINI_ADAPTER Adapter) return NO_OF_QUEUES+1; } -int SearchVcid(PMINI_ADAPTER Adapter,unsigned short usVcid) -{ - int iIndex=0; - - for(iIndex=(NO_OF_QUEUES-1);iIndex>=0;iIndex--) - if(Adapter->PackInfo[iIndex].usVCID_Value == usVcid) - return iIndex; - return NO_OF_QUEUES+1; - -} - - /* Function: SearchClsid Description: This routinue would search Classifier having specified ClassifierID as input parameter diff --git a/drivers/staging/bcm/InterfaceRx.c b/drivers/staging/bcm/InterfaceRx.c index 07326a97c4a2..533f8ebe0f84 100644 --- a/drivers/staging/bcm/InterfaceRx.c +++ b/drivers/staging/bcm/InterfaceRx.c @@ -1,5 +1,15 @@ #include "headers.h" -extern int SearchVcid(PMINI_ADAPTER , unsigned short); + +static int SearchVcid(PMINI_ADAPTER Adapter,unsigned short usVcid) +{ + int iIndex=0; + + for(iIndex=(NO_OF_QUEUES-1);iIndex>=0;iIndex--) + if(Adapter->PackInfo[iIndex].usVCID_Value == usVcid) + return iIndex; + return NO_OF_QUEUES+1; + +} static PUSB_RCB @@ -88,8 +98,7 @@ static void read_bulk_callback(struct urb *urb) if (netif_msg_rx_err(Adapter)) pr_info(PFX "%s: corrupted leader length...%d\n", Adapter->dev->name, pLeader->PLength); - atomic_inc(&Adapter->RxPacketDroppedCount); - atomic_add(pLeader->PLength, &Adapter->BadRxByteCount); + ++Adapter->dev->stats.rx_dropped; atomic_dec(&psIntfAdapter->uNumRcbUsed); return; } @@ -142,7 +151,6 @@ static void read_bulk_callback(struct urb *urb) skb_put (skb, pLeader->PLength + ETH_HLEN); Adapter->PackInfo[QueueIndex].uiTotalRxBytes+=pLeader->PLength; Adapter->PackInfo[QueueIndex].uiThisPeriodRxBytes+= pLeader->PLength; - atomic_add(pLeader->PLength, &Adapter->GoodRxByteCount); BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_RX, RX_DATA, DBG_LVL_ALL, "Recived Data pkt of len :0x%X", pLeader->PLength); if(netif_running(Adapter->dev)) @@ -172,7 +180,10 @@ static void read_bulk_callback(struct urb *urb) BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_RX, RX_DATA, DBG_LVL_ALL, "i/f not up hance freeing SKB..."); dev_kfree_skb(skb); } - atomic_inc(&Adapter->GoodRxPktCount); + + ++Adapter->dev->stats.rx_packets; + Adapter->dev->stats.rx_bytes += pLeader->PLength; + for(uiIndex = 0 ; uiIndex < MIBS_MAX_HIST_ENTRIES ; uiIndex++) { if((pLeader->PLength <= MIBS_PKTSIZEHIST_RANGE*(uiIndex+1)) diff --git a/drivers/staging/bcm/Misc.c b/drivers/staging/bcm/Misc.c index 2f849b2a1275..c1d73a70f9e4 100644 --- a/drivers/staging/bcm/Misc.c +++ b/drivers/staging/bcm/Misc.c @@ -1859,8 +1859,6 @@ void flush_queue(PMINI_ADAPTER Adapter, UINT iQIndex) dev_kfree_skb(PacketToDrop); atomic_dec(&Adapter->TotalPacketCount); - atomic_inc(&Adapter->TxDroppedPacketCount); - } } spin_unlock_bh(&Adapter->PackInfo[iQIndex].SFQueueLock); diff --git a/drivers/staging/bcm/Prototypes.h b/drivers/staging/bcm/Prototypes.h index c27fce875be7..ba0444e70577 100644 --- a/drivers/staging/bcm/Prototypes.h +++ b/drivers/staging/bcm/Prototypes.h @@ -93,8 +93,6 @@ void beceem_parse_target_struct(PMINI_ADAPTER Adapter); int bcm_ioctl_fw_download(PMINI_ADAPTER Adapter, FIRMWARE_INFO *psFwInfo); -int SearchVcid(PMINI_ADAPTER Adapter,unsigned short usVcid); - void CopyMIBSExtendedSFParameters(PMINI_ADAPTER Adapter, CServiceFlowParamSI *psfLocalSet, UINT uiSearchRuleIndex); diff --git a/drivers/staging/bcm/Qos.c b/drivers/staging/bcm/Qos.c index e4d5a67c8c6b..88ec3b20742d 100644 --- a/drivers/staging/bcm/Qos.c +++ b/drivers/staging/bcm/Qos.c @@ -359,12 +359,13 @@ static VOID PruneQueue(PMINI_ADAPTER Adapter, INT iIndex) if(PacketToDrop) { + struct netdev_queue *txq = netdev_get_tx_queue(Adapter->dev, iIndex); if (netif_msg_tx_err(Adapter)) pr_info(PFX "%s: tx queue %d overlimit\n", Adapter->dev->name, iIndex); - netstats->tx_dropped++; - atomic_inc(&Adapter->TxDroppedPacketCount); + txq->tx_dropped++; + DEQUEUEPACKET(Adapter->PackInfo[iIndex].FirstTxQueue, Adapter->PackInfo[iIndex].LastTxQueue); /// update current bytes and packets count @@ -397,14 +398,15 @@ VOID flush_all_queues(PMINI_ADAPTER Adapter) { INT iQIndex; UINT uiTotalPacketLength; - struct sk_buff* PacketToDrop=NULL; - struct net_device_stats* netstats=&Adapter->dev->stats; + struct sk_buff* PacketToDrop=NULL; BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, DUMP_INFO, DBG_LVL_ALL, "=====>"); // down(&Adapter->data_packet_queue_lock); for(iQIndex=LowPriority; iQIndexdev, iQIndex); + spin_lock_bh(&Adapter->PackInfo[iQIndex].SFQueueLock); while(Adapter->PackInfo[iQIndex].FirstTxQueue) { @@ -412,8 +414,7 @@ VOID flush_all_queues(PMINI_ADAPTER Adapter) if(PacketToDrop) { uiTotalPacketLength = PacketToDrop->len; - netstats->tx_dropped++; - atomic_inc(&Adapter->TxDroppedPacketCount); + txq->tx_dropped++; } else uiTotalPacketLength = 0; diff --git a/drivers/staging/bcm/Transmit.c b/drivers/staging/bcm/Transmit.c index b924a6a4dd78..972e6ab6fae6 100644 --- a/drivers/staging/bcm/Transmit.c +++ b/drivers/staging/bcm/Transmit.c @@ -90,7 +90,7 @@ INT SetupNextSend(PMINI_ADAPTER Adapter, struct sk_buff *Packet, USHORT Vcid) int status=0; BOOLEAN bHeaderSupressionEnabled = FALSE; B_UINT16 uiClassifierRuleID; - int QueueIndex = NO_OF_QUEUES + 1; + u16 QueueIndex = skb_get_queue_mapping(Packet); LEADER Leader={0}; if(Packet->len > MAX_DEVICE_DESC_SIZE) @@ -101,14 +101,10 @@ INT SetupNextSend(PMINI_ADAPTER Adapter, struct sk_buff *Packet, USHORT Vcid) /* Get the Classifier Rule ID */ uiClassifierRuleID = *((UINT32*) (Packet->cb)+SKB_CB_CLASSIFICATION_OFFSET); - QueueIndex = SearchVcid( Adapter,Vcid); - if(QueueIndex < NO_OF_QUEUES) - { - bHeaderSupressionEnabled = - Adapter->PackInfo[QueueIndex].bHeaderSuppressionEnabled; - bHeaderSupressionEnabled = - bHeaderSupressionEnabled & Adapter->bPHSEnabled; - } + + bHeaderSupressionEnabled = Adapter->PackInfo[QueueIndex].bHeaderSuppressionEnabled + & Adapter->bPHSEnabled; + if(Adapter->device_removed) { status = STATUS_FAILURE; @@ -162,9 +158,12 @@ INT SetupNextSend(PMINI_ADAPTER Adapter, struct sk_buff *Packet, USHORT Vcid) } else { + struct netdev_queue *txq = netdev_get_tx_queue(Adapter->dev, QueueIndex); Adapter->PackInfo[QueueIndex].uiTotalTxBytes += Leader.PLength; - Adapter->dev->stats.tx_bytes += Leader.PLength; - ++Adapter->dev->stats.tx_packets; + + txq->tx_bytes += Leader.PLength; + ++txq->tx_packets; + Adapter->PackInfo[QueueIndex].uiCurrentTokenCount -= Leader.PLength << 3; Adapter->PackInfo[QueueIndex].uiSentBytes += (Packet->len); Adapter->PackInfo[QueueIndex].uiSentPackets++; diff --git a/drivers/staging/bcm/hostmibs.c b/drivers/staging/bcm/hostmibs.c index 144590037b24..c13ea5c9a2aa 100644 --- a/drivers/staging/bcm/hostmibs.c +++ b/drivers/staging/bcm/hostmibs.c @@ -82,12 +82,9 @@ INT ProcessGetHostMibs(PMINI_ADAPTER Adapter, S_MIBS_HOST_STATS_MIBS *pstHostMi } - //copy other Host Statistics parameters - pstHostMibs->stHostInfo.GoodTransmits = - atomic_read(&Adapter->TxTotalPacketCount); - pstHostMibs->stHostInfo.GoodReceives = - atomic_read(&Adapter->GoodRxPktCount); + pstHostMibs->stHostInfo.GoodTransmits = Adapter->dev->stats.tx_packets; + pstHostMibs->stHostInfo.GoodReceives = Adapter->dev->stats.rx_packets; pstHostMibs->stHostInfo.CurrNumFreeDesc = atomic_read(&Adapter->CurrNumFreeTxDesc); pstHostMibs->stHostInfo.BEBucketSize = Adapter->BEBucketSize; diff --git a/drivers/staging/bcm/led_control.c b/drivers/staging/bcm/led_control.c index a21d219f428c..16e939fa15d6 100644 --- a/drivers/staging/bcm/led_control.c +++ b/drivers/staging/bcm/led_control.c @@ -108,8 +108,9 @@ static INT LED_Proportional_Blink(PMINI_ADAPTER Adapter, UCHAR GPIO_Num_tx, ulong timeout = 0; /*Read initial value of packets sent/received */ - Initial_num_of_packts_tx = atomic_read(&Adapter->TxTotalPacketCount); - Initial_num_of_packts_rx = atomic_read(&Adapter->GoodRxPktCount); + Initial_num_of_packts_tx = Adapter->dev->stats.tx_packets; + Initial_num_of_packts_rx = Adapter->dev->stats.rx_packets; + /*Scale the rate of transfer to no of blinks.*/ num_of_time_tx= ScaleRateofTransfer((ULONG)rate_of_transfer_tx); num_of_time_rx= ScaleRateofTransfer((ULONG)rate_of_transfer_rx); @@ -212,9 +213,10 @@ static INT LED_Proportional_Blink(PMINI_ADAPTER Adapter, UCHAR GPIO_Num_tx, * Read the Tx & Rx packets transmission after 1 second and * calculate rate of transfer */ - Final_num_of_packts_tx = atomic_read(&Adapter->TxTotalPacketCount); + Final_num_of_packts_tx = Adapter->dev->stats.tx_packets; + Final_num_of_packts_rx = Adapter->dev->stats.rx_packets; + rate_of_transfer_tx = Final_num_of_packts_tx - Initial_num_of_packts_tx; - Final_num_of_packts_rx = atomic_read(&Adapter->GoodRxPktCount); rate_of_transfer_rx = Final_num_of_packts_rx - Initial_num_of_packts_rx; /*Read initial value of packets sent/received */ -- cgit v1.2.3 From 78afa9990fdbbf01227104300a657be3f3caa167 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Mon, 1 Nov 2010 13:54:21 -0400 Subject: beceem: fix definition of VLAN header type Signed-off-by: Stephen Hemminger --- drivers/staging/bcm/Protocol.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/bcm/Protocol.h b/drivers/staging/bcm/Protocol.h index 00f1cc12356a..b8a4009bdf0c 100644 --- a/drivers/staging/bcm/Protocol.h +++ b/drivers/staging/bcm/Protocol.h @@ -85,10 +85,10 @@ typedef struct _ETH_CS_ETH2_FRAME ETH_HEADER_STRUC EThHdr; } __attribute__((packed)) ETH_CS_ETH2_FRAME; +#define ETHERNET_FRAMETYPE_IPV4 ntohs(0x0800) +#define ETHERNET_FRAMETYPE_IPV6 ntohs(0x86dd) +#define ETHERNET_FRAMETYPE_802QVLAN ntohs(0x8100) -#define ETHERNET_FRAMETYPE_IPV4 ntohs(0x0800) -#define ETHERNET_FRAMETYPE_IPV6 ntohs(0x86dd) -#define ETHERNET_FRAMETYPE_802QVLAN 0x8100 //Per SF CS Specification Encodings typedef enum _E_SERVICEFLOW_CS_SPEC_ { -- cgit v1.2.3 From 5cf084f44ac24189ef3373010da49e26d651aa06 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Mon, 1 Nov 2010 13:57:35 -0400 Subject: beceem: eliminate unused bcm_jiffies Unused, unneeded, and bogus. Signed-off-by: Stephen Hemminger --- drivers/staging/bcm/Adapter.h | 1 - drivers/staging/bcm/LeakyBucket.c | 24 +++--------------------- drivers/staging/bcm/Qos.c | 1 - drivers/staging/bcm/Transmit.c | 6 ------ 4 files changed, 3 insertions(+), 29 deletions(-) diff --git a/drivers/staging/bcm/Adapter.h b/drivers/staging/bcm/Adapter.h index 5e97cbeb58ec..62f9135d4d40 100644 --- a/drivers/staging/bcm/Adapter.h +++ b/drivers/staging/bcm/Adapter.h @@ -404,7 +404,6 @@ struct _MINI_ADAPTER PPER_TARANG_DATA pTarangs; spinlock_t control_queue_lock; wait_queue_head_t process_read_wait_queue; - ULONG bcm_jiffies; /* Store Jiffies value */ // the pointer to the first packet we have queued in send // deserialized miniport support variables diff --git a/drivers/staging/bcm/LeakyBucket.c b/drivers/staging/bcm/LeakyBucket.c index 669acc8d088b..f4cf41c0e46b 100644 --- a/drivers/staging/bcm/LeakyBucket.c +++ b/drivers/staging/bcm/LeakyBucket.c @@ -172,10 +172,8 @@ static VOID CheckAndSendPacketFromIndex(PMINI_ADAPTER Adapter, PacketInfo *psSF) BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "UpdateTokenCount "); if(Adapter->IdleMode || Adapter->bPreparingForLowPowerMode) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Device is in Idle Mode..Hence blocking Data Packets..\n"); - return; - } + return; /* in idle mode */ + // Check for Free Descriptors if(atomic_read(&Adapter->CurrNumFreeTxDesc) <= MINIMUM_PENDING_DESCRIPTORS) { @@ -262,17 +260,6 @@ static VOID CheckAndSendPacketFromIndex(PMINI_ADAPTER Adapter, PacketInfo *psSF) } } } - - if(Status != STATUS_SUCCESS) //Tx of data packet to device Failed - { - if(Adapter->bcm_jiffies == 0) - Adapter->bcm_jiffies = jiffies; - } - else - { - Adapter->bcm_jiffies = 0; - } - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "<====="); } @@ -359,12 +346,7 @@ VOID transmit_packets(PMINI_ADAPTER Adapter) if(exit_flag == TRUE ) break ; }/* end of inner while loop */ - if(Adapter->bcm_jiffies == 0 && - atomic_read(&Adapter->TotalPacketCount) != 0 && - uiPrevTotalCount == atomic_read(&Adapter->TotalPacketCount)) - { - Adapter->bcm_jiffies = jiffies; - } + update_per_cid_rx (Adapter); Adapter->txtransmit_running = 0; BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_PACKETS, DBG_LVL_ALL, "<======"); diff --git a/drivers/staging/bcm/Qos.c b/drivers/staging/bcm/Qos.c index 88ec3b20742d..8ce4536e6e28 100644 --- a/drivers/staging/bcm/Qos.c +++ b/drivers/staging/bcm/Qos.c @@ -384,7 +384,6 @@ static VOID PruneQueue(PMINI_ADAPTER Adapter, INT iIndex) Adapter->PackInfo[iIndex].uiDroppedCountPackets); atomic_dec(&Adapter->TotalPacketCount); - Adapter->bcm_jiffies = jiffies; } spin_unlock_bh(&Adapter->PackInfo[iIndex].SFQueueLock); diff --git a/drivers/staging/bcm/Transmit.c b/drivers/staging/bcm/Transmit.c index 972e6ab6fae6..652ba27407af 100644 --- a/drivers/staging/bcm/Transmit.c +++ b/drivers/staging/bcm/Transmit.c @@ -55,12 +55,6 @@ INT SendControlPacket(PMINI_ADAPTER Adapter, char *pControlPacket) ((PLeader->PLength-1)/MAX_DEVICE_DESC_SIZE)+1)) { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "NO FREE DESCRIPTORS TO SEND CONTROL PACKET"); - if(Adapter->bcm_jiffies == 0) - { - Adapter->bcm_jiffies = jiffies; - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "UPDATED TIME(hex): %lu", - Adapter->bcm_jiffies); - } return STATUS_FAILURE; } -- cgit v1.2.3 From 473f89fff76568a9f30c53b458e6323d48b0ab95 Mon Sep 17 00:00:00 2001 From: Jarkko Nikula Date: Fri, 29 Oct 2010 16:47:44 +0300 Subject: ASoC: Fix SND_SOC_ALL_CODECS typo for alc5623 Include alc5623.c in SND_SOC_ALL_CODECS when dependencies are met. Signed-off-by: Jarkko Nikula Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/codecs/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index 8d11fbd1b1aa..e61fbab48aa2 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -22,7 +22,7 @@ config SND_SOC_ALL_CODECS select SND_SOC_AK4535 if I2C select SND_SOC_AK4642 if I2C select SND_SOC_AK4671 if I2C - select SND_SOC_ALC562 if I2C + select SND_SOC_ALC5623 if I2C select SND_SOC_CQ0093VC if MFD_DAVINCI_VOICECODEC select SND_SOC_CS42L51 if I2C select SND_SOC_CS4270 if I2C -- cgit v1.2.3 From 9c5d77009db6ff09d02a7b0a99a70c0dfd3af6c6 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Mon, 1 Nov 2010 13:59:01 -0400 Subject: beceem: don't overrun user buffer on read Serious bug in original code, if app reads 10 bytes but 20 byte msg received memory would get overwritten. Signed-off-by: Stephen Hemminger --- drivers/staging/bcm/Bcmchar.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/bcm/Bcmchar.c b/drivers/staging/bcm/Bcmchar.c index 1a255609aeda..8089d19e6c1b 100644 --- a/drivers/staging/bcm/Bcmchar.c +++ b/drivers/staging/bcm/Bcmchar.c @@ -139,7 +139,7 @@ static ssize_t bcm_char_read(struct file *filp, char __user *buf, size_t size, l if(Packet) { PktLen = Packet->len; - if(copy_to_user(buf, Packet->data, PktLen)) + if(copy_to_user(buf, Packet->data, min_t(size_t, PktLen, size))) { dev_kfree_skb(Packet); BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "\nReturning from copy to user failure \n"); -- cgit v1.2.3 From 4ea4f7a0d3d7a9961bf77f0860df8dd4a213b8a3 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Mon, 1 Nov 2010 14:06:24 -0400 Subject: beceem: change startup messages Change the regsister/unregister routines to generate better messages, and control arrival of new frames when USB device is unplugged. Signed-off-by: Stephen Hemminger --- drivers/staging/bcm/Bcmnet.c | 52 ++++++++++++++++++++++++------------- drivers/staging/bcm/InterfaceInit.c | 32 +++++++++++------------ drivers/staging/bcm/Misc.c | 2 +- drivers/staging/bcm/Prototypes.h | 1 + drivers/staging/bcm/nvm.c | 32 +++-------------------- 5 files changed, 56 insertions(+), 63 deletions(-) diff --git a/drivers/staging/bcm/Bcmnet.c b/drivers/staging/bcm/Bcmnet.c index eb224a9dafab..a6ce2396c791 100644 --- a/drivers/staging/bcm/Bcmnet.c +++ b/drivers/staging/bcm/Bcmnet.c @@ -1,14 +1,5 @@ #include "headers.h" -static int debug = -1; -module_param(debug, uint, 0600); -MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)"); - -static const u32 default_msg = - NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_LINK - | NETIF_MSG_TIMER | NETIF_MSG_TX_ERR | NETIF_MSG_RX_ERR - | NETIF_MSG_IFUP | NETIF_MSG_IFDOWN; - struct net_device *gblpnetdev; static INT bcm_open(struct net_device *dev) @@ -194,6 +185,10 @@ static const struct ethtool_ops bcm_ethtool_ops = { int register_networkdev(PMINI_ADAPTER Adapter) { struct net_device *net = Adapter->dev; + PS_INTERFACE_ADAPTER IntfAdapter = Adapter->pvInterfaceAdapter; + struct usb_interface *udev = IntfAdapter->interface; + struct usb_device *xdev = IntfAdapter->udev; + int result; net->netdev_ops = &bcmNetDevOps; @@ -201,22 +196,43 @@ int register_networkdev(PMINI_ADAPTER Adapter) net->mtu = MTU_SIZE; /* 1400 Bytes */ net->tx_queue_len = TX_QLEN; net->flags |= IFF_NOARP; - Adapter->msg_enable = netif_msg_init(debug, default_msg); netif_carrier_off(net); SET_NETDEV_DEVTYPE(net, &wimax_type); /* Read the MAC Address from EEPROM */ - ReadMacAddressFromNVM(Adapter); + result = ReadMacAddressFromNVM(Adapter); + if (result != STATUS_SUCCESS) { + dev_err(&udev->dev, + PFX "Error in Reading the mac Address: %d", result); + return -EIO; + } result = register_netdev(net); - if (result == 0) - gblpnetdev = Adapter->dev = net; - else { - Adapter->dev = NULL; - free_netdev(net); - } + if (result) + return result; + + gblpnetdev = Adapter->dev; - return result; + if (netif_msg_probe(Adapter)) + dev_info(&udev->dev, PFX "%s: register usb-%s-%s %pM\n", + net->name, xdev->bus->bus_name, xdev->devpath, + net->dev_addr); + + return 0; +} + +void unregister_networkdev(PMINI_ADAPTER Adapter) +{ + struct net_device *net = Adapter->dev; + PS_INTERFACE_ADAPTER IntfAdapter = Adapter->pvInterfaceAdapter; + struct usb_interface *udev = IntfAdapter->interface; + struct usb_device *xdev = IntfAdapter->udev; + + if (netif_msg_probe(Adapter)) + dev_info(&udev->dev, PFX "%s: unregister usb-%s%s\n", + net->name, xdev->bus->bus_name, xdev->devpath); + + unregister_netdev(Adapter->dev); } diff --git a/drivers/staging/bcm/InterfaceInit.c b/drivers/staging/bcm/InterfaceInit.c index a64092e940cc..8a26a3ef5bd3 100644 --- a/drivers/staging/bcm/InterfaceInit.c +++ b/drivers/staging/bcm/InterfaceInit.c @@ -11,6 +11,15 @@ static struct usb_device_id InterfaceUsbtable[] = { }; MODULE_DEVICE_TABLE(usb, InterfaceUsbtable); +static int debug = -1; +module_param(debug, uint, 0600); +MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)"); + +static const u32 default_msg = + NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_LINK + | NETIF_MSG_TIMER | NETIF_MSG_TX_ERR | NETIF_MSG_RX_ERR + | NETIF_MSG_IFUP | NETIF_MSG_IFDOWN; + static INT InterfaceAdapterInit(PS_INTERFACE_ADAPTER Adapter); static VOID InterfaceAdapterFree(PS_INTERFACE_ADAPTER psIntfAdapter) @@ -158,6 +167,7 @@ usbbcm_device_probe(struct usb_interface *intf, const struct usb_device_id *id) psAdapter = netdev_priv(ndev); psAdapter->dev = ndev; + psAdapter->msg_enable = netif_msg_init(debug, default_msg); /* Init default driver debug state */ @@ -269,32 +279,22 @@ usbbcm_device_probe(struct usb_interface *intf, const struct usb_device_id *id) static void usbbcm_disconnect (struct usb_interface *intf) { - PS_INTERFACE_ADAPTER psIntfAdapter = NULL; - PMINI_ADAPTER psAdapter = NULL; - struct usb_device *udev = NULL; - PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); + PS_INTERFACE_ADAPTER psIntfAdapter = usb_get_intfdata(intf); + PMINI_ADAPTER psAdapter; + struct usb_device *udev = interface_to_usbdev (intf); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Usb disconnected"); - if(intf == NULL) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "intf pointer is NULL"); - return; - } - psIntfAdapter = usb_get_intfdata(intf); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "psIntfAdapter 0x%p",psIntfAdapter); if(psIntfAdapter == NULL) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "InterfaceAdapter pointer is NULL"); return; - } + psAdapter = psIntfAdapter->psAdapter; + netif_device_detach(psAdapter->dev); + if(psAdapter->bDoSuspend) intf->needs_remote_wakeup = 0; psAdapter->device_removed = TRUE ; usb_set_intfdata(intf, NULL); InterfaceAdapterFree(psIntfAdapter); - udev = interface_to_usbdev (intf); usb_put_dev(udev); } diff --git a/drivers/staging/bcm/Misc.c b/drivers/staging/bcm/Misc.c index c1d73a70f9e4..82d9f86821ca 100644 --- a/drivers/staging/bcm/Misc.c +++ b/drivers/staging/bcm/Misc.c @@ -132,7 +132,7 @@ VOID AdapterFree(PMINI_ADAPTER Adapter) if(Adapter->LEDInfo.led_thread_running & (BCM_LED_THREAD_RUNNING_ACTIVELY | BCM_LED_THREAD_RUNNING_INACTIVELY)) kthread_stop (Adapter->LEDInfo.led_cntrl_threadid); - unregister_netdev(Adapter->dev); + unregister_networkdev(Adapter); /* FIXME: use proper wait_event and refcounting */ while(atomic_read(&Adapter->ApplicationRunning)) diff --git a/drivers/staging/bcm/Prototypes.h b/drivers/staging/bcm/Prototypes.h index ba0444e70577..b80b806c90a3 100644 --- a/drivers/staging/bcm/Prototypes.h +++ b/drivers/staging/bcm/Prototypes.h @@ -52,6 +52,7 @@ INT SendControlPacket(PMINI_ADAPTER Adapter, /**dev->dev_addr, puMacAddr, MAC_ADDRESS_SIZE); - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Modem MAC Addr :"); - BCM_DEBUG_PRINT_BUFFER(Adapter,DBG_TYPE_PRINTK, 0, DBG_LVL_ALL,&Adapter->dev->dev_addr[0],MAC_ADDRESS_SIZE); - for(i=0;idev->dev_addr[i] == 0x00) - AllZeroMac++; - if(Adapter->dev->dev_addr[i] == 0xFF) - AllFFMac++; - - } - //BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "\n"); - if(AllZeroMac == MAC_ADDRESS_SIZE) - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Warning :: MAC Address has all 00's"); - if(AllFFMac == MAC_ADDRESS_SIZE) - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, NVM_RW, DBG_LVL_ALL,"Warning :: MAC Address has all FF's"); + if(Status == STATUS_SUCCESS) + memcpy(Adapter->dev->dev_addr, puMacAddr, MAC_ADDRESS_SIZE); return Status; - } //----------------------------------------------------------------------------- -- cgit v1.2.3 From 349fa79498df313c70e2a4b7c16688be0a91dd0b Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Mon, 1 Nov 2010 14:09:05 -0400 Subject: beceem: dump control packet information Add control packet information is useful for debugging. Signed-off-by: Stephen Hemminger --- drivers/staging/bcm/HandleControlPacket.c | 6 ++++-- drivers/staging/bcm/Transmit.c | 5 +++++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/staging/bcm/HandleControlPacket.c b/drivers/staging/bcm/HandleControlPacket.c index e7afa56c0dcf..2b1e9e17e11c 100644 --- a/drivers/staging/bcm/HandleControlPacket.c +++ b/drivers/staging/bcm/HandleControlPacket.c @@ -19,8 +19,10 @@ static VOID handle_rx_control_packet(PMINI_ADAPTER Adapter, struct sk_buff *skb) CHAR cntrl_msg_mask_bit = 0; BOOLEAN drop_pkt_flag = TRUE ; USHORT usStatus = *(PUSHORT)(skb->data); - BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CP_CTRL_PKT, DBG_LVL_ALL, "=====>"); - /* Get the Leader field */ + + if (netif_msg_pktdata(Adapter)) + print_hex_dump(KERN_DEBUG, PFX "rx control: ", DUMP_PREFIX_NONE, + 16, 1, skb->data, skb->len, 0); switch(usStatus) { diff --git a/drivers/staging/bcm/Transmit.c b/drivers/staging/bcm/Transmit.c index 652ba27407af..0f7000960d50 100644 --- a/drivers/staging/bcm/Transmit.c +++ b/drivers/staging/bcm/Transmit.c @@ -65,6 +65,11 @@ INT SendControlPacket(PMINI_ADAPTER Adapter, char *pControlPacket) BCM_DEBUG_PRINT(Adapter,DBG_TYPE_TX, TX_CONTROL, DBG_LVL_ALL, "Leader Length: %x",PLeader->PLength); if(Adapter->device_removed) return 0; + + if (netif_msg_pktdata(Adapter)) + print_hex_dump(KERN_DEBUG, PFX "tx control: ", DUMP_PREFIX_NONE, + 16, 1, pControlPacket, PLeader->PLength + LEADER_SIZE, 0); + Adapter->interface_transmit(Adapter->pvInterfaceAdapter, pControlPacket, (PLeader->PLength + LEADER_SIZE)); -- cgit v1.2.3 From 2932af344a86cb1bd84ca8cc217ee016e8fb5255 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Mon, 1 Nov 2010 14:18:16 -0400 Subject: beceem: update TODO list Signed-off-by: Stephen Hemminger --- drivers/staging/bcm/TODO | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/drivers/staging/bcm/TODO b/drivers/staging/bcm/TODO index 366634be5fe1..cd3e9f2ed87a 100644 --- a/drivers/staging/bcm/TODO +++ b/drivers/staging/bcm/TODO @@ -1,15 +1,22 @@ +This driver is barely functional in its current state. + +BIG: + - existing API is (/dev/tarang) should be replaced + Is it possible to use same API as Intel Wimax stack and + have same user level components. + - Qos and queue model is non-standard and inflexible. + Use existing TC Qos? + TODO: + - support more than one board - eliminate global variables + - remove developer debug BCM_DEBUG() macros + add a limited number of messages through netif_msg() - fix non-standard kernel style - - sparse warnings - checkpatch warnings - - remove compatiablity code for older kernels - - remove #ifdef's - - fix bogus device nameing and reference counting (see bcm_notify_event) - - fix use of file I/O to load config - - request firmware - - update to current network device API - - merge some files together + - use request firmware + - fix use of file I/O to load config with better API + - merge some files together? - cleanup/eliminate debug messages - - integrate with existing Wimax stack? + -- cgit v1.2.3 From 04561c5aa243c98cae93cde27e05740df787e692 Mon Sep 17 00:00:00 2001 From: Ignaz Forster Date: Mon, 1 Nov 2010 15:13:37 -0400 Subject: HID: Add Force Feedback support for EMS Trio Linker Plus II The device has connections for GameCube, PlayStation 2 and Dreamcast controllers, however Force Feedback is only supported for PS2 and GC controllers. When using a PS2 controller it may be necessary to press the "Analog" button to enable support for both motors (this behavior is identical to the Windows driver, I have found no way to avoid that). Signed-off-by: Ignaz Forster Signed-off-by: Jiri Kosina --- drivers/hid/Kconfig | 10 +++ drivers/hid/Makefile | 1 + drivers/hid/hid-core.c | 1 + drivers/hid/hid-emsff.c | 162 ++++++++++++++++++++++++++++++++++++++++++++++++ drivers/hid/hid-ids.h | 3 + 5 files changed, 177 insertions(+) create mode 100644 drivers/hid/hid-emsff.c diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index 3052e2969ad0..3d9a95f28aea 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig @@ -150,6 +150,16 @@ config DRAGONRISE_FF Say Y here if you want to enable force feedback support for DragonRise Inc. game controllers. +config HID_EMS_FF + tristate "EMS Production Inc. force feedback support" + depends on USB_HID + select INPUT_FF_MEMLESS + ---help--- + Say Y here if you want to enable force feedback support for devices by + EMS Production Ltd. + Currently the following devices are known to be supported: + - Trio Linker Plus II + config HID_EGALAX tristate "eGalax multi-touch panel" depends on USB_HID diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile index c335605b9200..86192f67d7c2 100644 --- a/drivers/hid/Makefile +++ b/drivers/hid/Makefile @@ -35,6 +35,7 @@ obj-$(CONFIG_HID_CHERRY) += hid-cherry.o obj-$(CONFIG_HID_CHICONY) += hid-chicony.o obj-$(CONFIG_HID_CYPRESS) += hid-cypress.o obj-$(CONFIG_HID_DRAGONRISE) += hid-drff.o +obj-$(CONFIG_HID_EMS_FF) += hid-emsff.o obj-$(CONFIG_HID_EGALAX) += hid-egalax.o obj-$(CONFIG_HID_ELECOM) += hid-elecom.o obj-$(CONFIG_HID_EZKEY) += hid-ezkey.o diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 7832b6e2478b..b3393e17b375 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -1301,6 +1301,7 @@ static const struct hid_device_id hid_blacklist[] = { { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH) }, { HID_USB_DEVICE(USB_VENDOR_ID_DWAV, USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH1) }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_ELECOM, USB_DEVICE_ID_ELECOM_BM084) }, + { HID_USB_DEVICE(USB_VENDOR_ID_EMS, USB_DEVICE_ID_EMS_TRIO_LINKER_PLUS_II) }, { HID_USB_DEVICE(USB_VENDOR_ID_EZKEY, USB_DEVICE_ID_BTC_8193) }, { HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PSX_ADAPTOR) }, { HID_USB_DEVICE(USB_VENDOR_ID_GAMERON, USB_DEVICE_ID_GAMERON_DUAL_PCS_ADAPTOR) }, diff --git a/drivers/hid/hid-emsff.c b/drivers/hid/hid-emsff.c new file mode 100644 index 000000000000..c61b192d7cff --- /dev/null +++ b/drivers/hid/hid-emsff.c @@ -0,0 +1,162 @@ +/* + * Force feedback support for EMS Trio Linker Plus II + * + * Copyright (c) 2010 Ignaz Forster + */ + +/* + * 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. + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#include +#include +#include + +#include "hid-ids.h" +#include "usbhid/usbhid.h" + +struct emsff_device { + struct hid_report *report; +}; + +static int emsff_play(struct input_dev *dev, void *data, + struct ff_effect *effect) +{ + struct hid_device *hid = input_get_drvdata(dev); + struct emsff_device *emsff = data; + int weak, strong; + + weak = effect->u.rumble.weak_magnitude; + strong = effect->u.rumble.strong_magnitude; + + dbg_hid("called with 0x%04x 0x%04x\n", strong, weak); + + weak = weak * 0xff / 0xffff; + strong = strong * 0xff / 0xffff; + + emsff->report->field[0]->value[1] = weak; + emsff->report->field[0]->value[2] = strong; + + dbg_hid("running with 0x%02x 0x%02x\n", strong, weak); + usbhid_submit_report(hid, emsff->report, USB_DIR_OUT); + + return 0; +} + +static int emsff_init(struct hid_device *hid) +{ + struct emsff_device *emsff; + struct hid_report *report; + struct hid_input *hidinput = list_first_entry(&hid->inputs, + struct hid_input, list); + struct list_head *report_list = + &hid->report_enum[HID_OUTPUT_REPORT].report_list; + struct input_dev *dev = hidinput->input; + int error; + + if (list_empty(report_list)) { + dev_err(&hid->dev, "no output reports found\n"); + return -ENODEV; + } + + report = list_first_entry(report_list, struct hid_report, list); + if (report->maxfield < 1) { + dev_err(&hid->dev, "no fields in the report\n"); + return -ENODEV; + } + + if (report->field[0]->report_count < 7) { + dev_err(&hid->dev, "not enough values in the field\n"); + return -ENODEV; + } + + emsff = kzalloc(sizeof(struct emsff_device), GFP_KERNEL); + if (!emsff) + return -ENOMEM; + + set_bit(FF_RUMBLE, dev->ffbit); + + error = input_ff_create_memless(dev, emsff, emsff_play); + if (error) { + kfree(emsff); + return error; + } + + emsff->report = report; + emsff->report->field[0]->value[0] = 0x01; + emsff->report->field[0]->value[1] = 0x00; + emsff->report->field[0]->value[2] = 0x00; + emsff->report->field[0]->value[3] = 0x00; + emsff->report->field[0]->value[4] = 0x00; + emsff->report->field[0]->value[5] = 0x00; + emsff->report->field[0]->value[6] = 0x00; + usbhid_submit_report(hid, emsff->report, USB_DIR_OUT); + + dev_info(&hid->dev, "force feedback for EMS based devices by " + "Ignaz Forster \n"); + + return 0; +} + +static int ems_probe(struct hid_device *hdev, const struct hid_device_id *id) +{ + int ret; + + ret = hid_parse(hdev); + if (ret) { + dev_err(&hdev->dev, "parse failed\n"); + goto err; + } + + ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT & ~HID_CONNECT_FF); + if (ret) { + dev_err(&hdev->dev, "hw start failed\n"); + goto err; + } + + emsff_init(hdev); + + return 0; +err: + return ret; +} + +static const struct hid_device_id ems_devices[] = { + { HID_USB_DEVICE(USB_VENDOR_ID_EMS, 0x118) }, + { } +}; +MODULE_DEVICE_TABLE(hid, ems_devices); + +static struct hid_driver ems_driver = { + .name = "hkems", + .id_table = ems_devices, + .probe = ems_probe, +}; + +static int ems_init(void) +{ + return hid_register_driver(&ems_driver); +} + +static void ems_exit(void) +{ + hid_unregister_driver(&ems_driver); +} + +module_init(ems_init); +module_exit(ems_exit); +MODULE_LICENSE("GPL"); + diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 3ee999d33004..68114dbcd895 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -203,6 +203,9 @@ #define USB_VENDOR_ID_ELO 0x04E7 #define USB_DEVICE_ID_ELO_TS2700 0x0020 +#define USB_VENDOR_ID_EMS 0x2006 +#define USB_DEVICE_ID_EMS_TRIO_LINKER_PLUS_II 0x0118 + #define USB_VENDOR_ID_ESSENTIAL_REALITY 0x0d7f #define USB_DEVICE_ID_ESSENTIAL_REALITY_P5 0x0100 -- cgit v1.2.3 From 6aaccece1c483f189f76f1282b3984ff4c7ecb0a Mon Sep 17 00:00:00 2001 From: Michael Witten Date: Mon, 1 Nov 2010 17:50:12 +0000 Subject: Kconfig: typo: and -> an Signed-off-by: Michael Witten Signed-off-by: Jiri Kosina --- fs/notify/fanotify/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/notify/fanotify/Kconfig b/fs/notify/fanotify/Kconfig index 3ac36b7bf6b9..7dceff005a67 100644 --- a/fs/notify/fanotify/Kconfig +++ b/fs/notify/fanotify/Kconfig @@ -6,7 +6,7 @@ config FANOTIFY ---help--- Say Y here to enable fanotify suport. fanotify is a file access notification system which differs from inotify in that it sends - and open file descriptor to the userspace listener along with + an open file descriptor to the userspace listener along with the event. If unsure, say Y. -- cgit v1.2.3 From b595076a180a56d1bb170e6eceda6eb9d76f4cd3 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Mon, 1 Nov 2010 15:38:34 -0400 Subject: tree-wide: fix comment/printk typos MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit "gadget", "through", "command", "maintain", "maintain", "controller", "address", "between", "initiali[zs]e", "instead", "function", "select", "already", "equal", "access", "management", "hierarchy", "registration", "interest", "relative", "memory", "offset", "already", Signed-off-by: Uwe Kleine-König Signed-off-by: Jiri Kosina --- Documentation/DocBook/mtdnand.tmpl | 2 +- Documentation/cgroups/cgroup_event_listener.c | 2 +- Documentation/cgroups/memcg_test.txt | 2 +- Documentation/kprobes.txt | 2 +- Documentation/kvm/api.txt | 2 +- Documentation/networking/caif/spi_porting.txt | 2 +- Documentation/powerpc/booting-without-of.txt | 2 +- Documentation/scsi/ChangeLog.lpfc | 2 +- Documentation/timers/timer_stats.txt | 2 +- arch/arm/common/it8152.c | 2 +- arch/arm/common/vic.c | 2 +- arch/arm/mach-at91/board-ecbat91.c | 6 +++--- arch/arm/mach-bcmring/csp/chipc/chipcHw.c | 2 +- arch/arm/mach-bcmring/csp/dmac/dmacHw.c | 2 +- arch/arm/mach-bcmring/csp/dmac/dmacHw_extra.c | 2 +- arch/arm/mach-bcmring/csp/tmr/tmrHw.c | 2 +- arch/arm/mach-bcmring/dma.c | 2 +- arch/arm/mach-bcmring/include/csp/dmacHw.h | 2 +- arch/arm/mach-bcmring/include/mach/csp/dmacHw_priv.h | 2 +- arch/arm/mach-bcmring/include/mach/csp/dmacHw_reg.h | 2 +- arch/arm/mach-gemini/include/mach/hardware.h | 2 +- arch/arm/mach-msm/io.c | 2 +- arch/arm/mach-omap2/cpuidle34xx.c | 2 +- arch/arm/mach-omap2/serial.c | 2 +- arch/arm/mach-pxa/mxm8x10.c | 2 +- arch/arm/mach-s3c64xx/dma.c | 2 +- arch/arm/mach-spear3xx/spear300.c | 4 ++-- arch/arm/mach-spear3xx/spear310.c | 2 +- arch/arm/mach-spear3xx/spear320.c | 2 +- arch/arm/mach-spear3xx/spear3xx.c | 6 +++--- arch/arm/mach-spear6xx/spear6xx.c | 4 ++-- arch/arm/mach-u300/Kconfig | 2 +- arch/arm/mach-u300/include/mach/coh901318.h | 4 ++-- arch/arm/plat-mxc/include/mach/irqs.h | 2 +- arch/arm/plat-omap/include/plat/omap_hwmod.h | 2 +- arch/blackfin/mach-bf518/include/mach/defBF51x_base.h | 2 +- arch/blackfin/mach-bf527/include/mach/defBF52x_base.h | 2 +- arch/blackfin/mach-bf537/include/mach/defBF534.h | 2 +- arch/blackfin/mach-bf538/include/mach/defBF539.h | 2 +- arch/cris/arch-v32/lib/nand_init.S | 2 +- arch/cris/include/asm/etraxgpio.h | 2 +- arch/h8300/Kconfig.debug | 2 +- arch/ia64/kvm/mmio.c | 2 +- arch/mips/alchemy/common/power.c | 2 +- arch/mips/include/asm/mach-powertv/ioremap.h | 2 +- arch/mips/jz4740/board-qi_lb60.c | 4 ++-- arch/mips/jz4740/gpio.c | 2 +- arch/mips/mti-malta/malta-memory.c | 2 +- arch/mips/pci/pcie-octeon.c | 2 +- arch/mips/powertv/memory.c | 2 +- arch/mips/txx9/generic/pci.c | 2 +- arch/powerpc/include/asm/8xx_immap.h | 4 ++-- arch/powerpc/oprofile/op_model_cell.c | 2 +- arch/powerpc/platforms/83xx/suspend-asm.S | 6 +++--- arch/powerpc/platforms/ps3/device-init.c | 4 ++-- arch/powerpc/platforms/ps3/interrupt.c | 2 +- arch/sh/mm/cache-sh5.c | 2 +- arch/sparc/kernel/traps_64.c | 2 +- arch/x86/include/asm/pgalloc.h | 2 +- arch/x86/include/asm/processor.h | 2 +- arch/x86/kernel/amd_iommu.c | 4 ++-- arch/x86/kernel/early_printk_mrst.c | 2 +- arch/x86/kernel/head_32.S | 2 +- block/cfq-iosched.c | 2 +- drivers/acpi/acpica/acobject.h | 2 +- drivers/ata/libata-core.c | 4 ++-- drivers/ata/sata_vsc.c | 2 +- drivers/atm/idt77252.h | 2 +- drivers/atm/iphase.c | 4 ++-- drivers/base/power/main.c | 2 +- drivers/dma/intel_mid_dma.c | 6 +++--- drivers/edac/amd8131_edac.h | 2 +- drivers/edac/cell_edac.c | 4 ++-- drivers/edac/edac_core.h | 2 +- drivers/edac/ppc4xx_edac.c | 6 +++--- drivers/gpu/drm/radeon/atombios.h | 2 +- drivers/i2c/busses/i2c-nomadik.c | 4 ++-- drivers/infiniband/hw/cxgb3/cxio_wr.h | 2 +- drivers/infiniband/hw/qib/qib_iba7322.c | 2 +- drivers/input/touchscreen/Kconfig | 2 +- drivers/isdn/gigaset/bas-gigaset.c | 4 ++-- drivers/isdn/gigaset/ser-gigaset.c | 4 ++-- drivers/isdn/gigaset/usb-gigaset.c | 4 ++-- drivers/isdn/hardware/mISDN/ipac.h | 4 ++-- drivers/isdn/hardware/mISDN/isar.h | 2 +- drivers/isdn/hisax/isar.c | 4 ++-- drivers/media/video/cx25840/cx25840-ir.c | 2 +- drivers/media/video/davinci/vpif.h | 2 +- drivers/media/video/davinci/vpss.c | 2 +- drivers/media/video/omap/omap_vout.c | 2 +- drivers/media/video/saa7164/saa7164-core.c | 4 ++-- drivers/media/video/sn9c102/sn9c102_sensor.h | 2 +- drivers/media/video/zoran/zoran.h | 2 +- drivers/message/fusion/lsi/mpi_log_sas.h | 2 +- drivers/message/fusion/mptbase.c | 2 +- drivers/message/fusion/mptsas.c | 2 +- drivers/message/i2o/i2o_block.c | 2 +- drivers/misc/arm-charlcd.c | 2 +- drivers/mmc/card/block.c | 2 +- drivers/mmc/host/Kconfig | 2 +- drivers/mmc/host/au1xmmc.c | 2 +- drivers/mmc/host/sdricoh_cs.c | 4 ++-- drivers/mtd/nand/nand_base.c | 2 +- drivers/net/bnx2x/bnx2x_main.c | 2 +- drivers/net/bnx2x/bnx2x_reg.h | 2 +- drivers/net/bonding/bond_3ad.c | 6 +++--- drivers/net/chelsio/subr.c | 2 +- drivers/net/cxgb3/mc5.c | 2 +- drivers/net/cxgb3/t3_hw.c | 2 +- drivers/net/e1000/e1000_hw.h | 2 +- drivers/net/e1000/e1000_main.c | 2 +- drivers/net/e1000e/82571.c | 2 +- drivers/net/e1000e/ich8lan.c | 2 +- drivers/net/e1000e/phy.c | 2 +- drivers/net/eepro.c | 2 +- drivers/net/irda/donauboe.h | 2 +- drivers/net/ixgbe/ixgbe_82599.c | 4 ++-- drivers/net/ll_temac_main.c | 2 +- drivers/net/sis900.c | 2 +- drivers/net/tehuti.c | 6 +++--- drivers/net/tun.c | 2 +- drivers/net/vxge/vxge-traffic.h | 2 +- drivers/net/wan/dscc4.c | 2 +- drivers/net/wimax/i2400m/driver.c | 2 +- drivers/net/wimax/i2400m/i2400m.h | 2 +- drivers/net/wireless/ath/ath5k/reg.h | 6 +++--- drivers/net/wireless/b43/phy_g.c | 2 +- drivers/net/wireless/b43legacy/phy.c | 2 +- drivers/net/wireless/iwlwifi/iwl-sta.c | 2 +- drivers/net/wireless/prism54/islpci_dev.c | 6 +++--- drivers/net/wireless/prism54/islpci_eth.c | 2 +- drivers/net/wireless/rt2x00/rt2x00mac.c | 2 +- drivers/net/wireless/wl3501_cs.c | 2 +- drivers/pcmcia/m32r_cfc.h | 2 +- drivers/pcmcia/m32r_pcc.h | 2 +- drivers/pcmcia/m8xx_pcmcia.c | 2 +- drivers/platform/x86/thinkpad_acpi.c | 2 +- drivers/power/s3c_adc_battery.c | 4 ++-- drivers/s390/net/lcs.c | 2 +- drivers/s390/scsi/zfcp_cfdc.c | 2 +- drivers/scsi/a100u2w.c | 2 +- drivers/scsi/aacraid/commsup.c | 2 +- drivers/scsi/aic7xxx_old/aic7xxx.seq | 2 +- drivers/scsi/aic94xx/aic94xx_reg_def.h | 4 ++-- drivers/scsi/aic94xx/aic94xx_seq.c | 6 +++--- drivers/scsi/bfa/bfa_fcpim.c | 2 +- drivers/scsi/bfa/bfa_fcs_lport.c | 2 +- drivers/scsi/dc395x.c | 8 ++++---- drivers/scsi/libfc/fc_fcp.c | 2 +- drivers/scsi/lpfc/lpfc_attr.c | 2 +- drivers/scsi/lpfc/lpfc_hbadisc.c | 2 +- drivers/scsi/lpfc/lpfc_sli.c | 2 +- drivers/scsi/megaraid.h | 2 +- drivers/scsi/pm8001/pm8001_init.c | 2 +- drivers/scsi/scsi_netlink.c | 2 +- drivers/scsi/sym53c8xx_2/sym_glue.c | 2 +- drivers/spi/atmel_spi.c | 4 ++-- drivers/spi/spidev.c | 2 +- drivers/staging/stradis/stradis.c | 2 +- drivers/usb/gadget/imx_udc.c | 2 +- drivers/usb/host/imx21-hcd.c | 2 +- drivers/usb/host/oxu210hp-hcd.c | 2 +- drivers/usb/misc/adutux.c | 2 +- drivers/usb/misc/iowarrior.c | 2 +- drivers/usb/misc/ldusb.c | 2 +- drivers/usb/musb/musb_gadget.c | 4 ++-- drivers/usb/wusbcore/wa-rpipe.c | 2 +- drivers/video/sstfb.c | 2 +- fs/ext4/ext4.h | 2 +- fs/ext4/extents.c | 4 ++-- fs/ext4/inode.c | 4 ++-- fs/ocfs2/inode.c | 2 +- fs/ocfs2/suballoc.c | 2 +- fs/xfs/linux-2.6/xfs_super.c | 2 +- include/acpi/actbl1.h | 2 +- include/linux/cgroup.h | 2 +- include/linux/firewire-cdev.h | 2 +- include/linux/mfd/core.h | 2 +- include/net/sctp/user.h | 4 ++-- include/scsi/fc/fc_fcp.h | 4 ++-- kernel/debug/kdb/kdb_main.c | 2 +- kernel/kexec.c | 2 +- kernel/power/swap.c | 2 +- kernel/sched.c | 2 +- kernel/sysctl_binary.c | 2 +- kernel/time/clocksource.c | 2 +- kernel/trace/trace_entries.h | 2 +- lib/nlattr.c | 2 +- lib/swiotlb.c | 2 +- mm/percpu.c | 2 +- mm/sparse-vmemmap.c | 2 +- net/core/dev.c | 2 +- net/decnet/dn_dev.c | 2 +- net/ipv4/tcp_output.c | 2 +- scripts/kconfig/confdata.c | 2 +- scripts/mod/modpost.c | 2 +- security/apparmor/include/match.h | 2 +- sound/core/init.c | 2 +- sound/core/pcm_native.c | 2 +- sound/isa/opl3sa2.c | 2 +- sound/pci/ca0106/ca0106.h | 2 +- sound/pci/emu10k1/emu10k1x.c | 2 +- sound/pci/emu10k1/p16v.h | 2 +- sound/pci/es1968.c | 2 +- sound/pci/rme9652/hdspm.c | 6 +++--- sound/soc/codecs/max98088.c | 2 +- sound/soc/s3c24xx/smdk_spdif.c | 6 +++--- 207 files changed, 261 insertions(+), 261 deletions(-) diff --git a/Documentation/DocBook/mtdnand.tmpl b/Documentation/DocBook/mtdnand.tmpl index 020ac80d4682..620eb3f6a90a 100644 --- a/Documentation/DocBook/mtdnand.tmpl +++ b/Documentation/DocBook/mtdnand.tmpl @@ -250,7 +250,7 @@ static void board_hwcontrol(struct mtd_info *mtd, int cmd) Device ready function If the hardware interface has the ready busy pin of the NAND chip connected to a - GPIO or other accesible I/O pin, this function is used to read back the state of the + GPIO or other accessible I/O pin, this function is used to read back the state of the pin. The function has no arguments and should return 0, if the device is busy (R/B pin is low) and 1, if the device is ready (R/B pin is high). If the hardware interface does not give access to the ready busy pin, then diff --git a/Documentation/cgroups/cgroup_event_listener.c b/Documentation/cgroups/cgroup_event_listener.c index 8c2bfc4a6358..3e082f96dc12 100644 --- a/Documentation/cgroups/cgroup_event_listener.c +++ b/Documentation/cgroups/cgroup_event_listener.c @@ -91,7 +91,7 @@ int main(int argc, char **argv) if (ret == -1) { perror("cgroup.event_control " - "is not accessable any more"); + "is not accessible any more"); break; } diff --git a/Documentation/cgroups/memcg_test.txt b/Documentation/cgroups/memcg_test.txt index b7eececfb195..fc8fa97a09ac 100644 --- a/Documentation/cgroups/memcg_test.txt +++ b/Documentation/cgroups/memcg_test.txt @@ -398,7 +398,7 @@ Under below explanation, we assume CONFIG_MEM_RES_CTRL_SWAP=y. written to move_charge_at_immigrate. 9.10 Memory thresholds - Memory controler implements memory thresholds using cgroups notification + Memory controller implements memory thresholds using cgroups notification API. You can use Documentation/cgroups/cgroup_event_listener.c to test it. diff --git a/Documentation/kprobes.txt b/Documentation/kprobes.txt index 741fe66d6eca..0cfb00fd86ff 100644 --- a/Documentation/kprobes.txt +++ b/Documentation/kprobes.txt @@ -598,7 +598,7 @@ a 5-byte jump instruction. So there are several limitations. a) The instructions in DCR must be relocatable. b) The instructions in DCR must not include a call instruction. c) JTPR must not be targeted by any jump or call instruction. -d) DCR must not straddle the border betweeen functions. +d) DCR must not straddle the border between functions. Anyway, these limitations are checked by the in-kernel instruction decoder, so you don't need to worry about that. diff --git a/Documentation/kvm/api.txt b/Documentation/kvm/api.txt index b336266bea5e..50713e37c695 100644 --- a/Documentation/kvm/api.txt +++ b/Documentation/kvm/api.txt @@ -874,7 +874,7 @@ Possible values are: - KVM_MP_STATE_HALTED: the vcpu has executed a HLT instruction and is waiting for an interrupt - KVM_MP_STATE_SIPI_RECEIVED: the vcpu has just received a SIPI (vector - accesible via KVM_GET_VCPU_EVENTS) + accessible via KVM_GET_VCPU_EVENTS) This ioctl is only useful after KVM_CREATE_IRQCHIP. Without an in-kernel irqchip, the multiprocessing state must be maintained by userspace. diff --git a/Documentation/networking/caif/spi_porting.txt b/Documentation/networking/caif/spi_porting.txt index 61d7c9247453..0cb8cb9098f4 100644 --- a/Documentation/networking/caif/spi_porting.txt +++ b/Documentation/networking/caif/spi_porting.txt @@ -32,7 +32,7 @@ the physical hardware, both with regard to SPI and to GPIOs. This function is called by the CAIF SPI interface to give you a chance to set up your hardware to be ready to receive a stream of data from the master. The xfer structure contains - both physical and logical adresses, as well as the total length + both physical and logical addresses, as well as the total length of the transfer in both directions.The dev parameter can be used to map to different CAIF SPI slave devices. diff --git a/Documentation/powerpc/booting-without-of.txt b/Documentation/powerpc/booting-without-of.txt index 302db5da49b3..1c6660d2d7f5 100644 --- a/Documentation/powerpc/booting-without-of.txt +++ b/Documentation/powerpc/booting-without-of.txt @@ -1098,7 +1098,7 @@ supported currently at the toplevel. * an arbitrary array of bytes */ - childnode@addresss { /* define a child node named "childnode" + childnode@address { /* define a child node named "childnode" * whose unit name is "childnode at * address" */ diff --git a/Documentation/scsi/ChangeLog.lpfc b/Documentation/scsi/ChangeLog.lpfc index 337c924cc81f..5e83769c6aa9 100644 --- a/Documentation/scsi/ChangeLog.lpfc +++ b/Documentation/scsi/ChangeLog.lpfc @@ -573,7 +573,7 @@ Changes from 20041018 to 20041123 * Backround nodev_timeout processing to DPC This enables us to unblock (stop dev_loss_tmo) when appopriate. * Fix array discovery with multiple luns. The max_luns was 0 at - the time the host structure was intialized. lpfc_cfg_params + the time the host structure was initialized. lpfc_cfg_params then set the max_luns to the correct value afterwards. * Remove unused define LPFC_MAX_LUN and set the default value of lpfc_max_lun parameter to 512. diff --git a/Documentation/timers/timer_stats.txt b/Documentation/timers/timer_stats.txt index 9bd00fc2e823..8abd40b22b7f 100644 --- a/Documentation/timers/timer_stats.txt +++ b/Documentation/timers/timer_stats.txt @@ -19,7 +19,7 @@ Linux system over a sample period: - the pid of the task(process) which initialized the timer - the name of the process which initialized the timer -- the function where the timer was intialized +- the function where the timer was initialized - the callback function which is associated to the timer - the number of events (callbacks) diff --git a/arch/arm/common/it8152.c b/arch/arm/common/it8152.c index 1bec96e85196..60dc077ea7cc 100644 --- a/arch/arm/common/it8152.c +++ b/arch/arm/common/it8152.c @@ -236,7 +236,7 @@ static struct resource it8152_mem = { /* * The following functions are needed for DMA bouncing. - * ITE8152 chip can addrees up to 64MByte, so all the devices + * ITE8152 chip can address up to 64MByte, so all the devices * connected to ITE8152 (PCI and USB) should have limited DMA window */ diff --git a/arch/arm/common/vic.c b/arch/arm/common/vic.c index ba65f6eedca6..cb660bc54d7a 100644 --- a/arch/arm/common/vic.c +++ b/arch/arm/common/vic.c @@ -70,7 +70,7 @@ static inline struct vic_device *to_vic(struct sys_device *sys) * vic_init2 - common initialisation code * @base: Base of the VIC. * - * Common initialisation code for registeration + * Common initialisation code for registration * and resume. */ static void vic_init2(void __iomem *base) diff --git a/arch/arm/mach-at91/board-ecbat91.c b/arch/arm/mach-at91/board-ecbat91.c index 7b58c948a957..de2fd04e7c8a 100644 --- a/arch/arm/mach-at91/board-ecbat91.c +++ b/arch/arm/mach-at91/board-ecbat91.c @@ -128,17 +128,17 @@ static struct spi_board_info __initdata ecb_at91spi_devices[] = { .platform_data = &my_flash0_platform, #endif }, - { /* User accessable spi - cs1 (250KHz) */ + { /* User accessible spi - cs1 (250KHz) */ .modalias = "spi-cs1", .chip_select = 1, .max_speed_hz = 250 * 1000, }, - { /* User accessable spi - cs2 (1MHz) */ + { /* User accessible spi - cs2 (1MHz) */ .modalias = "spi-cs2", .chip_select = 2, .max_speed_hz = 1 * 1000 * 1000, }, - { /* User accessable spi - cs3 (10MHz) */ + { /* User accessible spi - cs3 (10MHz) */ .modalias = "spi-cs3", .chip_select = 3, .max_speed_hz = 10 * 1000 * 1000, diff --git a/arch/arm/mach-bcmring/csp/chipc/chipcHw.c b/arch/arm/mach-bcmring/csp/chipc/chipcHw.c index b3a61d860c65..96273ff34956 100644 --- a/arch/arm/mach-bcmring/csp/chipc/chipcHw.c +++ b/arch/arm/mach-bcmring/csp/chipc/chipcHw.c @@ -757,7 +757,7 @@ static int chipcHw_divide(int num, int denom) t = t << 1; } - /* Intialize the result */ + /* Initialize the result */ r = 0; do { diff --git a/arch/arm/mach-bcmring/csp/dmac/dmacHw.c b/arch/arm/mach-bcmring/csp/dmac/dmacHw.c index 7b9bac2d79a5..6b9be2e98e51 100644 --- a/arch/arm/mach-bcmring/csp/dmac/dmacHw.c +++ b/arch/arm/mach-bcmring/csp/dmac/dmacHw.c @@ -893,7 +893,7 @@ int dmacHw_setDataDescriptor(dmacHw_CONFIG_t *pConfig, /* [ IN ] Configuration */ /****************************************************************************/ uint32_t dmacHw_getDmaControllerAttribute(dmacHw_HANDLE_t handle, /* [ IN ] DMA Channel handle */ - dmacHw_CONTROLLER_ATTRIB_e attr /* [ IN ] DMA Controler attribute of type dmacHw_CONTROLLER_ATTRIB_e */ + dmacHw_CONTROLLER_ATTRIB_e attr /* [ IN ] DMA Controller attribute of type dmacHw_CONTROLLER_ATTRIB_e */ ) { dmacHw_CBLK_t *pCblk = dmacHw_HANDLE_TO_CBLK(handle); diff --git a/arch/arm/mach-bcmring/csp/dmac/dmacHw_extra.c b/arch/arm/mach-bcmring/csp/dmac/dmacHw_extra.c index ff7b436d0935..77f84b40dda9 100644 --- a/arch/arm/mach-bcmring/csp/dmac/dmacHw_extra.c +++ b/arch/arm/mach-bcmring/csp/dmac/dmacHw_extra.c @@ -316,7 +316,7 @@ static void DisplayDescRing(void *pDescriptor, /* [ IN ] Descriptor buffer */ /** * @brief Check if DMA channel is the flow controller * -* @return 1 : If DMA is a flow controler +* @return 1 : If DMA is a flow controller * 0 : Peripheral is the flow controller * * @note diff --git a/arch/arm/mach-bcmring/csp/tmr/tmrHw.c b/arch/arm/mach-bcmring/csp/tmr/tmrHw.c index 5c1c9a0e5ed2..16225e43f3c3 100644 --- a/arch/arm/mach-bcmring/csp/tmr/tmrHw.c +++ b/arch/arm/mach-bcmring/csp/tmr/tmrHw.c @@ -558,7 +558,7 @@ static int tmrHw_divide(int num, int denom) t = t << 1; } - /* Intialize the result */ + /* Initialize the result */ r = 0; do { diff --git a/arch/arm/mach-bcmring/dma.c b/arch/arm/mach-bcmring/dma.c index 77eb35c89cd0..8d1baf3f4683 100644 --- a/arch/arm/mach-bcmring/dma.c +++ b/arch/arm/mach-bcmring/dma.c @@ -671,7 +671,7 @@ static int ConfigChannel(DMA_Handle_t handle) /****************************************************************************/ /** -* Intializes all of the data structures associated with the DMA. +* Initializes all of the data structures associated with the DMA. * @return * >= 0 - Initialization was successfull. * diff --git a/arch/arm/mach-bcmring/include/csp/dmacHw.h b/arch/arm/mach-bcmring/include/csp/dmacHw.h index 5d510130a25f..6c8da2b9fc1f 100644 --- a/arch/arm/mach-bcmring/include/csp/dmacHw.h +++ b/arch/arm/mach-bcmring/include/csp/dmacHw.h @@ -590,7 +590,7 @@ void dmacHw_printDebugInfo(dmacHw_HANDLE_t handle, /* [ IN ] DMA Channel handle */ /****************************************************************************/ uint32_t dmacHw_getDmaControllerAttribute(dmacHw_HANDLE_t handle, /* [ IN ] DMA Channel handle */ - dmacHw_CONTROLLER_ATTRIB_e attr /* [ IN ] DMA Controler attribute of type dmacHw_CONTROLLER_ATTRIB_e */ + dmacHw_CONTROLLER_ATTRIB_e attr /* [ IN ] DMA Controller attribute of type dmacHw_CONTROLLER_ATTRIB_e */ ); #endif /* _DMACHW_H */ diff --git a/arch/arm/mach-bcmring/include/mach/csp/dmacHw_priv.h b/arch/arm/mach-bcmring/include/mach/csp/dmacHw_priv.h index cbf334d1c761..d67e2f8c22de 100644 --- a/arch/arm/mach-bcmring/include/mach/csp/dmacHw_priv.h +++ b/arch/arm/mach-bcmring/include/mach/csp/dmacHw_priv.h @@ -28,7 +28,7 @@ /* Data type for DMA Link List Item */ typedef struct { - uint32_t sar; /* Source Adress Register. + uint32_t sar; /* Source Address Register. Address must be aligned to CTLx.SRC_TR_WIDTH. */ uint32_t dar; /* Destination Address Register. Address must be aligned to CTLx.DST_TR_WIDTH. */ diff --git a/arch/arm/mach-bcmring/include/mach/csp/dmacHw_reg.h b/arch/arm/mach-bcmring/include/mach/csp/dmacHw_reg.h index 891cea87e333..f1ecf96f2da5 100644 --- a/arch/arm/mach-bcmring/include/mach/csp/dmacHw_reg.h +++ b/arch/arm/mach-bcmring/include/mach/csp/dmacHw_reg.h @@ -35,7 +35,7 @@ typedef struct { /* Data type representing DMA channel registers */ typedef struct { - dmacHw_REG64_t ChannelSar; /* Source Adress Register. 64 bits (upper 32 bits are reserved) + dmacHw_REG64_t ChannelSar; /* Source Address Register. 64 bits (upper 32 bits are reserved) Address must be aligned to CTLx.SRC_TR_WIDTH. */ dmacHw_REG64_t ChannelDar; /* Destination Address Register.64 bits (upper 32 bits are reserved) diff --git a/arch/arm/mach-gemini/include/mach/hardware.h b/arch/arm/mach-gemini/include/mach/hardware.h index 213a4fcfeb1c..8c950e1d06be 100644 --- a/arch/arm/mach-gemini/include/mach/hardware.h +++ b/arch/arm/mach-gemini/include/mach/hardware.h @@ -33,7 +33,7 @@ #define GEMINI_LPC_HOST_BASE 0x47000000 #define GEMINI_LPC_IO_BASE 0x47800000 #define GEMINI_INTERRUPT_BASE 0x48000000 -/* TODO: Different interrupt controlers when SMP +/* TODO: Different interrupt controllers when SMP * #define GEMINI_INTERRUPT0_BASE 0x48000000 * #define GEMINI_INTERRUPT1_BASE 0x49000000 */ diff --git a/arch/arm/mach-msm/io.c b/arch/arm/mach-msm/io.c index d36b61074146..7f8d15d56834 100644 --- a/arch/arm/mach-msm/io.c +++ b/arch/arm/mach-msm/io.c @@ -153,7 +153,7 @@ __msm_ioremap(unsigned long phys_addr, size_t size, unsigned int mtype) { if (mtype == MT_DEVICE) { /* The peripherals in the 88000000 - D0000000 range - * are only accessable by type MT_DEVICE_NONSHARED. + * are only accessible by type MT_DEVICE_NONSHARED. * Adjust mtype as necessary to make this "just work." */ if ((phys_addr >= 0x88000000) && (phys_addr < 0xD0000000)) diff --git a/arch/arm/mach-omap2/cpuidle34xx.c b/arch/arm/mach-omap2/cpuidle34xx.c index 0d50b45d041c..1e6fe6d11aee 100644 --- a/arch/arm/mach-omap2/cpuidle34xx.c +++ b/arch/arm/mach-omap2/cpuidle34xx.c @@ -252,7 +252,7 @@ static int omap3_enter_idle_bm(struct cpuidle_device *dev, * FIXME: we currently manage device-specific idle states * for PER and CORE in combination with CPU-specific * idle states. This is wrong, and device-specific - * idle managment needs to be separated out into + * idle management needs to be separated out into * its own code. */ diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c index becf0e38ef7e..db79ac68ed97 100644 --- a/arch/arm/mach-omap2/serial.c +++ b/arch/arm/mach-omap2/serial.c @@ -843,7 +843,7 @@ void __init omap_serial_init_port(int port) } /** - * omap_serial_init() - intialize all supported serial ports + * omap_serial_init() - initialize all supported serial ports * * Initializes all available UARTs as serial ports. Platforms * can call this function when they want to have default behaviour diff --git a/arch/arm/mach-pxa/mxm8x10.c b/arch/arm/mach-pxa/mxm8x10.c index 462167ac05f9..cdf7f41e2bb3 100644 --- a/arch/arm/mach-pxa/mxm8x10.c +++ b/arch/arm/mach-pxa/mxm8x10.c @@ -337,7 +337,7 @@ void __init mxm_8x10_mmc_init(void) } #endif -/* USB Open Host Controler Interface */ +/* USB Open Host Controller Interface */ static struct pxaohci_platform_data mxm_8x10_ohci_platform_data = { .port_mode = PMM_NPS_MODE, .flags = ENABLE_PORT_ALL diff --git a/arch/arm/mach-s3c64xx/dma.c b/arch/arm/mach-s3c64xx/dma.c index e7d03ab41d80..372ea6855454 100644 --- a/arch/arm/mach-s3c64xx/dma.c +++ b/arch/arm/mach-s3c64xx/dma.c @@ -740,7 +740,7 @@ static int __init s3c64xx_dma_init(void) /* Set all DMA configuration to be DMA, not SDMA */ writel(0xffffff, S3C_SYSREG(0x110)); - /* Register standard DMA controlers */ + /* Register standard DMA controllers */ s3c64xx_dma_init1(0, DMACH_UART0, IRQ_DMA0, 0x75000000); s3c64xx_dma_init1(8, DMACH_PCM1_TX, IRQ_DMA1, 0x75100000); diff --git a/arch/arm/mach-spear3xx/spear300.c b/arch/arm/mach-spear3xx/spear300.c index 3560f8c1e723..5aa2d54ebfaa 100644 --- a/arch/arm/mach-spear3xx/spear300.c +++ b/arch/arm/mach-spear3xx/spear300.c @@ -371,7 +371,7 @@ struct pmx_driver pmx_driver = { }; /* Add spear300 specific devices here */ -/* arm gpio1 device registeration */ +/* arm gpio1 device registration */ static struct pl061_platform_data gpio1_plat_data = { .gpio_base = 8, .irq_base = SPEAR_GPIO1_INT_BASE, @@ -451,7 +451,7 @@ void __init spear300_init(void) /* call spear3xx family common init function */ spear3xx_init(); - /* shared irq registeration */ + /* shared irq registration */ shirq_ras1.regs.base = ioremap(SPEAR300_TELECOM_BASE, SPEAR300_TELECOM_REG_SIZE); if (shirq_ras1.regs.base) { diff --git a/arch/arm/mach-spear3xx/spear310.c b/arch/arm/mach-spear3xx/spear310.c index 96a1ab824bac..53b41b52d7ee 100644 --- a/arch/arm/mach-spear3xx/spear310.c +++ b/arch/arm/mach-spear3xx/spear310.c @@ -266,7 +266,7 @@ void __init spear310_init(void) /* call spear3xx family common init function */ spear3xx_init(); - /* shared irq registeration */ + /* shared irq registration */ base = ioremap(SPEAR310_SOC_CONFIG_BASE, SPEAR310_SOC_CONFIG_SIZE); if (base) { /* shirq 1 */ diff --git a/arch/arm/mach-spear3xx/spear320.c b/arch/arm/mach-spear3xx/spear320.c index 6a1219549369..88b465284c36 100644 --- a/arch/arm/mach-spear3xx/spear320.c +++ b/arch/arm/mach-spear3xx/spear320.c @@ -519,7 +519,7 @@ void __init spear320_init(void) /* call spear3xx family common init function */ spear3xx_init(); - /* shared irq registeration */ + /* shared irq registration */ base = ioremap(SPEAR320_SOC_CONFIG_BASE, SPEAR320_SOC_CONFIG_SIZE); if (base) { /* shirq 1 */ diff --git a/arch/arm/mach-spear3xx/spear3xx.c b/arch/arm/mach-spear3xx/spear3xx.c index e87313aeae20..52f553c8c46d 100644 --- a/arch/arm/mach-spear3xx/spear3xx.c +++ b/arch/arm/mach-spear3xx/spear3xx.c @@ -22,7 +22,7 @@ #include /* Add spear3xx machines common devices here */ -/* gpio device registeration */ +/* gpio device registration */ static struct pl061_platform_data gpio_plat_data = { .gpio_base = 0, .irq_base = SPEAR_GPIO_INT_BASE, @@ -41,7 +41,7 @@ struct amba_device gpio_device = { .irq = {IRQ_BASIC_GPIO, NO_IRQ}, }; -/* uart device registeration */ +/* uart device registration */ struct amba_device uart_device = { .dev = { .init_name = "uart", @@ -543,6 +543,6 @@ void spear_pmx_init(struct pmx_driver *pmx_driver, uint base, uint size) pmx_fail: if (ret) - printk(KERN_ERR "padmux: registeration failed. err no: %d\n", + printk(KERN_ERR "padmux: registration failed. err no: %d\n", ret); } diff --git a/arch/arm/mach-spear6xx/spear6xx.c b/arch/arm/mach-spear6xx/spear6xx.c index baf6bcc3169c..f2fe14e8471d 100644 --- a/arch/arm/mach-spear6xx/spear6xx.c +++ b/arch/arm/mach-spear6xx/spear6xx.c @@ -23,7 +23,7 @@ #include /* Add spear6xx machines common devices here */ -/* uart device registeration */ +/* uart device registration */ struct amba_device uart_device[] = { { .dev = { @@ -50,7 +50,7 @@ struct amba_device uart_device[] = { } }; -/* gpio device registeration */ +/* gpio device registration */ static struct pl061_platform_data gpio_plat_data[] = { { .gpio_base = 0, diff --git a/arch/arm/mach-u300/Kconfig b/arch/arm/mach-u300/Kconfig index 801b21e7f677..32a7b0f7e9f7 100644 --- a/arch/arm/mach-u300/Kconfig +++ b/arch/arm/mach-u300/Kconfig @@ -64,7 +64,7 @@ config MACH_U300_DUAL_RAM bool "Dual RAM" help Select this if you want support for Dual RAM phones. - This is two RAM memorys on different EMIFs. + This is two RAM memories on different EMIFs. endchoice config U300_DEBUG diff --git a/arch/arm/mach-u300/include/mach/coh901318.h b/arch/arm/mach-u300/include/mach/coh901318.h index 193da2df732c..6193aaa47794 100644 --- a/arch/arm/mach-u300/include/mach/coh901318.h +++ b/arch/arm/mach-u300/include/mach/coh901318.h @@ -24,7 +24,7 @@ * @src_addr: transfer source address * @dst_addr: transfer destination address * @link_addr: physical address to next lli - * @virt_link_addr: virtual addres of next lli (only used by pool_free) + * @virt_link_addr: virtual address of next lli (only used by pool_free) * @phy_this: physical address of current lli (only used by pool_free) */ struct coh901318_lli { @@ -90,7 +90,7 @@ struct powersave { * struct coh901318_platform - platform arch structure * @chans_slave: specifying dma slave channels * @chans_memcpy: specifying dma memcpy channels - * @access_memory_state: requesting DMA memeory access (on / off) + * @access_memory_state: requesting DMA memory access (on / off) * @chan_conf: dma channel configurations * @max_channels: max number of dma chanenls */ diff --git a/arch/arm/plat-mxc/include/mach/irqs.h b/arch/arm/plat-mxc/include/mach/irqs.h index 86781f7b0c0c..664c453babbe 100644 --- a/arch/arm/plat-mxc/include/mach/irqs.h +++ b/arch/arm/plat-mxc/include/mach/irqs.h @@ -66,7 +66,7 @@ extern int imx_irq_set_priority(unsigned char irq, unsigned char prio); /* all normal IRQs can be FIQs */ #define FIQ_START 0 -/* switch betwean IRQ and FIQ */ +/* switch between IRQ and FIQ */ extern int mxc_set_irq_fiq(unsigned int irq, unsigned int type); #endif /* __ASM_ARCH_MXC_IRQS_H__ */ diff --git a/arch/arm/plat-omap/include/plat/omap_hwmod.h b/arch/arm/plat-omap/include/plat/omap_hwmod.h index 7eaa8edf3b14..79ac24ceb54d 100644 --- a/arch/arm/plat-omap/include/plat/omap_hwmod.h +++ b/arch/arm/plat-omap/include/plat/omap_hwmod.h @@ -339,7 +339,7 @@ struct omap_hwmod_omap2_prcm { /** * struct omap_hwmod_omap4_prcm - OMAP4-specific PRCM data * @clkctrl_reg: PRCM address of the clock control register - * @rstctrl_reg: adress of the XXX_RSTCTRL register located in the PRM + * @rstctrl_reg: address of the XXX_RSTCTRL register located in the PRM * @submodule_wkdep_bit: bit shift of the WKDEP range */ struct omap_hwmod_omap4_prcm { diff --git a/arch/blackfin/mach-bf518/include/mach/defBF51x_base.h b/arch/blackfin/mach-bf518/include/mach/defBF51x_base.h index 5f84913dcd91..750f4d803845 100644 --- a/arch/blackfin/mach-bf518/include/mach/defBF51x_base.h +++ b/arch/blackfin/mach-bf518/include/mach/defBF51x_base.h @@ -1197,7 +1197,7 @@ #define SADD_LEN 0x0002 /* Slave Address Length */ #define STDVAL 0x0004 /* Slave Transmit Data Valid */ #define NAK 0x0008 /* NAK/ACK* Generated At Conclusion Of Transfer */ -#define GEN 0x0010 /* General Call Adrress Matching Enabled */ +#define GEN 0x0010 /* General Call Address Matching Enabled */ /* TWI_SLAVE_STAT Masks */ #define SDIR 0x0001 /* Slave Transfer Direction (Transmit/Receive*) */ diff --git a/arch/blackfin/mach-bf527/include/mach/defBF52x_base.h b/arch/blackfin/mach-bf527/include/mach/defBF52x_base.h index 09475034c6a1..e3ab78ef9001 100644 --- a/arch/blackfin/mach-bf527/include/mach/defBF52x_base.h +++ b/arch/blackfin/mach-bf527/include/mach/defBF52x_base.h @@ -1206,7 +1206,7 @@ #define SADD_LEN 0x0002 /* Slave Address Length */ #define STDVAL 0x0004 /* Slave Transmit Data Valid */ #define NAK 0x0008 /* NAK/ACK* Generated At Conclusion Of Transfer */ -#define GEN 0x0010 /* General Call Adrress Matching Enabled */ +#define GEN 0x0010 /* General Call Address Matching Enabled */ /* TWI_SLAVE_STAT Masks */ #define SDIR 0x0001 /* Slave Transfer Direction (Transmit/Receive*) */ diff --git a/arch/blackfin/mach-bf537/include/mach/defBF534.h b/arch/blackfin/mach-bf537/include/mach/defBF534.h index 0323e6bacdae..042064b2b44a 100644 --- a/arch/blackfin/mach-bf537/include/mach/defBF534.h +++ b/arch/blackfin/mach-bf537/include/mach/defBF534.h @@ -1523,7 +1523,7 @@ #define SADD_LEN 0x0002 /* Slave Address Length */ #define STDVAL 0x0004 /* Slave Transmit Data Valid */ #define NAK 0x0008 /* NAK/ACK* Generated At Conclusion Of Transfer */ -#define GEN 0x0010 /* General Call Adrress Matching Enabled */ +#define GEN 0x0010 /* General Call Address Matching Enabled */ /* TWI_SLAVE_STAT Masks */ #define SDIR 0x0001 /* Slave Transfer Direction (Transmit/Receive*) */ diff --git a/arch/blackfin/mach-bf538/include/mach/defBF539.h b/arch/blackfin/mach-bf538/include/mach/defBF539.h index 7a8ac5f44204..d85d128c97ca 100644 --- a/arch/blackfin/mach-bf538/include/mach/defBF539.h +++ b/arch/blackfin/mach-bf538/include/mach/defBF539.h @@ -2185,7 +2185,7 @@ #define SADD_LEN 0x0002 /* Slave Address Length */ #define STDVAL 0x0004 /* Slave Transmit Data Valid */ #define NAK 0x0008 /* NAK/ACK* Generated At Conclusion Of Transfer */ -#define GEN 0x0010 /* General Call Adrress Matching Enabled */ +#define GEN 0x0010 /* General Call Address Matching Enabled */ /* TWIx_SLAVE_STAT Masks */ #define SDIR 0x0001 /* Slave Transfer Direction (Transmit/Receive*) */ diff --git a/arch/cris/arch-v32/lib/nand_init.S b/arch/cris/arch-v32/lib/nand_init.S index e705f5cce969..d671fed451c9 100644 --- a/arch/cris/arch-v32/lib/nand_init.S +++ b/arch/cris/arch-v32/lib/nand_init.S @@ -139,7 +139,7 @@ copy_nand_to_ram: lsrq 8, $r4 move.b $r4, [$r1] ; Row address lsrq 8, $r4 - move.b $r4, [$r1] ; Row adddress + move.b $r4, [$r1] ; Row address moveq 20, $r4 2: bne 2b subq 1, $r4 diff --git a/arch/cris/include/asm/etraxgpio.h b/arch/cris/include/asm/etraxgpio.h index d474818a537e..461c089db765 100644 --- a/arch/cris/include/asm/etraxgpio.h +++ b/arch/cris/include/asm/etraxgpio.h @@ -1,5 +1,5 @@ /* - * The following devices are accessable using this driver using + * The following devices are accessible using this driver using * GPIO_MAJOR (120) and a couple of minor numbers. * * For ETRAX 100LX (CONFIG_ETRAX_ARCH_V10): diff --git a/arch/h8300/Kconfig.debug b/arch/h8300/Kconfig.debug index ee671c3f2c74..e8d1b236ad8c 100644 --- a/arch/h8300/Kconfig.debug +++ b/arch/h8300/Kconfig.debug @@ -48,7 +48,7 @@ config DEFAULT_CMDLINE builtin kernel commandline enabled. config KERNEL_COMMAND - string "Buildin commmand string" + string "Buildin command string" depends on DEFAULT_CMDLINE help builtin kernel commandline strings. diff --git a/arch/ia64/kvm/mmio.c b/arch/ia64/kvm/mmio.c index fb8f9f59a1ed..f1e17d3d6cd9 100644 --- a/arch/ia64/kvm/mmio.c +++ b/arch/ia64/kvm/mmio.c @@ -130,7 +130,7 @@ static void mmio_access(struct kvm_vcpu *vcpu, u64 src_pa, u64 *dest, local_irq_save(psr); - /*Intercept the acces for PIB range*/ + /*Intercept the access for PIB range*/ if (iot == GPFN_PIB) { if (!dir) lsapic_write(vcpu, src_pa, s, *dest); diff --git a/arch/mips/alchemy/common/power.c b/arch/mips/alchemy/common/power.c index e5916a516e58..647e518c90bc 100644 --- a/arch/mips/alchemy/common/power.c +++ b/arch/mips/alchemy/common/power.c @@ -130,7 +130,7 @@ static void restore_core_regs(void) au_writel(sleep_usb[1], USBD_ENABLE); au_sync(); #else - /* enable accces to OTG memory */ + /* enable access to OTG memory */ au_writel(au_readl(USB_MSR_BASE + 4) | (1 << 6), USB_MSR_BASE + 4); au_sync(); diff --git a/arch/mips/include/asm/mach-powertv/ioremap.h b/arch/mips/include/asm/mach-powertv/ioremap.h index 076f2eeaa575..c86ef094ec37 100644 --- a/arch/mips/include/asm/mach-powertv/ioremap.h +++ b/arch/mips/include/asm/mach-powertv/ioremap.h @@ -88,7 +88,7 @@ static inline dma_addr_t _dma_to_phys_offset_raw(dma_addr_t dma) } /* These are not portable and should not be used in drivers. Drivers should - * be using ioremap() and friends to map physical addreses to virtual + * be using ioremap() and friends to map physical addresses to virtual * addresses and dma_map*() and friends to map virtual addresses into DMA * addresses and back. */ diff --git a/arch/mips/jz4740/board-qi_lb60.c b/arch/mips/jz4740/board-qi_lb60.c index 5742bb4d78f4..de4433c5a771 100644 --- a/arch/mips/jz4740/board-qi_lb60.c +++ b/arch/mips/jz4740/board-qi_lb60.c @@ -65,7 +65,7 @@ static struct nand_ecclayout qi_lb60_ecclayout_1gb = { /* Early prototypes of the QI LB60 had only 1GB of NAND. * In order to support these devices aswell the partition and ecc layout is - * initalized depending on the NAND size */ + * initialized depending on the NAND size */ static struct mtd_partition qi_lb60_partitions_1gb[] = { { .name = "NAND BOOT partition", @@ -464,7 +464,7 @@ static int __init qi_lb60_board_setup(void) board_gpio_setup(); if (qi_lb60_init_platform_devices()) - panic("Failed to initalize platform devices\n"); + panic("Failed to initialize platform devices\n"); return 0; } diff --git a/arch/mips/jz4740/gpio.c b/arch/mips/jz4740/gpio.c index 38f60f35156c..88e6aeda5bf1 100644 --- a/arch/mips/jz4740/gpio.c +++ b/arch/mips/jz4740/gpio.c @@ -546,7 +546,7 @@ static int __init jz4740_gpio_init(void) for (i = 0; i < ARRAY_SIZE(jz4740_gpio_chips); ++i) jz4740_gpio_chip_init(&jz4740_gpio_chips[i], i); - printk(KERN_INFO "JZ4740 GPIO initalized\n"); + printk(KERN_INFO "JZ4740 GPIO initialized\n"); return 0; } diff --git a/arch/mips/mti-malta/malta-memory.c b/arch/mips/mti-malta/malta-memory.c index b27419c84919..a96d281f9221 100644 --- a/arch/mips/mti-malta/malta-memory.c +++ b/arch/mips/mti-malta/malta-memory.c @@ -43,7 +43,7 @@ static struct prom_pmemblock mdesc[PROM_MAX_PMEMBLOCKS]; static char *mtypes[3] = { "Dont use memory", "YAMON PROM memory", - "Free memmory", + "Free memory", }; #endif diff --git a/arch/mips/pci/pcie-octeon.c b/arch/mips/pci/pcie-octeon.c index 385f035b24e4..0583c463e5f1 100644 --- a/arch/mips/pci/pcie-octeon.c +++ b/arch/mips/pci/pcie-octeon.c @@ -900,7 +900,7 @@ static int cvmx_pcie_rc_initialize(int pcie_port) mem_access_subid.s.ror = 0; /* Disable Relaxed Ordering for Writes. */ mem_access_subid.s.row = 0; - /* PCIe Adddress Bits <63:34>. */ + /* PCIe Address Bits <63:34>. */ mem_access_subid.s.ba = 0; /* diff --git a/arch/mips/powertv/memory.c b/arch/mips/powertv/memory.c index 73880ad29bc2..fb3d29660c42 100644 --- a/arch/mips/powertv/memory.c +++ b/arch/mips/powertv/memory.c @@ -57,7 +57,7 @@ unsigned long ptv_memsize; /* - * struct low_mem_reserved - Items in low memmory that are reserved + * struct low_mem_reserved - Items in low memory that are reserved * @start: Physical address of item * @size: Size, in bytes, of this item * @is_aliased: True if this is RAM aliased from another location. If false, diff --git a/arch/mips/txx9/generic/pci.c b/arch/mips/txx9/generic/pci.c index 9a0be810cafa..96e69a00ffc8 100644 --- a/arch/mips/txx9/generic/pci.c +++ b/arch/mips/txx9/generic/pci.c @@ -107,7 +107,7 @@ int txx9_pci_mem_high __initdata; /* * allocate pci_controller and resources. - * mem_base, io_base: physical addresss. 0 for auto assignment. + * mem_base, io_base: physical address. 0 for auto assignment. * mem_size and io_size means max size on auto assignment. * pcic must be &txx9_primary_pcic or NULL. */ diff --git a/arch/powerpc/include/asm/8xx_immap.h b/arch/powerpc/include/asm/8xx_immap.h index 4b0e15206006..6b6dc20b0beb 100644 --- a/arch/powerpc/include/asm/8xx_immap.h +++ b/arch/powerpc/include/asm/8xx_immap.h @@ -93,7 +93,7 @@ typedef struct mem_ctlr { } memctl8xx_t; /*----------------------------------------------------------------------- - * BR - Memory Controler: Base Register 16-9 + * BR - Memory Controller: Base Register 16-9 */ #define BR_BA_MSK 0xffff8000 /* Base Address Mask */ #define BR_AT_MSK 0x00007000 /* Address Type Mask */ @@ -110,7 +110,7 @@ typedef struct mem_ctlr { #define BR_V 0x00000001 /* Bank Valid */ /*----------------------------------------------------------------------- - * OR - Memory Controler: Option Register 16-11 + * OR - Memory Controller: Option Register 16-11 */ #define OR_AM_MSK 0xffff8000 /* Address Mask Mask */ #define OR_ATM_MSK 0x00007000 /* Address Type Mask Mask */ diff --git a/arch/powerpc/oprofile/op_model_cell.c b/arch/powerpc/oprofile/op_model_cell.c index 7fd90d02d8c6..c4d2b7167568 100644 --- a/arch/powerpc/oprofile/op_model_cell.c +++ b/arch/powerpc/oprofile/op_model_cell.c @@ -1469,7 +1469,7 @@ static int cell_global_start(struct op_counter_config *ctr) * The pm_interval register is setup to write the SPU PC value into the * trace buffer at the maximum rate possible. The trace buffer is configured * to store the PCs, wrapping when it is full. The performance counter is - * intialized to the max hardware count minus the number of events, N, between + * initialized to the max hardware count minus the number of events, N, between * samples. Once the N events have occured, a HW counter overflow occurs * causing the generation of a HW counter interrupt which also stops the * writing of the SPU PC values to the trace buffer. Hence the last PC diff --git a/arch/powerpc/platforms/83xx/suspend-asm.S b/arch/powerpc/platforms/83xx/suspend-asm.S index 1930543c98d3..3d1ecd211776 100644 --- a/arch/powerpc/platforms/83xx/suspend-asm.S +++ b/arch/powerpc/platforms/83xx/suspend-asm.S @@ -231,7 +231,7 @@ _GLOBAL(mpc83xx_enter_deep_sleep) ori r4, r4, 0x002a mtspr SPRN_DBAT0L, r4 lis r8, TMP_VIRT_IMMR@h - ori r4, r8, 0x001e /* 1 MByte accessable from Kernel Space only */ + ori r4, r8, 0x001e /* 1 MByte accessible from Kernel Space only */ mtspr SPRN_DBAT0U, r4 isync @@ -241,7 +241,7 @@ _GLOBAL(mpc83xx_enter_deep_sleep) ori r4, r4, 0x002a mtspr SPRN_DBAT1L, r4 lis r9, (TMP_VIRT_IMMR + 0x01000000)@h - ori r4, r9, 0x001e /* 1 MByte accessable from Kernel Space only */ + ori r4, r9, 0x001e /* 1 MByte accessible from Kernel Space only */ mtspr SPRN_DBAT1U, r4 isync @@ -253,7 +253,7 @@ _GLOBAL(mpc83xx_enter_deep_sleep) li r4, 0x0002 mtspr SPRN_DBAT2L, r4 lis r4, KERNELBASE@h - ori r4, r4, 0x001e /* 1 MByte accessable from Kernel Space only */ + ori r4, r4, 0x001e /* 1 MByte accessible from Kernel Space only */ mtspr SPRN_DBAT2U, r4 isync diff --git a/arch/powerpc/platforms/ps3/device-init.c b/arch/powerpc/platforms/ps3/device-init.c index b341018326df..6c4b5837fc8a 100644 --- a/arch/powerpc/platforms/ps3/device-init.c +++ b/arch/powerpc/platforms/ps3/device-init.c @@ -566,10 +566,10 @@ static int ps3_setup_dynamic_device(const struct ps3_repository_device *repo) case PS3_DEV_TYPE_STOR_DISK: result = ps3_setup_storage_dev(repo, PS3_MATCH_ID_STOR_DISK); - /* Some devices are not accessable from the Other OS lpar. */ + /* Some devices are not accessible from the Other OS lpar. */ if (result == -ENODEV) { result = 0; - pr_debug("%s:%u: not accessable\n", __func__, + pr_debug("%s:%u: not accessible\n", __func__, __LINE__); } diff --git a/arch/powerpc/platforms/ps3/interrupt.c b/arch/powerpc/platforms/ps3/interrupt.c index 59d9712d7364..92290ff4761a 100644 --- a/arch/powerpc/platforms/ps3/interrupt.c +++ b/arch/powerpc/platforms/ps3/interrupt.c @@ -44,7 +44,7 @@ * @lock: * @ipi_debug_brk_mask: * - * The HV mantains per SMT thread mappings of HV outlet to HV plug on + * The HV maintains per SMT thread mappings of HV outlet to HV plug on * behalf of the guest. These mappings are implemented as 256 bit guest * supplied bitmaps indexed by plug number. The addresses of the bitmaps * are registered with the HV through lv1_configure_irq_state_bitmap(). diff --git a/arch/sh/mm/cache-sh5.c b/arch/sh/mm/cache-sh5.c index eb4cc4ec7952..d1bffbcd9d52 100644 --- a/arch/sh/mm/cache-sh5.c +++ b/arch/sh/mm/cache-sh5.c @@ -568,7 +568,7 @@ static void sh5_flush_dcache_page(void *page) } /* - * Flush the range [start,end] of kernel virtual adddress space from + * Flush the range [start,end] of kernel virtual address space from * the I-cache. The corresponding range must be purged from the * D-cache also because the SH-5 doesn't have cache snooping between * the caches. The addresses will be visible through the superpage diff --git a/arch/sparc/kernel/traps_64.c b/arch/sparc/kernel/traps_64.c index 42ad2ba85010..1e9770936c3b 100644 --- a/arch/sparc/kernel/traps_64.c +++ b/arch/sparc/kernel/traps_64.c @@ -622,7 +622,7 @@ static const char CHAFSR_PERR_msg[] = static const char CHAFSR_IERR_msg[] = "Internal processor error"; static const char CHAFSR_ISAP_msg[] = - "System request parity error on incoming addresss"; + "System request parity error on incoming address"; static const char CHAFSR_UCU_msg[] = "Uncorrectable E-cache ECC error for ifetch/data"; static const char CHAFSR_UCC_msg[] = diff --git a/arch/x86/include/asm/pgalloc.h b/arch/x86/include/asm/pgalloc.h index 271de94c3810..b4389a468fb6 100644 --- a/arch/x86/include/asm/pgalloc.h +++ b/arch/x86/include/asm/pgalloc.h @@ -92,7 +92,7 @@ static inline void pmd_free(struct mm_struct *mm, pmd_t *pmd) extern void ___pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmd); static inline void __pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmd, - unsigned long adddress) + unsigned long address) { ___pmd_free_tlb(tlb, pmd); } diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h index cae9c3cb95cf..c3e6d9a3de65 100644 --- a/arch/x86/include/asm/processor.h +++ b/arch/x86/include/asm/processor.h @@ -902,7 +902,7 @@ extern unsigned long thread_saved_pc(struct task_struct *tsk); /* * The below -8 is to reserve 8 bytes on top of the ring0 stack. * This is necessary to guarantee that the entire "struct pt_regs" - * is accessable even if the CPU haven't stored the SS/ESP registers + * is accessible even if the CPU haven't stored the SS/ESP registers * on the stack (interrupt gate does not save these registers * when switching to the same priv ring). * Therefore beware: accessing the ss/esp fields of the diff --git a/arch/x86/kernel/amd_iommu.c b/arch/x86/kernel/amd_iommu.c index d2fdb0826df2..57ca77787220 100644 --- a/arch/x86/kernel/amd_iommu.c +++ b/arch/x86/kernel/amd_iommu.c @@ -1086,7 +1086,7 @@ static int alloc_new_range(struct dma_ops_domain *dma_dom, dma_dom->aperture_size += APERTURE_RANGE_SIZE; - /* Intialize the exclusion range if necessary */ + /* Initialize the exclusion range if necessary */ for_each_iommu(iommu) { if (iommu->exclusion_start && iommu->exclusion_start >= dma_dom->aperture[index]->offset @@ -1353,7 +1353,7 @@ static void dma_ops_domain_free(struct dma_ops_domain *dom) /* * Allocates a new protection domain usable for the dma_ops functions. - * It also intializes the page table and the address allocator data + * It also initializes the page table and the address allocator data * structures required for the dma_ops interface */ static struct dma_ops_domain *dma_ops_domain_alloc(void) diff --git a/arch/x86/kernel/early_printk_mrst.c b/arch/x86/kernel/early_printk_mrst.c index 65df603622b2..25bfdbb5b130 100644 --- a/arch/x86/kernel/early_printk_mrst.c +++ b/arch/x86/kernel/early_printk_mrst.c @@ -103,7 +103,7 @@ struct dw_spi_reg { static unsigned long mrst_spi_paddr = MRST_REGBASE_SPI0; static u32 *pclk_spi0; -/* Always contains an accessable address, start with 0 */ +/* Always contains an accessible address, start with 0 */ static struct dw_spi_reg *pspi; static struct kmsg_dumper dw_dumper; diff --git a/arch/x86/kernel/head_32.S b/arch/x86/kernel/head_32.S index bcece91dd311..8e09aa3aa6d6 100644 --- a/arch/x86/kernel/head_32.S +++ b/arch/x86/kernel/head_32.S @@ -124,7 +124,7 @@ ENTRY(startup_32) movsl movl pa(boot_params) + NEW_CL_POINTER,%esi andl %esi,%esi - jz 1f # No comand line + jz 1f # No command line movl $pa(boot_command_line),%edi movl $(COMMAND_LINE_SIZE/4),%ecx rep diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c index 4cd59b0d7c15..78ee4b1d4e85 100644 --- a/block/cfq-iosched.c +++ b/block/cfq-iosched.c @@ -1030,7 +1030,7 @@ cfq_find_alloc_cfqg(struct cfq_data *cfqd, struct cgroup *cgroup, int create) /* * Add group onto cgroup list. It might happen that bdi->dev is - * not initiliazed yet. Initialize this new group without major + * not initialized yet. Initialize this new group without major * and minor info and this info will be filled in once a new thread * comes for IO. See code above. */ diff --git a/drivers/acpi/acpica/acobject.h b/drivers/acpi/acpica/acobject.h index bdbfaf22bd14..962a3ccff6fd 100644 --- a/drivers/acpi/acpica/acobject.h +++ b/drivers/acpi/acpica/acobject.h @@ -93,7 +93,7 @@ #define AOPOBJ_AML_CONSTANT 0x01 /* Integer is an AML constant */ #define AOPOBJ_STATIC_POINTER 0x02 /* Data is part of an ACPI table, don't delete */ -#define AOPOBJ_DATA_VALID 0x04 /* Object is intialized and data is valid */ +#define AOPOBJ_DATA_VALID 0x04 /* Object is initialized and data is valid */ #define AOPOBJ_OBJECT_INITIALIZED 0x08 /* Region is initialized, _REG was run */ #define AOPOBJ_SETUP_COMPLETE 0x10 /* Region setup is complete */ #define AOPOBJ_INVALID 0x20 /* Host OS won't allow a Region address */ diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 7f77c67d267c..5b0295a923a7 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -2240,7 +2240,7 @@ int ata_dev_configure(struct ata_device *dev) if (id[ATA_ID_CFA_KEY_MGMT] & 1) ata_dev_printk(dev, KERN_WARNING, "supports DRM functions and may " - "not be fully accessable.\n"); + "not be fully accessible.\n"); snprintf(revbuf, 7, "CFA"); } else { snprintf(revbuf, 7, "ATA-%d", ata_id_major_version(id)); @@ -2248,7 +2248,7 @@ int ata_dev_configure(struct ata_device *dev) if (ata_id_has_tpm(id)) ata_dev_printk(dev, KERN_WARNING, "supports DRM functions and may " - "not be fully accessable.\n"); + "not be fully accessible.\n"); } dev->n_sectors = ata_id_n_sectors(id); diff --git a/drivers/ata/sata_vsc.c b/drivers/ata/sata_vsc.c index b777176ff494..e079cf29ed5d 100644 --- a/drivers/ata/sata_vsc.c +++ b/drivers/ata/sata_vsc.c @@ -370,7 +370,7 @@ static int __devinit vsc_sata_init_one(struct pci_dev *pdev, if (pci_resource_len(pdev, 0) == 0) return -ENODEV; - /* map IO regions and intialize host accordingly */ + /* map IO regions and initialize host accordingly */ rc = pcim_iomap_regions(pdev, 1 << VSC_MMIO_BAR, DRV_NAME); if (rc == -EBUSY) pcim_pin_device(pdev); diff --git a/drivers/atm/idt77252.h b/drivers/atm/idt77252.h index 5042bb2dab15..f53a43ae2bbe 100644 --- a/drivers/atm/idt77252.h +++ b/drivers/atm/idt77252.h @@ -572,7 +572,7 @@ struct idt77252_dev #define SAR_STAT_TSQF 0x00001000 /* Transmit Status Queue full */ #define SAR_STAT_TMROF 0x00000800 /* Timer overflow */ #define SAR_STAT_PHYI 0x00000400 /* PHY device Interrupt flag */ -#define SAR_STAT_CMDBZ 0x00000200 /* ABR SAR Comand Busy Flag */ +#define SAR_STAT_CMDBZ 0x00000200 /* ABR SAR Command Busy Flag */ #define SAR_STAT_FBQ3A 0x00000100 /* Free Buffer Queue 3 Attention */ #define SAR_STAT_FBQ2A 0x00000080 /* Free Buffer Queue 2 Attention */ #define SAR_STAT_RSQF 0x00000040 /* Receive Status Queue full */ diff --git a/drivers/atm/iphase.c b/drivers/atm/iphase.c index 9309d4724e13..ad8e207784d4 100644 --- a/drivers/atm/iphase.c +++ b/drivers/atm/iphase.c @@ -2063,7 +2063,7 @@ static int tx_init(struct atm_dev *dev) - UBR Table size is 4K - UBR wait queue is 4K since the table and wait queues are contiguous, all the bytes - can be initialized by one memeset. + can be initialized by one memeset. */ vcsize_sel = 0; @@ -2089,7 +2089,7 @@ static int tx_init(struct atm_dev *dev) - ABR Table size is 2K - ABR wait queue is 2K since the table and wait queues are contiguous, all the bytes - can be intialized by one memeset. + can be initialized by one memeset. */ i = ABR_SCHED_TABLE * iadev->memSize; writew((i >> 11) & 0xffff, iadev->seg_reg+ABR_SBPTR_BASE); diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c index 31b526661ec4..c5356ef7e54e 100644 --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c @@ -8,7 +8,7 @@ * * * The driver model core calls device_pm_add() when a device is registered. - * This will intialize the embedded device_pm_info object in the device + * This will initialize the embedded device_pm_info object in the device * and add it to the list of power-controlled devices. sysfs entries for * controlling device power management will also be added. * diff --git a/drivers/dma/intel_mid_dma.c b/drivers/dma/intel_mid_dma.c index 338bc4eed1f3..da8b7f161cdb 100644 --- a/drivers/dma/intel_mid_dma.c +++ b/drivers/dma/intel_mid_dma.c @@ -1060,8 +1060,8 @@ static irqreturn_t intel_mid_dma_interrupt2(int irq, void *data) * mid_setup_dma - Setup the DMA controller * @pdev: Controller PCI device structure * - * Initilize the DMA controller, channels, registers with DMA engine, - * ISR. Initilize DMA controller channels. + * Initialize the DMA controller, channels, registers with DMA engine, + * ISR. Initialize DMA controller channels. */ static int mid_setup_dma(struct pci_dev *pdev) { @@ -1219,7 +1219,7 @@ static void middma_shutdown(struct pci_dev *pdev) * @pdev: Controller PCI device structure * @id: pci device id structure * - * Initilize the PCI device, map BARs, query driver data. + * Initialize the PCI device, map BARs, query driver data. * Call setup_dma to complete contoller and chan initilzation */ static int __devinit intel_mid_dma_probe(struct pci_dev *pdev, diff --git a/drivers/edac/amd8131_edac.h b/drivers/edac/amd8131_edac.h index 60e0d1c72dee..6f8b07131ec4 100644 --- a/drivers/edac/amd8131_edac.h +++ b/drivers/edac/amd8131_edac.h @@ -99,7 +99,7 @@ struct amd8131_dev_info { /* * AMD8131 chipset has two pairs of PCIX Bridge and related IOAPIC - * Controler, and ATCA-6101 has two AMD8131 chipsets, so there are + * Controller, and ATCA-6101 has two AMD8131 chipsets, so there are * four PCIX Bridges on ATCA-6101 altogether. * * These PCIX Bridges share the same PCI Device ID and are all of diff --git a/drivers/edac/cell_edac.c b/drivers/edac/cell_edac.c index c973004c002c..db1df59ae2b6 100644 --- a/drivers/edac/cell_edac.c +++ b/drivers/edac/cell_edac.c @@ -47,7 +47,7 @@ static void cell_edac_count_ce(struct mem_ctl_info *mci, int chan, u64 ar) offset = address & ~PAGE_MASK; syndrome = (ar & 0x000000001fe00000ul) >> 21; - /* TODO: Decoding of the error addresss */ + /* TODO: Decoding of the error address */ edac_mc_handle_ce(mci, csrow->first_page + pfn, offset, syndrome, 0, chan, ""); } @@ -68,7 +68,7 @@ static void cell_edac_count_ue(struct mem_ctl_info *mci, int chan, u64 ar) pfn = address >> PAGE_SHIFT; offset = address & ~PAGE_MASK; - /* TODO: Decoding of the error addresss */ + /* TODO: Decoding of the error address */ edac_mc_handle_ue(mci, csrow->first_page + pfn, offset, 0, ""); } diff --git a/drivers/edac/edac_core.h b/drivers/edac/edac_core.h index d7ca43a828bd..035eaaf2d906 100644 --- a/drivers/edac/edac_core.h +++ b/drivers/edac/edac_core.h @@ -258,7 +258,7 @@ enum scrub_type { * for single channel are 64 bits, for dual channel 128 * bits. * - * Single-Ranked stick: A Single-ranked stick has 1 chip-select row of memmory. + * Single-Ranked stick: A Single-ranked stick has 1 chip-select row of memory. * Motherboards commonly drive two chip-select pins to * a memory stick. A single-ranked stick, will occupy * only one of those rows. The other will be unused. diff --git a/drivers/edac/ppc4xx_edac.c b/drivers/edac/ppc4xx_edac.c index 070cea41b661..b9f0c20df1aa 100644 --- a/drivers/edac/ppc4xx_edac.c +++ b/drivers/edac/ppc4xx_edac.c @@ -873,7 +873,7 @@ ppc4xx_edac_get_mtype(u32 mcopt1) } /** - * ppc4xx_edac_init_csrows - intialize driver instance rows + * ppc4xx_edac_init_csrows - initialize driver instance rows * @mci: A pointer to the EDAC memory controller instance * associated with the ibm,sdram-4xx-ddr2 controller for which * the csrows (i.e. banks/ranks) are being initialized. @@ -881,7 +881,7 @@ ppc4xx_edac_get_mtype(u32 mcopt1) * currently set for the controller, from which bank width * and memory typ information is derived. * - * This routine intializes the virtual "chip select rows" associated + * This routine initializes the virtual "chip select rows" associated * with the EDAC memory controller instance. An ibm,sdram-4xx-ddr2 * controller bank/rank is mapped to a row. * @@ -992,7 +992,7 @@ ppc4xx_edac_init_csrows(struct mem_ctl_info *mci, u32 mcopt1) } /** - * ppc4xx_edac_mc_init - intialize driver instance + * ppc4xx_edac_mc_init - initialize driver instance * @mci: A pointer to the EDAC memory controller instance being * initialized. * @op: A pointer to the OpenFirmware device tree node associated diff --git a/drivers/gpu/drm/radeon/atombios.h b/drivers/gpu/drm/radeon/atombios.h index fe359a239df3..4707cbdb35cd 100644 --- a/drivers/gpu/drm/radeon/atombios.h +++ b/drivers/gpu/drm/radeon/atombios.h @@ -1314,7 +1314,7 @@ typedef struct _GET_ENGINE_CLOCK_PARAMETERS typedef struct _READ_EDID_FROM_HW_I2C_DATA_PARAMETERS { USHORT usPrescale; //Ratio between Engine clock and I2C clock - USHORT usVRAMAddress; //Adress in Frame Buffer where to pace raw EDID + USHORT usVRAMAddress; //Address in Frame Buffer where to pace raw EDID USHORT usStatus; //When use output: lower byte EDID checksum, high byte hardware status //WHen use input: lower byte as 'byte to read':currently limited to 128byte or 1byte UCHAR ucSlaveAddr; //Read from which slave diff --git a/drivers/i2c/busses/i2c-nomadik.c b/drivers/i2c/busses/i2c-nomadik.c index c9fffd0389fe..2bd3469b3071 100644 --- a/drivers/i2c/busses/i2c-nomadik.c +++ b/drivers/i2c/busses/i2c-nomadik.c @@ -434,7 +434,7 @@ static int read_i2c(struct nmk_i2c_dev *dev) } if (timeout == 0) { - /* controler has timedout, re-init the h/w */ + /* controller has timedout, re-init the h/w */ dev_err(&dev->pdev->dev, "controller timed out, re-init h/w\n"); (void) init_hw(dev); status = -ETIMEDOUT; @@ -498,7 +498,7 @@ static int write_i2c(struct nmk_i2c_dev *dev) } if (timeout == 0) { - /* controler has timedout, re-init the h/w */ + /* controller has timedout, re-init the h/w */ dev_err(&dev->pdev->dev, "controller timed out, re-init h/w\n"); (void) init_hw(dev); status = -ETIMEDOUT; diff --git a/drivers/infiniband/hw/cxgb3/cxio_wr.h b/drivers/infiniband/hw/cxgb3/cxio_wr.h index 4bb997aa39d0..83d2e19d31ae 100644 --- a/drivers/infiniband/hw/cxgb3/cxio_wr.h +++ b/drivers/infiniband/hw/cxgb3/cxio_wr.h @@ -689,7 +689,7 @@ struct t3_swrq { * A T3 WQ implements both the SQ and RQ. */ struct t3_wq { - union t3_wr *queue; /* DMA accessable memory */ + union t3_wr *queue; /* DMA accessible memory */ dma_addr_t dma_addr; /* DMA address for HW */ DEFINE_DMA_UNMAP_ADDR(mapping); /* unmap kruft */ u32 error; /* 1 once we go to ERROR */ diff --git a/drivers/infiniband/hw/qib/qib_iba7322.c b/drivers/infiniband/hw/qib/qib_iba7322.c index 584d443b5335..ead2627c06a8 100644 --- a/drivers/infiniband/hw/qib/qib_iba7322.c +++ b/drivers/infiniband/hw/qib/qib_iba7322.c @@ -314,7 +314,7 @@ MODULE_PARM_DESC(txselect, \ #define krp_serdesctrl KREG_IBPORT_IDX(IBSerdesCtrl) /* - * Per-context kernel registers. Acess only with qib_read_kreg_ctxt() + * Per-context kernel registers. Access only with qib_read_kreg_ctxt() * or qib_write_kreg_ctxt() */ #define krc_rcvhdraddr KREG_IDX(RcvHdrAddr0) diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig index 06ea8da95c62..6675bd7dde19 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig @@ -610,7 +610,7 @@ config TOUCHSCREEN_USB_ZYTRONIC config TOUCHSCREEN_USB_ETT_TC45USB default y - bool "ET&T USB series TC4UM/TC5UH touchscreen controler support" if EMBEDDED + bool "ET&T USB series TC4UM/TC5UH touchscreen controller support" if EMBEDDED depends on TOUCHSCREEN_USB_COMPOSITE config TOUCHSCREEN_USB_NEXIO diff --git a/drivers/isdn/gigaset/bas-gigaset.c b/drivers/isdn/gigaset/bas-gigaset.c index 178942a2ee61..8a3c5cfc4fea 100644 --- a/drivers/isdn/gigaset/bas-gigaset.c +++ b/drivers/isdn/gigaset/bas-gigaset.c @@ -2318,7 +2318,7 @@ static int gigaset_probe(struct usb_interface *interface, __func__, le16_to_cpu(udev->descriptor.idVendor), le16_to_cpu(udev->descriptor.idProduct)); - /* allocate memory for our device state and intialize it */ + /* allocate memory for our device state and initialize it */ cs = gigaset_initcs(driver, BAS_CHANNELS, 0, 0, cidmode, GIGASET_MODULENAME); if (!cs) @@ -2576,7 +2576,7 @@ static int __init bas_gigaset_init(void) { int result; - /* allocate memory for our driver state and intialize it */ + /* allocate memory for our driver state and initialize it */ driver = gigaset_initdriver(GIGASET_MINOR, GIGASET_MINORS, GIGASET_MODULENAME, GIGASET_DEVNAME, &gigops, THIS_MODULE); diff --git a/drivers/isdn/gigaset/ser-gigaset.c b/drivers/isdn/gigaset/ser-gigaset.c index d151dcbf770d..0ef09d0eb96b 100644 --- a/drivers/isdn/gigaset/ser-gigaset.c +++ b/drivers/isdn/gigaset/ser-gigaset.c @@ -513,7 +513,7 @@ gigaset_tty_open(struct tty_struct *tty) return -ENODEV; } - /* allocate memory for our device state and intialize it */ + /* allocate memory for our device state and initialize it */ cs = gigaset_initcs(driver, 1, 1, 0, cidmode, GIGASET_MODULENAME); if (!cs) goto error; @@ -771,7 +771,7 @@ static int __init ser_gigaset_init(void) return rc; } - /* allocate memory for our driver state and intialize it */ + /* allocate memory for our driver state and initialize it */ driver = gigaset_initdriver(GIGASET_MINOR, GIGASET_MINORS, GIGASET_MODULENAME, GIGASET_DEVNAME, &ops, THIS_MODULE); diff --git a/drivers/isdn/gigaset/usb-gigaset.c b/drivers/isdn/gigaset/usb-gigaset.c index 4a66338f4e7d..5e3300d8a2a5 100644 --- a/drivers/isdn/gigaset/usb-gigaset.c +++ b/drivers/isdn/gigaset/usb-gigaset.c @@ -695,7 +695,7 @@ static int gigaset_probe(struct usb_interface *interface, dev_info(&udev->dev, "%s: Device matched ... !\n", __func__); - /* allocate memory for our device state and intialize it */ + /* allocate memory for our device state and initialize it */ cs = gigaset_initcs(driver, 1, 1, 0, cidmode, GIGASET_MODULENAME); if (!cs) return -ENODEV; @@ -894,7 +894,7 @@ static int __init usb_gigaset_init(void) { int result; - /* allocate memory for our driver state and intialize it */ + /* allocate memory for our driver state and initialize it */ driver = gigaset_initdriver(GIGASET_MINOR, GIGASET_MINORS, GIGASET_MODULENAME, GIGASET_DEVNAME, &ops, THIS_MODULE); diff --git a/drivers/isdn/hardware/mISDN/ipac.h b/drivers/isdn/hardware/mISDN/ipac.h index 74a6ccf9065c..8121e046b739 100644 --- a/drivers/isdn/hardware/mISDN/ipac.h +++ b/drivers/isdn/hardware/mISDN/ipac.h @@ -29,7 +29,7 @@ struct isac_hw { u32 type; u32 off; /* offset to isac regs */ char *name; - spinlock_t *hwlock; /* lock HW acccess */ + spinlock_t *hwlock; /* lock HW access */ read_reg_func *read_reg; write_reg_func *write_reg; fifo_func *read_fifo; @@ -70,7 +70,7 @@ struct ipac_hw { struct hscx_hw hscx[2]; char *name; void *hw; - spinlock_t *hwlock; /* lock HW acccess */ + spinlock_t *hwlock; /* lock HW access */ struct module *owner; u32 type; read_reg_func *read_reg; diff --git a/drivers/isdn/hardware/mISDN/isar.h b/drivers/isdn/hardware/mISDN/isar.h index 4a134acd44d0..9962bdf699c7 100644 --- a/drivers/isdn/hardware/mISDN/isar.h +++ b/drivers/isdn/hardware/mISDN/isar.h @@ -44,7 +44,7 @@ struct isar_ch { struct isar_hw { struct isar_ch ch[2]; void *hw; - spinlock_t *hwlock; /* lock HW acccess */ + spinlock_t *hwlock; /* lock HW access */ char *name; struct module *owner; read_reg_func *read_reg; diff --git a/drivers/isdn/hisax/isar.c b/drivers/isdn/hisax/isar.c index 40b914bded8c..2e72227bd071 100644 --- a/drivers/isdn/hisax/isar.c +++ b/drivers/isdn/hisax/isar.c @@ -1427,8 +1427,8 @@ modeisar(struct BCState *bcs, int mode, int bc) &bcs->hw.isar.reg->Flags)) bcs->hw.isar.dpath = 1; else { - printk(KERN_WARNING"isar modeisar analog funktions only with DP1\n"); - debugl1(cs, "isar modeisar analog funktions only with DP1"); + printk(KERN_WARNING"isar modeisar analog functions only with DP1\n"); + debugl1(cs, "isar modeisar analog functions only with DP1"); return(1); } break; diff --git a/drivers/media/video/cx25840/cx25840-ir.c b/drivers/media/video/cx25840/cx25840-ir.c index 97a4e9b25fe4..a9d83b5d0e49 100644 --- a/drivers/media/video/cx25840/cx25840-ir.c +++ b/drivers/media/video/cx25840/cx25840-ir.c @@ -261,7 +261,7 @@ static u16 ns_to_pulse_width_count(u32 ns, u16 divider) u32 rem; /* - * The 2 lsb's of the pulse width timer count are not accessable, hence + * The 2 lsb's of the pulse width timer count are not accessible, hence * the (1 << 2) */ n = ((u64) ns) * CX25840_IR_REFCLK_FREQ / 1000000; /* millicycles */ diff --git a/drivers/media/video/davinci/vpif.h b/drivers/media/video/davinci/vpif.h index 188841b476e0..ebd5c4338ebb 100644 --- a/drivers/media/video/davinci/vpif.h +++ b/drivers/media/video/davinci/vpif.h @@ -33,7 +33,7 @@ extern spinlock_t vpif_lock; #define regr(reg) readl((reg) + vpif_base) #define regw(value, reg) writel(value, (reg + vpif_base)) -/* Register Addresss Offsets */ +/* Register Address Offsets */ #define VPIF_PID (0x0000) #define VPIF_CH0_CTRL (0x0004) #define VPIF_CH1_CTRL (0x0008) diff --git a/drivers/media/video/davinci/vpss.c b/drivers/media/video/davinci/vpss.c index 7918680917d0..3e5cf27ec2b2 100644 --- a/drivers/media/video/davinci/vpss.c +++ b/drivers/media/video/davinci/vpss.c @@ -85,7 +85,7 @@ enum vpss_platform_type { /* * vpss operations. Depends on platform. Not all functions are available * on all platforms. The api, first check if a functio is available before - * invoking it. In the probe, the function ptrs are intialized based on + * invoking it. In the probe, the function ptrs are initialized based on * vpss name. vpss name can be "dm355_vpss", "dm644x_vpss" etc. */ struct vpss_hw_ops { diff --git a/drivers/media/video/omap/omap_vout.c b/drivers/media/video/omap/omap_vout.c index 15f8793e325b..21d7c0d8f51f 100644 --- a/drivers/media/video/omap/omap_vout.c +++ b/drivers/media/video/omap/omap_vout.c @@ -1286,7 +1286,7 @@ static int omap_vout_release(struct file *file) videobuf_mmap_free(q); /* Even if apply changes fails we should continue - freeing allocated memeory */ + freeing allocated memory */ if (vout->streaming) { u32 mask = 0; diff --git a/drivers/media/video/saa7164/saa7164-core.c b/drivers/media/video/saa7164/saa7164-core.c index e1bac5051460..cdd8e348a543 100644 --- a/drivers/media/video/saa7164/saa7164-core.c +++ b/drivers/media/video/saa7164/saa7164-core.c @@ -653,8 +653,8 @@ static irqreturn_t saa7164_irq(int irq, void *dev_id) goto out; } - /* Check that the hardware is accessable. If the status bytes are - * 0xFF then the device is not accessable, the the IRQ belongs + /* Check that the hardware is accessible. If the status bytes are + * 0xFF then the device is not accessible, the the IRQ belongs * to another driver. * 4 x u32 interrupt registers. */ diff --git a/drivers/media/video/sn9c102/sn9c102_sensor.h b/drivers/media/video/sn9c102/sn9c102_sensor.h index 494957b10bac..7f38549715b6 100644 --- a/drivers/media/video/sn9c102/sn9c102_sensor.h +++ b/drivers/media/video/sn9c102/sn9c102_sensor.h @@ -147,7 +147,7 @@ enum sn9c102_i2c_interface { struct sn9c102_sensor { char name[32], /* sensor name */ - maintainer[64]; /* name of the mantainer */ + maintainer[64]; /* name of the maintainer */ enum sn9c102_bridge supported_bridge; /* supported SN9C1xx bridges */ diff --git a/drivers/media/video/zoran/zoran.h b/drivers/media/video/zoran/zoran.h index 37fe16181e3c..1f04438695dd 100644 --- a/drivers/media/video/zoran/zoran.h +++ b/drivers/media/video/zoran/zoran.h @@ -95,7 +95,7 @@ struct zoran_params { int quality; /* Measure for quality of compressed images. * Scales linearly with the size of the compressed images. - * Must be beetween 0 and 100, 100 is a compression + * Must be between 0 and 100, 100 is a compression * ratio of 1:4 */ int odd_even; /* Which field should come first ??? */ diff --git a/drivers/message/fusion/lsi/mpi_log_sas.h b/drivers/message/fusion/lsi/mpi_log_sas.h index 691620dbedd2..8b04810df469 100644 --- a/drivers/message/fusion/lsi/mpi_log_sas.h +++ b/drivers/message/fusion/lsi/mpi_log_sas.h @@ -268,7 +268,7 @@ /* Compatibility Error : IR Disabled */ #define IR_LOGINFO_COMPAT_ERROR_RAID_DISABLED (0x00010030) -/* Compatibility Error : Inquiry Comand failed */ +/* Compatibility Error : Inquiry Command failed */ #define IR_LOGINFO_COMPAT_ERROR_INQUIRY_FAILED (0x00010031) /* Compatibility Error : Device not direct access device */ #define IR_LOGINFO_COMPAT_ERROR_NOT_DIRECT_ACCESS (0x00010032) diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c index 3e57b61ca446..3358c0af3466 100644 --- a/drivers/message/fusion/mptbase.c +++ b/drivers/message/fusion/mptbase.c @@ -7977,7 +7977,7 @@ mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info) NULL, /* 2Eh */ NULL, /* 2Fh */ "Compatibility Error: IR Disabled", /* 30h */ - "Compatibility Error: Inquiry Comand Failed", /* 31h */ + "Compatibility Error: Inquiry Command Failed", /* 31h */ "Compatibility Error: Device not Direct Access " "Device ", /* 32h */ "Compatibility Error: Removable Device Found", /* 33h */ diff --git a/drivers/message/fusion/mptsas.c b/drivers/message/fusion/mptsas.c index 83a5115f0251..5651f77a8cc1 100644 --- a/drivers/message/fusion/mptsas.c +++ b/drivers/message/fusion/mptsas.c @@ -1146,7 +1146,7 @@ mptsas_target_reset_queue(MPT_ADAPTER *ioc, * * This function will delete scheduled target reset from the list and * try to send next target reset. This will be called from completion - * context of any Task managment command. + * context of any Task management command. */ void diff --git a/drivers/message/i2o/i2o_block.c b/drivers/message/i2o/i2o_block.c index f87a9d405a5e..ae7cad185898 100644 --- a/drivers/message/i2o/i2o_block.c +++ b/drivers/message/i2o/i2o_block.c @@ -309,7 +309,7 @@ static inline void i2o_block_request_free(struct i2o_block_request *ireq) * @ireq: I2O block request * @mptr: message body pointer * - * Builds the SG list and map it to be accessable by the controller. + * Builds the SG list and map it to be accessible by the controller. * * Returns 0 on failure or 1 on success. */ diff --git a/drivers/misc/arm-charlcd.c b/drivers/misc/arm-charlcd.c index 9e3879ef58f2..fe8616a8d287 100644 --- a/drivers/misc/arm-charlcd.c +++ b/drivers/misc/arm-charlcd.c @@ -313,7 +313,7 @@ static int __init charlcd_probe(struct platform_device *pdev) INIT_DELAYED_WORK(&lcd->init_work, charlcd_init_work); schedule_delayed_work(&lcd->init_work, 0); - dev_info(&pdev->dev, "initalized ARM character LCD at %08x\n", + dev_info(&pdev->dev, "initialized ARM character LCD at %08x\n", lcd->phybase); return 0; diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index 217f82037fc1..bfc8a8ae55df 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c @@ -257,7 +257,7 @@ static u32 get_card_status(struct mmc_card *card, struct request *req) cmd.flags = MMC_RSP_SPI_R2 | MMC_RSP_R1 | MMC_CMD_AC; err = mmc_wait_for_cmd(card->host, &cmd, 0); if (err) - printk(KERN_ERR "%s: error %d sending status comand", + printk(KERN_ERR "%s: error %d sending status command", req->rq_disk->disk_name, err); return cmd.resp[0]; } diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig index d618e8673996..c99a1fcd97f6 100644 --- a/drivers/mmc/host/Kconfig +++ b/drivers/mmc/host/Kconfig @@ -462,7 +462,7 @@ config MMC_SH_MMCIF tristate "SuperH Internal MMCIF support" depends on MMC_BLOCK && (SUPERH || ARCH_SHMOBILE) help - This selects the MMC Host Interface controler (MMCIF). + This selects the MMC Host Interface controller (MMCIF). This driver supports MMCIF in sh7724/sh7757/sh7372. diff --git a/drivers/mmc/host/au1xmmc.c b/drivers/mmc/host/au1xmmc.c index 41e5a60493ad..ef72e874ca36 100644 --- a/drivers/mmc/host/au1xmmc.c +++ b/drivers/mmc/host/au1xmmc.c @@ -192,7 +192,7 @@ static inline void SEND_STOP(struct au1xmmc_host *host) au_writel(config2 | SD_CONFIG2_DF, HOST_CONFIG2(host)); au_sync(); - /* Send the stop commmand */ + /* Send the stop command */ au_writel(STOP_CMD, HOST_CMD(host)); } diff --git a/drivers/mmc/host/sdricoh_cs.c b/drivers/mmc/host/sdricoh_cs.c index f472c2714eb8..bbc298fd2a15 100644 --- a/drivers/mmc/host/sdricoh_cs.c +++ b/drivers/mmc/host/sdricoh_cs.c @@ -446,7 +446,7 @@ static int sdricoh_init_mmc(struct pci_dev *pci_dev, mmc->max_seg_size = 1024 * 512; mmc->max_blk_size = 512; - /* reset the controler */ + /* reset the controller */ if (sdricoh_reset(host)) { dev_dbg(dev, "could not reset\n"); result = -EIO; @@ -478,7 +478,7 @@ static int sdricoh_pcmcia_probe(struct pcmcia_device *pcmcia_dev) dev_info(&pcmcia_dev->dev, "Searching MMC controller for pcmcia device" " %s %s ...\n", pcmcia_dev->prod_id[0], pcmcia_dev->prod_id[1]); - /* search pci cardbus bridge that contains the mmc controler */ + /* search pci cardbus bridge that contains the mmc controller */ /* the io region is already claimed by yenta_socket... */ while ((pci_dev = pci_get_device(PCI_VENDOR_ID_RICOH, PCI_DEVICE_ID_RICOH_RL5C476, diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index 1f75a1b1f7c3..31bf376b82a0 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -821,7 +821,7 @@ retry: * * Wait for command done. This is a helper function for nand_wait used when * we are in interrupt context. May happen when in panic and trying to write - * an oops trough mtdoops. + * an oops through mtdoops. */ static void panic_nand_wait(struct mtd_info *mtd, struct nand_chip *chip, unsigned long timeo) diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c index e9ad16f00b56..4a6f0eac8b12 100644 --- a/drivers/net/bnx2x/bnx2x_main.c +++ b/drivers/net/bnx2x/bnx2x_main.c @@ -4947,7 +4947,7 @@ static int bnx2x_init_hw_common(struct bnx2x *bp, u32 load_code) memset(&ilt_cli, 0, sizeof(struct ilt_client_info)); memset(&ilt, 0, sizeof(struct bnx2x_ilt)); - /* initalize dummy TM client */ + /* initialize dummy TM client */ ilt_cli.start = 0; ilt_cli.end = ILT_NUM_PAGE_ENTRIES - 1; ilt_cli.client_num = ILT_CLIENT_TM; diff --git a/drivers/net/bnx2x/bnx2x_reg.h b/drivers/net/bnx2x/bnx2x_reg.h index 1cefe489a955..245220af9feb 100644 --- a/drivers/net/bnx2x/bnx2x_reg.h +++ b/drivers/net/bnx2x/bnx2x_reg.h @@ -1604,7 +1604,7 @@ (~misc_registers_sw_timer_cfg_4.sw_timer_cfg_4[1] ) is set */ #define MISC_REG_SW_TIMER_RELOAD_VAL_4 0xa2fc /* [RW 32] the value of the counter for sw timers1-8. there are 8 addresses - in this register. addres 0 - timer 1; address 1 - timer 2, ... address 7 - + in this register. address 0 - timer 1; address 1 - timer 2, ... address 7 - timer 8 */ #define MISC_REG_SW_TIMER_VAL 0xa5c0 /* [RW 1] Set by the MCP to remember if one or more of the drivers is/are diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c index 881914bc4e9c..106718c1be5b 100644 --- a/drivers/net/bonding/bond_3ad.c +++ b/drivers/net/bonding/bond_3ad.c @@ -840,7 +840,7 @@ static int ad_lacpdu_send(struct port *port) lacpdu_header = (struct lacpdu_header *)skb_put(skb, length); memcpy(lacpdu_header->hdr.h_dest, lacpdu_mcast_addr, ETH_ALEN); - /* Note: source addres is set to be the member's PERMANENT address, + /* Note: source address is set to be the member's PERMANENT address, because we use it to identify loopback lacpdus in receive. */ memcpy(lacpdu_header->hdr.h_source, slave->perm_hwaddr, ETH_ALEN); lacpdu_header->hdr.h_proto = PKT_TYPE_LACPDU; @@ -881,7 +881,7 @@ static int ad_marker_send(struct port *port, struct bond_marker *marker) marker_header = (struct bond_marker_header *)skb_put(skb, length); memcpy(marker_header->hdr.h_dest, lacpdu_mcast_addr, ETH_ALEN); - /* Note: source addres is set to be the member's PERMANENT address, + /* Note: source address is set to be the member's PERMANENT address, because we use it to identify loopback MARKERs in receive. */ memcpy(marker_header->hdr.h_source, slave->perm_hwaddr, ETH_ALEN); marker_header->hdr.h_proto = PKT_TYPE_LACPDU; @@ -1916,7 +1916,7 @@ int bond_3ad_bind_slave(struct slave *slave) return -1; } - //check that the slave has not been intialized yet. + //check that the slave has not been initialized yet. if (SLAVE_AD_INFO(slave).port.slave != slave) { // port initialization diff --git a/drivers/net/chelsio/subr.c b/drivers/net/chelsio/subr.c index 63ebf76d2390..8a43c7e19701 100644 --- a/drivers/net/chelsio/subr.c +++ b/drivers/net/chelsio/subr.c @@ -556,7 +556,7 @@ struct chelsio_vpd_t { #define EEPROM_MAX_POLL 4 /* - * Read SEEPROM. A zero is written to the flag register when the addres is + * Read SEEPROM. A zero is written to the flag register when the address is * written to the Control register. The hardware device will set the flag to a * one when 4B have been transferred to the Data register. */ diff --git a/drivers/net/cxgb3/mc5.c b/drivers/net/cxgb3/mc5.c index a8766fb2f9ab..e13b7fe9d082 100644 --- a/drivers/net/cxgb3/mc5.c +++ b/drivers/net/cxgb3/mc5.c @@ -318,7 +318,7 @@ static void mc5_dbgi_mode_disable(const struct mc5 *mc5) /* * Initialization that requires the OS and protocol layers to already - * be intialized goes here. + * be initialized goes here. */ int t3_mc5_init(struct mc5 *mc5, unsigned int nservers, unsigned int nfilters, unsigned int nroutes) diff --git a/drivers/net/cxgb3/t3_hw.c b/drivers/net/cxgb3/t3_hw.c index 3a6adf0b3e9d..0b197043bc34 100644 --- a/drivers/net/cxgb3/t3_hw.c +++ b/drivers/net/cxgb3/t3_hw.c @@ -607,7 +607,7 @@ struct t3_vpd { * * Read a 32-bit word from a location in VPD EEPROM using the card's PCI * VPD ROM capability. A zero is written to the flag bit when the - * addres is written to the control register. The hardware device will + * address is written to the control register. The hardware device will * set the flag to 1 when 4 bytes have been read into the data register. */ int t3_seeprom_read(struct adapter *adapter, u32 addr, __le32 *data) diff --git a/drivers/net/e1000/e1000_hw.h b/drivers/net/e1000/e1000_hw.h index ecd9f6c6bcd5..5e820f4e68b9 100644 --- a/drivers/net/e1000/e1000_hw.h +++ b/drivers/net/e1000/e1000_hw.h @@ -41,7 +41,7 @@ struct e1000_hw; struct e1000_hw_stats; /* Enumerated types specific to the e1000 hardware */ -/* Media Access Controlers */ +/* Media Access Controllers */ typedef enum { e1000_undefined = 0, e1000_82542_rev2_0, diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c index 4686c3983fc3..1b8a43a29c01 100644 --- a/drivers/net/e1000/e1000_main.c +++ b/drivers/net/e1000/e1000_main.c @@ -2194,7 +2194,7 @@ static void e1000_set_rx_mode(struct net_device *netdev) * addresses take precedence to avoid disabling unicast filtering * when possible. * - * RAR 0 is used for the station MAC adddress + * RAR 0 is used for the station MAC address * if there are not 14 addresses, go ahead and clear the filters */ i = 1; diff --git a/drivers/net/e1000e/82571.c b/drivers/net/e1000e/82571.c index 7236f1a53ba0..a655beb69320 100644 --- a/drivers/net/e1000e/82571.c +++ b/drivers/net/e1000e/82571.c @@ -300,7 +300,7 @@ static s32 e1000_init_mac_params_82571(struct e1000_adapter *adapter) /* * Ensure that the inter-port SWSM.SMBI lock bit is clear before - * first NVM or PHY acess. This should be done for single-port + * first NVM or PHY access. This should be done for single-port * devices, and for one port only on dual-port devices so that * for those devices we can still use the SMBI lock to synchronize * inter-port accesses to the PHY & NVM. diff --git a/drivers/net/e1000e/ich8lan.c b/drivers/net/e1000e/ich8lan.c index e3374d9a2472..38c84ba3e3c1 100644 --- a/drivers/net/e1000e/ich8lan.c +++ b/drivers/net/e1000e/ich8lan.c @@ -321,7 +321,7 @@ static s32 e1000_init_phy_params_pchlan(struct e1000_hw *hw) } /* - * Reset the PHY before any acccess to it. Doing so, ensures that + * Reset the PHY before any access to it. Doing so, ensures that * the PHY is in a known good state before we read/write PHY registers. * The generic reset is sufficient here, because we haven't determined * the PHY type yet. diff --git a/drivers/net/e1000e/phy.c b/drivers/net/e1000e/phy.c index 3d3dc0c82355..b9bff5ba009f 100644 --- a/drivers/net/e1000e/phy.c +++ b/drivers/net/e1000e/phy.c @@ -2976,7 +2976,7 @@ s32 e1000_write_phy_reg_hv_locked(struct e1000_hw *hw, u32 offset, u16 data) } /** - * e1000_get_phy_addr_for_hv_page - Get PHY adrress based on page + * e1000_get_phy_addr_for_hv_page - Get PHY address based on page * @page: page to be accessed **/ static u32 e1000_get_phy_addr_for_hv_page(u32 page) diff --git a/drivers/net/eepro.c b/drivers/net/eepro.c index 7c826319ee5a..dbaec546c428 100644 --- a/drivers/net/eepro.c +++ b/drivers/net/eepro.c @@ -1760,7 +1760,7 @@ module_param_array(io, int, NULL, 0); module_param_array(irq, int, NULL, 0); module_param_array(mem, int, NULL, 0); module_param(autodetect, int, 0); -MODULE_PARM_DESC(io, "EtherExpress Pro/10 I/O base addres(es)"); +MODULE_PARM_DESC(io, "EtherExpress Pro/10 I/O base address(es)"); MODULE_PARM_DESC(irq, "EtherExpress Pro/10 IRQ number(s)"); MODULE_PARM_DESC(mem, "EtherExpress Pro/10 Rx buffer size(es) in kB (3-29)"); MODULE_PARM_DESC(autodetect, "EtherExpress Pro/10 force board(s) detection (0-1)"); diff --git a/drivers/net/irda/donauboe.h b/drivers/net/irda/donauboe.h index 4dc39e5f0156..77fcf4459161 100644 --- a/drivers/net/irda/donauboe.h +++ b/drivers/net/irda/donauboe.h @@ -30,7 +30,7 @@ * or the type-DO IR port. * * IrDA chip set list from Toshiba Computer Engineering Corp. - * model method maker controler Version + * model method maker controller Version * Portege 320CT FIR,SIR Toshiba Oboe(Triangle) * Portege 3010CT FIR,SIR Toshiba Oboe(Sydney) * Portege 3015CT FIR,SIR Toshiba Oboe(Sydney) diff --git a/drivers/net/ixgbe/ixgbe_82599.c b/drivers/net/ixgbe/ixgbe_82599.c index 0bd8fbb5bfd0..05e6b8cafb39 100644 --- a/drivers/net/ixgbe/ixgbe_82599.c +++ b/drivers/net/ixgbe/ixgbe_82599.c @@ -1078,7 +1078,7 @@ s32 ixgbe_init_fdir_signature_82599(struct ixgbe_hw *hw, u32 pballoc) /* * The defaults in the HW for RX PB 1-7 are not zero and so should be - * intialized to zero for non DCB mode otherwise actual total RX PB + * initialized to zero for non DCB mode otherwise actual total RX PB * would be bigger than programmed and filter space would run into * the PB 0 region. */ @@ -1169,7 +1169,7 @@ s32 ixgbe_init_fdir_perfect_82599(struct ixgbe_hw *hw, u32 pballoc) /* * The defaults in the HW for RX PB 1-7 are not zero and so should be - * intialized to zero for non DCB mode otherwise actual total RX PB + * initialized to zero for non DCB mode otherwise actual total RX PB * would be bigger than programmed and filter space would run into * the PB 0 region. */ diff --git a/drivers/net/ll_temac_main.c b/drivers/net/ll_temac_main.c index 9f8e7027b0b3..661ed1ff4c2e 100644 --- a/drivers/net/ll_temac_main.c +++ b/drivers/net/ll_temac_main.c @@ -238,7 +238,7 @@ static int temac_dma_bd_init(struct net_device *ndev) goto out; } /* allocate the tx and rx ring buffer descriptors. */ - /* returns a virtual addres and a physical address. */ + /* returns a virtual address and a physical address. */ lp->tx_bd_v = dma_alloc_coherent(ndev->dev.parent, sizeof(*lp->tx_bd_v) * TX_BD_NUM, &lp->tx_bd_p, GFP_KERNEL); diff --git a/drivers/net/sis900.c b/drivers/net/sis900.c index 581836867098..5976d1d51df1 100644 --- a/drivers/net/sis900.c +++ b/drivers/net/sis900.c @@ -36,7 +36,7 @@ Rev 1.07.06 Nov. 7 2000 Jeff Garzik some bug fix and cleaning Rev 1.07.05 Nov. 6 2000 metapirat contribute media type select by ifconfig Rev 1.07.04 Sep. 6 2000 Lei-Chun Chang added ICS1893 PHY support - Rev 1.07.03 Aug. 24 2000 Lei-Chun Chang (lcchang@sis.com.tw) modified 630E eqaulizer workaround rule + Rev 1.07.03 Aug. 24 2000 Lei-Chun Chang (lcchang@sis.com.tw) modified 630E equalizer workaround rule Rev 1.07.01 Aug. 08 2000 Ollie Lho minor update for SiS 630E and SiS 630E A1 Rev 1.07 Mar. 07 2000 Ollie Lho bug fix in Rx buffer ring Rev 1.06.04 Feb. 11 2000 Jeff Garzik softnet and init for kernel 2.4 diff --git a/drivers/net/tehuti.c b/drivers/net/tehuti.c index 8b3dc1eb4015..474652a2f70d 100644 --- a/drivers/net/tehuti.c +++ b/drivers/net/tehuti.c @@ -12,7 +12,7 @@ /* * RX HW/SW interaction overview * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * There are 2 types of RX communication channels betwean driver and NIC. + * There are 2 types of RX communication channels between driver and NIC. * 1) RX Free Fifo - RXF - holds descriptors of empty buffers to accept incoming * traffic. This Fifo is filled by SW and is readen by HW. Each descriptor holds * info about buffer's location, size and ID. An ID field is used to identify a @@ -821,7 +821,7 @@ static void bdx_setmulti(struct net_device *ndev) } /* use PMF to accept first MAC_MCST_NUM (15) addresses */ - /* TBD: sort addreses and write them in ascending order + /* TBD: sort addresses and write them in ascending order * into RX_MAC_MCST regs. we skip this phase now and accept ALL * multicast frames throu IMF */ /* accept the rest of addresses throu IMF */ @@ -1346,7 +1346,7 @@ static void print_rxfd(struct rxf_desc *rxfd) /* * TX HW/SW interaction overview * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - * There are 2 types of TX communication channels betwean driver and NIC. + * There are 2 types of TX communication channels between driver and NIC. * 1) TX Free Fifo - TXF - holds ack descriptors for sent packets * 2) TX Data Fifo - TXD - holds descriptors of full buffers. * diff --git a/drivers/net/tun.c b/drivers/net/tun.c index 55f3a3e667a9..e625f9530cf9 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c @@ -1309,7 +1309,7 @@ static long __tun_chr_ioctl(struct file *file, unsigned int cmd, break; case SIOCGIFHWADDR: - /* Get hw addres */ + /* Get hw address */ memcpy(ifr.ifr_hwaddr.sa_data, tun->dev->dev_addr, ETH_ALEN); ifr.ifr_hwaddr.sa_family = tun->dev->type; if (copy_to_user(argp, &ifr, ifreq_len)) diff --git a/drivers/net/vxge/vxge-traffic.h b/drivers/net/vxge/vxge-traffic.h index 9890d4d596d0..654295816a39 100644 --- a/drivers/net/vxge/vxge-traffic.h +++ b/drivers/net/vxge/vxge-traffic.h @@ -1695,7 +1695,7 @@ struct vxge_hw_device_stats_sw_err { * struct vxge_hw_device_stats - Contains HW per-device statistics, * including hw. * @devh: HW device handle. - * @dma_addr: DMA addres of the %hw_info. Given to device to fill-in the stats. + * @dma_addr: DMA address of the %hw_info. Given to device to fill-in the stats. * @hw_info_dmah: DMA handle used to map hw statistics onto the device memory * space. * @hw_info_dma_acch: One more DMA handle used subsequently to free the diff --git a/drivers/net/wan/dscc4.c b/drivers/net/wan/dscc4.c index d45b08d1dbc9..94ff9b02e28e 100644 --- a/drivers/net/wan/dscc4.c +++ b/drivers/net/wan/dscc4.c @@ -125,7 +125,7 @@ static u32 dscc4_pci_config_store[16]; /* Module parameters */ MODULE_AUTHOR("Maintainer: Francois Romieu "); -MODULE_DESCRIPTION("Siemens PEB20534 PCI Controler"); +MODULE_DESCRIPTION("Siemens PEB20534 PCI Controller"); MODULE_LICENSE("GPL"); module_param(debug, int, 0); MODULE_PARM_DESC(debug,"Enable/disable extra messages"); diff --git a/drivers/net/wimax/i2400m/driver.c b/drivers/net/wimax/i2400m/driver.c index cdedab46ba21..bcb483fdc4d9 100644 --- a/drivers/net/wimax/i2400m/driver.c +++ b/drivers/net/wimax/i2400m/driver.c @@ -280,7 +280,7 @@ int i2400m_check_mac_addr(struct i2400m *i2400m) result); goto error; } - /* Extract MAC addresss */ + /* Extract MAC address */ ddi = (void *) skb->data; BUILD_BUG_ON(ETH_ALEN != sizeof(ddi->mac_address)); d_printf(2, dev, "GET DEVICE INFO: mac addr %pM\n", diff --git a/drivers/net/wimax/i2400m/i2400m.h b/drivers/net/wimax/i2400m/i2400m.h index 59ac7705e76e..8cde3a52d225 100644 --- a/drivers/net/wimax/i2400m/i2400m.h +++ b/drivers/net/wimax/i2400m/i2400m.h @@ -698,7 +698,7 @@ enum i2400m_bm_cmd_flags { * @I2400M_BRI_MAC_REINIT: We need to reinitialize the boot * rom after reading the MAC address. This is quite a dirty hack, * if you ask me -- the device requires the bootrom to be - * intialized after reading the MAC address. + * initialized after reading the MAC address. */ enum i2400m_bri { I2400M_BRI_SOFT = 1 << 1, diff --git a/drivers/net/wireless/ath/ath5k/reg.h b/drivers/net/wireless/ath/ath5k/reg.h index ca79ecd832fd..2a246d13b520 100644 --- a/drivers/net/wireless/ath/ath5k/reg.h +++ b/drivers/net/wireless/ath/ath5k/reg.h @@ -1063,7 +1063,7 @@ /* * EEPROM command register */ -#define AR5K_EEPROM_CMD 0x6008 /* Register Addres */ +#define AR5K_EEPROM_CMD 0x6008 /* Register Address */ #define AR5K_EEPROM_CMD_READ 0x00000001 /* EEPROM read */ #define AR5K_EEPROM_CMD_WRITE 0x00000002 /* EEPROM write */ #define AR5K_EEPROM_CMD_RESET 0x00000004 /* EEPROM reset */ @@ -1083,7 +1083,7 @@ /* * EEPROM config register */ -#define AR5K_EEPROM_CFG 0x6010 /* Register Addres */ +#define AR5K_EEPROM_CFG 0x6010 /* Register Address */ #define AR5K_EEPROM_CFG_SIZE 0x00000003 /* Size determination override */ #define AR5K_EEPROM_CFG_SIZE_AUTO 0 #define AR5K_EEPROM_CFG_SIZE_4KBIT 1 @@ -1125,7 +1125,7 @@ * Second station id register (Upper 16 bits of MAC address + PCU settings) */ #define AR5K_STA_ID1 0x8004 /* Register Address */ -#define AR5K_STA_ID1_ADDR_U16 0x0000ffff /* Upper 16 bits of MAC addres */ +#define AR5K_STA_ID1_ADDR_U16 0x0000ffff /* Upper 16 bits of MAC address */ #define AR5K_STA_ID1_AP 0x00010000 /* Set AP mode */ #define AR5K_STA_ID1_ADHOC 0x00020000 /* Set Ad-Hoc mode */ #define AR5K_STA_ID1_PWR_SV 0x00040000 /* Power save reporting */ diff --git a/drivers/net/wireless/b43/phy_g.c b/drivers/net/wireless/b43/phy_g.c index 0dc33b65e86b..be4828167012 100644 --- a/drivers/net/wireless/b43/phy_g.c +++ b/drivers/net/wireless/b43/phy_g.c @@ -1919,7 +1919,7 @@ static void b43_hardware_pctl_init_gphy(struct b43_wldev *dev) b43_hf_write(dev, b43_hf_read(dev) | B43_HF_HWPCTL); } -/* Intialize B/G PHY power control */ +/* Initialize B/G PHY power control */ static void b43_phy_init_pctl(struct b43_wldev *dev) { struct ssb_bus *bus = dev->dev->bus; diff --git a/drivers/net/wireless/b43legacy/phy.c b/drivers/net/wireless/b43legacy/phy.c index 35033dd342ce..28e477d01587 100644 --- a/drivers/net/wireless/b43legacy/phy.c +++ b/drivers/net/wireless/b43legacy/phy.c @@ -153,7 +153,7 @@ void b43legacy_phy_calibrate(struct b43legacy_wldev *dev) phy->calibrated = 1; } -/* intialize B PHY power control +/* initialize B PHY power control * as described in http://bcm-specs.sipsolutions.net/InitPowerControl */ static void b43legacy_phy_init_pctl(struct b43legacy_wldev *dev) diff --git a/drivers/net/wireless/iwlwifi/iwl-sta.c b/drivers/net/wireless/iwlwifi/iwl-sta.c index 7c7f7dcb1b1e..972b738c0e4a 100644 --- a/drivers/net/wireless/iwlwifi/iwl-sta.c +++ b/drivers/net/wireless/iwlwifi/iwl-sta.c @@ -107,7 +107,7 @@ static int iwl_process_add_sta_resp(struct iwl_priv *priv, /* * XXX: The MAC address in the command buffer is often changed from * the original sent to the device. That is, the MAC address - * written to the command buffer often is not the same MAC adress + * written to the command buffer often is not the same MAC address * read from the command buffer when the command returns. This * issue has not yet been resolved and this debugging is left to * observe the problem. diff --git a/drivers/net/wireless/prism54/islpci_dev.c b/drivers/net/wireless/prism54/islpci_dev.c index 2c8cc954d1b6..ec2c75d77cea 100644 --- a/drivers/net/wireless/prism54/islpci_dev.c +++ b/drivers/net/wireless/prism54/islpci_dev.c @@ -630,7 +630,7 @@ islpci_alloc_memory(islpci_private *priv) printk(KERN_DEBUG "islpci_alloc_memory\n"); #endif - /* remap the PCI device base address to accessable */ + /* remap the PCI device base address to accessible */ if (!(priv->device_base = ioremap(pci_resource_start(priv->pdev, 0), ISL38XX_PCI_MEM_SIZE))) { @@ -709,7 +709,7 @@ islpci_alloc_memory(islpci_private *priv) PCI_DMA_FROMDEVICE); if (!priv->pci_map_rx_address[counter]) { /* error mapping the buffer to device - accessable memory address */ + accessible memory address */ printk(KERN_ERR "failed to map skb DMA'able\n"); goto out_free; } @@ -773,7 +773,7 @@ islpci_free_memory(islpci_private *priv) priv->data_low_rx[counter] = NULL; } - /* Free the acces control list and the WPA list */ + /* Free the access control list and the WPA list */ prism54_acl_clean(&priv->acl); prism54_wpa_bss_ie_clean(priv); mgt_clean(priv); diff --git a/drivers/net/wireless/prism54/islpci_eth.c b/drivers/net/wireless/prism54/islpci_eth.c index 2fc52bc2d7dd..d44f8e20cce0 100644 --- a/drivers/net/wireless/prism54/islpci_eth.c +++ b/drivers/net/wireless/prism54/islpci_eth.c @@ -450,7 +450,7 @@ islpci_eth_receive(islpci_private *priv) MAX_FRAGMENT_SIZE_RX + 2, PCI_DMA_FROMDEVICE); if (unlikely(!priv->pci_map_rx_address[index])) { - /* error mapping the buffer to device accessable memory address */ + /* error mapping the buffer to device accessible memory address */ DEBUG(SHOW_ERROR_MESSAGES, "Error mapping DMA address\n"); diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c index c3c206a97d54..a7d3f4c3ee0d 100644 --- a/drivers/net/wireless/rt2x00/rt2x00mac.c +++ b/drivers/net/wireless/rt2x00/rt2x00mac.c @@ -274,7 +274,7 @@ int rt2x00mac_add_interface(struct ieee80211_hw *hw, intf->beacon = entry; /* - * The MAC adddress must be configured after the device + * The MAC address must be configured after the device * has been initialized. Otherwise the device can reset * the MAC registers. * The BSSID address must only be configured in AP mode, diff --git a/drivers/net/wireless/wl3501_cs.c b/drivers/net/wireless/wl3501_cs.c index ee82df62e646..3e5befe4d03b 100644 --- a/drivers/net/wireless/wl3501_cs.c +++ b/drivers/net/wireless/wl3501_cs.c @@ -192,7 +192,7 @@ static inline void wl3501_switch_page(struct wl3501_card *this, u8 page) } /* - * Get Ethernet MAC addresss. + * Get Ethernet MAC address. * * WARNING: We switch to FPAGE0 and switc back again. * Making sure there is no other WL function beening called by ISR. diff --git a/drivers/pcmcia/m32r_cfc.h b/drivers/pcmcia/m32r_cfc.h index 8146e3bee2e8..f558e1adf954 100644 --- a/drivers/pcmcia/m32r_cfc.h +++ b/drivers/pcmcia/m32r_cfc.h @@ -9,7 +9,7 @@ #endif /* - * M32R PC Card Controler + * M32R PC Card Controller */ #define M32R_PCC0_BASE 0x00ef7000 #define M32R_PCC1_BASE 0x00ef7020 diff --git a/drivers/pcmcia/m32r_pcc.h b/drivers/pcmcia/m32r_pcc.h index e4fffe417ba9..f95c58563bc8 100644 --- a/drivers/pcmcia/m32r_pcc.h +++ b/drivers/pcmcia/m32r_pcc.h @@ -5,7 +5,7 @@ #define M32R_MAX_PCC 2 /* - * M32R PC Card Controler + * M32R PC Card Controller */ #define M32R_PCC0_BASE 0x00ef7000 #define M32R_PCC1_BASE 0x00ef7020 diff --git a/drivers/pcmcia/m8xx_pcmcia.c b/drivers/pcmcia/m8xx_pcmcia.c index 99d4f23cb435..0db482771fb5 100644 --- a/drivers/pcmcia/m8xx_pcmcia.c +++ b/drivers/pcmcia/m8xx_pcmcia.c @@ -1198,7 +1198,7 @@ static int __init m8xx_probe(struct platform_device *ofdev, out_be32(M8XX_PGCRX(1), M8XX_PGCRX_CXOE | (mk_int_int_mask(hwirq) << 16)); - /* intialize the fixed memory windows */ + /* initialize the fixed memory windows */ for (i = 0; i < PCMCIA_SOCKETS_NO; i++) { for (m = 0; m < PCMCIA_MEM_WIN_NO; m++) { diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index 2d61186ad5a2..304333faf441 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c @@ -7193,7 +7193,7 @@ static struct ibm_struct volume_driver_data = { * TPACPI_FAN_WR_ACPI_FANS (X31/X40/X41) * * FIRMWARE BUG: on some models, EC 0x2f might not be initialized at - * boot. Apparently the EC does not intialize it, so unless ACPI DSDT + * boot. Apparently the EC does not initialize it, so unless ACPI DSDT * does so, its initial value is meaningless (0x07). * * For firmware bugs, refer to: diff --git a/drivers/power/s3c_adc_battery.c b/drivers/power/s3c_adc_battery.c index fe16b482e912..4a8ae3935b3b 100644 --- a/drivers/power/s3c_adc_battery.c +++ b/drivers/power/s3c_adc_battery.c @@ -1,5 +1,5 @@ /* - * iPAQ h1930/h1940/rx1950 battery controler driver + * iPAQ h1930/h1940/rx1950 battery controller driver * Copyright (c) Vasily Khoruzhick * Based on h1940_battery.c by Arnaud Patard * @@ -427,5 +427,5 @@ static void __exit s3c_adc_bat_exit(void) module_exit(s3c_adc_bat_exit); MODULE_AUTHOR("Vasily Khoruzhick "); -MODULE_DESCRIPTION("iPAQ H1930/H1940/RX1950 battery controler driver"); +MODULE_DESCRIPTION("iPAQ H1930/H1940/RX1950 battery controller driver"); MODULE_LICENSE("GPL"); diff --git a/drivers/s390/net/lcs.c b/drivers/s390/net/lcs.c index 0f19d540b655..122382dc4684 100644 --- a/drivers/s390/net/lcs.c +++ b/drivers/s390/net/lcs.c @@ -840,7 +840,7 @@ lcs_notify_lancmd_waiters(struct lcs_card *card, struct lcs_cmd *cmd) } /** - * Emit buffer of a lan comand. + * Emit buffer of a lan command. */ static void lcs_lancmd_timeout(unsigned long data) diff --git a/drivers/s390/scsi/zfcp_cfdc.c b/drivers/s390/scsi/zfcp_cfdc.c index d692e229ecba..4c09d03bcb32 100644 --- a/drivers/s390/scsi/zfcp_cfdc.c +++ b/drivers/s390/scsi/zfcp_cfdc.c @@ -317,7 +317,7 @@ static void zfcp_act_eval_err(struct zfcp_adapter *adapter, u32 table) /** * zfcp_cfdc_port_denied - Process "access denied" for port - * @port: The port where the acces has been denied + * @port: The port where the access has been denied * @qual: The FSF status qualifier for the access denied FSF status */ void zfcp_cfdc_port_denied(struct zfcp_port *port, diff --git a/drivers/scsi/a100u2w.c b/drivers/scsi/a100u2w.c index dbbc601948e5..7cb575654e40 100644 --- a/drivers/scsi/a100u2w.c +++ b/drivers/scsi/a100u2w.c @@ -416,7 +416,7 @@ static u8 orc_load_firmware(struct orc_host * host) /* Go back and check they match */ outb(PRGMRST | DOWNLOAD, host->base + ORC_RISCCTL); /* Reset program count 0 */ - bios_addr -= 0x1000; /* Reset the BIOS adddress */ + bios_addr -= 0x1000; /* Reset the BIOS address */ for (i = 0, data32_ptr = (u8 *) & data32; /* Check the code */ i < 0x1000; /* Firmware code size = 4K */ i++, bios_addr++) { diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c index afc9aeba5edb..060ac4bd5a14 100644 --- a/drivers/scsi/aacraid/commsup.c +++ b/drivers/scsi/aacraid/commsup.c @@ -91,7 +91,7 @@ void aac_fib_map_free(struct aac_dev *dev) * aac_fib_setup - setup the fibs * @dev: Adapter to set up * - * Allocate the PCI space for the fibs, map it and then intialise the + * Allocate the PCI space for the fibs, map it and then initialise the * fib area, the unmapped fib data and also the free list */ diff --git a/drivers/scsi/aic7xxx_old/aic7xxx.seq b/drivers/scsi/aic7xxx_old/aic7xxx.seq index 5997e7c3a191..1565be9ebd49 100644 --- a/drivers/scsi/aic7xxx_old/aic7xxx.seq +++ b/drivers/scsi/aic7xxx_old/aic7xxx.seq @@ -1178,7 +1178,7 @@ notFound: /* * Retrieve an SCB by SCBID first searching the disconnected list falling * back to DMA'ing the SCB down from the host. This routine assumes that - * ARG_1 is the SCBID of interrest and that SINDEX is the position in the + * ARG_1 is the SCBID of interest and that SINDEX is the position in the * disconnected list to start the search from. If SINDEX is SCB_LIST_NULL, * we go directly to the host for the SCB. */ diff --git a/drivers/scsi/aic94xx/aic94xx_reg_def.h b/drivers/scsi/aic94xx/aic94xx_reg_def.h index 28aaf349c111..40273a747d29 100644 --- a/drivers/scsi/aic94xx/aic94xx_reg_def.h +++ b/drivers/scsi/aic94xx/aic94xx_reg_def.h @@ -1689,7 +1689,7 @@ #define PHY_START_CAL 0x01 /* - * HST_PCIX2 Registers, Addresss Range: (0x00-0xFC) + * HST_PCIX2 Registers, Address Range: (0x00-0xFC) */ #define PCIX_REG_BASE_ADR 0xB8040000 @@ -1802,7 +1802,7 @@ #define PCIC_TP_CTRL 0xFC /* - * EXSI Registers, Addresss Range: (0x00-0xFC) + * EXSI Registers, Address Range: (0x00-0xFC) */ #define EXSI_REG_BASE_ADR REG_BASE_ADDR_EXSI diff --git a/drivers/scsi/aic94xx/aic94xx_seq.c b/drivers/scsi/aic94xx/aic94xx_seq.c index 74374618010c..390168f62a13 100644 --- a/drivers/scsi/aic94xx/aic94xx_seq.c +++ b/drivers/scsi/aic94xx/aic94xx_seq.c @@ -797,7 +797,7 @@ static void asd_init_lseq_mdp(struct asd_ha_struct *asd_ha, int lseq) int j; /* Start from Page 1 of Mode 0 and 1. */ moffs = LSEQ_PAGE_SIZE + i*LSEQ_MODE_SCRATCH_SIZE; - /* All the fields of page 1 can be intialized to 0. */ + /* All the fields of page 1 can be initialized to 0. */ for (j = 0; j < LSEQ_PAGE_SIZE; j += 4) asd_write_reg_dword(asd_ha, LmSCRATCH(lseq)+moffs+j,0); } @@ -938,7 +938,7 @@ static void asd_init_cseq_cio(struct asd_ha_struct *asd_ha) asd_write_reg_dword(asd_ha, SCBPRO, 0); asd_write_reg_dword(asd_ha, CSEQCON, 0); - /* Intialize CSEQ Mode 11 Interrupt Vectors. + /* Initialize CSEQ Mode 11 Interrupt Vectors. * The addresses are 16 bit wide and in dword units. * The values of their macros are in byte units. * Thus we have to divide by 4. */ @@ -961,7 +961,7 @@ static void asd_init_cseq_cio(struct asd_ha_struct *asd_ha) asd_write_reg_word(asd_ha, CPRGMCNT, cseq_idle_loop); for (i = 0; i < 8; i++) { - /* Intialize Mode n Link m Interrupt Enable. */ + /* Initialize Mode n Link m Interrupt Enable. */ asd_write_reg_dword(asd_ha, CMnINTEN(i), EN_CMnRSPMBXF); /* Initialize Mode n Request Mailbox. */ asd_write_reg_dword(asd_ha, CMnREQMBX(i), 0); diff --git a/drivers/scsi/bfa/bfa_fcpim.c b/drivers/scsi/bfa/bfa_fcpim.c index 33c8dd51f474..aabbf3d3b394 100644 --- a/drivers/scsi/bfa/bfa_fcpim.c +++ b/drivers/scsi/bfa/bfa_fcpim.c @@ -2092,7 +2092,7 @@ bfa_ioim_sm_cleanup_qfull(struct bfa_ioim_s *ioim, enum bfa_ioim_event event) case BFA_IOIM_SM_ABORT: /** - * IO is alraedy being cleaned up implicitly + * IO is already being cleaned up implicitly */ ioim->io_cbfn = __bfa_cb_ioim_abort; break; diff --git a/drivers/scsi/bfa/bfa_fcs_lport.c b/drivers/scsi/bfa/bfa_fcs_lport.c index b522bf30247a..b7aa23a3b1e8 100644 --- a/drivers/scsi/bfa/bfa_fcs_lport.c +++ b/drivers/scsi/bfa/bfa_fcs_lport.c @@ -5742,7 +5742,7 @@ bfa_cb_lps_fdisc_comp(void *bfad, void *uarg, bfa_status_t status) switch (status) { case BFA_STATUS_OK: /* - * Initialiaze the V-Port fields + * Initialize the V-Port fields */ __vport_fcid(vport) = bfa_lps_get_pid(vport->lps); vport->vport_stats.fdisc_accepts++; diff --git a/drivers/scsi/dc395x.c b/drivers/scsi/dc395x.c index 54f50b07dac7..31bbfb244bc4 100644 --- a/drivers/scsi/dc395x.c +++ b/drivers/scsi/dc395x.c @@ -3795,7 +3795,7 @@ static struct DeviceCtlBlk *device_alloc(struct AdapterCtlBlk *acb, * adapter_add_device - Adds the device instance to the adaptor instance. * * @acb: The adapter device to be updated - * @dcb: A newly created and intialised device instance to add. + * @dcb: A newly created and initialised device instance to add. **/ static void adapter_add_device(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb) @@ -4497,7 +4497,7 @@ static void __devinit adapter_init_chip(struct AdapterCtlBlk *acb) * init_adapter - Grab the resource for the card, setup the adapter * information, set the card into a known state, create the various * tables etc etc. This basically gets all adapter information all up - * to date, intialised and gets the chip in sync with it. + * to date, initialised and gets the chip in sync with it. * * @host: This hosts adapter structure * @io_port: The base I/O port @@ -4788,7 +4788,7 @@ static void banner_display(void) * that it finds in the system. The pci_dev strcuture indicates which * instance we are being called from. * - * @dev: The PCI device to intialize. + * @dev: The PCI device to initialize. * @id: Looks like a pointer to the entry in our pci device table * that was actually matched by the PCI subsystem. * @@ -4859,7 +4859,7 @@ fail: * dc395x_remove_one - Called to remove a single instance of the * adapter. * - * @dev: The PCI device to intialize. + * @dev: The PCI device to initialize. **/ static void __devexit dc395x_remove_one(struct pci_dev *dev) { diff --git a/drivers/scsi/libfc/fc_fcp.c b/drivers/scsi/libfc/fc_fcp.c index c797f6b48f05..54a6ec8e131d 100644 --- a/drivers/scsi/libfc/fc_fcp.c +++ b/drivers/scsi/libfc/fc_fcp.c @@ -1212,7 +1212,7 @@ static void fc_lun_reset_send(unsigned long data) /** * fc_lun_reset() - Send a LUN RESET command to a device * and wait for the reply - * @lport: The local port to sent the comand on + * @lport: The local port to sent the command on * @fsp: The FCP packet that identifies the LUN to be reset * @id: The SCSI command ID * @lun: The LUN ID to be reset diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c index f681eea57730..0e4abb96d68e 100644 --- a/drivers/scsi/lpfc/lpfc_attr.c +++ b/drivers/scsi/lpfc/lpfc_attr.c @@ -1339,7 +1339,7 @@ lpfc_##attr##_show(struct device *dev, struct device_attribute *attr, \ } /** - * lpfc_param_init - Intializes a cfg attribute + * lpfc_param_init - Initializes a cfg attribute * * Description: * Macro that given an attr e.g. hba_queue_depth expands diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index a345dde16c86..2a6866e63aae 100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c @@ -2614,7 +2614,7 @@ lpfc_mbx_process_link_up(struct lpfc_hba *phba, READ_LA_VAR *la) if (unlikely(!fcf_record)) { lpfc_printf_log(phba, KERN_ERR, LOG_MBOX | LOG_SLI, - "2554 Could not allocate memmory for " + "2554 Could not allocate memory for " "fcf record\n"); rc = -ENODEV; goto out; diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index 0d1e187b005d..c5614cfcc6e9 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c @@ -9619,7 +9619,7 @@ lpfc_sli4_intr_handler(int irq, void *dev_id) * lpfc_sli4_queue_free - free a queue structure and associated memory * @queue: The queue structure to free. * - * This function frees a queue structure and the DMAable memeory used for + * This function frees a queue structure and the DMAable memory used for * the host resident queue. This function must be called after destroying the * queue on the HBA. **/ diff --git a/drivers/scsi/megaraid.h b/drivers/scsi/megaraid.h index 2b4a048cadf1..deb24ad1b8d2 100644 --- a/drivers/scsi/megaraid.h +++ b/drivers/scsi/megaraid.h @@ -13,7 +13,7 @@ */ /* - * Comand coalescing - This feature allows the driver to be able to combine + * Command coalescing - This feature allows the driver to be able to combine * two or more commands and issue as one command in order to boost I/O * performance. Useful if the nature of the I/O is sequential. It is not very * useful for random natured I/Os. diff --git a/drivers/scsi/pm8001/pm8001_init.c b/drivers/scsi/pm8001/pm8001_init.c index f8c86b28f03f..b95285f3383f 100644 --- a/drivers/scsi/pm8001/pm8001_init.c +++ b/drivers/scsi/pm8001/pm8001_init.c @@ -603,7 +603,7 @@ static u32 pm8001_request_irq(struct pm8001_hba_info *pm8001_ha) #endif intx: - /* intialize the INT-X interrupt */ + /* initialize the INT-X interrupt */ rc = request_irq(pdev->irq, irq_handler, IRQF_SHARED, DRV_NAME, SHOST_TO_SAS_HA(pm8001_ha->shost)); return rc; diff --git a/drivers/scsi/scsi_netlink.c b/drivers/scsi/scsi_netlink.c index d53e6503c6d5..a2ed201885ae 100644 --- a/drivers/scsi/scsi_netlink.c +++ b/drivers/scsi/scsi_netlink.c @@ -477,7 +477,7 @@ EXPORT_SYMBOL_GPL(scsi_nl_remove_driver); /** - * scsi_netlink_init - Called by SCSI subsystem to intialize + * scsi_netlink_init - Called by SCSI subsystem to initialize * the SCSI transport netlink interface * **/ diff --git a/drivers/scsi/sym53c8xx_2/sym_glue.c b/drivers/scsi/sym53c8xx_2/sym_glue.c index 8b955b534a36..4afa81ad2caa 100644 --- a/drivers/scsi/sym53c8xx_2/sym_glue.c +++ b/drivers/scsi/sym53c8xx_2/sym_glue.c @@ -1864,7 +1864,7 @@ static pci_ers_result_t sym2_io_slot_dump(struct pci_dev *pdev) * * This routine is similar to sym_set_workarounds(), except * that, at this point, we already know that the device was - * successfully intialized at least once before, and so most + * successfully initialized at least once before, and so most * of the steps taken there are un-needed here. */ static void sym2_reset_workarounds(struct pci_dev *pdev) diff --git a/drivers/spi/atmel_spi.c b/drivers/spi/atmel_spi.c index 154529aacc03..49596a18f953 100644 --- a/drivers/spi/atmel_spi.c +++ b/drivers/spi/atmel_spi.c @@ -341,9 +341,9 @@ static void atmel_spi_next_message(struct spi_master *master) /* * For DMA, tx_buf/tx_dma have the same relationship as rx_buf/rx_dma: * - The buffer is either valid for CPU access, else NULL - * - If the buffer is valid, so is its DMA addresss + * - If the buffer is valid, so is its DMA address * - * This driver manages the dma addresss unless message->is_dma_mapped. + * This driver manages the dma address unless message->is_dma_mapped. */ static int atmel_spi_dma_map_xfer(struct atmel_spi *as, struct spi_transfer *xfer) diff --git a/drivers/spi/spidev.c b/drivers/spi/spidev.c index 4e6245e67995..603428213d21 100644 --- a/drivers/spi/spidev.c +++ b/drivers/spi/spidev.c @@ -38,7 +38,7 @@ /* - * This supports acccess to SPI devices using normal userspace I/O calls. + * This supports access to SPI devices using normal userspace I/O calls. * Note that while traditional UNIX/POSIX I/O semantics are half duplex, * and often mask message boundaries, full SPI support requires full duplex * transfers. There are several kinds of internal message boundaries to diff --git a/drivers/staging/stradis/stradis.c b/drivers/staging/stradis/stradis.c index a057824e7ebc..dd3874b78263 100644 --- a/drivers/staging/stradis/stradis.c +++ b/drivers/staging/stradis/stradis.c @@ -745,7 +745,7 @@ static void set_out_format(struct saa7146 *saa, int mode) } } -/* Intialize bitmangler to map from a byte value to the mangled word that +/* Initialize bitmangler to map from a byte value to the mangled word that * must be output to program the Xilinx part through the DEBI port. * Xilinx Data Bit->DEBI Bit: 0->15 1->7 2->6 3->12 4->11 5->2 6->1 7->0 * transfer FPGA code, init IBM chip, transfer IBM microcode diff --git a/drivers/usb/gadget/imx_udc.c b/drivers/usb/gadget/imx_udc.c index ed0266462c57..1f8084d59a43 100644 --- a/drivers/usb/gadget/imx_udc.c +++ b/drivers/usb/gadget/imx_udc.c @@ -1316,7 +1316,7 @@ static struct imx_udc_struct controller = { }; /******************************************************************************* - * USB gadged driver functions + * USB gadget driver functions ******************************************************************************* */ int usb_gadget_probe_driver(struct usb_gadget_driver *driver, diff --git a/drivers/usb/host/imx21-hcd.c b/drivers/usb/host/imx21-hcd.c index e49b75a78000..f90d003f2302 100644 --- a/drivers/usb/host/imx21-hcd.c +++ b/drivers/usb/host/imx21-hcd.c @@ -1658,7 +1658,7 @@ static int imx21_hc_reset(struct usb_hcd *hcd) spin_lock_irqsave(&imx21->lock, flags); - /* Reset the Host controler modules */ + /* Reset the Host controller modules */ writel(USBOTG_RST_RSTCTRL | USBOTG_RST_RSTRH | USBOTG_RST_RSTHSIE | USBOTG_RST_RSTHC, imx21->regs + USBOTG_RST_CTRL); diff --git a/drivers/usb/host/oxu210hp-hcd.c b/drivers/usb/host/oxu210hp-hcd.c index 32149be4ad8e..e0cb12b573f9 100644 --- a/drivers/usb/host/oxu210hp-hcd.c +++ b/drivers/usb/host/oxu210hp-hcd.c @@ -3094,7 +3094,7 @@ static int oxu_hub_status_data(struct usb_hcd *hcd, char *buf) /* Some boards (mostly VIA?) report bogus overcurrent indications, * causing massive log spam unless we completely ignore them. It - * may be relevant that VIA VT8235 controlers, where PORT_POWER is + * may be relevant that VIA VT8235 controllers, where PORT_POWER is * always set, seem to clear PORT_OCC and PORT_CSC when writing to * PORT_POWER; that's surprising, but maybe within-spec. */ diff --git a/drivers/usb/misc/adutux.c b/drivers/usb/misc/adutux.c index 44f8b9225054..a6afd15f6a46 100644 --- a/drivers/usb/misc/adutux.c +++ b/drivers/usb/misc/adutux.c @@ -717,7 +717,7 @@ static int adu_probe(struct usb_interface *interface, goto exit; } - /* allocate memory for our device state and intialize it */ + /* allocate memory for our device state and initialize it */ dev = kzalloc(sizeof(struct adu_device), GFP_KERNEL); if (dev == NULL) { dev_err(&interface->dev, "Out of memory\n"); diff --git a/drivers/usb/misc/iowarrior.c b/drivers/usb/misc/iowarrior.c index 375664198776..7a10e48b78f9 100644 --- a/drivers/usb/misc/iowarrior.c +++ b/drivers/usb/misc/iowarrior.c @@ -768,7 +768,7 @@ static int iowarrior_probe(struct usb_interface *interface, int i; int retval = -ENOMEM; - /* allocate memory for our device state and intialize it */ + /* allocate memory for our device state and initialize it */ dev = kzalloc(sizeof(struct iowarrior), GFP_KERNEL); if (dev == NULL) { dev_err(&interface->dev, "Out of memory\n"); diff --git a/drivers/usb/misc/ldusb.c b/drivers/usb/misc/ldusb.c index edffef642337..eefb8275bb7e 100644 --- a/drivers/usb/misc/ldusb.c +++ b/drivers/usb/misc/ldusb.c @@ -642,7 +642,7 @@ static int ld_usb_probe(struct usb_interface *intf, const struct usb_device_id * int i; int retval = -ENOMEM; - /* allocate memory for our device state and intialize it */ + /* allocate memory for our device state and initialize it */ dev = kzalloc(sizeof(*dev), GFP_KERNEL); if (dev == NULL) { diff --git a/drivers/usb/musb/musb_gadget.c b/drivers/usb/musb/musb_gadget.c index 5d815049cbaa..1cbeaa17ffff 100644 --- a/drivers/usb/musb/musb_gadget.c +++ b/drivers/usb/musb/musb_gadget.c @@ -1636,7 +1636,7 @@ static inline void __init musb_g_init_endpoints(struct musb *musb) struct musb_hw_ep *hw_ep; unsigned count = 0; - /* intialize endpoint list just once */ + /* initialize endpoint list just once */ INIT_LIST_HEAD(&(musb->g.ep_list)); for (epnum = 0, hw_ep = musb->endpoints; @@ -1715,7 +1715,7 @@ void musb_gadget_cleanup(struct musb *musb) * * -EINVAL something went wrong (not driver) * -EBUSY another gadget is already using the controller - * -ENOMEM no memeory to perform the operation + * -ENOMEM no memory to perform the operation * * @param driver the gadget driver * @param bind the driver's bind function diff --git a/drivers/usb/wusbcore/wa-rpipe.c b/drivers/usb/wusbcore/wa-rpipe.c index c7b1d8108de9..8cb9d80207fa 100644 --- a/drivers/usb/wusbcore/wa-rpipe.c +++ b/drivers/usb/wusbcore/wa-rpipe.c @@ -49,7 +49,7 @@ * * USB Stack port number 4 (1 based) * WUSB code port index 3 (0 based) - * USB Addresss 5 (2 based -- 0 is for default, 1 for root hub) + * USB Address 5 (2 based -- 0 is for default, 1 for root hub) * * Now, because we don't use the concept as default address exactly * like the (wired) USB code does, we need to kind of skip it. So we diff --git a/drivers/video/sstfb.c b/drivers/video/sstfb.c index dee64c3b1e67..2ab704118c44 100644 --- a/drivers/video/sstfb.c +++ b/drivers/video/sstfb.c @@ -536,7 +536,7 @@ static int sstfb_set_par(struct fb_info *info) fbiinit2 = sst_read(FBIINIT2); fbiinit3 = sst_read(FBIINIT3); - /* everything is reset. we enable fbiinit2/3 remap : dac acces ok */ + /* everything is reset. we enable fbiinit2/3 remap : dac access ok */ pci_write_config_dword(sst_dev, PCI_INIT_ENABLE, PCI_EN_INIT_WR | PCI_REMAP_DAC ); diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index 8b5dd6369f82..47162de0b957 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h @@ -577,7 +577,7 @@ struct ext4_mount_options { #endif }; -/* Max physical block we can addres w/o extents */ +/* Max physical block we can address w/o extents */ #define EXT4_MAX_BLOCK_FILE_PHYS 0xFFFFFFFF /* diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index 0554c48cb1fd..966ecb0d8f86 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c @@ -2825,14 +2825,14 @@ fix_extent_len: * to an uninitialized extent. * * Writing to an uninitized extent may result in splitting the uninitialized - * extent into multiple /intialized unintialized extents (up to three) + * extent into multiple /initialized uninitialized extents (up to three) * There are three possibilities: * a> There is no split required: Entire extent should be uninitialized * b> Splits in two extents: Write is happening at either end of the extent * c> Splits in three extents: Somone is writing in middle of the extent * * One of more index blocks maybe needed if the extent tree grow after - * the unintialized extent split. To prevent ENOSPC occur at the IO + * the uninitialized extent split. To prevent ENOSPC occur at the IO * complete, we need to split the uninitialized extent before DIO submit * the IO. The uninitialized extent called at this time will be split * into three uninitialized extent(at most). After IO complete, the part diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 191616470466..4bc84b8adb7f 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -3740,9 +3740,9 @@ retry: * preallocated extents, and those write extend the file, no need to * fall back to buffered IO. * - * For holes, we fallocate those blocks, mark them as unintialized + * For holes, we fallocate those blocks, mark them as uninitialized * If those blocks were preallocated, we mark sure they are splited, but - * still keep the range to write as unintialized. + * still keep the range to write as uninitialized. * * The unwrritten extents will be converted to written when DIO is completed. * For async direct IO, since the IO may still pending when return, we diff --git a/fs/ocfs2/inode.c b/fs/ocfs2/inode.c index f935fd6600dd..4068c6c4c6f6 100644 --- a/fs/ocfs2/inode.c +++ b/fs/ocfs2/inode.c @@ -434,7 +434,7 @@ static int ocfs2_read_locked_inode(struct inode *inode, * #1 and #2 can be simply solved by never taking the lock * here for system files (which are the only type we read * during mount). It's a heavier approach, but our main - * concern is user-accesible files anyway. + * concern is user-accessible files anyway. * * #3 works itself out because we'll eventually take the * cluster lock before trusting anything anyway. diff --git a/fs/ocfs2/suballoc.c b/fs/ocfs2/suballoc.c index 5fed60de7630..71998d4d61d5 100644 --- a/fs/ocfs2/suballoc.c +++ b/fs/ocfs2/suballoc.c @@ -1916,7 +1916,7 @@ static int ocfs2_claim_suballoc_bits(struct ocfs2_alloc_context *ac, if (res->sr_bg_blkno) { /* Attempt to short-circuit the usual search mechanism * by jumping straight to the most recently used - * allocation group. This helps us mantain some + * allocation group. This helps us maintain some * contiguousness across allocations. */ status = ocfs2_search_one_group(ac, handle, bits_wanted, min_bits, res, &bits_left); diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c index 9f3a78fe6ae4..7465a7ffc4fd 100644 --- a/fs/xfs/linux-2.6/xfs_super.c +++ b/fs/xfs/linux-2.6/xfs_super.c @@ -938,7 +938,7 @@ out_reclaim: * Slab object creation initialisation for the XFS inode. * This covers only the idempotent fields in the XFS inode; * all other fields need to be initialised on allocation - * from the slab. This avoids the need to repeatedly intialise + * from the slab. This avoids the need to repeatedly initialise * fields in the xfs inode that left in the initialise state * when freeing the inode. */ diff --git a/include/acpi/actbl1.h b/include/acpi/actbl1.h index c637b75b9f3f..cd77aa75c962 100644 --- a/include/acpi/actbl1.h +++ b/include/acpi/actbl1.h @@ -119,7 +119,7 @@ struct acpi_whea_header { struct acpi_table_bert { struct acpi_table_header header; /* Common ACPI table header */ u32 region_length; /* Length of the boot error region */ - u64 address; /* Physical addresss of the error region */ + u64 address; /* Physical address of the error region */ }; /* Boot Error Region (not a subtable, pointed to by Address field above) */ diff --git a/include/linux/cgroup.h b/include/linux/cgroup.h index ed4ba111bc8d..ce104e33cd22 100644 --- a/include/linux/cgroup.h +++ b/include/linux/cgroup.h @@ -564,7 +564,7 @@ struct cgroup_iter { /* * To iterate across the tasks in a cgroup: * - * 1) call cgroup_iter_start to intialize an iterator + * 1) call cgroup_iter_start to initialize an iterator * * 2) call cgroup_iter_next() to retrieve member tasks until it * returns NULL or until you want to end the iteration diff --git a/include/linux/firewire-cdev.h b/include/linux/firewire-cdev.h index 68c642d8843d..59ea406be7f6 100644 --- a/include/linux/firewire-cdev.h +++ b/include/linux/firewire-cdev.h @@ -273,7 +273,7 @@ struct fw_cdev_event_iso_interrupt { * @closure: See &fw_cdev_event_common; * set by %FW_CDEV_CREATE_ISO_CONTEXT ioctl * @type: %FW_CDEV_EVENT_ISO_INTERRUPT_MULTICHANNEL - * @completed: Offset into the receive buffer; data before this offest is valid + * @completed: Offset into the receive buffer; data before this offset is valid * * This event is sent in multichannel contexts (context type * %FW_CDEV_ISO_CONTEXT_RECEIVE_MULTICHANNEL) for &fw_cdev_iso_packet buffer diff --git a/include/linux/mfd/core.h b/include/linux/mfd/core.h index cb93d80aa642..5582ab3d3e48 100644 --- a/include/linux/mfd/core.h +++ b/include/linux/mfd/core.h @@ -39,7 +39,7 @@ struct mfd_cell { size_t data_size; /* - * This resources can be specified relatievly to the parent device. + * This resources can be specified relatively to the parent device. * For accessing device you should use resources from device */ int num_resources; diff --git a/include/net/sctp/user.h b/include/net/sctp/user.h index 2b2769c5ca9f..2a128c8c2718 100644 --- a/include/net/sctp/user.h +++ b/include/net/sctp/user.h @@ -99,8 +99,8 @@ typedef __s32 sctp_assoc_t; #define SCTP_SOCKOPT_PEELOFF 102 /* peel off association. */ /* Options 104-106 are deprecated and removed. Do not use this space */ #define SCTP_SOCKOPT_CONNECTX_OLD 107 /* CONNECTX old requests. */ -#define SCTP_GET_PEER_ADDRS 108 /* Get all peer addresss. */ -#define SCTP_GET_LOCAL_ADDRS 109 /* Get all local addresss. */ +#define SCTP_GET_PEER_ADDRS 108 /* Get all peer address. */ +#define SCTP_GET_LOCAL_ADDRS 109 /* Get all local address. */ #define SCTP_SOCKOPT_CONNECTX 110 /* CONNECTX requests. */ #define SCTP_SOCKOPT_CONNECTX3 111 /* CONNECTX requests (updated) */ diff --git a/include/scsi/fc/fc_fcp.h b/include/scsi/fc/fc_fcp.h index 8e9b222251c2..8a143ca79878 100644 --- a/include/scsi/fc/fc_fcp.h +++ b/include/scsi/fc/fc_fcp.h @@ -46,7 +46,7 @@ */ struct fcp_cmnd { __u8 fc_lun[8]; /* logical unit number */ - __u8 fc_cmdref; /* commmand reference number */ + __u8 fc_cmdref; /* command reference number */ __u8 fc_pri_ta; /* priority and task attribute */ __u8 fc_tm_flags; /* task management flags */ __u8 fc_flags; /* additional len & flags */ @@ -58,7 +58,7 @@ struct fcp_cmnd { struct fcp_cmnd32 { __u8 fc_lun[8]; /* logical unit number */ - __u8 fc_cmdref; /* commmand reference number */ + __u8 fc_cmdref; /* command reference number */ __u8 fc_pri_ta; /* priority and task attribute */ __u8 fc_tm_flags; /* task management flags */ __u8 fc_flags; /* additional len & flags */ diff --git a/kernel/debug/kdb/kdb_main.c b/kernel/debug/kdb/kdb_main.c index 37755d621924..7242cc71bb7e 100644 --- a/kernel/debug/kdb/kdb_main.c +++ b/kernel/debug/kdb/kdb_main.c @@ -2913,7 +2913,7 @@ static void __init kdb_cmd_init(void) } } -/* Intialize kdb_printf, breakpoint tables and kdb state */ +/* Initialize kdb_printf, breakpoint tables and kdb state */ void __init kdb_init(int lvl) { static int kdb_init_lvl = KDB_NOT_INITIALIZED; diff --git a/kernel/kexec.c b/kernel/kexec.c index b55045bc7563..ec19b92c7ebd 100644 --- a/kernel/kexec.c +++ b/kernel/kexec.c @@ -163,7 +163,7 @@ static int do_kimage_alloc(struct kimage **rimage, unsigned long entry, * just verifies it is an address we can use. * * Since the kernel does everything in page size chunks ensure - * the destination addreses are page aligned. Too many + * the destination addresses are page aligned. Too many * special cases crop of when we don't do this. The most * insidious is getting overlapping destination addresses * simply because addresses are changed to page size diff --git a/kernel/power/swap.c b/kernel/power/swap.c index a0e4a86ccf94..cd09c22de03d 100644 --- a/kernel/power/swap.c +++ b/kernel/power/swap.c @@ -865,7 +865,7 @@ out_finish: /** * swsusp_read - read the hibernation image. * @flags_p: flags passed by the "frozen" kernel in the image header should - * be written into this memeory location + * be written into this memory location */ int swsusp_read(unsigned int *flags_p) diff --git a/kernel/sched.c b/kernel/sched.c index aa14a56f9d03..554c0d6c489e 100644 --- a/kernel/sched.c +++ b/kernel/sched.c @@ -2568,7 +2568,7 @@ out: * try_to_wake_up_local - try to wake up a local task with rq lock held * @p: the thread to be awakened * - * Put @p on the run-queue if it's not alredy there. The caller must + * Put @p on the run-queue if it's not already there. The caller must * ensure that this_rq() is locked, @p is bound to this_rq() and not * the current task. this_rq() stays locked over invocation. */ diff --git a/kernel/sysctl_binary.c b/kernel/sysctl_binary.c index 1357c5786064..d9c5fe4ff1b2 100644 --- a/kernel/sysctl_binary.c +++ b/kernel/sysctl_binary.c @@ -1193,7 +1193,7 @@ static ssize_t bin_dn_node_address(struct file *file, buf[result] = '\0'; - /* Convert the decnet addresss to binary */ + /* Convert the decnet address to binary */ result = -EIO; nodep = strchr(buf, '.') + 1; if (!nodep) diff --git a/kernel/time/clocksource.c b/kernel/time/clocksource.c index c18d7efa1b4b..ddbbaf2950ef 100644 --- a/kernel/time/clocksource.c +++ b/kernel/time/clocksource.c @@ -678,7 +678,7 @@ EXPORT_SYMBOL_GPL(__clocksource_updatefreq_scale); int __clocksource_register_scale(struct clocksource *cs, u32 scale, u32 freq) { - /* Intialize mult/shift and max_idle_ns */ + /* Initialize mult/shift and max_idle_ns */ __clocksource_updatefreq_scale(cs, scale, freq); /* Add clocksource to the clcoksource list */ diff --git a/kernel/trace/trace_entries.h b/kernel/trace/trace_entries.h index e3dfecaf13e6..6cf223764be8 100644 --- a/kernel/trace/trace_entries.h +++ b/kernel/trace/trace_entries.h @@ -53,7 +53,7 @@ */ /* - * Function trace entry - function address and parent function addres: + * Function trace entry - function address and parent function address: */ FTRACE_ENTRY(function, ftrace_entry, diff --git a/lib/nlattr.c b/lib/nlattr.c index c4706eb98d3d..18d158df6f0e 100644 --- a/lib/nlattr.c +++ b/lib/nlattr.c @@ -167,7 +167,7 @@ nla_policy_len(const struct nla_policy *p, int n) * @policy: validation policy * * Parses a stream of attributes and stores a pointer to each attribute in - * the tb array accessable via the attribute type. Attributes with a type + * the tb array accessible via the attribute type. Attributes with a type * exceeding maxtype will be silently ignored for backwards compatibility * reasons. policy may be set to NULL if no validation is required. * diff --git a/lib/swiotlb.c b/lib/swiotlb.c index 7c06ee51a29a..c47bbe11b804 100644 --- a/lib/swiotlb.c +++ b/lib/swiotlb.c @@ -60,7 +60,7 @@ int swiotlb_force; static char *io_tlb_start, *io_tlb_end; /* - * The number of IO TLB blocks (in groups of 64) betweeen io_tlb_start and + * The number of IO TLB blocks (in groups of 64) between io_tlb_start and * io_tlb_end. This is command line adjustable via setup_io_tlb_npages. */ static unsigned long io_tlb_nslabs; diff --git a/mm/percpu.c b/mm/percpu.c index efe816856a9d..f715d01d5ba3 100644 --- a/mm/percpu.c +++ b/mm/percpu.c @@ -258,7 +258,7 @@ static void __maybe_unused pcpu_next_pop(struct pcpu_chunk *chunk, /* * (Un)populated page region iterators. Iterate over (un)populated - * page regions betwen @start and @end in @chunk. @rs and @re should + * page regions between @start and @end in @chunk. @rs and @re should * be integer variables and will be set to start and end page index of * the current region. */ diff --git a/mm/sparse-vmemmap.c b/mm/sparse-vmemmap.c index 29d6cbffb283..64b984091edb 100644 --- a/mm/sparse-vmemmap.c +++ b/mm/sparse-vmemmap.c @@ -9,7 +9,7 @@ * * However, virtual mappings need a page table and TLBs. Many Linux * architectures already map their physical space using 1-1 mappings - * via TLBs. For those arches the virtual memmory map is essentially + * via TLBs. For those arches the virtual memory map is essentially * for free if we use the same page size as the 1-1 mappings. In that * case the overhead consists of a few additional pages that are * allocated to create a view of memory for vmemmap. diff --git a/net/core/dev.c b/net/core/dev.c index 35dfb8318483..89204e8c0e14 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -6096,7 +6096,7 @@ static void __net_exit default_device_exit(struct net *net) static void __net_exit default_device_exit_batch(struct list_head *net_list) { /* At exit all network devices most be removed from a network - * namespace. Do this in the reverse order of registeration. + * namespace. Do this in the reverse order of registration. * Do this across as many network namespaces as possible to * improve batching efficiency. */ diff --git a/net/decnet/dn_dev.c b/net/decnet/dn_dev.c index 4c409b46aa35..9b73e0b03e34 100644 --- a/net/decnet/dn_dev.c +++ b/net/decnet/dn_dev.c @@ -1112,7 +1112,7 @@ static struct dn_dev *dn_dev_create(struct net_device *dev, int *err) /* * This processes a device up event. We only start up * the loopback device & ethernet devices with correct - * MAC addreses automatically. Others must be started + * MAC addresses automatically. Others must be started * specifically. * * FIXME: How should we configure the loopback address ? If we could dispense diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 05b1ecf36763..e96152207164 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c @@ -1336,7 +1336,7 @@ static inline unsigned int tcp_cwnd_test(struct tcp_sock *tp, return 0; } -/* Intialize TSO state of a skb. +/* Initialize TSO state of a skb. * This must be invoked the first time we consider transmitting * SKB onto the wire. */ diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c index 9df80114b47b..c06f1503aa8b 100644 --- a/scripts/kconfig/confdata.c +++ b/scripts/kconfig/confdata.c @@ -946,7 +946,7 @@ static void randomize_choice_values(struct symbol *csym) int cnt, def; /* - * If choice is mod then we may have more items slected + * If choice is mod then we may have more items selected * and if no then no-one. * In both cases stop. */ diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 33122ca04e7c..6619ed8843f9 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -1614,7 +1614,7 @@ static void section_rel(const char *modname, struct elf_info *elf, * A module includes a number of sections that are discarded * either when loaded or when used as built-in. * For loaded modules all functions marked __init and all data - * marked __initdata will be discarded when the module has been intialized. + * marked __initdata will be discarded when the module has been initialized. * Likewise for modules used built-in the sections marked __exit * are discarded because __exit marked function are supposed to be called * only when a module is unloaded which never happens for built-in modules. diff --git a/security/apparmor/include/match.h b/security/apparmor/include/match.h index 734a6d35112c..e00c3c7c96be 100644 --- a/security/apparmor/include/match.h +++ b/security/apparmor/include/match.h @@ -27,7 +27,7 @@ * The format used for transition tables is based on the GNU flex table * file format (--tables-file option; see Table File Format in the flex * info pages and the flex sources for documentation). The magic number - * used in the header is 0x1B5E783D insted of 0xF13C57B1 though, because + * used in the header is 0x1B5E783D instead of 0xF13C57B1 though, because * the YY_ID_CHK (check) and YY_ID_DEF (default) tables are used * slightly differently (see the apparmor-parser package). */ diff --git a/sound/core/init.c b/sound/core/init.c index 57b792e2439a..3e65da21a08c 100644 --- a/sound/core/init.c +++ b/sound/core/init.c @@ -642,7 +642,7 @@ static struct device_attribute card_number_attrs = * external accesses. Thus, you should call this function at the end * of the initialization of the card. * - * Returns zero otherwise a negative error code if the registrain failed. + * Returns zero otherwise a negative error code if the registration failed. */ int snd_card_register(struct snd_card *card) { diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index 8bc7cb3db330..8e022fc70f55 100644 --- a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c @@ -985,7 +985,7 @@ static int snd_pcm_do_pause(struct snd_pcm_substream *substream, int push) if (push) snd_pcm_update_hw_ptr(substream); /* The jiffies check in snd_pcm_update_hw_ptr*() is done by - * a delta betwen the current jiffies, this gives a large enough + * a delta between the current jiffies, this gives a large enough * delta, effectively to skip the check once. */ substream->runtime->hw_ptr_jiffies = jiffies - HZ * 1000; diff --git a/sound/isa/opl3sa2.c b/sound/isa/opl3sa2.c index 265abcce9dba..9b915e27b5bd 100644 --- a/sound/isa/opl3sa2.c +++ b/sound/isa/opl3sa2.c @@ -264,7 +264,7 @@ static int __devinit snd_opl3sa2_detect(struct snd_card *card) snd_printd("OPL3-SA [0x%lx] detect (1) = 0x%x (0x%x)\n", port, tmp, tmp1); return -ENODEV; } - /* try if the MIC register is accesible */ + /* try if the MIC register is accessible */ tmp = snd_opl3sa2_read(chip, OPL3SA2_MIC); snd_opl3sa2_write(chip, OPL3SA2_MIC, 0x8a); if (((tmp1 = snd_opl3sa2_read(chip, OPL3SA2_MIC)) & 0x9f) != 0x8a) { diff --git a/sound/pci/ca0106/ca0106.h b/sound/pci/ca0106/ca0106.h index f19c11077255..fc53b9bca26d 100644 --- a/sound/pci/ca0106/ca0106.h +++ b/sound/pci/ca0106/ca0106.h @@ -188,7 +188,7 @@ #define PLAYBACK_LIST_PTR 0x02 /* Pointer to the current period being played */ /* PTR[5:0], Default: 0x0 */ #define PLAYBACK_UNKNOWN3 0x03 /* Not used ?? */ -#define PLAYBACK_DMA_ADDR 0x04 /* Playback DMA addresss */ +#define PLAYBACK_DMA_ADDR 0x04 /* Playback DMA address */ /* DMA[31:0], Default: 0x0 */ #define PLAYBACK_PERIOD_SIZE 0x05 /* Playback period size. win2000 uses 0x04000000 */ /* SIZE[31:16], Default: 0x0 */ diff --git a/sound/pci/emu10k1/emu10k1x.c b/sound/pci/emu10k1/emu10k1x.c index df47f738098d..0c701e4ec8a5 100644 --- a/sound/pci/emu10k1/emu10k1x.c +++ b/sound/pci/emu10k1/emu10k1x.c @@ -114,7 +114,7 @@ MODULE_PARM_DESC(enable, "Enable the EMU10K1X soundcard."); */ #define PLAYBACK_LIST_SIZE 0x01 /* Size of list in bytes << 16. E.g. 8 periods -> 0x00380000 */ #define PLAYBACK_LIST_PTR 0x02 /* Pointer to the current period being played */ -#define PLAYBACK_DMA_ADDR 0x04 /* Playback DMA addresss */ +#define PLAYBACK_DMA_ADDR 0x04 /* Playback DMA address */ #define PLAYBACK_PERIOD_SIZE 0x05 /* Playback period size */ #define PLAYBACK_POINTER 0x06 /* Playback period pointer. Sample currently in DAC */ #define PLAYBACK_UNKNOWN1 0x07 diff --git a/sound/pci/emu10k1/p16v.h b/sound/pci/emu10k1/p16v.h index 153214940336..00f4817533b1 100644 --- a/sound/pci/emu10k1/p16v.h +++ b/sound/pci/emu10k1/p16v.h @@ -96,7 +96,7 @@ #define PLAYBACK_LIST_SIZE 0x01 /* Size of list in bytes << 16. E.g. 8 periods -> 0x00380000 */ #define PLAYBACK_LIST_PTR 0x02 /* Pointer to the current period being played */ #define PLAYBACK_UNKNOWN3 0x03 /* Not used */ -#define PLAYBACK_DMA_ADDR 0x04 /* Playback DMA addresss */ +#define PLAYBACK_DMA_ADDR 0x04 /* Playback DMA address */ #define PLAYBACK_PERIOD_SIZE 0x05 /* Playback period size. win2000 uses 0x04000000 */ #define PLAYBACK_POINTER 0x06 /* Playback period pointer. Used with PLAYBACK_LIST_PTR to determine buffer position currently in DAC */ #define PLAYBACK_FIFO_END_ADDRESS 0x07 /* Playback FIFO end address */ diff --git a/sound/pci/es1968.c b/sound/pci/es1968.c index 23a58f0d6cb9..7c17f45d876d 100644 --- a/sound/pci/es1968.c +++ b/sound/pci/es1968.c @@ -220,7 +220,7 @@ MODULE_PARM_DESC(joystick, "Enable joystick."); #define RINGB_EN_2CODEC 0x0020 #define RINGB_SING_BIT_DUAL 0x0040 -/* ****Port Adresses**** */ +/* ****Port Addresses**** */ /* Write & Read */ #define ESM_INDEX 0x02 diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c index 0c98ef9156d8..f5eadfc0672a 100644 --- a/sound/pci/rme9652/hdspm.c +++ b/sound/pci/rme9652/hdspm.c @@ -487,7 +487,7 @@ struct hdspm { struct snd_kcontrol *playback_mixer_ctls[HDSPM_MAX_CHANNELS]; /* but input to much, so not used */ struct snd_kcontrol *input_mixer_ctls[HDSPM_MAX_CHANNELS]; - /* full mixer accessable over mixer ioctl or hwdep-device */ + /* full mixer accessible over mixer ioctl or hwdep-device */ struct hdspm_mixer *mixer; }; @@ -550,7 +550,7 @@ static inline int HDSPM_bit2freq(int n) return bit2freq_tab[n]; } -/* Write/read to/from HDSPM with Adresses in Bytes +/* Write/read to/from HDSPM with Addresses in Bytes not words but only 32Bit writes are allowed */ static inline void hdspm_write(struct hdspm * hdspm, unsigned int reg, @@ -2908,7 +2908,7 @@ static int snd_hdspm_create_controls(struct snd_card *card, struct hdspm * hdspm /* Channel playback mixer as default control Note: the whole matrix would be 128*HDSPM_MIXER_CHANNELS Faders, - thats too * big for any alsamixer they are accesible via special + thats too * big for any alsamixer they are accessible via special IOCTL on hwdep and the mixer 2dimensional mixer control */ diff --git a/sound/soc/codecs/max98088.c b/sound/soc/codecs/max98088.c index bc22ee93a75d..43316a70be05 100644 --- a/sound/soc/codecs/max98088.c +++ b/sound/soc/codecs/max98088.c @@ -1953,7 +1953,7 @@ static int max98088_probe(struct snd_soc_codec *codec) return ret; } - /* initalize private data */ + /* initialize private data */ max98088->sysclk = (unsigned)-1; max98088->eq_textcnt = 0; diff --git a/sound/soc/s3c24xx/smdk_spdif.c b/sound/soc/s3c24xx/smdk_spdif.c index f31d22ad7c88..11c88b13dd2e 100644 --- a/sound/soc/s3c24xx/smdk_spdif.c +++ b/sound/soc/s3c24xx/smdk_spdif.c @@ -61,7 +61,7 @@ static int set_audio_clock_heirachy(struct platform_device *pdev) goto out3; } - /* Set audio clock heirachy for S/PDIF */ + /* Set audio clock hierarchy for S/PDIF */ clk_set_parent(mout_epll, fout_epll); clk_set_parent(sclk_audio0, mout_epll); clk_set_parent(sclk_spdif, sclk_audio0); @@ -79,7 +79,7 @@ out1: /* We should haved to set clock directly on this part because of clock * scheme of Samsudng SoCs did not support to set rates from abstrct - * clock of it's heirachy. + * clock of it's hierarchy. */ static int set_audio_clock_rate(unsigned long epll_rate, unsigned long audio_rate) @@ -197,7 +197,7 @@ static int __init smdk_init(void) if (ret) goto err1; - /* Set audio clock heirachy manually */ + /* Set audio clock hierarchy manually */ ret = set_audio_clock_heirachy(smdk_snd_spdif_device); if (ret) goto err1; -- cgit v1.2.3 From 328fc1325f144027f4a8269b11e9f8dcf1edcb97 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 2 Nov 2010 10:00:34 +0000 Subject: Revert "drm/i915: add MMIO debug output" We can use mmiotrace instead of our own debug printks. This reverts commit be282fd48e7492812402a22d73a348c44bf95b63. Conflicts: drivers/gpu/drm/i915/i915_drv.h --- drivers/gpu/drm/i915/i915_drv.h | 30 ++---------------------------- 1 file changed, 2 insertions(+), 28 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index a0063f82fa33..81ee20c2d24e 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -287,9 +287,6 @@ typedef struct drm_i915_private { int front_offset; int current_page; int page_flipping; -#define I915_DEBUG_READ (1<<0) -#define I915_DEBUG_WRITE (1<<1) - unsigned long debug_flags; wait_queue_head_t irq_queue; atomic_t irq_received; @@ -1172,26 +1169,8 @@ extern void intel_overlay_print_error_state(struct seq_file *m, struct intel_ove LOCK_TEST_WITH_RETURN(dev, file_priv); \ } while (0) -static inline u32 i915_read(struct drm_i915_private *dev_priv, u32 reg) -{ - u32 val; - - val = readl(dev_priv->regs + reg); - if (dev_priv->debug_flags & I915_DEBUG_READ) - printk(KERN_ERR "read 0x%08x from 0x%08x\n", val, reg); - return val; -} - -static inline void i915_write(struct drm_i915_private *dev_priv, u32 reg, - u32 val) -{ - writel(val, dev_priv->regs + reg); - if (dev_priv->debug_flags & I915_DEBUG_WRITE) - printk(KERN_ERR "wrote 0x%08x to 0x%08x\n", val, reg); -} - -#define I915_READ(reg) i915_read(dev_priv, (reg)) -#define I915_WRITE(reg, val) i915_write(dev_priv, (reg), (val)) +#define I915_READ(reg) readl(dev_priv->regs + (reg)) +#define I915_WRITE(reg, val) writel(val, dev_priv->regs + (reg)) #define I915_READ16(reg) readw(dev_priv->regs + (reg)) #define I915_WRITE16(reg, val) writel(val, dev_priv->regs + (reg)) #define I915_READ8(reg) readb(dev_priv->regs + (reg)) @@ -1201,11 +1180,6 @@ static inline void i915_write(struct drm_i915_private *dev_priv, u32 reg, #define POSTING_READ(reg) (void)I915_READ(reg) #define POSTING_READ16(reg) (void)I915_READ16(reg) -#define I915_DEBUG_ENABLE_IO() (dev_priv->debug_flags |= I915_DEBUG_READ | \ - I915_DEBUG_WRITE) -#define I915_DEBUG_DISABLE_IO() (dev_priv->debug_flags &= ~(I915_DEBUG_READ | \ - I915_DEBUG_WRITE)) - #define BEGIN_LP_RING(n) \ intel_ring_begin(&dev_priv->render_ring, (n)) -- cgit v1.2.3 From d110852513148a7ec44fad4e036455aeb816d713 Mon Sep 17 00:00:00 2001 From: Zhenyu Wang Date: Tue, 2 Nov 2010 17:30:46 +0800 Subject: agp/intel: fix cache control for sandybridge This is broken from 97ef1bdd0bc75bce7b2058e9c432b6c277dcf4d3. Let's set the correct bit for LLC+MLC and LLC only. Signed-off-by: Zhenyu Wang Signed-off-by: Chris Wilson --- drivers/char/agp/intel-gtt.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/char/agp/intel-gtt.c b/drivers/char/agp/intel-gtt.c index f800e9cfc368..c51efe6f2c7f 100644 --- a/drivers/char/agp/intel-gtt.c +++ b/drivers/char/agp/intel-gtt.c @@ -1291,11 +1291,11 @@ static void gen6_write_entry(dma_addr_t addr, unsigned int entry, if (type_mask == AGP_USER_UNCACHED_MEMORY) pte_flags = GEN6_PTE_UNCACHED | I810_PTE_VALID; else if (type_mask == AGP_USER_CACHED_MEMORY_LLC_MLC) { - pte_flags = GEN6_PTE_LLC | I810_PTE_VALID; + pte_flags = GEN6_PTE_LLC_MLC | I810_PTE_VALID; if (gfdt) pte_flags |= GEN6_PTE_GFDT; } else { /* set 'normal'/'cached' to LLC by default */ - pte_flags = GEN6_PTE_LLC_MLC | I810_PTE_VALID; + pte_flags = GEN6_PTE_LLC | I810_PTE_VALID; if (gfdt) pte_flags |= GEN6_PTE_GFDT; } -- cgit v1.2.3 From 897ef192514a6b0fc10a0ce3fe7e7aa0de09bc52 Mon Sep 17 00:00:00 2001 From: Zhenyu Wang Date: Tue, 2 Nov 2010 17:30:47 +0800 Subject: agp/intel: restore cache behavior on sandybridge This restores cache behavior for default AGP_USER_MEMORY as uncached, and leave default AGP_USER_CACHED_MEMORY as LLC only. I've seen different cache behavior on one sandybridge desktop CPU vs. another mobile CPU. Until we figure out how to detect the real cache config, restore back to the original behavior now. Signed-off-by: Zhenyu Wang Signed-off-by: Chris Wilson --- drivers/char/agp/intel-gtt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/char/agp/intel-gtt.c b/drivers/char/agp/intel-gtt.c index c51efe6f2c7f..fc1637c32cb1 100644 --- a/drivers/char/agp/intel-gtt.c +++ b/drivers/char/agp/intel-gtt.c @@ -1288,7 +1288,7 @@ static void gen6_write_entry(dma_addr_t addr, unsigned int entry, unsigned int gfdt = flags & AGP_USER_CACHED_MEMORY_GFDT; u32 pte_flags; - if (type_mask == AGP_USER_UNCACHED_MEMORY) + if (type_mask == AGP_USER_MEMORY) pte_flags = GEN6_PTE_UNCACHED | I810_PTE_VALID; else if (type_mask == AGP_USER_CACHED_MEMORY_LLC_MLC) { pte_flags = GEN6_PTE_LLC_MLC | I810_PTE_VALID; -- cgit v1.2.3 From 8d19215be8254f4f75e9c5a0d28345947b0382db Mon Sep 17 00:00:00 2001 From: Zou Nan hai Date: Tue, 2 Nov 2010 16:31:01 +0800 Subject: drm/i915: SNB BLT workaround On some stepping of SNB cpu, the first command to be parsed in BLT command streamer should be MI_BATCHBUFFER_START otherwise the GPU may hang. Signed-off-by: Zou Nan hai [ickle: rebased for -next] Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/intel_ringbuffer.c | 123 +++++++++++++++++++++++++++++++- drivers/gpu/drm/i915/intel_ringbuffer.h | 3 + 2 files changed, 123 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 390aa21edbe4..a0702b6fb631 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -658,6 +658,9 @@ void intel_cleanup_ring_buffer(struct intel_ring_buffer *ring) drm_gem_object_unreference(ring->gem_object); ring->gem_object = NULL; + if (ring->cleanup) + ring->cleanup(ring); + cleanup_status_page(ring); } @@ -877,19 +880,133 @@ blt_ring_put_user_irq(struct intel_ring_buffer *ring) /* do nothing */ } + +/* Workaround for some stepping of SNB, + * each time when BLT engine ring tail moved, + * the first command in the ring to be parsed + * should be MI_BATCH_BUFFER_START + */ +#define NEED_BLT_WORKAROUND(dev) \ + (IS_GEN6(dev) && (dev->pdev->revision < 8)) + +static inline struct drm_i915_gem_object * +to_blt_workaround(struct intel_ring_buffer *ring) +{ + return ring->private; +} + +static int blt_ring_init(struct intel_ring_buffer *ring) +{ + if (NEED_BLT_WORKAROUND(ring->dev)) { + struct drm_i915_gem_object *obj; + u32 __iomem *ptr; + int ret; + + obj = to_intel_bo(i915_gem_alloc_object(ring->dev, 4096)); + if (obj == NULL) + return -ENOMEM; + + ret = i915_gem_object_pin(&obj->base, 4096, true, false); + if (ret) { + drm_gem_object_unreference(&obj->base); + return ret; + } + + ptr = kmap(obj->pages[0]); + iowrite32(MI_BATCH_BUFFER_END, ptr); + iowrite32(MI_NOOP, ptr+1); + kunmap(obj->pages[0]); + + ret = i915_gem_object_set_to_gtt_domain(&obj->base, false); + if (ret) { + i915_gem_object_unpin(&obj->base); + drm_gem_object_unreference(&obj->base); + return ret; + } + + ring->private = obj; + } + + return init_ring_common(ring); +} + +static int blt_ring_begin(struct intel_ring_buffer *ring, + int num_dwords) +{ + if (ring->private) { + int ret = intel_ring_begin(ring, num_dwords+2); + if (ret) + return ret; + + intel_ring_emit(ring, MI_BATCH_BUFFER_START); + intel_ring_emit(ring, to_blt_workaround(ring)->gtt_offset); + + return 0; + } else + return intel_ring_begin(ring, 4); +} + +static void blt_ring_flush(struct intel_ring_buffer *ring, + u32 invalidate_domains, + u32 flush_domains) +{ + if (blt_ring_begin(ring, 4) == 0) { + intel_ring_emit(ring, MI_FLUSH_DW); + intel_ring_emit(ring, 0); + intel_ring_emit(ring, 0); + intel_ring_emit(ring, 0); + intel_ring_advance(ring); + } +} + +static int +blt_ring_add_request(struct intel_ring_buffer *ring, + u32 *result) +{ + u32 seqno; + int ret; + + ret = blt_ring_begin(ring, 4); + if (ret) + return ret; + + seqno = i915_gem_get_seqno(ring->dev); + + intel_ring_emit(ring, MI_STORE_DWORD_INDEX); + intel_ring_emit(ring, I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT); + intel_ring_emit(ring, seqno); + intel_ring_emit(ring, MI_USER_INTERRUPT); + intel_ring_advance(ring); + + DRM_DEBUG_DRIVER("%s %d\n", ring->name, seqno); + *result = seqno; + return 0; +} + +static void blt_ring_cleanup(struct intel_ring_buffer *ring) +{ + if (!ring->private) + return; + + i915_gem_object_unpin(ring->private); + drm_gem_object_unreference(ring->private); + ring->private = NULL; +} + static const struct intel_ring_buffer gen6_blt_ring = { .name = "blt ring", .id = RING_BLT, .mmio_base = BLT_RING_BASE, .size = 32 * PAGE_SIZE, - .init = init_ring_common, + .init = blt_ring_init, .write_tail = ring_write_tail, - .flush = gen6_ring_flush, - .add_request = ring_add_request, + .flush = blt_ring_flush, + .add_request = blt_ring_add_request, .get_seqno = ring_status_page_get_seqno, .user_irq_get = blt_ring_get_user_irq, .user_irq_put = blt_ring_put_user_irq, .dispatch_execbuffer = gen6_ring_dispatch_execbuffer, + .cleanup = blt_ring_cleanup, }; int intel_init_render_ring_buffer(struct drm_device *dev) diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index acd23374fe89..68043f1a186e 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -55,6 +55,7 @@ struct intel_ring_buffer { struct drm_i915_gem_execbuffer2 *exec, struct drm_clip_rect *cliprects, uint64_t exec_offset); + void (*cleanup)(struct intel_ring_buffer *ring); /** * List of objects currently involved in rendering from the @@ -90,6 +91,8 @@ struct intel_ring_buffer { wait_queue_head_t irq_queue; drm_local_map_t map; + + void *private; }; static inline u32 -- cgit v1.2.3 From 27153f72d04bcd83b3a66e219418a21d6269553b Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 2 Nov 2010 11:17:23 +0000 Subject: drm/i915: Drop the iomem accessors when writing to the kmapped blt batch I presumed that we would be writing to the batch through the GTT having bound it, so I converted it to use iomem. Even later as I spotted that we didn't even move the batch to the GTT (now an issue since we default to uncached memory on SNB) I still didn't realise that using iomem for kmapped memory was incorrect. Fix it. Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/intel_ringbuffer.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index a0702b6fb631..85071570e1f9 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -899,7 +899,7 @@ static int blt_ring_init(struct intel_ring_buffer *ring) { if (NEED_BLT_WORKAROUND(ring->dev)) { struct drm_i915_gem_object *obj; - u32 __iomem *ptr; + u32 *ptr; int ret; obj = to_intel_bo(i915_gem_alloc_object(ring->dev, 4096)); @@ -913,8 +913,8 @@ static int blt_ring_init(struct intel_ring_buffer *ring) } ptr = kmap(obj->pages[0]); - iowrite32(MI_BATCH_BUFFER_END, ptr); - iowrite32(MI_NOOP, ptr+1); + *ptr++ = MI_BATCH_BUFFER_END; + *ptr++ = MI_NOOP; kunmap(obj->pages[0]); ret = i915_gem_object_set_to_gtt_domain(&obj->base, false); -- cgit v1.2.3 From 1ed7c2077aa236b378dd28319e664422ef010e9b Mon Sep 17 00:00:00 2001 From: Michael Witten Date: Fri, 26 Mar 2010 21:41:10 +0000 Subject: Docs: typo: Complete -> Completely Signed-off-by: Michael Witten Signed-off-by: Jiri Kosina --- Documentation/scheduler/00-INDEX | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/scheduler/00-INDEX b/Documentation/scheduler/00-INDEX index 3c00c9c3219e..d2651c47ae27 100644 --- a/Documentation/scheduler/00-INDEX +++ b/Documentation/scheduler/00-INDEX @@ -3,7 +3,7 @@ sched-arch.txt - CPU Scheduler implementation hints for architecture specific code. sched-design-CFS.txt - - goals, design and implementation of the Complete Fair Scheduler. + - goals, design and implementation of the Completely Fair Scheduler. sched-domains.txt - information on scheduling domains. sched-nice-design.txt -- cgit v1.2.3 From de7fd0fc989727d657d40f6ddf2fb99639bd6262 Mon Sep 17 00:00:00 2001 From: Michael Witten Date: Wed, 27 Oct 2010 23:11:10 +0000 Subject: Kconfig: typo: boad -> board Signed-off-by: Michael Witten Signed-off-by: Jiri Kosina --- drivers/input/serio/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/input/serio/Kconfig b/drivers/input/serio/Kconfig index 6256233d2bfb..44a351cdc641 100644 --- a/drivers/input/serio/Kconfig +++ b/drivers/input/serio/Kconfig @@ -230,7 +230,7 @@ config SERIO_PS2MULT tristate "TQC PS/2 multiplexer" help Say Y here if you have the PS/2 line multiplexer like the one - present on TQC boads. + present on TQC boards. To compile this driver as a module, choose M here: the module will be called ps2mult. -- cgit v1.2.3 From 45c1de8e20cec40b6846def0aeca09cb1bfb839b Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Tue, 2 Nov 2010 17:08:37 +0100 Subject: ALSA: oxygen: merge HiFier driver into snd-oxygen The snd-hifier driver contains more duplicated code than model-specific code, so it does not make sense for it to be a separate driver. Handling the two-channel output restriction can be easily done in the generic driver. Signed-off-by: Clemens Ladisch Signed-off-by: Takashi Iwai --- Documentation/sound/alsa/ALSA-Configuration.txt | 10 +- sound/pci/Kconfig | 15 +- sound/pci/oxygen/Makefile | 2 - sound/pci/oxygen/hifier.c | 239 ------------------------ sound/pci/oxygen/oxygen.c | 43 ++++- 5 files changed, 42 insertions(+), 267 deletions(-) delete mode 100644 sound/pci/oxygen/hifier.c diff --git a/Documentation/sound/alsa/ALSA-Configuration.txt b/Documentation/sound/alsa/ALSA-Configuration.txt index d0eb696d32e8..f1a1787e71e5 100644 --- a/Documentation/sound/alsa/ALSA-Configuration.txt +++ b/Documentation/sound/alsa/ALSA-Configuration.txt @@ -974,13 +974,6 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. See hdspm.txt for details. - Module snd-hifier - ----------------- - - Module for the MediaTek/TempoTec HiFier Fantasia sound card. - - This module supports autoprobe and multiple cards. - Module snd-ice1712 ------------------ @@ -1531,7 +1524,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. Module snd-oxygen ----------------- - Module for sound cards based on the C-Media CMI8788 chip: + Module for sound cards based on the C-Media CMI8787/8788 chip: * Asound A-8788 * AuzenTech X-Meridian * Bgears b-Enspirer @@ -1540,6 +1533,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. * HT-Omega Claro halo (XT) * Razer Barracuda AC-1 * Sondigo Inferno + * TempoTec HiFier Fantasia This module supports autoprobe and multiple cards. diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig index 12e34653b8a8..dfe406de9935 100644 --- a/sound/pci/Kconfig +++ b/sound/pci/Kconfig @@ -209,7 +209,7 @@ config SND_OXYGEN_LIB tristate config SND_OXYGEN - tristate "C-Media 8788 (Oxygen)" + tristate "C-Media 8787, 8788 (Oxygen)" select SND_OXYGEN_LIB select SND_PCM select SND_MPU401_UART @@ -224,6 +224,7 @@ config SND_OXYGEN * HT-Omega Claro halo (XT) * Razer Barracuda AC-1 * Sondigo Inferno + * TempoTec/MediaTek HiFier Fantasia To compile this driver as a module, choose M here: the module will be called snd-oxygen. @@ -578,18 +579,6 @@ config SND_HDSPM To compile this driver as a module, choose M here: the module will be called snd-hdspm. -config SND_HIFIER - tristate "TempoTec HiFier Fantasia" - select SND_OXYGEN_LIB - select SND_PCM - select SND_MPU401_UART - help - Say Y here to include support for the MediaTek/TempoTec HiFier - Fantasia sound card. - - To compile this driver as a module, choose M here: the module - will be called snd-hifier. - config SND_ICE1712 tristate "ICEnsemble ICE1712 (Envy24)" select SND_MPU401_UART diff --git a/sound/pci/oxygen/Makefile b/sound/pci/oxygen/Makefile index acd8f15f7bff..bd67c0d7779c 100644 --- a/sound/pci/oxygen/Makefile +++ b/sound/pci/oxygen/Makefile @@ -1,10 +1,8 @@ snd-oxygen-lib-objs := oxygen_io.o oxygen_lib.o oxygen_mixer.o oxygen_pcm.o -snd-hifier-objs := hifier.o snd-oxygen-objs := oxygen.o snd-virtuoso-objs := virtuoso.o xonar_lib.o \ xonar_pcm179x.o xonar_cs43xx.o xonar_wm87x6.o xonar_hdmi.o obj-$(CONFIG_SND_OXYGEN_LIB) += snd-oxygen-lib.o -obj-$(CONFIG_SND_HIFIER) += snd-hifier.o obj-$(CONFIG_SND_OXYGEN) += snd-oxygen.o obj-$(CONFIG_SND_VIRTUOSO) += snd-virtuoso.o diff --git a/sound/pci/oxygen/hifier.c b/sound/pci/oxygen/hifier.c deleted file mode 100644 index 5a87d683691f..000000000000 --- a/sound/pci/oxygen/hifier.c +++ /dev/null @@ -1,239 +0,0 @@ -/* - * C-Media CMI8788 driver for the MediaTek/TempoTec HiFier Fantasia - * - * Copyright (c) Clemens Ladisch - * - * - * This driver is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License, version 2. - * - * This driver 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. - * - * You should have received a copy of the GNU General Public License - * along with this driver; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - */ - -/* - * CMI8788: - * - * SPI 0 -> AK4396 - */ - -#include -#include -#include -#include -#include -#include -#include -#include "oxygen.h" -#include "ak4396.h" - -MODULE_AUTHOR("Clemens Ladisch "); -MODULE_DESCRIPTION("TempoTec HiFier driver"); -MODULE_LICENSE("GPL v2"); - -static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; -static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; -static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; - -module_param_array(index, int, NULL, 0444); -MODULE_PARM_DESC(index, "card index"); -module_param_array(id, charp, NULL, 0444); -MODULE_PARM_DESC(id, "ID string"); -module_param_array(enable, bool, NULL, 0444); -MODULE_PARM_DESC(enable, "enable card"); - -static DEFINE_PCI_DEVICE_TABLE(hifier_ids) = { - { OXYGEN_PCI_SUBID(0x14c3, 0x1710) }, - { OXYGEN_PCI_SUBID(0x14c3, 0x1711) }, - { OXYGEN_PCI_SUBID_BROKEN_EEPROM }, - { } -}; -MODULE_DEVICE_TABLE(pci, hifier_ids); - -struct hifier_data { - u8 ak4396_regs[5]; -}; - -static void ak4396_write(struct oxygen *chip, u8 reg, u8 value) -{ - struct hifier_data *data = chip->model_data; - - oxygen_write_spi(chip, OXYGEN_SPI_TRIGGER | - OXYGEN_SPI_DATA_LENGTH_2 | - OXYGEN_SPI_CLOCK_160 | - (0 << OXYGEN_SPI_CODEC_SHIFT) | - OXYGEN_SPI_CEN_LATCH_CLOCK_HI, - AK4396_WRITE | (reg << 8) | value); - data->ak4396_regs[reg] = value; -} - -static void ak4396_write_cached(struct oxygen *chip, u8 reg, u8 value) -{ - struct hifier_data *data = chip->model_data; - - if (value != data->ak4396_regs[reg]) - ak4396_write(chip, reg, value); -} - -static void hifier_registers_init(struct oxygen *chip) -{ - struct hifier_data *data = chip->model_data; - - ak4396_write(chip, AK4396_CONTROL_1, AK4396_DIF_24_MSB | AK4396_RSTN); - ak4396_write(chip, AK4396_CONTROL_2, - data->ak4396_regs[AK4396_CONTROL_2]); - ak4396_write(chip, AK4396_CONTROL_3, AK4396_PCM); - ak4396_write(chip, AK4396_LCH_ATT, chip->dac_volume[0]); - ak4396_write(chip, AK4396_RCH_ATT, chip->dac_volume[1]); -} - -static void hifier_init(struct oxygen *chip) -{ - struct hifier_data *data = chip->model_data; - - data->ak4396_regs[AK4396_CONTROL_2] = - AK4396_SMUTE | AK4396_DEM_OFF | AK4396_DFS_NORMAL; - hifier_registers_init(chip); - - snd_component_add(chip->card, "AK4396"); - snd_component_add(chip->card, "CS5340"); -} - -static void hifier_cleanup(struct oxygen *chip) -{ -} - -static void hifier_resume(struct oxygen *chip) -{ - hifier_registers_init(chip); -} - -static void set_ak4396_params(struct oxygen *chip, - struct snd_pcm_hw_params *params) -{ - struct hifier_data *data = chip->model_data; - u8 value; - - value = data->ak4396_regs[AK4396_CONTROL_2] & ~AK4396_DFS_MASK; - if (params_rate(params) <= 54000) - value |= AK4396_DFS_NORMAL; - else if (params_rate(params) <= 108000) - value |= AK4396_DFS_DOUBLE; - else - value |= AK4396_DFS_QUAD; - - msleep(1); /* wait for the new MCLK to become stable */ - - if (value != data->ak4396_regs[AK4396_CONTROL_2]) { - ak4396_write(chip, AK4396_CONTROL_1, - AK4396_DIF_24_MSB); - ak4396_write(chip, AK4396_CONTROL_2, value); - ak4396_write(chip, AK4396_CONTROL_1, - AK4396_DIF_24_MSB | AK4396_RSTN); - } -} - -static void update_ak4396_volume(struct oxygen *chip) -{ - ak4396_write_cached(chip, AK4396_LCH_ATT, chip->dac_volume[0]); - ak4396_write_cached(chip, AK4396_RCH_ATT, chip->dac_volume[1]); -} - -static void update_ak4396_mute(struct oxygen *chip) -{ - struct hifier_data *data = chip->model_data; - u8 value; - - value = data->ak4396_regs[AK4396_CONTROL_2] & ~AK4396_SMUTE; - if (chip->dac_mute) - value |= AK4396_SMUTE; - ak4396_write_cached(chip, AK4396_CONTROL_2, value); -} - -static void set_cs5340_params(struct oxygen *chip, - struct snd_pcm_hw_params *params) -{ -} - -static const DECLARE_TLV_DB_LINEAR(ak4396_db_scale, TLV_DB_GAIN_MUTE, 0); - -static const struct oxygen_model model_hifier = { - .shortname = "C-Media CMI8787", - .longname = "C-Media Oxygen HD Audio", - .chip = "CMI8788", - .init = hifier_init, - .cleanup = hifier_cleanup, - .resume = hifier_resume, - .get_i2s_mclk = oxygen_default_i2s_mclk, - .set_dac_params = set_ak4396_params, - .set_adc_params = set_cs5340_params, - .update_dac_volume = update_ak4396_volume, - .update_dac_mute = update_ak4396_mute, - .dac_tlv = ak4396_db_scale, - .model_data_size = sizeof(struct hifier_data), - .device_config = PLAYBACK_0_TO_I2S | - PLAYBACK_1_TO_SPDIF | - CAPTURE_0_FROM_I2S_1, - .dac_channels = 2, - .dac_volume_min = 0, - .dac_volume_max = 255, - .function_flags = OXYGEN_FUNCTION_SPI, - .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST, - .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST, -}; - -static int __devinit get_hifier_model(struct oxygen *chip, - const struct pci_device_id *id) -{ - chip->model = model_hifier; - return 0; -} - -static int __devinit hifier_probe(struct pci_dev *pci, - const struct pci_device_id *pci_id) -{ - static int dev; - int err; - - if (dev >= SNDRV_CARDS) - return -ENODEV; - if (!enable[dev]) { - ++dev; - return -ENOENT; - } - err = oxygen_pci_probe(pci, index[dev], id[dev], THIS_MODULE, - hifier_ids, get_hifier_model); - if (err >= 0) - ++dev; - return err; -} - -static struct pci_driver hifier_driver = { - .name = "CMI8787HiFier", - .id_table = hifier_ids, - .probe = hifier_probe, - .remove = __devexit_p(oxygen_pci_remove), -#ifdef CONFIG_PM - .suspend = oxygen_pci_suspend, - .resume = oxygen_pci_resume, -#endif -}; - -static int __init alsa_card_hifier_init(void) -{ - return pci_register_driver(&hifier_driver); -} - -static void __exit alsa_card_hifier_exit(void) -{ - pci_unregister_driver(&hifier_driver); -} - -module_init(alsa_card_hifier_init) -module_exit(alsa_card_hifier_exit) diff --git a/sound/pci/oxygen/oxygen.c b/sound/pci/oxygen/oxygen.c index 98a8eb3c92f7..5e258b26f044 100644 --- a/sound/pci/oxygen/oxygen.c +++ b/sound/pci/oxygen/oxygen.c @@ -70,6 +70,7 @@ enum { MODEL_MERIDIAN, /* AuzenTech X-Meridian */ MODEL_CLARO, /* HT-Omega Claro */ MODEL_CLARO_HALO, /* HT-Omega Claro halo */ + MODEL_HIFIER, /* TempoTec HiFier Fantasia */ }; static DEFINE_PCI_DEVICE_TABLE(oxygen_ids) = { @@ -81,6 +82,8 @@ static DEFINE_PCI_DEVICE_TABLE(oxygen_ids) = { { OXYGEN_PCI_SUBID(0x13f6, 0x8788), .driver_data = MODEL_CMEDIA_REF }, { OXYGEN_PCI_SUBID(0x13f6, 0xffff), .driver_data = MODEL_CMEDIA_REF }, { OXYGEN_PCI_SUBID(0x147a, 0xa017), .driver_data = MODEL_CMEDIA_REF }, + { OXYGEN_PCI_SUBID(0x14c3, 0x1710), .driver_data = MODEL_HIFIER }, + { OXYGEN_PCI_SUBID(0x14c3, 0x1711), .driver_data = MODEL_HIFIER }, { OXYGEN_PCI_SUBID(0x1a58, 0x0910), .driver_data = MODEL_CMEDIA_REF }, { OXYGEN_PCI_SUBID(0x415a, 0x5431), .driver_data = MODEL_MERIDIAN }, { OXYGEN_PCI_SUBID(0x7284, 0x9761), .driver_data = MODEL_CLARO }, @@ -98,6 +101,7 @@ MODULE_DEVICE_TABLE(pci, oxygen_ids); #define GPIO_CLARO_HP 0x0100 struct generic_data { + unsigned int dacs; u8 ak4396_regs[4][5]; u16 wm8785_regs[3]; }; @@ -148,7 +152,7 @@ static void ak4396_registers_init(struct oxygen *chip) struct generic_data *data = chip->model_data; unsigned int i; - for (i = 0; i < 4; ++i) { + for (i = 0; i < data->dacs; ++i) { ak4396_write(chip, i, AK4396_CONTROL_1, AK4396_DIF_24_MSB | AK4396_RSTN); ak4396_write(chip, i, AK4396_CONTROL_2, @@ -166,6 +170,7 @@ static void ak4396_init(struct oxygen *chip) { struct generic_data *data = chip->model_data; + data->dacs = chip->model.dac_channels / 2; data->ak4396_regs[0][AK4396_CONTROL_2] = AK4396_SMUTE | AK4396_DEM_OFF | AK4396_DFS_NORMAL; ak4396_registers_init(chip); @@ -232,6 +237,12 @@ static void claro_halo_init(struct oxygen *chip) claro_enable_hp(chip); } +static void hifier_init(struct oxygen *chip) +{ + ak4396_init(chip); + snd_component_add(chip->card, "CS5340"); +} + static void generic_cleanup(struct oxygen *chip) { } @@ -268,6 +279,11 @@ static void claro_resume(struct oxygen *chip) claro_enable_hp(chip); } +static void stereo_resume(struct oxygen *chip) +{ + ak4396_registers_init(chip); +} + static void set_ak4396_params(struct oxygen *chip, struct snd_pcm_hw_params *params) { @@ -286,7 +302,7 @@ static void set_ak4396_params(struct oxygen *chip, msleep(1); /* wait for the new MCLK to become stable */ if (value != data->ak4396_regs[0][AK4396_CONTROL_2]) { - for (i = 0; i < 4; ++i) { + for (i = 0; i < data->dacs; ++i) { ak4396_write(chip, i, AK4396_CONTROL_1, AK4396_DIF_24_MSB); ak4396_write(chip, i, AK4396_CONTROL_2, value); @@ -298,9 +314,10 @@ static void set_ak4396_params(struct oxygen *chip, static void update_ak4396_volume(struct oxygen *chip) { + struct generic_data *data = chip->model_data; unsigned int i; - for (i = 0; i < 4; ++i) { + for (i = 0; i < data->dacs; ++i) { ak4396_write_cached(chip, i, AK4396_LCH_ATT, chip->dac_volume[i * 2]); ak4396_write_cached(chip, i, AK4396_RCH_ATT, @@ -317,7 +334,7 @@ static void update_ak4396_mute(struct oxygen *chip) value = data->ak4396_regs[0][AK4396_CONTROL_2] & ~AK4396_SMUTE; if (chip->dac_mute) value |= AK4396_SMUTE; - for (i = 0; i < 4; ++i) + for (i = 0; i < data->dacs; ++i) ak4396_write_cached(chip, i, AK4396_CONTROL_2, value); } @@ -356,6 +373,10 @@ static void set_ak5385_params(struct oxygen *chip, value, GPIO_AK5385_DFS_MASK); } +static void set_no_params(struct oxygen *chip, struct snd_pcm_hw_params *params) +{ +} + static int rolloff_info(struct snd_kcontrol *ctl, struct snd_ctl_elem_info *info) { @@ -400,7 +421,7 @@ static int rolloff_put(struct snd_kcontrol *ctl, reg &= ~AK4396_SLOW; changed = reg != data->ak4396_regs[0][AK4396_CONTROL_2]; if (changed) { - for (i = 0; i < 4; ++i) + for (i = 0; i < data->dacs; ++i) ak4396_write(chip, i, AK4396_CONTROL_2, reg); } mutex_unlock(&chip->mutex); @@ -550,6 +571,18 @@ static int __devinit get_oxygen_model(struct oxygen *chip, CAPTURE_0_FROM_I2S_2 | CAPTURE_1_FROM_SPDIF; break; + case MODEL_HIFIER: + chip->model.shortname = "C-Media CMI8787"; + chip->model.chip = "CMI8787"; + chip->model.init = hifier_init; + chip->model.resume = stereo_resume; + chip->model.mixer_init = generic_mixer_init; + chip->model.set_adc_params = set_no_params; + chip->model.device_config = PLAYBACK_0_TO_I2S | + PLAYBACK_1_TO_SPDIF | + CAPTURE_0_FROM_I2S_1; + chip->model.dac_channels = 2; + break; } if (id->driver_data == MODEL_MERIDIAN || id->driver_data == MODEL_CLARO_HALO) { -- cgit v1.2.3 From 31f86bacfc9c8f6a3f25fa991c1f373374a9f25b Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Tue, 2 Nov 2010 17:18:23 +0100 Subject: ALSA: oxygen: add Kuroutoshikou CMI8787-HG2PCI support Add support for the Kuroutoshikou CMI8787-HG2PCI sound card. [replaced non-latin letters in the patch by tiwai] Signed-off-by: Clemens Ladisch Signed-off-by: Takashi Iwai --- Documentation/sound/alsa/ALSA-Configuration.txt | 1 + sound/pci/Kconfig | 1 + sound/pci/oxygen/oxygen.c | 19 +++++++++++++++---- sound/pci/oxygen/oxygen_lib.c | 2 +- 4 files changed, 18 insertions(+), 5 deletions(-) diff --git a/Documentation/sound/alsa/ALSA-Configuration.txt b/Documentation/sound/alsa/ALSA-Configuration.txt index f1a1787e71e5..fdd388ded62a 100644 --- a/Documentation/sound/alsa/ALSA-Configuration.txt +++ b/Documentation/sound/alsa/ALSA-Configuration.txt @@ -1531,6 +1531,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. * Club3D Theatron DTS * HT-Omega Claro (plus) * HT-Omega Claro halo (XT) + * Kuroutoshikou CMI8787-HG2PCI * Razer Barracuda AC-1 * Sondigo Inferno * TempoTec HiFier Fantasia diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig index dfe406de9935..f7139d09cbbe 100644 --- a/sound/pci/Kconfig +++ b/sound/pci/Kconfig @@ -222,6 +222,7 @@ config SND_OXYGEN * Club3D Theatron DTS * HT-Omega Claro (plus) * HT-Omega Claro halo (XT) + * Kuroutoshikou CMI8787-HG2PCI * Razer Barracuda AC-1 * Sondigo Inferno * TempoTec/MediaTek HiFier Fantasia diff --git a/sound/pci/oxygen/oxygen.c b/sound/pci/oxygen/oxygen.c index 5e258b26f044..dd0f3f478999 100644 --- a/sound/pci/oxygen/oxygen.c +++ b/sound/pci/oxygen/oxygen.c @@ -71,6 +71,7 @@ enum { MODEL_CLARO, /* HT-Omega Claro */ MODEL_CLARO_HALO, /* HT-Omega Claro halo */ MODEL_HIFIER, /* TempoTec HiFier Fantasia */ + MODEL_HG2PCI, /* Kuroutoshikou CMI8787-HG2PCI */ }; static DEFINE_PCI_DEVICE_TABLE(oxygen_ids) = { @@ -80,7 +81,7 @@ static DEFINE_PCI_DEVICE_TABLE(oxygen_ids) = { { OXYGEN_PCI_SUBID(0x13f6, 0x0001), .driver_data = MODEL_CMEDIA_REF }, { OXYGEN_PCI_SUBID(0x13f6, 0x0010), .driver_data = MODEL_CMEDIA_REF }, { OXYGEN_PCI_SUBID(0x13f6, 0x8788), .driver_data = MODEL_CMEDIA_REF }, - { OXYGEN_PCI_SUBID(0x13f6, 0xffff), .driver_data = MODEL_CMEDIA_REF }, + { OXYGEN_PCI_SUBID(0x13f6, 0xffff), .driver_data = MODEL_HG2PCI }, { OXYGEN_PCI_SUBID(0x147a, 0xa017), .driver_data = MODEL_CMEDIA_REF }, { OXYGEN_PCI_SUBID(0x14c3, 0x1710), .driver_data = MODEL_HIFIER }, { OXYGEN_PCI_SUBID(0x14c3, 0x1711), .driver_data = MODEL_HIFIER }, @@ -243,6 +244,11 @@ static void hifier_init(struct oxygen *chip) snd_component_add(chip->card, "CS5340"); } +static void hg2pci_init(struct oxygen *chip) +{ + ak4396_init(chip); +} + static void generic_cleanup(struct oxygen *chip) { } @@ -572,15 +578,20 @@ static int __devinit get_oxygen_model(struct oxygen *chip, CAPTURE_1_FROM_SPDIF; break; case MODEL_HIFIER: + case MODEL_HG2PCI: chip->model.shortname = "C-Media CMI8787"; chip->model.chip = "CMI8787"; - chip->model.init = hifier_init; + if (id->driver_data == MODEL_HIFIER) + chip->model.init = hifier_init; + else + chip->model.init = hg2pci_init; chip->model.resume = stereo_resume; chip->model.mixer_init = generic_mixer_init; chip->model.set_adc_params = set_no_params; chip->model.device_config = PLAYBACK_0_TO_I2S | - PLAYBACK_1_TO_SPDIF | - CAPTURE_0_FROM_I2S_1; + PLAYBACK_1_TO_SPDIF; + if (id->driver_data == MODEL_HIFIER) + chip->model.device_config |= CAPTURE_0_FROM_I2S_1; chip->model.dac_channels = 2; break; } diff --git a/sound/pci/oxygen/oxygen_lib.c b/sound/pci/oxygen/oxygen_lib.c index e5ebe56fb0c5..2e6579962217 100644 --- a/sound/pci/oxygen/oxygen_lib.c +++ b/sound/pci/oxygen/oxygen_lib.c @@ -262,7 +262,7 @@ oxygen_search_pci_id(struct oxygen *chip, const struct pci_device_id ids[]) */ subdevice = oxygen_read_eeprom(chip, 2); /* use default ID if EEPROM is missing */ - if (subdevice == 0xffff) + if (subdevice == 0xffff && oxygen_read_eeprom(chip, 1) == 0xffff) subdevice = 0x8788; /* * We use only the subsystem device ID for searching because it is -- cgit v1.2.3 From 085ce2643713830cf772c12c1a16da9d0ba83f36 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 3 Nov 2010 09:27:53 +0000 Subject: drm/i915: Ensure that if we ever try to pin+fence it is mappable. When merging Daniel's full-gtt patches I had a set of tweaks which I thought I had undone. I was half right... Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=31286 Reported-by: jinjin.wang@intel.com Reported-by: Alexey Fisher Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_gem.c | 1 + drivers/gpu/drm/i915/intel_display.c | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 5bd86033a88e..12dae003c011 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -4151,6 +4151,7 @@ i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment, int ret; BUG_ON(obj_priv->pin_count == DRM_I915_GEM_OBJECT_MAX_PIN_COUNT); + BUG_ON(need_fence && !mappable); WARN_ON(i915_verify_lists(dev)); if (obj_priv->gtt_space != NULL) { diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 33c178c8d6dd..a33d9a2c7429 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -1462,7 +1462,8 @@ intel_pin_and_fence_fb_obj(struct drm_device *dev, } ret = i915_gem_object_pin(obj, alignment, - !pipelined, obj_priv->tiling_mode); + !pipelined || obj_priv->tiling_mode, + obj_priv->tiling_mode); if (ret) return ret; -- cgit v1.2.3 From 18f24839f18f1934c1e37e86ce8f3fecbb0328c9 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Wed, 3 Nov 2010 11:36:33 +0100 Subject: ALSA: oxygen: reorganize PCI IDs Sort the PCI IDs so that they make logical sense. Also move the card name comments into this list because the model symbols should be (more) self-explanationary. Signed-off-by: Clemens Ladisch Signed-off-by: Takashi Iwai --- sound/pci/oxygen/oxygen.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/sound/pci/oxygen/oxygen.c b/sound/pci/oxygen/oxygen.c index dd0f3f478999..13f39e58f3de 100644 --- a/sound/pci/oxygen/oxygen.c +++ b/sound/pci/oxygen/oxygen.c @@ -66,28 +66,34 @@ module_param_array(enable, bool, NULL, 0444); MODULE_PARM_DESC(enable, "enable card"); enum { - MODEL_CMEDIA_REF, /* C-Media's reference design */ - MODEL_MERIDIAN, /* AuzenTech X-Meridian */ - MODEL_CLARO, /* HT-Omega Claro */ - MODEL_CLARO_HALO, /* HT-Omega Claro halo */ - MODEL_HIFIER, /* TempoTec HiFier Fantasia */ - MODEL_HG2PCI, /* Kuroutoshikou CMI8787-HG2PCI */ + MODEL_CMEDIA_REF, + MODEL_MERIDIAN, + MODEL_CLARO, + MODEL_CLARO_HALO, + MODEL_HIFIER, + MODEL_HG2PCI, }; static DEFINE_PCI_DEVICE_TABLE(oxygen_ids) = { + /* C-Media's reference design */ { OXYGEN_PCI_SUBID(0x10b0, 0x0216), .driver_data = MODEL_CMEDIA_REF }, { OXYGEN_PCI_SUBID(0x10b0, 0x0218), .driver_data = MODEL_CMEDIA_REF }, { OXYGEN_PCI_SUBID(0x10b0, 0x0219), .driver_data = MODEL_CMEDIA_REF }, { OXYGEN_PCI_SUBID(0x13f6, 0x0001), .driver_data = MODEL_CMEDIA_REF }, { OXYGEN_PCI_SUBID(0x13f6, 0x0010), .driver_data = MODEL_CMEDIA_REF }, { OXYGEN_PCI_SUBID(0x13f6, 0x8788), .driver_data = MODEL_CMEDIA_REF }, - { OXYGEN_PCI_SUBID(0x13f6, 0xffff), .driver_data = MODEL_HG2PCI }, { OXYGEN_PCI_SUBID(0x147a, 0xa017), .driver_data = MODEL_CMEDIA_REF }, + { OXYGEN_PCI_SUBID(0x1a58, 0x0910), .driver_data = MODEL_CMEDIA_REF }, + /* Kuroutoshikou CMI8787-HG2PCI */ + { OXYGEN_PCI_SUBID(0x13f6, 0xffff), .driver_data = MODEL_HG2PCI }, + /* TempoTec HiFier Fantasia */ { OXYGEN_PCI_SUBID(0x14c3, 0x1710), .driver_data = MODEL_HIFIER }, { OXYGEN_PCI_SUBID(0x14c3, 0x1711), .driver_data = MODEL_HIFIER }, - { OXYGEN_PCI_SUBID(0x1a58, 0x0910), .driver_data = MODEL_CMEDIA_REF }, + /* AuzenTech X-Meridian */ { OXYGEN_PCI_SUBID(0x415a, 0x5431), .driver_data = MODEL_MERIDIAN }, + /* HT-Omega Claro */ { OXYGEN_PCI_SUBID(0x7284, 0x9761), .driver_data = MODEL_CLARO }, + /* HT-Omega Claro halo */ { OXYGEN_PCI_SUBID(0x7284, 0x9781), .driver_data = MODEL_CLARO_HALO }, { } }; -- cgit v1.2.3 From 2146dcfd15ad55cfdd18b45e1e6601d6a86f0cbe Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Wed, 3 Nov 2010 12:26:35 +0100 Subject: ALSA: oxygen: add HiFier Serenade support Add support for the TempoTec/MediaTek HiFier Serenade sound card. The PCI ID was already there, but the driver handled it like the Fantasia model, which resulted in a dummy recording device. As a stereo output-only card, this model is to be handled exactly like the HG2PCI. Signed-off-by: Clemens Ladisch Signed-off-by: Takashi Iwai --- Documentation/sound/alsa/ALSA-Configuration.txt | 1 + sound/pci/Kconfig | 1 + sound/pci/oxygen/oxygen.c | 27 +++++++++++++------------ 3 files changed, 16 insertions(+), 13 deletions(-) diff --git a/Documentation/sound/alsa/ALSA-Configuration.txt b/Documentation/sound/alsa/ALSA-Configuration.txt index fdd388ded62a..7124340038ea 100644 --- a/Documentation/sound/alsa/ALSA-Configuration.txt +++ b/Documentation/sound/alsa/ALSA-Configuration.txt @@ -1535,6 +1535,7 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. * Razer Barracuda AC-1 * Sondigo Inferno * TempoTec HiFier Fantasia + * TempoTec HiFier Serenade This module supports autoprobe and multiple cards. diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig index f7139d09cbbe..5add96bdf172 100644 --- a/sound/pci/Kconfig +++ b/sound/pci/Kconfig @@ -226,6 +226,7 @@ config SND_OXYGEN * Razer Barracuda AC-1 * Sondigo Inferno * TempoTec/MediaTek HiFier Fantasia + * TempoTec/MediaTek HiFier Serenade To compile this driver as a module, choose M here: the module will be called snd-oxygen. diff --git a/sound/pci/oxygen/oxygen.c b/sound/pci/oxygen/oxygen.c index 13f39e58f3de..ea8fffefad9f 100644 --- a/sound/pci/oxygen/oxygen.c +++ b/sound/pci/oxygen/oxygen.c @@ -70,8 +70,8 @@ enum { MODEL_MERIDIAN, MODEL_CLARO, MODEL_CLARO_HALO, - MODEL_HIFIER, - MODEL_HG2PCI, + MODEL_FANTASIA, + MODEL_2CH_OUTPUT, }; static DEFINE_PCI_DEVICE_TABLE(oxygen_ids) = { @@ -85,10 +85,11 @@ static DEFINE_PCI_DEVICE_TABLE(oxygen_ids) = { { OXYGEN_PCI_SUBID(0x147a, 0xa017), .driver_data = MODEL_CMEDIA_REF }, { OXYGEN_PCI_SUBID(0x1a58, 0x0910), .driver_data = MODEL_CMEDIA_REF }, /* Kuroutoshikou CMI8787-HG2PCI */ - { OXYGEN_PCI_SUBID(0x13f6, 0xffff), .driver_data = MODEL_HG2PCI }, + { OXYGEN_PCI_SUBID(0x13f6, 0xffff), .driver_data = MODEL_2CH_OUTPUT }, /* TempoTec HiFier Fantasia */ - { OXYGEN_PCI_SUBID(0x14c3, 0x1710), .driver_data = MODEL_HIFIER }, - { OXYGEN_PCI_SUBID(0x14c3, 0x1711), .driver_data = MODEL_HIFIER }, + { OXYGEN_PCI_SUBID(0x14c3, 0x1710), .driver_data = MODEL_FANTASIA }, + /* TempoTec HiFier Serenade */ + { OXYGEN_PCI_SUBID(0x14c3, 0x1711), .driver_data = MODEL_2CH_OUTPUT }, /* AuzenTech X-Meridian */ { OXYGEN_PCI_SUBID(0x415a, 0x5431), .driver_data = MODEL_MERIDIAN }, /* HT-Omega Claro */ @@ -244,13 +245,13 @@ static void claro_halo_init(struct oxygen *chip) claro_enable_hp(chip); } -static void hifier_init(struct oxygen *chip) +static void fantasia_init(struct oxygen *chip) { ak4396_init(chip); snd_component_add(chip->card, "CS5340"); } -static void hg2pci_init(struct oxygen *chip) +static void stereo_output_init(struct oxygen *chip) { ak4396_init(chip); } @@ -583,20 +584,20 @@ static int __devinit get_oxygen_model(struct oxygen *chip, CAPTURE_0_FROM_I2S_2 | CAPTURE_1_FROM_SPDIF; break; - case MODEL_HIFIER: - case MODEL_HG2PCI: + case MODEL_FANTASIA: + case MODEL_2CH_OUTPUT: chip->model.shortname = "C-Media CMI8787"; chip->model.chip = "CMI8787"; - if (id->driver_data == MODEL_HIFIER) - chip->model.init = hifier_init; + if (id->driver_data == MODEL_FANTASIA) + chip->model.init = fantasia_init; else - chip->model.init = hg2pci_init; + chip->model.init = stereo_output_init; chip->model.resume = stereo_resume; chip->model.mixer_init = generic_mixer_init; chip->model.set_adc_params = set_no_params; chip->model.device_config = PLAYBACK_0_TO_I2S | PLAYBACK_1_TO_SPDIF; - if (id->driver_data == MODEL_HIFIER) + if (id->driver_data == MODEL_FANTASIA) chip->model.device_config |= CAPTURE_0_FROM_I2S_1; chip->model.dac_channels = 2; break; -- cgit v1.2.3 From 8d814961234fda66f01bb0505f166537913d745c Mon Sep 17 00:00:00 2001 From: Andrea Gelmini Date: Sat, 16 Oct 2010 15:19:24 +0200 Subject: drivers: scsi: fix typo in comment Signed-off-by: Andrea Gelmini Signed-off-by: Jiri Kosina --- drivers/scsi/aic94xx/aic94xx_scb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/aic94xx/aic94xx_scb.c b/drivers/scsi/aic94xx/aic94xx_scb.c index c43698b1cb64..29593275201a 100644 --- a/drivers/scsi/aic94xx/aic94xx_scb.c +++ b/drivers/scsi/aic94xx/aic94xx_scb.c @@ -867,7 +867,7 @@ void asd_build_initiate_link_adm_task(struct asd_ascb *ascb, int phy_id, * resources they have with this SCB, and then call this one at the * end of their timeout function. To do this, one should initialize * the ascb->timer.{function, data, expires} prior to calling the post - * funcion. The timer is started by the post function. + * function. The timer is started by the post function. */ void asd_ascb_timedout(unsigned long data) { -- cgit v1.2.3 From 79ee820d2aa24ac2577ca4e89ecc49c26d099707 Mon Sep 17 00:00:00 2001 From: Jarkko Nikula Date: Mon, 1 Nov 2010 14:03:55 +0200 Subject: ASoC: tlv320aic3x: Use gpio_is_valid in checking for valid gpio_reset I promised to convert this at some point. Signed-off-by: Jarkko Nikula Acked-by: Mark Brown Signed-off-by: Liam Girdwood --- sound/soc/codecs/tlv320aic3x.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c index fc687790188b..157b534585f4 100644 --- a/sound/soc/codecs/tlv320aic3x.c +++ b/sound/soc/codecs/tlv320aic3x.c @@ -1075,7 +1075,7 @@ static int aic3x_regulator_event(struct notifier_block *nb, * Put codec to reset and require cache sync as at least one * of the supplies was disabled */ - if (aic3x->gpio_reset >= 0) + if (gpio_is_valid(aic3x->gpio_reset)) gpio_set_value(aic3x->gpio_reset, 0); aic3x->codec->cache_sync = 1; } @@ -1102,7 +1102,7 @@ static int aic3x_set_power(struct snd_soc_codec *codec, int power) if (!codec->cache_sync) goto out; - if (aic3x->gpio_reset >= 0) { + if (gpio_is_valid(aic3x->gpio_reset)) { udelay(1); gpio_set_value(aic3x->gpio_reset, 1); } @@ -1359,7 +1359,7 @@ static int aic3x_probe(struct snd_soc_codec *codec) return ret; } - if (aic3x->gpio_reset >= 0) { + if (gpio_is_valid(aic3x->gpio_reset)) { ret = gpio_request(aic3x->gpio_reset, "tlv320aic3x reset"); if (ret != 0) goto err_gpio; @@ -1414,7 +1414,7 @@ err_notif: &aic3x->disable_nb[i].nb); regulator_bulk_free(ARRAY_SIZE(aic3x->supplies), aic3x->supplies); err_get: - if (aic3x->gpio_reset >= 0) + if (gpio_is_valid(aic3x->gpio_reset)) gpio_free(aic3x->gpio_reset); err_gpio: kfree(aic3x); @@ -1427,7 +1427,7 @@ static int aic3x_remove(struct snd_soc_codec *codec) int i; aic3x_set_bias_level(codec, SND_SOC_BIAS_OFF); - if (aic3x->gpio_reset >= 0) { + if (gpio_is_valid(aic3x->gpio_reset)) { gpio_set_value(aic3x->gpio_reset, 0); gpio_free(aic3x->gpio_reset); } -- cgit v1.2.3 From 414c73abfd0e565950f3b02336cf516147f0e104 Mon Sep 17 00:00:00 2001 From: Jarkko Nikula Date: Mon, 1 Nov 2010 14:03:56 +0200 Subject: ASoC: tlv320aic3x: Add support to shared common reset line This is aimed to configurations where multiple aic3x codecs share the same reset line and are powered from same supply voltages. Currently aic3x_probe will fail if trying to request already requested gpio_reset and passing -1 to another aic3x instances cause that those instances cannot release reset in aic3x_set_power. That is, another instances can work only if primary aic3x instance is powered and reset is released. Solve this by implementing a list of probed instances that is used for checking if other instance shares the same gpio_reset number. If a shared reset line exists, then only first instance tries to request and configure it and the last instance releases it. Runtime modifications are not needed since aic3x_regulator_event with help of regulator framework takes already care that reset is pulled down only when some or all supplies are disabled meaning that all instances using them are idle. Signed-off-by: Jarkko Nikula Acked-by: Mark Brown Signed-off-by: Liam Girdwood --- sound/soc/codecs/tlv320aic3x.c | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c index 157b534585f4..684ca3a57caa 100644 --- a/sound/soc/codecs/tlv320aic3x.c +++ b/sound/soc/codecs/tlv320aic3x.c @@ -61,6 +61,8 @@ static const char *aic3x_supply_names[AIC3X_NUM_SUPPLIES] = { "DRVDD", /* ADC Analog and Output Driver Voltage */ }; +static LIST_HEAD(reset_list); + struct aic3x_priv; struct aic3x_disable_nb { @@ -77,6 +79,7 @@ struct aic3x_priv { struct aic3x_setup_data *setup; void *control_data; unsigned int sysclk; + struct list_head list; int master; int gpio_reset; int power; @@ -1344,11 +1347,25 @@ static int aic3x_init(struct snd_soc_codec *codec) return 0; } +static bool aic3x_is_shared_reset(struct aic3x_priv *aic3x) +{ + struct aic3x_priv *a; + + list_for_each_entry(a, &reset_list, list) { + if (gpio_is_valid(aic3x->gpio_reset) && + aic3x->gpio_reset == a->gpio_reset) + return true; + } + + return false; +} + static int aic3x_probe(struct snd_soc_codec *codec) { struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec); int ret, i; + INIT_LIST_HEAD(&aic3x->list); codec->control_data = aic3x->control_data; aic3x->codec = codec; codec->idle_bias_off = 1; @@ -1359,7 +1376,8 @@ static int aic3x_probe(struct snd_soc_codec *codec) return ret; } - if (gpio_is_valid(aic3x->gpio_reset)) { + if (gpio_is_valid(aic3x->gpio_reset) && + !aic3x_is_shared_reset(aic3x)) { ret = gpio_request(aic3x->gpio_reset, "tlv320aic3x reset"); if (ret != 0) goto err_gpio; @@ -1405,6 +1423,7 @@ static int aic3x_probe(struct snd_soc_codec *codec) snd_soc_add_controls(codec, &aic3x_classd_amp_gain_ctrl, 1); aic3x_add_widgets(codec); + list_add(&aic3x->list, &reset_list); return 0; @@ -1414,7 +1433,8 @@ err_notif: &aic3x->disable_nb[i].nb); regulator_bulk_free(ARRAY_SIZE(aic3x->supplies), aic3x->supplies); err_get: - if (gpio_is_valid(aic3x->gpio_reset)) + if (gpio_is_valid(aic3x->gpio_reset) && + !aic3x_is_shared_reset(aic3x)) gpio_free(aic3x->gpio_reset); err_gpio: kfree(aic3x); @@ -1427,7 +1447,9 @@ static int aic3x_remove(struct snd_soc_codec *codec) int i; aic3x_set_bias_level(codec, SND_SOC_BIAS_OFF); - if (gpio_is_valid(aic3x->gpio_reset)) { + list_del(&aic3x->list); + if (gpio_is_valid(aic3x->gpio_reset) && + !aic3x_is_shared_reset(aic3x)) { gpio_set_value(aic3x->gpio_reset, 0); gpio_free(aic3x->gpio_reset); } -- cgit v1.2.3 From 6d2ad1e318adbf593746305746b0c1252d5949ae Mon Sep 17 00:00:00 2001 From: matt mooney Date: Mon, 27 Sep 2010 19:04:44 -0700 Subject: powerpc: remove cast from void* Unnecessary cast from void* in assignment. Signed-off-by: matt mooney Acked-by: Benjamin Herrenschmidt Signed-off-by: Jiri Kosina --- arch/powerpc/platforms/pseries/hvCall_inst.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/powerpc/platforms/pseries/hvCall_inst.c b/arch/powerpc/platforms/pseries/hvCall_inst.c index e19ff021e711..f106662f4381 100644 --- a/arch/powerpc/platforms/pseries/hvCall_inst.c +++ b/arch/powerpc/platforms/pseries/hvCall_inst.c @@ -55,7 +55,7 @@ static void hc_stop(struct seq_file *m, void *p) static int hc_show(struct seq_file *m, void *p) { unsigned long h_num = (unsigned long)p; - struct hcall_stats *hs = (struct hcall_stats *)m->private; + struct hcall_stats *hs = m->private; if (hs[h_num].num_calls) { if (cpu_has_feature(CPU_FTR_PURR)) -- cgit v1.2.3 From 99b9f758bbc904f22faffcf4d83205f4a5e7bc0c Mon Sep 17 00:00:00 2001 From: "Edgar (gimli) Hucek" Date: Wed, 3 Nov 2010 10:36:18 -0400 Subject: HID: add MacBookAir 3,1 and 3,2 support This patch add support for the MacBookAir3,1 and MacBookAir3,2 to the hid driver. Signed-off-by: Edgar (gimli) Hucek Signed-off-by: Jiri Kosina --- drivers/hid/hid-apple.c | 46 ++++++++++++++++++++++++++++++++++++++++++---- drivers/hid/hid-core.c | 12 ++++++++++++ drivers/hid/hid-ids.h | 6 ++++++ 3 files changed, 60 insertions(+), 4 deletions(-) diff --git a/drivers/hid/hid-apple.c b/drivers/hid/hid-apple.c index eaeca564a8d3..6c52203cdbdf 100644 --- a/drivers/hid/hid-apple.c +++ b/drivers/hid/hid-apple.c @@ -59,6 +59,27 @@ struct apple_key_translation { u8 flags; }; +static const struct apple_key_translation macbookair_fn_keys[] = { + { KEY_BACKSPACE, KEY_DELETE }, + { KEY_ENTER, KEY_INSERT }, + { KEY_F1, KEY_BRIGHTNESSDOWN, APPLE_FLAG_FKEY }, + { KEY_F2, KEY_BRIGHTNESSUP, APPLE_FLAG_FKEY }, + { KEY_F3, KEY_SCALE, APPLE_FLAG_FKEY }, + { KEY_F4, KEY_DASHBOARD, APPLE_FLAG_FKEY }, + { KEY_F6, KEY_PREVIOUSSONG, APPLE_FLAG_FKEY }, + { KEY_F7, KEY_PLAYPAUSE, APPLE_FLAG_FKEY }, + { KEY_F8, KEY_NEXTSONG, APPLE_FLAG_FKEY }, + { KEY_F9, KEY_MUTE, APPLE_FLAG_FKEY }, + { KEY_F10, KEY_VOLUMEDOWN, APPLE_FLAG_FKEY }, + { KEY_F11, KEY_VOLUMEUP, APPLE_FLAG_FKEY }, + { KEY_F12, KEY_EJECTCD, APPLE_FLAG_FKEY }, + { KEY_UP, KEY_PAGEUP }, + { KEY_DOWN, KEY_PAGEDOWN }, + { KEY_LEFT, KEY_HOME }, + { KEY_RIGHT, KEY_END }, + { } +}; + static const struct apple_key_translation apple_fn_keys[] = { { KEY_BACKSPACE, KEY_DELETE }, { KEY_ENTER, KEY_INSERT }, @@ -157,10 +178,15 @@ static int hidinput_apple_event(struct hid_device *hid, struct input_dev *input, if (fnmode) { int do_translate; - trans = apple_find_translation((hid->product < 0x21d || - hid->product >= 0x300) ? - powerbook_fn_keys : apple_fn_keys, - usage->code); + if(hid->product >= USB_DEVICE_ID_APPLE_WELLSPRING4_ANSI && + hid->product <= USB_DEVICE_ID_APPLE_WELLSPRING4A_JIS) { + trans = apple_find_translation(macbookair_fn_keys, usage->code); + } else if (hid->product < 0x21d || hid->product >= 0x300) { + trans = apple_find_translation(powerbook_fn_keys, usage->code); + } else { + trans = apple_find_translation(apple_fn_keys, usage->code); + } + if (trans) { if (test_bit(usage->code, asc->pressed_fn)) do_translate = 1; @@ -440,6 +466,18 @@ static const struct hid_device_id apple_devices[] = { .driver_data = APPLE_HAS_FN | APPLE_ISO_KEYBOARD }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_JIS), .driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4_ANSI), + .driver_data = APPLE_HAS_FN }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4_ISO), + .driver_data = APPLE_HAS_FN | APPLE_ISO_KEYBOARD }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4_JIS), + .driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4A_ANSI), + .driver_data = APPLE_HAS_FN }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4A_ISO), + .driver_data = APPLE_HAS_FN | APPLE_ISO_KEYBOARD }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4A_JIS), + .driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI), .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO), diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index b3393e17b375..53ac909e2fff 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -1276,6 +1276,12 @@ static const struct hid_device_id hid_blacklist[] = { { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_ANSI) }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_ISO) }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_JIS) }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4_ANSI) }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4_ISO) }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4_JIS) }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4A_ANSI) }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4A_ISO) }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4A_JIS) }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI) }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO) }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_JIS) }, @@ -1757,6 +1763,12 @@ static const struct hid_device_id hid_mouse_ignore_list[] = { { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_ANSI) }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_ISO) }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING3_JIS) }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4_ANSI) }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4_ISO) }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4_JIS) }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4A_ANSI) }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4A_ISO) }, + { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING4A_JIS) }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_FOUNTAIN_TP_ONLY) }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_GEYSER1_TP_ONLY) }, { } diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 68114dbcd895..104b9f9a4c0b 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -97,6 +97,12 @@ #define USB_DEVICE_ID_APPLE_WELLSPRING3_ANSI 0x0236 #define USB_DEVICE_ID_APPLE_WELLSPRING3_ISO 0x0237 #define USB_DEVICE_ID_APPLE_WELLSPRING3_JIS 0x0238 +#define USB_DEVICE_ID_APPLE_WELLSPRING4_ANSI 0x023f +#define USB_DEVICE_ID_APPLE_WELLSPRING4_ISO 0x0240 +#define USB_DEVICE_ID_APPLE_WELLSPRING4_JIS 0x0241 +#define USB_DEVICE_ID_APPLE_WELLSPRING4A_ANSI 0x0242 +#define USB_DEVICE_ID_APPLE_WELLSPRING4A_ISO 0x0243 +#define USB_DEVICE_ID_APPLE_WELLSPRING4A_JIS 0x0244 #define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI 0x0239 #define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO 0x023a #define USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_JIS 0x023b -- cgit v1.2.3 From a4bc6926d05b60bf70aab2db2c6715e15118cbdc Mon Sep 17 00:00:00 2001 From: Jiri Kosina Date: Wed, 3 Nov 2010 10:42:02 -0400 Subject: HID: make translation table selection more clear Reshuffle the code a little bit so that the translation table selection is more obvious and there is only one place performing the actual translation using the selected table. Signed-off-by: Jiri Kosina --- drivers/hid/hid-apple.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/drivers/hid/hid-apple.c b/drivers/hid/hid-apple.c index 6c52203cdbdf..8aa71750a23c 100644 --- a/drivers/hid/hid-apple.c +++ b/drivers/hid/hid-apple.c @@ -167,7 +167,7 @@ static int hidinput_apple_event(struct hid_device *hid, struct input_dev *input, struct hid_usage *usage, __s32 value) { struct apple_sc *asc = hid_get_drvdata(hid); - const struct apple_key_translation *trans; + const struct apple_key_translation *trans, *table; if (usage->code == KEY_FN) { asc->fn_on = !!value; @@ -178,14 +178,15 @@ static int hidinput_apple_event(struct hid_device *hid, struct input_dev *input, if (fnmode) { int do_translate; - if(hid->product >= USB_DEVICE_ID_APPLE_WELLSPRING4_ANSI && - hid->product <= USB_DEVICE_ID_APPLE_WELLSPRING4A_JIS) { - trans = apple_find_translation(macbookair_fn_keys, usage->code); - } else if (hid->product < 0x21d || hid->product >= 0x300) { - trans = apple_find_translation(powerbook_fn_keys, usage->code); - } else { - trans = apple_find_translation(apple_fn_keys, usage->code); - } + if (hid->product >= USB_DEVICE_ID_APPLE_WELLSPRING4_ANSI && + hid->product <= USB_DEVICE_ID_APPLE_WELLSPRING4A_JIS) + table = macbookair_fn_keys; + else if (hid->product < 0x21d || hid->product >= 0x300) + table = powerbook_fn_keys; + else + table = apple_fn_keys; + + trans = apple_find_translation (table, usage->code); if (trans) { if (test_bit(usage->code, asc->pressed_fn)) -- cgit v1.2.3 From 3f58fd84b0c0bd482151259ee0d2921974e1fe4c Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 3 Nov 2010 09:35:31 -0400 Subject: ASoC: Convert soc-jack code to use request_any_context_irq() Allow the standard soc-jack GPIO based jack handling to handle the use of GPIOs which may sleep (such as those on GPIO expanders) by converting the code to use request_any_context_irq(). Signed-off-by: Mark Brown Acked-by: Liam Girdwood --- sound/soc/soc-jack.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/sound/soc/soc-jack.c b/sound/soc/soc-jack.c index 8a0a9205b1e7..9f07551e155f 100644 --- a/sound/soc/soc-jack.c +++ b/sound/soc/soc-jack.c @@ -263,11 +263,12 @@ int snd_soc_jack_add_gpios(struct snd_soc_jack *jack, int count, INIT_DELAYED_WORK(&gpios[i].work, gpio_work); gpios[i].jack = jack; - ret = request_irq(gpio_to_irq(gpios[i].gpio), - gpio_handler, - IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, - jack->codec->dev->driver->name, - &gpios[i]); + ret = request_any_context_irq(gpio_to_irq(gpios[i].gpio), + gpio_handler, + IRQF_TRIGGER_RISING | + IRQF_TRIGGER_FALLING, + jack->codec->dev->driver->name, + &gpios[i]); if (ret) goto err; -- cgit v1.2.3 From c3753707991218aa2c18449a921847877533aa09 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Mon, 1 Nov 2010 15:41:57 -0400 Subject: ASoC: Push snd_soc_write() and snd_soc_read() into the source file Facilitating adding trace type stuff. For a first pass add some dev_dbg() statements into them. Signed-off-by: Mark Brown Acked-by: Liam Girdwood --- include/sound/soc.h | 14 +++----------- sound/soc/soc-core.c | 19 +++++++++++++++++++ 2 files changed, 22 insertions(+), 11 deletions(-) diff --git a/include/sound/soc.h b/include/sound/soc.h index 5c3bce83f28a..aaf34d7cd95e 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -639,17 +639,9 @@ struct soc_enum { }; /* codec IO */ -static inline unsigned int snd_soc_read(struct snd_soc_codec *codec, - unsigned int reg) -{ - return codec->driver->read(codec, reg); -} - -static inline unsigned int snd_soc_write(struct snd_soc_codec *codec, - unsigned int reg, unsigned int val) -{ - return codec->driver->write(codec, reg, val); -} +unsigned int snd_soc_read(struct snd_soc_codec *codec, unsigned int reg); +unsigned int snd_soc_write(struct snd_soc_codec *codec, + unsigned int reg, unsigned int val); /* device driver data */ diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 614a8b30d87b..4360436ef035 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -1877,6 +1877,25 @@ 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->driver->read(codec, reg); + dev_dbg(codec->dev, "read %x => %x\n", 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); + return codec->driver->write(codec, reg, val); +} +EXPORT_SYMBOL_GPL(snd_soc_write); + /** * snd_soc_update_bits - update codec register bits * @codec: audio codec -- cgit v1.2.3 From 11dbf0acb4aba818a4f0600996216be55667b400 Mon Sep 17 00:00:00 2001 From: Dimitris Papastamos Date: Wed, 3 Nov 2010 16:50:36 +0000 Subject: ASoC: soc-cache: Remove unnecessary debugging info No need to print the register-value pair again, as we've already hooked snd_soc_write() for that matter. Signed-off-by: Dimitris Papastamos Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/soc-cache.c | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/sound/soc/soc-cache.c b/sound/soc/soc-cache.c index d214f02cbb65..8785a0c918d2 100644 --- a/sound/soc/soc-cache.c +++ b/sound/soc/soc-cache.c @@ -50,8 +50,6 @@ static int snd_soc_4_12_write(struct snd_soc_codec *codec, unsigned int reg, return 0; } - dev_dbg(codec->dev, "0x%x = 0x%x\n", reg, value); - ret = codec->hw_write(codec->control_data, data, 2); if (ret == 2) return 0; @@ -126,8 +124,6 @@ static int snd_soc_7_9_write(struct snd_soc_codec *codec, unsigned int reg, return 0; } - dev_dbg(codec->dev, "0x%x = 0x%x\n", reg, value); - ret = codec->hw_write(codec->control_data, data, 2); if (ret == 2) return 0; @@ -186,8 +182,6 @@ static int snd_soc_8_8_write(struct snd_soc_codec *codec, unsigned int reg, return 0; } - dev_dbg(codec->dev, "0x%x = 0x%x\n", reg, value); - if (codec->hw_write(codec->control_data, data, 2) == 2) return 0; else @@ -260,8 +254,6 @@ static int snd_soc_8_16_write(struct snd_soc_codec *codec, unsigned int reg, return 0; } - dev_dbg(codec->dev, "0x%x = 0x%x\n", reg, value); - if (codec->hw_write(codec->control_data, data, 3) == 3) return 0; else @@ -455,8 +447,6 @@ static int snd_soc_16_8_write(struct snd_soc_codec *codec, unsigned int reg, return 0; } - dev_dbg(codec->dev, "0x%x = 0x%x\n", reg, value); - ret = codec->hw_write(codec->control_data, data, 3); if (ret == 3) return 0; @@ -568,8 +558,6 @@ static int snd_soc_16_16_write(struct snd_soc_codec *codec, unsigned int reg, return 0; } - dev_dbg(codec->dev, "0x%x = 0x%x\n", reg, value); - ret = codec->hw_write(codec->control_data, data, 4); if (ret == 4) return 0; -- cgit v1.2.3 From 9db3b9bcc7f53487da8766b32e2d790ad03c53b9 Mon Sep 17 00:00:00 2001 From: Ross Kirk Date: Fri, 22 Oct 2010 16:43:17 +0100 Subject: audit: error message typo correction Fixes a typo in the error message raised by audit when auditd has died. Signed-off-by: Ross Kirk -- Signed-off-by: Jiri Kosina --- kernel/audit.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/audit.c b/kernel/audit.c index 77770a034d59..e4956244ae50 100644 --- a/kernel/audit.c +++ b/kernel/audit.c @@ -400,7 +400,7 @@ static void kauditd_send_skb(struct sk_buff *skb) if (err < 0) { BUG_ON(err != -ECONNREFUSED); /* Shouldn't happen */ printk(KERN_ERR "audit: *NO* daemon at audit_pid=%d\n", audit_pid); - audit_log_lost("auditd dissapeared\n"); + audit_log_lost("auditd disappeared\n"); audit_pid = 0; /* we might get lucky and get this in the next auditd */ audit_hold_skb(skb); -- cgit v1.2.3 From 7b0f42b59a01a2cc563c5f8670133b819e5c9895 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 3 Nov 2010 13:48:04 -0400 Subject: ASoC: Remove register write trace from WM8994 We now have trace in the ASoC core so we don't need to our own trace in the driver. Signed-off-by: Mark Brown Acked-by: Liam Girdwood --- sound/soc/codecs/wm8994.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index 3f70dee048b0..d81cac5b93b4 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c @@ -1730,8 +1730,6 @@ static int wm8994_write(struct snd_soc_codec *codec, unsigned int reg, if (!wm8994_volatile(reg)) wm8994->reg_cache[reg] = value; - dev_dbg(codec->dev, "0x%x = 0x%x\n", reg, value); - return wm8994_reg_write(codec->control_data, reg, value); } -- cgit v1.2.3 From 11e16eb365f4f6979cfcb2a2d379338b383590d9 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 3 Nov 2010 14:45:07 -0400 Subject: ASoC: Use pm_wakeup_event() in WM8962 jack detection Ensure that the system does not suspend while we process a WM8962 jack event by using pm_wakeup_event() to block the suspend while we're waiting for the jack to settle. Use a slightly longer timeout than the jack waits to allow for other stuff to take over and delays in scheduling. Signed-off-by: Mark Brown Acked-by: Liam Girdwood --- sound/soc/codecs/wm8962.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c index 894d0cd3aa9b..2eaf9bb36b57 100644 --- a/sound/soc/codecs/wm8962.c +++ b/sound/soc/codecs/wm8962.c @@ -3353,6 +3353,8 @@ static irqreturn_t wm8962_irq(int irq, void *data) if (active & (WM8962_MICSCD_EINT | WM8962_MICD_EINT)) { dev_dbg(codec->dev, "Microphone event detected\n"); + pm_wakeup_event(codec->dev, 300); + schedule_delayed_work(&wm8962->mic_work, msecs_to_jiffies(250)); } -- cgit v1.2.3 From 90246e79af062fcbb8c3728a5f29cb19b3468f59 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Thu, 4 Nov 2010 13:00:22 -0500 Subject: crypto: hash - Fix async import on shash algorithm The function shash_async_import did not initialise the descriptor correctly prior to calling the underlying shash import function. This patch adds the required initialisation. Reported-by: Miloslav Trmac Signed-off-by: Herbert Xu --- crypto/shash.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/crypto/shash.c b/crypto/shash.c index 22fd9433141f..76f74b963151 100644 --- a/crypto/shash.c +++ b/crypto/shash.c @@ -310,7 +310,13 @@ static int shash_async_export(struct ahash_request *req, void *out) static int shash_async_import(struct ahash_request *req, const void *in) { - return crypto_shash_import(ahash_request_ctx(req), in); + struct crypto_shash **ctx = crypto_ahash_ctx(crypto_ahash_reqtfm(req)); + struct shash_desc *desc = ahash_request_ctx(req); + + desc->tfm = *ctx; + desc->flags = req->base.flags; + + return crypto_shash_import(desc, in); } static void crypto_exit_shash_ops_async(struct crypto_tfm *tfm) -- cgit v1.2.3 From 818f2a3cc34b0673dccd4188ce4a1862d9d90127 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Thu, 4 Nov 2010 17:04:29 +0100 Subject: drm/i915: revert pageflip/mappable related abi breakage In a00b10c360b35d6431a "Only enforce fence limits inside the GTT" Chris Wilson implemented an optimization to only pin framebuffers as mappable for crtc_set_base (but not for pageflips). This breaks the abi, eg: A double buffering mesa client might leave the last framebuffer in unmappable space on close. A subsequent glReadPix by a frontbuffer rendering client then goes boom. My pretty anal mappable/unmappable consistency checking detected this, see https://bugs.freedesktop.org/show_bug.cgi?id=31286 Chris Wilson tried to fix this in 085ce2643713830cf772c by pinning tiled framebuffers into mappable space. This a) renders the original optimization of not forcing framebuffers for pageflipping clients into mappable pointless because all our scanout buffers are tiled by default. b) doesn't solve the problem for untiled framebuffers. So kill this. Emperically it's no gain anyway because framebuffers are being reused by the ddx and hence there's no chance for them to get constanly bounced between mappable and unmappable. Signed-off-by: Daniel Vetter Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/intel_display.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index f1e4eca44866..a2cd579eb9b2 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -1461,8 +1461,7 @@ intel_pin_and_fence_fb_obj(struct drm_device *dev, BUG(); } - ret = i915_gem_object_pin(obj, alignment, - !pipelined || obj_priv->tiling_mode, + ret = i915_gem_object_pin(obj, alignment, true, obj_priv->tiling_mode); if (ret) return ret; -- cgit v1.2.3 From 75e9e9158f38e5cb21eff23b30bafa6f32e0a606 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Thu, 4 Nov 2010 17:11:09 +0100 Subject: drm/i915: kill mappable/fenceable disdinction a00b10c360b35d6431a "Only enforce fence limits inside the GTT" also added a fenceable/mappable disdinction when binding/pinning buffers. This only complicates the code with no pratical gain: - In execbuffer this matters on for g33/pineview, as this is the only chip that needs fences and has an unmappable gtt area. But fences are only possible in the mappable part of the gtt, so need_fence implies need_mappable. And need_mappable is only set independantly with relocations which implies (for sane userspace) that the buffer is untiled. - The overlay code is only really used on i8xx, which doesn't have unmappable gtt. And it doesn't support tiled buffers, currently. - For all other buffers it's a bug to pass in a tiled bo. In short, this disdinction doesn't have any practical gain. I've also reverted mapping the overlay and context pages as possibly unmappable. It's not worth being overtly clever here, all the big gains from unmappable are for execbuf bos. Also add a comment for a clever optimization that confused me while reading the original patch by Chris Wilson. Signed-off-by: Daniel Vetter Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_drv.h | 10 ++-- drivers/gpu/drm/i915/i915_gem.c | 84 ++++++++++++++++----------------- drivers/gpu/drm/i915/intel_display.c | 7 ++- drivers/gpu/drm/i915/intel_overlay.c | 4 +- drivers/gpu/drm/i915/intel_ringbuffer.c | 6 +-- 5 files changed, 56 insertions(+), 55 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 48d0aefec1f8..621234265454 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -752,8 +752,6 @@ struct drm_i915_gem_object { * Advice: are the backing pages purgeable? */ unsigned int madv : 2; - unsigned int fenceable : 1; - unsigned int mappable : 1; /** * Current tiling mode for the object. @@ -772,6 +770,12 @@ struct drm_i915_gem_object { unsigned int pin_count : 4; #define DRM_I915_GEM_OBJECT_MAX_PIN_COUNT 0xf + /** + * Is the object at the current location in the gtt mappable and + * fenceable? Used to avoid costly recalculations. + */ + unsigned int map_and_fenceable : 1; + /** * Whether the current gtt mapping needs to be mappable (and isn't just * mappable by accident). Track pin and fault separate for a more @@ -1013,7 +1017,7 @@ struct drm_gem_object * i915_gem_alloc_object(struct drm_device *dev, size_t size); void i915_gem_free_object(struct drm_gem_object *obj); int i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment, - bool mappable, bool need_fence); + bool map_and_fenceable); void i915_gem_object_unpin(struct drm_gem_object *obj); int i915_gem_object_unbind(struct drm_gem_object *obj); void i915_gem_release_mmap(struct drm_gem_object *obj); diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 12dae003c011..47c665eeaf17 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -59,8 +59,7 @@ static int i915_gem_object_wait_rendering(struct drm_gem_object *obj, bool interruptible); static int i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment, - bool mappable, - bool need_fence); + bool map_and_fenceable); static void i915_gem_clear_fence_reg(struct drm_gem_object *obj); static int i915_gem_phys_pwrite(struct drm_device *dev, struct drm_gem_object *obj, struct drm_i915_gem_pwrite *args, @@ -1074,7 +1073,7 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data, else if (obj_priv->tiling_mode == I915_TILING_NONE && obj_priv->gtt_space && obj->write_domain != I915_GEM_DOMAIN_CPU) { - ret = i915_gem_object_pin(obj, 0, true, false); + ret = i915_gem_object_pin(obj, 0, true); if (ret) goto out; @@ -1300,8 +1299,7 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) BUG_ON(obj_priv->pin_count && !obj_priv->pin_mappable); if (obj_priv->gtt_space) { - if (!obj_priv->mappable || - (obj_priv->tiling_mode && !obj_priv->fenceable)) { + if (!obj_priv->map_and_fenceable) { ret = i915_gem_object_unbind(obj); if (ret) goto unlock; @@ -1309,8 +1307,7 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) } if (!obj_priv->gtt_space) { - ret = i915_gem_object_bind_to_gtt(obj, 0, - true, obj_priv->tiling_mode); + ret = i915_gem_object_bind_to_gtt(obj, 0, true); if (ret) goto unlock; } @@ -2273,8 +2270,8 @@ i915_gem_object_unbind(struct drm_gem_object *obj) i915_gem_info_remove_gtt(dev_priv, obj_priv); list_del_init(&obj_priv->mm_list); - obj_priv->fenceable = true; - obj_priv->mappable = true; + /* Avoid an unnecessary call to unbind on rebind. */ + obj_priv->map_and_fenceable = true; drm_mm_put_block(obj_priv->gtt_space); obj_priv->gtt_space = NULL; @@ -2383,7 +2380,7 @@ static void i915_write_fence_reg(struct drm_gem_object *obj) if ((obj_priv->gtt_offset & ~I915_FENCE_START_MASK) || (obj_priv->gtt_offset & (size - 1))) { WARN(1, "%s: object 0x%08x [fenceable? %d] not 1M or size (0x%08x) aligned [gtt_space offset=%lx, size=%lx]\n", - __func__, obj_priv->gtt_offset, obj_priv->fenceable, size, + __func__, obj_priv->gtt_offset, obj_priv->map_and_fenceable, size, obj_priv->gtt_space->start, obj_priv->gtt_space->size); return; } @@ -2687,8 +2684,7 @@ i915_gem_object_put_fence_reg(struct drm_gem_object *obj, static int i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, unsigned alignment, - bool mappable, - bool need_fence) + bool map_and_fenceable) { struct drm_device *dev = obj->dev; drm_i915_private_t *dev_priv = dev->dev_private; @@ -2696,6 +2692,7 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, struct drm_mm_node *free_space; gfp_t gfpmask = __GFP_NORETRY | __GFP_NOWARN; u32 size, fence_size, fence_alignment; + bool mappable, fenceable; int ret; if (obj_priv->madv != I915_MADV_WILLNEED) { @@ -2707,25 +2704,25 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, fence_alignment = i915_gem_get_gtt_alignment(obj_priv); if (alignment == 0) - alignment = need_fence ? fence_alignment : 4096; - if (need_fence && alignment & (fence_alignment - 1)) { + alignment = map_and_fenceable ? fence_alignment : 4096; + if (map_and_fenceable && alignment & (fence_alignment - 1)) { DRM_ERROR("Invalid object alignment requested %u\n", alignment); return -EINVAL; } - size = need_fence ? fence_size : obj->size; + size = map_and_fenceable ? fence_size : obj->size; /* If the object is bigger than the entire aperture, reject it early * before evicting everything in a vain attempt to find space. */ if (obj->size > - (mappable ? dev_priv->mm.gtt_mappable_end : dev_priv->mm.gtt_total)) { + (map_and_fenceable ? dev_priv->mm.gtt_mappable_end : dev_priv->mm.gtt_total)) { DRM_ERROR("Attempting to bind an object larger than the aperture\n"); return -E2BIG; } search_free: - if (mappable) + if (map_and_fenceable) free_space = drm_mm_search_free_in_range(&dev_priv->mm.gtt_space, size, alignment, 0, @@ -2736,7 +2733,7 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, size, alignment, 0); if (free_space != NULL) { - if (mappable) + if (map_and_fenceable) obj_priv->gtt_space = drm_mm_get_block_range_generic(free_space, size, alignment, 0, @@ -2750,7 +2747,8 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, /* If the gtt is empty and we're still having trouble * fitting our object in, we're out of memory. */ - ret = i915_gem_evict_something(dev, size, alignment, mappable); + ret = i915_gem_evict_something(dev, size, alignment, + map_and_fenceable); if (ret) return ret; @@ -2765,7 +2763,8 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, if (ret == -ENOMEM) { /* first try to clear up some space from the GTT */ ret = i915_gem_evict_something(dev, size, - alignment, mappable); + alignment, + map_and_fenceable); if (ret) { /* now try to shrink everyone else */ if (gfpmask) { @@ -2796,7 +2795,7 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, obj_priv->gtt_space = NULL; ret = i915_gem_evict_something(dev, size, - alignment, mappable); + alignment, map_and_fenceable); if (ret) return ret; @@ -2816,15 +2815,17 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, BUG_ON(obj->read_domains & I915_GEM_GPU_DOMAINS); BUG_ON(obj->write_domain & I915_GEM_GPU_DOMAINS); - trace_i915_gem_object_bind(obj, obj_priv->gtt_offset, mappable); + trace_i915_gem_object_bind(obj, obj_priv->gtt_offset, map_and_fenceable); - obj_priv->fenceable = + fenceable = obj_priv->gtt_space->size == fence_size && (obj_priv->gtt_space->start & (fence_alignment -1)) == 0; - obj_priv->mappable = + mappable = obj_priv->gtt_offset + obj->size <= dev_priv->mm.gtt_mappable_end; + obj_priv->map_and_fenceable = mappable && fenceable; + return 0; } @@ -3538,8 +3539,7 @@ i915_gem_execbuffer_pin(struct drm_device *dev, entry->relocation_count ? true : need_fence; /* Check fence reg constraints and rebind if necessary */ - if ((need_fence && !obj->fenceable) || - (need_mappable && !obj->mappable)) { + if (need_mappable && !obj->map_and_fenceable) { ret = i915_gem_object_unbind(&obj->base); if (ret) break; @@ -3547,8 +3547,7 @@ i915_gem_execbuffer_pin(struct drm_device *dev, ret = i915_gem_object_pin(&obj->base, entry->alignment, - need_mappable, - need_fence); + need_mappable); if (ret) break; @@ -4143,7 +4142,7 @@ i915_gem_execbuffer2(struct drm_device *dev, void *data, int i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment, - bool mappable, bool need_fence) + bool map_and_fenceable) { struct drm_device *dev = obj->dev; struct drm_i915_private *dev_priv = dev->dev_private; @@ -4151,19 +4150,19 @@ i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment, int ret; BUG_ON(obj_priv->pin_count == DRM_I915_GEM_OBJECT_MAX_PIN_COUNT); - BUG_ON(need_fence && !mappable); + BUG_ON(map_and_fenceable && !map_and_fenceable); WARN_ON(i915_verify_lists(dev)); if (obj_priv->gtt_space != NULL) { if ((alignment && obj_priv->gtt_offset & (alignment - 1)) || - (need_fence && !obj_priv->fenceable) || - (mappable && !obj_priv->mappable)) { + (map_and_fenceable && !obj_priv->map_and_fenceable)) { WARN(obj_priv->pin_count, "bo is already pinned with incorrect alignment:" - " offset=%x, req.alignment=%x, need_fence=%d, fenceable=%d, mappable=%d, cpu_accessible=%d\n", + " offset=%x, req.alignment=%x, req.map_and_fenceable=%d," + " obj->map_and_fenceable=%d\n", obj_priv->gtt_offset, alignment, - need_fence, obj_priv->fenceable, - mappable, obj_priv->mappable); + map_and_fenceable, + obj_priv->map_and_fenceable); ret = i915_gem_object_unbind(obj); if (ret) return ret; @@ -4172,18 +4171,18 @@ i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment, if (obj_priv->gtt_space == NULL) { ret = i915_gem_object_bind_to_gtt(obj, alignment, - mappable, need_fence); + map_and_fenceable); if (ret) return ret; } if (obj_priv->pin_count++ == 0) { - i915_gem_info_add_pin(dev_priv, obj_priv, mappable); + i915_gem_info_add_pin(dev_priv, obj_priv, map_and_fenceable); if (!obj_priv->active) list_move_tail(&obj_priv->mm_list, &dev_priv->mm.pinned_list); } - BUG_ON(!obj_priv->pin_mappable && mappable); + BUG_ON(!obj_priv->pin_mappable && map_and_fenceable); WARN_ON(i915_verify_lists(dev)); return 0; @@ -4245,8 +4244,7 @@ i915_gem_pin_ioctl(struct drm_device *dev, void *data, obj_priv->user_pin_count++; obj_priv->pin_filp = file_priv; if (obj_priv->user_pin_count == 1) { - ret = i915_gem_object_pin(obj, args->alignment, - true, obj_priv->tiling_mode); + ret = i915_gem_object_pin(obj, args->alignment, true); if (ret) goto out; } @@ -4439,8 +4437,8 @@ struct drm_gem_object * i915_gem_alloc_object(struct drm_device *dev, INIT_LIST_HEAD(&obj->ring_list); INIT_LIST_HEAD(&obj->gpu_write_list); obj->madv = I915_MADV_WILLNEED; - obj->fenceable = true; - obj->mappable = true; + /* Avoid an unnecessary call to unbind on the first bind. */ + obj->map_and_fenceable = true; return &obj->base; } @@ -4560,7 +4558,7 @@ i915_gem_init_pipe_control(struct drm_device *dev) obj_priv = to_intel_bo(obj); obj_priv->agp_type = AGP_USER_CACHED_MEMORY; - ret = i915_gem_object_pin(obj, 4096, true, false); + ret = i915_gem_object_pin(obj, 4096, true); if (ret) goto err_unref; diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index a2cd579eb9b2..77b34942dc91 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -1461,8 +1461,7 @@ intel_pin_and_fence_fb_obj(struct drm_device *dev, BUG(); } - ret = i915_gem_object_pin(obj, alignment, true, - obj_priv->tiling_mode); + ret = i915_gem_object_pin(obj, alignment, true); if (ret) return ret; @@ -4367,7 +4366,7 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc, /* we only need to pin inside GTT if cursor is non-phy */ mutex_lock(&dev->struct_mutex); if (!dev_priv->info->cursor_needs_physical) { - ret = i915_gem_object_pin(bo, PAGE_SIZE, true, false); + ret = i915_gem_object_pin(bo, PAGE_SIZE, true); if (ret) { DRM_ERROR("failed to pin cursor bo\n"); goto fail_locked; @@ -5531,7 +5530,7 @@ intel_alloc_context_page(struct drm_device *dev) } mutex_lock(&dev->struct_mutex); - ret = i915_gem_object_pin(ctx, 4096, false, false); + ret = i915_gem_object_pin(ctx, 4096, true); if (ret) { DRM_ERROR("failed to pin power context: %d\n", ret); goto err_unref; diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c index 659f8349a15c..ec8ffaccbbdb 100644 --- a/drivers/gpu/drm/i915/intel_overlay.c +++ b/drivers/gpu/drm/i915/intel_overlay.c @@ -781,7 +781,7 @@ static int intel_overlay_do_put_image(struct intel_overlay *overlay, if (ret != 0) return ret; - ret = i915_gem_object_pin(new_bo, PAGE_SIZE, false, false); + ret = i915_gem_object_pin(new_bo, PAGE_SIZE, true); if (ret != 0) return ret; @@ -1425,7 +1425,7 @@ void intel_setup_overlay(struct drm_device *dev) } overlay->flip_addr = overlay->reg_bo->phys_obj->handle->busaddr; } else { - ret = i915_gem_object_pin(reg_bo, PAGE_SIZE, true, false); + ret = i915_gem_object_pin(reg_bo, PAGE_SIZE, true); if (ret) { DRM_ERROR("failed to pin overlay register bo\n"); goto out_free_bo; diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 85071570e1f9..78a5061a58f6 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -547,7 +547,7 @@ static int init_status_page(struct intel_ring_buffer *ring) obj_priv = to_intel_bo(obj); obj_priv->agp_type = AGP_USER_CACHED_MEMORY; - ret = i915_gem_object_pin(obj, 4096, true, false); + ret = i915_gem_object_pin(obj, 4096, true); if (ret != 0) { goto err_unref; } @@ -602,7 +602,7 @@ int intel_init_ring_buffer(struct drm_device *dev, ring->gem_object = obj; - ret = i915_gem_object_pin(obj, PAGE_SIZE, true, false); + ret = i915_gem_object_pin(obj, PAGE_SIZE, true); if (ret) goto err_unref; @@ -906,7 +906,7 @@ static int blt_ring_init(struct intel_ring_buffer *ring) if (obj == NULL) return -ENOMEM; - ret = i915_gem_object_pin(&obj->base, 4096, true, false); + ret = i915_gem_object_pin(&obj->base, 4096, true); if (ret) { drm_gem_object_unreference(&obj->base); return ret; -- cgit v1.2.3 From 98e2d5a802518694465368406c5f1b020f4df998 Mon Sep 17 00:00:00 2001 From: Ben Collins Date: Thu, 4 Nov 2010 22:37:15 -0400 Subject: solo6x10: Spaces to tabs Signed-off-by: Ben Collins --- drivers/staging/solo6x10/solo6010-enc.c | 4 ++-- drivers/staging/solo6x10/solo6010-g723.c | 14 +++++++------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/drivers/staging/solo6x10/solo6010-enc.c b/drivers/staging/solo6x10/solo6010-enc.c index a6cf0a8a3f20..42314a1e3250 100644 --- a/drivers/staging/solo6x10/solo6010-enc.c +++ b/drivers/staging/solo6x10/solo6010-enc.c @@ -145,8 +145,8 @@ int solo_osd_print(struct solo_enc_dev *solo_enc) solo_p2m_dma(solo_dev, 0, 1, buf, SOLO_EOSD_EXT_ADDR(solo_dev) + (solo_enc->ch * SOLO_EOSD_EXT_SIZE), SOLO_EOSD_EXT_SIZE); - reg |= (1 << solo_enc->ch); - solo_reg_write(solo_dev, SOLO_VE_OSD_CH, reg); + reg |= (1 << solo_enc->ch); + solo_reg_write(solo_dev, SOLO_VE_OSD_CH, reg); kfree(buf); diff --git a/drivers/staging/solo6x10/solo6010-g723.c b/drivers/staging/solo6x10/solo6010-g723.c index 82fbcb845878..63a1b5b64b56 100644 --- a/drivers/staging/solo6x10/solo6010-g723.c +++ b/drivers/staging/solo6x10/solo6010-g723.c @@ -158,7 +158,7 @@ static int snd_solo_pcm_close(struct snd_pcm_substream *ss) snd_pcm_substream_chip(ss) = solo_pcm->solo_dev; kfree(solo_pcm); - return 0; + return 0; } static int snd_solo_pcm_trigger(struct snd_pcm_substream *ss, int cmd) @@ -197,7 +197,7 @@ static int snd_solo_pcm_trigger(struct snd_pcm_substream *ss, int cmd) static int snd_solo_pcm_prepare(struct snd_pcm_substream *ss) { - return 0; + return 0; } static snd_pcm_uframes_t snd_solo_pcm_pointer(struct snd_pcm_substream *ss) @@ -271,7 +271,7 @@ static int snd_solo_capture_volume_get(struct snd_kcontrol *kcontrol, value->value.integer.value[0] = tw28_get_audio_gain(solo_dev, ch); - return 0; + return 0; } static int snd_solo_capture_volume_put(struct snd_kcontrol *kcontrol, @@ -279,15 +279,15 @@ static int snd_solo_capture_volume_put(struct snd_kcontrol *kcontrol, { struct solo6010_dev *solo_dev = snd_kcontrol_chip(kcontrol); u8 ch = value->id.numid - 1; - u8 old_val; + u8 old_val; - old_val = tw28_get_audio_gain(solo_dev, ch); + old_val = tw28_get_audio_gain(solo_dev, ch); if (old_val == value->value.integer.value[0]) return 0; tw28_set_audio_gain(solo_dev, ch, value->value.integer.value[0]); - return 1; + return 1; } static struct snd_kcontrol_new snd_solo_capture_volume = { @@ -368,7 +368,7 @@ int solo_g723_init(struct solo6010_dev *solo_dev) strcpy(card->mixername, "SOLO-6010"); kctl = snd_solo_capture_volume; kctl.count = solo_dev->nr_chans; - ret = snd_ctl_add(card, snd_ctl_new1(&kctl, solo_dev)); + ret = snd_ctl_add(card, snd_ctl_new1(&kctl, solo_dev)); if (ret < 0) return ret; -- cgit v1.2.3 From 1194cf4308d786c69b808ec3aa8704d01d130e94 Mon Sep 17 00:00:00 2001 From: Ben Collins Date: Thu, 4 Nov 2010 22:42:25 -0400 Subject: solo6x10: Update TODO Signed-off-by: Ben Collins --- drivers/staging/solo6x10/TODO | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/staging/solo6x10/TODO b/drivers/staging/solo6x10/TODO index e6a2ee226743..82439d38ba74 100644 --- a/drivers/staging/solo6x10/TODO +++ b/drivers/staging/solo6x10/TODO @@ -1,7 +1,5 @@ TODO (staging => main): - * checkpatch.pl (haven't run it yet) - * Lindent (should be clean, but check) * Motion detection flags need to be moved to v4l2 * Some private CIDs need to be moved to v4l2 @@ -17,12 +15,11 @@ TODO (general): * implement a CID control for motion areas/thresholds * implement CID controls for mozaic areas * allow for higher level of interval (for < 1 fps) + * Get proper descriptor mode working in p2m * sound: - implement playback via external sound jack - implement loopback of external sound jack with incoming audio? - implement pause/resume - - check into jacking sound from tx28xx chips directly (to avoid - g.723/8khz limitations) Plase send patches to Greg Kroah-Hartman and Cc Ben Collins -- cgit v1.2.3 From f62de9be26ce2144ad0dcf292727e4f58577d401 Mon Sep 17 00:00:00 2001 From: Ben Collins Date: Thu, 4 Nov 2010 22:51:17 -0400 Subject: solo6x10: Conversion to videobuf-dma-sg (from dma-cont) Full rewrite of the P2M DMA Engine to support scatter gather and take advantage of some of the features of the hardware. This includes using repeat DMA operations and line-mode transfers (for copying OSG and video display buffers). What isn't working: For some reason, descriptor mode is not working. I've implemented a psuedo version (still has one-interrupt per DMA operation), but we would get huge improvements if we could hand off a ring of descriptors to the P2M and get back one interrupt when it was done with all of them. Documentation is very vague on this, and even the ODM example code half attempts to get it right, but comments it out of the driver because it just doesn't work *sigh* Converts all v4l2 to dma-sg. So long slow dma-contiguous, but hello more interrupts :( Signed-off-by: Ben Collins --- drivers/staging/solo6x10/Kconfig | 2 +- drivers/staging/solo6x10/solo6010-core.c | 12 +- drivers/staging/solo6x10/solo6010-disp.c | 2 +- drivers/staging/solo6x10/solo6010-gpio.c | 4 +- drivers/staging/solo6x10/solo6010-i2c.c | 8 +- drivers/staging/solo6x10/solo6010-p2m.c | 148 +++++++++-- drivers/staging/solo6x10/solo6010-v4l2-enc.c | 352 +++++++++++++++++++-------- drivers/staging/solo6x10/solo6010-v4l2.c | 182 +++++++++++--- drivers/staging/solo6x10/solo6010.h | 38 ++- 9 files changed, 554 insertions(+), 194 deletions(-) diff --git a/drivers/staging/solo6x10/Kconfig b/drivers/staging/solo6x10/Kconfig index d96398c701f8..de60ac841b7e 100644 --- a/drivers/staging/solo6x10/Kconfig +++ b/drivers/staging/solo6x10/Kconfig @@ -1,7 +1,7 @@ config SOLO6X10 tristate "Softlogic 6x10 MPEG codec cards" depends on PCI && VIDEO_DEV && SND - select VIDEOBUF_DMA_CONTIG + select VIDEOBUF_DMA_SG ---help--- This driver supports the Softlogic based MPEG-4 and h.264 codec codec cards. diff --git a/drivers/staging/solo6x10/solo6010-core.c b/drivers/staging/solo6x10/solo6010-core.c index 4a051cde55da..9dad749ca963 100644 --- a/drivers/staging/solo6x10/solo6010-core.c +++ b/drivers/staging/solo6x10/solo6010-core.c @@ -136,6 +136,7 @@ static int __devinit solo6010_pci_probe(struct pci_dev *pdev, int ret; int sdram; u8 chip_id; + solo_dev = kzalloc(sizeof(*solo_dev), GFP_KERNEL); if (solo_dev == NULL) return -ENOMEM; @@ -261,13 +262,18 @@ static void __devexit solo6010_pci_remove(struct pci_dev *pdev) } static struct pci_device_id solo6010_id_table[] = { + /* 6010 based cards */ {PCI_DEVICE(PCI_VENDOR_ID_SOFTLOGIC, PCI_DEVICE_ID_SOLO6010)}, {PCI_DEVICE(PCI_VENDOR_ID_BLUECHERRY, PCI_DEVICE_ID_NEUSOLO_4)}, {PCI_DEVICE(PCI_VENDOR_ID_BLUECHERRY, PCI_DEVICE_ID_NEUSOLO_9)}, {PCI_DEVICE(PCI_VENDOR_ID_BLUECHERRY, PCI_DEVICE_ID_NEUSOLO_16)}, - {PCI_DEVICE(PCI_VENDOR_ID_BLUECHERRY, PCI_DEVICE_ID_COMMSOLO_4)}, - {PCI_DEVICE(PCI_VENDOR_ID_BLUECHERRY, PCI_DEVICE_ID_COMMSOLO_9)}, - {PCI_DEVICE(PCI_VENDOR_ID_BLUECHERRY, PCI_DEVICE_ID_COMMSOLO_16)}, + {PCI_DEVICE(PCI_VENDOR_ID_BLUECHERRY, PCI_DEVICE_ID_BC_SOLO_4)}, + {PCI_DEVICE(PCI_VENDOR_ID_BLUECHERRY, PCI_DEVICE_ID_BC_SOLO_9)}, + {PCI_DEVICE(PCI_VENDOR_ID_BLUECHERRY, PCI_DEVICE_ID_BC_SOLO_16)}, + /* 6110 based cards */ + {PCI_DEVICE(PCI_VENDOR_ID_BLUECHERRY, PCI_DEVICE_ID_BC_6110_4)}, + {PCI_DEVICE(PCI_VENDOR_ID_BLUECHERRY, PCI_DEVICE_ID_BC_6110_8)}, + {PCI_DEVICE(PCI_VENDOR_ID_BLUECHERRY, PCI_DEVICE_ID_BC_6110_16)}, {0,} }; diff --git a/drivers/staging/solo6x10/solo6010-disp.c b/drivers/staging/solo6x10/solo6010-disp.c index 555f024f72e7..a15151d15ea5 100644 --- a/drivers/staging/solo6x10/solo6010-disp.c +++ b/drivers/staging/solo6x10/solo6010-disp.c @@ -198,7 +198,7 @@ static void solo_motion_config(struct solo6010_dev *solo_dev) } /* Default motion settings */ - solo_reg_write(solo_dev, SOLO_VI_MOT_ADR, SOLO_VI_MOTION_EN(0) | + solo_reg_write(solo_dev, SOLO_VI_MOT_ADR, SOLO_VI_MOTION_EN(0) | (SOLO_MOTION_EXT_ADDR(solo_dev) >> 16)); solo_reg_write(solo_dev, SOLO_VI_MOT_CTRL, SOLO_VI_MOTION_FRAME_COUNT(3) | diff --git a/drivers/staging/solo6x10/solo6010-gpio.c b/drivers/staging/solo6x10/solo6010-gpio.c index 46f7a71edabc..8869b88dc307 100644 --- a/drivers/staging/solo6x10/solo6010-gpio.c +++ b/drivers/staging/solo6x10/solo6010-gpio.c @@ -92,8 +92,8 @@ static void solo_gpio_config(struct solo6010_dev *solo_dev) int solo_gpio_init(struct solo6010_dev *solo_dev) { - solo_gpio_config(solo_dev); - return 0; + solo_gpio_config(solo_dev); + return 0; } void solo_gpio_exit(struct solo6010_dev *solo_dev) diff --git a/drivers/staging/solo6x10/solo6010-i2c.c b/drivers/staging/solo6x10/solo6010-i2c.c index cadd5120d575..c1d4a23f4275 100644 --- a/drivers/staging/solo6x10/solo6010-i2c.c +++ b/drivers/staging/solo6x10/solo6010-i2c.c @@ -46,7 +46,7 @@ u8 solo_i2c_readbyte(struct solo6010_dev *solo_dev, int id, u8 addr, u8 off) i2c_transfer(&solo_dev->i2c_adap[id], msgs, 2); - return data; + return data; } void solo_i2c_writebyte(struct solo6010_dev *solo_dev, int id, u8 addr, @@ -227,7 +227,7 @@ static int solo_i2c_master_xfer(struct i2c_adapter *adap, if (i == SOLO_I2C_ADAPTERS) return num; // XXX Right return value for failure? - down(&solo_dev->i2c_sem); + mutex_lock(&solo_dev->i2c_mutex); solo_dev->i2c_id = i; solo_dev->i2c_msg = msgs; solo_dev->i2c_msg_num = num; @@ -258,7 +258,7 @@ static int solo_i2c_master_xfer(struct i2c_adapter *adap, solo_dev->i2c_state = IIC_STATE_IDLE; solo_dev->i2c_id = -1; - up(&solo_dev->i2c_sem); + mutex_unlock(&solo_dev->i2c_mutex); return ret; } @@ -284,7 +284,7 @@ int solo_i2c_init(struct solo6010_dev *solo_dev) solo_dev->i2c_id = -1; solo_dev->i2c_state = IIC_STATE_IDLE; init_waitqueue_head(&solo_dev->i2c_wait); - sema_init(&solo_dev->i2c_sem, 1); + mutex_init(&solo_dev->i2c_mutex); for (i = 0; i < SOLO_I2C_ADAPTERS; i++) { struct i2c_adapter *adap = &solo_dev->i2c_adap[i]; diff --git a/drivers/staging/solo6x10/solo6010-p2m.c b/drivers/staging/solo6x10/solo6010-p2m.c index 7ed3ed4b8f7e..a46ebf2f376a 100644 --- a/drivers/staging/solo6x10/solo6010-p2m.c +++ b/drivers/staging/solo6x10/solo6010-p2m.c @@ -18,6 +18,7 @@ */ #include +#include #include "solo6010.h" @@ -30,8 +31,9 @@ int solo_p2m_dma(struct solo6010_dev *solo_dev, u8 id, int wr, int ret; WARN_ON(!size); - WARN_ON(id >= SOLO_NR_P2M); - if (!size || id >= SOLO_NR_P2M) + BUG_ON(id >= SOLO_NR_P2M); + + if (!size) return -EINVAL; dma_addr = pci_map_single(solo_dev->pdev, sys_addr, size, @@ -47,42 +49,118 @@ int solo_p2m_dma(struct solo6010_dev *solo_dev, u8 id, int wr, int solo_p2m_dma_t(struct solo6010_dev *solo_dev, u8 id, int wr, dma_addr_t dma_addr, u32 ext_addr, u32 size) +{ + struct p2m_desc desc; + + solo_p2m_push_desc(&desc, wr, dma_addr, ext_addr, size, 0, 0); + + return solo_p2m_dma_desc(solo_dev, id, &desc, 1); +} + +void solo_p2m_push_desc(struct p2m_desc *desc, int wr, dma_addr_t dma_addr, + u32 ext_addr, u32 size, int repeat, u32 ext_size) +{ + desc->ta = dma_addr; + desc->fa = ext_addr; + + desc->ext = SOLO_P2M_COPY_SIZE(size >> 2); + desc->ctrl = SOLO_P2M_BURST_SIZE(SOLO_P2M_BURST_256) | + (wr ? SOLO_P2M_WRITE : 0) | SOLO_P2M_TRANS_ON; + + /* Ext size only matters when we're repeating */ + if (repeat) { + desc->ext |= SOLO_P2M_EXT_INC(ext_size >> 2); + desc->ctrl |= SOLO_P2M_PCI_INC(size >> 2) | + SOLO_P2M_REPEAT(repeat); + } +} + +int solo_p2m_dma_desc(struct solo6010_dev *solo_dev, u8 id, + struct p2m_desc *desc, int desc_count) { struct solo_p2m_dev *p2m_dev; - unsigned int timeout = 0; + unsigned int timeout; + int ret = 0; - WARN_ON(!size); - WARN_ON(id >= SOLO_NR_P2M); - if (!size || id >= SOLO_NR_P2M) - return -EINVAL; + BUG_ON(id >= SOLO_NR_P2M); + BUG_ON(desc_count > SOLO_NR_P2M_DESC); p2m_dev = &solo_dev->p2m_dev[id]; - down(&p2m_dev->sem); + mutex_lock(&p2m_dev->mutex); -start_dma: INIT_COMPLETION(p2m_dev->completion); p2m_dev->error = 0; - solo_reg_write(solo_dev, SOLO_P2M_TAR_ADR(id), dma_addr); - solo_reg_write(solo_dev, SOLO_P2M_EXT_ADR(id), ext_addr); - solo_reg_write(solo_dev, SOLO_P2M_EXT_CFG(id), - SOLO_P2M_COPY_SIZE(size >> 2)); - solo_reg_write(solo_dev, SOLO_P2M_CONTROL(id), - SOLO_P2M_BURST_SIZE(SOLO_P2M_BURST_256) | - (wr ? SOLO_P2M_WRITE : 0) | SOLO_P2M_TRANS_ON); + /* Setup the descriptor count and base address */ + p2m_dev->num_descs = desc_count; + p2m_dev->descs = desc; + p2m_dev->desc_idx = 0; + + /* We plug in the first descriptor here. The isr will take + * over from desc[1] after this. */ + solo_reg_write(solo_dev, SOLO_P2M_TAR_ADR(id), desc[0].ta); + solo_reg_write(solo_dev, SOLO_P2M_EXT_ADR(id), desc[0].fa); + solo_reg_write(solo_dev, SOLO_P2M_EXT_CFG(id), desc[0].ext); + solo_reg_write(solo_dev, SOLO_P2M_CONTROL(id), desc[0].ctrl); + + /* Should have all descriptors completed from one interrupt */ timeout = wait_for_completion_timeout(&p2m_dev->completion, HZ); solo_reg_write(solo_dev, SOLO_P2M_CONTROL(id), 0); - /* XXX Really looks to me like we will get stuck here if a - * real PCI P2M error occurs */ if (p2m_dev->error) - goto start_dma; + ret = -EIO; + else if (timeout == 0) + ret = -EAGAIN; - up(&p2m_dev->sem); + mutex_unlock(&p2m_dev->mutex); - return (timeout == 0) ? -EAGAIN : 0; + WARN_ON_ONCE(ret); + + return ret; +} + +int solo_p2m_dma_sg(struct solo6010_dev *solo_dev, u8 id, + struct p2m_desc *pdesc, int wr, + struct scatterlist *sg, u32 sg_off, + u32 ext_addr, u32 size) +{ + int i; + int idx; + + BUG_ON(id >= SOLO_NR_P2M); + + if (WARN_ON_ONCE(!size)) + return -EINVAL; + + for (i = idx = 0; i < SOLO_NR_P2M_DESC && sg && size > 0; + i++, sg = sg_next(sg)) { + struct p2m_desc *desc = &pdesc[i]; + u32 sg_len = sg_dma_len(sg); + u32 len; + + if (sg_off >= sg_len) { + sg_off -= sg_len; + continue; + } + + sg_len -= sg_off; + len = min(sg_len, size); + + solo_p2m_push_desc(desc, wr, sg_dma_address(sg) + sg_off, + ext_addr, len, 0, 0); + + size -= len; + ext_addr += len; + idx++; + + sg_off = 0; + } + + WARN_ON_ONCE(size || i >= SOLO_NR_P2M_DESC); + + return solo_p2m_dma_desc(solo_dev, id, pdesc, idx); } #ifdef SOLO_TEST_P2M @@ -152,8 +230,27 @@ static void run_p2m_test(struct solo6010_dev *solo_dev) void solo_p2m_isr(struct solo6010_dev *solo_dev, int id) { + struct solo_p2m_dev *p2m_dev = &solo_dev->p2m_dev[id]; + struct p2m_desc *desc; + solo_reg_write(solo_dev, SOLO_IRQ_STAT, SOLO_IRQ_P2M(id)); - complete(&solo_dev->p2m_dev[id].completion); + + p2m_dev->desc_idx++; + + if (p2m_dev->desc_idx >= p2m_dev->num_descs) { + complete(&p2m_dev->completion); + return; + } + + /* Reset the p2m and start the next one */ + solo_reg_write(solo_dev, SOLO_P2M_CONTROL(id), 0); + + desc = &p2m_dev->descs[p2m_dev->desc_idx]; + + solo_reg_write(solo_dev, SOLO_P2M_TAR_ADR(id), desc->ta); + solo_reg_write(solo_dev, SOLO_P2M_EXT_ADR(id), desc->fa); + solo_reg_write(solo_dev, SOLO_P2M_EXT_CFG(id), desc->ext); + solo_reg_write(solo_dev, SOLO_P2M_CONTROL(id), desc->ctrl); } void solo_p2m_error_isr(struct solo6010_dev *solo_dev, u32 status) @@ -188,16 +285,13 @@ int solo_p2m_init(struct solo6010_dev *solo_dev) for (i = 0; i < SOLO_NR_P2M; i++) { p2m_dev = &solo_dev->p2m_dev[i]; - sema_init(&p2m_dev->sem, 1); + mutex_init(&p2m_dev->mutex); init_completion(&p2m_dev->completion); - solo_reg_write(solo_dev, SOLO_P2M_DES_ADR(i), - __pa(p2m_dev->desc)); - solo_reg_write(solo_dev, SOLO_P2M_CONTROL(i), 0); solo_reg_write(solo_dev, SOLO_P2M_CONFIG(i), SOLO_P2M_CSC_16BIT_565 | - SOLO_P2M_DMA_INTERVAL(0) | + SOLO_P2M_DMA_INTERVAL(3) | SOLO_P2M_PCI_MASTER_MODE); solo6010_irq_on(solo_dev, SOLO_IRQ_P2M(i)); } diff --git a/drivers/staging/solo6x10/solo6010-v4l2-enc.c b/drivers/staging/solo6x10/solo6010-v4l2-enc.c index bbf3d9c4abb0..736fad6dc1fb 100644 --- a/drivers/staging/solo6x10/solo6010-v4l2-enc.c +++ b/drivers/staging/solo6x10/solo6010-v4l2-enc.c @@ -24,7 +24,7 @@ #include #include -#include +#include #include "solo6010.h" #include "solo6010-tw28.h" @@ -47,13 +47,14 @@ struct solo_enc_fh { struct videobuf_queue vidq; struct list_head vidq_active; struct task_struct *kthread; + struct p2m_desc desc[SOLO_NR_P2M_DESC]; }; static unsigned char vid_vop_header[] = { 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x20, 0x02, 0x48, 0x05, 0xc0, 0x00, 0x40, 0x00, 0x40, 0x00, 0x40, 0x00, 0x80, 0x00, 0x97, 0x53, 0x04, - 0x1f, 0x4c, 0x58, 0x10, 0x78, 0x51, 0x18, 0x3e, + 0x1f, 0x4c, 0x58, 0x10, 0x78, 0x51, 0x18, 0x3f, }; /* @@ -151,6 +152,11 @@ static void solo_motion_toggle(struct solo_enc_dev *solo_enc, int on) else solo_dev->motion_mask &= ~(1 << ch); + /* Do this regardless of if we are turning on or off */ + solo_reg_write(solo_enc->solo_dev, SOLO_VI_MOT_CLEAR, + 1 << solo_enc->ch); + solo_enc->motion_detected = 0; + solo_reg_write(solo_dev, SOLO_VI_MOT_ADR, SOLO_VI_MOTION_EN(solo_dev->motion_mask) | (SOLO_MOTION_EXT_ADDR(solo_dev) >> 16)); @@ -184,7 +190,7 @@ static void solo_update_mode(struct solo_enc_dev *solo_enc) solo_enc->bw_weight <<= 2; break; default: - WARN(1, "mode is unknown"); + WARN(1, "mode is unknown\n"); } } @@ -211,11 +217,6 @@ static int solo_enc_on(struct solo_enc_fh *fh) solo_dev->enc_bw_remain -= solo_enc->bw_weight; } - fh->kthread = kthread_run(solo_enc_thread, fh, SOLO6010_NAME "_enc"); - - if (IS_ERR(fh->kthread)) - return PTR_ERR(fh->kthread); - fh->enc_on = 1; fh->rd_idx = solo_enc->solo_dev->enc_wr_idx; @@ -279,6 +280,24 @@ static void solo_enc_off(struct solo_enc_fh *fh) solo_reg_write(solo_dev, SOLO_CAP_CH_COMP_ENA_E(solo_enc->ch), 0); } +static int solo_start_fh_thread(struct solo_enc_fh *fh) +{ + struct solo_enc_dev *solo_enc = fh->enc; + + fh->kthread = kthread_run(solo_enc_thread, fh, SOLO6010_NAME "_enc"); + + /* Oops, we had a problem */ + if (IS_ERR(fh->kthread)) { + spin_lock(&solo_enc->lock); + solo_enc_off(fh); + spin_unlock(&solo_enc->lock); + + return PTR_ERR(fh->kthread); + } + + return 0; +} + static void enc_reset_gop(struct solo6010_dev *solo_dev, u8 ch) { BUG_ON(ch >= solo_dev->nr_chans); @@ -299,22 +318,68 @@ static int enc_gop_reset(struct solo6010_dev *solo_dev, u8 ch, u8 vop) return 0; } -static int enc_get_mpeg_dma_t(struct solo6010_dev *solo_dev, dma_addr_t buf, - unsigned int off, unsigned int size) +static void enc_write_sg(struct scatterlist *sglist, void *buf, int size) +{ + struct scatterlist *sg; + u8 *src = buf; + + for (sg = sglist; sg && size > 0; sg = sg_next(sg)) { + u8 *p = sg_virt(sg); + size_t len = sg_dma_len(sg); + int i; + + for (i = 0; i < len && size; i++) + p[i] = *(src++); + } +} + +static int enc_get_mpeg_dma_sg(struct solo6010_dev *solo_dev, + struct p2m_desc *desc, + struct scatterlist *sglist, int skip, + unsigned int off, unsigned int size) +{ + int ret; + + if (off > SOLO_MP4E_EXT_SIZE(solo_dev)) + return -EINVAL; + + if (off + size <= SOLO_MP4E_EXT_SIZE(solo_dev)) { + return solo_p2m_dma_sg(solo_dev, SOLO_P2M_DMA_ID_MP4E, + desc, 0, sglist, skip, + SOLO_MP4E_EXT_ADDR(solo_dev) + off, size); + } + + /* Buffer wrap */ + ret = solo_p2m_dma_sg(solo_dev, SOLO_P2M_DMA_ID_MP4E, desc, 0, + sglist, skip, SOLO_MP4E_EXT_ADDR(solo_dev) + off, + SOLO_MP4E_EXT_SIZE(solo_dev) - off); + + ret |= solo_p2m_dma_sg(solo_dev, SOLO_P2M_DMA_ID_MP4E, desc, 0, + sglist, skip + SOLO_MP4E_EXT_SIZE(solo_dev) - off, + SOLO_MP4E_EXT_ADDR(solo_dev), + size + off - SOLO_MP4E_EXT_SIZE(solo_dev)); + + return ret; +} + +static int enc_get_mpeg_dma_t(struct solo6010_dev *solo_dev, + dma_addr_t buf, unsigned int off, + unsigned int size) { int ret; if (off > SOLO_MP4E_EXT_SIZE(solo_dev)) return -EINVAL; - if (off + size <= SOLO_MP4E_EXT_SIZE(solo_dev)) + if (off + size <= SOLO_MP4E_EXT_SIZE(solo_dev)) { return solo_p2m_dma_t(solo_dev, SOLO_P2M_DMA_ID_MP4E, 0, buf, SOLO_MP4E_EXT_ADDR(solo_dev) + off, size); + } /* Buffer wrap */ ret = solo_p2m_dma_t(solo_dev, SOLO_P2M_DMA_ID_MP4E, 0, buf, - SOLO_MP4E_EXT_ADDR(solo_dev) + off, - SOLO_MP4E_EXT_SIZE(solo_dev) - off); + SOLO_MP4E_EXT_ADDR(solo_dev) + off, + SOLO_MP4E_EXT_SIZE(solo_dev) - off); ret |= solo_p2m_dma_t(solo_dev, SOLO_P2M_DMA_ID_MP4E, 0, buf + SOLO_MP4E_EXT_SIZE(solo_dev) - off, @@ -337,70 +402,108 @@ static int enc_get_mpeg_dma(struct solo6010_dev *solo_dev, void *buf, return ret; } -static int enc_get_jpeg_dma(struct solo6010_dev *solo_dev, dma_addr_t buf, - unsigned int off, unsigned int size) +static int enc_get_jpeg_dma_sg(struct solo6010_dev *solo_dev, + struct p2m_desc *desc, + struct scatterlist *sglist, int skip, + unsigned int off, unsigned int size) { int ret; if (off > SOLO_JPEG_EXT_SIZE(solo_dev)) return -EINVAL; - if (off + size <= SOLO_JPEG_EXT_SIZE(solo_dev)) - return solo_p2m_dma_t(solo_dev, SOLO_P2M_DMA_ID_JPEG, 0, buf, - SOLO_JPEG_EXT_ADDR(solo_dev) + off, size); + if (off + size <= SOLO_JPEG_EXT_SIZE(solo_dev)) { + return solo_p2m_dma_sg(solo_dev, SOLO_P2M_DMA_ID_JPEG, + desc, 0, sglist, skip, + SOLO_JPEG_EXT_ADDR(solo_dev) + off, size); + } /* Buffer wrap */ - ret = solo_p2m_dma_t(solo_dev, SOLO_P2M_DMA_ID_JPEG, 0, buf, - SOLO_JPEG_EXT_ADDR(solo_dev) + off, - SOLO_JPEG_EXT_SIZE(solo_dev) - off); + ret = solo_p2m_dma_sg(solo_dev, SOLO_P2M_DMA_ID_JPEG, desc, 0, + sglist, skip, SOLO_JPEG_EXT_ADDR(solo_dev) + off, + SOLO_JPEG_EXT_SIZE(solo_dev) - off); - ret |= solo_p2m_dma_t(solo_dev, SOLO_P2M_DMA_ID_JPEG, 0, - buf + SOLO_JPEG_EXT_SIZE(solo_dev) - off, - SOLO_JPEG_EXT_ADDR(solo_dev), - size + off - SOLO_JPEG_EXT_SIZE(solo_dev)); + ret |= solo_p2m_dma_sg(solo_dev, SOLO_P2M_DMA_ID_JPEG, desc, 0, + sglist, skip + SOLO_JPEG_EXT_SIZE(solo_dev) - off, + SOLO_JPEG_EXT_ADDR(solo_dev), + size + off - SOLO_JPEG_EXT_SIZE(solo_dev)); return ret; } +/* Returns true of __chk is within the first __range bytes of __off */ +#define OFF_IN_RANGE(__off, __range, __chk) \ + ((__off <= __chk) && ((__off + __range) >= __chk)) + +static void solo_jpeg_header(struct solo_enc_dev *solo_enc, + struct videobuf_dmabuf *vbuf) +{ + struct scatterlist *sg; + void *src = jpeg_header; + size_t copied = 0; + size_t to_copy = sizeof(jpeg_header); + + for (sg = vbuf->sglist; sg && copied < to_copy; sg = sg_next(sg)) { + size_t this_copy = min(sg_dma_len(sg), + (unsigned int)(to_copy - copied)); + u8 *p = sg_virt(sg); + + memcpy(p, src + copied, this_copy); + + if (OFF_IN_RANGE(copied, this_copy, SOF0_START + 5)) + p[(SOF0_START + 5) - copied] = + 0xff & (solo_enc->height >> 8); + if (OFF_IN_RANGE(copied, this_copy, SOF0_START + 6)) + p[(SOF0_START + 6) - copied] = 0xff & solo_enc->height; + if (OFF_IN_RANGE(copied, this_copy, SOF0_START + 7)) + p[(SOF0_START + 7) - copied] = + 0xff & (solo_enc->width >> 8); + if (OFF_IN_RANGE(copied, this_copy, SOF0_START + 8)) + p[(SOF0_START + 8) - copied] = 0xff & solo_enc->width; + + copied += this_copy; + } +} + static int solo_fill_jpeg(struct solo_enc_fh *fh, struct solo_enc_buf *enc_buf, - struct videobuf_buffer *vb, dma_addr_t vbuf) + struct videobuf_buffer *vb, + struct videobuf_dmabuf *vbuf) { - struct solo_enc_dev *solo_enc = fh->enc; - struct solo6010_dev *solo_dev = solo_enc->solo_dev; - u8 *p = videobuf_queue_to_vaddr(&fh->vidq, vb); + struct solo6010_dev *solo_dev = fh->enc->solo_dev; + int size = enc_buf->jpeg_size; - memcpy(p, jpeg_header, sizeof(jpeg_header)); - p[SOF0_START + 5] = 0xff & (solo_enc->height >> 8); - p[SOF0_START + 6] = 0xff & solo_enc->height; - p[SOF0_START + 7] = 0xff & (solo_enc->width >> 8); - p[SOF0_START + 8] = 0xff & solo_enc->width; + /* Copy the header first (direct write) */ + solo_jpeg_header(fh->enc, vbuf); - vbuf += sizeof(jpeg_header); - vb->size = enc_buf->jpeg_size + sizeof(jpeg_header); + vb->size = size + sizeof(jpeg_header); - return enc_get_jpeg_dma(solo_dev, vbuf, enc_buf->jpeg_off, - enc_buf->jpeg_size); + /* Grab the jpeg frame */ + return enc_get_jpeg_dma_sg(solo_dev, fh->desc, vbuf->sglist, + sizeof(jpeg_header), + enc_buf->jpeg_off, size); } static int solo_fill_mpeg(struct solo_enc_fh *fh, struct solo_enc_buf *enc_buf, - struct videobuf_buffer *vb, dma_addr_t vbuf) + struct videobuf_buffer *vb, + struct videobuf_dmabuf *vbuf) { struct solo_enc_dev *solo_enc = fh->enc; struct solo6010_dev *solo_dev = solo_enc->solo_dev; struct vop_header vh; int ret; int frame_size, frame_off; + int skip = 0; if (WARN_ON_ONCE(enc_buf->size <= sizeof(vh))) - return -1; + return -EINVAL; /* First get the hardware vop header (not real mpeg) */ ret = enc_get_mpeg_dma(solo_dev, &vh, enc_buf->off, sizeof(vh)); - if (ret) - return -1; + if (WARN_ON_ONCE(ret)) + return ret; if (WARN_ON_ONCE(vh.size > enc_buf->size)) - return -1; + return -EINVAL; vb->width = vh.hsize << 4; vb->height = vh.vsize << 4; @@ -410,9 +513,9 @@ static int solo_fill_mpeg(struct solo_enc_fh *fh, struct solo_enc_buf *enc_buf, if (!enc_buf->vop) { u16 fps = solo_dev->fps * 1000; u16 interval = solo_enc->interval * 1000; - u8 *p = videobuf_queue_to_vaddr(&fh->vidq, vb); + u8 p[sizeof(vid_vop_header)]; - memcpy(p, vid_vop_header, sizeof(vid_vop_header)); + memcpy(p, vid_vop_header, sizeof(p)); if (solo_dev->video_type == SOLO_VO_FMT_TYPE_NTSC) p[10] |= ((XVID_PAR_43_NTSC << 3) & 0x78); @@ -434,43 +537,49 @@ static int solo_fill_mpeg(struct solo_enc_fh *fh, struct solo_enc_buf *enc_buf, if (vh.interlace) p[29] |= 0x20; + enc_write_sg(vbuf->sglist, p, sizeof(p)); + /* Adjust the dma buffer past this header */ vb->size += sizeof(vid_vop_header); - vbuf += sizeof(vid_vop_header); + skip = sizeof(vid_vop_header); } /* Now get the actual mpeg payload */ frame_off = (enc_buf->off + sizeof(vh)) % SOLO_MP4E_EXT_SIZE(solo_dev); frame_size = enc_buf->size - sizeof(vh); - ret = enc_get_mpeg_dma_t(solo_dev, vbuf, frame_off, frame_size); - if (WARN_ON_ONCE(ret)) - return -1; - return 0; + ret = enc_get_mpeg_dma_sg(solo_dev, fh->desc, vbuf->sglist, + skip, frame_off, frame_size); + WARN_ON_ONCE(ret); + + return ret; } -/* On successful return (0), leaves solo_enc->lock unlocked */ -static int solo_enc_fillbuf(struct solo_enc_fh *fh, +static void solo_enc_fillbuf(struct solo_enc_fh *fh, struct videobuf_buffer *vb) { struct solo_enc_dev *solo_enc = fh->enc; struct solo6010_dev *solo_dev = solo_enc->solo_dev; struct solo_enc_buf *enc_buf = NULL; - dma_addr_t vbuf; + struct videobuf_dmabuf *vbuf; int ret; + int error = 1; u16 idx = fh->rd_idx; while (idx != solo_dev->enc_wr_idx) { struct solo_enc_buf *ebuf = &solo_dev->enc_buf[idx]; + idx = (idx + 1) % SOLO_NR_RING_BUFS; + + if (ebuf->ch != solo_enc->ch) + continue; + if (fh->fmt == V4L2_PIX_FMT_MPEG) { - if (fh->type != ebuf->type) - continue; - if (ebuf->ch == solo_enc->ch) { + if (fh->type == ebuf->type) { enc_buf = ebuf; break; } - } else if (ebuf->ch == solo_enc->ch) { + } else { /* For mjpeg, keep reading to the newest frame */ enc_buf = ebuf; } @@ -478,48 +587,54 @@ static int solo_enc_fillbuf(struct solo_enc_fh *fh, fh->rd_idx = idx; - if (!enc_buf) - return -1; + if (WARN_ON_ONCE(!enc_buf)) + goto buf_err; if ((fh->fmt == V4L2_PIX_FMT_MPEG && vb->bsize < enc_buf->size) || (fh->fmt == V4L2_PIX_FMT_MJPEG && vb->bsize < (enc_buf->jpeg_size + sizeof(jpeg_header)))) { - return -1; + WARN_ON_ONCE(1); + goto buf_err; } - if (!(vbuf = videobuf_to_dma_contig(vb))) - return -1; - - /* Is it ok that we mess with this buffer out of lock? */ - spin_unlock(&solo_enc->lock); + if (WARN_ON_ONCE(!(vbuf = videobuf_to_dma(vb)))) + goto buf_err; if (fh->fmt == V4L2_PIX_FMT_MPEG) ret = solo_fill_mpeg(fh, enc_buf, vb, vbuf); else ret = solo_fill_jpeg(fh, enc_buf, vb, vbuf); - if (ret) // Ignore failures - return 0; + if (!ret) + error = 0; - list_del(&vb->queue); - vb->field_count++; - vb->ts = enc_buf->ts; - vb->state = VIDEOBUF_DONE; +buf_err: + if (error) { + vb->state = VIDEOBUF_ERROR; + } else { + vb->field_count++; + vb->ts = enc_buf->ts; + vb->state = VIDEOBUF_DONE; + } wake_up(&vb->done); - return 0; + return; } static void solo_enc_thread_try(struct solo_enc_fh *fh) { struct solo_enc_dev *solo_enc = fh->enc; + struct solo6010_dev *solo_dev = solo_enc->solo_dev; struct videobuf_buffer *vb; for (;;) { spin_lock(&solo_enc->lock); + if (fh->rd_idx == solo_dev->enc_wr_idx) + break; + if (list_empty(&fh->vidq_active)) break; @@ -529,9 +644,11 @@ static void solo_enc_thread_try(struct solo_enc_fh *fh) if (!waitqueue_active(&vb->done)) break; - /* On success, returns with solo_enc->lock unlocked */ - if (solo_enc_fillbuf(fh, vb)) - break; + list_del(&vb->queue); + + spin_unlock(&solo_enc->lock); + + solo_enc_fillbuf(fh, vb); } assert_spin_locked(&solo_enc->lock); @@ -557,7 +674,7 @@ static int solo_enc_thread(void *data) remove_wait_queue(&solo_enc->thread_wait, &wait); - return 0; + return 0; } void solo_motion_isr(struct solo6010_dev *solo_dev) @@ -669,12 +786,12 @@ void solo_enc_v4l2_isr(struct solo6010_dev *solo_dev) static int solo_enc_buf_setup(struct videobuf_queue *vq, unsigned int *count, unsigned int *size) { - *size = FRAME_BUF_SIZE; + *size = FRAME_BUF_SIZE; - if (*count < MIN_VID_BUFFERS) + if (*count < MIN_VID_BUFFERS) *count = MIN_VID_BUFFERS; - return 0; + return 0; } static int solo_enc_buf_prepare(struct videobuf_queue *vq, @@ -696,7 +813,9 @@ static int solo_enc_buf_prepare(struct videobuf_queue *vq, if (vb->state == VIDEOBUF_NEEDS_INIT) { int rc = videobuf_iolock(vq, vb, NULL); if (rc < 0) { - videobuf_dma_contig_free(vq, vb); + struct videobuf_dmabuf *dma = videobuf_to_dma(vb); + videobuf_dma_unmap(vq, dma); + videobuf_dma_free(dma); vb->state = VIDEOBUF_NEEDS_INIT; return rc; } @@ -719,7 +838,10 @@ static void solo_enc_buf_queue(struct videobuf_queue *vq, static void solo_enc_buf_release(struct videobuf_queue *vq, struct videobuf_buffer *vb) { - videobuf_dma_contig_free(vq, vb); + struct videobuf_dmabuf *dma = videobuf_to_dma(vb); + + videobuf_dma_unmap(vq, dma); + videobuf_dma_free(dma); vb->state = VIDEOBUF_NEEDS_INIT; } @@ -753,22 +875,18 @@ static int solo_enc_open(struct file *file) if ((fh = kzalloc(sizeof(*fh), GFP_KERNEL)) == NULL) return -ENOMEM; - spin_lock(&solo_enc->lock); - fh->enc = solo_enc; file->private_data = fh; INIT_LIST_HEAD(&fh->vidq_active); fh->fmt = V4L2_PIX_FMT_MPEG; fh->type = SOLO_ENC_TYPE_STD; - videobuf_queue_dma_contig_init(&fh->vidq, &solo_enc_video_qops, - &solo_enc->solo_dev->pdev->dev, - &solo_enc->lock, - V4L2_BUF_TYPE_VIDEO_CAPTURE, - V4L2_FIELD_INTERLACED, - sizeof(struct videobuf_buffer), fh); - - spin_unlock(&solo_enc->lock); + videobuf_queue_sg_init(&fh->vidq, &solo_enc_video_qops, + &solo_enc->solo_dev->pdev->dev, + &solo_enc->lock, + V4L2_BUF_TYPE_VIDEO_CAPTURE, + V4L2_FIELD_INTERLACED, + sizeof(struct videobuf_buffer), fh); return 0; } @@ -785,7 +903,11 @@ static ssize_t solo_enc_read(struct file *file, char __user *data, spin_lock(&solo_enc->lock); ret = solo_enc_on(fh); - spin_unlock(&solo_enc->lock); + spin_unlock(&solo_enc->lock); + if (ret) + return ret; + + ret = solo_start_fh_thread(fh); if (ret) return ret; } @@ -797,10 +919,15 @@ static ssize_t solo_enc_read(struct file *file, char __user *data, static int solo_enc_release(struct file *file) { struct solo_enc_fh *fh = file->private_data; + struct solo_enc_dev *solo_enc = fh->enc; videobuf_stop(&fh->vidq); videobuf_mmap_free(&fh->vidq); + + spin_lock(&solo_enc->lock); solo_enc_off(fh); + spin_unlock(&solo_enc->lock); + kfree(fh); return 0; @@ -842,7 +969,7 @@ static int solo_enc_enum_input(struct file *file, void *priv, if (solo_dev->video_type == SOLO_VO_FMT_TYPE_NTSC) input->std = V4L2_STD_NTSC_M; else - input->std = V4L2_STD_PAL_M; + input->std = V4L2_STD_PAL_B; if (!tw28_get_video_status(solo_dev, solo_enc->ch)) input->status = V4L2_IN_ST_NO_SIGNAL; @@ -956,7 +1083,10 @@ static int solo_enc_set_fmt_cap(struct file *file, void *priv, spin_unlock(&solo_enc->lock); - return ret; + if (ret) + return ret; + + return solo_start_fh_thread(fh); } static int solo_enc_get_fmt_cap(struct file *file, void *priv, @@ -1014,6 +1144,10 @@ static int solo_enc_dqbuf(struct file *file, void *priv, spin_unlock(&solo_enc->lock); if (ret) return ret; + + ret = solo_start_fh_thread(fh); + if (ret) + return ret; } ret = videobuf_dqbuf(&fh->vidq, buf, file->f_flags & O_NONBLOCK); @@ -1033,12 +1167,16 @@ static int solo_enc_dqbuf(struct file *file, void *priv, /* Check for key frame on mpeg data */ if (fh->fmt == V4L2_PIX_FMT_MPEG) { - struct videobuf_buffer *vb = fh->vidq.bufs[buf->index]; - u8 *p = videobuf_queue_to_vaddr(&fh->vidq, vb); - if (p[3] == 0x00) - buf->flags |= V4L2_BUF_FLAG_KEYFRAME; - else - buf->flags |= V4L2_BUF_FLAG_PFRAME; + struct videobuf_dmabuf *vbuf = + videobuf_to_dma(fh->vidq.bufs[buf->index]); + + if (vbuf) { + u8 *p = sg_virt(vbuf->sglist); + if (p[3] == 0x00) + buf->flags |= V4L2_BUF_FLAG_KEYFRAME; + else + buf->flags |= V4L2_BUF_FLAG_PFRAME; + } } return 0; @@ -1136,7 +1274,7 @@ static int solo_g_parm(struct file *file, void *priv, /* XXX: Shouldn't we be able to get/set this from videobuf? */ cp->readbuffers = 2; - return 0; + return 0; } static int solo_s_parm(struct file *file, void *priv, @@ -1176,7 +1314,7 @@ static int solo_s_parm(struct file *file, void *priv, spin_unlock(&solo_enc->lock); - return 0; + return 0; } static int solo_queryctrl(struct file *file, void *priv, @@ -1240,7 +1378,7 @@ static int solo_queryctrl(struct file *file, void *priv, return 0; } - return -EINVAL; + return -EINVAL; } static int solo_querymenu(struct file *file, void *priv, @@ -1350,9 +1488,9 @@ static int solo_s_ext_ctrls(struct file *file, void *priv, switch (ctrl->id) { case V4L2_CID_RDS_TX_RADIO_TEXT: if (ctrl->size - 1 > OSD_TEXT_MAX) - err = -ERANGE; + err = -ERANGE; else { - err = copy_from_user(solo_enc->osd_text, + err = copy_from_user(solo_enc->osd_text, ctrl->string, OSD_TEXT_MAX); solo_enc->osd_text[OSD_TEXT_MAX] = '\0'; @@ -1459,7 +1597,7 @@ static struct video_device solo_enc_template = { .minor = -1, .release = video_device_release, - .tvnorms = V4L2_STD_NTSC_M | V4L2_STD_PAL_M, + .tvnorms = V4L2_STD_NTSC_M | V4L2_STD_PAL_B, .current_norm = V4L2_STD_NTSC_M, }; @@ -1505,7 +1643,7 @@ static struct solo_enc_dev *solo_enc_alloc(struct solo6010_dev *solo_dev, u8 ch) atomic_set(&solo_enc->readers, 0); solo_enc->qp = SOLO_DEFAULT_QP; - solo_enc->gop = solo_dev->fps; + solo_enc->gop = solo_dev->fps; solo_enc->interval = 1; solo_enc->mode = SOLO_ENC_MODE_CIF; solo_enc->motion_thresh = SOLO_DEF_MOT_THRESH; diff --git a/drivers/staging/solo6x10/solo6010-v4l2.c b/drivers/staging/solo6x10/solo6010-v4l2.c index 9731fa02b5e8..4cf7257e1eb0 100644 --- a/drivers/staging/solo6x10/solo6010-v4l2.c +++ b/drivers/staging/solo6x10/solo6010-v4l2.c @@ -24,14 +24,13 @@ #include #include -#include +#include #include "solo6010.h" #include "solo6010-tw28.h" #define SOLO_HW_BPL 2048 #define SOLO_DISP_PIX_FIELD V4L2_FIELD_INTERLACED -#define SOLO_DISP_BUF_SIZE (64 * 1024) // 64k /* Image size is two fields, SOLO_HW_BPL is one horizontal line */ #define solo_vlines(__solo) (__solo->video_vsize * 2) @@ -49,6 +48,8 @@ struct solo_filehandle { spinlock_t slock; int old_write; struct list_head vidq_active; + struct p2m_desc desc[SOLO_NR_P2M_DESC]; + int desc_idx; }; unsigned video_nr = -1; @@ -96,7 +97,7 @@ static void solo_win_setup(struct solo6010_dev *solo_dev, u8 ch, SOLO_VI_WIN_EX(ex) | SOLO_VI_WIN_SCALE(scale)); - solo_reg_write(solo_dev, SOLO_VI_WIN_CTRL1(ch), + solo_reg_write(solo_dev, SOLO_VI_WIN_CTRL1(ch), SOLO_VI_WIN_SY(sy) | SOLO_VI_WIN_EY(ey)); } @@ -203,50 +204,146 @@ static int solo_v4l2_set_ch(struct solo6010_dev *solo_dev, u8 ch) return 0; } +static void disp_reset_desc(struct solo_filehandle *fh) +{ + fh->desc_idx = 0; +} + +static int disp_flush_descs(struct solo_filehandle *fh) +{ + int ret; + + if (!fh->desc_idx) + return 0; + + ret = solo_p2m_dma_desc(fh->solo_dev, SOLO_P2M_DMA_ID_DISP, + fh->desc, fh->desc_idx); + disp_reset_desc(fh); + + return ret; +} + +static int disp_push_desc(struct solo_filehandle *fh, dma_addr_t dma_addr, + u32 ext_addr, int size, int repeat, int ext_size) +{ + if (fh->desc_idx >= SOLO_NR_P2M_DESC) { + int ret = disp_flush_descs(fh); + if (ret) + return ret; + } + + solo_p2m_push_desc(&fh->desc[fh->desc_idx], 0, dma_addr, ext_addr, + size, repeat, ext_size); + fh->desc_idx++; + + return 0; +} + static void solo_fillbuf(struct solo_filehandle *fh, struct videobuf_buffer *vb) { struct solo6010_dev *solo_dev = fh->solo_dev; - dma_addr_t vbuf; + struct videobuf_dmabuf* vbuf; unsigned int fdma_addr; - int frame_size; int error = 1; int i; + struct scatterlist* sg; + dma_addr_t sg_dma; + int sg_size_left; - if (!(vbuf = videobuf_to_dma_contig(vb))) + if (!(vbuf = videobuf_to_dma(vb))) goto finish_buf; if (erase_off(solo_dev)) { - void *p = videobuf_queue_to_vaddr(&fh->vidq, vb); - int image_size = solo_image_size(solo_dev); - for (i = 0; i < image_size; i += 2) { - ((u8 *)p)[i] = 0x80; - ((u8 *)p)[i + 1] = 0x00; + int i; + + /* Just blit to the entire sg list, ignoring size */ + for_each_sg(vbuf->sglist, sg, vbuf->sglen, i) { + void *p = sg_virt(sg); + size_t len = sg_dma_len(sg); + + for (i = 0; i < len; i += 2) { + ((u8 *)p)[i] = 0x80; + ((u8 *)p)[i + 1] = 0x00; + } } + error = 0; goto finish_buf; } - frame_size = SOLO_HW_BPL * solo_vlines(solo_dev); - fdma_addr = SOLO_DISP_EXT_ADDR(solo_dev) + (fh->old_write * frame_size); + disp_reset_desc(fh); + sg = vbuf->sglist; + sg_dma = sg_dma_address(sg); + sg_size_left = sg_dma_len(sg); + + fdma_addr = SOLO_DISP_EXT_ADDR(solo_dev) + (fh->old_write * + (SOLO_HW_BPL * solo_vlines(solo_dev))); - for (i = 0; i < frame_size / SOLO_DISP_BUF_SIZE; i++) { - int j; - for (j = 0; j < (SOLO_DISP_BUF_SIZE / SOLO_HW_BPL); j++) { - if (solo_p2m_dma_t(solo_dev, SOLO_P2M_DMA_ID_DISP, 0, - vbuf, fdma_addr + (j * SOLO_HW_BPL), - solo_bytesperline(solo_dev))) + for (i = 0; i < solo_vlines(solo_dev); i++) { + int line_len = solo_bytesperline(solo_dev); + int lines; + + if (!sg_size_left) { + sg = sg_next(sg); + if (sg == NULL) goto finish_buf; - vbuf += solo_bytesperline(solo_dev); + sg_dma = sg_dma_address(sg); + sg_size_left = sg_dma_len(sg); } - fdma_addr += SOLO_DISP_BUF_SIZE; + + /* No room for an entire line, so chunk it up */ + if (sg_size_left < line_len) { + int this_addr = fdma_addr; + + while (line_len > 0) { + int this_write; + + if (!sg_size_left) { + sg = sg_next(sg); + if (sg == NULL) + goto finish_buf; + sg_dma = sg_dma_address(sg); + sg_size_left = sg_dma_len(sg); + } + + this_write = min(sg_size_left, line_len); + + if (disp_push_desc(fh, sg_dma, this_addr, + this_write, 0, 0)) + goto finish_buf; + + line_len -= this_write; + sg_size_left -= this_write; + sg_dma += this_write; + this_addr += this_write; + } + + fdma_addr += SOLO_HW_BPL; + continue; + } + + /* Shove as many lines into a repeating descriptor as possible */ + lines = min(sg_size_left / line_len, + solo_vlines(solo_dev) - i); + + if (disp_push_desc(fh, sg_dma, fdma_addr, line_len, + lines - 1, SOLO_HW_BPL)) + goto finish_buf; + + i += lines - 1; + fdma_addr += SOLO_HW_BPL * lines; + sg_dma += lines * line_len; + sg_size_left -= lines * line_len; } - error = 0; + + error = disp_flush_descs(fh); finish_buf: if (error) { vb->state = VIDEOBUF_ERROR; } else { + vb->size = solo_vlines(solo_dev) * solo_bytesperline(solo_dev); vb->state = VIDEOBUF_DONE; vb->field_count++; do_gettimeofday(&vb->ts); @@ -275,7 +372,7 @@ static void solo_thread_try(struct solo_filehandle *fh) break; cur_write = SOLO_VI_STATUS0_PAGE(solo_reg_read(fh->solo_dev, - SOLO_VI_STATUS0)); + SOLO_VI_STATUS0)); if (cur_write == fh->old_write) break; @@ -310,7 +407,7 @@ static int solo_thread(void *data) remove_wait_queue(&solo_dev->disp_thread_wait, &wait); - return 0; + return 0; } static int solo_start_thread(struct solo_filehandle *fh) @@ -337,12 +434,12 @@ static int solo_buf_setup(struct videobuf_queue *vq, unsigned int *count, struct solo_filehandle *fh = vq->priv_data; struct solo6010_dev *solo_dev = fh->solo_dev; - *size = solo_image_size(solo_dev); + *size = solo_image_size(solo_dev); - if (*count < MIN_VID_BUFFERS) + if (*count < MIN_VID_BUFFERS) *count = MIN_VID_BUFFERS; - return 0; + return 0; } static int solo_buf_prepare(struct videobuf_queue *vq, @@ -364,7 +461,9 @@ static int solo_buf_prepare(struct videobuf_queue *vq, if (vb->state == VIDEOBUF_NEEDS_INIT) { int rc = videobuf_iolock(vq, vb, NULL); if (rc < 0) { - videobuf_dma_contig_free(vq, vb); + struct videobuf_dmabuf *dma = videobuf_to_dma(vb); + videobuf_dma_unmap(vq, dma); + videobuf_dma_free(dma); vb->state = VIDEOBUF_NEEDS_INIT; return rc; } @@ -388,7 +487,10 @@ static void solo_buf_queue(struct videobuf_queue *vq, static void solo_buf_release(struct videobuf_queue *vq, struct videobuf_buffer *vb) { - videobuf_dma_contig_free(vq, vb); + struct videobuf_dmabuf *dma = videobuf_to_dma(vb); + + videobuf_dma_unmap(vq, dma); + videobuf_dma_free(dma); vb->state = VIDEOBUF_NEEDS_INIT; } @@ -404,7 +506,7 @@ static unsigned int solo_v4l2_poll(struct file *file, { struct solo_filehandle *fh = file->private_data; - return videobuf_poll_stream(file, &fh->vidq, wait); + return videobuf_poll_stream(file, &fh->vidq, wait); } static int solo_v4l2_mmap(struct file *file, struct vm_area_struct *vma) @@ -433,11 +535,11 @@ static int solo_v4l2_open(struct file *file) return ret; } - videobuf_queue_dma_contig_init(&fh->vidq, &solo_video_qops, - &solo_dev->pdev->dev, &fh->slock, - V4L2_BUF_TYPE_VIDEO_CAPTURE, - SOLO_DISP_PIX_FIELD, - sizeof(struct videobuf_buffer), fh); + videobuf_queue_sg_init(&fh->vidq, &solo_video_qops, + &solo_dev->pdev->dev, &fh->slock, + V4L2_BUF_TYPE_VIDEO_CAPTURE, + SOLO_DISP_PIX_FIELD, + sizeof(struct videobuf_buffer), fh); return 0; } @@ -530,7 +632,7 @@ static int solo_enum_input(struct file *file, void *priv, if (solo_dev->video_type == SOLO_VO_FMT_TYPE_NTSC) input->std = V4L2_STD_NTSC_M; else - input->std = V4L2_STD_PAL_M; + input->std = V4L2_STD_PAL_B; return 0; } @@ -781,11 +883,11 @@ static const struct v4l2_ioctl_ops solo_v4l2_ioctl_ops = { .vidioc_qbuf = solo_qbuf, .vidioc_dqbuf = solo_dqbuf, .vidioc_streamon = solo_streamon, - .vidioc_streamoff = solo_streamoff, + .vidioc_streamoff = solo_streamoff, /* Controls */ .vidioc_queryctrl = solo_disp_queryctrl, - .vidioc_g_ctrl = solo_disp_g_ctrl, - .vidioc_s_ctrl = solo_disp_s_ctrl, + .vidioc_g_ctrl = solo_disp_g_ctrl, + .vidioc_s_ctrl = solo_disp_s_ctrl, }; static struct video_device solo_v4l2_template = { @@ -795,7 +897,7 @@ static struct video_device solo_v4l2_template = { .minor = -1, .release = video_device_release, - .tvnorms = V4L2_STD_NTSC_M | V4L2_STD_PAL_M, + .tvnorms = V4L2_STD_NTSC_M | V4L2_STD_PAL_B, .current_norm = V4L2_STD_NTSC_M, }; diff --git a/drivers/staging/solo6x10/solo6010.h b/drivers/staging/solo6x10/solo6010.h index dca8e3e15450..332fd79fa936 100644 --- a/drivers/staging/solo6x10/solo6010.h +++ b/drivers/staging/solo6x10/solo6010.h @@ -26,8 +26,8 @@ #include #include #include -#include #include +#include #include #include @@ -48,10 +48,14 @@ #define PCI_DEVICE_ID_NEUSOLO_4 0x4304 #define PCI_DEVICE_ID_NEUSOLO_9 0x4309 #define PCI_DEVICE_ID_NEUSOLO_16 0x4310 -/* Commell Softlogic 6010 based cards */ -#define PCI_DEVICE_ID_COMMSOLO_4 0x4E04 -#define PCI_DEVICE_ID_COMMSOLO_9 0x4E09 -#define PCI_DEVICE_ID_COMMSOLO_16 0x4E10 +/* Bluecherry Softlogic 6010 based cards */ +#define PCI_DEVICE_ID_BC_SOLO_4 0x4E04 +#define PCI_DEVICE_ID_BC_SOLO_9 0x4E09 +#define PCI_DEVICE_ID_BC_SOLO_16 0x4E10 +/* Bluecherry Softlogic 6110 based cards */ +#define PCI_DEVICE_ID_BC_6110_4 0x5304 +#define PCI_DEVICE_ID_BC_6110_8 0x5308 +#define PCI_DEVICE_ID_BC_6110_16 0x5310 #endif /* Bluecherry */ #define SOLO6010_NAME "solo6010" @@ -78,7 +82,6 @@ /* DMA Engine setup */ #define SOLO_NR_P2M 4 #define SOLO_NR_P2M_DESC 256 -#define SOLO_P2M_DESC_SIZE (SOLO_NR_P2M_DESC * 16) /* MPEG and JPEG share the same interrupt and locks so they must be together * in the same dma channel. */ #define SOLO_P2M_DMA_ID_MP4E 0 @@ -123,11 +126,20 @@ enum SOLO_I2C_STATE { IIC_STATE_STOP }; +struct p2m_desc { + u32 ctrl; + u32 ext; + u32 ta; + u32 fa; +}; + struct solo_p2m_dev { - struct semaphore sem; + struct mutex mutex; struct completion completion; int error; - u8 desc[SOLO_P2M_DESC_SIZE]; + int num_descs; + int desc_idx; + struct p2m_desc *descs; }; #define OSD_TEXT_MAX 30 @@ -185,7 +197,7 @@ struct solo6010_dev { /* i2c related items */ struct i2c_adapter i2c_adap[SOLO_I2C_ADAPTERS]; enum SOLO_I2C_STATE i2c_state; - struct semaphore i2c_sem; + struct mutex i2c_mutex; int i2c_id; wait_queue_head_t i2c_wait; struct i2c_msg *i2c_msg; @@ -306,6 +318,14 @@ int solo_p2m_dma_t(struct solo6010_dev *solo_dev, u8 id, int wr, dma_addr_t dma_addr, u32 ext_addr, u32 size); int solo_p2m_dma(struct solo6010_dev *solo_dev, u8 id, int wr, void *sys_addr, u32 ext_addr, u32 size); +int solo_p2m_dma_sg(struct solo6010_dev *solo_dev, u8 id, + struct p2m_desc *pdesc, int wr, + struct scatterlist *sglist, u32 sg_off, + u32 ext_addr, u32 size); +void solo_p2m_push_desc(struct p2m_desc *desc, int wr, dma_addr_t dma_addr, + u32 ext_addr, u32 size, int repeat, u32 ext_size); +int solo_p2m_dma_desc(struct solo6010_dev *solo_dev, u8 id, + struct p2m_desc *desc, int desc_count); /* Set the threshold for motion detection */ void solo_set_motion_threshold(struct solo6010_dev *solo_dev, u8 ch, u16 val); -- cgit v1.2.3 From 319fb3bacc517829cbd4d758f3b8969fdbde5c92 Mon Sep 17 00:00:00 2001 From: Ben Collins Date: Thu, 4 Nov 2010 23:20:31 -0400 Subject: solo6x10: Updates to videobuf-dma-sg functions for latest kernel Signed-off-by: Ben Collins --- drivers/staging/solo6x10/solo6010-v4l2-enc.c | 6 +++--- drivers/staging/solo6x10/solo6010-v4l2.c | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/staging/solo6x10/solo6010-v4l2-enc.c b/drivers/staging/solo6x10/solo6010-v4l2-enc.c index 736fad6dc1fb..5e2001aeb846 100644 --- a/drivers/staging/solo6x10/solo6010-v4l2-enc.c +++ b/drivers/staging/solo6x10/solo6010-v4l2-enc.c @@ -814,7 +814,7 @@ static int solo_enc_buf_prepare(struct videobuf_queue *vq, int rc = videobuf_iolock(vq, vb, NULL); if (rc < 0) { struct videobuf_dmabuf *dma = videobuf_to_dma(vb); - videobuf_dma_unmap(vq, dma); + videobuf_dma_unmap(vq->dev, dma); videobuf_dma_free(dma); vb->state = VIDEOBUF_NEEDS_INIT; return rc; @@ -840,7 +840,7 @@ static void solo_enc_buf_release(struct videobuf_queue *vq, { struct videobuf_dmabuf *dma = videobuf_to_dma(vb); - videobuf_dma_unmap(vq, dma); + videobuf_dma_unmap(vq->dev, dma); videobuf_dma_free(dma); vb->state = VIDEOBUF_NEEDS_INIT; } @@ -886,7 +886,7 @@ static int solo_enc_open(struct file *file) &solo_enc->lock, V4L2_BUF_TYPE_VIDEO_CAPTURE, V4L2_FIELD_INTERLACED, - sizeof(struct videobuf_buffer), fh); + sizeof(struct videobuf_buffer), fh, NULL); return 0; } diff --git a/drivers/staging/solo6x10/solo6010-v4l2.c b/drivers/staging/solo6x10/solo6010-v4l2.c index 4cf7257e1eb0..af80e6acb496 100644 --- a/drivers/staging/solo6x10/solo6010-v4l2.c +++ b/drivers/staging/solo6x10/solo6010-v4l2.c @@ -462,7 +462,7 @@ static int solo_buf_prepare(struct videobuf_queue *vq, int rc = videobuf_iolock(vq, vb, NULL); if (rc < 0) { struct videobuf_dmabuf *dma = videobuf_to_dma(vb); - videobuf_dma_unmap(vq, dma); + videobuf_dma_unmap(vq->dev, dma); videobuf_dma_free(dma); vb->state = VIDEOBUF_NEEDS_INIT; return rc; @@ -489,7 +489,7 @@ static void solo_buf_release(struct videobuf_queue *vq, { struct videobuf_dmabuf *dma = videobuf_to_dma(vb); - videobuf_dma_unmap(vq, dma); + videobuf_dma_unmap(vq->dev, dma); videobuf_dma_free(dma); vb->state = VIDEOBUF_NEEDS_INIT; } @@ -539,7 +539,7 @@ static int solo_v4l2_open(struct file *file) &solo_dev->pdev->dev, &fh->slock, V4L2_BUF_TYPE_VIDEO_CAPTURE, SOLO_DISP_PIX_FIELD, - sizeof(struct videobuf_buffer), fh); + sizeof(struct videobuf_buffer), fh, NULL); return 0; } -- cgit v1.2.3 From 22e2fda5660cdf62513acabdb5c82a5af415f838 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Thu, 4 Nov 2010 17:05:45 +0100 Subject: ASoC: i.MX: we can do mono Whether we can do mono or not depends on the codec. No need to limit this in the ssi driver. Signed-off-by: Sascha Hauer Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/imx/imx-ssi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/imx/imx-ssi.c b/sound/soc/imx/imx-ssi.c index d2d98c75ee8a..ad21f814e6a1 100644 --- a/sound/soc/imx/imx-ssi.c +++ b/sound/soc/imx/imx-ssi.c @@ -456,13 +456,13 @@ static int imx_ssi_dai_probe(struct snd_soc_dai *dai) static struct snd_soc_dai_driver imx_ssi_dai = { .probe = imx_ssi_dai_probe, .playback = { - .channels_min = 2, + .channels_min = 1, .channels_max = 2, .rates = SNDRV_PCM_RATE_8000_96000, .formats = SNDRV_PCM_FMTBIT_S16_LE, }, .capture = { - .channels_min = 2, + .channels_min = 1, .channels_max = 2, .rates = SNDRV_PCM_RATE_8000_96000, .formats = SNDRV_PCM_FMTBIT_S16_LE, -- cgit v1.2.3 From 0e4de059d90c96930ab237e7d4fbb7e3814afcb6 Mon Sep 17 00:00:00 2001 From: Ben Collins Date: Fri, 5 Nov 2010 10:29:33 -0400 Subject: solo6x10: Implement working P2M descriptor more DMA We have to insert 1 dead descriptor first (all zereos), and then the real data descriptors after that. Everything uses descriptor mode now (8800 interrupts per second for display v4l2 is now down to ~96). Signed-off-by: Ben Collins --- drivers/staging/solo6x10/TODO | 1 - drivers/staging/solo6x10/solo6010-p2m.c | 69 ++++++++++++++++---------------- drivers/staging/solo6x10/solo6010-v4l2.c | 4 +- drivers/staging/solo6x10/solo6010.h | 3 -- 4 files changed, 38 insertions(+), 39 deletions(-) diff --git a/drivers/staging/solo6x10/TODO b/drivers/staging/solo6x10/TODO index 82439d38ba74..7e6c4fa130df 100644 --- a/drivers/staging/solo6x10/TODO +++ b/drivers/staging/solo6x10/TODO @@ -15,7 +15,6 @@ TODO (general): * implement a CID control for motion areas/thresholds * implement CID controls for mozaic areas * allow for higher level of interval (for < 1 fps) - * Get proper descriptor mode working in p2m * sound: - implement playback via external sound jack - implement loopback of external sound jack with incoming audio? diff --git a/drivers/staging/solo6x10/solo6010-p2m.c b/drivers/staging/solo6x10/solo6010-p2m.c index a46ebf2f376a..9f2418093af5 100644 --- a/drivers/staging/solo6x10/solo6010-p2m.c +++ b/drivers/staging/solo6x10/solo6010-p2m.c @@ -50,11 +50,14 @@ int solo_p2m_dma(struct solo6010_dev *solo_dev, u8 id, int wr, int solo_p2m_dma_t(struct solo6010_dev *solo_dev, u8 id, int wr, dma_addr_t dma_addr, u32 ext_addr, u32 size) { - struct p2m_desc desc; + struct p2m_desc *desc = kzalloc(sizeof(*desc) * 2, GFP_DMA); - solo_p2m_push_desc(&desc, wr, dma_addr, ext_addr, size, 0, 0); + if (desc == NULL) + return -ENOMEM; - return solo_p2m_dma_desc(solo_dev, id, &desc, 1); + solo_p2m_push_desc(&desc[1], wr, dma_addr, ext_addr, size, 0, 0); + + return solo_p2m_dma_desc(solo_dev, id, desc, 2); } void solo_p2m_push_desc(struct p2m_desc *desc, int wr, dma_addr_t dma_addr, @@ -81,34 +84,44 @@ int solo_p2m_dma_desc(struct solo6010_dev *solo_dev, u8 id, struct solo_p2m_dev *p2m_dev; unsigned int timeout; int ret = 0; + u32 config = 0; + dma_addr_t desc_dma = 0; BUG_ON(id >= SOLO_NR_P2M); - BUG_ON(desc_count > SOLO_NR_P2M_DESC); + BUG_ON(!desc_count || desc_count > SOLO_NR_P2M_DESC); p2m_dev = &solo_dev->p2m_dev[id]; mutex_lock(&p2m_dev->mutex); + solo_reg_write(solo_dev, SOLO_P2M_CONTROL(id), 0); + INIT_COMPLETION(p2m_dev->completion); p2m_dev->error = 0; - /* Setup the descriptor count and base address */ - p2m_dev->num_descs = desc_count; - p2m_dev->descs = desc; - p2m_dev->desc_idx = 0; - - /* We plug in the first descriptor here. The isr will take - * over from desc[1] after this. */ - solo_reg_write(solo_dev, SOLO_P2M_TAR_ADR(id), desc[0].ta); - solo_reg_write(solo_dev, SOLO_P2M_EXT_ADR(id), desc[0].fa); - solo_reg_write(solo_dev, SOLO_P2M_EXT_CFG(id), desc[0].ext); - solo_reg_write(solo_dev, SOLO_P2M_CONTROL(id), desc[0].ctrl); + /* Enable the descriptors */ + config = solo_reg_read(solo_dev, SOLO_P2M_CONFIG(id)); + desc_dma = pci_map_single(solo_dev->pdev, desc, + desc_count * sizeof(*desc), + PCI_DMA_TODEVICE); + solo_reg_write(solo_dev, SOLO_P2M_DES_ADR(id), desc_dma); + solo_reg_write(solo_dev, SOLO_P2M_DESC_ID(id), desc_count - 1); + solo_reg_write(solo_dev, SOLO_P2M_CONFIG(id), config | + SOLO_P2M_DESC_MODE); /* Should have all descriptors completed from one interrupt */ timeout = wait_for_completion_timeout(&p2m_dev->completion, HZ); solo_reg_write(solo_dev, SOLO_P2M_CONTROL(id), 0); + /* Reset back to non-descriptor mode */ + solo_reg_write(solo_dev, SOLO_P2M_CONFIG(id), config); + solo_reg_write(solo_dev, SOLO_P2M_DESC_ID(id), 0); + solo_reg_write(solo_dev, SOLO_P2M_DES_ADR(id), 0); + pci_unmap_single(solo_dev->pdev, desc_dma, + desc_count * sizeof(*desc), + PCI_DMA_TODEVICE); + if (p2m_dev->error) ret = -EIO; else if (timeout == 0) @@ -134,9 +147,12 @@ int solo_p2m_dma_sg(struct solo6010_dev *solo_dev, u8 id, if (WARN_ON_ONCE(!size)) return -EINVAL; - for (i = idx = 0; i < SOLO_NR_P2M_DESC && sg && size > 0; + memset(pdesc, 0, sizeof(*pdesc)); + + /* Should rewrite this to handle > SOLO_NR_P2M_DESC transactions */ + for (i = 0, idx = 1; idx < SOLO_NR_P2M_DESC && sg && size > 0; i++, sg = sg_next(sg)) { - struct p2m_desc *desc = &pdesc[i]; + struct p2m_desc *desc = &pdesc[idx]; u32 sg_len = sg_dma_len(sg); u32 len; @@ -231,26 +247,10 @@ static void run_p2m_test(struct solo6010_dev *solo_dev) void solo_p2m_isr(struct solo6010_dev *solo_dev, int id) { struct solo_p2m_dev *p2m_dev = &solo_dev->p2m_dev[id]; - struct p2m_desc *desc; solo_reg_write(solo_dev, SOLO_IRQ_STAT, SOLO_IRQ_P2M(id)); - p2m_dev->desc_idx++; - - if (p2m_dev->desc_idx >= p2m_dev->num_descs) { - complete(&p2m_dev->completion); - return; - } - - /* Reset the p2m and start the next one */ - solo_reg_write(solo_dev, SOLO_P2M_CONTROL(id), 0); - - desc = &p2m_dev->descs[p2m_dev->desc_idx]; - - solo_reg_write(solo_dev, SOLO_P2M_TAR_ADR(id), desc->ta); - solo_reg_write(solo_dev, SOLO_P2M_EXT_ADR(id), desc->fa); - solo_reg_write(solo_dev, SOLO_P2M_EXT_CFG(id), desc->ext); - solo_reg_write(solo_dev, SOLO_P2M_CONTROL(id), desc->ctrl); + complete(&p2m_dev->completion); } void solo_p2m_error_isr(struct solo6010_dev *solo_dev, u32 status) @@ -292,6 +292,7 @@ int solo_p2m_init(struct solo6010_dev *solo_dev) solo_reg_write(solo_dev, SOLO_P2M_CONFIG(i), SOLO_P2M_CSC_16BIT_565 | SOLO_P2M_DMA_INTERVAL(3) | + SOLO_P2M_DESC_INTR_OPT | SOLO_P2M_PCI_MASTER_MODE); solo6010_irq_on(solo_dev, SOLO_IRQ_P2M(i)); } diff --git a/drivers/staging/solo6x10/solo6010-v4l2.c b/drivers/staging/solo6x10/solo6010-v4l2.c index af80e6acb496..7a9c348de565 100644 --- a/drivers/staging/solo6x10/solo6010-v4l2.c +++ b/drivers/staging/solo6x10/solo6010-v4l2.c @@ -206,7 +206,9 @@ static int solo_v4l2_set_ch(struct solo6010_dev *solo_dev, u8 ch) static void disp_reset_desc(struct solo_filehandle *fh) { - fh->desc_idx = 0; + /* We use desc mode, which ignores desc 0 */ + memset(fh->desc, 0, sizeof(*fh->desc)); + fh->desc_idx = 1; } static int disp_flush_descs(struct solo_filehandle *fh) diff --git a/drivers/staging/solo6x10/solo6010.h b/drivers/staging/solo6x10/solo6010.h index 332fd79fa936..9f5d2a326ae1 100644 --- a/drivers/staging/solo6x10/solo6010.h +++ b/drivers/staging/solo6x10/solo6010.h @@ -137,9 +137,6 @@ struct solo_p2m_dev { struct mutex mutex; struct completion completion; int error; - int num_descs; - int desc_idx; - struct p2m_desc *descs; }; #define OSD_TEXT_MAX 30 -- cgit v1.2.3 From 0d24db337e6d81c0c620ab65cc6947bd6553f742 Mon Sep 17 00:00:00 2001 From: Christoph Lameter Date: Thu, 21 Oct 2010 13:01:56 -0500 Subject: slub: move slabinfo.c to tools/slub/slabinfo.c We now have a tools directory for these things. Reviewed-by: KOSAKI Motohiro Acked-by: David Rientjes Signed-off-by: Christoph Lameter Signed-off-by: Pekka Enberg --- Documentation/vm/slabinfo.c | 1364 ------------------------------------------- tools/slub/slabinfo.c | 1364 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 1364 insertions(+), 1364 deletions(-) delete mode 100644 Documentation/vm/slabinfo.c create mode 100644 tools/slub/slabinfo.c diff --git a/Documentation/vm/slabinfo.c b/Documentation/vm/slabinfo.c deleted file mode 100644 index 92e729f4b676..000000000000 --- a/Documentation/vm/slabinfo.c +++ /dev/null @@ -1,1364 +0,0 @@ -/* - * Slabinfo: Tool to get reports about slabs - * - * (C) 2007 sgi, Christoph Lameter - * - * Compile by: - * - * gcc -o slabinfo slabinfo.c - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define MAX_SLABS 500 -#define MAX_ALIASES 500 -#define MAX_NODES 1024 - -struct slabinfo { - char *name; - int alias; - int refs; - int aliases, align, cache_dma, cpu_slabs, destroy_by_rcu; - int hwcache_align, object_size, objs_per_slab; - int sanity_checks, slab_size, store_user, trace; - int order, poison, reclaim_account, red_zone; - unsigned long partial, objects, slabs, objects_partial, objects_total; - unsigned long alloc_fastpath, alloc_slowpath; - unsigned long free_fastpath, free_slowpath; - unsigned long free_frozen, free_add_partial, free_remove_partial; - unsigned long alloc_from_partial, alloc_slab, free_slab, alloc_refill; - unsigned long cpuslab_flush, deactivate_full, deactivate_empty; - unsigned long deactivate_to_head, deactivate_to_tail; - unsigned long deactivate_remote_frees, order_fallback; - int numa[MAX_NODES]; - int numa_partial[MAX_NODES]; -} slabinfo[MAX_SLABS]; - -struct aliasinfo { - char *name; - char *ref; - struct slabinfo *slab; -} aliasinfo[MAX_ALIASES]; - -int slabs = 0; -int actual_slabs = 0; -int aliases = 0; -int alias_targets = 0; -int highest_node = 0; - -char buffer[4096]; - -int show_empty = 0; -int show_report = 0; -int show_alias = 0; -int show_slab = 0; -int skip_zero = 1; -int show_numa = 0; -int show_track = 0; -int show_first_alias = 0; -int validate = 0; -int shrink = 0; -int show_inverted = 0; -int show_single_ref = 0; -int show_totals = 0; -int sort_size = 0; -int sort_active = 0; -int set_debug = 0; -int show_ops = 0; -int show_activity = 0; - -/* Debug options */ -int sanity = 0; -int redzone = 0; -int poison = 0; -int tracking = 0; -int tracing = 0; - -int page_size; - -regex_t pattern; - -static void fatal(const char *x, ...) -{ - va_list ap; - - va_start(ap, x); - vfprintf(stderr, x, ap); - va_end(ap); - exit(EXIT_FAILURE); -} - -static void usage(void) -{ - printf("slabinfo 5/7/2007. (c) 2007 sgi.\n\n" - "slabinfo [-ahnpvtsz] [-d debugopts] [slab-regexp]\n" - "-a|--aliases Show aliases\n" - "-A|--activity Most active slabs first\n" - "-d|--debug= Set/Clear Debug options\n" - "-D|--display-active Switch line format to activity\n" - "-e|--empty Show empty slabs\n" - "-f|--first-alias Show first alias\n" - "-h|--help Show usage information\n" - "-i|--inverted Inverted list\n" - "-l|--slabs Show slabs\n" - "-n|--numa Show NUMA information\n" - "-o|--ops Show kmem_cache_ops\n" - "-s|--shrink Shrink slabs\n" - "-r|--report Detailed report on single slabs\n" - "-S|--Size Sort by size\n" - "-t|--tracking Show alloc/free information\n" - "-T|--Totals Show summary information\n" - "-v|--validate Validate slabs\n" - "-z|--zero Include empty slabs\n" - "-1|--1ref Single reference\n" - "\nValid debug options (FZPUT may be combined)\n" - "a / A Switch on all debug options (=FZUP)\n" - "- Switch off all debug options\n" - "f / F Sanity Checks (SLAB_DEBUG_FREE)\n" - "z / Z Redzoning\n" - "p / P Poisoning\n" - "u / U Tracking\n" - "t / T Tracing\n" - ); -} - -static unsigned long read_obj(const char *name) -{ - FILE *f = fopen(name, "r"); - - if (!f) - buffer[0] = 0; - else { - if (!fgets(buffer, sizeof(buffer), f)) - buffer[0] = 0; - fclose(f); - if (buffer[strlen(buffer)] == '\n') - buffer[strlen(buffer)] = 0; - } - return strlen(buffer); -} - - -/* - * Get the contents of an attribute - */ -static unsigned long get_obj(const char *name) -{ - if (!read_obj(name)) - return 0; - - return atol(buffer); -} - -static unsigned long get_obj_and_str(const char *name, char **x) -{ - unsigned long result = 0; - char *p; - - *x = NULL; - - if (!read_obj(name)) { - x = NULL; - return 0; - } - result = strtoul(buffer, &p, 10); - while (*p == ' ') - p++; - if (*p) - *x = strdup(p); - return result; -} - -static void set_obj(struct slabinfo *s, const char *name, int n) -{ - char x[100]; - FILE *f; - - snprintf(x, 100, "%s/%s", s->name, name); - f = fopen(x, "w"); - if (!f) - fatal("Cannot write to %s\n", x); - - fprintf(f, "%d\n", n); - fclose(f); -} - -static unsigned long read_slab_obj(struct slabinfo *s, const char *name) -{ - char x[100]; - FILE *f; - size_t l; - - snprintf(x, 100, "%s/%s", s->name, name); - f = fopen(x, "r"); - if (!f) { - buffer[0] = 0; - l = 0; - } else { - l = fread(buffer, 1, sizeof(buffer), f); - buffer[l] = 0; - fclose(f); - } - return l; -} - - -/* - * Put a size string together - */ -static int store_size(char *buffer, unsigned long value) -{ - unsigned long divisor = 1; - char trailer = 0; - int n; - - if (value > 1000000000UL) { - divisor = 100000000UL; - trailer = 'G'; - } else if (value > 1000000UL) { - divisor = 100000UL; - trailer = 'M'; - } else if (value > 1000UL) { - divisor = 100; - trailer = 'K'; - } - - value /= divisor; - n = sprintf(buffer, "%ld",value); - if (trailer) { - buffer[n] = trailer; - n++; - buffer[n] = 0; - } - if (divisor != 1) { - memmove(buffer + n - 2, buffer + n - 3, 4); - buffer[n-2] = '.'; - n++; - } - return n; -} - -static void decode_numa_list(int *numa, char *t) -{ - int node; - int nr; - - memset(numa, 0, MAX_NODES * sizeof(int)); - - if (!t) - return; - - while (*t == 'N') { - t++; - node = strtoul(t, &t, 10); - if (*t == '=') { - t++; - nr = strtoul(t, &t, 10); - numa[node] = nr; - if (node > highest_node) - highest_node = node; - } - while (*t == ' ') - t++; - } -} - -static void slab_validate(struct slabinfo *s) -{ - if (strcmp(s->name, "*") == 0) - return; - - set_obj(s, "validate", 1); -} - -static void slab_shrink(struct slabinfo *s) -{ - if (strcmp(s->name, "*") == 0) - return; - - set_obj(s, "shrink", 1); -} - -int line = 0; - -static void first_line(void) -{ - if (show_activity) - printf("Name Objects Alloc Free %%Fast Fallb O\n"); - else - printf("Name Objects Objsize Space " - "Slabs/Part/Cpu O/S O %%Fr %%Ef Flg\n"); -} - -/* - * Find the shortest alias of a slab - */ -static struct aliasinfo *find_one_alias(struct slabinfo *find) -{ - struct aliasinfo *a; - struct aliasinfo *best = NULL; - - for(a = aliasinfo;a < aliasinfo + aliases; a++) { - if (a->slab == find && - (!best || strlen(best->name) < strlen(a->name))) { - best = a; - if (strncmp(a->name,"kmall", 5) == 0) - return best; - } - } - return best; -} - -static unsigned long slab_size(struct slabinfo *s) -{ - return s->slabs * (page_size << s->order); -} - -static unsigned long slab_activity(struct slabinfo *s) -{ - return s->alloc_fastpath + s->free_fastpath + - s->alloc_slowpath + s->free_slowpath; -} - -static void slab_numa(struct slabinfo *s, int mode) -{ - int node; - - if (strcmp(s->name, "*") == 0) - return; - - if (!highest_node) { - printf("\n%s: No NUMA information available.\n", s->name); - return; - } - - if (skip_zero && !s->slabs) - return; - - if (!line) { - printf("\n%-21s:", mode ? "NUMA nodes" : "Slab"); - for(node = 0; node <= highest_node; node++) - printf(" %4d", node); - printf("\n----------------------"); - for(node = 0; node <= highest_node; node++) - printf("-----"); - printf("\n"); - } - printf("%-21s ", mode ? "All slabs" : s->name); - for(node = 0; node <= highest_node; node++) { - char b[20]; - - store_size(b, s->numa[node]); - printf(" %4s", b); - } - printf("\n"); - if (mode) { - printf("%-21s ", "Partial slabs"); - for(node = 0; node <= highest_node; node++) { - char b[20]; - - store_size(b, s->numa_partial[node]); - printf(" %4s", b); - } - printf("\n"); - } - line++; -} - -static void show_tracking(struct slabinfo *s) -{ - printf("\n%s: Kernel object allocation\n", s->name); - printf("-----------------------------------------------------------------------\n"); - if (read_slab_obj(s, "alloc_calls")) - printf(buffer); - else - printf("No Data\n"); - - printf("\n%s: Kernel object freeing\n", s->name); - printf("------------------------------------------------------------------------\n"); - if (read_slab_obj(s, "free_calls")) - printf(buffer); - else - printf("No Data\n"); - -} - -static void ops(struct slabinfo *s) -{ - if (strcmp(s->name, "*") == 0) - return; - - if (read_slab_obj(s, "ops")) { - printf("\n%s: kmem_cache operations\n", s->name); - printf("--------------------------------------------\n"); - printf(buffer); - } else - printf("\n%s has no kmem_cache operations\n", s->name); -} - -static const char *onoff(int x) -{ - if (x) - return "On "; - return "Off"; -} - -static void slab_stats(struct slabinfo *s) -{ - unsigned long total_alloc; - unsigned long total_free; - unsigned long total; - - if (!s->alloc_slab) - return; - - total_alloc = s->alloc_fastpath + s->alloc_slowpath; - total_free = s->free_fastpath + s->free_slowpath; - - if (!total_alloc) - return; - - printf("\n"); - printf("Slab Perf Counter Alloc Free %%Al %%Fr\n"); - printf("--------------------------------------------------\n"); - printf("Fastpath %8lu %8lu %3lu %3lu\n", - s->alloc_fastpath, s->free_fastpath, - s->alloc_fastpath * 100 / total_alloc, - s->free_fastpath * 100 / total_free); - printf("Slowpath %8lu %8lu %3lu %3lu\n", - total_alloc - s->alloc_fastpath, s->free_slowpath, - (total_alloc - s->alloc_fastpath) * 100 / total_alloc, - s->free_slowpath * 100 / total_free); - printf("Page Alloc %8lu %8lu %3lu %3lu\n", - s->alloc_slab, s->free_slab, - s->alloc_slab * 100 / total_alloc, - s->free_slab * 100 / total_free); - printf("Add partial %8lu %8lu %3lu %3lu\n", - s->deactivate_to_head + s->deactivate_to_tail, - s->free_add_partial, - (s->deactivate_to_head + s->deactivate_to_tail) * 100 / total_alloc, - s->free_add_partial * 100 / total_free); - printf("Remove partial %8lu %8lu %3lu %3lu\n", - s->alloc_from_partial, s->free_remove_partial, - s->alloc_from_partial * 100 / total_alloc, - s->free_remove_partial * 100 / total_free); - - printf("RemoteObj/SlabFrozen %8lu %8lu %3lu %3lu\n", - s->deactivate_remote_frees, s->free_frozen, - s->deactivate_remote_frees * 100 / total_alloc, - s->free_frozen * 100 / total_free); - - printf("Total %8lu %8lu\n\n", total_alloc, total_free); - - if (s->cpuslab_flush) - printf("Flushes %8lu\n", s->cpuslab_flush); - - if (s->alloc_refill) - printf("Refill %8lu\n", s->alloc_refill); - - total = s->deactivate_full + s->deactivate_empty + - s->deactivate_to_head + s->deactivate_to_tail; - - if (total) - printf("Deactivate Full=%lu(%lu%%) Empty=%lu(%lu%%) " - "ToHead=%lu(%lu%%) ToTail=%lu(%lu%%)\n", - s->deactivate_full, (s->deactivate_full * 100) / total, - s->deactivate_empty, (s->deactivate_empty * 100) / total, - s->deactivate_to_head, (s->deactivate_to_head * 100) / total, - s->deactivate_to_tail, (s->deactivate_to_tail * 100) / total); -} - -static void report(struct slabinfo *s) -{ - if (strcmp(s->name, "*") == 0) - return; - - printf("\nSlabcache: %-20s Aliases: %2d Order : %2d Objects: %lu\n", - s->name, s->aliases, s->order, s->objects); - if (s->hwcache_align) - printf("** Hardware cacheline aligned\n"); - if (s->cache_dma) - printf("** Memory is allocated in a special DMA zone\n"); - if (s->destroy_by_rcu) - printf("** Slabs are destroyed via RCU\n"); - if (s->reclaim_account) - printf("** Reclaim accounting active\n"); - - printf("\nSizes (bytes) Slabs Debug Memory\n"); - printf("------------------------------------------------------------------------\n"); - printf("Object : %7d Total : %7ld Sanity Checks : %s Total: %7ld\n", - s->object_size, s->slabs, onoff(s->sanity_checks), - s->slabs * (page_size << s->order)); - printf("SlabObj: %7d Full : %7ld Redzoning : %s Used : %7ld\n", - s->slab_size, s->slabs - s->partial - s->cpu_slabs, - onoff(s->red_zone), s->objects * s->object_size); - printf("SlabSiz: %7d Partial: %7ld Poisoning : %s Loss : %7ld\n", - page_size << s->order, s->partial, onoff(s->poison), - s->slabs * (page_size << s->order) - s->objects * s->object_size); - printf("Loss : %7d CpuSlab: %7d Tracking : %s Lalig: %7ld\n", - s->slab_size - s->object_size, s->cpu_slabs, onoff(s->store_user), - (s->slab_size - s->object_size) * s->objects); - printf("Align : %7d Objects: %7d Tracing : %s Lpadd: %7ld\n", - s->align, s->objs_per_slab, onoff(s->trace), - ((page_size << s->order) - s->objs_per_slab * s->slab_size) * - s->slabs); - - ops(s); - show_tracking(s); - slab_numa(s, 1); - slab_stats(s); -} - -static void slabcache(struct slabinfo *s) -{ - char size_str[20]; - char dist_str[40]; - char flags[20]; - char *p = flags; - - if (strcmp(s->name, "*") == 0) - return; - - if (actual_slabs == 1) { - report(s); - return; - } - - if (skip_zero && !show_empty && !s->slabs) - return; - - if (show_empty && s->slabs) - return; - - store_size(size_str, slab_size(s)); - snprintf(dist_str, 40, "%lu/%lu/%d", s->slabs - s->cpu_slabs, - s->partial, s->cpu_slabs); - - if (!line++) - first_line(); - - if (s->aliases) - *p++ = '*'; - if (s->cache_dma) - *p++ = 'd'; - if (s->hwcache_align) - *p++ = 'A'; - if (s->poison) - *p++ = 'P'; - if (s->reclaim_account) - *p++ = 'a'; - if (s->red_zone) - *p++ = 'Z'; - if (s->sanity_checks) - *p++ = 'F'; - if (s->store_user) - *p++ = 'U'; - if (s->trace) - *p++ = 'T'; - - *p = 0; - if (show_activity) { - unsigned long total_alloc; - unsigned long total_free; - - total_alloc = s->alloc_fastpath + s->alloc_slowpath; - total_free = s->free_fastpath + s->free_slowpath; - - printf("%-21s %8ld %10ld %10ld %3ld %3ld %5ld %1d\n", - s->name, s->objects, - total_alloc, total_free, - total_alloc ? (s->alloc_fastpath * 100 / total_alloc) : 0, - total_free ? (s->free_fastpath * 100 / total_free) : 0, - s->order_fallback, s->order); - } - else - printf("%-21s %8ld %7d %8s %14s %4d %1d %3ld %3ld %s\n", - s->name, s->objects, s->object_size, size_str, dist_str, - s->objs_per_slab, s->order, - s->slabs ? (s->partial * 100) / s->slabs : 100, - s->slabs ? (s->objects * s->object_size * 100) / - (s->slabs * (page_size << s->order)) : 100, - flags); -} - -/* - * Analyze debug options. Return false if something is amiss. - */ -static int debug_opt_scan(char *opt) -{ - if (!opt || !opt[0] || strcmp(opt, "-") == 0) - return 1; - - if (strcasecmp(opt, "a") == 0) { - sanity = 1; - poison = 1; - redzone = 1; - tracking = 1; - return 1; - } - - for ( ; *opt; opt++) - switch (*opt) { - case 'F' : case 'f': - if (sanity) - return 0; - sanity = 1; - break; - case 'P' : case 'p': - if (poison) - return 0; - poison = 1; - break; - - case 'Z' : case 'z': - if (redzone) - return 0; - redzone = 1; - break; - - case 'U' : case 'u': - if (tracking) - return 0; - tracking = 1; - break; - - case 'T' : case 't': - if (tracing) - return 0; - tracing = 1; - break; - default: - return 0; - } - return 1; -} - -static int slab_empty(struct slabinfo *s) -{ - if (s->objects > 0) - return 0; - - /* - * We may still have slabs even if there are no objects. Shrinking will - * remove them. - */ - if (s->slabs != 0) - set_obj(s, "shrink", 1); - - return 1; -} - -static void slab_debug(struct slabinfo *s) -{ - if (strcmp(s->name, "*") == 0) - return; - - if (sanity && !s->sanity_checks) { - set_obj(s, "sanity", 1); - } - if (!sanity && s->sanity_checks) { - if (slab_empty(s)) - set_obj(s, "sanity", 0); - else - fprintf(stderr, "%s not empty cannot disable sanity checks\n", s->name); - } - if (redzone && !s->red_zone) { - if (slab_empty(s)) - set_obj(s, "red_zone", 1); - else - fprintf(stderr, "%s not empty cannot enable redzoning\n", s->name); - } - if (!redzone && s->red_zone) { - if (slab_empty(s)) - set_obj(s, "red_zone", 0); - else - fprintf(stderr, "%s not empty cannot disable redzoning\n", s->name); - } - if (poison && !s->poison) { - if (slab_empty(s)) - set_obj(s, "poison", 1); - else - fprintf(stderr, "%s not empty cannot enable poisoning\n", s->name); - } - if (!poison && s->poison) { - if (slab_empty(s)) - set_obj(s, "poison", 0); - else - fprintf(stderr, "%s not empty cannot disable poisoning\n", s->name); - } - if (tracking && !s->store_user) { - if (slab_empty(s)) - set_obj(s, "store_user", 1); - else - fprintf(stderr, "%s not empty cannot enable tracking\n", s->name); - } - if (!tracking && s->store_user) { - if (slab_empty(s)) - set_obj(s, "store_user", 0); - else - fprintf(stderr, "%s not empty cannot disable tracking\n", s->name); - } - if (tracing && !s->trace) { - if (slabs == 1) - set_obj(s, "trace", 1); - else - fprintf(stderr, "%s can only enable trace for one slab at a time\n", s->name); - } - if (!tracing && s->trace) - set_obj(s, "trace", 1); -} - -static void totals(void) -{ - struct slabinfo *s; - - int used_slabs = 0; - char b1[20], b2[20], b3[20], b4[20]; - unsigned long long max = 1ULL << 63; - - /* Object size */ - unsigned long long min_objsize = max, max_objsize = 0, avg_objsize; - - /* Number of partial slabs in a slabcache */ - unsigned long long min_partial = max, max_partial = 0, - avg_partial, total_partial = 0; - - /* Number of slabs in a slab cache */ - unsigned long long min_slabs = max, max_slabs = 0, - avg_slabs, total_slabs = 0; - - /* Size of the whole slab */ - unsigned long long min_size = max, max_size = 0, - avg_size, total_size = 0; - - /* Bytes used for object storage in a slab */ - unsigned long long min_used = max, max_used = 0, - avg_used, total_used = 0; - - /* Waste: Bytes used for alignment and padding */ - unsigned long long min_waste = max, max_waste = 0, - avg_waste, total_waste = 0; - /* Number of objects in a slab */ - unsigned long long min_objects = max, max_objects = 0, - avg_objects, total_objects = 0; - /* Waste per object */ - unsigned long long min_objwaste = max, - max_objwaste = 0, avg_objwaste, - total_objwaste = 0; - - /* Memory per object */ - unsigned long long min_memobj = max, - max_memobj = 0, avg_memobj, - total_objsize = 0; - - /* Percentage of partial slabs per slab */ - unsigned long min_ppart = 100, max_ppart = 0, - avg_ppart, total_ppart = 0; - - /* Number of objects in partial slabs */ - unsigned long min_partobj = max, max_partobj = 0, - avg_partobj, total_partobj = 0; - - /* Percentage of partial objects of all objects in a slab */ - unsigned long min_ppartobj = 100, max_ppartobj = 0, - avg_ppartobj, total_ppartobj = 0; - - - for (s = slabinfo; s < slabinfo + slabs; s++) { - unsigned long long size; - unsigned long used; - unsigned long long wasted; - unsigned long long objwaste; - unsigned long percentage_partial_slabs; - unsigned long percentage_partial_objs; - - if (!s->slabs || !s->objects) - continue; - - used_slabs++; - - size = slab_size(s); - used = s->objects * s->object_size; - wasted = size - used; - objwaste = s->slab_size - s->object_size; - - percentage_partial_slabs = s->partial * 100 / s->slabs; - if (percentage_partial_slabs > 100) - percentage_partial_slabs = 100; - - percentage_partial_objs = s->objects_partial * 100 - / s->objects; - - if (percentage_partial_objs > 100) - percentage_partial_objs = 100; - - if (s->object_size < min_objsize) - min_objsize = s->object_size; - if (s->partial < min_partial) - min_partial = s->partial; - if (s->slabs < min_slabs) - min_slabs = s->slabs; - if (size < min_size) - min_size = size; - if (wasted < min_waste) - min_waste = wasted; - if (objwaste < min_objwaste) - min_objwaste = objwaste; - if (s->objects < min_objects) - min_objects = s->objects; - if (used < min_used) - min_used = used; - if (s->objects_partial < min_partobj) - min_partobj = s->objects_partial; - if (percentage_partial_slabs < min_ppart) - min_ppart = percentage_partial_slabs; - if (percentage_partial_objs < min_ppartobj) - min_ppartobj = percentage_partial_objs; - if (s->slab_size < min_memobj) - min_memobj = s->slab_size; - - if (s->object_size > max_objsize) - max_objsize = s->object_size; - if (s->partial > max_partial) - max_partial = s->partial; - if (s->slabs > max_slabs) - max_slabs = s->slabs; - if (size > max_size) - max_size = size; - if (wasted > max_waste) - max_waste = wasted; - if (objwaste > max_objwaste) - max_objwaste = objwaste; - if (s->objects > max_objects) - max_objects = s->objects; - if (used > max_used) - max_used = used; - if (s->objects_partial > max_partobj) - max_partobj = s->objects_partial; - if (percentage_partial_slabs > max_ppart) - max_ppart = percentage_partial_slabs; - if (percentage_partial_objs > max_ppartobj) - max_ppartobj = percentage_partial_objs; - if (s->slab_size > max_memobj) - max_memobj = s->slab_size; - - total_partial += s->partial; - total_slabs += s->slabs; - total_size += size; - total_waste += wasted; - - total_objects += s->objects; - total_used += used; - total_partobj += s->objects_partial; - total_ppart += percentage_partial_slabs; - total_ppartobj += percentage_partial_objs; - - total_objwaste += s->objects * objwaste; - total_objsize += s->objects * s->slab_size; - } - - if (!total_objects) { - printf("No objects\n"); - return; - } - if (!used_slabs) { - printf("No slabs\n"); - return; - } - - /* Per slab averages */ - avg_partial = total_partial / used_slabs; - avg_slabs = total_slabs / used_slabs; - avg_size = total_size / used_slabs; - avg_waste = total_waste / used_slabs; - - avg_objects = total_objects / used_slabs; - avg_used = total_used / used_slabs; - avg_partobj = total_partobj / used_slabs; - avg_ppart = total_ppart / used_slabs; - avg_ppartobj = total_ppartobj / used_slabs; - - /* Per object object sizes */ - avg_objsize = total_used / total_objects; - avg_objwaste = total_objwaste / total_objects; - avg_partobj = total_partobj * 100 / total_objects; - avg_memobj = total_objsize / total_objects; - - printf("Slabcache Totals\n"); - printf("----------------\n"); - printf("Slabcaches : %3d Aliases : %3d->%-3d Active: %3d\n", - slabs, aliases, alias_targets, used_slabs); - - store_size(b1, total_size);store_size(b2, total_waste); - store_size(b3, total_waste * 100 / total_used); - printf("Memory used: %6s # Loss : %6s MRatio:%6s%%\n", b1, b2, b3); - - store_size(b1, total_objects);store_size(b2, total_partobj); - store_size(b3, total_partobj * 100 / total_objects); - printf("# Objects : %6s # PartObj: %6s ORatio:%6s%%\n", b1, b2, b3); - - printf("\n"); - printf("Per Cache Average Min Max Total\n"); - printf("---------------------------------------------------------\n"); - - store_size(b1, avg_objects);store_size(b2, min_objects); - store_size(b3, max_objects);store_size(b4, total_objects); - printf("#Objects %10s %10s %10s %10s\n", - b1, b2, b3, b4); - - store_size(b1, avg_slabs);store_size(b2, min_slabs); - store_size(b3, max_slabs);store_size(b4, total_slabs); - printf("#Slabs %10s %10s %10s %10s\n", - b1, b2, b3, b4); - - store_size(b1, avg_partial);store_size(b2, min_partial); - store_size(b3, max_partial);store_size(b4, total_partial); - printf("#PartSlab %10s %10s %10s %10s\n", - b1, b2, b3, b4); - store_size(b1, avg_ppart);store_size(b2, min_ppart); - store_size(b3, max_ppart); - store_size(b4, total_partial * 100 / total_slabs); - printf("%%PartSlab%10s%% %10s%% %10s%% %10s%%\n", - b1, b2, b3, b4); - - store_size(b1, avg_partobj);store_size(b2, min_partobj); - store_size(b3, max_partobj); - store_size(b4, total_partobj); - printf("PartObjs %10s %10s %10s %10s\n", - b1, b2, b3, b4); - - store_size(b1, avg_ppartobj);store_size(b2, min_ppartobj); - store_size(b3, max_ppartobj); - store_size(b4, total_partobj * 100 / total_objects); - printf("%% PartObj%10s%% %10s%% %10s%% %10s%%\n", - b1, b2, b3, b4); - - store_size(b1, avg_size);store_size(b2, min_size); - store_size(b3, max_size);store_size(b4, total_size); - printf("Memory %10s %10s %10s %10s\n", - b1, b2, b3, b4); - - store_size(b1, avg_used);store_size(b2, min_used); - store_size(b3, max_used);store_size(b4, total_used); - printf("Used %10s %10s %10s %10s\n", - b1, b2, b3, b4); - - store_size(b1, avg_waste);store_size(b2, min_waste); - store_size(b3, max_waste);store_size(b4, total_waste); - printf("Loss %10s %10s %10s %10s\n", - b1, b2, b3, b4); - - printf("\n"); - printf("Per Object Average Min Max\n"); - printf("---------------------------------------------\n"); - - store_size(b1, avg_memobj);store_size(b2, min_memobj); - store_size(b3, max_memobj); - printf("Memory %10s %10s %10s\n", - b1, b2, b3); - store_size(b1, avg_objsize);store_size(b2, min_objsize); - store_size(b3, max_objsize); - printf("User %10s %10s %10s\n", - b1, b2, b3); - - store_size(b1, avg_objwaste);store_size(b2, min_objwaste); - store_size(b3, max_objwaste); - printf("Loss %10s %10s %10s\n", - b1, b2, b3); -} - -static void sort_slabs(void) -{ - struct slabinfo *s1,*s2; - - for (s1 = slabinfo; s1 < slabinfo + slabs; s1++) { - for (s2 = s1 + 1; s2 < slabinfo + slabs; s2++) { - int result; - - if (sort_size) - result = slab_size(s1) < slab_size(s2); - else if (sort_active) - result = slab_activity(s1) < slab_activity(s2); - else - result = strcasecmp(s1->name, s2->name); - - if (show_inverted) - result = -result; - - if (result > 0) { - struct slabinfo t; - - memcpy(&t, s1, sizeof(struct slabinfo)); - memcpy(s1, s2, sizeof(struct slabinfo)); - memcpy(s2, &t, sizeof(struct slabinfo)); - } - } - } -} - -static void sort_aliases(void) -{ - struct aliasinfo *a1,*a2; - - for (a1 = aliasinfo; a1 < aliasinfo + aliases; a1++) { - for (a2 = a1 + 1; a2 < aliasinfo + aliases; a2++) { - char *n1, *n2; - - n1 = a1->name; - n2 = a2->name; - if (show_alias && !show_inverted) { - n1 = a1->ref; - n2 = a2->ref; - } - if (strcasecmp(n1, n2) > 0) { - struct aliasinfo t; - - memcpy(&t, a1, sizeof(struct aliasinfo)); - memcpy(a1, a2, sizeof(struct aliasinfo)); - memcpy(a2, &t, sizeof(struct aliasinfo)); - } - } - } -} - -static void link_slabs(void) -{ - struct aliasinfo *a; - struct slabinfo *s; - - for (a = aliasinfo; a < aliasinfo + aliases; a++) { - - for (s = slabinfo; s < slabinfo + slabs; s++) - if (strcmp(a->ref, s->name) == 0) { - a->slab = s; - s->refs++; - break; - } - if (s == slabinfo + slabs) - fatal("Unresolved alias %s\n", a->ref); - } -} - -static void alias(void) -{ - struct aliasinfo *a; - char *active = NULL; - - sort_aliases(); - link_slabs(); - - for(a = aliasinfo; a < aliasinfo + aliases; a++) { - - if (!show_single_ref && a->slab->refs == 1) - continue; - - if (!show_inverted) { - if (active) { - if (strcmp(a->slab->name, active) == 0) { - printf(" %s", a->name); - continue; - } - } - printf("\n%-12s <- %s", a->slab->name, a->name); - active = a->slab->name; - } - else - printf("%-20s -> %s\n", a->name, a->slab->name); - } - if (active) - printf("\n"); -} - - -static void rename_slabs(void) -{ - struct slabinfo *s; - struct aliasinfo *a; - - for (s = slabinfo; s < slabinfo + slabs; s++) { - if (*s->name != ':') - continue; - - if (s->refs > 1 && !show_first_alias) - continue; - - a = find_one_alias(s); - - if (a) - s->name = a->name; - else { - s->name = "*"; - actual_slabs--; - } - } -} - -static int slab_mismatch(char *slab) -{ - return regexec(&pattern, slab, 0, NULL, 0); -} - -static void read_slab_dir(void) -{ - DIR *dir; - struct dirent *de; - struct slabinfo *slab = slabinfo; - struct aliasinfo *alias = aliasinfo; - char *p; - char *t; - int count; - - if (chdir("/sys/kernel/slab") && chdir("/sys/slab")) - fatal("SYSFS support for SLUB not active\n"); - - dir = opendir("."); - while ((de = readdir(dir))) { - if (de->d_name[0] == '.' || - (de->d_name[0] != ':' && slab_mismatch(de->d_name))) - continue; - switch (de->d_type) { - case DT_LNK: - alias->name = strdup(de->d_name); - count = readlink(de->d_name, buffer, sizeof(buffer)); - - if (count < 0) - fatal("Cannot read symlink %s\n", de->d_name); - - buffer[count] = 0; - p = buffer + count; - while (p > buffer && p[-1] != '/') - p--; - alias->ref = strdup(p); - alias++; - break; - case DT_DIR: - if (chdir(de->d_name)) - fatal("Unable to access slab %s\n", slab->name); - slab->name = strdup(de->d_name); - slab->alias = 0; - slab->refs = 0; - slab->aliases = get_obj("aliases"); - slab->align = get_obj("align"); - slab->cache_dma = get_obj("cache_dma"); - slab->cpu_slabs = get_obj("cpu_slabs"); - slab->destroy_by_rcu = get_obj("destroy_by_rcu"); - slab->hwcache_align = get_obj("hwcache_align"); - slab->object_size = get_obj("object_size"); - slab->objects = get_obj("objects"); - slab->objects_partial = get_obj("objects_partial"); - slab->objects_total = get_obj("objects_total"); - slab->objs_per_slab = get_obj("objs_per_slab"); - slab->order = get_obj("order"); - slab->partial = get_obj("partial"); - slab->partial = get_obj_and_str("partial", &t); - decode_numa_list(slab->numa_partial, t); - free(t); - slab->poison = get_obj("poison"); - slab->reclaim_account = get_obj("reclaim_account"); - slab->red_zone = get_obj("red_zone"); - slab->sanity_checks = get_obj("sanity_checks"); - slab->slab_size = get_obj("slab_size"); - slab->slabs = get_obj_and_str("slabs", &t); - decode_numa_list(slab->numa, t); - free(t); - slab->store_user = get_obj("store_user"); - slab->trace = get_obj("trace"); - slab->alloc_fastpath = get_obj("alloc_fastpath"); - slab->alloc_slowpath = get_obj("alloc_slowpath"); - slab->free_fastpath = get_obj("free_fastpath"); - slab->free_slowpath = get_obj("free_slowpath"); - slab->free_frozen= get_obj("free_frozen"); - slab->free_add_partial = get_obj("free_add_partial"); - slab->free_remove_partial = get_obj("free_remove_partial"); - slab->alloc_from_partial = get_obj("alloc_from_partial"); - slab->alloc_slab = get_obj("alloc_slab"); - slab->alloc_refill = get_obj("alloc_refill"); - slab->free_slab = get_obj("free_slab"); - slab->cpuslab_flush = get_obj("cpuslab_flush"); - slab->deactivate_full = get_obj("deactivate_full"); - slab->deactivate_empty = get_obj("deactivate_empty"); - slab->deactivate_to_head = get_obj("deactivate_to_head"); - slab->deactivate_to_tail = get_obj("deactivate_to_tail"); - slab->deactivate_remote_frees = get_obj("deactivate_remote_frees"); - slab->order_fallback = get_obj("order_fallback"); - chdir(".."); - if (slab->name[0] == ':') - alias_targets++; - slab++; - break; - default : - fatal("Unknown file type %lx\n", de->d_type); - } - } - closedir(dir); - slabs = slab - slabinfo; - actual_slabs = slabs; - aliases = alias - aliasinfo; - if (slabs > MAX_SLABS) - fatal("Too many slabs\n"); - if (aliases > MAX_ALIASES) - fatal("Too many aliases\n"); -} - -static void output_slabs(void) -{ - struct slabinfo *slab; - - for (slab = slabinfo; slab < slabinfo + slabs; slab++) { - - if (slab->alias) - continue; - - - if (show_numa) - slab_numa(slab, 0); - else if (show_track) - show_tracking(slab); - else if (validate) - slab_validate(slab); - else if (shrink) - slab_shrink(slab); - else if (set_debug) - slab_debug(slab); - else if (show_ops) - ops(slab); - else if (show_slab) - slabcache(slab); - else if (show_report) - report(slab); - } -} - -struct option opts[] = { - { "aliases", 0, NULL, 'a' }, - { "activity", 0, NULL, 'A' }, - { "debug", 2, NULL, 'd' }, - { "display-activity", 0, NULL, 'D' }, - { "empty", 0, NULL, 'e' }, - { "first-alias", 0, NULL, 'f' }, - { "help", 0, NULL, 'h' }, - { "inverted", 0, NULL, 'i'}, - { "numa", 0, NULL, 'n' }, - { "ops", 0, NULL, 'o' }, - { "report", 0, NULL, 'r' }, - { "shrink", 0, NULL, 's' }, - { "slabs", 0, NULL, 'l' }, - { "track", 0, NULL, 't'}, - { "validate", 0, NULL, 'v' }, - { "zero", 0, NULL, 'z' }, - { "1ref", 0, NULL, '1'}, - { NULL, 0, NULL, 0 } -}; - -int main(int argc, char *argv[]) -{ - int c; - int err; - char *pattern_source; - - page_size = getpagesize(); - - while ((c = getopt_long(argc, argv, "aAd::Defhil1noprstvzTS", - opts, NULL)) != -1) - switch (c) { - case '1': - show_single_ref = 1; - break; - case 'a': - show_alias = 1; - break; - case 'A': - sort_active = 1; - break; - case 'd': - set_debug = 1; - if (!debug_opt_scan(optarg)) - fatal("Invalid debug option '%s'\n", optarg); - break; - case 'D': - show_activity = 1; - break; - case 'e': - show_empty = 1; - break; - case 'f': - show_first_alias = 1; - break; - case 'h': - usage(); - return 0; - case 'i': - show_inverted = 1; - break; - case 'n': - show_numa = 1; - break; - case 'o': - show_ops = 1; - break; - case 'r': - show_report = 1; - break; - case 's': - shrink = 1; - break; - case 'l': - show_slab = 1; - break; - case 't': - show_track = 1; - break; - case 'v': - validate = 1; - break; - case 'z': - skip_zero = 0; - break; - case 'T': - show_totals = 1; - break; - case 'S': - sort_size = 1; - break; - - default: - fatal("%s: Invalid option '%c'\n", argv[0], optopt); - - } - - if (!show_slab && !show_alias && !show_track && !show_report - && !validate && !shrink && !set_debug && !show_ops) - show_slab = 1; - - if (argc > optind) - pattern_source = argv[optind]; - else - pattern_source = ".*"; - - err = regcomp(&pattern, pattern_source, REG_ICASE|REG_NOSUB); - if (err) - fatal("%s: Invalid pattern '%s' code %d\n", - argv[0], pattern_source, err); - read_slab_dir(); - if (show_alias) - alias(); - else - if (show_totals) - totals(); - else { - link_slabs(); - rename_slabs(); - sort_slabs(); - output_slabs(); - } - return 0; -} diff --git a/tools/slub/slabinfo.c b/tools/slub/slabinfo.c new file mode 100644 index 000000000000..516551c9f172 --- /dev/null +++ b/tools/slub/slabinfo.c @@ -0,0 +1,1364 @@ +/* + * Slabinfo: Tool to get reports about slabs + * + * (C) 2007 sgi, Christoph Lameter + * + * Compile by: + * + * gcc -o slabinfo slabinfo.c + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MAX_SLABS 500 +#define MAX_ALIASES 500 +#define MAX_NODES 1024 + +struct slabinfo { + char *name; + int alias; + int refs; + int aliases, align, cache_dma, cpu_slabs, destroy_by_rcu; + int hwcache_align, object_size, objs_per_slab; + int sanity_checks, slab_size, store_user, trace; + int order, poison, reclaim_account, red_zone; + unsigned long partial, objects, slabs, objects_partial, objects_total; + unsigned long alloc_fastpath, alloc_slowpath; + unsigned long free_fastpath, free_slowpath; + unsigned long free_frozen, free_add_partial, free_remove_partial; + unsigned long alloc_from_partial, alloc_slab, free_slab, alloc_refill; + unsigned long cpuslab_flush, deactivate_full, deactivate_empty; + unsigned long deactivate_to_head, deactivate_to_tail; + unsigned long deactivate_remote_frees, order_fallback; + int numa[MAX_NODES]; + int numa_partial[MAX_NODES]; +} slabinfo[MAX_SLABS]; + +struct aliasinfo { + char *name; + char *ref; + struct slabinfo *slab; +} aliasinfo[MAX_ALIASES]; + +int slabs = 0; +int actual_slabs = 0; +int aliases = 0; +int alias_targets = 0; +int highest_node = 0; + +char buffer[4096]; + +int show_empty = 0; +int show_report = 0; +int show_alias = 0; +int show_slab = 0; +int skip_zero = 1; +int show_numa = 0; +int show_track = 0; +int show_first_alias = 0; +int validate = 0; +int shrink = 0; +int show_inverted = 0; +int show_single_ref = 0; +int show_totals = 0; +int sort_size = 0; +int sort_active = 0; +int set_debug = 0; +int show_ops = 0; +int show_activity = 0; + +/* Debug options */ +int sanity = 0; +int redzone = 0; +int poison = 0; +int tracking = 0; +int tracing = 0; + +int page_size; + +regex_t pattern; + +static void fatal(const char *x, ...) +{ + va_list ap; + + va_start(ap, x); + vfprintf(stderr, x, ap); + va_end(ap); + exit(EXIT_FAILURE); +} + +static void usage(void) +{ + printf("slabinfo 5/7/2007. (c) 2007 sgi.\n\n" + "slabinfo [-ahnpvtsz] [-d debugopts] [slab-regexp]\n" + "-a|--aliases Show aliases\n" + "-A|--activity Most active slabs first\n" + "-d|--debug= Set/Clear Debug options\n" + "-D|--display-active Switch line format to activity\n" + "-e|--empty Show empty slabs\n" + "-f|--first-alias Show first alias\n" + "-h|--help Show usage information\n" + "-i|--inverted Inverted list\n" + "-l|--slabs Show slabs\n" + "-n|--numa Show NUMA information\n" + "-o|--ops Show kmem_cache_ops\n" + "-s|--shrink Shrink slabs\n" + "-r|--report Detailed report on single slabs\n" + "-S|--Size Sort by size\n" + "-t|--tracking Show alloc/free information\n" + "-T|--Totals Show summary information\n" + "-v|--validate Validate slabs\n" + "-z|--zero Include empty slabs\n" + "-1|--1ref Single reference\n" + "\nValid debug options (FZPUT may be combined)\n" + "a / A Switch on all debug options (=FZUP)\n" + "- Switch off all debug options\n" + "f / F Sanity Checks (SLAB_DEBUG_FREE)\n" + "z / Z Redzoning\n" + "p / P Poisoning\n" + "u / U Tracking\n" + "t / T Tracing\n" + ); +} + +static unsigned long read_obj(const char *name) +{ + FILE *f = fopen(name, "r"); + + if (!f) + buffer[0] = 0; + else { + if (!fgets(buffer, sizeof(buffer), f)) + buffer[0] = 0; + fclose(f); + if (buffer[strlen(buffer)] == '\n') + buffer[strlen(buffer)] = 0; + } + return strlen(buffer); +} + + +/* + * Get the contents of an attribute + */ +static unsigned long get_obj(const char *name) +{ + if (!read_obj(name)) + return 0; + + return atol(buffer); +} + +static unsigned long get_obj_and_str(const char *name, char **x) +{ + unsigned long result = 0; + char *p; + + *x = NULL; + + if (!read_obj(name)) { + x = NULL; + return 0; + } + result = strtoul(buffer, &p, 10); + while (*p == ' ') + p++; + if (*p) + *x = strdup(p); + return result; +} + +static void set_obj(struct slabinfo *s, const char *name, int n) +{ + char x[100]; + FILE *f; + + snprintf(x, 100, "%s/%s", s->name, name); + f = fopen(x, "w"); + if (!f) + fatal("Cannot write to %s\n", x); + + fprintf(f, "%d\n", n); + fclose(f); +} + +static unsigned long read_slab_obj(struct slabinfo *s, const char *name) +{ + char x[100]; + FILE *f; + size_t l; + + snprintf(x, 100, "%s/%s", s->name, name); + f = fopen(x, "r"); + if (!f) { + buffer[0] = 0; + l = 0; + } else { + l = fread(buffer, 1, sizeof(buffer), f); + buffer[l] = 0; + fclose(f); + } + return l; +} + + +/* + * Put a size string together + */ +static int store_size(char *buffer, unsigned long value) +{ + unsigned long divisor = 1; + char trailer = 0; + int n; + + if (value > 1000000000UL) { + divisor = 100000000UL; + trailer = 'G'; + } else if (value > 1000000UL) { + divisor = 100000UL; + trailer = 'M'; + } else if (value > 1000UL) { + divisor = 100; + trailer = 'K'; + } + + value /= divisor; + n = sprintf(buffer, "%ld",value); + if (trailer) { + buffer[n] = trailer; + n++; + buffer[n] = 0; + } + if (divisor != 1) { + memmove(buffer + n - 2, buffer + n - 3, 4); + buffer[n-2] = '.'; + n++; + } + return n; +} + +static void decode_numa_list(int *numa, char *t) +{ + int node; + int nr; + + memset(numa, 0, MAX_NODES * sizeof(int)); + + if (!t) + return; + + while (*t == 'N') { + t++; + node = strtoul(t, &t, 10); + if (*t == '=') { + t++; + nr = strtoul(t, &t, 10); + numa[node] = nr; + if (node > highest_node) + highest_node = node; + } + while (*t == ' ') + t++; + } +} + +static void slab_validate(struct slabinfo *s) +{ + if (strcmp(s->name, "*") == 0) + return; + + set_obj(s, "validate", 1); +} + +static void slab_shrink(struct slabinfo *s) +{ + if (strcmp(s->name, "*") == 0) + return; + + set_obj(s, "shrink", 1); +} + +int line = 0; + +static void first_line(void) +{ + if (show_activity) + printf("Name Objects Alloc Free %%Fast Fallb O\n"); + else + printf("Name Objects Objsize Space " + "Slabs/Part/Cpu O/S O %%Fr %%Ef Flg\n"); +} + +/* + * Find the shortest alias of a slab + */ +static struct aliasinfo *find_one_alias(struct slabinfo *find) +{ + struct aliasinfo *a; + struct aliasinfo *best = NULL; + + for(a = aliasinfo;a < aliasinfo + aliases; a++) { + if (a->slab == find && + (!best || strlen(best->name) < strlen(a->name))) { + best = a; + if (strncmp(a->name,"kmall", 5) == 0) + return best; + } + } + return best; +} + +static unsigned long slab_size(struct slabinfo *s) +{ + return s->slabs * (page_size << s->order); +} + +static unsigned long slab_activity(struct slabinfo *s) +{ + return s->alloc_fastpath + s->free_fastpath + + s->alloc_slowpath + s->free_slowpath; +} + +static void slab_numa(struct slabinfo *s, int mode) +{ + int node; + + if (strcmp(s->name, "*") == 0) + return; + + if (!highest_node) { + printf("\n%s: No NUMA information available.\n", s->name); + return; + } + + if (skip_zero && !s->slabs) + return; + + if (!line) { + printf("\n%-21s:", mode ? "NUMA nodes" : "Slab"); + for(node = 0; node <= highest_node; node++) + printf(" %4d", node); + printf("\n----------------------"); + for(node = 0; node <= highest_node; node++) + printf("-----"); + printf("\n"); + } + printf("%-21s ", mode ? "All slabs" : s->name); + for(node = 0; node <= highest_node; node++) { + char b[20]; + + store_size(b, s->numa[node]); + printf(" %4s", b); + } + printf("\n"); + if (mode) { + printf("%-21s ", "Partial slabs"); + for(node = 0; node <= highest_node; node++) { + char b[20]; + + store_size(b, s->numa_partial[node]); + printf(" %4s", b); + } + printf("\n"); + } + line++; +} + +static void show_tracking(struct slabinfo *s) +{ + printf("\n%s: Kernel object allocation\n", s->name); + printf("-----------------------------------------------------------------------\n"); + if (read_slab_obj(s, "alloc_calls")) + printf(buffer); + else + printf("No Data\n"); + + printf("\n%s: Kernel object freeing\n", s->name); + printf("------------------------------------------------------------------------\n"); + if (read_slab_obj(s, "free_calls")) + printf(buffer); + else + printf("No Data\n"); + +} + +static void ops(struct slabinfo *s) +{ + if (strcmp(s->name, "*") == 0) + return; + + if (read_slab_obj(s, "ops")) { + printf("\n%s: kmem_cache operations\n", s->name); + printf("--------------------------------------------\n"); + printf(buffer); + } else + printf("\n%s has no kmem_cache operations\n", s->name); +} + +static const char *onoff(int x) +{ + if (x) + return "On "; + return "Off"; +} + +static void slab_stats(struct slabinfo *s) +{ + unsigned long total_alloc; + unsigned long total_free; + unsigned long total; + + if (!s->alloc_slab) + return; + + total_alloc = s->alloc_fastpath + s->alloc_slowpath; + total_free = s->free_fastpath + s->free_slowpath; + + if (!total_alloc) + return; + + printf("\n"); + printf("Slab Perf Counter Alloc Free %%Al %%Fr\n"); + printf("--------------------------------------------------\n"); + printf("Fastpath %8lu %8lu %3lu %3lu\n", + s->alloc_fastpath, s->free_fastpath, + s->alloc_fastpath * 100 / total_alloc, + s->free_fastpath * 100 / total_free); + printf("Slowpath %8lu %8lu %3lu %3lu\n", + total_alloc - s->alloc_fastpath, s->free_slowpath, + (total_alloc - s->alloc_fastpath) * 100 / total_alloc, + s->free_slowpath * 100 / total_free); + printf("Page Alloc %8lu %8lu %3lu %3lu\n", + s->alloc_slab, s->free_slab, + s->alloc_slab * 100 / total_alloc, + s->free_slab * 100 / total_free); + printf("Add partial %8lu %8lu %3lu %3lu\n", + s->deactivate_to_head + s->deactivate_to_tail, + s->free_add_partial, + (s->deactivate_to_head + s->deactivate_to_tail) * 100 / total_alloc, + s->free_add_partial * 100 / total_free); + printf("Remove partial %8lu %8lu %3lu %3lu\n", + s->alloc_from_partial, s->free_remove_partial, + s->alloc_from_partial * 100 / total_alloc, + s->free_remove_partial * 100 / total_free); + + printf("RemoteObj/SlabFrozen %8lu %8lu %3lu %3lu\n", + s->deactivate_remote_frees, s->free_frozen, + s->deactivate_remote_frees * 100 / total_alloc, + s->free_frozen * 100 / total_free); + + printf("Total %8lu %8lu\n\n", total_alloc, total_free); + + if (s->cpuslab_flush) + printf("Flushes %8lu\n", s->cpuslab_flush); + + if (s->alloc_refill) + printf("Refill %8lu\n", s->alloc_refill); + + total = s->deactivate_full + s->deactivate_empty + + s->deactivate_to_head + s->deactivate_to_tail; + + if (total) + printf("Deactivate Full=%lu(%lu%%) Empty=%lu(%lu%%) " + "ToHead=%lu(%lu%%) ToTail=%lu(%lu%%)\n", + s->deactivate_full, (s->deactivate_full * 100) / total, + s->deactivate_empty, (s->deactivate_empty * 100) / total, + s->deactivate_to_head, (s->deactivate_to_head * 100) / total, + s->deactivate_to_tail, (s->deactivate_to_tail * 100) / total); +} + +static void report(struct slabinfo *s) +{ + if (strcmp(s->name, "*") == 0) + return; + + printf("\nSlabcache: %-20s Aliases: %2d Order : %2d Objects: %lu\n", + s->name, s->aliases, s->order, s->objects); + if (s->hwcache_align) + printf("** Hardware cacheline aligned\n"); + if (s->cache_dma) + printf("** Memory is allocated in a special DMA zone\n"); + if (s->destroy_by_rcu) + printf("** Slabs are destroyed via RCU\n"); + if (s->reclaim_account) + printf("** Reclaim accounting active\n"); + + printf("\nSizes (bytes) Slabs Debug Memory\n"); + printf("------------------------------------------------------------------------\n"); + printf("Object : %7d Total : %7ld Sanity Checks : %s Total: %7ld\n", + s->object_size, s->slabs, onoff(s->sanity_checks), + s->slabs * (page_size << s->order)); + printf("SlabObj: %7d Full : %7ld Redzoning : %s Used : %7ld\n", + s->slab_size, s->slabs - s->partial - s->cpu_slabs, + onoff(s->red_zone), s->objects * s->object_size); + printf("SlabSiz: %7d Partial: %7ld Poisoning : %s Loss : %7ld\n", + page_size << s->order, s->partial, onoff(s->poison), + s->slabs * (page_size << s->order) - s->objects * s->object_size); + printf("Loss : %7d CpuSlab: %7d Tracking : %s Lalig: %7ld\n", + s->slab_size - s->object_size, s->cpu_slabs, onoff(s->store_user), + (s->slab_size - s->object_size) * s->objects); + printf("Align : %7d Objects: %7d Tracing : %s Lpadd: %7ld\n", + s->align, s->objs_per_slab, onoff(s->trace), + ((page_size << s->order) - s->objs_per_slab * s->slab_size) * + s->slabs); + + ops(s); + show_tracking(s); + slab_numa(s, 1); + slab_stats(s); +} + +static void slabcache(struct slabinfo *s) +{ + char size_str[20]; + char dist_str[40]; + char flags[20]; + char *p = flags; + + if (strcmp(s->name, "*") == 0) + return; + + if (actual_slabs == 1) { + report(s); + return; + } + + if (skip_zero && !show_empty && !s->slabs) + return; + + if (show_empty && s->slabs) + return; + + store_size(size_str, slab_size(s)); + snprintf(dist_str, 40, "%lu/%lu/%d", s->slabs - s->cpu_slabs, + s->partial, s->cpu_slabs); + + if (!line++) + first_line(); + + if (s->aliases) + *p++ = '*'; + if (s->cache_dma) + *p++ = 'd'; + if (s->hwcache_align) + *p++ = 'A'; + if (s->poison) + *p++ = 'P'; + if (s->reclaim_account) + *p++ = 'a'; + if (s->red_zone) + *p++ = 'Z'; + if (s->sanity_checks) + *p++ = 'F'; + if (s->store_user) + *p++ = 'U'; + if (s->trace) + *p++ = 'T'; + + *p = 0; + if (show_activity) { + unsigned long total_alloc; + unsigned long total_free; + + total_alloc = s->alloc_fastpath + s->alloc_slowpath; + total_free = s->free_fastpath + s->free_slowpath; + + printf("%-21s %8ld %10ld %10ld %3ld %3ld %5ld %1d\n", + s->name, s->objects, + total_alloc, total_free, + total_alloc ? (s->alloc_fastpath * 100 / total_alloc) : 0, + total_free ? (s->free_fastpath * 100 / total_free) : 0, + s->order_fallback, s->order); + } + else + printf("%-21s %8ld %7d %8s %14s %4d %1d %3ld %3ld %s\n", + s->name, s->objects, s->object_size, size_str, dist_str, + s->objs_per_slab, s->order, + s->slabs ? (s->partial * 100) / s->slabs : 100, + s->slabs ? (s->objects * s->object_size * 100) / + (s->slabs * (page_size << s->order)) : 100, + flags); +} + +/* + * Analyze debug options. Return false if something is amiss. + */ +static int debug_opt_scan(char *opt) +{ + if (!opt || !opt[0] || strcmp(opt, "-") == 0) + return 1; + + if (strcasecmp(opt, "a") == 0) { + sanity = 1; + poison = 1; + redzone = 1; + tracking = 1; + return 1; + } + + for ( ; *opt; opt++) + switch (*opt) { + case 'F' : case 'f': + if (sanity) + return 0; + sanity = 1; + break; + case 'P' : case 'p': + if (poison) + return 0; + poison = 1; + break; + + case 'Z' : case 'z': + if (redzone) + return 0; + redzone = 1; + break; + + case 'U' : case 'u': + if (tracking) + return 0; + tracking = 1; + break; + + case 'T' : case 't': + if (tracing) + return 0; + tracing = 1; + break; + default: + return 0; + } + return 1; +} + +static int slab_empty(struct slabinfo *s) +{ + if (s->objects > 0) + return 0; + + /* + * We may still have slabs even if there are no objects. Shrinking will + * remove them. + */ + if (s->slabs != 0) + set_obj(s, "shrink", 1); + + return 1; +} + +static void slab_debug(struct slabinfo *s) +{ + if (strcmp(s->name, "*") == 0) + return; + + if (sanity && !s->sanity_checks) { + set_obj(s, "sanity", 1); + } + if (!sanity && s->sanity_checks) { + if (slab_empty(s)) + set_obj(s, "sanity", 0); + else + fprintf(stderr, "%s not empty cannot disable sanity checks\n", s->name); + } + if (redzone && !s->red_zone) { + if (slab_empty(s)) + set_obj(s, "red_zone", 1); + else + fprintf(stderr, "%s not empty cannot enable redzoning\n", s->name); + } + if (!redzone && s->red_zone) { + if (slab_empty(s)) + set_obj(s, "red_zone", 0); + else + fprintf(stderr, "%s not empty cannot disable redzoning\n", s->name); + } + if (poison && !s->poison) { + if (slab_empty(s)) + set_obj(s, "poison", 1); + else + fprintf(stderr, "%s not empty cannot enable poisoning\n", s->name); + } + if (!poison && s->poison) { + if (slab_empty(s)) + set_obj(s, "poison", 0); + else + fprintf(stderr, "%s not empty cannot disable poisoning\n", s->name); + } + if (tracking && !s->store_user) { + if (slab_empty(s)) + set_obj(s, "store_user", 1); + else + fprintf(stderr, "%s not empty cannot enable tracking\n", s->name); + } + if (!tracking && s->store_user) { + if (slab_empty(s)) + set_obj(s, "store_user", 0); + else + fprintf(stderr, "%s not empty cannot disable tracking\n", s->name); + } + if (tracing && !s->trace) { + if (slabs == 1) + set_obj(s, "trace", 1); + else + fprintf(stderr, "%s can only enable trace for one slab at a time\n", s->name); + } + if (!tracing && s->trace) + set_obj(s, "trace", 1); +} + +static void totals(void) +{ + struct slabinfo *s; + + int used_slabs = 0; + char b1[20], b2[20], b3[20], b4[20]; + unsigned long long max = 1ULL << 63; + + /* Object size */ + unsigned long long min_objsize = max, max_objsize = 0, avg_objsize; + + /* Number of partial slabs in a slabcache */ + unsigned long long min_partial = max, max_partial = 0, + avg_partial, total_partial = 0; + + /* Number of slabs in a slab cache */ + unsigned long long min_slabs = max, max_slabs = 0, + avg_slabs, total_slabs = 0; + + /* Size of the whole slab */ + unsigned long long min_size = max, max_size = 0, + avg_size, total_size = 0; + + /* Bytes used for object storage in a slab */ + unsigned long long min_used = max, max_used = 0, + avg_used, total_used = 0; + + /* Waste: Bytes used for alignment and padding */ + unsigned long long min_waste = max, max_waste = 0, + avg_waste, total_waste = 0; + /* Number of objects in a slab */ + unsigned long long min_objects = max, max_objects = 0, + avg_objects, total_objects = 0; + /* Waste per object */ + unsigned long long min_objwaste = max, + max_objwaste = 0, avg_objwaste, + total_objwaste = 0; + + /* Memory per object */ + unsigned long long min_memobj = max, + max_memobj = 0, avg_memobj, + total_objsize = 0; + + /* Percentage of partial slabs per slab */ + unsigned long min_ppart = 100, max_ppart = 0, + avg_ppart, total_ppart = 0; + + /* Number of objects in partial slabs */ + unsigned long min_partobj = max, max_partobj = 0, + avg_partobj, total_partobj = 0; + + /* Percentage of partial objects of all objects in a slab */ + unsigned long min_ppartobj = 100, max_ppartobj = 0, + avg_ppartobj, total_ppartobj = 0; + + + for (s = slabinfo; s < slabinfo + slabs; s++) { + unsigned long long size; + unsigned long used; + unsigned long long wasted; + unsigned long long objwaste; + unsigned long percentage_partial_slabs; + unsigned long percentage_partial_objs; + + if (!s->slabs || !s->objects) + continue; + + used_slabs++; + + size = slab_size(s); + used = s->objects * s->object_size; + wasted = size - used; + objwaste = s->slab_size - s->object_size; + + percentage_partial_slabs = s->partial * 100 / s->slabs; + if (percentage_partial_slabs > 100) + percentage_partial_slabs = 100; + + percentage_partial_objs = s->objects_partial * 100 + / s->objects; + + if (percentage_partial_objs > 100) + percentage_partial_objs = 100; + + if (s->object_size < min_objsize) + min_objsize = s->object_size; + if (s->partial < min_partial) + min_partial = s->partial; + if (s->slabs < min_slabs) + min_slabs = s->slabs; + if (size < min_size) + min_size = size; + if (wasted < min_waste) + min_waste = wasted; + if (objwaste < min_objwaste) + min_objwaste = objwaste; + if (s->objects < min_objects) + min_objects = s->objects; + if (used < min_used) + min_used = used; + if (s->objects_partial < min_partobj) + min_partobj = s->objects_partial; + if (percentage_partial_slabs < min_ppart) + min_ppart = percentage_partial_slabs; + if (percentage_partial_objs < min_ppartobj) + min_ppartobj = percentage_partial_objs; + if (s->slab_size < min_memobj) + min_memobj = s->slab_size; + + if (s->object_size > max_objsize) + max_objsize = s->object_size; + if (s->partial > max_partial) + max_partial = s->partial; + if (s->slabs > max_slabs) + max_slabs = s->slabs; + if (size > max_size) + max_size = size; + if (wasted > max_waste) + max_waste = wasted; + if (objwaste > max_objwaste) + max_objwaste = objwaste; + if (s->objects > max_objects) + max_objects = s->objects; + if (used > max_used) + max_used = used; + if (s->objects_partial > max_partobj) + max_partobj = s->objects_partial; + if (percentage_partial_slabs > max_ppart) + max_ppart = percentage_partial_slabs; + if (percentage_partial_objs > max_ppartobj) + max_ppartobj = percentage_partial_objs; + if (s->slab_size > max_memobj) + max_memobj = s->slab_size; + + total_partial += s->partial; + total_slabs += s->slabs; + total_size += size; + total_waste += wasted; + + total_objects += s->objects; + total_used += used; + total_partobj += s->objects_partial; + total_ppart += percentage_partial_slabs; + total_ppartobj += percentage_partial_objs; + + total_objwaste += s->objects * objwaste; + total_objsize += s->objects * s->slab_size; + } + + if (!total_objects) { + printf("No objects\n"); + return; + } + if (!used_slabs) { + printf("No slabs\n"); + return; + } + + /* Per slab averages */ + avg_partial = total_partial / used_slabs; + avg_slabs = total_slabs / used_slabs; + avg_size = total_size / used_slabs; + avg_waste = total_waste / used_slabs; + + avg_objects = total_objects / used_slabs; + avg_used = total_used / used_slabs; + avg_partobj = total_partobj / used_slabs; + avg_ppart = total_ppart / used_slabs; + avg_ppartobj = total_ppartobj / used_slabs; + + /* Per object object sizes */ + avg_objsize = total_used / total_objects; + avg_objwaste = total_objwaste / total_objects; + avg_partobj = total_partobj * 100 / total_objects; + avg_memobj = total_objsize / total_objects; + + printf("Slabcache Totals\n"); + printf("----------------\n"); + printf("Slabcaches : %3d Aliases : %3d->%-3d Active: %3d\n", + slabs, aliases, alias_targets, used_slabs); + + store_size(b1, total_size);store_size(b2, total_waste); + store_size(b3, total_waste * 100 / total_used); + printf("Memory used: %6s # Loss : %6s MRatio:%6s%%\n", b1, b2, b3); + + store_size(b1, total_objects);store_size(b2, total_partobj); + store_size(b3, total_partobj * 100 / total_objects); + printf("# Objects : %6s # PartObj: %6s ORatio:%6s%%\n", b1, b2, b3); + + printf("\n"); + printf("Per Cache Average Min Max Total\n"); + printf("---------------------------------------------------------\n"); + + store_size(b1, avg_objects);store_size(b2, min_objects); + store_size(b3, max_objects);store_size(b4, total_objects); + printf("#Objects %10s %10s %10s %10s\n", + b1, b2, b3, b4); + + store_size(b1, avg_slabs);store_size(b2, min_slabs); + store_size(b3, max_slabs);store_size(b4, total_slabs); + printf("#Slabs %10s %10s %10s %10s\n", + b1, b2, b3, b4); + + store_size(b1, avg_partial);store_size(b2, min_partial); + store_size(b3, max_partial);store_size(b4, total_partial); + printf("#PartSlab %10s %10s %10s %10s\n", + b1, b2, b3, b4); + store_size(b1, avg_ppart);store_size(b2, min_ppart); + store_size(b3, max_ppart); + store_size(b4, total_partial * 100 / total_slabs); + printf("%%PartSlab%10s%% %10s%% %10s%% %10s%%\n", + b1, b2, b3, b4); + + store_size(b1, avg_partobj);store_size(b2, min_partobj); + store_size(b3, max_partobj); + store_size(b4, total_partobj); + printf("PartObjs %10s %10s %10s %10s\n", + b1, b2, b3, b4); + + store_size(b1, avg_ppartobj);store_size(b2, min_ppartobj); + store_size(b3, max_ppartobj); + store_size(b4, total_partobj * 100 / total_objects); + printf("%% PartObj%10s%% %10s%% %10s%% %10s%%\n", + b1, b2, b3, b4); + + store_size(b1, avg_size);store_size(b2, min_size); + store_size(b3, max_size);store_size(b4, total_size); + printf("Memory %10s %10s %10s %10s\n", + b1, b2, b3, b4); + + store_size(b1, avg_used);store_size(b2, min_used); + store_size(b3, max_used);store_size(b4, total_used); + printf("Used %10s %10s %10s %10s\n", + b1, b2, b3, b4); + + store_size(b1, avg_waste);store_size(b2, min_waste); + store_size(b3, max_waste);store_size(b4, total_waste); + printf("Loss %10s %10s %10s %10s\n", + b1, b2, b3, b4); + + printf("\n"); + printf("Per Object Average Min Max\n"); + printf("---------------------------------------------\n"); + + store_size(b1, avg_memobj);store_size(b2, min_memobj); + store_size(b3, max_memobj); + printf("Memory %10s %10s %10s\n", + b1, b2, b3); + store_size(b1, avg_objsize);store_size(b2, min_objsize); + store_size(b3, max_objsize); + printf("User %10s %10s %10s\n", + b1, b2, b3); + + store_size(b1, avg_objwaste);store_size(b2, min_objwaste); + store_size(b3, max_objwaste); + printf("Loss %10s %10s %10s\n", + b1, b2, b3); +} + +static void sort_slabs(void) +{ + struct slabinfo *s1,*s2; + + for (s1 = slabinfo; s1 < slabinfo + slabs; s1++) { + for (s2 = s1 + 1; s2 < slabinfo + slabs; s2++) { + int result; + + if (sort_size) + result = slab_size(s1) < slab_size(s2); + else if (sort_active) + result = slab_activity(s1) < slab_activity(s2); + else + result = strcasecmp(s1->name, s2->name); + + if (show_inverted) + result = -result; + + if (result > 0) { + struct slabinfo t; + + memcpy(&t, s1, sizeof(struct slabinfo)); + memcpy(s1, s2, sizeof(struct slabinfo)); + memcpy(s2, &t, sizeof(struct slabinfo)); + } + } + } +} + +static void sort_aliases(void) +{ + struct aliasinfo *a1,*a2; + + for (a1 = aliasinfo; a1 < aliasinfo + aliases; a1++) { + for (a2 = a1 + 1; a2 < aliasinfo + aliases; a2++) { + char *n1, *n2; + + n1 = a1->name; + n2 = a2->name; + if (show_alias && !show_inverted) { + n1 = a1->ref; + n2 = a2->ref; + } + if (strcasecmp(n1, n2) > 0) { + struct aliasinfo t; + + memcpy(&t, a1, sizeof(struct aliasinfo)); + memcpy(a1, a2, sizeof(struct aliasinfo)); + memcpy(a2, &t, sizeof(struct aliasinfo)); + } + } + } +} + +static void link_slabs(void) +{ + struct aliasinfo *a; + struct slabinfo *s; + + for (a = aliasinfo; a < aliasinfo + aliases; a++) { + + for (s = slabinfo; s < slabinfo + slabs; s++) + if (strcmp(a->ref, s->name) == 0) { + a->slab = s; + s->refs++; + break; + } + if (s == slabinfo + slabs) + fatal("Unresolved alias %s\n", a->ref); + } +} + +static void alias(void) +{ + struct aliasinfo *a; + char *active = NULL; + + sort_aliases(); + link_slabs(); + + for(a = aliasinfo; a < aliasinfo + aliases; a++) { + + if (!show_single_ref && a->slab->refs == 1) + continue; + + if (!show_inverted) { + if (active) { + if (strcmp(a->slab->name, active) == 0) { + printf(" %s", a->name); + continue; + } + } + printf("\n%-12s <- %s", a->slab->name, a->name); + active = a->slab->name; + } + else + printf("%-20s -> %s\n", a->name, a->slab->name); + } + if (active) + printf("\n"); +} + + +static void rename_slabs(void) +{ + struct slabinfo *s; + struct aliasinfo *a; + + for (s = slabinfo; s < slabinfo + slabs; s++) { + if (*s->name != ':') + continue; + + if (s->refs > 1 && !show_first_alias) + continue; + + a = find_one_alias(s); + + if (a) + s->name = a->name; + else { + s->name = "*"; + actual_slabs--; + } + } +} + +static int slab_mismatch(char *slab) +{ + return regexec(&pattern, slab, 0, NULL, 0); +} + +static void read_slab_dir(void) +{ + DIR *dir; + struct dirent *de; + struct slabinfo *slab = slabinfo; + struct aliasinfo *alias = aliasinfo; + char *p; + char *t; + int count; + + if (chdir("/sys/kernel/slab") && chdir("/sys/slab")) + fatal("SYSFS support for SLUB not active\n"); + + dir = opendir("."); + while ((de = readdir(dir))) { + if (de->d_name[0] == '.' || + (de->d_name[0] != ':' && slab_mismatch(de->d_name))) + continue; + switch (de->d_type) { + case DT_LNK: + alias->name = strdup(de->d_name); + count = readlink(de->d_name, buffer, sizeof(buffer)); + + if (count < 0) + fatal("Cannot read symlink %s\n", de->d_name); + + buffer[count] = 0; + p = buffer + count; + while (p > buffer && p[-1] != '/') + p--; + alias->ref = strdup(p); + alias++; + break; + case DT_DIR: + if (chdir(de->d_name)) + fatal("Unable to access slab %s\n", slab->name); + slab->name = strdup(de->d_name); + slab->alias = 0; + slab->refs = 0; + slab->aliases = get_obj("aliases"); + slab->align = get_obj("align"); + slab->cache_dma = get_obj("cache_dma"); + slab->cpu_slabs = get_obj("cpu_slabs"); + slab->destroy_by_rcu = get_obj("destroy_by_rcu"); + slab->hwcache_align = get_obj("hwcache_align"); + slab->object_size = get_obj("object_size"); + slab->objects = get_obj("objects"); + slab->objects_partial = get_obj("objects_partial"); + slab->objects_total = get_obj("objects_total"); + slab->objs_per_slab = get_obj("objs_per_slab"); + slab->order = get_obj("order"); + slab->partial = get_obj("partial"); + slab->partial = get_obj_and_str("partial", &t); + decode_numa_list(slab->numa_partial, t); + free(t); + slab->poison = get_obj("poison"); + slab->reclaim_account = get_obj("reclaim_account"); + slab->red_zone = get_obj("red_zone"); + slab->sanity_checks = get_obj("sanity_checks"); + slab->slab_size = get_obj("slab_size"); + slab->slabs = get_obj_and_str("slabs", &t); + decode_numa_list(slab->numa, t); + free(t); + slab->store_user = get_obj("store_user"); + slab->trace = get_obj("trace"); + slab->alloc_fastpath = get_obj("alloc_fastpath"); + slab->alloc_slowpath = get_obj("alloc_slowpath"); + slab->free_fastpath = get_obj("free_fastpath"); + slab->free_slowpath = get_obj("free_slowpath"); + slab->free_frozen= get_obj("free_frozen"); + slab->free_add_partial = get_obj("free_add_partial"); + slab->free_remove_partial = get_obj("free_remove_partial"); + slab->alloc_from_partial = get_obj("alloc_from_partial"); + slab->alloc_slab = get_obj("alloc_slab"); + slab->alloc_refill = get_obj("alloc_refill"); + slab->free_slab = get_obj("free_slab"); + slab->cpuslab_flush = get_obj("cpuslab_flush"); + slab->deactivate_full = get_obj("deactivate_full"); + slab->deactivate_empty = get_obj("deactivate_empty"); + slab->deactivate_to_head = get_obj("deactivate_to_head"); + slab->deactivate_to_tail = get_obj("deactivate_to_tail"); + slab->deactivate_remote_frees = get_obj("deactivate_remote_frees"); + slab->order_fallback = get_obj("order_fallback"); + chdir(".."); + if (slab->name[0] == ':') + alias_targets++; + slab++; + break; + default : + fatal("Unknown file type %lx\n", de->d_type); + } + } + closedir(dir); + slabs = slab - slabinfo; + actual_slabs = slabs; + aliases = alias - aliasinfo; + if (slabs > MAX_SLABS) + fatal("Too many slabs\n"); + if (aliases > MAX_ALIASES) + fatal("Too many aliases\n"); +} + +static void output_slabs(void) +{ + struct slabinfo *slab; + + for (slab = slabinfo; slab < slabinfo + slabs; slab++) { + + if (slab->alias) + continue; + + + if (show_numa) + slab_numa(slab, 0); + else if (show_track) + show_tracking(slab); + else if (validate) + slab_validate(slab); + else if (shrink) + slab_shrink(slab); + else if (set_debug) + slab_debug(slab); + else if (show_ops) + ops(slab); + else if (show_slab) + slabcache(slab); + else if (show_report) + report(slab); + } +} + +struct option opts[] = { + { "aliases", 0, NULL, 'a' }, + { "activity", 0, NULL, 'A' }, + { "debug", 2, NULL, 'd' }, + { "display-activity", 0, NULL, 'D' }, + { "empty", 0, NULL, 'e' }, + { "first-alias", 0, NULL, 'f' }, + { "help", 0, NULL, 'h' }, + { "inverted", 0, NULL, 'i'}, + { "numa", 0, NULL, 'n' }, + { "ops", 0, NULL, 'o' }, + { "report", 0, NULL, 'r' }, + { "shrink", 0, NULL, 's' }, + { "slabs", 0, NULL, 'l' }, + { "track", 0, NULL, 't'}, + { "validate", 0, NULL, 'v' }, + { "zero", 0, NULL, 'z' }, + { "1ref", 0, NULL, '1'}, + { NULL, 0, NULL, 0 } +}; + +int main(int argc, char *argv[]) +{ + int c; + int err; + char *pattern_source; + + page_size = getpagesize(); + + while ((c = getopt_long(argc, argv, "aAd::Defhil1noprstvzTS", + opts, NULL)) != -1) + switch (c) { + case '1': + show_single_ref = 1; + break; + case 'a': + show_alias = 1; + break; + case 'A': + sort_active = 1; + break; + case 'd': + set_debug = 1; + if (!debug_opt_scan(optarg)) + fatal("Invalid debug option '%s'\n", optarg); + break; + case 'D': + show_activity = 1; + break; + case 'e': + show_empty = 1; + break; + case 'f': + show_first_alias = 1; + break; + case 'h': + usage(); + return 0; + case 'i': + show_inverted = 1; + break; + case 'n': + show_numa = 1; + break; + case 'o': + show_ops = 1; + break; + case 'r': + show_report = 1; + break; + case 's': + shrink = 1; + break; + case 'l': + show_slab = 1; + break; + case 't': + show_track = 1; + break; + case 'v': + validate = 1; + break; + case 'z': + skip_zero = 0; + break; + case 'T': + show_totals = 1; + break; + case 'S': + sort_size = 1; + break; + + default: + fatal("%s: Invalid option '%c'\n", argv[0], optopt); + + } + + if (!show_slab && !show_alias && !show_track && !show_report + && !validate && !shrink && !set_debug && !show_ops) + show_slab = 1; + + if (argc > optind) + pattern_source = argv[optind]; + else + pattern_source = ".*"; + + err = regcomp(&pattern, pattern_source, REG_ICASE|REG_NOSUB); + if (err) + fatal("%s: Invalid pattern '%s' code %d\n", + argv[0], pattern_source, err); + read_slab_dir(); + if (show_alias) + alias(); + else + if (show_totals) + totals(); + else { + link_slabs(); + rename_slabs(); + sort_slabs(); + output_slabs(); + } + return 0; +} -- cgit v1.2.3 From 4a92379bdfb48680a5e6775dd53a586df7b6b0b1 Mon Sep 17 00:00:00 2001 From: Richard Kennedy Date: Thu, 21 Oct 2010 10:29:19 +0100 Subject: slub tracing: move trace calls out of always inlined functions to reduce kernel code size Having the trace calls defined in the always inlined kmalloc functions in include/linux/slub_def.h causes a lot of code duplication as the trace functions get instantiated for each kamalloc call site. This can simply be removed by pushing the trace calls down into the functions in slub.c. On my x86_64 built this patch shrinks the code size of the kernel by approx 36K and also shrinks the code size of many modules -- too many to list here ;) size vmlinux (2.6.36) reports text data bss dec hex filename 5410611 743172 828928 6982711 6a8c37 vmlinux 5373738 744244 828928 6946910 6a005e vmlinux + patch The resulting kernel has had some testing & kmalloc trace still seems to work. This patch - moves trace_kmalloc out of the inlined kmalloc() and pushes it down into kmem_cache_alloc_trace() so this it only get instantiated once. - rename kmem_cache_alloc_notrace() to kmem_cache_alloc_trace() to indicate that now is does have tracing. (maybe this would better being called something like kmalloc_kmem_cache ?) - adds a new function kmalloc_order() to handle allocation and tracing of large allocations of page order. - removes tracing from the inlined kmalloc_large() replacing them with a call to kmalloc_order(); - move tracing out of inlined kmalloc_node() and pushing it down into kmem_cache_alloc_node_trace - rename kmem_cache_alloc_node_notrace() to kmem_cache_alloc_node_trace() - removes the include of trace/events/kmem.h from slub_def.h. v2 - keep kmalloc_order_trace inline when !CONFIG_TRACE Signed-off-by: Richard Kennedy Signed-off-by: Pekka Enberg --- include/linux/slub_def.h | 55 +++++++++++++++++++++++------------------------- mm/slub.c | 30 ++++++++++++++++++++------ 2 files changed, 49 insertions(+), 36 deletions(-) diff --git a/include/linux/slub_def.h b/include/linux/slub_def.h index e4f5ed180b9b..8b6e8ae5d5ca 100644 --- a/include/linux/slub_def.h +++ b/include/linux/slub_def.h @@ -10,9 +10,8 @@ #include #include #include -#include -#include +#include enum stat_item { ALLOC_FASTPATH, /* Allocation from cpu slab */ @@ -216,31 +215,40 @@ static __always_inline struct kmem_cache *kmalloc_slab(size_t size) void *kmem_cache_alloc(struct kmem_cache *, gfp_t); void *__kmalloc(size_t size, gfp_t flags); +static __always_inline void * +kmalloc_order(size_t size, gfp_t flags, unsigned int order) +{ + void *ret = (void *) __get_free_pages(flags | __GFP_COMP, order); + kmemleak_alloc(ret, size, 1, flags); + return ret; +} + #ifdef CONFIG_TRACING -extern void *kmem_cache_alloc_notrace(struct kmem_cache *s, gfp_t gfpflags); +extern void * +kmem_cache_alloc_trace(struct kmem_cache *s, gfp_t gfpflags, size_t size); +extern void *kmalloc_order_trace(size_t size, gfp_t flags, unsigned int order); #else static __always_inline void * -kmem_cache_alloc_notrace(struct kmem_cache *s, gfp_t gfpflags) +kmem_cache_alloc_trace(struct kmem_cache *s, gfp_t gfpflags, size_t size) { return kmem_cache_alloc(s, gfpflags); } + +static __always_inline void * +kmalloc_order_trace(size_t size, gfp_t flags, unsigned int order) +{ + return kmalloc_order(size, flags, order); +} #endif static __always_inline void *kmalloc_large(size_t size, gfp_t flags) { unsigned int order = get_order(size); - void *ret = (void *) __get_free_pages(flags | __GFP_COMP, order); - - kmemleak_alloc(ret, size, 1, flags); - trace_kmalloc(_THIS_IP_, ret, size, PAGE_SIZE << order, flags); - - return ret; + return kmalloc_order_trace(size, flags, order); } static __always_inline void *kmalloc(size_t size, gfp_t flags) { - void *ret; - if (__builtin_constant_p(size)) { if (size > SLUB_MAX_SIZE) return kmalloc_large(size, flags); @@ -251,11 +259,7 @@ static __always_inline void *kmalloc(size_t size, gfp_t flags) if (!s) return ZERO_SIZE_PTR; - ret = kmem_cache_alloc_notrace(s, flags); - - trace_kmalloc(_THIS_IP_, ret, size, s->size, flags); - - return ret; + return kmem_cache_alloc_trace(s, flags, size); } } return __kmalloc(size, flags); @@ -266,14 +270,14 @@ void *__kmalloc_node(size_t size, gfp_t flags, int node); void *kmem_cache_alloc_node(struct kmem_cache *, gfp_t flags, int node); #ifdef CONFIG_TRACING -extern void *kmem_cache_alloc_node_notrace(struct kmem_cache *s, +extern void *kmem_cache_alloc_node_trace(struct kmem_cache *s, gfp_t gfpflags, - int node); + int node, size_t size); #else static __always_inline void * -kmem_cache_alloc_node_notrace(struct kmem_cache *s, +kmem_cache_alloc_node_trace(struct kmem_cache *s, gfp_t gfpflags, - int node) + int node, size_t size) { return kmem_cache_alloc_node(s, gfpflags, node); } @@ -281,8 +285,6 @@ kmem_cache_alloc_node_notrace(struct kmem_cache *s, static __always_inline void *kmalloc_node(size_t size, gfp_t flags, int node) { - void *ret; - if (__builtin_constant_p(size) && size <= SLUB_MAX_SIZE && !(flags & SLUB_DMA)) { struct kmem_cache *s = kmalloc_slab(size); @@ -290,12 +292,7 @@ static __always_inline void *kmalloc_node(size_t size, gfp_t flags, int node) if (!s) return ZERO_SIZE_PTR; - ret = kmem_cache_alloc_node_notrace(s, flags, node); - - trace_kmalloc_node(_THIS_IP_, ret, - size, s->size, flags, node); - - return ret; + return kmem_cache_alloc_node_trace(s, flags, node, size); } return __kmalloc_node(size, flags, node); } diff --git a/mm/slub.c b/mm/slub.c index 8fd5401bb071..7e657aa19475 100644 --- a/mm/slub.c +++ b/mm/slub.c @@ -28,6 +28,8 @@ #include #include +#include + /* * Lock order: * 1. slab_lock(page) @@ -1774,11 +1776,21 @@ void *kmem_cache_alloc(struct kmem_cache *s, gfp_t gfpflags) EXPORT_SYMBOL(kmem_cache_alloc); #ifdef CONFIG_TRACING -void *kmem_cache_alloc_notrace(struct kmem_cache *s, gfp_t gfpflags) +void *kmem_cache_alloc_trace(struct kmem_cache *s, gfp_t gfpflags, size_t size) +{ + void *ret = slab_alloc(s, gfpflags, NUMA_NO_NODE, _RET_IP_); + trace_kmalloc(_RET_IP_, ret, size, s->size, gfpflags); + return ret; +} +EXPORT_SYMBOL(kmem_cache_alloc_trace); + +void *kmalloc_order_trace(size_t size, gfp_t flags, unsigned int order) { - return slab_alloc(s, gfpflags, NUMA_NO_NODE, _RET_IP_); + void *ret = kmalloc_order(size, flags, order); + trace_kmalloc(_RET_IP_, ret, size, PAGE_SIZE << order, flags); + return ret; } -EXPORT_SYMBOL(kmem_cache_alloc_notrace); +EXPORT_SYMBOL(kmalloc_order_trace); #endif #ifdef CONFIG_NUMA @@ -1794,13 +1806,17 @@ void *kmem_cache_alloc_node(struct kmem_cache *s, gfp_t gfpflags, int node) EXPORT_SYMBOL(kmem_cache_alloc_node); #ifdef CONFIG_TRACING -void *kmem_cache_alloc_node_notrace(struct kmem_cache *s, +void *kmem_cache_alloc_node_trace(struct kmem_cache *s, gfp_t gfpflags, - int node) + int node, size_t size) { - return slab_alloc(s, gfpflags, node, _RET_IP_); + void *ret = slab_alloc(s, gfpflags, node, _RET_IP_); + + trace_kmalloc_node(_RET_IP_, ret, + size, s->size, gfpflags, node); + return ret; } -EXPORT_SYMBOL(kmem_cache_alloc_node_notrace); +EXPORT_SYMBOL(kmem_cache_alloc_node_trace); #endif #endif -- cgit v1.2.3 From 716ce5d4a6f81653507c21b152eb7629d150ce7a Mon Sep 17 00:00:00 2001 From: Pekka Enberg Date: Wed, 27 Oct 2010 18:17:38 +0300 Subject: slub: Fix build breakage in Documentation/vm This patch fixes a build breakage introduced by commit f5ac4916e9840292edd33c7a52b10364526547f3 ("slub: move slabinfo.c to tools/slub/slabinfo.c") that was repoted by Stephen: After merging the slab tree, today's linux-next build (x86_64 allmodconfig) failed like this: gcc: /scratch/sfr/next/Documentation/vm/slabinfo.c: No such file or directory gcc: no input files Caused by commit f5ac4916e9840292edd33c7a52b10364526547f3 ("slub: move slabinfo.c to tools/slub/slabinfo.c"). Missing update to Documentation/vm/Makefile? Reported-by: Stephen Rothwell Signed-off-by: Pekka Enberg --- Documentation/vm/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/vm/Makefile b/Documentation/vm/Makefile index 9dcff328b964..3fa4d0668864 100644 --- a/Documentation/vm/Makefile +++ b/Documentation/vm/Makefile @@ -2,7 +2,7 @@ obj- := dummy.o # List of programs to build -hostprogs-y := slabinfo page-types hugepage-mmap hugepage-shm map_hugetlb +hostprogs-y := page-types hugepage-mmap hugepage-shm map_hugetlb # Tell kbuild to always build the programs always := $(hostprogs-y) -- cgit v1.2.3 From 98072e4d977aabe6a39abb95951cd8bf2c2202d5 Mon Sep 17 00:00:00 2001 From: Pavel Emelyanov Date: Thu, 28 Oct 2010 13:50:37 +0400 Subject: slub: Fix slub_lock down/up imbalance There are two places, that do not release the slub_lock. Respective bugs were introduced by sysfs changes ab4d5ed5 (slub: Enable sysfs support for !CONFIG_SLUB_DEBUG) and 2bce6485 ( slub: Allow removal of slab caches during boot). Acked-by: Christoph Lameter Signed-off-by: Pavel Emelyanov Signed-off-by: Pekka Enberg --- mm/slub.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mm/slub.c b/mm/slub.c index 7e657aa19475..7796a0446b3f 100644 --- a/mm/slub.c +++ b/mm/slub.c @@ -3289,9 +3289,9 @@ struct kmem_cache *kmem_cache_create(const char *name, size_t size, kfree(n); kfree(s); } +err: up_write(&slub_lock); -err: if (flags & SLAB_PANIC) panic("Cannot create slabcache %s\n", name); else @@ -3878,6 +3878,7 @@ static ssize_t show_slab_objects(struct kmem_cache *s, x += sprintf(buf + x, " N%d=%lu", node, nodes[node]); #endif + up_read(&slub_lock); kfree(nodes); return x + sprintf(buf + x, "\n"); } -- cgit v1.2.3 From ce6120cca2589ede530200c7cfe11ac9f144333c Mon Sep 17 00:00:00 2001 From: Liam Girdwood Date: Fri, 5 Nov 2010 15:53:46 +0200 Subject: ASoC: Decouple DAPM from CODECs Decoupling Dynamic Audio Power Management (DAPM) from codec devices is required when developing ASoC further. Such as for other ASoC components to have DAPM widgets or when extending DAPM to handle cross-device paths. This patch decouples DAPM related variables from struct snd_soc_codec and moves them to new struct snd_soc_dapm_context that is used to encapsulate DAPM context of a device. ASoC core and API of DAPM functions are modified to use DAPM context instead of codec. This patch does not change current functionality and a large part of changes come because of structure and internal API changes. Core implementation is from Liam Girdwood with some minor core changes, codecs and machine driver conversions from Jarkko Nikula . Signed-off-by: Liam Girdwood Signed-off-by: Jarkko Nikula Cc: Nicolas Ferre Cc: Manuel Lauss Cc: Mike Frysinger Cc: Cliff Cai Cc: Kevin Hilman Cc: Ryan Mallon Cc: Timur Tabi Cc: Sascha Hauer Cc: Lars-Peter Clausen Cc: Arnaud Patard (Rtp) Cc: Wan ZongShun Cc: Eric Miao Cc: Jassi Brar Cc: Daniel Gloeckner Cc: Kuninori Morimoto Signed-off-by: Mark Brown --- include/sound/soc-dapm.h | 49 +++- include/sound/soc.h | 9 +- sound/soc/atmel/playpaq_wm8510.c | 11 +- sound/soc/atmel/sam9g20_wm8731.c | 17 +- sound/soc/atmel/snd-soc-afeb9260.c | 13 +- sound/soc/codecs/88pm860x-codec.c | 9 +- sound/soc/codecs/ad1836.c | 5 +- sound/soc/codecs/ad193x.c | 5 +- sound/soc/codecs/ak4535.c | 9 +- sound/soc/codecs/ak4642.c | 2 +- sound/soc/codecs/ak4671.c | 9 +- sound/soc/codecs/alc5623.c | 23 +- sound/soc/codecs/cq93vc.c | 2 +- sound/soc/codecs/cs42l51.c | 5 +- sound/soc/codecs/cx20442.c | 15 +- sound/soc/codecs/da7210.c | 2 +- sound/soc/codecs/jz4740.c | 10 +- sound/soc/codecs/max98088.c | 12 +- sound/soc/codecs/ssm2602.c | 9 +- sound/soc/codecs/stac9766.c | 3 +- sound/soc/codecs/tlv320aic23.c | 9 +- sound/soc/codecs/tlv320aic3x.c | 22 +- sound/soc/codecs/tlv320dac33.c | 15 +- sound/soc/codecs/tpa6130a2.c | 5 +- sound/soc/codecs/twl4030.c | 13 +- sound/soc/codecs/twl6040.c | 12 +- sound/soc/codecs/uda134x.c | 2 +- sound/soc/codecs/uda1380.c | 13 +- sound/soc/codecs/wm2000.c | 5 +- sound/soc/codecs/wm8350.c | 28 +- sound/soc/codecs/wm8400.c | 11 +- sound/soc/codecs/wm8510.c | 11 +- sound/soc/codecs/wm8523.c | 11 +- sound/soc/codecs/wm8580.c | 11 +- sound/soc/codecs/wm8711.c | 9 +- sound/soc/codecs/wm8728.c | 11 +- sound/soc/codecs/wm8731.c | 13 +- sound/soc/codecs/wm8741.c | 7 +- sound/soc/codecs/wm8750.c | 11 +- sound/soc/codecs/wm8753.c | 29 +- sound/soc/codecs/wm8776.c | 9 +- sound/soc/codecs/wm8804.c | 6 +- sound/soc/codecs/wm8900.c | 11 +- sound/soc/codecs/wm8903.c | 11 +- sound/soc/codecs/wm8904.c | 33 +-- sound/soc/codecs/wm8940.c | 5 +- sound/soc/codecs/wm8955.c | 11 +- sound/soc/codecs/wm8960.c | 25 +- sound/soc/codecs/wm8961.c | 11 +- sound/soc/codecs/wm8962.c | 30 ++- sound/soc/codecs/wm8971.c | 29 +- sound/soc/codecs/wm8974.c | 11 +- sound/soc/codecs/wm8978.c | 11 +- sound/soc/codecs/wm8985.c | 11 +- sound/soc/codecs/wm8988.c | 9 +- sound/soc/codecs/wm8990.c | 11 +- sound/soc/codecs/wm8993.c | 9 +- sound/soc/codecs/wm8994.c | 13 +- sound/soc/codecs/wm9081.c | 9 +- sound/soc/codecs/wm9090.c | 17 +- sound/soc/codecs/wm9705.c | 6 +- sound/soc/codecs/wm9712.c | 9 +- sound/soc/codecs/wm9713.c | 8 +- sound/soc/codecs/wm_hubs.c | 18 +- sound/soc/davinci/davinci-evm.c | 21 +- sound/soc/ep93xx/snappercl15.c | 5 +- sound/soc/imx/wm1133-ev1.c | 7 +- sound/soc/jz4740/qi_lb60.c | 13 +- sound/soc/kirkwood/kirkwood-t5325.c | 13 +- sound/soc/omap/am3517evm.c | 13 +- sound/soc/omap/ams-delta.c | 82 +++--- sound/soc/omap/n810.c | 42 +-- sound/soc/omap/omap3pandora.c | 44 +-- sound/soc/omap/osk5912.c | 13 +- sound/soc/omap/rx51.c | 25 +- sound/soc/omap/sdp3430.c | 43 +-- sound/soc/omap/sdp4430.c | 19 +- sound/soc/omap/zoom2.c | 35 +-- sound/soc/pxa/corgi.c | 51 ++-- sound/soc/pxa/e740_wm9705.c | 29 +- sound/soc/pxa/e750_wm9705.c | 29 +- sound/soc/pxa/e800_wm9712.c | 7 +- sound/soc/pxa/magician.c | 35 +-- sound/soc/pxa/mioa701_wm9713.c | 17 +- sound/soc/pxa/palm27x.c | 33 +-- sound/soc/pxa/poodle.c | 25 +- sound/soc/pxa/saarb.c | 17 +- sound/soc/pxa/spitz.c | 69 ++--- sound/soc/pxa/tavorevb3.c | 17 +- sound/soc/pxa/tosa.c | 37 +-- sound/soc/pxa/z2.c | 15 +- sound/soc/pxa/zylonite.c | 11 +- sound/soc/s3c24xx/aquila_wm8994.c | 25 +- sound/soc/s3c24xx/goni_wm8994.c | 21 +- sound/soc/s3c24xx/jive_wm8750.c | 19 +- sound/soc/s3c24xx/neo1973_gta02_wm8753.c | 41 +-- sound/soc/s3c24xx/neo1973_wm8753.c | 123 ++++----- sound/soc/s3c24xx/rx1950_uda1380.c | 11 +- sound/soc/s3c24xx/s3c24xx_simtec_hermes.c | 15 +- sound/soc/s3c24xx/s3c24xx_simtec_tlv320aic23.c | 15 +- sound/soc/s3c24xx/smartq_wm8987.c | 21 +- sound/soc/s3c24xx/smdk64xx_wm8580.c | 16 +- sound/soc/s6000/s6105-ipcam.c | 40 +-- sound/soc/sh/migor.c | 5 +- sound/soc/sh/sh7760-ac97.c | 2 +- sound/soc/soc-core.c | 29 +- sound/soc/soc-dapm.c | 355 +++++++++++++------------ sound/soc/soc-jack.c | 8 +- 108 files changed, 1239 insertions(+), 1064 deletions(-) diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h index 8fd3b41b763f..5881876e8f5b 100644 --- a/include/sound/soc-dapm.h +++ b/include/sound/soc-dapm.h @@ -297,6 +297,7 @@ enum snd_soc_dapm_type; struct snd_soc_dapm_path; struct snd_soc_dapm_pin; struct snd_soc_dapm_route; +struct snd_soc_dapm_context; int dapm_reg_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event); @@ -324,16 +325,16 @@ int snd_soc_dapm_get_pin_switch(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *uncontrol); int snd_soc_dapm_put_pin_switch(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *uncontrol); -int snd_soc_dapm_new_control(struct snd_soc_codec *codec, +int snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm, const struct snd_soc_dapm_widget *widget); -int snd_soc_dapm_new_controls(struct snd_soc_codec *codec, +int snd_soc_dapm_new_controls(struct snd_soc_dapm_context *dapm, const struct snd_soc_dapm_widget *widget, int num); /* dapm path setup */ -int snd_soc_dapm_new_widgets(struct snd_soc_codec *codec); -void snd_soc_dapm_free(struct snd_soc_codec *codec); -int snd_soc_dapm_add_routes(struct snd_soc_codec *codec, +int snd_soc_dapm_new_widgets(struct snd_soc_dapm_context *dapm); +void snd_soc_dapm_free(struct snd_soc_dapm_context *dapm); +int snd_soc_dapm_add_routes(struct snd_soc_dapm_context *dapm, const struct snd_soc_dapm_route *route, int num); /* dapm events */ @@ -343,17 +344,21 @@ void snd_soc_dapm_shutdown(struct snd_soc_card *card); /* dapm sys fs - used by the core */ int snd_soc_dapm_sys_add(struct device *dev); -void snd_soc_dapm_debugfs_init(struct snd_soc_codec *codec); +void snd_soc_dapm_debugfs_init(struct snd_soc_dapm_context *dapm); /* dapm audio pin control and status */ -int snd_soc_dapm_enable_pin(struct snd_soc_codec *codec, const char *pin); -int snd_soc_dapm_disable_pin(struct snd_soc_codec *codec, const char *pin); -int snd_soc_dapm_nc_pin(struct snd_soc_codec *codec, const char *pin); -int snd_soc_dapm_get_pin_status(struct snd_soc_codec *codec, const char *pin); -int snd_soc_dapm_sync(struct snd_soc_codec *codec); -int snd_soc_dapm_force_enable_pin(struct snd_soc_codec *codec, +int snd_soc_dapm_enable_pin(struct snd_soc_dapm_context *dapm, + const char *pin); +int snd_soc_dapm_disable_pin(struct snd_soc_dapm_context *dapm, + const char *pin); +int snd_soc_dapm_nc_pin(struct snd_soc_dapm_context *dapm, const char *pin); +int snd_soc_dapm_get_pin_status(struct snd_soc_dapm_context *dapm, + const char *pin); +int snd_soc_dapm_sync(struct snd_soc_dapm_context *dapm); +int snd_soc_dapm_force_enable_pin(struct snd_soc_dapm_context *dapm, const char *pin); -int snd_soc_dapm_ignore_suspend(struct snd_soc_codec *codec, const char *pin); +int snd_soc_dapm_ignore_suspend(struct snd_soc_dapm_context *dapm, + const char *pin); /* dapm widget types */ enum snd_soc_dapm_type { @@ -425,6 +430,7 @@ struct snd_soc_dapm_widget { char *sname; /* stream name */ struct snd_soc_codec *codec; struct list_head list; + struct snd_soc_dapm_context *dapm; /* dapm control */ short reg; /* negative reg = no direct dapm */ @@ -461,4 +467,21 @@ struct snd_soc_dapm_widget { struct list_head power_list; }; +/* DAPM context */ +struct snd_soc_dapm_context { + u32 pop_time; + struct list_head widgets; + struct list_head paths; + enum snd_soc_bias_level bias_level; + enum snd_soc_bias_level suspend_bias_level; + struct delayed_work delayed_work; + unsigned int idle_bias_off:1; /* Use BIAS_OFF instead of STANDBY */ + + struct device *dev; /* from parent - for debug */ + struct snd_soc_codec *codec; /* parent codec */ +#ifdef CONFIG_DEBUG_FS + struct dentry *debugfs_dapm; +#endif +}; + #endif diff --git a/include/sound/soc.h b/include/sound/soc.h index aaf34d7cd95e..b048e08e2cc7 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -238,6 +238,7 @@ struct soc_enum; struct snd_soc_ac97_ops; struct snd_soc_jack; struct snd_soc_jack_pin; +#include #ifdef CONFIG_GPIOLIB struct snd_soc_jack_gpio; @@ -436,7 +437,6 @@ struct snd_soc_codec { /* runtime */ struct snd_ac97 *ac97; /* for ad-hoc ac97 devices */ unsigned int active; - unsigned int idle_bias_off:1; /* Use BIAS_OFF instead of STANDBY */ unsigned int cache_only:1; /* Suppress writes to hardware */ unsigned int cache_sync:1; /* Cache needs to be synced to hardware */ unsigned int suspended:1; /* Codec is in suspend PM state */ @@ -452,12 +452,7 @@ struct snd_soc_codec { void *reg_cache; /* dapm */ - u32 pop_time; - struct list_head dapm_widgets; - struct list_head dapm_paths; - enum snd_soc_bias_level bias_level; - enum snd_soc_bias_level suspend_bias_level; - struct delayed_work delayed_work; + struct snd_soc_dapm_context dapm; #ifdef CONFIG_DEBUG_FS struct dentry *debugfs_codec_root; diff --git a/sound/soc/atmel/playpaq_wm8510.c b/sound/soc/atmel/playpaq_wm8510.c index 5f4e59f4461c..aede7e74ec34 100644 --- a/sound/soc/atmel/playpaq_wm8510.c +++ b/sound/soc/atmel/playpaq_wm8510.c @@ -318,27 +318,28 @@ static const struct snd_soc_dapm_route intercon[] = { static int playpaq_wm8510_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_dapm_context *dapm = &codec->dapm; int i; /* * Add DAPM widgets */ for (i = 0; i < ARRAY_SIZE(playpaq_dapm_widgets); i++) - snd_soc_dapm_new_control(codec, &playpaq_dapm_widgets[i]); + snd_soc_dapm_new_control(dapm, &playpaq_dapm_widgets[i]); /* * Setup audio path interconnects */ - snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon)); + snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon)); /* always connected pins */ - snd_soc_dapm_enable_pin(codec, "Int Mic"); - snd_soc_dapm_enable_pin(codec, "Ext Spk"); - snd_soc_dapm_sync(codec); + snd_soc_dapm_enable_pin(dapm, "Int Mic"); + snd_soc_dapm_enable_pin(dapm, "Ext Spk"); + snd_soc_dapm_sync(dapm); diff --git a/sound/soc/atmel/sam9g20_wm8731.c b/sound/soc/atmel/sam9g20_wm8731.c index 293569dfd0ed..da9c3037496f 100644 --- a/sound/soc/atmel/sam9g20_wm8731.c +++ b/sound/soc/atmel/sam9g20_wm8731.c @@ -140,6 +140,7 @@ static int at91sam9g20ek_wm8731_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; struct snd_soc_dai *codec_dai = rtd->codec_dai; + struct snd_soc_dapm_context *dapm = &codec->dapm; int ret; printk(KERN_DEBUG @@ -154,25 +155,25 @@ static int at91sam9g20ek_wm8731_init(struct snd_soc_pcm_runtime *rtd) } /* Add specific widgets */ - snd_soc_dapm_new_controls(codec, at91sam9g20ek_dapm_widgets, + snd_soc_dapm_new_controls(dapm, at91sam9g20ek_dapm_widgets, ARRAY_SIZE(at91sam9g20ek_dapm_widgets)); /* Set up specific audio path interconnects */ - snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon)); + snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon)); /* not connected */ - snd_soc_dapm_nc_pin(codec, "RLINEIN"); - snd_soc_dapm_nc_pin(codec, "LLINEIN"); + snd_soc_dapm_nc_pin(dapm, "RLINEIN"); + snd_soc_dapm_nc_pin(dapm, "LLINEIN"); #ifdef ENABLE_MIC_INPUT - snd_soc_dapm_enable_pin(codec, "Int Mic"); + snd_soc_dapm_enable_pin(dapm, "Int Mic"); #else - snd_soc_dapm_nc_pin(codec, "Int Mic"); + snd_soc_dapm_nc_pin(dapm, "Int Mic"); #endif /* always connected */ - snd_soc_dapm_enable_pin(codec, "Ext Spk"); + snd_soc_dapm_enable_pin(dapm, "Ext Spk"); - snd_soc_dapm_sync(codec); + snd_soc_dapm_sync(dapm); return 0; } diff --git a/sound/soc/atmel/snd-soc-afeb9260.c b/sound/soc/atmel/snd-soc-afeb9260.c index e3d283561c19..92c709ed0965 100644 --- a/sound/soc/atmel/snd-soc-afeb9260.c +++ b/sound/soc/atmel/snd-soc-afeb9260.c @@ -105,19 +105,20 @@ static const struct snd_soc_dapm_route audio_map[] = { static int afeb9260_tlv320aic23_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_dapm_context *dapm = &codec->dapm; /* Add afeb9260 specific widgets */ - snd_soc_dapm_new_controls(codec, tlv320aic23_dapm_widgets, + snd_soc_dapm_new_controls(dapm, tlv320aic23_dapm_widgets, ARRAY_SIZE(tlv320aic23_dapm_widgets)); /* Set up afeb9260 specific audio path audio_map */ - snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); + snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); - snd_soc_dapm_enable_pin(codec, "Headphone Jack"); - snd_soc_dapm_enable_pin(codec, "Line In"); - snd_soc_dapm_enable_pin(codec, "Mic Jack"); + snd_soc_dapm_enable_pin(dapm, "Headphone Jack"); + snd_soc_dapm_enable_pin(dapm, "Line In"); + snd_soc_dapm_enable_pin(dapm, "Mic Jack"); - snd_soc_dapm_sync(codec); + snd_soc_dapm_sync(dapm); return 0; } diff --git a/sound/soc/codecs/88pm860x-codec.c b/sound/soc/codecs/88pm860x-codec.c index 01d19e9f53f9..a15a3e974f0d 100644 --- a/sound/soc/codecs/88pm860x-codec.c +++ b/sound/soc/codecs/88pm860x-codec.c @@ -1172,7 +1172,7 @@ static int pm860x_set_bias_level(struct snd_soc_codec *codec, break; case SND_SOC_BIAS_STANDBY: - if (codec->bias_level == SND_SOC_BIAS_OFF) { + if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { /* Enable Audio PLL & Audio section */ data = AUDIO_PLL | AUDIO_SECTION_RESET | AUDIO_SECTION_ON; @@ -1185,7 +1185,7 @@ static int pm860x_set_bias_level(struct snd_soc_codec *codec, pm860x_set_bits(codec->control_data, REG_MISC2, data, 0); break; } - codec->bias_level = level; + codec->dapm.bias_level = level; return 0; } @@ -1346,6 +1346,7 @@ EXPORT_SYMBOL_GPL(pm860x_mic_jack_detect); static int pm860x_probe(struct snd_soc_codec *codec) { struct pm860x_priv *pm860x = snd_soc_codec_get_drvdata(codec); + struct snd_soc_dapm_context *dapm = &codec->dapm; int i, ret; pm860x->codec = codec; @@ -1374,9 +1375,9 @@ static int pm860x_probe(struct snd_soc_codec *codec) snd_soc_add_controls(codec, pm860x_snd_controls, ARRAY_SIZE(pm860x_snd_controls)); - snd_soc_dapm_new_controls(codec, pm860x_dapm_widgets, + snd_soc_dapm_new_controls(dapm, pm860x_dapm_widgets, ARRAY_SIZE(pm860x_dapm_widgets)); - snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); + snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); return 0; out_codec: diff --git a/sound/soc/codecs/ad1836.c b/sound/soc/codecs/ad1836.c index d272534c8f84..c71b05ddd752 100644 --- a/sound/soc/codecs/ad1836.c +++ b/sound/soc/codecs/ad1836.c @@ -220,6 +220,7 @@ static struct snd_soc_dai_driver ad1836_dai = { static int ad1836_probe(struct snd_soc_codec *codec) { struct ad1836_priv *ad1836 = snd_soc_codec_get_drvdata(codec); + struct snd_soc_dapm_context *dapm = &codec->dapm; int ret = 0; codec->control_data = ad1836->control_data; @@ -252,9 +253,9 @@ static int ad1836_probe(struct snd_soc_codec *codec) snd_soc_add_controls(codec, ad1836_snd_controls, ARRAY_SIZE(ad1836_snd_controls)); - snd_soc_dapm_new_controls(codec, ad1836_dapm_widgets, + snd_soc_dapm_new_controls(dapm, ad1836_dapm_widgets, ARRAY_SIZE(ad1836_dapm_widgets)); - snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths)); + snd_soc_dapm_add_routes(dapm, audio_paths, ARRAY_SIZE(audio_paths)); return ret; } diff --git a/sound/soc/codecs/ad193x.c b/sound/soc/codecs/ad193x.c index fa2834c91b9f..dc105d8aaa0f 100644 --- a/sound/soc/codecs/ad193x.c +++ b/sound/soc/codecs/ad193x.c @@ -353,6 +353,7 @@ static struct snd_soc_dai_driver ad193x_dai = { static int ad193x_probe(struct snd_soc_codec *codec) { struct ad193x_priv *ad193x = snd_soc_codec_get_drvdata(codec); + struct snd_soc_dapm_context *dapm = &codec->dapm; int ret; codec->control_data = ad193x->control_data; @@ -385,9 +386,9 @@ static int ad193x_probe(struct snd_soc_codec *codec) snd_soc_add_controls(codec, ad193x_snd_controls, ARRAY_SIZE(ad193x_snd_controls)); - snd_soc_dapm_new_controls(codec, ad193x_dapm_widgets, + snd_soc_dapm_new_controls(dapm, ad193x_dapm_widgets, ARRAY_SIZE(ad193x_dapm_widgets)); - snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths)); + snd_soc_dapm_add_routes(dapm, audio_paths, ARRAY_SIZE(audio_paths)); return ret; } diff --git a/sound/soc/codecs/ak4535.c b/sound/soc/codecs/ak4535.c index cd88c8f32a38..52abb93a7dce 100644 --- a/sound/soc/codecs/ak4535.c +++ b/sound/soc/codecs/ak4535.c @@ -290,10 +290,11 @@ static const struct snd_soc_dapm_route audio_map[] = { static int ak4535_add_widgets(struct snd_soc_codec *codec) { - snd_soc_dapm_new_controls(codec, ak4535_dapm_widgets, - ARRAY_SIZE(ak4535_dapm_widgets)); + struct snd_soc_dapm_context *dapm = &codec->dapm; - snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); + snd_soc_dapm_new_controls(dapm, ak4535_dapm_widgets, + ARRAY_SIZE(ak4535_dapm_widgets)); + snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); return 0; } @@ -399,7 +400,7 @@ static int ak4535_set_bias_level(struct snd_soc_codec *codec, ak4535_write(codec, AK4535_PM1, i & (~0x80)); break; } - codec->bias_level = level; + codec->dapm.bias_level = level; return 0; } diff --git a/sound/soc/codecs/ak4642.c b/sound/soc/codecs/ak4642.c index 90c90b7f4a2e..f00eba313dfd 100644 --- a/sound/soc/codecs/ak4642.c +++ b/sound/soc/codecs/ak4642.c @@ -26,7 +26,7 @@ #include #include #include -#include +#include #include #include diff --git a/sound/soc/codecs/ak4671.c b/sound/soc/codecs/ak4671.c index 24f5f49bb9d2..1d6573c38af4 100644 --- a/sound/soc/codecs/ak4671.c +++ b/sound/soc/codecs/ak4671.c @@ -437,10 +437,11 @@ static const struct snd_soc_dapm_route intercon[] = { static int ak4671_add_widgets(struct snd_soc_codec *codec) { - snd_soc_dapm_new_controls(codec, ak4671_dapm_widgets, - ARRAY_SIZE(ak4671_dapm_widgets)); + struct snd_soc_dapm_context *dapm = &codec->dapm; - snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon)); + snd_soc_dapm_new_controls(dapm, ak4671_dapm_widgets, + ARRAY_SIZE(ak4671_dapm_widgets)); + snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon)); return 0; } @@ -602,7 +603,7 @@ static int ak4671_set_bias_level(struct snd_soc_codec *codec, snd_soc_write(codec, AK4671_AD_DA_POWER_MANAGEMENT, 0x00); break; } - codec->bias_level = level; + codec->dapm.bias_level = level; return 0; } diff --git a/sound/soc/codecs/alc5623.c b/sound/soc/codecs/alc5623.c index fac61744f8c7..5a45067b43ba 100644 --- a/sound/soc/codecs/alc5623.c +++ b/sound/soc/codecs/alc5623.c @@ -832,7 +832,7 @@ static int alc5623_set_bias_level(struct snd_soc_codec *codec, snd_soc_write(codec, ALC5623_PWR_MANAG_ADD1, 0); break; } - codec->bias_level = level; + codec->dapm.bias_level = level; return 0; } @@ -888,10 +888,10 @@ static int alc5623_resume(struct snd_soc_codec *codec) alc5623_set_bias_level(codec, SND_SOC_BIAS_STANDBY); /* charge alc5623 caps */ - if (codec->suspend_bias_level == SND_SOC_BIAS_ON) { + if (codec->dapm.suspend_bias_level == SND_SOC_BIAS_ON) { alc5623_set_bias_level(codec, SND_SOC_BIAS_STANDBY); - codec->bias_level = SND_SOC_BIAS_ON; - alc5623_set_bias_level(codec, codec->bias_level); + codec->dapm.bias_level = SND_SOC_BIAS_ON; + alc5623_set_bias_level(codec, codec->dapm.bias_level); } return 0; @@ -900,6 +900,7 @@ static int alc5623_resume(struct snd_soc_codec *codec) static int alc5623_probe(struct snd_soc_codec *codec) { struct alc5623_priv *alc5623 = snd_soc_codec_get_drvdata(codec); + struct snd_soc_dapm_context *dapm = &codec->dapm; int ret; ret = snd_soc_codec_set_cache_io(codec, 8, 16, alc5623->control_type); @@ -943,24 +944,24 @@ static int alc5623_probe(struct snd_soc_codec *codec) snd_soc_add_controls(codec, alc5623_snd_controls, ARRAY_SIZE(alc5623_snd_controls)); - snd_soc_dapm_new_controls(codec, alc5623_dapm_widgets, + snd_soc_dapm_new_controls(dapm, alc5623_dapm_widgets, ARRAY_SIZE(alc5623_dapm_widgets)); /* set up audio path interconnects */ - snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon)); + snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon)); switch (alc5623->id) { default: case 0x21: case 0x22: - snd_soc_dapm_new_controls(codec, alc5623_dapm_amp_widgets, + snd_soc_dapm_new_controls(dapm, alc5623_dapm_amp_widgets, ARRAY_SIZE(alc5623_dapm_amp_widgets)); - snd_soc_dapm_add_routes(codec, intercon_amp_spk, - ARRAY_SIZE(intercon_amp_spk)); + snd_soc_dapm_add_routes(dapm, intercon_amp_spk, + ARRAY_SIZE(intercon_amp_spk)); break; case 0x23: - snd_soc_dapm_add_routes(codec, intercon_spk, - ARRAY_SIZE(intercon_spk)); + snd_soc_dapm_add_routes(dapm, intercon_spk, + ARRAY_SIZE(intercon_spk)); break; } diff --git a/sound/soc/codecs/cq93vc.c b/sound/soc/codecs/cq93vc.c index 823643932dde..98b9e5294cbe 100644 --- a/sound/soc/codecs/cq93vc.c +++ b/sound/soc/codecs/cq93vc.c @@ -116,7 +116,7 @@ static int cq93vc_set_bias_level(struct snd_soc_codec *codec, DAVINCI_VC_REG12_POWER_ALL_OFF); break; } - codec->bias_level = level; + codec->dapm.bias_level = level; return 0; } diff --git a/sound/soc/codecs/cs42l51.c b/sound/soc/codecs/cs42l51.c index cb086eaf4e07..a7fdca36b490 100644 --- a/sound/soc/codecs/cs42l51.c +++ b/sound/soc/codecs/cs42l51.c @@ -519,6 +519,7 @@ static struct snd_soc_dai_driver cs42l51_dai = { static int cs42l51_probe(struct snd_soc_codec *codec) { struct cs42l51_private *cs42l51 = snd_soc_codec_get_drvdata(codec); + struct snd_soc_dapm_context *dapm = &codec->dapm; int ret, reg; codec->control_data = cs42l51->control_data; @@ -550,9 +551,9 @@ static int cs42l51_probe(struct snd_soc_codec *codec) snd_soc_add_controls(codec, cs42l51_snd_controls, ARRAY_SIZE(cs42l51_snd_controls)); - snd_soc_dapm_new_controls(codec, cs42l51_dapm_widgets, + snd_soc_dapm_new_controls(dapm, cs42l51_dapm_widgets, ARRAY_SIZE(cs42l51_dapm_widgets)); - snd_soc_dapm_add_routes(codec, cs42l51_routes, + snd_soc_dapm_add_routes(dapm, cs42l51_routes, ARRAY_SIZE(cs42l51_routes)); return 0; diff --git a/sound/soc/codecs/cx20442.c b/sound/soc/codecs/cx20442.c index e8d27c8f9ba3..11beb1a77c4e 100644 --- a/sound/soc/codecs/cx20442.c +++ b/sound/soc/codecs/cx20442.c @@ -18,7 +18,7 @@ #include #include -#include +#include #include "cx20442.h" @@ -89,10 +89,11 @@ static const struct snd_soc_dapm_route cx20442_audio_map[] = { static int cx20442_add_widgets(struct snd_soc_codec *codec) { - snd_soc_dapm_new_controls(codec, cx20442_dapm_widgets, - ARRAY_SIZE(cx20442_dapm_widgets)); + struct snd_soc_dapm_context *dapm = &codec->dapm; - snd_soc_dapm_add_routes(codec, cx20442_audio_map, + snd_soc_dapm_new_controls(dapm, cx20442_dapm_widgets, + ARRAY_SIZE(cx20442_dapm_widgets)); + snd_soc_dapm_add_routes(dapm, cx20442_audio_map, ARRAY_SIZE(cx20442_audio_map)); return 0; @@ -263,7 +264,7 @@ static void v253_close(struct tty_struct *tty) /* Prevent the codec driver from further accessing the modem */ codec->hw_write = NULL; cx20442->control_data = NULL; - codec->pop_time = 0; + codec->dapm.pop_time = 0; } /* Line discipline .hangup() */ @@ -291,7 +292,7 @@ static void v253_receive(struct tty_struct *tty, /* Set up codec driver access to modem controls */ cx20442->control_data = tty; codec->hw_write = (hw_write_t)tty->ops->write; - codec->pop_time = 1; + codec->dapm.pop_time = 1; } } @@ -348,7 +349,7 @@ static int cx20442_codec_probe(struct snd_soc_codec *codec) cx20442->control_data = NULL; codec->hw_write = NULL; - codec->pop_time = 0; + codec->dapm.pop_time = 0; return 0; } diff --git a/sound/soc/codecs/da7210.c b/sound/soc/codecs/da7210.c index 58bb9b994811..92fd9d7a9221 100644 --- a/sound/soc/codecs/da7210.c +++ b/sound/soc/codecs/da7210.c @@ -21,7 +21,7 @@ #include #include #include -#include +#include #include #include diff --git a/sound/soc/codecs/jz4740.c b/sound/soc/codecs/jz4740.c index 16253ec9b022..8a45562a96d4 100644 --- a/sound/soc/codecs/jz4740.c +++ b/sound/soc/codecs/jz4740.c @@ -266,7 +266,7 @@ static int jz4740_codec_set_bias_level(struct snd_soc_codec *codec, break; case SND_SOC_BIAS_STANDBY: /* The only way to clear the suspend flag is to reset the codec */ - if (codec->bias_level == SND_SOC_BIAS_OFF) + if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) jz4740_codec_wakeup(codec); mask = JZ4740_CODEC_1_VREF_DISABLE | @@ -288,23 +288,25 @@ static int jz4740_codec_set_bias_level(struct snd_soc_codec *codec, break; } - codec->bias_level = level; + codec->dapm.bias_level = level; return 0; } static int jz4740_codec_dev_probe(struct snd_soc_codec *codec) { + struct snd_soc_dapm_context *dapm = &codec->dapm; + snd_soc_update_bits(codec, JZ4740_REG_CODEC_1, JZ4740_CODEC_1_SW2_ENABLE, JZ4740_CODEC_1_SW2_ENABLE); snd_soc_add_controls(codec, jz4740_codec_controls, ARRAY_SIZE(jz4740_codec_controls)); - snd_soc_dapm_new_controls(codec, jz4740_codec_dapm_widgets, + snd_soc_dapm_new_controls(dapm, jz4740_codec_dapm_widgets, ARRAY_SIZE(jz4740_codec_dapm_widgets)); - snd_soc_dapm_add_routes(codec, jz4740_codec_dapm_routes, + snd_soc_dapm_add_routes(dapm, jz4740_codec_dapm_routes, ARRAY_SIZE(jz4740_codec_dapm_routes)); snd_soc_dapm_new_widgets(codec); diff --git a/sound/soc/codecs/max98088.c b/sound/soc/codecs/max98088.c index bc22ee93a75d..ef06007d8895 100644 --- a/sound/soc/codecs/max98088.c +++ b/sound/soc/codecs/max98088.c @@ -1224,15 +1224,17 @@ static const struct snd_soc_dapm_route audio_map[] = { static int max98088_add_widgets(struct snd_soc_codec *codec) { - snd_soc_dapm_new_controls(codec, max98088_dapm_widgets, + struct snd_soc_dapm_context *dapm = &codec->dapm; + + snd_soc_dapm_new_controls(dapm, max98088_dapm_widgets, ARRAY_SIZE(max98088_dapm_widgets)); - snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); + snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); snd_soc_add_controls(codec, max98088_snd_controls, ARRAY_SIZE(max98088_snd_controls)); - snd_soc_dapm_new_widgets(codec); + snd_soc_dapm_new_widgets(dapm); return 0; } @@ -1617,7 +1619,7 @@ static int max98088_set_bias_level(struct snd_soc_codec *codec, break; case SND_SOC_BIAS_STANDBY: - if (codec->bias_level == SND_SOC_BIAS_OFF) + if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) max98088_sync_cache(codec); snd_soc_update_bits(codec, M98088_REG_4C_PWR_EN_IN, @@ -1630,7 +1632,7 @@ static int max98088_set_bias_level(struct snd_soc_codec *codec, codec->cache_sync = 1; break; } - codec->bias_level = level; + codec->dapm.bias_level = level; return 0; } diff --git a/sound/soc/codecs/ssm2602.c b/sound/soc/codecs/ssm2602.c index 6f38d619bf8a..adbc3e8dafc8 100644 --- a/sound/soc/codecs/ssm2602.c +++ b/sound/soc/codecs/ssm2602.c @@ -207,10 +207,11 @@ static const struct snd_soc_dapm_route audio_conn[] = { static int ssm2602_add_widgets(struct snd_soc_codec *codec) { - snd_soc_dapm_new_controls(codec, ssm2602_dapm_widgets, - ARRAY_SIZE(ssm2602_dapm_widgets)); + struct snd_soc_dapm_context *dapm = &codec->dapm; - snd_soc_dapm_add_routes(codec, audio_conn, ARRAY_SIZE(audio_conn)); + snd_soc_dapm_new_controls(dapm, ssm2602_dapm_widgets, + ARRAY_SIZE(ssm2602_dapm_widgets)); + snd_soc_dapm_add_routes(dapm, audio_conn, ARRAY_SIZE(audio_conn)); return 0; } @@ -493,7 +494,7 @@ static int ssm2602_set_bias_level(struct snd_soc_codec *codec, break; } - codec->bias_level = level; + codec->dapm.bias_level = level; return 0; } diff --git a/sound/soc/codecs/stac9766.c b/sound/soc/codecs/stac9766.c index 00d67cc8e206..8aad3a2c4f3d 100644 --- a/sound/soc/codecs/stac9766.c +++ b/sound/soc/codecs/stac9766.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include "stac9766.h" @@ -236,7 +237,7 @@ static int stac9766_set_bias_level(struct snd_soc_codec *codec, stac9766_ac97_write(codec, AC97_POWERDOWN, 0xffff); break; } - codec->bias_level = level; + codec->dapm.bias_level = level; return 0; } diff --git a/sound/soc/codecs/tlv320aic23.c b/sound/soc/codecs/tlv320aic23.c index e8652b1ae326..d9d8e844d63f 100644 --- a/sound/soc/codecs/tlv320aic23.c +++ b/sound/soc/codecs/tlv320aic23.c @@ -391,11 +391,12 @@ static int set_sample_rate_control(struct snd_soc_codec *codec, int mclk, static int tlv320aic23_add_widgets(struct snd_soc_codec *codec) { - snd_soc_dapm_new_controls(codec, tlv320aic23_dapm_widgets, - ARRAY_SIZE(tlv320aic23_dapm_widgets)); + struct snd_soc_dapm_context *dapm = &codec->dapm; + snd_soc_dapm_new_controls(dapm, tlv320aic23_dapm_widgets, + ARRAY_SIZE(tlv320aic23_dapm_widgets)); /* set up audio path interconnects */ - snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon)); + snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon)); return 0; } @@ -574,7 +575,7 @@ static int tlv320aic23_set_bias_level(struct snd_soc_codec *codec, tlv320aic23_write(codec, TLV320AIC23_PWR, 0xffff); break; } - codec->bias_level = level; + codec->dapm.bias_level = level; return 0; } diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c index fc687790188b..6173c2b4c364 100644 --- a/sound/soc/codecs/tlv320aic3x.c +++ b/sound/soc/codecs/tlv320aic3x.c @@ -183,7 +183,7 @@ static int snd_soc_dapm_put_volsw_aic3x(struct snd_kcontrol *kcontrol, if (snd_soc_test_bits(widget->codec, reg, val_mask, val)) { /* find dapm widget path assoc with kcontrol */ - list_for_each_entry(path, &widget->codec->dapm_paths, list) { + list_for_each_entry(path, &widget->dapm->paths, list) { if (path->kcontrol != kcontrol) continue; @@ -199,7 +199,7 @@ static int snd_soc_dapm_put_volsw_aic3x(struct snd_kcontrol *kcontrol, } if (found) - snd_soc_dapm_sync(widget->codec); + snd_soc_dapm_sync(widget->dapm); } ret = snd_soc_update_bits(widget->codec, reg, val_mask, val); @@ -788,17 +788,19 @@ static const struct snd_soc_dapm_route intercon_3007[] = { static int aic3x_add_widgets(struct snd_soc_codec *codec) { struct aic3x_priv *aic3x = snd_soc_codec_get_drvdata(codec); + struct snd_soc_dapm_context *dapm = &codec->dapm; - snd_soc_dapm_new_controls(codec, aic3x_dapm_widgets, + snd_soc_dapm_new_controls(dapm, aic3x_dapm_widgets, ARRAY_SIZE(aic3x_dapm_widgets)); /* set up audio path interconnects */ - snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon)); + snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon)); if (aic3x->model == AIC3X_MODEL_3007) { - snd_soc_dapm_new_controls(codec, aic3007_dapm_widgets, + snd_soc_dapm_new_controls(dapm, aic3007_dapm_widgets, ARRAY_SIZE(aic3007_dapm_widgets)); - snd_soc_dapm_add_routes(codec, intercon_3007, ARRAY_SIZE(intercon_3007)); + snd_soc_dapm_add_routes(dapm, intercon_3007, + ARRAY_SIZE(intercon_3007)); } return 0; @@ -1135,7 +1137,7 @@ static int aic3x_set_bias_level(struct snd_soc_codec *codec, case SND_SOC_BIAS_ON: break; case SND_SOC_BIAS_PREPARE: - if (codec->bias_level == SND_SOC_BIAS_STANDBY && + if (codec->dapm.bias_level == SND_SOC_BIAS_STANDBY && aic3x->master) { /* enable pll */ reg = snd_soc_read(codec, AIC3X_PLL_PROGA_REG); @@ -1146,7 +1148,7 @@ static int aic3x_set_bias_level(struct snd_soc_codec *codec, case SND_SOC_BIAS_STANDBY: if (!aic3x->power) aic3x_set_power(codec, 1); - if (codec->bias_level == SND_SOC_BIAS_PREPARE && + if (codec->dapm.bias_level == SND_SOC_BIAS_PREPARE && aic3x->master) { /* disable pll */ reg = snd_soc_read(codec, AIC3X_PLL_PROGA_REG); @@ -1159,7 +1161,7 @@ static int aic3x_set_bias_level(struct snd_soc_codec *codec, aic3x_set_power(codec, 0); break; } - codec->bias_level = level; + codec->dapm.bias_level = level; return 0; } @@ -1351,7 +1353,7 @@ static int aic3x_probe(struct snd_soc_codec *codec) codec->control_data = aic3x->control_data; aic3x->codec = codec; - codec->idle_bias_off = 1; + codec->dapm.idle_bias_off = 1; ret = snd_soc_codec_set_cache_io(codec, 8, 8, aic3x->control_type); if (ret != 0) { diff --git a/sound/soc/codecs/tlv320dac33.c b/sound/soc/codecs/tlv320dac33.c index c5ab8c805771..7149c14b289e 100644 --- a/sound/soc/codecs/tlv320dac33.c +++ b/sound/soc/codecs/tlv320dac33.c @@ -628,11 +628,12 @@ static const struct snd_soc_dapm_route audio_map[] = { static int dac33_add_widgets(struct snd_soc_codec *codec) { - snd_soc_dapm_new_controls(codec, dac33_dapm_widgets, - ARRAY_SIZE(dac33_dapm_widgets)); + struct snd_soc_dapm_context *dapm = &codec->dapm; + snd_soc_dapm_new_controls(dapm, dac33_dapm_widgets, + ARRAY_SIZE(dac33_dapm_widgets)); /* set up audio path interconnects */ - snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); + snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); return 0; } @@ -649,7 +650,7 @@ static int dac33_set_bias_level(struct snd_soc_codec *codec, case SND_SOC_BIAS_PREPARE: break; case SND_SOC_BIAS_STANDBY: - if (codec->bias_level == SND_SOC_BIAS_OFF) { + if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { /* Coming from OFF, switch on the codec */ ret = dac33_hard_power(codec, 1); if (ret != 0) @@ -660,14 +661,14 @@ static int dac33_set_bias_level(struct snd_soc_codec *codec, break; case SND_SOC_BIAS_OFF: /* Do not power off, when the codec is already off */ - if (codec->bias_level == SND_SOC_BIAS_OFF) + if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) return 0; ret = dac33_hard_power(codec, 0); if (ret != 0) return ret; break; } - codec->bias_level = level; + codec->dapm.bias_level = level; return 0; } @@ -1415,7 +1416,7 @@ static int dac33_soc_probe(struct snd_soc_codec *codec) codec->control_data = dac33->control_data; codec->hw_write = (hw_write_t) i2c_master_send; - codec->idle_bias_off = 1; + codec->dapm.idle_bias_off = 1; dac33->codec = codec; /* Read the tlv320dac33 ID registers */ diff --git a/sound/soc/codecs/tpa6130a2.c b/sound/soc/codecs/tpa6130a2.c index ee4fb201de60..f9a92ea6b50a 100644 --- a/sound/soc/codecs/tpa6130a2.c +++ b/sound/soc/codecs/tpa6130a2.c @@ -388,16 +388,17 @@ static const struct snd_soc_dapm_route audio_map[] = { int tpa6130a2_add_controls(struct snd_soc_codec *codec) { struct tpa6130a2_data *data; + struct snd_soc_dapm_context *dapm = &codec->dapm; if (tpa6130a2_client == NULL) return -ENODEV; data = i2c_get_clientdata(tpa6130a2_client); - snd_soc_dapm_new_controls(codec, tpa6130a2_dapm_widgets, + snd_soc_dapm_new_controls(dapm, tpa6130a2_dapm_widgets, ARRAY_SIZE(tpa6130a2_dapm_widgets)); - snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); + snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); if (data->id == TPA6140A2) return snd_soc_add_controls(codec, tpa6140a2_controls, diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c index cbebec6ba1ba..f4602e8b67cc 100644 --- a/sound/soc/codecs/twl4030.c +++ b/sound/soc/codecs/twl4030.c @@ -1621,10 +1621,11 @@ static const struct snd_soc_dapm_route intercon[] = { static int twl4030_add_widgets(struct snd_soc_codec *codec) { - snd_soc_dapm_new_controls(codec, twl4030_dapm_widgets, - ARRAY_SIZE(twl4030_dapm_widgets)); + struct snd_soc_dapm_context *dapm = &codec->dapm; - snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon)); + snd_soc_dapm_new_controls(dapm, twl4030_dapm_widgets, + ARRAY_SIZE(twl4030_dapm_widgets)); + snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon)); return 0; } @@ -1638,14 +1639,14 @@ static int twl4030_set_bias_level(struct snd_soc_codec *codec, case SND_SOC_BIAS_PREPARE: break; case SND_SOC_BIAS_STANDBY: - if (codec->bias_level == SND_SOC_BIAS_OFF) + if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) twl4030_codec_enable(codec, 1); break; case SND_SOC_BIAS_OFF: twl4030_codec_enable(codec, 0); break; } - codec->bias_level = level; + codec->dapm.bias_level = level; return 0; } @@ -2245,7 +2246,7 @@ static int twl4030_soc_probe(struct snd_soc_codec *codec) snd_soc_codec_set_drvdata(codec, twl4030); /* Set the defaults, and power up the codec */ twl4030->sysclk = twl4030_codec_get_mclk() / 1000; - codec->idle_bias_off = 1; + codec->dapm.idle_bias_off = 1; twl4030_init_chip(codec); diff --git a/sound/soc/codecs/twl6040.c b/sound/soc/codecs/twl6040.c index 10f6e5214511..0dd2d5397264 100644 --- a/sound/soc/codecs/twl6040.c +++ b/sound/soc/codecs/twl6040.c @@ -641,12 +641,12 @@ static const struct snd_soc_dapm_route intercon[] = { static int twl6040_add_widgets(struct snd_soc_codec *codec) { - snd_soc_dapm_new_controls(codec, twl6040_dapm_widgets, - ARRAY_SIZE(twl6040_dapm_widgets)); - - snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon)); + struct snd_soc_dapm_context *dapm = &codec->dapm; - snd_soc_dapm_new_widgets(codec); + snd_soc_dapm_new_controls(dapm, twl6040_dapm_widgets, + ARRAY_SIZE(twl6040_dapm_widgets)); + snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon)); + snd_soc_dapm_new_widgets(dapm); return 0; } @@ -739,7 +739,7 @@ static int twl6040_set_bias_level(struct snd_soc_codec *codec, break; } - codec->bias_level = level; + codec->dapm.bias_level = level; return 0; } diff --git a/sound/soc/codecs/uda134x.c b/sound/soc/codecs/uda134x.c index 7540a509a6f5..8ea81d48124a 100644 --- a/sound/soc/codecs/uda134x.c +++ b/sound/soc/codecs/uda134x.c @@ -389,7 +389,7 @@ static int uda134x_set_bias_level(struct snd_soc_codec *codec, pd->power(0); break; } - codec->bias_level = level; + codec->dapm.bias_level = level; return 0; } diff --git a/sound/soc/codecs/uda1380.c b/sound/soc/codecs/uda1380.c index 0c6c725736c6..cd6dd19fa1aa 100644 --- a/sound/soc/codecs/uda1380.c +++ b/sound/soc/codecs/uda1380.c @@ -414,10 +414,11 @@ static const struct snd_soc_dapm_route audio_map[] = { static int uda1380_add_widgets(struct snd_soc_codec *codec) { - snd_soc_dapm_new_controls(codec, uda1380_dapm_widgets, - ARRAY_SIZE(uda1380_dapm_widgets)); + struct snd_soc_dapm_context *dapm = &codec->dapm; - snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); + snd_soc_dapm_new_controls(dapm, uda1380_dapm_widgets, + ARRAY_SIZE(uda1380_dapm_widgets)); + snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); return 0; } @@ -603,7 +604,7 @@ static int uda1380_set_bias_level(struct snd_soc_codec *codec, int reg; struct uda1380_platform_data *pdata = codec->dev->platform_data; - if (codec->bias_level == level) + if (codec->dapm.bias_level == level) return 0; switch (level) { @@ -613,7 +614,7 @@ static int uda1380_set_bias_level(struct snd_soc_codec *codec, uda1380_write(codec, UDA1380_PM, R02_PON_BIAS | pm); break; case SND_SOC_BIAS_STANDBY: - if (codec->bias_level == SND_SOC_BIAS_OFF) { + if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { if (gpio_is_valid(pdata->gpio_power)) { gpio_set_value(pdata->gpio_power, 1); mdelay(1); @@ -636,7 +637,7 @@ static int uda1380_set_bias_level(struct snd_soc_codec *codec, for (reg = UDA1380_MVOL; reg < UDA1380_CACHEREGNUM; reg++) set_bit(reg - 0x10, &uda1380_cache_dirty); } - codec->bias_level = level; + codec->dapm.bias_level = level; return 0; } diff --git a/sound/soc/codecs/wm2000.c b/sound/soc/codecs/wm2000.c index 4bcd168794e1..9277d8d7474e 100644 --- a/sound/soc/codecs/wm2000.c +++ b/sound/soc/codecs/wm2000.c @@ -705,6 +705,7 @@ static const struct snd_soc_dapm_route audio_map[] = { /* Called from the machine driver */ int wm2000_add_controls(struct snd_soc_codec *codec) { + struct snd_soc_dapm_context *dapm = &codec->dapm; int ret; if (!wm2000_i2c) { @@ -712,12 +713,12 @@ int wm2000_add_controls(struct snd_soc_codec *codec) return -ENODEV; } - ret = snd_soc_dapm_new_controls(codec, wm2000_dapm_widgets, + ret = snd_soc_dapm_new_controls(dapm, wm2000_dapm_widgets, ARRAY_SIZE(wm2000_dapm_widgets)); if (ret < 0) return ret; - ret = snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); + ret = snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); if (ret < 0) return ret; diff --git a/sound/soc/codecs/wm8350.c b/sound/soc/codecs/wm8350.c index f4f1fba38eb9..4c6c81e11544 100644 --- a/sound/soc/codecs/wm8350.c +++ b/sound/soc/codecs/wm8350.c @@ -230,8 +230,9 @@ static inline int wm8350_out2_ramp_step(struct snd_soc_codec *codec) */ static void wm8350_pga_work(struct work_struct *work) { - struct snd_soc_codec *codec = - container_of(work, struct snd_soc_codec, delayed_work.work); + struct snd_soc_dapm_context *dapm = + container_of(work, struct snd_soc_dapm_context, delayed_work.work); + struct snd_soc_codec *codec = dapm->codec; struct wm8350_data *wm8350_data = snd_soc_codec_get_drvdata(codec); struct wm8350_output *out1 = &wm8350_data->out1, *out2 = &wm8350_data->out2; @@ -302,8 +303,8 @@ static int pga_event(struct snd_soc_dapm_widget *w, out->ramp = WM8350_RAMP_UP; out->active = 1; - if (!delayed_work_pending(&codec->delayed_work)) - schedule_delayed_work(&codec->delayed_work, + if (!delayed_work_pending(&codec->dapm.delayed_work)) + schedule_delayed_work(&codec->dapm.delayed_work, msecs_to_jiffies(1)); break; @@ -311,8 +312,8 @@ static int pga_event(struct snd_soc_dapm_widget *w, out->ramp = WM8350_RAMP_DOWN; out->active = 0; - if (!delayed_work_pending(&codec->delayed_work)) - schedule_delayed_work(&codec->delayed_work, + if (!delayed_work_pending(&codec->dapm.delayed_work)) + schedule_delayed_work(&codec->dapm.delayed_work, msecs_to_jiffies(1)); break; } @@ -786,9 +787,10 @@ static const struct snd_soc_dapm_route audio_map[] = { static int wm8350_add_widgets(struct snd_soc_codec *codec) { + struct snd_soc_dapm_context *dapm = &codec->dapm; int ret; - ret = snd_soc_dapm_new_controls(codec, + ret = snd_soc_dapm_new_controls(dapm, wm8350_dapm_widgets, ARRAY_SIZE(wm8350_dapm_widgets)); if (ret != 0) { @@ -797,7 +799,7 @@ static int wm8350_add_widgets(struct snd_soc_codec *codec) } /* set up audio paths */ - ret = snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); + ret = snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); if (ret != 0) { dev_err(codec->dev, "DAPM route register failed\n"); return ret; @@ -1184,7 +1186,7 @@ static int wm8350_set_bias_level(struct snd_soc_codec *codec, break; case SND_SOC_BIAS_STANDBY: - if (codec->bias_level == SND_SOC_BIAS_OFF) { + if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { ret = regulator_bulk_enable(ARRAY_SIZE(priv->supplies), priv->supplies); if (ret != 0) @@ -1317,7 +1319,7 @@ static int wm8350_set_bias_level(struct snd_soc_codec *codec, priv->supplies); break; } - codec->bias_level = level; + codec->dapm.bias_level = level; return 0; } @@ -1550,7 +1552,7 @@ static int wm8350_codec_probe(struct snd_soc_codec *codec) /* Put the codec into reset if it wasn't already */ wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_5, WM8350_CODEC_ENA); - INIT_DELAYED_WORK(&codec->delayed_work, wm8350_pga_work); + INIT_DELAYED_WORK(&codec->dapm.delayed_work, wm8350_pga_work); /* Enable the codec */ wm8350_set_bits(wm8350, WM8350_POWER_MGMT_5, WM8350_CODEC_ENA); @@ -1635,12 +1637,12 @@ static int wm8350_codec_remove(struct snd_soc_codec *codec) priv->mic.jack = NULL; /* cancel any work waiting to be queued. */ - ret = cancel_delayed_work(&codec->delayed_work); + ret = cancel_delayed_work(&codec->dapm.delayed_work); /* if there was any work waiting then we run it now and * wait for its completion */ if (ret) { - schedule_delayed_work(&codec->delayed_work, 0); + schedule_delayed_work(&codec->dapm.delayed_work, 0); flush_scheduled_work(); } diff --git a/sound/soc/codecs/wm8400.c b/sound/soc/codecs/wm8400.c index 850299786e02..96927a457a34 100644 --- a/sound/soc/codecs/wm8400.c +++ b/sound/soc/codecs/wm8400.c @@ -911,10 +911,11 @@ static const struct snd_soc_dapm_route audio_map[] = { static int wm8400_add_widgets(struct snd_soc_codec *codec) { - snd_soc_dapm_new_controls(codec, wm8400_dapm_widgets, - ARRAY_SIZE(wm8400_dapm_widgets)); + struct snd_soc_dapm_context *dapm = &codec->dapm; - snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); + snd_soc_dapm_new_controls(dapm, wm8400_dapm_widgets, + ARRAY_SIZE(wm8400_dapm_widgets)); + snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); return 0; } @@ -1219,7 +1220,7 @@ static int wm8400_set_bias_level(struct snd_soc_codec *codec, break; case SND_SOC_BIAS_STANDBY: - if (codec->bias_level == SND_SOC_BIAS_OFF) { + if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { ret = regulator_bulk_enable(ARRAY_SIZE(power), &power[0]); if (ret != 0) { @@ -1306,7 +1307,7 @@ static int wm8400_set_bias_level(struct snd_soc_codec *codec, break; } - codec->bias_level = level; + codec->dapm.bias_level = level; return 0; } diff --git a/sound/soc/codecs/wm8510.c b/sound/soc/codecs/wm8510.c index 8f107095760e..6b3833c7bdf3 100644 --- a/sound/soc/codecs/wm8510.c +++ b/sound/soc/codecs/wm8510.c @@ -216,10 +216,11 @@ static const struct snd_soc_dapm_route audio_map[] = { static int wm8510_add_widgets(struct snd_soc_codec *codec) { - snd_soc_dapm_new_controls(codec, wm8510_dapm_widgets, - ARRAY_SIZE(wm8510_dapm_widgets)); + struct snd_soc_dapm_context *dapm = &codec->dapm; - snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); + snd_soc_dapm_new_controls(dapm, wm8510_dapm_widgets, + ARRAY_SIZE(wm8510_dapm_widgets)); + snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); return 0; } @@ -478,7 +479,7 @@ static int wm8510_set_bias_level(struct snd_soc_codec *codec, case SND_SOC_BIAS_STANDBY: power1 |= WM8510_POWER1_BIASEN | WM8510_POWER1_BUFIOEN; - if (codec->bias_level == SND_SOC_BIAS_OFF) { + if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { /* Initial cap charge at VMID 5k */ snd_soc_write(codec, WM8510_POWER1, power1 | 0x3); mdelay(100); @@ -495,7 +496,7 @@ static int wm8510_set_bias_level(struct snd_soc_codec *codec, break; } - codec->bias_level = level; + codec->dapm.bias_level = level; return 0; } diff --git a/sound/soc/codecs/wm8523.c b/sound/soc/codecs/wm8523.c index 712ef7c76f90..d3318886f43e 100644 --- a/sound/soc/codecs/wm8523.c +++ b/sound/soc/codecs/wm8523.c @@ -110,10 +110,11 @@ static const struct snd_soc_dapm_route intercon[] = { static int wm8523_add_widgets(struct snd_soc_codec *codec) { - snd_soc_dapm_new_controls(codec, wm8523_dapm_widgets, - ARRAY_SIZE(wm8523_dapm_widgets)); + struct snd_soc_dapm_context *dapm = &codec->dapm; - snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon)); + snd_soc_dapm_new_controls(dapm, wm8523_dapm_widgets, + ARRAY_SIZE(wm8523_dapm_widgets)); + snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon)); return 0; } @@ -328,7 +329,7 @@ static int wm8523_set_bias_level(struct snd_soc_codec *codec, break; case SND_SOC_BIAS_STANDBY: - if (codec->bias_level == SND_SOC_BIAS_OFF) { + if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { ret = regulator_bulk_enable(ARRAY_SIZE(wm8523->supplies), wm8523->supplies); if (ret != 0) { @@ -367,7 +368,7 @@ static int wm8523_set_bias_level(struct snd_soc_codec *codec, wm8523->supplies); break; } - codec->bias_level = level; + codec->dapm.bias_level = level; return 0; } diff --git a/sound/soc/codecs/wm8580.c b/sound/soc/codecs/wm8580.c index a2e0ed59b376..dfd1dbd71f1d 100644 --- a/sound/soc/codecs/wm8580.c +++ b/sound/soc/codecs/wm8580.c @@ -302,10 +302,11 @@ static const struct snd_soc_dapm_route audio_map[] = { static int wm8580_add_widgets(struct snd_soc_codec *codec) { - snd_soc_dapm_new_controls(codec, wm8580_dapm_widgets, - ARRAY_SIZE(wm8580_dapm_widgets)); + struct snd_soc_dapm_context *dapm = &codec->dapm; - snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); + snd_soc_dapm_new_controls(dapm, wm8580_dapm_widgets, + ARRAY_SIZE(wm8580_dapm_widgets)); + snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); return 0; } @@ -767,7 +768,7 @@ static int wm8580_set_bias_level(struct snd_soc_codec *codec, break; case SND_SOC_BIAS_STANDBY: - if (codec->bias_level == SND_SOC_BIAS_OFF) { + if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { /* Power up and get individual control of the DACs */ reg = snd_soc_read(codec, WM8580_PWRDN1); reg &= ~(WM8580_PWRDN1_PWDN | WM8580_PWRDN1_ALLDACPD); @@ -785,7 +786,7 @@ static int wm8580_set_bias_level(struct snd_soc_codec *codec, snd_soc_write(codec, WM8580_PWRDN1, reg | WM8580_PWRDN1_PWDN); break; } - codec->bias_level = level; + codec->dapm.bias_level = level; return 0; } diff --git a/sound/soc/codecs/wm8711.c b/sound/soc/codecs/wm8711.c index 54fbd76c8bca..ea2daf4da57c 100644 --- a/sound/soc/codecs/wm8711.c +++ b/sound/soc/codecs/wm8711.c @@ -93,10 +93,11 @@ static const struct snd_soc_dapm_route intercon[] = { static int wm8711_add_widgets(struct snd_soc_codec *codec) { - snd_soc_dapm_new_controls(codec, wm8711_dapm_widgets, - ARRAY_SIZE(wm8711_dapm_widgets)); + struct snd_soc_dapm_context *dapm = &codec->dapm; - snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon)); + snd_soc_dapm_new_controls(dapm, wm8711_dapm_widgets, + ARRAY_SIZE(wm8711_dapm_widgets)); + snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon)); return 0; } @@ -318,7 +319,7 @@ static int wm8711_set_bias_level(struct snd_soc_codec *codec, snd_soc_write(codec, WM8711_PWR, 0xffff); break; } - codec->bias_level = level; + codec->dapm.bias_level = level; return 0; } diff --git a/sound/soc/codecs/wm8728.c b/sound/soc/codecs/wm8728.c index 075f35e4f4cb..23939976c3cc 100644 --- a/sound/soc/codecs/wm8728.c +++ b/sound/soc/codecs/wm8728.c @@ -73,10 +73,11 @@ static const struct snd_soc_dapm_route intercon[] = { static int wm8728_add_widgets(struct snd_soc_codec *codec) { - snd_soc_dapm_new_controls(codec, wm8728_dapm_widgets, - ARRAY_SIZE(wm8728_dapm_widgets)); + struct snd_soc_dapm_context *dapm = &codec->dapm; - snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon)); + snd_soc_dapm_new_controls(dapm, wm8728_dapm_widgets, + ARRAY_SIZE(wm8728_dapm_widgets)); + snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon)); return 0; } @@ -180,7 +181,7 @@ static int wm8728_set_bias_level(struct snd_soc_codec *codec, case SND_SOC_BIAS_ON: case SND_SOC_BIAS_PREPARE: case SND_SOC_BIAS_STANDBY: - if (codec->bias_level == SND_SOC_BIAS_OFF) { + if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { /* Power everything up... */ reg = snd_soc_read(codec, WM8728_DACCTL); snd_soc_write(codec, WM8728_DACCTL, reg & ~0x4); @@ -197,7 +198,7 @@ static int wm8728_set_bias_level(struct snd_soc_codec *codec, snd_soc_write(codec, WM8728_DACCTL, reg | 0x4); break; } - codec->bias_level = level; + codec->dapm.bias_level = level; return 0; } diff --git a/sound/soc/codecs/wm8731.c b/sound/soc/codecs/wm8731.c index 631385802eb4..95ade3245056 100644 --- a/sound/soc/codecs/wm8731.c +++ b/sound/soc/codecs/wm8731.c @@ -165,10 +165,11 @@ static const struct snd_soc_dapm_route intercon[] = { static int wm8731_add_widgets(struct snd_soc_codec *codec) { - snd_soc_dapm_new_controls(codec, wm8731_dapm_widgets, - ARRAY_SIZE(wm8731_dapm_widgets)); + struct snd_soc_dapm_context *dapm = &codec->dapm; - snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon)); + snd_soc_dapm_new_controls(dapm, wm8731_dapm_widgets, + ARRAY_SIZE(wm8731_dapm_widgets)); + snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon)); return 0; } @@ -319,7 +320,7 @@ static int wm8731_set_dai_sysclk(struct snd_soc_dai *codec_dai, return -EINVAL; } - snd_soc_dapm_sync(codec); + snd_soc_dapm_sync(&codec->dapm); return 0; } @@ -399,7 +400,7 @@ static int wm8731_set_bias_level(struct snd_soc_codec *codec, case SND_SOC_BIAS_PREPARE: break; case SND_SOC_BIAS_STANDBY: - if (codec->bias_level == SND_SOC_BIAS_OFF) { + if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { ret = regulator_bulk_enable(ARRAY_SIZE(wm8731->supplies), wm8731->supplies); if (ret != 0) @@ -428,7 +429,7 @@ static int wm8731_set_bias_level(struct snd_soc_codec *codec, wm8731->supplies); break; } - codec->bias_level = level; + codec->dapm.bias_level = level; return 0; } diff --git a/sound/soc/codecs/wm8741.c b/sound/soc/codecs/wm8741.c index 90e31e9aa6f7..43c49dfc9928 100644 --- a/sound/soc/codecs/wm8741.c +++ b/sound/soc/codecs/wm8741.c @@ -95,10 +95,11 @@ static const struct snd_soc_dapm_route intercon[] = { static int wm8741_add_widgets(struct snd_soc_codec *codec) { - snd_soc_dapm_new_controls(codec, wm8741_dapm_widgets, - ARRAY_SIZE(wm8741_dapm_widgets)); + struct snd_soc_dapm_context *dapm = &codec->dapm; - snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon)); + snd_soc_dapm_new_controls(dapm, wm8741_dapm_widgets, + ARRAY_SIZE(wm8741_dapm_widgets)); + snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon)); return 0; } diff --git a/sound/soc/codecs/wm8750.c b/sound/soc/codecs/wm8750.c index 6c924cd2cfd4..178b967af73f 100644 --- a/sound/soc/codecs/wm8750.c +++ b/sound/soc/codecs/wm8750.c @@ -399,10 +399,11 @@ static const struct snd_soc_dapm_route audio_map[] = { static int wm8750_add_widgets(struct snd_soc_codec *codec) { - snd_soc_dapm_new_controls(codec, wm8750_dapm_widgets, - ARRAY_SIZE(wm8750_dapm_widgets)); + struct snd_soc_dapm_context *dapm = &codec->dapm; - snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); + snd_soc_dapm_new_controls(dapm, wm8750_dapm_widgets, + ARRAY_SIZE(wm8750_dapm_widgets)); + snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); return 0; } @@ -615,7 +616,7 @@ static int wm8750_set_bias_level(struct snd_soc_codec *codec, case SND_SOC_BIAS_PREPARE: break; case SND_SOC_BIAS_STANDBY: - if (codec->bias_level == SND_SOC_BIAS_OFF) { + if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { /* Set VMID to 5k */ snd_soc_write(codec, WM8750_PWR1, pwr_reg | 0x01c1); @@ -630,7 +631,7 @@ static int wm8750_set_bias_level(struct snd_soc_codec *codec, snd_soc_write(codec, WM8750_PWR1, 0x0001); break; } - codec->bias_level = level; + codec->dapm.bias_level = level; return 0; } diff --git a/sound/soc/codecs/wm8753.c b/sound/soc/codecs/wm8753.c index 8f679a13f2bc..26096b47a493 100644 --- a/sound/soc/codecs/wm8753.c +++ b/sound/soc/codecs/wm8753.c @@ -670,10 +670,11 @@ static const struct snd_soc_dapm_route audio_map[] = { static int wm8753_add_widgets(struct snd_soc_codec *codec) { - snd_soc_dapm_new_controls(codec, wm8753_dapm_widgets, - ARRAY_SIZE(wm8753_dapm_widgets)); + struct snd_soc_dapm_context *dapm = &codec->dapm; - snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); + snd_soc_dapm_new_controls(dapm, wm8753_dapm_widgets, + ARRAY_SIZE(wm8753_dapm_widgets)); + snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); return 0; } @@ -1292,7 +1293,7 @@ static int wm8753_set_bias_level(struct snd_soc_codec *codec, wm8753_write(codec, WM8753_PWR1, 0x0001); break; } - codec->bias_level = level; + codec->dapm.bias_level = level; return 0; } @@ -1482,9 +1483,11 @@ static void wm8753_set_dai_mode(struct snd_soc_codec *codec, static void wm8753_work(struct work_struct *work) { - struct snd_soc_codec *codec = - container_of(work, struct snd_soc_codec, delayed_work.work); - wm8753_set_bias_level(codec, codec->bias_level); + struct snd_soc_dapm_context *dapm = + container_of(work, struct snd_soc_dapm_context, + delayed_work.work); + struct snd_soc_codec *codec = dapm->codec; + wm8753_set_bias_level(codec, dapm->bias_level); } static int wm8753_suspend(struct snd_soc_codec *codec, pm_message_t state) @@ -1516,10 +1519,10 @@ static int wm8753_resume(struct snd_soc_codec *codec) wm8753_set_bias_level(codec, SND_SOC_BIAS_STANDBY); /* charge wm8753 caps */ - if (codec->suspend_bias_level == SND_SOC_BIAS_ON) { + if (codec->dapm.suspend_bias_level == SND_SOC_BIAS_ON) { wm8753_set_bias_level(codec, SND_SOC_BIAS_PREPARE); - codec->bias_level = SND_SOC_BIAS_ON; - schedule_delayed_work(&codec->delayed_work, + codec->dapm.bias_level = SND_SOC_BIAS_ON; + schedule_delayed_work(&codec->dapm.delayed_work, msecs_to_jiffies(caps_charge)); } @@ -1550,7 +1553,7 @@ static int wm8753_probe(struct snd_soc_codec *codec) struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec); int ret = 0, reg; - INIT_DELAYED_WORK(&codec->delayed_work, wm8753_work); + INIT_DELAYED_WORK(&codec->dapm.delayed_work, wm8753_work); ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8753->control_type); if (ret < 0) { @@ -1569,7 +1572,7 @@ static int wm8753_probe(struct snd_soc_codec *codec) /* charge output caps */ wm8753_set_bias_level(codec, SND_SOC_BIAS_PREPARE); - schedule_delayed_work(&codec->delayed_work, + schedule_delayed_work(&codec->dapm.delayed_work, msecs_to_jiffies(caps_charge)); /* set the update bits */ @@ -1604,7 +1607,7 @@ static int wm8753_probe(struct snd_soc_codec *codec) /* power down chip */ static int wm8753_remove(struct snd_soc_codec *codec) { - run_delayed_work(&codec->delayed_work); + run_delayed_work(&codec->dapm.delayed_work); wm8753_set_bias_level(codec, SND_SOC_BIAS_OFF); return 0; diff --git a/sound/soc/codecs/wm8776.c b/sound/soc/codecs/wm8776.c index 04182c464e35..96474a40da8d 100644 --- a/sound/soc/codecs/wm8776.c +++ b/sound/soc/codecs/wm8776.c @@ -307,7 +307,7 @@ static int wm8776_set_bias_level(struct snd_soc_codec *codec, case SND_SOC_BIAS_PREPARE: break; case SND_SOC_BIAS_STANDBY: - if (codec->bias_level == SND_SOC_BIAS_OFF) { + if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { /* Disable the global powerdown; DAPM does the rest */ snd_soc_update_bits(codec, WM8776_PWRDOWN, 1, 0); } @@ -318,7 +318,7 @@ static int wm8776_set_bias_level(struct snd_soc_codec *codec, break; } - codec->bias_level = level; + codec->dapm.bias_level = level; return 0; } @@ -405,6 +405,7 @@ static int wm8776_resume(struct snd_soc_codec *codec) static int wm8776_probe(struct snd_soc_codec *codec) { struct wm8776_priv *wm8776 = snd_soc_codec_get_drvdata(codec); + struct snd_soc_dapm_context *dapm = &codec->dapm; int ret = 0; ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8776->control_type); @@ -428,9 +429,9 @@ static int wm8776_probe(struct snd_soc_codec *codec) snd_soc_add_controls(codec, wm8776_snd_controls, ARRAY_SIZE(wm8776_snd_controls)); - snd_soc_dapm_new_controls(codec, wm8776_dapm_widgets, + snd_soc_dapm_new_controls(dapm, wm8776_dapm_widgets, ARRAY_SIZE(wm8776_dapm_widgets)); - snd_soc_dapm_add_routes(codec, routes, ARRAY_SIZE(routes)); + snd_soc_dapm_add_routes(dapm, routes, ARRAY_SIZE(routes)); return ret; } diff --git a/sound/soc/codecs/wm8804.c b/sound/soc/codecs/wm8804.c index 4599e8e95aa2..031a0d421108 100644 --- a/sound/soc/codecs/wm8804.c +++ b/sound/soc/codecs/wm8804.c @@ -515,7 +515,7 @@ static int wm8804_set_bias_level(struct snd_soc_codec *codec, snd_soc_update_bits(codec, WM8804_PWRDN, 0x9, 0); break; case SND_SOC_BIAS_STANDBY: - if (codec->bias_level == SND_SOC_BIAS_OFF) { + if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { ret = regulator_bulk_enable(ARRAY_SIZE(wm8804->supplies), wm8804->supplies); if (ret) { @@ -537,7 +537,7 @@ static int wm8804_set_bias_level(struct snd_soc_codec *codec, break; } - codec->bias_level = level; + codec->dapm.bias_level = level; return 0; } @@ -581,7 +581,7 @@ static int wm8804_probe(struct snd_soc_codec *codec) wm8804 = snd_soc_codec_get_drvdata(codec); wm8804->codec = codec; - codec->idle_bias_off = 1; + codec->dapm.idle_bias_off = 1; ret = snd_soc_codec_set_cache_io(codec, 8, 8, wm8804->control_type); if (ret < 0) { diff --git a/sound/soc/codecs/wm8900.c b/sound/soc/codecs/wm8900.c index aca4b1ea10bb..06ea9c0f863b 100644 --- a/sound/soc/codecs/wm8900.c +++ b/sound/soc/codecs/wm8900.c @@ -611,10 +611,11 @@ static const struct snd_soc_dapm_route audio_map[] = { static int wm8900_add_widgets(struct snd_soc_codec *codec) { - snd_soc_dapm_new_controls(codec, wm8900_dapm_widgets, - ARRAY_SIZE(wm8900_dapm_widgets)); + struct snd_soc_dapm_context *dapm = &codec->dapm; - snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); + snd_soc_dapm_new_controls(dapm, wm8900_dapm_widgets, + ARRAY_SIZE(wm8900_dapm_widgets)); + snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); return 0; } @@ -1051,7 +1052,7 @@ static int wm8900_set_bias_level(struct snd_soc_codec *codec, case SND_SOC_BIAS_STANDBY: /* Charge capacitors if initial power up */ - if (codec->bias_level == SND_SOC_BIAS_OFF) { + if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { /* STARTUP_BIAS_ENA on */ snd_soc_write(codec, WM8900_REG_POWER1, WM8900_REG_POWER1_STARTUP_BIAS_ENA); @@ -1119,7 +1120,7 @@ static int wm8900_set_bias_level(struct snd_soc_codec *codec, WM8900_REG_POWER2_SYSCLK_ENA); break; } - codec->bias_level = level; + codec->dapm.bias_level = level; return 0; } diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c index 622b60238a82..4a6df4b69a04 100644 --- a/sound/soc/codecs/wm8903.c +++ b/sound/soc/codecs/wm8903.c @@ -923,10 +923,11 @@ static const struct snd_soc_dapm_route intercon[] = { static int wm8903_add_widgets(struct snd_soc_codec *codec) { - snd_soc_dapm_new_controls(codec, wm8903_dapm_widgets, - ARRAY_SIZE(wm8903_dapm_widgets)); + struct snd_soc_dapm_context *dapm = &codec->dapm; - snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon)); + snd_soc_dapm_new_controls(dapm, wm8903_dapm_widgets, + ARRAY_SIZE(wm8903_dapm_widgets)); + snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon)); return 0; } @@ -946,7 +947,7 @@ static int wm8903_set_bias_level(struct snd_soc_codec *codec, break; case SND_SOC_BIAS_STANDBY: - if (codec->bias_level == SND_SOC_BIAS_OFF) { + if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { snd_soc_write(codec, WM8903_CLOCK_RATES_2, WM8903_CLK_SYS_ENA); @@ -991,7 +992,7 @@ static int wm8903_set_bias_level(struct snd_soc_codec *codec, break; } - codec->bias_level = level; + codec->dapm.bias_level = level; return 0; } diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c index 33be84e506ea..be90399c1cb4 100644 --- a/sound/soc/codecs/wm8904.c +++ b/sound/soc/codecs/wm8904.c @@ -1428,10 +1428,11 @@ static const struct snd_soc_dapm_route wm8912_intercon[] = { static int wm8904_add_widgets(struct snd_soc_codec *codec) { struct wm8904_priv *wm8904 = snd_soc_codec_get_drvdata(codec); + struct snd_soc_dapm_context *dapm = &codec->dapm; - snd_soc_dapm_new_controls(codec, wm8904_core_dapm_widgets, + snd_soc_dapm_new_controls(dapm, wm8904_core_dapm_widgets, ARRAY_SIZE(wm8904_core_dapm_widgets)); - snd_soc_dapm_add_routes(codec, core_intercon, + snd_soc_dapm_add_routes(dapm, core_intercon, ARRAY_SIZE(core_intercon)); switch (wm8904->devtype) { @@ -1443,20 +1444,20 @@ static int wm8904_add_widgets(struct snd_soc_codec *codec) snd_soc_add_controls(codec, wm8904_snd_controls, ARRAY_SIZE(wm8904_snd_controls)); - snd_soc_dapm_new_controls(codec, wm8904_adc_dapm_widgets, + snd_soc_dapm_new_controls(dapm, wm8904_adc_dapm_widgets, ARRAY_SIZE(wm8904_adc_dapm_widgets)); - snd_soc_dapm_new_controls(codec, wm8904_dac_dapm_widgets, + snd_soc_dapm_new_controls(dapm, wm8904_dac_dapm_widgets, ARRAY_SIZE(wm8904_dac_dapm_widgets)); - snd_soc_dapm_new_controls(codec, wm8904_dapm_widgets, + snd_soc_dapm_new_controls(dapm, wm8904_dapm_widgets, ARRAY_SIZE(wm8904_dapm_widgets)); - snd_soc_dapm_add_routes(codec, core_intercon, + snd_soc_dapm_add_routes(dapm, core_intercon, ARRAY_SIZE(core_intercon)); - snd_soc_dapm_add_routes(codec, adc_intercon, + snd_soc_dapm_add_routes(dapm, adc_intercon, ARRAY_SIZE(adc_intercon)); - snd_soc_dapm_add_routes(codec, dac_intercon, + snd_soc_dapm_add_routes(dapm, dac_intercon, ARRAY_SIZE(dac_intercon)); - snd_soc_dapm_add_routes(codec, wm8904_intercon, + snd_soc_dapm_add_routes(dapm, wm8904_intercon, ARRAY_SIZE(wm8904_intercon)); break; @@ -1464,17 +1465,17 @@ static int wm8904_add_widgets(struct snd_soc_codec *codec) snd_soc_add_controls(codec, wm8904_dac_snd_controls, ARRAY_SIZE(wm8904_dac_snd_controls)); - snd_soc_dapm_new_controls(codec, wm8904_dac_dapm_widgets, + snd_soc_dapm_new_controls(dapm, wm8904_dac_dapm_widgets, ARRAY_SIZE(wm8904_dac_dapm_widgets)); - snd_soc_dapm_add_routes(codec, dac_intercon, + snd_soc_dapm_add_routes(dapm, dac_intercon, ARRAY_SIZE(dac_intercon)); - snd_soc_dapm_add_routes(codec, wm8912_intercon, + snd_soc_dapm_add_routes(dapm, wm8912_intercon, ARRAY_SIZE(wm8912_intercon)); break; } - snd_soc_dapm_new_widgets(codec); + snd_soc_dapm_new_widgets(dapm); return 0; } @@ -2139,7 +2140,7 @@ static int wm8904_set_bias_level(struct snd_soc_codec *codec, break; case SND_SOC_BIAS_STANDBY: - if (codec->bias_level == SND_SOC_BIAS_OFF) { + if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { ret = regulator_bulk_enable(ARRAY_SIZE(wm8904->supplies), wm8904->supplies); if (ret != 0) { @@ -2198,7 +2199,7 @@ static int wm8904_set_bias_level(struct snd_soc_codec *codec, wm8904->supplies); break; } - codec->bias_level = level; + codec->dapm.bias_level = level; return 0; } @@ -2373,7 +2374,7 @@ static int wm8904_probe(struct snd_soc_codec *codec) int ret, i; codec->cache_sync = 1; - codec->idle_bias_off = 1; + codec->dapm.idle_bias_off = 1; switch (wm8904->devtype) { case WM8904: diff --git a/sound/soc/codecs/wm8940.c b/sound/soc/codecs/wm8940.c index 2cb16f895c46..c2def1b01ae0 100644 --- a/sound/soc/codecs/wm8940.c +++ b/sound/soc/codecs/wm8940.c @@ -291,13 +291,14 @@ static const struct snd_soc_dapm_route audio_map[] = { static int wm8940_add_widgets(struct snd_soc_codec *codec) { + struct snd_soc_dapm_context *dapm = &codec->dapm; int ret; - ret = snd_soc_dapm_new_controls(codec, wm8940_dapm_widgets, + ret = snd_soc_dapm_new_controls(dapm, wm8940_dapm_widgets, ARRAY_SIZE(wm8940_dapm_widgets)); if (ret) goto error_ret; - ret = snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); + ret = snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); if (ret) goto error_ret; diff --git a/sound/soc/codecs/wm8955.c b/sound/soc/codecs/wm8955.c index f89ad6c9a80b..df1940fdbf69 100644 --- a/sound/soc/codecs/wm8955.c +++ b/sound/soc/codecs/wm8955.c @@ -577,13 +577,14 @@ static const struct snd_soc_dapm_route wm8955_intercon[] = { static int wm8955_add_widgets(struct snd_soc_codec *codec) { + struct snd_soc_dapm_context *dapm = &codec->dapm; + snd_soc_add_controls(codec, wm8955_snd_controls, ARRAY_SIZE(wm8955_snd_controls)); - snd_soc_dapm_new_controls(codec, wm8955_dapm_widgets, + snd_soc_dapm_new_controls(dapm, wm8955_dapm_widgets, ARRAY_SIZE(wm8955_dapm_widgets)); - - snd_soc_dapm_add_routes(codec, wm8955_intercon, + snd_soc_dapm_add_routes(dapm, wm8955_intercon, ARRAY_SIZE(wm8955_intercon)); return 0; @@ -786,7 +787,7 @@ static int wm8955_set_bias_level(struct snd_soc_codec *codec, break; case SND_SOC_BIAS_STANDBY: - if (codec->bias_level == SND_SOC_BIAS_OFF) { + if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { ret = regulator_bulk_enable(ARRAY_SIZE(wm8955->supplies), wm8955->supplies); if (ret != 0) { @@ -850,7 +851,7 @@ static int wm8955_set_bias_level(struct snd_soc_codec *codec, wm8955->supplies); break; } - codec->bias_level = level; + codec->dapm.bias_level = level; return 0; } diff --git a/sound/soc/codecs/wm8960.c b/sound/soc/codecs/wm8960.c index 8d5efb333c33..0ea578815003 100644 --- a/sound/soc/codecs/wm8960.c +++ b/sound/soc/codecs/wm8960.c @@ -388,27 +388,28 @@ static int wm8960_add_widgets(struct snd_soc_codec *codec) { struct wm8960_data *pdata = codec->dev->platform_data; struct wm8960_priv *wm8960 = snd_soc_codec_get_drvdata(codec); + struct snd_soc_dapm_context *dapm = &codec->dapm; struct snd_soc_dapm_widget *w; - snd_soc_dapm_new_controls(codec, wm8960_dapm_widgets, + snd_soc_dapm_new_controls(dapm, wm8960_dapm_widgets, ARRAY_SIZE(wm8960_dapm_widgets)); - snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths)); + snd_soc_dapm_add_routes(dapm, audio_paths, ARRAY_SIZE(audio_paths)); /* In capless mode OUT3 is used to provide VMID for the * headphone outputs, otherwise it is used as a mono mixer. */ if (pdata && pdata->capless) { - snd_soc_dapm_new_controls(codec, wm8960_dapm_widgets_capless, + snd_soc_dapm_new_controls(dapm, wm8960_dapm_widgets_capless, ARRAY_SIZE(wm8960_dapm_widgets_capless)); - snd_soc_dapm_add_routes(codec, audio_paths_capless, + snd_soc_dapm_add_routes(dapm, audio_paths_capless, ARRAY_SIZE(audio_paths_capless)); } else { - snd_soc_dapm_new_controls(codec, wm8960_dapm_widgets_out3, + snd_soc_dapm_new_controls(dapm, wm8960_dapm_widgets_out3, ARRAY_SIZE(wm8960_dapm_widgets_out3)); - snd_soc_dapm_add_routes(codec, audio_paths_out3, + snd_soc_dapm_add_routes(dapm, audio_paths_out3, ARRAY_SIZE(audio_paths_out3)); } @@ -417,7 +418,7 @@ static int wm8960_add_widgets(struct snd_soc_codec *codec) * list each time to find the desired power state do so now * and save the result. */ - list_for_each_entry(w, &codec->dapm_widgets, list) { + list_for_each_entry(w, &codec->dapm.widgets, list) { if (strcmp(w->name, "LOUT1 PGA") == 0) wm8960->lout1 = w; if (strcmp(w->name, "ROUT1 PGA") == 0) @@ -572,7 +573,7 @@ static int wm8960_set_bias_level_out3(struct snd_soc_codec *codec, break; case SND_SOC_BIAS_STANDBY: - if (codec->bias_level == SND_SOC_BIAS_OFF) { + if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { /* Enable anti-pop features */ snd_soc_write(codec, WM8960_APOP1, WM8960_POBCTRL | WM8960_SOFT_ST | @@ -610,7 +611,7 @@ static int wm8960_set_bias_level_out3(struct snd_soc_codec *codec, break; } - codec->bias_level = level; + codec->dapm.bias_level = level; return 0; } @@ -626,7 +627,7 @@ static int wm8960_set_bias_level_capless(struct snd_soc_codec *codec, break; case SND_SOC_BIAS_PREPARE: - switch (codec->bias_level) { + switch (codec->dapm.bias_level) { case SND_SOC_BIAS_STANDBY: /* Enable anti pop mode */ snd_soc_update_bits(codec, WM8960_APOP1, @@ -681,7 +682,7 @@ static int wm8960_set_bias_level_capless(struct snd_soc_codec *codec, break; case SND_SOC_BIAS_STANDBY: - switch (codec->bias_level) { + switch (codec->dapm.bias_level) { case SND_SOC_BIAS_PREPARE: /* Disable HP discharge */ snd_soc_update_bits(codec, WM8960_APOP2, @@ -705,7 +706,7 @@ static int wm8960_set_bias_level_capless(struct snd_soc_codec *codec, break; } - codec->bias_level = level; + codec->dapm.bias_level = level; return 0; } diff --git a/sound/soc/codecs/wm8961.c b/sound/soc/codecs/wm8961.c index 4f326f604104..79b650945bb2 100644 --- a/sound/soc/codecs/wm8961.c +++ b/sound/soc/codecs/wm8961.c @@ -882,7 +882,7 @@ static int wm8961_set_bias_level(struct snd_soc_codec *codec, break; case SND_SOC_BIAS_PREPARE: - if (codec->bias_level == SND_SOC_BIAS_STANDBY) { + if (codec->dapm.bias_level == SND_SOC_BIAS_STANDBY) { /* Enable bias generation */ reg = snd_soc_read(codec, WM8961_ANTI_POP); reg |= WM8961_BUFIOEN | WM8961_BUFDCOPEN; @@ -897,7 +897,7 @@ static int wm8961_set_bias_level(struct snd_soc_codec *codec, break; case SND_SOC_BIAS_STANDBY: - if (codec->bias_level == SND_SOC_BIAS_PREPARE) { + if (codec->dapm.bias_level == SND_SOC_BIAS_PREPARE) { /* VREF off */ reg = snd_soc_read(codec, WM8961_PWR_MGMT_1); reg &= ~WM8961_VREF; @@ -919,7 +919,7 @@ static int wm8961_set_bias_level(struct snd_soc_codec *codec, break; } - codec->bias_level = level; + codec->dapm.bias_level = level; return 0; } @@ -959,6 +959,7 @@ static struct snd_soc_dai_driver wm8961_dai = { static int wm8961_probe(struct snd_soc_codec *codec) { + struct snd_soc_dapm_context *dapm = &codec->dapm; int ret = 0; u16 reg; @@ -1024,9 +1025,9 @@ static int wm8961_probe(struct snd_soc_codec *codec) snd_soc_add_controls(codec, wm8961_snd_controls, ARRAY_SIZE(wm8961_snd_controls)); - snd_soc_dapm_new_controls(codec, wm8961_dapm_widgets, + snd_soc_dapm_new_controls(dapm, wm8961_dapm_widgets, ARRAY_SIZE(wm8961_dapm_widgets)); - snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths)); + snd_soc_dapm_add_routes(dapm, audio_paths, ARRAY_SIZE(audio_paths)); return 0; } diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c index 3fc63b43c6a1..80986105f52e 100644 --- a/sound/soc/codecs/wm8962.c +++ b/sound/soc/codecs/wm8962.c @@ -2682,6 +2682,7 @@ static const struct snd_soc_dapm_route wm8962_spk_stereo_intercon[] = { static int wm8962_add_widgets(struct snd_soc_codec *codec) { struct wm8962_pdata *pdata = dev_get_platdata(codec->dev); + struct snd_soc_dapm_context *dapm = &codec->dapm; snd_soc_add_controls(codec, wm8962_snd_controls, ARRAY_SIZE(wm8962_snd_controls)); @@ -2693,26 +2694,26 @@ static int wm8962_add_widgets(struct snd_soc_codec *codec) ARRAY_SIZE(wm8962_spk_stereo_controls)); - snd_soc_dapm_new_controls(codec, wm8962_dapm_widgets, + snd_soc_dapm_new_controls(dapm, wm8962_dapm_widgets, ARRAY_SIZE(wm8962_dapm_widgets)); if (pdata && pdata->spk_mono) - snd_soc_dapm_new_controls(codec, wm8962_dapm_spk_mono_widgets, + snd_soc_dapm_new_controls(dapm, wm8962_dapm_spk_mono_widgets, ARRAY_SIZE(wm8962_dapm_spk_mono_widgets)); else - snd_soc_dapm_new_controls(codec, wm8962_dapm_spk_stereo_widgets, + snd_soc_dapm_new_controls(dapm, wm8962_dapm_spk_stereo_widgets, ARRAY_SIZE(wm8962_dapm_spk_stereo_widgets)); - snd_soc_dapm_add_routes(codec, wm8962_intercon, + snd_soc_dapm_add_routes(dapm, wm8962_intercon, ARRAY_SIZE(wm8962_intercon)); if (pdata && pdata->spk_mono) - snd_soc_dapm_add_routes(codec, wm8962_spk_mono_intercon, + snd_soc_dapm_add_routes(dapm, wm8962_spk_mono_intercon, ARRAY_SIZE(wm8962_spk_mono_intercon)); else - snd_soc_dapm_add_routes(codec, wm8962_spk_stereo_intercon, + snd_soc_dapm_add_routes(dapm, wm8962_spk_stereo_intercon, ARRAY_SIZE(wm8962_spk_stereo_intercon)); - snd_soc_dapm_disable_pin(codec, "Beep"); + snd_soc_dapm_disable_pin(dapm, "Beep"); return 0; } @@ -2819,7 +2820,7 @@ static int wm8962_set_bias_level(struct snd_soc_codec *codec, struct wm8962_priv *wm8962 = snd_soc_codec_get_drvdata(codec); int ret; - if (level == codec->bias_level) + if (level == codec->dapm.bias_level) return 0; switch (level) { @@ -2833,7 +2834,7 @@ static int wm8962_set_bias_level(struct snd_soc_codec *codec, break; case SND_SOC_BIAS_STANDBY: - if (codec->bias_level == SND_SOC_BIAS_OFF) { + if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { ret = regulator_bulk_enable(ARRAY_SIZE(wm8962->supplies), wm8962->supplies); if (ret != 0) { @@ -2883,7 +2884,7 @@ static int wm8962_set_bias_level(struct snd_soc_codec *codec, wm8962->supplies); break; } - codec->bias_level = level; + codec->dapm.bias_level = level; return 0; } @@ -3441,6 +3442,7 @@ static void wm8962_beep_work(struct work_struct *work) struct wm8962_priv *wm8962 = container_of(work, struct wm8962_priv, beep_work); struct snd_soc_codec *codec = wm8962->codec; + struct snd_soc_dapm_context *dapm = &codec->dapm; int i; int reg = 0; int best = 0; @@ -3457,16 +3459,16 @@ static void wm8962_beep_work(struct work_struct *work) reg = WM8962_BEEP_ENA | (best << WM8962_BEEP_RATE_SHIFT); - snd_soc_dapm_enable_pin(codec, "Beep"); + snd_soc_dapm_enable_pin(dapm, "Beep"); } else { dev_dbg(codec->dev, "Disabling beep\n"); - snd_soc_dapm_disable_pin(codec, "Beep"); + snd_soc_dapm_disable_pin(dapm, "Beep"); } snd_soc_update_bits(codec, WM8962_BEEP_GENERATOR_1, WM8962_BEEP_ENA | WM8962_BEEP_RATE_MASK, reg); - snd_soc_dapm_sync(codec); + snd_soc_dapm_sync(dapm); } /* For usability define a way of injecting beep events for the device - @@ -3713,7 +3715,7 @@ static int wm8962_probe(struct snd_soc_codec *codec) INIT_DELAYED_WORK(&wm8962->mic_work, wm8962_mic_work); codec->cache_sync = 1; - codec->idle_bias_off = 1; + codec->dapm.idle_bias_off = 1; ret = snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_I2C); if (ret != 0) { diff --git a/sound/soc/codecs/wm8971.c b/sound/soc/codecs/wm8971.c index 63f6dbf5d070..84b2dcb18aea 100644 --- a/sound/soc/codecs/wm8971.c +++ b/sound/soc/codecs/wm8971.c @@ -333,10 +333,11 @@ static const struct snd_soc_dapm_route audio_map[] = { static int wm8971_add_widgets(struct snd_soc_codec *codec) { - snd_soc_dapm_new_controls(codec, wm8971_dapm_widgets, - ARRAY_SIZE(wm8971_dapm_widgets)); + struct snd_soc_dapm_context *dapm = &codec->dapm; - snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); + snd_soc_dapm_new_controls(dapm, wm8971_dapm_widgets, + ARRAY_SIZE(wm8971_dapm_widgets)); + snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); return 0; } @@ -553,7 +554,7 @@ static int wm8971_set_bias_level(struct snd_soc_codec *codec, snd_soc_write(codec, WM8971_PWR1, 0x0001); break; } - codec->bias_level = level; + codec->dapm.bias_level = level; return 0; } @@ -590,9 +591,11 @@ static struct snd_soc_dai_driver wm8971_dai = { static void wm8971_work(struct work_struct *work) { - struct snd_soc_codec *codec = - container_of(work, struct snd_soc_codec, delayed_work.work); - wm8971_set_bias_level(codec, codec->bias_level); + struct snd_soc_dapm_context *dapm = + container_of(work, struct snd_soc_dapm_context, + delayed_work.work); + struct snd_soc_codec *codec = dapm->codec; + wm8971_set_bias_level(codec, codec->dapm.bias_level); } static int wm8971_suspend(struct snd_soc_codec *codec, pm_message_t state) @@ -620,11 +623,11 @@ static int wm8971_resume(struct snd_soc_codec *codec) wm8971_set_bias_level(codec, SND_SOC_BIAS_STANDBY); /* charge wm8971 caps */ - if (codec->suspend_bias_level == SND_SOC_BIAS_ON) { + if (codec->dapm.suspend_bias_level == SND_SOC_BIAS_ON) { reg = snd_soc_read(codec, WM8971_PWR1) & 0xfe3e; snd_soc_write(codec, WM8971_PWR1, reg | 0x01c0); - codec->bias_level = SND_SOC_BIAS_ON; - queue_delayed_work(wm8971_workq, &codec->delayed_work, + codec->dapm.bias_level = SND_SOC_BIAS_ON; + queue_delayed_work(wm8971_workq, &codec->dapm.delayed_work, msecs_to_jiffies(1000)); } @@ -643,7 +646,7 @@ static int wm8971_probe(struct snd_soc_codec *codec) return ret; } - INIT_DELAYED_WORK(&codec->delayed_work, wm8971_work); + INIT_DELAYED_WORK(&codec->dapm.delayed_work, wm8971_work); wm8971_workq = create_workqueue("wm8971"); if (wm8971_workq == NULL) return -ENOMEM; @@ -653,8 +656,8 @@ static int wm8971_probe(struct snd_soc_codec *codec) /* charge output caps - set vmid to 5k for quick power up */ reg = snd_soc_read(codec, WM8971_PWR1) & 0xfe3e; snd_soc_write(codec, WM8971_PWR1, reg | 0x01c0); - codec->bias_level = SND_SOC_BIAS_STANDBY; - queue_delayed_work(wm8971_workq, &codec->delayed_work, + codec->dapm.bias_level = SND_SOC_BIAS_STANDBY; + queue_delayed_work(wm8971_workq, &codec->dapm.delayed_work, msecs_to_jiffies(1000)); /* set the update bits */ diff --git a/sound/soc/codecs/wm8974.c b/sound/soc/codecs/wm8974.c index b4363f6d19b3..d19bb14842d4 100644 --- a/sound/soc/codecs/wm8974.c +++ b/sound/soc/codecs/wm8974.c @@ -274,10 +274,11 @@ static const struct snd_soc_dapm_route audio_map[] = { static int wm8974_add_widgets(struct snd_soc_codec *codec) { - snd_soc_dapm_new_controls(codec, wm8974_dapm_widgets, - ARRAY_SIZE(wm8974_dapm_widgets)); + struct snd_soc_dapm_context *dapm = &codec->dapm; - snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); + snd_soc_dapm_new_controls(dapm, wm8974_dapm_widgets, + ARRAY_SIZE(wm8974_dapm_widgets)); + snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); return 0; } @@ -530,7 +531,7 @@ static int wm8974_set_bias_level(struct snd_soc_codec *codec, case SND_SOC_BIAS_STANDBY: power1 |= WM8974_POWER1_BIASEN | WM8974_POWER1_BUFIOEN; - if (codec->bias_level == SND_SOC_BIAS_OFF) { + if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { /* Initial cap charge at VMID 5k */ snd_soc_write(codec, WM8974_POWER1, power1 | 0x3); mdelay(100); @@ -547,7 +548,7 @@ static int wm8974_set_bias_level(struct snd_soc_codec *codec, break; } - codec->bias_level = level; + codec->dapm.bias_level = level; return 0; } diff --git a/sound/soc/codecs/wm8978.c b/sound/soc/codecs/wm8978.c index 13b979a71a7c..ac43b6088e2e 100644 --- a/sound/soc/codecs/wm8978.c +++ b/sound/soc/codecs/wm8978.c @@ -355,11 +355,12 @@ static const struct snd_soc_dapm_route audio_map[] = { static int wm8978_add_widgets(struct snd_soc_codec *codec) { - snd_soc_dapm_new_controls(codec, wm8978_dapm_widgets, - ARRAY_SIZE(wm8978_dapm_widgets)); + struct snd_soc_dapm_context *dapm = &codec->dapm; + snd_soc_dapm_new_controls(dapm, wm8978_dapm_widgets, + ARRAY_SIZE(wm8978_dapm_widgets)); /* set up the WM8978 audio map */ - snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); + snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); return 0; } @@ -837,7 +838,7 @@ static int wm8978_set_bias_level(struct snd_soc_codec *codec, /* bit 3: enable bias, bit 2: enable I/O tie off buffer */ power1 |= 0xc; - if (codec->bias_level == SND_SOC_BIAS_OFF) { + if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { /* Initial cap charge at VMID 5k */ snd_soc_write(codec, WM8978_POWER_MANAGEMENT_1, power1 | 0x3); @@ -857,7 +858,7 @@ static int wm8978_set_bias_level(struct snd_soc_codec *codec, dev_dbg(codec->dev, "%s: %d, %x\n", __func__, level, power1); - codec->bias_level = level; + codec->dapm.bias_level = level; return 0; } diff --git a/sound/soc/codecs/wm8985.c b/sound/soc/codecs/wm8985.c index fd2e7cca1228..c3c8fd23d503 100644 --- a/sound/soc/codecs/wm8985.c +++ b/sound/soc/codecs/wm8985.c @@ -533,10 +533,11 @@ static int eqmode_put(struct snd_kcontrol *kcontrol, static int wm8985_add_widgets(struct snd_soc_codec *codec) { - snd_soc_dapm_new_controls(codec, wm8985_dapm_widgets, - ARRAY_SIZE(wm8985_dapm_widgets)); + struct snd_soc_dapm_context *dapm = &codec->dapm; - snd_soc_dapm_add_routes(codec, audio_map, + snd_soc_dapm_new_controls(dapm, wm8985_dapm_widgets, + ARRAY_SIZE(wm8985_dapm_widgets)); + snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); return 0; } @@ -879,7 +880,7 @@ static int wm8985_set_bias_level(struct snd_soc_codec *codec, 1 << WM8985_VMIDSEL_SHIFT); break; case SND_SOC_BIAS_STANDBY: - if (codec->bias_level == SND_SOC_BIAS_OFF) { + if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { ret = regulator_bulk_enable(ARRAY_SIZE(wm8985->supplies), wm8985->supplies); if (ret) { @@ -939,7 +940,7 @@ static int wm8985_set_bias_level(struct snd_soc_codec *codec, break; } - codec->bias_level = level; + codec->dapm.bias_level = level; return 0; } diff --git a/sound/soc/codecs/wm8988.c b/sound/soc/codecs/wm8988.c index d7f259711970..0bc2eb530c7a 100644 --- a/sound/soc/codecs/wm8988.c +++ b/sound/soc/codecs/wm8988.c @@ -677,7 +677,7 @@ static int wm8988_set_bias_level(struct snd_soc_codec *codec, break; case SND_SOC_BIAS_STANDBY: - if (codec->bias_level == SND_SOC_BIAS_OFF) { + if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { /* VREF, VMID=2x5k */ snd_soc_write(codec, WM8988_PWR1, pwr_reg | 0x1c1); @@ -693,7 +693,7 @@ static int wm8988_set_bias_level(struct snd_soc_codec *codec, snd_soc_write(codec, WM8988_PWR1, 0x0000); break; } - codec->bias_level = level; + codec->dapm.bias_level = level; return 0; } @@ -759,6 +759,7 @@ static int wm8988_resume(struct snd_soc_codec *codec) static int wm8988_probe(struct snd_soc_codec *codec) { struct wm8988_priv *wm8988 = snd_soc_codec_get_drvdata(codec); + struct snd_soc_dapm_context *dapm = &codec->dapm; int ret = 0; u16 reg; @@ -790,9 +791,9 @@ static int wm8988_probe(struct snd_soc_codec *codec) snd_soc_add_controls(codec, wm8988_snd_controls, ARRAY_SIZE(wm8988_snd_controls)); - snd_soc_dapm_new_controls(codec, wm8988_dapm_widgets, + snd_soc_dapm_new_controls(dapm, wm8988_dapm_widgets, ARRAY_SIZE(wm8988_dapm_widgets)); - snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); + snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); return 0; } diff --git a/sound/soc/codecs/wm8990.c b/sound/soc/codecs/wm8990.c index 264828e4e67c..309664ea7dc3 100644 --- a/sound/soc/codecs/wm8990.c +++ b/sound/soc/codecs/wm8990.c @@ -914,11 +914,12 @@ static const struct snd_soc_dapm_route audio_map[] = { static int wm8990_add_widgets(struct snd_soc_codec *codec) { - snd_soc_dapm_new_controls(codec, wm8990_dapm_widgets, - ARRAY_SIZE(wm8990_dapm_widgets)); + struct snd_soc_dapm_context *dapm = &codec->dapm; + snd_soc_dapm_new_controls(dapm, wm8990_dapm_widgets, + ARRAY_SIZE(wm8990_dapm_widgets)); /* set up the WM8990 audio map */ - snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); + snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); return 0; } @@ -1170,7 +1171,7 @@ static int wm8990_set_bias_level(struct snd_soc_codec *codec, break; case SND_SOC_BIAS_STANDBY: - if (codec->bias_level == SND_SOC_BIAS_OFF) { + if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { /* Enable all output discharge bits */ snd_soc_write(codec, WM8990_ANTIPOP1, WM8990_DIS_LLINE | WM8990_DIS_RLINE | WM8990_DIS_OUT3 | @@ -1266,7 +1267,7 @@ static int wm8990_set_bias_level(struct snd_soc_codec *codec, break; } - codec->bias_level = level; + codec->dapm.bias_level = level; return 0; } diff --git a/sound/soc/codecs/wm8993.c b/sound/soc/codecs/wm8993.c index 67fe5ccc6082..bcc54be572ce 100644 --- a/sound/soc/codecs/wm8993.c +++ b/sound/soc/codecs/wm8993.c @@ -970,7 +970,7 @@ static int wm8993_set_bias_level(struct snd_soc_codec *codec, break; case SND_SOC_BIAS_STANDBY: - if (codec->bias_level == SND_SOC_BIAS_OFF) { + if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { ret = regulator_bulk_enable(ARRAY_SIZE(wm8993->supplies), wm8993->supplies); if (ret != 0) @@ -1045,7 +1045,7 @@ static int wm8993_set_bias_level(struct snd_soc_codec *codec, break; } - codec->bias_level = level; + codec->dapm.bias_level = level; return 0; } @@ -1424,6 +1424,7 @@ static struct snd_soc_dai_driver wm8993_dai = { static int wm8993_probe(struct snd_soc_codec *codec) { struct wm8993_priv *wm8993 = snd_soc_codec_get_drvdata(codec); + struct snd_soc_dapm_context *dapm = &codec->dapm; int ret, i, val; wm8993->hubs_data.hp_startup_mode = 1; @@ -1505,11 +1506,11 @@ static int wm8993_probe(struct snd_soc_codec *codec) ARRAY_SIZE(wm8993_eq_controls)); } - snd_soc_dapm_new_controls(codec, wm8993_dapm_widgets, + snd_soc_dapm_new_controls(dapm, wm8993_dapm_widgets, ARRAY_SIZE(wm8993_dapm_widgets)); wm_hubs_add_analogue_controls(codec); - snd_soc_dapm_add_routes(codec, routes, ARRAY_SIZE(routes)); + snd_soc_dapm_add_routes(dapm, routes, ARRAY_SIZE(routes)); wm_hubs_add_analogue_routes(codec, wm8993->pdata.lineout1_diff, wm8993->pdata.lineout2_diff); diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index d81cac5b93b4..f7dea3d34a3e 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c @@ -1835,7 +1835,7 @@ static int configure_clock(struct snd_soc_codec *codec) snd_soc_update_bits(codec, WM8994_CLOCKING_1, WM8994_SYSCLK_SRC, new); - snd_soc_dapm_sync(codec); + snd_soc_dapm_sync(&codec->dapm); return 0; } @@ -3108,7 +3108,7 @@ static int wm8994_set_bias_level(struct snd_soc_codec *codec, break; case SND_SOC_BIAS_STANDBY: - if (codec->bias_level == SND_SOC_BIAS_OFF) { + if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { /* Tweak DC servo and DSP configuration for * improved performance. */ if (wm8994->revision < 4) { @@ -3152,7 +3152,7 @@ static int wm8994_set_bias_level(struct snd_soc_codec *codec, break; case SND_SOC_BIAS_OFF: - if (codec->bias_level == SND_SOC_BIAS_STANDBY) { + if (codec->dapm.bias_level == SND_SOC_BIAS_STANDBY) { /* Switch over to startup biases */ snd_soc_update_bits(codec, WM8994_ANTIPOP_2, WM8994_BIAS_SRC | @@ -3187,7 +3187,7 @@ static int wm8994_set_bias_level(struct snd_soc_codec *codec, } break; } - codec->bias_level = level; + codec->dapm.bias_level = level; return 0; } @@ -3895,6 +3895,7 @@ static irqreturn_t wm8994_mic_irq(int irq, void *data) static int wm8994_codec_probe(struct snd_soc_codec *codec) { struct wm8994_priv *wm8994; + struct snd_soc_dapm_context *dapm = &codec->dapm; int ret, i; codec->control_data = dev_get_drvdata(codec->dev->parent); @@ -4033,10 +4034,10 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) wm_hubs_add_analogue_controls(codec); snd_soc_add_controls(codec, wm8994_snd_controls, ARRAY_SIZE(wm8994_snd_controls)); - snd_soc_dapm_new_controls(codec, wm8994_dapm_widgets, + snd_soc_dapm_new_controls(dapm, wm8994_dapm_widgets, ARRAY_SIZE(wm8994_dapm_widgets)); wm_hubs_add_analogue_routes(codec, 0, 0); - snd_soc_dapm_add_routes(codec, intercon, ARRAY_SIZE(intercon)); + snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon)); return 0; diff --git a/sound/soc/codecs/wm9081.c b/sound/soc/codecs/wm9081.c index ecc7c37180c7..c03e2c3e24e1 100644 --- a/sound/soc/codecs/wm9081.c +++ b/sound/soc/codecs/wm9081.c @@ -805,7 +805,7 @@ static int wm9081_set_bias_level(struct snd_soc_codec *codec, case SND_SOC_BIAS_STANDBY: /* Initial cold start */ - if (codec->bias_level == SND_SOC_BIAS_OFF) { + if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { /* Disable LINEOUT discharge */ reg = snd_soc_read(codec, WM9081_ANTI_POP_CONTROL); reg &= ~WM9081_LINEOUT_DISCH; @@ -865,7 +865,7 @@ static int wm9081_set_bias_level(struct snd_soc_codec *codec, break; } - codec->bias_level = level; + codec->dapm.bias_level = level; return 0; } @@ -1228,6 +1228,7 @@ static struct snd_soc_dai_driver wm9081_dai = { static int wm9081_probe(struct snd_soc_codec *codec) { struct wm9081_priv *wm9081 = snd_soc_codec_get_drvdata(codec); + struct snd_soc_dapm_context *dapm = &codec->dapm; int ret; u16 reg; @@ -1269,9 +1270,9 @@ static int wm9081_probe(struct snd_soc_codec *codec) ARRAY_SIZE(wm9081_eq_controls)); } - snd_soc_dapm_new_controls(codec, wm9081_dapm_widgets, + snd_soc_dapm_new_controls(dapm, wm9081_dapm_widgets, ARRAY_SIZE(wm9081_dapm_widgets)); - snd_soc_dapm_add_routes(codec, audio_paths, ARRAY_SIZE(audio_paths)); + snd_soc_dapm_add_routes(dapm, audio_paths, ARRAY_SIZE(audio_paths)); return ret; } diff --git a/sound/soc/codecs/wm9090.c b/sound/soc/codecs/wm9090.c index 99c046ba46bb..b5afa01aa383 100644 --- a/sound/soc/codecs/wm9090.c +++ b/sound/soc/codecs/wm9090.c @@ -443,31 +443,32 @@ static const struct snd_soc_dapm_route audio_map_in2_diff[] = { static int wm9090_add_controls(struct snd_soc_codec *codec) { struct wm9090_priv *wm9090 = snd_soc_codec_get_drvdata(codec); + struct snd_soc_dapm_context *dapm = &codec->dapm; int i; - snd_soc_dapm_new_controls(codec, wm9090_dapm_widgets, + snd_soc_dapm_new_controls(dapm, wm9090_dapm_widgets, ARRAY_SIZE(wm9090_dapm_widgets)); - snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); + snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); snd_soc_add_controls(codec, wm9090_controls, ARRAY_SIZE(wm9090_controls)); if (wm9090->pdata.lin1_diff) { - snd_soc_dapm_add_routes(codec, audio_map_in1_diff, + snd_soc_dapm_add_routes(dapm, audio_map_in1_diff, ARRAY_SIZE(audio_map_in1_diff)); } else { - snd_soc_dapm_add_routes(codec, audio_map_in1_se, + snd_soc_dapm_add_routes(dapm, audio_map_in1_se, ARRAY_SIZE(audio_map_in1_se)); snd_soc_add_controls(codec, wm9090_in1_se_controls, ARRAY_SIZE(wm9090_in1_se_controls)); } if (wm9090->pdata.lin2_diff) { - snd_soc_dapm_add_routes(codec, audio_map_in2_diff, + snd_soc_dapm_add_routes(dapm, audio_map_in2_diff, ARRAY_SIZE(audio_map_in2_diff)); } else { - snd_soc_dapm_add_routes(codec, audio_map_in2_se, + snd_soc_dapm_add_routes(dapm, audio_map_in2_se, ARRAY_SIZE(audio_map_in2_se)); snd_soc_add_controls(codec, wm9090_in2_se_controls, ARRAY_SIZE(wm9090_in2_se_controls)); @@ -514,7 +515,7 @@ static int wm9090_set_bias_level(struct snd_soc_codec *codec, break; case SND_SOC_BIAS_STANDBY: - if (codec->bias_level == SND_SOC_BIAS_OFF) { + if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { /* Restore the register cache */ for (i = 1; i < codec->driver->reg_cache_size; i++) { if (reg_cache[i] == wm9090_reg_defaults[i]) @@ -544,7 +545,7 @@ static int wm9090_set_bias_level(struct snd_soc_codec *codec, break; } - codec->bias_level = level; + codec->dapm.bias_level = level; return 0; } diff --git a/sound/soc/codecs/wm9705.c b/sound/soc/codecs/wm9705.c index a144acda751c..58d120824498 100644 --- a/sound/soc/codecs/wm9705.c +++ b/sound/soc/codecs/wm9705.c @@ -203,9 +203,11 @@ static const struct snd_soc_dapm_route audio_map[] = { static int wm9705_add_widgets(struct snd_soc_codec *codec) { - snd_soc_dapm_new_controls(codec, wm9705_dapm_widgets, + struct snd_soc_dapm_context *dapm = &codec->dapm; + + snd_soc_dapm_new_controls(dapm, wm9705_dapm_widgets, ARRAY_SIZE(wm9705_dapm_widgets)); - snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); + snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); return 0; } diff --git a/sound/soc/codecs/wm9712.c b/sound/soc/codecs/wm9712.c index d2f224d62744..3ca42a35e03a 100644 --- a/sound/soc/codecs/wm9712.c +++ b/sound/soc/codecs/wm9712.c @@ -432,10 +432,11 @@ static const struct snd_soc_dapm_route audio_map[] = { static int wm9712_add_widgets(struct snd_soc_codec *codec) { - snd_soc_dapm_new_controls(codec, wm9712_dapm_widgets, - ARRAY_SIZE(wm9712_dapm_widgets)); + struct snd_soc_dapm_context *dapm = &codec->dapm; - snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); + snd_soc_dapm_new_controls(dapm, wm9712_dapm_widgets, + ARRAY_SIZE(wm9712_dapm_widgets)); + snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); return 0; } @@ -570,7 +571,7 @@ static int wm9712_set_bias_level(struct snd_soc_codec *codec, ac97_write(codec, AC97_POWERDOWN, 0xffff); break; } - codec->bias_level = level; + codec->dapm.bias_level = level; return 0; } diff --git a/sound/soc/codecs/wm9713.c b/sound/soc/codecs/wm9713.c index 7da13b07a53d..87b236b16016 100644 --- a/sound/soc/codecs/wm9713.c +++ b/sound/soc/codecs/wm9713.c @@ -647,10 +647,12 @@ static const struct snd_soc_dapm_route audio_map[] = { static int wm9713_add_widgets(struct snd_soc_codec *codec) { - snd_soc_dapm_new_controls(codec, wm9713_dapm_widgets, + struct snd_soc_dapm_context *dapm = &codec->dapm; + + snd_soc_dapm_new_controls(dapm, wm9713_dapm_widgets, ARRAY_SIZE(wm9713_dapm_widgets)); - snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); + snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); return 0; } @@ -1147,7 +1149,7 @@ static int wm9713_set_bias_level(struct snd_soc_codec *codec, ac97_write(codec, AC97_POWERDOWN, 0xffff); break; } - codec->bias_level = level; + codec->dapm.bias_level = level; return 0; } diff --git a/sound/soc/codecs/wm_hubs.c b/sound/soc/codecs/wm_hubs.c index 008b1f27aea8..8aff0efe72f5 100644 --- a/sound/soc/codecs/wm_hubs.c +++ b/sound/soc/codecs/wm_hubs.c @@ -814,6 +814,8 @@ static const struct snd_soc_dapm_route lineout2_se_routes[] = { int wm_hubs_add_analogue_controls(struct snd_soc_codec *codec) { + struct snd_soc_dapm_context *dapm = &codec->dapm; + /* Latch volume update bits & default ZC on */ snd_soc_update_bits(codec, WM8993_LEFT_LINE_INPUT_1_2_VOLUME, WM8993_IN1_VU, WM8993_IN1_VU); @@ -842,7 +844,7 @@ int wm_hubs_add_analogue_controls(struct snd_soc_codec *codec) snd_soc_add_controls(codec, analogue_snd_controls, ARRAY_SIZE(analogue_snd_controls)); - snd_soc_dapm_new_controls(codec, analogue_dapm_widgets, + snd_soc_dapm_new_controls(dapm, analogue_dapm_widgets, ARRAY_SIZE(analogue_dapm_widgets)); return 0; } @@ -851,24 +853,26 @@ EXPORT_SYMBOL_GPL(wm_hubs_add_analogue_controls); int wm_hubs_add_analogue_routes(struct snd_soc_codec *codec, int lineout1_diff, int lineout2_diff) { - snd_soc_dapm_add_routes(codec, analogue_routes, + struct snd_soc_dapm_context *dapm = &codec->dapm; + + snd_soc_dapm_add_routes(dapm, analogue_routes, ARRAY_SIZE(analogue_routes)); if (lineout1_diff) - snd_soc_dapm_add_routes(codec, + snd_soc_dapm_add_routes(dapm, lineout1_diff_routes, ARRAY_SIZE(lineout1_diff_routes)); else - snd_soc_dapm_add_routes(codec, + snd_soc_dapm_add_routes(dapm, lineout1_se_routes, ARRAY_SIZE(lineout1_se_routes)); if (lineout2_diff) - snd_soc_dapm_add_routes(codec, + snd_soc_dapm_add_routes(dapm, lineout2_diff_routes, ARRAY_SIZE(lineout2_diff_routes)); else - snd_soc_dapm_add_routes(codec, + snd_soc_dapm_add_routes(dapm, lineout2_se_routes, ARRAY_SIZE(lineout2_se_routes)); @@ -895,7 +899,7 @@ int wm_hubs_handle_analogue_pdata(struct snd_soc_codec *codec, * VMID as an output and can disable it. */ if (lineout1_diff && lineout2_diff) - codec->idle_bias_off = 1; + codec->dapm.idle_bias_off = 1; if (lineout1fb) snd_soc_update_bits(codec, WM8993_ADDITIONAL_CONTROL, diff --git a/sound/soc/davinci/davinci-evm.c b/sound/soc/davinci/davinci-evm.c index 2b07b17a6b2d..a2cf64b221e5 100644 --- a/sound/soc/davinci/davinci-evm.c +++ b/sound/soc/davinci/davinci-evm.c @@ -132,26 +132,27 @@ static const struct snd_soc_dapm_route audio_map[] = { static int evm_aic3x_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_dapm_context *dapm = &codec->dapm; /* Add davinci-evm specific widgets */ - snd_soc_dapm_new_controls(codec, aic3x_dapm_widgets, + snd_soc_dapm_new_controls(dapm, aic3x_dapm_widgets, ARRAY_SIZE(aic3x_dapm_widgets)); /* Set up davinci-evm specific audio path audio_map */ - snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); + snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); /* not connected */ - snd_soc_dapm_disable_pin(codec, "MONO_LOUT"); - snd_soc_dapm_disable_pin(codec, "HPLCOM"); - snd_soc_dapm_disable_pin(codec, "HPRCOM"); + snd_soc_dapm_disable_pin(dapm, "MONO_LOUT"); + snd_soc_dapm_disable_pin(dapm, "HPLCOM"); + snd_soc_dapm_disable_pin(dapm, "HPRCOM"); /* always connected */ - snd_soc_dapm_enable_pin(codec, "Headphone Jack"); - snd_soc_dapm_enable_pin(codec, "Line Out"); - snd_soc_dapm_enable_pin(codec, "Mic Jack"); - snd_soc_dapm_enable_pin(codec, "Line In"); + snd_soc_dapm_enable_pin(dapm, "Headphone Jack"); + snd_soc_dapm_enable_pin(dapm, "Line Out"); + snd_soc_dapm_enable_pin(dapm, "Mic Jack"); + snd_soc_dapm_enable_pin(dapm, "Line In"); - snd_soc_dapm_sync(codec); + snd_soc_dapm_sync(dapm); return 0; } diff --git a/sound/soc/ep93xx/snappercl15.c b/sound/soc/ep93xx/snappercl15.c index 28ab5ff772ac..f1c78516ccac 100644 --- a/sound/soc/ep93xx/snappercl15.c +++ b/sound/soc/ep93xx/snappercl15.c @@ -79,11 +79,12 @@ static const struct snd_soc_dapm_route audio_map[] = { static int snappercl15_tlv320aic23_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_dapm_context *dapm = &codec->dapm; - snd_soc_dapm_new_controls(codec, tlv320aic23_dapm_widgets, + snd_soc_dapm_new_controls(dapm, tlv320aic23_dapm_widgets, ARRAY_SIZE(tlv320aic23_dapm_widgets)); - snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); + snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); return 0; } diff --git a/sound/soc/imx/wm1133-ev1.c b/sound/soc/imx/wm1133-ev1.c index 30fdb15065be..46fadf497243 100644 --- a/sound/soc/imx/wm1133-ev1.c +++ b/sound/soc/imx/wm1133-ev1.c @@ -213,11 +213,12 @@ static struct snd_soc_jack_pin mic_jack_pins[] = { static int wm1133_ev1_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_dapm_context *dapm = &codec->dapm; - snd_soc_dapm_new_controls(codec, wm1133_ev1_widgets, + snd_soc_dapm_new_controls(dapm, wm1133_ev1_widgets, ARRAY_SIZE(wm1133_ev1_widgets)); - snd_soc_dapm_add_routes(codec, wm1133_ev1_map, + snd_soc_dapm_add_routes(dapm, wm1133_ev1_map, ARRAY_SIZE(wm1133_ev1_map)); /* Headphone jack detection */ @@ -234,7 +235,7 @@ static int wm1133_ev1_init(struct snd_soc_pcm_runtime *rtd) wm8350_mic_jack_detect(codec, &mic_jack, SND_JACK_MICROPHONE, SND_JACK_BTN_0); - snd_soc_dapm_force_enable_pin(codec, "Mic Bias"); + snd_soc_dapm_force_enable_pin(dapm, "Mic Bias"); return 0; } diff --git a/sound/soc/jz4740/qi_lb60.c b/sound/soc/jz4740/qi_lb60.c index ef1a99e6a3bd..70afbfada9fd 100644 --- a/sound/soc/jz4740/qi_lb60.c +++ b/sound/soc/jz4740/qi_lb60.c @@ -59,10 +59,11 @@ static int qi_lb60_codec_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + struct snd_soc_dapm_context *dapm = &codec->dapm; int ret; - snd_soc_dapm_nc_pin(codec, "LIN"); - snd_soc_dapm_nc_pin(codec, "RIN"); + snd_soc_dapm_nc_pin(dapm, "LIN"); + snd_soc_dapm_nc_pin(dapm, "RIN"); ret = snd_soc_dai_set_fmt(cpu_dai, QI_LB60_DAIFMT); if (ret < 0) { @@ -70,9 +71,11 @@ static int qi_lb60_codec_init(struct snd_soc_pcm_runtime *rtd) return ret; } - snd_soc_dapm_new_controls(codec, qi_lb60_widgets, ARRAY_SIZE(qi_lb60_widgets)); - snd_soc_dapm_add_routes(codec, qi_lb60_routes, ARRAY_SIZE(qi_lb60_routes)); - snd_soc_dapm_sync(codec); + snd_soc_dapm_new_controls(dapm, qi_lb60_widgets, + ARRAY_SIZE(qi_lb60_widgets)); + snd_soc_dapm_add_routes(dapm, qi_lb60_routes, + ARRAY_SIZE(qi_lb60_routes)); + snd_soc_dapm_sync(dapm); return 0; } diff --git a/sound/soc/kirkwood/kirkwood-t5325.c b/sound/soc/kirkwood/kirkwood-t5325.c index 51b52e31cb0b..07b6ecaed2f2 100644 --- a/sound/soc/kirkwood/kirkwood-t5325.c +++ b/sound/soc/kirkwood/kirkwood-t5325.c @@ -69,17 +69,18 @@ static const struct snd_soc_dapm_route t5325_route[] = { static int t5325_dai_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_dapm_context *dapm = &codec->dapm; - snd_soc_dapm_new_controls(codec, t5325_dapm_widgets, + snd_soc_dapm_new_controls(dapm, t5325_dapm_widgets, ARRAY_SIZE(t5325_dapm_widgets)); - snd_soc_dapm_add_routes(codec, t5325_route, ARRAY_SIZE(t5325_route)); + snd_soc_dapm_add_routes(dapm, t5325_route, ARRAY_SIZE(t5325_route)); - snd_soc_dapm_enable_pin(codec, "Mic Jack"); - snd_soc_dapm_enable_pin(codec, "Headphone Jack"); - snd_soc_dapm_enable_pin(codec, "Speaker"); + snd_soc_dapm_enable_pin(dapm, "Mic Jack"); + snd_soc_dapm_enable_pin(dapm, "Headphone Jack"); + snd_soc_dapm_enable_pin(dapm, "Speaker"); - snd_soc_dapm_sync(codec); + snd_soc_dapm_sync(dapm); return 0; } diff --git a/sound/soc/omap/am3517evm.c b/sound/soc/omap/am3517evm.c index 979dd508305f..668773def0dc 100644 --- a/sound/soc/omap/am3517evm.c +++ b/sound/soc/omap/am3517evm.c @@ -114,20 +114,21 @@ static const struct snd_soc_dapm_route audio_map[] = { static int am3517evm_aic23_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_dapm_context *dapm = &codec->dapm; /* Add am3517-evm specific widgets */ - snd_soc_dapm_new_controls(codec, tlv320aic23_dapm_widgets, + snd_soc_dapm_new_controls(dapm, tlv320aic23_dapm_widgets, ARRAY_SIZE(tlv320aic23_dapm_widgets)); /* Set up davinci-evm specific audio path audio_map */ - snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); + snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); /* always connected */ - snd_soc_dapm_enable_pin(codec, "Line Out"); - snd_soc_dapm_enable_pin(codec, "Line In"); - snd_soc_dapm_enable_pin(codec, "Mic In"); + snd_soc_dapm_enable_pin(dapm, "Line Out"); + snd_soc_dapm_enable_pin(dapm, "Line In"); + snd_soc_dapm_enable_pin(dapm, "Mic In"); - snd_soc_dapm_sync(codec); + snd_soc_dapm_sync(dapm); return 0; } diff --git a/sound/soc/omap/ams-delta.c b/sound/soc/omap/ams-delta.c index 438146addbb8..2101bdcee21f 100644 --- a/sound/soc/omap/ams-delta.c +++ b/sound/soc/omap/ams-delta.c @@ -26,7 +26,7 @@ #include #include -#include +#include #include #include @@ -94,6 +94,7 @@ 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 soc_enum *control = (struct soc_enum *)kcontrol->private_value; unsigned short pins; int pin, changed = 0; @@ -112,48 +113,48 @@ static int ams_delta_set_audio_mode(struct snd_kcontrol *kcontrol, /* Setup pins after corresponding bits if changed */ pin = !!(pins & (1 << AMS_DELTA_MOUTHPIECE)); - if (pin != snd_soc_dapm_get_pin_status(codec, "Mouthpiece")) { + if (pin != snd_soc_dapm_get_pin_status(dapm, "Mouthpiece")) { changed = 1; if (pin) - snd_soc_dapm_enable_pin(codec, "Mouthpiece"); + snd_soc_dapm_enable_pin(dapm, "Mouthpiece"); else - snd_soc_dapm_disable_pin(codec, "Mouthpiece"); + snd_soc_dapm_disable_pin(dapm, "Mouthpiece"); } pin = !!(pins & (1 << AMS_DELTA_EARPIECE)); - if (pin != snd_soc_dapm_get_pin_status(codec, "Earpiece")) { + if (pin != snd_soc_dapm_get_pin_status(dapm, "Earpiece")) { changed = 1; if (pin) - snd_soc_dapm_enable_pin(codec, "Earpiece"); + snd_soc_dapm_enable_pin(dapm, "Earpiece"); else - snd_soc_dapm_disable_pin(codec, "Earpiece"); + snd_soc_dapm_disable_pin(dapm, "Earpiece"); } pin = !!(pins & (1 << AMS_DELTA_MICROPHONE)); - if (pin != snd_soc_dapm_get_pin_status(codec, "Microphone")) { + if (pin != snd_soc_dapm_get_pin_status(dapm, "Microphone")) { changed = 1; if (pin) - snd_soc_dapm_enable_pin(codec, "Microphone"); + snd_soc_dapm_enable_pin(dapm, "Microphone"); else - snd_soc_dapm_disable_pin(codec, "Microphone"); + snd_soc_dapm_disable_pin(dapm, "Microphone"); } pin = !!(pins & (1 << AMS_DELTA_SPEAKER)); - if (pin != snd_soc_dapm_get_pin_status(codec, "Speaker")) { + if (pin != snd_soc_dapm_get_pin_status(dapm, "Speaker")) { changed = 1; if (pin) - snd_soc_dapm_enable_pin(codec, "Speaker"); + snd_soc_dapm_enable_pin(dapm, "Speaker"); else - snd_soc_dapm_disable_pin(codec, "Speaker"); + snd_soc_dapm_disable_pin(dapm, "Speaker"); } pin = !!(pins & (1 << AMS_DELTA_AGC)); if (pin != ams_delta_audio_agc) { ams_delta_audio_agc = pin; changed = 1; if (pin) - snd_soc_dapm_enable_pin(codec, "AGCIN"); + snd_soc_dapm_enable_pin(dapm, "AGCIN"); else - snd_soc_dapm_disable_pin(codec, "AGCIN"); + snd_soc_dapm_disable_pin(dapm, "AGCIN"); } if (changed) - snd_soc_dapm_sync(codec); + snd_soc_dapm_sync(dapm); mutex_unlock(&codec->mutex); @@ -164,19 +165,20 @@ 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; unsigned short pins, mode; - pins = ((snd_soc_dapm_get_pin_status(codec, "Mouthpiece") << + pins = ((snd_soc_dapm_get_pin_status(dapm, "Mouthpiece") << AMS_DELTA_MOUTHPIECE) | - (snd_soc_dapm_get_pin_status(codec, "Earpiece") << + (snd_soc_dapm_get_pin_status(dapm, "Earpiece") << AMS_DELTA_EARPIECE)); if (pins) - pins |= (snd_soc_dapm_get_pin_status(codec, "Microphone") << + pins |= (snd_soc_dapm_get_pin_status(dapm, "Microphone") << AMS_DELTA_MICROPHONE); else - pins = ((snd_soc_dapm_get_pin_status(codec, "Microphone") << + pins = ((snd_soc_dapm_get_pin_status(dapm, "Microphone") << AMS_DELTA_MICROPHONE) | - (snd_soc_dapm_get_pin_status(codec, "Speaker") << + (snd_soc_dapm_get_pin_status(dapm, "Speaker") << AMS_DELTA_SPEAKER) | (ams_delta_audio_agc << AMS_DELTA_AGC)); @@ -300,6 +302,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; del_timer_sync(&cx81801_timer); @@ -312,12 +315,12 @@ static void cx81801_close(struct tty_struct *tty) v253_ops.close(tty); /* Revert back to default audio input/output constellation */ - snd_soc_dapm_disable_pin(codec, "Mouthpiece"); - snd_soc_dapm_enable_pin(codec, "Earpiece"); - snd_soc_dapm_enable_pin(codec, "Microphone"); - snd_soc_dapm_disable_pin(codec, "Speaker"); - snd_soc_dapm_disable_pin(codec, "AGCIN"); - snd_soc_dapm_sync(codec); + snd_soc_dapm_disable_pin(dapm, "Mouthpiece"); + snd_soc_dapm_enable_pin(dapm, "Earpiece"); + snd_soc_dapm_enable_pin(dapm, "Microphone"); + snd_soc_dapm_disable_pin(dapm, "Speaker"); + snd_soc_dapm_disable_pin(dapm, "AGCIN"); + snd_soc_dapm_sync(dapm); } /* Line discipline .hangup() */ @@ -432,16 +435,16 @@ static int ams_delta_set_bias_level(struct snd_soc_card *card, case SND_SOC_BIAS_ON: case SND_SOC_BIAS_PREPARE: case SND_SOC_BIAS_STANDBY: - if (codec->bias_level == SND_SOC_BIAS_OFF) + if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) ams_delta_latch2_write(AMS_DELTA_LATCH2_MODEM_NRESET, AMS_DELTA_LATCH2_MODEM_NRESET); break; case SND_SOC_BIAS_OFF: - if (codec->bias_level != SND_SOC_BIAS_OFF) + if (codec->dapm.bias_level != SND_SOC_BIAS_OFF) ams_delta_latch2_write(AMS_DELTA_LATCH2_MODEM_NRESET, 0); } - codec->bias_level = level; + codec->dapm.bias_level = level; return 0; } @@ -492,6 +495,7 @@ 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; int ret; @@ -541,7 +545,7 @@ static int ams_delta_cx20442_init(struct snd_soc_pcm_runtime *rtd) } /* Add board specific DAPM widgets and routes */ - ret = snd_soc_dapm_new_controls(codec, ams_delta_dapm_widgets, + ret = snd_soc_dapm_new_controls(dapm, ams_delta_dapm_widgets, ARRAY_SIZE(ams_delta_dapm_widgets)); if (ret) { dev_warn(card->dev, @@ -550,7 +554,7 @@ static int ams_delta_cx20442_init(struct snd_soc_pcm_runtime *rtd) return 0; } - ret = snd_soc_dapm_add_routes(codec, ams_delta_audio_map, + ret = snd_soc_dapm_add_routes(dapm, ams_delta_audio_map, ARRAY_SIZE(ams_delta_audio_map)); if (ret) { dev_warn(card->dev, @@ -560,13 +564,13 @@ static int ams_delta_cx20442_init(struct snd_soc_pcm_runtime *rtd) } /* Set up initial pin constellation */ - snd_soc_dapm_disable_pin(codec, "Mouthpiece"); - snd_soc_dapm_enable_pin(codec, "Earpiece"); - snd_soc_dapm_enable_pin(codec, "Microphone"); - snd_soc_dapm_disable_pin(codec, "Speaker"); - snd_soc_dapm_disable_pin(codec, "AGCIN"); - snd_soc_dapm_disable_pin(codec, "AGCOUT"); - snd_soc_dapm_sync(codec); + snd_soc_dapm_disable_pin(dapm, "Mouthpiece"); + snd_soc_dapm_enable_pin(dapm, "Earpiece"); + snd_soc_dapm_enable_pin(dapm, "Microphone"); + snd_soc_dapm_disable_pin(dapm, "Speaker"); + snd_soc_dapm_disable_pin(dapm, "AGCIN"); + snd_soc_dapm_disable_pin(dapm, "AGCOUT"); + snd_soc_dapm_sync(dapm); /* Add virtual switch */ ret = snd_soc_add_controls(codec, ams_delta_audio_controls, diff --git a/sound/soc/omap/n810.c b/sound/soc/omap/n810.c index a3b6d897ad84..296cd9b7eecb 100644 --- a/sound/soc/omap/n810.c +++ b/sound/soc/omap/n810.c @@ -58,6 +58,7 @@ static int n810_dmic_func; static void n810_ext_control(struct snd_soc_codec *codec) { + struct snd_soc_dapm_context *dapm = &codec->dapm; int hp = 0, line1l = 0; switch (n810_jack_func) { @@ -72,25 +73,25 @@ static void n810_ext_control(struct snd_soc_codec *codec) } if (n810_spk_func) - snd_soc_dapm_enable_pin(codec, "Ext Spk"); + snd_soc_dapm_enable_pin(dapm, "Ext Spk"); else - snd_soc_dapm_disable_pin(codec, "Ext Spk"); + snd_soc_dapm_disable_pin(dapm, "Ext Spk"); if (hp) - snd_soc_dapm_enable_pin(codec, "Headphone Jack"); + snd_soc_dapm_enable_pin(dapm, "Headphone Jack"); else - snd_soc_dapm_disable_pin(codec, "Headphone Jack"); + snd_soc_dapm_disable_pin(dapm, "Headphone Jack"); if (line1l) - snd_soc_dapm_enable_pin(codec, "LINE1L"); + snd_soc_dapm_enable_pin(dapm, "LINE1L"); else - snd_soc_dapm_disable_pin(codec, "LINE1L"); + snd_soc_dapm_disable_pin(dapm, "LINE1L"); if (n810_dmic_func) - snd_soc_dapm_enable_pin(codec, "DMic"); + snd_soc_dapm_enable_pin(dapm, "DMic"); else - snd_soc_dapm_disable_pin(codec, "DMic"); + snd_soc_dapm_disable_pin(dapm, "DMic"); - snd_soc_dapm_sync(codec); + snd_soc_dapm_sync(dapm); } static int n810_startup(struct snd_pcm_substream *substream) @@ -274,17 +275,18 @@ static const struct snd_kcontrol_new aic33_n810_controls[] = { static int n810_aic33_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_dapm_context *dapm = &codec->dapm; int err; /* Not connected */ - snd_soc_dapm_nc_pin(codec, "MONO_LOUT"); - snd_soc_dapm_nc_pin(codec, "HPLCOM"); - snd_soc_dapm_nc_pin(codec, "HPRCOM"); - snd_soc_dapm_nc_pin(codec, "MIC3L"); - snd_soc_dapm_nc_pin(codec, "MIC3R"); - snd_soc_dapm_nc_pin(codec, "LINE1R"); - snd_soc_dapm_nc_pin(codec, "LINE2L"); - snd_soc_dapm_nc_pin(codec, "LINE2R"); + snd_soc_dapm_nc_pin(dapm, "MONO_LOUT"); + snd_soc_dapm_nc_pin(dapm, "HPLCOM"); + snd_soc_dapm_nc_pin(dapm, "HPRCOM"); + snd_soc_dapm_nc_pin(dapm, "MIC3L"); + snd_soc_dapm_nc_pin(dapm, "MIC3R"); + snd_soc_dapm_nc_pin(dapm, "LINE1R"); + snd_soc_dapm_nc_pin(dapm, "LINE2L"); + snd_soc_dapm_nc_pin(dapm, "LINE2R"); /* Add N810 specific controls */ err = snd_soc_add_controls(codec, aic33_n810_controls, @@ -293,13 +295,13 @@ static int n810_aic33_init(struct snd_soc_pcm_runtime *rtd) return err; /* Add N810 specific widgets */ - snd_soc_dapm_new_controls(codec, aic33_dapm_widgets, + snd_soc_dapm_new_controls(dapm, aic33_dapm_widgets, ARRAY_SIZE(aic33_dapm_widgets)); /* Set up N810 specific audio path audio_map */ - snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); + snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); - snd_soc_dapm_sync(codec); + snd_soc_dapm_sync(dapm); return 0; } diff --git a/sound/soc/omap/omap3pandora.c b/sound/soc/omap/omap3pandora.c index dbd9d96b5f92..93e83c0f6660 100644 --- a/sound/soc/omap/omap3pandora.c +++ b/sound/soc/omap/omap3pandora.c @@ -170,51 +170,53 @@ static const struct snd_soc_dapm_route omap3pandora_in_map[] = { 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(codec, "EARPIECE"); - snd_soc_dapm_nc_pin(codec, "PREDRIVEL"); - snd_soc_dapm_nc_pin(codec, "PREDRIVER"); - snd_soc_dapm_nc_pin(codec, "HSOL"); - snd_soc_dapm_nc_pin(codec, "HSOR"); - snd_soc_dapm_nc_pin(codec, "CARKITL"); - snd_soc_dapm_nc_pin(codec, "CARKITR"); - snd_soc_dapm_nc_pin(codec, "HFL"); - snd_soc_dapm_nc_pin(codec, "HFR"); - snd_soc_dapm_nc_pin(codec, "VIBRA"); - - ret = snd_soc_dapm_new_controls(codec, omap3pandora_out_dapm_widgets, + snd_soc_dapm_nc_pin(dapm, "EARPIECE"); + snd_soc_dapm_nc_pin(dapm, "PREDRIVEL"); + snd_soc_dapm_nc_pin(dapm, "PREDRIVER"); + snd_soc_dapm_nc_pin(dapm, "HSOL"); + snd_soc_dapm_nc_pin(dapm, "HSOR"); + snd_soc_dapm_nc_pin(dapm, "CARKITL"); + snd_soc_dapm_nc_pin(dapm, "CARKITR"); + snd_soc_dapm_nc_pin(dapm, "HFL"); + 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; - snd_soc_dapm_add_routes(codec, omap3pandora_out_map, + snd_soc_dapm_add_routes(dapm, omap3pandora_out_map, ARRAY_SIZE(omap3pandora_out_map)); - return snd_soc_dapm_sync(codec); + return snd_soc_dapm_sync(dapm); } 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(codec, "HSMIC"); - snd_soc_dapm_nc_pin(codec, "CARKITMIC"); - snd_soc_dapm_nc_pin(codec, "DIGIMIC0"); - snd_soc_dapm_nc_pin(codec, "DIGIMIC1"); + snd_soc_dapm_nc_pin(dapm, "HSMIC"); + snd_soc_dapm_nc_pin(dapm, "CARKITMIC"); + snd_soc_dapm_nc_pin(dapm, "DIGIMIC0"); + snd_soc_dapm_nc_pin(dapm, "DIGIMIC1"); - ret = snd_soc_dapm_new_controls(codec, omap3pandora_in_dapm_widgets, + ret = snd_soc_dapm_new_controls(dapm, omap3pandora_in_dapm_widgets, ARRAY_SIZE(omap3pandora_in_dapm_widgets)); if (ret < 0) return ret; - snd_soc_dapm_add_routes(codec, omap3pandora_in_map, + snd_soc_dapm_add_routes(dapm, omap3pandora_in_map, ARRAY_SIZE(omap3pandora_in_map)); - return snd_soc_dapm_sync(codec); + return snd_soc_dapm_sync(dapm); } static struct snd_soc_ops omap3pandora_ops = { diff --git a/sound/soc/omap/osk5912.c b/sound/soc/omap/osk5912.c index f0e662556428..c2a54204559d 100644 --- a/sound/soc/omap/osk5912.c +++ b/sound/soc/omap/osk5912.c @@ -116,19 +116,20 @@ static const struct snd_soc_dapm_route audio_map[] = { static int osk_tlv320aic23_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_dapm_context *dapm = &codec->dapm; /* Add osk5912 specific widgets */ - snd_soc_dapm_new_controls(codec, tlv320aic23_dapm_widgets, + snd_soc_dapm_new_controls(dapm, tlv320aic23_dapm_widgets, ARRAY_SIZE(tlv320aic23_dapm_widgets)); /* Set up osk5912 specific audio path audio_map */ - snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); + snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); - snd_soc_dapm_enable_pin(codec, "Headphone Jack"); - snd_soc_dapm_enable_pin(codec, "Line In"); - snd_soc_dapm_enable_pin(codec, "Mic Jack"); + snd_soc_dapm_enable_pin(dapm, "Headphone Jack"); + snd_soc_dapm_enable_pin(dapm, "Line In"); + snd_soc_dapm_enable_pin(dapm, "Mic Jack"); - snd_soc_dapm_sync(codec); + snd_soc_dapm_sync(dapm); return 0; } diff --git a/sound/soc/omap/rx51.c b/sound/soc/omap/rx51.c index 04b5723bf89b..62fc7a4f306b 100644 --- a/sound/soc/omap/rx51.c +++ b/sound/soc/omap/rx51.c @@ -58,19 +58,21 @@ static int rx51_jack_func; static void rx51_ext_control(struct snd_soc_codec *codec) { + struct snd_soc_dapm_context *dapm = &codec->dapm; + if (rx51_spk_func) - snd_soc_dapm_enable_pin(codec, "Ext Spk"); + snd_soc_dapm_enable_pin(dapm, "Ext Spk"); else - snd_soc_dapm_disable_pin(codec, "Ext Spk"); + snd_soc_dapm_disable_pin(dapm, "Ext Spk"); if (rx51_dmic_func) - snd_soc_dapm_enable_pin(codec, "DMic"); + snd_soc_dapm_enable_pin(dapm, "DMic"); else - snd_soc_dapm_disable_pin(codec, "DMic"); + snd_soc_dapm_disable_pin(dapm, "DMic"); gpio_set_value(RX51_TVOUT_SEL_GPIO, rx51_jack_func == RX51_JACK_TVOUT); - snd_soc_dapm_sync(codec); + snd_soc_dapm_sync(dapm); } static int rx51_startup(struct snd_pcm_substream *substream) @@ -244,12 +246,13 @@ static const struct snd_kcontrol_new aic34_rx51_controls[] = { static int rx51_aic34_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_dapm_context *dapm = &codec->dapm; int err; /* Set up NC codec pins */ - snd_soc_dapm_nc_pin(codec, "MIC3L"); - snd_soc_dapm_nc_pin(codec, "MIC3R"); - snd_soc_dapm_nc_pin(codec, "LINE1R"); + snd_soc_dapm_nc_pin(dapm, "MIC3L"); + snd_soc_dapm_nc_pin(dapm, "MIC3R"); + snd_soc_dapm_nc_pin(dapm, "LINE1R"); /* Add RX-51 specific controls */ err = snd_soc_add_controls(codec, aic34_rx51_controls, @@ -258,13 +261,13 @@ static int rx51_aic34_init(struct snd_soc_pcm_runtime *rtd) return err; /* Add RX-51 specific widgets */ - snd_soc_dapm_new_controls(codec, aic34_dapm_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(codec, audio_map, ARRAY_SIZE(audio_map)); + snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); - snd_soc_dapm_sync(codec); + snd_soc_dapm_sync(dapm); /* AV jack detection */ err = snd_soc_jack_new(codec, "AV Jack", diff --git a/sound/soc/omap/sdp3430.c b/sound/soc/omap/sdp3430.c index 07fbcf7d2411..a3dd07a39fec 100644 --- a/sound/soc/omap/sdp3430.c +++ b/sound/soc/omap/sdp3430.c @@ -191,39 +191,40 @@ static const struct snd_soc_dapm_route audio_map[] = { static int sdp3430_twl4030_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_dapm_context *dapm = &codec->dapm; int ret; /* Add SDP3430 specific widgets */ - ret = snd_soc_dapm_new_controls(codec, sdp3430_twl4030_dapm_widgets, + ret = snd_soc_dapm_new_controls(dapm, sdp3430_twl4030_dapm_widgets, ARRAY_SIZE(sdp3430_twl4030_dapm_widgets)); if (ret) return ret; /* Set up SDP3430 specific audio path audio_map */ - snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); + snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); /* SDP3430 connected pins */ - snd_soc_dapm_enable_pin(codec, "Ext Mic"); - snd_soc_dapm_enable_pin(codec, "Ext Spk"); - snd_soc_dapm_disable_pin(codec, "Headset Mic"); - snd_soc_dapm_disable_pin(codec, "Headset Stereophone"); + snd_soc_dapm_enable_pin(dapm, "Ext Mic"); + snd_soc_dapm_enable_pin(dapm, "Ext Spk"); + snd_soc_dapm_disable_pin(dapm, "Headset Mic"); + snd_soc_dapm_disable_pin(dapm, "Headset Stereophone"); /* TWL4030 not connected pins */ - snd_soc_dapm_nc_pin(codec, "AUXL"); - snd_soc_dapm_nc_pin(codec, "AUXR"); - snd_soc_dapm_nc_pin(codec, "CARKITMIC"); - snd_soc_dapm_nc_pin(codec, "DIGIMIC0"); - snd_soc_dapm_nc_pin(codec, "DIGIMIC1"); - - snd_soc_dapm_nc_pin(codec, "OUTL"); - snd_soc_dapm_nc_pin(codec, "OUTR"); - snd_soc_dapm_nc_pin(codec, "EARPIECE"); - snd_soc_dapm_nc_pin(codec, "PREDRIVEL"); - snd_soc_dapm_nc_pin(codec, "PREDRIVER"); - snd_soc_dapm_nc_pin(codec, "CARKITL"); - snd_soc_dapm_nc_pin(codec, "CARKITR"); - - ret = snd_soc_dapm_sync(codec); + snd_soc_dapm_nc_pin(dapm, "AUXL"); + snd_soc_dapm_nc_pin(dapm, "AUXR"); + snd_soc_dapm_nc_pin(dapm, "CARKITMIC"); + snd_soc_dapm_nc_pin(dapm, "DIGIMIC0"); + snd_soc_dapm_nc_pin(dapm, "DIGIMIC1"); + + snd_soc_dapm_nc_pin(dapm, "OUTL"); + snd_soc_dapm_nc_pin(dapm, "OUTR"); + snd_soc_dapm_nc_pin(dapm, "EARPIECE"); + snd_soc_dapm_nc_pin(dapm, "PREDRIVEL"); + snd_soc_dapm_nc_pin(dapm, "PREDRIVER"); + snd_soc_dapm_nc_pin(dapm, "CARKITL"); + snd_soc_dapm_nc_pin(dapm, "CARKITR"); + + ret = snd_soc_dapm_sync(dapm); if (ret) return ret; diff --git a/sound/soc/omap/sdp4430.c b/sound/soc/omap/sdp4430.c index 4b4463db6ba0..3ce17318a291 100644 --- a/sound/soc/omap/sdp4430.c +++ b/sound/soc/omap/sdp4430.c @@ -129,6 +129,7 @@ static const struct snd_soc_dapm_route audio_map[] = { static int sdp4430_twl6040_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_dapm_context *dapm = &codec->dapm; int ret; /* Add SDP4430 specific controls */ @@ -138,25 +139,25 @@ static int sdp4430_twl6040_init(struct snd_soc_pcm_runtime *rtd) return ret; /* Add SDP4430 specific widgets */ - ret = snd_soc_dapm_new_controls(codec, sdp4430_twl6040_dapm_widgets, + ret = snd_soc_dapm_new_controls(dapm, sdp4430_twl6040_dapm_widgets, ARRAY_SIZE(sdp4430_twl6040_dapm_widgets)); if (ret) return ret; /* Set up SDP4430 specific audio path audio_map */ - snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); + snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); /* SDP4430 connected pins */ - snd_soc_dapm_enable_pin(codec, "Ext Mic"); - snd_soc_dapm_enable_pin(codec, "Ext Spk"); - snd_soc_dapm_enable_pin(codec, "Headset Mic"); - snd_soc_dapm_enable_pin(codec, "Headset Stereophone"); + snd_soc_dapm_enable_pin(dapm, "Ext Mic"); + snd_soc_dapm_enable_pin(dapm, "Ext Spk"); + snd_soc_dapm_enable_pin(dapm, "Headset Mic"); + snd_soc_dapm_enable_pin(dapm, "Headset Stereophone"); /* TWL6040 not connected pins */ - snd_soc_dapm_nc_pin(codec, "AFML"); - snd_soc_dapm_nc_pin(codec, "AFMR"); + snd_soc_dapm_nc_pin(dapm, "AFML"); + snd_soc_dapm_nc_pin(dapm, "AFMR"); - ret = snd_soc_dapm_sync(codec); + ret = snd_soc_dapm_sync(dapm); return ret; } diff --git a/sound/soc/omap/zoom2.c b/sound/soc/omap/zoom2.c index 718031eeac34..cc5bc523b302 100644 --- a/sound/soc/omap/zoom2.c +++ b/sound/soc/omap/zoom2.c @@ -162,35 +162,36 @@ static const struct snd_soc_dapm_route audio_map[] = { static int zoom2_twl4030_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_dapm_context *dapm = &codec->dapm; int ret; /* Add Zoom2 specific widgets */ - ret = snd_soc_dapm_new_controls(codec, zoom2_twl4030_dapm_widgets, + ret = snd_soc_dapm_new_controls(dapm, zoom2_twl4030_dapm_widgets, ARRAY_SIZE(zoom2_twl4030_dapm_widgets)); if (ret) return ret; /* Set up Zoom2 specific audio path audio_map */ - snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); + snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); /* Zoom2 connected pins */ - snd_soc_dapm_enable_pin(codec, "Ext Mic"); - snd_soc_dapm_enable_pin(codec, "Ext Spk"); - snd_soc_dapm_enable_pin(codec, "Headset Mic"); - snd_soc_dapm_enable_pin(codec, "Headset Stereophone"); - snd_soc_dapm_enable_pin(codec, "Aux In"); + snd_soc_dapm_enable_pin(dapm, "Ext Mic"); + snd_soc_dapm_enable_pin(dapm, "Ext Spk"); + snd_soc_dapm_enable_pin(dapm, "Headset Mic"); + snd_soc_dapm_enable_pin(dapm, "Headset Stereophone"); + snd_soc_dapm_enable_pin(dapm, "Aux In"); /* TWL4030 not connected pins */ - snd_soc_dapm_nc_pin(codec, "CARKITMIC"); - snd_soc_dapm_nc_pin(codec, "DIGIMIC0"); - snd_soc_dapm_nc_pin(codec, "DIGIMIC1"); - snd_soc_dapm_nc_pin(codec, "EARPIECE"); - snd_soc_dapm_nc_pin(codec, "PREDRIVEL"); - snd_soc_dapm_nc_pin(codec, "PREDRIVER"); - snd_soc_dapm_nc_pin(codec, "CARKITL"); - snd_soc_dapm_nc_pin(codec, "CARKITR"); - - ret = snd_soc_dapm_sync(codec); + snd_soc_dapm_nc_pin(dapm, "CARKITMIC"); + snd_soc_dapm_nc_pin(dapm, "DIGIMIC0"); + snd_soc_dapm_nc_pin(dapm, "DIGIMIC1"); + snd_soc_dapm_nc_pin(dapm, "EARPIECE"); + snd_soc_dapm_nc_pin(dapm, "PREDRIVEL"); + snd_soc_dapm_nc_pin(dapm, "PREDRIVER"); + snd_soc_dapm_nc_pin(dapm, "CARKITL"); + snd_soc_dapm_nc_pin(dapm, "CARKITR"); + + ret = snd_soc_dapm_sync(dapm); return ret; } diff --git a/sound/soc/pxa/corgi.c b/sound/soc/pxa/corgi.c index 97e9423615c9..810633cc3b6d 100644 --- a/sound/soc/pxa/corgi.c +++ b/sound/soc/pxa/corgi.c @@ -48,51 +48,53 @@ static int corgi_spk_func; static void corgi_ext_control(struct snd_soc_codec *codec) { + struct snd_soc_dapm_context *dapm = &codec->dapm; + /* set up jack connection */ switch (corgi_jack_func) { case CORGI_HP: /* set = unmute headphone */ gpio_set_value(CORGI_GPIO_MUTE_L, 1); gpio_set_value(CORGI_GPIO_MUTE_R, 1); - snd_soc_dapm_disable_pin(codec, "Mic Jack"); - snd_soc_dapm_disable_pin(codec, "Line Jack"); - snd_soc_dapm_enable_pin(codec, "Headphone Jack"); - snd_soc_dapm_disable_pin(codec, "Headset Jack"); + snd_soc_dapm_disable_pin(dapm, "Mic Jack"); + snd_soc_dapm_disable_pin(dapm, "Line Jack"); + snd_soc_dapm_enable_pin(dapm, "Headphone Jack"); + snd_soc_dapm_disable_pin(dapm, "Headset Jack"); break; case CORGI_MIC: /* reset = mute headphone */ gpio_set_value(CORGI_GPIO_MUTE_L, 0); gpio_set_value(CORGI_GPIO_MUTE_R, 0); - snd_soc_dapm_enable_pin(codec, "Mic Jack"); - snd_soc_dapm_disable_pin(codec, "Line Jack"); - snd_soc_dapm_disable_pin(codec, "Headphone Jack"); - snd_soc_dapm_disable_pin(codec, "Headset Jack"); + snd_soc_dapm_enable_pin(dapm, "Mic Jack"); + snd_soc_dapm_disable_pin(dapm, "Line Jack"); + snd_soc_dapm_disable_pin(dapm, "Headphone Jack"); + snd_soc_dapm_disable_pin(dapm, "Headset Jack"); break; case CORGI_LINE: gpio_set_value(CORGI_GPIO_MUTE_L, 0); gpio_set_value(CORGI_GPIO_MUTE_R, 0); - snd_soc_dapm_disable_pin(codec, "Mic Jack"); - snd_soc_dapm_enable_pin(codec, "Line Jack"); - snd_soc_dapm_disable_pin(codec, "Headphone Jack"); - snd_soc_dapm_disable_pin(codec, "Headset Jack"); + snd_soc_dapm_disable_pin(dapm, "Mic Jack"); + snd_soc_dapm_enable_pin(dapm, "Line Jack"); + snd_soc_dapm_disable_pin(dapm, "Headphone Jack"); + snd_soc_dapm_disable_pin(dapm, "Headset Jack"); break; case CORGI_HEADSET: gpio_set_value(CORGI_GPIO_MUTE_L, 0); gpio_set_value(CORGI_GPIO_MUTE_R, 1); - snd_soc_dapm_enable_pin(codec, "Mic Jack"); - snd_soc_dapm_disable_pin(codec, "Line Jack"); - snd_soc_dapm_disable_pin(codec, "Headphone Jack"); - snd_soc_dapm_enable_pin(codec, "Headset Jack"); + snd_soc_dapm_enable_pin(dapm, "Mic Jack"); + snd_soc_dapm_disable_pin(dapm, "Line Jack"); + snd_soc_dapm_disable_pin(dapm, "Headphone Jack"); + snd_soc_dapm_enable_pin(dapm, "Headset Jack"); break; } if (corgi_spk_func == CORGI_SPK_ON) - snd_soc_dapm_enable_pin(codec, "Ext Spk"); + snd_soc_dapm_enable_pin(dapm, "Ext Spk"); else - snd_soc_dapm_disable_pin(codec, "Ext Spk"); + snd_soc_dapm_disable_pin(dapm, "Ext Spk"); /* signal a DAPM event */ - snd_soc_dapm_sync(codec); + snd_soc_dapm_sync(dapm); } static int corgi_startup(struct snd_pcm_substream *substream) @@ -274,10 +276,11 @@ static const struct snd_kcontrol_new wm8731_corgi_controls[] = { static int corgi_wm8731_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_dapm_context *dapm = &codec->dapm; int err; - snd_soc_dapm_nc_pin(codec, "LLINEIN"); - snd_soc_dapm_nc_pin(codec, "RLINEIN"); + snd_soc_dapm_nc_pin(dapm, "LLINEIN"); + snd_soc_dapm_nc_pin(dapm, "RLINEIN"); /* Add corgi specific controls */ err = snd_soc_add_controls(codec, wm8731_corgi_controls, @@ -286,13 +289,13 @@ static int corgi_wm8731_init(struct snd_soc_pcm_runtime *rtd) return err; /* Add corgi specific widgets */ - snd_soc_dapm_new_controls(codec, wm8731_dapm_widgets, + snd_soc_dapm_new_controls(dapm, wm8731_dapm_widgets, ARRAY_SIZE(wm8731_dapm_widgets)); /* Set up corgi specific audio path audio_map */ - snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); + snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); - snd_soc_dapm_sync(codec); + snd_soc_dapm_sync(dapm); return 0; } diff --git a/sound/soc/pxa/e740_wm9705.c b/sound/soc/pxa/e740_wm9705.c index c82cedb602fd..38a84b821ff4 100644 --- a/sound/soc/pxa/e740_wm9705.c +++ b/sound/soc/pxa/e740_wm9705.c @@ -92,23 +92,24 @@ static const struct snd_soc_dapm_route audio_map[] = { static int e740_ac97_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; - - snd_soc_dapm_nc_pin(codec, "HPOUTL"); - snd_soc_dapm_nc_pin(codec, "HPOUTR"); - snd_soc_dapm_nc_pin(codec, "PHONE"); - snd_soc_dapm_nc_pin(codec, "LINEINL"); - snd_soc_dapm_nc_pin(codec, "LINEINR"); - snd_soc_dapm_nc_pin(codec, "CDINL"); - snd_soc_dapm_nc_pin(codec, "CDINR"); - snd_soc_dapm_nc_pin(codec, "PCBEEP"); - snd_soc_dapm_nc_pin(codec, "MIC2"); - - snd_soc_dapm_new_controls(codec, e740_dapm_widgets, + struct snd_soc_dapm_context *dapm = &codec->dapm; + + snd_soc_dapm_nc_pin(dapm, "HPOUTL"); + snd_soc_dapm_nc_pin(dapm, "HPOUTR"); + snd_soc_dapm_nc_pin(dapm, "PHONE"); + snd_soc_dapm_nc_pin(dapm, "LINEINL"); + snd_soc_dapm_nc_pin(dapm, "LINEINR"); + snd_soc_dapm_nc_pin(dapm, "CDINL"); + snd_soc_dapm_nc_pin(dapm, "CDINR"); + snd_soc_dapm_nc_pin(dapm, "PCBEEP"); + snd_soc_dapm_nc_pin(dapm, "MIC2"); + + snd_soc_dapm_new_controls(dapm, e740_dapm_widgets, ARRAY_SIZE(e740_dapm_widgets)); - snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); + snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); - snd_soc_dapm_sync(codec); + snd_soc_dapm_sync(dapm); return 0; } diff --git a/sound/soc/pxa/e750_wm9705.c b/sound/soc/pxa/e750_wm9705.c index 4c143803a75e..2bc97e92446b 100644 --- a/sound/soc/pxa/e750_wm9705.c +++ b/sound/soc/pxa/e750_wm9705.c @@ -74,23 +74,24 @@ static const struct snd_soc_dapm_route audio_map[] = { static int e750_ac97_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; - - snd_soc_dapm_nc_pin(codec, "LOUT"); - snd_soc_dapm_nc_pin(codec, "ROUT"); - snd_soc_dapm_nc_pin(codec, "PHONE"); - snd_soc_dapm_nc_pin(codec, "LINEINL"); - snd_soc_dapm_nc_pin(codec, "LINEINR"); - snd_soc_dapm_nc_pin(codec, "CDINL"); - snd_soc_dapm_nc_pin(codec, "CDINR"); - snd_soc_dapm_nc_pin(codec, "PCBEEP"); - snd_soc_dapm_nc_pin(codec, "MIC2"); - - snd_soc_dapm_new_controls(codec, e750_dapm_widgets, + struct snd_soc_dapm_context *dapm = &codec->dapm; + + snd_soc_dapm_nc_pin(dapm, "LOUT"); + snd_soc_dapm_nc_pin(dapm, "ROUT"); + snd_soc_dapm_nc_pin(dapm, "PHONE"); + snd_soc_dapm_nc_pin(dapm, "LINEINL"); + snd_soc_dapm_nc_pin(dapm, "LINEINR"); + snd_soc_dapm_nc_pin(dapm, "CDINL"); + snd_soc_dapm_nc_pin(dapm, "CDINR"); + snd_soc_dapm_nc_pin(dapm, "PCBEEP"); + snd_soc_dapm_nc_pin(dapm, "MIC2"); + + snd_soc_dapm_new_controls(dapm, e750_dapm_widgets, ARRAY_SIZE(e750_dapm_widgets)); - snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); + snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); - snd_soc_dapm_sync(codec); + snd_soc_dapm_sync(dapm); return 0; } diff --git a/sound/soc/pxa/e800_wm9712.c b/sound/soc/pxa/e800_wm9712.c index d42e5fe832c5..eac846c7bd9c 100644 --- a/sound/soc/pxa/e800_wm9712.c +++ b/sound/soc/pxa/e800_wm9712.c @@ -75,12 +75,13 @@ static const struct snd_soc_dapm_route audio_map[] = { static int e800_ac97_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_dapm_context *dapm = &codec->dapm; - snd_soc_dapm_new_controls(codec, e800_dapm_widgets, + snd_soc_dapm_new_controls(dapm, e800_dapm_widgets, ARRAY_SIZE(e800_dapm_widgets)); - snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); - snd_soc_dapm_sync(codec); + snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); + snd_soc_dapm_sync(dapm); return 0; } diff --git a/sound/soc/pxa/magician.c b/sound/soc/pxa/magician.c index b8207ced4072..f1acdc57cfd8 100644 --- a/sound/soc/pxa/magician.c +++ b/sound/soc/pxa/magician.c @@ -44,27 +44,29 @@ static int magician_in_sel = MAGICIAN_MIC; static void magician_ext_control(struct snd_soc_codec *codec) { + struct snd_soc_dapm_context *dapm = &codec->dapm; + if (magician_spk_switch) - snd_soc_dapm_enable_pin(codec, "Speaker"); + snd_soc_dapm_enable_pin(dapm, "Speaker"); else - snd_soc_dapm_disable_pin(codec, "Speaker"); + snd_soc_dapm_disable_pin(dapm, "Speaker"); if (magician_hp_switch) - snd_soc_dapm_enable_pin(codec, "Headphone Jack"); + snd_soc_dapm_enable_pin(dapm, "Headphone Jack"); else - snd_soc_dapm_disable_pin(codec, "Headphone Jack"); + snd_soc_dapm_disable_pin(dapm, "Headphone Jack"); switch (magician_in_sel) { case MAGICIAN_MIC: - snd_soc_dapm_disable_pin(codec, "Headset Mic"); - snd_soc_dapm_enable_pin(codec, "Call Mic"); + snd_soc_dapm_disable_pin(dapm, "Headset Mic"); + snd_soc_dapm_enable_pin(dapm, "Call Mic"); break; case MAGICIAN_MIC_EXT: - snd_soc_dapm_disable_pin(codec, "Call Mic"); - snd_soc_dapm_enable_pin(codec, "Headset Mic"); + snd_soc_dapm_disable_pin(dapm, "Call Mic"); + snd_soc_dapm_enable_pin(dapm, "Headset Mic"); break; } - snd_soc_dapm_sync(codec); + snd_soc_dapm_sync(dapm); } static int magician_startup(struct snd_pcm_substream *substream) @@ -395,15 +397,16 @@ static const struct snd_kcontrol_new uda1380_magician_controls[] = { static int magician_uda1380_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_dapm_context *dapm = &codec->dapm; int err; /* NC codec pins */ - snd_soc_dapm_nc_pin(codec, "VOUTLHP"); - snd_soc_dapm_nc_pin(codec, "VOUTRHP"); + snd_soc_dapm_nc_pin(dapm, "VOUTLHP"); + snd_soc_dapm_nc_pin(dapm, "VOUTRHP"); /* FIXME: is anything connected here? */ - snd_soc_dapm_nc_pin(codec, "VINL"); - snd_soc_dapm_nc_pin(codec, "VINR"); + snd_soc_dapm_nc_pin(dapm, "VINL"); + snd_soc_dapm_nc_pin(dapm, "VINR"); /* Add magician specific controls */ err = snd_soc_add_controls(codec, uda1380_magician_controls, @@ -412,13 +415,13 @@ static int magician_uda1380_init(struct snd_soc_pcm_runtime *rtd) return err; /* Add magician specific widgets */ - snd_soc_dapm_new_controls(codec, uda1380_dapm_widgets, + snd_soc_dapm_new_controls(dapm, uda1380_dapm_widgets, ARRAY_SIZE(uda1380_dapm_widgets)); /* Set up magician specific audio path interconnects */ - snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); + snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); - snd_soc_dapm_sync(codec); + snd_soc_dapm_sync(dapm); return 0; } diff --git a/sound/soc/pxa/mioa701_wm9713.c b/sound/soc/pxa/mioa701_wm9713.c index f284cc54bc80..f7a1e8f09f9a 100644 --- a/sound/soc/pxa/mioa701_wm9713.c +++ b/sound/soc/pxa/mioa701_wm9713.c @@ -130,13 +130,14 @@ static const struct snd_soc_dapm_route audio_map[] = { static int mioa701_wm9713_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_dapm_context *dapm = &codec->dapm; unsigned short reg; /* Add mioa701 specific widgets */ - snd_soc_dapm_new_controls(codec, ARRAY_AND_SIZE(mioa701_dapm_widgets)); + snd_soc_dapm_new_controls(dapm, ARRAY_AND_SIZE(mioa701_dapm_widgets)); /* Set up mioa701 specific audio path audio_mapnects */ - snd_soc_dapm_add_routes(codec, ARRAY_AND_SIZE(audio_map)); + snd_soc_dapm_add_routes(dapm, ARRAY_AND_SIZE(audio_map)); /* Prepare GPIO8 for rear speaker amplifier */ reg = codec->driver->read(codec, AC97_GPIO_CFG); @@ -146,12 +147,12 @@ static int mioa701_wm9713_init(struct snd_soc_pcm_runtime *rtd) reg = codec->driver->read(codec, AC97_3D_CONTROL); codec->driver->write(codec, AC97_3D_CONTROL, reg | 0xc000); - snd_soc_dapm_enable_pin(codec, "Front Speaker"); - snd_soc_dapm_enable_pin(codec, "Rear Speaker"); - snd_soc_dapm_enable_pin(codec, "Front Mic"); - snd_soc_dapm_enable_pin(codec, "GSM Line In"); - snd_soc_dapm_enable_pin(codec, "GSM Line Out"); - snd_soc_dapm_sync(codec); + snd_soc_dapm_enable_pin(dapm, "Front Speaker"); + snd_soc_dapm_enable_pin(dapm, "Rear Speaker"); + snd_soc_dapm_enable_pin(dapm, "Front Mic"); + snd_soc_dapm_enable_pin(dapm, "GSM Line In"); + snd_soc_dapm_enable_pin(dapm, "GSM Line Out"); + snd_soc_dapm_sync(dapm); return 0; } diff --git a/sound/soc/pxa/palm27x.c b/sound/soc/pxa/palm27x.c index 13f6d485d571..530064dd06a9 100644 --- a/sound/soc/pxa/palm27x.c +++ b/sound/soc/pxa/palm27x.c @@ -77,37 +77,38 @@ static struct snd_soc_card palm27x_asoc; static int palm27x_ac97_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_dapm_context *dapm = &codec->dapm; int err; /* add palm27x specific widgets */ - err = snd_soc_dapm_new_controls(codec, palm27x_dapm_widgets, + err = snd_soc_dapm_new_controls(dapm, palm27x_dapm_widgets, ARRAY_SIZE(palm27x_dapm_widgets)); if (err) return err; /* set up palm27x specific audio path audio_map */ - err = snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); + err = snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); if (err) return err; /* connected pins */ if (machine_is_palmld()) - snd_soc_dapm_enable_pin(codec, "MIC1"); - snd_soc_dapm_enable_pin(codec, "HPOUTL"); - snd_soc_dapm_enable_pin(codec, "HPOUTR"); - snd_soc_dapm_enable_pin(codec, "LOUT2"); - snd_soc_dapm_enable_pin(codec, "ROUT2"); + snd_soc_dapm_enable_pin(dapm, "MIC1"); + snd_soc_dapm_enable_pin(dapm, "HPOUTL"); + snd_soc_dapm_enable_pin(dapm, "HPOUTR"); + snd_soc_dapm_enable_pin(dapm, "LOUT2"); + snd_soc_dapm_enable_pin(dapm, "ROUT2"); /* not connected pins */ - snd_soc_dapm_nc_pin(codec, "OUT3"); - snd_soc_dapm_nc_pin(codec, "MONOOUT"); - snd_soc_dapm_nc_pin(codec, "LINEINL"); - snd_soc_dapm_nc_pin(codec, "LINEINR"); - snd_soc_dapm_nc_pin(codec, "PCBEEP"); - snd_soc_dapm_nc_pin(codec, "PHONE"); - snd_soc_dapm_nc_pin(codec, "MIC2"); - - err = snd_soc_dapm_sync(codec); + snd_soc_dapm_nc_pin(dapm, "OUT3"); + snd_soc_dapm_nc_pin(dapm, "MONOOUT"); + snd_soc_dapm_nc_pin(dapm, "LINEINL"); + snd_soc_dapm_nc_pin(dapm, "LINEINR"); + snd_soc_dapm_nc_pin(dapm, "PCBEEP"); + snd_soc_dapm_nc_pin(dapm, "PHONE"); + snd_soc_dapm_nc_pin(dapm, "MIC2"); + + err = snd_soc_dapm_sync(dapm); if (err) return err; diff --git a/sound/soc/pxa/poodle.c b/sound/soc/pxa/poodle.c index af84ee9c5e11..7353ee5034fe 100644 --- a/sound/soc/pxa/poodle.c +++ b/sound/soc/pxa/poodle.c @@ -46,6 +46,8 @@ static int poodle_spk_func; static void poodle_ext_control(struct snd_soc_codec *codec) { + struct snd_soc_dapm_context *dapm = &codec->dapm; + /* set up jack connection */ if (poodle_jack_func == POODLE_HP) { /* set = unmute headphone */ @@ -53,23 +55,23 @@ static void poodle_ext_control(struct snd_soc_codec *codec) POODLE_LOCOMO_GPIO_MUTE_L, 1); locomo_gpio_write(&poodle_locomo_device.dev, POODLE_LOCOMO_GPIO_MUTE_R, 1); - snd_soc_dapm_enable_pin(codec, "Headphone Jack"); + snd_soc_dapm_enable_pin(dapm, "Headphone Jack"); } else { locomo_gpio_write(&poodle_locomo_device.dev, POODLE_LOCOMO_GPIO_MUTE_L, 0); locomo_gpio_write(&poodle_locomo_device.dev, POODLE_LOCOMO_GPIO_MUTE_R, 0); - snd_soc_dapm_disable_pin(codec, "Headphone Jack"); + snd_soc_dapm_disable_pin(dapm, "Headphone Jack"); } /* set the enpoints to their new connetion states */ if (poodle_spk_func == POODLE_SPK_ON) - snd_soc_dapm_enable_pin(codec, "Ext Spk"); + snd_soc_dapm_enable_pin(dapm, "Ext Spk"); else - snd_soc_dapm_disable_pin(codec, "Ext Spk"); + snd_soc_dapm_disable_pin(dapm, "Ext Spk"); /* signal a DAPM event */ - snd_soc_dapm_sync(codec); + snd_soc_dapm_sync(dapm); } static int poodle_startup(struct snd_pcm_substream *substream) @@ -239,11 +241,12 @@ static const struct snd_kcontrol_new wm8731_poodle_controls[] = { static int poodle_wm8731_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_dapm_context *dapm = &codec->dapm; int err; - snd_soc_dapm_nc_pin(codec, "LLINEIN"); - snd_soc_dapm_nc_pin(codec, "RLINEIN"); - snd_soc_dapm_enable_pin(codec, "MICIN"); + snd_soc_dapm_nc_pin(dapm, "LLINEIN"); + snd_soc_dapm_nc_pin(dapm, "RLINEIN"); + snd_soc_dapm_enable_pin(dapm, "MICIN"); /* Add poodle specific controls */ err = snd_soc_add_controls(codec, wm8731_poodle_controls, @@ -252,13 +255,13 @@ static int poodle_wm8731_init(struct snd_soc_pcm_runtime *rtd) return err; /* Add poodle specific widgets */ - snd_soc_dapm_new_controls(codec, wm8731_dapm_widgets, + snd_soc_dapm_new_controls(dapm, wm8731_dapm_widgets, ARRAY_SIZE(wm8731_dapm_widgets)); /* Set up poodle specific audio path audio_map */ - snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); + snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); - snd_soc_dapm_sync(codec); + snd_soc_dapm_sync(dapm); return 0; } diff --git a/sound/soc/pxa/saarb.c b/sound/soc/pxa/saarb.c index d63cb474b4e1..ee06f9982c09 100644 --- a/sound/soc/pxa/saarb.c +++ b/sound/soc/pxa/saarb.c @@ -133,20 +133,21 @@ static struct snd_soc_card snd_soc_card_saarb = { static int saarb_pm860x_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_dapm_context *dapm = &codec->dapm; int ret; - snd_soc_dapm_new_controls(codec, saarb_dapm_widgets, + snd_soc_dapm_new_controls(dapm, saarb_dapm_widgets, ARRAY_SIZE(saarb_dapm_widgets)); - snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); + snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); /* connected pins */ - snd_soc_dapm_enable_pin(codec, "Ext Speaker"); - snd_soc_dapm_enable_pin(codec, "Ext Mic 1"); - snd_soc_dapm_enable_pin(codec, "Ext Mic 3"); - snd_soc_dapm_disable_pin(codec, "Headset Mic 2"); - snd_soc_dapm_disable_pin(codec, "Headset Stereophone"); + snd_soc_dapm_enable_pin(dapm, "Ext Speaker"); + snd_soc_dapm_enable_pin(dapm, "Ext Mic 1"); + snd_soc_dapm_enable_pin(dapm, "Ext Mic 3"); + snd_soc_dapm_disable_pin(dapm, "Headset Mic 2"); + snd_soc_dapm_disable_pin(dapm, "Headset Stereophone"); - ret = snd_soc_dapm_sync(codec); + ret = snd_soc_dapm_sync(dapm); if (ret) return ret; diff --git a/sound/soc/pxa/spitz.c b/sound/soc/pxa/spitz.c index f470f360f4dd..0680b11c2685 100644 --- a/sound/soc/pxa/spitz.c +++ b/sound/soc/pxa/spitz.c @@ -46,61 +46,63 @@ static int spitz_spk_func; static void spitz_ext_control(struct snd_soc_codec *codec) { + struct snd_soc_dapm_context *dapm = &codec->dapm; + if (spitz_spk_func == SPITZ_SPK_ON) - snd_soc_dapm_enable_pin(codec, "Ext Spk"); + snd_soc_dapm_enable_pin(dapm, "Ext Spk"); else - snd_soc_dapm_disable_pin(codec, "Ext Spk"); + snd_soc_dapm_disable_pin(dapm, "Ext Spk"); /* set up jack connection */ switch (spitz_jack_func) { case SPITZ_HP: /* enable and unmute hp jack, disable mic bias */ - snd_soc_dapm_disable_pin(codec, "Headset Jack"); - snd_soc_dapm_disable_pin(codec, "Mic Jack"); - snd_soc_dapm_disable_pin(codec, "Line Jack"); - snd_soc_dapm_enable_pin(codec, "Headphone Jack"); + snd_soc_dapm_disable_pin(dapm, "Headset Jack"); + snd_soc_dapm_disable_pin(dapm, "Mic Jack"); + snd_soc_dapm_disable_pin(dapm, "Line Jack"); + snd_soc_dapm_enable_pin(dapm, "Headphone Jack"); gpio_set_value(SPITZ_GPIO_MUTE_L, 1); gpio_set_value(SPITZ_GPIO_MUTE_R, 1); break; case SPITZ_MIC: /* enable mic jack and bias, mute hp */ - snd_soc_dapm_disable_pin(codec, "Headphone Jack"); - snd_soc_dapm_disable_pin(codec, "Headset Jack"); - snd_soc_dapm_disable_pin(codec, "Line Jack"); - snd_soc_dapm_enable_pin(codec, "Mic Jack"); + snd_soc_dapm_disable_pin(dapm, "Headphone Jack"); + snd_soc_dapm_disable_pin(dapm, "Headset Jack"); + snd_soc_dapm_disable_pin(dapm, "Line Jack"); + snd_soc_dapm_enable_pin(dapm, "Mic Jack"); gpio_set_value(SPITZ_GPIO_MUTE_L, 0); gpio_set_value(SPITZ_GPIO_MUTE_R, 0); break; case SPITZ_LINE: /* enable line jack, disable mic bias and mute hp */ - snd_soc_dapm_disable_pin(codec, "Headphone Jack"); - snd_soc_dapm_disable_pin(codec, "Headset Jack"); - snd_soc_dapm_disable_pin(codec, "Mic Jack"); - snd_soc_dapm_enable_pin(codec, "Line Jack"); + snd_soc_dapm_disable_pin(dapm, "Headphone Jack"); + snd_soc_dapm_disable_pin(dapm, "Headset Jack"); + snd_soc_dapm_disable_pin(dapm, "Mic Jack"); + snd_soc_dapm_enable_pin(dapm, "Line Jack"); gpio_set_value(SPITZ_GPIO_MUTE_L, 0); gpio_set_value(SPITZ_GPIO_MUTE_R, 0); break; case SPITZ_HEADSET: /* enable and unmute headset jack enable mic bias, mute L hp */ - snd_soc_dapm_disable_pin(codec, "Headphone Jack"); - snd_soc_dapm_enable_pin(codec, "Mic Jack"); - snd_soc_dapm_disable_pin(codec, "Line Jack"); - snd_soc_dapm_enable_pin(codec, "Headset Jack"); + snd_soc_dapm_disable_pin(dapm, "Headphone Jack"); + snd_soc_dapm_enable_pin(dapm, "Mic Jack"); + snd_soc_dapm_disable_pin(dapm, "Line Jack"); + snd_soc_dapm_enable_pin(dapm, "Headset Jack"); gpio_set_value(SPITZ_GPIO_MUTE_L, 0); gpio_set_value(SPITZ_GPIO_MUTE_R, 1); break; case SPITZ_HP_OFF: /* jack removed, everything off */ - snd_soc_dapm_disable_pin(codec, "Headphone Jack"); - snd_soc_dapm_disable_pin(codec, "Headset Jack"); - snd_soc_dapm_disable_pin(codec, "Mic Jack"); - snd_soc_dapm_disable_pin(codec, "Line Jack"); + snd_soc_dapm_disable_pin(dapm, "Headphone Jack"); + snd_soc_dapm_disable_pin(dapm, "Headset Jack"); + snd_soc_dapm_disable_pin(dapm, "Mic Jack"); + snd_soc_dapm_disable_pin(dapm, "Line Jack"); gpio_set_value(SPITZ_GPIO_MUTE_L, 0); gpio_set_value(SPITZ_GPIO_MUTE_R, 0); break; } - snd_soc_dapm_sync(codec); + snd_soc_dapm_sync(dapm); } static int spitz_startup(struct snd_pcm_substream *substream) @@ -276,16 +278,17 @@ static const struct snd_kcontrol_new wm8750_spitz_controls[] = { static int spitz_wm8750_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_dapm_context *dapm = &codec->dapm; int err; /* NC codec pins */ - snd_soc_dapm_nc_pin(codec, "RINPUT1"); - snd_soc_dapm_nc_pin(codec, "LINPUT2"); - snd_soc_dapm_nc_pin(codec, "RINPUT2"); - snd_soc_dapm_nc_pin(codec, "LINPUT3"); - snd_soc_dapm_nc_pin(codec, "RINPUT3"); - snd_soc_dapm_nc_pin(codec, "OUT3"); - snd_soc_dapm_nc_pin(codec, "MONO1"); + snd_soc_dapm_nc_pin(dapm, "RINPUT1"); + snd_soc_dapm_nc_pin(dapm, "LINPUT2"); + snd_soc_dapm_nc_pin(dapm, "RINPUT2"); + snd_soc_dapm_nc_pin(dapm, "LINPUT3"); + snd_soc_dapm_nc_pin(dapm, "RINPUT3"); + snd_soc_dapm_nc_pin(dapm, "OUT3"); + snd_soc_dapm_nc_pin(dapm, "MONO1"); /* Add spitz specific controls */ err = snd_soc_add_controls(codec, wm8750_spitz_controls, @@ -294,13 +297,13 @@ static int spitz_wm8750_init(struct snd_soc_pcm_runtime *rtd) return err; /* Add spitz specific widgets */ - snd_soc_dapm_new_controls(codec, wm8750_dapm_widgets, + snd_soc_dapm_new_controls(dapm, wm8750_dapm_widgets, ARRAY_SIZE(wm8750_dapm_widgets)); /* Set up spitz specific audio paths */ - snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); + snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); - snd_soc_dapm_sync(codec); + snd_soc_dapm_sync(dapm); return 0; } diff --git a/sound/soc/pxa/tavorevb3.c b/sound/soc/pxa/tavorevb3.c index 248c283fc4df..18cbe0e7c223 100644 --- a/sound/soc/pxa/tavorevb3.c +++ b/sound/soc/pxa/tavorevb3.c @@ -133,20 +133,21 @@ static struct snd_soc_card snd_soc_card_evb3 = { static int evb3_pm860x_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_dapm_context *dapm = &codec->dapm; int ret; - snd_soc_dapm_new_controls(codec, evb3_dapm_widgets, + snd_soc_dapm_new_controls(dapm, evb3_dapm_widgets, ARRAY_SIZE(evb3_dapm_widgets)); - snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); + snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); /* connected pins */ - snd_soc_dapm_enable_pin(codec, "Ext Speaker"); - snd_soc_dapm_enable_pin(codec, "Ext Mic 1"); - snd_soc_dapm_enable_pin(codec, "Ext Mic 3"); - snd_soc_dapm_disable_pin(codec, "Headset Mic 2"); - snd_soc_dapm_disable_pin(codec, "Headset Stereophone"); + snd_soc_dapm_enable_pin(dapm, "Ext Speaker"); + snd_soc_dapm_enable_pin(dapm, "Ext Mic 1"); + snd_soc_dapm_enable_pin(dapm, "Ext Mic 3"); + snd_soc_dapm_disable_pin(dapm, "Headset Mic 2"); + snd_soc_dapm_disable_pin(dapm, "Headset Stereophone"); - ret = snd_soc_dapm_sync(codec); + ret = snd_soc_dapm_sync(dapm); if (ret) return ret; diff --git a/sound/soc/pxa/tosa.c b/sound/soc/pxa/tosa.c index 73d0edd8ded9..0a9bd68ef749 100644 --- a/sound/soc/pxa/tosa.c +++ b/sound/soc/pxa/tosa.c @@ -49,31 +49,33 @@ static int tosa_spk_func; static void tosa_ext_control(struct snd_soc_codec *codec) { + struct snd_soc_dapm_context *dapm = &codec->dapm; + /* set up jack connection */ switch (tosa_jack_func) { case TOSA_HP: - snd_soc_dapm_disable_pin(codec, "Mic (Internal)"); - snd_soc_dapm_enable_pin(codec, "Headphone Jack"); - snd_soc_dapm_disable_pin(codec, "Headset Jack"); + snd_soc_dapm_disable_pin(dapm, "Mic (Internal)"); + snd_soc_dapm_enable_pin(dapm, "Headphone Jack"); + snd_soc_dapm_disable_pin(dapm, "Headset Jack"); break; case TOSA_MIC_INT: - snd_soc_dapm_enable_pin(codec, "Mic (Internal)"); - snd_soc_dapm_disable_pin(codec, "Headphone Jack"); - snd_soc_dapm_disable_pin(codec, "Headset Jack"); + snd_soc_dapm_enable_pin(dapm, "Mic (Internal)"); + snd_soc_dapm_disable_pin(dapm, "Headphone Jack"); + snd_soc_dapm_disable_pin(dapm, "Headset Jack"); break; case TOSA_HEADSET: - snd_soc_dapm_disable_pin(codec, "Mic (Internal)"); - snd_soc_dapm_disable_pin(codec, "Headphone Jack"); - snd_soc_dapm_enable_pin(codec, "Headset Jack"); + snd_soc_dapm_disable_pin(dapm, "Mic (Internal)"); + snd_soc_dapm_disable_pin(dapm, "Headphone Jack"); + snd_soc_dapm_enable_pin(dapm, "Headset Jack"); break; } if (tosa_spk_func == TOSA_SPK_ON) - snd_soc_dapm_enable_pin(codec, "Speaker"); + snd_soc_dapm_enable_pin(dapm, "Speaker"); else - snd_soc_dapm_disable_pin(codec, "Speaker"); + snd_soc_dapm_disable_pin(dapm, "Speaker"); - snd_soc_dapm_sync(codec); + snd_soc_dapm_sync(dapm); } static int tosa_startup(struct snd_pcm_substream *substream) @@ -186,10 +188,11 @@ static const struct snd_kcontrol_new tosa_controls[] = { static int tosa_ac97_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_dapm_context *dapm = &codec->dapm; int err; - snd_soc_dapm_nc_pin(codec, "OUT3"); - snd_soc_dapm_nc_pin(codec, "MONOOUT"); + snd_soc_dapm_nc_pin(dapm, "OUT3"); + snd_soc_dapm_nc_pin(dapm, "MONOOUT"); /* add tosa specific controls */ err = snd_soc_add_controls(codec, tosa_controls, @@ -198,13 +201,13 @@ static int tosa_ac97_init(struct snd_soc_pcm_runtime *rtd) return err; /* add tosa specific widgets */ - snd_soc_dapm_new_controls(codec, tosa_dapm_widgets, + snd_soc_dapm_new_controls(dapm, tosa_dapm_widgets, ARRAY_SIZE(tosa_dapm_widgets)); /* set up tosa specific audio path audio_map */ - snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); + snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); - snd_soc_dapm_sync(codec); + snd_soc_dapm_sync(dapm); return 0; } diff --git a/sound/soc/pxa/z2.c b/sound/soc/pxa/z2.c index 4cc841b44182..cacbcd4a55eb 100644 --- a/sound/soc/pxa/z2.c +++ b/sound/soc/pxa/z2.c @@ -140,22 +140,23 @@ static const struct snd_soc_dapm_route audio_map[] = { static int z2_wm8750_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_dapm_context *dapm = &codec->dapm; int ret; /* NC codec pins */ - snd_soc_dapm_disable_pin(codec, "LINPUT3"); - snd_soc_dapm_disable_pin(codec, "RINPUT3"); - snd_soc_dapm_disable_pin(codec, "OUT3"); - snd_soc_dapm_disable_pin(codec, "MONO"); + snd_soc_dapm_disable_pin(dapm, "LINPUT3"); + snd_soc_dapm_disable_pin(dapm, "RINPUT3"); + snd_soc_dapm_disable_pin(dapm, "OUT3"); + snd_soc_dapm_disable_pin(dapm, "MONO"); /* Add z2 specific widgets */ - snd_soc_dapm_new_controls(codec, wm8750_dapm_widgets, + snd_soc_dapm_new_controls(dapm, wm8750_dapm_widgets, ARRAY_SIZE(wm8750_dapm_widgets)); /* Set up z2 specific audio paths */ - snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); + snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); - ret = snd_soc_dapm_sync(codec); + ret = snd_soc_dapm_sync(dapm); if (ret) goto err; diff --git a/sound/soc/pxa/zylonite.c b/sound/soc/pxa/zylonite.c index d27e05af7759..c74eac30ebff 100644 --- a/sound/soc/pxa/zylonite.c +++ b/sound/soc/pxa/zylonite.c @@ -73,21 +73,22 @@ static const struct snd_soc_dapm_route audio_map[] = { static int zylonite_wm9713_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_dapm_context *dapm = &codec->dapm; if (clk_pout) snd_soc_dai_set_pll(rtd->codec_dai, 0, 0, clk_get_rate(pout), 0); - snd_soc_dapm_new_controls(codec, zylonite_dapm_widgets, + snd_soc_dapm_new_controls(dapm, zylonite_dapm_widgets, ARRAY_SIZE(zylonite_dapm_widgets)); - snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); + snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); /* Static setup for now */ - snd_soc_dapm_enable_pin(codec, "Headphone"); - snd_soc_dapm_enable_pin(codec, "Headset Earpiece"); + snd_soc_dapm_enable_pin(dapm, "Headphone"); + snd_soc_dapm_enable_pin(dapm, "Headset Earpiece"); - snd_soc_dapm_sync(codec); + snd_soc_dapm_sync(dapm); return 0; } diff --git a/sound/soc/s3c24xx/aquila_wm8994.c b/sound/soc/s3c24xx/aquila_wm8994.c index 235d1973f7d0..33bebdae08a7 100644 --- a/sound/soc/s3c24xx/aquila_wm8994.c +++ b/sound/soc/s3c24xx/aquila_wm8994.c @@ -93,27 +93,28 @@ static const struct snd_soc_dapm_route aquila_dapm_routes[] = { static int aquila_wm8994_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_dapm_context *dapm = &codec->dapm; int ret; /* add aquila specific widgets */ - snd_soc_dapm_new_controls(codec, aquila_dapm_widgets, + snd_soc_dapm_new_controls(dapm, aquila_dapm_widgets, ARRAY_SIZE(aquila_dapm_widgets)); /* set up aquila specific audio routes */ - snd_soc_dapm_add_routes(codec, aquila_dapm_routes, + snd_soc_dapm_add_routes(dapm, aquila_dapm_routes, ARRAY_SIZE(aquila_dapm_routes)); /* set endpoints to not connected */ - snd_soc_dapm_nc_pin(codec, "IN2LP:VXRN"); - snd_soc_dapm_nc_pin(codec, "IN2RP:VXRP"); - snd_soc_dapm_nc_pin(codec, "LINEOUT1N"); - snd_soc_dapm_nc_pin(codec, "LINEOUT1P"); - snd_soc_dapm_nc_pin(codec, "LINEOUT2N"); - snd_soc_dapm_nc_pin(codec, "LINEOUT2P"); - snd_soc_dapm_nc_pin(codec, "SPKOUTRN"); - snd_soc_dapm_nc_pin(codec, "SPKOUTRP"); - - snd_soc_dapm_sync(codec); + snd_soc_dapm_nc_pin(dapm, "IN2LP:VXRN"); + snd_soc_dapm_nc_pin(dapm, "IN2RP:VXRP"); + snd_soc_dapm_nc_pin(dapm, "LINEOUT1N"); + snd_soc_dapm_nc_pin(dapm, "LINEOUT1P"); + snd_soc_dapm_nc_pin(dapm, "LINEOUT2N"); + snd_soc_dapm_nc_pin(dapm, "LINEOUT2P"); + snd_soc_dapm_nc_pin(dapm, "SPKOUTRN"); + snd_soc_dapm_nc_pin(dapm, "SPKOUTRP"); + + snd_soc_dapm_sync(dapm); /* Headset jack detection */ ret = snd_soc_jack_new(&aquila, "Headset Jack", diff --git a/sound/soc/s3c24xx/goni_wm8994.c b/sound/soc/s3c24xx/goni_wm8994.c index 694f702cc8e2..052729c6540d 100644 --- a/sound/soc/s3c24xx/goni_wm8994.c +++ b/sound/soc/s3c24xx/goni_wm8994.c @@ -97,25 +97,26 @@ static const struct snd_soc_dapm_route goni_dapm_routes[] = { static int goni_wm8994_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_dapm_context *dapm = &codec->dapm; int ret; /* add goni specific widgets */ - snd_soc_dapm_new_controls(codec, goni_dapm_widgets, + snd_soc_dapm_new_controls(dapm, goni_dapm_widgets, ARRAY_SIZE(goni_dapm_widgets)); /* set up goni specific audio routes */ - snd_soc_dapm_add_routes(codec, goni_dapm_routes, + snd_soc_dapm_add_routes(dapm, goni_dapm_routes, ARRAY_SIZE(goni_dapm_routes)); /* set endpoints to not connected */ - snd_soc_dapm_nc_pin(codec, "IN2LP:VXRN"); - snd_soc_dapm_nc_pin(codec, "IN2RP:VXRP"); - snd_soc_dapm_nc_pin(codec, "LINEOUT1N"); - snd_soc_dapm_nc_pin(codec, "LINEOUT1P"); - snd_soc_dapm_nc_pin(codec, "LINEOUT2N"); - snd_soc_dapm_nc_pin(codec, "LINEOUT2P"); - - snd_soc_dapm_sync(codec); + snd_soc_dapm_nc_pin(dapm, "IN2LP:VXRN"); + snd_soc_dapm_nc_pin(dapm, "IN2RP:VXRP"); + snd_soc_dapm_nc_pin(dapm, "LINEOUT1N"); + snd_soc_dapm_nc_pin(dapm, "LINEOUT1P"); + snd_soc_dapm_nc_pin(dapm, "LINEOUT2N"); + snd_soc_dapm_nc_pin(dapm, "LINEOUT2P"); + + snd_soc_dapm_sync(dapm); /* Headset jack detection */ ret = snd_soc_jack_new(&goni, "Headset Jack", diff --git a/sound/soc/s3c24xx/jive_wm8750.c b/sound/soc/s3c24xx/jive_wm8750.c index 49605cd83947..e3599e283568 100644 --- a/sound/soc/s3c24xx/jive_wm8750.c +++ b/sound/soc/s3c24xx/jive_wm8750.c @@ -111,18 +111,19 @@ static struct snd_soc_ops jive_ops = { static int jive_wm8750_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_dapm_context *dapm = &codec->dapm; int err; /* These endpoints are not being used. */ - snd_soc_dapm_nc_pin(codec, "LINPUT2"); - snd_soc_dapm_nc_pin(codec, "RINPUT2"); - snd_soc_dapm_nc_pin(codec, "LINPUT3"); - snd_soc_dapm_nc_pin(codec, "RINPUT3"); - snd_soc_dapm_nc_pin(codec, "OUT3"); - snd_soc_dapm_nc_pin(codec, "MONO"); + snd_soc_dapm_nc_pin(dapm, "LINPUT2"); + snd_soc_dapm_nc_pin(dapm, "RINPUT2"); + snd_soc_dapm_nc_pin(dapm, "LINPUT3"); + snd_soc_dapm_nc_pin(dapm, "RINPUT3"); + snd_soc_dapm_nc_pin(dapm, "OUT3"); + snd_soc_dapm_nc_pin(dapm, "MONO"); /* Add jive specific widgets */ - err = snd_soc_dapm_new_controls(codec, wm8750_dapm_widgets, + err = snd_soc_dapm_new_controls(dapm, wm8750_dapm_widgets, ARRAY_SIZE(wm8750_dapm_widgets)); if (err) { printk(KERN_ERR "%s: failed to add widgets (%d)\n", @@ -130,8 +131,8 @@ static int jive_wm8750_init(struct snd_soc_pcm_runtime *rtd) return err; } - snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); - snd_soc_dapm_sync(codec); + snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); + snd_soc_dapm_sync(dapm); return 0; } diff --git a/sound/soc/s3c24xx/neo1973_gta02_wm8753.c b/sound/soc/s3c24xx/neo1973_gta02_wm8753.c index e97bdf150a03..c3f63ef8ab12 100644 --- a/sound/soc/s3c24xx/neo1973_gta02_wm8753.c +++ b/sound/soc/s3c24xx/neo1973_gta02_wm8753.c @@ -333,16 +333,17 @@ static const struct snd_kcontrol_new wm8753_neo1973_gta02_controls[] = { static int neo1973_gta02_wm8753_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_dapm_context *dapm = &codec->dapm; int err; /* set up NC codec pins */ - snd_soc_dapm_nc_pin(codec, "OUT3"); - snd_soc_dapm_nc_pin(codec, "OUT4"); - snd_soc_dapm_nc_pin(codec, "LINE1"); - snd_soc_dapm_nc_pin(codec, "LINE2"); + snd_soc_dapm_nc_pin(dapm, "OUT3"); + snd_soc_dapm_nc_pin(dapm, "OUT4"); + snd_soc_dapm_nc_pin(dapm, "LINE1"); + snd_soc_dapm_nc_pin(dapm, "LINE2"); /* Add neo1973 gta02 specific widgets */ - snd_soc_dapm_new_controls(codec, wm8753_dapm_widgets, + snd_soc_dapm_new_controls(dapm, wm8753_dapm_widgets, ARRAY_SIZE(wm8753_dapm_widgets)); /* add neo1973 gta02 specific controls */ @@ -353,25 +354,25 @@ static int neo1973_gta02_wm8753_init(struct snd_soc_pcm_runtime *rtd) return err; /* set up neo1973 gta02 specific audio path audio_map */ - snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); + snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); /* set endpoints to default off mode */ - snd_soc_dapm_disable_pin(codec, "Stereo Out"); - snd_soc_dapm_disable_pin(codec, "GSM Line Out"); - snd_soc_dapm_disable_pin(codec, "GSM Line In"); - snd_soc_dapm_disable_pin(codec, "Headset Mic"); - snd_soc_dapm_disable_pin(codec, "Handset Mic"); - snd_soc_dapm_disable_pin(codec, "Handset Spk"); + snd_soc_dapm_disable_pin(dapm, "Stereo Out"); + snd_soc_dapm_disable_pin(dapm, "GSM Line Out"); + snd_soc_dapm_disable_pin(dapm, "GSM Line In"); + snd_soc_dapm_disable_pin(dapm, "Headset Mic"); + snd_soc_dapm_disable_pin(dapm, "Handset Mic"); + snd_soc_dapm_disable_pin(dapm, "Handset Spk"); /* allow audio paths from the GSM modem to run during suspend */ - snd_soc_dapm_ignore_suspend(codec, "Stereo Out"); - snd_soc_dapm_ignore_suspend(codec, "GSM Line Out"); - snd_soc_dapm_ignore_suspend(codec, "GSM Line In"); - snd_soc_dapm_ignore_suspend(codec, "Headset Mic"); - snd_soc_dapm_ignore_suspend(codec, "Handset Mic"); - snd_soc_dapm_ignore_suspend(codec, "Handset Spk"); - - snd_soc_dapm_sync(codec); + snd_soc_dapm_ignore_suspend(dapm, "Stereo Out"); + snd_soc_dapm_ignore_suspend(dapm, "GSM Line Out"); + snd_soc_dapm_ignore_suspend(dapm, "GSM Line In"); + snd_soc_dapm_ignore_suspend(dapm, "Headset Mic"); + snd_soc_dapm_ignore_suspend(dapm, "Handset Mic"); + snd_soc_dapm_ignore_suspend(dapm, "Handset Spk"); + + snd_soc_dapm_sync(dapm); return 0; } diff --git a/sound/soc/s3c24xx/neo1973_wm8753.c b/sound/soc/s3c24xx/neo1973_wm8753.c index f4f2ee731f01..e94ffe01a4a5 100644 --- a/sound/soc/s3c24xx/neo1973_wm8753.c +++ b/sound/soc/s3c24xx/neo1973_wm8753.c @@ -237,81 +237,83 @@ static int neo1973_get_scenario(struct snd_kcontrol *kcontrol, static int set_scenario_endpoints(struct snd_soc_codec *codec, int scenario) { + struct snd_soc_dapm_context *dapm = &codec->dapm; + pr_debug("Entered %s\n", __func__); switch (neo1973_scenario) { case NEO_AUDIO_OFF: - snd_soc_dapm_disable_pin(codec, "Audio Out"); - snd_soc_dapm_disable_pin(codec, "GSM Line Out"); - snd_soc_dapm_disable_pin(codec, "GSM Line In"); - snd_soc_dapm_disable_pin(codec, "Headset Mic"); - snd_soc_dapm_disable_pin(codec, "Call Mic"); + snd_soc_dapm_disable_pin(dapm, "Audio Out"); + snd_soc_dapm_disable_pin(dapm, "GSM Line Out"); + snd_soc_dapm_disable_pin(dapm, "GSM Line In"); + snd_soc_dapm_disable_pin(dapm, "Headset Mic"); + snd_soc_dapm_disable_pin(dapm, "Call Mic"); break; case NEO_GSM_CALL_AUDIO_HANDSET: - snd_soc_dapm_enable_pin(codec, "Audio Out"); - snd_soc_dapm_enable_pin(codec, "GSM Line Out"); - snd_soc_dapm_enable_pin(codec, "GSM Line In"); - snd_soc_dapm_disable_pin(codec, "Headset Mic"); - snd_soc_dapm_enable_pin(codec, "Call Mic"); + snd_soc_dapm_enable_pin(dapm, "Audio Out"); + snd_soc_dapm_enable_pin(dapm, "GSM Line Out"); + snd_soc_dapm_enable_pin(dapm, "GSM Line In"); + snd_soc_dapm_disable_pin(dapm, "Headset Mic"); + snd_soc_dapm_enable_pin(dapm, "Call Mic"); break; case NEO_GSM_CALL_AUDIO_HEADSET: - snd_soc_dapm_enable_pin(codec, "Audio Out"); - snd_soc_dapm_enable_pin(codec, "GSM Line Out"); - snd_soc_dapm_enable_pin(codec, "GSM Line In"); - snd_soc_dapm_enable_pin(codec, "Headset Mic"); - snd_soc_dapm_disable_pin(codec, "Call Mic"); + snd_soc_dapm_enable_pin(dapm, "Audio Out"); + snd_soc_dapm_enable_pin(dapm, "GSM Line Out"); + snd_soc_dapm_enable_pin(dapm, "GSM Line In"); + snd_soc_dapm_enable_pin(dapm, "Headset Mic"); + snd_soc_dapm_disable_pin(dapm, "Call Mic"); break; case NEO_GSM_CALL_AUDIO_BLUETOOTH: - snd_soc_dapm_disable_pin(codec, "Audio Out"); - snd_soc_dapm_enable_pin(codec, "GSM Line Out"); - snd_soc_dapm_enable_pin(codec, "GSM Line In"); - snd_soc_dapm_disable_pin(codec, "Headset Mic"); - snd_soc_dapm_disable_pin(codec, "Call Mic"); + snd_soc_dapm_disable_pin(dapm, "Audio Out"); + snd_soc_dapm_enable_pin(dapm, "GSM Line Out"); + snd_soc_dapm_enable_pin(dapm, "GSM Line In"); + snd_soc_dapm_disable_pin(dapm, "Headset Mic"); + snd_soc_dapm_disable_pin(dapm, "Call Mic"); break; case NEO_STEREO_TO_SPEAKERS: - snd_soc_dapm_enable_pin(codec, "Audio Out"); - snd_soc_dapm_disable_pin(codec, "GSM Line Out"); - snd_soc_dapm_disable_pin(codec, "GSM Line In"); - snd_soc_dapm_disable_pin(codec, "Headset Mic"); - snd_soc_dapm_disable_pin(codec, "Call Mic"); + snd_soc_dapm_enable_pin(dapm, "Audio Out"); + snd_soc_dapm_disable_pin(dapm, "GSM Line Out"); + snd_soc_dapm_disable_pin(dapm, "GSM Line In"); + snd_soc_dapm_disable_pin(dapm, "Headset Mic"); + snd_soc_dapm_disable_pin(dapm, "Call Mic"); break; case NEO_STEREO_TO_HEADPHONES: - snd_soc_dapm_enable_pin(codec, "Audio Out"); - snd_soc_dapm_disable_pin(codec, "GSM Line Out"); - snd_soc_dapm_disable_pin(codec, "GSM Line In"); - snd_soc_dapm_disable_pin(codec, "Headset Mic"); - snd_soc_dapm_disable_pin(codec, "Call Mic"); + snd_soc_dapm_enable_pin(dapm, "Audio Out"); + snd_soc_dapm_disable_pin(dapm, "GSM Line Out"); + snd_soc_dapm_disable_pin(dapm, "GSM Line In"); + snd_soc_dapm_disable_pin(dapm, "Headset Mic"); + snd_soc_dapm_disable_pin(dapm, "Call Mic"); break; case NEO_CAPTURE_HANDSET: - snd_soc_dapm_disable_pin(codec, "Audio Out"); - snd_soc_dapm_disable_pin(codec, "GSM Line Out"); - snd_soc_dapm_disable_pin(codec, "GSM Line In"); - snd_soc_dapm_disable_pin(codec, "Headset Mic"); - snd_soc_dapm_enable_pin(codec, "Call Mic"); + snd_soc_dapm_disable_pin(dapm, "Audio Out"); + snd_soc_dapm_disable_pin(dapm, "GSM Line Out"); + snd_soc_dapm_disable_pin(dapm, "GSM Line In"); + snd_soc_dapm_disable_pin(dapm, "Headset Mic"); + snd_soc_dapm_enable_pin(dapm, "Call Mic"); break; case NEO_CAPTURE_HEADSET: - snd_soc_dapm_disable_pin(codec, "Audio Out"); - snd_soc_dapm_disable_pin(codec, "GSM Line Out"); - snd_soc_dapm_disable_pin(codec, "GSM Line In"); - snd_soc_dapm_enable_pin(codec, "Headset Mic"); - snd_soc_dapm_disable_pin(codec, "Call Mic"); + snd_soc_dapm_disable_pin(dapm, "Audio Out"); + snd_soc_dapm_disable_pin(dapm, "GSM Line Out"); + snd_soc_dapm_disable_pin(dapm, "GSM Line In"); + snd_soc_dapm_enable_pin(dapm, "Headset Mic"); + snd_soc_dapm_disable_pin(dapm, "Call Mic"); break; case NEO_CAPTURE_BLUETOOTH: - snd_soc_dapm_disable_pin(codec, "Audio Out"); - snd_soc_dapm_disable_pin(codec, "GSM Line Out"); - snd_soc_dapm_disable_pin(codec, "GSM Line In"); - snd_soc_dapm_disable_pin(codec, "Headset Mic"); - snd_soc_dapm_disable_pin(codec, "Call Mic"); + snd_soc_dapm_disable_pin(dapm, "Audio Out"); + snd_soc_dapm_disable_pin(dapm, "GSM Line Out"); + snd_soc_dapm_disable_pin(dapm, "GSM Line In"); + snd_soc_dapm_disable_pin(dapm, "Headset Mic"); + snd_soc_dapm_disable_pin(dapm, "Call Mic"); break; default: - snd_soc_dapm_disable_pin(codec, "Audio Out"); - snd_soc_dapm_disable_pin(codec, "GSM Line Out"); - snd_soc_dapm_disable_pin(codec, "GSM Line In"); - snd_soc_dapm_disable_pin(codec, "Headset Mic"); - snd_soc_dapm_disable_pin(codec, "Call Mic"); + snd_soc_dapm_disable_pin(dapm, "Audio Out"); + snd_soc_dapm_disable_pin(dapm, "GSM Line Out"); + snd_soc_dapm_disable_pin(dapm, "GSM Line In"); + snd_soc_dapm_disable_pin(dapm, "Headset Mic"); + snd_soc_dapm_disable_pin(dapm, "Call Mic"); } - snd_soc_dapm_sync(codec); + snd_soc_dapm_sync(dapm); return 0; } @@ -502,20 +504,21 @@ static const struct snd_kcontrol_new wm8753_neo1973_controls[] = { static int neo1973_wm8753_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_dapm_context *dapm = &codec->dapm; int err; pr_debug("Entered %s\n", __func__); /* set up NC codec pins */ - snd_soc_dapm_nc_pin(codec, "LOUT2"); - snd_soc_dapm_nc_pin(codec, "ROUT2"); - snd_soc_dapm_nc_pin(codec, "OUT3"); - snd_soc_dapm_nc_pin(codec, "OUT4"); - snd_soc_dapm_nc_pin(codec, "LINE1"); - snd_soc_dapm_nc_pin(codec, "LINE2"); + snd_soc_dapm_nc_pin(dapm, "LOUT2"); + snd_soc_dapm_nc_pin(dapm, "ROUT2"); + snd_soc_dapm_nc_pin(dapm, "OUT3"); + snd_soc_dapm_nc_pin(dapm, "OUT4"); + snd_soc_dapm_nc_pin(dapm, "LINE1"); + snd_soc_dapm_nc_pin(dapm, "LINE2"); /* Add neo1973 specific widgets */ - snd_soc_dapm_new_controls(codec, wm8753_dapm_widgets, + snd_soc_dapm_new_controls(dapm, wm8753_dapm_widgets, ARRAY_SIZE(wm8753_dapm_widgets)); /* set endpoints to default mode */ @@ -528,10 +531,10 @@ static int neo1973_wm8753_init(struct snd_soc_pcm_runtime *rtd) return err; /* set up neo1973 specific audio routes */ - err = snd_soc_dapm_add_routes(codec, dapm_routes, + err = snd_soc_dapm_add_routes(dapm, dapm_routes, ARRAY_SIZE(dapm_routes)); - snd_soc_dapm_sync(codec); + snd_soc_dapm_sync(dapm); return 0; } diff --git a/sound/soc/s3c24xx/rx1950_uda1380.c b/sound/soc/s3c24xx/rx1950_uda1380.c index ffd5cf2fb0a9..105d177fa427 100644 --- a/sound/soc/s3c24xx/rx1950_uda1380.c +++ b/sound/soc/s3c24xx/rx1950_uda1380.c @@ -232,26 +232,27 @@ static int rx1950_hw_params(struct snd_pcm_substream *substream, static int rx1950_uda1380_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_dapm_context *dapm = &codec->dapm; int err; /* Add rx1950 specific widgets */ - err = snd_soc_dapm_new_controls(codec, uda1380_dapm_widgets, + err = snd_soc_dapm_new_controls(dapm, uda1380_dapm_widgets, ARRAY_SIZE(uda1380_dapm_widgets)); if (err) return err; /* Set up rx1950 specific audio path audio_mapnects */ - err = snd_soc_dapm_add_routes(codec, audio_map, + err = snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); if (err) return err; - snd_soc_dapm_enable_pin(codec, "Headphone Jack"); - snd_soc_dapm_enable_pin(codec, "Speaker"); + snd_soc_dapm_enable_pin(dapm, "Headphone Jack"); + snd_soc_dapm_enable_pin(dapm, "Speaker"); - snd_soc_dapm_sync(codec); + snd_soc_dapm_sync(dapm); snd_soc_jack_new(codec, "Headphone Jack", SND_JACK_HEADPHONE, &hp_jack); diff --git a/sound/soc/s3c24xx/s3c24xx_simtec_hermes.c b/sound/soc/s3c24xx/s3c24xx_simtec_hermes.c index f88453735ae2..05c793705d90 100644 --- a/sound/soc/s3c24xx/s3c24xx_simtec_hermes.c +++ b/sound/soc/s3c24xx/s3c24xx_simtec_hermes.c @@ -76,19 +76,20 @@ static const struct snd_soc_dapm_route base_map[] = { static int simtec_hermes_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_dapm_context *dapm = &codec->dapm; - snd_soc_dapm_new_controls(codec, dapm_widgets, + snd_soc_dapm_new_controls(dapm, dapm_widgets, ARRAY_SIZE(dapm_widgets)); - snd_soc_dapm_add_routes(codec, base_map, ARRAY_SIZE(base_map)); + snd_soc_dapm_add_routes(dapm, base_map, ARRAY_SIZE(base_map)); - snd_soc_dapm_enable_pin(codec, "Headphone Jack"); - snd_soc_dapm_enable_pin(codec, "Line In"); - snd_soc_dapm_enable_pin(codec, "Line Out"); - snd_soc_dapm_enable_pin(codec, "Mic Jack"); + snd_soc_dapm_enable_pin(dapm, "Headphone Jack"); + snd_soc_dapm_enable_pin(dapm, "Line In"); + snd_soc_dapm_enable_pin(dapm, "Line Out"); + snd_soc_dapm_enable_pin(dapm, "Mic Jack"); simtec_audio_init(rtd); - snd_soc_dapm_sync(codec); + snd_soc_dapm_sync(dapm); return 0; } diff --git a/sound/soc/s3c24xx/s3c24xx_simtec_tlv320aic23.c b/sound/soc/s3c24xx/s3c24xx_simtec_tlv320aic23.c index c0967593510d..653dc7592e81 100644 --- a/sound/soc/s3c24xx/s3c24xx_simtec_tlv320aic23.c +++ b/sound/soc/s3c24xx/s3c24xx_simtec_tlv320aic23.c @@ -65,19 +65,20 @@ static const struct snd_soc_dapm_route base_map[] = { static int simtec_tlv320aic23_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_dapm_context *dapm = &codec->dapm; - snd_soc_dapm_new_controls(codec, dapm_widgets, + snd_soc_dapm_new_controls(dapm, dapm_widgets, ARRAY_SIZE(dapm_widgets)); - snd_soc_dapm_add_routes(codec, base_map, ARRAY_SIZE(base_map)); + snd_soc_dapm_add_routes(dapm, base_map, ARRAY_SIZE(base_map)); - snd_soc_dapm_enable_pin(codec, "Headphone Jack"); - snd_soc_dapm_enable_pin(codec, "Line In"); - snd_soc_dapm_enable_pin(codec, "Line Out"); - snd_soc_dapm_enable_pin(codec, "Mic Jack"); + snd_soc_dapm_enable_pin(dapm, "Headphone Jack"); + snd_soc_dapm_enable_pin(dapm, "Line In"); + snd_soc_dapm_enable_pin(dapm, "Line Out"); + snd_soc_dapm_enable_pin(dapm, "Mic Jack"); simtec_audio_init(rtd); - snd_soc_dapm_sync(codec); + snd_soc_dapm_sync(dapm); return 0; } diff --git a/sound/soc/s3c24xx/smartq_wm8987.c b/sound/soc/s3c24xx/smartq_wm8987.c index dd20ca7f4681..1f6da1e27b1e 100644 --- a/sound/soc/s3c24xx/smartq_wm8987.c +++ b/sound/soc/s3c24xx/smartq_wm8987.c @@ -158,10 +158,11 @@ static const struct snd_soc_dapm_route audio_map[] = { static int smartq_wm8987_init(struct snd_soc_codec *codec) { + struct snd_soc_dapm_context *dapm = &codec->dapm; int err = 0; /* Add SmartQ specific widgets */ - snd_soc_dapm_new_controls(codec, wm8987_dapm_widgets, + snd_soc_dapm_new_controls(dapm, wm8987_dapm_widgets, ARRAY_SIZE(wm8987_dapm_widgets)); /* add SmartQ specific controls */ @@ -172,20 +173,20 @@ static int smartq_wm8987_init(struct snd_soc_codec *codec) return err; /* setup SmartQ specific audio path */ - snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); + snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); /* set endpoints to not connected */ - snd_soc_dapm_nc_pin(codec, "LINPUT1"); - snd_soc_dapm_nc_pin(codec, "RINPUT1"); - snd_soc_dapm_nc_pin(codec, "OUT3"); - snd_soc_dapm_nc_pin(codec, "ROUT1"); + snd_soc_dapm_nc_pin(dapm, "LINPUT1"); + snd_soc_dapm_nc_pin(dapm, "RINPUT1"); + snd_soc_dapm_nc_pin(dapm, "OUT3"); + snd_soc_dapm_nc_pin(dapm, "ROUT1"); /* set endpoints to default off mode */ - snd_soc_dapm_enable_pin(codec, "Internal Speaker"); - snd_soc_dapm_enable_pin(codec, "Internal Mic"); - snd_soc_dapm_disable_pin(codec, "Headphone Jack"); + snd_soc_dapm_enable_pin(dapm, "Internal Speaker"); + snd_soc_dapm_enable_pin(dapm, "Internal Mic"); + snd_soc_dapm_disable_pin(dapm, "Headphone Jack"); - err = snd_soc_dapm_sync(codec); + err = snd_soc_dapm_sync(dapm); if (err) return err; diff --git a/sound/soc/s3c24xx/smdk64xx_wm8580.c b/sound/soc/s3c24xx/smdk64xx_wm8580.c index 052e499b68d1..291939cf8483 100644 --- a/sound/soc/s3c24xx/smdk64xx_wm8580.c +++ b/sound/soc/s3c24xx/smdk64xx_wm8580.c @@ -182,21 +182,22 @@ static const struct snd_soc_dapm_route audio_map_rx[] = { static int smdk64xx_wm8580_init_paiftx(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_dapm_context *dapm = &codec->dapm; /* Add smdk64xx specific Capture widgets */ - snd_soc_dapm_new_controls(codec, wm8580_dapm_widgets_cpt, + snd_soc_dapm_new_controls(dapm, wm8580_dapm_widgets_cpt, ARRAY_SIZE(wm8580_dapm_widgets_cpt)); /* Set up PAIFTX audio path */ - snd_soc_dapm_add_routes(codec, audio_map_tx, ARRAY_SIZE(audio_map_tx)); + snd_soc_dapm_add_routes(dapm, audio_map_tx, ARRAY_SIZE(audio_map_tx)); /* Enabling the microphone requires the fitting of a 0R * resistor to connect the line from the microphone jack. */ - snd_soc_dapm_disable_pin(codec, "MicIn"); + snd_soc_dapm_disable_pin(dapm, "MicIn"); /* signal a DAPM event */ - snd_soc_dapm_sync(codec); + snd_soc_dapm_sync(dapm); return 0; } @@ -204,16 +205,17 @@ static int smdk64xx_wm8580_init_paiftx(struct snd_soc_pcm_runtime *rtd) static int smdk64xx_wm8580_init_paifrx(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_dapm_context *dapm = &codec->dapm; /* Add smdk64xx specific Playback widgets */ - snd_soc_dapm_new_controls(codec, wm8580_dapm_widgets_pbk, + snd_soc_dapm_new_controls(dapm, wm8580_dapm_widgets_pbk, ARRAY_SIZE(wm8580_dapm_widgets_pbk)); /* Set up PAIFRX audio path */ - snd_soc_dapm_add_routes(codec, audio_map_rx, ARRAY_SIZE(audio_map_rx)); + snd_soc_dapm_add_routes(dapm, audio_map_rx, ARRAY_SIZE(audio_map_rx)); /* signal a DAPM event */ - snd_soc_dapm_sync(codec); + snd_soc_dapm_sync(dapm); return 0; } diff --git a/sound/soc/s6000/s6105-ipcam.c b/sound/soc/s6000/s6105-ipcam.c index 96c05e137538..db1803d9665a 100644 --- a/sound/soc/s6000/s6105-ipcam.c +++ b/sound/soc/s6000/s6105-ipcam.c @@ -107,6 +107,7 @@ static int output_type_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_soc_codec *codec = kcontrol->private_data; + struct snd_soc_dapm_context *dapm = &codec->dapm; unsigned int val = (ucontrol->value.enumerated.item[0] != 0); char *differential = "Audio Out Differential"; char *stereo = "Audio Out Stereo"; @@ -114,10 +115,10 @@ static int output_type_put(struct snd_kcontrol *kcontrol, if (kcontrol->private_value == val) return 0; kcontrol->private_value = val; - snd_soc_dapm_disable_pin(codec, val ? differential : stereo); - snd_soc_dapm_sync(codec); - snd_soc_dapm_enable_pin(codec, val ? stereo : differential); - snd_soc_dapm_sync(codec); + snd_soc_dapm_disable_pin(dapm, val ? differential : stereo); + snd_soc_dapm_sync(dapm); + snd_soc_dapm_enable_pin(dapm, val ? stereo : differential); + snd_soc_dapm_sync(dapm); return 1; } @@ -137,35 +138,36 @@ static const struct snd_kcontrol_new audio_out_mux = { static int s6105_aic3x_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_dapm_context *dapm = &codec->dapm; /* Add s6105 specific widgets */ - snd_soc_dapm_new_controls(codec, aic3x_dapm_widgets, + snd_soc_dapm_new_controls(dapm, aic3x_dapm_widgets, ARRAY_SIZE(aic3x_dapm_widgets)); /* Set up s6105 specific audio path audio_map */ - snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); + snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); /* not present */ - snd_soc_dapm_nc_pin(codec, "MONO_LOUT"); - snd_soc_dapm_nc_pin(codec, "LINE2L"); - snd_soc_dapm_nc_pin(codec, "LINE2R"); + snd_soc_dapm_nc_pin(dapm, "MONO_LOUT"); + snd_soc_dapm_nc_pin(dapm, "LINE2L"); + snd_soc_dapm_nc_pin(dapm, "LINE2R"); /* not connected */ - snd_soc_dapm_nc_pin(codec, "MIC3L"); /* LINE2L on this chip */ - snd_soc_dapm_nc_pin(codec, "MIC3R"); /* LINE2R on this chip */ - snd_soc_dapm_nc_pin(codec, "LLOUT"); - snd_soc_dapm_nc_pin(codec, "RLOUT"); - snd_soc_dapm_nc_pin(codec, "HPRCOM"); + snd_soc_dapm_nc_pin(dapm, "MIC3L"); /* LINE2L on this chip */ + snd_soc_dapm_nc_pin(dapm, "MIC3R"); /* LINE2R on this chip */ + snd_soc_dapm_nc_pin(dapm, "LLOUT"); + snd_soc_dapm_nc_pin(dapm, "RLOUT"); + snd_soc_dapm_nc_pin(dapm, "HPRCOM"); /* always connected */ - snd_soc_dapm_enable_pin(codec, "Audio In"); + snd_soc_dapm_enable_pin(dapm, "Audio In"); /* must correspond to audio_out_mux.private_value initializer */ - snd_soc_dapm_disable_pin(codec, "Audio Out Differential"); - snd_soc_dapm_sync(codec); - snd_soc_dapm_enable_pin(codec, "Audio Out Stereo"); + snd_soc_dapm_disable_pin(dapm, "Audio Out Differential"); + snd_soc_dapm_sync(dapm); + snd_soc_dapm_enable_pin(dapm, "Audio Out Stereo"); - snd_soc_dapm_sync(codec); + snd_soc_dapm_sync(dapm); snd_ctl_add(codec->snd_card, snd_ctl_new1(&audio_out_mux, codec)); diff --git a/sound/soc/sh/migor.c b/sound/soc/sh/migor.c index ac6c49ce6fdf..c61fc188394d 100644 --- a/sound/soc/sh/migor.c +++ b/sound/soc/sh/migor.c @@ -140,11 +140,12 @@ static const struct snd_soc_dapm_route audio_map[] = { static int migor_dai_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_dapm_context *dapm = &codec->dapm; - snd_soc_dapm_new_controls(codec, migor_dapm_widgets, + snd_soc_dapm_new_controls(dapm, migor_dapm_widgets, ARRAY_SIZE(migor_dapm_widgets)); - snd_soc_dapm_add_routes(codec, audio_map, ARRAY_SIZE(audio_map)); + snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); return 0; } diff --git a/sound/soc/sh/sh7760-ac97.c b/sound/soc/sh/sh7760-ac97.c index f8e0ab82ef59..105d4112e3ba 100644 --- a/sound/soc/sh/sh7760-ac97.c +++ b/sound/soc/sh/sh7760-ac97.c @@ -23,7 +23,7 @@ extern struct snd_soc_platform_driver sh7760_soc_platform; static int machine_init(struct snd_soc_pcm_runtime *rtd) { - snd_soc_dapm_sync(rtd->codec); + snd_soc_dapm_sync(&rtd->codec->dapm); return 0; } diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 2198936cfb68..3c7c884f212c 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -255,18 +255,18 @@ static void soc_init_codec_debugfs(struct snd_soc_codec *codec) codec->debugfs_pop_time = debugfs_create_u32("dapm_pop_time", 0644, codec->debugfs_codec_root, - &codec->pop_time); + &codec->dapm.pop_time); if (!codec->debugfs_pop_time) printk(KERN_WARNING "Failed to create pop time debugfs file\n"); - codec->debugfs_dapm = debugfs_create_dir("dapm", + codec->dapm.debugfs_dapm = debugfs_create_dir("dapm", codec->debugfs_codec_root); - if (!codec->debugfs_dapm) + if (!codec->dapm.debugfs_dapm) printk(KERN_WARNING "Failed to create DAPM debugfs directory\n"); - snd_soc_dapm_debugfs_init(codec); + snd_soc_dapm_debugfs_init(&codec->dapm); } static void soc_cleanup_codec_debugfs(struct snd_soc_codec *codec) @@ -1017,7 +1017,7 @@ static int soc_suspend(struct device *dev) /* close any waiting streams and save state */ for (i = 0; i < card->num_rtd; i++) { run_delayed_work(&card->rtd[i].delayed_work); - card->rtd[i].codec->suspend_bias_level = card->rtd[i].codec->bias_level; + card->rtd[i].codec->dapm.suspend_bias_level = card->rtd[i].codec->dapm.bias_level; } for (i = 0; i < card->num_rtd; i++) { @@ -1041,7 +1041,7 @@ static int soc_suspend(struct device *dev) /* If there are paths active then the CODEC will be held with * bias _ON and should not be suspended. */ if (!codec->suspended && codec->driver->suspend) { - switch (codec->bias_level) { + switch (codec->dapm.bias_level) { case SND_SOC_BIAS_STANDBY: case SND_SOC_BIAS_OFF: codec->driver->suspend(codec, PMSG_SUSPEND); @@ -1110,7 +1110,7 @@ static void soc_resume_deferred(struct work_struct *work) * resume. Otherwise the suspend was suppressed. */ if (codec->driver->resume && codec->suspended) { - switch (codec->bias_level) { + switch (codec->dapm.bias_level) { case SND_SOC_BIAS_STANDBY: case SND_SOC_BIAS_OFF: codec->driver->resume(codec); @@ -1346,7 +1346,7 @@ static void soc_remove_dai_link(struct snd_soc_card *card, int num) } /* Make sure all DAPM widgets are freed */ - snd_soc_dapm_free(codec); + snd_soc_dapm_free(&codec->dapm); soc_cleanup_codec_debugfs(codec); device_remove_file(&rtd->dev, &dev_attr_codec_reg); @@ -1470,8 +1470,8 @@ static int soc_probe_dai_link(struct snd_soc_card *card, int num) } /* Make sure all DAPM widgets are instantiated */ - snd_soc_dapm_new_widgets(codec); - snd_soc_dapm_sync(codec); + snd_soc_dapm_new_widgets(&codec->dapm); + snd_soc_dapm_sync(&codec->dapm); /* register the rtd device */ rtd->dev.release = rtd_release; @@ -3238,6 +3238,12 @@ int snd_soc_register_codec(struct device *dev, return -ENOMEM; } + INIT_LIST_HEAD(&codec->dapm.widgets); + INIT_LIST_HEAD(&codec->dapm.paths); + codec->dapm.bias_level = SND_SOC_BIAS_OFF; + codec->dapm.dev = dev; + codec->dapm.codec = codec; + /* allocate CODEC register cache */ if (codec_drv->reg_cache_size && codec_drv->reg_word_size) { @@ -3257,11 +3263,8 @@ int snd_soc_register_codec(struct device *dev, codec->dev = dev; codec->driver = codec_drv; - codec->bias_level = SND_SOC_BIAS_OFF; codec->num_dai = num_dai; mutex_init(&codec->mutex); - INIT_LIST_HEAD(&codec->dapm_widgets); - INIT_LIST_HEAD(&codec->dapm_paths); for (i = 0; i < num_dai; i++) { fixup_codec_formats(&dai_drv[i].playback); diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index 7d85c6496afa..b8f653eaffaa 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -42,6 +42,7 @@ #include #include #include +#include #include #include @@ -120,35 +121,36 @@ static inline struct snd_soc_dapm_widget *dapm_cnew_widget( * Returns 0 for success else error. */ static int snd_soc_dapm_set_bias_level(struct snd_soc_card *card, - struct snd_soc_codec *codec, enum snd_soc_bias_level level) + struct snd_soc_dapm_context *dapm, + enum snd_soc_bias_level level) { int ret = 0; switch (level) { case SND_SOC_BIAS_ON: - dev_dbg(codec->dev, "Setting full bias\n"); + dev_dbg(dapm->dev, "Setting full bias\n"); break; case SND_SOC_BIAS_PREPARE: - dev_dbg(codec->dev, "Setting bias prepare\n"); + dev_dbg(dapm->dev, "Setting bias prepare\n"); break; case SND_SOC_BIAS_STANDBY: - dev_dbg(codec->dev, "Setting standby bias\n"); + dev_dbg(dapm->dev, "Setting standby bias\n"); break; case SND_SOC_BIAS_OFF: - dev_dbg(codec->dev, "Setting bias off\n"); + dev_dbg(dapm->dev, "Setting bias off\n"); break; default: - dev_err(codec->dev, "Setting invalid bias %d\n", level); + dev_err(dapm->dev, "Setting invalid bias %d\n", level); return -EINVAL; } if (card && card->set_bias_level) ret = card->set_bias_level(card, level); if (ret == 0) { - if (codec->driver->set_bias_level) - ret = codec->driver->set_bias_level(codec, level); + if (dapm->codec && dapm->codec->driver->set_bias_level) + ret = dapm->codec->driver->set_bias_level(dapm->codec, level); else - codec->bias_level = level; + dapm->bias_level = level; } return ret; @@ -241,7 +243,7 @@ static void dapm_set_path_status(struct snd_soc_dapm_widget *w, } /* connect mux widget to its interconnecting audio paths */ -static int dapm_connect_mux(struct snd_soc_codec *codec, +static int dapm_connect_mux(struct snd_soc_dapm_context *dapm, struct snd_soc_dapm_widget *src, struct snd_soc_dapm_widget *dest, struct snd_soc_dapm_path *path, const char *control_name, const struct snd_kcontrol_new *kcontrol) @@ -251,7 +253,7 @@ static int dapm_connect_mux(struct snd_soc_codec *codec, for (i = 0; i < e->max; i++) { if (!(strcmp(control_name, e->texts[i]))) { - list_add(&path->list, &codec->dapm_paths); + list_add(&path->list, &dapm->paths); list_add(&path->list_sink, &dest->sources); list_add(&path->list_source, &src->sinks); path->name = (char*)e->texts[i]; @@ -264,7 +266,7 @@ static int dapm_connect_mux(struct snd_soc_codec *codec, } /* connect mixer widget to its interconnecting audio paths */ -static int dapm_connect_mixer(struct snd_soc_codec *codec, +static int dapm_connect_mixer(struct snd_soc_dapm_context *dapm, struct snd_soc_dapm_widget *src, struct snd_soc_dapm_widget *dest, struct snd_soc_dapm_path *path, const char *control_name) { @@ -273,7 +275,7 @@ static int dapm_connect_mixer(struct snd_soc_codec *codec, /* search for mixer kcontrol */ for (i = 0; i < dest->num_kcontrols; i++) { if (!strcmp(control_name, dest->kcontrols[i].name)) { - list_add(&path->list, &codec->dapm_paths); + list_add(&path->list, &dapm->paths); list_add(&path->list_sink, &dest->sources); list_add(&path->list_source, &src->sinks); path->name = dest->kcontrols[i].name; @@ -290,6 +292,7 @@ static int dapm_update_bits(struct snd_soc_dapm_widget *widget) int change, power; unsigned int old, new; struct snd_soc_codec *codec = widget->codec; + struct snd_soc_dapm_context *dapm = widget->dapm; /* check for valid widgets */ if (widget->reg < 0 || widget->id == snd_soc_dapm_input || @@ -309,10 +312,10 @@ static int dapm_update_bits(struct snd_soc_dapm_widget *widget) change = old != new; if (change) { - pop_dbg(codec->pop_time, "pop test %s : %s in %d ms\n", + pop_dbg(dapm->pop_time, "pop test %s : %s in %d ms\n", widget->name, widget->power ? "on" : "off", - codec->pop_time); - pop_wait(codec->pop_time); + dapm->pop_time); + pop_wait(dapm->pop_time); snd_soc_write(codec, widget->reg, new); } pr_debug("reg %x old %x new %x change %d\n", widget->reg, @@ -321,12 +324,13 @@ static int dapm_update_bits(struct snd_soc_dapm_widget *widget) } /* create new dapm mixer control */ -static int dapm_new_mixer(struct snd_soc_codec *codec, +static int dapm_new_mixer(struct snd_soc_dapm_context *dapm, struct snd_soc_dapm_widget *w) { int i, ret = 0; size_t name_len; struct snd_soc_dapm_path *path; + struct snd_card *card = dapm->codec->card->snd_card; /* add kcontrol */ for (i = 0; i < w->num_kcontrols; i++) { @@ -368,7 +372,7 @@ static int dapm_new_mixer(struct snd_soc_codec *codec, path->kcontrol = snd_soc_cnew(&w->kcontrols[i], w, path->long_name); - ret = snd_ctl_add(codec->card->snd_card, path->kcontrol); + ret = snd_ctl_add(card, path->kcontrol); if (ret < 0) { printk(KERN_ERR "asoc: failed to add dapm kcontrol %s: %d\n", path->long_name, @@ -383,11 +387,12 @@ static int dapm_new_mixer(struct snd_soc_codec *codec, } /* create new dapm mux control */ -static int dapm_new_mux(struct snd_soc_codec *codec, +static int dapm_new_mux(struct snd_soc_dapm_context *dapm, struct snd_soc_dapm_widget *w) { struct snd_soc_dapm_path *path = NULL; struct snd_kcontrol *kcontrol; + struct snd_card *card = dapm->codec->card->snd_card; int ret = 0; if (!w->num_kcontrols) { @@ -396,7 +401,8 @@ static int dapm_new_mux(struct snd_soc_codec *codec, } kcontrol = snd_soc_cnew(&w->kcontrols[0], w, w->name); - ret = snd_ctl_add(codec->card->snd_card, kcontrol); + ret = snd_ctl_add(card, kcontrol); + if (ret < 0) goto err; @@ -411,7 +417,7 @@ err: } /* create new dapm volume control */ -static int dapm_new_pga(struct snd_soc_codec *codec, +static int dapm_new_pga(struct snd_soc_dapm_context *dapm, struct snd_soc_dapm_widget *w) { if (w->num_kcontrols) @@ -421,11 +427,11 @@ static int dapm_new_pga(struct snd_soc_codec *codec, } /* reset 'walked' bit for each dapm path */ -static inline void dapm_clear_walk(struct snd_soc_codec *codec) +static inline void dapm_clear_walk(struct snd_soc_dapm_context *dapm) { struct snd_soc_dapm_path *p; - list_for_each_entry(p, &codec->dapm_paths, list) + list_for_each_entry(p, &dapm->paths, list) p->walked = 0; } @@ -435,7 +441,7 @@ static inline void dapm_clear_walk(struct snd_soc_codec *codec) */ static int snd_soc_dapm_suspend_check(struct snd_soc_dapm_widget *widget) { - int level = snd_power_get_state(widget->codec->card->snd_card); + int level = snd_power_get_state(widget->dapm->codec->card->snd_card); switch (level) { case SNDRV_CTL_POWER_D3hot: @@ -621,9 +627,9 @@ static int dapm_generic_check_power(struct snd_soc_dapm_widget *w) int in, out; in = is_connected_input_ep(w); - dapm_clear_walk(w->codec); + dapm_clear_walk(w->dapm); out = is_connected_output_ep(w); - dapm_clear_walk(w->codec); + dapm_clear_walk(w->dapm); return out != 0 && in != 0; } @@ -634,7 +640,7 @@ static int dapm_adc_check_power(struct snd_soc_dapm_widget *w) if (w->active) { in = is_connected_input_ep(w); - dapm_clear_walk(w->codec); + dapm_clear_walk(w->dapm); return in != 0; } else { return dapm_generic_check_power(w); @@ -648,7 +654,7 @@ static int dapm_dac_check_power(struct snd_soc_dapm_widget *w) if (w->active) { out = is_connected_output_ep(w); - dapm_clear_walk(w->codec); + dapm_clear_walk(w->dapm); return out != 0; } else { return dapm_generic_check_power(w); @@ -674,7 +680,7 @@ static int dapm_supply_check_power(struct snd_soc_dapm_widget *w) } } - dapm_clear_walk(w->codec); + dapm_clear_walk(w->dapm); return power; } @@ -710,7 +716,7 @@ static void dapm_seq_insert(struct snd_soc_dapm_widget *new_widget, } /* Apply the coalesced changes from a DAPM sequence */ -static void dapm_seq_run_coalesced(struct snd_soc_codec *codec, +static void dapm_seq_run_coalesced(struct snd_soc_dapm_context *dapm, struct list_head *pending) { struct snd_soc_dapm_widget *w; @@ -735,14 +741,14 @@ static void dapm_seq_run_coalesced(struct snd_soc_codec *codec, if (power) value |= cur_mask; - pop_dbg(codec->pop_time, + pop_dbg(dapm->pop_time, "pop test : Queue %s: reg=0x%x, 0x%x/0x%x\n", w->name, reg, value, mask); /* power up pre event */ if (w->power && w->event && (w->event_flags & SND_SOC_DAPM_PRE_PMU)) { - pop_dbg(codec->pop_time, "pop test : %s PRE_PMU\n", + pop_dbg(dapm->pop_time, "pop test : %s PRE_PMU\n", w->name); ret = w->event(w, NULL, SND_SOC_DAPM_PRE_PMU); if (ret < 0) @@ -753,7 +759,7 @@ static void dapm_seq_run_coalesced(struct snd_soc_codec *codec, /* power down pre event */ if (!w->power && w->event && (w->event_flags & SND_SOC_DAPM_PRE_PMD)) { - pop_dbg(codec->pop_time, "pop test : %s PRE_PMD\n", + pop_dbg(dapm->pop_time, "pop test : %s PRE_PMD\n", w->name); ret = w->event(w, NULL, SND_SOC_DAPM_PRE_PMD); if (ret < 0) @@ -763,18 +769,18 @@ static void dapm_seq_run_coalesced(struct snd_soc_codec *codec, } if (reg >= 0) { - pop_dbg(codec->pop_time, + pop_dbg(dapm->pop_time, "pop test : Applying 0x%x/0x%x to %x in %dms\n", - value, mask, reg, codec->pop_time); - pop_wait(codec->pop_time); - snd_soc_update_bits(codec, reg, mask, value); + value, mask, reg, dapm->pop_time); + pop_wait(dapm->pop_time); + snd_soc_update_bits(dapm->codec, reg, mask, value); } list_for_each_entry(w, pending, power_list) { /* power up post event */ if (w->power && w->event && (w->event_flags & SND_SOC_DAPM_POST_PMU)) { - pop_dbg(codec->pop_time, "pop test : %s POST_PMU\n", + pop_dbg(dapm->pop_time, "pop test : %s POST_PMU\n", w->name); ret = w->event(w, NULL, SND_SOC_DAPM_POST_PMU); @@ -786,7 +792,7 @@ static void dapm_seq_run_coalesced(struct snd_soc_codec *codec, /* power down post event */ if (!w->power && w->event && (w->event_flags & SND_SOC_DAPM_POST_PMD)) { - pop_dbg(codec->pop_time, "pop test : %s POST_PMD\n", + pop_dbg(dapm->pop_time, "pop test : %s POST_PMD\n", w->name); ret = w->event(w, NULL, SND_SOC_DAPM_POST_PMD); if (ret < 0) @@ -804,8 +810,8 @@ static void dapm_seq_run_coalesced(struct snd_soc_codec *codec, * Currently anything that requires more than a single write is not * handled. */ -static void dapm_seq_run(struct snd_soc_codec *codec, struct list_head *list, - int event, int sort[]) +static void dapm_seq_run(struct snd_soc_dapm_context *dapm, + struct list_head *list, int event, int sort[]) { struct snd_soc_dapm_widget *w, *n; LIST_HEAD(pending); @@ -819,7 +825,7 @@ static void dapm_seq_run(struct snd_soc_codec *codec, struct list_head *list, /* Do we need to apply any queued changes? */ if (sort[w->id] != cur_sort || w->reg != cur_reg) { if (!list_empty(&pending)) - dapm_seq_run_coalesced(codec, &pending); + dapm_seq_run_coalesced(dapm, &pending); INIT_LIST_HEAD(&pending); cur_sort = -1; @@ -877,7 +883,7 @@ static void dapm_seq_run(struct snd_soc_codec *codec, struct list_head *list, } if (!list_empty(&pending)) - dapm_seq_run_coalesced(codec, &pending); + dapm_seq_run_coalesced(dapm, &pending); } /* @@ -889,9 +895,9 @@ static void dapm_seq_run(struct snd_soc_codec *codec, struct list_head *list, * o Input pin to Output pin (bypass, sidetone) * o DAC to ADC (loopback). */ -static int dapm_power_widgets(struct snd_soc_codec *codec, int event) +static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event) { - struct snd_soc_card *card = codec->card; + struct snd_soc_card *card = dapm->codec->card; struct snd_soc_dapm_widget *w; LIST_HEAD(up_list); LIST_HEAD(down_list); @@ -902,7 +908,7 @@ static int dapm_power_widgets(struct snd_soc_codec *codec, int event) /* Check which widgets we need to power and store them in * lists indicating if they should be powered up or down. */ - list_for_each_entry(w, &codec->dapm_widgets, list) { + list_for_each_entry(w, &dapm->widgets, list) { switch (w->id) { case snd_soc_dapm_pre: dapm_seq_insert(w, &down_list, dapm_down_seq); @@ -938,7 +944,7 @@ static int dapm_power_widgets(struct snd_soc_codec *codec, int event) /* If there are no DAPM widgets then try to figure out power from the * event type. */ - if (list_empty(&codec->dapm_widgets)) { + if (list_empty(&dapm->widgets)) { switch (event) { case SND_SOC_DAPM_STREAM_START: case SND_SOC_DAPM_STREAM_RESUME: @@ -948,7 +954,7 @@ static int dapm_power_widgets(struct snd_soc_codec *codec, int event) sys_power = 0; break; case SND_SOC_DAPM_STREAM_NOP: - switch (codec->bias_level) { + switch (dapm->bias_level) { case SND_SOC_BIAS_STANDBY: case SND_SOC_BIAS_OFF: sys_power = 0; @@ -963,52 +969,52 @@ static int dapm_power_widgets(struct snd_soc_codec *codec, int event) } } - if (sys_power && codec->bias_level == SND_SOC_BIAS_OFF) { - ret = snd_soc_dapm_set_bias_level(card, codec, + if (sys_power && dapm->bias_level == SND_SOC_BIAS_OFF) { + ret = snd_soc_dapm_set_bias_level(card, dapm, SND_SOC_BIAS_STANDBY); if (ret != 0) pr_err("Failed to turn on bias: %d\n", ret); } /* If we're changing to all on or all off then prepare */ - if ((sys_power && codec->bias_level == SND_SOC_BIAS_STANDBY) || - (!sys_power && codec->bias_level == SND_SOC_BIAS_ON)) { - ret = snd_soc_dapm_set_bias_level(card, codec, SND_SOC_BIAS_PREPARE); + if ((sys_power && dapm->bias_level == SND_SOC_BIAS_STANDBY) || + (!sys_power && dapm->bias_level == SND_SOC_BIAS_ON)) { + ret = snd_soc_dapm_set_bias_level(card, dapm, SND_SOC_BIAS_PREPARE); if (ret != 0) pr_err("Failed to prepare bias: %d\n", ret); } /* Power down widgets first; try to avoid amplifying pops. */ - dapm_seq_run(codec, &down_list, event, dapm_down_seq); + dapm_seq_run(dapm, &down_list, event, dapm_down_seq); /* Now power up. */ - dapm_seq_run(codec, &up_list, event, dapm_up_seq); + dapm_seq_run(dapm, &up_list, event, dapm_up_seq); /* If we just powered the last thing off drop to standby bias */ - if (codec->bias_level == SND_SOC_BIAS_PREPARE && !sys_power) { - ret = snd_soc_dapm_set_bias_level(card, codec, SND_SOC_BIAS_STANDBY); + if (dapm->bias_level == SND_SOC_BIAS_PREPARE && !sys_power) { + ret = snd_soc_dapm_set_bias_level(card, dapm, SND_SOC_BIAS_STANDBY); if (ret != 0) pr_err("Failed to apply standby bias: %d\n", ret); } /* If we're in standby and can support bias off then do that */ - if (codec->bias_level == SND_SOC_BIAS_STANDBY && - codec->idle_bias_off) { - ret = snd_soc_dapm_set_bias_level(card, codec, SND_SOC_BIAS_OFF); + if (dapm->bias_level == SND_SOC_BIAS_STANDBY && + dapm->idle_bias_off) { + ret = snd_soc_dapm_set_bias_level(card, dapm, SND_SOC_BIAS_OFF); if (ret != 0) pr_err("Failed to turn off bias: %d\n", ret); } /* If we just powered up then move to active bias */ - if (codec->bias_level == SND_SOC_BIAS_PREPARE && sys_power) { - ret = snd_soc_dapm_set_bias_level(card, codec, SND_SOC_BIAS_ON); + if (dapm->bias_level == SND_SOC_BIAS_PREPARE && sys_power) { + ret = snd_soc_dapm_set_bias_level(card, dapm, SND_SOC_BIAS_ON); if (ret != 0) pr_err("Failed to apply active bias: %d\n", ret); } - pop_dbg(codec->pop_time, "DAPM sequencing finished, waiting %dms\n", - codec->pop_time); - pop_wait(codec->pop_time); + pop_dbg(dapm->pop_time, "DAPM sequencing finished, waiting %dms\n", + dapm->pop_time); + pop_wait(dapm->pop_time); return 0; } @@ -1035,9 +1041,9 @@ static ssize_t dapm_widget_power_read_file(struct file *file, return -ENOMEM; in = is_connected_input_ep(w); - dapm_clear_walk(w->codec); + dapm_clear_walk(w->dapm); out = is_connected_output_ep(w); - dapm_clear_walk(w->codec); + dapm_clear_walk(w->dapm); ret = snprintf(buf, PAGE_SIZE, "%s: %s in %d out %d", w->name, w->power ? "On" : "Off", in, out); @@ -1087,20 +1093,20 @@ static const struct file_operations dapm_widget_power_fops = { .llseek = default_llseek, }; -void snd_soc_dapm_debugfs_init(struct snd_soc_codec *codec) +void snd_soc_dapm_debugfs_init(struct snd_soc_dapm_context *dapm) { struct snd_soc_dapm_widget *w; struct dentry *d; - if (!codec->debugfs_dapm) + if (!dapm->debugfs_dapm) return; - list_for_each_entry(w, &codec->dapm_widgets, list) { + list_for_each_entry(w, &dapm->widgets, list) { if (!w->name) continue; d = debugfs_create_file(w->name, 0444, - codec->debugfs_dapm, w, + dapm->debugfs_dapm, w, &dapm_widget_power_fops); if (!d) printk(KERN_WARNING @@ -1109,7 +1115,7 @@ void snd_soc_dapm_debugfs_init(struct snd_soc_codec *codec) } } #else -void snd_soc_dapm_debugfs_init(struct snd_soc_codec *codec) +void snd_soc_dapm_debugfs_init(struct snd_soc_dapm_context *dapm) { } #endif @@ -1130,7 +1136,7 @@ static int dapm_mux_update_power(struct snd_soc_dapm_widget *widget, return 0; /* find dapm widget path assoc with kcontrol */ - list_for_each_entry(path, &widget->codec->dapm_paths, list) { + list_for_each_entry(path, &widget->dapm->paths, list) { if (path->kcontrol != kcontrol) continue; @@ -1146,7 +1152,7 @@ static int dapm_mux_update_power(struct snd_soc_dapm_widget *widget, } if (found) - dapm_power_widgets(widget->codec, SND_SOC_DAPM_STREAM_NOP); + dapm_power_widgets(widget->dapm, SND_SOC_DAPM_STREAM_NOP); return 0; } @@ -1164,7 +1170,7 @@ static int dapm_mixer_update_power(struct snd_soc_dapm_widget *widget, return -ENODEV; /* find dapm widget path assoc with kcontrol */ - list_for_each_entry(path, &widget->codec->dapm_paths, list) { + list_for_each_entry(path, &widget->dapm->paths, list) { if (path->kcontrol != kcontrol) continue; @@ -1175,7 +1181,7 @@ static int dapm_mixer_update_power(struct snd_soc_dapm_widget *widget, } if (found) - dapm_power_widgets(widget->codec, SND_SOC_DAPM_STREAM_NOP); + dapm_power_widgets(widget->dapm, SND_SOC_DAPM_STREAM_NOP); return 0; } @@ -1191,7 +1197,7 @@ static ssize_t dapm_widget_show(struct device *dev, int count = 0; char *state = "not set"; - list_for_each_entry(w, &codec->dapm_widgets, list) { + list_for_each_entry(w, &codec->dapm.widgets, list) { /* only display widgets that burnm power */ switch (w->id) { @@ -1215,7 +1221,7 @@ static ssize_t dapm_widget_show(struct device *dev, } } - switch (codec->bias_level) { + switch (codec->dapm.bias_level) { case SND_SOC_BIAS_ON: state = "On"; break; @@ -1247,31 +1253,31 @@ static void snd_soc_dapm_sys_remove(struct device *dev) } /* free all dapm widgets and resources */ -static void dapm_free_widgets(struct snd_soc_codec *codec) +static void dapm_free_widgets(struct snd_soc_dapm_context *dapm) { struct snd_soc_dapm_widget *w, *next_w; struct snd_soc_dapm_path *p, *next_p; - list_for_each_entry_safe(w, next_w, &codec->dapm_widgets, list) { + list_for_each_entry_safe(w, next_w, &dapm->widgets, list) { list_del(&w->list); kfree(w); } - list_for_each_entry_safe(p, next_p, &codec->dapm_paths, list) { + list_for_each_entry_safe(p, next_p, &dapm->paths, list) { list_del(&p->list); kfree(p->long_name); kfree(p); } } -static int snd_soc_dapm_set_pin(struct snd_soc_codec *codec, +static int snd_soc_dapm_set_pin(struct snd_soc_dapm_context *dapm, const char *pin, int status) { struct snd_soc_dapm_widget *w; - list_for_each_entry(w, &codec->dapm_widgets, list) { + list_for_each_entry(w, &dapm->widgets, list) { if (!strcmp(w->name, pin)) { - pr_debug("dapm: %s: pin %s\n", codec->name, pin); + pr_debug("dapm: %s: pin %s\n", dapm->codec->name, pin); w->connected = status; /* Allow disabling of forced pins */ if (status == 0) @@ -1280,26 +1286,27 @@ static int snd_soc_dapm_set_pin(struct snd_soc_codec *codec, } } - pr_err("dapm: %s: configuring unknown pin %s\n", codec->name, pin); + pr_err("dapm: %s: configuring unknown pin %s\n", + dapm->codec->name, pin); return -EINVAL; } /** * snd_soc_dapm_sync - scan and power dapm paths - * @codec: audio codec + * @dapm: DAPM context * * Walks all dapm audio paths and powers widgets according to their * stream or path usage. * * Returns 0 for success. */ -int snd_soc_dapm_sync(struct snd_soc_codec *codec) +int snd_soc_dapm_sync(struct snd_soc_dapm_context *dapm) { - return dapm_power_widgets(codec, SND_SOC_DAPM_STREAM_NOP); + return dapm_power_widgets(dapm, SND_SOC_DAPM_STREAM_NOP); } EXPORT_SYMBOL_GPL(snd_soc_dapm_sync); -static int snd_soc_dapm_add_route(struct snd_soc_codec *codec, +static int snd_soc_dapm_add_route(struct snd_soc_dapm_context *dapm, const struct snd_soc_dapm_route *route) { struct snd_soc_dapm_path *path; @@ -1310,7 +1317,7 @@ static int snd_soc_dapm_add_route(struct snd_soc_codec *codec, int ret = 0; /* find src and dest widgets */ - list_for_each_entry(w, &codec->dapm_widgets, list) { + list_for_each_entry(w, &dapm->widgets, list) { if (!wsink && !(strcmp(w->name, sink))) { wsink = w; @@ -1353,7 +1360,7 @@ static int snd_soc_dapm_add_route(struct snd_soc_codec *codec, /* connect static paths */ if (control == NULL) { - list_add(&path->list, &codec->dapm_paths); + list_add(&path->list, &dapm->paths); list_add(&path->list_sink, &wsink->sources); list_add(&path->list_source, &wsource->sinks); path->connect = 1; @@ -1374,14 +1381,14 @@ static int snd_soc_dapm_add_route(struct snd_soc_codec *codec, case snd_soc_dapm_supply: case snd_soc_dapm_aif_in: case snd_soc_dapm_aif_out: - list_add(&path->list, &codec->dapm_paths); + list_add(&path->list, &dapm->paths); list_add(&path->list_sink, &wsink->sources); list_add(&path->list_source, &wsource->sinks); path->connect = 1; return 0; case snd_soc_dapm_mux: case snd_soc_dapm_value_mux: - ret = dapm_connect_mux(codec, wsource, wsink, path, control, + ret = dapm_connect_mux(dapm, wsource, wsink, path, control, &wsink->kcontrols[0]); if (ret != 0) goto err; @@ -1389,7 +1396,7 @@ static int snd_soc_dapm_add_route(struct snd_soc_codec *codec, case snd_soc_dapm_switch: case snd_soc_dapm_mixer: case snd_soc_dapm_mixer_named_ctl: - ret = dapm_connect_mixer(codec, wsource, wsink, path, control); + ret = dapm_connect_mixer(dapm, wsource, wsink, path, control); if (ret != 0) goto err; break; @@ -1397,7 +1404,7 @@ static int snd_soc_dapm_add_route(struct snd_soc_codec *codec, case snd_soc_dapm_mic: case snd_soc_dapm_line: case snd_soc_dapm_spk: - list_add(&path->list, &codec->dapm_paths); + list_add(&path->list, &dapm->paths); list_add(&path->list_sink, &wsink->sources); list_add(&path->list_source, &wsource->sinks); path->connect = 0; @@ -1414,7 +1421,7 @@ err: /** * snd_soc_dapm_add_routes - Add routes between DAPM widgets - * @codec: codec + * @dapm: DAPM context * @route: audio routes * @num: number of routes * @@ -1425,13 +1432,13 @@ err: * Returns 0 for success else error. On error all resources can be freed * with a call to snd_soc_card_free(). */ -int snd_soc_dapm_add_routes(struct snd_soc_codec *codec, +int snd_soc_dapm_add_routes(struct snd_soc_dapm_context *dapm, const struct snd_soc_dapm_route *route, int num) { int i, ret; for (i = 0; i < num; i++) { - ret = snd_soc_dapm_add_route(codec, route); + ret = snd_soc_dapm_add_route(dapm, route); if (ret < 0) { printk(KERN_ERR "Failed to add route %s->%s\n", route->source, @@ -1447,17 +1454,17 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_add_routes); /** * snd_soc_dapm_new_widgets - add new dapm widgets - * @codec: audio codec + * @dapm: DAPM context * * Checks the codec for any new dapm widgets and creates them if found. * * Returns 0 for success. */ -int snd_soc_dapm_new_widgets(struct snd_soc_codec *codec) +int snd_soc_dapm_new_widgets(struct snd_soc_dapm_context *dapm) { struct snd_soc_dapm_widget *w; - list_for_each_entry(w, &codec->dapm_widgets, list) + list_for_each_entry(w, &dapm->widgets, list) { if (w->new) continue; @@ -1467,12 +1474,12 @@ int snd_soc_dapm_new_widgets(struct snd_soc_codec *codec) case snd_soc_dapm_mixer: case snd_soc_dapm_mixer_named_ctl: w->power_check = dapm_generic_check_power; - dapm_new_mixer(codec, w); + dapm_new_mixer(dapm, w); break; case snd_soc_dapm_mux: case snd_soc_dapm_value_mux: w->power_check = dapm_generic_check_power; - dapm_new_mux(codec, w); + dapm_new_mux(dapm, w); break; case snd_soc_dapm_adc: case snd_soc_dapm_aif_out: @@ -1484,7 +1491,7 @@ int snd_soc_dapm_new_widgets(struct snd_soc_codec *codec) break; case snd_soc_dapm_pga: w->power_check = dapm_generic_check_power; - dapm_new_pga(codec, w); + dapm_new_pga(dapm, w); break; case snd_soc_dapm_input: case snd_soc_dapm_output: @@ -1505,7 +1512,7 @@ int snd_soc_dapm_new_widgets(struct snd_soc_codec *codec) w->new = 1; } - dapm_power_widgets(codec, SND_SOC_DAPM_STREAM_NOP); + dapm_power_widgets(dapm, SND_SOC_DAPM_STREAM_NOP); return 0; } EXPORT_SYMBOL_GPL(snd_soc_dapm_new_widgets); @@ -1889,7 +1896,7 @@ int snd_soc_dapm_get_pin_switch(struct snd_kcontrol *kcontrol, mutex_lock(&codec->mutex); ucontrol->value.integer.value[0] = - snd_soc_dapm_get_pin_status(codec, pin); + snd_soc_dapm_get_pin_status(&codec->dapm, pin); mutex_unlock(&codec->mutex); @@ -1912,11 +1919,11 @@ int snd_soc_dapm_put_pin_switch(struct snd_kcontrol *kcontrol, mutex_lock(&codec->mutex); if (ucontrol->value.integer.value[0]) - snd_soc_dapm_enable_pin(codec, pin); + snd_soc_dapm_enable_pin(&codec->dapm, pin); else - snd_soc_dapm_disable_pin(codec, pin); + snd_soc_dapm_disable_pin(&codec->dapm, pin); - snd_soc_dapm_sync(codec); + snd_soc_dapm_sync(&codec->dapm); mutex_unlock(&codec->mutex); @@ -1926,14 +1933,14 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_put_pin_switch); /** * snd_soc_dapm_new_control - create new dapm control - * @codec: audio codec + * @dapm: DAPM context * @widget: widget template * * Creates a new dapm control based upon the template. * * Returns 0 for success else error. */ -int snd_soc_dapm_new_control(struct snd_soc_codec *codec, +int snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm, const struct snd_soc_dapm_widget *widget) { struct snd_soc_dapm_widget *w; @@ -1941,11 +1948,12 @@ int snd_soc_dapm_new_control(struct snd_soc_codec *codec, if ((w = dapm_cnew_widget(widget)) == NULL) return -ENOMEM; - w->codec = codec; + w->dapm = dapm; + w->codec = dapm->codec; INIT_LIST_HEAD(&w->sources); INIT_LIST_HEAD(&w->sinks); INIT_LIST_HEAD(&w->list); - list_add(&w->list, &codec->dapm_widgets); + list_add(&w->list, &dapm->widgets); /* machine layer set ups unconnected pins and insertions */ w->connected = 1; @@ -1955,7 +1963,7 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_new_control); /** * snd_soc_dapm_new_controls - create new dapm controls - * @codec: audio codec + * @dapm: DAPM context * @widget: widget array * @num: number of widgets * @@ -1963,14 +1971,14 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_new_control); * * Returns 0 for success else error. */ -int snd_soc_dapm_new_controls(struct snd_soc_codec *codec, +int snd_soc_dapm_new_controls(struct snd_soc_dapm_context *dapm, const struct snd_soc_dapm_widget *widget, int num) { int i, ret; for (i = 0; i < num; i++) { - ret = snd_soc_dapm_new_control(codec, widget); + ret = snd_soc_dapm_new_control(dapm, widget); if (ret < 0) { printk(KERN_ERR "ASoC: Failed to create DAPM control %s: %d\n", @@ -1983,29 +1991,12 @@ int snd_soc_dapm_new_controls(struct snd_soc_codec *codec, } EXPORT_SYMBOL_GPL(snd_soc_dapm_new_controls); - -/** - * snd_soc_dapm_stream_event - send a stream event to the dapm core - * @codec: audio codec - * @stream: stream name - * @event: stream event - * - * Sends a stream event to the dapm core. The core then makes any - * necessary widget power changes. - * - * Returns 0 for success else error. - */ -int snd_soc_dapm_stream_event(struct snd_soc_pcm_runtime *rtd, +static void soc_dapm_stream_event(struct snd_soc_dapm_context *dapm, const char *stream, int event) { - struct snd_soc_codec *codec = rtd->codec; struct snd_soc_dapm_widget *w; - if (stream == NULL) - return 0; - - mutex_lock(&codec->mutex); - list_for_each_entry(w, &codec->dapm_widgets, list) + list_for_each_entry(w, &dapm->widgets, list) { if (!w->sname) continue; @@ -2028,7 +2019,30 @@ int snd_soc_dapm_stream_event(struct snd_soc_pcm_runtime *rtd, } } - dapm_power_widgets(codec, event); + dapm_power_widgets(dapm, event); +} + +/** + * snd_soc_dapm_stream_event - send a stream event to the dapm core + * @rtd: PCM runtime data + * @stream: stream name + * @event: stream event + * + * Sends a stream event to the dapm core. The core then makes any + * necessary widget power changes. + * + * Returns 0 for success else error. + */ +int snd_soc_dapm_stream_event(struct snd_soc_pcm_runtime *rtd, + const char *stream, int event) +{ + struct snd_soc_codec *codec = rtd->codec; + + if (stream == NULL) + return 0; + + mutex_lock(&codec->mutex); + soc_dapm_stream_event(&codec->dapm, stream, event); mutex_unlock(&codec->mutex); return 0; } @@ -2036,7 +2050,7 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_stream_event); /** * snd_soc_dapm_enable_pin - enable pin. - * @codec: SoC codec + * @dapm: DAPM context * @pin: pin name * * Enables input/output pin and its parents or children widgets iff there is @@ -2044,15 +2058,15 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_stream_event); * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to * do any widget power switching. */ -int snd_soc_dapm_enable_pin(struct snd_soc_codec *codec, const char *pin) +int snd_soc_dapm_enable_pin(struct snd_soc_dapm_context *dapm, const char *pin) { - return snd_soc_dapm_set_pin(codec, pin, 1); + return snd_soc_dapm_set_pin(dapm, pin, 1); } EXPORT_SYMBOL_GPL(snd_soc_dapm_enable_pin); /** * snd_soc_dapm_force_enable_pin - force a pin to be enabled - * @codec: SoC codec + * @dapm: DAPM context * @pin: pin name * * Enables input/output pin regardless of any other state. This is @@ -2062,42 +2076,45 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_enable_pin); * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to * do any widget power switching. */ -int snd_soc_dapm_force_enable_pin(struct snd_soc_codec *codec, const char *pin) +int snd_soc_dapm_force_enable_pin(struct snd_soc_dapm_context *dapm, + const char *pin) { struct snd_soc_dapm_widget *w; - list_for_each_entry(w, &codec->dapm_widgets, list) { + list_for_each_entry(w, &dapm->widgets, list) { if (!strcmp(w->name, pin)) { - pr_debug("dapm: %s: pin %s\n", codec->name, pin); + pr_debug("dapm: %s: pin %s\n", dapm->codec->name, pin); w->connected = 1; w->force = 1; return 0; } } - pr_err("dapm: %s: configuring unknown pin %s\n", codec->name, pin); + pr_err("dapm: %s: configuring unknown pin %s\n", + dapm->codec->name, pin); return -EINVAL; } EXPORT_SYMBOL_GPL(snd_soc_dapm_force_enable_pin); /** * snd_soc_dapm_disable_pin - disable pin. - * @codec: SoC codec + * @dapm: DAPM context * @pin: pin name * * Disables input/output pin and its parents or children widgets. * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to * do any widget power switching. */ -int snd_soc_dapm_disable_pin(struct snd_soc_codec *codec, const char *pin) +int snd_soc_dapm_disable_pin(struct snd_soc_dapm_context *dapm, + const char *pin) { - return snd_soc_dapm_set_pin(codec, pin, 0); + return snd_soc_dapm_set_pin(dapm, pin, 0); } EXPORT_SYMBOL_GPL(snd_soc_dapm_disable_pin); /** * snd_soc_dapm_nc_pin - permanently disable pin. - * @codec: SoC codec + * @dapm: DAPM context * @pin: pin name * * Marks the specified pin as being not connected, disabling it along @@ -2109,26 +2126,27 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_disable_pin); * NOTE: snd_soc_dapm_sync() needs to be called after this for DAPM to * do any widget power switching. */ -int snd_soc_dapm_nc_pin(struct snd_soc_codec *codec, const char *pin) +int snd_soc_dapm_nc_pin(struct snd_soc_dapm_context *dapm, const char *pin) { - return snd_soc_dapm_set_pin(codec, pin, 0); + return snd_soc_dapm_set_pin(dapm, pin, 0); } EXPORT_SYMBOL_GPL(snd_soc_dapm_nc_pin); /** * snd_soc_dapm_get_pin_status - get audio pin status - * @codec: audio codec + * @dapm: DAPM context * @pin: audio signal pin endpoint (or start point) * * Get audio pin status - connected or disconnected. * * Returns 1 for connected otherwise 0. */ -int snd_soc_dapm_get_pin_status(struct snd_soc_codec *codec, const char *pin) +int snd_soc_dapm_get_pin_status(struct snd_soc_dapm_context *dapm, + const char *pin) { struct snd_soc_dapm_widget *w; - list_for_each_entry(w, &codec->dapm_widgets, list) { + list_for_each_entry(w, &dapm->widgets, list) { if (!strcmp(w->name, pin)) return w->connected; } @@ -2139,7 +2157,7 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_get_pin_status); /** * snd_soc_dapm_ignore_suspend - ignore suspend status for DAPM endpoint - * @codec: audio codec + * @dapm: DAPM context * @pin: audio signal pin endpoint (or start point) * * Mark the given endpoint or pin as ignoring suspend. When the @@ -2148,11 +2166,12 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_get_pin_status); * normal means at suspend time, it will not be turned on if it was not * already enabled. */ -int snd_soc_dapm_ignore_suspend(struct snd_soc_codec *codec, const char *pin) +int snd_soc_dapm_ignore_suspend(struct snd_soc_dapm_context *dapm, + const char *pin) { struct snd_soc_dapm_widget *w; - list_for_each_entry(w, &codec->dapm_widgets, list) { + list_for_each_entry(w, &dapm->widgets, list) { if (!strcmp(w->name, pin)) { w->ignore_suspend = 1; return 0; @@ -2170,20 +2189,20 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_ignore_suspend); * * Free all dapm widgets and resources. */ -void snd_soc_dapm_free(struct snd_soc_codec *codec) +void snd_soc_dapm_free(struct snd_soc_dapm_context *dapm) { - snd_soc_dapm_sys_remove(codec->dev); - dapm_free_widgets(codec); + snd_soc_dapm_sys_remove(dapm->dev); + dapm_free_widgets(dapm); } EXPORT_SYMBOL_GPL(snd_soc_dapm_free); -static void soc_dapm_shutdown_codec(struct snd_soc_codec *codec) +static void soc_dapm_shutdown_codec(struct snd_soc_dapm_context *dapm) { struct snd_soc_dapm_widget *w; LIST_HEAD(down_list); int powerdown = 0; - list_for_each_entry(w, &codec->dapm_widgets, list) { + list_for_each_entry(w, &dapm->widgets, list) { if (w->power) { dapm_seq_insert(w, &down_list, dapm_down_seq); w->power = 0; @@ -2195,9 +2214,9 @@ static void soc_dapm_shutdown_codec(struct snd_soc_codec *codec) * standby. */ if (powerdown) { - snd_soc_dapm_set_bias_level(NULL, codec, SND_SOC_BIAS_PREPARE); - dapm_seq_run(codec, &down_list, 0, dapm_down_seq); - snd_soc_dapm_set_bias_level(NULL, codec, SND_SOC_BIAS_STANDBY); + snd_soc_dapm_set_bias_level(NULL, dapm, SND_SOC_BIAS_PREPARE); + dapm_seq_run(dapm, &down_list, 0, dapm_down_seq); + snd_soc_dapm_set_bias_level(NULL, dapm, SND_SOC_BIAS_STANDBY); } } @@ -2208,10 +2227,10 @@ void snd_soc_dapm_shutdown(struct snd_soc_card *card) { struct snd_soc_codec *codec; - list_for_each_entry(codec, &card->codec_dev_list, list) - soc_dapm_shutdown_codec(codec); - - snd_soc_dapm_set_bias_level(card, codec, SND_SOC_BIAS_OFF); + list_for_each_entry(codec, &card->codec_dev_list, list) { + soc_dapm_shutdown_codec(&codec->dapm); + snd_soc_dapm_set_bias_level(card, &codec->dapm, SND_SOC_BIAS_OFF); + } } /* Module information */ diff --git a/sound/soc/soc-jack.c b/sound/soc/soc-jack.c index 9f07551e155f..4d95abb40288 100644 --- a/sound/soc/soc-jack.c +++ b/sound/soc/soc-jack.c @@ -60,6 +60,7 @@ EXPORT_SYMBOL_GPL(snd_soc_jack_new); void snd_soc_jack_report(struct snd_soc_jack *jack, int status, int mask) { struct snd_soc_codec *codec; + struct snd_soc_dapm_context *dapm; struct snd_soc_jack_pin *pin; int enable; int oldstatus; @@ -68,6 +69,7 @@ void snd_soc_jack_report(struct snd_soc_jack *jack, int status, int mask) return; codec = jack->codec; + dapm = &codec->dapm; mutex_lock(&codec->mutex); @@ -88,15 +90,15 @@ void snd_soc_jack_report(struct snd_soc_jack *jack, int status, int mask) enable = !enable; if (enable) - snd_soc_dapm_enable_pin(codec, pin->pin); + snd_soc_dapm_enable_pin(dapm, pin->pin); else - snd_soc_dapm_disable_pin(codec, pin->pin); + snd_soc_dapm_disable_pin(dapm, pin->pin); } /* Report before the DAPM sync to help users updating micbias status */ blocking_notifier_call_chain(&jack->notifier, status, NULL); - snd_soc_dapm_sync(codec); + snd_soc_dapm_sync(dapm); snd_jack_report(jack->jack, status); -- cgit v1.2.3 From a6052154944c822993d04ca8f8d8926e8b73b749 Mon Sep 17 00:00:00 2001 From: Jarkko Nikula Date: Fri, 5 Nov 2010 20:35:19 +0200 Subject: ASoC: Add sound card directory under debugfs/asoc/ There will be need to have sound card specific debugfs entries. This patch introduces a new debugfs/asoc/{card->name}/ directory but does not add yet any entries there. Signed-off-by: Jarkko Nikula Signed-off-by: Mark Brown --- include/sound/soc.h | 4 ++++ sound/soc/soc-core.c | 18 ++++++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/include/sound/soc.h b/include/sound/soc.h index b048e08e2cc7..95ce0ddd36d4 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -589,6 +589,10 @@ struct snd_soc_card { struct list_head codec_dev_list; struct list_head platform_dev_list; struct list_head dai_dev_list; + +#ifdef CONFIG_DEBUG_FS + struct dentry *debugfs_card_root; +#endif }; /* SoC machine DAI configuration, glues a codec and cpu DAI together */ diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 3c7c884f212c..b0f635ccf176 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -374,6 +374,20 @@ static const struct file_operations platform_list_fops = { .llseek = default_llseek,/* read accesses f_pos */ }; +static void soc_init_card_debugfs(struct snd_soc_card *card) +{ + card->debugfs_card_root = debugfs_create_dir(card->name, + debugfs_root); + if (!card->debugfs_card_root) + dev_warn(card->dev, + "ASoC: Failed to create codec debugfs directory\n"); +} + +static void soc_cleanup_card_debugfs(struct snd_soc_card *card) +{ + debugfs_remove_recursive(card->debugfs_card_root); +} + #else static inline void soc_init_codec_debugfs(struct snd_soc_codec *codec) @@ -1667,6 +1681,8 @@ static int soc_probe(struct platform_device *pdev) INIT_LIST_HEAD(&card->codec_dev_list); INIT_LIST_HEAD(&card->platform_dev_list); + soc_init_card_debugfs(card); + ret = snd_soc_register_card(card); if (ret != 0) { dev_err(&pdev->dev, "Failed to register card\n"); @@ -1694,6 +1710,8 @@ static int soc_remove(struct platform_device *pdev) for (i = 0; i < card->num_rtd; i++) soc_remove_dai_link(card, i); + soc_cleanup_card_debugfs(card); + /* remove the card */ if (card->remove) card->remove(pdev); -- cgit v1.2.3 From d6ce4cf3967dca78f967cd0bf70b175084885f40 Mon Sep 17 00:00:00 2001 From: Jarkko Nikula Date: Fri, 5 Nov 2010 20:35:20 +0200 Subject: ASoC: Move codec debugfs directories under parent card directory Make use of sound card debugfs directory and move codec directories under the parent card debugfs directory. debugfs/asoc/{codec dir} -> debugfs/asoc/{card->name}/{codec dir}. Signed-off-by: Jarkko Nikula Signed-off-by: Mark Brown --- sound/soc/soc-core.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index b0f635ccf176..57e5d7bfb130 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -238,8 +238,10 @@ static const struct file_operations codec_reg_fops = { static void soc_init_codec_debugfs(struct snd_soc_codec *codec) { - codec->debugfs_codec_root = debugfs_create_dir(codec->name , - debugfs_root); + struct dentry *debugfs_card_root = codec->card->debugfs_card_root; + + codec->debugfs_codec_root = debugfs_create_dir(codec->name, + debugfs_card_root); if (!codec->debugfs_codec_root) { printk(KERN_WARNING "ASoC: Failed to create codec debugfs directory\n"); -- cgit v1.2.3 From 3a45b8672d3f8542e430e7a5c7366ec9bdded054 Mon Sep 17 00:00:00 2001 From: Jarkko Nikula Date: Fri, 5 Nov 2010 20:35:21 +0200 Subject: ASoC: Move pop time from DAPM context to sound card Based on discussion the dapm_pop_time in debugsfs should be per card rather than per device. Single pop time value for entire card is cleaner when the DAPM sequencing is extended to cross-device paths. debugfs/asoc/{card->name}/{codec dir}/dapm_pop_time -> debugfs/asoc/{card->name}/dapm_pop_time Signed-off-by: Jarkko Nikula Signed-off-by: Mark Brown --- include/sound/soc-dapm.h | 2 +- include/sound/soc.h | 3 ++- sound/soc/codecs/cx20442.c | 6 +++--- sound/soc/soc-core.c | 19 +++++++++++-------- sound/soc/soc-dapm.c | 30 ++++++++++++++++-------------- 5 files changed, 33 insertions(+), 27 deletions(-) diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h index 5881876e8f5b..78d3560fa25a 100644 --- a/include/sound/soc-dapm.h +++ b/include/sound/soc-dapm.h @@ -469,7 +469,6 @@ struct snd_soc_dapm_widget { /* DAPM context */ struct snd_soc_dapm_context { - u32 pop_time; struct list_head widgets; struct list_head paths; enum snd_soc_bias_level bias_level; @@ -479,6 +478,7 @@ struct snd_soc_dapm_context { struct device *dev; /* from parent - for debug */ struct snd_soc_codec *codec; /* parent codec */ + struct snd_soc_card *card; /* parent card */ #ifdef CONFIG_DEBUG_FS struct dentry *debugfs_dapm; #endif diff --git a/include/sound/soc.h b/include/sound/soc.h index 95ce0ddd36d4..5d3954774ade 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -457,7 +457,6 @@ struct snd_soc_codec { #ifdef CONFIG_DEBUG_FS struct dentry *debugfs_codec_root; struct dentry *debugfs_reg; - struct dentry *debugfs_pop_time; struct dentry *debugfs_dapm; #endif }; @@ -592,7 +591,9 @@ struct snd_soc_card { #ifdef CONFIG_DEBUG_FS struct dentry *debugfs_card_root; + struct dentry *debugfs_pop_time; #endif + u32 pop_time; }; /* SoC machine DAI configuration, glues a codec and cpu DAI together */ diff --git a/sound/soc/codecs/cx20442.c b/sound/soc/codecs/cx20442.c index 11beb1a77c4e..a9521acad99c 100644 --- a/sound/soc/codecs/cx20442.c +++ b/sound/soc/codecs/cx20442.c @@ -264,7 +264,7 @@ static void v253_close(struct tty_struct *tty) /* Prevent the codec driver from further accessing the modem */ codec->hw_write = NULL; cx20442->control_data = NULL; - codec->dapm.pop_time = 0; + codec->card->pop_time = 0; } /* Line discipline .hangup() */ @@ -292,7 +292,7 @@ static void v253_receive(struct tty_struct *tty, /* Set up codec driver access to modem controls */ cx20442->control_data = tty; codec->hw_write = (hw_write_t)tty->ops->write; - codec->dapm.pop_time = 1; + codec->card->pop_time = 1; } } @@ -349,7 +349,7 @@ static int cx20442_codec_probe(struct snd_soc_codec *codec) cx20442->control_data = NULL; codec->hw_write = NULL; - codec->dapm.pop_time = 0; + codec->card->pop_time = 0; return 0; } diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 57e5d7bfb130..f030521c48d1 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -255,13 +255,6 @@ static void soc_init_codec_debugfs(struct snd_soc_codec *codec) printk(KERN_WARNING "ASoC: Failed to create codec register debugfs file\n"); - codec->debugfs_pop_time = debugfs_create_u32("dapm_pop_time", 0644, - codec->debugfs_codec_root, - &codec->dapm.pop_time); - if (!codec->debugfs_pop_time) - printk(KERN_WARNING - "Failed to create pop time debugfs file\n"); - codec->dapm.debugfs_dapm = debugfs_create_dir("dapm", codec->debugfs_codec_root); if (!codec->dapm.debugfs_dapm) @@ -380,9 +373,18 @@ static void soc_init_card_debugfs(struct snd_soc_card *card) { card->debugfs_card_root = debugfs_create_dir(card->name, debugfs_root); - if (!card->debugfs_card_root) + if (!card->debugfs_card_root) { dev_warn(card->dev, "ASoC: Failed to create codec debugfs directory\n"); + return; + } + + card->debugfs_pop_time = debugfs_create_u32("dapm_pop_time", 0644, + card->debugfs_card_root, + &card->pop_time); + if (!card->debugfs_pop_time) + dev_warn(card->dev, + "Failed to create pop time debugfs file\n"); } static void soc_cleanup_card_debugfs(struct snd_soc_card *card) @@ -1426,6 +1428,7 @@ static int soc_probe_dai_link(struct snd_soc_card *card, int num) /* probe the CODEC */ if (!codec->probed) { + codec->dapm.card = card; if (codec->driver->probe) { ret = codec->driver->probe(codec); if (ret < 0) { diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index b8f653eaffaa..960790cc6fbc 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -293,6 +293,7 @@ static int dapm_update_bits(struct snd_soc_dapm_widget *widget) unsigned int old, new; struct snd_soc_codec *codec = widget->codec; struct snd_soc_dapm_context *dapm = widget->dapm; + struct snd_soc_card *card = dapm->card; /* check for valid widgets */ if (widget->reg < 0 || widget->id == snd_soc_dapm_input || @@ -312,10 +313,10 @@ static int dapm_update_bits(struct snd_soc_dapm_widget *widget) change = old != new; if (change) { - pop_dbg(dapm->pop_time, "pop test %s : %s in %d ms\n", + pop_dbg(card->pop_time, "pop test %s : %s in %d ms\n", widget->name, widget->power ? "on" : "off", - dapm->pop_time); - pop_wait(dapm->pop_time); + card->pop_time); + pop_wait(card->pop_time); snd_soc_write(codec, widget->reg, new); } pr_debug("reg %x old %x new %x change %d\n", widget->reg, @@ -720,6 +721,7 @@ static void dapm_seq_run_coalesced(struct snd_soc_dapm_context *dapm, struct list_head *pending) { struct snd_soc_dapm_widget *w; + struct snd_soc_card *card = dapm->card; int reg, power, ret; unsigned int value = 0; unsigned int mask = 0; @@ -741,14 +743,14 @@ static void dapm_seq_run_coalesced(struct snd_soc_dapm_context *dapm, if (power) value |= cur_mask; - pop_dbg(dapm->pop_time, + pop_dbg(card->pop_time, "pop test : Queue %s: reg=0x%x, 0x%x/0x%x\n", w->name, reg, value, mask); /* power up pre event */ if (w->power && w->event && (w->event_flags & SND_SOC_DAPM_PRE_PMU)) { - pop_dbg(dapm->pop_time, "pop test : %s PRE_PMU\n", + pop_dbg(card->pop_time, "pop test : %s PRE_PMU\n", w->name); ret = w->event(w, NULL, SND_SOC_DAPM_PRE_PMU); if (ret < 0) @@ -759,7 +761,7 @@ static void dapm_seq_run_coalesced(struct snd_soc_dapm_context *dapm, /* power down pre event */ if (!w->power && w->event && (w->event_flags & SND_SOC_DAPM_PRE_PMD)) { - pop_dbg(dapm->pop_time, "pop test : %s PRE_PMD\n", + pop_dbg(card->pop_time, "pop test : %s PRE_PMD\n", w->name); ret = w->event(w, NULL, SND_SOC_DAPM_PRE_PMD); if (ret < 0) @@ -769,10 +771,10 @@ static void dapm_seq_run_coalesced(struct snd_soc_dapm_context *dapm, } if (reg >= 0) { - pop_dbg(dapm->pop_time, + pop_dbg(card->pop_time, "pop test : Applying 0x%x/0x%x to %x in %dms\n", - value, mask, reg, dapm->pop_time); - pop_wait(dapm->pop_time); + value, mask, reg, card->pop_time); + pop_wait(card->pop_time); snd_soc_update_bits(dapm->codec, reg, mask, value); } @@ -780,7 +782,7 @@ static void dapm_seq_run_coalesced(struct snd_soc_dapm_context *dapm, /* power up post event */ if (w->power && w->event && (w->event_flags & SND_SOC_DAPM_POST_PMU)) { - pop_dbg(dapm->pop_time, "pop test : %s POST_PMU\n", + pop_dbg(card->pop_time, "pop test : %s POST_PMU\n", w->name); ret = w->event(w, NULL, SND_SOC_DAPM_POST_PMU); @@ -792,7 +794,7 @@ static void dapm_seq_run_coalesced(struct snd_soc_dapm_context *dapm, /* power down post event */ if (!w->power && w->event && (w->event_flags & SND_SOC_DAPM_POST_PMD)) { - pop_dbg(dapm->pop_time, "pop test : %s POST_PMD\n", + pop_dbg(card->pop_time, "pop test : %s POST_PMD\n", w->name); ret = w->event(w, NULL, SND_SOC_DAPM_POST_PMD); if (ret < 0) @@ -1012,9 +1014,9 @@ static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event) pr_err("Failed to apply active bias: %d\n", ret); } - pop_dbg(dapm->pop_time, "DAPM sequencing finished, waiting %dms\n", - dapm->pop_time); - pop_wait(dapm->pop_time); + pop_dbg(card->pop_time, "DAPM sequencing finished, waiting %dms\n", + card->pop_time); + pop_wait(card->pop_time); return 0; } -- cgit v1.2.3 From c046fd4dd613b22b35379665a8f7656d17bde0b3 Mon Sep 17 00:00:00 2001 From: Dimitris Papastamos Date: Fri, 5 Nov 2010 18:41:25 +0000 Subject: ASoC: WM8770: Initial driver The WM8770 is a high performance, multi-channel audio codec. The WM8770 is ideal for surround sound processing applications for home hi-fi, automotive and other audio visual equipment. Signed-off-by: Dimitris Papastamos Signed-off-by: Mark Brown --- sound/soc/codecs/Kconfig | 4 + sound/soc/codecs/Makefile | 2 + sound/soc/codecs/wm8770.c | 750 ++++++++++++++++++++++++++++++++++++++++++++++ sound/soc/codecs/wm8770.h | 51 ++++ 4 files changed, 807 insertions(+) create mode 100644 sound/soc/codecs/wm8770.c create mode 100644 sound/soc/codecs/wm8770.h diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index e61fbab48aa2..6ebd3a685b2c 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -58,6 +58,7 @@ config SND_SOC_ALL_CODECS select SND_SOC_WM8741 if SND_SOC_I2C_AND_SPI select SND_SOC_WM8750 if SND_SOC_I2C_AND_SPI select SND_SOC_WM8753 if SND_SOC_I2C_AND_SPI + select SND_SOC_WM8770 if SPI_MASTER select SND_SOC_WM8776 if SND_SOC_I2C_AND_SPI select SND_SOC_WM8804 if SND_SOC_I2C_AND_SPI select SND_SOC_WM8900 if I2C @@ -244,6 +245,9 @@ config SND_SOC_WM8750 config SND_SOC_WM8753 tristate +config SND_SOC_WM8770 + tristate + config SND_SOC_WM8776 tristate diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index 0dcaed3e73f3..42f185d233f3 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile @@ -42,6 +42,7 @@ snd-soc-wm8731-objs := wm8731.o snd-soc-wm8741-objs := wm8741.o snd-soc-wm8750-objs := wm8750.o snd-soc-wm8753-objs := wm8753.o +snd-soc-wm8770-objs := wm8770.o snd-soc-wm8776-objs := wm8776.o snd-soc-wm8804-objs := wm8804.o snd-soc-wm8900-objs := wm8900.o @@ -118,6 +119,7 @@ obj-$(CONFIG_SND_SOC_WM8731) += snd-soc-wm8731.o obj-$(CONFIG_SND_SOC_WM8741) += snd-soc-wm8741.o obj-$(CONFIG_SND_SOC_WM8750) += snd-soc-wm8750.o obj-$(CONFIG_SND_SOC_WM8753) += snd-soc-wm8753.o +obj-$(CONFIG_SND_SOC_WM8770) += snd-soc-wm8770.o obj-$(CONFIG_SND_SOC_WM8776) += snd-soc-wm8776.o obj-$(CONFIG_SND_SOC_WM8804) += snd-soc-wm8804.o obj-$(CONFIG_SND_SOC_WM8900) += snd-soc-wm8900.o diff --git a/sound/soc/codecs/wm8770.c b/sound/soc/codecs/wm8770.c new file mode 100644 index 000000000000..8608b4a10b0a --- /dev/null +++ b/sound/soc/codecs/wm8770.c @@ -0,0 +1,750 @@ +/* + * wm8770.c -- WM8770 ALSA SoC Audio driver + * + * Copyright 2010 Wolfson Microelectronics plc + * + * Author: Dimitris Papastamos + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "wm8770.h" + +#define WM8770_NUM_SUPPLIES 3 +static const char *wm8770_supply_names[WM8770_NUM_SUPPLIES] = { + "AVDD1", + "AVDD2", + "DVDD" +}; + +static const u16 wm8770_reg_defs[WM8770_CACHEREGNUM] = { + 0x7f, 0x7f, 0x7f, 0x7f, + 0x7f, 0x7f, 0x7f, 0x7f, + 0x7f, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0, 0x90, 0, + 0, 0x22, 0x22, 0x3e, + 0xc, 0xc, 0x100, 0x189, + 0x189, 0x8770 +}; + +struct wm8770_priv { + enum snd_soc_control_type control_type; + struct regulator_bulk_data supplies[WM8770_NUM_SUPPLIES]; + struct notifier_block disable_nb[WM8770_NUM_SUPPLIES]; + struct snd_soc_codec *codec; + int sysclk; +}; + +static int vout12supply_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event); +static int vout34supply_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event); + +/* + * We can't use the same notifier block for more than one supply and + * there's no way I can see to get from a callback to the caller + * except container_of(). + */ +#define WM8770_REGULATOR_EVENT(n) \ +static int wm8770_regulator_event_##n(struct notifier_block *nb, \ + unsigned long event, void *data) \ +{ \ + struct wm8770_priv *wm8770 = container_of(nb, struct wm8770_priv, \ + disable_nb[n]); \ + if (event & REGULATOR_EVENT_DISABLE) { \ + wm8770->codec->cache_sync = 1; \ + } \ + return 0; \ +} + +WM8770_REGULATOR_EVENT(0) +WM8770_REGULATOR_EVENT(1) +WM8770_REGULATOR_EVENT(2) + +static const DECLARE_TLV_DB_SCALE(adc_tlv, -1200, 100, 0); +static const DECLARE_TLV_DB_SCALE(dac_dig_tlv, -12750, 50, 1); +static const DECLARE_TLV_DB_SCALE(dac_alg_tlv, -12700, 100, 1); + +static const char *dac_phase_text[][2] = { + { "DAC1 Normal", "DAC1 Inverted" }, + { "DAC2 Normal", "DAC2 Inverted" }, + { "DAC3 Normal", "DAC3 Inverted" }, + { "DAC4 Normal", "DAC4 Inverted" }, +}; + +static const struct soc_enum dac_phase[] = { + SOC_ENUM_DOUBLE(WM8770_DACPHASE, 0, 1, 2, dac_phase_text[0]), + SOC_ENUM_DOUBLE(WM8770_DACPHASE, 2, 3, 2, dac_phase_text[1]), + SOC_ENUM_DOUBLE(WM8770_DACPHASE, 4, 5, 2, dac_phase_text[2]), + SOC_ENUM_DOUBLE(WM8770_DACPHASE, 6, 7, 2, dac_phase_text[3]), +}; + +static const struct snd_kcontrol_new wm8770_snd_controls[] = { + /* global DAC playback controls */ + SOC_SINGLE_TLV("DAC Playback Volume", WM8770_MSDIGVOL, 0, 255, 0, + dac_dig_tlv), + SOC_SINGLE("DAC Playback Switch", WM8770_DACMUTE, 4, 1, 1), + SOC_SINGLE("DAC Playback ZC Switch", WM8770_DACCTRL1, 0, 1, 0), + + /* global VOUT playback controls */ + SOC_SINGLE_TLV("VOUT Playback Volume", WM8770_MSALGVOL, 0, 127, 0, + dac_alg_tlv), + SOC_SINGLE("VOUT Playback ZC Switch", WM8770_MSALGVOL, 7, 1, 0), + + /* VOUT1/2/3/4 specific controls */ + SOC_DOUBLE_R_TLV("VOUT1 Playback Volume", WM8770_VOUT1LVOL, + WM8770_VOUT1RVOL, 0, 127, 0, dac_alg_tlv), + SOC_DOUBLE_R("VOUT1 Playback ZC Switch", WM8770_VOUT1LVOL, + WM8770_VOUT1RVOL, 7, 1, 0), + SOC_DOUBLE_R_TLV("VOUT2 Playback Volume", WM8770_VOUT2LVOL, + WM8770_VOUT2RVOL, 0, 127, 0, dac_alg_tlv), + SOC_DOUBLE_R("VOUT2 Playback ZC Switch", WM8770_VOUT2LVOL, + WM8770_VOUT2RVOL, 7, 1, 0), + SOC_DOUBLE_R_TLV("VOUT3 Playback Volume", WM8770_VOUT3LVOL, + WM8770_VOUT3RVOL, 0, 127, 0, dac_alg_tlv), + SOC_DOUBLE_R("VOUT3 Playback ZC Switch", WM8770_VOUT3LVOL, + WM8770_VOUT3RVOL, 7, 1, 0), + SOC_DOUBLE_R_TLV("VOUT4 Playback Volume", WM8770_VOUT4LVOL, + WM8770_VOUT4RVOL, 0, 127, 0, dac_alg_tlv), + SOC_DOUBLE_R("VOUT4 Playback ZC Switch", WM8770_VOUT4LVOL, + WM8770_VOUT4RVOL, 7, 1, 0), + + /* DAC1/2/3/4 specific controls */ + SOC_DOUBLE_R_TLV("DAC1 Playback Volume", WM8770_DAC1LVOL, + WM8770_DAC1RVOL, 0, 255, 0, dac_dig_tlv), + SOC_SINGLE("DAC1 Deemphasis Switch", WM8770_DACCTRL2, 0, 1, 0), + SOC_ENUM("DAC1 Phase", dac_phase[0]), + SOC_DOUBLE_R_TLV("DAC2 Playback Volume", WM8770_DAC2LVOL, + WM8770_DAC2RVOL, 0, 255, 0, dac_dig_tlv), + SOC_SINGLE("DAC2 Deemphasis Switch", WM8770_DACCTRL2, 1, 1, 0), + SOC_ENUM("DAC2 Phase", dac_phase[1]), + SOC_DOUBLE_R_TLV("DAC3 Playback Volume", WM8770_DAC3LVOL, + WM8770_DAC3RVOL, 0, 255, 0, dac_dig_tlv), + SOC_SINGLE("DAC3 Deemphasis Switch", WM8770_DACCTRL2, 2, 1, 0), + SOC_ENUM("DAC3 Phase", dac_phase[2]), + SOC_DOUBLE_R_TLV("DAC4 Playback Volume", WM8770_DAC4LVOL, + WM8770_DAC4RVOL, 0, 255, 0, dac_dig_tlv), + SOC_SINGLE("DAC4 Deemphasis Switch", WM8770_DACCTRL2, 3, 1, 0), + SOC_ENUM("DAC4 Phase", dac_phase[3]), + + /* ADC specific controls */ + SOC_DOUBLE_R_TLV("Capture Volume", WM8770_ADCLCTRL, WM8770_ADCRCTRL, + 0, 31, 0, adc_tlv), + SOC_DOUBLE_R("Capture Switch", WM8770_ADCLCTRL, WM8770_ADCRCTRL, + 5, 1, 1), + + /* other controls */ + SOC_SINGLE("ADC 128x Oversampling Switch", WM8770_MSTRCTRL, 3, 1, 0), + SOC_SINGLE("ADC Highpass Filter Switch", WM8770_IFACECTRL, 8, 1, 1) +}; + +static const char *ain_text[] = { + "AIN1", "AIN2", "AIN3", "AIN4", + "AIN5", "AIN6", "AIN7", "AIN8" +}; + +static const struct soc_enum ain_enum = + SOC_ENUM_DOUBLE(WM8770_ADCMUX, 0, 4, 8, ain_text); + +static const struct snd_kcontrol_new ain_mux = + SOC_DAPM_ENUM("Capture Mux", ain_enum); + +static const struct snd_kcontrol_new vout1_mix_controls[] = { + SOC_DAPM_SINGLE("DAC1 Switch", WM8770_OUTMUX1, 0, 1, 0), + SOC_DAPM_SINGLE("AUX1 Switch", WM8770_OUTMUX1, 1, 1, 0), + SOC_DAPM_SINGLE("Bypass Switch", WM8770_OUTMUX1, 2, 1, 0) +}; + +static const struct snd_kcontrol_new vout2_mix_controls[] = { + SOC_DAPM_SINGLE("DAC2 Switch", WM8770_OUTMUX1, 3, 1, 0), + SOC_DAPM_SINGLE("AUX2 Switch", WM8770_OUTMUX1, 4, 1, 0), + SOC_DAPM_SINGLE("Bypass Switch", WM8770_OUTMUX1, 5, 1, 0) +}; + +static const struct snd_kcontrol_new vout3_mix_controls[] = { + SOC_DAPM_SINGLE("DAC3 Switch", WM8770_OUTMUX2, 0, 1, 0), + SOC_DAPM_SINGLE("AUX3 Switch", WM8770_OUTMUX2, 1, 1, 0), + SOC_DAPM_SINGLE("Bypass Switch", WM8770_OUTMUX2, 2, 1, 0) +}; + +static const struct snd_kcontrol_new vout4_mix_controls[] = { + SOC_DAPM_SINGLE("DAC4 Switch", WM8770_OUTMUX2, 3, 1, 0), + SOC_DAPM_SINGLE("Bypass Switch", WM8770_OUTMUX2, 4, 1, 0) +}; + +static const struct snd_soc_dapm_widget wm8770_dapm_widgets[] = { + SND_SOC_DAPM_INPUT("AUX1"), + SND_SOC_DAPM_INPUT("AUX2"), + SND_SOC_DAPM_INPUT("AUX3"), + + SND_SOC_DAPM_INPUT("AIN1"), + SND_SOC_DAPM_INPUT("AIN2"), + SND_SOC_DAPM_INPUT("AIN3"), + SND_SOC_DAPM_INPUT("AIN4"), + SND_SOC_DAPM_INPUT("AIN5"), + SND_SOC_DAPM_INPUT("AIN6"), + SND_SOC_DAPM_INPUT("AIN7"), + SND_SOC_DAPM_INPUT("AIN8"), + + SND_SOC_DAPM_MUX("Capture Mux", WM8770_ADCMUX, 8, 1, &ain_mux), + + SND_SOC_DAPM_ADC("ADC", "Capture", WM8770_PWDNCTRL, 1, 1), + + SND_SOC_DAPM_DAC("DAC1", "Playback", WM8770_PWDNCTRL, 2, 1), + SND_SOC_DAPM_DAC("DAC2", "Playback", WM8770_PWDNCTRL, 3, 1), + SND_SOC_DAPM_DAC("DAC3", "Playback", WM8770_PWDNCTRL, 4, 1), + SND_SOC_DAPM_DAC("DAC4", "Playback", WM8770_PWDNCTRL, 5, 1), + + SND_SOC_DAPM_SUPPLY("VOUT12 Supply", SND_SOC_NOPM, 0, 0, + vout12supply_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_SUPPLY("VOUT34 Supply", SND_SOC_NOPM, 0, 0, + vout34supply_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD), + + SND_SOC_DAPM_MIXER("VOUT1 Mixer", SND_SOC_NOPM, 0, 0, + vout1_mix_controls, ARRAY_SIZE(vout1_mix_controls)), + SND_SOC_DAPM_MIXER("VOUT2 Mixer", SND_SOC_NOPM, 0, 0, + vout2_mix_controls, ARRAY_SIZE(vout2_mix_controls)), + SND_SOC_DAPM_MIXER("VOUT3 Mixer", SND_SOC_NOPM, 0, 0, + vout3_mix_controls, ARRAY_SIZE(vout3_mix_controls)), + SND_SOC_DAPM_MIXER("VOUT4 Mixer", SND_SOC_NOPM, 0, 0, + vout4_mix_controls, ARRAY_SIZE(vout4_mix_controls)), + + SND_SOC_DAPM_OUTPUT("VOUT1"), + SND_SOC_DAPM_OUTPUT("VOUT2"), + SND_SOC_DAPM_OUTPUT("VOUT3"), + SND_SOC_DAPM_OUTPUT("VOUT4") +}; + +static const struct snd_soc_dapm_route wm8770_intercon[] = { + { "Capture Mux", "AIN1", "AIN1" }, + { "Capture Mux", "AIN2", "AIN2" }, + { "Capture Mux", "AIN3", "AIN3" }, + { "Capture Mux", "AIN4", "AIN4" }, + { "Capture Mux", "AIN5", "AIN5" }, + { "Capture Mux", "AIN6", "AIN6" }, + { "Capture Mux", "AIN7", "AIN7" }, + { "Capture Mux", "AIN8", "AIN8" }, + + { "ADC", NULL, "Capture Mux" }, + + { "VOUT1 Mixer", NULL, "VOUT12 Supply" }, + { "VOUT1 Mixer", "DAC1 Switch", "DAC1" }, + { "VOUT1 Mixer", "AUX1 Switch", "AUX1" }, + { "VOUT1 Mixer", "Bypass Switch", "Capture Mux" }, + + { "VOUT2 Mixer", NULL, "VOUT12 Supply" }, + { "VOUT2 Mixer", "DAC2 Switch", "DAC2" }, + { "VOUT2 Mixer", "AUX2 Switch", "AUX2" }, + { "VOUT2 Mixer", "Bypass Switch", "Capture Mux" }, + + { "VOUT3 Mixer", NULL, "VOUT34 Supply" }, + { "VOUT3 Mixer", "DAC3 Switch", "DAC3" }, + { "VOUT3 Mixer", "AUX3 Switch", "AUX3" }, + { "VOUT3 Mixer", "Bypass Switch", "Capture Mux" }, + + { "VOUT4 Mixer", NULL, "VOUT34 Supply" }, + { "VOUT4 Mixer", "DAC4 Switch", "DAC4" }, + { "VOUT4 Mixer", "Bypass Switch", "Capture Mux" }, + + { "VOUT1", NULL, "VOUT1 Mixer" }, + { "VOUT2", NULL, "VOUT2 Mixer" }, + { "VOUT3", NULL, "VOUT3 Mixer" }, + { "VOUT4", NULL, "VOUT4 Mixer" } +}; + +static int vout12supply_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec; + + codec = w->codec; + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + snd_soc_update_bits(codec, WM8770_OUTMUX1, 0x180, 0); + break; + case SND_SOC_DAPM_POST_PMD: + snd_soc_update_bits(codec, WM8770_OUTMUX1, 0x180, 0x180); + break; + } + + return 0; +} + +static int vout34supply_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec; + + codec = w->codec; + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + snd_soc_update_bits(codec, WM8770_OUTMUX2, 0x180, 0); + break; + case SND_SOC_DAPM_POST_PMD: + snd_soc_update_bits(codec, WM8770_OUTMUX2, 0x180, 0x180); + break; + } + + return 0; +} + +static int wm8770_reset(struct snd_soc_codec *codec) +{ + return snd_soc_write(codec, WM8770_RESET, 0); +} + +static int wm8770_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) +{ + struct snd_soc_codec *codec; + int iface, master; + + codec = dai->codec; + + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { + case SND_SOC_DAIFMT_CBM_CFM: + master = 0x100; + break; + case SND_SOC_DAIFMT_CBS_CFS: + master = 0; + break; + default: + return -EINVAL; + } + + iface = 0; + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { + case SND_SOC_DAIFMT_I2S: + iface |= 0x2; + break; + case SND_SOC_DAIFMT_RIGHT_J: + break; + case SND_SOC_DAIFMT_LEFT_J: + iface |= 0x1; + break; + default: + return -EINVAL; + } + + switch (fmt & SND_SOC_DAIFMT_INV_MASK) { + case SND_SOC_DAIFMT_NB_NF: + break; + case SND_SOC_DAIFMT_IB_IF: + iface |= 0xc; + break; + case SND_SOC_DAIFMT_IB_NF: + iface |= 0x8; + break; + case SND_SOC_DAIFMT_NB_IF: + iface |= 0x4; + break; + default: + return -EINVAL; + } + + snd_soc_update_bits(codec, WM8770_IFACECTRL, 0xf, iface); + snd_soc_update_bits(codec, WM8770_MSTRCTRL, 0x100, master); + + return 0; +} + +static const int mclk_ratios[] = { + 128, + 192, + 256, + 384, + 512, + 768 +}; + +static int wm8770_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct snd_soc_codec *codec; + struct wm8770_priv *wm8770; + int i; + int iface; + int shift; + int ratio; + + codec = dai->codec; + wm8770 = snd_soc_codec_get_drvdata(codec); + + iface = 0; + switch (params_format(params)) { + case SNDRV_PCM_FORMAT_S16_LE: + break; + case SNDRV_PCM_FORMAT_S20_3LE: + iface |= 0x10; + break; + case SNDRV_PCM_FORMAT_S24_LE: + iface |= 0x20; + break; + case SNDRV_PCM_FORMAT_S32_LE: + iface |= 0x30; + break; + } + + switch (substream->stream) { + case SNDRV_PCM_STREAM_PLAYBACK: + i = 0; + shift = 4; + break; + case SNDRV_PCM_STREAM_CAPTURE: + i = 2; + shift = 0; + break; + default: + return -EINVAL; + } + + /* Only need to set MCLK/LRCLK ratio if we're master */ + if (snd_soc_read(codec, WM8770_MSTRCTRL) & 0x100) { + for (; i < ARRAY_SIZE(mclk_ratios); ++i) { + ratio = wm8770->sysclk / params_rate(params); + if (ratio == mclk_ratios[i]) + break; + } + + if (i == ARRAY_SIZE(mclk_ratios)) { + dev_err(codec->dev, + "Unable to configure MCLK ratio %d/%d\n", + wm8770->sysclk, params_rate(params)); + return -EINVAL; + } + + dev_dbg(codec->dev, "MCLK is %dfs\n", mclk_ratios[i]); + + snd_soc_update_bits(codec, WM8770_MSTRCTRL, 0x7 << shift, + i << shift); + } + + snd_soc_update_bits(codec, WM8770_IFACECTRL, 0x30, iface); + + return 0; +} + +static int wm8770_mute(struct snd_soc_dai *dai, int mute) +{ + struct snd_soc_codec *codec; + + codec = dai->codec; + return snd_soc_update_bits(codec, WM8770_DACMUTE, 0x10, + !!mute << 4); +} + +static int wm8770_set_sysclk(struct snd_soc_dai *dai, + int clk_id, unsigned int freq, int dir) +{ + struct snd_soc_codec *codec; + struct wm8770_priv *wm8770; + + codec = dai->codec; + wm8770 = snd_soc_codec_get_drvdata(codec); + wm8770->sysclk = freq; + return 0; +} + +static void wm8770_sync_cache(struct snd_soc_codec *codec) +{ + int i; + u16 *cache; + + if (!codec->cache_sync) + return; + + codec->cache_only = 0; + cache = codec->reg_cache; + for (i = 0; i < codec->driver->reg_cache_size; i++) { + if (i == WM8770_RESET || cache[i] == wm8770_reg_defs[i]) + continue; + snd_soc_write(codec, i, cache[i]); + } + codec->cache_sync = 0; +} + +static int wm8770_set_bias_level(struct snd_soc_codec *codec, + enum snd_soc_bias_level level) +{ + int ret; + struct wm8770_priv *wm8770; + + wm8770 = snd_soc_codec_get_drvdata(codec); + + switch (level) { + case SND_SOC_BIAS_ON: + break; + case SND_SOC_BIAS_PREPARE: + break; + case SND_SOC_BIAS_STANDBY: + if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { + ret = regulator_bulk_enable(ARRAY_SIZE(wm8770->supplies), + wm8770->supplies); + if (ret) { + dev_err(codec->dev, + "Failed to enable supplies: %d\n", + ret); + return ret; + } + wm8770_sync_cache(codec); + /* global powerup */ + snd_soc_write(codec, WM8770_PWDNCTRL, 0); + } + break; + case SND_SOC_BIAS_OFF: + /* global powerdown */ + snd_soc_write(codec, WM8770_PWDNCTRL, 1); + regulator_bulk_disable(ARRAY_SIZE(wm8770->supplies), + wm8770->supplies); + break; + } + + codec->dapm.bias_level = level; + return 0; +} + +#define WM8770_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE | \ + SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE) + +static struct snd_soc_dai_ops wm8770_dai_ops = { + .digital_mute = wm8770_mute, + .hw_params = wm8770_hw_params, + .set_fmt = wm8770_set_fmt, + .set_sysclk = wm8770_set_sysclk, +}; + +static struct snd_soc_dai_driver wm8770_dai = { + .name = "wm8770-hifi", + .playback = { + .stream_name = "Playback", + .channels_min = 2, + .channels_max = 2, + .rates = SNDRV_PCM_RATE_8000_192000, + .formats = WM8770_FORMATS + }, + .capture = { + .stream_name = "Capture", + .channels_min = 2, + .channels_max = 2, + .rates = SNDRV_PCM_RATE_8000_96000, + .formats = WM8770_FORMATS + }, + .ops = &wm8770_dai_ops, + .symmetric_rates = 1 +}; + +#ifdef CONFIG_PM +static int wm8770_suspend(struct snd_soc_codec *codec, pm_message_t state) +{ + wm8770_set_bias_level(codec, SND_SOC_BIAS_OFF); + return 0; +} + +static int wm8770_resume(struct snd_soc_codec *codec) +{ + wm8770_set_bias_level(codec, SND_SOC_BIAS_STANDBY); + return 0; +} +#else +#define wm8770_suspend NULL +#define wm8770_resume NULL +#endif + +static int wm8770_probe(struct snd_soc_codec *codec) +{ + struct wm8770_priv *wm8770; + int ret; + int i; + + wm8770 = snd_soc_codec_get_drvdata(codec); + wm8770->codec = codec; + + codec->dapm.idle_bias_off = 1; + + ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8770->control_type); + if (ret < 0) { + dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); + return ret; + } + + for (i = 0; i < ARRAY_SIZE(wm8770->supplies); i++) + wm8770->supplies[i].supply = wm8770_supply_names[i]; + + ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8770->supplies), + wm8770->supplies); + if (ret) { + dev_err(codec->dev, "Failed to request supplies: %d\n", ret); + return ret; + } + + wm8770->disable_nb[0].notifier_call = wm8770_regulator_event_0; + wm8770->disable_nb[1].notifier_call = wm8770_regulator_event_1; + wm8770->disable_nb[2].notifier_call = wm8770_regulator_event_2; + + /* This should really be moved into the regulator core */ + for (i = 0; i < ARRAY_SIZE(wm8770->supplies); i++) { + ret = regulator_register_notifier(wm8770->supplies[i].consumer, + &wm8770->disable_nb[i]); + if (ret) { + dev_err(codec->dev, + "Failed to register regulator notifier: %d\n", + ret); + } + } + + ret = regulator_bulk_enable(ARRAY_SIZE(wm8770->supplies), + wm8770->supplies); + if (ret) { + dev_err(codec->dev, "Failed to enable supplies: %d\n", ret); + goto err_reg_get; + } + + ret = wm8770_reset(codec); + if (ret < 0) { + dev_err(codec->dev, "Failed to issue reset: %d\n", ret); + goto err_reg_enable; + } + + wm8770_set_bias_level(codec, SND_SOC_BIAS_STANDBY); + + /* latch the volume update bits */ + snd_soc_update_bits(codec, WM8770_MSDIGVOL, 0x100, 0x100); + snd_soc_update_bits(codec, WM8770_MSALGVOL, 0x100, 0x100); + snd_soc_update_bits(codec, WM8770_VOUT1RVOL, 0x100, 0x100); + snd_soc_update_bits(codec, WM8770_VOUT2RVOL, 0x100, 0x100); + snd_soc_update_bits(codec, WM8770_VOUT3RVOL, 0x100, 0x100); + snd_soc_update_bits(codec, WM8770_VOUT4RVOL, 0x100, 0x100); + snd_soc_update_bits(codec, WM8770_DAC1RVOL, 0x100, 0x100); + snd_soc_update_bits(codec, WM8770_DAC2RVOL, 0x100, 0x100); + snd_soc_update_bits(codec, WM8770_DAC3RVOL, 0x100, 0x100); + snd_soc_update_bits(codec, WM8770_DAC4RVOL, 0x100, 0x100); + + /* mute all DACs */ + snd_soc_update_bits(codec, WM8770_DACMUTE, 0x10, 0x10); + + snd_soc_add_controls(codec, wm8770_snd_controls, + ARRAY_SIZE(wm8770_snd_controls)); + snd_soc_dapm_new_controls(&codec->dapm, wm8770_dapm_widgets, + ARRAY_SIZE(wm8770_dapm_widgets)); + snd_soc_dapm_add_routes(&codec->dapm, wm8770_intercon, + ARRAY_SIZE(wm8770_intercon)); + return 0; + +err_reg_enable: + regulator_bulk_disable(ARRAY_SIZE(wm8770->supplies), wm8770->supplies); +err_reg_get: + regulator_bulk_free(ARRAY_SIZE(wm8770->supplies), wm8770->supplies); + return ret; +} + +static int wm8770_remove(struct snd_soc_codec *codec) +{ + struct wm8770_priv *wm8770; + int i; + + wm8770 = snd_soc_codec_get_drvdata(codec); + wm8770_set_bias_level(codec, SND_SOC_BIAS_OFF); + + for (i = 0; i < ARRAY_SIZE(wm8770->supplies); ++i) + regulator_unregister_notifier(wm8770->supplies[i].consumer, + &wm8770->disable_nb[i]); + regulator_bulk_free(ARRAY_SIZE(wm8770->supplies), wm8770->supplies); + return 0; +} + +static struct snd_soc_codec_driver soc_codec_dev_wm8770 = { + .probe = wm8770_probe, + .remove = wm8770_remove, + .suspend = wm8770_suspend, + .resume = wm8770_resume, + .set_bias_level = wm8770_set_bias_level, + .reg_cache_size = ARRAY_SIZE(wm8770_reg_defs), + .reg_word_size = sizeof (u16), + .reg_cache_default = wm8770_reg_defs +}; + +#if defined(CONFIG_SPI_MASTER) +static int __devinit wm8770_spi_probe(struct spi_device *spi) +{ + struct wm8770_priv *wm8770; + int ret; + + wm8770 = kzalloc(sizeof(struct wm8770_priv), GFP_KERNEL); + if (!wm8770) + return -ENOMEM; + + wm8770->control_type = SND_SOC_SPI; + spi_set_drvdata(spi, wm8770); + + ret = snd_soc_register_codec(&spi->dev, + &soc_codec_dev_wm8770, &wm8770_dai, 1); + if (ret < 0) + kfree(wm8770); + return ret; +} + +static int __devexit wm8770_spi_remove(struct spi_device *spi) +{ + snd_soc_unregister_codec(&spi->dev); + kfree(spi_get_drvdata(spi)); + return 0; +} + +static struct spi_driver wm8770_spi_driver = { + .driver = { + .name = "wm8770", + .owner = THIS_MODULE, + }, + .probe = wm8770_spi_probe, + .remove = __devexit_p(wm8770_spi_remove) +}; +#endif + +static int __init wm8770_modinit(void) +{ + int ret = 0; + +#if defined(CONFIG_SPI_MASTER) + ret = spi_register_driver(&wm8770_spi_driver); + if (ret) { + printk(KERN_ERR "Failed to register wm8770 SPI driver: %d\n", + ret); + } +#endif + return ret; +} +module_init(wm8770_modinit); + +static void __exit wm8770_exit(void) +{ +#if defined(CONFIG_SPI_MASTER) + spi_unregister_driver(&wm8770_spi_driver); +#endif +} +module_exit(wm8770_exit); + +MODULE_DESCRIPTION("ASoC WM8770 driver"); +MODULE_AUTHOR("Dimitris Papastamos "); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/codecs/wm8770.h b/sound/soc/codecs/wm8770.h new file mode 100644 index 000000000000..5f1b3bda6cc8 --- /dev/null +++ b/sound/soc/codecs/wm8770.h @@ -0,0 +1,51 @@ +/* + * wm8770.h -- WM8770 ASoC driver + * + * Copyright 2010 Wolfson Microelectronics plc + * + * Author: Dimitris Papastamos + * + * 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. + */ + +#ifndef _WM8770_H +#define _WM8770_H + +/* Registers */ +#define WM8770_VOUT1LVOL 0 +#define WM8770_VOUT1RVOL 0x1 +#define WM8770_VOUT2LVOL 0x2 +#define WM8770_VOUT2RVOL 0x3 +#define WM8770_VOUT3LVOL 0x4 +#define WM8770_VOUT3RVOL 0x5 +#define WM8770_VOUT4LVOL 0x6 +#define WM8770_VOUT4RVOL 0x7 +#define WM8770_MSALGVOL 0x8 +#define WM8770_DAC1LVOL 0x9 +#define WM8770_DAC1RVOL 0xa +#define WM8770_DAC2LVOL 0xb +#define WM8770_DAC2RVOL 0xc +#define WM8770_DAC3LVOL 0xd +#define WM8770_DAC3RVOL 0xe +#define WM8770_DAC4LVOL 0xf +#define WM8770_DAC4RVOL 0x10 +#define WM8770_MSDIGVOL 0x11 +#define WM8770_DACPHASE 0x12 +#define WM8770_DACCTRL1 0x13 +#define WM8770_DACMUTE 0x14 +#define WM8770_DACCTRL2 0x15 +#define WM8770_IFACECTRL 0x16 +#define WM8770_MSTRCTRL 0x17 +#define WM8770_PWDNCTRL 0x18 +#define WM8770_ADCLCTRL 0x19 +#define WM8770_ADCRCTRL 0x1a +#define WM8770_ADCMUX 0x1b +#define WM8770_OUTMUX1 0x1c +#define WM8770_OUTMUX2 0x1d +#define WM8770_RESET 0x31 + +#define WM8770_CACHEREGNUM 0x20 + +#endif -- cgit v1.2.3 From 045e769ab69ce94dedbcdcfd46c2578b385c2986 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sun, 7 Nov 2010 09:18:22 +0000 Subject: drm/i915: Handle GPU hangs during fault gracefully. Instead of killing the process, just return no page found and reschedule the process giving the GPU some time to (hopefully) recover. Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_gem.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 47c665eeaf17..7c91bf2bbdfd 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1340,11 +1340,12 @@ unlock: mutex_unlock(&dev->struct_mutex); switch (ret) { + case -EAGAIN: + set_need_resched(); case 0: case -ERESTARTSYS: return VM_FAULT_NOPAGE; case -ENOMEM: - case -EAGAIN: return VM_FAULT_OOM; default: return VM_FAULT_SIGBUS; -- cgit v1.2.3 From ae69b42a10dafe61adb016e0e52ec1e8d1ba11b4 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sun, 7 Nov 2010 11:45:52 +0000 Subject: drm/i915/ringbuffer: Be consistent in use of ring->size when initialising Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/intel_ringbuffer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 78a5061a58f6..9033697783b9 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -173,7 +173,7 @@ static int init_ring_common(struct intel_ring_buffer *ring) } I915_WRITE_CTL(ring, - ((ring->gem_object->size - PAGE_SIZE) & RING_NR_PAGES) + ((ring->size - PAGE_SIZE) & RING_NR_PAGES) | RING_REPORT_64K | RING_VALID); /* If the head is still not zero, the ring is dead */ -- cgit v1.2.3 From 629e894173c9de589913cf649deaadec4b0579bd Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sun, 7 Nov 2010 11:50:02 +0000 Subject: drm/i915/ringbuffer: Ignore failure to setup the ring on Sandybridge The ring buffer registers return 0 whilst idle (for some values of idle) on early Sandybridge hw. Persevere even when all appears hopeless... Fortunately the head auto-reporting prevents most hangs. Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=31370 Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/intel_ringbuffer.c | 32 ++++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 9033697783b9..f5d6151c953f 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -180,14 +180,30 @@ static int init_ring_common(struct intel_ring_buffer *ring) if ((I915_READ_CTL(ring) & RING_VALID) == 0 || I915_READ_START(ring) != obj_priv->gtt_offset || (I915_READ_HEAD(ring) & HEAD_ADDR) != 0) { - DRM_ERROR("%s initialization failed " - "ctl %08x head %08x tail %08x start %08x\n", - ring->name, - I915_READ_CTL(ring), - I915_READ_HEAD(ring), - I915_READ_TAIL(ring), - I915_READ_START(ring)); - return -EIO; + if (IS_GEN6(ring->dev) && ring->dev->pdev->revision <= 8) { + /* Early revisions of Sandybridge do not like + * revealing the contents of the ring buffer + * registers whilst idle. Fortunately, the + * auto-reporting mechanism prevents most hangs, + * but this will bite us eventually... + */ + DRM_DEBUG("%s initialization failed " + "ctl %08x head %08x tail %08x start %08x. Ignoring, hope for the best!\n", + ring->name, + I915_READ_CTL(ring), + I915_READ_HEAD(ring), + I915_READ_TAIL(ring), + I915_READ_START(ring)); + } else { + DRM_ERROR("%s initialization failed " + "ctl %08x head %08x tail %08x start %08x\n", + ring->name, + I915_READ_CTL(ring), + I915_READ_HEAD(ring), + I915_READ_TAIL(ring), + I915_READ_START(ring)); + return -EIO; + } } if (!drm_core_check_feature(ring->dev, DRIVER_MODESET)) -- cgit v1.2.3 From de6e2eaf2c420bb8b0d4485913ef312a5539b489 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Sat, 6 Nov 2010 14:53:32 -0700 Subject: drm/i915: Apply B-spec mandated workaround for read flushes on Ironlake. This is not known to fix any particular bugs we have, but the spec says to do it, and the BIOS hadn't already set it up on my system. Signed-off-by: Eric Anholt Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_reg.h | 13 +++++++++++++ drivers/gpu/drm/i915/intel_display.c | 6 ++++++ 2 files changed, 19 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index c79d4ba4fb12..09e2a5502652 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -316,6 +316,19 @@ #define ERROR_GEN6 0x040a0 +/* GM45+ chicken bits -- debug workaround bits that may be required + * for various sorts of correct behavior. The top 16 bits of each are + * the enables for writing to the corresponding low bit. + */ +#define _3D_CHICKEN 0x02084 +#define _3D_CHICKEN2 0x0208c +/* Disables pipelining of read flushes past the SF-WIZ interface. + * Required on all Ironlake steppings according to the B-Spec, but the + * particular danger of not doing so is not specified. + */ +# define _3D_CHICKEN2_WM_READ_PIPELINED (1 << 14) +#define _3D_CHICKEN3 0x02090 + #define MI_MODE 0x0209c # define VS_TIMER_DISPATCH (1 << 6) # define MI_FLUSH_ENABLE (1 << 11) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 77b34942dc91..5ab403556846 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -5818,6 +5818,12 @@ void intel_init_clock_gating(struct drm_device *dev) ILK_DPFC_DIS2 | ILK_CLK_FBC); } + + if (IS_GEN5(dev)) { + I915_WRITE(_3D_CHICKEN2, + _3D_CHICKEN2_WM_READ_PIPELINED << 16 | + _3D_CHICKEN2_WM_READ_PIPELINED); + } return; } else if (IS_G4X(dev)) { uint32_t dspclk_gate; -- cgit v1.2.3 From 67e92af01cb6f7e9a5fd5c930c43cd6f6ef45929 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Sat, 6 Nov 2010 14:53:33 -0700 Subject: drm/i915: Apply display workaround required according to the B-Spec. Not known to fix any current bugs. Signed-off-by: Eric Anholt Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_reg.h | 2 ++ drivers/gpu/drm/i915/intel_display.c | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 09e2a5502652..61fe2619bb63 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -2609,6 +2609,8 @@ #define GTIER 0x4401c #define ILK_DISPLAY_CHICKEN2 0x42004 +/* Required on all Ironlake and Sandybridge according to the B-Spec. */ +#define ILK_ELPIN_409_SELECT (1 << 25) #define ILK_DPARB_GATE (1<<22) #define ILK_VSDPFD_FULL (1<<21) #define ILK_DSPCLK_GATE 0x42020 diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 5ab403556846..c41dae5ade32 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -5819,6 +5819,10 @@ void intel_init_clock_gating(struct drm_device *dev) ILK_CLK_FBC); } + I915_WRITE(ILK_DISPLAY_CHICKEN2, + I915_READ(ILK_DISPLAY_CHICKEN2) | + ILK_ELPIN_409_SELECT); + if (IS_GEN5(dev)) { I915_WRITE(_3D_CHICKEN2, _3D_CHICKEN2_WM_READ_PIPELINED << 16 | -- cgit v1.2.3 From ba4f01a30480cdcd516b782f77a6e0951b83df1c Mon Sep 17 00:00:00 2001 From: Yuanhan Liu Date: Mon, 8 Nov 2010 17:09:41 +0800 Subject: drm/i915: trace down all the register write and read Add two tracepoints at I915_WRITE/READ for tracing down all the register write and read. Signed-off-by: Yuanhan Liu Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_drv.h | 61 ++++++++++++++++++++++++++++++++++----- drivers/gpu/drm/i915/i915_trace.h | 23 +++++++++++++++ 2 files changed, 76 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 621234265454..220ce53d4a9c 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -32,6 +32,7 @@ #include "i915_reg.h" #include "intel_bios.h" +#include "i915_trace.h" #include "intel_ringbuffer.h" #include #include @@ -1173,14 +1174,58 @@ extern void intel_overlay_print_error_state(struct seq_file *m, struct intel_ove LOCK_TEST_WITH_RETURN(dev, file_priv); \ } while (0) -#define I915_READ(reg) readl(dev_priv->regs + (reg)) -#define I915_WRITE(reg, val) writel(val, dev_priv->regs + (reg)) -#define I915_READ16(reg) readw(dev_priv->regs + (reg)) -#define I915_WRITE16(reg, val) writel(val, dev_priv->regs + (reg)) -#define I915_READ8(reg) readb(dev_priv->regs + (reg)) -#define I915_WRITE8(reg, val) writeb(val, dev_priv->regs + (reg)) -#define I915_WRITE64(reg, val) writeq(val, dev_priv->regs + (reg)) -#define I915_READ64(reg) readq(dev_priv->regs + (reg)) +static inline u32 i915_read(struct drm_i915_private *dev_priv, u32 reg, int len) +{ + u64 val = 0; + + switch (len) { + case 8: + val = readq(dev_priv->regs + reg); + break; + case 4: + val = readl(dev_priv->regs + reg); + break; + case 2: + val = readw(dev_priv->regs + reg); + break; + case 1: + val = readb(dev_priv->regs + reg); + break; + } + trace_i915_reg_rw('R', reg, val, len); + + return val; +} + +static inline void +i915_write(struct drm_i915_private *dev_priv, u32 reg, u64 val, int len) +{ + /* Trace down the write operation before the real write */ + trace_i915_reg_rw('W', reg, val, len); + switch (len) { + case 8: + writeq(val, dev_priv->regs + reg); + break; + case 4: + writel(val, dev_priv->regs + reg); + break; + case 2: + writew(val, dev_priv->regs + reg); + break; + case 1: + writeb(val, dev_priv->regs + reg); + break; + } +} + +#define I915_READ(reg) i915_read(dev_priv, (reg), 4) +#define I915_WRITE(reg, val) i915_write(dev_priv, (reg), (val), 4) +#define I915_READ16(reg) i915_read(dev_priv, (reg), 2) +#define I915_WRITE16(reg, val) i915_write(dev_priv, (reg), (val), 2) +#define I915_READ8(reg) i915_read(dev_priv, (reg), 1) +#define I915_WRITE8(reg, val) i915_write(dev_priv, (reg), (val), 1) +#define I915_WRITE64(reg, val) i915_write(dev_priv, (reg), (val), 8) +#define I915_READ64(reg) i915_read(dev_priv, (reg), 8) #define POSTING_READ(reg) (void)I915_READ(reg) #define POSTING_READ16(reg) (void)I915_READ16(reg) diff --git a/drivers/gpu/drm/i915/i915_trace.h b/drivers/gpu/drm/i915/i915_trace.h index 0b1049ff72a3..34ef49fd0377 100644 --- a/drivers/gpu/drm/i915/i915_trace.h +++ b/drivers/gpu/drm/i915/i915_trace.h @@ -301,6 +301,29 @@ TRACE_EVENT(i915_flip_complete, TP_printk("plane=%d, obj=%p", __entry->plane, __entry->obj) ); +TRACE_EVENT(i915_reg_rw, + TP_PROTO(int cmd, uint32_t reg, uint64_t val, int len), + + TP_ARGS(cmd, reg, val, len), + + TP_STRUCT__entry( + __field(int, cmd) + __field(uint32_t, reg) + __field(uint64_t, val) + __field(int, len) + ), + + TP_fast_assign( + __entry->cmd = cmd; + __entry->reg = reg; + __entry->val = (uint64_t)val; + __entry->len = len; + ), + + TP_printk("cmd=%c, reg=0x%x, val=0x%llx, len=%d", + __entry->cmd, __entry->reg, __entry->val, __entry->len) +); + #endif /* _I915_TRACE_H_ */ /* This part must be outside protection */ -- cgit v1.2.3 From 65e5ecb066fe54c13c8445d6acfdcdf149ad5df9 Mon Sep 17 00:00:00 2001 From: Yuanhan Liu Date: Mon, 8 Nov 2010 09:56:37 +0000 Subject: drm/i915: Add untraced register read/write interface This will be used later to hide the frequently written registers from debug traces in order to increase the signal-to-noise. Signed-off-by: Yuanhan Liu Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_drv.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 220ce53d4a9c..02c35d57fbed 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1229,6 +1229,11 @@ i915_write(struct drm_i915_private *dev_priv, u32 reg, u64 val, int len) #define POSTING_READ(reg) (void)I915_READ(reg) #define POSTING_READ16(reg) (void)I915_READ16(reg) +#define I915_READ_NOTRACE(reg) readl(dev_priv->regs + (reg)) +#define I915_WRITE_NOTRACE(reg, val) writel(val, dev_priv->regs + (reg)) +#define POSTING_READ_NOTRACE(reg) (void)I915_READ_NOTRACE(reg) + + #define BEGIN_LP_RING(n) \ intel_ring_begin(&dev_priv->render_ring, (n)) -- cgit v1.2.3 From db5e4172a023cff68b3597ace8a5390b02669d27 Mon Sep 17 00:00:00 2001 From: Yuanhan Liu Date: Mon, 8 Nov 2010 09:58:16 +0000 Subject: drm/i915: filter out the read/write of GPIO registers from debug tracing These registers are written very frequently, are timing sensitive, and not particularly relevant to any debugging, so remove the tracepoints from these. Signed-off-by: Yuanhan Liu Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/intel_i2c.c | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_i2c.c b/drivers/gpu/drm/i915/intel_i2c.c index 2be4f728ed0c..8f5c0d33ea00 100644 --- a/drivers/gpu/drm/i915/intel_i2c.c +++ b/drivers/gpu/drm/i915/intel_i2c.c @@ -85,8 +85,9 @@ static u32 get_reserved(struct intel_gpio *gpio) /* On most chips, these bits must be preserved in software. */ if (!IS_I830(dev) && !IS_845G(dev)) - reserved = I915_READ(gpio->reg) & (GPIO_DATA_PULLUP_DISABLE | - GPIO_CLOCK_PULLUP_DISABLE); + reserved = I915_READ_NOTRACE(gpio->reg) & + (GPIO_DATA_PULLUP_DISABLE | + GPIO_CLOCK_PULLUP_DISABLE); return reserved; } @@ -96,9 +97,9 @@ static int get_clock(void *data) struct intel_gpio *gpio = data; struct drm_i915_private *dev_priv = gpio->dev_priv; u32 reserved = get_reserved(gpio); - I915_WRITE(gpio->reg, reserved | GPIO_CLOCK_DIR_MASK); - I915_WRITE(gpio->reg, reserved); - return (I915_READ(gpio->reg) & GPIO_CLOCK_VAL_IN) != 0; + I915_WRITE_NOTRACE(gpio->reg, reserved | GPIO_CLOCK_DIR_MASK); + I915_WRITE_NOTRACE(gpio->reg, reserved); + return (I915_READ_NOTRACE(gpio->reg) & GPIO_CLOCK_VAL_IN) != 0; } static int get_data(void *data) @@ -106,9 +107,9 @@ static int get_data(void *data) struct intel_gpio *gpio = data; struct drm_i915_private *dev_priv = gpio->dev_priv; u32 reserved = get_reserved(gpio); - I915_WRITE(gpio->reg, reserved | GPIO_DATA_DIR_MASK); - I915_WRITE(gpio->reg, reserved); - return (I915_READ(gpio->reg) & GPIO_DATA_VAL_IN) != 0; + I915_WRITE_NOTRACE(gpio->reg, reserved | GPIO_DATA_DIR_MASK); + I915_WRITE_NOTRACE(gpio->reg, reserved); + return (I915_READ_NOTRACE(gpio->reg) & GPIO_DATA_VAL_IN) != 0; } static void set_clock(void *data, int state_high) @@ -124,8 +125,8 @@ static void set_clock(void *data, int state_high) clock_bits = GPIO_CLOCK_DIR_OUT | GPIO_CLOCK_DIR_MASK | GPIO_CLOCK_VAL_MASK; - I915_WRITE(gpio->reg, reserved | clock_bits); - POSTING_READ(gpio->reg); + I915_WRITE_NOTRACE(gpio->reg, reserved | clock_bits); + POSTING_READ_NOTRACE(gpio->reg); } static void set_data(void *data, int state_high) @@ -141,8 +142,8 @@ static void set_data(void *data, int state_high) data_bits = GPIO_DATA_DIR_OUT | GPIO_DATA_DIR_MASK | GPIO_DATA_VAL_MASK; - I915_WRITE(gpio->reg, reserved | data_bits); - POSTING_READ(gpio->reg); + I915_WRITE_NOTRACE(gpio->reg, reserved | data_bits); + POSTING_READ_NOTRACE(gpio->reg); } static struct i2c_adapter * -- cgit v1.2.3 From 2b51dca79a105dea022776ea7874193239df7fbd Mon Sep 17 00:00:00 2001 From: Pekka Enberg Date: Mon, 8 Nov 2010 14:44:34 +0100 Subject: floppy: replace NO_GEOM macro with a function This patch replaces the NO_GEOM macro with a proper static inline function and converts an open-coded caller in check_floppy_change() to use it. Cc: Stephen Hemminger Cc: Andrew Morton Signed-off-by: Pekka Enberg Signed-off-by: Jens Axboe --- drivers/block/floppy.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c index cf04c1b234ed..709e69c6d022 100644 --- a/drivers/block/floppy.c +++ b/drivers/block/floppy.c @@ -596,6 +596,11 @@ static unsigned char fsector_t; /* sector in track */ static unsigned char in_sector_offset; /* offset within physical sector, * expressed in units of 512 bytes */ +static inline bool drive_no_geom(int drive) +{ + return !current_type[drive] && !ITYPE(UDRS->fd_device); +} + #ifndef fd_eject static inline int fd_eject(int drive) { @@ -3757,7 +3762,7 @@ static int check_floppy_change(struct gendisk *disk) if (test_bit(FD_DISK_CHANGED_BIT, &UDRS->flags) || test_bit(FD_VERIFY_BIT, &UDRS->flags) || test_bit(drive, &fake_change) || - (!ITYPE(UDRS->fd_device) && !current_type[drive])) + drive_no_geom(drive)) return 1; return 0; } @@ -3823,13 +3828,13 @@ static int __floppy_read_block_0(struct block_device *bdev) static int floppy_revalidate(struct gendisk *disk) { int drive = (long)disk->private_data; -#define NO_GEOM (!current_type[drive] && !ITYPE(UDRS->fd_device)) int cf; int res = 0; if (test_bit(FD_DISK_CHANGED_BIT, &UDRS->flags) || test_bit(FD_VERIFY_BIT, &UDRS->flags) || - test_bit(drive, &fake_change) || NO_GEOM) { + test_bit(drive, &fake_change) || + drive_no_geom(drive)) { if (WARN(atomic_read(&usage_count) == 0, "VFS: revalidate called on non-open device.\n")) return -EFAULT; @@ -3837,7 +3842,7 @@ static int floppy_revalidate(struct gendisk *disk) lock_fdc(drive, false); cf = (test_bit(FD_DISK_CHANGED_BIT, &UDRS->flags) || test_bit(FD_VERIFY_BIT, &UDRS->flags)); - if (!(cf || test_bit(drive, &fake_change) || NO_GEOM)) { + if (!(cf || test_bit(drive, &fake_change) || drive_no_geom(drive))) { process_fd_request(); /*already done by another thread */ return 0; } @@ -3849,7 +3854,7 @@ static int floppy_revalidate(struct gendisk *disk) clear_bit(FD_DISK_CHANGED_BIT, &UDRS->flags); if (cf) UDRS->generation++; - if (NO_GEOM) { + if (drive_no_geom(drive)) { /* auto-sensing */ res = __floppy_read_block_0(opened_bdev[drive]); } else { -- cgit v1.2.3 From c1e44756fdb7b363fd22cb5514dced40752e36c5 Mon Sep 17 00:00:00 2001 From: Shaohua Li Date: Mon, 8 Nov 2010 15:01:02 +0100 Subject: cfq-iosched: do cleanup Some functions should return boolean. Signed-off-by: Shaohua Li Signed-off-by: Jens Axboe --- block/cfq-iosched.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c index 9eba291eb6fd..b8174bb4a6a1 100644 --- a/block/cfq-iosched.c +++ b/block/cfq-iosched.c @@ -637,11 +637,11 @@ cfq_set_prio_slice(struct cfq_data *cfqd, struct cfq_queue *cfqq) static inline bool cfq_slice_used(struct cfq_queue *cfqq) { if (cfq_cfqq_slice_new(cfqq)) - return 0; + return false; if (time_before(jiffies, cfqq->slice_end)) - return 0; + return false; - return 1; + return true; } /* @@ -1892,10 +1892,10 @@ static bool cfq_should_idle(struct cfq_data *cfqd, struct cfq_queue *cfqq) * in their service tree. */ if (service_tree->count == 1 && cfq_cfqq_sync(cfqq)) - return 1; + return true; cfq_log_cfqq(cfqd, cfqq, "Not idling. st->count:%d", service_tree->count); - return 0; + return false; } static void cfq_arm_slice_timer(struct cfq_data *cfqd) @@ -2359,12 +2359,12 @@ static inline bool cfq_slice_used_soon(struct cfq_data *cfqd, { /* the queue hasn't finished any request, can't estimate */ if (cfq_cfqq_slice_new(cfqq)) - return 1; + return true; if (time_after(jiffies + cfqd->cfq_slice_idle * cfqq->dispatched, cfqq->slice_end)) - return 1; + return true; - return 0; + return false; } static bool cfq_may_dispatch(struct cfq_data *cfqd, struct cfq_queue *cfqq) -- cgit v1.2.3 From d2d59e18a1ea8ecdd1c0a52af320e9a7f5391cc4 Mon Sep 17 00:00:00 2001 From: Shaohua Li Date: Mon, 8 Nov 2010 15:01:03 +0100 Subject: cfq-iosched: schedule dispatch for noidle queue A queue is idle at cfq_dispatch_requests(), but it gets noidle later. Unless other task explictly does unplug or all requests are drained, we will not deliever requests to the disk even cfq_arm_slice_timer doesn't make the queue idle. For example, cfq_should_idle() returns true because of service_tree->count == 1, and then other queues are added. Note, I didn't see obvious performance impacts so far with the patch, but just thought this could be a problem. Signed-off-by: Shaohua Li Signed-off-by: Jens Axboe --- block/cfq-iosched.c | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c index b8174bb4a6a1..986865e3fbc5 100644 --- a/block/cfq-iosched.c +++ b/block/cfq-iosched.c @@ -3255,6 +3255,10 @@ cfq_should_preempt(struct cfq_data *cfqd, struct cfq_queue *new_cfqq, if (cfq_class_rt(new_cfqq) && !cfq_class_rt(cfqq)) return true; + /* An idle queue should not be idle now for some reason */ + if (RB_EMPTY_ROOT(&cfqq->sort_list) && !cfq_should_idle(cfqd, cfqq)) + return true; + if (!cfqd->active_cic || !cfq_cfqq_wait_request(cfqq)) return false; @@ -3508,8 +3512,25 @@ static void cfq_completed_request(struct request_queue *q, struct request *rq) } } - if (!cfqd->rq_in_driver) + if (!cfqd->rq_in_driver) { + cfq_schedule_dispatch(cfqd); + return; + } + /* + * A queue is idle at cfq_dispatch_requests(), but it gets noidle + * later. We schedule a dispatch if the queue has no requests, + * otherwise the disk is actually in idle till all requests + * are finished even cfq_arm_slice_timer doesn't make the queue idle + * */ + cfqq = cfqd->active_queue; + if (!cfqq) + return; + + if (RB_EMPTY_ROOT(&cfqq->sort_list) && !cfq_should_idle(cfqd, cfqq) && + (!cfqd->cfq_group_idle || cfqq->cfqg->nr_cfqq > 1)) { + cfq_del_timer(cfqd, cfqq); cfq_schedule_dispatch(cfqd); + } } /* -- cgit v1.2.3 From 8e1ac6655104bc6e1e79d67e2df88cc8fa9b6e07 Mon Sep 17 00:00:00 2001 From: Shaohua Li Date: Mon, 8 Nov 2010 15:01:04 +0100 Subject: cfq-iosched: don't idle if a deep seek queue is slow If a deep seek queue slowly deliver requests but disk is much faster, idle for the queue just wastes disk throughput. If the queue delevers all requests before half its slice is used, the patch disable idle for it. In my test, application delivers 32 requests one time, the disk can accept 128 requests at maxium and disk is fast. without the patch, the throughput is just around 30m/s, while with it, the speed is about 80m/s. The disk is a SSD, but is detected as a rotational disk. I can configure it as SSD, but I thought the deep seek queue logic should be fixed too, for example, considering a fast raid. Signed-off-by: Shaohua Li Signed-off-by: Jens Axboe --- block/cfq-iosched.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c index 986865e3fbc5..ca4d19907243 100644 --- a/block/cfq-iosched.c +++ b/block/cfq-iosched.c @@ -2285,6 +2285,17 @@ static struct cfq_queue *cfq_select_queue(struct cfq_data *cfqd) goto keep_queue; } + /* + * This is a deep seek queue, but the device is much faster than + * the queue can deliver, don't idle + **/ + if (CFQQ_SEEKY(cfqq) && cfq_cfqq_idle_window(cfqq) && + (cfq_cfqq_slice_new(cfqq) || + (cfqq->slice_end - jiffies > jiffies - cfqq->slice_start))) { + cfq_clear_cfqq_deep(cfqq); + cfq_clear_cfqq_idle_window(cfqq); + } + if (cfqq->dispatched && cfq_should_idle(cfqd, cfqq)) { cfqq = NULL; goto keep_queue; -- cgit v1.2.3 From 5bf68592e72eb0ded154efaaf43b39aab6964fc3 Mon Sep 17 00:00:00 2001 From: Ben Collins Date: Mon, 8 Nov 2010 10:07:42 -0500 Subject: solo6x10: [P2M] Fix memory leak Signed-off-by: Ben Collins --- drivers/staging/solo6x10/solo6010-p2m.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/staging/solo6x10/solo6010-p2m.c b/drivers/staging/solo6x10/solo6010-p2m.c index 9f2418093af5..c91fc4652a00 100644 --- a/drivers/staging/solo6x10/solo6010-p2m.c +++ b/drivers/staging/solo6x10/solo6010-p2m.c @@ -51,13 +51,16 @@ int solo_p2m_dma_t(struct solo6010_dev *solo_dev, u8 id, int wr, dma_addr_t dma_addr, u32 ext_addr, u32 size) { struct p2m_desc *desc = kzalloc(sizeof(*desc) * 2, GFP_DMA); + int ret; if (desc == NULL) return -ENOMEM; solo_p2m_push_desc(&desc[1], wr, dma_addr, ext_addr, size, 0, 0); + ret = solo_p2m_dma_desc(solo_dev, id, desc, 2); + kfree(desc); - return solo_p2m_dma_desc(solo_dev, id, desc, 2); + return ret; } void solo_p2m_push_desc(struct p2m_desc *desc, int wr, dma_addr_t dma_addr, -- cgit v1.2.3 From 5aaa062c27273d21d1f52ddc20e697b6466057d4 Mon Sep 17 00:00:00 2001 From: Dimitris Papastamos Date: Mon, 8 Nov 2010 15:37:07 +0000 Subject: ASoC: soc-cache: Use BUG_ON() for unsupported hw_read() calls Instead of dereferencing a NULL function pointer and falling apart use BUG_ON() for any unimplemented hw_read() calls. Signed-off-by: Dimitris Papastamos Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/soc-cache.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/sound/soc/soc-cache.c b/sound/soc/soc-cache.c index 8785a0c918d2..e7479988deca 100644 --- a/sound/soc/soc-cache.c +++ b/sound/soc/soc-cache.c @@ -25,6 +25,7 @@ static unsigned int snd_soc_4_12_read(struct snd_soc_codec *codec, if (codec->cache_only) return -1; + BUG_ON(!codec->hw_read); return codec->hw_read(codec, reg); } @@ -99,6 +100,7 @@ static unsigned int snd_soc_7_9_read(struct snd_soc_codec *codec, if (codec->cache_only) return -1; + BUG_ON(!codec->hw_read); return codec->hw_read(codec, reg); } @@ -199,6 +201,7 @@ static unsigned int snd_soc_8_8_read(struct snd_soc_codec *codec, if (codec->cache_only) return -1; + BUG_ON(!codec->hw_read); return codec->hw_read(codec, reg); } @@ -270,6 +273,7 @@ static unsigned int snd_soc_8_16_read(struct snd_soc_codec *codec, if (codec->cache_only) return -1; + BUG_ON(!codec->hw_read); return codec->hw_read(codec, reg); } else { return cache[reg]; @@ -420,6 +424,7 @@ static unsigned int snd_soc_16_8_read(struct snd_soc_codec *codec, if (codec->cache_only) return -1; + BUG_ON(!codec->hw_read); return codec->hw_read(codec, reg); } @@ -531,6 +536,7 @@ static unsigned int snd_soc_16_16_read(struct snd_soc_codec *codec, if (codec->cache_only) return -1; + BUG_ON(!codec->hw_read); return codec->hw_read(codec, reg); } -- cgit v1.2.3 From 0aa34b16f9f34a81bd50c097f1953877614220db Mon Sep 17 00:00:00 2001 From: Dimitris Papastamos Date: Mon, 8 Nov 2010 10:41:53 +0000 Subject: ASoC: Remove unneeded use of address-of operator There is no need to use '&' in this case. Either way, if a is an array of some type, then a == &a == &a[0]. Signed-off-by: Dimitris Papastamos Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/codecs/wm8580.c | 2 +- sound/soc/codecs/wm8741.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/wm8580.c b/sound/soc/codecs/wm8580.c index dfd1dbd71f1d..36c035bf4e42 100644 --- a/sound/soc/codecs/wm8580.c +++ b/sound/soc/codecs/wm8580.c @@ -906,7 +906,7 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8580 = { .set_bias_level = wm8580_set_bias_level, .reg_cache_size = ARRAY_SIZE(wm8580_reg), .reg_word_size = sizeof(u16), - .reg_cache_default = &wm8580_reg, + .reg_cache_default = wm8580_reg, }; #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) diff --git a/sound/soc/codecs/wm8741.c b/sound/soc/codecs/wm8741.c index 43c49dfc9928..2543a26513fb 100644 --- a/sound/soc/codecs/wm8741.c +++ b/sound/soc/codecs/wm8741.c @@ -456,7 +456,7 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8741 = { .resume = wm8741_resume, .reg_cache_size = ARRAY_SIZE(wm8741_reg_defaults), .reg_word_size = sizeof(u16), - .reg_cache_default = &wm8741_reg_defaults, + .reg_cache_default = wm8741_reg_defaults, }; #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) -- cgit v1.2.3 From 374c479bef7ecd2b41d6dd6e24aa21d73b3afae5 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 8 Nov 2010 21:07:24 +0000 Subject: drm/i915: POSTING_READs are simply flushes and so irrelevant to tracing As we use POSTING_READ to flush the write to the register before proceeding, we do not care what the return value is and similar we do not care for the read to be recorded whilst tracing register read/writes. Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_drv.h | 8 +++++--- drivers/gpu/drm/i915/intel_i2c.c | 4 ++-- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 02c35d57fbed..ff7593f70f0f 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1226,12 +1226,14 @@ i915_write(struct drm_i915_private *dev_priv, u32 reg, u64 val, int len) #define I915_WRITE8(reg, val) i915_write(dev_priv, (reg), (val), 1) #define I915_WRITE64(reg, val) i915_write(dev_priv, (reg), (val), 8) #define I915_READ64(reg) i915_read(dev_priv, (reg), 8) -#define POSTING_READ(reg) (void)I915_READ(reg) -#define POSTING_READ16(reg) (void)I915_READ16(reg) #define I915_READ_NOTRACE(reg) readl(dev_priv->regs + (reg)) #define I915_WRITE_NOTRACE(reg, val) writel(val, dev_priv->regs + (reg)) -#define POSTING_READ_NOTRACE(reg) (void)I915_READ_NOTRACE(reg) +#define I915_READ16_NOTRACE(reg) readw(dev_priv->regs + (reg)) +#define I915_WRITE16_NOTRACE(reg, val) writew(val, dev_priv->regs + (reg)) + +#define POSTING_READ(reg) (void)I915_READ_NOTRACE(reg) +#define POSTING_READ16(reg) (void)I915_READ16_NOTRACE(reg) #define BEGIN_LP_RING(n) \ diff --git a/drivers/gpu/drm/i915/intel_i2c.c b/drivers/gpu/drm/i915/intel_i2c.c index 8f5c0d33ea00..d2d493a24e65 100644 --- a/drivers/gpu/drm/i915/intel_i2c.c +++ b/drivers/gpu/drm/i915/intel_i2c.c @@ -126,7 +126,7 @@ static void set_clock(void *data, int state_high) GPIO_CLOCK_VAL_MASK; I915_WRITE_NOTRACE(gpio->reg, reserved | clock_bits); - POSTING_READ_NOTRACE(gpio->reg); + POSTING_READ(gpio->reg); } static void set_data(void *data, int state_high) @@ -143,7 +143,7 @@ static void set_data(void *data, int state_high) GPIO_DATA_VAL_MASK; I915_WRITE_NOTRACE(gpio->reg, reserved | data_bits); - POSTING_READ_NOTRACE(gpio->reg); + POSTING_READ(gpio->reg); } static struct i2c_adapter * -- cgit v1.2.3 From 56e2ea346ab4c2ea159ecdec85fffc24f50c2903 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 8 Nov 2010 17:10:29 +0000 Subject: drm/i915: Fix unload after failed initialisation If modeset init failed we attempted to unload the module, before we finished setting it up and so triggered various oopses. Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_dma.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index eee88cfcb3aa..307bad0fcef7 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -1993,7 +1993,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) drm_core_check_feature(dev, DRIVER_MODESET)) { DRM_ERROR("kernel modesetting requires GEM, disabling driver.\n"); ret = -ENODEV; - goto out_iomapfree; + goto out_workqueue_free; } dev->driver->get_vblank_counter = i915_get_vblank_counter; @@ -2016,8 +2016,8 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) /* Init HWS */ if (!I915_NEED_GFX_HWS(dev)) { ret = i915_init_phys_hws(dev); - if (ret != 0) - goto out_workqueue_free; + if (ret) + goto out_gem_unload; } if (IS_PINEVIEW(dev)) @@ -2044,11 +2044,8 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) dev_priv->trace_irq_seqno = 0; ret = drm_vblank_init(dev, I915_NUM_PIPE); - - if (ret) { - (void) i915_driver_unload(dev); - return ret; - } + if (ret) + goto out_gem_unload; /* Start out suspended */ dev_priv->mm.suspended = 1; @@ -2059,7 +2056,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) ret = i915_load_modeset_init(dev); if (ret < 0) { DRM_ERROR("failed to init modeset\n"); - goto out_workqueue_free; + goto out_gem_unload; } } @@ -2077,6 +2074,12 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) return 0; +out_gem_unload: + if (dev->pdev->msi_enabled) + pci_disable_msi(dev->pdev); + + intel_teardown_gmbus(dev); + intel_teardown_mchbar(dev); out_workqueue_free: destroy_workqueue(dev_priv->wq); out_iomapfree: -- cgit v1.2.3 From 2b9408a45978dcda77407859148deeccf403c372 Mon Sep 17 00:00:00 2001 From: Shaohua Li Date: Tue, 9 Nov 2010 14:51:13 +0100 Subject: cfq-iosched: don't schedule a dispatch for a non-idle queue Vivek suggests we don't need schedule a dispatch when an idle queue becomes nonidle. And he is right, cfq_should_preempt already covers the logic. Signed-off-by: Shaohua Li Signed-off-by: Jens Axboe --- block/cfq-iosched.c | 19 +------------------ 1 file changed, 1 insertion(+), 18 deletions(-) diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c index ca4d19907243..f90519430be6 100644 --- a/block/cfq-iosched.c +++ b/block/cfq-iosched.c @@ -3523,25 +3523,8 @@ static void cfq_completed_request(struct request_queue *q, struct request *rq) } } - if (!cfqd->rq_in_driver) { + if (!cfqd->rq_in_driver) cfq_schedule_dispatch(cfqd); - return; - } - /* - * A queue is idle at cfq_dispatch_requests(), but it gets noidle - * later. We schedule a dispatch if the queue has no requests, - * otherwise the disk is actually in idle till all requests - * are finished even cfq_arm_slice_timer doesn't make the queue idle - * */ - cfqq = cfqd->active_queue; - if (!cfqq) - return; - - if (RB_EMPTY_ROOT(&cfqq->sort_list) && !cfq_should_idle(cfqd, cfqq) && - (!cfqd->cfq_group_idle || cfqq->cfqg->nr_cfqq > 1)) { - cfq_del_timer(cfqd, cfqq); - cfq_schedule_dispatch(cfqd); - } } /* -- cgit v1.2.3 From b95fccbc025cb5788776ed8b80dba20b24529b15 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Tue, 9 Nov 2010 17:06:44 +0800 Subject: ASoC: Fix compile error if CONFIG_DEBUG_FS is not configured Add soc_init_card_debugfs and soc_cleanup_card_debugfs functions to fix below error. CC sound/soc/soc-core.o sound/soc/soc-core.c: In function 'soc_probe': sound/soc/soc-core.c:1689: error: implicit declaration of function 'soc_init_card_debugfs' sound/soc/soc-core.c: In function 'soc_remove': sound/soc/soc-core.c:1718: error: implicit declaration of function 'soc_cleanup_card_debugfs' make[2]: *** [sound/soc/soc-core.o] Error 1 make[1]: *** [sound/soc] Error 2 make: *** [sound] Error 2 Signed-off-by: Axel Lin Acked-by: Jarkko Nikula Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/soc-core.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index f030521c48d1..c18ce1dc51b8 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -401,6 +401,14 @@ static inline void soc_init_codec_debugfs(struct snd_soc_codec *codec) static inline void soc_cleanup_codec_debugfs(struct snd_soc_codec *codec) { } + +static inline void soc_init_card_debugfs(struct snd_soc_card *card) +{ +} + +static inline void soc_cleanup_card_debugfs(struct snd_soc_card *card) +{ +} #endif #ifdef CONFIG_SND_SOC_AC97_BUS -- cgit v1.2.3 From 0656f6cf6c394ede78657595dd5a8ca7a1e64853 Mon Sep 17 00:00:00 2001 From: Jarkko Nikula Date: Mon, 8 Nov 2010 10:57:57 +0200 Subject: ASoC: tpa6130a2: Revisit power-up sequence There are no known problems with current power-up sequence which first sets the /shutdown pin high and then enables the supply. However, swap the order so that the device is kept in shutdown/reset mode during the supply voltage transition since slowly rising voltages can usually cause problems if the device is not kept in reset. Signed-off-by: Jarkko Nikula Cc: Peter Ujfalusi Acked-by: Peter Ujfalusi Acked-by: Mark Brown Signed-off-by: Liam Girdwood --- sound/soc/codecs/tpa6130a2.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/soc/codecs/tpa6130a2.c b/sound/soc/codecs/tpa6130a2.c index 329acc1a2074..e55317b35786 100644 --- a/sound/soc/codecs/tpa6130a2.c +++ b/sound/soc/codecs/tpa6130a2.c @@ -126,9 +126,6 @@ static int tpa6130a2_power(int power) mutex_lock(&data->mutex); if (power) { - /* Power on */ - if (data->power_gpio >= 0) - gpio_set_value(data->power_gpio, 1); ret = regulator_enable(data->supply); if (ret != 0) { @@ -136,6 +133,9 @@ static int tpa6130a2_power(int power) "Failed to enable supply: %d\n", ret); goto exit; } + /* Power on */ + if (data->power_gpio >= 0) + gpio_set_value(data->power_gpio, 1); data->power_state = 1; ret = tpa6130a2_initialize(); -- cgit v1.2.3 From d0f40c5041f9c48afbd8f7fbf8a5faa9e5dbd39a Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Wed, 20 Oct 2010 18:51:06 -0700 Subject: Staging: intel_sst: Use pr_fmt, fix misspellings Remove leading "sst: " from format strings. Add #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt Prefix is changed from "sst: " to "snd_intel_sst: " Add missing newlines Trim trailing spaces after newlines Fix several different misspellings Signed-off-by: Joe Perches Cc: Vinod Koul Cc: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/staging/intel_sst/intel_sst.c | 50 ++--- .../staging/intel_sst/intel_sst_app_interface.c | 140 +++++++------- .../staging/intel_sst/intel_sst_drv_interface.c | 62 ++++--- drivers/staging/intel_sst/intel_sst_dsp.c | 67 +++---- drivers/staging/intel_sst/intel_sst_ipc.c | 144 ++++++++------- drivers/staging/intel_sst/intel_sst_pvt.c | 36 ++-- drivers/staging/intel_sst/intel_sst_stream.c | 18 +- .../staging/intel_sst/intel_sst_stream_encoded.c | 205 +++++++++++---------- drivers/staging/intel_sst/intelmid.c | 157 ++++++++-------- drivers/staging/intel_sst/intelmid_ctrl.c | 15 +- drivers/staging/intel_sst/intelmid_msic_control.c | 24 +-- drivers/staging/intel_sst/intelmid_pvt.c | 27 +-- drivers/staging/intel_sst/intelmid_v0_control.c | 32 ++-- drivers/staging/intel_sst/intelmid_v1_control.c | 28 +-- drivers/staging/intel_sst/intelmid_v2_control.c | 94 +++++----- 15 files changed, 566 insertions(+), 533 deletions(-) diff --git a/drivers/staging/intel_sst/intel_sst.c b/drivers/staging/intel_sst/intel_sst.c index 24d3928e7071..0ba6742d9236 100644 --- a/drivers/staging/intel_sst/intel_sst.c +++ b/drivers/staging/intel_sst/intel_sst.c @@ -29,6 +29,8 @@ * This file contains all init functions */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -169,17 +171,17 @@ static int __devinit intel_sst_probe(struct pci_dev *pci, { int i, ret = 0; - pr_debug("sst: Probe for DID %x\n", pci->device); + pr_debug("Probe for DID %x\n", pci->device); mutex_lock(&drv_ctx_lock); if (sst_drv_ctx) { - pr_err("sst: Only one sst handle is supported\n"); + pr_err("Only one sst handle is supported\n"); mutex_unlock(&drv_ctx_lock); return -EBUSY; } sst_drv_ctx = kzalloc(sizeof(*sst_drv_ctx), GFP_KERNEL); if (!sst_drv_ctx) { - pr_err("sst: intel_sst malloc fail\n"); + pr_err("malloc fail\n"); mutex_unlock(&drv_ctx_lock); return -ENOMEM; } @@ -226,7 +228,7 @@ static int __devinit intel_sst_probe(struct pci_dev *pci, spin_lock_init(&sst_drv_ctx->list_spin_lock); sst_drv_ctx->max_streams = pci_id->driver_data; - pr_debug("sst: Got drv data max stream %d\n", + pr_debug("Got drv data max stream %d\n", sst_drv_ctx->max_streams); for (i = 1; i <= sst_drv_ctx->max_streams; i++) { struct stream_info *stream = &sst_drv_ctx->streams[i]; @@ -241,18 +243,18 @@ static int __devinit intel_sst_probe(struct pci_dev *pci, sst_drv_ctx->mmap_mem = kzalloc(sst_drv_ctx->mmap_len, GFP_KERNEL); if (sst_drv_ctx->mmap_mem) { - pr_debug("sst: Got memory %p size 0x%x\n", + pr_debug("Got memory %p size 0x%x\n", sst_drv_ctx->mmap_mem, sst_drv_ctx->mmap_len); break; } if (sst_drv_ctx->mmap_len < (SST_MMAP_STEP*PAGE_SIZE)) { - pr_err("sst: mem alloc fail...abort!!\n"); + pr_err("mem alloc fail...abort!!\n"); ret = -ENOMEM; goto free_process_reply_wq; } sst_drv_ctx->mmap_len -= (SST_MMAP_STEP * PAGE_SIZE); - pr_debug("sst:mem alloc failed...trying %d\n", + pr_debug("mem alloc failed...trying %d\n", sst_drv_ctx->mmap_len); } } @@ -260,7 +262,7 @@ static int __devinit intel_sst_probe(struct pci_dev *pci, /* Init the device */ ret = pci_enable_device(pci); if (ret) { - pr_err("sst: device cant be enabled\n"); + pr_err("device cant be enabled\n"); goto do_free_mem; } sst_drv_ctx->pci = pci_dev_get(pci); @@ -273,25 +275,25 @@ static int __devinit intel_sst_probe(struct pci_dev *pci, sst_drv_ctx->shim = pci_ioremap_bar(pci, 1); if (!sst_drv_ctx->shim) goto do_release_regions; - pr_debug("sst: SST Shim Ptr %p\n", sst_drv_ctx->shim); + pr_debug("SST Shim Ptr %p\n", sst_drv_ctx->shim); /* Shared SRAM */ sst_drv_ctx->mailbox = pci_ioremap_bar(pci, 2); if (!sst_drv_ctx->mailbox) goto do_unmap_shim; - pr_debug("sst: SRAM Ptr %p\n", sst_drv_ctx->mailbox); + pr_debug("SRAM Ptr %p\n", sst_drv_ctx->mailbox); /* IRAM */ sst_drv_ctx->iram = pci_ioremap_bar(pci, 3); if (!sst_drv_ctx->iram) goto do_unmap_sram; - pr_debug("sst:IRAM Ptr %p\n", sst_drv_ctx->iram); + pr_debug("IRAM Ptr %p\n", sst_drv_ctx->iram); /* DRAM */ sst_drv_ctx->dram = pci_ioremap_bar(pci, 4); if (!sst_drv_ctx->dram) goto do_unmap_iram; - pr_debug("sst: DRAM Ptr %p\n", sst_drv_ctx->dram); + pr_debug("DRAM Ptr %p\n", sst_drv_ctx->dram); mutex_lock(&sst_drv_ctx->sst_lock); sst_drv_ctx->sst_state = SST_UN_INIT; @@ -301,24 +303,24 @@ static int __devinit intel_sst_probe(struct pci_dev *pci, IRQF_SHARED, SST_DRV_NAME, sst_drv_ctx); if (ret) goto do_unmap_dram; - pr_debug("sst: Registered IRQ 0x%x\n", pci->irq); + pr_debug("Registered IRQ 0x%x\n", pci->irq); if (sst_drv_ctx->pci_id == SST_MRST_PCI_ID) { ret = misc_register(&lpe_dev); if (ret) { - pr_err("sst: couldn't register LPE device\n"); + pr_err("couldn't register LPE device\n"); goto do_free_irq; } /*Register LPE Control as misc driver*/ ret = misc_register(&lpe_ctrl); if (ret) { - pr_err("sst: couldn't register misc driver\n"); + pr_err("couldn't register misc driver\n"); goto do_free_irq; } } sst_drv_ctx->lpe_stalled = 0; - pr_debug("sst: ...successfully done!!!\n"); + pr_debug("...successfully done!!!\n"); return ret; do_free_irq: @@ -347,7 +349,7 @@ free_mad_wq: destroy_workqueue(sst_drv_ctx->mad_wq); do_free_drv_ctx: kfree(sst_drv_ctx); - pr_err("sst: Probe failed with 0x%x\n", ret); + pr_err("Probe failed with 0x%x\n", ret); return ret; } @@ -404,7 +406,7 @@ int intel_sst_suspend(struct pci_dev *pci, pm_message_t state) { union config_status_reg csr; - pr_debug("sst: intel_sst_suspend called\n"); + pr_debug("intel_sst_suspend called\n"); if (sst_drv_ctx->pb_streams != 0 || sst_drv_ctx->cp_streams != 0) return -EPERM; @@ -434,9 +436,9 @@ int intel_sst_resume(struct pci_dev *pci) { int ret = 0; - pr_debug("sst: intel_sst_resume called\n"); + pr_debug("intel_sst_resume called\n"); if (sst_drv_ctx->sst_state != SST_SUSPENDED) { - pr_err("sst: SST is not in suspended state\n"); + pr_err("SST is not in suspended state\n"); return -EPERM; } sst_drv_ctx = pci_get_drvdata(pci); @@ -444,7 +446,7 @@ int intel_sst_resume(struct pci_dev *pci) pci_restore_state(pci); ret = pci_enable_device(pci); if (ret) - pr_err("sst: device cant be enabled\n"); + pr_err("device cant be enabled\n"); mutex_lock(&sst_drv_ctx->sst_lock); sst_drv_ctx->sst_state = SST_UN_INIT; @@ -482,14 +484,14 @@ static int __init intel_sst_init(void) { /* Init all variables, data structure etc....*/ int ret = 0; - pr_debug("sst: INFO: ******** SST DRIVER loading.. Ver: %s\n", + pr_debug("INFO: ******** SST DRIVER loading.. Ver: %s\n", SST_DRIVER_VERSION); mutex_init(&drv_ctx_lock); /* Register with PCI */ ret = pci_register_driver(&driver); if (ret) - pr_err("sst: PCI register failed\n"); + pr_err("PCI register failed\n"); return ret; } @@ -504,7 +506,7 @@ static void __exit intel_sst_exit(void) { pci_unregister_driver(&driver); - pr_debug("sst: driver unloaded\n"); + pr_debug("driver unloaded\n"); return; } diff --git a/drivers/staging/intel_sst/intel_sst_app_interface.c b/drivers/staging/intel_sst/intel_sst_app_interface.c index 463e5cba8307..fb718d47f54b 100644 --- a/drivers/staging/intel_sst/intel_sst_app_interface.c +++ b/drivers/staging/intel_sst/intel_sst_app_interface.c @@ -27,6 +27,8 @@ * Upper layer interfaces (MAD driver, MMF) to SST driver */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -59,14 +61,14 @@ static int intel_sst_check_device(void) { int retval = 0; if (sst_drv_ctx->pmic_state != SND_MAD_INIT_DONE) { - pr_warn("sst: Sound card not availble\n "); + pr_warn("Sound card not available\n"); return -EIO; } if (sst_drv_ctx->sst_state == SST_SUSPENDED) { - pr_debug("sst: Resuming from Suspended state\n"); + pr_debug("Resuming from Suspended state\n"); retval = intel_sst_resume(sst_drv_ctx->pci); if (retval) { - pr_debug("sst: Resume Failed= %#x,abort\n", retval); + pr_debug("Resume Failed= %#x,abort\n", retval); return retval; } } @@ -116,7 +118,7 @@ int intel_sst_open(struct inode *i_node, struct file *file_ptr) data->pvt_id = sst_assign_pvt_id(sst_drv_ctx); data->str_id = 0; file_ptr->private_data = (void *)data; - pr_debug("sst: pvt_id handle = %d!\n", data->pvt_id); + pr_debug("pvt_id handle = %d!\n", data->pvt_id); } else { retval = -EUSERS; mutex_unlock(&sst_drv_ctx->stream_lock); @@ -145,7 +147,7 @@ int intel_sst_open_cntrl(struct inode *i_node, struct file *file_ptr) mutex_lock(&sst_drv_ctx->stream_lock); if (sst_drv_ctx->am_cnt < MAX_AM_HANDLES) { sst_drv_ctx->am_cnt++; - pr_debug("sst: AM handle opened...\n"); + pr_debug("AM handle opened...\n"); file_ptr->private_data = NULL; } else retval = -EACCES; @@ -167,7 +169,7 @@ int intel_sst_release(struct inode *i_node, struct file *file_ptr) { struct ioctl_pvt_data *data = file_ptr->private_data; - pr_debug("sst: Release called, closing app handle\n"); + pr_debug("Release called, closing app handle\n"); mutex_lock(&sst_drv_ctx->stream_lock); sst_drv_ctx->encoded_cnt--; sst_drv_ctx->stream_cnt--; @@ -183,7 +185,7 @@ int intel_sst_release_cntrl(struct inode *i_node, struct file *file_ptr) mutex_lock(&sst_drv_ctx->stream_lock); sst_drv_ctx->am_cnt--; mutex_unlock(&sst_drv_ctx->stream_lock); - pr_debug("sst: AM handle closed\n"); + pr_debug("AM handle closed\n"); return 0; } @@ -209,7 +211,7 @@ int intel_sst_mmap(struct file *file_ptr, struct vm_area_struct *vma) return -EINVAL; length = vma->vm_end - vma->vm_start; - pr_debug("sst: called for stream %d length 0x%x\n", str_id, length); + pr_debug("called for stream %d length 0x%x\n", str_id, length); if (length > sst_drv_ctx->mmap_len) return -ENOMEM; @@ -232,7 +234,7 @@ int intel_sst_mmap(struct file *file_ptr, struct vm_area_struct *vma) else sst_drv_ctx->streams[str_id].mmapped = true; - pr_debug("sst: mmap ret 0x%x\n", retval); + pr_debug("mmap ret 0x%x\n", retval); return retval; } @@ -245,7 +247,7 @@ static int intel_sst_mmap_play_capture(u32 str_id, struct stream_info *stream; struct snd_sst_mmap_buff_entry *buf_entry; - pr_debug("sst:called for str_id %d\n", str_id); + pr_debug("called for str_id %d\n", str_id); retval = sst_validate_strid(str_id); if (retval) return -EINVAL; @@ -262,7 +264,7 @@ static int intel_sst_mmap_play_capture(u32 str_id, stream->curr_bytes = 0; stream->cumm_bytes = 0; - pr_debug("sst:new buffers count %d status %d\n", + pr_debug("new buffers count %d status %d\n", mmap_buf->entries, stream->status); buf_entry = mmap_buf->buff; for (i = 0; i < mmap_buf->entries; i++) { @@ -291,13 +293,13 @@ static int intel_sst_mmap_play_capture(u32 str_id, stream->status = STREAM_RUNNING; if (stream->ops == STREAM_OPS_PLAYBACK) { if (sst_play_frame(str_id) < 0) { - pr_warn("sst: play frames fail\n"); + pr_warn("play frames fail\n"); mutex_unlock(&stream->lock); return -EIO; } } else if (stream->ops == STREAM_OPS_CAPTURE) { if (sst_capture_frame(str_id) < 0) { - pr_warn("sst: capture frame fail\n"); + pr_warn("capture frame fail\n"); mutex_unlock(&stream->lock); return -EIO; } @@ -313,7 +315,7 @@ static int intel_sst_mmap_play_capture(u32 str_id, if (retval >= 0) retval = stream->cumm_bytes; - pr_debug("sst:end of play/rec ioctl bytes = %d!!\n", retval); + pr_debug("end of play/rec ioctl bytes = %d!!\n", retval); return retval; } @@ -335,7 +337,7 @@ static int intel_sst_play_capture(struct stream_info *stream, int str_id) if (stream->status == STREAM_INIT && stream->prev == STREAM_UN_INIT) { /* stream is not started yet */ - pr_debug("sst: Stream isn't in started state %d, prev %d\n", + pr_debug("Stream isn't in started state %d, prev %d\n", stream->status, stream->prev); } else if ((stream->status == STREAM_RUNNING || stream->status == STREAM_PAUSED) && @@ -344,13 +346,13 @@ static int intel_sst_play_capture(struct stream_info *stream, int str_id) if (stream->ops == STREAM_OPS_PLAYBACK || stream->ops == STREAM_OPS_PLAYBACK_DRM) { if (sst_play_frame(str_id) < 0) { - pr_warn("sst: play frames failed\n"); + pr_warn("play frames failed\n"); mutex_unlock(&stream->lock); return -EIO; } } else if (stream->ops == STREAM_OPS_CAPTURE) { if (sst_capture_frame(str_id) < 0) { - pr_warn("sst: capture frames failed\n "); + pr_warn("capture frames failed\n"); mutex_unlock(&stream->lock); return -EIO; } @@ -365,7 +367,7 @@ static int intel_sst_play_capture(struct stream_info *stream, int str_id) retval = sst_wait_interruptible(sst_drv_ctx, &stream->data_blk); if (retval) { stream->status = STREAM_INIT; - pr_debug("sst: wait returned error...\n"); + pr_debug("wait returned error...\n"); } return retval; } @@ -463,7 +465,7 @@ static int snd_sst_fill_kernel_list(struct stream_info *stream, if (((unsigned long)iovec[index].iov_base + iovec[index].iov_len) < ((unsigned long)iovec[index].iov_base)) { - pr_debug("sst: Buffer overflows"); + pr_debug("Buffer overflows\n"); kfree(stream_bufs); return -EINVAL; } @@ -476,7 +478,7 @@ static int snd_sst_fill_kernel_list(struct stream_info *stream, } copied_size += size; - pr_debug("sst: copied_size - %lx\n", copied_size); + pr_debug("copied_size - %lx\n", copied_size); if ((copied_size >= mmap_len) || (stream->sg_index == nr_segs)) { add_to_list = 1; @@ -506,7 +508,7 @@ static int snd_sst_copy_userbuf_capture(struct stream_info *stream, int retval = 0; /* copy sent buffers */ - pr_debug("sst: capture stream copying to user now...\n"); + pr_debug("capture stream copying to user now...\n"); list_for_each_entry_safe(kbufs, _kbufs, &stream->bufs, node) { if (kbufs->in_use == true) { /* copy to user */ @@ -526,7 +528,7 @@ static int snd_sst_copy_userbuf_capture(struct stream_info *stream, } } } - pr_debug("sst: end of cap copy\n"); + pr_debug("end of cap copy\n"); return retval; } @@ -578,7 +580,7 @@ static int intel_sst_read_write(unsigned int str_id, char __user *buf, return -EINVAL; stream = &sst_drv_ctx->streams[str_id]; if (stream->mmapped == true) { - pr_warn("sst: user write and stream is mapped"); + pr_warn("user write and stream is mapped\n"); return -EIO; } if (!count) @@ -586,7 +588,7 @@ static int intel_sst_read_write(unsigned int str_id, char __user *buf, stream->curr_bytes = 0; stream->cumm_bytes = 0; /* copy user buf details */ - pr_debug("sst: new buffers %p, copy size %d, status %d\n" , + pr_debug("new buffers %p, copy size %d, status %d\n" , buf, (int) count, (int) stream->status); stream->buf_type = SST_BUF_USER_STATIC; @@ -606,7 +608,7 @@ static int intel_sst_read_write(unsigned int str_id, char __user *buf, stream->cur_ptr = NULL; if (retval >= 0) retval = stream->cumm_bytes; - pr_debug("sst: end of play/rec bytes = %d!!\n", retval); + pr_debug("end of play/rec bytes = %d!!\n", retval); return retval; } @@ -627,7 +629,7 @@ int intel_sst_write(struct file *file_ptr, const char __user *buf, int str_id = data->str_id; struct stream_info *stream = &sst_drv_ctx->streams[str_id]; - pr_debug("sst: called for %d\n", str_id); + pr_debug("called for %d\n", str_id); if (stream->status == STREAM_UN_INIT || stream->status == STREAM_DECODE) { return -EBADRQC; @@ -653,12 +655,12 @@ ssize_t intel_sst_aio_write(struct kiocb *kiocb, const struct iovec *iov, int str_id = data->str_id; struct stream_info *stream; - pr_debug("sst: entry - %ld\n", nr_segs); + pr_debug("entry - %ld\n", nr_segs); if (is_sync_kiocb(kiocb) == false) return -EINVAL; - pr_debug("sst: called for str_id %d\n", str_id); + pr_debug("called for str_id %d\n", str_id); retval = sst_validate_strid(str_id); if (retval) return -EINVAL; @@ -671,7 +673,7 @@ ssize_t intel_sst_aio_write(struct kiocb *kiocb, const struct iovec *iov, } stream->curr_bytes = 0; stream->cumm_bytes = 0; - pr_debug("sst: new segs %ld, offset %d, status %d\n" , + pr_debug("new segs %ld, offset %d, status %d\n" , nr_segs, (int) offset, (int) stream->status); stream->buf_type = SST_BUF_USER_STATIC; do { @@ -686,7 +688,7 @@ ssize_t intel_sst_aio_write(struct kiocb *kiocb, const struct iovec *iov, stream->cur_ptr = NULL; if (retval >= 0) retval = stream->cumm_bytes; - pr_debug("sst: end of play/rec bytes = %d!!\n", retval); + pr_debug("end of play/rec bytes = %d!!\n", retval); return retval; } @@ -707,7 +709,7 @@ int intel_sst_read(struct file *file_ptr, char __user *buf, int str_id = data->str_id; struct stream_info *stream = &sst_drv_ctx->streams[str_id]; - pr_debug("sst: called for %d\n", str_id); + pr_debug("called for %d\n", str_id); if (stream->status == STREAM_UN_INIT || stream->status == STREAM_DECODE) return -EBADRQC; @@ -732,14 +734,14 @@ ssize_t intel_sst_aio_read(struct kiocb *kiocb, const struct iovec *iov, int str_id = data->str_id; struct stream_info *stream; - pr_debug("sst: entry - %ld\n", nr_segs); + pr_debug("entry - %ld\n", nr_segs); if (is_sync_kiocb(kiocb) == false) { - pr_debug("sst: aio_read from user space is not allowed\n"); + pr_debug("aio_read from user space is not allowed\n"); return -EINVAL; } - pr_debug("sst: called for str_id %d\n", str_id); + pr_debug("called for str_id %d\n", str_id); retval = sst_validate_strid(str_id); if (retval) return -EINVAL; @@ -752,7 +754,7 @@ ssize_t intel_sst_aio_read(struct kiocb *kiocb, const struct iovec *iov, stream->curr_bytes = 0; stream->cumm_bytes = 0; - pr_debug("sst: new segs %ld, offset %d, status %d\n" , + pr_debug("new segs %ld, offset %d, status %d\n" , nr_segs, (int) offset, (int) stream->status); stream->buf_type = SST_BUF_USER_STATIC; do { @@ -767,34 +769,34 @@ ssize_t intel_sst_aio_read(struct kiocb *kiocb, const struct iovec *iov, stream->cur_ptr = NULL; if (retval >= 0) retval = stream->cumm_bytes; - pr_debug("sst: end of play/rec bytes = %d!!\n", retval); + pr_debug("end of play/rec bytes = %d!!\n", retval); return retval; } /* sst_print_stream_params - prints the stream parameters (debug fn)*/ static void sst_print_stream_params(struct snd_sst_get_stream_params *get_prm) { - pr_debug("sst: codec params:result =%d\n", + pr_debug("codec params:result = %d\n", get_prm->codec_params.result); - pr_debug("sst: codec params:stream = %d\n", + pr_debug("codec params:stream = %d\n", get_prm->codec_params.stream_id); - pr_debug("sst: codec params:codec = %d\n", + pr_debug("codec params:codec = %d\n", get_prm->codec_params.codec); - pr_debug("sst: codec params:ops = %d\n", + pr_debug("codec params:ops = %d\n", get_prm->codec_params.ops); - pr_debug("sst: codec params:stream_type= %d\n", + pr_debug("codec params:stream_type = %d\n", get_prm->codec_params.stream_type); - pr_debug("sst: pcmparams:sfreq= %d\n", + pr_debug("pcmparams:sfreq = %d\n", get_prm->pcm_params.sfreq); - pr_debug("sst: pcmparams:num_chan= %d\n", + pr_debug("pcmparams:num_chan = %d\n", get_prm->pcm_params.num_chan); - pr_debug("sst: pcmparams:pcm_wd_sz= %d\n", + pr_debug("pcmparams:pcm_wd_sz = %d\n", get_prm->pcm_params.pcm_wd_sz); return; } /** - * intel_sst_ioctl - recieves the device ioctl's + * intel_sst_ioctl - receives the device ioctl's * @file_ptr:pointer to file * @cmd:Ioctl cmd * @arg:data @@ -820,7 +822,7 @@ long intel_sst_ioctl(struct file *file_ptr, unsigned int cmd, unsigned long arg) switch (_IOC_NR(cmd)) { case _IOC_NR(SNDRV_SST_STREAM_PAUSE): - pr_debug("sst: IOCTL_PAUSE recieved for %d!\n", str_id); + pr_debug("IOCTL_PAUSE received for %d!\n", str_id); if (minor != STREAM_MODULE) { retval = -EBADRQC; break; @@ -829,7 +831,7 @@ long intel_sst_ioctl(struct file *file_ptr, unsigned int cmd, unsigned long arg) break; case _IOC_NR(SNDRV_SST_STREAM_RESUME): - pr_debug("sst: SNDRV_SST_IOCTL_RESUME recieved!\n"); + pr_debug("SNDRV_SST_IOCTL_RESUME received!\n"); if (minor != STREAM_MODULE) { retval = -EBADRQC; break; @@ -840,7 +842,7 @@ long intel_sst_ioctl(struct file *file_ptr, unsigned int cmd, unsigned long arg) case _IOC_NR(SNDRV_SST_STREAM_SET_PARAMS): { struct snd_sst_params *str_param = (struct snd_sst_params *)arg; - pr_debug("sst: IOCTL_SET_PARAMS recieved!\n"); + pr_debug("IOCTL_SET_PARAMS received!\n"); if (minor != STREAM_MODULE) { retval = -EBADRQC; break; @@ -864,7 +866,7 @@ long intel_sst_ioctl(struct file *file_ptr, unsigned int cmd, unsigned long arg) retval = -EINVAL; } } else { - pr_debug("sst: SET_STREAM_PARAMS recieved!\n"); + pr_debug("SET_STREAM_PARAMS received!\n"); /* allocated set params only */ retval = sst_set_stream_param(str_id, str_param); /* Block the call for reply */ @@ -887,21 +889,21 @@ long intel_sst_ioctl(struct file *file_ptr, unsigned int cmd, unsigned long arg) case _IOC_NR(SNDRV_SST_SET_VOL): { struct snd_sst_vol *set_vol; struct snd_sst_vol *rec_vol = (struct snd_sst_vol *)arg; - pr_debug("sst: SET_VOLUME recieved for %d!\n", + pr_debug("SET_VOLUME received for %d!\n", rec_vol->stream_id); if (minor == STREAM_MODULE && rec_vol->stream_id == 0) { - pr_debug("sst: invalid operation!\n"); + pr_debug("invalid operation!\n"); retval = -EPERM; break; } set_vol = kzalloc(sizeof(*set_vol), GFP_ATOMIC); if (!set_vol) { - pr_debug("sst: mem allocation failed\n"); + pr_debug("mem allocation failed\n"); retval = -ENOMEM; break; } if (copy_from_user(set_vol, rec_vol, sizeof(*set_vol))) { - pr_debug("sst: copy failed\n"); + pr_debug("copy failed\n"); retval = -EFAULT; break; } @@ -912,10 +914,10 @@ long intel_sst_ioctl(struct file *file_ptr, unsigned int cmd, unsigned long arg) case _IOC_NR(SNDRV_SST_GET_VOL): { struct snd_sst_vol *rec_vol = (struct snd_sst_vol *)arg; struct snd_sst_vol get_vol; - pr_debug("sst: IOCTL_GET_VOLUME recieved for stream = %d!\n", + pr_debug("IOCTL_GET_VOLUME received for stream = %d!\n", rec_vol->stream_id); if (minor == STREAM_MODULE && rec_vol->stream_id == 0) { - pr_debug("sst: invalid operation!\n"); + pr_debug("invalid operation!\n"); retval = -EPERM; break; } @@ -925,7 +927,7 @@ long intel_sst_ioctl(struct file *file_ptr, unsigned int cmd, unsigned long arg) retval = -EIO; break; } - pr_debug("sst: id:%d\n, vol:%d, ramp_dur:%d, ramp_type:%d\n", + pr_debug("id:%d\n, vol:%d, ramp_dur:%d, ramp_type:%d\n", get_vol.stream_id, get_vol.volume, get_vol.ramp_duration, get_vol.ramp_type); if (copy_to_user((struct snd_sst_vol *)arg, @@ -940,7 +942,7 @@ long intel_sst_ioctl(struct file *file_ptr, unsigned int cmd, unsigned long arg) case _IOC_NR(SNDRV_SST_MUTE): { struct snd_sst_mute *set_mute; struct snd_sst_vol *rec_mute = (struct snd_sst_vol *)arg; - pr_debug("sst: SNDRV_SST_SET_VOLUME recieved for %d!\n", + pr_debug("SNDRV_SST_SET_VOLUME received for %d!\n", rec_mute->stream_id); if (minor == STREAM_MODULE && rec_mute->stream_id == 0) { retval = -EPERM; @@ -962,7 +964,7 @@ long intel_sst_ioctl(struct file *file_ptr, unsigned int cmd, unsigned long arg) case _IOC_NR(SNDRV_SST_STREAM_GET_PARAMS): { struct snd_sst_get_stream_params get_params; - pr_debug("sst: IOCTL_GET_PARAMS recieved!\n"); + pr_debug("IOCTL_GET_PARAMS received!\n"); if (minor != 0) { retval = -EBADRQC; break; @@ -984,7 +986,7 @@ long intel_sst_ioctl(struct file *file_ptr, unsigned int cmd, unsigned long arg) case _IOC_NR(SNDRV_SST_MMAP_PLAY): case _IOC_NR(SNDRV_SST_MMAP_CAPTURE): - pr_debug("sst: SNDRV_SST_MMAP_PLAY/CAPTURE recieved!\n"); + pr_debug("SNDRV_SST_MMAP_PLAY/CAPTURE received!\n"); if (minor != STREAM_MODULE) { retval = -EBADRQC; break; @@ -994,7 +996,7 @@ long intel_sst_ioctl(struct file *file_ptr, unsigned int cmd, unsigned long arg) break; case _IOC_NR(SNDRV_SST_STREAM_DROP): - pr_debug("sst: SNDRV_SST_IOCTL_DROP recieved!\n"); + pr_debug("SNDRV_SST_IOCTL_DROP received!\n"); if (minor != STREAM_MODULE) { retval = -EINVAL; break; @@ -1007,7 +1009,7 @@ long intel_sst_ioctl(struct file *file_ptr, unsigned int cmd, unsigned long arg) struct snd_sst_tstamp tstamp = {0}; unsigned long long time, freq, mod; - pr_debug("sst: SNDRV_SST_STREAM_GET_TSTAMP recieved!\n"); + pr_debug("SNDRV_SST_STREAM_GET_TSTAMP received!\n"); if (minor != STREAM_MODULE) { retval = -EBADRQC; break; @@ -1028,7 +1030,7 @@ long intel_sst_ioctl(struct file *file_ptr, unsigned int cmd, unsigned long arg) case _IOC_NR(SNDRV_SST_STREAM_START):{ struct stream_info *stream; - pr_debug("sst: SNDRV_SST_STREAM_START recieved!\n"); + pr_debug("SNDRV_SST_STREAM_START received!\n"); if (minor != STREAM_MODULE) { retval = -EINVAL; break; @@ -1067,7 +1069,7 @@ long intel_sst_ioctl(struct file *file_ptr, unsigned int cmd, unsigned long arg) case _IOC_NR(SNDRV_SST_SET_TARGET_DEVICE): { struct snd_sst_target_device *target_device; - pr_debug("sst: SET_TARGET_DEVICE recieved!\n"); + pr_debug("SET_TARGET_DEVICE received!\n"); target_device = (struct snd_sst_target_device *)arg; BUG_ON(!target_device); if (minor != AM_MODULE) { @@ -1082,7 +1084,7 @@ long intel_sst_ioctl(struct file *file_ptr, unsigned int cmd, unsigned long arg) struct snd_sst_driver_info *info = (struct snd_sst_driver_info *)arg; - pr_debug("sst: SNDRV_SST_DRIVER_INFO recived\n"); + pr_debug("SNDRV_SST_DRIVER_INFO received\n"); info->version = SST_VERSION_NUM; /* hard coding, shud get sumhow later */ info->active_pcm_streams = sst_drv_ctx->stream_cnt - @@ -1102,7 +1104,7 @@ long intel_sst_ioctl(struct file *file_ptr, unsigned int cmd, unsigned long arg) struct snd_sst_buff_entry ibuf_temp[param->ibufs->entries], obuf_temp[param->obufs->entries]; - pr_debug("sst: SNDRV_SST_STREAM_DECODE recived\n"); + pr_debug("SNDRV_SST_STREAM_DECODE received\n"); if (minor != STREAM_MODULE) { retval = -EBADRQC; break; @@ -1155,7 +1157,7 @@ long intel_sst_ioctl(struct file *file_ptr, unsigned int cmd, unsigned long arg) } case _IOC_NR(SNDRV_SST_STREAM_DRAIN): - pr_debug("sst: SNDRV_SST_STREAM_DRAIN recived\n"); + pr_debug("SNDRV_SST_STREAM_DRAIN received\n"); if (minor != STREAM_MODULE) { retval = -EINVAL; break; @@ -1167,7 +1169,7 @@ long intel_sst_ioctl(struct file *file_ptr, unsigned int cmd, unsigned long arg) unsigned long long *bytes = (unsigned long long *)arg; struct snd_sst_tstamp tstamp = {0}; - pr_debug("sst: STREAM_BYTES_DECODED recieved!\n"); + pr_debug("STREAM_BYTES_DECODED received!\n"); if (minor != STREAM_MODULE) { retval = -EINVAL; break; @@ -1184,7 +1186,7 @@ long intel_sst_ioctl(struct file *file_ptr, unsigned int cmd, unsigned long arg) case _IOC_NR(SNDRV_SST_FW_INFO): { struct snd_sst_fw_info *fw_info; - pr_debug("sst: SNDRV_SST_FW_INFO recived\n"); + pr_debug("SNDRV_SST_FW_INFO received\n"); fw_info = kzalloc(sizeof(*fw_info), GFP_ATOMIC); if (!fw_info) { @@ -1210,7 +1212,7 @@ long intel_sst_ioctl(struct file *file_ptr, unsigned int cmd, unsigned long arg) default: retval = -EINVAL; } - pr_debug("sst: intel_sst_ioctl:complete ret code = %d\n", retval); + pr_debug("intel_sst_ioctl:complete ret code = %d\n", retval); return retval; } diff --git a/drivers/staging/intel_sst/intel_sst_drv_interface.c b/drivers/staging/intel_sst/intel_sst_drv_interface.c index 669e298016f2..5b10ddf60092 100644 --- a/drivers/staging/intel_sst/intel_sst_drv_interface.c +++ b/drivers/staging/intel_sst/intel_sst_drv_interface.c @@ -26,6 +26,8 @@ * Upper layer interfaces (MAD driver, MMF) to SST driver */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -52,10 +54,10 @@ int sst_download_fw(void) name = SST_FW_FILENAME_MRST; else name = SST_FW_FILENAME_MFLD; - pr_debug("sst: Downloading %s FW now...\n", name); + pr_debug("Downloading %s FW now...\n", name); retval = request_firmware(&fw_sst, name, &sst_drv_ctx->pci->dev); if (retval) { - pr_err("sst: request fw failed %d\n", retval); + pr_err("request fw failed %d\n", retval); return retval; } sst_drv_ctx->alloc_block[0].sst_id = FW_DWNL_ID; @@ -66,7 +68,7 @@ int sst_download_fw(void) retval = sst_wait_timeout(sst_drv_ctx, &sst_drv_ctx->alloc_block[0]); if (retval) - pr_err("sst: fw download failed %d\n" , retval); + pr_err("fw download failed %d\n" , retval); end_restore: release_firmware(fw_sst); sst_drv_ctx->alloc_block[0].sst_id = BLOCK_UNINIT; @@ -90,7 +92,7 @@ int sst_stalled(void) retry--; } - pr_debug("sst: in Stalled State\n"); + pr_debug("in Stalled State\n"); return retval; } @@ -138,23 +140,23 @@ int sst_get_stream_allocated(struct snd_sst_params *str_param, retval = sst_alloc_stream((char *) &str_param->sparams, str_param->ops, str_param->codec, str_param->device_type); if (retval < 0) { - pr_err("sst: sst_alloc_stream failed %d\n", retval); + pr_err("sst_alloc_stream failed %d\n", retval); return retval; } - pr_debug("sst: Stream allocated %d\n", retval); + pr_debug("Stream allocated %d\n", retval); str_id = retval; str_info = &sst_drv_ctx->streams[str_id]; /* Block the call for reply */ retval = sst_wait_interruptible_timeout(sst_drv_ctx, &str_info->ctrl_blk, SST_BLOCK_TIMEOUT); if ((retval != 0) || (str_info->ctrl_blk.ret_code != 0)) { - pr_debug("sst: FW alloc failed retval %d, ret_code %d\n", + pr_debug("FW alloc failed retval %d, ret_code %d\n", retval, str_info->ctrl_blk.ret_code); str_id = -str_info->ctrl_blk.ret_code; /*return error*/ *lib_dnld = str_info->ctrl_blk.data; sst_clean_stream(str_info); } else - pr_debug("sst: FW Stream allocated sucess\n"); + pr_debug("FW Stream allocated success\n"); return str_id; /*will ret either error (in above if) or correct str id*/ } @@ -196,14 +198,14 @@ int sst_get_stream(struct snd_sst_params *str_param) /* codec download is required */ struct snd_sst_alloc_response *response; - pr_debug("sst: Codec is required.... trying that\n"); + pr_debug("Codec is required.... trying that\n"); if (lib_dnld == NULL) { - pr_err("sst: lib download null!!! abort\n"); + pr_err("lib download null!!! abort\n"); return -EIO; } i = sst_get_block_stream(sst_drv_ctx); response = sst_drv_ctx->alloc_block[i].ops_block.data; - pr_debug("sst: alloc block allocated = %d\n", i); + pr_debug("alloc block allocated = %d\n", i); if (i < 0) { kfree(lib_dnld); return -ENOMEM; @@ -213,15 +215,15 @@ int sst_get_stream(struct snd_sst_params *str_param) sst_drv_ctx->alloc_block[i].sst_id = BLOCK_UNINIT; if (!retval) { - pr_debug("sst: codec was downloaded sucesfully\n"); + pr_debug("codec was downloaded successfully\n"); retval = sst_get_stream_allocated(str_param, &lib_dnld); if (retval <= 0) goto err; - pr_debug("sst: Alloc done stream id %d\n", retval); + pr_debug("Alloc done stream id %d\n", retval); } else { - pr_debug("sst: codec download failed\n"); + pr_debug("codec download failed\n"); retval = -EIO; goto err; } @@ -279,10 +281,10 @@ void sst_process_mad_ops(struct work_struct *work) retval = sst_start_stream(mad_ops->stream_id); break; case SST_SND_STREAM_PROCESS: - pr_debug("sst: play/capt frames...\n"); + pr_debug("play/capt frames...\n"); break; default: - pr_err("sst: wrong control_ops reported\n"); + pr_err(" wrong control_ops reported\n"); } return; } @@ -301,19 +303,19 @@ int sst_control_set(int control_element, void *value) if (sst_drv_ctx->sst_state == SST_SUSPENDED) { /*LPE is suspended, resume it before proceding*/ - pr_debug("sst: Resuming from Suspended state\n"); + pr_debug("Resuming from Suspended state\n"); retval = intel_sst_resume(sst_drv_ctx->pci); if (retval) { - pr_err("sst: Resume Failed = %#x, abort\n", retval); + pr_err("Resume Failed = %#x, abort\n", retval); return retval; } } if (sst_drv_ctx->sst_state == SST_UN_INIT) { /* FW is not downloaded */ - pr_debug("sst: DSP Downloading FW now...\n"); + pr_debug("DSP Downloading FW now...\n"); retval = sst_download_fw(); if (retval) { - pr_err("sst: FW download fail %x, abort\n", retval); + pr_err("FW download fail %x, abort\n", retval); return retval; } if (sst_drv_ctx->pci_id == SST_MRST_PCI_ID && @@ -361,7 +363,7 @@ int sst_control_set(int control_element, void *value) struct pcm_stream_info *str_info; struct stream_info *stream; - pr_debug("sst: stream init called\n"); + pr_debug("stream init called\n"); str_info = (struct pcm_stream_info *)value; str_id = str_info->str_id; retval = sst_validate_strid(str_id); @@ -369,7 +371,7 @@ int sst_control_set(int control_element, void *value) break; stream = &sst_drv_ctx->streams[str_id]; - pr_debug("sst: setting the period ptrs\n"); + pr_debug("setting the period ptrs\n"); stream->pcm_substream = str_info->mad_substream; stream->period_elapsed = str_info->period_elapsed; stream->sfreq = str_info->sfreq; @@ -398,14 +400,14 @@ int sst_control_set(int control_element, void *value) +(str_id * sizeof(fw_tstamp))), sizeof(fw_tstamp)); - pr_debug("sst: Pointer Query on strid = %d ops %d\n", + pr_debug("Pointer Query on strid = %d ops %d\n", str_id, stream->ops); if (stream->ops == STREAM_OPS_PLAYBACK) stream_info->buffer_ptr = fw_tstamp.samples_rendered; else stream_info->buffer_ptr = fw_tstamp.samples_processed; - pr_debug("sst: Samples rendered = %llu, buffer ptr %llu\n", + pr_debug("Samples rendered = %llu, buffer ptr %llu\n", fw_tstamp.samples_rendered, stream_info->buffer_ptr); break; } @@ -417,7 +419,7 @@ int sst_control_set(int control_element, void *value) } default: /* Illegal case */ - pr_warn("sst: illegal req\n"); + pr_warn("illegal req\n"); return -EINVAL; } @@ -439,12 +441,12 @@ struct intel_sst_card_ops sst_pmic_ops = { int register_sst_card(struct intel_sst_card_ops *card) { if (!sst_drv_ctx) { - pr_err("sst: No SST driver register card reject\n"); + pr_err("No SST driver register card reject\n"); return -ENODEV; } if (!card || !card->module_name) { - pr_err("sst: Null Pointer Passed\n"); + pr_err("Null Pointer Passed\n"); return -EINVAL; } if (sst_drv_ctx->pmic_state == SND_MAD_UN_INIT) { @@ -460,13 +462,13 @@ int register_sst_card(struct intel_sst_card_ops *card) sst_drv_ctx->scard_ops->card_status = SND_CARD_UN_INIT; return 0; } else { - pr_err("sst: strcmp fail %s\n", card->module_name); + pr_err("strcmp fail %s\n", card->module_name); return -EINVAL; } } else { /* already registered a driver */ - pr_err("sst: Repeat for registeration..denied\n"); + pr_err("Repeat for registration..denied\n"); return -EBADRQC; } return 0; @@ -486,7 +488,7 @@ void unregister_sst_card(struct intel_sst_card_ops *card) /* unreg */ sst_pmic_ops.module_name = ""; sst_drv_ctx->pmic_state = SND_MAD_UN_INIT; - pr_debug("sst: Unregistered %s\n", card->module_name); + pr_debug("Unregistered %s\n", card->module_name); } return; } diff --git a/drivers/staging/intel_sst/intel_sst_dsp.c b/drivers/staging/intel_sst/intel_sst_dsp.c index d80a6ee2deb8..d1b0537cf4b8 100644 --- a/drivers/staging/intel_sst/intel_sst_dsp.c +++ b/drivers/staging/intel_sst/intel_sst_dsp.c @@ -29,6 +29,9 @@ * This file contains all dsp controlling functions like firmware download, * setting/resetting dsp cores, etc */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -47,7 +50,7 @@ static int intel_sst_reset_dsp_mrst(void) { union config_status_reg csr; - pr_debug("sst: Resetting the DSP in mrst\n"); + pr_debug("Resetting the DSP in mrst\n"); csr.full = 0x3a2; sst_shim_write(sst_drv_ctx->shim, SST_CSR, csr.full); csr.full = sst_shim_read(sst_drv_ctx->shim, SST_CSR); @@ -68,7 +71,7 @@ static int intel_sst_reset_dsp_medfield(void) { union config_status_reg csr; - pr_debug("sst: Resetting the DSP in medfield\n"); + pr_debug("Resetting the DSP in medfield\n"); csr.full = 0x048303E2; sst_shim_write(sst_drv_ctx->shim, SST_CSR, csr.full); @@ -90,7 +93,7 @@ static int sst_start_mrst(void) csr.part.run_stall = 0; csr.part.sst_reset = 0; csr.part.strb_cntr_rst = 1; - pr_debug("sst: Setting SST to execute_mrst 0x%x\n", csr.full); + pr_debug("Setting SST to execute_mrst 0x%x\n", csr.full); sst_shim_write(sst_drv_ctx->shim, SST_CSR, csr.full); return 0; @@ -111,7 +114,7 @@ static int sst_start_medfield(void) sst_shim_write(sst_drv_ctx->shim, SST_CSR, csr.full); csr.full = 0x04830061; sst_shim_write(sst_drv_ctx->shim, SST_CSR, csr.full); - pr_debug("sst: Starting the DSP_medfld\n"); + pr_debug("Starting the DSP_medfld\n"); return 0; } @@ -130,16 +133,16 @@ static int sst_parse_module(struct fw_module_header *module) u32 count; void __iomem *ram; - pr_debug("sst: module sign %s size %x blocks %x type %x\n", + pr_debug("module sign %s size %x blocks %x type %x\n", module->signature, module->mod_size, module->blocks, module->type); - pr_debug("sst: module entrypoint 0x%x\n", module->entry_point); + pr_debug("module entrypoint 0x%x\n", module->entry_point); block = (void *)module + sizeof(*module); for (count = 0; count < module->blocks; count++) { if (block->size <= 0) { - pr_err("sst: block size invalid\n"); + pr_err("block size invalid\n"); return -EINVAL; } switch (block->type) { @@ -150,7 +153,7 @@ static int sst_parse_module(struct fw_module_header *module) ram = sst_drv_ctx->dram; break; default: - pr_err("sst: wrong ram type0x%x in block0x%x\n", + pr_err("wrong ram type0x%x in block0x%x\n", block->type, count); return -EINVAL; } @@ -184,10 +187,10 @@ static int sst_parse_fw_image(const struct firmware *sst_fw) if ((strncmp(header->signature, SST_FW_SIGN, 4) != 0) || (sst_fw->size != header->file_size + sizeof(*header))) { /* Invalid FW signature */ - pr_err("sst: InvalidFW sign/filesize mismatch\n"); + pr_err("Invalid FW sign/filesize mismatch\n"); return -EINVAL; } - pr_debug("sst: header sign=%s size=%x modules=%x fmt=%x size=%x\n", + pr_debug("header sign=%s size=%x modules=%x fmt=%x size=%x\n", header->signature, header->file_size, header->modules, header->file_format, sizeof(*header)); module = (void *)sst_fw->data + sizeof(*header); @@ -214,7 +217,7 @@ int sst_load_fw(const struct firmware *fw, void *context) { int ret_val; - pr_debug("sst: load_fw called\n"); + pr_debug("load_fw called\n"); BUG_ON(!fw); if (sst_drv_ctx->pci_id == SST_MRST_PCI_ID) @@ -239,7 +242,7 @@ int sst_load_fw(const struct firmware *fw, void *context) if (ret_val) return ret_val; - pr_debug("sst: fw loaded successful!!!\n"); + pr_debug("fw loaded successful!!!\n"); return ret_val; } @@ -261,7 +264,7 @@ static int sst_download_library(const struct firmware *fw_lib, pvt_id = sst_assign_pvt_id(sst_drv_ctx); i = sst_get_block_stream(sst_drv_ctx); - pr_debug("sst: alloc block allocated = %d, pvt_id %d\n", i, pvt_id); + pr_debug("alloc block allocated = %d, pvt_id %d\n", i, pvt_id); if (i < 0) { kfree(msg); return -ENOMEM; @@ -281,11 +284,11 @@ static int sst_download_library(const struct firmware *fw_lib, if (retval) { /* error */ sst_drv_ctx->alloc_block[i].sst_id = BLOCK_UNINIT; - pr_err("sst: Prep codec downloaded failed %d\n", + pr_err("Prep codec downloaded failed %d\n", retval); return -EIO; } - pr_debug("sst: FW responded, ready for download now...\n"); + pr_debug("FW responded, ready for download now...\n"); /* downloading on success */ mutex_lock(&sst_drv_ctx->sst_lock); sst_drv_ctx->sst_state = SST_FW_LOADED; @@ -325,7 +328,7 @@ static int sst_download_library(const struct firmware *fw_lib, list_add_tail(&msg->node, &sst_drv_ctx->ipc_dispatch_list); spin_unlock(&sst_drv_ctx->list_spin_lock); sst_post_message(&sst_drv_ctx->ipc_post_msg_wq); - pr_debug("sst: Waiting for FW response Download complete\n"); + pr_debug("Waiting for FW response Download complete\n"); sst_drv_ctx->alloc_block[i].ops_block.condition = false; retval = sst_wait_timeout(sst_drv_ctx, &sst_drv_ctx->alloc_block[i]); if (retval) { @@ -337,7 +340,7 @@ static int sst_download_library(const struct firmware *fw_lib, return -EIO; } - pr_debug("sst: FW sucess on Download complete\n"); + pr_debug("FW success on Download complete\n"); sst_drv_ctx->alloc_block[i].sst_id = BLOCK_UNINIT; mutex_lock(&sst_drv_ctx->sst_lock); sst_drv_ctx->sst_state = SST_FW_RUNNING; @@ -360,14 +363,14 @@ static int sst_validate_library(const struct firmware *fw_lib, header = (struct fw_header *)fw_lib->data; if (header->modules != 1) { - pr_err("sst: Module no mismatch found\n "); + pr_err("Module no mismatch found\n"); err = -EINVAL; goto exit; } module = (void *)fw_lib->data + sizeof(*header); *entry_point = module->entry_point; - pr_debug("sst: Module entry point 0x%x\n", *entry_point); - pr_debug("sst: Module Sign %s, Size 0x%x, Blocks 0x%x Type 0x%x\n", + pr_debug("Module entry point 0x%x\n", *entry_point); + pr_debug("Module Sign %s, Size 0x%x, Blocks 0x%x Type 0x%x\n", module->signature, module->mod_size, module->blocks, module->type); @@ -381,20 +384,20 @@ static int sst_validate_library(const struct firmware *fw_lib, dsize += block->size; break; default: - pr_err("sst: Invalid block type for 0x%x\n", n_blk); + pr_err("Invalid block type for 0x%x\n", n_blk); err = -EINVAL; goto exit; } block = (void *)block + sizeof(*block) + block->size; } if (isize > slot->iram_size || dsize > slot->dram_size) { - pr_err("sst: library exceeds size allocated\n"); + pr_err("library exceeds size allocated\n"); err = -EINVAL; goto exit; } else - pr_debug("sst: Library is safe for download...\n"); + pr_debug("Library is safe for download...\n"); - pr_debug("sst: iram 0x%x, dram 0x%x, iram 0x%x, dram 0x%x\n", + pr_debug("iram 0x%x, dram 0x%x, iram 0x%x, dram 0x%x\n", isize, dsize, slot->iram_size, slot->dram_size); exit: return err; @@ -414,15 +417,15 @@ int sst_load_library(struct snd_sst_lib_download *lib, u8 ops) memset(buf, 0, sizeof(buf)); - pr_debug("sst: Lib Type 0x%x, Slot 0x%x, ops 0x%x\n", + pr_debug("Lib Type 0x%x, Slot 0x%x, ops 0x%x\n", lib->lib_info.lib_type, lib->slot_info.slot_num, ops); - pr_debug("sst: Version 0x%x, name %s, caps 0x%x media type 0x%x\n", + pr_debug("Version 0x%x, name %s, caps 0x%x media type 0x%x\n", lib->lib_info.lib_version, lib->lib_info.lib_name, lib->lib_info.lib_caps, lib->lib_info.media_type); - pr_debug("sst: IRAM Size 0x%x, offset 0x%x\n", + pr_debug("IRAM Size 0x%x, offset 0x%x\n", lib->slot_info.iram_size, lib->slot_info.iram_offset); - pr_debug("sst: DRAM Size 0x%x, offset 0x%x\n", + pr_debug("DRAM Size 0x%x, offset 0x%x\n", lib->slot_info.dram_size, lib->slot_info.dram_offset); switch (lib->lib_info.lib_type) { @@ -442,7 +445,7 @@ int sst_load_library(struct snd_sst_lib_download *lib, u8 ops) type = "wma9_"; break; default: - pr_err("sst: Invalid codec type\n"); + pr_err("Invalid codec type\n"); error = -EINVAL; goto wake; } @@ -458,11 +461,11 @@ int sst_load_library(struct snd_sst_lib_download *lib, u8 ops) lib->slot_info.slot_num); len += snprintf(buf + len, sizeof(buf) - len, ".bin"); - pr_debug("sst: Requesting %s\n", buf); + pr_debug("Requesting %s\n", buf); error = request_firmware(&fw_lib, buf, &sst_drv_ctx->pci->dev); if (error) { - pr_err("sst: library load failed %d\n", error); + pr_err("library load failed %d\n", error); goto wake; } error = sst_validate_library(fw_lib, &lib->slot_info, &entry_point); @@ -476,7 +479,7 @@ int sst_load_library(struct snd_sst_lib_download *lib, u8 ops) goto wake_free; /* lib is downloaded and init send alloc again */ - pr_debug("sst: Library is downloaded now...\n"); + pr_debug("Library is downloaded now...\n"); wake_free: /* sst_wake_up_alloc_block(sst_drv_ctx, pvt_id, error, NULL); */ release_firmware(fw_lib); diff --git a/drivers/staging/intel_sst/intel_sst_ipc.c b/drivers/staging/intel_sst/intel_sst_ipc.c index 39c67fa0bd0c..993c5333e906 100644 --- a/drivers/staging/intel_sst/intel_sst_ipc.c +++ b/drivers/staging/intel_sst/intel_sst_ipc.c @@ -26,6 +26,8 @@ * This file defines all ipc functions */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -75,16 +77,16 @@ void sst_post_message(struct work_struct *work) /*To check if LPE is in stalled state.*/ retval = sst_stalled(); if (retval < 0) { - pr_err("sst: in stalled state\n"); + pr_err("in stalled state\n"); return; } - pr_debug("sst: post message called\n"); + pr_debug("post message called\n"); spin_lock(&sst_drv_ctx->list_spin_lock); /* check list */ if (list_empty(&sst_drv_ctx->ipc_dispatch_list)) { /* list is empty, mask imr */ - pr_debug("sst: Empty msg queue... masking\n"); + pr_debug("Empty msg queue... masking\n"); imr.full = readl(sst_drv_ctx->shim + SST_IMRX); imr.part.done_interrupt = 1; /* dummy register for shim workaround */ @@ -97,7 +99,7 @@ void sst_post_message(struct work_struct *work) header.full = sst_shim_read(sst_drv_ctx->shim, SST_IPCX); if (header.part.busy) { /* busy, unmask */ - pr_debug("sst: Busy not free... unmasking\n"); + pr_debug("Busy not free... unmasking\n"); imr.full = readl(sst_drv_ctx->shim + SST_IMRX); imr.part.done_interrupt = 0; /* dummy register for shim workaround */ @@ -109,8 +111,8 @@ void sst_post_message(struct work_struct *work) msg = list_entry(sst_drv_ctx->ipc_dispatch_list.next, struct ipc_post, node); list_del(&msg->node); - pr_debug("sst: Post message: header = %x\n", msg->header.full); - pr_debug("sst: size: = %x\n", msg->header.part.data); + pr_debug("Post message: header = %x\n", msg->header.full); + pr_debug("size: = %x\n", msg->header.part.data); if (msg->header.part.large) memcpy_toio(sst_drv_ctx->mailbox + SST_MAILBOX_SEND, msg->mailbox_data, msg->header.part.data); @@ -166,13 +168,13 @@ int process_fw_init(struct sst_ipc_msg_wq *msg) (struct ipc_header_fw_init *)msg->mailbox; int retval = 0; - pr_debug("sst: *** FW Init msg came***\n"); + pr_debug("*** FW Init msg came***\n"); if (init->result) { mutex_lock(&sst_drv_ctx->sst_lock); sst_drv_ctx->sst_state = SST_ERROR; mutex_unlock(&sst_drv_ctx->sst_lock); - pr_debug("sst: FW Init failed, Error %x\n", init->result); - pr_err("sst: FW Init failed, Error %x\n", init->result); + pr_debug("FW Init failed, Error %x\n", init->result); + pr_err("FW Init failed, Error %x\n", init->result); retval = -init->result; return retval; } @@ -181,11 +183,11 @@ int process_fw_init(struct sst_ipc_msg_wq *msg) mutex_lock(&sst_drv_ctx->sst_lock); sst_drv_ctx->sst_state = SST_FW_RUNNING; mutex_unlock(&sst_drv_ctx->sst_lock); - pr_debug("sst: FW Version %x.%x\n", + pr_debug("FW Version %x.%x\n", init->fw_version.major, init->fw_version.minor); - pr_debug("sst: Build No %x Type %x\n", + pr_debug("Build No %x Type %x\n", init->fw_version.build, init->fw_version.type); - pr_debug("sst: Build date %s Time %s\n", + pr_debug(" Build date %s Time %s\n", init->build_info.date, init->build_info.time); sst_wake_up_alloc_block(sst_drv_ctx, FW_DWNL_ID, retval, NULL); return retval; @@ -204,19 +206,19 @@ void sst_process_message(struct work_struct *work) container_of(work, struct sst_ipc_msg_wq, wq); int str_id = msg->header.part.str_id; - pr_debug("sst: IPC process for %x\n", msg->header.full); + pr_debug("IPC process for %x\n", msg->header.full); /* based on msg in list call respective handler */ switch (msg->header.part.msg_id) { case IPC_SST_BUF_UNDER_RUN: case IPC_SST_BUF_OVER_RUN: if (sst_validate_strid(str_id)) { - pr_err("sst: stream id %d invalid\n", str_id); + pr_err("stream id %d invalid\n", str_id); break; } - pr_err("sst: Buffer under/overrun for%d\n", + pr_err("Buffer under/overrun for %d\n", msg->header.part.str_id); - pr_err("sst: Got Underrun & not to send data...ignore\n"); + pr_err("Got Underrun & not to send data...ignore\n"); break; case IPC_SST_GET_PLAY_FRAMES: @@ -224,35 +226,35 @@ void sst_process_message(struct work_struct *work) struct stream_info *stream ; if (sst_validate_strid(str_id)) { - pr_err("sst: strid %d invalid\n", str_id); + pr_err("strid %d invalid\n", str_id); break; } /* call sst_play_frame */ stream = &sst_drv_ctx->streams[str_id]; - pr_debug("sst: sst_play_frames for %d\n", + pr_debug("sst_play_frames for %d\n", msg->header.part.str_id); mutex_lock(&sst_drv_ctx->streams[str_id].lock); sst_play_frame(msg->header.part.str_id); mutex_unlock(&sst_drv_ctx->streams[str_id].lock); break; } else - pr_err("sst: sst_play_frames for Penwell!!\n"); + pr_err("sst_play_frames for Penwell!!\n"); case IPC_SST_GET_CAPT_FRAMES: if (sst_drv_ctx->pci_id == SST_MRST_PCI_ID) { struct stream_info *stream; /* call sst_capture_frame */ if (sst_validate_strid(str_id)) { - pr_err("sst: str id %d invalid\n", str_id); + pr_err("str id %d invalid\n", str_id); break; } stream = &sst_drv_ctx->streams[str_id]; - pr_debug("sst: sst_capture_frames for %d\n", + pr_debug("sst_capture_frames for %d\n", msg->header.part.str_id); mutex_lock(&stream->lock); if (stream->mmapped == false && stream->src == SST_DRV) { - pr_debug("sst: waking up block for copy.\n"); + pr_debug("waking up block for copy.\n"); stream->data_blk.ret_code = 0; stream->data_blk.condition = true; stream->data_blk.on = false; @@ -261,11 +263,11 @@ void sst_process_message(struct work_struct *work) sst_capture_frame(msg->header.part.str_id); mutex_unlock(&stream->lock); } else - pr_err("sst: sst_play_frames for Penwell!!\n"); + pr_err("sst_play_frames for Penwell!!\n"); break; case IPC_IA_PRINT_STRING: - pr_debug("sst: been asked to print something by fw\n"); + pr_debug("been asked to print something by fw\n"); /* TBD */ break; @@ -277,12 +279,12 @@ void sst_process_message(struct work_struct *work) case IPC_SST_STREAM_PROCESS_FATAL_ERR: if (sst_validate_strid(str_id)) { - pr_err("sst: stream id %d invalid\n", str_id); + pr_err("stream id %d invalid\n", str_id); break; } - pr_err("sst: codec fatal error %x stream %d...\n", + pr_err("codec fatal error %x stream %d...\n", msg->header.full, msg->header.part.str_id); - pr_err("sst: Dropping the stream\n"); + pr_err("Dropping the stream\n"); sst_drop_stream(msg->header.part.str_id); break; case IPC_IA_LPE_GETTING_STALLED: @@ -293,7 +295,7 @@ void sst_process_message(struct work_struct *work) break; default: /* Illegal case */ - pr_err("sst: Unhandled msg %x header %x\n", + pr_err("Unhandled msg %x header %x\n", msg->header.part.msg_id, msg->header.full); } sst_clear_interrupt(); @@ -322,7 +324,7 @@ void sst_process_reply(struct work_struct *work) if (!msg->header.part.data) { sst_drv_ctx->tgt_dev_blk.ret_code = 0; } else { - pr_err("sst: Msg %x reply error %x\n", + pr_err(" Msg %x reply error %x\n", msg->header.part.msg_id, msg->header.part.data); sst_drv_ctx->tgt_dev_blk.ret_code = -msg->header.part.data; @@ -340,7 +342,7 @@ void sst_process_reply(struct work_struct *work) int major = fw_info->fw_version.major; int minor = fw_info->fw_version.minor; int build = fw_info->fw_version.build; - pr_debug("sst: Msg succedded %x\n", + pr_debug("Msg succeeded %x\n", msg->header.part.msg_id); pr_debug("INFO: ***FW*** = %02d.%02d.%02d\n", major, minor, build); @@ -349,13 +351,13 @@ void sst_process_reply(struct work_struct *work) sizeof(struct snd_sst_fw_info)); sst_drv_ctx->fw_info_blk.ret_code = 0; } else { - pr_err("sst: Msg %x reply error %x\n", + pr_err(" Msg %x reply error %x\n", msg->header.part.msg_id, msg->header.part.data); sst_drv_ctx->fw_info_blk.ret_code = -msg->header.part.data; } if (sst_drv_ctx->fw_info_blk.on == true) { - pr_debug("sst: Memcopy succedded\n"); + pr_debug("Memcopy succeeded\n"); sst_drv_ctx->fw_info_blk.on = false; sst_drv_ctx->fw_info_blk.condition = true; wake_up(&sst_drv_ctx->wait_queue); @@ -364,11 +366,11 @@ void sst_process_reply(struct work_struct *work) } case IPC_IA_SET_STREAM_MUTE: if (!msg->header.part.data) { - pr_debug("sst: Msg succedded %x\n", + pr_debug("Msg succeeded %x\n", msg->header.part.msg_id); sst_drv_ctx->mute_info_blk.ret_code = 0; } else { - pr_err("sst: Msg %x reply error %x\n", + pr_err(" Msg %x reply error %x\n", msg->header.part.msg_id, msg->header.part.data); sst_drv_ctx->mute_info_blk.ret_code = -msg->header.part.data; @@ -382,11 +384,11 @@ void sst_process_reply(struct work_struct *work) break; case IPC_IA_SET_STREAM_VOL: if (!msg->header.part.data) { - pr_debug("sst: Msg succedded %x\n", + pr_debug("Msg succeeded %x\n", msg->header.part.msg_id); sst_drv_ctx->vol_info_blk.ret_code = 0; } else { - pr_err("sst: Msg %x reply error %x\n", + pr_err(" Msg %x reply error %x\n", msg->header.part.msg_id, msg->header.part.data); sst_drv_ctx->vol_info_blk.ret_code = @@ -402,15 +404,15 @@ void sst_process_reply(struct work_struct *work) break; case IPC_IA_GET_STREAM_VOL: if (msg->header.part.large) { - pr_debug("sst: Large Msg Received Successfully\n"); - pr_debug("sst: Msg succedded %x\n", + pr_debug("Large Msg Received Successfully\n"); + pr_debug("Msg succeeded %x\n", msg->header.part.msg_id); memcpy_fromio(sst_drv_ctx->vol_info_blk.data, (void *) msg->mailbox, sizeof(struct snd_sst_vol)); sst_drv_ctx->vol_info_blk.ret_code = 0; } else { - pr_err("sst: Msg %x reply error %x\n", + pr_err("Msg %x reply error %x\n", msg->header.part.msg_id, msg->header.part.data); sst_drv_ctx->vol_info_blk.ret_code = -msg->header.part.data; @@ -424,18 +426,18 @@ void sst_process_reply(struct work_struct *work) case IPC_IA_GET_STREAM_PARAMS: if (sst_validate_strid(str_id)) { - pr_err("sst: stream id %d invalid\n", str_id); + pr_err("stream id %d invalid\n", str_id); break; } str_info = &sst_drv_ctx->streams[str_id]; if (msg->header.part.large) { - pr_debug("sst: Get stream large success\n"); + pr_debug("Get stream large success\n"); memcpy_fromio(str_info->ctrl_blk.data, ((void *)(msg->mailbox)), sizeof(struct snd_sst_fw_get_stream_params)); str_info->ctrl_blk.ret_code = 0; } else { - pr_err("sst: Msg %x reply error %x\n", + pr_err("Msg %x reply error %x\n", msg->header.part.msg_id, msg->header.part.data); str_info->ctrl_blk.ret_code = -msg->header.part.data; } @@ -447,19 +449,19 @@ void sst_process_reply(struct work_struct *work) break; case IPC_IA_DECODE_FRAMES: if (sst_validate_strid(str_id)) { - pr_err("sst: stream id %d invalid\n", str_id); + pr_err("stream id %d invalid\n", str_id); break; } str_info = &sst_drv_ctx->streams[str_id]; if (msg->header.part.large) { - pr_debug("sst: Msg succedded %x\n", + pr_debug("Msg succeeded %x\n", msg->header.part.msg_id); memcpy_fromio(str_info->data_blk.data, ((void *)(msg->mailbox)), sizeof(struct snd_sst_decode_info)); str_info->data_blk.ret_code = 0; } else { - pr_err("sst: Msg %x reply error %x\n", + pr_err("Msg %x reply error %x\n", msg->header.part.msg_id, msg->header.part.data); str_info->data_blk.ret_code = -msg->header.part.data; } @@ -471,17 +473,17 @@ void sst_process_reply(struct work_struct *work) break; case IPC_IA_DRAIN_STREAM: if (sst_validate_strid(str_id)) { - pr_err("sst: stream id %d invalid\n", str_id); + pr_err("stream id %d invalid\n", str_id); break; } str_info = &sst_drv_ctx->streams[str_id]; if (!msg->header.part.data) { - pr_debug("sst: Msg succedded %x\n", + pr_debug("Msg succeeded %x\n", msg->header.part.msg_id); str_info->ctrl_blk.ret_code = 0; } else { - pr_err("sst: Msg %x reply error %x\n", + pr_err(" Msg %x reply error %x\n", msg->header.part.msg_id, msg->header.part.data); str_info->ctrl_blk.ret_code = -msg->header.part.data; @@ -496,7 +498,7 @@ void sst_process_reply(struct work_struct *work) case IPC_IA_DROP_STREAM: if (sst_validate_strid(str_id)) { - pr_err("sst: str id %d invalid\n", str_id); + pr_err("str id %d invalid\n", str_id); break; } str_info = &sst_drv_ctx->streams[str_id]; @@ -504,12 +506,12 @@ void sst_process_reply(struct work_struct *work) struct snd_sst_drop_response *drop_resp = (struct snd_sst_drop_response *)msg->mailbox; - pr_debug("sst: Drop ret bytes %x\n", drop_resp->bytes); + pr_debug("Drop ret bytes %x\n", drop_resp->bytes); str_info->curr_bytes = drop_resp->bytes; str_info->ctrl_blk.ret_code = 0; } else { - pr_err("sst: Msg %x reply error %x\n", + pr_err(" Msg %x reply error %x\n", msg->header.part.msg_id, msg->header.part.data); str_info->ctrl_blk.ret_code = -msg->header.part.data; } @@ -521,10 +523,10 @@ void sst_process_reply(struct work_struct *work) break; case IPC_IA_ENABLE_RX_TIME_SLOT: if (!msg->header.part.data) { - pr_debug("sst: RX_TIME_SLOT success\n"); + pr_debug("RX_TIME_SLOT success\n"); sst_drv_ctx->hs_info_blk.ret_code = 0; } else { - pr_err("sst: Msg %x reply error %x\n", + pr_err(" Msg %x reply error %x\n", msg->header.part.msg_id, msg->header.part.data); sst_drv_ctx->hs_info_blk.ret_code = @@ -541,17 +543,17 @@ void sst_process_reply(struct work_struct *work) case IPC_IA_SET_STREAM_PARAMS: str_info = &sst_drv_ctx->streams[str_id]; if (!msg->header.part.data) { - pr_debug("sst: Msg succedded %x\n", + pr_debug("Msg succeeded %x\n", msg->header.part.msg_id); str_info->ctrl_blk.ret_code = 0; } else { - pr_err("sst: Msg %x reply error %x\n", + pr_err(" Msg %x reply error %x\n", msg->header.part.msg_id, msg->header.part.data); str_info->ctrl_blk.ret_code = -msg->header.part.data; } if (sst_validate_strid(str_id)) { - pr_err("sst: stream id %d invalid\n", str_id); + pr_err(" stream id %d invalid\n", str_id); break; } @@ -564,9 +566,9 @@ void sst_process_reply(struct work_struct *work) case IPC_IA_FREE_STREAM: if (!msg->header.part.data) { - pr_debug("sst: Stream %d freed\n", str_id); + pr_debug("Stream %d freed\n", str_id); } else { - pr_err("sst: Free for %d ret error %x\n", + pr_err("Free for %d ret error %x\n", str_id, msg->header.part.data); } break; @@ -575,7 +577,7 @@ void sst_process_reply(struct work_struct *work) struct snd_sst_alloc_response *resp = (struct snd_sst_alloc_response *)msg->mailbox; if (resp->str_type.result) - pr_err("sst: error alloc stream = %x\n", + pr_err("error alloc stream = %x\n", resp->str_type.result); sst_alloc_stream_response(str_id, resp); break; @@ -584,21 +586,21 @@ void sst_process_reply(struct work_struct *work) case IPC_IA_PLAY_FRAMES: case IPC_IA_CAPT_FRAMES: if (sst_validate_strid(str_id)) { - pr_err("sst: stream id %d invalid\n" , str_id); + pr_err("stream id %d invalid\n", str_id); break; } - pr_debug("sst: Ack for play/capt frames recived\n"); + pr_debug("Ack for play/capt frames received\n"); break; case IPC_IA_PREP_LIB_DNLD: { struct snd_sst_str_type *str_type = (struct snd_sst_str_type *)msg->mailbox; - pr_debug("sst: Prep Lib download %x\n", + pr_debug("Prep Lib download %x\n", msg->header.part.msg_id); if (str_type->result) - pr_err("sst: Prep lib download %x\n", str_type->result); + pr_err("Prep lib download %x\n", str_type->result); else - pr_debug("sst: Can download codec now...\n"); + pr_debug("Can download codec now...\n"); sst_wake_up_alloc_block(sst_drv_ctx, str_id, str_type->result, NULL); break; @@ -609,12 +611,12 @@ void sst_process_reply(struct work_struct *work) (struct snd_sst_lib_download_info *)msg->mailbox; int retval = resp->result; - pr_debug("sst: Lib downloaded %x\n", msg->header.part.msg_id); + pr_debug("Lib downloaded %x\n", msg->header.part.msg_id); if (resp->result) { - pr_err("sst: err in lib dload %x\n", resp->result); + pr_err("err in lib dload %x\n", resp->result); } else { - pr_debug("sst: Codec download complete...\n"); - pr_debug("sst: codec Type %d Ver %d Built %s: %s\n", + pr_debug("Codec download complete...\n"); + pr_debug("codec Type %d Ver %d Built %s: %s\n", resp->dload_lib.lib_info.lib_type, resp->dload_lib.lib_info.lib_version, resp->dload_lib.lib_info.b_date, @@ -639,17 +641,17 @@ void sst_process_reply(struct work_struct *work) case IPC_IA_GET_FW_BUILD_INF: { struct sst_fw_build_info *build = (struct sst_fw_build_info *)msg->mailbox; - pr_debug("sst: Build date:%sTime:%s", build->date, build->time); + pr_debug("Build date:%sTime:%s", build->date, build->time); break; } case IPC_IA_SET_PMIC_TYPE: break; case IPC_IA_START_STREAM: - pr_debug("sst: reply for START STREAM %x\n", msg->header.full); + pr_debug("reply for START STREAM %x\n", msg->header.full); break; default: /* Illegal case */ - pr_err("sst: process reply:default = %x\n", msg->header.full); + pr_err("process reply:default = %x\n", msg->header.full); } sst_clear_interrupt(); return; diff --git a/drivers/staging/intel_sst/intel_sst_pvt.c b/drivers/staging/intel_sst/intel_sst_pvt.c index 6487e192bf93..01f8c3b1cf74 100644 --- a/drivers/staging/intel_sst/intel_sst_pvt.c +++ b/drivers/staging/intel_sst/intel_sst_pvt.c @@ -29,6 +29,8 @@ * This file contains all private functions */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -60,7 +62,7 @@ int sst_get_block_stream(struct intel_sst_drv *sst_drv_ctx) } } if (i == MAX_ACTIVE_STREAM) { - pr_err("sst: max alloc_stream reached"); + pr_err("max alloc_stream reached\n"); i = -EBUSY; /* active stream limit reached */ } return i; @@ -84,14 +86,14 @@ int sst_wait_interruptible(struct intel_sst_drv *sst_drv_ctx, block->condition)) { /* event wake */ if (block->ret_code < 0) { - pr_err("sst: stream failed %d\n", block->ret_code); + pr_err("stream failed %d\n", block->ret_code); retval = -EBUSY; } else { - pr_debug("sst: event up\n"); + pr_debug("event up\n"); retval = 0; } } else { - pr_err("sst: signal interrupted\n"); + pr_err("signal interrupted\n"); retval = -EINTR; } return retval; @@ -115,18 +117,18 @@ int sst_wait_interruptible_timeout( { int retval = 0; - pr_debug("sst: sst_wait_interruptible_timeout - waiting....\n"); + pr_debug("sst_wait_interruptible_timeout - waiting....\n"); if (wait_event_interruptible_timeout(sst_drv_ctx->wait_queue, block->condition, msecs_to_jiffies(timeout))) { if (block->ret_code < 0) - pr_err("sst: stream failed %d\n", block->ret_code); + pr_err("stream failed %d\n", block->ret_code); else - pr_debug("sst: event up\n"); + pr_debug("event up\n"); retval = block->ret_code; } else { block->on = false; - pr_err("sst: timeout occured...\n"); + pr_err("timeout occurred...\n"); /*setting firmware state as uninit so that the firmware will get re-downloaded on next request this is because firmare not responding for 5 sec @@ -156,18 +158,18 @@ int sst_wait_timeout(struct intel_sst_drv *sst_drv_ctx, /* NOTE: Observed that FW processes the alloc msg and replies even before the alloc thread has finished execution */ - pr_debug("sst: waiting for %x, condition %x\n", + pr_debug("waiting for %x, condition %x\n", block->sst_id, block->ops_block.condition); if (wait_event_interruptible_timeout(sst_drv_ctx->wait_queue, block->ops_block.condition, msecs_to_jiffies(SST_BLOCK_TIMEOUT))) { /* event wake */ - pr_debug("sst: Event wake %x\n", block->ops_block.condition); - pr_debug("sst: message ret: %d\n", block->ops_block.ret_code); + pr_debug("Event wake %x\n", block->ops_block.condition); + pr_debug("message ret: %d\n", block->ops_block.ret_code); retval = block->ops_block.ret_code; } else { block->ops_block.on = false; - pr_err("sst: Wait timed-out %x\n", block->ops_block.condition); + pr_err("Wait timed-out %x\n", block->ops_block.condition); /* settign firmware state as uninit so that the firmware will get redownloaded on next request this is because firmare not responding for 5 sec @@ -192,14 +194,14 @@ int sst_create_large_msg(struct ipc_post **arg) msg = kzalloc(sizeof(struct ipc_post), GFP_ATOMIC); if (!msg) { - pr_err("sst: kzalloc msg failed\n"); + pr_err("kzalloc msg failed\n"); return -ENOMEM; } msg->mailbox_data = kzalloc(SST_MAILBOX_SIZE, GFP_ATOMIC); if (!msg->mailbox_data) { kfree(msg); - pr_err("sst: kzalloc mailbox_data failed"); + pr_err("kzalloc mailbox_data failed"); return -ENOMEM; }; *arg = msg; @@ -219,7 +221,7 @@ int sst_create_short_msg(struct ipc_post **arg) msg = kzalloc(sizeof(*msg), GFP_ATOMIC); if (!msg) { - pr_err("sst: kzalloc msg failed\n"); + pr_err("kzalloc msg failed\n"); return -ENOMEM; } msg->mailbox_data = NULL; @@ -290,10 +292,10 @@ int sst_enable_rx_timeslot(int status) struct ipc_post *msg = NULL; if (sst_create_short_msg(&msg)) { - pr_err("sst: mem allocation failed\n"); + pr_err("mem allocation failed\n"); return -ENOMEM; } - pr_debug("sst: ipc message sending: ENABLE_RX_TIME_SLOT\n"); + pr_debug("ipc message sending: ENABLE_RX_TIME_SLOT\n"); sst_fill_header(&msg->header, IPC_IA_ENABLE_RX_TIME_SLOT, 0, 0); msg->header.part.data = status; sst_drv_ctx->hs_info_blk.condition = false; diff --git a/drivers/staging/intel_sst/intel_sst_stream.c b/drivers/staging/intel_sst/intel_sst_stream.c index b2c4b7067da0..8f6e1005371d 100644 --- a/drivers/staging/intel_sst/intel_sst_stream.c +++ b/drivers/staging/intel_sst/intel_sst_stream.c @@ -26,6 +26,8 @@ * This file contains the stream operations of SST driver */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -46,7 +48,7 @@ int sst_check_device_type(u32 device, u32 num_chan, u32 *pcm_slot) { if (device >= MAX_NUM_STREAMS) { - pr_debug("sst: device type invalid %d\n", device); + pr_debug("device type invalid %d\n", device); return -EINVAL; } if (sst_drv_ctx->streams[device].status == STREAM_UN_INIT) { @@ -71,15 +73,15 @@ int sst_check_device_type(u32 device, u32 num_chan, u32 *pcm_slot) else if (device == SND_SST_DEVICE_CAPTURE && num_chan == 4) *pcm_slot = 0x0F; else { - pr_debug("sst: No condition satisfied.. ret err\n"); + pr_debug("No condition satisfied.. ret err\n"); return -EINVAL; } } else { - pr_debug("sst: this stream state is not uni-init, is %d\n", + pr_debug("this stream state is not uni-init, is %d\n", sst_drv_ctx->streams[device].status); return -EBADRQC; } - pr_debug("sst: returning slot %x\n", *pcm_slot); + pr_debug("returning slot %x\n", *pcm_slot); return 0; } /** @@ -96,7 +98,7 @@ static unsigned int get_mrst_stream_id(void) if (sst_drv_ctx->streams[i].status == STREAM_UN_INIT) return i; } - pr_debug("sst: Didnt find empty stream for mrst\n"); + pr_debug("Didnt find empty stream for mrst\n"); return -EBUSY; } @@ -305,7 +307,7 @@ int sst_pause_stream(int str_id) if (str_info->prev == STREAM_UN_INIT) return -EBADRQC; if (str_info->ctrl_blk.on == true) { - pr_err("SST ERR: control path is in use\n "); + pr_err("SST ERR: control path is in use\n"); return -EINVAL; } if (sst_create_short_msg(&msg)) @@ -333,7 +335,7 @@ int sst_pause_stream(int str_id) } } else { retval = -EBADRQC; - pr_err("SST ERR:BADQRC for stream\n "); + pr_err("SST ERR: BADQRC for stream\n"); } return retval; @@ -468,7 +470,7 @@ int sst_drop_stream(int str_id) } } else { retval = -EBADRQC; - pr_err("SST ERR:BADQRC for stream\n"); + pr_err("SST ERR: BADQRC for stream\n"); } return retval; } diff --git a/drivers/staging/intel_sst/intel_sst_stream_encoded.c b/drivers/staging/intel_sst/intel_sst_stream_encoded.c index fbae39fda5c0..d4e94f1ec830 100644 --- a/drivers/staging/intel_sst/intel_sst_stream_encoded.c +++ b/drivers/staging/intel_sst/intel_sst_stream_encoded.c @@ -26,6 +26,8 @@ * This file contains the stream operations of SST driver */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -53,7 +55,7 @@ int sst_get_stream_params(int str_id, struct stream_info *str_info; struct snd_sst_fw_get_stream_params *fw_params; - pr_debug("sst: get_stream for %d\n", str_id); + pr_debug("get_stream for %d\n", str_id); retval = sst_validate_strid(str_id); if (retval) return retval; @@ -61,16 +63,16 @@ int sst_get_stream_params(int str_id, str_info = &sst_drv_ctx->streams[str_id]; if (str_info->status != STREAM_UN_INIT) { if (str_info->ctrl_blk.on == true) { - pr_err("sst: control path in use\n"); + pr_err("control path in use\n"); return -EINVAL; } if (sst_create_short_msg(&msg)) { - pr_err("sst: message creation failed\n"); + pr_err("message creation failed\n"); return -ENOMEM; } fw_params = kzalloc(sizeof(*fw_params), GFP_ATOMIC); if (!fw_params) { - pr_err("sst: mem allcoation failed\n "); + pr_err("mem allocation failed\n"); kfree(msg); return -ENOMEM; } @@ -104,7 +106,7 @@ int sst_get_stream_params(int str_id, get_params->codec_params.stream_type = str_info->str_type; kfree(fw_params); } else { - pr_debug("sst: Stream is not in the init state\n"); + pr_debug("Stream is not in the init state\n"); } return retval; } @@ -125,17 +127,17 @@ int sst_set_stream_param(int str_id, struct snd_sst_params *str_param) BUG_ON(!str_param); if (sst_drv_ctx->streams[str_id].ops != str_param->ops) { - pr_err("sst: Invalid operation\n"); + pr_err("Invalid operation\n"); return -EINVAL; } retval = sst_validate_strid(str_id); if (retval) return retval; - pr_debug("sst: set_stream for %d\n", str_id); + pr_debug("set_stream for %d\n", str_id); str_info = &sst_drv_ctx->streams[str_id]; if (sst_drv_ctx->streams[str_id].status == STREAM_INIT) { if (str_info->ctrl_blk.on == true) { - pr_err("sst: control path in use\n"); + pr_err("control path in use\n"); return -EAGAIN; } if (sst_create_large_msg(&msg)) @@ -163,7 +165,7 @@ int sst_set_stream_param(int str_id, struct snd_sst_params *str_param) } } else { retval = -EBADRQC; - pr_err("sst: BADQRC for stream\n"); + pr_err("BADQRC for stream\n"); } return retval; } @@ -183,7 +185,7 @@ int sst_get_vol(struct snd_sst_vol *get_vol) struct snd_sst_vol *fw_get_vol; int str_id = get_vol->stream_id; - pr_debug("sst: get vol called\n"); + pr_debug("get vol called\n"); if (sst_create_short_msg(&msg)) return -ENOMEM; @@ -195,7 +197,7 @@ int sst_get_vol(struct snd_sst_vol *get_vol) sst_drv_ctx->vol_info_blk.on = true; fw_get_vol = kzalloc(sizeof(*fw_get_vol), GFP_ATOMIC); if (!fw_get_vol) { - pr_err("sst: mem allocation failed\n"); + pr_err("mem allocation failed\n"); kfree(msg); return -ENOMEM; } @@ -209,10 +211,10 @@ int sst_get_vol(struct snd_sst_vol *get_vol) if (retval) retval = -EIO; else { - pr_debug("sst: stream id %d\n", fw_get_vol->stream_id); - pr_debug("sst: volume %d\n", fw_get_vol->volume); - pr_debug("sst: ramp duration %d\n", fw_get_vol->ramp_duration); - pr_debug("sst: ramp_type %d\n", fw_get_vol->ramp_type); + pr_debug("stream id %d\n", fw_get_vol->stream_id); + pr_debug("volume %d\n", fw_get_vol->volume); + pr_debug("ramp duration %d\n", fw_get_vol->ramp_duration); + pr_debug("ramp_type %d\n", fw_get_vol->ramp_type); memcpy(get_vol, fw_get_vol, sizeof(*fw_get_vol)); } return retval; @@ -231,10 +233,10 @@ int sst_set_vol(struct snd_sst_vol *set_vol) int retval = 0; struct ipc_post *msg = NULL; - pr_debug("sst: set vol called\n"); + pr_debug("set vol called\n"); if (sst_create_large_msg(&msg)) { - pr_err("sst: message creation failed\n"); + pr_err("message creation failed\n"); return -ENOMEM; } sst_fill_header(&msg->header, IPC_IA_SET_STREAM_VOL, 1, @@ -254,7 +256,7 @@ int sst_set_vol(struct snd_sst_vol *set_vol) retval = sst_wait_interruptible_timeout(sst_drv_ctx, &sst_drv_ctx->vol_info_blk, SST_BLOCK_TIMEOUT); if (retval) { - pr_err("sst: error in set_vol = %d\n", retval); + pr_err("error in set_vol = %d\n", retval); retval = -EIO; } return retval; @@ -273,10 +275,10 @@ int sst_set_mute(struct snd_sst_mute *set_mute) int retval = 0; struct ipc_post *msg = NULL; - pr_debug("sst: set mute called\n"); + pr_debug("set mute called\n"); if (sst_create_large_msg(&msg)) { - pr_err("sst: message creation failed\n"); + pr_err("message creation failed\n"); return -ENOMEM; } sst_fill_header(&msg->header, IPC_IA_SET_STREAM_MUTE, 1, @@ -297,7 +299,7 @@ int sst_set_mute(struct snd_sst_mute *set_mute) retval = sst_wait_interruptible_timeout(sst_drv_ctx, &sst_drv_ctx->mute_info_blk, SST_BLOCK_TIMEOUT); if (retval) { - pr_err("sst: error in set_mute = %d\n", retval); + pr_err("error in set_mute = %d\n", retval); retval = -EIO; } return retval; @@ -358,20 +360,20 @@ int sst_parse_target(struct snd_sst_slot_info *slot) slot->device_type == SND_SST_DEVICE_PCM) { retval = sst_activate_target(slot); if (retval) - pr_err("sst: SST_Activate_target_fail\n"); + pr_err("SST_Activate_target_fail\n"); else - pr_err("sst: SST_Activate_target_pass\n"); + pr_err("SST_Activate_target_pass\n"); return retval; } else if (slot->action == SND_SST_PORT_PREPARE && slot->device_type == SND_SST_DEVICE_PCM) { retval = sst_prepare_target(slot); if (retval) - pr_err("sst: SST_prepare_target_fail\n"); + pr_err("SST_prepare_target_fail\n"); else - pr_err("sst: SST_prepare_target_pass\n"); + pr_err("SST_prepare_target_pass\n"); return retval; } else { - pr_err("sst: slot_action : %d, device_type: %d\n", + pr_err("slot_action : %d, device_type: %d\n", slot->action, slot->device_type); return retval; } @@ -383,7 +385,7 @@ int sst_send_target(struct snd_sst_target_device *target) struct ipc_post *msg; if (sst_create_large_msg(&msg)) { - pr_err("sst: message creation failed\n"); + pr_err("message creation failed\n"); return -ENOMEM; } sst_fill_header(&msg->header, IPC_IA_TARGET_DEV_SELECT, 1, 0); @@ -399,11 +401,11 @@ int sst_send_target(struct snd_sst_target_device *target) list_add_tail(&msg->node, &sst_drv_ctx->ipc_dispatch_list); spin_unlock(&sst_drv_ctx->list_spin_lock); sst_post_message(&sst_drv_ctx->ipc_post_msg_wq); - pr_debug("sst: message sent- waiting\n"); + pr_debug("message sent- waiting\n"); retval = sst_wait_interruptible_timeout(sst_drv_ctx, &sst_drv_ctx->tgt_dev_blk, TARGET_DEV_BLOCK_TIMEOUT); if (retval) - pr_err("sst: target device ipc failed = 0x%x\n", retval); + pr_err("target device ipc failed = 0x%x\n", retval); return retval; } @@ -439,7 +441,7 @@ int sst_target_device_validate(struct snd_sst_target_device *target) goto err; } else { err: - pr_err("sst: i/p params incorrect\n"); + pr_err("i/p params incorrect\n"); return -EINVAL; } } @@ -460,15 +462,15 @@ int sst_target_device_select(struct snd_sst_target_device *target) { int retval, i, prepare_count = 0; - pr_debug("sst: Target Device Select\n"); + pr_debug("Target Device Select\n"); if (target->device_route < 0 || target->device_route > 2) { - pr_err("sst: device route is invalid\n"); + pr_err("device route is invalid\n"); return -EINVAL; } if (target->device_route != 0) { - pr_err("sst: Unsupported config\n"); + pr_err("Unsupported config\n"); return -EIO; } retval = sst_target_device_validate(target); @@ -480,18 +482,18 @@ int sst_target_device_select(struct snd_sst_target_device *target) return retval; for (i = 0; i < SST_MAX_TARGET_DEVICES; i++) { if (target->devices[i].action == SND_SST_PORT_ACTIVATE) { - pr_debug("sst: activate called in %d\n", i); + pr_debug("activate called in %d\n", i); retval = sst_parse_target(&target->devices[i]); if (retval) return retval; } else if (target->devices[i].action == SND_SST_PORT_PREPARE) { - pr_debug("sst: PREPARE in %d, Forwading\n", i); + pr_debug("PREPARE in %d, Forwarding\n", i); retval = sst_parse_target(&target->devices[i]); if (retval) { - pr_err("sst: Parse Target fail %d", retval); + pr_err("Parse Target fail %d\n", retval); return retval; } - pr_debug("sst: Parse Target successful %d", retval); + pr_debug("Parse Target successful %d\n", retval); if (target->devices[i].device_type == SND_SST_DEVICE_PCM) prepare_count++; @@ -512,11 +514,11 @@ static inline int sst_get_RAR(struct RAR_buffer *buffers, int count) rar_status = rar_handle_to_bus(buffers, count); if (count != rar_status) { - pr_err("sst: The rar CALL Failed"); + pr_err("The rar CALL Failed"); retval = -EIO; } if (buffers->info.type != RAR_TYPE_AUDIO) { - pr_err("sst: Invalid RAR type\n"); + pr_err("Invalid RAR type\n"); return -EINVAL; } return retval; @@ -539,10 +541,10 @@ static int sst_create_sg_list(struct stream_info *stream, if (kbufs->in_use == false) { #ifdef CONFIG_MRST_RAR_HANDLER if (stream->ops == STREAM_OPS_PLAYBACK_DRM) { - pr_debug("sst: DRM playback handling\n"); + pr_debug("DRM playback handling\n"); rar_buffers.info.handle = (__u32)kbufs->addr; rar_buffers.info.size = kbufs->size; - pr_debug("sst: rar handle 0x%x size=0x%x", + pr_debug("rar handle 0x%x size=0x%x\n", rar_buffers.info.handle, rar_buffers.info.size); retval = sst_get_RAR(&rar_buffers, 1); @@ -552,7 +554,7 @@ static int sst_create_sg_list(struct stream_info *stream, sg_list->addr[i].addr = rar_buffers.bus_address; /* rar_buffers.info.size; */ sg_list->addr[i].size = (__u32)kbufs->size; - pr_debug("sst: phyaddr[%d] 0x%x Size:0x%x\n" + pr_debug("phyaddr[%d] 0x%x Size:0x%x\n" , i, sg_list->addr[i].addr, sg_list->addr[i].size); } @@ -562,7 +564,7 @@ static int sst_create_sg_list(struct stream_info *stream, virt_to_phys((void *) kbufs->addr + kbufs->offset); sg_list->addr[i].size = kbufs->size; - pr_debug("sst: phyaddr[%d]:0x%x Size:0x%x\n" + pr_debug("phyaddr[%d]:0x%x Size:0x%x\n" , i , sg_list->addr[i].addr, kbufs->size); } stream->curr_bytes += sg_list->addr[i].size; @@ -574,7 +576,7 @@ static int sst_create_sg_list(struct stream_info *stream, } sg_list->num_entries = i; - pr_debug("sst:sg list entries = %d\n", sg_list->num_entries); + pr_debug("sg list entries = %d\n", sg_list->num_entries); return i; } @@ -595,7 +597,7 @@ int sst_play_frame(int str_id) struct sst_stream_bufs *kbufs = NULL, *_kbufs; struct stream_info *stream; - pr_debug("sst: play frame for %d\n", str_id); + pr_debug("play frame for %d\n", str_id); retval = sst_validate_strid(str_id); if (retval) return retval; @@ -615,14 +617,14 @@ int sst_play_frame(int str_id) stream->curr_bytes = 0; if (list_empty(&stream->bufs)) { /* no user buffer available */ - pr_debug("sst: Null buffer stream status %d\n", stream->status); + pr_debug("Null buffer stream status %d\n", stream->status); stream->prev = stream->status; stream->status = STREAM_INIT; - pr_debug("sst:new stream status = %d\n", stream->status); + pr_debug("new stream status = %d\n", stream->status); if (stream->need_draining == true) { - pr_debug("sst:draining stream\n"); + pr_debug("draining stream\n"); if (sst_create_short_msg(&msg)) { - pr_err("sst: mem alloc failed\n"); + pr_err("mem allocation failed\n"); return -ENOMEM; } sst_fill_header(&msg->header, IPC_IA_DRAIN_STREAM, @@ -633,7 +635,7 @@ int sst_play_frame(int str_id) spin_unlock(&sst_drv_ctx->list_spin_lock); sst_post_message(&sst_drv_ctx->ipc_post_msg_wq); } else if (stream->data_blk.on == true) { - pr_debug("sst:user list empty.. wake\n"); + pr_debug("user list empty.. wake\n"); /* unblock */ stream->data_blk.ret_code = 0; stream->data_blk.condition = true; @@ -678,7 +680,7 @@ int sst_capture_frame(int str_id) struct stream_info *stream; - pr_debug("sst:capture frame for %d\n", str_id); + pr_debug("capture frame for %d\n", str_id); retval = sst_validate_strid(str_id); if (retval) return retval; @@ -688,19 +690,19 @@ int sst_capture_frame(int str_id) if (kbufs->in_use == true) { list_del(&kbufs->node); kfree(kbufs); - pr_debug("sst:del node\n"); + pr_debug("del node\n"); } } if (list_empty(&stream->bufs)) { /* no user buffer available */ - pr_debug("sst:Null buffer!!!!stream status %d\n", + pr_debug("Null buffer!!!!stream status %d\n", stream->status); stream->prev = stream->status; stream->status = STREAM_INIT; - pr_debug("sst:new stream status = %d\n", + pr_debug("new stream status = %d\n", stream->status); if (stream->data_blk.on == true) { - pr_debug("sst:user list empty.. wake\n"); + pr_debug("user list empty.. wake\n"); /* unblock */ stream->data_blk.ret_code = 0; stream->data_blk.condition = true; @@ -731,7 +733,7 @@ int sst_capture_frame(int str_id) stream->cumm_bytes += stream->curr_bytes; stream->curr_bytes = 0; - pr_debug("sst:Cum bytes = %d\n", stream->cumm_bytes); + pr_debug("Cum bytes = %d\n", stream->cumm_bytes); return 0; } @@ -743,7 +745,7 @@ static unsigned int calculate_min_size(struct snd_sst_buffs *bufs) if (bufs->buff_entry[i].size < min_val) min_val = bufs->buff_entry[i].size; } - pr_debug("sst:min_val = %d\n", min_val); + pr_debug("min_val = %d\n", min_val); return min_val; } @@ -754,7 +756,7 @@ static unsigned int calculate_max_size(struct snd_sst_buffs *bufs) if (bufs->buff_entry[i].size > max_val) max_val = bufs->buff_entry[i].size; } - pr_debug("sst:max_val = %d\n", max_val); + pr_debug("max_val = %d\n", max_val); return max_val; } @@ -773,7 +775,7 @@ static int sst_allocate_decode_buf(struct stream_info *str_info, if (dbufs->ibufs->entries == dbufs->obufs->entries) return 0; else { - pr_err("sst: RAR entries dont match\n"); + pr_err("RAR entries dont match\n"); return -EINVAL; } } else @@ -783,26 +785,26 @@ static int sst_allocate_decode_buf(struct stream_info *str_info, } #endif if (!str_info->decode_ibuf) { - pr_debug("sst:no i/p buffers, trying full size\n"); + pr_debug("no i/p buffers, trying full size\n"); str_info->decode_isize = cum_input_given; str_info->decode_ibuf = kzalloc(str_info->decode_isize, GFP_KERNEL); str_info->idecode_alloc = str_info->decode_isize; } if (!str_info->decode_ibuf) { - pr_debug("sst:buff alloc failed, try max size\n"); + pr_debug("buff alloc failed, try max size\n"); str_info->decode_isize = calculate_max_size(dbufs->ibufs); str_info->decode_ibuf = kzalloc( str_info->decode_isize, GFP_KERNEL); str_info->idecode_alloc = str_info->decode_isize; } if (!str_info->decode_ibuf) { - pr_debug("sst:buff alloc failed, try min size\n"); + pr_debug("buff alloc failed, try min size\n"); str_info->decode_isize = calculate_min_size(dbufs->ibufs); str_info->decode_ibuf = kzalloc(str_info->decode_isize, GFP_KERNEL); if (!str_info->decode_ibuf) { - pr_err("sst: mem allocation failed\n"); + pr_err("mem allocation failed\n"); return -ENOMEM; } str_info->idecode_alloc = str_info->decode_isize; @@ -820,7 +822,7 @@ static int sst_send_decode_mess(int str_id, struct stream_info *str_info, struct ipc_post *msg = NULL; int retval = 0; - pr_debug("SST DBGsst_set_mute:called\n"); + pr_debug("SST DBG:sst_set_mute:called\n"); if (str_info->decode_ibuf_type == SST_BUF_RAR) { #ifdef CONFIG_MRST_RAR_HANDLER @@ -857,7 +859,7 @@ static int sst_send_decode_mess(int str_id, struct stream_info *str_info, dec_info->input_bytes_consumed = 0; dec_info->output_bytes_produced = 0; if (sst_create_large_msg(&msg)) { - pr_err("sst: message creation failed\n"); + pr_err("message creation failed\n"); return -ENOMEM; } @@ -894,7 +896,7 @@ static int sst_prepare_input_buffers_rar(struct stream_info *str_info, dbufs->ibufs->buff_entry[i].buffer, sizeof(__u32)); if (retval) { - pr_err("sst:cpy from user fail\n"); + pr_err("cpy from user fail\n"); return -EAGAIN; } rar_buffers.info.type = dbufs->ibufs->type; @@ -931,7 +933,7 @@ static int sst_prepare_input_buffers(struct stream_info *str_info, { int i, cpy_size, retval = 0; - pr_debug("sst:input_index = %d, input entries = %d\n", + pr_debug("input_index = %d, input entries = %d\n", *input_index, dbufs->ibufs->entries); for (i = *input_index; i < dbufs->ibufs->entries; i++) { #ifdef CONFIG_MRST_RAR_HANDLER @@ -939,7 +941,7 @@ static int sst_prepare_input_buffers(struct stream_info *str_info, dbufs, input_index, in_copied, input_index_valid_size, new_entry_flag); if (retval) { - pr_err("sst: In prepare input buffers for RAR\n"); + pr_err("In prepare input buffers for RAR\n"); return -EIO; } #endif @@ -947,10 +949,10 @@ static int sst_prepare_input_buffers(struct stream_info *str_info, if (*input_index_valid_size == 0) *input_index_valid_size = dbufs->ibufs->buff_entry[i].size; - pr_debug("sst:inout addr = %p, size = %d\n", + pr_debug("inout addr = %p, size = %d\n", dbufs->ibufs->buff_entry[i].buffer, *input_index_valid_size); - pr_debug("sst:decode_isize = %d, in_copied %d\n", + pr_debug("decode_isize = %d, in_copied %d\n", str_info->decode_isize, *in_copied); if (*input_index_valid_size <= (str_info->decode_isize - *in_copied)) @@ -958,12 +960,12 @@ static int sst_prepare_input_buffers(struct stream_info *str_info, else cpy_size = str_info->decode_isize - *in_copied; - pr_debug("sst:cpy size = %d\n", cpy_size); + pr_debug("cpy size = %d\n", cpy_size); if (!dbufs->ibufs->buff_entry[i].buffer) { - pr_err("sst: i/p buffer is null\n"); + pr_err("i/p buffer is null\n"); return -EINVAL; } - pr_debug("sst:Try copy To %p, From %p, size %d\n", + pr_debug("Try copy To %p, From %p, size %d\n", str_info->decode_ibuf + *in_copied, dbufs->ibufs->buff_entry[i].buffer, cpy_size); @@ -972,22 +974,22 @@ static int sst_prepare_input_buffers(struct stream_info *str_info, (void *) dbufs->ibufs->buff_entry[i].buffer, cpy_size); if (retval) { - pr_err("sst: copy from user failed\n"); + pr_err("copy from user failed\n"); return -EIO; } *in_copied += cpy_size; *input_index_valid_size -= cpy_size; - pr_debug("sst:in buff size = %d, in_copied = %d\n", + pr_debug("in buff size = %d, in_copied = %d\n", *input_index_valid_size, *in_copied); if (*input_index_valid_size != 0) { - pr_debug("sst:more input buffers left\n"); + pr_debug("more input buffers left\n"); dbufs->ibufs->buff_entry[i].buffer += cpy_size; break; } if (*in_copied == str_info->decode_isize && *input_index_valid_size == 0 && (i+1) <= dbufs->ibufs->entries) { - pr_debug("sst:all input buffers copied\n"); + pr_debug("all input buffers copied\n"); *new_entry_flag = true; *input_index = i + 1; break; @@ -1005,23 +1007,23 @@ static int sst_prepare_output_buffers(struct stream_info *str_info, { int i, cpy_size, retval = 0; - pr_debug("sst:output_index = %d, output entries = %d\n", + pr_debug("output_index = %d, output entries = %d\n", *output_index, dbufs->obufs->entries); for (i = *output_index; i < dbufs->obufs->entries; i++) { *output_index = i; - pr_debug("sst:output addr = %p, size = %d\n", + pr_debug("output addr = %p, size = %d\n", dbufs->obufs->buff_entry[i].buffer, dbufs->obufs->buff_entry[i].size); - pr_debug("sst:output_size = %d, out_copied = %d\n", + pr_debug("output_size = %d, out_copied = %d\n", output_size, *out_copied); if (dbufs->obufs->buff_entry[i].size < (output_size - *out_copied)) cpy_size = dbufs->obufs->buff_entry[i].size; else cpy_size = output_size - *out_copied; - pr_debug("sst:cpy size = %d\n", cpy_size); - pr_debug("sst:Try copy To: %p, From %p, size %d\n", + pr_debug("cpy size = %d\n", cpy_size); + pr_debug("Try copy To: %p, From %p, size %d\n", dbufs->obufs->buff_entry[i].buffer, sst_drv_ctx->mmap_mem + *out_copied, cpy_size); @@ -1029,13 +1031,13 @@ static int sst_prepare_output_buffers(struct stream_info *str_info, sst_drv_ctx->mmap_mem + *out_copied, cpy_size); if (retval) { - pr_err("sst: copy to user failed\n"); + pr_err("copy to user failed\n"); return -EIO; } else - pr_debug("sst:copy to user passed\n"); + pr_debug("copy to user passed\n"); *out_copied += cpy_size; dbufs->obufs->buff_entry[i].size -= cpy_size; - pr_debug("sst:o/p buff size %d, out_copied %d\n", + pr_debug("o/p buff size %d, out_copied %d\n", dbufs->obufs->buff_entry[i].size, *out_copied); if (dbufs->obufs->buff_entry[i].size != 0) { *output_index = i; @@ -1073,7 +1075,7 @@ int sst_decode(int str_id, struct snd_sst_dbufs *dbufs) unsigned long long input_bytes, output_bytes; sst_drv_ctx->scard_ops->power_down_pmic(); - pr_debug("sst: Powering_down_PMIC...\n"); + pr_debug("Powering_down_PMIC...\n"); retval = sst_validate_strid(str_id); if (retval) @@ -1081,7 +1083,7 @@ int sst_decode(int str_id, struct snd_sst_dbufs *dbufs) str_info = &sst_drv_ctx->streams[str_id]; if (str_info->status != STREAM_INIT) { - pr_err("sst: invalid stream state = %d\n", + pr_err("invalid stream state = %d\n", str_info->status); return -EINVAL; } @@ -1098,7 +1100,7 @@ int sst_decode(int str_id, struct snd_sst_dbufs *dbufs) retval = sst_allocate_decode_buf(str_info, dbufs, cum_input_given, cum_output_given); if (retval) { - pr_err("sst: mem allocation failed, abort!!!\n"); + pr_err("mem allocation failed, abort!!!\n"); retval = -ENOMEM; goto finish; } @@ -1114,7 +1116,7 @@ int sst_decode(int str_id, struct snd_sst_dbufs *dbufs) dbufs, &input_index, &in_copied, &input_index_valid_size, &new_entry_flag); if (retval) { - pr_err("sst: prepare in buffers failed\n"); + pr_err("prepare in buffers failed\n"); goto finish; } @@ -1145,8 +1147,8 @@ int sst_decode(int str_id, struct snd_sst_dbufs *dbufs) str_info->decode_osize = dbufs->obufs-> buff_entry[output_index].size; str_info->decode_obuf_type = dbufs->obufs->type; - pr_debug("sst:DRM handling\n"); - pr_debug("o/p_add=0x%lu Size=0x%x", + pr_debug("DRM handling\n"); + pr_debug("o/p_add=0x%lu Size=0x%x\n", (unsigned long) str_info->decode_obuf, str_info->decode_osize); } else { @@ -1160,7 +1162,7 @@ int sst_decode(int str_id, struct snd_sst_dbufs *dbufs) if (str_info->ops != STREAM_OPS_PLAYBACK_DRM) { if (str_info->decode_isize > in_copied) { str_info->decode_isize = in_copied; - pr_debug("sst:i/p size = %d\n", + pr_debug("i/p size = %d\n", str_info->decode_isize); } } @@ -1168,20 +1170,19 @@ int sst_decode(int str_id, struct snd_sst_dbufs *dbufs) retval = sst_send_decode_mess(str_id, str_info, &dec_info); if (retval || dec_info.input_bytes_consumed == 0) { - pr_err( - "SST ERR: mess failed or no input consumed\n"); + pr_err("SST ERR: mess failed or no input consumed\n"); goto finish; } input_bytes = dec_info.input_bytes_consumed; output_bytes = dec_info.output_bytes_produced; - pr_debug("sst:in_copied=%d, con=%lld, prod=%lld\n", + pr_debug("in_copied=%d, con=%lld, prod=%lld\n", in_copied, input_bytes, output_bytes); if (dbufs->obufs->type == SST_BUF_RAR) { output_index += 1; if (output_index == dbufs->obufs->entries) { copy_in_done = true; - pr_debug("sst:all i/p cpy done\n"); + pr_debug("all i/p cpy done\n"); } total_output += output_bytes; } else { @@ -1190,14 +1191,14 @@ int sst_decode(int str_id, struct snd_sst_dbufs *dbufs) retval = sst_prepare_output_buffers(str_info, dbufs, &output_index, output_size, &out_copied); if (retval) { - pr_err("sst:prep out buff fail\n"); + pr_err("prep out buff fail\n"); goto finish; } if (str_info->ops != STREAM_OPS_PLAYBACK_DRM) { if (in_copied != input_bytes) { int bytes_left = in_copied - input_bytes; - pr_debug("sst:bytes %d\n", + pr_debug("bytes %d\n", bytes_left); if (new_entry_flag == true) input_index--; @@ -1237,7 +1238,7 @@ int sst_decode(int str_id, struct snd_sst_dbufs *dbufs) total_output += out_copied; if (str_info->decode_osize != out_copied) { str_info->decode_osize -= out_copied; - pr_debug("sst:output size modified = %d\n", + pr_debug("output size modified = %d\n", str_info->decode_osize); } } @@ -1251,16 +1252,16 @@ int sst_decode(int str_id, struct snd_sst_dbufs *dbufs) } else { if (total_output == cum_output_given) { copy_out_done = true; - pr_debug("sst:all o/p cpy done\n"); + pr_debug("all o/p cpy done\n"); } if (total_input == cum_input_given) { copy_in_done = true; - pr_debug("sst:all i/p cpy done\n"); + pr_debug("all i/p cpy done\n"); } } - pr_debug("sst:copy_out = %d, copy_in = %d\n", + pr_debug("copy_out = %d, copy_in = %d\n", copy_out_done, copy_in_done); } diff --git a/drivers/staging/intel_sst/intelmid.c b/drivers/staging/intel_sst/intelmid.c index 4c0264ceaa88..47b91e500c3c 100644 --- a/drivers/staging/intel_sst/intelmid.c +++ b/drivers/staging/intel_sst/intelmid.c @@ -24,6 +24,9 @@ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * ALSA driver for Intel MID sound card chipset */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -118,7 +121,7 @@ static int snd_intelmad_pcm_trigger(struct snd_pcm_substream *substream, switch (cmd) { case SNDRV_PCM_TRIGGER_START: - pr_debug("sst: Trigger Start\n"); + pr_debug("Trigger Start\n"); ret_val = intelmaddata->sstdrv_ops->control_set(SST_SND_START, &stream->stream_info.str_id); if (ret_val) @@ -128,7 +131,7 @@ static int snd_intelmad_pcm_trigger(struct snd_pcm_substream *substream, stream->stream_status = RUNNING; break; case SNDRV_PCM_TRIGGER_STOP: - pr_debug("sst: in stop\n"); + pr_debug("in stop\n"); ret_val = intelmaddata->sstdrv_ops->control_set(SST_SND_DROP, &stream->stream_info.str_id); if (ret_val) @@ -136,7 +139,7 @@ static int snd_intelmad_pcm_trigger(struct snd_pcm_substream *substream, stream->stream_status = DROPPED; break; case SNDRV_PCM_TRIGGER_PAUSE_PUSH: - pr_debug("sst: in pause\n"); + pr_debug("in pause\n"); ret_val = intelmaddata->sstdrv_ops->control_set(SST_SND_PAUSE, &stream->stream_info.str_id); if (ret_val) @@ -144,7 +147,7 @@ static int snd_intelmad_pcm_trigger(struct snd_pcm_substream *substream, stream->stream_status = PAUSED; break; case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - pr_debug("sst: in pause release\n"); + pr_debug("in pause release\n"); ret_val = intelmaddata->sstdrv_ops->control_set(SST_SND_RESUME, &stream->stream_info.str_id); if (ret_val) @@ -170,17 +173,17 @@ static int snd_intelmad_pcm_prepare(struct snd_pcm_substream *substream) int ret_val = 0; struct snd_intelmad *intelmaddata; - pr_debug("sst: pcm_prepare called\n"); + pr_debug("pcm_prepare called\n"); WARN_ON(!substream); stream = substream->runtime->private_data; intelmaddata = snd_pcm_substream_chip(substream); - pr_debug("sst: pb cnt = %d cap cnt = %d\n",\ + pr_debug("pb cnt = %d cap cnt = %d\n",\ intelmaddata->playback_cnt, intelmaddata->capture_cnt); if (stream->stream_info.str_id) { - pr_debug("sst: Prepare called for already set stream\n"); + pr_debug("Prepare called for already set stream\n"); ret_val = intelmaddata->sstdrv_ops->control_set(SST_SND_DROP, &stream->stream_info.str_id); return ret_val; @@ -197,7 +200,7 @@ static int snd_intelmad_pcm_prepare(struct snd_pcm_substream *substream) /* return back the stream id */ snprintf(substream->pcm->id, sizeof(substream->pcm->id), "%d", stream->stream_info.str_id); - pr_debug("sst: stream id to user = %s\n", + pr_debug("stream id to user = %s\n", substream->pcm->id); ret_val = snd_intelmad_init_stream(substream); @@ -212,7 +215,7 @@ static int snd_intelmad_hw_params(struct snd_pcm_substream *substream, { int ret_val; - pr_debug("sst: snd_intelmad_hw_params called\n"); + pr_debug("snd_intelmad_hw_params called\n"); ret_val = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params)); memset(substream->runtime->dma_area, 0, @@ -223,7 +226,7 @@ static int snd_intelmad_hw_params(struct snd_pcm_substream *substream, static int snd_intelmad_hw_free(struct snd_pcm_substream *substream) { - pr_debug("sst: snd_intelmad_hw_free called\n"); + pr_debug("snd_intelmad_hw_free called\n"); return snd_pcm_lib_free_pages(substream); } @@ -253,12 +256,12 @@ static snd_pcm_uframes_t snd_intelmad_pcm_pointer ret_val = intelmaddata->sstdrv_ops->control_set(SST_SND_BUFFER_POINTER, &stream->stream_info); if (ret_val) { - pr_err("sst: error code = 0x%x\n", ret_val); + pr_err("error code = 0x%x\n", ret_val); return ret_val; } - pr_debug("sst: samples reported out 0x%llx\n", + pr_debug("samples reported out 0x%llx\n", stream->stream_info.buffer_ptr); - pr_debug("sst: Frame bits:: %d period_count :: %d\n", + pr_debug("Frame bits:: %d period_count :: %d\n", (int)substream->runtime->frame_bits, (int)substream->runtime->period_size); @@ -283,10 +286,10 @@ static int snd_intelmad_close(struct snd_pcm_substream *substream) stream = substream->runtime->private_data; - pr_debug("sst: snd_intelmad_close called\n"); + pr_debug("snd_intelmad_close called\n"); intelmaddata = snd_pcm_substream_chip(substream); - pr_debug("sst: str id = %d\n", stream->stream_info.str_id); + pr_debug("str id = %d\n", stream->stream_info.str_id); if (stream->stream_info.str_id) { /* SST API to actually stop/free the stream */ ret_val = intelmaddata->sstdrv_ops->control_set(SST_SND_FREE, @@ -296,7 +299,7 @@ static int snd_intelmad_close(struct snd_pcm_substream *substream) else intelmaddata->capture_cnt--; } - pr_debug("sst: snd_intelmad_close : pb cnt = %d cap cnt = %d\n", + pr_debug("snd_intelmad_close : pb cnt = %d cap cnt = %d\n", intelmaddata->playback_cnt, intelmaddata->capture_cnt); kfree(substream->runtime->private_data); return ret_val; @@ -319,7 +322,7 @@ static int snd_intelmad_open(struct snd_pcm_substream *substream, WARN_ON(!substream); - pr_debug("sst: snd_intelmad_open called\n"); + pr_debug("snd_intelmad_open called\n"); intelmaddata = snd_pcm_substream_chip(substream); runtime = substream->runtime; @@ -456,17 +459,17 @@ void sst_mad_send_jack_report(struct snd_jack *jack, { if (!jack) { - pr_debug("sst: MAD error jack empty\n"); + pr_debug("MAD error jack empty\n"); } else { - pr_debug("sst: MAD send jack report for = %d!!!\n", status); - pr_debug("sst: MAD send jack report %d\n", jack->type); + pr_debug("MAD send jack report for = %d!!!\n", status); + pr_debug("MAD send jack report %d\n", jack->type); snd_jack_report(jack, status); /*button pressed and released */ if (buttonpressevent) snd_jack_report(jack, 0); - pr_debug("sst: MAD sending jack report Done !!!\n"); + pr_debug("MAD sending jack report Done !!!\n"); } @@ -490,7 +493,7 @@ void sst_mad_jackdetection_fs(u8 intsts , struct snd_intelmad *intelmaddata) if (intsts & 0x4) { if (!(intelmid_audio_interrupt_enable)) { - pr_debug("sst: Audio interrupt enable\n"); + pr_debug("Audio interrupt enable\n"); sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 3); sst_sc_reg_access(sc_access_write, PMIC_WRITE, 1); @@ -500,7 +503,7 @@ void sst_mad_jackdetection_fs(u8 intsts , struct snd_intelmad *intelmaddata) } /* send headphone detect */ - pr_debug("sst: MAD headphone %d\n", intsts & 0x4); + pr_debug("MAD headphone %d\n", intsts & 0x4); jack = &intelmaddata->jack[0].jack; present = !(intelmaddata->jack[0].jack_status); intelmaddata->jack[0].jack_status = present; @@ -510,7 +513,7 @@ void sst_mad_jackdetection_fs(u8 intsts , struct snd_intelmad *intelmaddata) if (intsts & 0x2) { /* send short push */ - pr_debug("sst: MAD short push %d\n", intsts & 0x2); + pr_debug("MAD short push %d\n", intsts & 0x2); jack = &intelmaddata->jack[2].jack; present = 1; jack_event_flag = 1; @@ -518,7 +521,7 @@ void sst_mad_jackdetection_fs(u8 intsts , struct snd_intelmad *intelmaddata) } if (intsts & 0x1) { /* send long push */ - pr_debug("sst: MAD long push %d\n", intsts & 0x1); + pr_debug("MAD long push %d\n", intsts & 0x1); jack = &intelmaddata->jack[3].jack; present = 1; jack_event_flag = 1; @@ -526,7 +529,7 @@ void sst_mad_jackdetection_fs(u8 intsts , struct snd_intelmad *intelmaddata) } if (intsts & 0x8) { if (!(intelmid_audio_interrupt_enable)) { - pr_debug("sst: Audio interrupt enable\n"); + pr_debug("Audio interrupt enable\n"); sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 3); sst_sc_reg_access(sc_access_write, PMIC_WRITE, 1); @@ -535,7 +538,7 @@ void sst_mad_jackdetection_fs(u8 intsts , struct snd_intelmad *intelmaddata) intelmaddata->jack[1].jack_status = 0; } /* send headset detect */ - pr_debug("sst: MAD headset = %d\n", intsts & 0x8); + pr_debug("MAD headset = %d\n", intsts & 0x8); jack = &intelmaddata->jack[1].jack; present = !(intelmaddata->jack[1].jack_status); intelmaddata->jack[1].jack_status = present; @@ -558,10 +561,10 @@ void sst_mad_jackdetection_mx(u8 intsts, struct snd_intelmad *intelmaddata) scard_ops = intelmaddata->sstdrv_ops->scard_ops; - pr_debug("sst: previous value: %x\n", intelmaddata->jack_prev_state); + pr_debug("previous value: %x\n", intelmaddata->jack_prev_state); if (!(intelmid_audio_interrupt_enable)) { - pr_debug("sst: Audio interrupt enable\n"); + pr_debug("Audio interrupt enable\n"); intelmaddata->jack_prev_state = 0xC0; intelmid_audio_interrupt_enable = 1; } @@ -572,12 +575,12 @@ void sst_mad_jackdetection_mx(u8 intsts, struct snd_intelmad *intelmaddata) sc_access_read.reg_addr = 0x201; sst_sc_reg_access(&sc_access_read, PMIC_READ, 1); value = (sc_access_read.value); - pr_debug("sst: value returned = 0x%x\n", value); + pr_debug("value returned = 0x%x\n", value); } if (jack_prev_state == 0xc0 && value == 0x40) { /*headset detected. */ - pr_debug("sst: MAD headset inserted\n"); + pr_debug("MAD headset inserted\n"); jack = &intelmaddata->jack[1].jack; present = 1; jack_event_flag = 1; @@ -587,7 +590,7 @@ void sst_mad_jackdetection_mx(u8 intsts, struct snd_intelmad *intelmaddata) if (jack_prev_state == 0xc0 && value == 0x00) { /* headphone detected. */ - pr_debug("sst: MAD headphone inserted\n"); + pr_debug("MAD headphone inserted\n"); jack = &intelmaddata->jack[0].jack; present = 1; jack_event_flag = 1; @@ -596,9 +599,9 @@ void sst_mad_jackdetection_mx(u8 intsts, struct snd_intelmad *intelmaddata) if (jack_prev_state == 0x40 && value == 0xc0) { /*headset removed*/ - pr_debug("sst: Jack headset status %d\n", + pr_debug("Jack headset status %d\n", intelmaddata->jack[1].jack_status); - pr_debug("sst: MAD headset removed\n"); + pr_debug("MAD headset removed\n"); jack = &intelmaddata->jack[1].jack; present = 0; jack_event_flag = 1; @@ -607,9 +610,9 @@ void sst_mad_jackdetection_mx(u8 intsts, struct snd_intelmad *intelmaddata) if (jack_prev_state == 0x00 && value == 0xc0) { /* headphone detected. */ - pr_debug("sst: Jack headphone status %d\n", + pr_debug("Jack headphone status %d\n", intelmaddata->jack[0].jack_status); - pr_debug("sst: headphone removed\n"); + pr_debug("headphone removed\n"); jack = &intelmaddata->jack[0].jack; present = 0; jack_event_flag = 1; @@ -618,7 +621,7 @@ void sst_mad_jackdetection_mx(u8 intsts, struct snd_intelmad *intelmaddata) if (jack_prev_state == 0x40 && value == 0x00) { /*button pressed*/ do_gettimeofday(&intelmaddata->jack[1].buttonpressed); - pr_debug("sst: MAD button press detected n"); + pr_debug("MAD button press detected\n"); } @@ -628,19 +631,19 @@ void sst_mad_jackdetection_mx(u8 intsts, struct snd_intelmad *intelmaddata) do_gettimeofday( &intelmaddata->jack[1].buttonreleased); /*button pressed */ - pr_debug("sst: Button Released detected\n"); + pr_debug("Button Released detected\n"); timediff = intelmaddata->jack[1]. buttonreleased.tv_sec - intelmaddata-> jack[1].buttonpressed.tv_sec; buttonpressflag = 1; if (timediff > 1) { - pr_debug("sst: long press detected\n"); + pr_debug("long press detected\n"); /* send headphone detect/undetect */ jack = &intelmaddata->jack[3].jack; present = 1; jack_event_flag = 1; } else { - pr_debug("sst: short press detected\n"); + pr_debug("short press detected\n"); /* send headphone detect/undetect */ jack = &intelmaddata->jack[2].jack; present = 1; @@ -667,24 +670,24 @@ void sst_mad_jackdetection_nec(u8 intsts, struct snd_intelmad *intelmaddata) sc_access_read.reg_addr = 0x132; sst_sc_reg_access(&sc_access_read, PMIC_READ, 1); value = (sc_access_read.value); - pr_debug("sst: value returned = 0x%x\n", value); + pr_debug("value returned = 0x%x\n", value); } if (intsts & 0x1) { - pr_debug("sst: headset detected\n"); + pr_debug("headset detected\n"); /* send headset detect/undetect */ jack = &intelmaddata->jack[1].jack; present = (value == 0x1) ? 1 : 0; jack_event_flag = 1; } if (intsts & 0x2) { - pr_debug("sst: headphone detected\n"); + pr_debug("headphone detected\n"); /* send headphone detect/undetect */ jack = &intelmaddata->jack[0].jack; present = (value == 0x2) ? 1 : 0; jack_event_flag = 1; } if (intsts & 0x4) { - pr_debug("sst: short push detected\n"); + pr_debug("short push detected\n"); /* send short push */ jack = &intelmaddata->jack[2].jack; present = 1; @@ -692,7 +695,7 @@ void sst_mad_jackdetection_nec(u8 intsts, struct snd_intelmad *intelmaddata) buttonpressflag = 1; } if (intsts & 0x8) { - pr_debug("sst: long push detected\n"); + pr_debug("long push detected\n"); /* send long push */ jack = &intelmaddata->jack[3].jack; present = 1; @@ -738,12 +741,12 @@ static int __devinit snd_intelmad_register_irq( u32 regbase = AUDINT_BASE, regsize = 8; char *drv_name; - pr_debug("sst: irq reg done, regbase 0x%x, regsize 0x%x\n", + pr_debug("irq reg done, regbase 0x%x, regsize 0x%x\n", regbase, regsize); intelmaddata->int_base = ioremap_nocache(regbase, regsize); if (!intelmaddata->int_base) - pr_err("sst: Mapping of cache failed\n"); - pr_debug("sst: irq = 0x%x\n", intelmaddata->irq); + pr_err("Mapping of cache failed\n"); + pr_debug("irq = 0x%x\n", intelmaddata->irq); if (intelmaddata->cpu_id == CPU_CHIP_PENWELL) drv_name = DRIVER_NAME_MFLD; else @@ -753,7 +756,7 @@ static int __devinit snd_intelmad_register_irq( IRQF_SHARED, drv_name, intelmaddata); if (ret_val) - pr_err("sst: cannot register IRQ\n"); + pr_err("cannot register IRQ\n"); return ret_val; } @@ -775,10 +778,10 @@ static int __devinit snd_intelmad_sst_register( if (ret_val) return ret_val; sst_card_vendor_id = (vendor_addr.value & (MASK2|MASK1|MASK0)); - pr_debug("sst: orginal n extrated vendor id = 0x%x %d\n", + pr_debug("orginal n extrated vendor id = 0x%x %d\n", vendor_addr.value, sst_card_vendor_id); if (sst_card_vendor_id < 0 || sst_card_vendor_id > 2) { - pr_err("sst: vendor card not supported!!\n"); + pr_err("vendor card not supported!!\n"); return -EIO; } } else @@ -801,7 +804,7 @@ static int __devinit snd_intelmad_sst_register( /* registering with SST driver to get access to SST APIs to use */ ret_val = register_sst_card(intelmaddata->sstdrv_ops); if (ret_val) { - pr_err("sst: sst card registration failed\n"); + pr_err("sst card registration failed\n"); return ret_val; } @@ -832,7 +835,7 @@ static int __devinit snd_intelmad_pcm_new(struct snd_card *card, char name[32] = INTEL_MAD; struct snd_pcm_ops *pb_ops = NULL, *cap_ops = NULL; - pr_debug("sst: called for pb %d, cp %d, idx %d\n", pb, cap, index); + pr_debug("called for pb %d, cp %d, idx %d\n", pb, cap, index); ret_val = snd_pcm_new(card, name, index, pb, cap, &pcm); if (ret_val) return ret_val; @@ -878,7 +881,7 @@ static int __devinit snd_intelmad_pcm(struct snd_card *card, WARN_ON(!card); WARN_ON(!intelmaddata); - pr_debug("sst: snd_intelmad_pcm called\n"); + pr_debug("snd_intelmad_pcm called\n"); ret_val = snd_intelmad_pcm_new(card, intelmaddata, 1, 1, 0); if (intelmaddata->cpu_id == CPU_CHIP_LINCROFT) return ret_val; @@ -903,7 +906,7 @@ static int snd_intelmad_jack(struct snd_intelmad *intelmaddata) struct snd_jack *jack; int retval; - pr_debug("sst: snd_intelmad_jack called\n"); + pr_debug("snd_intelmad_jack called\n"); jack = &intelmaddata->jack[0].jack; retval = snd_jack_new(intelmaddata->card, "Headphone", SND_JACK_HEADPHONE, &jack); @@ -982,9 +985,9 @@ static int __devinit snd_intelmad_mixer(struct snd_intelmad *intelmaddata) ret_val = snd_ctl_add(card, snd_ctl_new1(&controls[idx], intelmaddata)); - pr_debug("sst: mixer[idx]=%d added\n", idx); + pr_debug("mixer[idx]=%d added\n", idx); if (ret_val) { - pr_err("sst: in adding of control index = %d\n", idx); + pr_err("in adding of control index = %d\n", idx); break; } } @@ -999,7 +1002,7 @@ static int snd_intelmad_dev_free(struct snd_device *device) intelmaddata = device->device_data; - pr_debug("sst: snd_intelmad_dev_free called\n"); + pr_debug("snd_intelmad_dev_free called\n"); snd_card_free(intelmaddata->card); /*genl_unregister_family(&audio_event_genl_family);*/ unregister_sst_card(intelmaddata->sstdrv_ops); @@ -1040,23 +1043,23 @@ int __devinit snd_intelmad_probe(struct platform_device *pdev) const struct platform_device_id *id = platform_get_device_id(pdev); unsigned int cpu_id = (unsigned int)id->driver_data; - pr_debug("sst: probe for %s cpu_id %d\n", pdev->name, cpu_id); + pr_debug("probe for %s cpu_id %d\n", pdev->name, cpu_id); if (!strcmp(pdev->name, DRIVER_NAME_MRST)) - pr_debug("sst: detected MRST\n"); + pr_debug("detected MRST\n"); else if (!strcmp(pdev->name, DRIVER_NAME_MFLD)) - pr_debug("sst: detected MFLD\n"); + pr_debug("detected MFLD\n"); else { - pr_err("sst: detected unknown device abort!!\n"); + pr_err("detected unknown device abort!!\n"); return -EIO; } if ((cpu_id < CPU_CHIP_LINCROFT) || (cpu_id > CPU_CHIP_PENWELL)) { - pr_err("sst: detected unknown cpu_id abort!!\n"); + pr_err("detected unknown cpu_id abort!!\n"); return -EIO; } /* allocate memory for saving internal context and working */ intelmaddata = kzalloc(sizeof(*intelmaddata), GFP_KERNEL); if (!intelmaddata) { - pr_debug("sst: mem alloctn fail\n"); + pr_debug("mem alloctn fail\n"); return -ENOMEM; } @@ -1064,7 +1067,7 @@ int __devinit snd_intelmad_probe(struct platform_device *pdev) intelmaddata->sstdrv_ops = kzalloc(sizeof(struct intel_sst_card_ops), GFP_KERNEL); if (!intelmaddata->sstdrv_ops) { - pr_err("sst: mem allocation for ops fail\n"); + pr_err("mem allocation for ops fail\n"); kfree(intelmaddata); return -ENOMEM; } @@ -1073,7 +1076,7 @@ int __devinit snd_intelmad_probe(struct platform_device *pdev) /* create a card instance with ALSA framework */ ret_val = snd_card_create(card_index, card_id, THIS_MODULE, 0, &card); if (ret_val) { - pr_err("sst: snd_card_create fail\n"); + pr_err("snd_card_create fail\n"); goto free_allocs; } @@ -1092,7 +1095,7 @@ int __devinit snd_intelmad_probe(struct platform_device *pdev) /* registering with LPE driver to get access to SST APIs to use */ ret_val = snd_intelmad_sst_register(intelmaddata); if (ret_val) { - pr_err("sst: snd_intelmad_sst_register failed\n"); + pr_err("snd_intelmad_sst_register failed\n"); goto free_allocs; } @@ -1100,19 +1103,19 @@ int __devinit snd_intelmad_probe(struct platform_device *pdev) ret_val = snd_intelmad_pcm(card, intelmaddata); if (ret_val) { - pr_err("sst: snd_intelmad_pcm failed\n"); + pr_err("snd_intelmad_pcm failed\n"); goto free_allocs; } ret_val = snd_intelmad_mixer(intelmaddata); if (ret_val) { - pr_err("sst: snd_intelmad_mixer failed\n"); + pr_err("snd_intelmad_mixer failed\n"); goto free_allocs; } ret_val = snd_intelmad_jack(intelmaddata); if (ret_val) { - pr_err("sst: snd_intelmad_jack failed\n"); + pr_err("snd_intelmad_jack failed\n"); goto free_allocs; } @@ -1126,31 +1129,31 @@ int __devinit snd_intelmad_probe(struct platform_device *pdev) ret_val = snd_intelmad_register_irq(intelmaddata); if (ret_val) { - pr_err("sst: snd_intelmad_register_irq fail\n"); + pr_err("snd_intelmad_register_irq fail\n"); goto free_allocs; } /* internal function call to register device with ALSA */ ret_val = snd_intelmad_create(intelmaddata, card); if (ret_val) { - pr_err("sst: snd_intelmad_create failed\n"); + pr_err("snd_intelmad_create failed\n"); goto free_allocs; } card->private_data = &intelmaddata; snd_card_set_dev(card, &pdev->dev); ret_val = snd_card_register(card); if (ret_val) { - pr_err("sst: snd_card_register failed\n"); + pr_err("snd_card_register failed\n"); goto free_allocs; } - pr_debug("sst:snd_intelmad_probe complete\n"); + pr_debug("snd_intelmad_probe complete\n"); return ret_val; free_mad_jack_wq: destroy_workqueue(intelmaddata->mad_jack_wq); free_allocs: - pr_err("sst: probe failed\n"); + pr_err("probe failed\n"); snd_card_free(card); kfree(intelmaddata->sstdrv_ops); kfree(intelmaddata); @@ -1200,7 +1203,7 @@ static struct platform_driver snd_intelmad_driver = { */ static int __init alsa_card_intelmad_init(void) { - pr_debug("sst: mad_init called\n"); + pr_debug("mad_init called\n"); return platform_driver_register(&snd_intelmad_driver); } @@ -1211,7 +1214,7 @@ static int __init alsa_card_intelmad_init(void) */ static void __exit alsa_card_intelmad_exit(void) { - pr_debug("sst:mad_exit called\n"); + pr_debug("mad_exit called\n"); return platform_driver_unregister(&snd_intelmad_driver); } diff --git a/drivers/staging/intel_sst/intelmid_ctrl.c b/drivers/staging/intel_sst/intelmid_ctrl.c index 03b4ece02f91..0d9135715c74 100644 --- a/drivers/staging/intel_sst/intelmid_ctrl.c +++ b/drivers/staging/intel_sst/intelmid_ctrl.c @@ -24,6 +24,9 @@ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * ALSA driver handling mixer controls for Intel MAD chipset */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include "jack.h" @@ -216,7 +219,7 @@ static int snd_intelmad_volume_get(struct snd_kcontrol *kcontrol, struct snd_intelmad *intelmaddata; struct snd_pmic_ops *scard_ops; - pr_debug("sst: snd_intelmad_volume_get called\n"); + pr_debug("snd_intelmad_volume_get called\n"); WARN_ON(!uval); WARN_ON(!kcontrol); @@ -273,7 +276,7 @@ static int snd_intelmad_mute_get(struct snd_kcontrol *kcontrol, struct snd_intelmad *intelmaddata; struct snd_pmic_ops *scard_ops; - pr_debug("sst: Mute_get called\n"); + pr_debug("Mute_get called\n"); WARN_ON(!uval); WARN_ON(!kcontrol); @@ -332,7 +335,7 @@ static int snd_intelmad_volume_set(struct snd_kcontrol *kcontrol, struct snd_intelmad *intelmaddata; struct snd_pmic_ops *scard_ops; - pr_debug("sst: volume set called:%ld %ld\n", + pr_debug("volume set called:%ld %ld\n", uval->value.integer.value[0], uval->value.integer.value[1]); @@ -387,7 +390,7 @@ static int snd_intelmad_mute_set(struct snd_kcontrol *kcontrol, struct snd_intelmad *intelmaddata; struct snd_pmic_ops *scard_ops; - pr_debug("sst: snd_intelmad_mute_set called\n"); + pr_debug("snd_intelmad_mute_set called\n"); WARN_ON(!uval); WARN_ON(!kcontrol); @@ -455,7 +458,7 @@ static int snd_intelmad_device_get(struct snd_kcontrol *kcontrol, { struct snd_intelmad *intelmaddata; struct snd_pmic_ops *scard_ops; - pr_debug("sst: device_get called\n"); + pr_debug("device_get called\n"); WARN_ON(!uval); WARN_ON(!kcontrol); @@ -492,7 +495,7 @@ static int snd_intelmad_device_set(struct snd_kcontrol *kcontrol, struct snd_pmic_ops *scard_ops; int ret_val = 0, vendor, status; - pr_debug("sst: snd_intelmad_device_set called\n"); + pr_debug("snd_intelmad_device_set called\n"); WARN_ON(!uval); WARN_ON(!kcontrol); diff --git a/drivers/staging/intel_sst/intelmid_msic_control.c b/drivers/staging/intel_sst/intelmid_msic_control.c index 4d1755efceef..da093ed0cd88 100644 --- a/drivers/staging/intel_sst/intelmid_msic_control.c +++ b/drivers/staging/intel_sst/intelmid_msic_control.c @@ -24,6 +24,8 @@ * This file contains the control operations of msic vendors */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include "intel_sst.h" @@ -83,7 +85,7 @@ static int msic_init_card(void) snd_msic_ops.cap_on = 0; snd_msic_ops.input_dev_id = DMIC; /*def dev*/ snd_msic_ops.output_dev_id = STEREO_HEADPHONE; - pr_debug("sst: msic init complete!!\n"); + pr_debug("msic init complete!!\n"); return 0; } @@ -173,7 +175,7 @@ static int msic_power_up_pb(unsigned int device) return retval; } - pr_debug("sst: powering up pb.... Device %d\n", device); + pr_debug("powering up pb.... Device %d\n", device); sst_sc_reg_access(sc_access1, PMIC_WRITE, 4); switch (device) { case SND_SST_DEVICE_HEADSET: @@ -205,7 +207,7 @@ static int msic_power_up_pb(unsigned int device) break; default: - pr_warn("sst: Wrong Device %d, selected %d\n", + pr_warn("Wrong Device %d, selected %d\n", device, snd_msic_ops.output_dev_id); } return sst_sc_reg_access(sc_access_pcm2, PMIC_READ_MODIFY, 1); @@ -268,7 +270,7 @@ static int msic_power_up_cp(unsigned int device) return retval; } - pr_debug("sst: powering up cp....%d\n", snd_msic_ops.input_dev_id); + pr_debug("powering up cp....%d\n", snd_msic_ops.input_dev_id); sst_sc_reg_access(sc_access2, PMIC_READ_MODIFY, 1); snd_msic_ops.cap_on = 1; if (snd_msic_ops.input_dev_id == AMIC) @@ -283,7 +285,7 @@ static int msic_power_down(void) { int retval = 0; - pr_debug("sst: powering dn msic\n"); + pr_debug("powering dn msic\n"); snd_msic_ops.pb_on = 0; snd_msic_ops.cap_on = 0; return retval; @@ -293,7 +295,7 @@ static int msic_power_down_pb(void) { int retval = 0; - pr_debug("sst: powering dn pb....\n"); + pr_debug("powering dn pb....\n"); snd_msic_ops.pb_on = 0; return retval; } @@ -302,7 +304,7 @@ static int msic_power_down_cp(void) { int retval = 0; - pr_debug("sst: powering dn cp....\n"); + pr_debug("powering dn cp....\n"); snd_msic_ops.cap_on = 0; return retval; } @@ -311,7 +313,7 @@ static int msic_set_selected_output_dev(u8 value) { int retval = 0; - pr_debug("sst: msic set selected output:%d\n", value); + pr_debug("msic set selected output:%d\n", value); snd_msic_ops.output_dev_id = value; if (snd_msic_ops.pb_on) msic_power_up_pb(SND_SST_DEVICE_HEADSET); @@ -330,15 +332,15 @@ static int msic_set_selected_input_dev(u8 value) }; int retval = 0; - pr_debug("sst: msic_set_selected_input_dev:%d\n", value); + pr_debug("msic_set_selected_input_dev:%d\n", value); snd_msic_ops.input_dev_id = value; switch (value) { case AMIC: - pr_debug("sst: Selecting AMIC1\n"); + pr_debug("Selecting AMIC1\n"); retval = sst_sc_reg_access(sc_access_amic, PMIC_WRITE, 1); break; case DMIC: - pr_debug("sst: Selecting DMIC1\n"); + pr_debug("Selecting DMIC1\n"); retval = sst_sc_reg_access(sc_access_dmic, PMIC_WRITE, 1); break; default: diff --git a/drivers/staging/intel_sst/intelmid_pvt.c b/drivers/staging/intel_sst/intelmid_pvt.c index 9ed9475ccc7b..4f9bdf364dca 100644 --- a/drivers/staging/intel_sst/intelmid_pvt.c +++ b/drivers/staging/intel_sst/intelmid_pvt.c @@ -23,6 +23,9 @@ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * ALSA driver for Intel MID sound card chipset - holding private functions */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -50,7 +53,7 @@ void period_elapsed(void *mad_substream) if (stream->stream_status != RUNNING) return; - pr_debug("sst: calling period elapsed\n"); + pr_debug("calling period elapsed\n"); snd_pcm_period_elapsed(substream); return; } @@ -76,8 +79,8 @@ int snd_intelmad_alloc_stream(struct snd_pcm_substream *substream) param.uc.pcm_params.period_count = substream->runtime->period_size; param.uc.pcm_params.ring_buffer_addr = virt_to_phys(substream->runtime->dma_area); - pr_debug("sst: period_cnt = %d\n", param.uc.pcm_params.period_count); - pr_debug("sst: sfreq= %d, wd_sz = %d\n", + pr_debug("period_cnt = %d\n", param.uc.pcm_params.period_count); + pr_debug("sfreq= %d, wd_sz = %d\n", param.uc.pcm_params.sfreq, param.uc.pcm_params.pcm_wd_sz); str_params.sparams = param; @@ -85,16 +88,16 @@ int snd_intelmad_alloc_stream(struct snd_pcm_substream *substream) if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { str_params.ops = STREAM_OPS_PLAYBACK; - pr_debug("sst: Playbck stream,Device %d\n", stream->device); + pr_debug("Playbck stream,Device %d\n", stream->device); } else { str_params.ops = STREAM_OPS_CAPTURE; stream->device = SND_SST_DEVICE_CAPTURE; - pr_debug("sst: Capture stream,Device %d\n", stream->device); + pr_debug("Capture stream,Device %d\n", stream->device); } str_params.device_type = stream->device; ret_val = intelmaddata->sstdrv_ops->control_set(SST_SND_ALLOC, &str_params); - pr_debug("sst: SST_SND_PLAY/CAPTURE ret_val = %x\n", + pr_debug("SST_SND_PLAY/CAPTURE ret_val = %x\n", ret_val); if (ret_val < 0) return ret_val; @@ -102,7 +105,7 @@ int snd_intelmad_alloc_stream(struct snd_pcm_substream *substream) stream->stream_info.str_id = ret_val; stream->stream_status = INIT; stream->stream_info.buffer_ptr = 0; - pr_debug("sst: str id : %d\n", stream->stream_info.str_id); + pr_debug("str id : %d\n", stream->stream_info.str_id); return ret_val; } @@ -113,7 +116,7 @@ int snd_intelmad_init_stream(struct snd_pcm_substream *substream) struct snd_intelmad *intelmaddata = snd_pcm_substream_chip(substream); int ret_val; - pr_debug("sst: setting buffer ptr param\n"); + pr_debug("setting buffer ptr param\n"); stream->stream_info.period_elapsed = period_elapsed; stream->stream_info.mad_substream = substream; stream->stream_info.buffer_ptr = 0; @@ -121,7 +124,7 @@ int snd_intelmad_init_stream(struct snd_pcm_substream *substream) ret_val = intelmaddata->sstdrv_ops->control_set(SST_SND_STREAM_INIT, &stream->stream_info); if (ret_val) - pr_err("sst: control_set ret error %d\n", ret_val); + pr_err("control_set ret error %d\n", ret_val); return ret_val; } @@ -146,7 +149,7 @@ int sst_sc_reg_access(struct sc_reg_access *sc_access, retval = intel_scu_ipc_iowrite8(sc_access[i].reg_addr, sc_access[i].value); if (retval) { - pr_err("sst: IPC write failed!!! %d\n", retval); + pr_err("IPC write failed!!! %d\n", retval); return retval; } } @@ -155,7 +158,7 @@ int sst_sc_reg_access(struct sc_reg_access *sc_access, retval = intel_scu_ipc_ioread8(sc_access[i].reg_addr, &(sc_access[i].value)); if (retval) { - pr_err("sst: IPC read failed!!!!!%d\n", retval); + pr_err("IPC read failed!!!!!%d\n", retval); return retval; } } @@ -165,7 +168,7 @@ int sst_sc_reg_access(struct sc_reg_access *sc_access, sc_access[i].reg_addr, sc_access[i].value, sc_access[i].mask); if (retval) { - pr_err("sst: IPC Modify failed!!!%d\n", retval); + pr_err("IPC Modify failed!!!%d\n", retval); return retval; } } diff --git a/drivers/staging/intel_sst/intelmid_v0_control.c b/drivers/staging/intel_sst/intelmid_v0_control.c index f586d62ac9af..7859225e3d60 100644 --- a/drivers/staging/intel_sst/intelmid_v0_control.c +++ b/drivers/staging/intel_sst/intelmid_v0_control.c @@ -26,6 +26,8 @@ * This file contains the control operations of vendor 1 */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include "intel_sst.h" @@ -151,7 +153,7 @@ static int fs_power_up_pb(unsigned int port) if (retval) return retval; - pr_debug("sst: in fs power up pb\n"); + pr_debug("in fs power up pb\n"); return fs_enable_audiodac(UNMUTE); } @@ -173,7 +175,7 @@ static int fs_power_down_pb(void) if (retval) return retval; - pr_debug("sst: in fsl power down pb\n"); + pr_debug("in fsl power down pb\n"); return fs_enable_audiodac(UNMUTE); } @@ -380,7 +382,7 @@ static int fs_set_pcm_audio_params(int sfreq, int word_size, int num_channel) sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 2); } - pr_debug("sst: sfreq:%d,Register value = %x\n", sfreq, config1); + pr_debug("sfreq:%d,Register value = %x\n", sfreq, config1); if (word_size == 24) { sc_access[0].reg_addr = AUDIOPORT1; @@ -438,18 +440,18 @@ static int fs_set_selected_input_dev(u8 value) switch (value) { case AMIC: - pr_debug("sst: Selecting amic not supported in mono cfg\n"); + pr_debug("Selecting amic not supported in mono cfg\n"); return sst_sc_reg_access(sc_access_mic, PMIC_READ_MODIFY, 2); break; case HS_MIC: - pr_debug("sst: Selecting hsmic\n"); + pr_debug("Selecting hsmic\n"); return sst_sc_reg_access(sc_access_hsmic, PMIC_READ_MODIFY, 2); break; case DMIC: - pr_debug("sst: Selecting dmic\n"); + pr_debug("Selecting dmic\n"); return sst_sc_reg_access(sc_access_dmic, PMIC_READ_MODIFY, 2); break; @@ -505,7 +507,7 @@ static int fs_set_mute(int dev_id, u8 value) return retval; - pr_debug("sst: dev_id:0x%x value:0x%x\n", dev_id, value); + pr_debug("dev_id:0x%x value:0x%x\n", dev_id, value); switch (dev_id) { case PMIC_SND_DMIC_MUTE: sc_access[0].reg_addr = MICCTRL; @@ -606,7 +608,7 @@ static int fs_set_vol(int dev_id, int value) switch (dev_id) { case PMIC_SND_LEFT_PB_VOL: - pr_debug("sst: PMIC_SND_LEFT_PB_VOL:%d\n", value); + pr_debug("PMIC_SND_LEFT_PB_VOL:%d\n", value); sc_access[0].value = sc_access[1].value = value; sc_access[0].reg_addr = AUD16; sc_access[1].reg_addr = AUD15; @@ -616,7 +618,7 @@ static int fs_set_vol(int dev_id, int value) break; case PMIC_SND_RIGHT_PB_VOL: - pr_debug("sst: PMIC_SND_RIGHT_PB_VOL:%d\n", value); + pr_debug("PMIC_SND_RIGHT_PB_VOL:%d\n", value); sc_access[0].value = sc_access[1].value = value; sc_access[0].reg_addr = AUD17; sc_access[1].reg_addr = AUD15; @@ -629,7 +631,7 @@ static int fs_set_vol(int dev_id, int value) reg_num = 2; break; case PMIC_SND_CAPTURE_VOL: - pr_debug("sst: PMIC_SND_CAPTURE_VOL:%d\n", value); + pr_debug("PMIC_SND_CAPTURE_VOL:%d\n", value); sc_access[0].reg_addr = MICLICTRL1; sc_access[1].reg_addr = MICLICTRL2; sc_access[2].reg_addr = DMICCTRL1; @@ -726,17 +728,17 @@ static int fs_get_vol(int dev_id, int *value) switch (dev_id) { case PMIC_SND_CAPTURE_VOL: - pr_debug("sst: PMIC_SND_CAPTURE_VOL\n"); + pr_debug("PMIC_SND_CAPTURE_VOL\n"); sc_access.reg_addr = MICLICTRL1; mask = (MASK5|MASK4|MASK3|MASK2|MASK1|MASK0); break; case PMIC_SND_LEFT_PB_VOL: - pr_debug("sst: PMIC_SND_LEFT_PB_VOL\n"); + pr_debug("PMIC_SND_LEFT_PB_VOL\n"); sc_access.reg_addr = AUD16; mask = (MASK5|MASK4|MASK3|MASK2|MASK1|MASK0); break; case PMIC_SND_RIGHT_PB_VOL: - pr_debug("sst: PMIC_SND_RT_PB_VOL\n"); + pr_debug("PMIC_SND_RT_PB_VOL\n"); sc_access.reg_addr = AUD17; mask = (MASK5|MASK4|MASK3|MASK2|MASK1|MASK0); break; @@ -745,9 +747,9 @@ static int fs_get_vol(int dev_id, int *value) } retval = sst_sc_reg_access(&sc_access, PMIC_READ, 1); - pr_debug("sst: value read = 0x%x\n", sc_access.value); + pr_debug("value read = 0x%x\n", sc_access.value); *value = (int) (sc_access.value & mask); - pr_debug("sst: value returned = 0x%x\n", *value); + pr_debug("value returned = 0x%x\n", *value); return retval; } diff --git a/drivers/staging/intel_sst/intelmid_v1_control.c b/drivers/staging/intel_sst/intelmid_v1_control.c index 9de86b2f6b08..62a932bf809a 100644 --- a/drivers/staging/intel_sst/intelmid_v1_control.c +++ b/drivers/staging/intel_sst/intelmid_v1_control.c @@ -25,6 +25,8 @@ * This file contains the control operations of vendor 2 */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -150,11 +152,11 @@ static int mx_init_capture_card(void) retval = sst_sc_reg_access(sc_access, PMIC_WRITE, 8); if (0 != retval) { /* pmic communication fails */ - pr_debug("sst: pmic commn failed\n"); + pr_debug("pmic commn failed\n"); return retval; } - pr_debug("sst: Capture configuration complete!!\n"); + pr_debug("Capture configuration complete!!\n"); return 0; } @@ -174,11 +176,11 @@ static int mx_init_playback_card(void) retval = sst_sc_reg_access(sc_access, PMIC_WRITE, 9); if (0 != retval) { /* pmic communication fails */ - pr_debug("sst: pmic commn failed\n"); + pr_debug("pmic commn failed\n"); return retval; } - pr_debug("sst: Playback configuration complete!!\n"); + pr_debug("Playback configuration complete!!\n"); return 0; } @@ -204,7 +206,7 @@ static int mx_enable_audiodac(int value) retval = sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 2); if (retval) return retval; - pr_debug("sst: mute status = %d", snd_pmic_ops_mx.mute_status); + pr_debug("mute status = %d\n", snd_pmic_ops_mx.mute_status); if (snd_pmic_ops_mx.mute_status == MUTE || snd_pmic_ops_mx.master_mute == MUTE) return retval; @@ -412,7 +414,7 @@ static int mx_set_pcm_voice_params(void) if (retval) return retval; } - pr_debug("sst: SST DBG mx_set_pcm_voice_params called\n"); + pr_debug("SST DBG:mx_set_pcm_voice_params called\n"); return sst_sc_reg_access(sc_access, PMIC_WRITE, 44); } @@ -529,7 +531,7 @@ static int mx_set_selected_output_dev(u8 dev_id) return retval; } - pr_debug("sst: mx_set_selected_output_dev dev_id:0x%x\n", dev_id); + pr_debug("mx_set_selected_output_dev dev_id:0x%x\n", dev_id); snd_pmic_ops_mx.output_dev_id = dev_id; switch (dev_id) { case STEREO_HEADPHONE: @@ -549,7 +551,7 @@ static int mx_set_selected_output_dev(u8 dev_id) num_reg = 1; break; case RECEIVER: - pr_debug("sst: RECEIVER Koski selected\n"); + pr_debug("RECEIVER Koski selected\n"); /* configuration - AS enable, receiver enable */ sc_access[0].reg_addr = 0xFF; @@ -559,7 +561,7 @@ static int mx_set_selected_output_dev(u8 dev_id) num_reg = 1; break; default: - pr_err("sst: Not a valid output dev\n"); + pr_err("Not a valid output dev\n"); return 0; } return sst_sc_reg_access(sc_access, PMIC_WRITE, num_reg); @@ -598,7 +600,7 @@ static int mx_set_selected_input_dev(u8 dev_id) return retval; } snd_pmic_ops_mx.input_dev_id = dev_id; - pr_debug("sst: mx_set_selected_input_dev dev_id:0x%x\n", dev_id); + pr_debug("mx_set_selected_input_dev dev_id:0x%x\n", dev_id); switch (dev_id) { case AMIC: @@ -646,7 +648,7 @@ static int mx_set_mute(int dev_id, u8 value) } - pr_debug("sst: set_mute dev_id:0x%x , value:%d\n", dev_id, value); + pr_debug("set_mute dev_id:0x%x , value:%d\n", dev_id, value); switch (dev_id) { case PMIC_SND_DMIC_MUTE: @@ -760,7 +762,7 @@ static int mx_set_vol(int dev_id, int value) if (retval) return retval; } - pr_debug("sst: set_vol dev_id:0x%x ,value:%d\n", dev_id, value); + pr_debug("set_vol dev_id:0x%x ,value:%d\n", dev_id, value); switch (dev_id) { case PMIC_SND_RECEIVER_VOL: return 0; @@ -875,7 +877,7 @@ static int mx_get_vol(int dev_id, int *value) if (retval) return retval; *value = -(sc_access.value & mask); - pr_debug("sst: get volume value extracted %d\n", *value); + pr_debug("get volume value extracted %d\n", *value); return retval; } diff --git a/drivers/staging/intel_sst/intelmid_v2_control.c b/drivers/staging/intel_sst/intelmid_v2_control.c index 3a7de769842a..81cb9d70870b 100644 --- a/drivers/staging/intel_sst/intelmid_v2_control.c +++ b/drivers/staging/intel_sst/intelmid_v2_control.c @@ -26,6 +26,8 @@ * This file contains the control operations of vendor 3 */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include "intel_sst.h" @@ -120,7 +122,7 @@ static int nc_init_card(void) snd_pmic_ops_nc.master_mute = UNMUTE; snd_pmic_ops_nc.mute_status = UNMUTE; sst_sc_reg_access(sc_access, PMIC_WRITE, 26); - pr_debug("sst: init complete!!\n"); + pr_debug("init complete!!\n"); return 0; } @@ -169,7 +171,7 @@ static int nc_power_up_pb(unsigned int port) nc_enable_audiodac(MUTE); msleep(30); - pr_debug("sst: powering up pb....\n"); + pr_debug("powering up pb....\n"); sc_access[0].reg_addr = VAUDIOCNT; sc_access[0].value = 0x27; @@ -222,7 +224,7 @@ static int nc_power_up_cp(unsigned int port) return retval; - pr_debug("sst: powering up cp....\n"); + pr_debug("powering up cp....\n"); if (port == 0xFF) return 0; @@ -275,7 +277,7 @@ static int nc_power_down(void) nc_enable_audiodac(MUTE); - pr_debug("sst: powering dn nc_power_down ....\n"); + pr_debug("powering dn nc_power_down ....\n"); msleep(30); @@ -324,7 +326,7 @@ static int nc_power_down_pb(void) if (retval) return retval; - pr_debug("sst: powering dn pb....\n"); + pr_debug("powering dn pb....\n"); nc_enable_audiodac(MUTE); @@ -370,7 +372,7 @@ static int nc_power_down_cp(void) if (retval) return retval; - pr_debug("sst: powering dn cp....\n"); + pr_debug("powering dn cp....\n"); return sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 1); } @@ -400,7 +402,7 @@ static int nc_set_pcm_voice_params(void) return retval; sst_sc_reg_access(sc_access, PMIC_WRITE, 14); - pr_debug("sst: Voice parameters set successfully!!\n"); + pr_debug("Voice parameters set successfully!!\n"); return 0; } @@ -451,20 +453,20 @@ static int nc_set_pcm_audio_params(int sfreq, int word_size, int num_channel) sc_access.value = 0x07; sc_access.reg_addr = RMUTE; - pr_debug("sst: RIGHT_HP_MUTE value%d\n", sc_access.value); + pr_debug("RIGHT_HP_MUTE value%d\n", sc_access.value); sc_access.mask = MASK2; sst_sc_reg_access(&sc_access, PMIC_READ_MODIFY, 1); } else { sc_access.value = 0x00; sc_access.reg_addr = RMUTE; - pr_debug("sst: RIGHT_HP_MUTE value %d\n", sc_access.value); + pr_debug("RIGHT_HP_MUTE value %d\n", sc_access.value); sc_access.mask = MASK2; sst_sc_reg_access(&sc_access, PMIC_READ_MODIFY, 1); } - pr_debug("sst: word_size = %d\n", word_size); + pr_debug("word_size = %d\n", word_size); if (word_size == 24) { sc_access.reg_addr = AUDIOPORT2; @@ -477,7 +479,7 @@ static int nc_set_pcm_audio_params(int sfreq, int word_size, int num_channel) } sst_sc_reg_access(&sc_access, PMIC_READ_MODIFY, 1); - pr_debug("sst: word_size = %d\n", word_size); + pr_debug("word_size = %d\n", word_size); sc_access.reg_addr = AUDIOPORT1; sc_access.mask = MASK5|MASK4|MASK1|MASK0; if (word_size == 16) @@ -508,7 +510,7 @@ static int nc_set_selected_output_dev(u8 value) retval = nc_init_card(); if (retval) return retval; - pr_debug("sst: nc set selected output:%d\n", value); + pr_debug("nc set selected output:%d\n", value); switch (value) { case STEREO_HEADPHONE: retval = sst_sc_reg_access(sc_access_HP, PMIC_WRITE, 2); @@ -517,7 +519,7 @@ static int nc_set_selected_output_dev(u8 value) retval = sst_sc_reg_access(sc_access_IS, PMIC_WRITE, 2); break; default: - pr_err("sst: rcvd illegal request: %d\n", value); + pr_err("rcvd illegal request: %d\n", value); return -EINVAL; } return retval; @@ -541,7 +543,7 @@ static int nc_audio_init(void) }; sst_sc_reg_access(sc_access, PMIC_WRITE, 12); - pr_debug("sst: Audio Init successfully!!\n"); + pr_debug("Audio Init successfully!!\n"); /*set output device */ nc_set_selected_output_dev(snd_pmic_ops_nc.output_dev_id); @@ -549,13 +551,13 @@ static int nc_audio_init(void) if (snd_pmic_ops_nc.num_channel == 1) { sc_acces.value = 0x07; sc_acces.reg_addr = RMUTE; - pr_debug("sst: RIGHT_HP_MUTE value%d\n", sc_acces.value); + pr_debug("RIGHT_HP_MUTE value%d\n", sc_acces.value); sc_acces.mask = MASK2; sst_sc_reg_access(&sc_acces, PMIC_READ_MODIFY, 1); } else { sc_acces.value = 0x00; sc_acces.reg_addr = RMUTE; - pr_debug("sst: RIGHT_HP_MUTE value%d\n", sc_acces.value); + pr_debug("RIGHT_HP_MUTE value%d\n", sc_acces.value); sc_acces.mask = MASK2; sst_sc_reg_access(&sc_acces, PMIC_READ_MODIFY, 1); } @@ -629,11 +631,11 @@ static int nc_set_mute(int dev_id, u8 value) if (retval) return retval; - pr_debug("sst: set device id::%d, value %d\n", dev_id, value); + pr_debug("set device id::%d, value %d\n", dev_id, value); switch (dev_id) { case PMIC_SND_MUTE_ALL: - pr_debug("sst: PMIC_SND_MUTE_ALL value %d\n", value); + pr_debug("PMIC_SND_MUTE_ALL value %d\n", value); snd_pmic_ops_nc.mute_status = value; snd_pmic_ops_nc.master_mute = value; if (value == UNMUTE) { @@ -669,7 +671,7 @@ static int nc_set_mute(int dev_id, u8 value) } break; case PMIC_SND_HP_MIC_MUTE: - pr_debug("sst: PMIC_SND_HPMIC_MUTE value %d\n", value); + pr_debug("PMIC_SND_HPMIC_MUTE value %d\n", value); if (value == UNMUTE) { /* unmute the system, set the 6th bit to one */ sc_access[0].value = 0x00; @@ -682,7 +684,7 @@ static int nc_set_mute(int dev_id, u8 value) retval = sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 1); break; case PMIC_SND_AMIC_MUTE: - pr_debug("sst: PMIC_SND_AMIC_MUTE value %d\n", value); + pr_debug("PMIC_SND_AMIC_MUTE value %d\n", value); if (value == UNMUTE) { /* unmute the system, set the 6th bit to one */ sc_access[0].value = 0x00; @@ -696,7 +698,7 @@ static int nc_set_mute(int dev_id, u8 value) break; case PMIC_SND_DMIC_MUTE: - pr_debug("sst: INPUT_MUTE_DMIC value%d\n", value); + pr_debug("INPUT_MUTE_DMIC value%d\n", value); if (value == UNMUTE) { /* unmute the system, set the 6th bit to one */ sc_access[1].value = 0x00; @@ -724,13 +726,13 @@ static int nc_set_mute(int dev_id, u8 value) if (dev_id == PMIC_SND_LEFT_HP_MUTE) { sc_access[0].reg_addr = LMUTE; - pr_debug("sst: LEFT_HP_MUTE value %d\n", + pr_debug("LEFT_HP_MUTE value %d\n", sc_access[0].value); } else { if (snd_pmic_ops_nc.num_channel == 1) sc_access[0].value = 0x04; sc_access[0].reg_addr = RMUTE; - pr_debug("sst: RIGHT_HP_MUTE value %d\n", + pr_debug("RIGHT_HP_MUTE value %d\n", sc_access[0].value); } sc_access[0].mask = MASK2; @@ -743,7 +745,7 @@ static int nc_set_mute(int dev_id, u8 value) else sc_access[0].value = 0x03; sc_access[0].reg_addr = LMUTE; - pr_debug("sst: SPEAKER_MUTE %d\n", sc_access[0].value); + pr_debug("SPEAKER_MUTE %d\n", sc_access[0].value); sc_access[0].mask = MASK1; retval = sst_sc_reg_access(sc_access, PMIC_READ_MODIFY, 1); break; @@ -764,10 +766,10 @@ static int nc_set_vol(int dev_id, int value) if (retval) return retval; - pr_debug("sst: set volume:%d\n", dev_id); + pr_debug("set volume:%d\n", dev_id); switch (dev_id) { case PMIC_SND_CAPTURE_VOL: - pr_debug("sst: PMIC_SND_CAPTURE_VOL:value::%d\n", value); + pr_debug("PMIC_SND_CAPTURE_VOL:value::%d\n", value); sc_access[0].value = sc_access[1].value = sc_access[2].value = -value; sc_access[0].mask = sc_access[1].mask = sc_access[2].mask = @@ -779,7 +781,7 @@ static int nc_set_vol(int dev_id, int value) break; case PMIC_SND_LEFT_PB_VOL: - pr_debug("sst: PMIC_SND_LEFT_HP_VOL %d\n", value); + pr_debug("PMIC_SND_LEFT_HP_VOL %d\n", value); sc_access[0].value = -value; sc_access[0].reg_addr = AUDIOLVOL; sc_access[0].mask = @@ -788,7 +790,7 @@ static int nc_set_vol(int dev_id, int value) break; case PMIC_SND_RIGHT_PB_VOL: - pr_debug("sst: PMIC_SND_RIGHT_HP_VOL value %d\n", value); + pr_debug("PMIC_SND_RIGHT_HP_VOL value %d\n", value); if (snd_pmic_ops_nc.num_channel == 1) { sc_access[0].value = 0x04; sc_access[0].reg_addr = RMUTE; @@ -821,11 +823,11 @@ static int nc_set_selected_input_dev(u8 value) return retval; snd_pmic_ops_nc.input_dev_id = value; - pr_debug("sst: nc set selected input:%d\n", value); + pr_debug("nc set selected input:%d\n", value); switch (value) { case AMIC: - pr_debug("sst: Selecting AMIC\n"); + pr_debug("Selecting AMIC\n"); sc_access[0].reg_addr = 0x107; sc_access[0].value = 0x40; sc_access[0].mask = MASK6|MASK4|MASK3|MASK1|MASK0; @@ -842,7 +844,7 @@ static int nc_set_selected_input_dev(u8 value) break; case HS_MIC: - pr_debug("sst: Selecting HS_MIC\n"); + pr_debug("Selecting HS_MIC\n"); sc_access[0].reg_addr = 0x107; sc_access[0].mask = MASK6|MASK4|MASK3|MASK1|MASK0; sc_access[0].value = 0x10; @@ -859,7 +861,7 @@ static int nc_set_selected_input_dev(u8 value) break; case DMIC: - pr_debug("sst: DMIC\n"); + pr_debug("DMIC\n"); sc_access[0].reg_addr = 0x107; sc_access[0].mask = MASK6|MASK4|MASK3|MASK1|MASK0; sc_access[0].value = 0x0B; @@ -890,23 +892,23 @@ static int nc_get_mute(int dev_id, u8 *value) if (retval) return retval; - pr_debug("sst: get mute::%d\n", dev_id); + pr_debug("get mute::%d\n", dev_id); switch (dev_id) { case PMIC_SND_AMIC_MUTE: - pr_debug("sst: PMIC_SND_INPUT_MUTE_MIC1\n"); + pr_debug("PMIC_SND_INPUT_MUTE_MIC1\n"); sc_access.reg_addr = LILSEL; mask = MASK6; break; case PMIC_SND_HP_MIC_MUTE: - pr_debug("sst: PMIC_SND_INPUT_MUTE_MIC2\n"); + pr_debug("PMIC_SND_INPUT_MUTE_MIC2\n"); sc_access.reg_addr = LIRSEL; mask = MASK6; break; case PMIC_SND_LEFT_HP_MUTE: case PMIC_SND_RIGHT_HP_MUTE: mask = MASK2; - pr_debug("sst: PMIC_SN_LEFT/RIGHT_HP_MUTE\n"); + pr_debug("PMIC_SN_LEFT/RIGHT_HP_MUTE\n"); if (dev_id == PMIC_SND_RIGHT_HP_MUTE) sc_access.reg_addr = RMUTE; else @@ -914,12 +916,12 @@ static int nc_get_mute(int dev_id, u8 *value) break; case PMIC_SND_LEFT_SPEAKER_MUTE: - pr_debug("sst: PMIC_MONO_EARPIECE_MUTE\n"); + pr_debug("PMIC_MONO_EARPIECE_MUTE\n"); sc_access.reg_addr = RMUTE; mask = MASK1; break; case PMIC_SND_DMIC_MUTE: - pr_debug("sst: PMIC_SND_INPUT_MUTE_DMIC\n"); + pr_debug("PMIC_SND_INPUT_MUTE_DMIC\n"); sc_access.reg_addr = 0x105; mask = MASK6; break; @@ -928,16 +930,16 @@ static int nc_get_mute(int dev_id, u8 *value) } retval = sst_sc_reg_access(&sc_access, PMIC_READ, 1); - pr_debug("sst: reg value = %d\n", sc_access.value); + pr_debug("reg value = %d\n", sc_access.value); if (retval) return retval; *value = (sc_access.value) & mask; - pr_debug("sst: masked value = %d\n", *value); + pr_debug("masked value = %d\n", *value); if (*value) *value = 0; else *value = 1; - pr_debug("sst: value returned = 0x%x\n", *value); + pr_debug("value returned = 0x%x\n", *value); return retval; } @@ -953,19 +955,19 @@ static int nc_get_vol(int dev_id, int *value) switch (dev_id) { case PMIC_SND_CAPTURE_VOL: - pr_debug("sst: PMIC_SND_INPUT_CAPTURE_VOL\n"); + pr_debug("PMIC_SND_INPUT_CAPTURE_VOL\n"); sc_access.reg_addr = LILSEL; mask = (MASK0|MASK1|MASK2|MASK3|MASK4|MASK5); break; case PMIC_SND_RIGHT_PB_VOL: - pr_debug("sst: GET_VOLUME_PMIC_LEFT_HP_VOL\n"); + pr_debug("GET_VOLUME_PMIC_LEFT_HP_VOL\n"); sc_access.reg_addr = AUDIOLVOL; mask = (MASK0|MASK1|MASK2|MASK3|MASK4|MASK5|MASK6); break; case PMIC_SND_LEFT_PB_VOL: - pr_debug("sst: GET_VOLUME_PMIC_RIGHT_HP_VOL\n"); + pr_debug("GET_VOLUME_PMIC_RIGHT_HP_VOL\n"); sc_access.reg_addr = AUDIORVOL; mask = (MASK0|MASK1|MASK2|MASK3|MASK4|MASK5|MASK6); break; @@ -975,9 +977,9 @@ static int nc_get_vol(int dev_id, int *value) } retval = sst_sc_reg_access(&sc_access, PMIC_READ, 1); - pr_debug("sst: value read = 0x%x\n", sc_access.value); + pr_debug("value read = 0x%x\n", sc_access.value); *value = -((sc_access.value) & mask); - pr_debug("sst: get vol value returned = %d\n", *value); + pr_debug("get vol value returned = %d\n", *value); return retval; } -- cgit v1.2.3 From dec34f85c62845a4d190a45aa5b5e9dd96797880 Mon Sep 17 00:00:00 2001 From: Tracey Dent Date: Fri, 22 Oct 2010 17:30:28 -0400 Subject: Staging: msm: Makefile: replace the use of -objs with -y Changed -objs to -y in Makefile. Signed-off-by: Tracey Dent Signed-off-by: Greg Kroah-Hartman --- drivers/staging/msm/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/msm/Makefile b/drivers/staging/msm/Makefile index bb3606faf20e..07a89ecfcc2b 100644 --- a/drivers/staging/msm/Makefile +++ b/drivers/staging/msm/Makefile @@ -41,11 +41,11 @@ obj-$(CONFIG_FB_MSM_EBI2) += ebi2_lcd.o obj-$(CONFIG_FB_MSM_LCDC) += lcdc.o # MDDI -msm_mddi-objs := mddi.o mddihost.o mddihosti.o +msm_mddi-y := mddi.o mddihost.o mddihosti.o obj-$(CONFIG_FB_MSM_MDDI) += msm_mddi.o # External MDDI -msm_mddi_ext-objs := mddihost_e.o mddi_ext.o +msm_mddi_ext-y := mddihost_e.o mddi_ext.o obj-$(CONFIG_FB_MSM_EXTMDDI) += msm_mddi_ext.o # TVEnc -- cgit v1.2.3 From c4fb2bab7dea7780452e57166bd00cdfa9dba6ef Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Tue, 26 Oct 2010 21:57:52 +0200 Subject: Staging: trivial: fix typos concerning "configure" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Uwe Kleine-König Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/rtd520.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/comedi/drivers/rtd520.c b/drivers/staging/comedi/drivers/rtd520.c index 60ebfc3c75fd..aa8aeeee043f 100644 --- a/drivers/staging/comedi/drivers/rtd520.c +++ b/drivers/staging/comedi/drivers/rtd520.c @@ -753,7 +753,7 @@ static int rtd_attach(struct comedi_device *dev, struct comedi_devconfig *it) struct comedi_subdevice *s; struct pci_dev *pcidev; int ret; - resource_size_t physLas0; /* configuation */ + resource_size_t physLas0; /* configuration */ resource_size_t physLas1; /* data area */ resource_size_t physLcfg; /* PLX9080 */ #ifdef USE_DMA -- cgit v1.2.3 From af02b584bc0e1f46cf1477ad54ae18ec3842b6f4 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Tue, 26 Oct 2010 21:57:53 +0200 Subject: Staging: trivial: fix typos concerning "controller" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Uwe Kleine-König Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/addi-data/addi_common.c | 4 ++-- drivers/staging/comedi/drivers/addi-data/hwdrv_APCI1710.c | 2 +- drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c | 2 +- drivers/staging/rtl8192u/r8192U_core.c | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/staging/comedi/drivers/addi-data/addi_common.c b/drivers/staging/comedi/drivers/addi-data/addi_common.c index 93d7c056741d..76f2483871a7 100644 --- a/drivers/staging/comedi/drivers/addi-data/addi_common.c +++ b/drivers/staging/comedi/drivers/addi-data/addi_common.c @@ -2710,10 +2710,10 @@ static int i_ADDI_Attach(struct comedi_device *dev, struct comedi_devconfig *it) } else { outl(0x83838383, devpriv->i_IobaseAmcc + 0x60); } - /* Enable the interrupt for the controler */ + /* Enable the interrupt for the controller */ dw_Dummy = inl(devpriv->i_IobaseAmcc + 0x38); outl(dw_Dummy | 0x2000, devpriv->i_IobaseAmcc + 0x38); - printk("\nEnable the interrupt for the controler"); + printk("\nEnable the interrupt for the controller"); } printk("\nRead Eeprom"); i_EepromReadMainHeader(io_addr[0], this_board->pc_EepromChip, diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_APCI1710.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_APCI1710.c index 912bc0fc54bf..a76ed2553fb4 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_APCI1710.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_APCI1710.c @@ -225,7 +225,7 @@ int i_APCI1710_Reset(struct comedi_device *dev) devpriv->s_BoardInfos.b_BoardVersion = 1; - /* Enable the interrupt for the controler */ + /* Enable the interrupt for the controller */ dw_Dummy = inl(devpriv->s_BoardInfos.ui_Address + 0x38); outl(dw_Dummy | 0x2000, devpriv->s_BoardInfos.ui_Address + 0x38); diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c index b943a06e70dc..a93e2349ad3a 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3200.c @@ -3011,7 +3011,7 @@ int i_APCI3200_Reset(struct comedi_device *dev) outl(0x83838383, devpriv->i_IobaseAmcc + 0x60); - /* Enable the interrupt for the controler */ + /* Enable the interrupt for the controller */ dw_Dummy = inl(devpriv->i_IobaseAmcc + 0x38); outl(dw_Dummy | 0x2000, devpriv->i_IobaseAmcc + 0x38); outl(0, devpriv->i_IobaseAddon); /* Resets the output */ diff --git a/drivers/staging/rtl8192u/r8192U_core.c b/drivers/staging/rtl8192u/r8192U_core.c index 494f180acc26..4cc7b418c91e 100644 --- a/drivers/staging/rtl8192u/r8192U_core.c +++ b/drivers/staging/rtl8192u/r8192U_core.c @@ -1507,7 +1507,7 @@ static void rtl8192_tx_isr(struct urb *tx_urb) { // // Handle HW Beacon: - // We had transfer our beacon frame to host controler at this moment. + // We had transfer our beacon frame to host controller at this moment. // // // Caution: -- cgit v1.2.3 From fc2347e2023221ef04c6d9ce84019aa8c7e0ad6d Mon Sep 17 00:00:00 2001 From: Atul Sowani Date: Wed, 3 Nov 2010 18:40:56 +0530 Subject: Staging: xgifb: change obsolete pci_find_device() with pci_get_device() Replaced obsolete pci_find_device() calls with pci_get_device() calls. This is recommended in pci.txt filei in PCI Documentation. Signed-off-by: Atul Sowani Acked-by: Arnaud Patard Signed-off-by: Greg Kroah-Hartman --- drivers/staging/xgifb/XGI_main_26.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/staging/xgifb/XGI_main_26.c b/drivers/staging/xgifb/XGI_main_26.c index 4f73d095c3ac..36ec45b84fca 100644 --- a/drivers/staging/xgifb/XGI_main_26.c +++ b/drivers/staging/xgifb/XGI_main_26.c @@ -472,9 +472,11 @@ unsigned char XGIfb_query_north_bridge_space(struct xgi_hw_device_info *pXGIhw_e break; } - pdev = pci_find_device(PCI_VENDOR_ID_SI, nbridge_id, pdev); - if (pdev) + pdev = pci_get_device(PCI_VENDOR_ID_SI, nbridge_id, pdev); + if (pdev) { valid_pdev = 1; + pci_dev_put(pdev); + } } if (!valid_pdev) { -- cgit v1.2.3 From 78fd115e21087133be74bc6dd7a9bc1969aea8f8 Mon Sep 17 00:00:00 2001 From: Ramesh Agarwal Date: Fri, 22 Oct 2010 14:00:20 +0100 Subject: Staging: add Synaptics TM1217 Touchscreen Controller driver This is submitted as a staging driver because there is a more generic driver "on the way" for all these devices and has been for some time. The intent is that as soon as the general drivers are in the mainstream this one will get any leftovers integrated and then be dumped. Until this unspecified future data at least people can actually use their hardware. As its interface is simply input layer we can do that without pain. Some clean up by Alan Cox - Extract gpio support and IRQ support more sanely - Tidying Signed-off-by: Ramesh Agarwal [avoid deference NULL ts if kzalloc fails] [finger_touched may be used uninitialized] [fix missing sync which confused twm] Signed-off-by: Hong Liu Signed-off-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/staging/Kconfig | 2 + drivers/staging/Makefile | 1 + drivers/staging/cptm1217/Kconfig | 11 + drivers/staging/cptm1217/Makefile | 2 + drivers/staging/cptm1217/TODO | 5 + drivers/staging/cptm1217/clearpad_tm1217.c | 675 +++++++++++++++++++++++++++++ drivers/staging/cptm1217/cp_tm1217.h | 9 + 7 files changed, 705 insertions(+) create mode 100644 drivers/staging/cptm1217/Kconfig create mode 100644 drivers/staging/cptm1217/Makefile create mode 100644 drivers/staging/cptm1217/TODO create mode 100644 drivers/staging/cptm1217/clearpad_tm1217.c create mode 100644 drivers/staging/cptm1217/cp_tm1217.h diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index 5eafdf435550..2c478c476edd 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -175,5 +175,7 @@ source "drivers/staging/intel_sst/Kconfig" source "drivers/staging/speakup/Kconfig" +source "drivers/staging/cptm1217/Kconfig" + endif # !STAGING_EXCLUDE_BUILD endif # STAGING diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index a97a955c094b..74d0b4cc7a0a 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -68,3 +68,4 @@ obj-$(CONFIG_BCM_WIMAX) += bcm/ obj-$(CONFIG_FT1000) += ft1000/ obj-$(CONFIG_SND_INTEL_SST) += intel_sst/ obj-$(CONFIG_SPEAKUP) += speakup/ +obj-$(CONFIG_TOUCHSCREEN_CLEARPAD_TM1217) += cptm1217/ diff --git a/drivers/staging/cptm1217/Kconfig b/drivers/staging/cptm1217/Kconfig new file mode 100644 index 000000000000..f90545d78f93 --- /dev/null +++ b/drivers/staging/cptm1217/Kconfig @@ -0,0 +1,11 @@ +config TOUCHSCREEN_CLEARPAD_TM1217 + tristate "Synaptics Clearpad TM1217" + depends on I2C + depends on GPIOLIB + help + Say Y here if you have a Synaptics Clearpad TM1217 Controller + + If unsure, say N. + + To compile this driver as a module, choose M here: the + module will be called clearpad_tm1217. diff --git a/drivers/staging/cptm1217/Makefile b/drivers/staging/cptm1217/Makefile new file mode 100644 index 000000000000..8961fafa80e7 --- /dev/null +++ b/drivers/staging/cptm1217/Makefile @@ -0,0 +1,2 @@ +obj-$(CONFIG_TOUCHSCREEN_CLEARPAD_TM1217) += clearpad_tm1217.o + diff --git a/drivers/staging/cptm1217/TODO b/drivers/staging/cptm1217/TODO new file mode 100644 index 000000000000..303922465e4d --- /dev/null +++ b/drivers/staging/cptm1217/TODO @@ -0,0 +1,5 @@ +- Wait for the official upstream general clearpad drivers as promised over + the past few months +- Merge any device support needed from this driver into it +- Delete this driver + diff --git a/drivers/staging/cptm1217/clearpad_tm1217.c b/drivers/staging/cptm1217/clearpad_tm1217.c new file mode 100644 index 000000000000..269503f9516f --- /dev/null +++ b/drivers/staging/cptm1217/clearpad_tm1217.c @@ -0,0 +1,675 @@ +/* + * clearpad_tm1217.c - Touch Screen driver for Synaptics Clearpad + * TM1217 controller + * + * Copyright (C) 2008 Intel Corp + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * 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; version 2 of the License. + * + * 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. + * + * You should have received a copy of the GNU General Public License along + * with this program; ifnot, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + * + * Questions/Comments/Bug fixes to Ramesh Agarwal (ramesh.agarwal@intel.com) + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "cp_tm1217.h" + +#define CPTM1217_DEVICE_NAME "cptm1217" +#define CPTM1217_DRIVER_NAME CPTM1217_DEVICE_NAME + +#define MAX_TOUCH_SUPPORTED 2 +#define TOUCH_SUPPORTED 1 +#define SAMPLING_FREQ 80 /* Frequency in HZ */ +#define DELAY_BTWIN_SAMPLE (1000 / SAMPLING_FREQ) +#define WAIT_FOR_RESPONSE 5 /* 5msec just works */ +#define MAX_RETRIES 5 /* As above */ +#define INCREMENTAL_DELAY 5 /* As above */ + +/* Regster Definitions */ +#define TMA1217_DEV_STATUS 0x13 /* Device Status */ +#define TMA1217_INT_STATUS 0x14 /* Interrupt Status */ + +/* Controller can detect upto 2 possible finger touches. + * Each finger touch provides 12 bit X Y co-ordinates, the values are split + * across 2 registers, and an 8 bit Z value */ +#define TMA1217_FINGER_STATE 0x18 /* Finger State */ +#define TMA1217_FINGER1_X_HIGHER8 0x19 /* Higher 8 bit of X coordinate */ +#define TMA1217_FINGER1_Y_HIGHER8 0x1A /* Higher 8 bit of Y coordinate */ +#define TMA1217_FINGER1_XY_LOWER4 0x1B /* Lower 4 bits of X and Y */ +#define TMA1217_FINGER1_Z_VALUE 0x1D /* 8 bit Z value for finger 1 */ +#define TMA1217_FINGER2_X_HIGHER8 0x1E /* Higher 8 bit of X coordinate */ +#define TMA1217_FINGER2_Y_HIGHER8 0x1F /* Higher 8 bit of Y coordinate */ +#define TMA1217_FINGER2_XY_LOWER4 0x20 /* Lower 4 bits of X and Y */ +#define TMA1217_FINGER2_Z_VALUE 0x22 /* 8 bit Z value for finger 2 */ +#define TMA1217_DEVICE_CTRL 0x23 /* Device Control */ +#define TMA1217_INTERRUPT_ENABLE 0x24 /* Interrupt Enable */ +#define TMA1217_REPORT_MODE 0x2B /* Reporting Mode */ +#define TMA1217_MAX_X_LOWER8 0x31 /* Bit 0-7 for Max X */ +#define TMA1217_MAX_X_HIGHER4 0x32 /* Bit 8-11 for Max X */ +#define TMA1217_MAX_Y_LOWER8 0x33 /* Bit 0-7 for Max Y */ +#define TMA1217_MAX_Y_HIGHER4 0x34 /* Bit 8-11 for Max Y */ +#define TMA1217_DEVICE_CMD_RESET 0x67 /* Device CMD reg for reset */ +#define TMA1217_DEVICE_CMD_REZERO 0x69 /* Device CMD reg for rezero */ + +#define TMA1217_MANUFACTURER_ID 0x73 /* Manufacturer Id */ +#define TMA1217_PRODUCT_FAMILY 0x75 /* Product Family */ +#define TMA1217_FIRMWARE_REVISION 0x76 /* Firmware Revision */ +#define TMA1217_SERIAL_NO_HIGH 0x7C /* Bit 8-15 of device serial no. */ +#define TMA1217_SERIAL_NO_LOW 0x7D /* Bit 0-7 of device serial no. */ +#define TMA1217_PRODUCT_ID_START 0x7E /* Start address for 10 byte ID */ +#define TMA1217_DEVICE_CAPABILITY 0x8B /* Reporting capability */ + + +/* + * The touch position structure. + */ +struct touch_state { + int x; + int y; + bool button; +}; + +/* Device Specific info given by the controller */ +struct cp_dev_info { + u16 maxX; + u16 maxY; +}; + +/* Vendor related info given by the controller */ +struct cp_vendor_info { + u8 vendor_id; + u8 product_family; + u8 firmware_rev; + u16 serial_no; +}; + +/* + * Private structure to store the device details + */ +struct cp_tm1217_device { + struct i2c_client *client; + struct device *dev; + struct cp_vendor_info vinfo; + struct cp_dev_info dinfo; + struct input_dev_info { + char phys[32]; + char name[128]; + struct input_dev *input; + struct touch_state touch; + } cp_input_info[MAX_TOUCH_SUPPORTED]; + + int thread_running; + struct mutex thread_mutex; + + int gpio; +}; + + +/* The following functions are used to read/write registers on the device + * as per the RMI prorocol. Technically, a page select should be written + * before doing read/write but since the register offsets are below 0xFF + * we can use the default value of page which is 0x00 + */ +static int cp_tm1217_read(struct cp_tm1217_device *ts, + u8 *req, int size) +{ + int i, retval; + + /* Send the address */ + retval = i2c_master_send(ts->client, &req[0], 1); + if (retval != 1) { + dev_err(ts->dev, "cp_tm1217: I2C send failed\n"); + return retval; + } + msleep(WAIT_FOR_RESPONSE); + for (i = 0; i < MAX_RETRIES; i++) { + retval = i2c_master_recv(ts->client, &req[1], size); + if (retval == size) { + break; + } else { + msleep(INCREMENTAL_DELAY); + dev_dbg(ts->dev, "cp_tm1217: Retry count is %d\n", i); + } + } + if (retval != size) + dev_err(ts->dev, "cp_tm1217: Read from device failed\n"); + + return retval; +} + +static int cp_tm1217_write(struct cp_tm1217_device *ts, + u8 *req, int size) +{ + int retval; + + /* Send the address and the data to be written */ + retval = i2c_master_send(ts->client, &req[0], size + 1); + if (retval != size + 1) { + dev_err(ts->dev, "cp_tm1217: I2C write failed: %d\n", retval); + return retval; + } + /* Wait for the write to complete. TBD why this is required */ + msleep(WAIT_FOR_RESPONSE); + + return size; +} + +static int cp_tm1217_mask_interrupt(struct cp_tm1217_device *ts) +{ + u8 req[2]; + int retval; + + req[0] = TMA1217_INTERRUPT_ENABLE; + req[1] = 0x0; + retval = cp_tm1217_write(ts, req, 1); + if (retval != 1) + return -EIO; + + return 0; +} + +static int cp_tm1217_unmask_interrupt(struct cp_tm1217_device *ts) +{ + u8 req[2]; + int retval; + + req[0] = TMA1217_INTERRUPT_ENABLE; + req[1] = 0xa; + retval = cp_tm1217_write(ts, req, 1); + if (retval != 1) + return -EIO; + + return 0; +} + +static void process_touch(struct cp_tm1217_device *ts, int index) +{ + int retval; + struct input_dev_info *input_info = + (struct input_dev_info *)&ts->cp_input_info[index]; + u8 xy_data[6]; + + if (index == 0) + xy_data[0] = TMA1217_FINGER1_X_HIGHER8; + else + xy_data[0] = TMA1217_FINGER2_X_HIGHER8; + + retval = cp_tm1217_read(ts, xy_data, 5); + if (retval < 5) { + dev_err(ts->dev, "cp_tm1217: XY read from device failed\n"); + return; + } + + /* Note: Currently not using the Z values but may be requried in + the future. */ + input_info->touch.x = (xy_data[1] << 4) + | (xy_data[3] & 0x0F); + input_info->touch.y = (xy_data[2] << 4) + | ((xy_data[3] & 0xF0) >> 4); + input_report_abs(input_info->input, ABS_X, input_info->touch.x); + input_report_abs(input_info->input, ABS_Y, input_info->touch.y); + input_sync(input_info->input); +} + +static void cp_tm1217_get_data(struct cp_tm1217_device *ts) +{ + u8 req[2]; + int retval, i, finger_touched = 0; + + do { + req[0] = TMA1217_FINGER_STATE; + retval = cp_tm1217_read(ts, req, 1); + if (retval != 1) { + dev_err(ts->dev, + "cp_tm1217: Read from device failed\n"); + continue; + } + finger_touched = 0; + /* Start sampling until the pressure is below + threshold */ + for (i = 0; i < TOUCH_SUPPORTED; i++) { + if (req[1] & 0x3) { + finger_touched++; + if (ts->cp_input_info[i].touch.button == 0) { + /* send the button touch event */ + input_report_key( + ts->cp_input_info[i].input, + BTN_TOUCH, 1); + ts->cp_input_info[i].touch.button = 1; + } + process_touch(ts, i); + } else { + if (ts->cp_input_info[i].touch.button == 1) { + /* send the button release event */ + input_report_key( + ts->cp_input_info[i].input, + BTN_TOUCH, 0); + input_sync(ts->cp_input_info[i].input); + ts->cp_input_info[i].touch.button = 0; + } + } + req[1] = req[1] >> 2; + } + msleep(DELAY_BTWIN_SAMPLE); + } while (finger_touched > 0); +} + +static irqreturn_t cp_tm1217_sample_thread(int irq, void *handle) +{ + struct cp_tm1217_device *ts = (struct cp_tm1217_device *) handle; + u8 req[2]; + int retval; + + /* Chedk if another thread is already running */ + mutex_lock(&ts->thread_mutex); + if (ts->thread_running == 1) { + mutex_unlock(&ts->thread_mutex); + return IRQ_HANDLED; + } else { + ts->thread_running = 1; + mutex_unlock(&ts->thread_mutex); + } + + /* Mask the interrupts */ + retval = cp_tm1217_mask_interrupt(ts); + + /* Read the Interrupt Status register to find the cause of the + Interrupt */ + req[0] = TMA1217_INT_STATUS; + retval = cp_tm1217_read(ts, req, 1); + if (retval != 1) + goto exit_thread; + + if (!(req[1] & 0x8)) + goto exit_thread; + + cp_tm1217_get_data(ts); + +exit_thread: + /* Unmask the interrupts before going to sleep */ + retval = cp_tm1217_unmask_interrupt(ts); + + mutex_lock(&ts->thread_mutex); + ts->thread_running = 0; + mutex_unlock(&ts->thread_mutex); + + return IRQ_HANDLED; +} + +static int cp_tm1217_init_data(struct cp_tm1217_device *ts) +{ + int retval; + u8 req[2]; + + /* Read the vendor id/ fw revision etc. Ignoring return check as this + is non critical info */ + req[0] = TMA1217_MANUFACTURER_ID; + retval = cp_tm1217_read(ts, req, 1); + ts->vinfo.vendor_id = req[1]; + + req[0] = TMA1217_PRODUCT_FAMILY; + retval = cp_tm1217_read(ts, req, 1); + ts->vinfo.product_family = req[1]; + + req[0] = TMA1217_FIRMWARE_REVISION; + retval = cp_tm1217_read(ts, req, 1); + ts->vinfo.firmware_rev = req[1]; + + req[0] = TMA1217_SERIAL_NO_HIGH; + retval = cp_tm1217_read(ts, req, 1); + ts->vinfo.serial_no = (req[1] << 8); + + req[0] = TMA1217_SERIAL_NO_LOW; + retval = cp_tm1217_read(ts, req, 1); + ts->vinfo.serial_no = ts->vinfo.serial_no | req[1]; + + req[0] = TMA1217_MAX_X_HIGHER4; + retval = cp_tm1217_read(ts, req, 1); + ts->dinfo.maxX = (req[1] & 0xF) << 8; + + req[0] = TMA1217_MAX_X_LOWER8; + retval = cp_tm1217_read(ts, req, 1); + ts->dinfo.maxX = ts->dinfo.maxX | req[1]; + + req[0] = TMA1217_MAX_Y_HIGHER4; + retval = cp_tm1217_read(ts, req, 1); + ts->dinfo.maxY = (req[1] & 0xF) << 8; + + req[0] = TMA1217_MAX_Y_LOWER8; + retval = cp_tm1217_read(ts, req, 1); + ts->dinfo.maxY = ts->dinfo.maxY | req[1]; + + return 0; + +} + +/* + * Set up a GPIO for use as the interrupt. We can't simply do this at + * boot time because the GPIO drivers themselves may not be around at + * boot/firmware set up time to do the work. Instead defer it to driver + * detection. + */ + +static int cp_tm1217_setup_gpio_irq(struct cp_tm1217_device *ts) +{ + int retval; + + /* Hook up the irq handler */ + retval = gpio_request(ts->gpio, "cp_tm1217_touch"); + if (retval < 0) { + dev_err(ts->dev, "cp_tm1217: GPIO request failed error %d\n", + retval); + return retval; + } + + retval = gpio_direction_input(ts->gpio); + if (retval < 0) { + dev_err(ts->dev, + "cp_tm1217: GPIO direction configuration failed, error %d\n", + retval); + gpio_free(ts->gpio); + return retval; + } + + retval = gpio_to_irq(ts->gpio); + if (retval < 0) { + dev_err(ts->dev, "cp_tm1217: GPIO to IRQ failedi," + " error %d\n", retval); + gpio_free(ts->gpio); + } + dev_dbg(ts->dev, + "cp_tm1217: Got IRQ number is %d for GPIO %d\n", + retval, ts->gpio); + return retval; +} + +static int cp_tm1217_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct cp_tm1217_device *ts; + struct input_dev *input_dev; + struct input_dev_info *input_info; + struct cp_tm1217_platform_data *pdata; + u8 req[2]; + int i, retval; + + /* No pdata is fine - we then use "normal" IRQ mode */ + + pdata = client->dev.platform_data; + + ts = kzalloc(sizeof(struct cp_tm1217_device), GFP_KERNEL); + if (!ts) { + dev_err(&client->dev, + "cp_tm1217: Private Device Struct alloc failed\n"); + return -ENOMEM; + } + + ts->client = client; + ts->dev = &client->dev; + i2c_set_clientdata(client, ts); + + ts->thread_running = 0; + mutex_init(&ts->thread_mutex); + + /* Reset the Controller */ + req[0] = TMA1217_DEVICE_CMD_RESET; + req[1] = 0x1; + retval = cp_tm1217_write(ts, req, 1); + if (retval != 1) { + dev_err(ts->dev, "cp_tm1217: Controller reset failed\n"); + kfree(ts); + return -EIO; + } + + /* Clear up the interrupt status from reset. */ + req[0] = TMA1217_INT_STATUS; + retval = cp_tm1217_read(ts, req, 1); + + /* Mask all the interrupts */ + retval = cp_tm1217_mask_interrupt(ts); + + /* Read the controller information */ + cp_tm1217_init_data(ts); + + /* The following code will register multiple event devices when + multi-pointer is enabled, the code has not been tested + with MPX */ + for (i = 0; i < TOUCH_SUPPORTED; i++) { + input_dev = input_allocate_device(); + if (input_dev == NULL) { + kfree(ts); + dev_err(ts->dev, + "cp_tm1217:Input Device Struct alloc failed\n"); + return -ENOMEM; + } + input_info = &ts->cp_input_info[i]; + snprintf(input_info->name, sizeof(input_info->name), + "cp_tm1217_touchscreen_%d", i); + input_dev->name = input_info->name; + snprintf(input_info->phys, sizeof(input_info->phys), + "%s/input%d", dev_name(&client->dev), i); + + input_dev->phys = input_info->phys; + input_dev->id.bustype = BUS_I2C; + + input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); + input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); + + input_set_abs_params(input_dev, ABS_X, 0, ts->dinfo.maxX, 0, 0); + input_set_abs_params(input_dev, ABS_Y, 0, ts->dinfo.maxY, 0, 0); + + retval = input_register_device(input_dev); + if (retval) { + dev_err(ts->dev, + "Input dev registration failed for %s\n", + input_dev->name); + goto fail; + } + input_info->input = input_dev; + } + + /* Setup the reporting mode to send an interrupt only when + finger arrives or departs. */ + req[0] = TMA1217_REPORT_MODE; + req[1] = 0x02; + retval = cp_tm1217_write(ts, req, 1); + + /* Setup the device to no sleep mode for now and make it configured */ + req[0] = TMA1217_DEVICE_CTRL; + req[1] = 0x84; + retval = cp_tm1217_write(ts, req, 1); + + /* Check for the status of the device */ + req[0] = TMA1217_DEV_STATUS; + retval = cp_tm1217_read(ts, req, 1); + if (req[1] != 0) { + dev_err(ts->dev, + "cp_tm1217: Device Status 0x%x != 0: config failed\n", + req[1]); + + retval = -EIO; + goto fail; + } + + if (pdata && pdata->gpio) { + ts->gpio = pdata->gpio; + retval = cp_tm1217_setup_gpio_irq(ts); + } else + retval = client->irq; + + if (retval < 0) { + dev_err(ts->dev, "cp_tm1217: GPIO request failed error %d\n", + retval); + goto fail; + } + + client->irq = retval; + + + retval = request_threaded_irq(client->irq, + NULL, cp_tm1217_sample_thread, + IRQF_TRIGGER_FALLING, "cp_tm1217_touch", ts); + if (retval < 0) { + dev_err(ts->dev, "cp_tm1217: Request IRQ error %d\n", retval); + goto fail_gpio; + } + + /* Unmask the interrupts */ + retval = cp_tm1217_unmask_interrupt(ts); + if (retval == 0) + return 0; + + free_irq(client->irq, ts); +fail_gpio: + if (ts->gpio) + gpio_free(ts->gpio); +fail: + /* Clean up before returning failure */ + for (i = 0; i < TOUCH_SUPPORTED; i++) { + if (ts->cp_input_info[i].input) { + input_unregister_device(ts->cp_input_info[i].input); + input_free_device(ts->cp_input_info[i].input); + } + } + kfree(ts); + return retval; + +} + +/* + * cp_tm1217 suspend + * + */ +static int cp_tm1217_suspend(struct i2c_client *client, pm_message_t mesg) +{ + struct cp_tm1217_device *ts = i2c_get_clientdata(client); + u8 req[2]; + int retval; + + /* Put the controller to sleep */ + req[0] = TMA1217_DEVICE_CTRL; + retval = cp_tm1217_read(ts, req, 1); + req[1] = (req[1] & 0xF8) | 0x1; + retval = cp_tm1217_write(ts, req, 1); + + if (device_may_wakeup(&client->dev)) + enable_irq_wake(client->irq); + + return 0; +} + +/* + * cp_tm1217_resume + * + */ +static int cp_tm1217_resume(struct i2c_client *client) +{ + struct cp_tm1217_device *ts = i2c_get_clientdata(client); + u8 req[2]; + int retval; + + /* Take the controller out of sleep */ + req[0] = TMA1217_DEVICE_CTRL; + retval = cp_tm1217_read(ts, req, 1); + req[1] = (req[1] & 0xF8) | 0x4; + retval = cp_tm1217_write(ts, req, 1); + + /* Restore the register settings sinc the power to the + could have been cut off */ + + /* Setup the reporting mode to send an interrupt only when + finger arrives or departs. */ + req[0] = TMA1217_REPORT_MODE; + req[1] = 0x02; + retval = cp_tm1217_write(ts, req, 1); + + /* Setup the device to no sleep mode for now and make it configured */ + req[0] = TMA1217_DEVICE_CTRL; + req[1] = 0x84; + retval = cp_tm1217_write(ts, req, 1); + + /* Setup the interrupt mask */ + retval = cp_tm1217_unmask_interrupt(ts); + + if (device_may_wakeup(&client->dev)) + disable_irq_wake(client->irq); + + return 0; +} + +/* + * cp_tm1217_remove + * + */ +static int cp_tm1217_remove(struct i2c_client *client) +{ + struct cp_tm1217_device *ts = i2c_get_clientdata(client); + int i; + + free_irq(client->irq, ts); + if (ts->gpio) + gpio_free(ts->gpio); + for (i = 0; i < TOUCH_SUPPORTED; i++) + input_unregister_device(ts->cp_input_info[i].input); + kfree(ts); + return 0; +} + +static struct i2c_device_id cp_tm1217_idtable[] = { + { CPTM1217_DEVICE_NAME, 0 }, + { } +}; + +MODULE_DEVICE_TABLE(i2c, cp_tm1217_idtable); + +static struct i2c_driver cp_tm1217_driver = { + .driver = { + .owner = THIS_MODULE, + .name = CPTM1217_DRIVER_NAME, + }, + .id_table = cp_tm1217_idtable, + .probe = cp_tm1217_probe, + .remove = cp_tm1217_remove, + .suspend = cp_tm1217_suspend, + .resume = cp_tm1217_resume, +}; + +static int __init clearpad_tm1217_init(void) +{ + return i2c_add_driver(&cp_tm1217_driver); +} + +static void __exit clearpad_tm1217_exit(void) +{ + i2c_del_driver(&cp_tm1217_driver); +} + +module_init(clearpad_tm1217_init); +module_exit(clearpad_tm1217_exit); + +MODULE_AUTHOR("Ramesh Agarwal "); +MODULE_DESCRIPTION("Synaptics TM1217 TouchScreen Driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/staging/cptm1217/cp_tm1217.h b/drivers/staging/cptm1217/cp_tm1217.h new file mode 100644 index 000000000000..a0ce31db53f8 --- /dev/null +++ b/drivers/staging/cptm1217/cp_tm1217.h @@ -0,0 +1,9 @@ +#ifndef __LINUX_I2C_CP_TM1217_H +#define __LINUX_I2C_CP_TM1217_H + +struct cp_tm1217_platform_data +{ + int gpio; /* If not set uses the IRQ resource 0 */ +}; + +#endif -- cgit v1.2.3 From eba499d3e376983f4d521bac05bf7e9a634ace2f Mon Sep 17 00:00:00 2001 From: Naveen Kumar Gaddipati Date: Tue, 2 Nov 2010 17:38:45 +0530 Subject: Staging: add Synaptics RMI4 touchpad driver support Added the Synaptics RMI4 touchpad driver support. Acked-by: Linus Walleij Signed-off-by: Naveen Kumar Gaddipati Cc: Dmitry Torokhov Cc: Alan Cox Cc: Christopher Heiny Signed-off-by: Greg Kroah-Hartman --- drivers/staging/Kconfig | 2 + drivers/staging/Makefile | 1 + drivers/staging/ste_rmi4/Kconfig | 9 + drivers/staging/ste_rmi4/Makefile | 4 + drivers/staging/ste_rmi4/TODO | 7 + drivers/staging/ste_rmi4/synaptics_i2c_rmi4.c | 1179 +++++++++++++++++++++++++ drivers/staging/ste_rmi4/synaptics_i2c_rmi4.h | 50 ++ 7 files changed, 1252 insertions(+) create mode 100644 drivers/staging/ste_rmi4/Kconfig create mode 100644 drivers/staging/ste_rmi4/Makefile create mode 100644 drivers/staging/ste_rmi4/TODO create mode 100644 drivers/staging/ste_rmi4/synaptics_i2c_rmi4.c create mode 100644 drivers/staging/ste_rmi4/synaptics_i2c_rmi4.h diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index 2c478c476edd..49aee27b296d 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -177,5 +177,7 @@ source "drivers/staging/speakup/Kconfig" source "drivers/staging/cptm1217/Kconfig" +source "drivers/staging/ste_rmi4/Kconfig" + endif # !STAGING_EXCLUDE_BUILD endif # STAGING diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index 74d0b4cc7a0a..20c5641b6cd7 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -69,3 +69,4 @@ obj-$(CONFIG_FT1000) += ft1000/ obj-$(CONFIG_SND_INTEL_SST) += intel_sst/ obj-$(CONFIG_SPEAKUP) += speakup/ obj-$(CONFIG_TOUCHSCREEN_CLEARPAD_TM1217) += cptm1217/ +obj-$(CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4) += ste_rmi4/ diff --git a/drivers/staging/ste_rmi4/Kconfig b/drivers/staging/ste_rmi4/Kconfig new file mode 100644 index 000000000000..95fd5a915f0a --- /dev/null +++ b/drivers/staging/ste_rmi4/Kconfig @@ -0,0 +1,9 @@ +config TOUCHSCREEN_SYNAPTICS_I2C_RMI4 + tristate "Synaptics i2c rmi4 touchscreen" + depends on I2C + help + Say Y here if you have a Synaptics RMI4 and + want to enable support for the built-in touchscreen. + + To compile this driver as a module, choose M here: the + module will be called synaptics_rmi4_ts. diff --git a/drivers/staging/ste_rmi4/Makefile b/drivers/staging/ste_rmi4/Makefile new file mode 100644 index 000000000000..6cce2ed187ef --- /dev/null +++ b/drivers/staging/ste_rmi4/Makefile @@ -0,0 +1,4 @@ +# +# Makefile for the RMI4 touchscreen driver. +# +obj-$(CONFIG_TOUCHSCREEN_SYNAPTICS_I2C_RMI4) += synaptics_i2c_rmi4.o diff --git a/drivers/staging/ste_rmi4/TODO b/drivers/staging/ste_rmi4/TODO new file mode 100644 index 000000000000..9be2437da85f --- /dev/null +++ b/drivers/staging/ste_rmi4/TODO @@ -0,0 +1,7 @@ +TODO +---- + +Wait for the official upstream synaptics rmi4 clearpad drivers as promised over the past few months +Merge any device support needed from this driver into it +Delete this driver + diff --git a/drivers/staging/ste_rmi4/synaptics_i2c_rmi4.c b/drivers/staging/ste_rmi4/synaptics_i2c_rmi4.c new file mode 100644 index 000000000000..e8f047e86a32 --- /dev/null +++ b/drivers/staging/ste_rmi4/synaptics_i2c_rmi4.c @@ -0,0 +1,1179 @@ +/** + * + * Synaptics Register Mapped Interface (RMI4) I2C Physical Layer Driver. + * Copyright (c) 2007-2010, Synaptics Incorporated + * + * Author: Js HA for ST-Ericsson + * Author: Naveen Kumar G for ST-Ericsson + * Copyright 2010 (c) ST-Ericsson AB + */ +/* + * This file is licensed under the GPL2 license. + * + *############################################################################# + * GPL + * + * 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. + * + *############################################################################# + */ + +#include +#include +#include +#include +#include +#include "synaptics_i2c_rmi4.h" + +/* TODO: for multiple device support will need a per-device mutex */ +#define DRIVER_NAME "synaptics_rmi4_i2c" + +#define MAX_ERROR_REPORT 6 +#define MAX_TOUCH_MAJOR 15 +#define MAX_RETRY_COUNT 5 +#define STD_QUERY_LEN 21 +#define PAGE_LEN 2 +#define DATA_BUF_LEN 32 +#define BUF_LEN 37 +#define QUERY_LEN 9 +#define DATA_LEN 12 +#define HAS_TAP 0x01 +#define HAS_PALMDETECT 0x01 +#define HAS_ROTATE 0x02 +#define HAS_TAPANDHOLD 0x02 +#define HAS_DOUBLETAP 0x04 +#define HAS_EARLYTAP 0x08 +#define HAS_RELEASE 0x08 +#define HAS_FLICK 0x10 +#define HAS_PRESS 0x20 +#define HAS_PINCH 0x40 + +#define MASK_16BIT 0xFFFF +#define MASK_8BIT 0xFF +#define MASK_7BIT 0x7F +#define MASK_5BIT 0x1F +#define MASK_4BIT 0x0F +#define MASK_3BIT 0x07 +#define MASK_2BIT 0x03 +#define TOUCHPAD_CTRL_INTR 0x8 +#define PDT_START_SCAN_LOCATION (0x00E9) +#define PDT_END_SCAN_LOCATION (0x000A) +#define PDT_ENTRY_SIZE (0x0006) +#define RMI4_NUMBER_OF_MAX_FINGERS (8) +#define SYNAPTICS_RMI4_TOUCHPAD_FUNC_NUM (0x11) +#define SYNAPTICS_RMI4_DEVICE_CONTROL_FUNC_NUM (0x01) + +/** + * struct synaptics_rmi4_fn_desc - contains the funtion descriptor information + * @query_base_addr: base address for query + * @cmd_base_addr: base address for command + * @ctrl_base_addr: base address for control + * @data_base_addr: base address for data + * @intr_src_count: count for the interrupt source + * @fn_number: function number + * + * This structure is used to gives the function descriptor information + * of the particular functionality. + */ +struct synaptics_rmi4_fn_desc { + unsigned char query_base_addr; + unsigned char cmd_base_addr; + unsigned char ctrl_base_addr; + unsigned char data_base_addr; + unsigned char intr_src_count; + unsigned char fn_number; +}; + +/** + * struct synaptics_rmi4_fn - contains the funtion information + * @fn_number: function number + * @num_of_data_sources: number of data sources + * @num_of_data_points: number of fingers touched + * @size_of_data_register_block: data register block size + * @index_to_intr_reg: index for interrupt register + * @intr_mask: interrupt mask value + * @fn_desc: variable for function descriptor structure + * @link: linked list for function descriptors + * + * This structure gives information about the number of data sources and + * the number of data registers associated with the function. + */ +struct synaptics_rmi4_fn { + unsigned char fn_number; + unsigned char num_of_data_sources; + unsigned char num_of_data_points; + unsigned char size_of_data_register_block; + unsigned char index_to_intr_reg; + unsigned char intr_mask; + struct synaptics_rmi4_fn_desc fn_desc; + struct list_head link; +}; + +/** + * struct synaptics_rmi4_device_info - contains the rmi4 device information + * @version_major: protocol major version number + * @version_minor: protocol minor version number + * @manufacturer_id: manufacturer identification byte + * @product_props: product properties information + * @product_info: product info array + * @date_code: device manufacture date + * @tester_id: tester id array + * @serial_number: serial number for that device + * @product_id_string: product id for the device + * @support_fn_list: linked list for device information + * + * This structure gives information about the number of data sources and + * the number of data registers associated with the function. + */ +struct synaptics_rmi4_device_info { + unsigned int version_major; + unsigned int version_minor; + unsigned char manufacturer_id; + unsigned char product_props; + unsigned char product_info[2]; + unsigned char date_code[3]; + unsigned short tester_id; + unsigned short serial_number; + unsigned char product_id_string[11]; + struct list_head support_fn_list; +}; + +/** + * struct synaptics_rmi4_data - contains the rmi4 device data + * @rmi4_mod_info: structure variable for rmi4 device info + * @input_dev: pointer for input device + * @i2c_client: pointer for i2c client + * @board: constant pointer for touch platform data + * @fn_list_mutex: mutex for funtion list + * @rmi4_page_mutex: mutex for rmi4 page + * @current_page: variable for integer + * @number_of_interrupt_register: interrupt registers count + * @fn01_ctrl_base_addr: control base address for fn01 + * @fn01_query_base_addr: query base address for fn01 + * @fn01_data_base_addr: data base address for fn01 + * @sensor_max_x: sensor maximum x value + * @sensor_max_y: sensor maximum y value + * @regulator: pointer to the regulator structure + * @wait: wait queue structure variable + * @touch_stopped: flag to stop the thread function + * + * This structure gives the device data information. + */ +struct synaptics_rmi4_data { + struct synaptics_rmi4_device_info rmi4_mod_info; + struct input_dev *input_dev; + struct i2c_client *i2c_client; + const struct synaptics_rmi4_platform_data *board; + struct mutex fn_list_mutex; + struct mutex rmi4_page_mutex; + int current_page; + unsigned int number_of_interrupt_register; + unsigned short fn01_ctrl_base_addr; + unsigned short fn01_query_base_addr; + unsigned short fn01_data_base_addr; + int sensor_max_x; + int sensor_max_y; + struct regulator *regulator; + wait_queue_head_t wait; + bool touch_stopped; +}; + +/** + * synaptics_rmi4_set_page() - sets the page + * @pdata: pointer to synaptics_rmi4_data structure + * @address: set the address of the page + * + * This function is used to set the page and returns integer. + */ +static int synaptics_rmi4_set_page(struct synaptics_rmi4_data *pdata, + unsigned int address) +{ + unsigned char txbuf[PAGE_LEN]; + int retval; + unsigned int page; + struct i2c_client *i2c = pdata->i2c_client; + + page = ((address >> 8) & MASK_8BIT); + if (page != pdata->current_page) { + txbuf[0] = MASK_8BIT; + txbuf[1] = page; + retval = i2c_master_send(i2c, txbuf, PAGE_LEN); + if (retval != PAGE_LEN) + dev_err(&i2c->dev, "%s:failed:%d\n", __func__, retval); + else + pdata->current_page = page; + } else + retval = PAGE_LEN; + return retval; +} +/** + * synaptics_rmi4_i2c_block_read() - read the block of data + * @pdata: pointer to synaptics_rmi4_data structure + * @address: read the block of data from this offset + * @valp: pointer to a buffer containing the data to be read + * @size: number of bytes to read + * + * This function is to read the block of data and returns integer. + */ +static int synaptics_rmi4_i2c_block_read(struct synaptics_rmi4_data *pdata, + unsigned short address, + unsigned char *valp, int size) +{ + int retval = 0; + int retry_count = 0; + int index; + struct i2c_client *i2c = pdata->i2c_client; + + mutex_lock(&(pdata->rmi4_page_mutex)); + retval = synaptics_rmi4_set_page(pdata, address); + if (retval != PAGE_LEN) + goto exit; + index = address & MASK_8BIT; +retry: + retval = i2c_smbus_read_i2c_block_data(i2c, index, size, valp); + if (retval != size) { + if (++retry_count == MAX_RETRY_COUNT) + dev_err(&i2c->dev, + "%s:address 0x%04x size %d failed:%d\n", + __func__, address, size, retval); + else { + synaptics_rmi4_set_page(pdata, address); + goto retry; + } + } +exit: + mutex_unlock(&(pdata->rmi4_page_mutex)); + return retval; +} + +/** + * synaptics_rmi4_i2c_byte_write() - write the single byte data + * @pdata: pointer to synaptics_rmi4_data structure + * @address: write the block of data from this offset + * @data: data to be write + * + * This function is to write the single byte data and returns integer. + */ +static int synaptics_rmi4_i2c_byte_write(struct synaptics_rmi4_data *pdata, + unsigned short address, + unsigned char data) +{ + unsigned char txbuf[2]; + int retval = 0; + struct i2c_client *i2c = pdata->i2c_client; + + /* Can't have anyone else changing the page behind our backs */ + mutex_lock(&(pdata->rmi4_page_mutex)); + + retval = synaptics_rmi4_set_page(pdata, address); + if (retval != PAGE_LEN) + goto exit; + txbuf[0] = address & MASK_8BIT; + txbuf[1] = data; + retval = i2c_master_send(pdata->i2c_client, txbuf, 2); + /* Add in retry on writes only in certian error return values */ + if (retval != 2) { + dev_err(&i2c->dev, "%s:failed:%d\n", __func__, retval); + retval = -EIO; + } else + retval = 1; +exit: + mutex_unlock(&(pdata->rmi4_page_mutex)); + return retval; +} + +/** + * synpatics_rmi4_touchpad_report() - reports for the rmi4 touchpad device + * @pdata: pointer to synaptics_rmi4_data structure + * @rfi: pointer to synaptics_rmi4_fn structure + * + * This function calls to reports for the rmi4 touchpad device + */ +static int synpatics_rmi4_touchpad_report(struct synaptics_rmi4_data *pdata, + struct synaptics_rmi4_fn *rfi) +{ + /* number of touch points - fingers down in this case */ + int touch_count = 0; + int finger; + int fingers_supported; + int finger_registers; + int reg; + int finger_shift; + int finger_status; + int retval; + unsigned short data_base_addr; + unsigned short data_offset; + unsigned char data_reg_blk_size; + unsigned char values[2]; + unsigned char data[DATA_LEN]; + int x[RMI4_NUMBER_OF_MAX_FINGERS]; + int y[RMI4_NUMBER_OF_MAX_FINGERS]; + int wx[RMI4_NUMBER_OF_MAX_FINGERS]; + int wy[RMI4_NUMBER_OF_MAX_FINGERS]; + struct i2c_client *client = pdata->i2c_client; + + /* get 2D sensor finger data */ + /* + * First get the finger status field - the size of the finger status + * field is determined by the number of finger supporte - 2 bits per + * finger, so the number of registers to read is: + * registerCount = ceil(numberOfFingers/4). + * Read the required number of registers and check each 2 bit field to + * determine if a finger is down: + * 00 = finger not present, + * 01 = finger present and data accurate, + * 10 = finger present but data may not be accurate, + * 11 = reserved for product use. + */ + fingers_supported = rfi->num_of_data_points; + finger_registers = (fingers_supported + 3)/4; + data_base_addr = rfi->fn_desc.data_base_addr; + retval = synaptics_rmi4_i2c_block_read(pdata, data_base_addr, values, + finger_registers); + if (retval != finger_registers) { + dev_err(&client->dev, "%s:read status registers failed\n", + __func__); + return 0; + } + /* + * For each finger present, read the proper number of registers + * to get absolute data. + */ + data_reg_blk_size = rfi->size_of_data_register_block; + for (finger = 0; finger < fingers_supported; finger++) { + /* determine which data byte the finger status is in */ + reg = finger/4; + /* bit shift to get finger's status */ + finger_shift = (finger % 4) * 2; + finger_status = (values[reg] >> finger_shift) & 3; + /* + * if finger status indicates a finger is present then + * read the finger data and report it + */ + if (finger_status == 1 || finger_status == 2) { + /* Read the finger data */ + data_offset = data_base_addr + + ((finger * data_reg_blk_size) + + finger_registers); + retval = synaptics_rmi4_i2c_block_read(pdata, + data_offset, data, + data_reg_blk_size); + if (retval != data_reg_blk_size) { + printk(KERN_ERR "%s:read data failed\n", + __func__); + return 0; + } else { + x[touch_count] = + (data[0] << 4) | (data[2] & MASK_4BIT); + y[touch_count] = + (data[1] << 4) | + ((data[2] >> 4) & MASK_4BIT); + wy[touch_count] = + (data[3] >> 4) & MASK_4BIT; + wx[touch_count] = + (data[3] & MASK_4BIT); + + if (pdata->board->x_flip) + x[touch_count] = + pdata->sensor_max_x - + x[touch_count]; + if (pdata->board->y_flip) + y[touch_count] = + pdata->sensor_max_y - + y[touch_count]; + } + /* number of active touch points */ + touch_count++; + } + } + + /* report to input subsystem */ + if (touch_count) { + for (finger = 0; finger < touch_count; finger++) { + input_report_abs(pdata->input_dev, ABS_MT_TOUCH_MAJOR, + max(wx[finger] , wy[finger])); + input_report_abs(pdata->input_dev, ABS_MT_POSITION_X, + x[finger]); + input_report_abs(pdata->input_dev, ABS_MT_POSITION_Y, + y[finger]); + input_mt_sync(pdata->input_dev); + } + } else + input_mt_sync(pdata->input_dev); + + /* sync after groups of events */ + input_sync(pdata->input_dev); + /* return the number of touch points */ + return touch_count; +} + +/** + * synaptics_rmi4_report_device() - reports the rmi4 device + * @pdata: pointer to synaptics_rmi4_data structure + * @rfi: pointer to synaptics_rmi4_fn + * + * This function is used to call the report function of the rmi4 device. + */ +static int synaptics_rmi4_report_device(struct synaptics_rmi4_data *pdata, + struct synaptics_rmi4_fn *rfi) +{ + int touch = 0; + struct i2c_client *client = pdata->i2c_client; + static int num_error_reports; + if (rfi->fn_number != SYNAPTICS_RMI4_TOUCHPAD_FUNC_NUM) { + num_error_reports++; + if (num_error_reports < MAX_ERROR_REPORT) + dev_err(&client->dev, "%s:report not supported\n", + __func__); + } else + touch = synpatics_rmi4_touchpad_report(pdata, rfi); + return touch; +} +/** + * synaptics_rmi4_sensor_report() - reports to input subsystem + * @pdata: pointer to synaptics_rmi4_data structure + * + * This function is used to reads in all data sources and reports + * them to the input subsystem. + */ +static int synaptics_rmi4_sensor_report(struct synaptics_rmi4_data *pdata) +{ + unsigned char intr_status[4]; + /* number of touch points - fingers or buttons */ + int touch = 0; + unsigned int retval; + struct synaptics_rmi4_fn *rfi; + struct synaptics_rmi4_device_info *rmi; + struct i2c_client *client = pdata->i2c_client; + + /* + * Get the interrupt status from the function $01 + * control register+1 to find which source(s) were interrupting + * so we can read the data from the source(s) (2D sensor, buttons..) + */ + retval = synaptics_rmi4_i2c_block_read(pdata, + pdata->fn01_data_base_addr + 1, + intr_status, + pdata->number_of_interrupt_register); + if (retval != pdata->number_of_interrupt_register) { + dev_err(&client->dev, + "could not read interrupt status registers\n"); + return 0; + } + /* + * check each function that has data sources and if the interrupt for + * that triggered then call that RMI4 functions report() function to + * gather data and report it to the input subsystem + */ + rmi = &(pdata->rmi4_mod_info); + list_for_each_entry(rfi, &rmi->support_fn_list, link) { + if (rfi->num_of_data_sources) { + if (intr_status[rfi->index_to_intr_reg] & + rfi->intr_mask) + touch = synaptics_rmi4_report_device(pdata, + rfi); + } + } + /* return the number of touch points */ + return touch; +} + +/** + * synaptics_rmi4_irq() - thread function for rmi4 attention line + * @irq: irq value + * @data: void pointer + * + * This function is interrupt thread function. It just notifies the + * application layer that attention is required. + */ +static irqreturn_t synaptics_rmi4_irq(int irq, void *data) +{ + struct synaptics_rmi4_data *pdata = data; + int touch_count; + do { + touch_count = synaptics_rmi4_sensor_report(pdata); + if (touch_count) + wait_event_timeout(pdata->wait, pdata->touch_stopped, + msecs_to_jiffies(1)); + else + break; + } while (!pdata->touch_stopped); + return IRQ_HANDLED; +} + +/** + * synpatics_rmi4_touchpad_detect() - detects the rmi4 touchpad device + * @pdata: pointer to synaptics_rmi4_data structure + * @rfi: pointer to synaptics_rmi4_fn structure + * @fd: pointer to synaptics_rmi4_fn_desc structure + * @interruptcount: count the number of interrupts + * + * This function calls to detects the rmi4 touchpad device + */ +static int synpatics_rmi4_touchpad_detect(struct synaptics_rmi4_data *pdata, + struct synaptics_rmi4_fn *rfi, + struct synaptics_rmi4_fn_desc *fd, + unsigned int interruptcount) +{ + unsigned char queries[QUERY_LEN]; + unsigned short intr_offset; + unsigned char abs_data_size; + unsigned char abs_data_blk_size; + unsigned char egr_0, egr_1; + unsigned int all_data_blk_size; + int has_pinch, has_flick, has_tap; + int has_tapandhold, has_doubletap; + int has_earlytap, has_press; + int has_palmdetect, has_rotate; + int has_rel; + int i; + int retval; + struct i2c_client *client = pdata->i2c_client; + + rfi->fn_desc.query_base_addr = fd->query_base_addr; + rfi->fn_desc.data_base_addr = fd->data_base_addr; + rfi->fn_desc.intr_src_count = fd->intr_src_count; + rfi->fn_desc.fn_number = fd->fn_number; + rfi->fn_number = fd->fn_number; + rfi->num_of_data_sources = fd->intr_src_count; + rfi->fn_desc.ctrl_base_addr = fd->ctrl_base_addr; + rfi->fn_desc.cmd_base_addr = fd->cmd_base_addr; + + /* + * need to get number of fingers supported, data size, etc. + * to be used when getting data since the number of registers to + * read depends on the number of fingers supported and data size. + */ + retval = synaptics_rmi4_i2c_block_read(pdata, fd->query_base_addr, + queries, + sizeof(queries)); + if (retval != sizeof(queries)) { + dev_err(&client->dev, "%s:read function query registers\n", + __func__); + return retval; + } + /* + * 2D data sources have only 3 bits for the number of fingers + * supported - so the encoding is a bit wierd. + */ + if ((queries[1] & MASK_3BIT) <= 4) + /* add 1 since zero based */ + rfi->num_of_data_points = (queries[1] & MASK_3BIT) + 1; + else { + /* + * a value of 5 is up to 10 fingers - 6 and 7 are reserved + * (shouldn't get these i int retval;n a normal 2D source). + */ + if ((queries[1] & MASK_3BIT) == 5) + rfi->num_of_data_points = 10; + } + /* Need to get interrupt info for handling interrupts */ + rfi->index_to_intr_reg = (interruptcount + 7)/8; + if (rfi->index_to_intr_reg != 0) + rfi->index_to_intr_reg -= 1; + /* + * loop through interrupts for each source in fn $11 + * and or in a bit to the interrupt mask for each. + */ + intr_offset = interruptcount % 8; + rfi->intr_mask = 0; + for (i = intr_offset; + i < ((fd->intr_src_count & MASK_3BIT) + intr_offset); i++) + rfi->intr_mask |= 1 << i; + + /* Size of just the absolute data for one finger */ + abs_data_size = queries[5] & MASK_2BIT; + /* One each for X and Y, one for LSB for X & Y, one for W, one for Z */ + abs_data_blk_size = 3 + (2 * (abs_data_size == 0 ? 1 : 0)); + rfi->size_of_data_register_block = abs_data_blk_size; + + /* + * need to determine the size of data to read - this depends on + * conditions such as whether Relative data is reported and if Gesture + * data is reported. + */ + egr_0 = queries[7]; + egr_1 = queries[8]; + + /* + * Get info about what EGR data is supported, whether it has + * Relative data supported, etc. + */ + has_pinch = egr_0 & HAS_PINCH; + has_flick = egr_0 & HAS_FLICK; + has_tap = egr_0 & HAS_TAP; + has_earlytap = egr_0 & HAS_EARLYTAP; + has_press = egr_0 & HAS_PRESS; + has_rotate = egr_1 & HAS_ROTATE; + has_rel = queries[1] & HAS_RELEASE; + has_tapandhold = egr_0 & HAS_TAPANDHOLD; + has_doubletap = egr_0 & HAS_DOUBLETAP; + has_palmdetect = egr_1 & HAS_PALMDETECT; + + /* + * Size of all data including finger status, absolute data for each + * finger, relative data and EGR data + */ + all_data_blk_size = + /* finger status, four fingers per register */ + ((rfi->num_of_data_points + 3) / 4) + + /* absolute data, per finger times number of fingers */ + (abs_data_blk_size * rfi->num_of_data_points) + + /* + * two relative registers (if relative is being reported) + */ + 2 * has_rel + + /* + * F11_2D_data8 is only present if the egr_0 + * register is non-zero. + */ + !!(egr_0) + + /* + * F11_2D_data9 is only present if either egr_0 or + * egr_1 registers are non-zero. + */ + (egr_0 || egr_1) + + /* + * F11_2D_data10 is only present if EGR_PINCH or EGR_FLICK of + * egr_0 reports as 1. + */ + !!(has_pinch | has_flick) + + /* + * F11_2D_data11 and F11_2D_data12 are only present if + * EGR_FLICK of egr_0 reports as 1. + */ + 2 * !!(has_flick); + return retval; +} + +/** + * synpatics_rmi4_touchpad_config() - confiures the rmi4 touchpad device + * @pdata: pointer to synaptics_rmi4_data structure + * @rfi: pointer to synaptics_rmi4_fn structure + * + * This function calls to confiures the rmi4 touchpad device + */ +int synpatics_rmi4_touchpad_config(struct synaptics_rmi4_data *pdata, + struct synaptics_rmi4_fn *rfi) +{ + /* + * For the data source - print info and do any + * source specific configuration. + */ + unsigned char data[BUF_LEN]; + int retval = 0; + struct i2c_client *client = pdata->i2c_client; + + /* Get and print some info about the data source... */ + /* To Query 2D devices we need to read from the address obtained + * from the function descriptor stored in the RMI function info. + */ + retval = synaptics_rmi4_i2c_block_read(pdata, + rfi->fn_desc.query_base_addr, + data, QUERY_LEN); + if (retval != QUERY_LEN) + dev_err(&client->dev, "%s:read query registers failed\n", + __func__); + else { + retval = synaptics_rmi4_i2c_block_read(pdata, + rfi->fn_desc.ctrl_base_addr, + data, DATA_BUF_LEN); + if (retval != DATA_BUF_LEN) { + dev_err(&client->dev, + "%s:read control registers failed\n", + __func__); + return retval; + } + /* Store these for use later*/ + pdata->sensor_max_x = ((data[6] & MASK_8BIT) << 0) | + ((data[7] & MASK_4BIT) << 8); + pdata->sensor_max_y = ((data[8] & MASK_5BIT) << 0) | + ((data[9] & MASK_4BIT) << 8); + } + return retval; +} + +/** + * synaptics_rmi4_i2c_query_device() - query the rmi4 device + * @pdata: pointer to synaptics_rmi4_data structure + * + * This function is used to query the rmi4 device. + */ +static int synaptics_rmi4_i2c_query_device(struct synaptics_rmi4_data *pdata) +{ + int i; + int retval; + unsigned char std_queries[STD_QUERY_LEN]; + unsigned char intr_count = 0; + int data_sources = 0; + unsigned int ctrl_offset; + struct synaptics_rmi4_fn *rfi; + struct synaptics_rmi4_fn_desc rmi_fd; + struct synaptics_rmi4_device_info *rmi; + struct i2c_client *client = pdata->i2c_client; + + /* + * init the physical drivers RMI module + * info list of functions + */ + INIT_LIST_HEAD(&pdata->rmi4_mod_info.support_fn_list); + + /* + * Read the Page Descriptor Table to determine what functions + * are present + */ + for (i = PDT_START_SCAN_LOCATION; i > PDT_END_SCAN_LOCATION; + i -= PDT_ENTRY_SIZE) { + retval = synaptics_rmi4_i2c_block_read(pdata, i, + (unsigned char *)&rmi_fd, + sizeof(rmi_fd)); + if (retval != sizeof(rmi_fd)) { + /* failed to read next PDT entry */ + dev_err(&client->dev, "%s: read error\n", __func__); + return -EIO; + } + rfi = NULL; + if (rmi_fd.fn_number) { + switch (rmi_fd.fn_number & MASK_8BIT) { + case SYNAPTICS_RMI4_DEVICE_CONTROL_FUNC_NUM: + pdata->fn01_query_base_addr = + rmi_fd.query_base_addr; + pdata->fn01_ctrl_base_addr = + rmi_fd.ctrl_base_addr; + pdata->fn01_data_base_addr = + rmi_fd.data_base_addr; + break; + case SYNAPTICS_RMI4_TOUCHPAD_FUNC_NUM: + if (rmi_fd.intr_src_count) { + rfi = kmalloc(sizeof(*rfi), + GFP_KERNEL); + if (!rfi) { + dev_err(&client->dev, + "%s:kmalloc failed\n", + __func__); + return -ENOMEM; + } + retval = synpatics_rmi4_touchpad_detect + (pdata, rfi, + &rmi_fd, + intr_count); + if (retval < 0) + return retval; + } + break; + } + /* interrupt count for next iteration */ + intr_count += (rmi_fd.intr_src_count & MASK_3BIT); + /* + * We only want to add functions to the list + * that have data associated with them. + */ + if (rfi && rmi_fd.intr_src_count) { + /* link this function info to the RMI module */ + mutex_lock(&(pdata->fn_list_mutex)); + list_add_tail(&rfi->link, + &pdata->rmi4_mod_info.support_fn_list); + mutex_unlock(&(pdata->fn_list_mutex)); + } + } else { + /* + * A zero in the function number + * signals the end of the PDT + */ + dev_dbg(&client->dev, + "%s:end of PDT\n", __func__); + break; + } + } + /* + * calculate the interrupt register count - used in the + * ISR to read the correct number of interrupt registers + */ + pdata->number_of_interrupt_register = (intr_count + 7) / 8; + /* + * Function $01 will be used to query the product properties, + * and product ID so we had to read the PDT above first to get + * the Fn $01 query address and prior to filling in the product + * info. NOTE: Even an unflashed device will still have FN $01. + */ + + /* Load up the standard queries and get the RMI4 module info */ + retval = synaptics_rmi4_i2c_block_read(pdata, + pdata->fn01_query_base_addr, + std_queries, + sizeof(std_queries)); + if (retval != sizeof(std_queries)) { + dev_err(&client->dev, "%s:Failed reading queries\n", + __func__); + return -EIO; + } + + /* Currently supported RMI version is 4.0 */ + pdata->rmi4_mod_info.version_major = 4; + pdata->rmi4_mod_info.version_minor = 0; + /* + * get manufacturer id, product_props, product info, + * date code, tester id, serial num and product id (name) + */ + pdata->rmi4_mod_info.manufacturer_id = std_queries[0]; + pdata->rmi4_mod_info.product_props = std_queries[1]; + pdata->rmi4_mod_info.product_info[0] = std_queries[2]; + pdata->rmi4_mod_info.product_info[1] = std_queries[3]; + /* year - 2001-2032 */ + pdata->rmi4_mod_info.date_code[0] = std_queries[4] & MASK_5BIT; + /* month - 1-12 */ + pdata->rmi4_mod_info.date_code[1] = std_queries[5] & MASK_4BIT; + /* day - 1-31 */ + pdata->rmi4_mod_info.date_code[2] = std_queries[6] & MASK_5BIT; + pdata->rmi4_mod_info.tester_id = ((std_queries[7] & MASK_7BIT) << 8) | + (std_queries[8] & MASK_7BIT); + pdata->rmi4_mod_info.serial_number = + ((std_queries[9] & MASK_7BIT) << 8) | + (std_queries[10] & MASK_7BIT); + memcpy(pdata->rmi4_mod_info.product_id_string, &std_queries[11], 10); + + /* Check if this is a Synaptics device - report if not. */ + if (pdata->rmi4_mod_info.manufacturer_id != 1) + dev_err(&client->dev, "%s: non-Synaptics mfg id:%d\n", + __func__, pdata->rmi4_mod_info.manufacturer_id); + + list_for_each_entry(rfi, &pdata->rmi4_mod_info.support_fn_list, link) + data_sources += rfi->num_of_data_sources; + if (data_sources) { + rmi = &(pdata->rmi4_mod_info); + list_for_each_entry(rfi, &rmi->support_fn_list, link) { + if (rfi->num_of_data_sources) { + if (rfi->fn_number == + SYNAPTICS_RMI4_TOUCHPAD_FUNC_NUM) { + retval = synpatics_rmi4_touchpad_config + (pdata, rfi); + if (retval < 0) + return retval; + } else + dev_err(&client->dev, + "%s:fn_number not supported\n", + __func__); + /* + * Turn on interrupts for this + * function's data sources. + */ + ctrl_offset = pdata->fn01_ctrl_base_addr + 1 + + rfi->index_to_intr_reg; + retval = synaptics_rmi4_i2c_byte_write(pdata, + ctrl_offset, + rfi->intr_mask); + if (retval < 0) + return retval; + } + } + } + return 0; +} + +/** + * synaptics_rmi4_probe() - Initialze the i2c-client touchscreen driver + * @i2c: i2c client structure pointer + * @id:i2c device id pointer + * + * This function will allocate and initialize the instance + * data and request the irq and set the instance data as the clients + * platform data then register the physical driver which will do a scan of + * the rmi4 Physical Device Table and enumerate any rmi4 functions that + * have data sources associated with them. + */ +static int __devinit synaptics_rmi4_probe + (struct i2c_client *client, const struct i2c_device_id *dev_id) +{ + int retval; + unsigned char intr_status[4]; + struct synaptics_rmi4_data *rmi4_data; + const struct synaptics_rmi4_platform_data *platformdata = + client->dev.platform_data; + + if (!i2c_check_functionality(client->adapter, + I2C_FUNC_SMBUS_BYTE_DATA)) { + dev_err(&client->dev, "i2c smbus byte data not supported\n"); + return -EIO; + } + + if (!platformdata) { + dev_err(&client->dev, "%s: no platform data\n", __func__); + return -EINVAL; + } + + /* Allocate and initialize the instance data for this client */ + rmi4_data = kzalloc(sizeof(struct synaptics_rmi4_data) * 2, + GFP_KERNEL); + if (!rmi4_data) { + dev_err(&client->dev, "%s: no memory allocated\n", __func__); + return -ENOMEM; + } + + rmi4_data->input_dev = input_allocate_device(); + if (rmi4_data->input_dev == NULL) { + dev_err(&client->dev, "%s:input device alloc failed\n", + __func__); + retval = -ENOMEM; + goto err_input; + } + + dev_set_name(&client->dev, platformdata->name); + + if (platformdata->regulator_en) { + rmi4_data->regulator = regulator_get(&client->dev, "v-touch"); + if (IS_ERR(rmi4_data->regulator)) { + dev_err(&client->dev, "%s:get regulator failed\n", + __func__); + retval = PTR_ERR(rmi4_data->regulator); + goto err_regulator; + } + regulator_enable(rmi4_data->regulator); + } + + init_waitqueue_head(&rmi4_data->wait); + /* + * Copy i2c_client pointer into RTID's i2c_client pointer for + * later use in rmi4_read, rmi4_write, etc. + */ + rmi4_data->i2c_client = client; + /* So we set the page correctly the first time */ + rmi4_data->current_page = MASK_16BIT; + rmi4_data->board = platformdata; + rmi4_data->touch_stopped = false; + + /* init the mutexes for maintain the lists */ + mutex_init(&(rmi4_data->fn_list_mutex)); + mutex_init(&(rmi4_data->rmi4_page_mutex)); + + /* + * Register physical driver - this will call the detect function that + * will then scan the device and determine the supported + * rmi4 functions. + */ + retval = synaptics_rmi4_i2c_query_device(rmi4_data); + if (retval) { + dev_err(&client->dev, "%s: rmi4 query device failed\n", + __func__); + goto err_query_dev; + } + + /* Store the instance data in the i2c_client */ + i2c_set_clientdata(client, rmi4_data); + + /*initialize the input device parameters */ + rmi4_data->input_dev->name = DRIVER_NAME; + rmi4_data->input_dev->phys = "Synaptics_Clearpad"; + rmi4_data->input_dev->id.bustype = BUS_I2C; + rmi4_data->input_dev->dev.parent = &client->dev; + input_set_drvdata(rmi4_data->input_dev, rmi4_data); + + /* Initialize the function handlers for rmi4 */ + set_bit(EV_SYN, rmi4_data->input_dev->evbit); + set_bit(EV_KEY, rmi4_data->input_dev->evbit); + set_bit(EV_ABS, rmi4_data->input_dev->evbit); + + input_set_abs_params(rmi4_data->input_dev, ABS_MT_POSITION_X, 0, + rmi4_data->sensor_max_x, 0, 0); + input_set_abs_params(rmi4_data->input_dev, ABS_MT_POSITION_Y, 0, + rmi4_data->sensor_max_y, 0, 0); + input_set_abs_params(rmi4_data->input_dev, ABS_MT_TOUCH_MAJOR, 0, + MAX_TOUCH_MAJOR, 0, 0); + + retval = input_register_device(rmi4_data->input_dev); + if (retval) { + dev_err(&client->dev, "%s:input register failed\n", __func__); + goto err_input_register; + } + + /* Clear interrupts */ + synaptics_rmi4_i2c_block_read(rmi4_data, + rmi4_data->fn01_data_base_addr + 1, intr_status, + rmi4_data->number_of_interrupt_register); + retval = request_threaded_irq(platformdata->irq_number, NULL, + synaptics_rmi4_irq, + platformdata->irq_type, + platformdata->name, rmi4_data); + if (retval) { + dev_err(&client->dev, "%s:Unable to get attn irq %d\n", + __func__, platformdata->irq_number); + goto err_request_irq; + } + + return retval; + +err_request_irq: + free_irq(platformdata->irq_number, rmi4_data); + input_unregister_device(rmi4_data->input_dev); +err_input_register: + i2c_set_clientdata(client, NULL); +err_query_dev: + if (platformdata->regulator_en) { + regulator_disable(rmi4_data->regulator); + regulator_put(rmi4_data->regulator); + } +err_regulator: + input_free_device(rmi4_data->input_dev); + rmi4_data->input_dev = NULL; +err_input: + kfree(rmi4_data); + + return retval; +} +/** + * synaptics_rmi4_remove() - Removes the i2c-client touchscreen driver + * @client: i2c client structure pointer + * + * This funtion uses to remove the i2c-client + * touchscreen driver and returns integer. + */ +static int __devexit synaptics_rmi4_remove(struct i2c_client *client) +{ + struct synaptics_rmi4_data *rmi4_data = i2c_get_clientdata(client); + const struct synaptics_rmi4_platform_data *pdata = rmi4_data->board; + + rmi4_data->touch_stopped = true; + wake_up(&rmi4_data->wait); + free_irq(pdata->irq_number, rmi4_data); + input_unregister_device(rmi4_data->input_dev); + if (pdata->regulator_en) { + regulator_disable(rmi4_data->regulator); + regulator_put(rmi4_data->regulator); + } + kfree(rmi4_data); + + return 0; +} + +#ifdef CONFIG_PM +/** + * synaptics_rmi4_suspend() - suspend the touch screen controller + * @dev: pointer to device structure + * + * This funtion is used to suspend the + * touch panel controller and returns integer + */ +static int synaptics_rmi4_suspend(struct device *dev) +{ + /* Touch sleep mode */ + int retval; + unsigned char intr_status; + struct synaptics_rmi4_data *rmi4_data = dev_get_drvdata(dev); + const struct synaptics_rmi4_platform_data *pdata = rmi4_data->board; + + rmi4_data->touch_stopped = true; + disable_irq(pdata->irq_number); + + retval = synaptics_rmi4_i2c_block_read(rmi4_data, + rmi4_data->fn01_data_base_addr + 1, + &intr_status, + rmi4_data->number_of_interrupt_register); + if (retval < 0) + return retval; + + retval = synaptics_rmi4_i2c_byte_write(rmi4_data, + rmi4_data->fn01_ctrl_base_addr + 1, + (intr_status & ~TOUCHPAD_CTRL_INTR)); + if (retval < 0) + return retval; + + if (pdata->regulator_en) + regulator_disable(rmi4_data->regulator); + + return 0; +} +/** + * synaptics_rmi4_resume() - resume the touch screen controller + * @dev: pointer to device structure + * + * This funtion is used to resume the touch panel + * controller and returns integer. + */ +static int synaptics_rmi4_resume(struct device *dev) +{ + int retval; + unsigned char intr_status; + struct synaptics_rmi4_data *rmi4_data = dev_get_drvdata(dev); + const struct synaptics_rmi4_platform_data *pdata = rmi4_data->board; + + if (pdata->regulator_en) + regulator_enable(rmi4_data->regulator); + + enable_irq(pdata->irq_number); + rmi4_data->touch_stopped = false; + + retval = synaptics_rmi4_i2c_block_read(rmi4_data, + rmi4_data->fn01_data_base_addr + 1, + &intr_status, + rmi4_data->number_of_interrupt_register); + if (retval < 0) + return retval; + + retval = synaptics_rmi4_i2c_byte_write(rmi4_data, + rmi4_data->fn01_ctrl_base_addr + 1, + (intr_status | TOUCHPAD_CTRL_INTR)); + if (retval < 0) + return retval; + + return 0; +} + +static const struct dev_pm_ops synaptics_rmi4_dev_pm_ops = { + .suspend = synaptics_rmi4_suspend, + .resume = synaptics_rmi4_resume, +}; +#endif + +static const struct i2c_device_id synaptics_rmi4_id_table[] = { + { DRIVER_NAME, 0 }, + { }, +}; +MODULE_DEVICE_TABLE(i2c, synaptics_rmi4_id_table); + +static struct i2c_driver synaptics_rmi4_driver = { + .driver = { + .name = DRIVER_NAME, + .owner = THIS_MODULE, +#ifdef CONFIG_PM + .pm = &synaptics_rmi4_dev_pm_ops, +#endif + }, + .probe = synaptics_rmi4_probe, + .remove = __devexit_p(synaptics_rmi4_remove), + .id_table = synaptics_rmi4_id_table, +}; +/** + * synaptics_rmi4_init() - Initialize the touchscreen driver + * + * This funtion uses to initializes the synaptics + * touchscreen driver and returns integer. + */ +static int __init synaptics_rmi4_init(void) +{ + return i2c_add_driver(&synaptics_rmi4_driver); +} +/** + * synaptics_rmi4_exit() - De-initialize the touchscreen driver + * + * This funtion uses to de-initialize the synaptics + * touchscreen driver and returns none. + */ +static void __exit synaptics_rmi4_exit(void) +{ + i2c_del_driver(&synaptics_rmi4_driver); +} + + +module_init(synaptics_rmi4_init); +module_exit(synaptics_rmi4_exit); + +MODULE_LICENSE("GPL v2"); +MODULE_AUTHOR("naveen.gaddipati@stericsson.com, js.ha@stericsson.com"); +MODULE_DESCRIPTION("synaptics rmi4 i2c touch Driver"); +MODULE_ALIAS("i2c:synaptics_rmi4_ts"); diff --git a/drivers/staging/ste_rmi4/synaptics_i2c_rmi4.h b/drivers/staging/ste_rmi4/synaptics_i2c_rmi4.h new file mode 100644 index 000000000000..820ae275fa2b --- /dev/null +++ b/drivers/staging/ste_rmi4/synaptics_i2c_rmi4.h @@ -0,0 +1,50 @@ +/** + * + * Synaptics Register Mapped Interface (RMI4) I2C Physical Layer Driver. + * Copyright (c) 2007-2010, Synaptics Incorporated + * + * Author: Js HA for ST-Ericsson + * Author: Naveen Kumar G for ST-Ericsson + * Copyright 2010 (c) ST-Ericsson AB + */ +/* + * This file is licensed under the GPL2 license. + * + *############################################################################# + * GPL + * + * 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 _SYNAPTICS_RMI4_H_INCLUDED_ +#define _SYNAPTICS_RMI4_H_INCLUDED_ + +/** + * struct synaptics_rmi4_platform_data - contains the rmi4 platform data + * @irq_number: irq number + * @irq_type: irq type + * @x flip: x flip flag + * @y flip: y flip flag + * @regulator_en: regulator enable flag + * + * This structure gives platform data for rmi4. + */ +struct synaptics_rmi4_platform_data { + const char *name; + int irq_number; + int irq_type; + bool x_flip; + bool y_flip; + bool regulator_en; +}; + +#endif -- cgit v1.2.3 From e38b67c7cd3d2e377868e4c8ff4772f14ec7c45b Mon Sep 17 00:00:00 2001 From: Sven Eckelmann Date: Mon, 25 Oct 2010 23:43:14 +0200 Subject: Staging: batman-adv: Remove useless braces 77099f0afe94928b5b0066a7efa5fa9f81696b54 added changes to vis.c which trigger a checkpatch.pl warning about braces which are not necessary anymore. WARNING: braces {} are not necessary for any arm of this statement + if (entry->primary) [...] + else { [...] Signed-off-by: Sven Eckelmann Cc: Andy Shevchenko Cc: Marek Lindner Cc: Simon Wunderlich Cc: Andrew Lunn Signed-off-by: Greg Kroah-Hartman --- drivers/staging/batman-adv/vis.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/staging/batman-adv/vis.c b/drivers/staging/batman-adv/vis.c index 3d2c1bccf2e6..4473cc8ed6b0 100644 --- a/drivers/staging/batman-adv/vis.c +++ b/drivers/staging/batman-adv/vis.c @@ -135,9 +135,8 @@ static ssize_t vis_data_read_prim_sec(char *buff, struct hlist_head *if_list) hlist_for_each_entry(entry, pos, if_list, list) { if (entry->primary) len += sprintf(buff + len, "PRIMARY, "); - else { + else len += sprintf(buff + len, "SEC %pM, ", entry->addr); - } } return len; -- cgit v1.2.3 From 53b6b34dfaa0263128d1e03bed0ba6fb40df88f8 Mon Sep 17 00:00:00 2001 From: Brett Rudley Date: Tue, 26 Oct 2010 09:17:04 -0700 Subject: staging: brcm80211: Purge unused lines from bcmdefs.h/wlc_pub.h Purge unused lines Signed-off-by: Brett Rudley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/include/bcmdefs.h | 56 ++--------------------------- drivers/staging/brcm80211/sys/wlc_pub.h | 4 +-- 2 files changed, 4 insertions(+), 56 deletions(-) diff --git a/drivers/staging/brcm80211/include/bcmdefs.h b/drivers/staging/brcm80211/include/bcmdefs.h index dc52e9dbb8b5..ae6a65a64714 100644 --- a/drivers/staging/brcm80211/include/bcmdefs.h +++ b/drivers/staging/brcm80211/include/bcmdefs.h @@ -42,9 +42,6 @@ #define BCMFASTPATH #endif -/* Put some library data/code into ROM to reduce RAM requirements */ -#define BCMROMFN(_fn) _fn - /* Bus types */ #define SI_BUS 0 /* SOC Interconnect */ #define PCI_BUS 1 /* PCI target */ @@ -54,35 +51,10 @@ #define SPI_BUS 6 /* gSPI target */ #define RPC_BUS 7 /* RPC target */ -/* Allows size optimization for single-bus image */ -#ifdef BCMBUSTYPE -#define BUSTYPE(bus) (BCMBUSTYPE) -#else #define BUSTYPE(bus) (bus) -#endif - -/* Allows size optimization for single-backplane image */ -#ifdef BCMCHIPTYPE -#define CHIPTYPE(bus) (BCMCHIPTYPE) -#else #define CHIPTYPE(bus) (bus) -#endif - -/* Allows size optimization for SPROM support */ -#define SPROMBUS (PCI_BUS) - -/* Allows size optimization for single-chip image */ -#ifdef BCMCHIPID -#define CHIPID(chip) (BCMCHIPID) -#else #define CHIPID(chip) (chip) -#endif - -#ifdef BCMCHIPREV -#define CHIPREV(rev) (BCMCHIPREV) -#else #define CHIPREV(rev) (rev) -#endif /* Defines for DMA Address Width - Shared between OSL and HNDDMA */ #define DMADDR_MASK_32 0x0 /* Address mask for 32-bits */ @@ -146,31 +118,11 @@ typedef struct { #define BCMEXTRAHDROOM 172 -/* Headroom required for dongle-to-host communication. Packets allocated - * locally in the dongle (e.g. for CDC ioctls or RNDIS messages) should - * leave this much room in front for low-level message headers which may - * be needed to get across the dongle bus to the host. (These messages - * don't go over the network, so room for the full WL header above would - * be a waste.). -*/ -#define BCMDONGLEHDRSZ 12 -#define BCMDONGLEPADSZ 16 - -#define BCMDONGLEOVERHEAD (BCMDONGLEHDRSZ + BCMDONGLEPADSZ) - #ifdef BCMDBG - -#define BCMDBG_ERR - #ifndef BCMDBG_ASSERT #define BCMDBG_ASSERT -#endif /* BCMDBG_ASSERT */ - -#endif /* BCMDBG */ - -#if defined(BCMDBG_ASSERT) -#define BCMASSERT_SUPPORT -#endif +#endif /* BCMDBG_ASSERT */ +#endif /* BCMDBG */ /* Macros for doing definition and get/set of bitfields * Usage example, e.g. a three-bit field (bits 4-6): @@ -190,10 +142,6 @@ typedef struct { (((val) & (~(field ## _M << field ## _S))) | \ ((unsigned)(bits) << field ## _S)) -/* define BCMSMALL to remove misc features for memory-constrained environments */ -#define BCMSPACE -#define bcmspace true /* if (bcmspace) code is retained */ - /* Max. nvram variable table size */ #define MAXSZ_NVRAM_VARS 4096 diff --git a/drivers/staging/brcm80211/sys/wlc_pub.h b/drivers/staging/brcm80211/sys/wlc_pub.h index a6a8c33483c9..a392436c4d45 100644 --- a/drivers/staging/brcm80211/sys/wlc_pub.h +++ b/drivers/staging/brcm80211/sys/wlc_pub.h @@ -437,9 +437,9 @@ struct wlc_if; #define EDCF_ENAB(pub) (WME_ENAB(pub)) #define QOS_ENAB(pub) (WME_ENAB(pub) || N_ENAB(pub)) -#define MONITOR_ENAB(wlc) (bcmspace && (wlc)->monitor) +#define MONITOR_ENAB(wlc) ((wlc)->monitor) -#define PROMISC_ENAB(wlc) (bcmspace && (wlc)->promisc) +#define PROMISC_ENAB(wlc) ((wlc)->promisc) extern void wlc_pkttag_info_move(wlc_pub_t *pub, void *pkt_from, void *pkt_to); -- cgit v1.2.3 From ded6d25baa6bb0b3a41fa50a0427258c5d09ea7f Mon Sep 17 00:00:00 2001 From: Brett Rudley Date: Tue, 26 Oct 2010 09:17:05 -0700 Subject: staging: brcm80211: Purge unused includes from d11.h Purge unused #includes from d11.h Signed-off-by: Brett Rudley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/include/d11.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/staging/brcm80211/include/d11.h b/drivers/staging/brcm80211/include/d11.h index c07548c70e30..f52714165cc9 100644 --- a/drivers/staging/brcm80211/include/d11.h +++ b/drivers/staging/brcm80211/include/d11.h @@ -17,12 +17,9 @@ #ifndef _D11_H #define _D11_H -#include #include -#include #include #include -#include /* This marks the start of a packed structure section. */ #include -- cgit v1.2.3 From a52ba66cf2e06dc7b9ad655b74324e81f756dbd3 Mon Sep 17 00:00:00 2001 From: Brett Rudley Date: Tue, 26 Oct 2010 09:17:06 -0700 Subject: staging: brcm80211: Move #includes out of d11.h Move #includes out of d11.h and into .c files Signed-off-by: Brett Rudley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/include/d11.h | 4 ---- drivers/staging/brcm80211/phy/wlc_phy_cmn.c | 3 +++ drivers/staging/brcm80211/phy/wlc_phy_lcn.c | 4 ++++ drivers/staging/brcm80211/phy/wlc_phy_n.c | 4 ++++ drivers/staging/brcm80211/phy/wlc_phytbl_lcn.c | 2 ++ drivers/staging/brcm80211/phy/wlc_phytbl_n.c | 2 ++ drivers/staging/brcm80211/sys/wl_mac80211.c | 2 ++ drivers/staging/brcm80211/sys/wlc_alloc.c | 2 ++ drivers/staging/brcm80211/sys/wlc_ampdu.c | 1 + drivers/staging/brcm80211/sys/wlc_antsel.c | 3 +++ drivers/staging/brcm80211/sys/wlc_bmac.c | 1 + drivers/staging/brcm80211/sys/wlc_channel.c | 2 ++ drivers/staging/brcm80211/sys/wlc_event.c | 2 ++ drivers/staging/brcm80211/sys/wlc_mac80211.c | 2 ++ drivers/staging/brcm80211/sys/wlc_rate.c | 2 ++ drivers/staging/brcm80211/sys/wlc_stf.c | 2 ++ 16 files changed, 34 insertions(+), 4 deletions(-) diff --git a/drivers/staging/brcm80211/include/d11.h b/drivers/staging/brcm80211/include/d11.h index f52714165cc9..be2d4970407c 100644 --- a/drivers/staging/brcm80211/include/d11.h +++ b/drivers/staging/brcm80211/include/d11.h @@ -17,10 +17,6 @@ #ifndef _D11_H #define _D11_H -#include -#include -#include - /* This marks the start of a packed structure section. */ #include diff --git a/drivers/staging/brcm80211/phy/wlc_phy_cmn.c b/drivers/staging/brcm80211/phy/wlc_phy_cmn.c index 8287261120f4..c1882e2b291f 100644 --- a/drivers/staging/brcm80211/phy/wlc_phy_cmn.c +++ b/drivers/staging/brcm80211/phy/wlc_phy_cmn.c @@ -24,6 +24,9 @@ #include #include #include +#include +#include +#include #include #include diff --git a/drivers/staging/brcm80211/phy/wlc_phy_lcn.c b/drivers/staging/brcm80211/phy/wlc_phy_lcn.c index 3d3112ed4e20..4efd8623e715 100644 --- a/drivers/staging/brcm80211/phy/wlc_phy_lcn.c +++ b/drivers/staging/brcm80211/phy/wlc_phy_lcn.c @@ -24,6 +24,10 @@ #include #include +#include +#include +#include + #include #include #include diff --git a/drivers/staging/brcm80211/phy/wlc_phy_n.c b/drivers/staging/brcm80211/phy/wlc_phy_n.c index 950008f122b1..36f73e8adb64 100644 --- a/drivers/staging/brcm80211/phy/wlc_phy_n.c +++ b/drivers/staging/brcm80211/phy/wlc_phy_n.c @@ -25,6 +25,10 @@ #include #include +#include +#include +#include + #include #include #include diff --git a/drivers/staging/brcm80211/phy/wlc_phytbl_lcn.c b/drivers/staging/brcm80211/phy/wlc_phytbl_lcn.c index 6ce9e5d96830..fd155a0a22ef 100644 --- a/drivers/staging/brcm80211/phy/wlc_phytbl_lcn.c +++ b/drivers/staging/brcm80211/phy/wlc_phytbl_lcn.c @@ -15,6 +15,8 @@ */ #include +#include +#include #include #include diff --git a/drivers/staging/brcm80211/phy/wlc_phytbl_n.c b/drivers/staging/brcm80211/phy/wlc_phytbl_n.c index 7cc2c563c727..257c0bba4e54 100644 --- a/drivers/staging/brcm80211/phy/wlc_phytbl_n.c +++ b/drivers/staging/brcm80211/phy/wlc_phytbl_n.c @@ -16,6 +16,8 @@ #include +#include +#include #include #include diff --git a/drivers/staging/brcm80211/sys/wl_mac80211.c b/drivers/staging/brcm80211/sys/wl_mac80211.c index d060377629ac..d182b0233c9b 100644 --- a/drivers/staging/brcm80211/sys/wl_mac80211.c +++ b/drivers/staging/brcm80211/sys/wl_mac80211.c @@ -35,6 +35,8 @@ #include #include #include +#include +#include #include #include #include diff --git a/drivers/staging/brcm80211/sys/wlc_alloc.c b/drivers/staging/brcm80211/sys/wlc_alloc.c index 2dc89f9c2635..dc1fe2448d70 100644 --- a/drivers/staging/brcm80211/sys/wlc_alloc.c +++ b/drivers/staging/brcm80211/sys/wlc_alloc.c @@ -24,6 +24,8 @@ #include #include #include +#include +#include #include #include diff --git a/drivers/staging/brcm80211/sys/wlc_ampdu.c b/drivers/staging/brcm80211/sys/wlc_ampdu.c index a4e49f3c1363..7a8340bd80dd 100644 --- a/drivers/staging/brcm80211/sys/wlc_ampdu.c +++ b/drivers/staging/brcm80211/sys/wlc_ampdu.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/staging/brcm80211/sys/wlc_antsel.c b/drivers/staging/brcm80211/sys/wlc_antsel.c index 5ff8831d2fa8..eac5b21d5df5 100644 --- a/drivers/staging/brcm80211/sys/wlc_antsel.c +++ b/drivers/staging/brcm80211/sys/wlc_antsel.c @@ -26,6 +26,9 @@ #include #include +#include +#include +#include #include #include #include diff --git a/drivers/staging/brcm80211/sys/wlc_bmac.c b/drivers/staging/brcm80211/sys/wlc_bmac.c index b70f9d099233..5045b8c68300 100644 --- a/drivers/staging/brcm80211/sys/wlc_bmac.c +++ b/drivers/staging/brcm80211/sys/wlc_bmac.c @@ -42,6 +42,7 @@ #include #include #include +#include /* BMAC_NOTE: a WLC_HIGH compile include of wlc.h adds in more structures and type * dependencies. Need to include these to files to allow a clean include of wlc.h * with WLC_HIGH defined. diff --git a/drivers/staging/brcm80211/sys/wlc_channel.c b/drivers/staging/brcm80211/sys/wlc_channel.c index 509280337e34..e786d990639e 100644 --- a/drivers/staging/brcm80211/sys/wlc_channel.c +++ b/drivers/staging/brcm80211/sys/wlc_channel.c @@ -22,6 +22,8 @@ #include #include #include +#include +#include #include #include #include diff --git a/drivers/staging/brcm80211/sys/wlc_event.c b/drivers/staging/brcm80211/sys/wlc_event.c index 7e1bf0e2ecdd..87181c111056 100644 --- a/drivers/staging/brcm80211/sys/wlc_event.c +++ b/drivers/staging/brcm80211/sys/wlc_event.c @@ -19,6 +19,8 @@ #include #include #include +#include +#include #include #include #include diff --git a/drivers/staging/brcm80211/sys/wlc_mac80211.c b/drivers/staging/brcm80211/sys/wlc_mac80211.c index feaffcc64ec6..f64177436a62 100644 --- a/drivers/staging/brcm80211/sys/wlc_mac80211.c +++ b/drivers/staging/brcm80211/sys/wlc_mac80211.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -28,6 +29,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/staging/brcm80211/sys/wlc_rate.c b/drivers/staging/brcm80211/sys/wlc_rate.c index d2d72568756d..5b216b0bd9a4 100644 --- a/drivers/staging/brcm80211/sys/wlc_rate.c +++ b/drivers/staging/brcm80211/sys/wlc_rate.c @@ -23,6 +23,8 @@ #include #include +#include +#include #include #include #include diff --git a/drivers/staging/brcm80211/sys/wlc_stf.c b/drivers/staging/brcm80211/sys/wlc_stf.c index 4728ad90e295..2d02ae7bdd8b 100644 --- a/drivers/staging/brcm80211/sys/wlc_stf.c +++ b/drivers/staging/brcm80211/sys/wlc_stf.c @@ -25,6 +25,8 @@ #include #include #include +#include +#include #include #include #include -- cgit v1.2.3 From c6ac24e90a3f6a3cf25e3b1e4d8957032acf70a6 Mon Sep 17 00:00:00 2001 From: Brett Rudley Date: Tue, 26 Oct 2010 11:55:23 -0700 Subject: staging: brcm80211: Purge linuxver.h and redistribute #includes as required Linuxver.h only included other .h files. Delete it and move #includes to .c's as needed. Signed-off-by: Brett Rudley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmfmac/bcmsdh.c | 1 + drivers/staging/brcm80211/brcmfmac/bcmsdh_linux.c | 3 +- drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c | 1 + .../brcm80211/brcmfmac/bcmsdh_sdmmc_linux.c | 1 + drivers/staging/brcm80211/brcmfmac/dhd_cdc.c | 1 + drivers/staging/brcm80211/brcmfmac/dhd_common.c | 1 + .../staging/brcm80211/brcmfmac/dhd_custom_gpio.c | 2 +- drivers/staging/brcm80211/brcmfmac/dhd_linux.c | 1 - .../staging/brcm80211/brcmfmac/dhd_linux_sched.c | 1 - drivers/staging/brcm80211/brcmfmac/dhd_sdio.c | 1 + drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c | 1 - drivers/staging/brcm80211/brcmfmac/wl_iw.c | 2 +- drivers/staging/brcm80211/include/linux_osl.h | 4 --- drivers/staging/brcm80211/include/linuxver.h | 38 ---------------------- drivers/staging/brcm80211/phy/wlc_phy_cmn.c | 3 +- drivers/staging/brcm80211/phy/wlc_phy_lcn.c | 2 +- drivers/staging/brcm80211/phy/wlc_phy_n.c | 2 +- drivers/staging/brcm80211/sys/wl_mac80211.c | 4 ++- drivers/staging/brcm80211/sys/wlc_alloc.c | 3 +- drivers/staging/brcm80211/sys/wlc_ampdu.c | 2 -- drivers/staging/brcm80211/sys/wlc_antsel.c | 3 +- drivers/staging/brcm80211/sys/wlc_bmac.c | 4 ++- drivers/staging/brcm80211/sys/wlc_channel.c | 3 +- drivers/staging/brcm80211/sys/wlc_event.c | 3 +- drivers/staging/brcm80211/sys/wlc_mac80211.c | 1 - drivers/staging/brcm80211/sys/wlc_phy_shim.c | 3 +- drivers/staging/brcm80211/sys/wlc_rate.c | 2 +- drivers/staging/brcm80211/sys/wlc_stf.c | 2 +- drivers/staging/brcm80211/util/aiutils.c | 6 +++- drivers/staging/brcm80211/util/bcmotp.c | 3 +- drivers/staging/brcm80211/util/bcmsrom.c | 3 +- drivers/staging/brcm80211/util/bcmutils.c | 5 +-- drivers/staging/brcm80211/util/bcmwifi.c | 3 ++ drivers/staging/brcm80211/util/hnddma.c | 3 +- drivers/staging/brcm80211/util/hndpmu.c | 6 +++- drivers/staging/brcm80211/util/linux_osl.c | 5 ++- drivers/staging/brcm80211/util/nicpci.c | 2 +- drivers/staging/brcm80211/util/sbutils.c | 3 ++ drivers/staging/brcm80211/util/siutils.c | 6 +++- 39 files changed, 66 insertions(+), 74 deletions(-) delete mode 100644 drivers/staging/brcm80211/include/linuxver.h diff --git a/drivers/staging/brcm80211/brcmfmac/bcmsdh.c b/drivers/staging/brcm80211/brcmfmac/bcmsdh.c index 4c613da3553a..3f79637f9e3c 100644 --- a/drivers/staging/brcm80211/brcmfmac/bcmsdh.c +++ b/drivers/staging/brcm80211/brcmfmac/bcmsdh.c @@ -16,6 +16,7 @@ /* ****************** BCMSDH Interface Functions *************************** */ #include +#include #include #include #include diff --git a/drivers/staging/brcm80211/brcmfmac/bcmsdh_linux.c b/drivers/staging/brcm80211/brcmfmac/bcmsdh_linux.c index 9028cd01d9d0..59eaf71040b2 100644 --- a/drivers/staging/brcm80211/brcmfmac/bcmsdh_linux.c +++ b/drivers/staging/brcm80211/brcmfmac/bcmsdh_linux.c @@ -20,8 +20,7 @@ #define __UNDEF_NO_VERSION__ -#include - +#include #include #include diff --git a/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c b/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c index f6c9c4541813..7d3d7cc74948 100644 --- a/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c +++ b/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c @@ -14,6 +14,7 @@ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include +#include #include #include #include diff --git a/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc_linux.c b/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc_linux.c index ae7b566b11d7..b9f91fa86104 100644 --- a/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc_linux.c +++ b/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc_linux.c @@ -15,6 +15,7 @@ */ #include #include /* request_irq() */ +#include #include #include #include /* SDIO Specs */ diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_cdc.c b/drivers/staging/brcm80211/brcmfmac/dhd_cdc.c index bcbaac9bcdcc..0d14f6c1fcfa 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_cdc.c +++ b/drivers/staging/brcm80211/brcmfmac/dhd_cdc.c @@ -15,6 +15,7 @@ */ #include +#include #include #include diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_common.c b/drivers/staging/brcm80211/brcmfmac/dhd_common.c index 703188fc28ec..f7ffea69233c 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_common.c +++ b/drivers/staging/brcm80211/brcmfmac/dhd_common.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_custom_gpio.c b/drivers/staging/brcm80211/brcmfmac/dhd_custom_gpio.c index f647034f36d6..bb3c7b8c4b98 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_custom_gpio.c +++ b/drivers/staging/brcm80211/brcmfmac/dhd_custom_gpio.c @@ -14,7 +14,7 @@ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include +#include #include #include diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_linux.c b/drivers/staging/brcm80211/brcmfmac/dhd_linux.c index bbbe7c5f7492..797bff3be416 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_linux.c +++ b/drivers/staging/brcm80211/brcmfmac/dhd_linux.c @@ -32,7 +32,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_linux_sched.c b/drivers/staging/brcm80211/brcmfmac/dhd_linux_sched.c index bf8df9801030..c66f1c2941e2 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_linux_sched.c +++ b/drivers/staging/brcm80211/brcmfmac/dhd_linux_sched.c @@ -16,7 +16,6 @@ #include #include #include -#include int setScheduler(struct task_struct *p, int policy, struct sched_param *param) { diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c b/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c index b2281d9dfdcf..66884d47e834 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c +++ b/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c @@ -16,6 +16,7 @@ #include #include +#include #include #include diff --git a/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c index 3f29488d9c72..21fe38fa736e 100644 --- a/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c +++ b/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c @@ -16,7 +16,6 @@ #include #include -#include #include #include diff --git a/drivers/staging/brcm80211/brcmfmac/wl_iw.c b/drivers/staging/brcm80211/brcmfmac/wl_iw.c index 979a494fda59..3e053fe56c79 100644 --- a/drivers/staging/brcm80211/brcmfmac/wl_iw.c +++ b/drivers/staging/brcm80211/brcmfmac/wl_iw.c @@ -16,7 +16,7 @@ #include #include -#include +#include #include #include diff --git a/drivers/staging/brcm80211/include/linux_osl.h b/drivers/staging/brcm80211/include/linux_osl.h index c9c860b6e474..b13ae7614042 100644 --- a/drivers/staging/brcm80211/include/linux_osl.h +++ b/drivers/staging/brcm80211/include/linux_osl.h @@ -299,10 +299,6 @@ extern int osl_error(int bcmerror); #define W_SM(r, v) (*(r) = (v)) #define BZERO_SM(r, len) memset((r), '\0', (len)) -#ifdef BRCM_FULLMAC -#include /* use current 2.4.x calling conventions */ -#endif - /* packet primitives */ #define PKTGET(osh, len, send) osl_pktget((osh), (len)) #define PKTFREE(osh, skb, send) osl_pktfree((osh), (skb), (send)) diff --git a/drivers/staging/brcm80211/include/linuxver.h b/drivers/staging/brcm80211/include/linuxver.h deleted file mode 100644 index dc721413ee29..000000000000 --- a/drivers/staging/brcm80211/include/linuxver.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _linuxver_h_ -#define _linuxver_h_ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#undef IP_TOS -#include - -#endif /* _linuxver_h_ */ diff --git a/drivers/staging/brcm80211/phy/wlc_phy_cmn.c b/drivers/staging/brcm80211/phy/wlc_phy_cmn.c index c1882e2b291f..9e6bbcdf8b6f 100644 --- a/drivers/staging/brcm80211/phy/wlc_phy_cmn.c +++ b/drivers/staging/brcm80211/phy/wlc_phy_cmn.c @@ -20,7 +20,8 @@ #include #include #include -#include +#include +#include #include #include #include diff --git a/drivers/staging/brcm80211/phy/wlc_phy_lcn.c b/drivers/staging/brcm80211/phy/wlc_phy_lcn.c index 4efd8623e715..1fde9d5701b0 100644 --- a/drivers/staging/brcm80211/phy/wlc_phy_lcn.c +++ b/drivers/staging/brcm80211/phy/wlc_phy_lcn.c @@ -20,7 +20,7 @@ #include #include #include -#include +#include #include #include diff --git a/drivers/staging/brcm80211/phy/wlc_phy_n.c b/drivers/staging/brcm80211/phy/wlc_phy_n.c index 36f73e8adb64..3e1ab579c086 100644 --- a/drivers/staging/brcm80211/phy/wlc_phy_n.c +++ b/drivers/staging/brcm80211/phy/wlc_phy_n.c @@ -18,7 +18,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/drivers/staging/brcm80211/sys/wl_mac80211.c b/drivers/staging/brcm80211/sys/wl_mac80211.c index d182b0233c9b..a2e21dc34444 100644 --- a/drivers/staging/brcm80211/sys/wl_mac80211.c +++ b/drivers/staging/brcm80211/sys/wl_mac80211.c @@ -21,7 +21,9 @@ #include #include #include -#include +#include +#include +#include #include #define WLC_MAXBSSCFG 1 /* single BSS configs */ diff --git a/drivers/staging/brcm80211/sys/wlc_alloc.c b/drivers/staging/brcm80211/sys/wlc_alloc.c index dc1fe2448d70..8240d4ba962e 100644 --- a/drivers/staging/brcm80211/sys/wlc_alloc.c +++ b/drivers/staging/brcm80211/sys/wlc_alloc.c @@ -17,7 +17,8 @@ #include #include #include -#include +#include +#include #include #include #include diff --git a/drivers/staging/brcm80211/sys/wlc_ampdu.c b/drivers/staging/brcm80211/sys/wlc_ampdu.c index 7a8340bd80dd..5a3acf852efa 100644 --- a/drivers/staging/brcm80211/sys/wlc_ampdu.c +++ b/drivers/staging/brcm80211/sys/wlc_ampdu.c @@ -16,8 +16,6 @@ #include #include #include -#include -#include #include #include #include diff --git a/drivers/staging/brcm80211/sys/wlc_antsel.c b/drivers/staging/brcm80211/sys/wlc_antsel.c index eac5b21d5df5..3a1c1e9e7131 100644 --- a/drivers/staging/brcm80211/sys/wlc_antsel.c +++ b/drivers/staging/brcm80211/sys/wlc_antsel.c @@ -19,7 +19,8 @@ #ifdef WLANTSEL #include -#include +#include +#include #include #include #include diff --git a/drivers/staging/brcm80211/sys/wlc_bmac.c b/drivers/staging/brcm80211/sys/wlc_bmac.c index 5045b8c68300..a92a68fb4604 100644 --- a/drivers/staging/brcm80211/sys/wlc_bmac.c +++ b/drivers/staging/brcm80211/sys/wlc_bmac.c @@ -20,7 +20,9 @@ #include #include -#include +#include +#include +#include #include #include #include diff --git a/drivers/staging/brcm80211/sys/wlc_channel.c b/drivers/staging/brcm80211/sys/wlc_channel.c index e786d990639e..c7f416188093 100644 --- a/drivers/staging/brcm80211/sys/wlc_channel.c +++ b/drivers/staging/brcm80211/sys/wlc_channel.c @@ -19,7 +19,8 @@ #include #include #include -#include +#include +#include #include #include #include diff --git a/drivers/staging/brcm80211/sys/wlc_event.c b/drivers/staging/brcm80211/sys/wlc_event.c index 87181c111056..88418a293181 100644 --- a/drivers/staging/brcm80211/sys/wlc_event.c +++ b/drivers/staging/brcm80211/sys/wlc_event.c @@ -16,7 +16,8 @@ #include #include -#include +#include +#include #include #include #include diff --git a/drivers/staging/brcm80211/sys/wlc_mac80211.c b/drivers/staging/brcm80211/sys/wlc_mac80211.c index f64177436a62..c434f786594f 100644 --- a/drivers/staging/brcm80211/sys/wlc_mac80211.c +++ b/drivers/staging/brcm80211/sys/wlc_mac80211.c @@ -18,7 +18,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/staging/brcm80211/sys/wlc_phy_shim.c b/drivers/staging/brcm80211/sys/wlc_phy_shim.c index bf8e2e1a15f6..45d583b1a271 100644 --- a/drivers/staging/brcm80211/sys/wlc_phy_shim.c +++ b/drivers/staging/brcm80211/sys/wlc_phy_shim.c @@ -24,7 +24,8 @@ #include #include #include -#include +#include +#include #include #include diff --git a/drivers/staging/brcm80211/sys/wlc_rate.c b/drivers/staging/brcm80211/sys/wlc_rate.c index 5b216b0bd9a4..e1199b236f5f 100644 --- a/drivers/staging/brcm80211/sys/wlc_rate.c +++ b/drivers/staging/brcm80211/sys/wlc_rate.c @@ -17,7 +17,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/drivers/staging/brcm80211/sys/wlc_stf.c b/drivers/staging/brcm80211/sys/wlc_stf.c index 2d02ae7bdd8b..7bf326fc015b 100644 --- a/drivers/staging/brcm80211/sys/wlc_stf.c +++ b/drivers/staging/brcm80211/sys/wlc_stf.c @@ -15,8 +15,8 @@ */ #include +#include #include -#include #include #include #include diff --git a/drivers/staging/brcm80211/util/aiutils.c b/drivers/staging/brcm80211/util/aiutils.c index 75a7e3a5c009..1d4e3729ad61 100644 --- a/drivers/staging/brcm80211/util/aiutils.c +++ b/drivers/staging/brcm80211/util/aiutils.c @@ -17,8 +17,12 @@ #include #include #include +#ifdef BRCM_FULLMAC +#include +#endif #include -#include +#include +#include #include #include #include diff --git a/drivers/staging/brcm80211/util/bcmotp.c b/drivers/staging/brcm80211/util/bcmotp.c index c909832c7ee1..9b1e6d961a72 100644 --- a/drivers/staging/brcm80211/util/bcmotp.c +++ b/drivers/staging/brcm80211/util/bcmotp.c @@ -18,7 +18,8 @@ #include #include #include -#include +#include +#include #include #include #include diff --git a/drivers/staging/brcm80211/util/bcmsrom.c b/drivers/staging/brcm80211/util/bcmsrom.c index 1282ef7eb922..4f3d3ca1af79 100644 --- a/drivers/staging/brcm80211/util/bcmsrom.c +++ b/drivers/staging/brcm80211/util/bcmsrom.c @@ -17,7 +17,8 @@ #include #include #include -#include +#include +#include #include #include #include diff --git a/drivers/staging/brcm80211/util/bcmutils.c b/drivers/staging/brcm80211/util/bcmutils.c index 9789ea45ecd6..869d34c420d2 100644 --- a/drivers/staging/brcm80211/util/bcmutils.c +++ b/drivers/staging/brcm80211/util/bcmutils.c @@ -19,8 +19,10 @@ #include #include #include +#include +#include +#include #include -#include #include #include #include @@ -30,7 +32,6 @@ #include #include - /* copy a buffer into a pkt buffer chain */ uint pktfrombuf(osl_t *osh, void *p, uint offset, int len, unsigned char *buf) { diff --git a/drivers/staging/brcm80211/util/bcmwifi.c b/drivers/staging/brcm80211/util/bcmwifi.c index 1bb6c78eece7..2e472e00adc3 100644 --- a/drivers/staging/brcm80211/util/bcmwifi.c +++ b/drivers/staging/brcm80211/util/bcmwifi.c @@ -15,6 +15,9 @@ */ #include #include +#ifdef BRCM_FULLMAC +#include +#endif #include #include #include diff --git a/drivers/staging/brcm80211/util/hnddma.c b/drivers/staging/brcm80211/util/hnddma.c index fe503e7de563..b4dcb05705b3 100644 --- a/drivers/staging/brcm80211/util/hnddma.c +++ b/drivers/staging/brcm80211/util/hnddma.c @@ -16,7 +16,8 @@ #include #include -#include +#include +#include #include #include #include diff --git a/drivers/staging/brcm80211/util/hndpmu.c b/drivers/staging/brcm80211/util/hndpmu.c index a8f3306c1d2b..6fb256bc5549 100644 --- a/drivers/staging/brcm80211/util/hndpmu.c +++ b/drivers/staging/brcm80211/util/hndpmu.c @@ -15,7 +15,11 @@ */ #include #include -#include +#include +#include +#ifdef BRCM_FULLMAC +#include +#endif #include #include #include diff --git a/drivers/staging/brcm80211/util/linux_osl.c b/drivers/staging/brcm80211/util/linux_osl.c index 2bb5b8722df6..effe043f1962 100644 --- a/drivers/staging/brcm80211/util/linux_osl.c +++ b/drivers/staging/brcm80211/util/linux_osl.c @@ -20,7 +20,10 @@ #include #endif /* mips */ #include -#include +#include +#include +#include +#include #include #include #include diff --git a/drivers/staging/brcm80211/util/nicpci.c b/drivers/staging/brcm80211/util/nicpci.c index 23f86dd7b159..169a4287ee63 100644 --- a/drivers/staging/brcm80211/util/nicpci.c +++ b/drivers/staging/brcm80211/util/nicpci.c @@ -15,7 +15,7 @@ */ #include -#include +#include #include #include #include diff --git a/drivers/staging/brcm80211/util/sbutils.c b/drivers/staging/brcm80211/util/sbutils.c index e4c0baba553d..82767e266e97 100644 --- a/drivers/staging/brcm80211/util/sbutils.c +++ b/drivers/staging/brcm80211/util/sbutils.c @@ -16,6 +16,9 @@ #include #include +#ifdef BRCM_FULLMAC +#include +#endif #include #include #include diff --git a/drivers/staging/brcm80211/util/siutils.c b/drivers/staging/brcm80211/util/siutils.c index f3ea7e1a7aef..3b99293307ea 100644 --- a/drivers/staging/brcm80211/util/siutils.c +++ b/drivers/staging/brcm80211/util/siutils.c @@ -17,8 +17,12 @@ #include #include #include +#ifdef BRCM_FULLMAC +#include +#endif #include -#include +#include +#include #include #include #include -- cgit v1.2.3 From 7f7c3dbb3f6d8624109ee30ad5a8f6b23f0a72f4 Mon Sep 17 00:00:00 2001 From: Brett Rudley Date: Tue, 26 Oct 2010 15:23:09 -0700 Subject: staging: brcm80211: Move #include from bcmutils.h out to .c files Part of effort to move #includes out of .h files and unwind the include mess. Signed-off-by: Brett Rudley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmfmac/bcmsdh.c | 2 +- drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c | 2 +- drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc_linux.c | 1 + drivers/staging/brcm80211/include/bcmutils.h | 1 - drivers/staging/brcm80211/phy/wlc_phytbl_lcn.c | 1 + drivers/staging/brcm80211/phy/wlc_phytbl_n.c | 1 + drivers/staging/brcm80211/sys/wlc_event.c | 1 + drivers/staging/brcm80211/sys/wlc_phy_shim.c | 2 +- drivers/staging/brcm80211/util/bcmwifi.c | 1 + 9 files changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/staging/brcm80211/brcmfmac/bcmsdh.c b/drivers/staging/brcm80211/brcmfmac/bcmsdh.c index 3f79637f9e3c..6738983e2d5c 100644 --- a/drivers/staging/brcm80211/brcmfmac/bcmsdh.c +++ b/drivers/staging/brcm80211/brcmfmac/bcmsdh.c @@ -20,10 +20,10 @@ #include #include #include +#include #include #include #include -#include #include /* BRCM API for SDIO clients (such as wl, dhd) */ diff --git a/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c b/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c index 7d3d7cc74948..039f114130d2 100644 --- a/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c +++ b/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c @@ -18,8 +18,8 @@ #include #include #include -#include #include +#include #include /* SDIO Device and Protocol Specs */ #include /* SDIO Host Controller Specification */ #include /* bcmsdh to/from specific controller APIs */ diff --git a/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc_linux.c b/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc_linux.c index b9f91fa86104..14f73fd28760 100644 --- a/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc_linux.c +++ b/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc_linux.c @@ -17,6 +17,7 @@ #include /* request_irq() */ #include #include +#include #include #include /* SDIO Specs */ #include /* bcmsdh to/from specific controller APIs */ diff --git a/drivers/staging/brcm80211/include/bcmutils.h b/drivers/staging/brcm80211/include/bcmutils.h index b53315981be0..7f1d33481ee8 100644 --- a/drivers/staging/brcm80211/include/bcmutils.h +++ b/drivers/staging/brcm80211/include/bcmutils.h @@ -30,7 +30,6 @@ }; /* ** driver-only section ** */ -#include #define GPIO_PIN_NOTDEFINED 0x20 /* Pin not defined */ diff --git a/drivers/staging/brcm80211/phy/wlc_phytbl_lcn.c b/drivers/staging/brcm80211/phy/wlc_phytbl_lcn.c index fd155a0a22ef..330b88152b65 100644 --- a/drivers/staging/brcm80211/phy/wlc_phytbl_lcn.c +++ b/drivers/staging/brcm80211/phy/wlc_phytbl_lcn.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include diff --git a/drivers/staging/brcm80211/phy/wlc_phytbl_n.c b/drivers/staging/brcm80211/phy/wlc_phytbl_n.c index 257c0bba4e54..a9fc193721ef 100644 --- a/drivers/staging/brcm80211/phy/wlc_phytbl_n.c +++ b/drivers/staging/brcm80211/phy/wlc_phytbl_n.c @@ -18,6 +18,7 @@ #include #include +#include #include #include diff --git a/drivers/staging/brcm80211/sys/wlc_event.c b/drivers/staging/brcm80211/sys/wlc_event.c index 88418a293181..4b0a59896bec 100644 --- a/drivers/staging/brcm80211/sys/wlc_event.c +++ b/drivers/staging/brcm80211/sys/wlc_event.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/staging/brcm80211/sys/wlc_phy_shim.c b/drivers/staging/brcm80211/sys/wlc_phy_shim.c index 45d583b1a271..900c505ced34 100644 --- a/drivers/staging/brcm80211/sys/wlc_phy_shim.c +++ b/drivers/staging/brcm80211/sys/wlc_phy_shim.c @@ -26,8 +26,8 @@ #include #include #include -#include #include +#include #include #include diff --git a/drivers/staging/brcm80211/util/bcmwifi.c b/drivers/staging/brcm80211/util/bcmwifi.c index 2e472e00adc3..81e54bd7a554 100644 --- a/drivers/staging/brcm80211/util/bcmwifi.c +++ b/drivers/staging/brcm80211/util/bcmwifi.c @@ -18,6 +18,7 @@ #ifdef BRCM_FULLMAC #include #endif +#include #include #include #include -- cgit v1.2.3 From eb8160364f007c668c423614e262b9b7fc7b2c74 Mon Sep 17 00:00:00 2001 From: Brett Rudley Date: Tue, 26 Oct 2010 18:37:24 -0700 Subject: staging: brcm80211: Separate fullmac vs softmac defs in shared file wlioctl.h is shared by fullmac and softmac but mostly fullmac. Separate out fullmac to purge extranous code in softmac and possibly as a step towards it own file. Signed-off-by: Brett Rudley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/include/wlioctl.h | 12 ++++++++++++ drivers/staging/brcm80211/sys/wlc_mac80211.c | 2 ++ 2 files changed, 14 insertions(+) diff --git a/drivers/staging/brcm80211/include/wlioctl.h b/drivers/staging/brcm80211/include/wlioctl.h index 96866fb8898c..81863e0cab1e 100644 --- a/drivers/staging/brcm80211/include/wlioctl.h +++ b/drivers/staging/brcm80211/include/wlioctl.h @@ -33,6 +33,7 @@ #define BWL_DEFAULT_PACKING #include +#ifdef BRCM_FULLMAC /* Legacy structure to help keep backward compatible wl tool and tray app */ #define LEGACY_WL_BSS_INFO_VERSION 107 /* older version of wl_bss_info struct */ @@ -148,12 +149,14 @@ typedef struct wl_bss_info { /* Add new fields here */ /* variable length Information Elements */ } wl_bss_info_t; +#endif /* BRCM_FULLMAC */ typedef struct wlc_ssid { u32 SSID_len; unsigned char SSID[32]; } wlc_ssid_t; +#ifdef BRCM_FULLMAC typedef struct chan_scandata { u8 txpower; u8 pad; @@ -308,6 +311,7 @@ typedef struct wl_probe_params { struct ether_addr bssid; struct ether_addr mac; } wl_probe_params_t; +#endif /* BRCM_FULLMAC */ #define WL_NUMRATES 16 /* max # of rates in a rateset */ typedef struct wl_rateset { @@ -315,6 +319,7 @@ typedef struct wl_rateset { u8 rates[WL_NUMRATES]; /* rates in 500kbps units w/hi bit set if basic */ } wl_rateset_t; +#ifdef BRCM_FULLMAC typedef struct wl_rateset_args { u32 count; /* # rates in this set */ u8 rates[WL_NUMRATES]; /* rates in 500kbps units w/hi bit set if basic */ @@ -352,6 +357,8 @@ typedef struct wl_join_params { } wl_join_params_t; #define WL_JOIN_PARAMS_FIXED_SIZE (sizeof(wl_join_params_t) - sizeof(chanspec_t)) +#endif /* BRCM_FULLMAC */ + /* defines used by the nrate iovar */ #define NRATE_MCS_INUSE 0x00000080 /* MSC in use,indicates b0-6 holds an mcs */ #define NRATE_RATE_MASK 0x0000007f /* rate/mcs value */ @@ -391,6 +398,7 @@ typedef struct { #define HIGHEST_SINGLE_STREAM_MCS 7 /* MCS values greater than this enable multiple streams */ +#ifdef BRCM_FULLMAC #define MAX_CCA_CHANNELS 38 /* Max number of 20 Mhz wide channels */ #define MAX_CCA_SECS 60 /* CCA keeps this many seconds history */ @@ -428,8 +436,11 @@ typedef struct { cca_congest_t secs[1]; /* Data */ } cca_congest_channel_req_t; +#endif /* BRCM_FULLMAC */ + #define WLC_CNTRY_BUF_SZ 4 /* Country string is 3 bytes + NUL */ +#ifdef BRCM_FULLMAC typedef struct wl_country { char country_abbrev[WLC_CNTRY_BUF_SZ]; /* nul-terminated country code used in * the Country IE @@ -516,6 +527,7 @@ typedef struct wl_rm_rep { wl_rm_rep_elt_t rep[1]; /* variable length block of reports */ } wl_rm_rep_t; #define WL_RM_REP_FIXED_LEN 8 +#endif /* BRCM_FULLMAC */ /* Enumerate crypto algorithms */ #define CRYPTO_ALGO_OFF 0 diff --git a/drivers/staging/brcm80211/sys/wlc_mac80211.c b/drivers/staging/brcm80211/sys/wlc_mac80211.c index c434f786594f..01b8110afd1c 100644 --- a/drivers/staging/brcm80211/sys/wlc_mac80211.c +++ b/drivers/staging/brcm80211/sys/wlc_mac80211.c @@ -1781,8 +1781,10 @@ void *wlc_attach(void *wl, u16 vendor, u16 device, uint unit, bool piomode, ASSERT(sizeof(struct dot11_bcn_prb) == DOT11_BCN_PRB_LEN); ASSERT(sizeof(tx_status_t) == TXSTATUS_LEN); ASSERT(sizeof(ht_cap_ie_t) == HT_CAP_IE_LEN); +#ifdef BRCM_FULLMAC ASSERT(offsetof(wl_scan_params_t, channel_list) == WL_SCAN_PARAMS_FIXED_SIZE); +#endif ASSERT(IS_ALIGNED(offsetof(wsec_key_t, data), sizeof(u32))); ASSERT(ISPOWEROF2(MA_WINDOW_SZ)); -- cgit v1.2.3 From 4766ae6ce7c5098a26136241576cd8a287d20484 Mon Sep 17 00:00:00 2001 From: Brett Rudley Date: Wed, 27 Oct 2010 15:47:53 -0700 Subject: staging: brcm80211: purge epivers.h Purge include/epivers.h moving individual lines to where they are needed and delete unused refs. Signed-off-by: Brett Rudley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/include/epivers.h | 44 ---------------------------- drivers/staging/brcm80211/sys/wl_mac80211.c | 11 ++++--- drivers/staging/brcm80211/sys/wlc_mac80211.c | 3 +- 3 files changed, 7 insertions(+), 51 deletions(-) delete mode 100644 drivers/staging/brcm80211/include/epivers.h diff --git a/drivers/staging/brcm80211/include/epivers.h b/drivers/staging/brcm80211/include/epivers.h deleted file mode 100644 index 2e6b5190ad6c..000000000000 --- a/drivers/staging/brcm80211/include/epivers.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _epivers_h_ -#define _epivers_h_ - -#define EPI_MAJOR_VERSION 5 - -#define EPI_MINOR_VERSION 75 - -#define EPI_RC_NUMBER 11 - -#define EPI_INCREMENTAL_NUMBER 0 - -#define EPI_BUILD_NUMBER 1 - -#define EPI_VERSION { 5, 75, 11, 0 } - -#ifdef BCMSDIO -/* EPI_VERSION_NUM must match FW version */ -#define EPI_VERSION_NUM 0x054b0c00 -#else -#define EPI_VERSION_NUM 0x054b0b00 -#endif - -#define EPI_VERSION_DEV 5.75.11 - -/* Driver Version String, ASCII, 32 chars max */ -#define EPI_VERSION_STR "5.75.11" - -#endif /* _epivers_h_ */ diff --git a/drivers/staging/brcm80211/sys/wl_mac80211.c b/drivers/staging/brcm80211/sys/wl_mac80211.c index a2e21dc34444..d951d330a1c8 100644 --- a/drivers/staging/brcm80211/sys/wl_mac80211.c +++ b/drivers/staging/brcm80211/sys/wl_mac80211.c @@ -29,7 +29,6 @@ #include #include -#include #ifndef WLC_HIGH_ONLY #include #endif @@ -894,8 +893,8 @@ static wl_info_t *wl_attach(u16 vendor, u16 device, unsigned long regs, wl_release_fw(wl); #endif if (!wl->wlc) { - printf("%s: %s wlc_attach() failed with code %d\n", - KBUILD_MODNAME, EPI_VERSION_STR, err); + printf("%s: wlc_attach() failed with code %d\n", + KBUILD_MODNAME, err); goto fail; } wl->pub = wlc_pub(wl->wlc); @@ -962,10 +961,10 @@ static wl_info_t *wl_attach(u16 vendor, u16 device, unsigned long regs, } #ifndef WLC_HIGH_ONLY WL_ERROR(("wl%d: Broadcom BCM43xx 802.11 MAC80211 Driver " - EPI_VERSION_STR " (" PHY_VERSION_STR ")", unit)); + " (" PHY_VERSION_STR ")", unit)); #else - WL_ERROR(("wl%d: Broadcom BCM43xx 802.11 MAC80211 Driver " - EPI_VERSION_STR, unit)); + WL_ERROR(("wl%d: Broadcom BCM43xx 802.11 Splitmac MAC80211 Driver " + , unit)); #endif #ifdef BCMDBG diff --git a/drivers/staging/brcm80211/sys/wlc_mac80211.c b/drivers/staging/brcm80211/sys/wlc_mac80211.c index 01b8110afd1c..e7a4bcb1c65a 100644 --- a/drivers/staging/brcm80211/sys/wlc_mac80211.c +++ b/drivers/staging/brcm80211/sys/wlc_mac80211.c @@ -27,7 +27,6 @@ #include #include #include -#include #include #include #include @@ -136,6 +135,8 @@ uint wl_msg_level = #define SCAN_IN_PROGRESS(x) 0 +#define EPI_VERSION_NUM 0x054b0b00 + #ifdef BCMDBG /* pointer to most recently allocated wl/wlc */ static wlc_info_t *wlc_info_dbg = (wlc_info_t *) (NULL); -- cgit v1.2.3 From 8fb6b18884703d447af4c5ed1eeec02b489aa54b Mon Sep 17 00:00:00 2001 From: Brett Rudley Date: Mon, 1 Nov 2010 17:10:15 -0700 Subject: staging: brcm80211: Remove abstraction layer for dma alignment Directly align buffers instead of abstracting it. Signed-off-by: Brett Rudley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/include/linux_osl.h | 2 -- drivers/staging/brcm80211/util/linux_osl.c | 7 +------ 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/drivers/staging/brcm80211/include/linux_osl.h b/drivers/staging/brcm80211/include/linux_osl.h index b13ae7614042..e6d2f30c63ca 100644 --- a/drivers/staging/brcm80211/include/linux_osl.h +++ b/drivers/staging/brcm80211/include/linux_osl.h @@ -91,8 +91,6 @@ typedef struct { #define BUS_SWAP32(v) (v) -#define DMA_CONSISTENT_ALIGN osl_dma_consistent_align() -extern uint osl_dma_consistent_align(void); extern void *osl_dma_alloc_consistent(osl_t *osh, uint size, u16 align, uint *tot, unsigned long *pap); diff --git a/drivers/staging/brcm80211/util/linux_osl.c b/drivers/staging/brcm80211/util/linux_osl.c index effe043f1962..01851e56b157 100644 --- a/drivers/staging/brcm80211/util/linux_osl.c +++ b/drivers/staging/brcm80211/util/linux_osl.c @@ -285,11 +285,6 @@ uint osl_pci_slot(osl_t *osh) return PCI_SLOT(((struct pci_dev *)osh->pdev)->devfn); } -uint osl_dma_consistent_align(void) -{ - return PAGE_SIZE; -} - void *osl_dma_alloc_consistent(osl_t *osh, uint size, u16 align_bits, uint *alloced, unsigned long *pap) { @@ -297,7 +292,7 @@ void *osl_dma_alloc_consistent(osl_t *osh, uint size, u16 align_bits, if (align_bits) { u16 align = (1 << align_bits); - if (!IS_ALIGNED(DMA_CONSISTENT_ALIGN, align)) + if (!IS_ALIGNED(PAGE_SIZE, align)) size += align; *alloced = size; } -- cgit v1.2.3 From 683ab518a19fe55de9b9f682c94f672951315fe2 Mon Sep 17 00:00:00 2001 From: Brett Rudley Date: Mon, 1 Nov 2010 17:10:16 -0700 Subject: staging: brcm80211: Remove dead code from osl.h Signed-off-by: Brett Rudley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/include/linux_osl.h | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/drivers/staging/brcm80211/include/linux_osl.h b/drivers/staging/brcm80211/include/linux_osl.h index e6d2f30c63ca..62afbe88f793 100644 --- a/drivers/staging/brcm80211/include/linux_osl.h +++ b/drivers/staging/brcm80211/include/linux_osl.h @@ -18,12 +18,6 @@ #define _linux_osl_h_ -/* Linux Kernel: File Operations: start */ -extern void *osl_os_open_image(char *filename); -extern int osl_os_get_image_block(char *buf, int len, void *image); -extern void osl_os_close_image(void *image); -/* Linux Kernel: File Operations: end */ - extern osl_t *osl_attach(void *pdev, uint bustype, bool pkttag); extern void osl_detach(osl_t *osh); @@ -269,22 +263,6 @@ extern int osl_error(int bcmerror); #define OSL_CACHED(va) ((void *)va) #endif /* mips */ -#if defined(mips) -#define OSL_GETCYCLES(x) ((x) = read_c0_count() * 2) -#elif defined(__i386__) -#define OSL_GETCYCLES(x) rdtscl((x)) -#else -#define OSL_GETCYCLES(x) ((x) = 0) -#endif /* defined(mips) */ - -/* dereference an address that may cause a bus exception */ -#ifdef mips -#define BUSPROBE(val, addr) get_dbe((val), (addr)) -#include -#else -#define BUSPROBE(val, addr) ({ (val) = R_REG(NULL, (addr)); 0; }) -#endif /* mips */ - /* map/unmap physical to virtual I/O */ #if !defined(CONFIG_MMC_MSM7X00A) #define REG_MAP(pa, size) ioremap_nocache((unsigned long)(pa), (unsigned long)(size)) -- cgit v1.2.3 From 9014378bf42912533299d37f14677f9dfa21268a Mon Sep 17 00:00:00 2001 From: Brett Rudley Date: Mon, 1 Nov 2010 17:10:17 -0700 Subject: staging: brcm80211: Remove OSL_ERROR entry point Get rid of generic OSL_ERROR and error code translation to the only place that needs it: dhd. Signed-off-by: Brett Rudley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmfmac/dhd_linux.c | 52 +++++++++++++++++- drivers/staging/brcm80211/include/linux_osl.h | 3 -- drivers/staging/brcm80211/util/linux_osl.c | 73 -------------------------- 3 files changed, 51 insertions(+), 77 deletions(-) diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_linux.c b/drivers/staging/brcm80211/brcmfmac/dhd_linux.c index 797bff3be416..ba6fdc6133db 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_linux.c +++ b/drivers/staging/brcm80211/brcmfmac/dhd_linux.c @@ -1620,6 +1620,51 @@ static int dhd_ethtool(dhd_info_t *dhd, void *uaddr) return 0; } +static s16 linuxbcmerrormap[] = { 0, /* 0 */ + -EINVAL, /* BCME_ERROR */ + -EINVAL, /* BCME_BADARG */ + -EINVAL, /* BCME_BADOPTION */ + -EINVAL, /* BCME_NOTUP */ + -EINVAL, /* BCME_NOTDOWN */ + -EINVAL, /* BCME_NOTAP */ + -EINVAL, /* BCME_NOTSTA */ + -EINVAL, /* BCME_BADKEYIDX */ + -EINVAL, /* BCME_RADIOOFF */ + -EINVAL, /* BCME_NOTBANDLOCKED */ + -EINVAL, /* BCME_NOCLK */ + -EINVAL, /* BCME_BADRATESET */ + -EINVAL, /* BCME_BADBAND */ + -E2BIG, /* BCME_BUFTOOSHORT */ + -E2BIG, /* BCME_BUFTOOLONG */ + -EBUSY, /* BCME_BUSY */ + -EINVAL, /* BCME_NOTASSOCIATED */ + -EINVAL, /* BCME_BADSSIDLEN */ + -EINVAL, /* BCME_OUTOFRANGECHAN */ + -EINVAL, /* BCME_BADCHAN */ + -EFAULT, /* BCME_BADADDR */ + -ENOMEM, /* BCME_NORESOURCE */ + -EOPNOTSUPP, /* BCME_UNSUPPORTED */ + -EMSGSIZE, /* BCME_BADLENGTH */ + -EINVAL, /* BCME_NOTREADY */ + -EPERM, /* BCME_NOTPERMITTED */ + -ENOMEM, /* BCME_NOMEM */ + -EINVAL, /* BCME_ASSOCIATED */ + -ERANGE, /* BCME_RANGE */ + -EINVAL, /* BCME_NOTFOUND */ + -EINVAL, /* BCME_WME_NOT_ENABLED */ + -EINVAL, /* BCME_TSPEC_NOTFOUND */ + -EINVAL, /* BCME_ACM_NOTSUPPORTED */ + -EINVAL, /* BCME_NOT_WME_ASSOCIATION */ + -EIO, /* BCME_SDIO_ERROR */ + -ENODEV, /* BCME_DONGLE_DOWN */ + -EINVAL, /* BCME_VERSION */ + -EIO, /* BCME_TXFAIL */ + -EIO, /* BCME_RXFAIL */ + -EINVAL, /* BCME_NODEVICE */ + -EINVAL, /* BCME_NMODE_DISABLED */ + -ENODATA, /* BCME_NONRESIDENT */ +}; + static int dhd_ioctl_entry(struct net_device *net, struct ifreq *ifr, int cmd) { dhd_info_t *dhd = *(dhd_info_t **) netdev_priv(net); @@ -1741,7 +1786,12 @@ done: if (buf) kfree(buf); - return OSL_ERROR(bcmerror); + if (bcmerror > 0) + bcmerror = 0; + else if (bcmerror < BCME_LAST) + bcmerror = BCME_ERROR; + + return linuxbcmerrormap[-bcmerror]; } static int dhd_stop(struct net_device *net) diff --git a/drivers/staging/brcm80211/include/linux_osl.h b/drivers/staging/brcm80211/include/linux_osl.h index 62afbe88f793..c398f7908447 100644 --- a/drivers/staging/brcm80211/include/linux_osl.h +++ b/drivers/staging/brcm80211/include/linux_osl.h @@ -134,9 +134,6 @@ extern void osl_dma_unmap(osl_t *osh, uint pa, uint size, int direction); #define SELECT_BUS_READ(osh, mmap_op, bus_op) mmap_op #endif -#define OSL_ERROR(bcmerror) osl_error(bcmerror) -extern int osl_error(int bcmerror); - /* the largest reasonable packet buffer driver uses for ethernet MTU in bytes */ #define PKTBUFSZ 2048 /* largest reasonable packet buffer, driver uses for ethernet MTU */ diff --git a/drivers/staging/brcm80211/util/linux_osl.c b/drivers/staging/brcm80211/util/linux_osl.c index 01851e56b157..3255b31b88eb 100644 --- a/drivers/staging/brcm80211/util/linux_osl.c +++ b/drivers/staging/brcm80211/util/linux_osl.c @@ -46,74 +46,6 @@ struct osl_info { /* Global ASSERT type flag */ u32 g_assert_type; -#ifdef BRCM_FULLMAC -static s16 linuxbcmerrormap[] = { 0, /* 0 */ - -EINVAL, /* BCME_ERROR */ - -EINVAL, /* BCME_BADARG */ - -EINVAL, /* BCME_BADOPTION */ - -EINVAL, /* BCME_NOTUP */ - -EINVAL, /* BCME_NOTDOWN */ - -EINVAL, /* BCME_NOTAP */ - -EINVAL, /* BCME_NOTSTA */ - -EINVAL, /* BCME_BADKEYIDX */ - -EINVAL, /* BCME_RADIOOFF */ - -EINVAL, /* BCME_NOTBANDLOCKED */ - -EINVAL, /* BCME_NOCLK */ - -EINVAL, /* BCME_BADRATESET */ - -EINVAL, /* BCME_BADBAND */ - -E2BIG, /* BCME_BUFTOOSHORT */ - -E2BIG, /* BCME_BUFTOOLONG */ - -EBUSY, /* BCME_BUSY */ - -EINVAL, /* BCME_NOTASSOCIATED */ - -EINVAL, /* BCME_BADSSIDLEN */ - -EINVAL, /* BCME_OUTOFRANGECHAN */ - -EINVAL, /* BCME_BADCHAN */ - -EFAULT, /* BCME_BADADDR */ - -ENOMEM, /* BCME_NORESOURCE */ - -EOPNOTSUPP, /* BCME_UNSUPPORTED */ - -EMSGSIZE, /* BCME_BADLENGTH */ - -EINVAL, /* BCME_NOTREADY */ - -EPERM, /* BCME_NOTPERMITTED */ - -ENOMEM, /* BCME_NOMEM */ - -EINVAL, /* BCME_ASSOCIATED */ - -ERANGE, /* BCME_RANGE */ - -EINVAL, /* BCME_NOTFOUND */ - -EINVAL, /* BCME_WME_NOT_ENABLED */ - -EINVAL, /* BCME_TSPEC_NOTFOUND */ - -EINVAL, /* BCME_ACM_NOTSUPPORTED */ - -EINVAL, /* BCME_NOT_WME_ASSOCIATION */ - -EIO, /* BCME_SDIO_ERROR */ - -ENODEV, /* BCME_DONGLE_DOWN */ - -EINVAL, /* BCME_VERSION */ - -EIO, /* BCME_TXFAIL */ - -EIO, /* BCME_RXFAIL */ - -EINVAL, /* BCME_NODEVICE */ - -EINVAL, /* BCME_NMODE_DISABLED */ - -ENODATA, /* BCME_NONRESIDENT */ - -/* When an new error code is added to bcmutils.h, add os - * spcecific error translation here as well - */ -/* check if BCME_LAST changed since the last time this function was updated */ -#if BCME_LAST != -42 -#error "You need to add a OS error translation in the linuxbcmerrormap \ - for new error code defined in bcmutils.h" -#endif -}; - -/* translate bcmerrors into linux errors */ -int osl_error(int bcmerror) -{ - if (bcmerror > 0) - bcmerror = 0; - else if (bcmerror < BCME_LAST) - bcmerror = BCME_ERROR; - - /* Array bounds covered by ASSERT in osl_attach */ - return linuxbcmerrormap[-bcmerror]; -} -#endif /* BRCM_FULLMAC */ - osl_t *osl_attach(void *pdev, uint bustype, bool pkttag) { osl_t *osh; @@ -123,11 +55,6 @@ osl_t *osl_attach(void *pdev, uint bustype, bool pkttag) bzero(osh, sizeof(osl_t)); -#ifdef BRCM_FULLMAC - /* Check that error map has the right number of entries in it */ - ASSERT(ABS(BCME_LAST) == (ARRAY_SIZE(linuxbcmerrormap) - 1)); -#endif /* BRCM_FULLMAC */ - osh->magic = OS_HANDLE_MAGIC; osh->failed = 0; osh->pdev = pdev; -- cgit v1.2.3 From a28792e78669dc1bb984dd7798f0bccda741acbb Mon Sep 17 00:00:00 2001 From: Brett Rudley Date: Mon, 1 Nov 2010 17:10:18 -0700 Subject: staging: brcm80211: Remove cruft from wlioctl.h Signed-off-by: Brett Rudley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/include/wlioctl.h | 329 +--------------------------- 1 file changed, 6 insertions(+), 323 deletions(-) diff --git a/drivers/staging/brcm80211/include/wlioctl.h b/drivers/staging/brcm80211/include/wlioctl.h index 81863e0cab1e..45e02e5293eb 100644 --- a/drivers/staging/brcm80211/include/wlioctl.h +++ b/drivers/staging/brcm80211/include/wlioctl.h @@ -34,82 +34,8 @@ #include #ifdef BRCM_FULLMAC -/* Legacy structure to help keep backward compatible wl tool and tray app */ -#define LEGACY_WL_BSS_INFO_VERSION 107 /* older version of wl_bss_info struct */ - -typedef struct wl_bss_info_107 { - u32 version; /* version field */ - u32 length; /* byte length of data in this record, - * starting at version and including IEs - */ - struct ether_addr BSSID; - u16 beacon_period; /* units are Kusec */ - u16 capability; /* Capability information */ - u8 SSID_len; - u8 SSID[32]; - struct { - uint count; /* # rates in this set */ - u8 rates[16]; /* rates in 500kbps units w/hi bit set if basic */ - } rateset; /* supported rates */ - u8 channel; /* Channel no. */ - u16 atim_window; /* units are Kusec */ - u8 dtim_period; /* DTIM period */ - s16 RSSI; /* receive signal strength (in dBm) */ - s8 phy_noise; /* noise (in dBm) */ - u32 ie_length; /* byte length of Information Elements */ - /* variable length Information Elements */ -} wl_bss_info_107_t; - -/* - * Per-BSS information structure. - */ - -#define LEGACY2_WL_BSS_INFO_VERSION 108 /* old version of wl_bss_info struct */ - -/* BSS info structure - * Applications MUST CHECK ie_offset field and length field to access IEs and - * next bss_info structure in a vector (in wl_scan_results_t) - */ -typedef struct wl_bss_info_108 { - u32 version; /* version field */ - u32 length; /* byte length of data in this record, - * starting at version and including IEs - */ - struct ether_addr BSSID; - u16 beacon_period; /* units are Kusec */ - u16 capability; /* Capability information */ - u8 SSID_len; - u8 SSID[32]; - struct { - uint count; /* # rates in this set */ - u8 rates[16]; /* rates in 500kbps units w/hi bit set if basic */ - } rateset; /* supported rates */ - chanspec_t chanspec; /* chanspec for bss */ - u16 atim_window; /* units are Kusec */ - u8 dtim_period; /* DTIM period */ - s16 RSSI; /* receive signal strength (in dBm) */ - s8 phy_noise; /* noise (in dBm) */ - - u8 n_cap; /* BSS is 802.11N Capable */ - u32 nbss_cap; /* 802.11N BSS Capabilities (based on HT_CAP_*) */ - u8 ctl_ch; /* 802.11N BSS control channel number */ - u32 reserved32[1]; /* Reserved for expansion of BSS properties */ - u8 flags; /* flags */ - u8 reserved[3]; /* Reserved for expansion of BSS properties */ - u8 basic_mcs[MCSSET_LEN]; /* 802.11N BSS required MCS set */ - - u16 ie_offset; /* offset at which IEs start, from beginning */ - u32 ie_length; /* byte length of Information Elements */ - /* Add new fields here */ - /* variable length Information Elements */ -} wl_bss_info_108_t; - -#ifdef BRCM_FULLMAC #define WL_BSS_INFO_VERSION 108 /* current ver of wl_bss_info struct */ -#else -#define WL_BSS_INFO_VERSION 109 /* current ver of wl_bss_info struct */ -#endif /* BSS info structure * Applications MUST CHECK ie_offset field and length field to access IEs and @@ -633,27 +559,6 @@ typedef struct wl_led_info { u8 activehi; } wl_led_info_t; -/* flags */ -#define WLC_ASSOC_REQ_IS_REASSOC 0x01 /* assoc req was actually a reassoc */ - -/* srom read/write struct passed through ioctl */ -typedef struct { - uint byteoff; /* byte offset */ - uint nbytes; /* number of bytes */ - u16 buf[1]; -} srom_rw_t; - -/* similar cis (srom or otp) struct [iovar: may not be aligned] */ -typedef struct { - u32 source; /* cis source */ - u32 byteoff; /* byte offset */ - u32 nbytes; /* number of bytes */ - /* data follows here */ -} cis_rw_t; - -#define WLC_CIS_DEFAULT 0 /* built-in default */ -#define WLC_CIS_SROM 1 /* source is sprom */ -#define WLC_CIS_OTP 2 /* source is otp */ /* R_REG and W_REG struct passed through ioctl */ typedef struct { @@ -663,102 +568,14 @@ typedef struct { uint band; /* band (optional) */ } rw_reg_t; -/* Structure used by GET/SET_ATTEN ioctls - it controls power in b/g-band */ -/* PCL - Power Control Loop */ -/* current gain setting is replaced by user input */ -#define WL_ATTEN_APP_INPUT_PCL_OFF 0 /* turn off PCL, apply supplied input */ -#define WL_ATTEN_PCL_ON 1 /* turn on PCL */ -/* current gain setting is maintained */ -#define WL_ATTEN_PCL_OFF 2 /* turn off PCL. */ - -typedef struct { - u16 auto_ctrl; /* WL_ATTEN_XX */ - u16 bb; /* Baseband attenuation */ - u16 radio; /* Radio attenuation */ - u16 txctl1; /* Radio TX_CTL1 value */ -} atten_t; - -/* Per-AC retry parameters */ -struct wme_tx_params_s { - u8 short_retry; - u8 short_fallback; - u8 long_retry; - u8 long_fallback; - u16 max_rate; /* In units of 512 Kbps */ -}; - -typedef struct wme_tx_params_s wme_tx_params_t; - -#define WL_WME_TX_PARAMS_IO_BYTES (sizeof(wme_tx_params_t) * AC_COUNT) - -/* defines used by poweridx iovar - it controls power in a-band */ -/* current gain setting is maintained */ -#define WL_PWRIDX_PCL_OFF -2 /* turn off PCL. */ -#define WL_PWRIDX_PCL_ON -1 /* turn on PCL */ -#define WL_PWRIDX_LOWER_LIMIT -2 /* lower limit */ -#define WL_PWRIDX_UPPER_LIMIT 63 /* upper limit */ -/* value >= 0 causes - * - input to be set to that value - * - PCL to be off - */ - -/* Used to get specific link/ac parameters */ -typedef struct { - int ac; - u8 val; - struct ether_addr ea; -} link_val_t; - -#define BCM_MAC_STATUS_INDICATION (0x40010200L) - -typedef struct { - u16 ver; /* version of this struct */ - u16 len; /* length in bytes of this structure */ - u16 cap; /* sta's advertised capabilities */ - u32 flags; /* flags defined below */ - u32 idle; /* time since data pkt rx'd from sta */ - struct ether_addr ea; /* Station address */ - wl_rateset_t rateset; /* rateset in use */ - u32 in; /* seconds elapsed since associated */ - u32 listen_interval_inms; /* Min Listen interval in ms for this STA */ - u32 tx_pkts; /* # of packets transmitted */ - u32 tx_failures; /* # of packets failed */ - u32 rx_ucast_pkts; /* # of unicast packets received */ - u32 rx_mcast_pkts; /* # of multicast packets received */ - u32 tx_rate; /* Rate of last successful tx frame */ - u32 rx_rate; /* Rate of last successful rx frame */ - u32 rx_decrypt_succeeds; /* # of packet decrypted successfully */ - u32 rx_decrypt_failures; /* # of packet decrypted unsuccessfully */ -} sta_info_t; - -#define WL_OLD_STAINFO_SIZE offsetof(sta_info_t, tx_pkts) - -#define WL_STA_VER 3 - -/* Flags for sta_info_t indicating properties of STA */ -#define WL_STA_BRCM 0x1 /* Running a Broadcom driver */ -#define WL_STA_WME 0x2 /* WMM association */ -#define WL_STA_ABCAP 0x4 -#define WL_STA_AUTHE 0x8 /* Authenticated */ -#define WL_STA_ASSOC 0x10 /* Associated */ -#define WL_STA_AUTHO 0x20 /* Authorized */ -#define WL_STA_WDS 0x40 /* Wireless Distribution System */ -#define WL_STA_WDS_LINKUP 0x80 /* WDS traffic/probes flowing properly */ -#define WL_STA_PS 0x100 /* STA is in power save mode from AP's viewpoint */ -#define WL_STA_APSD_BE 0x200 /* APSD delv/trigger for AC_BE is default enabled */ -#define WL_STA_APSD_BK 0x400 /* APSD delv/trigger for AC_BK is default enabled */ -#define WL_STA_APSD_VI 0x800 /* APSD delv/trigger for AC_VI is default enabled */ -#define WL_STA_APSD_VO 0x1000 /* APSD delv/trigger for AC_VO is default enabled */ -#define WL_STA_N_CAP 0x2000 /* STA 802.11n capable */ -#define WL_STA_SCBSTATS 0x4000 /* Per STA debug stats */ - -#define WL_WDS_LINKUP WL_STA_WDS_LINKUP /* deprecated */ +#ifdef BRCM_FULLMAC /* Used to get specific STA parameters */ typedef struct { u32 val; struct ether_addr ea; } scb_val_t; +#endif /* BRCM_FULLMAC */ /* channel encoding */ typedef struct channel_info { @@ -782,6 +599,7 @@ typedef struct get_pktcnt { uint rx_ocast_good_pkt; /* unicast packets destined for others */ } get_pktcnt_t; +#ifdef BRCM_FULLMAC /* Linux network driver ioctl encoding */ typedef struct wl_ioctl { uint cmd; /* common ioctl definition */ @@ -791,11 +609,8 @@ typedef struct wl_ioctl { uint used; /* bytes read or written (optional) */ uint needed; /* bytes needed (optional) */ } wl_ioctl_t; +#endif /* BRCM_FULLMAC */ -/* reference to wl_ioctl_t struct used by usermode driver */ -#define ioctl_subtype set /* subtype param */ -#define ioctl_pid used /* pid param */ -#define ioctl_status needed /* status param */ /* * Structure for passing hardware and software @@ -822,45 +637,11 @@ typedef struct wlc_rev_info { #define WL_REV_INFO_LEGACY_LENGTH 48 -#define WL_BRAND_MAX 10 -typedef struct wl_instance_info { - uint instance; - char brand[WL_BRAND_MAX]; -} wl_instance_info_t; - -/* structure to change size of tx fifo */ -typedef struct wl_txfifo_sz { - u16 magic; - u16 fifo; - u16 size; -} wl_txfifo_sz_t; -/* magic pattern used for mismatch driver and wl */ -#define WL_TXFIFO_SZ_MAGIC 0xa5a5 - -/* Transfer info about an IOVar from the driver */ -/* Max supported IOV name size in bytes, + 1 for nul termination */ -#define WLC_IOV_NAME_LEN 30 -typedef struct wlc_iov_trx_s { - u8 module; - u8 type; - char name[WLC_IOV_NAME_LEN]; -} wlc_iov_trx_t; - -/* check this magic number */ -#define WLC_IOCTL_MAGIC 0x14e46c77 - -#define PROC_ENTRY_NAME "brcm_debug" -/* bump this number if you change the ioctl interface */ -#define WLC_IOCTL_VERSION 1 - #ifdef BRCM_FULLMAC -#define WLC_IOCTL_MAXLEN 8192 -#else -#define WLC_IOCTL_MAXLEN 3072 /* max length ioctl buffer required */ -#endif #define WLC_IOCTL_SMLEN 256 /* "small" length ioctl buffer required */ #define WLC_IOCTL_MEDLEN 1536 /* "med" length ioctl buffer required */ -#define WLC_SAMPLECOLLECT_MAXLEN 10240 /* Max Sample Collect buffer for two cores */ +#define WLC_IOCTL_MAXLEN 8192 +#endif /* common ioctl definitions */ #define WLC_GET_MAGIC 0 @@ -1411,23 +1192,6 @@ typedef struct { #define WL_TX_POWER_MCS40_FIRST 28 #define WL_TX_POWER_MCS40_NUM 17 -typedef struct { - u32 flags; - chanspec_t chanspec; /* txpwr report for this channel */ - chanspec_t local_chanspec; /* channel on which we are associated */ - u8 local_max; /* local max according to the AP */ - u8 local_constraint; /* local constraint according to the AP */ - s8 antgain[2]; /* Ant gain for each band - from SROM */ - u8 rf_cores; /* count of RF Cores being reported */ - u8 est_Pout[4]; /* Latest tx power out estimate per RF - * chain without adjustment - */ - u8 est_Pout_cck; /* Latest CCK tx power out estimate */ - u8 user_limit[WL_TX_POWER_RATES_LEGACY]; /* User limit */ - u8 reg_limit[WL_TX_POWER_RATES_LEGACY]; /* Regulatory power limit */ - u8 board_limit[WL_TX_POWER_RATES_LEGACY]; /* Max power board can support (SROM) */ - u8 target[WL_TX_POWER_RATES_LEGACY]; /* Latest target power */ -} tx_power_legacy2_t; #define WL_TX_POWER_RATES 101 #define WL_TX_POWER_CCK_FIRST 0 @@ -1860,63 +1624,6 @@ struct ampdu_retry_tid { u8 retry; /* retry value */ }; -/* structure for addts arguments */ -/* For ioctls that take a list of TSPEC */ -struct tslist { - int count; /* number of tspecs */ - struct tsinfo_arg tsinfo[1]; /* variable length array of tsinfo */ -}; - -/* structure for addts/delts arguments */ -typedef struct tspec_arg { - u16 version; /* see definition of TSPEC_ARG_VERSION */ - u16 length; /* length of entire structure */ - uint flag; /* bit field */ - /* TSPEC Arguments */ - struct tsinfo_arg tsinfo; /* TS Info bit field */ - u16 nom_msdu_size; /* (Nominal or fixed) MSDU Size (bytes) */ - u16 max_msdu_size; /* Maximum MSDU Size (bytes) */ - uint min_srv_interval; /* Minimum Service Interval (us) */ - uint max_srv_interval; /* Maximum Service Interval (us) */ - uint inactivity_interval; /* Inactivity Interval (us) */ - uint suspension_interval; /* Suspension Interval (us) */ - uint srv_start_time; /* Service Start Time (us) */ - uint min_data_rate; /* Minimum Data Rate (bps) */ - uint mean_data_rate; /* Mean Data Rate (bps) */ - uint peak_data_rate; /* Peak Data Rate (bps) */ - uint max_burst_size; /* Maximum Burst Size (bytes) */ - uint delay_bound; /* Delay Bound (us) */ - uint min_phy_rate; /* Minimum PHY Rate (bps) */ - u16 surplus_bw; /* Surplus Bandwidth Allowance (range 1.0 to 8.0) */ - u16 medium_time; /* Medium Time (32 us/s periods) */ - u8 dialog_token; /* dialog token */ -} tspec_arg_t; - -/* tspec arg for desired station */ -typedef struct tspec_per_sta_arg { - struct ether_addr ea; - struct tspec_arg ts; -} tspec_per_sta_arg_t; - -/* structure for max bandwidth for each access category */ -typedef struct wme_max_bandwidth { - u32 ac[AC_COUNT]; /* max bandwidth for each access category */ -} wme_max_bandwidth_t; - -#define WL_WME_MBW_PARAMS_IO_BYTES (sizeof(wme_max_bandwidth_t)) - -/* current version of wl_tspec_arg_t struct */ -#define TSPEC_ARG_VERSION 2 /* current version of wl_tspec_arg_t struct */ -#define TSPEC_ARG_LENGTH 55 /* argument length from tsinfo to medium_time */ -#define TSPEC_DEFAULT_DIALOG_TOKEN 42 /* default dialog token */ -#define TSPEC_DEFAULT_SBW_FACTOR 0x3000 /* default surplus bw */ - -/* define for flag */ -#define TSPEC_PENDING 0 /* TSPEC pending */ -#define TSPEC_ACCEPTED 1 /* TSPEC accepted */ -#define TSPEC_REJECTED 2 /* TSPEC rejected */ -#define TSPEC_UNKNOWN 3 /* TSPEC unknown */ -#define TSPEC_STATUS_MASK 7 /* TSPEC status mask */ /* Software feature flag defines used by wlfeatureflag */ #define WL_SWFL_NOHWRADIO 0x0004 @@ -1925,16 +1632,6 @@ typedef struct wme_max_bandwidth { #define WL_LIFETIME_MAX 0xFFFF /* Max value in ms */ -/* - * Dongle pattern matching filter. - */ - -/* Packet filter types. Currently, only pattern matching is supported. */ -typedef enum wl_pkt_filter_type { - WL_PKT_FILTER_TYPE_PATTERN_MATCH /* Pattern matching filter */ -} wl_pkt_filter_type_t; - -#define WL_PKT_FILTER_TYPE wl_pkt_filter_type_t /* Pattern matching filter. Specifies an offset within received packets to * start matching, the pattern to match, the size of the pattern, and a bitmask @@ -1969,20 +1666,6 @@ typedef struct wl_pkt_filter_enable { u32 enable; /* Enable/disable bool */ } wl_pkt_filter_enable_t; -/* IOVAR "pkt_filter_list" parameter. Used to retrieve a list of installed filters. */ -typedef struct wl_pkt_filter_list { - u32 num; /* Number of installed packet filters */ - wl_pkt_filter_t filter[1]; /* Variable array of packet filters. */ -} wl_pkt_filter_list_t; - -#define WL_PKT_FILTER_LIST_FIXED_LEN offsetof(wl_pkt_filter_list_t, filter) - -/* IOVAR "pkt_filter_stats" parameter. Used to retrieve debug statistics. */ -typedef struct wl_pkt_filter_stats { - u32 num_pkts_matched; /* # filter matches for specified filter id */ - u32 num_pkts_forwarded; /* # packets fwded from dongle to host for all filters */ - u32 num_pkts_discarded; /* # packets discarded by dongle for all filters */ -} wl_pkt_filter_stats_t; #define WLC_RSSI_INVALID 0 /* invalid RSSI value */ -- cgit v1.2.3 From 2578f7edf895fd4aad278134452cde1dc1b2fef5 Mon Sep 17 00:00:00 2001 From: Nicolas Kaiser Date: Sat, 30 Oct 2010 00:10:29 +0200 Subject: Staging: brcm80211: simplify expression Simplify: ((a && b) || !a) => (b || !a) Signed-off-by: Nicolas Kaiser Cc: Brett Rudley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/sys/wlc_mac80211.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/brcm80211/sys/wlc_mac80211.c b/drivers/staging/brcm80211/sys/wlc_mac80211.c index e7a4bcb1c65a..f3e8e3c24276 100644 --- a/drivers/staging/brcm80211/sys/wlc_mac80211.c +++ b/drivers/staging/brcm80211/sys/wlc_mac80211.c @@ -669,7 +669,7 @@ bool wlc_ps_check(wlc_info_t *wlc) * may be either true or false due to the low level override. */ wake = STAY_AWAKE(wlc); - wake_ok = (wake && ((tmp & MCTL_WAKE) != 0)) || !wake; + wake_ok = ((tmp & MCTL_WAKE) != 0) || !wake; #endif if (hps && !wake_ok) { WL_ERROR(("wl%d: wake not sync, sw %d maccontrol 0x%x\n", wlc->pub->unit, wake, tmp)); -- cgit v1.2.3 From df0d8bb8daa1e8c3c2afcf93c46ef0294c78ac26 Mon Sep 17 00:00:00 2001 From: Brett Rudley Date: Wed, 3 Nov 2010 19:53:58 -0700 Subject: staging: brcm80211: Remove 'failed' field from osh Signed-off-by: Brett Rudley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/util/linux_osl.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/staging/brcm80211/util/linux_osl.c b/drivers/staging/brcm80211/util/linux_osl.c index 3255b31b88eb..d6cca69814cf 100644 --- a/drivers/staging/brcm80211/util/linux_osl.c +++ b/drivers/staging/brcm80211/util/linux_osl.c @@ -39,7 +39,6 @@ struct osl_info { osl_pubinfo_t pub; uint magic; void *pdev; - uint failed; uint bustype; }; @@ -56,7 +55,6 @@ osl_t *osl_attach(void *pdev, uint bustype, bool pkttag) bzero(osh, sizeof(osl_t)); osh->magic = OS_HANDLE_MAGIC; - osh->failed = 0; osh->pdev = pdev; osh->pub.pkttag = pkttag; osh->bustype = bustype; -- cgit v1.2.3 From 997dd24fe9aadf6e0b3652580e7c79372ccb600c Mon Sep 17 00:00:00 2001 From: Brett Rudley Date: Wed, 3 Nov 2010 19:53:59 -0700 Subject: staging: brcm80211: Remove pkttag from osl Signed-off-by: Brett Rudley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmfmac/bcmsdh_linux.c | 6 +++--- drivers/staging/brcm80211/brcmfmac/dhd_linux.c | 2 +- drivers/staging/brcm80211/include/linux_osl.h | 10 +--------- drivers/staging/brcm80211/include/osl.h | 2 -- drivers/staging/brcm80211/sys/wl_mac80211.c | 3 +-- drivers/staging/brcm80211/sys/wlc_pub.h | 4 ---- drivers/staging/brcm80211/util/linux_osl.c | 10 +--------- 7 files changed, 7 insertions(+), 30 deletions(-) diff --git a/drivers/staging/brcm80211/brcmfmac/bcmsdh_linux.c b/drivers/staging/brcm80211/brcmfmac/bcmsdh_linux.c index 59eaf71040b2..be33696b8f74 100644 --- a/drivers/staging/brcm80211/brcmfmac/bcmsdh_linux.c +++ b/drivers/staging/brcm80211/brcmfmac/bcmsdh_linux.c @@ -188,7 +188,7 @@ int bcmsdh_probe(struct device *dev) } #endif /* defined(OOB_INTR_ONLY) */ /* allocate SDIO Host Controller state info */ - osh = osl_attach(dev, PCI_BUS, false); + osh = osl_attach(dev, PCI_BUS); if (!osh) { SDLX_MSG(("%s: osl_attach failed\n", __func__)); goto err; @@ -384,7 +384,7 @@ bcmsdh_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) SDLX_MSG(("%s: Disabling TI FlashMedia Controller.\n", __func__)); - osh = osl_attach(pdev, PCI_BUS, false); + osh = osl_attach(pdev, PCI_BUS); if (!osh) { SDLX_MSG(("%s: osl_attach failed\n", __func__)); goto err; @@ -419,7 +419,7 @@ bcmsdh_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) */ /* allocate SDIO Host Controller state info */ - osh = osl_attach(pdev, PCI_BUS, false); + osh = osl_attach(pdev, PCI_BUS); if (!osh) { SDLX_MSG(("%s: osl_attach failed\n", __func__)); goto err; diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_linux.c b/drivers/staging/brcm80211/brcmfmac/dhd_linux.c index ba6fdc6133db..794dc13cf1a5 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_linux.c +++ b/drivers/staging/brcm80211/brcmfmac/dhd_linux.c @@ -1865,7 +1865,7 @@ static int dhd_open(struct net_device *net) osl_t *dhd_osl_attach(void *pdev, uint bustype) { - return osl_attach(pdev, bustype, true); + return osl_attach(pdev, bustype); } void dhd_osl_detach(osl_t *osh) diff --git a/drivers/staging/brcm80211/include/linux_osl.h b/drivers/staging/brcm80211/include/linux_osl.h index c398f7908447..586e652e75c7 100644 --- a/drivers/staging/brcm80211/include/linux_osl.h +++ b/drivers/staging/brcm80211/include/linux_osl.h @@ -18,7 +18,7 @@ #define _linux_osl_h_ -extern osl_t *osl_attach(void *pdev, uint bustype, bool pkttag); +extern osl_t *osl_attach(void *pdev, uint bustype); extern void osl_detach(osl_t *osh); extern u32 g_assert_type; @@ -56,7 +56,6 @@ extern uint osl_pci_slot(osl_t *osh); /* Pkttag flag should be part of public information */ typedef struct { - bool pkttag; uint pktalloced; /* Number of allocated packet buffers */ bool mmbus; /* Bus supports memory-mapped register accesses */ pktfree_cb_fn_t tx_fn; /* Callback function for PKTFREE */ @@ -285,7 +284,6 @@ extern void osl_dma_unmap(osl_t *osh, uint pa, uint size, int direction); #define PKTSETLEN(skb, len) __skb_trim((struct sk_buff *)(skb), (len)) #define PKTPUSH(skb, bytes) skb_push((struct sk_buff *)(skb), (bytes)) #define PKTPULL(skb, bytes) skb_pull((struct sk_buff *)(skb), (bytes)) -#define PKTTAG(skb) ((void *)(((struct sk_buff *)(skb))->cb)) #define PKTALLOCED(osh) (((osl_pubinfo_t *)(osh))->pktalloced) #define PKTSETPOOL(osh, skb, x, y) do {} while (0) #define PKTPOOL(osh, skb) false @@ -301,9 +299,6 @@ osl_pkt_frmnative(osl_pubinfo_t *osh, struct sk_buff *skb) { struct sk_buff *nskb; - if (osh->pkttag) - bzero((void *)skb->cb, OSL_PKTTAG_SZ); - for (nskb = skb; nskb; nskb = nskb->next) osh->pktalloced++; @@ -317,9 +312,6 @@ osl_pkt_tonative(osl_pubinfo_t *osh, void *pkt) { struct sk_buff *nskb; - if (osh->pkttag) - bzero(((struct sk_buff *)pkt)->cb, OSL_PKTTAG_SZ); - for (nskb = (struct sk_buff *)pkt; nskb; nskb = nskb->next) osh->pktalloced--; diff --git a/drivers/staging/brcm80211/include/osl.h b/drivers/staging/brcm80211/include/osl.h index c0ebb3d97220..bcb56aa5dc96 100644 --- a/drivers/staging/brcm80211/include/osl.h +++ b/drivers/staging/brcm80211/include/osl.h @@ -21,8 +21,6 @@ typedef struct osl_info osl_t; typedef struct osl_dmainfo osldma_t; -#define OSL_PKTTAG_SZ 32 /* Size of PktTag */ - /* Drivers use PKTFREESETCB to register a callback function when a packet is freed by OSL */ typedef void (*pktfree_cb_fn_t) (void *ctx, void *pkt, unsigned int status); diff --git a/drivers/staging/brcm80211/sys/wl_mac80211.c b/drivers/staging/brcm80211/sys/wl_mac80211.c index d951d330a1c8..cb5dba95fc86 100644 --- a/drivers/staging/brcm80211/sys/wl_mac80211.c +++ b/drivers/staging/brcm80211/sys/wl_mac80211.c @@ -789,8 +789,7 @@ static wl_info_t *wl_attach(u16 vendor, u16 device, unsigned long regs, return NULL; } - /* Requires pkttag feature */ - osh = osl_attach(btparam, bustype, true); + osh = osl_attach(btparam, bustype); ASSERT(osh); #ifdef WLC_HIGH_ONLY diff --git a/drivers/staging/brcm80211/sys/wlc_pub.h b/drivers/staging/brcm80211/sys/wlc_pub.h index a392436c4d45..f6ac5e99cf31 100644 --- a/drivers/staging/brcm80211/sys/wlc_pub.h +++ b/drivers/staging/brcm80211/sys/wlc_pub.h @@ -441,10 +441,6 @@ struct wlc_if; #define PROMISC_ENAB(wlc) ((wlc)->promisc) -extern void wlc_pkttag_info_move(wlc_pub_t *pub, void *pkt_from, void *pkt_to); - -#define WLPKTTAGSCB(p) (WLPKTTAG(p)->_scb) - #define WLC_PREC_COUNT 16 /* Max precedence level implemented */ /* pri is PKTPRIO encoded in the packet. This maps the Packet priority to diff --git a/drivers/staging/brcm80211/util/linux_osl.c b/drivers/staging/brcm80211/util/linux_osl.c index d6cca69814cf..7211f8a383ff 100644 --- a/drivers/staging/brcm80211/util/linux_osl.c +++ b/drivers/staging/brcm80211/util/linux_osl.c @@ -45,7 +45,7 @@ struct osl_info { /* Global ASSERT type flag */ u32 g_assert_type; -osl_t *osl_attach(void *pdev, uint bustype, bool pkttag) +osl_t *osl_attach(void *pdev, uint bustype) { osl_t *osh; @@ -56,7 +56,6 @@ osl_t *osl_attach(void *pdev, uint bustype, bool pkttag) osh->magic = OS_HANDLE_MAGIC; osh->pdev = pdev; - osh->pub.pkttag = pkttag; osh->bustype = bustype; switch (bustype) { @@ -77,12 +76,6 @@ osl_t *osl_attach(void *pdev, uint bustype, bool pkttag) break; } -#if defined(BCMDBG) && !defined(BRCM_FULLMAC) - if (pkttag) { - struct sk_buff *skb; - ASSERT(OSL_PKTTAG_SZ <= sizeof(skb->cb)); - } -#endif return osh; } @@ -95,7 +88,6 @@ void osl_detach(osl_t *osh) kfree(osh); } -/* Return a new packet. zero out pkttag */ void *BCMFASTPATH osl_pktget(osl_t *osh, uint len) { struct sk_buff *skb; -- cgit v1.2.3 From 69ec303a99ff68cfb5dbc6cefb043e53b6ba8945 Mon Sep 17 00:00:00 2001 From: Brett Rudley Date: Fri, 5 Nov 2010 19:20:16 -0700 Subject: staging: brcm80211: migrate #includes from headers into .c files. Signed-off-by: Brett Rudley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/sys/wlc_alloc.c | 2 ++ drivers/staging/brcm80211/sys/wlc_ampdu.c | 2 ++ drivers/staging/brcm80211/sys/wlc_antsel.c | 1 + drivers/staging/brcm80211/sys/wlc_bmac.c | 2 ++ drivers/staging/brcm80211/sys/wlc_channel.c | 2 ++ drivers/staging/brcm80211/sys/wlc_event.c | 1 + drivers/staging/brcm80211/sys/wlc_mac80211.c | 2 ++ drivers/staging/brcm80211/sys/wlc_mac80211.h | 6 ------ drivers/staging/brcm80211/sys/wlc_phy_shim.c | 2 ++ drivers/staging/brcm80211/sys/wlc_stf.c | 2 ++ 10 files changed, 16 insertions(+), 6 deletions(-) diff --git a/drivers/staging/brcm80211/sys/wlc_alloc.c b/drivers/staging/brcm80211/sys/wlc_alloc.c index 8240d4ba962e..8001dca44918 100644 --- a/drivers/staging/brcm80211/sys/wlc_alloc.c +++ b/drivers/staging/brcm80211/sys/wlc_alloc.c @@ -27,8 +27,10 @@ #include #include #include +#include #include #include +#include static wlc_pub_t *wlc_pub_malloc(osl_t *osh, uint unit, uint *err, uint devid); diff --git a/drivers/staging/brcm80211/sys/wlc_ampdu.c b/drivers/staging/brcm80211/sys/wlc_ampdu.c index 5a3acf852efa..0bd7069dc331 100644 --- a/drivers/staging/brcm80211/sys/wlc_ampdu.c +++ b/drivers/staging/brcm80211/sys/wlc_ampdu.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -35,6 +36,7 @@ #include #include #include +#include #ifdef WLC_HIGH_ONLY #include diff --git a/drivers/staging/brcm80211/sys/wlc_antsel.c b/drivers/staging/brcm80211/sys/wlc_antsel.c index 3a1c1e9e7131..ecc35de77004 100644 --- a/drivers/staging/brcm80211/sys/wlc_antsel.c +++ b/drivers/staging/brcm80211/sys/wlc_antsel.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/staging/brcm80211/sys/wlc_bmac.c b/drivers/staging/brcm80211/sys/wlc_bmac.c index a92a68fb4604..fc5201d5171a 100644 --- a/drivers/staging/brcm80211/sys/wlc_bmac.c +++ b/drivers/staging/brcm80211/sys/wlc_bmac.c @@ -51,6 +51,7 @@ * At some point we may be able to skip the include of wlc.h and instead just * define a stub wlc_info and band struct to allow rpc calls to get the rpc handle. */ +#include #include #include #include @@ -72,6 +73,7 @@ #include #include +#include #define TIMER_INTERVAL_WATCHDOG_BMAC 1000 /* watchdog timer, in unit of ms */ diff --git a/drivers/staging/brcm80211/sys/wlc_channel.c b/drivers/staging/brcm80211/sys/wlc_channel.c index c7f416188093..2fcdbc72c837 100644 --- a/drivers/staging/brcm80211/sys/wlc_channel.c +++ b/drivers/staging/brcm80211/sys/wlc_channel.c @@ -28,10 +28,12 @@ #include #include #include +#include #include #include #include #include +#include typedef struct wlc_cm_band { u8 locale_flags; /* locale_info_t flags */ diff --git a/drivers/staging/brcm80211/sys/wlc_event.c b/drivers/staging/brcm80211/sys/wlc_event.c index 4b0a59896bec..e4ab077bf87f 100644 --- a/drivers/staging/brcm80211/sys/wlc_event.c +++ b/drivers/staging/brcm80211/sys/wlc_event.c @@ -36,6 +36,7 @@ #ifdef MSGTRACE #include #endif +#include /* Local prototypes */ static void wlc_timer_cb(void *arg); diff --git a/drivers/staging/brcm80211/sys/wlc_mac80211.c b/drivers/staging/brcm80211/sys/wlc_mac80211.c index f3e8e3c24276..a9fa48a14c5d 100644 --- a/drivers/staging/brcm80211/sys/wlc_mac80211.c +++ b/drivers/staging/brcm80211/sys/wlc_mac80211.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include @@ -61,6 +62,7 @@ #endif /* WLC_HIGH_ONLY */ #include #include +#include #ifdef WLC_HIGH_ONLY #undef R_REG diff --git a/drivers/staging/brcm80211/sys/wlc_mac80211.h b/drivers/staging/brcm80211/sys/wlc_mac80211.h index 6a77591234b7..a3c6fb884990 100644 --- a/drivers/staging/brcm80211/sys/wlc_mac80211.h +++ b/drivers/staging/brcm80211/sys/wlc_mac80211.h @@ -17,19 +17,13 @@ #ifndef _wlc_h_ #define _wlc_h_ -#include - -#include #include -#include #include #include #ifdef WLC_SPLIT #include #endif - #include - #include #define MA_WINDOW_SZ 8 /* moving average window size */ diff --git a/drivers/staging/brcm80211/sys/wlc_phy_shim.c b/drivers/staging/brcm80211/sys/wlc_phy_shim.c index 900c505ced34..201ecdb319cd 100644 --- a/drivers/staging/brcm80211/sys/wlc_phy_shim.c +++ b/drivers/staging/brcm80211/sys/wlc_phy_shim.c @@ -47,6 +47,7 @@ #include #include #include +#include #include @@ -54,6 +55,7 @@ #include #include #include +#include /* PHY SHIM module specific state */ struct wlc_phy_shim_info { diff --git a/drivers/staging/brcm80211/sys/wlc_stf.c b/drivers/staging/brcm80211/sys/wlc_stf.c index 7bf326fc015b..2bca0526b44c 100644 --- a/drivers/staging/brcm80211/sys/wlc_stf.c +++ b/drivers/staging/brcm80211/sys/wlc_stf.c @@ -33,11 +33,13 @@ #include #include #include +#include #include #include #include #include #include +#include #define WLC_STF_SS_STBC_RX(wlc) (WLCISNPHY(wlc->band) && \ NREV_GT(wlc->band->phyrev, 3) && NREV_LE(wlc->band->phyrev, 6)) -- cgit v1.2.3 From d4fcdc68564f49cbb4fdaf9b0ebfb5c3d02c81d3 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Sun, 7 Nov 2010 17:20:37 +0000 Subject: Staging: brcmfmac: Fix MAC header lookup on 64-bit architectures Fix direct use of sk_buff::mac_header which is an offset rather than a pointer on 64-bit architectures. Signed-off-by: Ben Hutchings Cc: Brett Rudley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmfmac/dhd_linux.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_linux.c b/drivers/staging/brcm80211/brcmfmac/dhd_linux.c index 794dc13cf1a5..d7ad3e44dd78 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_linux.c +++ b/drivers/staging/brcm80211/brcmfmac/dhd_linux.c @@ -1189,7 +1189,7 @@ void dhd_rx_frame(dhd_pub_t *dhdp, int ifidx, void *pktbuf, int numpkt) /* Process special event packets and then discard them */ if (ntoh16(skb->protocol) == ETHER_TYPE_BRCM) dhd_wl_host_event(dhd, &ifidx, - skb->mac_header, + skb_mac_header(skb), &event, &data); ASSERT(ifidx < DHD_MAX_IFS && dhd->iflist[ifidx]); -- cgit v1.2.3 From 3b785a8cfc6ac1bc837b0a1424056b6a4a1e544e Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Tue, 9 Nov 2010 00:10:02 +0100 Subject: Staging: brcm80211: Remove unnecessary casts of void ptr returning alloc function return values The [vk][cmz]alloc(_node) family of functions return void pointers which it's completely unnecessary/pointless to cast to other pointer types since that happens implicitly. This patch removes such casts from drivers/staging/brcm80211/ Signed-off-by: Jesper Juhl Cc: Brett Rudley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c | 23 +++++++++++------------ drivers/staging/brcm80211/brcmfmac/wl_iw.c | 7 ++----- 2 files changed, 13 insertions(+), 17 deletions(-) diff --git a/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c index 21fe38fa736e..6433a9241b4e 100644 --- a/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c +++ b/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c @@ -704,7 +704,7 @@ wl_run_iscan(struct wl_iscan_ctrl *iscan, struct wlc_ssid *ssid, u16 action) if (ssid && ssid->SSID_len) params_size += sizeof(struct wlc_ssid); - params = (struct wl_iscan_params *)kzalloc(params_size, GFP_KERNEL); + params = kzalloc(params_size, GFP_KERNEL); if (unlikely(!params)) return -ENOMEM; memset(params, 0, params_size); @@ -2793,53 +2793,52 @@ static void wl_init_eloop_handler(struct wl_event_loop *el) static s32 wl_init_priv_mem(struct wl_priv *wl) { - wl->scan_results = (void *)kzalloc(WL_SCAN_BUF_MAX, GFP_KERNEL); + wl->scan_results = kzalloc(WL_SCAN_BUF_MAX, GFP_KERNEL); if (unlikely(!wl->scan_results)) { WL_ERR(("Scan results alloc failed\n")); goto init_priv_mem_out; } - wl->conf = (void *)kzalloc(sizeof(*wl->conf), GFP_KERNEL); + wl->conf = kzalloc(sizeof(*wl->conf), GFP_KERNEL); if (unlikely(!wl->conf)) { WL_ERR(("wl_conf alloc failed\n")); goto init_priv_mem_out; } - wl->profile = (void *)kzalloc(sizeof(*wl->profile), GFP_KERNEL); + wl->profile = kzalloc(sizeof(*wl->profile), GFP_KERNEL); if (unlikely(!wl->profile)) { WL_ERR(("wl_profile alloc failed\n")); goto init_priv_mem_out; } - wl->bss_info = (void *)kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL); + wl->bss_info = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL); if (unlikely(!wl->bss_info)) { WL_ERR(("Bss information alloc failed\n")); goto init_priv_mem_out; } - wl->scan_req_int = - (void *)kzalloc(sizeof(*wl->scan_req_int), GFP_KERNEL); + wl->scan_req_int = kzalloc(sizeof(*wl->scan_req_int), GFP_KERNEL); if (unlikely(!wl->scan_req_int)) { WL_ERR(("Scan req alloc failed\n")); goto init_priv_mem_out; } - wl->ioctl_buf = (void *)kzalloc(WL_IOCTL_LEN_MAX, GFP_KERNEL); + wl->ioctl_buf = kzalloc(WL_IOCTL_LEN_MAX, GFP_KERNEL); if (unlikely(!wl->ioctl_buf)) { WL_ERR(("Ioctl buf alloc failed\n")); goto init_priv_mem_out; } - wl->extra_buf = (void *)kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL); + wl->extra_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL); if (unlikely(!wl->extra_buf)) { WL_ERR(("Extra buf alloc failed\n")); goto init_priv_mem_out; } - wl->iscan = (void *)kzalloc(sizeof(*wl->iscan), GFP_KERNEL); + wl->iscan = kzalloc(sizeof(*wl->iscan), GFP_KERNEL); if (unlikely(!wl->iscan)) { WL_ERR(("Iscan buf alloc failed\n")); goto init_priv_mem_out; } - wl->fw = (void *)kzalloc(sizeof(*wl->fw), GFP_KERNEL); + wl->fw = kzalloc(sizeof(*wl->fw), GFP_KERNEL); if (unlikely(!wl->fw)) { WL_ERR(("fw object alloc failed\n")); goto init_priv_mem_out; } - wl->pmk_list = (void *)kzalloc(sizeof(*wl->pmk_list), GFP_KERNEL); + wl->pmk_list = kzalloc(sizeof(*wl->pmk_list), GFP_KERNEL); if (unlikely(!wl->pmk_list)) { WL_ERR(("pmk list alloc failed\n")); goto init_priv_mem_out; diff --git a/drivers/staging/brcm80211/brcmfmac/wl_iw.c b/drivers/staging/brcm80211/brcmfmac/wl_iw.c index 3e053fe56c79..d583b9d65d35 100644 --- a/drivers/staging/brcm80211/brcmfmac/wl_iw.c +++ b/drivers/staging/brcm80211/brcmfmac/wl_iw.c @@ -3690,8 +3690,7 @@ int wl_iw_attach(struct net_device *dev, void *dhdp) return -ENOMEM; memset(iscan, 0, sizeof(iscan_info_t)); - iscan->iscan_ex_params_p = - (wl_iscan_params_t *) kmalloc(params_size, GFP_KERNEL); + iscan->iscan_ex_params_p = kmalloc(params_size, GFP_KERNEL); if (!iscan->iscan_ex_params_p) return -ENOMEM; iscan->iscan_ex_param_size = params_size; @@ -3723,9 +3722,7 @@ int wl_iw_attach(struct net_device *dev, void *dhdp) priv_dev = dev; MUTEX_LOCK_SOFTAP_SET_INIT(iw->pub); #endif - g_scan = NULL; - - g_scan = (void *)kmalloc(G_SCAN_RESULTS, GFP_KERNEL); + g_scan = kmalloc(G_SCAN_RESULTS, GFP_KERNEL); if (!g_scan) return -ENOMEM; -- cgit v1.2.3 From 61a4295b492f96878b4b47d577a173568530ecff Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Wed, 27 Oct 2010 21:43:46 -0400 Subject: staging: iio: adis16350: add missing reference to temp offset We declare this attr but never link it in to the attr list. Signed-off-by: Mike Frysinger Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/imu/adis16350_core.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/staging/iio/imu/adis16350_core.c b/drivers/staging/iio/imu/adis16350_core.c index 97c1ec8594ce..cf7176bc766b 100644 --- a/drivers/staging/iio/imu/adis16350_core.c +++ b/drivers/staging/iio/imu/adis16350_core.c @@ -570,6 +570,7 @@ static struct attribute *adis16350_attributes[] = { &iio_dev_attr_temp_y_raw.dev_attr.attr, &iio_dev_attr_temp_z_raw.dev_attr.attr, &iio_const_attr_temp_scale.dev_attr.attr, + &iio_const_attr_temp_offset.dev_attr.attr, &iio_dev_attr_in1_raw.dev_attr.attr, &iio_const_attr_in1_scale.dev_attr.attr, &iio_dev_attr_sampling_frequency.dev_attr.attr, -- cgit v1.2.3 From f733d02ab61787239d1ca05c30f6f393275a7899 Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Wed, 27 Oct 2010 21:43:47 -0400 Subject: staging: iio: gyro: make sure grep can find the ADIS16265 support Signed-off-by: Michael Hennerich Signed-off-by: Mike Frysinger Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/gyro/Kconfig | 7 +++++-- drivers/staging/iio/gyro/adis16260_core.c | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/staging/iio/gyro/Kconfig b/drivers/staging/iio/gyro/Kconfig index c4043610c0df..d1dde82dbc9e 100644 --- a/drivers/staging/iio/gyro/Kconfig +++ b/drivers/staging/iio/gyro/Kconfig @@ -4,10 +4,13 @@ comment "Digital gyroscope sensors" config ADIS16260 - tristate "Analog Devices ADIS16260/5 Digital Gyroscope Sensor SPI driver" + tristate "Analog Devices ADIS16260 ADIS16265 Digital Gyroscope Sensor SPI driver" depends on SPI select IIO_TRIGGER if IIO_RING_BUFFER select IIO_SW_RING if IIO_RING_BUFFER help - Say yes here to build support for Analog Devices adis16260/5 + Say yes here to build support for Analog Devices ADIS16260 ADIS16265 programmable digital gyroscope sensor. + + This driver can also be built as a module. If so, the module + will be called adis16260. diff --git a/drivers/staging/iio/gyro/adis16260_core.c b/drivers/staging/iio/gyro/adis16260_core.c index 7d7716e5857c..8190c0fe0bea 100644 --- a/drivers/staging/iio/gyro/adis16260_core.c +++ b/drivers/staging/iio/gyro/adis16260_core.c @@ -1,5 +1,5 @@ /* - * ADIS16260 Programmable Digital Gyroscope Sensor Driver + * ADIS16260/ADIS16265 Programmable Digital Gyroscope Sensor Driver * * Copyright 2010 Analog Devices Inc. * -- cgit v1.2.3 From 6f125f17945a65e0bed37a4dfd7e5397a2c7a886 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Wed, 27 Oct 2010 21:43:48 -0400 Subject: staging: iio: add ADI info to TODO Signed-off-by: Mike Frysinger Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/TODO | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/staging/iio/TODO b/drivers/staging/iio/TODO index 898cba1c939f..d1ad35e24abb 100644 --- a/drivers/staging/iio/TODO +++ b/drivers/staging/iio/TODO @@ -61,6 +61,10 @@ necessitate a header that is also visible from arch board files. (avoided at the moment to keep the driver set contained in staging). +ADI Drivers: +CC the device-drivers-devel@blackfin.uclinux.org mailing list when +e-mailing the normal IIO list (see below). + Documentation 1) Lots of cleanup and expansion. 2) Some device require indvidual docs. -- cgit v1.2.3 From f7fe1d1dd5a512a44f0ada40ff7f120664e2e082 Mon Sep 17 00:00:00 2001 From: Barry Song Date: Wed, 27 Oct 2010 21:43:49 -0400 Subject: staging: iio: new adis16201 driver IIO driver for dual Axis Accelerometer/inclinometer adis16201 parts. Signed-off-by: Barry Song Signed-off-by: Michael Hennerich Acked-by: Jonathan Cameron Signed-off-by: Mike Frysinger Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/accel/Kconfig | 9 + drivers/staging/iio/accel/Makefile | 4 + drivers/staging/iio/accel/adis16201.h | 150 ++++++ drivers/staging/iio/accel/adis16201_core.c | 659 ++++++++++++++++++++++++++ drivers/staging/iio/accel/adis16201_ring.c | 218 +++++++++ drivers/staging/iio/accel/adis16201_trigger.c | 122 +++++ 6 files changed, 1162 insertions(+) create mode 100644 drivers/staging/iio/accel/adis16201.h create mode 100644 drivers/staging/iio/accel/adis16201_core.c create mode 100644 drivers/staging/iio/accel/adis16201_ring.c create mode 100644 drivers/staging/iio/accel/adis16201_trigger.c diff --git a/drivers/staging/iio/accel/Kconfig b/drivers/staging/iio/accel/Kconfig index 5926c03be1a5..0b87557a554e 100644 --- a/drivers/staging/iio/accel/Kconfig +++ b/drivers/staging/iio/accel/Kconfig @@ -3,6 +3,15 @@ # comment "Accelerometers" +config ADIS16201 + tristate "Analog Devices ADIS16201 Dual-Axis Digital Inclinometer and Accelerometer" + depends on SPI + select IIO_TRIGGER if IIO_RING_BUFFER + select IIO_SW_RING if IIO_RING_BUFFER + help + Say yes here to build support for Analog Devices adis16201 dual-axis + digital inclinometer and accelerometer. + config ADIS16209 tristate "Analog Devices ADIS16209 Dual-Axis Digital Inclinometer and Accelerometer" depends on SPI diff --git a/drivers/staging/iio/accel/Makefile b/drivers/staging/iio/accel/Makefile index ff84703a16f6..4a22a013cff8 100644 --- a/drivers/staging/iio/accel/Makefile +++ b/drivers/staging/iio/accel/Makefile @@ -2,6 +2,10 @@ # Makefile for industrial I/O accelerometer drivers # +adis16201-y := adis16201_core.o +adis16201-$(CONFIG_IIO_RING_BUFFER) += adis16201_ring.o adis16201_trigger.o +obj-$(CONFIG_ADIS16201) += adis16201.o + adis16209-y := adis16209_core.o adis16209-$(CONFIG_IIO_RING_BUFFER) += adis16209_ring.o adis16209_trigger.o obj-$(CONFIG_ADIS16209) += adis16209.o diff --git a/drivers/staging/iio/accel/adis16201.h b/drivers/staging/iio/accel/adis16201.h new file mode 100644 index 000000000000..c9bf22c13428 --- /dev/null +++ b/drivers/staging/iio/accel/adis16201.h @@ -0,0 +1,150 @@ +#ifndef SPI_ADIS16201_H_ +#define SPI_ADIS16201_H_ + +#define ADIS16201_STARTUP_DELAY 220 /* ms */ + +#define ADIS16201_READ_REG(a) a +#define ADIS16201_WRITE_REG(a) ((a) | 0x80) + +#define ADIS16201_FLASH_CNT 0x00 /* Flash memory write count */ +#define ADIS16201_SUPPLY_OUT 0x02 /* Output, power supply */ +#define ADIS16201_XACCL_OUT 0x04 /* Output, x-axis accelerometer */ +#define ADIS16201_YACCL_OUT 0x06 /* Output, y-axis accelerometer */ +#define ADIS16201_AUX_ADC 0x08 /* Output, auxiliary ADC input */ +#define ADIS16201_TEMP_OUT 0x0A /* Output, temperature */ +#define ADIS16201_XINCL_OUT 0x0C /* Output, x-axis inclination */ +#define ADIS16201_YINCL_OUT 0x0E /* Output, y-axis inclination */ +#define ADIS16201_XACCL_OFFS 0x10 /* Calibration, x-axis acceleration offset */ +#define ADIS16201_YACCL_OFFS 0x12 /* Calibration, y-axis acceleration offset */ +#define ADIS16201_XACCL_SCALE 0x14 /* x-axis acceleration scale factor */ +#define ADIS16201_YACCL_SCALE 0x16 /* y-axis acceleration scale factor */ +#define ADIS16201_XINCL_OFFS 0x18 /* Calibration, x-axis inclination offset */ +#define ADIS16201_YINCL_OFFS 0x1A /* Calibration, y-axis inclination offset */ +#define ADIS16201_XINCL_SCALE 0x1C /* x-axis inclination scale factor */ +#define ADIS16201_YINCL_SCALE 0x1E /* y-axis inclination scale factor */ +#define ADIS16201_ALM_MAG1 0x20 /* Alarm 1 amplitude threshold */ +#define ADIS16201_ALM_MAG2 0x22 /* Alarm 2 amplitude threshold */ +#define ADIS16201_ALM_SMPL1 0x24 /* Alarm 1, sample period */ +#define ADIS16201_ALM_SMPL2 0x26 /* Alarm 2, sample period */ +#define ADIS16201_ALM_CTRL 0x28 /* Alarm control */ +#define ADIS16201_AUX_DAC 0x30 /* Auxiliary DAC data */ +#define ADIS16201_GPIO_CTRL 0x32 /* General-purpose digital input/output control */ +#define ADIS16201_MSC_CTRL 0x34 /* Miscellaneous control */ +#define ADIS16201_SMPL_PRD 0x36 /* Internal sample period (rate) control */ +#define ADIS16201_AVG_CNT 0x38 /* Operation, filter configuration */ +#define ADIS16201_SLP_CNT 0x3A /* Operation, sleep mode control */ +#define ADIS16201_DIAG_STAT 0x3C /* Diagnostics, system status register */ +#define ADIS16201_GLOB_CMD 0x3E /* Operation, system command register */ + +#define ADIS16201_OUTPUTS 7 + +/* MSC_CTRL */ +#define ADIS16201_MSC_CTRL_SELF_TEST_EN (1 << 8) /* Self-test enable */ +#define ADIS16201_MSC_CTRL_DATA_RDY_EN (1 << 2) /* Data-ready enable: 1 = enabled, 0 = disabled */ +#define ADIS16201_MSC_CTRL_ACTIVE_HIGH (1 << 1) /* Data-ready polarity: 1 = active high, 0 = active low */ +#define ADIS16201_MSC_CTRL_DATA_RDY_DIO1 (1 << 0) /* Data-ready line selection: 1 = DIO1, 0 = DIO0 */ + +/* DIAG_STAT */ +#define ADIS16201_DIAG_STAT_ALARM2 (1<<9) /* Alarm 2 status: 1 = alarm active, 0 = alarm inactive */ +#define ADIS16201_DIAG_STAT_ALARM1 (1<<8) /* Alarm 1 status: 1 = alarm active, 0 = alarm inactive */ +#define ADIS16201_DIAG_STAT_SPI_FAIL (1<<3) /* SPI communications failure */ +#define ADIS16201_DIAG_STAT_FLASH_UPT (1<<2) /* Flash update failure */ +#define ADIS16201_DIAG_STAT_POWER_HIGH (1<<1) /* Power supply above 3.625 V */ +#define ADIS16201_DIAG_STAT_POWER_LOW (1<<0) /* Power supply below 3.15 V */ + +/* GLOB_CMD */ +#define ADIS16201_GLOB_CMD_SW_RESET (1<<7) +#define ADIS16201_GLOB_CMD_FACTORY_CAL (1<<1) + +#define ADIS16201_MAX_TX 14 +#define ADIS16201_MAX_RX 14 + +#define ADIS16201_ERROR_ACTIVE (1<<14) + +/** + * struct adis16201_state - device instance specific data + * @us: actual spi_device + * @work_trigger_to_ring: bh for triggered event handling + * @inter: used to check if new interrupt has been triggered + * @last_timestamp: passing timestamp from th to bh of interrupt handler + * @indio_dev: industrial I/O device structure + * @trig: data ready trigger registered with iio + * @tx: transmit buffer + * @rx: recieve buffer + * @buf_lock: mutex to protect tx and rx + **/ +struct adis16201_state { + struct spi_device *us; + struct work_struct work_trigger_to_ring; + s64 last_timestamp; + struct iio_dev *indio_dev; + struct iio_trigger *trig; + u8 *tx; + u8 *rx; + struct mutex buf_lock; +}; + +int adis16201_set_irq(struct device *dev, bool enable); + +#ifdef CONFIG_IIO_RING_BUFFER +enum adis16201_scan { + ADIS16201_SCAN_SUPPLY, + ADIS16201_SCAN_ACC_X, + ADIS16201_SCAN_ACC_Y, + ADIS16201_SCAN_AUX_ADC, + ADIS16201_SCAN_TEMP, + ADIS16201_SCAN_INCLI_X, + ADIS16201_SCAN_INCLI_Y, +}; + +void adis16201_remove_trigger(struct iio_dev *indio_dev); +int adis16201_probe_trigger(struct iio_dev *indio_dev); + +ssize_t adis16201_read_data_from_ring(struct device *dev, + struct device_attribute *attr, + char *buf); + +int adis16201_configure_ring(struct iio_dev *indio_dev); +void adis16201_unconfigure_ring(struct iio_dev *indio_dev); + +int adis16201_initialize_ring(struct iio_ring_buffer *ring); +void adis16201_uninitialize_ring(struct iio_ring_buffer *ring); +#else /* CONFIG_IIO_RING_BUFFER */ + +static inline void adis16201_remove_trigger(struct iio_dev *indio_dev) +{ +} + +static inline int adis16201_probe_trigger(struct iio_dev *indio_dev) +{ + return 0; +} + +static inline ssize_t +adis16201_read_data_from_ring(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + return 0; +} + +static int adis16201_configure_ring(struct iio_dev *indio_dev) +{ + return 0; +} + +static inline void adis16201_unconfigure_ring(struct iio_dev *indio_dev) +{ +} + +static inline int adis16201_initialize_ring(struct iio_ring_buffer *ring) +{ + return 0; +} + +static inline void adis16201_uninitialize_ring(struct iio_ring_buffer *ring) +{ +} + +#endif /* CONFIG_IIO_RING_BUFFER */ +#endif /* SPI_ADIS16201_H_ */ diff --git a/drivers/staging/iio/accel/adis16201_core.c b/drivers/staging/iio/accel/adis16201_core.c new file mode 100644 index 000000000000..79b785a0013a --- /dev/null +++ b/drivers/staging/iio/accel/adis16201_core.c @@ -0,0 +1,659 @@ +/* + * ADIS16201 Programmable Digital Vibration Sensor driver + * + * Copyright 2010 Analog Devices Inc. + * + * Licensed under the GPL-2 or later. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../iio.h" +#include "../sysfs.h" +#include "accel.h" +#include "inclinometer.h" +#include "../gyro/gyro.h" +#include "../adc/adc.h" + +#include "adis16201.h" + +#define DRIVER_NAME "adis16201" + +static int adis16201_check_status(struct device *dev); + +/** + * adis16201_spi_write_reg_8() - write single byte to a register + * @dev: device associated with child of actual device (iio_dev or iio_trig) + * @reg_address: the address of the register to be written + * @val: the value to write + **/ +static int adis16201_spi_write_reg_8(struct device *dev, + u8 reg_address, + u8 val) +{ + int ret; + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct adis16201_state *st = iio_dev_get_devdata(indio_dev); + + mutex_lock(&st->buf_lock); + st->tx[0] = ADIS16201_WRITE_REG(reg_address); + st->tx[1] = val; + + ret = spi_write(st->us, st->tx, 2); + mutex_unlock(&st->buf_lock); + + return ret; +} + +/** + * adis16201_spi_write_reg_16() - write 2 bytes to a pair of registers + * @dev: device associated with child of actual device (iio_dev or iio_trig) + * @reg_address: the address of the lower of the two registers. Second register + * is assumed to have address one greater. + * @val: value to be written + **/ +static int adis16201_spi_write_reg_16(struct device *dev, + u8 lower_reg_address, + u16 value) +{ + int ret; + struct spi_message msg; + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct adis16201_state *st = iio_dev_get_devdata(indio_dev); + struct spi_transfer xfers[] = { + { + .tx_buf = st->tx, + .bits_per_word = 8, + .len = 2, + .cs_change = 1, + }, { + .tx_buf = st->tx + 2, + .bits_per_word = 8, + .len = 2, + .cs_change = 1, + }, + }; + + mutex_lock(&st->buf_lock); + st->tx[0] = ADIS16201_WRITE_REG(lower_reg_address); + st->tx[1] = value & 0xFF; + st->tx[2] = ADIS16201_WRITE_REG(lower_reg_address + 1); + st->tx[3] = (value >> 8) & 0xFF; + + spi_message_init(&msg); + spi_message_add_tail(&xfers[0], &msg); + spi_message_add_tail(&xfers[1], &msg); + ret = spi_sync(st->us, &msg); + mutex_unlock(&st->buf_lock); + + return ret; +} + +/** + * adis16201_spi_read_reg_16() - read 2 bytes from a 16-bit register + * @dev: device associated with child of actual device (iio_dev or iio_trig) + * @reg_address: the address of the lower of the two registers. Second register + * is assumed to have address one greater. + * @val: somewhere to pass back the value read + **/ +static int adis16201_spi_read_reg_16(struct device *dev, + u8 lower_reg_address, + u16 *val) +{ + struct spi_message msg; + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct adis16201_state *st = iio_dev_get_devdata(indio_dev); + int ret; + struct spi_transfer xfers[] = { + { + .tx_buf = st->tx, + .bits_per_word = 8, + .len = 2, + .cs_change = 1, + .delay_usecs = 20, + }, { + .rx_buf = st->rx, + .bits_per_word = 8, + .len = 2, + .cs_change = 1, + .delay_usecs = 20, + }, + }; + + mutex_lock(&st->buf_lock); + st->tx[0] = ADIS16201_READ_REG(lower_reg_address); + st->tx[1] = 0; + + spi_message_init(&msg); + spi_message_add_tail(&xfers[0], &msg); + spi_message_add_tail(&xfers[1], &msg); + ret = spi_sync(st->us, &msg); + if (ret) { + dev_err(&st->us->dev, "problem when reading 16 bit register 0x%02X", + lower_reg_address); + goto error_ret; + } + *val = (st->rx[0] << 8) | st->rx[1]; + +error_ret: + mutex_unlock(&st->buf_lock); + return ret; +} + +static ssize_t adis16201_read_12bit_unsigned(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + int ret; + u16 val = 0; + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + + ret = adis16201_spi_read_reg_16(dev, this_attr->address, &val); + if (ret) + return ret; + + if (val & ADIS16201_ERROR_ACTIVE) { + ret = adis16201_check_status(dev); + if (ret) + return ret; + } + + return sprintf(buf, "%u\n", val & 0x0FFF); +} + +static ssize_t adis16201_read_temp(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + ssize_t ret; + u16 val; + + /* Take the iio_dev status lock */ + mutex_lock(&indio_dev->mlock); + + ret = adis16201_spi_read_reg_16(dev, ADIS16201_TEMP_OUT, (u16 *)&val); + if (ret) + goto error_ret; + + if (val & ADIS16201_ERROR_ACTIVE) { + ret = adis16201_check_status(dev); + if (ret) + goto error_ret; + } + + val &= 0xFFF; + ret = sprintf(buf, "%d\n", val); + +error_ret: + mutex_unlock(&indio_dev->mlock); + return ret; +} + +static ssize_t adis16201_read_9bit_signed(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + s16 val = 0; + ssize_t ret; + + mutex_lock(&indio_dev->mlock); + + ret = adis16201_spi_read_reg_16(dev, this_attr->address, (u16 *)&val); + if (!ret) { + if (val & ADIS16201_ERROR_ACTIVE) { + ret = adis16201_check_status(dev); + if (ret) + goto error_ret; + } + val = ((s16)(val << 7) >> 7); + ret = sprintf(buf, "%d\n", val); + } + +error_ret: + mutex_unlock(&indio_dev->mlock); + + return ret; +} + +static ssize_t adis16201_read_12bit_signed(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + s16 val = 0; + ssize_t ret; + + mutex_lock(&indio_dev->mlock); + + ret = adis16201_spi_read_reg_16(dev, this_attr->address, (u16 *)&val); + if (!ret) { + if (val & ADIS16201_ERROR_ACTIVE) { + ret = adis16201_check_status(dev); + if (ret) + goto error_ret; + } + + val = ((s16)(val << 4) >> 4); + ret = sprintf(buf, "%d\n", val); + } + +error_ret: + mutex_unlock(&indio_dev->mlock); + + return ret; +} + +static ssize_t adis16201_read_14bit_signed(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + s16 val = 0; + ssize_t ret; + + mutex_lock(&indio_dev->mlock); + + ret = adis16201_spi_read_reg_16(dev, this_attr->address, (u16 *)&val); + if (!ret) { + if (val & ADIS16201_ERROR_ACTIVE) { + ret = adis16201_check_status(dev); + if (ret) + goto error_ret; + } + + val = ((s16)(val << 2) >> 2); + ret = sprintf(buf, "%d\n", val); + } + +error_ret: + mutex_unlock(&indio_dev->mlock); + + return ret; +} + +static ssize_t adis16201_write_16bit(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + int ret; + long val; + + ret = strict_strtol(buf, 10, &val); + if (ret) + goto error_ret; + ret = adis16201_spi_write_reg_16(dev, this_attr->address, val); + +error_ret: + return ret ? ret : len; +} + +static int adis16201_reset(struct device *dev) +{ + int ret; + ret = adis16201_spi_write_reg_8(dev, + ADIS16201_GLOB_CMD, + ADIS16201_GLOB_CMD_SW_RESET); + if (ret) + dev_err(dev, "problem resetting device"); + + return ret; +} + +static ssize_t adis16201_write_reset(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t len) +{ + if (len < 1) + return -EINVAL; + switch (buf[0]) { + case '1': + case 'y': + case 'Y': + return adis16201_reset(dev); + } + return -EINVAL; +} + +int adis16201_set_irq(struct device *dev, bool enable) +{ + int ret = 0; + u16 msc; + + ret = adis16201_spi_read_reg_16(dev, ADIS16201_MSC_CTRL, &msc); + if (ret) + goto error_ret; + + msc |= ADIS16201_MSC_CTRL_ACTIVE_HIGH; + msc &= ~ADIS16201_MSC_CTRL_DATA_RDY_DIO1; + if (enable) + msc |= ADIS16201_MSC_CTRL_DATA_RDY_EN; + else + msc &= ~ADIS16201_MSC_CTRL_DATA_RDY_EN; + + ret = adis16201_spi_write_reg_16(dev, ADIS16201_MSC_CTRL, msc); + +error_ret: + return ret; +} + +static int adis16201_check_status(struct device *dev) +{ + u16 status; + int ret; + + ret = adis16201_spi_read_reg_16(dev, ADIS16201_DIAG_STAT, &status); + if (ret < 0) { + dev_err(dev, "Reading status failed\n"); + goto error_ret; + } + ret = status & 0xF; + if (ret) + ret = -EFAULT; + + if (status & ADIS16201_DIAG_STAT_SPI_FAIL) + dev_err(dev, "SPI failure\n"); + if (status & ADIS16201_DIAG_STAT_FLASH_UPT) + dev_err(dev, "Flash update failed\n"); + if (status & ADIS16201_DIAG_STAT_POWER_HIGH) + dev_err(dev, "Power supply above 3.625V\n"); + if (status & ADIS16201_DIAG_STAT_POWER_LOW) + dev_err(dev, "Power supply below 3.15V\n"); + +error_ret: + return ret; +} + +static int adis16201_self_test(struct device *dev) +{ + int ret; + ret = adis16201_spi_write_reg_16(dev, + ADIS16201_MSC_CTRL, + ADIS16201_MSC_CTRL_SELF_TEST_EN); + if (ret) { + dev_err(dev, "problem starting self test"); + goto err_ret; + } + + ret = adis16201_check_status(dev); + +err_ret: + return ret; +} + +static int adis16201_initial_setup(struct adis16201_state *st) +{ + int ret; + struct device *dev = &st->indio_dev->dev; + + /* Disable IRQ */ + ret = adis16201_set_irq(dev, false); + if (ret) { + dev_err(dev, "disable irq failed"); + goto err_ret; + } + + /* Do self test */ + ret = adis16201_self_test(dev); + if (ret) { + dev_err(dev, "self test failure"); + goto err_ret; + } + + /* Read status register to check the result */ + ret = adis16201_check_status(dev); + if (ret) { + adis16201_reset(dev); + dev_err(dev, "device not playing ball -> reset"); + msleep(ADIS16201_STARTUP_DELAY); + ret = adis16201_check_status(dev); + if (ret) { + dev_err(dev, "giving up"); + goto err_ret; + } + } + + printk(KERN_INFO DRIVER_NAME ": at CS%d (irq %d)\n", + st->us->chip_select, st->us->irq); + +err_ret: + return ret; +} + +static IIO_DEV_ATTR_IN_NAMED_RAW(0, supply, adis16201_read_12bit_unsigned, + ADIS16201_SUPPLY_OUT); +static IIO_CONST_ATTR(in0_supply_scale, "0.00122"); +static IIO_DEV_ATTR_IN_RAW(1, adis16201_read_12bit_unsigned, + ADIS16201_AUX_ADC); +static IIO_CONST_ATTR(in1_scale, "0.00061"); + +static IIO_DEV_ATTR_ACCEL_X(adis16201_read_14bit_signed, + ADIS16201_XACCL_OUT); +static IIO_DEV_ATTR_ACCEL_Y(adis16201_read_14bit_signed, + ADIS16201_YACCL_OUT); +static IIO_DEV_ATTR_ACCEL_X_OFFSET(S_IWUSR | S_IRUGO, + adis16201_read_12bit_signed, + adis16201_write_16bit, + ADIS16201_XACCL_OFFS); +static IIO_DEV_ATTR_ACCEL_Y_OFFSET(S_IWUSR | S_IRUGO, + adis16201_read_12bit_signed, + adis16201_write_16bit, + ADIS16201_YACCL_OFFS); +static IIO_CONST_ATTR(accel_scale, "0.4625"); + +static IIO_DEV_ATTR_INCLI_X(adis16201_read_14bit_signed, + ADIS16201_XINCL_OUT); +static IIO_DEV_ATTR_INCLI_Y(adis16201_read_14bit_signed, + ADIS16201_YINCL_OUT); +static IIO_DEV_ATTR_INCLI_X_OFFSET(S_IWUSR | S_IRUGO, + adis16201_read_9bit_signed, + adis16201_write_16bit, + ADIS16201_XACCL_OFFS); +static IIO_DEV_ATTR_INCLI_Y_OFFSET(S_IWUSR | S_IRUGO, + adis16201_read_9bit_signed, + adis16201_write_16bit, + ADIS16201_YACCL_OFFS); +static IIO_CONST_ATTR(incli_scale, "0.1"); + +static IIO_DEV_ATTR_TEMP_RAW(adis16201_read_temp); +static IIO_CONST_ATTR(temp_offset, "25"); +static IIO_CONST_ATTR(temp_scale, "-0.47"); + +static IIO_DEVICE_ATTR(reset, S_IWUSR, NULL, adis16201_write_reset, 0); + +static IIO_CONST_ATTR(name, "adis16201"); + +static struct attribute *adis16201_event_attributes[] = { + NULL +}; + +static struct attribute_group adis16201_event_attribute_group = { + .attrs = adis16201_event_attributes, +}; + +static struct attribute *adis16201_attributes[] = { + &iio_dev_attr_in0_supply_raw.dev_attr.attr, + &iio_const_attr_in0_supply_scale.dev_attr.attr, + &iio_dev_attr_temp_raw.dev_attr.attr, + &iio_const_attr_temp_offset.dev_attr.attr, + &iio_const_attr_temp_scale.dev_attr.attr, + &iio_dev_attr_reset.dev_attr.attr, + &iio_const_attr_name.dev_attr.attr, + &iio_dev_attr_in1_raw.dev_attr.attr, + &iio_const_attr_in1_scale.dev_attr.attr, + &iio_dev_attr_accel_x_raw.dev_attr.attr, + &iio_dev_attr_accel_y_raw.dev_attr.attr, + &iio_dev_attr_accel_x_offset.dev_attr.attr, + &iio_dev_attr_accel_y_offset.dev_attr.attr, + &iio_const_attr_accel_scale.dev_attr.attr, + &iio_dev_attr_incli_x_raw.dev_attr.attr, + &iio_dev_attr_incli_y_raw.dev_attr.attr, + &iio_dev_attr_incli_x_offset.dev_attr.attr, + &iio_dev_attr_incli_y_offset.dev_attr.attr, + &iio_const_attr_incli_scale.dev_attr.attr, + NULL +}; + +static const struct attribute_group adis16201_attribute_group = { + .attrs = adis16201_attributes, +}; + +static int __devinit adis16201_probe(struct spi_device *spi) +{ + int ret, regdone = 0; + struct adis16201_state *st = kzalloc(sizeof *st, GFP_KERNEL); + if (!st) { + ret = -ENOMEM; + goto error_ret; + } + /* this is only used for removal purposes */ + spi_set_drvdata(spi, st); + + /* Allocate the comms buffers */ + st->rx = kzalloc(sizeof(*st->rx)*ADIS16201_MAX_RX, GFP_KERNEL); + if (st->rx == NULL) { + ret = -ENOMEM; + goto error_free_st; + } + st->tx = kzalloc(sizeof(*st->tx)*ADIS16201_MAX_TX, GFP_KERNEL); + if (st->tx == NULL) { + ret = -ENOMEM; + goto error_free_rx; + } + st->us = spi; + mutex_init(&st->buf_lock); + /* setup the industrialio driver allocated elements */ + st->indio_dev = iio_allocate_device(); + if (st->indio_dev == NULL) { + ret = -ENOMEM; + goto error_free_tx; + } + + st->indio_dev->dev.parent = &spi->dev; + st->indio_dev->num_interrupt_lines = 1; + st->indio_dev->event_attrs = &adis16201_event_attribute_group; + st->indio_dev->attrs = &adis16201_attribute_group; + st->indio_dev->dev_data = (void *)(st); + st->indio_dev->driver_module = THIS_MODULE; + st->indio_dev->modes = INDIO_DIRECT_MODE; + + ret = adis16201_configure_ring(st->indio_dev); + if (ret) + goto error_free_dev; + + ret = iio_device_register(st->indio_dev); + if (ret) + goto error_unreg_ring_funcs; + regdone = 1; + + ret = adis16201_initialize_ring(st->indio_dev->ring); + if (ret) { + printk(KERN_ERR "failed to initialize the ring\n"); + goto error_unreg_ring_funcs; + } + + if (spi->irq) { + ret = iio_register_interrupt_line(spi->irq, + st->indio_dev, + 0, + IRQF_TRIGGER_RISING, + "adis16201"); + if (ret) + goto error_uninitialize_ring; + + ret = adis16201_probe_trigger(st->indio_dev); + if (ret) + goto error_unregister_line; + } + + /* Get the device into a sane initial state */ + ret = adis16201_initial_setup(st); + if (ret) + goto error_remove_trigger; + return 0; + +error_remove_trigger: + adis16201_remove_trigger(st->indio_dev); +error_unregister_line: + if (spi->irq) + iio_unregister_interrupt_line(st->indio_dev, 0); +error_uninitialize_ring: + adis16201_uninitialize_ring(st->indio_dev->ring); +error_unreg_ring_funcs: + adis16201_unconfigure_ring(st->indio_dev); +error_free_dev: + if (regdone) + iio_device_unregister(st->indio_dev); + else + iio_free_device(st->indio_dev); +error_free_tx: + kfree(st->tx); +error_free_rx: + kfree(st->rx); +error_free_st: + kfree(st); +error_ret: + return ret; +} + +static int adis16201_remove(struct spi_device *spi) +{ + struct adis16201_state *st = spi_get_drvdata(spi); + struct iio_dev *indio_dev = st->indio_dev; + + flush_scheduled_work(); + + adis16201_remove_trigger(indio_dev); + if (spi->irq) + iio_unregister_interrupt_line(indio_dev, 0); + + adis16201_uninitialize_ring(indio_dev->ring); + iio_device_unregister(indio_dev); + adis16201_unconfigure_ring(indio_dev); + kfree(st->tx); + kfree(st->rx); + kfree(st); + + return 0; +} + +static struct spi_driver adis16201_driver = { + .driver = { + .name = "adis16201", + .owner = THIS_MODULE, + }, + .probe = adis16201_probe, + .remove = __devexit_p(adis16201_remove), +}; + +static __init int adis16201_init(void) +{ + return spi_register_driver(&adis16201_driver); +} +module_init(adis16201_init); + +static __exit void adis16201_exit(void) +{ + spi_unregister_driver(&adis16201_driver); +} +module_exit(adis16201_exit); + +MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>"); +MODULE_DESCRIPTION("Analog Devices ADIS16201 Programmable Digital Vibration Sensor driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/staging/iio/accel/adis16201_ring.c b/drivers/staging/iio/accel/adis16201_ring.c new file mode 100644 index 000000000000..e6870a2721f1 --- /dev/null +++ b/drivers/staging/iio/accel/adis16201_ring.c @@ -0,0 +1,218 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../iio.h" +#include "../sysfs.h" +#include "../ring_sw.h" +#include "accel.h" +#include "../trigger.h" +#include "adis16201.h" + +static IIO_SCAN_EL_C(in_supply, ADIS16201_SCAN_SUPPLY, ADIS16201_SUPPLY_OUT, NULL); +static IIO_CONST_ATTR_SCAN_EL_TYPE(in_supply, u, 12, 16); +static IIO_SCAN_EL_C(accel_x, ADIS16201_SCAN_ACC_X, ADIS16201_XACCL_OUT, NULL); +static IIO_SCAN_EL_C(accel_y, ADIS16201_SCAN_ACC_Y, ADIS16201_YACCL_OUT, NULL); +static IIO_CONST_ATTR_SCAN_EL_TYPE(accel, s, 14, 16); +static IIO_SCAN_EL_C(in0, ADIS16201_SCAN_AUX_ADC, ADIS16201_AUX_ADC, NULL); +static IIO_CONST_ATTR_SCAN_EL_TYPE(in0, u, 12, 16); +static IIO_SCAN_EL_C(temp, ADIS16201_SCAN_TEMP, ADIS16201_TEMP_OUT, NULL); +static IIO_CONST_ATTR_SCAN_EL_TYPE(temp, u, 12, 16); +static IIO_SCAN_EL_C(incli_x, ADIS16201_SCAN_INCLI_X, + ADIS16201_XINCL_OUT, NULL); +static IIO_SCAN_EL_C(incli_y, ADIS16201_SCAN_INCLI_Y, + ADIS16201_YINCL_OUT, NULL); +static IIO_CONST_ATTR_SCAN_EL_TYPE(incli, s, 14, 16); +static IIO_SCAN_EL_TIMESTAMP(7); +static IIO_CONST_ATTR_SCAN_EL_TYPE(timestamp, s, 64, 64); + +static struct attribute *adis16201_scan_el_attrs[] = { + &iio_scan_el_in_supply.dev_attr.attr, + &iio_const_attr_in_supply_index.dev_attr.attr, + &iio_const_attr_in_supply_type.dev_attr.attr, + &iio_scan_el_accel_x.dev_attr.attr, + &iio_const_attr_accel_x_index.dev_attr.attr, + &iio_scan_el_accel_y.dev_attr.attr, + &iio_const_attr_accel_y_index.dev_attr.attr, + &iio_const_attr_accel_type.dev_attr.attr, + &iio_scan_el_in0.dev_attr.attr, + &iio_const_attr_in0_index.dev_attr.attr, + &iio_const_attr_in0_type.dev_attr.attr, + &iio_scan_el_temp.dev_attr.attr, + &iio_const_attr_temp_index.dev_attr.attr, + &iio_const_attr_temp_type.dev_attr.attr, + &iio_scan_el_incli_x.dev_attr.attr, + &iio_const_attr_incli_x_index.dev_attr.attr, + &iio_scan_el_incli_y.dev_attr.attr, + &iio_const_attr_incli_y_index.dev_attr.attr, + &iio_const_attr_incli_type.dev_attr.attr, + &iio_scan_el_timestamp.dev_attr.attr, + &iio_const_attr_timestamp_index.dev_attr.attr, + &iio_const_attr_timestamp_type.dev_attr.attr, + NULL, +}; + +static struct attribute_group adis16201_scan_el_group = { + .attrs = adis16201_scan_el_attrs, + .name = "scan_elements", +}; + +/** + * adis16201_poll_func_th() top half interrupt handler called by trigger + * @private_data: iio_dev + **/ +static void adis16201_poll_func_th(struct iio_dev *indio_dev, s64 time) +{ + struct adis16201_state *st = iio_dev_get_devdata(indio_dev); + st->last_timestamp = time; + schedule_work(&st->work_trigger_to_ring); +} + +/** + * adis16201_read_ring_data() read data registers which will be placed into ring + * @dev: device associated with child of actual device (iio_dev or iio_trig) + * @rx: somewhere to pass back the value read + **/ +static int adis16201_read_ring_data(struct device *dev, u8 *rx) +{ + struct spi_message msg; + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct adis16201_state *st = iio_dev_get_devdata(indio_dev); + struct spi_transfer xfers[ADIS16201_OUTPUTS + 1]; + int ret; + int i; + + mutex_lock(&st->buf_lock); + + spi_message_init(&msg); + + memset(xfers, 0, sizeof(xfers)); + for (i = 0; i <= ADIS16201_OUTPUTS; i++) { + xfers[i].bits_per_word = 8; + xfers[i].cs_change = 1; + xfers[i].len = 2; + xfers[i].delay_usecs = 20; + xfers[i].tx_buf = st->tx + 2 * i; + st->tx[2 * i] = ADIS16201_READ_REG(ADIS16201_SUPPLY_OUT + 2 * i); + st->tx[2 * i + 1] = 0; + if (i >= 1) + xfers[i].rx_buf = rx + 2 * (i - 1); + spi_message_add_tail(&xfers[i], &msg); + } + + ret = spi_sync(st->us, &msg); + if (ret) + dev_err(&st->us->dev, "problem when burst reading"); + + mutex_unlock(&st->buf_lock); + + return ret; +} + +/* Whilst this makes a lot of calls to iio_sw_ring functions - it is to device + * specific to be rolled into the core. + */ +static void adis16201_trigger_bh_to_ring(struct work_struct *work_s) +{ + struct adis16201_state *st + = container_of(work_s, struct adis16201_state, + work_trigger_to_ring); + struct iio_ring_buffer *ring = st->indio_dev->ring; + + int i = 0; + s16 *data; + size_t datasize = ring->access.get_bytes_per_datum(ring); + + data = kmalloc(datasize, GFP_KERNEL); + if (data == NULL) { + dev_err(&st->us->dev, "memory alloc failed in ring bh"); + return; + } + + if (ring->scan_count) + if (adis16201_read_ring_data(&st->indio_dev->dev, st->rx) >= 0) + for (; i < ring->scan_count; i++) + data[i] = be16_to_cpup( + (__be16 *)&(st->rx[i*2])); + + /* Guaranteed to be aligned with 8 byte boundary */ + if (ring->scan_timestamp) + *((s64 *)(data + ((i + 3)/4)*4)) = st->last_timestamp; + + ring->access.store_to(ring, + (u8 *)data, + st->last_timestamp); + + iio_trigger_notify_done(st->indio_dev->trig); + kfree(data); + + return; +} + +void adis16201_unconfigure_ring(struct iio_dev *indio_dev) +{ + kfree(indio_dev->pollfunc); + iio_sw_rb_free(indio_dev->ring); +} + +int adis16201_configure_ring(struct iio_dev *indio_dev) +{ + int ret = 0; + struct adis16201_state *st = indio_dev->dev_data; + struct iio_ring_buffer *ring; + INIT_WORK(&st->work_trigger_to_ring, adis16201_trigger_bh_to_ring); + + ring = iio_sw_rb_allocate(indio_dev); + if (!ring) { + ret = -ENOMEM; + return ret; + } + indio_dev->ring = ring; + /* Effectively select the ring buffer implementation */ + iio_ring_sw_register_funcs(&ring->access); + ring->bpe = 2; + ring->scan_el_attrs = &adis16201_scan_el_group; + ring->scan_timestamp = true; + ring->preenable = &iio_sw_ring_preenable; + ring->postenable = &iio_triggered_ring_postenable; + ring->predisable = &iio_triggered_ring_predisable; + ring->owner = THIS_MODULE; + + /* Set default scan mode */ + iio_scan_mask_set(ring, iio_scan_el_in_supply.number); + iio_scan_mask_set(ring, iio_scan_el_accel_x.number); + iio_scan_mask_set(ring, iio_scan_el_accel_y.number); + iio_scan_mask_set(ring, iio_scan_el_temp.number); + iio_scan_mask_set(ring, iio_scan_el_in0.number); + iio_scan_mask_set(ring, iio_scan_el_incli_x.number); + iio_scan_mask_set(ring, iio_scan_el_incli_y.number); + + ret = iio_alloc_pollfunc(indio_dev, NULL, &adis16201_poll_func_th); + if (ret) + goto error_iio_sw_rb_free; + + indio_dev->modes |= INDIO_RING_TRIGGERED; + return 0; + +error_iio_sw_rb_free: + iio_sw_rb_free(indio_dev->ring); + return ret; +} + +int adis16201_initialize_ring(struct iio_ring_buffer *ring) +{ + return iio_ring_buffer_register(ring, 0); +} + +void adis16201_uninitialize_ring(struct iio_ring_buffer *ring) +{ + iio_ring_buffer_unregister(ring); +} diff --git a/drivers/staging/iio/accel/adis16201_trigger.c b/drivers/staging/iio/accel/adis16201_trigger.c new file mode 100644 index 000000000000..8a9cea1986e7 --- /dev/null +++ b/drivers/staging/iio/accel/adis16201_trigger.c @@ -0,0 +1,122 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../iio.h" +#include "../sysfs.h" +#include "../trigger.h" +#include "adis16201.h" + +/** + * adis16201_data_rdy_trig_poll() the event handler for the data rdy trig + **/ +static int adis16201_data_rdy_trig_poll(struct iio_dev *dev_info, + int index, + s64 timestamp, + int no_test) +{ + struct adis16201_state *st = iio_dev_get_devdata(dev_info); + struct iio_trigger *trig = st->trig; + + iio_trigger_poll(trig, timestamp); + + return IRQ_HANDLED; +} + +IIO_EVENT_SH(data_rdy_trig, &adis16201_data_rdy_trig_poll); + +static DEVICE_ATTR(name, S_IRUGO, iio_trigger_read_name, NULL); + +static struct attribute *adis16201_trigger_attrs[] = { + &dev_attr_name.attr, + NULL, +}; + +static const struct attribute_group adis16201_trigger_attr_group = { + .attrs = adis16201_trigger_attrs, +}; + +/** + * adis16201_data_rdy_trigger_set_state() set datardy interrupt state + **/ +static int adis16201_data_rdy_trigger_set_state(struct iio_trigger *trig, + bool state) +{ + struct adis16201_state *st = trig->private_data; + struct iio_dev *indio_dev = st->indio_dev; + int ret = 0; + + dev_dbg(&indio_dev->dev, "%s (%d)\n", __func__, state); + ret = adis16201_set_irq(&st->indio_dev->dev, state); + if (state == false) { + iio_remove_event_from_list(&iio_event_data_rdy_trig, + &indio_dev->interrupts[0] + ->ev_list); + flush_scheduled_work(); + } else { + iio_add_event_to_list(&iio_event_data_rdy_trig, + &indio_dev->interrupts[0]->ev_list); + } + return ret; +} + +/** + * adis16201_trig_try_reen() try renabling irq for data rdy trigger + * @trig: the datardy trigger + **/ +static int adis16201_trig_try_reen(struct iio_trigger *trig) +{ + struct adis16201_state *st = trig->private_data; + enable_irq(st->us->irq); + return 0; +} + +int adis16201_probe_trigger(struct iio_dev *indio_dev) +{ + int ret; + struct adis16201_state *st = indio_dev->dev_data; + + st->trig = iio_allocate_trigger(); + st->trig->name = kasprintf(GFP_KERNEL, + "adis16201-dev%d", + indio_dev->id); + if (!st->trig->name) { + ret = -ENOMEM; + goto error_free_trig; + } + st->trig->dev.parent = &st->us->dev; + st->trig->owner = THIS_MODULE; + st->trig->private_data = st; + st->trig->set_trigger_state = &adis16201_data_rdy_trigger_set_state; + st->trig->try_reenable = &adis16201_trig_try_reen; + st->trig->control_attrs = &adis16201_trigger_attr_group; + ret = iio_trigger_register(st->trig); + + /* select default trigger */ + indio_dev->trig = st->trig; + if (ret) + goto error_free_trig_name; + + return 0; + +error_free_trig_name: + kfree(st->trig->name); +error_free_trig: + iio_free_trigger(st->trig); + + return ret; +} + +void adis16201_remove_trigger(struct iio_dev *indio_dev) +{ + struct adis16201_state *state = indio_dev->dev_data; + + iio_trigger_unregister(state->trig); + kfree(state->trig->name); + iio_free_trigger(state->trig); +} -- cgit v1.2.3 From f11ba4f5774957415aa15eea7c8c8717126907ee Mon Sep 17 00:00:00 2001 From: Barry Song Date: Wed, 27 Oct 2010 21:43:50 -0400 Subject: staging: iio: new adis16203 driver IIO driver for Programmable 360 Degrees Inclinometer adis16203 parts. Signed-off-by: Barry Song Signed-off-by: Michael Hennerich Acked-by: Jonathan Cameron Signed-off-by: Mike Frysinger Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/accel/Kconfig | 9 + drivers/staging/iio/accel/Makefile | 4 + drivers/staging/iio/accel/adis16203.h | 143 +++++++ drivers/staging/iio/accel/adis16203_core.c | 568 ++++++++++++++++++++++++++ drivers/staging/iio/accel/adis16203_ring.c | 211 ++++++++++ drivers/staging/iio/accel/adis16203_trigger.c | 122 ++++++ 6 files changed, 1057 insertions(+) create mode 100644 drivers/staging/iio/accel/adis16203.h create mode 100644 drivers/staging/iio/accel/adis16203_core.c create mode 100644 drivers/staging/iio/accel/adis16203_ring.c create mode 100644 drivers/staging/iio/accel/adis16203_trigger.c diff --git a/drivers/staging/iio/accel/Kconfig b/drivers/staging/iio/accel/Kconfig index 0b87557a554e..cc057c640e64 100644 --- a/drivers/staging/iio/accel/Kconfig +++ b/drivers/staging/iio/accel/Kconfig @@ -12,6 +12,15 @@ config ADIS16201 Say yes here to build support for Analog Devices adis16201 dual-axis digital inclinometer and accelerometer. +config ADIS16203 + tristate "Analog Devices ADIS16203 Programmable 360 Degrees Inclinometer" + depends on SPI + select IIO_TRIGGER if IIO_RING_BUFFER + select IIO_SW_RING if IIO_RING_BUFFER + help + Say yes here to build support for Analog Devices adis16203 Programmable + 360 Degrees Inclinometer. + config ADIS16209 tristate "Analog Devices ADIS16209 Dual-Axis Digital Inclinometer and Accelerometer" depends on SPI diff --git a/drivers/staging/iio/accel/Makefile b/drivers/staging/iio/accel/Makefile index 4a22a013cff8..76cc92fed23d 100644 --- a/drivers/staging/iio/accel/Makefile +++ b/drivers/staging/iio/accel/Makefile @@ -6,6 +6,10 @@ adis16201-y := adis16201_core.o adis16201-$(CONFIG_IIO_RING_BUFFER) += adis16201_ring.o adis16201_trigger.o obj-$(CONFIG_ADIS16201) += adis16201.o +adis16203-y := adis16203_core.o +adis16203-$(CONFIG_IIO_RING_BUFFER) += adis16203_ring.o adis16203_trigger.o +obj-$(CONFIG_ADIS16203) += adis16203.o + adis16209-y := adis16209_core.o adis16209-$(CONFIG_IIO_RING_BUFFER) += adis16209_ring.o adis16209_trigger.o obj-$(CONFIG_ADIS16209) += adis16209.o diff --git a/drivers/staging/iio/accel/adis16203.h b/drivers/staging/iio/accel/adis16203.h new file mode 100644 index 000000000000..b39323eac9e3 --- /dev/null +++ b/drivers/staging/iio/accel/adis16203.h @@ -0,0 +1,143 @@ +#ifndef SPI_ADIS16203_H_ +#define SPI_ADIS16203_H_ + +#define ADIS16203_STARTUP_DELAY 220 /* ms */ + +#define ADIS16203_READ_REG(a) a +#define ADIS16203_WRITE_REG(a) ((a) | 0x80) + +#define ADIS16203_FLASH_CNT 0x00 /* Flash memory write count */ +#define ADIS16203_SUPPLY_OUT 0x02 /* Output, power supply */ +#define ADIS16203_AUX_ADC 0x08 /* Output, auxiliary ADC input */ +#define ADIS16203_TEMP_OUT 0x0A /* Output, temperature */ +#define ADIS16203_XINCL_OUT 0x0C /* Output, x-axis inclination */ +#define ADIS16203_YINCL_OUT 0x0E /* Output, y-axis inclination */ +#define ADIS16203_INCL_NULL 0x18 /* Incline null calibration */ +#define ADIS16203_ALM_MAG1 0x20 /* Alarm 1 amplitude threshold */ +#define ADIS16203_ALM_MAG2 0x22 /* Alarm 2 amplitude threshold */ +#define ADIS16203_ALM_SMPL1 0x24 /* Alarm 1, sample period */ +#define ADIS16203_ALM_SMPL2 0x26 /* Alarm 2, sample period */ +#define ADIS16203_ALM_CTRL 0x28 /* Alarm control */ +#define ADIS16203_AUX_DAC 0x30 /* Auxiliary DAC data */ +#define ADIS16203_GPIO_CTRL 0x32 /* General-purpose digital input/output control */ +#define ADIS16203_MSC_CTRL 0x34 /* Miscellaneous control */ +#define ADIS16203_SMPL_PRD 0x36 /* Internal sample period (rate) control */ +#define ADIS16203_AVG_CNT 0x38 /* Operation, filter configuration */ +#define ADIS16203_SLP_CNT 0x3A /* Operation, sleep mode control */ +#define ADIS16203_DIAG_STAT 0x3C /* Diagnostics, system status register */ +#define ADIS16203_GLOB_CMD 0x3E /* Operation, system command register */ + +#define ADIS16203_OUTPUTS 5 + +/* MSC_CTRL */ +#define ADIS16203_MSC_CTRL_PWRUP_SELF_TEST (1 << 10) /* Self-test at power-on: 1 = disabled, 0 = enabled */ +#define ADIS16203_MSC_CTRL_REVERSE_ROT_EN (1 << 9) /* Reverses rotation of both inclination outputs */ +#define ADIS16203_MSC_CTRL_SELF_TEST_EN (1 << 8) /* Self-test enable */ +#define ADIS16203_MSC_CTRL_DATA_RDY_EN (1 << 2) /* Data-ready enable: 1 = enabled, 0 = disabled */ +#define ADIS16203_MSC_CTRL_ACTIVE_HIGH (1 << 1) /* Data-ready polarity: 1 = active high, 0 = active low */ +#define ADIS16203_MSC_CTRL_DATA_RDY_DIO1 (1 << 0) /* Data-ready line selection: 1 = DIO1, 0 = DIO0 */ + +/* DIAG_STAT */ +#define ADIS16203_DIAG_STAT_ALARM2 (1<<9) /* Alarm 2 status: 1 = alarm active, 0 = alarm inactive */ +#define ADIS16203_DIAG_STAT_ALARM1 (1<<8) /* Alarm 1 status: 1 = alarm active, 0 = alarm inactive */ +#define ADIS16203_DIAG_STAT_SELFTEST_FAIL (1<<5) /* Self-test diagnostic error flag */ +#define ADIS16203_DIAG_STAT_SPI_FAIL (1<<3) /* SPI communications failure */ +#define ADIS16203_DIAG_STAT_FLASH_UPT (1<<2) /* Flash update failure */ +#define ADIS16203_DIAG_STAT_POWER_HIGH (1<<1) /* Power supply above 3.625 V */ +#define ADIS16203_DIAG_STAT_POWER_LOW (1<<0) /* Power supply below 3.15 V */ + +/* GLOB_CMD */ +#define ADIS16203_GLOB_CMD_SW_RESET (1<<7) +#define ADIS16203_GLOB_CMD_CLEAR_STAT (1<<4) +#define ADIS16203_GLOB_CMD_FACTORY_CAL (1<<1) + +#define ADIS16203_MAX_TX 12 +#define ADIS16203_MAX_RX 10 + +#define ADIS16203_ERROR_ACTIVE (1<<14) + +/** + * struct adis16203_state - device instance specific data + * @us: actual spi_device + * @work_trigger_to_ring: bh for triggered event handling + * @inter: used to check if new interrupt has been triggered + * @last_timestamp: passing timestamp from th to bh of interrupt handler + * @indio_dev: industrial I/O device structure + * @trig: data ready trigger registered with iio + * @tx: transmit buffer + * @rx: recieve buffer + * @buf_lock: mutex to protect tx and rx + **/ +struct adis16203_state { + struct spi_device *us; + struct work_struct work_trigger_to_ring; + s64 last_timestamp; + struct iio_dev *indio_dev; + struct iio_trigger *trig; + u8 *tx; + u8 *rx; + struct mutex buf_lock; +}; + +int adis16203_set_irq(struct device *dev, bool enable); + +#ifdef CONFIG_IIO_RING_BUFFER +enum adis16203_scan { + ADIS16203_SCAN_SUPPLY, + ADIS16203_SCAN_AUX_ADC, + ADIS16203_SCAN_TEMP, + ADIS16203_SCAN_INCLI_X, + ADIS16203_SCAN_INCLI_Y, +}; + +void adis16203_remove_trigger(struct iio_dev *indio_dev); +int adis16203_probe_trigger(struct iio_dev *indio_dev); + +ssize_t adis16203_read_data_from_ring(struct device *dev, + struct device_attribute *attr, + char *buf); + +int adis16203_configure_ring(struct iio_dev *indio_dev); +void adis16203_unconfigure_ring(struct iio_dev *indio_dev); + +int adis16203_initialize_ring(struct iio_ring_buffer *ring); +void adis16203_uninitialize_ring(struct iio_ring_buffer *ring); +#else /* CONFIG_IIO_RING_BUFFER */ + +static inline void adis16203_remove_trigger(struct iio_dev *indio_dev) +{ +} + +static inline int adis16203_probe_trigger(struct iio_dev *indio_dev) +{ + return 0; +} + +static inline ssize_t +adis16203_read_data_from_ring(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + return 0; +} + +static int adis16203_configure_ring(struct iio_dev *indio_dev) +{ + return 0; +} + +static inline void adis16203_unconfigure_ring(struct iio_dev *indio_dev) +{ +} + +static inline int adis16203_initialize_ring(struct iio_ring_buffer *ring) +{ + return 0; +} + +static inline void adis16203_uninitialize_ring(struct iio_ring_buffer *ring) +{ +} + +#endif /* CONFIG_IIO_RING_BUFFER */ +#endif /* SPI_ADIS16203_H_ */ diff --git a/drivers/staging/iio/accel/adis16203_core.c b/drivers/staging/iio/accel/adis16203_core.c new file mode 100644 index 000000000000..b57f19087a93 --- /dev/null +++ b/drivers/staging/iio/accel/adis16203_core.c @@ -0,0 +1,568 @@ +/* + * ADIS16203 Programmable Digital Vibration Sensor driver + * + * Copyright 2010 Analog Devices Inc. + * + * Licensed under the GPL-2 or later. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../iio.h" +#include "../sysfs.h" +#include "accel.h" +#include "inclinometer.h" +#include "../gyro/gyro.h" +#include "../adc/adc.h" + +#include "adis16203.h" + +#define DRIVER_NAME "adis16203" + +static int adis16203_check_status(struct device *dev); + +/** + * adis16203_spi_write_reg_8() - write single byte to a register + * @dev: device associated with child of actual device (iio_dev or iio_trig) + * @reg_address: the address of the register to be written + * @val: the value to write + **/ +static int adis16203_spi_write_reg_8(struct device *dev, + u8 reg_address, + u8 val) +{ + int ret; + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct adis16203_state *st = iio_dev_get_devdata(indio_dev); + + mutex_lock(&st->buf_lock); + st->tx[0] = ADIS16203_WRITE_REG(reg_address); + st->tx[1] = val; + + ret = spi_write(st->us, st->tx, 2); + mutex_unlock(&st->buf_lock); + + return ret; +} + +/** + * adis16203_spi_write_reg_16() - write 2 bytes to a pair of registers + * @dev: device associated with child of actual device (iio_dev or iio_trig) + * @reg_address: the address of the lower of the two registers. Second register + * is assumed to have address one greater. + * @val: value to be written + **/ +static int adis16203_spi_write_reg_16(struct device *dev, + u8 lower_reg_address, + u16 value) +{ + int ret; + struct spi_message msg; + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct adis16203_state *st = iio_dev_get_devdata(indio_dev); + struct spi_transfer xfers[] = { + { + .tx_buf = st->tx, + .bits_per_word = 8, + .len = 2, + .cs_change = 1, + }, { + .tx_buf = st->tx + 2, + .bits_per_word = 8, + .len = 2, + .cs_change = 1, + }, + }; + + mutex_lock(&st->buf_lock); + st->tx[0] = ADIS16203_WRITE_REG(lower_reg_address); + st->tx[1] = value & 0xFF; + st->tx[2] = ADIS16203_WRITE_REG(lower_reg_address + 1); + st->tx[3] = (value >> 8) & 0xFF; + + spi_message_init(&msg); + spi_message_add_tail(&xfers[0], &msg); + spi_message_add_tail(&xfers[1], &msg); + ret = spi_sync(st->us, &msg); + mutex_unlock(&st->buf_lock); + + return ret; +} + +/** + * adis16203_spi_read_reg_16() - read 2 bytes from a 16-bit register + * @dev: device associated with child of actual device (iio_dev or iio_trig) + * @reg_address: the address of the lower of the two registers. Second register + * is assumed to have address one greater. + * @val: somewhere to pass back the value read + **/ +static int adis16203_spi_read_reg_16(struct device *dev, + u8 lower_reg_address, + u16 *val) +{ + struct spi_message msg; + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct adis16203_state *st = iio_dev_get_devdata(indio_dev); + int ret; + struct spi_transfer xfers[] = { + { + .tx_buf = st->tx, + .bits_per_word = 8, + .len = 2, + .cs_change = 1, + .delay_usecs = 20, + }, { + .rx_buf = st->rx, + .bits_per_word = 8, + .len = 2, + .cs_change = 1, + .delay_usecs = 20, + }, + }; + + mutex_lock(&st->buf_lock); + st->tx[0] = ADIS16203_READ_REG(lower_reg_address); + st->tx[1] = 0; + + spi_message_init(&msg); + spi_message_add_tail(&xfers[0], &msg); + spi_message_add_tail(&xfers[1], &msg); + ret = spi_sync(st->us, &msg); + if (ret) { + dev_err(&st->us->dev, "problem when reading 16 bit register 0x%02X", + lower_reg_address); + goto error_ret; + } + *val = (st->rx[0] << 8) | st->rx[1]; + +error_ret: + mutex_unlock(&st->buf_lock); + return ret; +} + +static ssize_t adis16203_read_12bit_unsigned(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + int ret; + u16 val = 0; + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + + ret = adis16203_spi_read_reg_16(dev, this_attr->address, &val); + if (ret) + return ret; + + if (val & ADIS16203_ERROR_ACTIVE) + adis16203_check_status(dev); + + return sprintf(buf, "%u\n", val & 0x0FFF); +} + +static ssize_t adis16203_read_temp(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + ssize_t ret; + u16 val; + + /* Take the iio_dev status lock */ + mutex_lock(&indio_dev->mlock); + + ret = adis16203_spi_read_reg_16(dev, ADIS16203_TEMP_OUT, (u16 *)&val); + if (ret) + goto error_ret; + + if (val & ADIS16203_ERROR_ACTIVE) + adis16203_check_status(dev); + + val &= 0xFFF; + ret = sprintf(buf, "%d\n", val); + +error_ret: + mutex_unlock(&indio_dev->mlock); + return ret; +} + +static ssize_t adis16203_read_14bit_signed(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + s16 val = 0; + ssize_t ret; + + mutex_lock(&indio_dev->mlock); + + ret = adis16203_spi_read_reg_16(dev, this_attr->address, (u16 *)&val); + if (!ret) { + if (val & ADIS16203_ERROR_ACTIVE) + adis16203_check_status(dev); + + val = ((s16)(val << 2) >> 2); + ret = sprintf(buf, "%d\n", val); + } + + mutex_unlock(&indio_dev->mlock); + + return ret; +} + +static ssize_t adis16203_write_16bit(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + int ret; + long val; + + ret = strict_strtol(buf, 10, &val); + if (ret) + goto error_ret; + ret = adis16203_spi_write_reg_16(dev, this_attr->address, val); + +error_ret: + return ret ? ret : len; +} + +static int adis16203_reset(struct device *dev) +{ + int ret; + ret = adis16203_spi_write_reg_8(dev, + ADIS16203_GLOB_CMD, + ADIS16203_GLOB_CMD_SW_RESET); + if (ret) + dev_err(dev, "problem resetting device"); + + return ret; +} + +static ssize_t adis16203_write_reset(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t len) +{ + if (len < 1) + return -EINVAL; + switch (buf[0]) { + case '1': + case 'y': + case 'Y': + return adis16203_reset(dev); + } + return -EINVAL; +} + +int adis16203_set_irq(struct device *dev, bool enable) +{ + int ret = 0; + u16 msc; + + ret = adis16203_spi_read_reg_16(dev, ADIS16203_MSC_CTRL, &msc); + if (ret) + goto error_ret; + + msc |= ADIS16203_MSC_CTRL_ACTIVE_HIGH; + msc &= ~ADIS16203_MSC_CTRL_DATA_RDY_DIO1; + if (enable) + msc |= ADIS16203_MSC_CTRL_DATA_RDY_EN; + else + msc &= ~ADIS16203_MSC_CTRL_DATA_RDY_EN; + + ret = adis16203_spi_write_reg_16(dev, ADIS16203_MSC_CTRL, msc); + +error_ret: + return ret; +} + +static int adis16203_check_status(struct device *dev) +{ + u16 status; + int ret; + + ret = adis16203_spi_read_reg_16(dev, ADIS16203_DIAG_STAT, &status); + if (ret < 0) { + dev_err(dev, "Reading status failed\n"); + goto error_ret; + } + ret = status & 0x1F; + + if (status & ADIS16203_DIAG_STAT_SELFTEST_FAIL) + dev_err(dev, "Self test failure\n"); + if (status & ADIS16203_DIAG_STAT_SPI_FAIL) + dev_err(dev, "SPI failure\n"); + if (status & ADIS16203_DIAG_STAT_FLASH_UPT) + dev_err(dev, "Flash update failed\n"); + if (status & ADIS16203_DIAG_STAT_POWER_HIGH) + dev_err(dev, "Power supply above 3.625V\n"); + if (status & ADIS16203_DIAG_STAT_POWER_LOW) + dev_err(dev, "Power supply below 3.15V\n"); + +error_ret: + return ret; +} + +static int adis16203_self_test(struct device *dev) +{ + int ret; + ret = adis16203_spi_write_reg_16(dev, + ADIS16203_MSC_CTRL, + ADIS16203_MSC_CTRL_SELF_TEST_EN); + if (ret) { + dev_err(dev, "problem starting self test"); + goto err_ret; + } + + adis16203_check_status(dev); + +err_ret: + return ret; +} + +static int adis16203_initial_setup(struct adis16203_state *st) +{ + int ret; + struct device *dev = &st->indio_dev->dev; + + /* Disable IRQ */ + ret = adis16203_set_irq(dev, false); + if (ret) { + dev_err(dev, "disable irq failed"); + goto err_ret; + } + + /* Do self test */ + ret = adis16203_self_test(dev); + if (ret) { + dev_err(dev, "self test failure"); + goto err_ret; + } + + /* Read status register to check the result */ + ret = adis16203_check_status(dev); + if (ret) { + adis16203_reset(dev); + dev_err(dev, "device not playing ball -> reset"); + msleep(ADIS16203_STARTUP_DELAY); + ret = adis16203_check_status(dev); + if (ret) { + dev_err(dev, "giving up"); + goto err_ret; + } + } + + printk(KERN_INFO DRIVER_NAME ": at CS%d (irq %d)\n", + st->us->chip_select, st->us->irq); + +err_ret: + return ret; +} + +static IIO_DEV_ATTR_IN_NAMED_RAW(0, supply, adis16203_read_12bit_unsigned, + ADIS16203_SUPPLY_OUT); +static IIO_CONST_ATTR(in0_supply_scale, "0.00122"); +static IIO_DEV_ATTR_IN_RAW(1, adis16203_read_12bit_unsigned, + ADIS16203_AUX_ADC); +static IIO_CONST_ATTR(in1_scale, "0.00061"); + +static IIO_DEV_ATTR_INCLI_X(adis16203_read_14bit_signed, + ADIS16203_XINCL_OUT); +static IIO_DEV_ATTR_INCLI_Y(adis16203_read_14bit_signed, + ADIS16203_YINCL_OUT); +static IIO_DEV_ATTR_INCLI_X_OFFSET(S_IWUSR | S_IRUGO, + adis16203_read_14bit_signed, + adis16203_write_16bit, + ADIS16203_INCL_NULL); +static IIO_CONST_ATTR(incli_scale, "0.025"); + +static IIO_DEV_ATTR_TEMP_RAW(adis16203_read_temp); +static IIO_CONST_ATTR(temp_offset, "25"); +static IIO_CONST_ATTR(temp_scale, "-0.47"); + +static IIO_DEVICE_ATTR(reset, S_IWUSR, NULL, adis16203_write_reset, 0); + +static IIO_CONST_ATTR(name, "adis16203"); + +static struct attribute *adis16203_event_attributes[] = { + NULL +}; + +static struct attribute_group adis16203_event_attribute_group = { + .attrs = adis16203_event_attributes, +}; + +static struct attribute *adis16203_attributes[] = { + &iio_dev_attr_in0_supply_raw.dev_attr.attr, + &iio_const_attr_in0_supply_scale.dev_attr.attr, + &iio_dev_attr_temp_raw.dev_attr.attr, + &iio_const_attr_temp_offset.dev_attr.attr, + &iio_const_attr_temp_scale.dev_attr.attr, + &iio_dev_attr_reset.dev_attr.attr, + &iio_const_attr_name.dev_attr.attr, + &iio_dev_attr_in1_raw.dev_attr.attr, + &iio_const_attr_in1_scale.dev_attr.attr, + &iio_dev_attr_incli_x_raw.dev_attr.attr, + &iio_dev_attr_incli_y_raw.dev_attr.attr, + &iio_dev_attr_incli_x_offset.dev_attr.attr, + &iio_const_attr_incli_scale.dev_attr.attr, + NULL +}; + +static const struct attribute_group adis16203_attribute_group = { + .attrs = adis16203_attributes, +}; + +static int __devinit adis16203_probe(struct spi_device *spi) +{ + int ret, regdone = 0; + struct adis16203_state *st = kzalloc(sizeof *st, GFP_KERNEL); + if (!st) { + ret = -ENOMEM; + goto error_ret; + } + /* this is only used for removal purposes */ + spi_set_drvdata(spi, st); + + /* Allocate the comms buffers */ + st->rx = kzalloc(sizeof(*st->rx)*ADIS16203_MAX_RX, GFP_KERNEL); + if (st->rx == NULL) { + ret = -ENOMEM; + goto error_free_st; + } + st->tx = kzalloc(sizeof(*st->tx)*ADIS16203_MAX_TX, GFP_KERNEL); + if (st->tx == NULL) { + ret = -ENOMEM; + goto error_free_rx; + } + st->us = spi; + mutex_init(&st->buf_lock); + /* setup the industrialio driver allocated elements */ + st->indio_dev = iio_allocate_device(); + if (st->indio_dev == NULL) { + ret = -ENOMEM; + goto error_free_tx; + } + + st->indio_dev->dev.parent = &spi->dev; + st->indio_dev->num_interrupt_lines = 1; + st->indio_dev->event_attrs = &adis16203_event_attribute_group; + st->indio_dev->attrs = &adis16203_attribute_group; + st->indio_dev->dev_data = (void *)(st); + st->indio_dev->driver_module = THIS_MODULE; + st->indio_dev->modes = INDIO_DIRECT_MODE; + + ret = adis16203_configure_ring(st->indio_dev); + if (ret) + goto error_free_dev; + + ret = iio_device_register(st->indio_dev); + if (ret) + goto error_unreg_ring_funcs; + regdone = 1; + + ret = adis16203_initialize_ring(st->indio_dev->ring); + if (ret) { + printk(KERN_ERR "failed to initialize the ring\n"); + goto error_unreg_ring_funcs; + } + + if (spi->irq) { + ret = iio_register_interrupt_line(spi->irq, + st->indio_dev, + 0, + IRQF_TRIGGER_RISING, + "adis16203"); + if (ret) + goto error_uninitialize_ring; + + ret = adis16203_probe_trigger(st->indio_dev); + if (ret) + goto error_unregister_line; + } + + /* Get the device into a sane initial state */ + ret = adis16203_initial_setup(st); + if (ret) + goto error_remove_trigger; + return 0; + +error_remove_trigger: + adis16203_remove_trigger(st->indio_dev); +error_unregister_line: + if (spi->irq) + iio_unregister_interrupt_line(st->indio_dev, 0); +error_uninitialize_ring: + adis16203_uninitialize_ring(st->indio_dev->ring); +error_unreg_ring_funcs: + adis16203_unconfigure_ring(st->indio_dev); +error_free_dev: + if (regdone) + iio_device_unregister(st->indio_dev); + else + iio_free_device(st->indio_dev); +error_free_tx: + kfree(st->tx); +error_free_rx: + kfree(st->rx); +error_free_st: + kfree(st); +error_ret: + return ret; +} + +static int adis16203_remove(struct spi_device *spi) +{ + struct adis16203_state *st = spi_get_drvdata(spi); + struct iio_dev *indio_dev = st->indio_dev; + + flush_scheduled_work(); + + adis16203_remove_trigger(indio_dev); + if (spi->irq) + iio_unregister_interrupt_line(indio_dev, 0); + + adis16203_uninitialize_ring(indio_dev->ring); + iio_device_unregister(indio_dev); + adis16203_unconfigure_ring(indio_dev); + kfree(st->tx); + kfree(st->rx); + kfree(st); + + return 0; +} + +static struct spi_driver adis16203_driver = { + .driver = { + .name = "adis16203", + .owner = THIS_MODULE, + }, + .probe = adis16203_probe, + .remove = __devexit_p(adis16203_remove), +}; + +static __init int adis16203_init(void) +{ + return spi_register_driver(&adis16203_driver); +} +module_init(adis16203_init); + +static __exit void adis16203_exit(void) +{ + spi_unregister_driver(&adis16203_driver); +} +module_exit(adis16203_exit); + +MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>"); +MODULE_DESCRIPTION("Analog Devices ADIS16203 Programmable Digital Vibration Sensor driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/staging/iio/accel/adis16203_ring.c b/drivers/staging/iio/accel/adis16203_ring.c new file mode 100644 index 000000000000..3d774f7efa25 --- /dev/null +++ b/drivers/staging/iio/accel/adis16203_ring.c @@ -0,0 +1,211 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../iio.h" +#include "../sysfs.h" +#include "../ring_sw.h" +#include "accel.h" +#include "../trigger.h" +#include "adis16203.h" + +static IIO_SCAN_EL_C(in_supply, ADIS16203_SCAN_SUPPLY, ADIS16203_SUPPLY_OUT, NULL); +static IIO_CONST_ATTR_SCAN_EL_TYPE(in_supply, u, 12, 16); +static IIO_SCAN_EL_C(in0, ADIS16203_SCAN_AUX_ADC, ADIS16203_AUX_ADC, NULL); +static IIO_CONST_ATTR_SCAN_EL_TYPE(in0, u, 12, 16); +static IIO_SCAN_EL_C(temp, ADIS16203_SCAN_TEMP, ADIS16203_TEMP_OUT, NULL); +static IIO_CONST_ATTR_SCAN_EL_TYPE(temp, u, 12, 16); +static IIO_SCAN_EL_C(incli_x, ADIS16203_SCAN_INCLI_X, + ADIS16203_XINCL_OUT, NULL); +static IIO_SCAN_EL_C(incli_y, ADIS16203_SCAN_INCLI_Y, + ADIS16203_YINCL_OUT, NULL); +static IIO_CONST_ATTR_SCAN_EL_TYPE(incli, s, 14, 16); +static IIO_SCAN_EL_TIMESTAMP(5); +static IIO_CONST_ATTR_SCAN_EL_TYPE(timestamp, s, 64, 64); + +static struct attribute *adis16203_scan_el_attrs[] = { + &iio_scan_el_in_supply.dev_attr.attr, + &iio_const_attr_in_supply_index.dev_attr.attr, + &iio_const_attr_in_supply_type.dev_attr.attr, + &iio_scan_el_in0.dev_attr.attr, + &iio_const_attr_in0_index.dev_attr.attr, + &iio_const_attr_in0_type.dev_attr.attr, + &iio_scan_el_temp.dev_attr.attr, + &iio_const_attr_temp_index.dev_attr.attr, + &iio_const_attr_temp_type.dev_attr.attr, + &iio_scan_el_incli_x.dev_attr.attr, + &iio_const_attr_incli_x_index.dev_attr.attr, + &iio_scan_el_incli_y.dev_attr.attr, + &iio_const_attr_incli_y_index.dev_attr.attr, + &iio_const_attr_incli_type.dev_attr.attr, + &iio_scan_el_timestamp.dev_attr.attr, + &iio_const_attr_timestamp_index.dev_attr.attr, + &iio_const_attr_timestamp_type.dev_attr.attr, + NULL, +}; + +static struct attribute_group adis16203_scan_el_group = { + .attrs = adis16203_scan_el_attrs, + .name = "scan_elements", +}; + +/** + * adis16203_poll_func_th() top half interrupt handler called by trigger + * @private_data: iio_dev + **/ +static void adis16203_poll_func_th(struct iio_dev *indio_dev, s64 timestamp) +{ + struct adis16203_state *st = iio_dev_get_devdata(indio_dev); + st->last_timestamp = timestamp; + schedule_work(&st->work_trigger_to_ring); +} + +/** + * adis16203_read_ring_data() read data registers which will be placed into ring + * @dev: device associated with child of actual device (iio_dev or iio_trig) + * @rx: somewhere to pass back the value read + **/ +static int adis16203_read_ring_data(struct device *dev, u8 *rx) +{ + struct spi_message msg; + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct adis16203_state *st = iio_dev_get_devdata(indio_dev); + struct spi_transfer xfers[ADIS16203_OUTPUTS + 1]; + int ret; + int i; + + mutex_lock(&st->buf_lock); + + spi_message_init(&msg); + + memset(xfers, 0, sizeof(xfers)); + for (i = 0; i <= ADIS16203_OUTPUTS; i++) { + xfers[i].bits_per_word = 8; + xfers[i].cs_change = 1; + xfers[i].len = 2; + xfers[i].delay_usecs = 20; + xfers[i].tx_buf = st->tx + 2 * i; + if (i < 1) /* SUPPLY_OUT: 0x02, AUX_ADC: 0x08 */ + st->tx[2 * i] = ADIS16203_READ_REG(ADIS16203_SUPPLY_OUT + 2 * i); + else + st->tx[2 * i] = ADIS16203_READ_REG(ADIS16203_SUPPLY_OUT + 2 * i + 6); + st->tx[2 * i + 1] = 0; + if (i >= 1) + xfers[i].rx_buf = rx + 2 * (i - 1); + spi_message_add_tail(&xfers[i], &msg); + } + + ret = spi_sync(st->us, &msg); + if (ret) + dev_err(&st->us->dev, "problem when burst reading"); + + mutex_unlock(&st->buf_lock); + + return ret; +} + +/* Whilst this makes a lot of calls to iio_sw_ring functions - it is to device + * specific to be rolled into the core. + */ +static void adis16203_trigger_bh_to_ring(struct work_struct *work_s) +{ + struct adis16203_state *st + = container_of(work_s, struct adis16203_state, + work_trigger_to_ring); + struct iio_ring_buffer *ring = st->indio_dev->ring; + + int i = 0; + s16 *data; + size_t datasize = ring->access.get_bytes_per_datum(ring); + + data = kmalloc(datasize, GFP_KERNEL); + if (data == NULL) { + dev_err(&st->us->dev, "memory alloc failed in ring bh"); + return; + } + + if (ring->scan_count) + if (adis16203_read_ring_data(&st->indio_dev->dev, st->rx) >= 0) + for (; i < ring->scan_count; i++) + data[i] = be16_to_cpup( + (__be16 *)&(st->rx[i*2])); + + /* Guaranteed to be aligned with 8 byte boundary */ + if (ring->scan_timestamp) + *((s64 *)(data + ((i + 3)/4)*4)) = st->last_timestamp; + + ring->access.store_to(ring, + (u8 *)data, + st->last_timestamp); + + iio_trigger_notify_done(st->indio_dev->trig); + kfree(data); + + return; +} + +void adis16203_unconfigure_ring(struct iio_dev *indio_dev) +{ + kfree(indio_dev->pollfunc); + iio_sw_rb_free(indio_dev->ring); +} + +int adis16203_configure_ring(struct iio_dev *indio_dev) +{ + int ret = 0; + struct adis16203_state *st = indio_dev->dev_data; + struct iio_ring_buffer *ring; + INIT_WORK(&st->work_trigger_to_ring, adis16203_trigger_bh_to_ring); + + ring = iio_sw_rb_allocate(indio_dev); + if (!ring) { + ret = -ENOMEM; + return ret; + } + indio_dev->ring = ring; + /* Effectively select the ring buffer implementation */ + iio_ring_sw_register_funcs(&ring->access); + ring->bpe = 2; + ring->scan_el_attrs = &adis16203_scan_el_group; + ring->scan_timestamp = true; + ring->preenable = &iio_sw_ring_preenable; + ring->postenable = &iio_triggered_ring_postenable; + ring->predisable = &iio_triggered_ring_predisable; + ring->owner = THIS_MODULE; + + /* Set default scan mode */ + iio_scan_mask_set(ring, iio_scan_el_in_supply.number); + iio_scan_mask_set(ring, iio_scan_el_temp.number); + iio_scan_mask_set(ring, iio_scan_el_in0.number); + iio_scan_mask_set(ring, iio_scan_el_incli_x.number); + iio_scan_mask_set(ring, iio_scan_el_incli_y.number); + + ret = iio_alloc_pollfunc(indio_dev, NULL, &adis16203_poll_func_th); + if (ret) + goto error_iio_sw_rb_free; + + indio_dev->modes |= INDIO_RING_TRIGGERED; + return 0; + +error_iio_sw_rb_free: + iio_sw_rb_free(indio_dev->ring); + return ret; +} + +int adis16203_initialize_ring(struct iio_ring_buffer *ring) +{ + return iio_ring_buffer_register(ring, 0); +} + +void adis16203_uninitialize_ring(struct iio_ring_buffer *ring) +{ + iio_ring_buffer_unregister(ring); +} diff --git a/drivers/staging/iio/accel/adis16203_trigger.c b/drivers/staging/iio/accel/adis16203_trigger.c new file mode 100644 index 000000000000..50be51c25dc2 --- /dev/null +++ b/drivers/staging/iio/accel/adis16203_trigger.c @@ -0,0 +1,122 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../iio.h" +#include "../sysfs.h" +#include "../trigger.h" +#include "adis16203.h" + +/** + * adis16203_data_rdy_trig_poll() the event handler for the data rdy trig + **/ +static int adis16203_data_rdy_trig_poll(struct iio_dev *dev_info, + int index, + s64 timestamp, + int no_test) +{ + struct adis16203_state *st = iio_dev_get_devdata(dev_info); + struct iio_trigger *trig = st->trig; + + iio_trigger_poll(trig, timestamp); + + return IRQ_HANDLED; +} + +IIO_EVENT_SH(data_rdy_trig, &adis16203_data_rdy_trig_poll); + +static DEVICE_ATTR(name, S_IRUGO, iio_trigger_read_name, NULL); + +static struct attribute *adis16203_trigger_attrs[] = { + &dev_attr_name.attr, + NULL, +}; + +static const struct attribute_group adis16203_trigger_attr_group = { + .attrs = adis16203_trigger_attrs, +}; + +/** + * adis16203_data_rdy_trigger_set_state() set datardy interrupt state + **/ +static int adis16203_data_rdy_trigger_set_state(struct iio_trigger *trig, + bool state) +{ + struct adis16203_state *st = trig->private_data; + struct iio_dev *indio_dev = st->indio_dev; + int ret = 0; + + dev_dbg(&indio_dev->dev, "%s (%d)\n", __func__, state); + ret = adis16203_set_irq(&st->indio_dev->dev, state); + if (state == false) { + iio_remove_event_from_list(&iio_event_data_rdy_trig, + &indio_dev->interrupts[0] + ->ev_list); + flush_scheduled_work(); + } else { + iio_add_event_to_list(&iio_event_data_rdy_trig, + &indio_dev->interrupts[0]->ev_list); + } + return ret; +} + +/** + * adis16203_trig_try_reen() try renabling irq for data rdy trigger + * @trig: the datardy trigger + **/ +static int adis16203_trig_try_reen(struct iio_trigger *trig) +{ + struct adis16203_state *st = trig->private_data; + enable_irq(st->us->irq); + return 0; +} + +int adis16203_probe_trigger(struct iio_dev *indio_dev) +{ + int ret; + struct adis16203_state *st = indio_dev->dev_data; + + st->trig = iio_allocate_trigger(); + st->trig->name = kasprintf(GFP_KERNEL, + "adis16203-dev%d", + indio_dev->id); + if (!st->trig->name) { + ret = -ENOMEM; + goto error_free_trig; + } + st->trig->dev.parent = &st->us->dev; + st->trig->owner = THIS_MODULE; + st->trig->private_data = st; + st->trig->set_trigger_state = &adis16203_data_rdy_trigger_set_state; + st->trig->try_reenable = &adis16203_trig_try_reen; + st->trig->control_attrs = &adis16203_trigger_attr_group; + ret = iio_trigger_register(st->trig); + + /* select default trigger */ + indio_dev->trig = st->trig; + if (ret) + goto error_free_trig_name; + + return 0; + +error_free_trig_name: + kfree(st->trig->name); +error_free_trig: + iio_free_trigger(st->trig); + + return ret; +} + +void adis16203_remove_trigger(struct iio_dev *indio_dev) +{ + struct adis16203_state *state = indio_dev->dev_data; + + iio_trigger_unregister(state->trig); + kfree(state->trig->name); + iio_free_trigger(state->trig); +} -- cgit v1.2.3 From bb6f19eafe3a1a5dd937ce66668e70aeaa1b0bf4 Mon Sep 17 00:00:00 2001 From: Barry Song Date: Wed, 27 Oct 2010 21:43:51 -0400 Subject: staging: iio: new adis16204 driver IIO driver for Programmable High-g Digital Impact Sensor and Recorder. Signed-off-by: Barry Song Signed-off-by: Michael Hennerich Acked-by: Jonathan Cameron Signed-off-by: Mike Frysinger Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/accel/Kconfig | 9 + drivers/staging/iio/accel/Makefile | 4 + drivers/staging/iio/accel/accel.h | 20 + drivers/staging/iio/accel/adis16204.h | 151 +++++++ drivers/staging/iio/accel/adis16204_core.c | 613 ++++++++++++++++++++++++++ drivers/staging/iio/accel/adis16204_ring.c | 206 +++++++++ drivers/staging/iio/accel/adis16204_trigger.c | 122 +++++ 7 files changed, 1125 insertions(+) create mode 100644 drivers/staging/iio/accel/adis16204.h create mode 100644 drivers/staging/iio/accel/adis16204_core.c create mode 100644 drivers/staging/iio/accel/adis16204_ring.c create mode 100644 drivers/staging/iio/accel/adis16204_trigger.c diff --git a/drivers/staging/iio/accel/Kconfig b/drivers/staging/iio/accel/Kconfig index cc057c640e64..a34f1d3e673c 100644 --- a/drivers/staging/iio/accel/Kconfig +++ b/drivers/staging/iio/accel/Kconfig @@ -21,6 +21,15 @@ config ADIS16203 Say yes here to build support for Analog Devices adis16203 Programmable 360 Degrees Inclinometer. +config ADIS16204 + tristate "Analog Devices ADIS16204 Programmable High-g Digital Impact Sensor and Recorder" + depends on SPI + select IIO_TRIGGER if IIO_RING_BUFFER + select IIO_SW_RING if IIO_RING_BUFFER + help + Say yes here to build support for Analog Devices adis16204 Programmable + High-g Digital Impact Sensor and Recorder. + config ADIS16209 tristate "Analog Devices ADIS16209 Dual-Axis Digital Inclinometer and Accelerometer" depends on SPI diff --git a/drivers/staging/iio/accel/Makefile b/drivers/staging/iio/accel/Makefile index 76cc92fed23d..1b2a6d3ddafa 100644 --- a/drivers/staging/iio/accel/Makefile +++ b/drivers/staging/iio/accel/Makefile @@ -10,6 +10,10 @@ adis16203-y := adis16203_core.o adis16203-$(CONFIG_IIO_RING_BUFFER) += adis16203_ring.o adis16203_trigger.o obj-$(CONFIG_ADIS16203) += adis16203.o +adis16204-y := adis16204_core.o +adis16204-$(CONFIG_IIO_RING_BUFFER) += adis16204_ring.o adis16204_trigger.o +obj-$(CONFIG_ADIS16204) += adis16204.o + adis16209-y := adis16209_core.o adis16209-$(CONFIG_IIO_RING_BUFFER) += adis16209_ring.o adis16209_trigger.o obj-$(CONFIG_ADIS16209) += adis16209.o diff --git a/drivers/staging/iio/accel/accel.h b/drivers/staging/iio/accel/accel.h index f5f61b2497aa..50651f835cea 100644 --- a/drivers/staging/iio/accel/accel.h +++ b/drivers/staging/iio/accel/accel.h @@ -65,3 +65,23 @@ #define IIO_DEV_ATTR_ACCEL_Z(_show, _addr) \ IIO_DEVICE_ATTR(accel_z_raw, S_IRUGO, _show, NULL, _addr) +#define IIO_DEV_ATTR_ACCEL_XY(_show, _addr) \ + IIO_DEVICE_ATTR(accel_xy, S_IRUGO, _show, NULL, _addr) + +#define IIO_DEV_ATTR_ACCEL_PEAK(_show, _addr) \ + IIO_DEVICE_ATTR(accel_peak, S_IRUGO, _show, NULL, _addr) + +#define IIO_DEV_ATTR_ACCEL_XPEAK(_show, _addr) \ + IIO_DEVICE_ATTR(accel_xpeak, S_IRUGO, _show, NULL, _addr) + +#define IIO_DEV_ATTR_ACCEL_YPEAK(_show, _addr) \ + IIO_DEVICE_ATTR(accel_ypeak, S_IRUGO, _show, NULL, _addr) + +#define IIO_DEV_ATTR_ACCEL_ZPEAK(_show, _addr) \ + IIO_DEVICE_ATTR(accel_zpeak, S_IRUGO, _show, NULL, _addr) + +#define IIO_DEV_ATTR_ACCEL_XYPEAK(_show, _addr) \ + IIO_DEVICE_ATTR(accel_xypeak, S_IRUGO, _show, NULL, _addr) + +#define IIO_DEV_ATTR_ACCEL_XYZPEAK(_show, _addr) \ + IIO_DEVICE_ATTR(accel_xyzpeak, S_IRUGO, _show, NULL, _addr) diff --git a/drivers/staging/iio/accel/adis16204.h b/drivers/staging/iio/accel/adis16204.h new file mode 100644 index 000000000000..e9ed7cb048cf --- /dev/null +++ b/drivers/staging/iio/accel/adis16204.h @@ -0,0 +1,151 @@ +#ifndef SPI_ADIS16204_H_ +#define SPI_ADIS16204_H_ + +#define ADIS16204_STARTUP_DELAY 220 /* ms */ + +#define ADIS16204_READ_REG(a) a +#define ADIS16204_WRITE_REG(a) ((a) | 0x80) + +#define ADIS16204_FLASH_CNT 0x00 /* Flash memory write count */ +#define ADIS16204_SUPPLY_OUT 0x02 /* Output, power supply */ +#define ADIS16204_XACCL_OUT 0x04 /* Output, x-axis accelerometer */ +#define ADIS16204_YACCL_OUT 0x06 /* Output, y-axis accelerometer */ +#define ADIS16204_AUX_ADC 0x08 /* Output, auxiliary ADC input */ +#define ADIS16204_TEMP_OUT 0x0A /* Output, temperature */ +#define ADIS16204_X_PEAK_OUT 0x0C /* Twos complement */ +#define ADIS16204_Y_PEAK_OUT 0x0E /* Twos complement */ +#define ADIS16204_XACCL_NULL 0x10 /* Calibration, x-axis acceleration offset null */ +#define ADIS16204_YACCL_NULL 0x12 /* Calibration, y-axis acceleration offset null */ +#define ADIS16204_XACCL_SCALE 0x14 /* X-axis scale factor calibration register */ +#define ADIS16204_YACCL_SCALE 0x16 /* Y-axis scale factor calibration register */ +#define ADIS16204_XY_RSS_OUT 0x18 /* XY combined acceleration (RSS) */ +#define ADIS16204_XY_PEAK_OUT 0x1A /* Peak, XY combined output (RSS) */ +#define ADIS16204_CAP_BUF_1 0x1C /* Capture buffer output register 1 */ +#define ADIS16204_CAP_BUF_2 0x1E /* Capture buffer output register 2 */ +#define ADIS16204_ALM_MAG1 0x20 /* Alarm 1 amplitude threshold */ +#define ADIS16204_ALM_MAG2 0x22 /* Alarm 2 amplitude threshold */ +#define ADIS16204_ALM_CTRL 0x28 /* Alarm control */ +#define ADIS16204_CAPT_PNTR 0x2A /* Capture register address pointer */ +#define ADIS16204_AUX_DAC 0x30 /* Auxiliary DAC data */ +#define ADIS16204_GPIO_CTRL 0x32 /* General-purpose digital input/output control */ +#define ADIS16204_MSC_CTRL 0x34 /* Miscellaneous control */ +#define ADIS16204_SMPL_PRD 0x36 /* Internal sample period (rate) control */ +#define ADIS16204_AVG_CNT 0x38 /* Operation, filter configuration */ +#define ADIS16204_SLP_CNT 0x3A /* Operation, sleep mode control */ +#define ADIS16204_DIAG_STAT 0x3C /* Diagnostics, system status register */ +#define ADIS16204_GLOB_CMD 0x3E /* Operation, system command register */ + +#define ADIS16204_OUTPUTS 5 + +/* MSC_CTRL */ +#define ADIS16204_MSC_CTRL_PWRUP_SELF_TEST (1 << 10) /* Self-test at power-on: 1 = disabled, 0 = enabled */ +#define ADIS16204_MSC_CTRL_SELF_TEST_EN (1 << 8) /* Self-test enable */ +#define ADIS16204_MSC_CTRL_DATA_RDY_EN (1 << 2) /* Data-ready enable: 1 = enabled, 0 = disabled */ +#define ADIS16204_MSC_CTRL_ACTIVE_HIGH (1 << 1) /* Data-ready polarity: 1 = active high, 0 = active low */ +#define ADIS16204_MSC_CTRL_DATA_RDY_DIO2 (1 << 0) /* Data-ready line selection: 1 = DIO2, 0 = DIO1 */ + +/* DIAG_STAT */ +#define ADIS16204_DIAG_STAT_ALARM2 (1<<9) /* Alarm 2 status: 1 = alarm active, 0 = alarm inactive */ +#define ADIS16204_DIAG_STAT_ALARM1 (1<<8) /* Alarm 1 status: 1 = alarm active, 0 = alarm inactive */ +#define ADIS16204_DIAG_STAT_SELFTEST_FAIL (1<<5) /* Self-test diagnostic error flag: 1 = error condition, + 0 = normal operation */ +#define ADIS16204_DIAG_STAT_SPI_FAIL (1<<3) /* SPI communications failure */ +#define ADIS16204_DIAG_STAT_FLASH_UPT (1<<2) /* Flash update failure */ +#define ADIS16204_DIAG_STAT_POWER_HIGH (1<<1) /* Power supply above 3.625 V */ +#define ADIS16204_DIAG_STAT_POWER_LOW (1<<0) /* Power supply below 2.975 V */ + +/* GLOB_CMD */ +#define ADIS16204_GLOB_CMD_SW_RESET (1<<7) +#define ADIS16204_GLOB_CMD_CLEAR_STAT (1<<4) +#define ADIS16204_GLOB_CMD_FACTORY_CAL (1<<1) + +#define ADIS16204_MAX_TX 24 +#define ADIS16204_MAX_RX 24 + +#define ADIS16204_ERROR_ACTIVE (1<<14) + +/** + * struct adis16204_state - device instance specific data + * @us: actual spi_device + * @work_trigger_to_ring: bh for triggered event handling + * @inter: used to check if new interrupt has been triggered + * @last_timestamp: passing timestamp from th to bh of interrupt handler + * @indio_dev: industrial I/O device structure + * @trig: data ready trigger registered with iio + * @tx: transmit buffer + * @rx: recieve buffer + * @buf_lock: mutex to protect tx and rx + **/ +struct adis16204_state { + struct spi_device *us; + struct work_struct work_trigger_to_ring; + s64 last_timestamp; + struct iio_dev *indio_dev; + struct iio_trigger *trig; + u8 *tx; + u8 *rx; + struct mutex buf_lock; +}; + +int adis16204_set_irq(struct device *dev, bool enable); + +#ifdef CONFIG_IIO_RING_BUFFER +enum adis16204_scan { + ADIS16204_SCAN_SUPPLY, + ADIS16204_SCAN_ACC_X, + ADIS16204_SCAN_ACC_Y, + ADIS16204_SCAN_AUX_ADC, + ADIS16204_SCAN_TEMP, +}; + +void adis16204_remove_trigger(struct iio_dev *indio_dev); +int adis16204_probe_trigger(struct iio_dev *indio_dev); + +ssize_t adis16204_read_data_from_ring(struct device *dev, + struct device_attribute *attr, + char *buf); + +int adis16204_configure_ring(struct iio_dev *indio_dev); +void adis16204_unconfigure_ring(struct iio_dev *indio_dev); + +int adis16204_initialize_ring(struct iio_ring_buffer *ring); +void adis16204_uninitialize_ring(struct iio_ring_buffer *ring); +#else /* CONFIG_IIO_RING_BUFFER */ + +static inline void adis16204_remove_trigger(struct iio_dev *indio_dev) +{ +} + +static inline int adis16204_probe_trigger(struct iio_dev *indio_dev) +{ + return 0; +} + +static inline ssize_t +adis16204_read_data_from_ring(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + return 0; +} + +static int adis16204_configure_ring(struct iio_dev *indio_dev) +{ + return 0; +} + +static inline void adis16204_unconfigure_ring(struct iio_dev *indio_dev) +{ +} + +static inline int adis16204_initialize_ring(struct iio_ring_buffer *ring) +{ + return 0; +} + +static inline void adis16204_uninitialize_ring(struct iio_ring_buffer *ring) +{ +} + +#endif /* CONFIG_IIO_RING_BUFFER */ +#endif /* SPI_ADIS16204_H_ */ diff --git a/drivers/staging/iio/accel/adis16204_core.c b/drivers/staging/iio/accel/adis16204_core.c new file mode 100644 index 000000000000..cc15e40726fc --- /dev/null +++ b/drivers/staging/iio/accel/adis16204_core.c @@ -0,0 +1,613 @@ +/* + * ADIS16204 Programmable High-g Digital Impact Sensor and Recorder + * + * Copyright 2010 Analog Devices Inc. + * + * Licensed under the GPL-2 or later. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../iio.h" +#include "../sysfs.h" +#include "accel.h" +#include "../gyro/gyro.h" +#include "../adc/adc.h" + +#include "adis16204.h" + +#define DRIVER_NAME "adis16204" + +static int adis16204_check_status(struct device *dev); + +/** + * adis16204_spi_write_reg_8() - write single byte to a register + * @dev: device associated with child of actual device (iio_dev or iio_trig) + * @reg_address: the address of the register to be written + * @val: the value to write + **/ +static int adis16204_spi_write_reg_8(struct device *dev, + u8 reg_address, + u8 val) +{ + int ret; + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct adis16204_state *st = iio_dev_get_devdata(indio_dev); + + mutex_lock(&st->buf_lock); + st->tx[0] = ADIS16204_WRITE_REG(reg_address); + st->tx[1] = val; + + ret = spi_write(st->us, st->tx, 2); + mutex_unlock(&st->buf_lock); + + return ret; +} + +/** + * adis16204_spi_write_reg_16() - write 2 bytes to a pair of registers + * @dev: device associated with child of actual device (iio_dev or iio_trig) + * @reg_address: the address of the lower of the two registers. Second register + * is assumed to have address one greater. + * @val: value to be written + **/ +static int adis16204_spi_write_reg_16(struct device *dev, + u8 lower_reg_address, + u16 value) +{ + int ret; + struct spi_message msg; + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct adis16204_state *st = iio_dev_get_devdata(indio_dev); + struct spi_transfer xfers[] = { + { + .tx_buf = st->tx, + .bits_per_word = 8, + .len = 2, + .cs_change = 1, + }, { + .tx_buf = st->tx + 2, + .bits_per_word = 8, + .len = 2, + .cs_change = 1, + }, + }; + + mutex_lock(&st->buf_lock); + st->tx[0] = ADIS16204_WRITE_REG(lower_reg_address); + st->tx[1] = value & 0xFF; + st->tx[2] = ADIS16204_WRITE_REG(lower_reg_address + 1); + st->tx[3] = (value >> 8) & 0xFF; + + spi_message_init(&msg); + spi_message_add_tail(&xfers[0], &msg); + spi_message_add_tail(&xfers[1], &msg); + ret = spi_sync(st->us, &msg); + mutex_unlock(&st->buf_lock); + + return ret; +} + +/** + * adis16204_spi_read_reg_16() - read 2 bytes from a 16-bit register + * @dev: device associated with child of actual device (iio_dev or iio_trig) + * @reg_address: the address of the lower of the two registers. Second register + * is assumed to have address one greater. + * @val: somewhere to pass back the value read + **/ +static int adis16204_spi_read_reg_16(struct device *dev, + u8 lower_reg_address, + u16 *val) +{ + struct spi_message msg; + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct adis16204_state *st = iio_dev_get_devdata(indio_dev); + int ret; + struct spi_transfer xfers[] = { + { + .tx_buf = st->tx, + .bits_per_word = 8, + .len = 2, + .cs_change = 1, + .delay_usecs = 20, + }, { + .rx_buf = st->rx, + .bits_per_word = 8, + .len = 2, + .cs_change = 1, + .delay_usecs = 20, + }, + }; + + mutex_lock(&st->buf_lock); + st->tx[0] = ADIS16204_READ_REG(lower_reg_address); + st->tx[1] = 0; + + spi_message_init(&msg); + spi_message_add_tail(&xfers[0], &msg); + spi_message_add_tail(&xfers[1], &msg); + ret = spi_sync(st->us, &msg); + if (ret) { + dev_err(&st->us->dev, "problem when reading 16 bit register 0x%02X", + lower_reg_address); + goto error_ret; + } + *val = (st->rx[0] << 8) | st->rx[1]; + +error_ret: + mutex_unlock(&st->buf_lock); + return ret; +} + +static ssize_t adis16204_read_12bit_unsigned(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + int ret; + u16 val = 0; + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + + ret = adis16204_spi_read_reg_16(dev, this_attr->address, &val); + if (ret) + return ret; + + if (val & ADIS16204_ERROR_ACTIVE) + adis16204_check_status(dev); + + return sprintf(buf, "%u\n", val & 0x0FFF); +} + +static ssize_t adis16204_read_temp(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + ssize_t ret; + u16 val; + + /* Take the iio_dev status lock */ + mutex_lock(&indio_dev->mlock); + + ret = adis16204_spi_read_reg_16(dev, ADIS16204_TEMP_OUT, (u16 *)&val); + if (ret) + goto error_ret; + + if (val & ADIS16204_ERROR_ACTIVE) + adis16204_check_status(dev); + + val &= 0xFFF; + ret = sprintf(buf, "%d\n", val); + +error_ret: + mutex_unlock(&indio_dev->mlock); + return ret; +} + +static ssize_t adis16204_read_12bit_signed(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + s16 val = 0; + ssize_t ret; + + mutex_lock(&indio_dev->mlock); + + ret = adis16204_spi_read_reg_16(dev, this_attr->address, (u16 *)&val); + if (!ret) { + if (val & ADIS16204_ERROR_ACTIVE) + adis16204_check_status(dev); + + val = ((s16)(val << 4) >> 4); + ret = sprintf(buf, "%d\n", val); + } + + mutex_unlock(&indio_dev->mlock); + + return ret; +} + +static ssize_t adis16204_read_14bit_signed(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + s16 val = 0; + ssize_t ret; + + mutex_lock(&indio_dev->mlock); + + ret = adis16204_spi_read_reg_16(dev, this_attr->address, (u16 *)&val); + if (!ret) { + if (val & ADIS16204_ERROR_ACTIVE) + adis16204_check_status(dev); + + val = ((s16)(val << 2) >> 2); + ret = sprintf(buf, "%d\n", val); + } + + mutex_unlock(&indio_dev->mlock); + + return ret; +} + +static ssize_t adis16204_write_16bit(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + int ret; + long val; + + ret = strict_strtol(buf, 10, &val); + if (ret) + goto error_ret; + ret = adis16204_spi_write_reg_16(dev, this_attr->address, val); + +error_ret: + return ret ? ret : len; +} + +static int adis16204_reset(struct device *dev) +{ + int ret; + ret = adis16204_spi_write_reg_8(dev, + ADIS16204_GLOB_CMD, + ADIS16204_GLOB_CMD_SW_RESET); + if (ret) + dev_err(dev, "problem resetting device"); + + return ret; +} + +static ssize_t adis16204_write_reset(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t len) +{ + if (len < 1) + return -EINVAL; + switch (buf[0]) { + case '1': + case 'y': + case 'Y': + return adis16204_reset(dev); + } + return -EINVAL; +} + +int adis16204_set_irq(struct device *dev, bool enable) +{ + int ret = 0; + u16 msc; + + ret = adis16204_spi_read_reg_16(dev, ADIS16204_MSC_CTRL, &msc); + if (ret) + goto error_ret; + + msc |= ADIS16204_MSC_CTRL_ACTIVE_HIGH; + msc &= ~ADIS16204_MSC_CTRL_DATA_RDY_DIO2; + if (enable) + msc |= ADIS16204_MSC_CTRL_DATA_RDY_EN; + else + msc &= ~ADIS16204_MSC_CTRL_DATA_RDY_EN; + + ret = adis16204_spi_write_reg_16(dev, ADIS16204_MSC_CTRL, msc); + +error_ret: + return ret; +} + +static int adis16204_check_status(struct device *dev) +{ + u16 status; + int ret; + + ret = adis16204_spi_read_reg_16(dev, ADIS16204_DIAG_STAT, &status); + if (ret < 0) { + dev_err(dev, "Reading status failed\n"); + goto error_ret; + } + ret = status & 0x1F; + + if (status & ADIS16204_DIAG_STAT_SELFTEST_FAIL) + dev_err(dev, "Self test failure\n"); + if (status & ADIS16204_DIAG_STAT_SPI_FAIL) + dev_err(dev, "SPI failure\n"); + if (status & ADIS16204_DIAG_STAT_FLASH_UPT) + dev_err(dev, "Flash update failed\n"); + if (status & ADIS16204_DIAG_STAT_POWER_HIGH) + dev_err(dev, "Power supply above 3.625V\n"); + if (status & ADIS16204_DIAG_STAT_POWER_LOW) + dev_err(dev, "Power supply below 2.975V\n"); + +error_ret: + return ret; +} + +static int adis16204_self_test(struct device *dev) +{ + int ret; + ret = adis16204_spi_write_reg_16(dev, + ADIS16204_MSC_CTRL, + ADIS16204_MSC_CTRL_SELF_TEST_EN); + if (ret) { + dev_err(dev, "problem starting self test"); + goto err_ret; + } + + adis16204_check_status(dev); + +err_ret: + return ret; +} + +static int adis16204_initial_setup(struct adis16204_state *st) +{ + int ret; + struct device *dev = &st->indio_dev->dev; + + /* Disable IRQ */ + ret = adis16204_set_irq(dev, false); + if (ret) { + dev_err(dev, "disable irq failed"); + goto err_ret; + } + + /* Do self test */ + ret = adis16204_self_test(dev); + if (ret) { + dev_err(dev, "self test failure"); + goto err_ret; + } + + /* Read status register to check the result */ + ret = adis16204_check_status(dev); + if (ret) { + adis16204_reset(dev); + dev_err(dev, "device not playing ball -> reset"); + msleep(ADIS16204_STARTUP_DELAY); + ret = adis16204_check_status(dev); + if (ret) { + dev_err(dev, "giving up"); + goto err_ret; + } + } + + printk(KERN_INFO DRIVER_NAME ": at CS%d (irq %d)\n", + st->us->chip_select, st->us->irq); + +err_ret: + return ret; +} + +static IIO_DEV_ATTR_IN_NAMED_RAW(0, supply, adis16204_read_12bit_unsigned, + ADIS16204_SUPPLY_OUT); +static IIO_CONST_ATTR(in0_supply_scale, "0.00122"); +static IIO_DEV_ATTR_IN_RAW(1, adis16204_read_12bit_unsigned, + ADIS16204_AUX_ADC); +static IIO_CONST_ATTR(in1_scale, "0.00061"); + +static IIO_DEV_ATTR_ACCEL_X(adis16204_read_14bit_signed, + ADIS16204_XACCL_OUT); +static IIO_DEV_ATTR_ACCEL_Y(adis16204_read_14bit_signed, + ADIS16204_YACCL_OUT); +static IIO_DEV_ATTR_ACCEL_XY(adis16204_read_14bit_signed, + ADIS16204_XY_RSS_OUT); +static IIO_DEV_ATTR_ACCEL_XPEAK(adis16204_read_14bit_signed, + ADIS16204_X_PEAK_OUT); +static IIO_DEV_ATTR_ACCEL_YPEAK(adis16204_read_14bit_signed, + ADIS16204_Y_PEAK_OUT); +static IIO_DEV_ATTR_ACCEL_XYPEAK(adis16204_read_14bit_signed, + ADIS16204_XY_PEAK_OUT); +static IIO_DEV_ATTR_ACCEL_X_OFFSET(S_IWUSR | S_IRUGO, + adis16204_read_12bit_signed, + adis16204_write_16bit, + ADIS16204_XACCL_NULL); +static IIO_DEV_ATTR_ACCEL_Y_OFFSET(S_IWUSR | S_IRUGO, + adis16204_read_12bit_signed, + adis16204_write_16bit, + ADIS16204_YACCL_NULL); +static IIO_CONST_ATTR(accel_x_scale, "0.017125"); +static IIO_CONST_ATTR(accel_y_scale, "0.008407"); +static IIO_CONST_ATTR(accel_xy_scale, "0.017125"); + +static IIO_DEV_ATTR_TEMP_RAW(adis16204_read_temp); +static IIO_CONST_ATTR(temp_offset, "25"); +static IIO_CONST_ATTR(temp_scale, "-0.47"); + +static IIO_DEVICE_ATTR(reset, S_IWUSR, NULL, adis16204_write_reset, 0); + +static IIO_CONST_ATTR(name, "adis16204"); + +static struct attribute *adis16204_event_attributes[] = { + NULL +}; + +static struct attribute_group adis16204_event_attribute_group = { + .attrs = adis16204_event_attributes, +}; + +static struct attribute *adis16204_attributes[] = { + &iio_dev_attr_in0_supply_raw.dev_attr.attr, + &iio_const_attr_in0_supply_scale.dev_attr.attr, + &iio_dev_attr_temp_raw.dev_attr.attr, + &iio_const_attr_temp_offset.dev_attr.attr, + &iio_const_attr_temp_scale.dev_attr.attr, + &iio_dev_attr_reset.dev_attr.attr, + &iio_const_attr_name.dev_attr.attr, + &iio_dev_attr_in1_raw.dev_attr.attr, + &iio_const_attr_in1_scale.dev_attr.attr, + &iio_dev_attr_accel_x_raw.dev_attr.attr, + &iio_dev_attr_accel_y_raw.dev_attr.attr, + &iio_dev_attr_accel_xy.dev_attr.attr, + &iio_dev_attr_accel_xpeak.dev_attr.attr, + &iio_dev_attr_accel_ypeak.dev_attr.attr, + &iio_dev_attr_accel_xypeak.dev_attr.attr, + &iio_dev_attr_accel_x_offset.dev_attr.attr, + &iio_dev_attr_accel_y_offset.dev_attr.attr, + &iio_const_attr_accel_x_scale.dev_attr.attr, + &iio_const_attr_accel_y_scale.dev_attr.attr, + &iio_const_attr_accel_xy_scale.dev_attr.attr, + NULL +}; + +static const struct attribute_group adis16204_attribute_group = { + .attrs = adis16204_attributes, +}; + +static int __devinit adis16204_probe(struct spi_device *spi) +{ + int ret, regdone = 0; + struct adis16204_state *st = kzalloc(sizeof *st, GFP_KERNEL); + if (!st) { + ret = -ENOMEM; + goto error_ret; + } + /* this is only used for removal purposes */ + spi_set_drvdata(spi, st); + + /* Allocate the comms buffers */ + st->rx = kzalloc(sizeof(*st->rx)*ADIS16204_MAX_RX, GFP_KERNEL); + if (st->rx == NULL) { + ret = -ENOMEM; + goto error_free_st; + } + st->tx = kzalloc(sizeof(*st->tx)*ADIS16204_MAX_TX, GFP_KERNEL); + if (st->tx == NULL) { + ret = -ENOMEM; + goto error_free_rx; + } + st->us = spi; + mutex_init(&st->buf_lock); + /* setup the industrialio driver allocated elements */ + st->indio_dev = iio_allocate_device(); + if (st->indio_dev == NULL) { + ret = -ENOMEM; + goto error_free_tx; + } + + st->indio_dev->dev.parent = &spi->dev; + st->indio_dev->num_interrupt_lines = 1; + st->indio_dev->event_attrs = &adis16204_event_attribute_group; + st->indio_dev->attrs = &adis16204_attribute_group; + st->indio_dev->dev_data = (void *)(st); + st->indio_dev->driver_module = THIS_MODULE; + st->indio_dev->modes = INDIO_DIRECT_MODE; + + ret = adis16204_configure_ring(st->indio_dev); + if (ret) + goto error_free_dev; + + ret = iio_device_register(st->indio_dev); + if (ret) + goto error_unreg_ring_funcs; + regdone = 1; + + ret = adis16204_initialize_ring(st->indio_dev->ring); + if (ret) { + printk(KERN_ERR "failed to initialize the ring\n"); + goto error_unreg_ring_funcs; + } + + if (spi->irq) { + ret = iio_register_interrupt_line(spi->irq, + st->indio_dev, + 0, + IRQF_TRIGGER_RISING, + "adis16204"); + if (ret) + goto error_uninitialize_ring; + + ret = adis16204_probe_trigger(st->indio_dev); + if (ret) + goto error_unregister_line; + } + + /* Get the device into a sane initial state */ + ret = adis16204_initial_setup(st); + if (ret) + goto error_remove_trigger; + return 0; + +error_remove_trigger: + adis16204_remove_trigger(st->indio_dev); +error_unregister_line: + if (spi->irq) + iio_unregister_interrupt_line(st->indio_dev, 0); +error_uninitialize_ring: + adis16204_uninitialize_ring(st->indio_dev->ring); +error_unreg_ring_funcs: + adis16204_unconfigure_ring(st->indio_dev); +error_free_dev: + if (regdone) + iio_device_unregister(st->indio_dev); + else + iio_free_device(st->indio_dev); +error_free_tx: + kfree(st->tx); +error_free_rx: + kfree(st->rx); +error_free_st: + kfree(st); +error_ret: + return ret; +} + +static int adis16204_remove(struct spi_device *spi) +{ + struct adis16204_state *st = spi_get_drvdata(spi); + struct iio_dev *indio_dev = st->indio_dev; + + flush_scheduled_work(); + + adis16204_remove_trigger(indio_dev); + if (spi->irq) + iio_unregister_interrupt_line(indio_dev, 0); + + adis16204_uninitialize_ring(indio_dev->ring); + iio_device_unregister(indio_dev); + adis16204_unconfigure_ring(indio_dev); + kfree(st->tx); + kfree(st->rx); + kfree(st); + + return 0; +} + +static struct spi_driver adis16204_driver = { + .driver = { + .name = "adis16204", + .owner = THIS_MODULE, + }, + .probe = adis16204_probe, + .remove = __devexit_p(adis16204_remove), +}; + +static __init int adis16204_init(void) +{ + return spi_register_driver(&adis16204_driver); +} +module_init(adis16204_init); + +static __exit void adis16204_exit(void) +{ + spi_unregister_driver(&adis16204_driver); +} +module_exit(adis16204_exit); + +MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>"); +MODULE_DESCRIPTION("Analog Devices ADIS16204 Programmable High-g Digital Impact Sensor and Recorder"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/staging/iio/accel/adis16204_ring.c b/drivers/staging/iio/accel/adis16204_ring.c new file mode 100644 index 000000000000..420b160fe3ab --- /dev/null +++ b/drivers/staging/iio/accel/adis16204_ring.c @@ -0,0 +1,206 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../iio.h" +#include "../sysfs.h" +#include "../ring_sw.h" +#include "accel.h" +#include "../trigger.h" +#include "adis16204.h" + +static IIO_SCAN_EL_C(in_supply, ADIS16204_SCAN_SUPPLY, ADIS16204_SUPPLY_OUT, NULL); +static IIO_CONST_ATTR_SCAN_EL_TYPE(in_supply, u, 12, 16); +static IIO_SCAN_EL_C(accel_x, ADIS16204_SCAN_ACC_X, ADIS16204_XACCL_OUT, NULL); +static IIO_SCAN_EL_C(accel_y, ADIS16204_SCAN_ACC_Y, ADIS16204_YACCL_OUT, NULL); +static IIO_CONST_ATTR_SCAN_EL_TYPE(accel, s, 14, 16); +static IIO_SCAN_EL_C(in0, ADIS16204_SCAN_AUX_ADC, ADIS16204_AUX_ADC, NULL); +static IIO_CONST_ATTR_SCAN_EL_TYPE(in0, u, 12, 16); +static IIO_SCAN_EL_C(temp, ADIS16204_SCAN_TEMP, ADIS16204_TEMP_OUT, NULL); +static IIO_CONST_ATTR_SCAN_EL_TYPE(temp, u, 12, 16); +static IIO_SCAN_EL_TIMESTAMP(5); +static IIO_CONST_ATTR_SCAN_EL_TYPE(timestamp, s, 64, 64); + +static struct attribute *adis16204_scan_el_attrs[] = { + &iio_scan_el_in_supply.dev_attr.attr, + &iio_const_attr_in_supply_index.dev_attr.attr, + &iio_const_attr_in_supply_type.dev_attr.attr, + &iio_scan_el_accel_x.dev_attr.attr, + &iio_const_attr_accel_x_index.dev_attr.attr, + &iio_scan_el_accel_y.dev_attr.attr, + &iio_const_attr_accel_y_index.dev_attr.attr, + &iio_const_attr_accel_type.dev_attr.attr, + &iio_scan_el_in0.dev_attr.attr, + &iio_const_attr_in0_index.dev_attr.attr, + &iio_const_attr_in0_type.dev_attr.attr, + &iio_scan_el_temp.dev_attr.attr, + &iio_const_attr_temp_index.dev_attr.attr, + &iio_const_attr_temp_type.dev_attr.attr, + &iio_scan_el_timestamp.dev_attr.attr, + &iio_const_attr_timestamp_index.dev_attr.attr, + &iio_const_attr_timestamp_type.dev_attr.attr, + NULL, +}; + +static struct attribute_group adis16204_scan_el_group = { + .attrs = adis16204_scan_el_attrs, + .name = "scan_elements", +}; + +/** + * adis16204_poll_func_th() top half interrupt handler called by trigger + * @private_data: iio_dev + **/ +static void adis16204_poll_func_th(struct iio_dev *indio_dev, s64 timestamp) +{ + struct adis16204_state *st = iio_dev_get_devdata(indio_dev); + st->last_timestamp = timestamp; + schedule_work(&st->work_trigger_to_ring); +} + +/** + * adis16204_read_ring_data() read data registers which will be placed into ring + * @dev: device associated with child of actual device (iio_dev or iio_trig) + * @rx: somewhere to pass back the value read + **/ +static int adis16204_read_ring_data(struct device *dev, u8 *rx) +{ + struct spi_message msg; + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct adis16204_state *st = iio_dev_get_devdata(indio_dev); + struct spi_transfer xfers[ADIS16204_OUTPUTS + 1]; + int ret; + int i; + + mutex_lock(&st->buf_lock); + + spi_message_init(&msg); + + memset(xfers, 0, sizeof(xfers)); + for (i = 0; i <= ADIS16204_OUTPUTS; i++) { + xfers[i].bits_per_word = 8; + xfers[i].cs_change = 1; + xfers[i].len = 2; + xfers[i].delay_usecs = 20; + xfers[i].tx_buf = st->tx + 2 * i; + st->tx[2 * i] = ADIS16204_READ_REG(ADIS16204_SUPPLY_OUT + 2 * i); + st->tx[2 * i + 1] = 0; + if (i >= 1) + xfers[i].rx_buf = rx + 2 * (i - 1); + spi_message_add_tail(&xfers[i], &msg); + } + + ret = spi_sync(st->us, &msg); + if (ret) + dev_err(&st->us->dev, "problem when burst reading"); + + mutex_unlock(&st->buf_lock); + + return ret; +} + +/* Whilst this makes a lot of calls to iio_sw_ring functions - it is to device + * specific to be rolled into the core. + */ +static void adis16204_trigger_bh_to_ring(struct work_struct *work_s) +{ + struct adis16204_state *st + = container_of(work_s, struct adis16204_state, + work_trigger_to_ring); + struct iio_ring_buffer *ring = st->indio_dev->ring; + + int i = 0; + s16 *data; + size_t datasize = ring->access.get_bytes_per_datum(ring); + + data = kmalloc(datasize, GFP_KERNEL); + if (data == NULL) { + dev_err(&st->us->dev, "memory alloc failed in ring bh"); + return; + } + + if (ring->scan_count) + if (adis16204_read_ring_data(&st->indio_dev->dev, st->rx) >= 0) + for (; i < ring->scan_count; i++) + data[i] = be16_to_cpup( + (__be16 *)&(st->rx[i*2])); + + /* Guaranteed to be aligned with 8 byte boundary */ + if (ring->scan_timestamp) + *((s64 *)(data + ((i + 3)/4)*4)) = st->last_timestamp; + + ring->access.store_to(ring, + (u8 *)data, + st->last_timestamp); + + iio_trigger_notify_done(st->indio_dev->trig); + kfree(data); + + return; +} + +void adis16204_unconfigure_ring(struct iio_dev *indio_dev) +{ + kfree(indio_dev->pollfunc); + iio_sw_rb_free(indio_dev->ring); +} + +int adis16204_configure_ring(struct iio_dev *indio_dev) +{ + int ret = 0; + struct adis16204_state *st = indio_dev->dev_data; + struct iio_ring_buffer *ring; + INIT_WORK(&st->work_trigger_to_ring, adis16204_trigger_bh_to_ring); + + ring = iio_sw_rb_allocate(indio_dev); + if (!ring) { + ret = -ENOMEM; + return ret; + } + indio_dev->ring = ring; + /* Effectively select the ring buffer implementation */ + iio_ring_sw_register_funcs(&ring->access); + ring->bpe = 2; + ring->scan_el_attrs = &adis16204_scan_el_group; + ring->scan_timestamp = true; + ring->preenable = &iio_sw_ring_preenable; + ring->postenable = &iio_triggered_ring_postenable; + ring->predisable = &iio_triggered_ring_predisable; + ring->owner = THIS_MODULE; + + /* Set default scan mode */ + iio_scan_mask_set(ring, iio_scan_el_in_supply.number); + iio_scan_mask_set(ring, iio_scan_el_accel_x.number); + iio_scan_mask_set(ring, iio_scan_el_accel_y.number); + iio_scan_mask_set(ring, iio_scan_el_temp.number); + iio_scan_mask_set(ring, iio_scan_el_in0.number); + + ret = iio_alloc_pollfunc(indio_dev, NULL, &adis16204_poll_func_th); + if (ret) + goto error_iio_sw_rb_free; + + indio_dev->modes |= INDIO_RING_TRIGGERED; + return 0; + +error_iio_sw_rb_free: + iio_sw_rb_free(indio_dev->ring); + return ret; +} + +int adis16204_initialize_ring(struct iio_ring_buffer *ring) +{ + return iio_ring_buffer_register(ring, 0); +} + +void adis16204_uninitialize_ring(struct iio_ring_buffer *ring) +{ + iio_ring_buffer_unregister(ring); +} diff --git a/drivers/staging/iio/accel/adis16204_trigger.c b/drivers/staging/iio/accel/adis16204_trigger.c new file mode 100644 index 000000000000..8e9db90e51eb --- /dev/null +++ b/drivers/staging/iio/accel/adis16204_trigger.c @@ -0,0 +1,122 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../iio.h" +#include "../sysfs.h" +#include "../trigger.h" +#include "adis16204.h" + +/** + * adis16204_data_rdy_trig_poll() the event handler for the data rdy trig + **/ +static int adis16204_data_rdy_trig_poll(struct iio_dev *dev_info, + int index, + s64 timestamp, + int no_test) +{ + struct adis16204_state *st = iio_dev_get_devdata(dev_info); + struct iio_trigger *trig = st->trig; + + iio_trigger_poll(trig, timestamp); + + return IRQ_HANDLED; +} + +IIO_EVENT_SH(data_rdy_trig, &adis16204_data_rdy_trig_poll); + +static DEVICE_ATTR(name, S_IRUGO, iio_trigger_read_name, NULL); + +static struct attribute *adis16204_trigger_attrs[] = { + &dev_attr_name.attr, + NULL, +}; + +static const struct attribute_group adis16204_trigger_attr_group = { + .attrs = adis16204_trigger_attrs, +}; + +/** + * adis16204_data_rdy_trigger_set_state() set datardy interrupt state + **/ +static int adis16204_data_rdy_trigger_set_state(struct iio_trigger *trig, + bool state) +{ + struct adis16204_state *st = trig->private_data; + struct iio_dev *indio_dev = st->indio_dev; + int ret = 0; + + dev_dbg(&indio_dev->dev, "%s (%d)\n", __func__, state); + ret = adis16204_set_irq(&st->indio_dev->dev, state); + if (state == false) { + iio_remove_event_from_list(&iio_event_data_rdy_trig, + &indio_dev->interrupts[0] + ->ev_list); + flush_scheduled_work(); + } else { + iio_add_event_to_list(&iio_event_data_rdy_trig, + &indio_dev->interrupts[0]->ev_list); + } + return ret; +} + +/** + * adis16204_trig_try_reen() try renabling irq for data rdy trigger + * @trig: the datardy trigger + **/ +static int adis16204_trig_try_reen(struct iio_trigger *trig) +{ + struct adis16204_state *st = trig->private_data; + enable_irq(st->us->irq); + return 0; +} + +int adis16204_probe_trigger(struct iio_dev *indio_dev) +{ + int ret; + struct adis16204_state *st = indio_dev->dev_data; + + st->trig = iio_allocate_trigger(); + st->trig->name = kasprintf(GFP_KERNEL, + "adis16204-dev%d", + indio_dev->id); + if (!st->trig->name) { + ret = -ENOMEM; + goto error_free_trig; + } + st->trig->dev.parent = &st->us->dev; + st->trig->owner = THIS_MODULE; + st->trig->private_data = st; + st->trig->set_trigger_state = &adis16204_data_rdy_trigger_set_state; + st->trig->try_reenable = &adis16204_trig_try_reen; + st->trig->control_attrs = &adis16204_trigger_attr_group; + ret = iio_trigger_register(st->trig); + + /* select default trigger */ + indio_dev->trig = st->trig; + if (ret) + goto error_free_trig_name; + + return 0; + +error_free_trig_name: + kfree(st->trig->name); +error_free_trig: + iio_free_trigger(st->trig); + + return ret; +} + +void adis16204_remove_trigger(struct iio_dev *indio_dev) +{ + struct adis16204_state *state = indio_dev->dev_data; + + iio_trigger_unregister(state->trig); + kfree(state->trig->name); + iio_free_trigger(state->trig); +} -- cgit v1.2.3 From 35f6b6b86ede34a9f8c029943842640b2ffbfa19 Mon Sep 17 00:00:00 2001 From: Sonic Zhang Date: Wed, 27 Oct 2010 21:43:52 -0400 Subject: staging: iio: new ADT7316/7/8 and ADT7516/7/9 driver IIO driver for temperature sensor, ADC and DAC devices over SPI and I2C. Signed-off-by: Sonic Zhang Signed-off-by: Michael Hennerich Acked-by: Jonathan Cameron Signed-off-by: Mike Frysinger Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/Kconfig | 1 + drivers/staging/iio/Makefile | 1 + drivers/staging/iio/addac/Kconfig | 25 + drivers/staging/iio/addac/Makefile | 7 + drivers/staging/iio/addac/adt7316-i2c.c | 170 +++ drivers/staging/iio/addac/adt7316-spi.c | 180 +++ drivers/staging/iio/addac/adt7316.c | 2402 +++++++++++++++++++++++++++++++ drivers/staging/iio/addac/adt7316.h | 33 + 8 files changed, 2819 insertions(+) create mode 100644 drivers/staging/iio/addac/Kconfig create mode 100644 drivers/staging/iio/addac/Makefile create mode 100644 drivers/staging/iio/addac/adt7316-i2c.c create mode 100644 drivers/staging/iio/addac/adt7316-spi.c create mode 100644 drivers/staging/iio/addac/adt7316.c create mode 100644 drivers/staging/iio/addac/adt7316.h diff --git a/drivers/staging/iio/Kconfig b/drivers/staging/iio/Kconfig index ed48815a916b..b8bb5f162540 100644 --- a/drivers/staging/iio/Kconfig +++ b/drivers/staging/iio/Kconfig @@ -42,6 +42,7 @@ config IIO_TRIGGER source "drivers/staging/iio/accel/Kconfig" source "drivers/staging/iio/adc/Kconfig" +source "drivers/staging/iio/addac/Kconfig" source "drivers/staging/iio/gyro/Kconfig" source "drivers/staging/iio/imu/Kconfig" source "drivers/staging/iio/light/Kconfig" diff --git a/drivers/staging/iio/Makefile b/drivers/staging/iio/Makefile index e909674920fc..0111647b9b9a 100644 --- a/drivers/staging/iio/Makefile +++ b/drivers/staging/iio/Makefile @@ -11,6 +11,7 @@ obj-$(CONFIG_IIO_SW_RING) += ring_sw.o obj-y += accel/ obj-y += adc/ +obj-y += addac/ obj-y += gyro/ obj-y += imu/ obj-y += light/ diff --git a/drivers/staging/iio/addac/Kconfig b/drivers/staging/iio/addac/Kconfig new file mode 100644 index 000000000000..9847baf02700 --- /dev/null +++ b/drivers/staging/iio/addac/Kconfig @@ -0,0 +1,25 @@ +# +# ADDAC drivers +# +comment "Analog digital bi-direction convertors" + +config ADT7316 + tristate "Analog Devices ADT7316/7/8 ADT7516/7/9 temperature sensor, ADC and DAC driver" + help + Say yes here to build support for Analog Devices ADT7316, ADT7317, ADT7318 + and ADT7516, ADT7517, ADT7519 temperature sensors, ADC and DAC. + +config ADT7316_SPI + tristate "support SPI bus connection" + depends on SPI && ADT7316 + default y + help + Say yes here to build SPI bus support for Analog Devices ADT7316/7/8 + and ADT7516/7/9. + +config ADT7316_I2C + tristate "support I2C bus connection" + depends on I2C && ADT7316 + help + Say yes here to build I2C bus support for Analog Devices ADT7316/7/8 + and ADT7516/7/9. diff --git a/drivers/staging/iio/addac/Makefile b/drivers/staging/iio/addac/Makefile new file mode 100644 index 000000000000..4c7686133692 --- /dev/null +++ b/drivers/staging/iio/addac/Makefile @@ -0,0 +1,7 @@ +# +# Makefile for industrial I/O ADDAC drivers +# + +obj-$(CONFIG_ADT7316) += adt7316.o +obj-$(CONFIG_ADT7316_SPI) += adt7316-spi.o +obj-$(CONFIG_ADT7316_I2C) += adt7316-i2c.o diff --git a/drivers/staging/iio/addac/adt7316-i2c.c b/drivers/staging/iio/addac/adt7316-i2c.c new file mode 100644 index 000000000000..52d1ea349635 --- /dev/null +++ b/drivers/staging/iio/addac/adt7316-i2c.c @@ -0,0 +1,170 @@ +/* + * I2C bus driver for ADT7316/7/8 ADT7516/7/9 digital temperature + * sensor, ADC and DAC + * + * Copyright 2010 Analog Devices Inc. + * + * Licensed under the GPL-2 or later. + */ + +#include +#include +#include +#include + +#include "adt7316.h" + +/* + * adt7316 register access by I2C + */ +static int adt7316_i2c_read(void *client, u8 reg, u8 *data) +{ + struct i2c_client *cl = client; + int ret = 0; + + ret = i2c_smbus_write_byte(cl, reg); + if (ret < 0) { + dev_err(&cl->dev, "I2C fail to select reg\n"); + return ret; + } + + ret = i2c_smbus_read_byte(client); + if (ret < 0) { + dev_err(&cl->dev, "I2C read error\n"); + return ret; + } + + return 0; +} + +static int adt7316_i2c_write(void *client, u8 reg, u8 data) +{ + struct i2c_client *cl = client; + int ret = 0; + + ret = i2c_smbus_write_byte_data(cl, reg, data); + if (ret < 0) + dev_err(&cl->dev, "I2C write error\n"); + + return ret; +} + +static int adt7316_i2c_multi_read(void *client, u8 reg, u8 count, u8 *data) +{ + struct i2c_client *cl = client; + int i, ret = 0; + + if (count > ADT7316_REG_MAX_ADDR) + count = ADT7316_REG_MAX_ADDR; + + for (i = 0; i < count; i++) { + ret = adt7316_i2c_read(cl, reg, &data[i]); + if (ret < 0) { + dev_err(&cl->dev, "I2C multi read error\n"); + return ret; + } + } + + return 0; +} + +static int adt7316_i2c_multi_write(void *client, u8 reg, u8 count, u8 *data) +{ + struct i2c_client *cl = client; + int i, ret = 0; + + if (count > ADT7316_REG_MAX_ADDR) + count = ADT7316_REG_MAX_ADDR; + + for (i = 0; i < count; i++) { + ret = adt7316_i2c_write(cl, reg, data[i]); + if (ret < 0) { + dev_err(&cl->dev, "I2C multi write error\n"); + return ret; + } + } + + return 0; +} + +/* + * device probe and remove + */ + +static int __devinit adt7316_i2c_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct adt7316_bus bus = { + .client = client, + .irq = client->irq, + .irq_flags = IRQF_TRIGGER_LOW, + .read = adt7316_i2c_read, + .write = adt7316_i2c_write, + .multi_read = adt7316_i2c_multi_read, + .multi_write = adt7316_i2c_multi_write, + }; + + return adt7316_probe(&client->dev, &bus, id->name); +} + +static int __devexit adt7316_i2c_remove(struct i2c_client *client) +{ + return adt7316_remove(&client->dev);; +} + +static const struct i2c_device_id adt7316_i2c_id[] = { + { "adt7316", 0 }, + { "adt7317", 0 }, + { "adt7318", 0 }, + { "adt7516", 0 }, + { "adt7517", 0 }, + { "adt7519", 0 }, + { } +}; + +MODULE_DEVICE_TABLE(i2c, adt7316_i2c_id); + +#ifdef CONFIG_PM +static int adt7316_i2c_suspend(struct i2c_client *client, pm_message_t message) +{ + return adt7316_disable(&client->dev); +} + +static int adt7316_i2c_resume(struct i2c_client *client) +{ + return adt7316_enable(&client->dev); +} +#else +# define adt7316_i2c_suspend NULL +# define adt7316_i2c_resume NULL +#endif + +static struct i2c_driver adt7316_driver = { + .driver = { + .name = "adt7316", + .owner = THIS_MODULE, + }, + .probe = adt7316_i2c_probe, + .remove = __devexit_p(adt7316_i2c_remove), + .suspend = adt7316_i2c_suspend, + .resume = adt7316_i2c_resume, + .id_table = adt7316_i2c_id, +}; + +static __init int adt7316_i2c_init(void) +{ + return i2c_add_driver(&adt7316_driver); +} + +static __exit void adt7316_i2c_exit(void) +{ + i2c_del_driver(&adt7316_driver); +} + +MODULE_AUTHOR("Sonic Zhang "); +MODULE_DESCRIPTION("I2C bus driver for Analog Devices ADT7316/7/9 and" + "ADT7516/7/8 digital temperature sensor, ADC and DAC"); +MODULE_LICENSE("GPL v2"); + +module_init(adt7316_i2c_init); +module_exit(adt7316_i2c_exit); diff --git a/drivers/staging/iio/addac/adt7316-spi.c b/drivers/staging/iio/addac/adt7316-spi.c new file mode 100644 index 000000000000..369d4d01ed97 --- /dev/null +++ b/drivers/staging/iio/addac/adt7316-spi.c @@ -0,0 +1,180 @@ +/* + * API bus driver for ADT7316/7/8 ADT7516/7/9 digital temperature + * sensor, ADC and DAC + * + * Copyright 2010 Analog Devices Inc. + * + * Licensed under the GPL-2 or later. + */ + +#include +#include +#include +#include +#include + +#include "adt7316.h" + +#define ADT7316_SPI_MAX_FREQ_HZ 5000000 +#define ADT7316_SPI_CMD_READ 0x91 +#define ADT7316_SPI_CMD_WRITE 0x90 + +/* + * adt7316 register access by SPI + */ + +static int adt7316_spi_multi_read(void *client, u8 reg, u8 count, u8 *data) +{ + struct spi_device *spi_dev = client; + u8 cmd[2]; + int ret = 0; + + if (count > ADT7316_REG_MAX_ADDR) + count = ADT7316_REG_MAX_ADDR; + + cmd[0] = ADT7316_SPI_CMD_WRITE; + cmd[1] = reg; + + ret = spi_write(spi_dev, cmd, 2); + if (ret < 0) { + dev_err(&spi_dev->dev, "SPI fail to select reg\n"); + return ret; + } + + cmd[0] = ADT7316_SPI_CMD_READ; + + ret = spi_write_then_read(spi_dev, cmd, 1, data, count); + if (ret < 0) { + dev_err(&spi_dev->dev, "SPI read data error\n"); + return ret; + } + + return 0; +} + +static int adt7316_spi_multi_write(void *client, u8 reg, u8 count, u8 *data) +{ + struct spi_device *spi_dev = client; + u8 buf[ADT7316_REG_MAX_ADDR + 2]; + int i, ret = 0; + + if (count > ADT7316_REG_MAX_ADDR) + count = ADT7316_REG_MAX_ADDR; + + buf[0] = ADT7316_SPI_CMD_WRITE; + buf[1] = reg; + for (i = 0; i < count; i++) + buf[i + 2] = data[i]; + + ret = spi_write(spi_dev, buf, count + 2); + if (ret < 0) { + dev_err(&spi_dev->dev, "SPI write error\n"); + return ret; + } + + return ret; +} + +static int adt7316_spi_read(void *client, u8 reg, u8 *data) +{ + return adt7316_spi_multi_read(client, reg, 1, data); +} + +static int adt7316_spi_write(void *client, u8 reg, u8 val) +{ + return adt7316_spi_multi_write(client, reg, 1, &val); +} + +/* + * device probe and remove + */ + +static int __devinit adt7316_spi_probe(struct spi_device *spi_dev) +{ + struct adt7316_bus bus = { + .client = spi_dev, + .irq = spi_dev->irq, + .irq_flags = IRQF_TRIGGER_LOW, + .read = adt7316_spi_read, + .write = adt7316_spi_write, + .multi_read = adt7316_spi_multi_read, + .multi_write = adt7316_spi_multi_write, + }; + + /* don't exceed max specified SPI CLK frequency */ + if (spi_dev->max_speed_hz > ADT7316_SPI_MAX_FREQ_HZ) { + dev_err(&spi_dev->dev, "SPI CLK %d Hz?\n", + spi_dev->max_speed_hz); + return -EINVAL; + } + + /* switch from default I2C protocol to SPI protocol */ + adt7316_spi_write(spi_dev, 0, 0); + adt7316_spi_write(spi_dev, 0, 0); + adt7316_spi_write(spi_dev, 0, 0); + + return adt7316_probe(&spi_dev->dev, &bus, spi_dev->modalias); +} + +static int __devexit adt7316_spi_remove(struct spi_device *spi_dev) +{ + return adt7316_remove(&spi_dev->dev); +} + +static const struct spi_device_id adt7316_spi_id[] = { + { "adt7316", 0 }, + { "adt7317", 0 }, + { "adt7318", 0 }, + { "adt7516", 0 }, + { "adt7517", 0 }, + { "adt7519", 0 }, + { } +}; + +MODULE_DEVICE_TABLE(spi, adt7316_spi_id); + +#ifdef CONFIG_PM +static int adt7316_spi_suspend(struct spi_device *spi_dev, pm_message_t message) +{ + return adt7316_disable(&spi_dev->dev); +} + +static int adt7316_spi_resume(struct spi_device *spi_dev) +{ + return adt7316_enable(&spi_dev->dev); +} +#else +# define adt7316_spi_suspend NULL +# define adt7316_spi_resume NULL +#endif + +static struct spi_driver adt7316_driver = { + .driver = { + .name = "adt7316", + .bus = &spi_bus_type, + .owner = THIS_MODULE, + }, + .probe = adt7316_spi_probe, + .remove = __devexit_p(adt7316_spi_remove), + .suspend = adt7316_spi_suspend, + .resume = adt7316_spi_resume, + .id_table = adt7316_spi_id, +}; + +static __init int adt7316_spi_init(void) +{ + return spi_register_driver(&adt7316_driver); +} + +static __exit void adt7316_spi_exit(void) +{ + spi_unregister_driver(&adt7316_driver); +} + +MODULE_AUTHOR("Sonic Zhang "); +MODULE_DESCRIPTION("SPI bus driver for Analog Devices ADT7316/7/8 and" + "ADT7516/7/9 digital temperature sensor, ADC and DAC"); +MODULE_LICENSE("GPL v2"); + +module_init(adt7316_spi_init); +module_exit(adt7316_spi_exit); diff --git a/drivers/staging/iio/addac/adt7316.c b/drivers/staging/iio/addac/adt7316.c new file mode 100644 index 000000000000..d1b5b13629d9 --- /dev/null +++ b/drivers/staging/iio/addac/adt7316.c @@ -0,0 +1,2402 @@ +/* + * ADT7316 digital temperature sensor driver supporting ADT7316/7/8 ADT7516/7/9 + * + * + * Copyright 2010 Analog Devices Inc. + * + * Licensed under the GPL-2 or later. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../iio.h" +#include "../sysfs.h" +#include "adt7316.h" + +/* + * ADT7316 registers definition + */ +#define ADT7316_INT_STAT1 0x0 +#define ADT7316_INT_STAT2 0x1 +#define ADT7316_LSB_IN_TEMP_VDD 0x3 +#define ADT7316_LSB_IN_TEMP_MASK 0x3 +#define ADT7316_LSB_VDD_MASK 0xC +#define ADT7316_LSB_VDD_OFFSET 2 +#define ADT7316_LSB_EX_TEMP_AIN 0x4 +#define ADT7316_LSB_EX_TEMP_MASK 0x3 +#define ADT7516_LSB_AIN_SHIFT 2 +#define ADT7316_AD_MSB_DATA_BASE 0x6 +#define ADT7316_AD_MSB_DATA_REGS 3 +#define ADT7516_AD_MSB_DATA_REGS 6 +#define ADT7316_MSB_VDD 0x6 +#define ADT7316_MSB_IN_TEMP 0x7 +#define ADT7316_MSB_EX_TEMP 0x8 +#define ADT7516_MSB_AIN1 0x8 +#define ADT7516_MSB_AIN2 0x9 +#define ADT7516_MSB_AIN3 0xA +#define ADT7516_MSB_AIN4 0xB +#define ADT7316_DA_DATA_BASE 0x10 +#define ADT7316_DA_MSB_DATA_REGS 4 +#define ADT7316_LSB_DAC_A 0x10 +#define ADT7316_MSB_DAC_A 0x11 +#define ADT7316_LSB_DAC_B 0x12 +#define ADT7316_MSB_DAC_B 0x13 +#define ADT7316_LSB_DAC_C 0x14 +#define ADT7316_MSB_DAC_C 0x15 +#define ADT7316_LSB_DAC_D 0x16 +#define ADT7316_MSB_DAC_D 0x17 +#define ADT7316_CONFIG1 0x18 +#define ADT7316_CONFIG2 0x19 +#define ADT7316_CONFIG3 0x1A +#define ADT7316_LDAC_CONFIG 0x1B +#define ADT7316_DAC_CONFIG 0x1C +#define ADT7316_INT_MASK1 0x1D +#define ADT7316_INT_MASK2 0x1E +#define ADT7316_IN_TEMP_OFFSET 0x1F +#define ADT7316_EX_TEMP_OFFSET 0x20 +#define ADT7316_IN_ANALOG_TEMP_OFFSET 0x21 +#define ADT7316_EX_ANALOG_TEMP_OFFSET 0x22 +#define ADT7316_VDD_HIGH 0x23 +#define ADT7316_VDD_LOW 0x24 +#define ADT7316_IN_TEMP_HIGH 0x25 +#define ADT7316_IN_TEMP_LOW 0x26 +#define ADT7316_EX_TEMP_HIGH 0x27 +#define ADT7316_EX_TEMP_LOW 0x28 +#define ADT7516_AIN2_HIGH 0x2B +#define ADT7516_AIN2_LOW 0x2C +#define ADT7516_AIN3_HIGH 0x2D +#define ADT7516_AIN3_LOW 0x2E +#define ADT7516_AIN4_HIGH 0x2F +#define ADT7516_AIN4_LOW 0x30 +#define ADT7316_DEVICE_ID 0x4D +#define ADT7316_MANUFACTURE_ID 0x4E +#define ADT7316_DEVICE_REV 0x4F +#define ADT7316_SPI_LOCK_STAT 0x7F + +/* + * ADT7316 config1 + */ +#define ADT7316_EN 0x1 +#define ADT7516_SEL_EX_TEMP 0x4 +#define ADT7516_SEL_AIN1_2_EX_TEMP_MASK 0x6 +#define ADT7516_SEL_AIN3 0x8 +#define ADT7316_INT_EN 0x20 +#define ADT7316_INT_POLARITY 0x40 +#define ADT7316_PD 0x80 + +/* + * ADT7316 config2 + */ +#define ADT7316_AD_SINGLE_CH_MASK 0x3 +#define ADT7516_AD_SINGLE_CH_MASK 0x7 +#define ADT7316_AD_SINGLE_CH_VDD 0 +#define ADT7316_AD_SINGLE_CH_IN 1 +#define ADT7316_AD_SINGLE_CH_EX 2 +#define ADT7516_AD_SINGLE_CH_AIN1 2 +#define ADT7516_AD_SINGLE_CH_AIN2 3 +#define ADT7516_AD_SINGLE_CH_AIN3 4 +#define ADT7516_AD_SINGLE_CH_AIN4 5 +#define ADT7316_AD_SINGLE_CH_MODE 0x10 +#define ADT7316_DISABLE_AVERAGING 0x20 +#define ADT7316_EN_SMBUS_TIMEOUT 0x40 +#define ADT7316_RESET 0x80 + +/* + * ADT7316 config3 + */ +#define ADT7316_ADCLK_22_5 0x1 +#define ADT7316_DA_HIGH_RESOLUTION 0x2 +#define ADT7316_DA_EN_VIA_DAC_LDCA 0x4 +#define ADT7516_AIN_IN_VREF 0x10 +#define ADT7316_EN_IN_TEMP_PROP_DACA 0x20 +#define ADT7316_EN_EX_TEMP_PROP_DACB 0x40 + +/* + * ADT7316 DAC config + */ +#define ADT7316_DA_2VREF_CH_MASK 0xF +#define ADT7316_DA_EN_MODE_MASK 0x30 +#define ADT7316_DA_EN_MODE_SINGLE 0x00 +#define ADT7316_DA_EN_MODE_AB_CD 0x10 +#define ADT7316_DA_EN_MODE_ABCD 0x20 +#define ADT7316_DA_EN_MODE_LDAC 0x30 +#define ADT7316_VREF_BYPASS_DAC_AB 0x40 +#define ADT7316_VREF_BYPASS_DAC_CD 0x80 + +/* + * ADT7316 LDAC config + */ +#define ADT7316_LDAC_EN_DA_MASK 0xF +#define ADT7316_DAC_IN_VREF 0x10 +#define ADT7516_DAC_AB_IN_VREF 0x10 +#define ADT7516_DAC_CD_IN_VREF 0x20 +#define ADT7516_DAC_IN_VREF_OFFSET 4 +#define ADT7516_DAC_IN_VREF_MASK 0x30 + +/* + * ADT7316 INT_MASK2 + */ +#define ADT7316_INT_MASK2_VDD 0x10 + +/* + * ADT7316 value masks + */ +#define ADT7316_VALUE_MASK 0xfff +#define ADT7316_T_VALUE_SIGN 0x400 +#define ADT7316_T_VALUE_FLOAT_OFFSET 2 +#define ADT7316_T_VALUE_FLOAT_MASK 0x2 + +/* + * Chip ID + */ +#define ID_ADT7316 0x1 +#define ID_ADT7317 0x2 +#define ID_ADT7318 0x3 +#define ID_ADT7516 0x11 +#define ID_ADT7517 0x12 +#define ID_ADT7519 0x14 + +#define ID_FAMILY_MASK 0xF0 +#define ID_ADT73XX 0x0 +#define ID_ADT75XX 0x10 + +/* + * struct adt7316_chip_info - chip specifc information + */ + +struct adt7316_chip_info { + const char *name; + struct iio_dev *indio_dev; + struct work_struct thresh_work; + s64 last_timestamp; + struct adt7316_bus bus; + u16 ldac_pin; + u16 int_mask; /* 0x2f */ + u8 config1; + u8 config2; + u8 config3; + u8 dac_config; /* DAC config */ + u8 ldac_config; /* LDAC config */ + u8 dac_bits; /* 8, 10, 12 */ + u8 id; /* chip id */ +}; + +/* + * Logic interrupt mask for user application to enable + * interrupts. + */ +#define ADT7316_IN_TEMP_HIGH_INT_MASK 0x1 +#define ADT7316_IN_TEMP_LOW_INT_MASK 0x2 +#define ADT7316_EX_TEMP_HIGH_INT_MASK 0x4 +#define ADT7316_EX_TEMP_LOW_INT_MASK 0x8 +#define ADT7316_EX_TEMP_FAULT_INT_MASK 0x10 +#define ADT7516_AIN1_INT_MASK 0x4 +#define ADT7516_AIN2_INT_MASK 0x20 +#define ADT7516_AIN3_INT_MASK 0x40 +#define ADT7516_AIN4_INT_MASK 0x80 +#define ADT7316_VDD_INT_MASK 0x100 +#define ADT7316_TEMP_INT_MASK 0x1F +#define ADT7516_AIN_INT_MASK 0xE0 +#define ADT7316_TEMP_AIN_INT_MASK \ + (ADT7316_TEMP_INT_MASK | ADT7316_TEMP_INT_MASK) + +/* + * struct adt7316_chip_info - chip specifc information + */ + +struct adt7316_limit_regs { + u16 data_high; + u16 data_low; +}; + +static ssize_t adt7316_show_enabled(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct adt7316_chip_info *chip = dev_info->dev_data; + + return sprintf(buf, "%d\n", !!(chip->config1 & ADT7316_EN)); +} + +static ssize_t _adt7316_store_enabled(struct adt7316_chip_info *chip, + int enable) +{ + u8 config1; + int ret; + + if (enable) + config1 = chip->config1 | ADT7316_EN; + else + config1 = chip->config1 & ~ADT7316_EN; + + ret = chip->bus.write(chip->bus.client, ADT7316_CONFIG1, config1); + if (ret) + return -EIO; + + chip->config1 = config1; + + return ret; + +} + +static ssize_t adt7316_store_enabled(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct adt7316_chip_info *chip = dev_info->dev_data; + int enable; + + if (!memcmp(buf, "1", 1)) + enable = 1; + else + enable = 0; + + if (_adt7316_store_enabled(chip, enable) < 0) + return -EIO; + else + return len; +} + +static IIO_DEVICE_ATTR(enabled, S_IRUGO | S_IWUSR, + adt7316_show_enabled, + adt7316_store_enabled, + 0); + +static ssize_t adt7316_show_select_ex_temp(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct adt7316_chip_info *chip = dev_info->dev_data; + + if ((chip->id & ID_FAMILY_MASK) != ID_ADT75XX) + return -EPERM; + + return sprintf(buf, "%d\n", !!(chip->config1 & ADT7516_SEL_EX_TEMP)); +} + +static ssize_t adt7316_store_select_ex_temp(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct adt7316_chip_info *chip = dev_info->dev_data; + u8 config1; + int ret; + + if ((chip->id & ID_FAMILY_MASK) != ID_ADT75XX) + return -EPERM; + + config1 = chip->config1 & (~ADT7516_SEL_EX_TEMP); + if (!memcmp(buf, "1", 1)) + config1 |= ADT7516_SEL_EX_TEMP; + + ret = chip->bus.write(chip->bus.client, ADT7316_CONFIG1, config1); + if (ret) + return -EIO; + + chip->config1 = config1; + + return len; +} + +static IIO_DEVICE_ATTR(select_ex_temp, S_IRUGO | S_IWUSR, + adt7316_show_select_ex_temp, + adt7316_store_select_ex_temp, + 0); + +static ssize_t adt7316_show_mode(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct adt7316_chip_info *chip = dev_info->dev_data; + + if (chip->config2 & ADT7316_AD_SINGLE_CH_MODE) + return sprintf(buf, "single_channel\n"); + else + return sprintf(buf, "round_robin\n"); +} + +static ssize_t adt7316_store_mode(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct adt7316_chip_info *chip = dev_info->dev_data; + u8 config2; + int ret; + + config2 = chip->config2 & (~ADT7316_AD_SINGLE_CH_MODE); + if (!memcmp(buf, "single_channel", 14)) + config2 |= ADT7316_AD_SINGLE_CH_MODE; + + ret = chip->bus.write(chip->bus.client, ADT7316_CONFIG2, config2); + if (ret) + return -EIO; + + chip->config2 = config2; + + return len; +} + +static IIO_DEVICE_ATTR(mode, S_IRUGO | S_IWUSR, + adt7316_show_mode, + adt7316_store_mode, + 0); + +static ssize_t adt7316_show_all_modes(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + return sprintf(buf, "single_channel\nround_robin\n"); +} + +static IIO_DEVICE_ATTR(all_modes, S_IRUGO, adt7316_show_all_modes, NULL, 0); + +static ssize_t adt7316_show_ad_channel(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct adt7316_chip_info *chip = dev_info->dev_data; + + if (!(chip->config2 & ADT7316_AD_SINGLE_CH_MODE)) + return -EPERM; + + switch (chip->config2 & ADT7516_AD_SINGLE_CH_MASK) { + case ADT7316_AD_SINGLE_CH_VDD: + return sprintf(buf, "0 - VDD\n"); + case ADT7316_AD_SINGLE_CH_IN: + return sprintf(buf, "1 - Internal Temperature\n"); + case ADT7316_AD_SINGLE_CH_EX: + if (((chip->id & ID_FAMILY_MASK) == ID_ADT75XX) && + (chip->config1 & ADT7516_SEL_AIN1_2_EX_TEMP_MASK) == 0) + return sprintf(buf, "2 - AIN1\n"); + else + return sprintf(buf, "2 - External Temperature\n"); + case ADT7516_AD_SINGLE_CH_AIN2: + if ((chip->config1 & ADT7516_SEL_AIN1_2_EX_TEMP_MASK) == 0) + return sprintf(buf, "3 - AIN2\n"); + else + return sprintf(buf, "N/A\n"); + case ADT7516_AD_SINGLE_CH_AIN3: + if (chip->config1 & ADT7516_SEL_AIN3) + return sprintf(buf, "4 - AIN3\n"); + else + return sprintf(buf, "N/A\n"); + case ADT7516_AD_SINGLE_CH_AIN4: + return sprintf(buf, "5 - AIN4\n"); + default: + return sprintf(buf, "N/A\n"); + }; +} + +static ssize_t adt7316_store_ad_channel(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct adt7316_chip_info *chip = dev_info->dev_data; + u8 config2; + unsigned long data = 0; + int ret; + + if (!(chip->config2 & ADT7316_AD_SINGLE_CH_MODE)) + return -EPERM; + + ret = strict_strtoul(buf, 10, &data); + if (ret) + return -EINVAL; + + if ((chip->id & ID_FAMILY_MASK) == ID_ADT75XX) { + if (data > 5) + return -EINVAL; + + config2 = chip->config2 & (~ADT7516_AD_SINGLE_CH_MASK); + } else { + if (data > 2) + return -EINVAL; + + config2 = chip->config2 & (~ADT7316_AD_SINGLE_CH_MASK); + } + + + config2 |= data; + + ret = chip->bus.write(chip->bus.client, ADT7316_CONFIG2, config2); + if (ret) + return -EIO; + + chip->config2 = config2; + + return len; +} + +static IIO_DEVICE_ATTR(ad_channel, S_IRUGO | S_IWUSR, + adt7316_show_ad_channel, + adt7316_store_ad_channel, + 0); + +static ssize_t adt7316_show_all_ad_channels(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct adt7316_chip_info *chip = dev_info->dev_data; + + if (!(chip->config2 & ADT7316_AD_SINGLE_CH_MODE)) + return -EPERM; + + if ((chip->id & ID_FAMILY_MASK) == ID_ADT75XX) + return sprintf(buf, "0 - VDD\n1 - Internal Temperature\n" + "2 - External Temperature or AIN2\n" + "3 - AIN2\n4 - AIN3\n5 - AIN4\n"); + else + return sprintf(buf, "0 - VDD\n1 - Internal Temperature\n" + "2 - External Temperature\n"); +} + +static IIO_DEVICE_ATTR(all_ad_channels, S_IRUGO, + adt7316_show_all_ad_channels, NULL, 0); + +static ssize_t adt7316_show_disable_averaging(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct adt7316_chip_info *chip = dev_info->dev_data; + + return sprintf(buf, "%d\n", + !!(chip->config2 & ADT7316_DISABLE_AVERAGING)); +} + +static ssize_t adt7316_store_disable_averaging(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct adt7316_chip_info *chip = dev_info->dev_data; + u8 config2; + int ret; + + config2 = chip->config2 & (~ADT7316_DISABLE_AVERAGING); + if (!memcmp(buf, "1", 1)) + config2 |= ADT7316_DISABLE_AVERAGING; + + ret = chip->bus.write(chip->bus.client, ADT7316_CONFIG2, config2); + if (ret) + return -EIO; + + chip->config2 = config2; + + return len; +} + +static IIO_DEVICE_ATTR(disable_averaging, S_IRUGO | S_IWUSR, + adt7316_show_disable_averaging, + adt7316_store_disable_averaging, + 0); + +static ssize_t adt7316_show_enable_smbus_timeout(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct adt7316_chip_info *chip = dev_info->dev_data; + + return sprintf(buf, "%d\n", + !!(chip->config2 & ADT7316_EN_SMBUS_TIMEOUT)); +} + +static ssize_t adt7316_store_enable_smbus_timeout(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct adt7316_chip_info *chip = dev_info->dev_data; + u8 config2; + int ret; + + config2 = chip->config2 & (~ADT7316_EN_SMBUS_TIMEOUT); + if (!memcmp(buf, "1", 1)) + config2 |= ADT7316_EN_SMBUS_TIMEOUT; + + ret = chip->bus.write(chip->bus.client, ADT7316_CONFIG2, config2); + if (ret) + return -EIO; + + chip->config2 = config2; + + return len; +} + +static IIO_DEVICE_ATTR(enable_smbus_timeout, S_IRUGO | S_IWUSR, + adt7316_show_enable_smbus_timeout, + adt7316_store_enable_smbus_timeout, + 0); + + +static ssize_t adt7316_store_reset(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct adt7316_chip_info *chip = dev_info->dev_data; + u8 config2; + int ret; + + config2 = chip->config2 | ADT7316_RESET; + + ret = chip->bus.write(chip->bus.client, ADT7316_CONFIG2, config2); + if (ret) + return -EIO; + + return len; +} + +static IIO_DEVICE_ATTR(reset, S_IWUSR, + NULL, + adt7316_store_reset, + 0); + +static ssize_t adt7316_show_powerdown(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct adt7316_chip_info *chip = dev_info->dev_data; + + return sprintf(buf, "%d\n", !!(chip->config1 & ADT7316_PD)); +} + +static ssize_t adt7316_store_powerdown(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct adt7316_chip_info *chip = dev_info->dev_data; + u8 config1; + int ret; + + config1 = chip->config1 & (~ADT7316_PD); + if (!memcmp(buf, "1", 1)) + config1 |= ADT7316_PD; + + ret = chip->bus.write(chip->bus.client, ADT7316_CONFIG1, config1); + if (ret) + return -EIO; + + chip->config1 = config1; + + return len; +} + +static IIO_DEVICE_ATTR(powerdown, S_IRUGO | S_IWUSR, + adt7316_show_powerdown, + adt7316_store_powerdown, + 0); + +static ssize_t adt7316_show_fast_ad_clock(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct adt7316_chip_info *chip = dev_info->dev_data; + + return sprintf(buf, "%d\n", !!(chip->config3 & ADT7316_ADCLK_22_5)); +} + +static ssize_t adt7316_store_fast_ad_clock(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct adt7316_chip_info *chip = dev_info->dev_data; + u8 config3; + int ret; + + config3 = chip->config3 & (~ADT7316_ADCLK_22_5); + if (!memcmp(buf, "1", 1)) + config3 |= ADT7316_ADCLK_22_5; + + ret = chip->bus.write(chip->bus.client, ADT7316_CONFIG3, config3); + if (ret) + return -EIO; + + chip->config3 = config3; + + return len; +} + +static IIO_DEVICE_ATTR(fast_ad_clock, S_IRUGO | S_IWUSR, + adt7316_show_fast_ad_clock, + adt7316_store_fast_ad_clock, + 0); + +static ssize_t adt7316_show_da_high_resolution(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct adt7316_chip_info *chip = dev_info->dev_data; + + if (chip->config3 & ADT7316_DA_HIGH_RESOLUTION) { + if (chip->id == ID_ADT7316 || chip->id == ID_ADT7516) + return sprintf(buf, "1 (12 bits)\n"); + else if (chip->id == ID_ADT7317 || chip->id == ID_ADT7517) + return sprintf(buf, "1 (10 bits)\n"); + } + + return sprintf(buf, "0 (8 bits)\n"); +} + +static ssize_t adt7316_store_da_high_resolution(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct adt7316_chip_info *chip = dev_info->dev_data; + u8 config3; + int ret; + + chip->dac_bits = 8; + + if (!memcmp(buf, "1", 1)) { + config3 = chip->config3 | ADT7316_DA_HIGH_RESOLUTION; + if (chip->id == ID_ADT7316 || chip->id == ID_ADT7516) + chip->dac_bits = 12; + else if (chip->id == ID_ADT7317 || chip->id == ID_ADT7517) + chip->dac_bits = 10; + } else + config3 = chip->config3 & (~ADT7316_DA_HIGH_RESOLUTION); + + ret = chip->bus.write(chip->bus.client, ADT7316_CONFIG3, config3); + if (ret) + return -EIO; + + chip->config3 = config3; + + return len; +} + +static IIO_DEVICE_ATTR(da_high_resolution, S_IRUGO | S_IWUSR, + adt7316_show_da_high_resolution, + adt7316_store_da_high_resolution, + 0); + +static ssize_t adt7316_show_AIN_internal_Vref(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct adt7316_chip_info *chip = dev_info->dev_data; + + if ((chip->id & ID_FAMILY_MASK) != ID_ADT75XX) + return -EPERM; + + return sprintf(buf, "%d\n", + !!(chip->config3 & ADT7516_AIN_IN_VREF)); +} + +static ssize_t adt7316_store_AIN_internal_Vref(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct adt7316_chip_info *chip = dev_info->dev_data; + u8 config3; + int ret; + + if ((chip->id & ID_FAMILY_MASK) != ID_ADT75XX) + return -EPERM; + + if (memcmp(buf, "1", 1)) + config3 = chip->config3 & (~ADT7516_AIN_IN_VREF); + else + config3 = chip->config3 | ADT7516_AIN_IN_VREF; + + ret = chip->bus.write(chip->bus.client, ADT7316_CONFIG3, config3); + if (ret) + return -EIO; + + chip->config3 = config3; + + return len; +} + +static IIO_DEVICE_ATTR(AIN_internal_Vref, S_IRUGO | S_IWUSR, + adt7316_show_AIN_internal_Vref, + adt7316_store_AIN_internal_Vref, + 0); + + +static ssize_t adt7316_show_enable_prop_DACA(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct adt7316_chip_info *chip = dev_info->dev_data; + + return sprintf(buf, "%d\n", + !!(chip->config3 & ADT7316_EN_IN_TEMP_PROP_DACA)); +} + +static ssize_t adt7316_store_enable_prop_DACA(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct adt7316_chip_info *chip = dev_info->dev_data; + u8 config3; + int ret; + + config3 = chip->config3 & (~ADT7316_EN_IN_TEMP_PROP_DACA); + if (!memcmp(buf, "1", 1)) + config3 |= ADT7316_EN_IN_TEMP_PROP_DACA; + + ret = chip->bus.write(chip->bus.client, ADT7316_CONFIG3, config3); + if (ret) + return -EIO; + + chip->config3 = config3; + + return len; +} + +static IIO_DEVICE_ATTR(enable_proportion_DACA, S_IRUGO | S_IWUSR, + adt7316_show_enable_prop_DACA, + adt7316_store_enable_prop_DACA, + 0); + +static ssize_t adt7316_show_enable_prop_DACB(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct adt7316_chip_info *chip = dev_info->dev_data; + + return sprintf(buf, "%d\n", + !!(chip->config3 & ADT7316_EN_EX_TEMP_PROP_DACB)); +} + +static ssize_t adt7316_store_enable_prop_DACB(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct adt7316_chip_info *chip = dev_info->dev_data; + u8 config3; + int ret; + + config3 = chip->config3 & (~ADT7316_EN_EX_TEMP_PROP_DACB); + if (!memcmp(buf, "1", 1)) + config3 |= ADT7316_EN_EX_TEMP_PROP_DACB; + + ret = chip->bus.write(chip->bus.client, ADT7316_CONFIG3, config3); + if (ret) + return -EIO; + + chip->config3 = config3; + + return len; +} + +static IIO_DEVICE_ATTR(enable_proportion_DACB, S_IRUGO | S_IWUSR, + adt7316_show_enable_prop_DACB, + adt7316_store_enable_prop_DACB, + 0); + +static ssize_t adt7316_show_DAC_2Vref_ch_mask(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct adt7316_chip_info *chip = dev_info->dev_data; + + return sprintf(buf, "0x%x\n", + chip->dac_config & ADT7316_DA_2VREF_CH_MASK); +} + +static ssize_t adt7316_store_DAC_2Vref_ch_mask(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct adt7316_chip_info *chip = dev_info->dev_data; + u8 dac_config; + unsigned long data = 0; + int ret; + + ret = strict_strtoul(buf, 16, &data); + if (ret || data > ADT7316_DA_2VREF_CH_MASK) + return -EINVAL; + + dac_config = chip->dac_config & (~ADT7316_DA_2VREF_CH_MASK); + dac_config |= data; + + ret = chip->bus.write(chip->bus.client, ADT7316_DAC_CONFIG, dac_config); + if (ret) + return -EIO; + + chip->dac_config = dac_config; + + return len; +} + +static IIO_DEVICE_ATTR(DAC_2Vref_channels_mask, S_IRUGO | S_IWUSR, + adt7316_show_DAC_2Vref_ch_mask, + adt7316_store_DAC_2Vref_ch_mask, + 0); + +static ssize_t adt7316_show_DAC_update_mode(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct adt7316_chip_info *chip = dev_info->dev_data; + + if (!(chip->config3 & ADT7316_DA_EN_VIA_DAC_LDCA)) + return sprintf(buf, "manual\n"); + else { + switch (chip->dac_config & ADT7316_DA_EN_MODE_MASK) { + case ADT7316_DA_EN_MODE_SINGLE: + return sprintf(buf, "0 - auto at any MSB DAC writing\n"); + case ADT7316_DA_EN_MODE_AB_CD: + return sprintf(buf, "1 - auto at MSB DAC AB and CD writing\n"); + case ADT7316_DA_EN_MODE_ABCD: + return sprintf(buf, "2 - auto at MSB DAC ABCD writing\n"); + default: /* ADT7316_DA_EN_MODE_LDAC */ + return sprintf(buf, "3 - manual\n"); + }; + } +} + +static ssize_t adt7316_store_DAC_update_mode(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct adt7316_chip_info *chip = dev_info->dev_data; + u8 dac_config; + unsigned long data; + int ret; + + if (!(chip->config3 & ADT7316_DA_EN_VIA_DAC_LDCA)) + return -EPERM; + + ret = strict_strtoul(buf, 10, &data); + if (ret || data > ADT7316_DA_EN_MODE_MASK) + return -EINVAL; + + dac_config = chip->dac_config & (~ADT7316_DA_EN_MODE_MASK); + dac_config |= data; + + ret = chip->bus.write(chip->bus.client, ADT7316_DAC_CONFIG, dac_config); + if (ret) + return -EIO; + + chip->dac_config = dac_config; + + return len; +} + +static IIO_DEVICE_ATTR(DAC_update_mode, S_IRUGO | S_IWUSR, + adt7316_show_DAC_update_mode, + adt7316_store_DAC_update_mode, + 0); + +static ssize_t adt7316_show_all_DAC_update_modes(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct adt7316_chip_info *chip = dev_info->dev_data; + + if (chip->config3 & ADT7316_DA_EN_VIA_DAC_LDCA) + return sprintf(buf, "0 - auto at any MSB DAC writing\n" + "1 - auto at MSB DAC AB and CD writing\n" + "2 - auto at MSB DAC ABCD writing\n" + "3 - manual\n"); + else + return sprintf(buf, "manual\n"); +} + +static IIO_DEVICE_ATTR(all_DAC_update_modes, S_IRUGO, + adt7316_show_all_DAC_update_modes, NULL, 0); + + +static ssize_t adt7316_store_update_DAC(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct adt7316_chip_info *chip = dev_info->dev_data; + u8 ldac_config; + unsigned long data; + int ret; + + if (chip->config3 & ADT7316_DA_EN_VIA_DAC_LDCA) { + if ((chip->dac_config & ADT7316_DA_EN_MODE_MASK) != + ADT7316_DA_EN_MODE_LDAC) + return -EPERM; + + ret = strict_strtoul(buf, 16, &data); + if (ret || data > ADT7316_LDAC_EN_DA_MASK) + return -EINVAL; + + ldac_config = chip->ldac_config & (~ADT7316_LDAC_EN_DA_MASK); + ldac_config |= data; + + ret = chip->bus.write(chip->bus.client, ADT7316_LDAC_CONFIG, + ldac_config); + if (ret) + return -EIO; + } else { + gpio_set_value(chip->ldac_pin, 0); + gpio_set_value(chip->ldac_pin, 1); + } + + return len; +} + +static IIO_DEVICE_ATTR(update_DAC, S_IRUGO | S_IWUSR, + NULL, + adt7316_store_update_DAC, + 0); + +static ssize_t adt7316_show_DA_AB_Vref_bypass(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct adt7316_chip_info *chip = dev_info->dev_data; + + if ((chip->id & ID_FAMILY_MASK) == ID_ADT75XX) + return -EPERM; + + return sprintf(buf, "%d\n", + !!(chip->dac_config & ADT7316_VREF_BYPASS_DAC_AB)); +} + +static ssize_t adt7316_store_DA_AB_Vref_bypass(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct adt7316_chip_info *chip = dev_info->dev_data; + u8 dac_config; + int ret; + + if ((chip->id & ID_FAMILY_MASK) == ID_ADT75XX) + return -EPERM; + + dac_config = chip->dac_config & (~ADT7316_VREF_BYPASS_DAC_AB); + if (!memcmp(buf, "1", 1)) + dac_config |= ADT7316_VREF_BYPASS_DAC_AB; + + ret = chip->bus.write(chip->bus.client, ADT7316_DAC_CONFIG, dac_config); + if (ret) + return -EIO; + + chip->dac_config = dac_config; + + return len; +} + +static IIO_DEVICE_ATTR(DA_AB_Vref_bypass, S_IRUGO | S_IWUSR, + adt7316_show_DA_AB_Vref_bypass, + adt7316_store_DA_AB_Vref_bypass, + 0); + +static ssize_t adt7316_show_DA_CD_Vref_bypass(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct adt7316_chip_info *chip = dev_info->dev_data; + + if ((chip->id & ID_FAMILY_MASK) == ID_ADT75XX) + return -EPERM; + + return sprintf(buf, "%d\n", + !!(chip->dac_config & ADT7316_VREF_BYPASS_DAC_CD)); +} + +static ssize_t adt7316_store_DA_CD_Vref_bypass(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct adt7316_chip_info *chip = dev_info->dev_data; + u8 dac_config; + int ret; + + if ((chip->id & ID_FAMILY_MASK) == ID_ADT75XX) + return -EPERM; + + dac_config = chip->dac_config & (~ADT7316_VREF_BYPASS_DAC_CD); + if (!memcmp(buf, "1", 1)) + dac_config |= ADT7316_VREF_BYPASS_DAC_CD; + + ret = chip->bus.write(chip->bus.client, ADT7316_DAC_CONFIG, dac_config); + if (ret) + return -EIO; + + chip->dac_config = dac_config; + + return len; +} + +static IIO_DEVICE_ATTR(DA_CD_Vref_bypass, S_IRUGO | S_IWUSR, + adt7316_show_DA_CD_Vref_bypass, + adt7316_store_DA_CD_Vref_bypass, + 0); + +static ssize_t adt7316_show_DAC_internal_Vref(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct adt7316_chip_info *chip = dev_info->dev_data; + + if ((chip->id & ID_FAMILY_MASK) == ID_ADT75XX) + return sprintf(buf, "0x%x\n", + (chip->dac_config & ADT7516_DAC_IN_VREF_MASK) >> + ADT7516_DAC_IN_VREF_OFFSET); + else + return sprintf(buf, "%d\n", + !!(chip->dac_config & ADT7316_DAC_IN_VREF)); +} + +static ssize_t adt7316_store_DAC_internal_Vref(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct adt7316_chip_info *chip = dev_info->dev_data; + u8 ldac_config; + unsigned long data; + int ret; + + if ((chip->id & ID_FAMILY_MASK) == ID_ADT75XX) { + ret = strict_strtoul(buf, 16, &data); + if (ret || data > 3) + return -EINVAL; + + ldac_config = chip->ldac_config & (~ADT7516_DAC_IN_VREF_MASK); + if (data & 0x1) + ldac_config |= ADT7516_DAC_AB_IN_VREF; + else if (data & 0x2) + ldac_config |= ADT7516_DAC_CD_IN_VREF; + } else { + ret = strict_strtoul(buf, 16, &data); + if (ret) + return -EINVAL; + + ldac_config = chip->ldac_config & (~ADT7316_DAC_IN_VREF); + if (data) + ldac_config = chip->ldac_config | ADT7316_DAC_IN_VREF; + } + + ret = chip->bus.write(chip->bus.client, ADT7316_LDAC_CONFIG, ldac_config); + if (ret) + return -EIO; + + chip->ldac_config = ldac_config; + + return len; +} + +static IIO_DEVICE_ATTR(DAC_internal_Vref, S_IRUGO | S_IWUSR, + adt7316_show_DAC_internal_Vref, + adt7316_store_DAC_internal_Vref, + 0); + +static ssize_t adt7316_show_ad(struct adt7316_chip_info *chip, + int channel, char *buf) +{ + u16 data; + u8 msb, lsb; + char sign = ' '; + int ret; + + if ((chip->config2 & ADT7316_AD_SINGLE_CH_MODE) && + channel != (chip->config2 & ADT7516_AD_SINGLE_CH_MASK)) + return -EPERM; + + switch (channel) { + case ADT7316_AD_SINGLE_CH_IN: + ret = chip->bus.read(chip->bus.client, + ADT7316_LSB_IN_TEMP_VDD, &lsb); + if (ret) + return -EIO; + + ret = chip->bus.read(chip->bus.client, + ADT7316_AD_MSB_DATA_BASE + channel, &msb); + if (ret) + return -EIO; + + data = msb << ADT7316_T_VALUE_FLOAT_OFFSET; + data |= lsb & ADT7316_LSB_IN_TEMP_MASK; + break; + case ADT7316_AD_SINGLE_CH_VDD: + ret = chip->bus.read(chip->bus.client, + ADT7316_LSB_IN_TEMP_VDD, &lsb); + if (ret) + return -EIO; + + ret = chip->bus.read(chip->bus.client, + + ADT7316_AD_MSB_DATA_BASE + channel, &msb); + if (ret) + return -EIO; + + data = msb << ADT7316_T_VALUE_FLOAT_OFFSET; + data |= (lsb & ADT7316_LSB_VDD_MASK) >> ADT7316_LSB_VDD_OFFSET; + return sprintf(buf, "%d\n", data); + default: /* ex_temp and ain */ + ret = chip->bus.read(chip->bus.client, + ADT7316_LSB_EX_TEMP_AIN, &lsb); + if (ret) + return -EIO; + + ret = chip->bus.read(chip->bus.client, + ADT7316_AD_MSB_DATA_BASE + channel, &msb); + if (ret) + return -EIO; + + data = msb << ADT7316_T_VALUE_FLOAT_OFFSET; + data |= lsb & (ADT7316_LSB_EX_TEMP_MASK << + (ADT7516_LSB_AIN_SHIFT * (channel - + (ADT7316_MSB_EX_TEMP - ADT7316_AD_MSB_DATA_BASE)))); + + if ((chip->id & ID_FAMILY_MASK) == ID_ADT75XX) + return sprintf(buf, "%d\n", data); + else + break; + }; + + if (data & ADT7316_T_VALUE_SIGN) { + /* convert supplement to positive value */ + data = (ADT7316_T_VALUE_SIGN << 1) - data; + sign = '-'; + } + + return sprintf(buf, "%c%d.%.2d\n", sign, + (data >> ADT7316_T_VALUE_FLOAT_OFFSET), + (data & ADT7316_T_VALUE_FLOAT_MASK) * 25); +} + +static ssize_t adt7316_show_VDD(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct adt7316_chip_info *chip = dev_info->dev_data; + + return adt7316_show_ad(chip, ADT7316_AD_SINGLE_CH_VDD, buf); +} +static IIO_DEVICE_ATTR(VDD, S_IRUGO, adt7316_show_VDD, NULL, 0); + +static ssize_t adt7316_show_in_temp(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct adt7316_chip_info *chip = dev_info->dev_data; + + return adt7316_show_ad(chip, ADT7316_AD_SINGLE_CH_IN, buf); +} + +static IIO_DEVICE_ATTR(in_temp, S_IRUGO, adt7316_show_in_temp, NULL, 0); + +static ssize_t adt7316_show_ex_temp_AIN1(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct adt7316_chip_info *chip = dev_info->dev_data; + + return adt7316_show_ad(chip, ADT7316_AD_SINGLE_CH_EX, buf); +} + +static IIO_DEVICE_ATTR(ex_temp_AIN1, S_IRUGO, adt7316_show_ex_temp_AIN1, NULL, 0); +static IIO_DEVICE_ATTR(ex_temp, S_IRUGO, adt7316_show_ex_temp_AIN1, NULL, 0); + +static ssize_t adt7316_show_AIN2(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct adt7316_chip_info *chip = dev_info->dev_data; + + return adt7316_show_ad(chip, ADT7516_AD_SINGLE_CH_AIN2, buf); +} +static IIO_DEVICE_ATTR(AIN2, S_IRUGO, adt7316_show_AIN2, NULL, 0); + +static ssize_t adt7316_show_AIN3(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct adt7316_chip_info *chip = dev_info->dev_data; + + return adt7316_show_ad(chip, ADT7516_AD_SINGLE_CH_AIN3, buf); +} +static IIO_DEVICE_ATTR(AIN3, S_IRUGO, adt7316_show_AIN3, NULL, 0); + +static ssize_t adt7316_show_AIN4(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct adt7316_chip_info *chip = dev_info->dev_data; + + return adt7316_show_ad(chip, ADT7516_AD_SINGLE_CH_AIN4, buf); +} +static IIO_DEVICE_ATTR(AIN4, S_IRUGO, adt7316_show_AIN4, NULL, 0); + +static ssize_t adt7316_show_temp_offset(struct adt7316_chip_info *chip, + int offset_addr, char *buf) +{ + int data; + u8 val; + int ret; + + ret = chip->bus.read(chip->bus.client, offset_addr, &val); + if (ret) + return -EIO; + + data = (int)val; + if (val & 0x80) + data -= 256; + + return sprintf(buf, "%d\n", data); +} + +static ssize_t adt7316_store_temp_offset(struct adt7316_chip_info *chip, + int offset_addr, const char *buf, size_t len) +{ + long data; + u8 val; + int ret; + + ret = strict_strtol(buf, 10, &data); + if (ret || data > 127 || data < -128) + return -EINVAL; + + if (data < 0) + data += 256; + + val = (u8)data; + + ret = chip->bus.write(chip->bus.client, offset_addr, val); + if (ret) + return -EIO; + + return len; +} + +static ssize_t adt7316_show_in_temp_offset(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct adt7316_chip_info *chip = dev_info->dev_data; + + return adt7316_show_temp_offset(chip, ADT7316_IN_TEMP_OFFSET, buf); +} + +static ssize_t adt7316_store_in_temp_offset(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct adt7316_chip_info *chip = dev_info->dev_data; + + return adt7316_store_temp_offset(chip, ADT7316_IN_TEMP_OFFSET, buf, len); +} + +static IIO_DEVICE_ATTR(in_temp_offset, S_IRUGO | S_IWUSR, + adt7316_show_in_temp_offset, + adt7316_store_in_temp_offset, 0); + +static ssize_t adt7316_show_ex_temp_offset(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct adt7316_chip_info *chip = dev_info->dev_data; + + return adt7316_show_temp_offset(chip, ADT7316_EX_TEMP_OFFSET, buf); +} + +static ssize_t adt7316_store_ex_temp_offset(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct adt7316_chip_info *chip = dev_info->dev_data; + + return adt7316_store_temp_offset(chip, ADT7316_EX_TEMP_OFFSET, buf, len); +} + +static IIO_DEVICE_ATTR(ex_temp_offset, S_IRUGO | S_IWUSR, + adt7316_show_ex_temp_offset, + adt7316_store_ex_temp_offset, 0); + +static ssize_t adt7316_show_in_analog_temp_offset(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct adt7316_chip_info *chip = dev_info->dev_data; + + return adt7316_show_temp_offset(chip, + ADT7316_IN_ANALOG_TEMP_OFFSET, buf); +} + +static ssize_t adt7316_store_in_analog_temp_offset(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct adt7316_chip_info *chip = dev_info->dev_data; + + return adt7316_store_temp_offset(chip, + ADT7316_IN_ANALOG_TEMP_OFFSET, buf, len); +} + +static IIO_DEVICE_ATTR(in_analog_temp_offset, S_IRUGO | S_IWUSR, + adt7316_show_in_analog_temp_offset, + adt7316_store_in_analog_temp_offset, 0); + +static ssize_t adt7316_show_ex_analog_temp_offset(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct adt7316_chip_info *chip = dev_info->dev_data; + + return adt7316_show_temp_offset(chip, + ADT7316_EX_ANALOG_TEMP_OFFSET, buf); +} + +static ssize_t adt7316_store_ex_analog_temp_offset(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct adt7316_chip_info *chip = dev_info->dev_data; + + return adt7316_store_temp_offset(chip, + ADT7316_EX_ANALOG_TEMP_OFFSET, buf, len); +} + +static IIO_DEVICE_ATTR(ex_analog_temp_offset, S_IRUGO | S_IWUSR, + adt7316_show_ex_analog_temp_offset, + adt7316_store_ex_analog_temp_offset, 0); + +static ssize_t adt7316_show_DAC(struct adt7316_chip_info *chip, + int channel, char *buf) +{ + u16 data; + u8 msb, lsb, offset; + int ret; + + if (channel >= ADT7316_DA_MSB_DATA_REGS || + (channel == 0 && + (chip->config3 & ADT7316_EN_IN_TEMP_PROP_DACA)) || + (channel == 1 && + (chip->config3 & ADT7316_EN_EX_TEMP_PROP_DACB))) + return -EPERM; + + offset = chip->dac_bits - 8; + + if (chip->dac_bits > 8) { + ret = chip->bus.read(chip->bus.client, + ADT7316_DA_DATA_BASE + channel * 2, &lsb); + if (ret) + return -EIO; + } + + ret = chip->bus.read(chip->bus.client, + ADT7316_DA_DATA_BASE + 1 + channel * 2, &msb); + if (ret) + return -EIO; + + data = (msb << offset) + (lsb & ((1 << offset) - 1)); + + return sprintf(buf, "%d\n", data); +} + +static ssize_t adt7316_store_DAC(struct adt7316_chip_info *chip, + int channel, const char *buf, size_t len) +{ + u8 msb, lsb, offset; + unsigned long data; + int ret; + + if (channel >= ADT7316_DA_MSB_DATA_REGS || + (channel == 0 && + (chip->config3 & ADT7316_EN_IN_TEMP_PROP_DACA)) || + (channel == 1 && + (chip->config3 & ADT7316_EN_EX_TEMP_PROP_DACB))) + return -EPERM; + + offset = chip->dac_bits - 8; + + ret = strict_strtoul(buf, 10, &data); + if (ret || data >= (1 << chip->dac_bits)) + return -EINVAL; + + if (chip->dac_bits > 8) { + lsb = data & (1 << offset); + ret = chip->bus.write(chip->bus.client, + ADT7316_DA_DATA_BASE + channel * 2, lsb); + if (ret) + return -EIO; + } + + msb = data >> offset; + ret = chip->bus.write(chip->bus.client, + ADT7316_DA_DATA_BASE + 1 + channel * 2, msb); + if (ret) + return -EIO; + + return len; +} + +static ssize_t adt7316_show_DAC_A(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct adt7316_chip_info *chip = dev_info->dev_data; + + return adt7316_show_DAC(chip, 0, buf); +} + +static ssize_t adt7316_store_DAC_A(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct adt7316_chip_info *chip = dev_info->dev_data; + + return adt7316_store_DAC(chip, 0, buf, len); +} + +static IIO_DEVICE_ATTR(DAC_A, S_IRUGO | S_IWUSR, adt7316_show_DAC_A, + adt7316_store_DAC_A, 0); + +static ssize_t adt7316_show_DAC_B(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct adt7316_chip_info *chip = dev_info->dev_data; + + return adt7316_show_DAC(chip, 1, buf); +} + +static ssize_t adt7316_store_DAC_B(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct adt7316_chip_info *chip = dev_info->dev_data; + + return adt7316_store_DAC(chip, 1, buf, len); +} + +static IIO_DEVICE_ATTR(DAC_B, S_IRUGO | S_IWUSR, adt7316_show_DAC_B, + adt7316_store_DAC_B, 0); + +static ssize_t adt7316_show_DAC_C(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct adt7316_chip_info *chip = dev_info->dev_data; + + return adt7316_show_DAC(chip, 2, buf); +} + +static ssize_t adt7316_store_DAC_C(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct adt7316_chip_info *chip = dev_info->dev_data; + + return adt7316_store_DAC(chip, 2, buf, len); +} + +static IIO_DEVICE_ATTR(DAC_C, S_IRUGO | S_IWUSR, adt7316_show_DAC_C, + adt7316_store_DAC_C, 0); + +static ssize_t adt7316_show_DAC_D(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct adt7316_chip_info *chip = dev_info->dev_data; + + return adt7316_show_DAC(chip, 3, buf); +} + +static ssize_t adt7316_store_DAC_D(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct adt7316_chip_info *chip = dev_info->dev_data; + + return adt7316_store_DAC(chip, 3, buf, len); +} + +static IIO_DEVICE_ATTR(DAC_D, S_IRUGO | S_IWUSR, adt7316_show_DAC_D, + adt7316_store_DAC_D, 0); + +static ssize_t adt7316_show_device_id(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct adt7316_chip_info *chip = dev_info->dev_data; + u8 id; + int ret; + + ret = chip->bus.read(chip->bus.client, ADT7316_DEVICE_ID, &id); + if (ret) + return -EIO; + + return sprintf(buf, "%d\n", id); +} + +static IIO_DEVICE_ATTR(device_id, S_IRUGO, adt7316_show_device_id, NULL, 0); + +static ssize_t adt7316_show_manufactorer_id(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct adt7316_chip_info *chip = dev_info->dev_data; + u8 id; + int ret; + + ret = chip->bus.read(chip->bus.client, ADT7316_MANUFACTURE_ID, &id); + if (ret) + return -EIO; + + return sprintf(buf, "%d\n", id); +} + +static IIO_DEVICE_ATTR(manufactorer_id, S_IRUGO, + adt7316_show_manufactorer_id, NULL, 0); + +static ssize_t adt7316_show_device_rev(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct adt7316_chip_info *chip = dev_info->dev_data; + u8 rev; + int ret; + + ret = chip->bus.read(chip->bus.client, ADT7316_DEVICE_REV, &rev); + if (ret) + return -EIO; + + return sprintf(buf, "%d\n", rev); +} + +static IIO_DEVICE_ATTR(device_rev, S_IRUGO, adt7316_show_device_rev, NULL, 0); + +static ssize_t adt7316_show_bus_type(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct adt7316_chip_info *chip = dev_info->dev_data; + u8 stat; + int ret; + + ret = chip->bus.read(chip->bus.client, ADT7316_SPI_LOCK_STAT, &stat); + if (ret) + return -EIO; + + if (stat) + return sprintf(buf, "spi\n"); + else + return sprintf(buf, "i2c\n"); +} + +static IIO_DEVICE_ATTR(bus_type, S_IRUGO, adt7316_show_bus_type, NULL, 0); + +static ssize_t adt7316_show_name(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct adt7316_chip_info *chip = dev_info->dev_data; + + return sprintf(buf, "%s\n", chip->name); +} + +static IIO_DEVICE_ATTR(name, S_IRUGO, adt7316_show_name, NULL, 0); + +static struct attribute *adt7316_attributes[] = { + &iio_dev_attr_all_modes.dev_attr.attr, + &iio_dev_attr_mode.dev_attr.attr, + &iio_dev_attr_reset.dev_attr.attr, + &iio_dev_attr_enabled.dev_attr.attr, + &iio_dev_attr_ad_channel.dev_attr.attr, + &iio_dev_attr_all_ad_channels.dev_attr.attr, + &iio_dev_attr_disable_averaging.dev_attr.attr, + &iio_dev_attr_enable_smbus_timeout.dev_attr.attr, + &iio_dev_attr_powerdown.dev_attr.attr, + &iio_dev_attr_fast_ad_clock.dev_attr.attr, + &iio_dev_attr_da_high_resolution.dev_attr.attr, + &iio_dev_attr_enable_proportion_DACA.dev_attr.attr, + &iio_dev_attr_enable_proportion_DACB.dev_attr.attr, + &iio_dev_attr_DAC_2Vref_channels_mask.dev_attr.attr, + &iio_dev_attr_DAC_update_mode.dev_attr.attr, + &iio_dev_attr_all_DAC_update_modes.dev_attr.attr, + &iio_dev_attr_update_DAC.dev_attr.attr, + &iio_dev_attr_DA_AB_Vref_bypass.dev_attr.attr, + &iio_dev_attr_DA_CD_Vref_bypass.dev_attr.attr, + &iio_dev_attr_DAC_internal_Vref.dev_attr.attr, + &iio_dev_attr_VDD.dev_attr.attr, + &iio_dev_attr_in_temp.dev_attr.attr, + &iio_dev_attr_ex_temp.dev_attr.attr, + &iio_dev_attr_in_temp_offset.dev_attr.attr, + &iio_dev_attr_ex_temp_offset.dev_attr.attr, + &iio_dev_attr_in_analog_temp_offset.dev_attr.attr, + &iio_dev_attr_ex_analog_temp_offset.dev_attr.attr, + &iio_dev_attr_DAC_A.dev_attr.attr, + &iio_dev_attr_DAC_B.dev_attr.attr, + &iio_dev_attr_DAC_C.dev_attr.attr, + &iio_dev_attr_DAC_D.dev_attr.attr, + &iio_dev_attr_device_id.dev_attr.attr, + &iio_dev_attr_manufactorer_id.dev_attr.attr, + &iio_dev_attr_device_rev.dev_attr.attr, + &iio_dev_attr_bus_type.dev_attr.attr, + &iio_dev_attr_name.dev_attr.attr, + NULL, +}; + +static const struct attribute_group adt7316_attribute_group = { + .attrs = adt7316_attributes, +}; + +static struct attribute *adt7516_attributes[] = { + &iio_dev_attr_all_modes.dev_attr.attr, + &iio_dev_attr_mode.dev_attr.attr, + &iio_dev_attr_select_ex_temp.dev_attr.attr, + &iio_dev_attr_reset.dev_attr.attr, + &iio_dev_attr_enabled.dev_attr.attr, + &iio_dev_attr_ad_channel.dev_attr.attr, + &iio_dev_attr_all_ad_channels.dev_attr.attr, + &iio_dev_attr_disable_averaging.dev_attr.attr, + &iio_dev_attr_enable_smbus_timeout.dev_attr.attr, + &iio_dev_attr_powerdown.dev_attr.attr, + &iio_dev_attr_fast_ad_clock.dev_attr.attr, + &iio_dev_attr_AIN_internal_Vref.dev_attr.attr, + &iio_dev_attr_da_high_resolution.dev_attr.attr, + &iio_dev_attr_enable_proportion_DACA.dev_attr.attr, + &iio_dev_attr_enable_proportion_DACB.dev_attr.attr, + &iio_dev_attr_DAC_2Vref_channels_mask.dev_attr.attr, + &iio_dev_attr_DAC_update_mode.dev_attr.attr, + &iio_dev_attr_all_DAC_update_modes.dev_attr.attr, + &iio_dev_attr_update_DAC.dev_attr.attr, + &iio_dev_attr_DA_AB_Vref_bypass.dev_attr.attr, + &iio_dev_attr_DA_CD_Vref_bypass.dev_attr.attr, + &iio_dev_attr_DAC_internal_Vref.dev_attr.attr, + &iio_dev_attr_VDD.dev_attr.attr, + &iio_dev_attr_in_temp.dev_attr.attr, + &iio_dev_attr_ex_temp_AIN1.dev_attr.attr, + &iio_dev_attr_AIN2.dev_attr.attr, + &iio_dev_attr_AIN3.dev_attr.attr, + &iio_dev_attr_AIN4.dev_attr.attr, + &iio_dev_attr_in_temp_offset.dev_attr.attr, + &iio_dev_attr_ex_temp_offset.dev_attr.attr, + &iio_dev_attr_in_analog_temp_offset.dev_attr.attr, + &iio_dev_attr_ex_analog_temp_offset.dev_attr.attr, + &iio_dev_attr_DAC_A.dev_attr.attr, + &iio_dev_attr_DAC_B.dev_attr.attr, + &iio_dev_attr_DAC_C.dev_attr.attr, + &iio_dev_attr_DAC_D.dev_attr.attr, + &iio_dev_attr_device_id.dev_attr.attr, + &iio_dev_attr_manufactorer_id.dev_attr.attr, + &iio_dev_attr_device_rev.dev_attr.attr, + &iio_dev_attr_bus_type.dev_attr.attr, + &iio_dev_attr_name.dev_attr.attr, + NULL, +}; + +static const struct attribute_group adt7516_attribute_group = { + .attrs = adt7516_attributes, +}; + + +/* + * temperature bound events + */ + +#define IIO_EVENT_CODE_ADT7316_IN_TEMP_HIGH IIO_BUFFER_EVENT_CODE(0) +#define IIO_EVENT_CODE_ADT7316_IN_TEMP_LOW IIO_BUFFER_EVENT_CODE(1) +#define IIO_EVENT_CODE_ADT7316_EX_TEMP_HIGH IIO_BUFFER_EVENT_CODE(2) +#define IIO_EVENT_CODE_ADT7316_EX_TEMP_LOW IIO_BUFFER_EVENT_CODE(3) +#define IIO_EVENT_CODE_ADT7316_EX_TEMP_FAULT IIO_BUFFER_EVENT_CODE(4) +#define IIO_EVENT_CODE_ADT7516_AIN1 IIO_BUFFER_EVENT_CODE(5) +#define IIO_EVENT_CODE_ADT7516_AIN2 IIO_BUFFER_EVENT_CODE(6) +#define IIO_EVENT_CODE_ADT7516_AIN3 IIO_BUFFER_EVENT_CODE(7) +#define IIO_EVENT_CODE_ADT7516_AIN4 IIO_BUFFER_EVENT_CODE(8) +#define IIO_EVENT_CODE_ADT7316_VDD IIO_BUFFER_EVENT_CODE(9) + +static void adt7316_interrupt_bh(struct work_struct *work_s) +{ + struct adt7316_chip_info *chip = + container_of(work_s, struct adt7316_chip_info, thresh_work); + u8 stat1, stat2; + int i, ret, count; + + ret = chip->bus.read(chip->bus.client, ADT7316_INT_STAT1, &stat1); + if (!ret) { + if ((chip->id & ID_FAMILY_MASK) == ID_ADT75XX) + count = 8; + else + count = 5; + + for (i = 0; i < count; i++) { + if (stat1 & (1 << i)) + iio_push_event(chip->indio_dev, 0, + IIO_EVENT_CODE_ADT7316_IN_TEMP_HIGH + i, + chip->last_timestamp); + } + } + + ret = chip->bus.read(chip->bus.client, ADT7316_INT_STAT2, &stat2); + if (!ret) { + if (stat2 & ADT7316_INT_MASK2_VDD) + iio_push_event(chip->indio_dev, 0, + IIO_EVENT_CODE_ADT7316_VDD, + chip->last_timestamp); + } + + enable_irq(chip->bus.irq); +} + +static int adt7316_interrupt(struct iio_dev *dev_info, + int index, + s64 timestamp, + int no_test) +{ + struct adt7316_chip_info *chip = dev_info->dev_data; + + chip->last_timestamp = timestamp; + schedule_work(&chip->thresh_work); + + return 0; +} + +IIO_EVENT_SH(adt7316, &adt7316_interrupt); + +/* + * Show mask of enabled interrupts in Hex. + */ +static ssize_t adt7316_show_int_mask(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct adt7316_chip_info *chip = dev_info->dev_data; + + return sprintf(buf, "0x%x\n", chip->int_mask); +} + +/* + * Set 1 to the mask in Hex to enabled interrupts. + */ +static ssize_t adt7316_set_int_mask(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct adt7316_chip_info *chip = dev_info->dev_data; + unsigned long data; + int ret; + u8 mask; + + ret = strict_strtoul(buf, 16, &data); + if (ret || data >= ADT7316_VDD_INT_MASK + 1) + return -EINVAL; + + if (data & ADT7316_VDD_INT_MASK) + mask = 0; /* enable vdd int */ + else + mask = ADT7316_INT_MASK2_VDD; /* disable vdd int */ + + ret = chip->bus.write(chip->bus.client, ADT7316_INT_MASK2, mask); + if (!ret) { + chip->int_mask &= ~ADT7316_VDD_INT_MASK; + chip->int_mask |= data & ADT7316_VDD_INT_MASK; + } + + if (data & ADT7316_TEMP_AIN_INT_MASK) { + if ((chip->id & ID_FAMILY_MASK) == ID_ADT73XX) + /* mask in reg is opposite, set 1 to disable */ + mask = (~data) & ADT7316_TEMP_INT_MASK; + else + /* mask in reg is opposite, set 1 to disable */ + mask = (~data) & ADT7316_TEMP_AIN_INT_MASK; + } + ret = chip->bus.write(chip->bus.client, ADT7316_INT_MASK1, mask); + + chip->int_mask = mask; + + return len; +} +static inline ssize_t adt7316_show_ad_bound(struct device *dev, + struct device_attribute *attr, + u8 bound_reg, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct adt7316_chip_info *chip = dev_info->dev_data; + u8 val; + int data; + int ret; + + if ((chip->id & ID_FAMILY_MASK) == ID_ADT73XX && + bound_reg > ADT7316_EX_TEMP_LOW) + return -EPERM; + + ret = chip->bus.read(chip->bus.client, bound_reg, &val); + if (ret) + return -EIO; + + data = (int)val; + + if (!((chip->id & ID_FAMILY_MASK) == ID_ADT75XX && + (chip->config1 & ADT7516_SEL_AIN1_2_EX_TEMP_MASK) == 0)) { + if (data & 0x80) + data -= 256; + } + + return sprintf(buf, "%d\n", data); +} + +static inline ssize_t adt7316_set_ad_bound(struct device *dev, + struct device_attribute *attr, + u8 bound_reg, + const char *buf, + size_t len) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct adt7316_chip_info *chip = dev_info->dev_data; + long data; + u8 val; + int ret; + + if ((chip->id & ID_FAMILY_MASK) == ID_ADT73XX && + bound_reg > ADT7316_EX_TEMP_LOW) + return -EPERM; + + ret = strict_strtol(buf, 10, &data); + if (ret) + return -EINVAL; + + if ((chip->id & ID_FAMILY_MASK) == ID_ADT75XX && + (chip->config1 & ADT7516_SEL_AIN1_2_EX_TEMP_MASK) == 0) { + if (data > 255 || data < 0) + return -EINVAL; + } else { + if (data > 127 || data < -128) + return -EINVAL; + + if (data < 0) + data += 256; + } + + val = (u8)data; + + ret = chip->bus.write(chip->bus.client, bound_reg, val); + if (ret) + return -EIO; + + return len; +} + +static ssize_t adt7316_show_in_temp_high(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + return adt7316_show_ad_bound(dev, attr, + ADT7316_IN_TEMP_HIGH, buf); +} + +static inline ssize_t adt7316_set_in_temp_high(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + return adt7316_set_ad_bound(dev, attr, + ADT7316_IN_TEMP_HIGH, buf, len); +} + +static ssize_t adt7316_show_in_temp_low(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + return adt7316_show_ad_bound(dev, attr, + ADT7316_IN_TEMP_LOW, buf); +} + +static inline ssize_t adt7316_set_in_temp_low(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + return adt7316_set_ad_bound(dev, attr, + ADT7316_IN_TEMP_LOW, buf, len); +} + +static ssize_t adt7316_show_ex_temp_ain1_high(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + return adt7316_show_ad_bound(dev, attr, + ADT7316_EX_TEMP_HIGH, buf); +} + +static inline ssize_t adt7316_set_ex_temp_ain1_high(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + return adt7316_set_ad_bound(dev, attr, + ADT7316_EX_TEMP_HIGH, buf, len); +} + +static ssize_t adt7316_show_ex_temp_ain1_low(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + return adt7316_show_ad_bound(dev, attr, + ADT7316_EX_TEMP_LOW, buf); +} + +static inline ssize_t adt7316_set_ex_temp_ain1_low(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + return adt7316_set_ad_bound(dev, attr, + ADT7316_EX_TEMP_LOW, buf, len); +} + +static ssize_t adt7316_show_ain2_high(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + return adt7316_show_ad_bound(dev, attr, + ADT7516_AIN2_HIGH, buf); +} + +static inline ssize_t adt7316_set_ain2_high(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + return adt7316_set_ad_bound(dev, attr, + ADT7516_AIN2_HIGH, buf, len); +} + +static ssize_t adt7316_show_ain2_low(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + return adt7316_show_ad_bound(dev, attr, + ADT7516_AIN2_LOW, buf); +} + +static inline ssize_t adt7316_set_ain2_low(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + return adt7316_set_ad_bound(dev, attr, + ADT7516_AIN2_LOW, buf, len); +} + +static ssize_t adt7316_show_ain3_high(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + return adt7316_show_ad_bound(dev, attr, + ADT7516_AIN3_HIGH, buf); +} + +static inline ssize_t adt7316_set_ain3_high(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + return adt7316_set_ad_bound(dev, attr, + ADT7516_AIN3_HIGH, buf, len); +} + +static ssize_t adt7316_show_ain3_low(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + return adt7316_show_ad_bound(dev, attr, + ADT7516_AIN3_LOW, buf); +} + +static inline ssize_t adt7316_set_ain3_low(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + return adt7316_set_ad_bound(dev, attr, + ADT7516_AIN3_LOW, buf, len); +} + +static ssize_t adt7316_show_ain4_high(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + return adt7316_show_ad_bound(dev, attr, + ADT7516_AIN4_HIGH, buf); +} + +static inline ssize_t adt7316_set_ain4_high(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + return adt7316_set_ad_bound(dev, attr, + ADT7516_AIN4_HIGH, buf, len); +} + +static ssize_t adt7316_show_ain4_low(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + return adt7316_show_ad_bound(dev, attr, + ADT7516_AIN4_LOW, buf); +} + +static inline ssize_t adt7316_set_ain4_low(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + return adt7316_set_ad_bound(dev, attr, + ADT7516_AIN4_LOW, buf, len); +} + +static ssize_t adt7316_show_int_enabled(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct adt7316_chip_info *chip = dev_info->dev_data; + + return sprintf(buf, "%d\n", !!(chip->config1 & ADT7316_INT_EN)); +} + +static ssize_t adt7316_set_int_enabled(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct adt7316_chip_info *chip = dev_info->dev_data; + u8 config1; + int ret; + + config1 = chip->config1 & (~ADT7316_INT_EN); + if (!memcmp(buf, "1", 1)) + config1 |= ADT7316_INT_EN; + + ret = chip->bus.write(chip->bus.client, ADT7316_CONFIG1, config1); + if (ret) + return -EIO; + + chip->config1 = config1; + + return len; +} + + +IIO_EVENT_ATTR_SH(int_mask, iio_event_adt7316, + adt7316_show_int_mask, adt7316_set_int_mask, 0); +IIO_EVENT_ATTR_SH(in_temp_high, iio_event_adt7316, + adt7316_show_in_temp_high, adt7316_set_in_temp_high, 0); +IIO_EVENT_ATTR_SH(in_temp_low, iio_event_adt7316, + adt7316_show_in_temp_low, adt7316_set_in_temp_low, 0); +IIO_EVENT_ATTR_SH(ex_temp_high, iio_event_adt7316, + adt7316_show_ex_temp_ain1_high, + adt7316_set_ex_temp_ain1_high, 0); +IIO_EVENT_ATTR_SH(ex_temp_low, iio_event_adt7316, + adt7316_show_ex_temp_ain1_low, + adt7316_set_ex_temp_ain1_low, 0); +IIO_EVENT_ATTR_SH(ex_temp_ain1_high, iio_event_adt7316, + adt7316_show_ex_temp_ain1_high, + adt7316_set_ex_temp_ain1_high, 0); +IIO_EVENT_ATTR_SH(ex_temp_ain1_low, iio_event_adt7316, + adt7316_show_ex_temp_ain1_low, + adt7316_set_ex_temp_ain1_low, 0); +IIO_EVENT_ATTR_SH(ain2_high, iio_event_adt7316, + adt7316_show_ain2_high, adt7316_set_ain2_high, 0); +IIO_EVENT_ATTR_SH(ain2_low, iio_event_adt7316, + adt7316_show_ain2_low, adt7316_set_ain2_low, 0); +IIO_EVENT_ATTR_SH(ain3_high, iio_event_adt7316, + adt7316_show_ain3_high, adt7316_set_ain3_high, 0); +IIO_EVENT_ATTR_SH(ain3_low, iio_event_adt7316, + adt7316_show_ain3_low, adt7316_set_ain3_low, 0); +IIO_EVENT_ATTR_SH(ain4_high, iio_event_adt7316, + adt7316_show_ain4_high, adt7316_set_ain4_high, 0); +IIO_EVENT_ATTR_SH(ain4_low, iio_event_adt7316, + adt7316_show_ain4_low, adt7316_set_ain4_low, 0); +IIO_EVENT_ATTR_SH(int_enabled, iio_event_adt7316, + adt7316_show_int_enabled, adt7316_set_int_enabled, 0); + +static struct attribute *adt7316_event_attributes[] = { + &iio_event_attr_int_mask.dev_attr.attr, + &iio_event_attr_in_temp_high.dev_attr.attr, + &iio_event_attr_in_temp_low.dev_attr.attr, + &iio_event_attr_ex_temp_high.dev_attr.attr, + &iio_event_attr_ex_temp_low.dev_attr.attr, + &iio_event_attr_int_enabled.dev_attr.attr, + NULL, +}; + +static struct attribute_group adt7316_event_attribute_group = { + .attrs = adt7316_event_attributes, +}; + +static struct attribute *adt7516_event_attributes[] = { + &iio_event_attr_int_mask.dev_attr.attr, + &iio_event_attr_in_temp_high.dev_attr.attr, + &iio_event_attr_in_temp_low.dev_attr.attr, + &iio_event_attr_ex_temp_ain1_high.dev_attr.attr, + &iio_event_attr_ex_temp_ain1_low.dev_attr.attr, + &iio_event_attr_ain2_high.dev_attr.attr, + &iio_event_attr_ain2_low.dev_attr.attr, + &iio_event_attr_ain3_high.dev_attr.attr, + &iio_event_attr_ain3_low.dev_attr.attr, + &iio_event_attr_ain4_high.dev_attr.attr, + &iio_event_attr_ain4_low.dev_attr.attr, + &iio_event_attr_int_enabled.dev_attr.attr, + NULL, +}; + +static struct attribute_group adt7516_event_attribute_group = { + .attrs = adt7516_event_attributes, +}; + +#ifdef CONFIG_PM +int adt7316_disable(struct device *dev) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct adt7316_chip_info *chip = dev_info->dev_data; + + return _adt7316_store_enabled(chip, 0); +} +EXPORT_SYMBOL(adt7316_disable); + +int adt7316_enable(struct device *dev) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct adt7316_chip_info *chip = dev_info->dev_data; + + return _adt7316_store_enabled(chip, 1); +} +EXPORT_SYMBOL(adt7316_enable); +#endif + +/* + * device probe and remove + */ +int __devinit adt7316_probe(struct device *dev, struct adt7316_bus *bus, + const char *name) +{ + struct adt7316_chip_info *chip; + unsigned short *adt7316_platform_data = dev->platform_data; + int ret = 0; + + chip = kzalloc(sizeof(struct adt7316_chip_info), GFP_KERNEL); + + if (chip == NULL) + return -ENOMEM; + + /* this is only used for device removal purposes */ + dev_set_drvdata(dev, chip); + + chip->bus = *bus; + chip->name = name; + + if (name[4] == '3') + chip->id = ID_ADT7316 + (name[6] - '6'); + else if (name[4] == '5') + chip->id = ID_ADT7516 + (name[6] - '6'); + else + return -ENODEV; + + chip->ldac_pin = adt7316_platform_data[1]; + if (chip->ldac_pin) { + chip->config3 |= ADT7316_DA_EN_VIA_DAC_LDCA; + if ((chip->id & ID_FAMILY_MASK) == ID_ADT75XX) + chip->config1 |= ADT7516_SEL_AIN3; + } + chip->int_mask = ADT7316_TEMP_INT_MASK | ADT7316_VDD_INT_MASK; + if ((chip->id & ID_FAMILY_MASK) == ID_ADT75XX) + chip->int_mask |= ADT7516_AIN_INT_MASK; + + chip->indio_dev = iio_allocate_device(); + if (chip->indio_dev == NULL) { + ret = -ENOMEM; + goto error_free_chip; + } + + chip->indio_dev->dev.parent = dev; + if ((chip->id & ID_FAMILY_MASK) == ID_ADT75XX) { + chip->indio_dev->attrs = &adt7516_attribute_group; + chip->indio_dev->event_attrs = &adt7516_event_attribute_group; + } else { + chip->indio_dev->attrs = &adt7316_attribute_group; + chip->indio_dev->event_attrs = &adt7316_event_attribute_group; + } + chip->indio_dev->dev_data = (void *)chip; + chip->indio_dev->driver_module = THIS_MODULE; + chip->indio_dev->num_interrupt_lines = 1; + chip->indio_dev->modes = INDIO_DIRECT_MODE; + + ret = iio_device_register(chip->indio_dev); + if (ret) + goto error_free_dev; + + if (chip->bus.irq > 0) { + if (adt7316_platform_data[0]) + chip->bus.irq_flags = adt7316_platform_data[0]; + + ret = iio_register_interrupt_line(chip->bus.irq, + chip->indio_dev, + 0, + chip->bus.irq_flags, + chip->name); + if (ret) + goto error_unreg_dev; + + /* + * The event handler list element refer to iio_event_adt7316. + * All event attributes bind to the same event handler. + * So, only register event handler once. + */ + iio_add_event_to_list(&iio_event_adt7316, + &chip->indio_dev->interrupts[0]->ev_list); + + INIT_WORK(&chip->thresh_work, adt7316_interrupt_bh); + + if (chip->bus.irq_flags & IRQF_TRIGGER_HIGH) + chip->config1 |= ADT7316_INT_POLARITY; + } + + ret = chip->bus.write(chip->bus.client, ADT7316_CONFIG1, chip->config1); + if (ret) { + ret = -EIO; + goto error_unreg_irq; + } + + ret = chip->bus.write(chip->bus.client, ADT7316_CONFIG3, chip->config3); + if (ret) { + ret = -EIO; + goto error_unreg_irq; + } + + dev_info(dev, "%s temperature sensor, ADC and DAC registered.\n", + chip->name); + + return 0; + +error_unreg_irq: + iio_unregister_interrupt_line(chip->indio_dev, 0); +error_unreg_dev: + iio_device_unregister(chip->indio_dev); +error_free_dev: + iio_free_device(chip->indio_dev); +error_free_chip: + kfree(chip); + + return ret; +} +EXPORT_SYMBOL(adt7316_probe); + +int __devexit adt7316_remove(struct device *dev) +{ + + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct adt7316_chip_info *chip = dev_info->dev_data; + struct iio_dev *indio_dev = chip->indio_dev; + + dev_set_drvdata(dev, NULL); + if (chip->bus.irq) + iio_unregister_interrupt_line(indio_dev, 0); + iio_device_unregister(indio_dev); + iio_free_device(chip->indio_dev); + kfree(chip); + + return 0; +} +EXPORT_SYMBOL(adt7316_remove); + +MODULE_AUTHOR("Sonic Zhang "); +MODULE_DESCRIPTION("Analog Devices ADT7316/7/8 and ADT7516/7/9 digital" + " temperature sensor, ADC and DAC driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/staging/iio/addac/adt7316.h b/drivers/staging/iio/addac/adt7316.h new file mode 100644 index 000000000000..d34bd679bb4e --- /dev/null +++ b/drivers/staging/iio/addac/adt7316.h @@ -0,0 +1,33 @@ +/* + * ADT7316 digital temperature sensor driver supporting ADT7316/7/8 ADT7516/7/9 + * + * Copyright 2010 Analog Devices Inc. + * + * Licensed under the GPL-2 or later. + */ + +#ifndef _ADT7316_H_ +#define _ADT7316_H_ + +#include + +#define ADT7316_REG_MAX_ADDR 0x3F + +struct adt7316_bus { + void *client; + int irq; + int irq_flags; + int (*read) (void *client, u8 reg, u8 *data); + int (*write) (void *client, u8 reg, u8 val); + int (*multi_read) (void *client, u8 first_reg, u8 count, u8 *data); + int (*multi_write) (void *client, u8 first_reg, u8 count, u8 *data); +}; + +#ifdef CONFIG_PM +int adt7316_disable(struct device *dev); +int adt7316_enable(struct device *dev); +#endif +int adt7316_probe(struct device *dev, struct adt7316_bus *bus, const char *name); +int adt7316_remove(struct device *dev); + +#endif -- cgit v1.2.3 From 54c5be349bf66ed0c50c2e293803057d148a4c95 Mon Sep 17 00:00:00 2001 From: Barry Song Date: Wed, 27 Oct 2010 21:43:53 -0400 Subject: staging: iio: adc: new driver for AD7150/1/6 devices Signed-off-by: Barry Song Signed-off-by: Michael Hennerich Acked-by: Jonathan Cameron Signed-off-by: Mike Frysinger Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/adc/Kconfig | 7 + drivers/staging/iio/adc/Makefile | 2 + drivers/staging/iio/adc/ad7150.c | 877 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 886 insertions(+) create mode 100644 drivers/staging/iio/adc/ad7150.c diff --git a/drivers/staging/iio/adc/Kconfig b/drivers/staging/iio/adc/Kconfig index acb67677e563..51b9cc654c86 100644 --- a/drivers/staging/iio/adc/Kconfig +++ b/drivers/staging/iio/adc/Kconfig @@ -27,6 +27,13 @@ config MAX1363_RING_BUFFER Say yes here to include ring buffer support in the MAX1363 ADC driver. +config AD7150 + tristate "Analog Devices ad7150/1/6 capacitive sensor driver" + depends on I2C + help + Say yes here to build support for Analog Devices capacitive sensors. + (ad7150, ad7151, ad7156) Provides direct access via sysfs. + config AD799X tristate "Analog Devices AD799x ADC driver" depends on I2C diff --git a/drivers/staging/iio/adc/Makefile b/drivers/staging/iio/adc/Makefile index b62c319bcedd..51b39aab061a 100644 --- a/drivers/staging/iio/adc/Makefile +++ b/drivers/staging/iio/adc/Makefile @@ -14,3 +14,5 @@ obj-$(CONFIG_AD799X) += ad799x.o ad7476-y := ad7476_core.o ad7476-$(CONFIG_IIO_RING_BUFFER) += ad7476_ring.o obj-$(CONFIG_AD7476) += ad7476.o + +obj-$(CONFIG_AD7150) += ad7150.o diff --git a/drivers/staging/iio/adc/ad7150.c b/drivers/staging/iio/adc/ad7150.c new file mode 100644 index 000000000000..8555766109d8 --- /dev/null +++ b/drivers/staging/iio/adc/ad7150.c @@ -0,0 +1,877 @@ +/* + * AD7150 capacitive sensor driver supporting AD7150/1/6 + * + * Copyright 2010 Analog Devices Inc. + * + * Licensed under the GPL-2 or later. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../iio.h" +#include "../sysfs.h" + +/* + * AD7150 registers definition + */ + +#define AD7150_STATUS 0 +#define AD7150_STATUS_OUT1 (1 << 3) +#define AD7150_STATUS_OUT2 (1 << 5) +#define AD7150_CH1_DATA_HIGH 1 +#define AD7150_CH1_DATA_LOW 2 +#define AD7150_CH2_DATA_HIGH 3 +#define AD7150_CH2_DATA_LOW 4 +#define AD7150_CH1_AVG_HIGH 5 +#define AD7150_CH1_AVG_LOW 6 +#define AD7150_CH2_AVG_HIGH 7 +#define AD7150_CH2_AVG_LOW 8 +#define AD7150_CH1_SENSITIVITY 9 +#define AD7150_CH1_THR_HOLD_H 9 +#define AD7150_CH1_TIMEOUT 10 +#define AD7150_CH1_THR_HOLD_L 10 +#define AD7150_CH1_SETUP 11 +#define AD7150_CH2_SENSITIVITY 12 +#define AD7150_CH2_THR_HOLD_H 12 +#define AD7150_CH2_TIMEOUT 13 +#define AD7150_CH2_THR_HOLD_L 13 +#define AD7150_CH2_SETUP 14 +#define AD7150_CFG 15 +#define AD7150_CFG_FIX (1 << 7) +#define AD7150_PD_TIMER 16 +#define AD7150_CH1_CAPDAC 17 +#define AD7150_CH2_CAPDAC 18 +#define AD7150_SN3 19 +#define AD7150_SN2 20 +#define AD7150_SN1 21 +#define AD7150_SN0 22 +#define AD7150_ID 23 + +#define AD7150_MAX_CONV_MODE 4 + +/* + * struct ad7150_chip_info - chip specifc information + */ + +struct ad7150_chip_info { + const char *name; + struct i2c_client *client; + struct iio_dev *indio_dev; + struct work_struct thresh_work; + bool inter; + s64 last_timestamp; + u16 ch1_threshold; /* Ch1 Threshold (in fixed threshold mode) */ + u8 ch1_sensitivity; /* Ch1 Sensitivity (in adaptive threshold mode) */ + u8 ch1_timeout; /* Ch1 Timeout (in adaptive threshold mode) */ + u8 ch1_setup; + u16 ch2_threshold; /* Ch2 Threshold (in fixed threshold mode) */ + u8 ch2_sensitivity; /* Ch1 Sensitivity (in adaptive threshold mode) */ + u8 ch2_timeout; /* Ch1 Timeout (in adaptive threshold mode) */ + u8 ch2_setup; + u8 powerdown_timer; + char threshold_mode[10]; /* adaptive/fixed threshold mode */ + int old_state; + char *conversion_mode; +}; + +struct ad7150_conversion_mode { + char *name; + u8 reg_cfg; +}; + +struct ad7150_conversion_mode ad7150_conv_mode_table[AD7150_MAX_CONV_MODE] = { + { "idle", 0 }, + { "continuous-conversion", 1 }, + { "single-conversion", 2 }, + { "power-down", 3 }, +}; + +/* + * ad7150 register access by I2C + */ + +static int ad7150_i2c_read(struct ad7150_chip_info *chip, u8 reg, u8 *data, int len) +{ + struct i2c_client *client = chip->client; + int ret = 0; + + ret = i2c_master_send(client, ®, 1); + if (ret < 0) { + dev_err(&client->dev, "I2C write error\n"); + return ret; + } + + ret = i2c_master_recv(client, data, len); + if (ret < 0) { + dev_err(&client->dev, "I2C read error\n"); + return ret; + } + + return ret; +} + +static int ad7150_i2c_write(struct ad7150_chip_info *chip, u8 reg, u8 data) +{ + struct i2c_client *client = chip->client; + int ret = 0; + + u8 tx[2] = { + reg, + data, + }; + + ret = i2c_master_send(client, tx, 2); + if (ret < 0) + dev_err(&client->dev, "I2C write error\n"); + + return ret; +} + +/* + * sysfs nodes + */ + +#define IIO_DEV_ATTR_AVAIL_CONVERSION_MODES(_show) \ + IIO_DEVICE_ATTR(available_conversion_modes, S_IRUGO, _show, NULL, 0) +#define IIO_DEV_ATTR_CONVERSION_MODE(_mode, _show, _store) \ + IIO_DEVICE_ATTR(conversion_mode, _mode, _show, _store, 0) +#define IIO_DEV_ATTR_AVAIL_THRESHOLD_MODES(_show) \ + IIO_DEVICE_ATTR(available_threshold_modes, S_IRUGO, _show, NULL, 0) +#define IIO_DEV_ATTR_THRESHOLD_MODE(_mode, _show, _store) \ + IIO_DEVICE_ATTR(threshold_mode, _mode, _show, _store, 0) +#define IIO_DEV_ATTR_CH1_THRESHOLD(_mode, _show, _store) \ + IIO_DEVICE_ATTR(ch1_threshold, _mode, _show, _store, 0) +#define IIO_DEV_ATTR_CH2_THRESHOLD(_mode, _show, _store) \ + IIO_DEVICE_ATTR(ch2_threshold, _mode, _show, _store, 0) +#define IIO_DEV_ATTR_CH1_SENSITIVITY(_mode, _show, _store) \ + IIO_DEVICE_ATTR(ch1_sensitivity, _mode, _show, _store, 0) +#define IIO_DEV_ATTR_CH2_SENSITIVITY(_mode, _show, _store) \ + IIO_DEVICE_ATTR(ch2_sensitivity, _mode, _show, _store, 0) +#define IIO_DEV_ATTR_CH1_TIMEOUT(_mode, _show, _store) \ + IIO_DEVICE_ATTR(ch1_timeout, _mode, _show, _store, 0) +#define IIO_DEV_ATTR_CH2_TIMEOUT(_mode, _show, _store) \ + IIO_DEVICE_ATTR(ch2_timeout, _mode, _show, _store, 0) +#define IIO_DEV_ATTR_CH1_VALUE(_show) \ + IIO_DEVICE_ATTR(ch1_value, S_IRUGO, _show, NULL, 0) +#define IIO_DEV_ATTR_CH2_VALUE(_show) \ + IIO_DEVICE_ATTR(ch2_value, S_IRUGO, _show, NULL, 0) +#define IIO_DEV_ATTR_CH1_SETUP(_mode, _show, _store) \ + IIO_DEVICE_ATTR(ch1_setup, _mode, _show, _store, 0) +#define IIO_DEV_ATTR_CH2_SETUP(_mode, _show, _store) \ + IIO_DEVICE_ATTR(ch2_setup, _mode, _show, _store, 0) +#define IIO_DEV_ATTR_POWERDOWN_TIMER(_mode, _show, _store) \ + IIO_DEVICE_ATTR(powerdown_timer, _mode, _show, _store, 0) + +static ssize_t ad7150_show_conversion_modes(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + int i; + int len = 0; + + for (i = 0; i < AD7150_MAX_CONV_MODE; i++) + len += sprintf(buf + len, "%s\n", ad7150_conv_mode_table[i].name); + + return len; +} + +static IIO_DEV_ATTR_AVAIL_CONVERSION_MODES(ad7150_show_conversion_modes); + +static ssize_t ad7150_show_conversion_mode(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad7150_chip_info *chip = dev_info->dev_data; + + return sprintf(buf, "%s\n", chip->conversion_mode); +} + +static ssize_t ad7150_store_conversion_mode(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad7150_chip_info *chip = dev_info->dev_data; + u8 cfg; + int i; + + ad7150_i2c_read(chip, AD7150_CFG, &cfg, 1); + + for (i = 0; i < AD7150_MAX_CONV_MODE; i++) { + if (strncmp(buf, ad7150_conv_mode_table[i].name, + strlen(ad7150_conv_mode_table[i].name) - 1) == 0) { + chip->conversion_mode = ad7150_conv_mode_table[i].name; + cfg |= 0x18 | ad7150_conv_mode_table[i].reg_cfg; + ad7150_i2c_write(chip, AD7150_CFG, cfg); + return len; + } + } + + dev_err(dev, "not supported conversion mode\n"); + + return -EINVAL; +} + +static IIO_DEV_ATTR_CONVERSION_MODE(S_IRUGO | S_IWUSR, + ad7150_show_conversion_mode, + ad7150_store_conversion_mode); + +static ssize_t ad7150_show_threshold_modes(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + return sprintf(buf, "adaptive\nfixed\n"); +} + +static IIO_DEV_ATTR_AVAIL_THRESHOLD_MODES(ad7150_show_threshold_modes); + +static ssize_t ad7150_show_ch1_value(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad7150_chip_info *chip = dev_info->dev_data; + u8 data[2]; + + ad7150_i2c_read(chip, AD7150_CH1_DATA_HIGH, data, 2); + return sprintf(buf, "%d\n", ((int) data[0] << 8) | data[1]); +} + +static IIO_DEV_ATTR_CH1_VALUE(ad7150_show_ch1_value); + +static ssize_t ad7150_show_ch2_value(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad7150_chip_info *chip = dev_info->dev_data; + u8 data[2]; + + ad7150_i2c_read(chip, AD7150_CH2_DATA_HIGH, data, 2); + return sprintf(buf, "%d\n", ((int) data[0] << 8) | data[1]); +} + +static IIO_DEV_ATTR_CH2_VALUE(ad7150_show_ch2_value); + +static ssize_t ad7150_show_threshold_mode(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad7150_chip_info *chip = dev_info->dev_data; + + return sprintf(buf, "%s\n", chip->threshold_mode); +} + +static ssize_t ad7150_store_threshold_mode(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad7150_chip_info *chip = dev_info->dev_data; + u8 cfg; + + ad7150_i2c_read(chip, AD7150_CFG, &cfg, 1); + + if (strncmp(buf, "fixed", 5) == 0) { + strcpy(chip->threshold_mode, "fixed"); + cfg |= AD7150_CFG_FIX; + ad7150_i2c_write(chip, AD7150_CFG, cfg); + + return len; + } else if (strncmp(buf, "adaptive", 8) == 0) { + strcpy(chip->threshold_mode, "adaptive"); + cfg &= ~AD7150_CFG_FIX; + ad7150_i2c_write(chip, AD7150_CFG, cfg); + + return len; + } + + dev_err(dev, "not supported threshold mode\n"); + return -EINVAL; +} + +static IIO_DEV_ATTR_THRESHOLD_MODE(S_IRUGO | S_IWUSR, + ad7150_show_threshold_mode, + ad7150_store_threshold_mode); + +static ssize_t ad7150_show_ch1_threshold(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad7150_chip_info *chip = dev_info->dev_data; + + return sprintf(buf, "%d\n", chip->ch1_threshold); +} + +static ssize_t ad7150_store_ch1_threshold(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad7150_chip_info *chip = dev_info->dev_data; + unsigned long data; + int ret; + + ret = strict_strtoul(buf, 10, &data); + + if ((!ret) && (data < 0x10000)) { + ad7150_i2c_write(chip, AD7150_CH1_THR_HOLD_H, data >> 8); + ad7150_i2c_write(chip, AD7150_CH1_THR_HOLD_L, data); + chip->ch1_threshold = data; + return len; + } + + return -EINVAL; +} + +static IIO_DEV_ATTR_CH1_THRESHOLD(S_IRUGO | S_IWUSR, + ad7150_show_ch1_threshold, + ad7150_store_ch1_threshold); + +static ssize_t ad7150_show_ch2_threshold(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad7150_chip_info *chip = dev_info->dev_data; + + return sprintf(buf, "%d\n", chip->ch2_threshold); +} + +static ssize_t ad7150_store_ch2_threshold(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad7150_chip_info *chip = dev_info->dev_data; + unsigned long data; + int ret; + + ret = strict_strtoul(buf, 10, &data); + + if ((!ret) && (data < 0x10000)) { + ad7150_i2c_write(chip, AD7150_CH2_THR_HOLD_H, data >> 8); + ad7150_i2c_write(chip, AD7150_CH2_THR_HOLD_L, data); + chip->ch2_threshold = data; + return len; + } + + return -EINVAL; +} + +static IIO_DEV_ATTR_CH2_THRESHOLD(S_IRUGO | S_IWUSR, + ad7150_show_ch2_threshold, + ad7150_store_ch2_threshold); + +static ssize_t ad7150_show_ch1_sensitivity(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad7150_chip_info *chip = dev_info->dev_data; + + return sprintf(buf, "%d\n", chip->ch1_sensitivity); +} + +static ssize_t ad7150_store_ch1_sensitivity(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad7150_chip_info *chip = dev_info->dev_data; + unsigned long data; + int ret; + + ret = strict_strtoul(buf, 10, &data); + + if ((!ret) && (data < 0x100)) { + ad7150_i2c_write(chip, AD7150_CH1_SENSITIVITY, data); + chip->ch1_sensitivity = data; + return len; + } + + return -EINVAL; +} + +static IIO_DEV_ATTR_CH1_SENSITIVITY(S_IRUGO | S_IWUSR, + ad7150_show_ch1_sensitivity, + ad7150_store_ch1_sensitivity); + +static ssize_t ad7150_show_ch2_sensitivity(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad7150_chip_info *chip = dev_info->dev_data; + + return sprintf(buf, "%d\n", chip->ch2_sensitivity); +} + +static ssize_t ad7150_store_ch2_sensitivity(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad7150_chip_info *chip = dev_info->dev_data; + unsigned long data; + int ret; + + ret = strict_strtoul(buf, 10, &data); + + if ((!ret) && (data < 0x100)) { + ad7150_i2c_write(chip, AD7150_CH2_SENSITIVITY, data); + chip->ch2_sensitivity = data; + return len; + } + + return -EINVAL; +} + +static IIO_DEV_ATTR_CH2_SENSITIVITY(S_IRUGO | S_IWUSR, + ad7150_show_ch2_sensitivity, + ad7150_store_ch2_sensitivity); + +static ssize_t ad7150_show_ch1_timeout(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad7150_chip_info *chip = dev_info->dev_data; + + return sprintf(buf, "%d\n", chip->ch1_timeout); +} + +static ssize_t ad7150_store_ch1_timeout(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad7150_chip_info *chip = dev_info->dev_data; + unsigned long data; + int ret; + + ret = strict_strtoul(buf, 10, &data); + + if ((!ret) && (data < 0x100)) { + ad7150_i2c_write(chip, AD7150_CH1_TIMEOUT, data); + chip->ch1_timeout = data; + return len; + } + + return -EINVAL; +} + +static IIO_DEV_ATTR_CH1_TIMEOUT(S_IRUGO | S_IWUSR, + ad7150_show_ch1_timeout, + ad7150_store_ch1_timeout); + +static ssize_t ad7150_show_ch2_timeout(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad7150_chip_info *chip = dev_info->dev_data; + + return sprintf(buf, "%d\n", chip->ch2_timeout); +} + +static ssize_t ad7150_store_ch2_timeout(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad7150_chip_info *chip = dev_info->dev_data; + unsigned long data; + int ret; + + ret = strict_strtoul(buf, 10, &data); + + if ((!ret) && (data < 0x100)) { + ad7150_i2c_write(chip, AD7150_CH2_TIMEOUT, data); + chip->ch2_timeout = data; + return len; + } + + return -EINVAL; +} + +static IIO_DEV_ATTR_CH2_TIMEOUT(S_IRUGO | S_IWUSR, + ad7150_show_ch2_timeout, + ad7150_store_ch2_timeout); + +static ssize_t ad7150_show_ch1_setup(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad7150_chip_info *chip = dev_info->dev_data; + + return sprintf(buf, "0x%02x\n", chip->ch1_setup); +} + +static ssize_t ad7150_store_ch1_setup(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad7150_chip_info *chip = dev_info->dev_data; + unsigned long data; + int ret; + + ret = strict_strtoul(buf, 10, &data); + + if ((!ret) && (data < 0x100)) { + ad7150_i2c_write(chip, AD7150_CH1_SETUP, data); + chip->ch1_setup = data; + return len; + } + + + return -EINVAL; +} + +static IIO_DEV_ATTR_CH1_SETUP(S_IRUGO | S_IWUSR, + ad7150_show_ch1_setup, + ad7150_store_ch1_setup); + +static ssize_t ad7150_show_ch2_setup(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad7150_chip_info *chip = dev_info->dev_data; + + return sprintf(buf, "0x%02x\n", chip->ch2_setup); +} + +static ssize_t ad7150_store_ch2_setup(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad7150_chip_info *chip = dev_info->dev_data; + unsigned long data; + int ret; + + ret = strict_strtoul(buf, 10, &data); + + if ((!ret) && (data < 0x100)) { + ad7150_i2c_write(chip, AD7150_CH2_SETUP, data); + chip->ch2_setup = data; + return len; + } + + return -EINVAL; +} + +static IIO_DEV_ATTR_CH2_SETUP(S_IRUGO | S_IWUSR, + ad7150_show_ch2_setup, + ad7150_store_ch2_setup); + +static ssize_t ad7150_show_name(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad7150_chip_info *chip = dev_info->dev_data; + return sprintf(buf, "%s\n", chip->name); +} + +static IIO_DEVICE_ATTR(name, S_IRUGO, ad7150_show_name, NULL, 0); + +static ssize_t ad7150_show_powerdown_timer(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad7150_chip_info *chip = dev_info->dev_data; + + return sprintf(buf, "0x%02x\n", chip->powerdown_timer); +} + +static ssize_t ad7150_store_powerdown_timer(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad7150_chip_info *chip = dev_info->dev_data; + unsigned long data; + int ret; + + ret = strict_strtoul(buf, 10, &data); + + if ((!ret) && (data < 0x40)) { + chip->powerdown_timer = data; + return len; + } + + return -EINVAL; +} + +static IIO_DEV_ATTR_POWERDOWN_TIMER(S_IRUGO | S_IWUSR, + ad7150_show_powerdown_timer, + ad7150_store_powerdown_timer); + +static struct attribute *ad7150_attributes[] = { + &iio_dev_attr_available_threshold_modes.dev_attr.attr, + &iio_dev_attr_threshold_mode.dev_attr.attr, + &iio_dev_attr_ch1_threshold.dev_attr.attr, + &iio_dev_attr_ch2_threshold.dev_attr.attr, + &iio_dev_attr_ch1_timeout.dev_attr.attr, + &iio_dev_attr_ch2_timeout.dev_attr.attr, + &iio_dev_attr_ch1_setup.dev_attr.attr, + &iio_dev_attr_ch2_setup.dev_attr.attr, + &iio_dev_attr_ch1_sensitivity.dev_attr.attr, + &iio_dev_attr_ch2_sensitivity.dev_attr.attr, + &iio_dev_attr_powerdown_timer.dev_attr.attr, + &iio_dev_attr_ch1_value.dev_attr.attr, + &iio_dev_attr_ch2_value.dev_attr.attr, + &iio_dev_attr_name.dev_attr.attr, + NULL, +}; + +static const struct attribute_group ad7150_attribute_group = { + .attrs = ad7150_attributes, +}; + +/* + * threshold events + */ + +#define IIO_EVENT_CODE_CH1_HIGH IIO_BUFFER_EVENT_CODE(0) +#define IIO_EVENT_CODE_CH1_LOW IIO_BUFFER_EVENT_CODE(1) +#define IIO_EVENT_CODE_CH2_HIGH IIO_BUFFER_EVENT_CODE(2) +#define IIO_EVENT_CODE_CH2_LOW IIO_BUFFER_EVENT_CODE(3) + +#define IIO_EVENT_ATTR_CH1_HIGH_SH(_evlist, _show, _store, _mask) \ + IIO_EVENT_ATTR_SH(ch1_high, _evlist, _show, _store, _mask) + +#define IIO_EVENT_ATTR_CH2_HIGH_SH(_evlist, _show, _store, _mask) \ + IIO_EVENT_ATTR_SH(ch2_high, _evlist, _show, _store, _mask) + +#define IIO_EVENT_ATTR_CH1_LOW_SH(_evlist, _show, _store, _mask) \ + IIO_EVENT_ATTR_SH(ch1_low, _evlist, _show, _store, _mask) + +#define IIO_EVENT_ATTR_CH2_LOW_SH(_evlist, _show, _store, _mask) \ + IIO_EVENT_ATTR_SH(ch2_low, _evlist, _show, _store, _mask) + +static void ad7150_interrupt_handler_bh(struct work_struct *work_s) +{ + struct ad7150_chip_info *chip = + container_of(work_s, struct ad7150_chip_info, thresh_work); + u8 int_status; + + enable_irq(chip->client->irq); + + ad7150_i2c_read(chip, AD7150_STATUS, &int_status, 1); + + if ((int_status & AD7150_STATUS_OUT1) && !(chip->old_state & AD7150_STATUS_OUT1)) + iio_push_event(chip->indio_dev, 0, + IIO_EVENT_CODE_CH1_HIGH, + chip->last_timestamp); + else if ((!(int_status & AD7150_STATUS_OUT1)) && (chip->old_state & AD7150_STATUS_OUT1)) + iio_push_event(chip->indio_dev, 0, + IIO_EVENT_CODE_CH1_LOW, + chip->last_timestamp); + + if ((int_status & AD7150_STATUS_OUT2) && !(chip->old_state & AD7150_STATUS_OUT2)) + iio_push_event(chip->indio_dev, 0, + IIO_EVENT_CODE_CH2_HIGH, + chip->last_timestamp); + else if ((!(int_status & AD7150_STATUS_OUT2)) && (chip->old_state & AD7150_STATUS_OUT2)) + iio_push_event(chip->indio_dev, 0, + IIO_EVENT_CODE_CH2_LOW, + chip->last_timestamp); +} + +static int ad7150_interrupt_handler_th(struct iio_dev *dev_info, + int index, + s64 timestamp, + int no_test) +{ + struct ad7150_chip_info *chip = dev_info->dev_data; + + chip->last_timestamp = timestamp; + schedule_work(&chip->thresh_work); + + return 0; +} + +IIO_EVENT_SH(threshold, &ad7150_interrupt_handler_th); + +static ssize_t ad7150_query_out_mode(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + /* + * AD7150 provides two logic output channels, which can be used as interrupt + * but the pins are not configurable + */ + return sprintf(buf, "1\n"); +} + +static ssize_t ad7150_set_out_mode(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + return len; +} + +IIO_EVENT_ATTR_CH1_HIGH_SH(iio_event_threshold, ad7150_query_out_mode, ad7150_set_out_mode, 0); +IIO_EVENT_ATTR_CH2_HIGH_SH(iio_event_threshold, ad7150_query_out_mode, ad7150_set_out_mode, 0); +IIO_EVENT_ATTR_CH1_LOW_SH(iio_event_threshold, ad7150_query_out_mode, ad7150_set_out_mode, 0); +IIO_EVENT_ATTR_CH2_LOW_SH(iio_event_threshold, ad7150_query_out_mode, ad7150_set_out_mode, 0); + +static struct attribute *ad7150_event_attributes[] = { + &iio_event_attr_ch1_high.dev_attr.attr, + &iio_event_attr_ch2_high.dev_attr.attr, + &iio_event_attr_ch1_low.dev_attr.attr, + &iio_event_attr_ch2_low.dev_attr.attr, + NULL, +}; + +static struct attribute_group ad7150_event_attribute_group = { + .attrs = ad7150_event_attributes, +}; + +/* + * device probe and remove + */ + +static int __devinit ad7150_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + int ret = 0, regdone = 0; + struct ad7150_chip_info *chip = kzalloc(sizeof(*chip), GFP_KERNEL); + if (chip == NULL) { + ret = -ENOMEM; + goto error_ret; + } + + /* this is only used for device removal purposes */ + i2c_set_clientdata(client, chip); + + chip->client = client; + chip->name = id->name; + + chip->indio_dev = iio_allocate_device(); + if (chip->indio_dev == NULL) { + ret = -ENOMEM; + goto error_free_chip; + } + + /* Echipabilish that the iio_dev is a child of the i2c device */ + chip->indio_dev->dev.parent = &client->dev; + chip->indio_dev->attrs = &ad7150_attribute_group; + chip->indio_dev->event_attrs = &ad7150_event_attribute_group; + chip->indio_dev->dev_data = (void *)(chip); + chip->indio_dev->driver_module = THIS_MODULE; + chip->indio_dev->num_interrupt_lines = 1; + chip->indio_dev->modes = INDIO_DIRECT_MODE; + + ret = iio_device_register(chip->indio_dev); + if (ret) + goto error_free_dev; + regdone = 1; + + if (client->irq && gpio_is_valid(irq_to_gpio(client->irq)) > 0) { + ret = iio_register_interrupt_line(client->irq, + chip->indio_dev, + 0, + IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, + "ad7150"); + if (ret) + goto error_free_dev; + + iio_add_event_to_list(iio_event_attr_ch2_low.listel, + &chip->indio_dev->interrupts[0]->ev_list); + + INIT_WORK(&chip->thresh_work, ad7150_interrupt_handler_bh); + } + + dev_err(&client->dev, "%s capacitive sensor registered, irq: %d\n", id->name, client->irq); + + return 0; + +error_free_dev: + if (regdone) + iio_device_unregister(chip->indio_dev); + else + iio_free_device(chip->indio_dev); +error_free_chip: + kfree(chip); +error_ret: + return ret; +} + +static int __devexit ad7150_remove(struct i2c_client *client) +{ + struct ad7150_chip_info *chip = i2c_get_clientdata(client); + struct iio_dev *indio_dev = chip->indio_dev; + + if (client->irq && gpio_is_valid(irq_to_gpio(client->irq)) > 0) + iio_unregister_interrupt_line(indio_dev, 0); + iio_device_unregister(indio_dev); + kfree(chip); + + return 0; +} + +static const struct i2c_device_id ad7150_id[] = { + { "ad7150", 0 }, + { "ad7151", 0 }, + { "ad7156", 0 }, + {} +}; + +MODULE_DEVICE_TABLE(i2c, ad7150_id); + +static struct i2c_driver ad7150_driver = { + .driver = { + .name = "ad7150", + }, + .probe = ad7150_probe, + .remove = __devexit_p(ad7150_remove), + .id_table = ad7150_id, +}; + +static __init int ad7150_init(void) +{ + return i2c_add_driver(&ad7150_driver); +} + +static __exit void ad7150_exit(void) +{ + i2c_del_driver(&ad7150_driver); +} + +MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>"); +MODULE_DESCRIPTION("Analog Devices ad7150/1/6 capacitive sensor driver"); +MODULE_LICENSE("GPL v2"); + +module_init(ad7150_init); +module_exit(ad7150_exit); -- cgit v1.2.3 From a20ebd930081edaf21f354db195e7bb9820b18d8 Mon Sep 17 00:00:00 2001 From: Barry Song Date: Wed, 27 Oct 2010 21:43:54 -0400 Subject: staging: iio: adc: new driver for AD7152/3 devices Signed-off-by: Barry Song Signed-off-by: Michael Hennerich Acked-by: Jonathan Cameron Signed-off-by: Mike Frysinger Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/adc/Kconfig | 7 + drivers/staging/iio/adc/Makefile | 1 + drivers/staging/iio/adc/ad7152.c | 610 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 618 insertions(+) create mode 100644 drivers/staging/iio/adc/ad7152.c diff --git a/drivers/staging/iio/adc/Kconfig b/drivers/staging/iio/adc/Kconfig index 51b9cc654c86..7f03571227a5 100644 --- a/drivers/staging/iio/adc/Kconfig +++ b/drivers/staging/iio/adc/Kconfig @@ -34,6 +34,13 @@ config AD7150 Say yes here to build support for Analog Devices capacitive sensors. (ad7150, ad7151, ad7156) Provides direct access via sysfs. +config AD7152 + tristate "Analog Devices ad7152/3 capacitive sensor driver" + depends on I2C + help + Say yes here to build support for Analog Devices capacitive sensors. + (ad7152, ad7153) Provides direct access via sysfs. + config AD799X tristate "Analog Devices AD799x ADC driver" depends on I2C diff --git a/drivers/staging/iio/adc/Makefile b/drivers/staging/iio/adc/Makefile index 51b39aab061a..a13475412371 100644 --- a/drivers/staging/iio/adc/Makefile +++ b/drivers/staging/iio/adc/Makefile @@ -16,3 +16,4 @@ ad7476-$(CONFIG_IIO_RING_BUFFER) += ad7476_ring.o obj-$(CONFIG_AD7476) += ad7476.o obj-$(CONFIG_AD7150) += ad7150.o +obj-$(CONFIG_AD7152) += ad7152.o diff --git a/drivers/staging/iio/adc/ad7152.c b/drivers/staging/iio/adc/ad7152.c new file mode 100644 index 000000000000..fa7f84062307 --- /dev/null +++ b/drivers/staging/iio/adc/ad7152.c @@ -0,0 +1,610 @@ +/* + * AD7152 capacitive sensor driver supporting AD7152/3 + * + * Copyright 2010 Analog Devices Inc. + * + * Licensed under the GPL-2 or later. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../iio.h" +#include "../sysfs.h" + +/* + * AD7152 registers definition + */ + +#define AD7152_STATUS 0 +#define AD7152_STATUS_RDY1 (1 << 0) +#define AD7152_STATUS_RDY2 (1 << 1) +#define AD7152_CH1_DATA_HIGH 1 +#define AD7152_CH1_DATA_LOW 2 +#define AD7152_CH2_DATA_HIGH 3 +#define AD7152_CH2_DATA_LOW 4 +#define AD7152_CH1_OFFS_HIGH 5 +#define AD7152_CH1_OFFS_LOW 6 +#define AD7152_CH2_OFFS_HIGH 7 +#define AD7152_CH2_OFFS_LOW 8 +#define AD7152_CH1_GAIN_HIGH 9 +#define AD7152_CH1_GAIN_LOW 10 +#define AD7152_CH1_SETUP 11 +#define AD7152_CH2_GAIN_HIGH 12 +#define AD7152_CH2_GAIN_LOW 13 +#define AD7152_CH2_SETUP 14 +#define AD7152_CFG 15 +#define AD7152_RESEVERD 16 +#define AD7152_CAPDAC_POS 17 +#define AD7152_CAPDAC_NEG 18 +#define AD7152_CFG2 26 + +#define AD7152_MAX_CONV_MODE 6 + +/* + * struct ad7152_chip_info - chip specifc information + */ + +struct ad7152_chip_info { + const char *name; + struct i2c_client *client; + struct iio_dev *indio_dev; + u16 ch1_offset; /* Channel 1 offset calibration coefficient */ + u16 ch1_gain; /* Channel 1 gain coefficient */ + u8 ch1_setup; + u16 ch2_offset; /* Channel 2 offset calibration coefficient */ + u16 ch2_gain; /* Channel 1 gain coefficient */ + u8 ch2_setup; + u8 filter_rate_setup; /* Capacitive channel digital filter setup; conversion time/update rate setup per channel */ + char *conversion_mode; +}; + +struct ad7152_conversion_mode { + char *name; + u8 reg_cfg; +}; + +struct ad7152_conversion_mode ad7152_conv_mode_table[AD7152_MAX_CONV_MODE] = { + { "idle", 0 }, + { "continuous-conversion", 1 }, + { "single-conversion", 2 }, + { "power-down", 3 }, + { "offset-calibration", 5 }, + { "gain-calibration", 6 }, +}; + +/* + * ad7152 register access by I2C + */ + +static int ad7152_i2c_read(struct ad7152_chip_info *chip, u8 reg, u8 *data, int len) +{ + struct i2c_client *client = chip->client; + int ret; + + ret = i2c_master_send(client, ®, 1); + if (ret < 0) { + dev_err(&client->dev, "I2C write error\n"); + return ret; + } + + ret = i2c_master_recv(client, data, len); + if (ret < 0) { + dev_err(&client->dev, "I2C read error\n"); + } + + return ret; +} + +static int ad7152_i2c_write(struct ad7152_chip_info *chip, u8 reg, u8 data) +{ + struct i2c_client *client = chip->client; + int ret; + + u8 tx[2] = { + reg, + data, + }; + + ret = i2c_master_send(client, tx, 2); + if (ret < 0) + dev_err(&client->dev, "I2C write error\n"); + + return ret; +} + +/* + * sysfs nodes + */ + +#define IIO_DEV_ATTR_AVAIL_CONVERSION_MODES(_show) \ + IIO_DEVICE_ATTR(available_conversion_modes, S_IRUGO, _show, NULL, 0) +#define IIO_DEV_ATTR_CONVERSION_MODE(_mode, _show, _store) \ + IIO_DEVICE_ATTR(conversion_mode, _mode, _show, _store, 0) +#define IIO_DEV_ATTR_CH1_OFFSET(_mode, _show, _store) \ + IIO_DEVICE_ATTR(ch1_offset, _mode, _show, _store, 0) +#define IIO_DEV_ATTR_CH2_OFFSET(_mode, _show, _store) \ + IIO_DEVICE_ATTR(ch2_offset, _mode, _show, _store, 0) +#define IIO_DEV_ATTR_CH1_GAIN(_mode, _show, _store) \ + IIO_DEVICE_ATTR(ch1_gain, _mode, _show, _store, 0) +#define IIO_DEV_ATTR_CH2_GAIN(_mode, _show, _store) \ + IIO_DEVICE_ATTR(ch2_gain, _mode, _show, _store, 0) +#define IIO_DEV_ATTR_CH1_VALUE(_show) \ + IIO_DEVICE_ATTR(ch1_value, S_IRUGO, _show, NULL, 0) +#define IIO_DEV_ATTR_CH2_VALUE(_show) \ + IIO_DEVICE_ATTR(ch2_value, S_IRUGO, _show, NULL, 0) +#define IIO_DEV_ATTR_CH1_SETUP(_mode, _show, _store) \ + IIO_DEVICE_ATTR(ch1_setup, _mode, _show, _store, 0) +#define IIO_DEV_ATTR_CH2_SETUP(_mode, _show, _store) \ + IIO_DEVICE_ATTR(ch2_setup, _mode, _show, _store, 0) +#define IIO_DEV_ATTR_FILTER_RATE_SETUP(_mode, _show, _store) \ + IIO_DEVICE_ATTR(filter_rate_setup, _mode, _show, _store, 0) + +static ssize_t ad7152_show_conversion_modes(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + int i; + int len = 0; + + for (i = 0; i < AD7152_MAX_CONV_MODE; i++) + len += sprintf(buf + len, "%s ", ad7152_conv_mode_table[i].name); + + len += sprintf(buf + len, "\n"); + + return len; +} + +static IIO_DEV_ATTR_AVAIL_CONVERSION_MODES(ad7152_show_conversion_modes); + +static ssize_t ad7152_show_ch1_value(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad7152_chip_info *chip = dev_info->dev_data; + u8 data[2]; + + ad7152_i2c_read(chip, AD7152_CH1_DATA_HIGH, data, 2); + return sprintf(buf, "%d\n", ((int)data[0] << 8) | data[1]); +} + +static IIO_DEV_ATTR_CH1_VALUE(ad7152_show_ch1_value); + +static ssize_t ad7152_show_ch2_value(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad7152_chip_info *chip = dev_info->dev_data; + u8 data[2]; + + ad7152_i2c_read(chip, AD7152_CH2_DATA_HIGH, data, 2); + return sprintf(buf, "%d\n", ((int)data[0] << 8) | data[1]); +} + +static IIO_DEV_ATTR_CH2_VALUE(ad7152_show_ch2_value); + +static ssize_t ad7152_show_conversion_mode(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad7152_chip_info *chip = dev_info->dev_data; + + return sprintf(buf, "%s\n", chip->conversion_mode); +} + +static ssize_t ad7152_store_conversion_mode(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad7152_chip_info *chip = dev_info->dev_data; + u8 cfg; + int i; + + ad7152_i2c_read(chip, AD7152_CFG, &cfg, 1); + + for (i = 0; i < AD7152_MAX_CONV_MODE; i++) + if (strncmp(buf, ad7152_conv_mode_table[i].name, + strlen(ad7152_conv_mode_table[i].name) - 1) == 0) { + chip->conversion_mode = ad7152_conv_mode_table[i].name; + cfg |= 0x18 | ad7152_conv_mode_table[i].reg_cfg; + ad7152_i2c_write(chip, AD7152_CFG, cfg); + return len; + } + + dev_err(dev, "not supported conversion mode\n"); + + return -EINVAL; +} + +static IIO_DEV_ATTR_CONVERSION_MODE(S_IRUGO | S_IWUSR, + ad7152_show_conversion_mode, + ad7152_store_conversion_mode); + +static ssize_t ad7152_show_ch1_offset(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad7152_chip_info *chip = dev_info->dev_data; + + return sprintf(buf, "%d\n", chip->ch1_offset); +} + +static ssize_t ad7152_store_ch1_offset(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad7152_chip_info *chip = dev_info->dev_data; + unsigned long data; + int ret; + + ret = strict_strtoul(buf, 10, &data); + + if ((!ret) && (data < 0x10000)) { + ad7152_i2c_write(chip, AD7152_CH1_OFFS_HIGH, data >> 8); + ad7152_i2c_write(chip, AD7152_CH1_OFFS_LOW, data); + chip->ch1_offset = data; + return len; + } + + return -EINVAL; +} + +static IIO_DEV_ATTR_CH1_OFFSET(S_IRUGO | S_IWUSR, + ad7152_show_ch1_offset, + ad7152_store_ch1_offset); + +static ssize_t ad7152_show_ch2_offset(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad7152_chip_info *chip = dev_info->dev_data; + + return sprintf(buf, "%d\n", chip->ch2_offset); +} + +static ssize_t ad7152_store_ch2_offset(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad7152_chip_info *chip = dev_info->dev_data; + unsigned long data; + int ret; + + ret = strict_strtoul(buf, 10, &data); + + if ((!ret) && (data < 0x10000)) { + ad7152_i2c_write(chip, AD7152_CH2_OFFS_HIGH, data >> 8); + ad7152_i2c_write(chip, AD7152_CH2_OFFS_LOW, data); + chip->ch2_offset = data; + return len; + } + + return -EINVAL; +} + +static IIO_DEV_ATTR_CH2_OFFSET(S_IRUGO | S_IWUSR, + ad7152_show_ch2_offset, + ad7152_store_ch2_offset); + +static ssize_t ad7152_show_ch1_gain(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad7152_chip_info *chip = dev_info->dev_data; + + return sprintf(buf, "%d\n", chip->ch1_gain); +} + +static ssize_t ad7152_store_ch1_gain(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad7152_chip_info *chip = dev_info->dev_data; + unsigned long data; + int ret; + + ret = strict_strtoul(buf, 10, &data); + + if ((!ret) && (data < 0x10000)) { + ad7152_i2c_write(chip, AD7152_CH1_GAIN_HIGH, data >> 8); + ad7152_i2c_write(chip, AD7152_CH1_GAIN_LOW, data); + chip->ch1_gain = data; + return len; + } + + return -EINVAL; +} + +static IIO_DEV_ATTR_CH1_GAIN(S_IRUGO | S_IWUSR, + ad7152_show_ch1_gain, + ad7152_store_ch1_gain); + +static ssize_t ad7152_show_ch2_gain(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad7152_chip_info *chip = dev_info->dev_data; + + return sprintf(buf, "%d\n", chip->ch2_gain); +} + +static ssize_t ad7152_store_ch2_gain(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad7152_chip_info *chip = dev_info->dev_data; + unsigned long data; + int ret; + + ret = strict_strtoul(buf, 10, &data); + + if ((!ret) && (data < 0x10000)) { + ad7152_i2c_write(chip, AD7152_CH2_GAIN_HIGH, data >> 8); + ad7152_i2c_write(chip, AD7152_CH2_GAIN_LOW, data); + chip->ch2_gain = data; + return len; + } + + return -EINVAL; +} + +static IIO_DEV_ATTR_CH2_GAIN(S_IRUGO | S_IWUSR, + ad7152_show_ch2_gain, + ad7152_store_ch2_gain); + +static ssize_t ad7152_show_ch1_setup(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad7152_chip_info *chip = dev_info->dev_data; + + return sprintf(buf, "0x%02x\n", chip->ch1_setup); +} + +static ssize_t ad7152_store_ch1_setup(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad7152_chip_info *chip = dev_info->dev_data; + unsigned long data; + int ret; + + ret = strict_strtoul(buf, 10, &data); + + if ((!ret) && (data < 0x100)) { + ad7152_i2c_write(chip, AD7152_CH1_SETUP, data); + chip->ch1_setup = data; + return len; + } + + return -EINVAL; +} + +static IIO_DEV_ATTR_CH1_SETUP(S_IRUGO | S_IWUSR, + ad7152_show_ch1_setup, + ad7152_store_ch1_setup); + +static ssize_t ad7152_show_ch2_setup(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad7152_chip_info *chip = dev_info->dev_data; + + return sprintf(buf, "0x%02x\n", chip->ch2_setup); +} + +static ssize_t ad7152_store_ch2_setup(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad7152_chip_info *chip = dev_info->dev_data; + unsigned long data; + int ret; + + ret = strict_strtoul(buf, 10, &data); + + if ((!ret) && (data < 0x100)) { + ad7152_i2c_write(chip, AD7152_CH2_SETUP, data); + chip->ch2_setup = data; + return len; + } + + return -EINVAL; +} + +static IIO_DEV_ATTR_CH2_SETUP(S_IRUGO | S_IWUSR, + ad7152_show_ch2_setup, + ad7152_store_ch2_setup); + +static ssize_t ad7152_show_filter_rate_setup(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad7152_chip_info *chip = dev_info->dev_data; + + return sprintf(buf, "0x%02x\n", chip->filter_rate_setup); +} + +static ssize_t ad7152_store_filter_rate_setup(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad7152_chip_info *chip = dev_info->dev_data; + unsigned long data; + int ret; + + ret = strict_strtoul(buf, 10, &data); + + if ((!ret) && (data < 0x100)) { + ad7152_i2c_write(chip, AD7152_CFG2, data); + chip->filter_rate_setup = data; + return len; + } + + return -EINVAL; +} + +static IIO_DEV_ATTR_FILTER_RATE_SETUP(S_IRUGO | S_IWUSR, + ad7152_show_filter_rate_setup, + ad7152_store_filter_rate_setup); + +static ssize_t ad7152_show_name(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad7152_chip_info *chip = dev_info->dev_data; + return sprintf(buf, "%s\n", chip->name); +} + +static IIO_DEVICE_ATTR(name, S_IRUGO, ad7152_show_name, NULL, 0); + +static struct attribute *ad7152_attributes[] = { + &iio_dev_attr_available_conversion_modes.dev_attr.attr, + &iio_dev_attr_conversion_mode.dev_attr.attr, + &iio_dev_attr_ch1_gain.dev_attr.attr, + &iio_dev_attr_ch2_gain.dev_attr.attr, + &iio_dev_attr_ch1_offset.dev_attr.attr, + &iio_dev_attr_ch2_offset.dev_attr.attr, + &iio_dev_attr_ch1_value.dev_attr.attr, + &iio_dev_attr_ch2_value.dev_attr.attr, + &iio_dev_attr_ch1_setup.dev_attr.attr, + &iio_dev_attr_ch2_setup.dev_attr.attr, + &iio_dev_attr_filter_rate_setup.dev_attr.attr, + &iio_dev_attr_name.dev_attr.attr, + NULL, +}; + +static const struct attribute_group ad7152_attribute_group = { + .attrs = ad7152_attributes, +}; + +/* + * device probe and remove + */ + +static int __devinit ad7152_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + int ret = 0; + struct ad7152_chip_info *chip = kzalloc(sizeof(*chip), GFP_KERNEL); + if (chip == NULL) { + ret = -ENOMEM; + goto error_ret; + } + + /* this is only used for device removal purposes */ + i2c_set_clientdata(client, chip); + + chip->client = client; + chip->name = id->name; + + chip->indio_dev = iio_allocate_device(); + if (chip->indio_dev == NULL) { + ret = -ENOMEM; + goto error_free_chip; + } + + /* Echipabilish that the iio_dev is a child of the i2c device */ + chip->indio_dev->dev.parent = &client->dev; + chip->indio_dev->attrs = &ad7152_attribute_group; + chip->indio_dev->dev_data = (void *)(chip); + chip->indio_dev->driver_module = THIS_MODULE; + chip->indio_dev->modes = INDIO_DIRECT_MODE; + + ret = iio_device_register(chip->indio_dev); + if (ret) + goto error_free_dev; + + dev_err(&client->dev, "%s capacitive sensor registered\n", id->name); + + return 0; + +error_free_dev: + iio_free_device(chip->indio_dev); +error_free_chip: + kfree(chip); +error_ret: + return ret; +} + +static int __devexit ad7152_remove(struct i2c_client *client) +{ + struct ad7152_chip_info *chip = i2c_get_clientdata(client); + struct iio_dev *indio_dev = chip->indio_dev; + + if (client->irq && gpio_is_valid(irq_to_gpio(client->irq)) > 0) + iio_unregister_interrupt_line(indio_dev, 0); + iio_device_unregister(indio_dev); + kfree(chip); + + return 0; +} + +static const struct i2c_device_id ad7152_id[] = { + { "ad7152", 0 }, + { "ad7153", 0 }, + {} +}; + +MODULE_DEVICE_TABLE(i2c, ad7152_id); + +static struct i2c_driver ad7152_driver = { + .driver = { + .name = "ad7152", + }, + .probe = ad7152_probe, + .remove = __devexit_p(ad7152_remove), + .id_table = ad7152_id, +}; + +static __init int ad7152_init(void) +{ + return i2c_add_driver(&ad7152_driver); +} + +static __exit void ad7152_exit(void) +{ + i2c_del_driver(&ad7152_driver); +} + +MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>"); +MODULE_DESCRIPTION("Analog Devices ad7152/3 capacitive sensor driver"); +MODULE_LICENSE("GPL v2"); + +module_init(ad7152_init); +module_exit(ad7152_exit); -- cgit v1.2.3 From ddaecd5ba8cc3bc68b65b01cc8dbfedcac87254e Mon Sep 17 00:00:00 2001 From: Sonic Zhang Date: Wed, 27 Oct 2010 21:43:55 -0400 Subject: staging: iio: adc: new driver for AD7291 devices Signed-off-by: Sonic Zhang Signed-off-by: Michael Hennerich Acked-by: Jonathan Cameron Signed-off-by: Mike Frysinger Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/adc/Kconfig | 7 + drivers/staging/iio/adc/Makefile | 1 + drivers/staging/iio/adc/ad7291.c | 1039 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 1047 insertions(+) create mode 100644 drivers/staging/iio/adc/ad7291.c diff --git a/drivers/staging/iio/adc/Kconfig b/drivers/staging/iio/adc/Kconfig index 7f03571227a5..fa78413f3fae 100644 --- a/drivers/staging/iio/adc/Kconfig +++ b/drivers/staging/iio/adc/Kconfig @@ -41,6 +41,13 @@ config AD7152 Say yes here to build support for Analog Devices capacitive sensors. (ad7152, ad7153) Provides direct access via sysfs. +config AD7291 + tristate "Analog Devices AD7291 temperature sensor driver" + depends on I2C + help + Say yes here to build support for Analog Devices AD7291 + temperature sensors. + config AD799X tristate "Analog Devices AD799x ADC driver" depends on I2C diff --git a/drivers/staging/iio/adc/Makefile b/drivers/staging/iio/adc/Makefile index a13475412371..5e99a863203a 100644 --- a/drivers/staging/iio/adc/Makefile +++ b/drivers/staging/iio/adc/Makefile @@ -17,3 +17,4 @@ obj-$(CONFIG_AD7476) += ad7476.o obj-$(CONFIG_AD7150) += ad7150.o obj-$(CONFIG_AD7152) += ad7152.o +obj-$(CONFIG_AD7291) += ad7291.o diff --git a/drivers/staging/iio/adc/ad7291.c b/drivers/staging/iio/adc/ad7291.c new file mode 100644 index 000000000000..34041a72aa52 --- /dev/null +++ b/drivers/staging/iio/adc/ad7291.c @@ -0,0 +1,1039 @@ +/* + * AD7291 digital temperature sensor driver supporting AD7291 + * + * Copyright 2010 Analog Devices Inc. + * + * Licensed under the GPL-2 or later. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../iio.h" +#include "../sysfs.h" + +/* + * AD7291 registers definition + */ +#define AD7291_COMMAND 0 +#define AD7291_VOLTAGE 1 +#define AD7291_T_SENSE 2 +#define AD7291_T_AVERAGE 3 +#define AD7291_VOLTAGE_LIMIT_BASE 4 +#define AD7291_VOLTAGE_LIMIT_COUNT 8 +#define AD7291_T_SENSE_HIGH 0x1c +#define AD7291_T_SENSE_LOW 0x1d +#define AD7291_T_SENSE_HYST 0x1e +#define AD7291_VOLTAGE_ALERT_STATUS 0x1f +#define AD7291_T_ALERT_STATUS 0x20 + +/* + * AD7291 command + */ +#define AD7291_AUTOCYCLE 0x1 +#define AD7291_RESET 0x2 +#define AD7291_ALART_CLEAR 0x4 +#define AD7291_ALART_POLARITY 0x8 +#define AD7291_EXT_REF 0x10 +#define AD7291_NOISE_DELAY 0x20 +#define AD7291_T_SENSE_MASK 0x40 +#define AD7291_VOLTAGE_MASK 0xff00 +#define AD7291_VOLTAGE_OFFSET 0x8 + +/* + * AD7291 value masks + */ +#define AD7291_CHANNEL_MASK 0xf000 +#define AD7291_VALUE_MASK 0xfff +#define AD7291_T_VALUE_SIGN 0x400 +#define AD7291_T_VALUE_FLOAT_OFFSET 2 +#define AD7291_T_VALUE_FLOAT_MASK 0x2 + +/* + * struct ad7291_chip_info - chip specifc information + */ + +struct ad7291_chip_info { + const char *name; + struct i2c_client *client; + struct iio_dev *indio_dev; + struct work_struct thresh_work; + s64 last_timestamp; + u16 command; + u8 channels; /* Active voltage channels */ +}; + +/* + * struct ad7291_chip_info - chip specifc information + */ + +struct ad7291_limit_regs { + u16 data_high; + u16 data_low; + u16 hysteresis; +}; + +/* + * ad7291 register access by I2C + */ +static int ad7291_i2c_read(struct ad7291_chip_info *chip, u8 reg, u16 *data) +{ + struct i2c_client *client = chip->client; + int ret = 0; + + ret = i2c_smbus_read_word_data(client, reg); + if (ret < 0) { + dev_err(&client->dev, "I2C read error\n"); + return ret; + } + + *data = swab16((u16)ret); + + return 0; +} + +static int ad7291_i2c_write(struct ad7291_chip_info *chip, u8 reg, u16 data) +{ + struct i2c_client *client = chip->client; + int ret = 0; + + ret = i2c_smbus_write_word_data(client, reg, swab16(data)); + if (ret < 0) + dev_err(&client->dev, "I2C write error\n"); + + return ret; +} + +/* Returns negative errno, or else the number of words read. */ +static int ad7291_i2c_read_data(struct ad7291_chip_info *chip, u8 reg, u16 *data) +{ + struct i2c_client *client = chip->client; + u8 commands[4]; + int ret = 0; + int i, count; + + if (reg == AD7291_T_SENSE || reg == AD7291_T_AVERAGE) + count = 2; + else if (reg == AD7291_VOLTAGE) { + if (!chip->channels) { + dev_err(&client->dev, "No voltage channel is selected.\n"); + return -EINVAL; + } + count = 2 + chip->channels * 2; + } else { + dev_err(&client->dev, "I2C wrong data register\n"); + return -EINVAL; + } + + commands[0] = 0; + commands[1] = (chip->command >> 8) & 0xff; + commands[2] = chip->command & 0xff; + commands[3] = reg; + + ret = i2c_master_send(client, commands, 4); + if (ret < 0) { + dev_err(&client->dev, "I2C master send error\n"); + return ret; + } + + ret = i2c_master_recv(client, (u8 *)data, count); + if (ret < 0) { + dev_err(&client->dev, "I2C master receive error\n"); + return ret; + } + ret >>= 2; + + for (i = 0; i < ret; i++) + data[i] = swab16(data[i]); + + return ret; +} + +static ssize_t ad7291_show_mode(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad7291_chip_info *chip = dev_info->dev_data; + + if (chip->command & AD7291_AUTOCYCLE) + return sprintf(buf, "autocycle\n"); + else + return sprintf(buf, "command\n"); +} + +static ssize_t ad7291_store_mode(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad7291_chip_info *chip = dev_info->dev_data; + u16 command; + int ret; + + command = chip->command & (~AD7291_AUTOCYCLE); + if (strcmp(buf, "autocycle")) + command |= AD7291_AUTOCYCLE; + + ret = ad7291_i2c_write(chip, AD7291_COMMAND, command); + if (ret) + return -EIO; + + chip->command = command; + + return ret; +} + +static IIO_DEVICE_ATTR(mode, S_IRUGO | S_IWUSR, + ad7291_show_mode, + ad7291_store_mode, + 0); + +static ssize_t ad7291_show_available_modes(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + return sprintf(buf, "command\nautocycle\n"); +} + +static IIO_DEVICE_ATTR(available_modes, S_IRUGO, ad7291_show_available_modes, NULL, 0); + +static ssize_t ad7291_store_reset(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad7291_chip_info *chip = dev_info->dev_data; + u16 command; + int ret; + + command = chip->command | AD7291_RESET; + + ret = ad7291_i2c_write(chip, AD7291_COMMAND, command); + if (ret) + return -EIO; + + return ret; +} + +static IIO_DEVICE_ATTR(reset, S_IWUSR, + NULL, + ad7291_store_reset, + 0); + +static ssize_t ad7291_show_ext_ref(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad7291_chip_info *chip = dev_info->dev_data; + + return sprintf(buf, "%d\n", !!(chip->command & AD7291_EXT_REF)); +} + +static ssize_t ad7291_store_ext_ref(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad7291_chip_info *chip = dev_info->dev_data; + u16 command; + int ret; + + command = chip->command & (~AD7291_EXT_REF); + if (strcmp(buf, "1")) + command |= AD7291_EXT_REF; + + ret = ad7291_i2c_write(chip, AD7291_COMMAND, command); + if (ret) + return -EIO; + + chip->command = command; + + return ret; +} + +static IIO_DEVICE_ATTR(ext_ref, S_IRUGO | S_IWUSR, + ad7291_show_ext_ref, + ad7291_store_ext_ref, + 0); + +static ssize_t ad7291_show_noise_delay(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad7291_chip_info *chip = dev_info->dev_data; + + return sprintf(buf, "%d\n", !!(chip->command & AD7291_NOISE_DELAY)); +} + +static ssize_t ad7291_store_noise_delay(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad7291_chip_info *chip = dev_info->dev_data; + u16 command; + int ret; + + command = chip->command & (~AD7291_NOISE_DELAY); + if (strcmp(buf, "1")) + command |= AD7291_NOISE_DELAY; + + ret = ad7291_i2c_write(chip, AD7291_COMMAND, command); + if (ret) + return -EIO; + + chip->command = command; + + return ret; +} + +static IIO_DEVICE_ATTR(noise_delay, S_IRUGO | S_IWUSR, + ad7291_show_noise_delay, + ad7291_store_noise_delay, + 0); + +static ssize_t ad7291_show_t_sense(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad7291_chip_info *chip = dev_info->dev_data; + u16 data; + char sign = ' '; + int ret; + + ret = ad7291_i2c_read_data(chip, AD7291_T_SENSE, &data); + if (ret) + return -EIO; + + if (data & AD7291_T_VALUE_SIGN) { + /* convert supplement to positive value */ + data = (AD7291_T_VALUE_SIGN << 1) - data; + sign = '-'; + } + + return sprintf(buf, "%c%d.%.2d\n", sign, + (data >> AD7291_T_VALUE_FLOAT_OFFSET), + (data & AD7291_T_VALUE_FLOAT_MASK) * 25); +} + +static IIO_DEVICE_ATTR(t_sense, S_IRUGO, ad7291_show_t_sense, NULL, 0); + +static ssize_t ad7291_show_t_average(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad7291_chip_info *chip = dev_info->dev_data; + u16 data; + char sign = ' '; + int ret; + + ret = ad7291_i2c_read_data(chip, AD7291_T_AVERAGE, &data); + if (ret) + return -EIO; + + if (data & AD7291_T_VALUE_SIGN) { + /* convert supplement to positive value */ + data = (AD7291_T_VALUE_SIGN << 1) - data; + sign = '-'; + } + + return sprintf(buf, "%c%d.%.2d\n", sign, + (data >> AD7291_T_VALUE_FLOAT_OFFSET), + (data & AD7291_T_VALUE_FLOAT_MASK) * 25); +} + +static IIO_DEVICE_ATTR(t_average, S_IRUGO, ad7291_show_t_average, NULL, 0); + +static ssize_t ad7291_show_voltage(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad7291_chip_info *chip = dev_info->dev_data; + u16 data[AD7291_VOLTAGE_LIMIT_COUNT]; + int i, size, ret; + + ret = ad7291_i2c_read_data(chip, AD7291_VOLTAGE, data); + if (ret) + return -EIO; + + for (i = 0; i < AD7291_VOLTAGE_LIMIT_COUNT; i++) { + if (chip->command & (AD7291_T_SENSE_MASK << i)) { + ret = sprintf(buf, "channel[%d]=%d\n", i, + data[i] & AD7291_VALUE_MASK); + if (ret < 0) + break; + buf += ret; + size += ret; + } + } + + return size; +} + +static IIO_DEVICE_ATTR(voltage, S_IRUGO, ad7291_show_voltage, NULL, 0); + +static ssize_t ad7291_show_channel_mask(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad7291_chip_info *chip = dev_info->dev_data; + + return sprintf(buf, "0x%x\n", (chip->command & AD7291_VOLTAGE_MASK) >> + AD7291_VOLTAGE_OFFSET); +} + +static ssize_t ad7291_store_channel_mask(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad7291_chip_info *chip = dev_info->dev_data; + u16 command; + unsigned long data; + int i, ret; + + ret = strict_strtoul(buf, 16, &data); + if (ret || data > 0xff) + return -EINVAL; + + command = chip->command & (~AD7291_VOLTAGE_MASK); + command |= data << AD7291_VOLTAGE_OFFSET; + + ret = ad7291_i2c_write(chip, AD7291_COMMAND, command); + if (ret) + return -EIO; + + chip->command = command; + + for (i = 0, chip->channels = 0; i < AD7291_VOLTAGE_LIMIT_COUNT; i++) { + if (chip->command & (AD7291_T_SENSE_MASK << i)) + chip->channels++; + } + + return ret; +} + +static IIO_DEVICE_ATTR(channel_mask, S_IRUGO | S_IWUSR, + ad7291_show_channel_mask, + ad7291_store_channel_mask, + 0); + +static ssize_t ad7291_show_name(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad7291_chip_info *chip = dev_info->dev_data; + return sprintf(buf, "%s\n", chip->name); +} + +static IIO_DEVICE_ATTR(name, S_IRUGO, ad7291_show_name, NULL, 0); + +static struct attribute *ad7291_attributes[] = { + &iio_dev_attr_available_modes.dev_attr.attr, + &iio_dev_attr_mode.dev_attr.attr, + &iio_dev_attr_reset.dev_attr.attr, + &iio_dev_attr_ext_ref.dev_attr.attr, + &iio_dev_attr_noise_delay.dev_attr.attr, + &iio_dev_attr_t_sense.dev_attr.attr, + &iio_dev_attr_t_average.dev_attr.attr, + &iio_dev_attr_voltage.dev_attr.attr, + &iio_dev_attr_channel_mask.dev_attr.attr, + &iio_dev_attr_name.dev_attr.attr, + NULL, +}; + +static const struct attribute_group ad7291_attribute_group = { + .attrs = ad7291_attributes, +}; + +/* + * temperature bound events + */ + +#define IIO_EVENT_CODE_AD7291_T_SENSE_HIGH IIO_BUFFER_EVENT_CODE(0) +#define IIO_EVENT_CODE_AD7291_T_SENSE_LOW IIO_BUFFER_EVENT_CODE(1) +#define IIO_EVENT_CODE_AD7291_T_AVG_HIGH IIO_BUFFER_EVENT_CODE(2) +#define IIO_EVENT_CODE_AD7291_T_AVG_LOW IIO_BUFFER_EVENT_CODE(3) +#define IIO_EVENT_CODE_AD7291_VOLTAGE_BASE IIO_BUFFER_EVENT_CODE(4) + +static void ad7291_interrupt_bh(struct work_struct *work_s) +{ + struct ad7291_chip_info *chip = + container_of(work_s, struct ad7291_chip_info, thresh_work); + u16 t_status, v_status; + u16 command; + int i; + + if (ad7291_i2c_read(chip, AD7291_T_ALERT_STATUS, &t_status)) + return; + + if (ad7291_i2c_read(chip, AD7291_VOLTAGE_ALERT_STATUS, &v_status)) + return; + + if (!(t_status || v_status)) + return; + + command = chip->command | AD7291_ALART_CLEAR; + ad7291_i2c_write(chip, AD7291_COMMAND, command); + + command = chip->command & ~AD7291_ALART_CLEAR; + ad7291_i2c_write(chip, AD7291_COMMAND, command); + + enable_irq(chip->client->irq); + + for (i = 0; i < 4; i++) { + if (t_status & (1 << i)) + iio_push_event(chip->indio_dev, 0, + IIO_EVENT_CODE_AD7291_T_SENSE_HIGH + i, + chip->last_timestamp); + } + + for (i = 0; i < AD7291_VOLTAGE_LIMIT_COUNT*2; i++) { + if (v_status & (1 << i)) + iio_push_event(chip->indio_dev, 0, + IIO_EVENT_CODE_AD7291_VOLTAGE_BASE + i, + chip->last_timestamp); + } +} + +static int ad7291_interrupt(struct iio_dev *dev_info, + int index, + s64 timestamp, + int no_test) +{ + struct ad7291_chip_info *chip = dev_info->dev_data; + + chip->last_timestamp = timestamp; + schedule_work(&chip->thresh_work); + + return 0; +} + +IIO_EVENT_SH(ad7291, &ad7291_interrupt); + +static inline ssize_t ad7291_show_t_bound(struct device *dev, + struct device_attribute *attr, + u8 bound_reg, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad7291_chip_info *chip = dev_info->dev_data; + u16 data; + char sign = ' '; + int ret; + + ret = ad7291_i2c_read(chip, bound_reg, &data); + if (ret) + return -EIO; + + data &= AD7291_VALUE_MASK; + if (data & AD7291_T_VALUE_SIGN) { + /* convert supplement to positive value */ + data = (AD7291_T_VALUE_SIGN << 1) - data; + sign = '-'; + } + + return sprintf(buf, "%c%d.%.2d\n", sign, + data >> AD7291_T_VALUE_FLOAT_OFFSET, + (data & AD7291_T_VALUE_FLOAT_MASK) * 25); +} + +static inline ssize_t ad7291_set_t_bound(struct device *dev, + struct device_attribute *attr, + u8 bound_reg, + const char *buf, + size_t len) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad7291_chip_info *chip = dev_info->dev_data; + long tmp1, tmp2; + u16 data; + char *pos; + int ret; + + pos = strchr(buf, '.'); + + ret = strict_strtol(buf, 10, &tmp1); + + if (ret || tmp1 > 127 || tmp1 < -128) + return -EINVAL; + + if (pos) { + len = strlen(pos); + if (len > AD7291_T_VALUE_FLOAT_OFFSET) + len = AD7291_T_VALUE_FLOAT_OFFSET; + pos[len] = 0; + ret = strict_strtol(pos, 10, &tmp2); + + if (!ret) + tmp2 = (tmp2 / 25) * 25; + } + + if (tmp1 < 0) + data = (u16)(-tmp1); + else + data = (u16)tmp1; + data = (data << AD7291_T_VALUE_FLOAT_OFFSET) | + (tmp2 & AD7291_T_VALUE_FLOAT_MASK); + if (tmp1 < 0) + /* convert positive value to supplyment */ + data = (AD7291_T_VALUE_SIGN << 1) - data; + + ret = ad7291_i2c_write(chip, bound_reg, data); + if (ret) + return -EIO; + + return ret; +} + +static ssize_t ad7291_show_t_sense_high(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + return ad7291_show_t_bound(dev, attr, + AD7291_T_SENSE_HIGH, buf); +} + +static inline ssize_t ad7291_set_t_sense_high(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + return ad7291_set_t_bound(dev, attr, + AD7291_T_SENSE_HIGH, buf, len); +} + +static ssize_t ad7291_show_t_sense_low(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + return ad7291_show_t_bound(dev, attr, + AD7291_T_SENSE_LOW, buf); +} + +static inline ssize_t ad7291_set_t_sense_low(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + return ad7291_set_t_bound(dev, attr, + AD7291_T_SENSE_LOW, buf, len); +} + +static ssize_t ad7291_show_t_sense_hyst(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + return ad7291_show_t_bound(dev, attr, + AD7291_T_SENSE_HYST, buf); +} + +static inline ssize_t ad7291_set_t_sense_hyst(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + return ad7291_set_t_bound(dev, attr, + AD7291_T_SENSE_HYST, buf, len); +} + +static inline ssize_t ad7291_show_v_bound(struct device *dev, + struct device_attribute *attr, + u8 bound_reg, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad7291_chip_info *chip = dev_info->dev_data; + u16 data; + int ret; + + if (bound_reg < AD7291_VOLTAGE_LIMIT_BASE || + bound_reg >= AD7291_VOLTAGE_LIMIT_BASE + + AD7291_VOLTAGE_LIMIT_COUNT) + return -EINVAL; + + ret = ad7291_i2c_read(chip, bound_reg, &data); + if (ret) + return -EIO; + + data &= AD7291_VALUE_MASK; + + return sprintf(buf, "%d\n", data); +} + +static inline ssize_t ad7291_set_v_bound(struct device *dev, + struct device_attribute *attr, + u8 bound_reg, + const char *buf, + size_t len) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad7291_chip_info *chip = dev_info->dev_data; + unsigned long value; + u16 data; + int ret; + + if (bound_reg < AD7291_VOLTAGE_LIMIT_BASE || + bound_reg >= AD7291_VOLTAGE_LIMIT_BASE + + AD7291_VOLTAGE_LIMIT_COUNT) + return -EINVAL; + + ret = strict_strtoul(buf, 10, &value); + + if (ret || value >= 4096) + return -EINVAL; + + data = (u16)value; + ret = ad7291_i2c_write(chip, bound_reg, data); + if (ret) + return -EIO; + + return ret; +} + +static int ad7291_get_voltage_limit_regs(const char *channel) +{ + int index; + + if (strlen(channel) < 3 && channel[0] != 'v') + return -EINVAL; + + index = channel[1] - '0'; + if (index >= AD7291_VOLTAGE_LIMIT_COUNT) + return -EINVAL; + + return index; +} + +static ssize_t ad7291_show_voltage_high(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + int regs; + + regs = ad7291_get_voltage_limit_regs(attr->attr.name); + + if (regs < 0) + return regs; + + return ad7291_show_t_bound(dev, attr, regs, buf); +} + +static inline ssize_t ad7291_set_voltage_high(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + int regs; + + regs = ad7291_get_voltage_limit_regs(attr->attr.name); + + if (regs < 0) + return regs; + + return ad7291_set_t_bound(dev, attr, regs, buf, len); +} + +static ssize_t ad7291_show_voltage_low(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + int regs; + + regs = ad7291_get_voltage_limit_regs(attr->attr.name); + + if (regs < 0) + return regs; + + return ad7291_show_t_bound(dev, attr, regs+1, buf); +} + +static inline ssize_t ad7291_set_voltage_low(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + int regs; + + regs = ad7291_get_voltage_limit_regs(attr->attr.name); + + if (regs < 0) + return regs; + + return ad7291_set_t_bound(dev, attr, regs+1, buf, len); +} + +static ssize_t ad7291_show_voltage_hyst(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + int regs; + + regs = ad7291_get_voltage_limit_regs(attr->attr.name); + + if (regs < 0) + return regs; + + return ad7291_show_t_bound(dev, attr, regs+2, buf); +} + +static inline ssize_t ad7291_set_voltage_hyst(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + int regs; + + regs = ad7291_get_voltage_limit_regs(attr->attr.name); + + if (regs < 0) + return regs; + + return ad7291_set_t_bound(dev, attr, regs+2, buf, len); +} + +IIO_EVENT_ATTR_SH(t_sense_high, iio_event_ad7291, + ad7291_show_t_sense_high, ad7291_set_t_sense_high, 0); +IIO_EVENT_ATTR_SH(t_sense_low, iio_event_ad7291, + ad7291_show_t_sense_low, ad7291_set_t_sense_low, 0); +IIO_EVENT_ATTR_SH(t_sense_hyst, iio_event_ad7291, + ad7291_show_t_sense_hyst, ad7291_set_t_sense_hyst, 0); + +IIO_EVENT_ATTR_SH(v0_high, iio_event_ad7291, + ad7291_show_voltage_high, ad7291_set_voltage_high, 0); +IIO_EVENT_ATTR_SH(v0_low, iio_event_ad7291, + ad7291_show_voltage_low, ad7291_set_voltage_low, 0); +IIO_EVENT_ATTR_SH(v0_hyst, iio_event_ad7291, + ad7291_show_voltage_hyst, ad7291_set_voltage_hyst, 0); +IIO_EVENT_ATTR_SH(v1_high, iio_event_ad7291, + ad7291_show_voltage_high, ad7291_set_voltage_high, 0); +IIO_EVENT_ATTR_SH(v1_low, iio_event_ad7291, + ad7291_show_voltage_low, ad7291_set_voltage_low, 0); +IIO_EVENT_ATTR_SH(v1_hyst, iio_event_ad7291, + ad7291_show_voltage_hyst, ad7291_set_voltage_hyst, 0); +IIO_EVENT_ATTR_SH(v2_high, iio_event_ad7291, + ad7291_show_voltage_high, ad7291_set_voltage_high, 0); +IIO_EVENT_ATTR_SH(v2_low, iio_event_ad7291, + ad7291_show_voltage_low, ad7291_set_voltage_low, 0); +IIO_EVENT_ATTR_SH(v2_hyst, iio_event_ad7291, + ad7291_show_voltage_hyst, ad7291_set_voltage_hyst, 0); +IIO_EVENT_ATTR_SH(v3_high, iio_event_ad7291, + ad7291_show_voltage_high, ad7291_set_voltage_high, 0); +IIO_EVENT_ATTR_SH(v3_low, iio_event_ad7291, + ad7291_show_voltage_low, ad7291_set_voltage_low, 0); +IIO_EVENT_ATTR_SH(v3_hyst, iio_event_ad7291, + ad7291_show_voltage_hyst, ad7291_set_voltage_hyst, 0); +IIO_EVENT_ATTR_SH(v4_high, iio_event_ad7291, + ad7291_show_voltage_high, ad7291_set_voltage_high, 0); +IIO_EVENT_ATTR_SH(v4_low, iio_event_ad7291, + ad7291_show_voltage_low, ad7291_set_voltage_low, 0); +IIO_EVENT_ATTR_SH(v4_hyst, iio_event_ad7291, + ad7291_show_voltage_hyst, ad7291_set_voltage_hyst, 0); +IIO_EVENT_ATTR_SH(v5_high, iio_event_ad7291, + ad7291_show_voltage_high, ad7291_set_voltage_high, 0); +IIO_EVENT_ATTR_SH(v5_low, iio_event_ad7291, + ad7291_show_voltage_low, ad7291_set_voltage_low, 0); +IIO_EVENT_ATTR_SH(v5_hyst, iio_event_ad7291, + ad7291_show_voltage_hyst, ad7291_set_voltage_hyst, 0); +IIO_EVENT_ATTR_SH(v6_high, iio_event_ad7291, + ad7291_show_voltage_high, ad7291_set_voltage_high, 0); +IIO_EVENT_ATTR_SH(v6_low, iio_event_ad7291, + ad7291_show_voltage_low, ad7291_set_voltage_low, 0); +IIO_EVENT_ATTR_SH(v6_hyst, iio_event_ad7291, + ad7291_show_voltage_hyst, ad7291_set_voltage_hyst, 0); +IIO_EVENT_ATTR_SH(v7_high, iio_event_ad7291, + ad7291_show_voltage_high, ad7291_set_voltage_high, 0); +IIO_EVENT_ATTR_SH(v7_low, iio_event_ad7291, + ad7291_show_voltage_low, ad7291_set_voltage_low, 0); +IIO_EVENT_ATTR_SH(v7_hyst, iio_event_ad7291, + ad7291_show_voltage_hyst, ad7291_set_voltage_hyst, 0); + +static struct attribute *ad7291_event_attributes[] = { + &iio_event_attr_t_sense_high.dev_attr.attr, + &iio_event_attr_t_sense_low.dev_attr.attr, + &iio_event_attr_t_sense_hyst.dev_attr.attr, + &iio_event_attr_v0_high.dev_attr.attr, + &iio_event_attr_v0_low.dev_attr.attr, + &iio_event_attr_v0_hyst.dev_attr.attr, + &iio_event_attr_v1_high.dev_attr.attr, + &iio_event_attr_v1_low.dev_attr.attr, + &iio_event_attr_v1_hyst.dev_attr.attr, + &iio_event_attr_v2_high.dev_attr.attr, + &iio_event_attr_v2_low.dev_attr.attr, + &iio_event_attr_v2_hyst.dev_attr.attr, + &iio_event_attr_v3_high.dev_attr.attr, + &iio_event_attr_v3_low.dev_attr.attr, + &iio_event_attr_v3_hyst.dev_attr.attr, + &iio_event_attr_v4_high.dev_attr.attr, + &iio_event_attr_v4_low.dev_attr.attr, + &iio_event_attr_v4_hyst.dev_attr.attr, + &iio_event_attr_v5_high.dev_attr.attr, + &iio_event_attr_v5_low.dev_attr.attr, + &iio_event_attr_v5_hyst.dev_attr.attr, + &iio_event_attr_v6_high.dev_attr.attr, + &iio_event_attr_v6_low.dev_attr.attr, + &iio_event_attr_v6_hyst.dev_attr.attr, + &iio_event_attr_v7_high.dev_attr.attr, + &iio_event_attr_v7_low.dev_attr.attr, + &iio_event_attr_v7_hyst.dev_attr.attr, + NULL, +}; + +static struct attribute_group ad7291_event_attribute_group = { + .attrs = ad7291_event_attributes, +}; + +/* + * device probe and remove + */ + +static int __devinit ad7291_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct ad7291_chip_info *chip; + int ret = 0; + + chip = kzalloc(sizeof(struct ad7291_chip_info), GFP_KERNEL); + + if (chip == NULL) + return -ENOMEM; + + /* this is only used for device removal purposes */ + i2c_set_clientdata(client, chip); + + chip->client = client; + chip->name = id->name; + chip->command = AD7291_NOISE_DELAY | AD7291_T_SENSE_MASK; + + chip->indio_dev = iio_allocate_device(); + if (chip->indio_dev == NULL) { + ret = -ENOMEM; + goto error_free_chip; + } + + chip->indio_dev->dev.parent = &client->dev; + chip->indio_dev->attrs = &ad7291_attribute_group; + chip->indio_dev->event_attrs = &ad7291_event_attribute_group; + chip->indio_dev->dev_data = (void *)chip; + chip->indio_dev->driver_module = THIS_MODULE; + chip->indio_dev->num_interrupt_lines = 1; + chip->indio_dev->modes = INDIO_DIRECT_MODE; + + ret = iio_device_register(chip->indio_dev); + if (ret) + goto error_free_dev; + + if (client->irq > 0) { + ret = iio_register_interrupt_line(client->irq, + chip->indio_dev, + 0, + IRQF_TRIGGER_LOW, + chip->name); + if (ret) + goto error_unreg_dev; + + /* + * The event handler list element refer to iio_event_ad7291. + * All event attributes bind to the same event handler. + * So, only register event handler once. + */ + iio_add_event_to_list(&iio_event_ad7291, + &chip->indio_dev->interrupts[0]->ev_list); + + INIT_WORK(&chip->thresh_work, ad7291_interrupt_bh); + + /* set irq polarity low level */ + chip->command |= AD7291_ALART_POLARITY; + } + + ret = ad7291_i2c_write(chip, AD7291_COMMAND, chip->command); + if (ret) { + ret = -EIO; + goto error_unreg_irq; + } + + dev_info(&client->dev, "%s temperature sensor registered.\n", + id->name); + + return 0; + +error_unreg_irq: + iio_unregister_interrupt_line(chip->indio_dev, 0); +error_unreg_dev: + iio_device_unregister(chip->indio_dev); +error_free_dev: + iio_free_device(chip->indio_dev); +error_free_chip: + kfree(chip); + + return ret; +} + +static int __devexit ad7291_remove(struct i2c_client *client) +{ + struct ad7291_chip_info *chip = i2c_get_clientdata(client); + struct iio_dev *indio_dev = chip->indio_dev; + + if (client->irq) + iio_unregister_interrupt_line(indio_dev, 0); + iio_device_unregister(indio_dev); + iio_free_device(chip->indio_dev); + kfree(chip); + + return 0; +} + +static const struct i2c_device_id ad7291_id[] = { + { "ad7291", 0 }, + {} +}; + +MODULE_DEVICE_TABLE(i2c, ad7291_id); + +static struct i2c_driver ad7291_driver = { + .driver = { + .name = "ad7291", + }, + .probe = ad7291_probe, + .remove = __devexit_p(ad7291_remove), + .id_table = ad7291_id, +}; + +static __init int ad7291_init(void) +{ + return i2c_add_driver(&ad7291_driver); +} + +static __exit void ad7291_exit(void) +{ + i2c_del_driver(&ad7291_driver); +} + +MODULE_AUTHOR("Sonic Zhang "); +MODULE_DESCRIPTION("Analog Devices AD7291 digital" + " temperature sensor driver"); +MODULE_LICENSE("GPL v2"); + +module_init(ad7291_init); +module_exit(ad7291_exit); -- cgit v1.2.3 From e8ada962bc2e34e964d370f721994387df7b1363 Mon Sep 17 00:00:00 2001 From: Sonic Zhang Date: Wed, 27 Oct 2010 21:43:56 -0400 Subject: staging: iio: adc: new driver for AD7298 devices Signed-off-by: Sonic Zhang Signed-off-by: Michael Hennerich Acked-by: Jonathan Cameron Signed-off-by: Mike Frysinger Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/adc/Kconfig | 7 + drivers/staging/iio/adc/Makefile | 1 + drivers/staging/iio/adc/ad7298.c | 501 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 509 insertions(+) create mode 100644 drivers/staging/iio/adc/ad7298.c diff --git a/drivers/staging/iio/adc/Kconfig b/drivers/staging/iio/adc/Kconfig index fa78413f3fae..e6bc7faf2d28 100644 --- a/drivers/staging/iio/adc/Kconfig +++ b/drivers/staging/iio/adc/Kconfig @@ -48,6 +48,13 @@ config AD7291 Say yes here to build support for Analog Devices AD7291 temperature sensors. +config AD7298 + tristate "Analog Devices AD7298 temperature sensor and ADC driver" + depends on SPI + help + Say yes here to build support for Analog Devices AD7298 + temperature sensors and ADC. + config AD799X tristate "Analog Devices AD799x ADC driver" depends on I2C diff --git a/drivers/staging/iio/adc/Makefile b/drivers/staging/iio/adc/Makefile index 5e99a863203a..6c036323c3b7 100644 --- a/drivers/staging/iio/adc/Makefile +++ b/drivers/staging/iio/adc/Makefile @@ -18,3 +18,4 @@ obj-$(CONFIG_AD7476) += ad7476.o obj-$(CONFIG_AD7150) += ad7150.o obj-$(CONFIG_AD7152) += ad7152.o obj-$(CONFIG_AD7291) += ad7291.o +obj-$(CONFIG_AD7298) += ad7298.o diff --git a/drivers/staging/iio/adc/ad7298.c b/drivers/staging/iio/adc/ad7298.c new file mode 100644 index 000000000000..1a080c977637 --- /dev/null +++ b/drivers/staging/iio/adc/ad7298.c @@ -0,0 +1,501 @@ +/* + * AD7298 digital temperature sensor driver supporting AD7298 + * + * Copyright 2010 Analog Devices Inc. + * + * Licensed under the GPL-2 or later. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../iio.h" +#include "../sysfs.h" + +/* + * AD7298 command + */ +#define AD7298_PD 0x1 +#define AD7298_T_AVG_MASK 0x2 +#define AD7298_EXT_REF 0x4 +#define AD7298_T_SENSE_MASK 0x20 +#define AD7298_VOLTAGE_MASK 0x3fc0 +#define AD7298_VOLTAGE_OFFSET 0x6 +#define AD7298_VOLTAGE_LIMIT_COUNT 8 +#define AD7298_REPEAT 0x40 +#define AD7298_WRITE 0x80 + +/* + * AD7298 value masks + */ +#define AD7298_CHANNEL_MASK 0xf000 +#define AD7298_VALUE_MASK 0xfff +#define AD7298_T_VALUE_SIGN 0x400 +#define AD7298_T_VALUE_FLOAT_OFFSET 2 +#define AD7298_T_VALUE_FLOAT_MASK 0x2 + +/* + * struct ad7298_chip_info - chip specifc information + */ + +struct ad7298_chip_info { + const char *name; + struct spi_device *spi_dev; + struct iio_dev *indio_dev; + u16 command; + u16 busy_pin; + u8 channels; /* Active voltage channels */ +}; + +/* + * ad7298 register access by SPI + */ +static int ad7298_spi_write(struct ad7298_chip_info *chip, u16 data) +{ + struct spi_device *spi_dev = chip->spi_dev; + int ret = 0; + + data |= AD7298_WRITE; + data = cpu_to_be16(data); + ret = spi_write(spi_dev, (u8 *)&data, sizeof(data)); + if (ret < 0) + dev_err(&spi_dev->dev, "SPI write error\n"); + + return ret; +} + +static int ad7298_spi_read(struct ad7298_chip_info *chip, u16 mask, u16 *data) +{ + struct spi_device *spi_dev = chip->spi_dev; + int ret = 0; + u8 count = chip->channels; + u16 command; + int i; + + if (mask & AD7298_T_SENSE_MASK) { + command = chip->command & ~(AD7298_T_AVG_MASK | AD7298_VOLTAGE_MASK); + command |= AD7298_T_SENSE_MASK; + count = 1; + } else if (mask & AD7298_T_AVG_MASK) { + command = chip->command & ~AD7298_VOLTAGE_MASK; + command |= AD7298_T_SENSE_MASK | AD7298_T_AVG_MASK; + count = 2; + } else if (mask & AD7298_VOLTAGE_MASK) { + command = chip->command & ~(AD7298_T_AVG_MASK | AD7298_T_SENSE_MASK); + count = chip->channels; + } + + ret = ad7298_spi_write(chip, chip->command); + if (ret < 0) { + dev_err(&spi_dev->dev, "SPI write command error\n"); + return ret; + } + + ret = spi_read(spi_dev, (u8 *)&command, sizeof(command)); + if (ret < 0) { + dev_err(&spi_dev->dev, "SPI read error\n"); + return ret; + } + + i = 10000; + while (i && gpio_get_value(chip->busy_pin)) { + cpu_relax(); + i--; + } + if (!i) { + dev_err(&spi_dev->dev, "Always in busy convertion.\n"); + return -EBUSY; + } + + for (i = 0; i < count; i++) { + ret = spi_read(spi_dev, (u8 *)&data[i], sizeof(data[i])); + if (ret < 0) { + dev_err(&spi_dev->dev, "SPI read error\n"); + return ret; + } + *data = be16_to_cpu(data[i]); + } + + return 0; +} + +static ssize_t ad7298_show_mode(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad7298_chip_info *chip = dev_info->dev_data; + + if (chip->command & AD7298_REPEAT) + return sprintf(buf, "repeat\n"); + else + return sprintf(buf, "normal\n"); +} + +static ssize_t ad7298_store_mode(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad7298_chip_info *chip = dev_info->dev_data; + + if (strcmp(buf, "repeat")) + chip->command |= AD7298_REPEAT; + else + chip->command &= (~AD7298_REPEAT); + + return 1; +} + +static IIO_DEVICE_ATTR(mode, S_IRUGO | S_IWUSR, + ad7298_show_mode, + ad7298_store_mode, + 0); + +static ssize_t ad7298_show_available_modes(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + return sprintf(buf, "normal\nrepeat\n"); +} + +static IIO_DEVICE_ATTR(available_modes, S_IRUGO, ad7298_show_available_modes, NULL, 0); + +static ssize_t ad7298_store_reset(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad7298_chip_info *chip = dev_info->dev_data; + u16 command; + int ret; + + command = chip->command & ~AD7298_PD; + + ret = ad7298_spi_write(chip, command); + if (ret) + return -EIO; + + command = chip->command | AD7298_PD; + + ret = ad7298_spi_write(chip, command); + if (ret) + return -EIO; + + return len; +} + +static IIO_DEVICE_ATTR(reset, S_IWUSR, + NULL, + ad7298_store_reset, + 0); + +static ssize_t ad7298_show_ext_ref(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad7298_chip_info *chip = dev_info->dev_data; + + return sprintf(buf, "%d\n", !!(chip->command & AD7298_EXT_REF)); +} + +static ssize_t ad7298_store_ext_ref(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad7298_chip_info *chip = dev_info->dev_data; + u16 command; + int ret; + + command = chip->command & (~AD7298_EXT_REF); + if (strcmp(buf, "1")) + command |= AD7298_EXT_REF; + + ret = ad7298_spi_write(chip, command); + if (ret) + return -EIO; + + chip->command = command; + + return len; +} + +static IIO_DEVICE_ATTR(ext_ref, S_IRUGO | S_IWUSR, + ad7298_show_ext_ref, + ad7298_store_ext_ref, + 0); + +static ssize_t ad7298_show_t_sense(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad7298_chip_info *chip = dev_info->dev_data; + u16 data; + char sign = ' '; + int ret; + + ret = ad7298_spi_read(chip, AD7298_T_SENSE_MASK, &data); + if (ret) + return -EIO; + + if (data & AD7298_T_VALUE_SIGN) { + /* convert supplement to positive value */ + data = (AD7298_T_VALUE_SIGN << 1) - data; + sign = '-'; + } + + return sprintf(buf, "%c%d.%.2d\n", sign, + (data >> AD7298_T_VALUE_FLOAT_OFFSET), + (data & AD7298_T_VALUE_FLOAT_MASK) * 25); +} + +static IIO_DEVICE_ATTR(t_sense, S_IRUGO, ad7298_show_t_sense, NULL, 0); + +static ssize_t ad7298_show_t_average(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad7298_chip_info *chip = dev_info->dev_data; + u16 data[2]; + char sign = ' '; + int ret; + + ret = ad7298_spi_read(chip, AD7298_T_AVG_MASK, data); + if (ret) + return -EIO; + + if (data[1] & AD7298_T_VALUE_SIGN) { + /* convert supplement to positive value */ + data[1] = (AD7298_T_VALUE_SIGN << 1) - data[1]; + sign = '-'; + } + + return sprintf(buf, "%c%d.%.2d\n", sign, + (data[1] >> AD7298_T_VALUE_FLOAT_OFFSET), + (data[1] & AD7298_T_VALUE_FLOAT_MASK) * 25); +} + +static IIO_DEVICE_ATTR(t_average, S_IRUGO, ad7298_show_t_average, NULL, 0); + +static ssize_t ad7298_show_voltage(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad7298_chip_info *chip = dev_info->dev_data; + u16 data[AD7298_VOLTAGE_LIMIT_COUNT]; + int i, size, ret; + + ret = ad7298_spi_read(chip, AD7298_VOLTAGE_MASK, data); + if (ret) + return -EIO; + + for (i = 0; i < AD7298_VOLTAGE_LIMIT_COUNT; i++) { + if (chip->command & (AD7298_T_SENSE_MASK << i)) { + ret = sprintf(buf, "channel[%d]=%d\n", i, + data[i] & AD7298_VALUE_MASK); + if (ret < 0) + break; + buf += ret; + size += ret; + } + } + + return size; +} + +static IIO_DEVICE_ATTR(voltage, S_IRUGO, ad7298_show_voltage, NULL, 0); + +static ssize_t ad7298_show_channel_mask(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad7298_chip_info *chip = dev_info->dev_data; + + return sprintf(buf, "0x%x\n", (chip->command & AD7298_VOLTAGE_MASK) >> + AD7298_VOLTAGE_OFFSET); +} + +static ssize_t ad7298_store_channel_mask(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad7298_chip_info *chip = dev_info->dev_data; + unsigned long data; + int i, ret; + + ret = strict_strtoul(buf, 16, &data); + if (ret || data > 0xff) + return -EINVAL; + + chip->command &= (~AD7298_VOLTAGE_MASK); + chip->command |= data << AD7298_VOLTAGE_OFFSET; + + for (i = 0, chip->channels = 0; i < AD7298_VOLTAGE_LIMIT_COUNT; i++) { + if (chip->command & (AD7298_T_SENSE_MASK << i)) + chip->channels++; + } + + return ret; +} + +static IIO_DEVICE_ATTR(channel_mask, S_IRUGO | S_IWUSR, + ad7298_show_channel_mask, + ad7298_store_channel_mask, + 0); + +static ssize_t ad7298_show_name(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad7298_chip_info *chip = dev_info->dev_data; + return sprintf(buf, "%s\n", chip->name); +} + +static IIO_DEVICE_ATTR(name, S_IRUGO, ad7298_show_name, NULL, 0); + +static struct attribute *ad7298_attributes[] = { + &iio_dev_attr_available_modes.dev_attr.attr, + &iio_dev_attr_mode.dev_attr.attr, + &iio_dev_attr_reset.dev_attr.attr, + &iio_dev_attr_ext_ref.dev_attr.attr, + &iio_dev_attr_t_sense.dev_attr.attr, + &iio_dev_attr_t_average.dev_attr.attr, + &iio_dev_attr_voltage.dev_attr.attr, + &iio_dev_attr_channel_mask.dev_attr.attr, + &iio_dev_attr_name.dev_attr.attr, + NULL, +}; + +static const struct attribute_group ad7298_attribute_group = { + .attrs = ad7298_attributes, +}; + +/* + * device probe and remove + */ +static int __devinit ad7298_probe(struct spi_device *spi_dev) +{ + struct ad7298_chip_info *chip; + unsigned short *pins = spi_dev->dev.platform_data; + int ret = 0; + + chip = kzalloc(sizeof(struct ad7298_chip_info), GFP_KERNEL); + + if (chip == NULL) + return -ENOMEM; + + /* this is only used for device removal purposes */ + dev_set_drvdata(&spi_dev->dev, chip); + + chip->spi_dev = spi_dev; + chip->name = spi_dev->modalias; + chip->busy_pin = pins[0]; + + ret = gpio_request(chip->busy_pin, chip->name); + if (ret) { + dev_err(&spi_dev->dev, "Fail to request busy gpio PIN %d.\n", + chip->busy_pin); + goto error_free_chip; + } + gpio_direction_input(chip->busy_pin); + + chip->indio_dev = iio_allocate_device(); + if (chip->indio_dev == NULL) { + ret = -ENOMEM; + goto error_free_gpio; + } + + chip->indio_dev->dev.parent = &spi_dev->dev; + chip->indio_dev->attrs = &ad7298_attribute_group; + chip->indio_dev->dev_data = (void *)chip; + chip->indio_dev->driver_module = THIS_MODULE; + chip->indio_dev->modes = INDIO_DIRECT_MODE; + + ret = iio_device_register(chip->indio_dev); + if (ret) + goto error_free_dev; + + dev_info(&spi_dev->dev, "%s temperature sensor and ADC registered.\n", + chip->name); + + return 0; + +error_free_dev: + iio_free_device(chip->indio_dev); +error_free_gpio: + gpio_free(chip->busy_pin); +error_free_chip: + kfree(chip); + + return ret; +} + +static int __devexit ad7298_remove(struct spi_device *spi_dev) +{ + struct ad7298_chip_info *chip = dev_get_drvdata(&spi_dev->dev); + struct iio_dev *indio_dev = chip->indio_dev; + + dev_set_drvdata(&spi_dev->dev, NULL); + iio_device_unregister(indio_dev); + iio_free_device(chip->indio_dev); + gpio_free(chip->busy_pin); + kfree(chip); + + return 0; +} + +static const struct spi_device_id ad7298_id[] = { + { "ad7298", 0 }, + {} +}; + +MODULE_DEVICE_TABLE(spi, ad7298_id); + +static struct spi_driver ad7298_driver = { + .driver = { + .name = "ad7298", + .bus = &spi_bus_type, + .owner = THIS_MODULE, + }, + .probe = ad7298_probe, + .remove = __devexit_p(ad7298_remove), + .id_table = ad7298_id, +}; + +static __init int ad7298_init(void) +{ + return spi_register_driver(&ad7298_driver); +} + +static __exit void ad7298_exit(void) +{ + spi_unregister_driver(&ad7298_driver); +} + +MODULE_AUTHOR("Sonic Zhang "); +MODULE_DESCRIPTION("Analog Devices AD7298 digital" + " temperature sensor and ADC driver"); +MODULE_LICENSE("GPL v2"); + +module_init(ad7298_init); +module_exit(ad7298_exit); -- cgit v1.2.3 From f84c26e61eedaa9eb21fe8a238d38fffb8d3c394 Mon Sep 17 00:00:00 2001 From: Sonic Zhang Date: Wed, 27 Oct 2010 21:43:57 -0400 Subject: staging: iio: adc: new driver for AD7314 devices Signed-off-by: Sonic Zhang Signed-off-by: Michael Hennerich Acked-by: Jonathan Cameron Signed-off-by: Mike Frysinger Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/adc/Kconfig | 7 + drivers/staging/iio/adc/Makefile | 1 + drivers/staging/iio/adc/ad7314.c | 308 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 316 insertions(+) create mode 100644 drivers/staging/iio/adc/ad7314.c diff --git a/drivers/staging/iio/adc/Kconfig b/drivers/staging/iio/adc/Kconfig index e6bc7faf2d28..4e7b6a84e84a 100644 --- a/drivers/staging/iio/adc/Kconfig +++ b/drivers/staging/iio/adc/Kconfig @@ -55,6 +55,13 @@ config AD7298 Say yes here to build support for Analog Devices AD7298 temperature sensors and ADC. +config AD7314 + tristate "Analog Devices AD7314 temperature sensor driver" + depends on SPI + help + Say yes here to build support for Analog Devices AD7314 + temperature sensors. + config AD799X tristate "Analog Devices AD799x ADC driver" depends on I2C diff --git a/drivers/staging/iio/adc/Makefile b/drivers/staging/iio/adc/Makefile index 6c036323c3b7..36e66f93d6f9 100644 --- a/drivers/staging/iio/adc/Makefile +++ b/drivers/staging/iio/adc/Makefile @@ -19,3 +19,4 @@ obj-$(CONFIG_AD7150) += ad7150.o obj-$(CONFIG_AD7152) += ad7152.o obj-$(CONFIG_AD7291) += ad7291.o obj-$(CONFIG_AD7298) += ad7298.o +obj-$(CONFIG_AD7314) += ad7314.o diff --git a/drivers/staging/iio/adc/ad7314.c b/drivers/staging/iio/adc/ad7314.c new file mode 100644 index 000000000000..8c17b1fe9026 --- /dev/null +++ b/drivers/staging/iio/adc/ad7314.c @@ -0,0 +1,308 @@ +/* + * AD7314 digital temperature sensor driver for AD7314, ADT7301 and ADT7302 + * + * Copyright 2010 Analog Devices Inc. + * + * Licensed under the GPL-2 or later. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../iio.h" +#include "../sysfs.h" + +/* + * AD7314 power mode + */ +#define AD7314_PD 0x2000 + +/* + * AD7314 temperature masks + */ +#define AD7314_TEMP_SIGN 0x200 +#define AD7314_TEMP_MASK 0x7FE0 +#define AD7314_TEMP_OFFSET 5 +#define AD7314_TEMP_FLOAT_OFFSET 2 +#define AD7314_TEMP_FLOAT_MASK 0x3 + +/* + * ADT7301 and ADT7302 temperature masks + */ +#define ADT7301_TEMP_SIGN 0x2000 +#define ADT7301_TEMP_MASK 0x2FFF +#define ADT7301_TEMP_FLOAT_OFFSET 5 +#define ADT7301_TEMP_FLOAT_MASK 0x1F + +/* + * struct ad7314_chip_info - chip specifc information + */ + +struct ad7314_chip_info { + const char *name; + struct spi_device *spi_dev; + struct iio_dev *indio_dev; + s64 last_timestamp; + u8 mode; +}; + +/* + * ad7314 register access by SPI + */ + +static int ad7314_spi_read(struct ad7314_chip_info *chip, u16 *data) +{ + struct spi_device *spi_dev = chip->spi_dev; + int ret = 0; + u16 value; + + ret = spi_read(spi_dev, (u8 *)&value, sizeof(value)); + if (ret < 0) { + dev_err(&spi_dev->dev, "SPI read error\n"); + return ret; + } + + *data = be16_to_cpu((u16)value); + + return ret; +} + +static int ad7314_spi_write(struct ad7314_chip_info *chip, u16 data) +{ + struct spi_device *spi_dev = chip->spi_dev; + int ret = 0; + u16 value = cpu_to_be16(data); + + ret = spi_write(spi_dev, (u8 *)&value, sizeof(value)); + if (ret < 0) + dev_err(&spi_dev->dev, "SPI write error\n"); + + return ret; +} + +static ssize_t ad7314_show_mode(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad7314_chip_info *chip = dev_info->dev_data; + + if (chip->mode) + return sprintf(buf, "power-save\n"); + else + return sprintf(buf, "full\n"); +} + +static ssize_t ad7314_store_mode(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad7314_chip_info *chip = dev_info->dev_data; + u16 mode = 0; + int ret; + + if (!strcmp(buf, "full")) + mode = AD7314_PD; + + ret = ad7314_spi_write(chip, mode); + if (ret) + return -EIO; + + chip->mode = mode; + + return len; +} + +static IIO_DEVICE_ATTR(mode, S_IRUGO | S_IWUSR, + ad7314_show_mode, + ad7314_store_mode, + 0); + +static ssize_t ad7314_show_available_modes(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + return sprintf(buf, "full\npower-save\n"); +} + +static IIO_DEVICE_ATTR(available_modes, S_IRUGO, ad7314_show_available_modes, NULL, 0); + +static ssize_t ad7314_show_temperature(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad7314_chip_info *chip = dev_info->dev_data; + u16 data; + char sign = ' '; + int ret; + + if (chip->mode) { + ret = ad7314_spi_write(chip, 0); + if (ret) + return -EIO; + } + + ret = ad7314_spi_read(chip, &data); + if (ret) + return -EIO; + + if (chip->mode) + ad7314_spi_write(chip, chip->mode); + + if (strcmp(chip->name, "ad7314")) { + data = (data & AD7314_TEMP_MASK) >> + AD7314_TEMP_OFFSET; + if (data & AD7314_TEMP_SIGN) { + data = (AD7314_TEMP_SIGN << 1) - data; + sign = '-'; + } + + return sprintf(buf, "%c%d.%.2d\n", sign, + data >> AD7314_TEMP_FLOAT_OFFSET, + (data & AD7314_TEMP_FLOAT_MASK) * 25); + } else { + data &= ADT7301_TEMP_MASK; + if (data & ADT7301_TEMP_SIGN) { + data = (ADT7301_TEMP_SIGN << 1) - data; + sign = '-'; + } + + return sprintf(buf, "%c%d.%.5d\n", sign, + data >> ADT7301_TEMP_FLOAT_OFFSET, + (data & ADT7301_TEMP_FLOAT_MASK) * 3125); + } +} + +static IIO_DEVICE_ATTR(temperature, S_IRUGO, ad7314_show_temperature, NULL, 0); + +static ssize_t ad7314_show_name(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad7314_chip_info *chip = dev_info->dev_data; + return sprintf(buf, "%s\n", chip->name); +} + +static IIO_DEVICE_ATTR(name, S_IRUGO, ad7314_show_name, NULL, 0); + +static struct attribute *ad7314_attributes[] = { + &iio_dev_attr_available_modes.dev_attr.attr, + &iio_dev_attr_mode.dev_attr.attr, + &iio_dev_attr_temperature.dev_attr.attr, + &iio_dev_attr_name.dev_attr.attr, + NULL, +}; + +static const struct attribute_group ad7314_attribute_group = { + .attrs = ad7314_attributes, +}; + +/* + * device probe and remove + */ + +static int __devinit ad7314_probe(struct spi_device *spi_dev) +{ + struct ad7314_chip_info *chip; + int ret = 0; + + chip = kzalloc(sizeof(struct ad7314_chip_info), GFP_KERNEL); + + if (chip == NULL) + return -ENOMEM; + + /* this is only used for device removal purposes */ + dev_set_drvdata(&spi_dev->dev, chip); + + chip->spi_dev = spi_dev; + chip->name = spi_dev->modalias; + + chip->indio_dev = iio_allocate_device(); + if (chip->indio_dev == NULL) { + ret = -ENOMEM; + goto error_free_chip; + } + + chip->indio_dev->dev.parent = &spi_dev->dev; + chip->indio_dev->attrs = &ad7314_attribute_group; + chip->indio_dev->dev_data = (void *)chip; + chip->indio_dev->driver_module = THIS_MODULE; + + ret = iio_device_register(chip->indio_dev); + if (ret) + goto error_free_dev; + + dev_info(&spi_dev->dev, "%s temperature sensor registered.\n", + chip->name); + + return 0; +error_free_dev: + iio_free_device(chip->indio_dev); +error_free_chip: + kfree(chip); + + return ret; +} + +static int __devexit ad7314_remove(struct spi_device *spi_dev) +{ + struct ad7314_chip_info *chip = dev_get_drvdata(&spi_dev->dev); + struct iio_dev *indio_dev = chip->indio_dev; + + dev_set_drvdata(&spi_dev->dev, NULL); + if (spi_dev->irq) + iio_unregister_interrupt_line(indio_dev, 0); + iio_device_unregister(indio_dev); + iio_free_device(chip->indio_dev); + kfree(chip); + + return 0; +} + +static const struct spi_device_id ad7314_id[] = { + { "adt7301", 0 }, + { "adt7302", 0 }, + { "ad7314", 0 }, + {} +}; + +static struct spi_driver ad7314_driver = { + .driver = { + .name = "ad7314", + .bus = &spi_bus_type, + .owner = THIS_MODULE, + }, + .probe = ad7314_probe, + .remove = __devexit_p(ad7314_remove), + .id_table = ad7314_id, +}; + +static __init int ad7314_init(void) +{ + return spi_register_driver(&ad7314_driver); +} + +static __exit void ad7314_exit(void) +{ + spi_unregister_driver(&ad7314_driver); +} + +MODULE_AUTHOR("Sonic Zhang "); +MODULE_DESCRIPTION("Analog Devices AD7314, ADT7301 and ADT7302 digital" + " temperature sensor driver"); +MODULE_LICENSE("GPL v2"); + +module_init(ad7314_init); +module_exit(ad7314_exit); -- cgit v1.2.3 From 671d85f2aa3dadc6e221b6f6f7e087bf487275e7 Mon Sep 17 00:00:00 2001 From: Barry Song Date: Wed, 27 Oct 2010 21:43:58 -0400 Subject: staging: iio: adc: new driver for AD7745/6/7 devices Signed-off-by: Barry Song Signed-off-by: Michael Hennerich Acked-by: Jonathan Cameron Signed-off-by: Mike Frysinger Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/adc/Kconfig | 14 +- drivers/staging/iio/adc/Makefile | 1 + drivers/staging/iio/adc/ad7745.c | 734 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 747 insertions(+), 2 deletions(-) create mode 100644 drivers/staging/iio/adc/ad7745.c diff --git a/drivers/staging/iio/adc/Kconfig b/drivers/staging/iio/adc/Kconfig index 4e7b6a84e84a..34c6822ae070 100644 --- a/drivers/staging/iio/adc/Kconfig +++ b/drivers/staging/iio/adc/Kconfig @@ -85,9 +85,9 @@ config AD799X_RING_BUFFER config AD7476 tristate "Analog Devices AD7475/6/7/8 AD7466/7/8 and AD7495 ADC driver" depends on SPI - select IIO_RING_BUFFER + select IIO_RING_BUFFER select IIO_SW_RING - select IIO_TRIGGER + select IIO_TRIGGER help Say yes here to build support for Analog Devices AD7475, AD7476, AD7477, AD7478, AD7466, AD7467, AD7468, AD7495 @@ -96,3 +96,13 @@ config AD7476 To compile this driver as a module, choose M here: the module will be called ad7476. + +config AD7745 + tristate "Analog Devices AD7745, AD7746 AD7747 capacitive sensor driver" + depends on I2C + help + Say yes here to build support for Analog Devices capacitive sensors. + (AD7745, AD7746, AD7747) Provides direct access via sysfs. + + To compile this driver as a module, choose M here: the + module will be called ad7745. diff --git a/drivers/staging/iio/adc/Makefile b/drivers/staging/iio/adc/Makefile index 36e66f93d6f9..ac83bad5125a 100644 --- a/drivers/staging/iio/adc/Makefile +++ b/drivers/staging/iio/adc/Makefile @@ -20,3 +20,4 @@ obj-$(CONFIG_AD7152) += ad7152.o obj-$(CONFIG_AD7291) += ad7291.o obj-$(CONFIG_AD7298) += ad7298.o obj-$(CONFIG_AD7314) += ad7314.o +obj-$(CONFIG_AD7745) += ad7745.o diff --git a/drivers/staging/iio/adc/ad7745.c b/drivers/staging/iio/adc/ad7745.c new file mode 100644 index 000000000000..ab7ef8450ae2 --- /dev/null +++ b/drivers/staging/iio/adc/ad7745.c @@ -0,0 +1,734 @@ +/* + * AD774X capacitive sensor driver supporting AD7745/6/7 + * + * Copyright 2010 Analog Devices Inc. + * + * Licensed under the GPL-2 or later. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../iio.h" +#include "../sysfs.h" + +/* + * AD774X registers definition + */ + +#define AD774X_STATUS 0 +#define AD774X_STATUS_RDY (1 << 2) +#define AD774X_STATUS_RDYVT (1 << 1) +#define AD774X_STATUS_RDYCAP (1 << 0) +#define AD774X_CAP_DATA_HIGH 1 +#define AD774X_CAP_DATA_MID 2 +#define AD774X_CAP_DATA_LOW 3 +#define AD774X_VT_DATA_HIGH 4 +#define AD774X_VT_DATA_MID 5 +#define AD774X_VT_DATA_LOW 6 +#define AD774X_CAP_SETUP 7 +#define AD774X_VT_SETUP 8 +#define AD774X_EXEC_SETUP 9 +#define AD774X_CFG 10 +#define AD774X_CAPDACA 11 +#define AD774X_CAPDACB 12 +#define AD774X_CAPDAC_EN (1 << 7) +#define AD774X_CAP_OFFH 13 +#define AD774X_CAP_OFFL 14 +#define AD774X_CAP_GAINH 15 +#define AD774X_CAP_GAINL 16 +#define AD774X_VOLT_GAINH 17 +#define AD774X_VOLT_GAINL 18 + +#define AD774X_MAX_CONV_MODE 6 + +/* + * struct ad774x_chip_info - chip specifc information + */ + +struct ad774x_chip_info { + const char *name; + struct i2c_client *client; + struct iio_dev *indio_dev; + struct work_struct thresh_work; + bool inter; + s64 last_timestamp; + u16 cap_offs; /* Capacitive offset */ + u16 cap_gain; /* Capacitive gain calibration */ + u16 volt_gain; /* Voltage gain calibration */ + u8 cap_setup; + u8 vt_setup; + u8 exec_setup; + + char *conversion_mode; +}; + +struct ad774x_conversion_mode { + char *name; + u8 reg_cfg; +}; + +struct ad774x_conversion_mode ad774x_conv_mode_table[AD774X_MAX_CONV_MODE] = { + { "idle", 0 }, + { "continuous-conversion", 1 }, + { "single-conversion", 2 }, + { "power-down", 3 }, + { "offset-calibration", 5 }, + { "gain-calibration", 6 }, +}; + +/* + * ad774x register access by I2C + */ + +static int ad774x_i2c_read(struct ad774x_chip_info *chip, u8 reg, u8 *data, int len) +{ + struct i2c_client *client = chip->client; + int ret; + + ret = i2c_master_send(client, ®, 1); + if (ret < 0) { + dev_err(&client->dev, "I2C write error\n"); + return ret; + } + + ret = i2c_master_recv(client, data, len); + if (ret < 0) { + dev_err(&client->dev, "I2C read error\n"); + return ret; + } + + return ret; +} + +static int ad774x_i2c_write(struct ad774x_chip_info *chip, u8 reg, u8 data) +{ + struct i2c_client *client = chip->client; + int ret; + + u8 tx[2] = { + reg, + data, + }; + + ret = i2c_master_send(client, tx, 2); + if (ret < 0) + dev_err(&client->dev, "I2C write error\n"); + + return ret; +} + +/* + * sysfs nodes + */ + +#define IIO_DEV_ATTR_AVAIL_CONVERSION_MODES(_show) \ + IIO_DEVICE_ATTR(available_conversion_modes, S_IRUGO, _show, NULL, 0) +#define IIO_DEV_ATTR_CONVERSION_MODE(_mode, _show, _store) \ + IIO_DEVICE_ATTR(conversion_mode, _mode, _show, _store, 0) +#define IIO_DEV_ATTR_CAP_SETUP(_mode, _show, _store) \ + IIO_DEVICE_ATTR(cap_setup, _mode, _show, _store, 0) +#define IIO_DEV_ATTR_VT_SETUP(_mode, _show, _store) \ + IIO_DEVICE_ATTR(in0_setup, _mode, _show, _store, 0) +#define IIO_DEV_ATTR_EXEC_SETUP(_mode, _show, _store) \ + IIO_DEVICE_ATTR(exec_setup, _mode, _show, _store, 0) +#define IIO_DEV_ATTR_VOLT_GAIN(_mode, _show, _store) \ + IIO_DEVICE_ATTR(in0_gain, _mode, _show, _store, 0) +#define IIO_DEV_ATTR_CAP_OFFS(_mode, _show, _store) \ + IIO_DEVICE_ATTR(cap_offs, _mode, _show, _store, 0) +#define IIO_DEV_ATTR_CAP_GAIN(_mode, _show, _store) \ + IIO_DEVICE_ATTR(cap_gain, _mode, _show, _store, 0) +#define IIO_DEV_ATTR_CAP_DATA(_show) \ + IIO_DEVICE_ATTR(cap0_raw, S_IRUGO, _show, NULL, 0) +#define IIO_DEV_ATTR_VT_DATA(_show) \ + IIO_DEVICE_ATTR(in0_raw, S_IRUGO, _show, NULL, 0) + +static ssize_t ad774x_show_conversion_modes(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + int i; + int len = 0; + + for (i = 0; i < AD774X_MAX_CONV_MODE; i++) + len += sprintf(buf + len, "%s ", ad774x_conv_mode_table[i].name); + + len += sprintf(buf + len, "\n"); + + return len; +} + +static IIO_DEV_ATTR_AVAIL_CONVERSION_MODES(ad774x_show_conversion_modes); + +static ssize_t ad774x_show_conversion_mode(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad774x_chip_info *chip = dev_info->dev_data; + + return sprintf(buf, "%s\n", chip->conversion_mode); +} + +static ssize_t ad774x_store_conversion_mode(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad774x_chip_info *chip = dev_info->dev_data; + u8 cfg; + int i; + + ad774x_i2c_read(chip, AD774X_CFG, &cfg, 1); + + for (i = 0; i < AD774X_MAX_CONV_MODE; i++) { + if (strncmp(buf, ad774x_conv_mode_table[i].name, + strlen(ad774x_conv_mode_table[i].name) - 1) == 0) { + chip->conversion_mode = ad774x_conv_mode_table[i].name; + cfg |= 0x18 | ad774x_conv_mode_table[i].reg_cfg; + ad774x_i2c_write(chip, AD774X_CFG, cfg); + return len; + } + } + + dev_err(dev, "not supported conversion mode\n"); + + return -EINVAL; +} + +static IIO_DEV_ATTR_CONVERSION_MODE(S_IRUGO | S_IWUSR, + ad774x_show_conversion_mode, + ad774x_store_conversion_mode); + +static ssize_t ad774x_show_dac_value(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad774x_chip_info *chip = dev_info->dev_data; + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + u8 data; + + ad774x_i2c_read(chip, this_attr->address, &data, 1); + + return sprintf(buf, "%02x\n", data & 0x7F); +} + +static ssize_t ad774x_store_dac_value(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad774x_chip_info *chip = dev_info->dev_data; + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + unsigned long data; + int ret; + + ret = strict_strtoul(buf, 10, &data); + + if (!ret) { + ad774x_i2c_write(chip, this_attr->address, + (data ? AD774X_CAPDAC_EN : 0) | (data & 0x7F)); + return len; + } + + return -EINVAL; +} + +static IIO_DEVICE_ATTR(capdac0_raw, S_IRUGO | S_IWUSR, + ad774x_show_dac_value, + ad774x_store_dac_value, + AD774X_CAPDACA); + +static IIO_DEVICE_ATTR(capdac1_raw, S_IRUGO | S_IWUSR, + ad774x_show_dac_value, + ad774x_store_dac_value, + AD774X_CAPDACB); + +static ssize_t ad774x_show_cap_setup(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad774x_chip_info *chip = dev_info->dev_data; + + return sprintf(buf, "0x%02x\n", chip->cap_setup); +} + +static ssize_t ad774x_store_cap_setup(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad774x_chip_info *chip = dev_info->dev_data; + unsigned long data; + int ret; + + ret = strict_strtoul(buf, 10, &data); + + if ((!ret) && (data < 0x100)) { + ad774x_i2c_write(chip, AD774X_CAP_SETUP, data); + chip->cap_setup = data; + return len; + } + + return -EINVAL; +} + +static IIO_DEV_ATTR_CAP_SETUP(S_IRUGO | S_IWUSR, + ad774x_show_cap_setup, + ad774x_store_cap_setup); + +static ssize_t ad774x_show_vt_setup(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad774x_chip_info *chip = dev_info->dev_data; + + return sprintf(buf, "0x%02x\n", chip->vt_setup); +} + +static ssize_t ad774x_store_vt_setup(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad774x_chip_info *chip = dev_info->dev_data; + unsigned long data; + int ret; + + ret = strict_strtoul(buf, 10, &data); + + if ((!ret) && (data < 0x100)) { + ad774x_i2c_write(chip, AD774X_VT_SETUP, data); + chip->vt_setup = data; + return len; + } + + return -EINVAL; +} + +static IIO_DEV_ATTR_VT_SETUP(S_IRUGO | S_IWUSR, + ad774x_show_vt_setup, + ad774x_store_vt_setup); + +static ssize_t ad774x_show_exec_setup(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad774x_chip_info *chip = dev_info->dev_data; + + return sprintf(buf, "0x%02x\n", chip->exec_setup); +} + +static ssize_t ad774x_store_exec_setup(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad774x_chip_info *chip = dev_info->dev_data; + unsigned long data; + int ret; + + ret = strict_strtoul(buf, 10, &data); + + if ((!ret) && (data < 0x100)) { + ad774x_i2c_write(chip, AD774X_EXEC_SETUP, data); + chip->exec_setup = data; + return len; + } + + return -EINVAL; +} + +static IIO_DEV_ATTR_EXEC_SETUP(S_IRUGO | S_IWUSR, + ad774x_show_exec_setup, + ad774x_store_exec_setup); + +static ssize_t ad774x_show_volt_gain(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad774x_chip_info *chip = dev_info->dev_data; + + return sprintf(buf, "%d\n", chip->volt_gain); +} + +static ssize_t ad774x_store_volt_gain(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad774x_chip_info *chip = dev_info->dev_data; + unsigned long data; + int ret; + + ret = strict_strtoul(buf, 10, &data); + + if ((!ret) && (data < 0x10000)) { + ad774x_i2c_write(chip, AD774X_VOLT_GAINH, data >> 8); + ad774x_i2c_write(chip, AD774X_VOLT_GAINL, data); + chip->volt_gain = data; + return len; + } + + return -EINVAL; +} + +static IIO_DEV_ATTR_VOLT_GAIN(S_IRUGO | S_IWUSR, + ad774x_show_volt_gain, + ad774x_store_volt_gain); + +static ssize_t ad774x_show_cap_data(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad774x_chip_info *chip = dev_info->dev_data; + unsigned long data; + char tmp[3]; + + ad774x_i2c_read(chip, AD774X_CAP_DATA_HIGH, tmp, 3); + data = ((int)tmp[0] << 16) | ((int)tmp[1] << 8) | (int)tmp[2]; + + return sprintf(buf, "%ld\n", data); +} + +static IIO_DEV_ATTR_CAP_DATA(ad774x_show_cap_data); + +static ssize_t ad774x_show_vt_data(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad774x_chip_info *chip = dev_info->dev_data; + unsigned long data; + char tmp[3]; + + ad774x_i2c_read(chip, AD774X_VT_DATA_HIGH, tmp, 3); + data = ((int)tmp[0] << 16) | ((int)tmp[1] << 8) | (int)tmp[2]; + + return sprintf(buf, "%ld\n", data); +} + +static IIO_DEV_ATTR_VT_DATA(ad774x_show_vt_data); + +static ssize_t ad774x_show_cap_offs(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad774x_chip_info *chip = dev_info->dev_data; + + return sprintf(buf, "%d\n", chip->cap_offs); +} + +static ssize_t ad774x_store_cap_offs(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad774x_chip_info *chip = dev_info->dev_data; + unsigned long data; + int ret; + + ret = strict_strtoul(buf, 10, &data); + + if ((!ret) && (data < 0x10000)) { + ad774x_i2c_write(chip, AD774X_CAP_OFFH, data >> 8); + ad774x_i2c_write(chip, AD774X_CAP_OFFL, data); + chip->cap_offs = data; + return len; + } + + return -EINVAL; +} + +static IIO_DEV_ATTR_CAP_OFFS(S_IRUGO | S_IWUSR, + ad774x_show_cap_offs, + ad774x_store_cap_offs); + +static ssize_t ad774x_show_cap_gain(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad774x_chip_info *chip = dev_info->dev_data; + + return sprintf(buf, "%d\n", chip->cap_gain); +} + +static ssize_t ad774x_store_cap_gain(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad774x_chip_info *chip = dev_info->dev_data; + unsigned long data; + int ret; + + ret = strict_strtoul(buf, 10, &data); + + if ((!ret) && (data < 0x10000)) { + ad774x_i2c_write(chip, AD774X_CAP_GAINH, data >> 8); + ad774x_i2c_write(chip, AD774X_CAP_GAINL, data); + chip->cap_gain = data; + return len; + } + + return -EINVAL; +} + +static IIO_DEV_ATTR_CAP_GAIN(S_IRUGO | S_IWUSR, + ad774x_show_cap_gain, + ad774x_store_cap_gain); + +static ssize_t ad774x_show_name(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad774x_chip_info *chip = dev_info->dev_data; + return sprintf(buf, "%s\n", chip->name); +} + +static IIO_DEVICE_ATTR(name, S_IRUGO, ad774x_show_name, NULL, 0); + +static struct attribute *ad774x_attributes[] = { + &iio_dev_attr_available_conversion_modes.dev_attr.attr, + &iio_dev_attr_conversion_mode.dev_attr.attr, + &iio_dev_attr_cap_setup.dev_attr.attr, + &iio_dev_attr_in0_setup.dev_attr.attr, + &iio_dev_attr_exec_setup.dev_attr.attr, + &iio_dev_attr_cap_offs.dev_attr.attr, + &iio_dev_attr_cap_gain.dev_attr.attr, + &iio_dev_attr_in0_gain.dev_attr.attr, + &iio_dev_attr_in0_raw.dev_attr.attr, + &iio_dev_attr_cap0_raw.dev_attr.attr, + &iio_dev_attr_capdac0_raw.dev_attr.attr, + &iio_dev_attr_capdac1_raw.dev_attr.attr, + &iio_dev_attr_name.dev_attr.attr, + NULL, +}; + +static const struct attribute_group ad774x_attribute_group = { + .attrs = ad774x_attributes, +}; + +/* + * data ready events + */ + +#define IIO_EVENT_CODE_CAP_RDY IIO_BUFFER_EVENT_CODE(0) +#define IIO_EVENT_CODE_VT_RDY IIO_BUFFER_EVENT_CODE(1) + +#define IIO_EVENT_ATTR_CAP_RDY_SH(_evlist, _show, _store, _mask) \ + IIO_EVENT_ATTR_SH(cap_rdy, _evlist, _show, _store, _mask) + +#define IIO_EVENT_ATTR_VT_RDY_SH(_evlist, _show, _store, _mask) \ + IIO_EVENT_ATTR_SH(vt_rdy, _evlist, _show, _store, _mask) + +static void ad774x_interrupt_handler_bh(struct work_struct *work_s) +{ + struct ad774x_chip_info *chip = + container_of(work_s, struct ad774x_chip_info, thresh_work); + u8 int_status; + + enable_irq(chip->client->irq); + + ad774x_i2c_read(chip, AD774X_STATUS, &int_status, 1); + + if (int_status & AD774X_STATUS_RDYCAP) + iio_push_event(chip->indio_dev, 0, + IIO_EVENT_CODE_CAP_RDY, + chip->last_timestamp); + + if (int_status & AD774X_STATUS_RDYVT) + iio_push_event(chip->indio_dev, 0, + IIO_EVENT_CODE_VT_RDY, + chip->last_timestamp); +} + +static int ad774x_interrupt_handler_th(struct iio_dev *dev_info, + int index, + s64 timestamp, + int no_test) +{ + struct ad774x_chip_info *chip = dev_info->dev_data; + + chip->last_timestamp = timestamp; + schedule_work(&chip->thresh_work); + + return 0; +} + +IIO_EVENT_SH(data_rdy, &ad774x_interrupt_handler_th); + +static ssize_t ad774x_query_out_mode(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + /* + * AD774X provides one /RDY pin, which can be used as interrupt + * but the pin is not configurable + */ + return sprintf(buf, "1\n"); +} + +static ssize_t ad774x_set_out_mode(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + return len; +} + +IIO_EVENT_ATTR_CAP_RDY_SH(iio_event_data_rdy, ad774x_query_out_mode, ad774x_set_out_mode, 0); +IIO_EVENT_ATTR_VT_RDY_SH(iio_event_data_rdy, ad774x_query_out_mode, ad774x_set_out_mode, 0); + +static struct attribute *ad774x_event_attributes[] = { + &iio_event_attr_cap_rdy.dev_attr.attr, + &iio_event_attr_vt_rdy.dev_attr.attr, + NULL, +}; + +static struct attribute_group ad774x_event_attribute_group = { + .attrs = ad774x_event_attributes, +}; + +/* + * device probe and remove + */ + +static int __devinit ad774x_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + int ret = 0, regdone = 0; + struct ad774x_chip_info *chip = kzalloc(sizeof(*chip), GFP_KERNEL); + if (chip == NULL) { + ret = -ENOMEM; + goto error_ret; + } + + /* this is only used for device removal purposes */ + i2c_set_clientdata(client, chip); + + chip->client = client; + chip->name = id->name; + + chip->indio_dev = iio_allocate_device(); + if (chip->indio_dev == NULL) { + ret = -ENOMEM; + goto error_free_chip; + } + + /* Establish that the iio_dev is a child of the i2c device */ + chip->indio_dev->dev.parent = &client->dev; + chip->indio_dev->attrs = &ad774x_attribute_group; + chip->indio_dev->event_attrs = &ad774x_event_attribute_group; + chip->indio_dev->dev_data = (void *)(chip); + chip->indio_dev->driver_module = THIS_MODULE; + chip->indio_dev->num_interrupt_lines = 1; + chip->indio_dev->modes = INDIO_DIRECT_MODE; + + ret = iio_device_register(chip->indio_dev); + if (ret) + goto error_free_dev; + regdone = 1; + + if (client->irq) { + ret = iio_register_interrupt_line(client->irq, + chip->indio_dev, + 0, + IRQF_TRIGGER_FALLING, + "ad774x"); + if (ret) + goto error_free_dev; + + iio_add_event_to_list(iio_event_attr_cap_rdy.listel, + &chip->indio_dev->interrupts[0]->ev_list); + + INIT_WORK(&chip->thresh_work, ad774x_interrupt_handler_bh); + } + + dev_err(&client->dev, "%s capacitive sensor registered, irq: %d\n", id->name, client->irq); + + return 0; + +error_free_dev: + if (regdone) + iio_device_unregister(chip->indio_dev); + else + iio_free_device(chip->indio_dev); +error_free_chip: + kfree(chip); +error_ret: + return ret; +} + +static int __devexit ad774x_remove(struct i2c_client *client) +{ + struct ad774x_chip_info *chip = i2c_get_clientdata(client); + struct iio_dev *indio_dev = chip->indio_dev; + + if (client->irq) + iio_unregister_interrupt_line(indio_dev, 0); + iio_device_unregister(indio_dev); + kfree(chip); + + return 0; +} + +static const struct i2c_device_id ad774x_id[] = { + { "ad7745", 0 }, + { "ad7746", 0 }, + { "ad7747", 0 }, + {} +}; + +MODULE_DEVICE_TABLE(i2c, ad774x_id); + +static struct i2c_driver ad774x_driver = { + .driver = { + .name = "ad774x", + }, + .probe = ad774x_probe, + .remove = __devexit_p(ad774x_remove), + .id_table = ad774x_id, +}; + +static __init int ad774x_init(void) +{ + return i2c_add_driver(&ad774x_driver); +} + +static __exit void ad774x_exit(void) +{ + i2c_del_driver(&ad774x_driver); +} + +MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>"); +MODULE_DESCRIPTION("Analog Devices ad7745/6/7 capacitive sensor driver"); +MODULE_LICENSE("GPL v2"); + +module_init(ad774x_init); +module_exit(ad774x_exit); -- cgit v1.2.3 From 7924425db04a6107e49312edf53c158590d52aae Mon Sep 17 00:00:00 2001 From: Sonic Zhang Date: Wed, 27 Oct 2010 21:43:59 -0400 Subject: staging: iio: adc: new driver for AD7816 devices Signed-off-by: Sonic Zhang Signed-off-by: Michael Hennerich Acked-by: Jonathan Cameron Signed-off-by: Mike Frysinger Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/adc/Kconfig | 7 + drivers/staging/iio/adc/Makefile | 1 + drivers/staging/iio/adc/ad7816.c | 535 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 543 insertions(+) create mode 100644 drivers/staging/iio/adc/ad7816.c diff --git a/drivers/staging/iio/adc/Kconfig b/drivers/staging/iio/adc/Kconfig index 34c6822ae070..e722b26ee197 100644 --- a/drivers/staging/iio/adc/Kconfig +++ b/drivers/staging/iio/adc/Kconfig @@ -106,3 +106,10 @@ config AD7745 To compile this driver as a module, choose M here: the module will be called ad7745. + +config AD7816 + tristate "Analog Devices AD7816/7/8 temperature sensor and ADC driver" + depends on SPI + help + Say yes here to build support for Analog Devices AD7816/7/8 + temperature sensors and ADC. diff --git a/drivers/staging/iio/adc/Makefile b/drivers/staging/iio/adc/Makefile index ac83bad5125a..b8d641cca1d2 100644 --- a/drivers/staging/iio/adc/Makefile +++ b/drivers/staging/iio/adc/Makefile @@ -21,3 +21,4 @@ obj-$(CONFIG_AD7291) += ad7291.o obj-$(CONFIG_AD7298) += ad7298.o obj-$(CONFIG_AD7314) += ad7314.o obj-$(CONFIG_AD7745) += ad7745.o +obj-$(CONFIG_AD7816) += ad7816.o diff --git a/drivers/staging/iio/adc/ad7816.c b/drivers/staging/iio/adc/ad7816.c new file mode 100644 index 000000000000..ad7415a6b8d9 --- /dev/null +++ b/drivers/staging/iio/adc/ad7816.c @@ -0,0 +1,535 @@ +/* + * AD7816 digital temperature sensor driver supporting AD7816/7/8 + * + * Copyright 2010 Analog Devices Inc. + * + * Licensed under the GPL-2 or later. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../iio.h" +#include "../sysfs.h" + +/* + * AD7816 config masks + */ +#define AD7816_FULL 0x1 +#define AD7816_PD 0x2 +#define AD7816_CS_MASK 0x7 +#define AD7816_CS_MAX 0x4 + +/* + * AD7816 temperature masks + */ +#define AD7816_VALUE_OFFSET 6 +#define AD7816_BOUND_VALUE_BASE 0x8 +#define AD7816_BOUND_VALUE_MIN -95 +#define AD7816_BOUND_VALUE_MAX 152 +#define AD7816_TEMP_FLOAT_OFFSET 2 +#define AD7816_TEMP_FLOAT_MASK 0x3 + + +/* + * struct ad7816_chip_info - chip specifc information + */ + +struct ad7816_chip_info { + const char *name; + struct spi_device *spi_dev; + struct iio_dev *indio_dev; + struct work_struct thresh_work; + s64 last_timestamp; + u16 rdwr_pin; + u16 convert_pin; + u16 busy_pin; + u8 oti_data[AD7816_CS_MAX+1]; + u8 channel_id; /* 0 always be temperature */ + u8 mode; +}; + +/* + * ad7816 data access by SPI + */ +static int ad7816_spi_read(struct ad7816_chip_info *chip, u16 *data) +{ + struct spi_device *spi_dev = chip->spi_dev; + int ret = 0; + + gpio_set_value(chip->rdwr_pin, 1); + gpio_set_value(chip->rdwr_pin, 0); + ret = spi_write(spi_dev, &chip->channel_id, sizeof(chip->channel_id)); + if (ret < 0) { + dev_err(&spi_dev->dev, "SPI channel setting error\n"); + return ret; + } + gpio_set_value(chip->rdwr_pin, 1); + + + if (chip->mode == AD7816_PD) { /* operating mode 2 */ + gpio_set_value(chip->convert_pin, 1); + gpio_set_value(chip->convert_pin, 0); + } else { /* operating mode 1 */ + gpio_set_value(chip->convert_pin, 0); + gpio_set_value(chip->convert_pin, 1); + } + + while (gpio_get_value(chip->busy_pin)) + cpu_relax(); + + gpio_set_value(chip->rdwr_pin, 0); + gpio_set_value(chip->rdwr_pin, 1); + ret = spi_read(spi_dev, (u8 *)data, sizeof(*data)); + if (ret < 0) { + dev_err(&spi_dev->dev, "SPI data read error\n"); + return ret; + } + + *data = be16_to_cpu(*data); + + return ret; +} + +static int ad7816_spi_write(struct ad7816_chip_info *chip, u8 data) +{ + struct spi_device *spi_dev = chip->spi_dev; + int ret = 0; + + gpio_set_value(chip->rdwr_pin, 1); + gpio_set_value(chip->rdwr_pin, 0); + ret = spi_write(spi_dev, &data, sizeof(data)); + if (ret < 0) + dev_err(&spi_dev->dev, "SPI oti data write error\n"); + + return ret; +} + +static ssize_t ad7816_show_mode(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad7816_chip_info *chip = dev_info->dev_data; + + if (chip->mode) + return sprintf(buf, "power-save\n"); + else + return sprintf(buf, "full\n"); +} + +static ssize_t ad7816_store_mode(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad7816_chip_info *chip = dev_info->dev_data; + + if (strcmp(buf, "full")) { + gpio_set_value(chip->rdwr_pin, 1); + chip->mode = AD7816_FULL; + } else { + gpio_set_value(chip->rdwr_pin, 0); + chip->mode = AD7816_PD; + } + + return len; +} + +static IIO_DEVICE_ATTR(mode, S_IRUGO | S_IWUSR, + ad7816_show_mode, + ad7816_store_mode, + 0); + +static ssize_t ad7816_show_available_modes(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + return sprintf(buf, "full\npower-save\n"); +} + +static IIO_DEVICE_ATTR(available_modes, S_IRUGO, ad7816_show_available_modes, NULL, 0); + +static ssize_t ad7816_show_channel(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad7816_chip_info *chip = dev_info->dev_data; + + return sprintf(buf, "%d\n", chip->channel_id); +} + +static ssize_t ad7816_store_channel(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad7816_chip_info *chip = dev_info->dev_data; + unsigned long data; + int ret; + + ret = strict_strtoul(buf, 10, &data); + if (ret) + return -EINVAL; + + if (data > AD7816_CS_MAX && data != AD7816_CS_MASK) { + dev_err(&chip->spi_dev->dev, "Invalid channel id %lu for %s.\n", + data, chip->name); + return -EINVAL; + } else if (strcmp(chip->name, "ad7818") == 0 && data > 1) { + dev_err(&chip->spi_dev->dev, + "Invalid channel id %lu for ad7818.\n", data); + return -EINVAL; + } else if (strcmp(chip->name, "ad7816") == 0 && data > 0) { + dev_err(&chip->spi_dev->dev, + "Invalid channel id %lu for ad7816.\n", data); + return -EINVAL; + } + + chip->channel_id = data; + + return len; +} + +static IIO_DEVICE_ATTR(channel, S_IRUGO | S_IWUSR, + ad7816_show_channel, + ad7816_store_channel, + 0); + + +static ssize_t ad7816_show_value(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad7816_chip_info *chip = dev_info->dev_data; + u16 data; + s8 value; + int ret; + + ret = ad7816_spi_read(chip, &data); + if (ret) + return -EIO; + + data >>= AD7816_VALUE_OFFSET; + + if (chip->channel_id == 0) { + value = (s8)((data >> AD7816_TEMP_FLOAT_OFFSET) - 103); + data &= AD7816_TEMP_FLOAT_MASK; + if (value < 0) + data = (1 << AD7816_TEMP_FLOAT_OFFSET) - data; + return sprintf(buf, "%d.%.2d\n", value, data * 25); + } else + return sprintf(buf, "%u\n", data); +} + +static IIO_DEVICE_ATTR(value, S_IRUGO, ad7816_show_value, NULL, 0); + +static ssize_t ad7816_show_name(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad7816_chip_info *chip = dev_info->dev_data; + return sprintf(buf, "%s\n", chip->name); +} + +static IIO_DEVICE_ATTR(name, S_IRUGO, ad7816_show_name, NULL, 0); + +static struct attribute *ad7816_attributes[] = { + &iio_dev_attr_available_modes.dev_attr.attr, + &iio_dev_attr_mode.dev_attr.attr, + &iio_dev_attr_channel.dev_attr.attr, + &iio_dev_attr_value.dev_attr.attr, + &iio_dev_attr_name.dev_attr.attr, + NULL, +}; + +static const struct attribute_group ad7816_attribute_group = { + .attrs = ad7816_attributes, +}; + +/* + * temperature bound events + */ + +#define IIO_EVENT_CODE_AD7816_OTI IIO_BUFFER_EVENT_CODE(0) + +static void ad7816_interrupt_bh(struct work_struct *work_s) +{ + struct ad7816_chip_info *chip = + container_of(work_s, struct ad7816_chip_info, thresh_work); + + enable_irq(chip->spi_dev->irq); + + iio_push_event(chip->indio_dev, 0, + IIO_EVENT_CODE_AD7816_OTI, + chip->last_timestamp); +} + +static int ad7816_interrupt(struct iio_dev *dev_info, + int index, + s64 timestamp, + int no_test) +{ + struct ad7816_chip_info *chip = dev_info->dev_data; + + chip->last_timestamp = timestamp; + schedule_work(&chip->thresh_work); + + return 0; +} + +IIO_EVENT_SH(ad7816, &ad7816_interrupt); + +static ssize_t ad7816_show_oti(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad7816_chip_info *chip = dev_info->dev_data; + int value; + + if (chip->channel_id > AD7816_CS_MAX) { + dev_err(dev, "Invalid oti channel id %d.\n", chip->channel_id); + return -EINVAL; + } else if (chip->channel_id == 0) { + value = AD7816_BOUND_VALUE_MIN + + (chip->oti_data[chip->channel_id] - + AD7816_BOUND_VALUE_BASE); + return sprintf(buf, "%d\n", value); + } else + return sprintf(buf, "%u\n", chip->oti_data[chip->channel_id]); +} + +static inline ssize_t ad7816_set_oti(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad7816_chip_info *chip = dev_info->dev_data; + long value; + u8 data; + int ret; + + ret = strict_strtol(buf, 10, &value); + + if (chip->channel_id > AD7816_CS_MAX) { + dev_err(dev, "Invalid oti channel id %d.\n", chip->channel_id); + return -EINVAL; + } else if (chip->channel_id == 0) { + if (ret || value < AD7816_BOUND_VALUE_MIN || + value > AD7816_BOUND_VALUE_MAX) + return -EINVAL; + + data = (u8)(value - AD7816_BOUND_VALUE_MIN + + AD7816_BOUND_VALUE_BASE); + } else { + if (ret || value < AD7816_BOUND_VALUE_BASE || value > 255) + return -EINVAL; + + data = (u8)value; + } + + ret = ad7816_spi_write(chip, data); + if (ret) + return -EIO; + + chip->oti_data[chip->channel_id] = data; + + return len; +} + +IIO_EVENT_ATTR_SH(oti, iio_event_ad7816, + ad7816_show_oti, ad7816_set_oti, 0); + +static struct attribute *ad7816_event_attributes[] = { + &iio_event_attr_oti.dev_attr.attr, + NULL, +}; + +static struct attribute_group ad7816_event_attribute_group = { + .attrs = ad7816_event_attributes, +}; + +/* + * device probe and remove + */ + +static int __devinit ad7816_probe(struct spi_device *spi_dev) +{ + struct ad7816_chip_info *chip; + unsigned short *pins = spi_dev->dev.platform_data; + int ret = 0; + int i; + + if (!pins) { + dev_err(&spi_dev->dev, "No necessary GPIO platform data.\n"); + return -EINVAL; + } + + chip = kzalloc(sizeof(struct ad7816_chip_info), GFP_KERNEL); + + if (chip == NULL) + return -ENOMEM; + + /* this is only used for device removal purposes */ + dev_set_drvdata(&spi_dev->dev, chip); + + chip->spi_dev = spi_dev; + chip->name = spi_dev->modalias; + for (i = 0; i <= AD7816_CS_MAX; i++) + chip->oti_data[i] = 203; + chip->rdwr_pin = pins[0]; + chip->convert_pin = pins[1]; + chip->busy_pin = pins[2]; + + ret = gpio_request(chip->rdwr_pin, chip->name); + if (ret) { + dev_err(&spi_dev->dev, "Fail to request rdwr gpio PIN %d.\n", + chip->rdwr_pin); + goto error_free_chip; + } + gpio_direction_input(chip->rdwr_pin); + ret = gpio_request(chip->convert_pin, chip->name); + if (ret) { + dev_err(&spi_dev->dev, "Fail to request convert gpio PIN %d.\n", + chip->convert_pin); + goto error_free_gpio_rdwr; + } + gpio_direction_input(chip->convert_pin); + ret = gpio_request(chip->busy_pin, chip->name); + if (ret) { + dev_err(&spi_dev->dev, "Fail to request busy gpio PIN %d.\n", + chip->busy_pin); + goto error_free_gpio_convert; + } + gpio_direction_input(chip->busy_pin); + + chip->indio_dev = iio_allocate_device(); + if (chip->indio_dev == NULL) { + ret = -ENOMEM; + goto error_free_gpio; + } + + chip->indio_dev->dev.parent = &spi_dev->dev; + chip->indio_dev->attrs = &ad7816_attribute_group; + chip->indio_dev->event_attrs = &ad7816_event_attribute_group; + chip->indio_dev->dev_data = (void *)chip; + chip->indio_dev->driver_module = THIS_MODULE; + chip->indio_dev->num_interrupt_lines = 1; + chip->indio_dev->modes = INDIO_DIRECT_MODE; + + ret = iio_device_register(chip->indio_dev); + if (ret) + goto error_free_dev; + + if (spi_dev->irq) { + /* Only low trigger is supported in ad7816/7/8 */ + ret = iio_register_interrupt_line(spi_dev->irq, + chip->indio_dev, + 0, + IRQF_TRIGGER_LOW, + chip->name); + if (ret) + goto error_unreg_dev; + + /* + * The event handler list element refer to iio_event_ad7816. + * All event attributes bind to the same event handler. + * So, only register event handler once. + */ + iio_add_event_to_list(&iio_event_ad7816, + &chip->indio_dev->interrupts[0]->ev_list); + + INIT_WORK(&chip->thresh_work, ad7816_interrupt_bh); + } + + dev_info(&spi_dev->dev, "%s temperature sensor and ADC registered.\n", + chip->name); + + return 0; + +error_unreg_dev: + iio_device_unregister(chip->indio_dev); +error_free_dev: + iio_free_device(chip->indio_dev); +error_free_gpio: + gpio_free(chip->busy_pin); +error_free_gpio_convert: + gpio_free(chip->convert_pin); +error_free_gpio_rdwr: + gpio_free(chip->rdwr_pin); +error_free_chip: + kfree(chip); + + return ret; +} + +static int __devexit ad7816_remove(struct spi_device *spi_dev) +{ + struct ad7816_chip_info *chip = dev_get_drvdata(&spi_dev->dev); + struct iio_dev *indio_dev = chip->indio_dev; + + dev_set_drvdata(&spi_dev->dev, NULL); + if (spi_dev->irq) + iio_unregister_interrupt_line(indio_dev, 0); + iio_device_unregister(indio_dev); + iio_free_device(chip->indio_dev); + gpio_free(chip->busy_pin); + gpio_free(chip->convert_pin); + gpio_free(chip->rdwr_pin); + kfree(chip); + + return 0; +} + +static const struct spi_device_id ad7816_id[] = { + { "ad7816", 0 }, + { "ad7817", 0 }, + { "ad7818", 0 }, + {} +}; + +MODULE_DEVICE_TABLE(spi, ad7816_id); + +static struct spi_driver ad7816_driver = { + .driver = { + .name = "ad7816", + .bus = &spi_bus_type, + .owner = THIS_MODULE, + }, + .probe = ad7816_probe, + .remove = __devexit_p(ad7816_remove), + .id_table = ad7816_id, +}; + +static __init int ad7816_init(void) +{ + return spi_register_driver(&ad7816_driver); +} + +static __exit void ad7816_exit(void) +{ + spi_unregister_driver(&ad7816_driver); +} + +MODULE_AUTHOR("Sonic Zhang "); +MODULE_DESCRIPTION("Analog Devices AD7816/7/8 digital" + " temperature sensor driver"); +MODULE_LICENSE("GPL v2"); + +module_init(ad7816_init); +module_exit(ad7816_exit); -- cgit v1.2.3 From d7713b6c56472b41e04ebcbdfdf85df84c8e82d6 Mon Sep 17 00:00:00 2001 From: Sonic Zhang Date: Wed, 27 Oct 2010 21:44:00 -0400 Subject: staging: iio: adc: new driver for ADT75 temperature sensors Signed-off-by: Sonic Zhang Signed-off-by: Michael Hennerich Acked-by: Jonathan Cameron Signed-off-by: Mike Frysinger Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/adc/Kconfig | 7 + drivers/staging/iio/adc/Makefile | 1 + drivers/staging/iio/adc/adt75.c | 732 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 740 insertions(+) create mode 100644 drivers/staging/iio/adc/adt75.c diff --git a/drivers/staging/iio/adc/Kconfig b/drivers/staging/iio/adc/Kconfig index e722b26ee197..a7c6b818dbb7 100644 --- a/drivers/staging/iio/adc/Kconfig +++ b/drivers/staging/iio/adc/Kconfig @@ -113,3 +113,10 @@ config AD7816 help Say yes here to build support for Analog Devices AD7816/7/8 temperature sensors and ADC. + +config ADT75 + tristate "Analog Devices ADT75 temperature sensor driver" + depends on I2C + help + Say yes here to build support for Analog Devices ADT75 + temperature sensors. diff --git a/drivers/staging/iio/adc/Makefile b/drivers/staging/iio/adc/Makefile index b8d641cca1d2..d1f1b5720cdf 100644 --- a/drivers/staging/iio/adc/Makefile +++ b/drivers/staging/iio/adc/Makefile @@ -22,3 +22,4 @@ obj-$(CONFIG_AD7298) += ad7298.o obj-$(CONFIG_AD7314) += ad7314.o obj-$(CONFIG_AD7745) += ad7745.o obj-$(CONFIG_AD7816) += ad7816.o +obj-$(CONFIG_ADT75) += adt75.o diff --git a/drivers/staging/iio/adc/adt75.c b/drivers/staging/iio/adc/adt75.c new file mode 100644 index 000000000000..aff4d31eb89c --- /dev/null +++ b/drivers/staging/iio/adc/adt75.c @@ -0,0 +1,732 @@ +/* + * ADT75 digital temperature sensor driver supporting ADT75 + * + * Copyright 2010 Analog Devices Inc. + * + * Licensed under the GPL-2 or later. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../iio.h" +#include "../sysfs.h" + +/* + * ADT75 registers definition + */ + +#define ADT75_TEMPERATURE 0 +#define ADT75_CONFIG 1 +#define ADT75_T_HYST 2 +#define ADT75_T_OS 3 +#define ADT75_ONESHOT 4 + +/* + * ADT75 config + */ +#define ADT75_PD 0x1 +#define ADT75_OS_INT 0x2 +#define ADT75_OS_POLARITY 0x4 +#define ADT75_FAULT_QUEUE_MASK 0x18 +#define ADT75_FAULT_QUEUE_OFFSET 3 +#define ADT75_SMBUS_ALART 0x8 + +/* + * ADT75 masks + */ +#define ADT75_VALUE_SIGN 0x800 +#define ADT75_VALUE_OFFSET 4 +#define ADT75_VALUE_FLOAT_OFFSET 4 +#define ADT75_VALUE_FLOAT_MASK 0xF + + +/* + * struct adt75_chip_info - chip specifc information + */ + +struct adt75_chip_info { + const char *name; + struct i2c_client *client; + struct iio_dev *indio_dev; + struct work_struct thresh_work; + s64 last_timestamp; + u8 config; +}; + +/* + * adt75 register access by I2C + */ + +static int adt75_i2c_read(struct adt75_chip_info *chip, u8 reg, u8 *data) +{ + struct i2c_client *client = chip->client; + int ret = 0, len; + + ret = i2c_smbus_write_byte(client, reg); + if (ret < 0) { + dev_err(&client->dev, "I2C read register address error\n"); + return ret; + } + + if (reg == ADT75_CONFIG || reg == ADT75_ONESHOT) + len = 1; + else + len = 2; + + ret = i2c_master_recv(client, data, len); + if (ret < 0) { + dev_err(&client->dev, "I2C read error\n"); + return ret; + } + + return ret; +} + +static int adt75_i2c_write(struct adt75_chip_info *chip, u8 reg, u8 data) +{ + struct i2c_client *client = chip->client; + int ret = 0; + + if (reg == ADT75_CONFIG || reg == ADT75_ONESHOT) + ret = i2c_smbus_write_byte_data(client, reg, data); + else + ret = i2c_smbus_write_word_data(client, reg, data); + + if (ret < 0) + dev_err(&client->dev, "I2C write error\n"); + + return ret; +} + +static ssize_t adt75_show_mode(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct adt75_chip_info *chip = dev_info->dev_data; + + if (chip->config & ADT75_PD) + return sprintf(buf, "power-save\n"); + else + return sprintf(buf, "full\n"); +} + +static ssize_t adt75_store_mode(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct adt75_chip_info *chip = dev_info->dev_data; + int ret; + u8 config; + + ret = adt75_i2c_read(chip, ADT75_CONFIG, &chip->config); + if (ret) + return -EIO; + + config = chip->config & ~ADT75_PD; + if (!strcmp(buf, "full")) + config |= ADT75_PD; + + ret = adt75_i2c_write(chip, ADT75_CONFIG, config); + if (ret) + return -EIO; + + chip->config = config; + + return ret; +} + +static IIO_DEVICE_ATTR(mode, S_IRUGO | S_IWUSR, + adt75_show_mode, + adt75_store_mode, + 0); + +static ssize_t adt75_show_available_modes(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + return sprintf(buf, "full\npower-down\n"); +} + +static IIO_DEVICE_ATTR(available_modes, S_IRUGO, adt75_show_available_modes, NULL, 0); + +static ssize_t adt75_show_oneshot(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct adt75_chip_info *chip = dev_info->dev_data; + + return sprintf(buf, "%d\n", !!(chip->config & ADT75_ONESHOT)); +} + +static ssize_t adt75_store_oneshot(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct adt75_chip_info *chip = dev_info->dev_data; + unsigned long data = 0; + int ret; + u8 config; + + ret = strict_strtoul(buf, 10, &data); + if (ret) + return -EINVAL; + + + ret = adt75_i2c_read(chip, ADT75_CONFIG, &chip->config); + if (ret) + return -EIO; + + config = chip->config & ~ADT75_ONESHOT; + if (data) + config |= ADT75_ONESHOT; + + ret = adt75_i2c_write(chip, ADT75_CONFIG, config); + if (ret) + return -EIO; + + chip->config = config; + + return ret; +} + +static IIO_DEVICE_ATTR(oneshot, S_IRUGO | S_IWUSR, + adt75_show_oneshot, + adt75_store_oneshot, + 0); + +static ssize_t adt75_show_value(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct adt75_chip_info *chip = dev_info->dev_data; + u16 data; + char sign = ' '; + int ret; + + if (chip->config & ADT75_PD) { + dev_err(dev, "Can't read value in power-down mode.\n"); + return -EIO; + } + + if (chip->config & ADT75_ONESHOT) { + /* write to active converter */ + ret = i2c_smbus_write_byte(chip->client, ADT75_ONESHOT); + if (ret) + return -EIO; + } + + ret = adt75_i2c_read(chip, ADT75_TEMPERATURE, (u8 *)&data); + if (ret) + return -EIO; + + data = swab16(data) >> ADT75_VALUE_OFFSET; + if (data & ADT75_VALUE_SIGN) { + /* convert supplement to positive value */ + data = (ADT75_VALUE_SIGN << 1) - data; + sign = '-'; + } + + return sprintf(buf, "%c%d.%.4d\n", sign, + (data >> ADT75_VALUE_FLOAT_OFFSET), + (data & ADT75_VALUE_FLOAT_MASK) * 625); +} + +static IIO_DEVICE_ATTR(value, S_IRUGO, adt75_show_value, NULL, 0); + +static ssize_t adt75_show_name(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct adt75_chip_info *chip = dev_info->dev_data; + return sprintf(buf, "%s\n", chip->name); +} + +static IIO_DEVICE_ATTR(name, S_IRUGO, adt75_show_name, NULL, 0); + +static struct attribute *adt75_attributes[] = { + &iio_dev_attr_available_modes.dev_attr.attr, + &iio_dev_attr_mode.dev_attr.attr, + &iio_dev_attr_oneshot.dev_attr.attr, + &iio_dev_attr_value.dev_attr.attr, + &iio_dev_attr_name.dev_attr.attr, + NULL, +}; + +static const struct attribute_group adt75_attribute_group = { + .attrs = adt75_attributes, +}; + +/* + * temperature bound events + */ + +#define IIO_EVENT_CODE_ADT75_OTI IIO_BUFFER_EVENT_CODE(0) + +static void adt75_interrupt_bh(struct work_struct *work_s) +{ + struct adt75_chip_info *chip = + container_of(work_s, struct adt75_chip_info, thresh_work); + + enable_irq(chip->client->irq); + + iio_push_event(chip->indio_dev, 0, + IIO_EVENT_CODE_ADT75_OTI, + chip->last_timestamp); +} + +static int adt75_interrupt(struct iio_dev *dev_info, + int index, + s64 timestamp, + int no_test) +{ + struct adt75_chip_info *chip = dev_info->dev_data; + + chip->last_timestamp = timestamp; + schedule_work(&chip->thresh_work); + + return 0; +} + +IIO_EVENT_SH(adt75, &adt75_interrupt); + +static ssize_t adt75_show_oti_mode(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct adt75_chip_info *chip = dev_info->dev_data; + int ret; + + /* retrive ALART status */ + ret = adt75_i2c_read(chip, ADT75_CONFIG, &chip->config); + if (ret) + return -EIO; + + if (chip->config & ADT75_OS_INT) + return sprintf(buf, "interrupt\n"); + else + return sprintf(buf, "comparator\n"); +} + +static ssize_t adt75_set_oti_mode(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct adt75_chip_info *chip = dev_info->dev_data; + int ret; + u8 config; + + /* retrive ALART status */ + ret = adt75_i2c_read(chip, ADT75_CONFIG, &chip->config); + if (ret) + return -EIO; + + config = chip->config & ~ADT75_OS_INT; + if (strcmp(buf, "comparator") != 0) + config |= ADT75_OS_INT; + + ret = adt75_i2c_write(chip, ADT75_CONFIG, config); + if (ret) + return -EIO; + + chip->config = config; + + return ret; +} + +static ssize_t adt75_show_available_oti_modes(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + return sprintf(buf, "comparator\ninterrupt\n"); +} + +static ssize_t adt75_show_smbus_alart(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct adt75_chip_info *chip = dev_info->dev_data; + int ret; + + /* retrive ALART status */ + ret = adt75_i2c_read(chip, ADT75_CONFIG, &chip->config); + if (ret) + return -EIO; + + return sprintf(buf, "%d\n", !!(chip->config & ADT75_SMBUS_ALART)); +} + +static ssize_t adt75_set_smbus_alart(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct adt75_chip_info *chip = dev_info->dev_data; + unsigned long data = 0; + int ret; + u8 config; + + ret = strict_strtoul(buf, 10, &data); + if (ret) + return -EINVAL; + + /* retrive ALART status */ + ret = adt75_i2c_read(chip, ADT75_CONFIG, &chip->config); + if (ret) + return -EIO; + + config = chip->config & ~ADT75_SMBUS_ALART; + if (data) + config |= ADT75_SMBUS_ALART; + + ret = adt75_i2c_write(chip, ADT75_CONFIG, config); + if (ret) + return -EIO; + + chip->config = config; + + return ret; +} + +static ssize_t adt75_show_fault_queue(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct adt75_chip_info *chip = dev_info->dev_data; + int ret; + + /* retrive ALART status */ + ret = adt75_i2c_read(chip, ADT75_CONFIG, &chip->config); + if (ret) + return -EIO; + + return sprintf(buf, "%d\n", (chip->config & ADT75_FAULT_QUEUE_MASK) >> + ADT75_FAULT_QUEUE_OFFSET); +} + +static ssize_t adt75_set_fault_queue(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct adt75_chip_info *chip = dev_info->dev_data; + unsigned long data; + int ret; + u8 config; + + ret = strict_strtoul(buf, 10, &data); + if (ret || data > 3) + return -EINVAL; + + /* retrive ALART status */ + ret = adt75_i2c_read(chip, ADT75_CONFIG, &chip->config); + if (ret) + return -EIO; + + config = chip->config & ~ADT75_FAULT_QUEUE_MASK; + config |= (data << ADT75_FAULT_QUEUE_OFFSET); + ret = adt75_i2c_write(chip, ADT75_CONFIG, config); + if (ret) + return -EIO; + + chip->config = config; + + return ret; +} +static inline ssize_t adt75_show_t_bound(struct device *dev, + struct device_attribute *attr, + u8 bound_reg, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct adt75_chip_info *chip = dev_info->dev_data; + u16 data; + char sign = ' '; + int ret; + + ret = adt75_i2c_read(chip, bound_reg, (u8 *)&data); + if (ret) + return -EIO; + + data = swab16(data) >> ADT75_VALUE_OFFSET; + if (data & ADT75_VALUE_SIGN) { + /* convert supplement to positive value */ + data = (ADT75_VALUE_SIGN << 1) - data; + sign = '-'; + } + + return sprintf(buf, "%c%d.%.4d\n", sign, + (data >> ADT75_VALUE_FLOAT_OFFSET), + (data & ADT75_VALUE_FLOAT_MASK) * 625); +} + +static inline ssize_t adt75_set_t_bound(struct device *dev, + struct device_attribute *attr, + u8 bound_reg, + const char *buf, + size_t len) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct adt75_chip_info *chip = dev_info->dev_data; + long tmp1, tmp2; + u16 data; + char *pos; + int ret; + + pos = strchr(buf, '.'); + + ret = strict_strtol(buf, 10, &tmp1); + + if (ret || tmp1 > 127 || tmp1 < -128) + return -EINVAL; + + if (pos) { + len = strlen(pos); + if (len > ADT75_VALUE_FLOAT_OFFSET) + len = ADT75_VALUE_FLOAT_OFFSET; + pos[len] = 0; + ret = strict_strtol(pos, 10, &tmp2); + + if (!ret) + tmp2 = (tmp2 / 625) * 625; + } + + if (tmp1 < 0) + data = (u16)(-tmp1); + else + data = (u16)tmp1; + data = (data << ADT75_VALUE_FLOAT_OFFSET) | (tmp2 & ADT75_VALUE_FLOAT_MASK); + if (tmp1 < 0) + /* convert positive value to supplyment */ + data = (ADT75_VALUE_SIGN << 1) - data; + data <<= ADT75_VALUE_OFFSET; + data = swab16(data); + + ret = adt75_i2c_write(chip, bound_reg, (u8)data); + if (ret) + return -EIO; + + return ret; +} + +static ssize_t adt75_show_t_os(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + return adt75_show_t_bound(dev, attr, + ADT75_T_OS, buf); +} + +static inline ssize_t adt75_set_t_os(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + return adt75_set_t_bound(dev, attr, + ADT75_T_OS, buf, len); +} + +static ssize_t adt75_show_t_hyst(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + return adt75_show_t_bound(dev, attr, + ADT75_T_HYST, buf); +} + +static inline ssize_t adt75_set_t_hyst(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + return adt75_set_t_bound(dev, attr, + ADT75_T_HYST, buf, len); +} + +IIO_EVENT_ATTR_SH(oti_mode, iio_event_adt75, + adt75_show_oti_mode, adt75_set_oti_mode, 0); +IIO_EVENT_ATTR_SH(available_oti_modes, iio_event_adt75, + adt75_show_available_oti_modes, NULL, 0); +IIO_EVENT_ATTR_SH(smbus_alart, iio_event_adt75, + adt75_show_smbus_alart, adt75_set_smbus_alart, 0); +IIO_EVENT_ATTR_SH(fault_queue, iio_event_adt75, + adt75_show_fault_queue, adt75_set_fault_queue, 0); +IIO_EVENT_ATTR_SH(t_os, iio_event_adt75, + adt75_show_t_os, adt75_set_t_os, 0); +IIO_EVENT_ATTR_SH(t_hyst, iio_event_adt75, + adt75_show_t_hyst, adt75_set_t_hyst, 0); + +static struct attribute *adt75_event_attributes[] = { + &iio_event_attr_oti_mode.dev_attr.attr, + &iio_event_attr_available_oti_modes.dev_attr.attr, + &iio_event_attr_smbus_alart.dev_attr.attr, + &iio_event_attr_fault_queue.dev_attr.attr, + &iio_event_attr_t_os.dev_attr.attr, + &iio_event_attr_t_hyst.dev_attr.attr, + NULL, +}; + +static struct attribute_group adt75_event_attribute_group = { + .attrs = adt75_event_attributes, +}; + +/* + * device probe and remove + */ + +static int __devinit adt75_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct adt75_chip_info *chip; + int ret = 0; + + chip = kzalloc(sizeof(struct adt75_chip_info), GFP_KERNEL); + + if (chip == NULL) + return -ENOMEM; + + /* this is only used for device removal purposes */ + i2c_set_clientdata(client, chip); + + chip->client = client; + chip->name = id->name; + + chip->indio_dev = iio_allocate_device(); + if (chip->indio_dev == NULL) { + ret = -ENOMEM; + goto error_free_chip; + } + + chip->indio_dev->dev.parent = &client->dev; + chip->indio_dev->attrs = &adt75_attribute_group; + chip->indio_dev->event_attrs = &adt75_event_attribute_group; + chip->indio_dev->dev_data = (void *)chip; + chip->indio_dev->driver_module = THIS_MODULE; + chip->indio_dev->num_interrupt_lines = 1; + chip->indio_dev->modes = INDIO_DIRECT_MODE; + + ret = iio_device_register(chip->indio_dev); + if (ret) + goto error_free_dev; + + if (client->irq > 0) { + ret = iio_register_interrupt_line(client->irq, + chip->indio_dev, + 0, + IRQF_TRIGGER_LOW, + chip->name); + if (ret) + goto error_unreg_dev; + + /* + * The event handler list element refer to iio_event_adt75. + * All event attributes bind to the same event handler. + * So, only register event handler once. + */ + iio_add_event_to_list(&iio_event_adt75, + &chip->indio_dev->interrupts[0]->ev_list); + + INIT_WORK(&chip->thresh_work, adt75_interrupt_bh); + + ret = adt75_i2c_read(chip, ADT75_CONFIG, &chip->config); + if (ret) { + ret = -EIO; + goto error_unreg_irq; + } + + /* set irq polarity low level */ + chip->config &= ~ADT75_OS_POLARITY; + + ret = adt75_i2c_write(chip, ADT75_CONFIG, chip->config); + if (ret) { + ret = -EIO; + goto error_unreg_irq; + } + } + + dev_info(&client->dev, "%s temperature sensor registered.\n", + id->name); + + return 0; +error_unreg_irq: + iio_unregister_interrupt_line(chip->indio_dev, 0); +error_unreg_dev: + iio_device_unregister(chip->indio_dev); +error_free_dev: + iio_free_device(chip->indio_dev); +error_free_chip: + kfree(chip); + + return ret; +} + +static int __devexit adt75_remove(struct i2c_client *client) +{ + struct adt75_chip_info *chip = i2c_get_clientdata(client); + struct iio_dev *indio_dev = chip->indio_dev; + + if (client->irq) + iio_unregister_interrupt_line(indio_dev, 0); + iio_device_unregister(indio_dev); + iio_free_device(chip->indio_dev); + kfree(chip); + + return 0; +} + +static const struct i2c_device_id adt75_id[] = { + { "adt75", 0 }, + {} +}; + +MODULE_DEVICE_TABLE(i2c, adt75_id); + +static struct i2c_driver adt75_driver = { + .driver = { + .name = "adt75", + }, + .probe = adt75_probe, + .remove = __devexit_p(adt75_remove), + .id_table = adt75_id, +}; + +static __init int adt75_init(void) +{ + return i2c_add_driver(&adt75_driver); +} + +static __exit void adt75_exit(void) +{ + i2c_del_driver(&adt75_driver); +} + +MODULE_AUTHOR("Sonic Zhang "); +MODULE_DESCRIPTION("Analog Devices ADT75 digital" + " temperature sensor driver"); +MODULE_LICENSE("GPL v2"); + +module_init(adt75_init); +module_exit(adt75_exit); -- cgit v1.2.3 From a5d8c6bc2f87c1c5cb69fb3a22d1ef0110a9eacc Mon Sep 17 00:00:00 2001 From: Sonic Zhang Date: Wed, 27 Oct 2010 21:44:01 -0400 Subject: staging: iio: adc: new driver for ADT7310 temperature sensors Signed-off-by: Sonic Zhang Signed-off-by: Michael Hennerich Acked-by: Jonathan Cameron Signed-off-by: Mike Frysinger Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/adc/Kconfig | 7 + drivers/staging/iio/adc/Makefile | 1 + drivers/staging/iio/adc/adt7310.c | 952 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 960 insertions(+) create mode 100644 drivers/staging/iio/adc/adt7310.c diff --git a/drivers/staging/iio/adc/Kconfig b/drivers/staging/iio/adc/Kconfig index a7c6b818dbb7..cd355260f794 100644 --- a/drivers/staging/iio/adc/Kconfig +++ b/drivers/staging/iio/adc/Kconfig @@ -120,3 +120,10 @@ config ADT75 help Say yes here to build support for Analog Devices ADT75 temperature sensors. + +config ADT7310 + tristate "Analog Devices ADT7310 temperature sensor driver" + depends on SPI + help + Say yes here to build support for Analog Devices ADT7310 + temperature sensors. diff --git a/drivers/staging/iio/adc/Makefile b/drivers/staging/iio/adc/Makefile index d1f1b5720cdf..6067b66f6a0b 100644 --- a/drivers/staging/iio/adc/Makefile +++ b/drivers/staging/iio/adc/Makefile @@ -23,3 +23,4 @@ obj-$(CONFIG_AD7314) += ad7314.o obj-$(CONFIG_AD7745) += ad7745.o obj-$(CONFIG_AD7816) += ad7816.o obj-$(CONFIG_ADT75) += adt75.o +obj-$(CONFIG_ADT7310) += adt7310.o diff --git a/drivers/staging/iio/adc/adt7310.c b/drivers/staging/iio/adc/adt7310.c new file mode 100644 index 000000000000..771a409ee94c --- /dev/null +++ b/drivers/staging/iio/adc/adt7310.c @@ -0,0 +1,952 @@ +/* + * ADT7310 digital temperature sensor driver supporting ADT7310 + * + * Copyright 2010 Analog Devices Inc. + * + * Licensed under the GPL-2 or later. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../iio.h" +#include "../sysfs.h" + +/* + * ADT7310 registers definition + */ + +#define ADT7310_STATUS 0 +#define ADT7310_CONFIG 1 +#define ADT7310_TEMPERATURE 2 +#define ADT7310_ID 3 +#define ADT7310_T_CRIT 4 +#define ADT7310_T_HYST 5 +#define ADT7310_T_ALARM_HIGH 6 +#define ADT7310_T_ALARM_LOW 7 + +/* + * ADT7310 status + */ +#define ADT7310_STAT_T_LOW 0x10 +#define ADT7310_STAT_T_HIGH 0x20 +#define ADT7310_STAT_T_CRIT 0x40 +#define ADT7310_STAT_NOT_RDY 0x80 + +/* + * ADT7310 config + */ +#define ADT7310_FAULT_QUEUE_MASK 0x3 +#define ADT7310_CT_POLARITY 0x4 +#define ADT7310_INT_POLARITY 0x8 +#define ADT7310_EVENT_MODE 0x10 +#define ADT7310_MODE_MASK 0x60 +#define ADT7310_ONESHOT 0x20 +#define ADT7310_SPS 0x40 +#define ADT7310_PD 0x60 +#define ADT7310_RESOLUTION 0x80 + +/* + * ADT7310 masks + */ +#define ADT7310_T16_VALUE_SIGN 0x8000 +#define ADT7310_T16_VALUE_FLOAT_OFFSET 7 +#define ADT7310_T16_VALUE_FLOAT_MASK 0x7F +#define ADT7310_T13_VALUE_SIGN 0x1000 +#define ADT7310_T13_VALUE_OFFSET 3 +#define ADT7310_T13_VALUE_FLOAT_OFFSET 4 +#define ADT7310_T13_VALUE_FLOAT_MASK 0xF +#define ADT7310_T_HYST_MASK 0xF +#define ADT7310_DEVICE_ID_MASK 0x7 +#define ADT7310_MANUFACTORY_ID_MASK 0xF8 +#define ADT7310_MANUFACTORY_ID_OFFSET 3 + + +#define ADT7310_CMD_REG_MASK 0x28 +#define ADT7310_CMD_REG_OFFSET 3 +#define ADT7310_CMD_READ 0x40 +#define ADT7310_CMD_CON_READ 0x4 + +#define ADT7310_IRQS 2 + +/* + * struct adt7310_chip_info - chip specifc information + */ + +struct adt7310_chip_info { + const char *name; + struct spi_device *spi_dev; + struct iio_dev *indio_dev; + struct work_struct thresh_work; + s64 last_timestamp; + u8 config; +}; + +/* + * adt7310 register access by SPI + */ + +static int adt7310_spi_read_word(struct adt7310_chip_info *chip, u8 reg, u16 *data) +{ + struct spi_device *spi_dev = chip->spi_dev; + u8 command = (reg << ADT7310_CMD_REG_OFFSET) & ADT7310_CMD_REG_MASK; + int ret = 0; + + command |= ADT7310_CMD_READ; + ret = spi_write(spi_dev, &command, sizeof(command)); + if (ret < 0) { + dev_err(&spi_dev->dev, "SPI write command error\n"); + return ret; + } + + ret = spi_read(spi_dev, (u8 *)data, sizeof(*data)); + if (ret < 0) { + dev_err(&spi_dev->dev, "SPI read word error\n"); + return ret; + } + + *data = be16_to_cpu(*data); + + return 0; +} + +static int adt7310_spi_write_word(struct adt7310_chip_info *chip, u8 reg, u16 data) +{ + struct spi_device *spi_dev = chip->spi_dev; + u8 buf[3]; + int ret = 0; + + buf[0] = (reg << ADT7310_CMD_REG_OFFSET) & ADT7310_CMD_REG_MASK; + buf[1] = (u8)(data >> 8); + buf[2] = (u8)(data & 0xFF); + + ret = spi_write(spi_dev, buf, 3); + if (ret < 0) { + dev_err(&spi_dev->dev, "SPI write word error\n"); + return ret; + } + + return ret; +} + +static int adt7310_spi_read_byte(struct adt7310_chip_info *chip, u8 reg, u8 *data) +{ + struct spi_device *spi_dev = chip->spi_dev; + u8 command = (reg << ADT7310_CMD_REG_OFFSET) & ADT7310_CMD_REG_MASK; + int ret = 0; + + command |= ADT7310_CMD_READ; + ret = spi_write(spi_dev, &command, sizeof(command)); + if (ret < 0) { + dev_err(&spi_dev->dev, "SPI write command error\n"); + return ret; + } + + ret = spi_read(spi_dev, data, sizeof(*data)); + if (ret < 0) { + dev_err(&spi_dev->dev, "SPI read byte error\n"); + return ret; + } + + return 0; +} + +static int adt7310_spi_write_byte(struct adt7310_chip_info *chip, u8 reg, u8 data) +{ + struct spi_device *spi_dev = chip->spi_dev; + u8 buf[2]; + int ret = 0; + + buf[0] = (reg << ADT7310_CMD_REG_OFFSET) & ADT7310_CMD_REG_MASK; + buf[1] = data; + + ret = spi_write(spi_dev, buf, 2); + if (ret < 0) { + dev_err(&spi_dev->dev, "SPI write byte error\n"); + return ret; + } + + return ret; +} + +static ssize_t adt7310_show_mode(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct adt7310_chip_info *chip = dev_info->dev_data; + u8 config; + + config = chip->config & ADT7310_MODE_MASK; + + switch (config) { + case ADT7310_PD: + return sprintf(buf, "power-down\n"); + case ADT7310_ONESHOT: + return sprintf(buf, "one-shot\n"); + case ADT7310_SPS: + return sprintf(buf, "sps\n"); + default: + return sprintf(buf, "full\n"); + } +} + +static ssize_t adt7310_store_mode(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct adt7310_chip_info *chip = dev_info->dev_data; + u16 config; + int ret; + + ret = adt7310_spi_read_byte(chip, ADT7310_CONFIG, &chip->config); + if (ret) + return -EIO; + + config = chip->config & (~ADT7310_MODE_MASK); + if (strcmp(buf, "power-down")) + config |= ADT7310_PD; + else if (strcmp(buf, "one-shot")) + config |= ADT7310_ONESHOT; + else if (strcmp(buf, "sps")) + config |= ADT7310_SPS; + + ret = adt7310_spi_write_byte(chip, ADT7310_CONFIG, config); + if (ret) + return -EIO; + + chip->config = config; + + return len; +} + +static IIO_DEVICE_ATTR(mode, S_IRUGO | S_IWUSR, + adt7310_show_mode, + adt7310_store_mode, + 0); + +static ssize_t adt7310_show_available_modes(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + return sprintf(buf, "full\none-shot\nsps\npower-down\n"); +} + +static IIO_DEVICE_ATTR(available_modes, S_IRUGO, adt7310_show_available_modes, NULL, 0); + +static ssize_t adt7310_show_resolution(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct adt7310_chip_info *chip = dev_info->dev_data; + int ret; + int bits; + + ret = adt7310_spi_read_byte(chip, ADT7310_CONFIG, &chip->config); + if (ret) + return -EIO; + + if (chip->config & ADT7310_RESOLUTION) + bits = 16; + else + bits = 13; + + return sprintf(buf, "%d bits\n", bits); +} + +static ssize_t adt7310_store_resolution(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct adt7310_chip_info *chip = dev_info->dev_data; + unsigned long data; + u16 config; + int ret; + + ret = strict_strtoul(buf, 10, &data); + if (ret) + return -EINVAL; + + ret = adt7310_spi_read_byte(chip, ADT7310_CONFIG, &chip->config); + if (ret) + return -EIO; + + config = chip->config & (~ADT7310_RESOLUTION); + if (data) + config |= ADT7310_RESOLUTION; + + ret = adt7310_spi_write_byte(chip, ADT7310_CONFIG, config); + if (ret) + return -EIO; + + chip->config = config; + + return len; +} + +static IIO_DEVICE_ATTR(resolution, S_IRUGO | S_IWUSR, + adt7310_show_resolution, + adt7310_store_resolution, + 0); + +static ssize_t adt7310_show_id(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct adt7310_chip_info *chip = dev_info->dev_data; + u8 id; + int ret; + + ret = adt7310_spi_read_byte(chip, ADT7310_ID, &id); + if (ret) + return -EIO; + + return sprintf(buf, "device id: 0x%x\nmanufactory id: 0x%x\n", + id & ADT7310_DEVICE_ID_MASK, + (id & ADT7310_MANUFACTORY_ID_MASK) >> ADT7310_MANUFACTORY_ID_OFFSET); +} + +static IIO_DEVICE_ATTR(id, S_IRUGO | S_IWUSR, + adt7310_show_id, + NULL, + 0); + +static ssize_t adt7310_convert_temperature(struct adt7310_chip_info *chip, + u16 data, char *buf) +{ + char sign = ' '; + + if (chip->config & ADT7310_RESOLUTION) { + if (data & ADT7310_T16_VALUE_SIGN) { + /* convert supplement to positive value */ + data = (u16)((ADT7310_T16_VALUE_SIGN << 1) - (u32)data); + sign = '-'; + } + return sprintf(buf, "%c%d.%.7d\n", sign, + (data >> ADT7310_T16_VALUE_FLOAT_OFFSET), + (data & ADT7310_T16_VALUE_FLOAT_MASK) * 78125); + } else { + if (data & ADT7310_T13_VALUE_SIGN) { + /* convert supplement to positive value */ + data >>= ADT7310_T13_VALUE_OFFSET; + data = (ADT7310_T13_VALUE_SIGN << 1) - data; + sign = '-'; + } + return sprintf(buf, "%c%d.%.4d\n", sign, + (data >> ADT7310_T13_VALUE_FLOAT_OFFSET), + (data & ADT7310_T13_VALUE_FLOAT_MASK) * 625); + } +} + +static ssize_t adt7310_show_value(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct adt7310_chip_info *chip = dev_info->dev_data; + u8 status; + u16 data; + int ret, i = 0; + + do { + ret = adt7310_spi_read_byte(chip, ADT7310_STATUS, &status); + if (ret) + return -EIO; + i++; + if (i == 10000) + return -EIO; + } while (status & ADT7310_STAT_NOT_RDY); + + ret = adt7310_spi_read_word(chip, ADT7310_TEMPERATURE, &data); + if (ret) + return -EIO; + + return adt7310_convert_temperature(chip, data, buf); +} + +static IIO_DEVICE_ATTR(value, S_IRUGO, adt7310_show_value, NULL, 0); + +static ssize_t adt7310_show_name(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct adt7310_chip_info *chip = dev_info->dev_data; + return sprintf(buf, "%s\n", chip->name); +} + +static IIO_DEVICE_ATTR(name, S_IRUGO, adt7310_show_name, NULL, 0); + +static struct attribute *adt7310_attributes[] = { + &iio_dev_attr_available_modes.dev_attr.attr, + &iio_dev_attr_mode.dev_attr.attr, + &iio_dev_attr_resolution.dev_attr.attr, + &iio_dev_attr_id.dev_attr.attr, + &iio_dev_attr_value.dev_attr.attr, + &iio_dev_attr_name.dev_attr.attr, + NULL, +}; + +static const struct attribute_group adt7310_attribute_group = { + .attrs = adt7310_attributes, +}; + +/* + * temperature bound events + */ + +#define IIO_EVENT_CODE_ADT7310_ABOVE_ALARM IIO_BUFFER_EVENT_CODE(0) +#define IIO_EVENT_CODE_ADT7310_BELLOW_ALARM IIO_BUFFER_EVENT_CODE(1) +#define IIO_EVENT_CODE_ADT7310_ABOVE_CRIT IIO_BUFFER_EVENT_CODE(2) + +static void adt7310_interrupt_bh(struct work_struct *work_s) +{ + struct adt7310_chip_info *chip = + container_of(work_s, struct adt7310_chip_info, thresh_work); + u8 status; + + if (adt7310_spi_read_byte(chip, ADT7310_STATUS, &status)) + return; + + if (status & ADT7310_STAT_T_HIGH) + iio_push_event(chip->indio_dev, 0, + IIO_EVENT_CODE_ADT7310_ABOVE_ALARM, + chip->last_timestamp); + if (status & ADT7310_STAT_T_LOW) + iio_push_event(chip->indio_dev, 0, + IIO_EVENT_CODE_ADT7310_BELLOW_ALARM, + chip->last_timestamp); + if (status & ADT7310_STAT_T_CRIT) + iio_push_event(chip->indio_dev, 0, + IIO_EVENT_CODE_ADT7310_ABOVE_CRIT, + chip->last_timestamp); +} + +static int adt7310_interrupt(struct iio_dev *dev_info, + int index, + s64 timestamp, + int no_test) +{ + struct adt7310_chip_info *chip = dev_info->dev_data; + + chip->last_timestamp = timestamp; + schedule_work(&chip->thresh_work); + + return 0; +} + +IIO_EVENT_SH(adt7310, &adt7310_interrupt); +IIO_EVENT_SH(adt7310_ct, &adt7310_interrupt); + +static ssize_t adt7310_show_event_mode(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct adt7310_chip_info *chip = dev_info->dev_data; + int ret; + + ret = adt7310_spi_read_byte(chip, ADT7310_CONFIG, &chip->config); + if (ret) + return -EIO; + + if (chip->config & ADT7310_EVENT_MODE) + return sprintf(buf, "interrupt\n"); + else + return sprintf(buf, "comparator\n"); +} + +static ssize_t adt7310_set_event_mode(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct adt7310_chip_info *chip = dev_info->dev_data; + u16 config; + int ret; + + ret = adt7310_spi_read_byte(chip, ADT7310_CONFIG, &chip->config); + if (ret) + return -EIO; + + config = chip->config &= ~ADT7310_EVENT_MODE; + if (strcmp(buf, "comparator") != 0) + config |= ADT7310_EVENT_MODE; + + ret = adt7310_spi_write_byte(chip, ADT7310_CONFIG, config); + if (ret) + return -EIO; + + chip->config = config; + + return len; +} + +static ssize_t adt7310_show_available_event_modes(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + return sprintf(buf, "comparator\ninterrupt\n"); +} + +static ssize_t adt7310_show_fault_queue(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct adt7310_chip_info *chip = dev_info->dev_data; + int ret; + + ret = adt7310_spi_read_byte(chip, ADT7310_CONFIG, &chip->config); + if (ret) + return -EIO; + + return sprintf(buf, "%d\n", chip->config & ADT7310_FAULT_QUEUE_MASK); +} + +static ssize_t adt7310_set_fault_queue(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct adt7310_chip_info *chip = dev_info->dev_data; + unsigned long data; + int ret; + u8 config; + + ret = strict_strtoul(buf, 10, &data); + if (ret || data > 3) + return -EINVAL; + + ret = adt7310_spi_read_byte(chip, ADT7310_CONFIG, &chip->config); + if (ret) + return -EIO; + + config = chip->config & ~ADT7310_FAULT_QUEUE_MASK; + config |= data; + ret = adt7310_spi_write_byte(chip, ADT7310_CONFIG, config); + if (ret) + return -EIO; + + chip->config = config; + + return len; +} + +static inline ssize_t adt7310_show_t_bound(struct device *dev, + struct device_attribute *attr, + u8 bound_reg, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct adt7310_chip_info *chip = dev_info->dev_data; + u16 data; + int ret; + + ret = adt7310_spi_read_word(chip, bound_reg, &data); + if (ret) + return -EIO; + + return adt7310_convert_temperature(chip, data, buf); +} + +static inline ssize_t adt7310_set_t_bound(struct device *dev, + struct device_attribute *attr, + u8 bound_reg, + const char *buf, + size_t len) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct adt7310_chip_info *chip = dev_info->dev_data; + long tmp1, tmp2; + u16 data; + char *pos; + int ret; + + pos = strchr(buf, '.'); + + ret = strict_strtol(buf, 10, &tmp1); + + if (ret || tmp1 > 127 || tmp1 < -128) + return -EINVAL; + + if (pos) { + len = strlen(pos); + + if (chip->config & ADT7310_RESOLUTION) { + if (len > ADT7310_T16_VALUE_FLOAT_OFFSET) + len = ADT7310_T16_VALUE_FLOAT_OFFSET; + pos[len] = 0; + ret = strict_strtol(pos, 10, &tmp2); + + if (!ret) + tmp2 = (tmp2 / 78125) * 78125; + } else { + if (len > ADT7310_T13_VALUE_FLOAT_OFFSET) + len = ADT7310_T13_VALUE_FLOAT_OFFSET; + pos[len] = 0; + ret = strict_strtol(pos, 10, &tmp2); + + if (!ret) + tmp2 = (tmp2 / 625) * 625; + } + } + + if (tmp1 < 0) + data = (u16)(-tmp1); + else + data = (u16)tmp1; + + if (chip->config & ADT7310_RESOLUTION) { + data = (data << ADT7310_T16_VALUE_FLOAT_OFFSET) | + (tmp2 & ADT7310_T16_VALUE_FLOAT_MASK); + + if (tmp1 < 0) + /* convert positive value to supplyment */ + data = (u16)((ADT7310_T16_VALUE_SIGN << 1) - (u32)data); + } else { + data = (data << ADT7310_T13_VALUE_FLOAT_OFFSET) | + (tmp2 & ADT7310_T13_VALUE_FLOAT_MASK); + + if (tmp1 < 0) + /* convert positive value to supplyment */ + data = (ADT7310_T13_VALUE_SIGN << 1) - data; + data <<= ADT7310_T13_VALUE_OFFSET; + } + + ret = adt7310_spi_write_word(chip, bound_reg, data); + if (ret) + return -EIO; + + return len; +} + +static ssize_t adt7310_show_t_alarm_high(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + return adt7310_show_t_bound(dev, attr, + ADT7310_T_ALARM_HIGH, buf); +} + +static inline ssize_t adt7310_set_t_alarm_high(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + return adt7310_set_t_bound(dev, attr, + ADT7310_T_ALARM_HIGH, buf, len); +} + +static ssize_t adt7310_show_t_alarm_low(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + return adt7310_show_t_bound(dev, attr, + ADT7310_T_ALARM_LOW, buf); +} + +static inline ssize_t adt7310_set_t_alarm_low(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + return adt7310_set_t_bound(dev, attr, + ADT7310_T_ALARM_LOW, buf, len); +} + +static ssize_t adt7310_show_t_crit(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + return adt7310_show_t_bound(dev, attr, + ADT7310_T_CRIT, buf); +} + +static inline ssize_t adt7310_set_t_crit(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + return adt7310_set_t_bound(dev, attr, + ADT7310_T_CRIT, buf, len); +} + +static ssize_t adt7310_show_t_hyst(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct adt7310_chip_info *chip = dev_info->dev_data; + int ret; + u8 t_hyst; + + ret = adt7310_spi_read_byte(chip, ADT7310_T_HYST, &t_hyst); + if (ret) + return -EIO; + + return sprintf(buf, "%d\n", t_hyst & ADT7310_T_HYST_MASK); +} + +static inline ssize_t adt7310_set_t_hyst(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct adt7310_chip_info *chip = dev_info->dev_data; + int ret; + unsigned long data; + u8 t_hyst; + + ret = strict_strtol(buf, 10, &data); + + if (ret || data > ADT7310_T_HYST_MASK) + return -EINVAL; + + t_hyst = (u8)data; + + ret = adt7310_spi_write_byte(chip, ADT7310_T_HYST, t_hyst); + if (ret) + return -EIO; + + return len; +} + +IIO_EVENT_ATTR_SH(event_mode, iio_event_adt7310, + adt7310_show_event_mode, adt7310_set_event_mode, 0); +IIO_EVENT_ATTR_SH(available_event_modes, iio_event_adt7310, + adt7310_show_available_event_modes, NULL, 0); +IIO_EVENT_ATTR_SH(fault_queue, iio_event_adt7310, + adt7310_show_fault_queue, adt7310_set_fault_queue, 0); +IIO_EVENT_ATTR_SH(t_alarm_high, iio_event_adt7310, + adt7310_show_t_alarm_high, adt7310_set_t_alarm_high, 0); +IIO_EVENT_ATTR_SH(t_alarm_low, iio_event_adt7310, + adt7310_show_t_alarm_low, adt7310_set_t_alarm_low, 0); +IIO_EVENT_ATTR_SH(t_crit, iio_event_adt7310_ct, + adt7310_show_t_crit, adt7310_set_t_crit, 0); +IIO_EVENT_ATTR_SH(t_hyst, iio_event_adt7310, + adt7310_show_t_hyst, adt7310_set_t_hyst, 0); + +static struct attribute *adt7310_event_int_attributes[] = { + &iio_event_attr_event_mode.dev_attr.attr, + &iio_event_attr_available_event_modes.dev_attr.attr, + &iio_event_attr_fault_queue.dev_attr.attr, + &iio_event_attr_t_alarm_high.dev_attr.attr, + &iio_event_attr_t_alarm_low.dev_attr.attr, + &iio_event_attr_t_hyst.dev_attr.attr, + NULL, +}; + +static struct attribute *adt7310_event_ct_attributes[] = { + &iio_event_attr_event_mode.dev_attr.attr, + &iio_event_attr_available_event_modes.dev_attr.attr, + &iio_event_attr_fault_queue.dev_attr.attr, + &iio_event_attr_t_crit.dev_attr.attr, + &iio_event_attr_t_hyst.dev_attr.attr, + NULL, +}; + +static struct attribute_group adt7310_event_attribute_group[ADT7310_IRQS] = { + { + .attrs = adt7310_event_int_attributes, + }, + { + .attrs = adt7310_event_ct_attributes, + } +}; + +/* + * device probe and remove + */ + +static int __devinit adt7310_probe(struct spi_device *spi_dev) +{ + struct adt7310_chip_info *chip; + int ret = 0; + unsigned long *adt7310_platform_data = spi_dev->dev.platform_data; + unsigned long irq_flags; + + chip = kzalloc(sizeof(struct adt7310_chip_info), GFP_KERNEL); + + if (chip == NULL) + return -ENOMEM; + + /* this is only used for device removal purposes */ + dev_set_drvdata(&spi_dev->dev, chip); + + chip->spi_dev = spi_dev; + chip->name = spi_dev->modalias; + + chip->indio_dev = iio_allocate_device(); + if (chip->indio_dev == NULL) { + ret = -ENOMEM; + goto error_free_chip; + } + + chip->indio_dev->dev.parent = &spi_dev->dev; + chip->indio_dev->attrs = &adt7310_attribute_group; + chip->indio_dev->event_attrs = adt7310_event_attribute_group; + chip->indio_dev->dev_data = (void *)chip; + chip->indio_dev->driver_module = THIS_MODULE; + chip->indio_dev->num_interrupt_lines = ADT7310_IRQS; + chip->indio_dev->modes = INDIO_DIRECT_MODE; + + ret = iio_device_register(chip->indio_dev); + if (ret) + goto error_free_dev; + + /* CT critcal temperature event. line 0 */ + if (spi_dev->irq) { + if (adt7310_platform_data[2]) + irq_flags = adt7310_platform_data[2]; + else + irq_flags = IRQF_TRIGGER_LOW; + ret = iio_register_interrupt_line(spi_dev->irq, + chip->indio_dev, + 0, + irq_flags, + chip->name); + if (ret) + goto error_unreg_dev; + + /* + * The event handler list element refer to iio_event_adt7310. + * All event attributes bind to the same event handler. + * One event handler can only be added to one event list. + */ + iio_add_event_to_list(&iio_event_adt7310, + &chip->indio_dev->interrupts[0]->ev_list); + } + + /* INT bound temperature alarm event. line 1 */ + if (adt7310_platform_data[0]) { + ret = iio_register_interrupt_line(adt7310_platform_data[0], + chip->indio_dev, + 1, + adt7310_platform_data[1], + chip->name); + if (ret) + goto error_unreg_ct_irq; + + /* + * The event handler list element refer to iio_event_adt7310. + * All event attributes bind to the same event handler. + * One event handler can only be added to one event list. + */ + iio_add_event_to_list(&iio_event_adt7310_ct, + &chip->indio_dev->interrupts[1]->ev_list); + } + + if (spi_dev->irq && adt7310_platform_data[0]) { + INIT_WORK(&chip->thresh_work, adt7310_interrupt_bh); + + ret = adt7310_spi_read_byte(chip, ADT7310_CONFIG, &chip->config); + if (ret) { + ret = -EIO; + goto error_unreg_int_irq; + } + + /* set irq polarity low level */ + chip->config &= ~ADT7310_CT_POLARITY; + + if (adt7310_platform_data[1] & IRQF_TRIGGER_HIGH) + chip->config |= ADT7310_INT_POLARITY; + else + chip->config &= ~ADT7310_INT_POLARITY; + + ret = adt7310_spi_write_byte(chip, ADT7310_CONFIG, chip->config); + if (ret) { + ret = -EIO; + goto error_unreg_int_irq; + } + } + + dev_info(&spi_dev->dev, "%s temperature sensor registered.\n", + chip->name); + + return 0; + +error_unreg_int_irq: + iio_unregister_interrupt_line(chip->indio_dev, 1); +error_unreg_ct_irq: + iio_unregister_interrupt_line(chip->indio_dev, 0); +error_unreg_dev: + iio_device_unregister(chip->indio_dev); +error_free_dev: + iio_free_device(chip->indio_dev); +error_free_chip: + kfree(chip); + + return ret; +} + +static int __devexit adt7310_remove(struct spi_device *spi_dev) +{ + struct adt7310_chip_info *chip = dev_get_drvdata(&spi_dev->dev); + struct iio_dev *indio_dev = chip->indio_dev; + unsigned long *adt7310_platform_data = spi_dev->dev.platform_data; + + dev_set_drvdata(&spi_dev->dev, NULL); + if (adt7310_platform_data[0]) + iio_unregister_interrupt_line(indio_dev, 1); + if (spi_dev->irq) + iio_unregister_interrupt_line(indio_dev, 0); + iio_device_unregister(indio_dev); + iio_free_device(chip->indio_dev); + kfree(chip); + + return 0; +} + +static const struct spi_device_id adt7310_id[] = { + { "adt7310", 0 }, + {} +}; + +MODULE_DEVICE_TABLE(spi, adt7310_id); + +static struct spi_driver adt7310_driver = { + .driver = { + .name = "adt7310", + .bus = &spi_bus_type, + .owner = THIS_MODULE, + }, + .probe = adt7310_probe, + .remove = __devexit_p(adt7310_remove), + .id_table = adt7310_id, +}; + +static __init int adt7310_init(void) +{ + return spi_register_driver(&adt7310_driver); +} + +static __exit void adt7310_exit(void) +{ + spi_unregister_driver(&adt7310_driver); +} + +MODULE_AUTHOR("Sonic Zhang "); +MODULE_DESCRIPTION("Analog Devices ADT7310 digital" + " temperature sensor driver"); +MODULE_LICENSE("GPL v2"); + +module_init(adt7310_init); +module_exit(adt7310_exit); -- cgit v1.2.3 From 06b86a75b148e44d489a960c047a8fc6926c841d Mon Sep 17 00:00:00 2001 From: Sonic Zhang Date: Wed, 27 Oct 2010 21:44:02 -0400 Subject: staging: iio: adc: new driver for ADT7410 temperature sensors Signed-off-by: Sonic Zhang Signed-off-by: Michael Hennerich Acked-by: Jonathan Cameron Signed-off-by: Mike Frysinger Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/adc/Kconfig | 7 + drivers/staging/iio/adc/Makefile | 1 + drivers/staging/iio/adc/adt7410.c | 915 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 923 insertions(+) create mode 100644 drivers/staging/iio/adc/adt7410.c diff --git a/drivers/staging/iio/adc/Kconfig b/drivers/staging/iio/adc/Kconfig index cd355260f794..9ca6565d2bae 100644 --- a/drivers/staging/iio/adc/Kconfig +++ b/drivers/staging/iio/adc/Kconfig @@ -127,3 +127,10 @@ config ADT7310 help Say yes here to build support for Analog Devices ADT7310 temperature sensors. + +config ADT7410 + tristate "Analog Devices ADT7410 temperature sensor driver" + depends on I2C + help + Say yes here to build support for Analog Devices ADT7410 + temperature sensors. diff --git a/drivers/staging/iio/adc/Makefile b/drivers/staging/iio/adc/Makefile index 6067b66f6a0b..a7dce6bd5f3a 100644 --- a/drivers/staging/iio/adc/Makefile +++ b/drivers/staging/iio/adc/Makefile @@ -24,3 +24,4 @@ obj-$(CONFIG_AD7745) += ad7745.o obj-$(CONFIG_AD7816) += ad7816.o obj-$(CONFIG_ADT75) += adt75.o obj-$(CONFIG_ADT7310) += adt7310.o +obj-$(CONFIG_ADT7410) += adt7410.o diff --git a/drivers/staging/iio/adc/adt7410.c b/drivers/staging/iio/adc/adt7410.c new file mode 100644 index 000000000000..c345f27ec7fc --- /dev/null +++ b/drivers/staging/iio/adc/adt7410.c @@ -0,0 +1,915 @@ +/* + * ADT7410 digital temperature sensor driver supporting ADT7410 + * + * Copyright 2010 Analog Devices Inc. + * + * Licensed under the GPL-2 or later. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../iio.h" +#include "../sysfs.h" + +/* + * ADT7410 registers definition + */ + +#define ADT7410_TEMPERATURE 0 +#define ADT7410_STATUS 2 +#define ADT7410_CONFIG 3 +#define ADT7410_T_ALARM_HIGH 4 +#define ADT7410_T_ALARM_LOW 6 +#define ADT7410_T_CRIT 8 +#define ADT7410_T_HYST 0xA +#define ADT7410_ID 0xB +#define ADT7410_RESET 0x2F + +/* + * ADT7410 status + */ +#define ADT7410_STAT_T_LOW 0x10 +#define ADT7410_STAT_T_HIGH 0x20 +#define ADT7410_STAT_T_CRIT 0x40 +#define ADT7410_STAT_NOT_RDY 0x80 + +/* + * ADT7410 config + */ +#define ADT7410_FAULT_QUEUE_MASK 0x3 +#define ADT7410_CT_POLARITY 0x4 +#define ADT7410_INT_POLARITY 0x8 +#define ADT7410_EVENT_MODE 0x10 +#define ADT7410_MODE_MASK 0x60 +#define ADT7410_ONESHOT 0x20 +#define ADT7410_SPS 0x40 +#define ADT7410_PD 0x60 +#define ADT7410_RESOLUTION 0x80 + +/* + * ADT7410 masks + */ +#define ADT7410_T16_VALUE_SIGN 0x8000 +#define ADT7410_T16_VALUE_FLOAT_OFFSET 7 +#define ADT7410_T16_VALUE_FLOAT_MASK 0x7F +#define ADT7410_T13_VALUE_SIGN 0x1000 +#define ADT7410_T13_VALUE_OFFSET 3 +#define ADT7410_T13_VALUE_FLOAT_OFFSET 4 +#define ADT7410_T13_VALUE_FLOAT_MASK 0xF +#define ADT7410_T_HYST_MASK 0xF +#define ADT7410_DEVICE_ID_MASK 0xF +#define ADT7410_MANUFACTORY_ID_MASK 0xF0 +#define ADT7410_MANUFACTORY_ID_OFFSET 4 + +#define ADT7410_IRQS 2 + +/* + * struct adt7410_chip_info - chip specifc information + */ + +struct adt7410_chip_info { + const char *name; + struct i2c_client *client; + struct iio_dev *indio_dev; + struct work_struct thresh_work; + s64 last_timestamp; + u8 config; +}; + +/* + * adt7410 register access by I2C + */ + +static int adt7410_i2c_read_word(struct adt7410_chip_info *chip, u8 reg, u16 *data) +{ + struct i2c_client *client = chip->client; + int ret = 0; + + ret = i2c_smbus_read_word_data(client, reg); + if (ret < 0) { + dev_err(&client->dev, "I2C read error\n"); + return ret; + } + + *data = swab16((u16)ret); + + return 0; +} + +static int adt7410_i2c_write_word(struct adt7410_chip_info *chip, u8 reg, u16 data) +{ + struct i2c_client *client = chip->client; + int ret = 0; + + ret = i2c_smbus_write_word_data(client, reg, swab16(data)); + if (ret < 0) + dev_err(&client->dev, "I2C write error\n"); + + return ret; +} + +static int adt7410_i2c_read_byte(struct adt7410_chip_info *chip, u8 reg, u8 *data) +{ + struct i2c_client *client = chip->client; + int ret = 0; + + ret = i2c_smbus_read_byte_data(client, reg); + if (ret < 0) { + dev_err(&client->dev, "I2C read error\n"); + return ret; + } + + *data = (u8)ret; + + return 0; +} + +static int adt7410_i2c_write_byte(struct adt7410_chip_info *chip, u8 reg, u8 data) +{ + struct i2c_client *client = chip->client; + int ret = 0; + + ret = i2c_smbus_write_byte_data(client, reg, data); + if (ret < 0) + dev_err(&client->dev, "I2C write error\n"); + + return ret; +} + +static ssize_t adt7410_show_mode(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct adt7410_chip_info *chip = dev_info->dev_data; + u8 config; + + config = chip->config & ADT7410_MODE_MASK; + + switch (config) { + case ADT7410_PD: + return sprintf(buf, "power-down\n"); + case ADT7410_ONESHOT: + return sprintf(buf, "one-shot\n"); + case ADT7410_SPS: + return sprintf(buf, "sps\n"); + default: + return sprintf(buf, "full\n"); + } +} + +static ssize_t adt7410_store_mode(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct adt7410_chip_info *chip = dev_info->dev_data; + u16 config; + int ret; + + ret = adt7410_i2c_read_byte(chip, ADT7410_CONFIG, &chip->config); + if (ret) + return -EIO; + + config = chip->config & (~ADT7410_MODE_MASK); + if (strcmp(buf, "power-down")) + config |= ADT7410_PD; + else if (strcmp(buf, "one-shot")) + config |= ADT7410_ONESHOT; + else if (strcmp(buf, "sps")) + config |= ADT7410_SPS; + + ret = adt7410_i2c_write_byte(chip, ADT7410_CONFIG, config); + if (ret) + return -EIO; + + chip->config = config; + + return ret; +} + +static IIO_DEVICE_ATTR(mode, S_IRUGO | S_IWUSR, + adt7410_show_mode, + adt7410_store_mode, + 0); + +static ssize_t adt7410_show_available_modes(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + return sprintf(buf, "full\none-shot\nsps\npower-down\n"); +} + +static IIO_DEVICE_ATTR(available_modes, S_IRUGO, adt7410_show_available_modes, NULL, 0); + +static ssize_t adt7410_show_resolution(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct adt7410_chip_info *chip = dev_info->dev_data; + int ret; + int bits; + + ret = adt7410_i2c_read_byte(chip, ADT7410_CONFIG, &chip->config); + if (ret) + return -EIO; + + if (chip->config & ADT7410_RESOLUTION) + bits = 16; + else + bits = 13; + + return sprintf(buf, "%d bits\n", bits); +} + +static ssize_t adt7410_store_resolution(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct adt7410_chip_info *chip = dev_info->dev_data; + unsigned long data; + u16 config; + int ret; + + ret = strict_strtoul(buf, 10, &data); + if (ret) + return -EINVAL; + + ret = adt7410_i2c_read_byte(chip, ADT7410_CONFIG, &chip->config); + if (ret) + return -EIO; + + config = chip->config & (~ADT7410_RESOLUTION); + if (data) + config |= ADT7410_RESOLUTION; + + ret = adt7410_i2c_write_byte(chip, ADT7410_CONFIG, config); + if (ret) + return -EIO; + + chip->config = config; + + return ret; +} + +static IIO_DEVICE_ATTR(resolution, S_IRUGO | S_IWUSR, + adt7410_show_resolution, + adt7410_store_resolution, + 0); + +static ssize_t adt7410_show_id(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct adt7410_chip_info *chip = dev_info->dev_data; + u8 id; + int ret; + + ret = adt7410_i2c_read_byte(chip, ADT7410_ID, &id); + if (ret) + return -EIO; + + return sprintf(buf, "device id: 0x%x\nmanufactory id: 0x%x\n", + id & ADT7410_DEVICE_ID_MASK, + (id & ADT7410_MANUFACTORY_ID_MASK) >> ADT7410_MANUFACTORY_ID_OFFSET); +} + +static IIO_DEVICE_ATTR(id, S_IRUGO | S_IWUSR, + adt7410_show_id, + NULL, + 0); + +static ssize_t adt7410_convert_temperature(struct adt7410_chip_info *chip, + u16 data, char *buf) +{ + char sign = ' '; + + if (chip->config & ADT7410_RESOLUTION) { + if (data & ADT7410_T16_VALUE_SIGN) { + /* convert supplement to positive value */ + data = (u16)((ADT7410_T16_VALUE_SIGN << 1) - (u32)data); + sign = '-'; + } + return sprintf(buf, "%c%d.%.7d\n", sign, + (data >> ADT7410_T16_VALUE_FLOAT_OFFSET), + (data & ADT7410_T16_VALUE_FLOAT_MASK) * 78125); + } else { + if (data & ADT7410_T13_VALUE_SIGN) { + /* convert supplement to positive value */ + data >>= ADT7410_T13_VALUE_OFFSET; + data = (ADT7410_T13_VALUE_SIGN << 1) - data; + sign = '-'; + } + return sprintf(buf, "%c%d.%.4d\n", sign, + (data >> ADT7410_T13_VALUE_FLOAT_OFFSET), + (data & ADT7410_T13_VALUE_FLOAT_MASK) * 625); + } +} + +static ssize_t adt7410_show_value(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct adt7410_chip_info *chip = dev_info->dev_data; + u8 status; + u16 data; + int ret, i = 0; + + do { + ret = adt7410_i2c_read_byte(chip, ADT7410_STATUS, &status); + if (ret) + return -EIO; + i++; + if (i == 10000) + return -EIO; + } while (status & ADT7410_STAT_NOT_RDY); + + ret = adt7410_i2c_read_word(chip, ADT7410_TEMPERATURE, &data); + if (ret) + return -EIO; + + return adt7410_convert_temperature(chip, data, buf); +} + +static IIO_DEVICE_ATTR(value, S_IRUGO, adt7410_show_value, NULL, 0); + +static ssize_t adt7410_show_name(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct adt7410_chip_info *chip = dev_info->dev_data; + return sprintf(buf, "%s\n", chip->name); +} + +static IIO_DEVICE_ATTR(name, S_IRUGO, adt7410_show_name, NULL, 0); + +static struct attribute *adt7410_attributes[] = { + &iio_dev_attr_available_modes.dev_attr.attr, + &iio_dev_attr_mode.dev_attr.attr, + &iio_dev_attr_resolution.dev_attr.attr, + &iio_dev_attr_id.dev_attr.attr, + &iio_dev_attr_value.dev_attr.attr, + &iio_dev_attr_name.dev_attr.attr, + NULL, +}; + +static const struct attribute_group adt7410_attribute_group = { + .attrs = adt7410_attributes, +}; + +/* + * temperature bound events + */ + +#define IIO_EVENT_CODE_ADT7410_ABOVE_ALARM IIO_BUFFER_EVENT_CODE(0) +#define IIO_EVENT_CODE_ADT7410_BELLOW_ALARM IIO_BUFFER_EVENT_CODE(1) +#define IIO_EVENT_CODE_ADT7410_ABOVE_CRIT IIO_BUFFER_EVENT_CODE(2) + +static void adt7410_interrupt_bh(struct work_struct *work_s) +{ + struct adt7410_chip_info *chip = + container_of(work_s, struct adt7410_chip_info, thresh_work); + u8 status; + + if (adt7410_i2c_read_byte(chip, ADT7410_STATUS, &status)) + return; + + enable_irq(chip->client->irq); + + if (status & ADT7410_STAT_T_HIGH) + iio_push_event(chip->indio_dev, 0, + IIO_EVENT_CODE_ADT7410_ABOVE_ALARM, + chip->last_timestamp); + if (status & ADT7410_STAT_T_LOW) + iio_push_event(chip->indio_dev, 0, + IIO_EVENT_CODE_ADT7410_BELLOW_ALARM, + chip->last_timestamp); + if (status & ADT7410_STAT_T_CRIT) + iio_push_event(chip->indio_dev, 0, + IIO_EVENT_CODE_ADT7410_ABOVE_CRIT, + chip->last_timestamp); +} + +static int adt7410_interrupt(struct iio_dev *dev_info, + int index, + s64 timestamp, + int no_test) +{ + struct adt7410_chip_info *chip = dev_info->dev_data; + + chip->last_timestamp = timestamp; + schedule_work(&chip->thresh_work); + + return 0; +} + +IIO_EVENT_SH(adt7410, &adt7410_interrupt); +IIO_EVENT_SH(adt7410_ct, &adt7410_interrupt); + +static ssize_t adt7410_show_event_mode(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct adt7410_chip_info *chip = dev_info->dev_data; + int ret; + + ret = adt7410_i2c_read_byte(chip, ADT7410_CONFIG, &chip->config); + if (ret) + return -EIO; + + if (chip->config & ADT7410_EVENT_MODE) + return sprintf(buf, "interrupt\n"); + else + return sprintf(buf, "comparator\n"); +} + +static ssize_t adt7410_set_event_mode(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct adt7410_chip_info *chip = dev_info->dev_data; + u16 config; + int ret; + + ret = adt7410_i2c_read_byte(chip, ADT7410_CONFIG, &chip->config); + if (ret) + return -EIO; + + config = chip->config &= ~ADT7410_EVENT_MODE; + if (strcmp(buf, "comparator") != 0) + config |= ADT7410_EVENT_MODE; + + ret = adt7410_i2c_write_byte(chip, ADT7410_CONFIG, config); + if (ret) + return -EIO; + + chip->config = config; + + return ret; +} + +static ssize_t adt7410_show_available_event_modes(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + return sprintf(buf, "comparator\ninterrupt\n"); +} + +static ssize_t adt7410_show_fault_queue(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct adt7410_chip_info *chip = dev_info->dev_data; + int ret; + + ret = adt7410_i2c_read_byte(chip, ADT7410_CONFIG, &chip->config); + if (ret) + return -EIO; + + return sprintf(buf, "%d\n", chip->config & ADT7410_FAULT_QUEUE_MASK); +} + +static ssize_t adt7410_set_fault_queue(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct adt7410_chip_info *chip = dev_info->dev_data; + unsigned long data; + int ret; + u8 config; + + ret = strict_strtoul(buf, 10, &data); + if (ret || data > 3) + return -EINVAL; + + ret = adt7410_i2c_read_byte(chip, ADT7410_CONFIG, &chip->config); + if (ret) + return -EIO; + + config = chip->config & ~ADT7410_FAULT_QUEUE_MASK; + config |= data; + ret = adt7410_i2c_write_byte(chip, ADT7410_CONFIG, config); + if (ret) + return -EIO; + + chip->config = config; + + return ret; +} + +static inline ssize_t adt7410_show_t_bound(struct device *dev, + struct device_attribute *attr, + u8 bound_reg, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct adt7410_chip_info *chip = dev_info->dev_data; + u16 data; + int ret; + + ret = adt7410_i2c_read_word(chip, bound_reg, &data); + if (ret) + return -EIO; + + return adt7410_convert_temperature(chip, data, buf); +} + +static inline ssize_t adt7410_set_t_bound(struct device *dev, + struct device_attribute *attr, + u8 bound_reg, + const char *buf, + size_t len) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct adt7410_chip_info *chip = dev_info->dev_data; + long tmp1, tmp2; + u16 data; + char *pos; + int ret; + + pos = strchr(buf, '.'); + + ret = strict_strtol(buf, 10, &tmp1); + + if (ret || tmp1 > 127 || tmp1 < -128) + return -EINVAL; + + if (pos) { + len = strlen(pos); + + if (chip->config & ADT7410_RESOLUTION) { + if (len > ADT7410_T16_VALUE_FLOAT_OFFSET) + len = ADT7410_T16_VALUE_FLOAT_OFFSET; + pos[len] = 0; + ret = strict_strtol(pos, 10, &tmp2); + + if (!ret) + tmp2 = (tmp2 / 78125) * 78125; + } else { + if (len > ADT7410_T13_VALUE_FLOAT_OFFSET) + len = ADT7410_T13_VALUE_FLOAT_OFFSET; + pos[len] = 0; + ret = strict_strtol(pos, 10, &tmp2); + + if (!ret) + tmp2 = (tmp2 / 625) * 625; + } + } + + if (tmp1 < 0) + data = (u16)(-tmp1); + else + data = (u16)tmp1; + + if (chip->config & ADT7410_RESOLUTION) { + data = (data << ADT7410_T16_VALUE_FLOAT_OFFSET) | + (tmp2 & ADT7410_T16_VALUE_FLOAT_MASK); + + if (tmp1 < 0) + /* convert positive value to supplyment */ + data = (u16)((ADT7410_T16_VALUE_SIGN << 1) - (u32)data); + } else { + data = (data << ADT7410_T13_VALUE_FLOAT_OFFSET) | + (tmp2 & ADT7410_T13_VALUE_FLOAT_MASK); + + if (tmp1 < 0) + /* convert positive value to supplyment */ + data = (ADT7410_T13_VALUE_SIGN << 1) - data; + data <<= ADT7410_T13_VALUE_OFFSET; + } + + ret = adt7410_i2c_write_word(chip, bound_reg, data); + if (ret) + return -EIO; + + return ret; +} + +static ssize_t adt7410_show_t_alarm_high(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + return adt7410_show_t_bound(dev, attr, + ADT7410_T_ALARM_HIGH, buf); +} + +static inline ssize_t adt7410_set_t_alarm_high(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + return adt7410_set_t_bound(dev, attr, + ADT7410_T_ALARM_HIGH, buf, len); +} + +static ssize_t adt7410_show_t_alarm_low(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + return adt7410_show_t_bound(dev, attr, + ADT7410_T_ALARM_LOW, buf); +} + +static inline ssize_t adt7410_set_t_alarm_low(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + return adt7410_set_t_bound(dev, attr, + ADT7410_T_ALARM_LOW, buf, len); +} + +static ssize_t adt7410_show_t_crit(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + return adt7410_show_t_bound(dev, attr, + ADT7410_T_CRIT, buf); +} + +static inline ssize_t adt7410_set_t_crit(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + return adt7410_set_t_bound(dev, attr, + ADT7410_T_CRIT, buf, len); +} + +static ssize_t adt7410_show_t_hyst(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct adt7410_chip_info *chip = dev_info->dev_data; + int ret; + u8 t_hyst; + + ret = adt7410_i2c_read_byte(chip, ADT7410_T_HYST, &t_hyst); + if (ret) + return -EIO; + + return sprintf(buf, "%d\n", t_hyst & ADT7410_T_HYST_MASK); +} + +static inline ssize_t adt7410_set_t_hyst(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct adt7410_chip_info *chip = dev_info->dev_data; + int ret; + unsigned long data; + u8 t_hyst; + + ret = strict_strtol(buf, 10, &data); + + if (ret || data > ADT7410_T_HYST_MASK) + return -EINVAL; + + t_hyst = (u8)data; + + ret = adt7410_i2c_write_byte(chip, ADT7410_T_HYST, t_hyst); + if (ret) + return -EIO; + + return ret; +} + +IIO_EVENT_ATTR_SH(event_mode, iio_event_adt7410, + adt7410_show_event_mode, adt7410_set_event_mode, 0); +IIO_EVENT_ATTR_SH(available_event_modes, iio_event_adt7410, + adt7410_show_available_event_modes, NULL, 0); +IIO_EVENT_ATTR_SH(fault_queue, iio_event_adt7410, + adt7410_show_fault_queue, adt7410_set_fault_queue, 0); +IIO_EVENT_ATTR_SH(t_alarm_high, iio_event_adt7410, + adt7410_show_t_alarm_high, adt7410_set_t_alarm_high, 0); +IIO_EVENT_ATTR_SH(t_alarm_low, iio_event_adt7410, + adt7410_show_t_alarm_low, adt7410_set_t_alarm_low, 0); +IIO_EVENT_ATTR_SH(t_crit, iio_event_adt7410_ct, + adt7410_show_t_crit, adt7410_set_t_crit, 0); +IIO_EVENT_ATTR_SH(t_hyst, iio_event_adt7410, + adt7410_show_t_hyst, adt7410_set_t_hyst, 0); + +static struct attribute *adt7410_event_int_attributes[] = { + &iio_event_attr_event_mode.dev_attr.attr, + &iio_event_attr_available_event_modes.dev_attr.attr, + &iio_event_attr_fault_queue.dev_attr.attr, + &iio_event_attr_t_alarm_high.dev_attr.attr, + &iio_event_attr_t_alarm_low.dev_attr.attr, + &iio_event_attr_t_hyst.dev_attr.attr, + NULL, +}; + +static struct attribute *adt7410_event_ct_attributes[] = { + &iio_event_attr_event_mode.dev_attr.attr, + &iio_event_attr_available_event_modes.dev_attr.attr, + &iio_event_attr_fault_queue.dev_attr.attr, + &iio_event_attr_t_crit.dev_attr.attr, + &iio_event_attr_t_hyst.dev_attr.attr, + NULL, +}; + +static struct attribute_group adt7410_event_attribute_group[ADT7410_IRQS] = { + { + .attrs = adt7410_event_int_attributes, + }, + { + .attrs = adt7410_event_ct_attributes, + } +}; + +/* + * device probe and remove + */ + +static int __devinit adt7410_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + struct adt7410_chip_info *chip; + int ret = 0; + unsigned long *adt7410_platform_data = client->dev.platform_data; + + chip = kzalloc(sizeof(struct adt7410_chip_info), GFP_KERNEL); + + if (chip == NULL) + return -ENOMEM; + + /* this is only used for device removal purposes */ + i2c_set_clientdata(client, chip); + + chip->client = client; + chip->name = id->name; + + chip->indio_dev = iio_allocate_device(); + if (chip->indio_dev == NULL) { + ret = -ENOMEM; + goto error_free_chip; + } + + chip->indio_dev->dev.parent = &client->dev; + chip->indio_dev->attrs = &adt7410_attribute_group; + chip->indio_dev->event_attrs = adt7410_event_attribute_group; + chip->indio_dev->dev_data = (void *)chip; + chip->indio_dev->driver_module = THIS_MODULE; + chip->indio_dev->num_interrupt_lines = ADT7410_IRQS; + chip->indio_dev->modes = INDIO_DIRECT_MODE; + + ret = iio_device_register(chip->indio_dev); + if (ret) + goto error_free_dev; + + /* CT critcal temperature event. line 0 */ + if (client->irq) { + ret = iio_register_interrupt_line(client->irq, + chip->indio_dev, + 0, + IRQF_TRIGGER_LOW, + chip->name); + if (ret) + goto error_unreg_dev; + + /* + * The event handler list element refer to iio_event_adt7410. + * All event attributes bind to the same event handler. + * One event handler can only be added to one event list. + */ + iio_add_event_to_list(&iio_event_adt7410, + &chip->indio_dev->interrupts[0]->ev_list); + } + + /* INT bound temperature alarm event. line 1 */ + if (adt7410_platform_data[0]) { + ret = iio_register_interrupt_line(adt7410_platform_data[0], + chip->indio_dev, + 1, + adt7410_platform_data[1], + chip->name); + if (ret) + goto error_unreg_ct_irq; + + /* + * The event handler list element refer to iio_event_adt7410. + * All event attributes bind to the same event handler. + * One event handler can only be added to one event list. + */ + iio_add_event_to_list(&iio_event_adt7410_ct, + &chip->indio_dev->interrupts[1]->ev_list); + } + + if (client->irq && adt7410_platform_data[0]) { + INIT_WORK(&chip->thresh_work, adt7410_interrupt_bh); + + ret = adt7410_i2c_read_byte(chip, ADT7410_CONFIG, &chip->config); + if (ret) { + ret = -EIO; + goto error_unreg_int_irq; + } + + /* set irq polarity low level */ + chip->config &= ~ADT7410_CT_POLARITY; + + if (adt7410_platform_data[1] & IRQF_TRIGGER_HIGH) + chip->config |= ADT7410_INT_POLARITY; + else + chip->config &= ~ADT7410_INT_POLARITY; + + ret = adt7410_i2c_write_byte(chip, ADT7410_CONFIG, chip->config); + if (ret) { + ret = -EIO; + goto error_unreg_int_irq; + } + } + + dev_info(&client->dev, "%s temperature sensor registered.\n", + id->name); + + return 0; + +error_unreg_int_irq: + iio_unregister_interrupt_line(chip->indio_dev, 1); +error_unreg_ct_irq: + iio_unregister_interrupt_line(chip->indio_dev, 0); +error_unreg_dev: + iio_device_unregister(chip->indio_dev); +error_free_dev: + iio_free_device(chip->indio_dev); +error_free_chip: + kfree(chip); + + return ret; +} + +static int __devexit adt7410_remove(struct i2c_client *client) +{ + struct adt7410_chip_info *chip = i2c_get_clientdata(client); + struct iio_dev *indio_dev = chip->indio_dev; + unsigned long *adt7410_platform_data = client->dev.platform_data; + + if (adt7410_platform_data[0]) + iio_unregister_interrupt_line(indio_dev, 1); + if (client->irq) + iio_unregister_interrupt_line(indio_dev, 0); + iio_device_unregister(indio_dev); + iio_free_device(chip->indio_dev); + kfree(chip); + + return 0; +} + +static const struct i2c_device_id adt7410_id[] = { + { "adt7410", 0 }, + {} +}; + +MODULE_DEVICE_TABLE(i2c, adt7410_id); + +static struct i2c_driver adt7410_driver = { + .driver = { + .name = "adt7410", + }, + .probe = adt7410_probe, + .remove = __devexit_p(adt7410_remove), + .id_table = adt7410_id, +}; + +static __init int adt7410_init(void) +{ + return i2c_add_driver(&adt7410_driver); +} + +static __exit void adt7410_exit(void) +{ + i2c_del_driver(&adt7410_driver); +} + +MODULE_AUTHOR("Sonic Zhang "); +MODULE_DESCRIPTION("Analog Devices ADT7410 digital" + " temperature sensor driver"); +MODULE_LICENSE("GPL v2"); + +module_init(adt7410_init); +module_exit(adt7410_exit); -- cgit v1.2.3 From 4f0cd86d66a81fd77912504d0e0b5883c473512e Mon Sep 17 00:00:00 2001 From: Barry Song Date: Wed, 27 Oct 2010 21:44:03 -0400 Subject: staging: iio: gyro: new driver for ADIS16251 devices Signed-off-by: Barry Song Signed-off-by: Michael Hennerich Acked-by: Jonathan Cameron Signed-off-by: Mike Frysinger Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/gyro/Kconfig | 10 + drivers/staging/iio/gyro/Makefile | 3 + drivers/staging/iio/gyro/adis16251.h | 185 +++++++ drivers/staging/iio/gyro/adis16251_core.c | 777 ++++++++++++++++++++++++++++++ drivers/staging/iio/sysfs.h | 6 + 5 files changed, 981 insertions(+) create mode 100644 drivers/staging/iio/gyro/adis16251.h create mode 100644 drivers/staging/iio/gyro/adis16251_core.c diff --git a/drivers/staging/iio/gyro/Kconfig b/drivers/staging/iio/gyro/Kconfig index d1dde82dbc9e..c7a7d299b05c 100644 --- a/drivers/staging/iio/gyro/Kconfig +++ b/drivers/staging/iio/gyro/Kconfig @@ -14,3 +14,13 @@ config ADIS16260 This driver can also be built as a module. If so, the module will be called adis16260. + +config ADIS16251 + tristate "Analog Devices ADIS16251 Digital Gyroscope Sensor SPI driver" + depends on SPI + help + Say yes here to build support for Analog Devices adis16261 programmable + digital gyroscope sensor. + + This driver can also be built as a module. If so, the module + will be called adis16251. diff --git a/drivers/staging/iio/gyro/Makefile b/drivers/staging/iio/gyro/Makefile index b5f0dc01122c..8a592d8f7f72 100644 --- a/drivers/staging/iio/gyro/Makefile +++ b/drivers/staging/iio/gyro/Makefile @@ -5,3 +5,6 @@ adis16260-y := adis16260_core.o adis16260-$(CONFIG_IIO_RING_BUFFER) += adis16260_ring.o adis16260_trigger.o obj-$(CONFIG_ADIS16260) += adis16260.o + +adis16251-y := adis16251_core.o +obj-$(CONFIG_ADIS16251) += adis16251.o diff --git a/drivers/staging/iio/gyro/adis16251.h b/drivers/staging/iio/gyro/adis16251.h new file mode 100644 index 000000000000..999db4981413 --- /dev/null +++ b/drivers/staging/iio/gyro/adis16251.h @@ -0,0 +1,185 @@ +#ifndef SPI_ADIS16251_H_ +#define SPI_ADIS16251_H_ + +#define ADIS16251_STARTUP_DELAY 220 /* ms */ + +#define ADIS16251_READ_REG(a) a +#define ADIS16251_WRITE_REG(a) ((a) | 0x80) + +#define ADIS16251_ENDURANCE 0x00 /* Flash memory write count */ +#define ADIS16251_SUPPLY_OUT 0x02 /* Power supply measurement */ +#define ADIS16251_GYRO_OUT 0x04 /* X-axis gyroscope output */ +#define ADIS16251_AUX_ADC 0x0A /* analog input channel measurement */ +#define ADIS16251_TEMP_OUT 0x0C /* internal temperature measurement */ +#define ADIS16251_ANGL_OUT 0x0E /* angle displacement */ +#define ADIS16251_GYRO_OFF 0x14 /* Calibration, offset/bias adjustment */ +#define ADIS16251_GYRO_SCALE 0x16 /* Calibration, scale adjustment */ +#define ADIS16251_ALM_MAG1 0x20 /* Alarm 1 magnitude/polarity setting */ +#define ADIS16251_ALM_MAG2 0x22 /* Alarm 2 magnitude/polarity setting */ +#define ADIS16251_ALM_SMPL1 0x24 /* Alarm 1 dynamic rate of change setting */ +#define ADIS16251_ALM_SMPL2 0x26 /* Alarm 2 dynamic rate of change setting */ +#define ADIS16251_ALM_CTRL 0x28 /* Alarm control */ +#define ADIS16251_AUX_DAC 0x30 /* Auxiliary DAC data */ +#define ADIS16251_GPIO_CTRL 0x32 /* Control, digital I/O line */ +#define ADIS16251_MSC_CTRL 0x34 /* Control, data ready, self-test settings */ +#define ADIS16251_SMPL_PRD 0x36 /* Control, internal sample rate */ +#define ADIS16251_SENS_AVG 0x38 /* Control, dynamic range, filtering */ +#define ADIS16251_SLP_CNT 0x3A /* Control, sleep mode initiation */ +#define ADIS16251_DIAG_STAT 0x3C /* Diagnostic, error flags */ +#define ADIS16251_GLOB_CMD 0x3E /* Control, global commands */ + +#define ADIS16251_ERROR_ACTIVE (1<<14) +#define ADIS16251_NEW_DATA (1<<14) + +/* MSC_CTRL */ +#define ADIS16251_MSC_CTRL_INT_SELF_TEST (1<<10) /* Internal self-test enable */ +#define ADIS16251_MSC_CTRL_NEG_SELF_TEST (1<<9) +#define ADIS16251_MSC_CTRL_POS_SELF_TEST (1<<8) +#define ADIS16251_MSC_CTRL_DATA_RDY_EN (1<<2) +#define ADIS16251_MSC_CTRL_DATA_RDY_POL_HIGH (1<<1) +#define ADIS16251_MSC_CTRL_DATA_RDY_DIO2 (1<<0) + +/* SMPL_PRD */ +#define ADIS16251_SMPL_PRD_TIME_BASE (1<<7) /* Time base (tB): 0 = 1.953 ms, 1 = 60.54 ms */ +#define ADIS16251_SMPL_PRD_DIV_MASK 0x7F + +/* SLP_CNT */ +#define ADIS16251_SLP_CNT_POWER_OFF 0x80 + +/* DIAG_STAT */ +#define ADIS16251_DIAG_STAT_ALARM2 (1<<9) +#define ADIS16251_DIAG_STAT_ALARM1 (1<<8) +#define ADIS16251_DIAG_STAT_SELF_TEST (1<<5) +#define ADIS16251_DIAG_STAT_OVERFLOW (1<<4) +#define ADIS16251_DIAG_STAT_SPI_FAIL (1<<3) +#define ADIS16251_DIAG_STAT_FLASH_UPT (1<<2) +#define ADIS16251_DIAG_STAT_POWER_HIGH (1<<1) +#define ADIS16251_DIAG_STAT_POWER_LOW (1<<0) + +#define ADIS16251_DIAG_STAT_ERR_MASK (ADIS16261_DIAG_STAT_ALARM2 | \ + ADIS16261_DIAG_STAT_ALARM1 | \ + ADIS16261_DIAG_STAT_SELF_TEST | \ + ADIS16261_DIAG_STAT_OVERFLOW | \ + ADIS16261_DIAG_STAT_SPI_FAIL | \ + ADIS16261_DIAG_STAT_FLASH_UPT | \ + ADIS16261_DIAG_STAT_POWER_HIGH | \ + ADIS16261_DIAG_STAT_POWER_LOW) + +/* GLOB_CMD */ +#define ADIS16251_GLOB_CMD_SW_RESET (1<<7) +#define ADIS16251_GLOB_CMD_FLASH_UPD (1<<3) +#define ADIS16251_GLOB_CMD_DAC_LATCH (1<<2) +#define ADIS16251_GLOB_CMD_FAC_CALIB (1<<1) +#define ADIS16251_GLOB_CMD_AUTO_NULL (1<<0) + +#define ADIS16251_MAX_TX 24 +#define ADIS16251_MAX_RX 24 + +#define ADIS16251_SPI_SLOW (u32)(300 * 1000) +#define ADIS16251_SPI_BURST (u32)(1000 * 1000) +#define ADIS16251_SPI_FAST (u32)(2000 * 1000) + +/** + * struct adis16251_state - device instance specific data + * @us: actual spi_device + * @work_trigger_to_ring: bh for triggered event handling + * @inter: used to check if new interrupt has been triggered + * @last_timestamp: passing timestamp from th to bh of interrupt handler + * @indio_dev: industrial I/O device structure + * @trig: data ready trigger registered with iio + * @tx: transmit buffer + * @rx: recieve buffer + * @buf_lock: mutex to protect tx and rx + **/ +struct adis16251_state { + struct spi_device *us; + struct work_struct work_trigger_to_ring; + s64 last_timestamp; + struct iio_dev *indio_dev; + struct iio_trigger *trig; + u8 *tx; + u8 *rx; + struct mutex buf_lock; +}; + +int adis16251_spi_write_reg_8(struct device *dev, + u8 reg_address, + u8 val); + +int adis16251_spi_read_burst(struct device *dev, u8 *rx); + +int adis16251_spi_read_sequence(struct device *dev, + u8 *tx, u8 *rx, int num); + +int adis16251_set_irq(struct device *dev, bool enable); + +int adis16251_reset(struct device *dev); + +int adis16251_stop_device(struct device *dev); + +int adis16251_check_status(struct device *dev); + +#if defined(CONFIG_IIO_RING_BUFFER) && defined(THIS_HAS_RING_BUFFER_SUPPORT) +/* At the moment triggers are only used for ring buffer + * filling. This may change! + */ + +enum adis16251_scan { + ADIS16251_SCAN_SUPPLY, + ADIS16251_SCAN_GYRO, + ADIS16251_SCAN_TEMP, + ADIS16251_SCAN_ADC_0, +}; + +void adis16251_remove_trigger(struct iio_dev *indio_dev); +int adis16251_probe_trigger(struct iio_dev *indio_dev); + +ssize_t adis16251_read_data_from_ring(struct device *dev, + struct device_attribute *attr, + char *buf); + + +int adis16251_configure_ring(struct iio_dev *indio_dev); +void adis16251_unconfigure_ring(struct iio_dev *indio_dev); + +int adis16251_initialize_ring(struct iio_ring_buffer *ring); +void adis16251_uninitialize_ring(struct iio_ring_buffer *ring); +#else /* CONFIG_IIO_RING_BUFFER */ + +static inline void adis16251_remove_trigger(struct iio_dev *indio_dev) +{ +} + +static inline int adis16251_probe_trigger(struct iio_dev *indio_dev) +{ + return 0; +} + +static inline ssize_t +adis16251_read_data_from_ring(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + return 0; +} + +static int adis16251_configure_ring(struct iio_dev *indio_dev) +{ + return 0; +} + +static inline void adis16251_unconfigure_ring(struct iio_dev *indio_dev) +{ +} + +static inline int adis16251_initialize_ring(struct iio_ring_buffer *ring) +{ + return 0; +} + +static inline void adis16251_uninitialize_ring(struct iio_ring_buffer *ring) +{ +} + +#endif /* CONFIG_IIO_RING_BUFFER */ +#endif /* SPI_ADIS16251_H_ */ diff --git a/drivers/staging/iio/gyro/adis16251_core.c b/drivers/staging/iio/gyro/adis16251_core.c new file mode 100644 index 000000000000..a0d400f7ee62 --- /dev/null +++ b/drivers/staging/iio/gyro/adis16251_core.c @@ -0,0 +1,777 @@ +/* + * ADIS16251 Programmable Digital Gyroscope Sensor Driver + * + * Copyright 2010 Analog Devices Inc. + * + * Licensed under the GPL-2 or later. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../iio.h" +#include "../sysfs.h" +#include "gyro.h" +#include "../adc/adc.h" + +#include "adis16251.h" + +#define DRIVER_NAME "adis16251" + +/* At the moment the spi framework doesn't allow global setting of cs_change. + * It's in the likely to be added comment at the top of spi.h. + * This means that use cannot be made of spi_write etc. + */ + +/** + * adis16251_spi_write_reg_8() - write single byte to a register + * @dev: device associated with child of actual device (iio_dev or iio_trig) + * @reg_address: the address of the register to be written + * @val: the value to write + **/ +int adis16251_spi_write_reg_8(struct device *dev, + u8 reg_address, + u8 val) +{ + int ret; + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct adis16251_state *st = iio_dev_get_devdata(indio_dev); + + mutex_lock(&st->buf_lock); + st->tx[0] = ADIS16251_WRITE_REG(reg_address); + st->tx[1] = val; + + ret = spi_write(st->us, st->tx, 2); + mutex_unlock(&st->buf_lock); + + return ret; +} + +/** + * adis16251_spi_write_reg_16() - write 2 bytes to a pair of registers + * @dev: device associated with child of actual device (iio_dev or iio_trig) + * @reg_address: the address of the lower of the two registers. Second register + * is assumed to have address one greater. + * @val: value to be written + **/ +static int adis16251_spi_write_reg_16(struct device *dev, + u8 lower_reg_address, + u16 value) +{ + int ret; + struct spi_message msg; + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct adis16251_state *st = iio_dev_get_devdata(indio_dev); + struct spi_transfer xfers[] = { + { + .tx_buf = st->tx, + .bits_per_word = 8, + .len = 2, + .cs_change = 1, + }, { + .tx_buf = st->tx + 2, + .bits_per_word = 8, + .len = 2, + .cs_change = 1, + }, + }; + + mutex_lock(&st->buf_lock); + st->tx[0] = ADIS16251_WRITE_REG(lower_reg_address); + st->tx[1] = value & 0xFF; + st->tx[2] = ADIS16251_WRITE_REG(lower_reg_address + 1); + st->tx[3] = (value >> 8) & 0xFF; + + spi_message_init(&msg); + spi_message_add_tail(&xfers[0], &msg); + spi_message_add_tail(&xfers[1], &msg); + ret = spi_sync(st->us, &msg); + mutex_unlock(&st->buf_lock); + + return ret; +} + +/** + * adis16251_spi_read_reg_16() - read 2 bytes from a 16-bit register + * @dev: device associated with child of actual device (iio_dev or iio_trig) + * @reg_address: the address of the lower of the two registers. Second register + * is assumed to have address one greater. + * @val: somewhere to pass back the value read + **/ +static int adis16251_spi_read_reg_16(struct device *dev, + u8 lower_reg_address, + u16 *val) +{ + struct spi_message msg; + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct adis16251_state *st = iio_dev_get_devdata(indio_dev); + int ret; + struct spi_transfer xfers[] = { + { + .tx_buf = st->tx, + .bits_per_word = 8, + .len = 2, + .cs_change = 1, + }, { + .rx_buf = st->rx, + .bits_per_word = 8, + .len = 2, + .cs_change = 1, + }, + }; + + mutex_lock(&st->buf_lock); + st->tx[0] = ADIS16251_READ_REG(lower_reg_address); + st->tx[1] = 0; + st->tx[2] = 0; + st->tx[3] = 0; + + spi_message_init(&msg); + spi_message_add_tail(&xfers[0], &msg); + spi_message_add_tail(&xfers[1], &msg); + ret = spi_sync(st->us, &msg); + if (ret) { + dev_err(&st->us->dev, "problem when reading 16 bit register 0x%02X", + lower_reg_address); + goto error_ret; + } + *val = (st->rx[0] << 8) | st->rx[1]; + +error_ret: + mutex_unlock(&st->buf_lock); + return ret; +} + +/** + * adis16251_spi_read_burst() - read all data registers + * @dev: device associated with child of actual device (iio_dev or iio_trig) + * @rx: somewhere to pass back the value read (min size is 24 bytes) + **/ +int adis16251_spi_read_burst(struct device *dev, u8 *rx) +{ + struct spi_message msg; + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct adis16251_state *st = iio_dev_get_devdata(indio_dev); + u32 old_speed_hz = st->us->max_speed_hz; + int ret; + + struct spi_transfer xfers[] = { + { + .tx_buf = st->tx, + .bits_per_word = 8, + .len = 2, + .cs_change = 0, + }, { + .rx_buf = rx, + .bits_per_word = 8, + .len = 24, + .cs_change = 1, + }, + }; + + mutex_lock(&st->buf_lock); + st->tx[0] = ADIS16251_READ_REG(ADIS16251_GLOB_CMD); + st->tx[1] = 0; + + spi_message_init(&msg); + spi_message_add_tail(&xfers[0], &msg); + spi_message_add_tail(&xfers[1], &msg); + + st->us->max_speed_hz = min(ADIS16251_SPI_BURST, old_speed_hz); + spi_setup(st->us); + + ret = spi_sync(st->us, &msg); + if (ret) + dev_err(&st->us->dev, "problem when burst reading"); + + st->us->max_speed_hz = old_speed_hz; + spi_setup(st->us); + mutex_unlock(&st->buf_lock); + return ret; +} + +/** + * adis16251_spi_read_sequence() - read a sequence of 16-bit registers + * @dev: device associated with child of actual device (iio_dev or iio_trig) + * @tx: register addresses in bytes 0,2,4,6... (min size is 2*num bytes) + * @rx: somewhere to pass back the value read (min size is 2*num bytes) + **/ +int adis16251_spi_read_sequence(struct device *dev, + u8 *tx, u8 *rx, int num) +{ + struct spi_message msg; + struct spi_transfer *xfers; + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct adis16251_state *st = iio_dev_get_devdata(indio_dev); + int ret, i; + + xfers = kzalloc(num + 1, GFP_KERNEL); + if (xfers == NULL) { + dev_err(&st->us->dev, "memory alloc failed"); + ret = -ENOMEM; + goto error_ret; + } + + /* tx: |add1|addr2|addr3|...|addrN |zero| + * rx: |zero|res1 |res2 |...|resN-1|resN| */ + spi_message_init(&msg); + for (i = 0; i < num + 1; i++) { + if (i > 0) + xfers[i].rx_buf = st->rx + 2*(i - 1); + if (i < num) + xfers[i].tx_buf = st->tx + 2*i; + xfers[i].bits_per_word = 8; + xfers[i].len = 2; + xfers[i].cs_change = 1; + spi_message_add_tail(&xfers[i], &msg); + } + + mutex_lock(&st->buf_lock); + + ret = spi_sync(st->us, &msg); + if (ret) + dev_err(&st->us->dev, "problem when reading sequence"); + + mutex_unlock(&st->buf_lock); + kfree(xfers); + +error_ret: + return ret; +} + +static ssize_t adis16251_spi_read_signed(struct device *dev, + struct device_attribute *attr, + char *buf, + unsigned bits) +{ + int ret; + s16 val = 0; + unsigned shift = 16 - bits; + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + + ret = adis16251_spi_read_reg_16(dev, this_attr->address, (u16 *)&val); + if (ret) + return ret; + + if (val & ADIS16251_ERROR_ACTIVE) + adis16251_check_status(dev); + val = ((s16)(val << shift) >> shift); + return sprintf(buf, "%d\n", val); +} + +static ssize_t adis16251_read_12bit_unsigned(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + int ret; + u16 val = 0; + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + + ret = adis16251_spi_read_reg_16(dev, this_attr->address, &val); + if (ret) + return ret; + + if (val & ADIS16251_ERROR_ACTIVE) + adis16251_check_status(dev); + + return sprintf(buf, "%u\n", val & 0x0FFF); +} + +static ssize_t adis16251_read_14bit_signed(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + ssize_t ret; + + /* Take the iio_dev status lock */ + mutex_lock(&indio_dev->mlock); + ret = adis16251_spi_read_signed(dev, attr, buf, 14); + mutex_unlock(&indio_dev->mlock); + + return ret; +} + +static ssize_t adis16251_read_12bit_signed(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + ssize_t ret; + + /* Take the iio_dev status lock */ + mutex_lock(&indio_dev->mlock); + ret = adis16251_spi_read_signed(dev, attr, buf, 12); + mutex_unlock(&indio_dev->mlock); + + return ret; +} + +static ssize_t adis16251_write_16bit(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + int ret; + long val; + + ret = strict_strtol(buf, 10, &val); + if (ret) + goto error_ret; + ret = adis16251_spi_write_reg_16(dev, this_attr->address, val); + +error_ret: + return ret ? ret : len; +} + +static ssize_t adis16251_read_frequency(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + int ret, len = 0; + u16 t; + int sps; + ret = adis16251_spi_read_reg_16(dev, + ADIS16251_SMPL_PRD, + &t); + if (ret) + return ret; + sps = (t & ADIS16251_SMPL_PRD_TIME_BASE) ? 8 : 256; + sps /= (t & ADIS16251_SMPL_PRD_DIV_MASK) + 1; + len = sprintf(buf, "%d SPS\n", sps); + return len; +} + +static ssize_t adis16251_write_frequency(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct adis16251_state *st = iio_dev_get_devdata(indio_dev); + long val; + int ret; + u8 t; + + ret = strict_strtol(buf, 10, &val); + if (ret) + return ret; + + mutex_lock(&indio_dev->mlock); + + t = (256 / val); + if (t > 0) + t--; + t &= ADIS16251_SMPL_PRD_DIV_MASK; + if ((t & ADIS16251_SMPL_PRD_DIV_MASK) >= 0x0A) + st->us->max_speed_hz = ADIS16251_SPI_SLOW; + else + st->us->max_speed_hz = ADIS16251_SPI_FAST; + + ret = adis16251_spi_write_reg_8(dev, + ADIS16251_SMPL_PRD, + t); + + mutex_unlock(&indio_dev->mlock); + + return ret ? ret : len; +} + +static ssize_t adis16251_write_reset(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t len) +{ + if (len < 1) + return -1; + switch (buf[0]) { + case '1': + case 'y': + case 'Y': + return adis16251_reset(dev); + } + return -1; +} + + + +int adis16251_set_irq(struct device *dev, bool enable) +{ + int ret; + u16 msc; + ret = adis16251_spi_read_reg_16(dev, ADIS16251_MSC_CTRL, &msc); + if (ret) + goto error_ret; + + msc |= ADIS16251_MSC_CTRL_DATA_RDY_POL_HIGH; + if (enable) + msc |= ADIS16251_MSC_CTRL_DATA_RDY_EN; + else + msc &= ~ADIS16251_MSC_CTRL_DATA_RDY_EN; + + ret = adis16251_spi_write_reg_16(dev, ADIS16251_MSC_CTRL, msc); + if (ret) + goto error_ret; + +error_ret: + return ret; +} + +int adis16251_reset(struct device *dev) +{ + int ret; + ret = adis16251_spi_write_reg_8(dev, + ADIS16251_GLOB_CMD, + ADIS16251_GLOB_CMD_SW_RESET); + if (ret) + dev_err(dev, "problem resetting device"); + + return ret; +} + +/* Power down the device */ +int adis16251_stop_device(struct device *dev) +{ + int ret; + u16 val = ADIS16251_SLP_CNT_POWER_OFF; + + ret = adis16251_spi_write_reg_16(dev, ADIS16251_SLP_CNT, val); + if (ret) + dev_err(dev, "problem with turning device off: SLP_CNT"); + + return ret; +} + +static int adis16251_self_test(struct device *dev) +{ + int ret; + + ret = adis16251_spi_write_reg_16(dev, + ADIS16251_MSC_CTRL, + ADIS16251_MSC_CTRL_INT_SELF_TEST); + if (ret) { + dev_err(dev, "problem starting self test"); + goto err_ret; + } + + adis16251_check_status(dev); + +err_ret: + return ret; +} + +int adis16251_check_status(struct device *dev) +{ + u16 status; + int ret; + + ret = adis16251_spi_read_reg_16(dev, ADIS16251_DIAG_STAT, &status); + + if (ret < 0) { + dev_err(dev, "Reading status failed\n"); + goto error_ret; + } + + if (!(status & ADIS16251_DIAG_STAT_ERR_MASK)) { + ret = 0; + goto error_ret; + } + + ret = -EFAULT; + + if (status & ADIS16251_DIAG_STAT_ALARM2) + dev_err(dev, "Alarm 2 active\n"); + if (status & ADIS16251_DIAG_STAT_ALARM1) + dev_err(dev, "Alarm 1 active\n"); + if (status & ADIS16251_DIAG_STAT_SELF_TEST) + dev_err(dev, "Self test error\n"); + if (status & ADIS16251_DIAG_STAT_OVERFLOW) + dev_err(dev, "Sensor overrange\n"); + if (status & ADIS16251_DIAG_STAT_SPI_FAIL) + dev_err(dev, "SPI failure\n"); + if (status & ADIS16251_DIAG_STAT_FLASH_UPT) + dev_err(dev, "Flash update failed\n"); + if (status & ADIS16251_DIAG_STAT_POWER_HIGH) + dev_err(dev, "Power supply above 5.25V\n"); + if (status & ADIS16251_DIAG_STAT_POWER_LOW) + dev_err(dev, "Power supply below 4.75V\n"); + +error_ret: + return ret; +} + +static int adis16251_initial_setup(struct adis16251_state *st) +{ + int ret; + u16 smp_prd; + struct device *dev = &st->indio_dev->dev; + + /* use low spi speed for init */ + st->us->max_speed_hz = ADIS16251_SPI_SLOW; + st->us->mode = SPI_MODE_3; + spi_setup(st->us); + + /* Disable IRQ */ + ret = adis16251_set_irq(dev, false); + if (ret) { + dev_err(dev, "disable irq failed"); + goto err_ret; + } + + /* Do self test */ + + /* Read status register to check the result */ + ret = adis16251_check_status(dev); + if (ret) { + adis16251_reset(dev); + dev_err(dev, "device not playing ball -> reset"); + msleep(ADIS16251_STARTUP_DELAY); + ret = adis16251_check_status(dev); + if (ret) { + dev_err(dev, "giving up"); + goto err_ret; + } + } + + printk(KERN_INFO DRIVER_NAME ": at CS%d (irq %d)\n", + st->us->chip_select, st->us->irq); + + /* use high spi speed if possible */ + ret = adis16251_spi_read_reg_16(dev, ADIS16251_SMPL_PRD, &smp_prd); + if (!ret && (smp_prd & ADIS16251_SMPL_PRD_DIV_MASK) < 0x0A) { + st->us->max_speed_hz = ADIS16251_SPI_SLOW; + spi_setup(st->us); + } + +err_ret: + return ret; +} + +static IIO_DEV_ATTR_IN_NAMED_RAW(0, supply, adis16251_read_12bit_signed, + ADIS16251_SUPPLY_OUT); +static IIO_CONST_ATTR(in0_supply_scale, "0.0018315"); + +static IIO_DEV_ATTR_GYRO(adis16251_read_14bit_signed, + ADIS16251_GYRO_OUT); +static IIO_DEV_ATTR_GYRO_SCALE(S_IWUSR | S_IRUGO, + adis16251_read_12bit_signed, + adis16251_write_16bit, + ADIS16251_GYRO_SCALE); +static IIO_DEV_ATTR_GYRO_OFFSET(S_IWUSR | S_IRUGO, + adis16251_read_12bit_signed, + adis16251_write_16bit, + ADIS16251_GYRO_OFF); + +static IIO_DEV_ATTR_TEMP_RAW(adis16251_read_12bit_signed); +static IIO_CONST_ATTR(temp_offset, "25 K"); +static IIO_CONST_ATTR(temp_scale, "0.1453 K"); + +static IIO_DEV_ATTR_IN_NAMED_RAW(1, aux, adis16251_read_12bit_unsigned, + ADIS16251_AUX_ADC); +static IIO_CONST_ATTR(in1_aux_scale, "0.0006105"); + +static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO, + adis16251_read_frequency, + adis16251_write_frequency); +static IIO_DEV_ATTR_ANGL(adis16251_read_14bit_signed, + ADIS16251_ANGL_OUT); + +static IIO_DEV_ATTR_RESET(adis16251_write_reset); + +static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("0.129 ~ 256"); + +static IIO_CONST_ATTR(name, "adis16251"); + +static struct attribute *adis16251_event_attributes[] = { + NULL +}; + +static struct attribute_group adis16251_event_attribute_group = { + .attrs = adis16251_event_attributes, +}; + +static struct attribute *adis16251_attributes[] = { + &iio_dev_attr_in0_supply_raw.dev_attr.attr, + &iio_const_attr_in0_supply_scale.dev_attr.attr, + &iio_dev_attr_gyro_raw.dev_attr.attr, + &iio_dev_attr_gyro_scale.dev_attr.attr, + &iio_dev_attr_gyro_offset.dev_attr.attr, + &iio_dev_attr_angl_raw.dev_attr.attr, + &iio_dev_attr_temp_raw.dev_attr.attr, + &iio_const_attr_temp_offset.dev_attr.attr, + &iio_const_attr_temp_scale.dev_attr.attr, + &iio_dev_attr_in1_aux_raw.dev_attr.attr, + &iio_const_attr_in1_aux_scale.dev_attr.attr, + &iio_dev_attr_sampling_frequency.dev_attr.attr, + &iio_const_attr_sampling_frequency_available.dev_attr.attr, + &iio_dev_attr_reset.dev_attr.attr, + &iio_const_attr_name.dev_attr.attr, + NULL +}; + +static const struct attribute_group adis16251_attribute_group = { + .attrs = adis16251_attributes, +}; + +static int __devinit adis16251_probe(struct spi_device *spi) +{ + int ret, regdone = 0; + struct adis16251_state *st = kzalloc(sizeof *st, GFP_KERNEL); + if (!st) { + ret = -ENOMEM; + goto error_ret; + } + /* this is only used for removal purposes */ + spi_set_drvdata(spi, st); + + /* Allocate the comms buffers */ + st->rx = kzalloc(sizeof(*st->rx)*ADIS16251_MAX_RX, GFP_KERNEL); + if (st->rx == NULL) { + ret = -ENOMEM; + goto error_free_st; + } + st->tx = kzalloc(sizeof(*st->tx)*ADIS16251_MAX_TX, GFP_KERNEL); + if (st->tx == NULL) { + ret = -ENOMEM; + goto error_free_rx; + } + st->us = spi; + mutex_init(&st->buf_lock); + /* setup the industrialio driver allocated elements */ + st->indio_dev = iio_allocate_device(); + if (st->indio_dev == NULL) { + ret = -ENOMEM; + goto error_free_tx; + } + + st->indio_dev->dev.parent = &spi->dev; + st->indio_dev->num_interrupt_lines = 1; + st->indio_dev->event_attrs = &adis16251_event_attribute_group; + st->indio_dev->attrs = &adis16251_attribute_group; + st->indio_dev->dev_data = (void *)(st); + st->indio_dev->driver_module = THIS_MODULE; + st->indio_dev->modes = INDIO_DIRECT_MODE; + + ret = adis16251_configure_ring(st->indio_dev); + if (ret) + goto error_free_dev; + + ret = iio_device_register(st->indio_dev); + if (ret) + goto error_unreg_ring_funcs; + regdone = 1; + + ret = adis16251_initialize_ring(st->indio_dev->ring); + if (ret) { + printk(KERN_ERR "failed to initialize the ring\n"); + goto error_unreg_ring_funcs; + } + + if (spi->irq && gpio_is_valid(irq_to_gpio(spi->irq)) > 0) { + ret = iio_register_interrupt_line(spi->irq, + st->indio_dev, + 0, + IRQF_TRIGGER_RISING, + "adis16251"); + if (ret) + goto error_uninitialize_ring; + + ret = adis16251_probe_trigger(st->indio_dev); + if (ret) + goto error_unregister_line; + } + + /* Get the device into a sane initial state */ + ret = adis16251_initial_setup(st); + if (ret) + goto error_remove_trigger; + return 0; + +error_remove_trigger: + if (st->indio_dev->modes & INDIO_RING_TRIGGERED) + adis16251_remove_trigger(st->indio_dev); +error_unregister_line: + if (st->indio_dev->modes & INDIO_RING_TRIGGERED) + iio_unregister_interrupt_line(st->indio_dev, 0); +error_uninitialize_ring: + adis16251_uninitialize_ring(st->indio_dev->ring); +error_unreg_ring_funcs: + adis16251_unconfigure_ring(st->indio_dev); +error_free_dev: + if (regdone) + iio_device_unregister(st->indio_dev); + else + iio_free_device(st->indio_dev); +error_free_tx: + kfree(st->tx); +error_free_rx: + kfree(st->rx); +error_free_st: + kfree(st); +error_ret: + return ret; +} + +/* fixme, confirm ordering in this function */ +static int adis16251_remove(struct spi_device *spi) +{ + int ret; + struct adis16251_state *st = spi_get_drvdata(spi); + struct iio_dev *indio_dev = st->indio_dev; + + ret = adis16251_stop_device(&(indio_dev->dev)); + if (ret) + goto err_ret; + + flush_scheduled_work(); + + adis16251_remove_trigger(indio_dev); + if (spi->irq && gpio_is_valid(irq_to_gpio(spi->irq)) > 0) + iio_unregister_interrupt_line(indio_dev, 0); + + adis16251_uninitialize_ring(indio_dev->ring); + adis16251_unconfigure_ring(indio_dev); + iio_device_unregister(indio_dev); + kfree(st->tx); + kfree(st->rx); + kfree(st); + + return 0; + +err_ret: + return ret; +} + +static struct spi_driver adis16251_driver = { + .driver = { + .name = "adis16251", + .owner = THIS_MODULE, + }, + .probe = adis16251_probe, + .remove = __devexit_p(adis16251_remove), +}; + +static __init int adis16251_init(void) +{ + return spi_register_driver(&adis16251_driver); +} +module_init(adis16251_init); + +static __exit void adis16251_exit(void) +{ + spi_unregister_driver(&adis16251_driver); +} +module_exit(adis16251_exit); + +MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>"); +MODULE_DESCRIPTION("Analog Devices ADIS16251 Digital Gyroscope Sensor SPI driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/staging/iio/sysfs.h b/drivers/staging/iio/sysfs.h index ee91a95a8b95..18bdaac2509d 100644 --- a/drivers/staging/iio/sysfs.h +++ b/drivers/staging/iio/sysfs.h @@ -107,6 +107,12 @@ struct iio_const_attr { #define IIO_DEV_ATTR_NAME(_show) \ IIO_DEVICE_ATTR(name, S_IRUGO, _show, NULL, 0) +/** + * IIO_DEV_ATTR_RESET: resets the device + **/ +#define IIO_DEV_ATTR_RESET(_store) \ + IIO_DEVICE_ATTR(reset, S_IWUGO, NULL, _store, 0) + /** * IIO_CONST_ATTR_NAME - constant identifier * @_string: the name -- cgit v1.2.3 From e071f6b8e47834e9c91a299a5e773bebffe10e67 Mon Sep 17 00:00:00 2001 From: Barry Song Date: Wed, 27 Oct 2010 21:44:04 -0400 Subject: staging: iio: gyro: new driver for ADIS16060 digital output gyros Signed-off-by: Barry Song Signed-off-by: Michael Hennerich Acked-by: Jonathan Cameron Signed-off-by: Mike Frysinger Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/gyro/Kconfig | 7 + drivers/staging/iio/gyro/Makefile | 3 + drivers/staging/iio/gyro/adis16060.h | 101 ++++++++++ drivers/staging/iio/gyro/adis16060_core.c | 319 ++++++++++++++++++++++++++++++ 4 files changed, 430 insertions(+) create mode 100644 drivers/staging/iio/gyro/adis16060.h create mode 100644 drivers/staging/iio/gyro/adis16060_core.c diff --git a/drivers/staging/iio/gyro/Kconfig b/drivers/staging/iio/gyro/Kconfig index c7a7d299b05c..77c0fe84380b 100644 --- a/drivers/staging/iio/gyro/Kconfig +++ b/drivers/staging/iio/gyro/Kconfig @@ -3,6 +3,13 @@ # comment "Digital gyroscope sensors" +config ADIS16060 + tristate "Analog Devices ADIS16060 Yaw Rate Gyroscope with SPI driver" + depends on SPI + help + Say yes here to build support for Analog Devices adis16060 wide bandwidth + yaw rate gyroscope with SPI. + config ADIS16260 tristate "Analog Devices ADIS16260 ADIS16265 Digital Gyroscope Sensor SPI driver" depends on SPI diff --git a/drivers/staging/iio/gyro/Makefile b/drivers/staging/iio/gyro/Makefile index 8a592d8f7f72..e2c4acb608b4 100644 --- a/drivers/staging/iio/gyro/Makefile +++ b/drivers/staging/iio/gyro/Makefile @@ -2,6 +2,9 @@ # Makefile for digital gyroscope sensor drivers # +adis16060-y := adis16060_core.o +obj-$(CONFIG_ADIS16060) += adis16060.o + adis16260-y := adis16260_core.o adis16260-$(CONFIG_IIO_RING_BUFFER) += adis16260_ring.o adis16260_trigger.o obj-$(CONFIG_ADIS16260) += adis16260.o diff --git a/drivers/staging/iio/gyro/adis16060.h b/drivers/staging/iio/gyro/adis16060.h new file mode 100644 index 000000000000..5c00e5385ee0 --- /dev/null +++ b/drivers/staging/iio/gyro/adis16060.h @@ -0,0 +1,101 @@ +#ifndef SPI_ADIS16060_H_ +#define SPI_ADIS16060_H_ + +#define ADIS16060_GYRO 0x20 /* Measure Angular Rate (Gyro) */ +#define ADIS16060_SUPPLY_OUT 0x10 /* Measure Temperature */ +#define ADIS16060_AIN2 0x80 /* Measure AIN2 */ +#define ADIS16060_AIN1 0x40 /* Measure AIN1 */ +#define ADIS16060_TEMP_OUT 0x22 /* Set Positive Self-Test and Output for Angular Rate */ +#define ADIS16060_ANGL_OUT 0x21 /* Set Negative Self-Test and Output for Angular Rate */ + +#define ADIS16060_MAX_TX 3 +#define ADIS16060_MAX_RX 3 + +/** + * struct adis16060_state - device instance specific data + * @us_w: actual spi_device to write data + * @work_trigger_to_ring: bh for triggered event handling + * @inter: used to check if new interrupt has been triggered + * @last_timestamp: passing timestamp from th to bh of interrupt handler + * @indio_dev: industrial I/O device structure + * @trig: data ready trigger registered with iio + * @tx: transmit buffer + * @rx: recieve buffer + * @buf_lock: mutex to protect tx and rx + **/ +struct adis16060_state { + struct spi_device *us_w; + struct spi_device *us_r; + struct work_struct work_trigger_to_ring; + s64 last_timestamp; + struct iio_dev *indio_dev; + struct iio_trigger *trig; + u8 *tx; + u8 *rx; + struct mutex buf_lock; +}; + +#if defined(CONFIG_IIO_RING_BUFFER) && defined(THIS_HAS_RING_BUFFER_SUPPORT) +/* At the moment triggers are only used for ring buffer + * filling. This may change! + */ + +enum adis16060_scan { + ADIS16060_SCAN_GYRO, + ADIS16060_SCAN_TEMP, + ADIS16060_SCAN_ADC_1, + ADIS16060_SCAN_ADC_2, +}; + +void adis16060_remove_trigger(struct iio_dev *indio_dev); +int adis16060_probe_trigger(struct iio_dev *indio_dev); + +ssize_t adis16060_read_data_from_ring(struct device *dev, + struct device_attribute *attr, + char *buf); + + +int adis16060_configure_ring(struct iio_dev *indio_dev); +void adis16060_unconfigure_ring(struct iio_dev *indio_dev); + +int adis16060_initialize_ring(struct iio_ring_buffer *ring); +void adis16060_uninitialize_ring(struct iio_ring_buffer *ring); +#else /* CONFIG_IIO_RING_BUFFER */ + +static inline void adis16060_remove_trigger(struct iio_dev *indio_dev) +{ +} + +static inline int adis16060_probe_trigger(struct iio_dev *indio_dev) +{ + return 0; +} + +static inline ssize_t +adis16060_read_data_from_ring(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + return 0; +} + +static int adis16060_configure_ring(struct iio_dev *indio_dev) +{ + return 0; +} + +static inline void adis16060_unconfigure_ring(struct iio_dev *indio_dev) +{ +} + +static inline int adis16060_initialize_ring(struct iio_ring_buffer *ring) +{ + return 0; +} + +static inline void adis16060_uninitialize_ring(struct iio_ring_buffer *ring) +{ +} + +#endif /* CONFIG_IIO_RING_BUFFER */ +#endif /* SPI_ADIS16060_H_ */ diff --git a/drivers/staging/iio/gyro/adis16060_core.c b/drivers/staging/iio/gyro/adis16060_core.c new file mode 100644 index 000000000000..fc48aca04bd3 --- /dev/null +++ b/drivers/staging/iio/gyro/adis16060_core.c @@ -0,0 +1,319 @@ +/* + * ADIS16060 Wide Bandwidth Yaw Rate Gyroscope with SPI driver + * + * Copyright 2010 Analog Devices Inc. + * + * Licensed under the GPL-2 or later. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../iio.h" +#include "../sysfs.h" +#include "gyro.h" +#include "../adc/adc.h" + +#include "adis16060.h" + +#define DRIVER_NAME "adis16060" + +struct adis16060_state *adis16060_st; + +int adis16060_spi_write(struct device *dev, + u8 val) +{ + int ret; + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct adis16060_state *st = iio_dev_get_devdata(indio_dev); + + mutex_lock(&st->buf_lock); + st->tx[0] = 0; + st->tx[1] = 0; + st->tx[2] = val; /* The last 8 bits clocked in are latched */ + + ret = spi_write(st->us_w, st->tx, 3); + mutex_unlock(&st->buf_lock); + + return ret; +} + +int adis16060_spi_read(struct device *dev, + u16 *val) +{ + int ret; + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct adis16060_state *st = iio_dev_get_devdata(indio_dev); + + mutex_lock(&st->buf_lock); + + ret = spi_read(st->us_r, st->rx, 3); + + /* The internal successive approximation ADC begins the conversion process + * on the falling edge of MSEL1 and starts to place data MSB first on the + * DOUT line at the 6th falling edge of SCLK + */ + if (ret == 0) + *val = ((st->rx[0] & 0x3) << 12) | (st->rx[1] << 4) | ((st->rx[2] >> 4) & 0xF); + mutex_unlock(&st->buf_lock); + + return ret; +} + +static ssize_t adis16060_read(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + u16 val; + ssize_t ret; + + /* Take the iio_dev status lock */ + mutex_lock(&indio_dev->mlock); + ret = adis16060_spi_read(dev, &val); + mutex_unlock(&indio_dev->mlock); + + if (ret == 0) + return sprintf(buf, "%d\n", val); + else + return ret; +} + +static ssize_t adis16060_write(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + int ret; + long val; + + ret = strict_strtol(buf, 16, &val); + if (ret) + goto error_ret; + ret = adis16060_spi_write(dev, val); + +error_ret: + return ret ? ret : len; +} + +#define IIO_DEV_ATTR_IN(_show) \ + IIO_DEVICE_ATTR(in, S_IRUGO, _show, NULL, 0) + +#define IIO_DEV_ATTR_OUT(_store) \ + IIO_DEVICE_ATTR(out, S_IRUGO, NULL, _store, 0) + +static IIO_DEV_ATTR_IN(adis16060_read); +static IIO_DEV_ATTR_OUT(adis16060_write); + +static IIO_CONST_ATTR(name, "adis16060"); + +static struct attribute *adis16060_event_attributes[] = { + NULL +}; + +static struct attribute_group adis16060_event_attribute_group = { + .attrs = adis16060_event_attributes, +}; + +static struct attribute *adis16060_attributes[] = { + &iio_dev_attr_in.dev_attr.attr, + &iio_dev_attr_out.dev_attr.attr, + &iio_const_attr_name.dev_attr.attr, + NULL +}; + +static const struct attribute_group adis16060_attribute_group = { + .attrs = adis16060_attributes, +}; + +static int __devinit adis16060_r_probe(struct spi_device *spi) +{ + int ret, regdone = 0; + struct adis16060_state *st = kzalloc(sizeof *st, GFP_KERNEL); + if (!st) { + ret = -ENOMEM; + goto error_ret; + } + /* this is only used for removal purposes */ + spi_set_drvdata(spi, st); + + /* Allocate the comms buffers */ + st->rx = kzalloc(sizeof(*st->rx)*ADIS16060_MAX_RX, GFP_KERNEL); + if (st->rx == NULL) { + ret = -ENOMEM; + goto error_free_st; + } + st->tx = kzalloc(sizeof(*st->tx)*ADIS16060_MAX_TX, GFP_KERNEL); + if (st->tx == NULL) { + ret = -ENOMEM; + goto error_free_rx; + } + st->us_r = spi; + mutex_init(&st->buf_lock); + /* setup the industrialio driver allocated elements */ + st->indio_dev = iio_allocate_device(); + if (st->indio_dev == NULL) { + ret = -ENOMEM; + goto error_free_tx; + } + + st->indio_dev->dev.parent = &spi->dev; + st->indio_dev->num_interrupt_lines = 1; + st->indio_dev->event_attrs = &adis16060_event_attribute_group; + st->indio_dev->attrs = &adis16060_attribute_group; + st->indio_dev->dev_data = (void *)(st); + st->indio_dev->driver_module = THIS_MODULE; + st->indio_dev->modes = INDIO_DIRECT_MODE; + + ret = adis16060_configure_ring(st->indio_dev); + if (ret) + goto error_free_dev; + + ret = iio_device_register(st->indio_dev); + if (ret) + goto error_unreg_ring_funcs; + regdone = 1; + + ret = adis16060_initialize_ring(st->indio_dev->ring); + if (ret) { + printk(KERN_ERR "failed to initialize the ring\n"); + goto error_unreg_ring_funcs; + } + + if (spi->irq && gpio_is_valid(irq_to_gpio(spi->irq)) > 0) { + ret = iio_register_interrupt_line(spi->irq, + st->indio_dev, + 0, + IRQF_TRIGGER_RISING, + "adis16060"); + if (ret) + goto error_uninitialize_ring; + + ret = adis16060_probe_trigger(st->indio_dev); + if (ret) + goto error_unregister_line; + } + + adis16060_st = st; + return 0; + +error_unregister_line: + if (st->indio_dev->modes & INDIO_RING_TRIGGERED) + iio_unregister_interrupt_line(st->indio_dev, 0); +error_uninitialize_ring: + adis16060_uninitialize_ring(st->indio_dev->ring); +error_unreg_ring_funcs: + adis16060_unconfigure_ring(st->indio_dev); +error_free_dev: + if (regdone) + iio_device_unregister(st->indio_dev); + else + iio_free_device(st->indio_dev); +error_free_tx: + kfree(st->tx); +error_free_rx: + kfree(st->rx); +error_free_st: + kfree(st); +error_ret: + return ret; +} + +/* fixme, confirm ordering in this function */ +static int adis16060_r_remove(struct spi_device *spi) +{ + struct adis16060_state *st = spi_get_drvdata(spi); + struct iio_dev *indio_dev = st->indio_dev; + + flush_scheduled_work(); + + adis16060_remove_trigger(indio_dev); + if (spi->irq && gpio_is_valid(irq_to_gpio(spi->irq)) > 0) + iio_unregister_interrupt_line(indio_dev, 0); + + adis16060_uninitialize_ring(indio_dev->ring); + adis16060_unconfigure_ring(indio_dev); + iio_device_unregister(indio_dev); + kfree(st->tx); + kfree(st->rx); + kfree(st); + + return 0; +} + +static int __devinit adis16060_w_probe(struct spi_device *spi) +{ + int ret; + struct adis16060_state *st = adis16060_st; + if (!st) { + ret = -ENODEV; + goto error_ret; + } + spi_set_drvdata(spi, st); + st->us_w = spi; + return 0; + +error_ret: + return ret; +} + +static int adis16060_w_remove(struct spi_device *spi) +{ + return 0; +} + +static struct spi_driver adis16060_r_driver = { + .driver = { + .name = "adis16060_r", + .owner = THIS_MODULE, + }, + .probe = adis16060_r_probe, + .remove = __devexit_p(adis16060_r_remove), +}; + +static struct spi_driver adis16060_w_driver = { + .driver = { + .name = "adis16060_w", + .owner = THIS_MODULE, + }, + .probe = adis16060_w_probe, + .remove = __devexit_p(adis16060_w_remove), +}; + +static __init int adis16060_init(void) +{ + int ret; + + ret = spi_register_driver(&adis16060_r_driver); + if (ret < 0) + return ret; + + ret = spi_register_driver(&adis16060_w_driver); + if (ret < 0) { + spi_unregister_driver(&adis16060_r_driver); + return ret; + } + + return 0; +} +module_init(adis16060_init); + +static __exit void adis16060_exit(void) +{ + spi_unregister_driver(&adis16060_w_driver); + spi_unregister_driver(&adis16060_r_driver); +} +module_exit(adis16060_exit); + +MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>"); +MODULE_DESCRIPTION("Analog Devices ADIS16060 Yaw Rate Gyroscope with SPI driver"); +MODULE_LICENSE("GPL v2"); -- cgit v1.2.3 From 1b2f99e1ae79b6039340571312ebbe0551d39c16 Mon Sep 17 00:00:00 2001 From: Barry Song Date: Wed, 27 Oct 2010 21:44:05 -0400 Subject: staging: iio: gyro: new driver for ADIS16080 digital output gyros Signed-off-by: Barry Song Signed-off-by: Michael Hennerich Acked-by: Jonathan Cameron Signed-off-by: Mike Frysinger Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/gyro/Kconfig | 7 + drivers/staging/iio/gyro/Makefile | 3 + drivers/staging/iio/gyro/adis16080.h | 102 +++++++++++ drivers/staging/iio/gyro/adis16080_core.c | 271 ++++++++++++++++++++++++++++++ 4 files changed, 383 insertions(+) create mode 100644 drivers/staging/iio/gyro/adis16080.h create mode 100644 drivers/staging/iio/gyro/adis16080_core.c diff --git a/drivers/staging/iio/gyro/Kconfig b/drivers/staging/iio/gyro/Kconfig index 77c0fe84380b..f219c948c85a 100644 --- a/drivers/staging/iio/gyro/Kconfig +++ b/drivers/staging/iio/gyro/Kconfig @@ -10,6 +10,13 @@ config ADIS16060 Say yes here to build support for Analog Devices adis16060 wide bandwidth yaw rate gyroscope with SPI. +config ADIS16080 + tristate "Analog Devices ADIS16080/100 Yaw Rate Gyroscope with SPI driver" + depends on SPI + help + Say yes here to build support for Analog Devices adis16080/100 Yaw Rate + Gyroscope with SPI. + config ADIS16260 tristate "Analog Devices ADIS16260 ADIS16265 Digital Gyroscope Sensor SPI driver" depends on SPI diff --git a/drivers/staging/iio/gyro/Makefile b/drivers/staging/iio/gyro/Makefile index e2c4acb608b4..747823f016df 100644 --- a/drivers/staging/iio/gyro/Makefile +++ b/drivers/staging/iio/gyro/Makefile @@ -5,6 +5,9 @@ adis16060-y := adis16060_core.o obj-$(CONFIG_ADIS16060) += adis16060.o +adis16080-y := adis16080_core.o +obj-$(CONFIG_ADIS16080) += adis16080.o + adis16260-y := adis16260_core.o adis16260-$(CONFIG_IIO_RING_BUFFER) += adis16260_ring.o adis16260_trigger.o obj-$(CONFIG_ADIS16260) += adis16260.o diff --git a/drivers/staging/iio/gyro/adis16080.h b/drivers/staging/iio/gyro/adis16080.h new file mode 100644 index 000000000000..3fcbe67f7c31 --- /dev/null +++ b/drivers/staging/iio/gyro/adis16080.h @@ -0,0 +1,102 @@ +#ifndef SPI_ADIS16080_H_ +#define SPI_ADIS16080_H_ + +#define ADIS16080_DIN_CODE 4 /* Output data format setting. 0: Twos complement. 1: Offset binary. */ +#define ADIS16080_DIN_GYRO (0 << 10) /* Gyroscope output */ +#define ADIS16080_DIN_TEMP (1 << 10) /* Temperature output */ +#define ADIS16080_DIN_AIN1 (2 << 10) +#define ADIS16080_DIN_AIN2 (3 << 10) +#define ADIS16080_DIN_WRITE (1 << 15) /* 1: Write contents on DIN to control register. + * 0: No changes to control register. + */ + +#define ADIS16080_MAX_TX 2 +#define ADIS16080_MAX_RX 2 + +/** + * struct adis16080_state - device instance specific data + * @us: actual spi_device to write data + * @work_trigger_to_ring: bh for triggered event handling + * @inter: used to check if new interrupt has been triggered + * @last_timestamp: passing timestamp from th to bh of interrupt handler + * @indio_dev: industrial I/O device structure + * @trig: data ready trigger registered with iio + * @tx: transmit buffer + * @rx: recieve buffer + * @buf_lock: mutex to protect tx and rx + **/ +struct adis16080_state { + struct spi_device *us; + struct work_struct work_trigger_to_ring; + s64 last_timestamp; + struct iio_dev *indio_dev; + struct iio_trigger *trig; + u8 *tx; + u8 *rx; + struct mutex buf_lock; +}; + +#if defined(CONFIG_IIO_RING_BUFFER) && defined(THIS_HAS_RING_BUFFER_SUPPORT) +/* At the moment triggers are only used for ring buffer + * filling. This may change! + */ + +enum adis16080_scan { + ADIS16080_SCAN_GYRO, + ADIS16080_SCAN_TEMP, + ADIS16080_SCAN_ADC_1, + ADIS16080_SCAN_ADC_2, +}; + +void adis16080_remove_trigger(struct iio_dev *indio_dev); +int adis16080_probe_trigger(struct iio_dev *indio_dev); + +ssize_t adis16080_read_data_from_ring(struct device *dev, + struct device_attribute *attr, + char *buf); + + +int adis16080_configure_ring(struct iio_dev *indio_dev); +void adis16080_unconfigure_ring(struct iio_dev *indio_dev); + +int adis16080_initialize_ring(struct iio_ring_buffer *ring); +void adis16080_uninitialize_ring(struct iio_ring_buffer *ring); +#else /* CONFIG_IIO_RING_BUFFER */ + +static inline void adis16080_remove_trigger(struct iio_dev *indio_dev) +{ +} + +static inline int adis16080_probe_trigger(struct iio_dev *indio_dev) +{ + return 0; +} + +static inline ssize_t +adis16080_read_data_from_ring(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + return 0; +} + +static int adis16080_configure_ring(struct iio_dev *indio_dev) +{ + return 0; +} + +static inline void adis16080_unconfigure_ring(struct iio_dev *indio_dev) +{ +} + +static inline int adis16080_initialize_ring(struct iio_ring_buffer *ring) +{ + return 0; +} + +static inline void adis16080_uninitialize_ring(struct iio_ring_buffer *ring) +{ +} + +#endif /* CONFIG_IIO_RING_BUFFER */ +#endif /* SPI_ADIS16080_H_ */ diff --git a/drivers/staging/iio/gyro/adis16080_core.c b/drivers/staging/iio/gyro/adis16080_core.c new file mode 100644 index 000000000000..0efb768db7d3 --- /dev/null +++ b/drivers/staging/iio/gyro/adis16080_core.c @@ -0,0 +1,271 @@ +/* + * ADIS16080/100 Yaw Rate Gyroscope with SPI driver + * + * Copyright 2010 Analog Devices Inc. + * + * Licensed under the GPL-2 or later. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../iio.h" +#include "../sysfs.h" +#include "gyro.h" +#include "../adc/adc.h" + +#include "adis16080.h" + +#define DRIVER_NAME "adis16080" + +struct adis16080_state *adis16080_st; + +int adis16080_spi_write(struct device *dev, + u16 val) +{ + int ret; + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct adis16080_state *st = iio_dev_get_devdata(indio_dev); + + mutex_lock(&st->buf_lock); + st->tx[0] = val >> 8; + st->tx[1] = val; + + ret = spi_write(st->us, st->tx, 2); + mutex_unlock(&st->buf_lock); + + return ret; +} + +int adis16080_spi_read(struct device *dev, + u16 *val) +{ + int ret; + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct adis16080_state *st = iio_dev_get_devdata(indio_dev); + + mutex_lock(&st->buf_lock); + + ret = spi_read(st->us, st->rx, 2); + + if (ret == 0) + *val = ((st->rx[0] & 0xF) << 8) | st->rx[1]; + mutex_unlock(&st->buf_lock); + + return ret; +} + +static ssize_t adis16080_read(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + u16 val; + ssize_t ret; + + /* Take the iio_dev status lock */ + mutex_lock(&indio_dev->mlock); + ret = adis16080_spi_read(dev, &val); + mutex_unlock(&indio_dev->mlock); + + if (ret == 0) + return sprintf(buf, "%d\n", val); + else + return ret; +} + +static ssize_t adis16080_write(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + int ret; + long val; + + ret = strict_strtol(buf, 16, &val); + if (ret) + goto error_ret; + ret = adis16080_spi_write(dev, val); + +error_ret: + return ret ? ret : len; +} + +#define IIO_DEV_ATTR_IN(_show) \ + IIO_DEVICE_ATTR(in, S_IRUGO, _show, NULL, 0) + +#define IIO_DEV_ATTR_OUT(_store) \ + IIO_DEVICE_ATTR(out, S_IRUGO, NULL, _store, 0) + +static IIO_DEV_ATTR_IN(adis16080_read); +static IIO_DEV_ATTR_OUT(adis16080_write); + +static IIO_CONST_ATTR(name, "adis16080"); + +static struct attribute *adis16080_event_attributes[] = { + NULL +}; + +static struct attribute_group adis16080_event_attribute_group = { + .attrs = adis16080_event_attributes, +}; + +static struct attribute *adis16080_attributes[] = { + &iio_dev_attr_in.dev_attr.attr, + &iio_dev_attr_out.dev_attr.attr, + &iio_const_attr_name.dev_attr.attr, + NULL +}; + +static const struct attribute_group adis16080_attribute_group = { + .attrs = adis16080_attributes, +}; + +static int __devinit adis16080_probe(struct spi_device *spi) +{ + int ret, regdone = 0; + struct adis16080_state *st = kzalloc(sizeof *st, GFP_KERNEL); + if (!st) { + ret = -ENOMEM; + goto error_ret; + } + /* this is only used for removal purposes */ + spi_set_drvdata(spi, st); + + /* Allocate the comms buffers */ + st->rx = kzalloc(sizeof(*st->rx)*ADIS16080_MAX_RX, GFP_KERNEL); + if (st->rx == NULL) { + ret = -ENOMEM; + goto error_free_st; + } + st->tx = kzalloc(sizeof(*st->tx)*ADIS16080_MAX_TX, GFP_KERNEL); + if (st->tx == NULL) { + ret = -ENOMEM; + goto error_free_rx; + } + st->us = spi; + mutex_init(&st->buf_lock); + /* setup the industrialio driver allocated elements */ + st->indio_dev = iio_allocate_device(); + if (st->indio_dev == NULL) { + ret = -ENOMEM; + goto error_free_tx; + } + + st->indio_dev->dev.parent = &spi->dev; + st->indio_dev->num_interrupt_lines = 1; + st->indio_dev->event_attrs = &adis16080_event_attribute_group; + st->indio_dev->attrs = &adis16080_attribute_group; + st->indio_dev->dev_data = (void *)(st); + st->indio_dev->driver_module = THIS_MODULE; + st->indio_dev->modes = INDIO_DIRECT_MODE; + + ret = adis16080_configure_ring(st->indio_dev); + if (ret) + goto error_free_dev; + + ret = iio_device_register(st->indio_dev); + if (ret) + goto error_unreg_ring_funcs; + regdone = 1; + + ret = adis16080_initialize_ring(st->indio_dev->ring); + if (ret) { + printk(KERN_ERR "failed to initialize the ring\n"); + goto error_unreg_ring_funcs; + } + + if (spi->irq && gpio_is_valid(irq_to_gpio(spi->irq)) > 0) { + ret = iio_register_interrupt_line(spi->irq, + st->indio_dev, + 0, + IRQF_TRIGGER_RISING, + "adis16080"); + if (ret) + goto error_uninitialize_ring; + + ret = adis16080_probe_trigger(st->indio_dev); + if (ret) + goto error_unregister_line; + } + + adis16080_st = st; + return 0; + +error_unregister_line: + if (st->indio_dev->modes & INDIO_RING_TRIGGERED) + iio_unregister_interrupt_line(st->indio_dev, 0); +error_uninitialize_ring: + adis16080_uninitialize_ring(st->indio_dev->ring); +error_unreg_ring_funcs: + adis16080_unconfigure_ring(st->indio_dev); +error_free_dev: + if (regdone) + iio_device_unregister(st->indio_dev); + else + iio_free_device(st->indio_dev); +error_free_tx: + kfree(st->tx); +error_free_rx: + kfree(st->rx); +error_free_st: + kfree(st); +error_ret: + return ret; +} + +/* fixme, confirm ordering in this function */ +static int adis16080_remove(struct spi_device *spi) +{ + struct adis16080_state *st = spi_get_drvdata(spi); + struct iio_dev *indio_dev = st->indio_dev; + + flush_scheduled_work(); + + adis16080_remove_trigger(indio_dev); + if (spi->irq && gpio_is_valid(irq_to_gpio(spi->irq)) > 0) + iio_unregister_interrupt_line(indio_dev, 0); + + adis16080_uninitialize_ring(indio_dev->ring); + adis16080_unconfigure_ring(indio_dev); + iio_device_unregister(indio_dev); + kfree(st->tx); + kfree(st->rx); + kfree(st); + + return 0; +} + +static struct spi_driver adis16080_driver = { + .driver = { + .name = "adis16080", + .owner = THIS_MODULE, + }, + .probe = adis16080_probe, + .remove = __devexit_p(adis16080_remove), +}; + +static __init int adis16080_init(void) +{ + return spi_register_driver(&adis16080_driver); +} +module_init(adis16080_init); + +static __exit void adis16080_exit(void) +{ + spi_unregister_driver(&adis16080_driver); +} +module_exit(adis16080_exit); + +MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>"); +MODULE_DESCRIPTION("Analog Devices ADIS16080/100 Yaw Rate Gyroscope with SPI driver"); +MODULE_LICENSE("GPL v2"); -- cgit v1.2.3 From 7a83f60d7bdf619cb7a37b5e0f6c128a91c6ecd0 Mon Sep 17 00:00:00 2001 From: Barry Song Date: Wed, 27 Oct 2010 21:44:06 -0400 Subject: staging: iio: gyro: new driver for ADIS16130 digital output gyros Signed-off-by: Barry Song Signed-off-by: Michael Hennerich Acked-by: Jonathan Cameron Signed-off-by: Mike Frysinger Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/gyro/Kconfig | 7 + drivers/staging/iio/gyro/Makefile | 3 + drivers/staging/iio/gyro/adis16130.h | 108 +++++++++++ drivers/staging/iio/gyro/adis16130_core.c | 313 ++++++++++++++++++++++++++++++ 4 files changed, 431 insertions(+) create mode 100644 drivers/staging/iio/gyro/adis16130.h create mode 100644 drivers/staging/iio/gyro/adis16130_core.c diff --git a/drivers/staging/iio/gyro/Kconfig b/drivers/staging/iio/gyro/Kconfig index f219c948c85a..236f15fdbfc9 100644 --- a/drivers/staging/iio/gyro/Kconfig +++ b/drivers/staging/iio/gyro/Kconfig @@ -17,6 +17,13 @@ config ADIS16080 Say yes here to build support for Analog Devices adis16080/100 Yaw Rate Gyroscope with SPI. +config ADIS16130 + tristate "Analog Devices ADIS16130 High Precision Angular Rate Sensor driver" + depends on SPI + help + Say yes here to build support for Analog Devices ADIS16130 High Precision + Angular Rate Sensor driver. + config ADIS16260 tristate "Analog Devices ADIS16260 ADIS16265 Digital Gyroscope Sensor SPI driver" depends on SPI diff --git a/drivers/staging/iio/gyro/Makefile b/drivers/staging/iio/gyro/Makefile index 747823f016df..2764c15025a5 100644 --- a/drivers/staging/iio/gyro/Makefile +++ b/drivers/staging/iio/gyro/Makefile @@ -8,6 +8,9 @@ obj-$(CONFIG_ADIS16060) += adis16060.o adis16080-y := adis16080_core.o obj-$(CONFIG_ADIS16080) += adis16080.o +adis16130-y := adis16130_core.o +obj-$(CONFIG_ADIS16130) += adis16130.o + adis16260-y := adis16260_core.o adis16260-$(CONFIG_IIO_RING_BUFFER) += adis16260_ring.o adis16260_trigger.o obj-$(CONFIG_ADIS16260) += adis16260.o diff --git a/drivers/staging/iio/gyro/adis16130.h b/drivers/staging/iio/gyro/adis16130.h new file mode 100644 index 000000000000..ab80ef6a8961 --- /dev/null +++ b/drivers/staging/iio/gyro/adis16130.h @@ -0,0 +1,108 @@ +#ifndef SPI_ADIS16130_H_ +#define SPI_ADIS16130_H_ + +#define ADIS16130_CON 0x0 +#define ADIS16130_CON_RD (1 << 6) +#define ADIS16130_IOP 0x1 +#define ADIS16130_IOP_ALL_RDY (1 << 3) /* 1 = data-ready signal low when unread data on all channels; */ +#define ADIS16130_IOP_SYNC (1 << 0) /* 1 = synchronization enabled */ +#define ADIS16130_RATEDATA 0x8 /* Gyroscope output, rate of rotation */ +#define ADIS16130_TEMPDATA 0xA /* Temperature output */ +#define ADIS16130_RATECS 0x28 /* Gyroscope channel setup */ +#define ADIS16130_RATECS_EN (1 << 3) /* 1 = channel enable; */ +#define ADIS16130_TEMPCS 0x2A /* Temperature channel setup */ +#define ADIS16130_TEMPCS_EN (1 << 3) +#define ADIS16130_RATECONV 0x30 +#define ADIS16130_TEMPCONV 0x32 +#define ADIS16130_MODE 0x38 +#define ADIS16130_MODE_24BIT (1 << 1) /* 1 = 24-bit resolution; */ + +#define ADIS16130_MAX_TX 4 +#define ADIS16130_MAX_RX 4 + +/** + * struct adis16130_state - device instance specific data + * @us: actual spi_device to write data + * @work_trigger_to_ring: bh for triggered event handling + * @inter: used to check if new interrupt has been triggered + * @last_timestamp: passing timestamp from th to bh of interrupt handler + * @indio_dev: industrial I/O device structure + * @trig: data ready trigger registered with iio + * @tx: transmit buffer + * @rx: recieve buffer + * @buf_lock: mutex to protect tx and rx + **/ +struct adis16130_state { + struct spi_device *us; + struct work_struct work_trigger_to_ring; + s64 last_timestamp; + struct iio_dev *indio_dev; + struct iio_trigger *trig; + u8 *tx; + u8 *rx; + u32 mode; /* 1: 24bits mode 0:16bits mode */ + struct mutex buf_lock; +}; + +#if defined(CONFIG_IIO_RING_BUFFER) && defined(THIS_HAS_RING_BUFFER_SUPPORT) +/* At the moment triggers are only used for ring buffer + * filling. This may change! + */ + +enum adis16130_scan { + ADIS16130_SCAN_GYRO, + ADIS16130_SCAN_TEMP, +}; + +void adis16130_remove_trigger(struct iio_dev *indio_dev); +int adis16130_probe_trigger(struct iio_dev *indio_dev); + +ssize_t adis16130_read_data_from_ring(struct device *dev, + struct device_attribute *attr, + char *buf); + + +int adis16130_configure_ring(struct iio_dev *indio_dev); +void adis16130_unconfigure_ring(struct iio_dev *indio_dev); + +int adis16130_initialize_ring(struct iio_ring_buffer *ring); +void adis16130_uninitialize_ring(struct iio_ring_buffer *ring); +#else /* CONFIG_IIO_RING_BUFFER */ + +static inline void adis16130_remove_trigger(struct iio_dev *indio_dev) +{ +} + +static inline int adis16130_probe_trigger(struct iio_dev *indio_dev) +{ + return 0; +} + +static inline ssize_t +adis16130_read_data_from_ring(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + return 0; +} + +static int adis16130_configure_ring(struct iio_dev *indio_dev) +{ + return 0; +} + +static inline void adis16130_unconfigure_ring(struct iio_dev *indio_dev) +{ +} + +static inline int adis16130_initialize_ring(struct iio_ring_buffer *ring) +{ + return 0; +} + +static inline void adis16130_uninitialize_ring(struct iio_ring_buffer *ring) +{ +} + +#endif /* CONFIG_IIO_RING_BUFFER */ +#endif /* SPI_ADIS16130_H_ */ diff --git a/drivers/staging/iio/gyro/adis16130_core.c b/drivers/staging/iio/gyro/adis16130_core.c new file mode 100644 index 000000000000..49ffc7b26e8a --- /dev/null +++ b/drivers/staging/iio/gyro/adis16130_core.c @@ -0,0 +1,313 @@ +/* + * ADIS16130 Digital Output, High Precision Angular Rate Sensor driver + * + * Copyright 2010 Analog Devices Inc. + * + * Licensed under the GPL-2 or later. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../iio.h" +#include "../sysfs.h" +#include "gyro.h" +#include "../adc/adc.h" + +#include "adis16130.h" + +#define DRIVER_NAME "adis16130" + +struct adis16130_state *adis16130_st; + +int adis16130_spi_write(struct device *dev, u8 reg_addr, + u8 val) +{ + int ret; + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct adis16130_state *st = iio_dev_get_devdata(indio_dev); + + mutex_lock(&st->buf_lock); + st->tx[0] = reg_addr; + st->tx[1] = val; + + ret = spi_write(st->us, st->tx, 2); + mutex_unlock(&st->buf_lock); + + return ret; +} + +int adis16130_spi_read(struct device *dev, u8 reg_addr, + u32 *val) +{ + int ret; + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct adis16130_state *st = iio_dev_get_devdata(indio_dev); + + mutex_lock(&st->buf_lock); + + st->tx[0] = ADIS16130_CON_RD | reg_addr; + if (st->mode) + ret = spi_read(st->us, st->rx, 4); + else + ret = spi_read(st->us, st->rx, 3); + + if (ret == 0) { + if (st->mode) + *val = (st->rx[1] << 16) | (st->rx[2] << 8) | st->rx[3]; + else + *val = (st->rx[1] << 8) | st->rx[2]; + } + + mutex_unlock(&st->buf_lock); + + return ret; +} + +static ssize_t adis16130_gyro_read(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + u32 val; + ssize_t ret; + + /* Take the iio_dev status lock */ + mutex_lock(&indio_dev->mlock); + ret = adis16130_spi_read(dev, ADIS16130_RATEDATA, &val); + mutex_unlock(&indio_dev->mlock); + + if (ret == 0) + return sprintf(buf, "%d\n", val); + else + return ret; +} + +static ssize_t adis16130_temp_read(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + u32 val; + ssize_t ret; + + /* Take the iio_dev status lock */ + mutex_lock(&indio_dev->mlock); + ret = adis16130_spi_read(dev, ADIS16130_TEMPDATA, &val); + mutex_unlock(&indio_dev->mlock); + + if (ret == 0) + return sprintf(buf, "%d\n", val); + else + return ret; +} + +static ssize_t adis16130_bitsmode_read(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct adis16130_state *st = iio_dev_get_devdata(indio_dev); + + return sprintf(buf, "%d\n", st->mode); +} + +static ssize_t adis16130_bitsmode_write(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + int ret; + long val; + + ret = strict_strtol(buf, 16, &val); + if (ret) + goto error_ret; + ret = adis16130_spi_write(dev, ADIS16130_MODE, !!val); + +error_ret: + return ret ? ret : len; +} + +static IIO_DEV_ATTR_TEMP_RAW(adis16130_temp_read); + +static IIO_CONST_ATTR(name, "adis16130"); + +static IIO_DEV_ATTR_GYRO(adis16130_gyro_read, + ADIS16130_RATEDATA); + +#define IIO_DEV_ATTR_BITS_MODE(_mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(bits_mode, _mode, _show, _store, _addr) + +static IIO_DEV_ATTR_BITS_MODE(S_IWUSR | S_IRUGO, adis16130_bitsmode_read, adis16130_bitsmode_write, + ADIS16130_MODE); + +static struct attribute *adis16130_event_attributes[] = { + NULL +}; + +static struct attribute_group adis16130_event_attribute_group = { + .attrs = adis16130_event_attributes, +}; + +static struct attribute *adis16130_attributes[] = { + &iio_dev_attr_temp_raw.dev_attr.attr, + &iio_const_attr_name.dev_attr.attr, + &iio_dev_attr_gyro_raw.dev_attr.attr, + &iio_dev_attr_bits_mode.dev_attr.attr, + NULL +}; + +static const struct attribute_group adis16130_attribute_group = { + .attrs = adis16130_attributes, +}; + +static int __devinit adis16130_probe(struct spi_device *spi) +{ + int ret, regdone = 0; + struct adis16130_state *st = kzalloc(sizeof *st, GFP_KERNEL); + if (!st) { + ret = -ENOMEM; + goto error_ret; + } + /* this is only used for removal purposes */ + spi_set_drvdata(spi, st); + + /* Allocate the comms buffers */ + st->rx = kzalloc(sizeof(*st->rx)*ADIS16130_MAX_RX, GFP_KERNEL); + if (st->rx == NULL) { + ret = -ENOMEM; + goto error_free_st; + } + st->tx = kzalloc(sizeof(*st->tx)*ADIS16130_MAX_TX, GFP_KERNEL); + if (st->tx == NULL) { + ret = -ENOMEM; + goto error_free_rx; + } + st->us = spi; + mutex_init(&st->buf_lock); + /* setup the industrialio driver allocated elements */ + st->indio_dev = iio_allocate_device(); + if (st->indio_dev == NULL) { + ret = -ENOMEM; + goto error_free_tx; + } + + st->indio_dev->dev.parent = &spi->dev; + st->indio_dev->num_interrupt_lines = 1; + st->indio_dev->event_attrs = &adis16130_event_attribute_group; + st->indio_dev->attrs = &adis16130_attribute_group; + st->indio_dev->dev_data = (void *)(st); + st->indio_dev->driver_module = THIS_MODULE; + st->indio_dev->modes = INDIO_DIRECT_MODE; + st->mode = 1; + + ret = adis16130_configure_ring(st->indio_dev); + if (ret) + goto error_free_dev; + + ret = iio_device_register(st->indio_dev); + if (ret) + goto error_unreg_ring_funcs; + regdone = 1; + + ret = adis16130_initialize_ring(st->indio_dev->ring); + if (ret) { + printk(KERN_ERR "failed to initialize the ring\n"); + goto error_unreg_ring_funcs; + } + + if (spi->irq && gpio_is_valid(irq_to_gpio(spi->irq)) > 0) { + ret = iio_register_interrupt_line(spi->irq, + st->indio_dev, + 0, + IRQF_TRIGGER_RISING, + "adis16130"); + if (ret) + goto error_uninitialize_ring; + + ret = adis16130_probe_trigger(st->indio_dev); + if (ret) + goto error_unregister_line; + } + + adis16130_st = st; + return 0; + +error_unregister_line: + if (st->indio_dev->modes & INDIO_RING_TRIGGERED) + iio_unregister_interrupt_line(st->indio_dev, 0); +error_uninitialize_ring: + adis16130_uninitialize_ring(st->indio_dev->ring); +error_unreg_ring_funcs: + adis16130_unconfigure_ring(st->indio_dev); +error_free_dev: + if (regdone) + iio_device_unregister(st->indio_dev); + else + iio_free_device(st->indio_dev); +error_free_tx: + kfree(st->tx); +error_free_rx: + kfree(st->rx); +error_free_st: + kfree(st); +error_ret: + return ret; +} + +/* fixme, confirm ordering in this function */ +static int adis16130_remove(struct spi_device *spi) +{ + struct adis16130_state *st = spi_get_drvdata(spi); + struct iio_dev *indio_dev = st->indio_dev; + + flush_scheduled_work(); + + adis16130_remove_trigger(indio_dev); + if (spi->irq && gpio_is_valid(irq_to_gpio(spi->irq)) > 0) + iio_unregister_interrupt_line(indio_dev, 0); + + adis16130_uninitialize_ring(indio_dev->ring); + adis16130_unconfigure_ring(indio_dev); + iio_device_unregister(indio_dev); + kfree(st->tx); + kfree(st->rx); + kfree(st); + + return 0; +} + +static struct spi_driver adis16130_driver = { + .driver = { + .name = "adis16130", + .owner = THIS_MODULE, + }, + .probe = adis16130_probe, + .remove = __devexit_p(adis16130_remove), +}; + +static __init int adis16130_init(void) +{ + return spi_register_driver(&adis16130_driver); +} +module_init(adis16130_init); + +static __exit void adis16130_exit(void) +{ + spi_unregister_driver(&adis16130_driver); +} +module_exit(adis16130_exit); + +MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>"); +MODULE_DESCRIPTION("Analog Devices ADIS16130 High Precision Angular Rate Sensor driver"); +MODULE_LICENSE("GPL v2"); -- cgit v1.2.3 From 6790e29fef61b20b213bd1cf5a025dc3412a4765 Mon Sep 17 00:00:00 2001 From: Barry Song Date: Wed, 27 Oct 2010 21:44:07 -0400 Subject: staging: iio: dac: new driver for AD5624R devices This is used to convert digital streams into voltages. Signed-off-by: Barry Song Signed-off-by: Michael Hennerich Acked-by: Jonathan Cameron Signed-off-by: Mike Frysinger Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/Kconfig | 1 + drivers/staging/iio/Makefile | 1 + drivers/staging/iio/dac/Kconfig | 11 ++ drivers/staging/iio/dac/Makefile | 5 + drivers/staging/iio/dac/ad5624r.h | 21 +++ drivers/staging/iio/dac/ad5624r_spi.c | 313 ++++++++++++++++++++++++++++++++++ drivers/staging/iio/dac/dac.h | 6 + 7 files changed, 358 insertions(+) create mode 100644 drivers/staging/iio/dac/Kconfig create mode 100644 drivers/staging/iio/dac/Makefile create mode 100644 drivers/staging/iio/dac/ad5624r.h create mode 100644 drivers/staging/iio/dac/ad5624r_spi.c create mode 100644 drivers/staging/iio/dac/dac.h diff --git a/drivers/staging/iio/Kconfig b/drivers/staging/iio/Kconfig index b8bb5f162540..773c30128ee7 100644 --- a/drivers/staging/iio/Kconfig +++ b/drivers/staging/iio/Kconfig @@ -43,6 +43,7 @@ config IIO_TRIGGER source "drivers/staging/iio/accel/Kconfig" source "drivers/staging/iio/adc/Kconfig" source "drivers/staging/iio/addac/Kconfig" +source "drivers/staging/iio/dac/Kconfig" source "drivers/staging/iio/gyro/Kconfig" source "drivers/staging/iio/imu/Kconfig" source "drivers/staging/iio/light/Kconfig" diff --git a/drivers/staging/iio/Makefile b/drivers/staging/iio/Makefile index 0111647b9b9a..15eba01805bf 100644 --- a/drivers/staging/iio/Makefile +++ b/drivers/staging/iio/Makefile @@ -12,6 +12,7 @@ obj-$(CONFIG_IIO_SW_RING) += ring_sw.o obj-y += accel/ obj-y += adc/ obj-y += addac/ +obj-y += dac/ obj-y += gyro/ obj-y += imu/ obj-y += light/ diff --git a/drivers/staging/iio/dac/Kconfig b/drivers/staging/iio/dac/Kconfig new file mode 100644 index 000000000000..583df785fd25 --- /dev/null +++ b/drivers/staging/iio/dac/Kconfig @@ -0,0 +1,11 @@ +# +# DAC drivers +# +comment "Digital to analog convertors" + +config AD5624R_SPI + tristate "Analog Devices AD5624/44/64R DAC spi driver" + depends on SPI + help + Say yes here to build support for Analog Devices AD5624R, AD5644R and + AD5664R convertors (DAC). This driver uses the common SPI interface. diff --git a/drivers/staging/iio/dac/Makefile b/drivers/staging/iio/dac/Makefile new file mode 100644 index 000000000000..7ddf05d5f1b4 --- /dev/null +++ b/drivers/staging/iio/dac/Makefile @@ -0,0 +1,5 @@ +# +# Makefile for industrial I/O DAC drivers +# + +obj-$(CONFIG_AD5624R_SPI) += ad5624r_spi.o diff --git a/drivers/staging/iio/dac/ad5624r.h b/drivers/staging/iio/dac/ad5624r.h new file mode 100644 index 000000000000..ce518be652b7 --- /dev/null +++ b/drivers/staging/iio/dac/ad5624r.h @@ -0,0 +1,21 @@ +#ifndef SPI_AD5624R_H_ +#define SPI_AD5624R_H_ + +#define AD5624R_DAC_CHANNELS 4 + +#define AD5624R_ADDR_DAC0 0x0 +#define AD5624R_ADDR_DAC1 0x1 +#define AD5624R_ADDR_DAC2 0x2 +#define AD5624R_ADDR_DAC3 0x3 +#define AD5624R_ADDR_ALL_DAC 0x7 + +#define AD5624R_CMD_WRITE_INPUT_N 0x0 +#define AD5624R_CMD_UPDATE_DAC_N 0x1 +#define AD5624R_CMD_WRITE_INPUT_N_UPDATE_ALL 0x2 +#define AD5624R_CMD_WRITE_INPUT_N_UPDATE_N 0x3 +#define AD5624R_CMD_POWERDOWN_DAC 0x4 +#define AD5624R_CMD_RESET 0x5 +#define AD5624R_CMD_LDAC_SETUP 0x6 +#define AD5624R_CMD_INTERNAL_REFER_SETUP 0x7 + +#endif diff --git a/drivers/staging/iio/dac/ad5624r_spi.c b/drivers/staging/iio/dac/ad5624r_spi.c new file mode 100644 index 000000000000..705ff505bf25 --- /dev/null +++ b/drivers/staging/iio/dac/ad5624r_spi.c @@ -0,0 +1,313 @@ +/* + * AD5624R, AD5644R, AD5664R Digital to analog convertors spi driver + * + * Copyright 2010 Analog Devices Inc. + * + * Licensed under the GPL-2 or later. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../iio.h" +#include "../sysfs.h" +#include "dac.h" +#include "ad5624r.h" + +/** + * struct ad5624r_state - device related storage + * @indio_dev: associated industrial IO device + * @us: spi device + **/ +struct ad5624r_state { + struct iio_dev *indio_dev; + struct spi_device *us; + int data_len; + int ldac_mode; + int dac_power_mode[AD5624R_DAC_CHANNELS]; + int internal_ref; +}; + +static int ad5624r_spi_write(struct spi_device *spi, u8 cmd, u8 addr, u16 val, u8 len) +{ + struct spi_transfer t; + struct spi_message m; + u32 data; + u8 msg[3]; + + /* + * The input shift register is 24 bits wide. The first two bits are don't care bits. + * The next three are the command bits, C2 to C0, followed by the 3-bit DAC address, + * A2 to A0, and then the 16-, 14-, 12-bit data-word. The data-word comprises the 16-, + * 14-, 12-bit input code followed by 0, 2, or 4 don't care bits, for the AD5664R, + * AD5644R, and AD5624R, respectively. + */ + data = (0 << 22) | (cmd << 19) | (addr << 16) | (val << (16 - len)); + msg[0] = data >> 16; + msg[1] = data >> 8; + msg[2] = data; + + spi_message_init(&m); + memset(&t, 0, (sizeof t)); + t.tx_buf = &msg[0]; + t.len = 3; + + spi_message_add_tail(&t, &m); + spi_sync(spi, &m); + + return len; +} + +static ssize_t ad5624r_write_dac(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + long readin; + int ret; + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct ad5624r_state *st = indio_dev->dev_data; + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + + ret = strict_strtol(buf, 10, &readin); + if (ret) + return ret; + + ad5624r_spi_write(st->us, AD5624R_CMD_WRITE_INPUT_N_UPDATE_N, + this_attr->address, readin, st->data_len); + return ret ? ret : len; +} + +static ssize_t ad5624r_read_ldac_mode(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct ad5624r_state *st = indio_dev->dev_data; + + return sprintf(buf, "%x\n", st->ldac_mode); +} + +static ssize_t ad5624r_write_ldac_mode(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + long readin; + int ret; + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct ad5624r_state *st = indio_dev->dev_data; + + ret = strict_strtol(buf, 16, &readin); + if (ret) + return ret; + + ad5624r_spi_write(st->us, AD5624R_CMD_LDAC_SETUP, 0, readin & 0xF, 16); + st->ldac_mode = readin & 0xF; + + return ret ? ret : len; +} + +static ssize_t ad5624r_read_dac_power_mode(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct ad5624r_state *st = indio_dev->dev_data; + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + + return sprintf(buf, "%d\n", st->dac_power_mode[this_attr->address]); +} + +static ssize_t ad5624r_write_dac_power_mode(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + long readin; + int ret; + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct ad5624r_state *st = indio_dev->dev_data; + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + + ret = strict_strtol(buf, 10, &readin); + if (ret) + return ret; + + ad5624r_spi_write(st->us, AD5624R_CMD_POWERDOWN_DAC, 0, + ((readin & 0x3) << 4) | (1 << this_attr->address), 16); + + st->dac_power_mode[this_attr->address] = readin & 0x3; + + return ret ? ret : len; +} + +static ssize_t ad5624r_read_internal_ref_mode(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct ad5624r_state *st = indio_dev->dev_data; + + return sprintf(buf, "%d\n", st->internal_ref); +} + +static ssize_t ad5624r_write_internal_ref_mode(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + long readin; + int ret; + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct ad5624r_state *st = indio_dev->dev_data; + + ret = strict_strtol(buf, 10, &readin); + if (ret) + return ret; + + ad5624r_spi_write(st->us, AD5624R_CMD_INTERNAL_REFER_SETUP, 0, !!readin, 16); + + st->internal_ref = !!readin; + + return ret ? ret : len; +} + +static IIO_DEV_ATTR_DAC(0, ad5624r_write_dac, AD5624R_ADDR_DAC0); +static IIO_DEV_ATTR_DAC(1, ad5624r_write_dac, AD5624R_ADDR_DAC1); +static IIO_DEV_ATTR_DAC(2, ad5624r_write_dac, AD5624R_ADDR_DAC2); +static IIO_DEV_ATTR_DAC(3, ad5624r_write_dac, AD5624R_ADDR_DAC3); + +static IIO_DEVICE_ATTR(ldac_mode, S_IRUGO | S_IWUSR, ad5624r_read_ldac_mode, + ad5624r_write_ldac_mode, 0); +static IIO_DEVICE_ATTR(internal_ref, S_IRUGO | S_IWUSR, ad5624r_read_internal_ref_mode, + ad5624r_write_internal_ref_mode, 0); + +#define IIO_DEV_ATTR_DAC_POWER_MODE(_num, _show, _store, _addr) \ + IIO_DEVICE_ATTR(dac_power_mode_##_num, S_IRUGO | S_IWUSR, _show, _store, _addr) + +static IIO_DEV_ATTR_DAC_POWER_MODE(0, ad5624r_read_dac_power_mode, ad5624r_write_dac_power_mode, 0); +static IIO_DEV_ATTR_DAC_POWER_MODE(1, ad5624r_read_dac_power_mode, ad5624r_write_dac_power_mode, 1); +static IIO_DEV_ATTR_DAC_POWER_MODE(2, ad5624r_read_dac_power_mode, ad5624r_write_dac_power_mode, 2); +static IIO_DEV_ATTR_DAC_POWER_MODE(3, ad5624r_read_dac_power_mode, ad5624r_write_dac_power_mode, 3); + +static struct attribute *ad5624r_attributes[] = { + &iio_dev_attr_dac_0.dev_attr.attr, + &iio_dev_attr_dac_1.dev_attr.attr, + &iio_dev_attr_dac_2.dev_attr.attr, + &iio_dev_attr_dac_3.dev_attr.attr, + &iio_dev_attr_dac_power_mode_0.dev_attr.attr, + &iio_dev_attr_dac_power_mode_1.dev_attr.attr, + &iio_dev_attr_dac_power_mode_2.dev_attr.attr, + &iio_dev_attr_dac_power_mode_3.dev_attr.attr, + &iio_dev_attr_ldac_mode.dev_attr.attr, + &iio_dev_attr_internal_ref.dev_attr.attr, + NULL, +}; + +static const struct attribute_group ad5624r_attribute_group = { + .attrs = ad5624r_attributes, +}; + +static int __devinit ad5624r_probe(struct spi_device *spi) +{ + + struct ad5624r_state *st; + int ret = 0; + char *chip_name = spi->dev.platform_data; + + if (!chip_name) + return -ENODEV; + + st = kzalloc(sizeof(*st), GFP_KERNEL); + if (st == NULL) { + ret = -ENOMEM; + goto error_ret; + } + spi_set_drvdata(spi, st); + + if (strcmp(chip_name, "ad5624r") == 0) + st->data_len = 12; + else if (strcmp(chip_name, "ad5644r") == 0) + st->data_len = 14; + else if (strcmp(chip_name, "ad5664r") == 0) + st->data_len = 16; + else { + dev_err(&spi->dev, "not supported chip type\n"); + ret = -EINVAL; + goto error_ret; + } + + st->us = spi; + st->indio_dev = iio_allocate_device(); + if (st->indio_dev == NULL) { + ret = -ENOMEM; + goto error_free_st; + } + st->indio_dev->dev.parent = &spi->dev; + st->indio_dev->num_interrupt_lines = 0; + st->indio_dev->event_attrs = NULL; + + st->indio_dev->attrs = &ad5624r_attribute_group; + st->indio_dev->dev_data = (void *)(st); + st->indio_dev->driver_module = THIS_MODULE; + st->indio_dev->modes = INDIO_DIRECT_MODE; + + ret = iio_device_register(st->indio_dev); + if (ret) + goto error_free_dev; + + spi->mode = SPI_MODE_0; + spi_setup(spi); + + return 0; + +error_free_dev: + iio_free_device(st->indio_dev); +error_free_st: + kfree(st); +error_ret: + return ret; +} + +static int __devexit ad5624r_remove(struct spi_device *spi) +{ + struct ad5624r_state *st = spi_get_drvdata(spi); + + iio_device_unregister(st->indio_dev); + kfree(st); + + return 0; +} + +static struct spi_driver ad5624r_driver = { + .driver = { + .name = "ad5624r", + .owner = THIS_MODULE, + }, + .probe = ad5624r_probe, + .remove = __devexit_p(ad5624r_remove), +}; + +static __init int ad5624r_spi_init(void) +{ + return spi_register_driver(&ad5624r_driver); +} +module_init(ad5624r_spi_init); + +static __exit void ad5624r_spi_exit(void) +{ + spi_unregister_driver(&ad5624r_driver); +} +module_exit(ad5624r_spi_exit); + +MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>"); +MODULE_DESCRIPTION("Analog Devices AD5624/44/64R DAC spi driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/staging/iio/dac/dac.h b/drivers/staging/iio/dac/dac.h new file mode 100644 index 000000000000..55005eec1214 --- /dev/null +++ b/drivers/staging/iio/dac/dac.h @@ -0,0 +1,6 @@ +/* + * dac.h - sysfs attributes associated with DACs + */ + +#define IIO_DEV_ATTR_DAC(_num, _store, _addr) \ + IIO_DEVICE_ATTR(dac_##_num, S_IWUSR, NULL, _store, _addr) -- cgit v1.2.3 From da6fcbdf764cbc8f539333a725411183a4253cfa Mon Sep 17 00:00:00 2001 From: Cliff Cai Date: Wed, 27 Oct 2010 21:44:08 -0400 Subject: staging: iio: dds: new driver for AD5930/2 devices This is the initial driver in the new Direct Digital Synthesis section. Signed-off-by: Cliff Cai Signed-off-by: Michael Hennerich Acked-by: Jonathan Cameron Signed-off-by: Mike Frysinger Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/Kconfig | 1 + drivers/staging/iio/Makefile | 1 + drivers/staging/iio/dds/Kconfig | 11 +++ drivers/staging/iio/dds/Makefile | 5 ++ drivers/staging/iio/dds/ad5930.c | 170 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 188 insertions(+) create mode 100644 drivers/staging/iio/dds/Kconfig create mode 100644 drivers/staging/iio/dds/Makefile create mode 100644 drivers/staging/iio/dds/ad5930.c diff --git a/drivers/staging/iio/Kconfig b/drivers/staging/iio/Kconfig index 773c30128ee7..5e5bc475f299 100644 --- a/drivers/staging/iio/Kconfig +++ b/drivers/staging/iio/Kconfig @@ -44,6 +44,7 @@ source "drivers/staging/iio/accel/Kconfig" source "drivers/staging/iio/adc/Kconfig" source "drivers/staging/iio/addac/Kconfig" source "drivers/staging/iio/dac/Kconfig" +source "drivers/staging/iio/dds/Kconfig" source "drivers/staging/iio/gyro/Kconfig" source "drivers/staging/iio/imu/Kconfig" source "drivers/staging/iio/light/Kconfig" diff --git a/drivers/staging/iio/Makefile b/drivers/staging/iio/Makefile index 15eba01805bf..766a5d1a8373 100644 --- a/drivers/staging/iio/Makefile +++ b/drivers/staging/iio/Makefile @@ -13,6 +13,7 @@ obj-y += accel/ obj-y += adc/ obj-y += addac/ obj-y += dac/ +obj-y += dds/ obj-y += gyro/ obj-y += imu/ obj-y += light/ diff --git a/drivers/staging/iio/dds/Kconfig b/drivers/staging/iio/dds/Kconfig new file mode 100644 index 000000000000..d32bebc63fb9 --- /dev/null +++ b/drivers/staging/iio/dds/Kconfig @@ -0,0 +1,11 @@ +# +# Direct Digital Synthesis drivers +# +comment "Direct Digital Synthesis" + +config AD5930 + tristate "Analog Devices ad5930/5932 driver" + depends on SPI + help + Say yes here to build support for Analog Devices DDS chip + ad5930/ad5932, provides direct access via sysfs. diff --git a/drivers/staging/iio/dds/Makefile b/drivers/staging/iio/dds/Makefile new file mode 100644 index 000000000000..110f28916c73 --- /dev/null +++ b/drivers/staging/iio/dds/Makefile @@ -0,0 +1,5 @@ +# +# Makefile for Direct Digital Synthesis drivers +# + +obj-$(CONFIG_AD5930) += ad5930.o diff --git a/drivers/staging/iio/dds/ad5930.c b/drivers/staging/iio/dds/ad5930.c new file mode 100644 index 000000000000..f80039c5d539 --- /dev/null +++ b/drivers/staging/iio/dds/ad5930.c @@ -0,0 +1,170 @@ +/* + * Driver for ADI Direct Digital Synthesis ad5930 + * + * Copyright (c) 2010-2010 Analog Devices Inc. + * + * 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 +#include +#include + +#include "../iio.h" +#include "../sysfs.h" + +#define DRV_NAME "ad5930" + +#define value_mask (u16)0xf000 +#define addr_shift 12 + +/* Register format: 4 bits addr + 12 bits value */ +struct ad5903_config { + u16 control; + u16 incnum; + u16 frqdelt[2]; + u16 incitvl; + u16 buritvl; + u16 strtfrq[2]; +}; + +struct ad5930_state { + struct mutex lock; + struct iio_dev *idev; + struct spi_device *sdev; +}; + +static ssize_t ad5930_set_parameter(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct spi_message msg; + struct spi_transfer xfer; + int ret; + struct ad5903_config *config = (struct ad5903_config *)buf; + struct iio_dev *idev = dev_get_drvdata(dev); + struct ad5930_state *st = idev->dev_data; + + config->control = (config->control & ~value_mask); + config->incnum = (config->control & ~value_mask) | (1 << addr_shift); + config->frqdelt[0] = (config->control & ~value_mask) | (2 << addr_shift); + config->frqdelt[1] = (config->control & ~value_mask) | 3 << addr_shift; + config->incitvl = (config->control & ~value_mask) | 4 << addr_shift; + config->buritvl = (config->control & ~value_mask) | 8 << addr_shift; + config->strtfrq[0] = (config->control & ~value_mask) | 0xc << addr_shift; + config->strtfrq[1] = (config->control & ~value_mask) | 0xd << addr_shift; + + xfer.len = len; + xfer.tx_buf = config; + mutex_lock(&st->lock); + + spi_message_init(&msg); + spi_message_add_tail(&xfer, &msg); + ret = spi_sync(st->sdev, &msg); + if (ret) + goto error_ret; +error_ret: + mutex_unlock(&st->lock); + + return ret ? ret : len; +} + +static IIO_DEVICE_ATTR(dds, S_IWUSR, NULL, ad5930_set_parameter, 0); + +static struct attribute *ad5930_attributes[] = { + &iio_dev_attr_dds.dev_attr.attr, + NULL, +}; + +static const struct attribute_group ad5930_attribute_group = { + .name = DRV_NAME, + .attrs = ad5930_attributes, +}; + +static int __devinit ad5930_probe(struct spi_device *spi) +{ + struct ad5930_state *st; + int ret = 0; + + st = kzalloc(sizeof(*st), GFP_KERNEL); + if (st == NULL) { + ret = -ENOMEM; + goto error_ret; + } + spi_set_drvdata(spi, st); + + mutex_init(&st->lock); + st->sdev = spi; + + st->idev = iio_allocate_device(); + if (st->idev == NULL) { + ret = -ENOMEM; + goto error_free_st; + } + st->idev->dev.parent = &spi->dev; + st->idev->num_interrupt_lines = 0; + st->idev->event_attrs = NULL; + + st->idev->attrs = &ad5930_attribute_group; + st->idev->dev_data = (void *)(st); + st->idev->driver_module = THIS_MODULE; + st->idev->modes = INDIO_DIRECT_MODE; + + ret = iio_device_register(st->idev); + if (ret) + goto error_free_dev; + spi->max_speed_hz = 2000000; + spi->mode = SPI_MODE_3; + spi->bits_per_word = 16; + spi_setup(spi); + + return 0; + +error_free_dev: + iio_free_device(st->idev); +error_free_st: + kfree(st); +error_ret: + return ret; +} + +static int __devexit ad5930_remove(struct spi_device *spi) +{ + struct ad5930_state *st = spi_get_drvdata(spi); + + iio_device_unregister(st->idev); + kfree(st); + + return 0; +} + +static struct spi_driver ad5930_driver = { + .driver = { + .name = DRV_NAME, + .owner = THIS_MODULE, + }, + .probe = ad5930_probe, + .remove = __devexit_p(ad5930_remove), +}; + +static __init int ad5930_spi_init(void) +{ + return spi_register_driver(&ad5930_driver); +} +module_init(ad5930_spi_init); + +static __exit void ad5930_spi_exit(void) +{ + spi_unregister_driver(&ad5930_driver); +} +module_exit(ad5930_spi_exit); + +MODULE_AUTHOR("Cliff Cai"); +MODULE_DESCRIPTION("Analog Devices ad5930 driver"); +MODULE_LICENSE("GPL v2"); -- cgit v1.2.3 From 4a8e6c33e88b09a3fdef022d1711dc13ce8cb7db Mon Sep 17 00:00:00 2001 From: Cliff Cai Date: Wed, 27 Oct 2010 21:44:09 -0400 Subject: staging: iio: dds: new driver for AD9832/3/4/5 devices Signed-off-by: Cliff Cai Signed-off-by: Michael Hennerich Acked-by: Jonathan Cameron Signed-off-by: Mike Frysinger Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/dds/Kconfig | 7 ++ drivers/staging/iio/dds/Makefile | 1 + drivers/staging/iio/dds/ad9832.c | 266 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 274 insertions(+) create mode 100644 drivers/staging/iio/dds/ad9832.c diff --git a/drivers/staging/iio/dds/Kconfig b/drivers/staging/iio/dds/Kconfig index d32bebc63fb9..c9fae1d0a81a 100644 --- a/drivers/staging/iio/dds/Kconfig +++ b/drivers/staging/iio/dds/Kconfig @@ -9,3 +9,10 @@ config AD5930 help Say yes here to build support for Analog Devices DDS chip ad5930/ad5932, provides direct access via sysfs. + +config AD9832 + tristate "Analog Devices ad9832/3/4/5 driver" + depends on SPI + help + Say yes here to build support for Analog Devices DDS chip + ad9832/3/4/5, provides direct access via sysfs. diff --git a/drivers/staging/iio/dds/Makefile b/drivers/staging/iio/dds/Makefile index 110f28916c73..d0f17f064dc5 100644 --- a/drivers/staging/iio/dds/Makefile +++ b/drivers/staging/iio/dds/Makefile @@ -3,3 +3,4 @@ # obj-$(CONFIG_AD5930) += ad5930.o +obj-$(CONFIG_AD9832) += ad9832.o diff --git a/drivers/staging/iio/dds/ad9832.c b/drivers/staging/iio/dds/ad9832.c new file mode 100644 index 000000000000..a4bb0482ed5b --- /dev/null +++ b/drivers/staging/iio/dds/ad9832.c @@ -0,0 +1,266 @@ +/* + * Driver for ADI Direct Digital Synthesis ad9832 + * + * Copyright (c) 2010 Analog Devices Inc. + * + * 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 +#include +#include + +#include "../iio.h" +#include "../sysfs.h" + +#define DRV_NAME "ad9832" + +#define value_mask (u16)0xf000 +#define cmd_shift 12 +#define add_shift 8 +#define AD9832_SYNC (1 << 13) +#define AD9832_SELSRC (1 << 12) +#define AD9832_SLEEP (1 << 13) +#define AD9832_RESET (1 << 12) +#define AD9832_CLR (1 << 11) + +#define ADD_FREQ0LL 0x0 +#define ADD_FREQ0HL 0x1 +#define ADD_FREQ0LM 0x2 +#define ADD_FREQ0HM 0x3 +#define ADD_FREQ1LL 0x4 +#define ADD_FREQ1HL 0x5 +#define ADD_FREQ1LM 0x6 +#define ADD_FREQ1HM 0x7 +#define ADD_PHASE0L 0x8 +#define ADD_PHASE0H 0x9 +#define ADD_PHASE1L 0xa +#define ADD_PHASE1H 0xb +#define ADD_PHASE2L 0xc +#define ADD_PHASE2H 0xd +#define ADD_PHASE3L 0xe +#define ADD_PHASE3H 0xf + +#define CMD_PHA8BITSW 0x1 +#define CMD_PHA16BITSW 0x0 +#define CMD_FRE8BITSW 0x3 +#define CMD_FRE16BITSW 0x2 +#define CMD_SELBITSCTL 0x6 + +struct ad9832_setting { + u16 freq0[4]; + u16 freq1[4]; + u16 phase0[2]; + u16 phase1[2]; + u16 phase2[2]; + u16 phase3[2]; +}; + +struct ad9832_state { + struct mutex lock; + struct iio_dev *idev; + struct spi_device *sdev; +}; + +static ssize_t ad9832_set_parameter(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct spi_message msg; + struct spi_transfer xfer; + int ret; + struct ad9832_setting config; + struct iio_dev *idev = dev_get_drvdata(dev); + struct ad9832_state *st = idev->dev_data; + + config.freq0[0] = (CMD_FRE8BITSW << add_shift | ADD_FREQ0LL << add_shift | buf[0]); + config.freq0[1] = (CMD_FRE16BITSW << add_shift | ADD_FREQ0HL << add_shift | buf[1]); + config.freq0[2] = (CMD_FRE8BITSW << add_shift | ADD_FREQ0LM << add_shift | buf[2]); + config.freq0[3] = (CMD_FRE16BITSW << add_shift | ADD_FREQ0HM << add_shift | buf[3]); + config.freq1[0] = (CMD_FRE8BITSW << add_shift | ADD_FREQ1LL << add_shift | buf[4]); + config.freq1[1] = (CMD_FRE16BITSW << add_shift | ADD_FREQ1HL << add_shift | buf[5]); + config.freq1[2] = (CMD_FRE8BITSW << add_shift | ADD_FREQ1LM << add_shift | buf[6]); + config.freq1[3] = (CMD_FRE16BITSW << add_shift | ADD_FREQ1HM << add_shift | buf[7]); + + config.phase0[0] = (CMD_PHA8BITSW << add_shift | ADD_PHASE0L << add_shift | buf[9]); + config.phase0[1] = (CMD_PHA16BITSW << add_shift | ADD_PHASE0H << add_shift | buf[10]); + config.phase1[0] = (CMD_PHA8BITSW << add_shift | ADD_PHASE1L << add_shift | buf[11]); + config.phase1[1] = (CMD_PHA16BITSW << add_shift | ADD_PHASE1H << add_shift | buf[12]); + config.phase2[0] = (CMD_PHA8BITSW << add_shift | ADD_PHASE2L << add_shift | buf[13]); + config.phase2[1] = (CMD_PHA16BITSW << add_shift | ADD_PHASE2H << add_shift | buf[14]); + config.phase3[0] = (CMD_PHA8BITSW << add_shift | ADD_PHASE3L << add_shift | buf[15]); + config.phase3[1] = (CMD_PHA16BITSW << add_shift | ADD_PHASE3H << add_shift | buf[16]); + + xfer.len = 2 * len; + xfer.tx_buf = &config; + mutex_lock(&st->lock); + + spi_message_init(&msg); + spi_message_add_tail(&xfer, &msg); + ret = spi_sync(st->sdev, &msg); + if (ret) + goto error_ret; +error_ret: + mutex_unlock(&st->lock); + + return ret ? ret : len; +} + +static IIO_DEVICE_ATTR(dds, S_IWUSR, NULL, ad9832_set_parameter, 0); + +static struct attribute *ad9832_attributes[] = { + &iio_dev_attr_dds.dev_attr.attr, + NULL, +}; + +static const struct attribute_group ad9832_attribute_group = { + .name = DRV_NAME, + .attrs = ad9832_attributes, +}; + +static void ad9832_init(struct ad9832_state *st) +{ + struct spi_message msg; + struct spi_transfer xfer; + int ret; + u16 config = 0; + + config = 0x3 << 14 | AD9832_SLEEP | AD9832_RESET | AD9832_CLR; + + mutex_lock(&st->lock); + + xfer.len = 2; + xfer.tx_buf = &config; + + spi_message_init(&msg); + spi_message_add_tail(&xfer, &msg); + ret = spi_sync(st->sdev, &msg); + if (ret) + goto error_ret; + + config = 0x2 << 14 | AD9832_SYNC | AD9832_SELSRC; + xfer.len = 2; + xfer.tx_buf = &config; + + spi_message_init(&msg); + spi_message_add_tail(&xfer, &msg); + ret = spi_sync(st->sdev, &msg); + if (ret) + goto error_ret; + + config = CMD_SELBITSCTL << cmd_shift; + xfer.len = 2; + xfer.tx_buf = &config; + + spi_message_init(&msg); + spi_message_add_tail(&xfer, &msg); + ret = spi_sync(st->sdev, &msg); + if (ret) + goto error_ret; + + config = 0x3 << 14; + + mutex_lock(&st->lock); + + xfer.len = 2; + xfer.tx_buf = &config; + + spi_message_init(&msg); + spi_message_add_tail(&xfer, &msg); + ret = spi_sync(st->sdev, &msg); + if (ret) + goto error_ret; +error_ret: + mutex_unlock(&st->lock); + + + +} + +static int __devinit ad9832_probe(struct spi_device *spi) +{ + struct ad9832_state *st; + int ret = 0; + + st = kzalloc(sizeof(*st), GFP_KERNEL); + if (st == NULL) { + ret = -ENOMEM; + goto error_ret; + } + spi_set_drvdata(spi, st); + + mutex_init(&st->lock); + st->sdev = spi; + + st->idev = iio_allocate_device(); + if (st->idev == NULL) { + ret = -ENOMEM; + goto error_free_st; + } + st->idev->dev.parent = &spi->dev; + st->idev->num_interrupt_lines = 0; + st->idev->event_attrs = NULL; + + st->idev->attrs = &ad9832_attribute_group; + st->idev->dev_data = (void *)(st); + st->idev->driver_module = THIS_MODULE; + st->idev->modes = INDIO_DIRECT_MODE; + + ret = iio_device_register(st->idev); + if (ret) + goto error_free_dev; + spi->max_speed_hz = 2000000; + spi->mode = SPI_MODE_3; + spi->bits_per_word = 16; + spi_setup(spi); + ad9832_init(st); + return 0; + +error_free_dev: + iio_free_device(st->idev); +error_free_st: + kfree(st); +error_ret: + return ret; +} + +static int __devexit ad9832_remove(struct spi_device *spi) +{ + struct ad9832_state *st = spi_get_drvdata(spi); + + iio_device_unregister(st->idev); + kfree(st); + + return 0; +} + +static struct spi_driver ad9832_driver = { + .driver = { + .name = DRV_NAME, + .owner = THIS_MODULE, + }, + .probe = ad9832_probe, + .remove = __devexit_p(ad9832_remove), +}; + +static __init int ad9832_spi_init(void) +{ + return spi_register_driver(&ad9832_driver); +} +module_init(ad9832_spi_init); + +static __exit void ad9832_spi_exit(void) +{ + spi_unregister_driver(&ad9832_driver); +} +module_exit(ad9832_spi_exit); + +MODULE_AUTHOR("Cliff Cai"); +MODULE_DESCRIPTION("Analog Devices ad9832 driver"); +MODULE_LICENSE("GPL v2"); -- cgit v1.2.3 From a82ab27aa758e4b02f130d86be5c2fedf29c0c0a Mon Sep 17 00:00:00 2001 From: Cliff Cai Date: Wed, 27 Oct 2010 21:44:10 -0400 Subject: staging: iio: dds: new driver for AD9850/1 devices Signed-off-by: Cliff Cai Signed-off-by: Michael Hennerich Acked-by: Jonathan Cameron Signed-off-by: Mike Frysinger Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/dds/Kconfig | 7 ++ drivers/staging/iio/dds/Makefile | 1 + drivers/staging/iio/dds/ad9850.c | 156 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 164 insertions(+) create mode 100644 drivers/staging/iio/dds/ad9850.c diff --git a/drivers/staging/iio/dds/Kconfig b/drivers/staging/iio/dds/Kconfig index c9fae1d0a81a..d42bc4cb228d 100644 --- a/drivers/staging/iio/dds/Kconfig +++ b/drivers/staging/iio/dds/Kconfig @@ -16,3 +16,10 @@ config AD9832 help Say yes here to build support for Analog Devices DDS chip ad9832/3/4/5, provides direct access via sysfs. + +config AD9850 + tristate "Analog Devices ad9850/1 driver" + depends on SPI + help + Say yes here to build support for Analog Devices DDS chip + ad9850/1, provides direct access via sysfs. diff --git a/drivers/staging/iio/dds/Makefile b/drivers/staging/iio/dds/Makefile index d0f17f064dc5..791db7411cb0 100644 --- a/drivers/staging/iio/dds/Makefile +++ b/drivers/staging/iio/dds/Makefile @@ -4,3 +4,4 @@ obj-$(CONFIG_AD5930) += ad5930.o obj-$(CONFIG_AD9832) += ad9832.o +obj-$(CONFIG_AD9850) += ad9850.o diff --git a/drivers/staging/iio/dds/ad9850.c b/drivers/staging/iio/dds/ad9850.c new file mode 100644 index 000000000000..b259bfeaf5aa --- /dev/null +++ b/drivers/staging/iio/dds/ad9850.c @@ -0,0 +1,156 @@ +/* + * Driver for ADI Direct Digital Synthesis ad9850 + * + * Copyright (c) 2010-2010 Analog Devices Inc. + * + * 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 +#include +#include + +#include "../iio.h" +#include "../sysfs.h" + +#define DRV_NAME "ad9850" + +#define value_mask (u16)0xf000 +#define addr_shift 12 + +/* Register format: 4 bits addr + 12 bits value */ +struct ad9850_config { + u8 control[5]; +}; + +struct ad9850_state { + struct mutex lock; + struct iio_dev *idev; + struct spi_device *sdev; +}; + +static ssize_t ad9850_set_parameter(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct spi_message msg; + struct spi_transfer xfer; + int ret; + struct ad9850_config *config = (struct ad9850_config *)buf; + struct iio_dev *idev = dev_get_drvdata(dev); + struct ad9850_state *st = idev->dev_data; + + xfer.len = len; + xfer.tx_buf = config; + mutex_lock(&st->lock); + + spi_message_init(&msg); + spi_message_add_tail(&xfer, &msg); + ret = spi_sync(st->sdev, &msg); + if (ret) + goto error_ret; +error_ret: + mutex_unlock(&st->lock); + + return ret ? ret : len; +} + +static IIO_DEVICE_ATTR(dds, S_IWUSR, NULL, ad9850_set_parameter, 0); + +static struct attribute *ad9850_attributes[] = { + &iio_dev_attr_dds.dev_attr.attr, + NULL, +}; + +static const struct attribute_group ad9850_attribute_group = { + .name = DRV_NAME, + .attrs = ad9850_attributes, +}; + +static int __devinit ad9850_probe(struct spi_device *spi) +{ + struct ad9850_state *st; + int ret = 0; + + st = kzalloc(sizeof(*st), GFP_KERNEL); + if (st == NULL) { + ret = -ENOMEM; + goto error_ret; + } + spi_set_drvdata(spi, st); + + mutex_init(&st->lock); + st->sdev = spi; + + st->idev = iio_allocate_device(); + if (st->idev == NULL) { + ret = -ENOMEM; + goto error_free_st; + } + st->idev->dev.parent = &spi->dev; + st->idev->num_interrupt_lines = 0; + st->idev->event_attrs = NULL; + + st->idev->attrs = &ad9850_attribute_group; + st->idev->dev_data = (void *)(st); + st->idev->driver_module = THIS_MODULE; + st->idev->modes = INDIO_DIRECT_MODE; + + ret = iio_device_register(st->idev); + if (ret) + goto error_free_dev; + spi->max_speed_hz = 2000000; + spi->mode = SPI_MODE_3; + spi->bits_per_word = 16; + spi_setup(spi); + + return 0; + +error_free_dev: + iio_free_device(st->idev); +error_free_st: + kfree(st); +error_ret: + return ret; +} + +static int __devexit ad9850_remove(struct spi_device *spi) +{ + struct ad9850_state *st = spi_get_drvdata(spi); + + iio_device_unregister(st->idev); + kfree(st); + + return 0; +} + +static struct spi_driver ad9850_driver = { + .driver = { + .name = DRV_NAME, + .owner = THIS_MODULE, + }, + .probe = ad9850_probe, + .remove = __devexit_p(ad9850_remove), +}; + +static __init int ad9850_spi_init(void) +{ + return spi_register_driver(&ad9850_driver); +} +module_init(ad9850_spi_init); + +static __exit void ad9850_spi_exit(void) +{ + spi_unregister_driver(&ad9850_driver); +} +module_exit(ad9850_spi_exit); + +MODULE_AUTHOR("Cliff Cai"); +MODULE_DESCRIPTION("Analog Devices ad9850 driver"); +MODULE_LICENSE("GPL v2"); -- cgit v1.2.3 From a886689f6c36ccad01d9600a92029f80a2a6279f Mon Sep 17 00:00:00 2001 From: Cliff Cai Date: Wed, 27 Oct 2010 21:44:11 -0400 Subject: staging: iio: dds: new driver for AD9852/4 devices Signed-off-by: Cliff Cai Signed-off-by: Michael Hennerich Acked-by: Jonathan Cameron Signed-off-by: Mike Frysinger Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/dds/Kconfig | 7 + drivers/staging/iio/dds/Makefile | 1 + drivers/staging/iio/dds/ad9852.c | 314 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 322 insertions(+) create mode 100644 drivers/staging/iio/dds/ad9852.c diff --git a/drivers/staging/iio/dds/Kconfig b/drivers/staging/iio/dds/Kconfig index d42bc4cb228d..dee31eb3d73c 100644 --- a/drivers/staging/iio/dds/Kconfig +++ b/drivers/staging/iio/dds/Kconfig @@ -23,3 +23,10 @@ config AD9850 help Say yes here to build support for Analog Devices DDS chip ad9850/1, provides direct access via sysfs. + +config AD9852 + tristate "Analog Devices ad9852/4 driver" + depends on SPI + help + Say yes here to build support for Analog Devices DDS chip + ad9852/4, provides direct access via sysfs. diff --git a/drivers/staging/iio/dds/Makefile b/drivers/staging/iio/dds/Makefile index 791db7411cb0..e344e8dced95 100644 --- a/drivers/staging/iio/dds/Makefile +++ b/drivers/staging/iio/dds/Makefile @@ -5,3 +5,4 @@ obj-$(CONFIG_AD5930) += ad5930.o obj-$(CONFIG_AD9832) += ad9832.o obj-$(CONFIG_AD9850) += ad9850.o +obj-$(CONFIG_AD9852) += ad9852.o diff --git a/drivers/staging/iio/dds/ad9852.c b/drivers/staging/iio/dds/ad9852.c new file mode 100644 index 000000000000..0a41d25583af --- /dev/null +++ b/drivers/staging/iio/dds/ad9852.c @@ -0,0 +1,314 @@ +/* + * Driver for ADI Direct Digital Synthesis ad9852 + * + * Copyright (c) 2010 Analog Devices Inc. + * + * 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 +#include +#include + +#include "../iio.h" +#include "../sysfs.h" + +#define DRV_NAME "ad9852" + +#define addr_phaad1 0x0 +#define addr_phaad2 0x1 +#define addr_fretu1 0x2 +#define addr_fretu2 0x3 +#define addr_delfre 0x4 +#define addr_updclk 0x5 +#define addr_ramclk 0x6 +#define addr_contrl 0x7 +#define addr_optskm 0x8 +#define addr_optskr 0xa +#define addr_dacctl 0xb + +#define COMPPD (1 << 4) +#define REFMULT2 (1 << 2) +#define BYPPLL (1 << 5) +#define PLLRANG (1 << 6) +#define IEUPCLK (1) +#define OSKEN (1 << 5) + +#define read_bit (1 << 7) + +/* Register format: 1 byte addr + value */ +struct ad9852_config { + u8 phajst0[3]; + u8 phajst1[3]; + u8 fretun1[6]; + u8 fretun2[6]; + u8 dltafre[6]; + u8 updtclk[5]; + u8 ramprat[4]; + u8 control[5]; + u8 outpskm[3]; + u8 outpskr[2]; + u8 daccntl[3]; +}; + +struct ad9852_state { + struct mutex lock; + struct iio_dev *idev; + struct spi_device *sdev; +}; + +static ssize_t ad9852_set_parameter(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct spi_message msg; + struct spi_transfer xfer; + int ret; + struct ad9852_config *config = (struct ad9852_config *)buf; + struct iio_dev *idev = dev_get_drvdata(dev); + struct ad9852_state *st = idev->dev_data; + + xfer.len = 3; + xfer.tx_buf = &config->phajst0[0]; + mutex_lock(&st->lock); + + spi_message_init(&msg); + spi_message_add_tail(&xfer, &msg); + ret = spi_sync(st->sdev, &msg); + if (ret) + goto error_ret; + + xfer.len = 3; + xfer.tx_buf = &config->phajst1[0]; + mutex_lock(&st->lock); + + spi_message_init(&msg); + spi_message_add_tail(&xfer, &msg); + ret = spi_sync(st->sdev, &msg); + if (ret) + goto error_ret; + + xfer.len = 6; + xfer.tx_buf = &config->fretun1[0]; + mutex_lock(&st->lock); + + spi_message_init(&msg); + spi_message_add_tail(&xfer, &msg); + ret = spi_sync(st->sdev, &msg); + if (ret) + goto error_ret; + + xfer.len = 6; + xfer.tx_buf = &config->fretun2[0]; + mutex_lock(&st->lock); + + spi_message_init(&msg); + spi_message_add_tail(&xfer, &msg); + ret = spi_sync(st->sdev, &msg); + if (ret) + goto error_ret; + + xfer.len = 6; + xfer.tx_buf = &config->dltafre[0]; + mutex_lock(&st->lock); + + spi_message_init(&msg); + spi_message_add_tail(&xfer, &msg); + ret = spi_sync(st->sdev, &msg); + if (ret) + goto error_ret; + + xfer.len = 5; + xfer.tx_buf = &config->updtclk[0]; + mutex_lock(&st->lock); + + spi_message_init(&msg); + spi_message_add_tail(&xfer, &msg); + ret = spi_sync(st->sdev, &msg); + if (ret) + goto error_ret; + + xfer.len = 4; + xfer.tx_buf = &config->ramprat[0]; + mutex_lock(&st->lock); + + spi_message_init(&msg); + spi_message_add_tail(&xfer, &msg); + ret = spi_sync(st->sdev, &msg); + if (ret) + goto error_ret; + + xfer.len = 5; + xfer.tx_buf = &config->control[0]; + mutex_lock(&st->lock); + + spi_message_init(&msg); + spi_message_add_tail(&xfer, &msg); + ret = spi_sync(st->sdev, &msg); + if (ret) + goto error_ret; + + xfer.len = 3; + xfer.tx_buf = &config->outpskm[0]; + mutex_lock(&st->lock); + + spi_message_init(&msg); + spi_message_add_tail(&xfer, &msg); + ret = spi_sync(st->sdev, &msg); + if (ret) + goto error_ret; + + xfer.len = 2; + xfer.tx_buf = &config->outpskr[0]; + mutex_lock(&st->lock); + + spi_message_init(&msg); + spi_message_add_tail(&xfer, &msg); + ret = spi_sync(st->sdev, &msg); + if (ret) + goto error_ret; + xfer.len = 3; + xfer.tx_buf = &config->daccntl[0]; + mutex_lock(&st->lock); + + spi_message_init(&msg); + spi_message_add_tail(&xfer, &msg); + ret = spi_sync(st->sdev, &msg); + if (ret) + goto error_ret; +error_ret: + mutex_unlock(&st->lock); + + return ret ? ret : len; +} + +static IIO_DEVICE_ATTR(dds, S_IWUSR, NULL, ad9852_set_parameter, 0); + +static void ad9852_init(struct ad9852_state *st) +{ + struct spi_message msg; + struct spi_transfer xfer; + int ret; + u8 config[5]; + + config[0] = addr_contrl; + config[1] = COMPPD; + config[2] = REFMULT2 | BYPPLL | PLLRANG; + config[3] = IEUPCLK; + config[4] = OSKEN; + + mutex_lock(&st->lock); + + xfer.len = 5; + xfer.tx_buf = &config; + + spi_message_init(&msg); + spi_message_add_tail(&xfer, &msg); + ret = spi_sync(st->sdev, &msg); + if (ret) + goto error_ret; + +error_ret: + mutex_unlock(&st->lock); + + + +} + +static struct attribute *ad9852_attributes[] = { + &iio_dev_attr_dds.dev_attr.attr, + NULL, +}; + +static const struct attribute_group ad9852_attribute_group = { + .name = DRV_NAME, + .attrs = ad9852_attributes, +}; + +static int __devinit ad9852_probe(struct spi_device *spi) +{ + struct ad9852_state *st; + int ret = 0; + + st = kzalloc(sizeof(*st), GFP_KERNEL); + if (st == NULL) { + ret = -ENOMEM; + goto error_ret; + } + spi_set_drvdata(spi, st); + + mutex_init(&st->lock); + st->sdev = spi; + + st->idev = iio_allocate_device(); + if (st->idev == NULL) { + ret = -ENOMEM; + goto error_free_st; + } + st->idev->dev.parent = &spi->dev; + st->idev->num_interrupt_lines = 0; + st->idev->event_attrs = NULL; + + st->idev->attrs = &ad9852_attribute_group; + st->idev->dev_data = (void *)(st); + st->idev->driver_module = THIS_MODULE; + st->idev->modes = INDIO_DIRECT_MODE; + + ret = iio_device_register(st->idev); + if (ret) + goto error_free_dev; + spi->max_speed_hz = 2000000; + spi->mode = SPI_MODE_3; + spi->bits_per_word = 8; + spi_setup(spi); + ad9852_init(st); + return 0; + +error_free_dev: + iio_free_device(st->idev); +error_free_st: + kfree(st); +error_ret: + return ret; +} + +static int __devexit ad9852_remove(struct spi_device *spi) +{ + struct ad9852_state *st = spi_get_drvdata(spi); + + iio_device_unregister(st->idev); + kfree(st); + + return 0; +} + +static struct spi_driver ad9852_driver = { + .driver = { + .name = DRV_NAME, + .owner = THIS_MODULE, + }, + .probe = ad9852_probe, + .remove = __devexit_p(ad9852_remove), +}; + +static __init int ad9852_spi_init(void) +{ + return spi_register_driver(&ad9852_driver); +} +module_init(ad9852_spi_init); + +static __exit void ad9852_spi_exit(void) +{ + spi_unregister_driver(&ad9852_driver); +} +module_exit(ad9852_spi_exit); + +MODULE_AUTHOR("Cliff Cai"); +MODULE_DESCRIPTION("Analog Devices ad9852 driver"); +MODULE_LICENSE("GPL v2"); -- cgit v1.2.3 From 2996a2dc38c58f96432a28fdd7f81ccfd692637d Mon Sep 17 00:00:00 2001 From: Cliff Cai Date: Wed, 27 Oct 2010 21:44:12 -0400 Subject: staging: iio: dds: new driver for AD9910 devices Signed-off-by: Cliff Cai Signed-off-by: Michael Hennerich Acked-by: Jonathan Cameron Signed-off-by: Mike Frysinger Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/dds/Kconfig | 7 + drivers/staging/iio/dds/Makefile | 1 + drivers/staging/iio/dds/ad9910.c | 454 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 462 insertions(+) create mode 100644 drivers/staging/iio/dds/ad9910.c diff --git a/drivers/staging/iio/dds/Kconfig b/drivers/staging/iio/dds/Kconfig index dee31eb3d73c..518d0c118083 100644 --- a/drivers/staging/iio/dds/Kconfig +++ b/drivers/staging/iio/dds/Kconfig @@ -30,3 +30,10 @@ config AD9852 help Say yes here to build support for Analog Devices DDS chip ad9852/4, provides direct access via sysfs. + +config AD9910 + tristate "Analog Devices ad9910 driver" + depends on SPI + help + Say yes here to build support for Analog Devices DDS chip + ad9910, provides direct access via sysfs. diff --git a/drivers/staging/iio/dds/Makefile b/drivers/staging/iio/dds/Makefile index e344e8dced95..d249b8125be3 100644 --- a/drivers/staging/iio/dds/Makefile +++ b/drivers/staging/iio/dds/Makefile @@ -6,3 +6,4 @@ obj-$(CONFIG_AD5930) += ad5930.o obj-$(CONFIG_AD9832) += ad9832.o obj-$(CONFIG_AD9850) += ad9850.o obj-$(CONFIG_AD9852) += ad9852.o +obj-$(CONFIG_AD9910) += ad9910.o diff --git a/drivers/staging/iio/dds/ad9910.c b/drivers/staging/iio/dds/ad9910.c new file mode 100644 index 000000000000..c59b40794768 --- /dev/null +++ b/drivers/staging/iio/dds/ad9910.c @@ -0,0 +1,454 @@ +/* + * Driver for ADI Direct Digital Synthesis ad9910 + * + * Copyright (c) 2010 Analog Devices Inc. + * + * 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 +#include +#include + +#include "../iio.h" +#include "../sysfs.h" + +#define DRV_NAME "ad9910" + +#define CFR1 0x0 +#define CFR2 0x1 +#define CFR3 0x2 + +#define AUXDAC 0x3 +#define IOUPD 0x4 +#define FTW 0x7 +#define POW 0x8 +#define ASF 0x9 +#define MULTC 0x0A +#define DIG_RAMPL 0x0B +#define DIG_RAMPS 0x0C +#define DIG_RAMPR 0x0D +#define SIN_TONEP0 0x0E +#define SIN_TONEP1 0x0F +#define SIN_TONEP2 0x10 +#define SIN_TONEP3 0x11 +#define SIN_TONEP4 0x12 +#define SIN_TONEP5 0x13 +#define SIN_TONEP6 0x14 +#define SIN_TONEP7 0x15 + +#define RAM_ENABLE (1 << 7) + +#define MANUAL_OSK (1 << 7) +#define INVSIC (1 << 6) +#define DDS_SINEOP (1) + +#define AUTO_OSK (1) +#define OSKEN (1 << 1) +#define LOAD_ARR (1 << 2) +#define CLR_PHA (1 << 3) +#define CLR_DIG (1 << 4) +#define ACLR_PHA (1 << 5) +#define ACLR_DIG (1 << 6) +#define LOAD_LRR (1 << 7) + +#define LSB_FST (1) +#define SDIO_IPT (1 << 1) +#define EXT_PWD (1 << 3) +#define ADAC_PWD (1 << 4) +#define REFCLK_PWD (1 << 5) +#define DAC_PWD (1 << 6) +#define DIG_PWD (1 << 7) + +#define ENA_AMP (1) +#define READ_FTW (1) +#define DIGR_LOW (1 << 1) +#define DIGR_HIGH (1 << 2) +#define DIGR_ENA (1 << 3) +#define SYNCCLK_ENA (1 << 6) +#define ITER_IOUPD (1 << 7) + +#define TX_ENA (1 << 1) +#define PDCLK_INV (1 << 2) +#define PDCLK_ENB (1 << 3) + +#define PARA_ENA (1 << 4) +#define SYNC_DIS (1 << 5) +#define DATA_ASS (1 << 6) +#define MATCH_ENA (1 << 7) + +#define PLL_ENA (1) +#define PFD_RST (1 << 2) +#define REFCLK_RST (1 << 6) +#define REFCLK_BYP (1 << 7) + +/* Register format: 1 byte addr + value */ +struct ad9910_config { + u8 auxdac[5]; + u8 ioupd[5]; + u8 ftw[5]; + u8 pow[3]; + u8 asf[5]; + u8 multc[5]; + u8 dig_rampl[9]; + u8 dig_ramps[9]; + u8 dig_rampr[5]; + u8 sin_tonep0[9]; + u8 sin_tonep1[9]; + u8 sin_tonep2[9]; + u8 sin_tonep3[9]; + u8 sin_tonep4[9]; + u8 sin_tonep5[9]; + u8 sin_tonep6[9]; + u8 sin_tonep7[9]; +}; + +struct ad9910_state { + struct mutex lock; + struct iio_dev *idev; + struct spi_device *sdev; +}; + +static ssize_t ad9910_set_parameter(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct spi_message msg; + struct spi_transfer xfer; + int ret; + struct ad9910_config *config = (struct ad9910_config *)buf; + struct iio_dev *idev = dev_get_drvdata(dev); + struct ad9910_state *st = idev->dev_data; + + xfer.len = 5; + xfer.tx_buf = &config->auxdac[0]; + mutex_lock(&st->lock); + + spi_message_init(&msg); + spi_message_add_tail(&xfer, &msg); + ret = spi_sync(st->sdev, &msg); + if (ret) + goto error_ret; + + xfer.len = 5; + xfer.tx_buf = &config->ioupd[0]; + mutex_lock(&st->lock); + + spi_message_init(&msg); + spi_message_add_tail(&xfer, &msg); + ret = spi_sync(st->sdev, &msg); + if (ret) + goto error_ret; + + xfer.len = 5; + xfer.tx_buf = &config->ftw[0]; + mutex_lock(&st->lock); + + spi_message_init(&msg); + spi_message_add_tail(&xfer, &msg); + ret = spi_sync(st->sdev, &msg); + if (ret) + goto error_ret; + + xfer.len = 3; + xfer.tx_buf = &config->pow[0]; + mutex_lock(&st->lock); + + spi_message_init(&msg); + spi_message_add_tail(&xfer, &msg); + ret = spi_sync(st->sdev, &msg); + if (ret) + goto error_ret; + + xfer.len = 5; + xfer.tx_buf = &config->asf[0]; + mutex_lock(&st->lock); + + spi_message_init(&msg); + spi_message_add_tail(&xfer, &msg); + ret = spi_sync(st->sdev, &msg); + if (ret) + goto error_ret; + + xfer.len = 5; + xfer.tx_buf = &config->multc[0]; + mutex_lock(&st->lock); + + spi_message_init(&msg); + spi_message_add_tail(&xfer, &msg); + ret = spi_sync(st->sdev, &msg); + if (ret) + goto error_ret; + + xfer.len = 9; + xfer.tx_buf = &config->dig_rampl[0]; + mutex_lock(&st->lock); + + spi_message_init(&msg); + spi_message_add_tail(&xfer, &msg); + ret = spi_sync(st->sdev, &msg); + if (ret) + goto error_ret; + + xfer.len = 9; + xfer.tx_buf = &config->dig_ramps[0]; + mutex_lock(&st->lock); + + spi_message_init(&msg); + spi_message_add_tail(&xfer, &msg); + ret = spi_sync(st->sdev, &msg); + if (ret) + goto error_ret; + + xfer.len = 5; + xfer.tx_buf = &config->dig_rampr[0]; + mutex_lock(&st->lock); + + spi_message_init(&msg); + spi_message_add_tail(&xfer, &msg); + ret = spi_sync(st->sdev, &msg); + if (ret) + goto error_ret; + + xfer.len = 9; + xfer.tx_buf = &config->sin_tonep0[0]; + mutex_lock(&st->lock); + + spi_message_init(&msg); + spi_message_add_tail(&xfer, &msg); + ret = spi_sync(st->sdev, &msg); + if (ret) + goto error_ret; + xfer.len = 9; + xfer.tx_buf = &config->sin_tonep1[0]; + mutex_lock(&st->lock); + + spi_message_init(&msg); + spi_message_add_tail(&xfer, &msg); + ret = spi_sync(st->sdev, &msg); + if (ret) + goto error_ret; + xfer.len = 9; + xfer.tx_buf = &config->sin_tonep2[0]; + mutex_lock(&st->lock); + + spi_message_init(&msg); + spi_message_add_tail(&xfer, &msg); + ret = spi_sync(st->sdev, &msg); + if (ret) + goto error_ret; + xfer.len = 9; + xfer.tx_buf = &config->sin_tonep3[0]; + mutex_lock(&st->lock); + + spi_message_init(&msg); + spi_message_add_tail(&xfer, &msg); + ret = spi_sync(st->sdev, &msg); + if (ret) + goto error_ret; + xfer.len = 9; + xfer.tx_buf = &config->sin_tonep4[0]; + mutex_lock(&st->lock); + + spi_message_init(&msg); + spi_message_add_tail(&xfer, &msg); + ret = spi_sync(st->sdev, &msg); + if (ret) + goto error_ret; + xfer.len = 9; + xfer.tx_buf = &config->sin_tonep5[0]; + mutex_lock(&st->lock); + + spi_message_init(&msg); + spi_message_add_tail(&xfer, &msg); + ret = spi_sync(st->sdev, &msg); + if (ret) + goto error_ret; + xfer.len = 9; + xfer.tx_buf = &config->sin_tonep6[0]; + mutex_lock(&st->lock); + + spi_message_init(&msg); + spi_message_add_tail(&xfer, &msg); + ret = spi_sync(st->sdev, &msg); + if (ret) + goto error_ret; + xfer.len = 9; + xfer.tx_buf = &config->sin_tonep7[0]; + mutex_lock(&st->lock); + + spi_message_init(&msg); + spi_message_add_tail(&xfer, &msg); + ret = spi_sync(st->sdev, &msg); + if (ret) + goto error_ret; +error_ret: + mutex_unlock(&st->lock); + + return ret ? ret : len; +} + +static IIO_DEVICE_ATTR(dds, S_IWUSR, NULL, ad9910_set_parameter, 0); + +static void ad9910_init(struct ad9910_state *st) +{ + struct spi_message msg; + struct spi_transfer xfer; + int ret; + u8 cfr[5]; + + cfr[0] = CFR1; + cfr[1] = 0; + cfr[2] = MANUAL_OSK | INVSIC | DDS_SINEOP; + cfr[3] = AUTO_OSK | OSKEN | ACLR_PHA | ACLR_DIG | LOAD_LRR; + cfr[4] = 0; + + mutex_lock(&st->lock); + + xfer.len = 5; + xfer.tx_buf = 𝔠 + + spi_message_init(&msg); + spi_message_add_tail(&xfer, &msg); + ret = spi_sync(st->sdev, &msg); + if (ret) + goto error_ret; + + cfr[0] = CFR2; + cfr[1] = ENA_AMP; + cfr[2] = READ_FTW | DIGR_ENA | ITER_IOUPD; + cfr[3] = TX_ENA | PDCLK_INV | PDCLK_ENB; + cfr[4] = PARA_ENA; + + mutex_lock(&st->lock); + + xfer.len = 5; + xfer.tx_buf = 𝔠 + + spi_message_init(&msg); + spi_message_add_tail(&xfer, &msg); + ret = spi_sync(st->sdev, &msg); + if (ret) + goto error_ret; + + cfr[0] = CFR3; + cfr[1] = PLL_ENA; + cfr[2] = 0; + cfr[3] = REFCLK_RST | REFCLK_BYP; + cfr[4] = 0; + + mutex_lock(&st->lock); + + xfer.len = 5; + xfer.tx_buf = 𝔠 + + spi_message_init(&msg); + spi_message_add_tail(&xfer, &msg); + ret = spi_sync(st->sdev, &msg); + if (ret) + goto error_ret; + +error_ret: + mutex_unlock(&st->lock); + + + +} + +static struct attribute *ad9910_attributes[] = { + &iio_dev_attr_dds.dev_attr.attr, + NULL, +}; + +static const struct attribute_group ad9910_attribute_group = { + .name = DRV_NAME, + .attrs = ad9910_attributes, +}; + +static int __devinit ad9910_probe(struct spi_device *spi) +{ + struct ad9910_state *st; + int ret = 0; + + st = kzalloc(sizeof(*st), GFP_KERNEL); + if (st == NULL) { + ret = -ENOMEM; + goto error_ret; + } + spi_set_drvdata(spi, st); + + mutex_init(&st->lock); + st->sdev = spi; + + st->idev = iio_allocate_device(); + if (st->idev == NULL) { + ret = -ENOMEM; + goto error_free_st; + } + st->idev->dev.parent = &spi->dev; + st->idev->num_interrupt_lines = 0; + st->idev->event_attrs = NULL; + + st->idev->attrs = &ad9910_attribute_group; + st->idev->dev_data = (void *)(st); + st->idev->driver_module = THIS_MODULE; + st->idev->modes = INDIO_DIRECT_MODE; + + ret = iio_device_register(st->idev); + if (ret) + goto error_free_dev; + spi->max_speed_hz = 2000000; + spi->mode = SPI_MODE_3; + spi->bits_per_word = 8; + spi_setup(spi); + ad9910_init(st); + return 0; + +error_free_dev: + iio_free_device(st->idev); +error_free_st: + kfree(st); +error_ret: + return ret; +} + +static int __devexit ad9910_remove(struct spi_device *spi) +{ + struct ad9910_state *st = spi_get_drvdata(spi); + + iio_device_unregister(st->idev); + kfree(st); + + return 0; +} + +static struct spi_driver ad9910_driver = { + .driver = { + .name = DRV_NAME, + .owner = THIS_MODULE, + }, + .probe = ad9910_probe, + .remove = __devexit_p(ad9910_remove), +}; + +static __init int ad9910_spi_init(void) +{ + return spi_register_driver(&ad9910_driver); +} +module_init(ad9910_spi_init); + +static __exit void ad9910_spi_exit(void) +{ + spi_unregister_driver(&ad9910_driver); +} +module_exit(ad9910_spi_exit); + +MODULE_AUTHOR("Cliff Cai"); +MODULE_DESCRIPTION("Analog Devices ad9910 driver"); +MODULE_LICENSE("GPL v2"); -- cgit v1.2.3 From 0152a0585281a03d734f38effcfe9515874b7d48 Mon Sep 17 00:00:00 2001 From: Cliff Cai Date: Wed, 27 Oct 2010 21:44:13 -0400 Subject: staging: iio: dds: new driver for AD9951 devices Signed-off-by: Cliff Cai Signed-off-by: Michael Hennerich Acked-by: Jonathan Cameron Signed-off-by: Mike Frysinger Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/dds/Kconfig | 7 ++ drivers/staging/iio/dds/Makefile | 1 + drivers/staging/iio/dds/ad9951.c | 254 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 262 insertions(+) create mode 100644 drivers/staging/iio/dds/ad9951.c diff --git a/drivers/staging/iio/dds/Kconfig b/drivers/staging/iio/dds/Kconfig index 518d0c118083..d045ed69ad38 100644 --- a/drivers/staging/iio/dds/Kconfig +++ b/drivers/staging/iio/dds/Kconfig @@ -37,3 +37,10 @@ config AD9910 help Say yes here to build support for Analog Devices DDS chip ad9910, provides direct access via sysfs. + +config AD9951 + tristate "Analog Devices ad9951 driver" + depends on SPI + help + Say yes here to build support for Analog Devices DDS chip + ad9951, provides direct access via sysfs. diff --git a/drivers/staging/iio/dds/Makefile b/drivers/staging/iio/dds/Makefile index d249b8125be3..6f274acb0fcf 100644 --- a/drivers/staging/iio/dds/Makefile +++ b/drivers/staging/iio/dds/Makefile @@ -7,3 +7,4 @@ obj-$(CONFIG_AD9832) += ad9832.o obj-$(CONFIG_AD9850) += ad9850.o obj-$(CONFIG_AD9852) += ad9852.o obj-$(CONFIG_AD9910) += ad9910.o +obj-$(CONFIG_AD9951) += ad9951.o diff --git a/drivers/staging/iio/dds/ad9951.c b/drivers/staging/iio/dds/ad9951.c new file mode 100644 index 000000000000..bc3befff167a --- /dev/null +++ b/drivers/staging/iio/dds/ad9951.c @@ -0,0 +1,254 @@ +/* + * Driver for ADI Direct Digital Synthesis ad9951 + * + * Copyright (c) 2010 Analog Devices Inc. + * + * 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 +#include +#include + +#include "../iio.h" +#include "../sysfs.h" + +#define DRV_NAME "ad9951" + +#define CFR1 0x0 +#define CFR2 0x1 + +#define AUTO_OSK (1) +#define OSKEN (1 << 1) +#define LOAD_ARR (1 << 2) + +#define AUTO_SYNC (1 << 7) + +#define LSB_FST (1) +#define SDIO_IPT (1 << 1) +#define CLR_PHA (1 << 2) +#define SINE_OPT (1 << 4) +#define ACLR_PHA (1 << 5) + +#define VCO_RANGE (1 << 2) + +#define CRS_OPT (1 << 1) +#define HMANU_SYNC (1 << 2) +#define HSPD_SYNC (1 << 3) + +/* Register format: 1 byte addr + value */ +struct ad9951_config { + u8 asf[3]; + u8 arr[2]; + u8 ftw0[5]; + u8 ftw1[3]; +}; + +struct ad9951_state { + struct mutex lock; + struct iio_dev *idev; + struct spi_device *sdev; +}; + +static ssize_t ad9951_set_parameter(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct spi_message msg; + struct spi_transfer xfer; + int ret; + struct ad9951_config *config = (struct ad9951_config *)buf; + struct iio_dev *idev = dev_get_drvdata(dev); + struct ad9951_state *st = idev->dev_data; + + xfer.len = 3; + xfer.tx_buf = &config->asf[0]; + mutex_lock(&st->lock); + + spi_message_init(&msg); + spi_message_add_tail(&xfer, &msg); + ret = spi_sync(st->sdev, &msg); + if (ret) + goto error_ret; + + xfer.len = 2; + xfer.tx_buf = &config->arr[0]; + mutex_lock(&st->lock); + + spi_message_init(&msg); + spi_message_add_tail(&xfer, &msg); + ret = spi_sync(st->sdev, &msg); + if (ret) + goto error_ret; + + xfer.len = 5; + xfer.tx_buf = &config->ftw0[0]; + mutex_lock(&st->lock); + + spi_message_init(&msg); + spi_message_add_tail(&xfer, &msg); + ret = spi_sync(st->sdev, &msg); + if (ret) + goto error_ret; + + xfer.len = 3; + xfer.tx_buf = &config->ftw1[0]; + mutex_lock(&st->lock); + + spi_message_init(&msg); + spi_message_add_tail(&xfer, &msg); + ret = spi_sync(st->sdev, &msg); + if (ret) + goto error_ret; +error_ret: + mutex_unlock(&st->lock); + + return ret ? ret : len; +} + +static IIO_DEVICE_ATTR(dds, S_IWUSR, NULL, ad9951_set_parameter, 0); + +static void ad9951_init(struct ad9951_state *st) +{ + struct spi_message msg; + struct spi_transfer xfer; + int ret; + u8 cfr[5]; + + cfr[0] = CFR1; + cfr[1] = 0; + cfr[2] = LSB_FST | CLR_PHA | SINE_OPT | ACLR_PHA; + cfr[3] = AUTO_OSK | OSKEN | LOAD_ARR; + cfr[4] = 0; + + mutex_lock(&st->lock); + + xfer.len = 5; + xfer.tx_buf = 𝔠 + + spi_message_init(&msg); + spi_message_add_tail(&xfer, &msg); + ret = spi_sync(st->sdev, &msg); + if (ret) + goto error_ret; + + cfr[0] = CFR2; + cfr[1] = VCO_RANGE; + cfr[2] = HSPD_SYNC; + cfr[3] = 0; + + mutex_lock(&st->lock); + + xfer.len = 4; + xfer.tx_buf = 𝔠 + + spi_message_init(&msg); + spi_message_add_tail(&xfer, &msg); + ret = spi_sync(st->sdev, &msg); + if (ret) + goto error_ret; + +error_ret: + mutex_unlock(&st->lock); + + + +} + +static struct attribute *ad9951_attributes[] = { + &iio_dev_attr_dds.dev_attr.attr, + NULL, +}; + +static const struct attribute_group ad9951_attribute_group = { + .name = DRV_NAME, + .attrs = ad9951_attributes, +}; + +static int __devinit ad9951_probe(struct spi_device *spi) +{ + struct ad9951_state *st; + int ret = 0; + + st = kzalloc(sizeof(*st), GFP_KERNEL); + if (st == NULL) { + ret = -ENOMEM; + goto error_ret; + } + spi_set_drvdata(spi, st); + + mutex_init(&st->lock); + st->sdev = spi; + + st->idev = iio_allocate_device(); + if (st->idev == NULL) { + ret = -ENOMEM; + goto error_free_st; + } + st->idev->dev.parent = &spi->dev; + st->idev->num_interrupt_lines = 0; + st->idev->event_attrs = NULL; + + st->idev->attrs = &ad9951_attribute_group; + st->idev->dev_data = (void *)(st); + st->idev->driver_module = THIS_MODULE; + st->idev->modes = INDIO_DIRECT_MODE; + + ret = iio_device_register(st->idev); + if (ret) + goto error_free_dev; + spi->max_speed_hz = 2000000; + spi->mode = SPI_MODE_3; + spi->bits_per_word = 8; + spi_setup(spi); + ad9951_init(st); + return 0; + +error_free_dev: + iio_free_device(st->idev); +error_free_st: + kfree(st); +error_ret: + return ret; +} + +static int __devexit ad9951_remove(struct spi_device *spi) +{ + struct ad9951_state *st = spi_get_drvdata(spi); + + iio_device_unregister(st->idev); + kfree(st); + + return 0; +} + +static struct spi_driver ad9951_driver = { + .driver = { + .name = DRV_NAME, + .owner = THIS_MODULE, + }, + .probe = ad9951_probe, + .remove = __devexit_p(ad9951_remove), +}; + +static __init int ad9951_spi_init(void) +{ + return spi_register_driver(&ad9951_driver); +} +module_init(ad9951_spi_init); + +static __exit void ad9951_spi_exit(void) +{ + spi_unregister_driver(&ad9951_driver); +} +module_exit(ad9951_spi_exit); + +MODULE_AUTHOR("Cliff Cai"); +MODULE_DESCRIPTION("Analog Devices ad9951 driver"); +MODULE_LICENSE("GPL v2"); -- cgit v1.2.3 From 09434ef7c2eedca448d2701ffce229b5ccade64f Mon Sep 17 00:00:00 2001 From: Barry Song Date: Wed, 27 Oct 2010 21:44:14 -0400 Subject: staging: iio: meter: new driver for ADE7753/6 devices This also kicks off the new meter subsection. Signed-off-by: Barry Song Signed-off-by: Michael Hennerich Acked-by: Jonathan Cameron Signed-off-by: Mike Frysinger Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/Kconfig | 2 +- drivers/staging/iio/Makefile | 3 +- drivers/staging/iio/meter/Kconfig | 11 + drivers/staging/iio/meter/Makefile | 5 + drivers/staging/iio/meter/ade7753.c | 730 ++++++++++++++++++++++++++++++++++++ drivers/staging/iio/meter/ade7753.h | 140 +++++++ drivers/staging/iio/meter/meter.h | 396 +++++++++++++++++++ 7 files changed, 1285 insertions(+), 2 deletions(-) create mode 100644 drivers/staging/iio/meter/Kconfig create mode 100644 drivers/staging/iio/meter/Makefile create mode 100644 drivers/staging/iio/meter/ade7753.c create mode 100644 drivers/staging/iio/meter/ade7753.h create mode 100644 drivers/staging/iio/meter/meter.h diff --git a/drivers/staging/iio/Kconfig b/drivers/staging/iio/Kconfig index 5e5bc475f299..ffe8912bd7ab 100644 --- a/drivers/staging/iio/Kconfig +++ b/drivers/staging/iio/Kconfig @@ -49,7 +49,7 @@ source "drivers/staging/iio/gyro/Kconfig" source "drivers/staging/iio/imu/Kconfig" source "drivers/staging/iio/light/Kconfig" source "drivers/staging/iio/magnetometer/Kconfig" - +source "drivers/staging/iio/meter/Kconfig" source "drivers/staging/iio/trigger/Kconfig" endif # IIO diff --git a/drivers/staging/iio/Makefile b/drivers/staging/iio/Makefile index 766a5d1a8373..5b449a15e5aa 100644 --- a/drivers/staging/iio/Makefile +++ b/drivers/staging/iio/Makefile @@ -17,5 +17,6 @@ obj-y += dds/ obj-y += gyro/ obj-y += imu/ obj-y += light/ -obj-y += trigger/ obj-y += magnetometer/ +obj-y += meter/ +obj-y += trigger/ diff --git a/drivers/staging/iio/meter/Kconfig b/drivers/staging/iio/meter/Kconfig new file mode 100644 index 000000000000..0c09c39b63ec --- /dev/null +++ b/drivers/staging/iio/meter/Kconfig @@ -0,0 +1,11 @@ +# +# IIO meter drivers configuration +# +comment "Active energy metering IC" + +config ADE7753 + tristate "Analog Devices ADE7753/6 Single-Phase Multifunction Metering IC Driver" + depends on SPI + help + Say yes here to build support for Analog Devices ADE7753 Single-Phase Multifunction + Metering IC with di/dt Sensor Interface. diff --git a/drivers/staging/iio/meter/Makefile b/drivers/staging/iio/meter/Makefile new file mode 100644 index 000000000000..b4eac385848d --- /dev/null +++ b/drivers/staging/iio/meter/Makefile @@ -0,0 +1,5 @@ +# +# Makefile for metering ic drivers +# + +obj-$(CONFIG_ADE7753) += ade7753.o diff --git a/drivers/staging/iio/meter/ade7753.c b/drivers/staging/iio/meter/ade7753.c new file mode 100644 index 000000000000..e72afbd2b841 --- /dev/null +++ b/drivers/staging/iio/meter/ade7753.c @@ -0,0 +1,730 @@ +/* + * ADE7753 Single-Phase Multifunction Metering IC with di/dt Sensor Interface Driver + * + * Copyright 2010 Analog Devices Inc. + * + * Licensed under the GPL-2 or later. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../iio.h" +#include "../sysfs.h" +#include "meter.h" +#include "ade7753.h" + +int ade7753_spi_write_reg_8(struct device *dev, + u8 reg_address, + u8 val) +{ + int ret; + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct ade7753_state *st = iio_dev_get_devdata(indio_dev); + + mutex_lock(&st->buf_lock); + st->tx[0] = ADE7753_WRITE_REG(reg_address); + st->tx[1] = val; + + ret = spi_write(st->us, st->tx, 2); + mutex_unlock(&st->buf_lock); + + return ret; +} + +static int ade7753_spi_write_reg_16(struct device *dev, + u8 reg_address, + u16 value) +{ + int ret; + struct spi_message msg; + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct ade7753_state *st = iio_dev_get_devdata(indio_dev); + struct spi_transfer xfers[] = { + { + .tx_buf = st->tx, + .bits_per_word = 8, + .len = 3, + } + }; + + mutex_lock(&st->buf_lock); + st->tx[0] = ADE7753_WRITE_REG(reg_address); + st->tx[1] = (value >> 8) & 0xFF; + st->tx[2] = value & 0xFF; + + spi_message_init(&msg); + spi_message_add_tail(xfers, &msg); + ret = spi_sync(st->us, &msg); + mutex_unlock(&st->buf_lock); + + return ret; +} + +static int ade7753_spi_read_reg_8(struct device *dev, + u8 reg_address, + u8 *val) +{ + struct spi_message msg; + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct ade7753_state *st = iio_dev_get_devdata(indio_dev); + int ret; + struct spi_transfer xfers[] = { + { + .tx_buf = st->tx, + .rx_buf = st->rx, + .bits_per_word = 8, + .len = 2, + }, + }; + + mutex_lock(&st->buf_lock); + st->tx[0] = ADE7753_READ_REG(reg_address); + st->tx[1] = 0; + + spi_message_init(&msg); + spi_message_add_tail(xfers, &msg); + ret = spi_sync(st->us, &msg); + if (ret) { + dev_err(&st->us->dev, "problem when reading 8 bit register 0x%02X", + reg_address); + goto error_ret; + } + *val = st->rx[1]; + +error_ret: + mutex_unlock(&st->buf_lock); + return ret; +} + +static int ade7753_spi_read_reg_16(struct device *dev, + u8 reg_address, + u16 *val) +{ + struct spi_message msg; + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct ade7753_state *st = iio_dev_get_devdata(indio_dev); + int ret; + struct spi_transfer xfers[] = { + { + .tx_buf = st->tx, + .rx_buf = st->rx, + .bits_per_word = 8, + .len = 3, + }, + }; + + mutex_lock(&st->buf_lock); + st->tx[0] = ADE7753_READ_REG(reg_address); + st->tx[1] = 0; + st->tx[2] = 0; + + spi_message_init(&msg); + spi_message_add_tail(xfers, &msg); + ret = spi_sync(st->us, &msg); + if (ret) { + dev_err(&st->us->dev, "problem when reading 16 bit register 0x%02X", + reg_address); + goto error_ret; + } + *val = (st->rx[1] << 8) | st->rx[2]; + +error_ret: + mutex_unlock(&st->buf_lock); + return ret; +} + +static int ade7753_spi_read_reg_24(struct device *dev, + u8 reg_address, + u32 *val) +{ + struct spi_message msg; + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct ade7753_state *st = iio_dev_get_devdata(indio_dev); + int ret; + struct spi_transfer xfers[] = { + { + .tx_buf = st->tx, + .rx_buf = st->rx, + .bits_per_word = 8, + .len = 4, + }, + }; + + mutex_lock(&st->buf_lock); + st->tx[0] = ADE7753_READ_REG(reg_address); + st->tx[1] = 0; + st->tx[2] = 0; + st->tx[3] = 0; + + spi_message_init(&msg); + spi_message_add_tail(xfers, &msg); + ret = spi_sync(st->us, &msg); + if (ret) { + dev_err(&st->us->dev, "problem when reading 24 bit register 0x%02X", + reg_address); + goto error_ret; + } + *val = (st->rx[1] << 16) | (st->rx[2] << 8) | st->rx[3]; + +error_ret: + mutex_unlock(&st->buf_lock); + return ret; +} + +static ssize_t ade7753_read_8bit(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + int ret; + u8 val = 0; + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + + ret = ade7753_spi_read_reg_8(dev, this_attr->address, &val); + if (ret) + return ret; + + return sprintf(buf, "%u\n", val); +} + +static ssize_t ade7753_read_16bit(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + int ret; + u16 val = 0; + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + + ret = ade7753_spi_read_reg_16(dev, this_attr->address, &val); + if (ret) + return ret; + + return sprintf(buf, "%u\n", val); +} + +static ssize_t ade7753_read_24bit(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + int ret; + u32 val = 0; + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + + ret = ade7753_spi_read_reg_24(dev, this_attr->address, &val); + if (ret) + return ret; + + return sprintf(buf, "%u\n", val & 0xFFFFFF); +} + +static ssize_t ade7753_write_8bit(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + int ret; + long val; + + ret = strict_strtol(buf, 10, &val); + if (ret) + goto error_ret; + ret = ade7753_spi_write_reg_8(dev, this_attr->address, val); + +error_ret: + return ret ? ret : len; +} + +static ssize_t ade7753_write_16bit(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + int ret; + long val; + + ret = strict_strtol(buf, 10, &val); + if (ret) + goto error_ret; + ret = ade7753_spi_write_reg_16(dev, this_attr->address, val); + +error_ret: + return ret ? ret : len; +} + +static int ade7753_reset(struct device *dev) +{ + int ret; + u16 val; + ade7753_spi_read_reg_16(dev, + ADE7753_MODE, + &val); + val |= 1 << 6; /* Software Chip Reset */ + ret = ade7753_spi_write_reg_16(dev, + ADE7753_MODE, + val); + + return ret; +} + +static ssize_t ade7753_write_reset(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t len) +{ + if (len < 1) + return -1; + switch (buf[0]) { + case '1': + case 'y': + case 'Y': + return ade7753_reset(dev); + } + return -1; +} + +static IIO_DEV_ATTR_AENERGY(ade7753_read_24bit, ADE7753_AENERGY); +static IIO_DEV_ATTR_LAENERGY(ade7753_read_24bit, ADE7753_LAENERGY); +static IIO_DEV_ATTR_VAENERGY(ade7753_read_24bit, ADE7753_VAENERGY); +static IIO_DEV_ATTR_LVAENERGY(ade7753_read_24bit, ADE7753_LVAENERGY); +static IIO_DEV_ATTR_CFDEN(S_IWUSR | S_IRUGO, + ade7753_read_16bit, + ade7753_write_16bit, + ADE7753_CFDEN); +static IIO_DEV_ATTR_CFNUM(S_IWUSR | S_IRUGO, + ade7753_read_8bit, + ade7753_write_8bit, + ADE7753_CFNUM); +static IIO_DEV_ATTR_CHKSUM(ade7753_read_8bit, ADE7753_CHKSUM); +static IIO_DEV_ATTR_PHCAL(S_IWUSR | S_IRUGO, + ade7753_read_16bit, + ade7753_write_16bit, + ADE7753_PHCAL); +static IIO_DEV_ATTR_APOS(S_IWUSR | S_IRUGO, + ade7753_read_16bit, + ade7753_write_16bit, + ADE7753_APOS); +static IIO_DEV_ATTR_SAGCYC(S_IWUSR | S_IRUGO, + ade7753_read_8bit, + ade7753_write_8bit, + ADE7753_SAGCYC); +static IIO_DEV_ATTR_SAGLVL(S_IWUSR | S_IRUGO, + ade7753_read_8bit, + ade7753_write_8bit, + ADE7753_SAGLVL); +static IIO_DEV_ATTR_LINECYC(S_IWUSR | S_IRUGO, + ade7753_read_8bit, + ade7753_write_8bit, + ADE7753_LINECYC); +static IIO_DEV_ATTR_WDIV(S_IWUSR | S_IRUGO, + ade7753_read_8bit, + ade7753_write_8bit, + ADE7753_WDIV); +static IIO_DEV_ATTR_IRMS(S_IWUSR | S_IRUGO, + ade7753_read_24bit, + NULL, + ADE7753_IRMS); +static IIO_DEV_ATTR_VRMS(S_IRUGO, + ade7753_read_24bit, + NULL, + ADE7753_VRMS); +static IIO_DEV_ATTR_IRMSOS(S_IWUSR | S_IRUGO, + ade7753_read_16bit, + ade7753_write_16bit, + ADE7753_IRMSOS); +static IIO_DEV_ATTR_VRMSOS(S_IWUSR | S_IRUGO, + ade7753_read_16bit, + ade7753_write_16bit, + ADE7753_VRMSOS); +static IIO_DEV_ATTR_WGAIN(S_IWUSR | S_IRUGO, + ade7753_read_16bit, + ade7753_write_16bit, + ADE7753_WGAIN); +static IIO_DEV_ATTR_VAGAIN(S_IWUSR | S_IRUGO, + ade7753_read_16bit, + ade7753_write_16bit, + ADE7753_VAGAIN); +static IIO_DEV_ATTR_PGA_GAIN(S_IWUSR | S_IRUGO, + ade7753_read_16bit, + ade7753_write_16bit, + ADE7753_GAIN); +static IIO_DEV_ATTR_IPKLVL(S_IWUSR | S_IRUGO, + ade7753_read_8bit, + ade7753_write_8bit, + ADE7753_IPKLVL); +static IIO_DEV_ATTR_VPKLVL(S_IWUSR | S_IRUGO, + ade7753_read_8bit, + ade7753_write_8bit, + ADE7753_VPKLVL); +static IIO_DEV_ATTR_IPEAK(S_IRUGO, + ade7753_read_24bit, + NULL, + ADE7753_IPEAK); +static IIO_DEV_ATTR_VPEAK(S_IRUGO, + ade7753_read_24bit, + NULL, + ADE7753_VPEAK); +static IIO_DEV_ATTR_VPERIOD(S_IRUGO, + ade7753_read_16bit, + NULL, + ADE7753_PERIOD); +static IIO_DEV_ATTR_CH_OFF(1, S_IWUSR | S_IRUGO, + ade7753_read_8bit, + ade7753_write_8bit, + ADE7753_CH1OS); +static IIO_DEV_ATTR_CH_OFF(2, S_IWUSR | S_IRUGO, + ade7753_read_8bit, + ade7753_write_8bit, + ADE7753_CH2OS); + +static int ade7753_set_irq(struct device *dev, bool enable) +{ + int ret; + u8 irqen; + ret = ade7753_spi_read_reg_8(dev, ADE7753_IRQEN, &irqen); + if (ret) + goto error_ret; + + if (enable) + irqen |= 1 << 3; /* Enables an interrupt when a data is + present in the waveform register */ + else + irqen &= ~(1 << 3); + + ret = ade7753_spi_write_reg_8(dev, ADE7753_IRQEN, irqen); + if (ret) + goto error_ret; + +error_ret: + return ret; +} + +/* Power down the device */ +int ade7753_stop_device(struct device *dev) +{ + int ret; + u16 val; + ade7753_spi_read_reg_16(dev, + ADE7753_MODE, + &val); + val |= 1 << 4; /* AD converters can be turned off */ + ret = ade7753_spi_write_reg_16(dev, + ADE7753_MODE, + val); + + return ret; +} + +static int ade7753_initial_setup(struct ade7753_state *st) +{ + int ret; + struct device *dev = &st->indio_dev->dev; + + /* use low spi speed for init */ + st->us->mode = SPI_MODE_3; + spi_setup(st->us); + + /* Disable IRQ */ + ret = ade7753_set_irq(dev, false); + if (ret) { + dev_err(dev, "disable irq failed"); + goto err_ret; + } + + ade7753_reset(dev); + msleep(ADE7753_STARTUP_DELAY); + +err_ret: + return ret; +} + +static ssize_t ade7753_read_frequency(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + int ret, len = 0; + u8 t; + int sps; + ret = ade7753_spi_read_reg_8(dev, + ADE7753_MODE, + &t); + if (ret) + return ret; + + t = (t >> 11) & 0x3; + sps = 27900 / (1 + t); + + len = sprintf(buf, "%d SPS\n", sps); + return len; +} + +static ssize_t ade7753_write_frequency(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct ade7753_state *st = iio_dev_get_devdata(indio_dev); + unsigned long val; + int ret; + u16 reg, t; + + ret = strict_strtol(buf, 10, &val); + if (ret) + return ret; + + mutex_lock(&indio_dev->mlock); + + t = (27900 / val); + if (t > 0) + t--; + + if (t > 1) + st->us->max_speed_hz = ADE7753_SPI_SLOW; + else + st->us->max_speed_hz = ADE7753_SPI_FAST; + + ret = ade7753_spi_read_reg_16(dev, + ADE7753_MODE, + ®); + if (ret) + goto out; + + reg &= ~(3 << 11); + reg |= t << 11; + + ret = ade7753_spi_write_reg_16(dev, + ADE7753_MODE, + reg); + +out: + mutex_unlock(&indio_dev->mlock); + + return ret ? ret : len; +} +static IIO_DEV_ATTR_TEMP_RAW(ade7753_read_8bit); +static IIO_CONST_ATTR(temp_offset, "-25 C"); +static IIO_CONST_ATTR(temp_scale, "0.67 C"); + +static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO, + ade7753_read_frequency, + ade7753_write_frequency); + +static IIO_DEV_ATTR_RESET(ade7753_write_reset); + +static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("27900 14000 7000 3500"); + +static IIO_CONST_ATTR(name, "ade7753"); + +static struct attribute *ade7753_event_attributes[] = { + NULL +}; + +static struct attribute_group ade7753_event_attribute_group = { + .attrs = ade7753_event_attributes, +}; + +static struct attribute *ade7753_attributes[] = { + &iio_dev_attr_temp_raw.dev_attr.attr, + &iio_const_attr_temp_offset.dev_attr.attr, + &iio_const_attr_temp_scale.dev_attr.attr, + &iio_dev_attr_sampling_frequency.dev_attr.attr, + &iio_const_attr_sampling_frequency_available.dev_attr.attr, + &iio_dev_attr_reset.dev_attr.attr, + &iio_const_attr_name.dev_attr.attr, + &iio_dev_attr_phcal.dev_attr.attr, + &iio_dev_attr_cfden.dev_attr.attr, + &iio_dev_attr_aenergy.dev_attr.attr, + &iio_dev_attr_laenergy.dev_attr.attr, + &iio_dev_attr_vaenergy.dev_attr.attr, + &iio_dev_attr_lvaenergy.dev_attr.attr, + &iio_dev_attr_cfnum.dev_attr.attr, + &iio_dev_attr_apos.dev_attr.attr, + &iio_dev_attr_sagcyc.dev_attr.attr, + &iio_dev_attr_saglvl.dev_attr.attr, + &iio_dev_attr_linecyc.dev_attr.attr, + &iio_dev_attr_chksum.dev_attr.attr, + &iio_dev_attr_pga_gain.dev_attr.attr, + &iio_dev_attr_wgain.dev_attr.attr, + &iio_dev_attr_choff_1.dev_attr.attr, + &iio_dev_attr_choff_2.dev_attr.attr, + &iio_dev_attr_wdiv.dev_attr.attr, + &iio_dev_attr_irms.dev_attr.attr, + &iio_dev_attr_vrms.dev_attr.attr, + &iio_dev_attr_irmsos.dev_attr.attr, + &iio_dev_attr_vrmsos.dev_attr.attr, + &iio_dev_attr_vagain.dev_attr.attr, + &iio_dev_attr_ipklvl.dev_attr.attr, + &iio_dev_attr_vpklvl.dev_attr.attr, + &iio_dev_attr_ipeak.dev_attr.attr, + &iio_dev_attr_vpeak.dev_attr.attr, + &iio_dev_attr_vperiod.dev_attr.attr, + NULL, +}; + +static const struct attribute_group ade7753_attribute_group = { + .attrs = ade7753_attributes, +}; + +static int __devinit ade7753_probe(struct spi_device *spi) +{ + int ret, regdone = 0; + struct ade7753_state *st = kzalloc(sizeof *st, GFP_KERNEL); + if (!st) { + ret = -ENOMEM; + goto error_ret; + } + /* this is only used for removal purposes */ + spi_set_drvdata(spi, st); + + /* Allocate the comms buffers */ + st->rx = kzalloc(sizeof(*st->rx)*ADE7753_MAX_RX, GFP_KERNEL); + if (st->rx == NULL) { + ret = -ENOMEM; + goto error_free_st; + } + st->tx = kzalloc(sizeof(*st->tx)*ADE7753_MAX_TX, GFP_KERNEL); + if (st->tx == NULL) { + ret = -ENOMEM; + goto error_free_rx; + } + st->us = spi; + mutex_init(&st->buf_lock); + /* setup the industrialio driver allocated elements */ + st->indio_dev = iio_allocate_device(); + if (st->indio_dev == NULL) { + ret = -ENOMEM; + goto error_free_tx; + } + + st->indio_dev->dev.parent = &spi->dev; + st->indio_dev->num_interrupt_lines = 1; + st->indio_dev->event_attrs = &ade7753_event_attribute_group; + st->indio_dev->attrs = &ade7753_attribute_group; + st->indio_dev->dev_data = (void *)(st); + st->indio_dev->driver_module = THIS_MODULE; + st->indio_dev->modes = INDIO_DIRECT_MODE; + + ret = ade7753_configure_ring(st->indio_dev); + if (ret) + goto error_free_dev; + + ret = iio_device_register(st->indio_dev); + if (ret) + goto error_unreg_ring_funcs; + regdone = 1; + + ret = ade7753_initialize_ring(st->indio_dev->ring); + if (ret) { + printk(KERN_ERR "failed to initialize the ring\n"); + goto error_unreg_ring_funcs; + } + + if (spi->irq) { + ret = iio_register_interrupt_line(spi->irq, + st->indio_dev, + 0, + IRQF_TRIGGER_FALLING, + "ade7753"); + if (ret) + goto error_uninitialize_ring; + + ret = ade7753_probe_trigger(st->indio_dev); + if (ret) + goto error_unregister_line; + } + + /* Get the device into a sane initial state */ + ret = ade7753_initial_setup(st); + if (ret) + goto error_remove_trigger; + return 0; + +error_remove_trigger: + if (st->indio_dev->modes & INDIO_RING_TRIGGERED) + ade7753_remove_trigger(st->indio_dev); +error_unregister_line: + if (st->indio_dev->modes & INDIO_RING_TRIGGERED) + iio_unregister_interrupt_line(st->indio_dev, 0); +error_uninitialize_ring: + ade7753_uninitialize_ring(st->indio_dev->ring); +error_unreg_ring_funcs: + ade7753_unconfigure_ring(st->indio_dev); +error_free_dev: + if (regdone) + iio_device_unregister(st->indio_dev); + else + iio_free_device(st->indio_dev); +error_free_tx: + kfree(st->tx); +error_free_rx: + kfree(st->rx); +error_free_st: + kfree(st); +error_ret: + return ret; +} + +/* fixme, confirm ordering in this function */ +static int ade7753_remove(struct spi_device *spi) +{ + int ret; + struct ade7753_state *st = spi_get_drvdata(spi); + struct iio_dev *indio_dev = st->indio_dev; + + ret = ade7753_stop_device(&(indio_dev->dev)); + if (ret) + goto err_ret; + + flush_scheduled_work(); + + ade7753_remove_trigger(indio_dev); + if (spi->irq && gpio_is_valid(irq_to_gpio(spi->irq)) > 0) + iio_unregister_interrupt_line(indio_dev, 0); + + ade7753_uninitialize_ring(indio_dev->ring); + ade7753_unconfigure_ring(indio_dev); + iio_device_unregister(indio_dev); + kfree(st->tx); + kfree(st->rx); + kfree(st); + + return 0; + +err_ret: + return ret; +} + +static struct spi_driver ade7753_driver = { + .driver = { + .name = "ade7753", + .owner = THIS_MODULE, + }, + .probe = ade7753_probe, + .remove = __devexit_p(ade7753_remove), +}; + +static __init int ade7753_init(void) +{ + return spi_register_driver(&ade7753_driver); +} +module_init(ade7753_init); + +static __exit void ade7753_exit(void) +{ + spi_unregister_driver(&ade7753_driver); +} +module_exit(ade7753_exit); + +MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>"); +MODULE_DESCRIPTION("Analog Devices ADE7753/6 Single-Phase Multifunction Metering IC Driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/staging/iio/meter/ade7753.h b/drivers/staging/iio/meter/ade7753.h new file mode 100644 index 000000000000..a3722b8c90fa --- /dev/null +++ b/drivers/staging/iio/meter/ade7753.h @@ -0,0 +1,140 @@ +#ifndef _ADE7753_H +#define _ADE7753_H + +#define ADE7753_WAVEFORM 0x01 +#define ADE7753_AENERGY 0x02 +#define ADE7753_RAENERGY 0x03 +#define ADE7753_LAENERGY 0x04 +#define ADE7753_VAENERGY 0x05 +#define ADE7753_RVAENERGY 0x06 +#define ADE7753_LVAENERGY 0x07 +#define ADE7753_LVARENERGY 0x08 +#define ADE7753_MODE 0x09 +#define ADE7753_IRQEN 0x0A +#define ADE7753_STATUS 0x0B +#define ADE7753_RSTSTATUS 0x0C +#define ADE7753_CH1OS 0x0D +#define ADE7753_CH2OS 0x0E +#define ADE7753_GAIN 0x0F +#define ADE7753_PHCAL 0x10 +#define ADE7753_APOS 0x11 +#define ADE7753_WGAIN 0x12 +#define ADE7753_WDIV 0x13 +#define ADE7753_CFNUM 0x14 +#define ADE7753_CFDEN 0x15 +#define ADE7753_IRMS 0x16 +#define ADE7753_VRMS 0x17 +#define ADE7753_IRMSOS 0x18 +#define ADE7753_VRMSOS 0x19 +#define ADE7753_VAGAIN 0x1A +#define ADE7753_VADIV 0x1B +#define ADE7753_LINECYC 0x1C +#define ADE7753_ZXTOUT 0x1D +#define ADE7753_SAGCYC 0x1E +#define ADE7753_SAGLVL 0x1F +#define ADE7753_IPKLVL 0x20 +#define ADE7753_VPKLVL 0x21 +#define ADE7753_IPEAK 0x22 +#define ADE7753_RSTIPEAK 0x23 +#define ADE7753_VPEAK 0x24 +#define ADE7753_RSTVPEAK 0x25 +#define ADE7753_TEMP 0x26 +#define ADE7753_PERIOD 0x27 +#define ADE7753_TMODE 0x3D +#define ADE7753_CHKSUM 0x3E +#define ADE7753_DIEREV 0x3F + +#define ADE7753_READ_REG(a) a +#define ADE7753_WRITE_REG(a) ((a) | 0x80) + +#define ADE7753_MAX_TX 4 +#define ADE7753_MAX_RX 4 +#define ADE7753_STARTUP_DELAY 1 + +#define ADE7753_SPI_SLOW (u32)(300 * 1000) +#define ADE7753_SPI_BURST (u32)(1000 * 1000) +#define ADE7753_SPI_FAST (u32)(2000 * 1000) + +#define DRIVER_NAME "ade7753" + +/** + * struct ade7753_state - device instance specific data + * @us: actual spi_device + * @work_trigger_to_ring: bh for triggered event handling + * @inter: used to check if new interrupt has been triggered + * @last_timestamp: passing timestamp from th to bh of interrupt handler + * @indio_dev: industrial I/O device structure + * @trig: data ready trigger registered with iio + * @tx: transmit buffer + * @rx: recieve buffer + * @buf_lock: mutex to protect tx and rx + **/ +struct ade7753_state { + struct spi_device *us; + struct work_struct work_trigger_to_ring; + s64 last_timestamp; + struct iio_dev *indio_dev; + struct iio_trigger *trig; + u8 *tx; + u8 *rx; + struct mutex buf_lock; +}; +#if defined(CONFIG_IIO_RING_BUFFER) && defined(THIS_HAS_RING_BUFFER_SUPPORT) +/* At the moment triggers are only used for ring buffer + * filling. This may change! + */ + +enum ade7753_scan { + ADE7753_SCAN_ACTIVE_POWER, + ADE7753_SCAN_CH1, + ADE7753_SCAN_CH2, +}; + +void ade7753_remove_trigger(struct iio_dev *indio_dev); +int ade7753_probe_trigger(struct iio_dev *indio_dev); + +ssize_t ade7753_read_data_from_ring(struct device *dev, + struct device_attribute *attr, + char *buf); + + +int ade7753_configure_ring(struct iio_dev *indio_dev); +void ade7753_unconfigure_ring(struct iio_dev *indio_dev); + +int ade7753_initialize_ring(struct iio_ring_buffer *ring); +void ade7753_uninitialize_ring(struct iio_ring_buffer *ring); +#else /* CONFIG_IIO_RING_BUFFER */ + +static inline void ade7753_remove_trigger(struct iio_dev *indio_dev) +{ +} +static inline int ade7753_probe_trigger(struct iio_dev *indio_dev) +{ + return 0; +} + +static inline ssize_t +ade7753_read_data_from_ring(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + return 0; +} + +static int ade7753_configure_ring(struct iio_dev *indio_dev) +{ + return 0; +} +static inline void ade7753_unconfigure_ring(struct iio_dev *indio_dev) +{ +} +static inline int ade7753_initialize_ring(struct iio_ring_buffer *ring) +{ + return 0; +} +static inline void ade7753_uninitialize_ring(struct iio_ring_buffer *ring) +{ +} +#endif /* CONFIG_IIO_RING_BUFFER */ + +#endif diff --git a/drivers/staging/iio/meter/meter.h b/drivers/staging/iio/meter/meter.h new file mode 100644 index 000000000000..142c50d71fda --- /dev/null +++ b/drivers/staging/iio/meter/meter.h @@ -0,0 +1,396 @@ +#include "../sysfs.h" + +/* metering ic types of attribute */ + +#define IIO_DEV_ATTR_CURRENT_A_OFFSET(_mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(current_a_offset, _mode, _show, _store, _addr) + +#define IIO_DEV_ATTR_CURRENT_B_OFFSET(_mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(current_b_offset, _mode, _show, _store, _addr) + +#define IIO_DEV_ATTR_CURRENT_C_OFFSET(_mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(current_c_offset, _mode, _show, _store, _addr) + +#define IIO_DEV_ATTR_VOLT_A_OFFSET(_mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(volt_a_offset, _mode, _show, _store, _addr) + +#define IIO_DEV_ATTR_VOLT_B_OFFSET(_mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(volt_b_offset, _mode, _show, _store, _addr) + +#define IIO_DEV_ATTR_VOLT_C_OFFSET(_mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(volt_c_offset, _mode, _show, _store, _addr) + +#define IIO_DEV_ATTR_REACTIVE_POWER_A_OFFSET(_mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(reactive_power_a_offset, _mode, _show, _store, _addr) + +#define IIO_DEV_ATTR_REACTIVE_POWER_B_OFFSET(_mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(reactive_power_b_offset, _mode, _show, _store, _addr) + +#define IIO_DEV_ATTR_REACTIVE_POWER_C_OFFSET(_mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(reactive_power_c_offset, _mode, _show, _store, _addr) + +#define IIO_DEV_ATTR_ACTIVE_POWER_A_OFFSET(_mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(active_power_a_offset, _mode, _show, _store, _addr) + +#define IIO_DEV_ATTR_ACTIVE_POWER_B_OFFSET(_mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(active_power_b_offset, _mode, _show, _store, _addr) + +#define IIO_DEV_ATTR_ACTIVE_POWER_C_OFFSET(_mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(active_power_c_offset, _mode, _show, _store, _addr) + +#define IIO_DEV_ATTR_CURRENT_A_GAIN(_mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(current_a_gain, _mode, _show, _store, _addr) + +#define IIO_DEV_ATTR_CURRENT_B_GAIN(_mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(current_b_gain, _mode, _show, _store, _addr) + +#define IIO_DEV_ATTR_CURRENT_C_GAIN(_mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(current_c_gain, _mode, _show, _store, _addr) + +#define IIO_DEV_ATTR_APPARENT_POWER_A_GAIN(_mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(apparent_power_a_gain, _mode, _show, _store, _addr) + +#define IIO_DEV_ATTR_APPARENT_POWER_B_GAIN(_mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(apparent_power_b_gain, _mode, _show, _store, _addr) + +#define IIO_DEV_ATTR_APPARENT_POWER_C_GAIN(_mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(apparent_power_c_gain, _mode, _show, _store, _addr) + +#define IIO_DEV_ATTR_ACTIVE_POWER_GAIN(_mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(active_power_gain, _mode, _show, _store, _addr) + +#define IIO_DEV_ATTR_ACTIVE_POWER_A_GAIN(_mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(active_power_a_gain, _mode, _show, _store, _addr) + +#define IIO_DEV_ATTR_ACTIVE_POWER_B_GAIN(_mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(active_power_b_gain, _mode, _show, _store, _addr) + +#define IIO_DEV_ATTR_ACTIVE_POWER_C_GAIN(_mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(active_power_c_gain, _mode, _show, _store, _addr) + +#define IIO_DEV_ATTR_REACTIVE_POWER_A_GAIN(_mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(reactive_power_a_gain, _mode, _show, _store, _addr) + +#define IIO_DEV_ATTR_REACTIVE_POWER_B_GAIN(_mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(reactive_power_b_gain, _mode, _show, _store, _addr) + +#define IIO_DEV_ATTR_REACTIVE_POWER_C_GAIN(_mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(reactive_power_c_gain, _mode, _show, _store, _addr) + +#define IIO_DEV_ATTR_CURRENT_A(_show, _addr) \ + IIO_DEVICE_ATTR(current_a, S_IRUGO, _show, NULL, _addr) + +#define IIO_DEV_ATTR_CURRENT_B(_show, _addr) \ + IIO_DEVICE_ATTR(current_b, S_IRUGO, _show, NULL, _addr) + +#define IIO_DEV_ATTR_CURRENT_C(_show, _addr) \ + IIO_DEVICE_ATTR(current_c, S_IRUGO, _show, NULL, _addr) + +#define IIO_DEV_ATTR_VOLT_A(_show, _addr) \ + IIO_DEVICE_ATTR(volt_a, S_IRUGO, _show, NULL, _addr) + +#define IIO_DEV_ATTR_VOLT_B(_show, _addr) \ + IIO_DEVICE_ATTR(volt_b, S_IRUGO, _show, NULL, _addr) + +#define IIO_DEV_ATTR_VOLT_C(_show, _addr) \ + IIO_DEVICE_ATTR(volt_c, S_IRUGO, _show, NULL, _addr) + +#define IIO_DEV_ATTR_AENERGY(_show, _addr) \ + IIO_DEVICE_ATTR(aenergy, S_IRUGO, _show, NULL, _addr) + +#define IIO_DEV_ATTR_LENERGY(_show, _addr) \ + IIO_DEVICE_ATTR(lenergy, S_IRUGO, _show, NULL, _addr) + +#define IIO_DEV_ATTR_RAENERGY(_show, _addr) \ + IIO_DEVICE_ATTR(raenergy, S_IRUGO, _show, NULL, _addr) + +#define IIO_DEV_ATTR_LAENERGY(_show, _addr) \ + IIO_DEVICE_ATTR(laenergy, S_IRUGO, _show, NULL, _addr) + +#define IIO_DEV_ATTR_VAENERGY(_show, _addr) \ + IIO_DEVICE_ATTR(vaenergy, S_IRUGO, _show, NULL, _addr) + +#define IIO_DEV_ATTR_LVAENERGY(_show, _addr) \ + IIO_DEVICE_ATTR(lvaenergy, S_IRUGO, _show, NULL, _addr) + +#define IIO_DEV_ATTR_RVAENERGY(_show, _addr) \ + IIO_DEVICE_ATTR(rvaenergy, S_IRUGO, _show, NULL, _addr) + +#define IIO_DEV_ATTR_LVARENERGY(_show, _addr) \ + IIO_DEVICE_ATTR(lvarenergy, S_IRUGO, _show, NULL, _addr) + +#define IIO_DEV_ATTR_CHKSUM(_show, _addr) \ + IIO_DEVICE_ATTR(chksum, S_IRUGO, _show, NULL, _addr) + +#define IIO_DEV_ATTR_ANGLE0(_show, _addr) \ + IIO_DEVICE_ATTR(angle0, S_IRUGO, _show, NULL, _addr) + +#define IIO_DEV_ATTR_ANGLE1(_show, _addr) \ + IIO_DEVICE_ATTR(angle1, S_IRUGO, _show, NULL, _addr) + +#define IIO_DEV_ATTR_ANGLE2(_show, _addr) \ + IIO_DEVICE_ATTR(angle2, S_IRUGO, _show, NULL, _addr) + +#define IIO_DEV_ATTR_AWATTHR(_show, _addr) \ + IIO_DEVICE_ATTR(awatthr, S_IRUGO, _show, NULL, _addr) + +#define IIO_DEV_ATTR_BWATTHR(_show, _addr) \ + IIO_DEVICE_ATTR(bwatthr, S_IRUGO, _show, NULL, _addr) + +#define IIO_DEV_ATTR_CWATTHR(_show, _addr) \ + IIO_DEVICE_ATTR(cwatthr, S_IRUGO, _show, NULL, _addr) + +#define IIO_DEV_ATTR_AFWATTHR(_show, _addr) \ + IIO_DEVICE_ATTR(afwatthr, S_IRUGO, _show, NULL, _addr) + +#define IIO_DEV_ATTR_BFWATTHR(_show, _addr) \ + IIO_DEVICE_ATTR(bfwatthr, S_IRUGO, _show, NULL, _addr) + +#define IIO_DEV_ATTR_CFWATTHR(_show, _addr) \ + IIO_DEVICE_ATTR(cfwatthr, S_IRUGO, _show, NULL, _addr) + +#define IIO_DEV_ATTR_AVARHR(_show, _addr) \ + IIO_DEVICE_ATTR(avarhr, S_IRUGO, _show, NULL, _addr) + +#define IIO_DEV_ATTR_BVARHR(_show, _addr) \ + IIO_DEVICE_ATTR(bvarhr, S_IRUGO, _show, NULL, _addr) + +#define IIO_DEV_ATTR_CVARHR(_show, _addr) \ + IIO_DEVICE_ATTR(cvarhr, S_IRUGO, _show, NULL, _addr) + +#define IIO_DEV_ATTR_AVAHR(_show, _addr) \ + IIO_DEVICE_ATTR(avahr, S_IRUGO, _show, NULL, _addr) + +#define IIO_DEV_ATTR_BVAHR(_show, _addr) \ + IIO_DEVICE_ATTR(bvahr, S_IRUGO, _show, NULL, _addr) + +#define IIO_DEV_ATTR_CVAHR(_show, _addr) \ + IIO_DEVICE_ATTR(cvahr, S_IRUGO, _show, NULL, _addr) + +#define IIO_DEV_ATTR_IOS(_mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(ios, _mode, _show, _store, _addr) + +#define IIO_DEV_ATTR_VOS(_mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(vos, _mode, _show, _store, _addr) + +#define IIO_DEV_ATTR_PHCAL(_mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(phcal, _mode, _show, _store, _addr) + +#define IIO_DEV_ATTR_APHCAL(_mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(aphcal, _mode, _show, _store, _addr) + +#define IIO_DEV_ATTR_BPHCAL(_mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(bphcal, _mode, _show, _store, _addr) + +#define IIO_DEV_ATTR_CPHCAL(_mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(cphcal, _mode, _show, _store, _addr) + +#define IIO_DEV_ATTR_APOS(_mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(apos, _mode, _show, _store, _addr) + +#define IIO_DEV_ATTR_AAPOS(_mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(aapos, _mode, _show, _store, _addr) + +#define IIO_DEV_ATTR_BAPOS(_mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(bapos, _mode, _show, _store, _addr) + +#define IIO_DEV_ATTR_CAPOS(_mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(capos, _mode, _show, _store, _addr) + +#define IIO_DEV_ATTR_AVRMSGAIN(_mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(avrmsgain, _mode, _show, _store, _addr) + +#define IIO_DEV_ATTR_BVRMSGAIN(_mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(bvrmsgain, _mode, _show, _store, _addr) + +#define IIO_DEV_ATTR_CVRMSGAIN(_mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(cvrmsgain, _mode, _show, _store, _addr) + +#define IIO_DEV_ATTR_AIGAIN(_mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(aigain, _mode, _show, _store, _addr) + +#define IIO_DEV_ATTR_BIGAIN(_mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(bigain, _mode, _show, _store, _addr) + +#define IIO_DEV_ATTR_CIGAIN(_mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(cigain, _mode, _show, _store, _addr) + +#define IIO_DEV_ATTR_NIGAIN(_mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(nigain, _mode, _show, _store, _addr) + +#define IIO_DEV_ATTR_AVGAIN(_mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(avgain, _mode, _show, _store, _addr) + +#define IIO_DEV_ATTR_BVGAIN(_mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(bvgain, _mode, _show, _store, _addr) + +#define IIO_DEV_ATTR_CVGAIN(_mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(cvgain, _mode, _show, _store, _addr) + +#define IIO_DEV_ATTR_WGAIN(_mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(wgain, _mode, _show, _store, _addr) + +#define IIO_DEV_ATTR_WDIV(_mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(wdiv, _mode, _show, _store, _addr) + +#define IIO_DEV_ATTR_CFNUM(_mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(cfnum, _mode, _show, _store, _addr) + +#define IIO_DEV_ATTR_CFDEN(_mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(cfden, _mode, _show, _store, _addr) + +#define IIO_DEV_ATTR_CF1DEN(_mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(cf1den, _mode, _show, _store, _addr) + +#define IIO_DEV_ATTR_CF2DEN(_mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(cf2den, _mode, _show, _store, _addr) + +#define IIO_DEV_ATTR_CF3DEN(_mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(cf3den, _mode, _show, _store, _addr) + +#define IIO_DEV_ATTR_IRMS(_mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(irms, _mode, _show, _store, _addr) + +#define IIO_DEV_ATTR_VRMS(_mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(vrms, _mode, _show, _store, _addr) + +#define IIO_DEV_ATTR_AIRMS(_mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(airms, _mode, _show, _store, _addr) + +#define IIO_DEV_ATTR_BIRMS(_mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(birms, _mode, _show, _store, _addr) + +#define IIO_DEV_ATTR_CIRMS(_mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(cirms, _mode, _show, _store, _addr) + +#define IIO_DEV_ATTR_NIRMS(_mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(nirms, _mode, _show, _store, _addr) + +#define IIO_DEV_ATTR_AVRMS(_mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(avrms, _mode, _show, _store, _addr) + +#define IIO_DEV_ATTR_BVRMS(_mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(bvrms, _mode, _show, _store, _addr) + +#define IIO_DEV_ATTR_CVRMS(_mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(cvrms, _mode, _show, _store, _addr) + +#define IIO_DEV_ATTR_IRMSOS(_mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(irmsos, _mode, _show, _store, _addr) + +#define IIO_DEV_ATTR_VRMSOS(_mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(vrmsos, _mode, _show, _store, _addr) + +#define IIO_DEV_ATTR_AIRMSOS(_mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(airmsos, _mode, _show, _store, _addr) + +#define IIO_DEV_ATTR_BIRMSOS(_mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(birmsos, _mode, _show, _store, _addr) + +#define IIO_DEV_ATTR_CIRMSOS(_mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(cirmsos, _mode, _show, _store, _addr) + +#define IIO_DEV_ATTR_AVRMSOS(_mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(avrmsos, _mode, _show, _store, _addr) + +#define IIO_DEV_ATTR_BVRMSOS(_mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(bvrmsos, _mode, _show, _store, _addr) + +#define IIO_DEV_ATTR_CVRMSOS(_mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(cvrmsos, _mode, _show, _store, _addr) + +#define IIO_DEV_ATTR_VAGAIN(_mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(vagain, _mode, _show, _store, _addr) + +#define IIO_DEV_ATTR_PGA_GAIN(_mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(pga_gain, _mode, _show, _store, _addr) + +#define IIO_DEV_ATTR_VADIV(_mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(vadiv, _mode, _show, _store, _addr) + +#define IIO_DEV_ATTR_LINECYC(_mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(linecyc, _mode, _show, _store, _addr) + +#define IIO_DEV_ATTR_SAGCYC(_mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(sagcyc, _mode, _show, _store, _addr) + +#define IIO_DEV_ATTR_CFCYC(_mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(cfcyc, _mode, _show, _store, _addr) + +#define IIO_DEV_ATTR_PEAKCYC(_mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(peakcyc, _mode, _show, _store, _addr) + +#define IIO_DEV_ATTR_SAGLVL(_mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(saglvl, _mode, _show, _store, _addr) + +#define IIO_DEV_ATTR_IPKLVL(_mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(ipklvl, _mode, _show, _store, _addr) + +#define IIO_DEV_ATTR_VPKLVL(_mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(vpklvl, _mode, _show, _store, _addr) + +#define IIO_DEV_ATTR_IPEAK(_mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(ipeak, _mode, _show, _store, _addr) + +#define IIO_DEV_ATTR_RIPEAK(_mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(ripeak, _mode, _show, _store, _addr) + +#define IIO_DEV_ATTR_VPEAK(_mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(vpeak, _mode, _show, _store, _addr) + +#define IIO_DEV_ATTR_RVPEAK(_mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(rvpeak, _mode, _show, _store, _addr) + +#define IIO_DEV_ATTR_VPERIOD(_mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(vperiod, _mode, _show, _store, _addr) + +#define IIO_DEV_ATTR_CH_OFF(_num, _mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(choff_##_num, _mode, _show, _store, _addr) + +/* active energy register, AENERGY, is more than half full */ +#define IIO_EVENT_ATTR_AENERGY_HALF_FULL(_evlist, _show, _store, _mask) \ + IIO_EVENT_ATTR_SH(aenergy_half_full, _evlist, _show, _store, _mask) + +/* a SAG on the line voltage */ +#define IIO_EVENT_ATTR_LINE_VOLT_SAG(_evlist, _show, _store, _mask) \ + IIO_EVENT_ATTR_SH(line_volt_sag, _evlist, _show, _store, _mask) + +/* + * Indicates the end of energy accumulation over an integer number + * of half line cycles + */ +#define IIO_EVENT_ATTR_CYCEND(_evlist, _show, _store, _mask) \ + IIO_EVENT_ATTR_SH(cycend, _evlist, _show, _store, _mask) + +/* on the rising and falling edge of the the voltage waveform */ +#define IIO_EVENT_ATTR_ZERO_CROSS(_evlist, _show, _store, _mask) \ + IIO_EVENT_ATTR_SH(zero_cross, _evlist, _show, _store, _mask) + +/* the active energy register has overflowed */ +#define IIO_EVENT_ATTR_AENERGY_OVERFLOW(_evlist, _show, _store, _mask) \ + IIO_EVENT_ATTR_SH(aenergy_overflow, _evlist, _show, _store, _mask) + +/* the apparent energy register has overflowed */ +#define IIO_EVENT_ATTR_VAENERGY_OVERFLOW(_evlist, _show, _store, _mask) \ + IIO_EVENT_ATTR_SH(vaenergy_overflow, _evlist, _show, _store, _mask) + +/* the active energy register, VAENERGY, is more than half full */ +#define IIO_EVENT_ATTR_VAENERGY_HALF_FULL(_evlist, _show, _store, _mask) \ + IIO_EVENT_ATTR_SH(vaenergy_half_full, _evlist, _show, _store, _mask) + +/* the power has gone from negative to positive */ +#define IIO_EVENT_ATTR_PPOS(_evlist, _show, _store, _mask) \ + IIO_EVENT_ATTR_SH(ppos, _evlist, _show, _store, _mask) + +/* the power has gone from positive to negative */ +#define IIO_EVENT_ATTR_PNEG(_evlist, _show, _store, _mask) \ + IIO_EVENT_ATTR_SH(pneg, _evlist, _show, _store, _mask) + +/* waveform sample from Channel 1 has exceeded the IPKLVL value */ +#define IIO_EVENT_ATTR_IPKLVL_EXC(_evlist, _show, _store, _mask) \ + IIO_EVENT_ATTR_SH(ipklvl_exc, _evlist, _show, _store, _mask) + +/* waveform sample from Channel 2 has exceeded the VPKLVL value */ +#define IIO_EVENT_ATTR_VPKLVL_EXC(_evlist, _show, _store, _mask) \ + IIO_EVENT_ATTR_SH(vpklvl_exc, _evlist, _show, _store, _mask) + -- cgit v1.2.3 From 8d97a5877b85ab0a2b346c2c111a8192d336495f Mon Sep 17 00:00:00 2001 From: Barry Song Date: Wed, 27 Oct 2010 21:44:15 -0400 Subject: staging: iio: meter: new driver for ADE7754 devices Signed-off-by: Barry Song Signed-off-by: Michael Hennerich Acked-by: Jonathan Cameron Signed-off-by: Mike Frysinger Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/meter/Kconfig | 7 + drivers/staging/iio/meter/Makefile | 1 + drivers/staging/iio/meter/ade7754.c | 756 ++++++++++++++++++++++++++++++++++++ drivers/staging/iio/meter/ade7754.h | 161 ++++++++ 4 files changed, 925 insertions(+) create mode 100644 drivers/staging/iio/meter/ade7754.c create mode 100644 drivers/staging/iio/meter/ade7754.h diff --git a/drivers/staging/iio/meter/Kconfig b/drivers/staging/iio/meter/Kconfig index 0c09c39b63ec..19f20f4ad52c 100644 --- a/drivers/staging/iio/meter/Kconfig +++ b/drivers/staging/iio/meter/Kconfig @@ -9,3 +9,10 @@ config ADE7753 help Say yes here to build support for Analog Devices ADE7753 Single-Phase Multifunction Metering IC with di/dt Sensor Interface. + +config ADE7754 + tristate "Analog Devices ADE7754 Polyphase Multifunction Energy Metering IC Driver" + depends on SPI + help + Say yes here to build support for Analog Devices ADE7754 Polyphase + Multifunction Energy Metering IC Driver. diff --git a/drivers/staging/iio/meter/Makefile b/drivers/staging/iio/meter/Makefile index b4eac385848d..7f65b991eb15 100644 --- a/drivers/staging/iio/meter/Makefile +++ b/drivers/staging/iio/meter/Makefile @@ -3,3 +3,4 @@ # obj-$(CONFIG_ADE7753) += ade7753.o +obj-$(CONFIG_ADE7754) += ade7754.o diff --git a/drivers/staging/iio/meter/ade7754.c b/drivers/staging/iio/meter/ade7754.c new file mode 100644 index 000000000000..23dedfa7a270 --- /dev/null +++ b/drivers/staging/iio/meter/ade7754.c @@ -0,0 +1,756 @@ +/* + * ADE7754 Polyphase Multifunction Energy Metering IC Driver + * + * Copyright 2010 Analog Devices Inc. + * + * Licensed under the GPL-2 or later. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../iio.h" +#include "../sysfs.h" +#include "meter.h" +#include "ade7754.h" + +static int ade7754_spi_write_reg_8(struct device *dev, + u8 reg_address, + u8 val) +{ + int ret; + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct ade7754_state *st = iio_dev_get_devdata(indio_dev); + + mutex_lock(&st->buf_lock); + st->tx[0] = ADE7754_WRITE_REG(reg_address); + st->tx[1] = val; + + ret = spi_write(st->us, st->tx, 2); + mutex_unlock(&st->buf_lock); + + return ret; +} + +static int ade7754_spi_write_reg_16(struct device *dev, + u8 reg_address, + u16 value) +{ + int ret; + struct spi_message msg; + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct ade7754_state *st = iio_dev_get_devdata(indio_dev); + struct spi_transfer xfers[] = { + { + .tx_buf = st->tx, + .bits_per_word = 8, + .len = 3, + } + }; + + mutex_lock(&st->buf_lock); + st->tx[0] = ADE7754_WRITE_REG(reg_address); + st->tx[1] = (value >> 8) & 0xFF; + st->tx[2] = value & 0xFF; + + spi_message_init(&msg); + spi_message_add_tail(xfers, &msg); + ret = spi_sync(st->us, &msg); + mutex_unlock(&st->buf_lock); + + return ret; +} + +static int ade7754_spi_read_reg_8(struct device *dev, + u8 reg_address, + u8 *val) +{ + struct spi_message msg; + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct ade7754_state *st = iio_dev_get_devdata(indio_dev); + int ret; + struct spi_transfer xfers[] = { + { + .tx_buf = st->tx, + .rx_buf = st->rx, + .bits_per_word = 8, + .len = 2, + }, + }; + + mutex_lock(&st->buf_lock); + st->tx[0] = ADE7754_READ_REG(reg_address); + st->tx[1] = 0; + + spi_message_init(&msg); + spi_message_add_tail(xfers, &msg); + ret = spi_sync(st->us, &msg); + if (ret) { + dev_err(&st->us->dev, "problem when reading 8 bit register 0x%02X", + reg_address); + goto error_ret; + } + *val = st->rx[1]; + +error_ret: + mutex_unlock(&st->buf_lock); + return ret; +} + +static int ade7754_spi_read_reg_16(struct device *dev, + u8 reg_address, + u16 *val) +{ + struct spi_message msg; + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct ade7754_state *st = iio_dev_get_devdata(indio_dev); + int ret; + struct spi_transfer xfers[] = { + { + .tx_buf = st->tx, + .rx_buf = st->rx, + .bits_per_word = 8, + .len = 3, + }, + }; + + mutex_lock(&st->buf_lock); + st->tx[0] = ADE7754_READ_REG(reg_address); + st->tx[1] = 0; + st->tx[2] = 0; + + spi_message_init(&msg); + spi_message_add_tail(xfers, &msg); + ret = spi_sync(st->us, &msg); + if (ret) { + dev_err(&st->us->dev, "problem when reading 16 bit register 0x%02X", + reg_address); + goto error_ret; + } + *val = (st->rx[1] << 8) | st->rx[2]; + +error_ret: + mutex_unlock(&st->buf_lock); + return ret; +} + +static int ade7754_spi_read_reg_24(struct device *dev, + u8 reg_address, + u32 *val) +{ + struct spi_message msg; + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct ade7754_state *st = iio_dev_get_devdata(indio_dev); + int ret; + struct spi_transfer xfers[] = { + { + .tx_buf = st->tx, + .rx_buf = st->rx, + .bits_per_word = 8, + .len = 4, + }, + }; + + mutex_lock(&st->buf_lock); + st->tx[0] = ADE7754_READ_REG(reg_address); + st->tx[1] = 0; + st->tx[2] = 0; + st->tx[3] = 0; + + spi_message_init(&msg); + spi_message_add_tail(xfers, &msg); + ret = spi_sync(st->us, &msg); + if (ret) { + dev_err(&st->us->dev, "problem when reading 24 bit register 0x%02X", + reg_address); + goto error_ret; + } + *val = (st->rx[1] << 16) | (st->rx[2] << 8) | st->rx[3]; + +error_ret: + mutex_unlock(&st->buf_lock); + return ret; +} + +static ssize_t ade7754_read_8bit(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + int ret; + u8 val = 0; + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + + ret = ade7754_spi_read_reg_8(dev, this_attr->address, &val); + if (ret) + return ret; + + return sprintf(buf, "%u\n", val); +} + +static ssize_t ade7754_read_16bit(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + int ret; + u16 val = 0; + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + + ret = ade7754_spi_read_reg_16(dev, this_attr->address, &val); + if (ret) + return ret; + + return sprintf(buf, "%u\n", val); +} + +static ssize_t ade7754_read_24bit(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + int ret; + u32 val = 0; + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + + ret = ade7754_spi_read_reg_24(dev, this_attr->address, &val); + if (ret) + return ret; + + return sprintf(buf, "%u\n", val & 0xFFFFFF); +} + +static ssize_t ade7754_write_8bit(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + int ret; + long val; + + ret = strict_strtol(buf, 10, &val); + if (ret) + goto error_ret; + ret = ade7754_spi_write_reg_8(dev, this_attr->address, val); + +error_ret: + return ret ? ret : len; +} + +static ssize_t ade7754_write_16bit(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + int ret; + long val; + + ret = strict_strtol(buf, 10, &val); + if (ret) + goto error_ret; + ret = ade7754_spi_write_reg_16(dev, this_attr->address, val); + +error_ret: + return ret ? ret : len; +} + +static int ade7754_reset(struct device *dev) +{ + int ret; + u8 val; + ade7754_spi_read_reg_8(dev, + ADE7754_OPMODE, + &val); + val |= 1 << 6; /* Software Chip Reset */ + ret = ade7754_spi_write_reg_8(dev, + ADE7754_OPMODE, + val); + + return ret; +} + + +static ssize_t ade7754_write_reset(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t len) +{ + if (len < 1) + return -1; + switch (buf[0]) { + case '1': + case 'y': + case 'Y': + return ade7754_reset(dev); + } + return -1; +} + +static IIO_DEV_ATTR_AENERGY(ade7754_read_24bit, ADE7754_AENERGY); +static IIO_DEV_ATTR_LAENERGY(ade7754_read_24bit, ADE7754_LAENERGY); +static IIO_DEV_ATTR_VAENERGY(ade7754_read_24bit, ADE7754_VAENERGY); +static IIO_DEV_ATTR_LVAENERGY(ade7754_read_24bit, ADE7754_LVAENERGY); +static IIO_DEV_ATTR_VPEAK(S_IWUSR | S_IRUGO, + ade7754_read_8bit, + ade7754_write_8bit, + ADE7754_VPEAK); +static IIO_DEV_ATTR_IPEAK(S_IWUSR | S_IRUGO, + ade7754_read_8bit, + ade7754_write_8bit, + ADE7754_VPEAK); +static IIO_DEV_ATTR_APHCAL(S_IWUSR | S_IRUGO, + ade7754_read_8bit, + ade7754_write_8bit, + ADE7754_APHCAL); +static IIO_DEV_ATTR_BPHCAL(S_IWUSR | S_IRUGO, + ade7754_read_8bit, + ade7754_write_8bit, + ADE7754_BPHCAL); +static IIO_DEV_ATTR_CPHCAL(S_IWUSR | S_IRUGO, + ade7754_read_8bit, + ade7754_write_8bit, + ADE7754_CPHCAL); +static IIO_DEV_ATTR_AAPOS(S_IWUSR | S_IRUGO, + ade7754_read_16bit, + ade7754_write_16bit, + ADE7754_AAPOS); +static IIO_DEV_ATTR_BAPOS(S_IWUSR | S_IRUGO, + ade7754_read_16bit, + ade7754_write_16bit, + ADE7754_BAPOS); +static IIO_DEV_ATTR_CAPOS(S_IWUSR | S_IRUGO, + ade7754_read_16bit, + ade7754_write_16bit, + ADE7754_CAPOS); +static IIO_DEV_ATTR_WDIV(S_IWUSR | S_IRUGO, + ade7754_read_8bit, + ade7754_write_8bit, + ADE7754_WDIV); +static IIO_DEV_ATTR_VADIV(S_IWUSR | S_IRUGO, + ade7754_read_8bit, + ade7754_write_8bit, + ADE7754_VADIV); +static IIO_DEV_ATTR_CFNUM(S_IWUSR | S_IRUGO, + ade7754_read_16bit, + ade7754_write_16bit, + ADE7754_CFNUM); +static IIO_DEV_ATTR_CFDEN(S_IWUSR | S_IRUGO, + ade7754_read_16bit, + ade7754_write_16bit, + ADE7754_CFDEN); +static IIO_DEV_ATTR_ACTIVE_POWER_A_GAIN(S_IWUSR | S_IRUGO, + ade7754_read_16bit, + ade7754_write_16bit, + ADE7754_AAPGAIN); +static IIO_DEV_ATTR_ACTIVE_POWER_B_GAIN(S_IWUSR | S_IRUGO, + ade7754_read_16bit, + ade7754_write_16bit, + ADE7754_BAPGAIN); +static IIO_DEV_ATTR_ACTIVE_POWER_C_GAIN(S_IWUSR | S_IRUGO, + ade7754_read_16bit, + ade7754_write_16bit, + ADE7754_CAPGAIN); +static IIO_DEV_ATTR_AIRMS(S_IRUGO, + ade7754_read_24bit, + NULL, + ADE7754_AIRMS); +static IIO_DEV_ATTR_BIRMS(S_IRUGO, + ade7754_read_24bit, + NULL, + ADE7754_BIRMS); +static IIO_DEV_ATTR_CIRMS(S_IRUGO, + ade7754_read_24bit, + NULL, + ADE7754_CIRMS); +static IIO_DEV_ATTR_AVRMS(S_IRUGO, + ade7754_read_24bit, + NULL, + ADE7754_AVRMS); +static IIO_DEV_ATTR_BVRMS(S_IRUGO, + ade7754_read_24bit, + NULL, + ADE7754_BVRMS); +static IIO_DEV_ATTR_CVRMS(S_IRUGO, + ade7754_read_24bit, + NULL, + ADE7754_CVRMS); +static IIO_DEV_ATTR_AIRMSOS(S_IRUGO, + ade7754_read_16bit, + ade7754_write_16bit, + ADE7754_AIRMSOS); +static IIO_DEV_ATTR_BIRMSOS(S_IRUGO, + ade7754_read_16bit, + ade7754_write_16bit, + ADE7754_BIRMSOS); +static IIO_DEV_ATTR_CIRMSOS(S_IRUGO, + ade7754_read_16bit, + ade7754_write_16bit, + ADE7754_CIRMSOS); +static IIO_DEV_ATTR_AVRMSOS(S_IRUGO, + ade7754_read_16bit, + ade7754_write_16bit, + ADE7754_AVRMSOS); +static IIO_DEV_ATTR_BVRMSOS(S_IRUGO, + ade7754_read_16bit, + ade7754_write_16bit, + ADE7754_BVRMSOS); +static IIO_DEV_ATTR_CVRMSOS(S_IRUGO, + ade7754_read_16bit, + ade7754_write_16bit, + ADE7754_CVRMSOS); + +static int ade7754_set_irq(struct device *dev, bool enable) +{ + int ret; + u16 irqen; + ret = ade7754_spi_read_reg_16(dev, ADE7754_IRQEN, &irqen); + if (ret) + goto error_ret; + + if (enable) + irqen |= 1 << 14; /* Enables an interrupt when a data is + present in the waveform register */ + else + irqen &= ~(1 << 14); + + ret = ade7754_spi_write_reg_16(dev, ADE7754_IRQEN, irqen); + if (ret) + goto error_ret; + +error_ret: + return ret; +} + +/* Power down the device */ +static int ade7754_stop_device(struct device *dev) +{ + int ret; + u8 val; + ade7754_spi_read_reg_8(dev, + ADE7754_OPMODE, + &val); + val |= 7 << 3; /* ADE7754 powered down */ + ret = ade7754_spi_write_reg_8(dev, + ADE7754_OPMODE, + val); + + return ret; +} + +static int ade7754_initial_setup(struct ade7754_state *st) +{ + int ret; + struct device *dev = &st->indio_dev->dev; + + /* use low spi speed for init */ + st->us->mode = SPI_MODE_3; + spi_setup(st->us); + + /* Disable IRQ */ + ret = ade7754_set_irq(dev, false); + if (ret) { + dev_err(dev, "disable irq failed"); + goto err_ret; + } + + ade7754_reset(dev); + msleep(ADE7754_STARTUP_DELAY); + +err_ret: + return ret; +} + +static ssize_t ade7754_read_frequency(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + int ret, len = 0; + u8 t; + int sps; + ret = ade7754_spi_read_reg_8(dev, + ADE7754_WAVMODE, + &t); + if (ret) + return ret; + + t = (t >> 3) & 0x3; + sps = 26000 / (1 + t); + + len = sprintf(buf, "%d SPS\n", sps); + return len; +} + +static ssize_t ade7754_write_frequency(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct ade7754_state *st = iio_dev_get_devdata(indio_dev); + unsigned long val; + int ret; + u8 reg, t; + + ret = strict_strtol(buf, 10, &val); + if (ret) + return ret; + + mutex_lock(&indio_dev->mlock); + + t = (26000 / val); + if (t > 0) + t--; + + if (t > 1) + st->us->max_speed_hz = ADE7754_SPI_SLOW; + else + st->us->max_speed_hz = ADE7754_SPI_FAST; + + ret = ade7754_spi_read_reg_8(dev, + ADE7754_WAVMODE, + ®); + if (ret) + goto out; + + reg &= ~(3 << 3); + reg |= t << 3; + + ret = ade7754_spi_write_reg_8(dev, + ADE7754_WAVMODE, + reg); + +out: + mutex_unlock(&indio_dev->mlock); + + return ret ? ret : len; +} +static IIO_DEV_ATTR_TEMP_RAW(ade7754_read_8bit); +static IIO_CONST_ATTR(temp_offset, "129 C"); +static IIO_CONST_ATTR(temp_scale, "4 C"); + +static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO, + ade7754_read_frequency, + ade7754_write_frequency); + +static IIO_DEV_ATTR_RESET(ade7754_write_reset); + +static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("26000 13000 65000 33000"); + +static IIO_CONST_ATTR(name, "ade7754"); + +static struct attribute *ade7754_event_attributes[] = { + NULL +}; + +static struct attribute_group ade7754_event_attribute_group = { + .attrs = ade7754_event_attributes, +}; + +static struct attribute *ade7754_attributes[] = { + &iio_dev_attr_temp_raw.dev_attr.attr, + &iio_const_attr_temp_offset.dev_attr.attr, + &iio_const_attr_temp_scale.dev_attr.attr, + &iio_dev_attr_sampling_frequency.dev_attr.attr, + &iio_const_attr_sampling_frequency_available.dev_attr.attr, + &iio_dev_attr_reset.dev_attr.attr, + &iio_const_attr_name.dev_attr.attr, + &iio_dev_attr_aenergy.dev_attr.attr, + &iio_dev_attr_laenergy.dev_attr.attr, + &iio_dev_attr_vaenergy.dev_attr.attr, + &iio_dev_attr_lvaenergy.dev_attr.attr, + &iio_dev_attr_vpeak.dev_attr.attr, + &iio_dev_attr_ipeak.dev_attr.attr, + &iio_dev_attr_aphcal.dev_attr.attr, + &iio_dev_attr_bphcal.dev_attr.attr, + &iio_dev_attr_cphcal.dev_attr.attr, + &iio_dev_attr_aapos.dev_attr.attr, + &iio_dev_attr_bapos.dev_attr.attr, + &iio_dev_attr_capos.dev_attr.attr, + &iio_dev_attr_wdiv.dev_attr.attr, + &iio_dev_attr_vadiv.dev_attr.attr, + &iio_dev_attr_cfnum.dev_attr.attr, + &iio_dev_attr_cfden.dev_attr.attr, + &iio_dev_attr_active_power_a_gain.dev_attr.attr, + &iio_dev_attr_active_power_b_gain.dev_attr.attr, + &iio_dev_attr_active_power_c_gain.dev_attr.attr, + &iio_dev_attr_airms.dev_attr.attr, + &iio_dev_attr_birms.dev_attr.attr, + &iio_dev_attr_cirms.dev_attr.attr, + &iio_dev_attr_avrms.dev_attr.attr, + &iio_dev_attr_bvrms.dev_attr.attr, + &iio_dev_attr_cvrms.dev_attr.attr, + &iio_dev_attr_airmsos.dev_attr.attr, + &iio_dev_attr_birmsos.dev_attr.attr, + &iio_dev_attr_cirmsos.dev_attr.attr, + &iio_dev_attr_avrmsos.dev_attr.attr, + &iio_dev_attr_bvrmsos.dev_attr.attr, + &iio_dev_attr_cvrmsos.dev_attr.attr, + NULL, +}; + +static const struct attribute_group ade7754_attribute_group = { + .attrs = ade7754_attributes, +}; + + + +static int __devinit ade7754_probe(struct spi_device *spi) +{ + int ret, regdone = 0; + struct ade7754_state *st = kzalloc(sizeof *st, GFP_KERNEL); + if (!st) { + ret = -ENOMEM; + goto error_ret; + } + /* this is only used for removal purposes */ + spi_set_drvdata(spi, st); + + /* Allocate the comms buffers */ + st->rx = kzalloc(sizeof(*st->rx)*ADE7754_MAX_RX, GFP_KERNEL); + if (st->rx == NULL) { + ret = -ENOMEM; + goto error_free_st; + } + st->tx = kzalloc(sizeof(*st->tx)*ADE7754_MAX_TX, GFP_KERNEL); + if (st->tx == NULL) { + ret = -ENOMEM; + goto error_free_rx; + } + st->us = spi; + mutex_init(&st->buf_lock); + /* setup the industrialio driver allocated elements */ + st->indio_dev = iio_allocate_device(); + if (st->indio_dev == NULL) { + ret = -ENOMEM; + goto error_free_tx; + } + + st->indio_dev->dev.parent = &spi->dev; + st->indio_dev->num_interrupt_lines = 1; + st->indio_dev->event_attrs = &ade7754_event_attribute_group; + st->indio_dev->attrs = &ade7754_attribute_group; + st->indio_dev->dev_data = (void *)(st); + st->indio_dev->driver_module = THIS_MODULE; + st->indio_dev->modes = INDIO_DIRECT_MODE; + + ret = ade7754_configure_ring(st->indio_dev); + if (ret) + goto error_free_dev; + + ret = iio_device_register(st->indio_dev); + if (ret) + goto error_unreg_ring_funcs; + regdone = 1; + + ret = ade7754_initialize_ring(st->indio_dev->ring); + if (ret) { + printk(KERN_ERR "failed to initialize the ring\n"); + goto error_unreg_ring_funcs; + } + + if (spi->irq) { + ret = iio_register_interrupt_line(spi->irq, + st->indio_dev, + 0, + IRQF_TRIGGER_FALLING, + "ade7754"); + if (ret) + goto error_uninitialize_ring; + + ret = ade7754_probe_trigger(st->indio_dev); + if (ret) + goto error_unregister_line; + } + + /* Get the device into a sane initial state */ + ret = ade7754_initial_setup(st); + if (ret) + goto error_remove_trigger; + return 0; + +error_remove_trigger: + if (st->indio_dev->modes & INDIO_RING_TRIGGERED) + ade7754_remove_trigger(st->indio_dev); +error_unregister_line: + if (st->indio_dev->modes & INDIO_RING_TRIGGERED) + iio_unregister_interrupt_line(st->indio_dev, 0); +error_uninitialize_ring: + ade7754_uninitialize_ring(st->indio_dev->ring); +error_unreg_ring_funcs: + ade7754_unconfigure_ring(st->indio_dev); +error_free_dev: + if (regdone) + iio_device_unregister(st->indio_dev); + else + iio_free_device(st->indio_dev); +error_free_tx: + kfree(st->tx); +error_free_rx: + kfree(st->rx); +error_free_st: + kfree(st); +error_ret: + return ret; +} + +/* fixme, confirm ordering in this function */ +static int ade7754_remove(struct spi_device *spi) +{ + int ret; + struct ade7754_state *st = spi_get_drvdata(spi); + struct iio_dev *indio_dev = st->indio_dev; + + ret = ade7754_stop_device(&(indio_dev->dev)); + if (ret) + goto err_ret; + + flush_scheduled_work(); + + ade7754_remove_trigger(indio_dev); + if (spi->irq) + iio_unregister_interrupt_line(indio_dev, 0); + + ade7754_uninitialize_ring(indio_dev->ring); + ade7754_unconfigure_ring(indio_dev); + iio_device_unregister(indio_dev); + kfree(st->tx); + kfree(st->rx); + kfree(st); + + return 0; + +err_ret: + return ret; +} + +static struct spi_driver ade7754_driver = { + .driver = { + .name = "ade7754", + .owner = THIS_MODULE, + }, + .probe = ade7754_probe, + .remove = __devexit_p(ade7754_remove), +}; + +static __init int ade7754_init(void) +{ + return spi_register_driver(&ade7754_driver); +} +module_init(ade7754_init); + +static __exit void ade7754_exit(void) +{ + spi_unregister_driver(&ade7754_driver); +} +module_exit(ade7754_exit); + +MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>"); +MODULE_DESCRIPTION("Analog Devices ADE7754 Polyphase Multifunction Energy Metering IC Driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/staging/iio/meter/ade7754.h b/drivers/staging/iio/meter/ade7754.h new file mode 100644 index 000000000000..f6a3e4b926cf --- /dev/null +++ b/drivers/staging/iio/meter/ade7754.h @@ -0,0 +1,161 @@ +#ifndef _ADE7754_H +#define _ADE7754_H + +#define ADE7754_AENERGY 0x01 +#define ADE7754_RAENERGY 0x02 +#define ADE7754_LAENERGY 0x03 +#define ADE7754_VAENERGY 0x04 +#define ADE7754_RVAENERGY 0x05 +#define ADE7754_LVAENERGY 0x06 +#define ADE7754_PERIOD 0x07 +#define ADE7754_TEMP 0x08 +#define ADE7754_WFORM 0x09 +#define ADE7754_OPMODE 0x0A +#define ADE7754_MMODE 0x0B +#define ADE7754_WAVMODE 0x0C +#define ADE7754_WATMODE 0x0D +#define ADE7754_VAMODE 0x0E +#define ADE7754_IRQEN 0x0F +#define ADE7754_STATUS 0x10 +#define ADE7754_RSTATUS 0x11 +#define ADE7754_ZXTOUT 0x12 +#define ADE7754_LINCYC 0x13 +#define ADE7754_SAGCYC 0x14 +#define ADE7754_SAGLVL 0x15 +#define ADE7754_VPEAK 0x16 +#define ADE7754_IPEAK 0x17 +#define ADE7754_GAIN 0x18 +#define ADE7754_AWG 0x19 +#define ADE7754_BWG 0x1A +#define ADE7754_CWG 0x1B +#define ADE7754_AVAG 0x1C +#define ADE7754_BVAG 0x1D +#define ADE7754_CVAG 0x1E +#define ADE7754_APHCAL 0x1F +#define ADE7754_BPHCAL 0x20 +#define ADE7754_CPHCAL 0x21 +#define ADE7754_AAPOS 0x22 +#define ADE7754_BAPOS 0x23 +#define ADE7754_CAPOS 0x24 +#define ADE7754_CFNUM 0x25 +#define ADE7754_CFDEN 0x26 +#define ADE7754_WDIV 0x27 +#define ADE7754_VADIV 0x28 +#define ADE7754_AIRMS 0x29 +#define ADE7754_BIRMS 0x2A +#define ADE7754_CIRMS 0x2B +#define ADE7754_AVRMS 0x2C +#define ADE7754_BVRMS 0x2D +#define ADE7754_CVRMS 0x2E +#define ADE7754_AIRMSOS 0x2F +#define ADE7754_BIRMSOS 0x30 +#define ADE7754_CIRMSOS 0x31 +#define ADE7754_AVRMSOS 0x32 +#define ADE7754_BVRMSOS 0x33 +#define ADE7754_CVRMSOS 0x34 +#define ADE7754_AAPGAIN 0x35 +#define ADE7754_BAPGAIN 0x36 +#define ADE7754_CAPGAIN 0x37 +#define ADE7754_AVGAIN 0x38 +#define ADE7754_BVGAIN 0x39 +#define ADE7754_CVGAIN 0x3A +#define ADE7754_CHKSUM 0x3E +#define ADE7754_VERSION 0x3F + +#define ADE7754_READ_REG(a) a +#define ADE7754_WRITE_REG(a) ((a) | 0x80) + +#define ADE7754_MAX_TX 4 +#define ADE7754_MAX_RX 4 +#define ADE7754_STARTUP_DELAY 1 + +#define ADE7754_SPI_SLOW (u32)(300 * 1000) +#define ADE7754_SPI_BURST (u32)(1000 * 1000) +#define ADE7754_SPI_FAST (u32)(2000 * 1000) + +#define DRIVER_NAME "ade7754" + +/** + * struct ade7754_state - device instance specific data + * @us: actual spi_device + * @work_trigger_to_ring: bh for triggered event handling + * @inter: used to check if new interrupt has been triggered + * @last_timestamp: passing timestamp from th to bh of interrupt handler + * @indio_dev: industrial I/O device structure + * @trig: data ready trigger registered with iio + * @tx: transmit buffer + * @rx: recieve buffer + * @buf_lock: mutex to protect tx and rx + **/ +struct ade7754_state { + struct spi_device *us; + struct work_struct work_trigger_to_ring; + s64 last_timestamp; + struct iio_dev *indio_dev; + struct iio_trigger *trig; + u8 *tx; + u8 *rx; + struct mutex buf_lock; +}; +#if defined(CONFIG_IIO_RING_BUFFER) && defined(THIS_HAS_RING_BUFFER_SUPPORT) +/* At the moment triggers are only used for ring buffer + * filling. This may change! + */ + +enum ade7754_scan { + ADE7754_SCAN_PHA_V, + ADE7754_SCAN_PHB_V, + ADE7754_SCAN_PHC_V, + ADE7754_SCAN_PHA_I, + ADE7754_SCAN_PHB_I, + ADE7754_SCAN_PHC_I, +}; + +void ade7754_remove_trigger(struct iio_dev *indio_dev); +int ade7754_probe_trigger(struct iio_dev *indio_dev); + +ssize_t ade7754_read_data_from_ring(struct device *dev, + struct device_attribute *attr, + char *buf); + + +int ade7754_configure_ring(struct iio_dev *indio_dev); +void ade7754_unconfigure_ring(struct iio_dev *indio_dev); + +int ade7754_initialize_ring(struct iio_ring_buffer *ring); +void ade7754_uninitialize_ring(struct iio_ring_buffer *ring); +#else /* CONFIG_IIO_RING_BUFFER */ + +static inline void ade7754_remove_trigger(struct iio_dev *indio_dev) +{ +} +static inline int ade7754_probe_trigger(struct iio_dev *indio_dev) +{ + return 0; +} + +static inline ssize_t +ade7754_read_data_from_ring(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + return 0; +} + +static int ade7754_configure_ring(struct iio_dev *indio_dev) +{ + return 0; +} +static inline void ade7754_unconfigure_ring(struct iio_dev *indio_dev) +{ +} +static inline int ade7754_initialize_ring(struct iio_ring_buffer *ring) +{ + return 0; +} +static inline void ade7754_uninitialize_ring(struct iio_ring_buffer *ring) +{ +} +#endif /* CONFIG_IIO_RING_BUFFER */ + +#endif -- cgit v1.2.3 From 8210cfe9bd99fd63fae0b60c40fa793b8454e381 Mon Sep 17 00:00:00 2001 From: Barry Song Date: Wed, 27 Oct 2010 21:44:16 -0400 Subject: staging: iio: meter: new driver for ADE7758 devices Signed-off-by: Barry Song Signed-off-by: Michael Hennerich Acked-by: Jonathan Cameron Signed-off-by: Mike Frysinger Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/meter/Kconfig | 9 + drivers/staging/iio/meter/Makefile | 4 + drivers/staging/iio/meter/ade7758.h | 171 ++++++ drivers/staging/iio/meter/ade7758_core.c | 866 ++++++++++++++++++++++++++++ drivers/staging/iio/meter/ade7758_ring.c | 212 +++++++ drivers/staging/iio/meter/ade7758_trigger.c | 125 ++++ 6 files changed, 1387 insertions(+) create mode 100644 drivers/staging/iio/meter/ade7758.h create mode 100644 drivers/staging/iio/meter/ade7758_core.c create mode 100644 drivers/staging/iio/meter/ade7758_ring.c create mode 100644 drivers/staging/iio/meter/ade7758_trigger.c diff --git a/drivers/staging/iio/meter/Kconfig b/drivers/staging/iio/meter/Kconfig index 19f20f4ad52c..be88bb81b7dc 100644 --- a/drivers/staging/iio/meter/Kconfig +++ b/drivers/staging/iio/meter/Kconfig @@ -16,3 +16,12 @@ config ADE7754 help Say yes here to build support for Analog Devices ADE7754 Polyphase Multifunction Energy Metering IC Driver. + +config ADE7758 + tristate "Analog Devices ADE7758 Poly Phase Multifunction Energy Metering IC Driver" + depends on SPI + select IIO_TRIGGER if IIO_RING_BUFFER + select IIO_SW_RING if IIO_RING_BUFFER + help + Say yes here to build support for Analog Devices ADE7758 Polyphase + Multifunction Energy Metering IC with Per Phase Information Driver. diff --git a/drivers/staging/iio/meter/Makefile b/drivers/staging/iio/meter/Makefile index 7f65b991eb15..8e1a71d249c3 100644 --- a/drivers/staging/iio/meter/Makefile +++ b/drivers/staging/iio/meter/Makefile @@ -4,3 +4,7 @@ obj-$(CONFIG_ADE7753) += ade7753.o obj-$(CONFIG_ADE7754) += ade7754.o + +ade7758-y := ade7758_core.o +ade7758-$(CONFIG_IIO_RING_BUFFER) += ade7758_ring.o ade7758_trigger.o +obj-$(CONFIG_ADE7758) += ade7758.o diff --git a/drivers/staging/iio/meter/ade7758.h b/drivers/staging/iio/meter/ade7758.h new file mode 100644 index 000000000000..df5bb7ba5a0f --- /dev/null +++ b/drivers/staging/iio/meter/ade7758.h @@ -0,0 +1,171 @@ +#ifndef _ADE7758_H +#define _ADE7758_H + +#define ADE7758_AWATTHR 0x01 +#define ADE7758_BWATTHR 0x02 +#define ADE7758_CWATTHR 0x03 +#define ADE7758_AVARHR 0x04 +#define ADE7758_BVARHR 0x05 +#define ADE7758_CVARHR 0x06 +#define ADE7758_AVAHR 0x07 +#define ADE7758_BVAHR 0x08 +#define ADE7758_CVAHR 0x09 +#define ADE7758_AIRMS 0x0A +#define ADE7758_BIRMS 0x0B +#define ADE7758_CIRMS 0x0C +#define ADE7758_AVRMS 0x0D +#define ADE7758_BVRMS 0x0E +#define ADE7758_CVRMS 0x0F +#define ADE7758_FREQ 0x10 +#define ADE7758_TEMP 0x11 +#define ADE7758_WFORM 0x12 +#define ADE7758_OPMODE 0x13 +#define ADE7758_MMODE 0x14 +#define ADE7758_WAVMODE 0x15 +#define ADE7758_COMPMODE 0x16 +#define ADE7758_LCYCMODE 0x17 +#define ADE7758_MASK 0x18 +#define ADE7758_STATUS 0x19 +#define ADE7758_RSTATUS 0x1A +#define ADE7758_ZXTOUT 0x1B +#define ADE7758_LINECYC 0x1C +#define ADE7758_SAGCYC 0x1D +#define ADE7758_SAGLVL 0x1E +#define ADE7758_VPINTLVL 0x1F +#define ADE7758_IPINTLVL 0x20 +#define ADE7758_VPEAK 0x21 +#define ADE7758_IPEAK 0x22 +#define ADE7758_GAIN 0x23 +#define ADE7758_AVRMSGAIN 0x24 +#define ADE7758_BVRMSGAIN 0x25 +#define ADE7758_CVRMSGAIN 0x26 +#define ADE7758_AIGAIN 0x27 +#define ADE7758_BIGAIN 0x28 +#define ADE7758_CIGAIN 0x29 +#define ADE7758_AWG 0x2A +#define ADE7758_BWG 0x2B +#define ADE7758_CWG 0x2C +#define ADE7758_AVARG 0x2D +#define ADE7758_BVARG 0x2E +#define ADE7758_CVARG 0x2F +#define ADE7758_AVAG 0x30 +#define ADE7758_BVAG 0x31 +#define ADE7758_CVAG 0x32 +#define ADE7758_AVRMSOS 0x33 +#define ADE7758_BVRMSOS 0x34 +#define ADE7758_CVRMSOS 0x35 +#define ADE7758_AIRMSOS 0x36 +#define ADE7758_BIRMSOS 0x37 +#define ADE7758_CIRMSOS 0x38 +#define ADE7758_AWAITOS 0x39 +#define ADE7758_BWAITOS 0x3A +#define ADE7758_CWAITOS 0x3B +#define ADE7758_AVAROS 0x3C +#define ADE7758_BVAROS 0x3D +#define ADE7758_CVAROS 0x3E +#define ADE7758_APHCAL 0x3F +#define ADE7758_BPHCAL 0x40 +#define ADE7758_CPHCAL 0x41 +#define ADE7758_WDIV 0x42 +#define ADE7758_VADIV 0x44 +#define ADE7758_VARDIV 0x43 +#define ADE7758_APCFNUM 0x45 +#define ADE7758_APCFDEN 0x46 +#define ADE7758_VARCFNUM 0x47 +#define ADE7758_VARCFDEN 0x48 +#define ADE7758_CHKSUM 0x7E +#define ADE7758_VERSION 0x7F + +#define ADE7758_READ_REG(a) a +#define ADE7758_WRITE_REG(a) ((a) | 0x80) + +#define ADE7758_MAX_TX 8 +#define ADE7758_MAX_RX 4 +#define ADE7758_STARTUP_DELAY 1 + +#define ADE7758_SPI_SLOW (u32)(300 * 1000) +#define ADE7758_SPI_BURST (u32)(1000 * 1000) +#define ADE7758_SPI_FAST (u32)(2000 * 1000) + +#define DRIVER_NAME "ade7758" + +/** + * struct ade7758_state - device instance specific data + * @us: actual spi_device + * @work_trigger_to_ring: bh for triggered event handling + * @inter: used to check if new interrupt has been triggered + * @last_timestamp: passing timestamp from th to bh of interrupt handler + * @indio_dev: industrial I/O device structure + * @trig: data ready trigger registered with iio + * @tx: transmit buffer + * @rx: recieve buffer + * @buf_lock: mutex to protect tx and rx + **/ +struct ade7758_state { + struct spi_device *us; + struct work_struct work_trigger_to_ring; + s64 last_timestamp; + struct iio_dev *indio_dev; + struct iio_trigger *trig; + u8 *tx; + u8 *rx; + struct mutex buf_lock; +}; +#ifdef CONFIG_IIO_RING_BUFFER +/* At the moment triggers are only used for ring buffer + * filling. This may change! + */ + +enum ade7758_scan { + ADE7758_SCAN_WFORM, +}; + +void ade7758_remove_trigger(struct iio_dev *indio_dev); +int ade7758_probe_trigger(struct iio_dev *indio_dev); + +ssize_t ade7758_read_data_from_ring(struct device *dev, + struct device_attribute *attr, + char *buf); + + +int ade7758_configure_ring(struct iio_dev *indio_dev); +void ade7758_unconfigure_ring(struct iio_dev *indio_dev); + +int ade7758_initialize_ring(struct iio_ring_buffer *ring); +void ade7758_uninitialize_ring(struct iio_ring_buffer *ring); +int ade7758_set_irq(struct device *dev, bool enable); +#else /* CONFIG_IIO_RING_BUFFER */ + +static inline void ade7758_remove_trigger(struct iio_dev *indio_dev) +{ +} +static inline int ade7758_probe_trigger(struct iio_dev *indio_dev) +{ + return 0; +} + +static inline ssize_t +ade7758_read_data_from_ring(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + return 0; +} + +static int ade7758_configure_ring(struct iio_dev *indio_dev) +{ + return 0; +} +static inline void ade7758_unconfigure_ring(struct iio_dev *indio_dev) +{ +} +static inline int ade7758_initialize_ring(struct iio_ring_buffer *ring) +{ + return 0; +} +static inline void ade7758_uninitialize_ring(struct iio_ring_buffer *ring) +{ +} +#endif /* CONFIG_IIO_RING_BUFFER */ + +#endif diff --git a/drivers/staging/iio/meter/ade7758_core.c b/drivers/staging/iio/meter/ade7758_core.c new file mode 100644 index 000000000000..b7634cb7aa4f --- /dev/null +++ b/drivers/staging/iio/meter/ade7758_core.c @@ -0,0 +1,866 @@ +/* + * ADE7758 Polyphase Multifunction Energy Metering IC Driver + * + * Copyright 2010 Analog Devices Inc. + * + * Licensed under the GPL-2 or later. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../iio.h" +#include "../sysfs.h" +#include "meter.h" +#include "ade7758.h" + +int ade7758_spi_write_reg_8(struct device *dev, + u8 reg_address, + u8 val) +{ + int ret; + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct ade7758_state *st = iio_dev_get_devdata(indio_dev); + + mutex_lock(&st->buf_lock); + st->tx[0] = ADE7758_WRITE_REG(reg_address); + st->tx[1] = val; + + ret = spi_write(st->us, st->tx, 2); + mutex_unlock(&st->buf_lock); + + return ret; +} + +static int ade7758_spi_write_reg_16(struct device *dev, + u8 reg_address, + u16 value) +{ + int ret; + struct spi_message msg; + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct ade7758_state *st = iio_dev_get_devdata(indio_dev); + struct spi_transfer xfers[] = { + { + .tx_buf = st->tx, + .bits_per_word = 8, + .len = 3, + } + }; + + mutex_lock(&st->buf_lock); + st->tx[0] = ADE7758_WRITE_REG(reg_address); + st->tx[1] = (value >> 8) & 0xFF; + st->tx[2] = value & 0xFF; + + spi_message_init(&msg); + spi_message_add_tail(xfers, &msg); + ret = spi_sync(st->us, &msg); + mutex_unlock(&st->buf_lock); + + return ret; +} + +static int ade7758_spi_write_reg_24(struct device *dev, + u8 reg_address, + u32 value) +{ + int ret; + struct spi_message msg; + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct ade7758_state *st = iio_dev_get_devdata(indio_dev); + struct spi_transfer xfers[] = { + { + .tx_buf = st->tx, + .bits_per_word = 8, + .len = 4, + } + }; + + mutex_lock(&st->buf_lock); + st->tx[0] = ADE7758_WRITE_REG(reg_address); + st->tx[1] = (value >> 16) & 0xFF; + st->tx[2] = (value >> 8) & 0xFF; + st->tx[3] = value & 0xFF; + + spi_message_init(&msg); + spi_message_add_tail(xfers, &msg); + ret = spi_sync(st->us, &msg); + mutex_unlock(&st->buf_lock); + + return ret; +} + +static int ade7758_spi_read_reg_8(struct device *dev, + u8 reg_address, + u8 *val) +{ + struct spi_message msg; + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct ade7758_state *st = iio_dev_get_devdata(indio_dev); + int ret; + struct spi_transfer xfers[] = { + { + .tx_buf = st->tx, + .rx_buf = st->rx, + .bits_per_word = 8, + .len = 2, + }, + }; + + mutex_lock(&st->buf_lock); + st->tx[0] = ADE7758_READ_REG(reg_address); + st->tx[1] = 0; + + spi_message_init(&msg); + spi_message_add_tail(xfers, &msg); + ret = spi_sync(st->us, &msg); + if (ret) { + dev_err(&st->us->dev, "problem when reading 8 bit register 0x%02X", + reg_address); + goto error_ret; + } + *val = st->rx[1]; + +error_ret: + mutex_unlock(&st->buf_lock); + return ret; +} + +static int ade7758_spi_read_reg_16(struct device *dev, + u8 reg_address, + u16 *val) +{ + struct spi_message msg; + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct ade7758_state *st = iio_dev_get_devdata(indio_dev); + int ret; + struct spi_transfer xfers[] = { + { + .tx_buf = st->tx, + .rx_buf = st->rx, + .bits_per_word = 8, + .len = 3, + }, + }; + + mutex_lock(&st->buf_lock); + st->tx[0] = ADE7758_READ_REG(reg_address); + st->tx[1] = 0; + st->tx[2] = 0; + + spi_message_init(&msg); + spi_message_add_tail(xfers, &msg); + ret = spi_sync(st->us, &msg); + if (ret) { + dev_err(&st->us->dev, "problem when reading 16 bit register 0x%02X", + reg_address); + goto error_ret; + } + *val = (st->rx[1] << 8) | st->rx[2]; + +error_ret: + mutex_unlock(&st->buf_lock); + return ret; +} + +static int ade7758_spi_read_reg_24(struct device *dev, + u8 reg_address, + u32 *val) +{ + struct spi_message msg; + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct ade7758_state *st = iio_dev_get_devdata(indio_dev); + int ret; + struct spi_transfer xfers[] = { + { + .tx_buf = st->tx, + .rx_buf = st->rx, + .bits_per_word = 8, + .len = 4, + }, + }; + + mutex_lock(&st->buf_lock); + st->tx[0] = ADE7758_READ_REG(reg_address); + st->tx[1] = 0; + st->tx[2] = 0; + st->tx[3] = 0; + + spi_message_init(&msg); + spi_message_add_tail(xfers, &msg); + ret = spi_sync(st->us, &msg); + if (ret) { + dev_err(&st->us->dev, "problem when reading 24 bit register 0x%02X", + reg_address); + goto error_ret; + } + *val = (st->rx[1] << 16) | (st->rx[2] << 8) | st->rx[3]; + +error_ret: + mutex_unlock(&st->buf_lock); + return ret; +} + +static ssize_t ade7758_read_8bit(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + int ret; + u8 val = 0; + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + + ret = ade7758_spi_read_reg_8(dev, this_attr->address, &val); + if (ret) + return ret; + + return sprintf(buf, "%u\n", val); +} + +static ssize_t ade7758_read_16bit(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + int ret; + u16 val = 0; + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + + ret = ade7758_spi_read_reg_16(dev, this_attr->address, &val); + if (ret) + return ret; + + return sprintf(buf, "%u\n", val); +} + +static ssize_t ade7758_read_24bit(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + int ret; + u32 val = 0; + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + + ret = ade7758_spi_read_reg_24(dev, this_attr->address, &val); + if (ret) + return ret; + + return sprintf(buf, "%u\n", val & 0xFFFFFF); +} + +static ssize_t ade7758_write_8bit(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + int ret; + long val; + + ret = strict_strtol(buf, 10, &val); + if (ret) + goto error_ret; + ret = ade7758_spi_write_reg_8(dev, this_attr->address, val); + +error_ret: + return ret ? ret : len; +} + +static ssize_t ade7758_write_16bit(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + int ret; + long val; + + ret = strict_strtol(buf, 10, &val); + if (ret) + goto error_ret; + ret = ade7758_spi_write_reg_16(dev, this_attr->address, val); + +error_ret: + return ret ? ret : len; +} + +int ade7758_reset(struct device *dev) +{ + int ret; + u8 val; + ade7758_spi_read_reg_8(dev, + ADE7758_OPMODE, + &val); + val |= 1 << 6; /* Software Chip Reset */ + ret = ade7758_spi_write_reg_8(dev, + ADE7758_OPMODE, + val); + + return ret; +} + +static ssize_t ade7758_write_reset(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t len) +{ + if (len < 1) + return -1; + switch (buf[0]) { + case '1': + case 'y': + case 'Y': + return ade7758_reset(dev); + } + return -1; +} + +static IIO_DEV_ATTR_VPEAK(S_IWUSR | S_IRUGO, + ade7758_read_8bit, + ade7758_write_8bit, + ADE7758_VPEAK); +static IIO_DEV_ATTR_IPEAK(S_IWUSR | S_IRUGO, + ade7758_read_8bit, + ade7758_write_8bit, + ADE7758_VPEAK); +static IIO_DEV_ATTR_APHCAL(S_IWUSR | S_IRUGO, + ade7758_read_8bit, + ade7758_write_8bit, + ADE7758_APHCAL); +static IIO_DEV_ATTR_BPHCAL(S_IWUSR | S_IRUGO, + ade7758_read_8bit, + ade7758_write_8bit, + ADE7758_BPHCAL); +static IIO_DEV_ATTR_CPHCAL(S_IWUSR | S_IRUGO, + ade7758_read_8bit, + ade7758_write_8bit, + ADE7758_CPHCAL); +static IIO_DEV_ATTR_WDIV(S_IWUSR | S_IRUGO, + ade7758_read_8bit, + ade7758_write_8bit, + ADE7758_WDIV); +static IIO_DEV_ATTR_VADIV(S_IWUSR | S_IRUGO, + ade7758_read_8bit, + ade7758_write_8bit, + ADE7758_VADIV); +static IIO_DEV_ATTR_AIRMS(S_IRUGO, + ade7758_read_24bit, + NULL, + ADE7758_AIRMS); +static IIO_DEV_ATTR_BIRMS(S_IRUGO, + ade7758_read_24bit, + NULL, + ADE7758_BIRMS); +static IIO_DEV_ATTR_CIRMS(S_IRUGO, + ade7758_read_24bit, + NULL, + ADE7758_CIRMS); +static IIO_DEV_ATTR_AVRMS(S_IRUGO, + ade7758_read_24bit, + NULL, + ADE7758_AVRMS); +static IIO_DEV_ATTR_BVRMS(S_IRUGO, + ade7758_read_24bit, + NULL, + ADE7758_BVRMS); +static IIO_DEV_ATTR_CVRMS(S_IRUGO, + ade7758_read_24bit, + NULL, + ADE7758_CVRMS); +static IIO_DEV_ATTR_AIRMSOS(S_IWUSR | S_IRUGO, + ade7758_read_16bit, + ade7758_write_16bit, + ADE7758_AIRMSOS); +static IIO_DEV_ATTR_BIRMSOS(S_IWUSR | S_IRUGO, + ade7758_read_16bit, + ade7758_write_16bit, + ADE7758_BIRMSOS); +static IIO_DEV_ATTR_CIRMSOS(S_IWUSR | S_IRUGO, + ade7758_read_16bit, + ade7758_write_16bit, + ADE7758_CIRMSOS); +static IIO_DEV_ATTR_AVRMSOS(S_IWUSR | S_IRUGO, + ade7758_read_16bit, + ade7758_write_16bit, + ADE7758_AVRMSOS); +static IIO_DEV_ATTR_BVRMSOS(S_IWUSR | S_IRUGO, + ade7758_read_16bit, + ade7758_write_16bit, + ADE7758_BVRMSOS); +static IIO_DEV_ATTR_CVRMSOS(S_IWUSR | S_IRUGO, + ade7758_read_16bit, + ade7758_write_16bit, + ADE7758_CVRMSOS); +static IIO_DEV_ATTR_AIGAIN(S_IWUSR | S_IRUGO, + ade7758_read_16bit, + ade7758_write_16bit, + ADE7758_AIGAIN); +static IIO_DEV_ATTR_BIGAIN(S_IWUSR | S_IRUGO, + ade7758_read_16bit, + ade7758_write_16bit, + ADE7758_BIGAIN); +static IIO_DEV_ATTR_CIGAIN(S_IWUSR | S_IRUGO, + ade7758_read_16bit, + ade7758_write_16bit, + ADE7758_CIGAIN); +static IIO_DEV_ATTR_AVRMSGAIN(S_IWUSR | S_IRUGO, + ade7758_read_16bit, + ade7758_write_16bit, + ADE7758_AVRMSGAIN); +static IIO_DEV_ATTR_BVRMSGAIN(S_IWUSR | S_IRUGO, + ade7758_read_16bit, + ade7758_write_16bit, + ADE7758_BVRMSGAIN); +static IIO_DEV_ATTR_CVRMSGAIN(S_IWUSR | S_IRUGO, + ade7758_read_16bit, + ade7758_write_16bit, + ADE7758_CVRMSGAIN); + +int ade7758_set_irq(struct device *dev, bool enable) +{ + int ret; + u32 irqen; + ret = ade7758_spi_read_reg_24(dev, ADE7758_MASK, &irqen); + if (ret) + goto error_ret; + + if (enable) + irqen |= 1 << 16; /* Enables an interrupt when a data is + present in the waveform register */ + else + irqen &= ~(1 << 16); + + ret = ade7758_spi_write_reg_24(dev, ADE7758_MASK, irqen); + if (ret) + goto error_ret; + +error_ret: + return ret; +} + +/* Power down the device */ +static int ade7758_stop_device(struct device *dev) +{ + int ret; + u8 val; + ade7758_spi_read_reg_8(dev, + ADE7758_OPMODE, + &val); + val |= 7 << 3; /* ADE7758 powered down */ + ret = ade7758_spi_write_reg_8(dev, + ADE7758_OPMODE, + val); + + return ret; +} + +static int ade7758_initial_setup(struct ade7758_state *st) +{ + int ret; + struct device *dev = &st->indio_dev->dev; + + /* use low spi speed for init */ + st->us->mode = SPI_MODE_3; + spi_setup(st->us); + + /* Disable IRQ */ + ret = ade7758_set_irq(dev, false); + if (ret) { + dev_err(dev, "disable irq failed"); + goto err_ret; + } + + ade7758_reset(dev); + msleep(ADE7758_STARTUP_DELAY); + +err_ret: + return ret; +} + +static ssize_t ade7758_read_frequency(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + int ret, len = 0; + u8 t; + int sps; + ret = ade7758_spi_read_reg_8(dev, + ADE7758_WAVMODE, + &t); + if (ret) + return ret; + + t = (t >> 5) & 0x3; + sps = 26040 / (1 << t); + + len = sprintf(buf, "%d SPS\n", sps); + return len; +} + +static ssize_t ade7758_write_frequency(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct ade7758_state *st = iio_dev_get_devdata(indio_dev); + unsigned long val; + int ret; + u8 reg, t; + + ret = strict_strtol(buf, 10, &val); + if (ret) + return ret; + + mutex_lock(&indio_dev->mlock); + + t = (26040 / val); + if (t > 0) + t >>= 1; + + if (t > 1) + st->us->max_speed_hz = ADE7758_SPI_SLOW; + else + st->us->max_speed_hz = ADE7758_SPI_FAST; + + ret = ade7758_spi_read_reg_8(dev, + ADE7758_WAVMODE, + ®); + if (ret) + goto out; + + reg &= ~(5 << 3); + reg |= t << 5; + + ret = ade7758_spi_write_reg_8(dev, + ADE7758_WAVMODE, + reg); + +out: + mutex_unlock(&indio_dev->mlock); + + return ret ? ret : len; +} + +static ssize_t ade7758_read_waveform_type(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + int ret, len = 0; + u8 t; + ret = ade7758_spi_read_reg_8(dev, + ADE7758_WAVMODE, + &t); + if (ret) + return ret; + + t = (t >> 2) & 0x7; + + len = sprintf(buf, "%d\n", t); + + return len; +} + +static ssize_t ade7758_write_waveform_type(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + unsigned long val; + int ret; + u8 reg; + + ret = strict_strtol(buf, 10, &val); + if (ret) + return ret; + + if (val > 4) + return -EINVAL; + + mutex_lock(&indio_dev->mlock); + + ret = ade7758_spi_read_reg_8(dev, + ADE7758_WAVMODE, + ®); + if (ret) + goto out; + + reg &= ~(7 << 2); + reg |= val << 2; + + ret = ade7758_spi_write_reg_8(dev, + ADE7758_WAVMODE, + reg); + +out: + mutex_unlock(&indio_dev->mlock); + + return ret ? ret : len; +} + +static IIO_DEV_ATTR_TEMP_RAW(ade7758_read_8bit); +static IIO_CONST_ATTR(temp_offset, "129 C"); +static IIO_CONST_ATTR(temp_scale, "4 C"); + +static IIO_DEV_ATTR_AWATTHR(ade7758_read_16bit, + ADE7758_AWATTHR); +static IIO_DEV_ATTR_BWATTHR(ade7758_read_16bit, + ADE7758_BWATTHR); +static IIO_DEV_ATTR_CWATTHR(ade7758_read_16bit, + ADE7758_CWATTHR); +static IIO_DEV_ATTR_AVARHR(ade7758_read_16bit, + ADE7758_AVARHR); +static IIO_DEV_ATTR_BVARHR(ade7758_read_16bit, + ADE7758_BVARHR); +static IIO_DEV_ATTR_CVARHR(ade7758_read_16bit, + ADE7758_CVARHR); +static IIO_DEV_ATTR_AVAHR(ade7758_read_16bit, + ADE7758_AVAHR); +static IIO_DEV_ATTR_BVAHR(ade7758_read_16bit, + ADE7758_BVAHR); +static IIO_DEV_ATTR_CVAHR(ade7758_read_16bit, + ADE7758_CVAHR); + +static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO, + ade7758_read_frequency, + ade7758_write_frequency); + +/** + * IIO_DEV_ATTR_WAVEFORM_TYPE - set the type of waveform. + * @_mode: sysfs file mode/permissions + * @_show: output method for the attribute + * @_store: input method for the attribute + **/ +#define IIO_DEV_ATTR_WAVEFORM_TYPE(_mode, _show, _store) \ + IIO_DEVICE_ATTR(waveform_type, _mode, _show, _store, 0) + +static IIO_DEV_ATTR_WAVEFORM_TYPE(S_IWUSR | S_IRUGO, + ade7758_read_waveform_type, + ade7758_write_waveform_type); + +static IIO_DEV_ATTR_RESET(ade7758_write_reset); + +static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("26000 13000 65000 33000"); + +static IIO_CONST_ATTR(name, "ade7758"); + +static struct attribute *ade7758_event_attributes[] = { + NULL +}; + +static struct attribute_group ade7758_event_attribute_group = { + .attrs = ade7758_event_attributes, +}; + +static struct attribute *ade7758_attributes[] = { + &iio_dev_attr_temp_raw.dev_attr.attr, + &iio_const_attr_temp_offset.dev_attr.attr, + &iio_const_attr_temp_scale.dev_attr.attr, + &iio_dev_attr_sampling_frequency.dev_attr.attr, + &iio_dev_attr_waveform_type.dev_attr.attr, + &iio_const_attr_sampling_frequency_available.dev_attr.attr, + &iio_dev_attr_reset.dev_attr.attr, + &iio_const_attr_name.dev_attr.attr, + &iio_dev_attr_awatthr.dev_attr.attr, + &iio_dev_attr_bwatthr.dev_attr.attr, + &iio_dev_attr_cwatthr.dev_attr.attr, + &iio_dev_attr_avarhr.dev_attr.attr, + &iio_dev_attr_bvarhr.dev_attr.attr, + &iio_dev_attr_cvarhr.dev_attr.attr, + &iio_dev_attr_avahr.dev_attr.attr, + &iio_dev_attr_bvahr.dev_attr.attr, + &iio_dev_attr_cvahr.dev_attr.attr, + &iio_dev_attr_vpeak.dev_attr.attr, + &iio_dev_attr_ipeak.dev_attr.attr, + &iio_dev_attr_aphcal.dev_attr.attr, + &iio_dev_attr_bphcal.dev_attr.attr, + &iio_dev_attr_cphcal.dev_attr.attr, + &iio_dev_attr_wdiv.dev_attr.attr, + &iio_dev_attr_vadiv.dev_attr.attr, + &iio_dev_attr_airms.dev_attr.attr, + &iio_dev_attr_birms.dev_attr.attr, + &iio_dev_attr_cirms.dev_attr.attr, + &iio_dev_attr_avrms.dev_attr.attr, + &iio_dev_attr_bvrms.dev_attr.attr, + &iio_dev_attr_cvrms.dev_attr.attr, + &iio_dev_attr_aigain.dev_attr.attr, + &iio_dev_attr_bigain.dev_attr.attr, + &iio_dev_attr_cigain.dev_attr.attr, + &iio_dev_attr_avrmsgain.dev_attr.attr, + &iio_dev_attr_bvrmsgain.dev_attr.attr, + &iio_dev_attr_cvrmsgain.dev_attr.attr, + &iio_dev_attr_airmsos.dev_attr.attr, + &iio_dev_attr_birmsos.dev_attr.attr, + &iio_dev_attr_cirmsos.dev_attr.attr, + &iio_dev_attr_avrmsos.dev_attr.attr, + &iio_dev_attr_bvrmsos.dev_attr.attr, + &iio_dev_attr_cvrmsos.dev_attr.attr, + NULL, +}; + +static const struct attribute_group ade7758_attribute_group = { + .attrs = ade7758_attributes, +}; + + + +static int __devinit ade7758_probe(struct spi_device *spi) +{ + int ret, regdone = 0; + struct ade7758_state *st = kzalloc(sizeof *st, GFP_KERNEL); + if (!st) { + ret = -ENOMEM; + goto error_ret; + } + /* this is only used for removal purposes */ + spi_set_drvdata(spi, st); + + /* Allocate the comms buffers */ + st->rx = kzalloc(sizeof(*st->rx)*ADE7758_MAX_RX, GFP_KERNEL); + if (st->rx == NULL) { + ret = -ENOMEM; + goto error_free_st; + } + st->tx = kzalloc(sizeof(*st->tx)*ADE7758_MAX_TX, GFP_KERNEL); + if (st->tx == NULL) { + ret = -ENOMEM; + goto error_free_rx; + } + st->us = spi; + mutex_init(&st->buf_lock); + /* setup the industrialio driver allocated elements */ + st->indio_dev = iio_allocate_device(); + if (st->indio_dev == NULL) { + ret = -ENOMEM; + goto error_free_tx; + } + + st->indio_dev->dev.parent = &spi->dev; + st->indio_dev->num_interrupt_lines = 1; + st->indio_dev->event_attrs = &ade7758_event_attribute_group; + st->indio_dev->attrs = &ade7758_attribute_group; + st->indio_dev->dev_data = (void *)(st); + st->indio_dev->driver_module = THIS_MODULE; + st->indio_dev->modes = INDIO_DIRECT_MODE; + + ret = ade7758_configure_ring(st->indio_dev); + if (ret) + goto error_free_dev; + + ret = iio_device_register(st->indio_dev); + if (ret) + goto error_unreg_ring_funcs; + regdone = 1; + + ret = ade7758_initialize_ring(st->indio_dev->ring); + if (ret) { + printk(KERN_ERR "failed to initialize the ring\n"); + goto error_unreg_ring_funcs; + } + + if (spi->irq) { + ret = iio_register_interrupt_line(spi->irq, + st->indio_dev, + 0, + IRQF_TRIGGER_FALLING, + "ade7758"); + if (ret) + goto error_uninitialize_ring; + + ret = ade7758_probe_trigger(st->indio_dev); + if (ret) + goto error_unregister_line; + } + + /* Get the device into a sane initial state */ + ret = ade7758_initial_setup(st); + if (ret) + goto error_remove_trigger; + return 0; + +error_remove_trigger: + if (st->indio_dev->modes & INDIO_RING_TRIGGERED) + ade7758_remove_trigger(st->indio_dev); +error_unregister_line: + if (st->indio_dev->modes & INDIO_RING_TRIGGERED) + iio_unregister_interrupt_line(st->indio_dev, 0); +error_uninitialize_ring: + ade7758_uninitialize_ring(st->indio_dev->ring); +error_unreg_ring_funcs: + ade7758_unconfigure_ring(st->indio_dev); +error_free_dev: + if (regdone) + iio_device_unregister(st->indio_dev); + else + iio_free_device(st->indio_dev); +error_free_tx: + kfree(st->tx); +error_free_rx: + kfree(st->rx); +error_free_st: + kfree(st); +error_ret: + return ret; +} + +static int ade7758_remove(struct spi_device *spi) +{ + int ret; + struct ade7758_state *st = spi_get_drvdata(spi); + struct iio_dev *indio_dev = st->indio_dev; + + ret = ade7758_stop_device(&(indio_dev->dev)); + if (ret) + goto err_ret; + + flush_scheduled_work(); + + ade7758_remove_trigger(indio_dev); + if (spi->irq && gpio_is_valid(irq_to_gpio(spi->irq)) > 0) + iio_unregister_interrupt_line(indio_dev, 0); + + ade7758_uninitialize_ring(indio_dev->ring); + iio_device_unregister(indio_dev); + ade7758_unconfigure_ring(indio_dev); + kfree(st->tx); + kfree(st->rx); + kfree(st); + + return 0; + +err_ret: + return ret; +} + +static struct spi_driver ade7758_driver = { + .driver = { + .name = "ade7758", + .owner = THIS_MODULE, + }, + .probe = ade7758_probe, + .remove = __devexit_p(ade7758_remove), +}; + +static __init int ade7758_init(void) +{ + return spi_register_driver(&ade7758_driver); +} +module_init(ade7758_init); + +static __exit void ade7758_exit(void) +{ + spi_unregister_driver(&ade7758_driver); +} +module_exit(ade7758_exit); + +MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>"); +MODULE_DESCRIPTION("Analog Devices ADE7758 Polyphase Multifunction Energy Metering IC Driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/staging/iio/meter/ade7758_ring.c b/drivers/staging/iio/meter/ade7758_ring.c new file mode 100644 index 000000000000..274b4a07808c --- /dev/null +++ b/drivers/staging/iio/meter/ade7758_ring.c @@ -0,0 +1,212 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../iio.h" +#include "../sysfs.h" +#include "../ring_sw.h" +#include "../accel/accel.h" +#include "../trigger.h" +#include "ade7758.h" + +/** + * combine_8_to_32() utility function to munge to u8s into u32 + **/ +static inline u32 combine_8_to_32(u8 lower, u8 mid, u8 upper) +{ + u32 _lower = lower; + u32 _mid = mid; + u32 _upper = upper; + + return _lower | (_mid << 8) | (_upper << 16); +} + +static IIO_SCAN_EL_C(wform, ADE7758_SCAN_WFORM, ADE7758_WFORM, NULL); +static IIO_CONST_ATTR_SCAN_EL_TYPE(wform, s, 24, 32); +static IIO_SCAN_EL_TIMESTAMP(1); +static IIO_CONST_ATTR_SCAN_EL_TYPE(timestamp, s, 64, 64); + +static struct attribute *ade7758_scan_el_attrs[] = { + &iio_scan_el_wform.dev_attr.attr, + &iio_const_attr_wform_index.dev_attr.attr, + &iio_const_attr_wform_type.dev_attr.attr, + &iio_scan_el_timestamp.dev_attr.attr, + &iio_const_attr_timestamp_index.dev_attr.attr, + &iio_const_attr_timestamp_type.dev_attr.attr, + NULL, +}; + +static struct attribute_group ade7758_scan_el_group = { + .attrs = ade7758_scan_el_attrs, + .name = "scan_elements", +}; + +/** + * ade7758_poll_func_th() top half interrupt handler called by trigger + * @private_data: iio_dev + **/ +static void ade7758_poll_func_th(struct iio_dev *indio_dev, s64 time) +{ + struct ade7758_state *st = iio_dev_get_devdata(indio_dev); + st->last_timestamp = time; + schedule_work(&st->work_trigger_to_ring); + /* Indicate that this interrupt is being handled */ + + /* Technically this is trigger related, but without this + * handler running there is currently no way for the interrupt + * to clear. + */ +} + +/** + * ade7758_spi_read_burst() - read all data registers + * @dev: device associated with child of actual device (iio_dev or iio_trig) + * @rx: somewhere to pass back the value read (min size is 24 bytes) + **/ +static int ade7758_spi_read_burst(struct device *dev, u8 *rx) +{ + struct spi_message msg; + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct ade7758_state *st = iio_dev_get_devdata(indio_dev); + int ret; + + struct spi_transfer xfers[] = { + { + .tx_buf = st->tx, + .rx_buf = rx, + .bits_per_word = 8, + .len = 4, + }, { + .tx_buf = st->tx + 4, + .rx_buf = rx, + .bits_per_word = 8, + .len = 4, + }, + }; + + mutex_lock(&st->buf_lock); + st->tx[0] = ADE7758_READ_REG(ADE7758_RSTATUS); + st->tx[1] = 0; + st->tx[2] = 0; + st->tx[3] = 0; + st->tx[4] = ADE7758_READ_REG(ADE7758_WFORM); + st->tx[5] = 0; + st->tx[6] = 0; + st->tx[7] = 0; + + spi_message_init(&msg); + spi_message_add_tail(&xfers[0], &msg); + spi_message_add_tail(&xfers[1], &msg); + ret = spi_sync(st->us, &msg); + if (ret) + dev_err(&st->us->dev, "problem when reading WFORM value\n"); + + mutex_unlock(&st->buf_lock); + + return ret; +} + +/* Whilst this makes a lot of calls to iio_sw_ring functions - it is to device + * specific to be rolled into the core. + */ +static void ade7758_trigger_bh_to_ring(struct work_struct *work_s) +{ + struct ade7758_state *st + = container_of(work_s, struct ade7758_state, + work_trigger_to_ring); + struct iio_ring_buffer *ring = st->indio_dev->ring; + + int i = 0; + s32 *data; + size_t datasize = ring->access.get_bytes_per_datum(ring); + + data = kmalloc(datasize, GFP_KERNEL); + if (data == NULL) { + dev_err(&st->us->dev, "memory alloc failed in ring bh"); + return; + } + + if (ring->scan_count) + if (ade7758_spi_read_burst(&st->indio_dev->dev, st->rx) >= 0) + for (; i < ring->scan_count; i++) + data[i] = combine_8_to_32(st->rx[i*2+2], + st->rx[i*2+1], + st->rx[i*2]); + + /* Guaranteed to be aligned with 8 byte boundary */ + if (ring->scan_timestamp) + *((s64 *) + (((u32)data + 4 * ring->scan_count + 4) & ~0x7)) = + st->last_timestamp; + + ring->access.store_to(ring, + (u8 *)data, + st->last_timestamp); + + iio_trigger_notify_done(st->indio_dev->trig); + kfree(data); + + return; +} + +void ade7758_unconfigure_ring(struct iio_dev *indio_dev) +{ + kfree(indio_dev->pollfunc); + iio_sw_rb_free(indio_dev->ring); +} + +int ade7758_configure_ring(struct iio_dev *indio_dev) +{ + int ret = 0; + struct ade7758_state *st = indio_dev->dev_data; + struct iio_ring_buffer *ring; + INIT_WORK(&st->work_trigger_to_ring, ade7758_trigger_bh_to_ring); + + ring = iio_sw_rb_allocate(indio_dev); + if (!ring) { + ret = -ENOMEM; + return ret; + } + indio_dev->ring = ring; + /* Effectively select the ring buffer implementation */ + iio_ring_sw_register_funcs(&ring->access); + ring->bpe = 4; + ring->scan_el_attrs = &ade7758_scan_el_group; + ring->scan_timestamp = true; + ring->preenable = &iio_sw_ring_preenable; + ring->postenable = &iio_triggered_ring_postenable; + ring->predisable = &iio_triggered_ring_predisable; + ring->owner = THIS_MODULE; + + /* Set default scan mode */ + iio_scan_mask_set(ring, iio_scan_el_wform.number); + + ret = iio_alloc_pollfunc(indio_dev, NULL, &ade7758_poll_func_th); + if (ret) + goto error_iio_sw_rb_free; + + indio_dev->modes |= INDIO_RING_TRIGGERED; + return 0; + +error_iio_sw_rb_free: + iio_sw_rb_free(indio_dev->ring); + return ret; +} + +int ade7758_initialize_ring(struct iio_ring_buffer *ring) +{ + return iio_ring_buffer_register(ring, 0); +} + +void ade7758_uninitialize_ring(struct iio_ring_buffer *ring) +{ + iio_ring_buffer_unregister(ring); +} diff --git a/drivers/staging/iio/meter/ade7758_trigger.c b/drivers/staging/iio/meter/ade7758_trigger.c new file mode 100644 index 000000000000..60abca0c28ff --- /dev/null +++ b/drivers/staging/iio/meter/ade7758_trigger.c @@ -0,0 +1,125 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../iio.h" +#include "../sysfs.h" +#include "../trigger.h" +#include "ade7758.h" + +/** + * ade7758_data_rdy_trig_poll() the event handler for the data rdy trig + **/ +static int ade7758_data_rdy_trig_poll(struct iio_dev *dev_info, + int index, + s64 timestamp, + int no_test) +{ + struct ade7758_state *st = iio_dev_get_devdata(dev_info); + struct iio_trigger *trig = st->trig; + + iio_trigger_poll(trig, timestamp); + + return IRQ_HANDLED; +} + +IIO_EVENT_SH(data_rdy_trig, &ade7758_data_rdy_trig_poll); + +static DEVICE_ATTR(name, S_IRUGO, iio_trigger_read_name, NULL); + +static struct attribute *ade7758_trigger_attrs[] = { + &dev_attr_name.attr, + NULL, +}; + +static const struct attribute_group ade7758_trigger_attr_group = { + .attrs = ade7758_trigger_attrs, +}; + +/** + * ade7758_data_rdy_trigger_set_state() set datardy interrupt state + **/ +static int ade7758_data_rdy_trigger_set_state(struct iio_trigger *trig, + bool state) +{ + struct ade7758_state *st = trig->private_data; + struct iio_dev *indio_dev = st->indio_dev; + int ret = 0; + + dev_dbg(&indio_dev->dev, "%s (%d)\n", __func__, state); + ret = ade7758_set_irq(&st->indio_dev->dev, state); + if (state == false) { + iio_remove_event_from_list(&iio_event_data_rdy_trig, + &indio_dev->interrupts[0] + ->ev_list); + /* possible quirk with handler currently worked around + by ensuring the work queue is empty */ + flush_scheduled_work(); + } else { + iio_add_event_to_list(&iio_event_data_rdy_trig, + &indio_dev->interrupts[0]->ev_list); + } + return ret; +} + +/** + * ade7758_trig_try_reen() try renabling irq for data rdy trigger + * @trig: the datardy trigger + **/ +static int ade7758_trig_try_reen(struct iio_trigger *trig) +{ + struct ade7758_state *st = trig->private_data; + enable_irq(st->us->irq); + /* irq reenabled so success! */ + return 0; +} + +int ade7758_probe_trigger(struct iio_dev *indio_dev) +{ + int ret; + struct ade7758_state *st = indio_dev->dev_data; + + st->trig = iio_allocate_trigger(); + st->trig->name = kasprintf(GFP_KERNEL, + "ade7758-dev%d", + indio_dev->id); + if (!st->trig->name) { + ret = -ENOMEM; + goto error_free_trig; + } + st->trig->dev.parent = &st->us->dev; + st->trig->owner = THIS_MODULE; + st->trig->private_data = st; + st->trig->set_trigger_state = &ade7758_data_rdy_trigger_set_state; + st->trig->try_reenable = &ade7758_trig_try_reen; + st->trig->control_attrs = &ade7758_trigger_attr_group; + ret = iio_trigger_register(st->trig); + + /* select default trigger */ + indio_dev->trig = st->trig; + if (ret) + goto error_free_trig_name; + + return 0; + +error_free_trig_name: + kfree(st->trig->name); +error_free_trig: + iio_free_trigger(st->trig); + + return ret; +} + +void ade7758_remove_trigger(struct iio_dev *indio_dev) +{ + struct ade7758_state *state = indio_dev->dev_data; + + iio_trigger_unregister(state->trig); + kfree(state->trig->name); + iio_free_trigger(state->trig); +} -- cgit v1.2.3 From 2919fa54ef643364eab69bfff5a72e4aa50d3e39 Mon Sep 17 00:00:00 2001 From: Barry Song Date: Wed, 27 Oct 2010 21:44:17 -0400 Subject: staging: iio: meter: new driver for ADE7759 devices Signed-off-by: Barry Song Signed-off-by: Michael Hennerich Acked-by: Jonathan Cameron Signed-off-by: Mike Frysinger Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/meter/Kconfig | 7 + drivers/staging/iio/meter/Makefile | 2 + drivers/staging/iio/meter/ade7759.c | 670 ++++++++++++++++++++++++++++++++++++ drivers/staging/iio/meter/ade7759.h | 122 +++++++ 4 files changed, 801 insertions(+) create mode 100644 drivers/staging/iio/meter/ade7759.c create mode 100644 drivers/staging/iio/meter/ade7759.h diff --git a/drivers/staging/iio/meter/Kconfig b/drivers/staging/iio/meter/Kconfig index be88bb81b7dc..ebc253eafdeb 100644 --- a/drivers/staging/iio/meter/Kconfig +++ b/drivers/staging/iio/meter/Kconfig @@ -25,3 +25,10 @@ config ADE7758 help Say yes here to build support for Analog Devices ADE7758 Polyphase Multifunction Energy Metering IC with Per Phase Information Driver. + +config ADE7759 + tristate "Analog Devices ADE7759 Active Energy Metering IC Driver" + depends on SPI + help + Say yes here to build support for Analog Devices ADE7758 Active Energy + Metering IC with di/dt Sensor Interface. diff --git a/drivers/staging/iio/meter/Makefile b/drivers/staging/iio/meter/Makefile index 8e1a71d249c3..85e30213af34 100644 --- a/drivers/staging/iio/meter/Makefile +++ b/drivers/staging/iio/meter/Makefile @@ -8,3 +8,5 @@ obj-$(CONFIG_ADE7754) += ade7754.o ade7758-y := ade7758_core.o ade7758-$(CONFIG_IIO_RING_BUFFER) += ade7758_ring.o ade7758_trigger.o obj-$(CONFIG_ADE7758) += ade7758.o + +obj-$(CONFIG_ADE7759) += ade7759.o diff --git a/drivers/staging/iio/meter/ade7759.c b/drivers/staging/iio/meter/ade7759.c new file mode 100644 index 000000000000..fafc3c1e5aaa --- /dev/null +++ b/drivers/staging/iio/meter/ade7759.c @@ -0,0 +1,670 @@ +/* + * ADE7759 Active Energy Metering IC with di/dt Sensor Interface Driver + * + * Copyright 2010 Analog Devices Inc. + * + * Licensed under the GPL-2 or later. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../iio.h" +#include "../sysfs.h" +#include "meter.h" +#include "ade7759.h" + +int ade7759_spi_write_reg_8(struct device *dev, + u8 reg_address, + u8 val) +{ + int ret; + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct ade7759_state *st = iio_dev_get_devdata(indio_dev); + + mutex_lock(&st->buf_lock); + st->tx[0] = ADE7759_WRITE_REG(reg_address); + st->tx[1] = val; + + ret = spi_write(st->us, st->tx, 2); + mutex_unlock(&st->buf_lock); + + return ret; +} + +static int ade7759_spi_write_reg_16(struct device *dev, + u8 reg_address, + u16 value) +{ + int ret; + struct spi_message msg; + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct ade7759_state *st = iio_dev_get_devdata(indio_dev); + struct spi_transfer xfers[] = { + { + .tx_buf = st->tx, + .bits_per_word = 8, + .len = 3, + } + }; + + mutex_lock(&st->buf_lock); + st->tx[0] = ADE7759_WRITE_REG(reg_address); + st->tx[1] = (value >> 8) & 0xFF; + st->tx[2] = value & 0xFF; + + spi_message_init(&msg); + spi_message_add_tail(xfers, &msg); + ret = spi_sync(st->us, &msg); + mutex_unlock(&st->buf_lock); + + return ret; +} + +static int ade7759_spi_read_reg_8(struct device *dev, + u8 reg_address, + u8 *val) +{ + struct spi_message msg; + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct ade7759_state *st = iio_dev_get_devdata(indio_dev); + int ret; + struct spi_transfer xfers[] = { + { + .tx_buf = st->tx, + .rx_buf = st->rx, + .bits_per_word = 8, + .len = 2, + }, + }; + + mutex_lock(&st->buf_lock); + st->tx[0] = ADE7759_READ_REG(reg_address); + st->tx[1] = 0; + + spi_message_init(&msg); + spi_message_add_tail(xfers, &msg); + ret = spi_sync(st->us, &msg); + if (ret) { + dev_err(&st->us->dev, "problem when reading 8 bit register 0x%02X", + reg_address); + goto error_ret; + } + *val = st->rx[1]; + +error_ret: + mutex_unlock(&st->buf_lock); + return ret; +} + +static int ade7759_spi_read_reg_16(struct device *dev, + u8 reg_address, + u16 *val) +{ + struct spi_message msg; + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct ade7759_state *st = iio_dev_get_devdata(indio_dev); + int ret; + struct spi_transfer xfers[] = { + { + .tx_buf = st->tx, + .rx_buf = st->rx, + .bits_per_word = 8, + .len = 3, + }, + }; + + mutex_lock(&st->buf_lock); + st->tx[0] = ADE7759_READ_REG(reg_address); + st->tx[1] = 0; + st->tx[2] = 0; + + spi_message_init(&msg); + spi_message_add_tail(xfers, &msg); + ret = spi_sync(st->us, &msg); + if (ret) { + dev_err(&st->us->dev, "problem when reading 16 bit register 0x%02X", + reg_address); + goto error_ret; + } + *val = (st->rx[1] << 8) | st->rx[2]; + +error_ret: + mutex_unlock(&st->buf_lock); + return ret; +} + +static int ade7759_spi_read_reg_40(struct device *dev, + u8 reg_address, + u64 *val) +{ + struct spi_message msg; + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct ade7759_state *st = iio_dev_get_devdata(indio_dev); + int ret; + struct spi_transfer xfers[] = { + { + .tx_buf = st->tx, + .rx_buf = st->rx, + .bits_per_word = 8, + .len = 6, + }, + }; + + mutex_lock(&st->buf_lock); + st->tx[0] = ADE7759_READ_REG(reg_address); + memset(&st->tx[1], 0 , 5); + + spi_message_init(&msg); + spi_message_add_tail(xfers, &msg); + ret = spi_sync(st->us, &msg); + if (ret) { + dev_err(&st->us->dev, "problem when reading 40 bit register 0x%02X", + reg_address); + goto error_ret; + } + *val = ((u64)st->rx[1] << 32) | (st->rx[2] << 24) | + (st->rx[3] << 16) | (st->rx[4] << 8) | st->rx[5]; + +error_ret: + mutex_unlock(&st->buf_lock); + return ret; +} + +static ssize_t ade7759_read_8bit(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + int ret; + u8 val = 0; + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + + ret = ade7759_spi_read_reg_8(dev, this_attr->address, &val); + if (ret) + return ret; + + return sprintf(buf, "%u\n", val); +} + +static ssize_t ade7759_read_16bit(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + int ret; + u16 val = 0; + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + + ret = ade7759_spi_read_reg_16(dev, this_attr->address, &val); + if (ret) + return ret; + + return sprintf(buf, "%u\n", val); +} + +static ssize_t ade7759_read_40bit(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + int ret; + u64 val = 0; + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + + ret = ade7759_spi_read_reg_40(dev, this_attr->address, &val); + if (ret) + return ret; + + return sprintf(buf, "%llu\n", val); +} + +static ssize_t ade7759_write_8bit(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + int ret; + long val; + + ret = strict_strtol(buf, 10, &val); + if (ret) + goto error_ret; + ret = ade7759_spi_write_reg_8(dev, this_attr->address, val); + +error_ret: + return ret ? ret : len; +} + +static ssize_t ade7759_write_16bit(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + int ret; + long val; + + ret = strict_strtol(buf, 10, &val); + if (ret) + goto error_ret; + ret = ade7759_spi_write_reg_16(dev, this_attr->address, val); + +error_ret: + return ret ? ret : len; +} + +static int ade7759_reset(struct device *dev) +{ + int ret; + u16 val; + ade7759_spi_read_reg_16(dev, + ADE7759_MODE, + &val); + val |= 1 << 6; /* Software Chip Reset */ + ret = ade7759_spi_write_reg_16(dev, + ADE7759_MODE, + val); + + return ret; +} + +static ssize_t ade7759_write_reset(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t len) +{ + if (len < 1) + return -1; + switch (buf[0]) { + case '1': + case 'y': + case 'Y': + return ade7759_reset(dev); + } + return -1; +} + +static IIO_DEV_ATTR_AENERGY(ade7759_read_40bit, ADE7759_AENERGY); +static IIO_DEV_ATTR_CFDEN(S_IWUSR | S_IRUGO, + ade7759_read_16bit, + ade7759_write_16bit, + ADE7759_CFDEN); +static IIO_DEV_ATTR_CFNUM(S_IWUSR | S_IRUGO, + ade7759_read_8bit, + ade7759_write_8bit, + ADE7759_CFNUM); +static IIO_DEV_ATTR_CHKSUM(ade7759_read_8bit, ADE7759_CHKSUM); +static IIO_DEV_ATTR_PHCAL(S_IWUSR | S_IRUGO, + ade7759_read_16bit, + ade7759_write_16bit, + ADE7759_PHCAL); +static IIO_DEV_ATTR_APOS(S_IWUSR | S_IRUGO, + ade7759_read_16bit, + ade7759_write_16bit, + ADE7759_APOS); +static IIO_DEV_ATTR_SAGCYC(S_IWUSR | S_IRUGO, + ade7759_read_8bit, + ade7759_write_8bit, + ADE7759_SAGCYC); +static IIO_DEV_ATTR_SAGLVL(S_IWUSR | S_IRUGO, + ade7759_read_8bit, + ade7759_write_8bit, + ADE7759_SAGLVL); +static IIO_DEV_ATTR_LINECYC(S_IWUSR | S_IRUGO, + ade7759_read_8bit, + ade7759_write_8bit, + ADE7759_LINECYC); +static IIO_DEV_ATTR_LENERGY(ade7759_read_40bit, ADE7759_LENERGY); +static IIO_DEV_ATTR_PGA_GAIN(S_IWUSR | S_IRUGO, + ade7759_read_8bit, + ade7759_write_8bit, + ADE7759_GAIN); +static IIO_DEV_ATTR_ACTIVE_POWER_GAIN(S_IWUSR | S_IRUGO, + ade7759_read_16bit, + ade7759_write_16bit, + ADE7759_APGAIN); +static IIO_DEV_ATTR_CH_OFF(1, S_IWUSR | S_IRUGO, + ade7759_read_8bit, + ade7759_write_8bit, + ADE7759_CH1OS); +static IIO_DEV_ATTR_CH_OFF(2, S_IWUSR | S_IRUGO, + ade7759_read_8bit, + ade7759_write_8bit, + ADE7759_CH2OS); + +static int ade7759_set_irq(struct device *dev, bool enable) +{ + int ret; + u8 irqen; + ret = ade7759_spi_read_reg_8(dev, ADE7759_IRQEN, &irqen); + if (ret) + goto error_ret; + + if (enable) + irqen |= 1 << 3; /* Enables an interrupt when a data is + present in the waveform register */ + else + irqen &= ~(1 << 3); + + ret = ade7759_spi_write_reg_8(dev, ADE7759_IRQEN, irqen); + if (ret) + goto error_ret; + +error_ret: + return ret; +} + +/* Power down the device */ +int ade7759_stop_device(struct device *dev) +{ + int ret; + u16 val; + ade7759_spi_read_reg_16(dev, + ADE7759_MODE, + &val); + val |= 1 << 4; /* AD converters can be turned off */ + ret = ade7759_spi_write_reg_16(dev, + ADE7759_MODE, + val); + + return ret; +} + +static int ade7759_initial_setup(struct ade7759_state *st) +{ + int ret; + struct device *dev = &st->indio_dev->dev; + + /* use low spi speed for init */ + st->us->mode = SPI_MODE_3; + spi_setup(st->us); + + /* Disable IRQ */ + ret = ade7759_set_irq(dev, false); + if (ret) { + dev_err(dev, "disable irq failed"); + goto err_ret; + } + + ade7759_reset(dev); + msleep(ADE7759_STARTUP_DELAY); + +err_ret: + return ret; +} + +static ssize_t ade7759_read_frequency(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + int ret, len = 0; + u16 t; + int sps; + ret = ade7759_spi_read_reg_16(dev, + ADE7759_MODE, + &t); + if (ret) + return ret; + + t = (t >> 3) & 0x3; + sps = 27900 / (1 + t); + + len = sprintf(buf, "%d SPS\n", sps); + return len; +} + +static ssize_t ade7759_write_frequency(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct ade7759_state *st = iio_dev_get_devdata(indio_dev); + unsigned long val; + int ret; + u16 reg, t; + + ret = strict_strtol(buf, 10, &val); + if (ret) + return ret; + + mutex_lock(&indio_dev->mlock); + + t = (27900 / val); + if (t > 0) + t--; + + if (t > 1) + st->us->max_speed_hz = ADE7759_SPI_SLOW; + else + st->us->max_speed_hz = ADE7759_SPI_FAST; + + ret = ade7759_spi_read_reg_16(dev, + ADE7759_MODE, + ®); + if (ret) + goto out; + + reg &= ~(3 << 13); + reg |= t << 13; + + ret = ade7759_spi_write_reg_16(dev, + ADE7759_MODE, + reg); + +out: + mutex_unlock(&indio_dev->mlock); + + return ret ? ret : len; +} +static IIO_DEV_ATTR_TEMP_RAW(ade7759_read_8bit); +static IIO_CONST_ATTR(temp_offset, "70 C"); +static IIO_CONST_ATTR(temp_scale, "1 C"); + +static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO, + ade7759_read_frequency, + ade7759_write_frequency); + +static IIO_DEV_ATTR_RESET(ade7759_write_reset); + +static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("27900 14000 7000 3500"); + +static IIO_CONST_ATTR(name, "ade7759"); + +static struct attribute *ade7759_event_attributes[] = { + NULL +}; + +static struct attribute_group ade7759_event_attribute_group = { + .attrs = ade7759_event_attributes, +}; + +static struct attribute *ade7759_attributes[] = { + &iio_dev_attr_temp_raw.dev_attr.attr, + &iio_const_attr_temp_offset.dev_attr.attr, + &iio_const_attr_temp_scale.dev_attr.attr, + &iio_dev_attr_sampling_frequency.dev_attr.attr, + &iio_const_attr_sampling_frequency_available.dev_attr.attr, + &iio_dev_attr_reset.dev_attr.attr, + &iio_const_attr_name.dev_attr.attr, + &iio_dev_attr_phcal.dev_attr.attr, + &iio_dev_attr_cfden.dev_attr.attr, + &iio_dev_attr_aenergy.dev_attr.attr, + &iio_dev_attr_cfnum.dev_attr.attr, + &iio_dev_attr_apos.dev_attr.attr, + &iio_dev_attr_sagcyc.dev_attr.attr, + &iio_dev_attr_saglvl.dev_attr.attr, + &iio_dev_attr_linecyc.dev_attr.attr, + &iio_dev_attr_lenergy.dev_attr.attr, + &iio_dev_attr_chksum.dev_attr.attr, + &iio_dev_attr_pga_gain.dev_attr.attr, + &iio_dev_attr_active_power_gain.dev_attr.attr, + &iio_dev_attr_choff_1.dev_attr.attr, + &iio_dev_attr_choff_2.dev_attr.attr, + NULL, +}; + +static const struct attribute_group ade7759_attribute_group = { + .attrs = ade7759_attributes, +}; + +static int __devinit ade7759_probe(struct spi_device *spi) +{ + int ret, regdone = 0; + struct ade7759_state *st = kzalloc(sizeof *st, GFP_KERNEL); + if (!st) { + ret = -ENOMEM; + goto error_ret; + } + /* this is only used for removal purposes */ + spi_set_drvdata(spi, st); + + /* Allocate the comms buffers */ + st->rx = kzalloc(sizeof(*st->rx)*ADE7759_MAX_RX, GFP_KERNEL); + if (st->rx == NULL) { + ret = -ENOMEM; + goto error_free_st; + } + st->tx = kzalloc(sizeof(*st->tx)*ADE7759_MAX_TX, GFP_KERNEL); + if (st->tx == NULL) { + ret = -ENOMEM; + goto error_free_rx; + } + st->us = spi; + mutex_init(&st->buf_lock); + /* setup the industrialio driver allocated elements */ + st->indio_dev = iio_allocate_device(); + if (st->indio_dev == NULL) { + ret = -ENOMEM; + goto error_free_tx; + } + + st->indio_dev->dev.parent = &spi->dev; + st->indio_dev->num_interrupt_lines = 1; + st->indio_dev->event_attrs = &ade7759_event_attribute_group; + st->indio_dev->attrs = &ade7759_attribute_group; + st->indio_dev->dev_data = (void *)(st); + st->indio_dev->driver_module = THIS_MODULE; + st->indio_dev->modes = INDIO_DIRECT_MODE; + + ret = ade7759_configure_ring(st->indio_dev); + if (ret) + goto error_free_dev; + + ret = iio_device_register(st->indio_dev); + if (ret) + goto error_unreg_ring_funcs; + regdone = 1; + + ret = ade7759_initialize_ring(st->indio_dev->ring); + if (ret) { + printk(KERN_ERR "failed to initialize the ring\n"); + goto error_unreg_ring_funcs; + } + + if (spi->irq) { + ret = iio_register_interrupt_line(spi->irq, + st->indio_dev, + 0, + IRQF_TRIGGER_FALLING, + "ade7759"); + if (ret) + goto error_uninitialize_ring; + + ret = ade7759_probe_trigger(st->indio_dev); + if (ret) + goto error_unregister_line; + } + + /* Get the device into a sane initial state */ + ret = ade7759_initial_setup(st); + if (ret) + goto error_remove_trigger; + return 0; + +error_remove_trigger: + if (st->indio_dev->modes & INDIO_RING_TRIGGERED) + ade7759_remove_trigger(st->indio_dev); +error_unregister_line: + if (st->indio_dev->modes & INDIO_RING_TRIGGERED) + iio_unregister_interrupt_line(st->indio_dev, 0); +error_uninitialize_ring: + ade7759_uninitialize_ring(st->indio_dev->ring); +error_unreg_ring_funcs: + ade7759_unconfigure_ring(st->indio_dev); +error_free_dev: + if (regdone) + iio_device_unregister(st->indio_dev); + else + iio_free_device(st->indio_dev); +error_free_tx: + kfree(st->tx); +error_free_rx: + kfree(st->rx); +error_free_st: + kfree(st); +error_ret: + return ret; +} + +/* fixme, confirm ordering in this function */ +static int ade7759_remove(struct spi_device *spi) +{ + int ret; + struct ade7759_state *st = spi_get_drvdata(spi); + struct iio_dev *indio_dev = st->indio_dev; + + ret = ade7759_stop_device(&(indio_dev->dev)); + if (ret) + goto err_ret; + + flush_scheduled_work(); + + ade7759_remove_trigger(indio_dev); + if (spi->irq && gpio_is_valid(irq_to_gpio(spi->irq)) > 0) + iio_unregister_interrupt_line(indio_dev, 0); + + ade7759_uninitialize_ring(indio_dev->ring); + ade7759_unconfigure_ring(indio_dev); + iio_device_unregister(indio_dev); + kfree(st->tx); + kfree(st->rx); + kfree(st); + + return 0; + +err_ret: + return ret; +} + +static struct spi_driver ade7759_driver = { + .driver = { + .name = "ade7759", + .owner = THIS_MODULE, + }, + .probe = ade7759_probe, + .remove = __devexit_p(ade7759_remove), +}; + +static __init int ade7759_init(void) +{ + return spi_register_driver(&ade7759_driver); +} +module_init(ade7759_init); + +static __exit void ade7759_exit(void) +{ + spi_unregister_driver(&ade7759_driver); +} +module_exit(ade7759_exit); + +MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>"); +MODULE_DESCRIPTION("Analog Devices ADE7759 Active Energy Metering IC Driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/staging/iio/meter/ade7759.h b/drivers/staging/iio/meter/ade7759.h new file mode 100644 index 000000000000..813dea2676a9 --- /dev/null +++ b/drivers/staging/iio/meter/ade7759.h @@ -0,0 +1,122 @@ +#ifndef _ADE7759_H +#define _ADE7759_H + +#define ADE7759_WAVEFORM 0x01 +#define ADE7759_AENERGY 0x02 +#define ADE7759_RSTENERGY 0x03 +#define ADE7759_STATUS 0x04 +#define ADE7759_RSTSTATUS 0x05 +#define ADE7759_MODE 0x06 +#define ADE7759_CFDEN 0x07 +#define ADE7759_CH1OS 0x08 +#define ADE7759_CH2OS 0x09 +#define ADE7759_GAIN 0x0A +#define ADE7759_APGAIN 0x0B +#define ADE7759_PHCAL 0x0C +#define ADE7759_APOS 0x0D +#define ADE7759_ZXTOUT 0x0E +#define ADE7759_SAGCYC 0x0F +#define ADE7759_IRQEN 0x10 +#define ADE7759_SAGLVL 0x11 +#define ADE7759_TEMP 0x12 +#define ADE7759_LINECYC 0x13 +#define ADE7759_LENERGY 0x14 +#define ADE7759_CFNUM 0x15 +#define ADE7759_CHKSUM 0x1E +#define ADE7759_DIEREV 0x1F + +#define ADE7759_READ_REG(a) a +#define ADE7759_WRITE_REG(a) ((a) | 0x80) + +#define ADE7759_MAX_TX 6 +#define ADE7759_MAX_RX 6 +#define ADE7759_STARTUP_DELAY 1 + +#define ADE7759_SPI_SLOW (u32)(300 * 1000) +#define ADE7759_SPI_BURST (u32)(1000 * 1000) +#define ADE7759_SPI_FAST (u32)(2000 * 1000) + +#define DRIVER_NAME "ade7759" + +/** + * struct ade7759_state - device instance specific data + * @us: actual spi_device + * @work_trigger_to_ring: bh for triggered event handling + * @inter: used to check if new interrupt has been triggered + * @last_timestamp: passing timestamp from th to bh of interrupt handler + * @indio_dev: industrial I/O device structure + * @trig: data ready trigger registered with iio + * @tx: transmit buffer + * @rx: recieve buffer + * @buf_lock: mutex to protect tx and rx + **/ +struct ade7759_state { + struct spi_device *us; + struct work_struct work_trigger_to_ring; + s64 last_timestamp; + struct iio_dev *indio_dev; + struct iio_trigger *trig; + u8 *tx; + u8 *rx; + struct mutex buf_lock; +}; +#if defined(CONFIG_IIO_RING_BUFFER) && defined(THIS_HAS_RING_BUFFER_SUPPORT) +/* At the moment triggers are only used for ring buffer + * filling. This may change! + */ + +enum ade7759_scan { + ADE7759_SCAN_ACTIVE_POWER, + ADE7759_SCAN_CH1_CH2, + ADE7759_SCAN_CH1, + ADE7759_SCAN_CH2, +}; + +void ade7759_remove_trigger(struct iio_dev *indio_dev); +int ade7759_probe_trigger(struct iio_dev *indio_dev); + +ssize_t ade7759_read_data_from_ring(struct device *dev, + struct device_attribute *attr, + char *buf); + + +int ade7759_configure_ring(struct iio_dev *indio_dev); +void ade7759_unconfigure_ring(struct iio_dev *indio_dev); + +int ade7759_initialize_ring(struct iio_ring_buffer *ring); +void ade7759_uninitialize_ring(struct iio_ring_buffer *ring); +#else /* CONFIG_IIO_RING_BUFFER */ + +static inline void ade7759_remove_trigger(struct iio_dev *indio_dev) +{ +} +static inline int ade7759_probe_trigger(struct iio_dev *indio_dev) +{ + return 0; +} + +static inline ssize_t +ade7759_read_data_from_ring(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + return 0; +} + +static int ade7759_configure_ring(struct iio_dev *indio_dev) +{ + return 0; +} +static inline void ade7759_unconfigure_ring(struct iio_dev *indio_dev) +{ +} +static inline int ade7759_initialize_ring(struct iio_ring_buffer *ring) +{ + return 0; +} +static inline void ade7759_uninitialize_ring(struct iio_ring_buffer *ring) +{ +} +#endif /* CONFIG_IIO_RING_BUFFER */ + +#endif -- cgit v1.2.3 From 5b264a624ebc9a082873aa06ea641cbdc760e6e1 Mon Sep 17 00:00:00 2001 From: Barry Song Date: Wed, 27 Oct 2010 21:44:18 -0400 Subject: staging: iio: meter: new driver for ADE7854/58/68/78 devices Signed-off-by: Barry Song Signed-off-by: Michael Hennerich Acked-by: Jonathan Cameron Signed-off-by: Mike Frysinger Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/meter/Kconfig | 27 ++ drivers/staging/iio/meter/Makefile | 3 + drivers/staging/iio/meter/ade7854-i2c.c | 272 +++++++++++++ drivers/staging/iio/meter/ade7854-spi.c | 360 +++++++++++++++++ drivers/staging/iio/meter/ade7854.c | 680 ++++++++++++++++++++++++++++++++ drivers/staging/iio/meter/ade7854.h | 245 ++++++++++++ 6 files changed, 1587 insertions(+) create mode 100644 drivers/staging/iio/meter/ade7854-i2c.c create mode 100644 drivers/staging/iio/meter/ade7854-spi.c create mode 100644 drivers/staging/iio/meter/ade7854.c create mode 100644 drivers/staging/iio/meter/ade7854.h diff --git a/drivers/staging/iio/meter/Kconfig b/drivers/staging/iio/meter/Kconfig index ebc253eafdeb..12e36e460693 100644 --- a/drivers/staging/iio/meter/Kconfig +++ b/drivers/staging/iio/meter/Kconfig @@ -32,3 +32,30 @@ config ADE7759 help Say yes here to build support for Analog Devices ADE7758 Active Energy Metering IC with di/dt Sensor Interface. + +config ADE7854 + tristate "Analog Devices ADE7854/58/68/78 Polyphase Multifunction Energy Metering IC Driver" + depends on SPI || I2C + help + Say yes here to build support for Analog Devices ADE7854/58/68/78 Polyphase + Multifunction Energy Metering IC Driver. + +config ADE7854_I2C + tristate "support I2C bus connection" + depends on ADE7854 && I2C + default y + help + Say Y here if you have ADE7854/58/68/78 hooked to an I2C bus. + + To compile this driver as a module, choose M here: the + module will be called ade7854-i2c. + +config ADE7854_SPI + tristate "support SPI bus connection" + depends on ADE7854 && SPI + default y + help + Say Y here if you have ADE7854/58/68/78 hooked to a SPI bus. + + To compile this driver as a module, choose M here: the + module will be called ade7854-spi. diff --git a/drivers/staging/iio/meter/Makefile b/drivers/staging/iio/meter/Makefile index 85e30213af34..0cc7d5140dfe 100644 --- a/drivers/staging/iio/meter/Makefile +++ b/drivers/staging/iio/meter/Makefile @@ -10,3 +10,6 @@ ade7758-$(CONFIG_IIO_RING_BUFFER) += ade7758_ring.o ade7758_trigger.o obj-$(CONFIG_ADE7758) += ade7758.o obj-$(CONFIG_ADE7759) += ade7759.o +obj-$(CONFIG_ADE7854) += ade7854.o +obj-$(CONFIG_ADE7854_I2C) += ade7854-i2c.o +obj-$(CONFIG_ADE7854_SPI) += ade7854-spi.o diff --git a/drivers/staging/iio/meter/ade7854-i2c.c b/drivers/staging/iio/meter/ade7854-i2c.c new file mode 100644 index 000000000000..4578e7b7f460 --- /dev/null +++ b/drivers/staging/iio/meter/ade7854-i2c.c @@ -0,0 +1,272 @@ +/* + * ADE7854/58/68/78 Polyphase Multifunction Energy Metering IC Driver (I2C Bus) + * + * Copyright 2010 Analog Devices Inc. + * + * Licensed under the GPL-2 or later. + */ + +#include +#include +#include +#include + +#include "../iio.h" +#include "ade7854.h" + +static int ade7854_i2c_write_reg_8(struct device *dev, + u16 reg_address, + u8 value) +{ + int ret; + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct ade7854_state *st = iio_dev_get_devdata(indio_dev); + + mutex_lock(&st->buf_lock); + st->tx[0] = (reg_address >> 8) & 0xFF; + st->tx[1] = reg_address & 0xFF; + st->tx[2] = value; + + ret = i2c_master_send(st->i2c, st->tx, 3); + mutex_unlock(&st->buf_lock); + + return ret; +} + +static int ade7854_i2c_write_reg_16(struct device *dev, + u16 reg_address, + u16 value) +{ + int ret; + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct ade7854_state *st = iio_dev_get_devdata(indio_dev); + + mutex_lock(&st->buf_lock); + st->tx[0] = (reg_address >> 8) & 0xFF; + st->tx[1] = reg_address & 0xFF; + st->tx[2] = (value >> 8) & 0xFF; + st->tx[3] = value & 0xFF; + + ret = i2c_master_send(st->i2c, st->tx, 4); + mutex_unlock(&st->buf_lock); + + return ret; +} + +static int ade7854_i2c_write_reg_24(struct device *dev, + u16 reg_address, + u32 value) +{ + int ret; + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct ade7854_state *st = iio_dev_get_devdata(indio_dev); + + mutex_lock(&st->buf_lock); + st->tx[0] = (reg_address >> 8) & 0xFF; + st->tx[1] = reg_address & 0xFF; + st->tx[2] = (value >> 16) & 0xFF; + st->tx[3] = (value >> 8) & 0xFF; + st->tx[4] = value & 0xFF; + + ret = i2c_master_send(st->i2c, st->tx, 5); + mutex_unlock(&st->buf_lock); + + return ret; +} + +static int ade7854_i2c_write_reg_32(struct device *dev, + u16 reg_address, + u32 value) +{ + int ret; + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct ade7854_state *st = iio_dev_get_devdata(indio_dev); + + mutex_lock(&st->buf_lock); + st->tx[0] = (reg_address >> 8) & 0xFF; + st->tx[1] = reg_address & 0xFF; + st->tx[2] = (value >> 24) & 0xFF; + st->tx[3] = (value >> 16) & 0xFF; + st->tx[4] = (value >> 8) & 0xFF; + st->tx[5] = value & 0xFF; + + ret = i2c_master_send(st->i2c, st->tx, 6); + mutex_unlock(&st->buf_lock); + + return ret; +} + +static int ade7854_i2c_read_reg_8(struct device *dev, + u16 reg_address, + u8 *val) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct ade7854_state *st = iio_dev_get_devdata(indio_dev); + int ret; + + mutex_lock(&st->buf_lock); + st->tx[0] = (reg_address >> 8) & 0xFF; + st->tx[1] = reg_address & 0xFF; + + ret = i2c_master_send(st->i2c, st->tx, 2); + if (ret) + goto out; + + ret = i2c_master_recv(st->i2c, st->rx, 1); + if (ret) + goto out; + + *val = st->rx[0]; +out: + mutex_unlock(&st->buf_lock); + return ret; +} + +static int ade7854_i2c_read_reg_16(struct device *dev, + u16 reg_address, + u16 *val) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct ade7854_state *st = iio_dev_get_devdata(indio_dev); + int ret; + + mutex_lock(&st->buf_lock); + st->tx[0] = (reg_address >> 8) & 0xFF; + st->tx[1] = reg_address & 0xFF; + + ret = i2c_master_send(st->i2c, st->tx, 2); + if (ret) + goto out; + + ret = i2c_master_recv(st->i2c, st->rx, 2); + if (ret) + goto out; + + *val = (st->rx[0] << 8) | st->rx[1]; +out: + mutex_unlock(&st->buf_lock); + return ret; +} + +static int ade7854_i2c_read_reg_24(struct device *dev, + u16 reg_address, + u32 *val) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct ade7854_state *st = iio_dev_get_devdata(indio_dev); + int ret; + + mutex_lock(&st->buf_lock); + st->tx[0] = (reg_address >> 8) & 0xFF; + st->tx[1] = reg_address & 0xFF; + + ret = i2c_master_send(st->i2c, st->tx, 2); + if (ret) + goto out; + + ret = i2c_master_recv(st->i2c, st->rx, 3); + if (ret) + goto out; + + *val = (st->rx[0] << 16) | (st->rx[1] << 8) | st->rx[2]; +out: + mutex_unlock(&st->buf_lock); + return ret; +} + +static int ade7854_i2c_read_reg_32(struct device *dev, + u16 reg_address, + u32 *val) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct ade7854_state *st = iio_dev_get_devdata(indio_dev); + int ret; + + mutex_lock(&st->buf_lock); + st->tx[0] = (reg_address >> 8) & 0xFF; + st->tx[1] = reg_address & 0xFF; + + ret = i2c_master_send(st->i2c, st->tx, 2); + if (ret) + goto out; + + ret = i2c_master_recv(st->i2c, st->rx, 3); + if (ret) + goto out; + + *val = (st->rx[0] << 24) | (st->rx[1] << 16) | (st->rx[2] << 8) | st->rx[3]; +out: + mutex_unlock(&st->buf_lock); + return ret; +} + +static int __devinit ade7854_i2c_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + int ret; + struct ade7854_state *st = kzalloc(sizeof *st, GFP_KERNEL); + if (!st) { + ret = -ENOMEM; + return ret; + } + + i2c_set_clientdata(client, st); + st->read_reg_8 = ade7854_i2c_read_reg_8; + st->read_reg_16 = ade7854_i2c_read_reg_16; + st->read_reg_24 = ade7854_i2c_read_reg_24; + st->read_reg_32 = ade7854_i2c_read_reg_32; + st->write_reg_8 = ade7854_i2c_write_reg_8; + st->write_reg_16 = ade7854_i2c_write_reg_16; + st->write_reg_24 = ade7854_i2c_write_reg_24; + st->write_reg_32 = ade7854_i2c_write_reg_32; + st->i2c = client; + st->irq = client->irq; + + ret = ade7854_probe(st, &client->dev); + if (ret) { + kfree(st); + return ret; + } + + return ret; +} + +static int __devexit ade7854_i2c_remove(struct i2c_client *client) +{ + return ade7854_remove(i2c_get_clientdata(client)); +} + +static const struct i2c_device_id ade7854_id[] = { + { "ade7854", 0 }, + { "ade7858", 0 }, + { "ade7868", 0 }, + { "ade7878", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, ade7854_id); + +static struct i2c_driver ade7854_i2c_driver = { + .driver = { + .name = "ade7854", + }, + .probe = ade7854_i2c_probe, + .remove = __devexit_p(ade7854_i2c_remove), + .id_table = ade7854_id, +}; + +static __init int ade7854_i2c_init(void) +{ + return i2c_add_driver(&ade7854_i2c_driver); +} +module_init(ade7854_i2c_init); + +static __exit void ade7854_i2c_exit(void) +{ + i2c_del_driver(&ade7854_i2c_driver); +} +module_exit(ade7854_i2c_exit); + + +MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>"); +MODULE_DESCRIPTION("Analog Devices ADE7854/58/68/78 Polyphase Multifunction Energy Metering IC I2C Driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/staging/iio/meter/ade7854-spi.c b/drivers/staging/iio/meter/ade7854-spi.c new file mode 100644 index 000000000000..fe58103ed4ca --- /dev/null +++ b/drivers/staging/iio/meter/ade7854-spi.c @@ -0,0 +1,360 @@ +/* + * ADE7854/58/68/78 Polyphase Multifunction Energy Metering IC Driver (SPI Bus) + * + * Copyright 2010 Analog Devices Inc. + * + * Licensed under the GPL-2 or later. + */ + +#include +#include +#include +#include + +#include "../iio.h" +#include "ade7854.h" + +static int ade7854_spi_write_reg_8(struct device *dev, + u16 reg_address, + u8 value) +{ + int ret; + struct spi_message msg; + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct ade7854_state *st = iio_dev_get_devdata(indio_dev); + struct spi_transfer xfers[] = { + { + .tx_buf = st->tx, + .bits_per_word = 8, + .len = 4, + } + }; + + mutex_lock(&st->buf_lock); + st->tx[0] = ADE7854_WRITE_REG; + st->tx[1] = (reg_address >> 8) & 0xFF; + st->tx[2] = reg_address & 0xFF; + st->tx[3] = value & 0xFF; + + spi_message_init(&msg); + spi_message_add_tail(xfers, &msg); + ret = spi_sync(st->spi, &msg); + mutex_unlock(&st->buf_lock); + + return ret; +} + +static int ade7854_spi_write_reg_16(struct device *dev, + u16 reg_address, + u16 value) +{ + int ret; + struct spi_message msg; + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct ade7854_state *st = iio_dev_get_devdata(indio_dev); + struct spi_transfer xfers[] = { + { + .tx_buf = st->tx, + .bits_per_word = 8, + .len = 5, + } + }; + + mutex_lock(&st->buf_lock); + st->tx[0] = ADE7854_WRITE_REG; + st->tx[1] = (reg_address >> 8) & 0xFF; + st->tx[2] = reg_address & 0xFF; + st->tx[3] = (value >> 8) & 0xFF; + st->tx[4] = value & 0xFF; + + spi_message_init(&msg); + spi_message_add_tail(xfers, &msg); + ret = spi_sync(st->spi, &msg); + mutex_unlock(&st->buf_lock); + + return ret; +} + +static int ade7854_spi_write_reg_24(struct device *dev, + u16 reg_address, + u32 value) +{ + int ret; + struct spi_message msg; + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct ade7854_state *st = iio_dev_get_devdata(indio_dev); + struct spi_transfer xfers[] = { + { + .tx_buf = st->tx, + .bits_per_word = 8, + .len = 6, + } + }; + + mutex_lock(&st->buf_lock); + st->tx[0] = ADE7854_WRITE_REG; + st->tx[1] = (reg_address >> 8) & 0xFF; + st->tx[2] = reg_address & 0xFF; + st->tx[3] = (value >> 16) & 0xFF; + st->tx[4] = (value >> 8) & 0xFF; + st->tx[5] = value & 0xFF; + + spi_message_init(&msg); + spi_message_add_tail(xfers, &msg); + ret = spi_sync(st->spi, &msg); + mutex_unlock(&st->buf_lock); + + return ret; +} + +static int ade7854_spi_write_reg_32(struct device *dev, + u16 reg_address, + u32 value) +{ + int ret; + struct spi_message msg; + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct ade7854_state *st = iio_dev_get_devdata(indio_dev); + struct spi_transfer xfers[] = { + { + .tx_buf = st->tx, + .bits_per_word = 8, + .len = 7, + } + }; + + mutex_lock(&st->buf_lock); + st->tx[0] = ADE7854_WRITE_REG; + st->tx[1] = (reg_address >> 8) & 0xFF; + st->tx[2] = reg_address & 0xFF; + st->tx[3] = (value >> 24) & 0xFF; + st->tx[4] = (value >> 16) & 0xFF; + st->tx[5] = (value >> 8) & 0xFF; + st->tx[6] = value & 0xFF; + + spi_message_init(&msg); + spi_message_add_tail(xfers, &msg); + ret = spi_sync(st->spi, &msg); + mutex_unlock(&st->buf_lock); + + return ret; +} + +static int ade7854_spi_read_reg_8(struct device *dev, + u16 reg_address, + u8 *val) +{ + struct spi_message msg; + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct ade7854_state *st = iio_dev_get_devdata(indio_dev); + int ret; + struct spi_transfer xfers[] = { + { + .tx_buf = st->tx, + .bits_per_word = 8, + .len = 4, + }, + }; + + mutex_lock(&st->buf_lock); + + st->tx[0] = ADE7854_READ_REG; + st->tx[1] = (reg_address >> 8) & 0xFF; + st->tx[2] = reg_address & 0xFF; + st->tx[3] = 0; + + spi_message_init(&msg); + spi_message_add_tail(xfers, &msg); + ret = spi_sync(st->spi, &msg); + if (ret) { + dev_err(&st->spi->dev, "problem when reading 8 bit register 0x%02X", + reg_address); + goto error_ret; + } + *val = st->rx[3]; + +error_ret: + mutex_unlock(&st->buf_lock); + return ret; +} + +static int ade7854_spi_read_reg_16(struct device *dev, + u16 reg_address, + u16 *val) +{ + struct spi_message msg; + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct ade7854_state *st = iio_dev_get_devdata(indio_dev); + int ret; + struct spi_transfer xfers[] = { + { + .tx_buf = st->tx, + .bits_per_word = 8, + .len = 5, + }, + }; + + mutex_lock(&st->buf_lock); + st->tx[0] = ADE7854_READ_REG; + st->tx[1] = (reg_address >> 8) & 0xFF; + st->tx[2] = reg_address & 0xFF; + st->tx[3] = 0; + st->tx[4] = 0; + + spi_message_init(&msg); + spi_message_add_tail(xfers, &msg); + ret = spi_sync(st->spi, &msg); + if (ret) { + dev_err(&st->spi->dev, "problem when reading 16 bit register 0x%02X", + reg_address); + goto error_ret; + } + *val = (st->rx[3] << 8) | st->rx[4]; + +error_ret: + mutex_unlock(&st->buf_lock); + return ret; +} + +static int ade7854_spi_read_reg_24(struct device *dev, + u16 reg_address, + u32 *val) +{ + struct spi_message msg; + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct ade7854_state *st = iio_dev_get_devdata(indio_dev); + int ret; + struct spi_transfer xfers[] = { + { + .tx_buf = st->tx, + .bits_per_word = 8, + .len = 6, + }, + }; + + mutex_lock(&st->buf_lock); + + st->tx[0] = ADE7854_READ_REG; + st->tx[1] = (reg_address >> 8) & 0xFF; + st->tx[2] = reg_address & 0xFF; + st->tx[3] = 0; + st->tx[4] = 0; + st->tx[5] = 0; + + spi_message_init(&msg); + spi_message_add_tail(xfers, &msg); + ret = spi_sync(st->spi, &msg); + if (ret) { + dev_err(&st->spi->dev, "problem when reading 24 bit register 0x%02X", + reg_address); + goto error_ret; + } + *val = (st->rx[3] << 16) | (st->rx[4] << 8) | st->rx[5]; + +error_ret: + mutex_unlock(&st->buf_lock); + return ret; +} + +static int ade7854_spi_read_reg_32(struct device *dev, + u16 reg_address, + u32 *val) +{ + struct spi_message msg; + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct ade7854_state *st = iio_dev_get_devdata(indio_dev); + int ret; + struct spi_transfer xfers[] = { + { + .tx_buf = st->tx, + .bits_per_word = 8, + .len = 7, + }, + }; + + mutex_lock(&st->buf_lock); + + st->tx[0] = ADE7854_READ_REG; + st->tx[1] = (reg_address >> 8) & 0xFF; + st->tx[2] = reg_address & 0xFF; + st->tx[3] = 0; + st->tx[4] = 0; + st->tx[5] = 0; + st->tx[6] = 0; + + spi_message_init(&msg); + spi_message_add_tail(xfers, &msg); + ret = spi_sync(st->spi, &msg); + if (ret) { + dev_err(&st->spi->dev, "problem when reading 32 bit register 0x%02X", + reg_address); + goto error_ret; + } + *val = (st->rx[3] << 24) | (st->rx[4] << 16) | (st->rx[5] << 8) | st->rx[6]; + +error_ret: + mutex_unlock(&st->buf_lock); + return ret; +} + +static int __devinit ade7854_spi_probe(struct spi_device *spi) +{ + int ret; + struct ade7854_state *st = kzalloc(sizeof *st, GFP_KERNEL); + if (!st) { + ret = -ENOMEM; + return ret; + } + + spi_set_drvdata(spi, st); + st->read_reg_8 = ade7854_spi_read_reg_8; + st->read_reg_16 = ade7854_spi_read_reg_16; + st->read_reg_24 = ade7854_spi_read_reg_24; + st->read_reg_32 = ade7854_spi_read_reg_32; + st->write_reg_8 = ade7854_spi_write_reg_8; + st->write_reg_16 = ade7854_spi_write_reg_16; + st->write_reg_24 = ade7854_spi_write_reg_24; + st->write_reg_32 = ade7854_spi_write_reg_32; + st->irq = spi->irq; + st->spi = spi; + + ret = ade7854_probe(st, &spi->dev); + if (ret) { + kfree(st); + return ret; + } + + return 0; +} + +static int ade7854_spi_remove(struct spi_device *spi) +{ + ade7854_remove(spi_get_drvdata(spi)); + + return 0; +} + +static struct spi_driver ade7854_driver = { + .driver = { + .name = "ade7854", + .owner = THIS_MODULE, + }, + .probe = ade7854_spi_probe, + .remove = __devexit_p(ade7854_spi_remove), +}; + +static __init int ade7854_init(void) +{ + return spi_register_driver(&ade7854_driver); +} +module_init(ade7854_init); + +static __exit void ade7854_exit(void) +{ + spi_unregister_driver(&ade7854_driver); +} +module_exit(ade7854_exit); + +MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>"); +MODULE_DESCRIPTION("Analog Devices ADE7854/58/68/78 Polyphase Multifunction Energy Metering IC SPI Driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/staging/iio/meter/ade7854.c b/drivers/staging/iio/meter/ade7854.c new file mode 100644 index 000000000000..a13d5048cf42 --- /dev/null +++ b/drivers/staging/iio/meter/ade7854.c @@ -0,0 +1,680 @@ +/* + * ADE7854/58/68/78 Polyphase Multifunction Energy Metering IC Driver + * + * Copyright 2010 Analog Devices Inc. + * + * Licensed under the GPL-2 or later. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../iio.h" +#include "../sysfs.h" +#include "meter.h" +#include "ade7854.h" + +static ssize_t ade7854_read_8bit(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + int ret; + u8 val = 0; + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct ade7854_state *st = iio_dev_get_devdata(indio_dev); + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + + ret = st->read_reg_8(dev, this_attr->address, &val); + if (ret) + return ret; + + return sprintf(buf, "%u\n", val); +} + +static ssize_t ade7854_read_16bit(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + int ret; + u16 val = 0; + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct ade7854_state *st = iio_dev_get_devdata(indio_dev); + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + + ret = st->read_reg_16(dev, this_attr->address, &val); + if (ret) + return ret; + + return sprintf(buf, "%u\n", val); +} + +static ssize_t ade7854_read_24bit(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + int ret; + u32 val = 0; + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct ade7854_state *st = iio_dev_get_devdata(indio_dev); + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + + ret = st->read_reg_24(dev, this_attr->address, &val); + if (ret) + return ret; + + return sprintf(buf, "%u\n", val & 0xFFFFFF); +} + +static ssize_t ade7854_read_32bit(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + int ret; + u32 val = 0; + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct ade7854_state *st = iio_dev_get_devdata(indio_dev); + + ret = st->read_reg_32(dev, this_attr->address, &val); + if (ret) + return ret; + + return sprintf(buf, "%u\n", val); +} + +static ssize_t ade7854_write_8bit(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct ade7854_state *st = iio_dev_get_devdata(indio_dev); + + int ret; + long val; + + ret = strict_strtol(buf, 10, &val); + if (ret) + goto error_ret; + ret = st->write_reg_8(dev, this_attr->address, val); + +error_ret: + return ret ? ret : len; +} + +static ssize_t ade7854_write_16bit(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct ade7854_state *st = iio_dev_get_devdata(indio_dev); + + int ret; + long val; + + ret = strict_strtol(buf, 10, &val); + if (ret) + goto error_ret; + ret = st->write_reg_16(dev, this_attr->address, val); + +error_ret: + return ret ? ret : len; +} + +static ssize_t ade7854_write_24bit(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct ade7854_state *st = iio_dev_get_devdata(indio_dev); + + int ret; + long val; + + ret = strict_strtol(buf, 10, &val); + if (ret) + goto error_ret; + ret = st->write_reg_24(dev, this_attr->address, val); + +error_ret: + return ret ? ret : len; +} + +static ssize_t ade7854_write_32bit(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct ade7854_state *st = iio_dev_get_devdata(indio_dev); + + int ret; + long val; + + ret = strict_strtol(buf, 10, &val); + if (ret) + goto error_ret; + ret = st->write_reg_32(dev, this_attr->address, val); + +error_ret: + return ret ? ret : len; +} + +static int ade7854_reset(struct device *dev) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct ade7854_state *st = iio_dev_get_devdata(indio_dev); + + int ret; + u16 val; + + st->read_reg_16(dev, ADE7854_CONFIG, &val); + val |= 1 << 7; /* Software Chip Reset */ + ret = st->write_reg_16(dev, ADE7854_CONFIG, val); + + return ret; +} + + +static ssize_t ade7854_write_reset(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t len) +{ + if (len < 1) + return -1; + switch (buf[0]) { + case '1': + case 'y': + case 'Y': + return ade7854_reset(dev); + } + return -1; +} + +static IIO_DEV_ATTR_AIGAIN(S_IWUSR | S_IRUGO, + ade7854_read_24bit, + ade7854_write_24bit, + ADE7854_AIGAIN); +static IIO_DEV_ATTR_BIGAIN(S_IWUSR | S_IRUGO, + ade7854_read_24bit, + ade7854_write_24bit, + ADE7854_BIGAIN); +static IIO_DEV_ATTR_CIGAIN(S_IWUSR | S_IRUGO, + ade7854_read_24bit, + ade7854_write_24bit, + ADE7854_CIGAIN); +static IIO_DEV_ATTR_NIGAIN(S_IWUSR | S_IRUGO, + ade7854_read_24bit, + ade7854_write_24bit, + ADE7854_NIGAIN); +static IIO_DEV_ATTR_AVGAIN(S_IWUSR | S_IRUGO, + ade7854_read_24bit, + ade7854_write_24bit, + ADE7854_AVGAIN); +static IIO_DEV_ATTR_BVGAIN(S_IWUSR | S_IRUGO, + ade7854_read_24bit, + ade7854_write_24bit, + ADE7854_BVGAIN); +static IIO_DEV_ATTR_CVGAIN(S_IWUSR | S_IRUGO, + ade7854_read_24bit, + ade7854_write_24bit, + ADE7854_CVGAIN); +static IIO_DEV_ATTR_APPARENT_POWER_A_GAIN(S_IWUSR | S_IRUGO, + ade7854_read_24bit, + ade7854_write_24bit, + ADE7854_AVAGAIN); +static IIO_DEV_ATTR_APPARENT_POWER_B_GAIN(S_IWUSR | S_IRUGO, + ade7854_read_24bit, + ade7854_write_24bit, + ADE7854_BVAGAIN); +static IIO_DEV_ATTR_APPARENT_POWER_C_GAIN(S_IWUSR | S_IRUGO, + ade7854_read_24bit, + ade7854_write_24bit, + ADE7854_CVAGAIN); +static IIO_DEV_ATTR_ACTIVE_POWER_A_OFFSET(S_IWUSR | S_IRUGO, + ade7854_read_24bit, + ade7854_write_24bit, + ADE7854_AWATTOS); +static IIO_DEV_ATTR_ACTIVE_POWER_B_OFFSET(S_IWUSR | S_IRUGO, + ade7854_read_24bit, + ade7854_write_24bit, + ADE7854_BWATTOS); +static IIO_DEV_ATTR_ACTIVE_POWER_C_OFFSET(S_IWUSR | S_IRUGO, + ade7854_read_24bit, + ade7854_write_24bit, + ADE7854_CWATTOS); +static IIO_DEV_ATTR_REACTIVE_POWER_A_GAIN(S_IWUSR | S_IRUGO, + ade7854_read_24bit, + ade7854_write_24bit, + ADE7854_AVARGAIN); +static IIO_DEV_ATTR_REACTIVE_POWER_B_GAIN(S_IWUSR | S_IRUGO, + ade7854_read_24bit, + ade7854_write_24bit, + ADE7854_BVARGAIN); +static IIO_DEV_ATTR_REACTIVE_POWER_C_GAIN(S_IWUSR | S_IRUGO, + ade7854_read_24bit, + ade7854_write_24bit, + ADE7854_CVARGAIN); +static IIO_DEV_ATTR_REACTIVE_POWER_A_OFFSET(S_IWUSR | S_IRUGO, + ade7854_read_24bit, + ade7854_write_24bit, + ADE7854_AVAROS); +static IIO_DEV_ATTR_REACTIVE_POWER_B_OFFSET(S_IWUSR | S_IRUGO, + ade7854_read_24bit, + ade7854_write_24bit, + ADE7854_BVAROS); +static IIO_DEV_ATTR_REACTIVE_POWER_C_OFFSET(S_IWUSR | S_IRUGO, + ade7854_read_24bit, + ade7854_write_24bit, + ADE7854_CVAROS); +static IIO_DEV_ATTR_VPEAK(S_IWUSR | S_IRUGO, + ade7854_read_32bit, + ade7854_write_32bit, + ADE7854_VPEAK); +static IIO_DEV_ATTR_IPEAK(S_IWUSR | S_IRUGO, + ade7854_read_32bit, + ade7854_write_32bit, + ADE7854_VPEAK); +static IIO_DEV_ATTR_APHCAL(S_IWUSR | S_IRUGO, + ade7854_read_16bit, + ade7854_write_16bit, + ADE7854_APHCAL); +static IIO_DEV_ATTR_BPHCAL(S_IWUSR | S_IRUGO, + ade7854_read_16bit, + ade7854_write_16bit, + ADE7854_BPHCAL); +static IIO_DEV_ATTR_CPHCAL(S_IWUSR | S_IRUGO, + ade7854_read_16bit, + ade7854_write_16bit, + ADE7854_CPHCAL); +static IIO_DEV_ATTR_CF1DEN(S_IWUSR | S_IRUGO, + ade7854_read_16bit, + ade7854_write_16bit, + ADE7854_CF1DEN); +static IIO_DEV_ATTR_CF2DEN(S_IWUSR | S_IRUGO, + ade7854_read_16bit, + ade7854_write_16bit, + ADE7854_CF2DEN); +static IIO_DEV_ATTR_CF3DEN(S_IWUSR | S_IRUGO, + ade7854_read_16bit, + ade7854_write_16bit, + ADE7854_CF3DEN); +static IIO_DEV_ATTR_LINECYC(S_IWUSR | S_IRUGO, + ade7854_read_16bit, + ade7854_write_16bit, + ADE7854_LINECYC); +static IIO_DEV_ATTR_SAGCYC(S_IWUSR | S_IRUGO, + ade7854_read_8bit, + ade7854_write_8bit, + ADE7854_SAGCYC); +static IIO_DEV_ATTR_CFCYC(S_IWUSR | S_IRUGO, + ade7854_read_8bit, + ade7854_write_8bit, + ADE7854_CFCYC); +static IIO_DEV_ATTR_PEAKCYC(S_IWUSR | S_IRUGO, + ade7854_read_8bit, + ade7854_write_8bit, + ADE7854_PEAKCYC); +static IIO_DEV_ATTR_CHKSUM(ade7854_read_24bit, + ADE7854_CHECKSUM); +static IIO_DEV_ATTR_ANGLE0(ade7854_read_24bit, + ADE7854_ANGLE0); +static IIO_DEV_ATTR_ANGLE1(ade7854_read_24bit, + ADE7854_ANGLE1); +static IIO_DEV_ATTR_ANGLE2(ade7854_read_24bit, + ADE7854_ANGLE2); +static IIO_DEV_ATTR_AIRMS(S_IRUGO, + ade7854_read_24bit, + NULL, + ADE7854_AIRMS); +static IIO_DEV_ATTR_BIRMS(S_IRUGO, + ade7854_read_24bit, + NULL, + ADE7854_BIRMS); +static IIO_DEV_ATTR_CIRMS(S_IRUGO, + ade7854_read_24bit, + NULL, + ADE7854_CIRMS); +static IIO_DEV_ATTR_NIRMS(S_IRUGO, + ade7854_read_24bit, + NULL, + ADE7854_NIRMS); +static IIO_DEV_ATTR_AVRMS(S_IRUGO, + ade7854_read_24bit, + NULL, + ADE7854_AVRMS); +static IIO_DEV_ATTR_BVRMS(S_IRUGO, + ade7854_read_24bit, + NULL, + ADE7854_BVRMS); +static IIO_DEV_ATTR_CVRMS(S_IRUGO, + ade7854_read_24bit, + NULL, + ADE7854_CVRMS); +static IIO_DEV_ATTR_AIRMSOS(S_IRUGO, + ade7854_read_16bit, + ade7854_write_16bit, + ADE7854_AIRMSOS); +static IIO_DEV_ATTR_BIRMSOS(S_IRUGO, + ade7854_read_16bit, + ade7854_write_16bit, + ADE7854_BIRMSOS); +static IIO_DEV_ATTR_CIRMSOS(S_IRUGO, + ade7854_read_16bit, + ade7854_write_16bit, + ADE7854_CIRMSOS); +static IIO_DEV_ATTR_AVRMSOS(S_IRUGO, + ade7854_read_16bit, + ade7854_write_16bit, + ADE7854_AVRMSOS); +static IIO_DEV_ATTR_BVRMSOS(S_IRUGO, + ade7854_read_16bit, + ade7854_write_16bit, + ADE7854_BVRMSOS); +static IIO_DEV_ATTR_CVRMSOS(S_IRUGO, + ade7854_read_16bit, + ade7854_write_16bit, + ADE7854_CVRMSOS); +static IIO_DEV_ATTR_VOLT_A(ade7854_read_24bit, + ADE7854_VAWV); +static IIO_DEV_ATTR_VOLT_B(ade7854_read_24bit, + ADE7854_VBWV); +static IIO_DEV_ATTR_VOLT_C(ade7854_read_24bit, + ADE7854_VCWV); +static IIO_DEV_ATTR_CURRENT_A(ade7854_read_24bit, + ADE7854_IAWV); +static IIO_DEV_ATTR_CURRENT_B(ade7854_read_24bit, + ADE7854_IBWV); +static IIO_DEV_ATTR_CURRENT_C(ade7854_read_24bit, + ADE7854_ICWV); +static IIO_DEV_ATTR_AWATTHR(ade7854_read_32bit, + ADE7854_AWATTHR); +static IIO_DEV_ATTR_BWATTHR(ade7854_read_32bit, + ADE7854_BWATTHR); +static IIO_DEV_ATTR_CWATTHR(ade7854_read_32bit, + ADE7854_CWATTHR); +static IIO_DEV_ATTR_AFWATTHR(ade7854_read_32bit, + ADE7854_AFWATTHR); +static IIO_DEV_ATTR_BFWATTHR(ade7854_read_32bit, + ADE7854_BFWATTHR); +static IIO_DEV_ATTR_CFWATTHR(ade7854_read_32bit, + ADE7854_CFWATTHR); +static IIO_DEV_ATTR_AVARHR(ade7854_read_32bit, + ADE7854_AVARHR); +static IIO_DEV_ATTR_BVARHR(ade7854_read_32bit, + ADE7854_BVARHR); +static IIO_DEV_ATTR_CVARHR(ade7854_read_32bit, + ADE7854_CVARHR); +static IIO_DEV_ATTR_AVAHR(ade7854_read_32bit, + ADE7854_AVAHR); +static IIO_DEV_ATTR_BVAHR(ade7854_read_32bit, + ADE7854_BVAHR); +static IIO_DEV_ATTR_CVAHR(ade7854_read_32bit, + ADE7854_CVAHR); + +static int ade7854_set_irq(struct device *dev, bool enable) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct ade7854_state *st = iio_dev_get_devdata(indio_dev); + + int ret; + u32 irqen; + + ret = st->read_reg_32(dev, ADE7854_MASK0, &irqen); + if (ret) + goto error_ret; + + if (enable) + irqen |= 1 << 17; /* 1: interrupt enabled when all periodical + (at 8 kHz rate) DSP computations finish. */ + else + irqen &= ~(1 << 17); + + ret = st->write_reg_32(dev, ADE7854_MASK0, irqen); + if (ret) + goto error_ret; + +error_ret: + return ret; +} + +static int ade7854_initial_setup(struct ade7854_state *st) +{ + int ret; + struct device *dev = &st->indio_dev->dev; + + /* Disable IRQ */ + ret = ade7854_set_irq(dev, false); + if (ret) { + dev_err(dev, "disable irq failed"); + goto err_ret; + } + + ade7854_reset(dev); + msleep(ADE7854_STARTUP_DELAY); + +err_ret: + return ret; +} + +static IIO_DEV_ATTR_RESET(ade7854_write_reset); + +static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("8000"); + +static IIO_CONST_ATTR(name, "ade7854"); + +static struct attribute *ade7854_event_attributes[] = { + NULL +}; + +static struct attribute_group ade7854_event_attribute_group = { + .attrs = ade7854_event_attributes, +}; + +static struct attribute *ade7854_attributes[] = { + &iio_dev_attr_aigain.dev_attr.attr, + &iio_dev_attr_bigain.dev_attr.attr, + &iio_dev_attr_cigain.dev_attr.attr, + &iio_dev_attr_nigain.dev_attr.attr, + &iio_dev_attr_avgain.dev_attr.attr, + &iio_dev_attr_bvgain.dev_attr.attr, + &iio_dev_attr_cvgain.dev_attr.attr, + &iio_dev_attr_linecyc.dev_attr.attr, + &iio_dev_attr_sagcyc.dev_attr.attr, + &iio_dev_attr_cfcyc.dev_attr.attr, + &iio_dev_attr_peakcyc.dev_attr.attr, + &iio_dev_attr_chksum.dev_attr.attr, + &iio_dev_attr_apparent_power_a_gain.dev_attr.attr, + &iio_dev_attr_apparent_power_b_gain.dev_attr.attr, + &iio_dev_attr_apparent_power_c_gain.dev_attr.attr, + &iio_dev_attr_active_power_a_offset.dev_attr.attr, + &iio_dev_attr_active_power_b_offset.dev_attr.attr, + &iio_dev_attr_active_power_c_offset.dev_attr.attr, + &iio_dev_attr_reactive_power_a_gain.dev_attr.attr, + &iio_dev_attr_reactive_power_b_gain.dev_attr.attr, + &iio_dev_attr_reactive_power_c_gain.dev_attr.attr, + &iio_dev_attr_reactive_power_a_offset.dev_attr.attr, + &iio_dev_attr_reactive_power_b_offset.dev_attr.attr, + &iio_dev_attr_reactive_power_c_offset.dev_attr.attr, + &iio_dev_attr_awatthr.dev_attr.attr, + &iio_dev_attr_bwatthr.dev_attr.attr, + &iio_dev_attr_cwatthr.dev_attr.attr, + &iio_dev_attr_afwatthr.dev_attr.attr, + &iio_dev_attr_bfwatthr.dev_attr.attr, + &iio_dev_attr_cfwatthr.dev_attr.attr, + &iio_dev_attr_avarhr.dev_attr.attr, + &iio_dev_attr_bvarhr.dev_attr.attr, + &iio_dev_attr_cvarhr.dev_attr.attr, + &iio_dev_attr_angle0.dev_attr.attr, + &iio_dev_attr_angle1.dev_attr.attr, + &iio_dev_attr_angle2.dev_attr.attr, + &iio_dev_attr_avahr.dev_attr.attr, + &iio_dev_attr_bvahr.dev_attr.attr, + &iio_dev_attr_cvahr.dev_attr.attr, + &iio_const_attr_sampling_frequency_available.dev_attr.attr, + &iio_dev_attr_reset.dev_attr.attr, + &iio_const_attr_name.dev_attr.attr, + &iio_dev_attr_vpeak.dev_attr.attr, + &iio_dev_attr_ipeak.dev_attr.attr, + &iio_dev_attr_aphcal.dev_attr.attr, + &iio_dev_attr_bphcal.dev_attr.attr, + &iio_dev_attr_cphcal.dev_attr.attr, + &iio_dev_attr_cf1den.dev_attr.attr, + &iio_dev_attr_cf2den.dev_attr.attr, + &iio_dev_attr_cf3den.dev_attr.attr, + &iio_dev_attr_airms.dev_attr.attr, + &iio_dev_attr_birms.dev_attr.attr, + &iio_dev_attr_cirms.dev_attr.attr, + &iio_dev_attr_nirms.dev_attr.attr, + &iio_dev_attr_avrms.dev_attr.attr, + &iio_dev_attr_bvrms.dev_attr.attr, + &iio_dev_attr_cvrms.dev_attr.attr, + &iio_dev_attr_airmsos.dev_attr.attr, + &iio_dev_attr_birmsos.dev_attr.attr, + &iio_dev_attr_cirmsos.dev_attr.attr, + &iio_dev_attr_avrmsos.dev_attr.attr, + &iio_dev_attr_bvrmsos.dev_attr.attr, + &iio_dev_attr_cvrmsos.dev_attr.attr, + &iio_dev_attr_volt_a.dev_attr.attr, + &iio_dev_attr_volt_b.dev_attr.attr, + &iio_dev_attr_volt_c.dev_attr.attr, + &iio_dev_attr_current_a.dev_attr.attr, + &iio_dev_attr_current_b.dev_attr.attr, + &iio_dev_attr_current_c.dev_attr.attr, + NULL, +}; + +static const struct attribute_group ade7854_attribute_group = { + .attrs = ade7854_attributes, +}; + +int ade7854_probe(struct ade7854_state *st, struct device *dev) +{ + int ret, regdone = 0; + + /* Allocate the comms buffers */ + st->rx = kzalloc(sizeof(*st->rx)*ADE7854_MAX_RX, GFP_KERNEL); + if (st->rx == NULL) { + ret = -ENOMEM; + goto error_free_st; + } + st->tx = kzalloc(sizeof(*st->tx)*ADE7854_MAX_TX, GFP_KERNEL); + if (st->tx == NULL) { + ret = -ENOMEM; + goto error_free_rx; + } + mutex_init(&st->buf_lock); + /* setup the industrialio driver allocated elements */ + st->indio_dev = iio_allocate_device(); + if (st->indio_dev == NULL) { + ret = -ENOMEM; + goto error_free_tx; + } + + st->indio_dev->dev.parent = dev; + st->indio_dev->num_interrupt_lines = 1; + st->indio_dev->event_attrs = &ade7854_event_attribute_group; + st->indio_dev->attrs = &ade7854_attribute_group; + st->indio_dev->dev_data = (void *)(st); + st->indio_dev->driver_module = THIS_MODULE; + st->indio_dev->modes = INDIO_DIRECT_MODE; + + ret = ade7854_configure_ring(st->indio_dev); + if (ret) + goto error_free_dev; + + ret = iio_device_register(st->indio_dev); + if (ret) + goto error_unreg_ring_funcs; + regdone = 1; + + ret = ade7854_initialize_ring(st->indio_dev->ring); + if (ret) { + printk(KERN_ERR "failed to initialize the ring\n"); + goto error_unreg_ring_funcs; + } + + if (st->irq) { + ret = iio_register_interrupt_line(st->irq, + st->indio_dev, + 0, + IRQF_TRIGGER_FALLING, + "ade7854"); + if (ret) + goto error_uninitialize_ring; + + ret = ade7854_probe_trigger(st->indio_dev); + if (ret) + goto error_unregister_line; + } + /* Get the device into a sane initial state */ + ret = ade7854_initial_setup(st); + if (ret) + goto error_remove_trigger; + + return 0; + +error_remove_trigger: + if (st->indio_dev->modes & INDIO_RING_TRIGGERED) + ade7854_remove_trigger(st->indio_dev); +error_unregister_line: + if (st->indio_dev->modes & INDIO_RING_TRIGGERED) + iio_unregister_interrupt_line(st->indio_dev, 0); +error_uninitialize_ring: + ade7854_uninitialize_ring(st->indio_dev->ring); +error_unreg_ring_funcs: + ade7854_unconfigure_ring(st->indio_dev); +error_free_dev: + if (regdone) + iio_device_unregister(st->indio_dev); + else + iio_free_device(st->indio_dev); +error_free_tx: + kfree(st->tx); +error_free_rx: + kfree(st->rx); +error_free_st: + kfree(st); + return ret; + +} +EXPORT_SYMBOL(ade7854_probe); + +int ade7854_remove(struct ade7854_state *st) +{ + struct iio_dev *indio_dev = st->indio_dev; + + flush_scheduled_work(); + + ade7854_remove_trigger(indio_dev); + if (st->irq) + iio_unregister_interrupt_line(indio_dev, 0); + + ade7854_uninitialize_ring(indio_dev->ring); + ade7854_unconfigure_ring(indio_dev); + iio_device_unregister(indio_dev); + kfree(st->tx); + kfree(st->rx); + kfree(st); + + return 0; +} +EXPORT_SYMBOL(ade7854_remove); + +MODULE_AUTHOR("Barry Song <21cnbao@gmail.com>"); +MODULE_DESCRIPTION("Analog Devices ADE7854/58/68/78 Polyphase Multifunction Energy Metering IC Driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/staging/iio/meter/ade7854.h b/drivers/staging/iio/meter/ade7854.h new file mode 100644 index 000000000000..47690e521ec1 --- /dev/null +++ b/drivers/staging/iio/meter/ade7854.h @@ -0,0 +1,245 @@ +#ifndef _ADE7854_H +#define _ADE7854_H + +#define ADE7854_AIGAIN 0x4380 +#define ADE7854_AVGAIN 0x4381 +#define ADE7854_BIGAIN 0x4382 +#define ADE7854_BVGAIN 0x4383 +#define ADE7854_CIGAIN 0x4384 +#define ADE7854_CVGAIN 0x4385 +#define ADE7854_NIGAIN 0x4386 +#define ADE7854_AIRMSOS 0x4387 +#define ADE7854_AVRMSOS 0x4388 +#define ADE7854_BIRMSOS 0x4389 +#define ADE7854_BVRMSOS 0x438A +#define ADE7854_CIRMSOS 0x438B +#define ADE7854_CVRMSOS 0x438C +#define ADE7854_NIRMSOS 0x438D +#define ADE7854_AVAGAIN 0x438E +#define ADE7854_BVAGAIN 0x438F +#define ADE7854_CVAGAIN 0x4390 +#define ADE7854_AWGAIN 0x4391 +#define ADE7854_AWATTOS 0x4392 +#define ADE7854_BWGAIN 0x4393 +#define ADE7854_BWATTOS 0x4394 +#define ADE7854_CWGAIN 0x4395 +#define ADE7854_CWATTOS 0x4396 +#define ADE7854_AVARGAIN 0x4397 +#define ADE7854_AVAROS 0x4398 +#define ADE7854_BVARGAIN 0x4399 +#define ADE7854_BVAROS 0x439A +#define ADE7854_CVARGAIN 0x439B +#define ADE7854_CVAROS 0x439C +#define ADE7854_AFWGAIN 0x439D +#define ADE7854_AFWATTOS 0x439E +#define ADE7854_BFWGAIN 0x439F +#define ADE7854_BFWATTOS 0x43A0 +#define ADE7854_CFWGAIN 0x43A1 +#define ADE7854_CFWATTOS 0x43A2 +#define ADE7854_AFVARGAIN 0x43A3 +#define ADE7854_AFVAROS 0x43A4 +#define ADE7854_BFVARGAIN 0x43A5 +#define ADE7854_BFVAROS 0x43A6 +#define ADE7854_CFVARGAIN 0x43A7 +#define ADE7854_CFVAROS 0x43A8 +#define ADE7854_VATHR1 0x43A9 +#define ADE7854_VATHR0 0x43AA +#define ADE7854_WTHR1 0x43AB +#define ADE7854_WTHR0 0x43AC +#define ADE7854_VARTHR1 0x43AD +#define ADE7854_VARTHR0 0x43AE +#define ADE7854_RSV 0x43AF +#define ADE7854_VANOLOAD 0x43B0 +#define ADE7854_APNOLOAD 0x43B1 +#define ADE7854_VARNOLOAD 0x43B2 +#define ADE7854_VLEVEL 0x43B3 +#define ADE7854_DICOEFF 0x43B5 +#define ADE7854_HPFDIS 0x43B6 +#define ADE7854_ISUMLVL 0x43B8 +#define ADE7854_ISUM 0x43BF +#define ADE7854_AIRMS 0x43C0 +#define ADE7854_AVRMS 0x43C1 +#define ADE7854_BIRMS 0x43C2 +#define ADE7854_BVRMS 0x43C3 +#define ADE7854_CIRMS 0x43C4 +#define ADE7854_CVRMS 0x43C5 +#define ADE7854_NIRMS 0x43C6 +#define ADE7854_RUN 0xE228 +#define ADE7854_AWATTHR 0xE400 +#define ADE7854_BWATTHR 0xE401 +#define ADE7854_CWATTHR 0xE402 +#define ADE7854_AFWATTHR 0xE403 +#define ADE7854_BFWATTHR 0xE404 +#define ADE7854_CFWATTHR 0xE405 +#define ADE7854_AVARHR 0xE406 +#define ADE7854_BVARHR 0xE407 +#define ADE7854_CVARHR 0xE408 +#define ADE7854_AFVARHR 0xE409 +#define ADE7854_BFVARHR 0xE40A +#define ADE7854_CFVARHR 0xE40B +#define ADE7854_AVAHR 0xE40C +#define ADE7854_BVAHR 0xE40D +#define ADE7854_CVAHR 0xE40E +#define ADE7854_IPEAK 0xE500 +#define ADE7854_VPEAK 0xE501 +#define ADE7854_STATUS0 0xE502 +#define ADE7854_STATUS1 0xE503 +#define ADE7854_OILVL 0xE507 +#define ADE7854_OVLVL 0xE508 +#define ADE7854_SAGLVL 0xE509 +#define ADE7854_MASK0 0xE50A +#define ADE7854_MASK1 0xE50B +#define ADE7854_IAWV 0xE50C +#define ADE7854_IBWV 0xE50D +#define ADE7854_ICWV 0xE50E +#define ADE7854_VAWV 0xE510 +#define ADE7854_VBWV 0xE511 +#define ADE7854_VCWV 0xE512 +#define ADE7854_AWATT 0xE513 +#define ADE7854_BWATT 0xE514 +#define ADE7854_CWATT 0xE515 +#define ADE7854_AVA 0xE519 +#define ADE7854_BVA 0xE51A +#define ADE7854_CVA 0xE51B +#define ADE7854_CHECKSUM 0xE51F +#define ADE7854_VNOM 0xE520 +#define ADE7854_PHSTATUS 0xE600 +#define ADE7854_ANGLE0 0xE601 +#define ADE7854_ANGLE1 0xE602 +#define ADE7854_ANGLE2 0xE603 +#define ADE7854_PERIOD 0xE607 +#define ADE7854_PHNOLOAD 0xE608 +#define ADE7854_LINECYC 0xE60C +#define ADE7854_ZXTOUT 0xE60D +#define ADE7854_COMPMODE 0xE60E +#define ADE7854_GAIN 0xE60F +#define ADE7854_CFMODE 0xE610 +#define ADE7854_CF1DEN 0xE611 +#define ADE7854_CF2DEN 0xE612 +#define ADE7854_CF3DEN 0xE613 +#define ADE7854_APHCAL 0xE614 +#define ADE7854_BPHCAL 0xE615 +#define ADE7854_CPHCAL 0xE616 +#define ADE7854_PHSIGN 0xE617 +#define ADE7854_CONFIG 0xE618 +#define ADE7854_MMODE 0xE700 +#define ADE7854_ACCMODE 0xE701 +#define ADE7854_LCYCMODE 0xE702 +#define ADE7854_PEAKCYC 0xE703 +#define ADE7854_SAGCYC 0xE704 +#define ADE7854_CFCYC 0xE705 +#define ADE7854_HSDC_CFG 0xE706 +#define ADE7854_CONFIG2 0xEC01 + +#define ADE7854_READ_REG 0x1 +#define ADE7854_WRITE_REG 0x0 + +#define ADE7854_MAX_TX 7 +#define ADE7854_MAX_RX 7 +#define ADE7854_STARTUP_DELAY 1 + +#define ADE7854_SPI_SLOW (u32)(300 * 1000) +#define ADE7854_SPI_BURST (u32)(1000 * 1000) +#define ADE7854_SPI_FAST (u32)(2000 * 1000) + +#define DRIVER_NAME "ade7854" + +/** + * struct ade7854_state - device instance specific data + * @spi: actual spi_device + * @work_trigger_to_ring: bh for triggered event handling + * @inter: used to check if new interrupt has been triggered + * @last_timestamp: passing timestamp from th to bh of interrupt handler + * @indio_dev: industrial I/O device structure + * @trig: data ready trigger registered with iio + * @tx: transmit buffer + * @rx: recieve buffer + * @buf_lock: mutex to protect tx and rx + **/ +struct ade7854_state { + struct spi_device *spi; + struct i2c_client *i2c; + struct work_struct work_trigger_to_ring; + s64 last_timestamp; + struct iio_dev *indio_dev; + struct iio_trigger *trig; + u8 *tx; + u8 *rx; + int (*read_reg_8) (struct device *, u16, u8 *); + int (*read_reg_16) (struct device *, u16, u16 *); + int (*read_reg_24) (struct device *, u16, u32 *); + int (*read_reg_32) (struct device *, u16, u32 *); + int (*write_reg_8) (struct device *, u16, u8); + int (*write_reg_16) (struct device *, u16, u16); + int (*write_reg_24) (struct device *, u16, u32); + int (*write_reg_32) (struct device *, u16, u32); + int irq; + struct mutex buf_lock; +}; + +extern int ade7854_probe(struct ade7854_state *st, struct device *dev); +extern int ade7854_remove(struct ade7854_state *st); + +#if defined(CONFIG_IIO_RING_BUFFER) && defined(THIS_HAS_RING_BUFFER_SUPPORT) +/* At the moment triggers are only used for ring buffer + * filling. This may change! + */ + +enum ade7854_scan { + ADE7854_SCAN_PHA_V, + ADE7854_SCAN_PHB_V, + ADE7854_SCAN_PHC_V, + ADE7854_SCAN_PHA_I, + ADE7854_SCAN_PHB_I, + ADE7854_SCAN_PHC_I, +}; + +void ade7854_remove_trigger(struct iio_dev *indio_dev); +int ade7854_probe_trigger(struct iio_dev *indio_dev); + +ssize_t ade7854_read_data_from_ring(struct device *dev, + struct device_attribute *attr, + char *buf); + + +int ade7854_configure_ring(struct iio_dev *indio_dev); +void ade7854_unconfigure_ring(struct iio_dev *indio_dev); + +int ade7854_initialize_ring(struct iio_ring_buffer *ring); +void ade7854_uninitialize_ring(struct iio_ring_buffer *ring); +#else /* CONFIG_IIO_RING_BUFFER */ + +static inline void ade7854_remove_trigger(struct iio_dev *indio_dev) +{ +} +static inline int ade7854_probe_trigger(struct iio_dev *indio_dev) +{ + return 0; +} + +static inline ssize_t +ade7854_read_data_from_ring(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + return 0; +} + +static inline int ade7854_configure_ring(struct iio_dev *indio_dev) +{ + return 0; +} + +static inline void ade7854_unconfigure_ring(struct iio_dev *indio_dev) +{ +} +static inline int ade7854_initialize_ring(struct iio_ring_buffer *ring) +{ + return 0; +} +static inline void ade7854_uninitialize_ring(struct iio_ring_buffer *ring) +{ +} +#endif /* CONFIG_IIO_RING_BUFFER */ + +#endif -- cgit v1.2.3 From f46d9f154ac3001b90e75ca646400a13b499a49e Mon Sep 17 00:00:00 2001 From: Graf Yang Date: Wed, 27 Oct 2010 21:44:19 -0400 Subject: staging: iio: resolver: new driver for AD2S90 devices This also kicks off the new resolver subsection. Signed-off-by: Graf Yang Signed-off-by: Michael Hennerich Acked-by: Jonathan Cameron Signed-off-by: Mike Frysinger Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/Kconfig | 1 + drivers/staging/iio/Makefile | 1 + drivers/staging/iio/resolver/Kconfig | 11 +++ drivers/staging/iio/resolver/Makefile | 5 ++ drivers/staging/iio/resolver/ad2s90.c | 159 ++++++++++++++++++++++++++++++++++ 5 files changed, 177 insertions(+) create mode 100644 drivers/staging/iio/resolver/Kconfig create mode 100644 drivers/staging/iio/resolver/Makefile create mode 100644 drivers/staging/iio/resolver/ad2s90.c diff --git a/drivers/staging/iio/Kconfig b/drivers/staging/iio/Kconfig index ffe8912bd7ab..e2ac07d86110 100644 --- a/drivers/staging/iio/Kconfig +++ b/drivers/staging/iio/Kconfig @@ -50,6 +50,7 @@ source "drivers/staging/iio/imu/Kconfig" source "drivers/staging/iio/light/Kconfig" source "drivers/staging/iio/magnetometer/Kconfig" source "drivers/staging/iio/meter/Kconfig" +source "drivers/staging/iio/resolver/Kconfig" source "drivers/staging/iio/trigger/Kconfig" endif # IIO diff --git a/drivers/staging/iio/Makefile b/drivers/staging/iio/Makefile index 5b449a15e5aa..f9b5fb2fe8f1 100644 --- a/drivers/staging/iio/Makefile +++ b/drivers/staging/iio/Makefile @@ -19,4 +19,5 @@ obj-y += imu/ obj-y += light/ obj-y += magnetometer/ obj-y += meter/ +obj-y += resolver/ obj-y += trigger/ diff --git a/drivers/staging/iio/resolver/Kconfig b/drivers/staging/iio/resolver/Kconfig new file mode 100644 index 000000000000..05b15a909855 --- /dev/null +++ b/drivers/staging/iio/resolver/Kconfig @@ -0,0 +1,11 @@ +# +# Resolver/Synchro drivers +# +comment "Resolver to digital converters" + +config AD2S90 + tristate "Analog Devices ad2s90 driver" + depends on SPI + help + Say yes here to build support for Analog Devices spi resolver + to digital converters, ad2s90, provides direct access via sysfs. diff --git a/drivers/staging/iio/resolver/Makefile b/drivers/staging/iio/resolver/Makefile new file mode 100644 index 000000000000..067fa7044156 --- /dev/null +++ b/drivers/staging/iio/resolver/Makefile @@ -0,0 +1,5 @@ +# +# Makefile for Resolver/Synchro drivers +# + +obj-$(CONFIG_AD2S90) += ad2s90.o diff --git a/drivers/staging/iio/resolver/ad2s90.c b/drivers/staging/iio/resolver/ad2s90.c new file mode 100644 index 000000000000..4143535242d9 --- /dev/null +++ b/drivers/staging/iio/resolver/ad2s90.c @@ -0,0 +1,159 @@ +/* + * ad2s90.c simple support for the ADI Resolver to Digital Converters: AD2S90 + * + * Copyright (c) 2010-2010 Analog Devices Inc. + * + * 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 +#include +#include + +#include "../iio.h" +#include "../sysfs.h" + +#define DRV_NAME "ad2s90" + +struct ad2s90_state { + struct mutex lock; + struct iio_dev *idev; + struct spi_device *sdev; + u8 rx[2]; + u8 tx[2]; +}; + +static ssize_t ad2s90_show_angular(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct spi_message msg; + struct spi_transfer xfer; + int ret; + ssize_t len = 0; + u16 val; + struct iio_dev *idev = dev_get_drvdata(dev); + struct ad2s90_state *st = idev->dev_data; + + xfer.len = 1; + xfer.tx_buf = st->tx; + xfer.rx_buf = st->rx; + mutex_lock(&st->lock); + + spi_message_init(&msg); + spi_message_add_tail(&xfer, &msg); + ret = spi_sync(st->sdev, &msg); + if (ret) + goto error_ret; + val = (((u16)(st->rx[0])) << 4) | ((st->rx[1] & 0xF0) >> 4); + len = sprintf(buf, "%d\n", val); +error_ret: + mutex_unlock(&st->lock); + + return ret ? ret : len; +} + +#define IIO_DEV_ATTR_SIMPLE_RESOLVER(_show) \ + IIO_DEVICE_ATTR(angular, S_IRUGO, _show, NULL, 0) + +static IIO_CONST_ATTR(description, + "Low Cost, Complete 12-Bit Resolver-to-Digital Converter"); +static IIO_DEV_ATTR_SIMPLE_RESOLVER(ad2s90_show_angular); + +static struct attribute *ad2s90_attributes[] = { + &iio_const_attr_description.dev_attr.attr, + &iio_dev_attr_angular.dev_attr.attr, + NULL, +}; + +static const struct attribute_group ad2s90_attribute_group = { + .name = DRV_NAME, + .attrs = ad2s90_attributes, +}; + +static int __devinit ad2s90_probe(struct spi_device *spi) +{ + struct ad2s90_state *st; + int ret = 0; + + st = kzalloc(sizeof(*st), GFP_KERNEL); + if (st == NULL) { + ret = -ENOMEM; + goto error_ret; + } + spi_set_drvdata(spi, st); + + mutex_init(&st->lock); + st->sdev = spi; + + st->idev = iio_allocate_device(); + if (st->idev == NULL) { + ret = -ENOMEM; + goto error_free_st; + } + st->idev->dev.parent = &spi->dev; + st->idev->num_interrupt_lines = 0; + st->idev->event_attrs = NULL; + + st->idev->attrs = &ad2s90_attribute_group; + st->idev->dev_data = (void *)(st); + st->idev->driver_module = THIS_MODULE; + st->idev->modes = INDIO_DIRECT_MODE; + + ret = iio_device_register(st->idev); + if (ret) + goto error_free_dev; + + /* need 600ns between CS and the first falling edge of SCLK */ + spi->max_speed_hz = 830000; + spi->mode = SPI_MODE_3; + spi_setup(spi); + + return 0; + +error_free_dev: + iio_free_device(st->idev); +error_free_st: + kfree(st); +error_ret: + return ret; +} + +static int __devexit ad2s90_remove(struct spi_device *spi) +{ + struct ad2s90_state *st = spi_get_drvdata(spi); + + iio_device_unregister(st->idev); + kfree(st); + + return 0; +} + +static struct spi_driver ad2s90_driver = { + .driver = { + .name = DRV_NAME, + .owner = THIS_MODULE, + }, + .probe = ad2s90_probe, + .remove = __devexit_p(ad2s90_remove), +}; + +static __init int ad2s90_spi_init(void) +{ + return spi_register_driver(&ad2s90_driver); +} +module_init(ad2s90_spi_init); + +static __exit void ad2s90_spi_exit(void) +{ + spi_unregister_driver(&ad2s90_driver); +} +module_exit(ad2s90_spi_exit); + +MODULE_AUTHOR("Graff Yang "); +MODULE_DESCRIPTION("Analog Devices AD2S90 Resolver to Digital SPI driver"); +MODULE_LICENSE("GPL v2"); -- cgit v1.2.3 From ffd7a62f0dffa92409dc769562a4997eb424a7d3 Mon Sep 17 00:00:00 2001 From: Graf Yang Date: Wed, 27 Oct 2010 21:44:20 -0400 Subject: staging: iio: resolver: new driver for AD2S1200/1205 devices Signed-off-by: Graf Yang Signed-off-by: Michael Hennerich Acked-by: Jonathan Cameron Signed-off-by: Mike Frysinger Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/resolver/Kconfig | 8 + drivers/staging/iio/resolver/Makefile | 1 + drivers/staging/iio/resolver/ad2s120x.c | 310 ++++++++++++++++++++++++++++++++ 3 files changed, 319 insertions(+) create mode 100644 drivers/staging/iio/resolver/ad2s120x.c diff --git a/drivers/staging/iio/resolver/Kconfig b/drivers/staging/iio/resolver/Kconfig index 05b15a909855..32df73aeb0c5 100644 --- a/drivers/staging/iio/resolver/Kconfig +++ b/drivers/staging/iio/resolver/Kconfig @@ -9,3 +9,11 @@ config AD2S90 help Say yes here to build support for Analog Devices spi resolver to digital converters, ad2s90, provides direct access via sysfs. + +config AD2S120X + tristate "Analog Devices ad2s120x driver" + depends on SPI + help + Say yes here to build support for Analog Devices spi resolver + to digital converters, ad2s1200 and ad2s1205, provides direct access + via sysfs. diff --git a/drivers/staging/iio/resolver/Makefile b/drivers/staging/iio/resolver/Makefile index 067fa7044156..b2b3cc1ddc67 100644 --- a/drivers/staging/iio/resolver/Makefile +++ b/drivers/staging/iio/resolver/Makefile @@ -3,3 +3,4 @@ # obj-$(CONFIG_AD2S90) += ad2s90.o +obj-$(CONFIG_AD2S120X) += ad2s120x.o diff --git a/drivers/staging/iio/resolver/ad2s120x.c b/drivers/staging/iio/resolver/ad2s120x.c new file mode 100644 index 000000000000..8f497a23976c --- /dev/null +++ b/drivers/staging/iio/resolver/ad2s120x.c @@ -0,0 +1,310 @@ +/* + * ad2s120x.c simple support for the ADI Resolver to Digital Converters: AD2S1200/1205 + * + * Copyright (c) 2010-2010 Analog Devices Inc. + * + * 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 +#include +#include +#include +#include + +#include "../iio.h" +#include "../sysfs.h" + +#define DRV_NAME "ad2s120x" + +/* input pin sample and rdvel is controlled by driver */ +#define AD2S120X_PN 2 + +/* input clock on serial interface */ +#define AD2S120X_HZ 8192000 +/* clock period in nano second */ +#define AD2S120X_TSCLK (1000000000/AD2S120X_HZ) + +struct ad2s120x_state { + struct mutex lock; + struct iio_dev *idev; + struct spi_device *sdev; + unsigned short sample; + unsigned short rdvel; + u8 rx[2]; + u8 tx[2]; +}; + +static ssize_t ad2s120x_show_pos_vel(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct spi_message msg; + struct spi_transfer xfer; + int ret = 0; + ssize_t len = 0; + u16 pos; + s16 vel; + u8 status; + struct iio_dev *idev = dev_get_drvdata(dev); + struct ad2s120x_state *st = idev->dev_data; + + xfer.len = 1; + xfer.tx_buf = st->tx; + xfer.rx_buf = st->rx; + mutex_lock(&st->lock); + + gpio_set_value(st->sample, 0); + /* delay (6 * AD2S120X_TSCLK + 20) nano seconds */ + udelay(1); + gpio_set_value(st->sample, 1); + + spi_message_init(&msg); + spi_message_add_tail(&xfer, &msg); + ret = spi_sync(st->sdev, &msg); + if (ret) + goto error_ret; + status = st->rx[1]; + pos = (((u16)(st->rx[0])) << 4) | ((st->rx[1] & 0xF0) >> 4); + len = sprintf(buf, "%d %c%c%c%c ", pos, + (status & 0x8) ? 'P' : 'V', + (status & 0x4) ? 'd' : '_', + (status & 0x2) ? 'l' : '_', + (status & 0x1) ? '1' : '0'); + + /* delay 18 ns */ + /* ndelay(18); */ + + gpio_set_value(st->rdvel, 0); + /* ndelay(5);*/ + + spi_message_init(&msg); + spi_message_add_tail(&xfer, &msg); + ret = spi_sync(st->sdev, &msg); + if (ret) + goto error_ret; + status = st->rx[1]; + vel = (st->rx[0] & 0x80) ? 0xf000 : 0; + vel |= (((s16)(st->rx[0])) << 4) | ((st->rx[1] & 0xF0) >> 4); + len += sprintf(buf + len, "%d %c%c%c%c\n", vel, + (status & 0x8) ? 'P' : 'V', + (status & 0x4) ? 'd' : '_', + (status & 0x2) ? 'l' : '_', + (status & 0x1) ? '1' : '0'); +error_ret: + gpio_set_value(st->rdvel, 1); + /* delay (2 * AD2S120X_TSCLK + 20) ns for sample pulse */ + udelay(1); + mutex_unlock(&st->lock); + + return ret ? ret : len; +} + +static ssize_t ad2s120x_show_pos(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct spi_message msg; + struct spi_transfer xfer; + int ret = 0; + ssize_t len = 0; + u16 pos; + u8 status; + struct iio_dev *idev = dev_get_drvdata(dev); + struct ad2s120x_state *st = idev->dev_data; + + xfer.len = 1; + xfer.tx_buf = st->tx; + xfer.rx_buf = st->rx; + mutex_lock(&st->lock); + + gpio_set_value(st->sample, 0); + /* delay (6 * AD2S120X_TSCLK + 20) nano seconds */ + udelay(1); + gpio_set_value(st->sample, 1); + gpio_set_value(st->rdvel, 1); + + spi_message_init(&msg); + spi_message_add_tail(&xfer, &msg); + ret = spi_sync(st->sdev, &msg); + if (ret) + goto error_ret; + status = st->rx[1]; + pos = (((u16)(st->rx[0])) << 4) | ((st->rx[1] & 0xF0) >> 4); + len = sprintf(buf, "%d %c%c%c%c ", pos, + (status & 0x8) ? 'P' : 'V', + (status & 0x4) ? 'd' : '_', + (status & 0x2) ? 'l' : '_', + (status & 0x1) ? '1' : '0'); +error_ret: + /* delay (2 * AD2S120X_TSCLK + 20) ns for sample pulse */ + udelay(1); + mutex_unlock(&st->lock); + + return ret ? ret : len; +} + +static ssize_t ad2s120x_show_vel(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct spi_message msg; + struct spi_transfer xfer; + int ret = 0; + ssize_t len = 0; + s16 vel; + u8 status; + struct iio_dev *idev = dev_get_drvdata(dev); + struct ad2s120x_state *st = idev->dev_data; + + xfer.len = 1; + xfer.tx_buf = st->tx; + xfer.rx_buf = st->rx; + mutex_lock(&st->lock); + + gpio_set_value(st->sample, 0); + /* delay (6 * AD2S120X_TSCLK + 20) nano seconds */ + udelay(1); + gpio_set_value(st->sample, 1); + + gpio_set_value(st->rdvel, 0); + /* ndelay(5);*/ + + spi_message_init(&msg); + spi_message_add_tail(&xfer, &msg); + ret = spi_sync(st->sdev, &msg); + if (ret) + goto error_ret; + status = st->rx[1]; + vel = (st->rx[0] & 0x80) ? 0xf000 : 0; + vel |= (((s16)(st->rx[0])) << 4) | ((st->rx[1] & 0xF0) >> 4); + len += sprintf(buf + len, "%d %c%c%c%c\n", vel, + (status & 0x8) ? 'P' : 'V', + (status & 0x4) ? 'd' : '_', + (status & 0x2) ? 'l' : '_', + (status & 0x1) ? '1' : '0'); +error_ret: + gpio_set_value(st->rdvel, 1); + /* delay (2 * AD2S120X_TSCLK + 20) ns for sample pulse */ + udelay(1); + mutex_unlock(&st->lock); + + return ret ? ret : len; +} + +static IIO_CONST_ATTR(description, + "12-Bit R/D Converter with Reference Oscillator"); +static IIO_DEVICE_ATTR(pos_vel, S_IRUGO, ad2s120x_show_pos_vel, NULL, 0); +static IIO_DEVICE_ATTR(pos, S_IRUGO, ad2s120x_show_pos, NULL, 0); +static IIO_DEVICE_ATTR(vel, S_IRUGO, ad2s120x_show_vel, NULL, 0); + +static struct attribute *ad2s120x_attributes[] = { + &iio_const_attr_description.dev_attr.attr, + &iio_dev_attr_pos_vel.dev_attr.attr, + &iio_dev_attr_pos.dev_attr.attr, + &iio_dev_attr_vel.dev_attr.attr, + NULL, +}; + +static const struct attribute_group ad2s120x_attribute_group = { + .name = DRV_NAME, + .attrs = ad2s120x_attributes, +}; + +static int __devinit ad2s120x_probe(struct spi_device *spi) +{ + struct ad2s120x_state *st; + int pn, ret = 0; + unsigned short *pins = spi->dev.platform_data; + + for (pn = 0; pn < AD2S120X_PN; pn++) { + if (gpio_request(pins[pn], DRV_NAME)) { + pr_err("%s: request gpio pin %d failed\n", + DRV_NAME, pins[pn]); + goto error_ret; + } + gpio_direction_output(pins[pn], 1); + } + + st = kzalloc(sizeof(*st), GFP_KERNEL); + if (st == NULL) { + ret = -ENOMEM; + goto error_ret; + } + spi_set_drvdata(spi, st); + + mutex_init(&st->lock); + st->sdev = spi; + st->sample = pins[0]; + st->rdvel = pins[1]; + + st->idev = iio_allocate_device(); + if (st->idev == NULL) { + ret = -ENOMEM; + goto error_free_st; + } + st->idev->dev.parent = &spi->dev; + st->idev->num_interrupt_lines = 0; + st->idev->event_attrs = NULL; + + st->idev->attrs = &ad2s120x_attribute_group; + st->idev->dev_data = (void *)(st); + st->idev->driver_module = THIS_MODULE; + st->idev->modes = INDIO_DIRECT_MODE; + + ret = iio_device_register(st->idev); + if (ret) + goto error_free_dev; + + spi->max_speed_hz = AD2S120X_HZ; + spi->mode = SPI_MODE_3; + spi_setup(spi); + + return 0; + +error_free_dev: + iio_free_device(st->idev); +error_free_st: + kfree(st); +error_ret: + for (--pn; pn >= 0; pn--) + gpio_free(pins[pn]); + return ret; +} + +static int __devexit ad2s120x_remove(struct spi_device *spi) +{ + struct ad2s120x_state *st = spi_get_drvdata(spi); + + iio_device_unregister(st->idev); + kfree(st); + + return 0; +} + +static struct spi_driver ad2s120x_driver = { + .driver = { + .name = DRV_NAME, + .owner = THIS_MODULE, + }, + .probe = ad2s120x_probe, + .remove = __devexit_p(ad2s120x_remove), +}; + +static __init int ad2s120x_spi_init(void) +{ + return spi_register_driver(&ad2s120x_driver); +} +module_init(ad2s120x_spi_init); + +static __exit void ad2s120x_spi_exit(void) +{ + spi_unregister_driver(&ad2s120x_driver); +} +module_exit(ad2s120x_spi_exit); + +MODULE_AUTHOR("Graff Yang "); +MODULE_DESCRIPTION("Analog Devices AD2S1200/1205 Resolver to Digital SPI driver"); +MODULE_LICENSE("GPL v2"); -- cgit v1.2.3 From 817e5c65c511d4a83686333ae75507deb4b55d5e Mon Sep 17 00:00:00 2001 From: Graf Yang Date: Wed, 27 Oct 2010 21:44:21 -0400 Subject: staging: iio: resolver: new driver for AD2S1210 devices Signed-off-by: Graf Yang Signed-off-by: Michael Hennerich Acked-by: Jonathan Cameron Signed-off-by: Mike Frysinger Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/resolver/Kconfig | 35 ++ drivers/staging/iio/resolver/Makefile | 1 + drivers/staging/iio/resolver/ad2s1210.c | 872 ++++++++++++++++++++++++++++++++ 3 files changed, 908 insertions(+) create mode 100644 drivers/staging/iio/resolver/ad2s1210.c diff --git a/drivers/staging/iio/resolver/Kconfig b/drivers/staging/iio/resolver/Kconfig index 32df73aeb0c5..a4a363429355 100644 --- a/drivers/staging/iio/resolver/Kconfig +++ b/drivers/staging/iio/resolver/Kconfig @@ -17,3 +17,38 @@ config AD2S120X Say yes here to build support for Analog Devices spi resolver to digital converters, ad2s1200 and ad2s1205, provides direct access via sysfs. + +config AD2S1210 + tristate "Analog Devices ad2s1210 driver" + depends on SPI + help + Say yes here to build support for Analog Devices spi resolver + to digital converters, ad2s1210, provides direct access via sysfs. + +choice + prompt "Resolution Control" + depends on AD2S1210 + default AD2S1210_GPIO_NONE + help + In normal mode, the resolution of the digital output is selected + using the RES0 and RES1 input pins. In configuration mode, the + resolution is selected by setting the RES0 and RES1 bits in the + control regsiter. When switching between normal mode and configuration + mode, there are some schemes to keep them matchs. + +config AD2S1210_GPIO_INPUT + bool "read resolution from gpio pins" + help + GPIO pins are sampling RES0 and RES1 pins, read the resolution + settings from the GPIO pins. + +config AD2S1210_GPIO_OUTPUT + bool "set gpio pins to set resolution" + help + RES0 and RES1 pins are controlled by GPIOs, setting GPIO pins to + set the resolution. + +config AD2S1210_GPIO_NONE + bool "take the responsibility by user" + +endchoice diff --git a/drivers/staging/iio/resolver/Makefile b/drivers/staging/iio/resolver/Makefile index b2b3cc1ddc67..0b84a89e6cac 100644 --- a/drivers/staging/iio/resolver/Makefile +++ b/drivers/staging/iio/resolver/Makefile @@ -4,3 +4,4 @@ obj-$(CONFIG_AD2S90) += ad2s90.o obj-$(CONFIG_AD2S120X) += ad2s120x.o +obj-$(CONFIG_AD2S1210) += ad2s1210.o diff --git a/drivers/staging/iio/resolver/ad2s1210.c b/drivers/staging/iio/resolver/ad2s1210.c new file mode 100644 index 000000000000..34fb21aa8b07 --- /dev/null +++ b/drivers/staging/iio/resolver/ad2s1210.c @@ -0,0 +1,872 @@ +/* + * ad2s1210.c support for the ADI Resolver to Digital Converters: AD2S1210 + * + * Copyright (c) 2010-2010 Analog Devices Inc. + * + * 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 +#include +#include +#include +#include + +#include "../iio.h" +#include "../sysfs.h" + +#define DRV_NAME "ad2s1210" + +#define DEF_CONTROL 0x7E + +#define MSB_IS_HIGH 0x80 +#define MSB_IS_LOW 0x7F +#define PHASE_LOCK_RANGE_44 0x20 +#define ENABLE_HYSTERESIS 0x10 +#define SET_ENRES1 0x08 +#define SET_ENRES0 0x04 +#define SET_RES1 0x02 +#define SET_RES0 0x01 + +#define SET_ENRESOLUTION (SET_ENRES1 | SET_ENRES0) +#define SET_RESOLUTION (SET_RES1 | SET_RES0) + +#define REG_POSITION 0x80 +#define REG_VELOCITY 0x82 +#define REG_LOS_THRD 0x88 +#define REG_DOS_OVR_THRD 0x89 +#define REG_DOS_MIS_THRD 0x8A +#define REG_DOS_RST_MAX_THRD 0x8B +#define REG_DOS_RST_MIN_THRD 0x8C +#define REG_LOT_HIGH_THRD 0x8D +#define REG_LOT_LOW_THRD 0x8E +#define REG_EXCIT_FREQ 0x91 +#define REG_CONTROL 0x92 +#define REG_SOFT_RESET 0xF0 +#define REG_FAULT 0xFF + +/* pin SAMPLE, A0, A1, RES0, RES1, is controlled by driver */ +#define AD2S1210_SAA 3 +#if defined(CONFIG_AD2S1210_GPIO_INPUT) || defined(CONFIG_AD2S1210_GPIO_OUTPUT) +# define AD2S1210_RES 2 +#else +# define AD2S1210_RES 0 +#endif +#define AD2S1210_PN (AD2S1210_SAA + AD2S1210_RES) + +#define AD2S1210_MIN_CLKIN 6144000 +#define AD2S1210_MAX_CLKIN 10240000 +#define AD2S1210_MIN_EXCIT 2000 +#define AD2S1210_MAX_EXCIT 20000 +#define AD2S1210_MIN_FCW 0x4 +#define AD2S1210_MAX_FCW 0x50 + +/* default input clock on serial interface */ +#define AD2S1210_DEF_CLKIN 8192000 +/* clock period in nano second */ +#define AD2S1210_DEF_TCK (1000000000/AD2S1210_DEF_CLKIN) +#define AD2S1210_DEF_EXCIT 10000 + +enum ad2s1210_mode { + MOD_POS = 0, + MOD_VEL, + MOD_RESERVED, + MOD_CONFIG, +}; + +enum ad2s1210_res { + RES_10 = 10, + RES_12 = 12, + RES_14 = 14, + RES_16 = 16, +}; + +static unsigned int resolution_value[] = { + RES_10, RES_12, RES_14, RES_16}; + +struct ad2s1210_state { + struct mutex lock; + struct iio_dev *idev; + struct spi_device *sdev; + struct spi_transfer xfer; + unsigned int hysteresis; + unsigned int old_data; + enum ad2s1210_mode mode; + enum ad2s1210_res resolution; + unsigned int fclkin; + unsigned int fexcit; + unsigned short sample; + unsigned short a0; + unsigned short a1; + unsigned short res0; + unsigned short res1; + u8 rx[3]; + u8 tx[3]; +}; + +static inline void start_sample(struct ad2s1210_state *st) +{ + gpio_set_value(st->sample, 0); +} + +static inline void stop_sample(struct ad2s1210_state *st) +{ + gpio_set_value(st->sample, 1); +} + +static inline void set_mode(enum ad2s1210_mode mode, struct ad2s1210_state *st) +{ + switch (mode) { + case MOD_POS: + gpio_set_value(st->a0, 0); + gpio_set_value(st->a1, 0); + break; + case MOD_VEL: + gpio_set_value(st->a0, 0); + gpio_set_value(st->a1, 1); + break; + case MOD_CONFIG: + gpio_set_value(st->a0, 1); + gpio_set_value(st->a1, 1); + break; + default: + /* set to reserved mode */ + gpio_set_value(st->a0, 1); + gpio_set_value(st->a1, 0); + } + st->mode = mode; +} + +/* write 1 bytes (address or data) to the chip */ +static int config_write(struct ad2s1210_state *st, + unsigned char data) +{ + struct spi_message msg; + int ret = 0; + + st->xfer.len = 1; + set_mode(MOD_CONFIG, st); + + spi_message_init(&msg); + spi_message_add_tail(&st->xfer, &msg); + st->tx[0] = data; + ret = spi_sync(st->sdev, &msg); + if (ret) + return ret; + st->old_data = 1; + return ret; +} + +/* read value from one of the registers */ +static int config_read(struct ad2s1210_state *st, + unsigned char address, + unsigned char *data) +{ + struct spi_message msg; + int ret = 0; + + st->xfer.len = 2; + set_mode(MOD_CONFIG, st); + + spi_message_init(&msg); + spi_message_add_tail(&st->xfer, &msg); + st->tx[0] = address | MSB_IS_HIGH; + st->tx[1] = REG_FAULT; + ret = spi_sync(st->sdev, &msg); + if (ret) + return ret; + *data = st->rx[1]; + st->old_data = 1; + return ret; +} + +static inline void update_frequency_control_word(struct ad2s1210_state *st) +{ + unsigned char fcw; + fcw = (unsigned char)(st->fexcit * (1 << 15) / st->fclkin); + if (fcw >= AD2S1210_MIN_FCW && fcw <= AD2S1210_MAX_FCW) { + config_write(st, REG_EXCIT_FREQ); + config_write(st, fcw); + } else + pr_err("ad2s1210: FCW out of range\n"); +} + +#if defined(CONFIG_AD2S1210_GPIO_INPUT) +static inline unsigned char read_resolution_pin(struct ad2s1210_state *st) +{ + unsigned int data; + data = (gpio_get_value(st->res0) << 1) | + gpio_get_value(st->res1); + return resolution_value[data]; +} +#elif defined(CONFIG_AD2S1210_GPIO_OUTPUT) +static inline void set_resolution_pin(struct ad2s1210_state *st) +{ + switch (st->resolution) { + case RES_10: + gpio_set_value(st->res0, 0); + gpio_set_value(st->res1, 0); + break; + case RES_12: + gpio_set_value(st->res0, 0); + gpio_set_value(st->res1, 1); + break; + case RES_14: + gpio_set_value(st->res0, 1); + gpio_set_value(st->res1, 0); + break; + case RES_16: + gpio_set_value(st->res0, 1); + gpio_set_value(st->res1, 1); + break; + } +} +#endif + +static inline void soft_reset(struct ad2s1210_state *st) +{ + config_write(st, REG_SOFT_RESET); + config_write(st, 0x0); +} + + +/* return the OLD DATA since last spi bus write */ +static ssize_t ad2s1210_show_raw(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct iio_dev *idev = dev_get_drvdata(dev); + struct ad2s1210_state *st = idev->dev_data; + int ret; + + mutex_lock(&st->lock); + if (st->old_data) { + ret = sprintf(buf, "0x%x\n", st->rx[0]); + st->old_data = 0; + } else + ret = 0; + mutex_unlock(&st->lock); + return ret; +} + +static ssize_t ad2s1210_store_raw(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t len) +{ + struct iio_dev *idev = dev_get_drvdata(dev); + struct ad2s1210_state *st = idev->dev_data; + unsigned long udata; + unsigned char data; + int ret; + + ret = strict_strtoul(buf, 16, &udata); + if (ret) + return -EINVAL; + data = udata & 0xff; + mutex_lock(&st->lock); + config_write(st, data); + mutex_unlock(&st->lock); + return 1; +} + +static ssize_t ad2s1210_store_softreset(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t len) +{ + struct iio_dev *idev = dev_get_drvdata(dev); + struct ad2s1210_state *st = idev->dev_data; + mutex_lock(&st->lock); + soft_reset(st); + mutex_unlock(&st->lock); + return len; +} + +static ssize_t ad2s1210_show_fclkin(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct iio_dev *idev = dev_get_drvdata(dev); + struct ad2s1210_state *st = idev->dev_data; + return sprintf(buf, "%d\n", st->fclkin); +} + +static ssize_t ad2s1210_store_fclkin(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t len) +{ + struct iio_dev *idev = dev_get_drvdata(dev); + struct ad2s1210_state *st = idev->dev_data; + unsigned long fclkin; + int ret; + + ret = strict_strtoul(buf, 10, &fclkin); + if (!ret && fclkin >= AD2S1210_MIN_CLKIN && + fclkin <= AD2S1210_MAX_CLKIN) { + mutex_lock(&st->lock); + st->fclkin = fclkin; + } else { + pr_err("ad2s1210: fclkin out of range\n"); + return -EINVAL; + } + update_frequency_control_word(st); + soft_reset(st); + mutex_unlock(&st->lock); + return len; +} + +static ssize_t ad2s1210_show_fexcit(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct iio_dev *idev = dev_get_drvdata(dev); + struct ad2s1210_state *st = idev->dev_data; + return sprintf(buf, "%d\n", st->fexcit); +} + +static ssize_t ad2s1210_store_fexcit(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t len) +{ + struct iio_dev *idev = dev_get_drvdata(dev); + struct ad2s1210_state *st = idev->dev_data; + unsigned long fexcit; + int ret; + + ret = strict_strtoul(buf, 10, &fexcit); + if (!ret && fexcit >= AD2S1210_MIN_EXCIT && + fexcit <= AD2S1210_MAX_EXCIT) { + mutex_lock(&st->lock); + st->fexcit = fexcit; + } else { + pr_err("ad2s1210: excitation frequency out of range\n"); + return -EINVAL; + } + update_frequency_control_word(st); + soft_reset(st); + mutex_unlock(&st->lock); + return len; +} + +static ssize_t ad2s1210_show_control(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct iio_dev *idev = dev_get_drvdata(dev); + struct ad2s1210_state *st = idev->dev_data; + unsigned char data; + mutex_lock(&st->lock); + config_read(st, REG_CONTROL, &data); + mutex_unlock(&st->lock); + return sprintf(buf, "0x%x\n", data); +} + +static ssize_t ad2s1210_store_control(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t len) +{ + struct iio_dev *idev = dev_get_drvdata(dev); + struct ad2s1210_state *st = idev->dev_data; + unsigned long udata; + unsigned char data; + int ret; + + ret = strict_strtoul(buf, 16, &udata); + if (ret) { + ret = -EINVAL; + goto error_ret; + } + mutex_lock(&st->lock); + config_write(st, REG_CONTROL); + data = udata & MSB_IS_LOW; + config_write(st, data); + config_read(st, REG_CONTROL, &data); + if (data & MSB_IS_HIGH) { + ret = -EIO; + pr_err("ad2s1210: write control register fail\n"); + goto error_ret; + } + st->resolution = resolution_value[data & SET_RESOLUTION]; +#if defined(CONFIG_AD2S1210_GPIO_INPUT) + data = read_resolution_pin(st); + if (data != st->resolution) + pr_warning("ad2s1210: resolution settings not match\n"); +#elif defined(CONFIG_AD2S1210_GPIO_OUTPUT) + set_resolution_pin(st); +#endif + ret = len; + if (data & ENABLE_HYSTERESIS) + st->hysteresis = 1; + else + st->hysteresis = 0; +error_ret: + mutex_unlock(&st->lock); + return ret; +} + +static ssize_t ad2s1210_show_resolution(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct iio_dev *idev = dev_get_drvdata(dev); + struct ad2s1210_state *st = idev->dev_data; + return sprintf(buf, "%d\n", st->resolution); +} + +static ssize_t ad2s1210_store_resolution(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t len) +{ + struct iio_dev *idev = dev_get_drvdata(dev); + struct ad2s1210_state *st = idev->dev_data; + unsigned char data; + unsigned long udata; + int ret; + + ret = strict_strtoul(buf, 10, &udata); + if (ret || udata < RES_10 || udata > RES_16) { + pr_err("ad2s1210: resolution out of range\n"); + return -EINVAL; + } + mutex_lock(&st->lock); + config_read(st, REG_CONTROL, &data); + data &= ~SET_RESOLUTION; + data |= (udata - RES_10) >> 1; + config_write(st, REG_CONTROL); + config_write(st, data & MSB_IS_LOW); + config_read(st, REG_CONTROL, &data); + if (data & MSB_IS_HIGH) { + ret = -EIO; + pr_err("ad2s1210: setting resolution fail\n"); + goto error_ret; + } + st->resolution = resolution_value[data & SET_RESOLUTION]; +#if defined(CONFIG_AD2S1210_GPIO_INPUT) + data = read_resolution_pin(st); + if (data != st->resolution) + pr_warning("ad2s1210: resolution settings not match\n"); +#elif defined(CONFIG_AD2S1210_GPIO_OUTPUT) + set_resolution_pin(st); +#endif + ret = len; +error_ret: + mutex_unlock(&st->lock); + return ret; +} +/* read the fault register since last sample */ +static ssize_t ad2s1210_show_fault(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int ret = 0; + ssize_t len = 0; + unsigned char data; + struct iio_dev *idev = dev_get_drvdata(dev); + struct ad2s1210_state *st = idev->dev_data; + + mutex_lock(&st->lock); + ret = config_read(st, REG_FAULT, &data); + + if (ret) + goto error_ret; + len = sprintf(buf, "0x%x\n", data); +error_ret: + mutex_unlock(&st->lock); + return ret ? ret : len; +} + +static ssize_t ad2s1210_clear_fault(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t len) +{ + struct iio_dev *idev = dev_get_drvdata(dev); + struct ad2s1210_state *st = idev->dev_data; + unsigned char data; + + mutex_lock(&st->lock); + start_sample(st); + /* delay (2 * tck + 20) nano seconds */ + udelay(1); + stop_sample(st); + config_read(st, REG_FAULT, &data); + start_sample(st); + stop_sample(st); + mutex_unlock(&st->lock); + + return 0; +} + +static ssize_t ad2s1210_show_reg(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct iio_dev *idev = dev_get_drvdata(dev); + struct ad2s1210_state *st = idev->dev_data; + unsigned char data; + struct iio_dev_attr *iattr = to_iio_dev_attr(attr); + + mutex_lock(&st->lock); + config_read(st, iattr->address, &data); + mutex_unlock(&st->lock); + return sprintf(buf, "%d\n", data); +} + +static ssize_t ad2s1210_store_reg(struct device *dev, + struct device_attribute *attr, const char *buf, size_t len) +{ + struct iio_dev *idev = dev_get_drvdata(dev); + struct ad2s1210_state *st = idev->dev_data; + unsigned long data; + int ret; + struct iio_dev_attr *iattr = to_iio_dev_attr(attr); + + ret = strict_strtoul(buf, 10, &data); + if (ret) + return -EINVAL; + mutex_lock(&st->lock); + config_write(st, iattr->address); + config_write(st, data & MSB_IS_LOW); + mutex_unlock(&st->lock); + return len; +} + +static ssize_t ad2s1210_show_pos(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct spi_message msg; + int ret = 0; + ssize_t len = 0; + u16 pos; + struct iio_dev *idev = dev_get_drvdata(dev); + struct ad2s1210_state *st = idev->dev_data; + + st->xfer.len = 2; + mutex_lock(&st->lock); + start_sample(st); + /* delay (6 * tck + 20) nano seconds */ + udelay(1); + + set_mode(MOD_POS, st); + + spi_message_init(&msg); + spi_message_add_tail(&st->xfer, &msg); + ret = spi_sync(st->sdev, &msg); + if (ret) + goto error_ret; + pos = ((((u16)(st->rx[0])) << 8) | (st->rx[1])); + if (st->hysteresis) + pos >>= 16 - st->resolution; + len = sprintf(buf, "%d\n", pos); +error_ret: + stop_sample(st); + /* delay (2 * tck + 20) nano seconds */ + udelay(1); + mutex_unlock(&st->lock); + + return ret ? ret : len; +} + +static ssize_t ad2s1210_show_vel(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct spi_message msg; + unsigned short negative; + int ret = 0; + ssize_t len = 0; + s16 vel; + struct iio_dev *idev = dev_get_drvdata(dev); + struct ad2s1210_state *st = idev->dev_data; + + st->xfer.len = 2; + mutex_lock(&st->lock); + start_sample(st); + /* delay (6 * tck + 20) nano seconds */ + udelay(1); + + set_mode(MOD_VEL, st); + + spi_message_init(&msg); + spi_message_add_tail(&st->xfer, &msg); + ret = spi_sync(st->sdev, &msg); + if (ret) + goto error_ret; + negative = st->rx[0] & 0x80; + vel = ((((s16)(st->rx[0])) << 8) | (st->rx[1])); + vel >>= 16 - st->resolution; + if (negative) { + negative = (0xffff >> st->resolution) << st->resolution; + vel |= negative; + } + len = sprintf(buf, "%d\n", vel); +error_ret: + stop_sample(st); + /* delay (2 * tck + 20) nano seconds */ + udelay(1); + mutex_unlock(&st->lock); + + return ret ? ret : len; +} + +static ssize_t ad2s1210_show_pos_vel(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct spi_message msg; + unsigned short negative; + int ret = 0; + ssize_t len = 0; + u16 pos; + s16 vel; + struct iio_dev *idev = dev_get_drvdata(dev); + struct ad2s1210_state *st = idev->dev_data; + + st->xfer.len = 2; + mutex_lock(&st->lock); + start_sample(st); + /* delay (6 * tck + 20) nano seconds */ + udelay(1); + + set_mode(MOD_POS, st); + + spi_message_init(&msg); + spi_message_add_tail(&st->xfer, &msg); + ret = spi_sync(st->sdev, &msg); + if (ret) + goto error_ret; + pos = ((((u16)(st->rx[0])) << 8) | (st->rx[1])); + if (st->hysteresis) + pos >>= 16 - st->resolution; + len = sprintf(buf, "%d ", pos); + + st->xfer.len = 2; + set_mode(MOD_VEL, st); + spi_message_init(&msg); + spi_message_add_tail(&st->xfer, &msg); + ret = spi_sync(st->sdev, &msg); + if (ret) + goto error_ret; + negative = st->rx[0] & 0x80; + vel = ((((s16)(st->rx[0])) << 8) | (st->rx[1])); + vel >>= 16 - st->resolution; + if (negative) { + negative = (0xffff >> st->resolution) << st->resolution; + vel |= negative; + } + len += sprintf(buf + len, "%d\n", vel); +error_ret: + stop_sample(st); + /* delay (2 * tck + 20) nano seconds */ + udelay(1); + mutex_unlock(&st->lock); + + return ret ? ret : len; +} + +static IIO_CONST_ATTR(description, + "Variable Resolution, 10-Bit to 16Bit R/D\n\ +Converter with Reference Oscillator"); +static IIO_DEVICE_ATTR(raw_io, S_IRUGO | S_IWUGO, + ad2s1210_show_raw, ad2s1210_store_raw, 0); +static IIO_DEVICE_ATTR(reset, S_IWUGO, + NULL, ad2s1210_store_softreset, 0); +static IIO_DEVICE_ATTR(fclkin, S_IRUGO | S_IWUGO, + ad2s1210_show_fclkin, ad2s1210_store_fclkin, 0); +static IIO_DEVICE_ATTR(fexcit, S_IRUGO | S_IWUGO, + ad2s1210_show_fexcit, ad2s1210_store_fexcit, 0); +static IIO_DEVICE_ATTR(control, S_IRUGO | S_IWUGO, + ad2s1210_show_control, ad2s1210_store_control, 0); +static IIO_DEVICE_ATTR(bits, S_IRUGO | S_IWUGO, + ad2s1210_show_resolution, ad2s1210_store_resolution, 0); +static IIO_DEVICE_ATTR(fault, S_IRUGO | S_IWUGO, + ad2s1210_show_fault, ad2s1210_clear_fault, 0); +static IIO_DEVICE_ATTR(pos, S_IRUGO, + ad2s1210_show_pos, NULL, 0); +static IIO_DEVICE_ATTR(vel, S_IRUGO, + ad2s1210_show_vel, NULL, 0); +static IIO_DEVICE_ATTR(pos_vel, S_IRUGO, + ad2s1210_show_pos_vel, NULL, 0); +static IIO_DEVICE_ATTR(los_thrd, S_IRUGO | S_IWUGO, + ad2s1210_show_reg, ad2s1210_store_reg, REG_LOS_THRD); +static IIO_DEVICE_ATTR(dos_ovr_thrd, S_IRUGO | S_IWUGO, + ad2s1210_show_reg, ad2s1210_store_reg, REG_DOS_OVR_THRD); +static IIO_DEVICE_ATTR(dos_mis_thrd, S_IRUGO | S_IWUGO, + ad2s1210_show_reg, ad2s1210_store_reg, REG_DOS_MIS_THRD); +static IIO_DEVICE_ATTR(dos_rst_max_thrd, S_IRUGO | S_IWUGO, + ad2s1210_show_reg, ad2s1210_store_reg, REG_DOS_RST_MAX_THRD); +static IIO_DEVICE_ATTR(dos_rst_min_thrd, S_IRUGO | S_IWUGO, + ad2s1210_show_reg, ad2s1210_store_reg, REG_DOS_RST_MIN_THRD); +static IIO_DEVICE_ATTR(lot_high_thrd, S_IRUGO | S_IWUGO, + ad2s1210_show_reg, ad2s1210_store_reg, REG_LOT_HIGH_THRD); +static IIO_DEVICE_ATTR(lot_low_thrd, S_IRUGO | S_IWUGO, + ad2s1210_show_reg, ad2s1210_store_reg, REG_LOT_LOW_THRD); + +static struct attribute *ad2s1210_attributes[] = { + &iio_const_attr_description.dev_attr.attr, + &iio_dev_attr_raw_io.dev_attr.attr, + &iio_dev_attr_reset.dev_attr.attr, + &iio_dev_attr_fclkin.dev_attr.attr, + &iio_dev_attr_fexcit.dev_attr.attr, + &iio_dev_attr_control.dev_attr.attr, + &iio_dev_attr_bits.dev_attr.attr, + &iio_dev_attr_fault.dev_attr.attr, + &iio_dev_attr_pos.dev_attr.attr, + &iio_dev_attr_vel.dev_attr.attr, + &iio_dev_attr_pos_vel.dev_attr.attr, + &iio_dev_attr_los_thrd.dev_attr.attr, + &iio_dev_attr_dos_ovr_thrd.dev_attr.attr, + &iio_dev_attr_dos_mis_thrd.dev_attr.attr, + &iio_dev_attr_dos_rst_max_thrd.dev_attr.attr, + &iio_dev_attr_dos_rst_min_thrd.dev_attr.attr, + &iio_dev_attr_lot_high_thrd.dev_attr.attr, + &iio_dev_attr_lot_low_thrd.dev_attr.attr, + NULL, +}; + +static const struct attribute_group ad2s1210_attribute_group = { + .name = DRV_NAME, + .attrs = ad2s1210_attributes, +}; + +static int __devinit ad2s1210_initial(struct ad2s1210_state *st) +{ + unsigned char data; + int ret; + + mutex_lock(&st->lock); +#if defined(CONFIG_AD2S1210_GPIO_INPUT) + st->resolution = read_resolution_pin(st); +#elif defined(CONFIG_AD2S1210_GPIO_OUTPUT) + set_resolution_pin(st); +#endif + + config_write(st, REG_CONTROL); + data = DEF_CONTROL & ~(SET_RESOLUTION); + data |= (st->resolution - RES_10) >> 1; + config_write(st, data); + ret = config_read(st, REG_CONTROL, &data); + if (ret) + goto error_ret; + + if (data & MSB_IS_HIGH) { + ret = -EIO; + goto error_ret; + } + + update_frequency_control_word(st); + soft_reset(st); +error_ret: + mutex_unlock(&st->lock); + return ret; +} + +static int __devinit ad2s1210_probe(struct spi_device *spi) +{ + struct ad2s1210_state *st; + int pn, ret = 0; + unsigned short *pins = spi->dev.platform_data; + + for (pn = 0; pn < AD2S1210_PN; pn++) { + if (gpio_request(pins[pn], DRV_NAME)) { + pr_err("%s: request gpio pin %d failed\n", + DRV_NAME, pins[pn]); + goto error_ret; + } + if (pn < AD2S1210_SAA) + gpio_direction_output(pins[pn], 1); + else { +#if defined(CONFIG_AD2S1210_GPIO_INPUT) + gpio_direction_input(pins[pn]); +#elif defined(CONFIG_AD2S1210_GPIO_OUTPUT) + gpio_direction_output(pins[pn], 1); +#endif + } + } + + st = kzalloc(sizeof(*st), GFP_KERNEL); + if (st == NULL) { + ret = -ENOMEM; + goto error_ret; + } + spi_set_drvdata(spi, st); + + mutex_init(&st->lock); + st->sdev = spi; + st->xfer.tx_buf = st->tx; + st->xfer.rx_buf = st->rx; + st->hysteresis = 1; + st->mode = MOD_CONFIG; + st->resolution = RES_12; + st->fclkin = AD2S1210_DEF_CLKIN; + st->fexcit = AD2S1210_DEF_EXCIT; + st->sample = pins[0]; + st->a0 = pins[1]; + st->a1 = pins[2]; + st->res0 = pins[3]; + st->res1 = pins[4]; + + st->idev = iio_allocate_device(); + if (st->idev == NULL) { + ret = -ENOMEM; + goto error_free_st; + } + st->idev->dev.parent = &spi->dev; + st->idev->num_interrupt_lines = 0; + st->idev->event_attrs = NULL; + + st->idev->attrs = &ad2s1210_attribute_group; + st->idev->dev_data = (void *)(st); + st->idev->driver_module = THIS_MODULE; + st->idev->modes = INDIO_DIRECT_MODE; + + ret = iio_device_register(st->idev); + if (ret) + goto error_free_dev; + + if (spi->max_speed_hz != AD2S1210_DEF_CLKIN) + st->fclkin = spi->max_speed_hz; + spi->mode = SPI_MODE_3; + spi_setup(spi); + + ad2s1210_initial(st); + return 0; + +error_free_dev: + iio_free_device(st->idev); +error_free_st: + kfree(st); +error_ret: + for (--pn; pn >= 0; pn--) + gpio_free(pins[pn]); + return ret; +} + +static int __devexit ad2s1210_remove(struct spi_device *spi) +{ + struct ad2s1210_state *st = spi_get_drvdata(spi); + + iio_device_unregister(st->idev); + kfree(st); + + return 0; +} + +static struct spi_driver ad2s1210_driver = { + .driver = { + .name = DRV_NAME, + .owner = THIS_MODULE, + }, + .probe = ad2s1210_probe, + .remove = __devexit_p(ad2s1210_remove), +}; + +static __init int ad2s1210_spi_init(void) +{ + return spi_register_driver(&ad2s1210_driver); +} +module_init(ad2s1210_spi_init); + +static __exit void ad2s1210_spi_exit(void) +{ + spi_unregister_driver(&ad2s1210_driver); +} +module_exit(ad2s1210_spi_exit); + +MODULE_AUTHOR("Graff Yang "); +MODULE_DESCRIPTION("Analog Devices AD2S1210 Resolver to Digital SPI driver"); +MODULE_LICENSE("GPL v2"); -- cgit v1.2.3 From e1ffd62b8fc87e842431cc693821d7f1ac70b9de Mon Sep 17 00:00:00 2001 From: Barry Song Date: Wed, 27 Oct 2010 21:44:22 -0400 Subject: staging: iio: adis16209: tuning spi delay to make hardware more stable Looks like one spot was missed in the previous spi tune patch. Signed-off-by: Barry Song Signed-off-by: Mike Frysinger Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/accel/adis16209_ring.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/iio/accel/adis16209_ring.c b/drivers/staging/iio/accel/adis16209_ring.c index 033135c6f226..8eba0af98ed5 100644 --- a/drivers/staging/iio/accel/adis16209_ring.c +++ b/drivers/staging/iio/accel/adis16209_ring.c @@ -105,7 +105,7 @@ static int adis16209_read_ring_data(struct device *dev, u8 *rx) xfers[i].bits_per_word = 8; xfers[i].cs_change = 1; xfers[i].len = 2; - xfers[i].delay_usecs = 20; + xfers[i].delay_usecs = 30; xfers[i].tx_buf = st->tx + 2 * i; st->tx[2 * i] = ADIS16209_READ_REG(ADIS16209_SUPPLY_OUT + 2 * i); -- cgit v1.2.3 From 8892384803af7082056fe29faef02fd0c762493e Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Fri, 29 Oct 2010 15:19:27 +0200 Subject: staging: get rid of dev_base_lock dev_base_lock was the legacy rwlock used to protect netdevice list, and is expected to vanish. We now use RTNL and RCU locking. Signed-off-by: Eric Dumazet Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wlags49_h2/wl_sysfs.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/wlags49_h2/wl_sysfs.c b/drivers/staging/wlags49_h2/wl_sysfs.c index e4c8804ac37d..9b833b30ae62 100644 --- a/drivers/staging/wlags49_h2/wl_sysfs.c +++ b/drivers/staging/wlags49_h2/wl_sysfs.c @@ -42,7 +42,7 @@ static ssize_t show_tallies(struct device *d, struct device_attribute *attr, CFG_HERMES_TALLIES_STRCT tallies; ssize_t ret = -EINVAL; - read_lock(&dev_base_lock); + rcu_read_lock(); if (dev_isalive(dev)) { wl_lock(lp, &flags); @@ -102,7 +102,7 @@ static ssize_t show_tallies(struct device *d, struct device_attribute *attr, } } - read_unlock(&dev_base_lock); + rcu_read_unlock(); return ret; } -- cgit v1.2.3 From cc8b59d41fa597bb62bdca2c200e8509bc8bec2a Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Sat, 30 Oct 2010 14:08:38 -0700 Subject: Staging: solo6x10: Update WARN uses Add missing newlines. Signed-off-by: Joe Perches Signed-off-by: Greg Kroah-Hartman --- drivers/staging/solo6x10/solo6010-v4l2-enc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/solo6x10/solo6010-v4l2-enc.c b/drivers/staging/solo6x10/solo6010-v4l2-enc.c index 097e82bc7a63..2d05f3a148d0 100644 --- a/drivers/staging/solo6x10/solo6010-v4l2-enc.c +++ b/drivers/staging/solo6x10/solo6010-v4l2-enc.c @@ -184,7 +184,7 @@ static void solo_update_mode(struct solo_enc_dev *solo_enc) solo_enc->bw_weight <<= 2; break; default: - WARN(1, "mode is unknown"); + WARN(1, "mode is unknown\n"); } } -- cgit v1.2.3 From fc4f55860254566b43e066bed0962c7cca72da84 Mon Sep 17 00:00:00 2001 From: Matias De la Puente Date: Fri, 29 Oct 2010 19:07:45 -0300 Subject: staging: vt6656: resolved checkpatch finding removed parentesis and spaces at the start of a line of a return Signed-off-by: Matias De la Puente Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6656/card.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/vt6656/card.c b/drivers/staging/vt6656/card.c index 8de21aac1bff..a49053bd7c65 100644 --- a/drivers/staging/vt6656/card.c +++ b/drivers/staging/vt6656/card.c @@ -1092,7 +1092,7 @@ CARDbChannelSwitch ( pDevice->sMgmtObj.uCurrChannel = byNewChannel; bResult = CARDbSetMediaChannel(pDevice, byNewChannel); - return(bResult); + return bResult; } pDevice->byChannelSwitchCount = byCount; pDevice->byNewChannel = byNewChannel; -- cgit v1.2.3 From 4a499de2d13786de626c3f689022d7ec25230911 Mon Sep 17 00:00:00 2001 From: Mariano Reingart Date: Fri, 29 Oct 2010 19:15:26 -0300 Subject: staging: vt6656: resolved checkpatch finding removed a C99 '//' comment and added a space around '=' Signed-off-by: Mariano Reingart Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6656/rxtx.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/staging/vt6656/rxtx.c b/drivers/staging/vt6656/rxtx.c index bbdc127a987d..8f18578a5903 100644 --- a/drivers/staging/vt6656/rxtx.c +++ b/drivers/staging/vt6656/rxtx.c @@ -68,8 +68,7 @@ /*--------------------- Static Classes ----------------------------*/ /*--------------------- Static Variables --------------------------*/ -//static int msglevel =MSG_LEVEL_DEBUG; -static int msglevel =MSG_LEVEL_INFO; +static int msglevel = MSG_LEVEL_INFO; /*--------------------- Static Functions --------------------------*/ -- cgit v1.2.3 From 99b7bbb9b57da48f602732aaa107d7add49c842d Mon Sep 17 00:00:00 2001 From: Ariel Savini Date: Fri, 29 Oct 2010 19:19:20 -0300 Subject: staging: vt6656 resolved parenthesis not spaces removes before parenthesis Signed-off-by: Ariel Savini Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6656/tkip.c | 37 +++++++++++++++++++------------------ 1 file changed, 19 insertions(+), 18 deletions(-) diff --git a/drivers/staging/vt6656/tkip.c b/drivers/staging/vt6656/tkip.c index a6bd533f9577..0715636cb9cb 100644 --- a/drivers/staging/vt6656/tkip.c +++ b/drivers/staging/vt6656/tkip.c @@ -214,13 +214,14 @@ void TKIPvMixKey( /* Phase 1, step 2 */ for (i=0; i<8; i++) { j = 2*(i & 1); - p1k[0] = (p1k[0] + tkip_sbox( (p1k[4] ^ ((256*pbyTKey[1+j]) + pbyTKey[j])) % 65536 )) % 65536; - p1k[1] = (p1k[1] + tkip_sbox( (p1k[0] ^ ((256*pbyTKey[5+j]) + pbyTKey[4+j])) % 65536 )) % 65536; - p1k[2] = (p1k[2] + tkip_sbox( (p1k[1] ^ ((256*pbyTKey[9+j]) + pbyTKey[8+j])) % 65536 )) % 65536; - p1k[3] = (p1k[3] + tkip_sbox( (p1k[2] ^ ((256*pbyTKey[13+j]) + pbyTKey[12+j])) % 65536 )) % 65536; - p1k[4] = (p1k[4] + tkip_sbox( (p1k[3] ^ (((256*pbyTKey[1+j]) + pbyTKey[j]))) % 65536 )) % 65536; + p1k[0] = (p1k[0] + tkip_sbox((p1k[4] ^ ((256*pbyTKey[1+j]) + pbyTKey[j])) % 65536)) % 65536; + p1k[1] = (p1k[1] + tkip_sbox((p1k[0] ^ ((256*pbyTKey[5+j]) + pbyTKey[4+j])) % 65536)) % 65536; + p1k[2] = (p1k[2] + tkip_sbox((p1k[1] ^ ((256*pbyTKey[9+j]) + pbyTKey[8+j])) % 65536)) % 65536; + p1k[3] = (p1k[3] + tkip_sbox((p1k[2] ^ ((256*pbyTKey[13+j]) + pbyTKey[12+j])) % 65536)) % 65536; + p1k[4] = (p1k[4] + tkip_sbox((p1k[3] ^ (((256*pbyTKey[1+j]) + pbyTKey[j]))) % 65536)) % 65536; p1k[4] = (p1k[4] + i) % 65536; } + /* Phase 2, Step 1 */ ppk0 = p1k[0]; ppk1 = p1k[1]; @@ -230,19 +231,19 @@ void TKIPvMixKey( ppk5 = (p1k[4] + tsc2) % 65536; /* Phase2, Step 2 */ - ppk0 = ppk0 + tkip_sbox( (ppk5 ^ ((256*pbyTKey[1]) + pbyTKey[0])) % 65536); - ppk1 = ppk1 + tkip_sbox( (ppk0 ^ ((256*pbyTKey[3]) + pbyTKey[2])) % 65536); - ppk2 = ppk2 + tkip_sbox( (ppk1 ^ ((256*pbyTKey[5]) + pbyTKey[4])) % 65536); - ppk3 = ppk3 + tkip_sbox( (ppk2 ^ ((256*pbyTKey[7]) + pbyTKey[6])) % 65536); - ppk4 = ppk4 + tkip_sbox( (ppk3 ^ ((256*pbyTKey[9]) + pbyTKey[8])) % 65536); - ppk5 = ppk5 + tkip_sbox( (ppk4 ^ ((256*pbyTKey[11]) + pbyTKey[10])) % 65536); - - ppk0 = ppk0 + rotr1(ppk5 ^ ((256*pbyTKey[13]) + pbyTKey[12])); - ppk1 = ppk1 + rotr1(ppk0 ^ ((256*pbyTKey[15]) + pbyTKey[14])); - ppk2 = ppk2 + rotr1(ppk1); - ppk3 = ppk3 + rotr1(ppk2); - ppk4 = ppk4 + rotr1(ppk3); - ppk5 = ppk5 + rotr1(ppk4); + ppk0 = ppk0 + tkip_sbox((ppk5 ^ ((256*pbyTKey[1]) + pbyTKey[0])) % 65536); + ppk1 = ppk1 + tkip_sbox((ppk0 ^ ((256*pbyTKey[3]) + pbyTKey[2])) % 65536); + ppk2 = ppk2 + tkip_sbox((ppk1 ^ ((256*pbyTKey[5]) + pbyTKey[4])) % 65536); + ppk3 = ppk3 + tkip_sbox((ppk2 ^ ((256*pbyTKey[7]) + pbyTKey[6])) % 65536); + ppk4 = ppk4 + tkip_sbox((ppk3 ^ ((256*pbyTKey[9]) + pbyTKey[8])) % 65536); + ppk5 = ppk5 + tkip_sbox((ppk4 ^ ((256*pbyTKey[11]) + pbyTKey[10])) % 65536); + + ppk0 = ppk0 + rotr1(ppk5 ^ ((256*pbyTKey[13]) + pbyTKey[12])); + ppk1 = ppk1 + rotr1(ppk0 ^ ((256*pbyTKey[15]) + pbyTKey[14])); + ppk2 = ppk2 + rotr1(ppk1); + ppk3 = ppk3 + rotr1(ppk2); + ppk4 = ppk4 + rotr1(ppk3); + ppk5 = ppk5 + rotr1(ppk4); /* Phase 2, Step 3 */ pbyRC4Key[0] = (tsc2 >> 8) % 256; -- cgit v1.2.3 From ba5c2b3ddcb7a6a0e942c7c2434f048d152f08c5 Mon Sep 17 00:00:00 2001 From: Felipe Andres Besoain Pino Date: Fri, 29 Oct 2010 19:15:58 -0300 Subject: staging: vt6656: resolved checkpatch finding removed spaces at the start of a lines. Signed-off-by: Felipe Andres Besoain Pino Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vt6656/dpc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/vt6656/dpc.c b/drivers/staging/vt6656/dpc.c index 1f9d29636803..f4fb0c6e4eac 100644 --- a/drivers/staging/vt6656/dpc.c +++ b/drivers/staging/vt6656/dpc.c @@ -1608,8 +1608,8 @@ void RXvMngWorkItem(void *Context) } } - pDevice->bIsRxMngWorkItemQueued = FALSE; - spin_unlock_irq(&pDevice->lock); + pDevice->bIsRxMngWorkItemQueued = FALSE; + spin_unlock_irq(&pDevice->lock); } -- cgit v1.2.3 From 72ca8819f7f4ac4ddf82ab72ee614075821a3d00 Mon Sep 17 00:00:00 2001 From: Pekka Enberg Date: Mon, 1 Nov 2010 21:50:05 +0200 Subject: Staging: w35und: Merge wbhal_f.h to wbhal_s.h This patch merges HAL struct and function definitions into one header file. Acked-by: Pavel Machek Signed-off-by: Pekka Enberg Signed-off-by: Greg Kroah-Hartman --- drivers/staging/winbond/mds.c | 3 +- drivers/staging/winbond/mto.c | 4 +- drivers/staging/winbond/phy_calibration.c | 4 +- drivers/staging/winbond/phy_calibration.h | 2 +- drivers/staging/winbond/reg.c | 4 +- drivers/staging/winbond/wb35reg_s.h | 74 ++++++++++++++++++++++++++++ drivers/staging/winbond/wb35tx_f.h | 1 - drivers/staging/winbond/wbhal_f.h | 81 ------------------------------- drivers/staging/winbond/wbusb.c | 5 +- 9 files changed, 90 insertions(+), 88 deletions(-) delete mode 100644 drivers/staging/winbond/wbhal_f.h diff --git a/drivers/staging/winbond/mds.c b/drivers/staging/winbond/mds.c index 9217762b1814..2128e6e6ff5a 100644 --- a/drivers/staging/winbond/mds.c +++ b/drivers/staging/winbond/mds.c @@ -2,8 +2,9 @@ #include "mlmetxrx_f.h" #include "mto.h" #include "sysdef.h" -#include "wbhal_f.h" +#include "wbhal_s.h" #include "wblinux_f.h" +#include "wb35tx_f.h" unsigned char Mds_initial(struct wbsoft_priv *adapter) diff --git a/drivers/staging/winbond/mto.c b/drivers/staging/winbond/mto.c index 9cd212783d61..05d12625dfcd 100644 --- a/drivers/staging/winbond/mto.c +++ b/drivers/staging/winbond/mto.c @@ -19,7 +19,9 @@ #include "sysdef.h" #include "sme_api.h" -#include "wbhal_f.h" +#include "wbhal_s.h" +#include "wb35reg_f.h" +#include "core.h" /* Declare SQ3 to rate and fragmentation threshold table */ /* Declare fragmentation thresholds table */ diff --git a/drivers/staging/winbond/phy_calibration.c b/drivers/staging/winbond/phy_calibration.c index 2b375ba3812a..08cec74bdad7 100644 --- a/drivers/staging/winbond/phy_calibration.c +++ b/drivers/staging/winbond/phy_calibration.c @@ -12,7 +12,9 @@ /****************** INCLUDE FILES SECTION ***********************************/ #include "sysdef.h" #include "phy_calibration.h" -#include "wbhal_f.h" +#include "wbhal_s.h" +#include "wb35reg_f.h" +#include "core.h" /****************** DEBUG CONSTANT AND MACRO SECTION ************************/ diff --git a/drivers/staging/winbond/phy_calibration.h b/drivers/staging/winbond/phy_calibration.h index 303203148839..9fcdab137cb3 100644 --- a/drivers/staging/winbond/phy_calibration.h +++ b/drivers/staging/winbond/phy_calibration.h @@ -1,7 +1,7 @@ #ifndef __WINBOND_PHY_CALIBRATION_H #define __WINBOND_PHY_CALIBRATION_H -#include "wbhal_f.h" +#include "wbhal_s.h" #define REG_AGC_CTRL1 0x1000 #define REG_AGC_CTRL2 0x1004 diff --git a/drivers/staging/winbond/reg.c b/drivers/staging/winbond/reg.c index 990f9d4bdbbd..8df05c4d26ff 100644 --- a/drivers/staging/winbond/reg.c +++ b/drivers/staging/winbond/reg.c @@ -1,5 +1,7 @@ #include "sysdef.h" -#include "wbhal_f.h" +#include "wbhal_s.h" +#include "wb35reg_f.h" +#include "core.h" /* * ==================================================== diff --git a/drivers/staging/winbond/wb35reg_s.h b/drivers/staging/winbond/wb35reg_s.h index 4eff009444b8..9d5993bfc1f4 100644 --- a/drivers/staging/winbond/wb35reg_s.h +++ b/drivers/staging/winbond/wb35reg_s.h @@ -5,6 +5,8 @@ #include #include +struct hw_data; + /* ========================================================================= * * HAL setting function @@ -168,4 +170,76 @@ struct wb35_reg { u32 SQ3_filter[MAX_SQ3_FILTER_SIZE]; u32 SQ3_index; }; + +/* ===================================================================== + * Function declaration + * ===================================================================== + */ +void hal_remove_mapping_key(struct hw_data *hw_data, u8 *mac_addr); +void hal_remove_default_key(struct hw_data *hw_data, u32 index); +unsigned char hal_set_mapping_key(struct hw_data *adapter, u8 *mac_addr, + u8 null_key, u8 wep_on, u8 *tx_tsc, + u8 *rx_tsc, u8 key_type, u8 key_len, + u8 *key_data); +unsigned char hal_set_default_key(struct hw_data *adapter, u8 index, + u8 null_key, u8 wep_on, u8 *tx_tsc, + u8 *rx_tsc, u8 key_type, u8 key_len, + u8 *key_data); +void hal_clear_all_default_key(struct hw_data *hw_data); +void hal_clear_all_group_key(struct hw_data *hw_data); +void hal_clear_all_mapping_key(struct hw_data *hw_data); +void hal_clear_all_key(struct hw_data *hw_data); +void hal_set_power_save_mode(struct hw_data *hw_data, unsigned char power_save, + unsigned char wakeup, unsigned char dtim); +void hal_get_power_save_mode(struct hw_data *hw_data, u8 *in_pwr_save); +void hal_set_slot_time(struct hw_data *hw_data, u8 type); + +#define hal_set_atim_window(_A, _ATM) + +void hal_start_bss(struct hw_data *hw_data, u8 mac_op_mode); + +/* 0:BSS STA 1:IBSS STA */ +void hal_join_request(struct hw_data *hw_data, u8 bss_type); + +void hal_stop_sync_bss(struct hw_data *hw_data); +void hal_resume_sync_bss(struct hw_data *hw_data); +void hal_set_aid(struct hw_data *hw_data, u16 aid); +void hal_set_bssid(struct hw_data *hw_data, u8 *bssid); +void hal_get_bssid(struct hw_data *hw_data, u8 *bssid); +void hal_set_listen_interval(struct hw_data *hw_data, u16 listen_interval); +void hal_set_cap_info(struct hw_data *hw_data, u16 capability_info); +void hal_set_ssid(struct hw_data *hw_data, u8 *ssid, u8 ssid_len); +void hal_start_tx0(struct hw_data *hw_data); + +#define hal_get_cwmin(_A) ((_A)->cwmin) + +void hal_set_cwmax(struct hw_data *hw_data, u16 cwin_max); + +#define hal_get_cwmax(_A) ((_A)->cwmax) + +void hal_set_rsn_wpa(struct hw_data *hw_data, u32 *rsn_ie_bitmap, + u32 *rsn_oui_type , unsigned char desired_auth_mode); +void hal_set_connect_info(struct hw_data *hw_data, unsigned char bo_connect); +u8 hal_get_est_sq3(struct hw_data *hw_data, u8 count); +void hal_descriptor_indicate(struct hw_data *hw_data, + struct wb35_descriptor *des); +u8 hal_get_antenna_number(struct hw_data *hw_data); +u32 hal_get_bss_pk_cnt(struct hw_data *hw_data); + +#define hal_get_region_from_EEPROM(_A) ((_A)->reg.EEPROMRegion) +#define hal_get_tx_buffer(_A, _B) Wb35Tx_get_tx_buffer(_A, _B) +#define hal_software_set(_A) (_A->SoftwareSet) +#define hal_driver_init_OK(_A) (_A->IsInitOK) +#define hal_rssi_boundary_high(_A) (_A->RSSI_high) +#define hal_rssi_boundary_low(_A) (_A->RSSI_low) +#define hal_scan_interval(_A) (_A->Scan_Interval) + +#define PHY_DEBUG(msg, args...) + +/* return 100ms count */ +#define hal_get_time_count(_P) (_P->time_count / 10) +#define hal_detect_error(_P) (_P->WbUsb.DetectCount) + +#define hal_ibss_disconnect(_A) (hal_stop_sync_bss(_A)) + #endif diff --git a/drivers/staging/winbond/wb35tx_f.h b/drivers/staging/winbond/wb35tx_f.h index 1d3b515f83bc..018fd35e815d 100644 --- a/drivers/staging/winbond/wb35tx_f.h +++ b/drivers/staging/winbond/wb35tx_f.h @@ -2,7 +2,6 @@ #define __WINBOND_WB35TX_F_H #include "core.h" -#include "wbhal_f.h" /* * ==================================== diff --git a/drivers/staging/winbond/wbhal_f.h b/drivers/staging/winbond/wbhal_f.h deleted file mode 100644 index fc78c14ae583..000000000000 --- a/drivers/staging/winbond/wbhal_f.h +++ /dev/null @@ -1,81 +0,0 @@ -/* - * ===================================================================== - * Device related include - * ===================================================================== -*/ -#include "wb35reg_f.h" -#include "wb35tx_f.h" -#include "wb35rx_f.h" - -#include "core.h" - -/* ===================================================================== - * Function declaration - * ===================================================================== - */ -void hal_remove_mapping_key(struct hw_data *hw_data, u8 *mac_addr); -void hal_remove_default_key(struct hw_data *hw_data, u32 index); -unsigned char hal_set_mapping_key(struct hw_data *adapter, u8 *mac_addr, - u8 null_key, u8 wep_on, u8 *tx_tsc, - u8 *rx_tsc, u8 key_type, u8 key_len, - u8 *key_data); -unsigned char hal_set_default_key(struct hw_data *adapter, u8 index, - u8 null_key, u8 wep_on, u8 *tx_tsc, - u8 *rx_tsc, u8 key_type, u8 key_len, - u8 *key_data); -void hal_clear_all_default_key(struct hw_data *hw_data); -void hal_clear_all_group_key(struct hw_data *hw_data); -void hal_clear_all_mapping_key(struct hw_data *hw_data); -void hal_clear_all_key(struct hw_data *hw_data); -void hal_set_power_save_mode(struct hw_data *hw_data, unsigned char power_save, - unsigned char wakeup, unsigned char dtim); -void hal_get_power_save_mode(struct hw_data *hw_data, u8 *in_pwr_save); -void hal_set_slot_time(struct hw_data *hw_data, u8 type); - -#define hal_set_atim_window(_A, _ATM) - -void hal_start_bss(struct hw_data *hw_data, u8 mac_op_mode); - -/* 0:BSS STA 1:IBSS STA */ -void hal_join_request(struct hw_data *hw_data, u8 bss_type); - -void hal_stop_sync_bss(struct hw_data *hw_data); -void hal_resume_sync_bss(struct hw_data *hw_data); -void hal_set_aid(struct hw_data *hw_data, u16 aid); -void hal_set_bssid(struct hw_data *hw_data, u8 *bssid); -void hal_get_bssid(struct hw_data *hw_data, u8 *bssid); -void hal_set_listen_interval(struct hw_data *hw_data, u16 listen_interval); -void hal_set_cap_info(struct hw_data *hw_data, u16 capability_info); -void hal_set_ssid(struct hw_data *hw_data, u8 *ssid, u8 ssid_len); -void hal_start_tx0(struct hw_data *hw_data); - -#define hal_get_cwmin(_A) ((_A)->cwmin) - -void hal_set_cwmax(struct hw_data *hw_data, u16 cwin_max); - -#define hal_get_cwmax(_A) ((_A)->cwmax) - -void hal_set_rsn_wpa(struct hw_data *hw_data, u32 *rsn_ie_bitmap, - u32 *rsn_oui_type , unsigned char desired_auth_mode); -void hal_set_connect_info(struct hw_data *hw_data, unsigned char bo_connect); -u8 hal_get_est_sq3(struct hw_data *hw_data, u8 count); -void hal_descriptor_indicate(struct hw_data *hw_data, - struct wb35_descriptor *des); -u8 hal_get_antenna_number(struct hw_data *hw_data); -u32 hal_get_bss_pk_cnt(struct hw_data *hw_data); - -#define hal_get_region_from_EEPROM(_A) ((_A)->reg.EEPROMRegion) -#define hal_get_tx_buffer(_A, _B) Wb35Tx_get_tx_buffer(_A, _B) -#define hal_software_set(_A) (_A->SoftwareSet) -#define hal_driver_init_OK(_A) (_A->IsInitOK) -#define hal_rssi_boundary_high(_A) (_A->RSSI_high) -#define hal_rssi_boundary_low(_A) (_A->RSSI_low) -#define hal_scan_interval(_A) (_A->Scan_Interval) - -#define PHY_DEBUG(msg, args...) - -/* return 100ms count */ -#define hal_get_time_count(_P) (_P->time_count / 10) -#define hal_detect_error(_P) (_P->WbUsb.DetectCount) - -#define hal_ibss_disconnect(_A) (hal_stop_sync_bss(_A)) diff --git a/drivers/staging/winbond/wbusb.c b/drivers/staging/winbond/wbusb.c index 3f60cf7e6ec1..a053bbb39610 100644 --- a/drivers/staging/winbond/wbusb.c +++ b/drivers/staging/winbond/wbusb.c @@ -16,7 +16,10 @@ #include "mds_f.h" #include "mlmetxrx_f.h" #include "mto.h" -#include "wbhal_f.h" +#include "wbhal_s.h" +#include "wb35reg_f.h" +#include "wb35tx_f.h" +#include "wb35rx_f.h" #include "wblinux_f.h" MODULE_DESCRIPTION("IS89C35 802.11bg WLAN USB Driver"); -- cgit v1.2.3 From b5ef076141acc223e55aa298abd2d2f5fb844874 Mon Sep 17 00:00:00 2001 From: Pekka Enberg Date: Mon, 1 Nov 2010 21:50:06 +0200 Subject: Staging: w35und: Rename wbhal_s.h to wbhal.h This patch renames the wbhal_s.h header file to wbhal.h now that it contains both structure and function definitions. Acked-by: Pavel Machek Signed-off-by: Pekka Enberg Signed-off-by: Greg Kroah-Hartman --- drivers/staging/winbond/core.h | 2 +- drivers/staging/winbond/mds.c | 2 +- drivers/staging/winbond/mds_f.h | 2 +- drivers/staging/winbond/mto.c | 2 +- drivers/staging/winbond/phy_calibration.c | 2 +- drivers/staging/winbond/phy_calibration.h | 2 +- drivers/staging/winbond/reg.c | 2 +- drivers/staging/winbond/wb35reg_f.h | 2 +- drivers/staging/winbond/wb35rx_f.h | 2 +- drivers/staging/winbond/wbhal.h | 525 ++++++++++++++++++++++++++++++ drivers/staging/winbond/wbhal_s.h | 525 ------------------------------ drivers/staging/winbond/wbusb.c | 2 +- 12 files changed, 535 insertions(+), 535 deletions(-) create mode 100644 drivers/staging/winbond/wbhal.h delete mode 100644 drivers/staging/winbond/wbhal_s.h diff --git a/drivers/staging/winbond/core.h b/drivers/staging/winbond/core.h index 2b87a0007319..d7b3aca5ddeb 100644 --- a/drivers/staging/winbond/core.h +++ b/drivers/staging/winbond/core.h @@ -4,7 +4,7 @@ #include #include -#include "wbhal_s.h" +#include "wbhal.h" #include "mto.h" #include "mac_structures.h" diff --git a/drivers/staging/winbond/mds.c b/drivers/staging/winbond/mds.c index 2128e6e6ff5a..9ac2c874ef05 100644 --- a/drivers/staging/winbond/mds.c +++ b/drivers/staging/winbond/mds.c @@ -2,7 +2,7 @@ #include "mlmetxrx_f.h" #include "mto.h" #include "sysdef.h" -#include "wbhal_s.h" +#include "wbhal.h" #include "wblinux_f.h" #include "wb35tx_f.h" diff --git a/drivers/staging/winbond/mds_f.h b/drivers/staging/winbond/mds_f.h index 7f68deae6d04..d902843e8aed 100644 --- a/drivers/staging/winbond/mds_f.h +++ b/drivers/staging/winbond/mds_f.h @@ -1,7 +1,7 @@ #ifndef __WINBOND_MDS_F_H #define __WINBOND_MDS_F_H -#include "wbhal_s.h" +#include "wbhal.h" #include "core.h" unsigned char Mds_initial(struct wbsoft_priv *adapter); diff --git a/drivers/staging/winbond/mto.c b/drivers/staging/winbond/mto.c index 05d12625dfcd..1faebceceff7 100644 --- a/drivers/staging/winbond/mto.c +++ b/drivers/staging/winbond/mto.c @@ -19,7 +19,7 @@ #include "sysdef.h" #include "sme_api.h" -#include "wbhal_s.h" +#include "wbhal.h" #include "wb35reg_f.h" #include "core.h" diff --git a/drivers/staging/winbond/phy_calibration.c b/drivers/staging/winbond/phy_calibration.c index 08cec74bdad7..0658b09c7853 100644 --- a/drivers/staging/winbond/phy_calibration.c +++ b/drivers/staging/winbond/phy_calibration.c @@ -12,7 +12,7 @@ /****************** INCLUDE FILES SECTION ***********************************/ #include "sysdef.h" #include "phy_calibration.h" -#include "wbhal_s.h" +#include "wbhal.h" #include "wb35reg_f.h" #include "core.h" diff --git a/drivers/staging/winbond/phy_calibration.h b/drivers/staging/winbond/phy_calibration.h index 9fcdab137cb3..84f6e840a47a 100644 --- a/drivers/staging/winbond/phy_calibration.h +++ b/drivers/staging/winbond/phy_calibration.h @@ -1,7 +1,7 @@ #ifndef __WINBOND_PHY_CALIBRATION_H #define __WINBOND_PHY_CALIBRATION_H -#include "wbhal_s.h" +#include "wbhal.h" #define REG_AGC_CTRL1 0x1000 #define REG_AGC_CTRL2 0x1004 diff --git a/drivers/staging/winbond/reg.c b/drivers/staging/winbond/reg.c index 8df05c4d26ff..439d213fe951 100644 --- a/drivers/staging/winbond/reg.c +++ b/drivers/staging/winbond/reg.c @@ -1,5 +1,5 @@ #include "sysdef.h" -#include "wbhal_s.h" +#include "wbhal.h" #include "wb35reg_f.h" #include "core.h" diff --git a/drivers/staging/winbond/wb35reg_f.h b/drivers/staging/winbond/wb35reg_f.h index bf23c1084199..95dc98096845 100644 --- a/drivers/staging/winbond/wb35reg_f.h +++ b/drivers/staging/winbond/wb35reg_f.h @@ -1,7 +1,7 @@ #ifndef __WINBOND_WB35REG_F_H #define __WINBOND_WB35REG_F_H -#include "wbhal_s.h" +#include "wbhal.h" /* * ==================================== diff --git a/drivers/staging/winbond/wb35rx_f.h b/drivers/staging/winbond/wb35rx_f.h index 98acce517d90..1fdf65ea6041 100644 --- a/drivers/staging/winbond/wb35rx_f.h +++ b/drivers/staging/winbond/wb35rx_f.h @@ -2,7 +2,7 @@ #define __WINBOND_WB35RX_F_H #include -#include "wbhal_s.h" +#include "wbhal.h" //==================================== // Interface function declare diff --git a/drivers/staging/winbond/wbhal.h b/drivers/staging/winbond/wbhal.h new file mode 100644 index 000000000000..821a1b3f1301 --- /dev/null +++ b/drivers/staging/winbond/wbhal.h @@ -0,0 +1,525 @@ +#ifndef __WINBOND_WBHAL_S_H +#define __WINBOND_WBHAL_S_H + +#include +#include /* for ETH_ALEN */ + +#define HAL_LED_SET_MASK 0x001c +#define HAL_LED_SET_SHIFT 2 + +/* supported RF type */ +#define RF_MAXIM_2825 0 +#define RF_MAXIM_2827 1 +#define RF_MAXIM_2828 2 +#define RF_MAXIM_2829 3 +#define RF_MAXIM_V1 15 +#define RF_AIROHA_2230 16 +#define RF_AIROHA_7230 17 +#define RF_AIROHA_2230S 18 +#define RF_WB_242 33 +#define RF_WB_242_1 34 +#define RF_DECIDE_BY_INF 255 + +/* + * ---------------------------------------------------------------- + * The follow define connect to upper layer + * User must modify for connection between HAL and upper layer + * ---------------------------------------------------------------- + */ + +/* + * ============================== + * Common define + * ============================== + */ +/* Bit 5 */ +#define HAL_USB_MODE_BURST(_H) (_H->SoftwareSet & 0x20) + +/* Scan interval */ +#define SCAN_MAX_CHNL_TIME (50) + +/* For TxL2 Frame typr recognise */ +#define FRAME_TYPE_802_3_DATA 0 +#define FRAME_TYPE_802_11_MANAGEMENT 1 +#define FRAME_TYPE_802_11_MANAGEMENT_CHALLENGE 2 +#define FRAME_TYPE_802_11_CONTROL 3 +#define FRAME_TYPE_802_11_DATA 4 +#define FRAME_TYPE_PROMISCUOUS 5 + +/* The follow definition is used for convert the frame------------ */ +#define DOT_11_SEQUENCE_OFFSET 22 /* Sequence control offset */ +#define DOT_3_TYPE_OFFSET 12 +#define DOT_11_MAC_HEADER_SIZE 24 +#define DOT_11_SNAP_SIZE 6 +#define DOT_11_TYPE_OFFSET 30 /* The start offset of 802.11 Frame. Type encapsulation. */ +#define DEFAULT_SIFSTIME 10 +#define DEFAULT_FRAGMENT_THRESHOLD 2346 /* No fragment */ +#define DEFAULT_MSDU_LIFE_TIME 0xffff + +#define LONG_PREAMBLE_PLUS_PLCPHEADER_TIME (144 + 48) +#define SHORT_PREAMBLE_PLUS_PLCPHEADER_TIME (72 + 24) +#define PREAMBLE_PLUS_SIGNAL_PLUS_SIGNALEXTENSION (16 + 4 + 6) +#define Tsym 4 + +/* Frame Type of Bits (2, 3)----------------------------------- */ +#define MAC_TYPE_MANAGEMENT 0x00 +#define MAC_TYPE_CONTROL 0x04 +#define MAC_TYPE_DATA 0x08 +#define MASK_FRAGMENT_NUMBER 0x000F +#define SEQUENCE_NUMBER_SHIFT 4 + +#define HAL_WOL_TYPE_WAKEUP_FRAME 0x01 +#define HAL_WOL_TYPE_MAGIC_PACKET 0x02 + +#define HAL_KEYTYPE_WEP40 0 +#define HAL_KEYTYPE_WEP104 1 +#define HAL_KEYTYPE_TKIP 2 /* 128 bit key */ +#define HAL_KEYTYPE_AES_CCMP 3 /* 128 bit key */ + +/* For VM state */ +enum { + VM_STOP = 0, + VM_RUNNING, + VM_COMPLETED +}; + +/* + * ================================ + * Normal Key table format + * ================================ + */ + +/* The order of KEY index is MAPPING_KEY_START_INDEX > GROUP_KEY_START_INDEX */ +#define MAX_KEY_TABLE 24 /* 24 entry for storing key data */ +#define GROUP_KEY_START_INDEX 4 +#define MAPPING_KEY_START_INDEX 8 + +/* + * ========================================= + * Descriptor + * ========================================= + */ +#define MAX_DESCRIPTOR_BUFFER_INDEX 8 /* Have to multiple of 2 */ +#define FLAG_ERROR_TX_MASK 0x000000bf +#define FLAG_ERROR_RX_MASK 0x0000083f + +#define FLAG_BAND_RX_MASK 0x10000000 /* Bit 28 */ + +struct R00_descriptor { + union { + u32 value; +#ifdef _BIG_ENDIAN_ + struct { + u32 R00_packet_or_buffer_status:1; + u32 R00_packet_in_fifo:1; + u32 R00_RESERVED:2; + u32 R00_receive_byte_count:12; + u32 R00_receive_time_index:16; + }; +#else + struct { + u32 R00_receive_time_index:16; + u32 R00_receive_byte_count:12; + u32 R00_RESERVED:2; + u32 R00_packet_in_fifo:1; + u32 R00_packet_or_buffer_status:1; + }; +#endif + }; +}; + +struct T00_descriptor { + union { + u32 value; +#ifdef _BIG_ENDIAN_ + struct { + u32 T00_first_mpdu:1; /* for hardware use */ + u32 T00_last_mpdu:1; /* for hardware use */ + u32 T00_IsLastMpdu:1;/* 0:not 1:Yes for software used */ + u32 T00_IgnoreResult:1;/* The same mechanism with T00 setting. */ + u32 T00_RESERVED_ID:2;/* 3 bit ID reserved */ + u32 T00_tx_packet_id:4; + u32 T00_RESERVED:4; + u32 T00_header_length:6; + u32 T00_frame_length:12; + }; +#else + struct { + u32 T00_frame_length:12; + u32 T00_header_length:6; + u32 T00_RESERVED:4; + u32 T00_tx_packet_id:4; + u32 T00_RESERVED_ID:2; /* 3 bit ID reserved */ + u32 T00_IgnoreResult:1; /* The same mechanism with T00 setting. */ + u32 T00_IsLastMpdu:1; /* 0:not 1:Yes for software used */ + u32 T00_last_mpdu:1; /* for hardware use */ + u32 T00_first_mpdu:1; /* for hardware use */ + }; +#endif + }; +}; + +struct R01_descriptor { + union { + u32 value; +#ifdef _BIG_ENDIAN_ + struct { + u32 R01_RESERVED:3; + u32 R01_mod_type:1; + u32 R01_pre_type:1; + u32 R01_data_rate:3; + u32 R01_AGC_state:8; + u32 R01_LNA_state:2; + u32 R01_decryption_method:2; + u32 R01_mic_error:1; + u32 R01_replay:1; + u32 R01_broadcast_frame:1; + u32 R01_multicast_frame:1; + u32 R01_directed_frame:1; + u32 R01_receive_frame_antenna_selection:1; + u32 R01_frame_receive_during_atim_window:1; + u32 R01_protocol_version_error:1; + u32 R01_authentication_frame_icv_error:1; + u32 R01_null_key_to_authentication_frame:1; + u32 R01_icv_error:1; + u32 R01_crc_error:1; + }; +#else + struct { + u32 R01_crc_error:1; + u32 R01_icv_error:1; + u32 R01_null_key_to_authentication_frame:1; + u32 R01_authentication_frame_icv_error:1; + u32 R01_protocol_version_error:1; + u32 R01_frame_receive_during_atim_window:1; + u32 R01_receive_frame_antenna_selection:1; + u32 R01_directed_frame:1; + u32 R01_multicast_frame:1; + u32 R01_broadcast_frame:1; + u32 R01_replay:1; + u32 R01_mic_error:1; + u32 R01_decryption_method:2; + u32 R01_LNA_state:2; + u32 R01_AGC_state:8; + u32 R01_data_rate:3; + u32 R01_pre_type:1; + u32 R01_mod_type:1; + u32 R01_RESERVED:3; + }; +#endif + }; +}; + +struct T01_descriptor { + union { + u32 value; +#ifdef _BIG_ENDIAN_ + struct { + u32 T01_rts_cts_duration:16; + u32 T01_fall_back_rate:3; + u32 T01_add_rts:1; + u32 T01_add_cts:1; + u32 T01_modulation_type:1; + u32 T01_plcp_header_length:1; + u32 T01_transmit_rate:3; + u32 T01_wep_id:2; + u32 T01_add_challenge_text:1; + u32 T01_inhibit_crc:1; + u32 T01_loop_back_wep_mode:1; + u32 T01_retry_abort_ebable:1; + }; +#else + struct { + u32 T01_retry_abort_ebable:1; + u32 T01_loop_back_wep_mode:1; + u32 T01_inhibit_crc:1; + u32 T01_add_challenge_text:1; + u32 T01_wep_id:2; + u32 T01_transmit_rate:3; + u32 T01_plcp_header_length:1; + u32 T01_modulation_type:1; + u32 T01_add_cts:1; + u32 T01_add_rts:1; + u32 T01_fall_back_rate:3; + u32 T01_rts_cts_duration:16; + }; +#endif + }; +}; + +struct T02_descriptor { + union { + u32 value; +#ifdef _BIG_ENDIAN_ + struct { + u32 T02_IsLastMpdu:1; /* The same mechanism with T00 setting */ + u32 T02_IgnoreResult:1; /* The same mechanism with T00 setting. */ + u32 T02_RESERVED_ID:2; /* The same mechanism with T00 setting */ + u32 T02_Tx_PktID:4; + u32 T02_MPDU_Cnt:4; + u32 T02_RTS_Cnt:4; + u32 T02_RESERVED:7; + u32 T02_transmit_complete:1; + u32 T02_transmit_abort_due_to_TBTT:1; + u32 T02_effective_transmission_rate:1; + u32 T02_transmit_without_encryption_due_to_wep_on_false:1; + u32 T02_discard_due_to_null_wep_key:1; + u32 T02_RESERVED_1:1; + u32 T02_out_of_MaxTxMSDULiftTime:1; + u32 T02_transmit_abort:1; + u32 T02_transmit_fail:1; + }; +#else + struct { + u32 T02_transmit_fail:1; + u32 T02_transmit_abort:1; + u32 T02_out_of_MaxTxMSDULiftTime:1; + u32 T02_RESERVED_1:1; + u32 T02_discard_due_to_null_wep_key:1; + u32 T02_transmit_without_encryption_due_to_wep_on_false:1; + u32 T02_effective_transmission_rate:1; + u32 T02_transmit_abort_due_to_TBTT:1; + u32 T02_transmit_complete:1; + u32 T02_RESERVED:7; + u32 T02_RTS_Cnt:4; + u32 T02_MPDU_Cnt:4; + u32 T02_Tx_PktID:4; + u32 T02_RESERVED_ID:2; /* The same mechanism with T00 setting */ + u32 T02_IgnoreResult:1; /* The same mechanism with T00 setting. */ + u32 T02_IsLastMpdu:1; /* The same mechanism with T00 setting */ + }; +#endif + }; +}; + +struct wb35_descriptor { /* Skip length = 8 DWORD */ + /* ID for descriptor ---, The field doesn't be cleard in the operation of Descriptor definition */ + u8 Descriptor_ID; + /* ----------------------The above region doesn't be cleared by DESCRIPTOR_RESET------ */ + u8 RESERVED[3]; + + u16 FragmentThreshold; + u8 InternalUsed; /* Only can be used by operation of descriptor definition */ + u8 Type; /* 0: 802.3 1:802.11 data frame 2:802.11 management frame */ + + u8 PreambleMode;/* 0: short 1:long */ + u8 TxRate; + u8 FragmentCount; + u8 EapFix; /* For speed up key install */ + + /* For R00 and T00 ------------------------------ */ + union { + struct R00_descriptor R00; + struct T00_descriptor T00; + }; + + /* For R01 and T01 ------------------------------ */ + union { + struct R01_descriptor R01; + struct T01_descriptor T01; + }; + + /* For R02 and T02 ------------------------------ */ + union { + u32 R02; + struct T02_descriptor T02; + }; + + /* For R03 and T03 ------------------------------ */ + /* For software used */ + union { + u32 R03; + u32 T03; + struct { + u8 buffer_number; + u8 buffer_start_index; + u16 buffer_total_size; + }; + }; + + /* For storing the buffer */ + u16 buffer_size[MAX_DESCRIPTOR_BUFFER_INDEX]; + void *buffer_address[MAX_DESCRIPTOR_BUFFER_INDEX]; +}; + + +#define DEFAULT_NULL_PACKET_COUNT 180000 /* 180 seconds */ + +#define MAX_TXVGA_EEPROM 9 /* How many word(u16) of EEPROM will be used for TxVGA */ +#define MAX_RF_PARAMETER 32 + +struct txvga_for_50 { + u8 ChanNo; + u8 TxVgaValue; +}; + +/* + * ============================================== + * Device related include + * ============================================== + */ + +#include "wbusb_s.h" +#include "wb35reg_s.h" +#include "wb35tx_s.h" +#include "wb35rx_s.h" + +/* For Hal using ============================================ */ +struct hw_data { + /* For compatible with 33 */ + u32 revision; + u32 BB3c_cal; /* The value for Tx calibration comes from EEPROM */ + u32 BB54_cal; /* The value for Rx calibration comes from EEPROM */ + + /* For surprise remove */ + u32 SurpriseRemove; /* 0: Normal 1: Surprise remove */ + u8 IsKeyPreSet; + u8 CalOneTime; + + u8 VCO_trim; + + u32 FragCount; + u32 DMAFix; /* V1_DMA_FIX The variable can be removed if driver want to save mem space for V2. */ + + /* + * =============================================== + * Definition for MAC address + * =============================================== + */ + u8 PermanentMacAddress[ETH_ALEN + 2]; /* The Ethernet addr that are stored in EEPROM. + 2 to 8-byte alignment */ + u8 CurrentMacAddress[ETH_ALEN + 2]; /* The Enthernet addr that are in used. + 2 to 8-byte alignment */ + + /* + * ========================================= + * Definition for 802.11 + * ========================================= + */ + u8 *bssid_pointer; /* Used by hal_get_bssid for return value */ + u8 bssid[8]; /* Only 6 byte will be used. 8 byte is required for read buffer */ + u8 ssid[32]; /* maximum ssid length is 32 byte */ + + u16 AID; + u8 ssid_length; + u8 Channel; + + u16 ListenInterval; + u16 CapabilityInformation; + + u16 BeaconPeriod; + u16 ProbeDelay; + + u8 bss_type;/* 0: IBSS_NET or 1:ESS_NET */ + u8 preamble;/* 0: short preamble, 1: long preamble */ + u8 slot_time_select; /* 9 or 20 value */ + u8 phy_type; /* Phy select */ + + u32 phy_para[MAX_RF_PARAMETER]; + u32 phy_number; + + u32 CurrentRadioSw; /* 0:On 1:Off */ + u32 CurrentRadioHw; /* 0:On 1:Off */ + + u8 *power_save_point; /* Used by hal_get_power_save_mode for return value */ + u8 cwmin; + u8 desired_power_save; + u8 dtim; /* Is running dtim */ + u8 mapping_key_replace_index; /* In Key table, the next index be replaced */ + + u16 MaxReceiveLifeTime; + u16 FragmentThreshold; + u16 FragmentThreshold_tmp; + u16 cwmax; + + u8 Key_slot[MAX_KEY_TABLE][8]; /* Ownership record for key slot. For Alignment */ + u32 Key_content[MAX_KEY_TABLE][12]; /* 10DW for each entry + 2 for burst command (Off and On valid bit) */ + u8 CurrentDefaultKeyIndex; + u32 CurrentDefaultKeyLength; + + /* + * ================================================== + * Variable for each module + * ================================================== + */ + struct wb_usb WbUsb; /* Need WbUsb.h */ + struct wb35_reg reg; /* Need Wb35Reg.h */ + struct wb35_tx Wb35Tx; /* Need Wb35Tx.h */ + struct wb35_rx Wb35Rx; /* Need Wb35Rx.h */ + + struct timer_list LEDTimer; /* For LED */ + + u32 LEDpoint; /* For LED */ + + u32 dto_tx_retry_count; + u32 dto_tx_frag_count; + u32 rx_ok_count[13]; /* index=0: total rx ok */ + u32 rx_err_count[13]; /* index=0: total rx err */ + + /* for Tx debug */ + u32 tx_TBTT_start_count; + u32 tx_ETR_count; + u32 tx_WepOn_false_count; + u32 tx_Null_key_count; + u32 tx_retry_count[8]; + + u8 PowerIndexFromEEPROM; /* For 2412MHz */ + u8 power_index; + u8 IsWaitJoinComplete; /* TRUE: set join request */ + u8 band; + + u16 SoftwareSet; + u16 Reserved_s; + + u32 IsInitOK; /* 0: Driver starting 1: Driver init OK */ + + /* For Phy calibration */ + s32 iq_rsdl_gain_tx_d2; + s32 iq_rsdl_phase_tx_d2; + u32 txvga_setting_for_cal; + + u8 TxVgaSettingInEEPROM[(((MAX_TXVGA_EEPROM * 2) + 3) & ~0x03)]; /* For EEPROM value */ + u8 TxVgaFor24[16]; /* Max is 14, 2 for alignment */ + struct txvga_for_50 TxVgaFor50[36]; /* 35 channels in 5G. 35x2 = 70 byte. 2 for alignments */ + + u16 Scan_Interval; + u16 RESERVED6; + + /* LED control */ + u32 LED_control; + /* + * LED_control 4 byte: Gray_Led_1[3] Gray_Led_0[2] Led[1] Led[0] + * Gray_Led + * For Led gray setting + * Led + * 0: normal control, + * LED behavior will decide by EEPROM setting + * 1: Turn off specific LED + * 2: Always on specific LED + * 3: slow blinking specific LED + * 4: fast blinking specific LED + * 5: WPS led control is set. Led0 is Red, Led1 id Green + * + * Led[1] is parameter for WPS LED mode + * 1:InProgress + * 2: Error + * 3: Session overlap + * 4: Success control + */ + u32 LED_LinkOn; /* Turn LED on control */ + u32 LED_Scanning; /* Let LED in scan process control */ + u32 LED_Blinking; /* Temp variable for shining */ + u32 RxByteCountLast; + u32 TxByteCountLast; + + atomic_t SurpriseRemoveCount; + + /* For global timer */ + u32 time_count; /* TICK_TIME_100ms 1 = 100ms */ + + /* For error recover */ + u32 HwStop; + + /* For avoid AP disconnect */ + u32 NullPacketCount; +}; + +#endif diff --git a/drivers/staging/winbond/wbhal_s.h b/drivers/staging/winbond/wbhal_s.h deleted file mode 100644 index 821a1b3f1301..000000000000 --- a/drivers/staging/winbond/wbhal_s.h +++ /dev/null @@ -1,525 +0,0 @@ -#ifndef __WINBOND_WBHAL_S_H -#define __WINBOND_WBHAL_S_H - -#include -#include /* for ETH_ALEN */ - -#define HAL_LED_SET_MASK 0x001c -#define HAL_LED_SET_SHIFT 2 - -/* supported RF type */ -#define RF_MAXIM_2825 0 -#define RF_MAXIM_2827 1 -#define RF_MAXIM_2828 2 -#define RF_MAXIM_2829 3 -#define RF_MAXIM_V1 15 -#define RF_AIROHA_2230 16 -#define RF_AIROHA_7230 17 -#define RF_AIROHA_2230S 18 -#define RF_WB_242 33 -#define RF_WB_242_1 34 -#define RF_DECIDE_BY_INF 255 - -/* - * ---------------------------------------------------------------- - * The follow define connect to upper layer - * User must modify for connection between HAL and upper layer - * ---------------------------------------------------------------- - */ - -/* - * ============================== - * Common define - * ============================== - */ -/* Bit 5 */ -#define HAL_USB_MODE_BURST(_H) (_H->SoftwareSet & 0x20) - -/* Scan interval */ -#define SCAN_MAX_CHNL_TIME (50) - -/* For TxL2 Frame typr recognise */ -#define FRAME_TYPE_802_3_DATA 0 -#define FRAME_TYPE_802_11_MANAGEMENT 1 -#define FRAME_TYPE_802_11_MANAGEMENT_CHALLENGE 2 -#define FRAME_TYPE_802_11_CONTROL 3 -#define FRAME_TYPE_802_11_DATA 4 -#define FRAME_TYPE_PROMISCUOUS 5 - -/* The follow definition is used for convert the frame------------ */ -#define DOT_11_SEQUENCE_OFFSET 22 /* Sequence control offset */ -#define DOT_3_TYPE_OFFSET 12 -#define DOT_11_MAC_HEADER_SIZE 24 -#define DOT_11_SNAP_SIZE 6 -#define DOT_11_TYPE_OFFSET 30 /* The start offset of 802.11 Frame. Type encapsulation. */ -#define DEFAULT_SIFSTIME 10 -#define DEFAULT_FRAGMENT_THRESHOLD 2346 /* No fragment */ -#define DEFAULT_MSDU_LIFE_TIME 0xffff - -#define LONG_PREAMBLE_PLUS_PLCPHEADER_TIME (144 + 48) -#define SHORT_PREAMBLE_PLUS_PLCPHEADER_TIME (72 + 24) -#define PREAMBLE_PLUS_SIGNAL_PLUS_SIGNALEXTENSION (16 + 4 + 6) -#define Tsym 4 - -/* Frame Type of Bits (2, 3)----------------------------------- */ -#define MAC_TYPE_MANAGEMENT 0x00 -#define MAC_TYPE_CONTROL 0x04 -#define MAC_TYPE_DATA 0x08 -#define MASK_FRAGMENT_NUMBER 0x000F -#define SEQUENCE_NUMBER_SHIFT 4 - -#define HAL_WOL_TYPE_WAKEUP_FRAME 0x01 -#define HAL_WOL_TYPE_MAGIC_PACKET 0x02 - -#define HAL_KEYTYPE_WEP40 0 -#define HAL_KEYTYPE_WEP104 1 -#define HAL_KEYTYPE_TKIP 2 /* 128 bit key */ -#define HAL_KEYTYPE_AES_CCMP 3 /* 128 bit key */ - -/* For VM state */ -enum { - VM_STOP = 0, - VM_RUNNING, - VM_COMPLETED -}; - -/* - * ================================ - * Normal Key table format - * ================================ - */ - -/* The order of KEY index is MAPPING_KEY_START_INDEX > GROUP_KEY_START_INDEX */ -#define MAX_KEY_TABLE 24 /* 24 entry for storing key data */ -#define GROUP_KEY_START_INDEX 4 -#define MAPPING_KEY_START_INDEX 8 - -/* - * ========================================= - * Descriptor - * ========================================= - */ -#define MAX_DESCRIPTOR_BUFFER_INDEX 8 /* Have to multiple of 2 */ -#define FLAG_ERROR_TX_MASK 0x000000bf -#define FLAG_ERROR_RX_MASK 0x0000083f - -#define FLAG_BAND_RX_MASK 0x10000000 /* Bit 28 */ - -struct R00_descriptor { - union { - u32 value; -#ifdef _BIG_ENDIAN_ - struct { - u32 R00_packet_or_buffer_status:1; - u32 R00_packet_in_fifo:1; - u32 R00_RESERVED:2; - u32 R00_receive_byte_count:12; - u32 R00_receive_time_index:16; - }; -#else - struct { - u32 R00_receive_time_index:16; - u32 R00_receive_byte_count:12; - u32 R00_RESERVED:2; - u32 R00_packet_in_fifo:1; - u32 R00_packet_or_buffer_status:1; - }; -#endif - }; -}; - -struct T00_descriptor { - union { - u32 value; -#ifdef _BIG_ENDIAN_ - struct { - u32 T00_first_mpdu:1; /* for hardware use */ - u32 T00_last_mpdu:1; /* for hardware use */ - u32 T00_IsLastMpdu:1;/* 0:not 1:Yes for software used */ - u32 T00_IgnoreResult:1;/* The same mechanism with T00 setting. */ - u32 T00_RESERVED_ID:2;/* 3 bit ID reserved */ - u32 T00_tx_packet_id:4; - u32 T00_RESERVED:4; - u32 T00_header_length:6; - u32 T00_frame_length:12; - }; -#else - struct { - u32 T00_frame_length:12; - u32 T00_header_length:6; - u32 T00_RESERVED:4; - u32 T00_tx_packet_id:4; - u32 T00_RESERVED_ID:2; /* 3 bit ID reserved */ - u32 T00_IgnoreResult:1; /* The same mechanism with T00 setting. */ - u32 T00_IsLastMpdu:1; /* 0:not 1:Yes for software used */ - u32 T00_last_mpdu:1; /* for hardware use */ - u32 T00_first_mpdu:1; /* for hardware use */ - }; -#endif - }; -}; - -struct R01_descriptor { - union { - u32 value; -#ifdef _BIG_ENDIAN_ - struct { - u32 R01_RESERVED:3; - u32 R01_mod_type:1; - u32 R01_pre_type:1; - u32 R01_data_rate:3; - u32 R01_AGC_state:8; - u32 R01_LNA_state:2; - u32 R01_decryption_method:2; - u32 R01_mic_error:1; - u32 R01_replay:1; - u32 R01_broadcast_frame:1; - u32 R01_multicast_frame:1; - u32 R01_directed_frame:1; - u32 R01_receive_frame_antenna_selection:1; - u32 R01_frame_receive_during_atim_window:1; - u32 R01_protocol_version_error:1; - u32 R01_authentication_frame_icv_error:1; - u32 R01_null_key_to_authentication_frame:1; - u32 R01_icv_error:1; - u32 R01_crc_error:1; - }; -#else - struct { - u32 R01_crc_error:1; - u32 R01_icv_error:1; - u32 R01_null_key_to_authentication_frame:1; - u32 R01_authentication_frame_icv_error:1; - u32 R01_protocol_version_error:1; - u32 R01_frame_receive_during_atim_window:1; - u32 R01_receive_frame_antenna_selection:1; - u32 R01_directed_frame:1; - u32 R01_multicast_frame:1; - u32 R01_broadcast_frame:1; - u32 R01_replay:1; - u32 R01_mic_error:1; - u32 R01_decryption_method:2; - u32 R01_LNA_state:2; - u32 R01_AGC_state:8; - u32 R01_data_rate:3; - u32 R01_pre_type:1; - u32 R01_mod_type:1; - u32 R01_RESERVED:3; - }; -#endif - }; -}; - -struct T01_descriptor { - union { - u32 value; -#ifdef _BIG_ENDIAN_ - struct { - u32 T01_rts_cts_duration:16; - u32 T01_fall_back_rate:3; - u32 T01_add_rts:1; - u32 T01_add_cts:1; - u32 T01_modulation_type:1; - u32 T01_plcp_header_length:1; - u32 T01_transmit_rate:3; - u32 T01_wep_id:2; - u32 T01_add_challenge_text:1; - u32 T01_inhibit_crc:1; - u32 T01_loop_back_wep_mode:1; - u32 T01_retry_abort_ebable:1; - }; -#else - struct { - u32 T01_retry_abort_ebable:1; - u32 T01_loop_back_wep_mode:1; - u32 T01_inhibit_crc:1; - u32 T01_add_challenge_text:1; - u32 T01_wep_id:2; - u32 T01_transmit_rate:3; - u32 T01_plcp_header_length:1; - u32 T01_modulation_type:1; - u32 T01_add_cts:1; - u32 T01_add_rts:1; - u32 T01_fall_back_rate:3; - u32 T01_rts_cts_duration:16; - }; -#endif - }; -}; - -struct T02_descriptor { - union { - u32 value; -#ifdef _BIG_ENDIAN_ - struct { - u32 T02_IsLastMpdu:1; /* The same mechanism with T00 setting */ - u32 T02_IgnoreResult:1; /* The same mechanism with T00 setting. */ - u32 T02_RESERVED_ID:2; /* The same mechanism with T00 setting */ - u32 T02_Tx_PktID:4; - u32 T02_MPDU_Cnt:4; - u32 T02_RTS_Cnt:4; - u32 T02_RESERVED:7; - u32 T02_transmit_complete:1; - u32 T02_transmit_abort_due_to_TBTT:1; - u32 T02_effective_transmission_rate:1; - u32 T02_transmit_without_encryption_due_to_wep_on_false:1; - u32 T02_discard_due_to_null_wep_key:1; - u32 T02_RESERVED_1:1; - u32 T02_out_of_MaxTxMSDULiftTime:1; - u32 T02_transmit_abort:1; - u32 T02_transmit_fail:1; - }; -#else - struct { - u32 T02_transmit_fail:1; - u32 T02_transmit_abort:1; - u32 T02_out_of_MaxTxMSDULiftTime:1; - u32 T02_RESERVED_1:1; - u32 T02_discard_due_to_null_wep_key:1; - u32 T02_transmit_without_encryption_due_to_wep_on_false:1; - u32 T02_effective_transmission_rate:1; - u32 T02_transmit_abort_due_to_TBTT:1; - u32 T02_transmit_complete:1; - u32 T02_RESERVED:7; - u32 T02_RTS_Cnt:4; - u32 T02_MPDU_Cnt:4; - u32 T02_Tx_PktID:4; - u32 T02_RESERVED_ID:2; /* The same mechanism with T00 setting */ - u32 T02_IgnoreResult:1; /* The same mechanism with T00 setting. */ - u32 T02_IsLastMpdu:1; /* The same mechanism with T00 setting */ - }; -#endif - }; -}; - -struct wb35_descriptor { /* Skip length = 8 DWORD */ - /* ID for descriptor ---, The field doesn't be cleard in the operation of Descriptor definition */ - u8 Descriptor_ID; - /* ----------------------The above region doesn't be cleared by DESCRIPTOR_RESET------ */ - u8 RESERVED[3]; - - u16 FragmentThreshold; - u8 InternalUsed; /* Only can be used by operation of descriptor definition */ - u8 Type; /* 0: 802.3 1:802.11 data frame 2:802.11 management frame */ - - u8 PreambleMode;/* 0: short 1:long */ - u8 TxRate; - u8 FragmentCount; - u8 EapFix; /* For speed up key install */ - - /* For R00 and T00 ------------------------------ */ - union { - struct R00_descriptor R00; - struct T00_descriptor T00; - }; - - /* For R01 and T01 ------------------------------ */ - union { - struct R01_descriptor R01; - struct T01_descriptor T01; - }; - - /* For R02 and T02 ------------------------------ */ - union { - u32 R02; - struct T02_descriptor T02; - }; - - /* For R03 and T03 ------------------------------ */ - /* For software used */ - union { - u32 R03; - u32 T03; - struct { - u8 buffer_number; - u8 buffer_start_index; - u16 buffer_total_size; - }; - }; - - /* For storing the buffer */ - u16 buffer_size[MAX_DESCRIPTOR_BUFFER_INDEX]; - void *buffer_address[MAX_DESCRIPTOR_BUFFER_INDEX]; -}; - - -#define DEFAULT_NULL_PACKET_COUNT 180000 /* 180 seconds */ - -#define MAX_TXVGA_EEPROM 9 /* How many word(u16) of EEPROM will be used for TxVGA */ -#define MAX_RF_PARAMETER 32 - -struct txvga_for_50 { - u8 ChanNo; - u8 TxVgaValue; -}; - -/* - * ============================================== - * Device related include - * ============================================== - */ - -#include "wbusb_s.h" -#include "wb35reg_s.h" -#include "wb35tx_s.h" -#include "wb35rx_s.h" - -/* For Hal using ============================================ */ -struct hw_data { - /* For compatible with 33 */ - u32 revision; - u32 BB3c_cal; /* The value for Tx calibration comes from EEPROM */ - u32 BB54_cal; /* The value for Rx calibration comes from EEPROM */ - - /* For surprise remove */ - u32 SurpriseRemove; /* 0: Normal 1: Surprise remove */ - u8 IsKeyPreSet; - u8 CalOneTime; - - u8 VCO_trim; - - u32 FragCount; - u32 DMAFix; /* V1_DMA_FIX The variable can be removed if driver want to save mem space for V2. */ - - /* - * =============================================== - * Definition for MAC address - * =============================================== - */ - u8 PermanentMacAddress[ETH_ALEN + 2]; /* The Ethernet addr that are stored in EEPROM. + 2 to 8-byte alignment */ - u8 CurrentMacAddress[ETH_ALEN + 2]; /* The Enthernet addr that are in used. + 2 to 8-byte alignment */ - - /* - * ========================================= - * Definition for 802.11 - * ========================================= - */ - u8 *bssid_pointer; /* Used by hal_get_bssid for return value */ - u8 bssid[8]; /* Only 6 byte will be used. 8 byte is required for read buffer */ - u8 ssid[32]; /* maximum ssid length is 32 byte */ - - u16 AID; - u8 ssid_length; - u8 Channel; - - u16 ListenInterval; - u16 CapabilityInformation; - - u16 BeaconPeriod; - u16 ProbeDelay; - - u8 bss_type;/* 0: IBSS_NET or 1:ESS_NET */ - u8 preamble;/* 0: short preamble, 1: long preamble */ - u8 slot_time_select; /* 9 or 20 value */ - u8 phy_type; /* Phy select */ - - u32 phy_para[MAX_RF_PARAMETER]; - u32 phy_number; - - u32 CurrentRadioSw; /* 0:On 1:Off */ - u32 CurrentRadioHw; /* 0:On 1:Off */ - - u8 *power_save_point; /* Used by hal_get_power_save_mode for return value */ - u8 cwmin; - u8 desired_power_save; - u8 dtim; /* Is running dtim */ - u8 mapping_key_replace_index; /* In Key table, the next index be replaced */ - - u16 MaxReceiveLifeTime; - u16 FragmentThreshold; - u16 FragmentThreshold_tmp; - u16 cwmax; - - u8 Key_slot[MAX_KEY_TABLE][8]; /* Ownership record for key slot. For Alignment */ - u32 Key_content[MAX_KEY_TABLE][12]; /* 10DW for each entry + 2 for burst command (Off and On valid bit) */ - u8 CurrentDefaultKeyIndex; - u32 CurrentDefaultKeyLength; - - /* - * ================================================== - * Variable for each module - * ================================================== - */ - struct wb_usb WbUsb; /* Need WbUsb.h */ - struct wb35_reg reg; /* Need Wb35Reg.h */ - struct wb35_tx Wb35Tx; /* Need Wb35Tx.h */ - struct wb35_rx Wb35Rx; /* Need Wb35Rx.h */ - - struct timer_list LEDTimer; /* For LED */ - - u32 LEDpoint; /* For LED */ - - u32 dto_tx_retry_count; - u32 dto_tx_frag_count; - u32 rx_ok_count[13]; /* index=0: total rx ok */ - u32 rx_err_count[13]; /* index=0: total rx err */ - - /* for Tx debug */ - u32 tx_TBTT_start_count; - u32 tx_ETR_count; - u32 tx_WepOn_false_count; - u32 tx_Null_key_count; - u32 tx_retry_count[8]; - - u8 PowerIndexFromEEPROM; /* For 2412MHz */ - u8 power_index; - u8 IsWaitJoinComplete; /* TRUE: set join request */ - u8 band; - - u16 SoftwareSet; - u16 Reserved_s; - - u32 IsInitOK; /* 0: Driver starting 1: Driver init OK */ - - /* For Phy calibration */ - s32 iq_rsdl_gain_tx_d2; - s32 iq_rsdl_phase_tx_d2; - u32 txvga_setting_for_cal; - - u8 TxVgaSettingInEEPROM[(((MAX_TXVGA_EEPROM * 2) + 3) & ~0x03)]; /* For EEPROM value */ - u8 TxVgaFor24[16]; /* Max is 14, 2 for alignment */ - struct txvga_for_50 TxVgaFor50[36]; /* 35 channels in 5G. 35x2 = 70 byte. 2 for alignments */ - - u16 Scan_Interval; - u16 RESERVED6; - - /* LED control */ - u32 LED_control; - /* - * LED_control 4 byte: Gray_Led_1[3] Gray_Led_0[2] Led[1] Led[0] - * Gray_Led - * For Led gray setting - * Led - * 0: normal control, - * LED behavior will decide by EEPROM setting - * 1: Turn off specific LED - * 2: Always on specific LED - * 3: slow blinking specific LED - * 4: fast blinking specific LED - * 5: WPS led control is set. Led0 is Red, Led1 id Green - * - * Led[1] is parameter for WPS LED mode - * 1:InProgress - * 2: Error - * 3: Session overlap - * 4: Success control - */ - u32 LED_LinkOn; /* Turn LED on control */ - u32 LED_Scanning; /* Let LED in scan process control */ - u32 LED_Blinking; /* Temp variable for shining */ - u32 RxByteCountLast; - u32 TxByteCountLast; - - atomic_t SurpriseRemoveCount; - - /* For global timer */ - u32 time_count; /* TICK_TIME_100ms 1 = 100ms */ - - /* For error recover */ - u32 HwStop; - - /* For avoid AP disconnect */ - u32 NullPacketCount; -}; - -#endif diff --git a/drivers/staging/winbond/wbusb.c b/drivers/staging/winbond/wbusb.c index a053bbb39610..df055abf5c42 100644 --- a/drivers/staging/winbond/wbusb.c +++ b/drivers/staging/winbond/wbusb.c @@ -16,7 +16,7 @@ #include "mds_f.h" #include "mlmetxrx_f.h" #include "mto.h" -#include "wbhal_s.h" +#include "wbhal.h" #include "wb35reg_f.h" #include "wb35tx_f.h" #include "wb35rx_f.h" -- cgit v1.2.3 From 9dd5f271441bbe85578c2b7841820d8bca26096c Mon Sep 17 00:00:00 2001 From: Mauro Schilman Date: Mon, 1 Nov 2010 14:12:05 -0300 Subject: Staging: frontier: fix space and * coding style issues in alphatrack.c This is a patch to the alphatrack.c file that fixes up a space warning and a space after '*' warning found by the checkpatch.pl tool Signed-off-by: Mauro Schilman Signed-off-by: Greg Kroah-Hartman --- drivers/staging/frontier/alphatrack.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/frontier/alphatrack.c b/drivers/staging/frontier/alphatrack.c index ef7fbf8b069a..2babb034a254 100644 --- a/drivers/staging/frontier/alphatrack.c +++ b/drivers/staging/frontier/alphatrack.c @@ -89,7 +89,7 @@ static int debug = ALPHATRACK_DEBUG; /* Use our own dbg macro */ #define dbg_info(dev, format, arg...) do \ - { if (debug) dev_info(dev , format , ## arg); } while (0) + { if (debug) dev_info(dev , format , ## arg); } while (0) #define alphatrack_ocmd_info(dev, cmd, format, arg...) @@ -769,7 +769,7 @@ static int usb_alphatrack_probe(struct usb_interface *intf, } dev->write_buffer = - kmalloc(sizeof(struct alphatrack_ocmd) * true_size, GFP_KERNEL); + kmalloc(true_size * sizeof(struct alphatrack_ocmd), GFP_KERNEL); if (!dev->write_buffer) { dev_err(&intf->dev, "Couldn't allocate write_buffer\n"); -- cgit v1.2.3 From 6112063d804aa0afc8d4462b22e36fc259393b64 Mon Sep 17 00:00:00 2001 From: Pekka Enberg Date: Mon, 1 Nov 2010 22:29:28 +0200 Subject: Staging: w35und: Kill empty Mds_Destroy function The Mds_Destroy() function doesn't do anything so kill it. Acked-by: Pavel Machek Signed-off-by: Pekka Enberg Signed-off-by: Greg Kroah-Hartman --- drivers/staging/winbond/mds.c | 5 ----- drivers/staging/winbond/mds_f.h | 1 - drivers/staging/winbond/wbusb.c | 2 -- 3 files changed, 8 deletions(-) diff --git a/drivers/staging/winbond/mds.c b/drivers/staging/winbond/mds.c index 9ac2c874ef05..90f2cc019d3b 100644 --- a/drivers/staging/winbond/mds.c +++ b/drivers/staging/winbond/mds.c @@ -18,11 +18,6 @@ Mds_initial(struct wbsoft_priv *adapter) return hal_get_tx_buffer(&adapter->sHwData, &pMds->pTxBuffer); } -void -Mds_Destroy(struct wbsoft_priv *adapter) -{ -} - static void Mds_DurationSet(struct wbsoft_priv *adapter, struct wb35_descriptor *pDes, u8 *buffer) { struct T00_descriptor *pT00; diff --git a/drivers/staging/winbond/mds_f.h b/drivers/staging/winbond/mds_f.h index d902843e8aed..ce8be079e957 100644 --- a/drivers/staging/winbond/mds_f.h +++ b/drivers/staging/winbond/mds_f.h @@ -5,7 +5,6 @@ #include "core.h" unsigned char Mds_initial(struct wbsoft_priv *adapter); -void Mds_Destroy(struct wbsoft_priv *adapter); void Mds_Tx(struct wbsoft_priv *adapter); void Mds_SendComplete(struct wbsoft_priv *adapter, struct T02_descriptor *pt02); void Mds_MpduProcess(struct wbsoft_priv *adapter, struct wb35_descriptor *prxdes); diff --git a/drivers/staging/winbond/wbusb.c b/drivers/staging/winbond/wbusb.c index df055abf5c42..82040f457a03 100644 --- a/drivers/staging/winbond/wbusb.c +++ b/drivers/staging/winbond/wbusb.c @@ -863,8 +863,6 @@ static void hal_halt(struct hw_data *pHwData) static void wb35_hw_halt(struct wbsoft_priv *adapter) { - Mds_Destroy(adapter); - /* Turn off Rx and Tx hardware ability */ hal_stop(&adapter->sHwData); #ifdef _PE_USB_INI_DUMP_ -- cgit v1.2.3 From 4d0d302257d3d0eccf371aab49c74b41797bebc3 Mon Sep 17 00:00:00 2001 From: Pekka Enberg Date: Mon, 1 Nov 2010 22:29:29 +0200 Subject: Staging: w35und: Kill struct hwdata ->NullPacketCount This patch kills the NullPacketCount member of struct hwdata. It's not used for anything so it's safe to remove it. Acked-by: Pavel Machek Signed-off-by: Pekka Enberg Signed-off-by: Greg Kroah-Hartman --- drivers/staging/winbond/wbhal.h | 6 ------ drivers/staging/winbond/wbusb.c | 9 --------- 2 files changed, 15 deletions(-) diff --git a/drivers/staging/winbond/wbhal.h b/drivers/staging/winbond/wbhal.h index 821a1b3f1301..6f4cd76e7be2 100644 --- a/drivers/staging/winbond/wbhal.h +++ b/drivers/staging/winbond/wbhal.h @@ -342,9 +342,6 @@ struct wb35_descriptor { /* Skip length = 8 DWORD */ void *buffer_address[MAX_DESCRIPTOR_BUFFER_INDEX]; }; - -#define DEFAULT_NULL_PACKET_COUNT 180000 /* 180 seconds */ - #define MAX_TXVGA_EEPROM 9 /* How many word(u16) of EEPROM will be used for TxVGA */ #define MAX_RF_PARAMETER 32 @@ -517,9 +514,6 @@ struct hw_data { /* For error recover */ u32 HwStop; - - /* For avoid AP disconnect */ - u32 NullPacketCount; }; #endif diff --git a/drivers/staging/winbond/wbusb.c b/drivers/staging/winbond/wbusb.c index 82040f457a03..dcb6d5b63d76 100644 --- a/drivers/staging/winbond/wbusb.c +++ b/drivers/staging/winbond/wbusb.c @@ -611,15 +611,6 @@ static void hal_led_control(unsigned long data) } break; } - - /* Active send null packet to avoid AP disconnect */ - if (pHwData->LED_LinkOn) { - pHwData->NullPacketCount += TimeInterval; - if (pHwData->NullPacketCount >= - DEFAULT_NULL_PACKET_COUNT) { - pHwData->NullPacketCount = 0; - } - } } pHwData->time_count += TimeInterval; -- cgit v1.2.3 From 87cb9a6310bc5183de196b25ef6adfda3080a744 Mon Sep 17 00:00:00 2001 From: Pekka Enberg Date: Mon, 1 Nov 2010 22:29:30 +0200 Subject: Staging: w35und: Kill struct hwdata ->HwStop This patch kills the ->HwStop member of struct hwdata. It's a read-only variable that's always zero so it's safe to remove it. Acked-by: Pavel Machek Signed-off-by: Pekka Enberg Signed-off-by: Greg Kroah-Hartman --- drivers/staging/winbond/wb35rx.c | 4 ++-- drivers/staging/winbond/wb35tx.c | 8 ++++---- drivers/staging/winbond/wbhal.h | 3 --- 3 files changed, 6 insertions(+), 9 deletions(-) diff --git a/drivers/staging/winbond/wb35rx.c b/drivers/staging/winbond/wb35rx.c index 448514aada44..5af271f2de9c 100644 --- a/drivers/staging/winbond/wb35rx.c +++ b/drivers/staging/winbond/wb35rx.c @@ -174,7 +174,7 @@ static void Wb35Rx_Complete(struct urb *urb) /* The IRP is completed */ pWb35Rx->EP3vm_state = VM_COMPLETED; - if (pHwData->SurpriseRemove || pHwData->HwStop) /* Must be here, or RxBufferId is invalid */ + if (pHwData->SurpriseRemove) /* Must be here, or RxBufferId is invalid */ goto error; if (pWb35Rx->rx_halt) @@ -239,7 +239,7 @@ static void Wb35Rx(struct ieee80211_hw *hw) u32 RxBufferId; /* Issuing URB */ - if (pHwData->SurpriseRemove || pHwData->HwStop) + if (pHwData->SurpriseRemove) goto error; if (pWb35Rx->rx_halt) diff --git a/drivers/staging/winbond/wb35tx.c b/drivers/staging/winbond/wb35tx.c index 2a9d05557678..fd52554e46f8 100644 --- a/drivers/staging/winbond/wb35tx.c +++ b/drivers/staging/winbond/wb35tx.c @@ -41,7 +41,7 @@ static void Wb35Tx_complete(struct urb * pUrb) pWb35Tx->TxSendIndex++; pWb35Tx->TxSendIndex %= MAX_USB_TX_BUFFER_NUMBER; - if (pHwData->SurpriseRemove || pHwData->HwStop) // Let WbWlanHalt to handle surprise remove + if (pHwData->SurpriseRemove) // Let WbWlanHalt to handle surprise remove goto error; if (pWb35Tx->tx_halt) @@ -74,7 +74,7 @@ static void Wb35Tx(struct wbsoft_priv *adapter) u32 SendIndex; - if (pHwData->SurpriseRemove || pHwData->HwStop) + if (pHwData->SurpriseRemove) goto cleanup; if (pWb35Tx->tx_halt) @@ -222,7 +222,7 @@ static void Wb35Tx_EP2VM_complete(struct urb * pUrb) pWb35Tx->EP2VM_status = pUrb->status; // For Linux 2.4. Interrupt will always trigger - if (pHwData->SurpriseRemove || pHwData->HwStop) // Let WbWlanHalt to handle surprise remove + if (pHwData->SurpriseRemove) // Let WbWlanHalt to handle surprise remove goto error; if (pWb35Tx->tx_halt) @@ -263,7 +263,7 @@ static void Wb35Tx_EP2VM(struct wbsoft_priv *adapter) u32 * pltmp = (u32 *)pWb35Tx->EP2_buf; int retv; - if (pHwData->SurpriseRemove || pHwData->HwStop) + if (pHwData->SurpriseRemove) goto error; if (pWb35Tx->tx_halt) diff --git a/drivers/staging/winbond/wbhal.h b/drivers/staging/winbond/wbhal.h index 6f4cd76e7be2..1c91588fc5b3 100644 --- a/drivers/staging/winbond/wbhal.h +++ b/drivers/staging/winbond/wbhal.h @@ -511,9 +511,6 @@ struct hw_data { /* For global timer */ u32 time_count; /* TICK_TIME_100ms 1 = 100ms */ - - /* For error recover */ - u32 HwStop; }; #endif -- cgit v1.2.3 From 4d26d7e6ba3fffd224560acd586526bf2f2f4f73 Mon Sep 17 00:00:00 2001 From: Pekka Enberg Date: Mon, 1 Nov 2010 22:29:31 +0200 Subject: Staging: w35und: Kill struct hwdata ->SurpriseRemoveCount This patch kills the ->SurpriseRemoveCount member of struct hwdata. It's not used at all so it's safe to remove it. Acked-by: Pavel Machek Signed-off-by: Pekka Enberg Signed-off-by: Greg Kroah-Hartman --- drivers/staging/winbond/wbhal.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/staging/winbond/wbhal.h b/drivers/staging/winbond/wbhal.h index 1c91588fc5b3..dcf3b213b4f1 100644 --- a/drivers/staging/winbond/wbhal.h +++ b/drivers/staging/winbond/wbhal.h @@ -507,8 +507,6 @@ struct hw_data { u32 RxByteCountLast; u32 TxByteCountLast; - atomic_t SurpriseRemoveCount; - /* For global timer */ u32 time_count; /* TICK_TIME_100ms 1 = 100ms */ }; -- cgit v1.2.3 From eb21c1587ac3272d58592e775dc55af6266f7403 Mon Sep 17 00:00:00 2001 From: Marek Belisko Date: Tue, 2 Nov 2010 13:44:08 +0100 Subject: staging: ft1000: Use memset instead looping with for. Signed-off-by: Marek Belisko Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ft1000/ft1000-usb/ft1000_hw.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c index 5b89ee2a2971..bc6aaf4e23b6 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c @@ -874,10 +874,7 @@ u16 init_ft1000_netdev(struct ft1000_device *ft1000dev) pInfo->fCondResetPend = 0; pInfo->usbboot = 0; pInfo->dspalive = 0; - for (i=0;i<32 ;i++ ) - { - pInfo->tempbuf[i] = 0; - } + memset(&pInfo->tempbuf[0], 0, sizeof(pInfo->tempbuf)); INIT_LIST_HEAD(&pInfo->prov_list); -- cgit v1.2.3 From 019bd3f825a7fc438b1e9ce7d145b03f13102aee Mon Sep 17 00:00:00 2001 From: Marek Belisko Date: Tue, 2 Nov 2010 13:44:09 +0100 Subject: staging: ft1000: Remove dead code. Remove functions which was used nowhere. Also remove dead variables used by this functions. Signed-off-by: Marek Belisko Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ft1000/ft1000-usb/ft1000_hw.c | 199 ------------------------- drivers/staging/ft1000/ft1000-usb/ft1000_usb.c | 1 - drivers/staging/ft1000/ft1000-usb/ft1000_usb.h | 3 - 3 files changed, 203 deletions(-) diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c index bc6aaf4e23b6..5a9edfb1bd1f 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c @@ -45,33 +45,6 @@ static unsigned long gCardIndex; #define MAX_RCV_LOOP 100 -/**************************************************************** - * ft1000_control_complete - ****************************************************************/ -static void ft1000_control_complete(struct urb *urb) -{ - struct ft1000_device *ft1000dev = (struct ft1000_device *)urb->context; - - //DEBUG("FT1000_CONTROL_COMPLETE ENTERED\n"); - if (ft1000dev == NULL ) - { - DEBUG("NULL ft1000dev, failure\n"); - return ; - } - else if ( ft1000dev->dev == NULL ) - { - DEBUG("NULL ft1000dev->dev, failure\n"); - return ; - } - - if(waitqueue_active(&ft1000dev->control_wait)) - { - wake_up(&ft1000dev->control_wait); - } - - //DEBUG("FT1000_CONTROL_COMPLETE RETURNED\n"); -} - //--------------------------------------------------------------------------- // Function: ft1000_control // @@ -1023,178 +996,6 @@ static void ft1000_usb_transmit_complete(struct urb *urb) //DEBUG("Return from ft1000_usb_transmit_complete\n"); } - -/**************************************************************** - * ft1000_control - ****************************************************************/ -static int ft1000_read_fifo_reg(struct ft1000_device *ft1000dev,unsigned int pipe, - u8 request, - u8 requesttype, - u16 value, - u16 index, - void *data, - u16 size, - int timeout) -{ - u16 ret; - - DECLARE_WAITQUEUE(wait, current); - struct urb *urb; - struct usb_ctrlrequest *dr; - int status; - - if (ft1000dev == NULL ) - { - DEBUG("NULL ft1000dev, failure\n"); - return STATUS_FAILURE; - } - else if ( ft1000dev->dev == NULL ) - { - DEBUG("NULL ft1000dev->dev, failure\n"); - return STATUS_FAILURE; - } - - spin_lock(&ft1000dev->device_lock); - - if(in_interrupt()) - { - spin_unlock(&ft1000dev->device_lock); - return -EBUSY; - } - - urb = usb_alloc_urb(0, GFP_KERNEL); - dr = kmalloc(sizeof(struct usb_ctrlrequest), in_interrupt() ? GFP_ATOMIC : GFP_KERNEL); - - if(!urb || !dr) - { - kfree(dr); - usb_free_urb(urb); - spin_unlock(&ft1000dev->device_lock); - return -ENOMEM; - } - - - - dr->bRequestType = requesttype; - dr->bRequest = request; - dr->wValue = value; - dr->wIndex = index; - dr->wLength = size; - - usb_fill_control_urb(urb, ft1000dev->dev, pipe, (char*)dr, (void*)data, size, (void *)ft1000_control_complete, (void*)ft1000dev); - - - init_waitqueue_head(&ft1000dev->control_wait); - - set_current_state(TASK_INTERRUPTIBLE); - - add_wait_queue(&ft1000dev->control_wait, &wait); - - - - - status = usb_submit_urb(urb, GFP_KERNEL); - - if(status) - { - usb_free_urb(urb); - kfree(dr); - remove_wait_queue(&ft1000dev->control_wait, &wait); - spin_unlock(&ft1000dev->device_lock); - return status; - } - - if(urb->status == -EINPROGRESS) - { - while(timeout && urb->status == -EINPROGRESS) - { - status = timeout = schedule_timeout(timeout); - } - } - else - { - status = 1; - } - - remove_wait_queue(&ft1000dev->control_wait, &wait); - - if(!status) - { - usb_unlink_urb(urb); - printk("ft1000 timeout\n"); - status = -ETIMEDOUT; - } - else - { - status = urb->status; - - if(urb->status) - { - printk("ft1000 control message failed (urb addr: %p) with error number: %i\n", urb, (int)status); - - usb_clear_halt(ft1000dev->dev, usb_rcvctrlpipe(ft1000dev->dev, 0)); - usb_clear_halt(ft1000dev->dev, usb_sndctrlpipe(ft1000dev->dev, 0)); - usb_unlink_urb(urb); - } - } - - - - usb_free_urb(urb); - kfree(dr); - spin_unlock(&ft1000dev->device_lock); - return ret; - - -} - -//--------------------------------------------------------------------------- -// Function: ft1000_read_fifo_len -// -// Parameters: ft1000dev - device structure -// -// -// Returns: none -// -// Description: read the fifo length register content -// -// Notes: -// -//--------------------------------------------------------------------------- -static inline u16 ft1000_read_fifo_len (struct net_device *dev) -{ - u16 temp; - u16 ret; - - struct ft1000_info *info = (struct ft1000_info *) netdev_priv(dev); - struct ft1000_device *ft1000dev = info->pFt1000Dev; -// DEBUG("ft1000_read_fifo_len: enter ft1000dev %x\n", ft1000dev); //aelias [-] reason: warning: format ???%x??? expects type ???unsigned int???, but argument 2 has type ???struct ft1000_device *??? - DEBUG("ft1000_read_fifo_len: enter ft1000dev %p\n", ft1000dev); //aelias [+] reason: up - - ret = STATUS_SUCCESS; - - ret = ft1000_read_fifo_reg(ft1000dev, - usb_rcvctrlpipe(ft1000dev->dev,0), - HARLEY_READ_REGISTER, - HARLEY_READ_OPERATION, - 0, - FT1000_REG_MAG_UFSR, - &temp, - 2, - LARGE_TIMEOUT); - - if (ret>0) - ret = STATUS_SUCCESS; - else - ret = STATUS_FAILURE; - - DEBUG("ft1000_read_fifo_len: returned %d\n", temp); - - return (temp- 16); - -} - - //--------------------------------------------------------------------------- // // Function: ft1000_copy_down_pkt diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_usb.c b/drivers/staging/ft1000/ft1000-usb/ft1000_usb.c index 28f55b2030e9..4e81bdd6902a 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_usb.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_usb.c @@ -84,7 +84,6 @@ static int ft1000_probe(struct usb_interface *interface, ft1000dev->dev = dev; ft1000dev->status = 0; ft1000dev->net = NULL; - spin_lock_init(&ft1000dev->device_lock); ft1000dev->tx_urb = usb_alloc_urb(0, GFP_ATOMIC); ft1000dev->rx_urb = usb_alloc_urb(0, GFP_ATOMIC); diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_usb.h b/drivers/staging/ft1000/ft1000-usb/ft1000_usb.h index a9d419a98a06..503481a60d3f 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_usb.h +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_usb.h @@ -466,12 +466,9 @@ struct ft1000_device { struct usb_device *dev; struct net_device *net; - spinlock_t device_lock; u32 status; - wait_queue_head_t control_wait; - struct urb *rx_urb; struct urb *tx_urb; -- cgit v1.2.3 From d2b07455b85d20c72e4182fe7d53d8c70838f984 Mon Sep 17 00:00:00 2001 From: Marek Belisko Date: Tue, 2 Nov 2010 13:44:10 +0100 Subject: staging: ft1000: Pseudo header handlig improved. Handling for pseudo header was done by directly copying data to tx buffer. This hide a functionality and make code unreadable. Use approach where fill pseudo_hdr structure first with data and then copy to beginning of buffer. Signed-off-by: Marek Belisko Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ft1000/ft1000-usb/ft1000_hw.c | 35 +++++++++++++-------------- 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c index 5a9edfb1bd1f..90394e10ad2e 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c @@ -1017,10 +1017,9 @@ static int ft1000_copy_down_pkt (struct net_device *netdev, u8 *packet, u16 len) struct ft1000_device *pFt1000Dev = pInfo->pFt1000Dev; - int i, count, ret; - USHORT *pTemp; - USHORT checksum; + int count, ret; u8 *t; + struct pseudo_hdr hdr; if (!pInfo->CardReady) { @@ -1044,21 +1043,21 @@ static int ft1000_copy_down_pkt (struct net_device *netdev, u8 *packet, u16 len) if ( count % 4) count = count + (4- (count %4) ); - pTemp = (PUSHORT)&(pFt1000Dev->tx_buf[0]); - *pTemp ++ = ntohs(count); - *pTemp ++ = 0x1020; - *pTemp ++ = 0x2010; - *pTemp ++ = 0x9100; - *pTemp ++ = 0; - *pTemp ++ = 0; - *pTemp ++ = 0; - pTemp = (PUSHORT)&(pFt1000Dev->tx_buf[0]); - checksum = *pTemp ++; - for (i=1; i<7; i++) - { - checksum ^= *pTemp ++; - } - *pTemp++ = checksum; + memset(&hdr, 0, sizeof(struct pseudo_hdr)); + + hdr.length = ntohs(count); + hdr.source = 0x10; + hdr.destination = 0x20; + hdr.portdest = 0x20; + hdr.portsrc = 0x10; + hdr.sh_str_id = 0x91; + hdr.control = 0x00; + + hdr.checksum = hdr.length ^ hdr.source ^ hdr.destination ^ + hdr.portdest ^ hdr.portsrc ^ hdr.sh_str_id ^ + hdr.control; + + memcpy(&pFt1000Dev->tx_buf[0], &hdr, sizeof(hdr)); memcpy(&(pFt1000Dev->tx_buf[sizeof(struct pseudo_hdr)]), packet, len); netif_stop_queue(netdev); -- cgit v1.2.3 From 35e9403b052ff6cad71bc5d9a075385e0c62ab96 Mon Sep 17 00:00:00 2001 From: Marek Belisko Date: Tue, 2 Nov 2010 14:51:44 +0100 Subject: staging: ft1000: Use specific error codes instead self defined. Signed-off-by: Marek Belisko Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ft1000/ft1000-usb/ft1000_hw.c | 27 ++++++++++----------------- 1 file changed, 10 insertions(+), 17 deletions(-) diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c index 90394e10ad2e..9bb537734e84 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c @@ -1025,7 +1025,7 @@ static int ft1000_copy_down_pkt (struct net_device *netdev, u8 *packet, u16 len) { DEBUG("ft1000_copy_down_pkt::Card Not Ready\n"); - return STATUS_FAILURE; + return -ENODEV; } @@ -1037,7 +1037,7 @@ static int ft1000_copy_down_pkt (struct net_device *netdev, u8 *packet, u16 len) { DEBUG("Error:ft1000_copy_down_pkt:Message Size Overflow!\n"); DEBUG("size = %d\n", count); - return STATUS_FAILURE; + return -EINVAL; } if ( count % 4) @@ -1080,25 +1080,18 @@ static int ft1000_copy_down_pkt (struct net_device *netdev, u8 *packet, u16 len) }*/ - ret = usb_submit_urb(pFt1000Dev->tx_urb, GFP_ATOMIC); - if(ret) - { + ret = usb_submit_urb(pFt1000Dev->tx_urb, GFP_ATOMIC); + if (ret) { DEBUG("ft1000 failed tx_urb %d\n", ret); - - return STATUS_FAILURE; - - } - else - { - //DEBUG("ft1000 sucess tx_urb %d\n", ret); - - pInfo->stats.tx_packets++; - pInfo->stats.tx_bytes += (len+14); - } + return ret; + } else { + pInfo->stats.tx_packets++; + pInfo->stats.tx_bytes += (len+14); + } //DEBUG("ft1000_copy_down_pkt() exit\n"); - return STATUS_SUCCESS; + return 0; } //--------------------------------------------------------------------------- -- cgit v1.2.3 From 3b3291e868695194096591c4a5e3e302939e4c2b Mon Sep 17 00:00:00 2001 From: Marek Belisko Date: Tue, 2 Nov 2010 14:51:45 +0100 Subject: staging: ft1000: Use common return point. Signed-off-by: Marek Belisko Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ft1000/ft1000-usb/ft1000_hw.c | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c index 9bb537734e84..0de4a2eeb3d0 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c @@ -1121,14 +1121,13 @@ static int ft1000_start_xmit(struct sk_buff *skb, struct net_device *dev) if ( skb == NULL ) { DEBUG ("ft1000_hw: ft1000_start_xmit:skb == NULL!!!\n" ); - return STATUS_FAILURE; + return NETDEV_TX_OK; } if ( pFt1000Dev->status & FT1000_STATUS_CLOSING) { DEBUG("network driver is closed, return\n"); - dev_kfree_skb(skb); - return STATUS_SUCCESS; + goto err; } //DEBUG("ft1000_start_xmit 1:length of packet = %d\n", skb->len); @@ -1147,28 +1146,24 @@ static int ft1000_start_xmit(struct sk_buff *skb, struct net_device *dev) { /* Drop packet is mediastate is down */ DEBUG("ft1000_hw:ft1000_start_xmit:mediastate is down\n"); - dev_kfree_skb(skb); - return STATUS_SUCCESS; + goto err; } if ( (skb->len < ENET_HEADER_SIZE) || (skb->len > ENET_MAX_SIZE) ) { /* Drop packet which has invalid size */ DEBUG("ft1000_hw:ft1000_start_xmit:invalid ethernet length\n"); - dev_kfree_skb(skb); - return STATUS_SUCCESS; + goto err; } //mbelian - if(ft1000_copy_down_pkt (dev, (pdata+ENET_HEADER_SIZE-2), skb->len - ENET_HEADER_SIZE + 2) == STATUS_FAILURE) - { - dev_kfree_skb(skb); - return STATUS_SUCCESS; - } + ft1000_copy_down_pkt(dev, (pdata+ENET_HEADER_SIZE-2), + skb->len - ENET_HEADER_SIZE + 2); - dev_kfree_skb(skb); +err: + dev_kfree_skb(skb); //DEBUG(" ft1000_start_xmit() exit\n"); - return 0; + return NETDEV_TX_OK; } //--------------------------------------------------------------------------- -- cgit v1.2.3 From d7780865164f2efe3ea2fa6f1ebdf61ecc1f2a4d Mon Sep 17 00:00:00 2001 From: Marek Belisko Date: Tue, 2 Nov 2010 14:51:46 +0100 Subject: staging: ft1000: Correct return error values. Signed-off-by: Marek Belisko Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ft1000/ft1000-usb/ft1000_hw.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c index 0de4a2eeb3d0..30a847565ef4 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c @@ -1306,7 +1306,7 @@ static int ft1000_submit_rx_urb(struct ft1000_info *info) { DEBUG("network driver is closed, return\n"); //usb_kill_urb(pFt1000Dev->rx_urb); //mbelian - return STATUS_SUCCESS; + return -ENODEV; } usb_fill_bulk_urb(pFt1000Dev->rx_urb, @@ -1321,12 +1321,12 @@ static int ft1000_submit_rx_urb(struct ft1000_info *info) if((result = usb_submit_urb(pFt1000Dev->rx_urb, GFP_ATOMIC))) { printk("ft1000_submit_rx_urb: submitting rx_urb %d failed\n", result); - return STATUS_FAILURE; + return result; } //DEBUG("ft1000_submit_rx_urb exit: result=%d\n", result); - return STATUS_SUCCESS; + return 0; } //--------------------------------------------------------------------------- -- cgit v1.2.3 From 95112cb448b5962daeee68db8ee523b71266e28b Mon Sep 17 00:00:00 2001 From: Marek Belisko Date: Tue, 2 Nov 2010 14:51:47 +0100 Subject: staging: ft1000: Check return value. Function ft1000_submit_rx_urb() could fail so add checking for return value. Signed-off-by: Marek Belisko Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ft1000/ft1000-usb/ft1000_hw.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c index 30a847565ef4..1fa1f811b017 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c @@ -1347,6 +1347,7 @@ static int ft1000_open (struct net_device *dev) { struct ft1000_info *pInfo = (struct ft1000_info *)netdev_priv(dev); struct timeval tv; //mbelian + int ret; DEBUG("ft1000_open is called for card %d\n", pInfo->CardNumber); //DEBUG("ft1000_open: dev->addr=%x, dev->addr_len=%d\n", dev->addr, dev->addr_len); @@ -1364,8 +1365,9 @@ static int ft1000_open (struct net_device *dev) netif_carrier_on(dev); //mbelian - ft1000_submit_rx_urb(pInfo); - return 0; + ret = ft1000_submit_rx_urb(pInfo); + + return ret; } //--------------------------------------------------------------------------- -- cgit v1.2.3 From e2cb7da1671eb659c8edc81be9838afdd0b6b2cc Mon Sep 17 00:00:00 2001 From: Marek Belisko Date: Wed, 3 Nov 2010 11:19:47 +0100 Subject: staging: ft1000: Get rid of PUCHAR typedef. PUCHAR typedef was replaces by u8 *. Signed-off-by: Marek Belisko Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ft1000/ft1000-usb/ft1000_chdev.c | 4 +- .../staging/ft1000/ft1000-usb/ft1000_download.c | 44 +++++++++++----------- drivers/staging/ft1000/ft1000-usb/ft1000_hw.c | 40 ++++++++++---------- drivers/staging/ft1000/ft1000-usb/ft1000_proc.c | 6 +-- drivers/staging/ft1000/ft1000-usb/ft1000_usb.h | 11 +++--- 5 files changed, 52 insertions(+), 53 deletions(-) diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_chdev.c b/drivers/staging/ft1000/ft1000-usb/ft1000_chdev.c index 87a6487531c2..cadfb62229ef 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_chdev.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_chdev.c @@ -623,10 +623,10 @@ static long ft1000_ChIoctl (struct file *File, unsigned int Command, memcpy(get_stat_data.eui64, info->eui64, EUISZ); if (info->ProgConStat != 0xFF) { - ft1000_read_dpram16(ft1000dev, FT1000_MAG_DSP_LED, (PUCHAR)&ledStat, FT1000_MAG_DSP_LED_INDX); + ft1000_read_dpram16(ft1000dev, FT1000_MAG_DSP_LED, (u8 *)&ledStat, FT1000_MAG_DSP_LED_INDX); get_stat_data.LedStat = ntohs(ledStat); DEBUG("FT1000:ft1000_ChIoctl: LedStat = 0x%x\n", get_stat_data.LedStat); - ft1000_read_dpram16(ft1000dev, FT1000_MAG_DSP_CON_STATE, (PUCHAR)&conStat, FT1000_MAG_DSP_CON_STATE_INDX); + ft1000_read_dpram16(ft1000dev, FT1000_MAG_DSP_CON_STATE, (u8 *)&conStat, FT1000_MAG_DSP_CON_STATE_INDX); get_stat_data.ConStat = ntohs(conStat); DEBUG("FT1000:ft1000_ChIoctl: ConStat = 0x%x\n", get_stat_data.ConStat); } diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_download.c b/drivers/staging/ft1000/ft1000-usb/ft1000_download.c index 4dd456fbab9b..d7ca6ccad450 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_download.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_download.c @@ -228,7 +228,7 @@ static USHORT get_handshake(struct ft1000_device *ft1000dev, USHORT expected_val status = ft1000_write_register (ft1000dev, FT1000_DB_DNLD_RX, FT1000_REG_DOORBELL); } - status = ft1000_read_dpram16 (ft1000dev, DWNLD_MAG1_HANDSHAKE_LOC, (PUCHAR)&handshake, 1); + status = ft1000_read_dpram16 (ft1000dev, DWNLD_MAG1_HANDSHAKE_LOC, (u8 *)&handshake, 1); //DEBUG("get_handshake: handshake is %x\n", tempx); handshake = ntohs(handshake); //DEBUG("get_handshake: after swap, handshake is %x\n", handshake); @@ -300,10 +300,10 @@ static USHORT get_handshake_usb(struct ft1000_device *ft1000dev, USHORT expected while (loopcnt < 100) { if (pft1000info->usbboot == 2) { - status = ft1000_read_dpram32 (ft1000dev, 0, (PUCHAR)&(pft1000info->tempbuf[0]), 64); + status = ft1000_read_dpram32 (ft1000dev, 0, (u8 *)&(pft1000info->tempbuf[0]), 64); for (temp=0; temp<16; temp++) DEBUG("tempbuf %d = 0x%x\n", temp, pft1000info->tempbuf[temp]); - status = ft1000_read_dpram16 (ft1000dev, DWNLD_MAG1_HANDSHAKE_LOC, (PUCHAR)&handshake, 1); + status = ft1000_read_dpram16 (ft1000dev, DWNLD_MAG1_HANDSHAKE_LOC, (u8 *)&handshake, 1); DEBUG("handshake from read_dpram16 = 0x%x\n", handshake); if (pft1000info->dspalive == pft1000info->tempbuf[6]) handshake = 0; @@ -313,7 +313,7 @@ static USHORT get_handshake_usb(struct ft1000_device *ft1000dev, USHORT expected } } else { - status = ft1000_read_dpram16 (ft1000dev, DWNLD_MAG1_HANDSHAKE_LOC, (PUCHAR)&handshake, 1); + status = ft1000_read_dpram16 (ft1000dev, DWNLD_MAG1_HANDSHAKE_LOC, (u8 *)&handshake, 1); } loopcnt++; msleep(10); @@ -356,14 +356,14 @@ static USHORT get_request_type(struct ft1000_device *ft1000dev) if ( pft1000info->bootmode == 1) { - status = fix_ft1000_read_dpram32 (ft1000dev, DWNLD_MAG1_TYPE_LOC, (PUCHAR)&tempx); + status = fix_ft1000_read_dpram32 (ft1000dev, DWNLD_MAG1_TYPE_LOC, (u8 *)&tempx); tempx = ntohl(tempx); } else { tempx = 0; - status = ft1000_read_dpram16 (ft1000dev, DWNLD_MAG1_TYPE_LOC, (PUCHAR)&tempword, 1); + status = ft1000_read_dpram16 (ft1000dev, DWNLD_MAG1_TYPE_LOC, (u8 *)&tempword, 1); tempx |= (tempword << 16); tempx = ntohl(tempx); } @@ -383,7 +383,7 @@ static USHORT get_request_type_usb(struct ft1000_device *ft1000dev) struct ft1000_info *pft1000info = netdev_priv(ft1000dev->net); if ( pft1000info->bootmode == 1) { - status = fix_ft1000_read_dpram32 (ft1000dev, DWNLD_MAG1_TYPE_LOC, (PUCHAR)&tempx); + status = fix_ft1000_read_dpram32 (ft1000dev, DWNLD_MAG1_TYPE_LOC, (u8 *)&tempx); tempx = ntohl(tempx); } else @@ -394,7 +394,7 @@ static USHORT get_request_type_usb(struct ft1000_device *ft1000dev) } else { tempx = 0; - status = ft1000_read_dpram16 (ft1000dev, DWNLD_MAG1_TYPE_LOC, (PUCHAR)&tempword, 1); + status = ft1000_read_dpram16 (ft1000dev, DWNLD_MAG1_TYPE_LOC, (u8 *)&tempword, 1); } tempx |= (tempword << 16); tempx = ntohl(tempx); @@ -428,14 +428,14 @@ static long get_request_value(struct ft1000_device *ft1000dev) if ( pft1000info->bootmode == 1) { - status = fix_ft1000_read_dpram32(ft1000dev, DWNLD_MAG1_SIZE_LOC, (PUCHAR)&value); + status = fix_ft1000_read_dpram32(ft1000dev, DWNLD_MAG1_SIZE_LOC, (u8 *)&value); value = ntohl(value); } else { - status = ft1000_read_dpram16(ft1000dev, DWNLD_MAG1_SIZE_LOC, (PUCHAR)&tempword, 0); + status = ft1000_read_dpram16(ft1000dev, DWNLD_MAG1_SIZE_LOC, (u8 *)&tempword, 0); value = tempword; - status = ft1000_read_dpram16(ft1000dev, DWNLD_MAG1_SIZE_LOC, (PUCHAR)&tempword, 1); + status = ft1000_read_dpram16(ft1000dev, DWNLD_MAG1_SIZE_LOC, (u8 *)&tempword, 1); value |= (tempword << 16); value = ntohl(value); } @@ -460,7 +460,7 @@ static long get_request_value_usb(struct ft1000_device *ft1000dev) } else { value = 0; - status = ft1000_read_dpram16(ft1000dev, DWNLD_MAG1_SIZE_LOC, (PUCHAR)&tempword, 1); + status = ft1000_read_dpram16(ft1000dev, DWNLD_MAG1_SIZE_LOC, (u8 *)&tempword, 1); } value |= (tempword << 16); @@ -494,7 +494,7 @@ static void put_request_value(struct ft1000_device *ft1000dev, long lvalue) ULONG status; tempx = ntohl(lvalue); - status = fix_ft1000_write_dpram32(ft1000dev, DWNLD_MAG1_SIZE_LOC, (PUCHAR)&tempx); + status = fix_ft1000_write_dpram32(ft1000dev, DWNLD_MAG1_SIZE_LOC, (u8 *)&tempx); @@ -602,24 +602,24 @@ static ULONG write_blk (struct ft1000_device *ft1000dev, USHORT **pUsFile, UCHAR if (pft1000info->bootmode == 0) { if (dpram >= 0x3F4) - Status = ft1000_write_dpram32 (ft1000dev, dpram, (PUCHAR)&tempbuffer[0], 8); + Status = ft1000_write_dpram32 (ft1000dev, dpram, (u8 *)&tempbuffer[0], 8); else - Status = ft1000_write_dpram32 (ft1000dev, dpram, (PUCHAR)&tempbuffer[0], 64); + Status = ft1000_write_dpram32 (ft1000dev, dpram, (u8 *)&tempbuffer[0], 64); } else { for (j=0; j<10; j++) { - Status = ft1000_write_dpram32 (ft1000dev, dpram, (PUCHAR)&tempbuffer[0], 64); + Status = ft1000_write_dpram32 (ft1000dev, dpram, (u8 *)&tempbuffer[0], 64); if (Status == STATUS_SUCCESS) { // Work around for ASIC bit stuffing problem. if ( (tempbuffer[31] & 0xfe00) == 0xfe00) { - Status = ft1000_write_dpram32(ft1000dev, dpram+12, (PUCHAR)&tempbuffer[24], 64); + Status = ft1000_write_dpram32(ft1000dev, dpram+12, (u8 *)&tempbuffer[24], 64); } // Let's check the data written - Status = ft1000_read_dpram32 (ft1000dev, dpram, (PUCHAR)&resultbuffer[0], 64); + Status = ft1000_read_dpram32 (ft1000dev, dpram, (u8 *)&resultbuffer[0], 64); if ( (tempbuffer[31] & 0xfe00) == 0xfe00) { for (i=0; i<28; i++) @@ -633,7 +633,7 @@ static ULONG write_blk (struct ft1000_device *ft1000dev, USHORT **pUsFile, UCHAR break; } } - Status = ft1000_read_dpram32 (ft1000dev, dpram+12, (PUCHAR)&resultbuffer[0], 64); + Status = ft1000_read_dpram32 (ft1000dev, dpram+12, (u8 *)&resultbuffer[0], 64); for (i=0; i<16; i++) { if (resultbuffer[i] != tempbuffer[i+24]) @@ -799,7 +799,7 @@ u16 scram_dnldr(struct ft1000_device *ft1000dev, void *pFileStart, ULONG FileLe ULONG image_chksum = 0; USHORT dpram = 0; - PUCHAR pbuffer; + u8 *pbuffer; struct prov_record *pprov_record; struct ft1000_info *pft1000info = netdev_priv(ft1000dev->net); @@ -1066,7 +1066,7 @@ u16 scram_dnldr(struct ft1000_device *ft1000dev, void *pFileStart, ULONG FileLe templong = *pUsData++; templong |= (*pUsData++ << 16); - Status = fix_ft1000_write_dpram32 (ft1000dev, dpram++, (PUCHAR)&templong); + Status = fix_ft1000_write_dpram32 (ft1000dev, dpram++, (u8 *)&templong); } break; @@ -1095,7 +1095,7 @@ u16 scram_dnldr(struct ft1000_device *ft1000dev, void *pFileStart, ULONG FileLe templong = ntohs(*pUsFile++); temp = ntohs(*pUsFile++); templong |= (temp << 16); - Status = fix_ft1000_write_dpram32 (ft1000dev, dpram++, (PUCHAR)&templong); + Status = fix_ft1000_write_dpram32 (ft1000dev, dpram++, (u8 *)&templong); } break; diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c index 1fa1f811b017..8333e66bef2a 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c @@ -196,7 +196,7 @@ u16 ft1000_write_register(struct ft1000_device *ft1000dev, USHORT value, u16 nRe // //--------------------------------------------------------------------------- -u16 ft1000_read_dpram32(struct ft1000_device *ft1000dev, USHORT indx, PUCHAR buffer, USHORT cnt) +u16 ft1000_read_dpram32(struct ft1000_device *ft1000dev, USHORT indx, u8 *buffer, USHORT cnt) { u16 ret = STATUS_SUCCESS; @@ -235,7 +235,7 @@ u16 ft1000_read_dpram32(struct ft1000_device *ft1000dev, USHORT indx, PUCHAR buf // Notes: // //--------------------------------------------------------------------------- -u16 ft1000_write_dpram32(struct ft1000_device *ft1000dev, USHORT indx, PUCHAR buffer, USHORT cnt) +u16 ft1000_write_dpram32(struct ft1000_device *ft1000dev, USHORT indx, u8 *buffer, USHORT cnt) { u16 ret = STATUS_SUCCESS; @@ -272,7 +272,7 @@ u16 ft1000_write_dpram32(struct ft1000_device *ft1000dev, USHORT indx, PUCHAR bu // Notes: // //--------------------------------------------------------------------------- -u16 ft1000_read_dpram16(struct ft1000_device *ft1000dev, USHORT indx, PUCHAR buffer, u8 highlow) +u16 ft1000_read_dpram16(struct ft1000_device *ft1000dev, USHORT indx, u8 *buffer, u8 highlow) { u16 ret = STATUS_SUCCESS; @@ -365,7 +365,7 @@ u16 ft1000_write_dpram16(struct ft1000_device *ft1000dev, USHORT indx, USHORT va // Notes: // //--------------------------------------------------------------------------- -u16 fix_ft1000_read_dpram32(struct ft1000_device *ft1000dev, USHORT indx, PUCHAR buffer) +u16 fix_ft1000_read_dpram32(struct ft1000_device *ft1000dev, USHORT indx, u8 *buffer) { UCHAR buf[16]; USHORT pos; @@ -414,14 +414,14 @@ u16 fix_ft1000_read_dpram32(struct ft1000_device *ft1000dev, USHORT indx, PUCHAR // Notes: // //--------------------------------------------------------------------------- -u16 fix_ft1000_write_dpram32(struct ft1000_device *ft1000dev, USHORT indx, PUCHAR buffer) +u16 fix_ft1000_write_dpram32(struct ft1000_device *ft1000dev, USHORT indx, u8 *buffer) { USHORT pos1; USHORT pos2; USHORT i; UCHAR buf[32]; UCHAR resultbuffer[32]; - PUCHAR pdata; + u8 *pdata; u16 ret = STATUS_SUCCESS; //DEBUG("fix_ft1000_write_dpram32: Entered:\n"); @@ -445,7 +445,7 @@ u16 fix_ft1000_write_dpram32(struct ft1000_device *ft1000dev, USHORT indx, PUCHA return ret; } - ret = ft1000_read_dpram32(ft1000dev, pos1, (PUCHAR)&resultbuffer[0], 16); + ret = ft1000_read_dpram32(ft1000dev, pos1, (u8 *)&resultbuffer[0], 16); if (ret == STATUS_SUCCESS) { buffer = pdata; @@ -460,8 +460,8 @@ u16 fix_ft1000_write_dpram32(struct ft1000_device *ft1000dev, USHORT indx, PUCHA if (ret == STATUS_FAILURE) { - ret = ft1000_write_dpram32(ft1000dev, pos1, (PUCHAR)&tempbuffer[0], 16); - ret = ft1000_read_dpram32(ft1000dev, pos1, (PUCHAR)&resultbuffer[0], 16); + ret = ft1000_write_dpram32(ft1000dev, pos1, (u8 *)&tempbuffer[0], 16); + ret = ft1000_read_dpram32(ft1000dev, pos1, (u8 *)&resultbuffer[0], 16); if (ret == STATUS_SUCCESS) { buffer = pdata; @@ -621,7 +621,7 @@ int dsp_reload(struct ft1000_device *ft1000dev) status = ft1000_write_register (ft1000dev, HOST_INTF_BE, FT1000_REG_SUP_CTRL); // Let's check for FEFE - status = ft1000_read_dpram32 (ft1000dev, FT1000_MAG_DPRAM_FEFE_INDX, (PUCHAR)&templong, 4); + status = ft1000_read_dpram32 (ft1000dev, FT1000_MAG_DPRAM_FEFE_INDX, (u8 *)&templong, 4); DEBUG("templong (fefe) = 0x%8x\n", templong); // call codeloader @@ -1485,7 +1485,7 @@ static BOOLEAN ft1000_receive_cmd (struct ft1000_device *dev, u16 *pbuffer, int int i; u16 tempword; - ret = ft1000_read_dpram16(dev, FT1000_MAG_PH_LEN, (PUCHAR)&size, FT1000_MAG_PH_LEN_INDX); + ret = ft1000_read_dpram16(dev, FT1000_MAG_PH_LEN, (u8 *)&size, FT1000_MAG_PH_LEN_INDX); size = ntohs(size) + PSEUDOSZ; if (size > maxsz) { DEBUG("FT1000:ft1000_receive_cmd:Invalid command length = %d\n", size); @@ -1596,7 +1596,7 @@ static int ft1000_dsp_prov(void *arg) TempShortBuf[1] = htons (len); memcpy(&TempShortBuf[2], ppseudo_hdr, len); - status = ft1000_write_dpram32 (dev, 0, (PUCHAR)&TempShortBuf[0], (unsigned short)(len+2)); + status = ft1000_write_dpram32 (dev, 0, (u8 *)&TempShortBuf[0], (unsigned short)(len+2)); status = ft1000_write_register (dev, FT1000_DB_DPRAM_TX, FT1000_REG_DOORBELL); list_del(&ptr->list); @@ -1815,7 +1815,7 @@ static int ft1000_proc_drvmsg (struct ft1000_device *dev, u16 size) { } info->DSPInfoBlk[10] = 0x7200; info->DSPInfoBlk[11] = htons(info->DSPInfoBlklen); - status = ft1000_write_dpram32 (dev, 0, (PUCHAR)&info->DSPInfoBlk[0], (unsigned short)(info->DSPInfoBlklen+22)); + status = ft1000_write_dpram32 (dev, 0, (u8 *)&info->DSPInfoBlk[0], (unsigned short)(info->DSPInfoBlklen+22)); status = ft1000_write_register (dev, FT1000_DB_DPRAM_TX, FT1000_REG_DOORBELL); info->DrvMsgPend = 0; @@ -1930,14 +1930,14 @@ int ft1000_poll(void* dev_id) { if (tempword & FT1000_DB_DPRAM_RX) { //DEBUG("ft1000_poll: FT1000_REG_DOORBELL message type: FT1000_DB_DPRAM_RX\n"); - status = ft1000_read_dpram16(dev, 0x200, (PUCHAR)&data, 0); + status = ft1000_read_dpram16(dev, 0x200, (u8 *)&data, 0); //DEBUG("ft1000_poll:FT1000_DB_DPRAM_RX:ft1000_read_dpram16:size = 0x%x\n", data); size = ntohs(data) + 16 + 2; //wai if (size % 4) { modulo = 4 - (size % 4); size = size + modulo; } - status = ft1000_read_dpram16(dev, 0x201, (PUCHAR)&portid, 1); + status = ft1000_read_dpram16(dev, 0x201, (u8 *)&portid, 1); portid &= 0xff; //DEBUG("ft1000_poll: FT1000_REG_DOORBELL message type: FT1000_DB_DPRAM_RX : portid 0x%x\n", portid); @@ -2072,7 +2072,7 @@ int ft1000_poll(void* dev_id) { status = ft1000_write_register (dev, FT1000_ASIC_RESET_REQ, FT1000_REG_DOORBELL); status = ft1000_write_register (dev, HOST_INTF_BE, FT1000_REG_SUP_CTRL); // copy dsp session record from Adapter block - status = ft1000_write_dpram32 (dev, 0, (PUCHAR)&info->DSPSess.Rec[0], 1024); + status = ft1000_write_dpram32 (dev, 0, (u8 *)&info->DSPSess.Rec[0], 1024); // Program WMARK register status = ft1000_write_register (dev, 0x600, FT1000_REG_MAG_WATERMARK); // ring doorbell to tell DSP that ASIC is out of reset @@ -2086,10 +2086,10 @@ int ft1000_poll(void* dev_id) { if (info->fAppMsgPend == 0) { // Reset ASIC and DSP - status = ft1000_read_dpram16(dev, FT1000_MAG_DSP_TIMER0, (PUCHAR)&(info->DSP_TIME[0]), FT1000_MAG_DSP_TIMER0_INDX); - status = ft1000_read_dpram16(dev, FT1000_MAG_DSP_TIMER1, (PUCHAR)&(info->DSP_TIME[1]), FT1000_MAG_DSP_TIMER1_INDX); - status = ft1000_read_dpram16(dev, FT1000_MAG_DSP_TIMER2, (PUCHAR)&(info->DSP_TIME[2]), FT1000_MAG_DSP_TIMER2_INDX); - status = ft1000_read_dpram16(dev, FT1000_MAG_DSP_TIMER3, (PUCHAR)&(info->DSP_TIME[3]), FT1000_MAG_DSP_TIMER3_INDX); + status = ft1000_read_dpram16(dev, FT1000_MAG_DSP_TIMER0, (u8 *)&(info->DSP_TIME[0]), FT1000_MAG_DSP_TIMER0_INDX); + status = ft1000_read_dpram16(dev, FT1000_MAG_DSP_TIMER1, (u8 *)&(info->DSP_TIME[1]), FT1000_MAG_DSP_TIMER1_INDX); + status = ft1000_read_dpram16(dev, FT1000_MAG_DSP_TIMER2, (u8 *)&(info->DSP_TIME[2]), FT1000_MAG_DSP_TIMER2_INDX); + status = ft1000_read_dpram16(dev, FT1000_MAG_DSP_TIMER3, (u8 *)&(info->DSP_TIME[3]), FT1000_MAG_DSP_TIMER3_INDX); info->CardReady = 0; info->DrvErrNum = DSP_CONDRESET_INFO; DEBUG("ft1000_hw:DSP conditional reset requested\n"); diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_proc.c b/drivers/staging/ft1000/ft1000-usb/ft1000_proc.c index 36cdd588fa98..dda0e33b4864 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_proc.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_proc.c @@ -39,7 +39,7 @@ u16 ft1000_read_dpram16 (struct ft1000_device *ft1000dev, USHORT indx, - PUCHAR buffer, u8 highlow); + u8 *buffer, u8 highlow); static int @@ -77,11 +77,11 @@ ft1000ReadProc (char *page, char **start, off_t off, int count, int *eof, if (info->ProgConStat != 0xFF) { ft1000_read_dpram16 (info->pFt1000Dev, FT1000_MAG_DSP_LED, - (PUCHAR) & ledStat, FT1000_MAG_DSP_LED_INDX); + (u8 *)&ledStat, FT1000_MAG_DSP_LED_INDX); info->LedStat = ntohs (ledStat); ft1000_read_dpram16 (info->pFt1000Dev, FT1000_MAG_DSP_CON_STATE, - (PUCHAR) & conStat, FT1000_MAG_DSP_CON_STATE_INDX); + (u8 *)&conStat, FT1000_MAG_DSP_CON_STATE_INDX); info->ConStat = ntohs (conStat); do_gettimeofday (&tv); delta = (tv.tv_sec - info->ConTm); diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_usb.h b/drivers/staging/ft1000/ft1000-usb/ft1000_usb.h index 503481a60d3f..4996da9e2355 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_usb.h +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_usb.h @@ -104,7 +104,6 @@ struct prov_record { #define BOOLEAN u8 #define PULONG u32 * #define PUSHORT u16 * -#define PUCHAR u8 * #define PCHAR u8 * #define UINT u32 @@ -565,12 +564,12 @@ struct dpram_blk { u16 ft1000_read_register(struct ft1000_device *ft1000dev, u16* Data, u16 nRegIndx); u16 ft1000_write_register(struct ft1000_device *ft1000dev, USHORT value, u16 nRegIndx); -u16 ft1000_read_dpram32(struct ft1000_device *ft1000dev, USHORT indx, PUCHAR buffer, USHORT cnt); -u16 ft1000_write_dpram32(struct ft1000_device *ft1000dev, USHORT indx, PUCHAR buffer, USHORT cnt); -u16 ft1000_read_dpram16(struct ft1000_device *ft1000dev, USHORT indx, PUCHAR buffer, u8 highlow); +u16 ft1000_read_dpram32(struct ft1000_device *ft1000dev, USHORT indx, u8 *buffer, USHORT cnt); +u16 ft1000_write_dpram32(struct ft1000_device *ft1000dev, USHORT indx, u8 *buffer, USHORT cnt); +u16 ft1000_read_dpram16(struct ft1000_device *ft1000dev, USHORT indx, u8 *buffer, u8 highlow); u16 ft1000_write_dpram16(struct ft1000_device *ft1000dev, USHORT indx, USHORT value, u8 highlow); -u16 fix_ft1000_read_dpram32(struct ft1000_device *ft1000dev, USHORT indx, PUCHAR buffer); -u16 fix_ft1000_write_dpram32(struct ft1000_device *ft1000dev, USHORT indx, PUCHAR buffer); +u16 fix_ft1000_read_dpram32(struct ft1000_device *ft1000dev, USHORT indx, u8 *buffer); +u16 fix_ft1000_write_dpram32(struct ft1000_device *ft1000dev, USHORT indx, u8 *buffer); extern void *pFileStart; extern size_t FileLength; -- cgit v1.2.3 From c8f775c88b1b84909d5d73b171a48302bf46b2f8 Mon Sep 17 00:00:00 2001 From: Marek Belisko Date: Wed, 3 Nov 2010 11:19:48 +0100 Subject: staging: ft1000: Get rid of UCHAR typedef. Signed-off-by: Marek Belisko Signed-off-by: Greg Kroah-Hartman --- .../staging/ft1000/ft1000-usb/ft1000_download.c | 26 +++++++++++----------- drivers/staging/ft1000/ft1000-usb/ft1000_hw.c | 6 ++--- drivers/staging/ft1000/ft1000-usb/ft1000_usb.h | 11 +++++---- 3 files changed, 21 insertions(+), 22 deletions(-) diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_download.c b/drivers/staging/ft1000/ft1000-usb/ft1000_download.c index d7ca6ccad450..d7377eba7ede 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_download.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_download.c @@ -534,7 +534,7 @@ static USHORT hdr_checksum(struct pseudo_hdr *pHdr) // // Parameters: struct ft1000_device - device structure // USHORT **pUsFile - DSP image file pointer in USHORT -// UCHAR **pUcFile - DSP image file pointer in UCHAR +// u8 **pUcFile - DSP image file pointer in u8 // long word_length - lenght of the buffer to be written // to DPRAM // @@ -546,7 +546,7 @@ static USHORT hdr_checksum(struct pseudo_hdr *pHdr) // Notes: // //--------------------------------------------------------------------------- -static ULONG write_blk (struct ft1000_device *ft1000dev, USHORT **pUsFile, UCHAR **pUcFile, long word_length) +static ULONG write_blk (struct ft1000_device *ft1000dev, USHORT **pUsFile, u8 **pUcFile, long word_length) { ULONG Status = STATUS_SUCCESS; USHORT dpram; @@ -690,7 +690,7 @@ static void usb_dnld_complete (struct urb *urb) // // Parameters: struct ft1000_device - device structure // USHORT **pUsFile - DSP image file pointer in USHORT -// UCHAR **pUcFile - DSP image file pointer in UCHAR +// u8 **pUcFile - DSP image file pointer in u8 // long word_length - lenght of the buffer to be written // to DPRAM // @@ -702,7 +702,7 @@ static void usb_dnld_complete (struct urb *urb) // Notes: // //--------------------------------------------------------------------------- -static ULONG write_blk_fifo (struct ft1000_device *ft1000dev, USHORT **pUsFile, UCHAR **pUcFile, long word_length) +static ULONG write_blk_fifo (struct ft1000_device *ft1000dev, USHORT **pUsFile, u8 **pUcFile, long word_length) { ULONG Status = STATUS_SUCCESS; int byte_length; @@ -789,8 +789,8 @@ u16 scram_dnldr(struct ft1000_device *ft1000dev, void *pFileStart, ULONG FileLe struct drv_msg *pMailBoxData; USHORT *pUsData = NULL; USHORT *pUsFile = NULL; - UCHAR *pUcFile = NULL; - UCHAR *pBootEnd = NULL, *pCodeEnd= NULL; + u8 *pUcFile = NULL; + u8 *pBootEnd = NULL, *pCodeEnd= NULL; int imageN; long loader_code_address, loader_code_size = 0; long run_address = 0, run_size = 0; @@ -821,9 +821,9 @@ u16 scram_dnldr(struct ft1000_device *ft1000dev, void *pFileStart, ULONG FileLe ft1000_write_register (ft1000dev, 0x800, FT1000_REG_MAG_WATERMARK); pUsFile = (USHORT *)(pFileStart + pFileHdr5->loader_offset); - pUcFile = (UCHAR *)(pFileStart + pFileHdr5->loader_offset); + pUcFile = (u8 *)(pFileStart + pFileHdr5->loader_offset); - pBootEnd = (UCHAR *)(pFileStart + pFileHdr5->loader_code_end); + pBootEnd = (u8 *)(pFileStart + pFileHdr5->loader_code_end); loader_code_address = pFileHdr5->loader_code_address; loader_code_size = pFileHdr5->loader_code_size; @@ -879,7 +879,7 @@ u16 scram_dnldr(struct ft1000_device *ft1000dev, void *pFileStart, ULONG FileLe DEBUG("FT1000:REQUEST_DONE_BL\n"); /* Reposition ptrs to beginning of code section */ pUsFile = (USHORT *)(pBootEnd); - pUcFile = (UCHAR *)(pBootEnd); + pUcFile = (u8 *)(pBootEnd); //DEBUG("FT1000:download:pUsFile = 0x%8x\n", (int)pUsFile); //DEBUG("FT1000:download:pUcFile = 0x%8x\n", (int)pUcFile); uiState = STATE_CODE_DWNLD; @@ -989,7 +989,7 @@ u16 scram_dnldr(struct ft1000_device *ft1000dev, void *pFileStart, ULONG FileLe pft1000info->usbboot = 3; /* Reposition ptrs to beginning of provisioning section */ pUsFile = (USHORT *)(pFileStart + pFileHdr5->commands_offset); - pUcFile = (UCHAR *)(pFileStart + pFileHdr5->commands_offset); + pUcFile = (u8 *)(pFileStart + pFileHdr5->commands_offset); uiState = STATE_DONE_DWNLD; break; case REQUEST_CODE_SEGMENT: @@ -1119,8 +1119,8 @@ u16 scram_dnldr(struct ft1000_device *ft1000dev, void *pFileStart, ULONG FileLe bGoodVersion = TRUE; DEBUG("FT1000:download: bGoodVersion is TRUE\n"); pUsFile = (USHORT *)(pFileStart + pDspImageInfoV6->begin_offset); - pUcFile = (UCHAR *)(pFileStart + pDspImageInfoV6->begin_offset); - pCodeEnd = (UCHAR *)(pFileStart + pDspImageInfoV6->end_offset); + pUcFile = (u8 *)(pFileStart + pDspImageInfoV6->begin_offset); + pCodeEnd = (u8 *)(pFileStart + pDspImageInfoV6->end_offset); run_address = pDspImageInfoV6->run_address; run_size = pDspImageInfoV6->image_size; image_chksum = (ULONG)pDspImageInfoV6->checksum; @@ -1188,7 +1188,7 @@ u16 scram_dnldr(struct ft1000_device *ft1000dev, void *pFileStart, ULONG FileLe pprov_record->pprov_data = pbuffer; list_add_tail (&pprov_record->list, &pft1000info->prov_list); // Move to next entry if available - pUcFile = (UCHAR *)((unsigned long)pUcFile + (UINT)((usHdrLength + 1) & 0xFFFFFFFE) + sizeof(struct pseudo_hdr)); + pUcFile = (u8 *)((unsigned long)pUcFile + (UINT)((usHdrLength + 1) & 0xFFFFFFFE) + sizeof(struct pseudo_hdr)); if ( (unsigned long)(pUcFile) - (unsigned long)(pFileStart) >= (unsigned long)FileLength) { uiState = STATE_DONE_FILE; } diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c index 8333e66bef2a..2f195c8c9752 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c @@ -367,7 +367,7 @@ u16 ft1000_write_dpram16(struct ft1000_device *ft1000dev, USHORT indx, USHORT va //--------------------------------------------------------------------------- u16 fix_ft1000_read_dpram32(struct ft1000_device *ft1000dev, USHORT indx, u8 *buffer) { - UCHAR buf[16]; + u8 buf[16]; USHORT pos; u16 ret = STATUS_SUCCESS; @@ -419,8 +419,8 @@ u16 fix_ft1000_write_dpram32(struct ft1000_device *ft1000dev, USHORT indx, u8 *b USHORT pos1; USHORT pos2; USHORT i; - UCHAR buf[32]; - UCHAR resultbuffer[32]; + u8 buf[32]; + u8 resultbuffer[32]; u8 *pdata; u16 ret = STATUS_SUCCESS; diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_usb.h b/drivers/staging/ft1000/ft1000-usb/ft1000_usb.h index 4996da9e2355..96665a783919 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_usb.h +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_usb.h @@ -98,7 +98,6 @@ struct prov_record { /*end of Jim*/ #define DEBUG(args...) printk(KERN_INFO args) -#define UCHAR u8 #define USHORT u16 #define ULONG u32 /* WTF ??? */ #define BOOLEAN u8 @@ -371,15 +370,15 @@ struct prov_record { -#define ISR_EMPTY (UCHAR)0x00 // no bits set in ISR +#define ISR_EMPTY (u8)0x00 // no bits set in ISR -#define ISR_DOORBELL_ACK (UCHAR)0x01 // the doorbell i sent has been recieved. +#define ISR_DOORBELL_ACK (u8)0x01 // the doorbell i sent has been recieved. -#define ISR_DOORBELL_PEND (UCHAR)0x02 // doorbell for me +#define ISR_DOORBELL_PEND (u8)0x02 // doorbell for me -#define ISR_RCV (UCHAR)0x04 // packet received with no errors +#define ISR_RCV (u8)0x04 // packet received with no errors -#define ISR_WATERMARK (UCHAR)0x08 // +#define ISR_WATERMARK (u8)0x08 // -- cgit v1.2.3 From d1674983e0fdf3a18dbc4ac7f1f0912f7b1c246e Mon Sep 17 00:00:00 2001 From: Marek Belisko Date: Wed, 3 Nov 2010 11:19:49 +0100 Subject: staging: ft1000: GEt rid of PUSHORT typedef usage. Signed-off-by: Marek Belisko Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ft1000/ft1000-usb/ft1000_chdev.c | 6 +++--- drivers/staging/ft1000/ft1000-usb/ft1000_hw.c | 18 +++++++++--------- drivers/staging/ft1000/ft1000-usb/ft1000_hw.h | 2 +- drivers/staging/ft1000/ft1000-usb/ft1000_usb.h | 1 - 4 files changed, 13 insertions(+), 14 deletions(-) diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_chdev.c b/drivers/staging/ft1000/ft1000-usb/ft1000_chdev.c index cadfb62229ef..6659bc77fe5b 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_chdev.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_chdev.c @@ -656,7 +656,7 @@ static long ft1000_ChIoctl (struct file *File, unsigned int Command, USHORT qtype; USHORT msgsz; struct pseudo_hdr *ppseudo_hdr; - PUSHORT pmsg; + u16 *pmsg; USHORT total_len; USHORT app_index; u16 status; @@ -766,8 +766,8 @@ static long ft1000_ChIoctl (struct file *File, unsigned int Command, // Make sure we are within the limits of the slow queue memory limitation if ( (msgsz < MAX_CMD_SQSIZE) && (msgsz > PSEUDOSZ) ) { // Need to put sequence number plus new checksum for message - //pmsg = (PUSHORT)&dpram_command.dpram_blk.pseudohdr; - pmsg = (PUSHORT)&dpram_data->pseudohdr; + //pmsg = (u16 *)&dpram_command.dpram_blk.pseudohdr; + pmsg = (u16 *)&dpram_data->pseudohdr; ppseudo_hdr = (struct pseudo_hdr *)pmsg; total_len = msgsz+2; if (total_len & 0x1) { diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c index 2f195c8c9752..c964bf7fa1ea 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c @@ -1209,7 +1209,7 @@ static int ft1000_copy_up_pkt (struct urb *urb) //DEBUG("ft1000_copy_up_pkt: transfer_buffer_length=%d, actual_buffer_len=%d\n", // urb->transfer_buffer_length, urb->actual_length); - chksum = (PUSHORT)ft1000dev->rx_buf; + chksum = (u16 *)ft1000dev->rx_buf; tempword = *chksum++; for (i=1; i<7; i++) @@ -1541,7 +1541,7 @@ static int ft1000_dsp_prov(void *arg) u16 i=0; struct prov_record *ptr; struct pseudo_hdr *ppseudo_hdr; - PUSHORT pmsg; + u16 *pmsg; u16 status; USHORT TempShortBuf [256]; @@ -1579,7 +1579,7 @@ static int ft1000_dsp_prov(void *arg) len = htons(len); len += PSEUDOSZ; - pmsg = (PUSHORT)ptr->pprov_data; + pmsg = (u16 *)ptr->pprov_data; ppseudo_hdr = (struct pseudo_hdr *)pmsg; // Insert slow queue sequence number ppseudo_hdr->seq_num = info->squeseqnum++; @@ -1626,7 +1626,7 @@ static int ft1000_proc_drvmsg (struct ft1000_device *dev, u16 size) { struct drv_msg *pdrvmsg; u16 i; struct pseudo_hdr *ppseudo_hdr; - PUSHORT pmsg; + u16 *pmsg; u16 status; union { u8 byte[2]; @@ -1758,7 +1758,7 @@ static int ft1000_proc_drvmsg (struct ft1000_device *dev, u16 size) { tempword = ntohs(pdrvmsg->length); info->DSPInfoBlklen = tempword; if (tempword < (MAX_DSP_SESS_REC-4) ) { - pmsg = (PUSHORT)&pdrvmsg->data[0]; + pmsg = (u16 *)&pdrvmsg->data[0]; for (i=0; i<((tempword+1)/2); i++) { DEBUG("FT1000:drivermsg:dsp info data = 0x%x\n", *pmsg); info->DSPInfoBlk[i+10] = *pmsg++; @@ -1790,10 +1790,10 @@ static int ft1000_proc_drvmsg (struct ft1000_device *dev, u16 size) { // Put message into Slow Queue // Form Pseudo header - pmsg = (PUSHORT)info->DSPInfoBlk; + pmsg = (u16 *)info->DSPInfoBlk; *pmsg++ = 0; *pmsg++ = htons(info->DSPInfoBlklen+20+info->DSPInfoBlklen); - ppseudo_hdr = (struct pseudo_hdr *)(PUSHORT)&info->DSPInfoBlk[2]; + ppseudo_hdr = (struct pseudo_hdr *)(u16 *)&info->DSPInfoBlk[2]; ppseudo_hdr->length = htons(info->DSPInfoBlklen+4+info->DSPInfoBlklen); ppseudo_hdr->source = 0x10; ppseudo_hdr->destination = 0x20; @@ -1840,7 +1840,7 @@ static int ft1000_proc_drvmsg (struct ft1000_device *dev, u16 size) { if ( (tempword & FT1000_DB_DPRAM_TX) == 0) { // Put message into Slow Queue // Form Pseudo header - pmsg = (PUSHORT)&tempbuffer[0]; + pmsg = (u16 *)&tempbuffer[0]; ppseudo_hdr = (struct pseudo_hdr *)pmsg; ppseudo_hdr->length = htons(0x0012); ppseudo_hdr->source = 0x10; @@ -1861,7 +1861,7 @@ static int ft1000_proc_drvmsg (struct ft1000_device *dev, u16 size) { for (i=1; i<7; i++) { ppseudo_hdr->checksum ^= *pmsg++; } - pmsg = (PUSHORT)&tempbuffer[16]; + pmsg = (u16 *)&tempbuffer[16]; *pmsg++ = htons(RSP_DRV_ERR_RPT_MSG); *pmsg++ = htons(0x000e); *pmsg++ = htons(info->DSP_TIME[0]); diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.h b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.h index c58074131014..a2e19d25a7b5 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.h +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.h @@ -4,7 +4,7 @@ #include "ft1000_usb.h" -extern u16 ft1000_read_register(struct usb_device *dev, PUSHORT Data, u8 nRegIndx); +extern u16 ft1000_read_register(struct usb_device *dev, u16 *Data, u8 nRegIndx); extern u16 ft1000_write_register(struct usb_device *dev, USHORT value, u8 nRegIndx); #endif diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_usb.h b/drivers/staging/ft1000/ft1000-usb/ft1000_usb.h index 96665a783919..7ec8845ec601 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_usb.h +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_usb.h @@ -102,7 +102,6 @@ struct prov_record { #define ULONG u32 /* WTF ??? */ #define BOOLEAN u8 #define PULONG u32 * -#define PUSHORT u16 * #define PCHAR u8 * #define UINT u32 -- cgit v1.2.3 From fc549a05e74edf9535862a4e517e63ade3908f75 Mon Sep 17 00:00:00 2001 From: Marek Belisko Date: Wed, 3 Nov 2010 11:19:50 +0100 Subject: staging: ft1000: Get rid of USHORT typedef usage. Signed-off-by: Marek Belisko Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ft1000/ft1000-usb/ft1000_chdev.c | 8 +- .../staging/ft1000/ft1000-usb/ft1000_download.c | 114 ++++++++++----------- drivers/staging/ft1000/ft1000-usb/ft1000_hw.c | 36 +++---- drivers/staging/ft1000/ft1000-usb/ft1000_hw.h | 2 +- drivers/staging/ft1000/ft1000-usb/ft1000_proc.c | 2 +- drivers/staging/ft1000/ft1000-usb/ft1000_usb.h | 15 ++- 6 files changed, 88 insertions(+), 89 deletions(-) diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_chdev.c b/drivers/staging/ft1000/ft1000-usb/ft1000_chdev.c index 6659bc77fe5b..f6b2e919b56b 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_chdev.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_chdev.c @@ -653,12 +653,12 @@ static long ft1000_ChIoctl (struct file *File, unsigned int Command, { IOCTL_DPRAM_BLK *dpram_data; //IOCTL_DPRAM_COMMAND dpram_command; - USHORT qtype; - USHORT msgsz; + u16 qtype; + u16 msgsz; struct pseudo_hdr *ppseudo_hdr; u16 *pmsg; - USHORT total_len; - USHORT app_index; + u16 total_len; + u16 app_index; u16 status; //DEBUG("FT1000:ft1000_ChIoctl: IOCTL_FT1000_SET_DPRAM called\n"); diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_download.c b/drivers/staging/ft1000/ft1000-usb/ft1000_download.c index d7377eba7ede..d1bc53776d4b 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_download.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_download.c @@ -126,7 +126,7 @@ struct dsp_image_info { static ULONG check_usb_db (struct ft1000_device *ft1000dev) { int loopcnt; - USHORT temp; + u16 temp; ULONG status; loopcnt = 0; @@ -190,7 +190,7 @@ static ULONG check_usb_db (struct ft1000_device *ft1000dev) // Function: get_handshake // // Parameters: struct ft1000_device - device structure -// USHORT expected_value - the handshake value expected +// u16 expected_value - the handshake value expected // // Returns: handshakevalue - success // HANDSHAKE_TIMEOUT_VALUE - failure @@ -200,9 +200,9 @@ static ULONG check_usb_db (struct ft1000_device *ft1000dev) // Notes: // //--------------------------------------------------------------------------- -static USHORT get_handshake(struct ft1000_device *ft1000dev, USHORT expected_value) +static u16 get_handshake(struct ft1000_device *ft1000dev, u16 expected_value) { - USHORT handshake; + u16 handshake; int loopcnt; ULONG status=0; struct ft1000_info *pft1000info = netdev_priv(ft1000dev->net); @@ -259,7 +259,7 @@ static USHORT get_handshake(struct ft1000_device *ft1000dev, USHORT expected_val // Function: put_handshake // // Parameters: struct ft1000_device - device structure -// USHORT handshake_value - handshake to be written +// u16 handshake_value - handshake to be written // // Returns: none // @@ -269,10 +269,10 @@ static USHORT get_handshake(struct ft1000_device *ft1000dev, USHORT expected_val // Notes: // //--------------------------------------------------------------------------- -static void put_handshake(struct ft1000_device *ft1000dev,USHORT handshake_value) +static void put_handshake(struct ft1000_device *ft1000dev,u16 handshake_value) { ULONG tempx; - USHORT tempword; + u16 tempword; ULONG status; @@ -280,18 +280,18 @@ static void put_handshake(struct ft1000_device *ft1000dev,USHORT handshake_value tempx = (ULONG)handshake_value; tempx = ntohl(tempx); - tempword = (USHORT)(tempx & 0xffff); + tempword = (u16)(tempx & 0xffff); status = ft1000_write_dpram16 (ft1000dev, DWNLD_MAG1_HANDSHAKE_LOC, tempword, 0); - tempword = (USHORT)(tempx >> 16); + tempword = (u16)(tempx >> 16); status = ft1000_write_dpram16 (ft1000dev, DWNLD_MAG1_HANDSHAKE_LOC, tempword, 1); status = ft1000_write_register(ft1000dev, FT1000_DB_DNLD_TX, FT1000_REG_DOORBELL); } -static USHORT get_handshake_usb(struct ft1000_device *ft1000dev, USHORT expected_value) +static u16 get_handshake_usb(struct ft1000_device *ft1000dev, u16 expected_value) { - USHORT handshake; + u16 handshake; int loopcnt; - USHORT temp; + u16 temp; ULONG status=0; struct ft1000_info *pft1000info = netdev_priv(ft1000dev->net); @@ -327,7 +327,7 @@ static USHORT get_handshake_usb(struct ft1000_device *ft1000dev, USHORT expected return HANDSHAKE_TIMEOUT_VALUE; } -static void put_handshake_usb(struct ft1000_device *ft1000dev,USHORT handshake_value) +static void put_handshake_usb(struct ft1000_device *ft1000dev,u16 handshake_value) { int i; @@ -346,11 +346,11 @@ static void put_handshake_usb(struct ft1000_device *ft1000dev,USHORT handshake_v // Notes: // //--------------------------------------------------------------------------- -static USHORT get_request_type(struct ft1000_device *ft1000dev) +static u16 get_request_type(struct ft1000_device *ft1000dev) { - USHORT request_type; + u16 request_type; ULONG status; - USHORT tempword; + u16 tempword; ULONG tempx; struct ft1000_info *pft1000info = netdev_priv(ft1000dev->net); @@ -367,18 +367,18 @@ static USHORT get_request_type(struct ft1000_device *ft1000dev) tempx |= (tempword << 16); tempx = ntohl(tempx); } - request_type = (USHORT)tempx; + request_type = (u16)tempx; //DEBUG("get_request_type: request_type is %x\n", request_type); return request_type; } -static USHORT get_request_type_usb(struct ft1000_device *ft1000dev) +static u16 get_request_type_usb(struct ft1000_device *ft1000dev) { - USHORT request_type; + u16 request_type; ULONG status; - USHORT tempword; + u16 tempword; ULONG tempx; struct ft1000_info *pft1000info = netdev_priv(ft1000dev->net); if ( pft1000info->bootmode == 1) @@ -399,7 +399,7 @@ static USHORT get_request_type_usb(struct ft1000_device *ft1000dev) tempx |= (tempword << 16); tempx = ntohl(tempx); } - request_type = (USHORT)tempx; + request_type = (u16)tempx; //DEBUG("get_request_type: request_type is %x\n", request_type); return request_type; @@ -421,7 +421,7 @@ static USHORT get_request_type_usb(struct ft1000_device *ft1000dev) static long get_request_value(struct ft1000_device *ft1000dev) { ULONG value; - USHORT tempword; + u16 tempword; ULONG status; struct ft1000_info *pft1000info = netdev_priv(ft1000dev->net); @@ -450,7 +450,7 @@ static long get_request_value(struct ft1000_device *ft1000dev) static long get_request_value_usb(struct ft1000_device *ft1000dev) { ULONG value; - USHORT tempword; + u16 tempword; ULONG status; struct ft1000_info * pft1000info = netdev_priv(ft1000dev->net); @@ -516,10 +516,10 @@ static void put_request_value(struct ft1000_device *ft1000dev, long lvalue) // Notes: // //--------------------------------------------------------------------------- -static USHORT hdr_checksum(struct pseudo_hdr *pHdr) +static u16 hdr_checksum(struct pseudo_hdr *pHdr) { - USHORT *usPtr = (USHORT *)pHdr; - USHORT chksum; + u16 *usPtr = (u16 *)pHdr; + u16 chksum; chksum = ((((((usPtr[0] ^ usPtr[1]) ^ usPtr[2]) ^ usPtr[3]) ^ @@ -533,7 +533,7 @@ static USHORT hdr_checksum(struct pseudo_hdr *pHdr) // Function: write_blk // // Parameters: struct ft1000_device - device structure -// USHORT **pUsFile - DSP image file pointer in USHORT +// u16 **pUsFile - DSP image file pointer in u16 // u8 **pUcFile - DSP image file pointer in u8 // long word_length - lenght of the buffer to be written // to DPRAM @@ -546,20 +546,20 @@ static USHORT hdr_checksum(struct pseudo_hdr *pHdr) // Notes: // //--------------------------------------------------------------------------- -static ULONG write_blk (struct ft1000_device *ft1000dev, USHORT **pUsFile, u8 **pUcFile, long word_length) +static ULONG write_blk (struct ft1000_device *ft1000dev, u16 **pUsFile, u8 **pUcFile, long word_length) { ULONG Status = STATUS_SUCCESS; - USHORT dpram; + u16 dpram; long temp_word_length; int loopcnt, i, j; - USHORT *pTempFile; - USHORT tempword; - USHORT tempbuffer[64]; - USHORT resultbuffer[64]; + u16 *pTempFile; + u16 tempword; + u16 tempbuffer[64]; + u16 resultbuffer[64]; struct ft1000_info *pft1000info = netdev_priv(ft1000dev->net); //DEBUG("FT1000:download:start word_length = %d\n",(int)word_length); - dpram = (USHORT)DWNLD_MAG1_PS_HDR_LOC; + dpram = (u16)DWNLD_MAG1_PS_HDR_LOC; tempword = *(*pUsFile); (*pUsFile)++; Status = ft1000_write_dpram16(ft1000dev, dpram, tempword, 0); @@ -569,7 +569,7 @@ static ULONG write_blk (struct ft1000_device *ft1000dev, USHORT **pUsFile, u8 ** *pUcFile = *pUcFile + 4; word_length--; - tempword = (USHORT)word_length; + tempword = (u16)word_length; word_length = (word_length / 16) + 1; pTempFile = *pUsFile; temp_word_length = word_length; @@ -689,7 +689,7 @@ static void usb_dnld_complete (struct urb *urb) // Function: write_blk_fifo // // Parameters: struct ft1000_device - device structure -// USHORT **pUsFile - DSP image file pointer in USHORT +// u16 **pUsFile - DSP image file pointer in u16 // u8 **pUcFile - DSP image file pointer in u8 // long word_length - lenght of the buffer to be written // to DPRAM @@ -702,7 +702,7 @@ static void usb_dnld_complete (struct urb *urb) // Notes: // //--------------------------------------------------------------------------- -static ULONG write_blk_fifo (struct ft1000_device *ft1000dev, USHORT **pUsFile, u8 **pUcFile, long word_length) +static ULONG write_blk_fifo (struct ft1000_device *ft1000dev, u16 **pUsFile, u8 **pUcFile, long word_length) { ULONG Status = STATUS_SUCCESS; int byte_length; @@ -774,21 +774,21 @@ u16 scram_dnldr(struct ft1000_device *ft1000dev, void *pFileStart, ULONG FileLe { u16 Status = STATUS_SUCCESS; UINT uiState; - USHORT handshake; + u16 handshake; struct pseudo_hdr *pHdr; - USHORT usHdrLength; + u16 usHdrLength; long word_length; - USHORT request; - USHORT temp; - USHORT tempword; + u16 request; + u16 temp; + u16 tempword; struct dsp_file_hdr *pFileHdr5; struct dsp_image_info *pDspImageInfoV6 = NULL; long requested_version; BOOLEAN bGoodVersion; struct drv_msg *pMailBoxData; - USHORT *pUsData = NULL; - USHORT *pUsFile = NULL; + u16 *pUsData = NULL; + u16 *pUsFile = NULL; u8 *pUcFile = NULL; u8 *pBootEnd = NULL, *pCodeEnd= NULL; int imageN; @@ -798,7 +798,7 @@ u16 scram_dnldr(struct ft1000_device *ft1000dev, void *pFileStart, ULONG FileLe ULONG templong; ULONG image_chksum = 0; - USHORT dpram = 0; + u16 dpram = 0; u8 *pbuffer; struct prov_record *pprov_record; struct ft1000_info *pft1000info = netdev_priv(ft1000dev->net); @@ -820,7 +820,7 @@ u16 scram_dnldr(struct ft1000_device *ft1000dev, void *pFileStart, ULONG FileLe ft1000_write_register (ft1000dev, 0x800, FT1000_REG_MAG_WATERMARK); - pUsFile = (USHORT *)(pFileStart + pFileHdr5->loader_offset); + pUsFile = (u16 *)(pFileStart + pFileHdr5->loader_offset); pUcFile = (u8 *)(pFileStart + pFileHdr5->loader_offset); pBootEnd = (u8 *)(pFileStart + pFileHdr5->loader_code_end); @@ -878,7 +878,7 @@ u16 scram_dnldr(struct ft1000_device *ft1000dev, void *pFileStart, ULONG FileLe case REQUEST_DONE_BL: DEBUG("FT1000:REQUEST_DONE_BL\n"); /* Reposition ptrs to beginning of code section */ - pUsFile = (USHORT *)(pBootEnd); + pUsFile = (u16 *)(pBootEnd); pUcFile = (u8 *)(pBootEnd); //DEBUG("FT1000:download:pUsFile = 0x%8x\n", (int)pUsFile); //DEBUG("FT1000:download:pUcFile = 0x%8x\n", (int)pUcFile); @@ -909,7 +909,7 @@ u16 scram_dnldr(struct ft1000_device *ft1000dev, void *pFileStart, ULONG FileLe /* * Position ASIC DPRAM auto-increment pointer. */ - dpram = (USHORT)DWNLD_MAG1_PS_HDR_LOC; + dpram = (u16)DWNLD_MAG1_PS_HDR_LOC; if (word_length & 0x1) word_length++; word_length = word_length / 2; @@ -988,7 +988,7 @@ u16 scram_dnldr(struct ft1000_device *ft1000dev, void *pFileStart, ULONG FileLe case REQUEST_DONE_CL: pft1000info->usbboot = 3; /* Reposition ptrs to beginning of provisioning section */ - pUsFile = (USHORT *)(pFileStart + pFileHdr5->commands_offset); + pUsFile = (u16 *)(pFileStart + pFileHdr5->commands_offset); pUcFile = (u8 *)(pFileStart + pFileHdr5->commands_offset); uiState = STATE_DONE_DWNLD; break; @@ -1027,7 +1027,7 @@ u16 scram_dnldr(struct ft1000_device *ft1000dev, void *pFileStart, ULONG FileLe /* * Position ASIC DPRAM auto-increment pointer. */ - dpram = (USHORT)DWNLD_MAG1_PS_HDR_LOC; + dpram = (u16)DWNLD_MAG1_PS_HDR_LOC; if (word_length & 0x1) word_length++; word_length = word_length / 2; @@ -1053,8 +1053,8 @@ u16 scram_dnldr(struct ft1000_device *ft1000dev, void *pFileStart, ULONG FileLe */ - pUsData = (USHORT *)&pMailBoxData->data[0]; - dpram = (USHORT)DWNLD_MAG1_PS_HDR_LOC; + pUsData = (u16 *)&pMailBoxData->data[0]; + dpram = (u16)DWNLD_MAG1_PS_HDR_LOC; if (word_length & 0x1) word_length++; @@ -1079,10 +1079,10 @@ u16 scram_dnldr(struct ft1000_device *ft1000dev, void *pFileStart, ULONG FileLe * Position ASIC DPRAM auto-increment pointer. */ - pUsFile = (USHORT *)(pFileStart + pFileHdr5->version_data_offset); + pUsFile = (u16 *)(pFileStart + pFileHdr5->version_data_offset); - dpram = (USHORT)DWNLD_MAG1_PS_HDR_LOC; + dpram = (u16)DWNLD_MAG1_PS_HDR_LOC; if (word_length & 0x1) word_length++; @@ -1110,15 +1110,15 @@ u16 scram_dnldr(struct ft1000_device *ft1000dev, void *pFileStart, ULONG FileLe for (imageN = 0; imageN < pFileHdr5->nDspImages; imageN++) { - temp = (USHORT)(pDspImageInfoV6->version); + temp = (u16)(pDspImageInfoV6->version); templong = temp; - temp = (USHORT)(pDspImageInfoV6->version >> 16); + temp = (u16)(pDspImageInfoV6->version >> 16); templong |= (temp << 16); if (templong == (ULONG)requested_version) { bGoodVersion = TRUE; DEBUG("FT1000:download: bGoodVersion is TRUE\n"); - pUsFile = (USHORT *)(pFileStart + pDspImageInfoV6->begin_offset); + pUsFile = (u16 *)(pFileStart + pDspImageInfoV6->begin_offset); pUcFile = (u8 *)(pFileStart + pDspImageInfoV6->begin_offset); pCodeEnd = (u8 *)(pFileStart + pDspImageInfoV6->end_offset); run_address = pDspImageInfoV6->run_address; diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c index c964bf7fa1ea..709f8da12454 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c @@ -160,7 +160,7 @@ u16 ft1000_read_register(struct ft1000_device *ft1000dev, u16* Data, u16 nRegInd // Notes: // //--------------------------------------------------------------------------- -u16 ft1000_write_register(struct ft1000_device *ft1000dev, USHORT value, u16 nRegIndx) +u16 ft1000_write_register(struct ft1000_device *ft1000dev, u16 value, u16 nRegIndx) { u16 ret = STATUS_SUCCESS; @@ -196,7 +196,7 @@ u16 ft1000_write_register(struct ft1000_device *ft1000dev, USHORT value, u16 nRe // //--------------------------------------------------------------------------- -u16 ft1000_read_dpram32(struct ft1000_device *ft1000dev, USHORT indx, u8 *buffer, USHORT cnt) +u16 ft1000_read_dpram32(struct ft1000_device *ft1000dev, u16 indx, u8 *buffer, u16 cnt) { u16 ret = STATUS_SUCCESS; @@ -235,7 +235,7 @@ u16 ft1000_read_dpram32(struct ft1000_device *ft1000dev, USHORT indx, u8 *buffer // Notes: // //--------------------------------------------------------------------------- -u16 ft1000_write_dpram32(struct ft1000_device *ft1000dev, USHORT indx, u8 *buffer, USHORT cnt) +u16 ft1000_write_dpram32(struct ft1000_device *ft1000dev, u16 indx, u8 *buffer, u16 cnt) { u16 ret = STATUS_SUCCESS; @@ -272,7 +272,7 @@ u16 ft1000_write_dpram32(struct ft1000_device *ft1000dev, USHORT indx, u8 *buffe // Notes: // //--------------------------------------------------------------------------- -u16 ft1000_read_dpram16(struct ft1000_device *ft1000dev, USHORT indx, u8 *buffer, u8 highlow) +u16 ft1000_read_dpram16(struct ft1000_device *ft1000dev, u16 indx, u8 *buffer, u8 highlow) { u16 ret = STATUS_SUCCESS; @@ -320,7 +320,7 @@ u16 ft1000_read_dpram16(struct ft1000_device *ft1000dev, USHORT indx, u8 *buffer // Notes: // //--------------------------------------------------------------------------- -u16 ft1000_write_dpram16(struct ft1000_device *ft1000dev, USHORT indx, USHORT value, u8 highlow) +u16 ft1000_write_dpram16(struct ft1000_device *ft1000dev, u16 indx, u16 value, u8 highlow) { u16 ret = STATUS_SUCCESS; @@ -365,10 +365,10 @@ u16 ft1000_write_dpram16(struct ft1000_device *ft1000dev, USHORT indx, USHORT va // Notes: // //--------------------------------------------------------------------------- -u16 fix_ft1000_read_dpram32(struct ft1000_device *ft1000dev, USHORT indx, u8 *buffer) +u16 fix_ft1000_read_dpram32(struct ft1000_device *ft1000dev, u16 indx, u8 *buffer) { u8 buf[16]; - USHORT pos; + u16 pos; u16 ret = STATUS_SUCCESS; //DEBUG("fix_ft1000_read_dpram32: indx: %d \n", indx); @@ -414,11 +414,11 @@ u16 fix_ft1000_read_dpram32(struct ft1000_device *ft1000dev, USHORT indx, u8 *bu // Notes: // //--------------------------------------------------------------------------- -u16 fix_ft1000_write_dpram32(struct ft1000_device *ft1000dev, USHORT indx, u8 *buffer) +u16 fix_ft1000_write_dpram32(struct ft1000_device *ft1000dev, u16 indx, u8 *buffer) { - USHORT pos1; - USHORT pos2; - USHORT i; + u16 pos1; + u16 pos2; + u16 i; u8 buf[32]; u8 resultbuffer[32]; u8 *pdata; @@ -494,7 +494,7 @@ u16 fix_ft1000_write_dpram32(struct ft1000_device *ft1000dev, USHORT indx, u8 *b static void card_reset_dsp (struct ft1000_device *ft1000dev, BOOLEAN value) { u16 status = STATUS_SUCCESS; - USHORT tempword; + u16 tempword; status = ft1000_write_register (ft1000dev, HOST_INTF_BE, FT1000_REG_SUP_CTRL); status = ft1000_read_register(ft1000dev, &tempword, FT1000_REG_SUP_CTRL); @@ -593,7 +593,7 @@ void CardSendCommand(struct ft1000_device *ft1000dev, void *ptempbuffer, int siz int dsp_reload(struct ft1000_device *ft1000dev) { u16 status; - USHORT tempword; + u16 tempword; ULONG templong; struct ft1000_info *pft1000info; @@ -1543,7 +1543,7 @@ static int ft1000_dsp_prov(void *arg) struct pseudo_hdr *ppseudo_hdr; u16 *pmsg; u16 status; - USHORT TempShortBuf [256]; + u16 TempShortBuf [256]; DEBUG("*** DspProv Entered\n"); @@ -1876,7 +1876,7 @@ static int ft1000_proc_drvmsg (struct ft1000_device *dev, u16 size) { *pmsg++ = convert.wrd; *pmsg++ = htons(info->DrvErrNum); - CardSendCommand (dev, (unsigned char*)&tempbuffer[0], (USHORT)(0x0012 + PSEUDOSZ)); + CardSendCommand (dev, (unsigned char*)&tempbuffer[0], (u16)(0x0012 + PSEUDOSZ)); info->DrvErrNum = 0; } info->DrvMsgPend = 0; @@ -1907,9 +1907,9 @@ int ft1000_poll(void* dev_id) { u16 status; u16 size; int i; - USHORT data; - USHORT modulo; - USHORT portid; + u16 data; + u16 modulo; + u16 portid; u16 nxtph; struct dpram_blk *pdpram_blk; struct pseudo_hdr *ppseudo_hdr; diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.h b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.h index a2e19d25a7b5..ab9312f9f326 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.h +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.h @@ -5,6 +5,6 @@ #include "ft1000_usb.h" extern u16 ft1000_read_register(struct usb_device *dev, u16 *Data, u8 nRegIndx); -extern u16 ft1000_write_register(struct usb_device *dev, USHORT value, u8 nRegIndx); +extern u16 ft1000_write_register(struct usb_device *dev, u16 value, u8 nRegIndx); #endif diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_proc.c b/drivers/staging/ft1000/ft1000-usb/ft1000_proc.c index dda0e33b4864..f665640058ae 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_proc.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_proc.c @@ -38,7 +38,7 @@ //#endif -u16 ft1000_read_dpram16 (struct ft1000_device *ft1000dev, USHORT indx, +u16 ft1000_read_dpram16 (struct ft1000_device *ft1000dev, u16 indx, u8 *buffer, u8 highlow); diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_usb.h b/drivers/staging/ft1000/ft1000-usb/ft1000_usb.h index 7ec8845ec601..2e4868666e3d 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_usb.h +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_usb.h @@ -98,7 +98,6 @@ struct prov_record { /*end of Jim*/ #define DEBUG(args...) printk(KERN_INFO args) -#define USHORT u16 #define ULONG u32 /* WTF ??? */ #define BOOLEAN u8 #define PULONG u32 * @@ -561,13 +560,13 @@ struct dpram_blk { } __attribute__ ((packed)); u16 ft1000_read_register(struct ft1000_device *ft1000dev, u16* Data, u16 nRegIndx); -u16 ft1000_write_register(struct ft1000_device *ft1000dev, USHORT value, u16 nRegIndx); -u16 ft1000_read_dpram32(struct ft1000_device *ft1000dev, USHORT indx, u8 *buffer, USHORT cnt); -u16 ft1000_write_dpram32(struct ft1000_device *ft1000dev, USHORT indx, u8 *buffer, USHORT cnt); -u16 ft1000_read_dpram16(struct ft1000_device *ft1000dev, USHORT indx, u8 *buffer, u8 highlow); -u16 ft1000_write_dpram16(struct ft1000_device *ft1000dev, USHORT indx, USHORT value, u8 highlow); -u16 fix_ft1000_read_dpram32(struct ft1000_device *ft1000dev, USHORT indx, u8 *buffer); -u16 fix_ft1000_write_dpram32(struct ft1000_device *ft1000dev, USHORT indx, u8 *buffer); +u16 ft1000_write_register(struct ft1000_device *ft1000dev, u16 value, u16 nRegIndx); +u16 ft1000_read_dpram32(struct ft1000_device *ft1000dev, u16 indx, u8 *buffer, u16 cnt); +u16 ft1000_write_dpram32(struct ft1000_device *ft1000dev, u16 indx, u8 *buffer, u16 cnt); +u16 ft1000_read_dpram16(struct ft1000_device *ft1000dev, u16 indx, u8 *buffer, u8 highlow); +u16 ft1000_write_dpram16(struct ft1000_device *ft1000dev, u16 indx, u16 value, u8 highlow); +u16 fix_ft1000_read_dpram32(struct ft1000_device *ft1000dev, u16 indx, u8 *buffer); +u16 fix_ft1000_write_dpram32(struct ft1000_device *ft1000dev, u16 indx, u8 *buffer); extern void *pFileStart; extern size_t FileLength; -- cgit v1.2.3 From d44d76f93dafdbaeac0f1d541f3867777de65c8a Mon Sep 17 00:00:00 2001 From: Marek Belisko Date: Wed, 3 Nov 2010 11:19:51 +0100 Subject: staging: ft1000: Get rid of PULONG typedef usage. Signed-off-by: Marek Belisko Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ft1000/ft1000-usb/ft1000_usb.h | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_usb.h b/drivers/staging/ft1000/ft1000-usb/ft1000_usb.h index 2e4868666e3d..bc0022325df2 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_usb.h +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_usb.h @@ -100,7 +100,6 @@ struct prov_record { #define ULONG u32 /* WTF ??? */ #define BOOLEAN u8 -#define PULONG u32 * #define PCHAR u8 * #define UINT u32 -- cgit v1.2.3 From 84b7801d135ca90903df3a9170b9db5978fe8fce Mon Sep 17 00:00:00 2001 From: Marek Belisko Date: Wed, 3 Nov 2010 11:19:52 +0100 Subject: staging: ft1000: Get rid of ULONG typedef usage. Signed-off-by: Marek Belisko Signed-off-by: Greg Kroah-Hartman --- .../staging/ft1000/ft1000-usb/ft1000_download.c | 52 +++++++++++----------- drivers/staging/ft1000/ft1000-usb/ft1000_hw.c | 2 +- drivers/staging/ft1000/ft1000-usb/ft1000_usb.h | 3 +- 3 files changed, 28 insertions(+), 29 deletions(-) diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_download.c b/drivers/staging/ft1000/ft1000-usb/ft1000_download.c index d1bc53776d4b..0a2b833bfb3e 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_download.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_download.c @@ -123,11 +123,11 @@ struct dsp_image_info { // Notes: // //--------------------------------------------------------------------------- -static ULONG check_usb_db (struct ft1000_device *ft1000dev) +static u32 check_usb_db (struct ft1000_device *ft1000dev) { int loopcnt; u16 temp; - ULONG status; + u32 status; loopcnt = 0; while (loopcnt < 10) @@ -204,7 +204,7 @@ static u16 get_handshake(struct ft1000_device *ft1000dev, u16 expected_value) { u16 handshake; int loopcnt; - ULONG status=0; + u32 status=0; struct ft1000_info *pft1000info = netdev_priv(ft1000dev->net); loopcnt = 0; @@ -271,13 +271,13 @@ static u16 get_handshake(struct ft1000_device *ft1000dev, u16 expected_value) //--------------------------------------------------------------------------- static void put_handshake(struct ft1000_device *ft1000dev,u16 handshake_value) { - ULONG tempx; + u32 tempx; u16 tempword; - ULONG status; + u32 status; - tempx = (ULONG)handshake_value; + tempx = (u32)handshake_value; tempx = ntohl(tempx); tempword = (u16)(tempx & 0xffff); @@ -292,7 +292,7 @@ static u16 get_handshake_usb(struct ft1000_device *ft1000dev, u16 expected_value u16 handshake; int loopcnt; u16 temp; - ULONG status=0; + u32 status=0; struct ft1000_info *pft1000info = netdev_priv(ft1000dev->net); loopcnt = 0; @@ -349,9 +349,9 @@ static void put_handshake_usb(struct ft1000_device *ft1000dev,u16 handshake_valu static u16 get_request_type(struct ft1000_device *ft1000dev) { u16 request_type; - ULONG status; + u32 status; u16 tempword; - ULONG tempx; + u32 tempx; struct ft1000_info *pft1000info = netdev_priv(ft1000dev->net); if ( pft1000info->bootmode == 1) @@ -377,9 +377,9 @@ static u16 get_request_type(struct ft1000_device *ft1000dev) static u16 get_request_type_usb(struct ft1000_device *ft1000dev) { u16 request_type; - ULONG status; + u32 status; u16 tempword; - ULONG tempx; + u32 tempx; struct ft1000_info *pft1000info = netdev_priv(ft1000dev->net); if ( pft1000info->bootmode == 1) { @@ -420,9 +420,9 @@ static u16 get_request_type_usb(struct ft1000_device *ft1000dev) //--------------------------------------------------------------------------- static long get_request_value(struct ft1000_device *ft1000dev) { - ULONG value; + u32 value; u16 tempword; - ULONG status; + u32 status; struct ft1000_info *pft1000info = netdev_priv(ft1000dev->net); @@ -449,9 +449,9 @@ static long get_request_value(struct ft1000_device *ft1000dev) #if 0 static long get_request_value_usb(struct ft1000_device *ft1000dev) { - ULONG value; + u32 value; u16 tempword; - ULONG status; + u32 status; struct ft1000_info * pft1000info = netdev_priv(ft1000dev->net); if (pft1000info->usbboot == 2) { @@ -490,8 +490,8 @@ static long get_request_value_usb(struct ft1000_device *ft1000dev) //--------------------------------------------------------------------------- static void put_request_value(struct ft1000_device *ft1000dev, long lvalue) { - ULONG tempx; - ULONG status; + u32 tempx; + u32 status; tempx = ntohl(lvalue); status = fix_ft1000_write_dpram32(ft1000dev, DWNLD_MAG1_SIZE_LOC, (u8 *)&tempx); @@ -546,9 +546,9 @@ static u16 hdr_checksum(struct pseudo_hdr *pHdr) // Notes: // //--------------------------------------------------------------------------- -static ULONG write_blk (struct ft1000_device *ft1000dev, u16 **pUsFile, u8 **pUcFile, long word_length) +static u32 write_blk (struct ft1000_device *ft1000dev, u16 **pUsFile, u8 **pUcFile, long word_length) { - ULONG Status = STATUS_SUCCESS; + u32 Status = STATUS_SUCCESS; u16 dpram; long temp_word_length; int loopcnt, i, j; @@ -702,9 +702,9 @@ static void usb_dnld_complete (struct urb *urb) // Notes: // //--------------------------------------------------------------------------- -static ULONG write_blk_fifo (struct ft1000_device *ft1000dev, u16 **pUsFile, u8 **pUcFile, long word_length) +static u32 write_blk_fifo (struct ft1000_device *ft1000dev, u16 **pUsFile, u8 **pUcFile, long word_length) { - ULONG Status = STATUS_SUCCESS; + u32 Status = STATUS_SUCCESS; int byte_length; long aligncnt; @@ -770,7 +770,7 @@ static ULONG write_blk_fifo (struct ft1000_device *ft1000dev, u16 **pUsFile, u8 // Returns: status - return code //--------------------------------------------------------------------------- -u16 scram_dnldr(struct ft1000_device *ft1000dev, void *pFileStart, ULONG FileLength) +u16 scram_dnldr(struct ft1000_device *ft1000dev, void *pFileStart, u32 FileLength) { u16 Status = STATUS_SUCCESS; UINT uiState; @@ -795,8 +795,8 @@ u16 scram_dnldr(struct ft1000_device *ft1000dev, void *pFileStart, ULONG FileLe long loader_code_address, loader_code_size = 0; long run_address = 0, run_size = 0; - ULONG templong; - ULONG image_chksum = 0; + u32 templong; + u32 image_chksum = 0; u16 dpram = 0; u8 *pbuffer; @@ -1114,7 +1114,7 @@ u16 scram_dnldr(struct ft1000_device *ft1000dev, void *pFileStart, ULONG FileLe templong = temp; temp = (u16)(pDspImageInfoV6->version >> 16); templong |= (temp << 16); - if (templong == (ULONG)requested_version) + if (templong == (u32)requested_version) { bGoodVersion = TRUE; DEBUG("FT1000:download: bGoodVersion is TRUE\n"); @@ -1123,7 +1123,7 @@ u16 scram_dnldr(struct ft1000_device *ft1000dev, void *pFileStart, ULONG FileLe pCodeEnd = (u8 *)(pFileStart + pDspImageInfoV6->end_offset); run_address = pDspImageInfoV6->run_address; run_size = pDspImageInfoV6->image_size; - image_chksum = (ULONG)pDspImageInfoV6->checksum; + image_chksum = (u32)pDspImageInfoV6->checksum; break; } pDspImageInfoV6++; diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c index 709f8da12454..f97826d2acc0 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c @@ -594,7 +594,7 @@ int dsp_reload(struct ft1000_device *ft1000dev) { u16 status; u16 tempword; - ULONG templong; + u32 templong; struct ft1000_info *pft1000info; diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_usb.h b/drivers/staging/ft1000/ft1000-usb/ft1000_usb.h index bc0022325df2..64af71078789 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_usb.h +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_usb.h @@ -98,7 +98,6 @@ struct prov_record { /*end of Jim*/ #define DEBUG(args...) printk(KERN_INFO args) -#define ULONG u32 /* WTF ??? */ #define BOOLEAN u8 #define PCHAR u8 * #define UINT u32 @@ -572,7 +571,7 @@ extern size_t FileLength; extern int numofmsgbuf; int ft1000_close (struct net_device *dev); -u16 scram_dnldr(struct ft1000_device *ft1000dev, void *pFileStart, ULONG FileLength); +u16 scram_dnldr(struct ft1000_device *ft1000dev, void *pFileStart, u32 FileLength); extern struct list_head freercvpool; extern spinlock_t free_buff_lock; // lock to arbitrate free buffer list for receive command data -- cgit v1.2.3 From 81584137d8c97ab6bd87c2b4091f6105f600e66e Mon Sep 17 00:00:00 2001 From: Marek Belisko Date: Thu, 4 Nov 2010 07:37:13 +0100 Subject: staging: ft1000: Get rid of BOOLEAN typedef usage. Signed-off-by: Marek Belisko Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ft1000/ft1000-usb/ft1000_chdev.c | 2 +- drivers/staging/ft1000/ft1000-usb/ft1000_download.c | 2 +- drivers/staging/ft1000/ft1000-usb/ft1000_hw.c | 4 ++-- drivers/staging/ft1000/ft1000-usb/ft1000_usb.c | 2 +- drivers/staging/ft1000/ft1000-usb/ft1000_usb.h | 7 +++---- 5 files changed, 8 insertions(+), 9 deletions(-) diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_chdev.c b/drivers/staging/ft1000/ft1000-usb/ft1000_chdev.c index f6b2e919b56b..920ca52d6e4b 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_chdev.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_chdev.c @@ -64,7 +64,7 @@ spinlock_t free_buff_lock; int numofmsgbuf = 0; // Global variable to indicate that all provisioning data is sent to DSP -//BOOLEAN fProvComplete; +//bool fProvComplete; // // Table of entry-point routines for char device diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_download.c b/drivers/staging/ft1000/ft1000-usb/ft1000_download.c index 0a2b833bfb3e..11b7c203f098 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_download.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_download.c @@ -785,7 +785,7 @@ u16 scram_dnldr(struct ft1000_device *ft1000dev, void *pFileStart, u32 FileLeng struct dsp_file_hdr *pFileHdr5; struct dsp_image_info *pDspImageInfoV6 = NULL; long requested_version; - BOOLEAN bGoodVersion; + bool bGoodVersion; struct drv_msg *pMailBoxData; u16 *pUsData = NULL; u16 *pUsFile = NULL; diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c index f97826d2acc0..1a517dd8e7ad 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c @@ -491,7 +491,7 @@ u16 fix_ft1000_write_dpram32(struct ft1000_device *ft1000dev, u16 indx, u8 *buff // // Returns: None //----------------------------------------------------------------------- -static void card_reset_dsp (struct ft1000_device *ft1000dev, BOOLEAN value) +static void card_reset_dsp (struct ft1000_device *ft1000dev, bool value) { u16 status = STATUS_SUCCESS; u16 tempword; @@ -1479,7 +1479,7 @@ static int ft1000_chkcard (struct ft1000_device *dev) { // = 1 (successful) // //--------------------------------------------------------------------------- -static BOOLEAN ft1000_receive_cmd (struct ft1000_device *dev, u16 *pbuffer, int maxsz, u16 *pnxtph) { +static bool ft1000_receive_cmd (struct ft1000_device *dev, u16 *pbuffer, int maxsz, u16 *pnxtph) { u16 size, ret; u16 *ppseudohdr; int i; diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_usb.c b/drivers/staging/ft1000/ft1000-usb/ft1000_usb.c index 4e81bdd6902a..41bbe991f0de 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_usb.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_usb.c @@ -36,7 +36,7 @@ static struct usb_device_id id_table[] = { MODULE_DEVICE_TABLE(usb, id_table); -static BOOLEAN gPollingfailed = FALSE; +static bool gPollingfailed = FALSE; int ft1000_poll_thread(void *arg) { int ret = STATUS_SUCCESS; diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_usb.h b/drivers/staging/ft1000/ft1000-usb/ft1000_usb.h index 64af71078789..cf2c42ecdf35 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_usb.h +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_usb.h @@ -98,7 +98,6 @@ struct prov_record { /*end of Jim*/ #define DEBUG(args...) printk(KERN_INFO args) -#define BOOLEAN u8 #define PCHAR u8 * #define UINT u32 @@ -488,9 +487,9 @@ struct ft1000_info { unsigned char usbboot; unsigned short dspalive; u16 ASIC_ID; - BOOLEAN fProvComplete; - BOOLEAN fCondResetPend; - BOOLEAN fAppMsgPend; + bool fProvComplete; + bool fCondResetPend; + bool fAppMsgPend; char *pfwimg; int fwimgsz; u16 DrvErrNum; -- cgit v1.2.3 From c613f6f50f9d98015b8640f9aeff3b0c8e07548e Mon Sep 17 00:00:00 2001 From: Marek Belisko Date: Wed, 3 Nov 2010 11:19:54 +0100 Subject: staging: ft1000: Get rid of PCHAR typedef usage. Signed-off-by: Marek Belisko Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ft1000/ft1000-usb/ft1000_hw.c | 2 +- drivers/staging/ft1000/ft1000-usb/ft1000_usb.h | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c index 1a517dd8e7ad..b41884e60d07 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c @@ -726,7 +726,7 @@ static int ft1000_reset_card (struct net_device *dev) // Initialize DSP heartbeat area to ho ft1000_write_dpram16(ft1000dev, FT1000_MAG_HI_HO, ho_mag, FT1000_MAG_HI_HO_INDX); - ft1000_read_dpram16(ft1000dev, FT1000_MAG_HI_HO, (PCHAR)&tempword, FT1000_MAG_HI_HO_INDX); + ft1000_read_dpram16(ft1000dev, FT1000_MAG_HI_HO, (u8 *)&tempword, FT1000_MAG_HI_HO_INDX); DEBUG("ft1000_hw:ft1000_reset_card:hi_ho value = 0x%x\n", tempword); diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_usb.h b/drivers/staging/ft1000/ft1000-usb/ft1000_usb.h index cf2c42ecdf35..d1477e54f828 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_usb.h +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_usb.h @@ -98,7 +98,6 @@ struct prov_record { /*end of Jim*/ #define DEBUG(args...) printk(KERN_INFO args) -#define PCHAR u8 * #define UINT u32 #define FALSE 0 -- cgit v1.2.3 From e09f138e06d4f1ea63079e25bb55ee1dacff7933 Mon Sep 17 00:00:00 2001 From: Marek Belisko Date: Wed, 3 Nov 2010 11:19:55 +0100 Subject: staging: ft1000: Get rid of UINT typedef usage. Signed-off-by: Marek Belisko Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ft1000/ft1000-usb/ft1000_download.c | 6 +++--- drivers/staging/ft1000/ft1000-usb/ft1000_usb.h | 2 -- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_download.c b/drivers/staging/ft1000/ft1000-usb/ft1000_download.c index 11b7c203f098..e4905ad2badc 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_download.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_download.c @@ -773,7 +773,7 @@ static u32 write_blk_fifo (struct ft1000_device *ft1000dev, u16 **pUsFile, u8 ** u16 scram_dnldr(struct ft1000_device *ft1000dev, void *pFileStart, u32 FileLength) { u16 Status = STATUS_SUCCESS; - UINT uiState; + u32 uiState; u16 handshake; struct pseudo_hdr *pHdr; u16 usHdrLength; @@ -1181,14 +1181,14 @@ u16 scram_dnldr(struct ft1000_device *ft1000dev, void *pFileStart, u32 FileLeng // Get buffer for provisioning data pbuffer = kmalloc((usHdrLength + sizeof(struct pseudo_hdr)), GFP_ATOMIC); if (pbuffer) { - memcpy(pbuffer, (void *)pUcFile, (UINT)(usHdrLength + sizeof(struct pseudo_hdr))); + memcpy(pbuffer, (void *)pUcFile, (u32)(usHdrLength + sizeof(struct pseudo_hdr))); // link provisioning data pprov_record = kmalloc(sizeof(struct prov_record), GFP_ATOMIC); if (pprov_record) { pprov_record->pprov_data = pbuffer; list_add_tail (&pprov_record->list, &pft1000info->prov_list); // Move to next entry if available - pUcFile = (u8 *)((unsigned long)pUcFile + (UINT)((usHdrLength + 1) & 0xFFFFFFFE) + sizeof(struct pseudo_hdr)); + pUcFile = (u8 *)((unsigned long)pUcFile + (u32)((usHdrLength + 1) & 0xFFFFFFFE) + sizeof(struct pseudo_hdr)); if ( (unsigned long)(pUcFile) - (unsigned long)(pFileStart) >= (unsigned long)FileLength) { uiState = STATE_DONE_FILE; } diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_usb.h b/drivers/staging/ft1000/ft1000-usb/ft1000_usb.h index d1477e54f828..a07db26441f1 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_usb.h +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_usb.h @@ -98,8 +98,6 @@ struct prov_record { /*end of Jim*/ #define DEBUG(args...) printk(KERN_INFO args) -#define UINT u32 - #define FALSE 0 #define TRUE 1 -- cgit v1.2.3 From 5712dc7fc812d1bdbc5e634d389bc759d4e7550c Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Wed, 3 Nov 2010 10:59:02 +0100 Subject: staging: batman-adv: Use linux/etherdevice.h address helper functions Replace custom ethernet address check functions by calls to the helpers in linux/etherdevice.h In one case where the address was tested for broadcast and multicast address, the broadcast address check can be omitted as broadcast is also a multicast address. The patch is only compile-tested. Cc: Marek Lindner Cc: Simon Wunderlich Cc: Andrew Lunn Signed-off-by: Tobias Klauser Signed-off-by: Greg Kroah-Hartman --- drivers/staging/batman-adv/main.c | 12 +----------- drivers/staging/batman-adv/main.h | 3 +-- drivers/staging/batman-adv/routing.c | 16 ++++++++-------- drivers/staging/batman-adv/soft-interface.c | 2 +- drivers/staging/batman-adv/vis.c | 4 ++-- 5 files changed, 13 insertions(+), 24 deletions(-) diff --git a/drivers/staging/batman-adv/main.c b/drivers/staging/batman-adv/main.c index 0587940d2723..6ea64200ad16 100644 --- a/drivers/staging/batman-adv/main.c +++ b/drivers/staging/batman-adv/main.c @@ -149,7 +149,7 @@ void dec_module_count(void) int compare_orig(void *data1, void *data2) { - return (memcmp(data1, data2, ETH_ALEN) == 0 ? 1 : 0); + return (compare_ether_addr(data1, data2) == 0 ? 1 : 0); } /* hashfunction to choose an entry in a hash table of given size */ @@ -192,16 +192,6 @@ int is_my_mac(uint8_t *addr) } -int is_bcast(uint8_t *addr) -{ - return (addr[0] == (uint8_t)0xff) && (addr[1] == (uint8_t)0xff); -} - -int is_mcast(uint8_t *addr) -{ - return *addr & 0x01; -} - module_init(batman_init); module_exit(batman_exit); diff --git a/drivers/staging/batman-adv/main.h b/drivers/staging/batman-adv/main.h index 5e3f51681f5e..14d567d4911a 100644 --- a/drivers/staging/batman-adv/main.h +++ b/drivers/staging/batman-adv/main.h @@ -109,6 +109,7 @@ #include /* mutex */ #include /* needed by all modules */ #include /* netdevice */ +#include #include /* ethernet header */ #include /* poll_table */ #include /* kernel threads */ @@ -138,8 +139,6 @@ void dec_module_count(void); int compare_orig(void *data1, void *data2); int choose_orig(void *data, int32_t size); int is_my_mac(uint8_t *addr); -int is_bcast(uint8_t *addr); -int is_mcast(uint8_t *addr); #ifdef CONFIG_BATMAN_ADV_DEBUG int debug_log(struct bat_priv *bat_priv, char *fmt, ...); diff --git a/drivers/staging/batman-adv/routing.c b/drivers/staging/batman-adv/routing.c index 90102631330b..d42c16559dff 100644 --- a/drivers/staging/batman-adv/routing.c +++ b/drivers/staging/batman-adv/routing.c @@ -756,11 +756,11 @@ int recv_bat_packet(struct sk_buff *skb, struct batman_if *batman_if) ethhdr = (struct ethhdr *)skb_mac_header(skb); /* packet with broadcast indication but unicast recipient */ - if (!is_bcast(ethhdr->h_dest)) + if (!is_broadcast_ether_addr(ethhdr->h_dest)) return NET_RX_DROP; /* packet with broadcast sender address */ - if (is_bcast(ethhdr->h_source)) + if (is_broadcast_ether_addr(ethhdr->h_source)) return NET_RX_DROP; /* create a copy of the skb, if needed, to modify it. */ @@ -933,11 +933,11 @@ int recv_icmp_packet(struct sk_buff *skb, struct batman_if *recv_if) ethhdr = (struct ethhdr *)skb_mac_header(skb); /* packet with unicast indication but broadcast recipient */ - if (is_bcast(ethhdr->h_dest)) + if (is_broadcast_ether_addr(ethhdr->h_dest)) return NET_RX_DROP; /* packet with broadcast sender address */ - if (is_bcast(ethhdr->h_source)) + if (is_broadcast_ether_addr(ethhdr->h_source)) return NET_RX_DROP; /* not for me */ @@ -1107,11 +1107,11 @@ static int check_unicast_packet(struct sk_buff *skb, int hdr_size) ethhdr = (struct ethhdr *)skb_mac_header(skb); /* packet with unicast indication but broadcast recipient */ - if (is_bcast(ethhdr->h_dest)) + if (is_broadcast_ether_addr(ethhdr->h_dest)) return -1; /* packet with broadcast sender address */ - if (is_bcast(ethhdr->h_source)) + if (is_broadcast_ether_addr(ethhdr->h_source)) return -1; /* not for me */ @@ -1283,11 +1283,11 @@ int recv_bcast_packet(struct sk_buff *skb, struct batman_if *recv_if) ethhdr = (struct ethhdr *)skb_mac_header(skb); /* packet with broadcast indication but unicast recipient */ - if (!is_bcast(ethhdr->h_dest)) + if (!is_broadcast_ether_addr(ethhdr->h_dest)) return NET_RX_DROP; /* packet with broadcast sender address */ - if (is_bcast(ethhdr->h_source)) + if (is_broadcast_ether_addr(ethhdr->h_source)) return NET_RX_DROP; /* ignore broadcasts sent by myself */ diff --git a/drivers/staging/batman-adv/soft-interface.c b/drivers/staging/batman-adv/soft-interface.c index 3904db9ce7b1..820e14159dd3 100644 --- a/drivers/staging/batman-adv/soft-interface.c +++ b/drivers/staging/batman-adv/soft-interface.c @@ -140,7 +140,7 @@ int interface_tx(struct sk_buff *skb, struct net_device *soft_iface) hna_local_add(soft_iface, ethhdr->h_source); /* ethernet packet should be broadcasted */ - if (is_bcast(ethhdr->h_dest) || is_mcast(ethhdr->h_dest)) { + if (is_multicast_ether_addr(ethhdr->h_dest)) { if (!bat_priv->primary_if) goto dropped; diff --git a/drivers/staging/batman-adv/vis.c b/drivers/staging/batman-adv/vis.c index 4473cc8ed6b0..395f1109d606 100644 --- a/drivers/staging/batman-adv/vis.c +++ b/drivers/staging/batman-adv/vis.c @@ -469,7 +469,7 @@ void receive_client_update_packet(struct bat_priv *bat_priv, int are_target = 0; /* clients shall not broadcast. */ - if (is_bcast(vis_packet->target_orig)) + if (is_broadcast_ether_addr(vis_packet->target_orig)) return; /* Are we the target for this VIS packet? */ @@ -746,7 +746,7 @@ static void send_vis_packet(struct bat_priv *bat_priv, struct vis_info *info) ETH_ALEN); packet->ttl--; - if (is_bcast(packet->target_orig)) + if (is_broadcast_ether_addr(packet->target_orig)) broadcast_vis_packet(bat_priv, info); else unicast_vis_packet(bat_priv, info); -- cgit v1.2.3 From 391a169e99c789d59ef2a6b0cb80d1c6f63238dd Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Thu, 4 Nov 2010 22:27:42 +0100 Subject: pohmelfs: remove unneeded conditionals before calls to crypto_destroy_tfm wrappers. Hi, crypto_free_hash() and crypto_free_ablkcipher() are just wrappers around crypto_free_tfm() which is itself just a wrapper around crypto_destroy_tfm(). Passing crypto_destroy_tfm() a NULL pointer is valid, so there's no reason to check for NULL first. Removing the unneeded conditionals (which is what the patch does) brings us the benefit of having to execute a few fewer test/branch instructions and also reduces object code size slightly: before: text data bss dec hex filename 8630 112 3312 12054 2f16 drivers/staging/pohmelfs/crypto.o 0000000000000cbe : cbe: 55 push %rbp cbf: 48 89 e5 mov %rsp,%rbp cc2: 53 push %rbx cc3: 48 83 ec 08 sub $0x8,%rsp cc7: e8 00 00 00 00 callq ccc ccc: 48 ff 05 00 00 00 00 incq 0x0(%rip) # cd3 cd3: 48 89 fb mov %rdi,%rbx cd6: 48 8b 7f 20 mov 0x20(%rdi),%rdi cda: 48 85 ff test %rdi,%rdi cdd: 74 0c je ceb cdf: 48 ff 05 00 00 00 00 incq 0x0(%rip) # ce6 ce6: e8 58 fa ff ff callq 743 ceb: 48 8b 7b 28 mov 0x28(%rbx),%rdi cef: 48 85 ff test %rdi,%rdi cf2: 75 09 jne cfd cf4: 48 ff 05 00 00 00 00 incq 0x0(%rip) # cfb cfb: eb 16 jmp d13 cfd: 48 89 fe mov %rdi,%rsi d00: 48 ff 05 00 00 00 00 incq 0x0(%rip) # d07 d07: e8 00 00 00 00 callq d0c d0c: 48 ff 05 00 00 00 00 incq 0x0(%rip) # d13 d13: 48 8b 7b 18 mov 0x18(%rbx),%rdi d17: e8 00 00 00 00 callq d1c d1c: 48 ff 05 00 00 00 00 incq 0x0(%rip) # d23 d23: 5e pop %rsi d24: 5b pop %rbx d25: c9 leaveq d26: c3 retq after: text data bss dec hex filename 8604 112 3296 12012 2eec drivers/staging/pohmelfs/crypto.o 0000000000000cbe : cbe: 55 push %rbp cbf: 48 89 e5 mov %rsp,%rbp cc2: 53 push %rbx cc3: 48 83 ec 08 sub $0x8,%rsp cc7: e8 00 00 00 00 callq ccc ccc: 48 ff 05 00 00 00 00 incq 0x0(%rip) # cd3 cd3: 48 89 fb mov %rdi,%rbx cd6: 48 8b 7f 20 mov 0x20(%rdi),%rdi cda: e8 64 fa ff ff callq 743 cdf: 48 8b 7b 28 mov 0x28(%rbx),%rdi ce3: 48 ff 05 00 00 00 00 incq 0x0(%rip) # cea cea: 48 89 fe mov %rdi,%rsi ced: e8 00 00 00 00 callq cf2 cf2: 48 8b 7b 18 mov 0x18(%rbx),%rdi cf6: 48 ff 05 00 00 00 00 incq 0x0(%rip) # cfd cfd: e8 00 00 00 00 callq d02 d02: 48 ff 05 00 00 00 00 incq 0x0(%rip) # d09 d09: 5e pop %rsi d0a: 5b pop %rbx d0b: c9 leaveq d0c: c3 retq Signed-off-by: Jesper Juhl Acked-by: Evgeniy Polyakov Signed-off-by: Greg Kroah-Hartman --- drivers/staging/pohmelfs/crypto.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/staging/pohmelfs/crypto.c b/drivers/staging/pohmelfs/crypto.c index 2fdb3e01460d..6540864216c8 100644 --- a/drivers/staging/pohmelfs/crypto.c +++ b/drivers/staging/pohmelfs/crypto.c @@ -130,10 +130,8 @@ err_out_exit: void pohmelfs_crypto_engine_exit(struct pohmelfs_crypto_engine *e) { - if (e->hash) - crypto_free_hash(e->hash); - if (e->cipher) - crypto_free_ablkcipher(e->cipher); + crypto_free_hash(e->hash); + crypto_free_ablkcipher(e->cipher); kfree(e->data); } -- cgit v1.2.3 From ce36cedab3f865969653bf4360f7e364ab0937e4 Mon Sep 17 00:00:00 2001 From: Mike Thomas Date: Sun, 7 Nov 2010 19:56:40 +0000 Subject: staging/easycap: Remove obsolete routines The so-called bridger routine has proved unnecessary following general improvements elsewhere. The explain_() functions were a convenience during early development, but are unnecessary and inappropriate now. Signed-off-by: Mike Thomas Signed-off-by: Greg Kroah-Hartman --- drivers/staging/easycap/easycap.h | 36 +- drivers/staging/easycap/easycap_debug.h | 4 +- drivers/staging/easycap/easycap_ioctl.c | 695 ++--------------------------- drivers/staging/easycap/easycap_low.c | 23 - drivers/staging/easycap/easycap_main.c | 131 +----- drivers/staging/easycap/easycap_settings.c | 4 +- drivers/staging/easycap/easycap_sound.c | 9 +- drivers/staging/easycap/easycap_testcard.c | 290 ++++++------ 8 files changed, 198 insertions(+), 994 deletions(-) diff --git a/drivers/staging/easycap/easycap.h b/drivers/staging/easycap/easycap.h index f3c827eb0abe..9fb0f64d5477 100644 --- a/drivers/staging/easycap/easycap.h +++ b/drivers/staging/easycap/easycap.h @@ -42,12 +42,6 @@ #if (!defined(EASYCAP_H)) #define EASYCAP_H -#if defined(EASYCAP_DEBUG) -#if (9 < EASYCAP_DEBUG) -#error Debug levels 0 to 9 are okay.\ - To achieve higher levels, remove this trap manually from easycap.h -#endif -#endif /*EASYCAP_DEBUG*/ /*---------------------------------------------------------------------------*/ /* * THESE ARE FOR MAINTENANCE ONLY - NORMALLY UNDEFINED: @@ -56,21 +50,9 @@ #undef PREFER_NTSC #undef EASYCAP_TESTCARD #undef EASYCAP_TESTTONE -#undef LOCKFRAME #undef NOREADBACK #undef AUDIOTIME /*---------------------------------------------------------------------------*/ -/* - * - * DEFINE BRIDGER TO ACTIVATE THE ROUTINE FOR BRIDGING VIDEOTAPE DROPOUTS. - * - * *** UNDER DEVELOPMENT/TESTING - NOT READY YET!*** - * - */ -/*---------------------------------------------------------------------------*/ -#undef BRIDGER -/*---------------------------------------------------------------------------*/ - #include #include #include @@ -135,7 +117,7 @@ #define USB_EASYCAP_VENDOR_ID 0x05e1 #define USB_EASYCAP_PRODUCT_ID 0x0408 -#define EASYCAP_DRIVER_VERSION "0.8.21" +#define EASYCAP_DRIVER_VERSION "0.8.41" #define EASYCAP_DRIVER_DESCRIPTION "easycapdc60" #define USB_SKEL_MINOR_BASE 192 @@ -291,8 +273,6 @@ unsigned int audio_buffer_page_many; __s16 oldaudio; #endif /*UPSAMPLE*/ -struct easycap_format easycap_format[1 + SETTINGS_MANY]; - int ilk; bool microphone; @@ -307,10 +287,6 @@ struct usb_interface *pusb_interface; struct kref kref; -struct mutex mutex_mmap_video[FRAME_BUFFER_MANY]; -struct mutex mutex_timeval0; -struct mutex mutex_timeval1; - int queued[FRAME_BUFFER_MANY]; int done[FRAME_BUFFER_MANY]; @@ -347,8 +323,6 @@ int video_idle; int video_eof; int video_junk; -int fudge; - struct data_buffer video_isoc_buffer[VIDEO_ISOC_BUFFER_MANY]; struct data_buffer \ field_buffer[FIELD_BUFFER_MANY][(FIELD_BUFFER_SIZE/PAGE_SIZE)]; @@ -489,11 +463,7 @@ int kill_video_urbs(struct easycap *); int field2frame(struct easycap *); int redaub(struct easycap *, void *, void *, \ int, int, __u8, __u8, bool); -void debrief(struct easycap *); -void sayreadonly(struct easycap *); void easycap_testcard(struct easycap *, int); -int explain_ioctl(__u32); -int explain_cid(__u32); int fillin_formats(void); int adjust_standard(struct easycap *, v4l2_std_id); int adjust_format(struct easycap *, __u32, __u32, __u32, \ @@ -595,7 +565,7 @@ unsigned long long int remainder; #if defined(EASYCAP_DEBUG) #define JOT(n, format, args...) do { \ - if (n <= easycap_debug) { \ + if (n <= debug) { \ printk(KERN_DEBUG "easycap: %s: " format, __func__, ##args); \ } \ } while (0) @@ -603,8 +573,6 @@ unsigned long long int remainder; #define JOT(n, format, args...) do {} while (0) #endif /*EASYCAP_DEBUG*/ -#define POUT JOT(8, ":-(in file %s line %4i\n", __FILE__, __LINE__) - #define MICROSECONDS(X, Y) \ ((1000000*((long long int)(X.tv_sec - Y.tv_sec))) + \ (long long int)(X.tv_usec - Y.tv_usec)) diff --git a/drivers/staging/easycap/easycap_debug.h b/drivers/staging/easycap/easycap_debug.h index 1d10d7ea7d68..3e9b66a66076 100644 --- a/drivers/staging/easycap/easycap_debug.h +++ b/drivers/staging/easycap/easycap_debug.h @@ -1,6 +1,6 @@ /***************************************************************************** * * -* easycap_debug.h * +* debug.h * * * *****************************************************************************/ /* @@ -24,4 +24,4 @@ * */ /*****************************************************************************/ -extern int easycap_debug; +extern int debug; diff --git a/drivers/staging/easycap/easycap_ioctl.c b/drivers/staging/easycap/easycap_ioctl.c index 9a42ae02cd5d..5b038b8614d7 100644 --- a/drivers/staging/easycap/easycap_ioctl.c +++ b/drivers/staging/easycap/easycap_ioctl.c @@ -857,10 +857,8 @@ case VIDIOC_QUERYCAP: { &v4l2_capability.bus_info[0]); } if (0 != copy_to_user((void __user *)arg, &v4l2_capability, \ - sizeof(struct v4l2_capability))) { - POUT; + sizeof(struct v4l2_capability))) return -EFAULT; - } break; } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ @@ -871,10 +869,8 @@ case VIDIOC_ENUMINPUT: { JOT(8, "VIDIOC_ENUMINPUT\n"); if (0 != copy_from_user(&v4l2_input, (void __user *)arg, \ - sizeof(struct v4l2_input))) { - POUT; + sizeof(struct v4l2_input))) return -EFAULT; - } index = v4l2_input.index; memset(&v4l2_input, 0, sizeof(struct v4l2_input)); @@ -959,10 +955,8 @@ case VIDIOC_ENUMINPUT: { } if (0 != copy_to_user((void __user *)arg, &v4l2_input, \ - sizeof(struct v4l2_input))) { - POUT; + sizeof(struct v4l2_input))) return -EFAULT; - } break; } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ @@ -972,10 +966,8 @@ case VIDIOC_G_INPUT: { JOT(8, "VIDIOC_G_INPUT\n"); index = (__u32)peasycap->input; JOT(8, "user is told: %i\n", index); - if (0 != copy_to_user((void __user *)arg, &index, sizeof(__u32))) { - POUT; + if (0 != copy_to_user((void __user *)arg, &index, sizeof(__u32))) return -EFAULT; - } break; } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ @@ -985,10 +977,8 @@ case VIDIOC_S_INPUT: JOT(8, "VIDIOC_S_INPUT\n"); - if (0 != copy_from_user(&index, (void __user *)arg, sizeof(__u32))) { - POUT; + if (0 != copy_from_user(&index, (void __user *)arg, sizeof(__u32))) return -EFAULT; - } JOT(8, "user requests input %i\n", index); @@ -1019,10 +1009,8 @@ case VIDIOC_ENUMAUDOUT: { JOT(8, "VIDIOC_ENUMAUDOUT\n"); if (0 != copy_from_user(&v4l2_audioout, (void __user *)arg, \ - sizeof(struct v4l2_audioout))) { - POUT; + sizeof(struct v4l2_audioout))) return -EFAULT; - } if (0 != v4l2_audioout.index) return -EINVAL; @@ -1031,10 +1019,8 @@ case VIDIOC_ENUMAUDOUT: { strcpy(&v4l2_audioout.name[0], "Soundtrack"); if (0 != copy_to_user((void __user *)arg, &v4l2_audioout, \ - sizeof(struct v4l2_audioout))) { - POUT; + sizeof(struct v4l2_audioout))) return -EFAULT; - } break; } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ @@ -1045,10 +1031,8 @@ case VIDIOC_QUERYCTRL: { JOT(8, "VIDIOC_QUERYCTRL\n"); if (0 != copy_from_user(&v4l2_queryctrl, (void __user *)arg, \ - sizeof(struct v4l2_queryctrl))) { - POUT; + sizeof(struct v4l2_queryctrl))) return -EFAULT; - } i1 = 0; while (0xFFFFFFFF != easycap_control[i1].id) { @@ -1066,10 +1050,8 @@ case VIDIOC_QUERYCTRL: { return -EINVAL; } if (0 != copy_to_user((void __user *)arg, &v4l2_queryctrl, \ - sizeof(struct v4l2_queryctrl))) { - POUT; + sizeof(struct v4l2_queryctrl))) return -EFAULT; - } break; } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ @@ -1085,10 +1067,8 @@ case VIDIOC_G_CTRL: { JOT(8, "VIDIOC_G_CTRL\n"); if (0 != copy_from_user(&v4l2_control, (void __user *)arg, \ - sizeof(struct v4l2_control))) { - POUT; + sizeof(struct v4l2_control))) return -EFAULT; - } switch (v4l2_control.id) { case V4L2_CID_BRIGHTNESS: { @@ -1127,15 +1107,12 @@ case VIDIOC_G_CTRL: { default: { SAY("ERROR: unknown V4L2 control: 0x%08X=id\n", \ v4l2_control.id); - explain_cid(v4l2_control.id); return -EINVAL; } } if (0 != copy_to_user((void __user *)arg, &v4l2_control, \ - sizeof(struct v4l2_control))) { - POUT; + sizeof(struct v4l2_control))) return -EFAULT; - } break; } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ @@ -1151,10 +1128,8 @@ case VIDIOC_S_CTRL: JOT(8, "VIDIOC_S_CTRL\n"); if (0 != copy_from_user(&v4l2_control, (void __user *)arg, \ - sizeof(struct v4l2_control))) { - POUT; + sizeof(struct v4l2_control))) return -EFAULT; - } switch (v4l2_control.id) { case V4L2_CID_BRIGHTNESS: { @@ -1203,10 +1178,9 @@ case VIDIOC_S_CTRL: default: { SAY("ERROR: unknown V4L2 control: 0x%08X=id\n", \ v4l2_control.id); - explain_cid(v4l2_control.id); - return -EINVAL; - } + return -EINVAL; } + } break; } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ @@ -1222,10 +1196,8 @@ case VIDIOC_ENUM_FMT: { JOT(8, "VIDIOC_ENUM_FMT\n"); if (0 != copy_from_user(&v4l2_fmtdesc, (void __user *)arg, \ - sizeof(struct v4l2_fmtdesc))) { - POUT; + sizeof(struct v4l2_fmtdesc))) return -EFAULT; - } index = v4l2_fmtdesc.index; memset(&v4l2_fmtdesc, 0, sizeof(struct v4l2_fmtdesc)); @@ -1282,10 +1254,8 @@ case VIDIOC_ENUM_FMT: { } } if (0 != copy_to_user((void __user *)arg, &v4l2_fmtdesc, \ - sizeof(struct v4l2_fmtdesc))) { - POUT; + sizeof(struct v4l2_fmtdesc))) return -EFAULT; - } break; } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ @@ -1305,15 +1275,11 @@ case VIDIOC_G_FMT: { JOT(8, "VIDIOC_G_FMT\n"); if (0 != copy_from_user(&v4l2_format, (void __user *)arg, \ - sizeof(struct v4l2_format))) { - POUT; + sizeof(struct v4l2_format))) return -EFAULT; - } - if (v4l2_format.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { - POUT; + if (v4l2_format.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) return -EINVAL; - } memset(&v4l2_pix_format, 0, sizeof(struct v4l2_pix_format)); v4l2_format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; @@ -1324,10 +1290,8 @@ case VIDIOC_G_FMT: { &easycap_format[peasycap->format_offset].name[0]); if (0 != copy_to_user((void __user *)arg, &v4l2_format, \ - sizeof(struct v4l2_format))) { - POUT; + sizeof(struct v4l2_format))) return -EFAULT; - } break; } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ @@ -1347,10 +1311,8 @@ case VIDIOC_S_FMT: { } if (0 != copy_from_user(&v4l2_format, (void __user *)arg, \ - sizeof(struct v4l2_format))) { - POUT; + sizeof(struct v4l2_format))) return -EFAULT; - } best_format = adjust_format(peasycap, \ v4l2_format.fmt.pix.width, \ @@ -1371,10 +1333,8 @@ case VIDIOC_S_FMT: { JOT(8, "user is told: %s\n", &easycap_format[best_format].name[0]); if (0 != copy_to_user((void __user *)arg, &v4l2_format, \ - sizeof(struct v4l2_format))) { - POUT; + sizeof(struct v4l2_format))) return -EFAULT; - } break; } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ @@ -1384,10 +1344,8 @@ case VIDIOC_CROPCAP: { JOT(8, "VIDIOC_CROPCAP\n"); if (0 != copy_from_user(&v4l2_cropcap, (void __user *)arg, \ - sizeof(struct v4l2_cropcap))) { - POUT; + sizeof(struct v4l2_cropcap))) return -EFAULT; - } if (v4l2_cropcap.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) JOT(8, "v4l2_cropcap.type != V4L2_BUF_TYPE_VIDEO_CAPTURE\n"); @@ -1408,10 +1366,8 @@ case VIDIOC_CROPCAP: { JOT(8, "user is told: %ix%i\n", peasycap->width, peasycap->height); if (0 != copy_to_user((void __user *)arg, &v4l2_cropcap, \ - sizeof(struct v4l2_cropcap))) { - POUT; + sizeof(struct v4l2_cropcap))) return -EFAULT; - } break; } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ @@ -1444,10 +1400,8 @@ case VIDIOC_ENUMSTD: { JOT(8, "VIDIOC_ENUMSTD\n"); if (0 != copy_from_user(&v4l2_standard, (void __user *)arg, \ - sizeof(struct v4l2_standard))) { - POUT; + sizeof(struct v4l2_standard))) return -EFAULT; - } index = v4l2_standard.index; last3 = last2; last2 = last1; last1 = last0; last0 = index; @@ -1477,10 +1431,8 @@ case VIDIOC_ENUMSTD: { v4l2_standard.index = index; if (0 != copy_to_user((void __user *)arg, &v4l2_standard, \ - sizeof(struct v4l2_standard))) { - POUT; + sizeof(struct v4l2_standard))) return -EFAULT; - } break; } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ @@ -1491,10 +1443,8 @@ case VIDIOC_G_STD: { JOT(8, "VIDIOC_G_STD\n"); if (0 != copy_from_user(&std_id, (void __user *)arg, \ - sizeof(v4l2_std_id))) { - POUT; + sizeof(v4l2_std_id))) return -EFAULT; - } peasycap_standard = &easycap_standard[peasycap->standard_offset]; std_id = peasycap_standard->v4l2_standard.id; @@ -1503,10 +1453,8 @@ case VIDIOC_G_STD: { &peasycap_standard->v4l2_standard.name[0]); if (0 != copy_to_user((void __user *)arg, &std_id, \ - sizeof(v4l2_std_id))) { - POUT; + sizeof(v4l2_std_id))) return -EFAULT; - } break; } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ @@ -1517,10 +1465,8 @@ case VIDIOC_S_STD: { JOT(8, "VIDIOC_S_STD\n"); if (0 != copy_from_user(&std_id, (void __user *)arg, \ - sizeof(v4l2_std_id))) { - POUT; + sizeof(v4l2_std_id))) return -EFAULT; - } rc = adjust_standard(peasycap, std_id); if (0 > rc) { @@ -1537,17 +1483,13 @@ case VIDIOC_REQBUFS: { JOT(8, "VIDIOC_REQBUFS\n"); if (0 != copy_from_user(&v4l2_requestbuffers, (void __user *)arg, \ - sizeof(struct v4l2_requestbuffers))) { - POUT; + sizeof(struct v4l2_requestbuffers))) return -EFAULT; - } if (v4l2_requestbuffers.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) return -EINVAL; - if (v4l2_requestbuffers.memory != V4L2_MEMORY_MMAP) { - POUT; + if (v4l2_requestbuffers.memory != V4L2_MEMORY_MMAP) return -EINVAL; - } nbuffers = v4l2_requestbuffers.count; JOT(8, " User requests %i buffers ...\n", nbuffers); if (nbuffers < 2) @@ -1565,10 +1507,8 @@ case VIDIOC_REQBUFS: { peasycap->frame_buffer_many = nbuffers; if (0 != copy_to_user((void __user *)arg, &v4l2_requestbuffers, \ - sizeof(struct v4l2_requestbuffers))) { - POUT; + sizeof(struct v4l2_requestbuffers))) return -EFAULT; - } break; } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ @@ -1585,10 +1525,8 @@ case VIDIOC_QUERYBUF: { } if (0 != copy_from_user(&v4l2_buffer, (void __user *)arg, \ - sizeof(struct v4l2_buffer))) { - POUT; + sizeof(struct v4l2_buffer))) return -EFAULT; - } if (v4l2_buffer.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) return -EINVAL; @@ -1620,10 +1558,8 @@ case VIDIOC_QUERYBUF: { JOT(16, " %10i=length\n", v4l2_buffer.length); if (0 != copy_to_user((void __user *)arg, &v4l2_buffer, \ - sizeof(struct v4l2_buffer))) { - POUT; + sizeof(struct v4l2_buffer))) return -EFAULT; - } break; } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ @@ -1633,10 +1569,8 @@ case VIDIOC_QBUF: { JOT(8, "VIDIOC_QBUF\n"); if (0 != copy_from_user(&v4l2_buffer, (void __user *)arg, \ - sizeof(struct v4l2_buffer))) { - POUT; + sizeof(struct v4l2_buffer))) return -EFAULT; - } if (v4l2_buffer.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) return -EINVAL; @@ -1651,10 +1585,8 @@ case VIDIOC_QBUF: { peasycap->queued[v4l2_buffer.index] = V4L2_BUF_FLAG_QUEUED; if (0 != copy_to_user((void __user *)arg, &v4l2_buffer, \ - sizeof(struct v4l2_buffer))) { - POUT; + sizeof(struct v4l2_buffer))) return -EFAULT; - } JOT(8, "..... user queueing frame buffer %i\n", \ (int)v4l2_buffer.index); @@ -1687,10 +1619,8 @@ case VIDIOC_DQBUF: } if (0 != copy_from_user(&v4l2_buffer, (void __user *)arg, \ - sizeof(struct v4l2_buffer))) { - POUT; + sizeof(struct v4l2_buffer))) return -EFAULT; - } if (v4l2_buffer.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) return -EINVAL; @@ -1752,17 +1682,10 @@ case VIDIOC_DQBUF: timeval1 = timeval; timeval2 = timeval; dnbydt = 192000; - - if (mutex_lock_interruptible(&(peasycap->mutex_timeval0))) - return -ERESTARTSYS; peasycap->timeval0 = timeval0; - mutex_unlock(&(peasycap->mutex_timeval0)); } else { - if (mutex_lock_interruptible(&(peasycap->mutex_timeval1))) - return -ERESTARTSYS; dnbydt = peasycap->dnbydt; timeval1 = peasycap->timeval1; - mutex_unlock(&(peasycap->mutex_timeval1)); above = dnbydt * MICROSECONDS(timeval, timeval1); below = 192000; sdr = signed_div(above, below); @@ -1807,10 +1730,8 @@ case VIDIOC_DQBUF: JOT(16, " %10i=length\n", v4l2_buffer.length); if (0 != copy_to_user((void __user *)arg, &v4l2_buffer, \ - sizeof(struct v4l2_buffer))) { - POUT; + sizeof(struct v4l2_buffer))) return -EFAULT; - } JOT(8, "..... user is offered frame buffer %i\n", \ peasycap->frame_read); @@ -1879,15 +1800,11 @@ case VIDIOC_G_PARM: { JOT(8, "VIDIOC_G_PARM\n"); if (0 != copy_from_user(&v4l2_streamparm, (void __user *)arg, \ - sizeof(struct v4l2_streamparm))) { - POUT; + sizeof(struct v4l2_streamparm))) return -EFAULT; - } - if (v4l2_streamparm.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { - POUT; + if (v4l2_streamparm.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) return -EINVAL; - } v4l2_streamparm.parm.capture.capability = 0; v4l2_streamparm.parm.capture.capturemode = 0; v4l2_streamparm.parm.capture.timeperframe.numerator = 1; @@ -1895,10 +1812,8 @@ case VIDIOC_G_PARM: { v4l2_streamparm.parm.capture.readbuffers = peasycap->frame_buffer_many; v4l2_streamparm.parm.capture.extendedmode = 0; if (0 != copy_to_user((void __user *)arg, &v4l2_streamparm, \ - sizeof(struct v4l2_streamparm))) { - POUT; + sizeof(struct v4l2_streamparm))) return -EFAULT; - } break; } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ @@ -1941,8 +1856,6 @@ case VIDIOC_S_FREQUENCY: { /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ default: { JOT(8, "ERROR: unrecognized V4L2 IOCTL command: 0x%08X\n", cmd); - explain_ioctl(cmd); - POUT; return -ENOIOCTLCMD; } } @@ -2147,7 +2060,6 @@ case SNDCTL_DSP_GETISPACE: { } default: { JOT(8, "ERROR: unrecognized DSP IOCTL command: 0x%08X\n", cmd); - POUT; return -ENOIOCTLCMD; } } @@ -2165,531 +2077,4 @@ long easysnd_ioctl(struct file *file, unsigned int cmd, unsigned long arg) return ret; } - -/*****************************************************************************/ -int explain_ioctl(__u32 wot) -{ -int k; -/*---------------------------------------------------------------------------*/ -/* - * THE DATA FOR THE ARRAY mess BELOW WERE CONSTRUCTED BY RUNNING THE FOLLOWING - * SHELL SCRIPT: - * # - * cat /usr/src/linux-headers-`uname -r`/include/linux/videodev2.h | \ - * grep "^#define VIDIOC_" - | grep -v "_OLD" - | \ - * sed -e "s,_IO.*$,,;p" | sed -e "N;s,\n,, " | \ - * sed -e "s/^#define / {/;s/#define /, \"/;s/$/\"},/" | \ - * sed -e "s, ,,g;s, ,,g" >ioctl.tmp - * echo "{0xFFFFFFFF,\"\"}" >>ioctl.tmp - * exit 0 - * # - * AND REINSTATING THE EXCISED "_OLD" CASES WERE LATER MANUALLY. - * - * THE DATA FOR THE ARRAY mess1 BELOW WERE CONSTRUCTED BY RUNNING THE FOLLOWING - * SHELL SCRIPT: - * cat /usr/src/linux-headers-`uname -r`/include/linux/videodev.h | \ - * grep "^#define VIDIOC" - | grep -v "_OLD" - | \ - * sed -e "s,_IO.*$,,;p" | sed -e "N;s,\n,, " | \ - * sed -e "s/^#define / {/;s/#define /, \"/;s/$/\"},/" | \ - * sed -e "s, ,,g;s, ,,g" >ioctl.tmp - * echo "{0xFFFFFFFF,\"\"}" >>ioctl.tmp - * exit 0 - * # - */ -/*---------------------------------------------------------------------------*/ -static struct mess { - __u32 command; - char name[64]; -} mess[] = { -#if defined(VIDIOC_QUERYCAP) -{VIDIOC_QUERYCAP, "VIDIOC_QUERYCAP"}, -#endif -#if defined(VIDIOC_RESERVED) -{VIDIOC_RESERVED, "VIDIOC_RESERVED"}, -#endif -#if defined(VIDIOC_ENUM_FMT) -{VIDIOC_ENUM_FMT, "VIDIOC_ENUM_FMT"}, -#endif -#if defined(VIDIOC_G_FMT) -{VIDIOC_G_FMT, "VIDIOC_G_FMT"}, -#endif -#if defined(VIDIOC_S_FMT) -{VIDIOC_S_FMT, "VIDIOC_S_FMT"}, -#endif -#if defined(VIDIOC_REQBUFS) -{VIDIOC_REQBUFS, "VIDIOC_REQBUFS"}, -#endif -#if defined(VIDIOC_QUERYBUF) -{VIDIOC_QUERYBUF, "VIDIOC_QUERYBUF"}, -#endif -#if defined(VIDIOC_G_FBUF) -{VIDIOC_G_FBUF, "VIDIOC_G_FBUF"}, -#endif -#if defined(VIDIOC_S_FBUF) -{VIDIOC_S_FBUF, "VIDIOC_S_FBUF"}, -#endif -#if defined(VIDIOC_OVERLAY) -{VIDIOC_OVERLAY, "VIDIOC_OVERLAY"}, -#endif -#if defined(VIDIOC_QBUF) -{VIDIOC_QBUF, "VIDIOC_QBUF"}, -#endif -#if defined(VIDIOC_DQBUF) -{VIDIOC_DQBUF, "VIDIOC_DQBUF"}, -#endif -#if defined(VIDIOC_STREAMON) -{VIDIOC_STREAMON, "VIDIOC_STREAMON"}, -#endif -#if defined(VIDIOC_STREAMOFF) -{VIDIOC_STREAMOFF, "VIDIOC_STREAMOFF"}, -#endif -#if defined(VIDIOC_G_PARM) -{VIDIOC_G_PARM, "VIDIOC_G_PARM"}, -#endif -#if defined(VIDIOC_S_PARM) -{VIDIOC_S_PARM, "VIDIOC_S_PARM"}, -#endif -#if defined(VIDIOC_G_STD) -{VIDIOC_G_STD, "VIDIOC_G_STD"}, -#endif -#if defined(VIDIOC_S_STD) -{VIDIOC_S_STD, "VIDIOC_S_STD"}, -#endif -#if defined(VIDIOC_ENUMSTD) -{VIDIOC_ENUMSTD, "VIDIOC_ENUMSTD"}, -#endif -#if defined(VIDIOC_ENUMINPUT) -{VIDIOC_ENUMINPUT, "VIDIOC_ENUMINPUT"}, -#endif -#if defined(VIDIOC_G_CTRL) -{VIDIOC_G_CTRL, "VIDIOC_G_CTRL"}, -#endif -#if defined(VIDIOC_S_CTRL) -{VIDIOC_S_CTRL, "VIDIOC_S_CTRL"}, -#endif -#if defined(VIDIOC_G_TUNER) -{VIDIOC_G_TUNER, "VIDIOC_G_TUNER"}, -#endif -#if defined(VIDIOC_S_TUNER) -{VIDIOC_S_TUNER, "VIDIOC_S_TUNER"}, -#endif -#if defined(VIDIOC_G_AUDIO) -{VIDIOC_G_AUDIO, "VIDIOC_G_AUDIO"}, -#endif -#if defined(VIDIOC_S_AUDIO) -{VIDIOC_S_AUDIO, "VIDIOC_S_AUDIO"}, -#endif -#if defined(VIDIOC_QUERYCTRL) -{VIDIOC_QUERYCTRL, "VIDIOC_QUERYCTRL"}, -#endif -#if defined(VIDIOC_QUERYMENU) -{VIDIOC_QUERYMENU, "VIDIOC_QUERYMENU"}, -#endif -#if defined(VIDIOC_G_INPUT) -{VIDIOC_G_INPUT, "VIDIOC_G_INPUT"}, -#endif -#if defined(VIDIOC_S_INPUT) -{VIDIOC_S_INPUT, "VIDIOC_S_INPUT"}, -#endif -#if defined(VIDIOC_G_OUTPUT) -{VIDIOC_G_OUTPUT, "VIDIOC_G_OUTPUT"}, -#endif -#if defined(VIDIOC_S_OUTPUT) -{VIDIOC_S_OUTPUT, "VIDIOC_S_OUTPUT"}, -#endif -#if defined(VIDIOC_ENUMOUTPUT) -{VIDIOC_ENUMOUTPUT, "VIDIOC_ENUMOUTPUT"}, -#endif -#if defined(VIDIOC_G_AUDOUT) -{VIDIOC_G_AUDOUT, "VIDIOC_G_AUDOUT"}, -#endif -#if defined(VIDIOC_S_AUDOUT) -{VIDIOC_S_AUDOUT, "VIDIOC_S_AUDOUT"}, -#endif -#if defined(VIDIOC_G_MODULATOR) -{VIDIOC_G_MODULATOR, "VIDIOC_G_MODULATOR"}, -#endif -#if defined(VIDIOC_S_MODULATOR) -{VIDIOC_S_MODULATOR, "VIDIOC_S_MODULATOR"}, -#endif -#if defined(VIDIOC_G_FREQUENCY) -{VIDIOC_G_FREQUENCY, "VIDIOC_G_FREQUENCY"}, -#endif -#if defined(VIDIOC_S_FREQUENCY) -{VIDIOC_S_FREQUENCY, "VIDIOC_S_FREQUENCY"}, -#endif -#if defined(VIDIOC_CROPCAP) -{VIDIOC_CROPCAP, "VIDIOC_CROPCAP"}, -#endif -#if defined(VIDIOC_G_CROP) -{VIDIOC_G_CROP, "VIDIOC_G_CROP"}, -#endif -#if defined(VIDIOC_S_CROP) -{VIDIOC_S_CROP, "VIDIOC_S_CROP"}, -#endif -#if defined(VIDIOC_G_JPEGCOMP) -{VIDIOC_G_JPEGCOMP, "VIDIOC_G_JPEGCOMP"}, -#endif -#if defined(VIDIOC_S_JPEGCOMP) -{VIDIOC_S_JPEGCOMP, "VIDIOC_S_JPEGCOMP"}, -#endif -#if defined(VIDIOC_QUERYSTD) -{VIDIOC_QUERYSTD, "VIDIOC_QUERYSTD"}, -#endif -#if defined(VIDIOC_TRY_FMT) -{VIDIOC_TRY_FMT, "VIDIOC_TRY_FMT"}, -#endif -#if defined(VIDIOC_ENUMAUDIO) -{VIDIOC_ENUMAUDIO, "VIDIOC_ENUMAUDIO"}, -#endif -#if defined(VIDIOC_ENUMAUDOUT) -{VIDIOC_ENUMAUDOUT, "VIDIOC_ENUMAUDOUT"}, -#endif -#if defined(VIDIOC_G_PRIORITY) -{VIDIOC_G_PRIORITY, "VIDIOC_G_PRIORITY"}, -#endif -#if defined(VIDIOC_S_PRIORITY) -{VIDIOC_S_PRIORITY, "VIDIOC_S_PRIORITY"}, -#endif -#if defined(VIDIOC_G_SLICED_VBI_CAP) -{VIDIOC_G_SLICED_VBI_CAP, "VIDIOC_G_SLICED_VBI_CAP"}, -#endif -#if defined(VIDIOC_LOG_STATUS) -{VIDIOC_LOG_STATUS, "VIDIOC_LOG_STATUS"}, -#endif -#if defined(VIDIOC_G_EXT_CTRLS) -{VIDIOC_G_EXT_CTRLS, "VIDIOC_G_EXT_CTRLS"}, -#endif -#if defined(VIDIOC_S_EXT_CTRLS) -{VIDIOC_S_EXT_CTRLS, "VIDIOC_S_EXT_CTRLS"}, -#endif -#if defined(VIDIOC_TRY_EXT_CTRLS) -{VIDIOC_TRY_EXT_CTRLS, "VIDIOC_TRY_EXT_CTRLS"}, -#endif -#if defined(VIDIOC_ENUM_FRAMESIZES) -{VIDIOC_ENUM_FRAMESIZES, "VIDIOC_ENUM_FRAMESIZES"}, -#endif -#if defined(VIDIOC_ENUM_FRAMEINTERVALS) -{VIDIOC_ENUM_FRAMEINTERVALS, "VIDIOC_ENUM_FRAMEINTERVALS"}, -#endif -#if defined(VIDIOC_G_ENC_INDEX) -{VIDIOC_G_ENC_INDEX, "VIDIOC_G_ENC_INDEX"}, -#endif -#if defined(VIDIOC_ENCODER_CMD) -{VIDIOC_ENCODER_CMD, "VIDIOC_ENCODER_CMD"}, -#endif -#if defined(VIDIOC_TRY_ENCODER_CMD) -{VIDIOC_TRY_ENCODER_CMD, "VIDIOC_TRY_ENCODER_CMD"}, -#endif -#if defined(VIDIOC_G_CHIP_IDENT) -{VIDIOC_G_CHIP_IDENT, "VIDIOC_G_CHIP_IDENT"}, -#endif - -#if defined(VIDIOC_OVERLAY_OLD) -{VIDIOC_OVERLAY_OLD, "VIDIOC_OVERLAY_OLD"}, -#endif -#if defined(VIDIOC_S_PARM_OLD) -{VIDIOC_S_PARM_OLD, "VIDIOC_S_PARM_OLD"}, -#endif -#if defined(VIDIOC_S_CTRL_OLD) -{VIDIOC_S_CTRL_OLD, "VIDIOC_S_CTRL_OLD"}, -#endif -#if defined(VIDIOC_G_AUDIO_OLD) -{VIDIOC_G_AUDIO_OLD, "VIDIOC_G_AUDIO_OLD"}, -#endif -#if defined(VIDIOC_G_AUDOUT_OLD) -{VIDIOC_G_AUDOUT_OLD, "VIDIOC_G_AUDOUT_OLD"}, -#endif -#if defined(VIDIOC_CROPCAP_OLD) -{VIDIOC_CROPCAP_OLD, "VIDIOC_CROPCAP_OLD"}, -#endif -{0xFFFFFFFF, ""} -}; - -static struct mess mess1[] = \ -{ -#if defined(VIDIOCGCAP) -{VIDIOCGCAP, "VIDIOCGCAP"}, -#endif -#if defined(VIDIOCGCHAN) -{VIDIOCGCHAN, "VIDIOCGCHAN"}, -#endif -#if defined(VIDIOCSCHAN) -{VIDIOCSCHAN, "VIDIOCSCHAN"}, -#endif -#if defined(VIDIOCGTUNER) -{VIDIOCGTUNER, "VIDIOCGTUNER"}, -#endif -#if defined(VIDIOCSTUNER) -{VIDIOCSTUNER, "VIDIOCSTUNER"}, -#endif -#if defined(VIDIOCGPICT) -{VIDIOCGPICT, "VIDIOCGPICT"}, -#endif -#if defined(VIDIOCSPICT) -{VIDIOCSPICT, "VIDIOCSPICT"}, -#endif -#if defined(VIDIOCCAPTURE) -{VIDIOCCAPTURE, "VIDIOCCAPTURE"}, -#endif -#if defined(VIDIOCGWIN) -{VIDIOCGWIN, "VIDIOCGWIN"}, -#endif -#if defined(VIDIOCSWIN) -{VIDIOCSWIN, "VIDIOCSWIN"}, -#endif -#if defined(VIDIOCGFBUF) -{VIDIOCGFBUF, "VIDIOCGFBUF"}, -#endif -#if defined(VIDIOCSFBUF) -{VIDIOCSFBUF, "VIDIOCSFBUF"}, -#endif -#if defined(VIDIOCKEY) -{VIDIOCKEY, "VIDIOCKEY"}, -#endif -#if defined(VIDIOCGFREQ) -{VIDIOCGFREQ, "VIDIOCGFREQ"}, -#endif -#if defined(VIDIOCSFREQ) -{VIDIOCSFREQ, "VIDIOCSFREQ"}, -#endif -#if defined(VIDIOCGAUDIO) -{VIDIOCGAUDIO, "VIDIOCGAUDIO"}, -#endif -#if defined(VIDIOCSAUDIO) -{VIDIOCSAUDIO, "VIDIOCSAUDIO"}, -#endif -#if defined(VIDIOCSYNC) -{VIDIOCSYNC, "VIDIOCSYNC"}, -#endif -#if defined(VIDIOCMCAPTURE) -{VIDIOCMCAPTURE, "VIDIOCMCAPTURE"}, -#endif -#if defined(VIDIOCGMBUF) -{VIDIOCGMBUF, "VIDIOCGMBUF"}, -#endif -#if defined(VIDIOCGUNIT) -{VIDIOCGUNIT, "VIDIOCGUNIT"}, -#endif -#if defined(VIDIOCGCAPTURE) -{VIDIOCGCAPTURE, "VIDIOCGCAPTURE"}, -#endif -#if defined(VIDIOCSCAPTURE) -{VIDIOCSCAPTURE, "VIDIOCSCAPTURE"}, -#endif -#if defined(VIDIOCSPLAYMODE) -{VIDIOCSPLAYMODE, "VIDIOCSPLAYMODE"}, -#endif -#if defined(VIDIOCSWRITEMODE) -{VIDIOCSWRITEMODE, "VIDIOCSWRITEMODE"}, -#endif -#if defined(VIDIOCGPLAYINFO) -{VIDIOCGPLAYINFO, "VIDIOCGPLAYINFO"}, -#endif -#if defined(VIDIOCSMICROCODE) -{VIDIOCSMICROCODE, "VIDIOCSMICROCODE"}, -#endif -{0xFFFFFFFF, ""} -}; - -k = 0; -while (mess[k].name[0]) { - if (wot == mess[k].command) { - JOT(8, "ioctl 0x%08X is %s\n", \ - mess[k].command, &mess[k].name[0]); - return 0; - } - k++; -} -JOT(8, "ioctl 0x%08X is not in videodev2.h\n", wot); - -k = 0; -while (mess1[k].name[0]) { - if (wot == mess1[k].command) { - JOT(8, "ioctl 0x%08X is %s (V4L1)\n", \ - mess1[k].command, &mess1[k].name[0]); - return 0; - } - k++; -} -JOT(8, "ioctl 0x%08X is not in videodev.h\n", wot); -return -1; -} -/*****************************************************************************/ -int explain_cid(__u32 wot) -{ -int k; -/*---------------------------------------------------------------------------*/ -/* - * THE DATA FOR THE ARRAY mess BELOW WERE CONSTRUCTED BY RUNNING THE FOLLOWING - * SHELL SCRIPT: - * # - * cat /usr/src/linux-headers-`uname -r`/include/linux/videodev2.h | \ - * grep "^#define V4L2_CID_" | \ - * sed -e "s,(.*$,,;p" | sed -e "N;s,\n,, " | \ - * sed -e "s/^#define / {/;s/#define /, \"/;s/$/\"},/" | \ - * sed -e "s, ,,g;s, ,,g" | grep -v "_BASE" | grep -v "MPEG" >cid.tmp - * echo "{0xFFFFFFFF,\"\"}" >>cid.tmp - * exit 0 - * # - */ -/*---------------------------------------------------------------------------*/ -static struct mess -{ -__u32 command; -char name[64]; -} mess[] = { -#if defined(V4L2_CID_USER_CLASS) -{V4L2_CID_USER_CLASS, "V4L2_CID_USER_CLASS"}, -#endif -#if defined(V4L2_CID_BRIGHTNESS) -{V4L2_CID_BRIGHTNESS, "V4L2_CID_BRIGHTNESS"}, -#endif -#if defined(V4L2_CID_CONTRAST) -{V4L2_CID_CONTRAST, "V4L2_CID_CONTRAST"}, -#endif -#if defined(V4L2_CID_SATURATION) -{V4L2_CID_SATURATION, "V4L2_CID_SATURATION"}, -#endif -#if defined(V4L2_CID_HUE) -{V4L2_CID_HUE, "V4L2_CID_HUE"}, -#endif -#if defined(V4L2_CID_AUDIO_VOLUME) -{V4L2_CID_AUDIO_VOLUME, "V4L2_CID_AUDIO_VOLUME"}, -#endif -#if defined(V4L2_CID_AUDIO_BALANCE) -{V4L2_CID_AUDIO_BALANCE, "V4L2_CID_AUDIO_BALANCE"}, -#endif -#if defined(V4L2_CID_AUDIO_BASS) -{V4L2_CID_AUDIO_BASS, "V4L2_CID_AUDIO_BASS"}, -#endif -#if defined(V4L2_CID_AUDIO_TREBLE) -{V4L2_CID_AUDIO_TREBLE, "V4L2_CID_AUDIO_TREBLE"}, -#endif -#if defined(V4L2_CID_AUDIO_MUTE) -{V4L2_CID_AUDIO_MUTE, "V4L2_CID_AUDIO_MUTE"}, -#endif -#if defined(V4L2_CID_AUDIO_LOUDNESS) -{V4L2_CID_AUDIO_LOUDNESS, "V4L2_CID_AUDIO_LOUDNESS"}, -#endif -#if defined(V4L2_CID_BLACK_LEVEL) -{V4L2_CID_BLACK_LEVEL, "V4L2_CID_BLACK_LEVEL"}, -#endif -#if defined(V4L2_CID_AUTO_WHITE_BALANCE) -{V4L2_CID_AUTO_WHITE_BALANCE, "V4L2_CID_AUTO_WHITE_BALANCE"}, -#endif -#if defined(V4L2_CID_DO_WHITE_BALANCE) -{V4L2_CID_DO_WHITE_BALANCE, "V4L2_CID_DO_WHITE_BALANCE"}, -#endif -#if defined(V4L2_CID_RED_BALANCE) -{V4L2_CID_RED_BALANCE, "V4L2_CID_RED_BALANCE"}, -#endif -#if defined(V4L2_CID_BLUE_BALANCE) -{V4L2_CID_BLUE_BALANCE, "V4L2_CID_BLUE_BALANCE"}, -#endif -#if defined(V4L2_CID_GAMMA) -{V4L2_CID_GAMMA, "V4L2_CID_GAMMA"}, -#endif -#if defined(V4L2_CID_WHITENESS) -{V4L2_CID_WHITENESS, "V4L2_CID_WHITENESS"}, -#endif -#if defined(V4L2_CID_EXPOSURE) -{V4L2_CID_EXPOSURE, "V4L2_CID_EXPOSURE"}, -#endif -#if defined(V4L2_CID_AUTOGAIN) -{V4L2_CID_AUTOGAIN, "V4L2_CID_AUTOGAIN"}, -#endif -#if defined(V4L2_CID_GAIN) -{V4L2_CID_GAIN, "V4L2_CID_GAIN"}, -#endif -#if defined(V4L2_CID_HFLIP) -{V4L2_CID_HFLIP, "V4L2_CID_HFLIP"}, -#endif -#if defined(V4L2_CID_VFLIP) -{V4L2_CID_VFLIP, "V4L2_CID_VFLIP"}, -#endif -#if defined(V4L2_CID_HCENTER) -{V4L2_CID_HCENTER, "V4L2_CID_HCENTER"}, -#endif -#if defined(V4L2_CID_VCENTER) -{V4L2_CID_VCENTER, "V4L2_CID_VCENTER"}, -#endif -#if defined(V4L2_CID_POWER_LINE_FREQUENCY) -{V4L2_CID_POWER_LINE_FREQUENCY, "V4L2_CID_POWER_LINE_FREQUENCY"}, -#endif -#if defined(V4L2_CID_HUE_AUTO) -{V4L2_CID_HUE_AUTO, "V4L2_CID_HUE_AUTO"}, -#endif -#if defined(V4L2_CID_WHITE_BALANCE_TEMPERATURE) -{V4L2_CID_WHITE_BALANCE_TEMPERATURE, "V4L2_CID_WHITE_BALANCE_TEMPERATURE"}, -#endif -#if defined(V4L2_CID_SHARPNESS) -{V4L2_CID_SHARPNESS, "V4L2_CID_SHARPNESS"}, -#endif -#if defined(V4L2_CID_BACKLIGHT_COMPENSATION) -{V4L2_CID_BACKLIGHT_COMPENSATION, "V4L2_CID_BACKLIGHT_COMPENSATION"}, -#endif -#if defined(V4L2_CID_CHROMA_AGC) -{V4L2_CID_CHROMA_AGC, "V4L2_CID_CHROMA_AGC"}, -#endif -#if defined(V4L2_CID_COLOR_KILLER) -{V4L2_CID_COLOR_KILLER, "V4L2_CID_COLOR_KILLER"}, -#endif -#if defined(V4L2_CID_LASTP1) -{V4L2_CID_LASTP1, "V4L2_CID_LASTP1"}, -#endif -#if defined(V4L2_CID_CAMERA_CLASS) -{V4L2_CID_CAMERA_CLASS, "V4L2_CID_CAMERA_CLASS"}, -#endif -#if defined(V4L2_CID_EXPOSURE_AUTO) -{V4L2_CID_EXPOSURE_AUTO, "V4L2_CID_EXPOSURE_AUTO"}, -#endif -#if defined(V4L2_CID_EXPOSURE_ABSOLUTE) -{V4L2_CID_EXPOSURE_ABSOLUTE, "V4L2_CID_EXPOSURE_ABSOLUTE"}, -#endif -#if defined(V4L2_CID_EXPOSURE_AUTO_PRIORITY) -{V4L2_CID_EXPOSURE_AUTO_PRIORITY, "V4L2_CID_EXPOSURE_AUTO_PRIORITY"}, -#endif -#if defined(V4L2_CID_PAN_RELATIVE) -{V4L2_CID_PAN_RELATIVE, "V4L2_CID_PAN_RELATIVE"}, -#endif -#if defined(V4L2_CID_TILT_RELATIVE) -{V4L2_CID_TILT_RELATIVE, "V4L2_CID_TILT_RELATIVE"}, -#endif -#if defined(V4L2_CID_PAN_RESET) -{V4L2_CID_PAN_RESET, "V4L2_CID_PAN_RESET"}, -#endif -#if defined(V4L2_CID_TILT_RESET) -{V4L2_CID_TILT_RESET, "V4L2_CID_TILT_RESET"}, -#endif -#if defined(V4L2_CID_PAN_ABSOLUTE) -{V4L2_CID_PAN_ABSOLUTE, "V4L2_CID_PAN_ABSOLUTE"}, -#endif -#if defined(V4L2_CID_TILT_ABSOLUTE) -{V4L2_CID_TILT_ABSOLUTE, "V4L2_CID_TILT_ABSOLUTE"}, -#endif -#if defined(V4L2_CID_FOCUS_ABSOLUTE) -{V4L2_CID_FOCUS_ABSOLUTE, "V4L2_CID_FOCUS_ABSOLUTE"}, -#endif -#if defined(V4L2_CID_FOCUS_RELATIVE) -{V4L2_CID_FOCUS_RELATIVE, "V4L2_CID_FOCUS_RELATIVE"}, -#endif -#if defined(V4L2_CID_FOCUS_AUTO) -{V4L2_CID_FOCUS_AUTO, "V4L2_CID_FOCUS_AUTO"}, -#endif -{0xFFFFFFFF, ""} -}; - -k = 0; -while (mess[k].name[0]) { - if (wot == mess[k].command) { - JOT(8, "ioctl 0x%08X is %s\n", \ - mess[k].command, &mess[k].name[0]); - return 0; - } - k++; -} -JOT(8, "cid 0x%08X is not in videodev2.h\n", wot); -return -1; -} /*****************************************************************************/ diff --git a/drivers/staging/easycap/easycap_low.c b/drivers/staging/easycap/easycap_low.c index ad1fc4cc471a..709c3d98e936 100644 --- a/drivers/staging/easycap/easycap_low.c +++ b/drivers/staging/easycap/easycap_low.c @@ -64,45 +64,22 @@ const struct stk1160config { int reg; int set; } stk1160config[256] = { #if defined(PREFER_NTSC) -#undef OLDMARGIN -#if defined(OLDMARGIN) - {0x110, 0x0008}, -#else {0x110, 0x0014}, -#endif /*OLDMARGIN*/ - {0x111, 0x0000}, {0x112, 0x0003}, {0x113, 0x0000}, - -#if defined(OLDMARGIN) - {0x114, 0x0508}, -#else {0x114, 0x0514}, -#endif /*OLDMARGIN*/ - {0x115, 0x0005}, {0x116, 0x00F3}, {0x117, 0x0000}, #else /* ! PREFER_NTSC*/ -#if defined(OLDMARGIN) - {0x110, 0x0008}, -#else {0x110, 0x0014}, -#endif /*OLDMARGIN*/ - {0x111, 0x0000}, {0x112, 0x0020}, {0x113, 0x0000}, - -#if defined(OLDMARGIN) - {0x114, 0x0508}, -#else {0x114, 0x0514}, -#endif /*OLDMARGIN*/ - {0x115, 0x0005}, {0x116, 0x0110}, {0x117, 0x0001}, diff --git a/drivers/staging/easycap/easycap_main.c b/drivers/staging/easycap/easycap_main.c index 5a4bbd9b453f..5dba664475dd 100644 --- a/drivers/staging/easycap/easycap_main.c +++ b/drivers/staging/easycap/easycap_main.c @@ -31,8 +31,8 @@ #include "easycap.h" #include "easycap_standard.h" -int easycap_debug; -module_param(easycap_debug, int, S_IRUGO | S_IWUSR); +int debug; +module_param(debug, int, S_IRUGO | S_IWUSR); /*---------------------------------------------------------------------------*/ /* @@ -314,8 +314,6 @@ peasycap->audio_eof = 0; do_gettimeofday(&peasycap->timeval7); -peasycap->fudge = 0; - JOT(4, "finished initialization\n"); return 0; } @@ -855,15 +853,11 @@ if (NULL == peasycap) { */ /*---------------------------------------------------------------------------*/ miss = 0; -if (mutex_lock_interruptible(&(peasycap->mutex_mmap_video[0]))) - return -ERESTARTSYS; while ((peasycap->field_read == peasycap->field_fill) || \ (0 != (0xFF00 & peasycap->field_buffer\ [peasycap->field_read][0].kount)) || \ (0 != (0x00FF & peasycap->field_buffer\ [peasycap->field_read][0].kount))) { - mutex_unlock(&(peasycap->mutex_mmap_video[0])); - if (mode) return -EAGAIN; @@ -888,15 +882,11 @@ while ((peasycap->field_read == peasycap->field_fill) || \ } if (peasycap->video_eof) { JOT(8, "%i=peasycap->video_eof\n", peasycap->video_eof); - debrief(peasycap); kill_video_urbs(peasycap); return -EIO; } miss++; -if (mutex_lock_interruptible(&(peasycap->mutex_mmap_video[0]))) - return -ERESTARTSYS; } -mutex_unlock(&(peasycap->mutex_mmap_video[0])); JOT(8, "first awakening on wq_video after %i waits\n", miss); rc = field2frame(peasycap); @@ -925,15 +915,11 @@ JOT(8, "bumped to: %i=peasycap->frame_fill\n", peasycap->frame_fill); */ /*---------------------------------------------------------------------------*/ miss = 0; -if (mutex_lock_interruptible(&(peasycap->mutex_mmap_video[0]))) - return -ERESTARTSYS; while ((peasycap->field_read == peasycap->field_fill) || \ (0 != (0xFF00 & peasycap->field_buffer\ [peasycap->field_read][0].kount)) || \ (0 == (0x00FF & peasycap->field_buffer\ [peasycap->field_read][0].kount))) { - mutex_unlock(&(peasycap->mutex_mmap_video[0])); - if (mode) return -EAGAIN; @@ -957,15 +943,11 @@ while ((peasycap->field_read == peasycap->field_fill) || \ } if (peasycap->video_eof) { JOT(8, "%i=peasycap->video_eof\n", peasycap->video_eof); - debrief(peasycap); kill_video_urbs(peasycap); return -EIO; } miss++; -if (mutex_lock_interruptible(&(peasycap->mutex_mmap_video[0]))) - return -ERESTARTSYS; } -mutex_unlock(&(peasycap->mutex_mmap_video[0])); JOT(8, "second awakening on wq_video after %i waits\n", miss); rc = field2frame(peasycap); @@ -2233,41 +2215,6 @@ default: { return 0; } /*****************************************************************************/ -void -debrief(struct easycap *peasycap) -{ -if ((struct usb_device *)NULL != peasycap->pusb_device) { - check_stk(peasycap->pusb_device); - check_saa(peasycap->pusb_device); - sayreadonly(peasycap); - SAY("%i=peasycap->field_fill\n", peasycap->field_fill); - SAY("%i=peasycap->field_read\n", peasycap->field_read); - SAY("%i=peasycap->frame_fill\n", peasycap->frame_fill); - SAY("%i=peasycap->frame_read\n", peasycap->frame_read); -} -return; -} -/*****************************************************************************/ -void -sayreadonly(struct easycap *peasycap) -{ -static int done; -int got00, got1F, got60, got61, got62; - -if ((!done) && ((struct usb_device *)NULL != peasycap->pusb_device)) { - done = 1; - got00 = read_saa(peasycap->pusb_device, 0x00); - got1F = read_saa(peasycap->pusb_device, 0x1F); - got60 = read_saa(peasycap->pusb_device, 0x60); - got61 = read_saa(peasycap->pusb_device, 0x61); - got62 = read_saa(peasycap->pusb_device, 0x62); - SAY("0x%02X=reg0x00 0x%02X=reg0x1F\n", got00, got1F); - SAY("0x%02X=reg0x60 0x%02X=reg0x61 0x%02X=reg0x62\n", \ - got60, got61, got62); -} -return; -} -/*****************************************************************************/ /*---------------------------------------------------------------------------*/ /* * SEE CORBET ET AL. "LINUX DEVICE DRIVERS", 3rd EDITION, PAGES 430-434 @@ -2355,7 +2302,6 @@ if (NULL == peasycap) { SAY("ERROR: peasycap is NULL\n"); return retcode; } -mutex_lock(&(peasycap->mutex_mmap_video[0])); /*---------------------------------------------------------------------------*/ pbuf = peasycap->frame_buffer[k][m].pgo; if (NULL == pbuf) { @@ -2370,7 +2316,6 @@ if (NULL == page) { get_page(page); /*---------------------------------------------------------------------------*/ finish: -mutex_unlock(&(peasycap->mutex_mmap_video[0])); if (NULL == page) { SAY("ERROR: page is NULL after get_page(page)\n"); } else { @@ -2383,7 +2328,7 @@ return retcode; /*---------------------------------------------------------------------------*/ /* * ON COMPLETION OF A VIDEO URB ITS DATA IS COPIED TO THE FIELD BUFFERS - * PROVIDED peasycap->video_idle IS ZER0. REGARDLESS OF THIS BEING TRUE, + * PROVIDED peasycap->video_idle IS ZERO. REGARDLESS OF THIS BEING TRUE, * IT IS RESUBMITTED PROVIDED peasycap->video_isoc_streaming IS NOT ZERO. * * THIS FUNCTION IS AN INTERRUPT SERVICE ROUTINE AND MUST NOT SLEEP. @@ -2400,7 +2345,7 @@ return retcode; * 0 != (kount & 0x8000) => AT LEAST ONE URB COMPLETED WITH ERRORS * 0 != (kount & 0x4000) => BUFFER HAS TOO MUCH DATA * 0 != (kount & 0x2000) => BUFFER HAS NOT ENOUGH DATA - * 0 != (kount & 0x0400) => FIELD WAS SUBMITTED BY BRIDGER ROUTINE + * 0 != (kount & 0x0400) => RESERVED * 0 != (kount & 0x0200) => FIELD BUFFER NOT YET CHECKED * 0 != (kount & 0x0100) => BUFFER HAS TWO EXTRA BYTES - WHY? */ @@ -2417,10 +2362,6 @@ int videofieldamount; unsigned int override; int framestatus, framelength, frameactual, frameoffset; __u8 *pu; -#if defined(BRIDGER) -struct timeval timeval; -long long usec; -#endif /*BRIDGER*/ if (NULL == purb) { SAY("ERROR: easycap_complete(): purb is NULL\n"); @@ -2864,55 +2805,6 @@ if (purb->status) { } } /*---------------------------------------------------------------------------*/ -/* - * - * - * *** UNDER DEVELOPMENT/TESTING - NOT READY YET! *** - * - * - * - * VIDEOTAPES MAY HAVE BEEN MANUALLY PAUSED AND RESTARTED DURING RECORDING. - * THIS CAUSES LOSS OF SYNC, CONFUSING DOWNSTREAM USERSPACE PROGRAMS WHICH - * MAY INTERPRET THE INTERRUPTION AS A SYMPTOM OF LATENCY. TO OVERCOME THIS - * THE DRIVER BRIDGES THE HIATUS BY SENDING DUMMY VIDEO FRAMES AT ROUGHLY - * THE RIGHT TIME INTERVALS IN THE HOPE OF PERSUADING THE DOWNSTREAM USERSPACE - * PROGRAM TO RESUME NORMAL SERVICE WHEN THE INTERRUPTION IS OVER. - */ -/*---------------------------------------------------------------------------*/ -#if defined(BRIDGER) -do_gettimeofday(&timeval); -if (peasycap->timeval7.tv_sec) { - usec = 1000000*(timeval.tv_sec - peasycap->timeval7.tv_sec) + \ - (timeval.tv_usec - peasycap->timeval7.tv_usec); - if (usec > (peasycap->usec + peasycap->tolerate)) { - JOT(8, "bridging hiatus\n"); - peasycap->video_junk = 0; - peasycap->field_buffer[peasycap->field_fill][0].kount |= 0x0400; - - peasycap->field_read = (peasycap->field_fill)++; - - if (FIELD_BUFFER_MANY <= peasycap->field_fill) \ - peasycap->field_fill = 0; - peasycap->field_page = 0; - pfield_buffer = &peasycap->field_buffer\ - [peasycap->field_fill][peasycap->field_page]; - pfield_buffer->pto = pfield_buffer->pgo; - - JOT(8, "bumped to: %i=peasycap->field_fill %i=parity\n", \ - peasycap->field_fill, 0x00FF & pfield_buffer->kount); - JOT(8, "field buffer %i has %i bytes to be overwritten\n", \ - peasycap->field_read, videofieldamount); - JOT(8, "wakeup call to wq_video, " \ - "%i=field_read %i=field_fill %i=parity\n", \ - peasycap->field_read, peasycap->field_fill, \ - 0x00FF & \ - peasycap->field_buffer[peasycap->field_read][0].kount); - wake_up_interruptible(&(peasycap->wq_video)); - do_gettimeofday(&peasycap->timeval7); - } -} -#endif /*BRIDGER*/ -/*---------------------------------------------------------------------------*/ /* * RESUBMIT THIS URB, UNLESS A SEVERE PERSISTENT ERROR CONDITION EXISTS. * @@ -3152,12 +3044,6 @@ if (0 == bInterfaceNumber) { init_waitqueue_head(&(peasycap->wq_video)); init_waitqueue_head(&(peasycap->wq_audio)); - mutex_init(&(peasycap->mutex_timeval0)); - mutex_init(&(peasycap->mutex_timeval1)); - - for (k = 0; k < FRAME_BUFFER_MANY; k++) - mutex_init(&(peasycap->mutex_mmap_video[k])); - peasycap->ilk = 0; peasycap->microphone = false; @@ -3176,11 +3062,6 @@ if (0 == bInterfaceNumber) { peasycap->audio_isoc_buffer_size = -1; peasycap->frame_buffer_many = FRAME_BUFFER_MANY; - - if ((struct mutex *)NULL == &(peasycap->mutex_mmap_video[0])) { - SAY("ERROR: &(peasycap->mutex_mmap_video[%i]) is NULL\n", 0); - return -EFAULT; - } /*---------------------------------------------------------------------------*/ /* * DYNAMICALLY FILL IN THE AVAILABLE FORMATS. @@ -4308,7 +4189,7 @@ easycap_module_init(void) int result; SAY("========easycap=======\n"); -JOT(4, "begins. %i=debug\n", easycap_debug); +JOT(4, "begins. %i=debug\n", debug); SAY("version: " EASYCAP_DRIVER_VERSION "\n"); /*---------------------------------------------------------------------------*/ /* @@ -4349,6 +4230,6 @@ MODULE_AUTHOR("R.M. Thomas "); MODULE_DESCRIPTION(EASYCAP_DRIVER_DESCRIPTION); MODULE_VERSION(EASYCAP_DRIVER_VERSION); #if defined(EASYCAP_DEBUG) -MODULE_PARM_DESC(easycap_debug, "debug: 0 (default), 1, 2,..."); +MODULE_PARM_DESC(debug, "debug: 0 (default), 1, 2,..."); #endif /*EASYCAP_DEBUG*/ /*****************************************************************************/ diff --git a/drivers/staging/easycap/easycap_settings.c b/drivers/staging/easycap/easycap_settings.c index 38d94051241d..67f2e4f27323 100644 --- a/drivers/staging/easycap/easycap_settings.c +++ b/drivers/staging/easycap/easycap_settings.c @@ -413,7 +413,7 @@ return n; } /*---------------------------------------------------------------------------*/ struct v4l2_queryctrl easycap_control[] = \ - {{ +{{ .id = V4L2_CID_BRIGHTNESS, .type = V4L2_CTRL_TYPE_INTEGER, .name = "Brightness", @@ -485,5 +485,5 @@ struct v4l2_queryctrl easycap_control[] = \ { .id = 0xFFFFFFFF } - }; +}; /*****************************************************************************/ diff --git a/drivers/staging/easycap/easycap_sound.c b/drivers/staging/easycap/easycap_sound.c index 63562bda738e..7be5bcf7136f 100644 --- a/drivers/staging/easycap/easycap_sound.c +++ b/drivers/staging/easycap/easycap_sound.c @@ -36,7 +36,7 @@ /*---------------------------------------------------------------------------*/ /* * ON COMPLETION OF AN AUDIO URB ITS DATA IS COPIED TO THE AUDIO BUFFERS - * PROVIDED peasycap->audio_idle IS ZER0. REGARDLESS OF THIS BEING TRUE, + * PROVIDED peasycap->audio_idle IS ZERO. REGARDLESS OF THIS BEING TRUE, * IT IS RESUBMITTED PROVIDED peasycap->audio_isoc_streaming IS NOT ZERO. */ /*---------------------------------------------------------------------------*/ @@ -842,11 +842,7 @@ do_gettimeofday(&timeval); if (!peasycap->timeval1.tv_sec) { audio_bytes = 0; timeval1 = timeval; - - if (mutex_lock_interruptible(&(peasycap->mutex_timeval1))) - return -ERESTARTSYS; peasycap->timeval1 = timeval1; - mutex_unlock(&(peasycap->mutex_timeval1)); sdr.quotient = 192000; } else { audio_bytes += (long long int) szret; @@ -861,10 +857,7 @@ if (!peasycap->timeval1.tv_sec) { sdr.quotient = 192000; } JOT(8, "audio streaming at %lli bytes/second\n", sdr.quotient); -if (mutex_lock_interruptible(&(peasycap->mutex_timeval1))) - return -ERESTARTSYS; peasycap->dnbydt = sdr.quotient; -mutex_unlock(&(peasycap->mutex_timeval1)); JOT(8, "returning %li\n", (long int)szret); return szret; diff --git a/drivers/staging/easycap/easycap_testcard.c b/drivers/staging/easycap/easycap_testcard.c index 3c2ce28fab95..700c73ec1c59 100644 --- a/drivers/staging/easycap/easycap_testcard.c +++ b/drivers/staging/easycap/easycap_testcard.c @@ -161,31 +161,31 @@ return(0); } -----------------------------------------------------------------------------*/ int tones[2048] = { - 0, 0, 502, 502, 1004, 1004, 1505, 1505, 2005, 2005, - 2503, 2503, 2998, 2998, 3491, 3491, 3980, 3980, 4466, 4466, - 4948, 4948, 5424, 5424, 5896, 5896, 6362, 6362, 6822, 6822, - 7276, 7276, 7723, 7723, 8162, 8162, 8594, 8594, 9018, 9018, - 9434, 9434, 9840, 9840, 10237, 10237, 10625, 10625, 11002, 11002, - 11370, 11370, 11726, 11726, 12072, 12072, 12406, 12406, 12728, 12728, - 13038, 13038, 13337, 13337, 13622, 13622, 13895, 13895, 14155, 14155, - 14401, 14401, 14634, 14634, 14853, 14853, 15058, 15058, 15249, 15249, - 15426, 15426, 15588, 15588, 15735, 15735, 15868, 15868, 15985, 15985, - 16088, 16088, 16175, 16175, 16248, 16248, 16305, 16305, 16346, 16346, - 16372, 16372, 16383, 16383, 16379, 16379, 16359, 16359, 16323, 16323, - 16272, 16272, 16206, 16206, 16125, 16125, 16028, 16028, 15917, 15917, - 15790, 15790, 15649, 15649, 15492, 15492, 15322, 15322, 15136, 15136, - 14937, 14937, 14723, 14723, 14496, 14496, 14255, 14255, 14001, 14001, - 13733, 13733, 13452, 13452, 13159, 13159, 12854, 12854, 12536, 12536, - 12207, 12207, 11866, 11866, 11513, 11513, 11150, 11150, 10777, 10777, - 10393, 10393, 10000, 10000, 9597, 9597, 9185, 9185, 8765, 8765, - 8336, 8336, 7900, 7900, 7456, 7456, 7005, 7005, 6547, 6547, - 6083, 6083, 5614, 5614, 5139, 5139, 4659, 4659, 4175, 4175, - 3687, 3687, 3196, 3196, 2701, 2701, 2204, 2204, 1705, 1705, - 1205, 1205, 703, 703, 201, 201, -301, -301, -803, -803, - -1305, -1305, -1805, -1805, -2304, -2304, -2801, -2801, -3294, -3294, - -3785, -3785, -4272, -4272, -4756, -4756, -5234, -5234, -5708, -5708, - -6176, -6176, -6639, -6639, -7095, -7095, -7545, -7545, -7988, -7988, - -8423, -8423, -8850, -8850, -9268, -9268, -9679, -9679, -10079, -10079, +0, 0, 502, 502, 1004, 1004, 1505, 1505, 2005, 2005, +2503, 2503, 2998, 2998, 3491, 3491, 3980, 3980, 4466, 4466, +4948, 4948, 5424, 5424, 5896, 5896, 6362, 6362, 6822, 6822, +7276, 7276, 7723, 7723, 8162, 8162, 8594, 8594, 9018, 9018, +9434, 9434, 9840, 9840, 10237, 10237, 10625, 10625, 11002, 11002, +11370, 11370, 11726, 11726, 12072, 12072, 12406, 12406, 12728, 12728, +13038, 13038, 13337, 13337, 13622, 13622, 13895, 13895, 14155, 14155, +14401, 14401, 14634, 14634, 14853, 14853, 15058, 15058, 15249, 15249, +15426, 15426, 15588, 15588, 15735, 15735, 15868, 15868, 15985, 15985, +16088, 16088, 16175, 16175, 16248, 16248, 16305, 16305, 16346, 16346, +16372, 16372, 16383, 16383, 16379, 16379, 16359, 16359, 16323, 16323, +16272, 16272, 16206, 16206, 16125, 16125, 16028, 16028, 15917, 15917, +15790, 15790, 15649, 15649, 15492, 15492, 15322, 15322, 15136, 15136, +14937, 14937, 14723, 14723, 14496, 14496, 14255, 14255, 14001, 14001, +13733, 13733, 13452, 13452, 13159, 13159, 12854, 12854, 12536, 12536, +12207, 12207, 11866, 11866, 11513, 11513, 11150, 11150, 10777, 10777, +10393, 10393, 10000, 10000, 9597, 9597, 9185, 9185, 8765, 8765, +8336, 8336, 7900, 7900, 7456, 7456, 7005, 7005, 6547, 6547, +6083, 6083, 5614, 5614, 5139, 5139, 4659, 4659, 4175, 4175, +3687, 3687, 3196, 3196, 2701, 2701, 2204, 2204, 1705, 1705, +1205, 1205, 703, 703, 201, 201, -301, -301, -803, -803, +-1305, -1305, -1805, -1805, -2304, -2304, -2801, -2801, -3294, -3294, +-3785, -3785, -4272, -4272, -4756, -4756, -5234, -5234, -5708, -5708, +-6176, -6176, -6639, -6639, -7095, -7095, -7545, -7545, -7988, -7988, +-8423, -8423, -8850, -8850, -9268, -9268, -9679, -9679, -10079, -10079, -10471, -10471, -10853, -10853, -11224, -11224, -11585, -11585, -11935, -11935, -12273, -12273, -12600, -12600, -12916, -12916, -13219, -13219, -13510, -13510, -13788, -13788, -14053, -14053, -14304, -14304, -14543, -14543, -14767, -14767, @@ -198,35 +198,35 @@ int tones[2048] = { -14353, -14353, -14104, -14104, -13842, -13842, -13566, -13566, -13278, -13278, -12977, -12977, -12665, -12665, -12340, -12340, -12003, -12003, -11656, -11656, -11297, -11297, -10928, -10928, -10548, -10548, -10159, -10159, -9759, -9759, - -9351, -9351, -8934, -8934, -8509, -8509, -8075, -8075, -7634, -7634, - -7186, -7186, -6731, -6731, -6269, -6269, -5802, -5802, -5329, -5329, - -4852, -4852, -4369, -4369, -3883, -3883, -3393, -3393, -2900, -2900, - -2404, -2404, -1905, -1905, -1405, -1405, -904, -904, -402, -402, - 100, 100, 603, 603, 1105, 1105, 1605, 1605, 2105, 2105, - 2602, 2602, 3097, 3097, 3589, 3589, 4078, 4078, 4563, 4563, - 5043, 5043, 5519, 5519, 5990, 5990, 6455, 6455, 6914, 6914, - 7366, 7366, 7811, 7811, 8249, 8249, 8680, 8680, 9102, 9102, - 9516, 9516, 9920, 9920, 10315, 10315, 10701, 10701, 11077, 11077, - 11442, 11442, 11796, 11796, 12139, 12139, 12471, 12471, 12791, 12791, - 13099, 13099, 13395, 13395, 13678, 13678, 13948, 13948, 14205, 14205, - 14449, 14449, 14679, 14679, 14895, 14895, 15098, 15098, 15286, 15286, - 15459, 15459, 15618, 15618, 15763, 15763, 15892, 15892, 16007, 16007, - 16107, 16107, 16191, 16191, 16260, 16260, 16314, 16314, 16353, 16353, - 16376, 16376, 16384, 16384, 16376, 16376, 16353, 16353, 16314, 16314, - 16260, 16260, 16191, 16191, 16107, 16107, 16007, 16007, 15892, 15892, - 15763, 15763, 15618, 15618, 15459, 15459, 15286, 15286, 15098, 15098, - 14895, 14895, 14679, 14679, 14449, 14449, 14205, 14205, 13948, 13948, - 13678, 13678, 13395, 13395, 13099, 13099, 12791, 12791, 12471, 12471, - 12139, 12139, 11796, 11796, 11442, 11442, 11077, 11077, 10701, 10701, - 10315, 10315, 9920, 9920, 9516, 9516, 9102, 9102, 8680, 8680, - 8249, 8249, 7811, 7811, 7366, 7366, 6914, 6914, 6455, 6455, - 5990, 5990, 5519, 5519, 5043, 5043, 4563, 4563, 4078, 4078, - 3589, 3589, 3097, 3097, 2602, 2602, 2105, 2105, 1605, 1605, - 1105, 1105, 603, 603, 100, 100, -402, -402, -904, -904, - -1405, -1405, -1905, -1905, -2404, -2404, -2900, -2900, -3393, -3393, - -3883, -3883, -4369, -4369, -4852, -4852, -5329, -5329, -5802, -5802, - -6269, -6269, -6731, -6731, -7186, -7186, -7634, -7634, -8075, -8075, - -8509, -8509, -8934, -8934, -9351, -9351, -9759, -9759, -10159, -10159, +-9351, -9351, -8934, -8934, -8509, -8509, -8075, -8075, -7634, -7634, +-7186, -7186, -6731, -6731, -6269, -6269, -5802, -5802, -5329, -5329, +-4852, -4852, -4369, -4369, -3883, -3883, -3393, -3393, -2900, -2900, +-2404, -2404, -1905, -1905, -1405, -1405, -904, -904, -402, -402, +100, 100, 603, 603, 1105, 1105, 1605, 1605, 2105, 2105, +2602, 2602, 3097, 3097, 3589, 3589, 4078, 4078, 4563, 4563, +5043, 5043, 5519, 5519, 5990, 5990, 6455, 6455, 6914, 6914, +7366, 7366, 7811, 7811, 8249, 8249, 8680, 8680, 9102, 9102, +9516, 9516, 9920, 9920, 10315, 10315, 10701, 10701, 11077, 11077, +11442, 11442, 11796, 11796, 12139, 12139, 12471, 12471, 12791, 12791, +13099, 13099, 13395, 13395, 13678, 13678, 13948, 13948, 14205, 14205, +14449, 14449, 14679, 14679, 14895, 14895, 15098, 15098, 15286, 15286, +15459, 15459, 15618, 15618, 15763, 15763, 15892, 15892, 16007, 16007, +16107, 16107, 16191, 16191, 16260, 16260, 16314, 16314, 16353, 16353, +16376, 16376, 16384, 16384, 16376, 16376, 16353, 16353, 16314, 16314, +16260, 16260, 16191, 16191, 16107, 16107, 16007, 16007, 15892, 15892, +15763, 15763, 15618, 15618, 15459, 15459, 15286, 15286, 15098, 15098, +14895, 14895, 14679, 14679, 14449, 14449, 14205, 14205, 13948, 13948, +13678, 13678, 13395, 13395, 13099, 13099, 12791, 12791, 12471, 12471, +12139, 12139, 11796, 11796, 11442, 11442, 11077, 11077, 10701, 10701, +10315, 10315, 9920, 9920, 9516, 9516, 9102, 9102, 8680, 8680, +8249, 8249, 7811, 7811, 7366, 7366, 6914, 6914, 6455, 6455, +5990, 5990, 5519, 5519, 5043, 5043, 4563, 4563, 4078, 4078, +3589, 3589, 3097, 3097, 2602, 2602, 2105, 2105, 1605, 1605, +1105, 1105, 603, 603, 100, 100, -402, -402, -904, -904, +-1405, -1405, -1905, -1905, -2404, -2404, -2900, -2900, -3393, -3393, +-3883, -3883, -4369, -4369, -4852, -4852, -5329, -5329, -5802, -5802, +-6269, -6269, -6731, -6731, -7186, -7186, -7634, -7634, -8075, -8075, +-8509, -8509, -8934, -8934, -9351, -9351, -9759, -9759, -10159, -10159, -10548, -10548, -10928, -10928, -11297, -11297, -11656, -11656, -12003, -12003, -12340, -12340, -12665, -12665, -12977, -12977, -13278, -13278, -13566, -13566, -13842, -13842, -14104, -14104, -14353, -14353, -14589, -14589, -14810, -14810, @@ -239,35 +239,35 @@ int tones[2048] = { -14304, -14304, -14053, -14053, -13788, -13788, -13510, -13510, -13219, -13219, -12916, -12916, -12600, -12600, -12273, -12273, -11935, -11935, -11585, -11585, -11224, -11224, -10853, -10853, -10471, -10471, -10079, -10079, -9679, -9679, - -9268, -9268, -8850, -8850, -8423, -8423, -7988, -7988, -7545, -7545, - -7095, -7095, -6639, -6639, -6176, -6176, -5708, -5708, -5234, -5234, - -4756, -4756, -4272, -4272, -3785, -3785, -3294, -3294, -2801, -2801, - -2304, -2304, -1805, -1805, -1305, -1305, -803, -803, -301, -301, - 201, 201, 703, 703, 1205, 1205, 1705, 1705, 2204, 2204, - 2701, 2701, 3196, 3196, 3687, 3687, 4175, 4175, 4659, 4659, - 5139, 5139, 5614, 5614, 6083, 6083, 6547, 6547, 7005, 7005, - 7456, 7456, 7900, 7900, 8336, 8336, 8765, 8765, 9185, 9185, - 9597, 9597, 10000, 10000, 10393, 10393, 10777, 10777, 11150, 11150, - 11513, 11513, 11866, 11866, 12207, 12207, 12536, 12536, 12854, 12854, - 13159, 13159, 13452, 13452, 13733, 13733, 14001, 14001, 14255, 14255, - 14496, 14496, 14723, 14723, 14937, 14937, 15136, 15136, 15322, 15322, - 15492, 15492, 15649, 15649, 15790, 15790, 15917, 15917, 16028, 16028, - 16125, 16125, 16206, 16206, 16272, 16272, 16323, 16323, 16359, 16359, - 16379, 16379, 16383, 16383, 16372, 16372, 16346, 16346, 16305, 16305, - 16248, 16248, 16175, 16175, 16088, 16088, 15985, 15985, 15868, 15868, - 15735, 15735, 15588, 15588, 15426, 15426, 15249, 15249, 15058, 15058, - 14853, 14853, 14634, 14634, 14401, 14401, 14155, 14155, 13895, 13895, - 13622, 13622, 13337, 13337, 13038, 13038, 12728, 12728, 12406, 12406, - 12072, 12072, 11726, 11726, 11370, 11370, 11002, 11002, 10625, 10625, - 10237, 10237, 9840, 9840, 9434, 9434, 9018, 9018, 8594, 8594, - 8162, 8162, 7723, 7723, 7276, 7276, 6822, 6822, 6362, 6362, - 5896, 5896, 5424, 5424, 4948, 4948, 4466, 4466, 3980, 3980, - 3491, 3491, 2998, 2998, 2503, 2503, 2005, 2005, 1505, 1505, - 1004, 1004, 502, 502, 0, 0, -502, -502, -1004, -1004, - -1505, -1505, -2005, -2005, -2503, -2503, -2998, -2998, -3491, -3491, - -3980, -3980, -4466, -4466, -4948, -4948, -5424, -5424, -5896, -5896, - -6362, -6362, -6822, -6822, -7276, -7276, -7723, -7723, -8162, -8162, - -8594, -8594, -9018, -9018, -9434, -9434, -9840, -9840, -10237, -10237, +-9268, -9268, -8850, -8850, -8423, -8423, -7988, -7988, -7545, -7545, +-7095, -7095, -6639, -6639, -6176, -6176, -5708, -5708, -5234, -5234, +-4756, -4756, -4272, -4272, -3785, -3785, -3294, -3294, -2801, -2801, +-2304, -2304, -1805, -1805, -1305, -1305, -803, -803, -301, -301, +201, 201, 703, 703, 1205, 1205, 1705, 1705, 2204, 2204, +2701, 2701, 3196, 3196, 3687, 3687, 4175, 4175, 4659, 4659, +5139, 5139, 5614, 5614, 6083, 6083, 6547, 6547, 7005, 7005, +7456, 7456, 7900, 7900, 8336, 8336, 8765, 8765, 9185, 9185, +9597, 9597, 10000, 10000, 10393, 10393, 10777, 10777, 11150, 11150, +11513, 11513, 11866, 11866, 12207, 12207, 12536, 12536, 12854, 12854, +13159, 13159, 13452, 13452, 13733, 13733, 14001, 14001, 14255, 14255, +14496, 14496, 14723, 14723, 14937, 14937, 15136, 15136, 15322, 15322, +15492, 15492, 15649, 15649, 15790, 15790, 15917, 15917, 16028, 16028, +16125, 16125, 16206, 16206, 16272, 16272, 16323, 16323, 16359, 16359, +16379, 16379, 16383, 16383, 16372, 16372, 16346, 16346, 16305, 16305, +16248, 16248, 16175, 16175, 16088, 16088, 15985, 15985, 15868, 15868, +15735, 15735, 15588, 15588, 15426, 15426, 15249, 15249, 15058, 15058, +14853, 14853, 14634, 14634, 14401, 14401, 14155, 14155, 13895, 13895, +13622, 13622, 13337, 13337, 13038, 13038, 12728, 12728, 12406, 12406, +12072, 12072, 11726, 11726, 11370, 11370, 11002, 11002, 10625, 10625, +10237, 10237, 9840, 9840, 9434, 9434, 9018, 9018, 8594, 8594, +8162, 8162, 7723, 7723, 7276, 7276, 6822, 6822, 6362, 6362, +5896, 5896, 5424, 5424, 4948, 4948, 4466, 4466, 3980, 3980, +3491, 3491, 2998, 2998, 2503, 2503, 2005, 2005, 1505, 1505, +1004, 1004, 502, 502, 0, 0, -502, -502, -1004, -1004, +-1505, -1505, -2005, -2005, -2503, -2503, -2998, -2998, -3491, -3491, +-3980, -3980, -4466, -4466, -4948, -4948, -5424, -5424, -5896, -5896, +-6362, -6362, -6822, -6822, -7276, -7276, -7723, -7723, -8162, -8162, +-8594, -8594, -9018, -9018, -9434, -9434, -9840, -9840, -10237, -10237, -10625, -10625, -11002, -11002, -11370, -11370, -11726, -11726, -12072, -12072, -12406, -12406, -12728, -12728, -13038, -13038, -13337, -13337, -13622, -13622, -13895, -13895, -14155, -14155, -14401, -14401, -14634, -14634, -14853, -14853, @@ -280,35 +280,35 @@ int tones[2048] = { -14255, -14255, -14001, -14001, -13733, -13733, -13452, -13452, -13159, -13159, -12854, -12854, -12536, -12536, -12207, -12207, -11866, -11866, -11513, -11513, -11150, -11150, -10777, -10777, -10393, -10393, -10000, -10000, -9597, -9597, - -9185, -9185, -8765, -8765, -8336, -8336, -7900, -7900, -7456, -7456, - -7005, -7005, -6547, -6547, -6083, -6083, -5614, -5614, -5139, -5139, - -4659, -4659, -4175, -4175, -3687, -3687, -3196, -3196, -2701, -2701, - -2204, -2204, -1705, -1705, -1205, -1205, -703, -703, -201, -201, - 301, 301, 803, 803, 1305, 1305, 1805, 1805, 2304, 2304, - 2801, 2801, 3294, 3294, 3785, 3785, 4272, 4272, 4756, 4756, - 5234, 5234, 5708, 5708, 6176, 6176, 6639, 6639, 7095, 7095, - 7545, 7545, 7988, 7988, 8423, 8423, 8850, 8850, 9268, 9268, - 9679, 9679, 10079, 10079, 10471, 10471, 10853, 10853, 11224, 11224, - 11585, 11585, 11935, 11935, 12273, 12273, 12600, 12600, 12916, 12916, - 13219, 13219, 13510, 13510, 13788, 13788, 14053, 14053, 14304, 14304, - 14543, 14543, 14767, 14767, 14978, 14978, 15175, 15175, 15357, 15357, - 15525, 15525, 15678, 15678, 15817, 15817, 15940, 15940, 16049, 16049, - 16142, 16142, 16221, 16221, 16284, 16284, 16331, 16331, 16364, 16364, - 16381, 16381, 16382, 16382, 16368, 16368, 16339, 16339, 16294, 16294, - 16234, 16234, 16159, 16159, 16069, 16069, 15963, 15963, 15842, 15842, - 15707, 15707, 15557, 15557, 15392, 15392, 15212, 15212, 15018, 15018, - 14810, 14810, 14589, 14589, 14353, 14353, 14104, 14104, 13842, 13842, - 13566, 13566, 13278, 13278, 12977, 12977, 12665, 12665, 12340, 12340, - 12003, 12003, 11656, 11656, 11297, 11297, 10928, 10928, 10548, 10548, - 10159, 10159, 9759, 9759, 9351, 9351, 8934, 8934, 8509, 8509, - 8075, 8075, 7634, 7634, 7186, 7186, 6731, 6731, 6269, 6269, - 5802, 5802, 5329, 5329, 4852, 4852, 4369, 4369, 3883, 3883, - 3393, 3393, 2900, 2900, 2404, 2404, 1905, 1905, 1405, 1405, - 904, 904, 402, 402, -100, -100, -603, -603, -1105, -1105, - -1605, -1605, -2105, -2105, -2602, -2602, -3097, -3097, -3589, -3589, - -4078, -4078, -4563, -4563, -5043, -5043, -5519, -5519, -5990, -5990, - -6455, -6455, -6914, -6914, -7366, -7366, -7811, -7811, -8249, -8249, - -8680, -8680, -9102, -9102, -9516, -9516, -9920, -9920, -10315, -10315, +-9185, -9185, -8765, -8765, -8336, -8336, -7900, -7900, -7456, -7456, +-7005, -7005, -6547, -6547, -6083, -6083, -5614, -5614, -5139, -5139, +-4659, -4659, -4175, -4175, -3687, -3687, -3196, -3196, -2701, -2701, +-2204, -2204, -1705, -1705, -1205, -1205, -703, -703, -201, -201, +301, 301, 803, 803, 1305, 1305, 1805, 1805, 2304, 2304, +2801, 2801, 3294, 3294, 3785, 3785, 4272, 4272, 4756, 4756, +5234, 5234, 5708, 5708, 6176, 6176, 6639, 6639, 7095, 7095, +7545, 7545, 7988, 7988, 8423, 8423, 8850, 8850, 9268, 9268, +9679, 9679, 10079, 10079, 10471, 10471, 10853, 10853, 11224, 11224, +11585, 11585, 11935, 11935, 12273, 12273, 12600, 12600, 12916, 12916, +13219, 13219, 13510, 13510, 13788, 13788, 14053, 14053, 14304, 14304, +14543, 14543, 14767, 14767, 14978, 14978, 15175, 15175, 15357, 15357, +15525, 15525, 15678, 15678, 15817, 15817, 15940, 15940, 16049, 16049, +16142, 16142, 16221, 16221, 16284, 16284, 16331, 16331, 16364, 16364, +16381, 16381, 16382, 16382, 16368, 16368, 16339, 16339, 16294, 16294, +16234, 16234, 16159, 16159, 16069, 16069, 15963, 15963, 15842, 15842, +15707, 15707, 15557, 15557, 15392, 15392, 15212, 15212, 15018, 15018, +14810, 14810, 14589, 14589, 14353, 14353, 14104, 14104, 13842, 13842, +13566, 13566, 13278, 13278, 12977, 12977, 12665, 12665, 12340, 12340, +12003, 12003, 11656, 11656, 11297, 11297, 10928, 10928, 10548, 10548, +10159, 10159, 9759, 9759, 9351, 9351, 8934, 8934, 8509, 8509, +8075, 8075, 7634, 7634, 7186, 7186, 6731, 6731, 6269, 6269, +5802, 5802, 5329, 5329, 4852, 4852, 4369, 4369, 3883, 3883, +3393, 3393, 2900, 2900, 2404, 2404, 1905, 1905, 1405, 1405, +904, 904, 402, 402, -100, -100, -603, -603, -1105, -1105, +-1605, -1605, -2105, -2105, -2602, -2602, -3097, -3097, -3589, -3589, +-4078, -4078, -4563, -4563, -5043, -5043, -5519, -5519, -5990, -5990, +-6455, -6455, -6914, -6914, -7366, -7366, -7811, -7811, -8249, -8249, +-8680, -8680, -9102, -9102, -9516, -9516, -9920, -9920, -10315, -10315, -10701, -10701, -11077, -11077, -11442, -11442, -11796, -11796, -12139, -12139, -12471, -12471, -12791, -12791, -13099, -13099, -13395, -13395, -13678, -13678, -13948, -13948, -14205, -14205, -14449, -14449, -14679, -14679, -14895, -14895, @@ -321,35 +321,35 @@ int tones[2048] = { -14205, -14205, -13948, -13948, -13678, -13678, -13395, -13395, -13099, -13099, -12791, -12791, -12471, -12471, -12139, -12139, -11796, -11796, -11442, -11442, -11077, -11077, -10701, -10701, -10315, -10315, -9920, -9920, -9516, -9516, - -9102, -9102, -8680, -8680, -8249, -8249, -7811, -7811, -7366, -7366, - -6914, -6914, -6455, -6455, -5990, -5990, -5519, -5519, -5043, -5043, - -4563, -4563, -4078, -4078, -3589, -3589, -3097, -3097, -2602, -2602, - -2105, -2105, -1605, -1605, -1105, -1105, -603, -603, -100, -100, - 402, 402, 904, 904, 1405, 1405, 1905, 1905, 2404, 2404, - 2900, 2900, 3393, 3393, 3883, 3883, 4369, 4369, 4852, 4852, - 5329, 5329, 5802, 5802, 6269, 6269, 6731, 6731, 7186, 7186, - 7634, 7634, 8075, 8075, 8509, 8509, 8934, 8934, 9351, 9351, - 9759, 9759, 10159, 10159, 10548, 10548, 10928, 10928, 11297, 11297, - 11656, 11656, 12003, 12003, 12340, 12340, 12665, 12665, 12977, 12977, - 13278, 13278, 13566, 13566, 13842, 13842, 14104, 14104, 14353, 14353, - 14589, 14589, 14810, 14810, 15018, 15018, 15212, 15212, 15392, 15392, - 15557, 15557, 15707, 15707, 15842, 15842, 15963, 15963, 16069, 16069, - 16159, 16159, 16234, 16234, 16294, 16294, 16339, 16339, 16368, 16368, - 16382, 16382, 16381, 16381, 16364, 16364, 16331, 16331, 16284, 16284, - 16221, 16221, 16142, 16142, 16049, 16049, 15940, 15940, 15817, 15817, - 15678, 15678, 15525, 15525, 15357, 15357, 15175, 15175, 14978, 14978, - 14767, 14767, 14543, 14543, 14304, 14304, 14053, 14053, 13788, 13788, - 13510, 13510, 13219, 13219, 12916, 12916, 12600, 12600, 12273, 12273, - 11935, 11935, 11585, 11585, 11224, 11224, 10853, 10853, 10471, 10471, - 10079, 10079, 9679, 9679, 9268, 9268, 8850, 8850, 8423, 8423, - 7988, 7988, 7545, 7545, 7095, 7095, 6639, 6639, 6176, 6176, - 5708, 5708, 5234, 5234, 4756, 4756, 4272, 4272, 3785, 3785, - 3294, 3294, 2801, 2801, 2304, 2304, 1805, 1805, 1305, 1305, - 803, 803, 301, 301, -201, -201, -703, -703, -1205, -1205, - -1705, -1705, -2204, -2204, -2701, -2701, -3196, -3196, -3687, -3687, - -4175, -4175, -4659, -4659, -5139, -5139, -5614, -5614, -6083, -6083, - -6547, -6547, -7005, -7005, -7456, -7456, -7900, -7900, -8336, -8336, - -8765, -8765, -9185, -9185, -9597, -9597, -10000, -10000, -10393, -10393, +-9102, -9102, -8680, -8680, -8249, -8249, -7811, -7811, -7366, -7366, +-6914, -6914, -6455, -6455, -5990, -5990, -5519, -5519, -5043, -5043, +-4563, -4563, -4078, -4078, -3589, -3589, -3097, -3097, -2602, -2602, +-2105, -2105, -1605, -1605, -1105, -1105, -603, -603, -100, -100, +402, 402, 904, 904, 1405, 1405, 1905, 1905, 2404, 2404, +2900, 2900, 3393, 3393, 3883, 3883, 4369, 4369, 4852, 4852, +5329, 5329, 5802, 5802, 6269, 6269, 6731, 6731, 7186, 7186, +7634, 7634, 8075, 8075, 8509, 8509, 8934, 8934, 9351, 9351, +9759, 9759, 10159, 10159, 10548, 10548, 10928, 10928, 11297, 11297, +11656, 11656, 12003, 12003, 12340, 12340, 12665, 12665, 12977, 12977, +13278, 13278, 13566, 13566, 13842, 13842, 14104, 14104, 14353, 14353, +14589, 14589, 14810, 14810, 15018, 15018, 15212, 15212, 15392, 15392, +15557, 15557, 15707, 15707, 15842, 15842, 15963, 15963, 16069, 16069, +16159, 16159, 16234, 16234, 16294, 16294, 16339, 16339, 16368, 16368, +16382, 16382, 16381, 16381, 16364, 16364, 16331, 16331, 16284, 16284, +16221, 16221, 16142, 16142, 16049, 16049, 15940, 15940, 15817, 15817, +15678, 15678, 15525, 15525, 15357, 15357, 15175, 15175, 14978, 14978, +14767, 14767, 14543, 14543, 14304, 14304, 14053, 14053, 13788, 13788, +13510, 13510, 13219, 13219, 12916, 12916, 12600, 12600, 12273, 12273, +11935, 11935, 11585, 11585, 11224, 11224, 10853, 10853, 10471, 10471, +10079, 10079, 9679, 9679, 9268, 9268, 8850, 8850, 8423, 8423, +7988, 7988, 7545, 7545, 7095, 7095, 6639, 6639, 6176, 6176, +5708, 5708, 5234, 5234, 4756, 4756, 4272, 4272, 3785, 3785, +3294, 3294, 2801, 2801, 2304, 2304, 1805, 1805, 1305, 1305, +803, 803, 301, 301, -201, -201, -703, -703, -1205, -1205, +-1705, -1705, -2204, -2204, -2701, -2701, -3196, -3196, -3687, -3687, +-4175, -4175, -4659, -4659, -5139, -5139, -5614, -5614, -6083, -6083, +-6547, -6547, -7005, -7005, -7456, -7456, -7900, -7900, -8336, -8336, +-8765, -8765, -9185, -9185, -9597, -9597, -10000, -10000, -10393, -10393, -10777, -10777, -11150, -11150, -11513, -11513, -11866, -11866, -12207, -12207, -12536, -12536, -12854, -12854, -13159, -13159, -13452, -13452, -13733, -13733, -14001, -14001, -14255, -14255, -14496, -14496, -14723, -14723, -14937, -14937, @@ -362,10 +362,10 @@ int tones[2048] = { -14155, -14155, -13895, -13895, -13622, -13622, -13337, -13337, -13038, -13038, -12728, -12728, -12406, -12406, -12072, -12072, -11726, -11726, -11370, -11370, -11002, -11002, -10625, -10625, -10237, -10237, -9840, -9840, -9434, -9434, - -9018, -9018, -8594, -8594, -8162, -8162, -7723, -7723, -7276, -7276, - -6822, -6822, -6362, -6362, -5896, -5896, -5424, -5424, -4948, -4948, - -4466, -4466, -3980, -3980, -3491, -3491, -2998, -2998, -2503, -2503, - -2005, -2005, -1505, -1505, -1004, -1004, -502, -502 +-9018, -9018, -8594, -8594, -8162, -8162, -7723, -7723, -7276, -7276, +-6822, -6822, -6362, -6362, -5896, -5896, -5424, -5424, -4948, -4948, +-4466, -4466, -3980, -3980, -3491, -3491, -2998, -2998, -2503, -2503, +-2005, -2005, -1505, -1505, -1004, -1004, -502, -502 }; /*****************************************************************************/ void -- cgit v1.2.3 From e68703cfe8dd2f5605c53b46fae6c9c027e7ef50 Mon Sep 17 00:00:00 2001 From: Mike Thomas Date: Sun, 7 Nov 2010 19:58:55 +0000 Subject: staging/easycap: Make code re-entrant In order to allow multiple EasyCAP dongles to operate simultaneously without mutual interference all static variables have been eliminated except for a persistent inventory of plugged-in dongles at module level. Signed-off-by: Mike Thomas Signed-off-by: Greg Kroah-Hartman --- drivers/staging/easycap/easycap.h | 57 +- drivers/staging/easycap/easycap_debug.h | 2 +- drivers/staging/easycap/easycap_ioctl.c | 585 ++++++------ drivers/staging/easycap/easycap_low.c | 24 +- drivers/staging/easycap/easycap_main.c | 1424 ++++++++++++++-------------- drivers/staging/easycap/easycap_sound.c | 443 +++++---- drivers/staging/easycap/easycap_testcard.c | 2 +- 7 files changed, 1361 insertions(+), 1176 deletions(-) diff --git a/drivers/staging/easycap/easycap.h b/drivers/staging/easycap/easycap.h index 9fb0f64d5477..11ceda7dde30 100644 --- a/drivers/staging/easycap/easycap.h +++ b/drivers/staging/easycap/easycap.h @@ -121,7 +121,7 @@ #define EASYCAP_DRIVER_DESCRIPTION "easycapdc60" #define USB_SKEL_MINOR_BASE 192 -#define VIDEO_DEVICE_MANY 8 +#define DONGLE_MANY 8 /*---------------------------------------------------------------------------*/ /* @@ -264,6 +264,17 @@ struct v4l2_format v4l2_format; */ /*---------------------------------------------------------------------------*/ struct easycap { +int isdongle; + +/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +#if defined(EASYCAP_IS_VIDEODEV_CLIENT) +struct video_device video_device; +#if defined(EASYCAP_NEEDS_V4L2_DEVICE_H) +struct v4l2_device v4l2_device; +#endif /*EASYCAP_NEEDS_V4L2_DEVICE_H*/ +#endif /*EASYCAP_IS_VIDEODEV_CLIENT*/ +/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ + unsigned int audio_pages_per_fragment; unsigned int audio_bytes_per_fragment; unsigned int audio_buffer_page_many; @@ -276,12 +287,6 @@ __s16 oldaudio; int ilk; bool microphone; -/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -#if defined(EASYCAP_IS_VIDEODEV_CLIENT) -struct video_device *pvideo_device; -#endif /*EASYCAP_IS_VIDEODEV_CLIENT*/ -/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ - struct usb_device *pusb_device; struct usb_interface *pusb_interface; @@ -306,7 +311,10 @@ int merit[180]; struct timeval timeval0; struct timeval timeval1; struct timeval timeval2; +struct timeval timeval3; +struct timeval timeval6; struct timeval timeval7; +struct timeval timeval8; long long int dnbydt; int video_interface; @@ -332,6 +340,13 @@ struct data_buffer \ struct list_head urb_video_head; struct list_head *purb_video_head; +__u8 cache[8]; +__u8 *pcache; +int video_mt; +int audio_mt; +long long audio_bytes; +__u32 isequence; + int vma_many; /*---------------------------------------------------------------------------*/ @@ -530,6 +545,7 @@ int set2to93(struct usb_device *); int regset(struct usb_device *, __u16, __u16); int regget(struct usb_device *, __u16, void *); +int isdongle(struct easycap *); /*---------------------------------------------------------------------------*/ struct signed_div_result { long long int quotient; @@ -557,20 +573,39 @@ unsigned long long int remainder; } \ } while (0) /*---------------------------------------------------------------------------*/ - +/* + * MACROS SAM(...) AND JOM(...) ALLOW DIAGNOSTIC OUTPUT TO BE TAGGED WITH + * THE IDENTITY OF THE DONGLE TO WHICH IT APPLIES, BUT IF INVOKED WHEN THE + * POINTER peasycap IS INVALID AN Oops IS LIKELY, AND ITS CAUSE MAY NOT BE + * IMMEDIATELY OBVIOUS FROM A CASUAL READING OF THE SOURCE CODE. BEWARE. +*/ +/*---------------------------------------------------------------------------*/ #define SAY(format, args...) do { \ - printk(KERN_DEBUG "easycap: %s: " format, __func__, ##args); \ + printk(KERN_DEBUG "easycap:: %s: " \ + format, __func__, ##args); \ +} while (0) +#define SAM(format, args...) do { \ + printk(KERN_DEBUG "easycap::%i%s: " \ + format, peasycap->isdongle, __func__, ##args);\ } while (0) - #if defined(EASYCAP_DEBUG) #define JOT(n, format, args...) do { \ if (n <= debug) { \ - printk(KERN_DEBUG "easycap: %s: " format, __func__, ##args); \ + printk(KERN_DEBUG "easycap:: %s: " \ + format, __func__, ##args);\ } \ } while (0) +#define JOM(n, format, args...) do { \ + if (n <= debug) { \ + printk(KERN_DEBUG "easycap::%i%s: " \ + format, peasycap->isdongle, __func__, ##args);\ + } \ +} while (0) + #else #define JOT(n, format, args...) do {} while (0) +#define JOM(n, format, args...) do {} while (0) #endif /*EASYCAP_DEBUG*/ #define MICROSECONDS(X, Y) \ diff --git a/drivers/staging/easycap/easycap_debug.h b/drivers/staging/easycap/easycap_debug.h index 3e9b66a66076..a4dcd7dd4a89 100644 --- a/drivers/staging/easycap/easycap_debug.h +++ b/drivers/staging/easycap/easycap_debug.h @@ -1,6 +1,6 @@ /***************************************************************************** * * -* debug.h * +* easycap_debug.h * * * *****************************************************************************/ /* diff --git a/drivers/staging/easycap/easycap_ioctl.c b/drivers/staging/easycap/easycap_ioctl.c index 5b038b8614d7..d91d64ad6f68 100644 --- a/drivers/staging/easycap/easycap_ioctl.c +++ b/drivers/staging/easycap/easycap_ioctl.c @@ -48,8 +48,12 @@ __u16 reg, set; int ir, rc, need; unsigned int itwas, isnow; +if (NULL == peasycap) { + SAY("ERROR: peasycap is NULL\n"); + return -EFAULT; +} if ((struct usb_device *)NULL == peasycap->pusb_device) { - SAY("ERROR: peasycap->pusb_device is NULL\n"); + SAM("ERROR: peasycap->pusb_device is NULL\n"); return -EFAULT; } peasycap_standard = &easycap_standard[0]; @@ -59,25 +63,25 @@ while (0xFFFF != peasycap_standard->mask) { peasycap_standard++; } if (0xFFFF == peasycap_standard->mask) { - SAY("ERROR: 0x%08X=std_id: standard not found\n", \ + SAM("ERROR: 0x%08X=std_id: standard not found\n", \ (unsigned int)std_id); return -EINVAL; } -SAY("user requests standard: %s\n", \ +SAM("user requests standard: %s\n", \ &(peasycap_standard->v4l2_standard.name[0])); if (peasycap->standard_offset == \ (int)(peasycap_standard - &easycap_standard[0])) { - SAY("requested standard already in effect\n"); + SAM("requested standard already in effect\n"); return 0; } peasycap->standard_offset = (int)(peasycap_standard - &easycap_standard[0]); peasycap->fps = peasycap_standard->v4l2_standard.frameperiod.denominator / \ peasycap_standard->v4l2_standard.frameperiod.numerator; if (!peasycap->fps) { - SAY("MISTAKE: frames-per-second is zero\n"); + SAM("MISTAKE: frames-per-second is zero\n"); return -EFAULT; } -JOT(8, "%i frames-per-second\n", peasycap->fps); +JOM(8, "%i frames-per-second\n", peasycap->fps); peasycap->usec = 1000000 / (2 * peasycap->fps); peasycap->tolerate = 1000 * (25 / peasycap->fps); @@ -94,7 +98,7 @@ case NTSC_M_JP: { reg = 0x0A; set = 0x95; ir = read_saa(peasycap->pusb_device, reg); if (0 > ir) - SAY("ERROR: cannot read SAA register 0x%02X\n", reg); + SAM("ERROR: cannot read SAA register 0x%02X\n", reg); else itwas = (unsigned int)ir; @@ -104,15 +108,15 @@ case NTSC_M_JP: { rc = write_saa(peasycap->pusb_device, reg, set); if (0 != rc) - SAY("ERROR: failed to set SAA register " \ + SAM("ERROR: failed to set SAA register " \ "0x%02X to 0x%02X for JP standard\n", reg, set); else { isnow = (unsigned int)read_saa(peasycap->pusb_device, reg); if (0 > ir) - JOT(8, "SAA register 0x%02X changed " \ + JOM(8, "SAA register 0x%02X changed " \ "to 0x%02X\n", reg, isnow); else - JOT(8, "SAA register 0x%02X changed " \ + JOM(8, "SAA register 0x%02X changed " \ "from 0x%02X to 0x%02X\n", reg, itwas, isnow); set2to78(peasycap->pusb_device); @@ -122,7 +126,7 @@ case NTSC_M_JP: { reg = 0x0B; set = 0x48; ir = read_saa(peasycap->pusb_device, reg); if (0 > ir) - SAY("ERROR: cannot read SAA register 0x%02X\n", reg); + SAM("ERROR: cannot read SAA register 0x%02X\n", reg); else itwas = (unsigned int)ir; @@ -130,15 +134,15 @@ case NTSC_M_JP: { rc = write_saa(peasycap->pusb_device, reg, set); if (0 != rc) - SAY("ERROR: failed to set SAA register 0x%02X to 0x%02X " \ + SAM("ERROR: failed to set SAA register 0x%02X to 0x%02X " \ "for JP standard\n", reg, set); else { isnow = (unsigned int)read_saa(peasycap->pusb_device, reg); if (0 > ir) - JOT(8, "SAA register 0x%02X changed " \ + JOM(8, "SAA register 0x%02X changed " \ "to 0x%02X\n", reg, isnow); else - JOT(8, "SAA register 0x%02X changed " \ + JOM(8, "SAA register 0x%02X changed " \ "from 0x%02X to 0x%02X\n", reg, itwas, isnow); set2to78(peasycap->pusb_device); @@ -176,7 +180,7 @@ default: if (need) { ir = read_saa(peasycap->pusb_device, reg); if (0 > ir) - SAY("ERROR: failed to read SAA register 0x%02X\n", reg); + SAM("ERROR: failed to read SAA register 0x%02X\n", reg); else itwas = (unsigned int)ir; @@ -184,15 +188,15 @@ if (need) { rc = write_saa(peasycap->pusb_device, reg, set); if (0 != write_saa(peasycap->pusb_device, reg, set)) { - SAY("ERROR: failed to set SAA register " \ + SAM("ERROR: failed to set SAA register " \ "0x%02X to 0x%02X for table 42\n", reg, set); } else { isnow = (unsigned int)read_saa(peasycap->pusb_device, reg); if (0 > ir) - JOT(8, "SAA register 0x%02X changed " \ + JOM(8, "SAA register 0x%02X changed " \ "to 0x%02X\n", reg, isnow); else - JOT(8, "SAA register 0x%02X changed " \ + JOM(8, "SAA register 0x%02X changed " \ "from 0x%02X to 0x%02X\n", reg, itwas, isnow); } } @@ -204,7 +208,7 @@ if (need) { reg = 0x08; ir = read_saa(peasycap->pusb_device, reg); if (0 > ir) - SAY("ERROR: failed to read SAA register 0x%02X " \ + SAM("ERROR: failed to read SAA register 0x%02X " \ "so cannot reset\n", reg); else { itwas = (unsigned int)ir; @@ -217,13 +221,13 @@ set2to78(peasycap->pusb_device); rc = write_saa(peasycap->pusb_device, reg, set); if (0 != rc) - SAY("ERROR: failed to set SAA register 0x%02X to 0x%02X\n", reg, set); + SAM("ERROR: failed to set SAA register 0x%02X to 0x%02X\n", reg, set); else { isnow = (unsigned int)read_saa(peasycap->pusb_device, reg); if (0 > ir) - JOT(8, "SAA register 0x%02X changed to 0x%02X\n", reg, isnow); + JOM(8, "SAA register 0x%02X changed to 0x%02X\n", reg, isnow); else - JOT(8, "SAA register 0x%02X changed " \ + JOM(8, "SAA register 0x%02X changed " \ "from 0x%02X to 0x%02X\n", reg, itwas, isnow); } } @@ -235,7 +239,7 @@ else { reg = 0x40; ir = read_saa(peasycap->pusb_device, reg); if (0 > ir) - SAY("ERROR: failed to read SAA register 0x%02X " \ + SAM("ERROR: failed to read SAA register 0x%02X " \ "so cannot reset\n", reg); else { itwas = (unsigned int)ir; @@ -248,13 +252,13 @@ set2to78(peasycap->pusb_device); rc = write_saa(peasycap->pusb_device, reg, set); if (0 != rc) - SAY("ERROR: failed to set SAA register 0x%02X to 0x%02X\n", reg, set); + SAM("ERROR: failed to set SAA register 0x%02X to 0x%02X\n", reg, set); else { isnow = (unsigned int)read_saa(peasycap->pusb_device, reg); if (0 > ir) - JOT(8, "SAA register 0x%02X changed to 0x%02X\n", reg, isnow); + JOM(8, "SAA register 0x%02X changed to 0x%02X\n", reg, isnow); else - JOT(8, "SAA register 0x%02X changed " \ + JOM(8, "SAA register 0x%02X changed " \ "from 0x%02X to 0x%02X\n", reg, itwas, isnow); } } @@ -266,7 +270,7 @@ else { reg = 0x5A; ir = read_saa(peasycap->pusb_device, reg); if (0 > ir) - SAY("ERROR: failed to read SAA register 0x%02X but continuing\n", reg); + SAM("ERROR: failed to read SAA register 0x%02X but continuing\n", reg); itwas = (unsigned int)ir; if (peasycap_standard->mask & 0x0001) set = 0x0A ; @@ -276,19 +280,19 @@ if (0 > ir) set2to78(peasycap->pusb_device); if (0 != write_saa(peasycap->pusb_device, reg, set)) - SAY("ERROR: failed to set SAA register 0x%02X to 0x%02X\n", \ + SAM("ERROR: failed to set SAA register 0x%02X to 0x%02X\n", \ reg, set); else { isnow = (unsigned int)read_saa(peasycap->pusb_device, reg); if (0 > ir) - JOT(8, "SAA register 0x%02X changed " + JOM(8, "SAA register 0x%02X changed " "to 0x%02X\n", reg, isnow); else - JOT(8, "SAA register 0x%02X changed " + JOM(8, "SAA register 0x%02X changed " "from 0x%02X to 0x%02X\n", reg, itwas, isnow); } if (0 != check_saa(peasycap->pusb_device)) - SAY("ERROR: check_saa() failed\n"); + SAM("ERROR: check_saa() failed\n"); return 0; } /*****************************************************************************/ @@ -325,28 +329,28 @@ int miss, multiplier, best; char bf[5], *pc; __u32 uc; -if ((struct easycap *)NULL == peasycap) { +if (NULL == peasycap) { SAY("ERROR: peasycap is NULL\n"); return -EFAULT; } p = peasycap->pusb_device; if ((struct usb_device *)NULL == p) { - SAY("ERROR: peaycap->pusb_device is NULL\n"); + SAM("ERROR: peaycap->pusb_device is NULL\n"); return -EFAULT; } pc = &bf[0]; uc = pixelformat; memcpy((void *)pc, (void *)(&uc), 4); bf[4] = 0; mask = easycap_standard[peasycap->standard_offset].mask; -SAY("sought: %ix%i,%s(0x%08X),%i=field,0x%02X=std mask\n", \ +SAM("sought: %ix%i,%s(0x%08X),%i=field,0x%02X=std mask\n", \ width, height, pc, pixelformat, field, mask); if (V4L2_FIELD_ANY == field) { field = V4L2_FIELD_INTERLACED; - SAY("prefer: V4L2_FIELD_INTERLACED=field, was V4L2_FIELD_ANY\n"); + SAM("prefer: V4L2_FIELD_INTERLACED=field, was V4L2_FIELD_ANY\n"); } peasycap_best_format = (struct easycap_format *)NULL; peasycap_format = &easycap_format[0]; while (0 != peasycap_format->v4l2_format.fmt.pix.width) { - JOT(16, ".> %i %i 0x%08X %ix%i\n", \ + JOM(16, ".> %i %i 0x%08X %ix%i\n", \ peasycap_format->mask & 0x01, peasycap_format->v4l2_format.fmt.pix.field, peasycap_format->v4l2_format.fmt.pix.pixelformat, @@ -365,7 +369,7 @@ while (0 != peasycap_format->v4l2_format.fmt.pix.width) { peasycap_format++; } if (0 == peasycap_format->v4l2_format.fmt.pix.width) { - SAY("cannot do: %ix%i with standard mask 0x%02X\n", \ + SAM("cannot do: %ix%i with standard mask 0x%02X\n", \ width, height, mask); peasycap_format = &easycap_format[0]; best = -1; while (0 != peasycap_format->v4l2_format.fmt.pix.width) { @@ -386,16 +390,16 @@ if (0 == peasycap_format->v4l2_format.fmt.pix.width) { peasycap_format++; } if (-1 == best) { - SAY("cannot do %ix... with standard mask 0x%02X\n", \ + SAM("cannot do %ix... with standard mask 0x%02X\n", \ width, mask); - SAY("cannot do ...x%i with standard mask 0x%02X\n", \ + SAM("cannot do ...x%i with standard mask 0x%02X\n", \ height, mask); - SAY(" %ix%i unmatched\n", width, height); + SAM(" %ix%i unmatched\n", width, height); return peasycap->format_offset; } } if ((struct easycap_format *)NULL == peasycap_best_format) { - SAY("MISTAKE: peasycap_best_format is NULL"); + SAM("MISTAKE: peasycap_best_format is NULL"); return -EINVAL; } peasycap_format = peasycap_best_format; @@ -406,10 +410,10 @@ if (true == try) /*...........................................................................*/ if (false != try) { - SAY("MISTAKE: true==try where is should be false\n"); + SAM("MISTAKE: true==try where is should be false\n"); return -EINVAL; } -SAY("actioning: %ix%i %s\n", \ +SAM("actioning: %ix%i %s\n", \ peasycap_format->v4l2_format.fmt.pix.width, \ peasycap_format->v4l2_format.fmt.pix.height, &peasycap_format->name[0]); @@ -441,7 +445,7 @@ peasycap->frame_buffer_used = peasycap->bytesperpixel * \ peasycap->width * peasycap->height; if (true == peasycap->offerfields) { - SAY("WARNING: %i=peasycap->field is untested: " \ + SAM("WARNING: %i=peasycap->field is untested: " \ "please report problems\n", peasycap->field); @@ -474,13 +478,13 @@ if (0 == (0x01 & peasycap_format->mask)) { (288 == \ peasycap_format->v4l2_format.fmt.pix.height))) { if (0 != set_resolution(p, 0x0000, 0x0001, 0x05A0, 0x0121)) { - SAY("ERROR: set_resolution() failed\n"); + SAM("ERROR: set_resolution() failed\n"); return -EINVAL; } } else if ((704 == peasycap_format->v4l2_format.fmt.pix.width) && \ (576 == peasycap_format->v4l2_format.fmt.pix.height)) { if (0 != set_resolution(p, 0x0004, 0x0001, 0x0584, 0x0121)) { - SAY("ERROR: set_resolution() failed\n"); + SAM("ERROR: set_resolution() failed\n"); return -EINVAL; } } else if (((640 == peasycap_format->v4l2_format.fmt.pix.width) && \ @@ -491,11 +495,11 @@ if (0 == (0x01 & peasycap_format->mask)) { (240 == \ peasycap_format->v4l2_format.fmt.pix.height))) { if (0 != set_resolution(p, 0x0014, 0x0020, 0x0514, 0x0110)) { - SAY("ERROR: set_resolution() failed\n"); + SAM("ERROR: set_resolution() failed\n"); return -EINVAL; } } else { - SAY("MISTAKE: bad format, cannot set resolution\n"); + SAM("MISTAKE: bad format, cannot set resolution\n"); return -EINVAL; } /*---------------------------------------------------------------------------*/ @@ -512,7 +516,7 @@ if (0 == (0x01 & peasycap_format->mask)) { (240 == \ peasycap_format->v4l2_format.fmt.pix.height))) { if (0 != set_resolution(p, 0x0000, 0x0003, 0x05A0, 0x00F3)) { - SAY("ERROR: set_resolution() failed\n"); + SAM("ERROR: set_resolution() failed\n"); return -EINVAL; } } else if (((640 == peasycap_format->v4l2_format.fmt.pix.width) && \ @@ -523,11 +527,11 @@ if (0 == (0x01 & peasycap_format->mask)) { (240 == \ peasycap_format->v4l2_format.fmt.pix.height))) { if (0 != set_resolution(p, 0x0014, 0x0003, 0x0514, 0x00F3)) { - SAY("ERROR: set_resolution() failed\n"); + SAM("ERROR: set_resolution() failed\n"); return -EINVAL; } } else { - SAY("MISTAKE: bad format, cannot set resolution\n"); + SAM("MISTAKE: bad format, cannot set resolution\n"); return -EINVAL; } } @@ -543,8 +547,12 @@ int adjust_brightness(struct easycap *peasycap, int value) unsigned int mood; int i1; +if (NULL == peasycap) { + SAY("ERROR: peasycap is NULL\n"); + return -EFAULT; +} if ((struct usb_device *)NULL == peasycap->pusb_device) { - SAY("ERROR: peasycap->pusb_device is NULL\n"); + SAM("ERROR: peasycap->pusb_device is NULL\n"); return -EFAULT; } i1 = 0; @@ -559,10 +567,10 @@ while (0xFFFFFFFF != easycap_control[i1].id) { set2to78(peasycap->pusb_device); if (!write_saa(peasycap->pusb_device, 0x0A, mood)) { - SAY("adjusting brightness to 0x%02X\n", mood); + SAM("adjusting brightness to 0x%02X\n", mood); return 0; } else { - SAY("WARNING: failed to adjust brightness " \ + SAM("WARNING: failed to adjust brightness " \ "to 0x%02X\n", mood); return -ENOENT; } @@ -573,7 +581,7 @@ while (0xFFFFFFFF != easycap_control[i1].id) { } i1++; } -SAY("WARNING: failed to adjust brightness: control not found\n"); +SAM("WARNING: failed to adjust brightness: control not found\n"); return -ENOENT; } /*****************************************************************************/ @@ -582,8 +590,12 @@ int adjust_contrast(struct easycap *peasycap, int value) unsigned int mood; int i1; +if (NULL == peasycap) { + SAY("ERROR: peasycap is NULL\n"); + return -EFAULT; +} if ((struct usb_device *)NULL == peasycap->pusb_device) { - SAY("ERROR: peasycap->pusb_device is NULL\n"); + SAM("ERROR: peasycap->pusb_device is NULL\n"); return -EFAULT; } i1 = 0; @@ -598,10 +610,10 @@ while (0xFFFFFFFF != easycap_control[i1].id) { set2to78(peasycap->pusb_device); if (!write_saa(peasycap->pusb_device, 0x0B, mood)) { - SAY("adjusting contrast to 0x%02X\n", mood); + SAM("adjusting contrast to 0x%02X\n", mood); return 0; } else { - SAY("WARNING: failed to adjust contrast to " \ + SAM("WARNING: failed to adjust contrast to " \ "0x%02X\n", mood); return -ENOENT; } @@ -612,7 +624,7 @@ while (0xFFFFFFFF != easycap_control[i1].id) { } i1++; } -SAY("WARNING: failed to adjust contrast: control not found\n"); +SAM("WARNING: failed to adjust contrast: control not found\n"); return -ENOENT; } /*****************************************************************************/ @@ -621,8 +633,12 @@ int adjust_saturation(struct easycap *peasycap, int value) unsigned int mood; int i1; +if (NULL == peasycap) { + SAY("ERROR: peasycap is NULL\n"); + return -EFAULT; +} if ((struct usb_device *)NULL == peasycap->pusb_device) { - SAY("ERROR: peasycap->pusb_device is NULL\n"); + SAM("ERROR: peasycap->pusb_device is NULL\n"); return -EFAULT; } i1 = 0; @@ -637,10 +653,10 @@ while (0xFFFFFFFF != easycap_control[i1].id) { set2to78(peasycap->pusb_device); if (!write_saa(peasycap->pusb_device, 0x0C, mood)) { - SAY("adjusting saturation to 0x%02X\n", mood); + SAM("adjusting saturation to 0x%02X\n", mood); return 0; } else { - SAY("WARNING: failed to adjust saturation to " \ + SAM("WARNING: failed to adjust saturation to " \ "0x%02X\n", mood); return -ENOENT; } @@ -651,7 +667,7 @@ while (0xFFFFFFFF != easycap_control[i1].id) { } i1++; } -SAY("WARNING: failed to adjust saturation: control not found\n"); +SAM("WARNING: failed to adjust saturation: control not found\n"); return -ENOENT; } /*****************************************************************************/ @@ -660,8 +676,12 @@ int adjust_hue(struct easycap *peasycap, int value) unsigned int mood; int i1, i2; +if (NULL == peasycap) { + SAY("ERROR: peasycap is NULL\n"); + return -EFAULT; +} if ((struct usb_device *)NULL == peasycap->pusb_device) { - SAY("ERROR: peasycap->pusb_device is NULL\n"); + SAM("ERROR: peasycap->pusb_device is NULL\n"); return -EFAULT; } i1 = 0; @@ -677,10 +697,10 @@ while (0xFFFFFFFF != easycap_control[i1].id) { set2to78(peasycap->pusb_device); if (!write_saa(peasycap->pusb_device, 0x0D, mood)) { - SAY("adjusting hue to 0x%02X\n", mood); + SAM("adjusting hue to 0x%02X\n", mood); return 0; } else { - SAY("WARNING: failed to adjust hue to 0x%02X\n", mood); + SAM("WARNING: failed to adjust hue to 0x%02X\n", mood); return -ENOENT; } @@ -690,7 +710,7 @@ while (0xFFFFFFFF != easycap_control[i1].id) { } i1++; } -SAY("WARNING: failed to adjust hue: control not found\n"); +SAM("WARNING: failed to adjust hue: control not found\n"); return -ENOENT; } /*****************************************************************************/ @@ -699,8 +719,12 @@ int adjust_volume(struct easycap *peasycap, int value) __s8 mood; int i1; +if (NULL == peasycap) { + SAY("ERROR: peasycap is NULL\n"); + return -EFAULT; +} if ((struct usb_device *)NULL == peasycap->pusb_device) { - SAY("ERROR: peasycap->pusb_device is NULL\n"); + SAM("ERROR: peasycap->pusb_device is NULL\n"); return -EFAULT; } i1 = 0; @@ -714,10 +738,10 @@ while (0xFFFFFFFF != easycap_control[i1].id) { ((31 < peasycap->volume) ? 31 : \ (__s8) peasycap->volume); if (!audio_gainset(peasycap->pusb_device, mood)) { - SAY("adjusting volume to 0x%01X\n", mood); + SAM("adjusting volume to 0x%01X\n", mood); return 0; } else { - SAY("WARNING: failed to adjust volume to " \ + SAM("WARNING: failed to adjust volume to " \ "0x%1X\n", mood); return -ENOENT; } @@ -725,7 +749,7 @@ while (0xFFFFFFFF != easycap_control[i1].id) { } i1++; } -SAY("WARNING: failed to adjust volume: control not found\n"); +SAM("WARNING: failed to adjust volume: control not found\n"); return -ENOENT; } /*****************************************************************************/ @@ -744,8 +768,12 @@ int adjust_mute(struct easycap *peasycap, int value) { int i1; +if (NULL == peasycap) { + SAY("ERROR: peasycap is NULL\n"); + return -EFAULT; +} if ((struct usb_device *)NULL == peasycap->pusb_device) { - SAY("ERROR: peasycap->pusb_device is NULL\n"); + SAM("ERROR: peasycap->pusb_device is NULL\n"); return -EFAULT; } i1 = 0; @@ -756,13 +784,13 @@ while (0xFFFFFFFF != easycap_control[i1].id) { case 1: { peasycap->audio_idle = 1; peasycap->timeval0.tv_sec = 0; - SAY("adjusting mute: %i=peasycap->audio_idle\n", \ + SAM("adjusting mute: %i=peasycap->audio_idle\n", \ peasycap->audio_idle); return 0; } default: { peasycap->audio_idle = 0; - SAY("adjusting mute: %i=peasycap->audio_idle\n", \ + SAM("adjusting mute: %i=peasycap->audio_idle\n", \ peasycap->audio_idle); return 0; } @@ -771,26 +799,28 @@ while (0xFFFFFFFF != easycap_control[i1].id) { } i1++; } -SAY("WARNING: failed to adjust mute: control not found\n"); +SAM("WARNING: failed to adjust mute: control not found\n"); return -ENOENT; } - -/*--------------------------------------------------------------------------*/ +/*****************************************************************************/ static int easycap_ioctl_bkl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { static struct easycap *peasycap; static struct usb_device *p; -static __u32 isequence; +if (NULL == file) { + SAY("ERROR: file is NULL\n"); + return -ERESTARTSYS; +} peasycap = file->private_data; if (NULL == peasycap) { - SAY("ERROR: peasycap is NULL\n"); + SAY("ERROR: peasycap is NULL.\n"); return -1; } p = peasycap->pusb_device; -if ((struct usb_device *)NULL == p) { - SAY("ERROR: peasycap->pusb_device is NULL\n"); +if (NULL == p) { + SAM("ERROR: peasycap->pusb_device is NULL\n"); return -EFAULT; } /*---------------------------------------------------------------------------*/ @@ -803,15 +833,15 @@ if ((struct usb_device *)NULL == p) { /*---------------------------------------------------------------------------*/ switch (cmd) { case VIDIOC_QUERYCAP: { - static struct v4l2_capability v4l2_capability; - static char version[16], *p1, *p2; - static int i, rc, k[3]; - static long lng; + struct v4l2_capability v4l2_capability; + char version[16], *p1, *p2; + int i, rc, k[3]; + long lng; - JOT(8, "VIDIOC_QUERYCAP\n"); + JOM(8, "VIDIOC_QUERYCAP\n"); if (16 <= strlen(EASYCAP_DRIVER_VERSION)) { - SAY("ERROR: bad driver version string\n"); return -EINVAL; + SAM("ERROR: bad driver version string\n"); return -EINVAL; } strcpy(&version[0], EASYCAP_DRIVER_VERSION); for (i = 0; i < 3; i++) @@ -826,7 +856,7 @@ case VIDIOC_QUERYCAP: { if (3 > i) { rc = (int) strict_strtol(p1, 10, &lng); if (0 != rc) { - SAY("ERROR: %i=strict_strtol(%s,.,,)\n", \ + SAM("ERROR: %i=strict_strtol(%s,.,,)\n", \ rc, p1); return -EINVAL; } @@ -844,7 +874,7 @@ case VIDIOC_QUERYCAP: { V4L2_CAP_AUDIO | V4L2_CAP_READWRITE; v4l2_capability.version = KERNEL_VERSION(k[0], k[1], k[2]); - JOT(8, "v4l2_capability.version=(%i,%i,%i)\n", k[0], k[1], k[2]); + JOM(8, "v4l2_capability.version=(%i,%i,%i)\n", k[0], k[1], k[2]); strlcpy(&v4l2_capability.card[0], "EasyCAP DC60", \ sizeof(v4l2_capability.card)); @@ -853,7 +883,7 @@ case VIDIOC_QUERYCAP: { sizeof(v4l2_capability.bus_info)) < 0) { strlcpy(&v4l2_capability.bus_info[0], "EasyCAP bus_info", \ sizeof(v4l2_capability.bus_info)); - JOT(8, "%s=v4l2_capability.bus_info\n", \ + JOM(8, "%s=v4l2_capability.bus_info\n", \ &v4l2_capability.bus_info[0]); } if (0 != copy_to_user((void __user *)arg, &v4l2_capability, \ @@ -863,10 +893,10 @@ case VIDIOC_QUERYCAP: { } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ case VIDIOC_ENUMINPUT: { - static struct v4l2_input v4l2_input; - static __u32 index; + struct v4l2_input v4l2_input; + __u32 index; - JOT(8, "VIDIOC_ENUMINPUT\n"); + JOM(8, "VIDIOC_ENUMINPUT\n"); if (0 != copy_from_user(&v4l2_input, (void __user *)arg, \ sizeof(struct v4l2_input))) @@ -885,7 +915,7 @@ case VIDIOC_ENUMINPUT: { v4l2_input.std = V4L2_STD_PAL | V4L2_STD_SECAM | \ V4L2_STD_NTSC ; v4l2_input.status = 0; - JOT(8, "%i=index: %s\n", index, &v4l2_input.name[0]); + JOM(8, "%i=index: %s\n", index, &v4l2_input.name[0]); break; } case 1: { @@ -897,7 +927,7 @@ case VIDIOC_ENUMINPUT: { v4l2_input.std = V4L2_STD_PAL | V4L2_STD_SECAM | \ V4L2_STD_NTSC ; v4l2_input.status = 0; - JOT(8, "%i=index: %s\n", index, &v4l2_input.name[0]); + JOM(8, "%i=index: %s\n", index, &v4l2_input.name[0]); break; } case 2: { @@ -909,7 +939,7 @@ case VIDIOC_ENUMINPUT: { v4l2_input.std = V4L2_STD_PAL | V4L2_STD_SECAM | \ V4L2_STD_NTSC ; v4l2_input.status = 0; - JOT(8, "%i=index: %s\n", index, &v4l2_input.name[0]); + JOM(8, "%i=index: %s\n", index, &v4l2_input.name[0]); break; } case 3: { @@ -921,7 +951,7 @@ case VIDIOC_ENUMINPUT: { v4l2_input.std = V4L2_STD_PAL | V4L2_STD_SECAM | \ V4L2_STD_NTSC ; v4l2_input.status = 0; - JOT(8, "%i=index: %s\n", index, &v4l2_input.name[0]); + JOM(8, "%i=index: %s\n", index, &v4l2_input.name[0]); break; } case 4: { @@ -933,7 +963,7 @@ case VIDIOC_ENUMINPUT: { v4l2_input.std = V4L2_STD_PAL | V4L2_STD_SECAM | \ V4L2_STD_NTSC ; v4l2_input.status = 0; - JOT(8, "%i=index: %s\n", index, &v4l2_input.name[0]); + JOM(8, "%i=index: %s\n", index, &v4l2_input.name[0]); break; } case 5: { @@ -945,11 +975,11 @@ case VIDIOC_ENUMINPUT: { v4l2_input.std = V4L2_STD_PAL | V4L2_STD_SECAM | \ V4L2_STD_NTSC ; v4l2_input.status = 0; - JOT(8, "%i=index: %s\n", index, &v4l2_input.name[0]); + JOM(8, "%i=index: %s\n", index, &v4l2_input.name[0]); break; } default: { - JOT(8, "%i=index: exhausts inputs\n", index); + JOM(8, "%i=index: exhausts inputs\n", index); return -EINVAL; } } @@ -961,11 +991,11 @@ case VIDIOC_ENUMINPUT: { } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ case VIDIOC_G_INPUT: { - static __u32 index; + __u32 index; - JOT(8, "VIDIOC_G_INPUT\n"); + JOM(8, "VIDIOC_G_INPUT\n"); index = (__u32)peasycap->input; - JOT(8, "user is told: %i\n", index); + JOM(8, "user is told: %i\n", index); if (0 != copy_to_user((void __user *)arg, &index, sizeof(__u32))) return -EFAULT; break; @@ -973,22 +1003,22 @@ case VIDIOC_G_INPUT: { /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ case VIDIOC_S_INPUT: { - static __u32 index; + __u32 index; - JOT(8, "VIDIOC_S_INPUT\n"); + JOM(8, "VIDIOC_S_INPUT\n"); if (0 != copy_from_user(&index, (void __user *)arg, sizeof(__u32))) return -EFAULT; - JOT(8, "user requests input %i\n", index); + JOM(8, "user requests input %i\n", index); if ((int)index == peasycap->input) { - SAY("requested input already in effect\n"); + SAM("requested input already in effect\n"); break; } if ((0 > index) || (5 < index)) { - JOT(8, "ERROR: bad requested input: %i\n", index); + JOM(8, "ERROR: bad requested input: %i\n", index); return -EINVAL; } peasycap->input = (int)index; @@ -999,14 +1029,14 @@ case VIDIOC_S_INPUT: } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ case VIDIOC_ENUMAUDIO: { - JOT(8, "VIDIOC_ENUMAUDIO\n"); + JOM(8, "VIDIOC_ENUMAUDIO\n"); return -EINVAL; } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ case VIDIOC_ENUMAUDOUT: { - static struct v4l2_audioout v4l2_audioout; + struct v4l2_audioout v4l2_audioout; - JOT(8, "VIDIOC_ENUMAUDOUT\n"); + JOM(8, "VIDIOC_ENUMAUDOUT\n"); if (0 != copy_from_user(&v4l2_audioout, (void __user *)arg, \ sizeof(struct v4l2_audioout))) @@ -1025,10 +1055,10 @@ case VIDIOC_ENUMAUDOUT: { } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ case VIDIOC_QUERYCTRL: { - static int i1; - static struct v4l2_queryctrl v4l2_queryctrl; + int i1; + struct v4l2_queryctrl v4l2_queryctrl; - JOT(8, "VIDIOC_QUERYCTRL\n"); + JOM(8, "VIDIOC_QUERYCTRL\n"); if (0 != copy_from_user(&v4l2_queryctrl, (void __user *)arg, \ sizeof(struct v4l2_queryctrl))) @@ -1037,7 +1067,7 @@ case VIDIOC_QUERYCTRL: { i1 = 0; while (0xFFFFFFFF != easycap_control[i1].id) { if (easycap_control[i1].id == v4l2_queryctrl.id) { - JOT(8, "VIDIOC_QUERYCTRL %s=easycap_control[%i]" \ + JOM(8, "VIDIOC_QUERYCTRL %s=easycap_control[%i]" \ ".name\n", &easycap_control[i1].name[0], i1); memcpy(&v4l2_queryctrl, &easycap_control[i1], \ sizeof(struct v4l2_queryctrl)); @@ -1046,7 +1076,7 @@ case VIDIOC_QUERYCTRL: { i1++; } if (0xFFFFFFFF == easycap_control[i1].id) { - JOT(8, "%i=index: exhausts controls\n", i1); + JOM(8, "%i=index: exhausts controls\n", i1); return -EINVAL; } if (0 != copy_to_user((void __user *)arg, &v4l2_queryctrl, \ @@ -1056,15 +1086,15 @@ case VIDIOC_QUERYCTRL: { } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ case VIDIOC_QUERYMENU: { - JOT(8, "VIDIOC_QUERYMENU unsupported\n"); + JOM(8, "VIDIOC_QUERYMENU unsupported\n"); return -EINVAL; break; } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ case VIDIOC_G_CTRL: { - static struct v4l2_control v4l2_control; + struct v4l2_control v4l2_control; - JOT(8, "VIDIOC_G_CTRL\n"); + JOM(8, "VIDIOC_G_CTRL\n"); if (0 != copy_from_user(&v4l2_control, (void __user *)arg, \ sizeof(struct v4l2_control))) @@ -1073,27 +1103,27 @@ case VIDIOC_G_CTRL: { switch (v4l2_control.id) { case V4L2_CID_BRIGHTNESS: { v4l2_control.value = peasycap->brightness; - JOT(8, "user enquires brightness: %i\n", v4l2_control.value); + JOM(8, "user enquires brightness: %i\n", v4l2_control.value); break; } case V4L2_CID_CONTRAST: { v4l2_control.value = peasycap->contrast; - JOT(8, "user enquires contrast: %i\n", v4l2_control.value); + JOM(8, "user enquires contrast: %i\n", v4l2_control.value); break; } case V4L2_CID_SATURATION: { v4l2_control.value = peasycap->saturation; - JOT(8, "user enquires saturation: %i\n", v4l2_control.value); + JOM(8, "user enquires saturation: %i\n", v4l2_control.value); break; } case V4L2_CID_HUE: { v4l2_control.value = peasycap->hue; - JOT(8, "user enquires hue: %i\n", v4l2_control.value); + JOM(8, "user enquires hue: %i\n", v4l2_control.value); break; } case V4L2_CID_AUDIO_VOLUME: { v4l2_control.value = peasycap->volume; - JOT(8, "user enquires volume: %i\n", v4l2_control.value); + JOM(8, "user enquires volume: %i\n", v4l2_control.value); break; } case V4L2_CID_AUDIO_MUTE: { @@ -1101,11 +1131,11 @@ case VIDIOC_G_CTRL: { v4l2_control.value = true; else v4l2_control.value = false; - JOT(8, "user enquires mute: %i\n", v4l2_control.value); + JOM(8, "user enquires mute: %i\n", v4l2_control.value); break; } default: { - SAY("ERROR: unknown V4L2 control: 0x%08X=id\n", \ + SAM("ERROR: unknown V4L2 control: 0x%08X=id\n", \ v4l2_control.id); return -EINVAL; } @@ -1118,14 +1148,14 @@ case VIDIOC_G_CTRL: { /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ #if defined(VIDIOC_S_CTRL_OLD) case VIDIOC_S_CTRL_OLD: { - JOT(8, "VIDIOC_S_CTRL_OLD required at least for xawtv\n"); + JOM(8, "VIDIOC_S_CTRL_OLD required at least for xawtv\n"); } #endif /*VIDIOC_S_CTRL_OLD*/ case VIDIOC_S_CTRL: { - static struct v4l2_control v4l2_control; + struct v4l2_control v4l2_control; - JOT(8, "VIDIOC_S_CTRL\n"); + JOM(8, "VIDIOC_S_CTRL\n"); if (0 != copy_from_user(&v4l2_control, (void __user *)arg, \ sizeof(struct v4l2_control))) @@ -1133,31 +1163,31 @@ case VIDIOC_S_CTRL: switch (v4l2_control.id) { case V4L2_CID_BRIGHTNESS: { - JOT(8, "user requests brightness %i\n", v4l2_control.value); + JOM(8, "user requests brightness %i\n", v4l2_control.value); if (0 != adjust_brightness(peasycap, v4l2_control.value)) ; break; } case V4L2_CID_CONTRAST: { - JOT(8, "user requests contrast %i\n", v4l2_control.value); + JOM(8, "user requests contrast %i\n", v4l2_control.value); if (0 != adjust_contrast(peasycap, v4l2_control.value)) ; break; } case V4L2_CID_SATURATION: { - JOT(8, "user requests saturation %i\n", v4l2_control.value); + JOM(8, "user requests saturation %i\n", v4l2_control.value); if (0 != adjust_saturation(peasycap, v4l2_control.value)) ; break; } case V4L2_CID_HUE: { - JOT(8, "user requests hue %i\n", v4l2_control.value); + JOM(8, "user requests hue %i\n", v4l2_control.value); if (0 != adjust_hue(peasycap, v4l2_control.value)) ; break; } case V4L2_CID_AUDIO_VOLUME: { - JOT(8, "user requests volume %i\n", v4l2_control.value); + JOM(8, "user requests volume %i\n", v4l2_control.value); if (0 != adjust_volume(peasycap, v4l2_control.value)) ; break; @@ -1165,18 +1195,18 @@ case VIDIOC_S_CTRL: case V4L2_CID_AUDIO_MUTE: { int mute; - JOT(8, "user requests mute %i\n", v4l2_control.value); + JOM(8, "user requests mute %i\n", v4l2_control.value); if (true == v4l2_control.value) mute = 1; else mute = 0; if (0 != adjust_mute(peasycap, mute)) - SAY("WARNING: failed to adjust mute to %i\n", mute); + SAM("WARNING: failed to adjust mute to %i\n", mute); break; } default: { - SAY("ERROR: unknown V4L2 control: 0x%08X=id\n", \ + SAM("ERROR: unknown V4L2 control: 0x%08X=id\n", \ v4l2_control.id); return -EINVAL; } @@ -1185,15 +1215,15 @@ case VIDIOC_S_CTRL: } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ case VIDIOC_S_EXT_CTRLS: { - JOT(8, "VIDIOC_S_EXT_CTRLS unsupported\n"); + JOM(8, "VIDIOC_S_EXT_CTRLS unsupported\n"); return -EINVAL; } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ case VIDIOC_ENUM_FMT: { - static __u32 index; - static struct v4l2_fmtdesc v4l2_fmtdesc; + __u32 index; + struct v4l2_fmtdesc v4l2_fmtdesc; - JOT(8, "VIDIOC_ENUM_FMT\n"); + JOM(8, "VIDIOC_ENUM_FMT\n"); if (0 != copy_from_user(&v4l2_fmtdesc, (void __user *)arg, \ sizeof(struct v4l2_fmtdesc))) @@ -1210,46 +1240,46 @@ case VIDIOC_ENUM_FMT: { v4l2_fmtdesc.flags = 0; strcpy(&v4l2_fmtdesc.description[0], "uyvy"); v4l2_fmtdesc.pixelformat = V4L2_PIX_FMT_UYVY; - JOT(8, "%i=index: %s\n", index, &v4l2_fmtdesc.description[0]); + JOM(8, "%i=index: %s\n", index, &v4l2_fmtdesc.description[0]); break; } case 1: { v4l2_fmtdesc.flags = 0; strcpy(&v4l2_fmtdesc.description[0], "yuy2"); v4l2_fmtdesc.pixelformat = V4L2_PIX_FMT_YUYV; - JOT(8, "%i=index: %s\n", index, &v4l2_fmtdesc.description[0]); + JOM(8, "%i=index: %s\n", index, &v4l2_fmtdesc.description[0]); break; } case 2: { v4l2_fmtdesc.flags = 0; strcpy(&v4l2_fmtdesc.description[0], "rgb24"); v4l2_fmtdesc.pixelformat = V4L2_PIX_FMT_RGB24; - JOT(8, "%i=index: %s\n", index, &v4l2_fmtdesc.description[0]); + JOM(8, "%i=index: %s\n", index, &v4l2_fmtdesc.description[0]); break; } case 3: { v4l2_fmtdesc.flags = 0; strcpy(&v4l2_fmtdesc.description[0], "rgb32"); v4l2_fmtdesc.pixelformat = V4L2_PIX_FMT_RGB32; - JOT(8, "%i=index: %s\n", index, &v4l2_fmtdesc.description[0]); + JOM(8, "%i=index: %s\n", index, &v4l2_fmtdesc.description[0]); break; } case 4: { v4l2_fmtdesc.flags = 0; strcpy(&v4l2_fmtdesc.description[0], "bgr24"); v4l2_fmtdesc.pixelformat = V4L2_PIX_FMT_BGR24; - JOT(8, "%i=index: %s\n", index, &v4l2_fmtdesc.description[0]); + JOM(8, "%i=index: %s\n", index, &v4l2_fmtdesc.description[0]); break; } case 5: { v4l2_fmtdesc.flags = 0; strcpy(&v4l2_fmtdesc.description[0], "bgr32"); v4l2_fmtdesc.pixelformat = V4L2_PIX_FMT_BGR32; - JOT(8, "%i=index: %s\n", index, &v4l2_fmtdesc.description[0]); + JOM(8, "%i=index: %s\n", index, &v4l2_fmtdesc.description[0]); break; } default: { - JOT(8, "%i=index: exhausts formats\n", index); + JOM(8, "%i=index: exhausts formats\n", index); return -EINVAL; } } @@ -1260,19 +1290,19 @@ case VIDIOC_ENUM_FMT: { } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ case VIDIOC_ENUM_FRAMESIZES: { - JOT(8, "VIDIOC_ENUM_FRAMESIZES unsupported\n"); + JOM(8, "VIDIOC_ENUM_FRAMESIZES unsupported\n"); return -EINVAL; } case VIDIOC_ENUM_FRAMEINTERVALS: { - JOT(8, "VIDIOC_ENUM_FRAME_INTERVALS unsupported\n"); + JOM(8, "VIDIOC_ENUM_FRAME_INTERVALS unsupported\n"); return -EINVAL; } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ case VIDIOC_G_FMT: { - static struct v4l2_format v4l2_format; - static struct v4l2_pix_format v4l2_pix_format; + struct v4l2_format v4l2_format; + struct v4l2_pix_format v4l2_pix_format; - JOT(8, "VIDIOC_G_FMT\n"); + JOM(8, "VIDIOC_G_FMT\n"); if (0 != copy_from_user(&v4l2_format, (void __user *)arg, \ sizeof(struct v4l2_format))) @@ -1286,7 +1316,7 @@ case VIDIOC_G_FMT: { memcpy(&(v4l2_format.fmt.pix), \ &(easycap_format[peasycap->format_offset]\ .v4l2_format.fmt.pix), sizeof(v4l2_pix_format)); - JOT(8, "user is told: %s\n", \ + JOM(8, "user is told: %s\n", \ &easycap_format[peasycap->format_offset].name[0]); if (0 != copy_to_user((void __user *)arg, &v4l2_format, \ @@ -1297,16 +1327,16 @@ case VIDIOC_G_FMT: { /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ case VIDIOC_TRY_FMT: case VIDIOC_S_FMT: { - static struct v4l2_format v4l2_format; - static struct v4l2_pix_format v4l2_pix_format; - static bool try; - static int best_format; + struct v4l2_format v4l2_format; + struct v4l2_pix_format v4l2_pix_format; + bool try; + int best_format; if (VIDIOC_TRY_FMT == cmd) { - JOT(8, "VIDIOC_TRY_FMT\n"); + JOM(8, "VIDIOC_TRY_FMT\n"); try = true; } else { - JOT(8, "VIDIOC_S_FMT\n"); + JOM(8, "VIDIOC_S_FMT\n"); try = false; } @@ -1321,7 +1351,7 @@ case VIDIOC_S_FMT: { v4l2_format.fmt.pix.field, \ try); if (0 > best_format) { - JOT(8, "WARNING: adjust_format() returned %i\n", best_format); + JOM(8, "WARNING: adjust_format() returned %i\n", best_format); return -ENOENT; } /*...........................................................................*/ @@ -1330,7 +1360,7 @@ case VIDIOC_S_FMT: { memcpy(&(v4l2_format.fmt.pix), &(easycap_format[best_format]\ .v4l2_format.fmt.pix), sizeof(v4l2_pix_format)); - JOT(8, "user is told: %s\n", &easycap_format[best_format].name[0]); + JOM(8, "user is told: %s\n", &easycap_format[best_format].name[0]); if (0 != copy_to_user((void __user *)arg, &v4l2_format, \ sizeof(struct v4l2_format))) @@ -1339,16 +1369,16 @@ case VIDIOC_S_FMT: { } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ case VIDIOC_CROPCAP: { - static struct v4l2_cropcap v4l2_cropcap; + struct v4l2_cropcap v4l2_cropcap; - JOT(8, "VIDIOC_CROPCAP\n"); + JOM(8, "VIDIOC_CROPCAP\n"); if (0 != copy_from_user(&v4l2_cropcap, (void __user *)arg, \ sizeof(struct v4l2_cropcap))) return -EFAULT; if (v4l2_cropcap.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) - JOT(8, "v4l2_cropcap.type != V4L2_BUF_TYPE_VIDEO_CAPTURE\n"); + JOM(8, "v4l2_cropcap.type != V4L2_BUF_TYPE_VIDEO_CAPTURE\n"); memset(&v4l2_cropcap, 0, sizeof(struct v4l2_cropcap)); v4l2_cropcap.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; @@ -1363,7 +1393,7 @@ case VIDIOC_CROPCAP: { v4l2_cropcap.pixelaspect.numerator = 1; v4l2_cropcap.pixelaspect.denominator = 1; - JOT(8, "user is told: %ix%i\n", peasycap->width, peasycap->height); + JOM(8, "user is told: %ix%i\n", peasycap->width, peasycap->height); if (0 != copy_to_user((void __user *)arg, &v4l2_cropcap, \ sizeof(struct v4l2_cropcap))) @@ -1373,12 +1403,12 @@ case VIDIOC_CROPCAP: { /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ case VIDIOC_G_CROP: case VIDIOC_S_CROP: { - JOT(8, "VIDIOC_G_CROP|VIDIOC_S_CROP unsupported\n"); + JOM(8, "VIDIOC_G_CROP|VIDIOC_S_CROP unsupported\n"); return -EINVAL; } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ case VIDIOC_QUERYSTD: { - JOT(8, "VIDIOC_QUERYSTD: " \ + JOM(8, "VIDIOC_QUERYSTD: " \ "EasyCAP is incapable of detecting standard\n"); return -EINVAL; break; @@ -1392,12 +1422,12 @@ case VIDIOC_QUERYSTD: { */ /*---------------------------------------------------------------------------*/ case VIDIOC_ENUMSTD: { - static int last0 = -1, last1 = -1, last2 = -1, last3 = -1; - static struct v4l2_standard v4l2_standard; - static __u32 index; - static struct easycap_standard const *peasycap_standard; + int last0 = -1, last1 = -1, last2 = -1, last3 = -1; + struct v4l2_standard v4l2_standard; + __u32 index; + struct easycap_standard const *peasycap_standard; - JOT(8, "VIDIOC_ENUMSTD\n"); + JOM(8, "VIDIOC_ENUMSTD\n"); if (0 != copy_from_user(&v4l2_standard, (void __user *)arg, \ sizeof(struct v4l2_standard))) @@ -1420,10 +1450,10 @@ case VIDIOC_ENUMSTD: { peasycap_standard++; } if (0xFFFF == peasycap_standard->mask) { - JOT(8, "%i=index: exhausts standards\n", index); + JOM(8, "%i=index: exhausts standards\n", index); return -EINVAL; } - JOT(8, "%i=index: %s\n", index, \ + JOM(8, "%i=index: %s\n", index, \ &(peasycap_standard->v4l2_standard.name[0])); memcpy(&v4l2_standard, &(peasycap_standard->v4l2_standard), \ sizeof(struct v4l2_standard)); @@ -1437,10 +1467,10 @@ case VIDIOC_ENUMSTD: { } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ case VIDIOC_G_STD: { - static v4l2_std_id std_id; - static struct easycap_standard const *peasycap_standard; + v4l2_std_id std_id; + struct easycap_standard const *peasycap_standard; - JOT(8, "VIDIOC_G_STD\n"); + JOM(8, "VIDIOC_G_STD\n"); if (0 != copy_from_user(&std_id, (void __user *)arg, \ sizeof(v4l2_std_id))) @@ -1449,7 +1479,7 @@ case VIDIOC_G_STD: { peasycap_standard = &easycap_standard[peasycap->standard_offset]; std_id = peasycap_standard->v4l2_standard.id; - JOT(8, "user is told: %s\n", \ + JOM(8, "user is told: %s\n", \ &peasycap_standard->v4l2_standard.name[0]); if (0 != copy_to_user((void __user *)arg, &std_id, \ @@ -1459,10 +1489,10 @@ case VIDIOC_G_STD: { } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ case VIDIOC_S_STD: { - static v4l2_std_id std_id; - static int rc; + v4l2_std_id std_id; + int rc; - JOT(8, "VIDIOC_S_STD\n"); + JOM(8, "VIDIOC_S_STD\n"); if (0 != copy_from_user(&std_id, (void __user *)arg, \ sizeof(v4l2_std_id))) @@ -1470,17 +1500,17 @@ case VIDIOC_S_STD: { rc = adjust_standard(peasycap, std_id); if (0 > rc) { - JOT(8, "WARNING: adjust_standard() returned %i\n", rc); + JOM(8, "WARNING: adjust_standard() returned %i\n", rc); return -ENOENT; } break; } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ case VIDIOC_REQBUFS: { - static int nbuffers; - static struct v4l2_requestbuffers v4l2_requestbuffers; + int nbuffers; + struct v4l2_requestbuffers v4l2_requestbuffers; - JOT(8, "VIDIOC_REQBUFS\n"); + JOM(8, "VIDIOC_REQBUFS\n"); if (0 != copy_from_user(&v4l2_requestbuffers, (void __user *)arg, \ sizeof(struct v4l2_requestbuffers))) @@ -1491,16 +1521,16 @@ case VIDIOC_REQBUFS: { if (v4l2_requestbuffers.memory != V4L2_MEMORY_MMAP) return -EINVAL; nbuffers = v4l2_requestbuffers.count; - JOT(8, " User requests %i buffers ...\n", nbuffers); + JOM(8, " User requests %i buffers ...\n", nbuffers); if (nbuffers < 2) nbuffers = 2; if (nbuffers > FRAME_BUFFER_MANY) nbuffers = FRAME_BUFFER_MANY; if (v4l2_requestbuffers.count == nbuffers) { - JOT(8, " ... agree to %i buffers\n", \ + JOM(8, " ... agree to %i buffers\n", \ nbuffers); } else { - JOT(8, " ... insist on %i buffers\n", \ + JOM(8, " ... insist on %i buffers\n", \ nbuffers); v4l2_requestbuffers.count = nbuffers; } @@ -1513,13 +1543,13 @@ case VIDIOC_REQBUFS: { } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ case VIDIOC_QUERYBUF: { - static __u32 index; - static struct v4l2_buffer v4l2_buffer; + __u32 index; + struct v4l2_buffer v4l2_buffer; - JOT(8, "VIDIOC_QUERYBUF\n"); + JOM(8, "VIDIOC_QUERYBUF\n"); if (peasycap->video_eof) { - JOT(8, "returning -1 because %i=video_eof\n", \ + JOM(8, "returning -1 because %i=video_eof\n", \ peasycap->video_eof); return -1; } @@ -1545,17 +1575,17 @@ case VIDIOC_QUERYBUF: { v4l2_buffer.m.offset = index * FRAME_BUFFER_SIZE; v4l2_buffer.length = FRAME_BUFFER_SIZE; - JOT(16, " %10i=index\n", v4l2_buffer.index); - JOT(16, " 0x%08X=type\n", v4l2_buffer.type); - JOT(16, " %10i=bytesused\n", v4l2_buffer.bytesused); - JOT(16, " 0x%08X=flags\n", v4l2_buffer.flags); - JOT(16, " %10i=field\n", v4l2_buffer.field); - JOT(16, " %10li=timestamp.tv_usec\n", \ + JOM(16, " %10i=index\n", v4l2_buffer.index); + JOM(16, " 0x%08X=type\n", v4l2_buffer.type); + JOM(16, " %10i=bytesused\n", v4l2_buffer.bytesused); + JOM(16, " 0x%08X=flags\n", v4l2_buffer.flags); + JOM(16, " %10i=field\n", v4l2_buffer.field); + JOM(16, " %10li=timestamp.tv_usec\n", \ (long)v4l2_buffer.timestamp.tv_usec); - JOT(16, " %10i=sequence\n", v4l2_buffer.sequence); - JOT(16, " 0x%08X=memory\n", v4l2_buffer.memory); - JOT(16, " %10i=m.offset\n", v4l2_buffer.m.offset); - JOT(16, " %10i=length\n", v4l2_buffer.length); + JOM(16, " %10i=sequence\n", v4l2_buffer.sequence); + JOM(16, " 0x%08X=memory\n", v4l2_buffer.memory); + JOM(16, " %10i=m.offset\n", v4l2_buffer.m.offset); + JOM(16, " %10i=length\n", v4l2_buffer.length); if (0 != copy_to_user((void __user *)arg, &v4l2_buffer, \ sizeof(struct v4l2_buffer))) @@ -1564,9 +1594,9 @@ case VIDIOC_QUERYBUF: { } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ case VIDIOC_QBUF: { - static struct v4l2_buffer v4l2_buffer; + struct v4l2_buffer v4l2_buffer; - JOT(8, "VIDIOC_QBUF\n"); + JOM(8, "VIDIOC_QBUF\n"); if (0 != copy_from_user(&v4l2_buffer, (void __user *)arg, \ sizeof(struct v4l2_buffer))) @@ -1588,7 +1618,7 @@ case VIDIOC_QBUF: { sizeof(struct v4l2_buffer))) return -EFAULT; - JOT(8, "..... user queueing frame buffer %i\n", \ + JOM(8, "..... user queueing frame buffer %i\n", \ (int)v4l2_buffer.index); peasycap->frame_lock = 0; @@ -1599,20 +1629,20 @@ case VIDIOC_QBUF: { case VIDIOC_DQBUF: { #if defined(AUDIOTIME) - static struct signed_div_result sdr; - static long long int above, below, dnbydt, fudge, sll; - static unsigned long long int ull; - static struct timeval timeval0; + struct signed_div_result sdr; + long long int above, below, dnbydt, fudge, sll; + unsigned long long int ull; + struct timeval timeval0; struct timeval timeval1; #endif /*AUDIOTIME*/ - static struct timeval timeval, timeval2; - static int i, j; - static struct v4l2_buffer v4l2_buffer; + struct timeval timeval, timeval2; + int i, j; + struct v4l2_buffer v4l2_buffer; - JOT(8, "VIDIOC_DQBUF\n"); + JOM(8, "VIDIOC_DQBUF\n"); if ((peasycap->video_idle) || (peasycap->video_eof)) { - JOT(8, "returning -EIO because " \ + JOM(8, "returning -EIO because " \ "%i=video_idle %i=video_eof\n", \ peasycap->video_idle, peasycap->video_eof); return -EIO; @@ -1626,7 +1656,7 @@ case VIDIOC_DQBUF: return -EINVAL; if (!peasycap->video_isoc_streaming) { - JOT(16, "returning -EIO because video urbs not streaming\n"); + JOM(16, "returning -EIO because video urbs not streaming\n"); return -EIO; } /*---------------------------------------------------------------------------*/ @@ -1645,12 +1675,12 @@ case VIDIOC_DQBUF: return -EIO; } if (V4L2_BUF_FLAG_DONE != peasycap->done[peasycap->frame_read]) { - SAY("ERROR: V4L2_BUF_FLAG_DONE != 0x%08X\n", \ + SAM("ERROR: V4L2_BUF_FLAG_DONE != 0x%08X\n", \ peasycap->done[peasycap->frame_read]); } peasycap->polled = 0; - if (!(isequence % 10)) { + if (!(peasycap->isequence % 10)) { for (i = 0; i < 179; i++) peasycap->merit[i] = peasycap->merit[i+1]; peasycap->merit[179] = merit_saa(peasycap->pusb_device); @@ -1658,7 +1688,7 @@ case VIDIOC_DQBUF: for (i = 0; i < 180; i++) j += peasycap->merit[i]; if (90 < j) { - SAY("easycap driver shutting down " \ + SAM("easycap driver shutting down " \ "on condition blue\n"); peasycap->video_eof = 1; peasycap->audio_eof = 1; } @@ -1697,7 +1727,7 @@ case VIDIOC_DQBUF: timeval2.tv_usec = sdr.remainder; timeval2.tv_sec = timeval1.tv_sec + sdr.quotient; } - if (!(isequence % 500)) { + if (!(peasycap->isequence % 500)) { fudge = ((long long int)(1000000)) * \ ((long long int)(timeval.tv_sec - \ timeval2.tv_sec)) + \ @@ -1707,38 +1737,38 @@ case VIDIOC_DQBUF: sll = sdr.quotient; ull = sdr.remainder; - SAY("%5lli.%-3lli=ms timestamp fudge\n", sll, ull); + SAM("%5lli.%-3lli=ms timestamp fudge\n", sll, ull); } #endif /*AUDIOTIME*/ v4l2_buffer.timestamp = timeval2; - v4l2_buffer.sequence = isequence++; + v4l2_buffer.sequence = peasycap->isequence++; v4l2_buffer.memory = V4L2_MEMORY_MMAP; v4l2_buffer.m.offset = v4l2_buffer.index * FRAME_BUFFER_SIZE; v4l2_buffer.length = FRAME_BUFFER_SIZE; - JOT(16, " %10i=index\n", v4l2_buffer.index); - JOT(16, " 0x%08X=type\n", v4l2_buffer.type); - JOT(16, " %10i=bytesused\n", v4l2_buffer.bytesused); - JOT(16, " 0x%08X=flags\n", v4l2_buffer.flags); - JOT(16, " %10i=field\n", v4l2_buffer.field); - JOT(16, " %10li=timestamp.tv_usec\n", \ + JOM(16, " %10i=index\n", v4l2_buffer.index); + JOM(16, " 0x%08X=type\n", v4l2_buffer.type); + JOM(16, " %10i=bytesused\n", v4l2_buffer.bytesused); + JOM(16, " 0x%08X=flags\n", v4l2_buffer.flags); + JOM(16, " %10i=field\n", v4l2_buffer.field); + JOM(16, " %10li=timestamp.tv_usec\n", \ (long)v4l2_buffer.timestamp.tv_usec); - JOT(16, " %10i=sequence\n", v4l2_buffer.sequence); - JOT(16, " 0x%08X=memory\n", v4l2_buffer.memory); - JOT(16, " %10i=m.offset\n", v4l2_buffer.m.offset); - JOT(16, " %10i=length\n", v4l2_buffer.length); + JOM(16, " %10i=sequence\n", v4l2_buffer.sequence); + JOM(16, " 0x%08X=memory\n", v4l2_buffer.memory); + JOM(16, " %10i=m.offset\n", v4l2_buffer.m.offset); + JOM(16, " %10i=length\n", v4l2_buffer.length); if (0 != copy_to_user((void __user *)arg, &v4l2_buffer, \ sizeof(struct v4l2_buffer))) return -EFAULT; - JOT(8, "..... user is offered frame buffer %i\n", \ + JOM(8, "..... user is offered frame buffer %i\n", \ peasycap->frame_read); peasycap->frame_lock = 1; if (peasycap->frame_read == peasycap->frame_fill) { if (peasycap->frame_lock) { - JOT(8, "ERROR: filling frame buffer " \ + JOM(8, "ERROR: filling frame buffer " \ "while offered to user\n"); } } @@ -1752,15 +1782,15 @@ case VIDIOC_DQBUF: */ /*---------------------------------------------------------------------------*/ case VIDIOC_STREAMON: { - static int i; + int i; - JOT(8, "VIDIOC_STREAMON\n"); + JOM(8, "VIDIOC_STREAMON\n"); - isequence = 0; + peasycap->isequence = 0; for (i = 0; i < 180; i++) peasycap->merit[i] = 0; if ((struct usb_device *)NULL == peasycap->pusb_device) { - SAY("ERROR: peasycap->pusb_device is NULL\n"); + SAM("ERROR: peasycap->pusb_device is NULL\n"); return -EFAULT; } submit_video_urbs(peasycap); @@ -1772,10 +1802,10 @@ case VIDIOC_STREAMON: { } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ case VIDIOC_STREAMOFF: { - JOT(8, "VIDIOC_STREAMOFF\n"); + JOM(8, "VIDIOC_STREAMOFF\n"); if ((struct usb_device *)NULL == peasycap->pusb_device) { - SAY("ERROR: peasycap->pusb_device is NULL\n"); + SAM("ERROR: peasycap->pusb_device is NULL\n"); return -EFAULT; } @@ -1787,7 +1817,7 @@ case VIDIOC_STREAMOFF: { * THE USERSPACE PROGRAM, E.G. mplayer, MAY HANG ON EXIT. BEWARE. */ /*---------------------------------------------------------------------------*/ - JOT(8, "calling wake_up on wq_video and wq_audio\n"); + JOM(8, "calling wake_up on wq_video and wq_audio\n"); wake_up_interruptible(&(peasycap->wq_video)); wake_up_interruptible(&(peasycap->wq_audio)); /*---------------------------------------------------------------------------*/ @@ -1795,9 +1825,9 @@ case VIDIOC_STREAMOFF: { } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ case VIDIOC_G_PARM: { - static struct v4l2_streamparm v4l2_streamparm; + struct v4l2_streamparm v4l2_streamparm; - JOT(8, "VIDIOC_G_PARM\n"); + JOM(8, "VIDIOC_G_PARM\n"); if (0 != copy_from_user(&v4l2_streamparm, (void __user *)arg, \ sizeof(struct v4l2_streamparm))) @@ -1818,44 +1848,44 @@ case VIDIOC_G_PARM: { } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ case VIDIOC_S_PARM: { - JOT(8, "VIDIOC_S_PARM unsupported\n"); + JOM(8, "VIDIOC_S_PARM unsupported\n"); return -EINVAL; } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ case VIDIOC_G_AUDIO: { - JOT(8, "VIDIOC_G_AUDIO unsupported\n"); + JOM(8, "VIDIOC_G_AUDIO unsupported\n"); return -EINVAL; } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ case VIDIOC_S_AUDIO: { - JOT(8, "VIDIOC_S_AUDIO unsupported\n"); + JOM(8, "VIDIOC_S_AUDIO unsupported\n"); return -EINVAL; } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ case VIDIOC_S_TUNER: { - JOT(8, "VIDIOC_S_TUNER unsupported\n"); + JOM(8, "VIDIOC_S_TUNER unsupported\n"); return -EINVAL; } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ case VIDIOC_G_FBUF: case VIDIOC_S_FBUF: case VIDIOC_OVERLAY: { - JOT(8, "VIDIOC_G_FBUF|VIDIOC_S_FBUF|VIDIOC_OVERLAY unsupported\n"); + JOM(8, "VIDIOC_G_FBUF|VIDIOC_S_FBUF|VIDIOC_OVERLAY unsupported\n"); return -EINVAL; } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ case VIDIOC_G_TUNER: { - JOT(8, "VIDIOC_G_TUNER unsupported\n"); + JOM(8, "VIDIOC_G_TUNER unsupported\n"); return -EINVAL; } case VIDIOC_G_FREQUENCY: case VIDIOC_S_FREQUENCY: { - JOT(8, "VIDIOC_G_FREQUENCY|VIDIOC_S_FREQUENCY unsupported\n"); + JOM(8, "VIDIOC_G_FREQUENCY|VIDIOC_S_FREQUENCY unsupported\n"); return -EINVAL; } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ default: { - JOT(8, "ERROR: unrecognized V4L2 IOCTL command: 0x%08X\n", cmd); + JOM(8, "ERROR: unrecognized V4L2 IOCTL command: 0x%08X\n", cmd); return -ENOIOCTLCMD; } } @@ -1873,25 +1903,32 @@ long easycap_ioctl(struct file *file, unsigned int cmd, unsigned long arg) return ret; } - -/*--------------------------------------------------------------------------*/ +/*****************************************************************************/ static int easysnd_ioctl_bkl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { struct easycap *peasycap; struct usb_device *p; +if (NULL == file) { + SAY("ERROR: file is NULL\n"); + return -ERESTARTSYS; +} peasycap = file->private_data; if (NULL == peasycap) { SAY("ERROR: peasycap is NULL.\n"); - return -1; + return -EFAULT; } p = peasycap->pusb_device; +if (NULL == p) { + SAM("ERROR: peasycap->pusb_device is NULL\n"); + return -EFAULT; +} /*---------------------------------------------------------------------------*/ switch (cmd) { case SNDCTL_DSP_GETCAPS: { int caps; - JOT(8, "SNDCTL_DSP_GETCAPS\n"); + JOM(8, "SNDCTL_DSP_GETCAPS\n"); #if defined(UPSAMPLE) if (true == peasycap->microphone) @@ -1911,7 +1948,7 @@ case SNDCTL_DSP_GETCAPS: { } case SNDCTL_DSP_GETFMTS: { int incoming; - JOT(8, "SNDCTL_DSP_GETFMTS\n"); + JOM(8, "SNDCTL_DSP_GETFMTS\n"); #if defined(UPSAMPLE) if (true == peasycap->microphone) @@ -1931,10 +1968,10 @@ case SNDCTL_DSP_GETFMTS: { } case SNDCTL_DSP_SETFMT: { int incoming, outgoing; - JOT(8, "SNDCTL_DSP_SETFMT\n"); + JOM(8, "SNDCTL_DSP_SETFMT\n"); if (0 != copy_from_user(&incoming, (void __user *)arg, sizeof(int))) return -EFAULT; - JOT(8, "........... %i=incoming\n", incoming); + JOM(8, "........... %i=incoming\n", incoming); #if defined(UPSAMPLE) if (true == peasycap->microphone) @@ -1949,9 +1986,9 @@ case SNDCTL_DSP_SETFMT: { #endif /*UPSAMPLE*/ if (incoming != outgoing) { - JOT(8, "........... %i=outgoing\n", outgoing); - JOT(8, " cf. %i=AFMT_S16_LE\n", AFMT_S16_LE); - JOT(8, " cf. %i=AFMT_U8\n", AFMT_U8); + JOM(8, "........... %i=outgoing\n", outgoing); + JOM(8, " cf. %i=AFMT_S16_LE\n", AFMT_S16_LE); + JOM(8, " cf. %i=AFMT_U8\n", AFMT_U8); if (0 != copy_to_user((void __user *)arg, &outgoing, \ sizeof(int))) return -EFAULT; @@ -1961,10 +1998,10 @@ case SNDCTL_DSP_SETFMT: { } case SNDCTL_DSP_STEREO: { int incoming; - JOT(8, "SNDCTL_DSP_STEREO\n"); + JOM(8, "SNDCTL_DSP_STEREO\n"); if (0 != copy_from_user(&incoming, (void __user *)arg, sizeof(int))) return -EFAULT; - JOT(8, "........... %i=incoming\n", incoming); + JOM(8, "........... %i=incoming\n", incoming); #if defined(UPSAMPLE) if (true == peasycap->microphone) @@ -1984,10 +2021,10 @@ case SNDCTL_DSP_STEREO: { } case SNDCTL_DSP_SPEED: { int incoming; - JOT(8, "SNDCTL_DSP_SPEED\n"); + JOM(8, "SNDCTL_DSP_SPEED\n"); if (0 != copy_from_user(&incoming, (void __user *)arg, sizeof(int))) return -EFAULT; - JOT(8, "........... %i=incoming\n", incoming); + JOM(8, "........... %i=incoming\n", incoming); #if defined(UPSAMPLE) if (true == peasycap->microphone) @@ -2007,10 +2044,10 @@ case SNDCTL_DSP_SPEED: { } case SNDCTL_DSP_GETTRIGGER: { int incoming; - JOT(8, "SNDCTL_DSP_GETTRIGGER\n"); + JOM(8, "SNDCTL_DSP_GETTRIGGER\n"); if (0 != copy_from_user(&incoming, (void __user *)arg, sizeof(int))) return -EFAULT; - JOT(8, "........... %i=incoming\n", incoming); + JOM(8, "........... %i=incoming\n", incoming); incoming = PCM_ENABLE_INPUT; if (0 != copy_to_user((void __user *)arg, &incoming, sizeof(int))) @@ -2019,11 +2056,11 @@ case SNDCTL_DSP_GETTRIGGER: { } case SNDCTL_DSP_SETTRIGGER: { int incoming; - JOT(8, "SNDCTL_DSP_SETTRIGGER\n"); + JOM(8, "SNDCTL_DSP_SETTRIGGER\n"); if (0 != copy_from_user(&incoming, (void __user *)arg, sizeof(int))) return -EFAULT; - JOT(8, "........... %i=incoming\n", incoming); - JOT(8, "........... cf 0x%x=PCM_ENABLE_INPUT " \ + JOM(8, "........... %i=incoming\n", incoming); + JOM(8, "........... cf 0x%x=PCM_ENABLE_INPUT " \ "0x%x=PCM_ENABLE_OUTPUT\n", \ PCM_ENABLE_INPUT, PCM_ENABLE_OUTPUT); ; @@ -2034,10 +2071,10 @@ case SNDCTL_DSP_SETTRIGGER: { } case SNDCTL_DSP_GETBLKSIZE: { int incoming; - JOT(8, "SNDCTL_DSP_GETBLKSIZE\n"); + JOM(8, "SNDCTL_DSP_GETBLKSIZE\n"); if (0 != copy_from_user(&incoming, (void __user *)arg, sizeof(int))) return -EFAULT; - JOT(8, "........... %i=incoming\n", incoming); + JOM(8, "........... %i=incoming\n", incoming); incoming = peasycap->audio_bytes_per_fragment; if (0 != copy_to_user((void __user *)arg, &incoming, sizeof(int))) return -EFAULT; @@ -2046,7 +2083,7 @@ case SNDCTL_DSP_GETBLKSIZE: { case SNDCTL_DSP_GETISPACE: { struct audio_buf_info audio_buf_info; - JOT(8, "SNDCTL_DSP_GETISPACE\n"); + JOM(8, "SNDCTL_DSP_GETISPACE\n"); audio_buf_info.bytes = peasycap->audio_bytes_per_fragment; audio_buf_info.fragments = 1; @@ -2059,7 +2096,7 @@ case SNDCTL_DSP_GETISPACE: { break; } default: { - JOT(8, "ERROR: unrecognized DSP IOCTL command: 0x%08X\n", cmd); + JOM(8, "ERROR: unrecognized DSP IOCTL command: 0x%08X\n", cmd); return -ENOIOCTLCMD; } } diff --git a/drivers/staging/easycap/easycap_low.c b/drivers/staging/easycap/easycap_low.c index 709c3d98e936..a3be9c1e5a69 100644 --- a/drivers/staging/easycap/easycap_low.c +++ b/drivers/staging/easycap/easycap_low.c @@ -783,6 +783,12 @@ return usb_control_msg(pusb_device, usb_sndctrlpipe(pusb_device, 0), \ (int)50000); } /*****************************************************************************/ +int +audio_setup(struct easycap *peasycap) +{ +struct usb_device *pusb_device; +unsigned char buffer[1]; +int rc, id1, id2; /*---------------------------------------------------------------------------*/ /* * IMPORTANT: @@ -791,20 +797,12 @@ return usb_control_msg(pusb_device, usb_sndctrlpipe(pusb_device, 0), \ * TO ENABLE AUDIO THE VALUE 0x0200 MUST BE SENT. */ /*---------------------------------------------------------------------------*/ -int -audio_setup(struct easycap *peasycap) -{ -struct usb_device *pusb_device; -static __u8 request = 0x01; -static __u8 requesttype = \ +const __u8 request = 0x01; +const __u8 requesttype = \ (__u8)(USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE); - -static __u16 value_unmute = 0x0200; -static __u16 index = 0x0301; - -static unsigned char buffer[1]; -static __u16 length = 1; -int rc, id1, id2; +const __u16 value_unmute = 0x0200; +const __u16 index = 0x0301; +const __u16 length = 1; if (NULL == peasycap) return -EFAULT; diff --git a/drivers/staging/easycap/easycap_main.c b/drivers/staging/easycap/easycap_main.c index 5dba664475dd..ff6addfa15de 100644 --- a/drivers/staging/easycap/easycap_main.c +++ b/drivers/staging/easycap/easycap_main.c @@ -34,6 +34,18 @@ int debug; module_param(debug, int, S_IRUGO | S_IWUSR); +/*---------------------------------------------------------------------------*/ +/* + * dongle_this IS INDISPENSIBLY static BECAUSE FUNCTION easycap_usb_probe() + * IS CALLED SUCCESSIVELY FOR INTERFACES 0, 1, 2 AND THE POINTER peasycap + * ALLOCATED DURING THE PROBING OF INTERFACE 0 MUST BE REMEMBERED WHEN + * PROBING INTERFACES 1 AND 2. +*/ +/*---------------------------------------------------------------------------*/ + +struct easycap *peasycap_dongle[DONGLE_MANY]; +static int dongle_this; + /*---------------------------------------------------------------------------*/ /* * PARAMETERS APPLICABLE TO ENTIRE DRIVER, I.E. BOTH VIDEO AND AUDIO @@ -91,8 +103,6 @@ const struct v4l2_file_operations v4l2_fops = { .mmap = easycap_mmap, }; #endif /*EASYCAP_NEEDS_V4L2_FOPS*/ -int video_device_many /*=0*/; -struct video_device *pvideo_array[VIDEO_DEVICE_MANY], *pvideo_device; #endif /*EASYCAP_IS_VIDEODEV_CLIENT*/ /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ @@ -115,17 +125,26 @@ struct usb_class_driver easysnd_class = { .minor_base = USB_SKEL_MINOR_BASE, }; /****************************************************************************/ -/*--------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------*/ /* - * IT IS NOT APPROPRIATE FOR easycap_open() TO SUBMIT THE VIDEO URBS HERE, - * BECAUSE THERE WILL ALWAYS BE SUBSEQUENT NEGOTIATION OF TV STANDARD AND - * FORMAT BY IOCTL AND IT IS INADVISABLE TO HAVE THE URBS RUNNING WHILE - * REGISTERS OF THE SA7113H ARE BEING MANIPULATED. - * - * THE SUBMISSION OF VIDEO URBS IS THEREFORE DELAYED UNTIL THE IOCTL COMMAND - * STREAMON IS RECEIVED. - */ -/*--------------------------------------------------------------------------*/ + * THIS ROUTINE DOES NOT DETECT MULTIPLE OCCURRENCES OF POINTER peasycap +*/ +/*---------------------------------------------------------------------------*/ +int +isdongle(struct easycap *peasycap) +{ +int k; +if ((struct easycap *)NULL == peasycap) + return -2; +for (k = 0; k < DONGLE_MANY; k++) { + if (peasycap_dongle[k] == peasycap) { + peasycap->isdongle = k; + return k; + } +} +return -1; +} +/*****************************************************************************/ /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ #if defined(EASYCAP_IS_VIDEODEV_CLIENT) int @@ -140,6 +159,8 @@ easycap_open(struct inode *inode, struct file *file) { #if (!defined(EASYCAP_IS_VIDEODEV_CLIENT)) struct usb_interface *pusb_interface; +#else +struct video_device *pvideo_device; #endif /*EASYCAP_IS_VIDEODEV_CLIENT*/ struct usb_device *p; struct easycap *peasycap; @@ -149,6 +170,7 @@ JOT(4, "\n"); SAY("==========OPEN=========\n"); peasycap = (struct easycap *)NULL; +/*---------------------------------------------------------------------------*/ #if (!defined(EASYCAP_IS_VIDEODEV_CLIENT)) if ((struct inode *)NULL == inode) { SAY("ERROR: inode is NULL.\n"); @@ -162,17 +184,16 @@ if (!pusb_interface) { peasycap = usb_get_intfdata(pusb_interface); /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ #else -for (i = 0; i < video_device_many; i++) { - pvideo_device = pvideo_array[i]; - if ((struct video_device *)NULL != pvideo_device) { - peasycap = (struct easycap *)video_get_drvdata(pvideo_device); - break; - } +pvideo_device = video_devdata(file); +if ((struct video_device *)NULL == pvideo_device) { + SAY("ERROR: pvideo_device is NULL.\n"); + return -EFAULT; } -/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +peasycap = (struct easycap *)video_get_drvdata(pvideo_device); #endif /*EASYCAP_IS_VIDEODEV_CLIENT*/ +/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ if ((struct easycap *)NULL == peasycap) { - SAY("MISTAKE: peasycap is NULL\n"); + SAY("ERROR: peasycap is NULL\n"); return -EFAULT; } file->private_data = peasycap; @@ -181,7 +202,7 @@ file->private_data = peasycap; * INITIALIZATION */ /*---------------------------------------------------------------------------*/ -JOT(4, "starting initialization\n"); +JOM(4, "starting initialization\n"); for (k = 0; k < FRAME_BUFFER_MANY; k++) { for (m = 0; m < FRAME_BUFFER_SIZE/PAGE_SIZE; m++) @@ -189,40 +210,40 @@ for (k = 0; k < FRAME_BUFFER_MANY; k++) { } p = peasycap->pusb_device; if ((struct usb_device *)NULL == p) { - SAY("ERROR: peasycap->pusb_device is NULL\n"); + SAM("ERROR: peasycap->pusb_device is NULL\n"); return -EFAULT; } else { - JOT(16, "0x%08lX=peasycap->pusb_device\n", \ + JOM(16, "0x%08lX=peasycap->pusb_device\n", \ (long int)peasycap->pusb_device); } rc = wakeup_device(peasycap->pusb_device); if (0 == rc) - JOT(8, "wakeup_device() OK\n"); + JOM(8, "wakeup_device() OK\n"); else { - SAY("ERROR: wakeup_device() returned %i\n", rc); + SAM("ERROR: wakeup_device() returned %i\n", rc); return -EFAULT; } rc = setup_stk(p); peasycap->input = 0; if (0 == rc) - JOT(8, "setup_stk() OK\n"); + JOM(8, "setup_stk() OK\n"); else { - SAY("ERROR: setup_stk() returned %i\n", rc); + SAM("ERROR: setup_stk() returned %i\n", rc); return -EFAULT; } rc = setup_saa(p); if (0 == rc) - JOT(8, "setup_saa() OK\n"); + JOM(8, "setup_saa() OK\n"); else { - SAY("ERROR: setup_saa() returned %i\n", rc); + SAM("ERROR: setup_saa() returned %i\n", rc); return -EFAULT; } rc = check_saa(p); if (0 == rc) - JOT(8, "check_saa() OK\n"); + JOM(8, "check_saa() OK\n"); else if (-8 < rc) - SAY("check_saa() returned %i\n", rc); + SAM("check_saa() returned %i\n", rc); else { - SAY("ERROR: check_saa() returned %i\n", rc); + SAM("ERROR: check_saa() returned %i\n", rc); return -EFAULT; } peasycap->standard_offset = -1; @@ -231,17 +252,17 @@ peasycap->standard_offset = -1; rc = adjust_standard(peasycap, V4L2_STD_NTSC_M); if (0 == rc) - JOT(8, "adjust_standard(.,NTSC_M) OK\n"); + JOM(8, "adjust_standard(.,NTSC_M) OK\n"); else { - SAY("ERROR: adjust_standard(.,NTSC_M) returned %i\n", rc); + SAM("ERROR: adjust_standard(.,NTSC_M) returned %i\n", rc); return -EFAULT; } rc = adjust_format(peasycap, 640, 480, V4L2_PIX_FMT_UYVY, V4L2_FIELD_NONE, \ false); if (0 <= rc) - JOT(8, "adjust_format(.,640,480,UYVY) OK\n"); + JOM(8, "adjust_format(.,640,480,UYVY) OK\n"); else { - SAY("ERROR: adjust_format(.,640,480,UYVY) returned %i\n", rc); + SAM("ERROR: adjust_format(.,640,480,UYVY) returned %i\n", rc); return -EFAULT; } @@ -251,17 +272,17 @@ rc = adjust_standard(peasycap, \ (V4L2_STD_PAL_B | V4L2_STD_PAL_G | V4L2_STD_PAL_H | \ V4L2_STD_PAL_I | V4L2_STD_PAL_N)); if (0 == rc) - JOT(8, "adjust_standard(.,PAL_BGHIN) OK\n"); + JOM(8, "adjust_standard(.,PAL_BGHIN) OK\n"); else { - SAY("ERROR: adjust_standard(.,PAL_BGHIN) returned %i\n", rc); + SAM("ERROR: adjust_standard(.,PAL_BGHIN) returned %i\n", rc); return -EFAULT; } rc = adjust_format(peasycap, 640, 480, V4L2_PIX_FMT_UYVY, V4L2_FIELD_NONE, \ false); if (0 <= rc) - JOT(8, "adjust_format(.,640,480,uyvy,false) OK\n"); + JOM(8, "adjust_format(.,640,480,uyvy,false) OK\n"); else { - SAY("ERROR: adjust_format(.,640,480,uyvy,false) returned %i\n", rc); + SAM("ERROR: adjust_format(.,640,480,uyvy,false) returned %i\n", rc); return -EFAULT; } @@ -269,39 +290,39 @@ else { /*---------------------------------------------------------------------------*/ rc = adjust_brightness(peasycap, -8192); if (0 != rc) { - SAY("ERROR: adjust_brightness(default) returned %i\n", rc); + SAM("ERROR: adjust_brightness(default) returned %i\n", rc); return -EFAULT; } rc = adjust_contrast(peasycap, -8192); if (0 != rc) { - SAY("ERROR: adjust_contrast(default) returned %i\n", rc); + SAM("ERROR: adjust_contrast(default) returned %i\n", rc); return -EFAULT; } rc = adjust_saturation(peasycap, -8192); if (0 != rc) { - SAY("ERROR: adjust_saturation(default) returned %i\n", rc); + SAM("ERROR: adjust_saturation(default) returned %i\n", rc); return -EFAULT; } rc = adjust_hue(peasycap, -8192); if (0 != rc) { - SAY("ERROR: adjust_hue(default) returned %i\n", rc); + SAM("ERROR: adjust_hue(default) returned %i\n", rc); return -EFAULT; } /*---------------------------------------------------------------------------*/ rc = usb_set_interface(peasycap->pusb_device, peasycap->video_interface, \ peasycap->video_altsetting_on); if (0 == rc) - JOT(8, "usb_set_interface(.,%i,%i) OK\n", peasycap->video_interface, \ + JOM(8, "usb_set_interface(.,%i,%i) OK\n", peasycap->video_interface, \ peasycap->video_altsetting_on); else { - SAY("ERROR: usb_set_interface() returned %i\n", rc); + SAM("ERROR: usb_set_interface() returned %i\n", rc); return -EFAULT; } rc = start_100(p); if (0 == rc) - JOT(8, "start_100() OK\n"); + JOM(8, "start_100() OK\n"); else { - SAY("ERROR: start_100() returned %i\n", rc); + SAM("ERROR: start_100() returned %i\n", rc); return -EFAULT; } peasycap->video_isoc_sequence = VIDEO_ISOC_BUFFER_MANY - 1; @@ -314,7 +335,7 @@ peasycap->audio_eof = 0; do_gettimeofday(&peasycap->timeval7); -JOT(4, "finished initialization\n"); +JOM(4, "finished initialization\n"); return 0; } /*****************************************************************************/ @@ -324,33 +345,25 @@ submit_video_urbs(struct easycap *peasycap) struct data_urb *pdata_urb; struct urb *purb; struct list_head *plist_head; -int j, isbad, m, rc; +int j, isbad, nospc, m, rc; int isbuf; +if ((struct easycap *)NULL == peasycap) { + SAY("ERROR: peasycap is NULL\n"); + return -EFAULT; +} + if ((struct list_head *)NULL == peasycap->purb_video_head) { SAY("ERROR: peasycap->urb_video_head uninitialized\n"); return -EFAULT; } if ((struct usb_device *)NULL == peasycap->pusb_device) { SAY("ERROR: peasycap->pusb_device is NULL\n"); - return -EFAULT; + return -ENODEV; } if (!peasycap->video_isoc_streaming) { - - - - - - - - - JOT(4, "submission of all video urbs\n"); - if (0 != ready_saa(peasycap->pusb_device)) { - SAY("ERROR: not ready to capture after waiting " \ - "one second\n"); - SAY("..... continuing anyway\n"); - } - isbad = 0; m = 0; + JOM(4, "submission of all video urbs\n"); + isbad = 0; nospc = 0; m = 0; list_for_each(plist_head, (peasycap->purb_video_head)) { pdata_urb = list_entry(plist_head, struct data_urb, list_head); if (NULL != pdata_urb) { @@ -387,44 +400,57 @@ if (!peasycap->video_isoc_streaming) { rc = usb_submit_urb(purb, GFP_KERNEL); if (0 != rc) { isbad++; - SAY("ERROR: usb_submit_urb() failed " \ + SAM("ERROR: usb_submit_urb() failed " \ "for urb with rc:\n"); switch (rc) { case -ENOMEM: { - SAY("ENOMEM\n"); + SAM("ERROR: -ENOMEM=" \ + "usb_submit_urb()\n"); break; } case -ENODEV: { - SAY("ENODEV\n"); + SAM("ERROR: -ENODEV=" \ + "usb_submit_urb()\n"); break; } case -ENXIO: { - SAY("ENXIO\n"); + SAM("ERROR: -ENXIO=" \ + "usb_submit_urb()\n"); break; } case -EINVAL: { - SAY("EINVAL\n"); + SAM("ERROR: -EINVAL=" \ + "usb_submit_urb()\n"); break; } case -EAGAIN: { - SAY("EAGAIN\n"); + SAM("ERROR: -EAGAIN=" \ + "usb_submit_urb()\n"); break; } case -EFBIG: { - SAY("EFBIG\n"); + SAM("ERROR: -EFBIG=" \ + "usb_submit_urb()\n"); break; } case -EPIPE: { - SAY("EPIPE\n"); + SAM("ERROR: -EPIPE=" \ + "usb_submit_urb()\n"); break; } case -EMSGSIZE: { - SAY("EMSGSIZE\n"); + SAM("ERROR: -EMSGSIZE=" \ + "usb_submit_urb()\n"); + break; + } + case -ENOSPC: { + nospc++; break; } default: { - SAY("unknown error code %i\n",\ - rc); + SAM("ERROR: %i=" \ + "usb_submit_urb()\n",\ + rc); break; } } @@ -432,14 +458,20 @@ if (!peasycap->video_isoc_streaming) { m++; } } else { - isbad++; + isbad++; } } else { isbad++; } } + if (nospc) { + SAM("-ENOSPC=usb_submit_urb() for %i urbs\n", nospc); + SAM("..... possibly inadequate USB bandwidth\n"); + peasycap->video_eof = 1; + } + if (isbad) { - JOT(4, "attempting cleanup instead of submitting\n"); + JOM(4, "attempting cleanup instead of submitting\n"); list_for_each(plist_head, (peasycap->purb_video_head)) { pdata_urb = list_entry(plist_head, struct data_urb, \ list_head); @@ -452,16 +484,10 @@ if (!peasycap->video_isoc_streaming) { peasycap->video_isoc_streaming = 0; } else { peasycap->video_isoc_streaming = 1; - JOT(4, "submitted %i video urbs\n", m); + JOM(4, "submitted %i video urbs\n", m); } - - - - - - } else { - JOT(4, "already streaming video urbs\n"); + JOM(4, "already streaming video urbs\n"); } return 0; } @@ -478,12 +504,9 @@ if ((struct easycap *)NULL == peasycap) { return -EFAULT; } if (peasycap->video_isoc_streaming) { - - - if ((struct list_head *)NULL != peasycap->purb_video_head) { peasycap->video_isoc_streaming = 0; - JOT(4, "killing video urbs\n"); + JOM(4, "killing video urbs\n"); m = 0; list_for_each(plist_head, (peasycap->purb_video_head)) { pdata_urb = list_entry(plist_head, struct data_urb, \ @@ -495,13 +518,13 @@ if (peasycap->video_isoc_streaming) { } } } - JOT(4, "%i video urbs killed\n", m); + JOM(4, "%i video urbs killed\n", m); } else { - SAY("ERROR: peasycap->purb_video_head is NULL\n"); + SAM("ERROR: peasycap->purb_video_head is NULL\n"); return -EFAULT; } } else { - JOT(8, "%i=video_isoc_streaming, no video urbs killed\n", \ + JOM(8, "%i=video_isoc_streaming, no video urbs killed\n", \ peasycap->video_isoc_streaming); } return 0; @@ -532,10 +555,10 @@ if (NULL == peasycap) { return -EFAULT; } if (0 != kill_video_urbs(peasycap)) { - SAY("ERROR: kill_video_urbs() failed\n"); + SAM("ERROR: kill_video_urbs() failed\n"); return -EFAULT; } -JOT(4, "ending successfully\n"); +JOM(4, "ending successfully\n"); /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ #else # @@ -548,52 +571,28 @@ return 0; /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ #if defined(EASYCAP_IS_VIDEODEV_CLIENT) int -videodev_release(struct video_device *pvd) +videodev_release(struct video_device *pvideo_device) { struct easycap *peasycap; -int i, j, k; JOT(4, "\n"); -k = 0; -for (i = 0; i < video_device_many; i++) { - pvideo_device = pvideo_array[i]; - if ((struct video_device *)NULL != pvideo_device) { - if (pvd->minor == pvideo_device->minor) { - peasycap = (struct easycap *)\ - video_get_drvdata(pvideo_device); - if ((struct easycap *)NULL == peasycap) { - SAY("ERROR: peasycap is NULL\n"); - SAY("ending unsuccessfully\n"); - return -EFAULT; - } - if (0 != kill_video_urbs(peasycap)) { - SAY("ERROR: kill_video_urbs() failed\n"); - return -EFAULT; - } - JOT(4, "freeing video_device structure: " \ - "/dev/video%i\n", i); - kfree((void *)pvideo_device); - for (j = i; j < (VIDEO_DEVICE_MANY - 1); j++) - pvideo_array[j] = pvideo_array[j + 1]; - video_device_many--; k++; - break; - } - } -} -if (!k) { - SAY("ERROR: lost video_device structure for %i=minor\n", pvd->minor); - SAY("cannot free: may cause memory leak\n"); +peasycap = video_get_drvdata(pvideo_device); +if (NULL == peasycap) { + SAY("ERROR: peasycap is NULL\n"); SAY("ending unsuccessfully\n"); return -EFAULT; } - -JOT(4, "ending successfully\n"); +if (0 != kill_video_urbs(peasycap)) { + SAM("ERROR: kill_video_urbs() failed\n"); + return -EFAULT; +} +JOM(4, "ending successfully\n"); return 0; } #endif /*EASYCAP_IS_VIDEODEV_CLIENT*/ -/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -/****************************************************************************/ +/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +/*****************************************************************************/ /*--------------------------------------------------------------------------*/ /* * THIS FUNCTION IS CALLED FROM WITHIN easycap_usb_disconnect(). @@ -616,7 +615,7 @@ JOT(4, "\n"); peasycap = container_of(pkref, struct easycap, kref); if ((struct easycap *)NULL == peasycap) { - SAY("ERROR: peasycap is NULL: cannot perform deletions\n"); + SAM("ERROR: peasycap is NULL: cannot perform deletions\n"); return; } /*---------------------------------------------------------------------------*/ @@ -625,12 +624,12 @@ if ((struct easycap *)NULL == peasycap) { */ /*---------------------------------------------------------------------------*/ if ((struct list_head *)NULL != peasycap->purb_video_head) { - JOT(4, "freeing video urbs\n"); + JOM(4, "freeing video urbs\n"); m = 0; list_for_each(plist_head, (peasycap->purb_video_head)) { pdata_urb = list_entry(plist_head, struct data_urb, list_head); if (NULL == pdata_urb) - JOT(4, "ERROR: pdata_urb is NULL\n"); + JOM(4, "ERROR: pdata_urb is NULL\n"); else { if ((struct urb *)NULL != pdata_urb->purb) { usb_free_urb(pdata_urb->purb); @@ -641,9 +640,9 @@ if ((struct list_head *)NULL != peasycap->purb_video_head) { } } - JOT(4, "%i video urbs freed\n", m); + JOM(4, "%i video urbs freed\n", m); /*---------------------------------------------------------------------------*/ - JOT(4, "freeing video data_urb structures.\n"); + JOM(4, "freeing video data_urb structures.\n"); m = 0; list_for_each_safe(plist_head, plist_next, peasycap->purb_video_head) { pdata_urb = list_entry(plist_head, struct data_urb, list_head); @@ -654,14 +653,14 @@ if ((struct list_head *)NULL != peasycap->purb_video_head) { m++; } } - JOT(4, "%i video data_urb structures freed\n", m); - JOT(4, "setting peasycap->purb_video_head=NULL\n"); + JOM(4, "%i video data_urb structures freed\n", m); + JOM(4, "setting peasycap->purb_video_head=NULL\n"); peasycap->purb_video_head = (struct list_head *)NULL; } else { -JOT(4, "peasycap->purb_video_head is NULL\n"); +JOM(4, "peasycap->purb_video_head is NULL\n"); } /*---------------------------------------------------------------------------*/ -JOT(4, "freeing video isoc buffers.\n"); +JOM(4, "freeing video isoc buffers.\n"); m = 0; for (k = 0; k < VIDEO_ISOC_BUFFER_MANY; k++) { if ((void *)NULL != peasycap->video_isoc_buffer[k].pgo) { @@ -674,9 +673,9 @@ for (k = 0; k < VIDEO_ISOC_BUFFER_MANY; k++) { m++; } } -JOT(4, "isoc video buffers freed: %i pages\n", m * (0x01 << VIDEO_ISOC_ORDER)); +JOM(4, "isoc video buffers freed: %i pages\n", m * (0x01 << VIDEO_ISOC_ORDER)); /*---------------------------------------------------------------------------*/ -JOT(4, "freeing video field buffers.\n"); +JOM(4, "freeing video field buffers.\n"); lost = 0; for (k = 0; k < FIELD_BUFFER_MANY; k++) { for (m = 0; m < FIELD_BUFFER_SIZE/PAGE_SIZE; m++) { @@ -689,9 +688,9 @@ for (k = 0; k < FIELD_BUFFER_MANY; k++) { } } } -JOT(4, "video field buffers freed: %i pages\n", lost); +JOM(4, "video field buffers freed: %i pages\n", lost); /*---------------------------------------------------------------------------*/ -JOT(4, "freeing video frame buffers.\n"); +JOM(4, "freeing video frame buffers.\n"); lost = 0; for (k = 0; k < FRAME_BUFFER_MANY; k++) { for (m = 0; m < FRAME_BUFFER_SIZE/PAGE_SIZE; m++) { @@ -704,19 +703,19 @@ for (k = 0; k < FRAME_BUFFER_MANY; k++) { } } } -JOT(4, "video frame buffers freed: %i pages\n", lost); +JOM(4, "video frame buffers freed: %i pages\n", lost); /*---------------------------------------------------------------------------*/ /* * FREE AUDIO. */ /*---------------------------------------------------------------------------*/ if ((struct list_head *)NULL != peasycap->purb_audio_head) { - JOT(4, "freeing audio urbs\n"); + JOM(4, "freeing audio urbs\n"); m = 0; list_for_each(plist_head, (peasycap->purb_audio_head)) { pdata_urb = list_entry(plist_head, struct data_urb, list_head); if (NULL == pdata_urb) - JOT(4, "ERROR: pdata_urb is NULL\n"); + JOM(4, "ERROR: pdata_urb is NULL\n"); else { if ((struct urb *)NULL != pdata_urb->purb) { usb_free_urb(pdata_urb->purb); @@ -726,9 +725,9 @@ if ((struct list_head *)NULL != peasycap->purb_audio_head) { } } } - JOT(4, "%i audio urbs freed\n", m); + JOM(4, "%i audio urbs freed\n", m); /*---------------------------------------------------------------------------*/ - JOT(4, "freeing audio data_urb structures.\n"); + JOM(4, "freeing audio data_urb structures.\n"); m = 0; list_for_each_safe(plist_head, plist_next, peasycap->purb_audio_head) { pdata_urb = list_entry(plist_head, struct data_urb, list_head); @@ -739,14 +738,14 @@ if ((struct list_head *)NULL != peasycap->purb_audio_head) { m++; } } -JOT(4, "%i audio data_urb structures freed\n", m); -JOT(4, "setting peasycap->purb_audio_head=NULL\n"); +JOM(4, "%i audio data_urb structures freed\n", m); +JOM(4, "setting peasycap->purb_audio_head=NULL\n"); peasycap->purb_audio_head = (struct list_head *)NULL; } else { -JOT(4, "peasycap->purb_audio_head is NULL\n"); +JOM(4, "peasycap->purb_audio_head is NULL\n"); } /*---------------------------------------------------------------------------*/ -JOT(4, "freeing audio isoc buffers.\n"); +JOM(4, "freeing audio isoc buffers.\n"); m = 0; for (k = 0; k < AUDIO_ISOC_BUFFER_MANY; k++) { if ((void *)NULL != peasycap->audio_isoc_buffer[k].pgo) { @@ -759,10 +758,10 @@ for (k = 0; k < AUDIO_ISOC_BUFFER_MANY; k++) { m++; } } -JOT(4, "easysnd_delete(): isoc audio buffers freed: %i pages\n", \ +JOM(4, "easysnd_delete(): isoc audio buffers freed: %i pages\n", \ m * (0x01 << AUDIO_ISOC_ORDER)); /*---------------------------------------------------------------------------*/ -JOT(4, "freeing audio buffers.\n"); +JOM(4, "freeing audio buffers.\n"); lost = 0; for (k = 0; k < peasycap->audio_buffer_page_many; k++) { if ((void *)NULL != peasycap->audio_buffer[k].pgo) { @@ -772,9 +771,9 @@ for (k = 0; k < peasycap->audio_buffer_page_many; k++) { lost++; } } -JOT(4, "easysnd_delete(): audio buffers freed: %i pages\n", lost); +JOM(4, "easysnd_delete(): audio buffers freed: %i pages\n", lost); /*---------------------------------------------------------------------------*/ -JOT(4, "freeing easycap structure.\n"); +JOM(4, "freeing easycap structure.\n"); allocation_video_urb = peasycap->allocation_video_urb; allocation_video_page = peasycap->allocation_video_page; allocation_video_struct = peasycap->allocation_video_struct; @@ -861,7 +860,7 @@ while ((peasycap->field_read == peasycap->field_fill) || \ if (mode) return -EAGAIN; - JOT(8, "first wait on wq_video, " \ + JOM(8, "first wait on wq_video, " \ "%i=field_read %i=field_fill\n", \ peasycap->field_read, peasycap->field_fill); @@ -873,25 +872,25 @@ while ((peasycap->field_read == peasycap->field_fill) || \ [peasycap->field_read][0].kount)) && \ (0 == (0x00FF & peasycap->field_buffer\ [peasycap->field_read][0].kount))))))){ - SAY("aborted by signal\n"); + SAM("aborted by signal\n"); return -EIO; } if (peasycap->video_idle) { - JOT(8, "%i=peasycap->video_idle\n", peasycap->video_idle); + JOM(8, "%i=peasycap->video_idle\n", peasycap->video_idle); return -EIO; } if (peasycap->video_eof) { - JOT(8, "%i=peasycap->video_eof\n", peasycap->video_eof); + JOM(8, "%i=peasycap->video_eof\n", peasycap->video_eof); kill_video_urbs(peasycap); return -EIO; } miss++; } -JOT(8, "first awakening on wq_video after %i waits\n", miss); +JOM(8, "first awakening on wq_video after %i waits\n", miss); rc = field2frame(peasycap); if (0 != rc) - SAY("ERROR: field2frame() returned %i\n", rc); + SAM("ERROR: field2frame() returned %i\n", rc); if (true == peasycap->offerfields) { peasycap->frame_read = peasycap->frame_fill; @@ -906,8 +905,8 @@ if (true == peasycap->offerfields) { peasycap->frame_buffer[peasycap->frame_read][0].kount = \ V4L2_FIELD_TOP; } -JOT(8, "setting: %i=peasycap->frame_read\n", peasycap->frame_read); -JOT(8, "bumped to: %i=peasycap->frame_fill\n", peasycap->frame_fill); +JOM(8, "setting: %i=peasycap->frame_read\n", peasycap->frame_read); +JOM(8, "bumped to: %i=peasycap->frame_fill\n", peasycap->frame_fill); } /*---------------------------------------------------------------------------*/ /* @@ -923,7 +922,7 @@ while ((peasycap->field_read == peasycap->field_fill) || \ if (mode) return -EAGAIN; - JOT(8, "second wait on wq_video, " \ + JOM(8, "second wait on wq_video, " \ "%i=field_read %i=field_fill\n", \ peasycap->field_read, peasycap->field_fill); msleep(1); @@ -934,25 +933,25 @@ while ((peasycap->field_read == peasycap->field_fill) || \ [peasycap->field_read][0].kount)) && \ (0 != (0x00FF & peasycap->field_buffer\ [peasycap->field_read][0].kount))))))){ - SAY("aborted by signal\n"); + SAM("aborted by signal\n"); return -EIO; } if (peasycap->video_idle) { - JOT(8, "%i=peasycap->video_idle\n", peasycap->video_idle); + JOM(8, "%i=peasycap->video_idle\n", peasycap->video_idle); return -EIO; } if (peasycap->video_eof) { - JOT(8, "%i=peasycap->video_eof\n", peasycap->video_eof); + JOM(8, "%i=peasycap->video_eof\n", peasycap->video_eof); kill_video_urbs(peasycap); return -EIO; } miss++; } -JOT(8, "second awakening on wq_video after %i waits\n", miss); +JOM(8, "second awakening on wq_video after %i waits\n", miss); rc = field2frame(peasycap); if (0 != rc) - SAY("ERROR: field2frame() returned %i\n", rc); + SAM("ERROR: field2frame() returned %i\n", rc); peasycap->frame_read = peasycap->frame_fill; peasycap->queued[peasycap->frame_read] = 0; @@ -970,8 +969,8 @@ if (0x01 & easycap_standard[peasycap->standard_offset].mask) { V4L2_FIELD_BOTTOM; } -JOT(8, "setting: %i=peasycap->frame_read\n", peasycap->frame_read); -JOT(8, "bumped to: %i=peasycap->frame_fill\n", peasycap->frame_fill); +JOM(8, "setting: %i=peasycap->frame_read\n", peasycap->frame_read); +JOM(8, "bumped to: %i=peasycap->frame_fill\n", peasycap->frame_fill); return 0; } @@ -992,7 +991,6 @@ return 0; int field2frame(struct easycap *peasycap) { -static struct timeval timeval0; struct timeval timeval; long long int above, below; __u32 remainder; @@ -1005,12 +1003,17 @@ int rc, bytesperpixel, multiplier, much, more, over, rump, caches; __u8 mask, margin; bool odd, isuy, decimatepixel, offerfields; -JOT(8, "===== parity %i, field buffer %i --> frame buffer %i\n", \ +if ((struct easycap *)NULL == peasycap) { + SAY("ERROR: peasycap is NULL\n"); + return -EFAULT; +} + +JOM(8, "===== parity %i, field buffer %i --> frame buffer %i\n", \ peasycap->field_buffer[peasycap->field_read][0].kount,\ peasycap->field_read, peasycap->frame_fill); -JOT(8, "===== %i=bytesperpixel\n", peasycap->bytesperpixel); +JOM(8, "===== %i=bytesperpixel\n", peasycap->bytesperpixel); if (true == peasycap->offerfields) - JOT(8, "===== offerfields\n"); + JOM(8, "===== offerfields\n"); /*---------------------------------------------------------------------------*/ /* @@ -1018,7 +1021,7 @@ if (true == peasycap->offerfields) */ /*---------------------------------------------------------------------------*/ if (peasycap->field_read == peasycap->field_fill) { - SAY("ERROR: on entry, still filling field buffer %i\n", \ + SAM("ERROR: on entry, still filling field buffer %i\n", \ peasycap->field_read); return 0; } @@ -1037,7 +1040,7 @@ decimatepixel = peasycap->decimatepixel; if ((2 != bytesperpixel) && \ (3 != bytesperpixel) && \ (4 != bytesperpixel)) { - SAY("MISTAKE: %i=bytesperpixel\n", bytesperpixel); + SAM("MISTAKE: %i=bytesperpixel\n", bytesperpixel); return -EFAULT; } if (true == decimatepixel) @@ -1065,7 +1068,7 @@ else odd = false; if ((true == odd) && (false == offerfields) &&(false == decimatepixel)) { - JOT(8, " initial skipping %4i bytes p.%4i\n", \ + JOM(8, " initial skipping %4i bytes p.%4i\n", \ w3/multiplier, mad); pad += (w3 / multiplier); rad -= (w3 / multiplier); } @@ -1090,7 +1093,7 @@ while (cz < wz) { rump = 0; if (much % 2) { - SAY("MISTAKE: much is odd\n"); + SAM("MISTAKE: much is odd\n"); return -EFAULT; } @@ -1127,7 +1130,7 @@ while (cz < wz) { } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ } else { - SAY("MISTAKE: %i=bytesperpixel\n", \ + SAM("MISTAKE: %i=bytesperpixel\n", \ bytesperpixel); return -EFAULT; } @@ -1138,7 +1141,7 @@ while (cz < wz) { rc = redaub(peasycap, pad, pex, much, more, \ mask, margin, isuy); if (0 > rc) { - SAY("ERROR: redaub() failed\n"); + SAM("ERROR: redaub() failed\n"); return -EFAULT; } if (much % 4) { @@ -1206,7 +1209,7 @@ while (cz < wz) { rump = 0; if (much % 2) { - SAY("MISTAKE: much is odd\n"); + SAM("MISTAKE: much is odd\n"); return -EFAULT; } @@ -1243,7 +1246,7 @@ while (cz < wz) { } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ } else { - SAY("MISTAKE: %i=bytesperpixel\n", \ + SAM("MISTAKE: %i=bytesperpixel\n", \ bytesperpixel); return -EFAULT; } @@ -1254,7 +1257,7 @@ while (cz < wz) { rc = redaub(peasycap, pad, pex, much, more, \ mask, margin, isuy); if (0 > rc) { - SAY("ERROR: redaub() failed\n"); + SAM("ERROR: redaub() failed\n"); return -EFAULT; } over -= much; cz += much; @@ -1307,39 +1310,39 @@ while (cz < wz) { /*---------------------------------------------------------------------------*/ c2 = (mex + 1)*PAGE_SIZE - rex; if (cz != c2) - SAY("ERROR: discrepancy %i in bytes read\n", c2 - cz); + SAM("ERROR: discrepancy %i in bytes read\n", c2 - cz); c3 = (mad + 1)*PAGE_SIZE - rad; if (false == decimatepixel) { if (bytesperpixel * \ cz != c3) \ - SAY("ERROR: discrepancy %i in bytes written\n", \ + SAM("ERROR: discrepancy %i in bytes written\n", \ c3 - (bytesperpixel * \ cz)); } else { if (false == odd) { if (bytesperpixel * \ cz != (4 * c3)) - SAY("ERROR: discrepancy %i in bytes written\n", \ + SAM("ERROR: discrepancy %i in bytes written\n", \ (2*c3)-(bytesperpixel * \ cz)); } else { if (0 != c3) - SAY("ERROR: discrepancy %i " \ + SAM("ERROR: discrepancy %i " \ "in bytes written\n", c3); } } if (rump) - SAY("ERROR: undischarged cache at end of line in frame buffer\n"); + SAM("WORRY: undischarged cache at end of line in frame buffer\n"); -JOT(8, "===== field2frame(): %i bytes --> %i bytes (incl skip)\n", c2, c3); -JOT(8, "===== field2frame(): %i=mad %i=rad\n", mad, rad); +JOM(8, "===== field2frame(): %i bytes --> %i bytes (incl skip)\n", c2, c3); +JOM(8, "===== field2frame(): %i=mad %i=rad\n", mad, rad); if (true == odd) - JOT(8, "+++++ field2frame(): frame buffer %i is full\n", kad); + JOM(8, "+++++ field2frame(): frame buffer %i is full\n", kad); if (peasycap->field_read == peasycap->field_fill) - SAY("WARNING: on exit, filling field buffer %i\n", \ + SAM("WARNING: on exit, filling field buffer %i\n", \ peasycap->field_read); /*---------------------------------------------------------------------------*/ /* @@ -1347,23 +1350,24 @@ if (peasycap->field_read == peasycap->field_fill) */ /*---------------------------------------------------------------------------*/ do_gettimeofday(&timeval); -if (timeval0.tv_sec) { +if (peasycap->timeval6.tv_sec) { below = ((long long int)(1000000)) * \ - ((long long int)(timeval.tv_sec - timeval0.tv_sec)) + \ - (long long int)(timeval.tv_usec - timeval0.tv_usec); + ((long long int)(timeval.tv_sec - \ + peasycap->timeval6.tv_sec)) + \ + (long long int)(timeval.tv_usec - peasycap->timeval6.tv_usec); above = (long long int)1000000; sdr = signed_div(above, below); above = sdr.quotient; remainder = (__u32)sdr.remainder; - JOT(8, "video streaming at %3lli.%03i fields per second\n", above, \ + JOM(8, "video streaming at %3lli.%03i fields per second\n", above, \ (remainder/1000)); } -timeval0 = timeval; +peasycap->timeval6 = timeval; if (caches) - JOT(8, "%i=caches\n", caches); + JOM(8, "%i=caches\n", caches); return 0; } /*****************************************************************************/ @@ -1416,7 +1420,7 @@ redaub(struct easycap *peasycap, void *pad, void *pex, int much, int more, \ __u8 mask, __u8 margin, bool isuy) { static __s32 ay[256], bu[256], rv[256], gu[256], gv[256]; -static __u8 cache[8], *pcache; +__u8 *pcache; __u8 r, g, b, y, u, v, c, *p2, *p3, *pz, *pr; int bytesperpixel; bool byteswaporder, decimatepixel, last; @@ -1424,7 +1428,7 @@ int j, rump; __s32 s32; if (much % 2) { - SAY("MISTAKE: much is odd\n"); + SAM("MISTAKE: much is odd\n"); return -EFAULT; } bytesperpixel = peasycap->bytesperpixel; @@ -1457,30 +1461,31 @@ if (!bu[255]) { ay[j] = ay[16]; for (j = 236; j < 256; j++) ay[j] = ay[235]; - JOT(8, "lookup tables are prepared\n"); + JOM(8, "lookup tables are prepared\n"); } -if ((__u8 *)NULL == pcache) - pcache = &cache[0]; +pcache = peasycap->pcache; +if (NULL == pcache) + pcache = &peasycap->cache[0]; /*---------------------------------------------------------------------------*/ /* * TRANSFER CONTENTS OF CACHE TO THE FRAME BUFFER */ /*---------------------------------------------------------------------------*/ if (!pcache) { - SAY("MISTAKE: pcache is NULL\n"); + SAM("MISTAKE: pcache is NULL\n"); return -EFAULT; } -if (pcache != &cache[0]) - JOT(16, "cache has %i bytes\n", (int)(pcache - &cache[0])); -p2 = &cache[0]; -p3 = (__u8 *)pad - (int)(pcache - &cache[0]); +if (pcache != &peasycap->cache[0]) + JOM(16, "cache has %i bytes\n", (int)(pcache - &peasycap->cache[0])); +p2 = &peasycap->cache[0]; +p3 = (__u8 *)pad - (int)(pcache - &peasycap->cache[0]); while (p2 < pcache) { *p3++ = *p2; p2++; } -pcache = &cache[0]; +pcache = &peasycap->cache[0]; if (p3 != pad) { - SAY("MISTAKE: pointer misalignment\n"); + SAM("MISTAKE: pointer misalignment\n"); return -EFAULT; } /*---------------------------------------------------------------------------*/ @@ -1495,7 +1500,7 @@ else v = *(p2 - 1); if (rump) - JOT(16, "%4i=much %4i=more %i=rump\n", much, more, rump); + JOM(16, "%4i=much %4i=more %i=rump\n", much, more, rump); /*---------------------------------------------------------------------------*/ switch (bytesperpixel) { @@ -1601,7 +1606,7 @@ case 3: 0 : (__u8)s32); if ((true == last) && rump) { - pcache = &cache[0]; + pcache = &peasycap->cache[0]; switch (bytesperpixel - rump) { case 1: { *p3 = r; @@ -1616,7 +1621,7 @@ case 3: break; } default: { - SAY("MISTAKE: %i=rump\n", \ + SAM("MISTAKE: %i=rump\n", \ bytesperpixel - rump); return -EFAULT; } @@ -1674,7 +1679,7 @@ case 3: 0 : (__u8)s32); if ((true == last) && rump) { - pcache = &cache[0]; + pcache = &peasycap->cache[0]; switch (bytesperpixel - rump) { case 1: { *p3 = b; @@ -1689,7 +1694,7 @@ case 3: break; } default: { - SAY("MISTAKE: %i=rump\n", \ + SAM("MISTAKE: %i=rump\n", \ bytesperpixel - rump); return -EFAULT; } @@ -1750,7 +1755,7 @@ case 3: 0 : (__u8)s32); if ((true == last) && rump) { - pcache = &cache[0]; + pcache = &peasycap->cache[0]; switch (bytesperpixel - rump) { case 1: { *p3 = r; @@ -1765,7 +1770,7 @@ case 3: break; } default: { - SAY("MISTAKE: " \ + SAM("MISTAKE: " \ "%i=rump\n", \ bytesperpixel - rump); return -EFAULT; @@ -1826,7 +1831,7 @@ case 3: 0 : (__u8)s32); if ((true == last) && rump) { - pcache = &cache[0]; + pcache = &peasycap->cache[0]; switch (bytesperpixel - rump) { case 1: { *p3 = b; @@ -1841,7 +1846,7 @@ case 3: break; } default: { - SAY("MISTAKE: " \ + SAM("MISTAKE: " \ "%i=rump\n", \ bytesperpixel - rump); return -EFAULT; @@ -1906,7 +1911,7 @@ case 4: 0 : (__u8)s32); if ((true == last) && rump) { - pcache = &cache[0]; + pcache = &peasycap->cache[0]; switch (bytesperpixel - rump) { case 1: { *p3 = r; @@ -1930,7 +1935,7 @@ case 4: break; } default: { - SAY("MISTAKE: %i=rump\n", \ + SAM("MISTAKE: %i=rump\n", \ bytesperpixel - rump); return -EFAULT; } @@ -1988,7 +1993,7 @@ case 4: 0 : (__u8)s32); if ((true == last) && rump) { - pcache = &cache[0]; + pcache = &peasycap->cache[0]; switch (bytesperpixel - rump) { case 1: { *p3 = b; @@ -2012,7 +2017,7 @@ case 4: break; } default: { - SAY("MISTAKE: %i=rump\n", \ + SAM("MISTAKE: %i=rump\n", \ bytesperpixel - rump); return -EFAULT; } @@ -2075,7 +2080,7 @@ case 4: 0 : (__u8)s32); if ((true == last) && rump) { - pcache = &cache[0]; + pcache = &peasycap->cache[0]; switch (bytesperpixel - rump) { case 1: { *p3 = r; @@ -2099,7 +2104,7 @@ case 4: break; } default: { - SAY("MISTAKE: " \ + SAM("MISTAKE: " \ "%i=rump\n", \ bytesperpixel - \ rump); @@ -2160,7 +2165,7 @@ case 4: 0 : (__u8)s32); if ((true == last) && rump) { - pcache = &cache[0]; + pcache = &peasycap->cache[0]; switch (bytesperpixel - rump) { case 1: { *p3 = b; @@ -2184,7 +2189,7 @@ case 4: break; } default: { - SAY("MISTAKE: " \ + SAM("MISTAKE: " \ "%i=rump\n", \ bytesperpixel - rump); return -EFAULT; @@ -2208,7 +2213,7 @@ case 4: break; } default: { - SAY("MISTAKE: %i=bytesperpixel\n", bytesperpixel); + SAM("MISTAKE: %i=bytesperpixel\n", bytesperpixel); return -EFAULT; } } @@ -2305,19 +2310,19 @@ if (NULL == peasycap) { /*---------------------------------------------------------------------------*/ pbuf = peasycap->frame_buffer[k][m].pgo; if (NULL == pbuf) { - SAY("ERROR: pbuf is NULL\n"); + SAM("ERROR: pbuf is NULL\n"); goto finish; } page = virt_to_page(pbuf); if (NULL == page) { - SAY("ERROR: page is NULL\n"); + SAM("ERROR: page is NULL\n"); goto finish; } get_page(page); /*---------------------------------------------------------------------------*/ finish: if (NULL == page) { - SAY("ERROR: page is NULL after get_page(page)\n"); + SAM("ERROR: page is NULL after get_page(page)\n"); } else { pvmf->page = page; retcode = VM_FAULT_MINOR; @@ -2353,7 +2358,6 @@ return retcode; void easycap_complete(struct urb *purb) { -static int mt; struct easycap *peasycap; struct data_buffer *pfield_buffer; char errbuf[16]; @@ -2379,64 +2383,64 @@ if (peasycap->video_eof) for (i = 0; i < VIDEO_ISOC_BUFFER_MANY; i++) if (purb->transfer_buffer == peasycap->video_isoc_buffer[i].pgo) break; -JOT(16, "%2i=urb\n", i); +JOM(16, "%2i=urb\n", i); last = peasycap->video_isoc_sequence; if ((((VIDEO_ISOC_BUFFER_MANY - 1) == last) && \ (0 != i)) || \ (((VIDEO_ISOC_BUFFER_MANY - 1) != last) && \ ((last + 1) != i))) { - SAY("ERROR: out-of-order urbs %i,%i ... continuing\n", last, i); + SAM("ERROR: out-of-order urbs %i,%i ... continuing\n", last, i); } peasycap->video_isoc_sequence = i; if (peasycap->video_idle) { - JOT(16, "%i=video_idle %i=video_isoc_streaming\n", \ + JOM(16, "%i=video_idle %i=video_isoc_streaming\n", \ peasycap->video_idle, peasycap->video_isoc_streaming); if (peasycap->video_isoc_streaming) { rc = usb_submit_urb(purb, GFP_ATOMIC); if (0 != rc) { - SAY("ERROR: while %i=video_idle, " \ + SAM("ERROR: while %i=video_idle, " \ "usb_submit_urb() failed with rc:\n", \ peasycap->video_idle); switch (rc) { case -ENOMEM: { - SAY("ENOMEM\n"); + SAM("ENOMEM\n"); break; } case -ENODEV: { - SAY("ENODEV\n"); + SAM("ENODEV\n"); break; } case -ENXIO: { - SAY("ENXIO\n"); + SAM("ENXIO\n"); break; } case -EINVAL: { - SAY("EINVAL\n"); + SAM("EINVAL\n"); break; } case -EAGAIN: { - SAY("EAGAIN\n"); + SAM("EAGAIN\n"); break; } case -EFBIG: { - SAY("EFBIG\n"); + SAM("EFBIG\n"); break; } case -EPIPE: { - SAY("EPIPE\n"); + SAM("EPIPE\n"); break; } case -EMSGSIZE: { - SAY("EMSGSIZE\n"); + SAM("EMSGSIZE\n"); break; } case -ENOSPC: { - SAY("ENOSPC\n"); + SAM("ENOSPC\n"); break; } default: { - SAY("0x%08X\n", rc); + SAM("0x%08X\n", rc); break; } } @@ -2447,80 +2451,80 @@ return; override = 0; /*---------------------------------------------------------------------------*/ if (FIELD_BUFFER_MANY <= peasycap->field_fill) { - SAY("ERROR: bad peasycap->field_fill\n"); + SAM("ERROR: bad peasycap->field_fill\n"); return; } if (purb->status) { if ((-ESHUTDOWN == purb->status) || (-ENOENT == purb->status)) { - JOT(8, "urb status -ESHUTDOWN or -ENOENT\n"); + JOM(8, "urb status -ESHUTDOWN or -ENOENT\n"); return; } (peasycap->field_buffer[peasycap->field_fill][0].kount) |= 0x8000 ; - SAY("ERROR: bad urb status:\n"); + SAM("ERROR: bad urb status:\n"); switch (purb->status) { case -EINPROGRESS: { - SAY("-EINPROGRESS\n"); break; + SAM("-EINPROGRESS\n"); break; } case -ENOSR: { - SAY("-ENOSR\n"); break; + SAM("-ENOSR\n"); break; } case -EPIPE: { - SAY("-EPIPE\n"); break; + SAM("-EPIPE\n"); break; } case -EOVERFLOW: { - SAY("-EOVERFLOW\n"); break; + SAM("-EOVERFLOW\n"); break; } case -EPROTO: { - SAY("-EPROTO\n"); break; + SAM("-EPROTO\n"); break; } case -EILSEQ: { - SAY("-EILSEQ\n"); break; + SAM("-EILSEQ\n"); break; } case -ETIMEDOUT: { - SAY("-ETIMEDOUT\n"); break; + SAM("-ETIMEDOUT\n"); break; } case -EMSGSIZE: { - SAY("-EMSGSIZE\n"); break; + SAM("-EMSGSIZE\n"); break; } case -EOPNOTSUPP: { - SAY("-EOPNOTSUPP\n"); break; + SAM("-EOPNOTSUPP\n"); break; } case -EPFNOSUPPORT: { - SAY("-EPFNOSUPPORT\n"); break; + SAM("-EPFNOSUPPORT\n"); break; } case -EAFNOSUPPORT: { - SAY("-EAFNOSUPPORT\n"); break; + SAM("-EAFNOSUPPORT\n"); break; } case -EADDRINUSE: { - SAY("-EADDRINUSE\n"); break; + SAM("-EADDRINUSE\n"); break; } case -EADDRNOTAVAIL: { - SAY("-EADDRNOTAVAIL\n"); break; + SAM("-EADDRNOTAVAIL\n"); break; } case -ENOBUFS: { - SAY("-ENOBUFS\n"); break; + SAM("-ENOBUFS\n"); break; } case -EISCONN: { - SAY("-EISCONN\n"); break; + SAM("-EISCONN\n"); break; } case -ENOTCONN: { - SAY("-ENOTCONN\n"); break; + SAM("-ENOTCONN\n"); break; } case -ESHUTDOWN: { - SAY("-ESHUTDOWN\n"); break; + SAM("-ESHUTDOWN\n"); break; } case -ENOENT: { - SAY("-ENOENT\n"); break; + SAM("-ENOENT\n"); break; } case -ECONNRESET: { - SAY("-ECONNRESET\n"); break; + SAM("-ECONNRESET\n"); break; } case -ENOSPC: { - SAY("ENOSPC\n"); break; + SAM("ENOSPC\n"); break; } default: { - SAY("unknown error code 0x%08X\n", purb->status); break; + SAM("unknown error code 0x%08X\n", purb->status); break; } } /*---------------------------------------------------------------------------*/ @@ -2579,7 +2583,7 @@ if (purb->status) { strcpy(&errbuf[0], "-ECONNRESET"); break; } case -ENOSPC: { - SAY("ENOSPC\n"); break; + SAM("ENOSPC\n"); break; } case -ESHUTDOWN: { strcpy(&errbuf[0], "-ESHUTDOWN"); break; @@ -2594,7 +2598,7 @@ if (purb->status) { frameactual = purb->iso_frame_desc[i].actual_length; frameoffset = purb->iso_frame_desc[i].offset; - JOT(16, "frame[%2i]:" \ + JOM(16, "frame[%2i]:" \ "%4i=status " \ "%4i=actual " \ "%4i=length " \ @@ -2608,19 +2612,20 @@ if (purb->status) { PAGE_SIZE) + \ (int)(pfield_buffer->pto - pfield_buffer->pgo); if (4 == more) - mt++; + peasycap->video_mt++; if (4 < more) { - if (mt) { - JOT(8, "%4i empty video urb frames\n", mt); - mt = 0; + if (peasycap->video_mt) { + JOM(8, "%4i empty video urb frames\n", \ + peasycap->video_mt); + peasycap->video_mt = 0; } if (FIELD_BUFFER_MANY <= peasycap->field_fill) { - SAY("ERROR: bad peasycap->field_fill\n"); + SAM("ERROR: bad peasycap->field_fill\n"); return; } if (FIELD_BUFFER_SIZE/PAGE_SIZE <= \ peasycap->field_page) { - SAY("ERROR: bad peasycap->field_page\n"); + SAM("ERROR: bad peasycap->field_page\n"); return; } pfield_buffer = &peasycap->field_buffer\ @@ -2653,11 +2658,11 @@ if (purb->status) { peasycap->videofieldamount) { if (2 == videofieldamount - \ peasycap->\ - videofieldamount) + videofieldamount) { (peasycap->field_buffer\ [peasycap->field_fill]\ [0].kount) |= 0x0100; - else + } else (peasycap->field_buffer\ [peasycap->field_fill]\ [0].kount) |= 0x4000; @@ -2689,15 +2694,15 @@ if (purb->status) { pfield_buffer->pto = \ pfield_buffer->pgo; - JOT(8, "bumped to: %i=peasycap->" \ + JOM(8, "bumped to: %i=peasycap->" \ "field_fill %i=parity\n", \ peasycap->field_fill, \ 0x00FF & pfield_buffer->kount); - JOT(8, "field buffer %i has %i " \ + JOM(8, "field buffer %i has %i " \ "bytes fit to be read\n", \ peasycap->field_read, \ videofieldamount); - JOT(8, "wakeup call to wq_video, " \ + JOM(8, "wakeup call to wq_video, " \ "%i=field_read %i=field_fill "\ "%i=parity\n", \ peasycap->field_read, \ @@ -2710,7 +2715,7 @@ if (purb->status) { do_gettimeofday(&peasycap->timeval7); } else { peasycap->video_junk++; - JOT(8, "field buffer %i had %i " \ + JOM(8, "field buffer %i had %i " \ "bytes, now discarded\n", \ peasycap->field_fill, \ videofieldamount); @@ -2728,20 +2733,20 @@ if (purb->status) { pfield_buffer->pto = \ pfield_buffer->pgo; - JOT(8, "bumped to: %i=peasycap->" \ + JOM(8, "bumped to: %i=peasycap->" \ "field_fill %i=parity\n", \ peasycap->field_fill, \ 0x00FF & pfield_buffer->kount); } if (8 == more) { - JOT(8, "end-of-field: received " \ + JOM(8, "end-of-field: received " \ "parity byte 0x%02X\n", \ (0xFF & *pu)); if (0x40 & *pu) pfield_buffer->kount = 0x0000; else pfield_buffer->kount = 0x0001; - JOT(8, "end-of-field: 0x%02X=kount\n",\ + JOM(8, "end-of-field: 0x%02X=kount\n",\ 0xFF & pfield_buffer->kount); } } @@ -2754,12 +2759,12 @@ if (purb->status) { more -= leap; if (FIELD_BUFFER_MANY <= peasycap->field_fill) { - SAY("ERROR: bad peasycap->field_fill\n"); + SAM("ERROR: bad peasycap->field_fill\n"); return; } if (FIELD_BUFFER_SIZE/PAGE_SIZE <= \ peasycap->field_page) { - SAY("ERROR: bad peasycap->field_page\n"); + SAM("ERROR: bad peasycap->field_page\n"); return; } pfield_buffer = &peasycap->field_buffer\ @@ -2770,7 +2775,7 @@ if (purb->status) { [peasycap->field_page]; if (PAGE_SIZE < (pfield_buffer->pto - \ pfield_buffer->pgo)) { - SAY("ERROR: bad pfield_buffer->pto\n"); + SAM("ERROR: bad pfield_buffer->pto\n"); return; } if (PAGE_SIZE == (pfield_buffer->pto - \ @@ -2778,7 +2783,7 @@ if (purb->status) { (peasycap->field_page)++; if (FIELD_BUFFER_SIZE/PAGE_SIZE <= \ peasycap->field_page) { - JOT(16, "wrapping peasycap->" \ + JOM(16, "wrapping peasycap->" \ "field_page\n"); peasycap->field_page = 0; } @@ -2813,7 +2818,7 @@ if (purb->status) { */ /*---------------------------------------------------------------------------*/ if (VIDEO_ISOC_BUFFER_MANY <= peasycap->video_junk) { - SAY("easycap driver shutting down on condition green\n"); + SAM("easycap driver shutting down on condition green\n"); peasycap->video_eof = 1; peasycap->audio_eof = 1; peasycap->video_junk = -VIDEO_ISOC_BUFFER_MANY; @@ -2824,38 +2829,38 @@ if (VIDEO_ISOC_BUFFER_MANY <= peasycap->video_junk) { if (peasycap->video_isoc_streaming) { rc = usb_submit_urb(purb, GFP_ATOMIC); if (0 != rc) { - SAY("ERROR: while %i=video_idle, usb_submit_urb() failed " \ + SAM("ERROR: while %i=video_idle, usb_submit_urb() failed " \ "with rc:\n", peasycap->video_idle); switch (rc) { case -ENOMEM: { - SAY("ENOMEM\n"); break; + SAM("ENOMEM\n"); break; } case -ENODEV: { - SAY("ENODEV\n"); break; + SAM("ENODEV\n"); break; } case -ENXIO: { - SAY("ENXIO\n"); break; + SAM("ENXIO\n"); break; } case -EINVAL: { - SAY("EINVAL\n"); break; + SAM("EINVAL\n"); break; } case -EAGAIN: { - SAY("EAGAIN\n"); break; + SAM("EAGAIN\n"); break; } case -EFBIG: { - SAY("EFBIG\n"); break; + SAM("EFBIG\n"); break; } case -EPIPE: { - SAY("EPIPE\n"); break; + SAM("EPIPE\n"); break; } case -EMSGSIZE: { - SAY("EMSGSIZE\n"); break; + SAM("EMSGSIZE\n"); break; } case -ENOSPC: { - SAY("ENOSPC\n"); break; + SAM("ENOSPC\n"); break; } default: { - SAY("0x%08X\n", rc); break; + SAM("0x%08X\n", rc); break; } } } @@ -2886,7 +2891,7 @@ struct usb_endpoint_descriptor *pepd; struct usb_interface_descriptor *pusb_interface_descriptor; struct usb_interface_assoc_descriptor *pusb_interface_assoc_descriptor; struct urb *purb; -static struct easycap *peasycap /*=NULL*/; +struct easycap *peasycap; struct data_urb *pdata_urb; size_t wMaxPacketSize; int ISOCwMaxPacketSize; @@ -2896,18 +2901,18 @@ int CTRLwMaxPacketSize; __u8 bEndpointAddress; __u8 ISOCbEndpointAddress; __u8 INTbEndpointAddress; -int isin, i, j, k, m; +int isin, i, j, k, m, rc; __u8 bInterfaceNumber; __u8 bInterfaceClass; __u8 bInterfaceSubClass; void *pbuf; int okalt[8], isokalt; -int okepn[8], isokepn; -int okmps[8], isokmps; +int okepn[8]; +int okmps[8]; int maxpacketsize; -int rc; JOT(4, "\n"); +peasycap = (struct easycap *)NULL; if ((struct usb_interface *)NULL == pusb_interface) { SAY("ERROR: pusb_interface is NULL\n"); @@ -3009,40 +3014,74 @@ JOT(4, "intf[%i]: pusb_interface_assoc_descriptor is NULL\n", \ /* * A NEW struct easycap IS ALWAYS ALLOCATED WHEN INTERFACE 0 IS PROBED. * IT IS NOT POSSIBLE HERE TO FREE ANY EXISTING struct easycap. THIS - * SHOULD HAVE BEEN DONE BY easycap_delete() WHEN THE DEVICE WAS PHYSICALLY - * UNPLUGGED. - */ + * SHOULD HAVE BEEN DONE BY easycap_delete() WHEN THE EasyCAP WAS + * PHYSICALLY UNPLUGGED. + * + * THE POINTER peasycap TO THE struct easycap IS REMEMBERED WHEN + * INTERFACES 1 AND 2 ARE PROBED. + * + * IF TWO EasyCAPs ARE PLUGGED IN NEARLY SIMULTANEOUSLY THERE WILL + * BE TROUBLE. BEWARE. +*/ /*---------------------------------------------------------------------------*/ if (0 == bInterfaceNumber) { peasycap = kzalloc(sizeof(struct easycap), GFP_KERNEL); if (NULL == peasycap) { SAY("ERROR: Could not allocate peasycap\n"); return -ENOMEM; - } else { - peasycap->allocation_video_struct = sizeof(struct easycap); - peasycap->allocation_video_page = 0; - peasycap->allocation_video_urb = 0; - peasycap->allocation_audio_struct = 0; - peasycap->allocation_audio_page = 0; - peasycap->allocation_audio_urb = 0; } + SAM("allocated 0x%08lX=peasycap\n", (unsigned long int) peasycap); +/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +#if defined(EASYCAP_IS_VIDEODEV_CLIENT) + SAM("where 0x%08lX=&peasycap->video_device\n", \ + (unsigned long int) &peasycap->video_device); +#if defined(EASYCAP_NEEDS_V4L2_DEVICE_H) + SAM("and 0x%08lX=&peasycap->v4l2_device\n", \ + (unsigned long int) &peasycap->v4l2_device); +#endif /*EASYCAP_NEEDS_V4L2_DEVICE_H*/ +#endif /*EASYCAP_IS_VIDEODEV_CLIENT*/ +/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ /*---------------------------------------------------------------------------*/ /* - * INITIALIZE THE NEW easycap STRUCTURE. - * NO PARAMETERS ARE SPECIFIED HERE REQUIRING THE SETTING OF REGISTERS. - * THAT IS DONE FIRST BY easycap_open() AND LATER BY easycap_ioctl(). - */ + * PERFORM URGENT INTIALIZATIONS ... +*/ /*---------------------------------------------------------------------------*/ - peasycap->pusb_device = pusb_device; - peasycap->pusb_interface = pusb_interface; - kref_init(&peasycap->kref); - JOT(8, "intf[%i]: after kref_init(..._video) " \ + JOM(8, "intf[%i]: after kref_init(..._video) " \ "%i=peasycap->kref.refcount.counter\n", \ bInterfaceNumber, peasycap->kref.refcount.counter); - init_waitqueue_head(&(peasycap->wq_video)); - init_waitqueue_head(&(peasycap->wq_audio)); + init_waitqueue_head(&peasycap->wq_video); + init_waitqueue_head(&peasycap->wq_audio); + + for (dongle_this = 0; dongle_this < DONGLE_MANY; dongle_this++) { + if ((struct easycap *)NULL == peasycap_dongle[dongle_this]) { + peasycap_dongle[dongle_this] = peasycap; + JOM(8, "intf[%i]: peasycap-->easycap" \ + "_dongle[%i].peasycap\n", \ + bInterfaceNumber, dongle_this); + break; + } + } + if (DONGLE_MANY <= dongle_this) { + SAM("ERROR: too many dongles\n"); + return -ENOMEM; + } + + peasycap->allocation_video_struct = sizeof(struct easycap); + peasycap->allocation_video_page = 0; + peasycap->allocation_video_urb = 0; + peasycap->allocation_audio_struct = 0; + peasycap->allocation_audio_page = 0; + peasycap->allocation_audio_urb = 0; + +/*---------------------------------------------------------------------------*/ +/* + * ... AND FURTHER INITIALIZE THE STRUCTURE +*/ +/*---------------------------------------------------------------------------*/ + peasycap->pusb_device = pusb_device; + peasycap->pusb_interface = pusb_interface; peasycap->ilk = 0; peasycap->microphone = false; @@ -3062,6 +3101,8 @@ if (0 == bInterfaceNumber) { peasycap->audio_isoc_buffer_size = -1; peasycap->frame_buffer_many = FRAME_BUFFER_MANY; + + peasycap->offerfields = 0; /*---------------------------------------------------------------------------*/ /* * DYNAMICALLY FILL IN THE AVAILABLE FORMATS. @@ -3069,35 +3110,46 @@ if (0 == bInterfaceNumber) { /*---------------------------------------------------------------------------*/ rc = fillin_formats(); if (0 > rc) { - SAY("ERROR: fillin_formats() returned %i\n", rc); + SAM("ERROR: fillin_formats() returned %i\n", rc); return -EFAULT; } - JOT(4, "%i formats available\n", rc); - } else { + JOM(4, "%i formats available\n", rc); + JOM(4, "finished initialization\n"); +} else { /*---------------------------------------------------------------------------*/ - if ((struct easycap *)NULL == peasycap) { - SAY("ERROR: peasycap is NULL " \ - "when probing interface %i\n", \ - bInterfaceNumber); - return -EFAULT; - } + /* + * FOR INTERFACES 1 AND 2 THE POINTER peasycap IS OBTAINED BY ASSUMING + * THAT dongle_this HAS NOT CHANGED SINCE INTERFACE 0 WAS PROBED. IF + * THIS IS NOT THE CASE, FOR EXAMPLE WHEN TWO EASYCAPs ARE PLUGGED IN + * SIMULTANEOUSLY, THERE WILL BE VERY SERIOUS TROUBLE. + */ +/*---------------------------------------------------------------------------*/ + if ((0 > dongle_this) || (DONGLE_MANY <= dongle_this)) { + SAY("ERROR: bad dongle count\n"); + return -EFAULT; + } + peasycap = peasycap_dongle[dongle_this]; + JOT(8, "intf[%i]: peasycap_dongle[%i]-->peasycap\n", \ + bInterfaceNumber, dongle_this); - JOT(8, "kref_get() with %i=peasycap->kref.refcount.counter\n", \ - (int)peasycap->kref.refcount.counter); - kref_get(&peasycap->kref); + if ((struct easycap *)NULL == peasycap) { + SAY("ERROR: peasycap is NULL when probing interface %i\n", \ + bInterfaceNumber); + return -EFAULT; + } } /*---------------------------------------------------------------------------*/ if ((USB_CLASS_VIDEO == bInterfaceClass) || \ - (USB_CLASS_VENDOR_SPEC == bInterfaceClass)) { + (USB_CLASS_VENDOR_SPEC == bInterfaceClass)) { if (-1 == peasycap->video_interface) { peasycap->video_interface = bInterfaceNumber; - JOT(4, "setting peasycap->video_interface=%i\n", \ + JOM(4, "setting peasycap->video_interface=%i\n", \ peasycap->video_interface); } else { if (peasycap->video_interface != bInterfaceNumber) { - SAY("ERROR: attempting to reset " \ + SAM("ERROR: attempting to reset " \ "peasycap->video_interface\n"); - SAY("...... continuing with " \ + SAM("...... continuing with " \ "%i=peasycap->video_interface\n", \ peasycap->video_interface); } @@ -3106,13 +3158,13 @@ if ((USB_CLASS_VIDEO == bInterfaceClass) || \ (0x02 == bInterfaceSubClass)) { if (-1 == peasycap->audio_interface) { peasycap->audio_interface = bInterfaceNumber; - JOT(4, "setting peasycap->audio_interface=%i\n", \ + JOM(4, "setting peasycap->audio_interface=%i\n", \ peasycap->audio_interface); } else { if (peasycap->audio_interface != bInterfaceNumber) { - SAY("ERROR: attempting to reset " \ + SAM("ERROR: attempting to reset " \ "peasycap->audio_interface\n"); - SAY("...... continuing with " \ + SAM("...... continuing with " \ "%i=peasycap->audio_interface\n", \ peasycap->audio_interface); } @@ -3125,37 +3177,34 @@ if ((USB_CLASS_VIDEO == bInterfaceClass) || \ */ /*---------------------------------------------------------------------------*/ isokalt = 0; -isokepn = 0; -isokmps = 0; - for (i = 0; i < pusb_interface->num_altsetting; i++) { pusb_host_interface = &(pusb_interface->altsetting[i]); if ((struct usb_host_interface *)NULL == pusb_host_interface) { - SAY("ERROR: pusb_host_interface is NULL\n"); + SAM("ERROR: pusb_host_interface is NULL\n"); return -EFAULT; } pusb_interface_descriptor = &(pusb_host_interface->desc); if ((struct usb_interface_descriptor *)NULL == \ pusb_interface_descriptor) { - SAY("ERROR: pusb_interface_descriptor is NULL\n"); + SAM("ERROR: pusb_interface_descriptor is NULL\n"); return -EFAULT; } - JOT(4, "intf[%i]alt[%i]: desc.bDescriptorType=0x%02X\n", \ + JOM(4, "intf[%i]alt[%i]: desc.bDescriptorType=0x%02X\n", \ bInterfaceNumber, i, pusb_interface_descriptor->bDescriptorType); - JOT(4, "intf[%i]alt[%i]: desc.bInterfaceNumber=0x%02X\n", \ + JOM(4, "intf[%i]alt[%i]: desc.bInterfaceNumber=0x%02X\n", \ bInterfaceNumber, i, pusb_interface_descriptor->bInterfaceNumber); - JOT(4, "intf[%i]alt[%i]: desc.bAlternateSetting=0x%02X\n", \ + JOM(4, "intf[%i]alt[%i]: desc.bAlternateSetting=0x%02X\n", \ bInterfaceNumber, i, pusb_interface_descriptor->bAlternateSetting); - JOT(4, "intf[%i]alt[%i]: desc.bNumEndpoints=0x%02X\n", \ + JOM(4, "intf[%i]alt[%i]: desc.bNumEndpoints=0x%02X\n", \ bInterfaceNumber, i, pusb_interface_descriptor->bNumEndpoints); - JOT(4, "intf[%i]alt[%i]: desc.bInterfaceClass=0x%02X\n", \ + JOM(4, "intf[%i]alt[%i]: desc.bInterfaceClass=0x%02X\n", \ bInterfaceNumber, i, pusb_interface_descriptor->bInterfaceClass); - JOT(4, "intf[%i]alt[%i]: desc.bInterfaceSubClass=0x%02X\n", \ + JOM(4, "intf[%i]alt[%i]: desc.bInterfaceSubClass=0x%02X\n", \ bInterfaceNumber, i, pusb_interface_descriptor->bInterfaceSubClass); - JOT(4, "intf[%i]alt[%i]: desc.bInterfaceProtocol=0x%02X\n", \ + JOM(4, "intf[%i]alt[%i]: desc.bInterfaceProtocol=0x%02X\n", \ bInterfaceNumber, i, pusb_interface_descriptor->bInterfaceProtocol); - JOT(4, "intf[%i]alt[%i]: desc.iInterface=0x%02X\n", \ + JOM(4, "intf[%i]alt[%i]: desc.iInterface=0x%02X\n", \ bInterfaceNumber, i, pusb_interface_descriptor->iInterface); ISOCwMaxPacketSize = -1; @@ -3166,86 +3215,80 @@ for (i = 0; i < pusb_interface->num_altsetting; i++) { INTbEndpointAddress = 0; if (0 == pusb_interface_descriptor->bNumEndpoints) - JOT(4, "intf[%i]alt[%i] has no endpoints\n", \ + JOM(4, "intf[%i]alt[%i] has no endpoints\n", \ bInterfaceNumber, i); /*---------------------------------------------------------------------------*/ for (j = 0; j < pusb_interface_descriptor->bNumEndpoints; j++) { pepd = &(pusb_host_interface->endpoint[j].desc); if ((struct usb_endpoint_descriptor *)NULL == pepd) { - SAY("ERROR: pepd is NULL.\n"); - SAY("...... skipping\n"); + SAM("ERROR: pepd is NULL.\n"); + SAM("...... skipping\n"); continue; } wMaxPacketSize = le16_to_cpu(pepd->wMaxPacketSize); bEndpointAddress = pepd->bEndpointAddress; - JOT(4, "intf[%i]alt[%i]end[%i]: bEndpointAddress=0x%X\n", \ + JOM(4, "intf[%i]alt[%i]end[%i]: bEndpointAddress=0x%X\n", \ bInterfaceNumber, i, j, \ pepd->bEndpointAddress); - JOT(4, "intf[%i]alt[%i]end[%i]: bmAttributes=0x%X\n", \ + JOM(4, "intf[%i]alt[%i]end[%i]: bmAttributes=0x%X\n", \ bInterfaceNumber, i, j, \ pepd->bmAttributes); - JOT(4, "intf[%i]alt[%i]end[%i]: wMaxPacketSize=%i\n", \ + JOM(4, "intf[%i]alt[%i]end[%i]: wMaxPacketSize=%i\n", \ bInterfaceNumber, i, j, \ pepd->wMaxPacketSize); - JOT(4, "intf[%i]alt[%i]end[%i]: bInterval=%i\n", + JOM(4, "intf[%i]alt[%i]end[%i]: bInterval=%i\n", bInterfaceNumber, i, j, \ pepd->bInterval); if (pepd->bEndpointAddress & USB_DIR_IN) { - JOT(4, "intf[%i]alt[%i]end[%i] is an IN endpoint\n",\ + JOM(4, "intf[%i]alt[%i]end[%i] is an IN endpoint\n",\ bInterfaceNumber, i, j); isin = 1; } else { - JOT(4, "intf[%i]alt[%i]end[%i] is an OUT endpoint\n",\ + JOM(4, "intf[%i]alt[%i]end[%i] is an OUT endpoint\n",\ bInterfaceNumber, i, j); - SAY("ERROR: OUT endpoint unexpected\n"); - SAY("...... continuing\n"); + SAM("ERROR: OUT endpoint unexpected\n"); + SAM("...... continuing\n"); isin = 0; } if ((pepd->bmAttributes & \ USB_ENDPOINT_XFERTYPE_MASK) == \ USB_ENDPOINT_XFER_ISOC) { - JOT(4, "intf[%i]alt[%i]end[%i] is an ISOC endpoint\n",\ + JOM(4, "intf[%i]alt[%i]end[%i] is an ISOC endpoint\n",\ bInterfaceNumber, i, j); if (isin) { switch (bInterfaceClass) { case USB_CLASS_VIDEO: case USB_CLASS_VENDOR_SPEC: { if (!peasycap) { - SAY("MISTAKE: " \ + SAM("MISTAKE: " \ "peasycap is NULL\n"); return -EFAULT; } if (pepd->wMaxPacketSize) { if (8 > isokalt) { okalt[isokalt] = i; - JOT(4,\ + JOM(4,\ "%i=okalt[%i]\n", \ okalt[isokalt], \ isokalt); - isokalt++; - } - if (8 > isokepn) { - okepn[isokepn] = \ + okepn[isokalt] = \ pepd->\ bEndpointAddress & \ 0x0F; - JOT(4,\ + JOM(4,\ "%i=okepn[%i]\n", \ - okepn[isokepn], \ - isokepn); - isokepn++; - } - if (8 > isokmps) { - okmps[isokmps] = \ + okepn[isokalt], \ + isokalt); + okmps[isokalt] = \ le16_to_cpu(pepd->\ wMaxPacketSize); - JOT(4,\ + JOM(4,\ "%i=okmps[%i]\n", \ - okmps[isokmps], \ - isokmps); - isokmps++; + okmps[isokalt], \ + isokalt); + isokalt++; } } else { if (-1 == peasycap->\ @@ -3253,16 +3296,16 @@ for (i = 0; i < pusb_interface->num_altsetting; i++) { peasycap->\ video_altsetting_off =\ i; - JOT(4, "%i=video_" \ + JOM(4, "%i=video_" \ "altsetting_off " \ "<====\n", \ peasycap->\ video_altsetting_off); } else { - SAY("ERROR: peasycap" \ + SAM("ERROR: peasycap" \ "->video_altsetting_" \ "off already set\n"); - SAY("...... " \ + SAM("...... " \ "continuing with " \ "%i=peasycap->video_" \ "altsetting_off\n", \ @@ -3276,39 +3319,33 @@ for (i = 0; i < pusb_interface->num_altsetting; i++) { if (0x02 != bInterfaceSubClass) break; if (!peasycap) { - SAY("MISTAKE: " \ + SAM("MISTAKE: " \ "peasycap is NULL\n"); return -EFAULT; } if (pepd->wMaxPacketSize) { if (8 > isokalt) { okalt[isokalt] = i ; - JOT(4,\ + JOM(4,\ "%i=okalt[%i]\n", \ okalt[isokalt], \ isokalt); - isokalt++; - } - if (8 > isokepn) { - okepn[isokepn] = \ + okepn[isokalt] = \ pepd->\ bEndpointAddress & \ 0x0F; - JOT(4,\ + JOM(4,\ "%i=okepn[%i]\n", \ - okepn[isokepn], \ - isokepn); - isokepn++; - } - if (8 > isokmps) { - okmps[isokmps] = \ + okepn[isokalt], \ + isokalt); + okmps[isokalt] = \ le16_to_cpu(pepd->\ wMaxPacketSize); - JOT(4,\ + JOM(4,\ "%i=okmps[%i]\n",\ - okmps[isokmps], \ - isokmps); - isokmps++; + okmps[isokalt], \ + isokalt); + isokalt++; } } else { if (-1 == peasycap->\ @@ -3316,16 +3353,16 @@ for (i = 0; i < pusb_interface->num_altsetting; i++) { peasycap->\ audio_altsetting_off =\ i; - JOT(4, "%i=audio_" \ + JOM(4, "%i=audio_" \ "altsetting_off " \ "<====\n", \ peasycap->\ audio_altsetting_off); } else { - SAY("ERROR: peasycap" \ + SAM("ERROR: peasycap" \ "->audio_altsetting_" \ "off already set\n"); - SAY("...... " \ + SAM("...... " \ "continuing with " \ "%i=peasycap->\ audio_altsetting_" \ @@ -3343,19 +3380,19 @@ for (i = 0; i < pusb_interface->num_altsetting; i++) { } else if ((pepd->bmAttributes & \ USB_ENDPOINT_XFERTYPE_MASK) ==\ USB_ENDPOINT_XFER_BULK) { - JOT(4, "intf[%i]alt[%i]end[%i] is a BULK endpoint\n",\ + JOM(4, "intf[%i]alt[%i]end[%i] is a BULK endpoint\n",\ bInterfaceNumber, i, j); } else if ((pepd->bmAttributes & \ USB_ENDPOINT_XFERTYPE_MASK) ==\ USB_ENDPOINT_XFER_INT) { - JOT(4, "intf[%i]alt[%i]end[%i] is an INT endpoint\n",\ + JOM(4, "intf[%i]alt[%i]end[%i] is an INT endpoint\n",\ bInterfaceNumber, i, j); } else { - JOT(4, "intf[%i]alt[%i]end[%i] is a CTRL endpoint\n",\ + JOM(4, "intf[%i]alt[%i]end[%i] is a CTRL endpoint\n",\ bInterfaceNumber, i, j); } if (0 == pepd->wMaxPacketSize) { - JOT(4, "intf[%i]alt[%i]end[%i] " \ + JOM(4, "intf[%i]alt[%i]end[%i] " \ "has zero packet size\n", \ bInterfaceNumber, i, j); } @@ -3366,7 +3403,7 @@ for (i = 0; i < pusb_interface->num_altsetting; i++) { * PERFORM INITIALIZATION OF THE PROBED INTERFACE */ /*---------------------------------------------------------------------------*/ -JOT(4, "initialization begins for interface %i\n", \ +JOM(4, "initialization begins for interface %i\n", \ pusb_interface_descriptor->bInterfaceNumber); switch (bInterfaceNumber) { /*---------------------------------------------------------------------------*/ @@ -3376,89 +3413,78 @@ switch (bInterfaceNumber) { /*---------------------------------------------------------------------------*/ case 0: { if (!peasycap) { - SAY("MISTAKE: peasycap is NULL\n"); + SAM("MISTAKE: peasycap is NULL\n"); return -EFAULT; } if (!isokalt) { - SAY("ERROR: no viable video_altsetting_on\n"); + SAM("ERROR: no viable video_altsetting_on\n"); return -ENOENT; } else { peasycap->video_altsetting_on = okalt[isokalt - 1]; - JOT(4, "%i=video_altsetting_on <====\n", \ + JOM(4, "%i=video_altsetting_on <====\n", \ peasycap->video_altsetting_on); } - if (!isokepn) { - SAY("ERROR: no viable video_endpointnumber\n"); - return -ENOENT; - } else { - peasycap->video_endpointnumber = okepn[isokepn - 1]; - JOT(4, "%i=video_endpointnumber\n", \ - peasycap->video_endpointnumber); - } - if (!isokmps) { - SAY("ERROR: no viable video_maxpacketsize\n"); - return -ENOENT; /*---------------------------------------------------------------------------*/ /* * DECIDE THE VIDEO STREAMING PARAMETERS */ /*---------------------------------------------------------------------------*/ + peasycap->video_endpointnumber = okepn[isokalt - 1]; + JOM(4, "%i=video_endpointnumber\n", peasycap->video_endpointnumber); + maxpacketsize = okmps[isokalt - 1]; + if (USB_2_0_MAXPACKETSIZE > maxpacketsize) { + peasycap->video_isoc_maxframesize = maxpacketsize; } else { - maxpacketsize = okmps[isokmps - 1] - 1024; - if (USB_2_0_MAXPACKETSIZE > maxpacketsize) { - peasycap->video_isoc_maxframesize = maxpacketsize; - } else { - peasycap->video_isoc_maxframesize = \ - USB_2_0_MAXPACKETSIZE; - } - JOT(4, "%i=video_isoc_maxframesize\n", \ - peasycap->video_isoc_maxframesize); - if (0 >= peasycap->video_isoc_maxframesize) { - SAY("ERROR: bad video_isoc_maxframesize\n"); - return -ENOENT; - } - peasycap->video_isoc_framesperdesc = VIDEO_ISOC_FRAMESPERDESC; - JOT(4, "%i=video_isoc_framesperdesc\n", \ - peasycap->video_isoc_framesperdesc); - if (0 >= peasycap->video_isoc_framesperdesc) { - SAY("ERROR: bad video_isoc_framesperdesc\n"); - return -ENOENT; - } - peasycap->video_isoc_buffer_size = \ - peasycap->video_isoc_maxframesize * \ - peasycap->video_isoc_framesperdesc; - JOT(4, "%i=video_isoc_buffer_size\n", \ - peasycap->video_isoc_buffer_size); - if ((PAGE_SIZE << VIDEO_ISOC_ORDER) < \ - peasycap->video_isoc_buffer_size) { - SAY("MISTAKE: " \ - "peasycap->video_isoc_buffer_size too big\n"); - return -EFAULT; - } + peasycap->video_isoc_maxframesize = \ + USB_2_0_MAXPACKETSIZE; + } + JOM(4, "%i=video_isoc_maxframesize\n", \ + peasycap->video_isoc_maxframesize); + if (0 >= peasycap->video_isoc_maxframesize) { + SAM("ERROR: bad video_isoc_maxframesize\n"); + SAM(" possibly because port is USB 1.1\n"); + return -ENOENT; + } + peasycap->video_isoc_framesperdesc = VIDEO_ISOC_FRAMESPERDESC; + JOM(4, "%i=video_isoc_framesperdesc\n", \ + peasycap->video_isoc_framesperdesc); + if (0 >= peasycap->video_isoc_framesperdesc) { + SAM("ERROR: bad video_isoc_framesperdesc\n"); + return -ENOENT; + } + peasycap->video_isoc_buffer_size = \ + peasycap->video_isoc_maxframesize * \ + peasycap->video_isoc_framesperdesc; + JOM(4, "%i=video_isoc_buffer_size\n", \ + peasycap->video_isoc_buffer_size); + if ((PAGE_SIZE << VIDEO_ISOC_ORDER) < \ + peasycap->video_isoc_buffer_size) { + SAM("MISTAKE: peasycap->video_isoc_buffer_size too big\n"); + return -EFAULT; } /*---------------------------------------------------------------------------*/ if (-1 == peasycap->video_interface) { - SAY("MISTAKE: video_interface is unset\n"); + SAM("MISTAKE: video_interface is unset\n"); return -EFAULT; } if (-1 == peasycap->video_altsetting_on) { - SAY("MISTAKE: video_altsetting_on is unset\n"); + SAM("MISTAKE: video_altsetting_on is unset\n"); return -EFAULT; } if (-1 == peasycap->video_altsetting_off) { - SAY("MISTAKE: video_interface_off is unset\n"); + SAM("MISTAKE: video_interface_off is unset\n"); return -EFAULT; } if (-1 == peasycap->video_endpointnumber) { - SAY("MISTAKE: video_endpointnumber is unset\n"); + SAM("MISTAKE: video_endpointnumber is unset\n"); return -EFAULT; } if (-1 == peasycap->video_isoc_maxframesize) { - SAY("MISTAKE: video_isoc_maxframesize is unset\n"); + SAM("MISTAKE: video_isoc_maxframesize is unset\n"); return -EFAULT; } if (-1 == peasycap->video_isoc_buffer_size) { - SAY("MISTAKE: video_isoc_buffer_size is unset\n"); + SAM("MISTAKE: video_isoc_buffer_size is unset\n"); return -EFAULT; } /*---------------------------------------------------------------------------*/ @@ -3469,20 +3495,20 @@ case 0: { INIT_LIST_HEAD(&(peasycap->urb_video_head)); peasycap->purb_video_head = &(peasycap->urb_video_head); /*---------------------------------------------------------------------------*/ - JOT(4, "allocating %i frame buffers of size %li\n", \ + JOM(4, "allocating %i frame buffers of size %li\n", \ FRAME_BUFFER_MANY, (long int)FRAME_BUFFER_SIZE); - JOT(4, ".... each scattered over %li pages\n", \ + JOM(4, ".... each scattered over %li pages\n", \ FRAME_BUFFER_SIZE/PAGE_SIZE); for (k = 0; k < FRAME_BUFFER_MANY; k++) { for (m = 0; m < FRAME_BUFFER_SIZE/PAGE_SIZE; m++) { if ((void *)NULL != peasycap->frame_buffer[k][m].pgo) - SAY("attempting to reallocate frame " \ + SAM("attempting to reallocate frame " \ " buffers\n"); else { pbuf = (void *)__get_free_page(GFP_KERNEL); if ((void *)NULL == pbuf) { - SAY("ERROR: Could not allocate frame "\ + SAM("ERROR: Could not allocate frame "\ "buffer %i page %i\n", k, m); return -ENOMEM; } else @@ -3496,23 +3522,23 @@ case 0: { peasycap->frame_fill = 0; peasycap->frame_read = 0; - JOT(4, "allocation of frame buffers done: %i pages\n", k * \ + JOM(4, "allocation of frame buffers done: %i pages\n", k * \ m); /*---------------------------------------------------------------------------*/ - JOT(4, "allocating %i field buffers of size %li\n", \ + JOM(4, "allocating %i field buffers of size %li\n", \ FIELD_BUFFER_MANY, (long int)FIELD_BUFFER_SIZE); - JOT(4, ".... each scattered over %li pages\n", \ + JOM(4, ".... each scattered over %li pages\n", \ FIELD_BUFFER_SIZE/PAGE_SIZE); for (k = 0; k < FIELD_BUFFER_MANY; k++) { for (m = 0; m < FIELD_BUFFER_SIZE/PAGE_SIZE; m++) { if ((void *)NULL != peasycap->field_buffer[k][m].pgo) { - SAY("ERROR: attempting to reallocate " \ + SAM("ERROR: attempting to reallocate " \ "field buffers\n"); } else { pbuf = (void *) __get_free_page(GFP_KERNEL); if ((void *)NULL == pbuf) { - SAY("ERROR: Could not allocate field" \ + SAM("ERROR: Could not allocate field" \ " buffer %i page %i\n", k, m); return -ENOMEM; } @@ -3528,18 +3554,18 @@ case 0: { peasycap->field_fill = 0; peasycap->field_page = 0; peasycap->field_read = 0; - JOT(4, "allocation of field buffers done: %i pages\n", k * \ + JOM(4, "allocation of field buffers done: %i pages\n", k * \ m); /*---------------------------------------------------------------------------*/ - JOT(4, "allocating %i isoc video buffers of size %i\n", \ + JOM(4, "allocating %i isoc video buffers of size %i\n", \ VIDEO_ISOC_BUFFER_MANY, \ peasycap->video_isoc_buffer_size); - JOT(4, ".... each occupying contiguous memory pages\n"); + JOM(4, ".... each occupying contiguous memory pages\n"); for (k = 0; k < VIDEO_ISOC_BUFFER_MANY; k++) { pbuf = (void *)__get_free_pages(GFP_KERNEL, VIDEO_ISOC_ORDER); if (NULL == pbuf) { - SAY("ERROR: Could not allocate isoc video buffer " \ + SAM("ERROR: Could not allocate isoc video buffer " \ "%i\n", k); return -ENOMEM; } else @@ -3551,26 +3577,26 @@ case 0: { peasycap->video_isoc_buffer_size; peasycap->video_isoc_buffer[k].kount = k; } - JOT(4, "allocation of isoc video buffers done: %i pages\n", \ + JOM(4, "allocation of isoc video buffers done: %i pages\n", \ k * (0x01 << VIDEO_ISOC_ORDER)); /*---------------------------------------------------------------------------*/ /* * ALLOCATE AND INITIALIZE MULTIPLE struct urb ... */ /*---------------------------------------------------------------------------*/ - JOT(4, "allocating %i struct urb.\n", VIDEO_ISOC_BUFFER_MANY); - JOT(4, "using %i=peasycap->video_isoc_framesperdesc\n", \ + JOM(4, "allocating %i struct urb.\n", VIDEO_ISOC_BUFFER_MANY); + JOM(4, "using %i=peasycap->video_isoc_framesperdesc\n", \ peasycap->video_isoc_framesperdesc); - JOT(4, "using %i=peasycap->video_isoc_maxframesize\n", \ + JOM(4, "using %i=peasycap->video_isoc_maxframesize\n", \ peasycap->video_isoc_maxframesize); - JOT(4, "using %i=peasycap->video_isoc_buffer_sizen", \ + JOM(4, "using %i=peasycap->video_isoc_buffer_sizen", \ peasycap->video_isoc_buffer_size); for (k = 0; k < VIDEO_ISOC_BUFFER_MANY; k++) { purb = usb_alloc_urb(peasycap->video_isoc_framesperdesc, \ GFP_KERNEL); if (NULL == purb) { - SAY("ERROR: usb_alloc_urb returned NULL for buffer " \ + SAM("ERROR: usb_alloc_urb returned NULL for buffer " \ "%i\n", k); return -ENOMEM; } else @@ -3578,7 +3604,7 @@ case 0: { /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ pdata_urb = kzalloc(sizeof(struct data_urb), GFP_KERNEL); if (NULL == pdata_urb) { - SAY("ERROR: Could not allocate struct data_urb.\n"); + SAM("ERROR: Could not allocate struct data_urb.\n"); return -ENOMEM; } else peasycap->allocation_video_struct += \ @@ -3595,30 +3621,30 @@ case 0: { */ /*---------------------------------------------------------------------------*/ if (!k) { - JOT(4, "initializing video urbs thus:\n"); - JOT(4, " purb->interval = 1;\n"); - JOT(4, " purb->dev = peasycap->pusb_device;\n"); - JOT(4, " purb->pipe = usb_rcvisocpipe" \ + JOM(4, "initializing video urbs thus:\n"); + JOM(4, " purb->interval = 1;\n"); + JOM(4, " purb->dev = peasycap->pusb_device;\n"); + JOM(4, " purb->pipe = usb_rcvisocpipe" \ "(peasycap->pusb_device,%i);\n", \ peasycap->video_endpointnumber); - JOT(4, " purb->transfer_flags = URB_ISO_ASAP;\n"); - JOT(4, " purb->transfer_buffer = peasycap->" \ + JOM(4, " purb->transfer_flags = URB_ISO_ASAP;\n"); + JOM(4, " purb->transfer_buffer = peasycap->" \ "video_isoc_buffer[.].pgo;\n"); - JOT(4, " purb->transfer_buffer_length = %i;\n", \ + JOM(4, " purb->transfer_buffer_length = %i;\n", \ peasycap->video_isoc_buffer_size); - JOT(4, " purb->complete = easycap_complete;\n"); - JOT(4, " purb->context = peasycap;\n"); - JOT(4, " purb->start_frame = 0;\n"); - JOT(4, " purb->number_of_packets = %i;\n", \ + JOM(4, " purb->complete = easycap_complete;\n"); + JOM(4, " purb->context = peasycap;\n"); + JOM(4, " purb->start_frame = 0;\n"); + JOM(4, " purb->number_of_packets = %i;\n", \ peasycap->video_isoc_framesperdesc); - JOT(4, " for (j = 0; j < %i; j++)\n", \ + JOM(4, " for (j = 0; j < %i; j++)\n", \ peasycap->video_isoc_framesperdesc); - JOT(4, " {\n"); - JOT(4, " purb->iso_frame_desc[j].offset = j*%i;\n",\ + JOM(4, " {\n"); + JOM(4, " purb->iso_frame_desc[j].offset = j*%i;\n",\ peasycap->video_isoc_maxframesize); - JOT(4, " purb->iso_frame_desc[j].length = %i;\n", \ + JOM(4, " purb->iso_frame_desc[j].length = %i;\n", \ peasycap->video_isoc_maxframesize); - JOT(4, " }\n"); + JOM(4, " }\n"); } purb->interval = 1; @@ -3640,7 +3666,7 @@ case 0: { peasycap->video_isoc_maxframesize; } } - JOT(4, "allocation of %i struct urb done.\n", k); + JOM(4, "allocation of %i struct urb done.\n", k); /*--------------------------------------------------------------------------*/ /* * SAVE POINTER peasycap IN THIS INTERFACE. @@ -3657,48 +3683,55 @@ case 0: { err("Not able to get a minor for this device"); usb_set_intfdata(pusb_interface, NULL); return -ENODEV; - } else + } else { (peasycap->registered_video)++; - SAY("easycap attached to minor #%d\n", pusb_interface->minor); - break; -/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ -#else - pvideo_device = (struct video_device *)\ - kzalloc(sizeof(struct video_device), GFP_KERNEL); - if ((struct video_device *)NULL == pvideo_device) { - SAY("ERROR: Could not allocate structure video_device\n"); - return -ENOMEM; + SAM("easycap attached to minor #%d\n", pusb_interface->minor); + break; } - if (VIDEO_DEVICE_MANY <= video_device_many) { - SAY("ERROR: Too many /dev/videos\n"); - return -ENOMEM; +/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +#else +#if defined(EASYCAP_NEEDS_V4L2_DEVICE_H) + if (0 != (v4l2_device_register(&(pusb_interface->dev), \ + &(peasycap->v4l2_device)))) { + SAM("v4l2_device_register() failed\n"); + return -ENODEV; + } else { + JOM(4, "registered device instance: %s\n", \ + &(peasycap->v4l2_device.name[0])); } - pvideo_array[video_device_many] = pvideo_device; video_device_many++; +/*---------------------------------------------------------------------------*/ +/* + * THIS IS BELIEVED TO BE HARMLESS, BUT MAY WELL BE UNNECESSARY OR WRONG: +*/ +/*---------------------------------------------------------------------------*/ + peasycap->video_device.v4l2_dev = (struct v4l2_device *)NULL; +/*---------------------------------------------------------------------------*/ - strcpy(&pvideo_device->name[0], "easycapdc60"); +#endif /*EASYCAP_NEEDS_V4L2_DEVICE_H*/ + + strcpy(&peasycap->video_device.name[0], "easycapdc60"); #if defined(EASYCAP_NEEDS_V4L2_FOPS) - pvideo_device->fops = &v4l2_fops; + peasycap->video_device.fops = &v4l2_fops; #else - pvideo_device->fops = &easycap_fops; + peasycap->video_device.fops = &easycap_fops; #endif /*EASYCAP_NEEDS_V4L2_FOPS*/ - pvideo_device->minor = -1; - pvideo_device->release = (void *)(&videodev_release); + peasycap->video_device.minor = -1; + peasycap->video_device.release = (void *)(&videodev_release); - video_set_drvdata(pvideo_device, (void *)peasycap); + video_set_drvdata(&(peasycap->video_device), (void *)peasycap); - rc = video_register_device(pvideo_device, VFL_TYPE_GRABBER, -1); - if (0 != rc) { + if (0 != (video_register_device(&(peasycap->video_device), \ + VFL_TYPE_GRABBER, -1))) { err("Not able to register with videodev"); - videodev_release(pvideo_device); + videodev_release(&(peasycap->video_device)); return -ENODEV; } else { - peasycap->pvideo_device = pvideo_device; (peasycap->registered_video)++; - JOT(4, "registered with videodev: %i=minor\n", \ - pvideo_device->minor); + SAM("registered with videodev: %i=minor\n", \ + peasycap->video_device.minor); } -/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ #endif /*EASYCAP_IS_VIDEODEV_CLIENT*/ +/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ break; } /*--------------------------------------------------------------------------*/ @@ -3708,125 +3741,118 @@ case 0: { */ /*--------------------------------------------------------------------------*/ case 1: { + if (!peasycap) { + SAM("ERROR: peasycap is NULL\n"); + return -EFAULT; + } /*--------------------------------------------------------------------------*/ /* * SAVE POINTER peasycap IN INTERFACE 1 */ /*--------------------------------------------------------------------------*/ usb_set_intfdata(pusb_interface, peasycap); - JOT(4, "no initialization required for interface %i\n", \ + JOM(4, "no initialization required for interface %i\n", \ pusb_interface_descriptor->bInterfaceNumber); break; } /*--------------------------------------------------------------------------*/ case 2: { if (!peasycap) { - SAY("MISTAKE: peasycap is NULL\n"); + SAM("MISTAKE: peasycap is NULL\n"); return -EFAULT; } if (!isokalt) { - SAY("ERROR: no viable audio_altsetting_on\n"); + SAM("ERROR: no viable audio_altsetting_on\n"); return -ENOENT; } else { peasycap->audio_altsetting_on = okalt[isokalt - 1]; - JOT(4, "%i=audio_altsetting_on <====\n", \ + JOM(4, "%i=audio_altsetting_on <====\n", \ peasycap->audio_altsetting_on); } - if (!isokepn) { - SAY("ERROR: no viable audio_endpointnumber\n"); + + peasycap->audio_endpointnumber = okepn[isokalt - 1]; + JOM(4, "%i=audio_endpointnumber\n", peasycap->audio_endpointnumber); + + peasycap->audio_isoc_maxframesize = okmps[isokalt - 1]; + JOM(4, "%i=audio_isoc_maxframesize\n", \ + peasycap->audio_isoc_maxframesize); + if (0 >= peasycap->audio_isoc_maxframesize) { + SAM("ERROR: bad audio_isoc_maxframesize\n"); return -ENOENT; - } else { - peasycap->audio_endpointnumber = okepn[isokepn - 1]; - JOT(4, "%i=audio_endpointnumber\n", \ - peasycap->audio_endpointnumber); } - if (!isokmps) { - SAY("ERROR: no viable audio_maxpacketsize\n"); - return -ENOENT; + if (9 == peasycap->audio_isoc_maxframesize) { + peasycap->ilk |= 0x02; + SAM("hardware is FOUR-CVBS\n"); + peasycap->microphone = true; + peasycap->audio_pages_per_fragment = 4; + } else if (256 == peasycap->audio_isoc_maxframesize) { + peasycap->ilk &= ~0x02; + SAM("hardware is CVBS+S-VIDEO\n"); + peasycap->microphone = false; + peasycap->audio_pages_per_fragment = 4; } else { - peasycap->audio_isoc_maxframesize = okmps[isokmps - 1]; - JOT(4, "%i=audio_isoc_maxframesize\n", \ - peasycap->audio_isoc_maxframesize); - if (0 >= peasycap->audio_isoc_maxframesize) { - SAY("ERROR: bad audio_isoc_maxframesize\n"); - return -ENOENT; - } - if (9 == peasycap->audio_isoc_maxframesize) { - peasycap->ilk |= 0x02; - SAY("hardware is FOUR-CVBS\n"); - peasycap->microphone = true; - peasycap->audio_pages_per_fragment = 4; - } else if (256 == peasycap->audio_isoc_maxframesize) { - peasycap->ilk &= ~0x02; - SAY("hardware is CVBS+S-VIDEO\n"); - peasycap->microphone = false; - peasycap->audio_pages_per_fragment = 4; - } else { - SAY("hardware is unidentified:\n"); - SAY("%i=audio_isoc_maxframesize\n", \ + SAM("hardware is unidentified:\n"); + SAM("%i=audio_isoc_maxframesize\n", \ peasycap->audio_isoc_maxframesize); - return -ENOENT; - } + return -ENOENT; + } - peasycap->audio_bytes_per_fragment = \ + peasycap->audio_bytes_per_fragment = \ peasycap->audio_pages_per_fragment * \ PAGE_SIZE ; - peasycap->audio_buffer_page_many = (AUDIO_FRAGMENT_MANY * \ + peasycap->audio_buffer_page_many = (AUDIO_FRAGMENT_MANY * \ peasycap->audio_pages_per_fragment); - JOT(4, "%6i=AUDIO_FRAGMENT_MANY\n", AUDIO_FRAGMENT_MANY); - JOT(4, "%6i=audio_pages_per_fragment\n", \ + JOM(4, "%6i=AUDIO_FRAGMENT_MANY\n", AUDIO_FRAGMENT_MANY); + JOM(4, "%6i=audio_pages_per_fragment\n", \ peasycap->audio_pages_per_fragment); - JOT(4, "%6i=audio_bytes_per_fragment\n", \ + JOM(4, "%6i=audio_bytes_per_fragment\n", \ peasycap->audio_bytes_per_fragment); - JOT(4, "%6i=audio_buffer_page_many\n", \ + JOM(4, "%6i=audio_buffer_page_many\n", \ peasycap->audio_buffer_page_many); - peasycap->audio_isoc_framesperdesc = 128; + peasycap->audio_isoc_framesperdesc = 128; - JOT(4, "%i=audio_isoc_framesperdesc\n", \ + JOM(4, "%i=audio_isoc_framesperdesc\n", \ peasycap->audio_isoc_framesperdesc); - if (0 >= peasycap->audio_isoc_framesperdesc) { - SAY("ERROR: bad audio_isoc_framesperdesc\n"); - return -ENOENT; - } + if (0 >= peasycap->audio_isoc_framesperdesc) { + SAM("ERROR: bad audio_isoc_framesperdesc\n"); + return -ENOENT; + } - peasycap->audio_isoc_buffer_size = \ + peasycap->audio_isoc_buffer_size = \ peasycap->audio_isoc_maxframesize * \ peasycap->audio_isoc_framesperdesc; - JOT(4, "%i=audio_isoc_buffer_size\n", \ + JOM(4, "%i=audio_isoc_buffer_size\n", \ peasycap->audio_isoc_buffer_size); - if (AUDIO_ISOC_BUFFER_SIZE < \ - peasycap->audio_isoc_buffer_size) { - SAY("MISTAKE: audio_isoc_buffer_size bigger " + if (AUDIO_ISOC_BUFFER_SIZE < peasycap->audio_isoc_buffer_size) { + SAM("MISTAKE: audio_isoc_buffer_size bigger " "than %li=AUDIO_ISOC_BUFFER_SIZE\n", \ AUDIO_ISOC_BUFFER_SIZE); - return -EFAULT; - } + return -EFAULT; } - if (-1 == peasycap->audio_interface) { - SAY("MISTAKE: audio_interface is unset\n"); + SAM("MISTAKE: audio_interface is unset\n"); return -EFAULT; } if (-1 == peasycap->audio_altsetting_on) { - SAY("MISTAKE: audio_altsetting_on is unset\n"); + SAM("MISTAKE: audio_altsetting_on is unset\n"); return -EFAULT; } if (-1 == peasycap->audio_altsetting_off) { - SAY("MISTAKE: audio_interface_off is unset\n"); + SAM("MISTAKE: audio_interface_off is unset\n"); return -EFAULT; } if (-1 == peasycap->audio_endpointnumber) { - SAY("MISTAKE: audio_endpointnumber is unset\n"); + SAM("MISTAKE: audio_endpointnumber is unset\n"); return -EFAULT; } if (-1 == peasycap->audio_isoc_maxframesize) { - SAY("MISTAKE: audio_isoc_maxframesize is unset\n"); + SAM("MISTAKE: audio_isoc_maxframesize is unset\n"); return -EFAULT; } if (-1 == peasycap->audio_isoc_buffer_size) { - SAY("MISTAKE: audio_isoc_buffer_size is unset\n"); + SAM("MISTAKE: audio_isoc_buffer_size is unset\n"); return -EFAULT; } /*---------------------------------------------------------------------------*/ @@ -3837,17 +3863,17 @@ case 2: { INIT_LIST_HEAD(&(peasycap->urb_audio_head)); peasycap->purb_audio_head = &(peasycap->urb_audio_head); - JOT(4, "allocating an audio buffer\n"); - JOT(4, ".... scattered over %i pages\n", \ + JOM(4, "allocating an audio buffer\n"); + JOM(4, ".... scattered over %i pages\n", \ peasycap->audio_buffer_page_many); for (k = 0; k < peasycap->audio_buffer_page_many; k++) { if ((void *)NULL != peasycap->audio_buffer[k].pgo) { - SAY("ERROR: attempting to reallocate audio buffers\n"); + SAM("ERROR: attempting to reallocate audio buffers\n"); } else { pbuf = (void *) __get_free_page(GFP_KERNEL); if ((void *)NULL == pbuf) { - SAY("ERROR: Could not allocate audio " \ + SAM("ERROR: Could not allocate audio " \ "buffer page %i\n", k); return -ENOMEM; } else @@ -3860,16 +3886,16 @@ case 2: { peasycap->audio_fill = 0; peasycap->audio_read = 0; - JOT(4, "allocation of audio buffer done: %i pages\n", k); + JOM(4, "allocation of audio buffer done: %i pages\n", k); /*---------------------------------------------------------------------------*/ - JOT(4, "allocating %i isoc audio buffers of size %i\n", \ + JOM(4, "allocating %i isoc audio buffers of size %i\n", \ AUDIO_ISOC_BUFFER_MANY, peasycap->audio_isoc_buffer_size); - JOT(4, ".... each occupying contiguous memory pages\n"); + JOM(4, ".... each occupying contiguous memory pages\n"); for (k = 0; k < AUDIO_ISOC_BUFFER_MANY; k++) { pbuf = (void *)__get_free_pages(GFP_KERNEL, AUDIO_ISOC_ORDER); if (NULL == pbuf) { - SAY("ERROR: Could not allocate isoc audio buffer " \ + SAM("ERROR: Could not allocate isoc audio buffer " \ "%i\n", k); return -ENOMEM; } else @@ -3881,25 +3907,25 @@ case 2: { peasycap->audio_isoc_buffer_size; peasycap->audio_isoc_buffer[k].kount = k; } - JOT(4, "allocation of isoc audio buffers done.\n"); + JOM(4, "allocation of isoc audio buffers done.\n"); /*---------------------------------------------------------------------------*/ /* * ALLOCATE AND INITIALIZE MULTIPLE struct urb ... */ /*---------------------------------------------------------------------------*/ - JOT(4, "allocating %i struct urb.\n", AUDIO_ISOC_BUFFER_MANY); - JOT(4, "using %i=peasycap->audio_isoc_framesperdesc\n", \ + JOM(4, "allocating %i struct urb.\n", AUDIO_ISOC_BUFFER_MANY); + JOM(4, "using %i=peasycap->audio_isoc_framesperdesc\n", \ peasycap->audio_isoc_framesperdesc); - JOT(4, "using %i=peasycap->audio_isoc_maxframesize\n", \ + JOM(4, "using %i=peasycap->audio_isoc_maxframesize\n", \ peasycap->audio_isoc_maxframesize); - JOT(4, "using %i=peasycap->audio_isoc_buffer_size\n", \ + JOM(4, "using %i=peasycap->audio_isoc_buffer_size\n", \ peasycap->audio_isoc_buffer_size); for (k = 0; k < AUDIO_ISOC_BUFFER_MANY; k++) { purb = usb_alloc_urb(peasycap->audio_isoc_framesperdesc, \ GFP_KERNEL); if (NULL == purb) { - SAY("ERROR: usb_alloc_urb returned NULL for buffer " \ + SAM("ERROR: usb_alloc_urb returned NULL for buffer " \ "%i\n", k); return -ENOMEM; } else @@ -3907,7 +3933,7 @@ case 2: { /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ pdata_urb = kzalloc(sizeof(struct data_urb), GFP_KERNEL); if (NULL == pdata_urb) { - SAY("ERROR: Could not allocate struct data_urb.\n"); + SAM("ERROR: Could not allocate struct data_urb.\n"); return -ENOMEM; } else peasycap->allocation_audio_struct += \ @@ -3924,30 +3950,30 @@ case 2: { */ /*---------------------------------------------------------------------------*/ if (!k) { - JOT(4, "initializing audio urbs thus:\n"); - JOT(4, " purb->interval = 1;\n"); - JOT(4, " purb->dev = peasycap->pusb_device;\n"); - JOT(4, " purb->pipe = usb_rcvisocpipe(peasycap->" \ + JOM(4, "initializing audio urbs thus:\n"); + JOM(4, " purb->interval = 1;\n"); + JOM(4, " purb->dev = peasycap->pusb_device;\n"); + JOM(4, " purb->pipe = usb_rcvisocpipe(peasycap->" \ "pusb_device,%i);\n", \ peasycap->audio_endpointnumber); - JOT(4, " purb->transfer_flags = URB_ISO_ASAP;\n"); - JOT(4, " purb->transfer_buffer = " \ + JOM(4, " purb->transfer_flags = URB_ISO_ASAP;\n"); + JOM(4, " purb->transfer_buffer = " \ "peasycap->audio_isoc_buffer[.].pgo;\n"); - JOT(4, " purb->transfer_buffer_length = %i;\n", \ + JOM(4, " purb->transfer_buffer_length = %i;\n", \ peasycap->audio_isoc_buffer_size); - JOT(4, " purb->complete = easysnd_complete;\n"); - JOT(4, " purb->context = peasycap;\n"); - JOT(4, " purb->start_frame = 0;\n"); - JOT(4, " purb->number_of_packets = %i;\n", \ + JOM(4, " purb->complete = easysnd_complete;\n"); + JOM(4, " purb->context = peasycap;\n"); + JOM(4, " purb->start_frame = 0;\n"); + JOM(4, " purb->number_of_packets = %i;\n", \ peasycap->audio_isoc_framesperdesc); - JOT(4, " for (j = 0; j < %i; j++)\n", \ + JOM(4, " for (j = 0; j < %i; j++)\n", \ peasycap->audio_isoc_framesperdesc); - JOT(4, " {\n"); - JOT(4, " purb->iso_frame_desc[j].offset = j*%i;\n",\ + JOM(4, " {\n"); + JOM(4, " purb->iso_frame_desc[j].offset = j*%i;\n",\ peasycap->audio_isoc_maxframesize); - JOT(4, " purb->iso_frame_desc[j].length = %i;\n", \ + JOM(4, " purb->iso_frame_desc[j].length = %i;\n", \ peasycap->audio_isoc_maxframesize); - JOT(4, " }\n"); + JOM(4, " }\n"); } purb->interval = 1; @@ -3969,7 +3995,7 @@ case 2: { peasycap->audio_isoc_maxframesize; } } - JOT(4, "allocation of %i struct urb done.\n", k); + JOM(4, "allocation of %i struct urb done.\n", k); /*---------------------------------------------------------------------------*/ /* * SAVE POINTER peasycap IN THIS INTERFACE. @@ -3986,14 +4012,18 @@ case 2: { err("Not able to get a minor for this device."); usb_set_intfdata(pusb_interface, NULL); return -ENODEV; - } else + } else { + JOM(8, "kref_get() with %i=peasycap->kref.refcount.counter\n",\ + (int)peasycap->kref.refcount.counter); + kref_get(&peasycap->kref); (peasycap->registered_audio)++; + } /*---------------------------------------------------------------------------*/ /* * LET THE USER KNOW WHAT NODE THE AUDIO DEVICE IS ATTACHED TO. */ /*---------------------------------------------------------------------------*/ - SAY("easysnd attached to minor #%d\n", pusb_interface->minor); + SAM("easysnd attached to minor #%d\n", pusb_interface->minor); break; } /*---------------------------------------------------------------------------*/ @@ -4002,11 +4032,11 @@ case 2: { */ /*---------------------------------------------------------------------------*/ default: { - JOT(4, "ERROR: unexpected interface %i\n", bInterfaceNumber); + JOM(4, "ERROR: unexpected interface %i\n", bInterfaceNumber); return -EINVAL; } } -JOT(4, "ends successfully for interface %i\n", \ +JOM(4, "ends successfully for interface %i\n", \ pusb_interface_descriptor->bInterfaceNumber); return 0; } @@ -4050,60 +4080,67 @@ bInterfaceNumber = pusb_interface_descriptor->bInterfaceNumber; minor = pusb_interface->minor; JOT(4, "intf[%i]: minor=%i\n", bInterfaceNumber, minor); +if (1 == bInterfaceNumber) + return; + peasycap = usb_get_intfdata(pusb_interface); -if ((struct easycap *)NULL == peasycap) +if (NULL == peasycap) { SAY("ERROR: peasycap is NULL\n"); -else { - peasycap->pusb_device = (struct usb_device *)NULL; - switch (bInterfaceNumber) { -/*---------------------------------------------------------------------------*/ - case 0: { - if ((struct list_head *)NULL != peasycap->purb_video_head) { - JOT(4, "killing video urbs\n"); - m = 0; - list_for_each(plist_head, (peasycap->purb_video_head)) - { - pdata_urb = list_entry(plist_head, \ - struct data_urb, list_head); - if ((struct data_urb *)NULL != pdata_urb) { - if ((struct urb *)NULL != \ - pdata_urb->purb) { - usb_kill_urb(pdata_urb->purb); - m++; - } + return; +} +/*---------------------------------------------------------------------------*/ +/* + * IF THE WAIT QUEUES ARE NOT CLEARED A DEADLOCK IS POSSIBLE. BEWARE. +*/ +/*---------------------------------------------------------------------------*/ +peasycap->video_eof = 1; +peasycap->audio_eof = 1; +wake_up_interruptible(&peasycap->wq_video); +wake_up_interruptible(&peasycap->wq_audio); +/*---------------------------------------------------------------------------*/ +switch (bInterfaceNumber) { +case 0: { + if ((struct list_head *)NULL != peasycap->purb_video_head) { + JOM(4, "killing video urbs\n"); + m = 0; + list_for_each(plist_head, (peasycap->purb_video_head)) { + pdata_urb = list_entry(plist_head, \ + struct data_urb, list_head); + if ((struct data_urb *)NULL != pdata_urb) { + if ((struct urb *)NULL != \ + pdata_urb->purb) { + usb_kill_urb(pdata_urb->purb); + m++; } } - JOT(4, "%i video urbs killed\n", m); - } else - SAY("ERROR: peasycap->purb_video_head is NULL\n"); - break; + } + JOM(4, "%i video urbs killed\n", m); } + break; +} /*---------------------------------------------------------------------------*/ - case 2: { - if ((struct list_head *)NULL != peasycap->purb_audio_head) { - JOT(4, "killing audio urbs\n"); - m = 0; - list_for_each(plist_head, \ - (peasycap->purb_audio_head)) { - pdata_urb = list_entry(plist_head, \ - struct data_urb, list_head); - if ((struct data_urb *)NULL != pdata_urb) { - if ((struct urb *)NULL != \ - pdata_urb->purb) { - usb_kill_urb(pdata_urb->purb); - m++; - } +case 2: { + if ((struct list_head *)NULL != peasycap->purb_audio_head) { + JOM(4, "killing audio urbs\n"); + m = 0; + list_for_each(plist_head, (peasycap->purb_audio_head)) { + pdata_urb = list_entry(plist_head, \ + struct data_urb, list_head); + if ((struct data_urb *)NULL != pdata_urb) { + if ((struct urb *)NULL != \ + pdata_urb->purb) { + usb_kill_urb(pdata_urb->purb); + m++; } } - JOT(4, "%i audio urbs killed\n", m); - } else - SAY("ERROR: peasycap->purb_audio_head is NULL\n"); - break; + } + JOM(4, "%i audio urbs killed\n", m); } + break; +} /*---------------------------------------------------------------------------*/ - default: - break; - } +default: + break; } /*--------------------------------------------------------------------------*/ /* @@ -4112,29 +4149,30 @@ else { /*--------------------------------------------------------------------------*/ switch (bInterfaceNumber) { case 0: { + #if (!defined(EASYCAP_IS_VIDEODEV_CLIENT)) if ((struct easycap *)NULL == peasycap) { - SAY("ERROR: peasycap has become NULL\n"); + SAM("ERROR: peasycap has become NULL\n"); } else { lock_kernel(); usb_deregister_dev(pusb_interface, &easycap_class); (peasycap->registered_video)--; - JOT(4, "intf[%i]: usb_deregister_dev()\n", bInterfaceNumber); + JOM(4, "intf[%i]: usb_deregister_dev()\n", bInterfaceNumber); unlock_kernel(); - SAY("easycap detached from minor #%d\n", minor); + SAM("easycap detached from minor #%d\n", minor); } /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ #else if ((struct easycap *)NULL == peasycap) - SAY("ERROR: peasycap has become NULL\n"); + SAM("ERROR: peasycap has become NULL\n"); else { lock_kernel(); - video_unregister_device(peasycap->pvideo_device); + video_unregister_device(&peasycap->video_device); (peasycap->registered_video)--; unlock_kernel(); - JOT(4, "unregistered with videodev: %i=minor\n", \ - pvideo_device->minor); + JOM(4, "unregistered with videodev: %i=minor\n", \ + peasycap->video_device.minor); } /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ #endif /*EASYCAP_IS_VIDEODEV_CLIENT*/ @@ -4147,10 +4185,10 @@ case 2: { if ((struct easycap *)NULL != peasycap) (peasycap->registered_audio)--; - JOT(4, "intf[%i]: usb_deregister_dev()\n", bInterfaceNumber); + JOM(4, "intf[%i]: usb_deregister_dev()\n", bInterfaceNumber); unlock_kernel(); - SAY("easysnd detached from minor #%d\n", minor); + SAM("easysnd detached from minor #%d\n", minor); break; } default: @@ -4162,24 +4200,24 @@ default: */ /*---------------------------------------------------------------------------*/ if ((struct easycap *)NULL == peasycap) { - SAY("ERROR: peasycap has become NULL\n"); - SAY("cannot call kref_put()\n"); - SAY("ending unsuccessfully: may cause memory leak\n"); + SAM("ERROR: peasycap has become NULL\n"); + SAM("cannot call kref_put()\n"); + SAM("ending unsuccessfully: may cause memory leak\n"); return; } if (!peasycap->kref.refcount.counter) { - SAY("ERROR: peasycap->kref.refcount.counter is zero " \ + SAM("ERROR: peasycap->kref.refcount.counter is zero " \ "so cannot call kref_put()\n"); - SAY("ending unsuccessfully: may cause memory leak\n"); + SAM("ending unsuccessfully: may cause memory leak\n"); return; } -JOT(4, "intf[%i]: kref_put() with %i=peasycap->kref.refcount.counter\n", \ +JOM(4, "intf[%i]: kref_put() with %i=peasycap->kref.refcount.counter\n", \ bInterfaceNumber, (int)peasycap->kref.refcount.counter); kref_put(&peasycap->kref, easycap_delete); -JOT(4, "intf[%i]: kref_put() done.\n", bInterfaceNumber); +JOM(4, "intf[%i]: kref_put() done.\n", bInterfaceNumber); /*---------------------------------------------------------------------------*/ -JOT(4, "ends\n"); +JOM(4, "ends\n"); return; } /*****************************************************************************/ diff --git a/drivers/staging/easycap/easycap_sound.c b/drivers/staging/easycap/easycap_sound.c index 7be5bcf7136f..21275973faf3 100644 --- a/drivers/staging/easycap/easycap_sound.c +++ b/drivers/staging/easycap/easycap_sound.c @@ -43,10 +43,8 @@ void easysnd_complete(struct urb *purb) { -static int mt; struct easycap *peasycap; struct data_buffer *paudio_buffer; -char errbuf[16]; __u8 *p1, *p2; __s16 s16; int i, j, more, much, leap, rc; @@ -68,46 +66,55 @@ if (NULL == peasycap) { } much = 0; - if (peasycap->audio_idle) { - JOT(16, "%i=audio_idle %i=audio_isoc_streaming\n", \ + JOM(16, "%i=audio_idle %i=audio_isoc_streaming\n", \ peasycap->audio_idle, peasycap->audio_isoc_streaming); if (peasycap->audio_isoc_streaming) { rc = usb_submit_urb(purb, GFP_ATOMIC); if (0 != rc) { - SAY("ERROR: while %i=audio_idle, " \ + if (-ENODEV != rc) + SAM("ERROR: while %i=audio_idle, " \ "usb_submit_urb() failed with rc:\n", \ peasycap->audio_idle); switch (rc) { case -ENOMEM: { - SAY("ENOMEM\n"); break; + SAM("-ENOMEM\n"); + break; } case -ENODEV: { - SAY("ENODEV\n"); break; + break; } case -ENXIO: { - SAY("ENXIO\n"); break; + SAM("-ENXIO\n"); + break; } case -EINVAL: { - SAY("EINVAL\n"); break; + SAM("-EINVAL\n"); + break; } case -EAGAIN: { - SAY("EAGAIN\n"); break; + SAM("-EAGAIN\n"); + break; } case -EFBIG: { - SAY("EFBIG\n"); break; + SAM("-EFBIG\n"); + break; } case -EPIPE: { - SAY("EPIPE\n"); break; + SAM("-EPIPE\n"); + break; } case -EMSGSIZE: { - SAY("EMSGSIZE\n"); break; + SAM("-EMSGSIZE\n"); + break; } case -ENOSPC: { - SAY("ENOSPC\n"); break; + SAM("-ENOSPC\n"); + break; } default: { - SAY("0x%08X\n", rc); break; + SAM("unknown error: 0x%08X\n", rc); + break; } } } @@ -116,74 +123,95 @@ return; } /*---------------------------------------------------------------------------*/ if (purb->status) { - if (-ESHUTDOWN == purb->status) { - JOT(16, "immediate return because -ESHUTDOWN=purb->status\n"); + if ((-ESHUTDOWN == purb->status) || (-ENOENT == purb->status)) { + JOM(16, "urb status -ESHUTDOWN or -ENOENT\n"); return; } - SAY("ERROR: non-zero urb status:\n"); + SAM("ERROR: non-zero urb status:\n"); switch (purb->status) { case -EINPROGRESS: { - SAY("-EINPROGRESS\n"); break; + SAM("-EINPROGRESS\n"); + break; } case -ENOSR: { - SAY("-ENOSR\n"); break; + SAM("-ENOSR\n"); + break; } case -EPIPE: { - SAY("-EPIPE\n"); break; + SAM("-EPIPE\n"); + break; } case -EOVERFLOW: { - SAY("-EOVERFLOW\n"); break; + SAM("-EOVERFLOW\n"); + break; } case -EPROTO: { - SAY("-EPROTO\n"); break; + SAM("-EPROTO\n"); + break; } case -EILSEQ: { - SAY("-EILSEQ\n"); break; + SAM("-EILSEQ\n"); + break; } case -ETIMEDOUT: { - SAY("-ETIMEDOUT\n"); break; + SAM("-ETIMEDOUT\n"); + break; } case -EMSGSIZE: { - SAY("-EMSGSIZE\n"); break; + SAM("-EMSGSIZE\n"); + break; } case -EOPNOTSUPP: { - SAY("-EOPNOTSUPP\n"); break; + SAM("-EOPNOTSUPP\n"); + break; } case -EPFNOSUPPORT: { - SAY("-EPFNOSUPPORT\n"); break; + SAM("-EPFNOSUPPORT\n"); + break; } case -EAFNOSUPPORT: { - SAY("-EAFNOSUPPORT\n"); break; + SAM("-EAFNOSUPPORT\n"); + break; } case -EADDRINUSE: { - SAY("-EADDRINUSE\n"); break; + SAM("-EADDRINUSE\n"); + break; } case -EADDRNOTAVAIL: { - SAY("-EADDRNOTAVAIL\n"); break; + SAM("-EADDRNOTAVAIL\n"); + break; } case -ENOBUFS: { - SAY("-ENOBUFS\n"); break; + SAM("-ENOBUFS\n"); + break; } case -EISCONN: { - SAY("-EISCONN\n"); break; + SAM("-EISCONN\n"); + break; } case -ENOTCONN: { - SAY("-ENOTCONN\n"); break; + SAM("-ENOTCONN\n"); + break; } case -ESHUTDOWN: { - SAY("-ESHUTDOWN\n"); break; + SAM("-ESHUTDOWN\n"); + break; } case -ENOENT: { - SAY("-ENOENT\n"); break; + SAM("-ENOENT\n"); + break; } case -ECONNRESET: { - SAY("-ECONNRESET\n"); break; + SAM("-ECONNRESET\n"); + break; } case -ENOSPC: { - SAY("ENOSPC\n"); break; + SAM("ENOSPC\n"); + break; } default: { - SAY("unknown error code 0x%08X\n", purb->status); break; + SAM("unknown error code 0x%08X\n", purb->status); + break; } } /*---------------------------------------------------------------------------*/ @@ -196,35 +224,43 @@ if (purb->status) { if (peasycap->audio_isoc_streaming) { rc = usb_submit_urb(purb, GFP_ATOMIC); if (0 != rc) { - SAY("ERROR: while %i=audio_idle, usb_submit_urb() " + SAM("ERROR: while %i=audio_idle, usb_submit_urb() " "failed with rc:\n", peasycap->audio_idle); switch (rc) { case -ENOMEM: { - SAY("ENOMEM\n"); break; + SAM("-ENOMEM\n"); + break; } case -ENODEV: { - SAY("ENODEV\n"); break; + SAM("-ENODEV\n"); + break; } case -ENXIO: { - SAY("ENXIO\n"); break; + SAM("-ENXIO\n"); + break; } case -EINVAL: { - SAY("EINVAL\n"); break; + SAM("-EINVAL\n"); + break; } case -EAGAIN: { - SAY("EAGAIN\n"); break; + SAM("-EAGAIN\n"); + break; } case -EFBIG: { - SAY("EFBIG\n"); break; + SAM("-EFBIG\n"); + break; } case -EPIPE: { - SAY("EPIPE\n"); break; + SAM("-EPIPE\n"); + break; } case -EMSGSIZE: { - SAY("EMSGSIZE\n"); break; + SAM("-EMSGSIZE\n"); + break; } default: { - SAY("0x%08X\n", rc); break; + SAM("0x%08X\n", rc); break; } } } @@ -243,72 +279,80 @@ oldaudio = peasycap->oldaudio; for (i = 0; i < purb->number_of_packets; i++) { switch (purb->iso_frame_desc[i].status) { case 0: { - strcpy(&errbuf[0], "OK"); break; + break; } case -ENOENT: { - strcpy(&errbuf[0], "-ENOENT"); break; + SAM("-ENOENT\n"); + break; } case -EINPROGRESS: { - strcpy(&errbuf[0], "-EINPROGRESS"); break; + SAM("-EINPROGRESS\n"); + break; } case -EPROTO: { - strcpy(&errbuf[0], "-EPROTO"); break; + SAM("-EPROTO\n"); + break; } case -EILSEQ: { - strcpy(&errbuf[0], "-EILSEQ"); break; + SAM("-EILSEQ\n"); + break; } case -ETIME: { - strcpy(&errbuf[0], "-ETIME"); break; + SAM("-ETIME\n"); + break; } case -ETIMEDOUT: { - strcpy(&errbuf[0], "-ETIMEDOUT"); break; + SAM("-ETIMEDOUT\n"); + break; } case -EPIPE: { - strcpy(&errbuf[0], "-EPIPE"); break; + SAM("-EPIPE\n"); + break; } case -ECOMM: { - strcpy(&errbuf[0], "-ECOMM"); break; + SAM("-ECOMM\n"); + break; } case -ENOSR: { - strcpy(&errbuf[0], "-ENOSR"); break; + SAM("-ENOSR\n"); + break; } case -EOVERFLOW: { - strcpy(&errbuf[0], "-EOVERFLOW"); break; + SAM("-EOVERFLOW\n"); + break; } case -EREMOTEIO: { - strcpy(&errbuf[0], "-EREMOTEIO"); break; + SAM("-EREMOTEIO\n"); + break; } case -ENODEV: { - strcpy(&errbuf[0], "-ENODEV"); break; + SAM("-ENODEV\n"); + break; } case -EXDEV: { - strcpy(&errbuf[0], "-EXDEV"); break; + SAM("-EXDEV\n"); + break; } case -EINVAL: { - strcpy(&errbuf[0], "-EINVAL"); break; + SAM("-EINVAL\n"); + break; } case -ECONNRESET: { - strcpy(&errbuf[0], "-ECONNRESET"); break; + SAM("-ECONNRESET\n"); + break; } case -ENOSPC: { - strcpy(&errbuf[0], "-ENOSPC"); break; + SAM("-ENOSPC\n"); + break; } case -ESHUTDOWN: { - strcpy(&errbuf[0], "-ESHUTDOWN"); break; + SAM("-ESHUTDOWN\n"); + break; } default: { - strcpy(&errbuf[0], "UNKNOWN"); break; - } + SAM("unknown error:0x%08X\n", purb->iso_frame_desc[i].status); + break; } - if ((!purb->iso_frame_desc[i].status) && 0) { - JOT(16, "frame[%2i]: %i=status{=%16s} " \ - "%5i=actual " \ - "%5i=length " \ - "%3i=offset\n", \ - i, purb->iso_frame_desc[i].status, &errbuf[0], - purb->iso_frame_desc[i].actual_length, - purb->iso_frame_desc[i].length, - purb->iso_frame_desc[i].offset); } if (!purb->iso_frame_desc[i].status) { more = purb->iso_frame_desc[i].actual_length; @@ -319,11 +363,12 @@ for (i = 0; i < purb->number_of_packets; i++) { #endif if (!more) - mt++; + peasycap->audio_mt++; else { - if (mt) { - JOT(16, "%4i empty audio urb frames\n", mt); - mt = 0; + if (peasycap->audio_mt) { + JOM(16, "%4i empty audio urb frames\n", \ + peasycap->audio_mt); + peasycap->audio_mt = 0; } p1 = (__u8 *)(purb->transfer_buffer + \ @@ -340,13 +385,13 @@ for (i = 0; i < purb->number_of_packets; i++) { /*---------------------------------------------------------------------------*/ while (more) { if (0 > more) { - SAY("easysnd_complete: MISTAKE: " \ + SAM("easysnd_complete: MISTAKE: " \ "more is negative\n"); return; } if (peasycap->audio_buffer_page_many <= \ peasycap->audio_fill) { - SAY("ERROR: bad " \ + SAM("ERROR: bad " \ "peasycap->audio_fill\n"); return; } @@ -355,7 +400,7 @@ for (i = 0; i < purb->number_of_packets; i++) { [peasycap->audio_fill]; if (PAGE_SIZE < (paudio_buffer->pto - \ paudio_buffer->pgo)) { - SAY("ERROR: bad paudio_buffer->pto\n"); + SAM("ERROR: bad paudio_buffer->pto\n"); return; } if (PAGE_SIZE == (paudio_buffer->pto - \ @@ -374,7 +419,7 @@ for (i = 0; i < purb->number_of_packets; i++) { peasycap->audio_fill) peasycap->audio_fill = 0; - JOT(12, "bumped peasycap->" \ + JOM(12, "bumped peasycap->" \ "audio_fill to %i\n", \ peasycap->audio_fill); @@ -387,7 +432,7 @@ for (i = 0; i < purb->number_of_packets; i++) { if (!(peasycap->audio_fill % \ peasycap->\ audio_pages_per_fragment)) { - JOT(12, "wakeup call on wq_" \ + JOM(12, "wakeup call on wq_" \ "audio, %i=frag reading %i" \ "=fragment fill\n", \ (peasycap->audio_read / \ @@ -414,7 +459,7 @@ for (i = 0; i < purb->number_of_packets; i++) { } else { #if defined(UPSAMPLE) if (much % 16) - JOT(8, "MISTAKE? much" \ + JOM(8, "MISTAKE? much" \ " is not divisible by 16\n"); if (much > (16 * \ more)) @@ -468,7 +513,7 @@ for (i = 0; i < purb->number_of_packets; i++) { } } } else { - JOT(12, "discarding audio samples because " \ + JOM(12, "discarding audio samples because " \ "%i=purb->iso_frame_desc[i].status\n", \ purb->iso_frame_desc[i].status); } @@ -486,38 +531,50 @@ peasycap->oldaudio = oldaudio; if (peasycap->audio_isoc_streaming) { rc = usb_submit_urb(purb, GFP_ATOMIC); if (0 != rc) { - SAY("ERROR: while %i=audio_idle, usb_submit_urb() failed " \ + if (-ENODEV != rc) { + SAM("ERROR: while %i=audio_idle, " \ + "usb_submit_urb() failed " \ "with rc:\n", peasycap->audio_idle); + } switch (rc) { case -ENOMEM: { - SAY("ENOMEM\n"); break; + SAM("-ENOMEM\n"); + break; } case -ENODEV: { - SAY("ENODEV\n"); break; + break; } case -ENXIO: { - SAY("ENXIO\n"); break; + SAM("-ENXIO\n"); + break; } case -EINVAL: { - SAY("EINVAL\n"); break; + SAM("-EINVAL\n"); + break; } case -EAGAIN: { - SAY("EAGAIN\n"); break; + SAM("-EAGAIN\n"); + break; } case -EFBIG: { - SAY("EFBIG\n"); break; + SAM("-EFBIG\n"); + break; } case -EPIPE: { - SAY("EPIPE\n"); break; + SAM("-EPIPE\n"); + break; } case -EMSGSIZE: { - SAY("EMSGSIZE\n"); break; + SAM("-EMSGSIZE\n"); + break; } case -ENOSPC: { - SAY("ENOSPC\n"); break; + SAM("-ENOSPC\n"); + break; } default: { - SAY("0x%08X\n", rc); break; + SAM("unknown error: 0x%08X\n", rc); + break; } } } @@ -529,8 +586,7 @@ return; /* * THE AUDIO URBS ARE SUBMITTED AT THIS EARLY STAGE SO THAT IT IS POSSIBLE TO * STREAM FROM /dev/easysnd1 WITH SIMPLE PROGRAMS SUCH AS cat WHICH DO NOT - * HAVE AN IOCTL INTERFACE. THE VIDEO URBS, BY CONTRAST, MUST BE SUBMITTED - * MUCH LATER: SEE COMMENTS IN FILE easycap_main.c. + * HAVE AN IOCTL INTERFACE. */ /*---------------------------------------------------------------------------*/ int @@ -540,7 +596,7 @@ struct usb_interface *pusb_interface; struct easycap *peasycap; int subminor, rc; -JOT(4, "begins.\n"); +JOT(4, "begins\n"); subminor = iminor(inode); @@ -561,56 +617,54 @@ file->private_data = peasycap; /*---------------------------------------------------------------------------*/ /* - * INITIALIZATION. + * INITIALIZATION */ /*---------------------------------------------------------------------------*/ -JOT(4, "starting initialization\n"); +JOM(4, "starting initialization\n"); if ((struct usb_device *)NULL == peasycap->pusb_device) { - SAY("ERROR: peasycap->pusb_device is NULL\n"); + SAM("ERROR: peasycap->pusb_device is NULL\n"); return -EFAULT; -} else { - JOT(16, "0x%08lX=peasycap->pusb_device\n", \ - (long int)peasycap->pusb_device); } +JOM(16, "0x%08lX=peasycap->pusb_device\n", (long int)peasycap->pusb_device); rc = audio_setup(peasycap); if (0 <= rc) - JOT(8, "audio_setup() returned %i\n", rc); + JOM(8, "audio_setup() returned %i\n", rc); else - JOT(8, "easysnd open(): ERROR: audio_setup() returned %i\n", rc); + JOM(8, "easysnd open(): ERROR: audio_setup() returned %i\n", rc); if ((struct usb_device *)NULL == peasycap->pusb_device) { - SAY("ERROR: peasycap->pusb_device has become NULL\n"); + SAM("ERROR: peasycap->pusb_device has become NULL\n"); return -EFAULT; } rc = adjust_volume(peasycap, -8192); if (0 != rc) { - SAY("ERROR: adjust_volume(default) returned %i\n", rc); + SAM("ERROR: adjust_volume(default) returned %i\n", rc); return -EFAULT; } /*---------------------------------------------------------------------------*/ if ((struct usb_device *)NULL == peasycap->pusb_device) { - SAY("ERROR: peasycap->pusb_device has become NULL\n"); + SAM("ERROR: peasycap->pusb_device has become NULL\n"); return -EFAULT; } rc = usb_set_interface(peasycap->pusb_device, peasycap->audio_interface, \ peasycap->audio_altsetting_on); -JOT(8, "usb_set_interface(.,%i,%i) returned %i\n", peasycap->audio_interface, \ +JOM(8, "usb_set_interface(.,%i,%i) returned %i\n", peasycap->audio_interface, \ peasycap->audio_altsetting_on, rc); if ((struct usb_device *)NULL == peasycap->pusb_device) { - SAY("ERROR: peasycap->pusb_device has become NULL\n"); + SAM("ERROR: peasycap->pusb_device has become NULL\n"); return -EFAULT; } rc = wakeup_device(peasycap->pusb_device); if (0 == rc) - JOT(8, "wakeup_device() returned %i\n", rc); + JOM(8, "wakeup_device() returned %i\n", rc); else - JOT(8, "easysnd open(): ERROR: wakeup_device() returned %i\n", rc); + JOM(8, "easysnd open(): ERROR: wakeup_device() returned %i\n", rc); if ((struct usb_device *)NULL == peasycap->pusb_device) { - SAY("ERROR: peasycap->pusb_device has become NULL\n"); + SAM("ERROR: peasycap->pusb_device has become NULL\n"); return -EFAULT; } submit_audio_urbs(peasycap); @@ -619,7 +673,7 @@ peasycap->audio_idle = 0; peasycap->timeval1.tv_sec = 0; peasycap->timeval1.tv_usec = 0; -JOT(4, "finished initialization\n"); +JOM(4, "finished initialization\n"); return 0; } /*****************************************************************************/ @@ -636,10 +690,10 @@ if (NULL == peasycap) { return -EFAULT; } if (0 != kill_audio_urbs(peasycap)) { - SAY("ERROR: kill_audio_urbs() failed\n"); + SAM("ERROR: kill_audio_urbs() failed\n"); return -EFAULT; } -JOT(4, "ending successfully\n"); +JOM(4, "ending successfully\n"); return 0; } /*****************************************************************************/ @@ -648,8 +702,7 @@ easysnd_read(struct file *file, char __user *puserspacebuffer, \ size_t kount, loff_t *poff) { struct timeval timeval; -static struct timeval timeval1; -static long long int audio_bytes, above, below, mean; +long long int above, below, mean; struct signed_div_result sdr; unsigned char *p0; long int kount1, more, rc, l0, lm; @@ -679,15 +732,15 @@ if (NULL == peasycap) { /*---------------------------------------------------------------------------*/ if ((0 > peasycap->audio_read) || \ (peasycap->audio_buffer_page_many <= peasycap->audio_read)) { - SAY("ERROR: peasycap->audio_read out of range\n"); + SAM("ERROR: peasycap->audio_read out of range\n"); return -EFAULT; } pdata_buffer = &peasycap->audio_buffer[peasycap->audio_read]; if ((struct data_buffer *)NULL == pdata_buffer) { - SAY("ERROR: pdata_buffer is NULL\n"); + SAM("ERROR: pdata_buffer is NULL\n"); return -EFAULT; } -JOT(12, "before wait, %i=frag read %i=frag fill\n", \ +JOM(12, "before wait, %i=frag read %i=frag fill\n", \ (peasycap->audio_read / peasycap->audio_pages_per_fragment), \ (peasycap->audio_fill / peasycap->audio_pages_per_fragment)); fragment = (peasycap->audio_read / peasycap->audio_pages_per_fragment); @@ -695,7 +748,7 @@ while ((fragment == (peasycap->audio_fill / \ peasycap->audio_pages_per_fragment)) || \ (0 == (PAGE_SIZE - (pdata_buffer->pto - pdata_buffer->pgo)))) { if (file->f_flags & O_NONBLOCK) { - JOT(16, "returning -EAGAIN as instructed\n"); + JOM(16, "returning -EAGAIN as instructed\n"); return -EAGAIN; } rc = wait_event_interruptible(peasycap->wq_audio, \ @@ -704,50 +757,50 @@ while ((fragment == (peasycap->audio_fill / \ peasycap->audio_pages_per_fragment)) && \ (0 < (PAGE_SIZE - (pdata_buffer->pto - pdata_buffer->pgo)))))); if (0 != rc) { - SAY("aborted by signal\n"); + SAM("aborted by signal\n"); return -ERESTARTSYS; } if (peasycap->audio_eof) { - JOT(8, "returning 0 because %i=audio_eof\n", \ + JOM(8, "returning 0 because %i=audio_eof\n", \ peasycap->audio_eof); kill_audio_urbs(peasycap); msleep(500); return 0; } if (peasycap->audio_idle) { - JOT(16, "returning 0 because %i=audio_idle\n", \ + JOM(16, "returning 0 because %i=audio_idle\n", \ peasycap->audio_idle); return 0; } if (!peasycap->audio_isoc_streaming) { - JOT(16, "returning 0 because audio urbs not streaming\n"); + JOM(16, "returning 0 because audio urbs not streaming\n"); return 0; } } -JOT(12, "after wait, %i=frag read %i=frag fill\n", \ +JOM(12, "after wait, %i=frag read %i=frag fill\n", \ (peasycap->audio_read / peasycap->audio_pages_per_fragment), \ (peasycap->audio_fill / peasycap->audio_pages_per_fragment)); szret = (size_t)0; while (fragment == (peasycap->audio_read / \ peasycap->audio_pages_per_fragment)) { if (NULL == pdata_buffer->pgo) { - SAY("ERROR: pdata_buffer->pgo is NULL\n"); + SAM("ERROR: pdata_buffer->pgo is NULL\n"); return -EFAULT; } if (NULL == pdata_buffer->pto) { - SAY("ERROR: pdata_buffer->pto is NULL\n"); + SAM("ERROR: pdata_buffer->pto is NULL\n"); return -EFAULT; } kount1 = PAGE_SIZE - (pdata_buffer->pto - pdata_buffer->pgo); if (0 > kount1) { - SAY("easysnd_read: MISTAKE: kount1 is negative\n"); + SAM("easysnd_read: MISTAKE: kount1 is negative\n"); return -ERESTARTSYS; } if (!kount1) { (peasycap->audio_read)++; if (peasycap->audio_buffer_page_many <= peasycap->audio_read) peasycap->audio_read = 0; - JOT(12, "bumped peasycap->audio_read to %i\n", \ + JOM(12, "bumped peasycap->audio_read to %i\n", \ peasycap->audio_read); if (fragment != (peasycap->audio_read / \ @@ -757,30 +810,30 @@ while (fragment == (peasycap->audio_read / \ if ((0 > peasycap->audio_read) || \ (peasycap->audio_buffer_page_many <= \ peasycap->audio_read)) { - SAY("ERROR: peasycap->audio_read out of range\n"); + SAM("ERROR: peasycap->audio_read out of range\n"); return -EFAULT; } pdata_buffer = &peasycap->audio_buffer[peasycap->audio_read]; if ((struct data_buffer *)NULL == pdata_buffer) { - SAY("ERROR: pdata_buffer is NULL\n"); + SAM("ERROR: pdata_buffer is NULL\n"); return -EFAULT; } if (NULL == pdata_buffer->pgo) { - SAY("ERROR: pdata_buffer->pgo is NULL\n"); + SAM("ERROR: pdata_buffer->pgo is NULL\n"); return -EFAULT; } if (NULL == pdata_buffer->pto) { - SAY("ERROR: pdata_buffer->pto is NULL\n"); + SAM("ERROR: pdata_buffer->pto is NULL\n"); return -EFAULT; } kount1 = PAGE_SIZE - (pdata_buffer->pto - pdata_buffer->pgo); } - JOT(12, "ready to send %li bytes\n", (long int) kount1); - JOT(12, "still to send %li bytes\n", (long int) kount); + JOM(12, "ready to send %li bytes\n", (long int) kount1); + JOM(12, "still to send %li bytes\n", (long int) kount); more = kount1; if (more > kount) more = kount; - JOT(12, "agreed to send %li bytes from page %i\n", \ + JOM(12, "agreed to send %li bytes from page %i\n", \ more, peasycap->audio_read); if (!more) break; @@ -798,7 +851,7 @@ while (fragment == (peasycap->audio_read / \ /*---------------------------------------------------------------------------*/ rc = copy_to_user(puserspacebuffer, pdata_buffer->pto, more); if (0 != rc) { - SAY("ERROR: copy_to_user() returned %li\n", rc); + SAM("ERROR: copy_to_user() returned %li\n", rc); return -EFAULT; } *poff += (loff_t)more; @@ -807,11 +860,11 @@ while (fragment == (peasycap->audio_read / \ puserspacebuffer += more; kount -= (size_t)more; } -JOT(12, "after read, %i=frag read %i=frag fill\n", \ +JOM(12, "after read, %i=frag read %i=frag fill\n", \ (peasycap->audio_read / peasycap->audio_pages_per_fragment), \ (peasycap->audio_fill / peasycap->audio_pages_per_fragment)); if (kount < 0) { - SAY("MISTAKE: %li=kount %li=szret\n", \ + SAM("MISTAKE: %li=kount %li=szret\n", \ (long int)kount, (long int)szret); } /*---------------------------------------------------------------------------*/ @@ -827,11 +880,11 @@ if (peasycap->audio_sample) { mean = peasycap->audio_niveau; sdr = signed_div(mean, peasycap->audio_sample); - JOT(8, "%8lli=mean %8lli=meansquare after %lli samples, =>\n", \ + JOM(8, "%8lli=mean %8lli=meansquare after %lli samples, =>\n", \ sdr.quotient, above, peasycap->audio_sample); sdr = signed_div(above, 32768); - JOT(8, "audio dynamic range is roughly %lli\n", sdr.quotient); + JOM(8, "audio dynamic range is roughly %lli\n", sdr.quotient); } /*---------------------------------------------------------------------------*/ /* @@ -840,26 +893,27 @@ if (peasycap->audio_sample) { /*---------------------------------------------------------------------------*/ do_gettimeofday(&timeval); if (!peasycap->timeval1.tv_sec) { - audio_bytes = 0; - timeval1 = timeval; - peasycap->timeval1 = timeval1; + peasycap->audio_bytes = 0; + peasycap->timeval3 = timeval; + peasycap->timeval1 = peasycap->timeval3; sdr.quotient = 192000; } else { - audio_bytes += (long long int) szret; + peasycap->audio_bytes += (long long int) szret; below = ((long long int)(1000000)) * \ - ((long long int)(timeval.tv_sec - timeval1.tv_sec)) + \ - (long long int)(timeval.tv_usec - timeval1.tv_usec); - above = 1000000 * ((long long int) audio_bytes); + ((long long int)(timeval.tv_sec - \ + peasycap->timeval3.tv_sec)) + \ + (long long int)(timeval.tv_usec - peasycap->timeval3.tv_usec); + above = 1000000 * ((long long int) peasycap->audio_bytes); if (below) sdr = signed_div(above, below); else sdr.quotient = 192000; } -JOT(8, "audio streaming at %lli bytes/second\n", sdr.quotient); +JOM(8, "audio streaming at %lli bytes/second\n", sdr.quotient); peasycap->dnbydt = sdr.quotient; -JOT(8, "returning %li\n", (long int)szret); +JOM(8, "returning %li\n", (long int)szret); return szret; } /*****************************************************************************/ @@ -874,27 +928,31 @@ submit_audio_urbs(struct easycap *peasycap) struct data_urb *pdata_urb; struct urb *purb; struct list_head *plist_head; -int j, isbad, m, rc; +int j, isbad, nospc, m, rc; int isbuf; +if (NULL == peasycap) { + SAY("ERROR: peasycap is NULL\n"); + return -EFAULT; +} if ((struct list_head *)NULL == peasycap->purb_audio_head) { - SAY("ERROR: peasycap->urb_audio_head uninitialized\n"); + SAM("ERROR: peasycap->urb_audio_head uninitialized\n"); return -EFAULT; } if ((struct usb_device *)NULL == peasycap->pusb_device) { - SAY("ERROR: peasycap->pusb_device is NULL\n"); + SAM("ERROR: peasycap->pusb_device is NULL\n"); return -EFAULT; } if (!peasycap->audio_isoc_streaming) { - JOT(4, "initial submission of all audio urbs\n"); + JOM(4, "initial submission of all audio urbs\n"); rc = usb_set_interface(peasycap->pusb_device, peasycap->audio_interface, \ peasycap->audio_altsetting_on); - JOT(8, "usb_set_interface(.,%i,%i) returned %i\n", \ + JOM(8, "usb_set_interface(.,%i,%i) returned %i\n", \ peasycap->audio_interface, \ peasycap->audio_altsetting_on, rc); - isbad = 0; m = 0; + isbad = 0; nospc = 0; m = 0; list_for_each(plist_head, (peasycap->purb_audio_head)) { pdata_urb = list_entry(plist_head, struct data_urb, list_head); if (NULL != pdata_urb) { @@ -931,39 +989,49 @@ if (!peasycap->audio_isoc_streaming) { rc = usb_submit_urb(purb, GFP_KERNEL); if (0 != rc) { isbad++; - SAY("ERROR: usb_submit_urb() failed" \ + SAM("ERROR: usb_submit_urb() failed" \ " for urb with rc:\n"); switch (rc) { case -ENOMEM: { - SAY("ENOMEM\n"); break; + SAM("-ENOMEM\n"); + break; } case -ENODEV: { - SAY("ENODEV\n"); break; + SAM("-ENODEV\n"); + break; } case -ENXIO: { - SAY("ENXIO\n"); break; + SAM("-ENXIO\n"); + break; } case -EINVAL: { - SAY("EINVAL\n"); break; + SAM("-EINVAL\n"); + break; } case -EAGAIN: { - SAY("EAGAIN\n"); break; + SAM("-EAGAIN\n"); + break; } case -EFBIG: { - SAY("EFBIG\n"); break; + SAM("-EFBIG\n"); + break; } case -EPIPE: { - SAY("EPIPE\n"); break; + SAM("-EPIPE\n"); + break; } case -EMSGSIZE: { - SAY("EMSGSIZE\n"); break; + SAM("-EMSGSIZE\n"); + break; } case -ENOSPC: { - SAY("ENOSPC\n"); break; + nospc++; + break; } default: { - SAY("unknown error code %i\n",\ - rc); break; + SAM("unknown error code %i\n",\ + rc); + break; } } } else { @@ -976,8 +1044,13 @@ if (!peasycap->audio_isoc_streaming) { isbad++; } } + if (nospc) { + SAM("-ENOSPC=usb_submit_urb() for %i urbs\n", nospc); + SAM("..... possibly inadequate USB bandwidth\n"); + peasycap->audio_eof = 1; + } if (isbad) { - JOT(4, "attempting cleanup instead of submitting\n"); + JOM(4, "attempting cleanup instead of submitting\n"); list_for_each(plist_head, (peasycap->purb_audio_head)) { pdata_urb = list_entry(plist_head, struct data_urb, \ list_head); @@ -990,10 +1063,10 @@ if (!peasycap->audio_isoc_streaming) { peasycap->audio_isoc_streaming = 0; } else { peasycap->audio_isoc_streaming = 1; - JOT(4, "submitted %i audio urbs\n", m); + JOM(4, "submitted %i audio urbs\n", m); } } else - JOT(4, "already streaming audio urbs\n"); + JOM(4, "already streaming audio urbs\n"); return 0; } @@ -1010,10 +1083,14 @@ int m; struct list_head *plist_head; struct data_urb *pdata_urb; +if (NULL == peasycap) { + SAY("ERROR: peasycap is NULL\n"); + return -EFAULT; +} if (peasycap->audio_isoc_streaming) { if ((struct list_head *)NULL != peasycap->purb_audio_head) { peasycap->audio_isoc_streaming = 0; - JOT(4, "killing audio urbs\n"); + JOM(4, "killing audio urbs\n"); m = 0; list_for_each(plist_head, (peasycap->purb_audio_head)) { pdata_urb = list_entry(plist_head, struct data_urb, @@ -1025,13 +1102,13 @@ if (peasycap->audio_isoc_streaming) { } } } - JOT(4, "%i audio urbs killed\n", m); + JOM(4, "%i audio urbs killed\n", m); } else { - SAY("ERROR: peasycap->purb_audio_head is NULL\n"); + SAM("ERROR: peasycap->purb_audio_head is NULL\n"); return -EFAULT; } } else { - JOT(8, "%i=audio_isoc_streaming, no audio urbs killed\n", \ + JOM(8, "%i=audio_isoc_streaming, no audio urbs killed\n", \ peasycap->audio_isoc_streaming); } return 0; diff --git a/drivers/staging/easycap/easycap_testcard.c b/drivers/staging/easycap/easycap_testcard.c index 700c73ec1c59..dd98b471d5b8 100644 --- a/drivers/staging/easycap/easycap_testcard.c +++ b/drivers/staging/easycap/easycap_testcard.c @@ -157,7 +157,7 @@ for (i1 = 0; i1 <= last; i1++) printf("%6i, ", i2); printf("%6i\n};\n", i2); } } -return(0); +return 0; } -----------------------------------------------------------------------------*/ int tones[2048] = { -- cgit v1.2.3 From f36bc37a48148f31f936557b811431b98dbfe347 Mon Sep 17 00:00:00 2001 From: Mike Thomas Date: Sun, 7 Nov 2010 20:00:35 +0000 Subject: staging/easycap: Improve hardware initialization Sometimes at startup the video urbs consistently and persistently deliver bad data, each video frame (not isoc frame) containing an excess of precisely two bytes. A brute-force cure implemented here is to repeatedly reinitialize the registers of the SAA7113H chip and the STK1160 USB bridge until good behaviour is obtained. Signed-off-by: Mike Thomas Signed-off-by: Greg Kroah-Hartman --- drivers/staging/easycap/easycap.h | 47 +- drivers/staging/easycap/easycap_ioctl.c | 361 ++++++++++----- drivers/staging/easycap/easycap_low.c | 675 ++++++++++++++++----------- drivers/staging/easycap/easycap_main.c | 786 ++++++++++++++++++++++++++------ drivers/staging/easycap/easycap_sound.c | 20 +- 5 files changed, 1345 insertions(+), 544 deletions(-) diff --git a/drivers/staging/easycap/easycap.h b/drivers/staging/easycap/easycap.h index 11ceda7dde30..20e51ddec1e1 100644 --- a/drivers/staging/easycap/easycap.h +++ b/drivers/staging/easycap/easycap.h @@ -42,12 +42,19 @@ #if (!defined(EASYCAP_H)) #define EASYCAP_H +/*---------------------------------------------------------------------------*/ +/* + * THESE ARE NORMALLY DEFINED + */ +/*---------------------------------------------------------------------------*/ +#define PATIENCE 500 +#undef PREFER_NTSC +#define PERSEVERE /*---------------------------------------------------------------------------*/ /* * THESE ARE FOR MAINTENANCE ONLY - NORMALLY UNDEFINED: */ /*---------------------------------------------------------------------------*/ -#undef PREFER_NTSC #undef EASYCAP_TESTCARD #undef EASYCAP_TESTTONE #undef NOREADBACK @@ -122,7 +129,7 @@ #define USB_SKEL_MINOR_BASE 192 #define DONGLE_MANY 8 - +#define INPUT_MANY 6 /*---------------------------------------------------------------------------*/ /* * DEFAULT LUMINANCE, CONTRAST, SATURATION AND HUE @@ -146,6 +153,7 @@ #if (USB_2_0_MAXPACKETSIZE > PAGE_SIZE) #error video_isoc_buffer[.] will not be big enough #endif +#define VIDEO_JUNK_TOLERATE VIDEO_ISOC_BUFFER_MANY /*---------------------------------------------------------------------------*/ /* * VIDEO BUFFERS @@ -238,6 +246,7 @@ struct list_head list_head; void *pgo; void *pto; __u16 kount; +__u16 input; }; /*---------------------------------------------------------------------------*/ struct data_urb { @@ -256,6 +265,22 @@ __u16 mask; char name[128]; struct v4l2_format v4l2_format; }; +struct inputset { +int input; +int input_ok; +int standard_offset; +int standard_offset_ok; +int format_offset; +int format_offset_ok; +int brightness; +int brightness_ok; +int contrast; +int contrast_ok; +int saturation; +int saturation_ok; +int hue; +int hue_ok; +}; /*---------------------------------------------------------------------------*/ /* * easycap.ilk == 0 => CVBS+S-VIDEO HARDWARE, AUDIO wMaxPacketSize=256 @@ -274,7 +299,7 @@ struct v4l2_device v4l2_device; #endif /*EASYCAP_NEEDS_V4L2_DEVICE_H*/ #endif /*EASYCAP_IS_VIDEODEV_CLIENT*/ /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ - +int status; unsigned int audio_pages_per_fragment; unsigned int audio_bytes_per_fragment; unsigned int audio_buffer_page_many; @@ -302,7 +327,9 @@ int input; int polled; int standard_offset; int format_offset; +struct inputset inputset[INPUT_MANY]; +bool ntsc; int fps; int usec; int tolerate; @@ -480,6 +507,8 @@ int redaub(struct easycap *, void *, void *, \ int, int, __u8, __u8, bool); void easycap_testcard(struct easycap *, int); int fillin_formats(void); +int reset(struct easycap *); +int newinput(struct easycap *, int); int adjust_standard(struct easycap *, v4l2_std_id); int adjust_format(struct easycap *, __u32, __u32, __u32, \ int, bool); @@ -517,11 +546,11 @@ int wakeup_device(struct usb_device *); int confirm_resolution(struct usb_device *); int confirm_stream(struct usb_device *); -int setup_stk(struct usb_device *); -int setup_saa(struct usb_device *); +int setup_stk(struct usb_device *, bool); +int setup_saa(struct usb_device *, bool); int setup_vt(struct usb_device *); -int check_stk(struct usb_device *); -int check_saa(struct usb_device *); +int check_stk(struct usb_device *, bool); +int check_saa(struct usb_device *, bool); int ready_saa(struct usb_device *); int merit_saa(struct usb_device *); int check_vt(struct usb_device *); @@ -539,10 +568,6 @@ int stop_100(struct usb_device *); int write_300(struct usb_device *); int read_vt(struct usb_device *, __u16); int write_vt(struct usb_device *, __u16, __u16); - -int set2to78(struct usb_device *); -int set2to93(struct usb_device *); - int regset(struct usb_device *, __u16, __u16); int regget(struct usb_device *, __u16, void *); int isdongle(struct easycap *); diff --git a/drivers/staging/easycap/easycap_ioctl.c b/drivers/staging/easycap/easycap_ioctl.c index d91d64ad6f68..0ed37c23c7ec 100644 --- a/drivers/staging/easycap/easycap_ioctl.c +++ b/drivers/staging/easycap/easycap_ioctl.c @@ -36,6 +36,7 @@ * UNLESS THERE IS A PREMATURE ERROR RETURN THIS ROUTINE UPDATES THE * FOLLOWING: * peasycap->standard_offset + * peasycap->inputset[peasycap->input].standard_offset * peasycap->fps * peasycap->usec * peasycap->tolerate @@ -45,8 +46,9 @@ int adjust_standard(struct easycap *peasycap, v4l2_std_id std_id) { struct easycap_standard const *peasycap_standard; __u16 reg, set; -int ir, rc, need; +int ir, rc, need, k; unsigned int itwas, isnow; +bool resubmit; if (NULL == peasycap) { SAY("ERROR: peasycap is NULL\n"); @@ -67,7 +69,7 @@ if (0xFFFF == peasycap_standard->mask) { (unsigned int)std_id); return -EINVAL; } -SAM("user requests standard: %s\n", \ +SAM("selected standard: %s\n", \ &(peasycap_standard->v4l2_standard.name[0])); if (peasycap->standard_offset == \ (int)(peasycap_standard - &easycap_standard[0])) { @@ -75,18 +77,43 @@ if (peasycap->standard_offset == \ return 0; } peasycap->standard_offset = (int)(peasycap_standard - &easycap_standard[0]); +for (k = 0; k < INPUT_MANY; k++) { + if (!peasycap->inputset[k].standard_offset_ok) { + peasycap->inputset[k].standard_offset = \ + peasycap->standard_offset; + } +} +if ((0 <= peasycap->input) && (INPUT_MANY > peasycap->input)) { + peasycap->inputset[peasycap->input].standard_offset = \ + peasycap->standard_offset; + peasycap->inputset[peasycap->input].standard_offset_ok = 1; +} else + JOM(8, "%i=peasycap->input\n", peasycap->input); peasycap->fps = peasycap_standard->v4l2_standard.frameperiod.denominator / \ peasycap_standard->v4l2_standard.frameperiod.numerator; -if (!peasycap->fps) { - SAM("MISTAKE: frames-per-second is zero\n"); - return -EFAULT; +switch (peasycap->fps) { +case 30: { + peasycap->ntsc = true; + break; +} +case 25: { + peasycap->ntsc = false; + break; +} +default: { + SAM("MISTAKE: %i=frames-per-second\n", peasycap->fps); + return -ENOENT; +} } JOM(8, "%i frames-per-second\n", peasycap->fps); peasycap->usec = 1000000 / (2 * peasycap->fps); peasycap->tolerate = 1000 * (25 / peasycap->fps); -kill_video_urbs(peasycap); - +if (peasycap->video_isoc_streaming) { + resubmit = true; + kill_video_urbs(peasycap); +} else + resubmit = false; /*--------------------------------------------------------------------------*/ /* * SAA7113H DATASHEET PAGE 44, TABLE 42 @@ -101,11 +128,6 @@ case NTSC_M_JP: { SAM("ERROR: cannot read SAA register 0x%02X\n", reg); else itwas = (unsigned int)ir; - - - set2to78(peasycap->pusb_device); - - rc = write_saa(peasycap->pusb_device, reg, set); if (0 != rc) SAM("ERROR: failed to set SAA register " \ @@ -118,9 +140,6 @@ case NTSC_M_JP: { else JOM(8, "SAA register 0x%02X changed " \ "from 0x%02X to 0x%02X\n", reg, itwas, isnow); - - set2to78(peasycap->pusb_device); - } reg = 0x0B; set = 0x48; @@ -129,9 +148,6 @@ case NTSC_M_JP: { SAM("ERROR: cannot read SAA register 0x%02X\n", reg); else itwas = (unsigned int)ir; - - set2to78(peasycap->pusb_device); - rc = write_saa(peasycap->pusb_device, reg, set); if (0 != rc) SAM("ERROR: failed to set SAA register 0x%02X to 0x%02X " \ @@ -144,9 +160,6 @@ case NTSC_M_JP: { else JOM(8, "SAA register 0x%02X changed " \ "from 0x%02X to 0x%02X\n", reg, itwas, isnow); - - set2to78(peasycap->pusb_device); - } /*--------------------------------------------------------------------------*/ /* @@ -183,9 +196,6 @@ if (need) { SAM("ERROR: failed to read SAA register 0x%02X\n", reg); else itwas = (unsigned int)ir; - - set2to78(peasycap->pusb_device); - rc = write_saa(peasycap->pusb_device, reg, set); if (0 != write_saa(peasycap->pusb_device, reg, set)) { SAM("ERROR: failed to set SAA register " \ @@ -216,19 +226,18 @@ else { set = itwas | 0x40 ; else set = itwas & ~0x40 ; - -set2to78(peasycap->pusb_device); - -rc = write_saa(peasycap->pusb_device, reg, set); -if (0 != rc) - SAM("ERROR: failed to set SAA register 0x%02X to 0x%02X\n", reg, set); -else { - isnow = (unsigned int)read_saa(peasycap->pusb_device, reg); - if (0 > ir) - JOM(8, "SAA register 0x%02X changed to 0x%02X\n", reg, isnow); - else - JOM(8, "SAA register 0x%02X changed " \ - "from 0x%02X to 0x%02X\n", reg, itwas, isnow); + rc = write_saa(peasycap->pusb_device, reg, set); + if (0 != rc) + SAM("ERROR: failed to set SAA register 0x%02X to 0x%02X\n", \ + reg, set); + else { + isnow = (unsigned int)read_saa(peasycap->pusb_device, reg); + if (0 > ir) + JOM(8, "SAA register 0x%02X changed to 0x%02X\n", \ + reg, isnow); + else + JOM(8, "SAA register 0x%02X changed " \ + "from 0x%02X to 0x%02X\n", reg, itwas, isnow); } } /*--------------------------------------------------------------------------*/ @@ -247,19 +256,18 @@ else { set = itwas | 0x80 ; else set = itwas & ~0x80 ; - -set2to78(peasycap->pusb_device); - -rc = write_saa(peasycap->pusb_device, reg, set); -if (0 != rc) - SAM("ERROR: failed to set SAA register 0x%02X to 0x%02X\n", reg, set); -else { - isnow = (unsigned int)read_saa(peasycap->pusb_device, reg); - if (0 > ir) - JOM(8, "SAA register 0x%02X changed to 0x%02X\n", reg, isnow); - else - JOM(8, "SAA register 0x%02X changed " \ - "from 0x%02X to 0x%02X\n", reg, itwas, isnow); + rc = write_saa(peasycap->pusb_device, reg, set); + if (0 != rc) + SAM("ERROR: failed to set SAA register 0x%02X to 0x%02X\n", \ + reg, set); + else { + isnow = (unsigned int)read_saa(peasycap->pusb_device, reg); + if (0 > ir) + JOM(8, "SAA register 0x%02X changed to 0x%02X\n", \ + reg, isnow); + else + JOM(8, "SAA register 0x%02X changed " \ + "from 0x%02X to 0x%02X\n", reg, itwas, isnow); } } /*--------------------------------------------------------------------------*/ @@ -276,9 +284,6 @@ if (0 > ir) set = 0x0A ; else set = 0x07 ; - - set2to78(peasycap->pusb_device); - if (0 != write_saa(peasycap->pusb_device, reg, set)) SAM("ERROR: failed to set SAA register 0x%02X to 0x%02X\n", \ reg, set); @@ -291,18 +296,20 @@ if (0 > ir) JOM(8, "SAA register 0x%02X changed " "from 0x%02X to 0x%02X\n", reg, itwas, isnow); } - if (0 != check_saa(peasycap->pusb_device)) - SAM("ERROR: check_saa() failed\n"); +if (true == resubmit) + submit_video_urbs(peasycap); return 0; } /*****************************************************************************/ /*--------------------------------------------------------------------------*/ /* - * THE ALGORITHM FOR RESPONDING TO THE VIDIO_S_FMT IOCTL DEPENDS ON THE - * CURRENT VALUE OF peasycap->standard_offset. + * THE ALGORITHM FOR RESPONDING TO THE VIDIO_S_FMT IOCTL REQUIRES + * A VALID VALUE OF peasycap->standard_offset, OTHERWISE -EBUSY IS RETURNED. + * * PROVIDED THE ARGUMENT try IS false AND THERE IS NO PREMATURE ERROR RETURN * THIS ROUTINE UPDATES THE FOLLOWING: * peasycap->format_offset + * peasycap->inputset[peasycap->input].format_offset * peasycap->pixelformat * peasycap->field * peasycap->height @@ -325,14 +332,19 @@ int adjust_format(struct easycap *peasycap, \ struct easycap_format *peasycap_format, *peasycap_best_format; __u16 mask; struct usb_device *p; -int miss, multiplier, best; +int miss, multiplier, best, k; char bf[5], *pc; __u32 uc; +bool resubmit; if (NULL == peasycap) { SAY("ERROR: peasycap is NULL\n"); return -EFAULT; } +if (0 > peasycap->standard_offset) { + JOM(8, "%i=peasycap->standard_offset\n", peasycap->standard_offset); + return -EBUSY; +} p = peasycap->pusb_device; if ((struct usb_device *)NULL == p) { SAM("ERROR: peaycap->pusb_device is NULL\n"); @@ -422,6 +434,23 @@ peasycap->width = peasycap_format->v4l2_format.fmt.pix.width; peasycap->pixelformat = peasycap_format->v4l2_format.fmt.pix.pixelformat; peasycap->field = peasycap_format->v4l2_format.fmt.pix.field; peasycap->format_offset = (int)(peasycap_format - &easycap_format[0]); + + +for (k = 0; k < INPUT_MANY; k++) { + if (!peasycap->inputset[k].format_offset_ok) { + peasycap->inputset[k].format_offset = \ + peasycap->format_offset; + } +} +if ((0 <= peasycap->input) && (INPUT_MANY > peasycap->input)) { + peasycap->inputset[peasycap->input].format_offset = \ + peasycap->format_offset; + peasycap->inputset[peasycap->input].format_offset_ok = 1; +} else + JOM(8, "%i=peasycap->input\n", peasycap->input); + + + peasycap->bytesperpixel = (0x00F0 & peasycap_format->mask) >> 4 ; if (0x0100 & peasycap_format->mask) peasycap->byteswaporder = true; @@ -461,9 +490,11 @@ if (true == peasycap->offerfields) { } - -kill_video_urbs(peasycap); - +if (peasycap->video_isoc_streaming) { + resubmit = true; + kill_video_urbs(peasycap); +} else + resubmit = false; /*---------------------------------------------------------------------------*/ /* * PAL @@ -536,16 +567,15 @@ if (0 == (0x01 & peasycap_format->mask)) { } } /*---------------------------------------------------------------------------*/ - -check_stk(peasycap->pusb_device); - +if (true == resubmit) + submit_video_urbs(peasycap); return (int)(peasycap_best_format - &easycap_format[0]); } /*****************************************************************************/ int adjust_brightness(struct easycap *peasycap, int value) { unsigned int mood; -int i1; +int i1, k; if (NULL == peasycap) { SAY("ERROR: peasycap is NULL\n"); @@ -561,11 +591,29 @@ while (0xFFFFFFFF != easycap_control[i1].id) { if ((easycap_control[i1].minimum > value) || \ (easycap_control[i1].maximum < value)) value = easycap_control[i1].default_value; + + if ((easycap_control[i1].minimum <= peasycap->brightness) && \ + (easycap_control[i1].maximum >= \ + peasycap->brightness)) { + if (peasycap->brightness == value) { + SAM("unchanged brightness at 0x%02X\n", \ + value); + return 0; + } + } peasycap->brightness = value; + for (k = 0; k < INPUT_MANY; k++) { + if (!peasycap->inputset[k].brightness_ok) + peasycap->inputset[k].brightness = \ + peasycap->brightness; + } + if ((0 <= peasycap->input) && (INPUT_MANY > peasycap->input)) { + peasycap->inputset[peasycap->input].brightness = \ + peasycap->brightness; + peasycap->inputset[peasycap->input].brightness_ok = 1; + } else + JOM(8, "%i=peasycap->input\n", peasycap->input); mood = 0x00FF & (unsigned int)peasycap->brightness; - - set2to78(peasycap->pusb_device); - if (!write_saa(peasycap->pusb_device, 0x0A, mood)) { SAM("adjusting brightness to 0x%02X\n", mood); return 0; @@ -574,9 +622,6 @@ while (0xFFFFFFFF != easycap_control[i1].id) { "to 0x%02X\n", mood); return -ENOENT; } - - set2to78(peasycap->pusb_device); - break; } i1++; @@ -588,7 +633,7 @@ return -ENOENT; int adjust_contrast(struct easycap *peasycap, int value) { unsigned int mood; -int i1; +int i1, k; if (NULL == peasycap) { SAY("ERROR: peasycap is NULL\n"); @@ -604,11 +649,31 @@ while (0xFFFFFFFF != easycap_control[i1].id) { if ((easycap_control[i1].minimum > value) || \ (easycap_control[i1].maximum < value)) value = easycap_control[i1].default_value; - peasycap->contrast = value; - mood = 0x00FF & (unsigned int) (peasycap->contrast - 128); - set2to78(peasycap->pusb_device); + + if ((easycap_control[i1].minimum <= peasycap->contrast) && \ + (easycap_control[i1].maximum >= \ + peasycap->contrast)) { + if (peasycap->contrast == value) { + SAM("unchanged contrast at 0x%02X\n", value); + return 0; + } + } + peasycap->contrast = value; + for (k = 0; k < INPUT_MANY; k++) { + if (!peasycap->inputset[k].contrast_ok) { + peasycap->inputset[k].contrast = \ + peasycap->contrast; + } + } + if ((0 <= peasycap->input) && (INPUT_MANY > peasycap->input)) { + peasycap->inputset[peasycap->input].contrast = \ + peasycap->contrast; + peasycap->inputset[peasycap->input].contrast_ok = 1; + } else + JOM(8, "%i=peasycap->input\n", peasycap->input); + mood = 0x00FF & (unsigned int) (peasycap->contrast - 128); if (!write_saa(peasycap->pusb_device, 0x0B, mood)) { SAM("adjusting contrast to 0x%02X\n", mood); return 0; @@ -617,9 +682,6 @@ while (0xFFFFFFFF != easycap_control[i1].id) { "0x%02X\n", mood); return -ENOENT; } - - set2to78(peasycap->pusb_device); - break; } i1++; @@ -631,7 +693,7 @@ return -ENOENT; int adjust_saturation(struct easycap *peasycap, int value) { unsigned int mood; -int i1; +int i1, k; if (NULL == peasycap) { SAY("ERROR: peasycap is NULL\n"); @@ -647,11 +709,31 @@ while (0xFFFFFFFF != easycap_control[i1].id) { if ((easycap_control[i1].minimum > value) || \ (easycap_control[i1].maximum < value)) value = easycap_control[i1].default_value; - peasycap->saturation = value; - mood = 0x00FF & (unsigned int) (peasycap->saturation - 128); - set2to78(peasycap->pusb_device); + if ((easycap_control[i1].minimum <= peasycap->saturation) && \ + (easycap_control[i1].maximum >= \ + peasycap->saturation)) { + if (peasycap->saturation == value) { + SAM("unchanged saturation at 0x%02X\n", \ + value); + return 0; + } + } + peasycap->saturation = value; + for (k = 0; k < INPUT_MANY; k++) { + if (!peasycap->inputset[k].saturation_ok) { + peasycap->inputset[k].saturation = \ + peasycap->saturation; + } + } + if ((0 <= peasycap->input) && (INPUT_MANY > peasycap->input)) { + peasycap->inputset[peasycap->input].saturation = \ + peasycap->saturation; + peasycap->inputset[peasycap->input].saturation_ok = 1; + } else + JOM(8, "%i=peasycap->input\n", peasycap->input); + mood = 0x00FF & (unsigned int) (peasycap->saturation - 128); if (!write_saa(peasycap->pusb_device, 0x0C, mood)) { SAM("adjusting saturation to 0x%02X\n", mood); return 0; @@ -661,9 +743,6 @@ while (0xFFFFFFFF != easycap_control[i1].id) { return -ENOENT; } break; - - set2to78(peasycap->pusb_device); - } i1++; } @@ -674,7 +753,7 @@ return -ENOENT; int adjust_hue(struct easycap *peasycap, int value) { unsigned int mood; -int i1, i2; +int i1, i2, k; if (NULL == peasycap) { SAY("ERROR: peasycap is NULL\n"); @@ -690,12 +769,28 @@ while (0xFFFFFFFF != easycap_control[i1].id) { if ((easycap_control[i1].minimum > value) || \ (easycap_control[i1].maximum < value)) value = easycap_control[i1].default_value; + + if ((easycap_control[i1].minimum <= peasycap->hue) && \ + (easycap_control[i1].maximum >= \ + peasycap->hue)) { + if (peasycap->hue == value) { + SAM("unchanged hue at 0x%02X\n", value); + return 0; + } + } peasycap->hue = value; + for (k = 0; k < INPUT_MANY; k++) { + if (!peasycap->inputset[k].hue_ok) + peasycap->inputset[k].hue = peasycap->hue; + } + if ((0 <= peasycap->input) && (INPUT_MANY > peasycap->input)) { + peasycap->inputset[peasycap->input].hue = \ + peasycap->hue; + peasycap->inputset[peasycap->input].hue_ok = 1; + } else + JOM(8, "%i=peasycap->input\n", peasycap->input); i2 = peasycap->hue - 128; mood = 0x00FF & ((int) i2); - - set2to78(peasycap->pusb_device); - if (!write_saa(peasycap->pusb_device, 0x0D, mood)) { SAM("adjusting hue to 0x%02X\n", mood); return 0; @@ -703,9 +798,6 @@ while (0xFFFFFFFF != easycap_control[i1].id) { SAM("WARNING: failed to adjust hue to 0x%02X\n", mood); return -ENOENT; } - - set2to78(peasycap->pusb_device); - break; } i1++; @@ -1004,6 +1096,7 @@ case VIDIOC_G_INPUT: { case VIDIOC_S_INPUT: { __u32 index; + int rc; JOM(8, "VIDIOC_S_INPUT\n"); @@ -1017,14 +1110,18 @@ case VIDIOC_S_INPUT: break; } - if ((0 > index) || (5 < index)) { + if ((0 > index) || (INPUT_MANY <= index)) { JOM(8, "ERROR: bad requested input: %i\n", index); return -EINVAL; } - peasycap->input = (int)index; - - select_input(peasycap->pusb_device, peasycap->input, 9); + rc = newinput(peasycap, (int)index); + if (0 == rc) { + JOM(8, "newinput(.,%i) OK\n", (int)index); + } else { + SAM("ERROR: newinput(.,%i) returned %i\n", (int)index, rc); + return -EFAULT; + } break; } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ @@ -1351,6 +1448,8 @@ case VIDIOC_S_FMT: { v4l2_format.fmt.pix.field, \ try); if (0 > best_format) { + if (-EBUSY == best_format) + return -EBUSY; JOM(8, "WARNING: adjust_format() returned %i\n", best_format); return -ENOENT; } @@ -1472,6 +1571,12 @@ case VIDIOC_G_STD: { JOM(8, "VIDIOC_G_STD\n"); + if (0 > peasycap->standard_offset) { + JOM(8, "%i=peasycap->standard_offset\n", \ + peasycap->standard_offset); + return -EBUSY; + } + if (0 != copy_from_user(&std_id, (void __user *)arg, \ sizeof(v4l2_std_id))) return -EFAULT; @@ -1549,9 +1654,9 @@ case VIDIOC_QUERYBUF: { JOM(8, "VIDIOC_QUERYBUF\n"); if (peasycap->video_eof) { - JOM(8, "returning -1 because %i=video_eof\n", \ + JOM(8, "returning -EIO because %i=video_eof\n", \ peasycap->video_eof); - return -1; + return -EIO; } if (0 != copy_from_user(&v4l2_buffer, (void __user *)arg, \ @@ -1632,12 +1737,14 @@ case VIDIOC_DQBUF: struct signed_div_result sdr; long long int above, below, dnbydt, fudge, sll; unsigned long long int ull; - struct timeval timeval0; + struct timeval timeval8; struct timeval timeval1; #endif /*AUDIOTIME*/ struct timeval timeval, timeval2; int i, j; struct v4l2_buffer v4l2_buffer; + int rcdq; + __u16 input; JOM(8, "VIDIOC_DQBUF\n"); @@ -1668,8 +1775,14 @@ case VIDIOC_DQBUF: /*---------------------------------------------------------------------------*/ if (!peasycap->polled) { - if (-EIO == easycap_dqbuf(peasycap, 0)) - return -EIO; + do { + rcdq = easycap_dqbuf(peasycap, 0); + if (-EIO == rcdq) { + JOM(8, "returning -EIO because " \ + "dqbuf() returned -EIO\n"); + return -EIO; + } + } while (0 != rcdq); } else { if (peasycap->video_eof) return -EIO; @@ -1708,11 +1821,11 @@ case VIDIOC_DQBUF: #if defined(AUDIOTIME) if (!peasycap->timeval0.tv_sec) { - timeval0 = timeval; + timeval8 = timeval; timeval1 = timeval; timeval2 = timeval; dnbydt = 192000; - peasycap->timeval0 = timeval0; + peasycap->timeval0 = timeval8; } else { dnbydt = peasycap->dnbydt; timeval1 = peasycap->timeval1; @@ -1766,21 +1879,26 @@ case VIDIOC_DQBUF: JOM(8, "..... user is offered frame buffer %i\n", \ peasycap->frame_read); peasycap->frame_lock = 1; + + input = peasycap->frame_buffer[peasycap->frame_read][0].input; + if (0x08 & input) { + JOM(8, "user is offered frame buffer %i, input %i\n", \ + peasycap->frame_read, (0x07 & input)); + } else { + JOM(8, "user is offered frame buffer %i\n", \ + peasycap->frame_read); + } + peasycap->frame_lock = 1; + JOM(8, "%i=peasycap->frame_fill\n", peasycap->frame_fill); if (peasycap->frame_read == peasycap->frame_fill) { if (peasycap->frame_lock) { - JOM(8, "ERROR: filling frame buffer " \ + JOM(8, "WORRY: filling frame buffer " \ "while offered to user\n"); } } break; } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -/*---------------------------------------------------------------------------*/ -/* - * AUDIO URBS HAVE ALREADY BEEN SUBMITTED WHEN THIS COMMAND IS RECEIVED; - * VIDEO URBS HAVE NOT. - */ -/*---------------------------------------------------------------------------*/ case VIDIOC_STREAMON: { int i; @@ -1839,6 +1957,20 @@ case VIDIOC_G_PARM: { v4l2_streamparm.parm.capture.capturemode = 0; v4l2_streamparm.parm.capture.timeperframe.numerator = 1; v4l2_streamparm.parm.capture.timeperframe.denominator = 30; + + if (peasycap->fps) { + v4l2_streamparm.parm.capture.timeperframe.\ + denominator = peasycap->fps; + } else { + if (true == peasycap->ntsc) { + v4l2_streamparm.parm.capture.timeperframe.\ + denominator = 30; + } else { + v4l2_streamparm.parm.capture.timeperframe.\ + denominator = 25; + } + } + v4l2_streamparm.parm.capture.readbuffers = peasycap->frame_buffer_many; v4l2_streamparm.parm.capture.extendedmode = 0; if (0 != copy_to_user((void __user *)arg, &v4l2_streamparm, \ @@ -2095,6 +2227,15 @@ case SNDCTL_DSP_GETISPACE: { return -EFAULT; break; } +case 0x00005401: +case 0x00005402: +case 0x00005403: +case 0x00005404: +case 0x00005405: +case 0x00005406: { + JOM(8, "SNDCTL_TMR_...: 0x%08X unsupported\n", cmd); + return -ENOIOCTLCMD; +} default: { JOM(8, "ERROR: unrecognized DSP IOCTL command: 0x%08X\n", cmd); return -ENOIOCTLCMD; diff --git a/drivers/staging/easycap/easycap_low.c b/drivers/staging/easycap/easycap_low.c index a3be9c1e5a69..4badef263e9e 100644 --- a/drivers/staging/easycap/easycap_low.c +++ b/drivers/staging/easycap/easycap_low.c @@ -42,121 +42,205 @@ #include "easycap.h" /*--------------------------------------------------------------------------*/ -const struct stk1160config { int reg; int set; } stk1160config[256] = { - {0x000, 0x0098}, - {0x002, 0x0093}, - - {0x001, 0x0003}, - {0x003, 0x0080}, - {0x00D, 0x0000}, - {0x00F, 0x0002}, - {0x018, 0x0010}, - {0x019, 0x0000}, - {0x01A, 0x0014}, - {0x01B, 0x000E}, - {0x01C, 0x0046}, - - {0x100, 0x0033}, - {0x103, 0x0000}, - {0x104, 0x0000}, - {0x105, 0x0000}, - {0x106, 0x0000}, - -#if defined(PREFER_NTSC) - - {0x110, 0x0014}, - {0x111, 0x0000}, - {0x112, 0x0003}, - {0x113, 0x0000}, - {0x114, 0x0514}, - {0x115, 0x0005}, - {0x116, 0x00F3}, - {0x117, 0x0000}, - -#else /* ! PREFER_NTSC*/ - - {0x110, 0x0014}, - {0x111, 0x0000}, - {0x112, 0x0020}, - {0x113, 0x0000}, - {0x114, 0x0514}, - {0x115, 0x0005}, - {0x116, 0x0110}, - {0x117, 0x0001}, - -#endif /* ! PREFER_NTSC*/ - - {0x202, 0x000F}, - {0x203, 0x004A}, - {0x2FF, 0x0000}, -/*---------------------------------------------------------------------------*/ - {0xFFF, 0xFFFF} - }; +const struct stk1160config { int reg; int set; } stk1160configPAL[256] = { + {0x000, 0x0098}, + {0x002, 0x0093}, + + {0x001, 0x0003}, + {0x003, 0x0080}, + {0x00D, 0x0000}, + {0x00F, 0x0002}, + {0x018, 0x0010}, + {0x019, 0x0000}, + {0x01A, 0x0014}, + {0x01B, 0x000E}, + {0x01C, 0x0046}, + + {0x100, 0x0033}, + {0x103, 0x0000}, + {0x104, 0x0000}, + {0x105, 0x0000}, + {0x106, 0x0000}, + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +/* + * RESOLUTION 640x480 +*/ +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + {0x110, 0x0008}, + {0x111, 0x0000}, + {0x112, 0x0020}, + {0x113, 0x0000}, + {0x114, 0x0508}, + {0x115, 0x0005}, + {0x116, 0x0110}, + {0x117, 0x0001}, +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + {0x202, 0x000F}, + {0x203, 0x004A}, + {0x2FF, 0x0000}, + + {0xFFF, 0xFFFF} +}; /*--------------------------------------------------------------------------*/ -const struct saa7113config { int reg; int set; } saa7113config[256] = { - {0x01, 0x08}, - {0x02, 0x80}, - {0x03, 0x33}, - {0x04, 0x00}, - {0x05, 0x00}, - {0x06, 0xE9}, - {0x07, 0x0D}, -#if defined(PREFER_NTSC) - {0x08, 0x78}, -#else - {0x08, 0x38}, -#endif /* ! PREFER_NTSC*/ - {0x09, 0x00}, - {0x0A, SAA_0A_DEFAULT}, - {0x0B, SAA_0B_DEFAULT}, - {0x0C, SAA_0C_DEFAULT}, - {0x0D, SAA_0D_DEFAULT}, - {0x0E, 0x01}, - {0x0F, 0x36}, - {0x10, 0x00}, - {0x11, 0x0C}, - {0x12, 0xE7}, - {0x13, 0x00}, - {0x15, 0x00}, - {0x16, 0x00}, -#if defined(PREFER_NTSC) - {0x40, 0x82}, +const struct stk1160config stk1160configNTSC[256] = { + {0x000, 0x0098}, + {0x002, 0x0093}, + + {0x001, 0x0003}, + {0x003, 0x0080}, + {0x00D, 0x0000}, + {0x00F, 0x0002}, + {0x018, 0x0010}, + {0x019, 0x0000}, + {0x01A, 0x0014}, + {0x01B, 0x000E}, + {0x01C, 0x0046}, + + {0x100, 0x0033}, + {0x103, 0x0000}, + {0x104, 0x0000}, + {0x105, 0x0000}, + {0x106, 0x0000}, + +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +/* + * RESOLUTION 640x480 +*/ +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + {0x110, 0x0008}, + {0x111, 0x0000}, + {0x112, 0x0003}, + {0x113, 0x0000}, + {0x114, 0x0508}, + {0x115, 0x0005}, + {0x116, 0x00F3}, + {0x117, 0x0000}, +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ + + {0x202, 0x000F}, + {0x203, 0x004A}, + {0x2FF, 0x0000}, + + {0xFFF, 0xFFFF} +}; +/*--------------------------------------------------------------------------*/ +const struct saa7113config { int reg; int set; } saa7113configPAL[256] = { + {0x01, 0x08}, +#if defined(ANTIALIAS) + {0x02, 0xC0}, #else - {0x40, 0x02}, -#endif /* ! PREFER_NTSC*/ - {0x41, 0xFF}, - {0x42, 0xFF}, - {0x43, 0xFF}, - {0x44, 0xFF}, - {0x45, 0xFF}, - {0x46, 0xFF}, - {0x47, 0xFF}, - {0x48, 0xFF}, - {0x49, 0xFF}, - {0x4A, 0xFF}, - {0x4B, 0xFF}, - {0x4C, 0xFF}, - {0x4D, 0xFF}, - {0x4E, 0xFF}, - {0x4F, 0xFF}, - {0x50, 0xFF}, - {0x51, 0xFF}, - {0x52, 0xFF}, - {0x53, 0xFF}, - {0x54, 0xFF}, - {0x55, 0xFF}, - {0x56, 0xFF}, - {0x57, 0xFF}, - {0x58, 0x40}, - {0x59, 0x54}, -#if defined(PREFER_NTSC) - {0x5A, 0x0A}, + {0x02, 0x80}, +#endif /*ANTIALIAS*/ + {0x03, 0x33}, + {0x04, 0x00}, + {0x05, 0x00}, + {0x06, 0xE9}, + {0x07, 0x0D}, + {0x08, 0x38}, + {0x09, 0x00}, + {0x0A, SAA_0A_DEFAULT}, + {0x0B, SAA_0B_DEFAULT}, + {0x0C, SAA_0C_DEFAULT}, + {0x0D, SAA_0D_DEFAULT}, + {0x0E, 0x01}, + {0x0F, 0x36}, + {0x10, 0x00}, + {0x11, 0x0C}, + {0x12, 0xE7}, + {0x13, 0x00}, + {0x15, 0x00}, + {0x16, 0x00}, + {0x40, 0x02}, + {0x41, 0xFF}, + {0x42, 0xFF}, + {0x43, 0xFF}, + {0x44, 0xFF}, + {0x45, 0xFF}, + {0x46, 0xFF}, + {0x47, 0xFF}, + {0x48, 0xFF}, + {0x49, 0xFF}, + {0x4A, 0xFF}, + {0x4B, 0xFF}, + {0x4C, 0xFF}, + {0x4D, 0xFF}, + {0x4E, 0xFF}, + {0x4F, 0xFF}, + {0x50, 0xFF}, + {0x51, 0xFF}, + {0x52, 0xFF}, + {0x53, 0xFF}, + {0x54, 0xFF}, + {0x55, 0xFF}, + {0x56, 0xFF}, + {0x57, 0xFF}, + {0x58, 0x40}, + {0x59, 0x54}, + {0x5A, 0x07}, + {0x5B, 0x83}, + + {0xFF, 0xFF} +}; +/*--------------------------------------------------------------------------*/ +const struct saa7113config saa7113configNTSC[256] = { + {0x01, 0x08}, +#if defined(ANTIALIAS) + {0x02, 0xC0}, #else - {0x5A, 0x07}, -#endif /* ! PREFER_NTSC*/ - {0x5B, 0x83}, - {0xFF, 0xFF} - }; + {0x02, 0x80}, +#endif /*ANTIALIAS*/ + {0x03, 0x33}, + {0x04, 0x00}, + {0x05, 0x00}, + {0x06, 0xE9}, + {0x07, 0x0D}, + {0x08, 0x78}, + {0x09, 0x00}, + {0x0A, SAA_0A_DEFAULT}, + {0x0B, SAA_0B_DEFAULT}, + {0x0C, SAA_0C_DEFAULT}, + {0x0D, SAA_0D_DEFAULT}, + {0x0E, 0x01}, + {0x0F, 0x36}, + {0x10, 0x00}, + {0x11, 0x0C}, + {0x12, 0xE7}, + {0x13, 0x00}, + {0x15, 0x00}, + {0x16, 0x00}, + {0x40, 0x82}, + {0x41, 0xFF}, + {0x42, 0xFF}, + {0x43, 0xFF}, + {0x44, 0xFF}, + {0x45, 0xFF}, + {0x46, 0xFF}, + {0x47, 0xFF}, + {0x48, 0xFF}, + {0x49, 0xFF}, + {0x4A, 0xFF}, + {0x4B, 0xFF}, + {0x4C, 0xFF}, + {0x4D, 0xFF}, + {0x4E, 0xFF}, + {0x4F, 0xFF}, + {0x50, 0xFF}, + {0x51, 0xFF}, + {0x52, 0xFF}, + {0x53, 0xFF}, + {0x54, 0xFF}, + {0x55, 0xFF}, + {0x56, 0xFF}, + {0x57, 0xFF}, + {0x58, 0x40}, + {0x59, 0x54}, + {0x5A, 0x0A}, + {0x5B, 0x83}, + + {0xFF, 0xFF} +}; /*--------------------------------------------------------------------------*/ /****************************************************************************/ @@ -213,15 +297,22 @@ return 0; } /****************************************************************************/ int -setup_stk(struct usb_device *p) +setup_stk(struct usb_device *p, bool ntsc) { int i0; i0 = 0; -while (0xFFF != stk1160config[i0].reg) { - SET(p, stk1160config[i0].reg, stk1160config[i0].set); - i0++; +if (true == ntsc) { + while (0xFFF != stk1160configNTSC[i0].reg) { + SET(p, stk1160configNTSC[i0].reg, stk1160configNTSC[i0].set); + i0++; + } +} else { + while (0xFFF != stk1160configPAL[i0].reg) { + SET(p, stk1160configPAL[i0].reg, stk1160configPAL[i0].set); + i0++; } +} write_300(p); @@ -229,19 +320,24 @@ return 0; } /****************************************************************************/ int -setup_saa(struct usb_device *p) +setup_saa(struct usb_device *p, bool ntsc) { int i0, ir; - -set2to78(p); - - i0 = 0; -while (0xFF != saa7113config[i0].reg) { - ir = write_saa(p, saa7113config[i0].reg, saa7113config[i0].set); - i0++; +if (true == ntsc) { + while (0xFF != saa7113configNTSC[i0].reg) { + ir = write_saa(p, saa7113configNTSC[i0].reg, \ + saa7113configNTSC[i0].set); + i0++; + } +} else { + while (0xFF != saa7113configPAL[i0].reg) { + ir = write_saa(p, saa7113configPAL[i0].reg, \ + saa7113configPAL[i0].set); + i0++; } +} return 0; } /****************************************************************************/ @@ -353,24 +449,46 @@ return 0; */ /*--------------------------------------------------------------------------*/ int -check_saa(struct usb_device *p) +check_saa(struct usb_device *p, bool ntsc) { int i0, ir, rc; -i0 = 0; +i0 = 0; rc = 0; -while (0xFF != saa7113config[i0].reg) { - if (0x0F == saa7113config[i0].reg) { - i0++; continue; +if (true == ntsc) { + while (0xFF != saa7113configNTSC[i0].reg) { + if (0x0F == saa7113configNTSC[i0].reg) { + i0++; + continue; + } + + ir = read_saa(p, saa7113configNTSC[i0].reg); + if (ir != saa7113configNTSC[i0].set) { + SAY("SAA register 0x%02X has 0x%02X, " \ + "expected 0x%02X\n", \ + saa7113configNTSC[i0].reg, \ + ir, saa7113configNTSC[i0].set); + rc--; + } + i0++; } +} else { + while (0xFF != saa7113configPAL[i0].reg) { + if (0x0F == saa7113configPAL[i0].reg) { + i0++; + continue; + } - ir = read_saa(p, saa7113config[i0].reg); - if (ir != saa7113config[i0].set) { - SAY("SAA register 0x%02X has 0x%02X, expected 0x%02X\n", \ - saa7113config[i0].reg, ir, saa7113config[i0].set); - rc--; + ir = read_saa(p, saa7113configPAL[i0].reg); + if (ir != saa7113configPAL[i0].set) { + SAY("SAA register 0x%02X has 0x%02X, " \ + "expected 0x%02X\n", \ + saa7113configPAL[i0].reg, \ + ir, saa7113configPAL[i0].set); + rc--; + } + i0++; } - i0++; } if (-8 > rc) return rc; @@ -393,29 +511,44 @@ else int ready_saa(struct usb_device *p) { -int j, rc; -static int max = 10; - +int j, rc, rate; +const int max = 5, marktime = PATIENCE/5; +/*--------------------------------------------------------------------------*/ +/* + * RETURNS 0 FOR INTERLACED 50 Hz + * 1 FOR NON-INTERLACED 50 Hz + * 2 FOR INTERLACED 60 Hz + * 3 FOR NON-INTERLACED 60 Hz +*/ +/*--------------------------------------------------------------------------*/ j = 0; while (max > j) { rc = read_saa(p, 0x1F); if (0 <= rc) { - if ((1 == (0x01 & rc))&&(0 == (0x40 & rc))) + if (0 == (0x40 & rc)) + break; + if (1 == (0x01 & rc)) break; } - msleep(100); j++; + msleep(marktime); + j++; } if (max == j) return -1; else { - if (0x20 & rc) + if (0x20 & rc) { + rate = 2; JOT(8, "hardware detects 60 Hz\n"); - else + } else { + rate = 0; JOT(8, "hardware detects 50 Hz\n"); + } if (0x80 & rc) JOT(8, "hardware detects interlacing\n"); - else + else { + rate++; JOT(8, "hardware detects no interlacing\n"); + } } return 0; } @@ -424,45 +557,78 @@ return 0; /* * NOTE: THE FOLLOWING ARE NOT CHECKED: * REGISTERS 0x000, 0x002: FUNCTIONALITY IS NOT KNOWN - * REGISTER 0x100: ACCEPT ALSO (0x80 | stk1160config[.].set) + * REGISTER 0x100: ACCEPT ALSO (0x80 | stk1160config....[.].set) */ /*--------------------------------------------------------------------------*/ int -check_stk(struct usb_device *p) +check_stk(struct usb_device *p, bool ntsc) { int i0, ir; -i0 = 0; -while (0xFFF != stk1160config[i0].reg) { - if (0x000 == stk1160config[i0].reg) { - i0++; continue; - } - if (0x002 == stk1160config[i0].reg) { - i0++; continue; - } - - ir = read_stk(p, stk1160config[i0].reg); - if (0x100 == stk1160config[i0].reg) { - if ((ir != (0xFF & stk1160config[i0].set)) && \ - (ir != (0x80 | (0xFF & stk1160config[i0].set))) && \ - (0xFFFF != stk1160config[i0].set)) { - SAY("STK register 0x%03X has 0x%02X, " \ - "expected 0x%02X\n", \ - stk1160config[i0].reg, ir, \ - stk1160config[i0].set); +i0 = 0; +if (true == ntsc) { + while (0xFFF != stk1160configNTSC[i0].reg) { + if (0x000 == stk1160configNTSC[i0].reg) { + i0++; continue; + } + if (0x002 == stk1160configNTSC[i0].reg) { + i0++; continue; + } + ir = read_stk(p, stk1160configNTSC[i0].reg); + if (0x100 == stk1160configNTSC[i0].reg) { + if ((ir != (0xFF & stk1160configNTSC[i0].set)) && \ + (ir != (0x80 | (0xFF & \ + stk1160configNTSC[i0].set))) && \ + (0xFFFF != \ + stk1160configNTSC[i0].set)) { + SAY("STK register 0x%03X has 0x%02X, " \ + "expected 0x%02X\n", \ + stk1160configNTSC[i0].reg, \ + ir, stk1160configNTSC[i0].set); + } + i0++; continue; } - i0++; continue; + if ((ir != (0xFF & stk1160configNTSC[i0].set)) && \ + (0xFFFF != stk1160configNTSC[i0].set)) { + SAY("STK register 0x%03X has 0x%02X, " \ + "expected 0x%02X\n", \ + stk1160configNTSC[i0].reg, \ + ir, stk1160configNTSC[i0].set); } - - if ((ir != (0xFF & stk1160config[i0].set)) && \ - (0xFFFF != stk1160config[i0].set)) { - SAY("STK register 0x%03X has 0x%02X, " \ - "expected 0x%02X\n", \ - stk1160config[i0].reg, ir, \ - stk1160config[i0].set); + i0++; + } +} else { + while (0xFFF != stk1160configPAL[i0].reg) { + if (0x000 == stk1160configPAL[i0].reg) { + i0++; continue; + } + if (0x002 == stk1160configPAL[i0].reg) { + i0++; continue; + } + ir = read_stk(p, stk1160configPAL[i0].reg); + if (0x100 == stk1160configPAL[i0].reg) { + if ((ir != (0xFF & stk1160configPAL[i0].set)) && \ + (ir != (0x80 | (0xFF & \ + stk1160configPAL[i0].set))) && \ + (0xFFFF != \ + stk1160configPAL[i0].set)) { + SAY("STK register 0x%03X has 0x%02X, " \ + "expected 0x%02X\n", \ + stk1160configPAL[i0].reg, \ + ir, stk1160configPAL[i0].set); + } + i0++; continue; + } + if ((ir != (0xFF & stk1160configPAL[i0].set)) && \ + (0xFFFF != stk1160configPAL[i0].set)) { + SAY("STK register 0x%03X has 0x%02X, " \ + "expected 0x%02X\n", \ + stk1160configPAL[i0].reg, \ + ir, stk1160configPAL[i0].set); } - i0++; + i0++; } +} return 0; } /****************************************************************************/ @@ -489,8 +655,8 @@ igot = 0; GET(p, reg0, &igot); return igot; } -/*****************************************************************************/ -/*---------------------------------------------------------------------------*/ +/****************************************************************************/ +/*--------------------------------------------------------------------------*/ /* * HARDWARE USERSPACE INPUT NUMBER PHYSICAL INPUT DRIVER input VALUE * @@ -511,81 +677,98 @@ return igot; int select_input(struct usb_device *p, int input, int mode) { +int ir; stop_100(p); - -msleep(20); switch (input) { case 0: case 1: { - SET(p, 0x0000, 0x0098); break; + if (0 != write_saa(p, 0x02, 0x80)) { + SAY("ERROR: failed to set SAA register 0x02 for input %i\n", \ + input); + } + SET(p, 0x0000, 0x0098); + SET(p, 0x0002, 0x0078); + break; } case 2: { - SET(p, 0x0000, 0x0090); break; + if (0 != write_saa(p, 0x02, 0x80)) { + SAY("ERROR: failed to set SAA register 0x02 for input %i\n", \ + input); + } + SET(p, 0x0000, 0x0090); + SET(p, 0x0002, 0x0078); + break; } case 3: { - SET(p, 0x0000, 0x0088); break; + if (0 != write_saa(p, 0x02, 0x80)) { + SAY("ERROR: failed to set SAA register 0x02 for input %i\n", \ + input); + } + SET(p, 0x0000, 0x0088); + SET(p, 0x0002, 0x0078); + break; } case 4: { - SET(p, 0x0000, 0x0080); break; + if (0 != write_saa(p, 0x02, 0x80)) { + SAY("ERROR: failed to set SAA register 0x02 for input %i\n", \ + input); + } + SET(p, 0x0000, 0x0080); + SET(p, 0x0002, 0x0078); + break; } case 5: { if (9 != mode) mode = 7; switch (mode) { - case 7: - { + case 7: { if (0 != write_saa(p, 0x02, 0x87)) { - SAY("ERROR: failed to set SAA " \ - "register 0x02 for input " \ - "%i\n", input); + SAY("ERROR: failed to set SAA register 0x02 " \ + "for input %i\n", input); } if (0 != write_saa(p, 0x05, 0xFF)) { - SAY("ERROR: failed to set SAA " \ - "register 0x05 for input " \ - "%i\n", input); + SAY("ERROR: failed to set SAA register 0x05 " \ + "for input %i\n", input); } break; } - case 9: - { + case 9: { if (0 != write_saa(p, 0x02, 0x89)) { - SAY("ERROR: failed to set SAA " \ - "register 0x02 for input " \ - "%i\n", input); + SAY("ERROR: failed to set SAA register 0x02 " \ + "for input %i\n", input); } if (0 != write_saa(p, 0x05, 0x00)) { - SAY("ERROR: failed to set SAA " \ - "register 0x05 for input " \ - "%i\n", input); + SAY("ERROR: failed to set SAA register 0x05 " \ + "for input %i\n", input); } - break; + break; } - default: - { + default: { SAY("MISTAKE: bad mode: %i\n", mode); return -1; - } + } } if (0 != write_saa(p, 0x04, 0x00)) { - SAY("ERROR: failed to set SAA register 0x04 " \ - "for input %i\n", input); + SAY("ERROR: failed to set SAA register 0x04 for input %i\n", \ + input); } if (0 != write_saa(p, 0x09, 0x80)) { - SAY("ERROR: failed to set SAA register 0x09 " \ - "for input %i\n", input); + SAY("ERROR: failed to set SAA register 0x09 for input %i\n", \ + input); } + SET(p, 0x0002, 0x0093); break; } -default: - { +default: { SAY("ERROR: bad input: %i\n", input); return -1; } } -msleep(20); -SET(p, 0x0002, 0x0093); -msleep(20); +ir = read_stk(p, 0x00); +JOT(8, "STK register 0x00 has 0x%02X\n", ir); +ir = read_saa(p, 0x02); +JOT(8, "SAA register 0x02 has 0x%02X\n", ir); start_100(p); @@ -618,13 +801,23 @@ return 0; int start_100(struct usb_device *p) { -__u16 get0; -__u8 igot; - -GET(p, 0x0100, &igot); get0 = igot; -msleep(0x1f4); +__u16 get116, get117, get0; +__u8 igot116, igot117, igot; + +GET(p, 0x0116, &igot116); +get116 = igot116; +GET(p, 0x0117, &igot117); +get117 = igot117; +SET(p, 0x0116, 0x0000); +SET(p, 0x0117, 0x0000); + +GET(p, 0x0100, &igot); +get0 = igot; SET(p, 0x0100, (0x80 | get0)); -msleep(0x1f4); + +SET(p, 0x0116, get116); +SET(p, 0x0117, get117); + return 0; } /****************************************************************************/ @@ -634,10 +827,9 @@ stop_100(struct usb_device *p) __u16 get0; __u8 igot; -GET(p, 0x0100, &igot); get0 = igot; -msleep(0x1f4); +GET(p, 0x0100, &igot); +get0 = igot; SET(p, 0x0100, (0x7F & get0)); -msleep(0x1f4); return 0; } /****************************************************************************/ @@ -651,7 +843,7 @@ wait_i2c(struct usb_device *p) { __u16 get0; __u8 igot; -const int max = 4; +const int max = 2; int k; for (k = 0; k < max; k++) { @@ -662,7 +854,7 @@ for (k = 0; k < max; k++) { return 0; } case 0x00: { - msleep(10); + msleep(20); continue; } default: { @@ -718,27 +910,14 @@ case 0x204: case 0x205: case 0x350: case 0x351: { - if (0 != igot) { + if (0 != (0xFF & igot)) { JOT(8, "unexpected 0x%02X for STK register 0x%03X\n", \ igot, index); } break; } -case 0x114: -case 0x116: { - if ((0xFF & value) != igot) { - JOT(8, "unexpected 0x%02X != 0x%02X " \ - "for STK register 0x%03X\n", \ - igot, value, index); - } -break; -} -case 0x200: { - if (0 == igot) - break; -} default: { - if (value != igot) { + if ((0xFF & value) != (0xFF & igot)) { JOT(8, "unexpected 0x%02X != 0x%02X " \ "for STK register 0x%03X\n", \ igot, value, index); @@ -988,29 +1167,3 @@ if (0 > igot) return igot; } /*****************************************************************************/ -int -set2to78(struct usb_device *p) -{ -int ir; - -msleep(20); -ir = regset(p, 0x0002, 0x0078); -if (0 > ir) - SAY("ERROR: failed to set register 0x0002 to 0x0078\n"); -msleep(20); -return ir; -} -/*****************************************************************************/ -int -set2to93(struct usb_device *p) -{ -int ir; - -msleep(20); -ir = regset(p, 0x0002, 0x0093); -if (0 > ir) - SAY("ERROR: failed to set register 0x0002 to 0x0078\n"); -msleep(20); -return ir; -} -/*****************************************************************************/ diff --git a/drivers/staging/easycap/easycap_main.c b/drivers/staging/easycap/easycap_main.c index ff6addfa15de..b522c6eb65f6 100644 --- a/drivers/staging/easycap/easycap_main.c +++ b/drivers/staging/easycap/easycap_main.c @@ -30,6 +30,7 @@ #include "easycap.h" #include "easycap_standard.h" +#include "easycap_ioctl.h" int debug; module_param(debug, int, S_IRUGO | S_IWUSR); @@ -162,9 +163,8 @@ struct usb_interface *pusb_interface; #else struct video_device *pvideo_device; #endif /*EASYCAP_IS_VIDEODEV_CLIENT*/ -struct usb_device *p; struct easycap *peasycap; -int i, k, m, rc; +int rc; JOT(4, "\n"); SAY("==========OPEN=========\n"); @@ -197,19 +197,7 @@ if ((struct easycap *)NULL == peasycap) { return -EFAULT; } file->private_data = peasycap; -/*---------------------------------------------------------------------------*/ -/* - * INITIALIZATION - */ -/*---------------------------------------------------------------------------*/ -JOM(4, "starting initialization\n"); - -for (k = 0; k < FRAME_BUFFER_MANY; k++) { - for (m = 0; m < FRAME_BUFFER_SIZE/PAGE_SIZE; m++) - memset(peasycap->frame_buffer[k][m].pgo, 0, PAGE_SIZE); -} -p = peasycap->pusb_device; -if ((struct usb_device *)NULL == p) { +if (NULL == peasycap->pusb_device) { SAM("ERROR: peasycap->pusb_device is NULL\n"); return -EFAULT; } else { @@ -221,121 +209,398 @@ if (0 == rc) JOM(8, "wakeup_device() OK\n"); else { SAM("ERROR: wakeup_device() returned %i\n", rc); + if (-ENODEV == rc) + SAM("ERROR: wakeup_device() returned -ENODEV\n"); + else + SAM("ERROR: wakeup_device() returned %i\n", rc); + return rc; +} +peasycap->input = 0; +rc = reset(peasycap); +if (0 != rc) { + SAM("ERROR: reset() returned %i\n", rc); return -EFAULT; } -rc = setup_stk(p); peasycap->input = 0; +return 0; +} +/*****************************************************************************/ +/*---------------------------------------------------------------------------*/ +/* + * RESET THE HARDWARE TO ITS REFERENCE STATE. + * + * THIS ROUTINE MAY BE CALLED REPEATEDLY IF easycap_complete() DETECTS + * A BAD VIDEO FRAME SIZE. +*/ +/*---------------------------------------------------------------------------*/ +int +reset(struct easycap *peasycap) +{ +struct easycap_standard const *peasycap_standard; +int i, rc, input, rate; +bool ntsc, other; + +if ((struct easycap *)NULL == peasycap) { + SAY("ERROR: peasycap is NULL\n"); + return -EFAULT; +} +input = peasycap->input; + +/*---------------------------------------------------------------------------*/ +/* + * IF THE SAA7113H HAS ALREADY ACQUIRED LOCK, USE ITS HARDWARE-DETECTED + * FIELD FREQUENCY TO DISTINGUISH NTSC FROM PAL. THIS IS ESSENTIAL FOR + * gstreamer AND OTHER USERSPACE PROGRAMS WHICH MAY NOT ATTEMPT TO INITIATE + * A SWITCH BETWEEN PAL AND NTSC. + * + * FUNCTION ready_saa() MAY REQUIRE A SUBSTANTIAL FRACTION OF A SECOND TO + * COMPLETE, SO SHOULD NOT BE INVOKED WITHOUT GOOD REASON. +*/ +/*---------------------------------------------------------------------------*/ +other = false; +if (true == peasycap->ntsc) + JOM(8, "true=peasycap->ntsc\n"); +else + JOM(8, "false=peasycap->ntsc\n"); +rate = ready_saa(peasycap->pusb_device); +if (0 > rate) { + JOM(8, "not ready to capture after %i ms ...\n", PATIENCE); + if (true == peasycap->ntsc) { + JOM(8, "... trying PAL ...\n"); ntsc = false; + } else { + JOM(8, "... trying NTSC ...\n"); ntsc = true; +} +rc = setup_stk(peasycap->pusb_device, ntsc); if (0 == rc) - JOM(8, "setup_stk() OK\n"); + JOM(4, "setup_stk() OK\n"); else { SAM("ERROR: setup_stk() returned %i\n", rc); return -EFAULT; } -rc = setup_saa(p); +rc = setup_saa(peasycap->pusb_device, ntsc); if (0 == rc) - JOM(8, "setup_saa() OK\n"); + JOM(4, "setup_saa() OK\n"); else { SAM("ERROR: setup_saa() returned %i\n", rc); return -EFAULT; } -rc = check_saa(p); -if (0 == rc) - JOM(8, "check_saa() OK\n"); -else if (-8 < rc) - SAM("check_saa() returned %i\n", rc); -else { - SAM("ERROR: check_saa() returned %i\n", rc); - return -EFAULT; +rate = ready_saa(peasycap->pusb_device); +if (0 > rate) { + JOM(8, "not ready to capture after %i ms ...\n", PATIENCE); + JOM(8, "... saa register 0x1F has 0x%02X\n", \ + read_saa(peasycap->pusb_device, 0x1F)); + ntsc = peasycap->ntsc; + } else { + JOM(8, "... success at second try: %i=rate\n", rate); + ntsc = (0 < (rate/2)) ? true : false ; + other = true; + } +} else { + JOM(8, "... success at first try: %i=rate\n", rate); + ntsc = (0 < rate/2) ? true : false ; } -peasycap->standard_offset = -1; +if (true == ntsc) + JOM(8, "true=ntsc\n"); +else + JOM(8, "false=ntsc\n"); /*---------------------------------------------------------------------------*/ -#if defined(PREFER_NTSC) -rc = adjust_standard(peasycap, V4L2_STD_NTSC_M); +rc = setup_stk(peasycap->pusb_device, ntsc); if (0 == rc) - JOM(8, "adjust_standard(.,NTSC_M) OK\n"); + JOM(4, "setup_stk() OK\n"); else { - SAM("ERROR: adjust_standard(.,NTSC_M) returned %i\n", rc); + SAM("ERROR: setup_stk() returned %i\n", rc); return -EFAULT; } -rc = adjust_format(peasycap, 640, 480, V4L2_PIX_FMT_UYVY, V4L2_FIELD_NONE, \ - false); -if (0 <= rc) - JOM(8, "adjust_format(.,640,480,UYVY) OK\n"); +rc = setup_saa(peasycap->pusb_device, ntsc); +if (0 == rc) + JOM(4, "setup_saa() OK\n"); else { - SAM("ERROR: adjust_format(.,640,480,UYVY) returned %i\n", rc); + SAM("ERROR: setup_saa() returned %i\n", rc); return -EFAULT; } -#else +for (i = 0; i < 180; i++) + peasycap->merit[i] = 0; +peasycap->video_eof = 0; +peasycap->audio_eof = 0; +do_gettimeofday(&peasycap->timeval7); +/*---------------------------------------------------------------------------*/ +/* + * RESTORE INPUT AND FORCE REFRESH OF STANDARD, FORMAT, ETC. + * + * WHILE THIS PROCEDURE IS IN PROGRESS, SOME IOCTL COMMANDS WILL RETURN -EBUSY. +*/ +/*---------------------------------------------------------------------------*/ +peasycap->input = -8192; +peasycap->standard_offset = -8192; +if (true == other) { + peasycap_standard = &easycap_standard[0]; + while (0xFFFF != peasycap_standard->mask) { + if (true == ntsc) { + if (NTSC_M == \ + peasycap_standard->v4l2_standard.index) { + peasycap->inputset[input].standard_offset = \ + peasycap_standard - \ + &easycap_standard[0]; + break; + } + } else { + if (PAL_BGHIN == \ + peasycap_standard->v4l2_standard.index) { + peasycap->inputset[input].standard_offset = \ + peasycap_standard - + &easycap_standard[0]; + break; + } + } + peasycap_standard++; + } + if (0xFFFF == peasycap_standard->mask) { + SAM("ERROR: standard not found\n"); + return -EINVAL; + } +JOM(8, "%i=peasycap->inputset[%i].standard_offset\n", \ + peasycap->inputset[input].standard_offset, input); +} +peasycap->format_offset = -8192; +peasycap->brightness = -8192; +peasycap->contrast = -8192; +peasycap->saturation = -8192; +peasycap->hue = -8192; + +rc = newinput(peasycap, input); -rc = adjust_standard(peasycap, \ - (V4L2_STD_PAL_B | V4L2_STD_PAL_G | V4L2_STD_PAL_H | \ - V4L2_STD_PAL_I | V4L2_STD_PAL_N)); if (0 == rc) - JOM(8, "adjust_standard(.,PAL_BGHIN) OK\n"); + JOM(4, "restored input, standard and format\n"); else { - SAM("ERROR: adjust_standard(.,PAL_BGHIN) returned %i\n", rc); + SAM("ERROR: newinput(.,%i) returned %i\n", rc, input); return -EFAULT; } -rc = adjust_format(peasycap, 640, 480, V4L2_PIX_FMT_UYVY, V4L2_FIELD_NONE, \ - false); -if (0 <= rc) - JOM(8, "adjust_format(.,640,480,uyvy,false) OK\n"); -else { - SAM("ERROR: adjust_format(.,640,480,uyvy,false) returned %i\n", rc); +if (true == peasycap->ntsc) + JOM(8, "true=peasycap->ntsc\n"); +else + JOM(8, "false=peasycap->ntsc\n"); + +if (0 > peasycap->input) { + SAM("MISTAKE: %i=peasycap->input\n", peasycap->input); + return -ENOENT; +} +if (0 > peasycap->standard_offset) { + SAM("MISTAKE: %i=peasycap->standard_offset\n", \ + peasycap->standard_offset); + return -ENOENT; +} +if (0 > peasycap->format_offset) { + SAM("MISTAKE: %i=peasycap->format_offset\n", \ + peasycap->format_offset); + return -ENOENT; +} +if (0 > peasycap->brightness) { + SAM("MISTAKE: %i=peasycap->brightness\n", peasycap->brightness); + return -ENOENT; +} +if (0 > peasycap->contrast) { + SAM("MISTAKE: %i=peasycap->contrast\n", peasycap->contrast); + return -ENOENT; +} +if (0 > peasycap->saturation) { + SAM("MISTAKE: %i=peasycap->saturation\n", peasycap->saturation); + return -ENOENT; +} +if (0 > peasycap->hue) { + SAM("MISTAKE: %i=peasycap->hue\n", peasycap->hue); + return -ENOENT; +} +return 0; +} +/*****************************************************************************/ +/*---------------------------------------------------------------------------*/ +/* + * IF THE REQUESTED INPUT IS THE SAME AS THE EXISTING INPUT, DO NOTHING. + * OTHERWISE: + * KILL URBS, CLEAR FIELD AND FRAME BUFFERS AND RESET THEIR + * _read AND _fill POINTERS. + * SELECT THE NEW INPUT. + * ADJUST THE STANDARD, FORMAT, BRIGHTNESS, CONTRAST, SATURATION AND HUE + * ON THE BASIS OF INFORMATION IN STRUCTURE easycap.inputset[input]. + * RESUBMIT THE URBS IF STREAMING WAS ALREADY IN PROGRESS. + * + * NOTE: + * THIS ROUTINE MAY BE CALLED FREQUENTLY BY ZONEMINDER VIA IOCTL, + * SO IT SHOULD WRITE ONLY SPARINGLY TO THE LOGFILE. +*/ +/*---------------------------------------------------------------------------*/ +int +newinput(struct easycap *peasycap, int input) +{ +int rc, k, m, mood, off; +int inputnow, video_idlenow, audio_idlenow; +bool resubmit; + +if (NULL == peasycap) { + SAY("ERROR: peasycap is NULL\n"); return -EFAULT; } +JOM(8, "%i=input sought\n", input); -#endif /* !PREFER_NTSC*/ +if ((0 > input) &&(INPUT_MANY <= input)) + return -ENOENT; +inputnow = peasycap->input; +if (input == inputnow) + return 0; /*---------------------------------------------------------------------------*/ -rc = adjust_brightness(peasycap, -8192); -if (0 != rc) { - SAM("ERROR: adjust_brightness(default) returned %i\n", rc); - return -EFAULT; +/* + * IF STREAMING IS IN PROGRESS THE URBS ARE KILLED AT THIS + * STAGE AND WILL BE RESUBMITTED PRIOR TO EXIT FROM THE ROUTINE. + * IF NO STREAMING IS IN PROGRESS NO URBS WILL BE SUBMITTED BY THE + * ROUTINE. +*/ +/*---------------------------------------------------------------------------*/ +video_idlenow = peasycap->video_idle; +audio_idlenow = peasycap->audio_idle; + +peasycap->video_idle = 1; +peasycap->audio_idle = 1; +if (peasycap->video_isoc_streaming) { + resubmit = true; + kill_video_urbs(peasycap); +} else + resubmit = false; +/*---------------------------------------------------------------------------*/ +if (NULL == peasycap->pusb_device) { + SAM("ERROR: peasycap->pusb_device is NULL\n"); + return -ENODEV; } -rc = adjust_contrast(peasycap, -8192); +rc = usb_set_interface(peasycap->pusb_device, \ + peasycap->video_interface, \ + peasycap->video_altsetting_off); if (0 != rc) { - SAM("ERROR: adjust_contrast(default) returned %i\n", rc); + SAM("ERROR: usb_set_interface() returned %i\n", rc); return -EFAULT; } -rc = adjust_saturation(peasycap, -8192); +rc = stop_100(peasycap->pusb_device); if (0 != rc) { - SAM("ERROR: adjust_saturation(default) returned %i\n", rc); + SAM("ERROR: stop_100() returned %i\n", rc); return -EFAULT; } -rc = adjust_hue(peasycap, -8192); -if (0 != rc) { - SAM("ERROR: adjust_hue(default) returned %i\n", rc); - return -EFAULT; +for (k = 0; k < FIELD_BUFFER_MANY; k++) { + for (m = 0; m < FIELD_BUFFER_SIZE/PAGE_SIZE; m++) + memset(peasycap->field_buffer[k][m].pgo, 0, PAGE_SIZE); +} +for (k = 0; k < FRAME_BUFFER_MANY; k++) { + for (m = 0; m < FRAME_BUFFER_SIZE/PAGE_SIZE; m++) + memset(peasycap->frame_buffer[k][m].pgo, 0, PAGE_SIZE); +} +peasycap->field_page = 0; +peasycap->field_read = 0; +peasycap->field_fill = 0; + +peasycap->frame_read = 0; +peasycap->frame_fill = 0; +for (k = 0; k < peasycap->input; k++) { + (peasycap->frame_fill)++; + if (peasycap->frame_buffer_many <= peasycap->frame_fill) + peasycap->frame_fill = 0; } +peasycap->input = input; +select_input(peasycap->pusb_device, peasycap->input, 9); /*---------------------------------------------------------------------------*/ -rc = usb_set_interface(peasycap->pusb_device, peasycap->video_interface, \ - peasycap->video_altsetting_on); -if (0 == rc) - JOM(8, "usb_set_interface(.,%i,%i) OK\n", peasycap->video_interface, \ - peasycap->video_altsetting_on); -else { +if (input == peasycap->inputset[input].input) { + off = peasycap->inputset[input].standard_offset; + if (off != peasycap->standard_offset) { + rc = adjust_standard(peasycap, \ + easycap_standard[off].v4l2_standard.id); + if (0 != rc) { + SAM("ERROR: adjust_standard() returned %i\n", rc); + return -EFAULT; + } + JOM(8, "%i=peasycap->standard_offset\n", \ + peasycap->standard_offset); + } else { + JOM(8, "%i=peasycap->standard_offset unchanged\n", \ + peasycap->standard_offset); + } + off = peasycap->inputset[input].format_offset; + if (off != peasycap->format_offset) { + rc = adjust_format(peasycap, \ + easycap_format[off].v4l2_format.fmt.pix.width, \ + easycap_format[off].v4l2_format.fmt.pix.height, \ + easycap_format[off].v4l2_format.fmt.pix.pixelformat, \ + easycap_format[off].v4l2_format.fmt.pix.field, false); + if (0 > rc) { + SAM("ERROR: adjust_format() returned %i\n", rc); + return -EFAULT; + } + JOM(8, "%i=peasycap->format_offset\n", peasycap->format_offset); + } else { + JOM(8, "%i=peasycap->format_offset unchanged\n", \ + peasycap->format_offset); + } + mood = peasycap->inputset[input].brightness; + if (mood != peasycap->brightness) { + rc = adjust_brightness(peasycap, mood); + if (0 != rc) { + SAM("ERROR: adjust_brightness returned %i\n", rc); + return -EFAULT; + } + JOM(8, "%i=peasycap->brightness\n", peasycap->brightness); + } + mood = peasycap->inputset[input].contrast; + if (mood != peasycap->contrast) { + rc = adjust_contrast(peasycap, mood); + if (0 != rc) { + SAM("ERROR: adjust_contrast returned %i\n", rc); + return -EFAULT; + } + JOM(8, "%i=peasycap->contrast\n", peasycap->contrast); + } + mood = peasycap->inputset[input].saturation; + if (mood != peasycap->saturation) { + rc = adjust_saturation(peasycap, mood); + if (0 != rc) { + SAM("ERROR: adjust_saturation returned %i\n", rc); + return -EFAULT; + } + JOM(8, "%i=peasycap->saturation\n", peasycap->saturation); + } + mood = peasycap->inputset[input].hue; + if (mood != peasycap->hue) { + rc = adjust_hue(peasycap, mood); + if (0 != rc) { + SAM("ERROR: adjust_hue returned %i\n", rc); + return -EFAULT; + } + JOM(8, "%i=peasycap->hue\n", peasycap->hue); + } +} else { + SAM("MISTAKE: easycap.inputset[%i] unpopulated\n", input); + return -ENOENT; +} +/*---------------------------------------------------------------------------*/ +if ((struct usb_device *)NULL == peasycap->pusb_device) { + SAM("ERROR: peasycap->pusb_device is NULL\n"); + return -ENODEV; +} +rc = usb_set_interface(peasycap->pusb_device, + peasycap->video_interface, \ + peasycap->video_altsetting_on); +if (0 != rc) { SAM("ERROR: usb_set_interface() returned %i\n", rc); return -EFAULT; } -rc = start_100(p); -if (0 == rc) - JOM(8, "start_100() OK\n"); -else { +rc = start_100(peasycap->pusb_device); +if (0 != rc) { SAM("ERROR: start_100() returned %i\n", rc); return -EFAULT; } +if (true == resubmit) + submit_video_urbs(peasycap); + peasycap->video_isoc_sequence = VIDEO_ISOC_BUFFER_MANY - 1; -peasycap->video_idle = 0; +peasycap->video_idle = video_idlenow; +peasycap->audio_idle = audio_idlenow; peasycap->video_junk = 0; -for (i = 0; i < 180; i++) - peasycap->merit[i] = 0; -peasycap->video_eof = 0; -peasycap->audio_eof = 0; - -do_gettimeofday(&peasycap->timeval7); -JOM(4, "finished initialization\n"); return 0; } /*****************************************************************************/ @@ -864,24 +1129,44 @@ while ((peasycap->field_read == peasycap->field_fill) || \ "%i=field_read %i=field_fill\n", \ peasycap->field_read, peasycap->field_fill); - msleep(1); if (0 != (wait_event_interruptible(peasycap->wq_video, \ (peasycap->video_idle || peasycap->video_eof || \ ((peasycap->field_read != peasycap->field_fill) && \ (0 == (0xFF00 & peasycap->field_buffer\ [peasycap->field_read][0].kount)) && \ (0 == (0x00FF & peasycap->field_buffer\ - [peasycap->field_read][0].kount))))))){ + [peasycap->field_read][0].kount))))))) { SAM("aborted by signal\n"); return -EIO; } if (peasycap->video_idle) { - JOM(8, "%i=peasycap->video_idle\n", peasycap->video_idle); - return -EIO; + JOM(8, "%i=peasycap->video_idle ... returning -EAGAIN\n", \ + peasycap->video_idle); + return -EAGAIN; } if (peasycap->video_eof) { JOM(8, "%i=peasycap->video_eof\n", peasycap->video_eof); + #if defined(PERSEVERE) + if (1 == peasycap->status) { + JOM(8, "persevering ...\n"); + peasycap->video_eof = 0; + peasycap->audio_eof = 0; + if (0 != reset(peasycap)) { + JOM(8, " ... failed ... returning -EIO\n"); + peasycap->video_eof = 1; + peasycap->audio_eof = 1; + kill_video_urbs(peasycap); + return -EIO; + } + peasycap->status = 0; + JOM(8, " ... OK ... returning -EAGAIN\n"); + return -EAGAIN; + } + #endif /*PERSEVERE*/ + peasycap->video_eof = 1; + peasycap->audio_eof = 1; kill_video_urbs(peasycap); + JOM(8, "returning -EIO\n"); return -EIO; } miss++; @@ -925,24 +1210,44 @@ while ((peasycap->field_read == peasycap->field_fill) || \ JOM(8, "second wait on wq_video, " \ "%i=field_read %i=field_fill\n", \ peasycap->field_read, peasycap->field_fill); - msleep(1); if (0 != (wait_event_interruptible(peasycap->wq_video, \ (peasycap->video_idle || peasycap->video_eof || \ ((peasycap->field_read != peasycap->field_fill) && \ (0 == (0xFF00 & peasycap->field_buffer\ [peasycap->field_read][0].kount)) && \ (0 != (0x00FF & peasycap->field_buffer\ - [peasycap->field_read][0].kount))))))){ + [peasycap->field_read][0].kount))))))) { SAM("aborted by signal\n"); return -EIO; } if (peasycap->video_idle) { - JOM(8, "%i=peasycap->video_idle\n", peasycap->video_idle); - return -EIO; + JOM(8, "%i=peasycap->video_idle ... returning -EAGAIN\n", \ + peasycap->video_idle); + return -EAGAIN; } if (peasycap->video_eof) { JOM(8, "%i=peasycap->video_eof\n", peasycap->video_eof); + #if defined(PERSEVERE) + if (1 == peasycap->status) { + JOM(8, "persevering ...\n"); + peasycap->video_eof = 0; + peasycap->audio_eof = 0; + if (0 != reset(peasycap)) { + JOM(8, " ... failed ... returning -EIO\n"); + peasycap->video_eof = 1; + peasycap->audio_eof = 1; + kill_video_urbs(peasycap); + return -EIO; + } + peasycap->status = 0; + JOM(8, " ... OK ... returning -EAGAIN\n"); + return -EAGAIN; + } + #endif /*PERSEVERE*/ + peasycap->video_eof = 1; + peasycap->audio_eof = 1; kill_video_urbs(peasycap); + JOM(8, "returning -EIO\n"); return -EIO; } miss++; @@ -1001,13 +1306,15 @@ int kex, kad, mex, mad, rex, rad, rad2; int c2, c3, w2, w3, cz, wz; int rc, bytesperpixel, multiplier, much, more, over, rump, caches; __u8 mask, margin; -bool odd, isuy, decimatepixel, offerfields; +bool odd, isuy, decimatepixel, offerfields, badinput; if ((struct easycap *)NULL == peasycap) { SAY("ERROR: peasycap is NULL\n"); return -EFAULT; } +badinput = false; + JOM(8, "===== parity %i, field buffer %i --> frame buffer %i\n", \ peasycap->field_buffer[peasycap->field_read][0].kount,\ peasycap->field_read, peasycap->frame_fill); @@ -1138,6 +1445,15 @@ while (cz < wz) { if (rump) caches++; + if (true == badinput) { + JOM(8, "ERROR: 0x%02X=->field_buffer" \ + "[%i][%i].input, " \ + "0x%02X=(0x08|->input)\n", \ + peasycap->field_buffer\ + [kex][mex].input, kex, mex, \ + (0x08|peasycap->input)); + } + rc = redaub(peasycap, pad, pex, much, more, \ mask, margin, isuy); if (0 > rc) { @@ -1156,6 +1472,9 @@ while (cz < wz) { mex++; pex = peasycap->field_buffer[kex][mex].pgo; rex = PAGE_SIZE; + if (peasycap->field_buffer[kex][mex].input != \ + (0x08|peasycap->input)) + badinput = true; } pad += more; rad -= more; @@ -1254,6 +1573,15 @@ while (cz < wz) { if (rump) caches++; + if (true == badinput) { + JOM(8, "ERROR: 0x%02X=->field_buffer" \ + "[%i][%i].input, " \ + "0x%02X=(0x08|->input)\n", \ + peasycap->field_buffer\ + [kex][mex].input, kex, mex, \ + (0x08|peasycap->input)); + } + rc = redaub(peasycap, pad, pex, much, more, \ mask, margin, isuy); if (0 > rc) { @@ -1266,6 +1594,9 @@ while (cz < wz) { mex++; pex = peasycap->field_buffer[kex][mex].pgo; rex = PAGE_SIZE; + if (peasycap->field_buffer[kex][mex].input != \ + (0x08|peasycap->input)) + badinput = true; } pad += more; rad -= more; @@ -1292,6 +1623,16 @@ while (cz < wz) { mex++; pex = peasycap->field_buffer[kex][mex].pgo; rex = PAGE_SIZE; + if (peasycap->field_buffer[kex][mex].input != \ + (0x08|peasycap->input)) { + JOM(8, "ERROR: 0x%02X=->field_buffer"\ + "[%i][%i].input, " \ + "0x%02X=(0x08|->input)\n", \ + peasycap->field_buffer\ + [kex][mex].input, kex, mex, \ + (0x08|peasycap->input)); + badinput = true; + } } much = over; if (rex < much) @@ -2350,6 +2691,7 @@ return retcode; * 0 != (kount & 0x8000) => AT LEAST ONE URB COMPLETED WITH ERRORS * 0 != (kount & 0x4000) => BUFFER HAS TOO MUCH DATA * 0 != (kount & 0x2000) => BUFFER HAS NOT ENOUGH DATA + * 0 != (kount & 0x1000) => BUFFER HAS DATA FROM DISPARATE INPUTS * 0 != (kount & 0x0400) => RESERVED * 0 != (kount & 0x0200) => FIELD BUFFER NOT YET CHECKED * 0 != (kount & 0x0100) => BUFFER HAS TWO EXTRA BYTES - WHY? @@ -2363,7 +2705,7 @@ struct data_buffer *pfield_buffer; char errbuf[16]; int i, more, much, leap, rc, last; int videofieldamount; -unsigned int override; +unsigned int override, bad; int framestatus, framelength, frameactual, frameoffset; __u8 *pu; @@ -2389,7 +2731,7 @@ if ((((VIDEO_ISOC_BUFFER_MANY - 1) == last) && \ (0 != i)) || \ (((VIDEO_ISOC_BUFFER_MANY - 1) != last) && \ ((last + 1) != i))) { - SAM("ERROR: out-of-order urbs %i,%i ... continuing\n", last, i); + JOM(16, "ERROR: out-of-order urbs %i,%i ... continuing\n", last, i); } peasycap->video_isoc_sequence = i; @@ -2399,9 +2741,6 @@ if (peasycap->video_idle) { if (peasycap->video_isoc_streaming) { rc = usb_submit_urb(purb, GFP_ATOMIC); if (0 != rc) { - SAM("ERROR: while %i=video_idle, " \ - "usb_submit_urb() failed with rc:\n", \ - peasycap->video_idle); switch (rc) { case -ENOMEM: { SAM("ENOMEM\n"); @@ -2444,6 +2783,11 @@ if (peasycap->video_idle) { break; } } + if (-ENODEV != rc) \ + SAM("ERROR: while %i=video_idle, " \ + "usb_submit_urb() " \ + "failed with rc:\n", \ + peasycap->video_idle); } } return; @@ -2662,6 +3006,8 @@ if (purb->status) { (peasycap->field_buffer\ [peasycap->field_fill]\ [0].kount) |= 0x0100; + peasycap->video_junk += (1 + \ + VIDEO_JUNK_TOLERATE); } else (peasycap->field_buffer\ [peasycap->field_fill]\ @@ -2673,53 +3019,74 @@ if (purb->status) { [peasycap->field_fill]\ [0].kount) |= 0x2000; } - if (!(0xFF00 & peasycap->field_buffer\ + bad = 0xFF00 & peasycap->field_buffer\ [peasycap->field_fill]\ - [0].kount)) { - (peasycap->video_junk)--; - if (-16 > peasycap->video_junk) - peasycap->video_junk = -16; - peasycap->field_read = \ + [0].kount; + if (!bad) { + (peasycap->video_junk)--; + if (-VIDEO_JUNK_TOLERATE > \ + peasycap->video_junk) \ + peasycap->video_junk =\ + -VIDEO_JUNK_TOLERATE; + peasycap->field_read = \ (peasycap->\ field_fill)++; - - if (FIELD_BUFFER_MANY <= \ - peasycap->field_fill) - peasycap->field_fill = 0; - peasycap->field_page = 0; - pfield_buffer = &peasycap->\ - field_buffer\ - [peasycap->field_fill]\ - [peasycap->field_page]; - pfield_buffer->pto = \ + if (FIELD_BUFFER_MANY <= \ + peasycap->\ + field_fill) + peasycap->\ + field_fill = 0; + peasycap->field_page = 0; + pfield_buffer = &peasycap->\ + field_buffer\ + [peasycap->\ + field_fill]\ + [peasycap->\ + field_page]; + pfield_buffer->pto = \ pfield_buffer->pgo; - - JOM(8, "bumped to: %i=peasycap->" \ - "field_fill %i=parity\n", \ - peasycap->field_fill, \ - 0x00FF & pfield_buffer->kount); - JOM(8, "field buffer %i has %i " \ - "bytes fit to be read\n", \ - peasycap->field_read, \ - videofieldamount); - JOM(8, "wakeup call to wq_video, " \ - "%i=field_read %i=field_fill "\ - "%i=parity\n", \ - peasycap->field_read, \ - peasycap->field_fill, \ - 0x00FF & peasycap->\ - field_buffer[peasycap->\ - field_read][0].kount); - wake_up_interruptible(&(peasycap->\ - wq_video)); - do_gettimeofday(&peasycap->timeval7); + JOM(8, "bumped to: %i="\ + "peasycap->" \ + "field_fill %i="\ + "parity\n", \ + peasycap->field_fill, \ + 0x00FF & \ + pfield_buffer->kount); + JOM(8, "field buffer %i has "\ + "%i bytes fit to be "\ + "read\n", \ + peasycap->field_read, \ + videofieldamount); + JOM(8, "wakeup call to "\ + "wq_video, " \ + "%i=field_read "\ + "%i=field_fill "\ + "%i=parity\n", \ + peasycap->field_read, \ + peasycap->field_fill, \ + 0x00FF & peasycap->\ + field_buffer\ + [peasycap->\ + field_read][0].kount); + wake_up_interruptible\ + (&(peasycap->\ + wq_video)); + do_gettimeofday\ + (&peasycap->timeval7); } else { peasycap->video_junk++; + if (bad & 0x0010) \ + peasycap->video_junk += \ + (1 + VIDEO_JUNK_TOLERATE/2); JOM(8, "field buffer %i had %i " \ - "bytes, now discarded\n", \ + "bytes, now discarded: "\ + "0x%04X\n", \ peasycap->field_fill, \ - videofieldamount); - + videofieldamount,\ + (0xFF00 & \ + peasycap->field_buffer\ + [peasycap->field_fill][0].\ + kount)); (peasycap->field_fill)++; if (FIELD_BUFFER_MANY <= \ @@ -2746,6 +3113,8 @@ if (purb->status) { pfield_buffer->kount = 0x0000; else pfield_buffer->kount = 0x0001; + pfield_buffer->input = 0x08 | \ + (0x07 & peasycap->input); JOM(8, "end-of-field: 0x%02X=kount\n",\ 0xFF & pfield_buffer->kount); } @@ -2819,18 +3188,19 @@ if (purb->status) { /*---------------------------------------------------------------------------*/ if (VIDEO_ISOC_BUFFER_MANY <= peasycap->video_junk) { SAM("easycap driver shutting down on condition green\n"); + peasycap->status = 1; peasycap->video_eof = 1; + peasycap->video_junk = 0; + wake_up_interruptible(&peasycap->wq_video); +#if !defined(PERSEVERE) peasycap->audio_eof = 1; - peasycap->video_junk = -VIDEO_ISOC_BUFFER_MANY; - wake_up_interruptible(&(peasycap->wq_video)); - wake_up_interruptible(&(peasycap->wq_audio)); + wake_up_interruptible(&peasycap->wq_audio); +#endif /*PERSEVERE*/ return; } if (peasycap->video_isoc_streaming) { rc = usb_submit_urb(purb, GFP_ATOMIC); if (0 != rc) { - SAM("ERROR: while %i=video_idle, usb_submit_urb() failed " \ - "with rc:\n", peasycap->video_idle); switch (rc) { case -ENOMEM: { SAM("ENOMEM\n"); break; @@ -2863,6 +3233,11 @@ if (peasycap->video_isoc_streaming) { SAM("0x%08X\n", rc); break; } } + if (-ENODEV != rc) \ + SAM("ERROR: while %i=video_idle, " \ + "usb_submit_urb() " \ + "failed with rc:\n", \ + peasycap->video_idle); } } return; @@ -2910,6 +3285,9 @@ int okalt[8], isokalt; int okepn[8]; int okmps[8]; int maxpacketsize; +__u16 mask; +__s32 value; +struct easycap_format *peasycap_format; JOT(4, "\n"); peasycap = (struct easycap *)NULL; @@ -3056,13 +3434,14 @@ if (0 == bInterfaceNumber) { for (dongle_this = 0; dongle_this < DONGLE_MANY; dongle_this++) { if ((struct easycap *)NULL == peasycap_dongle[dongle_this]) { - peasycap_dongle[dongle_this] = peasycap; - JOM(8, "intf[%i]: peasycap-->easycap" \ + peasycap_dongle[dongle_this] = peasycap; + JOM(8, "intf[%i]: peasycap-->easycap" \ "_dongle[%i].peasycap\n", \ bInterfaceNumber, dongle_this); break; } } + if (DONGLE_MANY <= dongle_this) { SAM("ERROR: too many dongles\n"); return -ENOMEM; @@ -3105,7 +3484,7 @@ if (0 == bInterfaceNumber) { peasycap->offerfields = 0; /*---------------------------------------------------------------------------*/ /* - * DYNAMICALLY FILL IN THE AVAILABLE FORMATS. + * DYNAMICALLY FILL IN THE AVAILABLE FORMATS ... */ /*---------------------------------------------------------------------------*/ rc = fillin_formats(); @@ -3114,6 +3493,120 @@ if (0 == bInterfaceNumber) { return -EFAULT; } JOM(4, "%i formats available\n", rc); +/*---------------------------------------------------------------------------*/ +/* + * ... AND POPULATE easycap.inputset[] +*/ +/*---------------------------------------------------------------------------*/ + for (k = 0; k < INPUT_MANY; k++) { + peasycap->inputset[k].input_ok = 0; + peasycap->inputset[k].standard_offset_ok = 0; + peasycap->inputset[k].format_offset_ok = 0; + peasycap->inputset[k].brightness_ok = 0; + peasycap->inputset[k].contrast_ok = 0; + peasycap->inputset[k].saturation_ok = 0; + peasycap->inputset[k].hue_ok = 0; + } + if (true == peasycap->ntsc) { + i = 0; + m = 0; + mask = 0; + while (0xFFFF != easycap_standard[i].mask) { + if (NTSC_M == easycap_standard[i].\ + v4l2_standard.index) { + m++; + for (k = 0; k < INPUT_MANY; k++) { + peasycap->inputset[k].\ + standard_offset = i; + } + mask = easycap_standard[i].mask; + } + i++; + } + } else { + i = 0; + m = 0; + mask = 0; + while (0xFFFF != easycap_standard[i].mask) { + if (PAL_BGHIN == easycap_standard[i].\ + v4l2_standard.index) { + m++; + for (k = 0; k < INPUT_MANY; k++) { + peasycap->inputset[k].\ + standard_offset = i; + } + mask = easycap_standard[i].mask; + } + i++; + } + } + + if (1 != m) { + SAM("MISTAKE: easycap.inputset[].standard_offset " \ + "unpopulated, %i=m\n", m); + return -ENOENT; + } + + peasycap_format = &easycap_format[0]; + i = 0; + m = 0; + while (0 != peasycap_format->v4l2_format.fmt.pix.width) { + if (((peasycap_format->mask & 0x0F) == (mask & 0x0F)) && \ + (peasycap_format->\ + v4l2_format.fmt.pix.field == \ + V4L2_FIELD_NONE) && \ + (peasycap_format->\ + v4l2_format.fmt.pix.pixelformat == \ + V4L2_PIX_FMT_UYVY) && \ + (peasycap_format->\ + v4l2_format.fmt.pix.width == \ + 640) && \ + (peasycap_format->\ + v4l2_format.fmt.pix.height == 480)) { + m++; + for (k = 0; k < INPUT_MANY; k++) + peasycap->inputset[k].format_offset = i; + break; + } + peasycap_format++; + i++; + } + if (1 != m) { + SAM("MISTAKE: easycap.inputset[].format_offset unpopulated\n"); + return -ENOENT; + } + + i = 0; + m = 0; + while (0xFFFFFFFF != easycap_control[i].id) { + value = easycap_control[i].default_value; + if (V4L2_CID_BRIGHTNESS == easycap_control[i].id) { + m++; + for (k = 0; k < INPUT_MANY; k++) + peasycap->inputset[k].brightness = value; + } else if (V4L2_CID_CONTRAST == easycap_control[i].id) { + m++; + for (k = 0; k < INPUT_MANY; k++) + peasycap->inputset[k].contrast = value; + } else if (V4L2_CID_SATURATION == easycap_control[i].id) { + m++; + for (k = 0; k < INPUT_MANY; k++) + peasycap->inputset[k].saturation = value; + } else if (V4L2_CID_HUE == easycap_control[i].id) { + m++; + for (k = 0; k < INPUT_MANY; k++) + peasycap->inputset[k].hue = value; + } + i++; + } + if (4 != m) { + SAM("MISTAKE: easycap.inputset[].brightness,... " \ + "underpopulated\n"); + return -ENOENT; + } + for (k = 0; k < INPUT_MANY; k++) + peasycap->inputset[k].input = k; + JOM(4, "populated easycap.inputset[]\n"); JOM(4, "finished initialization\n"); } else { /*---------------------------------------------------------------------------*/ @@ -4095,15 +4588,16 @@ if (NULL == peasycap) { /*---------------------------------------------------------------------------*/ peasycap->video_eof = 1; peasycap->audio_eof = 1; -wake_up_interruptible(&peasycap->wq_video); -wake_up_interruptible(&peasycap->wq_audio); +wake_up_interruptible(&(peasycap->wq_video)); +wake_up_interruptible(&(peasycap->wq_audio)); /*---------------------------------------------------------------------------*/ switch (bInterfaceNumber) { case 0: { if ((struct list_head *)NULL != peasycap->purb_video_head) { JOM(4, "killing video urbs\n"); m = 0; - list_for_each(plist_head, (peasycap->purb_video_head)) { + list_for_each(plist_head, (peasycap->purb_video_head)) + { pdata_urb = list_entry(plist_head, \ struct data_urb, list_head); if ((struct data_urb *)NULL != pdata_urb) { @@ -4123,7 +4617,8 @@ case 2: { if ((struct list_head *)NULL != peasycap->purb_audio_head) { JOM(4, "killing audio urbs\n"); m = 0; - list_for_each(plist_head, (peasycap->purb_audio_head)) { + list_for_each(plist_head, \ + (peasycap->purb_audio_head)) { pdata_urb = list_entry(plist_head, \ struct data_urb, list_head); if ((struct data_urb *)NULL != pdata_urb) { @@ -4149,7 +4644,6 @@ default: /*--------------------------------------------------------------------------*/ switch (bInterfaceNumber) { case 0: { - #if (!defined(EASYCAP_IS_VIDEODEV_CLIENT)) if ((struct easycap *)NULL == peasycap) { SAM("ERROR: peasycap has become NULL\n"); diff --git a/drivers/staging/easycap/easycap_sound.c b/drivers/staging/easycap/easycap_sound.c index 21275973faf3..0b4b60b0a5a7 100644 --- a/drivers/staging/easycap/easycap_sound.c +++ b/drivers/staging/easycap/easycap_sound.c @@ -638,11 +638,6 @@ if ((struct usb_device *)NULL == peasycap->pusb_device) { SAM("ERROR: peasycap->pusb_device has become NULL\n"); return -EFAULT; } -rc = adjust_volume(peasycap, -8192); -if (0 != rc) { - SAM("ERROR: adjust_volume(default) returned %i\n", rc); - return -EFAULT; -} /*---------------------------------------------------------------------------*/ if ((struct usb_device *)NULL == peasycap->pusb_device) { SAM("ERROR: peasycap->pusb_device has become NULL\n"); @@ -653,26 +648,20 @@ rc = usb_set_interface(peasycap->pusb_device, peasycap->audio_interface, \ JOM(8, "usb_set_interface(.,%i,%i) returned %i\n", peasycap->audio_interface, \ peasycap->audio_altsetting_on, rc); -if ((struct usb_device *)NULL == peasycap->pusb_device) { - SAM("ERROR: peasycap->pusb_device has become NULL\n"); - return -EFAULT; -} rc = wakeup_device(peasycap->pusb_device); if (0 == rc) JOM(8, "wakeup_device() returned %i\n", rc); else - JOM(8, "easysnd open(): ERROR: wakeup_device() returned %i\n", rc); + JOM(8, "ERROR: wakeup_device() returned %i\n", rc); -if ((struct usb_device *)NULL == peasycap->pusb_device) { - SAM("ERROR: peasycap->pusb_device has become NULL\n"); - return -EFAULT; -} -submit_audio_urbs(peasycap); +peasycap->audio_eof = 0; peasycap->audio_idle = 0; peasycap->timeval1.tv_sec = 0; peasycap->timeval1.tv_usec = 0; +submit_audio_urbs(peasycap); + JOM(4, "finished initialization\n"); return 0; } @@ -764,7 +753,6 @@ while ((fragment == (peasycap->audio_fill / \ JOM(8, "returning 0 because %i=audio_eof\n", \ peasycap->audio_eof); kill_audio_urbs(peasycap); - msleep(500); return 0; } if (peasycap->audio_idle) { -- cgit v1.2.3 From 40b8d50ac98f8c8779aea7459f805e5a69fdb726 Mon Sep 17 00:00:00 2001 From: Mike Thomas Date: Sun, 7 Nov 2010 20:02:15 +0000 Subject: staging/easycap: Implement interlaced modes and reduced framerates Interlaced modes are requested by tvtime. Reduced framerates are preferred by some userspace programs, e.g. astronomy applications. Signed-off-by: Mike Thomas Signed-off-by: Greg Kroah-Hartman --- drivers/staging/easycap/easycap.h | 16 +- drivers/staging/easycap/easycap_ioctl.c | 338 +++++++++++++++++++++++++---- drivers/staging/easycap/easycap_main.c | 78 ++++--- drivers/staging/easycap/easycap_settings.c | 268 +++++++++++++++++++---- 4 files changed, 579 insertions(+), 121 deletions(-) diff --git a/drivers/staging/easycap/easycap.h b/drivers/staging/easycap/easycap.h index 20e51ddec1e1..7c4cf7a338c4 100644 --- a/drivers/staging/easycap/easycap.h +++ b/drivers/staging/easycap/easycap.h @@ -200,7 +200,17 @@ #define NTSC_M_JP 5 #define PAL_60 7 #define PAL_M 9 -#define STANDARD_MANY 10 +#define PAL_BGHIN_SLOW 10 +#define PAL_Nc_SLOW 12 +#define SECAM_SLOW 14 +#define NTSC_N_SLOW 16 +#define NTSC_N_443_SLOW 18 +#define NTSC_M_SLOW 11 +#define NTSC_443_SLOW 13 +#define NTSC_M_JP_SLOW 15 +#define PAL_60_SLOW 17 +#define PAL_M_SLOW 19 +#define STANDARD_MANY 20 /*---------------------------------------------------------------------------*/ /* * ENUMS @@ -228,7 +238,6 @@ PIXELFORMAT_MANY enum { FIELD_NONE, FIELD_INTERLACED, -FIELD_ALTERNATE, INTERLACE_MANY }; #define SETTINGS_MANY (STANDARD_MANY * \ @@ -333,6 +342,8 @@ bool ntsc; int fps; int usec; int tolerate; +int skip; +int skipped; int merit[180]; struct timeval timeval0; @@ -399,7 +410,6 @@ int frame_lock; /* Flag set to 1 by DQBUF and cleared by QBUF */ */ /*---------------------------------------------------------------------------*/ __u32 pixelformat; -__u32 field; int width; int height; int bytesperpixel; diff --git a/drivers/staging/easycap/easycap_ioctl.c b/drivers/staging/easycap/easycap_ioctl.c index 0ed37c23c7ec..3fe13851aba0 100644 --- a/drivers/staging/easycap/easycap_ioctl.c +++ b/drivers/staging/easycap/easycap_ioctl.c @@ -40,6 +40,7 @@ * peasycap->fps * peasycap->usec * peasycap->tolerate + * peasycap->skip */ /*---------------------------------------------------------------------------*/ int adjust_standard(struct easycap *peasycap, v4l2_std_id std_id) @@ -60,10 +61,18 @@ if ((struct usb_device *)NULL == peasycap->pusb_device) { } peasycap_standard = &easycap_standard[0]; while (0xFFFF != peasycap_standard->mask) { - if (std_id & peasycap_standard->v4l2_standard.id) + if (std_id == peasycap_standard->v4l2_standard.id) break; peasycap_standard++; } +if (0xFFFF == peasycap_standard->mask) { + peasycap_standard = &easycap_standard[0]; + while (0xFFFF != peasycap_standard->mask) { + if (std_id & peasycap_standard->v4l2_standard.id) + break; + peasycap_standard++; + } +} if (0xFFFF == peasycap_standard->mask) { SAM("ERROR: 0x%08X=std_id: standard not found\n", \ (unsigned int)std_id); @@ -92,10 +101,12 @@ if ((0 <= peasycap->input) && (INPUT_MANY > peasycap->input)) { peasycap->fps = peasycap_standard->v4l2_standard.frameperiod.denominator / \ peasycap_standard->v4l2_standard.frameperiod.numerator; switch (peasycap->fps) { +case 6: case 30: { peasycap->ntsc = true; break; } +case 5: case 25: { peasycap->ntsc = false; break; @@ -106,9 +117,15 @@ default: { } } JOM(8, "%i frames-per-second\n", peasycap->fps); -peasycap->usec = 1000000 / (2 * peasycap->fps); -peasycap->tolerate = 1000 * (25 / peasycap->fps); - +if (0x8000 & peasycap_standard->mask) { + peasycap->skip = 5; + peasycap->usec = 1000000 / (2 * (5 * peasycap->fps)); + peasycap->tolerate = 1000 * (25 / (5 * peasycap->fps)); +} else { + peasycap->skip = 0; + peasycap->usec = 1000000 / (2 * peasycap->fps); + peasycap->tolerate = 1000 * (25 / peasycap->fps); +} if (peasycap->video_isoc_streaming) { resubmit = true; kill_video_urbs(peasycap); @@ -311,7 +328,6 @@ return 0; * peasycap->format_offset * peasycap->inputset[peasycap->input].format_offset * peasycap->pixelformat - * peasycap->field * peasycap->height * peasycap->width * peasycap->bytesperpixel @@ -333,7 +349,7 @@ struct easycap_format *peasycap_format, *peasycap_best_format; __u16 mask; struct usb_device *p; int miss, multiplier, best, k; -char bf[5], *pc; +char bf[5], fo[32], *pc; __u32 uc; bool resubmit; @@ -351,13 +367,62 @@ if ((struct usb_device *)NULL == p) { return -EFAULT; } pc = &bf[0]; -uc = pixelformat; memcpy((void *)pc, (void *)(&uc), 4); bf[4] = 0; -mask = easycap_standard[peasycap->standard_offset].mask; +uc = pixelformat; +memcpy((void *)pc, (void *)(&uc), 4); +bf[4] = 0; +mask = 0xFF & easycap_standard[peasycap->standard_offset].mask; SAM("sought: %ix%i,%s(0x%08X),%i=field,0x%02X=std mask\n", \ width, height, pc, pixelformat, field, mask); +switch (field) { +case V4L2_FIELD_ANY: { + strcpy(&fo[0], "V4L2_FIELD_ANY "); + break; +} +case V4L2_FIELD_NONE: { + strcpy(&fo[0], "V4L2_FIELD_NONE"); + break; +} +case V4L2_FIELD_TOP: { + strcpy(&fo[0], "V4L2_FIELD_TOP"); + break; +} +case V4L2_FIELD_BOTTOM: { + strcpy(&fo[0], "V4L2_FIELD_BOTTOM"); + break; +} +case V4L2_FIELD_INTERLACED: { + strcpy(&fo[0], "V4L2_FIELD_INTERLACED"); + break; +} +case V4L2_FIELD_SEQ_TB: { + strcpy(&fo[0], "V4L2_FIELD_SEQ_TB"); + break; +} +case V4L2_FIELD_SEQ_BT: { + strcpy(&fo[0], "V4L2_FIELD_SEQ_BT"); + break; +} +case V4L2_FIELD_ALTERNATE: { + strcpy(&fo[0], "V4L2_FIELD_ALTERNATE"); + break; +} +case V4L2_FIELD_INTERLACED_TB: { + strcpy(&fo[0], "V4L2_FIELD_INTERLACED_TB"); + break; +} +case V4L2_FIELD_INTERLACED_BT: { + strcpy(&fo[0], "V4L2_FIELD_INTERLACED_BT"); + break; +} +default: { + strcpy(&fo[0], "V4L2_FIELD_... UNKNOWN "); + break; +} +} +SAM("sought: %s\n", &fo[0]); if (V4L2_FIELD_ANY == field) { - field = V4L2_FIELD_INTERLACED; - SAM("prefer: V4L2_FIELD_INTERLACED=field, was V4L2_FIELD_ANY\n"); + field = V4L2_FIELD_NONE; + SAM("prefer: V4L2_FIELD_NONE=field, was V4L2_FIELD_ANY\n"); } peasycap_best_format = (struct easycap_format *)NULL; peasycap_format = &easycap_format[0]; @@ -369,7 +434,7 @@ while (0 != peasycap_format->v4l2_format.fmt.pix.width) { peasycap_format->v4l2_format.fmt.pix.width, peasycap_format->v4l2_format.fmt.pix.height); - if (((peasycap_format->mask & 0x0F) == (mask & 0x0F)) && \ + if (((peasycap_format->mask & 0x1F) == (mask & 0x1F)) && \ (peasycap_format->v4l2_format.fmt.pix.field == field) && \ (peasycap_format->v4l2_format.fmt.pix.pixelformat == \ pixelformat) && \ @@ -385,7 +450,7 @@ if (0 == peasycap_format->v4l2_format.fmt.pix.width) { width, height, mask); peasycap_format = &easycap_format[0]; best = -1; while (0 != peasycap_format->v4l2_format.fmt.pix.width) { - if (((peasycap_format->mask & 0x0F) == (mask & 0x0F)) && \ + if (((peasycap_format->mask & 0x1F) == (mask & 0x1F)) && \ (peasycap_format->v4l2_format.fmt.pix\ .field == field) && \ (peasycap_format->v4l2_format.fmt.pix\ @@ -432,7 +497,6 @@ SAM("actioning: %ix%i %s\n", \ peasycap->height = peasycap_format->v4l2_format.fmt.pix.height; peasycap->width = peasycap_format->v4l2_format.fmt.pix.width; peasycap->pixelformat = peasycap_format->v4l2_format.fmt.pix.pixelformat; -peasycap->field = peasycap_format->v4l2_format.fmt.pix.field; peasycap->format_offset = (int)(peasycap_format - &easycap_format[0]); @@ -451,11 +515,15 @@ if ((0 <= peasycap->input) && (INPUT_MANY > peasycap->input)) { -peasycap->bytesperpixel = (0x00F0 & peasycap_format->mask) >> 4 ; +peasycap->bytesperpixel = (0x00E0 & peasycap_format->mask) >> 5 ; if (0x0100 & peasycap_format->mask) peasycap->byteswaporder = true; else peasycap->byteswaporder = false; +if (0x0200 & peasycap_format->mask) + peasycap->skip = 5; +else + peasycap->skip = 0; if (0x0800 & peasycap_format->mask) peasycap->decimatepixel = true; else @@ -472,24 +540,6 @@ peasycap->videofieldamount = multiplier * peasycap->width * \ multiplier * peasycap->height; peasycap->frame_buffer_used = peasycap->bytesperpixel * \ peasycap->width * peasycap->height; - -if (true == peasycap->offerfields) { - SAM("WARNING: %i=peasycap->field is untested: " \ - "please report problems\n", peasycap->field); - - -/* - * FIXME ---- THIS IS UNTESTED, MAY BE (AND PROBABLY IS) INCORRECT: - * - * peasycap->frame_buffer_used = peasycap->frame_buffer_used / 2; - * - * SO DO NOT RISK IT YET. - * - */ - - - -} if (peasycap->video_isoc_streaming) { resubmit = true; kill_video_urbs(peasycap); @@ -1386,13 +1436,191 @@ case VIDIOC_ENUM_FMT: { break; } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +/* + * THE RESPONSE TO VIDIOC_ENUM_FRAMESIZES MUST BE CONDITIONED ON THE + * THE CURRENT STANDARD, BECAUSE THAT IS WHAT gstreamer EXPECTS. BEWARE. +*/ +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ case VIDIOC_ENUM_FRAMESIZES: { - JOM(8, "VIDIOC_ENUM_FRAMESIZES unsupported\n"); - return -EINVAL; + __u32 index; + struct v4l2_frmsizeenum v4l2_frmsizeenum; + + JOM(8, "VIDIOC_ENUM_FRAMESIZES\n"); + + if (0 != copy_from_user(&v4l2_frmsizeenum, (void __user *)arg, \ + sizeof(struct v4l2_frmsizeenum))) + return -EFAULT; + + index = v4l2_frmsizeenum.index; + + v4l2_frmsizeenum.type = (__u32) V4L2_FRMSIZE_TYPE_DISCRETE; + + if (true == peasycap->ntsc) { + switch (index) { + case 0: { + v4l2_frmsizeenum.discrete.width = 640; + v4l2_frmsizeenum.discrete.height = 480; + JOM(8, "%i=index: %ix%i\n", index, \ + (int)(v4l2_frmsizeenum.\ + discrete.width), \ + (int)(v4l2_frmsizeenum.\ + discrete.height)); + break; + } + case 1: { + v4l2_frmsizeenum.discrete.width = 320; + v4l2_frmsizeenum.discrete.height = 240; + JOM(8, "%i=index: %ix%i\n", index, \ + (int)(v4l2_frmsizeenum.\ + discrete.width), \ + (int)(v4l2_frmsizeenum.\ + discrete.height)); + break; + } + case 2: { + v4l2_frmsizeenum.discrete.width = 720; + v4l2_frmsizeenum.discrete.height = 480; + JOM(8, "%i=index: %ix%i\n", index, \ + (int)(v4l2_frmsizeenum.\ + discrete.width), \ + (int)(v4l2_frmsizeenum.\ + discrete.height)); + break; + } + case 3: { + v4l2_frmsizeenum.discrete.width = 360; + v4l2_frmsizeenum.discrete.height = 240; + JOM(8, "%i=index: %ix%i\n", index, \ + (int)(v4l2_frmsizeenum.\ + discrete.width), \ + (int)(v4l2_frmsizeenum.\ + discrete.height)); + break; + } + default: { + JOM(8, "%i=index: exhausts framesizes\n", index); + return -EINVAL; + } + } + } else { + switch (index) { + case 0: { + v4l2_frmsizeenum.discrete.width = 640; + v4l2_frmsizeenum.discrete.height = 480; + JOM(8, "%i=index: %ix%i\n", index, \ + (int)(v4l2_frmsizeenum.\ + discrete.width), \ + (int)(v4l2_frmsizeenum.\ + discrete.height)); + break; + } + case 1: { + v4l2_frmsizeenum.discrete.width = 320; + v4l2_frmsizeenum.discrete.height = 240; + JOM(8, "%i=index: %ix%i\n", index, \ + (int)(v4l2_frmsizeenum.\ + discrete.width), \ + (int)(v4l2_frmsizeenum.\ + discrete.height)); + break; + } + case 2: { + v4l2_frmsizeenum.discrete.width = 704; + v4l2_frmsizeenum.discrete.height = 576; + JOM(8, "%i=index: %ix%i\n", index, \ + (int)(v4l2_frmsizeenum.\ + discrete.width), \ + (int)(v4l2_frmsizeenum.\ + discrete.height)); + break; + } + case 3: { + v4l2_frmsizeenum.discrete.width = 720; + v4l2_frmsizeenum.discrete.height = 576; + JOM(8, "%i=index: %ix%i\n", index, \ + (int)(v4l2_frmsizeenum.\ + discrete.width), \ + (int)(v4l2_frmsizeenum.\ + discrete.height)); + break; + } + case 4: { + v4l2_frmsizeenum.discrete.width = 360; + v4l2_frmsizeenum.discrete.height = 288; + JOM(8, "%i=index: %ix%i\n", index, \ + (int)(v4l2_frmsizeenum.\ + discrete.width), \ + (int)(v4l2_frmsizeenum.\ + discrete.height)); + break; + } + default: { + JOM(8, "%i=index: exhausts framesizes\n", index); + return -EINVAL; + } + } + } + if (0 != copy_to_user((void __user *)arg, &v4l2_frmsizeenum, \ + sizeof(struct v4l2_frmsizeenum))) + return -EFAULT; + break; } +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +/* + * THE RESPONSE TO VIDIOC_ENUM_FRAMEINTERVALS MUST BE CONDITIONED ON THE + * THE CURRENT STANDARD, BECAUSE THAT IS WHAT gstreamer EXPECTS. BEWARE. +*/ +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ case VIDIOC_ENUM_FRAMEINTERVALS: { - JOM(8, "VIDIOC_ENUM_FRAME_INTERVALS unsupported\n"); - return -EINVAL; + __u32 index; + int denominator; + struct v4l2_frmivalenum v4l2_frmivalenum; + + JOM(8, "VIDIOC_ENUM_FRAMEINTERVALS\n"); + + if (peasycap->fps) + denominator = peasycap->fps; + else { + if (true == peasycap->ntsc) + denominator = 30; + else + denominator = 25; + } + + if (0 != copy_from_user(&v4l2_frmivalenum, (void __user *)arg, \ + sizeof(struct v4l2_frmivalenum))) + return -EFAULT; + + index = v4l2_frmivalenum.index; + + v4l2_frmivalenum.type = (__u32) V4L2_FRMIVAL_TYPE_DISCRETE; + + switch (index) { + case 0: { + v4l2_frmivalenum.discrete.numerator = 1; + v4l2_frmivalenum.discrete.denominator = denominator; + JOM(8, "%i=index: %i/%i\n", index, \ + (int)(v4l2_frmivalenum.discrete.numerator), \ + (int)(v4l2_frmivalenum.discrete.denominator)); + break; + } + case 1: { + v4l2_frmivalenum.discrete.numerator = 1; + v4l2_frmivalenum.discrete.denominator = denominator/5; + JOM(8, "%i=index: %i/%i\n", index, \ + (int)(v4l2_frmivalenum.discrete.numerator), \ + (int)(v4l2_frmivalenum.discrete.denominator)); + break; + } + default: { + JOM(8, "%i=index: exhausts frameintervals\n", index); + return -EINVAL; + } + } + if (0 != copy_to_user((void __user *)arg, &v4l2_frmivalenum, \ + sizeof(struct v4l2_frmivalenum))) + return -EFAULT; + break; } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ case VIDIOC_G_FMT: { @@ -1603,6 +1831,10 @@ case VIDIOC_S_STD: { sizeof(v4l2_std_id))) return -EFAULT; + JOM(8, "User requests standard: 0x%08X%08X\n", \ + (int)((std_id & (((v4l2_std_id)0xFFFFFFFF) << 32)) >> 32), \ + (int)(std_id & ((v4l2_std_id)0xFFFFFFFF))); + rc = adjust_standard(peasycap, std_id); if (0 > rc) { JOM(8, "WARNING: adjust_standard() returned %i\n", rc); @@ -1675,7 +1907,7 @@ case VIDIOC_QUERYBUF: { v4l2_buffer.flags = V4L2_BUF_FLAG_MAPPED | \ peasycap->done[index] | \ peasycap->queued[index]; - v4l2_buffer.field = peasycap->field; + v4l2_buffer.field = V4L2_FIELD_NONE; v4l2_buffer.memory = V4L2_MEMORY_MMAP; v4l2_buffer.m.offset = index * FRAME_BUFFER_SIZE; v4l2_buffer.length = FRAME_BUFFER_SIZE; @@ -1762,6 +1994,24 @@ case VIDIOC_DQBUF: if (v4l2_buffer.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) return -EINVAL; + if (true == peasycap->offerfields) { + /*-----------------------------------------------------------*/ + /* + * IN ITS 50 "fps" MODE tvtime SEEMS ALWAYS TO REQUEST + * V4L2_FIELD_BOTTOM + */ + /*-----------------------------------------------------------*/ + if (V4L2_FIELD_TOP == v4l2_buffer.field) + JOM(8, "user wants V4L2_FIELD_TOP\n"); + else if (V4L2_FIELD_BOTTOM == v4l2_buffer.field) + JOM(8, "user wants V4L2_FIELD_BOTTOM\n"); + else if (V4L2_FIELD_ANY == v4l2_buffer.field) + JOM(8, "user wants V4L2_FIELD_ANY\n"); + else + JOM(8, "user wants V4L2_FIELD_...UNKNOWN: %i\n", \ + v4l2_buffer.field); + } + if (!peasycap->video_isoc_streaming) { JOM(16, "returning -EIO because video urbs not streaming\n"); return -EIO; @@ -1811,11 +2061,10 @@ case VIDIOC_DQBUF: v4l2_buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; v4l2_buffer.bytesused = peasycap->frame_buffer_used; v4l2_buffer.flags = V4L2_BUF_FLAG_MAPPED | V4L2_BUF_FLAG_DONE; - v4l2_buffer.field = peasycap->field; - if (V4L2_FIELD_ALTERNATE == v4l2_buffer.field) - v4l2_buffer.field = \ - 0x000F & (peasycap->\ - frame_buffer[peasycap->frame_read][0].kount); + if (true == peasycap->offerfields) + v4l2_buffer.field = V4L2_FIELD_BOTTOM; + else + v4l2_buffer.field = V4L2_FIELD_NONE; do_gettimeofday(&timeval); timeval2 = timeval; @@ -1876,10 +2125,6 @@ case VIDIOC_DQBUF: sizeof(struct v4l2_buffer))) return -EFAULT; - JOM(8, "..... user is offered frame buffer %i\n", \ - peasycap->frame_read); - peasycap->frame_lock = 1; - input = peasycap->frame_buffer[peasycap->frame_read][0].input; if (0x08 & input) { JOM(8, "user is offered frame buffer %i, input %i\n", \ @@ -1956,7 +2201,6 @@ case VIDIOC_G_PARM: { v4l2_streamparm.parm.capture.capability = 0; v4l2_streamparm.parm.capture.capturemode = 0; v4l2_streamparm.parm.capture.timeperframe.numerator = 1; - v4l2_streamparm.parm.capture.timeperframe.denominator = 30; if (peasycap->fps) { v4l2_streamparm.parm.capture.timeperframe.\ diff --git a/drivers/staging/easycap/easycap_main.c b/drivers/staging/easycap/easycap_main.c index b522c6eb65f6..988feee7bcbe 100644 --- a/drivers/staging/easycap/easycap_main.c +++ b/drivers/staging/easycap/easycap_main.c @@ -471,7 +471,7 @@ if (NULL == peasycap->pusb_device) { SAM("ERROR: peasycap->pusb_device is NULL\n"); return -ENODEV; } -rc = usb_set_interface(peasycap->pusb_device, \ +rc = usb_set_interface(peasycap->pusb_device, peasycap->video_interface, \ peasycap->video_altsetting_off); if (0 != rc) { @@ -1103,7 +1103,7 @@ else int easycap_dqbuf(struct easycap *peasycap, int mode) { -int miss, rc; +int ifield, miss, rc; JOT(8, "\n"); @@ -1111,16 +1111,18 @@ if (NULL == peasycap) { SAY("ERROR: peasycap is NULL\n"); return -EFAULT; } +ifield = 0; +JOM(8, "%i=ifield\n", ifield); /*---------------------------------------------------------------------------*/ /* - * WAIT FOR FIELD 0 + * WAIT FOR FIELD ifield (0 => TOP, 1 => BOTTOM) */ /*---------------------------------------------------------------------------*/ miss = 0; while ((peasycap->field_read == peasycap->field_fill) || \ (0 != (0xFF00 & peasycap->field_buffer\ [peasycap->field_read][0].kount)) || \ - (0 != (0x00FF & peasycap->field_buffer\ + (ifield != (0x00FF & peasycap->field_buffer\ [peasycap->field_read][0].kount))) { if (mode) return -EAGAIN; @@ -1134,7 +1136,7 @@ while ((peasycap->field_read == peasycap->field_fill) || \ ((peasycap->field_read != peasycap->field_fill) && \ (0 == (0xFF00 & peasycap->field_buffer\ [peasycap->field_read][0].kount)) && \ - (0 == (0x00FF & peasycap->field_buffer\ + (ifield == (0x00FF & peasycap->field_buffer\ [peasycap->field_read][0].kount))))))) { SAM("aborted by signal\n"); return -EIO; @@ -1176,33 +1178,20 @@ JOM(8, "first awakening on wq_video after %i waits\n", miss); rc = field2frame(peasycap); if (0 != rc) SAM("ERROR: field2frame() returned %i\n", rc); - -if (true == peasycap->offerfields) { - peasycap->frame_read = peasycap->frame_fill; - (peasycap->frame_fill)++; - if (peasycap->frame_buffer_many <= peasycap->frame_fill) - peasycap->frame_fill = 0; - - if (0x01 & easycap_standard[peasycap->standard_offset].mask) { - peasycap->frame_buffer[peasycap->frame_read][0].kount = \ - V4L2_FIELD_BOTTOM; - } else { - peasycap->frame_buffer[peasycap->frame_read][0].kount = \ - V4L2_FIELD_TOP; - } -JOM(8, "setting: %i=peasycap->frame_read\n", peasycap->frame_read); -JOM(8, "bumped to: %i=peasycap->frame_fill\n", peasycap->frame_fill); -} /*---------------------------------------------------------------------------*/ /* - * WAIT FOR FIELD 1 + * WAIT FOR THE OTHER FIELD */ /*---------------------------------------------------------------------------*/ +if (ifield) + ifield = 0; +else + ifield = 1; miss = 0; while ((peasycap->field_read == peasycap->field_fill) || \ (0 != (0xFF00 & peasycap->field_buffer\ [peasycap->field_read][0].kount)) || \ - (0 == (0x00FF & peasycap->field_buffer\ + (ifield != (0x00FF & peasycap->field_buffer\ [peasycap->field_read][0].kount))) { if (mode) return -EAGAIN; @@ -1215,8 +1204,9 @@ while ((peasycap->field_read == peasycap->field_fill) || \ ((peasycap->field_read != peasycap->field_fill) && \ (0 == (0xFF00 & peasycap->field_buffer\ [peasycap->field_read][0].kount)) && \ - (0 != (0x00FF & peasycap->field_buffer\ - [peasycap->field_read][0].kount))))))) { + (ifield == (0x00FF & peasycap->field_buffer\ + [peasycap->field_read][0].\ + kount))))))) { SAM("aborted by signal\n"); return -EIO; } @@ -1257,7 +1247,18 @@ JOM(8, "second awakening on wq_video after %i waits\n", miss); rc = field2frame(peasycap); if (0 != rc) SAM("ERROR: field2frame() returned %i\n", rc); - +/*---------------------------------------------------------------------------*/ +/* + * WASTE THIS FRAME +*/ +/*---------------------------------------------------------------------------*/ +if (0 != peasycap->skip) { + peasycap->skipped++; + if (peasycap->skip != peasycap->skipped) + return peasycap->skip - peasycap->skipped; + peasycap->skipped = 0; +} +/*---------------------------------------------------------------------------*/ peasycap->frame_read = peasycap->frame_fill; peasycap->queued[peasycap->frame_read] = 0; peasycap->done[peasycap->frame_read] = V4L2_BUF_FLAG_DONE; @@ -1289,8 +1290,7 @@ return 0; * odd==false IS TRANSFERRED TO THE FRAME BUFFER. * * THE BOOLEAN PARAMETER offerfields IS true ONLY WHEN THE USER PROGRAM - * CHOOSES THE OPTION V4L2_FIELD_ALTERNATE. NO USERSPACE PROGRAM TESTED - * TO DATE HAS DONE THIS. BUGS ARE LIKELY. + * CHOOSES THE OPTION V4L2_FIELD_INTERLACED. */ /*---------------------------------------------------------------------------*/ int @@ -1315,8 +1315,10 @@ if ((struct easycap *)NULL == peasycap) { badinput = false; -JOM(8, "===== parity %i, field buffer %i --> frame buffer %i\n", \ +JOM(8, "===== parity %i, input 0x%02X, field buffer %i --> " \ + "frame buffer %i\n", \ peasycap->field_buffer[peasycap->field_read][0].kount,\ + peasycap->field_buffer[peasycap->field_read][0].input,\ peasycap->field_read, peasycap->frame_fill); JOM(8, "===== %i=bytesperpixel\n", peasycap->bytesperpixel); if (true == peasycap->offerfields) @@ -1374,7 +1376,7 @@ if (peasycap->field_buffer[kex][0].kount) else odd = false; -if ((true == odd) && (false == offerfields) &&(false == decimatepixel)) { +if ((true == odd) && (false == decimatepixel)) { JOM(8, " initial skipping %4i bytes p.%4i\n", \ w3/multiplier, mad); pad += (w3 / multiplier); rad -= (w3 / multiplier); @@ -1494,7 +1496,7 @@ while (cz < wz) { * UNLESS IT IS THE LAST LINE OF AN ODD FRAME */ /*---------------------------------------------------------------------------*/ - if (((false == odd) || (cz != wz))&&(false == offerfields)) { + if ((false == odd) || (cz != wz)) { over = w3; do { if (!rad) { @@ -3162,6 +3164,15 @@ if (purb->status) { [peasycap->field_page]; pfield_buffer->pto = \ pfield_buffer->pgo; + pfield_buffer->input = 0x08 | \ + (0x07 & peasycap->input); + if ((peasycap->field_buffer[peasycap->\ + field_fill][0]).\ + input != \ + pfield_buffer->input) + (peasycap->field_buffer\ + [peasycap->field_fill]\ + [0]).kount |= 0x1000; } much = PAGE_SIZE - (int)(pfield_buffer->pto - \ @@ -3441,7 +3452,6 @@ if (0 == bInterfaceNumber) { break; } } - if (DONGLE_MANY <= dongle_this) { SAM("ERROR: too many dongles\n"); return -ENOMEM; @@ -3481,6 +3491,8 @@ if (0 == bInterfaceNumber) { peasycap->frame_buffer_many = FRAME_BUFFER_MANY; + peasycap->skip = 0; + peasycap->skipped = 0; peasycap->offerfields = 0; /*---------------------------------------------------------------------------*/ /* diff --git a/drivers/staging/easycap/easycap_settings.c b/drivers/staging/easycap/easycap_settings.c index 67f2e4f27323..df3f17d361b1 100644 --- a/drivers/staging/easycap/easycap_settings.c +++ b/drivers/staging/easycap/easycap_settings.c @@ -33,11 +33,15 @@ * THE LEAST SIGNIFICANT BIT OF easycap_standard.mask HAS MEANING: * 0 => 25 fps * 1 => 30 fps + * + * THE MOST SIGNIFICANT BIT OF easycap_standard.mask HAS MEANING: + * 0 => full framerate + * 1 => 20% framerate */ /*---------------------------------------------------------------------------*/ const struct easycap_standard easycap_standard[] = { { -.mask = 0x000F & PAL_BGHIN , +.mask = 0x00FF & PAL_BGHIN , .v4l2_standard = { .index = PAL_BGHIN, .id = (V4L2_STD_PAL_B | V4L2_STD_PAL_G | V4L2_STD_PAL_H | \ @@ -50,7 +54,7 @@ const struct easycap_standard easycap_standard[] = { }, /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ { -.mask = 0x000F & NTSC_N_443 , +.mask = 0x00FF & NTSC_N_443 , .v4l2_standard = { .index = NTSC_N_443, .id = V4L2_STD_UNKNOWN, @@ -62,7 +66,7 @@ const struct easycap_standard easycap_standard[] = { }, /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ { -.mask = 0x000F & PAL_Nc , +.mask = 0x00FF & PAL_Nc , .v4l2_standard = { .index = PAL_Nc, .id = V4L2_STD_PAL_Nc, @@ -74,7 +78,7 @@ const struct easycap_standard easycap_standard[] = { }, /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ { -.mask = 0x000F & NTSC_N , +.mask = 0x00FF & NTSC_N , .v4l2_standard = { .index = NTSC_N, .id = V4L2_STD_UNKNOWN, @@ -86,7 +90,7 @@ const struct easycap_standard easycap_standard[] = { }, /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ { -.mask = 0x000F & SECAM , +.mask = 0x00FF & SECAM , .v4l2_standard = { .index = SECAM, .id = V4L2_STD_SECAM, @@ -98,7 +102,7 @@ const struct easycap_standard easycap_standard[] = { }, /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ { -.mask = 0x000F & NTSC_M , +.mask = 0x00FF & NTSC_M , .v4l2_standard = { .index = NTSC_M, .id = V4L2_STD_NTSC_M, @@ -110,7 +114,7 @@ const struct easycap_standard easycap_standard[] = { }, /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ { -.mask = 0x000F & NTSC_M_JP , +.mask = 0x00FF & NTSC_M_JP , .v4l2_standard = { .index = NTSC_M_JP, .id = V4L2_STD_NTSC_M_JP, @@ -122,7 +126,7 @@ const struct easycap_standard easycap_standard[] = { }, /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ { -.mask = 0x000F & PAL_60 , +.mask = 0x00FF & PAL_60 , .v4l2_standard = { .index = PAL_60, .id = V4L2_STD_PAL_60, @@ -134,7 +138,7 @@ const struct easycap_standard easycap_standard[] = { }, /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ { -.mask = 0x000F & NTSC_443 , +.mask = 0x00FF & NTSC_443 , .v4l2_standard = { .index = NTSC_443, .id = V4L2_STD_NTSC_443, @@ -146,7 +150,7 @@ const struct easycap_standard easycap_standard[] = { }, /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ { -.mask = 0x000F & PAL_M , +.mask = 0x00FF & PAL_M , .v4l2_standard = { .index = PAL_M, .id = V4L2_STD_PAL_M, @@ -158,6 +162,128 @@ const struct easycap_standard easycap_standard[] = { }, /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ { +.mask = 0x8000 | (0x00FF & PAL_BGHIN_SLOW), +.v4l2_standard = { + .index = PAL_BGHIN_SLOW, + .id = (V4L2_STD_PAL_B | V4L2_STD_PAL_G | V4L2_STD_PAL_H | \ + V4L2_STD_PAL_I | V4L2_STD_PAL_N | \ + (((v4l2_std_id)0x01) << 32)), + .name = "PAL_BGHIN_SLOW", + .frameperiod = {1, 5}, + .framelines = 625, + .reserved = {0, 0, 0, 0} +} +}, +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +{ +.mask = 0x8000 | (0x00FF & NTSC_N_443_SLOW), +.v4l2_standard = { + .index = NTSC_N_443_SLOW, + .id = (V4L2_STD_UNKNOWN | (((v4l2_std_id)0x11) << 32)), + .name = "NTSC_N_443_SLOW", + .frameperiod = {1, 5}, + .framelines = 480, + .reserved = {0, 0, 0, 0} +} +}, +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +{ +.mask = 0x8000 | (0x00FF & PAL_Nc_SLOW), +.v4l2_standard = { + .index = PAL_Nc_SLOW, + .id = (V4L2_STD_PAL_Nc | (((v4l2_std_id)0x01) << 32)), + .name = "PAL_Nc_SLOW", + .frameperiod = {1, 5}, + .framelines = 625, + .reserved = {0, 0, 0, 0} +} +}, +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +{ +.mask = 0x8000 | (0x00FF & NTSC_N_SLOW), +.v4l2_standard = { + .index = NTSC_N_SLOW, + .id = (V4L2_STD_UNKNOWN | (((v4l2_std_id)0x21) << 32)), + .name = "NTSC_N_SLOW", + .frameperiod = {1, 5}, + .framelines = 525, + .reserved = {0, 0, 0, 0} +} +}, +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +{ +.mask = 0x8000 | (0x00FF & SECAM_SLOW), +.v4l2_standard = { + .index = SECAM_SLOW, + .id = (V4L2_STD_SECAM | (((v4l2_std_id)0x01) << 32)), + .name = "SECAM_SLOW", + .frameperiod = {1, 5}, + .framelines = 625, + .reserved = {0, 0, 0, 0} +} +}, +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +{ +.mask = 0x8000 | (0x00FF & NTSC_M_SLOW), +.v4l2_standard = { + .index = NTSC_M_SLOW, + .id = (V4L2_STD_NTSC_M | (((v4l2_std_id)0x01) << 32)), + .name = "NTSC_M_SLOW", + .frameperiod = {1, 6}, + .framelines = 525, + .reserved = {0, 0, 0, 0} +} +}, +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +{ +.mask = 0x8000 | (0x00FF & NTSC_M_JP_SLOW), +.v4l2_standard = { + .index = NTSC_M_JP_SLOW, + .id = (V4L2_STD_NTSC_M_JP | (((v4l2_std_id)0x01) << 32)), + .name = "NTSC_M_JP_SLOW", + .frameperiod = {1, 6}, + .framelines = 525, + .reserved = {0, 0, 0, 0} +} +}, +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +{ +.mask = 0x8000 | (0x00FF & PAL_60_SLOW), +.v4l2_standard = { + .index = PAL_60_SLOW, + .id = (V4L2_STD_PAL_60 | (((v4l2_std_id)0x01) << 32)), + .name = "PAL_60_SLOW", + .frameperiod = {1, 6}, + .framelines = 525, + .reserved = {0, 0, 0, 0} +} +}, +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +{ +.mask = 0x8000 | (0x00FF & NTSC_443_SLOW), +.v4l2_standard = { + .index = NTSC_443_SLOW, + .id = (V4L2_STD_NTSC_443 | (((v4l2_std_id)0x01) << 32)), + .name = "NTSC_443_SLOW", + .frameperiod = {1, 6}, + .framelines = 525, + .reserved = {0, 0, 0, 0} +} +}, +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +{ +.mask = 0x8000 | (0x00FF & PAL_M_SLOW), +.v4l2_standard = { + .index = PAL_M_SLOW, + .id = (V4L2_STD_PAL_M | (((v4l2_std_id)0x01) << 32)), + .name = "PAL_M_SLOW", + .frameperiod = {1, 6}, + .framelines = 525, + .reserved = {0, 0, 0, 0} +} +}, +/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ +{ .mask = 0xFFFF } }; @@ -165,15 +291,16 @@ const struct easycap_standard easycap_standard[] = { /* * THE 16-BIT easycap_format.mask HAS MEANING: * (least significant) BIT 0: 0 => PAL, 25 FPS; 1 => NTSC, 30 FPS - * BITS 1-3: RESERVED FOR DIFFERENTIATING STANDARDS - * BITS 4-7: NUMBER OF BYTES PER PIXEL + * BITS 2-4: RESERVED FOR DIFFERENTIATING STANDARDS + * BITS 5-7: NUMBER OF BYTES PER PIXEL * BIT 8: 0 => NATIVE BYTE ORDER; 1 => SWAPPED * BITS 9-10: RESERVED FOR OTHER BYTE PERMUTATIONS - * BIT 11: 0 => UNDECIMATED; 1 => DECIMATED - * BIT 12: 0 => OFFER FRAMES; 1 => OFFER FIELDS - * (most significant) BITS 13-15: RESERVED FOR OTHER FIELD ORDER OPTIONS + * BIT 11: 0 => UNDECIMATED; 1 => DECIMATED + * BIT 12: 0 => OFFER FRAMES; 1 => OFFER FIELDS + * BIT 13: 0 => FULL FRAMERATE; 1 => REDUCED + * (most significant) BITS 14-15: RESERVED FOR OTHER FIELD/FRAME OPTIONS * IT FOLLOWS THAT: - * bytesperpixel IS ((0x00F0 & easycap_format.mask) >> 4) + * bytesperpixel IS ((0x00E0 & easycap_format.mask) >> 5) * byteswaporder IS true IF (0 != (0x0100 & easycap_format.mask)) * * decimatepixel IS true IF (0 != (0x0800 & easycap_format.mask)) @@ -197,65 +324,135 @@ for (i = 0, n = 0; i < STANDARD_MANY; i++) { mask1 = 0x0000; switch (i) { case PAL_BGHIN: { - mask1 = PAL_BGHIN; + mask1 = 0x1F & PAL_BGHIN; strcpy(&name1[0], "PAL_BGHIN"); colorspace = V4L2_COLORSPACE_470_SYSTEM_BG; break; } case SECAM: { - mask1 = SECAM; + mask1 = 0x1F & SECAM; strcpy(&name1[0], "SECAM"); colorspace = V4L2_COLORSPACE_470_SYSTEM_BG; break; } case PAL_Nc: { - mask1 = PAL_Nc; + mask1 = 0x1F & PAL_Nc; strcpy(&name1[0], "PAL_Nc"); colorspace = V4L2_COLORSPACE_470_SYSTEM_BG; break; } case PAL_60: { - mask1 = PAL_60; + mask1 = 0x1F & PAL_60; strcpy(&name1[0], "PAL_60"); colorspace = V4L2_COLORSPACE_470_SYSTEM_BG; break; } case PAL_M: { - mask1 = PAL_M; + mask1 = 0x1F & PAL_M; strcpy(&name1[0], "PAL_M"); colorspace = V4L2_COLORSPACE_470_SYSTEM_BG; break; } case NTSC_M: { - mask1 = NTSC_M; + mask1 = 0x1F & NTSC_M; strcpy(&name1[0], "NTSC_M"); colorspace = V4L2_COLORSPACE_470_SYSTEM_M; break; } case NTSC_443: { - mask1 = NTSC_443; + mask1 = 0x1F & NTSC_443; strcpy(&name1[0], "NTSC_443"); colorspace = V4L2_COLORSPACE_470_SYSTEM_M; break; } case NTSC_M_JP: { - mask1 = NTSC_M_JP; + mask1 = 0x1F & NTSC_M_JP; strcpy(&name1[0], "NTSC_M_JP"); colorspace = V4L2_COLORSPACE_470_SYSTEM_M; break; } case NTSC_N: { - mask1 = NTSC_M; + mask1 = 0x1F & NTSC_M; strcpy(&name1[0], "NTSC_N"); colorspace = V4L2_COLORSPACE_470_SYSTEM_M; break; } case NTSC_N_443: { - mask1 = NTSC_N_443; + mask1 = 0x1F & NTSC_N_443; strcpy(&name1[0], "NTSC_N_443"); colorspace = V4L2_COLORSPACE_470_SYSTEM_M; break; } + case PAL_BGHIN_SLOW: { + mask1 = 0x001F & PAL_BGHIN_SLOW; + mask1 |= 0x0200; + strcpy(&name1[0], "PAL_BGHIN_SLOW"); + colorspace = V4L2_COLORSPACE_470_SYSTEM_BG; + break; + } + case SECAM_SLOW: { + mask1 = 0x001F & SECAM_SLOW; + mask1 |= 0x0200; + strcpy(&name1[0], "SECAM_SLOW"); + colorspace = V4L2_COLORSPACE_470_SYSTEM_BG; + break; + } + case PAL_Nc_SLOW: { + mask1 = 0x001F & PAL_Nc_SLOW; + mask1 |= 0x0200; + strcpy(&name1[0], "PAL_Nc_SLOW"); + colorspace = V4L2_COLORSPACE_470_SYSTEM_BG; + break; + } + case PAL_60_SLOW: { + mask1 = 0x001F & PAL_60_SLOW; + mask1 |= 0x0200; + strcpy(&name1[0], "PAL_60_SLOW"); + colorspace = V4L2_COLORSPACE_470_SYSTEM_BG; + break; + } + case PAL_M_SLOW: { + mask1 = 0x001F & PAL_M_SLOW; + mask1 |= 0x0200; + strcpy(&name1[0], "PAL_M_SLOW"); + colorspace = V4L2_COLORSPACE_470_SYSTEM_BG; + break; + } + case NTSC_M_SLOW: { + mask1 = 0x001F & NTSC_M_SLOW; + mask1 |= 0x0200; + strcpy(&name1[0], "NTSC_M_SLOW"); + colorspace = V4L2_COLORSPACE_470_SYSTEM_M; + break; + } + case NTSC_443_SLOW: { + mask1 = 0x001F & NTSC_443_SLOW; + mask1 |= 0x0200; + strcpy(&name1[0], "NTSC_443_SLOW"); + colorspace = V4L2_COLORSPACE_470_SYSTEM_M; + break; + } + case NTSC_M_JP_SLOW: { + mask1 = 0x001F & NTSC_M_JP_SLOW; + mask1 |= 0x0200; + strcpy(&name1[0], "NTSC_M_JP_SLOW"); + colorspace = V4L2_COLORSPACE_470_SYSTEM_M; + break; + } + case NTSC_N_SLOW: { + mask1 = 0x001F & NTSC_N_SLOW; + mask1 |= 0x0200; + strcpy(&name1[0], "NTSC_N_SLOW"); + colorspace = V4L2_COLORSPACE_470_SYSTEM_M; + break; + } + case NTSC_N_443_SLOW: { + mask1 = 0x001F & NTSC_N_443_SLOW; + mask1 |= 0x0200; + strcpy(&name1[0], "NTSC_N_443_SLOW"); + colorspace = V4L2_COLORSPACE_470_SYSTEM_M; + break; + } default: return -1; } @@ -311,39 +508,39 @@ for (i = 0, n = 0; i < STANDARD_MANY; i++) { case FMT_UYVY: { strcpy(&name3[0], "_" STRINGIZE(FMT_UYVY)); pixelformat = V4L2_PIX_FMT_UYVY; - mask3 |= (0x02 << 4); + mask3 |= (0x02 << 5); break; } case FMT_YUY2: { strcpy(&name3[0], "_" STRINGIZE(FMT_YUY2)); pixelformat = V4L2_PIX_FMT_YUYV; - mask3 |= (0x02 << 4); + mask3 |= (0x02 << 5); mask3 |= 0x0100; break; } case FMT_RGB24: { strcpy(&name3[0], "_" STRINGIZE(FMT_RGB24)); pixelformat = V4L2_PIX_FMT_RGB24; - mask3 |= (0x03 << 4); + mask3 |= (0x03 << 5); break; } case FMT_RGB32: { strcpy(&name3[0], "_" STRINGIZE(FMT_RGB32)); pixelformat = V4L2_PIX_FMT_RGB32; - mask3 |= (0x04 << 4); + mask3 |= (0x04 << 5); break; } case FMT_BGR24: { strcpy(&name3[0], "_" STRINGIZE(FMT_BGR24)); pixelformat = V4L2_PIX_FMT_BGR24; - mask3 |= (0x03 << 4); + mask3 |= (0x03 << 5); mask3 |= 0x0100; break; } case FMT_BGR32: { strcpy(&name3[0], "_" STRINGIZE(FMT_BGR32)); pixelformat = V4L2_PIX_FMT_BGR32; - mask3 |= (0x04 << 4); + mask3 |= (0x04 << 5); mask3 |= 0x0100; break; } @@ -363,13 +560,8 @@ for (i = 0, n = 0; i < STANDARD_MANY; i++) { } case FIELD_INTERLACED: { strcpy(&name4[0], "-i"); - field = V4L2_FIELD_INTERLACED; - break; - } - case FIELD_ALTERNATE: { - strcpy(&name4[0], "-a"); mask4 |= 0x1000; - field = V4L2_FIELD_ALTERNATE; + field = V4L2_FIELD_INTERLACED; break; } default: -- cgit v1.2.3 From 849322a0f114e52d05e16fe8349843c980cff2c6 Mon Sep 17 00:00:00 2001 From: Mike Thomas Date: Sun, 7 Nov 2010 20:03:50 +0000 Subject: staging/easycap: Add option to show conspicuous indication of signal loss A new module parameter turns on the option of displaying a testcard when the analogue input signal is lost (more precisely: when the hardware detects no field/frame synchronization). This feature has been requested in the context of security cameras used at night. Signed-off-by: Mike Thomas Signed-off-by: Greg Kroah-Hartman --- drivers/staging/easycap/easycap.h | 2 + drivers/staging/easycap/easycap_main.c | 71 ++++++++++++++++++++------ drivers/staging/easycap/easycap_testcard.c | 80 ++++++++++++++++++++---------- 3 files changed, 112 insertions(+), 41 deletions(-) diff --git a/drivers/staging/easycap/easycap.h b/drivers/staging/easycap/easycap.h index 7c4cf7a338c4..e9410b74ffc4 100644 --- a/drivers/staging/easycap/easycap.h +++ b/drivers/staging/easycap/easycap.h @@ -154,6 +154,7 @@ #error video_isoc_buffer[.] will not be big enough #endif #define VIDEO_JUNK_TOLERATE VIDEO_ISOC_BUFFER_MANY +#define VIDEO_LOST_TOLERATE 50 /*---------------------------------------------------------------------------*/ /* * VIDEO BUFFERS @@ -344,6 +345,7 @@ int usec; int tolerate; int skip; int skipped; +int lost[INPUT_MANY]; int merit[180]; struct timeval timeval0; diff --git a/drivers/staging/easycap/easycap_main.c b/drivers/staging/easycap/easycap_main.c index 988feee7bcbe..21450e83530f 100644 --- a/drivers/staging/easycap/easycap_main.c +++ b/drivers/staging/easycap/easycap_main.c @@ -33,7 +33,9 @@ #include "easycap_ioctl.h" int debug; +int bars; module_param(debug, int, S_IRUGO | S_IWUSR); +module_param(bars, int, S_IRUGO | S_IWUSR); /*---------------------------------------------------------------------------*/ /* @@ -868,7 +870,7 @@ return 0; void easycap_delete(struct kref *pkref) { -int k, m, lost; +int k, m, gone; int allocation_video_urb, allocation_video_page, allocation_video_struct; int allocation_audio_urb, allocation_audio_page, allocation_audio_struct; int registered_video, registered_audio; @@ -941,7 +943,7 @@ for (k = 0; k < VIDEO_ISOC_BUFFER_MANY; k++) { JOM(4, "isoc video buffers freed: %i pages\n", m * (0x01 << VIDEO_ISOC_ORDER)); /*---------------------------------------------------------------------------*/ JOM(4, "freeing video field buffers.\n"); -lost = 0; +gone = 0; for (k = 0; k < FIELD_BUFFER_MANY; k++) { for (m = 0; m < FIELD_BUFFER_SIZE/PAGE_SIZE; m++) { if ((void *)NULL != peasycap->field_buffer[k][m].pgo) { @@ -949,14 +951,14 @@ for (k = 0; k < FIELD_BUFFER_MANY; k++) { (peasycap->field_buffer[k][m].pgo)); peasycap->field_buffer[k][m].pgo = (void *)NULL; peasycap->allocation_video_page -= 1; - lost++; + gone++; } } } -JOM(4, "video field buffers freed: %i pages\n", lost); +JOM(4, "video field buffers freed: %i pages\n", gone); /*---------------------------------------------------------------------------*/ JOM(4, "freeing video frame buffers.\n"); -lost = 0; +gone = 0; for (k = 0; k < FRAME_BUFFER_MANY; k++) { for (m = 0; m < FRAME_BUFFER_SIZE/PAGE_SIZE; m++) { if ((void *)NULL != peasycap->frame_buffer[k][m].pgo) { @@ -964,11 +966,11 @@ for (k = 0; k < FRAME_BUFFER_MANY; k++) { (peasycap->frame_buffer[k][m].pgo)); peasycap->frame_buffer[k][m].pgo = (void *)NULL; peasycap->allocation_video_page -= 1; - lost++; + gone++; } } } -JOM(4, "video frame buffers freed: %i pages\n", lost); +JOM(4, "video frame buffers freed: %i pages\n", gone); /*---------------------------------------------------------------------------*/ /* * FREE AUDIO. @@ -1027,16 +1029,16 @@ JOM(4, "easysnd_delete(): isoc audio buffers freed: %i pages\n", \ m * (0x01 << AUDIO_ISOC_ORDER)); /*---------------------------------------------------------------------------*/ JOM(4, "freeing audio buffers.\n"); -lost = 0; +gone = 0; for (k = 0; k < peasycap->audio_buffer_page_many; k++) { if ((void *)NULL != peasycap->audio_buffer[k].pgo) { free_page((unsigned long)(peasycap->audio_buffer[k].pgo)); peasycap->audio_buffer[k].pgo = (void *)NULL; peasycap->allocation_audio_page -= 1; - lost++; + gone++; } } -JOM(4, "easysnd_delete(): audio buffers freed: %i pages\n", lost); +JOM(4, "easysnd_delete(): audio buffers freed: %i pages\n", gone); /*---------------------------------------------------------------------------*/ JOM(4, "freeing easycap structure.\n"); allocation_video_urb = peasycap->allocation_video_urb; @@ -1103,7 +1105,7 @@ else int easycap_dqbuf(struct easycap *peasycap, int mode) { -int ifield, miss, rc; +int input, ifield, miss, rc; JOT(8, "\n"); @@ -1114,6 +1116,36 @@ if (NULL == peasycap) { ifield = 0; JOM(8, "%i=ifield\n", ifield); /*---------------------------------------------------------------------------*/ +/* + * CHECK FOR LOST INPUT SIGNAL. + * + * FOR THE FOUR-CVBS EasyCAP, THIS DOES NOT WORK AS EXPECTED. + * IF INPUT 0 IS PRESENT AND LOCKED, UNPLUGGING INPUT 4 DOES NOT RESULT IN + * SETTING BIT 0x40 ON REGISTER 0x1F, PRESUMABLY BECAUSE THERE IS FLYWHEELING + * ON INPUT 0. THE UPSHOT IS: + * + * INPUT 0 PLUGGED, INPUT 4 PLUGGED => SCREEN 0 OK, SCREEN 4 OK + * INPUT 0 PLUGGED, INPUT 4 UNPLUGGED => SCREEN 0 OK, SCREEN 4 BLACK + * INPUT 0 UNPLUGGED, INPUT 4 PLUGGED => SCREEN 0 BARS, SCREEN 4 OK + * INPUT 0 UNPLUGGED, INPUT 4 UNPLUGGED => SCREEN 0 BARS, SCREEN 4 BARS +*/ +/*---------------------------------------------------------------------------*/ +input = peasycap->input; +if (0 <= input && INPUT_MANY > input) { + rc = read_saa(peasycap->pusb_device, 0x1F); + if (0 <= rc) { + if (rc & 0x40) + peasycap->lost[input] += 1; + else + peasycap->lost[input] -= 2; + + if (0 > peasycap->lost[input]) + peasycap->lost[input] = 0; + else if ((2 * VIDEO_LOST_TOLERATE) < peasycap->lost[input]) + peasycap->lost[input] = (2 * VIDEO_LOST_TOLERATE); + } +} +/*---------------------------------------------------------------------------*/ /* * WAIT FOR FIELD ifield (0 => TOP, 1 => BOTTOM) */ @@ -1304,7 +1336,7 @@ struct signed_div_result sdr; void *pex, *pad; int kex, kad, mex, mad, rex, rad, rad2; int c2, c3, w2, w3, cz, wz; -int rc, bytesperpixel, multiplier, much, more, over, rump, caches; +int rc, bytesperpixel, multiplier, much, more, over, rump, caches, input; __u8 mask, margin; bool odd, isuy, decimatepixel, offerfields, badinput; @@ -1314,6 +1346,7 @@ if ((struct easycap *)NULL == peasycap) { } badinput = false; +input = 0x07 & peasycap->field_buffer[peasycap->field_read][0].input; JOM(8, "===== parity %i, input 0x%02X, field buffer %i --> " \ "frame buffer %i\n", \ @@ -1337,8 +1370,10 @@ if (peasycap->field_read == peasycap->field_fill) { #if defined(EASYCAP_TESTCARD) easycap_testcard(peasycap, peasycap->field_read); #else -if (0 != (0x0400 & peasycap->field_buffer[peasycap->field_read][0].kount)) - easycap_testcard(peasycap, peasycap->field_read); +if (0 <= input && INPUT_MANY > input) { + if (bars && VIDEO_LOST_TOLERATE <= peasycap->lost[input]) + easycap_testcard(peasycap, peasycap->field_read); +} #endif /*EASYCAP_TESTCARD*/ /*---------------------------------------------------------------------------*/ @@ -3491,6 +3526,8 @@ if (0 == bInterfaceNumber) { peasycap->frame_buffer_many = FRAME_BUFFER_MANY; + for (k = 0; k < INPUT_MANY; k++) + peasycap->lost[k] = 0; peasycap->skip = 0; peasycap->skipped = 0; peasycap->offerfields = 0; @@ -4733,7 +4770,7 @@ easycap_module_init(void) int result; SAY("========easycap=======\n"); -JOT(4, "begins. %i=debug\n", debug); +JOT(4, "begins. %i=debug %i=bars\n", debug, bars); SAY("version: " EASYCAP_DRIVER_VERSION "\n"); /*---------------------------------------------------------------------------*/ /* @@ -4774,6 +4811,8 @@ MODULE_AUTHOR("R.M. Thomas "); MODULE_DESCRIPTION(EASYCAP_DRIVER_DESCRIPTION); MODULE_VERSION(EASYCAP_DRIVER_VERSION); #if defined(EASYCAP_DEBUG) -MODULE_PARM_DESC(debug, "debug: 0 (default), 1, 2,..."); +MODULE_PARM_DESC(debug, "Debug level: 0 (default),1,2,...,9"); #endif /*EASYCAP_DEBUG*/ +MODULE_PARM_DESC(bars, \ + "Testcard bars on input signal failure: 0=>no, 1=>yes(default)"); /*****************************************************************************/ diff --git a/drivers/staging/easycap/easycap_testcard.c b/drivers/staging/easycap/easycap_testcard.c index dd98b471d5b8..e27dfe9a9ba3 100644 --- a/drivers/staging/easycap/easycap_testcard.c +++ b/drivers/staging/easycap/easycap_testcard.c @@ -29,37 +29,69 @@ #include "easycap_debug.h" /*****************************************************************************/ -#define TESTCARD_BYTESPERLINE (2 * 1440) +#define TESTCARD_BYTESPERLINE (2 * 720) void -easycap_testcard(struct easycap *peasycap, int field_fill) +easycap_testcard(struct easycap *peasycap, int field) { int total; int y, u, v, r, g, b; unsigned char uyvy[4]; - -int i1, line, k, m, n, more, much, barwidth; +int i1, line, k, m, n, more, much, barwidth, barheight; unsigned char bfbar[TESTCARD_BYTESPERLINE / 8], *p1, *p2; struct data_buffer *pfield_buffer; -JOT(8, "%i=field_fill\n", field_fill); - -if ((TESTCARD_BYTESPERLINE / 2) < peasycap->width) { - SAY("ERROR: image is too wide\n"); +if (NULL == peasycap) { + SAY("ERROR: peasycap is NULL\n"); + return; +} +JOM(8, "%i=field\n", field); +switch (peasycap->width) { +case 720: +case 360: { + barwidth = (2 * 720) / 8; + break; +} +case 704: +case 352: { + barwidth = (2 * 704) / 8; + break; +} +case 640: +case 320: { + barwidth = (2 * 640) / 8; + break; +} +default: { + SAM("ERROR: cannot set barwidth\n"); return; } -if (peasycap->width % 16) { - SAY("ERROR: indivisible image width\n"); +} +if (TESTCARD_BYTESPERLINE < barwidth) { + SAM("ERROR: barwidth is too large\n"); return; } - +switch (peasycap->height) { +case 576: +case 288: { + barheight = 576; + break; +} +case 480: +case 240: { + barheight = 480; + break; +} +default: { + SAM("ERROR: cannot set barheight\n"); + return; +} +} total = 0; -barwidth = (2 * peasycap->width) / 8; - -k = field_fill; +k = field; m = 0; n = 0; -for (line = 0; line < (peasycap->height / 2); line++) { +for (line = 0; line < (barheight / 2); line++) { for (i1 = 0; i1 < 8; i1++) { r = (i1 * 256)/8; g = (i1 * 256)/8; @@ -88,15 +120,15 @@ for (line = 0; line < (peasycap->height / 2); line++) { while (more) { if ((FIELD_BUFFER_SIZE/PAGE_SIZE) <= m) { - SAY("ERROR: bad m reached\n"); + SAM("ERROR: bad m reached\n"); return; } if (PAGE_SIZE < n) { - SAY("ERROR: bad n reached\n"); return; + SAM("ERROR: bad n reached\n"); return; } if (0 > more) { - SAY("ERROR: internal fault\n"); + SAM("ERROR: internal fault\n"); return; } @@ -117,10 +149,6 @@ for (line = 0; line < (peasycap->height / 2); line++) { } } } - -JOT(8, "%i=total\n", total); -if (total != peasycap->width * peasycap->height) - SAY("ERROR: wrong number of bytes written: %i\n", total); return; } /*****************************************************************************/ @@ -375,10 +403,12 @@ int i1; unsigned char *p2; struct data_buffer *paudio_buffer; -JOT(8, "%i=audio_fill\n", audio_fill); - +if (NULL == peasycap) { + SAY("ERROR: peasycap is NULL\n"); + return; +} +JOM(8, "%i=audio_fill\n", audio_fill); paudio_buffer = &peasycap->audio_buffer[audio_fill]; - p2 = (unsigned char *)(paudio_buffer->pgo); for (i1 = 0; i1 < PAGE_SIZE; i1 += 4, p2 += 4) { *p2 = (unsigned char) (0x00FF & tones[i1/2]); -- cgit v1.2.3 From 94155cf4195bb3be0068481dc21e8688eda2e051 Mon Sep 17 00:00:00 2001 From: Mike Thomas Date: Sun, 7 Nov 2010 20:05:51 +0000 Subject: staging/easycap: Add option to set the hardware audio gain A new module parameter adjusts the gain of the AC'97 audio chip, if one is present. Attenuation as well as amplification should be possible according to the datasheet, but attenuation seems not to work yet. Signed-off-by: Mike Thomas Signed-off-by: Greg Kroah-Hartman --- drivers/staging/easycap/easycap_debug.h | 1 + drivers/staging/easycap/easycap_ioctl.c | 14 +++- drivers/staging/easycap/easycap_low.c | 120 +++++++++++++++++++++----------- drivers/staging/easycap/easycap_main.c | 8 ++- 4 files changed, 96 insertions(+), 47 deletions(-) diff --git a/drivers/staging/easycap/easycap_debug.h b/drivers/staging/easycap/easycap_debug.h index a4dcd7dd4a89..7042fe8e31fe 100644 --- a/drivers/staging/easycap/easycap_debug.h +++ b/drivers/staging/easycap/easycap_debug.h @@ -25,3 +25,4 @@ */ /*****************************************************************************/ extern int debug; +extern int gain; diff --git a/drivers/staging/easycap/easycap_ioctl.c b/drivers/staging/easycap/easycap_ioctl.c index 3fe13851aba0..7c46cb22daeb 100644 --- a/drivers/staging/easycap/easycap_ioctl.c +++ b/drivers/staging/easycap/easycap_ioctl.c @@ -873,18 +873,26 @@ i1 = 0; while (0xFFFFFFFF != easycap_control[i1].id) { if (V4L2_CID_AUDIO_VOLUME == easycap_control[i1].id) { if ((easycap_control[i1].minimum > value) || \ - (easycap_control[i1].maximum < value)) + (easycap_control[i1].maximum < value)) value = easycap_control[i1].default_value; + if ((easycap_control[i1].minimum <= peasycap->volume) && \ + (easycap_control[i1].maximum >= \ + peasycap->volume)) { + if (peasycap->volume == value) { + SAM("unchanged volume at 0x%02X\n", value); + return 0; + } + } peasycap->volume = value; mood = (16 > peasycap->volume) ? 16 : \ ((31 < peasycap->volume) ? 31 : \ (__s8) peasycap->volume); if (!audio_gainset(peasycap->pusb_device, mood)) { - SAM("adjusting volume to 0x%01X\n", mood); + SAM("adjusting volume to 0x%02X\n", mood); return 0; } else { SAM("WARNING: failed to adjust volume to " \ - "0x%1X\n", mood); + "0x%2X\n", mood); return -ENOENT; } break; diff --git a/drivers/staging/easycap/easycap_low.c b/drivers/staging/easycap/easycap_low.c index 4badef263e9e..7d778ba67ac8 100644 --- a/drivers/staging/easycap/easycap_low.c +++ b/drivers/staging/easycap/easycap_low.c @@ -988,9 +988,9 @@ if (NULL == peasycap) pusb_device = peasycap->pusb_device; if (NULL == pusb_device) - return -EFAULT; + return -ENODEV; -JOT(8, "%02X %02X %02X %02X %02X %02X %02X %02X\n", \ +JOM(8, "%02X %02X %02X %02X %02X %02X %02X %02X\n", \ requesttype, request, \ (0x00FF & value_unmute), \ (0xFF00 & value_unmute) >> 8, \ @@ -1029,41 +1029,25 @@ if (rc != (int)length) * THE UPPER BYTE SEEMS TO HAVE NO EFFECT. */ /*--------------------------------------------------------------------------*/ - SET(pusb_device, 0x0500, 0x0094); - SET(pusb_device, 0x0500, 0x008C); - SET(pusb_device, 0x0506, 0x0001); SET(pusb_device, 0x0507, 0x0000); - id1 = read_vt(pusb_device, 0x007C); id2 = read_vt(pusb_device, 0x007E); -SAY("0x%04X:0x%04X is audio vendor id\n", id1, id2); - +SAM("0x%04X:0x%04X is audio vendor id\n", id1, id2); /*---------------------------------------------------------------------------*/ /* -* SELECT AUDIO SOURCE "LINE IN" AND SET DEFAULT GAIN TO 0 dB. -* -* THESE COMMANDS SEEM TO BE ACCEPTED (THOUGH POSSIBLY IGNORED) EVEN WHEN -* THERE IS NO SEPARATE AUDIO CHIP PRESENT. + * SELECT AUDIO SOURCE "LINE IN" AND SET THE AUDIO GAIN. */ /*---------------------------------------------------------------------------*/ - -write_vt(pusb_device, 0x0002, 0x8000); -write_vt(pusb_device, 0x001C, 0x8000); - -write_vt(pusb_device, 0x000E, 0x0000); -write_vt(pusb_device, 0x0010, 0x0000); -write_vt(pusb_device, 0x0012, 0x8000); -write_vt(pusb_device, 0x0016, 0x0000); - -write_vt(pusb_device, 0x001A, 0x0404); -write_vt(pusb_device, 0x0002, 0x0000); -write_vt(pusb_device, 0x001C, 0x0000); - +if (31 < gain) + gain = 31; +if (0 > gain) + gain = 0; +if (0 != audio_gainset(pusb_device, (__s8)gain)) + SAY("ERROR: audio_gainset() failed\n"); check_vt(pusb_device); - return 0; } /*****************************************************************************/ @@ -1096,17 +1080,23 @@ if (0 > igot) if (0x8000 & igot) SAY("register 0x%02X muted\n", 0x12); +igot = read_vt(pusb_device, 0x0014); +if (0 > igot) + SAY("ERROR: failed to read VT1612A register 0x14\n"); +if (0x8000 & igot) + SAY("register 0x%02X muted\n", 0x14); + igot = read_vt(pusb_device, 0x0016); if (0 > igot) SAY("ERROR: failed to read VT1612A register 0x16\n"); if (0x8000 & igot) SAY("register 0x%02X muted\n", 0x16); -igot = read_vt(pusb_device, 0x001A); +igot = read_vt(pusb_device, 0x0018); if (0 > igot) - SAY("ERROR: failed to read VT1612A register 0x1A\n"); + SAY("ERROR: failed to read VT1612A register 0x18\n"); if (0x8000 & igot) - SAY("register 0x%02X muted\n", 0x1A); + SAY("register 0x%02X muted\n", 0x18); igot = read_vt(pusb_device, 0x001C); if (0 > igot) @@ -1118,14 +1108,18 @@ return 0; } /*****************************************************************************/ /*---------------------------------------------------------------------------*/ -/* - * NOTE: THIS DOES INCREASE THE VOLUME DRAMATICALLY: - * audio_gainset(pusb_device, 0x000F); +/* NOTE: THIS DOES INCREASE THE VOLUME DRAMATICALLY: + * audio_gainset(pusb_device, 0x000F); * - * IF 16 loud) - loud = 16; -u8 = 0x000F & (__u8)(loud - 16); +if ((struct usb_device *)NULL == pusb_device) + return -ENODEV; +if (0 > loud) + loud = 0; +if (31 < loud) + loud = 31; write_vt(pusb_device, 0x0002, 0x8000); +/*---------------------------------------------------------------------------*/ +igot = read_vt(pusb_device, 0x000E); +if (0 > igot) { + SAY("ERROR: failed to read VT1612A register 0x0E\n"); + mute = 0x0000; +} else + mute = 0x8000 & ((unsigned int)igot); +mute = 0; +if (16 > loud) + u8 = 0x01 | (0x001F & (((__u8)(15 - loud)) << 1)); +else + u8 = 0; + +JOT(8, "0x%04X=(mute|u8) for VT1612A register 0x0E\n", mute | u8); +write_vt(pusb_device, 0x000E, (mute | u8)); +/*---------------------------------------------------------------------------*/ +igot = read_vt(pusb_device, 0x0010); +if (0 > igot) { + SAY("ERROR: failed to read VT1612A register 0x10\n"); + mute = 0x0000; +} else + mute = 0x8000 & ((unsigned int)igot); +mute = 0; + +JOT(8, "0x%04X=(mute|u8|(u8<<8)) for VT1612A register 0x10,...0x18\n", \ + mute | u8 | (u8 << 8)); +write_vt(pusb_device, 0x0010, (mute | u8 | (u8 << 8))); +write_vt(pusb_device, 0x0012, (mute | u8 | (u8 << 8))); +write_vt(pusb_device, 0x0014, (mute | u8 | (u8 << 8))); +write_vt(pusb_device, 0x0016, (mute | u8 | (u8 << 8))); +write_vt(pusb_device, 0x0018, (mute | u8 | (u8 << 8))); +/*---------------------------------------------------------------------------*/ igot = read_vt(pusb_device, 0x001C); if (0 > igot) { SAY("ERROR: failed to read VT1612A register 0x1C\n"); mute = 0x0000; } else mute = 0x8000 & ((unsigned int)igot); +mute = 0; -JOT(8, "0x%04X=(mute|u8|(u8<<8))\n", mute | u8 | (u8 << 8)); +if (16 <= loud) + u8 = 0x000F & (__u8)(loud - 16); +else + u8 = 0; -write_vt(pusb_device, 0x001C, 0x8000); +JOT(8, "0x%04X=(mute|u8|(u8<<8)) for VT1612A register 0x1C\n", \ + mute | u8 | (u8 << 8)); write_vt(pusb_device, 0x001C, (mute | u8 | (u8 << 8))); +write_vt(pusb_device, 0x001A, 0x0404); write_vt(pusb_device, 0x0002, 0x0000); - return 0; } /*****************************************************************************/ @@ -1161,6 +1195,8 @@ audio_gainget(struct usb_device *pusb_device) { int igot; +if (NULL == pusb_device) + return -ENODEV; igot = read_vt(pusb_device, 0x001C); if (0 > igot) SAY("ERROR: failed to read VT1612A register 0x1C\n"); diff --git a/drivers/staging/easycap/easycap_main.c b/drivers/staging/easycap/easycap_main.c index 21450e83530f..ee5c8d990bdf 100644 --- a/drivers/staging/easycap/easycap_main.c +++ b/drivers/staging/easycap/easycap_main.c @@ -34,8 +34,10 @@ int debug; int bars; +int gain = 16; module_param(debug, int, S_IRUGO | S_IWUSR); module_param(bars, int, S_IRUGO | S_IWUSR); +module_param(gain, int, S_IRUGO | S_IWUSR); /*---------------------------------------------------------------------------*/ /* @@ -4770,7 +4772,8 @@ easycap_module_init(void) int result; SAY("========easycap=======\n"); -JOT(4, "begins. %i=debug %i=bars\n", debug, bars); +JOT(4, "begins. %i=debug %i=bars %i=gain\n", debug, bars, \ + gain); SAY("version: " EASYCAP_DRIVER_VERSION "\n"); /*---------------------------------------------------------------------------*/ /* @@ -4811,8 +4814,9 @@ MODULE_AUTHOR("R.M. Thomas "); MODULE_DESCRIPTION(EASYCAP_DRIVER_DESCRIPTION); MODULE_VERSION(EASYCAP_DRIVER_VERSION); #if defined(EASYCAP_DEBUG) -MODULE_PARM_DESC(debug, "Debug level: 0 (default),1,2,...,9"); +MODULE_PARM_DESC(debug, "Debug level: 0 (default),1,2,..."); #endif /*EASYCAP_DEBUG*/ MODULE_PARM_DESC(bars, \ "Testcard bars on input signal failure: 0=>no, 1=>yes(default)"); +MODULE_PARM_DESC(gain, "Audio gain: 0,...,16(default),...31"); /*****************************************************************************/ -- cgit v1.2.3 From 2a87a0b9220f8e0e6f204b0f61dc6e15ad64ccd4 Mon Sep 17 00:00:00 2001 From: Mike Thomas Date: Sun, 7 Nov 2010 20:07:12 +0000 Subject: staging/easycap: Avoid compiler warning about frame size ... larger than ... Replacing some of the large automatic variables by dynamically allocated variables in the IOCTL routines gets rid of the compiler warning. Signed-off-by: Mike Thomas Signed-off-by: Greg Kroah-Hartman --- drivers/staging/easycap/easycap_ioctl.c | 155 ++++++++++++++++++++------------ 1 file changed, 96 insertions(+), 59 deletions(-) diff --git a/drivers/staging/easycap/easycap_ioctl.c b/drivers/staging/easycap/easycap_ioctl.c index 7c46cb22daeb..5e9133b29dd0 100644 --- a/drivers/staging/easycap/easycap_ioctl.c +++ b/drivers/staging/easycap/easycap_ioctl.c @@ -956,8 +956,8 @@ return -ENOENT; static int easycap_ioctl_bkl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { -static struct easycap *peasycap; -static struct usb_device *p; +struct easycap *peasycap; +struct usb_device *p; if (NULL == file) { SAY("ERROR: file is NULL\n"); @@ -974,13 +974,6 @@ if (NULL == p) { return -EFAULT; } /*---------------------------------------------------------------------------*/ -/* - * MOST OF THE VARIABLES DECLARED static IN THE case{} BLOCKS BELOW ARE SO - * DECLARED SIMPLY TO AVOID A COMPILER WARNING OF THE KIND: - * easycap_ioctl.c: warning: - * the frame size of ... bytes is larger than 1024 bytes - */ -/*---------------------------------------------------------------------------*/ switch (cmd) { case VIDIOC_QUERYCAP: { struct v4l2_capability v4l2_capability; @@ -1247,57 +1240,67 @@ case VIDIOC_QUERYMENU: { } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ case VIDIOC_G_CTRL: { - struct v4l2_control v4l2_control; + struct v4l2_control *pv4l2_control; JOM(8, "VIDIOC_G_CTRL\n"); - - if (0 != copy_from_user(&v4l2_control, (void __user *)arg, \ - sizeof(struct v4l2_control))) + pv4l2_control = kzalloc(sizeof(struct v4l2_control), GFP_KERNEL); + if (!pv4l2_control) { + SAM("ERROR: out of memory\n"); + return -ENOMEM; + } + if (0 != copy_from_user(pv4l2_control, (void __user *)arg, \ + sizeof(struct v4l2_control))) { + kfree(pv4l2_control); return -EFAULT; + } - switch (v4l2_control.id) { + switch (pv4l2_control->id) { case V4L2_CID_BRIGHTNESS: { - v4l2_control.value = peasycap->brightness; - JOM(8, "user enquires brightness: %i\n", v4l2_control.value); + pv4l2_control->value = peasycap->brightness; + JOM(8, "user enquires brightness: %i\n", pv4l2_control->value); break; } case V4L2_CID_CONTRAST: { - v4l2_control.value = peasycap->contrast; - JOM(8, "user enquires contrast: %i\n", v4l2_control.value); + pv4l2_control->value = peasycap->contrast; + JOM(8, "user enquires contrast: %i\n", pv4l2_control->value); break; } case V4L2_CID_SATURATION: { - v4l2_control.value = peasycap->saturation; - JOM(8, "user enquires saturation: %i\n", v4l2_control.value); + pv4l2_control->value = peasycap->saturation; + JOM(8, "user enquires saturation: %i\n", pv4l2_control->value); break; } case V4L2_CID_HUE: { - v4l2_control.value = peasycap->hue; - JOM(8, "user enquires hue: %i\n", v4l2_control.value); + pv4l2_control->value = peasycap->hue; + JOM(8, "user enquires hue: %i\n", pv4l2_control->value); break; } case V4L2_CID_AUDIO_VOLUME: { - v4l2_control.value = peasycap->volume; - JOM(8, "user enquires volume: %i\n", v4l2_control.value); + pv4l2_control->value = peasycap->volume; + JOM(8, "user enquires volume: %i\n", pv4l2_control->value); break; } case V4L2_CID_AUDIO_MUTE: { if (1 == peasycap->mute) - v4l2_control.value = true; + pv4l2_control->value = true; else - v4l2_control.value = false; - JOM(8, "user enquires mute: %i\n", v4l2_control.value); + pv4l2_control->value = false; + JOM(8, "user enquires mute: %i\n", pv4l2_control->value); break; } default: { SAM("ERROR: unknown V4L2 control: 0x%08X=id\n", \ - v4l2_control.id); + pv4l2_control->id); + kfree(pv4l2_control); return -EINVAL; } } - if (0 != copy_to_user((void __user *)arg, &v4l2_control, \ - sizeof(struct v4l2_control))) + if (0 != copy_to_user((void __user *)arg, pv4l2_control, \ + sizeof(struct v4l2_control))) { + kfree(pv4l2_control); return -EFAULT; + } + kfree(pv4l2_control); break; } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ @@ -1596,8 +1599,9 @@ case VIDIOC_ENUM_FRAMEINTERVALS: { } if (0 != copy_from_user(&v4l2_frmivalenum, (void __user *)arg, \ - sizeof(struct v4l2_frmivalenum))) + sizeof(struct v4l2_frmivalenum))) { return -EFAULT; + } index = v4l2_frmivalenum.index; @@ -1632,29 +1636,50 @@ case VIDIOC_ENUM_FRAMEINTERVALS: { } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ case VIDIOC_G_FMT: { - struct v4l2_format v4l2_format; - struct v4l2_pix_format v4l2_pix_format; + struct v4l2_format *pv4l2_format; + struct v4l2_pix_format *pv4l2_pix_format; JOM(8, "VIDIOC_G_FMT\n"); - - if (0 != copy_from_user(&v4l2_format, (void __user *)arg, \ - sizeof(struct v4l2_format))) + pv4l2_format = kzalloc(sizeof(struct v4l2_format), GFP_KERNEL); + if (!pv4l2_format) { + SAM("ERROR: out of memory\n"); + return -ENOMEM; + } + pv4l2_pix_format = kzalloc(sizeof(struct v4l2_pix_format), GFP_KERNEL); + if (!pv4l2_pix_format) { + SAM("ERROR: out of memory\n"); + kfree(pv4l2_format); + return -ENOMEM; + } + if (0 != copy_from_user(pv4l2_format, (void __user *)arg, \ + sizeof(struct v4l2_format))) { + kfree(pv4l2_format); + kfree(pv4l2_pix_format); return -EFAULT; + } - if (v4l2_format.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + if (pv4l2_format->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { + kfree(pv4l2_format); + kfree(pv4l2_pix_format); return -EINVAL; + } - memset(&v4l2_pix_format, 0, sizeof(struct v4l2_pix_format)); - v4l2_format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; - memcpy(&(v4l2_format.fmt.pix), \ - &(easycap_format[peasycap->format_offset]\ - .v4l2_format.fmt.pix), sizeof(v4l2_pix_format)); + memset(pv4l2_pix_format, 0, sizeof(struct v4l2_pix_format)); + pv4l2_format->type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + memcpy(&pv4l2_format->fmt.pix, \ + &easycap_format[peasycap->format_offset]\ + .v4l2_format.fmt.pix, sizeof(struct v4l2_pix_format)); JOM(8, "user is told: %s\n", \ &easycap_format[peasycap->format_offset].name[0]); - if (0 != copy_to_user((void __user *)arg, &v4l2_format, \ - sizeof(struct v4l2_format))) + if (0 != copy_to_user((void __user *)arg, pv4l2_format, \ + sizeof(struct v4l2_format))) { + kfree(pv4l2_format); + kfree(pv4l2_pix_format); return -EFAULT; + } + kfree(pv4l2_format); + kfree(pv4l2_pix_format); break; } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ @@ -2196,38 +2221,50 @@ case VIDIOC_STREAMOFF: { } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ case VIDIOC_G_PARM: { - struct v4l2_streamparm v4l2_streamparm; + struct v4l2_streamparm *pv4l2_streamparm; JOM(8, "VIDIOC_G_PARM\n"); - - if (0 != copy_from_user(&v4l2_streamparm, (void __user *)arg, \ - sizeof(struct v4l2_streamparm))) + pv4l2_streamparm = kzalloc(sizeof(struct v4l2_streamparm), GFP_KERNEL); + if (!pv4l2_streamparm) { + SAM("ERROR: out of memory\n"); + return -ENOMEM; + } + if (0 != copy_from_user(pv4l2_streamparm, (void __user *)arg, \ + sizeof(struct v4l2_streamparm))) { + kfree(pv4l2_streamparm); return -EFAULT; + } - if (v4l2_streamparm.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + if (pv4l2_streamparm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { + kfree(pv4l2_streamparm); return -EINVAL; - v4l2_streamparm.parm.capture.capability = 0; - v4l2_streamparm.parm.capture.capturemode = 0; - v4l2_streamparm.parm.capture.timeperframe.numerator = 1; + } + pv4l2_streamparm->parm.capture.capability = 0; + pv4l2_streamparm->parm.capture.capturemode = 0; + pv4l2_streamparm->parm.capture.timeperframe.numerator = 1; if (peasycap->fps) { - v4l2_streamparm.parm.capture.timeperframe.\ + pv4l2_streamparm->parm.capture.timeperframe.\ denominator = peasycap->fps; } else { if (true == peasycap->ntsc) { - v4l2_streamparm.parm.capture.timeperframe.\ + pv4l2_streamparm->parm.capture.timeperframe.\ denominator = 30; } else { - v4l2_streamparm.parm.capture.timeperframe.\ + pv4l2_streamparm->parm.capture.timeperframe.\ denominator = 25; } } - v4l2_streamparm.parm.capture.readbuffers = peasycap->frame_buffer_many; - v4l2_streamparm.parm.capture.extendedmode = 0; - if (0 != copy_to_user((void __user *)arg, &v4l2_streamparm, \ - sizeof(struct v4l2_streamparm))) + pv4l2_streamparm->parm.capture.readbuffers = \ + peasycap->frame_buffer_many; + pv4l2_streamparm->parm.capture.extendedmode = 0; + if (0 != copy_to_user((void __user *)arg, pv4l2_streamparm, \ + sizeof(struct v4l2_streamparm))) { + kfree(pv4l2_streamparm); return -EFAULT; + } + kfree(pv4l2_streamparm); break; } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ -- cgit v1.2.3 From ae59dad4fef271222d65ac6afe2889eb12ea6ca9 Mon Sep 17 00:00:00 2001 From: Mike Thomas Date: Sun, 7 Nov 2010 20:09:19 +0000 Subject: staging/easycap: Eliminate BKL No locking is required for normal operation of the driver, but locking is needed to prevent an Oops during some hot-unplugging scenarios. The BKL is replaced here by mutex locks together with traps to detect null pointers following asynchronous device disconnection. Signed-off-by: Mike Thomas Signed-off-by: Greg Kroah-Hartman --- drivers/staging/easycap/Kconfig | 1 - drivers/staging/easycap/Makefile | 1 + drivers/staging/easycap/easycap.h | 16 +- drivers/staging/easycap/easycap_debug.h | 1 + drivers/staging/easycap/easycap_ioctl.c | 426 +++++++++++++++++++++++++------- drivers/staging/easycap/easycap_low.c | 55 ++++- drivers/staging/easycap/easycap_main.c | 311 ++++++++++++++++------- drivers/staging/easycap/easycap_sound.c | 76 +++++- 8 files changed, 695 insertions(+), 192 deletions(-) diff --git a/drivers/staging/easycap/Kconfig b/drivers/staging/easycap/Kconfig index 9d5fe4ddc30a..bd96f39f2735 100644 --- a/drivers/staging/easycap/Kconfig +++ b/drivers/staging/easycap/Kconfig @@ -1,7 +1,6 @@ config EASYCAP tristate "EasyCAP USB ID 05e1:0408 support" depends on USB && VIDEO_DEV - depends on BKL # please fix ---help--- This is an integrated audio/video driver for EasyCAP cards with diff --git a/drivers/staging/easycap/Makefile b/drivers/staging/easycap/Makefile index 8a3d911aee5d..f1f2fbebf8f6 100644 --- a/drivers/staging/easycap/Makefile +++ b/drivers/staging/easycap/Makefile @@ -10,4 +10,5 @@ ccflags-y := -Wall ccflags-y += -DEASYCAP_IS_VIDEODEV_CLIENT ccflags-y += -DEASYCAP_NEEDS_V4L2_DEVICE_H ccflags-y += -DEASYCAP_NEEDS_V4L2_FOPS +ccflags-y += -DEASYCAP_NEEDS_UNLOCKED_IOCTL diff --git a/drivers/staging/easycap/easycap.h b/drivers/staging/easycap/easycap.h index e9410b74ffc4..762c6cea54c3 100644 --- a/drivers/staging/easycap/easycap.h +++ b/drivers/staging/easycap/easycap.h @@ -251,6 +251,12 @@ INTERLACE_MANY * STRUCTURE DEFINITIONS */ /*---------------------------------------------------------------------------*/ +struct easycap_dongle { +struct easycap *peasycap; +struct mutex mutex_video; +struct mutex mutex_audio; +}; +/*---------------------------------------------------------------------------*/ struct data_buffer { struct list_head list_head; void *pgo; @@ -491,7 +497,10 @@ struct data_buffer audio_buffer[]; void easycap_complete(struct urb *); int easycap_open(struct inode *, struct file *); int easycap_release(struct inode *, struct file *); -long easycap_ioctl(struct file *, unsigned int, unsigned long); +long easycap_ioctl_noinode(struct file *, unsigned int, \ + unsigned long); +int easycap_ioctl(struct inode *, struct file *, unsigned int, \ + unsigned long); /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ #if defined(EASYCAP_IS_VIDEODEV_CLIENT) @@ -538,7 +547,10 @@ void easysnd_complete(struct urb *); ssize_t easysnd_read(struct file *, char __user *, size_t, loff_t *); int easysnd_open(struct inode *, struct file *); int easysnd_release(struct inode *, struct file *); -long easysnd_ioctl(struct file *, unsigned int, unsigned long); +long easysnd_ioctl_noinode(struct file *, unsigned int, \ + unsigned long); +int easysnd_ioctl(struct inode *, struct file *, unsigned int, \ + unsigned long); unsigned int easysnd_poll(struct file *, poll_table *); void easysnd_delete(struct kref *); int submit_audio_urbs(struct easycap *); diff --git a/drivers/staging/easycap/easycap_debug.h b/drivers/staging/easycap/easycap_debug.h index 7042fe8e31fe..518392e0d72d 100644 --- a/drivers/staging/easycap/easycap_debug.h +++ b/drivers/staging/easycap/easycap_debug.h @@ -26,3 +26,4 @@ /*****************************************************************************/ extern int debug; extern int gain; +extern struct easycap_dongle easycap_dongle[]; diff --git a/drivers/staging/easycap/easycap_ioctl.c b/drivers/staging/easycap/easycap_ioctl.c index 5e9133b29dd0..2f9b3eab4898 100644 --- a/drivers/staging/easycap/easycap_ioctl.c +++ b/drivers/staging/easycap/easycap_ioctl.c @@ -953,11 +953,23 @@ SAM("WARNING: failed to adjust mute: control not found\n"); return -ENOENT; } /*****************************************************************************/ -static int easycap_ioctl_bkl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) +/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +#if ((defined(EASYCAP_IS_VIDEODEV_CLIENT)) || \ + (defined(EASYCAP_NEEDS_UNLOCKED_IOCTL))) +long +easycap_ioctl_noinode(struct file *file, unsigned int cmd, unsigned long arg) { + return (long)easycap_ioctl((struct inode *)NULL, file, cmd, arg); +} +#endif /*EASYCAP_IS_VIDEODEV_CLIENT||EASYCAP_NEEDS_UNLOCKED_IOCTL*/ +/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +/*---------------------------------------------------------------------------*/ +int +easycap_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg) { struct easycap *peasycap; struct usb_device *p; +int kd; if (NULL == file) { SAY("ERROR: file is NULL\n"); @@ -973,6 +985,48 @@ if (NULL == p) { SAM("ERROR: peasycap->pusb_device is NULL\n"); return -EFAULT; } +kd = isdongle(peasycap); +if (0 <= kd && DONGLE_MANY > kd) { + if (mutex_lock_interruptible(&easycap_dongle[kd].mutex_video)) { + SAY("ERROR: cannot lock easycap_dongle[%i].mutex_video\n", kd); + return -ERESTARTSYS; + } + JOM(4, "locked easycap_dongle[%i].mutex_video\n", kd); +/*---------------------------------------------------------------------------*/ +/* + * MEANWHILE, easycap_usb_disconnect() MAY HAVE FREED POINTER peasycap, + * IN WHICH CASE A REPEAT CALL TO isdongle() WILL FAIL. + * IF NECESSARY, BAIL OUT. +*/ +/*---------------------------------------------------------------------------*/ + if (kd != isdongle(peasycap)) + return -ERESTARTSYS; + if (NULL == file) { + SAY("ERROR: file is NULL\n"); + mutex_unlock(&easycap_dongle[kd].mutex_video); + return -ERESTARTSYS; + } + peasycap = file->private_data; + if (NULL == peasycap) { + SAY("ERROR: peasycap is NULL\n"); + mutex_unlock(&easycap_dongle[kd].mutex_video); + return -ERESTARTSYS; + } + p = peasycap->pusb_device; + if (NULL == peasycap->pusb_device) { + SAM("ERROR: peasycap->pusb_device is NULL\n"); + mutex_unlock(&easycap_dongle[kd].mutex_video); + return -ERESTARTSYS; + } +} else { +/*---------------------------------------------------------------------------*/ +/* + * IF easycap_usb_disconnect() HAS ALREADY FREED POINTER peasycap BEFORE THE + * ATTEMPT TO ACQUIRE THE SEMAPHORE, isdongle() WILL HAVE FAILED. BAIL OUT. +*/ +/*---------------------------------------------------------------------------*/ + return -ERESTARTSYS; +} /*---------------------------------------------------------------------------*/ switch (cmd) { case VIDIOC_QUERYCAP: { @@ -984,7 +1038,9 @@ case VIDIOC_QUERYCAP: { JOM(8, "VIDIOC_QUERYCAP\n"); if (16 <= strlen(EASYCAP_DRIVER_VERSION)) { - SAM("ERROR: bad driver version string\n"); return -EINVAL; + SAM("ERROR: bad driver version string\n"); + mutex_unlock(&easycap_dongle[kd].mutex_video); + return -EINVAL; } strcpy(&version[0], EASYCAP_DRIVER_VERSION); for (i = 0; i < 3; i++) @@ -1001,6 +1057,7 @@ case VIDIOC_QUERYCAP: { if (0 != rc) { SAM("ERROR: %i=strict_strtol(%s,.,,)\n", \ rc, p1); + mutex_unlock(&easycap_dongle[kd].mutex_video); return -EINVAL; } k[i] = (int)lng; @@ -1030,8 +1087,10 @@ case VIDIOC_QUERYCAP: { &v4l2_capability.bus_info[0]); } if (0 != copy_to_user((void __user *)arg, &v4l2_capability, \ - sizeof(struct v4l2_capability))) + sizeof(struct v4l2_capability))) { + mutex_unlock(&easycap_dongle[kd].mutex_video); return -EFAULT; + } break; } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ @@ -1042,8 +1101,10 @@ case VIDIOC_ENUMINPUT: { JOM(8, "VIDIOC_ENUMINPUT\n"); if (0 != copy_from_user(&v4l2_input, (void __user *)arg, \ - sizeof(struct v4l2_input))) + sizeof(struct v4l2_input))) { + mutex_unlock(&easycap_dongle[kd].mutex_video); return -EFAULT; + } index = v4l2_input.index; memset(&v4l2_input, 0, sizeof(struct v4l2_input)); @@ -1123,13 +1184,16 @@ case VIDIOC_ENUMINPUT: { } default: { JOM(8, "%i=index: exhausts inputs\n", index); + mutex_unlock(&easycap_dongle[kd].mutex_video); return -EINVAL; } } if (0 != copy_to_user((void __user *)arg, &v4l2_input, \ - sizeof(struct v4l2_input))) + sizeof(struct v4l2_input))) { + mutex_unlock(&easycap_dongle[kd].mutex_video); return -EFAULT; + } break; } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ @@ -1139,8 +1203,10 @@ case VIDIOC_G_INPUT: { JOM(8, "VIDIOC_G_INPUT\n"); index = (__u32)peasycap->input; JOM(8, "user is told: %i\n", index); - if (0 != copy_to_user((void __user *)arg, &index, sizeof(__u32))) + if (0 != copy_to_user((void __user *)arg, &index, sizeof(__u32))) { + mutex_unlock(&easycap_dongle[kd].mutex_video); return -EFAULT; + } break; } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ @@ -1151,8 +1217,10 @@ case VIDIOC_S_INPUT: JOM(8, "VIDIOC_S_INPUT\n"); - if (0 != copy_from_user(&index, (void __user *)arg, sizeof(__u32))) + if (0 != copy_from_user(&index, (void __user *)arg, sizeof(__u32))) { + mutex_unlock(&easycap_dongle[kd].mutex_video); return -EFAULT; + } JOM(8, "user requests input %i\n", index); @@ -1163,6 +1231,7 @@ case VIDIOC_S_INPUT: if ((0 > index) || (INPUT_MANY <= index)) { JOM(8, "ERROR: bad requested input: %i\n", index); + mutex_unlock(&easycap_dongle[kd].mutex_video); return -EINVAL; } @@ -1171,6 +1240,7 @@ case VIDIOC_S_INPUT: JOM(8, "newinput(.,%i) OK\n", (int)index); } else { SAM("ERROR: newinput(.,%i) returned %i\n", (int)index, rc); + mutex_unlock(&easycap_dongle[kd].mutex_video); return -EFAULT; } break; @@ -1178,6 +1248,7 @@ case VIDIOC_S_INPUT: /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ case VIDIOC_ENUMAUDIO: { JOM(8, "VIDIOC_ENUMAUDIO\n"); + mutex_unlock(&easycap_dongle[kd].mutex_video); return -EINVAL; } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ @@ -1187,18 +1258,24 @@ case VIDIOC_ENUMAUDOUT: { JOM(8, "VIDIOC_ENUMAUDOUT\n"); if (0 != copy_from_user(&v4l2_audioout, (void __user *)arg, \ - sizeof(struct v4l2_audioout))) + sizeof(struct v4l2_audioout))) { + mutex_unlock(&easycap_dongle[kd].mutex_video); return -EFAULT; + } - if (0 != v4l2_audioout.index) + if (0 != v4l2_audioout.index) { + mutex_unlock(&easycap_dongle[kd].mutex_video); return -EINVAL; + } memset(&v4l2_audioout, 0, sizeof(struct v4l2_audioout)); v4l2_audioout.index = 0; strcpy(&v4l2_audioout.name[0], "Soundtrack"); if (0 != copy_to_user((void __user *)arg, &v4l2_audioout, \ - sizeof(struct v4l2_audioout))) + sizeof(struct v4l2_audioout))) { + mutex_unlock(&easycap_dongle[kd].mutex_video); return -EFAULT; + } break; } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ @@ -1209,8 +1286,10 @@ case VIDIOC_QUERYCTRL: { JOM(8, "VIDIOC_QUERYCTRL\n"); if (0 != copy_from_user(&v4l2_queryctrl, (void __user *)arg, \ - sizeof(struct v4l2_queryctrl))) + sizeof(struct v4l2_queryctrl))) { + mutex_unlock(&easycap_dongle[kd].mutex_video); return -EFAULT; + } i1 = 0; while (0xFFFFFFFF != easycap_control[i1].id) { @@ -1225,18 +1304,21 @@ case VIDIOC_QUERYCTRL: { } if (0xFFFFFFFF == easycap_control[i1].id) { JOM(8, "%i=index: exhausts controls\n", i1); + mutex_unlock(&easycap_dongle[kd].mutex_video); return -EINVAL; } if (0 != copy_to_user((void __user *)arg, &v4l2_queryctrl, \ - sizeof(struct v4l2_queryctrl))) + sizeof(struct v4l2_queryctrl))) { + mutex_unlock(&easycap_dongle[kd].mutex_video); return -EFAULT; + } break; } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ case VIDIOC_QUERYMENU: { JOM(8, "VIDIOC_QUERYMENU unsupported\n"); + mutex_unlock(&easycap_dongle[kd].mutex_video); return -EINVAL; - break; } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ case VIDIOC_G_CTRL: { @@ -1246,11 +1328,13 @@ case VIDIOC_G_CTRL: { pv4l2_control = kzalloc(sizeof(struct v4l2_control), GFP_KERNEL); if (!pv4l2_control) { SAM("ERROR: out of memory\n"); + mutex_unlock(&easycap_dongle[kd].mutex_video); return -ENOMEM; } if (0 != copy_from_user(pv4l2_control, (void __user *)arg, \ sizeof(struct v4l2_control))) { kfree(pv4l2_control); + mutex_unlock(&easycap_dongle[kd].mutex_video); return -EFAULT; } @@ -1292,12 +1376,14 @@ case VIDIOC_G_CTRL: { SAM("ERROR: unknown V4L2 control: 0x%08X=id\n", \ pv4l2_control->id); kfree(pv4l2_control); + mutex_unlock(&easycap_dongle[kd].mutex_video); return -EINVAL; } } if (0 != copy_to_user((void __user *)arg, pv4l2_control, \ sizeof(struct v4l2_control))) { kfree(pv4l2_control); + mutex_unlock(&easycap_dongle[kd].mutex_video); return -EFAULT; } kfree(pv4l2_control); @@ -1316,8 +1402,10 @@ case VIDIOC_S_CTRL: JOM(8, "VIDIOC_S_CTRL\n"); if (0 != copy_from_user(&v4l2_control, (void __user *)arg, \ - sizeof(struct v4l2_control))) + sizeof(struct v4l2_control))) { + mutex_unlock(&easycap_dongle[kd].mutex_video); return -EFAULT; + } switch (v4l2_control.id) { case V4L2_CID_BRIGHTNESS: { @@ -1366,14 +1454,16 @@ case VIDIOC_S_CTRL: default: { SAM("ERROR: unknown V4L2 control: 0x%08X=id\n", \ v4l2_control.id); + mutex_unlock(&easycap_dongle[kd].mutex_video); return -EINVAL; - } + } } break; } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ case VIDIOC_S_EXT_CTRLS: { JOM(8, "VIDIOC_S_EXT_CTRLS unsupported\n"); + mutex_unlock(&easycap_dongle[kd].mutex_video); return -EINVAL; } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ @@ -1384,8 +1474,10 @@ case VIDIOC_ENUM_FMT: { JOM(8, "VIDIOC_ENUM_FMT\n"); if (0 != copy_from_user(&v4l2_fmtdesc, (void __user *)arg, \ - sizeof(struct v4l2_fmtdesc))) + sizeof(struct v4l2_fmtdesc))) { + mutex_unlock(&easycap_dongle[kd].mutex_video); return -EFAULT; + } index = v4l2_fmtdesc.index; memset(&v4l2_fmtdesc, 0, sizeof(struct v4l2_fmtdesc)); @@ -1438,12 +1530,15 @@ case VIDIOC_ENUM_FMT: { } default: { JOM(8, "%i=index: exhausts formats\n", index); + mutex_unlock(&easycap_dongle[kd].mutex_video); return -EINVAL; } } if (0 != copy_to_user((void __user *)arg, &v4l2_fmtdesc, \ - sizeof(struct v4l2_fmtdesc))) + sizeof(struct v4l2_fmtdesc))) { + mutex_unlock(&easycap_dongle[kd].mutex_video); return -EFAULT; + } break; } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ @@ -1459,8 +1554,10 @@ case VIDIOC_ENUM_FRAMESIZES: { JOM(8, "VIDIOC_ENUM_FRAMESIZES\n"); if (0 != copy_from_user(&v4l2_frmsizeenum, (void __user *)arg, \ - sizeof(struct v4l2_frmsizeenum))) + sizeof(struct v4l2_frmsizeenum))) { + mutex_unlock(&easycap_dongle[kd].mutex_video); return -EFAULT; + } index = v4l2_frmsizeenum.index; @@ -1510,6 +1607,7 @@ case VIDIOC_ENUM_FRAMESIZES: { } default: { JOM(8, "%i=index: exhausts framesizes\n", index); + mutex_unlock(&easycap_dongle[kd].mutex_video); return -EINVAL; } } @@ -1567,13 +1665,16 @@ case VIDIOC_ENUM_FRAMESIZES: { } default: { JOM(8, "%i=index: exhausts framesizes\n", index); + mutex_unlock(&easycap_dongle[kd].mutex_video); return -EINVAL; } } } if (0 != copy_to_user((void __user *)arg, &v4l2_frmsizeenum, \ - sizeof(struct v4l2_frmsizeenum))) + sizeof(struct v4l2_frmsizeenum))) { + mutex_unlock(&easycap_dongle[kd].mutex_video); return -EFAULT; + } break; } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ @@ -1600,6 +1701,7 @@ case VIDIOC_ENUM_FRAMEINTERVALS: { if (0 != copy_from_user(&v4l2_frmivalenum, (void __user *)arg, \ sizeof(struct v4l2_frmivalenum))) { + mutex_unlock(&easycap_dongle[kd].mutex_video); return -EFAULT; } @@ -1626,12 +1728,15 @@ case VIDIOC_ENUM_FRAMEINTERVALS: { } default: { JOM(8, "%i=index: exhausts frameintervals\n", index); + mutex_unlock(&easycap_dongle[kd].mutex_video); return -EINVAL; } } if (0 != copy_to_user((void __user *)arg, &v4l2_frmivalenum, \ - sizeof(struct v4l2_frmivalenum))) + sizeof(struct v4l2_frmivalenum))) { + mutex_unlock(&easycap_dongle[kd].mutex_video); return -EFAULT; + } break; } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ @@ -1643,24 +1748,28 @@ case VIDIOC_G_FMT: { pv4l2_format = kzalloc(sizeof(struct v4l2_format), GFP_KERNEL); if (!pv4l2_format) { SAM("ERROR: out of memory\n"); - return -ENOMEM; + mutex_unlock(&easycap_dongle[kd].mutex_video); + return -ENOMEM; } pv4l2_pix_format = kzalloc(sizeof(struct v4l2_pix_format), GFP_KERNEL); if (!pv4l2_pix_format) { SAM("ERROR: out of memory\n"); kfree(pv4l2_format); + mutex_unlock(&easycap_dongle[kd].mutex_video); return -ENOMEM; } if (0 != copy_from_user(pv4l2_format, (void __user *)arg, \ sizeof(struct v4l2_format))) { kfree(pv4l2_format); kfree(pv4l2_pix_format); + mutex_unlock(&easycap_dongle[kd].mutex_video); return -EFAULT; } if (pv4l2_format->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { kfree(pv4l2_format); kfree(pv4l2_pix_format); + mutex_unlock(&easycap_dongle[kd].mutex_video); return -EINVAL; } @@ -1676,6 +1785,7 @@ case VIDIOC_G_FMT: { sizeof(struct v4l2_format))) { kfree(pv4l2_format); kfree(pv4l2_pix_format); + mutex_unlock(&easycap_dongle[kd].mutex_video); return -EFAULT; } kfree(pv4l2_format); @@ -1699,8 +1809,10 @@ case VIDIOC_S_FMT: { } if (0 != copy_from_user(&v4l2_format, (void __user *)arg, \ - sizeof(struct v4l2_format))) + sizeof(struct v4l2_format))) { + mutex_unlock(&easycap_dongle[kd].mutex_video); return -EFAULT; + } best_format = adjust_format(peasycap, \ v4l2_format.fmt.pix.width, \ @@ -1709,9 +1821,12 @@ case VIDIOC_S_FMT: { v4l2_format.fmt.pix.field, \ try); if (0 > best_format) { - if (-EBUSY == best_format) + if (-EBUSY == best_format) { + mutex_unlock(&easycap_dongle[kd].mutex_video); return -EBUSY; + } JOM(8, "WARNING: adjust_format() returned %i\n", best_format); + mutex_unlock(&easycap_dongle[kd].mutex_video); return -ENOENT; } /*...........................................................................*/ @@ -1723,8 +1838,10 @@ case VIDIOC_S_FMT: { JOM(8, "user is told: %s\n", &easycap_format[best_format].name[0]); if (0 != copy_to_user((void __user *)arg, &v4l2_format, \ - sizeof(struct v4l2_format))) + sizeof(struct v4l2_format))) { + mutex_unlock(&easycap_dongle[kd].mutex_video); return -EFAULT; + } break; } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ @@ -1734,8 +1851,10 @@ case VIDIOC_CROPCAP: { JOM(8, "VIDIOC_CROPCAP\n"); if (0 != copy_from_user(&v4l2_cropcap, (void __user *)arg, \ - sizeof(struct v4l2_cropcap))) + sizeof(struct v4l2_cropcap))) { + mutex_unlock(&easycap_dongle[kd].mutex_video); return -EFAULT; + } if (v4l2_cropcap.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) JOM(8, "v4l2_cropcap.type != V4L2_BUF_TYPE_VIDEO_CAPTURE\n"); @@ -1756,20 +1875,24 @@ case VIDIOC_CROPCAP: { JOM(8, "user is told: %ix%i\n", peasycap->width, peasycap->height); if (0 != copy_to_user((void __user *)arg, &v4l2_cropcap, \ - sizeof(struct v4l2_cropcap))) + sizeof(struct v4l2_cropcap))) { + mutex_unlock(&easycap_dongle[kd].mutex_video); return -EFAULT; + } break; } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ case VIDIOC_G_CROP: case VIDIOC_S_CROP: { JOM(8, "VIDIOC_G_CROP|VIDIOC_S_CROP unsupported\n"); + mutex_unlock(&easycap_dongle[kd].mutex_video); return -EINVAL; } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ case VIDIOC_QUERYSTD: { JOM(8, "VIDIOC_QUERYSTD: " \ "EasyCAP is incapable of detecting standard\n"); + mutex_unlock(&easycap_dongle[kd].mutex_video); return -EINVAL; break; } @@ -1790,8 +1913,10 @@ case VIDIOC_ENUMSTD: { JOM(8, "VIDIOC_ENUMSTD\n"); if (0 != copy_from_user(&v4l2_standard, (void __user *)arg, \ - sizeof(struct v4l2_standard))) + sizeof(struct v4l2_standard))) { + mutex_unlock(&easycap_dongle[kd].mutex_video); return -EFAULT; + } index = v4l2_standard.index; last3 = last2; last2 = last1; last1 = last0; last0 = index; @@ -1811,6 +1936,7 @@ case VIDIOC_ENUMSTD: { } if (0xFFFF == peasycap_standard->mask) { JOM(8, "%i=index: exhausts standards\n", index); + mutex_unlock(&easycap_dongle[kd].mutex_video); return -EINVAL; } JOM(8, "%i=index: %s\n", index, \ @@ -1821,8 +1947,10 @@ case VIDIOC_ENUMSTD: { v4l2_standard.index = index; if (0 != copy_to_user((void __user *)arg, &v4l2_standard, \ - sizeof(struct v4l2_standard))) + sizeof(struct v4l2_standard))) { + mutex_unlock(&easycap_dongle[kd].mutex_video); return -EFAULT; + } break; } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ @@ -1835,12 +1963,15 @@ case VIDIOC_G_STD: { if (0 > peasycap->standard_offset) { JOM(8, "%i=peasycap->standard_offset\n", \ peasycap->standard_offset); + mutex_unlock(&easycap_dongle[kd].mutex_video); return -EBUSY; } if (0 != copy_from_user(&std_id, (void __user *)arg, \ - sizeof(v4l2_std_id))) + sizeof(v4l2_std_id))) { + mutex_unlock(&easycap_dongle[kd].mutex_video); return -EFAULT; + } peasycap_standard = &easycap_standard[peasycap->standard_offset]; std_id = peasycap_standard->v4l2_standard.id; @@ -1849,8 +1980,10 @@ case VIDIOC_G_STD: { &peasycap_standard->v4l2_standard.name[0]); if (0 != copy_to_user((void __user *)arg, &std_id, \ - sizeof(v4l2_std_id))) + sizeof(v4l2_std_id))) { + mutex_unlock(&easycap_dongle[kd].mutex_video); return -EFAULT; + } break; } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ @@ -1861,8 +1994,10 @@ case VIDIOC_S_STD: { JOM(8, "VIDIOC_S_STD\n"); if (0 != copy_from_user(&std_id, (void __user *)arg, \ - sizeof(v4l2_std_id))) + sizeof(v4l2_std_id))) { + mutex_unlock(&easycap_dongle[kd].mutex_video); return -EFAULT; + } JOM(8, "User requests standard: 0x%08X%08X\n", \ (int)((std_id & (((v4l2_std_id)0xFFFFFFFF) << 32)) >> 32), \ @@ -1871,6 +2006,7 @@ case VIDIOC_S_STD: { rc = adjust_standard(peasycap, std_id); if (0 > rc) { JOM(8, "WARNING: adjust_standard() returned %i\n", rc); + mutex_unlock(&easycap_dongle[kd].mutex_video); return -ENOENT; } break; @@ -1883,13 +2019,19 @@ case VIDIOC_REQBUFS: { JOM(8, "VIDIOC_REQBUFS\n"); if (0 != copy_from_user(&v4l2_requestbuffers, (void __user *)arg, \ - sizeof(struct v4l2_requestbuffers))) + sizeof(struct v4l2_requestbuffers))) { + mutex_unlock(&easycap_dongle[kd].mutex_video); return -EFAULT; + } - if (v4l2_requestbuffers.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + if (v4l2_requestbuffers.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { + mutex_unlock(&easycap_dongle[kd].mutex_video); return -EINVAL; - if (v4l2_requestbuffers.memory != V4L2_MEMORY_MMAP) + } + if (v4l2_requestbuffers.memory != V4L2_MEMORY_MMAP) { + mutex_unlock(&easycap_dongle[kd].mutex_video); return -EINVAL; + } nbuffers = v4l2_requestbuffers.count; JOM(8, " User requests %i buffers ...\n", nbuffers); if (nbuffers < 2) @@ -1907,8 +2049,10 @@ case VIDIOC_REQBUFS: { peasycap->frame_buffer_many = nbuffers; if (0 != copy_to_user((void __user *)arg, &v4l2_requestbuffers, \ - sizeof(struct v4l2_requestbuffers))) + sizeof(struct v4l2_requestbuffers))) { + mutex_unlock(&easycap_dongle[kd].mutex_video); return -EFAULT; + } break; } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ @@ -1921,15 +2065,20 @@ case VIDIOC_QUERYBUF: { if (peasycap->video_eof) { JOM(8, "returning -EIO because %i=video_eof\n", \ peasycap->video_eof); + mutex_unlock(&easycap_dongle[kd].mutex_video); return -EIO; } if (0 != copy_from_user(&v4l2_buffer, (void __user *)arg, \ - sizeof(struct v4l2_buffer))) + sizeof(struct v4l2_buffer))) { + mutex_unlock(&easycap_dongle[kd].mutex_video); return -EFAULT; + } - if (v4l2_buffer.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + if (v4l2_buffer.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { + mutex_unlock(&easycap_dongle[kd].mutex_video); return -EINVAL; + } index = v4l2_buffer.index; if (index < 0 || index >= peasycap->frame_buffer_many) return -EINVAL; @@ -1958,8 +2107,10 @@ case VIDIOC_QUERYBUF: { JOM(16, " %10i=length\n", v4l2_buffer.length); if (0 != copy_to_user((void __user *)arg, &v4l2_buffer, \ - sizeof(struct v4l2_buffer))) + sizeof(struct v4l2_buffer))) { + mutex_unlock(&easycap_dongle[kd].mutex_video); return -EFAULT; + } break; } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ @@ -1969,24 +2120,34 @@ case VIDIOC_QBUF: { JOM(8, "VIDIOC_QBUF\n"); if (0 != copy_from_user(&v4l2_buffer, (void __user *)arg, \ - sizeof(struct v4l2_buffer))) + sizeof(struct v4l2_buffer))) { + mutex_unlock(&easycap_dongle[kd].mutex_video); return -EFAULT; + } - if (v4l2_buffer.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + if (v4l2_buffer.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { + mutex_unlock(&easycap_dongle[kd].mutex_video); return -EINVAL; - if (v4l2_buffer.memory != V4L2_MEMORY_MMAP) + } + if (v4l2_buffer.memory != V4L2_MEMORY_MMAP) { + mutex_unlock(&easycap_dongle[kd].mutex_video); return -EINVAL; + } if (v4l2_buffer.index < 0 || \ - (v4l2_buffer.index >= peasycap->frame_buffer_many)) + (v4l2_buffer.index >= peasycap->frame_buffer_many)) { + mutex_unlock(&easycap_dongle[kd].mutex_video); return -EINVAL; + } v4l2_buffer.flags = V4L2_BUF_FLAG_MAPPED | V4L2_BUF_FLAG_QUEUED; peasycap->done[v4l2_buffer.index] = 0; peasycap->queued[v4l2_buffer.index] = V4L2_BUF_FLAG_QUEUED; if (0 != copy_to_user((void __user *)arg, &v4l2_buffer, \ - sizeof(struct v4l2_buffer))) + sizeof(struct v4l2_buffer))) { + mutex_unlock(&easycap_dongle[kd].mutex_video); return -EFAULT; + } JOM(8, "..... user queueing frame buffer %i\n", \ (int)v4l2_buffer.index); @@ -2017,15 +2178,20 @@ case VIDIOC_DQBUF: JOM(8, "returning -EIO because " \ "%i=video_idle %i=video_eof\n", \ peasycap->video_idle, peasycap->video_eof); + mutex_unlock(&easycap_dongle[kd].mutex_video); return -EIO; } if (0 != copy_from_user(&v4l2_buffer, (void __user *)arg, \ - sizeof(struct v4l2_buffer))) + sizeof(struct v4l2_buffer))) { + mutex_unlock(&easycap_dongle[kd].mutex_video); return -EFAULT; + } - if (v4l2_buffer.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) + if (v4l2_buffer.type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { + mutex_unlock(&easycap_dongle[kd].mutex_video); return -EINVAL; + } if (true == peasycap->offerfields) { /*-----------------------------------------------------------*/ @@ -2047,6 +2213,7 @@ case VIDIOC_DQBUF: if (!peasycap->video_isoc_streaming) { JOM(16, "returning -EIO because video urbs not streaming\n"); + mutex_unlock(&easycap_dongle[kd].mutex_video); return -EIO; } /*---------------------------------------------------------------------------*/ @@ -2063,12 +2230,15 @@ case VIDIOC_DQBUF: if (-EIO == rcdq) { JOM(8, "returning -EIO because " \ "dqbuf() returned -EIO\n"); + mutex_unlock(&easycap_dongle[kd].mutex_video); return -EIO; } } while (0 != rcdq); } else { - if (peasycap->video_eof) + if (peasycap->video_eof) { + mutex_unlock(&easycap_dongle[kd].mutex_video); return -EIO; + } } if (V4L2_BUF_FLAG_DONE != peasycap->done[peasycap->frame_read]) { SAM("ERROR: V4L2_BUF_FLAG_DONE != 0x%08X\n", \ @@ -2155,8 +2325,10 @@ case VIDIOC_DQBUF: JOM(16, " %10i=length\n", v4l2_buffer.length); if (0 != copy_to_user((void __user *)arg, &v4l2_buffer, \ - sizeof(struct v4l2_buffer))) + sizeof(struct v4l2_buffer))) { + mutex_unlock(&easycap_dongle[kd].mutex_video); return -EFAULT; + } input = peasycap->frame_buffer[peasycap->frame_read][0].input; if (0x08 & input) { @@ -2187,6 +2359,7 @@ case VIDIOC_STREAMON: { peasycap->merit[i] = 0; if ((struct usb_device *)NULL == peasycap->pusb_device) { SAM("ERROR: peasycap->pusb_device is NULL\n"); + mutex_unlock(&easycap_dongle[kd].mutex_video); return -EFAULT; } submit_video_urbs(peasycap); @@ -2202,6 +2375,7 @@ case VIDIOC_STREAMOFF: { if ((struct usb_device *)NULL == peasycap->pusb_device) { SAM("ERROR: peasycap->pusb_device is NULL\n"); + mutex_unlock(&easycap_dongle[kd].mutex_video); return -EFAULT; } @@ -2227,16 +2401,19 @@ case VIDIOC_G_PARM: { pv4l2_streamparm = kzalloc(sizeof(struct v4l2_streamparm), GFP_KERNEL); if (!pv4l2_streamparm) { SAM("ERROR: out of memory\n"); + mutex_unlock(&easycap_dongle[kd].mutex_video); return -ENOMEM; } if (0 != copy_from_user(pv4l2_streamparm, (void __user *)arg, \ sizeof(struct v4l2_streamparm))) { kfree(pv4l2_streamparm); + mutex_unlock(&easycap_dongle[kd].mutex_video); return -EFAULT; } if (pv4l2_streamparm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { kfree(pv4l2_streamparm); + mutex_unlock(&easycap_dongle[kd].mutex_video); return -EINVAL; } pv4l2_streamparm->parm.capture.capability = 0; @@ -2262,6 +2439,7 @@ case VIDIOC_G_PARM: { if (0 != copy_to_user((void __user *)arg, pv4l2_streamparm, \ sizeof(struct v4l2_streamparm))) { kfree(pv4l2_streamparm); + mutex_unlock(&easycap_dongle[kd].mutex_video); return -EFAULT; } kfree(pv4l2_streamparm); @@ -2270,21 +2448,25 @@ case VIDIOC_G_PARM: { /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ case VIDIOC_S_PARM: { JOM(8, "VIDIOC_S_PARM unsupported\n"); + mutex_unlock(&easycap_dongle[kd].mutex_video); return -EINVAL; } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ case VIDIOC_G_AUDIO: { JOM(8, "VIDIOC_G_AUDIO unsupported\n"); + mutex_unlock(&easycap_dongle[kd].mutex_video); return -EINVAL; } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ case VIDIOC_S_AUDIO: { JOM(8, "VIDIOC_S_AUDIO unsupported\n"); + mutex_unlock(&easycap_dongle[kd].mutex_video); return -EINVAL; } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ case VIDIOC_S_TUNER: { JOM(8, "VIDIOC_S_TUNER unsupported\n"); + mutex_unlock(&easycap_dongle[kd].mutex_video); return -EINVAL; } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ @@ -2292,44 +2474,50 @@ case VIDIOC_G_FBUF: case VIDIOC_S_FBUF: case VIDIOC_OVERLAY: { JOM(8, "VIDIOC_G_FBUF|VIDIOC_S_FBUF|VIDIOC_OVERLAY unsupported\n"); + mutex_unlock(&easycap_dongle[kd].mutex_video); return -EINVAL; } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ case VIDIOC_G_TUNER: { JOM(8, "VIDIOC_G_TUNER unsupported\n"); + mutex_unlock(&easycap_dongle[kd].mutex_video); return -EINVAL; } case VIDIOC_G_FREQUENCY: case VIDIOC_S_FREQUENCY: { JOM(8, "VIDIOC_G_FREQUENCY|VIDIOC_S_FREQUENCY unsupported\n"); + mutex_unlock(&easycap_dongle[kd].mutex_video); return -EINVAL; } /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ default: { JOM(8, "ERROR: unrecognized V4L2 IOCTL command: 0x%08X\n", cmd); + mutex_unlock(&easycap_dongle[kd].mutex_video); return -ENOIOCTLCMD; } } +mutex_unlock(&easycap_dongle[kd].mutex_video); +JOM(4, "unlocked easycap_dongle[%i].mutex_video\n", kd); return 0; } - -long easycap_ioctl(struct file *file, unsigned int cmd, unsigned long arg) -{ - struct inode *inode = file->f_dentry->d_inode; - long ret; - - lock_kernel(); - ret = easycap_ioctl_bkl(inode, file, cmd, arg); - unlock_kernel(); - - return ret; -} /*****************************************************************************/ -static int easysnd_ioctl_bkl(struct inode *inode, struct file *file, - unsigned int cmd, unsigned long arg) +/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +#if ((defined(EASYCAP_IS_VIDEODEV_CLIENT)) || \ + (defined(EASYCAP_NEEDS_UNLOCKED_IOCTL))) +long +easysnd_ioctl_noinode(struct file *file, unsigned int cmd, unsigned long arg) { + return (long)easysnd_ioctl((struct inode *)NULL, file, cmd, arg); +} +#endif /*EASYCAP_IS_VIDEODEV_CLIENT||EASYCAP_NEEDS_UNLOCKED_IOCTL*/ +/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +/*---------------------------------------------------------------------------*/ +int +easysnd_ioctl(struct inode *inode, struct file *file, + unsigned int cmd, unsigned long arg) { struct easycap *peasycap; struct usb_device *p; +int kd; if (NULL == file) { SAY("ERROR: file is NULL\n"); @@ -2345,6 +2533,48 @@ if (NULL == p) { SAM("ERROR: peasycap->pusb_device is NULL\n"); return -EFAULT; } +kd = isdongle(peasycap); +if (0 <= kd && DONGLE_MANY > kd) { + if (mutex_lock_interruptible(&easycap_dongle[kd].mutex_audio)) { + SAY("ERROR: cannot lock easycap_dongle[%i].mutex_audio\n", kd); + return -ERESTARTSYS; + } + JOM(4, "locked easycap_dongle[%i].mutex_audio\n", kd); +/*---------------------------------------------------------------------------*/ +/* + * MEANWHILE, easycap_usb_disconnect() MAY HAVE FREED POINTER peasycap, + * IN WHICH CASE A REPEAT CALL TO isdongle() WILL FAIL. + * IF NECESSARY, BAIL OUT. +*/ +/*---------------------------------------------------------------------------*/ + if (kd != isdongle(peasycap)) + return -ERESTARTSYS; + if (NULL == file) { + SAY("ERROR: file is NULL\n"); + mutex_unlock(&easycap_dongle[kd].mutex_audio); + return -ERESTARTSYS; + } + peasycap = file->private_data; + if (NULL == peasycap) { + SAY("ERROR: peasycap is NULL\n"); + mutex_unlock(&easycap_dongle[kd].mutex_audio); + return -ERESTARTSYS; + } + p = peasycap->pusb_device; + if (NULL == peasycap->pusb_device) { + SAM("ERROR: peasycap->pusb_device is NULL\n"); + mutex_unlock(&easycap_dongle[kd].mutex_audio); + return -ERESTARTSYS; + } +} else { +/*---------------------------------------------------------------------------*/ +/* + * IF easycap_usb_disconnect() HAS ALREADY FREED POINTER peasycap BEFORE THE + * ATTEMPT TO ACQUIRE THE SEMAPHORE, isdongle() WILL HAVE FAILED. BAIL OUT. +*/ +/*---------------------------------------------------------------------------*/ + return -ERESTARTSYS; +} /*---------------------------------------------------------------------------*/ switch (cmd) { case SNDCTL_DSP_GETCAPS: { @@ -2363,8 +2593,10 @@ case SNDCTL_DSP_GETCAPS: { caps = 0x04400000; #endif /*UPSAMPLE*/ - if (0 != copy_to_user((void __user *)arg, &caps, sizeof(int))) + if (0 != copy_to_user((void __user *)arg, &caps, sizeof(int))) { + mutex_unlock(&easycap_dongle[kd].mutex_audio); return -EFAULT; + } break; } case SNDCTL_DSP_GETFMTS: { @@ -2383,15 +2615,19 @@ case SNDCTL_DSP_GETFMTS: { incoming = AFMT_S16_LE; #endif /*UPSAMPLE*/ - if (0 != copy_to_user((void __user *)arg, &incoming, sizeof(int))) + if (0 != copy_to_user((void __user *)arg, &incoming, sizeof(int))) { + mutex_unlock(&easycap_dongle[kd].mutex_audio); return -EFAULT; + } break; } case SNDCTL_DSP_SETFMT: { int incoming, outgoing; JOM(8, "SNDCTL_DSP_SETFMT\n"); - if (0 != copy_from_user(&incoming, (void __user *)arg, sizeof(int))) + if (0 != copy_from_user(&incoming, (void __user *)arg, sizeof(int))) { + mutex_unlock(&easycap_dongle[kd].mutex_audio); return -EFAULT; + } JOM(8, "........... %i=incoming\n", incoming); #if defined(UPSAMPLE) @@ -2411,8 +2647,11 @@ case SNDCTL_DSP_SETFMT: { JOM(8, " cf. %i=AFMT_S16_LE\n", AFMT_S16_LE); JOM(8, " cf. %i=AFMT_U8\n", AFMT_U8); if (0 != copy_to_user((void __user *)arg, &outgoing, \ - sizeof(int))) + sizeof(int))) { + mutex_unlock(&easycap_dongle[kd].mutex_audio); return -EFAULT; + } + mutex_unlock(&easycap_dongle[kd].mutex_audio); return -EINVAL ; } break; @@ -2420,8 +2659,10 @@ case SNDCTL_DSP_SETFMT: { case SNDCTL_DSP_STEREO: { int incoming; JOM(8, "SNDCTL_DSP_STEREO\n"); - if (0 != copy_from_user(&incoming, (void __user *)arg, sizeof(int))) + if (0 != copy_from_user(&incoming, (void __user *)arg, sizeof(int))) { + mutex_unlock(&easycap_dongle[kd].mutex_audio); return -EFAULT; + } JOM(8, "........... %i=incoming\n", incoming); #if defined(UPSAMPLE) @@ -2436,15 +2677,19 @@ case SNDCTL_DSP_STEREO: { incoming = 1; #endif /*UPSAMPLE*/ - if (0 != copy_to_user((void __user *)arg, &incoming, sizeof(int))) + if (0 != copy_to_user((void __user *)arg, &incoming, sizeof(int))) { + mutex_unlock(&easycap_dongle[kd].mutex_audio); return -EFAULT; + } break; } case SNDCTL_DSP_SPEED: { int incoming; JOM(8, "SNDCTL_DSP_SPEED\n"); - if (0 != copy_from_user(&incoming, (void __user *)arg, sizeof(int))) + if (0 != copy_from_user(&incoming, (void __user *)arg, sizeof(int))) { + mutex_unlock(&easycap_dongle[kd].mutex_audio); return -EFAULT; + } JOM(8, "........... %i=incoming\n", incoming); #if defined(UPSAMPLE) @@ -2459,27 +2704,35 @@ case SNDCTL_DSP_SPEED: { incoming = 48000; #endif /*UPSAMPLE*/ - if (0 != copy_to_user((void __user *)arg, &incoming, sizeof(int))) + if (0 != copy_to_user((void __user *)arg, &incoming, sizeof(int))) { + mutex_unlock(&easycap_dongle[kd].mutex_audio); return -EFAULT; + } break; } case SNDCTL_DSP_GETTRIGGER: { int incoming; JOM(8, "SNDCTL_DSP_GETTRIGGER\n"); - if (0 != copy_from_user(&incoming, (void __user *)arg, sizeof(int))) + if (0 != copy_from_user(&incoming, (void __user *)arg, sizeof(int))) { + mutex_unlock(&easycap_dongle[kd].mutex_audio); return -EFAULT; + } JOM(8, "........... %i=incoming\n", incoming); incoming = PCM_ENABLE_INPUT; - if (0 != copy_to_user((void __user *)arg, &incoming, sizeof(int))) + if (0 != copy_to_user((void __user *)arg, &incoming, sizeof(int))) { + mutex_unlock(&easycap_dongle[kd].mutex_audio); return -EFAULT; + } break; } case SNDCTL_DSP_SETTRIGGER: { int incoming; JOM(8, "SNDCTL_DSP_SETTRIGGER\n"); - if (0 != copy_from_user(&incoming, (void __user *)arg, sizeof(int))) + if (0 != copy_from_user(&incoming, (void __user *)arg, sizeof(int))) { + mutex_unlock(&easycap_dongle[kd].mutex_audio); return -EFAULT; + } JOM(8, "........... %i=incoming\n", incoming); JOM(8, "........... cf 0x%x=PCM_ENABLE_INPUT " \ "0x%x=PCM_ENABLE_OUTPUT\n", \ @@ -2493,12 +2746,16 @@ case SNDCTL_DSP_SETTRIGGER: { case SNDCTL_DSP_GETBLKSIZE: { int incoming; JOM(8, "SNDCTL_DSP_GETBLKSIZE\n"); - if (0 != copy_from_user(&incoming, (void __user *)arg, sizeof(int))) + if (0 != copy_from_user(&incoming, (void __user *)arg, sizeof(int))) { + mutex_unlock(&easycap_dongle[kd].mutex_audio); return -EFAULT; + } JOM(8, "........... %i=incoming\n", incoming); incoming = peasycap->audio_bytes_per_fragment; - if (0 != copy_to_user((void __user *)arg, &incoming, sizeof(int))) + if (0 != copy_to_user((void __user *)arg, &incoming, sizeof(int))) { + mutex_unlock(&easycap_dongle[kd].mutex_audio); return -EFAULT; + } break; } case SNDCTL_DSP_GETISPACE: { @@ -2512,8 +2769,10 @@ case SNDCTL_DSP_GETISPACE: { audio_buf_info.fragstotal = 0; if (0 != copy_to_user((void __user *)arg, &audio_buf_info, \ - sizeof(int))) + sizeof(int))) { + mutex_unlock(&easycap_dongle[kd].mutex_audio); return -EFAULT; + } break; } case 0x00005401: @@ -2523,25 +2782,16 @@ case 0x00005404: case 0x00005405: case 0x00005406: { JOM(8, "SNDCTL_TMR_...: 0x%08X unsupported\n", cmd); + mutex_unlock(&easycap_dongle[kd].mutex_audio); return -ENOIOCTLCMD; } default: { JOM(8, "ERROR: unrecognized DSP IOCTL command: 0x%08X\n", cmd); + mutex_unlock(&easycap_dongle[kd].mutex_audio); return -ENOIOCTLCMD; } } +mutex_unlock(&easycap_dongle[kd].mutex_audio); return 0; } - -long easysnd_ioctl(struct file *file, unsigned int cmd, unsigned long arg) -{ - struct inode *inode = file->f_dentry->d_inode; - long ret; - - lock_kernel(); - ret = easysnd_ioctl_bkl(inode, file, cmd, arg); - unlock_kernel(); - - return ret; -} /*****************************************************************************/ diff --git a/drivers/staging/easycap/easycap_low.c b/drivers/staging/easycap/easycap_low.c index 7d778ba67ac8..b75db82bba73 100644 --- a/drivers/staging/easycap/easycap_low.c +++ b/drivers/staging/easycap/easycap_low.c @@ -38,8 +38,8 @@ */ /****************************************************************************/ -#include "easycap_debug.h" #include "easycap.h" +#include "easycap_debug.h" /*--------------------------------------------------------------------------*/ const struct stk1160config { int reg; int set; } stk1160configPAL[256] = { @@ -248,6 +248,9 @@ int confirm_resolution(struct usb_device *p) { __u8 get0, get1, get2, get3, get4, get5, get6, get7; + +if (NULL == p) + return -ENODEV; GET(p, 0x0110, &get0); GET(p, 0x0111, &get1); GET(p, 0x0112, &get2); @@ -288,6 +291,8 @@ confirm_stream(struct usb_device *p) __u16 get2; __u8 igot; +if (NULL == p) + return -ENODEV; GET(p, 0x0100, &igot); get2 = 0x80 & igot; if (0x80 == get2) JOT(8, "confirm_stream: OK\n"); @@ -301,6 +306,8 @@ setup_stk(struct usb_device *p, bool ntsc) { int i0; +if (NULL == p) + return -ENODEV; i0 = 0; if (true == ntsc) { while (0xFFF != stk1160configNTSC[i0].reg) { @@ -324,6 +331,8 @@ setup_saa(struct usb_device *p, bool ntsc) { int i0, ir; +if (NULL == p) + return -ENODEV; i0 = 0; if (true == ntsc) { while (0xFF != saa7113configNTSC[i0].reg) { @@ -346,6 +355,8 @@ write_000(struct usb_device *p, __u16 set2, __u16 set0) { __u8 igot0, igot2; +if (NULL == p) + return -ENODEV; GET(p, 0x0002, &igot2); GET(p, 0x0000, &igot0); SET(p, 0x0002, set2); @@ -356,6 +367,8 @@ return 0; int write_saa(struct usb_device *p, __u16 reg0, __u16 set0) { +if (NULL == p) + return -ENODEV; SET(p, 0x200, 0x00); SET(p, 0x204, reg0); SET(p, 0x205, set0); @@ -379,6 +392,8 @@ __u8 igot; __u16 got502, got503; __u16 set502, set503; +if (NULL == p) + return -ENODEV; SET(p, 0x0504, reg0); SET(p, 0x0500, 0x008B); @@ -414,6 +429,8 @@ read_vt(struct usb_device *p, __u16 reg0) __u8 igot; __u16 got502, got503; +if (NULL == p) + return -ENODEV; SET(p, 0x0504, reg0); SET(p, 0x0500, 0x008B); @@ -433,6 +450,8 @@ return (got503 << 8) | got502; int write_300(struct usb_device *p) { +if (NULL == p) + return -ENODEV; SET(p, 0x300, 0x0012); SET(p, 0x350, 0x002D); SET(p, 0x351, 0x0001); @@ -453,6 +472,8 @@ check_saa(struct usb_device *p, bool ntsc) { int i0, ir, rc; +if (NULL == p) + return -ENODEV; i0 = 0; rc = 0; if (true == ntsc) { @@ -501,6 +522,8 @@ merit_saa(struct usb_device *p) { int rc; +if (NULL == p) + return -ENODEV; rc = read_saa(p, 0x1F); if ((0 > rc) || (0x02 & rc)) return 1 ; @@ -521,6 +544,8 @@ const int max = 5, marktime = PATIENCE/5; * 3 FOR NON-INTERLACED 60 Hz */ /*--------------------------------------------------------------------------*/ +if (NULL == p) + return -ENODEV; j = 0; while (max > j) { rc = read_saa(p, 0x1F); @@ -565,6 +590,8 @@ check_stk(struct usb_device *p, bool ntsc) { int i0, ir; +if (NULL == p) + return -ENODEV; i0 = 0; if (true == ntsc) { while (0xFFF != stk1160configNTSC[i0].reg) { @@ -637,6 +664,8 @@ read_saa(struct usb_device *p, __u16 reg0) { __u8 igot; +if (NULL == p) + return -ENODEV; SET(p, 0x208, reg0); SET(p, 0x200, 0x20); if (0 != wait_i2c(p)) @@ -651,6 +680,8 @@ read_stk(struct usb_device *p, __u32 reg0) { __u8 igot; +if (NULL == p) + return -ENODEV; igot = 0; GET(p, reg0, &igot); return igot; @@ -679,6 +710,8 @@ select_input(struct usb_device *p, int input, int mode) { int ir; +if (NULL == p) + return -ENODEV; stop_100(p); switch (input) { case 0: @@ -781,6 +814,8 @@ set_resolution(struct usb_device *p, \ { __u16 u0x0111, u0x0113, u0x0115, u0x0117; +if (NULL == p) + return -ENODEV; u0x0111 = ((0xFF00 & set0) >> 8); u0x0113 = ((0xFF00 & set1) >> 8); u0x0115 = ((0xFF00 & set2) >> 8); @@ -804,6 +839,8 @@ start_100(struct usb_device *p) __u16 get116, get117, get0; __u8 igot116, igot117, igot; +if (NULL == p) + return -ENODEV; GET(p, 0x0116, &igot116); get116 = igot116; GET(p, 0x0117, &igot117); @@ -827,6 +864,8 @@ stop_100(struct usb_device *p) __u16 get0; __u8 igot; +if (NULL == p) + return -ENODEV; GET(p, 0x0100, &igot); get0 = igot; SET(p, 0x0100, (0x7F & get0)); @@ -846,6 +885,8 @@ __u8 igot; const int max = 2; int k; +if (NULL == p) + return -ENODEV; for (k = 0; k < max; k++) { GET(p, 0x0201, &igot); get0 = igot; switch (get0) { @@ -872,8 +913,7 @@ __u16 igot; int rc0, rc1; if (!pusb_device) - return -EFAULT; - + return -ENODEV; rc1 = 0; igot = 0; rc0 = usb_control_msg(pusb_device, usb_sndctrlpipe(pusb_device, 0), \ (__u8)0x01, \ @@ -936,8 +976,7 @@ regget(struct usb_device *pusb_device, __u16 index, void *pvoid) int ir; if (!pusb_device) - return -EFAULT; - + return -ENODEV; ir = usb_control_msg(pusb_device, usb_rcvctrlpipe(pusb_device, 0), \ (__u8)0x00, \ (__u8)(USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE), \ @@ -952,6 +991,8 @@ return 0xFF & ir; int wakeup_device(struct usb_device *pusb_device) { +if (!pusb_device) + return -ENODEV; return usb_control_msg(pusb_device, usb_sndctrlpipe(pusb_device, 0), \ (__u8)USB_REQ_SET_FEATURE, \ (__u8)(USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_DEVICE), \ @@ -1056,6 +1097,8 @@ check_vt(struct usb_device *pusb_device) { int igot; +if (!pusb_device) + return -ENODEV; igot = read_vt(pusb_device, 0x0002); if (0 > igot) SAY("ERROR: failed to read VT1612A register 0x02\n"); @@ -1128,7 +1171,7 @@ int igot; __u8 u8; __u16 mute; -if ((struct usb_device *)NULL == pusb_device) +if (NULL == pusb_device) return -ENODEV; if (0 > loud) loud = 0; diff --git a/drivers/staging/easycap/easycap_main.c b/drivers/staging/easycap/easycap_main.c index ee5c8d990bdf..67ae755fcfac 100644 --- a/drivers/staging/easycap/easycap_main.c +++ b/drivers/staging/easycap/easycap_main.c @@ -45,11 +45,14 @@ module_param(gain, int, S_IRUGO | S_IWUSR); * IS CALLED SUCCESSIVELY FOR INTERFACES 0, 1, 2 AND THE POINTER peasycap * ALLOCATED DURING THE PROBING OF INTERFACE 0 MUST BE REMEMBERED WHEN * PROBING INTERFACES 1 AND 2. + * + * IOCTL LOCKING IS DONE AT MODULE LEVEL, NOT DEVICE LEVEL. */ /*---------------------------------------------------------------------------*/ -struct easycap *peasycap_dongle[DONGLE_MANY]; +struct easycap_dongle easycap_dongle[DONGLE_MANY]; static int dongle_this; +static int dongle_done; /*---------------------------------------------------------------------------*/ /* @@ -80,7 +83,11 @@ const struct file_operations easycap_fops = { .owner = THIS_MODULE, .open = easycap_open, .release = easycap_release, - .unlocked_ioctl = easycap_ioctl, +#if defined(EASYCAP_NEEDS_UNLOCKED_IOCTL) + .unlocked_ioctl = easycap_ioctl_noinode, +#else + .ioctl = easycap_ioctl, +#endif /*EASYCAP_NEEDS_UNLOCKED_IOCTL*/ .poll = easycap_poll, .mmap = easycap_mmap, .llseek = no_llseek, @@ -103,7 +110,11 @@ const struct v4l2_file_operations v4l2_fops = { .owner = THIS_MODULE, .open = easycap_open_noinode, .release = easycap_release_noinode, - .unlocked_ioctl = easycap_ioctl, +#if defined(EASYCAP_NEEDS_UNLOCKED_IOCTL) + .unlocked_ioctl = easycap_ioctl_noinode, +#else + .ioctl = easycap_ioctl, +#endif /*EASYCAP_NEEDS_UNLOCKED_IOCTL*/ .poll = easycap_poll, .mmap = easycap_mmap, }; @@ -120,7 +131,11 @@ const struct file_operations easysnd_fops = { .owner = THIS_MODULE, .open = easysnd_open, .release = easysnd_release, - .unlocked_ioctl = easysnd_ioctl, +#if defined(EASYCAP_NEEDS_UNLOCKED_IOCTL) + .unlocked_ioctl = easysnd_ioctl_noinode, +#else + .ioctl = easysnd_ioctl, +#endif /*EASYCAP_NEEDS_UNLOCKED_IOCTL*/ .read = easysnd_read, .llseek = no_llseek, }; @@ -139,10 +154,10 @@ int isdongle(struct easycap *peasycap) { int k; -if ((struct easycap *)NULL == peasycap) +if (NULL == peasycap) return -2; for (k = 0; k < DONGLE_MANY; k++) { - if (peasycap_dongle[k] == peasycap) { + if (easycap_dongle[k].peasycap == peasycap) { peasycap->isdongle = k; return k; } @@ -196,11 +211,10 @@ if ((struct video_device *)NULL == pvideo_device) { peasycap = (struct easycap *)video_get_drvdata(pvideo_device); #endif /*EASYCAP_IS_VIDEODEV_CLIENT*/ /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ -if ((struct easycap *)NULL == peasycap) { +if (NULL == peasycap) { SAY("ERROR: peasycap is NULL\n"); return -EFAULT; } -file->private_data = peasycap; if (NULL == peasycap->pusb_device) { SAM("ERROR: peasycap->pusb_device is NULL\n"); return -EFAULT; @@ -208,6 +222,7 @@ if (NULL == peasycap->pusb_device) { JOM(16, "0x%08lX=peasycap->pusb_device\n", \ (long int)peasycap->pusb_device); } +file->private_data = peasycap; rc = wakeup_device(peasycap->pusb_device); if (0 == rc) JOM(8, "wakeup_device() OK\n"); @@ -243,7 +258,7 @@ struct easycap_standard const *peasycap_standard; int i, rc, input, rate; bool ntsc, other; -if ((struct easycap *)NULL == peasycap) { +if (NULL == peasycap) { SAY("ERROR: peasycap is NULL\n"); return -EFAULT; } @@ -251,7 +266,7 @@ input = peasycap->input; /*---------------------------------------------------------------------------*/ /* - * IF THE SAA7113H HAS ALREADY ACQUIRED LOCK, USE ITS HARDWARE-DETECTED + * IF THE SAA7113H HAS ALREADY ACQUIRED SYNC, USE ITS HARDWARE-DETECTED * FIELD FREQUENCY TO DISTINGUISH NTSC FROM PAL. THIS IS ESSENTIAL FOR * gstreamer AND OTHER USERSPACE PROGRAMS WHICH MAY NOT ATTEMPT TO INITIATE * A SWITCH BETWEEN PAL AND NTSC. @@ -447,7 +462,7 @@ if (NULL == peasycap) { } JOM(8, "%i=input sought\n", input); -if ((0 > input) &&(INPUT_MANY <= input)) +if (0 > input && INPUT_MANY <= input) return -ENOENT; inputnow = peasycap->input; if (input == inputnow) @@ -581,7 +596,7 @@ if (input == peasycap->inputset[input].input) { return -ENOENT; } /*---------------------------------------------------------------------------*/ -if ((struct usb_device *)NULL == peasycap->pusb_device) { +if (NULL == peasycap->pusb_device) { SAM("ERROR: peasycap->pusb_device is NULL\n"); return -ENODEV; } @@ -617,16 +632,16 @@ struct list_head *plist_head; int j, isbad, nospc, m, rc; int isbuf; -if ((struct easycap *)NULL == peasycap) { +if (NULL == peasycap) { SAY("ERROR: peasycap is NULL\n"); return -EFAULT; } -if ((struct list_head *)NULL == peasycap->purb_video_head) { +if (NULL == peasycap->purb_video_head) { SAY("ERROR: peasycap->urb_video_head uninitialized\n"); return -EFAULT; } -if ((struct usb_device *)NULL == peasycap->pusb_device) { +if (NULL == peasycap->pusb_device) { SAY("ERROR: peasycap->pusb_device is NULL\n"); return -ENODEV; } @@ -768,7 +783,7 @@ int m; struct list_head *plist_head; struct data_urb *pdata_urb; -if ((struct easycap *)NULL == peasycap) { +if (NULL == peasycap) { SAY("ERROR: peasycap is NULL\n"); return -EFAULT; } @@ -780,8 +795,8 @@ if (peasycap->video_isoc_streaming) { list_for_each(plist_head, (peasycap->purb_video_head)) { pdata_urb = list_entry(plist_head, struct data_urb, \ list_head); - if ((struct data_urb *)NULL != pdata_urb) { - if ((struct urb *)NULL != pdata_urb->purb) { + if (NULL != pdata_urb) { + if (NULL != pdata_urb->purb) { usb_kill_urb(pdata_urb->purb); m++; } @@ -864,15 +879,17 @@ return 0; /*****************************************************************************/ /*--------------------------------------------------------------------------*/ /* - * THIS FUNCTION IS CALLED FROM WITHIN easycap_usb_disconnect(). - * BY THIS STAGE THE DEVICE HAS ALREADY BEEN PHYSICALLY UNPLUGGED. - * peasycap->pusb_device IS NO LONGER VALID AND SHOULD HAVE BEEN SET TO NULL. + * THIS FUNCTION IS CALLED FROM WITHIN easycap_usb_disconnect() AND IS + * PROTECTED BY SEMAPHORES SET AND CLEARED BY easycap_usb_disconnect(). + * + * BY THIS STAGE THE DEVICE HAS ALREADY BEEN PHYSICALLY UNPLUGGED, SO + * peasycap->pusb_device IS NO LONGER VALID. */ /*---------------------------------------------------------------------------*/ void easycap_delete(struct kref *pkref) { -int k, m, gone; +int k, m, gone, kd; int allocation_video_urb, allocation_video_page, allocation_video_struct; int allocation_audio_urb, allocation_audio_page, allocation_audio_struct; int registered_video, registered_audio; @@ -883,10 +900,11 @@ struct list_head *plist_head, *plist_next; JOT(4, "\n"); peasycap = container_of(pkref, struct easycap, kref); -if ((struct easycap *)NULL == peasycap) { +if (NULL == peasycap) { SAM("ERROR: peasycap is NULL: cannot perform deletions\n"); return; } +kd = isdongle(peasycap); /*---------------------------------------------------------------------------*/ /* * FREE VIDEO. @@ -925,8 +943,6 @@ if ((struct list_head *)NULL != peasycap->purb_video_head) { JOM(4, "%i video data_urb structures freed\n", m); JOM(4, "setting peasycap->purb_video_head=NULL\n"); peasycap->purb_video_head = (struct list_head *)NULL; - } else { -JOM(4, "peasycap->purb_video_head is NULL\n"); } /*---------------------------------------------------------------------------*/ JOM(4, "freeing video isoc buffers.\n"); @@ -1051,15 +1067,16 @@ allocation_audio_urb = peasycap->allocation_audio_urb; allocation_audio_page = peasycap->allocation_audio_page; allocation_audio_struct = peasycap->allocation_audio_struct; registered_audio = peasycap->registered_audio; -m = 0; -if ((struct easycap *)NULL != peasycap) { - kfree(peasycap); peasycap = (struct easycap *)NULL; + +kfree(peasycap); +if (0 <= kd && DONGLE_MANY > kd) { + easycap_dongle[kd].peasycap = (struct easycap *)NULL; + JOT(4, " null-->easycap_dongle[%i].peasycap\n", kd); allocation_video_struct -= sizeof(struct easycap); - m++; +} else { + SAY("ERROR: cannot purge easycap_dongle[].peasycap"); } -JOT(4, "%i easycap structure freed\n", m); /*---------------------------------------------------------------------------*/ - SAY("%8i= video urbs after all deletions\n", allocation_video_urb); SAY("%8i= video pages after all deletions\n", allocation_video_page); SAY("%8i= video structs after all deletions\n", allocation_video_struct); @@ -1076,27 +1093,75 @@ return; unsigned int easycap_poll(struct file *file, poll_table *wait) { struct easycap *peasycap; +int rc, kd; JOT(8, "\n"); if (NULL == ((poll_table *)wait)) JOT(8, "WARNING: poll table pointer is NULL ... continuing\n"); -if (NULL == ((struct file *)file)) { +if ((struct file *)NULL == file) { SAY("ERROR: file pointer is NULL\n"); - return -EFAULT; + return -ERESTARTSYS; } peasycap = file->private_data; if (NULL == peasycap) { SAY("ERROR: peasycap is NULL\n"); return -EFAULT; } +if (NULL == peasycap->pusb_device) { + SAY("ERROR: peasycap->pusb_device is NULL\n"); + return -EFAULT; +} +/*---------------------------------------------------------------------------*/ +kd = isdongle(peasycap); +if (0 <= kd && DONGLE_MANY > kd) { + if (mutex_lock_interruptible(&easycap_dongle[kd].mutex_video)) { + SAY("ERROR: cannot down easycap_dongle[%i].mutex_video\n", kd); + return -ERESTARTSYS; + } + JOM(4, "locked easycap_dongle[%i].mutex_video\n", kd); + /*-------------------------------------------------------------------*/ + /* + * MEANWHILE, easycap_usb_disconnect() MAY HAVE FREED POINTER + * peasycap, IN WHICH CASE A REPEAT CALL TO isdongle() WILL FAIL. + * IF NECESSARY, BAIL OUT. + */ + /*-------------------------------------------------------------------*/ + if (kd != isdongle(peasycap)) + return -ERESTARTSYS; + if (NULL == file) { + SAY("ERROR: file is NULL\n"); + mutex_unlock(&easycap_dongle[kd].mutex_video); + return -ERESTARTSYS; + } + peasycap = file->private_data; + if (NULL == peasycap) { + SAY("ERROR: peasycap is NULL\n"); + mutex_unlock(&easycap_dongle[kd].mutex_video); + return -ERESTARTSYS; + } + if (NULL == peasycap->pusb_device) { + SAM("ERROR: peasycap->pusb_device is NULL\n"); + mutex_unlock(&easycap_dongle[kd].mutex_video); + return -ERESTARTSYS; + } +} else + /*-------------------------------------------------------------------*/ + /* + * IF easycap_usb_disconnect() HAS ALREADY FREED POINTER peasycap + * BEFORE THE ATTEMPT TO ACQUIRE THE SEMAPHORE, isdongle() WILL + * HAVE FAILED. BAIL OUT. + */ + /*-------------------------------------------------------------------*/ + return -ERESTARTSYS; +/*---------------------------------------------------------------------------*/ +rc = easycap_dqbuf(peasycap, 0); peasycap->polled = 1; - -if (0 == easycap_dqbuf(peasycap, 0)) +mutex_unlock(&easycap_dongle[kd].mutex_video); +if (0 == rc) return POLLIN | POLLRDNORM; else return POLLERR; - } /*****************************************************************************/ /*---------------------------------------------------------------------------*/ @@ -1115,6 +1180,10 @@ if (NULL == peasycap) { SAY("ERROR: peasycap is NULL\n"); return -EFAULT; } +if (NULL == peasycap->pusb_device) { + SAY("ERROR: peasycap->pusb_device is NULL\n"); + return -EFAULT; +} ifield = 0; JOM(8, "%i=ifield\n", ifield); /*---------------------------------------------------------------------------*/ @@ -1122,9 +1191,9 @@ JOM(8, "%i=ifield\n", ifield); * CHECK FOR LOST INPUT SIGNAL. * * FOR THE FOUR-CVBS EasyCAP, THIS DOES NOT WORK AS EXPECTED. - * IF INPUT 0 IS PRESENT AND LOCKED, UNPLUGGING INPUT 4 DOES NOT RESULT IN - * SETTING BIT 0x40 ON REGISTER 0x1F, PRESUMABLY BECAUSE THERE IS FLYWHEELING - * ON INPUT 0. THE UPSHOT IS: + * IF INPUT 0 IS PRESENT AND SYNC ACQUIRED, UNPLUGGING INPUT 4 DOES NOT + * RESULT IN SETTING BIT 0x40 ON REGISTER 0x1F, PRESUMABLY BECAUSE THERE + * IS FLYWHEELING ON INPUT 0. THE UPSHOT IS: * * INPUT 0 PLUGGED, INPUT 4 PLUGGED => SCREEN 0 OK, SCREEN 4 OK * INPUT 0 PLUGGED, INPUT 4 UNPLUGGED => SCREEN 0 OK, SCREEN 4 BLACK @@ -1342,7 +1411,7 @@ int rc, bytesperpixel, multiplier, much, more, over, rump, caches, input; __u8 mask, margin; bool odd, isuy, decimatepixel, offerfields, badinput; -if ((struct easycap *)NULL == peasycap) { +if (NULL == peasycap) { SAY("ERROR: peasycap is NULL\n"); return -EFAULT; } @@ -1447,13 +1516,11 @@ while (cz < wz) { much) / 2; /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ if (1 < bytesperpixel) { - if ((rad * \ - 2) < (much * \ - bytesperpixel)) { + if (rad * 2 < much * bytesperpixel) { /* ** INJUDICIOUS ALTERATION OF THIS - ** BLOCK WILL CAUSE BREAKAGE. - ** BEWARE. + ** STATEMENT BLOCK WILL CAUSE + ** BREAKAGE. BEWARE. **/ rad2 = rad + bytesperpixel - 1; much = ((((2 * \ @@ -1483,7 +1550,6 @@ while (cz < wz) { /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ if (rump) caches++; - if (true == badinput) { JOM(8, "ERROR: 0x%02X=->field_buffer" \ "[%i][%i].input, " \ @@ -1492,7 +1558,6 @@ while (cz < wz) { [kex][mex].input, kex, mex, \ (0x08|peasycap->input)); } - rc = redaub(peasycap, pad, pex, much, more, \ mask, margin, isuy); if (0 > rc) { @@ -1575,12 +1640,11 @@ while (cz < wz) { much) / 4; /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */ if (1 < bytesperpixel) { - if ((rad * 4) < (much * \ - bytesperpixel)) { + if (rad * 4 < much * bytesperpixel) { /* ** INJUDICIOUS ALTERATION OF THIS - ** BLOCK WILL CAUSE BREAKAGE. - ** BEWARE. + ** STATEMENT BLOCK WILL CAUSE + ** BREAKAGE. BEWARE. **/ rad2 = rad + bytesperpixel - 1; much = ((((2 * rad2)/bytesperpixel)/2)\ @@ -1620,7 +1684,6 @@ while (cz < wz) { [kex][mex].input, kex, mex, \ (0x08|peasycap->input)); } - rc = redaub(peasycap, pad, pex, much, more, \ mask, margin, isuy); if (0 > rc) { @@ -3297,8 +3360,8 @@ return; * FIXME * * - * THIS FUNCTION ASSUMES THAT, ON EACH AND EVERY OCCASION THAT THE DEVICE IS - * PHYSICALLY PLUGGED IN, INTERFACE 0 IS PROBED FIRST. + * THIS FUNCTION ASSUMES THAT, ON EACH AND EVERY OCCASION THAT THE EasyCAP + * IS PHYSICALLY PLUGGED IN, INTERFACE 0 IS PROBED FIRST. * IF THIS IS NOT TRUE, THERE IS THE POSSIBILITY OF AN Oops. * * THIS HAS NEVER BEEN A PROBLEM IN PRACTICE, BUT SOMETHING SEEMS WRONG HERE. @@ -3338,6 +3401,16 @@ __s32 value; struct easycap_format *peasycap_format; JOT(4, "\n"); + +if (!dongle_done) { + dongle_done = 1; + for (k = 0; k < DONGLE_MANY; k++) { + easycap_dongle[k].peasycap = (struct easycap *)NULL; + mutex_init(&easycap_dongle[k].mutex_video); + mutex_init(&easycap_dongle[k].mutex_audio); + } +} + peasycap = (struct easycap *)NULL; if ((struct usb_interface *)NULL == pusb_interface) { @@ -3481,12 +3554,20 @@ if (0 == bInterfaceNumber) { init_waitqueue_head(&peasycap->wq_audio); for (dongle_this = 0; dongle_this < DONGLE_MANY; dongle_this++) { - if ((struct easycap *)NULL == peasycap_dongle[dongle_this]) { - peasycap_dongle[dongle_this] = peasycap; - JOM(8, "intf[%i]: peasycap-->easycap" \ + if (NULL == easycap_dongle[dongle_this].peasycap) { + if (0 == mutex_is_locked(&easycap_dongle\ + [dongle_this].mutex_video)) { + if (0 == mutex_is_locked(&easycap_dongle\ + [dongle_this].mutex_audio)) { + easycap_dongle\ + [dongle_this].peasycap = \ + peasycap; + JOM(8, "intf[%i]: peasycap-->easycap" \ "_dongle[%i].peasycap\n", \ bInterfaceNumber, dongle_this); - break; + break; + } + } } } if (DONGLE_MANY <= dongle_this) { @@ -3665,15 +3746,15 @@ if (0 == bInterfaceNumber) { * FOR INTERFACES 1 AND 2 THE POINTER peasycap IS OBTAINED BY ASSUMING * THAT dongle_this HAS NOT CHANGED SINCE INTERFACE 0 WAS PROBED. IF * THIS IS NOT THE CASE, FOR EXAMPLE WHEN TWO EASYCAPs ARE PLUGGED IN - * SIMULTANEOUSLY, THERE WILL BE VERY SERIOUS TROUBLE. + * SIMULTANEOUSLY, THERE WILL BE SERIOUS TROUBLE. */ /*---------------------------------------------------------------------------*/ if ((0 > dongle_this) || (DONGLE_MANY <= dongle_this)) { SAY("ERROR: bad dongle count\n"); return -EFAULT; } - peasycap = peasycap_dongle[dongle_this]; - JOT(8, "intf[%i]: peasycap_dongle[%i]-->peasycap\n", \ + peasycap = easycap_dongle[dongle_this].peasycap; + JOT(8, "intf[%i]: easycap_dongle[%i].peasycap-->peasycap\n", \ bInterfaceNumber, dongle_this); if ((struct easycap *)NULL == peasycap) { @@ -3721,6 +3802,7 @@ if ((USB_CLASS_VIDEO == bInterfaceClass) || \ */ /*---------------------------------------------------------------------------*/ isokalt = 0; + for (i = 0; i < pusb_interface->num_altsetting; i++) { pusb_host_interface = &(pusb_interface->altsetting[i]); if ((struct usb_host_interface *)NULL == pusb_host_interface) { @@ -4245,6 +4327,9 @@ case 0: { } /*---------------------------------------------------------------------------*/ /* + * FIXME + * + * * THIS IS BELIEVED TO BE HARMLESS, BUT MAY WELL BE UNNECESSARY OR WRONG: */ /*---------------------------------------------------------------------------*/ @@ -4587,9 +4672,8 @@ return 0; /*****************************************************************************/ /*---------------------------------------------------------------------------*/ /* - * WHEN THIS FUNCTION IS CALLED THE DEVICE HAS ALREADY BEEN PHYSICALLY - * UNPLUGGED. - * HENCE peasycap->pusb_device IS NO LONGER VALID AND MUST BE SET TO NULL. + * WHEN THIS FUNCTION IS CALLED THE EasyCAP HAS ALREADY BEEN PHYSICALLY + * UNPLUGGED. HENCE peasycap->pusb_device IS NO LONGER VALID. */ /*---------------------------------------------------------------------------*/ void @@ -4602,7 +4686,7 @@ struct easycap *peasycap; struct list_head *plist_head; struct data_urb *pdata_urb; -int minor, m; +int minor, m, kd; JOT(4, "\n"); @@ -4691,49 +4775,75 @@ default: /*--------------------------------------------------------------------------*/ /* * DEREGISTER + * + * THIS PROCEDURE WILL BLOCK UNTIL easycap_poll(), VIDEO IOCTL AND AUDIO + * IOCTL ARE ALL UNLOCKED. IF THIS IS NOT DONE AN Oops CAN OCCUR WHEN + * AN EasyCAP IS UNPLUGGED WHILE THE URBS ARE RUNNING. BEWARE. */ /*--------------------------------------------------------------------------*/ +kd = isdongle(peasycap); switch (bInterfaceNumber) { case 0: { + if (0 <= kd && DONGLE_MANY > kd) { + wake_up_interruptible(&peasycap->wq_video); + JOM(4, "about to lock easycap_dongle[%i].mutex_video\n", kd); + if (mutex_lock_interruptible(&easycap_dongle[kd].\ + mutex_video)) { + SAY("ERROR: cannot lock easycap_dongle[%i]." \ + "mutex_video\n", kd); + return; + } + JOM(4, "locked easycap_dongle[%i].mutex_video\n", kd); + } else + SAY("ERROR: %i=kd is bad: cannot lock dongle\n", kd); +/*---------------------------------------------------------------------------*/ #if (!defined(EASYCAP_IS_VIDEODEV_CLIENT)) if ((struct easycap *)NULL == peasycap) { SAM("ERROR: peasycap has become NULL\n"); } else { - lock_kernel(); usb_deregister_dev(pusb_interface, &easycap_class); (peasycap->registered_video)--; - JOM(4, "intf[%i]: usb_deregister_dev()\n", bInterfaceNumber); - unlock_kernel(); SAM("easycap detached from minor #%d\n", minor); } /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ #else - if ((struct easycap *)NULL == peasycap) - SAM("ERROR: peasycap has become NULL\n"); - else { - lock_kernel(); - video_unregister_device(&peasycap->video_device); - (peasycap->registered_video)--; - unlock_kernel(); - JOM(4, "unregistered with videodev: %i=minor\n", \ + video_unregister_device(&peasycap->video_device); + JOM(4, "unregistered with videodev: %i=minor\n", \ peasycap->video_device.minor); - } + (peasycap->registered_video)--; /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ #endif /*EASYCAP_IS_VIDEODEV_CLIENT*/ + if (0 <= kd && DONGLE_MANY > kd) { + mutex_unlock(&easycap_dongle[kd].mutex_video); + JOM(4, "unlocked easycap_dongle[%i].mutex_video\n", kd); + } break; } case 2: { - lock_kernel(); + if (0 <= kd && DONGLE_MANY > kd) { + wake_up_interruptible(&peasycap->wq_audio); + JOM(4, "about to lock easycap_dongle[%i].mutex_audio\n", kd); + if (mutex_lock_interruptible(&easycap_dongle[kd].\ + mutex_audio)) { + SAY("ERROR: cannot lock easycap_dongle[%i]." \ + "mutex_audio\n", kd); + return; + } + JOM(4, "locked easycap_dongle[%i].mutex_audio\n", kd); + } else + SAY("ERROR: %i=kd is bad: cannot lock dongle\n", kd); usb_deregister_dev(pusb_interface, &easysnd_class); - if ((struct easycap *)NULL != peasycap) - (peasycap->registered_audio)--; + (peasycap->registered_audio)--; JOM(4, "intf[%i]: usb_deregister_dev()\n", bInterfaceNumber); - unlock_kernel(); - SAM("easysnd detached from minor #%d\n", minor); + + if (0 <= kd && DONGLE_MANY > kd) { + mutex_unlock(&easycap_dongle[kd].mutex_audio); + JOM(4, "unlocked easycap_dongle[%i].mutex_audio\n", kd); + } break; } default: @@ -4744,24 +4854,41 @@ default: * CALL easycap_delete() IF NO REMAINING REFERENCES TO peasycap */ /*---------------------------------------------------------------------------*/ -if ((struct easycap *)NULL == peasycap) { - SAM("ERROR: peasycap has become NULL\n"); - SAM("cannot call kref_put()\n"); - SAM("ending unsuccessfully: may cause memory leak\n"); - return; -} if (!peasycap->kref.refcount.counter) { - SAM("ERROR: peasycap->kref.refcount.counter is zero " \ + SAM("ERROR: peasycap->kref.refcount.counter is zero " "so cannot call kref_put()\n"); SAM("ending unsuccessfully: may cause memory leak\n"); return; } -JOM(4, "intf[%i]: kref_put() with %i=peasycap->kref.refcount.counter\n", \ +if (0 <= kd && DONGLE_MANY > kd) { + JOM(4, "about to lock easycap_dongle[%i].mutex_video\n", kd); + if (mutex_lock_interruptible(&easycap_dongle[kd].mutex_video)) { + SAY("ERROR: cannot down easycap_dongle[%i].mutex_video\n", kd); + SAM("ending unsuccessfully: may cause memory leak\n"); + return; + } + JOM(4, "locked easycap_dongle[%i].mutex_video\n", kd); + JOM(4, "about to lock easycap_dongle[%i].mutex_audio\n", kd); + if (mutex_lock_interruptible(&easycap_dongle[kd].mutex_audio)) { + SAY("ERROR: cannot down easycap_dongle[%i].mutex_audio\n", kd); + mutex_unlock(&(easycap_dongle[kd].mutex_video)); + JOM(4, "unlocked easycap_dongle[%i].mutex_video\n", kd); + SAM("ending unsuccessfully: may cause memory leak\n"); + return; + } + JOM(4, "locked easycap_dongle[%i].mutex_audio\n", kd); +} +JOM(4, "intf[%i]: %i=peasycap->kref.refcount.counter\n", \ bInterfaceNumber, (int)peasycap->kref.refcount.counter); kref_put(&peasycap->kref, easycap_delete); -JOM(4, "intf[%i]: kref_put() done.\n", bInterfaceNumber); +JOT(4, "intf[%i]: kref_put() done.\n", bInterfaceNumber); +if (0 <= kd && DONGLE_MANY > kd) { + mutex_unlock(&(easycap_dongle[kd].mutex_audio)); + JOT(4, "unlocked easycap_dongle[%i].mutex_audio\n", kd); + mutex_unlock(&easycap_dongle[kd].mutex_video); + JOT(4, "unlocked easycap_dongle[%i].mutex_video\n", kd); +} /*---------------------------------------------------------------------------*/ - JOM(4, "ends\n"); return; } diff --git a/drivers/staging/easycap/easycap_sound.c b/drivers/staging/easycap/easycap_sound.c index 0b4b60b0a5a7..dc97516cca43 100644 --- a/drivers/staging/easycap/easycap_sound.c +++ b/drivers/staging/easycap/easycap_sound.c @@ -636,7 +636,7 @@ else if ((struct usb_device *)NULL == peasycap->pusb_device) { SAM("ERROR: peasycap->pusb_device has become NULL\n"); - return -EFAULT; + return -ENODEV; } /*---------------------------------------------------------------------------*/ if ((struct usb_device *)NULL == peasycap->pusb_device) { @@ -695,7 +695,7 @@ long long int above, below, mean; struct signed_div_result sdr; unsigned char *p0; long int kount1, more, rc, l0, lm; -int fragment; +int fragment, kd; struct easycap *peasycap; struct data_buffer *pdata_buffer; size_t szret; @@ -713,20 +713,76 @@ size_t szret; JOT(8, "===== easysnd_read(): kount=%i, *poff=%i\n", (int)kount, (int)(*poff)); -peasycap = (struct easycap *)(file->private_data); +if (NULL == file) { + SAY("ERROR: file is NULL\n"); + return -ERESTARTSYS; +} +peasycap = file->private_data; if (NULL == peasycap) { SAY("ERROR in easysnd_read(): peasycap is NULL\n"); return -EFAULT; } +if (NULL == peasycap->pusb_device) { + SAY("ERROR in easysnd_read(): peasycap->pusb_device is NULL\n"); + return -EFAULT; +} +kd = isdongle(peasycap); +if (0 <= kd && DONGLE_MANY > kd) { + if (mutex_lock_interruptible(&(easycap_dongle[kd].mutex_audio))) { + SAY("ERROR: cannot lock easycap_dongle[%i].mutex_audio\n", kd); + return -ERESTARTSYS; + } + JOM(4, "locked easycap_dongle[%i].mutex_audio\n", kd); +/*---------------------------------------------------------------------------*/ +/* + * MEANWHILE, easycap_usb_disconnect() MAY HAVE FREED POINTER peasycap, + * IN WHICH CASE A REPEAT CALL TO isdongle() WILL FAIL. + * IF NECESSARY, BAIL OUT. +*/ +/*---------------------------------------------------------------------------*/ + if (kd != isdongle(peasycap)) + return -ERESTARTSYS; + if (NULL == file) { + SAY("ERROR: file is NULL\n"); + mutex_unlock(&easycap_dongle[kd].mutex_audio); + return -ERESTARTSYS; + } + peasycap = file->private_data; + if (NULL == peasycap) { + SAY("ERROR: peasycap is NULL\n"); + mutex_unlock(&easycap_dongle[kd].mutex_audio); + return -ERESTARTSYS; + } + if (NULL == peasycap->pusb_device) { + SAM("ERROR: peasycap->pusb_device is NULL\n"); + mutex_unlock(&easycap_dongle[kd].mutex_audio); + return -ERESTARTSYS; + } +} else { +/*---------------------------------------------------------------------------*/ +/* + * IF easycap_usb_disconnect() HAS ALREADY FREED POINTER peasycap BEFORE THE + * ATTEMPT TO ACQUIRE THE SEMAPHORE, isdongle() WILL HAVE FAILED. BAIL OUT. +*/ +/*---------------------------------------------------------------------------*/ + return -ERESTARTSYS; +} /*---------------------------------------------------------------------------*/ +if (file->f_flags & O_NONBLOCK) + JOT(16, "NONBLOCK kount=%i, *poff=%i\n", (int)kount, (int)(*poff)); +else + JOT(8, "BLOCKING kount=%i, *poff=%i\n", (int)kount, (int)(*poff)); + if ((0 > peasycap->audio_read) || \ (peasycap->audio_buffer_page_many <= peasycap->audio_read)) { SAM("ERROR: peasycap->audio_read out of range\n"); + mutex_unlock(&easycap_dongle[kd].mutex_audio); return -EFAULT; } pdata_buffer = &peasycap->audio_buffer[peasycap->audio_read]; if ((struct data_buffer *)NULL == pdata_buffer) { SAM("ERROR: pdata_buffer is NULL\n"); + mutex_unlock(&easycap_dongle[kd].mutex_audio); return -EFAULT; } JOM(12, "before wait, %i=frag read %i=frag fill\n", \ @@ -738,6 +794,7 @@ while ((fragment == (peasycap->audio_fill / \ (0 == (PAGE_SIZE - (pdata_buffer->pto - pdata_buffer->pgo)))) { if (file->f_flags & O_NONBLOCK) { JOM(16, "returning -EAGAIN as instructed\n"); + mutex_unlock(&easycap_dongle[kd].mutex_audio); return -EAGAIN; } rc = wait_event_interruptible(peasycap->wq_audio, \ @@ -747,21 +804,25 @@ while ((fragment == (peasycap->audio_fill / \ (0 < (PAGE_SIZE - (pdata_buffer->pto - pdata_buffer->pgo)))))); if (0 != rc) { SAM("aborted by signal\n"); + mutex_unlock(&easycap_dongle[kd].mutex_audio); return -ERESTARTSYS; } if (peasycap->audio_eof) { JOM(8, "returning 0 because %i=audio_eof\n", \ peasycap->audio_eof); kill_audio_urbs(peasycap); + mutex_unlock(&easycap_dongle[kd].mutex_audio); return 0; } if (peasycap->audio_idle) { JOM(16, "returning 0 because %i=audio_idle\n", \ peasycap->audio_idle); + mutex_unlock(&easycap_dongle[kd].mutex_audio); return 0; } if (!peasycap->audio_isoc_streaming) { JOM(16, "returning 0 because audio urbs not streaming\n"); + mutex_unlock(&easycap_dongle[kd].mutex_audio); return 0; } } @@ -773,15 +834,18 @@ while (fragment == (peasycap->audio_read / \ peasycap->audio_pages_per_fragment)) { if (NULL == pdata_buffer->pgo) { SAM("ERROR: pdata_buffer->pgo is NULL\n"); + mutex_unlock(&easycap_dongle[kd].mutex_audio); return -EFAULT; } if (NULL == pdata_buffer->pto) { SAM("ERROR: pdata_buffer->pto is NULL\n"); + mutex_unlock(&easycap_dongle[kd].mutex_audio); return -EFAULT; } kount1 = PAGE_SIZE - (pdata_buffer->pto - pdata_buffer->pgo); if (0 > kount1) { SAM("easysnd_read: MISTAKE: kount1 is negative\n"); + mutex_unlock(&easycap_dongle[kd].mutex_audio); return -ERESTARTSYS; } if (!kount1) { @@ -799,19 +863,23 @@ while (fragment == (peasycap->audio_read / \ (peasycap->audio_buffer_page_many <= \ peasycap->audio_read)) { SAM("ERROR: peasycap->audio_read out of range\n"); + mutex_unlock(&easycap_dongle[kd].mutex_audio); return -EFAULT; } pdata_buffer = &peasycap->audio_buffer[peasycap->audio_read]; if ((struct data_buffer *)NULL == pdata_buffer) { SAM("ERROR: pdata_buffer is NULL\n"); + mutex_unlock(&easycap_dongle[kd].mutex_audio); return -EFAULT; } if (NULL == pdata_buffer->pgo) { SAM("ERROR: pdata_buffer->pgo is NULL\n"); + mutex_unlock(&easycap_dongle[kd].mutex_audio); return -EFAULT; } if (NULL == pdata_buffer->pto) { SAM("ERROR: pdata_buffer->pto is NULL\n"); + mutex_unlock(&easycap_dongle[kd].mutex_audio); return -EFAULT; } kount1 = PAGE_SIZE - (pdata_buffer->pto - pdata_buffer->pgo); @@ -840,6 +908,7 @@ while (fragment == (peasycap->audio_read / \ rc = copy_to_user(puserspacebuffer, pdata_buffer->pto, more); if (0 != rc) { SAM("ERROR: copy_to_user() returned %li\n", rc); + mutex_unlock(&easycap_dongle[kd].mutex_audio); return -EFAULT; } *poff += (loff_t)more; @@ -902,6 +971,7 @@ JOM(8, "audio streaming at %lli bytes/second\n", sdr.quotient); peasycap->dnbydt = sdr.quotient; JOM(8, "returning %li\n", (long int)szret); +mutex_unlock(&easycap_dongle[kd].mutex_audio); return szret; } /*****************************************************************************/ -- cgit v1.2.3 From 268dfede46e24eef55a2ef7a10a462617936771e Mon Sep 17 00:00:00 2001 From: Mike Thomas Date: Sun, 7 Nov 2010 20:11:36 +0000 Subject: staging/easycap: Improve interface to the videodev module The changes here represent an intermediate step towards bringing the driver within the V4L2 framework. Signed-off-by: Mike Thomas Signed-off-by: Greg Kroah-Hartman --- drivers/staging/easycap/README | 93 ++++++++++++------ drivers/staging/easycap/easycap.h | 16 +--- drivers/staging/easycap/easycap_ioctl.c | 26 +++++- drivers/staging/easycap/easycap_main.c | 161 ++++++++++++++++++++++++++------ drivers/staging/easycap/easycap_sound.c | 63 ++++++++++++- 5 files changed, 287 insertions(+), 72 deletions(-) diff --git a/drivers/staging/easycap/README b/drivers/staging/easycap/README index 3775481f05e8..6b5ac0d34bd9 100644 --- a/drivers/staging/easycap/README +++ b/drivers/staging/easycap/README @@ -24,6 +24,9 @@ Two kinds of EasyCAP have this USB ID, namely: BUILD OPTIONS AND DEPENDENCIES ------------------------------ +Unless EASYCAP_DEBUG is defined during compilation it will not be possible +to select a debug level at the time of module installation. + If the parameter EASYCAP_IS_VIDEODEV_CLIENT is undefined during compilation the built module is entirely independent of the videodev module, and when the EasyCAP is physically plugged into a USB port the special files @@ -33,41 +36,54 @@ respectively. If the parameter EASYCAP_IS_VIDEODEV_CLIENT is defined during compilation the built easycap module is configured to register with the videodev module, in which case the special files created when the EasyCAP is plugged in are -/dev/video0 and /dev/easysnd0. Use of the easycap module as a client of -the videodev module has received very little testing as of June 2010. +/dev/video0 and /dev/easysnd0. + +During in-tree builds the following should should be defined whenever the +parameter EASYCAP_IS_VIDEODEV_CLIENT is defined: + +EASYCAP_NEEDS_V4L2_DEVICE_H +EASYCAP_NEEDS_V4L2_FOPS +EASYCAP_NEEDS_UNLOCKED_IOCTL + +If the build is performed out-of-tree against older kernels the parameters +to be defined depend on the kernel version in a way which will not be +discussed here. -KNOWN BUILD PROBLEMS +KNOWN RUNTIME ISSUES -------------------- -(1) Recent gcc versions may generate the message: +(1) Intentionally, this driver will not stream material which is unambiguously +identified by the hardware as copy-protected. Normal video output will be +present for about a minute but will then freeze when this situation arises. - warning: the frame size of .... bytes is larger than 1024 bytes +(2) The controls for luminance, contrast, saturation, hue and volume may not +always work properly. -This warning can be suppressed by specifying in the Makefile: +(3) Reduced-resolution S-Video seems to suffer from moire artefacts. - EXTRA_CFLAGS += -Wframe-larger-than=8192 -but it would be preferable to remove the cause of the warning. +INPUT NUMBERING +--------------- +For the EasyCAP with S-VIDEO input cable the driver regards a request for +inputs numbered 0 or 1 as referring to CVBS and a request for input +numbered 5 as referring to S-VIDEO. -KNOWN RUNTIME ISSUES --------------------- +For the EasyCAP with four CVBS inputs the driver expects to be asked for +any one of inputs numbered 1,2,3,4. If input 0 is asked for, it is +interpreted as input 1. -(1) Randomly (maybe 5 to 10% of occasions) the driver fails to produce any -output at start-up. Closing mplayer (or whatever the user program is) and -restarting it restores normal performance without any other remedial action -being necessary. The reason for this is not known. -(2) Intentionally, this driver will not stream material which is unambiguously -identified by the hardware as copy-protected. The video output will freeze -within about a minute when this situation arises. +MODULE PARAMETERS +----------------- -(3) The controls for luminance, contrast, saturation, hue and volume may not -always work properly. +Three module parameters are defined: -(4) Reduced-resolution S-Video seems to suffer from moire artefacts. No -attempt has yet been made to rememdy this. +debug the easycap module is configured at diagnostic level n (0 to 9) +gain audio gain level n (0 to 31, default is 16) +bars 0 => testcard bars when incoming video signal is lost + 1 => testcard bars when incoming video signal is lost (default) SUPPORTED TV STANDARDS AND RESOLUTIONS @@ -82,18 +98,29 @@ usable as (for example) the "norm=" parameter in the mplayer command: PAL_60, NTSC_443, PAL_M. +In addition, the driver offers "custom" pseudo-standards with a framerate +which is 20% of the usual framerate. These pseudo-standards are named: + + PAL_BGHIN_SLOW, NTSC_N_443_SLOW, + PAL_Nc_SLOW, NTSC_N_SLOW, + SECAM_SLOW, NTSC_M_SLOW, NTSC_M_JP_SLOW, + PAL_60_SLOW, NTSC_443_SLOW, + PAL_M_SLOW. + + The available picture sizes are: at 25 frames per second: 720x576, 704x576, 640x480, 360x288, 320x240; - at 30 frames per second: 720x480, 640x480, 360x240, 320x240; + at 30 frames per second: 720x480, 640x480, 360x240, 320x240. WHAT'S TESTED AND WHAT'S NOT ---------------------------- -This driver is known to work with mplayer, mencoder, tvtime and sufficiently -recent versions of vlc. An interface to ffmpeg is implemented, but serious -audio-video synchronization problems remain. +This driver is known to work with mplayer, mencoder, tvtime, zoneminder, +xawtv, gstreamer and sufficiently recent versions of vlc. An interface +to ffmpeg is implemented, but serious audio-video synchronization problems +remain. The driver is designed to support all the TV standards accepted by the hardware, but as yet it has actually been tested on only a few of these. @@ -101,10 +128,7 @@ hardware, but as yet it has actually been tested on only a few of these. I have been unable to test and calibrate the S-video input myself because I do not possess any equipment with S-video output. -This driver does not understand the V4L1 IOCTL commands, so programs such -as camorama are not compatible. There are reports that the driver does -work with sufficiently recent (V4L2) versions of zoneminder, but I have not -attempted to confirm this myself. +This driver does not understand the V4L1 IOCTL commands. UDEV RULES @@ -120,6 +144,17 @@ ATTRS{idVendor}=="05e1", ATTRS{idProduct}=="0408", \ LABEL="easycap_rules_end" +MODPROBE CONFIGURATION +---------------------- + +The easycap module is in competition with the module snd-usb-audio for the +EasyCAP's audio channel, and its installation can be aided by providing a +file in directory /etc/modprobe.d with content: + +options easycap gain=16 bars=1 +install easycap /sbin/rmmod snd-usb-audio; /sbin/modprobe --ignore-install easycap + + ACKNOWLEGEMENTS AND REFERENCES ------------------------------ This driver makes use of information contained in the Syntek Semicon DC-1125 diff --git a/drivers/staging/easycap/easycap.h b/drivers/staging/easycap/easycap.h index 762c6cea54c3..cc8e8c581ae8 100644 --- a/drivers/staging/easycap/easycap.h +++ b/drivers/staging/easycap/easycap.h @@ -33,6 +33,7 @@ * EASYCAP_NEEDS_USBVIDEO_H * EASYCAP_NEEDS_V4L2_DEVICE_H * EASYCAP_NEEDS_V4L2_FOPS + * EASYCAP_NEEDS_UNLOCKED_IOCTL * * IF REQUIRED THEY MUST BE EXTERNALLY DEFINED, FOR EXAMPLE AS COMPILER * OPTIONS. @@ -81,25 +82,14 @@ /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ #if defined(EASYCAP_IS_VIDEODEV_CLIENT) -#if (!defined(__OLD_VIDIOC_)) -#define __OLD_VIDIOC_ -#endif /* !defined(__OLD_VIDIOC_) */ - #include - #if defined(EASYCAP_NEEDS_V4L2_DEVICE_H) #include #endif /*EASYCAP_NEEDS_V4L2_DEVICE_H*/ #endif /*EASYCAP_IS_VIDEODEV_CLIENT*/ /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ - -#if (!defined(__OLD_VIDIOC_)) -#define __OLD_VIDIOC_ -#endif /* !defined(__OLD_VIDIOC_) */ #include - #include - #if defined(EASYCAP_NEEDS_USBVIDEO_H) #include #endif /*EASYCAP_NEEDS_USBVIDEO_H*/ @@ -110,7 +100,6 @@ #define STRINGIZE_AGAIN(x) #x #define STRINGIZE(x) STRINGIZE_AGAIN(x) - /*---------------------------------------------------------------------------*/ /* VENDOR, PRODUCT: Syntek Semiconductor Co., Ltd * @@ -305,6 +294,8 @@ int hue_ok; */ /*---------------------------------------------------------------------------*/ struct easycap { +#define TELLTALE "expectedstring" +char telltale[16]; int isdongle; /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ @@ -501,7 +492,6 @@ long easycap_ioctl_noinode(struct file *, unsigned int, \ unsigned long); int easycap_ioctl(struct inode *, struct file *, unsigned int, \ unsigned long); - /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ #if defined(EASYCAP_IS_VIDEODEV_CLIENT) int easycap_open_noinode(struct file *); diff --git a/drivers/staging/easycap/easycap_ioctl.c b/drivers/staging/easycap/easycap_ioctl.c index 2f9b3eab4898..447953a4e80c 100644 --- a/drivers/staging/easycap/easycap_ioctl.c +++ b/drivers/staging/easycap/easycap_ioctl.c @@ -977,9 +977,13 @@ if (NULL == file) { } peasycap = file->private_data; if (NULL == peasycap) { - SAY("ERROR: peasycap is NULL.\n"); + SAY("ERROR: peasycap is NULL\n"); return -1; } +if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { + SAY("ERROR: bad peasycap\n"); + return -EFAULT; +} p = peasycap->pusb_device; if (NULL == p) { SAM("ERROR: peasycap->pusb_device is NULL\n"); @@ -1012,6 +1016,11 @@ if (0 <= kd && DONGLE_MANY > kd) { mutex_unlock(&easycap_dongle[kd].mutex_video); return -ERESTARTSYS; } + if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { + SAY("ERROR: bad peasycap\n"); + mutex_unlock(&easycap_dongle[kd].mutex_video); + return -EFAULT; + } p = peasycap->pusb_device; if (NULL == peasycap->pusb_device) { SAM("ERROR: peasycap->pusb_device is NULL\n"); @@ -2297,7 +2306,7 @@ case VIDIOC_DQBUF: ((long long int)(timeval.tv_sec - \ timeval2.tv_sec)) + \ (long long int)(timeval.tv_usec - \ - timeval2.tv_usec); + timeval2.tv_usec); sdr = signed_div(fudge, 1000); sll = sdr.quotient; ull = sdr.remainder; @@ -2317,6 +2326,8 @@ case VIDIOC_DQBUF: JOM(16, " %10i=bytesused\n", v4l2_buffer.bytesused); JOM(16, " 0x%08X=flags\n", v4l2_buffer.flags); JOM(16, " %10i=field\n", v4l2_buffer.field); + JOM(16, " %10li=timestamp.tv_sec\n", \ + (long)v4l2_buffer.timestamp.tv_sec); JOM(16, " %10li=timestamp.tv_usec\n", \ (long)v4l2_buffer.timestamp.tv_usec); JOM(16, " %10i=sequence\n", v4l2_buffer.sequence); @@ -2528,6 +2539,10 @@ if (NULL == peasycap) { SAY("ERROR: peasycap is NULL.\n"); return -EFAULT; } +if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { + SAY("ERROR: bad peasycap\n"); + return -EFAULT; +} p = peasycap->pusb_device; if (NULL == p) { SAM("ERROR: peasycap->pusb_device is NULL\n"); @@ -2560,6 +2575,11 @@ if (0 <= kd && DONGLE_MANY > kd) { mutex_unlock(&easycap_dongle[kd].mutex_audio); return -ERESTARTSYS; } + if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { + SAY("ERROR: bad peasycap\n"); + mutex_unlock(&easycap_dongle[kd].mutex_audio); + return -EFAULT; + } p = peasycap->pusb_device; if (NULL == peasycap->pusb_device) { SAM("ERROR: peasycap->pusb_device is NULL\n"); @@ -2795,3 +2815,5 @@ mutex_unlock(&easycap_dongle[kd].mutex_audio); return 0; } /*****************************************************************************/ + + diff --git a/drivers/staging/easycap/easycap_main.c b/drivers/staging/easycap/easycap_main.c index 67ae755fcfac..25e41784f4e5 100644 --- a/drivers/staging/easycap/easycap_main.c +++ b/drivers/staging/easycap/easycap_main.c @@ -93,16 +93,15 @@ const struct file_operations easycap_fops = { .llseek = no_llseek, }; struct vm_operations_struct easycap_vm_ops = { -.open = easycap_vma_open, -.close = easycap_vma_close, -.fault = easycap_vma_fault, + .open = easycap_vma_open, + .close = easycap_vma_close, + .fault = easycap_vma_fault, }; struct usb_class_driver easycap_class = { -.name = "usb/easycap%d", -.fops = &easycap_fops, -.minor_base = USB_SKEL_MINOR_BASE, + .name = "usb/easycap%d", + .fops = &easycap_fops, + .minor_base = USB_SKEL_MINOR_BASE, }; - /*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ #if defined(EASYCAP_IS_VIDEODEV_CLIENT) #if defined(EASYCAP_NEEDS_V4L2_FOPS) @@ -121,7 +120,6 @@ const struct v4l2_file_operations v4l2_fops = { #endif /*EASYCAP_NEEDS_V4L2_FOPS*/ #endif /*EASYCAP_IS_VIDEODEV_CLIENT*/ /*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ - /*--------------------------------------------------------------------------*/ /* * PARAMETERS USED WHEN REGISTERING THE AUDIO INTERFACE @@ -147,7 +145,7 @@ struct usb_class_driver easysnd_class = { /****************************************************************************/ /*---------------------------------------------------------------------------*/ /* - * THIS ROUTINE DOES NOT DETECT MULTIPLE OCCURRENCES OF POINTER peasycap + * THIS ROUTINE DOES NOT DETECT DUPLICATE OCCURRENCES OF POINTER peasycap */ /*---------------------------------------------------------------------------*/ int @@ -215,6 +213,10 @@ if (NULL == peasycap) { SAY("ERROR: peasycap is NULL\n"); return -EFAULT; } +if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { + SAY("ERROR: bad peasycap: 0x%08lX\n", (unsigned long int) peasycap); + return -EFAULT; +} if (NULL == peasycap->pusb_device) { SAM("ERROR: peasycap->pusb_device is NULL\n"); return -EFAULT; @@ -838,6 +840,10 @@ if (NULL == peasycap) { SAY("ending unsuccessfully\n"); return -EFAULT; } +if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { + SAY("ERROR: bad peasycap: 0x%08lX\n", (unsigned long int) peasycap); + return -EFAULT; +} if (0 != kill_video_urbs(peasycap)) { SAM("ERROR: kill_video_urbs() failed\n"); return -EFAULT; @@ -867,6 +873,10 @@ if (NULL == peasycap) { SAY("ending unsuccessfully\n"); return -EFAULT; } +if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { + SAY("ERROR: bad peasycap: 0x%08lX\n", (unsigned long int) peasycap); + return -EFAULT; +} if (0 != kill_video_urbs(peasycap)) { SAM("ERROR: kill_video_urbs() failed\n"); return -EFAULT; @@ -904,6 +914,10 @@ if (NULL == peasycap) { SAM("ERROR: peasycap is NULL: cannot perform deletions\n"); return; } +if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { + SAY("ERROR: bad peasycap: 0x%08lX\n", (unsigned long int) peasycap); + return; +} kd = isdongle(peasycap); /*---------------------------------------------------------------------------*/ /* @@ -1026,8 +1040,6 @@ if ((struct list_head *)NULL != peasycap->purb_audio_head) { JOM(4, "%i audio data_urb structures freed\n", m); JOM(4, "setting peasycap->purb_audio_head=NULL\n"); peasycap->purb_audio_head = (struct list_head *)NULL; -} else { -JOM(4, "peasycap->purb_audio_head is NULL\n"); } /*---------------------------------------------------------------------------*/ JOM(4, "freeing audio isoc buffers.\n"); @@ -1108,6 +1120,10 @@ if (NULL == peasycap) { SAY("ERROR: peasycap is NULL\n"); return -EFAULT; } +if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { + SAY("ERROR: bad peasycap: 0x%08lX\n", (unsigned long int) peasycap); + return -EFAULT; +} if (NULL == peasycap->pusb_device) { SAY("ERROR: peasycap->pusb_device is NULL\n"); return -EFAULT; @@ -1140,10 +1156,16 @@ if (0 <= kd && DONGLE_MANY > kd) { mutex_unlock(&easycap_dongle[kd].mutex_video); return -ERESTARTSYS; } + if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { + SAY("ERROR: bad peasycap: 0x%08lX\n", \ + (unsigned long int) peasycap); + mutex_unlock(&easycap_dongle[kd].mutex_video); + return -ERESTARTSYS; + } if (NULL == peasycap->pusb_device) { SAM("ERROR: peasycap->pusb_device is NULL\n"); mutex_unlock(&easycap_dongle[kd].mutex_video); - return -ERESTARTSYS; + return -ERESTARTSYS; } } else /*-------------------------------------------------------------------*/ @@ -2687,11 +2709,16 @@ easycap_vma_open(struct vm_area_struct *pvma) struct easycap *peasycap; peasycap = pvma->vm_private_data; -if (NULL != peasycap) - peasycap->vma_many++; - +if (NULL == peasycap) { + SAY("ERROR: peasycap is NULL\n"); + return; +} +if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { + SAY("ERROR: bad peasycap: 0x%08lX\n", (unsigned long int) peasycap); + return; +} +peasycap->vma_many++; JOT(8, "%i=peasycap->vma_many\n", peasycap->vma_many); - return; } /*****************************************************************************/ @@ -2701,10 +2728,16 @@ easycap_vma_close(struct vm_area_struct *pvma) struct easycap *peasycap; peasycap = pvma->vm_private_data; -if (NULL != peasycap) { - peasycap->vma_many--; - JOT(8, "%i=peasycap->vma_many\n", peasycap->vma_many); +if (NULL == peasycap) { + SAY("ERROR: peasycap is NULL\n"); + return; +} +if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { + SAY("ERROR: bad peasycap: 0x%08lX\n", (unsigned long int) peasycap); + return; } +peasycap->vma_many--; +JOT(8, "%i=peasycap->vma_many\n", peasycap->vma_many); return; } /*****************************************************************************/ @@ -2820,10 +2853,12 @@ if (NULL == peasycap) { SAY("ERROR: easycap_complete(): peasycap is NULL\n"); return; } - +if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { + SAY("ERROR: bad peasycap: 0x%08lX\n", (unsigned long int) peasycap); + return; +} if (peasycap->video_eof) return; - for (i = 0; i < VIDEO_ISOC_BUFFER_MANY; i++) if (purb->transfer_buffer == peasycap->video_isoc_buffer[i].pgo) break; @@ -3545,6 +3580,7 @@ if (0 == bInterfaceNumber) { * PERFORM URGENT INTIALIZATIONS ... */ /*---------------------------------------------------------------------------*/ + strcpy(&peasycap->telltale[0], TELLTALE); kref_init(&peasycap->kref); JOM(8, "intf[%i]: after kref_init(..._video) " \ "%i=peasycap->kref.refcount.counter\n", \ @@ -4299,6 +4335,26 @@ case 0: { */ /*--------------------------------------------------------------------------*/ usb_set_intfdata(pusb_interface, peasycap); +/*---------------------------------------------------------------------------*/ +/* + * IT IS ESSENTIAL TO INITIALIZE THE HARDWARE BEFORE, RATHER THAN AFTER, + * THE DEVICE IS REGISTERED, BECAUSE SOME VERSIONS OF THE videodev MODULE + * CALL easycap_open() IMMEDIATELY AFTER REGISTRATION, CAUSING A CLASH. + * BEWARE. +*/ +/*---------------------------------------------------------------------------*/ +#if defined(PREFER_NTSC) + peasycap->ntsc = true; + JOM(8, "defaulting initially to NTSC\n"); +#else + peasycap->ntsc = false; + JOM(8, "defaulting initially to PAL\n"); +#endif /*PREFER_NTSC*/ + rc = reset(peasycap); + if (0 != rc) { + SAM("ERROR: reset() returned %i\n", rc); + return -EFAULT; + } /*--------------------------------------------------------------------------*/ /* * THE VIDEO DEVICE CAN BE REGISTERED NOW, AS IT IS READY. @@ -4687,6 +4743,13 @@ struct easycap *peasycap; struct list_head *plist_head; struct data_urb *pdata_urb; int minor, m, kd; +/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +#if defined(EASYCAP_IS_VIDEODEV_CLIENT) +#if defined(EASYCAP_NEEDS_V4L2_DEVICE_H) +struct v4l2_device *pv4l2_device; +#endif /*EASYCAP_NEEDS_V4L2_DEVICE_H*/ +#endif /*EASYCAP_IS_VIDEODEV_CLIENT*/ +/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ JOT(4, "\n"); @@ -4717,6 +4780,38 @@ if (NULL == peasycap) { return; } /*---------------------------------------------------------------------------*/ +#if (!defined(EASYCAP_IS_VIDEODEV_CLIENT)) +# +/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +#else +#if defined(EASYCAP_NEEDS_V4L2_DEVICE_H) +/*---------------------------------------------------------------------------*/ +/* + * SOME VERSIONS OF THE videodev MODULE OVERWRITE THE DATA WHICH HAS + * BEEN WRITTEN BY THE CALL TO usb_set_intfdata() IN easycap_usb_probe(), + * REPLACING IT WITH A POINTER TO THE EMBEDDED v4l2_device STRUCTURE. + * TO DETECT THIS, THE STRING IN THE easycap.telltale[] BUFFER IS CHECKED. +*/ +/*---------------------------------------------------------------------------*/ +if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { + pv4l2_device = usb_get_intfdata(pusb_interface); + if ((struct v4l2_device *)NULL == pv4l2_device) { + SAY("ERROR: pv4l2_device is NULL\n"); + return; + } + peasycap = (struct easycap *) \ + container_of(pv4l2_device, struct easycap, v4l2_device); +} +#endif /*EASYCAP_NEEDS_V4L2_DEVICE_H*/ +# +#endif /*EASYCAP_IS_VIDEODEV_CLIENT*/ +/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +/*---------------------------------------------------------------------------*/ +if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { + SAY("ERROR: bad peasycap: 0x%08lX\n", (unsigned long int) peasycap); + return; +} +/*---------------------------------------------------------------------------*/ /* * IF THE WAIT QUEUES ARE NOT CLEARED A DEADLOCK IS POSSIBLE. BEWARE. */ @@ -4806,14 +4901,28 @@ case 0: { JOM(4, "intf[%i]: usb_deregister_dev()\n", bInterfaceNumber); SAM("easycap detached from minor #%d\n", minor); } -/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ #else +#if defined(EASYCAP_NEEDS_V4L2_DEVICE_H) + if (!peasycap->v4l2_device.name[0]) { + SAM("ERROR: peasycap->v4l2_device.name is empty\n"); + if (0 <= kd && DONGLE_MANY > kd) + mutex_unlock(&easycap_dongle[kd].mutex_video); + return; + } + v4l2_device_disconnect(&peasycap->v4l2_device); + JOM(4, "v4l2_device_disconnect() OK\n"); + v4l2_device_unregister(&peasycap->v4l2_device); + JOM(4, "v4l2_device_unregister() OK\n"); +#endif /*EASYCAP_NEEDS_V4L2_DEVICE_H*/ + video_unregister_device(&peasycap->video_device); - JOM(4, "unregistered with videodev: %i=minor\n", \ - peasycap->video_device.minor); + JOM(4, "intf[%i]: video_unregister_device() OK\n", bInterfaceNumber); (peasycap->registered_video)--; -/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ + JOM(4, "unregistered with videodev: %i=minor\n", minor); #endif /*EASYCAP_IS_VIDEODEV_CLIENT*/ +/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ + if (0 <= kd && DONGLE_MANY > kd) { mutex_unlock(&easycap_dongle[kd].mutex_video); JOM(4, "unlocked easycap_dongle[%i].mutex_video\n", kd); @@ -4941,7 +5050,7 @@ MODULE_AUTHOR("R.M. Thomas "); MODULE_DESCRIPTION(EASYCAP_DRIVER_DESCRIPTION); MODULE_VERSION(EASYCAP_DRIVER_VERSION); #if defined(EASYCAP_DEBUG) -MODULE_PARM_DESC(debug, "Debug level: 0 (default),1,2,..."); +MODULE_PARM_DESC(debug, "Debug level: 0(default),1,2,...,9"); #endif /*EASYCAP_DEBUG*/ MODULE_PARM_DESC(bars, \ "Testcard bars on input signal failure: 0=>no, 1=>yes(default)"); diff --git a/drivers/staging/easycap/easycap_sound.c b/drivers/staging/easycap/easycap_sound.c index dc97516cca43..24d8bb4e449e 100644 --- a/drivers/staging/easycap/easycap_sound.c +++ b/drivers/staging/easycap/easycap_sound.c @@ -64,6 +64,11 @@ if (NULL == peasycap) { SAY("ERROR: peasycap is NULL\n"); return; } +if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { + SAY("ERROR: bad peasycap\n"); + return; +} + much = 0; if (peasycap->audio_idle) { @@ -595,6 +600,13 @@ easysnd_open(struct inode *inode, struct file *file) struct usb_interface *pusb_interface; struct easycap *peasycap; int subminor, rc; +/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +#if defined(EASYCAP_IS_VIDEODEV_CLIENT) +#if defined(EASYCAP_NEEDS_V4L2_DEVICE_H) +struct v4l2_device *pv4l2_device; +#endif /*EASYCAP_NEEDS_V4L2_DEVICE_H*/ +#endif /*EASYCAP_IS_VIDEODEV_CLIENT*/ +/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ JOT(4, "begins\n"); @@ -612,6 +624,39 @@ if (NULL == peasycap) { SAY("ending unsuccessfully\n"); return -1; } +/*---------------------------------------------------------------------------*/ +#if (!defined(EASYCAP_IS_VIDEODEV_CLIENT)) +# +/*vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv*/ +#else +#if defined(EASYCAP_NEEDS_V4L2_DEVICE_H) +/*---------------------------------------------------------------------------*/ +/* + * SOME VERSIONS OF THE videodev MODULE OVERWRITE THE DATA WHICH HAS + * BEEN WRITTEN BY THE CALL TO usb_set_intfdata() IN easycap_usb_probe(), + * REPLACING IT WITH A POINTER TO THE EMBEDDED v4l2_device STRUCTURE. + * TO DETECT THIS, THE STRING IN THE easycap.telltale[] BUFFER IS CHECKED. +*/ +/*---------------------------------------------------------------------------*/ +if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { + pv4l2_device = usb_get_intfdata(pusb_interface); + if ((struct v4l2_device *)NULL == pv4l2_device) { + SAY("ERROR: pv4l2_device is NULL\n"); + return -EFAULT; + } + peasycap = (struct easycap *) \ + container_of(pv4l2_device, struct easycap, v4l2_device); +} +#endif /*EASYCAP_NEEDS_V4L2_DEVICE_H*/ +# +#endif /*EASYCAP_IS_VIDEODEV_CLIENT*/ +/*^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^*/ +/*---------------------------------------------------------------------------*/ +if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { + SAY("ERROR: bad peasycap: 0x%08lX\n", (unsigned long int) peasycap); + return -EFAULT; +} +/*---------------------------------------------------------------------------*/ file->private_data = peasycap; @@ -624,7 +669,7 @@ JOM(4, "starting initialization\n"); if ((struct usb_device *)NULL == peasycap->pusb_device) { SAM("ERROR: peasycap->pusb_device is NULL\n"); - return -EFAULT; + return -ENODEV; } JOM(16, "0x%08lX=peasycap->pusb_device\n", (long int)peasycap->pusb_device); @@ -641,7 +686,7 @@ if ((struct usb_device *)NULL == peasycap->pusb_device) { /*---------------------------------------------------------------------------*/ if ((struct usb_device *)NULL == peasycap->pusb_device) { SAM("ERROR: peasycap->pusb_device has become NULL\n"); - return -EFAULT; + return -ENODEV; } rc = usb_set_interface(peasycap->pusb_device, peasycap->audio_interface, \ peasycap->audio_altsetting_on); @@ -678,6 +723,10 @@ if (NULL == peasycap) { SAY("ERROR: peasycap is NULL.\n"); return -EFAULT; } +if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { + SAY("ERROR: bad peasycap: 0x%08lX\n", (unsigned long int) peasycap); + return -EFAULT; +} if (0 != kill_audio_urbs(peasycap)) { SAM("ERROR: kill_audio_urbs() failed\n"); return -EFAULT; @@ -722,6 +771,10 @@ if (NULL == peasycap) { SAY("ERROR in easysnd_read(): peasycap is NULL\n"); return -EFAULT; } +if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { + SAY("ERROR: bad peasycap: 0x%08lX\n", (unsigned long int) peasycap); + return -EFAULT; +} if (NULL == peasycap->pusb_device) { SAY("ERROR in easysnd_read(): peasycap->pusb_device is NULL\n"); return -EFAULT; @@ -753,6 +806,12 @@ if (0 <= kd && DONGLE_MANY > kd) { mutex_unlock(&easycap_dongle[kd].mutex_audio); return -ERESTARTSYS; } + if (memcmp(&peasycap->telltale[0], TELLTALE, strlen(TELLTALE))) { + SAY("ERROR: bad peasycap: 0x%08lX\n", \ + (unsigned long int) peasycap); + mutex_unlock(&easycap_dongle[kd].mutex_audio); + return -ERESTARTSYS; + } if (NULL == peasycap->pusb_device) { SAM("ERROR: peasycap->pusb_device is NULL\n"); mutex_unlock(&easycap_dongle[kd].mutex_audio); -- cgit v1.2.3 From a2ac9d69d69d8df88d4096903f5f76fe2de2345b Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Sun, 7 Nov 2010 12:22:18 -0600 Subject: staging: r8712u: Remove unneeded local variable in _malloc in osdep_service.h header The variable 'pbuf' is not needed. Signed-off-by: Jesper Juhl Signed-off-by: Larry Finger Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8712/osdep_service.h | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/drivers/staging/rtl8712/osdep_service.h b/drivers/staging/rtl8712/osdep_service.h index d1674cd282dc..f891a1b02180 100644 --- a/drivers/staging/rtl8712/osdep_service.h +++ b/drivers/staging/rtl8712/osdep_service.h @@ -196,10 +196,7 @@ static inline void sleep_schedulable(int ms) static inline u8 *_malloc(u32 sz) { - u8 *pbuf; - - pbuf = kmalloc(sz, GFP_ATOMIC); - return pbuf; + return kmalloc(sz, GFP_ATOMIC); } static inline unsigned char _cancel_timer_ex(struct timer_list *ptimer) -- cgit v1.2.3 From 4c510e95aef6138242ed4bc7fe29ee184bea413f Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Sun, 7 Nov 2010 12:22:18 -0600 Subject: staging: r8712u: Remove extraneous variables from osdep_service.h Jesper Juhl submitted a patch to remove one extraneous variable in this file; however, there are several others. Signed-off-by: Larry Finger Reviewed-by: Jesper Juhl Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8712/osdep_service.h | 20 ++++---------------- 1 file changed, 4 insertions(+), 16 deletions(-) diff --git a/drivers/staging/rtl8712/osdep_service.h b/drivers/staging/rtl8712/osdep_service.h index f891a1b02180..7d62714ff412 100644 --- a/drivers/staging/rtl8712/osdep_service.h +++ b/drivers/staging/rtl8712/osdep_service.h @@ -218,34 +218,22 @@ static inline void flush_signals_thread(void) static inline u32 _RND8(u32 sz) { - u32 val; - - val = ((sz >> 3) + ((sz & 7) ? 1 : 0)) << 3; - return val; + return ((sz >> 3) + ((sz & 7) ? 1 : 0)) << 3; } static inline u32 _RND128(u32 sz) { - u32 val; - - val = ((sz >> 7) + ((sz & 127) ? 1 : 0)) << 7; - return val; + return ((sz >> 7) + ((sz & 127) ? 1 : 0)) << 7; } static inline u32 _RND256(u32 sz) { - u32 val; - - val = ((sz >> 8) + ((sz & 255) ? 1 : 0)) << 8; - return val; + return ((sz >> 8) + ((sz & 255) ? 1 : 0)) << 8; } static inline u32 _RND512(u32 sz) { - u32 val; - - val = ((sz >> 9) + ((sz & 511) ? 1 : 0)) << 9; - return val; + return ((sz >> 9) + ((sz & 511) ? 1 : 0)) << 9; } #define STRUCT_PACKED __attribute__ ((packed)) -- cgit v1.2.3 From 4eb28f7197a2cbaf7a9be778d429a5fb9bb6172e Mon Sep 17 00:00:00 2001 From: Johan Meiring Date: Sat, 6 Nov 2010 15:46:54 +0200 Subject: Staging: wlan-ng: fixed coding style issues in p80211conv.c This is a patch to the p80211conv.c file that fixes a couple of coding style issues found by the checkpatch.pl tool. Signed-off-by: Johan Meiring Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wlan-ng/p80211conv.c | 45 ++++++++++++++++++++++-------------- 1 file changed, 28 insertions(+), 17 deletions(-) diff --git a/drivers/staging/wlan-ng/p80211conv.c b/drivers/staging/wlan-ng/p80211conv.c index 83879f9a0b7d..146f3651b6f2 100644 --- a/drivers/staging/wlan-ng/p80211conv.c +++ b/drivers/staging/wlan-ng/p80211conv.c @@ -148,7 +148,8 @@ int skb_ether_to_p80211(wlandevice_t *wlandev, u32 ethconv, /* tack on SNAP */ e_snap = - (struct wlan_snap *) skb_push(skb, sizeof(struct wlan_snap)); + (struct wlan_snap *) skb_push(skb, + sizeof(struct wlan_snap)); e_snap->type = htons(proto); if (ethconv == WLAN_ETHCONV_8021h && p80211_stt_findproto(proto)) { @@ -161,7 +162,8 @@ int skb_ether_to_p80211(wlandevice_t *wlandev, u32 ethconv, /* tack on llc */ e_llc = - (struct wlan_llc *) skb_push(skb, sizeof(struct wlan_llc)); + (struct wlan_llc *) skb_push(skb, + sizeof(struct wlan_llc)); e_llc->dsap = 0xAA; /* SNAP, see IEEE 802 */ e_llc->ssap = 0xAA; e_llc->ctl = 0x03; @@ -297,10 +299,12 @@ int skb_p80211_to_ether(wlandevice_t *wlandev, u32 ethconv, if ((WLAN_GET_FC_TODS(fc) == 0) && (WLAN_GET_FC_FROMDS(fc) == 0)) { memcpy(daddr, w_hdr->a3.a1, WLAN_ETHADDR_LEN); memcpy(saddr, w_hdr->a3.a2, WLAN_ETHADDR_LEN); - } else if ((WLAN_GET_FC_TODS(fc) == 0) && (WLAN_GET_FC_FROMDS(fc) == 1)) { + } else if ((WLAN_GET_FC_TODS(fc) == 0) + && (WLAN_GET_FC_FROMDS(fc) == 1)) { memcpy(daddr, w_hdr->a3.a1, WLAN_ETHADDR_LEN); memcpy(saddr, w_hdr->a3.a3, WLAN_ETHADDR_LEN); - } else if ((WLAN_GET_FC_TODS(fc) == 1) && (WLAN_GET_FC_FROMDS(fc) == 0)) { + } else if ((WLAN_GET_FC_TODS(fc) == 1) + && (WLAN_GET_FC_FROMDS(fc) == 0)) { memcpy(daddr, w_hdr->a3.a3, WLAN_ETHADDR_LEN); memcpy(saddr, w_hdr->a3.a2, WLAN_ETHADDR_LEN); } else { @@ -349,7 +353,8 @@ int skb_p80211_to_ether(wlandevice_t *wlandev, u32 ethconv, e_llc = (struct wlan_llc *) (skb->data + payload_offset); e_snap = - (struct wlan_snap *) (skb->data + payload_offset + sizeof(struct wlan_llc)); + (struct wlan_snap *) (skb->data + payload_offset + + sizeof(struct wlan_llc)); /* Test for the various encodings */ if ((payload_length >= sizeof(struct wlan_ethhdr)) && @@ -372,9 +377,11 @@ int skb_p80211_to_ether(wlandevice_t *wlandev, u32 ethconv, /* chop off the 802.11 CRC */ skb_trim(skb, skb->len - WLAN_CRC_LEN); - } else if ((payload_length >= sizeof(struct wlan_llc) + sizeof(struct wlan_snap)) - && (e_llc->dsap == 0xaa) && (e_llc->ssap == 0xaa) - && (e_llc->ctl == 0x03) + } else if ((payload_length >= sizeof(struct wlan_llc) + + sizeof(struct wlan_snap)) + &&(e_llc->dsap == 0xaa) + && (e_llc->ssap == 0xaa) + && (e_llc->ctl == 0x03) && (((memcmp(e_snap->oui, oui_rfc1042, WLAN_IEEE_OUI_LEN) == 0) && (ethconv == WLAN_ETHCONV_8021h) @@ -406,21 +413,25 @@ int skb_p80211_to_ether(wlandevice_t *wlandev, u32 ethconv, /* chop off the 802.11 CRC */ skb_trim(skb, skb->len - WLAN_CRC_LEN); - } else if ((payload_length >= sizeof(struct wlan_llc) + sizeof(struct wlan_snap)) - && (e_llc->dsap == 0xaa) && (e_llc->ssap == 0xaa) - && (e_llc->ctl == 0x03)) { + } else if ((payload_length >= sizeof(struct wlan_llc) + + sizeof(struct wlan_snap)) + &&(e_llc->dsap == 0xaa) + && (e_llc->ssap == 0xaa) + && (e_llc->ctl == 0x03)) { pr_debug("802.1h/RFC1042 len: %d\n", payload_length); - /* it's an 802.1h frame || (an RFC1042 && protocol is not in STT) */ - /* build a DIXII + RFC894 */ + /* it's an 802.1h frame || (an RFC1042 && protocol not in STT) + build a DIXII + RFC894 */ /* Test for an overlength frame */ - if ((payload_length - sizeof(struct wlan_llc) - sizeof(struct wlan_snap)) - > netdev->mtu) { + if ((payload_length - sizeof(struct wlan_llc) - + sizeof(struct wlan_snap)) + > netdev->mtu) { /* A bogus length ethfrm has been sent. */ /* Is someone trying an oflow attack? */ printk(KERN_ERR "DIXII frame too large (%ld > %d)\n", - (long int)(payload_length - sizeof(struct wlan_llc) - - sizeof(struct wlan_snap)), netdev->mtu); + (long int)(payload_length - + sizeof(struct wlan_llc) - + sizeof(struct wlan_snap)), netdev->mtu); return 1; } -- cgit v1.2.3 From 5b84cc781058bb452f869d84bb24442ec51948c4 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Thu, 4 Nov 2010 20:07:59 -0700 Subject: staging: Use vzalloc Signed-off-by: Joe Perches Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers.c | 4 +--- drivers/staging/rtl8192e/r8192E_core.c | 4 +--- drivers/staging/udlfb/udlfb.c | 5 ++--- drivers/staging/xgifb/XGI_main_26.c | 3 +-- drivers/staging/zram/zram_drv.c | 3 +-- 5 files changed, 6 insertions(+), 13 deletions(-) diff --git a/drivers/staging/comedi/drivers.c b/drivers/staging/comedi/drivers.c index 4a29ed737e3f..ef24a530278b 100644 --- a/drivers/staging/comedi/drivers.c +++ b/drivers/staging/comedi/drivers.c @@ -470,10 +470,8 @@ int comedi_buf_alloc(struct comedi_device *dev, struct comedi_subdevice *s, struct page **pages = NULL; async->buf_page_list = - vmalloc(sizeof(struct comedi_buf_page) * n_pages); + vzalloc(sizeof(struct comedi_buf_page) * n_pages); if (async->buf_page_list) { - memset(async->buf_page_list, 0, - sizeof(struct comedi_buf_page) * n_pages); pages = vmalloc(sizeof(struct page *) * n_pages); } if (pages) { diff --git a/drivers/staging/rtl8192e/r8192E_core.c b/drivers/staging/rtl8192e/r8192E_core.c index a202194b5cbb..c870014c559e 100644 --- a/drivers/staging/rtl8192e/r8192E_core.c +++ b/drivers/staging/rtl8192e/r8192E_core.c @@ -2283,9 +2283,7 @@ static void rtl8192_init_priv_variable(struct net_device* dev) IMR_TXFOVW | IMR_BcnInt | IMR_TBDOK | IMR_TBDER); priv->AcmControl = 0; - priv->pFirmware = (rt_firmware*)vmalloc(sizeof(rt_firmware)); - if (priv->pFirmware) - memset(priv->pFirmware, 0, sizeof(rt_firmware)); + priv->pFirmware = vzalloc(sizeof(rt_firmware)); /* rx related queue */ skb_queue_head_init(&priv->rx_queue); diff --git a/drivers/staging/udlfb/udlfb.c b/drivers/staging/udlfb/udlfb.c index 5969e848d297..e2283294c71a 100644 --- a/drivers/staging/udlfb/udlfb.c +++ b/drivers/staging/udlfb/udlfb.c @@ -1163,14 +1163,13 @@ static int dlfb_realloc_framebuffer(struct dlfb_data *dev, struct fb_info *info) * But with imperfect damage info we may send pixels over USB * that were, in fact, unchanged - wasting limited USB bandwidth */ - new_back = vmalloc(new_len); + new_back = vzalloc(new_len); if (!new_back) - dl_info("No shadow/backing buffer allcoated\n"); + dl_info("No shadow/backing buffer allocated\n"); else { if (dev->backing_buffer) vfree(dev->backing_buffer); dev->backing_buffer = new_back; - memset(dev->backing_buffer, 0, new_len); } } diff --git a/drivers/staging/xgifb/XGI_main_26.c b/drivers/staging/xgifb/XGI_main_26.c index 36ec45b84fca..ee008e5a0cbc 100644 --- a/drivers/staging/xgifb/XGI_main_26.c +++ b/drivers/staging/xgifb/XGI_main_26.c @@ -2180,8 +2180,7 @@ static int XGIfb_heap_init(void) #ifndef AGPOFF if (XGIfb_queuemode == AGP_CMD_QUEUE) { - agp_info = vmalloc(sizeof(*agp_info)); - memset((void *)agp_info, 0x00, sizeof(*agp_info)); + agp_info = vzalloc(sizeof(*agp_info)); agp_copy_info(agp_info); agp_backend_acquire(); diff --git a/drivers/staging/zram/zram_drv.c b/drivers/staging/zram/zram_drv.c index 8c3c057aa847..43fd6086bddf 100644 --- a/drivers/staging/zram/zram_drv.c +++ b/drivers/staging/zram/zram_drv.c @@ -533,7 +533,7 @@ int zram_init_device(struct zram *zram) } num_pages = zram->disksize >> PAGE_SHIFT; - zram->table = vmalloc(num_pages * sizeof(*zram->table)); + zram->table = vzalloc(num_pages * sizeof(*zram->table)); if (!zram->table) { pr_err("Error allocating zram address table\n"); /* To prevent accessing table entries during cleanup */ @@ -541,7 +541,6 @@ int zram_init_device(struct zram *zram) ret = -ENOMEM; goto fail; } - memset(zram->table, 0, num_pages * sizeof(*zram->table)); set_capacity(zram->disk, zram->disksize >> SECTOR_SHIFT); -- cgit v1.2.3 From 4314e5a68ab014092a55d5b2b26964952a97bc85 Mon Sep 17 00:00:00 2001 From: Johan Meiring Date: Sat, 6 Nov 2010 18:22:42 +0200 Subject: Staging: wlan-ng: fixed coding style issues in p80211netdev.h This is a patch to the p80211netdev.h file that fixes up warnings found by the checkpatch.pl tool. The typedefs have been left in place as they seem necessary. Signed-off-by: Johan Meiring Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wlan-ng/p80211netdev.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/staging/wlan-ng/p80211netdev.h b/drivers/staging/wlan-ng/p80211netdev.h index 1ec33740f10f..85884176b661 100644 --- a/drivers/staging/wlan-ng/p80211netdev.h +++ b/drivers/staging/wlan-ng/p80211netdev.h @@ -94,11 +94,11 @@ typedef struct net_device netdevice_t; #endif /*--- NSD Capabilities Flags ------------------------------*/ -#define P80211_NSDCAP_HARDWAREWEP 0x01 /* hardware wep engine */ -#define P80211_NSDCAP_SHORT_PREAMBLE 0x10 /* hardware supports */ -#define P80211_NSDCAP_HWFRAGMENT 0x80 /* nsd handles frag/defrag */ -#define P80211_NSDCAP_AUTOJOIN 0x100 /* nsd does autojoin */ -#define P80211_NSDCAP_NOSCAN 0x200 /* nsd can scan */ +#define P80211_NSDCAP_HARDWAREWEP 0x01 /* hardware wep engine */ +#define P80211_NSDCAP_SHORT_PREAMBLE 0x10 /* hardware supports */ +#define P80211_NSDCAP_HWFRAGMENT 0x80 /* nsd handles frag/defrag */ +#define P80211_NSDCAP_AUTOJOIN 0x100 /* nsd does autojoin */ +#define P80211_NSDCAP_NOSCAN 0x200 /* nsd can scan */ /* Received frame statistics */ typedef struct p80211_frmrx_t { -- cgit v1.2.3 From c5de2157b801b9f38c7852b4d30fea8aff0c1bbd Mon Sep 17 00:00:00 2001 From: Johan Meiring Date: Sat, 6 Nov 2010 18:23:09 +0200 Subject: Staging: wlan-ng: fix coding style issues in p80211types.h This is a patch that fixes various coding style issues in p80211types.h. The typedef declarations have been kept as they seem necessary. Signed-off-by: Johan Meiring Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wlan-ng/p80211types.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/wlan-ng/p80211types.h b/drivers/staging/wlan-ng/p80211types.h index 41a99c59c6c5..9dec8596f451 100644 --- a/drivers/staging/wlan-ng/p80211types.h +++ b/drivers/staging/wlan-ng/p80211types.h @@ -141,14 +141,14 @@ #define P80211DID_LSB_ITEM (12) #define P80211DID_LSB_INDEX (18) #define P80211DID_LSB_ISTABLE (26) -#define P80211DID_LSB_ACCESS (27) +#define P80211DID_LSB_ACCESS (27) #define P80211DID_MASK_SECTION (0x0000003fUL) #define P80211DID_MASK_GROUP (0x0000003fUL) #define P80211DID_MASK_ITEM (0x0000003fUL) #define P80211DID_MASK_INDEX (0x000000ffUL) #define P80211DID_MASK_ISTABLE (0x00000001UL) -#define P80211DID_MASK_ACCESS (0x00000003UL) +#define P80211DID_MASK_ACCESS (0x00000003UL) #define P80211DID_MK(a, m, l) ((((u32)(a)) & (m)) << (l)) -- cgit v1.2.3 From f83dfd065817ea3c7387b23afb2fd4d23fb470ff Mon Sep 17 00:00:00 2001 From: Johan Meiring Date: Sat, 6 Nov 2010 18:23:44 +0200 Subject: Staging: wlan-ng: fix coding style issues in prism2mgmt.c This is a patch to prism2mgmt.c that fixes coding style issues found by checkpatch.pl. Three instances of the 80 char line limit being exceeded have been kept as is so that string literals are not split up. Signed-off-by: Johan Meiring Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wlan-ng/prism2mgmt.c | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/drivers/staging/wlan-ng/prism2mgmt.c b/drivers/staging/wlan-ng/prism2mgmt.c index 04514a85d101..6675c8226cef 100644 --- a/drivers/staging/wlan-ng/prism2mgmt.c +++ b/drivers/staging/wlan-ng/prism2mgmt.c @@ -213,8 +213,8 @@ int prism2mgmt_scan(wlandevice_t *wlandev, void *msgp) u16 wordbuf[17]; result = hfa384x_drvr_setconfig16(hw, - HFA384x_RID_CNFROAMINGMODE, - HFA384x_ROAMMODE_HOSTSCAN_HOSTROAM); + HFA384x_RID_CNFROAMINGMODE, + HFA384x_ROAMMODE_HOSTSCAN_HOSTROAM); if (result) { printk(KERN_ERR "setconfig(ROAMINGMODE) failed. result=%d\n", @@ -258,8 +258,8 @@ int prism2mgmt_scan(wlandevice_t *wlandev, void *msgp) } /* ibss options */ result = hfa384x_drvr_setconfig16(hw, - HFA384x_RID_CREATEIBSS, - HFA384x_CREATEIBSS_JOINCREATEIBSS); + HFA384x_RID_CREATEIBSS, + HFA384x_CREATEIBSS_JOINCREATEIBSS); if (result) { printk(KERN_ERR "Failed to set CREATEIBSS.\n"); msg->resultcode.data = @@ -416,7 +416,8 @@ int prism2mgmt_scan_results(wlandevice_t *wlandev, void *msgp) #define REQBASICRATE(N) \ if ((count >= N) && DOT11_RATE5_ISBASIC_GET(item->supprates[(N)-1])) { \ req->basicrate ## N .data = item->supprates[(N)-1]; \ - req->basicrate ## N .status = P80211ENUM_msgitem_status_data_ok; \ + req->basicrate ## N .status = \ + P80211ENUM_msgitem_status_data_ok; \ } REQBASICRATE(1); @@ -431,7 +432,8 @@ int prism2mgmt_scan_results(wlandevice_t *wlandev, void *msgp) #define REQSUPPRATE(N) \ if (count >= N) { \ req->supprate ## N .data = item->supprates[(N)-1]; \ - req->supprate ## N .status = P80211ENUM_msgitem_status_data_ok; \ + req->supprate ## N .status = \ + P80211ENUM_msgitem_status_data_ok; \ } REQSUPPRATE(1); @@ -1102,7 +1104,7 @@ int prism2mgmt_wlansniff(wlandevice_t *wlandev, void *msgp) result = hfa384x_drvr_disable(hw, 0); if (result) { pr_debug - ("failed to disable port 0 after sniffing, result=%d\n", + ("failed to disable port 0 after sniffing, result=%d\n", result); goto failed; } @@ -1137,7 +1139,7 @@ int prism2mgmt_wlansniff(wlandevice_t *wlandev, void *msgp) result = hfa384x_drvr_enable(hw, 0); if (result) { pr_debug - ("failed to enable port to presniff setting, result=%d\n", + ("failed to enable port to presniff setting, result=%d\n", result); goto failed; } @@ -1161,7 +1163,7 @@ int prism2mgmt_wlansniff(wlandevice_t *wlandev, void *msgp) &(hw->presniff_port_type)); if (result) { pr_debug - ("failed to read porttype, result=%d\n", + ("failed to read porttype, result=%d\n", result); goto failed; } @@ -1171,7 +1173,7 @@ int prism2mgmt_wlansniff(wlandevice_t *wlandev, void *msgp) &(hw->presniff_wepflags)); if (result) { pr_debug - ("failed to read wepflags, result=%d\n", + ("failed to read wepflags, result=%d\n", result); goto failed; } @@ -1238,8 +1240,8 @@ int prism2mgmt_wlansniff(wlandevice_t *wlandev, void *msgp) if (result) { pr_debug - ("failed to set wepflags=0x%04x, result=%d\n", - word, result); + ("failed to set wepflags=0x%04x, result=%d\n", + word, result); goto failed; } } -- cgit v1.2.3 From 9f027eb6871335f6e16633df796263f983f08844 Mon Sep 17 00:00:00 2001 From: Johan Meiring Date: Sat, 6 Nov 2010 18:24:46 +0200 Subject: Staging: asus_oled: fix coding style issue in asus_oled.c This is a patch to the asus_oled.c file that fixes up brace and enum warning found by the checkpatch.pl tool Signed-off-by: Johan Meiring Signed-off-by: Greg Kroah-Hartman --- drivers/staging/asus_oled/asus_oled.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/asus_oled/asus_oled.c b/drivers/staging/asus_oled/asus_oled.c index 8c95d8c2a4f4..1dda9fbf11b6 100644 --- a/drivers/staging/asus_oled/asus_oled.c +++ b/drivers/staging/asus_oled/asus_oled.c @@ -70,7 +70,7 @@ module_param(start_off, uint, 0644); MODULE_PARM_DESC(start_off, "Set to 1 to switch off OLED display after it is attached"); -enum oled_pack_mode{ +enum oled_pack_mode { PACK_MODE_G1, PACK_MODE_G50, PACK_MODE_LAST -- cgit v1.2.3 From 869c4b4a715af94a14ec074c0a5528a562e3322b Mon Sep 17 00:00:00 2001 From: Johan Meiring Date: Sat, 6 Nov 2010 15:59:50 +0200 Subject: Staging: wlan-ng: fixed coding style issues in p80211conv.h This is a patch to the p80211conv.h file that fixes two 80 character line limit styling issues Signed-off-by: Johan Meiring Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wlan-ng/p80211conv.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/staging/wlan-ng/p80211conv.h b/drivers/staging/wlan-ng/p80211conv.h index eca0391c676f..ea493aa74f00 100644 --- a/drivers/staging/wlan-ng/p80211conv.h +++ b/drivers/staging/wlan-ng/p80211conv.h @@ -66,12 +66,14 @@ #define P80211_FRMMETA_MAGIC 0x802110 #define P80211SKB_FRMMETA(s) \ - (((((struct p80211_frmmeta *)((s)->cb))->magic) == P80211_FRMMETA_MAGIC) ? \ + (((((struct p80211_frmmeta *)((s)->cb))->magic) == \ + P80211_FRMMETA_MAGIC) ? \ ((struct p80211_frmmeta *)((s)->cb)) : \ (NULL)) #define P80211SKB_RXMETA(s) \ - (P80211SKB_FRMMETA((s)) ? P80211SKB_FRMMETA((s))->rx : ((struct p80211_rxmeta *)(NULL))) + (P80211SKB_FRMMETA((s)) ? P80211SKB_FRMMETA((s))->rx : \ + ((struct p80211_rxmeta *)(NULL))) struct p80211_rxmeta { struct wlandevice *wlandev; -- cgit v1.2.3 From 6f710907ff452ab67bd1161bc3f7a95f9a7e809d Mon Sep 17 00:00:00 2001 From: Johan Meiring Date: Sat, 6 Nov 2010 18:21:59 +0200 Subject: Staging: wlan-ng: fixed coding style issues in p80211netdev.c This is a patch to the p80211netdev.c file that fixes warnings that were found by the checkpatch.pl tool Signed-off-by: Johan Meiring Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wlan-ng/p80211netdev.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/staging/wlan-ng/p80211netdev.c b/drivers/staging/wlan-ng/p80211netdev.c index aa1792c8429e..48f223e05ddd 100644 --- a/drivers/staging/wlan-ng/p80211netdev.c +++ b/drivers/staging/wlan-ng/p80211netdev.c @@ -301,7 +301,8 @@ static void p80211netdev_rx_bh(unsigned long arg) if (memcmp (hdr->a1, wlandev->netdev->dev_addr, ETH_ALEN) != 0) { - /* but reject anything else that isn't multicast */ + /* but reject anything else that + isn't multicast */ if (!(hdr->a1[0] & 0x01)) { dev_kfree_skb(skb); continue; @@ -770,7 +771,8 @@ int wlan_setup(wlandevice_t *wlandev, struct device *physdev) } /* Allocate and initialize the struct device */ - netdev = alloc_netdev(sizeof(struct wireless_dev), "wlan%d", ether_setup); + netdev = alloc_netdev(sizeof(struct wireless_dev), "wlan%d", + ether_setup); if (netdev == NULL) { printk(KERN_ERR "Failed to alloc netdev.\n"); wlan_free_wiphy(wiphy); -- cgit v1.2.3 From 3c9d46526db88218a311a72971efae1b4366d4c6 Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Sun, 7 Nov 2010 07:37:03 +0100 Subject: Staging: Cypress WestBridge OMAP3430 Kernel Hal: Remove unneeded local variables from alloc functions In drivers/staging/westbridge/astoria/arch/arm/mach-omap2/cyashalomap_kernel.c the local variables 'ret_p' are not needed and should just go away. I have no way to test this code, but I believe the change is obviously correct. Please consider it. Signed-off-by: Jesper Juhl Acked-by: David Cross Signed-off-by: Greg Kroah-Hartman --- .../astoria/arch/arm/mach-omap2/cyashalomap_kernel.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/drivers/staging/westbridge/astoria/arch/arm/mach-omap2/cyashalomap_kernel.c b/drivers/staging/westbridge/astoria/arch/arm/mach-omap2/cyashalomap_kernel.c index a6780296888f..ad0c61db9937 100644 --- a/drivers/staging/westbridge/astoria/arch/arm/mach-omap2/cyashalomap_kernel.c +++ b/drivers/staging/westbridge/astoria/arch/arm/mach-omap2/cyashalomap_kernel.c @@ -2127,10 +2127,7 @@ void cy_as_hal_pll_lock_loss_handler(cy_as_hal_device_tag tag) */ void *cy_as_hal_alloc(uint32_t cnt) { - void *ret_p; - - ret_p = kmalloc(cnt, GFP_ATOMIC); - return ret_p; + return kmalloc(cnt, GFP_ATOMIC); } /* @@ -2150,10 +2147,7 @@ void cy_as_hal_free(void *mem_p) */ void *cy_as_hal_c_b_alloc(uint32_t cnt) { - void *ret_p; - - ret_p = kmalloc(cnt, GFP_ATOMIC); - return ret_p; + return kmalloc(cnt, GFP_ATOMIC); } /* -- cgit v1.2.3 From a32d4acab4a862c5cd297b73d625d813af8d4e0b Mon Sep 17 00:00:00 2001 From: Tracey Dent Date: Sat, 6 Nov 2010 14:48:48 -0400 Subject: Staging: speakup: spk_types: trival coding style issue Checkpatch.pl gives WARNING: missing space after struct definition. This patch fixes that warning that was on line 55. Signed-off-by: Tracey Dent Signed-off-by: Greg Kroah-Hartman --- drivers/staging/speakup/spk_types.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/speakup/spk_types.h b/drivers/staging/speakup/spk_types.h index 840bddb64101..d36c90e30d54 100644 --- a/drivers/staging/speakup/spk_types.h +++ b/drivers/staging/speakup/spk_types.h @@ -52,7 +52,7 @@ typedef int (*special_func)(struct vc_data *vc, u_char type, u_char ch, #define COLOR_BUFFER_SIZE 160 -struct spk_highlight_color_track{ +struct spk_highlight_color_track { /* Count of each background color */ unsigned int bgcount[8]; /* Buffer for characters drawn with each background color */ -- cgit v1.2.3 From c50f7fb28400bc4829c26bb4a2d6c06a45e90b1a Mon Sep 17 00:00:00 2001 From: Haiyang Zhang Date: Mon, 8 Nov 2010 14:04:38 -0800 Subject: staging: hv: Convert camel cased struct fields in channel_mgmt.h to lower cases staging: hv: Convert camel cased struct fields in channel_mgmt.h to lower cases Signed-off-by: Haiyang Zhang Signed-off-by: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/channel.c | 302 +++++++++++++++++++------------------- drivers/staging/hv/channel_mgmt.c | 186 +++++++++++------------ drivers/staging/hv/channel_mgmt.h | 244 +++++++++++++++--------------- drivers/staging/hv/connection.c | 38 ++--- drivers/staging/hv/hv_utils.c | 12 +- drivers/staging/hv/vmbus_drv.c | 42 +++--- 6 files changed, 412 insertions(+), 412 deletions(-) diff --git a/drivers/staging/hv/channel.c b/drivers/staging/hv/channel.c index 26ebc77f22b7..9fa0fe1525dc 100644 --- a/drivers/staging/hv/channel.c +++ b/drivers/staging/hv/channel.c @@ -74,21 +74,21 @@ static void vmbus_setevent(struct vmbus_channel *channel) { struct hv_monitor_page *monitorpage; - if (channel->OfferMsg.MonitorAllocated) { + if (channel->offermsg.monitor_allocated) { /* Each u32 represents 32 channels */ - set_bit(channel->OfferMsg.ChildRelId & 31, + set_bit(channel->offermsg.child_relid & 31, (unsigned long *) gVmbusConnection.SendInterruptPage + - (channel->OfferMsg.ChildRelId >> 5)); + (channel->offermsg.child_relid >> 5)); monitorpage = gVmbusConnection.MonitorPages; monitorpage++; /* Get the child to parent monitor page */ - set_bit(channel->MonitorBit, + set_bit(channel->monitor_bit, (unsigned long *)&monitorpage->TriggerGroup - [channel->MonitorGroup].Pending); + [channel->monitor_grp].Pending); } else { - VmbusSetEvent(channel->OfferMsg.ChildRelId); + VmbusSetEvent(channel->offermsg.child_relid); } } @@ -97,19 +97,19 @@ static void VmbusChannelClearEvent(struct vmbus_channel *channel) { struct hv_monitor_page *monitorPage; - if (Channel->OfferMsg.MonitorAllocated) { + if (Channel->offermsg.monitor_allocated) { /* Each u32 represents 32 channels */ - clear_bit(Channel->OfferMsg.ChildRelId & 31, + clear_bit(Channel->offermsg.child_relid & 31, (unsigned long *)gVmbusConnection.SendInterruptPage + - (Channel->OfferMsg.ChildRelId >> 5)); + (Channel->offermsg.child_relid >> 5)); monitorPage = (struct hv_monitor_page *)gVmbusConnection.MonitorPages; monitorPage++; /* Get the child to parent monitor page */ - clear_bit(Channel->MonitorBit, + clear_bit(Channel->monitor_bit, (unsigned long *)&monitorPage->TriggerGroup - [Channel->MonitorGroup].Pending); + [Channel->monitor_grp].Pending); } } @@ -121,42 +121,42 @@ void vmbus_get_debug_info(struct vmbus_channel *channel, struct vmbus_channel_debug_info *debuginfo) { struct hv_monitor_page *monitorpage; - u8 monitor_group = (u8)channel->OfferMsg.MonitorId / 32; - u8 monitor_offset = (u8)channel->OfferMsg.MonitorId % 32; + u8 monitor_group = (u8)channel->offermsg.monitorid / 32; + u8 monitor_offset = (u8)channel->offermsg.monitorid % 32; /* u32 monitorBit = 1 << monitorOffset; */ - debuginfo->RelId = channel->OfferMsg.ChildRelId; - debuginfo->State = channel->State; - memcpy(&debuginfo->InterfaceType, - &channel->OfferMsg.Offer.InterfaceType, sizeof(struct hv_guid)); - memcpy(&debuginfo->InterfaceInstance, - &channel->OfferMsg.Offer.InterfaceInstance, + debuginfo->relid = channel->offermsg.child_relid; + debuginfo->state = channel->state; + memcpy(&debuginfo->interfacetype, + &channel->offermsg.offer.InterfaceType, sizeof(struct hv_guid)); + memcpy(&debuginfo->interface_instance, + &channel->offermsg.offer.InterfaceInstance, sizeof(struct hv_guid)); monitorpage = (struct hv_monitor_page *)gVmbusConnection.MonitorPages; - debuginfo->MonitorId = channel->OfferMsg.MonitorId; + debuginfo->monitorid = channel->offermsg.monitorid; - debuginfo->ServerMonitorPending = + debuginfo->servermonitor_pending = monitorpage->TriggerGroup[monitor_group].Pending; - debuginfo->ServerMonitorLatency = + debuginfo->servermonitor_latency = monitorpage->Latency[monitor_group][monitor_offset]; - debuginfo->ServerMonitorConnectionId = + debuginfo->servermonitor_connectionid = monitorpage->Parameter[monitor_group] [monitor_offset].ConnectionId.u.Id; monitorpage++; - debuginfo->ClientMonitorPending = + debuginfo->clientmonitor_pending = monitorpage->TriggerGroup[monitor_group].Pending; - debuginfo->ClientMonitorLatency = + debuginfo->clientmonitor_latency = monitorpage->Latency[monitor_group][monitor_offset]; - debuginfo->ClientMonitorConnectionId = + debuginfo->clientmonitor_connectionid = monitorpage->Parameter[monitor_group] [monitor_offset].ConnectionId.u.Id; - RingBufferGetDebugInfo(&channel->Inbound, &debuginfo->Inbound); - RingBufferGetDebugInfo(&channel->Outbound, &debuginfo->Outbound); + RingBufferGetDebugInfo(&channel->inbound, &debuginfo->inbound); + RingBufferGetDebugInfo(&channel->outbound, &debuginfo->outbound); } /* @@ -176,8 +176,8 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size, /* ASSERT(!(SendRingBufferSize & (PAGE_SIZE - 1))); */ /* ASSERT(!(RecvRingBufferSize & (PAGE_SIZE - 1))); */ - newchannel->OnChannelCallback = onchannelcallback; - newchannel->ChannelCallbackContext = context; + newchannel->onchannel_callback = onchannelcallback; + newchannel->channel_callback_context = context; /* Allocate the ring buffer */ out = osd_PageAlloc((send_ringbuffer_size + recv_ringbuffer_size) @@ -189,17 +189,17 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size, in = (void *)((unsigned long)out + send_ringbuffer_size); - newchannel->RingBufferPages = out; - newchannel->RingBufferPageCount = (send_ringbuffer_size + + newchannel->ringbuffer_pages = out; + newchannel->ringbuffer_pagecount = (send_ringbuffer_size + recv_ringbuffer_size) >> PAGE_SHIFT; - ret = RingBufferInit(&newchannel->Outbound, out, send_ringbuffer_size); + ret = RingBufferInit(&newchannel->outbound, out, send_ringbuffer_size); if (ret != 0) { err = ret; goto errorout; } - ret = RingBufferInit(&newchannel->Inbound, in, recv_ringbuffer_size); + ret = RingBufferInit(&newchannel->inbound, in, recv_ringbuffer_size); if (ret != 0) { err = ret; goto errorout; @@ -210,13 +210,13 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size, DPRINT_DBG(VMBUS, "Establishing ring buffer's gpadl for channel %p...", newchannel); - newchannel->RingBufferGpadlHandle = 0; + newchannel->ringbuffer_gpadlhandle = 0; ret = vmbus_establish_gpadl(newchannel, - newchannel->Outbound.RingBuffer, + newchannel->outbound.RingBuffer, send_ringbuffer_size + recv_ringbuffer_size, - &newchannel->RingBufferGpadlHandle); + &newchannel->ringbuffer_gpadlhandle); if (ret != 0) { err = ret; @@ -225,12 +225,12 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size, DPRINT_DBG(VMBUS, "channel %p ", - newchannel, newchannel->OfferMsg.ChildRelId, - newchannel->RingBufferGpadlHandle, - newchannel->Outbound.RingBuffer, - newchannel->Outbound.RingSize, - newchannel->Inbound.RingBuffer, - newchannel->Inbound.RingSize, + newchannel, newchannel->offermsg.child_relid, + newchannel->ringbuffer_gpadlhandle, + newchannel->outbound.RingBuffer, + newchannel->outbound.RingSize, + newchannel->inbound.RingBuffer, + newchannel->inbound.RingSize, send_ringbuffer_size); /* Create and init the channel open message */ @@ -242,20 +242,20 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size, goto errorout; } - openInfo->WaitEvent = osd_WaitEventCreate(); - if (!openInfo->WaitEvent) { + openInfo->waitevent = osd_WaitEventCreate(); + if (!openInfo->waitevent) { err = -ENOMEM; goto errorout; } - openMsg = (struct vmbus_channel_open_channel *)openInfo->Msg; - openMsg->Header.MessageType = ChannelMessageOpenChannel; - openMsg->OpenId = newchannel->OfferMsg.ChildRelId; /* FIXME */ - openMsg->ChildRelId = newchannel->OfferMsg.ChildRelId; - openMsg->RingBufferGpadlHandle = newchannel->RingBufferGpadlHandle; - openMsg->DownstreamRingBufferPageOffset = send_ringbuffer_size >> + openMsg = (struct vmbus_channel_open_channel *)openInfo->msg; + openMsg->header.msgtype = CHANNELMSG_OPENCHANNEL; + openMsg->openid = newchannel->offermsg.child_relid; /* FIXME */ + openMsg->child_relid = newchannel->offermsg.child_relid; + openMsg->ringbuffer_gpadlhandle = newchannel->ringbuffer_gpadlhandle; + openMsg->downstream_ringbuffer_pageoffset = send_ringbuffer_size >> PAGE_SHIFT; - openMsg->ServerContextAreaGpadlHandle = 0; /* TODO */ + openMsg->server_contextarea_gpadlhandle = 0; /* TODO */ if (userdatalen > MAX_USER_DEFINED_BYTES) { err = -EINVAL; @@ -263,10 +263,10 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size, } if (userdatalen) - memcpy(openMsg->UserData, userdata, userdatalen); + memcpy(openMsg->userdata, userdata, userdatalen); spin_lock_irqsave(&gVmbusConnection.channelmsg_lock, flags); - list_add_tail(&openInfo->MsgListEntry, + list_add_tail(&openInfo->msglistentry, &gVmbusConnection.ChannelMsgList); spin_unlock_irqrestore(&gVmbusConnection.channelmsg_lock, flags); @@ -280,26 +280,26 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size, } /* FIXME: Need to time-out here */ - osd_WaitEventWait(openInfo->WaitEvent); + osd_WaitEventWait(openInfo->waitevent); - if (openInfo->Response.OpenResult.Status == 0) + if (openInfo->response.open_result.status == 0) DPRINT_INFO(VMBUS, "channel <%p> open success!!", newchannel); else DPRINT_INFO(VMBUS, "channel <%p> open failed - %d!!", - newchannel, openInfo->Response.OpenResult.Status); + newchannel, openInfo->response.open_result.status); Cleanup: spin_lock_irqsave(&gVmbusConnection.channelmsg_lock, flags); - list_del(&openInfo->MsgListEntry); + list_del(&openInfo->msglistentry); spin_unlock_irqrestore(&gVmbusConnection.channelmsg_lock, flags); - kfree(openInfo->WaitEvent); + kfree(openInfo->waitevent); kfree(openInfo); return 0; errorout: - RingBufferCleanup(&newchannel->Outbound); - RingBufferCleanup(&newchannel->Inbound); + RingBufferCleanup(&newchannel->outbound); + RingBufferCleanup(&newchannel->inbound); osd_PageFree(out, (send_ringbuffer_size + recv_ringbuffer_size) >> PAGE_SHIFT); kfree(openInfo); @@ -322,7 +322,7 @@ static void dump_gpadl_body(struct vmbus_channel_gpadl_body *gpadl, u32 len) for (i = 0; i < pfncount; i++) DPRINT_DBG(VMBUS, "gpadl body - %d) pfn %llu", - i, gpadl->Pfn[i]); + i, gpadl->pfn[i]); } /* @@ -336,18 +336,18 @@ static void dump_gpadl_header(struct vmbus_channel_gpadl_header *gpadl) DPRINT_DBG(VMBUS, "gpadl header - relid %d, range count %d, range buflen %d", - gpadl->ChildRelId, gpadl->RangeCount, gpadl->RangeBufLen); - for (i = 0; i < gpadl->RangeCount; i++) { - pagecount = gpadl->Range[i].ByteCount >> PAGE_SHIFT; + gpadl->child_relid, gpadl->rangecount, gpadl->range_buflen); + for (i = 0; i < gpadl->rangecount; i++) { + pagecount = gpadl->range[i].ByteCount >> PAGE_SHIFT; pagecount = (pagecount > 26) ? 26 : pagecount; DPRINT_DBG(VMBUS, "gpadl range %d - len %d offset %d " - "page count %d", i, gpadl->Range[i].ByteCount, - gpadl->Range[i].ByteOffset, pagecount); + "page count %d", i, gpadl->range[i].ByteCount, + gpadl->range[i].ByteOffset, pagecount); for (j = 0; j < pagecount; j++) DPRINT_DBG(VMBUS, "%d) pfn %llu", j, - gpadl->Range[i].PfnArray[j]); + gpadl->range[i].PfnArray[j]); } } @@ -391,18 +391,18 @@ static int create_gpadl_header(void *kbuffer, u32 size, if (!msgheader) goto nomem; - INIT_LIST_HEAD(&msgheader->SubMsgList); - msgheader->MessageSize = msgsize; + INIT_LIST_HEAD(&msgheader->submsglist); + msgheader->msgsize = msgsize; gpadl_header = (struct vmbus_channel_gpadl_header *) - msgheader->Msg; - gpadl_header->RangeCount = 1; - gpadl_header->RangeBufLen = sizeof(struct gpa_range) + + msgheader->msg; + gpadl_header->rangecount = 1; + gpadl_header->range_buflen = sizeof(struct gpa_range) + pagecount * sizeof(u64); - gpadl_header->Range[0].ByteOffset = 0; - gpadl_header->Range[0].ByteCount = size; + gpadl_header->range[0].ByteOffset = 0; + gpadl_header->range[0].ByteCount = size; for (i = 0; i < pfncount; i++) - gpadl_header->Range[0].PfnArray[i] = pfn+i; + gpadl_header->range[0].PfnArray[i] = pfn+i; *msginfo = msgheader; *messagecount = 1; @@ -428,10 +428,10 @@ static int create_gpadl_header(void *kbuffer, u32 size, /* FIXME: we probably need to more if this fails */ if (!msgbody) goto nomem; - msgbody->MessageSize = msgsize; + msgbody->msgsize = msgsize; (*messagecount)++; gpadl_body = - (struct vmbus_channel_gpadl_body *)msgbody->Msg; + (struct vmbus_channel_gpadl_body *)msgbody->msg; /* * FIXME: @@ -440,11 +440,11 @@ static int create_gpadl_header(void *kbuffer, u32 size, */ /* gpadl_body->Gpadl = kbuffer; */ for (i = 0; i < pfncurr; i++) - gpadl_body->Pfn[i] = pfn + pfnsum + i; + gpadl_body->pfn[i] = pfn + pfnsum + i; /* add to msg header */ - list_add_tail(&msgbody->MsgListEntry, - &msgheader->SubMsgList); + list_add_tail(&msgbody->msglistentry, + &msgheader->submsglist); pfnsum += pfncurr; pfnleft -= pfncurr; } @@ -456,17 +456,17 @@ static int create_gpadl_header(void *kbuffer, u32 size, msgheader = kzalloc(msgsize, GFP_KERNEL); if (msgheader == NULL) goto nomem; - msgheader->MessageSize = msgsize; + msgheader->msgsize = msgsize; gpadl_header = (struct vmbus_channel_gpadl_header *) - msgheader->Msg; - gpadl_header->RangeCount = 1; - gpadl_header->RangeBufLen = sizeof(struct gpa_range) + + msgheader->msg; + gpadl_header->rangecount = 1; + gpadl_header->range_buflen = sizeof(struct gpa_range) + pagecount * sizeof(u64); - gpadl_header->Range[0].ByteOffset = 0; - gpadl_header->Range[0].ByteCount = size; + gpadl_header->range[0].ByteOffset = 0; + gpadl_header->range[0].ByteCount = size; for (i = 0; i < pagecount; i++) - gpadl_header->Range[0].PfnArray[i] = pfn+i; + gpadl_header->range[0].PfnArray[i] = pfn+i; *msginfo = msgheader; *messagecount = 1; @@ -508,21 +508,21 @@ int vmbus_establish_gpadl(struct vmbus_channel *channel, void *kbuffer, if (ret) return ret; - msginfo->WaitEvent = osd_WaitEventCreate(); - if (!msginfo->WaitEvent) { + msginfo->waitevent = osd_WaitEventCreate(); + if (!msginfo->waitevent) { ret = -ENOMEM; goto Cleanup; } - gpadlmsg = (struct vmbus_channel_gpadl_header *)msginfo->Msg; - gpadlmsg->Header.MessageType = ChannelMessageGpadlHeader; - gpadlmsg->ChildRelId = channel->OfferMsg.ChildRelId; - gpadlmsg->Gpadl = next_gpadl_handle; + gpadlmsg = (struct vmbus_channel_gpadl_header *)msginfo->msg; + gpadlmsg->header.msgtype = CHANNELMSG_GPADL_HEADER; + gpadlmsg->child_relid = channel->offermsg.child_relid; + gpadlmsg->gpadl = next_gpadl_handle; dump_gpadl_header(gpadlmsg); spin_lock_irqsave(&gVmbusConnection.channelmsg_lock, flags); - list_add_tail(&msginfo->MsgListEntry, + list_add_tail(&msginfo->msglistentry, &gVmbusConnection.ChannelMsgList); spin_unlock_irqrestore(&gVmbusConnection.channelmsg_lock, flags); @@ -530,9 +530,9 @@ int vmbus_establish_gpadl(struct vmbus_channel *channel, void *kbuffer, kbuffer, size, msgcount); DPRINT_DBG(VMBUS, "Sending GPADL Header - len %zd", - msginfo->MessageSize - sizeof(*msginfo)); + msginfo->msgsize - sizeof(*msginfo)); - ret = VmbusPostMessage(gpadlmsg, msginfo->MessageSize - + ret = VmbusPostMessage(gpadlmsg, msginfo->msgsize - sizeof(*msginfo)); if (ret != 0) { DPRINT_ERR(VMBUS, "Unable to open channel - %d", ret); @@ -540,48 +540,48 @@ int vmbus_establish_gpadl(struct vmbus_channel *channel, void *kbuffer, } if (msgcount > 1) { - list_for_each(curr, &msginfo->SubMsgList) { + list_for_each(curr, &msginfo->submsglist) { /* FIXME: should this use list_entry() instead ? */ submsginfo = (struct vmbus_channel_msginfo *)curr; gpadl_body = - (struct vmbus_channel_gpadl_body *)submsginfo->Msg; + (struct vmbus_channel_gpadl_body *)submsginfo->msg; - gpadl_body->Header.MessageType = - ChannelMessageGpadlBody; - gpadl_body->Gpadl = next_gpadl_handle; + gpadl_body->header.msgtype = + CHANNELMSG_GPADL_BODY; + gpadl_body->gpadl = next_gpadl_handle; DPRINT_DBG(VMBUS, "Sending GPADL Body - len %zd", - submsginfo->MessageSize - + submsginfo->msgsize - sizeof(*submsginfo)); - dump_gpadl_body(gpadl_body, submsginfo->MessageSize - + dump_gpadl_body(gpadl_body, submsginfo->msgsize - sizeof(*submsginfo)); ret = VmbusPostMessage(gpadl_body, - submsginfo->MessageSize - + submsginfo->msgsize - sizeof(*submsginfo)); if (ret != 0) goto Cleanup; } } - osd_WaitEventWait(msginfo->WaitEvent); + osd_WaitEventWait(msginfo->waitevent); /* At this point, we received the gpadl created msg */ DPRINT_DBG(VMBUS, "Received GPADL created " "(relid %d, status %d handle %x)", - channel->OfferMsg.ChildRelId, - msginfo->Response.GpadlCreated.CreationStatus, - gpadlmsg->Gpadl); + channel->offermsg.child_relid, + msginfo->response.gpadl_created.creation_status, + gpadlmsg->gpadl); - *gpadl_handle = gpadlmsg->Gpadl; + *gpadl_handle = gpadlmsg->gpadl; Cleanup: spin_lock_irqsave(&gVmbusConnection.channelmsg_lock, flags); - list_del(&msginfo->MsgListEntry); + list_del(&msginfo->msglistentry); spin_unlock_irqrestore(&gVmbusConnection.channelmsg_lock, flags); - kfree(msginfo->WaitEvent); + kfree(msginfo->waitevent); kfree(msginfo); return ret; } @@ -604,20 +604,20 @@ int vmbus_teardown_gpadl(struct vmbus_channel *channel, u32 gpadl_handle) if (!info) return -ENOMEM; - info->WaitEvent = osd_WaitEventCreate(); - if (!info->WaitEvent) { + info->waitevent = osd_WaitEventCreate(); + if (!info->waitevent) { kfree(info); return -ENOMEM; } - msg = (struct vmbus_channel_gpadl_teardown *)info->Msg; + msg = (struct vmbus_channel_gpadl_teardown *)info->msg; - msg->Header.MessageType = ChannelMessageGpadlTeardown; - msg->ChildRelId = channel->OfferMsg.ChildRelId; - msg->Gpadl = gpadl_handle; + msg->header.msgtype = CHANNELMSG_GPADL_TEARDOWN; + msg->child_relid = channel->offermsg.child_relid; + msg->gpadl = gpadl_handle; spin_lock_irqsave(&gVmbusConnection.channelmsg_lock, flags); - list_add_tail(&info->MsgListEntry, + list_add_tail(&info->msglistentry, &gVmbusConnection.ChannelMsgList); spin_unlock_irqrestore(&gVmbusConnection.channelmsg_lock, flags); @@ -628,14 +628,14 @@ int vmbus_teardown_gpadl(struct vmbus_channel *channel, u32 gpadl_handle) /* something... */ } - osd_WaitEventWait(info->WaitEvent); + osd_WaitEventWait(info->waitevent); /* Received a torndown response */ spin_lock_irqsave(&gVmbusConnection.channelmsg_lock, flags); - list_del(&info->MsgListEntry); + list_del(&info->msglistentry); spin_unlock_irqrestore(&gVmbusConnection.channelmsg_lock, flags); - kfree(info->WaitEvent); + kfree(info->waitevent); kfree(info); return ret; } @@ -652,7 +652,7 @@ void vmbus_close(struct vmbus_channel *channel) int ret; /* Stop callback and cancel the timer asap */ - channel->OnChannelCallback = NULL; + channel->onchannel_callback = NULL; del_timer_sync(&channel->poll_timer); /* Send a closing message */ @@ -665,9 +665,9 @@ void vmbus_close(struct vmbus_channel *channel) /* info->waitEvent = osd_WaitEventCreate(); */ - msg = (struct vmbus_channel_close_channel *)info->Msg; - msg->Header.MessageType = ChannelMessageCloseChannel; - msg->ChildRelId = channel->OfferMsg.ChildRelId; + msg = (struct vmbus_channel_close_channel *)info->msg; + msg->header.msgtype = CHANNELMSG_CLOSECHANNEL; + msg->child_relid = channel->offermsg.child_relid; ret = VmbusPostMessage(msg, sizeof(struct vmbus_channel_close_channel)); if (ret != 0) { @@ -676,17 +676,17 @@ void vmbus_close(struct vmbus_channel *channel) } /* Tear down the gpadl for the channel's ring buffer */ - if (channel->RingBufferGpadlHandle) + if (channel->ringbuffer_gpadlhandle) vmbus_teardown_gpadl(channel, - channel->RingBufferGpadlHandle); + channel->ringbuffer_gpadlhandle); /* TODO: Send a msg to release the childRelId */ /* Cleanup the ring buffers for this channel */ - RingBufferCleanup(&channel->Outbound); - RingBufferCleanup(&channel->Inbound); + RingBufferCleanup(&channel->outbound); + RingBufferCleanup(&channel->inbound); - osd_PageFree(channel->RingBufferPages, channel->RingBufferPageCount); + osd_PageFree(channel->ringbuffer_pages, channel->ringbuffer_pagecount); kfree(info); @@ -696,9 +696,9 @@ void vmbus_close(struct vmbus_channel *channel) * caller will free the channel */ - if (channel->State == CHANNEL_OPEN_STATE) { + if (channel->state == CHANNEL_OPEN_STATE) { spin_lock_irqsave(&gVmbusConnection.channel_lock, flags); - list_del(&channel->ListEntry); + list_del(&channel->listentry); spin_unlock_irqrestore(&gVmbusConnection.channel_lock, flags); free_channel(channel); @@ -752,10 +752,10 @@ int vmbus_sendpacket(struct vmbus_channel *channel, const void *buffer, sg_set_buf(&bufferlist[2], &aligned_data, packetlen_aligned - packetlen); - ret = RingBufferWrite(&channel->Outbound, bufferlist, 3); + ret = RingBufferWrite(&channel->outbound, bufferlist, 3); /* TODO: We should determine if this is optional */ - if (ret == 0 && !GetRingBufferInterruptMask(&channel->Outbound)) + if (ret == 0 && !GetRingBufferInterruptMask(&channel->outbound)) vmbus_setevent(channel); return ret; @@ -817,10 +817,10 @@ int vmbus_sendpacket_pagebuffer(struct vmbus_channel *channel, sg_set_buf(&bufferlist[2], &aligned_data, packetlen_aligned - packetlen); - ret = RingBufferWrite(&channel->Outbound, bufferlist, 3); + ret = RingBufferWrite(&channel->outbound, bufferlist, 3); /* TODO: We should determine if this is optional */ - if (ret == 0 && !GetRingBufferInterruptMask(&channel->Outbound)) + if (ret == 0 && !GetRingBufferInterruptMask(&channel->outbound)) vmbus_setevent(channel); return ret; @@ -886,10 +886,10 @@ int vmbus_sendpacket_multipagebuffer(struct vmbus_channel *channel, sg_set_buf(&bufferlist[2], &aligned_data, packetlen_aligned - packetlen); - ret = RingBufferWrite(&channel->Outbound, bufferlist, 3); + ret = RingBufferWrite(&channel->outbound, bufferlist, 3); /* TODO: We should determine if this is optional */ - if (ret == 0 && !GetRingBufferInterruptMask(&channel->Outbound)) + if (ret == 0 && !GetRingBufferInterruptMask(&channel->outbound)) vmbus_setevent(channel); return ret; @@ -923,7 +923,7 @@ int vmbus_recvpacket(struct vmbus_channel *channel, void *buffer, spin_lock_irqsave(&channel->inbound_lock, flags); - ret = RingBufferPeek(&channel->Inbound, &desc, + ret = RingBufferPeek(&channel->inbound, &desc, sizeof(struct vmpacket_descriptor)); if (ret != 0) { spin_unlock_irqrestore(&channel->inbound_lock, flags); @@ -940,7 +940,7 @@ int vmbus_recvpacket(struct vmbus_channel *channel, void *buffer, DPRINT_DBG(VMBUS, "packet received on channel %p relid %d ", - channel, channel->OfferMsg.ChildRelId, desc.Type, + channel, channel->offermsg.child_relid, desc.Type, desc.Flags, desc.TransactionId, packetlen, userlen); *buffer_actual_len = userlen; @@ -956,7 +956,7 @@ int vmbus_recvpacket(struct vmbus_channel *channel, void *buffer, *requestid = desc.TransactionId; /* Copy over the packet to the user buffer */ - ret = RingBufferRead(&channel->Inbound, buffer, userlen, + ret = RingBufferRead(&channel->inbound, buffer, userlen, (desc.DataOffset8 << 3)); spin_unlock_irqrestore(&channel->inbound_lock, flags); @@ -983,7 +983,7 @@ int vmbus_recvpacket_raw(struct vmbus_channel *channel, void *buffer, spin_lock_irqsave(&channel->inbound_lock, flags); - ret = RingBufferPeek(&channel->Inbound, &desc, + ret = RingBufferPeek(&channel->inbound, &desc, sizeof(struct vmpacket_descriptor)); if (ret != 0) { spin_unlock_irqrestore(&channel->inbound_lock, flags); @@ -999,7 +999,7 @@ int vmbus_recvpacket_raw(struct vmbus_channel *channel, void *buffer, DPRINT_DBG(VMBUS, "packet received on channel %p relid %d ", - channel, channel->OfferMsg.ChildRelId, desc.Type, + channel, channel->offermsg.child_relid, desc.Type, desc.Flags, desc.TransactionId, packetlen, userlen); *buffer_actual_len = packetlen; @@ -1015,7 +1015,7 @@ int vmbus_recvpacket_raw(struct vmbus_channel *channel, void *buffer, *requestid = desc.TransactionId; /* Copy over the entire packet to the user buffer */ - ret = RingBufferRead(&channel->Inbound, buffer, packetlen, 0); + ret = RingBufferRead(&channel->inbound, buffer, packetlen, 0); spin_unlock_irqrestore(&channel->inbound_lock, flags); return 0; @@ -1030,7 +1030,7 @@ void vmbus_onchannel_event(struct vmbus_channel *channel) dump_vmbus_channel(channel); /* ASSERT(Channel->OnChannelCallback); */ - channel->OnChannelCallback(channel->ChannelCallbackContext); + channel->onchannel_callback(channel->channel_callback_context); mod_timer(&channel->poll_timer, jiffies + usecs_to_jiffies(100)); } @@ -1042,8 +1042,8 @@ void vmbus_ontimer(unsigned long data) { struct vmbus_channel *channel = (struct vmbus_channel *)data; - if (channel->OnChannelCallback) - channel->OnChannelCallback(channel->ChannelCallbackContext); + if (channel->onchannel_callback) + channel->onchannel_callback(channel->channel_callback_context); } /* @@ -1051,7 +1051,7 @@ void vmbus_ontimer(unsigned long data) */ static void dump_vmbus_channel(struct vmbus_channel *channel) { - DPRINT_DBG(VMBUS, "Channel (%d)", channel->OfferMsg.ChildRelId); - DumpRingInfo(&channel->Outbound, "Outbound "); - DumpRingInfo(&channel->Inbound, "Inbound "); + DPRINT_DBG(VMBUS, "Channel (%d)", channel->offermsg.child_relid); + DumpRingInfo(&channel->outbound, "Outbound "); + DumpRingInfo(&channel->inbound, "Inbound "); } diff --git a/drivers/staging/hv/channel_mgmt.c b/drivers/staging/hv/channel_mgmt.c index 45dbe305afed..dbfe0f22b6d6 100644 --- a/drivers/staging/hv/channel_mgmt.c +++ b/drivers/staging/hv/channel_mgmt.c @@ -251,8 +251,8 @@ static struct vmbus_channel *alloc_channel(void) channel->poll_timer.data = (unsigned long)channel; channel->poll_timer.function = vmbus_ontimer; - channel->ControlWQ = create_workqueue("hv_vmbus_ctl"); - if (!channel->ControlWQ) { + channel->controlwq = create_workqueue("hv_vmbus_ctl"); + if (!channel->controlwq) { kfree(channel); return NULL; } @@ -268,7 +268,7 @@ static inline void release_channel(void *context) struct vmbus_channel *channel = context; DPRINT_DBG(VMBUS, "releasing channel (%p)", channel); - destroy_workqueue(channel->ControlWQ); + destroy_workqueue(channel->controlwq); DPRINT_DBG(VMBUS, "channel released (%p)", channel); kfree(channel); @@ -325,12 +325,12 @@ static void vmbus_process_offer(void *context) /* Make sure this is a new offer */ spin_lock_irqsave(&gVmbusConnection.channel_lock, flags); - list_for_each_entry(channel, &gVmbusConnection.ChannelList, ListEntry) { - if (!memcmp(&channel->OfferMsg.Offer.InterfaceType, - &newchannel->OfferMsg.Offer.InterfaceType, + list_for_each_entry(channel, &gVmbusConnection.ChannelList, listentry) { + if (!memcmp(&channel->offermsg.offer.InterfaceType, + &newchannel->offermsg.offer.InterfaceType, sizeof(struct hv_guid)) && - !memcmp(&channel->OfferMsg.Offer.InterfaceInstance, - &newchannel->OfferMsg.Offer.InterfaceInstance, + !memcmp(&channel->offermsg.offer.InterfaceInstance, + &newchannel->offermsg.offer.InterfaceInstance, sizeof(struct hv_guid))) { fnew = false; break; @@ -338,14 +338,14 @@ static void vmbus_process_offer(void *context) } if (fnew) - list_add_tail(&newchannel->ListEntry, + list_add_tail(&newchannel->listentry, &gVmbusConnection.ChannelList); spin_unlock_irqrestore(&gVmbusConnection.channel_lock, flags); if (!fnew) { DPRINT_DBG(VMBUS, "Ignoring duplicate offer for relid (%d)", - newchannel->OfferMsg.ChildRelId); + newchannel->offermsg.child_relid); free_channel(newchannel); return; } @@ -355,27 +355,27 @@ static void vmbus_process_offer(void *context) * We need to set the DeviceObject field before calling * VmbusChildDeviceAdd() */ - newchannel->DeviceObject = VmbusChildDeviceCreate( - &newchannel->OfferMsg.Offer.InterfaceType, - &newchannel->OfferMsg.Offer.InterfaceInstance, + newchannel->device_obj = VmbusChildDeviceCreate( + &newchannel->offermsg.offer.InterfaceType, + &newchannel->offermsg.offer.InterfaceInstance, newchannel); DPRINT_DBG(VMBUS, "child device object allocated - %p", - newchannel->DeviceObject); + newchannel->device_obj); /* * Add the new device to the bus. This will kick off device-driver * binding which eventually invokes the device driver's AddDevice() * method. */ - ret = VmbusChildDeviceAdd(newchannel->DeviceObject); + ret = VmbusChildDeviceAdd(newchannel->device_obj); if (ret != 0) { DPRINT_ERR(VMBUS, "unable to add child device object (relid %d)", - newchannel->OfferMsg.ChildRelId); + newchannel->offermsg.child_relid); spin_lock_irqsave(&gVmbusConnection.channel_lock, flags); - list_del(&newchannel->ListEntry); + list_del(&newchannel->listentry); spin_unlock_irqrestore(&gVmbusConnection.channel_lock, flags); free_channel(newchannel); @@ -385,11 +385,11 @@ static void vmbus_process_offer(void *context) * so that when we do close the channel normally, we * can cleanup properly */ - newchannel->State = CHANNEL_OPEN_STATE; + newchannel->state = CHANNEL_OPEN_STATE; /* Open IC channels */ for (cnt = 0; cnt < MAX_MSG_TYPES; cnt++) { - if (memcmp(&newchannel->OfferMsg.Offer.InterfaceType, + if (memcmp(&newchannel->offermsg.offer.InterfaceType, &hv_cb_utils[cnt].data, sizeof(struct hv_guid)) == 0 && vmbus_open(newchannel, 2 * PAGE_SIZE, @@ -413,7 +413,7 @@ static void vmbus_process_rescind_offer(void *context) { struct vmbus_channel *channel = context; - VmbusChildDeviceRemove(channel->DeviceObject); + VmbusChildDeviceRemove(channel->device_obj); } /* @@ -434,7 +434,7 @@ static void vmbus_onoffer(struct vmbus_channel_message_header *hdr) offer = (struct vmbus_channel_offer_channel *)hdr; for (i = 0; i < MAX_NUM_DEVICE_CLASSES_SUPPORTED; i++) { - if (memcmp(&offer->Offer.InterfaceType, + if (memcmp(&offer->offer.InterfaceType, &gSupportedDeviceClasses[i], sizeof(struct hv_guid)) == 0) { fsupported = 1; break; @@ -443,12 +443,12 @@ static void vmbus_onoffer(struct vmbus_channel_message_header *hdr) if (!fsupported) { DPRINT_DBG(VMBUS, "Ignoring channel offer notification for " - "child relid %d", offer->ChildRelId); + "child relid %d", offer->child_relid); return; } - guidtype = &offer->Offer.InterfaceType; - guidinstance = &offer->Offer.InterfaceInstance; + guidtype = &offer->offer.InterfaceType; + guidinstance = &offer->offer.InterfaceInstance; DPRINT_INFO(VMBUS, "Channel offer notification - " "child relid %d monitor id %d allocated %d, " @@ -456,8 +456,8 @@ static void vmbus_onoffer(struct vmbus_channel_message_header *hdr) "%02x%02x%02x%02x%02x%02x%02x%02x} " "instance {%02x%02x%02x%02x-%02x%02x-%02x%02x-" "%02x%02x%02x%02x%02x%02x%02x%02x}", - offer->ChildRelId, offer->MonitorId, - offer->MonitorAllocated, + offer->child_relid, offer->monitorid, + offer->monitor_allocated, guidtype->data[3], guidtype->data[2], guidtype->data[1], guidtype->data[0], guidtype->data[5], guidtype->data[4], @@ -484,13 +484,13 @@ static void vmbus_onoffer(struct vmbus_channel_message_header *hdr) DPRINT_DBG(VMBUS, "channel object allocated - %p", newchannel); - memcpy(&newchannel->OfferMsg, offer, + memcpy(&newchannel->offermsg, offer, sizeof(struct vmbus_channel_offer_channel)); - newchannel->MonitorGroup = (u8)offer->MonitorId / 32; - newchannel->MonitorBit = (u8)offer->MonitorId % 32; + newchannel->monitor_grp = (u8)offer->monitorid / 32; + newchannel->monitor_bit = (u8)offer->monitorid % 32; /* TODO: Make sure the offer comes from our parent partition */ - osd_schedule_callback(newchannel->ControlWQ, vmbus_process_offer, + osd_schedule_callback(newchannel->controlwq, vmbus_process_offer, newchannel); } @@ -505,14 +505,14 @@ static void vmbus_onoffer_rescind(struct vmbus_channel_message_header *hdr) struct vmbus_channel *channel; rescind = (struct vmbus_channel_rescind_offer *)hdr; - channel = GetChannelFromRelId(rescind->ChildRelId); + channel = GetChannelFromRelId(rescind->child_relid); if (channel == NULL) { DPRINT_DBG(VMBUS, "channel not found for relId %d", - rescind->ChildRelId); + rescind->child_relid); return; } - osd_schedule_callback(channel->ControlWQ, + osd_schedule_callback(channel->controlwq, vmbus_process_rescind_offer, channel); } @@ -545,7 +545,7 @@ static void vmbus_onopen_result(struct vmbus_channel_message_header *hdr) unsigned long flags; result = (struct vmbus_channel_open_result *)hdr; - DPRINT_DBG(VMBUS, "vmbus open result - %d", result->Status); + DPRINT_DBG(VMBUS, "vmbus open result - %d", result->status); /* * Find the open msg, copy the result and signal/unblock the wait event @@ -556,17 +556,17 @@ static void vmbus_onopen_result(struct vmbus_channel_message_header *hdr) /* FIXME: this should probably use list_entry() instead */ msginfo = (struct vmbus_channel_msginfo *)curr; requestheader = - (struct vmbus_channel_message_header *)msginfo->Msg; + (struct vmbus_channel_message_header *)msginfo->msg; - if (requestheader->MessageType == ChannelMessageOpenChannel) { + if (requestheader->msgtype == CHANNELMSG_OPENCHANNEL) { openmsg = - (struct vmbus_channel_open_channel *)msginfo->Msg; - if (openmsg->ChildRelId == result->ChildRelId && - openmsg->OpenId == result->OpenId) { - memcpy(&msginfo->Response.OpenResult, + (struct vmbus_channel_open_channel *)msginfo->msg; + if (openmsg->child_relid == result->child_relid && + openmsg->openid == result->openid) { + memcpy(&msginfo->response.open_result, result, sizeof(struct vmbus_channel_open_result)); - osd_WaitEventSet(msginfo->WaitEvent); + osd_WaitEventSet(msginfo->waitevent); break; } } @@ -592,7 +592,7 @@ static void vmbus_ongpadl_created(struct vmbus_channel_message_header *hdr) gpadlcreated = (struct vmbus_channel_gpadl_created *)hdr; DPRINT_DBG(VMBUS, "vmbus gpadl created result - %d", - gpadlcreated->CreationStatus); + gpadlcreated->creation_status); /* * Find the establish msg, copy the result and signal/unblock the wait @@ -604,19 +604,19 @@ static void vmbus_ongpadl_created(struct vmbus_channel_message_header *hdr) /* FIXME: this should probably use list_entry() instead */ msginfo = (struct vmbus_channel_msginfo *)curr; requestheader = - (struct vmbus_channel_message_header *)msginfo->Msg; + (struct vmbus_channel_message_header *)msginfo->msg; - if (requestheader->MessageType == ChannelMessageGpadlHeader) { + if (requestheader->msgtype == CHANNELMSG_GPADL_HEADER) { gpadlheader = (struct vmbus_channel_gpadl_header *)requestheader; - if ((gpadlcreated->ChildRelId == - gpadlheader->ChildRelId) && - (gpadlcreated->Gpadl == gpadlheader->Gpadl)) { - memcpy(&msginfo->Response.GpadlCreated, + if ((gpadlcreated->child_relid == + gpadlheader->child_relid) && + (gpadlcreated->gpadl == gpadlheader->gpadl)) { + memcpy(&msginfo->response.gpadl_created, gpadlcreated, sizeof(struct vmbus_channel_gpadl_created)); - osd_WaitEventSet(msginfo->WaitEvent); + osd_WaitEventSet(msginfo->waitevent); break; } } @@ -652,17 +652,17 @@ static void vmbus_ongpadl_torndown( /* FIXME: this should probably use list_entry() instead */ msginfo = (struct vmbus_channel_msginfo *)curr; requestheader = - (struct vmbus_channel_message_header *)msginfo->Msg; + (struct vmbus_channel_message_header *)msginfo->msg; - if (requestheader->MessageType == ChannelMessageGpadlTeardown) { + if (requestheader->msgtype == CHANNELMSG_GPADL_TEARDOWN) { gpadl_teardown = (struct vmbus_channel_gpadl_teardown *)requestheader; - if (gpadl_torndown->Gpadl == gpadl_teardown->Gpadl) { - memcpy(&msginfo->Response.GpadlTorndown, + if (gpadl_torndown->gpadl == gpadl_teardown->gpadl) { + memcpy(&msginfo->response.gpadl_torndown, gpadl_torndown, sizeof(struct vmbus_channel_gpadl_torndown)); - osd_WaitEventSet(msginfo->WaitEvent); + osd_WaitEventSet(msginfo->waitevent); break; } } @@ -694,16 +694,16 @@ static void vmbus_onversion_response( /* FIXME: this should probably use list_entry() instead */ msginfo = (struct vmbus_channel_msginfo *)curr; requestheader = - (struct vmbus_channel_message_header *)msginfo->Msg; + (struct vmbus_channel_message_header *)msginfo->msg; - if (requestheader->MessageType == - ChannelMessageInitiateContact) { + if (requestheader->msgtype == + CHANNELMSG_INITIATE_CONTACT) { initiate = (struct vmbus_channel_initiate_contact *)requestheader; - memcpy(&msginfo->Response.VersionResponse, + memcpy(&msginfo->response.version_response, version_response, sizeof(struct vmbus_channel_version_response)); - osd_WaitEventSet(msginfo->WaitEvent); + osd_WaitEventSet(msginfo->waitevent); } } spin_unlock_irqrestore(&gVmbusConnection.channelmsg_lock, flags); @@ -711,24 +711,24 @@ static void vmbus_onversion_response( /* Channel message dispatch table */ static struct vmbus_channel_message_table_entry - gChannelMessageTable[ChannelMessageCount] = { - {ChannelMessageInvalid, NULL}, - {ChannelMessageOfferChannel, vmbus_onoffer}, - {ChannelMessageRescindChannelOffer, vmbus_onoffer_rescind}, - {ChannelMessageRequestOffers, NULL}, - {ChannelMessageAllOffersDelivered, vmbus_onoffers_delivered}, - {ChannelMessageOpenChannel, NULL}, - {ChannelMessageOpenChannelResult, vmbus_onopen_result}, - {ChannelMessageCloseChannel, NULL}, - {ChannelMessageGpadlHeader, NULL}, - {ChannelMessageGpadlBody, NULL}, - {ChannelMessageGpadlCreated, vmbus_ongpadl_created}, - {ChannelMessageGpadlTeardown, NULL}, - {ChannelMessageGpadlTorndown, vmbus_ongpadl_torndown}, - {ChannelMessageRelIdReleased, NULL}, - {ChannelMessageInitiateContact, NULL}, - {ChannelMessageVersionResponse, vmbus_onversion_response}, - {ChannelMessageUnload, NULL}, + gChannelMessageTable[CHANNELMSG_COUNT] = { + {CHANNELMSG_INVALID, NULL}, + {CHANNELMSG_OFFERCHANNEL, vmbus_onoffer}, + {CHANNELMSG_RESCIND_CHANNELOFFER, vmbus_onoffer_rescind}, + {CHANNELMSG_REQUESTOFFERS, NULL}, + {CHANNELMSG_ALLOFFERS_DELIVERED, vmbus_onoffers_delivered}, + {CHANNELMSG_OPENCHANNEL, NULL}, + {CHANNELMSG_OPENCHANNEL_RESULT, vmbus_onopen_result}, + {CHANNELMSG_CLOSECHANNEL, NULL}, + {CHANNELMSG_GPADL_HEADER, NULL}, + {CHANNELMSG_GPADL_BODY, NULL}, + {CHANNELMSG_GPADL_CREATED, vmbus_ongpadl_created}, + {CHANNELMSG_GPADL_TEARDOWN, NULL}, + {CHANNELMSG_GPADL_TORNDOWN, vmbus_ongpadl_torndown}, + {CHANNELMSG_RELID_RELEASED, NULL}, + {CHANNELMSG_INITIATE_CONTACT, NULL}, + {CHANNELMSG_VERSION_RESPONSE, vmbus_onversion_response}, + {CHANNELMSG_UNLOAD, NULL}, }; /* @@ -745,23 +745,23 @@ void vmbus_onmessage(void *context) hdr = (struct vmbus_channel_message_header *)msg->u.Payload; size = msg->Header.PayloadSize; - DPRINT_DBG(VMBUS, "message type %d size %d", hdr->MessageType, size); + DPRINT_DBG(VMBUS, "message type %d size %d", hdr->msgtype, size); - if (hdr->MessageType >= ChannelMessageCount) { + if (hdr->msgtype >= CHANNELMSG_COUNT) { DPRINT_ERR(VMBUS, "Received invalid channel message type %d size %d", - hdr->MessageType, size); + hdr->msgtype, size); print_hex_dump_bytes("", DUMP_PREFIX_NONE, (unsigned char *)msg->u.Payload, size); kfree(msg); return; } - if (gChannelMessageTable[hdr->MessageType].messageHandler) - gChannelMessageTable[hdr->MessageType].messageHandler(hdr); + if (gChannelMessageTable[hdr->msgtype].messageHandler) + gChannelMessageTable[hdr->msgtype].messageHandler(hdr); else DPRINT_ERR(VMBUS, "Unhandled channel message type %d", - hdr->MessageType); + hdr->msgtype); /* Free the msg that was allocated in VmbusOnMsgDPC() */ kfree(msg); @@ -782,15 +782,15 @@ int vmbus_request_offers(void) if (!msginfo) return -ENOMEM; - msginfo->WaitEvent = osd_WaitEventCreate(); - if (!msginfo->WaitEvent) { + msginfo->waitevent = osd_WaitEventCreate(); + if (!msginfo->waitevent) { kfree(msginfo); return -ENOMEM; } - msg = (struct vmbus_channel_message_header *)msginfo->Msg; + msg = (struct vmbus_channel_message_header *)msginfo->msg; - msg->MessageType = ChannelMessageRequestOffers; + msg->msgtype = CHANNELMSG_REQUESTOFFERS; /*SpinlockAcquire(gVmbusConnection.channelMsgLock); INSERT_TAIL_LIST(&gVmbusConnection.channelMsgList, @@ -817,7 +817,7 @@ int vmbus_request_offers(void) Cleanup: if (msginfo) { - kfree(msginfo->WaitEvent); + kfree(msginfo->waitevent); kfree(msginfo); } @@ -837,17 +837,17 @@ void vmbus_release_unattached_channels(void) spin_lock_irqsave(&gVmbusConnection.channel_lock, flags); list_for_each_entry_safe(channel, pos, &gVmbusConnection.ChannelList, - ListEntry) { + listentry) { if (channel == start) break; - if (!channel->DeviceObject->Driver) { - list_del(&channel->ListEntry); + if (!channel->device_obj->Driver) { + list_del(&channel->listentry); DPRINT_INFO(VMBUS, "Releasing unattached device object %p", - channel->DeviceObject); + channel->device_obj); - VmbusChildDeviceRemove(channel->DeviceObject); + VmbusChildDeviceRemove(channel->device_obj); free_channel(channel); } else { if (!start) diff --git a/drivers/staging/hv/channel_mgmt.h b/drivers/staging/hv/channel_mgmt.h index d16cc0811169..12f30aff152d 100644 --- a/drivers/staging/hv/channel_mgmt.h +++ b/drivers/staging/hv/channel_mgmt.h @@ -33,60 +33,60 @@ /* Version 1 messages */ enum vmbus_channel_message_type { - ChannelMessageInvalid = 0, - ChannelMessageOfferChannel = 1, - ChannelMessageRescindChannelOffer = 2, - ChannelMessageRequestOffers = 3, - ChannelMessageAllOffersDelivered = 4, - ChannelMessageOpenChannel = 5, - ChannelMessageOpenChannelResult = 6, - ChannelMessageCloseChannel = 7, - ChannelMessageGpadlHeader = 8, - ChannelMessageGpadlBody = 9, - ChannelMessageGpadlCreated = 10, - ChannelMessageGpadlTeardown = 11, - ChannelMessageGpadlTorndown = 12, - ChannelMessageRelIdReleased = 13, - ChannelMessageInitiateContact = 14, - ChannelMessageVersionResponse = 15, - ChannelMessageUnload = 16, + CHANNELMSG_INVALID = 0, + CHANNELMSG_OFFERCHANNEL = 1, + CHANNELMSG_RESCIND_CHANNELOFFER = 2, + CHANNELMSG_REQUESTOFFERS = 3, + CHANNELMSG_ALLOFFERS_DELIVERED = 4, + CHANNELMSG_OPENCHANNEL = 5, + CHANNELMSG_OPENCHANNEL_RESULT = 6, + CHANNELMSG_CLOSECHANNEL = 7, + CHANNELMSG_GPADL_HEADER = 8, + CHANNELMSG_GPADL_BODY = 9, + CHANNELMSG_GPADL_CREATED = 10, + CHANNELMSG_GPADL_TEARDOWN = 11, + CHANNELMSG_GPADL_TORNDOWN = 12, + CHANNELMSG_RELID_RELEASED = 13, + CHANNELMSG_INITIATE_CONTACT = 14, + CHANNELMSG_VERSION_RESPONSE = 15, + CHANNELMSG_UNLOAD = 16, #ifdef VMBUS_FEATURE_PARENT_OR_PEER_MEMORY_MAPPED_INTO_A_CHILD - ChannelMessageViewRangeAdd = 17, - ChannelMessageViewRangeRemove = 18, + CHANNELMSG_VIEWRANGE_ADD = 17, + CHANNELMSG_VIEWRANGE_REMOVE = 18, #endif - ChannelMessageCount + CHANNELMSG_COUNT }; struct vmbus_channel_message_header { - enum vmbus_channel_message_type MessageType; - u32 Padding; + enum vmbus_channel_message_type msgtype; + u32 padding; } __attribute__((packed)); /* Query VMBus Version parameters */ struct vmbus_channel_query_vmbus_version { - struct vmbus_channel_message_header Header; - u32 Version; + struct vmbus_channel_message_header header; + u32 version; } __attribute__((packed)); /* VMBus Version Supported parameters */ struct vmbus_channel_version_supported { - struct vmbus_channel_message_header Header; - bool VersionSupported; + struct vmbus_channel_message_header header; + bool version_supported; } __attribute__((packed)); /* Offer Channel parameters */ struct vmbus_channel_offer_channel { - struct vmbus_channel_message_header Header; - struct vmbus_channel_offer Offer; - u32 ChildRelId; - u8 MonitorId; - bool MonitorAllocated; + struct vmbus_channel_message_header header; + struct vmbus_channel_offer offer; + u32 child_relid; + u8 monitorid; + bool monitor_allocated; } __attribute__((packed)); /* Rescind Offer parameters */ struct vmbus_channel_rescind_offer { - struct vmbus_channel_message_header Header; - u32 ChildRelId; + struct vmbus_channel_message_header header; + u32 child_relid; } __attribute__((packed)); /* @@ -100,43 +100,43 @@ struct vmbus_channel_rescind_offer { /* Open Channel parameters */ struct vmbus_channel_open_channel { - struct vmbus_channel_message_header Header; + struct vmbus_channel_message_header header; /* Identifies the specific VMBus channel that is being opened. */ - u32 ChildRelId; + u32 child_relid; /* ID making a particular open request at a channel offer unique. */ - u32 OpenId; + u32 openid; /* GPADL for the channel's ring buffer. */ - u32 RingBufferGpadlHandle; + u32 ringbuffer_gpadlhandle; /* GPADL for the channel's server context save area. */ - u32 ServerContextAreaGpadlHandle; + u32 server_contextarea_gpadlhandle; /* * The upstream ring buffer begins at offset zero in the memory * described by RingBufferGpadlHandle. The downstream ring buffer * follows it at this offset (in pages). */ - u32 DownstreamRingBufferPageOffset; + u32 downstream_ringbuffer_pageoffset; /* User-specific data to be passed along to the server endpoint. */ - unsigned char UserData[MAX_USER_DEFINED_BYTES]; + unsigned char userdata[MAX_USER_DEFINED_BYTES]; } __attribute__((packed)); /* Open Channel Result parameters */ struct vmbus_channel_open_result { - struct vmbus_channel_message_header Header; - u32 ChildRelId; - u32 OpenId; - u32 Status; + struct vmbus_channel_message_header header; + u32 child_relid; + u32 openid; + u32 status; } __attribute__((packed)); /* Close channel parameters; */ struct vmbus_channel_close_channel { - struct vmbus_channel_message_header Header; - u32 ChildRelId; + struct vmbus_channel_message_header header; + u32 child_relid; } __attribute__((packed)); /* Channel Message GPADL */ @@ -151,72 +151,72 @@ struct vmbus_channel_close_channel { * follow-up packet that contains more. */ struct vmbus_channel_gpadl_header { - struct vmbus_channel_message_header Header; - u32 ChildRelId; - u32 Gpadl; - u16 RangeBufLen; - u16 RangeCount; - struct gpa_range Range[0]; + struct vmbus_channel_message_header header; + u32 child_relid; + u32 gpadl; + u16 range_buflen; + u16 rangecount; + struct gpa_range range[0]; } __attribute__((packed)); /* This is the followup packet that contains more PFNs. */ struct vmbus_channel_gpadl_body { - struct vmbus_channel_message_header Header; - u32 MessageNumber; - u32 Gpadl; - u64 Pfn[0]; + struct vmbus_channel_message_header header; + u32 msgnumber; + u32 gpadl; + u64 pfn[0]; } __attribute__((packed)); struct vmbus_channel_gpadl_created { - struct vmbus_channel_message_header Header; - u32 ChildRelId; - u32 Gpadl; - u32 CreationStatus; + struct vmbus_channel_message_header header; + u32 child_relid; + u32 gpadl; + u32 creation_status; } __attribute__((packed)); struct vmbus_channel_gpadl_teardown { - struct vmbus_channel_message_header Header; - u32 ChildRelId; - u32 Gpadl; + struct vmbus_channel_message_header header; + u32 child_relid; + u32 gpadl; } __attribute__((packed)); struct vmbus_channel_gpadl_torndown { - struct vmbus_channel_message_header Header; - u32 Gpadl; + struct vmbus_channel_message_header header; + u32 gpadl; } __attribute__((packed)); #ifdef VMBUS_FEATURE_PARENT_OR_PEER_MEMORY_MAPPED_INTO_A_CHILD struct vmbus_channel_view_range_add { - struct vmbus_channel_message_header Header; - PHYSICAL_ADDRESS ViewRangeBase; - u64 ViewRangeLength; - u32 ChildRelId; + struct vmbus_channel_message_header header; + PHYSICAL_ADDRESS viewrange_base; + u64 viewrange_length; + u32 child_relid; } __attribute__((packed)); struct vmbus_channel_view_range_remove { - struct vmbus_channel_message_header Header; - PHYSICAL_ADDRESS ViewRangeBase; - u32 ChildRelId; + struct vmbus_channel_message_header header; + PHYSICAL_ADDRESS viewrange_base; + u32 child_relid; } __attribute__((packed)); #endif struct vmbus_channel_relid_released { - struct vmbus_channel_message_header Header; - u32 ChildRelId; + struct vmbus_channel_message_header header; + u32 child_relid; } __attribute__((packed)); struct vmbus_channel_initiate_contact { - struct vmbus_channel_message_header Header; - u32 VMBusVersionRequested; - u32 Padding2; - u64 InterruptPage; - u64 MonitorPage1; - u64 MonitorPage2; + struct vmbus_channel_message_header header; + u32 vmbus_version_requested; + u32 padding2; + u64 interrupt_page; + u64 monitor_page1; + u64 monitor_page2; } __attribute__((packed)); struct vmbus_channel_version_response { - struct vmbus_channel_message_header Header; - bool VersionSupported; + struct vmbus_channel_message_header header; + bool version_supported; } __attribute__((packed)); enum vmbus_channel_state { @@ -226,54 +226,54 @@ enum vmbus_channel_state { }; struct vmbus_channel { - struct list_head ListEntry; + struct list_head listentry; - struct hv_device *DeviceObject; + struct hv_device *device_obj; struct timer_list poll_timer; /* SA-111 workaround */ - enum vmbus_channel_state State; + enum vmbus_channel_state state; - struct vmbus_channel_offer_channel OfferMsg; + struct vmbus_channel_offer_channel offermsg; /* * These are based on the OfferMsg.MonitorId. * Save it here for easy access. */ - u8 MonitorGroup; - u8 MonitorBit; + u8 monitor_grp; + u8 monitor_bit; - u32 RingBufferGpadlHandle; + u32 ringbuffer_gpadlhandle; /* Allocated memory for ring buffer */ - void *RingBufferPages; - u32 RingBufferPageCount; - struct hv_ring_buffer_info Outbound; /* send to parent */ - struct hv_ring_buffer_info Inbound; /* receive from parent */ + void *ringbuffer_pages; + u32 ringbuffer_pagecount; + struct hv_ring_buffer_info outbound; /* send to parent */ + struct hv_ring_buffer_info inbound; /* receive from parent */ spinlock_t inbound_lock; - struct workqueue_struct *ControlWQ; + struct workqueue_struct *controlwq; /* Channel callback are invoked in this workqueue context */ /* HANDLE dataWorkQueue; */ - void (*OnChannelCallback)(void *context); - void *ChannelCallbackContext; + void (*onchannel_callback)(void *context); + void *channel_callback_context; }; struct vmbus_channel_debug_info { - u32 RelId; - enum vmbus_channel_state State; - struct hv_guid InterfaceType; - struct hv_guid InterfaceInstance; - u32 MonitorId; - u32 ServerMonitorPending; - u32 ServerMonitorLatency; - u32 ServerMonitorConnectionId; - u32 ClientMonitorPending; - u32 ClientMonitorLatency; - u32 ClientMonitorConnectionId; - - struct hv_ring_buffer_debug_info Inbound; - struct hv_ring_buffer_debug_info Outbound; + u32 relid; + enum vmbus_channel_state state; + struct hv_guid interfacetype; + struct hv_guid interface_instance; + u32 monitorid; + u32 servermonitor_pending; + u32 servermonitor_latency; + u32 servermonitor_connectionid; + u32 clientmonitor_pending; + u32 clientmonitor_latency; + u32 clientmonitor_connectionid; + + struct hv_ring_buffer_debug_info inbound; + struct hv_ring_buffer_debug_info outbound; }; /* @@ -282,28 +282,28 @@ struct vmbus_channel_debug_info { */ struct vmbus_channel_msginfo { /* Bookkeeping stuff */ - struct list_head MsgListEntry; + struct list_head msglistentry; /* So far, this is only used to handle gpadl body message */ - struct list_head SubMsgList; + struct list_head submsglist; /* Synchronize the request/response if needed */ - struct osd_waitevent *WaitEvent; + struct osd_waitevent *waitevent; union { - struct vmbus_channel_version_supported VersionSupported; - struct vmbus_channel_open_result OpenResult; - struct vmbus_channel_gpadl_torndown GpadlTorndown; - struct vmbus_channel_gpadl_created GpadlCreated; - struct vmbus_channel_version_response VersionResponse; - } Response; - - u32 MessageSize; + struct vmbus_channel_version_supported version_supported; + struct vmbus_channel_open_result open_result; + struct vmbus_channel_gpadl_torndown gpadl_torndown; + struct vmbus_channel_gpadl_created gpadl_created; + struct vmbus_channel_version_response version_response; + } response; + + u32 msgsize; /* * The channel message that goes out on the "wire". * It will contain at minimum the VMBUS_CHANNEL_MESSAGE_HEADER header */ - unsigned char Msg[0]; + unsigned char msg[0]; }; diff --git a/drivers/staging/hv/connection.c b/drivers/staging/hv/connection.c index f8477072ace4..6f3f525bb84c 100644 --- a/drivers/staging/hv/connection.c +++ b/drivers/staging/hv/connection.c @@ -95,19 +95,19 @@ int VmbusConnect(void) goto Cleanup; } - msgInfo->WaitEvent = osd_WaitEventCreate(); - if (!msgInfo->WaitEvent) { + msgInfo->waitevent = osd_WaitEventCreate(); + if (!msgInfo->waitevent) { ret = -ENOMEM; goto Cleanup; } - msg = (struct vmbus_channel_initiate_contact *)msgInfo->Msg; + msg = (struct vmbus_channel_initiate_contact *)msgInfo->msg; - msg->Header.MessageType = ChannelMessageInitiateContact; - msg->VMBusVersionRequested = VMBUS_REVISION_NUMBER; - msg->InterruptPage = virt_to_phys(gVmbusConnection.InterruptPage); - msg->MonitorPage1 = virt_to_phys(gVmbusConnection.MonitorPages); - msg->MonitorPage2 = virt_to_phys( + msg->header.msgtype = CHANNELMSG_INITIATE_CONTACT; + msg->vmbus_version_requested = VMBUS_REVISION_NUMBER; + msg->interrupt_page = virt_to_phys(gVmbusConnection.InterruptPage); + msg->monitor_page1 = virt_to_phys(gVmbusConnection.MonitorPages); + msg->monitor_page2 = virt_to_phys( (void *)((unsigned long)gVmbusConnection.MonitorPages + PAGE_SIZE)); @@ -116,30 +116,30 @@ int VmbusConnect(void) * receive the response before returning from this routine */ spin_lock_irqsave(&gVmbusConnection.channelmsg_lock, flags); - list_add_tail(&msgInfo->MsgListEntry, + list_add_tail(&msgInfo->msglistentry, &gVmbusConnection.ChannelMsgList); spin_unlock_irqrestore(&gVmbusConnection.channelmsg_lock, flags); DPRINT_DBG(VMBUS, "Vmbus connection - interrupt pfn %llx, " "monitor1 pfn %llx,, monitor2 pfn %llx", - msg->InterruptPage, msg->MonitorPage1, msg->MonitorPage2); + msg->interrupt_page, msg->monitor_page1, msg->monitor_page2); DPRINT_DBG(VMBUS, "Sending channel initiate msg..."); ret = VmbusPostMessage(msg, sizeof(struct vmbus_channel_initiate_contact)); if (ret != 0) { - list_del(&msgInfo->MsgListEntry); + list_del(&msgInfo->msglistentry); goto Cleanup; } /* Wait for the connection response */ - osd_WaitEventWait(msgInfo->WaitEvent); + osd_WaitEventWait(msgInfo->waitevent); - list_del(&msgInfo->MsgListEntry); + list_del(&msgInfo->msglistentry); /* Check if successful */ - if (msgInfo->Response.VersionResponse.VersionSupported) { + if (msgInfo->response.version_response.version_supported) { DPRINT_INFO(VMBUS, "Vmbus connected!!"); gVmbusConnection.ConnectState = Connected; @@ -151,7 +151,7 @@ int VmbusConnect(void) goto Cleanup; } - kfree(msgInfo->WaitEvent); + kfree(msgInfo->waitevent); kfree(msgInfo); return 0; @@ -172,7 +172,7 @@ Cleanup: } if (msgInfo) { - kfree(msgInfo->WaitEvent); + kfree(msgInfo->waitevent); kfree(msgInfo); } @@ -195,7 +195,7 @@ int VmbusDisconnect(void) if (!msg) return -ENOMEM; - msg->MessageType = ChannelMessageUnload; + msg->msgtype = CHANNELMSG_UNLOAD; ret = VmbusPostMessage(msg, sizeof(struct vmbus_channel_message_header)); @@ -226,8 +226,8 @@ struct vmbus_channel *GetChannelFromRelId(u32 relId) unsigned long flags; spin_lock_irqsave(&gVmbusConnection.channel_lock, flags); - list_for_each_entry(channel, &gVmbusConnection.ChannelList, ListEntry) { - if (channel->OfferMsg.ChildRelId == relId) { + list_for_each_entry(channel, &gVmbusConnection.ChannelList, listentry) { + if (channel->offermsg.child_relid == relId) { foundChannel = channel; break; } diff --git a/drivers/staging/hv/hv_utils.c b/drivers/staging/hv/hv_utils.c index 702a478d5542..6dc1c35414d2 100644 --- a/drivers/staging/hv/hv_utils.c +++ b/drivers/staging/hv/hv_utils.c @@ -271,15 +271,15 @@ static int __init init_hyperv_utils(void) if (!dmi_check_system(hv_utils_dmi_table)) return -ENODEV; - hv_cb_utils[HV_SHUTDOWN_MSG].channel->OnChannelCallback = + hv_cb_utils[HV_SHUTDOWN_MSG].channel->onchannel_callback = &shutdown_onchannelcallback; hv_cb_utils[HV_SHUTDOWN_MSG].callback = &shutdown_onchannelcallback; - hv_cb_utils[HV_TIMESYNC_MSG].channel->OnChannelCallback = + hv_cb_utils[HV_TIMESYNC_MSG].channel->onchannel_callback = ×ync_onchannelcallback; hv_cb_utils[HV_TIMESYNC_MSG].callback = ×ync_onchannelcallback; - hv_cb_utils[HV_HEARTBEAT_MSG].channel->OnChannelCallback = + hv_cb_utils[HV_HEARTBEAT_MSG].channel->onchannel_callback = &heartbeat_onchannelcallback; hv_cb_utils[HV_HEARTBEAT_MSG].callback = &heartbeat_onchannelcallback; @@ -290,15 +290,15 @@ static void exit_hyperv_utils(void) { printk(KERN_INFO "De-Registered HyperV Utility Driver\n"); - hv_cb_utils[HV_SHUTDOWN_MSG].channel->OnChannelCallback = + hv_cb_utils[HV_SHUTDOWN_MSG].channel->onchannel_callback = &chn_cb_negotiate; hv_cb_utils[HV_SHUTDOWN_MSG].callback = &chn_cb_negotiate; - hv_cb_utils[HV_TIMESYNC_MSG].channel->OnChannelCallback = + hv_cb_utils[HV_TIMESYNC_MSG].channel->onchannel_callback = &chn_cb_negotiate; hv_cb_utils[HV_TIMESYNC_MSG].callback = &chn_cb_negotiate; - hv_cb_utils[HV_HEARTBEAT_MSG].channel->OnChannelCallback = + hv_cb_utils[HV_HEARTBEAT_MSG].channel->onchannel_callback = &chn_cb_negotiate; hv_cb_utils[HV_HEARTBEAT_MSG].callback = &chn_cb_negotiate; } diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c index 0d9f3a411e72..2bbf4ecdf550 100644 --- a/drivers/staging/hv/vmbus_drv.c +++ b/drivers/staging/hv/vmbus_drv.c @@ -139,35 +139,35 @@ static void get_channel_info(struct hv_device *device, vmbus_get_debug_info(device->channel, &debug_info); - info->ChannelId = debug_info.RelId; - info->ChannelState = debug_info.State; - memcpy(&info->ChannelType, &debug_info.InterfaceType, + info->ChannelId = debug_info.relid; + info->ChannelState = debug_info.state; + memcpy(&info->ChannelType, &debug_info.interfacetype, sizeof(struct hv_guid)); - memcpy(&info->ChannelInstance, &debug_info.InterfaceInstance, + memcpy(&info->ChannelInstance, &debug_info.interface_instance, sizeof(struct hv_guid)); - info->MonitorId = debug_info.MonitorId; + info->MonitorId = debug_info.monitorid; - info->ServerMonitorPending = debug_info.ServerMonitorPending; - info->ServerMonitorLatency = debug_info.ServerMonitorLatency; - info->ServerMonitorConnectionId = debug_info.ServerMonitorConnectionId; + info->ServerMonitorPending = debug_info.servermonitor_pending; + info->ServerMonitorLatency = debug_info.servermonitor_latency; + info->ServerMonitorConnectionId = debug_info.servermonitor_connectionid; - info->ClientMonitorPending = debug_info.ClientMonitorPending; - info->ClientMonitorLatency = debug_info.ClientMonitorLatency; - info->ClientMonitorConnectionId = debug_info.ClientMonitorConnectionId; + info->ClientMonitorPending = debug_info.clientmonitor_pending; + info->ClientMonitorLatency = debug_info.clientmonitor_latency; + info->ClientMonitorConnectionId = debug_info.clientmonitor_connectionid; - info->Inbound.InterruptMask = debug_info.Inbound.CurrentInterruptMask; - info->Inbound.ReadIndex = debug_info.Inbound.CurrentReadIndex; - info->Inbound.WriteIndex = debug_info.Inbound.CurrentWriteIndex; - info->Inbound.BytesAvailToRead = debug_info.Inbound.BytesAvailToRead; - info->Inbound.BytesAvailToWrite = debug_info.Inbound.BytesAvailToWrite; + info->Inbound.InterruptMask = debug_info.inbound.CurrentInterruptMask; + info->Inbound.ReadIndex = debug_info.inbound.CurrentReadIndex; + info->Inbound.WriteIndex = debug_info.inbound.CurrentWriteIndex; + info->Inbound.BytesAvailToRead = debug_info.inbound.BytesAvailToRead; + info->Inbound.BytesAvailToWrite = debug_info.inbound.BytesAvailToWrite; - info->Outbound.InterruptMask = debug_info.Outbound.CurrentInterruptMask; - info->Outbound.ReadIndex = debug_info.Outbound.CurrentReadIndex; - info->Outbound.WriteIndex = debug_info.Outbound.CurrentWriteIndex; - info->Outbound.BytesAvailToRead = debug_info.Outbound.BytesAvailToRead; + info->Outbound.InterruptMask = debug_info.outbound.CurrentInterruptMask; + info->Outbound.ReadIndex = debug_info.outbound.CurrentReadIndex; + info->Outbound.WriteIndex = debug_info.outbound.CurrentWriteIndex; + info->Outbound.BytesAvailToRead = debug_info.outbound.BytesAvailToRead; info->Outbound.BytesAvailToWrite = - debug_info.Outbound.BytesAvailToWrite; + debug_info.outbound.BytesAvailToWrite; } /* -- cgit v1.2.3 From f6feebe073db4c97dc10f6fab54f9d4b5816886b Mon Sep 17 00:00:00 2001 From: Haiyang Zhang Date: Mon, 8 Nov 2010 14:04:39 -0800 Subject: staging: hv: Convert camel cased struct fields in hv_api.h to lower cases staging: hv: Convert camel cased struct fields in hv_api.h to lower cases Signed-off-by: Haiyang Zhang Signed-off-by: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/channel.c | 32 ++--- drivers/staging/hv/channel_mgmt.c | 6 +- drivers/staging/hv/connection.c | 4 +- drivers/staging/hv/hv.c | 120 ++++++++--------- drivers/staging/hv/hv_api.h | 274 +++++++++++++++++++------------------- drivers/staging/hv/vmbus.c | 18 +-- 6 files changed, 227 insertions(+), 227 deletions(-) diff --git a/drivers/staging/hv/channel.c b/drivers/staging/hv/channel.c index 9fa0fe1525dc..7c15c4034e2d 100644 --- a/drivers/staging/hv/channel.c +++ b/drivers/staging/hv/channel.c @@ -43,24 +43,24 @@ static void DumpMonitorPage(struct hv_monitor_page *MonitorPage) int j = 0; DPRINT_DBG(VMBUS, "monitorPage - %p, trigger state - %d", - MonitorPage, MonitorPage->TriggerState); + MonitorPage, MonitorPage->trigger_state); for (i = 0; i < 4; i++) DPRINT_DBG(VMBUS, "trigger group (%d) - %llx", i, - MonitorPage->TriggerGroup[i].AsUINT64); + MonitorPage->trigger_group[i].as_uint64); for (i = 0; i < 4; i++) { for (j = 0; j < 32; j++) { DPRINT_DBG(VMBUS, "latency (%d)(%d) - %llx", i, j, - MonitorPage->Latency[i][j]); + MonitorPage->latency[i][j]); } } for (i = 0; i < 4; i++) { for (j = 0; j < 32; j++) { DPRINT_DBG(VMBUS, "param-conn id (%d)(%d) - %d", i, j, - MonitorPage->Parameter[i][j].ConnectionId.Asu32); + MonitorPage->parameter[i][j].connectionid.asu32); DPRINT_DBG(VMBUS, "param-flag (%d)(%d) - %d", i, j, - MonitorPage->Parameter[i][j].FlagNumber); + MonitorPage->parameter[i][j].flag_number); } } } @@ -84,8 +84,8 @@ static void vmbus_setevent(struct vmbus_channel *channel) monitorpage++; /* Get the child to parent monitor page */ set_bit(channel->monitor_bit, - (unsigned long *)&monitorpage->TriggerGroup - [channel->monitor_grp].Pending); + (unsigned long *)&monitorpage->trigger_group + [channel->monitor_grp].pending); } else { VmbusSetEvent(channel->offermsg.child_relid); @@ -108,7 +108,7 @@ static void VmbusChannelClearEvent(struct vmbus_channel *channel) monitorPage++; /* Get the child to parent monitor page */ clear_bit(Channel->monitor_bit, - (unsigned long *)&monitorPage->TriggerGroup + (unsigned long *)&monitorPage->trigger_group [Channel->monitor_grp].Pending); } } @@ -138,22 +138,22 @@ void vmbus_get_debug_info(struct vmbus_channel *channel, debuginfo->monitorid = channel->offermsg.monitorid; debuginfo->servermonitor_pending = - monitorpage->TriggerGroup[monitor_group].Pending; + monitorpage->trigger_group[monitor_group].pending; debuginfo->servermonitor_latency = - monitorpage->Latency[monitor_group][monitor_offset]; + monitorpage->latency[monitor_group][monitor_offset]; debuginfo->servermonitor_connectionid = - monitorpage->Parameter[monitor_group] - [monitor_offset].ConnectionId.u.Id; + monitorpage->parameter[monitor_group] + [monitor_offset].connectionid.u.id; monitorpage++; debuginfo->clientmonitor_pending = - monitorpage->TriggerGroup[monitor_group].Pending; + monitorpage->trigger_group[monitor_group].pending; debuginfo->clientmonitor_latency = - monitorpage->Latency[monitor_group][monitor_offset]; + monitorpage->latency[monitor_group][monitor_offset]; debuginfo->clientmonitor_connectionid = - monitorpage->Parameter[monitor_group] - [monitor_offset].ConnectionId.u.Id; + monitorpage->parameter[monitor_group] + [monitor_offset].connectionid.u.id; RingBufferGetDebugInfo(&channel->inbound, &debuginfo->inbound); RingBufferGetDebugInfo(&channel->outbound, &debuginfo->outbound); diff --git a/drivers/staging/hv/channel_mgmt.c b/drivers/staging/hv/channel_mgmt.c index dbfe0f22b6d6..be34e38c1a85 100644 --- a/drivers/staging/hv/channel_mgmt.c +++ b/drivers/staging/hv/channel_mgmt.c @@ -742,8 +742,8 @@ void vmbus_onmessage(void *context) struct vmbus_channel_message_header *hdr; int size; - hdr = (struct vmbus_channel_message_header *)msg->u.Payload; - size = msg->Header.PayloadSize; + hdr = (struct vmbus_channel_message_header *)msg->u.payload; + size = msg->header.payload_size; DPRINT_DBG(VMBUS, "message type %d size %d", hdr->msgtype, size); @@ -752,7 +752,7 @@ void vmbus_onmessage(void *context) "Received invalid channel message type %d size %d", hdr->msgtype, size); print_hex_dump_bytes("", DUMP_PREFIX_NONE, - (unsigned char *)msg->u.Payload, size); + (unsigned char *)msg->u.payload, size); kfree(msg); return; } diff --git a/drivers/staging/hv/connection.c b/drivers/staging/hv/connection.c index 6f3f525bb84c..ba50dd8fe52d 100644 --- a/drivers/staging/hv/connection.c +++ b/drivers/staging/hv/connection.c @@ -309,8 +309,8 @@ int VmbusPostMessage(void *buffer, size_t bufferLen) { union hv_connection_id connId; - connId.Asu32 = 0; - connId.u.Id = VMBUS_MESSAGE_CONNECTION_ID; + connId.asu32 = 0; + connId.u.id = VMBUS_MESSAGE_CONNECTION_ID; return HvPostMessage(connId, 1, buffer, bufferLen); } diff --git a/drivers/staging/hv/hv.c b/drivers/staging/hv/hv.c index 86b1ddd90404..ab033277226b 100644 --- a/drivers/staging/hv/hv.c +++ b/drivers/staging/hv/hv.c @@ -50,7 +50,7 @@ static int HvQueryHypervisorPresence(void) ebx = 0; ecx = 0; edx = 0; - op = HvCpuIdFunctionVersionAndFeatures; + op = HVCPUID_VERSION_FEATURES; cpuid(op, &eax, &ebx, &ecx, &edx); return ecx & HV_PRESENT_BIT; @@ -76,7 +76,7 @@ static int HvQueryHypervisorInfo(void) ebx = 0; ecx = 0; edx = 0; - op = HvCpuIdFunctionHvVendorAndMaxFunction; + op = HVCPUID_VENDOR_MAXFUNCTION; cpuid(op, &eax, &ebx, &ecx, &edx); DPRINT_INFO(VMBUS, "Vendor ID: %c%c%c%c%c%c%c%c%c%c%c%c", @@ -98,7 +98,7 @@ static int HvQueryHypervisorInfo(void) ebx = 0; ecx = 0; edx = 0; - op = HvCpuIdFunctionHvInterface; + op = HVCPUID_INTERFACE; cpuid(op, &eax, &ebx, &ecx, &edx); DPRINT_INFO(VMBUS, "Interface ID: %c%c%c%c", @@ -107,12 +107,12 @@ static int HvQueryHypervisorInfo(void) ((eax >> 16) & 0xFF), ((eax >> 24) & 0xFF)); - if (maxLeaf >= HvCpuIdFunctionMsHvVersion) { + if (maxLeaf >= HVCPUID_VERSION) { eax = 0; ebx = 0; ecx = 0; edx = 0; - op = HvCpuIdFunctionMsHvVersion; + op = HVCPUID_VERSION; cpuid(op, &eax, &ebx, &ecx, &edx); DPRINT_INFO(VMBUS, "OS Build:%d-%d.%d-%d-%d.%d",\ eax, @@ -222,7 +222,7 @@ int HvInit(void) gHvContext.GuestId = HV_LINUX_GUEST_ID; /* See if the hypercall page is already set */ - rdmsrl(HV_X64_MSR_HYPERCALL, hypercallMsr.AsUINT64); + rdmsrl(HV_X64_MSR_HYPERCALL, hypercallMsr.as_uint64); /* * Allocate the hypercall page memory @@ -236,16 +236,16 @@ int HvInit(void) goto Cleanup; } - hypercallMsr.Enable = 1; + hypercallMsr.enable = 1; - hypercallMsr.GuestPhysicalAddress = vmalloc_to_pfn(virtAddr); - wrmsrl(HV_X64_MSR_HYPERCALL, hypercallMsr.AsUINT64); + hypercallMsr.guest_physical_address = vmalloc_to_pfn(virtAddr); + wrmsrl(HV_X64_MSR_HYPERCALL, hypercallMsr.as_uint64); /* Confirm that hypercall page did get setup. */ - hypercallMsr.AsUINT64 = 0; - rdmsrl(HV_X64_MSR_HYPERCALL, hypercallMsr.AsUINT64); + hypercallMsr.as_uint64 = 0; + rdmsrl(HV_X64_MSR_HYPERCALL, hypercallMsr.as_uint64); - if (!hypercallMsr.Enable) { + if (!hypercallMsr.enable) { DPRINT_ERR(VMBUS, "unable to set hypercall page!!"); goto Cleanup; } @@ -254,7 +254,7 @@ int HvInit(void) DPRINT_INFO(VMBUS, "Hypercall page VA=%p, PA=0x%0llx", gHvContext.HypercallPage, - (u64)hypercallMsr.GuestPhysicalAddress << PAGE_SHIFT); + (u64)hypercallMsr.guest_physical_address << PAGE_SHIFT); /* Setup the global signal event param for the signal event hypercall */ gHvContext.SignalEventBuffer = @@ -267,19 +267,19 @@ int HvInit(void) (struct hv_input_signal_event *) (ALIGN_UP((unsigned long)gHvContext.SignalEventBuffer, HV_HYPERCALL_PARAM_ALIGN)); - gHvContext.SignalEventParam->ConnectionId.Asu32 = 0; - gHvContext.SignalEventParam->ConnectionId.u.Id = + gHvContext.SignalEventParam->connectionid.asu32 = 0; + gHvContext.SignalEventParam->connectionid.u.id = VMBUS_EVENT_CONNECTION_ID; - gHvContext.SignalEventParam->FlagNumber = 0; - gHvContext.SignalEventParam->RsvdZ = 0; + gHvContext.SignalEventParam->flag_number = 0; + gHvContext.SignalEventParam->rsvdz = 0; return ret; Cleanup: if (virtAddr) { - if (hypercallMsr.Enable) { - hypercallMsr.AsUINT64 = 0; - wrmsrl(HV_X64_MSR_HYPERCALL, hypercallMsr.AsUINT64); + if (hypercallMsr.enable) { + hypercallMsr.as_uint64 = 0; + wrmsrl(HV_X64_MSR_HYPERCALL, hypercallMsr.as_uint64); } vfree(virtAddr); @@ -302,8 +302,8 @@ void HvCleanup(void) gHvContext.SignalEventParam = NULL; if (gHvContext.HypercallPage) { - hypercallMsr.AsUINT64 = 0; - wrmsrl(HV_X64_MSR_HYPERCALL, hypercallMsr.AsUINT64); + hypercallMsr.as_uint64 = 0; + wrmsrl(HV_X64_MSR_HYPERCALL, hypercallMsr.as_uint64); vfree(gHvContext.HypercallPage); gHvContext.HypercallPage = NULL; } @@ -337,12 +337,12 @@ u16 HvPostMessage(union hv_connection_id connectionId, alignedMsg = (struct hv_input_post_message *) (ALIGN_UP(addr, HV_HYPERCALL_PARAM_ALIGN)); - alignedMsg->ConnectionId = connectionId; - alignedMsg->MessageType = messageType; - alignedMsg->PayloadSize = payloadSize; - memcpy((void *)alignedMsg->Payload, payload, payloadSize); + alignedMsg->connectionid = connectionId; + alignedMsg->message_type = messageType; + alignedMsg->payload_size = payloadSize; + memcpy((void *)alignedMsg->payload, payload, payloadSize); - status = HvDoHypercall(HvCallPostMessage, alignedMsg, NULL) & 0xFFFF; + status = HvDoHypercall(HVCALL_POST_MESSAGE, alignedMsg, NULL) & 0xFFFF; kfree((void *)addr); @@ -359,7 +359,7 @@ u16 HvSignalEvent(void) { u16 status; - status = HvDoHypercall(HvCallSignalEvent, gHvContext.SignalEventParam, + status = HvDoHypercall(HVCALL_SIGNAL_EVENT, gHvContext.SignalEventParam, NULL) & 0xFFFF; return status; } @@ -407,47 +407,47 @@ void HvSynicInit(void *irqarg) } /* Setup the Synic's message page */ - rdmsrl(HV_X64_MSR_SIMP, simp.AsUINT64); - simp.SimpEnabled = 1; - simp.BaseSimpGpa = virt_to_phys(gHvContext.synICMessagePage[cpu]) + rdmsrl(HV_X64_MSR_SIMP, simp.as_uint64); + simp.simp_enabled = 1; + simp.base_simp_gpa = virt_to_phys(gHvContext.synICMessagePage[cpu]) >> PAGE_SHIFT; - DPRINT_DBG(VMBUS, "HV_X64_MSR_SIMP msr set to: %llx", simp.AsUINT64); + DPRINT_DBG(VMBUS, "HV_X64_MSR_SIMP msr set to: %llx", simp.as_uint64); - wrmsrl(HV_X64_MSR_SIMP, simp.AsUINT64); + wrmsrl(HV_X64_MSR_SIMP, simp.as_uint64); /* Setup the Synic's event page */ - rdmsrl(HV_X64_MSR_SIEFP, siefp.AsUINT64); - siefp.SiefpEnabled = 1; - siefp.BaseSiefpGpa = virt_to_phys(gHvContext.synICEventPage[cpu]) + rdmsrl(HV_X64_MSR_SIEFP, siefp.as_uint64); + siefp.siefp_enabled = 1; + siefp.base_siefp_gpa = virt_to_phys(gHvContext.synICEventPage[cpu]) >> PAGE_SHIFT; - DPRINT_DBG(VMBUS, "HV_X64_MSR_SIEFP msr set to: %llx", siefp.AsUINT64); + DPRINT_DBG(VMBUS, "HV_X64_MSR_SIEFP msr set to: %llx", siefp.as_uint64); - wrmsrl(HV_X64_MSR_SIEFP, siefp.AsUINT64); + wrmsrl(HV_X64_MSR_SIEFP, siefp.as_uint64); /* Setup the interception SINT. */ /* wrmsrl((HV_X64_MSR_SINT0 + HV_SYNIC_INTERCEPTION_SINT_INDEX), */ - /* interceptionSint.AsUINT64); */ + /* interceptionSint.as_uint64); */ /* Setup the shared SINT. */ - rdmsrl(HV_X64_MSR_SINT0 + VMBUS_MESSAGE_SINT, sharedSint.AsUINT64); + rdmsrl(HV_X64_MSR_SINT0 + VMBUS_MESSAGE_SINT, sharedSint.as_uint64); - sharedSint.AsUINT64 = 0; - sharedSint.Vector = irqVector; /* HV_SHARED_SINT_IDT_VECTOR + 0x20; */ - sharedSint.Masked = false; - sharedSint.AutoEoi = true; + sharedSint.as_uint64 = 0; + sharedSint.vector = irqVector; /* HV_SHARED_SINT_IDT_VECTOR + 0x20; */ + sharedSint.masked = false; + sharedSint.auto_eoi = true; DPRINT_DBG(VMBUS, "HV_X64_MSR_SINT1 msr set to: %llx", - sharedSint.AsUINT64); + sharedSint.as_uint64); - wrmsrl(HV_X64_MSR_SINT0 + VMBUS_MESSAGE_SINT, sharedSint.AsUINT64); + wrmsrl(HV_X64_MSR_SINT0 + VMBUS_MESSAGE_SINT, sharedSint.as_uint64); /* Enable the global synic bit */ - rdmsrl(HV_X64_MSR_SCONTROL, sctrl.AsUINT64); - sctrl.Enable = 1; + rdmsrl(HV_X64_MSR_SCONTROL, sctrl.as_uint64); + sctrl.enable = 1; - wrmsrl(HV_X64_MSR_SCONTROL, sctrl.AsUINT64); + wrmsrl(HV_X64_MSR_SCONTROL, sctrl.as_uint64); gHvContext.SynICInitialized = true; return; @@ -474,25 +474,25 @@ void HvSynicCleanup(void *arg) if (!gHvContext.SynICInitialized) return; - rdmsrl(HV_X64_MSR_SINT0 + VMBUS_MESSAGE_SINT, sharedSint.AsUINT64); + rdmsrl(HV_X64_MSR_SINT0 + VMBUS_MESSAGE_SINT, sharedSint.as_uint64); - sharedSint.Masked = 1; + sharedSint.masked = 1; /* Need to correctly cleanup in the case of SMP!!! */ /* Disable the interrupt */ - wrmsrl(HV_X64_MSR_SINT0 + VMBUS_MESSAGE_SINT, sharedSint.AsUINT64); + wrmsrl(HV_X64_MSR_SINT0 + VMBUS_MESSAGE_SINT, sharedSint.as_uint64); - rdmsrl(HV_X64_MSR_SIMP, simp.AsUINT64); - simp.SimpEnabled = 0; - simp.BaseSimpGpa = 0; + rdmsrl(HV_X64_MSR_SIMP, simp.as_uint64); + simp.simp_enabled = 0; + simp.base_simp_gpa = 0; - wrmsrl(HV_X64_MSR_SIMP, simp.AsUINT64); + wrmsrl(HV_X64_MSR_SIMP, simp.as_uint64); - rdmsrl(HV_X64_MSR_SIEFP, siefp.AsUINT64); - siefp.SiefpEnabled = 0; - siefp.BaseSiefpGpa = 0; + rdmsrl(HV_X64_MSR_SIEFP, siefp.as_uint64); + siefp.siefp_enabled = 0; + siefp.base_siefp_gpa = 0; - wrmsrl(HV_X64_MSR_SIEFP, siefp.AsUINT64); + wrmsrl(HV_X64_MSR_SIEFP, siefp.as_uint64); osd_PageFree(gHvContext.synICMessagePage[cpu], 1); osd_PageFree(gHvContext.synICEventPage[cpu], 1); diff --git a/drivers/staging/hv/hv_api.h b/drivers/staging/hv/hv_api.h index 9eb818ee07ba..9df64724549a 100644 --- a/drivers/staging/hv/hv_api.h +++ b/drivers/staging/hv/hv_api.h @@ -510,21 +510,21 @@ /* * The below CPUID leaves are present if VersionAndFeatures.HypervisorPresent - * is set by CPUID(HvCpuIdFunctionVersionAndFeatures). + * is set by CPUID(HVCPUID_VERSION_FEATURES). */ enum hv_cpuid_function { - HvCpuIdFunctionVersionAndFeatures = 0x00000001, - HvCpuIdFunctionHvVendorAndMaxFunction = 0x40000000, - HvCpuIdFunctionHvInterface = 0x40000001, + HVCPUID_VERSION_FEATURES = 0x00000001, + HVCPUID_VENDOR_MAXFUNCTION = 0x40000000, + HVCPUID_INTERFACE = 0x40000001, /* * The remaining functions depend on the value of - * HvCpuIdFunctionInterface + * HVCPUID_INTERFACE */ - HvCpuIdFunctionMsHvVersion = 0x40000002, - HvCpuIdFunctionMsHvFeatures = 0x40000003, - HvCpuIdFunctionMsHvEnlightenmentInformation = 0x40000004, - HvCpuIdFunctionMsHvImplementationLimits = 0x40000005, + HVCPUID_VERSION = 0x40000002, + HVCPUID_FEATURES = 0x40000003, + HVCPUID_ENLIGHTENMENT_INFO = 0x40000004, + HVCPUID_IMPLEMENTATION_LIMITS = 0x40000005, }; /* Define the virtual APIC registers */ @@ -575,30 +575,30 @@ enum hv_cpuid_function { /* Define hypervisor message types. */ enum hv_message_type { - HvMessageTypeNone = 0x00000000, + HVMSG_NONE = 0x00000000, /* Memory access messages. */ - HvMessageTypeUnmappedGpa = 0x80000000, - HvMessageTypeGpaIntercept = 0x80000001, + HVMSG_UNMAPPED_GPA = 0x80000000, + HVMSG_GPA_INTERCEPT = 0x80000001, /* Timer notification messages. */ - HvMessageTimerExpired = 0x80000010, + HVMSG_TIMER_EXPIRED = 0x80000010, /* Error messages. */ - HvMessageTypeInvalidVpRegisterValue = 0x80000020, - HvMessageTypeUnrecoverableException = 0x80000021, - HvMessageTypeUnsupportedFeature = 0x80000022, + HVMSG_INVALID_VP_REGISTER_VALUE = 0x80000020, + HVMSG_UNRECOVERABLE_EXCEPTION = 0x80000021, + HVMSG_UNSUPPORTED_FEATURE = 0x80000022, /* Trace buffer complete messages. */ - HvMessageTypeEventLogBufferComplete = 0x80000040, + HVMSG_EVENTLOG_BUFFERCOMPLETE = 0x80000040, /* Platform-specific processor intercept messages. */ - HvMessageTypeX64IoPortIntercept = 0x80010000, - HvMessageTypeX64MsrIntercept = 0x80010001, - HvMessageTypeX64CpuidIntercept = 0x80010002, - HvMessageTypeX64ExceptionIntercept = 0x80010003, - HvMessageTypeX64ApicEoi = 0x80010004, - HvMessageTypeX64LegacyFpError = 0x80010005 + HVMSG_X64_IOPORT_INTERCEPT = 0x80010000, + HVMSG_X64_MSR_INTERCEPT = 0x80010001, + HVMSG_X64_CPUID_INTERCEPT = 0x80010002, + HVMSG_X64_EXCEPTION_INTERCEPT = 0x80010003, + HVMSG_X64_APIC_EOI = 0x80010004, + HVMSG_X64_LEGACY_FP_ERROR = 0x80010005 }; /* Define the number of synthetic interrupt sources. */ @@ -610,103 +610,103 @@ enum hv_message_type { /* Define connection identifier type. */ union hv_connection_id { - u32 Asu32; + u32 asu32; struct { - u32 Id:24; - u32 Reserved:8; + u32 id:24; + u32 reserved:8; } u; }; /* Define port identifier type. */ union hv_port_id { - u32 Asu32; + u32 asu32; struct { - u32 Id:24; - u32 Reserved:8; + u32 id:24; + u32 reserved:8; } u ; }; /* Define port type. */ enum hv_port_type { - HvPortTypeMessage = 1, - HvPortTypeEvent = 2, - HvPortTypeMonitor = 3 + HVPORT_MSG = 1, + HVPORT_EVENT = 2, + HVPORT_MONITOR = 3 }; /* Define port information structure. */ struct hv_port_info { - enum hv_port_type PortType; - u32 Padding; + enum hv_port_type port_type; + u32 padding; union { struct { - u32 TargetSint; - u32 TargetVp; - u64 RsvdZ; - } MessagePortInfo; + u32 target_sint; + u32 target_vp; + u64 rsvdz; + } message_port_info; struct { - u32 TargetSint; - u32 TargetVp; - u16 BaseFlagNumber; - u16 FlagCount; - u32 RsvdZ; - } EventPortInfo; + u32 target_sint; + u32 target_vp; + u16 base_flag_bumber; + u16 flag_count; + u32 rsvdz; + } event_port_info; struct { - u64 MonitorAddress; - u64 RsvdZ; - } MonitorPortInfo; + u64 monitor_address; + u64 rsvdz; + } monitor_port_info; }; }; struct hv_connection_info { - enum hv_port_type PortType; - u32 Padding; + enum hv_port_type port_type; + u32 padding; union { struct { - u64 RsvdZ; - } MessageConnectionInfo; + u64 rsvdz; + } message_connection_info; struct { - u64 RsvdZ; - } EventConnectionInfo; + u64 rsvdz; + } event_connection_info; struct { - u64 MonitorAddress; - } MonitorConnectionInfo; + u64 monitor_address; + } monitor_connection_info; }; }; /* Define synthetic interrupt controller message flags. */ union hv_message_flags { - u8 Asu8; + u8 asu8; struct { - u8 MessagePending:1; - u8 Reserved:7; + u8 msg_pending:1; + u8 reserved:7; }; }; /* Define synthetic interrupt controller message header. */ struct hv_message_header { - enum hv_message_type MessageType; - u8 PayloadSize; - union hv_message_flags MessageFlags; - u8 Reserved[2]; + enum hv_message_type message_type; + u8 payload_size; + union hv_message_flags message_flags; + u8 reserved[2]; union { - u64 Sender; - union hv_port_id Port; + u64 sender; + union hv_port_id port; }; }; /* Define timer message payload structure. */ struct hv_timer_message_payload { - u32 TimerIndex; - u32 Reserved; - u64 ExpirationTime; /* When the timer expired */ - u64 DeliveryTime; /* When the message was delivered */ + u32 timer_index; + u32 reserved; + u64 expiration_time; /* When the timer expired */ + u64 delivery_time; /* When the message was delivered */ }; /* Define synthetic interrupt controller message format. */ struct hv_message { - struct hv_message_header Header; + struct hv_message_header header; union { - u64 Payload[HV_MESSAGE_PAYLOAD_QWORD_COUNT]; + u64 payload[HV_MESSAGE_PAYLOAD_QWORD_COUNT]; } u ; }; @@ -715,82 +715,82 @@ struct hv_message { /* Define the synthetic interrupt message page layout. */ struct hv_message_page { - struct hv_message SintMessage[HV_SYNIC_SINT_COUNT]; + struct hv_message sint_message[HV_SYNIC_SINT_COUNT]; }; /* Define the synthetic interrupt controller event flags format. */ union hv_synic_event_flags { - u8 Flags8[HV_EVENT_FLAGS_BYTE_COUNT]; - u32 Flags32[HV_EVENT_FLAGS_DWORD_COUNT]; + u8 flags8[HV_EVENT_FLAGS_BYTE_COUNT]; + u32 flags32[HV_EVENT_FLAGS_DWORD_COUNT]; }; /* Define the synthetic interrupt flags page layout. */ struct hv_synic_event_flags_page { - union hv_synic_event_flags SintEventFlags[HV_SYNIC_SINT_COUNT]; + union hv_synic_event_flags sintevent_flags[HV_SYNIC_SINT_COUNT]; }; /* Define SynIC control register. */ union hv_synic_scontrol { - u64 AsUINT64; + u64 as_uint64; struct { - u64 Enable:1; - u64 Reserved:63; + u64 enable:1; + u64 reserved:63; }; }; /* Define synthetic interrupt source. */ union hv_synic_sint { - u64 AsUINT64; + u64 as_uint64; struct { - u64 Vector:8; - u64 Reserved1:8; - u64 Masked:1; - u64 AutoEoi:1; - u64 Reserved2:46; + u64 vector:8; + u64 reserved1:8; + u64 masked:1; + u64 auto_eoi:1; + u64 reserved2:46; }; }; /* Define the format of the SIMP register */ union hv_synic_simp { - u64 AsUINT64; + u64 as_uint64; struct { - u64 SimpEnabled:1; - u64 Preserved:11; - u64 BaseSimpGpa:52; + u64 simp_enabled:1; + u64 preserved:11; + u64 base_simp_gpa:52; }; }; /* Define the format of the SIEFP register */ union hv_synic_siefp { - u64 AsUINT64; + u64 as_uint64; struct { - u64 SiefpEnabled:1; - u64 Preserved:11; - u64 BaseSiefpGpa:52; + u64 siefp_enabled:1; + u64 preserved:11; + u64 base_siefp_gpa:52; }; }; /* Definitions for the monitored notification facility */ union hv_monitor_trigger_group { - u64 AsUINT64; + u64 as_uint64; struct { - u32 Pending; - u32 Armed; + u32 pending; + u32 armed; }; }; struct hv_monitor_parameter { - union hv_connection_id ConnectionId; - u16 FlagNumber; - u16 RsvdZ; + union hv_connection_id connectionid; + u16 flagnumber; + u16 rsvdz; }; union hv_monitor_trigger_state { - u32 Asu32; + u32 asu32; struct { - u32 GroupEnable:4; - u32 RsvdZ:28; + u32 group_enable:4; + u32 rsvdz:28; }; }; @@ -814,42 +814,42 @@ union hv_monitor_trigger_state { /* | 840 | Rsvd4[0] | */ /* ------------------------------------------------------ */ struct hv_monitor_page { - union hv_monitor_trigger_state TriggerState; - u32 RsvdZ1; + union hv_monitor_trigger_state trigger_state; + u32 rsvdz1; - union hv_monitor_trigger_group TriggerGroup[4]; - u64 RsvdZ2[3]; + union hv_monitor_trigger_group trigger_group[4]; + u64 rsvdz2[3]; - s32 NextCheckTime[4][32]; + s32 next_checktime[4][32]; - u16 Latency[4][32]; - u64 RsvdZ3[32]; + u16 latency[4][32]; + u64 rsvdz3[32]; - struct hv_monitor_parameter Parameter[4][32]; + struct hv_monitor_parameter parameter[4][32]; - u8 RsvdZ4[1984]; + u8 rsvdz4[1984]; }; /* Declare the various hypercall operations. */ enum hv_call_code { - HvCallPostMessage = 0x005c, - HvCallSignalEvent = 0x005d, + HVCALL_POST_MESSAGE = 0x005c, + HVCALL_SIGNAL_EVENT = 0x005d, }; /* Definition of the HvPostMessage hypercall input structure. */ struct hv_input_post_message { - union hv_connection_id ConnectionId; - u32 Reserved; - enum hv_message_type MessageType; - u32 PayloadSize; - u64 Payload[HV_MESSAGE_PAYLOAD_QWORD_COUNT]; + union hv_connection_id connectionid; + u32 reserved; + enum hv_message_type message_type; + u32 payload_size; + u64 payload[HV_MESSAGE_PAYLOAD_QWORD_COUNT]; }; /* Definition of the HvSignalEvent hypercall input structure. */ struct hv_input_signal_event { - union hv_connection_id ConnectionId; - u16 FlagNumber; - u16 RsvdZ; + union hv_connection_id connectionid; + u16 flag_number; + u16 rsvdz; }; /* @@ -859,16 +859,16 @@ struct hv_input_signal_event { /* Version info reported by guest OS's */ enum hv_guest_os_vendor { - HvGuestOsVendorMicrosoft = 0x0001 + HVGUESTOS_VENDOR_MICROSOFT = 0x0001 }; enum hv_guest_os_microsoft_ids { - HvGuestOsMicrosoftUndefined = 0x00, - HvGuestOsMicrosoftMSDOS = 0x01, - HvGuestOsMicrosoftWindows3x = 0x02, - HvGuestOsMicrosoftWindows9x = 0x03, - HvGuestOsMicrosoftWindowsNT = 0x04, - HvGuestOsMicrosoftWindowsCE = 0x05 + HVGUESTOS_MICROSOFT_UNDEFINED = 0x00, + HVGUESTOS_MICROSOFT_MSDOS = 0x01, + HVGUESTOS_MICROSOFT_WINDOWS3X = 0x02, + HVGUESTOS_MICROSOFT_WINDOWS9X = 0x03, + HVGUESTOS_MICROSOFT_WINDOWSNT = 0x04, + HVGUESTOS_MICROSOFT_WINDOWSCE = 0x05 }; /* @@ -877,14 +877,14 @@ enum hv_guest_os_microsoft_ids { #define HV_X64_MSR_GUEST_OS_ID 0x40000000 union hv_x64_msr_guest_os_id_contents { - u64 AsUINT64; + u64 as_uint64; struct { - u64 BuildNumber:16; - u64 ServiceVersion:8; /* Service Pack, etc. */ - u64 MinorVersion:8; - u64 MajorVersion:8; - u64 OsId:8; /* enum hv_guest_os_microsoft_ids (if Vendor=MS) */ - u64 VendorId:16; /* enum hv_guest_os_vendor */ + u64 build_number:16; + u64 service_version:8; /* Service Pack, etc. */ + u64 minor_version:8; + u64 major_version:8; + u64 os_id:8; /* enum hv_guest_os_microsoft_ids (if Vendor=MS) */ + u64 vendor_id:16; /* enum hv_guest_os_vendor */ }; }; @@ -894,11 +894,11 @@ union hv_x64_msr_guest_os_id_contents { #define HV_X64_MSR_HYPERCALL 0x40000001 union hv_x64_msr_hypercall_contents { - u64 AsUINT64; + u64 as_uint64; struct { - u64 Enable:1; - u64 Reserved:11; - u64 GuestPhysicalAddress:52; + u64 enable:1; + u64 reserved:11; + u64 guest_physical_address:52; }; }; diff --git a/drivers/staging/hv/vmbus.c b/drivers/staging/hv/vmbus.c index d449daf81976..7c54ca9a187b 100644 --- a/drivers/staging/hv/vmbus.c +++ b/drivers/staging/hv/vmbus.c @@ -153,7 +153,7 @@ static void VmbusOnMsgDPC(struct hv_driver *drv) struct hv_message *copied; while (1) { - if (msg->Header.MessageType == HvMessageTypeNone) { + if (msg->header.message_type == HVMSG_NONE) { /* no msg */ break; } else { @@ -166,18 +166,18 @@ static void VmbusOnMsgDPC(struct hv_driver *drv) (void *)copied); } - msg->Header.MessageType = HvMessageTypeNone; + msg->header.message_type = HVMSG_NONE; /* * Make sure the write to MessageType (ie set to - * HvMessageTypeNone) happens before we read the + * HVMSG_NONE) happens before we read the * MessagePending and EOMing. Otherwise, the EOMing * will not deliver any more messages since there is * no empty slot */ mb(); - if (msg->Header.MessageFlags.MessagePending) { + if (msg->header.message_flags.msg_pending) { /* * This will cause message queue rescan to * possibly deliver another msg from the @@ -212,10 +212,10 @@ static int VmbusOnISR(struct hv_driver *drv) msg = (struct hv_message *)page_addr + VMBUS_MESSAGE_SINT; /* Check if there are actual msgs to be process */ - if (msg->Header.MessageType != HvMessageTypeNone) { + if (msg->header.message_type != HVMSG_NONE) { DPRINT_DBG(VMBUS, "received msg type %d size %d", - msg->Header.MessageType, - msg->Header.PayloadSize); + msg->header.message_type, + msg->header.payload_size); ret |= 0x1; } @@ -224,8 +224,8 @@ static int VmbusOnISR(struct hv_driver *drv) event = (union hv_synic_event_flags *)page_addr + VMBUS_MESSAGE_SINT; /* Since we are a child, we only need to check bit 0 */ - if (test_and_clear_bit(0, (unsigned long *) &event->Flags32[0])) { - DPRINT_DBG(VMBUS, "received event %d", event->Flags32[0]); + if (test_and_clear_bit(0, (unsigned long *) &event->flags32[0])) { + DPRINT_DBG(VMBUS, "received event %d", event->flags32[0]); ret |= 0x2; } -- cgit v1.2.3 From 6a0aaa185057801343e000183ef0695c2a2b75a9 Mon Sep 17 00:00:00 2001 From: Haiyang Zhang Date: Mon, 8 Nov 2010 14:04:40 -0800 Subject: staging: hv: Convert camel cased struct fields in hv.h to lower cases staging: hv: Convert camel cased struct fields in hv.h to lower cases Signed-off-by: Haiyang Zhang Signed-off-by: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/hv.c | 95 ++++++++++++++++++++++++---------------------- drivers/staging/hv/hv.h | 20 +++++----- drivers/staging/hv/vmbus.c | 6 +-- 3 files changed, 63 insertions(+), 58 deletions(-) diff --git a/drivers/staging/hv/hv.c b/drivers/staging/hv/hv.c index ab033277226b..d0e8c85afb8a 100644 --- a/drivers/staging/hv/hv.c +++ b/drivers/staging/hv/hv.c @@ -28,11 +28,11 @@ #include "vmbus_private.h" /* The one and only */ -struct hv_context gHvContext = { - .SynICInitialized = false, - .HypercallPage = NULL, - .SignalEventParam = NULL, - .SignalEventBuffer = NULL, +struct hv_context hv_context = { + .synic_initialized = false, + .hypercall_page = NULL, + .signal_event_param = NULL, + .signal_event_buffer = NULL, }; /* @@ -134,7 +134,7 @@ static u64 HvDoHypercall(u64 Control, void *Input, void *Output) u64 hvStatus = 0; u64 inputAddress = (Input) ? virt_to_phys(Input) : 0; u64 outputAddress = (Output) ? virt_to_phys(Output) : 0; - volatile void *hypercallPage = gHvContext.HypercallPage; + volatile void *hypercallPage = hv_context.hypercall_page; DPRINT_DBG(VMBUS, "Hypercall ", @@ -162,7 +162,7 @@ static u64 HvDoHypercall(u64 Control, void *Input, void *Output) u64 outputAddress = (Output) ? virt_to_phys(Output) : 0; u32 outputAddressHi = outputAddress >> 32; u32 outputAddressLo = outputAddress & 0xFFFFFFFF; - volatile void *hypercallPage = gHvContext.HypercallPage; + volatile void *hypercallPage = hv_context.hypercall_page; DPRINT_DBG(VMBUS, "Hypercall ", Control, Input, Output); @@ -192,8 +192,9 @@ int HvInit(void) union hv_x64_msr_hypercall_contents hypercallMsr; void *virtAddr = NULL; - memset(gHvContext.synICEventPage, 0, sizeof(void *) * MAX_NUM_CPUS); - memset(gHvContext.synICMessagePage, 0, sizeof(void *) * MAX_NUM_CPUS); + memset(hv_context.synic_event_page, 0, sizeof(void *) * MAX_NUM_CPUS); + memset(hv_context.synic_message_page, 0, + sizeof(void *) * MAX_NUM_CPUS); if (!HvQueryHypervisorPresence()) { DPRINT_ERR(VMBUS, "No Windows hypervisor detected!!"); @@ -209,17 +210,17 @@ int HvInit(void) /* * We only support running on top of Hyper-V */ - rdmsrl(HV_X64_MSR_GUEST_OS_ID, gHvContext.GuestId); + rdmsrl(HV_X64_MSR_GUEST_OS_ID, hv_context.guestid); - if (gHvContext.GuestId != 0) { + if (hv_context.guestid != 0) { DPRINT_ERR(VMBUS, "Unknown guest id (0x%llx)!!", - gHvContext.GuestId); + hv_context.guestid); goto Cleanup; } /* Write our OS info */ wrmsrl(HV_X64_MSR_GUEST_OS_ID, HV_LINUX_GUEST_ID); - gHvContext.GuestId = HV_LINUX_GUEST_ID; + hv_context.guestid = HV_LINUX_GUEST_ID; /* See if the hypercall page is already set */ rdmsrl(HV_X64_MSR_HYPERCALL, hypercallMsr.as_uint64); @@ -250,28 +251,29 @@ int HvInit(void) goto Cleanup; } - gHvContext.HypercallPage = virtAddr; + hv_context.hypercall_page = virtAddr; DPRINT_INFO(VMBUS, "Hypercall page VA=%p, PA=0x%0llx", - gHvContext.HypercallPage, + hv_context.hypercall_page, (u64)hypercallMsr.guest_physical_address << PAGE_SHIFT); /* Setup the global signal event param for the signal event hypercall */ - gHvContext.SignalEventBuffer = + hv_context.signal_event_buffer = kmalloc(sizeof(struct hv_input_signal_event_buffer), GFP_KERNEL); - if (!gHvContext.SignalEventBuffer) + if (!hv_context.signal_event_buffer) goto Cleanup; - gHvContext.SignalEventParam = + hv_context.signal_event_param = (struct hv_input_signal_event *) - (ALIGN_UP((unsigned long)gHvContext.SignalEventBuffer, + (ALIGN_UP((unsigned long) + hv_context.signal_event_buffer, HV_HYPERCALL_PARAM_ALIGN)); - gHvContext.SignalEventParam->connectionid.asu32 = 0; - gHvContext.SignalEventParam->connectionid.u.id = + hv_context.signal_event_param->connectionid.asu32 = 0; + hv_context.signal_event_param->connectionid.u.id = VMBUS_EVENT_CONNECTION_ID; - gHvContext.SignalEventParam->flag_number = 0; - gHvContext.SignalEventParam->rsvdz = 0; + hv_context.signal_event_param->flag_number = 0; + hv_context.signal_event_param->rsvdz = 0; return ret; @@ -297,15 +299,15 @@ void HvCleanup(void) { union hv_x64_msr_hypercall_contents hypercallMsr; - kfree(gHvContext.SignalEventBuffer); - gHvContext.SignalEventBuffer = NULL; - gHvContext.SignalEventParam = NULL; + kfree(hv_context.signal_event_buffer); + hv_context.signal_event_buffer = NULL; + hv_context.signal_event_param = NULL; - if (gHvContext.HypercallPage) { + if (hv_context.hypercall_page) { hypercallMsr.as_uint64 = 0; wrmsrl(HV_X64_MSR_HYPERCALL, hypercallMsr.as_uint64); - vfree(gHvContext.HypercallPage); - gHvContext.HypercallPage = NULL; + vfree(hv_context.hypercall_page); + hv_context.hypercall_page = NULL; } } @@ -359,7 +361,8 @@ u16 HvSignalEvent(void) { u16 status; - status = HvDoHypercall(HVCALL_SIGNAL_EVENT, gHvContext.SignalEventParam, + status = HvDoHypercall(HVCALL_SIGNAL_EVENT, + hv_context.signal_event_param, NULL) & 0xFFFF; return status; } @@ -382,7 +385,7 @@ void HvSynicInit(void *irqarg) u32 irqVector = *((u32 *)(irqarg)); int cpu = smp_processor_id(); - if (!gHvContext.HypercallPage) + if (!hv_context.hypercall_page) return; /* Check the version */ @@ -390,17 +393,19 @@ void HvSynicInit(void *irqarg) DPRINT_INFO(VMBUS, "SynIC version: %llx", version); - gHvContext.synICMessagePage[cpu] = (void *)get_zeroed_page(GFP_ATOMIC); + hv_context.synic_message_page[cpu] = + (void *)get_zeroed_page(GFP_ATOMIC); - if (gHvContext.synICMessagePage[cpu] == NULL) { + if (hv_context.synic_message_page[cpu] == NULL) { DPRINT_ERR(VMBUS, "unable to allocate SYNIC message page!!"); goto Cleanup; } - gHvContext.synICEventPage[cpu] = (void *)get_zeroed_page(GFP_ATOMIC); + hv_context.synic_event_page[cpu] = + (void *)get_zeroed_page(GFP_ATOMIC); - if (gHvContext.synICEventPage[cpu] == NULL) { + if (hv_context.synic_event_page[cpu] == NULL) { DPRINT_ERR(VMBUS, "unable to allocate SYNIC event page!!"); goto Cleanup; @@ -409,7 +414,7 @@ void HvSynicInit(void *irqarg) /* Setup the Synic's message page */ rdmsrl(HV_X64_MSR_SIMP, simp.as_uint64); simp.simp_enabled = 1; - simp.base_simp_gpa = virt_to_phys(gHvContext.synICMessagePage[cpu]) + simp.base_simp_gpa = virt_to_phys(hv_context.synic_message_page[cpu]) >> PAGE_SHIFT; DPRINT_DBG(VMBUS, "HV_X64_MSR_SIMP msr set to: %llx", simp.as_uint64); @@ -419,7 +424,7 @@ void HvSynicInit(void *irqarg) /* Setup the Synic's event page */ rdmsrl(HV_X64_MSR_SIEFP, siefp.as_uint64); siefp.siefp_enabled = 1; - siefp.base_siefp_gpa = virt_to_phys(gHvContext.synICEventPage[cpu]) + siefp.base_siefp_gpa = virt_to_phys(hv_context.synic_event_page[cpu]) >> PAGE_SHIFT; DPRINT_DBG(VMBUS, "HV_X64_MSR_SIEFP msr set to: %llx", siefp.as_uint64); @@ -449,15 +454,15 @@ void HvSynicInit(void *irqarg) wrmsrl(HV_X64_MSR_SCONTROL, sctrl.as_uint64); - gHvContext.SynICInitialized = true; + hv_context.synic_initialized = true; return; Cleanup: - if (gHvContext.synICEventPage[cpu]) - osd_PageFree(gHvContext.synICEventPage[cpu], 1); + if (hv_context.synic_event_page[cpu]) + osd_PageFree(hv_context.synic_event_page[cpu], 1); - if (gHvContext.synICMessagePage[cpu]) - osd_PageFree(gHvContext.synICMessagePage[cpu], 1); + if (hv_context.synic_message_page[cpu]) + osd_PageFree(hv_context.synic_message_page[cpu], 1); return; } @@ -471,7 +476,7 @@ void HvSynicCleanup(void *arg) union hv_synic_siefp siefp; int cpu = smp_processor_id(); - if (!gHvContext.SynICInitialized) + if (!hv_context.synic_initialized) return; rdmsrl(HV_X64_MSR_SINT0 + VMBUS_MESSAGE_SINT, sharedSint.as_uint64); @@ -494,6 +499,6 @@ void HvSynicCleanup(void *arg) wrmsrl(HV_X64_MSR_SIEFP, siefp.as_uint64); - osd_PageFree(gHvContext.synICMessagePage[cpu], 1); - osd_PageFree(gHvContext.synICEventPage[cpu], 1); + osd_PageFree(hv_context.synic_message_page[cpu], 1); + osd_PageFree(hv_context.synic_event_page[cpu], 1); } diff --git a/drivers/staging/hv/hv.h b/drivers/staging/hv/hv.h index 41f5ebb86e17..6e396fca1942 100644 --- a/drivers/staging/hv/hv.h +++ b/drivers/staging/hv/hv.h @@ -92,33 +92,33 @@ static const struct hv_guid VMBUS_SERVICE_ID = { struct hv_input_signal_event_buffer { - u64 Align8; - struct hv_input_signal_event Event; + u64 align8; + struct hv_input_signal_event event; }; struct hv_context { /* We only support running on top of Hyper-V * So at this point this really can only contain the Hyper-V ID */ - u64 GuestId; + u64 guestid; - void *HypercallPage; + void *hypercall_page; - bool SynICInitialized; + bool synic_initialized; /* * This is used as an input param to HvCallSignalEvent hypercall. The * input param is immutable in our usage and must be dynamic mem (vs * stack or global). */ - struct hv_input_signal_event_buffer *SignalEventBuffer; + struct hv_input_signal_event_buffer *signal_event_buffer; /* 8-bytes aligned of the buffer above */ - struct hv_input_signal_event *SignalEventParam; + struct hv_input_signal_event *signal_event_param; - void *synICMessagePage[MAX_NUM_CPUS]; - void *synICEventPage[MAX_NUM_CPUS]; + void *synic_message_page[MAX_NUM_CPUS]; + void *synic_event_page[MAX_NUM_CPUS]; }; -extern struct hv_context gHvContext; +extern struct hv_context hv_context; /* Hv Interface */ diff --git a/drivers/staging/hv/vmbus.c b/drivers/staging/hv/vmbus.c index 7c54ca9a187b..b1ec8762f228 100644 --- a/drivers/staging/hv/vmbus.c +++ b/drivers/staging/hv/vmbus.c @@ -147,7 +147,7 @@ static void VmbusOnCleanup(struct hv_driver *drv) static void VmbusOnMsgDPC(struct hv_driver *drv) { int cpu = smp_processor_id(); - void *page_addr = gHvContext.synICMessagePage[cpu]; + void *page_addr = hv_context.synic_message_page[cpu]; struct hv_message *msg = (struct hv_message *)page_addr + VMBUS_MESSAGE_SINT; struct hv_message *copied; @@ -208,7 +208,7 @@ static int VmbusOnISR(struct hv_driver *drv) struct hv_message *msg; union hv_synic_event_flags *event; - page_addr = gHvContext.synICMessagePage[cpu]; + page_addr = hv_context.synic_message_page[cpu]; msg = (struct hv_message *)page_addr + VMBUS_MESSAGE_SINT; /* Check if there are actual msgs to be process */ @@ -220,7 +220,7 @@ static int VmbusOnISR(struct hv_driver *drv) } /* TODO: Check if there are events to be process */ - page_addr = gHvContext.synICEventPage[cpu]; + page_addr = hv_context.synic_event_page[cpu]; event = (union hv_synic_event_flags *)page_addr + VMBUS_MESSAGE_SINT; /* Since we are a child, we only need to check bit 0 */ -- cgit v1.2.3 From b8dfb264f4f9e55f9cf8384cb782dfe5159c413c Mon Sep 17 00:00:00 2001 From: Haiyang Zhang Date: Mon, 8 Nov 2010 14:04:41 -0800 Subject: staging: hv: Convert camel cased local variables in hv.c to lower cases staging: hv: Convert camel cased local variables in hv.c to lower cases Signed-off-by: Haiyang Zhang Signed-off-by: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/hv.c | 172 ++++++++++++++++++++++++------------------------ 1 file changed, 86 insertions(+), 86 deletions(-) diff --git a/drivers/staging/hv/hv.c b/drivers/staging/hv/hv.c index d0e8c85afb8a..2fd234d711ea 100644 --- a/drivers/staging/hv/hv.c +++ b/drivers/staging/hv/hv.c @@ -65,7 +65,7 @@ static int HvQueryHypervisorInfo(void) unsigned int ebx; unsigned int ecx; unsigned int edx; - unsigned int maxLeaf; + unsigned int max_leaf; unsigned int op; /* @@ -93,7 +93,7 @@ static int HvQueryHypervisorInfo(void) ((edx >> 16) & 0xFF), ((edx >> 24) & 0xFF)); - maxLeaf = eax; + max_leaf = eax; eax = 0; ebx = 0; ecx = 0; @@ -107,7 +107,7 @@ static int HvQueryHypervisorInfo(void) ((eax >> 16) & 0xFF), ((eax >> 24) & 0xFF)); - if (maxLeaf >= HVCPUID_VERSION) { + if (max_leaf >= HVCPUID_VERSION) { eax = 0; ebx = 0; ecx = 0; @@ -122,61 +122,61 @@ static int HvQueryHypervisorInfo(void) edx >> 24, edx & 0xFFFFFF); } - return maxLeaf; + return max_leaf; } /* * HvDoHypercall - Invoke the specified hypercall */ -static u64 HvDoHypercall(u64 Control, void *Input, void *Output) +static u64 HvDoHypercall(u64 control, void *input, void *output) { #ifdef CONFIG_X86_64 - u64 hvStatus = 0; - u64 inputAddress = (Input) ? virt_to_phys(Input) : 0; - u64 outputAddress = (Output) ? virt_to_phys(Output) : 0; - volatile void *hypercallPage = hv_context.hypercall_page; + u64 hv_status = 0; + u64 input_address = (input) ? virt_to_phys(input) : 0; + u64 output_address = (output) ? virt_to_phys(output) : 0; + volatile void *hypercall_page = hv_context.hypercall_page; DPRINT_DBG(VMBUS, "Hypercall ", - Control, inputAddress, Input, - outputAddress, Output, hypercallPage); + control, input_address, input, + output_address, output, hypercall_page); - __asm__ __volatile__("mov %0, %%r8" : : "r" (outputAddress) : "r8"); - __asm__ __volatile__("call *%3" : "=a" (hvStatus) : - "c" (Control), "d" (inputAddress), - "m" (hypercallPage)); + __asm__ __volatile__("mov %0, %%r8" : : "r" (output_address) : "r8"); + __asm__ __volatile__("call *%3" : "=a" (hv_status) : + "c" (control), "d" (input_address), + "m" (hypercall_page)); - DPRINT_DBG(VMBUS, "Hypercall ", hvStatus); + DPRINT_DBG(VMBUS, "Hypercall ", hv_status); - return hvStatus; + return hv_status; #else - u32 controlHi = Control >> 32; - u32 controlLo = Control & 0xFFFFFFFF; - u32 hvStatusHi = 1; - u32 hvStatusLo = 1; - u64 inputAddress = (Input) ? virt_to_phys(Input) : 0; - u32 inputAddressHi = inputAddress >> 32; - u32 inputAddressLo = inputAddress & 0xFFFFFFFF; - u64 outputAddress = (Output) ? virt_to_phys(Output) : 0; - u32 outputAddressHi = outputAddress >> 32; - u32 outputAddressLo = outputAddress & 0xFFFFFFFF; - volatile void *hypercallPage = hv_context.hypercall_page; + u32 control_hi = control >> 32; + u32 control_lo = control & 0xFFFFFFFF; + u32 hv_status_hi = 1; + u32 hv_status_lo = 1; + u64 input_address = (input) ? virt_to_phys(input) : 0; + u32 input_address_hi = input_address >> 32; + u32 input_address_lo = input_address & 0xFFFFFFFF; + u64 output_address = (output) ? virt_to_phys(output) : 0; + u32 output_address_hi = output_address >> 32; + u32 output_address_lo = output_address & 0xFFFFFFFF; + volatile void *hypercall_page = hv_context.hypercall_page; DPRINT_DBG(VMBUS, "Hypercall ", - Control, Input, Output); + control, input, output); - __asm__ __volatile__ ("call *%8" : "=d"(hvStatusHi), - "=a"(hvStatusLo) : "d" (controlHi), - "a" (controlLo), "b" (inputAddressHi), - "c" (inputAddressLo), "D"(outputAddressHi), - "S"(outputAddressLo), "m" (hypercallPage)); + __asm__ __volatile__ ("call *%8" : "=d"(hv_status_hi), + "=a"(hv_status_lo) : "d" (control_hi), + "a" (control_lo), "b" (input_address_hi), + "c" (input_address_lo), "D"(output_address_hi), + "S"(output_address_lo), "m" (hypercall_page)); DPRINT_DBG(VMBUS, "Hypercall ", - hvStatusLo | ((u64)hvStatusHi << 32)); + hv_status_lo | ((u64)hv_status_hi << 32)); - return hvStatusLo | ((u64)hvStatusHi << 32); + return hv_status_lo | ((u64)hv_status_hi << 32); #endif /* !x86_64 */ } @@ -188,9 +188,9 @@ static u64 HvDoHypercall(u64 Control, void *Input, void *Output) int HvInit(void) { int ret = 0; - int maxLeaf; - union hv_x64_msr_hypercall_contents hypercallMsr; - void *virtAddr = NULL; + int max_leaf; + union hv_x64_msr_hypercall_contents hypercall_msr; + void *virtaddr = NULL; memset(hv_context.synic_event_page, 0, sizeof(void *) * MAX_NUM_CPUS); memset(hv_context.synic_message_page, 0, @@ -204,7 +204,7 @@ int HvInit(void) DPRINT_INFO(VMBUS, "Windows hypervisor detected! Retrieving more info..."); - maxLeaf = HvQueryHypervisorInfo(); + max_leaf = HvQueryHypervisorInfo(); /* HvQueryHypervisorFeatures(maxLeaf); */ /* @@ -223,39 +223,39 @@ int HvInit(void) hv_context.guestid = HV_LINUX_GUEST_ID; /* See if the hypercall page is already set */ - rdmsrl(HV_X64_MSR_HYPERCALL, hypercallMsr.as_uint64); + rdmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64); /* * Allocate the hypercall page memory - * virtAddr = osd_PageAlloc(1); + * virtaddr = osd_PageAlloc(1); */ - virtAddr = osd_VirtualAllocExec(PAGE_SIZE); + virtaddr = osd_VirtualAllocExec(PAGE_SIZE); - if (!virtAddr) { + if (!virtaddr) { DPRINT_ERR(VMBUS, "unable to allocate hypercall page!!"); goto Cleanup; } - hypercallMsr.enable = 1; + hypercall_msr.enable = 1; - hypercallMsr.guest_physical_address = vmalloc_to_pfn(virtAddr); - wrmsrl(HV_X64_MSR_HYPERCALL, hypercallMsr.as_uint64); + hypercall_msr.guest_physical_address = vmalloc_to_pfn(virtaddr); + wrmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64); /* Confirm that hypercall page did get setup. */ - hypercallMsr.as_uint64 = 0; - rdmsrl(HV_X64_MSR_HYPERCALL, hypercallMsr.as_uint64); + hypercall_msr.as_uint64 = 0; + rdmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64); - if (!hypercallMsr.enable) { + if (!hypercall_msr.enable) { DPRINT_ERR(VMBUS, "unable to set hypercall page!!"); goto Cleanup; } - hv_context.hypercall_page = virtAddr; + hv_context.hypercall_page = virtaddr; DPRINT_INFO(VMBUS, "Hypercall page VA=%p, PA=0x%0llx", hv_context.hypercall_page, - (u64)hypercallMsr.guest_physical_address << PAGE_SHIFT); + (u64)hypercall_msr.guest_physical_address << PAGE_SHIFT); /* Setup the global signal event param for the signal event hypercall */ hv_context.signal_event_buffer = @@ -278,13 +278,13 @@ int HvInit(void) return ret; Cleanup: - if (virtAddr) { - if (hypercallMsr.enable) { - hypercallMsr.as_uint64 = 0; - wrmsrl(HV_X64_MSR_HYPERCALL, hypercallMsr.as_uint64); + if (virtaddr) { + if (hypercall_msr.enable) { + hypercall_msr.as_uint64 = 0; + wrmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64); } - vfree(virtAddr); + vfree(virtaddr); } ret = -1; return ret; @@ -297,15 +297,15 @@ Cleanup: */ void HvCleanup(void) { - union hv_x64_msr_hypercall_contents hypercallMsr; + union hv_x64_msr_hypercall_contents hypercall_msr; kfree(hv_context.signal_event_buffer); hv_context.signal_event_buffer = NULL; hv_context.signal_event_param = NULL; if (hv_context.hypercall_page) { - hypercallMsr.as_uint64 = 0; - wrmsrl(HV_X64_MSR_HYPERCALL, hypercallMsr.as_uint64); + hypercall_msr.as_uint64 = 0; + wrmsrl(HV_X64_MSR_HYPERCALL, hypercall_msr.as_uint64); vfree(hv_context.hypercall_page); hv_context.hypercall_page = NULL; } @@ -316,35 +316,35 @@ void HvCleanup(void) * * This involves a hypercall. */ -u16 HvPostMessage(union hv_connection_id connectionId, - enum hv_message_type messageType, - void *payload, size_t payloadSize) +u16 HvPostMessage(union hv_connection_id connection_id, + enum hv_message_type message_type, + void *payload, size_t payload_size) { - struct alignedInput { + struct aligned_input { u64 alignment8; struct hv_input_post_message msg; }; - struct hv_input_post_message *alignedMsg; + struct hv_input_post_message *aligned_msg; u16 status; unsigned long addr; - if (payloadSize > HV_MESSAGE_PAYLOAD_BYTE_COUNT) + if (payload_size > HV_MESSAGE_PAYLOAD_BYTE_COUNT) return -1; - addr = (unsigned long)kmalloc(sizeof(struct alignedInput), GFP_ATOMIC); + addr = (unsigned long)kmalloc(sizeof(struct aligned_input), GFP_ATOMIC); if (!addr) return -1; - alignedMsg = (struct hv_input_post_message *) + aligned_msg = (struct hv_input_post_message *) (ALIGN_UP(addr, HV_HYPERCALL_PARAM_ALIGN)); - alignedMsg->connectionid = connectionId; - alignedMsg->message_type = messageType; - alignedMsg->payload_size = payloadSize; - memcpy((void *)alignedMsg->payload, payload, payloadSize); + aligned_msg->connectionid = connection_id; + aligned_msg->message_type = message_type; + aligned_msg->payload_size = payload_size; + memcpy((void *)aligned_msg->payload, payload, payload_size); - status = HvDoHypercall(HVCALL_POST_MESSAGE, alignedMsg, NULL) & 0xFFFF; + status = HvDoHypercall(HVCALL_POST_MESSAGE, aligned_msg, NULL) & 0xFFFF; kfree((void *)addr); @@ -379,10 +379,10 @@ void HvSynicInit(void *irqarg) u64 version; union hv_synic_simp simp; union hv_synic_siefp siefp; - union hv_synic_sint sharedSint; + union hv_synic_sint shared_sint; union hv_synic_scontrol sctrl; - u32 irqVector = *((u32 *)(irqarg)); + u32 irq_vector = *((u32 *)(irqarg)); int cpu = smp_processor_id(); if (!hv_context.hypercall_page) @@ -436,17 +436,17 @@ void HvSynicInit(void *irqarg) /* interceptionSint.as_uint64); */ /* Setup the shared SINT. */ - rdmsrl(HV_X64_MSR_SINT0 + VMBUS_MESSAGE_SINT, sharedSint.as_uint64); + rdmsrl(HV_X64_MSR_SINT0 + VMBUS_MESSAGE_SINT, shared_sint.as_uint64); - sharedSint.as_uint64 = 0; - sharedSint.vector = irqVector; /* HV_SHARED_SINT_IDT_VECTOR + 0x20; */ - sharedSint.masked = false; - sharedSint.auto_eoi = true; + shared_sint.as_uint64 = 0; + shared_sint.vector = irq_vector; /* HV_SHARED_SINT_IDT_VECTOR + 0x20; */ + shared_sint.masked = false; + shared_sint.auto_eoi = true; DPRINT_DBG(VMBUS, "HV_X64_MSR_SINT1 msr set to: %llx", - sharedSint.as_uint64); + shared_sint.as_uint64); - wrmsrl(HV_X64_MSR_SINT0 + VMBUS_MESSAGE_SINT, sharedSint.as_uint64); + wrmsrl(HV_X64_MSR_SINT0 + VMBUS_MESSAGE_SINT, shared_sint.as_uint64); /* Enable the global synic bit */ rdmsrl(HV_X64_MSR_SCONTROL, sctrl.as_uint64); @@ -471,7 +471,7 @@ Cleanup: */ void HvSynicCleanup(void *arg) { - union hv_synic_sint sharedSint; + union hv_synic_sint shared_sint; union hv_synic_simp simp; union hv_synic_siefp siefp; int cpu = smp_processor_id(); @@ -479,13 +479,13 @@ void HvSynicCleanup(void *arg) if (!hv_context.synic_initialized) return; - rdmsrl(HV_X64_MSR_SINT0 + VMBUS_MESSAGE_SINT, sharedSint.as_uint64); + rdmsrl(HV_X64_MSR_SINT0 + VMBUS_MESSAGE_SINT, shared_sint.as_uint64); - sharedSint.masked = 1; + shared_sint.masked = 1; /* Need to correctly cleanup in the case of SMP!!! */ /* Disable the interrupt */ - wrmsrl(HV_X64_MSR_SINT0 + VMBUS_MESSAGE_SINT, sharedSint.as_uint64); + wrmsrl(HV_X64_MSR_SINT0 + VMBUS_MESSAGE_SINT, shared_sint.as_uint64); rdmsrl(HV_X64_MSR_SIMP, simp.as_uint64); simp.simp_enabled = 0; -- cgit v1.2.3 From d44890c8d2a83116463c230b59b9b9d356aafe85 Mon Sep 17 00:00:00 2001 From: Haiyang Zhang Date: Mon, 8 Nov 2010 14:04:42 -0800 Subject: staging: hv: Convert camel cased functions in hv.c to lower cases staging: hv: Convert camel cased functions in hv.c to lower cases Signed-off-by: Haiyang Zhang Signed-off-by: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/connection.c | 4 ++-- drivers/staging/hv/hv.c | 47 ++++++++++++++++++++++------------------- drivers/staging/hv/hv.h | 16 +++++++------- drivers/staging/hv/hv_api.h | 4 ++-- drivers/staging/hv/vmbus.c | 8 +++---- 5 files changed, 41 insertions(+), 38 deletions(-) diff --git a/drivers/staging/hv/connection.c b/drivers/staging/hv/connection.c index ba50dd8fe52d..97321d172c91 100644 --- a/drivers/staging/hv/connection.c +++ b/drivers/staging/hv/connection.c @@ -311,7 +311,7 @@ int VmbusPostMessage(void *buffer, size_t bufferLen) connId.asu32 = 0; connId.u.id = VMBUS_MESSAGE_CONNECTION_ID; - return HvPostMessage(connId, 1, buffer, bufferLen); + return hv_post_message(connId, 1, buffer, bufferLen); } /* @@ -324,5 +324,5 @@ int VmbusSetEvent(u32 childRelId) (unsigned long *)gVmbusConnection.SendInterruptPage + (childRelId >> 5)); - return HvSignalEvent(); + return hv_signal_event(); } diff --git a/drivers/staging/hv/hv.c b/drivers/staging/hv/hv.c index 2fd234d711ea..66f04d8063a6 100644 --- a/drivers/staging/hv/hv.c +++ b/drivers/staging/hv/hv.c @@ -36,9 +36,10 @@ struct hv_context hv_context = { }; /* - * HvQueryHypervisorPresence - Query the cpuid for presense of windows hypervisor + * query_hypervisor_presence + * - Query the cpuid for presense of windows hypervisor */ -static int HvQueryHypervisorPresence(void) +static int query_hypervisor_presence(void) { unsigned int eax; unsigned int ebx; @@ -57,9 +58,9 @@ static int HvQueryHypervisorPresence(void) } /* - * HvQueryHypervisorInfo - Get version info of the windows hypervisor + * query_hypervisor_info - Get version info of the windows hypervisor */ -static int HvQueryHypervisorInfo(void) +static int query_hypervisor_info(void) { unsigned int eax; unsigned int ebx; @@ -126,9 +127,9 @@ static int HvQueryHypervisorInfo(void) } /* - * HvDoHypercall - Invoke the specified hypercall + * do_hypercall- Invoke the specified hypercall */ -static u64 HvDoHypercall(u64 control, void *input, void *output) +static u64 do_hypercall(u64 control, void *input, void *output) { #ifdef CONFIG_X86_64 u64 hv_status = 0; @@ -181,11 +182,11 @@ static u64 HvDoHypercall(u64 control, void *input, void *output) } /* - * HvInit - Main initialization routine. + * hv_init - Main initialization routine. * * This routine must be called before any other routines in here are called */ -int HvInit(void) +int hv_init(void) { int ret = 0; int max_leaf; @@ -196,7 +197,7 @@ int HvInit(void) memset(hv_context.synic_message_page, 0, sizeof(void *) * MAX_NUM_CPUS); - if (!HvQueryHypervisorPresence()) { + if (!query_hypervisor_presence()) { DPRINT_ERR(VMBUS, "No Windows hypervisor detected!!"); goto Cleanup; } @@ -204,7 +205,7 @@ int HvInit(void) DPRINT_INFO(VMBUS, "Windows hypervisor detected! Retrieving more info..."); - max_leaf = HvQueryHypervisorInfo(); + max_leaf = query_hypervisor_info(); /* HvQueryHypervisorFeatures(maxLeaf); */ /* @@ -291,11 +292,11 @@ Cleanup: } /* - * HvCleanup - Cleanup routine. + * hv_cleanup - Cleanup routine. * * This routine is called normally during driver unloading or exiting. */ -void HvCleanup(void) +void hv_cleanup(void) { union hv_x64_msr_hypercall_contents hypercall_msr; @@ -312,11 +313,11 @@ void HvCleanup(void) } /* - * HvPostMessage - Post a message using the hypervisor message IPC. + * hv_post_message - Post a message using the hypervisor message IPC. * * This involves a hypercall. */ -u16 HvPostMessage(union hv_connection_id connection_id, +u16 hv_post_message(union hv_connection_id connection_id, enum hv_message_type message_type, void *payload, size_t payload_size) { @@ -344,7 +345,8 @@ u16 HvPostMessage(union hv_connection_id connection_id, aligned_msg->payload_size = payload_size; memcpy((void *)aligned_msg->payload, payload, payload_size); - status = HvDoHypercall(HVCALL_POST_MESSAGE, aligned_msg, NULL) & 0xFFFF; + status = do_hypercall(HVCALL_POST_MESSAGE, aligned_msg, NULL) + & 0xFFFF; kfree((void *)addr); @@ -353,28 +355,29 @@ u16 HvPostMessage(union hv_connection_id connection_id, /* - * HvSignalEvent - Signal an event on the specified connection using the hypervisor event IPC. + * hv_signal_event - + * Signal an event on the specified connection using the hypervisor event IPC. * * This involves a hypercall. */ -u16 HvSignalEvent(void) +u16 hv_signal_event(void) { u16 status; - status = HvDoHypercall(HVCALL_SIGNAL_EVENT, + status = do_hypercall(HVCALL_SIGNAL_EVENT, hv_context.signal_event_param, NULL) & 0xFFFF; return status; } /* - * HvSynicInit - Initialize the Synthethic Interrupt Controller. + * hv_synic_init - Initialize the Synthethic Interrupt Controller. * * If it is already initialized by another entity (ie x2v shim), we need to * retrieve the initialized message and event pages. Otherwise, we create and * initialize the message and event pages. */ -void HvSynicInit(void *irqarg) +void hv_synic_init(void *irqarg) { u64 version; union hv_synic_simp simp; @@ -467,9 +470,9 @@ Cleanup: } /* - * HvSynicCleanup - Cleanup routine for HvSynicInit(). + * hv_synic_cleanup - Cleanup routine for hv_synic_init(). */ -void HvSynicCleanup(void *arg) +void hv_synic_cleanup(void *arg) { union hv_synic_sint shared_sint; union hv_synic_simp simp; diff --git a/drivers/staging/hv/hv.h b/drivers/staging/hv/hv.h index 6e396fca1942..829aff81bb30 100644 --- a/drivers/staging/hv/hv.h +++ b/drivers/staging/hv/hv.h @@ -123,18 +123,18 @@ extern struct hv_context hv_context; /* Hv Interface */ -extern int HvInit(void); +extern int hv_init(void); -extern void HvCleanup(void); +extern void hv_cleanup(void); -extern u16 HvPostMessage(union hv_connection_id connectionId, - enum hv_message_type messageType, - void *payload, size_t payloadSize); +extern u16 hv_post_message(union hv_connection_id connection_id, + enum hv_message_type message_type, + void *payload, size_t payload_size); -extern u16 HvSignalEvent(void); +extern u16 hv_signal_event(void); -extern void HvSynicInit(void *irqarg); +extern void hv_synic_init(void *irqarg); -extern void HvSynicCleanup(void *arg); +extern void hv_synic_cleanup(void *arg); #endif /* __HV_H__ */ diff --git a/drivers/staging/hv/hv_api.h b/drivers/staging/hv/hv_api.h index 9df64724549a..70e863ad0464 100644 --- a/drivers/staging/hv/hv_api.h +++ b/drivers/staging/hv/hv_api.h @@ -836,7 +836,7 @@ enum hv_call_code { HVCALL_SIGNAL_EVENT = 0x005d, }; -/* Definition of the HvPostMessage hypercall input structure. */ +/* Definition of the hv_post_message hypercall input structure. */ struct hv_input_post_message { union hv_connection_id connectionid; u32 reserved; @@ -845,7 +845,7 @@ struct hv_input_post_message { u64 payload[HV_MESSAGE_PAYLOAD_QWORD_COUNT]; }; -/* Definition of the HvSignalEvent hypercall input structure. */ +/* Definition of the hv_signal_event hypercall input structure. */ struct hv_input_signal_event { union hv_connection_id connectionid; u16 flag_number; diff --git a/drivers/staging/hv/vmbus.c b/drivers/staging/hv/vmbus.c index b1ec8762f228..e6462c6774d1 100644 --- a/drivers/staging/hv/vmbus.c +++ b/drivers/staging/hv/vmbus.c @@ -109,7 +109,7 @@ static int VmbusOnDeviceAdd(struct hv_device *dev, void *AdditionalInfo) /* strcpy(dev->name, "vmbus"); */ /* SynIC setup... */ - on_each_cpu(HvSynicInit, (void *)irqvector, 1); + on_each_cpu(hv_synic_init, (void *)irqvector, 1); /* Connect to VMBus in the root partition */ ret = VmbusConnect(); @@ -127,7 +127,7 @@ static int VmbusOnDeviceRemove(struct hv_device *dev) vmbus_release_unattached_channels(); VmbusDisconnect(); - on_each_cpu(HvSynicCleanup, NULL, 1); + on_each_cpu(hv_synic_cleanup, NULL, 1); return ret; } @@ -138,7 +138,7 @@ static void VmbusOnCleanup(struct hv_driver *drv) { /* struct vmbus_driver *driver = (struct vmbus_driver *)drv; */ - HvCleanup(); + hv_cleanup(); } /* @@ -264,7 +264,7 @@ int VmbusInitialize(struct hv_driver *drv) driver->GetChannelOffers = VmbusGetChannelOffers; /* Hypervisor initialization...setup hypercall page..etc */ - ret = HvInit(); + ret = hv_init(); if (ret != 0) DPRINT_ERR(VMBUS, "Unable to initialize the hypervisor - 0x%x", ret); -- cgit v1.2.3 From d39f12866d90829e1ae0440c0203dd5a162c8cd8 Mon Sep 17 00:00:00 2001 From: Haiyang Zhang Date: Mon, 8 Nov 2010 14:04:43 -0800 Subject: staging: hv: Convert camel cased local variables in osd.c to lower cases staging: hv: Convert camel cased local variables in osd.c to lower cases Signed-off-by: Haiyang Zhang Signed-off-by: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/osd.c | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/drivers/staging/hv/osd.c b/drivers/staging/hv/osd.c index 8c3eb278a81f..b39ec250aefd 100644 --- a/drivers/staging/hv/osd.c +++ b/drivers/staging/hv/osd.c @@ -130,9 +130,9 @@ EXPORT_SYMBOL_GPL(osd_WaitEventCreate); /** * osd_WaitEventSet() - Wake up the process - * @waitEvent: Structure to event to be woken up + * @wait_event: Structure to event to be woken up * - * @waitevent is of type &struct osd_waitevent + * @wait_event is of type &struct osd_waitevent * * Wake up the sleeping process so it can do some work. * And set condition indicator in &struct osd_waitevent to indicate @@ -140,18 +140,18 @@ EXPORT_SYMBOL_GPL(osd_WaitEventCreate); * * Only used by Network and Storage Hyper-V drivers. */ -void osd_WaitEventSet(struct osd_waitevent *waitEvent) +void osd_WaitEventSet(struct osd_waitevent *wait_event) { - waitEvent->condition = 1; - wake_up_interruptible(&waitEvent->event); + wait_event->condition = 1; + wake_up_interruptible(&wait_event->event); } EXPORT_SYMBOL_GPL(osd_WaitEventSet); /** * osd_WaitEventWait() - Wait for event till condition is true - * @waitEvent: Structure to event to be put to sleep + * @wait_event: Structure to event to be put to sleep * - * @waitevent is of type &struct osd_waitevent + * @wait_event is of type &struct osd_waitevent * * Set up the process to sleep until waitEvent->condition get true. * And set condition indicator in &struct osd_waitevent to indicate @@ -161,25 +161,25 @@ EXPORT_SYMBOL_GPL(osd_WaitEventSet); * * Mainly used by Hyper-V drivers. */ -int osd_WaitEventWait(struct osd_waitevent *waitEvent) +int osd_WaitEventWait(struct osd_waitevent *wait_event) { int ret = 0; - ret = wait_event_interruptible(waitEvent->event, - waitEvent->condition); - waitEvent->condition = 0; + ret = wait_event_interruptible(wait_event->event, + wait_event->condition); + wait_event->condition = 0; return ret; } EXPORT_SYMBOL_GPL(osd_WaitEventWait); /** * osd_WaitEventWaitEx() - Wait for event or timeout for process wakeup - * @waitEvent: Structure to event to be put to sleep - * @TimeoutInMs: Total number of Milliseconds to wait before waking up + * @wait_event: Structure to event to be put to sleep + * @timeout_in_ms: Total number of Milliseconds to wait before waking up * - * @waitevent is of type &struct osd_waitevent + * @wait_event is of type &struct osd_waitevent * Set up the process to sleep until @waitEvent->condition get true or - * @TimeoutInMs (Time out in Milliseconds) has been reached. + * @timeout_in_ms (Time out in Milliseconds) has been reached. * And set condition indicator in &struct osd_waitevent to indicate * the process is in a sleeping state. * @@ -187,14 +187,14 @@ EXPORT_SYMBOL_GPL(osd_WaitEventWait); * * Mainly used by Hyper-V drivers. */ -int osd_WaitEventWaitEx(struct osd_waitevent *waitEvent, u32 TimeoutInMs) +int osd_WaitEventWaitEx(struct osd_waitevent *wait_event, u32 timeout_in_ms) { int ret = 0; - ret = wait_event_interruptible_timeout(waitEvent->event, - waitEvent->condition, - msecs_to_jiffies(TimeoutInMs)); - waitEvent->condition = 0; + ret = wait_event_interruptible_timeout(wait_event->event, + wait_event->condition, + msecs_to_jiffies(timeout_in_ms)); + wait_event->condition = 0; return ret; } EXPORT_SYMBOL_GPL(osd_WaitEventWaitEx); -- cgit v1.2.3 From 203df82d81a331e16caee4c2346cd382fcd820d6 Mon Sep 17 00:00:00 2001 From: Haiyang Zhang Date: Mon, 8 Nov 2010 14:04:44 -0800 Subject: staging: hv: Convert camel cased functions in osd.c to lower cases staging: hv: Convert camel cased functions in osd.c to lower cases Signed-off-by: Haiyang Zhang Signed-off-by: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/channel.c | 20 ++++++++++---------- drivers/staging/hv/channel_mgmt.c | 12 ++++++------ drivers/staging/hv/connection.c | 14 +++++++------- drivers/staging/hv/hv.c | 12 ++++++------ drivers/staging/hv/netvsc.c | 24 +++++++++++------------ drivers/staging/hv/osd.c | 40 +++++++++++++++++++-------------------- drivers/staging/hv/osd.h | 18 +++++++++--------- drivers/staging/hv/rndis_filter.c | 10 +++++----- drivers/staging/hv/storvsc.c | 16 ++++++++-------- 9 files changed, 83 insertions(+), 83 deletions(-) diff --git a/drivers/staging/hv/channel.c b/drivers/staging/hv/channel.c index 7c15c4034e2d..abc2988b4d4a 100644 --- a/drivers/staging/hv/channel.c +++ b/drivers/staging/hv/channel.c @@ -180,7 +180,7 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size, newchannel->channel_callback_context = context; /* Allocate the ring buffer */ - out = osd_PageAlloc((send_ringbuffer_size + recv_ringbuffer_size) + out = osd_page_alloc((send_ringbuffer_size + recv_ringbuffer_size) >> PAGE_SHIFT); if (!out) return -ENOMEM; @@ -242,7 +242,7 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size, goto errorout; } - openInfo->waitevent = osd_WaitEventCreate(); + openInfo->waitevent = osd_waitevent_create(); if (!openInfo->waitevent) { err = -ENOMEM; goto errorout; @@ -280,7 +280,7 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size, } /* FIXME: Need to time-out here */ - osd_WaitEventWait(openInfo->waitevent); + osd_waitevent_wait(openInfo->waitevent); if (openInfo->response.open_result.status == 0) DPRINT_INFO(VMBUS, "channel <%p> open success!!", newchannel); @@ -300,7 +300,7 @@ Cleanup: errorout: RingBufferCleanup(&newchannel->outbound); RingBufferCleanup(&newchannel->inbound); - osd_PageFree(out, (send_ringbuffer_size + recv_ringbuffer_size) + osd_page_free(out, (send_ringbuffer_size + recv_ringbuffer_size) >> PAGE_SHIFT); kfree(openInfo); return err; @@ -508,7 +508,7 @@ int vmbus_establish_gpadl(struct vmbus_channel *channel, void *kbuffer, if (ret) return ret; - msginfo->waitevent = osd_WaitEventCreate(); + msginfo->waitevent = osd_waitevent_create(); if (!msginfo->waitevent) { ret = -ENOMEM; goto Cleanup; @@ -565,7 +565,7 @@ int vmbus_establish_gpadl(struct vmbus_channel *channel, void *kbuffer, } } - osd_WaitEventWait(msginfo->waitevent); + osd_waitevent_wait(msginfo->waitevent); /* At this point, we received the gpadl created msg */ DPRINT_DBG(VMBUS, "Received GPADL created " @@ -604,7 +604,7 @@ int vmbus_teardown_gpadl(struct vmbus_channel *channel, u32 gpadl_handle) if (!info) return -ENOMEM; - info->waitevent = osd_WaitEventCreate(); + info->waitevent = osd_waitevent_create(); if (!info->waitevent) { kfree(info); return -ENOMEM; @@ -628,7 +628,7 @@ int vmbus_teardown_gpadl(struct vmbus_channel *channel, u32 gpadl_handle) /* something... */ } - osd_WaitEventWait(info->waitevent); + osd_waitevent_wait(info->waitevent); /* Received a torndown response */ spin_lock_irqsave(&gVmbusConnection.channelmsg_lock, flags); @@ -663,7 +663,7 @@ void vmbus_close(struct vmbus_channel *channel) if (!info) return; - /* info->waitEvent = osd_WaitEventCreate(); */ + /* info->waitEvent = osd_waitevent_create(); */ msg = (struct vmbus_channel_close_channel *)info->msg; msg->header.msgtype = CHANNELMSG_CLOSECHANNEL; @@ -686,7 +686,7 @@ void vmbus_close(struct vmbus_channel *channel) RingBufferCleanup(&channel->outbound); RingBufferCleanup(&channel->inbound); - osd_PageFree(channel->ringbuffer_pages, channel->ringbuffer_pagecount); + osd_page_free(channel->ringbuffer_pages, channel->ringbuffer_pagecount); kfree(info); diff --git a/drivers/staging/hv/channel_mgmt.c b/drivers/staging/hv/channel_mgmt.c index be34e38c1a85..ae830f2e4e3a 100644 --- a/drivers/staging/hv/channel_mgmt.c +++ b/drivers/staging/hv/channel_mgmt.c @@ -566,7 +566,7 @@ static void vmbus_onopen_result(struct vmbus_channel_message_header *hdr) memcpy(&msginfo->response.open_result, result, sizeof(struct vmbus_channel_open_result)); - osd_WaitEventSet(msginfo->waitevent); + osd_waitevent_set(msginfo->waitevent); break; } } @@ -616,7 +616,7 @@ static void vmbus_ongpadl_created(struct vmbus_channel_message_header *hdr) memcpy(&msginfo->response.gpadl_created, gpadlcreated, sizeof(struct vmbus_channel_gpadl_created)); - osd_WaitEventSet(msginfo->waitevent); + osd_waitevent_set(msginfo->waitevent); break; } } @@ -662,7 +662,7 @@ static void vmbus_ongpadl_torndown( memcpy(&msginfo->response.gpadl_torndown, gpadl_torndown, sizeof(struct vmbus_channel_gpadl_torndown)); - osd_WaitEventSet(msginfo->waitevent); + osd_waitevent_set(msginfo->waitevent); break; } } @@ -703,7 +703,7 @@ static void vmbus_onversion_response( memcpy(&msginfo->response.version_response, version_response, sizeof(struct vmbus_channel_version_response)); - osd_WaitEventSet(msginfo->waitevent); + osd_waitevent_set(msginfo->waitevent); } } spin_unlock_irqrestore(&gVmbusConnection.channelmsg_lock, flags); @@ -782,7 +782,7 @@ int vmbus_request_offers(void) if (!msginfo) return -ENOMEM; - msginfo->waitevent = osd_WaitEventCreate(); + msginfo->waitevent = osd_waitevent_create(); if (!msginfo->waitevent) { kfree(msginfo); return -ENOMEM; @@ -808,7 +808,7 @@ int vmbus_request_offers(void) goto Cleanup; } - /* osd_WaitEventWait(msgInfo->waitEvent); */ + /* osd_waitevent_wait(msgInfo->waitEvent); */ /*SpinlockAcquire(gVmbusConnection.channelMsgLock); REMOVE_ENTRY_LIST(&msgInfo->msgListEntry); diff --git a/drivers/staging/hv/connection.c b/drivers/staging/hv/connection.c index 97321d172c91..c2e298ff4834 100644 --- a/drivers/staging/hv/connection.c +++ b/drivers/staging/hv/connection.c @@ -66,7 +66,7 @@ int VmbusConnect(void) * Setup the vmbus event connection for channel interrupt * abstraction stuff */ - gVmbusConnection.InterruptPage = osd_PageAlloc(1); + gVmbusConnection.InterruptPage = osd_page_alloc(1); if (gVmbusConnection.InterruptPage == NULL) { ret = -1; goto Cleanup; @@ -81,7 +81,7 @@ int VmbusConnect(void) * Setup the monitor notification facility. The 1st page for * parent->child and the 2nd page for child->parent */ - gVmbusConnection.MonitorPages = osd_PageAlloc(2); + gVmbusConnection.MonitorPages = osd_page_alloc(2); if (gVmbusConnection.MonitorPages == NULL) { ret = -1; goto Cleanup; @@ -95,7 +95,7 @@ int VmbusConnect(void) goto Cleanup; } - msgInfo->waitevent = osd_WaitEventCreate(); + msgInfo->waitevent = osd_waitevent_create(); if (!msgInfo->waitevent) { ret = -ENOMEM; goto Cleanup; @@ -134,7 +134,7 @@ int VmbusConnect(void) } /* Wait for the connection response */ - osd_WaitEventWait(msgInfo->waitevent); + osd_waitevent_wait(msgInfo->waitevent); list_del(&msgInfo->msglistentry); @@ -162,12 +162,12 @@ Cleanup: destroy_workqueue(gVmbusConnection.WorkQueue); if (gVmbusConnection.InterruptPage) { - osd_PageFree(gVmbusConnection.InterruptPage, 1); + osd_page_free(gVmbusConnection.InterruptPage, 1); gVmbusConnection.InterruptPage = NULL; } if (gVmbusConnection.MonitorPages) { - osd_PageFree(gVmbusConnection.MonitorPages, 2); + osd_page_free(gVmbusConnection.MonitorPages, 2); gVmbusConnection.MonitorPages = NULL; } @@ -202,7 +202,7 @@ int VmbusDisconnect(void) if (ret != 0) goto Cleanup; - osd_PageFree(gVmbusConnection.InterruptPage, 1); + osd_page_free(gVmbusConnection.InterruptPage, 1); /* TODO: iterate thru the msg list and free up */ destroy_workqueue(gVmbusConnection.WorkQueue); diff --git a/drivers/staging/hv/hv.c b/drivers/staging/hv/hv.c index 66f04d8063a6..a34d713d9c57 100644 --- a/drivers/staging/hv/hv.c +++ b/drivers/staging/hv/hv.c @@ -228,9 +228,9 @@ int hv_init(void) /* * Allocate the hypercall page memory - * virtaddr = osd_PageAlloc(1); + * virtaddr = osd_page_alloc(1); */ - virtaddr = osd_VirtualAllocExec(PAGE_SIZE); + virtaddr = osd_virtual_alloc_exec(PAGE_SIZE); if (!virtaddr) { DPRINT_ERR(VMBUS, @@ -462,10 +462,10 @@ void hv_synic_init(void *irqarg) Cleanup: if (hv_context.synic_event_page[cpu]) - osd_PageFree(hv_context.synic_event_page[cpu], 1); + osd_page_free(hv_context.synic_event_page[cpu], 1); if (hv_context.synic_message_page[cpu]) - osd_PageFree(hv_context.synic_message_page[cpu], 1); + osd_page_free(hv_context.synic_message_page[cpu], 1); return; } @@ -502,6 +502,6 @@ void hv_synic_cleanup(void *arg) wrmsrl(HV_X64_MSR_SIEFP, siefp.as_uint64); - osd_PageFree(hv_context.synic_message_page[cpu], 1); - osd_PageFree(hv_context.synic_event_page[cpu], 1); + osd_page_free(hv_context.synic_message_page[cpu], 1); + osd_page_free(hv_context.synic_event_page[cpu], 1); } diff --git a/drivers/staging/hv/netvsc.c b/drivers/staging/hv/netvsc.c index 4c2632cb19e9..8022781a9b13 100644 --- a/drivers/staging/hv/netvsc.c +++ b/drivers/staging/hv/netvsc.c @@ -221,7 +221,7 @@ static int NetVscInitializeReceiveBufferWithNetVsp(struct hv_device *Device) /* ASSERT((netDevice->ReceiveBufferSize & (PAGE_SIZE - 1)) == 0); */ netDevice->ReceiveBuffer = - osd_PageAlloc(netDevice->ReceiveBufferSize >> PAGE_SHIFT); + osd_page_alloc(netDevice->ReceiveBufferSize >> PAGE_SHIFT); if (!netDevice->ReceiveBuffer) { DPRINT_ERR(NETVSC, "unable to allocate receive buffer of size %d", @@ -249,7 +249,7 @@ static int NetVscInitializeReceiveBufferWithNetVsp(struct hv_device *Device) goto Cleanup; } - /* osd_WaitEventWait(ext->ChannelInitEvent); */ + /* osd_waitevent_wait(ext->ChannelInitEvent); */ /* Notify the NetVsp of the gpadl handle */ DPRINT_INFO(NETVSC, "Sending NvspMessage1TypeSendReceiveBuffer..."); @@ -274,7 +274,7 @@ static int NetVscInitializeReceiveBufferWithNetVsp(struct hv_device *Device) goto Cleanup; } - osd_WaitEventWait(netDevice->ChannelInitEvent); + osd_waitevent_wait(netDevice->ChannelInitEvent); /* Check the response */ if (initPacket->Messages.Version1Messages.SendReceiveBufferComplete.Status != NvspStatusSuccess) { @@ -350,7 +350,7 @@ static int NetVscInitializeSendBufferWithNetVsp(struct hv_device *Device) /* ASSERT((netDevice->SendBufferSize & (PAGE_SIZE - 1)) == 0); */ netDevice->SendBuffer = - osd_PageAlloc(netDevice->SendBufferSize >> PAGE_SHIFT); + osd_page_alloc(netDevice->SendBufferSize >> PAGE_SHIFT); if (!netDevice->SendBuffer) { DPRINT_ERR(NETVSC, "unable to allocate send buffer of size %d", netDevice->SendBufferSize); @@ -375,7 +375,7 @@ static int NetVscInitializeSendBufferWithNetVsp(struct hv_device *Device) goto Cleanup; } - /* osd_WaitEventWait(ext->ChannelInitEvent); */ + /* osd_waitevent_wait(ext->ChannelInitEvent); */ /* Notify the NetVsp of the gpadl handle */ DPRINT_INFO(NETVSC, "Sending NvspMessage1TypeSendSendBuffer..."); @@ -400,7 +400,7 @@ static int NetVscInitializeSendBufferWithNetVsp(struct hv_device *Device) goto Cleanup; } - osd_WaitEventWait(netDevice->ChannelInitEvent); + osd_waitevent_wait(netDevice->ChannelInitEvent); /* Check the response */ if (initPacket->Messages.Version1Messages.SendSendBufferComplete.Status != NvspStatusSuccess) { @@ -480,7 +480,7 @@ static int NetVscDestroyReceiveBuffer(struct netvsc_device *NetDevice) DPRINT_INFO(NETVSC, "Freeing up receive buffer..."); /* Free up the receive buffer */ - osd_PageFree(NetDevice->ReceiveBuffer, + osd_page_free(NetDevice->ReceiveBuffer, NetDevice->ReceiveBufferSize >> PAGE_SHIFT); NetDevice->ReceiveBuffer = NULL; } @@ -553,7 +553,7 @@ static int NetVscDestroySendBuffer(struct netvsc_device *NetDevice) DPRINT_INFO(NETVSC, "Freeing up send buffer..."); /* Free up the receive buffer */ - osd_PageFree(NetDevice->SendBuffer, + osd_page_free(NetDevice->SendBuffer, NetDevice->SendBufferSize >> PAGE_SHIFT); NetDevice->SendBuffer = NULL; } @@ -597,7 +597,7 @@ static int NetVscConnectToVsp(struct hv_device *Device) goto Cleanup; } - osd_WaitEventWait(netDevice->ChannelInitEvent); + osd_waitevent_wait(netDevice->ChannelInitEvent); /* Now, check the response */ /* ASSERT(initPacket->Messages.InitMessages.InitComplete.MaximumMdlChainLength <= MAX_MULTIPAGE_BUFFER_COUNT); */ @@ -651,7 +651,7 @@ static int NetVscConnectToVsp(struct hv_device *Device) * packet) since our Vmbus always set the * VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED flag */ - /* osd_WaitEventWait(NetVscChannel->ChannelInitEvent); */ + /* osd_waitevent_wait(NetVscChannel->ChannelInitEvent); */ /* Post the big receive buffer to NetVSP */ ret = NetVscInitializeReceiveBufferWithNetVsp(Device); @@ -710,7 +710,7 @@ static int NetVscOnDeviceAdd(struct hv_device *Device, void *AdditionalInfo) list_add_tail(&packet->ListEntry, &netDevice->ReceivePacketList); } - netDevice->ChannelInitEvent = osd_WaitEventCreate(); + netDevice->ChannelInitEvent = osd_waitevent_create(); if (!netDevice->ChannelInitEvent) { ret = -ENOMEM; goto Cleanup; @@ -855,7 +855,7 @@ static void NetVscOnSendCompletion(struct hv_device *Device, /* Copy the response back */ memcpy(&netDevice->ChannelInitPacket, nvspPacket, sizeof(struct nvsp_message)); - osd_WaitEventSet(netDevice->ChannelInitEvent); + osd_waitevent_set(netDevice->ChannelInitEvent); } else if (nvspPacket->Header.MessageType == NvspMessage1TypeSendRNDISPacketComplete) { /* Get the send context */ diff --git a/drivers/staging/hv/osd.c b/drivers/staging/hv/osd.c index b39ec250aefd..b699ee27f07f 100644 --- a/drivers/staging/hv/osd.c +++ b/drivers/staging/hv/osd.c @@ -49,7 +49,7 @@ struct osd_callback_struct { void *data; }; -void *osd_VirtualAllocExec(unsigned int size) +void *osd_virtual_alloc_exec(unsigned int size) { #ifdef __x86_64__ return __vmalloc(size, GFP_KERNEL, PAGE_KERNEL_EXEC); @@ -60,7 +60,7 @@ void *osd_VirtualAllocExec(unsigned int size) } /** - * osd_PageAlloc() - Allocate pages + * osd_page_alloc() - Allocate pages * @count: Total number of Kernel pages you want to allocate * * Tries to allocate @count number of consecutive free kernel pages. @@ -68,7 +68,7 @@ void *osd_VirtualAllocExec(unsigned int size) * If successfull it will return pointer to the @count pages. * Mainly used by Hyper-V drivers. */ -void *osd_PageAlloc(unsigned int count) +void *osd_page_alloc(unsigned int count) { void *p; @@ -85,26 +85,26 @@ void *osd_PageAlloc(unsigned int count) /* if (p) memset(p, 0, PAGE_SIZE); */ /* return p; */ } -EXPORT_SYMBOL_GPL(osd_PageAlloc); +EXPORT_SYMBOL_GPL(osd_page_alloc); /** - * osd_PageFree() - Free pages + * osd_page_free() - Free pages * @page: Pointer to the first page to be freed * @count: Total number of Kernel pages you free * - * Frees the pages allocated by osd_PageAlloc() + * Frees the pages allocated by osd_page_alloc() * Mainly used by Hyper-V drivers. */ -void osd_PageFree(void *page, unsigned int count) +void osd_page_free(void *page, unsigned int count) { free_pages((unsigned long)page, get_order(count * PAGE_SIZE)); /*struct page* p = virt_to_page(page); __free_page(p);*/ } -EXPORT_SYMBOL_GPL(osd_PageFree); +EXPORT_SYMBOL_GPL(osd_page_free); /** - * osd_WaitEventCreate() - Create the event queue + * osd_waitevent_create() - Create the event queue * * Allocates memory for a &struct osd_waitevent. And then calls * init_waitqueue_head to set up the wait queue for the event. @@ -114,7 +114,7 @@ EXPORT_SYMBOL_GPL(osd_PageFree); * Returns pointer to &struct osd_waitevent * Mainly used by Hyper-V drivers. */ -struct osd_waitevent *osd_WaitEventCreate(void) +struct osd_waitevent *osd_waitevent_create(void) { struct osd_waitevent *wait = kmalloc(sizeof(struct osd_waitevent), GFP_KERNEL); @@ -125,11 +125,11 @@ struct osd_waitevent *osd_WaitEventCreate(void) init_waitqueue_head(&wait->event); return wait; } -EXPORT_SYMBOL_GPL(osd_WaitEventCreate); +EXPORT_SYMBOL_GPL(osd_waitevent_create); /** - * osd_WaitEventSet() - Wake up the process + * osd_waitevent_set() - Wake up the process * @wait_event: Structure to event to be woken up * * @wait_event is of type &struct osd_waitevent @@ -140,15 +140,15 @@ EXPORT_SYMBOL_GPL(osd_WaitEventCreate); * * Only used by Network and Storage Hyper-V drivers. */ -void osd_WaitEventSet(struct osd_waitevent *wait_event) +void osd_waitevent_set(struct osd_waitevent *wait_event) { wait_event->condition = 1; wake_up_interruptible(&wait_event->event); } -EXPORT_SYMBOL_GPL(osd_WaitEventSet); +EXPORT_SYMBOL_GPL(osd_waitevent_set); /** - * osd_WaitEventWait() - Wait for event till condition is true + * osd_waitevent_wait() - Wait for event till condition is true * @wait_event: Structure to event to be put to sleep * * @wait_event is of type &struct osd_waitevent @@ -161,7 +161,7 @@ EXPORT_SYMBOL_GPL(osd_WaitEventSet); * * Mainly used by Hyper-V drivers. */ -int osd_WaitEventWait(struct osd_waitevent *wait_event) +int osd_waitevent_wait(struct osd_waitevent *wait_event) { int ret = 0; @@ -170,10 +170,10 @@ int osd_WaitEventWait(struct osd_waitevent *wait_event) wait_event->condition = 0; return ret; } -EXPORT_SYMBOL_GPL(osd_WaitEventWait); +EXPORT_SYMBOL_GPL(osd_waitevent_wait); /** - * osd_WaitEventWaitEx() - Wait for event or timeout for process wakeup + * osd_waitevent_waitex() - Wait for event or timeout for process wakeup * @wait_event: Structure to event to be put to sleep * @timeout_in_ms: Total number of Milliseconds to wait before waking up * @@ -187,7 +187,7 @@ EXPORT_SYMBOL_GPL(osd_WaitEventWait); * * Mainly used by Hyper-V drivers. */ -int osd_WaitEventWaitEx(struct osd_waitevent *wait_event, u32 timeout_in_ms) +int osd_waitevent_waitex(struct osd_waitevent *wait_event, u32 timeout_in_ms) { int ret = 0; @@ -197,7 +197,7 @@ int osd_WaitEventWaitEx(struct osd_waitevent *wait_event, u32 timeout_in_ms) wait_event->condition = 0; return ret; } -EXPORT_SYMBOL_GPL(osd_WaitEventWaitEx); +EXPORT_SYMBOL_GPL(osd_waitevent_waitex); static void osd_callback_work(struct work_struct *work) { diff --git a/drivers/staging/hv/osd.h b/drivers/staging/hv/osd.h index ce064e8ea644..cae126ff6b9a 100644 --- a/drivers/staging/hv/osd.h +++ b/drivers/staging/hv/osd.h @@ -50,18 +50,18 @@ struct osd_waitevent { /* Osd routines */ -extern void *osd_VirtualAllocExec(unsigned int size); +extern void *osd_virtual_alloc_exec(unsigned int size); -extern void *osd_PageAlloc(unsigned int count); -extern void osd_PageFree(void *page, unsigned int count); +extern void *osd_page_alloc(unsigned int count); +extern void osd_page_free(void *page, unsigned int count); -extern struct osd_waitevent *osd_WaitEventCreate(void); -extern void osd_WaitEventSet(struct osd_waitevent *waitEvent); -extern int osd_WaitEventWait(struct osd_waitevent *waitEvent); +extern struct osd_waitevent *osd_waitevent_create(void); +extern void osd_waitevent_set(struct osd_waitevent *wait_event); +extern int osd_waitevent_wait(struct osd_waitevent *wait_event); -/* If >0, waitEvent got signaled. If ==0, timeout. If < 0, error */ -extern int osd_WaitEventWaitEx(struct osd_waitevent *waitEvent, - u32 TimeoutInMs); +/* If >0, wait_event got signaled. If ==0, timeout. If < 0, error */ +extern int osd_waitevent_waitex(struct osd_waitevent *wait_event, + u32 timeout_in_ms); int osd_schedule_callback(struct workqueue_struct *wq, void (*func)(void *), diff --git a/drivers/staging/hv/rndis_filter.c b/drivers/staging/hv/rndis_filter.c index fa2141f454f0..b85c82542421 100644 --- a/drivers/staging/hv/rndis_filter.c +++ b/drivers/staging/hv/rndis_filter.c @@ -129,7 +129,7 @@ static struct rndis_request *GetRndisRequest(struct rndis_device *Device, if (!request) return NULL; - request->WaitEvent = osd_WaitEventCreate(); + request->WaitEvent = osd_waitevent_create(); if (!request->WaitEvent) { kfree(request); return NULL; @@ -313,7 +313,7 @@ static void RndisFilterReceiveResponse(struct rndis_device *Device, } } - osd_WaitEventSet(request->WaitEvent); + osd_waitevent_set(request->WaitEvent); } else { DPRINT_ERR(NETVSC, "no rndis request found for this response " "(id 0x%x res type 0x%x)", @@ -497,7 +497,7 @@ static int RndisFilterQueryDevice(struct rndis_device *Device, u32 Oid, if (ret != 0) goto Cleanup; - osd_WaitEventWait(request->WaitEvent); + osd_waitevent_wait(request->WaitEvent); /* Copy the response back */ queryComplete = &request->ResponseMessage.Message.QueryComplete; @@ -572,7 +572,7 @@ static int RndisFilterSetPacketFilter(struct rndis_device *Device, if (ret != 0) goto Cleanup; - ret = osd_WaitEventWaitEx(request->WaitEvent, 2000/*2sec*/); + ret = osd_waitevent_waitex(request->WaitEvent, 2000/*2sec*/); if (!ret) { ret = -1; DPRINT_ERR(NETVSC, "timeout before we got a set response..."); @@ -665,7 +665,7 @@ static int RndisFilterInitDevice(struct rndis_device *Device) goto Cleanup; } - osd_WaitEventWait(request->WaitEvent); + osd_waitevent_wait(request->WaitEvent); initComplete = &request->ResponseMessage.Message.InitializeComplete; status = initComplete->Status; diff --git a/drivers/staging/hv/storvsc.c b/drivers/staging/hv/storvsc.c index 19e87f689fa0..525c8ee46f07 100644 --- a/drivers/staging/hv/storvsc.c +++ b/drivers/staging/hv/storvsc.c @@ -198,7 +198,7 @@ static int StorVscChannelInit(struct hv_device *Device) * channel */ memset(request, 0, sizeof(struct storvsc_request_extension)); - request->WaitEvent = osd_WaitEventCreate(); + request->WaitEvent = osd_waitevent_create(); if (!request->WaitEvent) { ret = -ENOMEM; goto nomem; @@ -224,7 +224,7 @@ static int StorVscChannelInit(struct hv_device *Device) goto Cleanup; } - osd_WaitEventWait(request->WaitEvent); + osd_waitevent_wait(request->WaitEvent); if (vstorPacket->Operation != VStorOperationCompleteIo || vstorPacket->Status != 0) { @@ -255,7 +255,7 @@ static int StorVscChannelInit(struct hv_device *Device) goto Cleanup; } - osd_WaitEventWait(request->WaitEvent); + osd_waitevent_wait(request->WaitEvent); /* TODO: Check returned version */ if (vstorPacket->Operation != VStorOperationCompleteIo || @@ -287,7 +287,7 @@ static int StorVscChannelInit(struct hv_device *Device) goto Cleanup; } - osd_WaitEventWait(request->WaitEvent); + osd_waitevent_wait(request->WaitEvent); /* TODO: Check returned version */ if (vstorPacket->Operation != VStorOperationCompleteIo || @@ -323,7 +323,7 @@ static int StorVscChannelInit(struct hv_device *Device) goto Cleanup; } - osd_WaitEventWait(request->WaitEvent); + osd_waitevent_wait(request->WaitEvent); if (vstorPacket->Operation != VStorOperationCompleteIo || vstorPacket->Status != 0) { @@ -473,7 +473,7 @@ static void StorVscOnChannelCallback(void *context) memcpy(&request->VStorPacket, packet, sizeof(struct vstor_packet)); - osd_WaitEventSet(request->WaitEvent); + osd_waitevent_set(request->WaitEvent); } else { StorVscOnReceive(device, (struct vstor_packet *)packet, @@ -622,7 +622,7 @@ int StorVscOnHostReset(struct hv_device *Device) request = &storDevice->ResetRequest; vstorPacket = &request->VStorPacket; - request->WaitEvent = osd_WaitEventCreate(); + request->WaitEvent = osd_waitevent_create(); if (!request->WaitEvent) { ret = -ENOMEM; goto Cleanup; @@ -644,7 +644,7 @@ int StorVscOnHostReset(struct hv_device *Device) } /* FIXME: Add a timeout */ - osd_WaitEventWait(request->WaitEvent); + osd_waitevent_wait(request->WaitEvent); kfree(request->WaitEvent); DPRINT_INFO(STORVSC, "host adapter reset completed"); -- cgit v1.2.3 From 82f8bd40a017716bfadcf074b4c6110ebe4c7ba6 Mon Sep 17 00:00:00 2001 From: Haiyang Zhang Date: Mon, 8 Nov 2010 14:04:45 -0800 Subject: staging: hv: Convert camel cased struct fields in ring_buffer.h to lower cases staging: hv: Convert camel cased struct fields in ring_buffer.h to lower cases Signed-off-by: Haiyang Zhang Signed-off-by: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/channel.c | 10 +++---- drivers/staging/hv/ring_buffer.c | 58 +++++++++++++++++++++------------------- drivers/staging/hv/ring_buffer.h | 30 ++++++++++----------- drivers/staging/hv/vmbus_drv.c | 25 +++++++++-------- 4 files changed, 65 insertions(+), 58 deletions(-) diff --git a/drivers/staging/hv/channel.c b/drivers/staging/hv/channel.c index abc2988b4d4a..0e554e91f1d8 100644 --- a/drivers/staging/hv/channel.c +++ b/drivers/staging/hv/channel.c @@ -213,7 +213,7 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size, newchannel->ringbuffer_gpadlhandle = 0; ret = vmbus_establish_gpadl(newchannel, - newchannel->outbound.RingBuffer, + newchannel->outbound.ring_buffer, send_ringbuffer_size + recv_ringbuffer_size, &newchannel->ringbuffer_gpadlhandle); @@ -227,10 +227,10 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size, "size %d recv ring %p size %d, downstreamoffset %d>", newchannel, newchannel->offermsg.child_relid, newchannel->ringbuffer_gpadlhandle, - newchannel->outbound.RingBuffer, - newchannel->outbound.RingSize, - newchannel->inbound.RingBuffer, - newchannel->inbound.RingSize, + newchannel->outbound.ring_buffer, + newchannel->outbound.ring_size, + newchannel->inbound.ring_buffer, + newchannel->inbound.ring_size, send_ringbuffer_size); /* Create and init the channel open message */ diff --git a/drivers/staging/hv/ring_buffer.c b/drivers/staging/hv/ring_buffer.c index d78c569ac94a..6095cc5ce711 100644 --- a/drivers/staging/hv/ring_buffer.c +++ b/drivers/staging/hv/ring_buffer.c @@ -51,11 +51,11 @@ GetRingBufferAvailBytes(struct hv_ring_buffer_info *rbi, u32 *read, u32 *write) u32 read_loc, write_loc; /* Capture the read/write indices before they changed */ - read_loc = rbi->RingBuffer->ReadIndex; - write_loc = rbi->RingBuffer->WriteIndex; + read_loc = rbi->ring_buffer->read_index; + write_loc = rbi->ring_buffer->write_index; - *write = BYTES_AVAIL_TO_WRITE(read_loc, write_loc, rbi->RingDataSize); - *read = rbi->RingDataSize - *write; + *write = BYTES_AVAIL_TO_WRITE(read_loc, write_loc, rbi->ring_datasize); + *read = rbi->ring_datasize - *write; } /*++ @@ -70,7 +70,7 @@ Description: static inline u32 GetNextWriteLocation(struct hv_ring_buffer_info *RingInfo) { - u32 next = RingInfo->RingBuffer->WriteIndex; + u32 next = RingInfo->ring_buffer->write_index; /* ASSERT(next < RingInfo->RingDataSize); */ @@ -90,7 +90,7 @@ static inline void SetNextWriteLocation(struct hv_ring_buffer_info *RingInfo, u32 NextWriteLocation) { - RingInfo->RingBuffer->WriteIndex = NextWriteLocation; + RingInfo->ring_buffer->write_index = NextWriteLocation; } /*++ @@ -105,7 +105,7 @@ Description: static inline u32 GetNextReadLocation(struct hv_ring_buffer_info *RingInfo) { - u32 next = RingInfo->RingBuffer->ReadIndex; + u32 next = RingInfo->ring_buffer->read_index; /* ASSERT(next < RingInfo->RingDataSize); */ @@ -125,11 +125,11 @@ Description: static inline u32 GetNextReadLocationWithOffset(struct hv_ring_buffer_info *RingInfo, u32 Offset) { - u32 next = RingInfo->RingBuffer->ReadIndex; + u32 next = RingInfo->ring_buffer->read_index; /* ASSERT(next < RingInfo->RingDataSize); */ next += Offset; - next %= RingInfo->RingDataSize; + next %= RingInfo->ring_datasize; return next; } @@ -146,7 +146,7 @@ Description: static inline void SetNextReadLocation(struct hv_ring_buffer_info *RingInfo, u32 NextReadLocation) { - RingInfo->RingBuffer->ReadIndex = NextReadLocation; + RingInfo->ring_buffer->read_index = NextReadLocation; } @@ -162,7 +162,7 @@ Description: static inline void * GetRingBuffer(struct hv_ring_buffer_info *RingInfo) { - return (void *)RingInfo->RingBuffer->Buffer; + return (void *)RingInfo->ring_buffer->buffer; } @@ -178,7 +178,7 @@ Description: static inline u32 GetRingBufferSize(struct hv_ring_buffer_info *RingInfo) { - return RingInfo->RingDataSize; + return RingInfo->ring_datasize; } /*++ @@ -193,7 +193,7 @@ Description: static inline u64 GetRingBufferIndices(struct hv_ring_buffer_info *RingInfo) { - return (u64)RingInfo->RingBuffer->WriteIndex << 32; + return (u64)RingInfo->ring_buffer->write_index << 32; } @@ -221,11 +221,11 @@ void DumpRingInfo(struct hv_ring_buffer_info *RingInfo, char *Prefix) "avail read %u read idx %u write idx %u>>", Prefix, RingInfo, - RingInfo->RingBuffer->Buffer, + RingInfo->ring_buffer->buffer, bytesAvailToWrite, bytesAvailToRead, - RingInfo->RingBuffer->ReadIndex, - RingInfo->RingBuffer->WriteIndex); + RingInfo->ring_buffer->read_index, + RingInfo->ring_buffer->write_index); } @@ -262,16 +262,19 @@ void RingBufferGetDebugInfo(struct hv_ring_buffer_info *RingInfo, u32 bytesAvailToWrite; u32 bytesAvailToRead; - if (RingInfo->RingBuffer) { + if (RingInfo->ring_buffer) { GetRingBufferAvailBytes(RingInfo, &bytesAvailToRead, &bytesAvailToWrite); - debug_info->BytesAvailToRead = bytesAvailToRead; - debug_info->BytesAvailToWrite = bytesAvailToWrite; - debug_info->CurrentReadIndex = RingInfo->RingBuffer->ReadIndex; - debug_info->CurrentWriteIndex = RingInfo->RingBuffer->WriteIndex; - debug_info->CurrentInterruptMask = RingInfo->RingBuffer->InterruptMask; + debug_info->bytes_avail_toread = bytesAvailToRead; + debug_info->bytes_avail_towrite = bytesAvailToWrite; + debug_info->current_read_index = + RingInfo->ring_buffer->read_index; + debug_info->current_write_index = + RingInfo->ring_buffer->write_index; + debug_info->current_interrupt_mask = + RingInfo->ring_buffer->interrupt_mask; } } @@ -287,7 +290,7 @@ Description: --*/ u32 GetRingBufferInterruptMask(struct hv_ring_buffer_info *rbi) { - return rbi->RingBuffer->InterruptMask; + return rbi->ring_buffer->interrupt_mask; } /*++ @@ -306,11 +309,12 @@ int RingBufferInit(struct hv_ring_buffer_info *RingInfo, void *Buffer, u32 Buffe memset(RingInfo, 0, sizeof(struct hv_ring_buffer_info)); - RingInfo->RingBuffer = (struct hv_ring_buffer *)Buffer; - RingInfo->RingBuffer->ReadIndex = RingInfo->RingBuffer->WriteIndex = 0; + RingInfo->ring_buffer = (struct hv_ring_buffer *)Buffer; + RingInfo->ring_buffer->read_index = + RingInfo->ring_buffer->write_index = 0; - RingInfo->RingSize = BufferLen; - RingInfo->RingDataSize = BufferLen - sizeof(struct hv_ring_buffer); + RingInfo->ring_size = BufferLen; + RingInfo->ring_datasize = BufferLen - sizeof(struct hv_ring_buffer); spin_lock_init(&RingInfo->ring_lock); diff --git a/drivers/staging/hv/ring_buffer.h b/drivers/staging/hv/ring_buffer.h index a7f1717c6a56..bb4c5bc484be 100644 --- a/drivers/staging/hv/ring_buffer.h +++ b/drivers/staging/hv/ring_buffer.h @@ -29,18 +29,18 @@ struct hv_ring_buffer { /* Offset in bytes from the start of ring data below */ - volatile u32 WriteIndex; + volatile u32 write_index; /* Offset in bytes from the start of ring data below */ - volatile u32 ReadIndex; + volatile u32 read_index; - volatile u32 InterruptMask; + volatile u32 interrupt_mask; /* Pad it to PAGE_SIZE so that data starts on page boundary */ - u8 Reserved[4084]; + u8 reserved[4084]; /* NOTE: - * The InterruptMask field is used only for channels but since our + * The interrupt_mask field is used only for channels but since our * vmbus connection also uses this data structure and its data starts * here, we commented out this field. */ @@ -50,24 +50,24 @@ struct hv_ring_buffer { * Ring data starts here + RingDataStartOffset * !!! DO NOT place any fields below this !!! */ - u8 Buffer[0]; + u8 buffer[0]; } __attribute__((packed)); struct hv_ring_buffer_info { - struct hv_ring_buffer *RingBuffer; - u32 RingSize; /* Include the shared header */ + struct hv_ring_buffer *ring_buffer; + u32 ring_size; /* Include the shared header */ spinlock_t ring_lock; - u32 RingDataSize; /* < ringSize */ - u32 RingDataStartOffset; + u32 ring_datasize; /* < ring_size */ + u32 ring_data_startoffset; }; struct hv_ring_buffer_debug_info { - u32 CurrentInterruptMask; - u32 CurrentReadIndex; - u32 CurrentWriteIndex; - u32 BytesAvailToRead; - u32 BytesAvailToWrite; + u32 current_interrupt_mask; + u32 current_read_index; + u32 current_write_index; + u32 bytes_avail_toread; + u32 bytes_avail_towrite; }; diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c index 2bbf4ecdf550..096587592e23 100644 --- a/drivers/staging/hv/vmbus_drv.c +++ b/drivers/staging/hv/vmbus_drv.c @@ -156,18 +156,21 @@ static void get_channel_info(struct hv_device *device, info->ClientMonitorLatency = debug_info.clientmonitor_latency; info->ClientMonitorConnectionId = debug_info.clientmonitor_connectionid; - info->Inbound.InterruptMask = debug_info.inbound.CurrentInterruptMask; - info->Inbound.ReadIndex = debug_info.inbound.CurrentReadIndex; - info->Inbound.WriteIndex = debug_info.inbound.CurrentWriteIndex; - info->Inbound.BytesAvailToRead = debug_info.inbound.BytesAvailToRead; - info->Inbound.BytesAvailToWrite = debug_info.inbound.BytesAvailToWrite; - - info->Outbound.InterruptMask = debug_info.outbound.CurrentInterruptMask; - info->Outbound.ReadIndex = debug_info.outbound.CurrentReadIndex; - info->Outbound.WriteIndex = debug_info.outbound.CurrentWriteIndex; - info->Outbound.BytesAvailToRead = debug_info.outbound.BytesAvailToRead; + info->Inbound.InterruptMask = debug_info.inbound.current_interrupt_mask; + info->Inbound.ReadIndex = debug_info.inbound.current_read_index; + info->Inbound.WriteIndex = debug_info.inbound.current_write_index; + info->Inbound.BytesAvailToRead = debug_info.inbound.bytes_avail_toread; + info->Inbound.BytesAvailToWrite = + debug_info.inbound.bytes_avail_towrite; + + info->Outbound.InterruptMask = + debug_info.outbound.current_interrupt_mask; + info->Outbound.ReadIndex = debug_info.outbound.current_read_index; + info->Outbound.WriteIndex = debug_info.outbound.current_write_index; + info->Outbound.BytesAvailToRead = + debug_info.outbound.bytes_avail_toread; info->Outbound.BytesAvailToWrite = - debug_info.outbound.BytesAvailToWrite; + debug_info.outbound.bytes_avail_towrite; } /* -- cgit v1.2.3 From fc8c72ebfa7547c044bab48fb8bba6906123f8c7 Mon Sep 17 00:00:00 2001 From: Haiyang Zhang Date: Mon, 8 Nov 2010 14:04:46 -0800 Subject: staging: hv: Convert camel cased local variables in ring_buffer.c to lower cases staging: hv: Convert camel cased local variables in ring_buffer.c to lower cases Signed-off-by: Haiyang Zhang Signed-off-by: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/channel.c | 4 +- drivers/staging/hv/ring_buffer.c | 337 ++++++++++++++++++++------------------- drivers/staging/hv/ring_buffer.h | 26 +-- 3 files changed, 185 insertions(+), 182 deletions(-) diff --git a/drivers/staging/hv/channel.c b/drivers/staging/hv/channel.c index 0e554e91f1d8..97db545a516c 100644 --- a/drivers/staging/hv/channel.c +++ b/drivers/staging/hv/channel.c @@ -1052,6 +1052,6 @@ void vmbus_ontimer(unsigned long data) static void dump_vmbus_channel(struct vmbus_channel *channel) { DPRINT_DBG(VMBUS, "Channel (%d)", channel->offermsg.child_relid); - DumpRingInfo(&channel->outbound, "Outbound "); - DumpRingInfo(&channel->inbound, "Inbound "); + Dumpring_info(&channel->outbound, "Outbound "); + Dumpring_info(&channel->inbound, "Inbound "); } diff --git a/drivers/staging/hv/ring_buffer.c b/drivers/staging/hv/ring_buffer.c index 6095cc5ce711..705d95f053fd 100644 --- a/drivers/staging/hv/ring_buffer.c +++ b/drivers/staging/hv/ring_buffer.c @@ -68,11 +68,11 @@ Description: --*/ static inline u32 -GetNextWriteLocation(struct hv_ring_buffer_info *RingInfo) +GetNextWriteLocation(struct hv_ring_buffer_info *ring_info) { - u32 next = RingInfo->ring_buffer->write_index; + u32 next = ring_info->ring_buffer->write_index; - /* ASSERT(next < RingInfo->RingDataSize); */ + /* ASSERT(next < ring_info->RingDataSize); */ return next; } @@ -87,10 +87,10 @@ Description: --*/ static inline void -SetNextWriteLocation(struct hv_ring_buffer_info *RingInfo, - u32 NextWriteLocation) +SetNextWriteLocation(struct hv_ring_buffer_info *ring_info, + u32 next_write_location) { - RingInfo->ring_buffer->write_index = NextWriteLocation; + ring_info->ring_buffer->write_index = next_write_location; } /*++ @@ -103,11 +103,11 @@ Description: --*/ static inline u32 -GetNextReadLocation(struct hv_ring_buffer_info *RingInfo) +GetNextReadLocation(struct hv_ring_buffer_info *ring_info) { - u32 next = RingInfo->ring_buffer->read_index; + u32 next = ring_info->ring_buffer->read_index; - /* ASSERT(next < RingInfo->RingDataSize); */ + /* ASSERT(next < ring_info->RingDataSize); */ return next; } @@ -123,13 +123,13 @@ Description: --*/ static inline u32 -GetNextReadLocationWithOffset(struct hv_ring_buffer_info *RingInfo, u32 Offset) +GetNextReadLocationWithOffset(struct hv_ring_buffer_info *ring_info, u32 offset) { - u32 next = RingInfo->ring_buffer->read_index; + u32 next = ring_info->ring_buffer->read_index; - /* ASSERT(next < RingInfo->RingDataSize); */ - next += Offset; - next %= RingInfo->ring_datasize; + /* ASSERT(next < ring_info->RingDataSize); */ + next += offset; + next %= ring_info->ring_datasize; return next; } @@ -144,9 +144,10 @@ Description: --*/ static inline void -SetNextReadLocation(struct hv_ring_buffer_info *RingInfo, u32 NextReadLocation) +SetNextReadLocation(struct hv_ring_buffer_info *ring_info, + u32 next_read_location) { - RingInfo->ring_buffer->read_index = NextReadLocation; + ring_info->ring_buffer->read_index = next_read_location; } @@ -160,9 +161,9 @@ Description: --*/ static inline void * -GetRingBuffer(struct hv_ring_buffer_info *RingInfo) +GetRingBuffer(struct hv_ring_buffer_info *ring_info) { - return (void *)RingInfo->ring_buffer->buffer; + return (void *)ring_info->ring_buffer->buffer; } @@ -176,9 +177,9 @@ Description: --*/ static inline u32 -GetRingBufferSize(struct hv_ring_buffer_info *RingInfo) +GetRingBufferSize(struct hv_ring_buffer_info *ring_info) { - return RingInfo->ring_datasize; + return ring_info->ring_datasize; } /*++ @@ -191,41 +192,41 @@ Description: --*/ static inline u64 -GetRingBufferIndices(struct hv_ring_buffer_info *RingInfo) +GetRingBufferIndices(struct hv_ring_buffer_info *ring_info) { - return (u64)RingInfo->ring_buffer->write_index << 32; + return (u64)ring_info->ring_buffer->write_index << 32; } /*++ Name: - DumpRingInfo() + Dumpring_info() Description: Dump out to console the ring buffer info --*/ -void DumpRingInfo(struct hv_ring_buffer_info *RingInfo, char *Prefix) +void Dumpring_info(struct hv_ring_buffer_info *ring_info, char *prefix) { - u32 bytesAvailToWrite; - u32 bytesAvailToRead; + u32 bytes_avail_towrite; + u32 bytes_avail_toread; - GetRingBufferAvailBytes(RingInfo, - &bytesAvailToRead, - &bytesAvailToWrite); + GetRingBufferAvailBytes(ring_info, + &bytes_avail_toread, + &bytes_avail_towrite); DPRINT(VMBUS, DEBUG_RING_LVL, "%s <>", - Prefix, - RingInfo, - RingInfo->ring_buffer->buffer, - bytesAvailToWrite, - bytesAvailToRead, - RingInfo->ring_buffer->read_index, - RingInfo->ring_buffer->write_index); + prefix, + ring_info, + ring_info->ring_buffer->buffer, + bytes_avail_towrite, + bytes_avail_toread, + ring_info->ring_buffer->read_index, + ring_info->ring_buffer->write_index); } @@ -233,17 +234,17 @@ void DumpRingInfo(struct hv_ring_buffer_info *RingInfo, char *Prefix) static u32 CopyToRingBuffer( - struct hv_ring_buffer_info *RingInfo, - u32 StartWriteOffset, - void *Src, - u32 SrcLen); + struct hv_ring_buffer_info *ring_info, + u32 start_write_offset, + void *src, + u32 srclen); static u32 CopyFromRingBuffer( - struct hv_ring_buffer_info *RingInfo, - void *Dest, - u32 DestLen, - u32 StartReadOffset); + struct hv_ring_buffer_info *ring_info, + void *dest, + u32 destlen, + u32 start_read_offset); @@ -256,25 +257,25 @@ Description: Get various debug metrics for the specified ring buffer --*/ -void RingBufferGetDebugInfo(struct hv_ring_buffer_info *RingInfo, +void RingBufferGetDebugInfo(struct hv_ring_buffer_info *ring_info, struct hv_ring_buffer_debug_info *debug_info) { - u32 bytesAvailToWrite; - u32 bytesAvailToRead; + u32 bytes_avail_towrite; + u32 bytes_avail_toread; - if (RingInfo->ring_buffer) { - GetRingBufferAvailBytes(RingInfo, - &bytesAvailToRead, - &bytesAvailToWrite); + if (ring_info->ring_buffer) { + GetRingBufferAvailBytes(ring_info, + &bytes_avail_toread, + &bytes_avail_towrite); - debug_info->bytes_avail_toread = bytesAvailToRead; - debug_info->bytes_avail_towrite = bytesAvailToWrite; + debug_info->bytes_avail_toread = bytes_avail_toread; + debug_info->bytes_avail_towrite = bytes_avail_towrite; debug_info->current_read_index = - RingInfo->ring_buffer->read_index; + ring_info->ring_buffer->read_index; debug_info->current_write_index = - RingInfo->ring_buffer->write_index; + ring_info->ring_buffer->write_index; debug_info->current_interrupt_mask = - RingInfo->ring_buffer->interrupt_mask; + ring_info->ring_buffer->interrupt_mask; } } @@ -302,21 +303,22 @@ Description: Initialize the ring buffer --*/ -int RingBufferInit(struct hv_ring_buffer_info *RingInfo, void *Buffer, u32 BufferLen) +int RingBufferInit(struct hv_ring_buffer_info *ring_info, + void *buffer, u32 buflen) { if (sizeof(struct hv_ring_buffer) != PAGE_SIZE) return -EINVAL; - memset(RingInfo, 0, sizeof(struct hv_ring_buffer_info)); + memset(ring_info, 0, sizeof(struct hv_ring_buffer_info)); - RingInfo->ring_buffer = (struct hv_ring_buffer *)Buffer; - RingInfo->ring_buffer->read_index = - RingInfo->ring_buffer->write_index = 0; + ring_info->ring_buffer = (struct hv_ring_buffer *)buffer; + ring_info->ring_buffer->read_index = + ring_info->ring_buffer->write_index = 0; - RingInfo->ring_size = BufferLen; - RingInfo->ring_datasize = BufferLen - sizeof(struct hv_ring_buffer); + ring_info->ring_size = buflen; + ring_info->ring_datasize = buflen - sizeof(struct hv_ring_buffer); - spin_lock_init(&RingInfo->ring_lock); + spin_lock_init(&ring_info->ring_lock); return 0; } @@ -330,7 +332,7 @@ Description: Cleanup the ring buffer --*/ -void RingBufferCleanup(struct hv_ring_buffer_info *RingInfo) +void RingBufferCleanup(struct hv_ring_buffer_info *ring_info) { } @@ -343,78 +345,78 @@ Description: Write to the ring buffer --*/ -int RingBufferWrite(struct hv_ring_buffer_info *OutRingInfo, +int RingBufferWrite(struct hv_ring_buffer_info *outring_info, struct scatterlist *sglist, u32 sgcount) { int i = 0; - u32 byteAvailToWrite; - u32 byteAvailToRead; - u32 totalBytesToWrite = 0; + u32 bytes_avail_towrite; + u32 bytes_avail_toread; + u32 totalbytes_towrite = 0; struct scatterlist *sg; - volatile u32 nextWriteLocation; - u64 prevIndices = 0; + volatile u32 next_write_location; + u64 prev_indices = 0; unsigned long flags; for_each_sg(sglist, sg, sgcount, i) { - totalBytesToWrite += sg->length; + totalbytes_towrite += sg->length; } - totalBytesToWrite += sizeof(u64); + totalbytes_towrite += sizeof(u64); - spin_lock_irqsave(&OutRingInfo->ring_lock, flags); + spin_lock_irqsave(&outring_info->ring_lock, flags); - GetRingBufferAvailBytes(OutRingInfo, - &byteAvailToRead, - &byteAvailToWrite); + GetRingBufferAvailBytes(outring_info, + &bytes_avail_toread, + &bytes_avail_towrite); - DPRINT_DBG(VMBUS, "Writing %u bytes...", totalBytesToWrite); + DPRINT_DBG(VMBUS, "Writing %u bytes...", totalbytes_towrite); - /* DumpRingInfo(OutRingInfo, "BEFORE "); */ + /* Dumpring_info(Outring_info, "BEFORE "); */ /* If there is only room for the packet, assume it is full. */ /* Otherwise, the next time around, we think the ring buffer */ /* is empty since the read index == write index */ - if (byteAvailToWrite <= totalBytesToWrite) { + if (bytes_avail_towrite <= totalbytes_towrite) { DPRINT_DBG(VMBUS, "No more space left on outbound ring buffer " "(needed %u, avail %u)", - totalBytesToWrite, - byteAvailToWrite); + totalbytes_towrite, + bytes_avail_towrite); - spin_unlock_irqrestore(&OutRingInfo->ring_lock, flags); + spin_unlock_irqrestore(&outring_info->ring_lock, flags); return -1; } /* Write to the ring buffer */ - nextWriteLocation = GetNextWriteLocation(OutRingInfo); + next_write_location = GetNextWriteLocation(outring_info); for_each_sg(sglist, sg, sgcount, i) { - nextWriteLocation = CopyToRingBuffer(OutRingInfo, - nextWriteLocation, + next_write_location = CopyToRingBuffer(outring_info, + next_write_location, sg_virt(sg), sg->length); } /* Set previous packet start */ - prevIndices = GetRingBufferIndices(OutRingInfo); + prev_indices = GetRingBufferIndices(outring_info); - nextWriteLocation = CopyToRingBuffer(OutRingInfo, - nextWriteLocation, - &prevIndices, + next_write_location = CopyToRingBuffer(outring_info, + next_write_location, + &prev_indices, sizeof(u64)); /* Make sure we flush all writes before updating the writeIndex */ mb(); /* Now, update the write location */ - SetNextWriteLocation(OutRingInfo, nextWriteLocation); + SetNextWriteLocation(outring_info, next_write_location); - /* DumpRingInfo(OutRingInfo, "AFTER "); */ + /* Dumpring_info(Outring_info, "AFTER "); */ - spin_unlock_irqrestore(&OutRingInfo->ring_lock, flags); + spin_unlock_irqrestore(&outring_info->ring_lock, flags); return 0; } @@ -428,41 +430,42 @@ Description: Read without advancing the read index --*/ -int RingBufferPeek(struct hv_ring_buffer_info *InRingInfo, void *Buffer, u32 BufferLen) +int RingBufferPeek(struct hv_ring_buffer_info *Inring_info, + void *Buffer, u32 buflen) { - u32 bytesAvailToWrite; - u32 bytesAvailToRead; - u32 nextReadLocation = 0; + u32 bytes_avail_towrite; + u32 bytes_avail_toread; + u32 next_read_location = 0; unsigned long flags; - spin_lock_irqsave(&InRingInfo->ring_lock, flags); + spin_lock_irqsave(&Inring_info->ring_lock, flags); - GetRingBufferAvailBytes(InRingInfo, - &bytesAvailToRead, - &bytesAvailToWrite); + GetRingBufferAvailBytes(Inring_info, + &bytes_avail_toread, + &bytes_avail_towrite); /* Make sure there is something to read */ - if (bytesAvailToRead < BufferLen) { + if (bytes_avail_toread < buflen) { /* DPRINT_DBG(VMBUS, "got callback but not enough to read " "!!", - bytesAvailToRead, + bytes_avail_toread, BufferLen); */ - spin_unlock_irqrestore(&InRingInfo->ring_lock, flags); + spin_unlock_irqrestore(&Inring_info->ring_lock, flags); return -1; } /* Convert to byte offset */ - nextReadLocation = GetNextReadLocation(InRingInfo); + next_read_location = GetNextReadLocation(Inring_info); - nextReadLocation = CopyFromRingBuffer(InRingInfo, + next_read_location = CopyFromRingBuffer(Inring_info, Buffer, - BufferLen, - nextReadLocation); + buflen, + next_read_location); - spin_unlock_irqrestore(&InRingInfo->ring_lock, flags); + spin_unlock_irqrestore(&Inring_info->ring_lock, flags); return 0; } @@ -477,52 +480,52 @@ Description: Read and advance the read index --*/ -int RingBufferRead(struct hv_ring_buffer_info *InRingInfo, void *Buffer, - u32 BufferLen, u32 Offset) +int RingBufferRead(struct hv_ring_buffer_info *inring_info, void *buffer, + u32 buflen, u32 offset) { - u32 bytesAvailToWrite; - u32 bytesAvailToRead; - u32 nextReadLocation = 0; - u64 prevIndices = 0; + u32 bytes_avail_towrite; + u32 bytes_avail_toread; + u32 next_read_location = 0; + u64 prev_indices = 0; unsigned long flags; - if (BufferLen <= 0) + if (buflen <= 0) return -EINVAL; - spin_lock_irqsave(&InRingInfo->ring_lock, flags); + spin_lock_irqsave(&inring_info->ring_lock, flags); - GetRingBufferAvailBytes(InRingInfo, - &bytesAvailToRead, - &bytesAvailToWrite); + GetRingBufferAvailBytes(inring_info, + &bytes_avail_toread, + &bytes_avail_towrite); - DPRINT_DBG(VMBUS, "Reading %u bytes...", BufferLen); + DPRINT_DBG(VMBUS, "Reading %u bytes...", buflen); - /* DumpRingInfo(InRingInfo, "BEFORE "); */ + /* Dumpring_info(Inring_info, "BEFORE "); */ /* Make sure there is something to read */ - if (bytesAvailToRead < BufferLen) { + if (bytes_avail_toread < buflen) { DPRINT_DBG(VMBUS, "got callback but not enough to read " "!!", - bytesAvailToRead, - BufferLen); + bytes_avail_toread, + buflen); - spin_unlock_irqrestore(&InRingInfo->ring_lock, flags); + spin_unlock_irqrestore(&inring_info->ring_lock, flags); return -1; } - nextReadLocation = GetNextReadLocationWithOffset(InRingInfo, Offset); + next_read_location = GetNextReadLocationWithOffset(inring_info, offset); - nextReadLocation = CopyFromRingBuffer(InRingInfo, - Buffer, - BufferLen, - nextReadLocation); + next_read_location = CopyFromRingBuffer(inring_info, + buffer, + buflen, + next_read_location); - nextReadLocation = CopyFromRingBuffer(InRingInfo, - &prevIndices, + next_read_location = CopyFromRingBuffer(inring_info, + &prev_indices, sizeof(u64), - nextReadLocation); + next_read_location); /* Make sure all reads are done before we update the read index since */ /* the writer may start writing to the read area once the read index */ @@ -530,11 +533,11 @@ int RingBufferRead(struct hv_ring_buffer_info *InRingInfo, void *Buffer, mb(); /* Update the read index */ - SetNextReadLocation(InRingInfo, nextReadLocation); + SetNextReadLocation(inring_info, next_read_location); - /* DumpRingInfo(InRingInfo, "AFTER "); */ + /* Dumpring_info(Inring_info, "AFTER "); */ - spin_unlock_irqrestore(&InRingInfo->ring_lock, flags); + spin_unlock_irqrestore(&inring_info->ring_lock, flags); return 0; } @@ -552,29 +555,29 @@ Description: --*/ static u32 CopyToRingBuffer( - struct hv_ring_buffer_info *RingInfo, - u32 StartWriteOffset, - void *Src, - u32 SrcLen) + struct hv_ring_buffer_info *ring_info, + u32 start_write_offset, + void *src, + u32 srclen) { - void *ringBuffer = GetRingBuffer(RingInfo); - u32 ringBufferSize = GetRingBufferSize(RingInfo); - u32 fragLen; + void *ring_buffer = GetRingBuffer(ring_info); + u32 ring_buffer_size = GetRingBufferSize(ring_info); + u32 frag_len; /* wrap-around detected! */ - if (SrcLen > ringBufferSize - StartWriteOffset) { + if (srclen > ring_buffer_size - start_write_offset) { DPRINT_DBG(VMBUS, "wrap-around detected!"); - fragLen = ringBufferSize - StartWriteOffset; - memcpy(ringBuffer + StartWriteOffset, Src, fragLen); - memcpy(ringBuffer, Src + fragLen, SrcLen - fragLen); + frag_len = ring_buffer_size - start_write_offset; + memcpy(ring_buffer + start_write_offset, src, frag_len); + memcpy(ring_buffer, src + frag_len, srclen - frag_len); } else - memcpy(ringBuffer + StartWriteOffset, Src, SrcLen); + memcpy(ring_buffer + start_write_offset, src, srclen); - StartWriteOffset += SrcLen; - StartWriteOffset %= ringBufferSize; + start_write_offset += srclen; + start_write_offset %= ring_buffer_size; - return StartWriteOffset; + return start_write_offset; } @@ -590,33 +593,33 @@ Description: --*/ static u32 CopyFromRingBuffer( - struct hv_ring_buffer_info *RingInfo, - void *Dest, - u32 DestLen, - u32 StartReadOffset) + struct hv_ring_buffer_info *ring_info, + void *dest, + u32 destlen, + u32 start_read_offset) { - void *ringBuffer = GetRingBuffer(RingInfo); - u32 ringBufferSize = GetRingBufferSize(RingInfo); + void *ring_buffer = GetRingBuffer(ring_info); + u32 ring_buffer_size = GetRingBufferSize(ring_info); - u32 fragLen; + u32 frag_len; /* wrap-around detected at the src */ - if (DestLen > ringBufferSize - StartReadOffset) { + if (destlen > ring_buffer_size - start_read_offset) { DPRINT_DBG(VMBUS, "src wrap-around detected!"); - fragLen = ringBufferSize - StartReadOffset; + frag_len = ring_buffer_size - start_read_offset; - memcpy(Dest, ringBuffer + StartReadOffset, fragLen); - memcpy(Dest + fragLen, ringBuffer, DestLen - fragLen); + memcpy(dest, ring_buffer + start_read_offset, frag_len); + memcpy(dest + frag_len, ring_buffer, destlen - frag_len); } else - memcpy(Dest, ringBuffer + StartReadOffset, DestLen); + memcpy(dest, ring_buffer + start_read_offset, destlen); - StartReadOffset += DestLen; - StartReadOffset %= ringBufferSize; + start_read_offset += destlen; + start_read_offset %= ring_buffer_size; - return StartReadOffset; + return start_read_offset; } diff --git a/drivers/staging/hv/ring_buffer.h b/drivers/staging/hv/ring_buffer.h index bb4c5bc484be..f30be1fa0744 100644 --- a/drivers/staging/hv/ring_buffer.h +++ b/drivers/staging/hv/ring_buffer.h @@ -75,28 +75,28 @@ struct hv_ring_buffer_debug_info { /* Interface */ -int RingBufferInit(struct hv_ring_buffer_info *RingInfo, void *Buffer, - u32 BufferLen); +int RingBufferInit(struct hv_ring_buffer_info *ring_info, void *buffer, + u32 buflen); -void RingBufferCleanup(struct hv_ring_buffer_info *RingInfo); +void RingBufferCleanup(struct hv_ring_buffer_info *ring_info); -int RingBufferWrite(struct hv_ring_buffer_info *RingInfo, +int RingBufferWrite(struct hv_ring_buffer_info *ring_info, struct scatterlist *sglist, u32 sgcount); -int RingBufferPeek(struct hv_ring_buffer_info *RingInfo, void *Buffer, - u32 BufferLen); +int RingBufferPeek(struct hv_ring_buffer_info *ring_info, void *buffer, + u32 buflen); -int RingBufferRead(struct hv_ring_buffer_info *RingInfo, - void *Buffer, - u32 BufferLen, - u32 Offset); +int RingBufferRead(struct hv_ring_buffer_info *ring_info, + void *buffer, + u32 buflen, + u32 offset); -u32 GetRingBufferInterruptMask(struct hv_ring_buffer_info *RingInfo); +u32 GetRingBufferInterruptMask(struct hv_ring_buffer_info *ring_info); -void DumpRingInfo(struct hv_ring_buffer_info *RingInfo, char *Prefix); +void Dumpring_info(struct hv_ring_buffer_info *ring_info, char *prefix); -void RingBufferGetDebugInfo(struct hv_ring_buffer_info *RingInfo, +void RingBufferGetDebugInfo(struct hv_ring_buffer_info *ring_info, struct hv_ring_buffer_debug_info *debug_info); #endif /* _RING_BUFFER_H_ */ -- cgit v1.2.3 From 1ac586445db8e46f0007855c5c7161ff55484836 Mon Sep 17 00:00:00 2001 From: Haiyang Zhang Date: Mon, 8 Nov 2010 14:04:47 -0800 Subject: staging: hv: Convert camel cased functions in ring_buffer.c to lower cases staging: hv: Convert camel cased functions in ring_buffer.c to lower cases Signed-off-by: Haiyang Zhang Signed-off-by: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/channel.c | 40 ++++++------- drivers/staging/hv/ring_buffer.c | 123 ++++++++++++++++++++------------------- drivers/staging/hv/ring_buffer.h | 16 ++--- 3 files changed, 91 insertions(+), 88 deletions(-) diff --git a/drivers/staging/hv/channel.c b/drivers/staging/hv/channel.c index 97db545a516c..45a627d77b41 100644 --- a/drivers/staging/hv/channel.c +++ b/drivers/staging/hv/channel.c @@ -155,8 +155,8 @@ void vmbus_get_debug_info(struct vmbus_channel *channel, monitorpage->parameter[monitor_group] [monitor_offset].connectionid.u.id; - RingBufferGetDebugInfo(&channel->inbound, &debuginfo->inbound); - RingBufferGetDebugInfo(&channel->outbound, &debuginfo->outbound); + ringbuffer_get_debuginfo(&channel->inbound, &debuginfo->inbound); + ringbuffer_get_debuginfo(&channel->outbound, &debuginfo->outbound); } /* @@ -193,13 +193,13 @@ int vmbus_open(struct vmbus_channel *newchannel, u32 send_ringbuffer_size, newchannel->ringbuffer_pagecount = (send_ringbuffer_size + recv_ringbuffer_size) >> PAGE_SHIFT; - ret = RingBufferInit(&newchannel->outbound, out, send_ringbuffer_size); + ret = ringbuffer_init(&newchannel->outbound, out, send_ringbuffer_size); if (ret != 0) { err = ret; goto errorout; } - ret = RingBufferInit(&newchannel->inbound, in, recv_ringbuffer_size); + ret = ringbuffer_init(&newchannel->inbound, in, recv_ringbuffer_size); if (ret != 0) { err = ret; goto errorout; @@ -298,8 +298,8 @@ Cleanup: return 0; errorout: - RingBufferCleanup(&newchannel->outbound); - RingBufferCleanup(&newchannel->inbound); + ringbuffer_cleanup(&newchannel->outbound); + ringbuffer_cleanup(&newchannel->inbound); osd_page_free(out, (send_ringbuffer_size + recv_ringbuffer_size) >> PAGE_SHIFT); kfree(openInfo); @@ -683,8 +683,8 @@ void vmbus_close(struct vmbus_channel *channel) /* TODO: Send a msg to release the childRelId */ /* Cleanup the ring buffers for this channel */ - RingBufferCleanup(&channel->outbound); - RingBufferCleanup(&channel->inbound); + ringbuffer_cleanup(&channel->outbound); + ringbuffer_cleanup(&channel->inbound); osd_page_free(channel->ringbuffer_pages, channel->ringbuffer_pagecount); @@ -752,10 +752,10 @@ int vmbus_sendpacket(struct vmbus_channel *channel, const void *buffer, sg_set_buf(&bufferlist[2], &aligned_data, packetlen_aligned - packetlen); - ret = RingBufferWrite(&channel->outbound, bufferlist, 3); + ret = ringbuffer_write(&channel->outbound, bufferlist, 3); /* TODO: We should determine if this is optional */ - if (ret == 0 && !GetRingBufferInterruptMask(&channel->outbound)) + if (ret == 0 && !get_ringbuffer_interrupt_mask(&channel->outbound)) vmbus_setevent(channel); return ret; @@ -817,10 +817,10 @@ int vmbus_sendpacket_pagebuffer(struct vmbus_channel *channel, sg_set_buf(&bufferlist[2], &aligned_data, packetlen_aligned - packetlen); - ret = RingBufferWrite(&channel->outbound, bufferlist, 3); + ret = ringbuffer_write(&channel->outbound, bufferlist, 3); /* TODO: We should determine if this is optional */ - if (ret == 0 && !GetRingBufferInterruptMask(&channel->outbound)) + if (ret == 0 && !get_ringbuffer_interrupt_mask(&channel->outbound)) vmbus_setevent(channel); return ret; @@ -886,10 +886,10 @@ int vmbus_sendpacket_multipagebuffer(struct vmbus_channel *channel, sg_set_buf(&bufferlist[2], &aligned_data, packetlen_aligned - packetlen); - ret = RingBufferWrite(&channel->outbound, bufferlist, 3); + ret = ringbuffer_write(&channel->outbound, bufferlist, 3); /* TODO: We should determine if this is optional */ - if (ret == 0 && !GetRingBufferInterruptMask(&channel->outbound)) + if (ret == 0 && !get_ringbuffer_interrupt_mask(&channel->outbound)) vmbus_setevent(channel); return ret; @@ -923,7 +923,7 @@ int vmbus_recvpacket(struct vmbus_channel *channel, void *buffer, spin_lock_irqsave(&channel->inbound_lock, flags); - ret = RingBufferPeek(&channel->inbound, &desc, + ret = ringbuffer_peek(&channel->inbound, &desc, sizeof(struct vmpacket_descriptor)); if (ret != 0) { spin_unlock_irqrestore(&channel->inbound_lock, flags); @@ -956,7 +956,7 @@ int vmbus_recvpacket(struct vmbus_channel *channel, void *buffer, *requestid = desc.TransactionId; /* Copy over the packet to the user buffer */ - ret = RingBufferRead(&channel->inbound, buffer, userlen, + ret = ringbuffer_read(&channel->inbound, buffer, userlen, (desc.DataOffset8 << 3)); spin_unlock_irqrestore(&channel->inbound_lock, flags); @@ -983,7 +983,7 @@ int vmbus_recvpacket_raw(struct vmbus_channel *channel, void *buffer, spin_lock_irqsave(&channel->inbound_lock, flags); - ret = RingBufferPeek(&channel->inbound, &desc, + ret = ringbuffer_peek(&channel->inbound, &desc, sizeof(struct vmpacket_descriptor)); if (ret != 0) { spin_unlock_irqrestore(&channel->inbound_lock, flags); @@ -1015,7 +1015,7 @@ int vmbus_recvpacket_raw(struct vmbus_channel *channel, void *buffer, *requestid = desc.TransactionId; /* Copy over the entire packet to the user buffer */ - ret = RingBufferRead(&channel->inbound, buffer, packetlen, 0); + ret = ringbuffer_read(&channel->inbound, buffer, packetlen, 0); spin_unlock_irqrestore(&channel->inbound_lock, flags); return 0; @@ -1052,6 +1052,6 @@ void vmbus_ontimer(unsigned long data) static void dump_vmbus_channel(struct vmbus_channel *channel) { DPRINT_DBG(VMBUS, "Channel (%d)", channel->offermsg.child_relid); - Dumpring_info(&channel->outbound, "Outbound "); - Dumpring_info(&channel->inbound, "Inbound "); + dump_ring_info(&channel->outbound, "Outbound "); + dump_ring_info(&channel->inbound, "Inbound "); } diff --git a/drivers/staging/hv/ring_buffer.c b/drivers/staging/hv/ring_buffer.c index 705d95f053fd..4d53392f1e60 100644 --- a/drivers/staging/hv/ring_buffer.c +++ b/drivers/staging/hv/ring_buffer.c @@ -38,7 +38,7 @@ /*++ Name: - GetRingBufferAvailBytes() + get_ringbuffer_availbytes() Description: Get number of bytes available to read and to write to @@ -46,7 +46,8 @@ Description: --*/ static inline void -GetRingBufferAvailBytes(struct hv_ring_buffer_info *rbi, u32 *read, u32 *write) +get_ringbuffer_availbytes(struct hv_ring_buffer_info *rbi, + u32 *read, u32 *write) { u32 read_loc, write_loc; @@ -61,14 +62,14 @@ GetRingBufferAvailBytes(struct hv_ring_buffer_info *rbi, u32 *read, u32 *write) /*++ Name: - GetNextWriteLocation() + get_next_write_location() Description: Get the next write location for the specified ring buffer --*/ static inline u32 -GetNextWriteLocation(struct hv_ring_buffer_info *ring_info) +get_next_write_location(struct hv_ring_buffer_info *ring_info) { u32 next = ring_info->ring_buffer->write_index; @@ -80,14 +81,14 @@ GetNextWriteLocation(struct hv_ring_buffer_info *ring_info) /*++ Name: - SetNextWriteLocation() + set_next_write_location() Description: Set the next write location for the specified ring buffer --*/ static inline void -SetNextWriteLocation(struct hv_ring_buffer_info *ring_info, +set_next_write_location(struct hv_ring_buffer_info *ring_info, u32 next_write_location) { ring_info->ring_buffer->write_index = next_write_location; @@ -96,14 +97,14 @@ SetNextWriteLocation(struct hv_ring_buffer_info *ring_info, /*++ Name: - GetNextReadLocation() + get_next_read_location() Description: Get the next read location for the specified ring buffer --*/ static inline u32 -GetNextReadLocation(struct hv_ring_buffer_info *ring_info) +get_next_read_location(struct hv_ring_buffer_info *ring_info) { u32 next = ring_info->ring_buffer->read_index; @@ -115,7 +116,7 @@ GetNextReadLocation(struct hv_ring_buffer_info *ring_info) /*++ Name: - GetNextReadLocationWithOffset() + get_next_readlocation_withoffset() Description: Get the next read location + offset for the specified ring buffer. @@ -123,7 +124,8 @@ Description: --*/ static inline u32 -GetNextReadLocationWithOffset(struct hv_ring_buffer_info *ring_info, u32 offset) +get_next_readlocation_withoffset(struct hv_ring_buffer_info *ring_info, + u32 offset) { u32 next = ring_info->ring_buffer->read_index; @@ -137,14 +139,14 @@ GetNextReadLocationWithOffset(struct hv_ring_buffer_info *ring_info, u32 offset) /*++ Name: - SetNextReadLocation() + set_next_read_location() Description: Set the next read location for the specified ring buffer --*/ static inline void -SetNextReadLocation(struct hv_ring_buffer_info *ring_info, +set_next_read_location(struct hv_ring_buffer_info *ring_info, u32 next_read_location) { ring_info->ring_buffer->read_index = next_read_location; @@ -154,14 +156,14 @@ SetNextReadLocation(struct hv_ring_buffer_info *ring_info, /*++ Name: - GetRingBuffer() + get_ring_buffer() Description: Get the start of the ring buffer --*/ static inline void * -GetRingBuffer(struct hv_ring_buffer_info *ring_info) +get_ring_buffer(struct hv_ring_buffer_info *ring_info) { return (void *)ring_info->ring_buffer->buffer; } @@ -170,14 +172,14 @@ GetRingBuffer(struct hv_ring_buffer_info *ring_info) /*++ Name: - GetRingBufferSize() + get_ring_buffersize() Description: Get the size of the ring buffer --*/ static inline u32 -GetRingBufferSize(struct hv_ring_buffer_info *ring_info) +get_ring_buffersize(struct hv_ring_buffer_info *ring_info) { return ring_info->ring_datasize; } @@ -185,14 +187,14 @@ GetRingBufferSize(struct hv_ring_buffer_info *ring_info) /*++ Name: - GetRingBufferIndices() + get_ring_bufferindices() Description: Get the read and write indices as u64 of the specified ring buffer --*/ static inline u64 -GetRingBufferIndices(struct hv_ring_buffer_info *ring_info) +get_ring_bufferindices(struct hv_ring_buffer_info *ring_info) { return (u64)ring_info->ring_buffer->write_index << 32; } @@ -201,18 +203,18 @@ GetRingBufferIndices(struct hv_ring_buffer_info *ring_info) /*++ Name: - Dumpring_info() + dump_ring_info() Description: Dump out to console the ring buffer info --*/ -void Dumpring_info(struct hv_ring_buffer_info *ring_info, char *prefix) +void dump_ring_info(struct hv_ring_buffer_info *ring_info, char *prefix) { u32 bytes_avail_towrite; u32 bytes_avail_toread; - GetRingBufferAvailBytes(ring_info, + get_ringbuffer_availbytes(ring_info, &bytes_avail_toread, &bytes_avail_towrite); @@ -233,14 +235,14 @@ void Dumpring_info(struct hv_ring_buffer_info *ring_info, char *prefix) /* Internal routines */ static u32 -CopyToRingBuffer( +copyto_ringbuffer( struct hv_ring_buffer_info *ring_info, u32 start_write_offset, void *src, u32 srclen); static u32 -CopyFromRingBuffer( +copyfrom_ringbuffer( struct hv_ring_buffer_info *ring_info, void *dest, u32 destlen, @@ -251,20 +253,20 @@ CopyFromRingBuffer( /*++ Name: - RingBufferGetDebugInfo() + ringbuffer_get_debuginfo() Description: Get various debug metrics for the specified ring buffer --*/ -void RingBufferGetDebugInfo(struct hv_ring_buffer_info *ring_info, +void ringbuffer_get_debuginfo(struct hv_ring_buffer_info *ring_info, struct hv_ring_buffer_debug_info *debug_info) { u32 bytes_avail_towrite; u32 bytes_avail_toread; if (ring_info->ring_buffer) { - GetRingBufferAvailBytes(ring_info, + get_ringbuffer_availbytes(ring_info, &bytes_avail_toread, &bytes_avail_towrite); @@ -283,13 +285,13 @@ void RingBufferGetDebugInfo(struct hv_ring_buffer_info *ring_info, /*++ Name: - GetRingBufferInterruptMask() + get_ringbuffer_interrupt_mask() Description: Get the interrupt mask for the specified ring buffer --*/ -u32 GetRingBufferInterruptMask(struct hv_ring_buffer_info *rbi) +u32 get_ringbuffer_interrupt_mask(struct hv_ring_buffer_info *rbi) { return rbi->ring_buffer->interrupt_mask; } @@ -297,13 +299,13 @@ u32 GetRingBufferInterruptMask(struct hv_ring_buffer_info *rbi) /*++ Name: - RingBufferInit() + ringbuffer_init() Description: Initialize the ring buffer --*/ -int RingBufferInit(struct hv_ring_buffer_info *ring_info, +int ringbuffer_init(struct hv_ring_buffer_info *ring_info, void *buffer, u32 buflen) { if (sizeof(struct hv_ring_buffer) != PAGE_SIZE) @@ -326,26 +328,26 @@ int RingBufferInit(struct hv_ring_buffer_info *ring_info, /*++ Name: - RingBufferCleanup() + ringbuffer_cleanup() Description: Cleanup the ring buffer --*/ -void RingBufferCleanup(struct hv_ring_buffer_info *ring_info) +void ringbuffer_cleanup(struct hv_ring_buffer_info *ring_info) { } /*++ Name: - RingBufferWrite() + ringbuffer_write() Description: Write to the ring buffer --*/ -int RingBufferWrite(struct hv_ring_buffer_info *outring_info, +int ringbuffer_write(struct hv_ring_buffer_info *outring_info, struct scatterlist *sglist, u32 sgcount) { int i = 0; @@ -367,7 +369,7 @@ int RingBufferWrite(struct hv_ring_buffer_info *outring_info, spin_lock_irqsave(&outring_info->ring_lock, flags); - GetRingBufferAvailBytes(outring_info, + get_ringbuffer_availbytes(outring_info, &bytes_avail_toread, &bytes_avail_towrite); @@ -390,20 +392,20 @@ int RingBufferWrite(struct hv_ring_buffer_info *outring_info, } /* Write to the ring buffer */ - next_write_location = GetNextWriteLocation(outring_info); + next_write_location = get_next_write_location(outring_info); for_each_sg(sglist, sg, sgcount, i) { - next_write_location = CopyToRingBuffer(outring_info, + next_write_location = copyto_ringbuffer(outring_info, next_write_location, sg_virt(sg), sg->length); } /* Set previous packet start */ - prev_indices = GetRingBufferIndices(outring_info); + prev_indices = get_ring_bufferindices(outring_info); - next_write_location = CopyToRingBuffer(outring_info, + next_write_location = copyto_ringbuffer(outring_info, next_write_location, &prev_indices, sizeof(u64)); @@ -412,7 +414,7 @@ int RingBufferWrite(struct hv_ring_buffer_info *outring_info, mb(); /* Now, update the write location */ - SetNextWriteLocation(outring_info, next_write_location); + set_next_write_location(outring_info, next_write_location); /* Dumpring_info(Outring_info, "AFTER "); */ @@ -424,13 +426,13 @@ int RingBufferWrite(struct hv_ring_buffer_info *outring_info, /*++ Name: - RingBufferPeek() + ringbuffer_peek() Description: Read without advancing the read index --*/ -int RingBufferPeek(struct hv_ring_buffer_info *Inring_info, +int ringbuffer_peek(struct hv_ring_buffer_info *Inring_info, void *Buffer, u32 buflen) { u32 bytes_avail_towrite; @@ -440,7 +442,7 @@ int RingBufferPeek(struct hv_ring_buffer_info *Inring_info, spin_lock_irqsave(&Inring_info->ring_lock, flags); - GetRingBufferAvailBytes(Inring_info, + get_ringbuffer_availbytes(Inring_info, &bytes_avail_toread, &bytes_avail_towrite); @@ -458,9 +460,9 @@ int RingBufferPeek(struct hv_ring_buffer_info *Inring_info, } /* Convert to byte offset */ - next_read_location = GetNextReadLocation(Inring_info); + next_read_location = get_next_read_location(Inring_info); - next_read_location = CopyFromRingBuffer(Inring_info, + next_read_location = copyfrom_ringbuffer(Inring_info, Buffer, buflen, next_read_location); @@ -474,13 +476,13 @@ int RingBufferPeek(struct hv_ring_buffer_info *Inring_info, /*++ Name: - RingBufferRead() + ringbuffer_read() Description: Read and advance the read index --*/ -int RingBufferRead(struct hv_ring_buffer_info *inring_info, void *buffer, +int ringbuffer_read(struct hv_ring_buffer_info *inring_info, void *buffer, u32 buflen, u32 offset) { u32 bytes_avail_towrite; @@ -494,7 +496,7 @@ int RingBufferRead(struct hv_ring_buffer_info *inring_info, void *buffer, spin_lock_irqsave(&inring_info->ring_lock, flags); - GetRingBufferAvailBytes(inring_info, + get_ringbuffer_availbytes(inring_info, &bytes_avail_toread, &bytes_avail_towrite); @@ -515,14 +517,15 @@ int RingBufferRead(struct hv_ring_buffer_info *inring_info, void *buffer, return -1; } - next_read_location = GetNextReadLocationWithOffset(inring_info, offset); + next_read_location = + get_next_readlocation_withoffset(inring_info, offset); - next_read_location = CopyFromRingBuffer(inring_info, + next_read_location = copyfrom_ringbuffer(inring_info, buffer, buflen, next_read_location); - next_read_location = CopyFromRingBuffer(inring_info, + next_read_location = copyfrom_ringbuffer(inring_info, &prev_indices, sizeof(u64), next_read_location); @@ -533,7 +536,7 @@ int RingBufferRead(struct hv_ring_buffer_info *inring_info, void *buffer, mb(); /* Update the read index */ - SetNextReadLocation(inring_info, next_read_location); + set_next_read_location(inring_info, next_read_location); /* Dumpring_info(Inring_info, "AFTER "); */ @@ -546,7 +549,7 @@ int RingBufferRead(struct hv_ring_buffer_info *inring_info, void *buffer, /*++ Name: - CopyToRingBuffer() + copyto_ringbuffer() Description: Helper routine to copy from source to ring buffer. @@ -554,14 +557,14 @@ Description: --*/ static u32 -CopyToRingBuffer( +copyto_ringbuffer( struct hv_ring_buffer_info *ring_info, u32 start_write_offset, void *src, u32 srclen) { - void *ring_buffer = GetRingBuffer(ring_info); - u32 ring_buffer_size = GetRingBufferSize(ring_info); + void *ring_buffer = get_ring_buffer(ring_info); + u32 ring_buffer_size = get_ring_buffersize(ring_info); u32 frag_len; /* wrap-around detected! */ @@ -584,7 +587,7 @@ CopyToRingBuffer( /*++ Name: - CopyFromRingBuffer() + copyfrom_ringbuffer() Description: Helper routine to copy to source from ring buffer. @@ -592,14 +595,14 @@ Description: --*/ static u32 -CopyFromRingBuffer( +copyfrom_ringbuffer( struct hv_ring_buffer_info *ring_info, void *dest, u32 destlen, u32 start_read_offset) { - void *ring_buffer = GetRingBuffer(ring_info); - u32 ring_buffer_size = GetRingBufferSize(ring_info); + void *ring_buffer = get_ring_buffer(ring_info); + u32 ring_buffer_size = get_ring_buffersize(ring_info); u32 frag_len; diff --git a/drivers/staging/hv/ring_buffer.h b/drivers/staging/hv/ring_buffer.h index f30be1fa0744..7bd6ecf2f015 100644 --- a/drivers/staging/hv/ring_buffer.h +++ b/drivers/staging/hv/ring_buffer.h @@ -75,28 +75,28 @@ struct hv_ring_buffer_debug_info { /* Interface */ -int RingBufferInit(struct hv_ring_buffer_info *ring_info, void *buffer, +int ringbuffer_init(struct hv_ring_buffer_info *ring_info, void *buffer, u32 buflen); -void RingBufferCleanup(struct hv_ring_buffer_info *ring_info); +void ringbuffer_cleanup(struct hv_ring_buffer_info *ring_info); -int RingBufferWrite(struct hv_ring_buffer_info *ring_info, +int ringbuffer_write(struct hv_ring_buffer_info *ring_info, struct scatterlist *sglist, u32 sgcount); -int RingBufferPeek(struct hv_ring_buffer_info *ring_info, void *buffer, +int ringbuffer_peek(struct hv_ring_buffer_info *ring_info, void *buffer, u32 buflen); -int RingBufferRead(struct hv_ring_buffer_info *ring_info, +int ringbuffer_read(struct hv_ring_buffer_info *ring_info, void *buffer, u32 buflen, u32 offset); -u32 GetRingBufferInterruptMask(struct hv_ring_buffer_info *ring_info); +u32 get_ringbuffer_interrupt_mask(struct hv_ring_buffer_info *ring_info); -void Dumpring_info(struct hv_ring_buffer_info *ring_info, char *prefix); +void dump_ring_info(struct hv_ring_buffer_info *ring_info, char *prefix); -void RingBufferGetDebugInfo(struct hv_ring_buffer_info *ring_info, +void ringbuffer_get_debuginfo(struct hv_ring_buffer_info *ring_info, struct hv_ring_buffer_debug_info *debug_info); #endif /* _RING_BUFFER_H_ */ -- cgit v1.2.3 From 6ccb5d7c62845788be9aafef26132333a07708bb Mon Sep 17 00:00:00 2001 From: "Justin P. Mattock" Date: Mon, 8 Nov 2010 13:41:46 -0800 Subject: staging: Fix typos in rt2860 Here is a patch that fixes some typos, and comments in drivers/staging/rt2860 Signed-off-by: Justin P. Mattock Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rt2860/chip/mac_pci.h | 7 ++-- drivers/staging/rt2860/chip/mac_usb.h | 5 ++- drivers/staging/rt2860/chip/rtmp_mac.h | 19 +++++----- drivers/staging/rt2860/chips/rt3090.c | 5 ++- drivers/staging/rt2860/chips/rt30xx.c | 9 +++-- drivers/staging/rt2860/mlme.h | 41 ++++++++++---------- drivers/staging/rt2860/oid.h | 13 ++++--- drivers/staging/rt2860/pci_main_dev.c | 17 +++++---- drivers/staging/rt2860/rt_linux.c | 12 +++--- drivers/staging/rt2860/rt_linux.h | 5 ++- drivers/staging/rt2860/rt_main_dev.c | 9 +++-- drivers/staging/rt2860/rt_pci_rbus.c | 7 ++-- drivers/staging/rt2860/rt_usb.c | 13 ++++--- drivers/staging/rt2860/rtmp.h | 69 +++++++++++++++++----------------- drivers/staging/rt2860/rtmp_def.h | 37 +++++++++--------- drivers/staging/rt2860/rtmp_timer.h | 13 ++++--- drivers/staging/rt2860/spectrum.h | 12 +++--- drivers/staging/rt2860/sta/assoc.c | 13 ++++--- drivers/staging/rt2860/sta/auth.c | 7 ++-- drivers/staging/rt2860/sta/connect.c | 35 ++++++++--------- drivers/staging/rt2860/sta/rtmp_data.c | 33 ++++++++-------- drivers/staging/rt2860/sta/sanity.c | 5 ++- drivers/staging/rt2860/sta/sync.c | 19 +++++----- drivers/staging/rt2860/sta/wpa.c | 5 ++- drivers/staging/rt2860/sta_ioctl.c | 25 ++++++------ drivers/staging/rt2860/usb_main_dev.c | 8 ++-- drivers/staging/rt2860/wpa.h | 5 ++- 27 files changed, 236 insertions(+), 212 deletions(-) diff --git a/drivers/staging/rt2860/chip/mac_pci.h b/drivers/staging/rt2860/chip/mac_pci.h index 9f25ef047f59..b8868a5b9e04 100644 --- a/drivers/staging/rt2860/chip/mac_pci.h +++ b/drivers/staging/rt2860/chip/mac_pci.h @@ -30,7 +30,8 @@ Abstract: Revision History: - Who When What + Who When What + Justin P. Mattock 11/07/2010 Fix some typos --------- ---------- ---------------------------------------------- */ @@ -45,7 +46,7 @@ /* */ /* Device ID & Vendor ID related definitions, */ -/* NOTE: you should not add the new VendorID/DeviceID here unless you not sure it belongs to what chip. */ +/* NOTE: you should not add the new VendorID/DeviceID here unless you know for sure what chip it belongs too. */ /* */ #define NIC_PCI_VENDOR_ID 0x1814 #define PCIBUS_INTEL_VENDOR 0x8086 @@ -83,7 +84,7 @@ struct PACKED rt_txd { u32 SDPtr1; /*Word3 */ u32 rsv2:24; - u32 WIV:1; /* Wireless Info Valid. 1 if Driver already fill WI, o if DMA needs to copy WI to correctposition */ + u32 WIV:1; /* Wireless Info Valid. 1 if Driver already fill WI, o if DMA needs to copy WI to correct position */ u32 QSEL:2; /* select on-chip FIFO ID for 2nd-stage output scheduler.0:MGMT, 1:HCCA 2:EDCA */ u32 rsv:2; u32 TCO:1; /* */ diff --git a/drivers/staging/rt2860/chip/mac_usb.h b/drivers/staging/rt2860/chip/mac_usb.h index ed0c0b43b05e..e8158fb58648 100644 --- a/drivers/staging/rt2860/chip/mac_usb.h +++ b/drivers/staging/rt2860/chip/mac_usb.h @@ -30,7 +30,8 @@ Abstract: Revision History: - Who When What + Who When What + Justin P. Mattock 11/07/2010 Fix a typo --------- ---------- ---------------------------------------------- */ @@ -93,7 +94,7 @@ struct rt_txinfo { /* Word 0 */ u32 USBDMATxPktLen:16; /*used ONLY in USB bulk Aggregation, Total byte counts of all sub-frame. */ u32 rsv:8; - u32 WIV:1; /* Wireless Info Valid. 1 if Driver already fill WI, o if DMA needs to copy WI to correctposition */ + u32 WIV:1; /* Wireless Info Valid. 1 if Driver already fill WI, o if DMA needs to copy WI to correct position */ u32 QSEL:2; /* select on-chip FIFO ID for 2nd-stage output scheduler.0:MGMT, 1:HCCA 2:EDCA */ u32 SwUseLastRound:1; /* Software use. */ u32 rsv2:2; /* Software use. */ diff --git a/drivers/staging/rt2860/chip/rtmp_mac.h b/drivers/staging/rt2860/chip/rtmp_mac.h index e8f7172ce42a..3d1e4915b956 100644 --- a/drivers/staging/rt2860/chip/rtmp_mac.h +++ b/drivers/staging/rt2860/chip/rtmp_mac.h @@ -32,6 +32,7 @@ Revision History: Who When What + Justin P. Mattock 11/07/2010 Fix a comments, and typos -------- ---------- ---------------------------------------------- */ @@ -43,7 +44,7 @@ /* ================================================================================= */ /* the first 24-byte in TXD is called TXINFO and will be DMAed to MAC block through TXFIFO. */ -/* MAC block use this TXINFO to control the transmission behavior of this frame. */ +/* MAC block uses this TXINFO to control the transmission behavior of this frame. */ #define FIFO_MGMT 0 #define FIFO_HCCA 1 #define FIFO_EDCA 2 @@ -458,8 +459,8 @@ typedef union _BBP_CSR_CFG_STRUC { /* */ typedef union _RF_CSR_CFG0_STRUC { struct { - u32 RegIdAndContent:24; /* Register value to program into BBP */ - u32 bitwidth:5; /* Selected BBP register */ + u32 RegIdAndContent:24; /* Register value to program into BBP */ + u32 bitwidth:5; /* Selected BBP register */ u32 StandbyMode:1; /* 0: high when stand by 1: low when standby */ u32 Sel:1; /* 0:RF_LE0 activate 1:RF_LE1 activate */ u32 Busy:1; /* 0: idle 1: 8busy */ @@ -469,7 +470,7 @@ typedef union _RF_CSR_CFG0_STRUC { #define RF_CSR_CFG1 0x1024 typedef union _RF_CSR_CFG1_STRUC { struct { - u32 RegIdAndContent:24; /* Register value to program into BBP */ + u32 RegIdAndContent:24; /* Register value to program into BBP */ u32 RFGap:5; /* Gap between BB_CONTROL_RF and RF_LE. 0: 3 system clock cycle (37.5usec) 1: 5 system clock cycle (62.5usec) */ u32 rsv:7; /* 0: idle 1: 8busy */ } field; @@ -478,7 +479,7 @@ typedef union _RF_CSR_CFG1_STRUC { #define RF_CSR_CFG2 0x1028 /* */ typedef union _RF_CSR_CFG2_STRUC { struct { - u32 RegIdAndContent:24; /* Register value to program into BBP */ + u32 RegIdAndContent:24; /* Register value to program into BBP */ u32 rsv:8; /* 0: idle 1: 8busy */ } field; u32 word; @@ -490,7 +491,7 @@ typedef union _LED_CFG_STRUC { u32 OffPeriod:8; /* blinking off period unit 1ms */ u32 SlowBlinkPeriod:6; /* slow blinking period. unit:1ms */ u32 rsv:2; - u32 RLedMode:2; /* red Led Mode 0: off1: blinking upon TX2: periodic slow blinking3: always on */ + u32 RLedMode:2; /* red Led Mode 0: off1: blinking upon TX2: periodic slow blinking3: always on */ u32 GLedMode:2; /* green Led Mode */ u32 YLedMode:2; /* yellow Led Mode */ u32 LedPolar:1; /* Led Polarity. 0: active low1: active high */ @@ -621,9 +622,9 @@ typedef union _TX_TIMEOUT_CFG_STRUC { #define TX_RTY_CFG 0x134c typedef union PACKED _TX_RTY_CFG_STRUC { struct { - u32 ShortRtyLimit:8; /* short retry limit */ - u32 LongRtyLimit:8; /*long retry limit */ - u32 LongRtyThre:12; /* Long retry threshoold */ + u32 ShortRtyLimit:8; /* short retry limit */ + u32 LongRtyLimit:8; /* long retry limit */ + u32 LongRtyThre:12; /* Long retry threshold */ u32 NonAggRtyMode:1; /* Non-Aggregate MPDU retry mode. 0:expired by retry limit, 1: expired by mpdu life timer */ u32 AggRtyMode:1; /* Aggregate MPDU retry mode. 0:expired by retry limit, 1: expired by mpdu life timer */ u32 TxautoFBEnable:1; /* Tx retry PHY rate auto fallback enable */ diff --git a/drivers/staging/rt2860/chips/rt3090.c b/drivers/staging/rt2860/chips/rt3090.c index c2933c69bc04..156eb36e56f2 100644 --- a/drivers/staging/rt2860/chips/rt3090.c +++ b/drivers/staging/rt2860/chips/rt3090.c @@ -28,10 +28,11 @@ rt3090.c Abstract: - Specific funcitons and variables for RT3070 + Specific functions and variables for RT3070 Revision History: - Who When What + Who When What + Justin P. Mattock 11/07/2010 Fix a typo -------- ---------- ---------------------------------------------- */ diff --git a/drivers/staging/rt2860/chips/rt30xx.c b/drivers/staging/rt2860/chips/rt30xx.c index 4367a196aeff..c8f728257197 100644 --- a/drivers/staging/rt2860/chips/rt30xx.c +++ b/drivers/staging/rt2860/chips/rt30xx.c @@ -28,10 +28,11 @@ rt30xx.c Abstract: - Specific funcitons and variables for RT30xx. + Specific functions and variables for RT30xx. Revision History: - Who When What + Who When What + Justin P. Mattock 11/07/2010 Fix some typos -------- ---------- ---------------------------------------------- */ @@ -89,7 +90,7 @@ struct rt_reg_pair RT30xx_RFRegTable[] = { u8 NUM_RF_REG_PARMS = (sizeof(RT30xx_RFRegTable) / sizeof(struct rt_reg_pair)); -/* Antenna divesity use GPIO3 and EESK pin for control */ +/* Antenna diversity use GPIO3 and EESK pin for control */ /* Antenna and EEPROM access are both using EESK pin, */ /* Therefor we should avoid accessing EESK at the same time */ /* Then restore antenna after EEPROM access */ @@ -243,7 +244,7 @@ void RTMPFilterCalibration(struct rt_rtmp_adapter *pAd) break; } - /* prevent infinite loop cause driver hang. */ + /* prevent infinite loop; causes driver hang. */ if (loopcnt++ > 100) { DBGPRINT(RT_DEBUG_ERROR, ("RTMPFilterCalibration - can't find a valid value, loopcnt=%d stop calibrating", diff --git a/drivers/staging/rt2860/mlme.h b/drivers/staging/rt2860/mlme.h index 01414c3b4889..cd1ee3d7a91d 100644 --- a/drivers/staging/rt2860/mlme.h +++ b/drivers/staging/rt2860/mlme.h @@ -32,8 +32,9 @@ Revision History: Who When What -------- ---------- ------------------------------ - John Chang 2003-08-28 Created - John Chang 2004-09-06 modified for RT2600 + John Chang 2003-08-28 Created + John Chang 2004-09-06 modified for RT2600 + Justin P. Mattock 11/07/2010 Fix typos in comments */ #ifndef __MLME_H__ @@ -41,7 +42,7 @@ #include "rtmp_dot11.h" -/* maximum supported capability information - */ +/* maximum supported capability information */ /* ESS, IBSS, Privacy, Short Preamble, Spectrum mgmt, Short Slot */ #define SUPPORTED_CAPABILITY_INFO 0x0533 @@ -77,7 +78,7 @@ #define CW_MAX_IN_BITS 10 /* actual CwMax = 2^CW_MAX_IN_BITS - 1 */ /* Note: RSSI_TO_DBM_OFFSET has been changed to variable for new RF (2004-0720). */ -/* SHould not refer to this constant anymore */ +/* Should not refer to this constant anymore */ /*#define RSSI_TO_DBM_OFFSET 120 // for RT2530 RSSI-115 = dBm */ #define RSSI_FOR_MID_TX_POWER -55 /* -55 db is considered mid-distance */ #define RSSI_FOR_LOW_TX_POWER -45 /* -45 db is considered very short distance and */ @@ -123,7 +124,7 @@ #define TID_MAC_HASH_INDEX(Addr, TID) (TID_MAC_HASH(Addr, TID) % HASH_TABLE_SIZE) /* LED Control */ -/* assoiation ON. one LED ON. another blinking when TX, OFF when idle */ +/* association ON. one LED ON. another blinking when TX, OFF when idle */ /* no association, both LED off */ #define ASIC_LED_ACT_ON(pAd) RTMP_IO_WRITE32(pAd, MAC_CSR14, 0x00031e46) #define ASIC_LED_ACT_OFF(pAd) RTMP_IO_WRITE32(pAd, MAC_CSR14, 0x00001e46) @@ -284,8 +285,8 @@ struct PACKED rt_ht_capability_ie { /* 802.11n draft3 related structure definitions. */ /* 7.3.2.60 */ -#define dot11OBSSScanPassiveDwell 20 /* in TU. min amount of time that the STA continously scans each channel when performing an active OBSS scan. */ -#define dot11OBSSScanActiveDwell 10 /* in TU.min amount of time that the STA continously scans each channel when performing an passive OBSS scan. */ +#define dot11OBSSScanPassiveDwell 20 /* in TU. min amount of time that the STA continuously scans each channel when performing an active OBSS scan. */ +#define dot11OBSSScanActiveDwell 10 /* in TU.min amount of time that the STA continuously scans each channel when performing an passive OBSS scan. */ #define dot11BSSWidthTriggerScanInterval 300 /* in sec. max interval between scan operations to be performed to detect BSS channel width trigger events. */ #define dot11OBSSScanPassiveTotalPerChannel 200 /* in TU. min total amount of time that the STA scans each channel when performing a passive OBSS scan. */ #define dot11OBSSScanActiveTotalPerChannel 20 /*in TU. min total amount of time that the STA scans each channel when performing a active OBSS scan */ @@ -325,7 +326,7 @@ struct rt_trigger_eventa { }; /* 20/40 trigger event table */ -/* If one Event A delete or created, or if Event B is detected or not detected, STA should send 2040BSSCoexistence to AP. */ +/* If one Event (A) is deleted or created, or if Event (B) is detected or not detected, STA should send 2040BSSCoexistence to AP. */ #define MAX_TRIGGER_EVENT 64 struct rt_trigger_event_tab { u8 EventANo; @@ -357,14 +358,14 @@ struct PACKED rt_bss_2040_intolerant_ch_report { u8 ChList[0]; }; -/* The structure for channel switch annoucement IE. This is in 802.11n D3.03 */ +/* The structure for channel switch announcement IE. This is in 802.11n D3.03 */ struct PACKED rt_cha_switch_announce_ie { u8 SwitchMode; /*channel switch mode */ u8 NewChannel; /* */ u8 SwitchCount; /* */ }; -/* The structure for channel switch annoucement IE. This is in 802.11n D3.03 */ +/* The structure for channel switch announcement IE. This is in 802.11n D3.03 */ struct PACKED rt_sec_cha_offset_ie { u8 SecondaryChannelOffset; /* 1: Secondary above, 3: Secondary below, 0: no Secondary */ }; @@ -377,7 +378,7 @@ struct rt_ht_phy_info { u8 MCSSet[16]; }; -/*This structure substracts ralink supports from all 802.11n-related features. */ +/*This structure subtracts ralink supports from all 802.11n-related features. */ /*Features not listed here but contained in 802.11n spec are not supported in rt2860. */ struct rt_ht_capability { u16 ChannelWidth:1; @@ -387,14 +388,14 @@ struct rt_ht_capability { u16 ShortGIfor40:1; /*for40MHz */ u16 TxSTBC:1; u16 RxSTBC:2; /* 2 bits */ - u16 AmsduEnable:1; /* Enable to transmit A-MSDU. Suggest disable. We should use A-MPDU to gain best benifit of 802.11n */ + u16 AmsduEnable:1; /* Enable to transmit A-MSDU. Suggest disable. We should use A-MPDU to gain best benefit of 802.11n */ u16 AmsduSize:1; /* Max receiving A-MSDU size */ u16 rsv:5; /*Substract from Addiont HT INFO IE */ u8 MaxRAmpduFactor:2; u8 MpduDensity:3; - u8 ExtChanOffset:2; /* Please not the difference with following u8 NewExtChannelOffset; from 802.11n */ + u8 ExtChanOffset:2; /* Please note the difference with following u8 NewExtChannelOffset; from 802.11n */ u8 RecomWidth:1; u16 OperaionMode:2; @@ -481,7 +482,7 @@ struct PACKED rt_ba_parm { u16 AMSDUSupported:1; /* 0: not permitted 1: permitted */ u16 BAPolicy:1; /* 1: immediately BA 0:delayed BA */ u16 TID:4; /* value of TC os TS */ - u16 BufSize:10; /* number of buffe of size 2304 octetsr */ + u16 BufSize:10; /* number of buffer of size 2304 octetsr */ }; /* 2-byte BA Starting Seq CONTROL field */ @@ -551,7 +552,7 @@ struct PACKED rt_frame_mtba_req { BASEQ_CONTROL BAStartingSeq; }; -/* Compressed format is mandantory in HT STA */ +/* Compressed format is mandatory in HT STA */ struct PACKED rt_frame_mtba { struct rt_frame_control FC; u16 Duration; @@ -647,7 +648,7 @@ struct PACKED rt_frame_ba { u8 bitmask[8]; }; -/* Radio Measuement Request Frame Format */ +/* Radio Measurement Request Frame Format */ struct PACKED rt_frame_rm_req_action { struct rt_header_802_11 Hdr; u8 Category; @@ -709,7 +710,7 @@ struct rt_edca_parm { u8 Cwmin[4]; u8 Cwmax[4]; u16 Txop[4]; /* in unit of 32-us */ - BOOLEAN bACM[4]; /* 1: Admission Control of AC_BK is mandattory */ + BOOLEAN bACM[4]; /* 1: Admission Control of AC_BK is mandatory */ }; /* QBSS LOAD information from QAP's BEACON/ProbeRsp */ @@ -757,7 +758,7 @@ struct rt_wpa_ie { struct rt_bss_entry { u8 Bssid[MAC_ADDR_LEN]; u8 Channel; - u8 CentralChannel; /*Store the wide-band central channel for 40MHz. .used in 40MHz AP. Or this is the same as Channel. */ + u8 CentralChannel; /*Store the wide-band central channel for 40MHz. used in 40MHz AP. Or this is the same as Channel. */ u8 BssType; u16 AtimWin; u16 BeaconPeriod; @@ -855,7 +856,7 @@ struct rt_state_machine { STATE_MACHINE_FUNC *TransFunc; }; -/* MLME AUX data structure that hold temporarliy settings during a connection attempt. */ +/* MLME AUX data structure that holds temporarliy settings during a connection attempt. */ /* Once this attemp succeeds, all settings will be copy to pAd->StaActive. */ /* A connection attempt (user set OID, roaming, CCX fast roaming,..) consists of */ /* several steps (JOIN, AUTH, ASSOC or REASSOC) and may fail at any step. We purposely */ @@ -996,7 +997,7 @@ struct PACKED rt_rtmp_tx_rate_switch { #define MAC_TABLE_ASSOC_TIMEOUT 5 /* unit: sec */ #define MAC_TABLE_FULL(Tab) ((Tab).size == MAX_LEN_OF_MAC_TABLE) -/* AP shall drop the sta if contine Tx fail count reach it. */ +/* AP shall drop the sta if continue Tx fail count reach it. */ #define MAC_ENTRY_LIFE_CHECK_CNT 20 /* packet cnt. */ /* Value domain of pMacEntry->Sst */ diff --git a/drivers/staging/rt2860/oid.h b/drivers/staging/rt2860/oid.h index 1704c27b2736..eaa3fe005088 100644 --- a/drivers/staging/rt2860/oid.h +++ b/drivers/staging/rt2860/oid.h @@ -32,7 +32,8 @@ Revision History: Who When What -------- ---------- ---------------------------------------------- - Name Date Modification logs + Name Date Modification logs + Justin P. Mattock 11/07/2010 Fix typos in comments */ #ifndef _OID_H_ #define _OID_H_ @@ -78,7 +79,7 @@ #define NDIS_802_11_LENGTH_RATES 8 #define NDIS_802_11_LENGTH_RATES_EX 16 #define MAC_ADDR_LENGTH 6 -/*#define MAX_NUM_OF_CHS 49 // 14 channels @2.4G + 12@UNII + 4 @MMAC + 11 @HiperLAN2 + 7 @Japan + 1 as NULL terminationc */ +/*#define MAX_NUM_OF_CHS 49 // 14 channels @2.4G + 12@UNII + 4 @MMAC + 11 @HiperLAN2 + 7 @Japan + 1 as NULL termination */ #define MAX_NUM_OF_CHS 54 /* 14 channels @2.4G + 12@UNII(lower/middle) + 16@HiperLAN2 + 11@UNII(upper) + 0 @Japan + 1 as NULL termination */ #define MAX_NUMBER_OF_EVENT 10 /* entry # in EVENT table */ #define MAX_NUMBER_OF_MAC 32 /* if MAX_MBSSID_NUM is 8, this value can't be larger than 211 */ @@ -610,7 +611,7 @@ struct rt_802_11_event_log { struct rt_802_11_event_table { unsigned long Num; - unsigned long Rsv; /* to align Log[] at LARGE_INEGER boundary */ + unsigned long Rsv; /* to align Log[] at LARGE_INTEGER boundary */ struct rt_802_11_event_log Log[MAX_NUMBER_OF_EVENT]; }; @@ -721,9 +722,9 @@ struct rt_802_11_tx_rates { #define AUTH_FAIL 0x4 /* Open authentication fail */ #define AUTH_FAIL_KEYS 0x5 /* Shared authentication fail */ #define ASSOC_FAIL 0x6 /* Association failed */ -#define EAP_MIC_FAILURE 0x7 /* Deauthencation because MIC failure */ -#define EAP_4WAY_TIMEOUT 0x8 /* Deauthencation on 4-way handshake timeout */ -#define EAP_GROUP_KEY_TIMEOUT 0x9 /* Deauthencation on group key handshake timeout */ +#define EAP_MIC_FAILURE 0x7 /* Deauthentication because MIC failure */ +#define EAP_4WAY_TIMEOUT 0x8 /* Deauthentication on 4-way handshake timeout */ +#define EAP_GROUP_KEY_TIMEOUT 0x9 /* Deauthentication on group key handshake timeout */ #define EAP_SUCCESS 0xa /* EAP succeed */ #define DETECT_RADAR_SIGNAL 0xb /* Radar signal occur in current channel */ #define EXTRA_INFO_MAX 0xb /* Indicate Last OID */ diff --git a/drivers/staging/rt2860/pci_main_dev.c b/drivers/staging/rt2860/pci_main_dev.c index 321facd6b0ab..c35c804a083e 100644 --- a/drivers/staging/rt2860/pci_main_dev.c +++ b/drivers/staging/rt2860/pci_main_dev.c @@ -31,7 +31,8 @@ Create and register network interface for PCI based chipsets in Linux platform. Revision History: - Who When What + Who When What + Justin P. Mattock 11/07/2010 Fix typos in some comments -------- ---------- ---------------------------------------------- */ @@ -40,8 +41,8 @@ #include /* Following information will be show when you run 'modinfo' */ -/* *** If you have a solution for the bug in current version of driver, please mail to me. */ -/* Otherwise post to forum in ralinktech's web site(www.ralinktech.com) and let all users help you. *** */ +/* If you have a solution for a bug in current version of driver, please e-mail me. */ +/* Otherwise post to forum in ralinktech's web site(www.ralinktech.com) and let all users help you. */ MODULE_AUTHOR("Jett Chen "); MODULE_DESCRIPTION("RT2860/RT3090 Wireless Lan Linux Driver"); MODULE_LICENSE("GPL"); @@ -599,7 +600,7 @@ void RTMPInitPCIeLinkCtrlValue(struct rt_rtmp_adapter *pAd) DBGPRINT_RAW(RT_DEBUG_ERROR, (" AUX_CTRL = 0x%32x\n", MacValue)); - /* for RT30xx F and after, PCIe infterface, and for power solution 3 */ + /* for RT30xx F and after, PCIe interface, and for power solution 3 */ if ((IS_VERSION_AFTER_F(pAd)) && (pAd->StaCfg.PSControl.field.rt30xxPowerMode >= 2) && (pAd->StaCfg.PSControl.field.rt30xxPowerMode <= 3)) { @@ -902,7 +903,7 @@ void RTMPPCIeLinkCtrlValueRestore(struct rt_rtmp_adapter *pAd, u8 Level) Configuration); if ((Configuration != 0) && (Configuration != 0xFFFF)) { Configuration &= 0xfefc; - /* If call from interface down, restore to orginial setting. */ + /* If call from interface down, restore to original setting. */ if (Level == RESTORE_CLOSE) Configuration |= pAd->HostLnkCtrlConfiguration; else @@ -924,7 +925,7 @@ void RTMPPCIeLinkCtrlValueRestore(struct rt_rtmp_adapter *pAd, u8 Level) Configuration); if ((Configuration != 0) && (Configuration != 0xFFFF)) { Configuration &= 0xfefc; - /* If call from interface down, restore to orginial setting. */ + /* If call from interface down, restore to original setting. */ if (Level == RESTORE_CLOSE) Configuration |= pAd->RLnkCtrlConfiguration; else @@ -1106,12 +1107,12 @@ void RTMPrt3xSetPCIePowerLinkCtrl(struct rt_rtmp_adapter *pAd) if (pos != 0) pAd->HostLnkCtrlOffset = pos + PCI_EXP_LNKCTL; - /* If configurared to turn on L1. */ + /* If configured to turn on L1. */ HostConfiguration = 0; if (pAd->StaCfg.PSControl.field.rt30xxForceASPMTest == 1) { DBGPRINT(RT_DEBUG_TRACE, ("Enter,PSM : Force ASPM\n")); - /* Skip non-exist deice right away */ + /* Skip non-exist device right away */ if ((pAd->HostLnkCtrlOffset != 0)) { PCI_REG_READ_WORD(pObj->parent_pci_dev, pAd->HostLnkCtrlOffset, diff --git a/drivers/staging/rt2860/rt_linux.c b/drivers/staging/rt2860/rt_linux.c index abfeea11721d..e680b0d97f74 100644 --- a/drivers/staging/rt2860/rt_linux.c +++ b/drivers/staging/rt2860/rt_linux.c @@ -767,13 +767,13 @@ void send_monitor_packets(struct rt_rtmp_adapter *pAd, struct rt_rx_blk *pRxBlk) /* QOS */ if (pRxBlk->pHeader->FC.SubType & 0x08) { header_len += 2; - /* Data skip QOS contorl field */ + /* Data skip QOS control field */ pRxBlk->DataSize -= 2; } /* Order bit: A-Ralink or HTC+ */ if (pRxBlk->pHeader->FC.Order) { header_len += 4; - /* Data skip HTC contorl field */ + /* Data skip HTC control field */ pRxBlk->DataSize -= 4; } /* Copy Header */ @@ -1175,7 +1175,7 @@ int RtmpOSNetDevAddrSet(struct net_device *pNetDev, u8 *pMacAddr) net_dev = pNetDev; GET_PAD_FROM_NET_DEV(pAd, net_dev); - /* work-around for the SuSE due to it has it's own interface name management system. */ + /* work-around for SuSE, due to them having their own interface name management system. */ { NdisZeroMemory(pAd->StaCfg.dev_name, 16); NdisMoveMemory(pAd->StaCfg.dev_name, net_dev->name, @@ -1300,7 +1300,7 @@ int RtmpOSNetDevAttach(struct net_device *pNetDev, int ret, rtnl_locked = FALSE; DBGPRINT(RT_DEBUG_TRACE, ("RtmpOSNetDevAttach()--->\n")); - /* If we need hook some callback function to the net device structrue, now do it. */ + /* If we need hook some callback function to the net device structure, now do it. */ if (pDevOpHook) { struct rt_rtmp_adapter *pAd = NULL; @@ -1351,10 +1351,10 @@ struct net_device *RtmpOSNetDevCreate(struct rt_rtmp_adapter *pAd, return NULL; } - /* find a available interface name, max 32 interfaces */ + /* find an available interface name, max 32 interfaces */ status = RtmpOSNetDevRequestName(pAd, pNetDev, pNamePrefix, devNum); if (status != NDIS_STATUS_SUCCESS) { - /* error! no any available ra name can be used! */ + /* error! no available ra name can be used! */ DBGPRINT(RT_DEBUG_ERROR, ("Assign interface name (%s with suffix 0~32) failed...\n", pNamePrefix)); diff --git a/drivers/staging/rt2860/rt_linux.h b/drivers/staging/rt2860/rt_linux.h index 5acedf18b1ab..a449b0bb85f1 100644 --- a/drivers/staging/rt2860/rt_linux.h +++ b/drivers/staging/rt2860/rt_linux.h @@ -30,7 +30,8 @@ Abstract: Revision History: - Who When What + Who When What + Justin P. Mattock 11/07/2010 Fix typo in a comment --------- ---------- ---------------------------------------------- */ @@ -726,7 +727,7 @@ void linux_pci_unmap_single(struct rt_rtmp_adapter *pAd, dma_addr_t dma_addr, #define RTMP_GET_PACKET_MOREDATA(_p) (RTPKT_TO_OSPKT(_p)->cb[CB_OFF+7]) /* */ -/* Sepcific Pakcet Type definition */ +/* Specific Packet Type definition */ /* */ #define RTMP_PACKET_SPECIFIC_CB_OFFSET 11 diff --git a/drivers/staging/rt2860/rt_main_dev.c b/drivers/staging/rt2860/rt_main_dev.c index ad60ceaf4b88..19e9bc6569f8 100644 --- a/drivers/staging/rt2860/rt_main_dev.c +++ b/drivers/staging/rt2860/rt_main_dev.c @@ -31,7 +31,8 @@ Create and register network interface. Revision History: - Who When What + Who When What + Justin P. Mattock 11/07/2010 Fix typos in comments -------- ---------- ---------------------------------------------- */ @@ -234,7 +235,7 @@ int rt28xx_close(struct net_device *dev) RTMPPCIeLinkCtrlValueRestore(pAd, RESTORE_CLOSE); #endif /* RTMP_MAC_PCI // */ - /* If dirver doesn't wake up firmware here, */ + /* If driver doesn't wake up firmware here, */ /* NICLoadFirmware will hang forever when interface is up again. */ if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_DOZE)) { AsicForceWakeup(pAd, TRUE); @@ -310,8 +311,8 @@ int rt28xx_close(struct net_device *dev) RTMP_ASIC_INTERRUPT_DISABLE(pAd); } /* Receive packets to clear DMA index after disable interrupt. */ - /*RTMPHandleRxDoneInterrupt(pAd); */ - /* put to radio off to save power when driver unload. After radiooff, can't write /read register. So need to finish all */ + /* RTMPHandleRxDoneInterrupt(pAd); */ + /* put radio off to save power when driver unloads. After radiooff, can't write/read register, so need to finish all. */ /* register access before Radio off. */ brc = RT28xxPciAsicRadioOff(pAd, RTMP_HALT, 0); diff --git a/drivers/staging/rt2860/rt_pci_rbus.c b/drivers/staging/rt2860/rt_pci_rbus.c index 3004be6da003..e5fb67cd9a68 100644 --- a/drivers/staging/rt2860/rt_pci_rbus.c +++ b/drivers/staging/rt2860/rt_pci_rbus.c @@ -31,7 +31,8 @@ Create and register network interface. Revision History: - Who When What + Who When What + Justin P. Mattock 11/07/2010 Fix a typo -------- ---------- ---------------------------------------------- */ @@ -356,7 +357,7 @@ static void mgmt_dma_done_tasklet(unsigned long data) RTMPHandleMgmtRingDmaDoneInterrupt(pAd); - /* if you use RTMP_SEM_LOCK, sometimes kernel will hang up, no any */ + /* if you use RTMP_SEM_LOCK, sometimes kernel will hang up, without any */ /* bug report output */ RTMP_INT_LOCK(&pAd->irq_lock, flags); /* @@ -787,7 +788,7 @@ IRQ_HANDLE_TYPE rt2860_interrupt(int irq, void *dev_instance) } /* - * invaild or writeback cache + * invalid or writeback cache * and convert virtual address to physical address */ dma_addr_t linux_pci_map_single(struct rt_rtmp_adapter *pAd, void *ptr, diff --git a/drivers/staging/rt2860/rt_usb.c b/drivers/staging/rt2860/rt_usb.c index bcfc0f54d2aa..580a20dd6e9d 100644 --- a/drivers/staging/rt2860/rt_usb.c +++ b/drivers/staging/rt2860/rt_usb.c @@ -32,7 +32,8 @@ Revision History: Who When What -------- ---------- ---------------------------------------------- - Name Date Modification logs + Name Date Modification logs + Justin P. Mattock 11/07/2010 Fix some typos. */ @@ -279,7 +280,7 @@ static void rtusb_dataout_complete(unsigned long data) && !RTUSB_TEST_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_FRAG << BulkOutPipeId))) { - /* Indicate There is data avaliable */ + /* Indicate There is data available */ RTUSB_SET_BULK_FLAG(pAd, (fRTUSB_BULK_OUT_DATA_NORMAL << BulkOutPipeId)); @@ -335,7 +336,7 @@ static void rtusb_null_frame_done_tasklet(unsigned long data) } /* Always call Bulk routine, even reset bulk. */ - /* The protectioon of rest bulk should be in BulkOut routine */ + /* The protection of rest bulk should be in BulkOut routine */ RTUSBKickBulkOut(pAd); } @@ -383,7 +384,7 @@ static void rtusb_rts_frame_done_tasklet(unsigned long data) RTMP_SEM_UNLOCK(&pAd->BulkOutLock[pRTSContext->BulkOutPipeId]); /* Always call Bulk routine, even reset bulk. */ - /* The protectioon of rest bulk should be in BulkOut routine */ + /* The protection of rest bulk should be in BulkOut routine */ RTUSBKickBulkOut(pAd); } @@ -427,7 +428,7 @@ static void rtusb_pspoll_frame_done_tasklet(unsigned long data) RTMP_SEM_UNLOCK(&pAd->BulkOutLock[0]); /* Always call Bulk routine, even reset bulk. */ - /* The protectioon of rest bulk should be in BulkOut routine */ + /* The protection of rest bulk should be in BulkOut routine */ RTUSBKickBulkOut(pAd); } @@ -575,7 +576,7 @@ static void rtusb_mgmt_dma_done_tasklet(unsigned long data) } else { /* Always call Bulk routine, even reset bulk. */ - /* The protectioon of rest bulk should be in BulkOut routine */ + /* The protection of rest bulk should be in BulkOut routine */ if (pAd->MgmtRing.TxSwFreeIdx < MGMT_RING_SIZE /* pMLMEContext->bWaitingBulkOut == TRUE */) { diff --git a/drivers/staging/rt2860/rtmp.h b/drivers/staging/rt2860/rtmp.h index ca54e53b6603..caf466242a13 100644 --- a/drivers/staging/rt2860/rtmp.h +++ b/drivers/staging/rt2860/rtmp.h @@ -31,11 +31,12 @@ Miniport generic portion header file Revision History: - Who When What + Who When What -------- ---------- ---------------------------------------------- - Paul Lin 2002-08-01 created - James Tan 2002-09-06 modified (Revise NTCRegTable) - John Chang 2004-09-06 modified for RT2600 + Paul Lin 2002-08-01 created + James Tan 2002-09-06 modified (Revise NTCRegTable) + John Chang 2004-09-06 modified for RT2600 + Justin P. Mattock 11/07/2010 Fix some typos */ #ifndef __RTMP_H__ #define __RTMP_H__ @@ -337,7 +338,7 @@ struct rt_rtmp_sg_list { #define LEAP_ON(_p) (((_p)->StaCfg.LeapAuthMode) == CISCO_AuthModeLEAP) #define LEAP_CCKM_ON(_p) ((((_p)->StaCfg.LeapAuthMode) == CISCO_AuthModeLEAP) && ((_p)->StaCfg.LeapAuthInfo.CCKM == TRUE)) -/* if orginal Ethernet frame contains no LLC/SNAP, then an extra LLC/SNAP encap is required */ +/* if original Ethernet frame contains no LLC/SNAP, then an extra LLC/SNAP encap is required */ #define EXTRA_LLCSNAP_ENCAP_FROM_PKT_START(_pBufVA, _pExtraLlcSnapEncap) \ { \ if (((*(_pBufVA + 12) << 8) + *(_pBufVA + 13)) > 1500) { \ @@ -466,7 +467,7 @@ struct rt_rtmp_dmabuf { /* Control block (Descriptor) for all ring descriptor DMA operation, buffer must be */ /* contiguous physical memory. char stored the binding Rx packet descriptor */ /* which won't be released, driver has to wait until upper layer return the packet */ -/* before giveing up this rx ring descriptor to ASIC. NDIS_BUFFER is assocaited pair */ +/* before giving up this rx ring descriptor to ASIC. NDIS_BUFFER is associated pair */ /* to describe the packet buffer. For Tx, char stored the tx packet descriptor */ /* which driver should ACK upper layer when the tx is physically done or failed. */ /* */ @@ -602,7 +603,7 @@ struct rt_counter_ralink { }; struct rt_counter_drs { - /* to record the each TX rate's quality. 0 is best, the bigger the worse. */ + /* record each TX rate's quality. 0 is best, the bigger the worse. */ u16 TxQuality[MAX_STEP_OF_TX_RATE_SWITCH]; u8 PER[MAX_STEP_OF_TX_RATE_SWITCH]; u8 TxRateUpPenalty; /* extra # of second penalty due to last unstable condition */ @@ -719,7 +720,7 @@ struct rt_fragment_frame { /* Packet information for NdisQueryPacket */ /* */ struct rt_packet_info { - u32 PhysicalBufferCount; /* Physical breaks of buffer descripor chained */ + u32 PhysicalBufferCount; /* Physical breaks of buffer descriptor chained */ u32 BufferCount; /* Number of Buffer descriptor chained */ u32 TotalPacketLength; /* Self explained */ char *pFirstBuffer; /* Pointer to first buffer descriptor */ @@ -846,8 +847,8 @@ typedef enum _ABGBAND_STATE_ { /* Power save method control */ typedef union _PS_CONTROL { struct { - unsigned long EnablePSinIdle:1; /* Enable radio off when not connect to AP. radio on only when sitesurvey, */ - unsigned long EnableNewPS:1; /* Enable new Chip power save fucntion . New method can only be applied in chip version after 2872. and PCIe. */ + unsigned long EnablePSinIdle:1; /* Enable radio off when not connected to AP. radio on only when sitesurvey, */ + unsigned long EnableNewPS:1; /* Enable new Chip power save function . New method can only be applied in chip version after 2872. and PCIe. */ unsigned long rt30xxPowerMode:2; /* Power Level Mode for rt30xx chip */ unsigned long rt30xxFollowHostASPM:1; /* Card Follows Host's setting for rt30xx chip. */ unsigned long rt30xxForceASPMTest:1; /* Force enable L1 for rt30xx chip. This has higher priority than rt30xxFollowHostASPM Mode. */ @@ -1117,8 +1118,8 @@ struct rt_beacon_sync { unsigned long TimIELocationInBeacon[HW_BEACON_MAX_COUNT]; unsigned long CapabilityInfoLocationInBeacon[HW_BEACON_MAX_COUNT]; BOOLEAN EnableBeacon; /* trigger to enable beacon transmission. */ - u8 BeaconBitMap; /* NOTE: If the MAX_MBSSID_NUM is larger than 8, this parameter need to change. */ - u8 DtimBitOn; /* NOTE: If the MAX_MBSSID_NUM is larger than 8, this parameter need to change. */ + u8 BeaconBitMap; /* NOTE: If the MAX_MBSSID_NUM is larger than 8, this parameter needs to change. */ + u8 DtimBitOn; /* NOTE: If the MAX_MBSSID_NUM is larger than 8, this parameter needs to change. */ }; #endif /* RTMP_MAC_USB // */ @@ -1211,7 +1212,7 @@ struct rt_common_config { /*BOOLEAN bAutoTxRateSwitch; */ u8 MinTxRate; /* RATE_1, RATE_2, RATE_5_5, RATE_11 */ u8 RtsRate; /* RATE_xxx */ - HTTRANSMIT_SETTING MlmeTransmit; /* MGMT frame PHY rate setting when operatin at Ht rate. */ + HTTRANSMIT_SETTING MlmeTransmit; /* MGMT frame PHY rate setting when operation at Ht rate. */ u8 MlmeRate; /* RATE_xxx, used to send MLME frames */ u8 BasicMlmeRate; /* Default Rate for sending MLME frames */ @@ -1264,7 +1265,7 @@ struct rt_common_config { struct rt_ht_capability_ie HtCapability; struct rt_add_ht_info_ie AddHTInfo; /* Useful as AP. */ /*This IE is used with channel switch announcement element when changing to a new 40MHz. */ - /*This IE is included in channel switch ammouncement frames 7.4.1.5, beacons, probe Rsp. */ + /*This IE is included in channel switch announcement frames 7.4.1.5, beacons, probe Rsp. */ struct rt_new_ext_chan_ie NewExtChanOffset; /*7.3.2.20A, 1 if extension channel is above the control channel, 3 if below, 0 if not present */ BOOLEAN bHTProtect; @@ -1329,7 +1330,7 @@ struct rt_sta_admin_config { /* GROUP 1 - */ /* User configuration loaded from Registry, E2PROM or OID_xxx. These settings describe */ /* the user intended configuration, but not necessary fully equal to the final */ - /* settings in ACTIVE BSS after negotiation/compromize with the BSS holder (either */ + /* settings in ACTIVE BSS after negotiation/compromise with the BSS holder (either */ /* AP or IBSS holder). */ /* Once initialized, user configuration can only be changed via OID_xxx */ u8 BssType; /* BSS_INFRA or BSS_ADHOC */ @@ -1386,12 +1387,12 @@ struct rt_sta_admin_config { /* For WPA countermeasures */ unsigned long LastMicErrorTime; /* record last MIC error time */ - unsigned long MicErrCnt; /* Should be 0, 1, 2, then reset to zero (after disassoiciation). */ + unsigned long MicErrCnt; /* Should be 0, 1, 2, then reset to zero (after disassociation). */ BOOLEAN bBlockAssoc; /* Block associate attempt for 60 seconds after counter measure occurred. */ /* For WPA-PSK supplicant state */ WPA_STATE WpaState; /* Default is SS_NOTUSE and handled by microsoft 802.1x */ u8 ReplayCounter[8]; - u8 ANonce[32]; /* ANonce for WPA-PSK from aurhenticator */ + u8 ANonce[32]; /* ANonce for WPA-PSK from auhenticator */ u8 SNonce[32]; /* SNonce for WPA-PSK */ u8 LastSNR0; /* last received BEACON's SNR */ @@ -1423,7 +1424,7 @@ struct rt_sta_admin_config { u8 RSNIE_Len; u8 RSN_IE[MAX_LEN_OF_RSNIE]; /* The content saved here should be little-endian format. */ - unsigned long CLBusyBytes; /* Save the total bytes received durning channel load scan time */ + unsigned long CLBusyBytes; /* Save the total bytes received during channel load scan time */ u16 RPIDensity[8]; /* Array for RPI density collection */ u8 RMReqCnt; /* Number of measurement request saved. */ @@ -1489,9 +1490,9 @@ struct rt_sta_admin_config { BOOLEAN bForceTxBurst; /* 1: force enble TX PACKET BURST, 0: disable */ }; -/* This data structure keep the current active BSS/IBSS's configuration that this STA */ +/* This data structure keeps the current active BSS/IBSS's configuration that this STA */ /* had agreed upon joining the network. Which means these parameters are usually decided */ -/* by the BSS/IBSS creator instead of user configuration. Data in this data structurre */ +/* by the BSS/IBSS creator instead of user configuration. Data in this data structure */ /* is valid only when either ADHOC_ON(pAd) or INFRA_ON(pAd) is TRUE. */ /* Normally, after SCAN or failed roaming attempts, we need to recover back to */ /* the current active settings. */ @@ -1519,7 +1520,7 @@ struct rt_mac_table_entry { /*Choose 1 from ValidAsWDS and ValidAsCLI to validize. */ BOOLEAN ValidAsCLI; /* Sta mode, set this TRUE after Linkup,too. */ BOOLEAN ValidAsWDS; /* This is WDS Entry. only for AP mode. */ - BOOLEAN ValidAsApCli; /*This is a AP-Client entry, only for AP mode which enable AP-Client functions. */ + BOOLEAN ValidAsApCli; /* This is a AP-Client entry, only for AP mode which enable AP-Client functions. */ BOOLEAN ValidAsMesh; BOOLEAN ValidAsDls; /* This is DLS Entry. only for STA mode. */ BOOLEAN isCached; @@ -1527,7 +1528,7 @@ struct rt_mac_table_entry { u8 EnqueueEapolStartTimerRunning; /* Enqueue EAPoL-Start for triggering EAP SM */ /*jan for wpa */ - /* record which entry revoke MIC Failure , if it leaves the BSS itself, AP won't update aMICFailTime MIB */ + /* record which entry revoke MIC Failure, if it leaves the BSS itself, AP won't update aMICFailTime MIB */ u8 CMTimerRunning; u8 apidx; /* MBSS number */ u8 RSNIE_Len; @@ -1722,7 +1723,7 @@ struct rt_rtmp_adapter { unsigned long Rt3xxRalinkLinkCtrl; /* USed for 3090F chip */ u16 DeviceID; /* Read from PCI config */ unsigned long AccessBBPFailCount; - BOOLEAN bPCIclkOff; /* flag that indicate if the PICE power status in Configuration SPace.. */ + BOOLEAN bPCIclkOff; /* flag that indicates if the PICE power status in Configuration Space.. */ BOOLEAN bPCIclkOffDisableTx; /* */ BOOLEAN brt30xxBanMcuCmd; /*when = 0xff means all commands are ok to set . */ @@ -1871,9 +1872,9 @@ struct rt_rtmp_adapter { /* ---------------------------- */ u8 RfIcType; /* RFIC_xxx */ unsigned long RfFreqOffset; /* Frequency offset for channel switching */ - struct rt_rtmp_rf_regs LatchRfRegs; /* latch th latest RF programming value since RF IC doesn't support READ */ + struct rt_rtmp_rf_regs LatchRfRegs; /* latch the latest RF programming value since RF IC doesn't support READ */ - EEPROM_ANTENNA_STRUC Antenna; /* Since ANtenna definition is different for a & g. We need to save it for future reference. */ + EEPROM_ANTENNA_STRUC Antenna; /* Since Antenna definition is different for a & g. We need to save it for future reference. */ EEPROM_NIC_CONFIG2_STRUC NicConfig2; /* This soft Rx Antenna Diversity mechanism is used only when user set */ @@ -1990,7 +1991,7 @@ struct rt_rtmp_adapter { struct rt_common_config CommonCfg; struct rt_mlme Mlme; - /* AP needs those vaiables for site survey feature. */ + /* AP needs those variables for site survey feature. */ struct rt_mlme_aux MlmeAux; /* temporary settings used during MLME state machine */ struct rt_bss_table ScanTab; /* store the latest SCAN result */ @@ -2012,7 +2013,7 @@ struct rt_rtmp_adapter { /* various Counters */ struct rt_counter_802_3 Counters8023; /* 802.3 counters */ struct rt_counter_802_11 WlanCounters; /* 802.11 MIB counters */ - struct rt_counter_ralink RalinkCounters; /* Ralink propriety counters */ + struct rt_counter_ralink RalinkCounters; /* Ralink proprietary counters */ struct rt_counter_drs DrsCounters; /* counters for Dynamic TX Rate Switching */ struct rt_private PrivateInfo; /* Private information & counters */ @@ -2024,7 +2025,7 @@ struct rt_rtmp_adapter { u16 Sequence; /* Control disconnect / connect event generation */ - /*+++Didn't used anymore */ + /*+++Not used anymore */ unsigned long LinkDownTime; /*--- */ unsigned long LastRxRate; @@ -2036,7 +2037,7 @@ struct rt_rtmp_adapter { unsigned long ExtraInfo; /* Extra information for displaying status */ unsigned long SystemErrorBitmap; /* b0: E2PROM version error */ - /*+++Didn't used anymore */ + /*+++Not used anymore */ unsigned long MacIcVersion; /* MAC/BBP serial interface issue solved after ver.D */ /*--- */ @@ -2089,7 +2090,7 @@ struct rt_rtmp_adapter { unsigned long BulkOutReq; unsigned long BulkOutComplete; unsigned long BulkOutCompleteOther; - unsigned long BulkOutCompleteCancel; /* seems not use now? */ + unsigned long BulkOutCompleteCancel; /* seems not used now? */ unsigned long BulkInReq; unsigned long BulkInComplete; unsigned long BulkInCompleteFail; @@ -2196,9 +2197,9 @@ struct rt_rx_blk { struct rt_tx_blk { u8 QueIdx; u8 TxFrameType; /* Indicate the Transmission type of the all frames in one batch */ - u8 TotalFrameNum; /* Total frame number want to send-out in one batch */ + u8 TotalFrameNum; /* Total frame number that wants to send-out in one batch */ u16 TotalFragNum; /* Total frame fragments required in one batch */ - u16 TotalFrameLen; /* Total length of all frames want to send-out in one batch */ + u16 TotalFrameLen; /* Total length of all frames that wants to send-out in one batch */ struct rt_queue_header TxPacketList; struct rt_mac_table_entry *pMacEntry; /* NULL: packet with 802.11 RA field is multicast/broadcast address */ @@ -2207,7 +2208,7 @@ struct rt_tx_blk { /* Following structure used for the characteristics of a specific packet. */ void *pPacket; u8 *pSrcBufHeader; /* Reference to the head of sk_buff->data */ - u8 *pSrcBufData; /* Reference to the sk_buff->data, will changed depends on hanlding progresss */ + u8 *pSrcBufData; /* Reference to the sk_buff->data, will change depending on the handling progresss */ u32 SrcBufLen; /* Length of packet payload which not including Layer 2 header */ u8 *pExtraLlcSnapEncap; /* NULL means no extra LLC/SNAP is required */ u8 HeaderBuf[128]; /* TempBuffer for TX_INFO + TX_WI + 802.11 Header + padding + AMSDU SubHeader + LLC/SNAP */ @@ -2219,7 +2220,7 @@ struct rt_tx_blk { u8 apidx; /* The interface associated to this packet */ u8 Wcid; /* The MAC entry associated to this packet */ u8 UserPriority; /* priority class of packet */ - u8 FrameGap; /* what kind of IFS this packet use */ + u8 FrameGap; /* what kind of IFS does this packet use */ u8 MpduReqNum; /* number of fragments of this frame */ u8 TxRate; /* TODO: Obsoleted? Should change to MCS? */ u8 CipherAlg; /* cipher alogrithm */ diff --git a/drivers/staging/rt2860/rtmp_def.h b/drivers/staging/rt2860/rtmp_def.h index 9c54bacb845b..6ac617e7c9bb 100644 --- a/drivers/staging/rt2860/rtmp_def.h +++ b/drivers/staging/rt2860/rtmp_def.h @@ -31,10 +31,11 @@ Miniport related definition header Revision History: - Who When What + Who When What -------- ---------- ---------------------------------------------- - Paul Lin 08-01-2002 created - John Chang 08-05-2003 add definition for 11g & other drafts + Paul Lin 08-01-2002 created + John Chang 08-05-2003 add definition for 11g & other drafts + Justin P. Mattock 11/07/2010 Fix some typos */ #ifndef __RTMP_DEF_H__ #define __RTMP_DEF_H__ @@ -111,11 +112,11 @@ WMM Note: If memory of your system is not much, please reduce the definition; or when you do WMM test, the queue for low priority AC will be full, i.e. TX_RING_SIZE + MAX_PACKETS_IN_QUEUE packets for the AC will be buffered in - WLAN, maybe no any packet buffer can be got in Ethernet driver. + WLAN, maybe no packet buffers can get into the Ethernet driver. - Sometimes no packet buffer can be got in Ethernet driver, the system will + Sometimes no packet buffer can be get into the Ethernet driver, the system will send flow control packet to the sender to slow down its sending rate. - So no WMM can be saw in the air. + So no WMM can be seen in the air. */ /* @@ -125,7 +126,7 @@ And in rt_main_end.c, clConfig.clNum = RX_RING_SIZE * 3; is changed to clConfig.clNum = RX_RING_SIZE * 4; */ -/* TODO: For VxWorks the size is 256. Shall we cahnge the value as 256 for all OS????? */ +/* TODO: For VxWorks the size is 256. Shall we change the value as 256 for all OS? */ #define MAX_PACKETS_IN_QUEUE (512) /*(512) // to pass WMM A5-WPAPSK */ #define MAX_PACKETS_IN_MCAST_PS_QUEUE 32 @@ -171,7 +172,7 @@ #define fRTMP_ADAPTER_SCAN_2040 0x04000000 #define fRTMP_ADAPTER_RADIO_MEASUREMENT 0x08000000 -#define fRTMP_ADAPTER_START_UP 0x10000000 /*Devive already initialized and enabled Tx/Rx. */ +#define fRTMP_ADAPTER_START_UP 0x10000000 /*Device already initialized and enabled Tx/Rx. */ #define fRTMP_ADAPTER_MEDIA_STATE_CHANGE 0x20000000 #define fRTMP_ADAPTER_IDLE_RADIO_OFF 0x40000000 @@ -205,8 +206,8 @@ #define fRTMP_PS_SET_PCI_CLK_OFF_COMMAND 0x00000002 /* Indicate driver should disable kick off hardware to send packets from now. */ #define fRTMP_PS_DISABLE_TX 0x00000004 -/* Indicate driver should IMMEDIATELY fo to sleep after receiving AP's beacon in which doesn't indicate unicate nor multicast packets for me */ -/*. This flag is used ONLY in RTMPHandleRxDoneInterrupt routine. */ +/* Indicate driver should IMMEDIATELY go to sleep after receiving AP's beacon in which doesn't indicate unicate nor multicast packets for me */ +/* This flag is used ONLY in RTMPHandleRxDoneInterrupt routine. */ #define fRTMP_PS_GO_TO_SLEEP_NOW 0x00000008 #define fRTMP_PS_TOGGLE_L1 0x00000010 /* Use Toggle L1 mechanism for rt28xx PCIe */ @@ -303,7 +304,7 @@ /* WDS definition */ #define MAX_WDS_ENTRY 4 -#define WDS_PAIRWISE_KEY_OFFSET 60 /* WDS links uses pairwise key#60 ~ 63 in ASIC pairwise key table */ +#define WDS_PAIRWISE_KEY_OFFSET 60 /* WDS links use pairwise key#60 ~ 63 in ASIC pairwise key table */ #define WDS_DISABLE_MODE 0 #define WDS_RESTRICT_MODE 1 @@ -559,7 +560,7 @@ #define IE_ADD_HT2 53 /* 802.11n d1. ADDITIONAL HT CAPABILITY. ELEMENT ID TBD */ /* For 802.11n D3.03 */ -/*#define IE_NEW_EXT_CHA_OFFSET 62 // 802.11n d1. New extension channel offset elemet */ +/*#define IE_NEW_EXT_CHA_OFFSET 62 // 802.11n d1. New extension channel offset element */ #define IE_SECONDARY_CH_OFFSET 62 /* 802.11n D3.03 Secondary Channel Offset element */ #define IE_WAPI 68 /* WAPI information element */ #define IE_2040_BSS_COEXIST 72 /* 802.11n D3.0.3 */ @@ -678,7 +679,7 @@ #define ACT_MACHINE_BASE 0 -/*Those PEER_xx_CATE number is based on real Categary value in IEEE spec. Please don'es modify it by your self. */ +/*Those PEER_xx_CATE number is based on real Categary value in IEEE spec. Please do not modify it by your self. */ /*Category */ #define MT2_PEER_SPECTRUM_CATE 0 #define MT2_PEER_QOS_CATE 1 @@ -748,7 +749,7 @@ #define ACT_FUNC_SIZE (MAX_ACT_STATE * MAX_ACT_MSG) /* */ -/* STA's AUTHENTICATION state machine: states, evvents, total function # */ +/* STA's AUTHENTICATION state machine: states, events, total function # */ /* */ #define AUTH_REQ_IDLE 0 #define AUTH_WAIT_SEQ2 1 @@ -948,7 +949,7 @@ #define BLOCK_ACK 0x60 /* b6:5 = 11 */ /* */ -/* rtmp_data.c use these definition */ +/* rtmp_data.c uses this definition */ /* */ #define LENGTH_802_11 24 #define LENGTH_802_11_AND_H 30 @@ -1288,7 +1289,7 @@ #define IW_STA_LINKDOWN_EVENT_FLAG 0x0210 #define IW_SCAN_COMPLETED_EVENT_FLAG 0x0211 #define IW_SCAN_ENQUEUE_FAIL_EVENT_FLAG 0x0212 -/* if add new system event flag, please upadte the IW_SYS_EVENT_FLAG_END */ +/* if add new system event flag, please update the IW_SYS_EVENT_FLAG_END */ #define IW_SYS_EVENT_FLAG_END 0x0212 #define IW_SYS_EVENT_TYPE_NUM (IW_SYS_EVENT_FLAG_END - IW_SYS_EVENT_FLAG_START + 1) /* For system event - end */ @@ -1305,7 +1306,7 @@ #define IW_SPOOF_DEAUTH_EVENT_FLAG 0x0307 #define IW_SPOOF_UNKNOWN_MGMT_EVENT_FLAG 0x0308 #define IW_REPLAY_ATTACK_EVENT_FLAG 0x0309 -/* if add new spoof attack event flag, please upadte the IW_SPOOF_EVENT_FLAG_END */ +/* if add new spoof attack event flag, please update the IW_SPOOF_EVENT_FLAG_END */ #define IW_SPOOF_EVENT_FLAG_END 0x0309 #define IW_SPOOF_EVENT_TYPE_NUM (IW_SPOOF_EVENT_FLAG_END - IW_SPOOF_EVENT_FLAG_START + 1) /* For spoof attack event - end */ @@ -1319,7 +1320,7 @@ #define IW_FLOOD_DISASSOC_EVENT_FLAG 0x0404 #define IW_FLOOD_DEAUTH_EVENT_FLAG 0x0405 #define IW_FLOOD_EAP_REQ_EVENT_FLAG 0x0406 -/* if add new flooding attack event flag, please upadte the IW_FLOOD_EVENT_FLAG_END */ +/* if add new flooding attack event flag, please update the IW_FLOOD_EVENT_FLAG_END */ #define IW_FLOOD_EVENT_FLAG_END 0x0406 #define IW_FLOOD_EVENT_TYPE_NUM (IW_FLOOD_EVENT_FLAG_END - IW_FLOOD_EVENT_FLAG_START + 1) /* For flooding attack - end */ diff --git a/drivers/staging/rt2860/rtmp_timer.h b/drivers/staging/rt2860/rtmp_timer.h index 28b8ac6e8352..15b628743500 100644 --- a/drivers/staging/rt2860/rtmp_timer.h +++ b/drivers/staging/rt2860/rtmp_timer.h @@ -28,13 +28,14 @@ rtmp_timer.h Abstract: - Ralink Wireless Driver timer related data structures and delcarations + Ralink Wireless Driver timer related data structures and declarations Revision History: - Who When What + Who When What -------- ---------- ---------------------------------------------- - Name Date Modification logs - Shiang Tu Aug-28-2008 init version + Name Date Modification logs + Shiang Tu Aug-28-2008 init version + Justin P. Mattock 11/07/2010 Fix a typo */ @@ -51,8 +52,8 @@ /* ----------------- Timer Related MARCO ---------------*/ /* In some os or chipset, we have a lot of timer functions and will read/write register, */ -/* it's not allowed in Linux USB sub-system to do it ( because of sleep issue when */ -/* submit to ctrl pipe). So we need a wrapper function to take care it. */ +/* it's not allowed in Linux USB sub-system to do it ( because of sleep issue when */ +/* submit to ctrl pipe). So we need a wrapper function to take care it. */ #ifdef RTMP_TIMER_TASK_SUPPORT typedef void(*RTMP_TIMER_TASK_HANDLE) (void *SystemSpecific1, diff --git a/drivers/staging/rt2860/spectrum.h b/drivers/staging/rt2860/spectrum.h index 648fd632b606..4c325ba7ba21 100644 --- a/drivers/staging/rt2860/spectrum.h +++ b/drivers/staging/rt2860/spectrum.h @@ -37,7 +37,7 @@ char RTMP_GetTxPwr(struct rt_rtmp_adapter *pAd, IN HTTRANSMIT_SETTING HTTxMode); ========================================================================== Description: Prepare Measurement request action frame and enqueue it into - management queue waiting for transmition. + management queue waiting for transmission. Parametrs: 1. the destination mac address of the frame. @@ -60,7 +60,7 @@ void MakeMeasurementReqFrame(struct rt_rtmp_adapter *pAd, ========================================================================== Description: Prepare Measurement report action frame and enqueue it into - management queue waiting for transmition. + management queue waiting for transmission. Parametrs: 1. the destination mac address of the frame. @@ -80,7 +80,7 @@ void EnqueueMeasurementRep(struct rt_rtmp_adapter *pAd, ========================================================================== Description: Prepare TPC Request action frame and enqueue it into - management queue waiting for transmition. + management queue waiting for transmission. Parametrs: 1. the destination mac address of the frame. @@ -94,7 +94,7 @@ void EnqueueTPCReq(struct rt_rtmp_adapter *pAd, u8 *pDA, u8 DialogToken); ========================================================================== Description: Prepare TPC Report action frame and enqueue it into - management queue waiting for transmition. + management queue waiting for transmission. Parametrs: 1. the destination mac address of the frame. @@ -110,7 +110,7 @@ void EnqueueTPCRep(struct rt_rtmp_adapter *pAd, ========================================================================== Description: Prepare Channel Switch Announcement action frame and enqueue it into - management queue waiting for transmition. + management queue waiting for transmission. Parametrs: 1. the destination mac address of the frame. @@ -126,7 +126,7 @@ void EnqueueChSwAnn(struct rt_rtmp_adapter *pAd, /* ========================================================================== Description: - Spectrun action frames Handler such as channel switch annoucement, + Spectrun action frames Handler such as channel switch announcement, measurement report, measurement request actions frames. Parametrs: diff --git a/drivers/staging/rt2860/sta/assoc.c b/drivers/staging/rt2860/sta/assoc.c index b7efb0b6b3f0..ab0a83bf76ef 100644 --- a/drivers/staging/rt2860/sta/assoc.c +++ b/drivers/staging/rt2860/sta/assoc.c @@ -32,7 +32,8 @@ Revision History: Who When What -------- ---------- ---------------------------------------------- - John 2004-9-3 porting from RT2500 + John 2004-9-3 porting from RT2500 + Justin P. Mattock 11/07/2010 Fix typos */ #include "../rt_config.h" @@ -277,10 +278,10 @@ void MlmeAssocReqAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem * u16 VarIesOffset; u16 Status; - /* Block all authentication request durning WPA block period */ + /* Block all authentication request during WPA block period */ if (pAd->StaCfg.bBlockAssoc == TRUE) { DBGPRINT(RT_DEBUG_TRACE, - ("ASSOC - Block Assoc request durning WPA block period!\n")); + ("ASSOC - Block Assoc request during WPA block period!\n")); pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE; Status = MLME_STATE_MACHINE_REJECT; MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_ASSOC_CONF, 2, @@ -605,10 +606,10 @@ void MlmeReassocReqAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem u8 *pOutBuffer = NULL; u16 Status; - /* Block all authentication request durning WPA block period */ + /* Block all authentication request during WPA block period */ if (pAd->StaCfg.bBlockAssoc == TRUE) { DBGPRINT(RT_DEBUG_TRACE, - ("ASSOC - Block ReAssoc request durning WPA block period!\n")); + ("ASSOC - Block ReAssoc request during WPA block period!\n")); pAd->Mlme.AssocMachine.CurrState = ASSOC_IDLE; Status = MLME_STATE_MACHINE_REJECT; MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_REASSOC_CONF, 2, @@ -1001,7 +1002,7 @@ void AssocPostProc(struct rt_rtmp_adapter *pAd, u8 *pAddr2, u16 CapabilityInfo, pAd->MlmeAux.CapabilityInfo = CapabilityInfo & SUPPORTED_CAPABILITY_INFO; - /* Some HT AP might lost WMM IE. We add WMM ourselves. beacuase HT requires QoS on. */ + /* Some HT AP might lost WMM IE. We add WMM ourselves. because HT requires QoS on. */ if ((HtCapabilityLen > 0) && (pEdcaParm->bValid == FALSE)) { pEdcaParm->bValid = TRUE; pEdcaParm->Aifsn[0] = 3; diff --git a/drivers/staging/rt2860/sta/auth.c b/drivers/staging/rt2860/sta/auth.c index 404bd220679d..a2bfafddb20e 100644 --- a/drivers/staging/rt2860/sta/auth.c +++ b/drivers/staging/rt2860/sta/auth.c @@ -32,7 +32,8 @@ Revision History: Who When What -------- ---------- ---------------------------------------------- - John 2004-9-3 porting from RT2500 + John 2004-9-3 porting from RT2500 + Justin P. Mattock 11/07/2010 Fix typos */ #include "../rt_config.h" @@ -455,10 +456,10 @@ BOOLEAN AUTH_ReqSend(struct rt_rtmp_adapter *pAd, u8 *pOutBuffer = NULL; unsigned long FrameLen = 0, tmp = 0; - /* Block all authentication request durning WPA block period */ + /* Block all authentication request during WPA block period */ if (pAd->StaCfg.bBlockAssoc == TRUE) { DBGPRINT(RT_DEBUG_TRACE, - ("%s - Block Auth request durning WPA block period!\n", + ("%s - Block Auth request during WPA block period!\n", pSMName)); pAd->Mlme.AuthMachine.CurrState = AUTH_REQ_IDLE; Status = MLME_STATE_MACHINE_REJECT; diff --git a/drivers/staging/rt2860/sta/connect.c b/drivers/staging/rt2860/sta/connect.c index c380551c0354..4b2c84e6509e 100644 --- a/drivers/staging/rt2860/sta/connect.c +++ b/drivers/staging/rt2860/sta/connect.c @@ -32,7 +32,8 @@ Revision History: Who When What -------- ---------- ---------------------------------------------- - John 2004-08-08 Major modification from RT2560 + John 2004-08-08 Major modification from RT2560 + Justin P. Mattock 11/07/2010 Fix typos */ #include "../rt_config.h" @@ -64,7 +65,7 @@ u8 CipherSuiteWpaNoneAesLen = /* The following MACRO is called after 1. starting an new IBSS, 2. successfully JOIN an IBSS, */ /* or 3. successfully ASSOCIATE to a BSS, 4. successfully RE_ASSOCIATE to a BSS */ -/* All settings successfuly negotiated furing MLME state machines become final settings */ +/* All settings successfuly negotiated firing MLME state machines become final settings */ /* and are copied to pAd->StaActive */ #define COPY_SETTINGS_FROM_MLME_AUX_TO_ACTIVE_CFG(_pAd) \ { \ @@ -553,7 +554,7 @@ void CntlOidRTBssidProc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem * NdisMoveMemory(&pAd->MlmeAux.SsidBssTab.BssEntry[0], &pAd->ScanTab.BssEntry[BssIdx], sizeof(struct rt_bss_entry)); - /* Add SSID into MlmeAux for site surey joining hidden SSID */ + /* Add SSID into MlmeAux for site survey joining hidden SSID */ pAd->MlmeAux.SsidLen = pAd->ScanTab.BssEntry[BssIdx].SsidLen; NdisMoveMemory(pAd->MlmeAux.Ssid, pAd->ScanTab.BssEntry[BssIdx].Ssid, pAd->MlmeAux.SsidLen); @@ -666,7 +667,7 @@ void CntlOidRTBssidProc(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem * } /* Roaming is the only external request triggering CNTL state machine */ -/* despite of other "SET OID" operation. All "SET OID" related oerations */ +/* despite of other "SET OID" operation. All "SET OID" related operations */ /* happen in sequence, because no other SET OID will be sent to this device */ /* until the the previous SET operation is complete (successful o failed). */ /* So, how do we quarantee this ROAMING request won't corrupt other "SET OID"? */ @@ -1224,7 +1225,7 @@ void LinkUp(struct rt_rtmp_adapter *pAd, u8 BssType) /* Change to AP channel */ if ((pAd->CommonCfg.CentralChannel > pAd->CommonCfg.Channel) && (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_40)) { - /* Must using 40MHz. */ + /* Must use 40MHz. */ pAd->CommonCfg.BBPCurrentBW = BW_40; AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE); AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel); @@ -1259,7 +1260,7 @@ void LinkUp(struct rt_rtmp_adapter *pAd, u8 BssType) } else if ((pAd->CommonCfg.CentralChannel < pAd->CommonCfg.Channel) && (pAd->MlmeAux.HtCapability.HtCapInfo.ChannelWidth == BW_40)) { - /* Must using 40MHz. */ + /* Must use 40MHz. */ pAd->CommonCfg.BBPCurrentBW = BW_40; AsicSwitchChannel(pAd, pAd->CommonCfg.CentralChannel, FALSE); AsicLockChannel(pAd, pAd->CommonCfg.CentralChannel); @@ -1343,12 +1344,12 @@ void LinkUp(struct rt_rtmp_adapter *pAd, u8 BssType) AsicSetSlotTime(pAd, TRUE); AsicSetEdcaParm(pAd, &pAd->CommonCfg.APEdcaParm); - /* Call this for RTS protectionfor legacy rate, we will always enable RTS threshold, but normally it will not hit */ + /* Call this for RTS protection for legacy rate, we will always enable RTS threshold, but normally it will not hit */ AsicUpdateProtect(pAd, 0, (OFDMSETPROTECT | CCKSETPROTECT), TRUE, FALSE); if ((pAd->StaActive.SupportedPhyInfo.bHtEnable == TRUE)) { - /* Update HT protectionfor based on AP's operating mode. */ + /* Update HT protection for based on AP's operating mode. */ if (pAd->MlmeAux.AddHtInfo.AddHtInfo2.NonGfPresent == 1) { AsicUpdateProtect(pAd, pAd->MlmeAux.AddHtInfo.AddHtInfo2. @@ -1530,7 +1531,7 @@ void LinkUp(struct rt_rtmp_adapter *pAd, u8 BssType) /* Add BSSID to WCID search table */ AsicUpdateRxWCIDTable(pAd, BSSID_WCID, pAd->CommonCfg.Bssid); - /* If WEP is enabled, add paiewise and shared key */ + /* If WEP is enabled, add pairwise and shared key */ if (((pAd->StaCfg.WpaSupplicantUP) && (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled) && (pAd->StaCfg.PortSecured == WPA_802_1X_PORT_SECURED)) || @@ -1681,9 +1682,9 @@ void LinkUp(struct rt_rtmp_adapter *pAd, u8 BssType) pAd->Mlme.PeriodicRound = 0; pAd->Mlme.OneSecPeriodicRound = 0; pAd->bConfigChanged = FALSE; /* Reset config flag */ - pAd->ExtraInfo = GENERAL_LINK_UP; /* Update extra information to link is up */ + pAd->ExtraInfo = GENERAL_LINK_UP; /* Update extra information after link is up */ - /* Set asic auto fall back */ + /* Set basic auto fall back */ { u8 *pTable; u8 TableSize = 0; @@ -1854,8 +1855,8 @@ void LinkUp(struct rt_rtmp_adapter *pAd, u8 BssType) Note: We need more information to know it's this requst from AP. If yes! we need to do extra handling, for example, remove the WPA key. - Otherwise on 4-way handshaking will faied, since the WPA key didn't be - remove while auto reconnect. + Otherwise on 4-way handshaking will fail, since the WPA key didn't get + removed while auto reconnect. Disconnect request from AP, it means we will start afresh 4-way handshaking on WPA mode. @@ -1870,9 +1871,9 @@ void LinkDown(struct rt_rtmp_adapter *pAd, IN BOOLEAN IsReqFromAP) return; RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_GO_TO_SLEEP_NOW); - /*Comment the codes, beasue the line 2291 call the same function. */ - /*RTMPCancelTimer(&pAd->Mlme.PsPollTimer, &Cancelled); */ - /* Not allow go to sleep within linkdown function. */ + /* Comment the codes, because the line 2291 call the same function. */ + /* RTMPCancelTimer(&pAd->Mlme.PsPollTimer, &Cancelled); */ + /* Not allowed go to sleep within the linkdown function. */ RTMP_CLEAR_PSFLAG(pAd, fRTMP_PS_CAN_GO_SLEEP); if (pAd->CommonCfg.bWirelessEvent) { @@ -1970,7 +1971,7 @@ void LinkDown(struct rt_rtmp_adapter *pAd, IN BOOLEAN IsReqFromAP) /* Set LED */ RTMPSetLED(pAd, LED_LINK_DOWN); pAd->LedIndicatorStrength = 0xF0; - RTMPSetSignalLED(pAd, -100); /* Force signal strength Led to be turned off, firmware is not done it. */ + RTMPSetSignalLED(pAd, -100); /* Force signal strength Led to be turned off, firmware has not done it. */ AsicDisableSync(pAd); diff --git a/drivers/staging/rt2860/sta/rtmp_data.c b/drivers/staging/rt2860/sta/rtmp_data.c index 23879b7cd49a..d7c2012be8a5 100644 --- a/drivers/staging/rt2860/sta/rtmp_data.c +++ b/drivers/staging/rt2860/sta/rtmp_data.c @@ -31,7 +31,8 @@ Data path subroutines Revision History: - Who When What + Who When What + Justin P. Mattock 11/07/2010 Fix typos -------- ---------- ---------------------------------------------- */ #include "../rt_config.h" @@ -257,8 +258,8 @@ void STARxDataFrameAnnounce(struct rt_rtmp_adapter *pAd, && (pAd->CommonCfg.bDisableReordering == 0)) { Indicate_AMPDU_Packet(pAd, pRxBlk, FromWhichBSSID); } else { - /* Determin the destination of the EAP frame */ - /* to WPA state machine or upper layer */ + /* Determine the destination of the EAP frame */ + /* to WPA state machine or upper layer */ STARxEAPOLFrameIndicate(pAd, pEntry, pRxBlk, FromWhichBSSID); } @@ -853,7 +854,7 @@ Return Value: NONE Note: - This function do early checking and classification for send-out packet. + This function does early checking and classification for send-out packet. You only can put OS-depened & STA related code in here. ======================================================================== */ @@ -943,7 +944,7 @@ int STASendPacket(struct rt_rtmp_adapter *pAd, void *pPacket) DBGPRINT(RT_DEBUG_ERROR, ("STASendPacket --> pSrcBufVA == NULL !SrcBufLen=%x\n", SrcBufLen)); - /* Resourece is low, system did not allocate virtual address */ + /* Resource is low, system did not allocate virtual address */ /* return NDIS_STATUS_FAILURE directly to upper layer */ RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE); return NDIS_STATUS_FAILURE; @@ -979,7 +980,7 @@ int STASendPacket(struct rt_rtmp_adapter *pAd, void *pPacket) DBGPRINT(RT_DEBUG_ERROR, ("STASendPacket->Cannot find pEntry(%pM) in MacTab!\n", pSrcBufVA)); - /* Resourece is low, system did not allocate virtual address */ + /* Resource is low, system did not allocate virtual address */ /* return NDIS_STATUS_FAILURE directly to upper layer */ RELEASE_NDIS_PACKET(pAd, pPacket, NDIS_STATUS_FAILURE); return NDIS_STATUS_FAILURE; @@ -1057,9 +1058,9 @@ int STASendPacket(struct rt_rtmp_adapter *pAd, void *pPacket) /* STEP 2. Check the requirement of RTS: */ /* If multiple fragment required, RTS is required only for the first fragment */ - /* if the fragment size large than RTS threshold */ + /* if the fragment size is larger than RTS threshold */ /* For RT28xx, Let ASIC send RTS/CTS */ -/* RTMP_SET_PACKET_RTS(pPacket, 0); */ + /* RTMP_SET_PACKET_RTS(pPacket, 0); */ if (NumberOfFrag > 1) RTSRequired = (pAd->CommonCfg.FragmentThreshold > @@ -1171,8 +1172,8 @@ int STASendPacket(struct rt_rtmp_adapter *pAd, void *pPacket) ======================================================================== Routine Description: - This subroutine will scan through releative ring descriptor to find - out avaliable free ring descriptor and compare with request size. + This subroutine will scan through relative ring descriptor to find + out available free ring descriptor and compare with request size. Arguments: pAd Pointer to our adapter @@ -1588,7 +1589,7 @@ static inline u8 *STA_Build_ARalink_Frame_Header(struct rt_rtmp_adapter *pAd, pHeaderBufPtr += 2; pTxBlk->MpduHeaderLen += 2; } - /* padding at front of LLC header. LLC header should at 4-bytes aligment. */ + /* padding at front of LLC header. LLC header should at 4-bytes alignment. */ pTxBlk->HdrPadLen = (unsigned long)pHeaderBufPtr; pHeaderBufPtr = (u8 *)ROUND_UP(pHeaderBufPtr, 4); pTxBlk->HdrPadLen = (unsigned long)(pHeaderBufPtr - pTxBlk->HdrPadLen); @@ -2014,7 +2015,7 @@ void STA_Legacy_Frame_Tx(struct rt_rtmp_adapter *pAd, struct rt_tx_blk *pTxBlk) pHeaderBufPtr += 2; pTxBlk->MpduHeaderLen += 2; } - /* The remaining content of MPDU header should locate at 4-octets aligment */ + /* The remaining content of MPDU header should locate at 4-octets alignment */ pTxBlk->HdrPadLen = (unsigned long)pHeaderBufPtr; pHeaderBufPtr = (u8 *)ROUND_UP(pHeaderBufPtr, 4); pTxBlk->HdrPadLen = (unsigned long)(pHeaderBufPtr - pTxBlk->HdrPadLen); @@ -2114,7 +2115,7 @@ void STA_ARalink_Frame_Tx(struct rt_rtmp_adapter *pAd, struct rt_tx_blk *pTxBlk) STA_Build_ARalink_Frame_Header(pAd, pTxBlk); /* It's ok write the TxWI here, because the TxWI->MPDUtotalByteCount */ - /* will be updated after final frame was handled. */ + /* will be updated after final frame was handled. */ RTMPWriteTxWI_Data(pAd, (struct rt_txwi *) (&pTxBlk-> HeaderBuf @@ -2291,8 +2292,8 @@ void STA_Fragment_Frame_Tx(struct rt_rtmp_adapter *pAd, struct rt_tx_blk *pTxBlk pTxBlk->pExtraLlcSnapEncap, pTxBlk->pKey, 0); - /* NOTE: DON'T refer the skb->len directly after following copy. Becasue the length is not adjust */ - /* to correct lenght, refer to pTxBlk->SrcBufLen for the packet length in following progress. */ + /* NOTE: DON'T refer the skb->len directly after following copy. Because the length is not adjusted */ + /* to correct length, refer to pTxBlk->SrcBufLen for the packet length in following progress. */ NdisMoveMemory(pTxBlk->pSrcBufData + pTxBlk->SrcBufLen, &pAd->PrivateInfo.Tx.MIC[0], 8); /*skb_put((RTPKT_TO_OSPKT(pTxBlk->pPacket))->tail, 8); */ @@ -2301,7 +2302,7 @@ void STA_Fragment_Frame_Tx(struct rt_rtmp_adapter *pAd, struct rt_tx_blk *pTxBlk pTxBlk->CipherAlg = CIPHER_TKIP_NO_MIC; } /* */ - /* calcuate the overhead bytes that encryption algorithm may add. This */ + /* calculate the overhead bytes that encryption algorithm may add. This */ /* affects the calculate of "duration" field */ /* */ if ((pTxBlk->CipherAlg == CIPHER_WEP64) diff --git a/drivers/staging/rt2860/sta/sanity.c b/drivers/staging/rt2860/sta/sanity.c index 8f9fd19be151..0c32604f2d3f 100644 --- a/drivers/staging/rt2860/sta/sanity.c +++ b/drivers/staging/rt2860/sta/sanity.c @@ -32,7 +32,8 @@ Revision History: Who When What -------- ---------- ---------------------------------------------- - John Chang 2004-09-01 add WMM support + John Chang 2004-09-01 add WMM support + Justin P. Mattock 11/07/2010 Fix typos */ #include "../rt_config.h" @@ -118,7 +119,7 @@ BOOLEAN PeerAssocRspSanity(struct rt_rtmp_adapter *pAd, void * pMsg, unsigned lo NdisMoveMemory(pAid, &pFrame->Octet[4], 2); Length += 2; - /* Aid already swaped byte order in RTMPFrameEndianChange() for big endian platform */ + /* Aid already swapped byte order in RTMPFrameEndianChange() for big endian platform */ *pAid = (*pAid) & 0x3fff; /* AID is low 14-bit */ /* -- get supported rates from payload and advance the pointer */ diff --git a/drivers/staging/rt2860/sta/sync.c b/drivers/staging/rt2860/sta/sync.c index 747d3c6d1851..05007d9c9b69 100644 --- a/drivers/staging/rt2860/sta/sync.c +++ b/drivers/staging/rt2860/sta/sync.c @@ -32,8 +32,9 @@ Revision History: Who When What -------- ---------- ---------------------------------------------- - John Chang 2004-09-01 modified for rt2561/2661 - Jan Lee 2006-08-01 modified for rt2860 for 802.11n + John Chang 2004-09-01 modified for rt2561/2661 + Jan Lee 2006-08-01 modified for rt2860 for 802.11n + Justin P. Mattock 11/07/2010 Fix typos */ #include "../rt_config.h" @@ -233,9 +234,9 @@ void MlmeScanReqAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *E RTMPSuspendMsduTransmission(pAd); /* */ - /* To prevent data lost. */ - /* Send an NULL data with turned PSM bit on to current associated AP before SCAN progress. */ - /* And should send an NULL data with turned PSM bit off to AP, when scan progress done */ + /* To prevent data loss. */ + /* Send a NULL data with turned PSM bit on to current associated AP before SCAN progress. */ + /* And should send a NULL data with turned PSM bit off to AP, when scan progress done */ /* */ if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED) && (INFRA_ON(pAd))) { @@ -750,9 +751,9 @@ void PeerBeaconAtJoinAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_el /* BEACON from desired BSS/IBSS found. We should be able to decide most */ /* BSS parameters here. */ - /* Q. But what happen if this JOIN doesn't conclude a successful ASSOCIATEION? */ - /* Do we need to receover back all parameters belonging to previous BSS? */ - /* A. Should be not. There's no back-door recover to previous AP. It still need */ + /* Q. But what happen if this JOIN doesn't conclude a successful ASSOCIATION? */ + /* Do we need to recover back all parameters belonging to previous BSS? */ + /* A. Should be not. There's no back-door recover to previous AP. It still needs */ /* a new JOIN-AUTH-ASSOC sequence. */ if (MAC_ADDR_EQUAL(pAd->MlmeAux.Bssid, Bssid)) { DBGPRINT(RT_DEBUG_TRACE, @@ -876,7 +877,7 @@ void PeerBeaconAtJoinAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_el pAd->MlmeAux.CfpMaxDuration = Cf.CfpMaxDuration; pAd->MlmeAux.APRalinkIe = RalinkIe; - /* Copy AP's supported rate to MlmeAux for creating assoication request */ + /* Copy AP's supported rate to MlmeAux for creating association request */ /* Also filter out not supported rate */ pAd->MlmeAux.SupRateLen = SupRateLen; NdisMoveMemory(pAd->MlmeAux.SupRate, SupRate, diff --git a/drivers/staging/rt2860/sta/wpa.c b/drivers/staging/rt2860/sta/wpa.c index 69b8a24daa21..ff348325028b 100644 --- a/drivers/staging/rt2860/sta/wpa.c +++ b/drivers/staging/rt2860/sta/wpa.c @@ -33,7 +33,8 @@ Who When What -------- ---------- ---------------------------------------------- Jan Lee 03-07-22 Initial - Paul Lin 03-11-28 Modify for supplicant + Paul Lin 03-11-28 Modify for supplicant + Justin P. Mattock 11/07/2010 Fix typos */ #include "../rt_config.h" @@ -86,7 +87,7 @@ void RTMPReportMicError(struct rt_rtmp_adapter *pAd, struct rt_cipher_key *pWpaK /* Violate MIC error counts, MIC countermeasures kicks in */ pAd->StaCfg.MicErrCnt++; /* We shall block all reception */ - /* We shall clean all Tx ring and disassoicate from AP after next EAPOL frame */ + /* We shall clean all Tx ring and disassociate from AP after next EAPOL frame */ /* */ /* No necessary to clean all Tx ring, on RTMPHardTransmit will stop sending non-802.1X EAPOL packets */ /* if pAd->StaCfg.MicErrCnt greater than 2. */ diff --git a/drivers/staging/rt2860/sta_ioctl.c b/drivers/staging/rt2860/sta_ioctl.c index e095a44cbc0e..5717e12a9544 100644 --- a/drivers/staging/rt2860/sta_ioctl.c +++ b/drivers/staging/rt2860/sta_ioctl.c @@ -31,10 +31,11 @@ IOCTL related subroutines Revision History: - Who When What + Who When What -------- ---------- ---------------------------------------------- - Rory Chen 01-03-2003 created - Rory Chen 02-14-2005 modify to support RT61 + Rory Chen 01-03-2003 created + Rory Chen 02-14-2005 modify to support RT61 + Justin P. Mattock 11/07/2010 Fix typos */ #include "rt_config.h" @@ -851,7 +852,7 @@ int rt_ioctl_giwscan(struct net_device *dev, /* Protocol: - it will show scanned AP's WirelessMode . + it will show scanned AP's WirelessMode. it might be 802.11a 802.11a/n @@ -875,13 +876,13 @@ int rt_ioctl_giwscan(struct net_device *dev, strcpy(iwe.u.name, "802.11a"); } else { /* - if one of non B mode rate is set supported rate . it mean G only. + if one of non B mode rate is set supported rate, it means G only. */ for (rateCnt = 0; rateCnt < pBssEntry->SupRateLen; rateCnt++) { /* - 6Mbps(140) 9Mbps(146) and >=12Mbps(152) are supported rate , it mean G only. + 6Mbps(140) 9Mbps(146) and >=12Mbps(152) are supported rate, it means G only. */ if (pBssEntry->SupRate[rateCnt] == 140 || pBssEntry->SupRate[rateCnt] == @@ -1417,7 +1418,7 @@ int rt_ioctl_siwencode(struct net_device *dev, if ((index >= 0) && (index < 4)) { pAdapter->StaCfg.DefaultKeyId = index; } else - /* Don't complain if only change the mode */ + /* Don't complain if the mode is only changed */ if (!(erq->flags & IW_ENCODE_MODE)) return -EINVAL; } @@ -2732,8 +2733,8 @@ int Set_NetworkType_Proc(struct rt_rtmp_adapter *pAdapter, char *arg) } if (INFRA_ON(pAdapter)) { /*BOOLEAN Cancelled; */ - /* Set the AutoReconnectSsid to prevent it reconnect to old SSID */ - /* Since calling this indicate user don't want to connect to that SSID anymore. */ + /* Set the AutoReconnectSsid to prevent it from reconnecting to the old SSID */ + /* Since calling this indicates users don't want to connect to that SSID anymore. */ pAdapter->MlmeAux.AutoReconnectSsidLen = 32; NdisZeroMemory(pAdapter->MlmeAux. AutoReconnectSsid, @@ -2766,8 +2767,8 @@ int Set_NetworkType_Proc(struct rt_rtmp_adapter *pAdapter, char *arg) LinkDown(pAdapter, FALSE); } if (ADHOC_ON(pAdapter)) { - /* Set the AutoReconnectSsid to prevent it reconnect to old SSID */ - /* Since calling this indicate user don't want to connect to that SSID anymore. */ + /* Set the AutoReconnectSsid to prevent it from reconnecting to the old SSID */ + /* Since calling this indicates users don't want to connect to that SSID anymore. */ pAdapter->MlmeAux.AutoReconnectSsidLen = 32; NdisZeroMemory(pAdapter->MlmeAux. AutoReconnectSsid, @@ -2884,7 +2885,7 @@ int Set_NetworkType_Proc(struct rt_rtmp_adapter *pAdapter, char *arg) } /* Enable Rx with promiscuous reception */ RTMP_IO_WRITE32(pAdapter, RX_FILTR_CFG, 0x3); - /* ASIC supporsts sniffer function with replacing RSSI with timestamp. */ + /* ASIC supports sniffer function with replacing RSSI with timestamp. */ /*RTMP_IO_READ32(pAdapter, MAC_SYS_CTRL, &Value); */ /*Value |= (0x80); */ /*RTMP_IO_WRITE32(pAdapter, MAC_SYS_CTRL, Value); */ diff --git a/drivers/staging/rt2860/usb_main_dev.c b/drivers/staging/rt2860/usb_main_dev.c index ebf9074a9083..a8820d3f6b3a 100644 --- a/drivers/staging/rt2860/usb_main_dev.c +++ b/drivers/staging/rt2860/usb_main_dev.c @@ -27,8 +27,8 @@ #include "rt_config.h" /* Following information will be show when you run 'modinfo' */ -/* *** If you have a solution for the bug in current version of driver, please mail to me. */ -/* Otherwise post to forum in ralinktech's web site(www.ralinktech.com) and let all users help you. *** */ +/* If you have a solution for the bug in current version of driver, please e-mail me. */ +/* Otherwise post to the forum at ralinktech's web site(www.ralinktech.com) and let all users help you. */ MODULE_AUTHOR("Paul Lin "); MODULE_DESCRIPTION("RT2870/RT3070 Wireless Lan Linux Driver"); MODULE_LICENSE("GPL"); @@ -882,8 +882,8 @@ static int __devinit rt2870_probe(IN struct usb_interface *intf, if (net_dev == NULL) goto err_out_free_radev; - /* Here are the net_device structure with usb specific parameters. */ - /* for supporting Network Manager. + /* Here are the net_device structure with usb specific parameters. + * for supporting Network Manager. * Set the sysfs physical device reference for the network logical device if set prior to registration will * cause a symlink during initialization. */ diff --git a/drivers/staging/rt2860/wpa.h b/drivers/staging/rt2860/wpa.h index 6199ae6cdcd0..116fc2caa886 100644 --- a/drivers/staging/rt2860/wpa.h +++ b/drivers/staging/rt2860/wpa.h @@ -32,13 +32,14 @@ Revision History: Who When What -------- ---------- ---------------------------------------------- - Name Date Modification logs + Name Date Modification logs + Justin P. Mattock 11/07/2010 Fix a typo */ #ifndef __WPA_H__ #define __WPA_H__ -/* EAPOL Key descripter frame format related length */ +/* EAPOL Key descriptor frame format related length */ #define LEN_KEY_DESC_NONCE 32 #define LEN_KEY_DESC_IV 16 #define LEN_KEY_DESC_RSC 8 -- cgit v1.2.3 From 60a1d01bcd348ae1c791260d2df564d9ffc1ac97 Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Tue, 9 Nov 2010 00:10:15 +0100 Subject: staging, keucr: Remove unnecessary casts of void ptr returning alloc function return values Hi, The [vk][cmz]alloc(_node) family of functions return void pointers which it's completely unnecessary/pointless to cast to other pointer types since that happens implicitly. This patch removes such casts from drivers/staging/keucr/ Signed-off-by: Jesper Juhl Signed-off-by: Greg Kroah-Hartman --- drivers/staging/keucr/ms.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/staging/keucr/ms.c b/drivers/staging/keucr/ms.c index d4340a9da87d..64778b1e77f5 100644 --- a/drivers/staging/keucr/ms.c +++ b/drivers/staging/keucr/ms.c @@ -347,7 +347,7 @@ int MS_LibProcessBootBlock(struct us_data *us, WORD PhyBlock, BYTE *PageData) BYTE *PageBuffer; MS_LibTypeExtdat ExtraData; - if ((PageBuffer = (BYTE *)kmalloc(MS_BYTES_PER_PAGE, GFP_KERNEL))==NULL) + if ((PageBuffer = kmalloc(MS_BYTES_PER_PAGE, GFP_KERNEL))==NULL) return (DWORD)-1; result = (DWORD)-1; @@ -480,8 +480,8 @@ int MS_LibAllocLogicalMap(struct us_data *us) DWORD i; - us->MS_Lib.Phy2LogMap = (WORD *)kmalloc(us->MS_Lib.NumberOfPhyBlock * sizeof(WORD), GFP_KERNEL); - us->MS_Lib.Log2PhyMap = (WORD *)kmalloc(us->MS_Lib.NumberOfLogBlock * sizeof(WORD), GFP_KERNEL); + us->MS_Lib.Phy2LogMap = kmalloc(us->MS_Lib.NumberOfPhyBlock * sizeof(WORD), GFP_KERNEL); + us->MS_Lib.Log2PhyMap = kmalloc(us->MS_Lib.NumberOfLogBlock * sizeof(WORD), GFP_KERNEL); if ((us->MS_Lib.Phy2LogMap == NULL) || (us->MS_Lib.Log2PhyMap == NULL)) { @@ -610,8 +610,8 @@ int MS_LibAllocWriteBuf(struct us_data *us) { us->MS_Lib.wrtblk = (WORD)-1; - us->MS_Lib.blkpag = (BYTE *)kmalloc(us->MS_Lib.PagesPerBlock * us->MS_Lib.BytesPerSector, GFP_KERNEL); - us->MS_Lib.blkext = (MS_LibTypeExtdat *)kmalloc(us->MS_Lib.PagesPerBlock * sizeof(MS_LibTypeExtdat), GFP_KERNEL); + us->MS_Lib.blkpag = kmalloc(us->MS_Lib.PagesPerBlock * us->MS_Lib.BytesPerSector, GFP_KERNEL); + us->MS_Lib.blkext = kmalloc(us->MS_Lib.PagesPerBlock * sizeof(MS_LibTypeExtdat), GFP_KERNEL); if ((us->MS_Lib.blkpag == NULL) || (us->MS_Lib.blkext == NULL)) { -- cgit v1.2.3 From 131a14b3f0330a844f79c6b87c0fe57ec86faf62 Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Tue, 9 Nov 2010 00:10:25 +0100 Subject: staging, rt2860: Remove unnecessary casts of void ptr returning alloc function return values Hi, The [vk][cmz]alloc(_node) family of functions return void pointers which it's completely unnecessary/pointless to cast to other pointer types since that happens implicitly. This patch removes such casts from drivers/staging/rt2860/ Signed-off-by: Jesper Juhl Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rt2860/common/ba_action.c | 12 ++++++------ drivers/staging/rt2860/rt_main_dev.c | 7 ++++--- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/drivers/staging/rt2860/common/ba_action.c b/drivers/staging/rt2860/common/ba_action.c index 8eef82d92621..ed8854b902d1 100644 --- a/drivers/staging/rt2860/common/ba_action.c +++ b/drivers/staging/rt2860/common/ba_action.c @@ -799,8 +799,8 @@ void BAOriSessionTearDown(struct rt_rtmp_adapter *pAd, /* force send specified TID DelBA */ struct rt_mlme_delba_req DelbaReq; struct rt_mlme_queue_elem *Elem = - (struct rt_mlme_queue_elem *)kmalloc(sizeof(struct rt_mlme_queue_elem), - MEM_ALLOC_FLAG); + kmalloc(sizeof(struct rt_mlme_queue_elem), + MEM_ALLOC_FLAG); if (Elem != NULL) { NdisZeroMemory(&DelbaReq, sizeof(DelbaReq)); NdisZeroMemory(Elem, sizeof(struct rt_mlme_queue_elem)); @@ -839,8 +839,8 @@ void BAOriSessionTearDown(struct rt_rtmp_adapter *pAd, && (pBAEntry->ORI_BA_Status == Originator_Done)) { struct rt_mlme_delba_req DelbaReq; struct rt_mlme_queue_elem *Elem = - (struct rt_mlme_queue_elem *)kmalloc(sizeof(struct rt_mlme_queue_elem), - MEM_ALLOC_FLAG); + kmalloc(sizeof(struct rt_mlme_queue_elem), + MEM_ALLOC_FLAG); if (Elem != NULL) { NdisZeroMemory(&DelbaReq, sizeof(DelbaReq)); NdisZeroMemory(Elem, sizeof(struct rt_mlme_queue_elem)); @@ -908,8 +908,8 @@ void BARecSessionTearDown(struct rt_rtmp_adapter *pAd, /* */ if (bPassive == FALSE) { struct rt_mlme_queue_elem *Elem = - (struct rt_mlme_queue_elem *)kmalloc(sizeof(struct rt_mlme_queue_elem), - MEM_ALLOC_FLAG); + kmalloc(sizeof(struct rt_mlme_queue_elem), + MEM_ALLOC_FLAG); if (Elem != NULL) { NdisZeroMemory(&DelbaReq, sizeof(DelbaReq)); NdisZeroMemory(Elem, sizeof(struct rt_mlme_queue_elem)); diff --git a/drivers/staging/rt2860/rt_main_dev.c b/drivers/staging/rt2860/rt_main_dev.c index 19e9bc6569f8..e8648219e0b5 100644 --- a/drivers/staging/rt2860/rt_main_dev.c +++ b/drivers/staging/rt2860/rt_main_dev.c @@ -102,8 +102,8 @@ int MainVirtualIF_close(IN struct net_device *net_dev) (!RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST))) { struct rt_mlme_disassoc_req DisReq; struct rt_mlme_queue_elem *MsgElem = - (struct rt_mlme_queue_elem *)kmalloc(sizeof(struct rt_mlme_queue_elem), - MEM_ALLOC_FLAG); + kmalloc(sizeof(struct rt_mlme_queue_elem), + MEM_ALLOC_FLAG); if (MsgElem) { COPY_MAC_ADDR(DisReq.Addr, @@ -725,7 +725,8 @@ Note: int AdapterBlockAllocateMemory(void *handle, void ** ppAd) { - *ppAd = (void *)vmalloc(sizeof(struct rt_rtmp_adapter)); /*pci_alloc_consistent(pci_dev, sizeof(struct rt_rtmp_adapter), phy_addr); */ + *ppAd = vmalloc(sizeof(struct rt_rtmp_adapter)); + /* pci_alloc_consistent(pci_dev, sizeof(struct rt_rtmp_adapter), phy_addr); */ if (*ppAd) { NdisZeroMemory(*ppAd, sizeof(struct rt_rtmp_adapter)); -- cgit v1.2.3 From 3c4e9c84970e555a80a4c92a5a3d3125c63f0e12 Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Tue, 9 Nov 2010 00:09:38 +0100 Subject: staging, ath6kl: Remove unnecessary casts of void ptr returning alloc function return values Hi, The [vk][cmz]alloc(_node) family of functions return void pointers which it's completely unnecessary/pointless to cast to other pointer types since that happens implicitly. This patch removes such casts from drivers/staging/ath6kl/ Signed-off-by: Jesper Juhl Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c b/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c index c307a5559362..6454a86c174c 100644 --- a/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c +++ b/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c @@ -1188,7 +1188,7 @@ addHifDevice(struct sdio_func *func) HIF_DEVICE *hifdevice; AR_DEBUG_PRINTF(ATH_DEBUG_TRACE, ("AR6000: addHifDevice\n")); AR_DEBUG_ASSERT(func != NULL); - hifdevice = (HIF_DEVICE *)kzalloc(sizeof(HIF_DEVICE), GFP_KERNEL); + hifdevice = kzalloc(sizeof(HIF_DEVICE), GFP_KERNEL); AR_DEBUG_ASSERT(hifdevice != NULL); #if HIF_USE_DMA_BOUNCE_BUFFER hifdevice->dma_buffer = kmalloc(HIF_DMA_BUFFER_SIZE, GFP_KERNEL); -- cgit v1.2.3 From 5ef3df5b9fed56e64e8544e36a175354d38d0206 Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Tue, 9 Nov 2010 00:10:44 +0100 Subject: staging, wlags49_h2: Remove unnecessary casts of void ptr returning alloc function return values Hi, The [vk][cmz]alloc(_node) family of functions return void pointers which it's completely unnecessary/pointless to cast to other pointer types since that happens implicitly. This patch removes such casts from drivers/staging/wlags49_h2/ Signed-off-by: Jesper Juhl Signed-off-by: Greg Kroah-Hartman --- drivers/staging/wlags49_h2/wl_profile.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/wlags49_h2/wl_profile.c b/drivers/staging/wlags49_h2/wl_profile.c index 7a1337db7aa1..a459e48c7bf0 100644 --- a/drivers/staging/wlags49_h2/wl_profile.c +++ b/drivers/staging/wlags49_h2/wl_profile.c @@ -248,7 +248,7 @@ void parse_config(struct net_device *dev) } else { DBG_TRACE(DbgInfo, "F/W image file found\n"); #define DHF_ALLOC_SIZE 96000 /* just below 96K, let's hope it suffices for now and for the future */ - cp = (char *)vmalloc(DHF_ALLOC_SIZE); + cp = vmalloc(DHF_ALLOC_SIZE); if (cp == NULL) { DBG_ERROR(DbgInfo, "error in vmalloc\n"); } else { -- cgit v1.2.3 From 0a1c62dedc6e28a1117b00c4ccb4427bc91b9f29 Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Tue, 9 Nov 2010 00:10:35 +0100 Subject: staging, spectra: Remove unnecessary casts of void ptr returning alloc function return values Hi, The [vk][cmz]alloc(_node) family of functions return void pointers which it's completely unnecessary/pointless to cast to other pointer types since that happens implicitly. This patch removes such casts from drivers/staging/spectra/ Signed-off-by: Jesper Juhl Signed-off-by: Greg Kroah-Hartman --- drivers/staging/spectra/lld_emu.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/staging/spectra/lld_emu.c b/drivers/staging/spectra/lld_emu.c index 6733bbf8016d..095f2f0c2e5b 100644 --- a/drivers/staging/spectra/lld_emu.c +++ b/drivers/staging/spectra/lld_emu.c @@ -180,10 +180,8 @@ u16 emu_Flash_Init(void) nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n", __FILE__, __LINE__, __func__); - flash_memory[0] = (u8 *)vmalloc(GLOB_LLD_PAGE_SIZE * - GLOB_LLD_BLOCKS * - GLOB_LLD_PAGES * - sizeof(u8)); + flash_memory[0] = vmalloc(GLOB_LLD_PAGE_SIZE * GLOB_LLD_BLOCKS * + GLOB_LLD_PAGES * sizeof(u8)); if (!flash_memory[0]) { printk(KERN_ERR "Fail to allocate memory " "for nand emulator!\n"); -- cgit v1.2.3 From 33d2323711059d14fd675fa7def317e560fa787e Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 10 Nov 2010 13:59:09 +0000 Subject: drm/i915: Unconditionally get the fence reg when pinning scanout We use i915_gem_object_get_fence_reg() to do LRU tracking of the fence registers, so stop trying to be too clever when pinning the fb->obj. Signed-off-by: Daniel Vetter Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/intel_display.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index c41dae5ade32..63770c963077 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -1474,8 +1474,7 @@ intel_pin_and_fence_fb_obj(struct drm_device *dev, * framebuffer compression. For simplicity, we always install * a fence as the cost is not that onerous. */ - if (obj_priv->fence_reg == I915_FENCE_REG_NONE && - obj_priv->tiling_mode != I915_TILING_NONE) { + if (obj_priv->tiling_mode != I915_TILING_NONE) { ret = i915_gem_object_get_fence_reg(obj, false); if (ret) goto err_unpin; -- cgit v1.2.3 From f7d41ae8361fb2d16fe059f65075d92c4efe562c Mon Sep 17 00:00:00 2001 From: Jarkko Nikula Date: Tue, 9 Nov 2010 14:40:27 +0200 Subject: ASoC: Update DAPM debug and error prints Switch printk and pr_ prints to dev_ variants. It is helpful to see parent device of DAPM context especially when there are multiple DAPM contexts (codecs currently). This is mostly simple conversion. Exceptions are in snd_soc_dapm_set_pin that prints also pin state, uniform "dapm: unknown pin" error prints from snd_soc_dapm_set_pin, snd_soc_dapm_force_enable_pin and snd_soc_dapm_ignore_suspend, and pop_dbg which is converted by an another patch. Signed-off-by: Jarkko Nikula Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/soc-dapm.c | 100 ++++++++++++++++++++++++++++----------------------- 1 file changed, 55 insertions(+), 45 deletions(-) diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index 960790cc6fbc..e8997bb97890 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -319,8 +319,8 @@ static int dapm_update_bits(struct snd_soc_dapm_widget *widget) pop_wait(card->pop_time); snd_soc_write(codec, widget->reg, new); } - pr_debug("reg %x old %x new %x change %d\n", widget->reg, - old, new, change); + dev_dbg(dapm->dev, "reg %x old %x new %x change %d\n", widget->reg, + old, new, change); return change; } @@ -375,9 +375,9 @@ static int dapm_new_mixer(struct snd_soc_dapm_context *dapm, path->long_name); ret = snd_ctl_add(card, path->kcontrol); if (ret < 0) { - printk(KERN_ERR "asoc: failed to add dapm kcontrol %s: %d\n", - path->long_name, - ret); + dev_err(dapm->dev, + "asoc: failed to add dapm kcontrol %s: %d\n", + path->long_name, ret); kfree(path->long_name); path->long_name = NULL; return ret; @@ -397,7 +397,7 @@ static int dapm_new_mux(struct snd_soc_dapm_context *dapm, int ret = 0; if (!w->num_kcontrols) { - printk(KERN_ERR "asoc: mux %s has no controls\n", w->name); + dev_err(dapm->dev, "asoc: mux %s has no controls\n", w->name); return -EINVAL; } @@ -413,7 +413,7 @@ static int dapm_new_mux(struct snd_soc_dapm_context *dapm, return ret; err: - printk(KERN_ERR "asoc: failed to add kcontrol %s\n", w->name); + dev_err(dapm->dev, "asoc: failed to add kcontrol %s\n", w->name); return ret; } @@ -422,7 +422,8 @@ static int dapm_new_pga(struct snd_soc_dapm_context *dapm, struct snd_soc_dapm_widget *w) { if (w->num_kcontrols) - pr_err("asoc: PGA controls not supported: '%s'\n", w->name); + dev_err(w->dapm->dev, + "asoc: PGA controls not supported: '%s'\n", w->name); return 0; } @@ -448,7 +449,8 @@ static int snd_soc_dapm_suspend_check(struct snd_soc_dapm_widget *widget) case SNDRV_CTL_POWER_D3hot: case SNDRV_CTL_POWER_D3cold: if (widget->ignore_suspend) - pr_debug("%s ignoring suspend\n", widget->name); + dev_dbg(widget->dapm->dev, "%s ignoring suspend\n", + widget->name); return widget->ignore_suspend; default: return 1; @@ -579,7 +581,7 @@ static int dapm_generic_apply_power(struct snd_soc_dapm_widget *w) /* call any power change event handlers */ if (w->event) - pr_debug("power %s event for %s flags %x\n", + dev_dbg(w->dapm->dev, "power %s event for %s flags %x\n", w->power ? "on" : "off", w->name, w->event_flags); @@ -754,8 +756,9 @@ static void dapm_seq_run_coalesced(struct snd_soc_dapm_context *dapm, w->name); ret = w->event(w, NULL, SND_SOC_DAPM_PRE_PMU); if (ret < 0) - pr_err("%s: pre event failed: %d\n", - w->name, ret); + dev_err(dapm->dev, + "%s: pre event failed: %d\n", + w->name, ret); } /* power down pre event */ @@ -765,8 +768,9 @@ static void dapm_seq_run_coalesced(struct snd_soc_dapm_context *dapm, w->name); ret = w->event(w, NULL, SND_SOC_DAPM_PRE_PMD); if (ret < 0) - pr_err("%s: pre event failed: %d\n", - w->name, ret); + dev_err(dapm->dev, + "%s: pre event failed: %d\n", + w->name, ret); } } @@ -787,8 +791,9 @@ static void dapm_seq_run_coalesced(struct snd_soc_dapm_context *dapm, ret = w->event(w, NULL, SND_SOC_DAPM_POST_PMU); if (ret < 0) - pr_err("%s: post event failed: %d\n", - w->name, ret); + dev_err(dapm->dev, + "%s: post event failed: %d\n", + w->name, ret); } /* power down post event */ @@ -798,8 +803,9 @@ static void dapm_seq_run_coalesced(struct snd_soc_dapm_context *dapm, w->name); ret = w->event(w, NULL, SND_SOC_DAPM_POST_PMD); if (ret < 0) - pr_err("%s: post event failed: %d\n", - w->name, ret); + dev_err(dapm->dev, + "%s: post event failed: %d\n", + w->name, ret); } } } @@ -880,8 +886,8 @@ static void dapm_seq_run(struct snd_soc_dapm_context *dapm, } if (ret < 0) - pr_err("Failed to apply widget power: %d\n", - ret); + dev_err(w->dapm->dev, + "Failed to apply widget power: %d\n", ret); } if (!list_empty(&pending)) @@ -975,7 +981,8 @@ static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event) ret = snd_soc_dapm_set_bias_level(card, dapm, SND_SOC_BIAS_STANDBY); if (ret != 0) - pr_err("Failed to turn on bias: %d\n", ret); + dev_err(dapm->dev, + "Failed to turn on bias: %d\n", ret); } /* If we're changing to all on or all off then prepare */ @@ -983,7 +990,8 @@ static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event) (!sys_power && dapm->bias_level == SND_SOC_BIAS_ON)) { ret = snd_soc_dapm_set_bias_level(card, dapm, SND_SOC_BIAS_PREPARE); if (ret != 0) - pr_err("Failed to prepare bias: %d\n", ret); + dev_err(dapm->dev, + "Failed to prepare bias: %d\n", ret); } /* Power down widgets first; try to avoid amplifying pops. */ @@ -996,7 +1004,8 @@ static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event) if (dapm->bias_level == SND_SOC_BIAS_PREPARE && !sys_power) { ret = snd_soc_dapm_set_bias_level(card, dapm, SND_SOC_BIAS_STANDBY); if (ret != 0) - pr_err("Failed to apply standby bias: %d\n", ret); + dev_err(dapm->dev, + "Failed to apply standby bias: %d\n", ret); } /* If we're in standby and can support bias off then do that */ @@ -1004,14 +1013,16 @@ static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event) dapm->idle_bias_off) { ret = snd_soc_dapm_set_bias_level(card, dapm, SND_SOC_BIAS_OFF); if (ret != 0) - pr_err("Failed to turn off bias: %d\n", ret); + dev_err(dapm->dev, + "Failed to turn off bias: %d\n", ret); } /* If we just powered up then move to active bias */ if (dapm->bias_level == SND_SOC_BIAS_PREPARE && sys_power) { ret = snd_soc_dapm_set_bias_level(card, dapm, SND_SOC_BIAS_ON); if (ret != 0) - pr_err("Failed to apply active bias: %d\n", ret); + dev_err(dapm->dev, + "Failed to apply active bias: %d\n", ret); } pop_dbg(card->pop_time, "DAPM sequencing finished, waiting %dms\n", @@ -1111,9 +1122,9 @@ void snd_soc_dapm_debugfs_init(struct snd_soc_dapm_context *dapm) dapm->debugfs_dapm, w, &dapm_widget_power_fops); if (!d) - printk(KERN_WARNING - "ASoC: Failed to create %s debugfs file\n", - w->name); + dev_warn(w->dapm->dev, + "ASoC: Failed to create %s debugfs file\n", + w->name); } } #else @@ -1279,7 +1290,8 @@ static int snd_soc_dapm_set_pin(struct snd_soc_dapm_context *dapm, list_for_each_entry(w, &dapm->widgets, list) { if (!strcmp(w->name, pin)) { - pr_debug("dapm: %s: pin %s\n", dapm->codec->name, pin); + dev_dbg(w->dapm->dev, "dapm: pin %s = %d\n", + pin, status); w->connected = status; /* Allow disabling of forced pins */ if (status == 0) @@ -1288,8 +1300,7 @@ static int snd_soc_dapm_set_pin(struct snd_soc_dapm_context *dapm, } } - pr_err("dapm: %s: configuring unknown pin %s\n", - dapm->codec->name, pin); + dev_err(dapm->dev, "dapm: unknown pin %s\n", pin); return -EINVAL; } @@ -1415,8 +1426,8 @@ static int snd_soc_dapm_add_route(struct snd_soc_dapm_context *dapm, return 0; err: - printk(KERN_WARNING "asoc: no dapm match for %s --> %s --> %s\n", source, - control, sink); + dev_warn(dapm->dev, "asoc: no dapm match for %s --> %s --> %s\n", + source, control, sink); kfree(path); return ret; } @@ -1442,9 +1453,8 @@ int snd_soc_dapm_add_routes(struct snd_soc_dapm_context *dapm, for (i = 0; i < num; i++) { ret = snd_soc_dapm_add_route(dapm, route); if (ret < 0) { - printk(KERN_ERR "Failed to add route %s->%s\n", - route->source, - route->sink); + dev_err(dapm->dev, "Failed to add route %s->%s\n", + route->source, route->sink); return ret; } route++; @@ -1982,9 +1992,9 @@ int snd_soc_dapm_new_controls(struct snd_soc_dapm_context *dapm, for (i = 0; i < num; i++) { ret = snd_soc_dapm_new_control(dapm, widget); if (ret < 0) { - printk(KERN_ERR - "ASoC: Failed to create DAPM control %s: %d\n", - widget->name, ret); + dev_err(dapm->dev, + "ASoC: Failed to create DAPM control %s: %d\n", + widget->name, ret); return ret; } widget++; @@ -2002,8 +2012,8 @@ static void soc_dapm_stream_event(struct snd_soc_dapm_context *dapm, { if (!w->sname) continue; - pr_debug("widget %s\n %s stream %s event %d\n", - w->name, w->sname, stream, event); + dev_dbg(w->dapm->dev, "widget %s\n %s stream %s event %d\n", + w->name, w->sname, stream, event); if (strstr(w->sname, stream)) { switch(event) { case SND_SOC_DAPM_STREAM_START: @@ -2085,15 +2095,15 @@ int snd_soc_dapm_force_enable_pin(struct snd_soc_dapm_context *dapm, list_for_each_entry(w, &dapm->widgets, list) { if (!strcmp(w->name, pin)) { - pr_debug("dapm: %s: pin %s\n", dapm->codec->name, pin); + dev_dbg(w->dapm->dev, + "dapm: force enable pin %s\n", pin); w->connected = 1; w->force = 1; return 0; } } - pr_err("dapm: %s: configuring unknown pin %s\n", - dapm->codec->name, pin); + dev_err(dapm->dev, "dapm: unknown pin %s\n", pin); return -EINVAL; } EXPORT_SYMBOL_GPL(snd_soc_dapm_force_enable_pin); @@ -2180,7 +2190,7 @@ int snd_soc_dapm_ignore_suspend(struct snd_soc_dapm_context *dapm, } } - pr_err("Unknown DAPM pin: %s\n", pin); + dev_err(dapm->dev, "dapm: unknown pin %s\n", pin); return -EINVAL; } EXPORT_SYMBOL_GPL(snd_soc_dapm_ignore_suspend); -- cgit v1.2.3 From fd8d3bc09033a275d08536c698309e18ee3c14bf Mon Sep 17 00:00:00 2001 From: Jarkko Nikula Date: Tue, 9 Nov 2010 14:40:28 +0200 Subject: ASoC: Convert pop_dbg to use dev_info Prints from pop_dbg are enabled when dapm_pop_time != 0. Convert it to use dev_info so that parent device of DAPM context is printed. Signed-off-by: Jarkko Nikula Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/soc-dapm.c | 44 ++++++++++++++++++++++++++------------------ 1 file changed, 26 insertions(+), 18 deletions(-) diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index e8997bb97890..450307ccaf68 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -91,17 +91,24 @@ static void pop_wait(u32 pop_time) schedule_timeout_uninterruptible(msecs_to_jiffies(pop_time)); } -static void pop_dbg(u32 pop_time, const char *fmt, ...) +static void pop_dbg(struct device *dev, u32 pop_time, const char *fmt, ...) { va_list args; + char *buf; - va_start(args, fmt); + if (!pop_time) + return; - if (pop_time) { - vprintk(fmt, args); - } + buf = kmalloc(PAGE_SIZE, GFP_KERNEL); + if (buf == NULL) + return; + va_start(args, fmt); + vsnprintf(buf, PAGE_SIZE, fmt, args); + dev_info(dev, buf); va_end(args); + + kfree(buf); } /* create a new dapm widget */ @@ -313,7 +320,8 @@ static int dapm_update_bits(struct snd_soc_dapm_widget *widget) change = old != new; if (change) { - pop_dbg(card->pop_time, "pop test %s : %s in %d ms\n", + pop_dbg(dapm->dev, card->pop_time, + "pop test %s : %s in %d ms\n", widget->name, widget->power ? "on" : "off", card->pop_time); pop_wait(card->pop_time); @@ -745,15 +753,15 @@ static void dapm_seq_run_coalesced(struct snd_soc_dapm_context *dapm, if (power) value |= cur_mask; - pop_dbg(card->pop_time, + pop_dbg(dapm->dev, card->pop_time, "pop test : Queue %s: reg=0x%x, 0x%x/0x%x\n", w->name, reg, value, mask); /* power up pre event */ if (w->power && w->event && (w->event_flags & SND_SOC_DAPM_PRE_PMU)) { - pop_dbg(card->pop_time, "pop test : %s PRE_PMU\n", - w->name); + pop_dbg(dapm->dev, card->pop_time, + "pop test : %s PRE_PMU\n", w->name); ret = w->event(w, NULL, SND_SOC_DAPM_PRE_PMU); if (ret < 0) dev_err(dapm->dev, @@ -764,8 +772,8 @@ static void dapm_seq_run_coalesced(struct snd_soc_dapm_context *dapm, /* power down pre event */ if (!w->power && w->event && (w->event_flags & SND_SOC_DAPM_PRE_PMD)) { - pop_dbg(card->pop_time, "pop test : %s PRE_PMD\n", - w->name); + pop_dbg(dapm->dev, card->pop_time, + "pop test : %s PRE_PMD\n", w->name); ret = w->event(w, NULL, SND_SOC_DAPM_PRE_PMD); if (ret < 0) dev_err(dapm->dev, @@ -775,7 +783,7 @@ static void dapm_seq_run_coalesced(struct snd_soc_dapm_context *dapm, } if (reg >= 0) { - pop_dbg(card->pop_time, + pop_dbg(dapm->dev, card->pop_time, "pop test : Applying 0x%x/0x%x to %x in %dms\n", value, mask, reg, card->pop_time); pop_wait(card->pop_time); @@ -786,8 +794,8 @@ static void dapm_seq_run_coalesced(struct snd_soc_dapm_context *dapm, /* power up post event */ if (w->power && w->event && (w->event_flags & SND_SOC_DAPM_POST_PMU)) { - pop_dbg(card->pop_time, "pop test : %s POST_PMU\n", - w->name); + pop_dbg(dapm->dev, card->pop_time, + "pop test : %s POST_PMU\n", w->name); ret = w->event(w, NULL, SND_SOC_DAPM_POST_PMU); if (ret < 0) @@ -799,8 +807,8 @@ static void dapm_seq_run_coalesced(struct snd_soc_dapm_context *dapm, /* power down post event */ if (!w->power && w->event && (w->event_flags & SND_SOC_DAPM_POST_PMD)) { - pop_dbg(card->pop_time, "pop test : %s POST_PMD\n", - w->name); + pop_dbg(dapm->dev, card->pop_time, + "pop test : %s POST_PMD\n", w->name); ret = w->event(w, NULL, SND_SOC_DAPM_POST_PMD); if (ret < 0) dev_err(dapm->dev, @@ -1025,8 +1033,8 @@ static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event) "Failed to apply active bias: %d\n", ret); } - pop_dbg(card->pop_time, "DAPM sequencing finished, waiting %dms\n", - card->pop_time); + pop_dbg(dapm->dev, card->pop_time, + "DAPM sequencing finished, waiting %dms\n", card->pop_time); pop_wait(card->pop_time); return 0; -- cgit v1.2.3 From 5d97eb69bd4767ce9973360881fa6ad161510fb0 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 10 Nov 2010 20:40:02 +0000 Subject: drm/i915: Only add the lazy request if we end up waiting for it. Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_gem.c | 9 +++------ drivers/gpu/drm/i915/intel_ringbuffer.h | 2 +- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 7c91bf2bbdfd..52f5c194c50f 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1664,9 +1664,7 @@ i915_gem_next_request_seqno(struct drm_device *dev, struct intel_ring_buffer *ring) { drm_i915_private_t *dev_priv = dev->dev_private; - - ring->outstanding_lazy_request = true; - return dev_priv->next_seqno; + return ring->outstanding_lazy_request = dev_priv->next_seqno; } static void @@ -2072,7 +2070,7 @@ i915_do_wait_request(struct drm_device *dev, uint32_t seqno, if (atomic_read(&dev_priv->mm.wedged)) return -EAGAIN; - if (ring->outstanding_lazy_request) { + if (seqno == ring->outstanding_lazy_request) { struct drm_i915_gem_request *request; request = kzalloc(sizeof(*request), GFP_KERNEL); @@ -2087,7 +2085,6 @@ i915_do_wait_request(struct drm_device *dev, uint32_t seqno, seqno = request->seqno; } - BUG_ON(seqno == dev_priv->next_seqno); if (!i915_seqno_passed(ring->get_seqno(ring), seqno)) { if (HAS_PCH_SPLIT(dev)) @@ -3973,7 +3970,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, i915_retire_commands(dev, ring); if (i915_add_request(dev, file, request, ring)) - ring->outstanding_lazy_request = true; + i915_gem_next_request_seqno(dev, ring); else request = NULL; diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index 68043f1a186e..d73145c790bd 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -87,7 +87,7 @@ struct intel_ring_buffer { /** * Do we have some not yet emitted requests outstanding? */ - bool outstanding_lazy_request; + u32 outstanding_lazy_request; wait_queue_head_t irq_queue; drm_local_map_t map; -- cgit v1.2.3 From a10bb4fb199bd7a1dc178a6228ad749f5070e0f9 Mon Sep 17 00:00:00 2001 From: Larry Finger Date: Tue, 9 Nov 2010 18:26:34 -0600 Subject: staging: r8712u: Update TODO for sparse fixes Signed-off-by: Larry Finger Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8712/TODO | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/staging/rtl8712/TODO b/drivers/staging/rtl8712/TODO index 5c888214666e..2aa5deb3af7b 100644 --- a/drivers/staging/rtl8712/TODO +++ b/drivers/staging/rtl8712/TODO @@ -3,7 +3,6 @@ TODO: - switch to use LIB80211 - switch to use MAC80211 - checkpatch.pl fixes - only a few remain -- sparse fixes - switch from large inline firmware file to use the firmware interface and add the file to the linux-firmware package. -- cgit v1.2.3 From c8b124e21dbb7f4941f292fea446ce63d92d80dd Mon Sep 17 00:00:00 2001 From: Marek Belisko Date: Wed, 10 Nov 2010 09:29:35 +0100 Subject: staging: ft1000: Check return value of kthread_run. kthread_run could fail so we will check return value. Signed-off-by: Marek Belisko Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ft1000/ft1000-usb/ft1000_usb.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_usb.c b/drivers/staging/ft1000/ft1000-usb/ft1000_usb.c index 41bbe991f0de..dcbc97c432e5 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_usb.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_usb.c @@ -175,6 +175,12 @@ static int ft1000_probe(struct usb_interface *interface, gPollingfailed = FALSE; pft1000info->pPollThread = kthread_run(ft1000_poll_thread, ft1000dev, "ft1000_poll"); + + if (IS_ERR(pft1000info->pPollThread)) { + ret = PTR_ERR(pft1000info->pPollThread); + goto err_load; + } + msleep(500); while (!pft1000info->CardReady) { -- cgit v1.2.3 From 2dab1ac81b4767095f96503a9ac093a68c6e9c95 Mon Sep 17 00:00:00 2001 From: Marek Belisko Date: Wed, 10 Nov 2010 10:04:30 +0100 Subject: staging: ft1000: Create common return point. When reg_ft1000_netdev() fails created kthread isn't stopped. So add return point for stopping thread. Signed-off-by: Marek Belisko Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ft1000/ft1000-usb/ft1000_usb.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_usb.c b/drivers/staging/ft1000/ft1000-usb/ft1000_usb.c index dcbc97c432e5..99e333902376 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_usb.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_usb.c @@ -178,15 +178,13 @@ static int ft1000_probe(struct usb_interface *interface, if (IS_ERR(pft1000info->pPollThread)) { ret = PTR_ERR(pft1000info->pPollThread); - goto err_load; + goto err_thread; } msleep(500); while (!pft1000info->CardReady) { if (gPollingfailed) { - if (pft1000info->pPollThread) - kthread_stop(pft1000info->pPollThread); ret = -EIO; goto err_load; } @@ -207,6 +205,8 @@ static int ft1000_probe(struct usb_interface *interface, return 0; err_load: + kthread_stop(pft1000info->pPollThread); +err_thread: kfree(pFileStart); err_fw: kfree(ft1000dev); -- cgit v1.2.3 From b706113f1475ce983faabf12120ac4e90d512d02 Mon Sep 17 00:00:00 2001 From: "Alejandro R. Sedeño" Date: Wed, 10 Nov 2010 01:42:01 -0500 Subject: Staging: beceem: Use 32-bit integers for hardware register values MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Switching to UINT because that's what the rest of this codebase uses. Signed-off-by: Alejandro R. Sedeño Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/Adapter.h | 4 ++-- drivers/staging/bcm/DDRInit.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/staging/bcm/Adapter.h b/drivers/staging/bcm/Adapter.h index 62f9135d4d40..32909e2938d5 100644 --- a/drivers/staging/bcm/Adapter.h +++ b/drivers/staging/bcm/Adapter.h @@ -601,8 +601,8 @@ typedef LINK_REQUEST CONTROL_MESSAGE; typedef struct _DDR_SETTING { - ULONG ulRegAddress; - ULONG ulRegValue; + UINT ulRegAddress; + UINT ulRegValue; }DDR_SETTING, *PDDR_SETTING; typedef DDR_SETTING DDR_SET_NODE, *PDDR_SET_NODE; INT diff --git a/drivers/staging/bcm/DDRInit.c b/drivers/staging/bcm/DDRInit.c index 411f02a6b6ea..1c7db81a1ee8 100644 --- a/drivers/staging/bcm/DDRInit.c +++ b/drivers/staging/bcm/DDRInit.c @@ -776,7 +776,7 @@ int ddr_init(MINI_ADAPTER *Adapter) { PDDR_SETTING psDDRSetting=NULL; ULONG RegCount=0; - ULONG value = 0; + UINT value = 0; UINT uiResetValue = 0; UINT uiClockSetting = 0; int retval = STATUS_SUCCESS; @@ -970,7 +970,7 @@ int ddr_init(MINI_ADAPTER *Adapter) { value = psDDRSetting->ulRegValue; } - retval = wrmalt(Adapter, psDDRSetting->ulRegAddress, (PUINT)&value, sizeof(value)); + retval = wrmalt(Adapter, psDDRSetting->ulRegAddress, &value, sizeof(value)); if(STATUS_SUCCESS != retval) { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"%s:%d\n", __FUNCTION__, __LINE__); break; -- cgit v1.2.3 From 16618c20e18d60b2c8908b7758228a62a450769a Mon Sep 17 00:00:00 2001 From: "Alejandro R. Sedeño" Date: Wed, 10 Nov 2010 01:42:02 -0500 Subject: Staging: beceem: Move ZTE TU25's USB id to the beceem module MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Alejandro R. Sedeño Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/InterfaceInit.c | 2 +- drivers/staging/bcm/InterfaceInit.h | 1 + drivers/usb/serial/option.c | 1 - 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/bcm/InterfaceInit.c b/drivers/staging/bcm/InterfaceInit.c index 8a26a3ef5bd3..869ebabfba77 100644 --- a/drivers/staging/bcm/InterfaceInit.c +++ b/drivers/staging/bcm/InterfaceInit.c @@ -6,7 +6,7 @@ static struct usb_device_id InterfaceUsbtable[] = { { USB_DEVICE(BCM_USB_VENDOR_ID_T3, BCM_USB_PRODUCT_ID_T3L) }, { USB_DEVICE(BCM_USB_VENDOR_ID_ZTE, BCM_USB_PRODUCT_ID_226) }, { USB_DEVICE(BCM_USB_VENDOR_ID_FOXCONN, BCM_USB_PRODUCT_ID_1901) }, - + { USB_DEVICE(BCM_USB_VENDOR_ID_ZTE, BCM_USB_PRODUCT_ID_ZTE_TU25) }, { } }; MODULE_DEVICE_TABLE(usb, InterfaceUsbtable); diff --git a/drivers/staging/bcm/InterfaceInit.h b/drivers/staging/bcm/InterfaceInit.h index 3b8e17b619ba..091cf78d63a1 100644 --- a/drivers/staging/bcm/InterfaceInit.h +++ b/drivers/staging/bcm/InterfaceInit.h @@ -11,6 +11,7 @@ #define BCM_USB_PRODUCT_ID_SYM 0x15E #define BCM_USB_PRODUCT_ID_1901 0xe017 #define BCM_USB_PRODUCT_ID_226 0x0132 +#define BCM_USB_PRODUCT_ID_ZTE_TU25 0x0007 #define BCM_USB_MINOR_BASE 192 diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 2297fb1bcf65..b17896e58c5f 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -615,7 +615,6 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0004, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0005, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0006, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0007, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0008, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0009, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x000a, 0xff, 0xff, 0xff) }, -- cgit v1.2.3 From afabbe6db368fbed0569d31d402aceb631d9f854 Mon Sep 17 00:00:00 2001 From: facugaich Date: Wed, 10 Nov 2010 10:39:33 -0300 Subject: Staging: solo6x10: Fix checkpatch errors and most warnings This patch fixes all errors and most warnings reported by checkpatch.pl for all the files in the driver. v2: Fix a typo and update the patch against the latest HEAD Signed-off-by: Facundo Gaich Signed-off-by: Greg Kroah-Hartman --- drivers/staging/solo6x10/solo6010-core.c | 30 +++---- drivers/staging/solo6x10/solo6010-disp.c | 4 +- drivers/staging/solo6x10/solo6010-enc.c | 2 +- drivers/staging/solo6x10/solo6010-g723.c | 8 +- drivers/staging/solo6x10/solo6010-i2c.c | 5 +- drivers/staging/solo6x10/solo6010-osd-font.h | 60 +++++++------- drivers/staging/solo6x10/solo6010-p2m.c | 4 +- drivers/staging/solo6x10/solo6010-tw28.c | 118 +++++++++++++-------------- drivers/staging/solo6x10/solo6010-v4l2-enc.c | 20 +++-- drivers/staging/solo6x10/solo6010-v4l2.c | 19 +++-- drivers/staging/solo6x10/solo6010.h | 4 +- 11 files changed, 142 insertions(+), 132 deletions(-) diff --git a/drivers/staging/solo6x10/solo6010-core.c b/drivers/staging/solo6x10/solo6010-core.c index 9dad749ca963..c433136f972c 100644 --- a/drivers/staging/solo6x10/solo6010-core.c +++ b/drivers/staging/solo6x10/solo6010-core.c @@ -164,21 +164,21 @@ static int __devinit solo6010_pci_probe(struct pci_dev *pdev, chip_id = solo_reg_read(solo_dev, SOLO_CHIP_OPTION) & SOLO_CHIP_ID_MASK; switch (chip_id) { - case 7: - solo_dev->nr_chans = 16; - solo_dev->nr_ext = 5; - break; - case 6: - solo_dev->nr_chans = 8; - solo_dev->nr_ext = 2; - break; - default: - dev_warn(&pdev->dev, "Invalid chip_id 0x%02x, " - "defaulting to 4 channels\n", - chip_id); - case 5: - solo_dev->nr_chans = 4; - solo_dev->nr_ext = 1; + case 7: + solo_dev->nr_chans = 16; + solo_dev->nr_ext = 5; + break; + case 6: + solo_dev->nr_chans = 8; + solo_dev->nr_ext = 2; + break; + default: + dev_warn(&pdev->dev, "Invalid chip_id 0x%02x, " + "defaulting to 4 channels\n", + chip_id); + case 5: + solo_dev->nr_chans = 4; + solo_dev->nr_ext = 1; } /* Disable all interrupts to start */ diff --git a/drivers/staging/solo6x10/solo6010-disp.c b/drivers/staging/solo6x10/solo6010-disp.c index a15151d15ea5..f866f8438175 100644 --- a/drivers/staging/solo6x10/solo6010-disp.c +++ b/drivers/staging/solo6x10/solo6010-disp.c @@ -203,7 +203,7 @@ static void solo_motion_config(struct solo6010_dev *solo_dev) solo_reg_write(solo_dev, SOLO_VI_MOT_CTRL, SOLO_VI_MOTION_FRAME_COUNT(3) | SOLO_VI_MOTION_SAMPLE_LENGTH(solo_dev->video_hsize / 16) - | //SOLO_VI_MOTION_INTR_START_STOP | + | /* SOLO_VI_MOTION_INTR_START_STOP | */ SOLO_VI_MOTION_SAMPLE_COUNT(10)); solo_reg_write(solo_dev, SOLO_VI_MOTION_BORDER, 0); @@ -264,7 +264,7 @@ void solo_disp_exit(struct solo6010_dev *solo_dev) solo_reg_write(solo_dev, SOLO_VO_RECTANGLE_CTRL(0), 0); solo_reg_write(solo_dev, SOLO_VO_RECTANGLE_START(0), 0); solo_reg_write(solo_dev, SOLO_VO_RECTANGLE_STOP(0), 0); - + solo_reg_write(solo_dev, SOLO_VO_RECTANGLE_CTRL(1), 0); solo_reg_write(solo_dev, SOLO_VO_RECTANGLE_START(1), 0); solo_reg_write(solo_dev, SOLO_VO_RECTANGLE_STOP(1), 0); diff --git a/drivers/staging/solo6x10/solo6010-enc.c b/drivers/staging/solo6x10/solo6010-enc.c index 42314a1e3250..481a49277f77 100644 --- a/drivers/staging/solo6x10/solo6010-enc.c +++ b/drivers/staging/solo6x10/solo6010-enc.c @@ -22,7 +22,7 @@ #include "solo6010.h" #include "solo6010-osd-font.h" -#define CAPTURE_MAX_BANDWIDTH 32 // D1 4channel (D1 == 4) +#define CAPTURE_MAX_BANDWIDTH 32 /* D1 4channel (D1 == 4) */ #define OSG_BUFFER_SIZE 1024 #define VI_PROG_HSIZE (1280 - 16) diff --git a/drivers/staging/solo6x10/solo6010-g723.c b/drivers/staging/solo6x10/solo6010-g723.c index 63a1b5b64b56..254b46ab20c5 100644 --- a/drivers/staging/solo6x10/solo6010-g723.c +++ b/drivers/staging/solo6x10/solo6010-g723.c @@ -47,7 +47,7 @@ * is broken down to 20 * 48 byte regions (one for each channel possible) * with the rest of the page being dummy data. */ #define MAX_BUFFER (G723_PERIOD_BYTES * PERIODS_MAX) -#define IRQ_PAGES 4 // 0 - 4 +#define IRQ_PAGES 4 /* 0 - 4 */ #define PERIODS_MIN (1 << IRQ_PAGES) #define PERIODS_MAX G723_FDMA_PAGES @@ -372,10 +372,12 @@ int solo_g723_init(struct solo6010_dev *solo_dev) if (ret < 0) return ret; - if ((ret = solo_snd_pcm_init(solo_dev)) < 0) + ret = solo_snd_pcm_init(solo_dev); + if (ret < 0) goto snd_error; - if ((ret = snd_card_register(card)) < 0) + ret = snd_card_register(card); + if (ret < 0) goto snd_error; solo_g723_config(solo_dev); diff --git a/drivers/staging/solo6x10/solo6010-i2c.c b/drivers/staging/solo6x10/solo6010-i2c.c index c1d4a23f4275..60b69cd0d09d 100644 --- a/drivers/staging/solo6x10/solo6010-i2c.c +++ b/drivers/staging/solo6x10/solo6010-i2c.c @@ -225,7 +225,7 @@ static int solo_i2c_master_xfer(struct i2c_adapter *adap, } if (i == SOLO_I2C_ADAPTERS) - return num; // XXX Right return value for failure? + return num; /* XXX Right return value for failure? */ mutex_lock(&solo_dev->i2c_mutex); solo_dev->i2c_id = i; @@ -296,7 +296,8 @@ int solo_i2c_init(struct solo6010_dev *solo_dev) adap->retries = 1; adap->dev.parent = &solo_dev->pdev->dev; - if ((ret = i2c_add_adapter(adap))) { + ret = i2c_add_adapter(adap); + if (ret) { adap->algo_data = NULL; break; } diff --git a/drivers/staging/solo6x10/solo6010-osd-font.h b/drivers/staging/solo6x10/solo6010-osd-font.h index d6f565bd76cc..d72efbb3bb3d 100644 --- a/drivers/staging/solo6x10/solo6010-osd-font.h +++ b/drivers/staging/solo6x10/solo6010-osd-font.h @@ -22,7 +22,7 @@ static const unsigned int solo_osd_font[] = { 0x00000000, 0x0000c0c8, 0xccfefe0c, 0x08000000, - 0x00000000, 0x10103838, 0x7c7cfefe, 0x00000000, // 0 + 0x00000000, 0x10103838, 0x7c7cfefe, 0x00000000, /* 0 */ 0x00000000, 0xfefe7c7c, 0x38381010, 0x10000000, 0x00000000, 0x7c82fefe, 0xfefefe7c, 0x00000000, 0x00000000, 0x00001038, 0x10000000, 0x00000000, @@ -54,67 +54,67 @@ static const unsigned int solo_osd_font[] = { 0x0000003f, 0x7f404c52, 0x524c407f, 0x00000000, 0x0000007c, 0x82ba82ba, 0x82ba82fe, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, - 0x00000000, 0x183c3c3c, 0x18180018, 0x18000000, // 32 ! + 0x00000000, 0x183c3c3c, 0x18180018, 0x18000000, /* 32 ! */ 0x00000066, 0x66240000, 0x00000000, 0x00000000, - 0x00000000, 0x6c6cfe6c, 0x6c6cfe6c, 0x6c000000, // 34 " # + 0x00000000, 0x6c6cfe6c, 0x6c6cfe6c, 0x6c000000, /* 34 " # */ 0x00001010, 0x7cd6d616, 0x7cd0d6d6, 0x7c101000, - 0x00000000, 0x0086c660, 0x30180cc6, 0xc2000000, // 36 $ % + 0x00000000, 0x0086c660, 0x30180cc6, 0xc2000000, /* 36 $ % */ 0x00000000, 0x386c6c38, 0xdc766666, 0xdc000000, - 0x0000000c, 0x0c0c0600, 0x00000000, 0x00000000, // 38 & ' + 0x0000000c, 0x0c0c0600, 0x00000000, 0x00000000, /* 38 & ' */ 0x00000000, 0x30180c0c, 0x0c0c0c18, 0x30000000, - 0x00000000, 0x0c183030, 0x30303018, 0x0c000000, // 40 ( ) + 0x00000000, 0x0c183030, 0x30303018, 0x0c000000, /* 40 ( ) */ 0x00000000, 0x0000663c, 0xff3c6600, 0x00000000, - 0x00000000, 0x00001818, 0x7e181800, 0x00000000, // 42 * + + 0x00000000, 0x00001818, 0x7e181800, 0x00000000, /* 42 * + */ 0x00000000, 0x00000000, 0x00000e0e, 0x0c060000, - 0x00000000, 0x00000000, 0x7e000000, 0x00000000, // 44 , - + 0x00000000, 0x00000000, 0x7e000000, 0x00000000, /* 44 , - */ 0x00000000, 0x00000000, 0x00000006, 0x06000000, - 0x00000000, 0x80c06030, 0x180c0602, 0x00000000, // 46 . / + 0x00000000, 0x80c06030, 0x180c0602, 0x00000000, /* 46 . / */ 0x0000007c, 0xc6e6f6de, 0xcec6c67c, 0x00000000, - 0x00000030, 0x383c3030, 0x303030fc, 0x00000000, // 48 0 1 + 0x00000030, 0x383c3030, 0x303030fc, 0x00000000, /* 48 0 1 */ 0x0000007c, 0xc6c06030, 0x180cc6fe, 0x00000000, - 0x0000007c, 0xc6c0c07c, 0xc0c0c67c, 0x00000000, // 50 2 3 + 0x0000007c, 0xc6c0c07c, 0xc0c0c67c, 0x00000000, /* 50 2 3 */ 0x00000060, 0x70786c66, 0xfe6060f0, 0x00000000, - 0x000000fe, 0x0606067e, 0xc0c0c67c, 0x00000000, // 52 4 5 + 0x000000fe, 0x0606067e, 0xc0c0c67c, 0x00000000, /* 52 4 5 */ 0x00000038, 0x0c06067e, 0xc6c6c67c, 0x00000000, - 0x000000fe, 0xc6c06030, 0x18181818, 0x00000000, // 54 6 7 + 0x000000fe, 0xc6c06030, 0x18181818, 0x00000000, /* 54 6 7 */ 0x0000007c, 0xc6c6c67c, 0xc6c6c67c, 0x00000000, - 0x0000007c, 0xc6c6c6fc, 0xc0c06038, 0x00000000, // 56 8 9 + 0x0000007c, 0xc6c6c6fc, 0xc0c06038, 0x00000000, /* 56 8 9 */ 0x00000000, 0x18180000, 0x00181800, 0x00000000, - 0x00000000, 0x18180000, 0x0018180c, 0x00000000, // 58 : ; + 0x00000000, 0x18180000, 0x0018180c, 0x00000000, /* 58 : ; */ 0x00000060, 0x30180c06, 0x0c183060, 0x00000000, 0x00000000, 0x007e0000, 0x007e0000, 0x00000000, 0x00000006, 0x0c183060, 0x30180c06, 0x00000000, 0x0000007c, 0xc6c66030, 0x30003030, 0x00000000, 0x0000007c, 0xc6f6d6d6, 0x7606067c, 0x00000000, - 0x00000010, 0x386cc6c6, 0xfec6c6c6, 0x00000000, // 64 @ A + 0x00000010, 0x386cc6c6, 0xfec6c6c6, 0x00000000, /* 64 @ A */ 0x0000007e, 0xc6c6c67e, 0xc6c6c67e, 0x00000000, - 0x00000078, 0xcc060606, 0x0606cc78, 0x00000000, // 66 + 0x00000078, 0xcc060606, 0x0606cc78, 0x00000000, /* 66 */ 0x0000003e, 0x66c6c6c6, 0xc6c6663e, 0x00000000, - 0x000000fe, 0x0606063e, 0x060606fe, 0x00000000, // 68 + 0x000000fe, 0x0606063e, 0x060606fe, 0x00000000, /* 68 */ 0x000000fe, 0x0606063e, 0x06060606, 0x00000000, - 0x00000078, 0xcc060606, 0xf6c6ccb8, 0x00000000, // 70 + 0x00000078, 0xcc060606, 0xf6c6ccb8, 0x00000000, /* 70 */ 0x000000c6, 0xc6c6c6fe, 0xc6c6c6c6, 0x00000000, - 0x0000003c, 0x18181818, 0x1818183c, 0x00000000, // 72 + 0x0000003c, 0x18181818, 0x1818183c, 0x00000000, /* 72 */ 0x00000060, 0x60606060, 0x6066663c, 0x00000000, - 0x000000c6, 0xc666361e, 0x3666c6c6, 0x00000000, // 74 + 0x000000c6, 0xc666361e, 0x3666c6c6, 0x00000000, /* 74 */ 0x00000006, 0x06060606, 0x060606fe, 0x00000000, - 0x000000c6, 0xeefed6c6, 0xc6c6c6c6, 0x00000000, // 76 + 0x000000c6, 0xeefed6c6, 0xc6c6c6c6, 0x00000000, /* 76 */ 0x000000c6, 0xcedefef6, 0xe6c6c6c6, 0x00000000, - 0x00000038, 0x6cc6c6c6, 0xc6c66c38, 0x00000000, // 78 + 0x00000038, 0x6cc6c6c6, 0xc6c66c38, 0x00000000, /* 78 */ 0x0000007e, 0xc6c6c67e, 0x06060606, 0x00000000, - 0x00000038, 0x6cc6c6c6, 0xc6d67c38, 0x60000000, // 80 + 0x00000038, 0x6cc6c6c6, 0xc6d67c38, 0x60000000, /* 80 */ 0x0000007e, 0xc6c6c67e, 0x66c6c6c6, 0x00000000, - 0x0000007c, 0xc6c60c38, 0x60c6c67c, 0x00000000, // 82 + 0x0000007c, 0xc6c60c38, 0x60c6c67c, 0x00000000, /* 82 */ 0x0000007e, 0x18181818, 0x18181818, 0x00000000, - 0x000000c6, 0xc6c6c6c6, 0xc6c6c67c, 0x00000000, // 84 + 0x000000c6, 0xc6c6c6c6, 0xc6c6c67c, 0x00000000, /* 84 */ 0x000000c6, 0xc6c6c6c6, 0xc66c3810, 0x00000000, - 0x000000c6, 0xc6c6c6c6, 0xd6d6fe6c, 0x00000000, // 86 + 0x000000c6, 0xc6c6c6c6, 0xd6d6fe6c, 0x00000000, /* 86 */ 0x000000c6, 0xc6c66c38, 0x6cc6c6c6, 0x00000000, - 0x00000066, 0x66666666, 0x3c181818, 0x00000000, // 88 + 0x00000066, 0x66666666, 0x3c181818, 0x00000000, /* 88 */ 0x000000fe, 0xc0603018, 0x0c0606fe, 0x00000000, - 0x0000003c, 0x0c0c0c0c, 0x0c0c0c3c, 0x00000000, // 90 + 0x0000003c, 0x0c0c0c0c, 0x0c0c0c3c, 0x00000000, /* 90 */ 0x00000002, 0x060c1830, 0x60c08000, 0x00000000, - 0x0000003c, 0x30303030, 0x3030303c, 0x00000000, // 92 + 0x0000003c, 0x30303030, 0x3030303c, 0x00000000, /* 92 */ 0x00001038, 0x6cc60000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00fe0000, 0x00001818, 0x30000000, 0x00000000, 0x00000000, diff --git a/drivers/staging/solo6x10/solo6010-p2m.c b/drivers/staging/solo6x10/solo6010-p2m.c index c91fc4652a00..956dea09348a 100644 --- a/drivers/staging/solo6x10/solo6010-p2m.c +++ b/drivers/staging/solo6x10/solo6010-p2m.c @@ -22,7 +22,7 @@ #include "solo6010.h" -// #define SOLO_TEST_P2M +/* #define SOLO_TEST_P2M */ int solo_p2m_dma(struct solo6010_dev *solo_dev, u8 id, int wr, void *sys_addr, u32 ext_addr, u32 size) @@ -244,7 +244,7 @@ static void run_p2m_test(struct solo6010_dev *solo_dev) return; } #else -#define run_p2m_test(__solo) do{}while(0) +#define run_p2m_test(__solo) do {} while (0) #endif void solo_p2m_isr(struct solo6010_dev *solo_dev, int id) diff --git a/drivers/staging/solo6x10/solo6010-tw28.c b/drivers/staging/solo6x10/solo6010-tw28.c index 0159c8392436..905a6ad23a37 100644 --- a/drivers/staging/solo6x10/solo6010-tw28.c +++ b/drivers/staging/solo6x10/solo6010-tw28.c @@ -35,107 +35,107 @@ #define DEFAULT_VACTIVE_PAL (312-DEFAULT_VDELAY_PAL) static u8 tbl_tw2864_template[] = { - 0x00, 0x00, 0x80, 0x10, 0x80, 0x80, 0x00, 0x02, // 0x00 + 0x00, 0x00, 0x80, 0x10, 0x80, 0x80, 0x00, 0x02, /* 0x00 */ 0x12, 0xf5, 0x09, 0xd0, 0x00, 0x00, 0x00, 0x7f, - 0x00, 0x00, 0x80, 0x10, 0x80, 0x80, 0x00, 0x02, // 0x10 + 0x00, 0x00, 0x80, 0x10, 0x80, 0x80, 0x00, 0x02, /* 0x10 */ 0x12, 0xf5, 0x09, 0xd0, 0x00, 0x00, 0x00, 0x7f, - 0x00, 0x00, 0x80, 0x10, 0x80, 0x80, 0x00, 0x02, // 0x20 + 0x00, 0x00, 0x80, 0x10, 0x80, 0x80, 0x00, 0x02, /* 0x20 */ 0x12, 0xf5, 0x09, 0xd0, 0x00, 0x00, 0x00, 0x7f, - 0x00, 0x00, 0x80, 0x10, 0x80, 0x80, 0x00, 0x02, // 0x30 + 0x00, 0x00, 0x80, 0x10, 0x80, 0x80, 0x00, 0x02, /* 0x30 */ 0x12, 0xf5, 0x09, 0xd0, 0x00, 0x00, 0x00, 0x7f, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x40 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x40 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x50 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x60 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x70 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA3, 0x00, - 0x00, 0x02, 0x00, 0xcc, 0x00, 0x80, 0x44, 0x50, // 0x80 + 0x00, 0x02, 0x00, 0xcc, 0x00, 0x80, 0x44, 0x50, /* 0x80 */ 0x22, 0x01, 0xd8, 0xbc, 0xb8, 0x44, 0x38, 0x00, - 0x00, 0x78, 0x72, 0x3e, 0x14, 0xa5, 0xe4, 0x05, // 0x90 + 0x00, 0x78, 0x72, 0x3e, 0x14, 0xa5, 0xe4, 0x05, /* 0x90 */ 0x00, 0x28, 0x44, 0x44, 0xa0, 0x88, 0x5a, 0x01, - 0x08, 0x08, 0x08, 0x08, 0x1a, 0x1a, 0x1a, 0x1a, // 0xa0 + 0x08, 0x08, 0x08, 0x08, 0x1a, 0x1a, 0x1a, 0x1a, /* 0xa0 */ 0x00, 0x00, 0x00, 0xf0, 0xf0, 0xf0, 0xf0, 0x44, - 0x44, 0x0a, 0x00, 0xff, 0xef, 0xef, 0xef, 0xef, // 0xb0 + 0x44, 0x0a, 0x00, 0xff, 0xef, 0xef, 0xef, 0xef, /* 0xb0 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xc0 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0 */ 0x00, 0x00, 0x55, 0x00, 0xb1, 0xe4, 0x40, 0x00, - 0x77, 0x77, 0x01, 0x13, 0x57, 0x9b, 0xdf, 0x20, // 0xd0 + 0x77, 0x77, 0x01, 0x13, 0x57, 0x9b, 0xdf, 0x20, /* 0xd0 */ 0x64, 0xa8, 0xec, 0xd1, 0x0f, 0x11, 0x11, 0x81, - 0x10, 0xe0, 0xbb, 0xbb, 0x00, 0x11, 0x00, 0x00, // 0xe0 + 0x10, 0xe0, 0xbb, 0xbb, 0x00, 0x11, 0x00, 0x00, /* 0xe0 */ 0x11, 0x00, 0x00, 0x11, 0x00, 0x00, 0x11, 0x00, - 0x83, 0xb5, 0x09, 0x78, 0x85, 0x00, 0x01, 0x20, // 0xf0 + 0x83, 0xb5, 0x09, 0x78, 0x85, 0x00, 0x01, 0x20, /* 0xf0 */ 0x64, 0x11, 0x40, 0xaf, 0xff, 0x00, 0x00, 0x00, }; static u8 tbl_tw2865_ntsc_template[] = { - 0x00, 0xf0, 0x70, 0x30, 0x80, 0x80, 0x00, 0x02, // 0x00 + 0x00, 0xf0, 0x70, 0x30, 0x80, 0x80, 0x00, 0x02, /* 0x00 */ 0x12, 0xff, 0x09, 0xd0, 0x00, 0x00, 0x00, 0x7f, - 0x00, 0xf0, 0x70, 0x30, 0x80, 0x80, 0x00, 0x02, // 0x10 + 0x00, 0xf0, 0x70, 0x30, 0x80, 0x80, 0x00, 0x02, /* 0x10 */ 0x12, 0xff, 0x09, 0xd0, 0x00, 0x00, 0x00, 0x7f, - 0x00, 0xf0, 0x70, 0x30, 0x80, 0x80, 0x00, 0x02, // 0x20 + 0x00, 0xf0, 0x70, 0x30, 0x80, 0x80, 0x00, 0x02, /* 0x20 */ 0x12, 0xff, 0x09, 0xd0, 0x00, 0x00, 0x00, 0x7f, - 0x00, 0xf0, 0x70, 0x48, 0x80, 0x80, 0x00, 0x02, // 0x30 + 0x00, 0xf0, 0x70, 0x48, 0x80, 0x80, 0x00, 0x02, /* 0x30 */ 0x12, 0xff, 0x09, 0xd0, 0x00, 0x00, 0x00, 0x7f, - 0x00, 0x00, 0x90, 0x68, 0x00, 0x38, 0x80, 0x80, // 0x40 + 0x00, 0x00, 0x90, 0x68, 0x00, 0x38, 0x80, 0x80, /* 0x40 */ 0x80, 0x80, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x50 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x45, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x60 + 0x45, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x43, - 0x08, 0x00, 0x00, 0x01, 0xf1, 0x03, 0xEF, 0x03, // 0x70 + 0x08, 0x00, 0x00, 0x01, 0xf1, 0x03, 0xEF, 0x03, /* 0x70 */ 0xE9, 0x03, 0xD9, 0x15, 0x15, 0xE4, 0xA3, 0x80, - 0x00, 0x02, 0x00, 0xCC, 0x00, 0x80, 0x44, 0x50, // 0x80 + 0x00, 0x02, 0x00, 0xCC, 0x00, 0x80, 0x44, 0x50, /* 0x80 */ 0x22, 0x01, 0xD8, 0xBC, 0xB8, 0x44, 0x38, 0x00, - 0x00, 0x78, 0x44, 0x3D, 0x14, 0xA5, 0xE0, 0x05, // 0x90 + 0x00, 0x78, 0x44, 0x3D, 0x14, 0xA5, 0xE0, 0x05, /* 0x90 */ 0x00, 0x28, 0x44, 0x44, 0xA0, 0x90, 0x52, 0x13, - 0x08, 0x08, 0x08, 0x08, 0x1A, 0x1A, 0x1B, 0x1A, // 0xa0 + 0x08, 0x08, 0x08, 0x08, 0x1A, 0x1A, 0x1B, 0x1A, /* 0xa0 */ 0x00, 0x00, 0x00, 0xF0, 0xF0, 0xF0, 0xF0, 0x44, - 0x44, 0x4A, 0x00, 0xFF, 0xEF, 0xEF, 0xEF, 0xEF, // 0xb0 + 0x44, 0x4A, 0x00, 0xFF, 0xEF, 0xEF, 0xEF, 0xEF, /* 0xb0 */ 0xFF, 0xE7, 0xE9, 0xE9, 0xEB, 0xFF, 0xD6, 0xD8, - 0xD8, 0xD7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xc0 + 0xD8, 0xD7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0 */ 0x00, 0x00, 0x55, 0x00, 0xE4, 0x39, 0x00, 0x80, - 0x77, 0x77, 0x03, 0x20, 0x57, 0x9b, 0xdf, 0x31, // 0xd0 + 0x77, 0x77, 0x03, 0x20, 0x57, 0x9b, 0xdf, 0x31, /* 0xd0 */ 0x64, 0xa8, 0xec, 0xd1, 0x0f, 0x11, 0x11, 0x81, - 0x10, 0xC0, 0xAA, 0xAA, 0x00, 0x11, 0x00, 0x00, // 0xe0 + 0x10, 0xC0, 0xAA, 0xAA, 0x00, 0x11, 0x00, 0x00, /* 0xe0 */ 0x11, 0x00, 0x00, 0x11, 0x00, 0x00, 0x11, 0x00, - 0x83, 0xB5, 0x09, 0x78, 0x85, 0x00, 0x01, 0x20, // 0xf0 + 0x83, 0xB5, 0x09, 0x78, 0x85, 0x00, 0x01, 0x20, /* 0xf0 */ 0x64, 0x51, 0x40, 0xaf, 0xFF, 0xF0, 0x00, 0xC0, }; static u8 tbl_tw2865_pal_template[] = { - 0x00, 0xf0, 0x70, 0x30, 0x80, 0x80, 0x00, 0x12, // 0x00 + 0x00, 0xf0, 0x70, 0x30, 0x80, 0x80, 0x00, 0x12, /* 0x00 */ 0x11, 0xff, 0x01, 0xc3, 0x00, 0x00, 0x01, 0x7f, - 0x00, 0xf0, 0x70, 0x30, 0x80, 0x80, 0x00, 0x12, // 0x10 + 0x00, 0xf0, 0x70, 0x30, 0x80, 0x80, 0x00, 0x12, /* 0x10 */ 0x11, 0xff, 0x01, 0xc3, 0x00, 0x00, 0x01, 0x7f, - 0x00, 0xf0, 0x70, 0x30, 0x80, 0x80, 0x00, 0x12, // 0x20 + 0x00, 0xf0, 0x70, 0x30, 0x80, 0x80, 0x00, 0x12, /* 0x20 */ 0x11, 0xff, 0x01, 0xc3, 0x00, 0x00, 0x01, 0x7f, - 0x00, 0xf0, 0x70, 0x30, 0x80, 0x80, 0x00, 0x12, // 0x30 + 0x00, 0xf0, 0x70, 0x30, 0x80, 0x80, 0x00, 0x12, /* 0x30 */ 0x11, 0xff, 0x01, 0xc3, 0x00, 0x00, 0x01, 0x7f, - 0x00, 0x94, 0x90, 0x48, 0x00, 0x38, 0x7F, 0x80, // 0x40 + 0x00, 0x94, 0x90, 0x48, 0x00, 0x38, 0x7F, 0x80, /* 0x40 */ 0x80, 0x80, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x50 + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x50 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x45, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x60 + 0x45, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x43, - 0x08, 0x00, 0x00, 0x01, 0xf1, 0x03, 0xEF, 0x03, // 0x70 + 0x08, 0x00, 0x00, 0x01, 0xf1, 0x03, 0xEF, 0x03, /* 0x70 */ 0xEA, 0x03, 0xD9, 0x15, 0x15, 0xE4, 0xA3, 0x80, - 0x00, 0x02, 0x00, 0xCC, 0x00, 0x80, 0x44, 0x50, // 0x80 + 0x00, 0x02, 0x00, 0xCC, 0x00, 0x80, 0x44, 0x50, /* 0x80 */ 0x22, 0x01, 0xD8, 0xBC, 0xB8, 0x44, 0x38, 0x00, - 0x00, 0x78, 0x44, 0x3D, 0x14, 0xA5, 0xE0, 0x05, // 0x90 + 0x00, 0x78, 0x44, 0x3D, 0x14, 0xA5, 0xE0, 0x05, /* 0x90 */ 0x00, 0x28, 0x44, 0x44, 0xA0, 0x90, 0x52, 0x13, - 0x08, 0x08, 0x08, 0x08, 0x1A, 0x1A, 0x1A, 0x1A, // 0xa0 + 0x08, 0x08, 0x08, 0x08, 0x1A, 0x1A, 0x1A, 0x1A, /* 0xa0 */ 0x00, 0x00, 0x00, 0xF0, 0xF0, 0xF0, 0xF0, 0x44, - 0x44, 0x4A, 0x00, 0xFF, 0xEF, 0xEF, 0xEF, 0xEF, // 0xb0 + 0x44, 0x4A, 0x00, 0xFF, 0xEF, 0xEF, 0xEF, 0xEF, /* 0xb0 */ 0xFF, 0xE7, 0xE9, 0xE9, 0xE9, 0xFF, 0xD7, 0xD8, - 0xD9, 0xD8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xc0 + 0xD9, 0xD8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xc0 */ 0x00, 0x00, 0x55, 0x00, 0xE4, 0x39, 0x00, 0x80, - 0x77, 0x77, 0x03, 0x20, 0x57, 0x9b, 0xdf, 0x31, // 0xd0 + 0x77, 0x77, 0x03, 0x20, 0x57, 0x9b, 0xdf, 0x31, /* 0xd0 */ 0x64, 0xa8, 0xec, 0xd1, 0x0f, 0x11, 0x11, 0x81, - 0x10, 0xC0, 0xAA, 0xAA, 0x00, 0x11, 0x00, 0x00, // 0xe0 + 0x10, 0xC0, 0xAA, 0xAA, 0x00, 0x11, 0x00, 0x00, /* 0xe0 */ 0x11, 0x00, 0x00, 0x11, 0x00, 0x00, 0x11, 0x00, - 0x83, 0xB5, 0x09, 0x00, 0xA0, 0x00, 0x01, 0x20, // 0xf0 + 0x83, 0xB5, 0x09, 0x00, 0xA0, 0x00, 0x01, 0x20, /* 0xf0 */ 0x64, 0x51, 0x40, 0xaf, 0xFF, 0xF0, 0x00, 0xC0, }; @@ -181,8 +181,8 @@ static void tw_write_and_verify(struct solo6010_dev *solo_dev, u8 addr, u8 off, msleep_interruptible(1); } -// printk("solo6010/tw28: Error writing register: %02x->%02x [%02x]\n", -// addr, off, val); +/* printk("solo6010/tw28: Error writing register: %02x->%02x [%02x]\n", + addr, off, val); */ } static int tw2865_setup(struct solo6010_dev *solo_dev, u8 dev_addr) @@ -217,7 +217,7 @@ static int tw2865_setup(struct solo6010_dev *solo_dev, u8 dev_addr) for (i = 0; i < 0xff; i++) { /* Skip read only registers */ - if (i >= 0xb8 && i <= 0xc1 ) + if (i >= 0xb8 && i <= 0xc1) continue; if ((i & ~0x30) == 0x00 || (i & ~0x30) == 0x0c || @@ -302,7 +302,7 @@ static int tw2864_setup(struct solo6010_dev *solo_dev, u8 dev_addr) for (i = 0; i < 0xff; i++) { /* Skip read only registers */ - if (i >= 0xb8 && i <= 0xc1 ) + if (i >= 0xb8 && i <= 0xc1) continue; if ((i & ~0x30) == 0x00 || (i & ~0x30) == 0x0c || @@ -334,13 +334,13 @@ static int tw2815_setup(struct solo6010_dev *solo_dev, u8 dev_addr) }; u8 tbl_tw2815_sfr[] = { - 0x00, 0x00, 0x00, 0xc0, 0x45, 0xa0, 0xd0, 0x2f, // 0x00 + 0x00, 0x00, 0x00, 0xc0, 0x45, 0xa0, 0xd0, 0x2f, /* 0x00 */ 0x64, 0x80, 0x80, 0x82, 0x82, 0x00, 0x00, 0x00, - 0x00, 0x0f, 0x05, 0x00, 0x00, 0x80, 0x06, 0x00, // 0x10 + 0x00, 0x0f, 0x05, 0x00, 0x00, 0x80, 0x06, 0x00, /* 0x10 */ 0x00, 0x00, 0x00, 0xff, 0x8f, 0x00, 0x00, 0x00, - 0x88, 0x88, 0xc0, 0x00, 0x20, 0x64, 0xa8, 0xec, // 0x20 + 0x88, 0x88, 0xc0, 0x00, 0x20, 0x64, 0xa8, 0xec, /* 0x20 */ 0x31, 0x75, 0xb9, 0xfd, 0x00, 0x00, 0x88, 0x88, - 0x88, 0x11, 0x00, 0x88, 0x88, 0x00, // 0x30 + 0x88, 0x11, 0x00, 0x88, 0x88, 0x00, /* 0x30 */ }; u8 *tbl_tw2815_common; int i; @@ -459,7 +459,7 @@ static int tw2815_setup(struct solo6010_dev *solo_dev, u8 dev_addr) for (i = 0; i < 0x0f; i++) { if (i == 0x00) - continue; // read-only + continue; /* read-only */ solo_i2c_writebyte(solo_dev, SOLO_I2C_TW, dev_addr, (ch * 0x10) + i, tbl_tw2815_common[i]); @@ -597,7 +597,7 @@ int solo_tw28_init(struct solo6010_dev *solo_dev) return 0; } -/* +/* * We accessed the video status signal in the Techwell chip through * iic/i2c because the video status reported by register REG_VI_STATUS1 * (address 0x012C) of the SOLO6010 chip doesn't give the correct video @@ -751,7 +751,7 @@ int tw28_get_ctrl_val(struct solo6010_dev *solo_dev, u32 ctrl, u8 ch, rval = tw_readbyte(solo_dev, chip_num, TW286x_BRIGHTNESS_ADDR(ch), TW_BRIGHTNESS_ADDR(ch)); - if (is_tw286x(solo_dev, chip_num)) + if (is_tw286x(solo_dev, chip_num)) *val = (s32)((char)rval) + 128; else *val = rval; diff --git a/drivers/staging/solo6x10/solo6010-v4l2-enc.c b/drivers/staging/solo6x10/solo6010-v4l2-enc.c index 5e2001aeb846..7bbb94097d29 100644 --- a/drivers/staging/solo6x10/solo6010-v4l2-enc.c +++ b/drivers/staging/solo6x10/solo6010-v4l2-enc.c @@ -598,7 +598,8 @@ static void solo_enc_fillbuf(struct solo_enc_fh *fh, goto buf_err; } - if (WARN_ON_ONCE(!(vbuf = videobuf_to_dma(vb)))) + vbuf = videobuf_to_dma(vb); + if (WARN_ON_ONCE(!vbuf)) goto buf_err; if (fh->fmt == V4L2_PIX_FMT_MPEG) @@ -731,7 +732,8 @@ void solo_enc_v4l2_isr(struct solo6010_dev *solo_dev) jpeg_next = solo_reg_read(solo_dev, SOLO_VE_JPEG_QUE(solo_dev->enc_idx)); - if ((ch = (mpeg_current >> 24) & 0x1f) >= SOLO_MAX_CHANNELS) { + ch = (mpeg_current >> 24) & 0x1f; + if (ch >= SOLO_MAX_CHANNELS) { ch -= SOLO_MAX_CHANNELS; enc_type = SOLO_ENC_TYPE_EXT; } else @@ -872,7 +874,8 @@ static int solo_enc_open(struct file *file) struct solo_enc_dev *solo_enc = video_drvdata(file); struct solo_enc_fh *fh; - if ((fh = kzalloc(sizeof(*fh), GFP_KERNEL)) == NULL) + fh = kzalloc(sizeof(*fh), GFP_KERNEL); + if (fh == NULL) return -ENOMEM; fh->enc = solo_enc; @@ -1042,9 +1045,8 @@ static int solo_enc_try_fmt_cap(struct file *file, void *priv, if (pix->field == V4L2_FIELD_ANY) pix->field = V4L2_FIELD_INTERLACED; - else if (pix->field != V4L2_FIELD_INTERLACED) { + else if (pix->field != V4L2_FIELD_INTERLACED) pix->field = V4L2_FIELD_INTERLACED; - } /* Just set these */ pix->colorspace = V4L2_COLORSPACE_SMPTE170M; @@ -1064,7 +1066,8 @@ static int solo_enc_set_fmt_cap(struct file *file, void *priv, spin_lock(&solo_enc->lock); - if ((ret = solo_enc_try_fmt_cap(file, priv, f))) { + ret = solo_enc_try_fmt_cap(file, priv, f); + if (ret) { spin_unlock(&solo_enc->lock); return ret; } @@ -1107,7 +1110,7 @@ static int solo_enc_get_fmt_cap(struct file *file, void *priv, return 0; } -static int solo_enc_reqbufs(struct file *file, void *priv, +static int solo_enc_reqbufs(struct file *file, void *priv, struct v4l2_requestbuffers *req) { struct solo_enc_fh *fh = priv; @@ -1388,7 +1391,8 @@ static int solo_querymenu(struct file *file, void *priv, int err; qctrl.id = qmenu->id; - if ((err = solo_queryctrl(file, priv, &qctrl))) + err = solo_queryctrl(file, priv, &qctrl); + if (err) return err; return v4l2_ctrl_query_menu(qmenu, &qctrl, NULL); diff --git a/drivers/staging/solo6x10/solo6010-v4l2.c b/drivers/staging/solo6x10/solo6010-v4l2.c index 7a9c348de565..a8491dc0e914 100644 --- a/drivers/staging/solo6x10/solo6010-v4l2.c +++ b/drivers/staging/solo6x10/solo6010-v4l2.c @@ -245,15 +245,16 @@ static void solo_fillbuf(struct solo_filehandle *fh, struct videobuf_buffer *vb) { struct solo6010_dev *solo_dev = fh->solo_dev; - struct videobuf_dmabuf* vbuf; + struct videobuf_dmabuf *vbuf; unsigned int fdma_addr; int error = 1; int i; - struct scatterlist* sg; + struct scatterlist *sg; dma_addr_t sg_dma; int sg_size_left; - if (!(vbuf = videobuf_to_dma(vb))) + vbuf = videobuf_to_dma(vb); + if (!vbuf) goto finish_buf; if (erase_off(solo_dev)) { @@ -524,7 +525,8 @@ static int solo_v4l2_open(struct file *file) struct solo_filehandle *fh; int ret; - if ((fh = kzalloc(sizeof(*fh), GFP_KERNEL)) == NULL) + fh = kzalloc(sizeof(*fh), GFP_KERNEL); + if (fh == NULL) return -ENOMEM; spin_lock_init(&fh->slock); @@ -532,7 +534,8 @@ static int solo_v4l2_open(struct file *file) fh->solo_dev = solo_dev; file->private_data = fh; - if ((ret = solo_start_thread(fh))) { + ret = solo_start_thread(fh); + if (ret) { kfree(fh); return ret; } @@ -726,7 +729,7 @@ static int solo_get_fmt_cap(struct file *file, void *priv, return 0; } -static int solo_reqbufs(struct file *file, void *priv, +static int solo_reqbufs(struct file *file, void *priv, struct v4l2_requestbuffers *req) { struct solo_filehandle *fh = priv; @@ -940,13 +943,13 @@ int solo_v4l2_init(struct solo6010_dev *solo_dev) for (i = 0; i < solo_dev->nr_chans; i++) { solo_v4l2_set_ch(solo_dev, i); while (erase_off(solo_dev)) - ;// Do nothing + ;/* Do nothing */ } /* Set the default display channel */ solo_v4l2_set_ch(solo_dev, 0); while (erase_off(solo_dev)) - ;// Do nothing + ;/* Do nothing */ solo6010_irq_on(solo_dev, SOLO_IRQ_VIDEO_IN); diff --git a/drivers/staging/solo6x10/solo6010.h b/drivers/staging/solo6x10/solo6010.h index 9f5d2a326ae1..9c930f3a017b 100644 --- a/drivers/staging/solo6x10/solo6010.h +++ b/drivers/staging/solo6x10/solo6010.h @@ -68,7 +68,7 @@ #define SOLO6010_VER_MINOR 0 #define SOLO6010_VER_SUB 0 #define SOLO6010_VER_NUM \ - KERNEL_VERSION(SOLO6010_VER_MAJOR, SOLO6010_VER_MINOR, SOLO6010_VER_SUB) + KERNEL_VERSION(SOLO6010_VER_MAJOR, SOLO6010_VER_MINOR, SOLO6010_VER_SUB) /* * The SOLO6010 actually has 8 i2c channels, but we only use 2. @@ -221,7 +221,7 @@ struct solo6010_dev { struct solo_enc_buf enc_buf[SOLO_NR_RING_BUFS]; /* Current video settings */ - u32 video_type; + u32 video_type; u16 video_hsize, video_vsize; u16 vout_hstart, vout_vstart; u16 vin_hstart, vin_vstart; -- cgit v1.2.3 From 3701befc44eb9b0e5a0e0b7169448658919b9850 Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Wed, 10 Nov 2010 21:31:38 +0100 Subject: Staging, bcm: Remove unnecessary casts of void ptr returning alloc function return values Here's a patch against a copy of linux-next that I just cloned. Don't pointlessly cast pointers returned by allocation functions that return void pointers which are implicitly converted. For drivers/staging/bcm/ Signed-off-by: Jesper Juhl Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/CmHost.c | 2 +- drivers/staging/bcm/InterfaceDld.c | 14 ++++++-------- drivers/staging/bcm/Misc.c | 15 ++++++--------- 3 files changed, 13 insertions(+), 18 deletions(-) diff --git a/drivers/staging/bcm/CmHost.c b/drivers/staging/bcm/CmHost.c index 38b64e69d81a..a685cadb778d 100644 --- a/drivers/staging/bcm/CmHost.c +++ b/drivers/staging/bcm/CmHost.c @@ -1702,7 +1702,7 @@ ULONG StoreCmControlResponseMessage(PMINI_ADAPTER Adapter,PVOID pvBuffer,UINT *p } // For DSA_REQ, only upto "psfAuthorizedSet" parameter should be accessed by driver! - pstAddIndication=(stLocalSFAddIndication *)kmalloc(sizeof(*pstAddIndication), GFP_KERNEL); + pstAddIndication=kmalloc(sizeof(*pstAddIndication), GFP_KERNEL); if(NULL==pstAddIndication) return 0; diff --git a/drivers/staging/bcm/InterfaceDld.c b/drivers/staging/bcm/InterfaceDld.c index 1fc36a15f187..df64acb06126 100644 --- a/drivers/staging/bcm/InterfaceDld.c +++ b/drivers/staging/bcm/InterfaceDld.c @@ -5,15 +5,14 @@ int InterfaceFileDownload( PVOID arg, struct file *flp, unsigned int on_chip_loc) { - char *buff=NULL; // unsigned int reg=0; mm_segment_t oldfs={0}; int errno=0, len=0 /*,is_config_file = 0*/; loff_t pos=0; PS_INTERFACE_ADAPTER psIntfAdapter = (PS_INTERFACE_ADAPTER)arg; //PMINI_ADAPTER Adapter = psIntfAdapter->psAdapter; + char *buff=kmalloc(MAX_TRANSFER_CTRL_BYTE_USB, GFP_KERNEL); - buff=(PCHAR)kmalloc(MAX_TRANSFER_CTRL_BYTE_USB, GFP_KERNEL); if(!buff) { return -ENOMEM; @@ -56,7 +55,7 @@ int InterfaceFileReadbackFromChip( PVOID arg, struct file *flp, unsigned int on_chip_loc) { - char *buff=NULL, *buff_readback=NULL; + char *buff, *buff_readback; unsigned int reg=0; mm_segment_t oldfs={0}; int errno=0, len=0, is_config_file = 0; @@ -65,8 +64,8 @@ int InterfaceFileReadbackFromChip( PVOID arg, INT Status = STATUS_SUCCESS; PS_INTERFACE_ADAPTER psIntfAdapter = (PS_INTERFACE_ADAPTER)arg; - buff=(PCHAR)kmalloc(MAX_TRANSFER_CTRL_BYTE_USB, GFP_DMA); - buff_readback=(PCHAR)kmalloc(MAX_TRANSFER_CTRL_BYTE_USB , GFP_DMA); + buff=kmalloc(MAX_TRANSFER_CTRL_BYTE_USB, GFP_DMA); + buff_readback=kmalloc(MAX_TRANSFER_CTRL_BYTE_USB , GFP_DMA); if(!buff || !buff_readback) { kfree(buff); @@ -287,7 +286,7 @@ int bcm_ioctl_fw_download(PMINI_ADAPTER Adapter, FIRMWARE_INFO *psFwInfo) else { - buff = (PUCHAR)kzalloc(psFwInfo->u32FirmwareLength,GFP_KERNEL); + buff = kzalloc(psFwInfo->u32FirmwareLength,GFP_KERNEL); if(buff==NULL) { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL,"Failed in allocation memory"); @@ -345,11 +344,10 @@ static INT buffRdbkVerify(PMINI_ADAPTER Adapter, PUCHAR mappedbuffer, UINT u32FirmwareLength, ULONG u32StartingAddress) { - PUCHAR readbackbuff = NULL; UINT len = u32FirmwareLength; INT retval = STATUS_SUCCESS; + PUCHAR readbackbuff = kzalloc(MAX_TRANSFER_CTRL_BYTE_USB,GFP_KERNEL); - readbackbuff = (PUCHAR)kzalloc(MAX_TRANSFER_CTRL_BYTE_USB,GFP_KERNEL); if(NULL == readbackbuff) { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "MEMORY ALLOCATION FAILED"); diff --git a/drivers/staging/bcm/Misc.c b/drivers/staging/bcm/Misc.c index 82d9f86821ca..1bb6a1d97ce0 100644 --- a/drivers/staging/bcm/Misc.c +++ b/drivers/staging/bcm/Misc.c @@ -71,8 +71,7 @@ InitAdapter(PMINI_ADAPTER psAdapter) default_wimax_protocol_initialize(psAdapter); for (i=0;itxctlpacket[i] = (char *)kmalloc(MAX_CNTL_PKT_SIZE, - GFP_KERNEL); + psAdapter->txctlpacket[i] = kmalloc(MAX_CNTL_PKT_SIZE, GFP_KERNEL); if(!psAdapter->txctlpacket[i]) { BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "No More Cntl pkts got, max got is %d", i); @@ -1228,11 +1227,11 @@ static int bcm_parse_target_params(PMINI_ADAPTER Adapter) { struct file *flp=NULL; mm_segment_t oldfs={0}; - char *buff = NULL; + char *buff; int len = 0; loff_t pos = 0; - buff=(PCHAR)kmalloc(BUFFER_1K, GFP_KERNEL); + buff=kmalloc(BUFFER_1K, GFP_KERNEL); if(!buff) { return -ENOMEM; @@ -1393,12 +1392,10 @@ static VOID doPowerAutoCorrection(PMINI_ADAPTER psAdapter) #if 0 static unsigned char *ReadMacAddrEEPROM(PMINI_ADAPTER Adapter, ulong dwAddress) { - unsigned char *pucmacaddr = NULL; - int status = 0, i=0; - unsigned int temp =0; + int status = 0, i = 0; + unsigned int temp = 0; + unsigned char *pucmacaddr = kmalloc(MAC_ADDRESS_SIZE, GFP_KERNEL); - - pucmacaddr = (unsigned char *)kmalloc(MAC_ADDRESS_SIZE, GFP_KERNEL); if(!pucmacaddr) { BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "No Buffers to Read the EEPROM Address\n"); -- cgit v1.2.3 From 319684b1cd15f24120b9513b38a949539c0b7938 Mon Sep 17 00:00:00 2001 From: Brandon Philips Date: Sat, 6 Nov 2010 21:19:22 -0400 Subject: driver core: fix whitespace in class_attr_string 869dfc875e3 addded a long line and indented with spaces. Fix. Signed-off-by: Brandon Philips Signed-off-by: Greg Kroah-Hartman --- drivers/base/class.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/base/class.c b/drivers/base/class.c index 9c63a5687d69..7975a52bdf5b 100644 --- a/drivers/base/class.c +++ b/drivers/base/class.c @@ -482,8 +482,8 @@ void class_interface_unregister(struct class_interface *class_intf) class_put(parent); } -ssize_t show_class_attr_string(struct class *class, struct class_attribute *attr, - char *buf) +ssize_t show_class_attr_string(struct class *class, + struct class_attribute *attr, char *buf) { struct class_attribute_string *cs; cs = container_of(attr, struct class_attribute_string, attr); -- cgit v1.2.3 From 6174c3496d43b78969d4a989e1aabfbc55acbf15 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Wed, 10 Nov 2010 17:08:26 -0800 Subject: Revert "staging: batman-adv: Use linux/etherdevice.h address helper functions" This reverts commit 5712dc7fc812d1bdbc5e634d389bc759d4e7550c. Turns out the batman maintainers didn't like the implementation of it, and the original author was going to rework it to meet their approval, and I applied it without fully realizing all of this. My fault. Cc: Marek Lindner Cc: Simon Wunderlich Cc: Andrew Lunn Cc: Tobias Klauser Signed-off-by: Greg Kroah-Hartman --- drivers/staging/batman-adv/main.c | 12 +++++++++++- drivers/staging/batman-adv/main.h | 3 ++- drivers/staging/batman-adv/routing.c | 16 ++++++++-------- drivers/staging/batman-adv/soft-interface.c | 2 +- drivers/staging/batman-adv/vis.c | 4 ++-- 5 files changed, 24 insertions(+), 13 deletions(-) diff --git a/drivers/staging/batman-adv/main.c b/drivers/staging/batman-adv/main.c index 6ea64200ad16..0587940d2723 100644 --- a/drivers/staging/batman-adv/main.c +++ b/drivers/staging/batman-adv/main.c @@ -149,7 +149,7 @@ void dec_module_count(void) int compare_orig(void *data1, void *data2) { - return (compare_ether_addr(data1, data2) == 0 ? 1 : 0); + return (memcmp(data1, data2, ETH_ALEN) == 0 ? 1 : 0); } /* hashfunction to choose an entry in a hash table of given size */ @@ -192,6 +192,16 @@ int is_my_mac(uint8_t *addr) } +int is_bcast(uint8_t *addr) +{ + return (addr[0] == (uint8_t)0xff) && (addr[1] == (uint8_t)0xff); +} + +int is_mcast(uint8_t *addr) +{ + return *addr & 0x01; +} + module_init(batman_init); module_exit(batman_exit); diff --git a/drivers/staging/batman-adv/main.h b/drivers/staging/batman-adv/main.h index 14d567d4911a..5e3f51681f5e 100644 --- a/drivers/staging/batman-adv/main.h +++ b/drivers/staging/batman-adv/main.h @@ -109,7 +109,6 @@ #include /* mutex */ #include /* needed by all modules */ #include /* netdevice */ -#include #include /* ethernet header */ #include /* poll_table */ #include /* kernel threads */ @@ -139,6 +138,8 @@ void dec_module_count(void); int compare_orig(void *data1, void *data2); int choose_orig(void *data, int32_t size); int is_my_mac(uint8_t *addr); +int is_bcast(uint8_t *addr); +int is_mcast(uint8_t *addr); #ifdef CONFIG_BATMAN_ADV_DEBUG int debug_log(struct bat_priv *bat_priv, char *fmt, ...); diff --git a/drivers/staging/batman-adv/routing.c b/drivers/staging/batman-adv/routing.c index d42c16559dff..90102631330b 100644 --- a/drivers/staging/batman-adv/routing.c +++ b/drivers/staging/batman-adv/routing.c @@ -756,11 +756,11 @@ int recv_bat_packet(struct sk_buff *skb, struct batman_if *batman_if) ethhdr = (struct ethhdr *)skb_mac_header(skb); /* packet with broadcast indication but unicast recipient */ - if (!is_broadcast_ether_addr(ethhdr->h_dest)) + if (!is_bcast(ethhdr->h_dest)) return NET_RX_DROP; /* packet with broadcast sender address */ - if (is_broadcast_ether_addr(ethhdr->h_source)) + if (is_bcast(ethhdr->h_source)) return NET_RX_DROP; /* create a copy of the skb, if needed, to modify it. */ @@ -933,11 +933,11 @@ int recv_icmp_packet(struct sk_buff *skb, struct batman_if *recv_if) ethhdr = (struct ethhdr *)skb_mac_header(skb); /* packet with unicast indication but broadcast recipient */ - if (is_broadcast_ether_addr(ethhdr->h_dest)) + if (is_bcast(ethhdr->h_dest)) return NET_RX_DROP; /* packet with broadcast sender address */ - if (is_broadcast_ether_addr(ethhdr->h_source)) + if (is_bcast(ethhdr->h_source)) return NET_RX_DROP; /* not for me */ @@ -1107,11 +1107,11 @@ static int check_unicast_packet(struct sk_buff *skb, int hdr_size) ethhdr = (struct ethhdr *)skb_mac_header(skb); /* packet with unicast indication but broadcast recipient */ - if (is_broadcast_ether_addr(ethhdr->h_dest)) + if (is_bcast(ethhdr->h_dest)) return -1; /* packet with broadcast sender address */ - if (is_broadcast_ether_addr(ethhdr->h_source)) + if (is_bcast(ethhdr->h_source)) return -1; /* not for me */ @@ -1283,11 +1283,11 @@ int recv_bcast_packet(struct sk_buff *skb, struct batman_if *recv_if) ethhdr = (struct ethhdr *)skb_mac_header(skb); /* packet with broadcast indication but unicast recipient */ - if (!is_broadcast_ether_addr(ethhdr->h_dest)) + if (!is_bcast(ethhdr->h_dest)) return NET_RX_DROP; /* packet with broadcast sender address */ - if (is_broadcast_ether_addr(ethhdr->h_source)) + if (is_bcast(ethhdr->h_source)) return NET_RX_DROP; /* ignore broadcasts sent by myself */ diff --git a/drivers/staging/batman-adv/soft-interface.c b/drivers/staging/batman-adv/soft-interface.c index 820e14159dd3..3904db9ce7b1 100644 --- a/drivers/staging/batman-adv/soft-interface.c +++ b/drivers/staging/batman-adv/soft-interface.c @@ -140,7 +140,7 @@ int interface_tx(struct sk_buff *skb, struct net_device *soft_iface) hna_local_add(soft_iface, ethhdr->h_source); /* ethernet packet should be broadcasted */ - if (is_multicast_ether_addr(ethhdr->h_dest)) { + if (is_bcast(ethhdr->h_dest) || is_mcast(ethhdr->h_dest)) { if (!bat_priv->primary_if) goto dropped; diff --git a/drivers/staging/batman-adv/vis.c b/drivers/staging/batman-adv/vis.c index 395f1109d606..4473cc8ed6b0 100644 --- a/drivers/staging/batman-adv/vis.c +++ b/drivers/staging/batman-adv/vis.c @@ -469,7 +469,7 @@ void receive_client_update_packet(struct bat_priv *bat_priv, int are_target = 0; /* clients shall not broadcast. */ - if (is_broadcast_ether_addr(vis_packet->target_orig)) + if (is_bcast(vis_packet->target_orig)) return; /* Are we the target for this VIS packet? */ @@ -746,7 +746,7 @@ static void send_vis_packet(struct bat_priv *bat_priv, struct vis_info *info) ETH_ALEN); packet->ttl--; - if (is_broadcast_ether_addr(packet->target_orig)) + if (is_bcast(packet->target_orig)) broadcast_vis_packet(bat_priv, info); else unicast_vis_packet(bat_priv, info); -- cgit v1.2.3 From 527f9e907c39f7e88abb57eaa8bccb43c8706a3d Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 11 Nov 2010 01:16:58 +0000 Subject: drm/i915: Remove the global irq wait queue ... as it has been replaced by per-ring waiters. Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_debugfs.c | 8 +------- drivers/gpu/drm/i915/i915_drv.h | 2 +- drivers/gpu/drm/i915/i915_irq.c | 2 +- 3 files changed, 3 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 9cb6061bf9d5..4c8fae9baaad 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -1022,7 +1022,6 @@ i915_wedged_write(struct file *filp, loff_t *ppos) { struct drm_device *dev = filp->private_data; - drm_i915_private_t *dev_priv = dev->dev_private; char buf[20]; int val = 1; @@ -1038,12 +1037,7 @@ i915_wedged_write(struct file *filp, } DRM_INFO("Manually setting wedged to %d\n", val); - - atomic_set(&dev_priv->mm.wedged, val); - if (val) { - wake_up_all(&dev_priv->irq_queue); - queue_work(dev_priv->wq, &dev_priv->error_work); - } + i915_handle_error(dev, val); return cnt; } diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index ff7593f70f0f..30d7a7bc6f2e 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -289,7 +289,6 @@ typedef struct drm_i915_private { int current_page; int page_flipping; - wait_queue_head_t irq_queue; atomic_t irq_received; /** Protects user_irq_refcount and irq_mask_reg */ spinlock_t user_irq_lock; @@ -915,6 +914,7 @@ extern void i915_update_gfx_val(struct drm_i915_private *dev_priv); /* i915_irq.c */ void i915_hangcheck_elapsed(unsigned long data); +void i915_handle_error(struct drm_device *dev, bool wedged); extern int i915_irq_emit(struct drm_device *dev, void *data, struct drm_file *file_priv); extern int i915_irq_wait(struct drm_device *dev, void *data, diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 3ec631f1129d..4a0664ea49b9 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -891,7 +891,7 @@ static void i915_report_and_clear_eir(struct drm_device *dev) * so userspace knows something bad happened (should trigger collection * of a ring dump etc.). */ -static void i915_handle_error(struct drm_device *dev, bool wedged) +void i915_handle_error(struct drm_device *dev, bool wedged) { struct drm_i915_private *dev_priv = dev->dev_private; -- cgit v1.2.3 From 34db1d595ef6f183fbc1e42cda45a3dfa0035258 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Thu, 11 Nov 2010 09:58:57 +0100 Subject: block: export 'ro' sysfs attribute for partitions We already export 'ro' for the disk. This adds the same attribute for partitions. Cc: Karel Zak Signed-off-by: Kay Sievers Signed-off-by: Jens Axboe --- fs/partitions/check.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/fs/partitions/check.c b/fs/partitions/check.c index 79fbf3f390f0..861ae84fcee5 100644 --- a/fs/partitions/check.c +++ b/fs/partitions/check.c @@ -237,6 +237,13 @@ ssize_t part_size_show(struct device *dev, return sprintf(buf, "%llu\n",(unsigned long long)p->nr_sects); } +ssize_t part_ro_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct hd_struct *p = dev_to_part(dev); + return sprintf(buf, "%d\n", p->policy ? 1 : 0); +} + ssize_t part_alignment_offset_show(struct device *dev, struct device_attribute *attr, char *buf) { @@ -312,6 +319,7 @@ ssize_t part_fail_store(struct device *dev, static DEVICE_ATTR(partition, S_IRUGO, part_partition_show, NULL); static DEVICE_ATTR(start, S_IRUGO, part_start_show, NULL); static DEVICE_ATTR(size, S_IRUGO, part_size_show, NULL); +static DEVICE_ATTR(ro, S_IRUGO, part_ro_show, NULL); static DEVICE_ATTR(alignment_offset, S_IRUGO, part_alignment_offset_show, NULL); static DEVICE_ATTR(discard_alignment, S_IRUGO, part_discard_alignment_show, NULL); @@ -326,6 +334,7 @@ static struct attribute *part_attrs[] = { &dev_attr_partition.attr, &dev_attr_start.attr, &dev_attr_size.attr, + &dev_attr_ro.attr, &dev_attr_alignment_offset.attr, &dev_attr_discard_alignment.attr, &dev_attr_stat.attr, -- cgit v1.2.3 From 06fc8846a2c0ddcc51e6666a78fc29a8e749ca3b Mon Sep 17 00:00:00 2001 From: Brett Rudley Date: Wed, 10 Nov 2010 17:19:41 -0800 Subject: staging: brcm80211: Remove unused module parameters. Signed-off-by: Brett Rudley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/sys/wl_mac80211.c | 48 ++++------------------------- 1 file changed, 6 insertions(+), 42 deletions(-) diff --git a/drivers/staging/brcm80211/sys/wl_mac80211.c b/drivers/staging/brcm80211/sys/wl_mac80211.c index cb5dba95fc86..4b59e073aa15 100644 --- a/drivers/staging/brcm80211/sys/wl_mac80211.c +++ b/drivers/staging/brcm80211/sys/wl_mac80211.c @@ -182,32 +182,6 @@ module_param(phymsglevel, int, 0); #endif /* WLC_HIGH_ONLY */ #endif /* BCMDBG */ -static int oneonly; -module_param(oneonly, int, 0); - -static int piomode; -module_param(piomode, int, 0); - -static int instance_base; /* Starting instance number */ -module_param(instance_base, int, 0); - -#if defined(BCMDBG) -static char *macaddr; -module_param(macaddr, charp, S_IRUGO); -#endif - -static int nompc = 1; -module_param(nompc, int, 0); - -static char name[IFNAMSIZ] = "eth%d"; -module_param_string(name, name, IFNAMSIZ, 0); - -#ifndef SRCBASE -#define SRCBASE "." -#endif - -#define WL_MAGIC 0xdeadbeef - #define HW_TO_WL(hw) (hw->priv) #define WL_TO_HW(wl) (wl->pub->ieee_hw) #ifdef WLC_HIGH_ONLY @@ -776,7 +750,7 @@ static wl_info_t *wl_attach(u16 vendor, u16 device, unsigned long regs, struct ieee80211_hw *hw; u8 perm[ETH_ALEN]; - unit = wl_found + instance_base; + unit = wl_found; err = 0; if (unit < 0) { @@ -784,11 +758,6 @@ static wl_info_t *wl_attach(u16 vendor, u16 device, unsigned long regs, return NULL; } - if (oneonly && (unit != instance_base)) { - WL_ERROR(("wl%d: wl_attach: oneonly is set, exiting\n", unit)); - return NULL; - } - osh = osl_attach(btparam, bustype); ASSERT(osh); @@ -808,7 +777,6 @@ static wl_info_t *wl_attach(u16 vendor, u16 device, unsigned long regs, #endif ASSERT(wl); - wl->magic = WL_MAGIC; wl->osh = osh; atomic_set(&wl->callbacks, 0); @@ -842,9 +810,7 @@ static wl_info_t *wl_attach(u16 vendor, u16 device, unsigned long regs, base_addr = regs; if (bustype == PCI_BUS) { - /* piomode can be overwritten by command argument */ - wl->piomode = piomode; - WL_TRACE(("PCI/%s\n", wl->piomode ? "PIO" : "DMA")); + wl->piomode = false; } else if (bustype == RPC_BUS) { /* Do nothing */ } else { @@ -911,11 +877,9 @@ static wl_info_t *wl_attach(u16 vendor, u16 device, unsigned long regs, wl_rpc_down, NULL, NULL); #endif /* WLC_HIGH_ONLY */ - if (nompc) { - if (wlc_iovar_setint(wl->wlc, "mpc", 0)) { - WL_ERROR(("wl%d: Error setting MPC variable to 0\n", - unit)); - } + if (wlc_iovar_setint(wl->wlc, "mpc", 0)) { + WL_ERROR(("wl%d: Error setting MPC variable to 0\n", + unit)); } #ifdef BCMSDIO /* Set SDIO drive strength */ @@ -967,7 +931,7 @@ static wl_info_t *wl_attach(u16 vendor, u16 device, unsigned long regs, #endif #ifdef BCMDBG - printf(" (Compiled in " SRCBASE " at " __TIME__ " on " __DATE__ ")"); + printf(" (Compiled at " __TIME__ " on " __DATE__ ")"); #endif /* BCMDBG */ printf("\n"); -- cgit v1.2.3 From 68f89ad8c233a88b10404c5fd8a1109d12999962 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 3 Nov 2010 23:51:49 -0400 Subject: ASoC: Factor out boiler plate for DAPM event generation Make the DAPM sequence execution look a bit nicer by factoring out the code to invoke an event into a single function since it's all the same pretty much. Signed-off-by: Mark Brown Acked-by: Liam Girdwood --- sound/soc/soc-dapm.c | 98 ++++++++++++++++++++++++++-------------------------- 1 file changed, 49 insertions(+), 49 deletions(-) diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index 450307ccaf68..5a5db3f58f0f 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -726,13 +726,55 @@ static void dapm_seq_insert(struct snd_soc_dapm_widget *new_widget, list_add_tail(&new_widget->power_list, list); } +static void dapm_seq_check_event(struct snd_soc_dapm_context *dapm, + struct snd_soc_dapm_widget *w, int event) +{ + struct snd_soc_card *card = dapm->card; + const char *ev_name; + int power, ret; + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + ev_name = "PRE_PMU"; + power = 1; + break; + case SND_SOC_DAPM_POST_PMU: + ev_name = "POST_PMU"; + power = 1; + break; + case SND_SOC_DAPM_PRE_PMD: + ev_name = "PRE_PMD"; + power = 0; + break; + case SND_SOC_DAPM_POST_PMD: + ev_name = "POST_PMD"; + power = 0; + break; + default: + BUG(); + return; + } + + if (w->power != power) + return; + + if (w->event && (w->event_flags & event)) { + pop_dbg(dapm->dev, card->pop_time, "pop test : %s %s\n", + w->name, ev_name); + ret = w->event(w, NULL, event); + if (ret < 0) + pr_err("%s: %s event failed: %d\n", + ev_name, w->name, ret); + } +} + /* Apply the coalesced changes from a DAPM sequence */ static void dapm_seq_run_coalesced(struct snd_soc_dapm_context *dapm, struct list_head *pending) { - struct snd_soc_dapm_widget *w; struct snd_soc_card *card = dapm->card; - int reg, power, ret; + struct snd_soc_dapm_widget *w; + int reg, power; unsigned int value = 0; unsigned int mask = 0; unsigned int cur_mask; @@ -757,29 +799,9 @@ static void dapm_seq_run_coalesced(struct snd_soc_dapm_context *dapm, "pop test : Queue %s: reg=0x%x, 0x%x/0x%x\n", w->name, reg, value, mask); - /* power up pre event */ - if (w->power && w->event && - (w->event_flags & SND_SOC_DAPM_PRE_PMU)) { - pop_dbg(dapm->dev, card->pop_time, - "pop test : %s PRE_PMU\n", w->name); - ret = w->event(w, NULL, SND_SOC_DAPM_PRE_PMU); - if (ret < 0) - dev_err(dapm->dev, - "%s: pre event failed: %d\n", - w->name, ret); - } - - /* power down pre event */ - if (!w->power && w->event && - (w->event_flags & SND_SOC_DAPM_PRE_PMD)) { - pop_dbg(dapm->dev, card->pop_time, - "pop test : %s PRE_PMD\n", w->name); - ret = w->event(w, NULL, SND_SOC_DAPM_PRE_PMD); - if (ret < 0) - dev_err(dapm->dev, - "%s: pre event failed: %d\n", - w->name, ret); - } + /* Check for events */ + dapm_seq_check_event(dapm, w, SND_SOC_DAPM_PRE_PMU); + dapm_seq_check_event(dapm, w, SND_SOC_DAPM_PRE_PMD); } if (reg >= 0) { @@ -791,30 +813,8 @@ static void dapm_seq_run_coalesced(struct snd_soc_dapm_context *dapm, } list_for_each_entry(w, pending, power_list) { - /* power up post event */ - if (w->power && w->event && - (w->event_flags & SND_SOC_DAPM_POST_PMU)) { - pop_dbg(dapm->dev, card->pop_time, - "pop test : %s POST_PMU\n", w->name); - ret = w->event(w, - NULL, SND_SOC_DAPM_POST_PMU); - if (ret < 0) - dev_err(dapm->dev, - "%s: post event failed: %d\n", - w->name, ret); - } - - /* power down post event */ - if (!w->power && w->event && - (w->event_flags & SND_SOC_DAPM_POST_PMD)) { - pop_dbg(dapm->dev, card->pop_time, - "pop test : %s POST_PMD\n", w->name); - ret = w->event(w, NULL, SND_SOC_DAPM_POST_PMD); - if (ret < 0) - dev_err(dapm->dev, - "%s: post event failed: %d\n", - w->name, ret); - } + dapm_seq_check_event(dapm, w, SND_SOC_DAPM_POST_PMU); + dapm_seq_check_event(dapm, w, SND_SOC_DAPM_POST_PMD); } } -- cgit v1.2.3 From a8b1d34f3ee1bc139ac5fbe3f84f6d16c90136bb Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 3 Nov 2010 18:05:58 -0400 Subject: ASoC: Add trace events for ASoC register read/write The trace subsystem provides a convenient way of instrumenting the kernel which can be left on all the time with extremely low impact on the system unlike prints to the kernel log which can be very spammy. Begin adding support for instrumenting ASoC via this interface by adding trace for the register access primitives. Signed-off-by: Mark Brown Acked-by: Liam Girdwood --- include/trace/events/asoc.h | 64 +++++++++++++++++++++++++++++++++++++++++++++ sound/soc/soc-core.c | 5 ++++ 2 files changed, 69 insertions(+) create mode 100644 include/trace/events/asoc.h diff --git a/include/trace/events/asoc.h b/include/trace/events/asoc.h new file mode 100644 index 000000000000..93c3371daaca --- /dev/null +++ b/include/trace/events/asoc.h @@ -0,0 +1,64 @@ +#undef TRACE_SYSTEM +#define TRACE_SYSTEM asoc + +#if !defined(_TRACE_ASOC_H) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_ASOC_H + +#include +#include + +struct snd_soc_codec; + +/* + * Log register events + */ +DECLARE_EVENT_CLASS(snd_soc_reg, + + TP_PROTO(struct snd_soc_codec *codec, unsigned int reg, + unsigned int val), + + TP_ARGS(codec, reg, val), + + TP_STRUCT__entry( + __string( name, codec->name ) + __field( int, id ) + __field( unsigned int, reg ) + __field( unsigned int, val ) + ), + + TP_fast_assign( + __assign_str(name, codec->name); + __entry->id = codec->id; + __entry->reg = reg; + __entry->val = val; + ), + + TP_printk("codec=%s.%d reg=%x val=%x", __get_str(name), + (int)__entry->id, (unsigned int)__entry->reg, + (unsigned int)__entry->val) +); + +DEFINE_EVENT(snd_soc_reg, snd_soc_reg_write, + + TP_PROTO(struct snd_soc_codec *codec, unsigned int reg, + unsigned int val), + + TP_ARGS(codec, reg, val) + +); + +DEFINE_EVENT(snd_soc_reg, snd_soc_reg_read, + + TP_PROTO(struct snd_soc_codec *codec, unsigned int reg, + unsigned int val), + + TP_ARGS(codec, reg, val) + +); + + + +#endif /* _TRACE_ASOC_H */ + +/* This part must be outside protection */ +#include diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index c18ce1dc51b8..700a6d5b9721 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -39,6 +39,9 @@ #include #include +#define CREATE_TRACE_POINTS +#include + #define NAME_SIZE 32 static DEFINE_MUTEX(pcm_mutex); @@ -1914,6 +1917,7 @@ unsigned int snd_soc_read(struct snd_soc_codec *codec, unsigned int reg) ret = codec->driver->read(codec, reg); dev_dbg(codec->dev, "read %x => %x\n", reg, ret); + trace_snd_soc_reg_read(codec, reg, ret); return ret; } @@ -1923,6 +1927,7 @@ 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->driver->write(codec, reg, val); } EXPORT_SYMBOL_GPL(snd_soc_write); -- cgit v1.2.3 From 84e909303dbd3c8d882f152c17d1319f2873e147 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 4 Nov 2010 00:07:02 -0400 Subject: ASoC: Add DAPM trace events Trace events for DAPM allow us to monitor the performance and behaviour of DAPM with logging which can be built into the kernel permanantly, is more suited to automated analysis and display and less likely to suffer interference from other logging activity. Currently trace events are generated for: - Start and stop of DAPM processing - Start and stop of bias level changes - Power decisions for widgets - Widget event execution start and stop giving some view as to what is happening and where latencies occur. Actual changes in widget power can be seen via the register write trace in soc-core. Signed-off-by: Mark Brown Acked-by: Liam Girdwood --- include/trace/events/asoc.h | 112 ++++++++++++++++++++++++++++++++++++++++++++ sound/soc/soc-dapm.c | 14 ++++++ 2 files changed, 126 insertions(+) diff --git a/include/trace/events/asoc.h b/include/trace/events/asoc.h index 93c3371daaca..9978856d5897 100644 --- a/include/trace/events/asoc.h +++ b/include/trace/events/asoc.h @@ -8,6 +8,8 @@ #include struct snd_soc_codec; +struct snd_soc_card; +struct snd_soc_dapm_widget; /* * Log register events @@ -56,7 +58,117 @@ DEFINE_EVENT(snd_soc_reg, snd_soc_reg_read, ); +DECLARE_EVENT_CLASS(snd_soc_card, + TP_PROTO(struct snd_soc_card *card, int val), + + TP_ARGS(card, val), + + TP_STRUCT__entry( + __string( name, card->name ) + __field( int, val ) + ), + + TP_fast_assign( + __assign_str(name, card->name); + __entry->val = val; + ), + + TP_printk("card=%s val=%d", __get_str(name), (int)__entry->val) +); + +DEFINE_EVENT(snd_soc_card, snd_soc_bias_level_start, + + TP_PROTO(struct snd_soc_card *card, int val), + + TP_ARGS(card, val) + +); + +DEFINE_EVENT(snd_soc_card, snd_soc_bias_level_done, + + TP_PROTO(struct snd_soc_card *card, int val), + + TP_ARGS(card, val) + +); + +DECLARE_EVENT_CLASS(snd_soc_dapm_basic, + + TP_PROTO(struct snd_soc_card *card), + + TP_ARGS(card), + + TP_STRUCT__entry( + __string( name, card->name ) + ), + + TP_fast_assign( + __assign_str(name, card->name); + ), + + TP_printk("card=%s", __get_str(name)) +); + +DEFINE_EVENT(snd_soc_dapm_basic, snd_soc_dapm_start, + + TP_PROTO(struct snd_soc_card *card), + + TP_ARGS(card) + +); + +DEFINE_EVENT(snd_soc_dapm_basic, snd_soc_dapm_done, + + TP_PROTO(struct snd_soc_card *card), + + TP_ARGS(card) + +); + +DECLARE_EVENT_CLASS(snd_soc_dapm_widget, + + TP_PROTO(struct snd_soc_dapm_widget *w, int val), + + TP_ARGS(w, val), + + TP_STRUCT__entry( + __string( name, w->name ) + __field( int, val ) + ), + + TP_fast_assign( + __assign_str(name, w->name); + __entry->val = val; + ), + + TP_printk("widget=%s val=%d", __get_str(name), + (int)__entry->val) +); + +DEFINE_EVENT(snd_soc_dapm_widget, snd_soc_dapm_widget_power, + + TP_PROTO(struct snd_soc_dapm_widget *w, int val), + + TP_ARGS(w, val) + +); + +DEFINE_EVENT(snd_soc_dapm_widget, snd_soc_dapm_widget_event_start, + + TP_PROTO(struct snd_soc_dapm_widget *w, int val), + + TP_ARGS(w, val) + +); + +DEFINE_EVENT(snd_soc_dapm_widget, snd_soc_dapm_widget_event_done, + + TP_PROTO(struct snd_soc_dapm_widget *w, int val), + + TP_ARGS(w, val) + +); #endif /* _TRACE_ASOC_H */ diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index 5a5db3f58f0f..8352430f4043 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -46,6 +46,8 @@ #include #include +#include + /* dapm power sequences - make this per codec in the future */ static int dapm_up_seq[] = { [snd_soc_dapm_pre] = 0, @@ -151,6 +153,8 @@ static int snd_soc_dapm_set_bias_level(struct snd_soc_card *card, return -EINVAL; } + trace_snd_soc_bias_level_start(card, level); + if (card && card->set_bias_level) ret = card->set_bias_level(card, level); if (ret == 0) { @@ -160,6 +164,8 @@ static int snd_soc_dapm_set_bias_level(struct snd_soc_card *card, dapm->bias_level = level; } + trace_snd_soc_bias_level_done(card, level); + return ret; } @@ -761,7 +767,9 @@ static void dapm_seq_check_event(struct snd_soc_dapm_context *dapm, if (w->event && (w->event_flags & event)) { pop_dbg(dapm->dev, card->pop_time, "pop test : %s %s\n", w->name, ev_name); + trace_snd_soc_dapm_widget_event_start(w, event); ret = w->event(w, NULL, event); + trace_snd_soc_dapm_widget_event_done(w, event); if (ret < 0) pr_err("%s: %s event failed: %d\n", ev_name, w->name, ret); @@ -921,6 +929,8 @@ static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event) int power; int sys_power = 0; + trace_snd_soc_dapm_start(card); + /* Check which widgets we need to power and store them in * lists indicating if they should be powered up or down. */ @@ -947,6 +957,8 @@ static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event) if (w->power == power) continue; + trace_snd_soc_dapm_widget_power(w, power); + if (power) dapm_seq_insert(w, &up_list, dapm_up_seq); else @@ -1037,6 +1049,8 @@ static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event) "DAPM sequencing finished, waiting %dms\n", card->pop_time); pop_wait(card->pop_time); + trace_snd_soc_dapm_done(card); + return 0; } -- cgit v1.2.3 From e86c2412c88fbe4676920c40348d3c547c9edb0d Mon Sep 17 00:00:00 2001 From: maximilian attems Date: Fri, 29 Oct 2010 15:55:50 +0200 Subject: kbuild, deb-pkg: Fix build with paranoid umask umask 077 make deb-pkg dpkg-deb: building package `linux-image-2.6.36+' in `../linux-image-2.6.36+_2.6.36+-4_amd64.deb'. dpkg-deb: control directory has bad permissions 700 (must be >=0755 and <=0775) make[1]: *** [deb-pkg] Error 2 Reported-by: Bastian Blank Signed-off-by: maximilian attems Signed-off-by: Michal Marek --- scripts/package/builddeb | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/scripts/package/builddeb b/scripts/package/builddeb index 49b74e1ee12d..4dfec9aaaace 100644 --- a/scripts/package/builddeb +++ b/scripts/package/builddeb @@ -49,8 +49,10 @@ fi # Setup the directory structure rm -rf "$tmpdir" "$fwdir" -mkdir -p "$tmpdir/DEBIAN" "$tmpdir/lib" "$tmpdir/boot" "$tmpdir/usr/share/doc/$packagename" -mkdir -p "$fwdir/DEBIAN" "$fwdir/lib" "$fwdir/usr/share/doc/$fwpackagename" +mkdir -m 755 -p "$tmpdir/DEBIAN" +mkdir -p "$tmpdir/lib" "$tmpdir/boot" "$tmpdir/usr/share/doc/$packagename" +mkdir -m 755 -p "$fwdir/DEBIAN" +mkdir -p "$fwdir/lib" "$fwdir/usr/share/doc/$fwpackagename" if [ "$ARCH" = "um" ] ; then mkdir -p "$tmpdir/usr/lib/uml/modules/$version" "$tmpdir/usr/bin" fi -- cgit v1.2.3 From 7a30a3db34cc7b2180a1a6c4a51d19d93c8a8b80 Mon Sep 17 00:00:00 2001 From: Dimitris Papastamos Date: Thu, 11 Nov 2010 10:04:57 +0000 Subject: ASoC: soc-cache: Add support for flat register caching This patch introduces the new caching API and migrates the old caching interface into the new one. The flat register caching technique does not use compression at all and it is equivalent to the old caching technique. One can still access codec->reg_cache directly but this is not advised as that will not be portable across different caching strategies. None of the existing drivers need to be changed to adapt to this caching technique. There should be no noticeable overhead associated with using the new caching API. Signed-off-by: Dimitris Papastamos Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- include/sound/soc.h | 27 ++++ sound/soc/soc-cache.c | 339 +++++++++++++++++++++++++++++++++++++++++++++----- sound/soc/soc-core.c | 37 +++--- 3 files changed, 349 insertions(+), 54 deletions(-) diff --git a/include/sound/soc.h b/include/sound/soc.h index 5d3954774ade..275e41133468 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -238,6 +238,7 @@ struct soc_enum; struct snd_soc_ac97_ops; struct snd_soc_jack; struct snd_soc_jack_pin; +struct snd_soc_cache_ops; #include #ifdef CONFIG_GPIOLIB @@ -254,6 +255,10 @@ enum snd_soc_control_type { SND_SOC_SPI, }; +enum snd_soc_compress_type { + SND_SOC_NO_COMPRESSION +}; + int snd_soc_register_platform(struct device *dev, struct snd_soc_platform_driver *platform_drv); void snd_soc_unregister_platform(struct device *dev); @@ -265,6 +270,13 @@ int snd_soc_codec_volatile_register(struct snd_soc_codec *codec, int reg); int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec, int addr_bits, int data_bits, enum snd_soc_control_type control); +int snd_soc_cache_sync(struct snd_soc_codec *codec); +int snd_soc_cache_init(struct snd_soc_codec *codec); +int snd_soc_cache_exit(struct snd_soc_codec *codec); +int snd_soc_cache_write(struct snd_soc_codec *codec, + unsigned int reg, unsigned int value); +int snd_soc_cache_read(struct snd_soc_codec *codec, + unsigned int reg, unsigned int *value); /* Utility functions to get clock rates from various things */ int snd_soc_calc_frame_size(int sample_size, int channels, int tdm_slots); @@ -421,6 +433,18 @@ struct snd_soc_ops { int (*trigger)(struct snd_pcm_substream *, int); }; +/* SoC cache ops */ +struct snd_soc_cache_ops { + enum snd_soc_compress_type id; + int (*init)(struct snd_soc_codec *codec); + int (*exit)(struct snd_soc_codec *codec); + int (*read)(struct snd_soc_codec *codec, unsigned int reg, + unsigned int *value); + int (*write)(struct snd_soc_codec *codec, unsigned int reg, + unsigned int value); + int (*sync)(struct snd_soc_codec *codec); +}; + /* SoC Audio Codec device */ struct snd_soc_codec { const char *name; @@ -450,6 +474,8 @@ struct snd_soc_codec { hw_write_t hw_write; unsigned int (*hw_read)(struct snd_soc_codec *, unsigned int); void *reg_cache; + const struct snd_soc_cache_ops *cache_ops; + struct mutex cache_rw_mutex; /* dapm */ struct snd_soc_dapm_context dapm; @@ -482,6 +508,7 @@ struct snd_soc_codec_driver { short reg_cache_step; short reg_word_size; const void *reg_cache_default; + enum snd_soc_compress_type compress_type; /* codec bias level */ int (*set_bias_level)(struct snd_soc_codec *, diff --git a/sound/soc/soc-cache.c b/sound/soc/soc-cache.c index e7479988deca..cbf9694097b2 100644 --- a/sound/soc/soc-cache.c +++ b/sound/soc/soc-cache.c @@ -18,7 +18,8 @@ static unsigned int snd_soc_4_12_read(struct snd_soc_codec *codec, unsigned int reg) { - u16 *cache = codec->reg_cache; + int ret; + unsigned int val; if (reg >= codec->driver->reg_cache_size || snd_soc_codec_volatile_register(codec, reg)) { @@ -29,13 +30,15 @@ static unsigned int snd_soc_4_12_read(struct snd_soc_codec *codec, return codec->hw_read(codec, reg); } - return cache[reg]; + ret = snd_soc_cache_read(codec, reg, &val); + if (ret < 0) + return -1; + return val; } static int snd_soc_4_12_write(struct snd_soc_codec *codec, unsigned int reg, unsigned int value) { - u16 *cache = codec->reg_cache; u8 data[2]; int ret; @@ -43,8 +46,11 @@ static int snd_soc_4_12_write(struct snd_soc_codec *codec, unsigned int reg, data[1] = value & 0x00ff; if (!snd_soc_codec_volatile_register(codec, reg) && - reg < codec->driver->reg_cache_size) - cache[reg] = value; + reg < codec->driver->reg_cache_size) { + ret = snd_soc_cache_write(codec, reg, value); + if (ret < 0) + return -1; + } if (codec->cache_only) { codec->cache_sync = 1; @@ -93,7 +99,8 @@ static int snd_soc_4_12_spi_write(void *control_data, const char *data, static unsigned int snd_soc_7_9_read(struct snd_soc_codec *codec, unsigned int reg) { - u16 *cache = codec->reg_cache; + int ret; + unsigned int val; if (reg >= codec->driver->reg_cache_size || snd_soc_codec_volatile_register(codec, reg)) { @@ -104,13 +111,15 @@ static unsigned int snd_soc_7_9_read(struct snd_soc_codec *codec, return codec->hw_read(codec, reg); } - return cache[reg]; + ret = snd_soc_cache_read(codec, reg, &val); + if (ret < 0) + return -1; + return val; } static int snd_soc_7_9_write(struct snd_soc_codec *codec, unsigned int reg, unsigned int value) { - u16 *cache = codec->reg_cache; u8 data[2]; int ret; @@ -118,8 +127,11 @@ static int snd_soc_7_9_write(struct snd_soc_codec *codec, unsigned int reg, data[1] = value & 0x00ff; if (!snd_soc_codec_volatile_register(codec, reg) && - reg < codec->driver->reg_cache_size) - cache[reg] = value; + reg < codec->driver->reg_cache_size) { + ret = snd_soc_cache_write(codec, reg, value); + if (ret < 0) + return -1; + } if (codec->cache_only) { codec->cache_sync = 1; @@ -168,16 +180,19 @@ static int snd_soc_7_9_spi_write(void *control_data, const char *data, static int snd_soc_8_8_write(struct snd_soc_codec *codec, unsigned int reg, unsigned int value) { - u8 *cache = codec->reg_cache; u8 data[2]; + int ret; reg &= 0xff; data[0] = reg; data[1] = value & 0xff; if (!snd_soc_codec_volatile_register(codec, reg) && - reg < codec->driver->reg_cache_size) - cache[reg] = value; + reg < codec->driver->reg_cache_size) { + ret = snd_soc_cache_write(codec, reg, value); + if (ret < 0) + return -1; + } if (codec->cache_only) { codec->cache_sync = 1; @@ -193,7 +208,8 @@ static int snd_soc_8_8_write(struct snd_soc_codec *codec, unsigned int reg, static unsigned int snd_soc_8_8_read(struct snd_soc_codec *codec, unsigned int reg) { - u8 *cache = codec->reg_cache; + int ret; + unsigned int val; reg &= 0xff; if (reg >= codec->driver->reg_cache_size || @@ -205,7 +221,10 @@ static unsigned int snd_soc_8_8_read(struct snd_soc_codec *codec, return codec->hw_read(codec, reg); } - return cache[reg]; + ret = snd_soc_cache_read(codec, reg, &val); + if (ret < 0) + return -1; + return val; } #if defined(CONFIG_SPI_MASTER) @@ -241,16 +260,19 @@ static int snd_soc_8_8_spi_write(void *control_data, const char *data, static int snd_soc_8_16_write(struct snd_soc_codec *codec, unsigned int reg, unsigned int value) { - u16 *reg_cache = codec->reg_cache; u8 data[3]; + int ret; data[0] = reg; data[1] = (value >> 8) & 0xff; data[2] = value & 0xff; if (!snd_soc_codec_volatile_register(codec, reg) && - reg < codec->driver->reg_cache_size) - reg_cache[reg] = value; + reg < codec->driver->reg_cache_size) { + ret = snd_soc_cache_write(codec, reg, value); + if (ret < 0) + return -1; + } if (codec->cache_only) { codec->cache_sync = 1; @@ -266,7 +288,8 @@ static int snd_soc_8_16_write(struct snd_soc_codec *codec, unsigned int reg, static unsigned int snd_soc_8_16_read(struct snd_soc_codec *codec, unsigned int reg) { - u16 *cache = codec->reg_cache; + int ret; + unsigned int val; if (reg >= codec->driver->reg_cache_size || snd_soc_codec_volatile_register(codec, reg)) { @@ -275,9 +298,12 @@ static unsigned int snd_soc_8_16_read(struct snd_soc_codec *codec, BUG_ON(!codec->hw_read); return codec->hw_read(codec, reg); - } else { - return cache[reg]; } + + ret = snd_soc_cache_read(codec, reg, &val); + if (ret < 0) + return -1; + return val; } #if defined(CONFIG_SPI_MASTER) @@ -416,7 +442,8 @@ static unsigned int snd_soc_16_8_read_i2c(struct snd_soc_codec *codec, static unsigned int snd_soc_16_8_read(struct snd_soc_codec *codec, unsigned int reg) { - u8 *cache = codec->reg_cache; + int ret; + unsigned int val; reg &= 0xff; if (reg >= codec->driver->reg_cache_size || @@ -428,13 +455,15 @@ static unsigned int snd_soc_16_8_read(struct snd_soc_codec *codec, return codec->hw_read(codec, reg); } - return cache[reg]; + ret = snd_soc_cache_read(codec, reg, &val); + if (ret < 0) + return -1; + return val; } static int snd_soc_16_8_write(struct snd_soc_codec *codec, unsigned int reg, unsigned int value) { - u8 *cache = codec->reg_cache; u8 data[3]; int ret; @@ -444,8 +473,11 @@ static int snd_soc_16_8_write(struct snd_soc_codec *codec, unsigned int reg, reg &= 0xff; if (!snd_soc_codec_volatile_register(codec, reg) && - reg < codec->driver->reg_cache_size) - cache[reg] = value; + reg < codec->driver->reg_cache_size) { + ret = snd_soc_cache_write(codec, reg, value); + if (ret < 0) + return -1; + } if (codec->cache_only) { codec->cache_sync = 1; @@ -529,7 +561,8 @@ static unsigned int snd_soc_16_16_read_i2c(struct snd_soc_codec *codec, static unsigned int snd_soc_16_16_read(struct snd_soc_codec *codec, unsigned int reg) { - u16 *cache = codec->reg_cache; + int ret; + unsigned int val; if (reg >= codec->driver->reg_cache_size || snd_soc_codec_volatile_register(codec, reg)) { @@ -540,13 +573,16 @@ static unsigned int snd_soc_16_16_read(struct snd_soc_codec *codec, return codec->hw_read(codec, reg); } - return cache[reg]; + ret = snd_soc_cache_read(codec, reg, &val); + if (ret < 0) + return -1; + + return val; } static int snd_soc_16_16_write(struct snd_soc_codec *codec, unsigned int reg, unsigned int value) { - u16 *cache = codec->reg_cache; u8 data[4]; int ret; @@ -556,8 +592,11 @@ static int snd_soc_16_16_write(struct snd_soc_codec *codec, unsigned int reg, data[3] = value & 0xff; if (!snd_soc_codec_volatile_register(codec, reg) && - reg < codec->driver->reg_cache_size) - cache[reg] = value; + reg < codec->driver->reg_cache_size) { + ret = snd_soc_cache_write(codec, reg, value); + if (ret < 0) + return -1; + } if (codec->cache_only) { codec->cache_sync = 1; @@ -718,3 +757,241 @@ int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec, return 0; } EXPORT_SYMBOL_GPL(snd_soc_codec_set_cache_io); + +static int snd_soc_flat_cache_sync(struct snd_soc_codec *codec) +{ + int i; + struct snd_soc_codec_driver *codec_drv; + unsigned int val; + + codec_drv = codec->driver; + for (i = 0; i < codec_drv->reg_cache_size; ++i) { + snd_soc_cache_read(codec, i, &val); + if (codec_drv->reg_cache_default) { + switch (codec_drv->reg_word_size) { + case 1: { + const u8 *cache; + + cache = codec_drv->reg_cache_default; + if (cache[i] == val) + continue; + } + break; + case 2: { + const u16 *cache; + + cache = codec_drv->reg_cache_default; + if (cache[i] == val) + continue; + } + break; + default: + BUG(); + } + } + snd_soc_write(codec, i, val); + dev_dbg(codec->dev, "Synced register %#x, value = %#x\n", + i, val); + } + return 0; +} + +static int snd_soc_flat_cache_write(struct snd_soc_codec *codec, + unsigned int reg, unsigned int value) +{ + switch (codec->driver->reg_word_size) { + case 1: { + u8 *cache; + + cache = codec->reg_cache; + cache[reg] = value; + } + break; + case 2: { + u16 *cache; + + cache = codec->reg_cache; + cache[reg] = value; + } + break; + default: + BUG(); + } + + return 0; +} + +static int snd_soc_flat_cache_read(struct snd_soc_codec *codec, + unsigned int reg, unsigned int *value) +{ + switch (codec->driver->reg_word_size) { + case 1: { + u8 *cache; + + cache = codec->reg_cache; + *value = cache[reg]; + } + break; + case 2: { + u16 *cache; + + cache = codec->reg_cache; + *value = cache[reg]; + } + break; + default: + BUG(); + } + + return 0; +} + +static int snd_soc_flat_cache_exit(struct snd_soc_codec *codec) +{ + if (!codec->reg_cache) + return 0; + kfree(codec->reg_cache); + codec->reg_cache = NULL; + return 0; +} + +static int snd_soc_flat_cache_init(struct snd_soc_codec *codec) +{ + struct snd_soc_codec_driver *codec_drv; + size_t reg_size; + + codec_drv = codec->driver; + reg_size = codec_drv->reg_cache_size * codec_drv->reg_word_size; + + if (codec_drv->reg_cache_default) + codec->reg_cache = kmemdup(codec_drv->reg_cache_default, + reg_size, GFP_KERNEL); + else + codec->reg_cache = kzalloc(reg_size, GFP_KERNEL); + if (!codec->reg_cache) + return -ENOMEM; + + return 0; +} + +/* an array of all supported compression types */ +static const struct snd_soc_cache_ops cache_types[] = { + { + .id = SND_SOC_NO_COMPRESSION, + .init = snd_soc_flat_cache_init, + .exit = snd_soc_flat_cache_exit, + .read = snd_soc_flat_cache_read, + .write = snd_soc_flat_cache_write, + .sync = snd_soc_flat_cache_sync + } +}; + +int snd_soc_cache_init(struct snd_soc_codec *codec) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(cache_types); ++i) + if (cache_types[i].id == codec->driver->compress_type) + break; + if (i == ARRAY_SIZE(cache_types)) { + dev_err(codec->dev, "Could not match compress type: %d\n", + codec->driver->compress_type); + return -EINVAL; + } + + mutex_init(&codec->cache_rw_mutex); + codec->cache_ops = &cache_types[i]; + + if (codec->cache_ops->init) + return codec->cache_ops->init(codec); + return -EINVAL; +} + +/* + * NOTE: keep in mind that this function might be called + * multiple times. + */ +int snd_soc_cache_exit(struct snd_soc_codec *codec) +{ + if (codec->cache_ops && codec->cache_ops->exit) + return codec->cache_ops->exit(codec); + return -EINVAL; +} + +/** + * snd_soc_cache_read: Fetch the value of a given register from the cache. + * + * @codec: CODEC to configure. + * @reg: The register index. + * @value: The value to be returned. + */ +int snd_soc_cache_read(struct snd_soc_codec *codec, + unsigned int reg, unsigned int *value) +{ + int ret; + + mutex_lock(&codec->cache_rw_mutex); + + if (value && codec->cache_ops && codec->cache_ops->read) { + ret = codec->cache_ops->read(codec, reg, value); + mutex_unlock(&codec->cache_rw_mutex); + return ret; + } + + mutex_unlock(&codec->cache_rw_mutex); + return -EINVAL; +} +EXPORT_SYMBOL_GPL(snd_soc_cache_read); + +/** + * snd_soc_cache_write: Set the value of a given register in the cache. + * + * @codec: CODEC to configure. + * @reg: The register index. + * @value: The new register value. + */ +int snd_soc_cache_write(struct snd_soc_codec *codec, + unsigned int reg, unsigned int value) +{ + int ret; + + mutex_lock(&codec->cache_rw_mutex); + + if (codec->cache_ops && codec->cache_ops->write) { + ret = codec->cache_ops->write(codec, reg, value); + mutex_unlock(&codec->cache_rw_mutex); + return ret; + } + + mutex_unlock(&codec->cache_rw_mutex); + return -EINVAL; +} +EXPORT_SYMBOL_GPL(snd_soc_cache_write); + +/** + * snd_soc_cache_sync: Sync the register cache with the hardware. + * + * @codec: CODEC to configure. + * + * Any registers that should not be synced should be marked as + * volatile. In general drivers can choose not to use the provided + * syncing functionality if they so require. + */ +int snd_soc_cache_sync(struct snd_soc_codec *codec) +{ + int ret; + + if (!codec->cache_sync) { + return 0; + } + + if (codec->cache_ops && codec->cache_ops->sync) { + ret = codec->cache_ops->sync(codec); + if (!ret) + codec->cache_sync = 0; + return ret; + } + + return -EINVAL; +} +EXPORT_SYMBOL_GPL(snd_soc_cache_sync); diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 700a6d5b9721..3d70ce58d03c 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -3279,29 +3279,21 @@ int snd_soc_register_codec(struct device *dev, codec->dapm.bias_level = SND_SOC_BIAS_OFF; codec->dapm.dev = dev; codec->dapm.codec = codec; + codec->dev = dev; + codec->driver = codec_drv; + codec->num_dai = num_dai; + mutex_init(&codec->mutex); /* allocate CODEC register cache */ if (codec_drv->reg_cache_size && codec_drv->reg_word_size) { - - if (codec_drv->reg_cache_default) - codec->reg_cache = kmemdup(codec_drv->reg_cache_default, - codec_drv->reg_cache_size * codec_drv->reg_word_size, GFP_KERNEL); - else - codec->reg_cache = kzalloc(codec_drv->reg_cache_size * - codec_drv->reg_word_size, GFP_KERNEL); - - if (codec->reg_cache == NULL) { - kfree(codec->name); - kfree(codec); - return -ENOMEM; + ret = snd_soc_cache_init(codec); + if (ret < 0) { + dev_err(codec->dev, "Failed to set cache compression type: %d\n", + ret); + goto error_cache; } } - codec->dev = dev; - codec->driver = codec_drv; - codec->num_dai = num_dai; - mutex_init(&codec->mutex); - for (i = 0; i < num_dai; i++) { fixup_codec_formats(&dai_drv[i].playback); fixup_codec_formats(&dai_drv[i].capture); @@ -3311,7 +3303,7 @@ int snd_soc_register_codec(struct device *dev, if (num_dai) { ret = snd_soc_register_dais(dev, dai_drv, num_dai); if (ret < 0) - goto error; + goto error_dais; } mutex_lock(&client_mutex); @@ -3322,9 +3314,9 @@ int snd_soc_register_codec(struct device *dev, pr_debug("Registered codec '%s'\n", codec->name); return 0; -error: - if (codec->reg_cache) - kfree(codec->reg_cache); +error_dais: + snd_soc_cache_exit(codec); +error_cache: kfree(codec->name); kfree(codec); return ret; @@ -3358,8 +3350,7 @@ found: pr_debug("Unregistered codec '%s'\n", codec->name); - if (codec->reg_cache) - kfree(codec->reg_cache); + snd_soc_cache_exit(codec); kfree(codec->name); kfree(codec); } -- cgit v1.2.3 From cc28fb8e7d55d4d7c1661dc0b236f4faddecdd9e Mon Sep 17 00:00:00 2001 From: Dimitris Papastamos Date: Thu, 11 Nov 2010 10:04:58 +0000 Subject: ASoC: soc-cache: Add support for LZO register caching This patch adds support for LZO compression when storing the register cache. The initial register defaults cache is marked as __devinitconst and the only change required for a driver to use LZO compression is to set the compress_type member in codec->driver to SND_SOC_LZO_COMPRESSION. For a typical device whose register map would normally occupy 25kB or 50kB by using the LZO compression technique, one can get down to ~5-7kB. There might be a performance penalty associated with each individual read/write due to decompressing/compressing the underlying cache, however that should not be noticeable. These memory benefits depend on whether the target architecture can get rid of the memory occupied by the original register defaults cache which is marked as __devinitconst. Nevertheless there will be some memory gain even if the target architecture can't get rid of the original register map, this should be around ~30-32kB instead of 50kB. Signed-off-by: Dimitris Papastamos Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- include/sound/soc.h | 3 +- sound/soc/Kconfig | 2 + sound/soc/soc-cache.c | 413 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 417 insertions(+), 1 deletion(-) diff --git a/include/sound/soc.h b/include/sound/soc.h index 275e41133468..10f5932d3d07 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -256,7 +256,8 @@ enum snd_soc_control_type { }; enum snd_soc_compress_type { - SND_SOC_NO_COMPRESSION + SND_SOC_NO_COMPRESSION, + SND_SOC_LZO_COMPRESSION }; int snd_soc_register_platform(struct device *dev, diff --git a/sound/soc/Kconfig b/sound/soc/Kconfig index 3e598e756e54..4562c898a7ef 100644 --- a/sound/soc/Kconfig +++ b/sound/soc/Kconfig @@ -4,6 +4,8 @@ menuconfig SND_SOC tristate "ALSA for SoC audio support" + select LZO_COMPRESS + select LZO_DECOMPRESS select SND_PCM select AC97_BUS if SND_SOC_AC97_BUS select SND_JACK if INPUT=y || INPUT=SND diff --git a/sound/soc/soc-cache.c b/sound/soc/soc-cache.c index cbf9694097b2..4581bf100222 100644 --- a/sound/soc/soc-cache.c +++ b/sound/soc/soc-cache.c @@ -14,6 +14,8 @@ #include #include #include +#include +#include static unsigned int snd_soc_4_12_read(struct snd_soc_codec *codec, unsigned int reg) @@ -758,6 +760,409 @@ int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec, } EXPORT_SYMBOL_GPL(snd_soc_codec_set_cache_io); +struct snd_soc_lzo_ctx { + void *wmem; + void *dst; + const void *src; + size_t src_len; + size_t dst_len; + size_t decompressed_size; + unsigned long *sync_bmp; + int sync_bmp_nbits; +}; + +#define LZO_BLOCK_NUM 8 +static int snd_soc_lzo_block_count(void) +{ + return LZO_BLOCK_NUM; +} + +static int snd_soc_lzo_prepare(struct snd_soc_lzo_ctx *lzo_ctx) +{ + lzo_ctx->wmem = kmalloc(LZO1X_MEM_COMPRESS, GFP_KERNEL); + if (!lzo_ctx->wmem) + return -ENOMEM; + return 0; +} + +static int snd_soc_lzo_compress(struct snd_soc_lzo_ctx *lzo_ctx) +{ + size_t compress_size; + int ret; + + ret = lzo1x_1_compress(lzo_ctx->src, lzo_ctx->src_len, + lzo_ctx->dst, &compress_size, lzo_ctx->wmem); + if (ret != LZO_E_OK || compress_size > lzo_ctx->dst_len) + return -EINVAL; + lzo_ctx->dst_len = compress_size; + return 0; +} + +static int snd_soc_lzo_decompress(struct snd_soc_lzo_ctx *lzo_ctx) +{ + size_t dst_len; + int ret; + + dst_len = lzo_ctx->dst_len; + ret = lzo1x_decompress_safe(lzo_ctx->src, lzo_ctx->src_len, + lzo_ctx->dst, &dst_len); + if (ret != LZO_E_OK || dst_len != lzo_ctx->dst_len) + return -EINVAL; + return 0; +} + +static int snd_soc_lzo_compress_cache_block(struct snd_soc_codec *codec, + struct snd_soc_lzo_ctx *lzo_ctx) +{ + int ret; + + lzo_ctx->dst_len = lzo1x_worst_compress(PAGE_SIZE); + lzo_ctx->dst = kmalloc(lzo_ctx->dst_len, GFP_KERNEL); + if (!lzo_ctx->dst) { + lzo_ctx->dst_len = 0; + return -ENOMEM; + } + + ret = snd_soc_lzo_compress(lzo_ctx); + if (ret < 0) + return ret; + return 0; +} + +static int snd_soc_lzo_decompress_cache_block(struct snd_soc_codec *codec, + struct snd_soc_lzo_ctx *lzo_ctx) +{ + int ret; + + lzo_ctx->dst_len = lzo_ctx->decompressed_size; + lzo_ctx->dst = kmalloc(lzo_ctx->dst_len, GFP_KERNEL); + if (!lzo_ctx->dst) { + lzo_ctx->dst_len = 0; + return -ENOMEM; + } + + ret = snd_soc_lzo_decompress(lzo_ctx); + if (ret < 0) + return ret; + return 0; +} + +static inline int snd_soc_lzo_get_blkindex(struct snd_soc_codec *codec, + unsigned int reg) +{ + struct snd_soc_codec_driver *codec_drv; + size_t reg_size; + + codec_drv = codec->driver; + reg_size = codec_drv->reg_cache_size * codec_drv->reg_word_size; + return (reg * codec_drv->reg_word_size) / + DIV_ROUND_UP(reg_size, snd_soc_lzo_block_count()); +} + +static inline int snd_soc_lzo_get_blkpos(struct snd_soc_codec *codec, + unsigned int reg) +{ + struct snd_soc_codec_driver *codec_drv; + size_t reg_size; + + codec_drv = codec->driver; + reg_size = codec_drv->reg_cache_size * codec_drv->reg_word_size; + return reg % (DIV_ROUND_UP(reg_size, snd_soc_lzo_block_count()) / + codec_drv->reg_word_size); +} + +static inline int snd_soc_lzo_get_blksize(struct snd_soc_codec *codec) +{ + struct snd_soc_codec_driver *codec_drv; + size_t reg_size; + + codec_drv = codec->driver; + reg_size = codec_drv->reg_cache_size * codec_drv->reg_word_size; + return DIV_ROUND_UP(reg_size, snd_soc_lzo_block_count()); +} + +static int snd_soc_lzo_cache_sync(struct snd_soc_codec *codec) +{ + struct snd_soc_lzo_ctx **lzo_blocks; + unsigned int val; + int i; + + lzo_blocks = codec->reg_cache; + for_each_set_bit(i, lzo_blocks[0]->sync_bmp, lzo_blocks[0]->sync_bmp_nbits) { + snd_soc_cache_read(codec, i, &val); + snd_soc_write(codec, i, val); + dev_dbg(codec->dev, "Synced register %#x, value = %#x\n", + i, val); + } + + return 0; +} + +static int snd_soc_lzo_cache_write(struct snd_soc_codec *codec, + unsigned int reg, unsigned int value) +{ + struct snd_soc_lzo_ctx *lzo_block, **lzo_blocks; + int ret, blkindex, blkpos; + size_t blksize, tmp_dst_len; + void *tmp_dst; + + /* index of the compressed lzo block */ + blkindex = snd_soc_lzo_get_blkindex(codec, reg); + /* register index within the decompressed block */ + blkpos = snd_soc_lzo_get_blkpos(codec, reg); + /* size of the compressed block */ + blksize = snd_soc_lzo_get_blksize(codec); + lzo_blocks = codec->reg_cache; + lzo_block = lzo_blocks[blkindex]; + + /* save the pointer and length of the compressed block */ + tmp_dst = lzo_block->dst; + tmp_dst_len = lzo_block->dst_len; + + /* prepare the source to be the compressed block */ + lzo_block->src = lzo_block->dst; + lzo_block->src_len = lzo_block->dst_len; + + /* decompress the block */ + ret = snd_soc_lzo_decompress_cache_block(codec, lzo_block); + if (ret < 0) { + kfree(lzo_block->dst); + goto out; + } + + /* write the new value to the cache */ + switch (codec->driver->reg_word_size) { + case 1: { + u8 *cache; + cache = lzo_block->dst; + if (cache[blkpos] == value) { + kfree(lzo_block->dst); + goto out; + } + cache[blkpos] = value; + } + break; + case 2: { + u16 *cache; + cache = lzo_block->dst; + if (cache[blkpos] == value) { + kfree(lzo_block->dst); + goto out; + } + cache[blkpos] = value; + } + break; + default: + BUG(); + } + + /* prepare the source to be the decompressed block */ + lzo_block->src = lzo_block->dst; + lzo_block->src_len = lzo_block->dst_len; + + /* compress the block */ + ret = snd_soc_lzo_compress_cache_block(codec, lzo_block); + if (ret < 0) { + kfree(lzo_block->dst); + kfree(lzo_block->src); + goto out; + } + + /* set the bit so we know we have to sync this register */ + set_bit(reg, lzo_block->sync_bmp); + kfree(tmp_dst); + kfree(lzo_block->src); + return 0; +out: + lzo_block->dst = tmp_dst; + lzo_block->dst_len = tmp_dst_len; + return ret; +} + +static int snd_soc_lzo_cache_read(struct snd_soc_codec *codec, + unsigned int reg, unsigned int *value) +{ + struct snd_soc_lzo_ctx *lzo_block, **lzo_blocks; + int ret, blkindex, blkpos; + size_t blksize, tmp_dst_len; + void *tmp_dst; + + *value = 0; + /* index of the compressed lzo block */ + blkindex = snd_soc_lzo_get_blkindex(codec, reg); + /* register index within the decompressed block */ + blkpos = snd_soc_lzo_get_blkpos(codec, reg); + /* size of the compressed block */ + blksize = snd_soc_lzo_get_blksize(codec); + lzo_blocks = codec->reg_cache; + lzo_block = lzo_blocks[blkindex]; + + /* save the pointer and length of the compressed block */ + tmp_dst = lzo_block->dst; + tmp_dst_len = lzo_block->dst_len; + + /* prepare the source to be the compressed block */ + lzo_block->src = lzo_block->dst; + lzo_block->src_len = lzo_block->dst_len; + + /* decompress the block */ + ret = snd_soc_lzo_decompress_cache_block(codec, lzo_block); + if (ret >= 0) { + /* fetch the value from the cache */ + switch (codec->driver->reg_word_size) { + case 1: { + u8 *cache; + cache = lzo_block->dst; + *value = cache[blkpos]; + } + break; + case 2: { + u16 *cache; + cache = lzo_block->dst; + *value = cache[blkpos]; + } + break; + default: + BUG(); + } + } + + kfree(lzo_block->dst); + /* restore the pointer and length of the compressed block */ + lzo_block->dst = tmp_dst; + lzo_block->dst_len = tmp_dst_len; + return 0; +} + +static int snd_soc_lzo_cache_exit(struct snd_soc_codec *codec) +{ + struct snd_soc_lzo_ctx **lzo_blocks; + int i, blkcount; + + lzo_blocks = codec->reg_cache; + if (!lzo_blocks) + return 0; + + blkcount = snd_soc_lzo_block_count(); + /* + * the pointer to the bitmap used for syncing the cache + * is shared amongst all lzo_blocks. Ensure it is freed + * only once. + */ + if (lzo_blocks[0]) + kfree(lzo_blocks[0]->sync_bmp); + for (i = 0; i < blkcount; ++i) { + if (lzo_blocks[i]) { + kfree(lzo_blocks[i]->wmem); + kfree(lzo_blocks[i]->dst); + } + /* each lzo_block is a pointer returned by kmalloc or NULL */ + kfree(lzo_blocks[i]); + } + kfree(lzo_blocks); + codec->reg_cache = NULL; + return 0; +} + +static int snd_soc_lzo_cache_init(struct snd_soc_codec *codec) +{ + struct snd_soc_lzo_ctx **lzo_blocks; + size_t reg_size, bmp_size; + struct snd_soc_codec_driver *codec_drv; + int ret, tofree, i, blksize, blkcount; + const char *p, *end; + unsigned long *sync_bmp; + + ret = 0; + codec_drv = codec->driver; + reg_size = codec_drv->reg_cache_size * codec_drv->reg_word_size; + + /* + * If we have not been given a default register cache + * then allocate a dummy zero-ed out region, compress it + * and remember to free it afterwards. + */ + tofree = 0; + if (!codec_drv->reg_cache_default) + tofree = 1; + + if (!codec_drv->reg_cache_default) { + codec_drv->reg_cache_default = kzalloc(reg_size, + GFP_KERNEL); + if (!codec_drv->reg_cache_default) + return -ENOMEM; + } + + blkcount = snd_soc_lzo_block_count(); + codec->reg_cache = kzalloc(blkcount * sizeof *lzo_blocks, + GFP_KERNEL); + if (!codec->reg_cache) { + ret = -ENOMEM; + goto err_tofree; + } + lzo_blocks = codec->reg_cache; + + /* + * allocate a bitmap to be used when syncing the cache with + * the hardware. Each time a register is modified, the corresponding + * bit is set in the bitmap, so we know that we have to sync + * that register. + */ + bmp_size = codec_drv->reg_cache_size; + sync_bmp = kmalloc(BITS_TO_LONGS(bmp_size) * sizeof (long), + GFP_KERNEL); + if (!sync_bmp) { + ret = -ENOMEM; + goto err; + } + bitmap_zero(sync_bmp, reg_size); + + /* allocate the lzo blocks and initialize them */ + for (i = 0; i < blkcount; ++i) { + lzo_blocks[i] = kzalloc(sizeof **lzo_blocks, + GFP_KERNEL); + if (!lzo_blocks[i]) { + kfree(sync_bmp); + ret = -ENOMEM; + goto err; + } + lzo_blocks[i]->sync_bmp = sync_bmp; + lzo_blocks[i]->sync_bmp_nbits = reg_size; + /* alloc the working space for the compressed block */ + ret = snd_soc_lzo_prepare(lzo_blocks[i]); + if (ret < 0) + goto err; + } + + blksize = snd_soc_lzo_get_blksize(codec); + p = codec_drv->reg_cache_default; + end = codec_drv->reg_cache_default + reg_size; + /* compress the register map and fill the lzo blocks */ + for (i = 0; i < blkcount; ++i, p += blksize) { + lzo_blocks[i]->src = p; + if (p + blksize > end) + lzo_blocks[i]->src_len = end - p; + else + lzo_blocks[i]->src_len = blksize; + ret = snd_soc_lzo_compress_cache_block(codec, + lzo_blocks[i]); + if (ret < 0) + goto err; + lzo_blocks[i]->decompressed_size = + lzo_blocks[i]->src_len; + } + + if (tofree) + kfree(codec_drv->reg_cache_default); + return 0; +err: + snd_soc_cache_exit(codec); +err_tofree: + if (tofree) + kfree(codec_drv->reg_cache_default); + return ret; +} + static int snd_soc_flat_cache_sync(struct snd_soc_codec *codec) { int i; @@ -883,6 +1288,14 @@ static const struct snd_soc_cache_ops cache_types[] = { .read = snd_soc_flat_cache_read, .write = snd_soc_flat_cache_write, .sync = snd_soc_flat_cache_sync + }, + { + .id = SND_SOC_LZO_COMPRESSION, + .init = snd_soc_lzo_cache_init, + .exit = snd_soc_lzo_cache_exit, + .read = snd_soc_lzo_cache_read, + .write = snd_soc_lzo_cache_write, + .sync = snd_soc_lzo_cache_sync } }; -- cgit v1.2.3 From a7f387d5afd5e1102f909ab611370014f1f59ae2 Mon Sep 17 00:00:00 2001 From: Dimitris Papastamos Date: Thu, 11 Nov 2010 10:04:59 +0000 Subject: ASoC: soc-cache: Add support for rbtree based register caching This patch adds support for rbtree compression when storing the register cache. It does this by not adding any uninitialized registers (those whose value is 0). If any of those registers is written with a nonzero value they get added into the rbtree. Consider a sample device with a large sparse register map. The register indices are between [0, 0x31ff]. An array of 12800 registers is thus created each of which is 2 bytes. This results in a 25kB region. This array normally lives outside soc-core, normally in the driver itself. The original soc-core code would kmemdup this region resulting in 50kB total memory. When using the rbtree compression technique and __devinitconst on the original array the figures are as follows. For this typical device, you might have 100 initialized registers, that is registers that are nonzero by default. We build an rbtree with 100 nodes, each of which is 24 bytes. This results in ~2kB of memory. Assuming that the target arch can freeup the memory used by the initial __devinitconst array, we end up using about ~2kB bytes of actual memory. The memory footprint will increase as uninitialized registers get written and thus new nodes created in the rbtree. In practice, most of those registers are never changed. If the target arch can't freeup the __devinitconst array, we end up using a total of ~27kB. The difference between the rbtree and the LZO caching techniques, is that if using the LZO technique the size of the cache will increase slower as more uninitialized registers get changed. Signed-off-by: Dimitris Papastamos Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- include/sound/soc.h | 3 +- sound/soc/soc-cache.c | 232 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 234 insertions(+), 1 deletion(-) diff --git a/include/sound/soc.h b/include/sound/soc.h index 10f5932d3d07..af23f4228869 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -257,7 +257,8 @@ enum snd_soc_control_type { enum snd_soc_compress_type { SND_SOC_NO_COMPRESSION, - SND_SOC_LZO_COMPRESSION + SND_SOC_LZO_COMPRESSION, + SND_SOC_RBTREE_COMPRESSION }; int snd_soc_register_platform(struct device *dev, diff --git a/sound/soc/soc-cache.c b/sound/soc/soc-cache.c index 4581bf100222..6c0589e3fefb 100644 --- a/sound/soc/soc-cache.c +++ b/sound/soc/soc-cache.c @@ -16,6 +16,7 @@ #include #include #include +#include static unsigned int snd_soc_4_12_read(struct snd_soc_codec *codec, unsigned int reg) @@ -760,6 +761,229 @@ int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec, } EXPORT_SYMBOL_GPL(snd_soc_codec_set_cache_io); +struct snd_soc_rbtree_node { + struct rb_node node; + unsigned int reg; + unsigned int value; + unsigned int defval; +} __attribute__ ((packed)); + +struct snd_soc_rbtree_ctx { + struct rb_root root; +}; + +static struct snd_soc_rbtree_node *snd_soc_rbtree_lookup( + struct rb_root *root, unsigned int reg) +{ + struct rb_node *node; + struct snd_soc_rbtree_node *rbnode; + + node = root->rb_node; + while (node) { + rbnode = container_of(node, struct snd_soc_rbtree_node, node); + if (rbnode->reg < reg) + node = node->rb_left; + else if (rbnode->reg > reg) + node = node->rb_right; + else + return rbnode; + } + + return NULL; +} + + +static int snd_soc_rbtree_insert(struct rb_root *root, + struct snd_soc_rbtree_node *rbnode) +{ + struct rb_node **new, *parent; + struct snd_soc_rbtree_node *rbnode_tmp; + + parent = NULL; + new = &root->rb_node; + while (*new) { + rbnode_tmp = container_of(*new, struct snd_soc_rbtree_node, + node); + parent = *new; + if (rbnode_tmp->reg < rbnode->reg) + new = &((*new)->rb_left); + else if (rbnode_tmp->reg > rbnode->reg) + new = &((*new)->rb_right); + else + return 0; + } + + /* insert the node into the rbtree */ + rb_link_node(&rbnode->node, parent, new); + rb_insert_color(&rbnode->node, root); + + return 1; +} + +static int snd_soc_rbtree_cache_sync(struct snd_soc_codec *codec) +{ + struct snd_soc_rbtree_ctx *rbtree_ctx; + struct rb_node *node; + struct snd_soc_rbtree_node *rbnode; + unsigned int val; + + rbtree_ctx = codec->reg_cache; + for (node = rb_first(&rbtree_ctx->root); node; node = rb_next(node)) { + rbnode = rb_entry(node, struct snd_soc_rbtree_node, node); + if (rbnode->value == rbnode->defval) + continue; + snd_soc_cache_read(codec, rbnode->reg, &val); + snd_soc_write(codec, rbnode->reg, val); + dev_dbg(codec->dev, "Synced register %#x, value = %#x\n", + rbnode->reg, val); + } + + return 0; +} + +static int snd_soc_rbtree_cache_write(struct snd_soc_codec *codec, + unsigned int reg, unsigned int value) +{ + struct snd_soc_rbtree_ctx *rbtree_ctx; + struct snd_soc_rbtree_node *rbnode; + + rbtree_ctx = codec->reg_cache; + rbnode = snd_soc_rbtree_lookup(&rbtree_ctx->root, reg); + if (rbnode) { + if (rbnode->value == value) + return 0; + rbnode->value = value; + } else { + /* bail out early, no need to create the rbnode yet */ + if (!value) + return 0; + /* + * for uninitialized registers whose value is changed + * from the default zero, create an rbnode and insert + * it into the tree. + */ + rbnode = kzalloc(sizeof *rbnode, GFP_KERNEL); + if (!rbnode) + return -ENOMEM; + rbnode->reg = reg; + rbnode->value = value; + snd_soc_rbtree_insert(&rbtree_ctx->root, rbnode); + } + + return 0; +} + +static int snd_soc_rbtree_cache_read(struct snd_soc_codec *codec, + unsigned int reg, unsigned int *value) +{ + struct snd_soc_rbtree_ctx *rbtree_ctx; + struct snd_soc_rbtree_node *rbnode; + + rbtree_ctx = codec->reg_cache; + rbnode = snd_soc_rbtree_lookup(&rbtree_ctx->root, reg); + if (rbnode) { + *value = rbnode->value; + } else { + /* uninitialized registers default to 0 */ + *value = 0; + } + + return 0; +} + +static int snd_soc_rbtree_cache_exit(struct snd_soc_codec *codec) +{ + struct rb_node *next; + struct snd_soc_rbtree_ctx *rbtree_ctx; + struct snd_soc_rbtree_node *rbtree_node; + + /* if we've already been called then just return */ + rbtree_ctx = codec->reg_cache; + if (!rbtree_ctx) + return 0; + + /* free up the rbtree */ + next = rb_first(&rbtree_ctx->root); + while (next) { + rbtree_node = rb_entry(next, struct snd_soc_rbtree_node, node); + next = rb_next(&rbtree_node->node); + rb_erase(&rbtree_node->node, &rbtree_ctx->root); + kfree(rbtree_node); + } + + /* release the resources */ + kfree(codec->reg_cache); + codec->reg_cache = NULL; + + return 0; +} + +static int snd_soc_rbtree_cache_init(struct snd_soc_codec *codec) +{ + struct snd_soc_rbtree_ctx *rbtree_ctx; + + codec->reg_cache = kmalloc(sizeof *rbtree_ctx, GFP_KERNEL); + if (!codec->reg_cache) + return -ENOMEM; + + rbtree_ctx = codec->reg_cache; + rbtree_ctx->root = RB_ROOT; + + if (!codec->driver->reg_cache_default) + return 0; + +/* + * populate the rbtree with the initialized registers. All other + * registers will be inserted into the tree when they are first written. + * + * The reasoning behind this, is that we need to step through and + * dereference the cache in u8/u16 increments without sacrificing + * portability. This could also be done using memcpy() but that would + * be slightly more cryptic. + */ +#define snd_soc_rbtree_populate(cache) \ +({ \ + int ret, i; \ + struct snd_soc_rbtree_node *rbtree_node; \ + \ + ret = 0; \ + cache = codec->driver->reg_cache_default; \ + for (i = 0; i < codec->driver->reg_cache_size; ++i) { \ + if (!cache[i]) \ + continue; \ + rbtree_node = kzalloc(sizeof *rbtree_node, GFP_KERNEL); \ + if (!rbtree_node) { \ + ret = -ENOMEM; \ + snd_soc_cache_exit(codec); \ + break; \ + } \ + rbtree_node->reg = i; \ + rbtree_node->value = cache[i]; \ + rbtree_node->defval = cache[i]; \ + snd_soc_rbtree_insert(&rbtree_ctx->root, \ + rbtree_node); \ + } \ + ret; \ +}) + + switch (codec->driver->reg_word_size) { + case 1: { + const u8 *cache; + + return snd_soc_rbtree_populate(cache); + } + case 2: { + const u16 *cache; + + return snd_soc_rbtree_populate(cache); + } + default: + BUG(); + } + + return 0; +} + struct snd_soc_lzo_ctx { void *wmem; void *dst; @@ -1296,6 +1520,14 @@ static const struct snd_soc_cache_ops cache_types[] = { .read = snd_soc_lzo_cache_read, .write = snd_soc_lzo_cache_write, .sync = snd_soc_lzo_cache_sync + }, + { + .id = SND_SOC_RBTREE_COMPRESSION, + .init = snd_soc_rbtree_cache_init, + .exit = snd_soc_rbtree_cache_exit, + .read = snd_soc_rbtree_cache_read, + .write = snd_soc_rbtree_cache_write, + .sync = snd_soc_rbtree_cache_sync } }; -- cgit v1.2.3 From 8af27e1dc4e4dd7a7b04c2cd0fc3d419d91d45b0 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Tue, 9 Nov 2010 16:29:27 +0100 Subject: fixdep: use hash table instead of a single array I noticed fixdep uses ~2% of cpu time in kernel build, in function use_config() fixdep spends a lot of cpu cycles in linear searches in its internal string array. With about 400 stored strings per dep file, this begins to be noticeable. Convert fixdep to use a hash table. kbuild results on my x86_64 allmodconfig Before patch : real 10m30.414s user 61m51.456s sys 8m28.200s real 10m12.334s user 61m50.236s sys 8m30.448s real 10m42.947s user 61m50.028s sys 8m32.380s After: real 10m8.180s user 61m22.506s sys 8m32.384s real 10m35.039s user 61m21.654s sys 8m32.212s real 10m14.487s user 61m23.498s sys 8m32.312s Signed-off-by: Eric Dumazet Signed-off-by: Michal Marek --- scripts/basic/fixdep.c | 109 +++++++++++++++++++++++++++---------------------- 1 file changed, 61 insertions(+), 48 deletions(-) diff --git a/scripts/basic/fixdep.c b/scripts/basic/fixdep.c index ea26b23de082..ed0584623690 100644 --- a/scripts/basic/fixdep.c +++ b/scripts/basic/fixdep.c @@ -138,38 +138,36 @@ static void print_cmdline(void) printf("cmd_%s := %s\n\n", target, cmdline); } -char * str_config = NULL; -int size_config = 0; -int len_config = 0; +struct item { + struct item *next; + unsigned int len; + unsigned int hash; + char name[0]; +}; -/* - * Grow the configuration string to a desired length. - * Usually the first growth is plenty. - */ -static void grow_config(int len) -{ - while (len_config + len > size_config) { - if (size_config == 0) - size_config = 2048; - str_config = realloc(str_config, size_config *= 2); - if (str_config == NULL) - { perror("fixdep:malloc"); exit(1); } - } -} +#define HASHSZ 256 +static struct item *hashtab[HASHSZ]; +static unsigned int strhash(const char *str, unsigned int sz) +{ + /* fnv32 hash */ + unsigned int i, hash = 2166136261U; + for (i = 0; i < sz; i++) + hash = (hash ^ str[i]) * 0x01000193; + return hash; +} /* * Lookup a value in the configuration string. */ -static int is_defined_config(const char * name, int len) +static int is_defined_config(const char *name, int len, unsigned int hash) { - const char * pconfig; - const char * plast = str_config + len_config - len; - for ( pconfig = str_config + 1; pconfig < plast; pconfig++ ) { - if (pconfig[ -1] == '\n' - && pconfig[len] == '\n' - && !memcmp(pconfig, name, len)) + struct item *aux; + + for (aux = hashtab[hash % HASHSZ]; aux; aux = aux->next) { + if (aux->hash == hash && aux->len == len && + memcmp(aux->name, name, len) == 0) return 1; } return 0; @@ -178,13 +176,19 @@ static int is_defined_config(const char * name, int len) /* * Add a new value to the configuration string. */ -static void define_config(const char * name, int len) +static void define_config(const char *name, int len, unsigned int hash) { - grow_config(len + 1); + struct item *aux = malloc(sizeof(*aux) + len); - memcpy(str_config+len_config, name, len); - len_config += len; - str_config[len_config++] = '\n'; + if (!aux) { + perror("fixdep:malloc"); + exit(1); + } + memcpy(aux->name, name, len); + aux->len = len; + aux->hash = hash; + aux->next = hashtab[hash % HASHSZ]; + hashtab[hash % HASHSZ] = aux; } /* @@ -192,40 +196,49 @@ static void define_config(const char * name, int len) */ static void clear_config(void) { - len_config = 0; - define_config("", 0); + struct item *aux, *next; + unsigned int i; + + for (i = 0; i < HASHSZ; i++) { + for (aux = hashtab[i]; aux; aux = next) { + next = aux->next; + free(aux); + } + hashtab[i] = NULL; + } } /* * Record the use of a CONFIG_* word. */ -static void use_config(char *m, int slen) +static void use_config(const char *m, int slen) { - char s[PATH_MAX]; - char *p; + unsigned int hash = strhash(m, slen); + int c, i; - if (is_defined_config(m, slen)) + if (is_defined_config(m, slen, hash)) return; - define_config(m, slen); - - memcpy(s, m, slen); s[slen] = 0; + define_config(m, slen, hash); - for (p = s; p < s + slen; p++) { - if (*p == '_') - *p = '/'; + printf(" $(wildcard include/config/"); + for (i = 0; i < slen; i++) { + c = m[i]; + if (c == '_') + c = '/'; else - *p = tolower((int)*p); + c = tolower(c); + putchar(c); } - printf(" $(wildcard include/config/%s.h) \\\n", s); + printf(".h) \\\n"); } -static void parse_config_file(char *map, size_t len) +static void parse_config_file(const char *map, size_t len) { - int *end = (int *) (map + len); + const int *end = (const int *) (map + len); /* start at +1, so that p can never be < map */ - int *m = (int *) map + 1; - char *p, *q; + const int *m = (const int *) map + 1; + const char *p, *q; for (; m < end; m++) { if (*m == INT_CONF) { p = (char *) m ; goto conf; } @@ -265,7 +278,7 @@ static int strrcmp(char *s, char *sub) return memcmp(s + slen - sublen, sub, sublen); } -static void do_config_file(char *filename) +static void do_config_file(const char *filename) { struct stat st; int fd; -- cgit v1.2.3 From cae5852dcaa1139b198e13ebd3aeb7f3c065f875 Mon Sep 17 00:00:00 2001 From: Zou Nan hai Date: Tue, 9 Nov 2010 17:17:32 +0800 Subject: drm/i915/ringbuffer: set FORCE_WAKE bit before reading ring register Before reading ring register, set FORCE_WAKE bit to prevent GT core power down to low power state, otherwise we may read stale values. Signed-off-by: Zou Nan hai [ickle: added a udelay which seemed to do the trick on my SNB] Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_drv.h | 176 +++++++++++++++++--------------- drivers/gpu/drm/i915/i915_reg.h | 1 + drivers/gpu/drm/i915/intel_ringbuffer.c | 2 +- drivers/gpu/drm/i915/intel_ringbuffer.h | 13 ++- 4 files changed, 106 insertions(+), 86 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 30d7a7bc6f2e..ecf12f9de1e0 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -876,6 +876,67 @@ enum intel_chip_family { CHIP_I965 = 0x08, }; +#define INTEL_INFO(dev) (((struct drm_i915_private *) (dev)->dev_private)->info) + +#define IS_I830(dev) ((dev)->pci_device == 0x3577) +#define IS_845G(dev) ((dev)->pci_device == 0x2562) +#define IS_I85X(dev) (INTEL_INFO(dev)->is_i85x) +#define IS_I865G(dev) ((dev)->pci_device == 0x2572) +#define IS_I915G(dev) (INTEL_INFO(dev)->is_i915g) +#define IS_I915GM(dev) ((dev)->pci_device == 0x2592) +#define IS_I945G(dev) ((dev)->pci_device == 0x2772) +#define IS_I945GM(dev) (INTEL_INFO(dev)->is_i945gm) +#define IS_BROADWATER(dev) (INTEL_INFO(dev)->is_broadwater) +#define IS_CRESTLINE(dev) (INTEL_INFO(dev)->is_crestline) +#define IS_GM45(dev) ((dev)->pci_device == 0x2A42) +#define IS_G4X(dev) (INTEL_INFO(dev)->is_g4x) +#define IS_PINEVIEW_G(dev) ((dev)->pci_device == 0xa001) +#define IS_PINEVIEW_M(dev) ((dev)->pci_device == 0xa011) +#define IS_PINEVIEW(dev) (INTEL_INFO(dev)->is_pineview) +#define IS_G33(dev) (INTEL_INFO(dev)->is_g33) +#define IS_IRONLAKE_D(dev) ((dev)->pci_device == 0x0042) +#define IS_IRONLAKE_M(dev) ((dev)->pci_device == 0x0046) +#define IS_MOBILE(dev) (INTEL_INFO(dev)->is_mobile) + +#define IS_GEN2(dev) (INTEL_INFO(dev)->gen == 2) +#define IS_GEN3(dev) (INTEL_INFO(dev)->gen == 3) +#define IS_GEN4(dev) (INTEL_INFO(dev)->gen == 4) +#define IS_GEN5(dev) (INTEL_INFO(dev)->gen == 5) +#define IS_GEN6(dev) (INTEL_INFO(dev)->gen == 6) + +#define HAS_BSD(dev) (INTEL_INFO(dev)->has_bsd_ring) +#define HAS_BLT(dev) (INTEL_INFO(dev)->has_blt_ring) +#define I915_NEED_GFX_HWS(dev) (INTEL_INFO(dev)->need_gfx_hws) + +#define HAS_OVERLAY(dev) (INTEL_INFO(dev)->has_overlay) +#define OVERLAY_NEEDS_PHYSICAL(dev) (INTEL_INFO(dev)->overlay_needs_physical) + +/* With the 945 and later, Y tiling got adjusted so that it was 32 128-byte + * rows, which changed the alignment requirements and fence programming. + */ +#define HAS_128_BYTE_Y_TILING(dev) (!IS_GEN2(dev) && !(IS_I915G(dev) || \ + IS_I915GM(dev))) +#define SUPPORTS_DIGITAL_OUTPUTS(dev) (!IS_GEN2(dev) && !IS_PINEVIEW(dev)) +#define SUPPORTS_INTEGRATED_HDMI(dev) (IS_G4X(dev) || IS_GEN5(dev)) +#define SUPPORTS_INTEGRATED_DP(dev) (IS_G4X(dev) || IS_GEN5(dev)) +#define SUPPORTS_EDP(dev) (IS_IRONLAKE_M(dev)) +#define SUPPORTS_TV(dev) (INTEL_INFO(dev)->supports_tv) +#define I915_HAS_HOTPLUG(dev) (INTEL_INFO(dev)->has_hotplug) +/* dsparb controlled by hw only */ +#define DSPARB_HWCONTROL(dev) (IS_G4X(dev) || IS_IRONLAKE(dev)) + +#define HAS_FW_BLC(dev) (INTEL_INFO(dev)->gen > 2) +#define HAS_PIPE_CXSR(dev) (INTEL_INFO(dev)->has_pipe_cxsr) +#define I915_HAS_FBC(dev) (INTEL_INFO(dev)->has_fbc) +#define I915_HAS_RC6(dev) (INTEL_INFO(dev)->has_rc6) + +#define HAS_PCH_SPLIT(dev) (IS_GEN5(dev) || IS_GEN6(dev)) +#define HAS_PIPE_CONTROL(dev) (IS_GEN5(dev) || IS_GEN6(dev)) + +#define INTEL_PCH_TYPE(dev) (((struct drm_i915_private *)(dev)->dev_private)->pch_type) +#define HAS_PCH_CPT(dev) (INTEL_PCH_TYPE(dev) == PCH_CPT) +#define HAS_PCH_IBX(dev) (INTEL_PCH_TYPE(dev) == PCH_IBX) + extern struct drm_ioctl_desc i915_ioctls[]; extern int i915_max_ioctl; extern unsigned int i915_fbpercrtc; @@ -1174,6 +1235,23 @@ extern void intel_overlay_print_error_state(struct seq_file *m, struct intel_ove LOCK_TEST_WITH_RETURN(dev, file_priv); \ } while (0) +#define I915_READ(reg) i915_read(dev_priv, (reg), 4) +#define I915_WRITE(reg, val) i915_write(dev_priv, (reg), (val), 4) +#define I915_READ16(reg) i915_read(dev_priv, (reg), 2) +#define I915_WRITE16(reg, val) i915_write(dev_priv, (reg), (val), 2) +#define I915_READ8(reg) i915_read(dev_priv, (reg), 1) +#define I915_WRITE8(reg, val) i915_write(dev_priv, (reg), (val), 1) +#define I915_WRITE64(reg, val) i915_write(dev_priv, (reg), (val), 8) +#define I915_READ64(reg) i915_read(dev_priv, (reg), 8) + +#define I915_READ_NOTRACE(reg) readl(dev_priv->regs + (reg)) +#define I915_WRITE_NOTRACE(reg, val) writel(val, dev_priv->regs + (reg)) +#define I915_READ16_NOTRACE(reg) readw(dev_priv->regs + (reg)) +#define I915_WRITE16_NOTRACE(reg, val) writew(val, dev_priv->regs + (reg)) + +#define POSTING_READ(reg) (void)I915_READ_NOTRACE(reg) +#define POSTING_READ16(reg) (void)I915_READ16_NOTRACE(reg) + static inline u32 i915_read(struct drm_i915_private *dev_priv, u32 reg, int len) { u64 val = 0; @@ -1197,6 +1275,23 @@ static inline u32 i915_read(struct drm_i915_private *dev_priv, u32 reg, int len) return val; } +/* On SNB platform, before reading ring registers forcewake bit + * must be set to prevent GT core from power down and stale values being + * returned. + */ +static inline u32 i915_safe_read(struct drm_i915_private *dev_priv, u32 reg) +{ + if (IS_GEN6(dev_priv->dev)) { + I915_WRITE_NOTRACE(FORCEWAKE, 1); + POSTING_READ(FORCEWAKE); + /* XXX How long do we really need to wait here? + * Will different registers/engines require different periods? + */ + udelay(100); + } + return I915_READ(reg); +} + static inline void i915_write(struct drm_i915_private *dev_priv, u32 reg, u64 val, int len) { @@ -1218,24 +1313,6 @@ i915_write(struct drm_i915_private *dev_priv, u32 reg, u64 val, int len) } } -#define I915_READ(reg) i915_read(dev_priv, (reg), 4) -#define I915_WRITE(reg, val) i915_write(dev_priv, (reg), (val), 4) -#define I915_READ16(reg) i915_read(dev_priv, (reg), 2) -#define I915_WRITE16(reg, val) i915_write(dev_priv, (reg), (val), 2) -#define I915_READ8(reg) i915_read(dev_priv, (reg), 1) -#define I915_WRITE8(reg, val) i915_write(dev_priv, (reg), (val), 1) -#define I915_WRITE64(reg, val) i915_write(dev_priv, (reg), (val), 8) -#define I915_READ64(reg) i915_read(dev_priv, (reg), 8) - -#define I915_READ_NOTRACE(reg) readl(dev_priv->regs + (reg)) -#define I915_WRITE_NOTRACE(reg, val) writel(val, dev_priv->regs + (reg)) -#define I915_READ16_NOTRACE(reg) readw(dev_priv->regs + (reg)) -#define I915_WRITE16_NOTRACE(reg, val) writew(val, dev_priv->regs + (reg)) - -#define POSTING_READ(reg) (void)I915_READ_NOTRACE(reg) -#define POSTING_READ16(reg) (void)I915_READ16_NOTRACE(reg) - - #define BEGIN_LP_RING(n) \ intel_ring_begin(&dev_priv->render_ring, (n)) @@ -1266,67 +1343,4 @@ i915_write(struct drm_i915_private *dev_priv, u32 reg, u64 val, int len) #define I915_GEM_HWS_INDEX 0x20 #define I915_BREADCRUMB_INDEX 0x21 -#define INTEL_INFO(dev) (((struct drm_i915_private *) (dev)->dev_private)->info) - -#define IS_I830(dev) ((dev)->pci_device == 0x3577) -#define IS_845G(dev) ((dev)->pci_device == 0x2562) -#define IS_I85X(dev) (INTEL_INFO(dev)->is_i85x) -#define IS_I865G(dev) ((dev)->pci_device == 0x2572) -#define IS_I915G(dev) (INTEL_INFO(dev)->is_i915g) -#define IS_I915GM(dev) ((dev)->pci_device == 0x2592) -#define IS_I945G(dev) ((dev)->pci_device == 0x2772) -#define IS_I945GM(dev) (INTEL_INFO(dev)->is_i945gm) -#define IS_BROADWATER(dev) (INTEL_INFO(dev)->is_broadwater) -#define IS_CRESTLINE(dev) (INTEL_INFO(dev)->is_crestline) -#define IS_GM45(dev) ((dev)->pci_device == 0x2A42) -#define IS_G4X(dev) (INTEL_INFO(dev)->is_g4x) -#define IS_PINEVIEW_G(dev) ((dev)->pci_device == 0xa001) -#define IS_PINEVIEW_M(dev) ((dev)->pci_device == 0xa011) -#define IS_PINEVIEW(dev) (INTEL_INFO(dev)->is_pineview) -#define IS_G33(dev) (INTEL_INFO(dev)->is_g33) -#define IS_IRONLAKE_D(dev) ((dev)->pci_device == 0x0042) -#define IS_IRONLAKE_M(dev) ((dev)->pci_device == 0x0046) -#define IS_MOBILE(dev) (INTEL_INFO(dev)->is_mobile) - -#define IS_GEN2(dev) (INTEL_INFO(dev)->gen == 2) -#define IS_GEN3(dev) (INTEL_INFO(dev)->gen == 3) -#define IS_GEN4(dev) (INTEL_INFO(dev)->gen == 4) -#define IS_GEN5(dev) (INTEL_INFO(dev)->gen == 5) -#define IS_GEN6(dev) (INTEL_INFO(dev)->gen == 6) - -#define HAS_BSD(dev) (INTEL_INFO(dev)->has_bsd_ring) -#define HAS_BLT(dev) (INTEL_INFO(dev)->has_blt_ring) -#define I915_NEED_GFX_HWS(dev) (INTEL_INFO(dev)->need_gfx_hws) - -#define HAS_OVERLAY(dev) (INTEL_INFO(dev)->has_overlay) -#define OVERLAY_NEEDS_PHYSICAL(dev) (INTEL_INFO(dev)->overlay_needs_physical) - -/* With the 945 and later, Y tiling got adjusted so that it was 32 128-byte - * rows, which changed the alignment requirements and fence programming. - */ -#define HAS_128_BYTE_Y_TILING(dev) (!IS_GEN2(dev) && !(IS_I915G(dev) || \ - IS_I915GM(dev))) -#define SUPPORTS_DIGITAL_OUTPUTS(dev) (!IS_GEN2(dev) && !IS_PINEVIEW(dev)) -#define SUPPORTS_INTEGRATED_HDMI(dev) (IS_G4X(dev) || IS_GEN5(dev)) -#define SUPPORTS_INTEGRATED_DP(dev) (IS_G4X(dev) || IS_GEN5(dev)) -#define SUPPORTS_EDP(dev) (IS_IRONLAKE_M(dev)) -#define SUPPORTS_TV(dev) (INTEL_INFO(dev)->supports_tv) -#define I915_HAS_HOTPLUG(dev) (INTEL_INFO(dev)->has_hotplug) -/* dsparb controlled by hw only */ -#define DSPARB_HWCONTROL(dev) (IS_G4X(dev) || IS_IRONLAKE(dev)) - -#define HAS_FW_BLC(dev) (INTEL_INFO(dev)->gen > 2) -#define HAS_PIPE_CXSR(dev) (INTEL_INFO(dev)->has_pipe_cxsr) -#define I915_HAS_FBC(dev) (INTEL_INFO(dev)->has_fbc) -#define I915_HAS_RC6(dev) (INTEL_INFO(dev)->has_rc6) - -#define HAS_PCH_SPLIT(dev) (IS_GEN5(dev) || IS_GEN6(dev)) -#define HAS_PIPE_CONTROL(dev) (IS_GEN5(dev) || IS_GEN6(dev)) - -#define INTEL_PCH_TYPE(dev) (((struct drm_i915_private *)(dev)->dev_private)->pch_type) -#define HAS_PCH_CPT(dev) (INTEL_PCH_TYPE(dev) == PCH_CPT) -#define HAS_PCH_IBX(dev) (INTEL_PCH_TYPE(dev) == PCH_IBX) - -#define PRIMARY_RINGBUFFER_SIZE (128*1024) - #endif diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 61fe2619bb63..1eca8e710b9e 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -3077,4 +3077,5 @@ #define EDP_LINK_TRAIN_800MV_0DB_SNB_B (0x38<<22) #define EDP_LINK_TRAIN_VOL_EMP_MASK_SNB (0x3f<<22) +#define FORCEWAKE 0xA18C #endif /* _I915_REG_H_ */ diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index f5d6151c953f..99f2c96a9c70 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -708,7 +708,7 @@ static int intel_wrap_ring_buffer(struct intel_ring_buffer *ring) int intel_wait_ring_buffer(struct intel_ring_buffer *ring, int n) { struct drm_device *dev = ring->dev; - drm_i915_private_t *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = dev->dev_private; unsigned long end; u32 head; diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index d73145c790bd..2565d65a625b 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -7,13 +7,18 @@ struct intel_hw_status_page { struct drm_gem_object *obj; }; -#define I915_READ_TAIL(ring) I915_READ(RING_TAIL(ring->mmio_base)) +#define I915_RING_READ(reg) i915_safe_read(dev_priv, reg) + +#define I915_READ_TAIL(ring) I915_RING_READ(RING_TAIL(ring->mmio_base)) #define I915_WRITE_TAIL(ring, val) I915_WRITE(RING_TAIL(ring->mmio_base), val) -#define I915_READ_START(ring) I915_READ(RING_START(ring->mmio_base)) + +#define I915_READ_START(ring) I915_RING_READ(RING_START(ring->mmio_base)) #define I915_WRITE_START(ring, val) I915_WRITE(RING_START(ring->mmio_base), val) -#define I915_READ_HEAD(ring) I915_READ(RING_HEAD(ring->mmio_base)) + +#define I915_READ_HEAD(ring) I915_RING_READ(RING_HEAD(ring->mmio_base)) #define I915_WRITE_HEAD(ring, val) I915_WRITE(RING_HEAD(ring->mmio_base), val) -#define I915_READ_CTL(ring) I915_READ(RING_CTL(ring->mmio_base)) + +#define I915_READ_CTL(ring) I915_RING_READ(RING_CTL(ring->mmio_base)) #define I915_WRITE_CTL(ring, val) I915_WRITE(RING_CTL(ring->mmio_base), val) struct drm_i915_gem_execbuffer2; -- cgit v1.2.3 From e74cfed521746544e6eeee84b24bd31c1e59ffe2 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 9 Nov 2010 10:16:56 +0000 Subject: Revert "drm/i915/ringbuffer: Ignore failure to setup the ring on Sandybridge" This reverts commit 629e894173c9de589913cf649deaadec4b0579bd. --- drivers/gpu/drm/i915/intel_ringbuffer.c | 32 ++++++++------------------------ 1 file changed, 8 insertions(+), 24 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 99f2c96a9c70..1db860d7989a 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -180,30 +180,14 @@ static int init_ring_common(struct intel_ring_buffer *ring) if ((I915_READ_CTL(ring) & RING_VALID) == 0 || I915_READ_START(ring) != obj_priv->gtt_offset || (I915_READ_HEAD(ring) & HEAD_ADDR) != 0) { - if (IS_GEN6(ring->dev) && ring->dev->pdev->revision <= 8) { - /* Early revisions of Sandybridge do not like - * revealing the contents of the ring buffer - * registers whilst idle. Fortunately, the - * auto-reporting mechanism prevents most hangs, - * but this will bite us eventually... - */ - DRM_DEBUG("%s initialization failed " - "ctl %08x head %08x tail %08x start %08x. Ignoring, hope for the best!\n", - ring->name, - I915_READ_CTL(ring), - I915_READ_HEAD(ring), - I915_READ_TAIL(ring), - I915_READ_START(ring)); - } else { - DRM_ERROR("%s initialization failed " - "ctl %08x head %08x tail %08x start %08x\n", - ring->name, - I915_READ_CTL(ring), - I915_READ_HEAD(ring), - I915_READ_TAIL(ring), - I915_READ_START(ring)); - return -EIO; - } + DRM_ERROR("%s initialization failed " + "ctl %08x head %08x tail %08x start %08x\n", + ring->name, + I915_READ_CTL(ring), + I915_READ_HEAD(ring), + I915_READ_TAIL(ring), + I915_READ_START(ring)); + return -EIO; } if (!drm_core_check_feature(ring->dev, DRIVER_MODESET)) -- cgit v1.2.3 From 8168bd48bb863c00747497aadf13884b2d69d287 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 11 Nov 2010 17:54:52 +0000 Subject: drm/i915: Remove the definitions for Primary Ring Buffer We only ever used the PRB0, neglecting the secondary ring buffers, and now with the advent of multiple engines with separate ring buffers we need to excise the anachronisms from our code (and be explicit about which ring we mean where). This is doubly important in light of the FORCEWAKE required to read ring buffer registers on SandyBridge. Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_dma.c | 4 ++-- drivers/gpu/drm/i915/i915_irq.c | 28 ++++++++++++++-------------- drivers/gpu/drm/i915/i915_reg.h | 10 ++++++---- drivers/gpu/drm/i915/intel_display.c | 10 +++++----- 4 files changed, 27 insertions(+), 25 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 307bad0fcef7..4cd04917868d 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -106,8 +106,8 @@ void i915_kernel_lost_context(struct drm_device * dev) if (drm_core_check_feature(dev, DRIVER_MODESET)) return; - ring->head = I915_READ(PRB0_HEAD) & HEAD_ADDR; - ring->tail = I915_READ(PRB0_TAIL) & TAIL_ADDR; + ring->head = I915_READ_HEAD(ring) & HEAD_ADDR; + ring->tail = I915_READ_TAIL(ring) & TAIL_ADDR; ring->space = ring->head - (ring->tail + 8); if (ring->space < 0) ring->space += ring->size; diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 4a0664ea49b9..21034527d3a4 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -520,30 +520,30 @@ i915_get_bbaddr(struct drm_device *dev, u32 *ring) } static u32 -i915_ringbuffer_last_batch(struct drm_device *dev) +i915_ringbuffer_last_batch(struct drm_device *dev, + struct intel_ring_buffer *ring) { struct drm_i915_private *dev_priv = dev->dev_private; u32 head, bbaddr; - u32 *ring; + u32 *val; /* Locate the current position in the ringbuffer and walk back * to find the most recently dispatched batch buffer. */ bbaddr = 0; - head = I915_READ(PRB0_HEAD) & HEAD_ADDR; - ring = (u32 *)(dev_priv->render_ring.virtual_start + head); + head = I915_READ_HEAD(ring) & HEAD_ADDR; + val = (u32 *)(ring->virtual_start + head); - while (--ring >= (u32 *)dev_priv->render_ring.virtual_start) { - bbaddr = i915_get_bbaddr(dev, ring); + while (--val >= (u32 *)ring->virtual_start) { + bbaddr = i915_get_bbaddr(dev, val); if (bbaddr) break; } if (bbaddr == 0) { - ring = (u32 *)(dev_priv->render_ring.virtual_start - + dev_priv->render_ring.size); - while (--ring >= (u32 *)dev_priv->render_ring.virtual_start) { - bbaddr = i915_get_bbaddr(dev, ring); + val = (u32 *)(ring->virtual_start + ring->size); + while (--val >= (u32 *)ring->virtual_start) { + bbaddr = i915_get_bbaddr(dev, val); if (bbaddr) break; } @@ -628,7 +628,7 @@ static void i915_capture_error_state(struct drm_device *dev) error->bbaddr = 0; } - bbaddr = i915_ringbuffer_last_batch(dev); + bbaddr = i915_ringbuffer_last_batch(dev, &dev_priv->render_ring); /* Grab the current batchbuffer, most likely to have crashed. */ batchbuffer[0] = NULL; @@ -1398,10 +1398,10 @@ void i915_hangcheck_elapsed(unsigned long data) * and break the hang. This should work on * all but the second generation chipsets. */ - u32 tmp = I915_READ(PRB0_CTL); + struct intel_ring_buffer *ring = &dev_priv->render_ring; + u32 tmp = I915_READ_CTL(ring); if (tmp & RING_WAIT) { - I915_WRITE(PRB0_CTL, tmp); - POSTING_READ(PRB0_CTL); + I915_WRITE_CTL(ring, tmp); goto repeat; } } diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 1eca8e710b9e..886c0e072490 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -256,10 +256,6 @@ * Instruction and interrupt control regs */ #define PGTBL_ER 0x02024 -#define PRB0_TAIL 0x02030 -#define PRB0_HEAD 0x02034 -#define PRB0_START 0x02038 -#define PRB0_CTL 0x0203c #define RENDER_RING_BASE 0x02000 #define BSD_RING_BASE 0x04000 #define GEN6_BSD_RING_BASE 0x12000 @@ -285,10 +281,16 @@ #define RING_INVALID 0x00000000 #define RING_WAIT_I8XX (1<<0) /* gen2, PRBx_HEAD */ #define RING_WAIT (1<<11) /* gen3+, PRBx_CTL */ +#if 0 +#define PRB0_TAIL 0x02030 +#define PRB0_HEAD 0x02034 +#define PRB0_START 0x02038 +#define PRB0_CTL 0x0203c #define PRB1_TAIL 0x02040 /* 915+ only */ #define PRB1_HEAD 0x02044 /* 915+ only */ #define PRB1_START 0x02048 /* 915+ only */ #define PRB1_CTL 0x0204c /* 915+ only */ +#endif #define IPEIR_I965 0x02064 #define IPEHR_I965 0x02068 #define INSTDONE_I965 0x0206c diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 63770c963077..6a7f11ff66f5 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -1983,17 +1983,17 @@ static void intel_flush_display_plane(struct drm_device *dev, static void intel_clear_scanline_wait(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_ring_buffer *ring; u32 tmp; if (IS_GEN2(dev)) /* Can't break the hang on i8xx */ return; - tmp = I915_READ(PRB0_CTL); - if (tmp & RING_WAIT) { - I915_WRITE(PRB0_CTL, tmp); - POSTING_READ(PRB0_CTL); - } + ring = &dev_priv->render_ring; + tmp = I915_READ_CTL(ring); + if (tmp & RING_WAIT) + I915_WRITE_CTL(ring, tmp); } static void intel_crtc_wait_for_pending_flips(struct drm_crtc *crtc) -- cgit v1.2.3 From b36930dd508e00f0c5083bcd57d25de6d0375c76 Mon Sep 17 00:00:00 2001 From: David Miller Date: Wed, 10 Nov 2010 21:56:39 -0800 Subject: dlm: Handle application limited situations properly. In the normal regime where an application uses non-blocking I/O writes on a socket, they will handle -EAGAIN and use poll() to wait for send space. They don't actually sleep on the socket I/O write. But kernel level RPC layers that do socket I/O operations directly and key off of -EAGAIN on the write() to "try again later" don't use poll(), they instead have their own sleeping mechanism and rely upon ->sk_write_space() to trigger the wakeup. So they do effectively sleep on the write(), but this mechanism alone does not let the socket layers know what's going on. Therefore they must emulate what would have happened, otherwise TCP cannot possibly see that the connection is application window size limited. Handle this, therefore, like SUNRPC by setting SOCK_NOSPACE and bumping the ->sk_write_count as needed when we hit the send buffer limits. This should make TCP send buffer size auto-tuning and the ->sk_write_space() callback invocations actually happen. Signed-off-by: David S. Miller Signed-off-by: David Teigland --- fs/dlm/lowcomms.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/fs/dlm/lowcomms.c b/fs/dlm/lowcomms.c index 37a34c2c622a..77720f89c879 100644 --- a/fs/dlm/lowcomms.c +++ b/fs/dlm/lowcomms.c @@ -108,6 +108,7 @@ struct connection { #define CF_INIT_PENDING 4 #define CF_IS_OTHERCON 5 #define CF_CLOSE 6 +#define CF_APP_LIMITED 7 struct list_head writequeue; /* List of outgoing writequeue_entries */ spinlock_t writequeue_lock; int (*rx_action) (struct connection *); /* What to do when active */ @@ -295,7 +296,17 @@ static void lowcomms_write_space(struct sock *sk) { struct connection *con = sock2con(sk); - if (con && !test_and_set_bit(CF_WRITE_PENDING, &con->flags)) + if (!con) + return; + + clear_bit(SOCK_NOSPACE, &con->sock->flags); + + if (test_and_clear_bit(CF_APP_LIMITED, &con->flags)) { + con->sock->sk->sk_write_pending--; + clear_bit(SOCK_ASYNC_NOSPACE, &con->sock->flags); + } + + if (!test_and_set_bit(CF_WRITE_PENDING, &con->flags)) queue_work(send_workqueue, &con->swork); } @@ -1319,6 +1330,15 @@ static void send_to_sock(struct connection *con) ret = kernel_sendpage(con->sock, e->page, offset, len, msg_flags); if (ret == -EAGAIN || ret == 0) { + if (ret == -EAGAIN && + test_bit(SOCK_ASYNC_NOSPACE, &con->sock->flags) && + !test_and_set_bit(CF_APP_LIMITED, &con->flags)) { + /* Notify TCP that we're limited by the + * application window size. + */ + set_bit(SOCK_NOSPACE, &con->sock->flags); + con->sock->sk->sk_write_pending++; + } cond_resched(); goto out; } -- cgit v1.2.3 From cb2b3cf1fedd31916b7c64d61e2d20d23bd3681a Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 11 Nov 2010 17:18:01 +0000 Subject: ASoC: Reset WM8962 with default ID value The value makes no odds and it makes life easier with caches. Signed-off-by: Mark Brown Acked-by: Liam Girdwood --- sound/soc/codecs/wm8962.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c index 80986105f52e..e021866f5a85 100644 --- a/sound/soc/codecs/wm8962.c +++ b/sound/soc/codecs/wm8962.c @@ -1958,7 +1958,7 @@ static int wm8962_readable_register(unsigned int reg) static int wm8962_reset(struct snd_soc_codec *codec) { - return snd_soc_write(codec, WM8962_SOFTWARE_RESET, 0); + return snd_soc_write(codec, WM8962_SOFTWARE_RESET, 0x6243); } static const DECLARE_TLV_DB_SCALE(inpga_tlv, -2325, 75, 0); -- cgit v1.2.3 From dcce240ead802d42b1e45ad2fcb2ed4a399cb255 Mon Sep 17 00:00:00 2001 From: Steven Whitehouse Date: Fri, 12 Nov 2010 12:12:29 +0000 Subject: dlm: Use cmwq for send and receive workqueues So far as I can tell, there is no reason to use a single-threaded send workqueue for dlm, since it may need to send to several sockets concurrently. Both workqueues are set to WQ_MEM_RECLAIM to avoid any possible deadlocks, WQ_HIGHPRI since locking traffic is highly latency sensitive (and to avoid a priority inversion wrt GFS2's glock_workqueue) and WQ_FREEZABLE just in case someone needs to do that (even though with current cluster infrastructure, it doesn't make sense as the node will most likely land up ejected from the cluster) in the future. Signed-off-by: Steven Whitehouse Cc: Tejun Heo Signed-off-by: David Teigland --- fs/dlm/lowcomms.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/fs/dlm/lowcomms.c b/fs/dlm/lowcomms.c index 77720f89c879..1d4e644c6589 100644 --- a/fs/dlm/lowcomms.c +++ b/fs/dlm/lowcomms.c @@ -1451,14 +1451,16 @@ static void work_stop(void) static int work_start(void) { int error; - recv_workqueue = create_workqueue("dlm_recv"); + recv_workqueue = alloc_workqueue("dlm_recv", WQ_MEM_RECLAIM | + WQ_HIGHPRI | WQ_FREEZEABLE, 0); error = IS_ERR(recv_workqueue); if (error) { log_print("can't start dlm_recv %d", error); return error; } - send_workqueue = create_singlethread_workqueue("dlm_send"); + send_workqueue = alloc_workqueue("dlm_send", WQ_MEM_RECLAIM | + WQ_HIGHPRI | WQ_FREEZEABLE, 0); error = IS_ERR(send_workqueue); if (error) { log_print("can't start dlm_send %d", error); -- cgit v1.2.3 From cb2d45da81c86d5191b19d0f67732a854bc0253c Mon Sep 17 00:00:00 2001 From: David Teigland Date: Fri, 12 Nov 2010 11:12:55 -0600 Subject: dlm: use TCP_NODELAY Nagling doesn't help and can sometimes hurt dlm comms. Signed-off-by: David Teigland --- fs/dlm/lowcomms.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/fs/dlm/lowcomms.c b/fs/dlm/lowcomms.c index 1d4e644c6589..2bedb0ac5f92 100644 --- a/fs/dlm/lowcomms.c +++ b/fs/dlm/lowcomms.c @@ -926,6 +926,7 @@ static void tcp_connect_to_sock(struct connection *con) struct sockaddr_storage saddr, src_addr; int addr_len; struct socket *sock = NULL; + int one = 1; if (con->nodeid == 0) { log_print("attempt to connect sock 0 foiled"); @@ -971,6 +972,11 @@ static void tcp_connect_to_sock(struct connection *con) make_sockaddr(&saddr, dlm_config.ci_tcp_port, &addr_len); log_print("connecting to %d", con->nodeid); + + /* Turn off Nagle's algorithm */ + kernel_setsockopt(sock, SOL_TCP, TCP_NODELAY, (char *)&one, + sizeof(one)); + result = sock->ops->connect(sock, (struct sockaddr *)&saddr, addr_len, O_NONBLOCK); @@ -1022,6 +1028,10 @@ static struct socket *tcp_create_listen_sock(struct connection *con, goto create_out; } + /* Turn off Nagle's algorithm */ + kernel_setsockopt(sock, SOL_TCP, TCP_NODELAY, (char *)&one, + sizeof(one)); + result = kernel_setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&one, sizeof(one)); -- cgit v1.2.3 From f92c8dd7a0eb18124521e2b549f88422e17f707b Mon Sep 17 00:00:00 2001 From: Bob Peterson Date: Fri, 12 Nov 2010 11:15:20 -0600 Subject: dlm: reduce cond_resched during send Calling cond_resched() after every send can unnecessarily degrade performance. Go back to an old method of scheduling after 25 messages. Signed-off-by: Bob Peterson Signed-off-by: David Teigland --- fs/dlm/lowcomms.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/fs/dlm/lowcomms.c b/fs/dlm/lowcomms.c index 2bedb0ac5f92..0e75f152eac2 100644 --- a/fs/dlm/lowcomms.c +++ b/fs/dlm/lowcomms.c @@ -63,6 +63,9 @@ #define NEEDED_RMEM (4*1024*1024) #define CONN_HASH_SIZE 32 +/* Number of messages to send before rescheduling */ +#define MAX_SEND_MSG_COUNT 25 + struct cbuf { unsigned int base; unsigned int len; @@ -1318,6 +1321,7 @@ static void send_to_sock(struct connection *con) const int msg_flags = MSG_DONTWAIT | MSG_NOSIGNAL; struct writequeue_entry *e; int len, offset; + int count = 0; mutex_lock(&con->sock_mutex); if (con->sock == NULL) @@ -1355,8 +1359,12 @@ static void send_to_sock(struct connection *con) if (ret <= 0) goto send_error; } - /* Don't starve people filling buffers */ + + /* Don't starve people filling buffers */ + if (++count >= MAX_SEND_MSG_COUNT) { cond_resched(); + count = 0; + } spin_lock(&con->writequeue_lock); e->offset += ret; -- cgit v1.2.3 From 731edacb7567c15f25b1fccac18a203bd432ae5e Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sat, 13 Nov 2010 11:55:16 +0100 Subject: mtd: fix bdev exclusive open bugs in block2mtd::add_device() There are two bdev exclusive open bugs. * open_bdev_exclusive() must not be called with NULL holder. Use dev as the holder. * open_by_devnum() doesn't open the bdev exclusively but block2mtd_free_device() always assumes it. Explicitly claim the bdev. The latter is rather clumsy but will be simplified with future blkdev_get/put() cleanups. - Updated to use local variable @mode to cache FMODE_* masks as suggested by Artem Bityutskiy. Signed-off-by: Tejun Heo Cc: linux-mtd@lists.infradead.org Cc: Artem Bityutskiy --- drivers/mtd/devices/block2mtd.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/drivers/mtd/devices/block2mtd.c b/drivers/mtd/devices/block2mtd.c index 2cf0cc6a4189..a9e2d3b38aeb 100644 --- a/drivers/mtd/devices/block2mtd.c +++ b/drivers/mtd/devices/block2mtd.c @@ -234,6 +234,7 @@ static void block2mtd_free_device(struct block2mtd_dev *dev) /* FIXME: ensure that mtd->size % erase_size == 0 */ static struct block2mtd_dev *add_device(char *devname, int erase_size) { + const fmode_t mode = FMODE_READ | FMODE_WRITE; struct block_device *bdev; struct block2mtd_dev *dev; char *name; @@ -246,7 +247,7 @@ static struct block2mtd_dev *add_device(char *devname, int erase_size) return NULL; /* Get a handle on the device */ - bdev = open_bdev_exclusive(devname, FMODE_READ|FMODE_WRITE, NULL); + bdev = open_bdev_exclusive(devname, mode, dev); #ifndef MODULE if (IS_ERR(bdev)) { @@ -255,7 +256,15 @@ static struct block2mtd_dev *add_device(char *devname, int erase_size) dev_t devt = name_to_dev_t(devname); if (devt) { - bdev = open_by_devnum(devt, FMODE_WRITE | FMODE_READ); + bdev = open_by_devnum(devt, mode); + if (!IS_ERR(bdev)) { + int ret; + ret = bd_claim(bdev, dev); + if (ret) { + blkdev_put(bdev, mode); + bdev = ERR_PTR(ret); + } + } } } #endif -- cgit v1.2.3 From 37004c42f7240035bc2726c340c4efa726b4818e Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sat, 13 Nov 2010 11:55:17 +0100 Subject: btrfs: close_bdev_exclusive() should use the same @flags as the matching open_bdev_exclusive() In the failure path of __btrfs_open_devices(), close_bdev_exclusive() is called with @flags which doesn't match the one used during open_bdev_exclusive(). Fix it. Signed-off-by: Tejun Heo Cc: Chris Mason --- fs/btrfs/volumes.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index cc04dc1445d6..d39596224d21 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c @@ -638,7 +638,7 @@ static int __btrfs_open_devices(struct btrfs_fs_devices *fs_devices, error_brelse: brelse(bh); error_close: - close_bdev_exclusive(bdev, FMODE_READ); + close_bdev_exclusive(bdev, flags); error: continue; } -- cgit v1.2.3 From e09b457bdb7e8d23fc54dcef0930ac697d8de895 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sat, 13 Nov 2010 11:55:17 +0100 Subject: block: simplify holder symlink handling Code to manage symlinks in /sys/block/*/{holders|slaves} are overly complex with multiple holder considerations, redundant extra references to all involved kobjects, unused generic kobject holder support and unnecessary mixup with bd_claim/release functionalities. Strip it down to what's necessary (single gendisk holder) and make it use a separate interface. This is a step for cleaning up bd_claim/release. This patch makes dm-table slightly more complex but it will be simplified again with further changes. Signed-off-by: Tejun Heo Acked-by: Neil Brown Acked-by: Mike Snitzer Cc: dm-devel@redhat.com --- drivers/md/dm-table.c | 23 +++- drivers/md/md.c | 4 +- fs/block_dev.c | 322 +++++++------------------------------------------- include/linux/fs.h | 16 ++- 4 files changed, 74 insertions(+), 291 deletions(-) diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c index 90267f8d64ee..2c876ffc63df 100644 --- a/drivers/md/dm-table.c +++ b/drivers/md/dm-table.c @@ -328,12 +328,22 @@ static int open_dev(struct dm_dev_internal *d, dev_t dev, bdev = open_by_devnum(dev, d->dm_dev.mode); if (IS_ERR(bdev)) return PTR_ERR(bdev); - r = bd_claim_by_disk(bdev, _claim_ptr, dm_disk(md)); - if (r) + + r = bd_claim(bdev, _claim_ptr); + if (r) { blkdev_put(bdev, d->dm_dev.mode); - else - d->dm_dev.bdev = bdev; - return r; + return r; + } + + r = bd_link_disk_holder(bdev, dm_disk(md)); + if (r) { + bd_release(bdev); + blkdev_put(bdev, d->dm_dev.mode); + return r; + } + + d->dm_dev.bdev = bdev; + return 0; } /* @@ -344,7 +354,8 @@ static void close_dev(struct dm_dev_internal *d, struct mapped_device *md) if (!d->dm_dev.bdev) return; - bd_release_from_disk(d->dm_dev.bdev, dm_disk(md)); + bd_unlink_disk_holder(d->dm_dev.bdev); + bd_release(d->dm_dev.bdev); blkdev_put(d->dm_dev.bdev, d->dm_dev.mode); d->dm_dev.bdev = NULL; } diff --git a/drivers/md/md.c b/drivers/md/md.c index 4e957f3140a8..c47644fca1a1 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -1880,7 +1880,7 @@ static int bind_rdev_to_array(mdk_rdev_t * rdev, mddev_t * mddev) rdev->sysfs_state = sysfs_get_dirent_safe(rdev->kobj.sd, "state"); list_add_rcu(&rdev->same_set, &mddev->disks); - bd_claim_by_disk(rdev->bdev, rdev->bdev->bd_holder, mddev->gendisk); + bd_link_disk_holder(rdev->bdev, mddev->gendisk); /* May as well allow recovery to be retried once */ mddev->recovery_disabled = 0; @@ -1907,7 +1907,7 @@ static void unbind_rdev_from_array(mdk_rdev_t * rdev) MD_BUG(); return; } - bd_release_from_disk(rdev->bdev, rdev->mddev->gendisk); + bd_unlink_disk_holder(rdev->bdev); list_del_rcu(&rdev->same_set); printk(KERN_INFO "md: unbind<%s>\n", bdevname(rdev->bdev,b)); rdev->mddev = NULL; diff --git a/fs/block_dev.c b/fs/block_dev.c index 06e8ff12b97c..9329068684d2 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c @@ -426,9 +426,6 @@ static void init_once(void *foo) mutex_init(&bdev->bd_mutex); INIT_LIST_HEAD(&bdev->bd_inodes); INIT_LIST_HEAD(&bdev->bd_list); -#ifdef CONFIG_SYSFS - INIT_LIST_HEAD(&bdev->bd_holder_list); -#endif inode_init_once(&ei->vfs_inode); /* Initialize mutex for freeze. */ mutex_init(&bdev->bd_fsfreeze_mutex); @@ -881,314 +878,83 @@ void bd_release(struct block_device *bdev) EXPORT_SYMBOL(bd_release); #ifdef CONFIG_SYSFS -/* - * Functions for bd_claim_by_kobject / bd_release_from_kobject - * - * If a kobject is passed to bd_claim_by_kobject() - * and the kobject has a parent directory, - * following symlinks are created: - * o from the kobject to the claimed bdev - * o from "holders" directory of the bdev to the parent of the kobject - * bd_release_from_kobject() removes these symlinks. - * - * Example: - * If /dev/dm-0 maps to /dev/sda, kobject corresponding to - * /sys/block/dm-0/slaves is passed to bd_claim_by_kobject(), then: - * /sys/block/dm-0/slaves/sda --> /sys/block/sda - * /sys/block/sda/holders/dm-0 --> /sys/block/dm-0 - */ - static int add_symlink(struct kobject *from, struct kobject *to) { - if (!from || !to) - return 0; return sysfs_create_link(from, to, kobject_name(to)); } static void del_symlink(struct kobject *from, struct kobject *to) { - if (!from || !to) - return; sysfs_remove_link(from, kobject_name(to)); } -/* - * 'struct bd_holder' contains pointers to kobjects symlinked by - * bd_claim_by_kobject. - * It's connected to bd_holder_list which is protected by bdev->bd_sem. - */ -struct bd_holder { - struct list_head list; /* chain of holders of the bdev */ - int count; /* references from the holder */ - struct kobject *sdir; /* holder object, e.g. "/block/dm-0/slaves" */ - struct kobject *hdev; /* e.g. "/block/dm-0" */ - struct kobject *hdir; /* e.g. "/block/sda/holders" */ - struct kobject *sdev; /* e.g. "/block/sda" */ -}; - -/* - * Get references of related kobjects at once. - * Returns 1 on success. 0 on failure. - * - * Should call bd_holder_release_dirs() after successful use. - */ -static int bd_holder_grab_dirs(struct block_device *bdev, - struct bd_holder *bo) -{ - if (!bdev || !bo) - return 0; - - bo->sdir = kobject_get(bo->sdir); - if (!bo->sdir) - return 0; - - bo->hdev = kobject_get(bo->sdir->parent); - if (!bo->hdev) - goto fail_put_sdir; - - bo->sdev = kobject_get(&part_to_dev(bdev->bd_part)->kobj); - if (!bo->sdev) - goto fail_put_hdev; - - bo->hdir = kobject_get(bdev->bd_part->holder_dir); - if (!bo->hdir) - goto fail_put_sdev; - - return 1; - -fail_put_sdev: - kobject_put(bo->sdev); -fail_put_hdev: - kobject_put(bo->hdev); -fail_put_sdir: - kobject_put(bo->sdir); - - return 0; -} - -/* Put references of related kobjects at once. */ -static void bd_holder_release_dirs(struct bd_holder *bo) -{ - kobject_put(bo->hdir); - kobject_put(bo->sdev); - kobject_put(bo->hdev); - kobject_put(bo->sdir); -} - -static struct bd_holder *alloc_bd_holder(struct kobject *kobj) -{ - struct bd_holder *bo; - - bo = kzalloc(sizeof(*bo), GFP_KERNEL); - if (!bo) - return NULL; - - bo->count = 1; - bo->sdir = kobj; - - return bo; -} - -static void free_bd_holder(struct bd_holder *bo) -{ - kfree(bo); -} - /** - * find_bd_holder - find matching struct bd_holder from the block device + * bd_link_disk_holder - create symlinks between holding disk and slave bdev + * @bdev: the claimed slave bdev + * @disk: the holding disk * - * @bdev: struct block device to be searched - * @bo: target struct bd_holder + * This functions creates the following sysfs symlinks. * - * Returns matching entry with @bo in @bdev->bd_holder_list. - * If found, increment the reference count and return the pointer. - * If not found, returns NULL. - */ -static struct bd_holder *find_bd_holder(struct block_device *bdev, - struct bd_holder *bo) -{ - struct bd_holder *tmp; - - list_for_each_entry(tmp, &bdev->bd_holder_list, list) - if (tmp->sdir == bo->sdir) { - tmp->count++; - return tmp; - } - - return NULL; -} - -/** - * add_bd_holder - create sysfs symlinks for bd_claim() relationship + * - from "slaves" directory of the holder @disk to the claimed @bdev + * - from "holders" directory of the @bdev to the holder @disk * - * @bdev: block device to be bd_claimed - * @bo: preallocated and initialized by alloc_bd_holder() + * For example, if /dev/dm-0 maps to /dev/sda and disk for dm-0 is + * passed to bd_link_disk_holder(), then: * - * Add @bo to @bdev->bd_holder_list, create symlinks. + * /sys/block/dm-0/slaves/sda --> /sys/block/sda + * /sys/block/sda/holders/dm-0 --> /sys/block/dm-0 * - * Returns 0 if symlinks are created. - * Returns -ve if something fails. - */ -static int add_bd_holder(struct block_device *bdev, struct bd_holder *bo) -{ - int err; - - if (!bo) - return -EINVAL; - - if (!bd_holder_grab_dirs(bdev, bo)) - return -EBUSY; - - err = add_symlink(bo->sdir, bo->sdev); - if (err) - return err; - - err = add_symlink(bo->hdir, bo->hdev); - if (err) { - del_symlink(bo->sdir, bo->sdev); - return err; - } - - list_add_tail(&bo->list, &bdev->bd_holder_list); - return 0; -} - -/** - * del_bd_holder - delete sysfs symlinks for bd_claim() relationship - * - * @bdev: block device to be bd_claimed - * @kobj: holder's kobject - * - * If there is matching entry with @kobj in @bdev->bd_holder_list - * and no other bd_claim() from the same kobject, - * remove the struct bd_holder from the list, delete symlinks for it. - * - * Returns a pointer to the struct bd_holder when it's removed from the list - * and ready to be freed. - * Returns NULL if matching claim isn't found or there is other bd_claim() - * by the same kobject. - */ -static struct bd_holder *del_bd_holder(struct block_device *bdev, - struct kobject *kobj) -{ - struct bd_holder *bo; - - list_for_each_entry(bo, &bdev->bd_holder_list, list) { - if (bo->sdir == kobj) { - bo->count--; - BUG_ON(bo->count < 0); - if (!bo->count) { - list_del(&bo->list); - del_symlink(bo->sdir, bo->sdev); - del_symlink(bo->hdir, bo->hdev); - bd_holder_release_dirs(bo); - return bo; - } - break; - } - } - - return NULL; -} - -/** - * bd_claim_by_kobject - bd_claim() with additional kobject signature - * - * @bdev: block device to be claimed - * @holder: holder's signature - * @kobj: holder's kobject + * The caller must have claimed @bdev before calling this function and + * ensure that both @bdev and @disk are valid during the creation and + * lifetime of these symlinks. * - * Do bd_claim() and if it succeeds, create sysfs symlinks between - * the bdev and the holder's kobject. - * Use bd_release_from_kobject() when relesing the claimed bdev. + * CONTEXT: + * Might sleep. * - * Returns 0 on success. (same as bd_claim()) - * Returns errno on failure. + * RETURNS: + * 0 on success, -errno on failure. */ -static int bd_claim_by_kobject(struct block_device *bdev, void *holder, - struct kobject *kobj) +int bd_link_disk_holder(struct block_device *bdev, struct gendisk *disk) { - int err; - struct bd_holder *bo, *found; - - if (!kobj) - return -EINVAL; - - bo = alloc_bd_holder(kobj); - if (!bo) - return -ENOMEM; + int ret = 0; mutex_lock(&bdev->bd_mutex); - err = bd_claim(bdev, holder); - if (err) - goto fail; + WARN_ON_ONCE(!bdev->bd_holder || bdev->bd_holder_disk); - found = find_bd_holder(bdev, bo); - if (found) - goto fail; + /* FIXME: remove the following once add_disk() handles errors */ + if (WARN_ON(!disk->slave_dir || !bdev->bd_part->holder_dir)) + goto out_unlock; - err = add_bd_holder(bdev, bo); - if (err) - bd_release(bdev); - else - bo = NULL; -fail: - mutex_unlock(&bdev->bd_mutex); - free_bd_holder(bo); - return err; -} + ret = add_symlink(disk->slave_dir, &part_to_dev(bdev->bd_part)->kobj); + if (ret) + goto out_unlock; -/** - * bd_release_from_kobject - bd_release() with additional kobject signature - * - * @bdev: block device to be released - * @kobj: holder's kobject - * - * Do bd_release() and remove sysfs symlinks created by bd_claim_by_kobject(). - */ -static void bd_release_from_kobject(struct block_device *bdev, - struct kobject *kobj) -{ - if (!kobj) - return; + ret = add_symlink(bdev->bd_part->holder_dir, &disk_to_dev(disk)->kobj); + if (ret) { + del_symlink(disk->slave_dir, &part_to_dev(bdev->bd_part)->kobj); + goto out_unlock; + } - mutex_lock(&bdev->bd_mutex); - bd_release(bdev); - free_bd_holder(del_bd_holder(bdev, kobj)); + bdev->bd_holder_disk = disk; +out_unlock: mutex_unlock(&bdev->bd_mutex); + return ret; } +EXPORT_SYMBOL_GPL(bd_link_disk_holder); -/** - * bd_claim_by_disk - wrapper function for bd_claim_by_kobject() - * - * @bdev: block device to be claimed - * @holder: holder's signature - * @disk: holder's gendisk - * - * Call bd_claim_by_kobject() with getting @disk->slave_dir. - */ -int bd_claim_by_disk(struct block_device *bdev, void *holder, - struct gendisk *disk) +void bd_unlink_disk_holder(struct block_device *bdev) { - return bd_claim_by_kobject(bdev, holder, kobject_get(disk->slave_dir)); -} -EXPORT_SYMBOL_GPL(bd_claim_by_disk); + struct gendisk *disk = bdev->bd_holder_disk; -/** - * bd_release_from_disk - wrapper function for bd_release_from_kobject() - * - * @bdev: block device to be claimed - * @disk: holder's gendisk - * - * Call bd_release_from_kobject() and put @disk->slave_dir. - */ -void bd_release_from_disk(struct block_device *bdev, struct gendisk *disk) -{ - bd_release_from_kobject(bdev, disk->slave_dir); - kobject_put(disk->slave_dir); + bdev->bd_holder_disk = NULL; + if (!disk) + return; + + del_symlink(disk->slave_dir, &part_to_dev(bdev->bd_part)->kobj); + del_symlink(bdev->bd_part->holder_dir, &disk_to_dev(disk)->kobj); } -EXPORT_SYMBOL_GPL(bd_release_from_disk); +EXPORT_SYMBOL_GPL(bd_unlink_disk_holder); #endif /* diff --git a/include/linux/fs.h b/include/linux/fs.h index 334d68a17108..66b7f2c5d7e9 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -663,7 +663,7 @@ struct block_device { void * bd_holder; int bd_holders; #ifdef CONFIG_SYSFS - struct list_head bd_holder_list; + struct gendisk * bd_holder_disk; /* for sysfs slave linkng */ #endif struct block_device * bd_contains; unsigned bd_block_size; @@ -2042,11 +2042,17 @@ extern int blkdev_put(struct block_device *, fmode_t); extern int bd_claim(struct block_device *, void *); extern void bd_release(struct block_device *); #ifdef CONFIG_SYSFS -extern int bd_claim_by_disk(struct block_device *, void *, struct gendisk *); -extern void bd_release_from_disk(struct block_device *, struct gendisk *); +extern int bd_link_disk_holder(struct block_device *bdev, struct gendisk *disk); +extern void bd_unlink_disk_holder(struct block_device *bdev); #else -#define bd_claim_by_disk(bdev, holder, disk) bd_claim(bdev, holder) -#define bd_release_from_disk(bdev, disk) bd_release(bdev) +static inline int bd_link_disk_holder(struct block_device *bdev, + struct gendisk *disk) +{ + return 0; +} +static inline void bd_unlink_disk_holder(struct block_device *bdev) +{ +} #endif #endif -- cgit v1.2.3 From e525fd89d380c4a94c0d63913a1dd1a593ed25e7 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sat, 13 Nov 2010 11:55:17 +0100 Subject: block: make blkdev_get/put() handle exclusive access Over time, block layer has accumulated a set of APIs dealing with bdev open, close, claim and release. * blkdev_get/put() are the primary open and close functions. * bd_claim/release() deal with exclusive open. * open/close_bdev_exclusive() are combination of open and claim and the other way around, respectively. * bd_link/unlink_disk_holder() to create and remove holder/slave symlinks. * open_by_devnum() wraps bdget() + blkdev_get(). The interface is a bit confusing and the decoupling of open and claim makes it impossible to properly guarantee exclusive access as in-kernel open + claim sequence can disturb the existing exclusive open even before the block layer knows the current open if for another exclusive access. Reorganize the interface such that, * blkdev_get() is extended to include exclusive access management. @holder argument is added and, if is @FMODE_EXCL specified, it will gain exclusive access atomically w.r.t. other exclusive accesses. * blkdev_put() is similarly extended. It now takes @mode argument and if @FMODE_EXCL is set, it releases an exclusive access. Also, when the last exclusive claim is released, the holder/slave symlinks are removed automatically. * bd_claim/release() and close_bdev_exclusive() are no longer necessary and either made static or removed. * bd_link_disk_holder() remains the same but bd_unlink_disk_holder() is no longer necessary and removed. * open_bdev_exclusive() becomes a simple wrapper around lookup_bdev() and blkdev_get(). It also has an unexpected extra bdev_read_only() test which probably should be moved into blkdev_get(). * open_by_devnum() is modified to take @holder argument and pass it to blkdev_get(). Most of bdev open/close operations are unified into blkdev_get/put() and most exclusive accesses are tested atomically at the open time (as it should). This cleans up code and removes some, both valid and invalid, but unnecessary all the same, corner cases. open_bdev_exclusive() and open_by_devnum() can use further cleanup - rename to blkdev_get_by_path() and blkdev_get_by_devt() and drop special features. Well, let's leave them for another day. Most conversions are straight-forward. drbd conversion is a bit more involved as there was some reordering, but the logic should stay the same. Signed-off-by: Tejun Heo Acked-by: Neil Brown Acked-by: Ryusuke Konishi Acked-by: Mike Snitzer Acked-by: Philipp Reisner Cc: Peter Osterlund Cc: Martin Schwidefsky Cc: Heiko Carstens Cc: Jan Kara Cc: Andrew Morton Cc: Andreas Dilger Cc: "Theodore Ts'o" Cc: Mark Fasheh Cc: Joel Becker Cc: Alex Elder Cc: Christoph Hellwig Cc: dm-devel@redhat.com Cc: drbd-dev@lists.linbit.com Cc: Leo Chen Cc: Scott Branden Cc: Chris Mason Cc: Steven Whitehouse Cc: Dave Kleikamp Cc: Joern Engel Cc: reiserfs-devel@vger.kernel.org Cc: Alexander Viro --- block/ioctl.c | 5 +- drivers/block/drbd/drbd_int.h | 2 - drivers/block/drbd/drbd_main.c | 7 +- drivers/block/drbd/drbd_nl.c | 103 ++++++++++----------------- drivers/block/pktcdvd.c | 22 +++--- drivers/char/raw.c | 14 ++-- drivers/md/dm-table.c | 15 +--- drivers/md/md.c | 14 +--- drivers/mtd/devices/block2mtd.c | 17 ++--- drivers/s390/block/dasd_genhd.c | 2 +- fs/block_dev.c | 149 ++++++++++++++-------------------------- fs/btrfs/volumes.c | 14 ++-- fs/ext3/super.c | 12 +--- fs/ext4/super.c | 12 +--- fs/gfs2/ops_fstype.c | 4 +- fs/jfs/jfs_logmgr.c | 17 ++--- fs/logfs/dev_bdev.c | 4 +- fs/nilfs2/super.c | 4 +- fs/ocfs2/cluster/heartbeat.c | 2 +- fs/partitions/check.c | 2 +- fs/reiserfs/journal.c | 17 ++--- fs/super.c | 14 ++-- fs/xfs/linux-2.6/xfs_super.c | 2 +- include/linux/fs.h | 14 ++-- kernel/power/swap.c | 5 +- mm/swapfile.c | 7 +- 26 files changed, 162 insertions(+), 318 deletions(-) diff --git a/block/ioctl.c b/block/ioctl.c index d724ceb1d465..cc46d499fd27 100644 --- a/block/ioctl.c +++ b/block/ioctl.c @@ -294,11 +294,12 @@ int blkdev_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd, return -EINVAL; if (get_user(n, (int __user *) arg)) return -EFAULT; - if (!(mode & FMODE_EXCL) && bd_claim(bdev, &bdev) < 0) + if (!(mode & FMODE_EXCL) && + blkdev_get(bdev, mode | FMODE_EXCL, &bdev) < 0) return -EBUSY; ret = set_blocksize(bdev, n); if (!(mode & FMODE_EXCL)) - bd_release(bdev); + blkdev_put(bdev, mode | FMODE_EXCL); return ret; case BLKPG: ret = blkpg_ioctl(bdev, (struct blkpg_ioctl_arg __user *) arg); diff --git a/drivers/block/drbd/drbd_int.h b/drivers/block/drbd/drbd_int.h index 9bdcf4393c0a..0590b9f67ec6 100644 --- a/drivers/block/drbd/drbd_int.h +++ b/drivers/block/drbd/drbd_int.h @@ -923,8 +923,6 @@ struct drbd_md { struct drbd_backing_dev { struct block_device *backing_bdev; struct block_device *md_bdev; - struct file *lo_file; - struct file *md_file; struct drbd_md md; struct disk_conf dc; /* The user provided config... */ sector_t known_size; /* last known size of that backing device */ diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c index 25c7a73c5062..7ec1a82064a9 100644 --- a/drivers/block/drbd/drbd_main.c +++ b/drivers/block/drbd/drbd_main.c @@ -3361,11 +3361,8 @@ void drbd_free_bc(struct drbd_backing_dev *ldev) if (ldev == NULL) return; - bd_release(ldev->backing_bdev); - bd_release(ldev->md_bdev); - - fput(ldev->lo_file); - fput(ldev->md_file); + blkdev_put(ldev->backing_bdev, FMODE_READ | FMODE_WRITE | FMODE_EXCL); + blkdev_put(ldev->md_bdev, FMODE_READ | FMODE_WRITE | FMODE_EXCL); kfree(ldev); } diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c index 87925e97e613..fd0346090289 100644 --- a/drivers/block/drbd/drbd_nl.c +++ b/drivers/block/drbd/drbd_nl.c @@ -855,7 +855,7 @@ static int drbd_nl_disk_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp sector_t max_possible_sectors; sector_t min_md_device_sectors; struct drbd_backing_dev *nbc = NULL; /* new_backing_conf */ - struct inode *inode, *inode2; + struct block_device *bdev; struct lru_cache *resync_lru = NULL; union drbd_state ns, os; unsigned int max_seg_s; @@ -902,46 +902,40 @@ static int drbd_nl_disk_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp } } - nbc->lo_file = filp_open(nbc->dc.backing_dev, O_RDWR, 0); - if (IS_ERR(nbc->lo_file)) { + bdev = open_bdev_exclusive(nbc->dc.backing_dev, + FMODE_READ | FMODE_WRITE, mdev); + if (IS_ERR(bdev)) { dev_err(DEV, "open(\"%s\") failed with %ld\n", nbc->dc.backing_dev, - PTR_ERR(nbc->lo_file)); - nbc->lo_file = NULL; + PTR_ERR(bdev)); retcode = ERR_OPEN_DISK; goto fail; } + nbc->backing_bdev = bdev; - inode = nbc->lo_file->f_dentry->d_inode; - - if (!S_ISBLK(inode->i_mode)) { - retcode = ERR_DISK_NOT_BDEV; - goto fail; - } - - nbc->md_file = filp_open(nbc->dc.meta_dev, O_RDWR, 0); - if (IS_ERR(nbc->md_file)) { + /* + * meta_dev_idx >= 0: external fixed size, possibly multiple + * drbd sharing one meta device. TODO in that case, paranoia + * check that [md_bdev, meta_dev_idx] is not yet used by some + * other drbd minor! (if you use drbd.conf + drbdadm, that + * should check it for you already; but if you don't, or + * someone fooled it, we need to double check here) + */ + bdev = open_bdev_exclusive(nbc->dc.meta_dev, + FMODE_READ | FMODE_WRITE, + (nbc->dc.meta_dev_idx < 0) ? + (void *)mdev : (void *)drbd_m_holder); + if (IS_ERR(bdev)) { dev_err(DEV, "open(\"%s\") failed with %ld\n", nbc->dc.meta_dev, - PTR_ERR(nbc->md_file)); - nbc->md_file = NULL; + PTR_ERR(bdev)); retcode = ERR_OPEN_MD_DISK; goto fail; } + nbc->md_bdev = bdev; - inode2 = nbc->md_file->f_dentry->d_inode; - - if (!S_ISBLK(inode2->i_mode)) { - retcode = ERR_MD_NOT_BDEV; - goto fail; - } - - nbc->backing_bdev = inode->i_bdev; - if (bd_claim(nbc->backing_bdev, mdev)) { - printk(KERN_ERR "drbd: bd_claim(%p,%p); failed [%p;%p;%u]\n", - nbc->backing_bdev, mdev, - nbc->backing_bdev->bd_holder, - nbc->backing_bdev->bd_contains->bd_holder, - nbc->backing_bdev->bd_holders); - retcode = ERR_BDCLAIM_DISK; + if ((nbc->backing_bdev == nbc->md_bdev) != + (nbc->dc.meta_dev_idx == DRBD_MD_INDEX_INTERNAL || + nbc->dc.meta_dev_idx == DRBD_MD_INDEX_FLEX_INT)) { + retcode = ERR_MD_IDX_INVALID; goto fail; } @@ -950,28 +944,7 @@ static int drbd_nl_disk_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp offsetof(struct bm_extent, lce)); if (!resync_lru) { retcode = ERR_NOMEM; - goto release_bdev_fail; - } - - /* meta_dev_idx >= 0: external fixed size, - * possibly multiple drbd sharing one meta device. - * TODO in that case, paranoia check that [md_bdev, meta_dev_idx] is - * not yet used by some other drbd minor! - * (if you use drbd.conf + drbdadm, - * that should check it for you already; but if you don't, or someone - * fooled it, we need to double check here) */ - nbc->md_bdev = inode2->i_bdev; - if (bd_claim(nbc->md_bdev, (nbc->dc.meta_dev_idx < 0) ? (void *)mdev - : (void *) drbd_m_holder)) { - retcode = ERR_BDCLAIM_MD_DISK; - goto release_bdev_fail; - } - - if ((nbc->backing_bdev == nbc->md_bdev) != - (nbc->dc.meta_dev_idx == DRBD_MD_INDEX_INTERNAL || - nbc->dc.meta_dev_idx == DRBD_MD_INDEX_FLEX_INT)) { - retcode = ERR_MD_IDX_INVALID; - goto release_bdev2_fail; + goto fail; } /* RT - for drbd_get_max_capacity() DRBD_MD_INDEX_FLEX_INT */ @@ -982,7 +955,7 @@ static int drbd_nl_disk_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp (unsigned long long) drbd_get_max_capacity(nbc), (unsigned long long) nbc->dc.disk_size); retcode = ERR_DISK_TO_SMALL; - goto release_bdev2_fail; + goto fail; } if (nbc->dc.meta_dev_idx < 0) { @@ -999,7 +972,7 @@ static int drbd_nl_disk_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp dev_warn(DEV, "refusing attach: md-device too small, " "at least %llu sectors needed for this meta-disk type\n", (unsigned long long) min_md_device_sectors); - goto release_bdev2_fail; + goto fail; } /* Make sure the new disk is big enough @@ -1007,7 +980,7 @@ static int drbd_nl_disk_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp if (drbd_get_max_capacity(nbc) < drbd_get_capacity(mdev->this_bdev)) { retcode = ERR_DISK_TO_SMALL; - goto release_bdev2_fail; + goto fail; } nbc->known_size = drbd_get_capacity(nbc->backing_bdev); @@ -1030,7 +1003,7 @@ static int drbd_nl_disk_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp retcode = _drbd_request_state(mdev, NS(disk, D_ATTACHING), CS_VERBOSE); drbd_resume_io(mdev); if (retcode < SS_SUCCESS) - goto release_bdev2_fail; + goto fail; if (!get_ldev_if_state(mdev, D_ATTACHING)) goto force_diskless; @@ -1264,18 +1237,14 @@ static int drbd_nl_disk_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp force_diskless: drbd_force_state(mdev, NS(disk, D_DISKLESS)); drbd_md_sync(mdev); - release_bdev2_fail: - if (nbc) - bd_release(nbc->md_bdev); - release_bdev_fail: - if (nbc) - bd_release(nbc->backing_bdev); fail: if (nbc) { - if (nbc->lo_file) - fput(nbc->lo_file); - if (nbc->md_file) - fput(nbc->md_file); + if (nbc->backing_bdev) + blkdev_put(nbc->backing_bdev, + FMODE_READ | FMODE_WRITE | FMODE_EXCL); + if (nbc->md_bdev) + blkdev_put(nbc->md_bdev, + FMODE_READ | FMODE_WRITE | FMODE_EXCL); kfree(nbc); } lc_destroy(resync_lru); diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c index 19b3568e9326..77d70eebb6b2 100644 --- a/drivers/block/pktcdvd.c +++ b/drivers/block/pktcdvd.c @@ -2296,15 +2296,12 @@ static int pkt_open_dev(struct pktcdvd_device *pd, fmode_t write) * so bdget() can't fail. */ bdget(pd->bdev->bd_dev); - if ((ret = blkdev_get(pd->bdev, FMODE_READ))) + if ((ret = blkdev_get(pd->bdev, FMODE_READ | FMODE_EXCL, pd))) goto out; - if ((ret = bd_claim(pd->bdev, pd))) - goto out_putdev; - if ((ret = pkt_get_last_written(pd, &lba))) { printk(DRIVER_NAME": pkt_get_last_written failed\n"); - goto out_unclaim; + goto out_putdev; } set_capacity(pd->disk, lba << 2); @@ -2314,7 +2311,7 @@ static int pkt_open_dev(struct pktcdvd_device *pd, fmode_t write) q = bdev_get_queue(pd->bdev); if (write) { if ((ret = pkt_open_write(pd))) - goto out_unclaim; + goto out_putdev; /* * Some CDRW drives can not handle writes larger than one packet, * even if the size is a multiple of the packet size. @@ -2329,23 +2326,21 @@ static int pkt_open_dev(struct pktcdvd_device *pd, fmode_t write) } if ((ret = pkt_set_segment_merging(pd, q))) - goto out_unclaim; + goto out_putdev; if (write) { if (!pkt_grow_pktlist(pd, CONFIG_CDROM_PKTCDVD_BUFFERS)) { printk(DRIVER_NAME": not enough memory for buffers\n"); ret = -ENOMEM; - goto out_unclaim; + goto out_putdev; } printk(DRIVER_NAME": %lukB available on disc\n", lba << 1); } return 0; -out_unclaim: - bd_release(pd->bdev); out_putdev: - blkdev_put(pd->bdev, FMODE_READ); + blkdev_put(pd->bdev, FMODE_READ | FMODE_EXCL); out: return ret; } @@ -2362,8 +2357,7 @@ static void pkt_release_dev(struct pktcdvd_device *pd, int flush) pkt_lock_door(pd, 0); pkt_set_speed(pd, MAX_SPEED, MAX_SPEED); - bd_release(pd->bdev); - blkdev_put(pd->bdev, FMODE_READ); + blkdev_put(pd->bdev, FMODE_READ | FMODE_EXCL); pkt_shrink_pktlist(pd); } @@ -2733,7 +2727,7 @@ static int pkt_new_dev(struct pktcdvd_device *pd, dev_t dev) bdev = bdget(dev); if (!bdev) return -ENOMEM; - ret = blkdev_get(bdev, FMODE_READ | FMODE_NDELAY); + ret = blkdev_get(bdev, FMODE_READ | FMODE_NDELAY, NULL); if (ret) return ret; diff --git a/drivers/char/raw.c b/drivers/char/raw.c index bfe25ea9766b..b4b9d5a47885 100644 --- a/drivers/char/raw.c +++ b/drivers/char/raw.c @@ -65,15 +65,12 @@ static int raw_open(struct inode *inode, struct file *filp) if (!bdev) goto out; igrab(bdev->bd_inode); - err = blkdev_get(bdev, filp->f_mode); + err = blkdev_get(bdev, filp->f_mode | FMODE_EXCL, raw_open); if (err) goto out; - err = bd_claim(bdev, raw_open); - if (err) - goto out1; err = set_blocksize(bdev, bdev_logical_block_size(bdev)); if (err) - goto out2; + goto out1; filp->f_flags |= O_DIRECT; filp->f_mapping = bdev->bd_inode->i_mapping; if (++raw_devices[minor].inuse == 1) @@ -83,10 +80,8 @@ static int raw_open(struct inode *inode, struct file *filp) mutex_unlock(&raw_mutex); return 0; -out2: - bd_release(bdev); out1: - blkdev_put(bdev, filp->f_mode); + blkdev_put(bdev, filp->f_mode | FMODE_EXCL); out: mutex_unlock(&raw_mutex); return err; @@ -110,8 +105,7 @@ static int raw_release(struct inode *inode, struct file *filp) } mutex_unlock(&raw_mutex); - bd_release(bdev); - blkdev_put(bdev, filp->f_mode); + blkdev_put(bdev, filp->f_mode | FMODE_EXCL); return 0; } diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c index 2c876ffc63df..9e88ca0c55e9 100644 --- a/drivers/md/dm-table.c +++ b/drivers/md/dm-table.c @@ -325,20 +325,13 @@ static int open_dev(struct dm_dev_internal *d, dev_t dev, BUG_ON(d->dm_dev.bdev); - bdev = open_by_devnum(dev, d->dm_dev.mode); + bdev = open_by_devnum(dev, d->dm_dev.mode | FMODE_EXCL, _claim_ptr); if (IS_ERR(bdev)) return PTR_ERR(bdev); - r = bd_claim(bdev, _claim_ptr); - if (r) { - blkdev_put(bdev, d->dm_dev.mode); - return r; - } - r = bd_link_disk_holder(bdev, dm_disk(md)); if (r) { - bd_release(bdev); - blkdev_put(bdev, d->dm_dev.mode); + blkdev_put(bdev, d->dm_dev.mode | FMODE_EXCL); return r; } @@ -354,9 +347,7 @@ static void close_dev(struct dm_dev_internal *d, struct mapped_device *md) if (!d->dm_dev.bdev) return; - bd_unlink_disk_holder(d->dm_dev.bdev); - bd_release(d->dm_dev.bdev); - blkdev_put(d->dm_dev.bdev, d->dm_dev.mode); + blkdev_put(d->dm_dev.bdev, d->dm_dev.mode | FMODE_EXCL); d->dm_dev.bdev = NULL; } diff --git a/drivers/md/md.c b/drivers/md/md.c index c47644fca1a1..6af951ffe0bb 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -1907,7 +1907,6 @@ static void unbind_rdev_from_array(mdk_rdev_t * rdev) MD_BUG(); return; } - bd_unlink_disk_holder(rdev->bdev); list_del_rcu(&rdev->same_set); printk(KERN_INFO "md: unbind<%s>\n", bdevname(rdev->bdev,b)); rdev->mddev = NULL; @@ -1935,19 +1934,13 @@ static int lock_rdev(mdk_rdev_t *rdev, dev_t dev, int shared) struct block_device *bdev; char b[BDEVNAME_SIZE]; - bdev = open_by_devnum(dev, FMODE_READ|FMODE_WRITE); + bdev = open_by_devnum(dev, FMODE_READ|FMODE_WRITE|FMODE_EXCL, + shared ? (mdk_rdev_t *)lock_rdev : rdev); if (IS_ERR(bdev)) { printk(KERN_ERR "md: could not open %s.\n", __bdevname(dev, b)); return PTR_ERR(bdev); } - err = bd_claim(bdev, shared ? (mdk_rdev_t *)lock_rdev : rdev); - if (err) { - printk(KERN_ERR "md: could not bd_claim %s.\n", - bdevname(bdev, b)); - blkdev_put(bdev, FMODE_READ|FMODE_WRITE); - return err; - } if (!shared) set_bit(AllReserved, &rdev->flags); rdev->bdev = bdev; @@ -1960,8 +1953,7 @@ static void unlock_rdev(mdk_rdev_t *rdev) rdev->bdev = NULL; if (!bdev) MD_BUG(); - bd_release(bdev); - blkdev_put(bdev, FMODE_READ|FMODE_WRITE); + blkdev_put(bdev, FMODE_READ|FMODE_WRITE|FMODE_EXCL); } void md_autodetect_dev(dev_t dev); diff --git a/drivers/mtd/devices/block2mtd.c b/drivers/mtd/devices/block2mtd.c index a9e2d3b38aeb..aa557beb8f51 100644 --- a/drivers/mtd/devices/block2mtd.c +++ b/drivers/mtd/devices/block2mtd.c @@ -224,7 +224,7 @@ static void block2mtd_free_device(struct block2mtd_dev *dev) if (dev->blkdev) { invalidate_mapping_pages(dev->blkdev->bd_inode->i_mapping, 0, -1); - close_bdev_exclusive(dev->blkdev, FMODE_READ|FMODE_WRITE); + blkdev_put(dev->blkdev, FMODE_READ|FMODE_WRITE|FMODE_EXCL); } kfree(dev); @@ -234,7 +234,7 @@ static void block2mtd_free_device(struct block2mtd_dev *dev) /* FIXME: ensure that mtd->size % erase_size == 0 */ static struct block2mtd_dev *add_device(char *devname, int erase_size) { - const fmode_t mode = FMODE_READ | FMODE_WRITE; + const fmode_t mode = FMODE_READ | FMODE_WRITE | FMODE_EXCL; struct block_device *bdev; struct block2mtd_dev *dev; char *name; @@ -255,17 +255,8 @@ static struct block2mtd_dev *add_device(char *devname, int erase_size) to resolve the device name by other means. */ dev_t devt = name_to_dev_t(devname); - if (devt) { - bdev = open_by_devnum(devt, mode); - if (!IS_ERR(bdev)) { - int ret; - ret = bd_claim(bdev, dev); - if (ret) { - blkdev_put(bdev, mode); - bdev = ERR_PTR(ret); - } - } - } + if (devt) + bdev = open_by_devnum(devt, mode, dev); } #endif diff --git a/drivers/s390/block/dasd_genhd.c b/drivers/s390/block/dasd_genhd.c index 30a1ca3d08b7..5505bc07e1e7 100644 --- a/drivers/s390/block/dasd_genhd.c +++ b/drivers/s390/block/dasd_genhd.c @@ -103,7 +103,7 @@ int dasd_scan_partitions(struct dasd_block *block) struct block_device *bdev; bdev = bdget_disk(block->gdp, 0); - if (!bdev || blkdev_get(bdev, FMODE_READ) < 0) + if (!bdev || blkdev_get(bdev, FMODE_READ, NULL) < 0) return -ENODEV; /* * See fs/partition/check.c:register_disk,rescan_partitions diff --git a/fs/block_dev.c b/fs/block_dev.c index 9329068684d2..fc48912354d1 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c @@ -660,7 +660,7 @@ static bool bd_may_claim(struct block_device *bdev, struct block_device *whole, else if (bdev->bd_contains == bdev) return true; /* is a whole device which isn't held */ - else if (whole->bd_holder == bd_claim) + else if (whole->bd_holder == bd_may_claim) return true; /* is a partition of a device that is being partitioned */ else if (whole->bd_holder != NULL) return false; /* is a partition of a held device */ @@ -807,10 +807,10 @@ static void __bd_claim(struct block_device *bdev, struct block_device *whole, { /* note that for a whole device bd_holders * will be incremented twice, and bd_holder will - * be set to bd_claim before being set to holder + * be set to bd_may_claim before being set to holder */ whole->bd_holders++; - whole->bd_holder = bd_claim; + whole->bd_holder = bd_may_claim; bdev->bd_holders++; bdev->bd_holder = holder; } @@ -835,37 +835,7 @@ static void bd_finish_claiming(struct block_device *bdev, __bd_abort_claiming(whole, holder); /* not actually an abort */ } -/** - * bd_claim - claim a block device - * @bdev: block device to claim - * @holder: holder trying to claim @bdev - * - * Try to claim @bdev which must have been opened successfully. - * - * CONTEXT: - * Might sleep. - * - * RETURNS: - * 0 if successful, -EBUSY if @bdev is already claimed. - */ -int bd_claim(struct block_device *bdev, void *holder) -{ - struct block_device *whole = bdev->bd_contains; - int res; - - might_sleep(); - - spin_lock(&bdev_lock); - res = bd_prepare_to_claim(bdev, whole, holder); - if (res == 0) - __bd_claim(bdev, whole, holder); - spin_unlock(&bdev_lock); - - return res; -} -EXPORT_SYMBOL(bd_claim); - -void bd_release(struct block_device *bdev) +static void bd_release(struct block_device *bdev) { spin_lock(&bdev_lock); if (!--bdev->bd_contains->bd_holders) @@ -875,8 +845,6 @@ void bd_release(struct block_device *bdev) spin_unlock(&bdev_lock); } -EXPORT_SYMBOL(bd_release); - #ifdef CONFIG_SYSFS static int add_symlink(struct kobject *from, struct kobject *to) { @@ -943,7 +911,7 @@ out_unlock: } EXPORT_SYMBOL_GPL(bd_link_disk_holder); -void bd_unlink_disk_holder(struct block_device *bdev) +static void bd_unlink_disk_holder(struct block_device *bdev) { struct gendisk *disk = bdev->bd_holder_disk; @@ -954,7 +922,9 @@ void bd_unlink_disk_holder(struct block_device *bdev) del_symlink(disk->slave_dir, &part_to_dev(bdev->bd_part)->kobj); del_symlink(bdev->bd_part->holder_dir, &disk_to_dev(disk)->kobj); } -EXPORT_SYMBOL_GPL(bd_unlink_disk_holder); +#else +static inline void bd_unlink_disk_holder(struct block_device *bdev) +{ } #endif /* @@ -964,12 +934,12 @@ EXPORT_SYMBOL_GPL(bd_unlink_disk_holder); * to be used for internal purposes. If you ever need it - reconsider * your API. */ -struct block_device *open_by_devnum(dev_t dev, fmode_t mode) +struct block_device *open_by_devnum(dev_t dev, fmode_t mode, void *holder) { struct block_device *bdev = bdget(dev); int err = -ENOMEM; if (bdev) - err = blkdev_get(bdev, mode); + err = blkdev_get(bdev, mode, holder); return err ? ERR_PTR(err) : bdev; } @@ -1235,17 +1205,37 @@ static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part) return ret; } -int blkdev_get(struct block_device *bdev, fmode_t mode) +int blkdev_get(struct block_device *bdev, fmode_t mode, void *holder) { - return __blkdev_get(bdev, mode, 0); + struct block_device *whole = NULL; + int res; + + WARN_ON_ONCE((mode & FMODE_EXCL) && !holder); + + if ((mode & FMODE_EXCL) && holder) { + whole = bd_start_claiming(bdev, holder); + if (IS_ERR(whole)) { + bdput(bdev); + return PTR_ERR(whole); + } + } + + res = __blkdev_get(bdev, mode, 0); + + if (whole) { + if (res == 0) + bd_finish_claiming(bdev, whole, holder); + else + bd_abort_claiming(whole, holder); + } + + return res; } EXPORT_SYMBOL(blkdev_get); static int blkdev_open(struct inode * inode, struct file * filp) { - struct block_device *whole = NULL; struct block_device *bdev; - int res; /* * Preserve backwards compatibility and allow large file access @@ -1266,26 +1256,9 @@ static int blkdev_open(struct inode * inode, struct file * filp) if (bdev == NULL) return -ENOMEM; - if (filp->f_mode & FMODE_EXCL) { - whole = bd_start_claiming(bdev, filp); - if (IS_ERR(whole)) { - bdput(bdev); - return PTR_ERR(whole); - } - } - filp->f_mapping = bdev->bd_inode->i_mapping; - res = blkdev_get(bdev, filp->f_mode); - - if (whole) { - if (res == 0) - bd_finish_claiming(bdev, whole, filp); - else - bd_abort_claiming(whole, filp); - } - - return res; + return blkdev_get(bdev, filp->f_mode, filp); } static int __blkdev_put(struct block_device *bdev, fmode_t mode, int for_part) @@ -1329,6 +1302,13 @@ static int __blkdev_put(struct block_device *bdev, fmode_t mode, int for_part) int blkdev_put(struct block_device *bdev, fmode_t mode) { + if (mode & FMODE_EXCL) { + mutex_lock(&bdev->bd_mutex); + bd_release(bdev); + if (!bdev->bd_holders) + bd_unlink_disk_holder(bdev); + mutex_unlock(&bdev->bd_mutex); + } return __blkdev_put(bdev, mode, 0); } EXPORT_SYMBOL(blkdev_put); @@ -1336,8 +1316,7 @@ EXPORT_SYMBOL(blkdev_put); static int blkdev_close(struct inode * inode, struct file * filp) { struct block_device *bdev = I_BDEV(filp->f_mapping->host); - if (bdev->bd_holder == filp) - bd_release(bdev); + return blkdev_put(bdev, filp->f_mode); } @@ -1494,55 +1473,27 @@ EXPORT_SYMBOL(lookup_bdev); */ struct block_device *open_bdev_exclusive(const char *path, fmode_t mode, void *holder) { - struct block_device *bdev, *whole; + struct block_device *bdev; int error; bdev = lookup_bdev(path); if (IS_ERR(bdev)) return bdev; - whole = bd_start_claiming(bdev, holder); - if (IS_ERR(whole)) { - bdput(bdev); - return whole; - } - - error = blkdev_get(bdev, mode); + error = blkdev_get(bdev, mode | FMODE_EXCL, holder); if (error) - goto out_abort_claiming; + return ERR_PTR(error); - error = -EACCES; - if ((mode & FMODE_WRITE) && bdev_read_only(bdev)) - goto out_blkdev_put; + if ((mode & FMODE_WRITE) && bdev_read_only(bdev)) { + blkdev_put(bdev, mode); + return ERR_PTR(-EACCES); + } - bd_finish_claiming(bdev, whole, holder); return bdev; - -out_blkdev_put: - blkdev_put(bdev, mode); -out_abort_claiming: - bd_abort_claiming(whole, holder); - return ERR_PTR(error); } EXPORT_SYMBOL(open_bdev_exclusive); -/** - * close_bdev_exclusive - close a blockdevice opened by open_bdev_exclusive() - * - * @bdev: blockdevice to close - * @mode: mode, must match that used to open. - * - * This is the counterpart to open_bdev_exclusive(). - */ -void close_bdev_exclusive(struct block_device *bdev, fmode_t mode) -{ - bd_release(bdev); - blkdev_put(bdev, mode); -} - -EXPORT_SYMBOL(close_bdev_exclusive); - int __invalidate_device(struct block_device *bdev) { struct super_block *sb = get_super(bdev); diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index d39596224d21..f1b729d3b883 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c @@ -489,7 +489,7 @@ again: continue; if (device->bdev) { - close_bdev_exclusive(device->bdev, device->mode); + blkdev_put(device->bdev, device->mode | FMODE_EXCL); device->bdev = NULL; fs_devices->open_devices--; } @@ -523,7 +523,7 @@ static int __btrfs_close_devices(struct btrfs_fs_devices *fs_devices) list_for_each_entry(device, &fs_devices->devices, dev_list) { if (device->bdev) { - close_bdev_exclusive(device->bdev, device->mode); + blkdev_put(device->bdev, device->mode | FMODE_EXCL); fs_devices->open_devices--; } if (device->writeable) { @@ -638,7 +638,7 @@ static int __btrfs_open_devices(struct btrfs_fs_devices *fs_devices, error_brelse: brelse(bh); error_close: - close_bdev_exclusive(bdev, flags); + blkdev_put(bdev, flags | FMODE_EXCL); error: continue; } @@ -716,7 +716,7 @@ int btrfs_scan_one_device(const char *path, fmode_t flags, void *holder, brelse(bh); error_close: - close_bdev_exclusive(bdev, flags); + blkdev_put(bdev, flags | FMODE_EXCL); error: mutex_unlock(&uuid_mutex); return ret; @@ -1244,7 +1244,7 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path) root->fs_info->fs_devices->latest_bdev = next_device->bdev; if (device->bdev) { - close_bdev_exclusive(device->bdev, device->mode); + blkdev_put(device->bdev, device->mode | FMODE_EXCL); device->bdev = NULL; device->fs_devices->open_devices--; } @@ -1287,7 +1287,7 @@ error_brelse: brelse(bh); error_close: if (bdev) - close_bdev_exclusive(bdev, FMODE_READ); + blkdev_put(bdev, FMODE_READ | FMODE_EXCL); out: mutex_unlock(&root->fs_info->volume_mutex); mutex_unlock(&uuid_mutex); @@ -1565,7 +1565,7 @@ out: mutex_unlock(&root->fs_info->volume_mutex); return ret; error: - close_bdev_exclusive(bdev, 0); + blkdev_put(bdev, FMODE_EXCL); if (seeding_dev) { mutex_unlock(&uuid_mutex); up_write(&sb->s_umount); diff --git a/fs/ext3/super.c b/fs/ext3/super.c index 2fedaf8b5012..23e7513dba9c 100644 --- a/fs/ext3/super.c +++ b/fs/ext3/super.c @@ -347,7 +347,7 @@ static struct block_device *ext3_blkdev_get(dev_t dev, struct super_block *sb) struct block_device *bdev; char b[BDEVNAME_SIZE]; - bdev = open_by_devnum(dev, FMODE_READ|FMODE_WRITE); + bdev = open_by_devnum(dev, FMODE_READ|FMODE_WRITE|FMODE_EXCL, sb); if (IS_ERR(bdev)) goto fail; return bdev; @@ -364,8 +364,7 @@ fail: */ static int ext3_blkdev_put(struct block_device *bdev) { - bd_release(bdev); - return blkdev_put(bdev, FMODE_READ|FMODE_WRITE); + return blkdev_put(bdev, FMODE_READ|FMODE_WRITE|FMODE_EXCL); } static int ext3_blkdev_remove(struct ext3_sb_info *sbi) @@ -2136,13 +2135,6 @@ static journal_t *ext3_get_dev_journal(struct super_block *sb, if (bdev == NULL) return NULL; - if (bd_claim(bdev, sb)) { - ext3_msg(sb, KERN_ERR, - "error: failed to claim external journal device"); - blkdev_put(bdev, FMODE_READ|FMODE_WRITE); - return NULL; - } - blocksize = sb->s_blocksize; hblock = bdev_logical_block_size(bdev); if (blocksize < hblock) { diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 61182fe6254e..5dd0b3e76fa8 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -647,7 +647,7 @@ static struct block_device *ext4_blkdev_get(dev_t dev, struct super_block *sb) struct block_device *bdev; char b[BDEVNAME_SIZE]; - bdev = open_by_devnum(dev, FMODE_READ|FMODE_WRITE); + bdev = open_by_devnum(dev, FMODE_READ|FMODE_WRITE|FMODE_EXCL, sb); if (IS_ERR(bdev)) goto fail; return bdev; @@ -663,8 +663,7 @@ fail: */ static int ext4_blkdev_put(struct block_device *bdev) { - bd_release(bdev); - return blkdev_put(bdev, FMODE_READ|FMODE_WRITE); + return blkdev_put(bdev, FMODE_READ|FMODE_WRITE|FMODE_EXCL); } static int ext4_blkdev_remove(struct ext4_sb_info *sbi) @@ -3758,13 +3757,6 @@ static journal_t *ext4_get_dev_journal(struct super_block *sb, if (bdev == NULL) return NULL; - if (bd_claim(bdev, sb)) { - ext4_msg(sb, KERN_ERR, - "failed to claim external journal device"); - blkdev_put(bdev, FMODE_READ|FMODE_WRITE); - return NULL; - } - blocksize = sb->s_blocksize; hblock = bdev_logical_block_size(bdev); if (blocksize < hblock) { diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c index 3eb1393f7b81..c1f0763a022b 100644 --- a/fs/gfs2/ops_fstype.c +++ b/fs/gfs2/ops_fstype.c @@ -1298,7 +1298,7 @@ static struct dentry *gfs2_mount(struct file_system_type *fs_type, int flags, goto error_bdev; if (s->s_root) - close_bdev_exclusive(bdev, mode); + blkdev_put(bdev, mode | FMODE_EXCL); memset(&args, 0, sizeof(args)); args.ar_quota = GFS2_QUOTA_DEFAULT; @@ -1342,7 +1342,7 @@ error_super: deactivate_locked_super(s); return ERR_PTR(error); error_bdev: - close_bdev_exclusive(bdev, mode); + blkdev_put(bdev, mode | FMODE_EXCL); return ERR_PTR(error); } diff --git a/fs/jfs/jfs_logmgr.c b/fs/jfs/jfs_logmgr.c index e1b8493b9aaa..5a290f22dcc3 100644 --- a/fs/jfs/jfs_logmgr.c +++ b/fs/jfs/jfs_logmgr.c @@ -1120,16 +1120,13 @@ int lmLogOpen(struct super_block *sb) * file systems to log may have n-to-1 relationship; */ - bdev = open_by_devnum(sbi->logdev, FMODE_READ|FMODE_WRITE); + bdev = open_by_devnum(sbi->logdev, FMODE_READ|FMODE_WRITE|FMODE_EXCL, + log); if (IS_ERR(bdev)) { rc = -PTR_ERR(bdev); goto free; } - if ((rc = bd_claim(bdev, log))) { - goto close; - } - log->bdev = bdev; memcpy(log->uuid, sbi->loguuid, sizeof(log->uuid)); @@ -1137,7 +1134,7 @@ int lmLogOpen(struct super_block *sb) * initialize log: */ if ((rc = lmLogInit(log))) - goto unclaim; + goto close; list_add(&log->journal_list, &jfs_external_logs); @@ -1163,11 +1160,8 @@ journal_found: list_del(&log->journal_list); lbmLogShutdown(log); - unclaim: - bd_release(bdev); - close: /* close external log device */ - blkdev_put(bdev, FMODE_READ|FMODE_WRITE); + blkdev_put(bdev, FMODE_READ|FMODE_WRITE|FMODE_EXCL); free: /* free log descriptor */ mutex_unlock(&jfs_log_mutex); @@ -1512,8 +1506,7 @@ int lmLogClose(struct super_block *sb) bdev = log->bdev; rc = lmLogShutdown(log); - bd_release(bdev); - blkdev_put(bdev, FMODE_READ|FMODE_WRITE); + blkdev_put(bdev, FMODE_READ|FMODE_WRITE|FMODE_EXCL); kfree(log); diff --git a/fs/logfs/dev_bdev.c b/fs/logfs/dev_bdev.c index 92ca6fbe09bd..734b9025858e 100644 --- a/fs/logfs/dev_bdev.c +++ b/fs/logfs/dev_bdev.c @@ -300,7 +300,7 @@ static int bdev_write_sb(struct super_block *sb, struct page *page) static void bdev_put_device(struct logfs_super *s) { - close_bdev_exclusive(s->s_bdev, FMODE_READ|FMODE_WRITE); + blkdev_put(s->s_bdev, FMODE_READ|FMODE_WRITE|FMODE_EXCL); } static int bdev_can_write_buf(struct super_block *sb, u64 ofs) @@ -331,7 +331,7 @@ int logfs_get_sb_bdev(struct logfs_super *p, struct file_system_type *type, if (MAJOR(bdev->bd_dev) == MTD_BLOCK_MAJOR) { int mtdnr = MINOR(bdev->bd_dev); - close_bdev_exclusive(bdev, FMODE_READ|FMODE_WRITE); + blkdev_put(bdev, FMODE_READ|FMODE_WRITE|FMODE_EXCL); return logfs_get_sb_mtd(p, mtdnr); } diff --git a/fs/nilfs2/super.c b/fs/nilfs2/super.c index f804d41ec9d3..756a6798d7c8 100644 --- a/fs/nilfs2/super.c +++ b/fs/nilfs2/super.c @@ -1233,7 +1233,7 @@ nilfs_mount(struct file_system_type *fs_type, int flags, } if (!s_new) - close_bdev_exclusive(sd.bdev, mode); + blkdev_put(sd.bdev, mode | FMODE_EXCL); return root_dentry; @@ -1242,7 +1242,7 @@ nilfs_mount(struct file_system_type *fs_type, int flags, failed: if (!s_new) - close_bdev_exclusive(sd.bdev, mode); + blkdev_put(sd.bdev, mode | FMODE_EXCL); return ERR_PTR(err); } diff --git a/fs/ocfs2/cluster/heartbeat.c b/fs/ocfs2/cluster/heartbeat.c index 52c7557f3e25..d0a2721eaceb 100644 --- a/fs/ocfs2/cluster/heartbeat.c +++ b/fs/ocfs2/cluster/heartbeat.c @@ -1674,7 +1674,7 @@ static ssize_t o2hb_region_dev_write(struct o2hb_region *reg, goto out; reg->hr_bdev = I_BDEV(filp->f_mapping->host); - ret = blkdev_get(reg->hr_bdev, FMODE_WRITE | FMODE_READ); + ret = blkdev_get(reg->hr_bdev, FMODE_WRITE | FMODE_READ, NULL); if (ret) { reg->hr_bdev = NULL; goto out; diff --git a/fs/partitions/check.c b/fs/partitions/check.c index 0a8b0ad0c7e2..2e6501d034ab 100644 --- a/fs/partitions/check.c +++ b/fs/partitions/check.c @@ -549,7 +549,7 @@ void register_disk(struct gendisk *disk) goto exit; bdev->bd_invalidated = 1; - err = blkdev_get(bdev, FMODE_READ); + err = blkdev_get(bdev, FMODE_READ, NULL); if (err < 0) goto exit; blkdev_put(bdev, FMODE_READ); diff --git a/fs/reiserfs/journal.c b/fs/reiserfs/journal.c index 076c8b194682..b488136f5ace 100644 --- a/fs/reiserfs/journal.c +++ b/fs/reiserfs/journal.c @@ -2552,8 +2552,6 @@ static int release_journal_dev(struct super_block *super, result = 0; if (journal->j_dev_bd != NULL) { - if (journal->j_dev_bd->bd_dev != super->s_dev) - bd_release(journal->j_dev_bd); result = blkdev_put(journal->j_dev_bd, journal->j_dev_mode); journal->j_dev_bd = NULL; } @@ -2571,7 +2569,7 @@ static int journal_init_dev(struct super_block *super, { int result; dev_t jdev; - fmode_t blkdev_mode = FMODE_READ | FMODE_WRITE; + fmode_t blkdev_mode = FMODE_READ | FMODE_WRITE | FMODE_EXCL; char b[BDEVNAME_SIZE]; result = 0; @@ -2585,7 +2583,9 @@ static int journal_init_dev(struct super_block *super, /* there is no "jdev" option and journal is on separate device */ if ((!jdev_name || !jdev_name[0])) { - journal->j_dev_bd = open_by_devnum(jdev, blkdev_mode); + if (jdev == super->s_dev) + blkdev_mode &= ~FMODE_EXCL; + journal->j_dev_bd = open_by_devnum(jdev, blkdev_mode, journal); journal->j_dev_mode = blkdev_mode; if (IS_ERR(journal->j_dev_bd)) { result = PTR_ERR(journal->j_dev_bd); @@ -2594,15 +2594,8 @@ static int journal_init_dev(struct super_block *super, "cannot init journal device '%s': %i", __bdevname(jdev, b), result); return result; - } else if (jdev != super->s_dev) { - result = bd_claim(journal->j_dev_bd, journal); - if (result) { - blkdev_put(journal->j_dev_bd, blkdev_mode); - return result; - } - + } else if (jdev != super->s_dev) set_blocksize(journal->j_dev_bd, super->s_blocksize); - } return 0; } diff --git a/fs/super.c b/fs/super.c index ca696155cd9a..22374bf0ba87 100644 --- a/fs/super.c +++ b/fs/super.c @@ -801,13 +801,13 @@ struct dentry *mount_bdev(struct file_system_type *fs_type, /* * s_umount nests inside bd_mutex during - * __invalidate_device(). close_bdev_exclusive() - * acquires bd_mutex and can't be called under - * s_umount. Drop s_umount temporarily. This is safe - * as we're holding an active reference. + * __invalidate_device(). blkdev_put() acquires + * bd_mutex and can't be called under s_umount. Drop + * s_umount temporarily. This is safe as we're + * holding an active reference. */ up_write(&s->s_umount); - close_bdev_exclusive(bdev, mode); + blkdev_put(bdev, mode | FMODE_EXCL); down_write(&s->s_umount); } else { char b[BDEVNAME_SIZE]; @@ -831,7 +831,7 @@ struct dentry *mount_bdev(struct file_system_type *fs_type, error_s: error = PTR_ERR(s); error_bdev: - close_bdev_exclusive(bdev, mode); + blkdev_put(bdev, mode | FMODE_EXCL); error: return ERR_PTR(error); } @@ -862,7 +862,7 @@ void kill_block_super(struct super_block *sb) bdev->bd_super = NULL; generic_shutdown_super(sb); sync_blockdev(bdev); - close_bdev_exclusive(bdev, mode); + blkdev_put(bdev, mode | FMODE_EXCL); } EXPORT_SYMBOL(kill_block_super); diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c index 9f3a78fe6ae4..a1a6e5ceea67 100644 --- a/fs/xfs/linux-2.6/xfs_super.c +++ b/fs/xfs/linux-2.6/xfs_super.c @@ -623,7 +623,7 @@ xfs_blkdev_put( struct block_device *bdev) { if (bdev) - close_bdev_exclusive(bdev, FMODE_READ|FMODE_WRITE); + blkdev_put(bdev, FMODE_READ|FMODE_WRITE|FMODE_EXCL); } /* diff --git a/include/linux/fs.h b/include/linux/fs.h index 66b7f2c5d7e9..1a033e8ebe4c 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -2006,7 +2006,8 @@ extern struct block_device *bdgrab(struct block_device *bdev); extern void bd_set_size(struct block_device *, loff_t size); extern void bd_forget(struct inode *inode); extern void bdput(struct block_device *); -extern struct block_device *open_by_devnum(dev_t, fmode_t); +extern struct block_device *open_by_devnum(dev_t dev, fmode_t mode, + void *holder); extern void invalidate_bdev(struct block_device *); extern int sync_blockdev(struct block_device *bdev); extern struct super_block *freeze_bdev(struct block_device *); @@ -2037,22 +2038,16 @@ extern const struct file_operations def_fifo_fops; extern int ioctl_by_bdev(struct block_device *, unsigned, unsigned long); extern int blkdev_ioctl(struct block_device *, fmode_t, unsigned, unsigned long); extern long compat_blkdev_ioctl(struct file *, unsigned, unsigned long); -extern int blkdev_get(struct block_device *, fmode_t); -extern int blkdev_put(struct block_device *, fmode_t); -extern int bd_claim(struct block_device *, void *); -extern void bd_release(struct block_device *); +extern int blkdev_get(struct block_device *bdev, fmode_t mode, void *holder); +extern int blkdev_put(struct block_device *bdev, fmode_t mode); #ifdef CONFIG_SYSFS extern int bd_link_disk_holder(struct block_device *bdev, struct gendisk *disk); -extern void bd_unlink_disk_holder(struct block_device *bdev); #else static inline int bd_link_disk_holder(struct block_device *bdev, struct gendisk *disk) { return 0; } -static inline void bd_unlink_disk_holder(struct block_device *bdev) -{ -} #endif #endif @@ -2089,7 +2084,6 @@ extern const char *__bdevname(dev_t, char *buffer); extern const char *bdevname(struct block_device *bdev, char *buffer); extern struct block_device *lookup_bdev(const char *); extern struct block_device *open_bdev_exclusive(const char *, fmode_t, void *); -extern void close_bdev_exclusive(struct block_device *, fmode_t); extern void blkdev_show(struct seq_file *,off_t); #else diff --git a/kernel/power/swap.c b/kernel/power/swap.c index a0e4a86ccf94..513a77f1a0b3 100644 --- a/kernel/power/swap.c +++ b/kernel/power/swap.c @@ -223,7 +223,7 @@ static int swsusp_swap_check(void) return res; root_swap = res; - res = blkdev_get(hib_resume_bdev, FMODE_WRITE); + res = blkdev_get(hib_resume_bdev, FMODE_WRITE, NULL); if (res) return res; @@ -907,7 +907,8 @@ int swsusp_check(void) { int error; - hib_resume_bdev = open_by_devnum(swsusp_resume_device, FMODE_READ); + hib_resume_bdev = open_by_devnum(swsusp_resume_device, + FMODE_READ, NULL); if (!IS_ERR(hib_resume_bdev)) { set_blocksize(hib_resume_bdev, PAGE_SIZE); clear_page(swsusp_header); diff --git a/mm/swapfile.c b/mm/swapfile.c index 67ddaaf98c74..b6adcfbf6f48 100644 --- a/mm/swapfile.c +++ b/mm/swapfile.c @@ -1677,7 +1677,7 @@ SYSCALL_DEFINE1(swapoff, const char __user *, specialfile) if (S_ISBLK(inode->i_mode)) { struct block_device *bdev = I_BDEV(inode); set_blocksize(bdev, p->old_block_size); - bd_release(bdev); + blkdev_put(bdev, FMODE_READ | FMODE_WRITE | FMODE_EXCL); } else { mutex_lock(&inode->i_mutex); inode->i_flags &= ~S_SWAPFILE; @@ -1939,7 +1939,8 @@ SYSCALL_DEFINE2(swapon, const char __user *, specialfile, int, swap_flags) error = -EINVAL; if (S_ISBLK(inode->i_mode)) { bdev = I_BDEV(inode); - error = bd_claim(bdev, sys_swapon); + error = blkdev_get(bdev, FMODE_READ | FMODE_WRITE | FMODE_EXCL, + sys_swapon); if (error < 0) { bdev = NULL; error = -EINVAL; @@ -2136,7 +2137,7 @@ SYSCALL_DEFINE2(swapon, const char __user *, specialfile, int, swap_flags) bad_swap: if (bdev) { set_blocksize(bdev, p->old_block_size); - bd_release(bdev); + blkdev_put(bdev, FMODE_READ | FMODE_WRITE | FMODE_EXCL); } destroy_swap_extents(p); swap_cgroup_swapoff(type); -- cgit v1.2.3 From 6a027eff62f6ae32d49f2ae5dadd6f4eee1ddae2 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sat, 13 Nov 2010 11:55:17 +0100 Subject: block: reorganize claim/release implementation With claim/release rolled into blkdev_get/put(), there's no reason to keep bd_abort/finish_claim(), __bd_claim() and bd_release() as separate functions. It only makes the code difficult to follow. Collapse them into blkdev_get/put(). This will ease future changes around claim/release. Signed-off-by: Tejun Heo --- fs/block_dev.c | 127 ++++++++++++++++++++++----------------------------------- 1 file changed, 48 insertions(+), 79 deletions(-) diff --git a/fs/block_dev.c b/fs/block_dev.c index fc48912354d1..269bfbbd10fc 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c @@ -772,79 +772,6 @@ static struct block_device *bd_start_claiming(struct block_device *bdev, } } -/* releases bdev_lock */ -static void __bd_abort_claiming(struct block_device *whole, void *holder) -{ - BUG_ON(whole->bd_claiming != holder); - whole->bd_claiming = NULL; - wake_up_bit(&whole->bd_claiming, 0); - - spin_unlock(&bdev_lock); - bdput(whole); -} - -/** - * bd_abort_claiming - abort claiming a block device - * @whole: whole block device returned by bd_start_claiming() - * @holder: holder trying to claim @bdev - * - * Abort a claiming block started by bd_start_claiming(). Note that - * @whole is not the block device to be claimed but the whole device - * returned by bd_start_claiming(). - * - * CONTEXT: - * Grabs and releases bdev_lock. - */ -static void bd_abort_claiming(struct block_device *whole, void *holder) -{ - spin_lock(&bdev_lock); - __bd_abort_claiming(whole, holder); /* releases bdev_lock */ -} - -/* increment holders when we have a legitimate claim. requires bdev_lock */ -static void __bd_claim(struct block_device *bdev, struct block_device *whole, - void *holder) -{ - /* note that for a whole device bd_holders - * will be incremented twice, and bd_holder will - * be set to bd_may_claim before being set to holder - */ - whole->bd_holders++; - whole->bd_holder = bd_may_claim; - bdev->bd_holders++; - bdev->bd_holder = holder; -} - -/** - * bd_finish_claiming - finish claiming a block device - * @bdev: block device of interest (passed to bd_start_claiming()) - * @whole: whole block device returned by bd_start_claiming() - * @holder: holder trying to claim @bdev - * - * Finish a claiming block started by bd_start_claiming(). - * - * CONTEXT: - * Grabs and releases bdev_lock. - */ -static void bd_finish_claiming(struct block_device *bdev, - struct block_device *whole, void *holder) -{ - spin_lock(&bdev_lock); - BUG_ON(!bd_may_claim(bdev, whole, holder)); - __bd_claim(bdev, whole, holder); - __bd_abort_claiming(whole, holder); /* not actually an abort */ -} - -static void bd_release(struct block_device *bdev) -{ - spin_lock(&bdev_lock); - if (!--bdev->bd_contains->bd_holders) - bdev->bd_contains->bd_holder = NULL; - if (!--bdev->bd_holders) - bdev->bd_holder = NULL; - spin_unlock(&bdev_lock); -} - #ifdef CONFIG_SYSFS static int add_symlink(struct kobject *from, struct kobject *to) { @@ -1223,10 +1150,30 @@ int blkdev_get(struct block_device *bdev, fmode_t mode, void *holder) res = __blkdev_get(bdev, mode, 0); if (whole) { - if (res == 0) - bd_finish_claiming(bdev, whole, holder); - else - bd_abort_claiming(whole, holder); + /* finish claiming */ + spin_lock(&bdev_lock); + + if (res == 0) { + BUG_ON(!bd_may_claim(bdev, whole, holder)); + /* + * Note that for a whole device bd_holders + * will be incremented twice, and bd_holder + * will be set to bd_may_claim before being + * set to holder + */ + whole->bd_holders++; + whole->bd_holder = bd_may_claim; + bdev->bd_holders++; + bdev->bd_holder = holder; + } + + /* tell others that we're done */ + BUG_ON(whole->bd_claiming != holder); + whole->bd_claiming = NULL; + wake_up_bit(&whole->bd_claiming, 0); + + spin_unlock(&bdev_lock); + bdput(whole); } return res; @@ -1272,6 +1219,7 @@ static int __blkdev_put(struct block_device *bdev, fmode_t mode, int for_part) bdev->bd_part_count--; if (!--bdev->bd_openers) { + WARN_ON_ONCE(bdev->bd_holders); sync_blockdev(bdev); kill_bdev(bdev); } @@ -1303,10 +1251,31 @@ static int __blkdev_put(struct block_device *bdev, fmode_t mode, int for_part) int blkdev_put(struct block_device *bdev, fmode_t mode) { if (mode & FMODE_EXCL) { + bool bdev_free; + + /* + * Release a claim on the device. The holder fields + * are protected with bdev_lock. bd_mutex is to + * synchronize disk_holder unlinking. + */ mutex_lock(&bdev->bd_mutex); - bd_release(bdev); - if (!bdev->bd_holders) + spin_lock(&bdev_lock); + + WARN_ON_ONCE(--bdev->bd_holders < 0); + WARN_ON_ONCE(--bdev->bd_contains->bd_holders < 0); + + /* bd_contains might point to self, check in a separate step */ + if ((bdev_free = !bdev->bd_holders)) + bdev->bd_holder = NULL; + if (!bdev->bd_contains->bd_holders) + bdev->bd_contains->bd_holder = NULL; + + spin_unlock(&bdev_lock); + + /* if this was the last claim, holder link should go too */ + if (bdev_free) bd_unlink_disk_holder(bdev); + mutex_unlock(&bdev->bd_mutex); } return __blkdev_put(bdev, mode, 0); -- cgit v1.2.3 From 75f1dc0d076d1c1168f2115f1941ea627d38bd5a Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sat, 13 Nov 2010 11:55:17 +0100 Subject: block: check bdev_read_only() from blkdev_get() bdev read-only status can be queried using bdev_read_only() and may change while the device is being opened. Enforce it by checking it from blkdev_get() after open succeeds. This makes bdev_read_only() check in open_bdev_exclusive() and fsg_lun_open() unnecessary. Drop them. Signed-off-by: Tejun Heo Cc: David Brownell Cc: linux-usb@vger.kernel.org --- drivers/usb/gadget/storage_common.c | 7 ++----- fs/block_dev.c | 11 ++++++----- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/drivers/usb/gadget/storage_common.c b/drivers/usb/gadget/storage_common.c index 3b513bafaf2a..b015561fd602 100644 --- a/drivers/usb/gadget/storage_common.c +++ b/drivers/usb/gadget/storage_common.c @@ -543,7 +543,7 @@ static int fsg_lun_open(struct fsg_lun *curlun, const char *filename) ro = curlun->initially_ro; if (!ro) { filp = filp_open(filename, O_RDWR | O_LARGEFILE, 0); - if (-EROFS == PTR_ERR(filp)) + if (PTR_ERR(filp) == -EROFS || PTR_ERR(filp) == -EACCES) ro = 1; } if (ro) @@ -558,10 +558,7 @@ static int fsg_lun_open(struct fsg_lun *curlun, const char *filename) if (filp->f_path.dentry) inode = filp->f_path.dentry->d_inode; - if (inode && S_ISBLK(inode->i_mode)) { - if (bdev_read_only(inode->i_bdev)) - ro = 1; - } else if (!inode || !S_ISREG(inode->i_mode)) { + if (!inode || (!S_ISREG(inode->i_mode) && !S_ISBLK(inode->i_mode))) { LINFO(curlun, "invalid file type: %s\n", filename); goto out; } diff --git a/fs/block_dev.c b/fs/block_dev.c index 269bfbbd10fc..606a5259f87f 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c @@ -1149,6 +1149,12 @@ int blkdev_get(struct block_device *bdev, fmode_t mode, void *holder) res = __blkdev_get(bdev, mode, 0); + /* __blkdev_get() may alter read only status, check it afterwards */ + if (!res && (mode & FMODE_WRITE) && bdev_read_only(bdev)) { + __blkdev_put(bdev, mode, 0); + res = -EACCES; + } + if (whole) { /* finish claiming */ spin_lock(&bdev_lock); @@ -1453,11 +1459,6 @@ struct block_device *open_bdev_exclusive(const char *path, fmode_t mode, void *h if (error) return ERR_PTR(error); - if ((mode & FMODE_WRITE) && bdev_read_only(bdev)) { - blkdev_put(bdev, mode); - return ERR_PTR(-EACCES); - } - return bdev; } -- cgit v1.2.3 From d4d77629953eabd3c14f6fa5746f6b28babfc55f Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sat, 13 Nov 2010 11:55:18 +0100 Subject: block: clean up blkdev_get() wrappers and their users After recent blkdev_get() modifications, open_by_devnum() and open_bdev_exclusive() are simple wrappers around blkdev_get(). Replace them with blkdev_get_by_dev() and blkdev_get_by_path(). blkdev_get_by_dev() is identical to open_by_devnum(). blkdev_get_by_path() is slightly different in that it doesn't automatically add %FMODE_EXCL to @mode. All users are converted. Most conversions are mechanical and don't introduce any behavior difference. There are several exceptions. * btrfs now sets FMODE_EXCL in btrfs_device->mode, so there's no reason to OR it explicitly on blkdev_put(). * gfs2, nilfs2 and the generic mount_bdev() now set FMODE_EXCL in sb->s_mode. * With the above changes, sb->s_mode now always should contain FMODE_EXCL. WARN_ON_ONCE() added to kill_block_super() to detect errors. The new blkdev_get_*() functions are with proper docbook comments. While at it, add function description to blkdev_get() too. Signed-off-by: Tejun Heo Cc: Philipp Reisner Cc: Neil Brown Cc: Mike Snitzer Cc: Joern Engel Cc: Chris Mason Cc: Jan Kara Cc: "Theodore Ts'o" Cc: KONISHI Ryusuke Cc: reiserfs-devel@vger.kernel.org Cc: xfs-masters@oss.sgi.com Cc: Alexander Viro --- drivers/block/drbd/drbd_nl.c | 12 ++-- drivers/md/dm-table.c | 2 +- drivers/md/md.c | 4 +- drivers/mtd/devices/block2mtd.c | 4 +- fs/block_dev.c | 139 +++++++++++++++++++++++++++------------- fs/btrfs/volumes.c | 24 ++++--- fs/btrfs/volumes.h | 2 +- fs/ext3/super.c | 2 +- fs/ext4/super.c | 2 +- fs/gfs2/ops_fstype.c | 8 +-- fs/jfs/jfs_logmgr.c | 4 +- fs/logfs/dev_bdev.c | 3 +- fs/nilfs2/super.c | 8 +-- fs/reiserfs/journal.c | 6 +- fs/super.c | 9 +-- fs/xfs/linux-2.6/xfs_super.c | 3 +- include/linux/fs.h | 7 +- kernel/power/swap.c | 4 +- 18 files changed, 149 insertions(+), 94 deletions(-) diff --git a/drivers/block/drbd/drbd_nl.c b/drivers/block/drbd/drbd_nl.c index fd0346090289..650e43ba4f7c 100644 --- a/drivers/block/drbd/drbd_nl.c +++ b/drivers/block/drbd/drbd_nl.c @@ -902,8 +902,8 @@ static int drbd_nl_disk_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp } } - bdev = open_bdev_exclusive(nbc->dc.backing_dev, - FMODE_READ | FMODE_WRITE, mdev); + bdev = blkdev_get_by_path(nbc->dc.backing_dev, + FMODE_READ | FMODE_WRITE | FMODE_EXCL, mdev); if (IS_ERR(bdev)) { dev_err(DEV, "open(\"%s\") failed with %ld\n", nbc->dc.backing_dev, PTR_ERR(bdev)); @@ -920,10 +920,10 @@ static int drbd_nl_disk_conf(struct drbd_conf *mdev, struct drbd_nl_cfg_req *nlp * should check it for you already; but if you don't, or * someone fooled it, we need to double check here) */ - bdev = open_bdev_exclusive(nbc->dc.meta_dev, - FMODE_READ | FMODE_WRITE, - (nbc->dc.meta_dev_idx < 0) ? - (void *)mdev : (void *)drbd_m_holder); + bdev = blkdev_get_by_path(nbc->dc.meta_dev, + FMODE_READ | FMODE_WRITE | FMODE_EXCL, + (nbc->dc.meta_dev_idx < 0) ? + (void *)mdev : (void *)drbd_m_holder); if (IS_ERR(bdev)) { dev_err(DEV, "open(\"%s\") failed with %ld\n", nbc->dc.meta_dev, PTR_ERR(bdev)); diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c index 9e88ca0c55e9..67150c32986c 100644 --- a/drivers/md/dm-table.c +++ b/drivers/md/dm-table.c @@ -325,7 +325,7 @@ static int open_dev(struct dm_dev_internal *d, dev_t dev, BUG_ON(d->dm_dev.bdev); - bdev = open_by_devnum(dev, d->dm_dev.mode | FMODE_EXCL, _claim_ptr); + bdev = blkdev_get_by_dev(dev, d->dm_dev.mode | FMODE_EXCL, _claim_ptr); if (IS_ERR(bdev)) return PTR_ERR(bdev); diff --git a/drivers/md/md.c b/drivers/md/md.c index 6af951ffe0bb..5aaa6bfbe638 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -1934,8 +1934,8 @@ static int lock_rdev(mdk_rdev_t *rdev, dev_t dev, int shared) struct block_device *bdev; char b[BDEVNAME_SIZE]; - bdev = open_by_devnum(dev, FMODE_READ|FMODE_WRITE|FMODE_EXCL, - shared ? (mdk_rdev_t *)lock_rdev : rdev); + bdev = blkdev_get_by_dev(dev, FMODE_READ|FMODE_WRITE|FMODE_EXCL, + shared ? (mdk_rdev_t *)lock_rdev : rdev); if (IS_ERR(bdev)) { printk(KERN_ERR "md: could not open %s.\n", __bdevname(dev, b)); diff --git a/drivers/mtd/devices/block2mtd.c b/drivers/mtd/devices/block2mtd.c index aa557beb8f51..f29a6f9df6e7 100644 --- a/drivers/mtd/devices/block2mtd.c +++ b/drivers/mtd/devices/block2mtd.c @@ -247,7 +247,7 @@ static struct block2mtd_dev *add_device(char *devname, int erase_size) return NULL; /* Get a handle on the device */ - bdev = open_bdev_exclusive(devname, mode, dev); + bdev = blkdev_get_by_path(devname, mode, dev); #ifndef MODULE if (IS_ERR(bdev)) { @@ -256,7 +256,7 @@ static struct block2mtd_dev *add_device(char *devname, int erase_size) dev_t devt = name_to_dev_t(devname); if (devt) - bdev = open_by_devnum(devt, mode, dev); + bdev = blkdev_get_by_dev(devt, mode, dev); } #endif diff --git a/fs/block_dev.c b/fs/block_dev.c index 606a5259f87f..c1c1b8c3fb99 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c @@ -854,24 +854,6 @@ static inline void bd_unlink_disk_holder(struct block_device *bdev) { } #endif -/* - * Tries to open block device by device number. Use it ONLY if you - * really do not have anything better - i.e. when you are behind a - * truly sucky interface and all you are given is a device number. _Never_ - * to be used for internal purposes. If you ever need it - reconsider - * your API. - */ -struct block_device *open_by_devnum(dev_t dev, fmode_t mode, void *holder) -{ - struct block_device *bdev = bdget(dev); - int err = -ENOMEM; - if (bdev) - err = blkdev_get(bdev, mode, holder); - return err ? ERR_PTR(err) : bdev; -} - -EXPORT_SYMBOL(open_by_devnum); - /** * flush_disk - invalidates all buffer-cache entries on a disk * @@ -1132,6 +1114,25 @@ static int __blkdev_get(struct block_device *bdev, fmode_t mode, int for_part) return ret; } +/** + * blkdev_get - open a block device + * @bdev: block_device to open + * @mode: FMODE_* mask + * @holder: exclusive holder identifier + * + * Open @bdev with @mode. If @mode includes %FMODE_EXCL, @bdev is + * open with exclusive access. Specifying %FMODE_EXCL with %NULL + * @holder is invalid. Exclusive opens may nest for the same @holder. + * + * On success, the reference count of @bdev is unchanged. On failure, + * @bdev is put. + * + * CONTEXT: + * Might sleep. + * + * RETURNS: + * 0 on success, -errno on failure. + */ int blkdev_get(struct block_device *bdev, fmode_t mode, void *holder) { struct block_device *whole = NULL; @@ -1186,6 +1187,80 @@ int blkdev_get(struct block_device *bdev, fmode_t mode, void *holder) } EXPORT_SYMBOL(blkdev_get); +/** + * blkdev_get_by_path - open a block device by name + * @path: path to the block device to open + * @mode: FMODE_* mask + * @holder: exclusive holder identifier + * + * Open the blockdevice described by the device file at @path. @mode + * and @holder are identical to blkdev_get(). + * + * On success, the returned block_device has reference count of one. + * + * CONTEXT: + * Might sleep. + * + * RETURNS: + * Pointer to block_device on success, ERR_PTR(-errno) on failure. + */ +struct block_device *blkdev_get_by_path(const char *path, fmode_t mode, + void *holder) +{ + struct block_device *bdev; + int err; + + bdev = lookup_bdev(path); + if (IS_ERR(bdev)) + return bdev; + + err = blkdev_get(bdev, mode, holder); + if (err) + return ERR_PTR(err); + + return bdev; +} +EXPORT_SYMBOL(blkdev_get_by_path); + +/** + * blkdev_get_by_dev - open a block device by device number + * @dev: device number of block device to open + * @mode: FMODE_* mask + * @holder: exclusive holder identifier + * + * Open the blockdevice described by device number @dev. @mode and + * @holder are identical to blkdev_get(). + * + * Use it ONLY if you really do not have anything better - i.e. when + * you are behind a truly sucky interface and all you are given is a + * device number. _Never_ to be used for internal purposes. If you + * ever need it - reconsider your API. + * + * On success, the returned block_device has reference count of one. + * + * CONTEXT: + * Might sleep. + * + * RETURNS: + * Pointer to block_device on success, ERR_PTR(-errno) on failure. + */ +struct block_device *blkdev_get_by_dev(dev_t dev, fmode_t mode, void *holder) +{ + struct block_device *bdev; + int err; + + bdev = bdget(dev); + if (!bdev) + return ERR_PTR(-ENOMEM); + + err = blkdev_get(bdev, mode, holder); + if (err) + return ERR_PTR(err); + + return bdev; +} +EXPORT_SYMBOL(blkdev_get_by_dev); + static int blkdev_open(struct inode * inode, struct file * filp) { struct block_device *bdev; @@ -1436,34 +1511,6 @@ fail: } EXPORT_SYMBOL(lookup_bdev); -/** - * open_bdev_exclusive - open a block device by name and set it up for use - * - * @path: special file representing the block device - * @mode: FMODE_... combination to pass be used - * @holder: owner for exclusion - * - * Open the blockdevice described by the special file at @path, claim it - * for the @holder. - */ -struct block_device *open_bdev_exclusive(const char *path, fmode_t mode, void *holder) -{ - struct block_device *bdev; - int error; - - bdev = lookup_bdev(path); - if (IS_ERR(bdev)) - return bdev; - - error = blkdev_get(bdev, mode | FMODE_EXCL, holder); - if (error) - return ERR_PTR(error); - - return bdev; -} - -EXPORT_SYMBOL(open_bdev_exclusive); - int __invalidate_device(struct block_device *bdev) { struct super_block *sb = get_super(bdev); diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index f1b729d3b883..95324e9f9280 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c @@ -489,7 +489,7 @@ again: continue; if (device->bdev) { - blkdev_put(device->bdev, device->mode | FMODE_EXCL); + blkdev_put(device->bdev, device->mode); device->bdev = NULL; fs_devices->open_devices--; } @@ -523,7 +523,7 @@ static int __btrfs_close_devices(struct btrfs_fs_devices *fs_devices) list_for_each_entry(device, &fs_devices->devices, dev_list) { if (device->bdev) { - blkdev_put(device->bdev, device->mode | FMODE_EXCL); + blkdev_put(device->bdev, device->mode); fs_devices->open_devices--; } if (device->writeable) { @@ -580,13 +580,15 @@ static int __btrfs_open_devices(struct btrfs_fs_devices *fs_devices, int seeding = 1; int ret = 0; + flags |= FMODE_EXCL; + list_for_each_entry(device, head, dev_list) { if (device->bdev) continue; if (!device->name) continue; - bdev = open_bdev_exclusive(device->name, flags, holder); + bdev = blkdev_get_by_path(device->name, flags, holder); if (IS_ERR(bdev)) { printk(KERN_INFO "open %s failed\n", device->name); goto error; @@ -638,7 +640,7 @@ static int __btrfs_open_devices(struct btrfs_fs_devices *fs_devices, error_brelse: brelse(bh); error_close: - blkdev_put(bdev, flags | FMODE_EXCL); + blkdev_put(bdev, flags); error: continue; } @@ -684,7 +686,8 @@ int btrfs_scan_one_device(const char *path, fmode_t flags, void *holder, mutex_lock(&uuid_mutex); - bdev = open_bdev_exclusive(path, flags, holder); + flags |= FMODE_EXCL; + bdev = blkdev_get_by_path(path, flags, holder); if (IS_ERR(bdev)) { ret = PTR_ERR(bdev); @@ -716,7 +719,7 @@ int btrfs_scan_one_device(const char *path, fmode_t flags, void *holder, brelse(bh); error_close: - blkdev_put(bdev, flags | FMODE_EXCL); + blkdev_put(bdev, flags); error: mutex_unlock(&uuid_mutex); return ret; @@ -1179,8 +1182,8 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path) goto out; } } else { - bdev = open_bdev_exclusive(device_path, FMODE_READ, - root->fs_info->bdev_holder); + bdev = blkdev_get_by_path(device_path, FMODE_READ | FMODE_EXCL, + root->fs_info->bdev_holder); if (IS_ERR(bdev)) { ret = PTR_ERR(bdev); goto out; @@ -1244,7 +1247,7 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path) root->fs_info->fs_devices->latest_bdev = next_device->bdev; if (device->bdev) { - blkdev_put(device->bdev, device->mode | FMODE_EXCL); + blkdev_put(device->bdev, device->mode); device->bdev = NULL; device->fs_devices->open_devices--; } @@ -1439,7 +1442,8 @@ int btrfs_init_new_device(struct btrfs_root *root, char *device_path) if ((sb->s_flags & MS_RDONLY) && !root->fs_info->fs_devices->seeding) return -EINVAL; - bdev = open_bdev_exclusive(device_path, 0, root->fs_info->bdev_holder); + bdev = blkdev_get_by_path(device_path, FMODE_EXCL, + root->fs_info->bdev_holder); if (IS_ERR(bdev)) return PTR_ERR(bdev); diff --git a/fs/btrfs/volumes.h b/fs/btrfs/volumes.h index 2b638b6e4eea..856e75770304 100644 --- a/fs/btrfs/volumes.h +++ b/fs/btrfs/volumes.h @@ -49,7 +49,7 @@ struct btrfs_device { struct block_device *bdev; - /* the mode sent to open_bdev_exclusive */ + /* the mode sent to blkdev_get */ fmode_t mode; char *name; diff --git a/fs/ext3/super.c b/fs/ext3/super.c index 23e7513dba9c..123720ba786d 100644 --- a/fs/ext3/super.c +++ b/fs/ext3/super.c @@ -347,7 +347,7 @@ static struct block_device *ext3_blkdev_get(dev_t dev, struct super_block *sb) struct block_device *bdev; char b[BDEVNAME_SIZE]; - bdev = open_by_devnum(dev, FMODE_READ|FMODE_WRITE|FMODE_EXCL, sb); + bdev = blkdev_get_by_dev(dev, FMODE_READ|FMODE_WRITE|FMODE_EXCL, sb); if (IS_ERR(bdev)) goto fail; return bdev; diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 5dd0b3e76fa8..bd63e6927219 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -647,7 +647,7 @@ static struct block_device *ext4_blkdev_get(dev_t dev, struct super_block *sb) struct block_device *bdev; char b[BDEVNAME_SIZE]; - bdev = open_by_devnum(dev, FMODE_READ|FMODE_WRITE|FMODE_EXCL, sb); + bdev = blkdev_get_by_dev(dev, FMODE_READ|FMODE_WRITE|FMODE_EXCL, sb); if (IS_ERR(bdev)) goto fail; return bdev; diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c index c1f0763a022b..bc56ccf98ffd 100644 --- a/fs/gfs2/ops_fstype.c +++ b/fs/gfs2/ops_fstype.c @@ -1268,7 +1268,7 @@ static struct dentry *gfs2_mount(struct file_system_type *fs_type, int flags, { struct block_device *bdev; struct super_block *s; - fmode_t mode = FMODE_READ; + fmode_t mode = FMODE_READ | FMODE_EXCL; int error; struct gfs2_args args; struct gfs2_sbd *sdp; @@ -1276,7 +1276,7 @@ static struct dentry *gfs2_mount(struct file_system_type *fs_type, int flags, if (!(flags & MS_RDONLY)) mode |= FMODE_WRITE; - bdev = open_bdev_exclusive(dev_name, mode, fs_type); + bdev = blkdev_get_by_path(dev_name, mode, fs_type); if (IS_ERR(bdev)) return ERR_CAST(bdev); @@ -1298,7 +1298,7 @@ static struct dentry *gfs2_mount(struct file_system_type *fs_type, int flags, goto error_bdev; if (s->s_root) - blkdev_put(bdev, mode | FMODE_EXCL); + blkdev_put(bdev, mode); memset(&args, 0, sizeof(args)); args.ar_quota = GFS2_QUOTA_DEFAULT; @@ -1342,7 +1342,7 @@ error_super: deactivate_locked_super(s); return ERR_PTR(error); error_bdev: - blkdev_put(bdev, mode | FMODE_EXCL); + blkdev_put(bdev, mode); return ERR_PTR(error); } diff --git a/fs/jfs/jfs_logmgr.c b/fs/jfs/jfs_logmgr.c index 5a290f22dcc3..278e3fb40b71 100644 --- a/fs/jfs/jfs_logmgr.c +++ b/fs/jfs/jfs_logmgr.c @@ -1120,8 +1120,8 @@ int lmLogOpen(struct super_block *sb) * file systems to log may have n-to-1 relationship; */ - bdev = open_by_devnum(sbi->logdev, FMODE_READ|FMODE_WRITE|FMODE_EXCL, - log); + bdev = blkdev_get_by_dev(sbi->logdev, FMODE_READ|FMODE_WRITE|FMODE_EXCL, + log); if (IS_ERR(bdev)) { rc = -PTR_ERR(bdev); goto free; diff --git a/fs/logfs/dev_bdev.c b/fs/logfs/dev_bdev.c index 734b9025858e..723bc5bca09a 100644 --- a/fs/logfs/dev_bdev.c +++ b/fs/logfs/dev_bdev.c @@ -325,7 +325,8 @@ int logfs_get_sb_bdev(struct logfs_super *p, struct file_system_type *type, { struct block_device *bdev; - bdev = open_bdev_exclusive(devname, FMODE_READ|FMODE_WRITE, type); + bdev = blkdev_get_by_path(devname, FMODE_READ|FMODE_WRITE|FMODE_EXCL, + type); if (IS_ERR(bdev)) return PTR_ERR(bdev); diff --git a/fs/nilfs2/super.c b/fs/nilfs2/super.c index 756a6798d7c8..0030640e2d72 100644 --- a/fs/nilfs2/super.c +++ b/fs/nilfs2/super.c @@ -1147,14 +1147,14 @@ nilfs_mount(struct file_system_type *fs_type, int flags, { struct nilfs_super_data sd; struct super_block *s; - fmode_t mode = FMODE_READ; + fmode_t mode = FMODE_READ | FMODE_EXCL; struct dentry *root_dentry; int err, s_new = false; if (!(flags & MS_RDONLY)) mode |= FMODE_WRITE; - sd.bdev = open_bdev_exclusive(dev_name, mode, fs_type); + sd.bdev = blkdev_get_by_path(dev_name, mode, fs_type); if (IS_ERR(sd.bdev)) return ERR_CAST(sd.bdev); @@ -1233,7 +1233,7 @@ nilfs_mount(struct file_system_type *fs_type, int flags, } if (!s_new) - blkdev_put(sd.bdev, mode | FMODE_EXCL); + blkdev_put(sd.bdev, mode); return root_dentry; @@ -1242,7 +1242,7 @@ nilfs_mount(struct file_system_type *fs_type, int flags, failed: if (!s_new) - blkdev_put(sd.bdev, mode | FMODE_EXCL); + blkdev_put(sd.bdev, mode); return ERR_PTR(err); } diff --git a/fs/reiserfs/journal.c b/fs/reiserfs/journal.c index b488136f5ace..e2fce519c0f2 100644 --- a/fs/reiserfs/journal.c +++ b/fs/reiserfs/journal.c @@ -2585,7 +2585,8 @@ static int journal_init_dev(struct super_block *super, if ((!jdev_name || !jdev_name[0])) { if (jdev == super->s_dev) blkdev_mode &= ~FMODE_EXCL; - journal->j_dev_bd = open_by_devnum(jdev, blkdev_mode, journal); + journal->j_dev_bd = blkdev_get_by_dev(jdev, blkdev_mode, + journal); journal->j_dev_mode = blkdev_mode; if (IS_ERR(journal->j_dev_bd)) { result = PTR_ERR(journal->j_dev_bd); @@ -2601,8 +2602,7 @@ static int journal_init_dev(struct super_block *super, } journal->j_dev_mode = blkdev_mode; - journal->j_dev_bd = open_bdev_exclusive(jdev_name, - blkdev_mode, journal); + journal->j_dev_bd = blkdev_get_by_path(jdev_name, blkdev_mode, journal); if (IS_ERR(journal->j_dev_bd)) { result = PTR_ERR(journal->j_dev_bd); journal->j_dev_bd = NULL; diff --git a/fs/super.c b/fs/super.c index 22374bf0ba87..5d9a4497849a 100644 --- a/fs/super.c +++ b/fs/super.c @@ -766,13 +766,13 @@ struct dentry *mount_bdev(struct file_system_type *fs_type, { struct block_device *bdev; struct super_block *s; - fmode_t mode = FMODE_READ; + fmode_t mode = FMODE_READ | FMODE_EXCL; int error = 0; if (!(flags & MS_RDONLY)) mode |= FMODE_WRITE; - bdev = open_bdev_exclusive(dev_name, mode, fs_type); + bdev = blkdev_get_by_path(dev_name, mode, fs_type); if (IS_ERR(bdev)) return ERR_CAST(bdev); @@ -807,7 +807,7 @@ struct dentry *mount_bdev(struct file_system_type *fs_type, * holding an active reference. */ up_write(&s->s_umount); - blkdev_put(bdev, mode | FMODE_EXCL); + blkdev_put(bdev, mode); down_write(&s->s_umount); } else { char b[BDEVNAME_SIZE]; @@ -831,7 +831,7 @@ struct dentry *mount_bdev(struct file_system_type *fs_type, error_s: error = PTR_ERR(s); error_bdev: - blkdev_put(bdev, mode | FMODE_EXCL); + blkdev_put(bdev, mode); error: return ERR_PTR(error); } @@ -862,6 +862,7 @@ void kill_block_super(struct super_block *sb) bdev->bd_super = NULL; generic_shutdown_super(sb); sync_blockdev(bdev); + WARN_ON_ONCE(!(mode & FMODE_EXCL)); blkdev_put(bdev, mode | FMODE_EXCL); } diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c index a1a6e5ceea67..9209cd199c47 100644 --- a/fs/xfs/linux-2.6/xfs_super.c +++ b/fs/xfs/linux-2.6/xfs_super.c @@ -609,7 +609,8 @@ xfs_blkdev_get( { int error = 0; - *bdevp = open_bdev_exclusive(name, FMODE_READ|FMODE_WRITE, mp); + *bdevp = blkdev_get_by_path(name, FMODE_READ|FMODE_WRITE|FMODE_EXCL, + mp); if (IS_ERR(*bdevp)) { error = PTR_ERR(*bdevp); printk("XFS: Invalid device [%s], error=%d\n", name, error); diff --git a/include/linux/fs.h b/include/linux/fs.h index 1a033e8ebe4c..f48501563917 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -2006,8 +2006,6 @@ extern struct block_device *bdgrab(struct block_device *bdev); extern void bd_set_size(struct block_device *, loff_t size); extern void bd_forget(struct inode *inode); extern void bdput(struct block_device *); -extern struct block_device *open_by_devnum(dev_t dev, fmode_t mode, - void *holder); extern void invalidate_bdev(struct block_device *); extern int sync_blockdev(struct block_device *bdev); extern struct super_block *freeze_bdev(struct block_device *); @@ -2039,6 +2037,10 @@ extern int ioctl_by_bdev(struct block_device *, unsigned, unsigned long); extern int blkdev_ioctl(struct block_device *, fmode_t, unsigned, unsigned long); extern long compat_blkdev_ioctl(struct file *, unsigned, unsigned long); extern int blkdev_get(struct block_device *bdev, fmode_t mode, void *holder); +extern struct block_device *blkdev_get_by_path(const char *path, fmode_t mode, + void *holder); +extern struct block_device *blkdev_get_by_dev(dev_t dev, fmode_t mode, + void *holder); extern int blkdev_put(struct block_device *bdev, fmode_t mode); #ifdef CONFIG_SYSFS extern int bd_link_disk_holder(struct block_device *bdev, struct gendisk *disk); @@ -2083,7 +2085,6 @@ static inline void unregister_chrdev(unsigned int major, const char *name) extern const char *__bdevname(dev_t, char *buffer); extern const char *bdevname(struct block_device *bdev, char *buffer); extern struct block_device *lookup_bdev(const char *); -extern struct block_device *open_bdev_exclusive(const char *, fmode_t, void *); extern void blkdev_show(struct seq_file *,off_t); #else diff --git a/kernel/power/swap.c b/kernel/power/swap.c index 513a77f1a0b3..b019609d1b45 100644 --- a/kernel/power/swap.c +++ b/kernel/power/swap.c @@ -907,8 +907,8 @@ int swsusp_check(void) { int error; - hib_resume_bdev = open_by_devnum(swsusp_resume_device, - FMODE_READ, NULL); + hib_resume_bdev = blkdev_get_by_dev(swsusp_resume_device, + FMODE_READ, NULL); if (!IS_ERR(hib_resume_bdev)) { set_blocksize(hib_resume_bdev, PAGE_SIZE); clear_page(swsusp_header); -- cgit v1.2.3 From 895be15745d59cc7ede0e1c203e3432b0abdb71c Mon Sep 17 00:00:00 2001 From: Nicolas Kaiser Date: Thu, 4 Nov 2010 14:58:12 -0400 Subject: crypto: cast5 - simplify if-statements I noticed that by factoring out common rounds from the branches of the if-statements in the encryption and decryption functions, the executable file size goes down significantly, for crypto/cast5.ko from 26688 bytes to 24336 bytes (amd64). On my test system, I saw a slight speedup. This is the first time I'm doing such a benchmark - I found a similar one on the crypto mailing list, and I hope I did it right? Before: # cryptsetup create dm-test /dev/hda2 -c cast5-cbc-plain -s 128 Passsatz eingeben: # dd if=/dev/zero of=/dev/mapper/dm-test bs=1M count=50 52428800 Bytes (52 MB) kopiert, 2,43484 s, 21,5 MB/s # dd if=/dev/zero of=/dev/mapper/dm-test bs=1M count=50 52428800 Bytes (52 MB) kopiert, 2,4089 s, 21,8 MB/s # dd if=/dev/zero of=/dev/mapper/dm-test bs=1M count=50 52428800 Bytes (52 MB) kopiert, 2,41091 s, 21,7 MB/s After: # cryptsetup create dm-test /dev/hda2 -c cast5-cbc-plain -s 128 Passsatz eingeben: # dd if=/dev/zero of=/dev/mapper/dm-test bs=1M count=50 52428800 Bytes (52 MB) kopiert, 2,38128 s, 22,0 MB/s # dd if=/dev/zero of=/dev/mapper/dm-test bs=1M count=50 52428800 Bytes (52 MB) kopiert, 2,29486 s, 22,8 MB/s # dd if=/dev/zero of=/dev/mapper/dm-test bs=1M count=50 52428800 Bytes (52 MB) kopiert, 2,37162 s, 22,1 MB/s Signed-off-by: Nicolas Kaiser Signed-off-by: Herbert Xu --- crypto/cast5.c | 74 +++++++++++++++++++--------------------------------------- 1 file changed, 24 insertions(+), 50 deletions(-) diff --git a/crypto/cast5.c b/crypto/cast5.c index a1d2294b50ad..4a230ddec877 100644 --- a/crypto/cast5.c +++ b/crypto/cast5.c @@ -604,36 +604,23 @@ static void cast5_encrypt(struct crypto_tfm *tfm, u8 *outbuf, const u8 *inbuf) * Rounds 3, 6, 9, 12, and 15 use f function Type 3. */ + t = l; l = r; r = t ^ F1(r, Km[0], Kr[0]); + t = l; l = r; r = t ^ F2(r, Km[1], Kr[1]); + t = l; l = r; r = t ^ F3(r, Km[2], Kr[2]); + t = l; l = r; r = t ^ F1(r, Km[3], Kr[3]); + t = l; l = r; r = t ^ F2(r, Km[4], Kr[4]); + t = l; l = r; r = t ^ F3(r, Km[5], Kr[5]); + t = l; l = r; r = t ^ F1(r, Km[6], Kr[6]); + t = l; l = r; r = t ^ F2(r, Km[7], Kr[7]); + t = l; l = r; r = t ^ F3(r, Km[8], Kr[8]); + t = l; l = r; r = t ^ F1(r, Km[9], Kr[9]); + t = l; l = r; r = t ^ F2(r, Km[10], Kr[10]); + t = l; l = r; r = t ^ F3(r, Km[11], Kr[11]); if (!(c->rr)) { - t = l; l = r; r = t ^ F1(r, Km[0], Kr[0]); - t = l; l = r; r = t ^ F2(r, Km[1], Kr[1]); - t = l; l = r; r = t ^ F3(r, Km[2], Kr[2]); - t = l; l = r; r = t ^ F1(r, Km[3], Kr[3]); - t = l; l = r; r = t ^ F2(r, Km[4], Kr[4]); - t = l; l = r; r = t ^ F3(r, Km[5], Kr[5]); - t = l; l = r; r = t ^ F1(r, Km[6], Kr[6]); - t = l; l = r; r = t ^ F2(r, Km[7], Kr[7]); - t = l; l = r; r = t ^ F3(r, Km[8], Kr[8]); - t = l; l = r; r = t ^ F1(r, Km[9], Kr[9]); - t = l; l = r; r = t ^ F2(r, Km[10], Kr[10]); - t = l; l = r; r = t ^ F3(r, Km[11], Kr[11]); t = l; l = r; r = t ^ F1(r, Km[12], Kr[12]); t = l; l = r; r = t ^ F2(r, Km[13], Kr[13]); t = l; l = r; r = t ^ F3(r, Km[14], Kr[14]); t = l; l = r; r = t ^ F1(r, Km[15], Kr[15]); - } else { - t = l; l = r; r = t ^ F1(r, Km[0], Kr[0]); - t = l; l = r; r = t ^ F2(r, Km[1], Kr[1]); - t = l; l = r; r = t ^ F3(r, Km[2], Kr[2]); - t = l; l = r; r = t ^ F1(r, Km[3], Kr[3]); - t = l; l = r; r = t ^ F2(r, Km[4], Kr[4]); - t = l; l = r; r = t ^ F3(r, Km[5], Kr[5]); - t = l; l = r; r = t ^ F1(r, Km[6], Kr[6]); - t = l; l = r; r = t ^ F2(r, Km[7], Kr[7]); - t = l; l = r; r = t ^ F3(r, Km[8], Kr[8]); - t = l; l = r; r = t ^ F1(r, Km[9], Kr[9]); - t = l; l = r; r = t ^ F2(r, Km[10], Kr[10]); - t = l; l = r; r = t ^ F3(r, Km[11], Kr[11]); } /* c1...c64 <-- (R16,L16). (Exchange final blocks L16, R16 and @@ -663,32 +650,19 @@ static void cast5_decrypt(struct crypto_tfm *tfm, u8 *outbuf, const u8 *inbuf) t = l; l = r; r = t ^ F3(r, Km[14], Kr[14]); t = l; l = r; r = t ^ F2(r, Km[13], Kr[13]); t = l; l = r; r = t ^ F1(r, Km[12], Kr[12]); - t = l; l = r; r = t ^ F3(r, Km[11], Kr[11]); - t = l; l = r; r = t ^ F2(r, Km[10], Kr[10]); - t = l; l = r; r = t ^ F1(r, Km[9], Kr[9]); - t = l; l = r; r = t ^ F3(r, Km[8], Kr[8]); - t = l; l = r; r = t ^ F2(r, Km[7], Kr[7]); - t = l; l = r; r = t ^ F1(r, Km[6], Kr[6]); - t = l; l = r; r = t ^ F3(r, Km[5], Kr[5]); - t = l; l = r; r = t ^ F2(r, Km[4], Kr[4]); - t = l; l = r; r = t ^ F1(r, Km[3], Kr[3]); - t = l; l = r; r = t ^ F3(r, Km[2], Kr[2]); - t = l; l = r; r = t ^ F2(r, Km[1], Kr[1]); - t = l; l = r; r = t ^ F1(r, Km[0], Kr[0]); - } else { - t = l; l = r; r = t ^ F3(r, Km[11], Kr[11]); - t = l; l = r; r = t ^ F2(r, Km[10], Kr[10]); - t = l; l = r; r = t ^ F1(r, Km[9], Kr[9]); - t = l; l = r; r = t ^ F3(r, Km[8], Kr[8]); - t = l; l = r; r = t ^ F2(r, Km[7], Kr[7]); - t = l; l = r; r = t ^ F1(r, Km[6], Kr[6]); - t = l; l = r; r = t ^ F3(r, Km[5], Kr[5]); - t = l; l = r; r = t ^ F2(r, Km[4], Kr[4]); - t = l; l = r; r = t ^ F1(r, Km[3], Kr[3]); - t = l; l = r; r = t ^ F3(r, Km[2], Kr[2]); - t = l; l = r; r = t ^ F2(r, Km[1], Kr[1]); - t = l; l = r; r = t ^ F1(r, Km[0], Kr[0]); } + t = l; l = r; r = t ^ F3(r, Km[11], Kr[11]); + t = l; l = r; r = t ^ F2(r, Km[10], Kr[10]); + t = l; l = r; r = t ^ F1(r, Km[9], Kr[9]); + t = l; l = r; r = t ^ F3(r, Km[8], Kr[8]); + t = l; l = r; r = t ^ F2(r, Km[7], Kr[7]); + t = l; l = r; r = t ^ F1(r, Km[6], Kr[6]); + t = l; l = r; r = t ^ F3(r, Km[5], Kr[5]); + t = l; l = r; r = t ^ F2(r, Km[4], Kr[4]); + t = l; l = r; r = t ^ F1(r, Km[3], Kr[3]); + t = l; l = r; r = t ^ F3(r, Km[2], Kr[2]); + t = l; l = r; r = t ^ F2(r, Km[1], Kr[1]); + t = l; l = r; r = t ^ F1(r, Km[0], Kr[0]); dst[0] = cpu_to_be32(r); dst[1] = cpu_to_be32(l); -- cgit v1.2.3 From 0bd82f5f6355775fbaf7d3c664432ce1b862be1e Mon Sep 17 00:00:00 2001 From: Tadeusz Struk Date: Thu, 4 Nov 2010 15:00:45 -0400 Subject: crypto: aesni-intel - RFC4106 AES-GCM Driver Using Intel New Instructions This patch adds an optimized RFC4106 AES-GCM implementation for 64-bit kernels. It supports 128-bit AES key size. This leverages the crypto AEAD interface type to facilitate a combined AES & GCM operation to be implemented in assembly code. The assembly code leverages Intel(R) AES New Instructions and the PCLMULQDQ instruction. Signed-off-by: Adrian Hoban Signed-off-by: Tadeusz Struk Signed-off-by: Gabriele Paoloni Signed-off-by: Aidan O'Mahony Signed-off-by: Erdinc Ozturk Signed-off-by: James Guilford Signed-off-by: Wajdi Feghali Signed-off-by: Herbert Xu --- arch/x86/crypto/aesni-intel_asm.S | 1192 ++++++++++++++++++++++++++++++++++++ arch/x86/crypto/aesni-intel_glue.c | 518 +++++++++++++++- 2 files changed, 1708 insertions(+), 2 deletions(-) diff --git a/arch/x86/crypto/aesni-intel_asm.S b/arch/x86/crypto/aesni-intel_asm.S index ff16756a51c1..aafced54df64 100644 --- a/arch/x86/crypto/aesni-intel_asm.S +++ b/arch/x86/crypto/aesni-intel_asm.S @@ -9,6 +9,17 @@ * Vinodh Gopal * Kahraman Akdemir * + * Added RFC4106 AES-GCM support for 128-bit keys under the AEAD + * interface for 64-bit kernels. + * Authors: Erdinc Ozturk (erdinc.ozturk@intel.com) + * Aidan O'Mahony (aidan.o.mahony@intel.com) + * Adrian Hoban + * James Guilford (james.guilford@intel.com) + * Gabriele Paoloni + * Tadeusz Struk (tadeusz.struk@intel.com) + * Wajdi Feghali (wajdi.k.feghali@intel.com) + * Copyright (c) 2010, Intel Corporation. + * * 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 @@ -18,8 +29,60 @@ #include #include +.data +POLY: .octa 0xC2000000000000000000000000000001 +TWOONE: .octa 0x00000001000000000000000000000001 + +# order of these constants should not change. +# more specifically, ALL_F should follow SHIFT_MASK, +# and ZERO should follow ALL_F + +SHUF_MASK: .octa 0x000102030405060708090A0B0C0D0E0F +MASK1: .octa 0x0000000000000000ffffffffffffffff +MASK2: .octa 0xffffffffffffffff0000000000000000 +SHIFT_MASK: .octa 0x0f0e0d0c0b0a09080706050403020100 +ALL_F: .octa 0xffffffffffffffffffffffffffffffff +ZERO: .octa 0x00000000000000000000000000000000 +ONE: .octa 0x00000000000000000000000000000001 +F_MIN_MASK: .octa 0xf1f2f3f4f5f6f7f8f9fafbfcfdfeff0 +dec: .octa 0x1 +enc: .octa 0x2 + + .text + +#define STACK_OFFSET 8*3 +#define HashKey 16*0 // store HashKey <<1 mod poly here +#define HashKey_2 16*1 // store HashKey^2 <<1 mod poly here +#define HashKey_3 16*2 // store HashKey^3 <<1 mod poly here +#define HashKey_4 16*3 // store HashKey^4 <<1 mod poly here +#define HashKey_k 16*4 // store XOR of High 64 bits and Low 64 + // bits of HashKey <<1 mod poly here + //(for Karatsuba purposes) +#define HashKey_2_k 16*5 // store XOR of High 64 bits and Low 64 + // bits of HashKey^2 <<1 mod poly here + // (for Karatsuba purposes) +#define HashKey_3_k 16*6 // store XOR of High 64 bits and Low 64 + // bits of HashKey^3 <<1 mod poly here + // (for Karatsuba purposes) +#define HashKey_4_k 16*7 // store XOR of High 64 bits and Low 64 + // bits of HashKey^4 <<1 mod poly here + // (for Karatsuba purposes) +#define VARIABLE_OFFSET 16*8 + +#define arg1 rdi +#define arg2 rsi +#define arg3 rdx +#define arg4 rcx +#define arg5 r8 +#define arg6 r9 +#define arg7 STACK_OFFSET+8(%r14) +#define arg8 STACK_OFFSET+16(%r14) +#define arg9 STACK_OFFSET+24(%r14) +#define arg10 STACK_OFFSET+32(%r14) + + #define STATE1 %xmm0 #define STATE2 %xmm4 #define STATE3 %xmm5 @@ -47,6 +110,1135 @@ #define T2 %r11 #define TCTR_LOW T2 + +/* GHASH_MUL MACRO to implement: Data*HashKey mod (128,127,126,121,0) +* +* +* Input: A and B (128-bits each, bit-reflected) +* Output: C = A*B*x mod poly, (i.e. >>1 ) +* To compute GH = GH*HashKey mod poly, give HK = HashKey<<1 mod poly as input +* GH = GH * HK * x mod poly which is equivalent to GH*HashKey mod poly. +* +*/ +.macro GHASH_MUL GH HK TMP1 TMP2 TMP3 TMP4 TMP5 + movdqa \GH, \TMP1 + pshufd $78, \GH, \TMP2 + pshufd $78, \HK, \TMP3 + pxor \GH, \TMP2 # TMP2 = a1+a0 + pxor \HK, \TMP3 # TMP3 = b1+b0 + PCLMULQDQ 0x11, \HK, \TMP1 # TMP1 = a1*b1 + PCLMULQDQ 0x00, \HK, \GH # GH = a0*b0 + PCLMULQDQ 0x00, \TMP3, \TMP2 # TMP2 = (a0+a1)*(b1+b0) + pxor \GH, \TMP2 + pxor \TMP1, \TMP2 # TMP2 = (a0*b0)+(a1*b0) + movdqa \TMP2, \TMP3 + pslldq $8, \TMP3 # left shift TMP3 2 DWs + psrldq $8, \TMP2 # right shift TMP2 2 DWs + pxor \TMP3, \GH + pxor \TMP2, \TMP1 # TMP2:GH holds the result of GH*HK + + # first phase of the reduction + + movdqa \GH, \TMP2 + movdqa \GH, \TMP3 + movdqa \GH, \TMP4 # copy GH into TMP2,TMP3 and TMP4 + # in in order to perform + # independent shifts + pslld $31, \TMP2 # packed right shift <<31 + pslld $30, \TMP3 # packed right shift <<30 + pslld $25, \TMP4 # packed right shift <<25 + pxor \TMP3, \TMP2 # xor the shifted versions + pxor \TMP4, \TMP2 + movdqa \TMP2, \TMP5 + psrldq $4, \TMP5 # right shift TMP5 1 DW + pslldq $12, \TMP2 # left shift TMP2 3 DWs + pxor \TMP2, \GH + + # second phase of the reduction + + movdqa \GH,\TMP2 # copy GH into TMP2,TMP3 and TMP4 + # in in order to perform + # independent shifts + movdqa \GH,\TMP3 + movdqa \GH,\TMP4 + psrld $1,\TMP2 # packed left shift >>1 + psrld $2,\TMP3 # packed left shift >>2 + psrld $7,\TMP4 # packed left shift >>7 + pxor \TMP3,\TMP2 # xor the shifted versions + pxor \TMP4,\TMP2 + pxor \TMP5, \TMP2 + pxor \TMP2, \GH + pxor \TMP1, \GH # result is in TMP1 +.endm + +/* +* if a = number of total plaintext bytes +* b = floor(a/16) +* num_initial_blocks = b mod 4 +* encrypt the initial num_initial_blocks blocks and apply ghash on +* the ciphertext +* %r10, %r11, %r12, %rax, %xmm5, %xmm6, %xmm7, %xmm8, %xmm9 registers +* are clobbered +* arg1, %arg2, %arg3, %r14 are used as a pointer only, not modified +*/ + +.macro INITIAL_BLOCKS num_initial_blocks TMP1 TMP2 TMP3 TMP4 TMP5 XMM0 XMM1 \ +XMM2 XMM3 XMM4 XMMDst TMP6 TMP7 i i_seq operation + + mov arg7, %r10 # %r10 = AAD + mov arg8, %r12 # %r12 = aadLen + mov %r12, %r11 + pxor %xmm\i, %xmm\i +_get_AAD_loop\num_initial_blocks\operation: + movd (%r10), \TMP1 + pslldq $12, \TMP1 + psrldq $4, %xmm\i + pxor \TMP1, %xmm\i + add $4, %r10 + sub $4, %r12 + jne _get_AAD_loop\num_initial_blocks\operation + cmp $16, %r11 + je _get_AAD_loop2_done\num_initial_blocks\operation + mov $16, %r12 +_get_AAD_loop2\num_initial_blocks\operation: + psrldq $4, %xmm\i + sub $4, %r12 + cmp %r11, %r12 + jne _get_AAD_loop2\num_initial_blocks\operation +_get_AAD_loop2_done\num_initial_blocks\operation: + pshufb SHUF_MASK(%rip), %xmm\i # byte-reflect the AAD data + xor %r11, %r11 # initialise the data pointer offset as zero + + # start AES for num_initial_blocks blocks + + mov %arg5, %rax # %rax = *Y0 + movdqu (%rax), \XMM0 # XMM0 = Y0 + pshufb SHUF_MASK(%rip), \XMM0 +.if \i_seq != 0 +.irpc index, \i_seq + paddd ONE(%rip), \XMM0 # INCR Y0 + movdqa \XMM0, %xmm\index + pshufb SHUF_MASK(%rip), %xmm\index # perform a 16 byte swap +.endr +.irpc index, \i_seq + pxor 16*0(%arg1), %xmm\index +.endr +.irpc index, \i_seq + movaps 0x10(%rdi), \TMP1 + AESENC \TMP1, %xmm\index # Round 1 +.endr +.irpc index, \i_seq + movaps 0x20(%arg1), \TMP1 + AESENC \TMP1, %xmm\index # Round 2 +.endr +.irpc index, \i_seq + movaps 0x30(%arg1), \TMP1 + AESENC \TMP1, %xmm\index # Round 2 +.endr +.irpc index, \i_seq + movaps 0x40(%arg1), \TMP1 + AESENC \TMP1, %xmm\index # Round 2 +.endr +.irpc index, \i_seq + movaps 0x50(%arg1), \TMP1 + AESENC \TMP1, %xmm\index # Round 2 +.endr +.irpc index, \i_seq + movaps 0x60(%arg1), \TMP1 + AESENC \TMP1, %xmm\index # Round 2 +.endr +.irpc index, \i_seq + movaps 0x70(%arg1), \TMP1 + AESENC \TMP1, %xmm\index # Round 2 +.endr +.irpc index, \i_seq + movaps 0x80(%arg1), \TMP1 + AESENC \TMP1, %xmm\index # Round 2 +.endr +.irpc index, \i_seq + movaps 0x90(%arg1), \TMP1 + AESENC \TMP1, %xmm\index # Round 2 +.endr +.irpc index, \i_seq + movaps 0xa0(%arg1), \TMP1 + AESENCLAST \TMP1, %xmm\index # Round 10 +.endr +.irpc index, \i_seq + movdqu (%arg3 , %r11, 1), \TMP1 + pxor \TMP1, %xmm\index + movdqu %xmm\index, (%arg2 , %r11, 1) + # write back plaintext/ciphertext for num_initial_blocks + add $16, %r11 +.if \operation == dec + movdqa \TMP1, %xmm\index +.endif + pshufb SHUF_MASK(%rip), %xmm\index + # prepare plaintext/ciphertext for GHASH computation +.endr +.endif + GHASH_MUL %xmm\i, \TMP3, \TMP1, \TMP2, \TMP4, \TMP5, \XMM1 + # apply GHASH on num_initial_blocks blocks + +.if \i == 5 + pxor %xmm5, %xmm6 + GHASH_MUL %xmm6, \TMP3, \TMP1, \TMP2, \TMP4, \TMP5, \XMM1 + pxor %xmm6, %xmm7 + GHASH_MUL %xmm7, \TMP3, \TMP1, \TMP2, \TMP4, \TMP5, \XMM1 + pxor %xmm7, %xmm8 + GHASH_MUL %xmm8, \TMP3, \TMP1, \TMP2, \TMP4, \TMP5, \XMM1 +.elseif \i == 6 + pxor %xmm6, %xmm7 + GHASH_MUL %xmm7, \TMP3, \TMP1, \TMP2, \TMP4, \TMP5, \XMM1 + pxor %xmm7, %xmm8 + GHASH_MUL %xmm8, \TMP3, \TMP1, \TMP2, \TMP4, \TMP5, \XMM1 +.elseif \i == 7 + pxor %xmm7, %xmm8 + GHASH_MUL %xmm8, \TMP3, \TMP1, \TMP2, \TMP4, \TMP5, \XMM1 +.endif + cmp $64, %r13 + jl _initial_blocks_done\num_initial_blocks\operation + # no need for precomputed values +/* +* +* Precomputations for HashKey parallel with encryption of first 4 blocks. +* Haskey_i_k holds XORed values of the low and high parts of the Haskey_i +*/ + paddd ONE(%rip), \XMM0 # INCR Y0 + movdqa \XMM0, \XMM1 + pshufb SHUF_MASK(%rip), \XMM1 # perform a 16 byte swap + paddd ONE(%rip), \XMM0 # INCR Y0 + movdqa \XMM0, \XMM2 + pshufb SHUF_MASK(%rip), \XMM2 # perform a 16 byte swap + paddd ONE(%rip), \XMM0 # INCR Y0 + movdqa \XMM0, \XMM3 + pshufb SHUF_MASK(%rip), \XMM3 # perform a 16 byte swap + paddd ONE(%rip), \XMM0 # INCR Y0 + movdqa \XMM0, \XMM4 + pshufb SHUF_MASK(%rip), \XMM4 # perform a 16 byte swap + pxor 16*0(%arg1), \XMM1 + pxor 16*0(%arg1), \XMM2 + pxor 16*0(%arg1), \XMM3 + pxor 16*0(%arg1), \XMM4 + movdqa \TMP3, \TMP5 + pshufd $78, \TMP3, \TMP1 + pxor \TMP3, \TMP1 + movdqa \TMP1, HashKey_k(%rsp) + GHASH_MUL \TMP5, \TMP3, \TMP1, \TMP2, \TMP4, \TMP6, \TMP7 +# TMP5 = HashKey^2<<1 (mod poly) + movdqa \TMP5, HashKey_2(%rsp) +# HashKey_2 = HashKey^2<<1 (mod poly) + pshufd $78, \TMP5, \TMP1 + pxor \TMP5, \TMP1 + movdqa \TMP1, HashKey_2_k(%rsp) +.irpc index, 1234 # do 4 rounds + movaps 0x10*\index(%arg1), \TMP1 + AESENC \TMP1, \XMM1 + AESENC \TMP1, \XMM2 + AESENC \TMP1, \XMM3 + AESENC \TMP1, \XMM4 +.endr + GHASH_MUL \TMP5, \TMP3, \TMP1, \TMP2, \TMP4, \TMP6, \TMP7 +# TMP5 = HashKey^3<<1 (mod poly) + movdqa \TMP5, HashKey_3(%rsp) + pshufd $78, \TMP5, \TMP1 + pxor \TMP5, \TMP1 + movdqa \TMP1, HashKey_3_k(%rsp) +.irpc index, 56789 # do next 5 rounds + movaps 0x10*\index(%arg1), \TMP1 + AESENC \TMP1, \XMM1 + AESENC \TMP1, \XMM2 + AESENC \TMP1, \XMM3 + AESENC \TMP1, \XMM4 +.endr + GHASH_MUL \TMP5, \TMP3, \TMP1, \TMP2, \TMP4, \TMP6, \TMP7 +# TMP5 = HashKey^3<<1 (mod poly) + movdqa \TMP5, HashKey_4(%rsp) + pshufd $78, \TMP5, \TMP1 + pxor \TMP5, \TMP1 + movdqa \TMP1, HashKey_4_k(%rsp) + movaps 0xa0(%arg1), \TMP2 + AESENCLAST \TMP2, \XMM1 + AESENCLAST \TMP2, \XMM2 + AESENCLAST \TMP2, \XMM3 + AESENCLAST \TMP2, \XMM4 + movdqu 16*0(%arg3 , %r11 , 1), \TMP1 + pxor \TMP1, \XMM1 +.if \operation == dec + movdqu \XMM1, 16*0(%arg2 , %r11 , 1) + movdqa \TMP1, \XMM1 +.endif + movdqu 16*1(%arg3 , %r11 , 1), \TMP1 + pxor \TMP1, \XMM2 +.if \operation == dec + movdqu \XMM2, 16*1(%arg2 , %r11 , 1) + movdqa \TMP1, \XMM2 +.endif + movdqu 16*2(%arg3 , %r11 , 1), \TMP1 + pxor \TMP1, \XMM3 +.if \operation == dec + movdqu \XMM3, 16*2(%arg2 , %r11 , 1) + movdqa \TMP1, \XMM3 +.endif + movdqu 16*3(%arg3 , %r11 , 1), \TMP1 + pxor \TMP1, \XMM4 +.if \operation == dec + movdqu \XMM4, 16*3(%arg2 , %r11 , 1) + movdqa \TMP1, \XMM4 +.else + movdqu \XMM1, 16*0(%arg2 , %r11 , 1) + movdqu \XMM2, 16*1(%arg2 , %r11 , 1) + movdqu \XMM3, 16*2(%arg2 , %r11 , 1) + movdqu \XMM4, 16*3(%arg2 , %r11 , 1) +.endif + add $64, %r11 + pshufb SHUF_MASK(%rip), \XMM1 # perform a 16 byte swap + pxor \XMMDst, \XMM1 +# combine GHASHed value with the corresponding ciphertext + pshufb SHUF_MASK(%rip), \XMM2 # perform a 16 byte swap + pshufb SHUF_MASK(%rip), \XMM3 # perform a 16 byte swap + pshufb SHUF_MASK(%rip), \XMM4 # perform a 16 byte swap +_initial_blocks_done\num_initial_blocks\operation: +.endm + +/* +* encrypt 4 blocks at a time +* ghash the 4 previously encrypted ciphertext blocks +* arg1, %arg2, %arg3 are used as pointers only, not modified +* %r11 is the data offset value +*/ +.macro GHASH_4_ENCRYPT_4_PARALLEL TMP1 TMP2 TMP3 TMP4 TMP5 \ +TMP6 XMM0 XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7 XMM8 operation + + movdqa \XMM1, \XMM5 + movdqa \XMM2, \XMM6 + movdqa \XMM3, \XMM7 + movdqa \XMM4, \XMM8 + + # multiply TMP5 * HashKey using karatsuba + + movdqa \XMM5, \TMP4 + pshufd $78, \XMM5, \TMP6 + pxor \XMM5, \TMP6 + paddd ONE(%rip), \XMM0 # INCR CNT + movdqa HashKey_4(%rsp), \TMP5 + PCLMULQDQ 0x11, \TMP5, \TMP4 # TMP4 = a1*b1 + movdqa \XMM0, \XMM1 + paddd ONE(%rip), \XMM0 # INCR CNT + movdqa \XMM0, \XMM2 + paddd ONE(%rip), \XMM0 # INCR CNT + movdqa \XMM0, \XMM3 + paddd ONE(%rip), \XMM0 # INCR CNT + movdqa \XMM0, \XMM4 + pshufb SHUF_MASK(%rip), \XMM1 # perform a 16 byte swap + PCLMULQDQ 0x00, \TMP5, \XMM5 # XMM5 = a0*b0 + pshufb SHUF_MASK(%rip), \XMM2 # perform a 16 byte swap + pshufb SHUF_MASK(%rip), \XMM3 # perform a 16 byte swap + pshufb SHUF_MASK(%rip), \XMM4 # perform a 16 byte swap + pxor (%arg1), \XMM1 + pxor (%arg1), \XMM2 + pxor (%arg1), \XMM3 + pxor (%arg1), \XMM4 + movdqa HashKey_4_k(%rsp), \TMP5 + PCLMULQDQ 0x00, \TMP5, \TMP6 # TMP6 = (a1+a0)*(b1+b0) + movaps 0x10(%arg1), \TMP1 + AESENC \TMP1, \XMM1 # Round 1 + AESENC \TMP1, \XMM2 + AESENC \TMP1, \XMM3 + AESENC \TMP1, \XMM4 + movaps 0x20(%arg1), \TMP1 + AESENC \TMP1, \XMM1 # Round 2 + AESENC \TMP1, \XMM2 + AESENC \TMP1, \XMM3 + AESENC \TMP1, \XMM4 + movdqa \XMM6, \TMP1 + pshufd $78, \XMM6, \TMP2 + pxor \XMM6, \TMP2 + movdqa HashKey_3(%rsp), \TMP5 + PCLMULQDQ 0x11, \TMP5, \TMP1 # TMP1 = a1 * b1 + movaps 0x30(%arg1), \TMP3 + AESENC \TMP3, \XMM1 # Round 3 + AESENC \TMP3, \XMM2 + AESENC \TMP3, \XMM3 + AESENC \TMP3, \XMM4 + PCLMULQDQ 0x00, \TMP5, \XMM6 # XMM6 = a0*b0 + movaps 0x40(%arg1), \TMP3 + AESENC \TMP3, \XMM1 # Round 4 + AESENC \TMP3, \XMM2 + AESENC \TMP3, \XMM3 + AESENC \TMP3, \XMM4 + movdqa HashKey_3_k(%rsp), \TMP5 + PCLMULQDQ 0x00, \TMP5, \TMP2 # TMP2 = (a1+a0)*(b1+b0) + movaps 0x50(%arg1), \TMP3 + AESENC \TMP3, \XMM1 # Round 5 + AESENC \TMP3, \XMM2 + AESENC \TMP3, \XMM3 + AESENC \TMP3, \XMM4 + pxor \TMP1, \TMP4 +# accumulate the results in TMP4:XMM5, TMP6 holds the middle part + pxor \XMM6, \XMM5 + pxor \TMP2, \TMP6 + movdqa \XMM7, \TMP1 + pshufd $78, \XMM7, \TMP2 + pxor \XMM7, \TMP2 + movdqa HashKey_2(%rsp ), \TMP5 + + # Multiply TMP5 * HashKey using karatsuba + + PCLMULQDQ 0x11, \TMP5, \TMP1 # TMP1 = a1*b1 + movaps 0x60(%arg1), \TMP3 + AESENC \TMP3, \XMM1 # Round 6 + AESENC \TMP3, \XMM2 + AESENC \TMP3, \XMM3 + AESENC \TMP3, \XMM4 + PCLMULQDQ 0x00, \TMP5, \XMM7 # XMM7 = a0*b0 + movaps 0x70(%arg1), \TMP3 + AESENC \TMP3, \XMM1 # Round 7 + AESENC \TMP3, \XMM2 + AESENC \TMP3, \XMM3 + AESENC \TMP3, \XMM4 + movdqa HashKey_2_k(%rsp), \TMP5 + PCLMULQDQ 0x00, \TMP5, \TMP2 # TMP2 = (a1+a0)*(b1+b0) + movaps 0x80(%arg1), \TMP3 + AESENC \TMP3, \XMM1 # Round 8 + AESENC \TMP3, \XMM2 + AESENC \TMP3, \XMM3 + AESENC \TMP3, \XMM4 + pxor \TMP1, \TMP4 +# accumulate the results in TMP4:XMM5, TMP6 holds the middle part + pxor \XMM7, \XMM5 + pxor \TMP2, \TMP6 + + # Multiply XMM8 * HashKey + # XMM8 and TMP5 hold the values for the two operands + + movdqa \XMM8, \TMP1 + pshufd $78, \XMM8, \TMP2 + pxor \XMM8, \TMP2 + movdqa HashKey(%rsp), \TMP5 + PCLMULQDQ 0x11, \TMP5, \TMP1 # TMP1 = a1*b1 + movaps 0x90(%arg1), \TMP3 + AESENC \TMP3, \XMM1 # Round 9 + AESENC \TMP3, \XMM2 + AESENC \TMP3, \XMM3 + AESENC \TMP3, \XMM4 + PCLMULQDQ 0x00, \TMP5, \XMM8 # XMM8 = a0*b0 + movaps 0xa0(%arg1), \TMP3 + AESENCLAST \TMP3, \XMM1 # Round 10 + AESENCLAST \TMP3, \XMM2 + AESENCLAST \TMP3, \XMM3 + AESENCLAST \TMP3, \XMM4 + movdqa HashKey_k(%rsp), \TMP5 + PCLMULQDQ 0x00, \TMP5, \TMP2 # TMP2 = (a1+a0)*(b1+b0) + movdqu (%arg3,%r11,1), \TMP3 + pxor \TMP3, \XMM1 # Ciphertext/Plaintext XOR EK +.if \operation == dec + movdqu \XMM1, (%arg2,%r11,1) # Write to plaintext buffer + movdqa \TMP3, \XMM1 +.endif + movdqu 16(%arg3,%r11,1), \TMP3 + pxor \TMP3, \XMM2 # Ciphertext/Plaintext XOR EK +.if \operation == dec + movdqu \XMM2, 16(%arg2,%r11,1) # Write to plaintext buffer + movdqa \TMP3, \XMM2 +.endif + movdqu 32(%arg3,%r11,1), \TMP3 + pxor \TMP3, \XMM3 # Ciphertext/Plaintext XOR EK +.if \operation == dec + movdqu \XMM3, 32(%arg2,%r11,1) # Write to plaintext buffer + movdqa \TMP3, \XMM3 +.endif + movdqu 48(%arg3,%r11,1), \TMP3 + pxor \TMP3, \XMM4 # Ciphertext/Plaintext XOR EK +.if \operation == dec + movdqu \XMM4, 48(%arg2,%r11,1) # Write to plaintext buffer + movdqa \TMP3, \XMM4 +.else + movdqu \XMM1, (%arg2,%r11,1) # Write to the ciphertext buffer + movdqu \XMM2, 16(%arg2,%r11,1) # Write to the ciphertext buffer + movdqu \XMM3, 32(%arg2,%r11,1) # Write to the ciphertext buffer + movdqu \XMM4, 48(%arg2,%r11,1) # Write to the ciphertext buffer +.endif + pshufb SHUF_MASK(%rip), \XMM1 # perform a 16 byte swap + pshufb SHUF_MASK(%rip), \XMM2 # perform a 16 byte swap + pshufb SHUF_MASK(%rip), \XMM3 # perform a 16 byte swap + pshufb SHUF_MASK(%rip), \XMM4 # perform a 16 byte sway + + pxor \TMP4, \TMP1 + pxor \XMM8, \XMM5 + pxor \TMP6, \TMP2 + pxor \TMP1, \TMP2 + pxor \XMM5, \TMP2 + movdqa \TMP2, \TMP3 + pslldq $8, \TMP3 # left shift TMP3 2 DWs + psrldq $8, \TMP2 # right shift TMP2 2 DWs + pxor \TMP3, \XMM5 + pxor \TMP2, \TMP1 # accumulate the results in TMP1:XMM5 + + # first phase of reduction + + movdqa \XMM5, \TMP2 + movdqa \XMM5, \TMP3 + movdqa \XMM5, \TMP4 +# move XMM5 into TMP2, TMP3, TMP4 in order to perform shifts independently + pslld $31, \TMP2 # packed right shift << 31 + pslld $30, \TMP3 # packed right shift << 30 + pslld $25, \TMP4 # packed right shift << 25 + pxor \TMP3, \TMP2 # xor the shifted versions + pxor \TMP4, \TMP2 + movdqa \TMP2, \TMP5 + psrldq $4, \TMP5 # right shift T5 1 DW + pslldq $12, \TMP2 # left shift T2 3 DWs + pxor \TMP2, \XMM5 + + # second phase of reduction + + movdqa \XMM5,\TMP2 # make 3 copies of XMM5 into TMP2, TMP3, TMP4 + movdqa \XMM5,\TMP3 + movdqa \XMM5,\TMP4 + psrld $1, \TMP2 # packed left shift >>1 + psrld $2, \TMP3 # packed left shift >>2 + psrld $7, \TMP4 # packed left shift >>7 + pxor \TMP3,\TMP2 # xor the shifted versions + pxor \TMP4,\TMP2 + pxor \TMP5, \TMP2 + pxor \TMP2, \XMM5 + pxor \TMP1, \XMM5 # result is in TMP1 + + pxor \XMM5, \XMM1 +.endm + +/* GHASH the last 4 ciphertext blocks. */ +.macro GHASH_LAST_4 TMP1 TMP2 TMP3 TMP4 TMP5 TMP6 \ +TMP7 XMM1 XMM2 XMM3 XMM4 XMMDst + + # Multiply TMP6 * HashKey (using Karatsuba) + + movdqa \XMM1, \TMP6 + pshufd $78, \XMM1, \TMP2 + pxor \XMM1, \TMP2 + movdqa HashKey_4(%rsp), \TMP5 + PCLMULQDQ 0x11, \TMP5, \TMP6 # TMP6 = a1*b1 + PCLMULQDQ 0x00, \TMP5, \XMM1 # XMM1 = a0*b0 + movdqa HashKey_4_k(%rsp), \TMP4 + PCLMULQDQ 0x00, \TMP4, \TMP2 # TMP2 = (a1+a0)*(b1+b0) + movdqa \XMM1, \XMMDst + movdqa \TMP2, \XMM1 # result in TMP6, XMMDst, XMM1 + + # Multiply TMP1 * HashKey (using Karatsuba) + + movdqa \XMM2, \TMP1 + pshufd $78, \XMM2, \TMP2 + pxor \XMM2, \TMP2 + movdqa HashKey_3(%rsp), \TMP5 + PCLMULQDQ 0x11, \TMP5, \TMP1 # TMP1 = a1*b1 + PCLMULQDQ 0x00, \TMP5, \XMM2 # XMM2 = a0*b0 + movdqa HashKey_3_k(%rsp), \TMP4 + PCLMULQDQ 0x00, \TMP4, \TMP2 # TMP2 = (a1+a0)*(b1+b0) + pxor \TMP1, \TMP6 + pxor \XMM2, \XMMDst + pxor \TMP2, \XMM1 +# results accumulated in TMP6, XMMDst, XMM1 + + # Multiply TMP1 * HashKey (using Karatsuba) + + movdqa \XMM3, \TMP1 + pshufd $78, \XMM3, \TMP2 + pxor \XMM3, \TMP2 + movdqa HashKey_2(%rsp), \TMP5 + PCLMULQDQ 0x11, \TMP5, \TMP1 # TMP1 = a1*b1 + PCLMULQDQ 0x00, \TMP5, \XMM3 # XMM3 = a0*b0 + movdqa HashKey_2_k(%rsp), \TMP4 + PCLMULQDQ 0x00, \TMP4, \TMP2 # TMP2 = (a1+a0)*(b1+b0) + pxor \TMP1, \TMP6 + pxor \XMM3, \XMMDst + pxor \TMP2, \XMM1 # results accumulated in TMP6, XMMDst, XMM1 + + # Multiply TMP1 * HashKey (using Karatsuba) + movdqa \XMM4, \TMP1 + pshufd $78, \XMM4, \TMP2 + pxor \XMM4, \TMP2 + movdqa HashKey(%rsp), \TMP5 + PCLMULQDQ 0x11, \TMP5, \TMP1 # TMP1 = a1*b1 + PCLMULQDQ 0x00, \TMP5, \XMM4 # XMM4 = a0*b0 + movdqa HashKey_k(%rsp), \TMP4 + PCLMULQDQ 0x00, \TMP4, \TMP2 # TMP2 = (a1+a0)*(b1+b0) + pxor \TMP1, \TMP6 + pxor \XMM4, \XMMDst + pxor \XMM1, \TMP2 + pxor \TMP6, \TMP2 + pxor \XMMDst, \TMP2 + # middle section of the temp results combined as in karatsuba algorithm + movdqa \TMP2, \TMP4 + pslldq $8, \TMP4 # left shift TMP4 2 DWs + psrldq $8, \TMP2 # right shift TMP2 2 DWs + pxor \TMP4, \XMMDst + pxor \TMP2, \TMP6 +# TMP6:XMMDst holds the result of the accumulated carry-less multiplications + # first phase of the reduction + movdqa \XMMDst, \TMP2 + movdqa \XMMDst, \TMP3 + movdqa \XMMDst, \TMP4 +# move XMMDst into TMP2, TMP3, TMP4 in order to perform 3 shifts independently + pslld $31, \TMP2 # packed right shifting << 31 + pslld $30, \TMP3 # packed right shifting << 30 + pslld $25, \TMP4 # packed right shifting << 25 + pxor \TMP3, \TMP2 # xor the shifted versions + pxor \TMP4, \TMP2 + movdqa \TMP2, \TMP7 + psrldq $4, \TMP7 # right shift TMP7 1 DW + pslldq $12, \TMP2 # left shift TMP2 3 DWs + pxor \TMP2, \XMMDst + + # second phase of the reduction + movdqa \XMMDst, \TMP2 + # make 3 copies of XMMDst for doing 3 shift operations + movdqa \XMMDst, \TMP3 + movdqa \XMMDst, \TMP4 + psrld $1, \TMP2 # packed left shift >> 1 + psrld $2, \TMP3 # packed left shift >> 2 + psrld $7, \TMP4 # packed left shift >> 7 + pxor \TMP3, \TMP2 # xor the shifted versions + pxor \TMP4, \TMP2 + pxor \TMP7, \TMP2 + pxor \TMP2, \XMMDst + pxor \TMP6, \XMMDst # reduced result is in XMMDst +.endm + +/* Encryption of a single block done*/ +.macro ENCRYPT_SINGLE_BLOCK XMM0 TMP1 + + pxor (%arg1), \XMM0 + movaps 16(%arg1), \TMP1 + AESENC \TMP1, \XMM0 + movaps 32(%arg1), \TMP1 + AESENC \TMP1, \XMM0 + movaps 48(%arg1), \TMP1 + AESENC \TMP1, \XMM0 + movaps 64(%arg1), \TMP1 + AESENC \TMP1, \XMM0 + movaps 80(%arg1), \TMP1 + AESENC \TMP1, \XMM0 + movaps 96(%arg1), \TMP1 + AESENC \TMP1, \XMM0 + movaps 112(%arg1), \TMP1 + AESENC \TMP1, \XMM0 + movaps 128(%arg1), \TMP1 + AESENC \TMP1, \XMM0 + movaps 144(%arg1), \TMP1 + AESENC \TMP1, \XMM0 + movaps 160(%arg1), \TMP1 + AESENCLAST \TMP1, \XMM0 +.endm + + +/***************************************************************************** +* void aesni_gcm_dec(void *aes_ctx, // AES Key schedule. Starts on a 16 byte boundary. +* u8 *out, // Plaintext output. Encrypt in-place is allowed. +* const u8 *in, // Ciphertext input +* u64 plaintext_len, // Length of data in bytes for decryption. +* u8 *iv, // Pre-counter block j0: 4 byte salt (from Security Association) +* // concatenated with 8 byte Initialisation Vector (from IPSec ESP Payload) +* // concatenated with 0x00000001. 16-byte aligned pointer. +* u8 *hash_subkey, // H, the Hash sub key input. Data starts on a 16-byte boundary. +* const u8 *aad, // Additional Authentication Data (AAD) +* u64 aad_len, // Length of AAD in bytes. With RFC4106 this is going to be 8 or 12 bytes +* u8 *auth_tag, // Authenticated Tag output. The driver will compare this to the +* // given authentication tag and only return the plaintext if they match. +* u64 auth_tag_len); // Authenticated Tag Length in bytes. Valid values are 16 +* // (most likely), 12 or 8. +* +* Assumptions: +* +* keys: +* keys are pre-expanded and aligned to 16 bytes. we are using the first +* set of 11 keys in the data structure void *aes_ctx +* +* iv: +* 0 1 2 3 +* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +* | Salt (From the SA) | +* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +* | Initialization Vector | +* | (This is the sequence number from IPSec header) | +* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +* | 0x1 | +* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +* +* +* +* AAD: +* AAD padded to 128 bits with 0 +* for example, assume AAD is a u32 vector +* +* if AAD is 8 bytes: +* AAD[3] = {A0, A1}; +* padded AAD in xmm register = {A1 A0 0 0} +* +* 0 1 2 3 +* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +* | SPI (A1) | +* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +* | 32-bit Sequence Number (A0) | +* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +* | 0x0 | +* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +* +* AAD Format with 32-bit Sequence Number +* +* if AAD is 12 bytes: +* AAD[3] = {A0, A1, A2}; +* padded AAD in xmm register = {A2 A1 A0 0} +* +* 0 1 2 3 +* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +* | SPI (A2) | +* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +* | 64-bit Extended Sequence Number {A1,A0} | +* | | +* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +* | 0x0 | +* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +* +* AAD Format with 64-bit Extended Sequence Number +* +* aadLen: +* from the definition of the spec, aadLen can only be 8 or 12 bytes. +* The code supports 16 too but for other sizes, the code will fail. +* +* TLen: +* from the definition of the spec, TLen can only be 8, 12 or 16 bytes. +* For other sizes, the code will fail. +* +* poly = x^128 + x^127 + x^126 + x^121 + 1 +* +*****************************************************************************/ + +ENTRY(aesni_gcm_dec) + push %r12 + push %r13 + push %r14 + mov %rsp, %r14 +/* +* states of %xmm registers %xmm6:%xmm15 not saved +* all %xmm registers are clobbered +*/ + sub $VARIABLE_OFFSET, %rsp + and $~63, %rsp # align rsp to 64 bytes + mov %arg6, %r12 + movdqu (%r12), %xmm13 # %xmm13 = HashKey + pshufb SHUF_MASK(%rip), %xmm13 + +# Precompute HashKey<<1 (mod poly) from the hash key (required for GHASH) + + movdqa %xmm13, %xmm2 + psllq $1, %xmm13 + psrlq $63, %xmm2 + movdqa %xmm2, %xmm1 + pslldq $8, %xmm2 + psrldq $8, %xmm1 + por %xmm2, %xmm13 + + # Reduction + + pshufd $0x24, %xmm1, %xmm2 + pcmpeqd TWOONE(%rip), %xmm2 + pand POLY(%rip), %xmm2 + pxor %xmm2, %xmm13 # %xmm13 holds the HashKey<<1 (mod poly) + + + # Decrypt first few blocks + + movdqa %xmm13, HashKey(%rsp) # store HashKey<<1 (mod poly) + mov %arg4, %r13 # save the number of bytes of plaintext/ciphertext + and $-16, %r13 # %r13 = %r13 - (%r13 mod 16) + mov %r13, %r12 + and $(3<<4), %r12 + jz _initial_num_blocks_is_0_decrypt + cmp $(2<<4), %r12 + jb _initial_num_blocks_is_1_decrypt + je _initial_num_blocks_is_2_decrypt +_initial_num_blocks_is_3_decrypt: + INITIAL_BLOCKS 3, %xmm9, %xmm10, %xmm13, %xmm11, %xmm12, %xmm0, \ +%xmm1, %xmm2, %xmm3, %xmm4, %xmm8, %xmm5, %xmm6, 5, 678, dec + sub $48, %r13 + jmp _initial_blocks_decrypted +_initial_num_blocks_is_2_decrypt: + INITIAL_BLOCKS 2, %xmm9, %xmm10, %xmm13, %xmm11, %xmm12, %xmm0, \ +%xmm1, %xmm2, %xmm3, %xmm4, %xmm8, %xmm5, %xmm6, 6, 78, dec + sub $32, %r13 + jmp _initial_blocks_decrypted +_initial_num_blocks_is_1_decrypt: + INITIAL_BLOCKS 1, %xmm9, %xmm10, %xmm13, %xmm11, %xmm12, %xmm0, \ +%xmm1, %xmm2, %xmm3, %xmm4, %xmm8, %xmm5, %xmm6, 7, 8, dec + sub $16, %r13 + jmp _initial_blocks_decrypted +_initial_num_blocks_is_0_decrypt: + INITIAL_BLOCKS 0, %xmm9, %xmm10, %xmm13, %xmm11, %xmm12, %xmm0, \ +%xmm1, %xmm2, %xmm3, %xmm4, %xmm8, %xmm5, %xmm6, 8, 0, dec +_initial_blocks_decrypted: + cmp $0, %r13 + je _zero_cipher_left_decrypt + sub $64, %r13 + je _four_cipher_left_decrypt +_decrypt_by_4: + GHASH_4_ENCRYPT_4_PARALLEL %xmm9, %xmm10, %xmm11, %xmm12, %xmm13, \ +%xmm14, %xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %xmm6, %xmm7, %xmm8, dec + add $64, %r11 + sub $64, %r13 + jne _decrypt_by_4 +_four_cipher_left_decrypt: + GHASH_LAST_4 %xmm9, %xmm10, %xmm11, %xmm12, %xmm13, %xmm14, \ +%xmm15, %xmm1, %xmm2, %xmm3, %xmm4, %xmm8 +_zero_cipher_left_decrypt: + mov %arg4, %r13 + and $15, %r13 # %r13 = arg4 (mod 16) + je _multiple_of_16_bytes_decrypt + + # Handle the last <16 byte block seperately + + paddd ONE(%rip), %xmm0 # increment CNT to get Yn + pshufb SHUF_MASK(%rip), %xmm0 + ENCRYPT_SINGLE_BLOCK %xmm0, %xmm1 # E(K, Yn) + sub $16, %r11 + add %r13, %r11 + movdqu (%arg3,%r11,1), %xmm1 # recieve the last <16 byte block + lea SHIFT_MASK+16(%rip), %r12 + sub %r13, %r12 +# adjust the shuffle mask pointer to be able to shift 16-%r13 bytes +# (%r13 is the number of bytes in plaintext mod 16) + movdqu (%r12), %xmm2 # get the appropriate shuffle mask + pshufb %xmm2, %xmm1 # right shift 16-%r13 butes + movdqa %xmm1, %xmm2 + pxor %xmm1, %xmm0 # Ciphertext XOR E(K, Yn) + movdqu ALL_F-SHIFT_MASK(%r12), %xmm1 + # get the appropriate mask to mask out top 16-%r13 bytes of %xmm0 + pand %xmm1, %xmm0 # mask out top 16-%r13 bytes of %xmm0 + pand %xmm1, %xmm2 + pshufb SHUF_MASK(%rip),%xmm2 + pxor %xmm2, %xmm8 + GHASH_MUL %xmm8, %xmm13, %xmm9, %xmm10, %xmm11, %xmm5, %xmm6 + # GHASH computation for the last <16 byte block + sub %r13, %r11 + add $16, %r11 + + # output %r13 bytes + movq %xmm0, %rax + cmp $8, %r13 + jle _less_than_8_bytes_left_decrypt + mov %rax, (%arg2 , %r11, 1) + add $8, %r11 + psrldq $8, %xmm0 + movq %xmm0, %rax + sub $8, %r13 +_less_than_8_bytes_left_decrypt: + mov %al, (%arg2, %r11, 1) + add $1, %r11 + shr $8, %rax + sub $1, %r13 + jne _less_than_8_bytes_left_decrypt +_multiple_of_16_bytes_decrypt: + mov arg8, %r12 # %r13 = aadLen (number of bytes) + shl $3, %r12 # convert into number of bits + movd %r12d, %xmm15 # len(A) in %xmm15 + shl $3, %arg4 # len(C) in bits (*128) + movq %arg4, %xmm1 + pslldq $8, %xmm15 # %xmm15 = len(A)||0x0000000000000000 + pxor %xmm1, %xmm15 # %xmm15 = len(A)||len(C) + pxor %xmm15, %xmm8 + GHASH_MUL %xmm8, %xmm13, %xmm9, %xmm10, %xmm11, %xmm5, %xmm6 + # final GHASH computation + pshufb SHUF_MASK(%rip), %xmm8 + mov %arg5, %rax # %rax = *Y0 + movdqu (%rax), %xmm0 # %xmm0 = Y0 + ENCRYPT_SINGLE_BLOCK %xmm0, %xmm1 # E(K, Y0) + pxor %xmm8, %xmm0 +_return_T_decrypt: + mov arg9, %r10 # %r10 = authTag + mov arg10, %r11 # %r11 = auth_tag_len + cmp $16, %r11 + je _T_16_decrypt + cmp $12, %r11 + je _T_12_decrypt +_T_8_decrypt: + movq %xmm0, %rax + mov %rax, (%r10) + jmp _return_T_done_decrypt +_T_12_decrypt: + movq %xmm0, %rax + mov %rax, (%r10) + psrldq $8, %xmm0 + movd %xmm0, %eax + mov %eax, 8(%r10) + jmp _return_T_done_decrypt +_T_16_decrypt: + movdqu %xmm0, (%r10) +_return_T_done_decrypt: + mov %r14, %rsp + pop %r14 + pop %r13 + pop %r12 + ret + + +/***************************************************************************** +* void aesni_gcm_enc(void *aes_ctx, // AES Key schedule. Starts on a 16 byte boundary. +* u8 *out, // Ciphertext output. Encrypt in-place is allowed. +* const u8 *in, // Plaintext input +* u64 plaintext_len, // Length of data in bytes for encryption. +* u8 *iv, // Pre-counter block j0: 4 byte salt (from Security Association) +* // concatenated with 8 byte Initialisation Vector (from IPSec ESP Payload) +* // concatenated with 0x00000001. 16-byte aligned pointer. +* u8 *hash_subkey, // H, the Hash sub key input. Data starts on a 16-byte boundary. +* const u8 *aad, // Additional Authentication Data (AAD) +* u64 aad_len, // Length of AAD in bytes. With RFC4106 this is going to be 8 or 12 bytes +* u8 *auth_tag, // Authenticated Tag output. +* u64 auth_tag_len); // Authenticated Tag Length in bytes. Valid values are 16 (most likely), +* // 12 or 8. +* +* Assumptions: +* +* keys: +* keys are pre-expanded and aligned to 16 bytes. we are using the +* first set of 11 keys in the data structure void *aes_ctx +* +* +* iv: +* 0 1 2 3 +* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +* | Salt (From the SA) | +* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +* | Initialization Vector | +* | (This is the sequence number from IPSec header) | +* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +* | 0x1 | +* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +* +* +* +* AAD: +* AAD padded to 128 bits with 0 +* for example, assume AAD is a u32 vector +* +* if AAD is 8 bytes: +* AAD[3] = {A0, A1}; +* padded AAD in xmm register = {A1 A0 0 0} +* +* 0 1 2 3 +* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +* | SPI (A1) | +* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +* | 32-bit Sequence Number (A0) | +* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +* | 0x0 | +* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +* +* AAD Format with 32-bit Sequence Number +* +* if AAD is 12 bytes: +* AAD[3] = {A0, A1, A2}; +* padded AAD in xmm register = {A2 A1 A0 0} +* +* 0 1 2 3 +* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +* | SPI (A2) | +* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +* | 64-bit Extended Sequence Number {A1,A0} | +* | | +* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +* | 0x0 | +* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ +* +* AAD Format with 64-bit Extended Sequence Number +* +* aadLen: +* from the definition of the spec, aadLen can only be 8 or 12 bytes. +* The code supports 16 too but for other sizes, the code will fail. +* +* TLen: +* from the definition of the spec, TLen can only be 8, 12 or 16 bytes. +* For other sizes, the code will fail. +* +* poly = x^128 + x^127 + x^126 + x^121 + 1 +***************************************************************************/ +ENTRY(aesni_gcm_enc) + push %r12 + push %r13 + push %r14 + mov %rsp, %r14 +# +# states of %xmm registers %xmm6:%xmm15 not saved +# all %xmm registers are clobbered +# + sub $VARIABLE_OFFSET, %rsp + and $~63, %rsp + mov %arg6, %r12 + movdqu (%r12), %xmm13 + pshufb SHUF_MASK(%rip), %xmm13 + +# precompute HashKey<<1 mod poly from the HashKey (required for GHASH) + + movdqa %xmm13, %xmm2 + psllq $1, %xmm13 + psrlq $63, %xmm2 + movdqa %xmm2, %xmm1 + pslldq $8, %xmm2 + psrldq $8, %xmm1 + por %xmm2, %xmm13 + + # reduce HashKey<<1 + + pshufd $0x24, %xmm1, %xmm2 + pcmpeqd TWOONE(%rip), %xmm2 + pand POLY(%rip), %xmm2 + pxor %xmm2, %xmm13 + movdqa %xmm13, HashKey(%rsp) + mov %arg4, %r13 # %xmm13 holds HashKey<<1 (mod poly) + and $-16, %r13 + mov %r13, %r12 + + # Encrypt first few blocks + + and $(3<<4), %r12 + jz _initial_num_blocks_is_0_encrypt + cmp $(2<<4), %r12 + jb _initial_num_blocks_is_1_encrypt + je _initial_num_blocks_is_2_encrypt +_initial_num_blocks_is_3_encrypt: + INITIAL_BLOCKS 3, %xmm9, %xmm10, %xmm13, %xmm11, %xmm12, %xmm0, \ +%xmm1, %xmm2, %xmm3, %xmm4, %xmm8, %xmm5, %xmm6, 5, 678, enc + sub $48, %r13 + jmp _initial_blocks_encrypted +_initial_num_blocks_is_2_encrypt: + INITIAL_BLOCKS 2, %xmm9, %xmm10, %xmm13, %xmm11, %xmm12, %xmm0, \ +%xmm1, %xmm2, %xmm3, %xmm4, %xmm8, %xmm5, %xmm6, 6, 78, enc + sub $32, %r13 + jmp _initial_blocks_encrypted +_initial_num_blocks_is_1_encrypt: + INITIAL_BLOCKS 1, %xmm9, %xmm10, %xmm13, %xmm11, %xmm12, %xmm0, \ +%xmm1, %xmm2, %xmm3, %xmm4, %xmm8, %xmm5, %xmm6, 7, 8, enc + sub $16, %r13 + jmp _initial_blocks_encrypted +_initial_num_blocks_is_0_encrypt: + INITIAL_BLOCKS 0, %xmm9, %xmm10, %xmm13, %xmm11, %xmm12, %xmm0, \ +%xmm1, %xmm2, %xmm3, %xmm4, %xmm8, %xmm5, %xmm6, 8, 0, enc +_initial_blocks_encrypted: + + # Main loop - Encrypt remaining blocks + + cmp $0, %r13 + je _zero_cipher_left_encrypt + sub $64, %r13 + je _four_cipher_left_encrypt +_encrypt_by_4_encrypt: + GHASH_4_ENCRYPT_4_PARALLEL %xmm9, %xmm10, %xmm11, %xmm12, %xmm13, \ +%xmm14, %xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %xmm6, %xmm7, %xmm8, enc + add $64, %r11 + sub $64, %r13 + jne _encrypt_by_4_encrypt +_four_cipher_left_encrypt: + GHASH_LAST_4 %xmm9, %xmm10, %xmm11, %xmm12, %xmm13, %xmm14, \ +%xmm15, %xmm1, %xmm2, %xmm3, %xmm4, %xmm8 +_zero_cipher_left_encrypt: + mov %arg4, %r13 + and $15, %r13 # %r13 = arg4 (mod 16) + je _multiple_of_16_bytes_encrypt + + # Handle the last <16 Byte block seperately + paddd ONE(%rip), %xmm0 # INCR CNT to get Yn + pshufb SHUF_MASK(%rip), %xmm0 + ENCRYPT_SINGLE_BLOCK %xmm0, %xmm1 # Encrypt(K, Yn) + sub $16, %r11 + add %r13, %r11 + movdqu (%arg3,%r11,1), %xmm1 # receive the last <16 byte blocks + lea SHIFT_MASK+16(%rip), %r12 + sub %r13, %r12 + # adjust the shuffle mask pointer to be able to shift 16-r13 bytes + # (%r13 is the number of bytes in plaintext mod 16) + movdqu (%r12), %xmm2 # get the appropriate shuffle mask + pshufb %xmm2, %xmm1 # shift right 16-r13 byte + pxor %xmm1, %xmm0 # Plaintext XOR Encrypt(K, Yn) + movdqu ALL_F-SHIFT_MASK(%r12), %xmm1 + # get the appropriate mask to mask out top 16-r13 bytes of xmm0 + pand %xmm1, %xmm0 # mask out top 16-r13 bytes of xmm0 + + pshufb SHUF_MASK(%rip),%xmm0 + pxor %xmm0, %xmm8 + GHASH_MUL %xmm8, %xmm13, %xmm9, %xmm10, %xmm11, %xmm5, %xmm6 + # GHASH computation for the last <16 byte block + sub %r13, %r11 + add $16, %r11 + pshufb SHUF_MASK(%rip), %xmm0 + # shuffle xmm0 back to output as ciphertext + + # Output %r13 bytes + movq %xmm0, %rax + cmp $8, %r13 + jle _less_than_8_bytes_left_encrypt + mov %rax, (%arg2 , %r11, 1) + add $8, %r11 + psrldq $8, %xmm0 + movq %xmm0, %rax + sub $8, %r13 +_less_than_8_bytes_left_encrypt: + mov %al, (%arg2, %r11, 1) + add $1, %r11 + shr $8, %rax + sub $1, %r13 + jne _less_than_8_bytes_left_encrypt +_multiple_of_16_bytes_encrypt: + mov arg8, %r12 # %r12 = addLen (number of bytes) + shl $3, %r12 + movd %r12d, %xmm15 # len(A) in %xmm15 + shl $3, %arg4 # len(C) in bits (*128) + movq %arg4, %xmm1 + pslldq $8, %xmm15 # %xmm15 = len(A)||0x0000000000000000 + pxor %xmm1, %xmm15 # %xmm15 = len(A)||len(C) + pxor %xmm15, %xmm8 + GHASH_MUL %xmm8, %xmm13, %xmm9, %xmm10, %xmm11, %xmm5, %xmm6 + # final GHASH computation + + pshufb SHUF_MASK(%rip), %xmm8 # perform a 16 byte swap + mov %arg5, %rax # %rax = *Y0 + movdqu (%rax), %xmm0 # %xmm0 = Y0 + ENCRYPT_SINGLE_BLOCK %xmm0, %xmm15 # Encrypt(K, Y0) + pxor %xmm8, %xmm0 +_return_T_encrypt: + mov arg9, %r10 # %r10 = authTag + mov arg10, %r11 # %r11 = auth_tag_len + cmp $16, %r11 + je _T_16_encrypt + cmp $12, %r11 + je _T_12_encrypt +_T_8_encrypt: + movq %xmm0, %rax + mov %rax, (%r10) + jmp _return_T_done_encrypt +_T_12_encrypt: + movq %xmm0, %rax + mov %rax, (%r10) + psrldq $8, %xmm0 + movd %xmm0, %eax + mov %eax, 8(%r10) + jmp _return_T_done_encrypt +_T_16_encrypt: + movdqu %xmm0, (%r10) +_return_T_done_encrypt: + mov %r14, %rsp + pop %r14 + pop %r13 + pop %r12 + ret + + + _key_expansion_128: _key_expansion_256a: pshufd $0b11111111, %xmm1, %xmm1 diff --git a/arch/x86/crypto/aesni-intel_glue.c b/arch/x86/crypto/aesni-intel_glue.c index 2cb3dcc4490a..02d349d64423 100644 --- a/arch/x86/crypto/aesni-intel_glue.c +++ b/arch/x86/crypto/aesni-intel_glue.c @@ -5,6 +5,14 @@ * Copyright (C) 2008, Intel Corp. * Author: Huang Ying * + * Added RFC4106 AES-GCM support for 128-bit keys under the AEAD + * interface for 64-bit kernels. + * Authors: Adrian Hoban + * Gabriele Paoloni + * Tadeusz Struk (tadeusz.struk@intel.com) + * Aidan O'Mahony (aidan.o.mahony@intel.com) + * Copyright (c) 2010, Intel Corporation. + * * 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 @@ -21,6 +29,10 @@ #include #include #include +#include +#include +#include +#include #if defined(CONFIG_CRYPTO_CTR) || defined(CONFIG_CRYPTO_CTR_MODULE) #define HAS_CTR @@ -42,8 +54,31 @@ struct async_aes_ctx { struct cryptd_ablkcipher *cryptd_tfm; }; -#define AESNI_ALIGN 16 +/* This data is stored at the end of the crypto_tfm struct. + * It's a type of per "session" data storage location. + * This needs to be 16 byte aligned. + */ +struct aesni_rfc4106_gcm_ctx { + u8 hash_subkey[16]; + struct crypto_aes_ctx aes_key_expanded; + u8 nonce[4]; + struct cryptd_aead *cryptd_tfm; +}; + +struct aesni_gcm_set_hash_subkey_result { + int err; + struct completion completion; +}; + +struct aesni_hash_subkey_req_data { + u8 iv[16]; + struct aesni_gcm_set_hash_subkey_result result; + struct scatterlist sg; +}; + +#define AESNI_ALIGN (16) #define AES_BLOCK_MASK (~(AES_BLOCK_SIZE-1)) +#define RFC4106_HASH_SUBKEY_SIZE 16 asmlinkage int aesni_set_key(struct crypto_aes_ctx *ctx, const u8 *in_key, unsigned int key_len); @@ -62,6 +97,57 @@ asmlinkage void aesni_cbc_dec(struct crypto_aes_ctx *ctx, u8 *out, asmlinkage void aesni_ctr_enc(struct crypto_aes_ctx *ctx, u8 *out, const u8 *in, unsigned int len, u8 *iv); +/* asmlinkage void aesni_gcm_enc() + * void *ctx, AES Key schedule. Starts on a 16 byte boundary. + * u8 *out, Ciphertext output. Encrypt in-place is allowed. + * const u8 *in, Plaintext input + * unsigned long plaintext_len, Length of data in bytes for encryption. + * u8 *iv, Pre-counter block j0: 4 byte salt (from Security Association) + * concatenated with 8 byte Initialisation Vector (from IPSec ESP + * Payload) concatenated with 0x00000001. 16-byte aligned pointer. + * u8 *hash_subkey, the Hash sub key input. Data starts on a 16-byte boundary. + * const u8 *aad, Additional Authentication Data (AAD) + * unsigned long aad_len, Length of AAD in bytes. With RFC4106 this + * is going to be 8 or 12 bytes + * u8 *auth_tag, Authenticated Tag output. + * unsigned long auth_tag_len), Authenticated Tag Length in bytes. + * Valid values are 16 (most likely), 12 or 8. + */ +asmlinkage void aesni_gcm_enc(void *ctx, u8 *out, + const u8 *in, unsigned long plaintext_len, u8 *iv, + u8 *hash_subkey, const u8 *aad, unsigned long aad_len, + u8 *auth_tag, unsigned long auth_tag_len); + +/* asmlinkage void aesni_gcm_dec() + * void *ctx, AES Key schedule. Starts on a 16 byte boundary. + * u8 *out, Plaintext output. Decrypt in-place is allowed. + * const u8 *in, Ciphertext input + * unsigned long ciphertext_len, Length of data in bytes for decryption. + * u8 *iv, Pre-counter block j0: 4 byte salt (from Security Association) + * concatenated with 8 byte Initialisation Vector (from IPSec ESP + * Payload) concatenated with 0x00000001. 16-byte aligned pointer. + * u8 *hash_subkey, the Hash sub key input. Data starts on a 16-byte boundary. + * const u8 *aad, Additional Authentication Data (AAD) + * unsigned long aad_len, Length of AAD in bytes. With RFC4106 this is going + * to be 8 or 12 bytes + * u8 *auth_tag, Authenticated Tag output. + * unsigned long auth_tag_len) Authenticated Tag Length in bytes. + * Valid values are 16 (most likely), 12 or 8. + */ +asmlinkage void aesni_gcm_dec(void *ctx, u8 *out, + const u8 *in, unsigned long ciphertext_len, u8 *iv, + u8 *hash_subkey, const u8 *aad, unsigned long aad_len, + u8 *auth_tag, unsigned long auth_tag_len); + +static inline struct +aesni_rfc4106_gcm_ctx *aesni_rfc4106_gcm_ctx_get(struct crypto_aead *tfm) +{ + return + (struct aesni_rfc4106_gcm_ctx *) + PTR_ALIGN((u8 *) + crypto_tfm_ctx(crypto_aead_tfm(tfm)), AESNI_ALIGN); +} + static inline struct crypto_aes_ctx *aes_ctx(void *raw_ctx) { unsigned long addr = (unsigned long)raw_ctx; @@ -730,6 +816,422 @@ static struct crypto_alg ablk_xts_alg = { }; #endif +static int rfc4106_init(struct crypto_tfm *tfm) +{ + struct cryptd_aead *cryptd_tfm; + struct aesni_rfc4106_gcm_ctx *ctx = (struct aesni_rfc4106_gcm_ctx *) + PTR_ALIGN((u8 *)crypto_tfm_ctx(tfm), AESNI_ALIGN); + cryptd_tfm = cryptd_alloc_aead("__driver-gcm-aes-aesni", 0, 0); + if (IS_ERR(cryptd_tfm)) + return PTR_ERR(cryptd_tfm); + ctx->cryptd_tfm = cryptd_tfm; + tfm->crt_aead.reqsize = sizeof(struct aead_request) + + crypto_aead_reqsize(&cryptd_tfm->base); + return 0; +} + +static void rfc4106_exit(struct crypto_tfm *tfm) +{ + struct aesni_rfc4106_gcm_ctx *ctx = + (struct aesni_rfc4106_gcm_ctx *) + PTR_ALIGN((u8 *)crypto_tfm_ctx(tfm), AESNI_ALIGN); + if (!IS_ERR(ctx->cryptd_tfm)) + cryptd_free_aead(ctx->cryptd_tfm); + return; +} + +static void +rfc4106_set_hash_subkey_done(struct crypto_async_request *req, int err) +{ + struct aesni_gcm_set_hash_subkey_result *result = req->data; + + if (err == -EINPROGRESS) + return; + result->err = err; + complete(&result->completion); +} + +static int +rfc4106_set_hash_subkey(u8 *hash_subkey, const u8 *key, unsigned int key_len) +{ + struct crypto_ablkcipher *ctr_tfm; + struct ablkcipher_request *req; + int ret = -EINVAL; + struct aesni_hash_subkey_req_data *req_data; + + ctr_tfm = crypto_alloc_ablkcipher("ctr(aes)", 0, 0); + if (IS_ERR(ctr_tfm)) + return PTR_ERR(ctr_tfm); + + crypto_ablkcipher_clear_flags(ctr_tfm, ~0); + + ret = crypto_ablkcipher_setkey(ctr_tfm, key, key_len); + if (ret) { + crypto_free_ablkcipher(ctr_tfm); + return ret; + } + + req = ablkcipher_request_alloc(ctr_tfm, GFP_KERNEL); + if (!req) { + crypto_free_ablkcipher(ctr_tfm); + return -EINVAL; + } + + req_data = kmalloc(sizeof(*req_data), GFP_KERNEL); + if (!req_data) { + crypto_free_ablkcipher(ctr_tfm); + return -ENOMEM; + } + memset(req_data->iv, 0, sizeof(req_data->iv)); + + /* Clear the data in the hash sub key container to zero.*/ + /* We want to cipher all zeros to create the hash sub key. */ + memset(hash_subkey, 0, RFC4106_HASH_SUBKEY_SIZE); + + init_completion(&req_data->result.completion); + sg_init_one(&req_data->sg, hash_subkey, RFC4106_HASH_SUBKEY_SIZE); + ablkcipher_request_set_tfm(req, ctr_tfm); + ablkcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_SLEEP | + CRYPTO_TFM_REQ_MAY_BACKLOG, + rfc4106_set_hash_subkey_done, + &req_data->result); + + ablkcipher_request_set_crypt(req, &req_data->sg, + &req_data->sg, RFC4106_HASH_SUBKEY_SIZE, req_data->iv); + + ret = crypto_ablkcipher_encrypt(req); + if (ret == -EINPROGRESS || ret == -EBUSY) { + ret = wait_for_completion_interruptible + (&req_data->result.completion); + if (!ret) + ret = req_data->result.err; + } + ablkcipher_request_free(req); + kfree(req_data); + crypto_free_ablkcipher(ctr_tfm); + return ret; +} + +static int rfc4106_set_key(struct crypto_aead *parent, const u8 *key, + unsigned int key_len) +{ + int ret = 0; + struct crypto_tfm *tfm = crypto_aead_tfm(parent); + struct aesni_rfc4106_gcm_ctx *ctx = aesni_rfc4106_gcm_ctx_get(parent); + u8 *new_key_mem = NULL; + + if (key_len < 4) { + crypto_tfm_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN); + return -EINVAL; + } + /*Account for 4 byte nonce at the end.*/ + key_len -= 4; + if (key_len != AES_KEYSIZE_128) { + crypto_tfm_set_flags(tfm, CRYPTO_TFM_RES_BAD_KEY_LEN); + return -EINVAL; + } + + memcpy(ctx->nonce, key + key_len, sizeof(ctx->nonce)); + /*This must be on a 16 byte boundary!*/ + if ((unsigned long)(&(ctx->aes_key_expanded.key_enc[0])) % AESNI_ALIGN) + return -EINVAL; + + if ((unsigned long)key % AESNI_ALIGN) { + /*key is not aligned: use an auxuliar aligned pointer*/ + new_key_mem = kmalloc(key_len+AESNI_ALIGN, GFP_KERNEL); + if (!new_key_mem) + return -ENOMEM; + + new_key_mem = PTR_ALIGN(new_key_mem, AESNI_ALIGN); + memcpy(new_key_mem, key, key_len); + key = new_key_mem; + } + + if (!irq_fpu_usable()) + ret = crypto_aes_expand_key(&(ctx->aes_key_expanded), + key, key_len); + else { + kernel_fpu_begin(); + ret = aesni_set_key(&(ctx->aes_key_expanded), key, key_len); + kernel_fpu_end(); + } + /*This must be on a 16 byte boundary!*/ + if ((unsigned long)(&(ctx->hash_subkey[0])) % AESNI_ALIGN) { + ret = -EINVAL; + goto exit; + } + ret = rfc4106_set_hash_subkey(ctx->hash_subkey, key, key_len); +exit: + kfree(new_key_mem); + return ret; +} + +/* This is the Integrity Check Value (aka the authentication tag length and can + * be 8, 12 or 16 bytes long. */ +static int rfc4106_set_authsize(struct crypto_aead *parent, + unsigned int authsize) +{ + struct aesni_rfc4106_gcm_ctx *ctx = aesni_rfc4106_gcm_ctx_get(parent); + struct crypto_aead *cryptd_child = cryptd_aead_child(ctx->cryptd_tfm); + + switch (authsize) { + case 8: + case 12: + case 16: + break; + default: + return -EINVAL; + } + crypto_aead_crt(parent)->authsize = authsize; + crypto_aead_crt(cryptd_child)->authsize = authsize; + return 0; +} + +static int rfc4106_encrypt(struct aead_request *req) +{ + int ret; + struct crypto_aead *tfm = crypto_aead_reqtfm(req); + struct aesni_rfc4106_gcm_ctx *ctx = aesni_rfc4106_gcm_ctx_get(tfm); + struct crypto_aead *cryptd_child = cryptd_aead_child(ctx->cryptd_tfm); + + if (!irq_fpu_usable()) { + struct aead_request *cryptd_req = + (struct aead_request *) aead_request_ctx(req); + memcpy(cryptd_req, req, sizeof(*req)); + aead_request_set_tfm(cryptd_req, &ctx->cryptd_tfm->base); + return crypto_aead_encrypt(cryptd_req); + } else { + kernel_fpu_begin(); + ret = cryptd_child->base.crt_aead.encrypt(req); + kernel_fpu_end(); + return ret; + } +} + +static int rfc4106_decrypt(struct aead_request *req) +{ + int ret; + struct crypto_aead *tfm = crypto_aead_reqtfm(req); + struct aesni_rfc4106_gcm_ctx *ctx = aesni_rfc4106_gcm_ctx_get(tfm); + struct crypto_aead *cryptd_child = cryptd_aead_child(ctx->cryptd_tfm); + + if (!irq_fpu_usable()) { + struct aead_request *cryptd_req = + (struct aead_request *) aead_request_ctx(req); + memcpy(cryptd_req, req, sizeof(*req)); + aead_request_set_tfm(cryptd_req, &ctx->cryptd_tfm->base); + return crypto_aead_decrypt(cryptd_req); + } else { + kernel_fpu_begin(); + ret = cryptd_child->base.crt_aead.decrypt(req); + kernel_fpu_end(); + return ret; + } +} + +static struct crypto_alg rfc4106_alg = { + .cra_name = "rfc4106(gcm(aes))", + .cra_driver_name = "rfc4106-gcm-aesni", + .cra_priority = 400, + .cra_flags = CRYPTO_ALG_TYPE_AEAD | CRYPTO_ALG_ASYNC, + .cra_blocksize = 1, + .cra_ctxsize = sizeof(struct aesni_rfc4106_gcm_ctx) + AESNI_ALIGN, + .cra_alignmask = 0, + .cra_type = &crypto_nivaead_type, + .cra_module = THIS_MODULE, + .cra_list = LIST_HEAD_INIT(rfc4106_alg.cra_list), + .cra_init = rfc4106_init, + .cra_exit = rfc4106_exit, + .cra_u = { + .aead = { + .setkey = rfc4106_set_key, + .setauthsize = rfc4106_set_authsize, + .encrypt = rfc4106_encrypt, + .decrypt = rfc4106_decrypt, + .geniv = "seqiv", + .ivsize = 8, + .maxauthsize = 16, + }, + }, +}; + +static int __driver_rfc4106_encrypt(struct aead_request *req) +{ + u8 one_entry_in_sg = 0; + u8 *src, *dst, *assoc; + __be32 counter = cpu_to_be32(1); + struct crypto_aead *tfm = crypto_aead_reqtfm(req); + struct aesni_rfc4106_gcm_ctx *ctx = aesni_rfc4106_gcm_ctx_get(tfm); + void *aes_ctx = &(ctx->aes_key_expanded); + unsigned long auth_tag_len = crypto_aead_authsize(tfm); + u8 iv_tab[16+AESNI_ALIGN]; + u8* iv = (u8 *) PTR_ALIGN((u8 *)iv_tab, AESNI_ALIGN); + struct scatter_walk src_sg_walk; + struct scatter_walk assoc_sg_walk; + struct scatter_walk dst_sg_walk; + unsigned int i; + + /* Assuming we are supporting rfc4106 64-bit extended */ + /* sequence numbers We need to have the AAD length equal */ + /* to 8 or 12 bytes */ + if (unlikely(req->assoclen != 8 && req->assoclen != 12)) + return -EINVAL; + /* IV below built */ + for (i = 0; i < 4; i++) + *(iv+i) = ctx->nonce[i]; + for (i = 0; i < 8; i++) + *(iv+4+i) = req->iv[i]; + *((__be32 *)(iv+12)) = counter; + + if ((sg_is_last(req->src)) && (sg_is_last(req->assoc))) { + one_entry_in_sg = 1; + scatterwalk_start(&src_sg_walk, req->src); + scatterwalk_start(&assoc_sg_walk, req->assoc); + src = scatterwalk_map(&src_sg_walk, 0); + assoc = scatterwalk_map(&assoc_sg_walk, 0); + dst = src; + if (unlikely(req->src != req->dst)) { + scatterwalk_start(&dst_sg_walk, req->dst); + dst = scatterwalk_map(&dst_sg_walk, 0); + } + + } else { + /* Allocate memory for src, dst, assoc */ + src = kmalloc(req->cryptlen + auth_tag_len + req->assoclen, + GFP_ATOMIC); + if (unlikely(!src)) + return -ENOMEM; + assoc = (src + req->cryptlen + auth_tag_len); + scatterwalk_map_and_copy(src, req->src, 0, req->cryptlen, 0); + scatterwalk_map_and_copy(assoc, req->assoc, 0, + req->assoclen, 0); + dst = src; + } + + aesni_gcm_enc(aes_ctx, dst, src, (unsigned long)req->cryptlen, iv, + ctx->hash_subkey, assoc, (unsigned long)req->assoclen, dst + + ((unsigned long)req->cryptlen), auth_tag_len); + + /* The authTag (aka the Integrity Check Value) needs to be written + * back to the packet. */ + if (one_entry_in_sg) { + if (unlikely(req->src != req->dst)) { + scatterwalk_unmap(dst, 0); + scatterwalk_done(&dst_sg_walk, 0, 0); + } + scatterwalk_unmap(src, 0); + scatterwalk_unmap(assoc, 0); + scatterwalk_done(&src_sg_walk, 0, 0); + scatterwalk_done(&assoc_sg_walk, 0, 0); + } else { + scatterwalk_map_and_copy(dst, req->dst, 0, + req->cryptlen + auth_tag_len, 1); + kfree(src); + } + return 0; +} + +static int __driver_rfc4106_decrypt(struct aead_request *req) +{ + u8 one_entry_in_sg = 0; + u8 *src, *dst, *assoc; + unsigned long tempCipherLen = 0; + __be32 counter = cpu_to_be32(1); + int retval = 0; + struct crypto_aead *tfm = crypto_aead_reqtfm(req); + struct aesni_rfc4106_gcm_ctx *ctx = aesni_rfc4106_gcm_ctx_get(tfm); + void *aes_ctx = &(ctx->aes_key_expanded); + unsigned long auth_tag_len = crypto_aead_authsize(tfm); + u8 iv_and_authTag[32+AESNI_ALIGN]; + u8 *iv = (u8 *) PTR_ALIGN((u8 *)iv_and_authTag, AESNI_ALIGN); + u8 *authTag = iv + 16; + struct scatter_walk src_sg_walk; + struct scatter_walk assoc_sg_walk; + struct scatter_walk dst_sg_walk; + unsigned int i; + + if (unlikely((req->cryptlen < auth_tag_len) || + (req->assoclen != 8 && req->assoclen != 12))) + return -EINVAL; + /* Assuming we are supporting rfc4106 64-bit extended */ + /* sequence numbers We need to have the AAD length */ + /* equal to 8 or 12 bytes */ + + tempCipherLen = (unsigned long)(req->cryptlen - auth_tag_len); + /* IV below built */ + for (i = 0; i < 4; i++) + *(iv+i) = ctx->nonce[i]; + for (i = 0; i < 8; i++) + *(iv+4+i) = req->iv[i]; + *((__be32 *)(iv+12)) = counter; + + if ((sg_is_last(req->src)) && (sg_is_last(req->assoc))) { + one_entry_in_sg = 1; + scatterwalk_start(&src_sg_walk, req->src); + scatterwalk_start(&assoc_sg_walk, req->assoc); + src = scatterwalk_map(&src_sg_walk, 0); + assoc = scatterwalk_map(&assoc_sg_walk, 0); + dst = src; + if (unlikely(req->src != req->dst)) { + scatterwalk_start(&dst_sg_walk, req->dst); + dst = scatterwalk_map(&dst_sg_walk, 0); + } + + } else { + /* Allocate memory for src, dst, assoc */ + src = kmalloc(req->cryptlen + req->assoclen, GFP_ATOMIC); + if (!src) + return -ENOMEM; + assoc = (src + req->cryptlen + auth_tag_len); + scatterwalk_map_and_copy(src, req->src, 0, req->cryptlen, 0); + scatterwalk_map_and_copy(assoc, req->assoc, 0, + req->assoclen, 0); + dst = src; + } + + aesni_gcm_dec(aes_ctx, dst, src, tempCipherLen, iv, + ctx->hash_subkey, assoc, (unsigned long)req->assoclen, + authTag, auth_tag_len); + + /* Compare generated tag with passed in tag. */ + retval = memcmp(src + tempCipherLen, authTag, auth_tag_len) ? + -EBADMSG : 0; + + if (one_entry_in_sg) { + if (unlikely(req->src != req->dst)) { + scatterwalk_unmap(dst, 0); + scatterwalk_done(&dst_sg_walk, 0, 0); + } + scatterwalk_unmap(src, 0); + scatterwalk_unmap(assoc, 0); + scatterwalk_done(&src_sg_walk, 0, 0); + scatterwalk_done(&assoc_sg_walk, 0, 0); + } else { + scatterwalk_map_and_copy(dst, req->dst, 0, req->cryptlen, 1); + kfree(src); + } + return retval; +} + +static struct crypto_alg __rfc4106_alg = { + .cra_name = "__gcm-aes-aesni", + .cra_driver_name = "__driver-gcm-aes-aesni", + .cra_priority = 0, + .cra_flags = CRYPTO_ALG_TYPE_AEAD, + .cra_blocksize = 1, + .cra_ctxsize = sizeof(struct aesni_rfc4106_gcm_ctx) + AESNI_ALIGN, + .cra_alignmask = 0, + .cra_type = &crypto_aead_type, + .cra_module = THIS_MODULE, + .cra_list = LIST_HEAD_INIT(__rfc4106_alg.cra_list), + .cra_u = { + .aead = { + .encrypt = __driver_rfc4106_encrypt, + .decrypt = __driver_rfc4106_decrypt, + }, + }, +}; + static int __init aesni_init(void) { int err; @@ -738,6 +1240,7 @@ static int __init aesni_init(void) printk(KERN_INFO "Intel AES-NI instructions are not detected.\n"); return -ENODEV; } + if ((err = crypto_register_alg(&aesni_alg))) goto aes_err; if ((err = crypto_register_alg(&__aesni_alg))) @@ -770,10 +1273,19 @@ static int __init aesni_init(void) if ((err = crypto_register_alg(&ablk_xts_alg))) goto ablk_xts_err; #endif - + err = crypto_register_alg(&__rfc4106_alg); + if (err) + goto __aead_gcm_err; + err = crypto_register_alg(&rfc4106_alg); + if (err) + goto aead_gcm_err; return err; +aead_gcm_err: + crypto_unregister_alg(&__rfc4106_alg); +__aead_gcm_err: #ifdef HAS_XTS + crypto_unregister_alg(&ablk_xts_alg); ablk_xts_err: #endif #ifdef HAS_PCBC @@ -809,6 +1321,8 @@ aes_err: static void __exit aesni_exit(void) { + crypto_unregister_alg(&__rfc4106_alg); + crypto_unregister_alg(&rfc4106_alg); #ifdef HAS_XTS crypto_unregister_alg(&ablk_xts_alg); #endif -- cgit v1.2.3 From 69435b94d01f49197b287eb5902fb8c5cee8fe1d Mon Sep 17 00:00:00 2001 From: Adrian Hoban Date: Thu, 4 Nov 2010 15:02:04 -0400 Subject: crypto: rfc4106 - Extending the RC4106 AES-GCM test vectors Updated RFC4106 AES-GCM testing. Some test vectors were taken from http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/ gcm/gcm-test-vectors.tar.gz Signed-off-by: Adrian Hoban Signed-off-by: Tadeusz Struk Signed-off-by: Gabriele Paoloni Signed-off-by: Aidan O'Mahony Signed-off-by: Herbert Xu --- crypto/tcrypt.c | 11 ++ crypto/testmgr.c | 24 ++++ crypto/testmgr.h | 361 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 396 insertions(+) diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c index 3ca68f9fc14d..9aac5e58be94 100644 --- a/crypto/tcrypt.c +++ b/crypto/tcrypt.c @@ -8,6 +8,13 @@ * Copyright (c) 2002 Jean-Francois Dive * Copyright (c) 2007 Nokia Siemens Networks * + * Updated RFC4106 AES-GCM testing. + * Authors: Aidan O'Mahony (aidan.o.mahony@intel.com) + * Adrian Hoban + * Gabriele Paoloni + * Tadeusz Struk (tadeusz.struk@intel.com) + * Copyright (c) 2010, Intel Corporation. + * * 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) @@ -980,6 +987,10 @@ static int do_test(int m) ret += tcrypt_test("ansi_cprng"); break; + case 151: + ret += tcrypt_test("rfc4106(gcm(aes))"); + break; + case 200: test_cipher_speed("ecb(aes)", ENCRYPT, sec, NULL, 0, speed_template_16_24_32); diff --git a/crypto/testmgr.c b/crypto/testmgr.c index fa8c8f78c8d4..27ea9fe9476f 100644 --- a/crypto/testmgr.c +++ b/crypto/testmgr.c @@ -6,6 +6,13 @@ * Copyright (c) 2007 Nokia Siemens Networks * Copyright (c) 2008 Herbert Xu * + * Updated RFC4106 AES-GCM testing. + * Authors: Aidan O'Mahony (aidan.o.mahony@intel.com) + * Adrian Hoban + * Gabriele Paoloni + * Tadeusz Struk (tadeusz.struk@intel.com) + * Copyright (c) 2010, Intel Corporation. + * * 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) @@ -2242,6 +2249,23 @@ static const struct alg_test_desc alg_test_descs[] = { } } }, { + .alg = "rfc4106(gcm(aes))", + .test = alg_test_aead, + .suite = { + .aead = { + .enc = { + .vecs = aes_gcm_rfc4106_enc_tv_template, + .count = AES_GCM_4106_ENC_TEST_VECTORS + }, + .dec = { + .vecs = aes_gcm_rfc4106_dec_tv_template, + .count = AES_GCM_4106_DEC_TEST_VECTORS + } + } + } + }, { + + .alg = "rfc4309(ccm(aes))", .test = alg_test_aead, .fips_allowed = 1, diff --git a/crypto/testmgr.h b/crypto/testmgr.h index 74e35377fd30..834af7f2adee 100644 --- a/crypto/testmgr.h +++ b/crypto/testmgr.h @@ -6,6 +6,15 @@ * Copyright (c) 2007 Nokia Siemens Networks * Copyright (c) 2008 Herbert Xu * + * Updated RFC4106 AES-GCM testing. Some test vectors were taken from + * http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/ + * gcm/gcm-test-vectors.tar.gz + * Authors: Aidan O'Mahony (aidan.o.mahony@intel.com) + * Adrian Hoban + * Gabriele Paoloni + * Tadeusz Struk (tadeusz.struk@intel.com) + * Copyright (c) 2010, Intel Corporation. + * * 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) @@ -2947,6 +2956,8 @@ static struct cipher_testvec cast6_dec_tv_template[] = { #define AES_CTR_3686_DEC_TEST_VECTORS 6 #define AES_GCM_ENC_TEST_VECTORS 9 #define AES_GCM_DEC_TEST_VECTORS 8 +#define AES_GCM_4106_ENC_TEST_VECTORS 7 +#define AES_GCM_4106_DEC_TEST_VECTORS 7 #define AES_CCM_ENC_TEST_VECTORS 7 #define AES_CCM_DEC_TEST_VECTORS 7 #define AES_CCM_4309_ENC_TEST_VECTORS 7 @@ -5829,6 +5840,356 @@ static struct aead_testvec aes_gcm_dec_tv_template[] = { } }; +static struct aead_testvec aes_gcm_rfc4106_enc_tv_template[] = { + { /* Generated using Crypto++ */ + .key = zeroed_string, + .klen = 20, + .iv = zeroed_string, + .input = zeroed_string, + .ilen = 16, + .assoc = zeroed_string, + .alen = 8, + .result = "\x03\x88\xDA\xCE\x60\xB6\xA3\x92" + "\xF3\x28\xC2\xB9\x71\xB2\xFE\x78" + "\x97\xFE\x4C\x23\x37\x42\x01\xE0" + "\x81\x9F\x8D\xC5\xD7\x41\xA0\x1B", + .rlen = 32, + },{ + .key = "\xfe\xff\xe9\x92\x86\x65\x73\x1c" + "\x6d\x6a\x8f\x94\x67\x30\x83\x08" + "\x00\x00\x00\x00", + .klen = 20, + .iv = "\x00\x00\x00\x00\x00\x00\x00\x01" + "\x00\x00\x00\x00", + .input = zeroed_string, + .ilen = 16, + .assoc = zeroed_string, + .alen = 8, + .result = "\xC0\x0D\x8B\x42\x0F\x8F\x34\x18" + "\x88\xB1\xC5\xBC\xC5\xB6\xD6\x28" + "\x6A\x9D\xDF\x11\x5E\xFE\x5E\x9D" + "\x2F\x70\x44\x92\xF7\xF2\xE3\xEF", + .rlen = 32, + + }, { + .key = "\xfe\xff\xe9\x92\x86\x65\x73\x1c" + "\x6d\x6a\x8f\x94\x67\x30\x83\x08" + "\x00\x00\x00\x00", + .klen = 20, + .iv = zeroed_string, + .input = "\x01\x01\x01\x01\x01\x01\x01\x01" + "\x01\x01\x01\x01\x01\x01\x01\x01", + .ilen = 16, + .assoc = zeroed_string, + .alen = 8, + .result = "\x4B\xB1\xB5\xE3\x25\x71\x70\xDE" + "\x7F\xC9\x9C\xA5\x14\x19\xF2\xAC" + "\x0B\x8F\x88\x69\x17\xE6\xB4\x3C" + "\xB1\x68\xFD\x14\x52\x64\x61\xB2", + .rlen = 32, + }, { + .key = "\xfe\xff\xe9\x92\x86\x65\x73\x1c" + "\x6d\x6a\x8f\x94\x67\x30\x83\x08" + "\x00\x00\x00\x00", + .klen = 20, + .iv = zeroed_string, + .input = "\x01\x01\x01\x01\x01\x01\x01\x01" + "\x01\x01\x01\x01\x01\x01\x01\x01", + .ilen = 16, + .assoc = "\x01\x01\x01\x01\x01\x01\x01\x01", + .alen = 8, + .result = "\x4B\xB1\xB5\xE3\x25\x71\x70\xDE" + "\x7F\xC9\x9C\xA5\x14\x19\xF2\xAC" + "\x90\x92\xB7\xE3\x5F\xA3\x9A\x63" + "\x7E\xD7\x1F\xD8\xD3\x7C\x4B\xF5", + .rlen = 32, + }, { + .key = "\xfe\xff\xe9\x92\x86\x65\x73\x1c" + "\x6d\x6a\x8f\x94\x67\x30\x83\x08" + "\x00\x00\x00\x00", + .klen = 20, + .iv = "\x00\x00\x00\x00\x00\x00\x00\x01" + "\x00\x00\x00\x00", + .input = "\x01\x01\x01\x01\x01\x01\x01\x01" + "\x01\x01\x01\x01\x01\x01\x01\x01", + .ilen = 16, + .assoc = "\x01\x01\x01\x01\x01\x01\x01\x01", + .alen = 8, + .result = "\xC1\x0C\x8A\x43\x0E\x8E\x35\x19" + "\x89\xB0\xC4\xBD\xC4\xB7\xD7\x29" + "\x64\x50\xF9\x32\x13\xFB\x74\x61" + "\xF4\xED\x52\xD3\xC5\x10\x55\x3C", + .rlen = 32, + }, { + .key = "\xfe\xff\xe9\x92\x86\x65\x73\x1c" + "\x6d\x6a\x8f\x94\x67\x30\x83\x08" + "\x00\x00\x00\x00", + .klen = 20, + .iv = "\x00\x00\x00\x00\x00\x00\x00\x01" + "\x00\x00\x00\x00", + .input = "\x01\x01\x01\x01\x01\x01\x01\x01" + "\x01\x01\x01\x01\x01\x01\x01\x01" + "\x01\x01\x01\x01\x01\x01\x01\x01" + "\x01\x01\x01\x01\x01\x01\x01\x01" + "\x01\x01\x01\x01\x01\x01\x01\x01" + "\x01\x01\x01\x01\x01\x01\x01\x01" + "\x01\x01\x01\x01\x01\x01\x01\x01" + "\x01\x01\x01\x01\x01\x01\x01\x01", + .ilen = 64, + .assoc = "\x01\x01\x01\x01\x01\x01\x01\x01", + .alen = 8, + .result = "\xC1\x0C\x8A\x43\x0E\x8E\x35\x19" + "\x89\xB0\xC4\xBD\xC4\xB7\xD7\x29" + "\x98\x14\xA1\x42\x37\x80\xFD\x90" + "\x68\x12\x01\xA8\x91\x89\xB9\x83" + "\x5B\x11\x77\x12\x9B\xFF\x24\x89" + "\x94\x5F\x18\x12\xBA\x27\x09\x39" + "\x99\x96\x76\x42\x15\x1C\xCD\xCB" + "\xDC\xD3\xDA\x65\x73\xAF\x80\xCD" + "\xD2\xB6\xC2\x4A\x76\xC2\x92\x85" + "\xBD\xCF\x62\x98\x58\x14\xE5\xBD", + .rlen = 80, + }, { + .key = "\x00\x01\x02\x03\x04\x05\x06\x07" + "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f" + "\x00\x00\x00\x00", + .klen = 20, + .iv = "\x00\x00\x45\x67\x89\xab\xcd\xef" + "\x00\x00\x00\x00", + .input = "\xff\xff\xff\xff\xff\xff\xff\xff" + "\xff\xff\xff\xff\xff\xff\xff\xff" + "\xff\xff\xff\xff\xff\xff\xff\xff" + "\xff\xff\xff\xff\xff\xff\xff\xff" + "\xff\xff\xff\xff\xff\xff\xff\xff" + "\xff\xff\xff\xff\xff\xff\xff\xff" + "\xff\xff\xff\xff\xff\xff\xff\xff" + "\xff\xff\xff\xff\xff\xff\xff\xff" + "\xff\xff\xff\xff\xff\xff\xff\xff" + "\xff\xff\xff\xff\xff\xff\xff\xff" + "\xff\xff\xff\xff\xff\xff\xff\xff" + "\xff\xff\xff\xff\xff\xff\xff\xff" + "\xff\xff\xff\xff\xff\xff\xff\xff" + "\xff\xff\xff\xff\xff\xff\xff\xff" + "\xff\xff\xff\xff\xff\xff\xff\xff" + "\xff\xff\xff\xff\xff\xff\xff\xff" + "\xff\xff\xff\xff\xff\xff\xff\xff" + "\xff\xff\xff\xff\xff\xff\xff\xff" + "\xff\xff\xff\xff\xff\xff\xff\xff" + "\xff\xff\xff\xff\xff\xff\xff\xff" + "\xff\xff\xff\xff\xff\xff\xff\xff" + "\xff\xff\xff\xff\xff\xff\xff\xff" + "\xff\xff\xff\xff\xff\xff\xff\xff" + "\xff\xff\xff\xff\xff\xff\xff\xff", + .ilen = 192, + .assoc = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa", + .alen = 12, + .result = "\xC1\x76\x33\x85\xE2\x9B\x5F\xDE" + "\xDE\x89\x3D\x42\xE7\xC9\x69\x8A" + "\x44\x6D\xC3\x88\x46\x2E\xC2\x01" + "\x5E\xF6\x0C\x39\xF0\xC4\xA5\x82" + "\xCD\xE8\x31\xCC\x0A\x4C\xE4\x44" + "\x41\xA9\x82\x6F\x22\xA1\x23\x1A" + "\xA8\xE3\x16\xFD\x31\x5C\x27\x31" + "\xF1\x7F\x01\x63\xA3\xAF\x70\xA1" + "\xCF\x07\x57\x41\x67\xD0\xC4\x42" + "\xDB\x18\xC6\x4C\x4C\xE0\x3D\x9F" + "\x05\x07\xFB\x13\x7D\x4A\xCA\x5B" + "\xF0\xBF\x64\x7E\x05\xB1\x72\xEE" + "\x7C\x3B\xD4\xCD\x14\x03\xB2\x2C" + "\xD3\xA9\xEE\xFA\x17\xFC\x9C\xDF" + "\xC7\x75\x40\xFF\xAE\xAD\x1E\x59" + "\x2F\x30\x24\xFB\xAD\x6B\x10\xFA" + "\x6C\x9F\x5B\xE7\x25\xD5\xD0\x25" + "\xAC\x4A\x4B\xDA\xFC\x7A\x85\x1B" + "\x7E\x13\x06\x82\x08\x17\xA4\x35" + "\xEC\xC5\x8D\x63\x96\x81\x0A\x8F" + "\xA3\x05\x38\x95\x20\x1A\x47\x04" + "\x6F\x6D\xDA\x8F\xEF\xC1\x76\x35" + "\x6B\xC7\x4D\x0F\x94\x12\xCA\x3E" + "\x2E\xD5\x03\x2E\x86\x7E\xAA\x3B" + "\x37\x08\x1C\xCF\xBA\x5D\x71\x46" + "\x80\x72\xB0\x4C\x82\x0D\x60\x3C", + .rlen = 208, + } +}; + +static struct aead_testvec aes_gcm_rfc4106_dec_tv_template[] = { + { /* Generated using Crypto++ */ + .key = zeroed_string, + .klen = 20, + .iv = zeroed_string, + .input = "\x03\x88\xDA\xCE\x60\xB6\xA3\x92" + "\xF3\x28\xC2\xB9\x71\xB2\xFE\x78" + "\x97\xFE\x4C\x23\x37\x42\x01\xE0" + "\x81\x9F\x8D\xC5\xD7\x41\xA0\x1B", + .ilen = 32, + .assoc = zeroed_string, + .alen = 8, + .result = zeroed_string, + .rlen = 16, + + },{ + .key = "\xfe\xff\xe9\x92\x86\x65\x73\x1c" + "\x6d\x6a\x8f\x94\x67\x30\x83\x08" + "\x00\x00\x00\x00", + .klen = 20, + .iv = "\x00\x00\x00\x00\x00\x00\x00\x01" + "\x00\x00\x00\x00", + .input = "\xC0\x0D\x8B\x42\x0F\x8F\x34\x18" + "\x88\xB1\xC5\xBC\xC5\xB6\xD6\x28" + "\x6A\x9D\xDF\x11\x5E\xFE\x5E\x9D" + "\x2F\x70\x44\x92\xF7\xF2\xE3\xEF", + .ilen = 32, + .assoc = zeroed_string, + .alen = 8, + .result = zeroed_string, + .rlen = 16, + }, { + .key = "\xfe\xff\xe9\x92\x86\x65\x73\x1c" + "\x6d\x6a\x8f\x94\x67\x30\x83\x08" + "\x00\x00\x00\x00", + .klen = 20, + .iv = zeroed_string, + .input = "\x4B\xB1\xB5\xE3\x25\x71\x70\xDE" + "\x7F\xC9\x9C\xA5\x14\x19\xF2\xAC" + "\x0B\x8F\x88\x69\x17\xE6\xB4\x3C" + "\xB1\x68\xFD\x14\x52\x64\x61\xB2", + .ilen = 32, + .assoc = zeroed_string, + .alen = 8, + .result = "\x01\x01\x01\x01\x01\x01\x01\x01" + "\x01\x01\x01\x01\x01\x01\x01\x01", + .rlen = 16, + }, { + .key = "\xfe\xff\xe9\x92\x86\x65\x73\x1c" + "\x6d\x6a\x8f\x94\x67\x30\x83\x08" + "\x00\x00\x00\x00", + .klen = 20, + .iv = zeroed_string, + .input = "\x4B\xB1\xB5\xE3\x25\x71\x70\xDE" + "\x7F\xC9\x9C\xA5\x14\x19\xF2\xAC" + "\x90\x92\xB7\xE3\x5F\xA3\x9A\x63" + "\x7E\xD7\x1F\xD8\xD3\x7C\x4B\xF5", + .ilen = 32, + .assoc = "\x01\x01\x01\x01\x01\x01\x01\x01", + .alen = 8, + .result = "\x01\x01\x01\x01\x01\x01\x01\x01" + "\x01\x01\x01\x01\x01\x01\x01\x01", + .rlen = 16, + + }, { + .key = "\xfe\xff\xe9\x92\x86\x65\x73\x1c" + "\x6d\x6a\x8f\x94\x67\x30\x83\x08" + "\x00\x00\x00\x00", + .klen = 20, + .iv = "\x00\x00\x00\x00\x00\x00\x00\x01" + "\x00\x00\x00\x00", + .input = "\xC1\x0C\x8A\x43\x0E\x8E\x35\x19" + "\x89\xB0\xC4\xBD\xC4\xB7\xD7\x29" + "\x64\x50\xF9\x32\x13\xFB\x74\x61" + "\xF4\xED\x52\xD3\xC5\x10\x55\x3C", + .ilen = 32, + .assoc = "\x01\x01\x01\x01\x01\x01\x01\x01", + .alen = 8, + .result = "\x01\x01\x01\x01\x01\x01\x01\x01" + "\x01\x01\x01\x01\x01\x01\x01\x01", + .rlen = 16, + }, { + .key = "\xfe\xff\xe9\x92\x86\x65\x73\x1c" + "\x6d\x6a\x8f\x94\x67\x30\x83\x08" + "\x00\x00\x00\x00", + .klen = 20, + .iv = "\x00\x00\x00\x00\x00\x00\x00\x01" + "\x00\x00\x00\x00", + .input = "\xC1\x0C\x8A\x43\x0E\x8E\x35\x19" + "\x89\xB0\xC4\xBD\xC4\xB7\xD7\x29" + "\x98\x14\xA1\x42\x37\x80\xFD\x90" + "\x68\x12\x01\xA8\x91\x89\xB9\x83" + "\x5B\x11\x77\x12\x9B\xFF\x24\x89" + "\x94\x5F\x18\x12\xBA\x27\x09\x39" + "\x99\x96\x76\x42\x15\x1C\xCD\xCB" + "\xDC\xD3\xDA\x65\x73\xAF\x80\xCD" + "\xD2\xB6\xC2\x4A\x76\xC2\x92\x85" + "\xBD\xCF\x62\x98\x58\x14\xE5\xBD", + .ilen = 80, + .assoc = "\x01\x01\x01\x01\x01\x01\x01\x01", + .alen = 8, + .result = "\x01\x01\x01\x01\x01\x01\x01\x01" + "\x01\x01\x01\x01\x01\x01\x01\x01" + "\x01\x01\x01\x01\x01\x01\x01\x01" + "\x01\x01\x01\x01\x01\x01\x01\x01" + "\x01\x01\x01\x01\x01\x01\x01\x01" + "\x01\x01\x01\x01\x01\x01\x01\x01" + "\x01\x01\x01\x01\x01\x01\x01\x01" + "\x01\x01\x01\x01\x01\x01\x01\x01", + .rlen = 64, + }, { + .key = "\x00\x01\x02\x03\x04\x05\x06\x07" + "\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f" + "\x00\x00\x00\x00", + .klen = 20, + .iv = "\x00\x00\x45\x67\x89\xab\xcd\xef" + "\x00\x00\x00\x00", + .input = "\xC1\x76\x33\x85\xE2\x9B\x5F\xDE" + "\xDE\x89\x3D\x42\xE7\xC9\x69\x8A" + "\x44\x6D\xC3\x88\x46\x2E\xC2\x01" + "\x5E\xF6\x0C\x39\xF0\xC4\xA5\x82" + "\xCD\xE8\x31\xCC\x0A\x4C\xE4\x44" + "\x41\xA9\x82\x6F\x22\xA1\x23\x1A" + "\xA8\xE3\x16\xFD\x31\x5C\x27\x31" + "\xF1\x7F\x01\x63\xA3\xAF\x70\xA1" + "\xCF\x07\x57\x41\x67\xD0\xC4\x42" + "\xDB\x18\xC6\x4C\x4C\xE0\x3D\x9F" + "\x05\x07\xFB\x13\x7D\x4A\xCA\x5B" + "\xF0\xBF\x64\x7E\x05\xB1\x72\xEE" + "\x7C\x3B\xD4\xCD\x14\x03\xB2\x2C" + "\xD3\xA9\xEE\xFA\x17\xFC\x9C\xDF" + "\xC7\x75\x40\xFF\xAE\xAD\x1E\x59" + "\x2F\x30\x24\xFB\xAD\x6B\x10\xFA" + "\x6C\x9F\x5B\xE7\x25\xD5\xD0\x25" + "\xAC\x4A\x4B\xDA\xFC\x7A\x85\x1B" + "\x7E\x13\x06\x82\x08\x17\xA4\x35" + "\xEC\xC5\x8D\x63\x96\x81\x0A\x8F" + "\xA3\x05\x38\x95\x20\x1A\x47\x04" + "\x6F\x6D\xDA\x8F\xEF\xC1\x76\x35" + "\x6B\xC7\x4D\x0F\x94\x12\xCA\x3E" + "\x2E\xD5\x03\x2E\x86\x7E\xAA\x3B" + "\x37\x08\x1C\xCF\xBA\x5D\x71\x46" + "\x80\x72\xB0\x4C\x82\x0D\x60\x3C", + .ilen = 208, + .assoc = "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa", + .alen = 12, + .result = "\xff\xff\xff\xff\xff\xff\xff\xff" + "\xff\xff\xff\xff\xff\xff\xff\xff" + "\xff\xff\xff\xff\xff\xff\xff\xff" + "\xff\xff\xff\xff\xff\xff\xff\xff" + "\xff\xff\xff\xff\xff\xff\xff\xff" + "\xff\xff\xff\xff\xff\xff\xff\xff" + "\xff\xff\xff\xff\xff\xff\xff\xff" + "\xff\xff\xff\xff\xff\xff\xff\xff" + "\xff\xff\xff\xff\xff\xff\xff\xff" + "\xff\xff\xff\xff\xff\xff\xff\xff" + "\xff\xff\xff\xff\xff\xff\xff\xff" + "\xff\xff\xff\xff\xff\xff\xff\xff" + "\xff\xff\xff\xff\xff\xff\xff\xff" + "\xff\xff\xff\xff\xff\xff\xff\xff" + "\xff\xff\xff\xff\xff\xff\xff\xff" + "\xff\xff\xff\xff\xff\xff\xff\xff" + "\xff\xff\xff\xff\xff\xff\xff\xff" + "\xff\xff\xff\xff\xff\xff\xff\xff" + "\xff\xff\xff\xff\xff\xff\xff\xff" + "\xff\xff\xff\xff\xff\xff\xff\xff" + "\xff\xff\xff\xff\xff\xff\xff\xff" + "\xff\xff\xff\xff\xff\xff\xff\xff" + "\xff\xff\xff\xff\xff\xff\xff\xff" + "\xff\xff\xff\xff\xff\xff\xff\xff", + .rlen = 192, + + } +}; + static struct aead_testvec aes_ccm_enc_tv_template[] = { { /* From RFC 3610 */ .key = "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7" -- cgit v1.2.3 From 5e78330126e23e009502b21d1efdabd68ab91397 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Sun, 14 Nov 2010 22:32:36 +0100 Subject: drm/i915: fix relaxed tiling for gen <= 3 && !g33 g33/pineview doesn't have any alignment constrains for unfenced tiled buffers. But older chips have. Fix this. Problem introduced in a00b10c360b35d6431a94cbf130a4e162870d661. Signed-off-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_gem.c | 43 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 40 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 52f5c194c50f..f2038f6df3b0 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1467,7 +1467,7 @@ i915_gem_free_mmap_offset(struct drm_gem_object *obj) * @obj: object to check * * Return the required GTT alignment for an object, taking into account - * potential fence register mapping if needed. + * potential fence register mapping. */ static uint32_t i915_gem_get_gtt_alignment(struct drm_i915_gem_object *obj_priv) @@ -1489,6 +1489,41 @@ i915_gem_get_gtt_alignment(struct drm_i915_gem_object *obj_priv) return i915_gem_get_gtt_size(obj_priv); } +/** + * i915_gem_get_unfenced_gtt_alignment - return required GTT alignment for an + * unfenced object + * @obj: object to check + * + * Return the required GTT alignment for an object, only taking into account + * unfenced tiled surface requirements. + */ +static uint32_t +i915_gem_get_unfenced_gtt_alignment(struct drm_i915_gem_object *obj_priv) +{ + struct drm_device *dev = obj_priv->base.dev; + int tile_height; + + /* + * Minimum alignment is 4k (GTT page size) for sane hw. + */ + if (INTEL_INFO(dev)->gen >= 4 || IS_G33(dev) || + obj_priv->tiling_mode == I915_TILING_NONE) + return 4096; + + /* + * Older chips need unfenced tiled buffers to be aligned to the left + * edge of an even tile row (where tile rows are counted as if the bo is + * placed in a fenced gtt region). + */ + if (IS_GEN2(dev) || + (obj_priv->tiling_mode == I915_TILING_Y && HAS_128_BYTE_Y_TILING(dev))) + tile_height = 32; + else + tile_height = 8; + + return tile_height * obj_priv->stride * 2; +} + static uint32_t i915_gem_get_gtt_size(struct drm_i915_gem_object *obj_priv) { @@ -2689,7 +2724,7 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); struct drm_mm_node *free_space; gfp_t gfpmask = __GFP_NORETRY | __GFP_NOWARN; - u32 size, fence_size, fence_alignment; + u32 size, fence_size, fence_alignment, unfenced_alignment; bool mappable, fenceable; int ret; @@ -2700,9 +2735,11 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, fence_size = i915_gem_get_gtt_size(obj_priv); fence_alignment = i915_gem_get_gtt_alignment(obj_priv); + unfenced_alignment = i915_gem_get_unfenced_gtt_alignment(obj_priv); if (alignment == 0) - alignment = map_and_fenceable ? fence_alignment : 4096; + alignment = map_and_fenceable ? fence_alignment : + unfenced_alignment; if (map_and_fenceable && alignment & (fence_alignment - 1)) { DRM_ERROR("Invalid object alignment requested %u\n", alignment); return -EINVAL; -- cgit v1.2.3 From 473ff6609c0778c5939164c5c57676b74164be71 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Sun, 14 Nov 2010 19:04:21 -0800 Subject: arch/microblaze: Remove unnecessary semicolons Signed-off-by: Joe Perches Signed-off-by: Michal Simek --- arch/microblaze/lib/memmove.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/microblaze/lib/memmove.c b/arch/microblaze/lib/memmove.c index 123e3616f2dd..810fd68775e3 100644 --- a/arch/microblaze/lib/memmove.c +++ b/arch/microblaze/lib/memmove.c @@ -182,7 +182,7 @@ void *memmove(void *v_dst, const void *v_src, __kernel_size_t c) for (; c >= 4; c -= 4) { value = *--i_src; *--i_dst = buf_hold | ((value & 0xFF000000)>> 24); - buf_hold = (value & 0xFFFFFF) << 8;; + buf_hold = (value & 0xFFFFFF) << 8; } #endif /* Realign the source */ -- cgit v1.2.3 From df15315899c0641412bd54b29565a70b078a6ac8 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 15 Nov 2010 05:25:58 +0000 Subject: drm/i915: Fix current tiling check for relaxed fencing As we may bind an object with the correct alignment, but with an invalid size, it may pass the current checks on whether the object may be reused with a fence. Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_gem_tiling.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem_tiling.c b/drivers/gpu/drm/i915/i915_gem_tiling.c index 0597a737ebad..a517b48d441d 100644 --- a/drivers/gpu/drm/i915/i915_gem_tiling.c +++ b/drivers/gpu/drm/i915/i915_gem_tiling.c @@ -245,6 +245,17 @@ i915_gem_object_fence_ok(struct drm_gem_object *obj, int tiling_mode) if (INTEL_INFO(obj->dev)->gen >= 4) return true; + if (!obj_priv->gtt_space) + return true; + + if (INTEL_INFO(obj->dev)->gen == 3) { + if (obj_priv->gtt_offset & ~I915_FENCE_START_MASK) + return false; + } else { + if (obj_priv->gtt_offset & ~I830_FENCE_START_MASK) + return false; + } + /* * Previous chips need to be aligned to the size of the smallest * fence register that can contain the object. @@ -257,16 +268,11 @@ i915_gem_object_fence_ok(struct drm_gem_object *obj, int tiling_mode) while (size < obj_priv->base.size) size <<= 1; - if (obj_priv->gtt_offset & (size - 1)) + if (obj_priv->gtt_space->size != size) return false; - if (INTEL_INFO(obj->dev)->gen == 3) { - if (obj_priv->gtt_offset & ~I915_FENCE_START_MASK) - return false; - } else { - if (obj_priv->gtt_offset & ~I830_FENCE_START_MASK) - return false; - } + if (obj_priv->gtt_offset & (size - 1)) + return false; return true; } -- cgit v1.2.3 From f9a67059d43a8f12446356ed42d7694afc34bb92 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Sun, 14 Nov 2010 19:25:09 +0000 Subject: ASoC: Prevent system suspend while debouncing wakeup capable GPIO jacks If the device associated with a GPIO jack is wakeup capable then disable suspend while we're debouncing the jack so that we skip suspends that race with the jack. Note that currently the GPIO based jack has a CODEC associated with it which we're using right now. These jacks should be reparented against the card itself and this code adjusted. Signed-off-by: Mark Brown Acked-by: Liam Girdwood --- sound/soc/soc-jack.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sound/soc/soc-jack.c b/sound/soc/soc-jack.c index 4d95abb40288..619061d689a3 100644 --- a/sound/soc/soc-jack.c +++ b/sound/soc/soc-jack.c @@ -209,6 +209,10 @@ static void snd_soc_jack_gpio_detect(struct snd_soc_jack_gpio *gpio) static irqreturn_t gpio_handler(int irq, void *data) { struct snd_soc_jack_gpio *gpio = data; + struct device *dev = gpio->jack->codec->card->dev; + + if (device_may_wakeup(dev)) + pm_wakeup_event(dev, gpio->debounce_time + 50); schedule_delayed_work(&gpio->work, msecs_to_jiffies(gpio->debounce_time)); -- cgit v1.2.3 From 3c9e28e751cf9969c2cb2e57b5573cab86cf521a Mon Sep 17 00:00:00 2001 From: "Arnaud Patard (Rtp)" Date: Sat, 13 Nov 2010 18:51:53 +0100 Subject: ASoC: Add support for OpenRD Ultimate OpenRD Ultimate & Client are similar machines so enable OpenRD client sound support on Ultimate too Tested-by: Robas Teodor Signed-off-by: Arnaud Patard Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- arch/arm/mach-kirkwood/openrd-setup.c | 2 +- sound/soc/kirkwood/Kconfig | 2 +- sound/soc/kirkwood/kirkwood-openrd.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/arm/mach-kirkwood/openrd-setup.c b/arch/arm/mach-kirkwood/openrd-setup.c index c9d77fad10ab..cfcca4174e25 100644 --- a/arch/arm/mach-kirkwood/openrd-setup.c +++ b/arch/arm/mach-kirkwood/openrd-setup.c @@ -171,7 +171,7 @@ static void __init openrd_init(void) kirkwood_i2c_init(); - if (machine_is_openrd_client()) { + if (machine_is_openrd_client() || machine_is_openrd_ultimate()) { i2c_register_board_info(0, i2c_board_info, ARRAY_SIZE(i2c_board_info)); kirkwood_audio_init(); diff --git a/sound/soc/kirkwood/Kconfig b/sound/soc/kirkwood/Kconfig index 54258fd9797f..8f49e165f4d1 100644 --- a/sound/soc/kirkwood/Kconfig +++ b/sound/soc/kirkwood/Kconfig @@ -11,7 +11,7 @@ config SND_KIRKWOOD_SOC_I2S config SND_KIRKWOOD_SOC_OPENRD tristate "SoC Audio support for Kirkwood Openrd Client" - depends on SND_KIRKWOOD_SOC && MACH_OPENRD_CLIENT + depends on SND_KIRKWOOD_SOC && (MACH_OPENRD_CLIENT || MACH_OPENRD_ULTIMATE) select SND_KIRKWOOD_SOC_I2S select SND_SOC_CS42L51 help diff --git a/sound/soc/kirkwood/kirkwood-openrd.c b/sound/soc/kirkwood/kirkwood-openrd.c index 9d7c81e921f1..d863afb3ee52 100644 --- a/sound/soc/kirkwood/kirkwood-openrd.c +++ b/sound/soc/kirkwood/kirkwood-openrd.c @@ -86,7 +86,7 @@ static int __init openrd_client_init(void) { int ret; - if (!machine_is_openrd_client()) + if (!machine_is_openrd_client() && !machine_is_openrd_ultimate()) return 0; openrd_client_snd_device = platform_device_alloc("soc-audio", -1); -- cgit v1.2.3 From 149d730fac715e077a8bcceb4b27f3523b314558 Mon Sep 17 00:00:00 2001 From: Jonathan Neuschäfer Date: Tue, 9 Nov 2010 23:20:26 +0100 Subject: spelling fix in drivers/misc/Kconfig MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Jonathan Neuschäfer Signed-off-by: Jiri Kosina --- drivers/misc/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index 4d073f1e4502..1e1a4be8eb6c 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -402,7 +402,7 @@ config TI_DAC7512 DAC7512 16-bit digital-to-analog converter. This driver can also be built as a module. If so, the module - will be calles ti_dac7512. + will be called ti_dac7512. config VMWARE_BALLOON tristate "VMware Balloon Driver" -- cgit v1.2.3 From 380cf090f4f531545b558b04a3dd90d09df52ee9 Mon Sep 17 00:00:00 2001 From: Wu Fengguang Date: Thu, 11 Nov 2010 19:23:29 +0800 Subject: ext4: fix redirty_page_for_writepage() typo in comment Signed-off-by: Wu Fengguang Signed-off-by: Jiri Kosina --- fs/ext4/inode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 4bc84b8adb7f..b6a4b41d7e14 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -3357,7 +3357,7 @@ int ext4_alloc_da_blocks(struct inode *inode) * doing I/O at all. * * We could call write_cache_pages(), and then redirty all of - * the pages by calling redirty_page_for_writeback() but that + * the pages by calling redirty_page_for_writepage() but that * would be ugly in the extreme. So instead we would need to * replicate parts of the code in the above functions, * simplifying them becuase we wouldn't actually intend to -- cgit v1.2.3 From 6021afcf19d8c6f5db6d11cadcfb6a22d0c28a48 Mon Sep 17 00:00:00 2001 From: "Edgar (gimli) Hucek" Date: Tue, 9 Nov 2010 17:38:42 +0100 Subject: input: bcm5974: Add support for MacBookAir3 This patch adds support for the MacBookAir3,1 and MacBookAir3,2 models. [rydberg@euromail.se: touchpad range calibration] Cc: stable@kernel.org Signed-off-by: Edgar (gimli) Hucek Signed-off-by: Henrik Rydberg Signed-off-by: Jiri Kosina --- drivers/input/mouse/bcm5974.c | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/drivers/input/mouse/bcm5974.c b/drivers/input/mouse/bcm5974.c index b95231763911..ee82851afe3e 100644 --- a/drivers/input/mouse/bcm5974.c +++ b/drivers/input/mouse/bcm5974.c @@ -55,6 +55,14 @@ #define USB_DEVICE_ID_APPLE_WELLSPRING3_ANSI 0x0236 #define USB_DEVICE_ID_APPLE_WELLSPRING3_ISO 0x0237 #define USB_DEVICE_ID_APPLE_WELLSPRING3_JIS 0x0238 +/* MacbookAir3,2 (unibody), aka wellspring5 */ +#define USB_DEVICE_ID_APPLE_WELLSPRING4_ANSI 0x023f +#define USB_DEVICE_ID_APPLE_WELLSPRING4_ISO 0x0240 +#define USB_DEVICE_ID_APPLE_WELLSPRING4_JIS 0x0241 +/* MacbookAir3,1 (unibody), aka wellspring4 */ +#define USB_DEVICE_ID_APPLE_WELLSPRING4A_ANSI 0x0242 +#define USB_DEVICE_ID_APPLE_WELLSPRING4A_ISO 0x0243 +#define USB_DEVICE_ID_APPLE_WELLSPRING4A_JIS 0x0244 #define BCM5974_DEVICE(prod) { \ .match_flags = (USB_DEVICE_ID_MATCH_DEVICE | \ @@ -80,6 +88,14 @@ static const struct usb_device_id bcm5974_table[] = { BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING3_ANSI), BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING3_ISO), BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING3_JIS), + /* MacbookAir3,2 */ + BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING4_ANSI), + BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING4_ISO), + BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING4_JIS), + /* MacbookAir3,1 */ + BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING4A_ANSI), + BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING4A_ISO), + BCM5974_DEVICE(USB_DEVICE_ID_APPLE_WELLSPRING4A_JIS), /* Terminating entry */ {} }; @@ -234,6 +250,30 @@ static const struct bcm5974_config bcm5974_config_table[] = { { DIM_X, DIM_X / SN_COORD, -4460, 5166 }, { DIM_Y, DIM_Y / SN_COORD, -75, 6700 } }, + { + USB_DEVICE_ID_APPLE_WELLSPRING4_ANSI, + USB_DEVICE_ID_APPLE_WELLSPRING4_ISO, + USB_DEVICE_ID_APPLE_WELLSPRING4_JIS, + HAS_INTEGRATED_BUTTON, + 0x84, sizeof(struct bt_data), + 0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS, + { DIM_PRESSURE, DIM_PRESSURE / SN_PRESSURE, 0, 300 }, + { DIM_WIDTH, DIM_WIDTH / SN_WIDTH, 0, 2048 }, + { DIM_X, DIM_X / SN_COORD, -4620, 5140 }, + { DIM_Y, DIM_Y / SN_COORD, -150, 6600 } + }, + { + USB_DEVICE_ID_APPLE_WELLSPRING4A_ANSI, + USB_DEVICE_ID_APPLE_WELLSPRING4A_ISO, + USB_DEVICE_ID_APPLE_WELLSPRING4A_JIS, + HAS_INTEGRATED_BUTTON, + 0x84, sizeof(struct bt_data), + 0x81, TYPE2, FINGER_TYPE2, FINGER_TYPE2 + SIZEOF_ALL_FINGERS, + { DIM_PRESSURE, DIM_PRESSURE / SN_PRESSURE, 0, 300 }, + { DIM_WIDTH, DIM_WIDTH / SN_WIDTH, 0, 2048 }, + { DIM_X, DIM_X / SN_COORD, -4616, 5112 }, + { DIM_Y, DIM_Y / SN_COORD, -142, 5234 } + }, {} }; -- cgit v1.2.3 From b7bedd804333f13248c0fee57eeef764edfcbc9b Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Sun, 7 Nov 2010 23:15:41 +0100 Subject: ARM, mm: Don't include smp_plat.h twice in flush.c It's enough to include the asm/smp_plat.h once in arch/arm/mm/flush.c Signed-off-by: Jesper Juhl Signed-off-by: Jiri Kosina --- arch/arm/mm/flush.c | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/arm/mm/flush.c b/arch/arm/mm/flush.c index 391ffae75098..7d6e92b29e56 100644 --- a/arch/arm/mm/flush.c +++ b/arch/arm/mm/flush.c @@ -17,7 +17,6 @@ #include #include #include -#include #include "mm.h" -- cgit v1.2.3 From e987fa357a4c585e4f43fc3e0ab15ba9e908e233 Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Sun, 7 Nov 2010 23:24:44 +0100 Subject: infiniband: Only include mutex.h once in drivers/infiniband/hw/cxgb4/iw_cxgb4.h Only include the header linux/mutex.h once inside drivers/infiniband/hw/cxgb4/iw_cxgb4.h Signed-off-by: Jesper Juhl Signed-off-by: Jiri Kosina --- drivers/infiniband/hw/cxgb4/iw_cxgb4.h | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/infiniband/hw/cxgb4/iw_cxgb4.h b/drivers/infiniband/hw/cxgb4/iw_cxgb4.h index 16032cdb4337..42bb5757d1b9 100644 --- a/drivers/infiniband/hw/cxgb4/iw_cxgb4.h +++ b/drivers/infiniband/hw/cxgb4/iw_cxgb4.h @@ -46,7 +46,6 @@ #include #include #include -#include #include -- cgit v1.2.3 From ead9b9199c09653dd9b889933c7af75f020c7286 Mon Sep 17 00:00:00 2001 From: Jarkko Nikula Date: Sat, 13 Nov 2010 20:40:44 +0200 Subject: ASoC: Add optional name_prefix for codec kcontrol, widget and route names There is a need to prefix codec kcontrol, widget and internal route names in an ASoC machine that has multiple codecs with conflicting names. The name collision would occur when codec drivers try to registering kcontrols with the same name or when building audio paths. This patch introduces optional prefix_map into struct snd_soc_card. With it machine drivers can specify a unique name prefix to each codec that have conflicting names with anothers. Prefix to codec is matched with codec name. Following example illustrates a machine that has two same codec instances. Name collision from kcontrol registration is avoided by specifying a name prefix "foo" for the second codec. As the codec widget names are prefixed then second audio map for that codec shows a prefixed widget name. static const struct snd_soc_dapm_route map0[] = { {"Spk", NULL, "MONO"}, }; static const struct snd_soc_dapm_route map1[] = { {"Vibra", NULL, "foo MONO"}, }; static struct snd_soc_prefix_map codec_prefix[] = { { .dev_name = "codec.2", .name_prefix = "foo", }, }; static struct snd_soc_card card = { ... .prefix_map = codec_prefix, .num_prefixes = ARRAY_SIZE(codec_prefix), }; Signed-off-by: Jarkko Nikula Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- include/sound/soc.h | 13 +++++++++++++ sound/soc/soc-core.c | 35 +++++++++++++++++++++++++++++++++-- sound/soc/soc-dapm.c | 34 ++++++++++++++++++++++++++++++++-- 3 files changed, 78 insertions(+), 4 deletions(-) diff --git a/include/sound/soc.h b/include/sound/soc.h index af23f4228869..3eb92ef6c83f 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -450,6 +450,7 @@ struct snd_soc_cache_ops { /* SoC Audio Codec device */ struct snd_soc_codec { const char *name; + const char *name_prefix; int id; struct device *dev; struct snd_soc_codec_driver *driver; @@ -577,6 +578,11 @@ struct snd_soc_dai_link { struct snd_soc_ops *ops; }; +struct snd_soc_prefix_map { + const char *dev_name; + const char *name_prefix; +}; + /* SoC card */ struct snd_soc_card { const char *name; @@ -611,6 +617,13 @@ struct snd_soc_card { struct snd_soc_pcm_runtime *rtd; int num_rtd; + /* + * optional map of kcontrol, widget and path name prefixes that are + * associated per device + */ + struct snd_soc_prefix_map *prefix_map; + int num_prefixes; + struct work_struct deferred_resume_work; /* lists of probed devices belonging to this card */ diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 3d70ce58d03c..2540efd67ee7 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -1397,6 +1397,23 @@ static void soc_remove_dai_link(struct snd_soc_card *card, int num) } } +static void soc_set_name_prefix(struct snd_soc_card *card, + struct snd_soc_codec *codec) +{ + int i; + + if (card->prefix_map == NULL) + return; + + for (i = 0; i < card->num_prefixes; i++) { + struct snd_soc_prefix_map *map = &card->prefix_map[i]; + if (map->dev_name && !strcmp(codec->name, map->dev_name)) { + codec->name_prefix = map->name_prefix; + break; + } + } +} + static void rtd_release(struct device *dev) {} static int soc_probe_dai_link(struct snd_soc_card *card, int num) @@ -1406,6 +1423,7 @@ static int soc_probe_dai_link(struct snd_soc_card *card, int num) struct snd_soc_codec *codec = rtd->codec; struct snd_soc_platform *platform = rtd->platform; struct snd_soc_dai *codec_dai = rtd->codec_dai, *cpu_dai = rtd->cpu_dai; + const char *temp; int ret; dev_dbg(card->dev, "probe %s dai link %d\n", card->name, num); @@ -1440,6 +1458,7 @@ static int soc_probe_dai_link(struct snd_soc_card *card, int num) /* probe the CODEC */ if (!codec->probed) { codec->dapm.card = card; + soc_set_name_prefix(card, codec); if (codec->driver->probe) { ret = codec->driver->probe(codec); if (ret < 0) { @@ -1492,11 +1511,15 @@ static int soc_probe_dai_link(struct snd_soc_card *card, int num) /* now that all clients have probed, initialise the DAI link */ if (dai_link->init) { + /* machine controls, routes and widgets are not prefixed */ + temp = rtd->codec->name_prefix; + rtd->codec->name_prefix = NULL; ret = dai_link->init(rtd); if (ret < 0) { printk(KERN_ERR "asoc: failed to init %s\n", dai_link->stream_name); return ret; } + rtd->codec->name_prefix = temp; } /* Make sure all DAPM widgets are instantiated */ @@ -2072,14 +2095,22 @@ int snd_soc_add_controls(struct snd_soc_codec *codec, const struct snd_kcontrol_new *controls, int num_controls) { struct snd_card *card = codec->card->snd_card; + char prefixed_name[44], *name; int err, i; for (i = 0; i < num_controls; i++) { const struct snd_kcontrol_new *control = &controls[i]; - err = snd_ctl_add(card, snd_soc_cnew(control, codec, NULL)); + if (codec->name_prefix) { + snprintf(prefixed_name, sizeof(prefixed_name), "%s %s", + codec->name_prefix, control->name); + name = prefixed_name; + } else { + name = control->name; + } + err = snd_ctl_add(card, snd_soc_cnew(control, codec, name)); if (err < 0) { dev_err(codec->dev, "%s: Failed to add %s: %d\n", - codec->name, control->name, err); + codec->name, name, err); return err; } } diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index bc2ec06943c0..60c8dec49480 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -1295,6 +1295,7 @@ static void dapm_free_widgets(struct snd_soc_dapm_context *dapm) list_for_each_entry_safe(w, next_w, &dapm->widgets, list) { list_del(&w->list); + kfree(w->name); kfree(w); } @@ -1346,11 +1347,25 @@ static int snd_soc_dapm_add_route(struct snd_soc_dapm_context *dapm, { struct snd_soc_dapm_path *path; struct snd_soc_dapm_widget *wsource = NULL, *wsink = NULL, *w; - const char *sink = route->sink; + const char *sink; const char *control = route->control; - const char *source = route->source; + const char *source; + char prefixed_sink[80]; + char prefixed_source[80]; int ret = 0; + if (dapm->codec->name_prefix) { + snprintf(prefixed_sink, sizeof(prefixed_sink), "%s %s", + dapm->codec->name_prefix, route->sink); + sink = prefixed_sink; + snprintf(prefixed_source, sizeof(prefixed_source), "%s %s", + dapm->codec->name_prefix, route->source); + source = prefixed_source; + } else { + sink = route->sink; + source = route->source; + } + /* find src and dest widgets */ list_for_each_entry(w, &dapm->widgets, list) { @@ -1978,10 +1993,25 @@ int snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm, const struct snd_soc_dapm_widget *widget) { struct snd_soc_dapm_widget *w; + size_t name_len; if ((w = dapm_cnew_widget(widget)) == NULL) return -ENOMEM; + name_len = strlen(widget->name) + 1; + if (dapm->codec->name_prefix) + name_len += 1 + strlen(dapm->codec->name_prefix); + w->name = kmalloc(name_len, GFP_KERNEL); + if (w->name == NULL) { + kfree(w); + return -ENOMEM; + } + if (dapm->codec->name_prefix) + snprintf(w->name, name_len, "%s %s", + dapm->codec->name_prefix, widget->name); + else + snprintf(w->name, name_len, "%s", widget->name); + w->dapm = dapm; w->codec = dapm->codec; INIT_LIST_HEAD(&w->sources); -- cgit v1.2.3 From ef995e3a91e290684f24696e1d2e8767a2a2ebb6 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 15 Nov 2010 09:09:17 -0800 Subject: ASoC: Remove unnecessary semicolons Signed-off-by: Joe Perches Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/codecs/wm8904.c | 2 +- sound/soc/codecs/wm8940.c | 1 - sound/soc/codecs/wm8993.c | 2 +- sound/soc/codecs/wm_hubs.c | 2 +- 4 files changed, 3 insertions(+), 4 deletions(-) diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c index be90399c1cb4..5e57bd2483e8 100644 --- a/sound/soc/codecs/wm8904.c +++ b/sound/soc/codecs/wm8904.c @@ -1591,7 +1591,7 @@ static int wm8904_hw_params(struct snd_pcm_substream *substream, - wm8904->fs); for (i = 1; i < ARRAY_SIZE(clk_sys_rates); i++) { cur_val = abs((wm8904->sysclk_rate / - clk_sys_rates[i].ratio) - wm8904->fs);; + clk_sys_rates[i].ratio) - wm8904->fs); if (cur_val < best_val) { best = i; best_val = cur_val; diff --git a/sound/soc/codecs/wm8940.c b/sound/soc/codecs/wm8940.c index c2def1b01ae0..caed0849e005 100644 --- a/sound/soc/codecs/wm8940.c +++ b/sound/soc/codecs/wm8940.c @@ -736,7 +736,6 @@ static int wm8940_probe(struct snd_soc_codec *codec) return ret; return ret; -; } static int wm8940_remove(struct snd_soc_codec *codec) diff --git a/sound/soc/codecs/wm8993.c b/sound/soc/codecs/wm8993.c index bcc54be572ce..991d90c79dd2 100644 --- a/sound/soc/codecs/wm8993.c +++ b/sound/soc/codecs/wm8993.c @@ -1227,7 +1227,7 @@ static int wm8993_hw_params(struct snd_pcm_substream *substream, - wm8993->fs); for (i = 1; i < ARRAY_SIZE(clk_sys_rates); i++) { cur_val = abs((wm8993->sysclk_rate / - clk_sys_rates[i].ratio) - wm8993->fs);; + clk_sys_rates[i].ratio) - wm8993->fs); if (cur_val < best_val) { best = i; best_val = cur_val; diff --git a/sound/soc/codecs/wm_hubs.c b/sound/soc/codecs/wm_hubs.c index 8aff0efe72f5..422c7fb383eb 100644 --- a/sound/soc/codecs/wm_hubs.c +++ b/sound/soc/codecs/wm_hubs.c @@ -119,7 +119,7 @@ static void calibrate_dc_servo(struct snd_soc_codec *codec) switch (hubs->dcs_readback_mode) { case 0: reg_l = snd_soc_read(codec, WM8993_DC_SERVO_READBACK_1) - & WM8993_DCS_INTEG_CHAN_0_MASK;; + & WM8993_DCS_INTEG_CHAN_0_MASK; reg_r = snd_soc_read(codec, WM8993_DC_SERVO_READBACK_2) & WM8993_DCS_INTEG_CHAN_1_MASK; break; -- cgit v1.2.3 From bdc85df7a8417b9893443ff5520804699416b6f3 Mon Sep 17 00:00:00 2001 From: Vivek Goyal Date: Mon, 15 Nov 2010 19:37:36 +0100 Subject: blk-cgroup: Allow creation of hierarchical cgroups o Allow hierarchical cgroup creation for blkio controller o Currently we disallow it as both the io controller policies (throttling as well as proportion bandwidth) do not support hierarhical accounting and control. But the flip side is that blkio controller can not be used with libvirt as libvirt creates a cgroup hierarchy deeper than 1 level. //libvirt/qemu/ o So this patch will allow creation of cgroup hierarhcy but at the backend everything will be treated as flat. So if somebody created a an hierarchy like as follows. root / \ test1 test2 | test3 CFQ and throttling will practically treat all groups at same level. pivot / | \ \ root test1 test2 test3 o Once we have actual support for hierarchical accounting and control then we can introduce another cgroup tunable file "blkio.use_hierarchy" which will be 0 by default but if user wants to enforce hierarhical control then it can be set to 1. This way there should not be any ABI problems down the line. o The only not so pretty part is introduction of extra file "use_hierarchy" down the line. Kame-san had mentioned that hierarhical accounting is expensive in memory controller hence they keep it off by default. I suspect same will be the case for IO controller also as for each IO completion we shall have to account IO through hierarchy up to the root. if yes, then it probably is not a very bad idea to introduce this extra file so that it will be used only when somebody needs it and some people might enable hierarchy only in part of the hierarchy. o This is how basically memory controller also uses "use_hierarhcy" and they also allowed creation of hierarchies when actual backend support was not available. Signed-off-by: Vivek Goyal Acked-by: Balbir Singh Reviewed-by: Gui Jianfeng Reviewed-by: Ciju Rajan K Tested-by: Ciju Rajan K Signed-off-by: Jens Axboe --- Documentation/cgroups/blkio-controller.txt | 27 +++++++++++++++++++++++++++ block/blk-cgroup.c | 4 ---- 2 files changed, 27 insertions(+), 4 deletions(-) diff --git a/Documentation/cgroups/blkio-controller.txt b/Documentation/cgroups/blkio-controller.txt index d6da611f8f63..4ed7b5ceeed2 100644 --- a/Documentation/cgroups/blkio-controller.txt +++ b/Documentation/cgroups/blkio-controller.txt @@ -89,6 +89,33 @@ Throttling/Upper Limit policy Limits for writes can be put using blkio.write_bps_device file. +Hierarchical Cgroups +==================== +- Currently none of the IO control policy supports hierarhical groups. But + cgroup interface does allow creation of hierarhical cgroups and internally + IO policies treat them as flat hierarchy. + + So this patch will allow creation of cgroup hierarhcy but at the backend + everything will be treated as flat. So if somebody created a hierarchy like + as follows. + + root + / \ + test1 test2 + | + test3 + + CFQ and throttling will practically treat all groups at same level. + + pivot + / | \ \ + root test1 test2 test3 + + Down the line we can implement hierarchical accounting/control support + and also introduce a new cgroup file "use_hierarchy" which will control + whether cgroup hierarchy is viewed as flat or hierarchical by the policy.. + This is how memory controller also has implemented the things. + Various user visible config options =================================== CONFIG_BLK_CGROUP diff --git a/block/blk-cgroup.c b/block/blk-cgroup.c index b1febd0f6d2a..455768a3eb9e 100644 --- a/block/blk-cgroup.c +++ b/block/blk-cgroup.c @@ -1452,10 +1452,6 @@ blkiocg_create(struct cgroup_subsys *subsys, struct cgroup *cgroup) goto done; } - /* Currently we do not support hierarchy deeper than two level (0,1) */ - if (parent != cgroup->top_cgroup) - return ERR_PTR(-EPERM); - blkcg = kzalloc(sizeof(*blkcg), GFP_KERNEL); if (!blkcg) return ERR_PTR(-ENOMEM); -- cgit v1.2.3 From c996d8b9a8f37bd1b4dd7823abc42780b20998f8 Mon Sep 17 00:00:00 2001 From: Michael Witten Date: Mon, 15 Nov 2010 19:55:34 +0000 Subject: Docs/Kconfig: Update: osdl.org -> linuxfoundation.org Some of the documentation refers to web pages under the domain `osdl.org'. However, `osdl.org' now redirects to `linuxfoundation.org'. Rather than rely on redirections, this patch updates the addresses appropriately; for the most part, only documentation that is meant to be current has been updated. The patch should be pretty quick to scan and check; each new web-page url was gotten by trying out the original URL in a browser and then simply copying the the redirected URL (formatting as necessary). There is some conflict as to which one of these domain names is preferred: linuxfoundation.org linux-foundation.org So, I wrote: info@linuxfoundation.org and got this reply: Message-ID: <4CE17EE6.9040807@linuxfoundation.org> Date: Mon, 15 Nov 2010 10:41:42 -0800 From: David Ames ... linuxfoundation.org is preferred. The canonical name for our web site is www.linuxfoundation.org. Our list site is actually lists.linux-foundation.org. Regarding email linuxfoundation.org is preferred there are a few people who choose to use linux-foundation.org for their own reasons. Consequently, I used `linuxfoundation.org' for web pages and `lists.linux-foundation.org' for mailing-list web pages and email addresses; the only personal email address I updated from `@osdl.org' was that of Andrew Morton, who prefers `linux-foundation.org' according `git log'. Signed-off-by: Michael Witten Signed-off-by: Jiri Kosina --- Documentation/ko_KR/HOWTO | 4 ++-- Documentation/lguest/lguest.txt | 7 +++++-- Documentation/networking/bridge.txt | 4 ++-- Documentation/networking/dccp.txt | 4 ++-- Documentation/networking/generic_netlink.txt | 2 +- Documentation/zh_CN/HOWTO | 4 ++-- Documentation/zh_CN/SubmittingDrivers | 2 +- MAINTAINERS | 10 +++++----- net/Kconfig | 4 +++- net/dccp/Kconfig | 4 +++- net/ipv4/Kconfig | 4 +++- net/sched/Kconfig | 2 +- 12 files changed, 30 insertions(+), 21 deletions(-) diff --git a/Documentation/ko_KR/HOWTO b/Documentation/ko_KR/HOWTO index e3a55b6091e9..ab5189ae3428 100644 --- a/Documentation/ko_KR/HOWTO +++ b/Documentation/ko_KR/HOWTO @@ -391,8 +391,8 @@ bugme-new ë©”ì¼ë§ 리스트나(새로운 버그 리í¬íŠ¸ë“¤ë§Œì´ ì´ê³³ì— bugme-janitor ë©”ì¼ë§ 리스트(bugzillaì— ëª¨ë“  ë³€í™”ë“¤ì´ ì—¬ê¸°ì„œ ë©”ì¼ë¡œ 전해진다) ì— ë“±ë¡í•˜ë©´ ëœë‹¤. - http://lists.osdl.org/mailman/listinfo/bugme-new - http://lists.osdl.org/mailman/listinfo/bugme-janitors + https://lists.linux-foundation.org/mailman/listinfo/bugme-new + https://lists.linux-foundation.org/mailman/listinfo/bugme-janitors diff --git a/Documentation/lguest/lguest.txt b/Documentation/lguest/lguest.txt index efb3a6a045a2..6ccaf8e1a00e 100644 --- a/Documentation/lguest/lguest.txt +++ b/Documentation/lguest/lguest.txt @@ -111,8 +111,11 @@ Running Lguest: Then use --tunnet=bridge:lg0 when launching the guest. - See http://linux-net.osdl.org/index.php/Bridge for general information - on how to get bridging working. + See: + + http://www.linuxfoundation.org/collaborate/workgroups/networking/bridge + + for general information on how to get bridging to work. There is a helpful mailing list at http://ozlabs.org/mailman/listinfo/lguest diff --git a/Documentation/networking/bridge.txt b/Documentation/networking/bridge.txt index bec69a8a1697..a7ba5e4e2c91 100644 --- a/Documentation/networking/bridge.txt +++ b/Documentation/networking/bridge.txt @@ -1,8 +1,8 @@ In order to use the Ethernet bridging functionality, you'll need the userspace tools. These programs and documentation are available -at http://www.linux-foundation.org/en/Net:Bridge. The download page is +at http://www.linuxfoundation.org/en/Net:Bridge. The download page is http://prdownloads.sourceforge.net/bridge. If you still have questions, don't hesitate to post to the mailing list -(more info http://lists.osdl.org/mailman/listinfo/bridge). +(more info https://lists.linux-foundation.org/mailman/listinfo/bridge). diff --git a/Documentation/networking/dccp.txt b/Documentation/networking/dccp.txt index 271d524a4c8d..1355fa413cb7 100644 --- a/Documentation/networking/dccp.txt +++ b/Documentation/networking/dccp.txt @@ -38,11 +38,11 @@ The Linux DCCP implementation does not currently support all the features that a specified in RFCs 4340...42. The known bugs are at: - http://linux-net.osdl.org/index.php/TODO#DCCP + http://www.linuxfoundation.org/collaborate/workgroups/networking/todo#DCCP For more up-to-date versions of the DCCP implementation, please consider using the experimental DCCP test tree; instructions for checking this out are on: -http://linux-net.osdl.org/index.php/DCCP_Testing#Experimental_DCCP_source_tree +http://www.linuxfoundation.org/collaborate/workgroups/networking/dccp_testing#Experimental_DCCP_source_tree Socket options diff --git a/Documentation/networking/generic_netlink.txt b/Documentation/networking/generic_netlink.txt index d4f8b8b9b53c..3e071115ca90 100644 --- a/Documentation/networking/generic_netlink.txt +++ b/Documentation/networking/generic_netlink.txt @@ -1,3 +1,3 @@ A wiki document on how to use Generic Netlink can be found here: - * http://linux-net.osdl.org/index.php/Generic_Netlink_HOWTO + * http://www.linuxfoundation.org/collaborate/workgroups/networking/generic_netlink_howto diff --git a/Documentation/zh_CN/HOWTO b/Documentation/zh_CN/HOWTO index 69160779e432..faf976c0c731 100644 --- a/Documentation/zh_CN/HOWTO +++ b/Documentation/zh_CN/HOWTO @@ -347,8 +347,8 @@ bugzilla.kernel.org是Linux内核开å‘者们用æ¥è·Ÿè¸ªå†…æ ¸Bug的网站。 最新bug的通知,å¯ä»¥è®¢é˜…bugme-new邮件列表(åªæœ‰æ–°çš„bug报告会被寄到这里) 或者订阅bugme-janitor邮件列表(所有bugzillaçš„å˜åŠ¨éƒ½ä¼šè¢«å¯„到这里)。 - http://lists.osdl.org/mailman/listinfo/bugme-new - http://lists.osdl.org/mailman/listinfo/bugme-janitors + https://lists.linux-foundation.org/mailman/listinfo/bugme-new + https://lists.linux-foundation.org/mailman/listinfo/bugme-janitors 邮件列表 diff --git a/Documentation/zh_CN/SubmittingDrivers b/Documentation/zh_CN/SubmittingDrivers index c27b0f6cdd39..5889f8df6312 100644 --- a/Documentation/zh_CN/SubmittingDrivers +++ b/Documentation/zh_CN/SubmittingDrivers @@ -61,7 +61,7 @@ Linux 2.4: Linux 2.6: 除了éµå¾ªå’Œ 2.4 版内核åŒæ ·çš„规则外,你还需è¦åœ¨ linux-kernel 邮件 列表上跟踪最新的 API å˜åŒ–ã€‚å‘ Linux 2.6 内核æ交驱动的顶级è”系人 - 是 Andrew Morton 。 + 是 Andrew Morton 。 决定设备驱动能å¦è¢«æŽ¥å—çš„æ¡ä»¶ ---------------------------- diff --git a/MAINTAINERS b/MAINTAINERS index cb8b58020352..4d204e2a9754 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1894,7 +1894,7 @@ F: drivers/scsi/dc395x.* DCCP PROTOCOL M: Arnaldo Carvalho de Melo L: dccp@vger.kernel.org -W: http://linux-net.osdl.org/index.php/DCCP +W: http://www.linuxfoundation.org/collaborate/workgroups/networking/dccp S: Maintained F: include/linux/dccp.h F: include/linux/tfrc.h @@ -2306,7 +2306,7 @@ ETHERNET BRIDGE M: Stephen Hemminger L: bridge@lists.linux-foundation.org L: netdev@vger.kernel.org -W: http://www.linux-foundation.org/en/Net:Bridge +W: http://www.linuxfoundation.org/en/Net:Bridge S: Maintained F: include/linux/netfilter_bridge/ F: net/bridge/ @@ -4478,7 +4478,7 @@ M: Jeremy Fitzhardinge M: Chris Wright M: Alok Kataria M: Rusty Russell -L: virtualization@lists.osdl.org +L: virtualization@lists.linux-foundation.org S: Supported F: Documentation/ia64/paravirt_ops.txt F: arch/*/kernel/paravirt* @@ -6352,7 +6352,7 @@ F: include/linux/virtio_console.h VIRTIO HOST (VHOST) M: "Michael S. Tsirkin" L: kvm@vger.kernel.org -L: virtualization@lists.osdl.org +L: virtualization@lists.linux-foundation.org L: netdev@vger.kernel.org S: Maintained F: drivers/vhost/ @@ -6613,7 +6613,7 @@ XEN HYPERVISOR INTERFACE M: Jeremy Fitzhardinge M: Konrad Rzeszutek Wilk L: xen-devel@lists.xen.org -L: virtualization@lists.osdl.org +L: virtualization@lists.linux-foundation.org S: Supported F: arch/x86/xen/ F: drivers/*/xen-*front.c diff --git a/net/Kconfig b/net/Kconfig index 55fd82e9ffd9..5e203b558703 100644 --- a/net/Kconfig +++ b/net/Kconfig @@ -247,7 +247,9 @@ config NET_TCPPROBE what was just said, you don't need it: say N. Documentation on how to use TCP connection probing can be found - at http://linux-net.osdl.org/index.php/TcpProbe + at: + + http://www.linuxfoundation.org/collaborate/workgroups/networking/tcpprobe To compile this code as a module, choose M here: the module will be called tcp_probe. diff --git a/net/dccp/Kconfig b/net/dccp/Kconfig index ad6dffd9070e..b75968a04017 100644 --- a/net/dccp/Kconfig +++ b/net/dccp/Kconfig @@ -49,7 +49,9 @@ config NET_DCCPPROBE what was just said, you don't need it: say N. Documentation on how to use DCCP connection probing can be found - at http://linux-net.osdl.org/index.php/DccpProbe + at: + + http://www.linuxfoundation.org/collaborate/workgroups/networking/dccpprobe To compile this code as a module, choose M here: the module will be called dccp_probe. diff --git a/net/ipv4/Kconfig b/net/ipv4/Kconfig index 9e95d7fb6d5a..a5a1050595d1 100644 --- a/net/ipv4/Kconfig +++ b/net/ipv4/Kconfig @@ -432,7 +432,9 @@ config INET_DIAG ---help--- Support for INET (TCP, DCCP, etc) socket monitoring interface used by native Linux tools such as ss. ss is included in iproute2, currently - downloadable at . + downloadable at: + + http://www.linuxfoundation.org/collaborate/workgroups/networking/iproute2 If unsure, say Y. diff --git a/net/sched/Kconfig b/net/sched/Kconfig index a36270a994d7..f04d4a484d53 100644 --- a/net/sched/Kconfig +++ b/net/sched/Kconfig @@ -24,7 +24,7 @@ menuconfig NET_SCHED To administer these schedulers, you'll need the user-level utilities from the package iproute2+tc at . That package also contains some documentation; for more, check out - . + . This Quality of Service (QoS) support will enable you to use Differentiated Services (diffserv) and Resource Reservation Protocol -- cgit v1.2.3 From af353d8a134d6147e29a3371015d2eef8d7f0657 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Tue, 16 Nov 2010 16:08:00 +0800 Subject: ASoC: Fix incorrect kfree in ad1836_probe error path We allocated memory for ad1836 in ad1836_spi_probe, and will free the memory in either ad1836_spi_probe error path or ad1836_spi_remove. Thus we should not call kfree(ad1836) in ad1836_probe, otherwise we have double free of ad1836. Signed-off-by: Axel Lin Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/codecs/ad1836.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sound/soc/codecs/ad1836.c b/sound/soc/codecs/ad1836.c index c71b05ddd752..e5d3db950a08 100644 --- a/sound/soc/codecs/ad1836.c +++ b/sound/soc/codecs/ad1836.c @@ -228,7 +228,6 @@ static int ad1836_probe(struct snd_soc_codec *codec) if (ret < 0) { dev_err(codec->dev, "failed to set cache I/O: %d\n", ret); - kfree(ad1836); return ret; } -- cgit v1.2.3 From 50d0ac2e1e98efa89f6dc167977b1a0d46d5e48e Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Tue, 16 Nov 2010 16:08:51 +0800 Subject: ASoC: Fix incorrect kfree in ad193x_probe error path We allocated memory for ad193x in ad193x_spi_probe, and will free the memory in either ad193x_spi_probe error path or ad193x_spi_remove. Thus we should not call kfree(ad193x) in ad193x_probe, otherwise we have double free of ad193x. Signed-off-by: Axel Lin Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/codecs/ad193x.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sound/soc/codecs/ad193x.c b/sound/soc/codecs/ad193x.c index dc105d8aaa0f..fd3e659f90b1 100644 --- a/sound/soc/codecs/ad193x.c +++ b/sound/soc/codecs/ad193x.c @@ -364,7 +364,6 @@ static int ad193x_probe(struct snd_soc_codec *codec) if (ret < 0) { dev_err(codec->dev, "failed to set cache I/O: %d\n", ret); - kfree(ad193x); return ret; } -- cgit v1.2.3 From 4ab867d276b83582f15c61270de1cc178df95659 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Tue, 16 Nov 2010 16:09:41 +0800 Subject: ASoC: Fix incorrect kfree in aic3x_probe error path We allocated memory for aic3x in aic3x_i2c_probe, and will free the memory in either aic3x_i2c_probe error path or aic3x_i2c_remove. Thus we should not call kfree(aic3x) in aic3x_probe, otherwise we have double free of aic3x. Signed-off-by: Axel Lin Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/codecs/tlv320aic3x.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c index 6173c2b4c364..df726a5066e8 100644 --- a/sound/soc/codecs/tlv320aic3x.c +++ b/sound/soc/codecs/tlv320aic3x.c @@ -1419,7 +1419,6 @@ err_get: if (aic3x->gpio_reset >= 0) gpio_free(aic3x->gpio_reset); err_gpio: - kfree(aic3x); return ret; } -- cgit v1.2.3 From 01cbea3293929acecef6785b7ea5be547dc039bc Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Tue, 16 Nov 2010 16:10:41 +0800 Subject: ASoC: Fix incorrect kfree in wm8731_probe error path We allocated memory for wm8731 in wm8731_spi_probe / wm8731_i2c_probe, and will free the memory in either wm8731_spi_probe / wm8731_i2c_probe error path or wm8731_spi_remove / wm8731_i2c_remove. Thus we should not call kfree(wm8731) in wm8731_probe, otherwise we have double free of wm8731. Signed-off-by: Axel Lin Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/codecs/wm8731.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sound/soc/codecs/wm8731.c b/sound/soc/codecs/wm8731.c index 95ade3245056..4b709589e26c 100644 --- a/sound/soc/codecs/wm8731.c +++ b/sound/soc/codecs/wm8731.c @@ -543,7 +543,6 @@ err_regulator_enable: err_regulator_get: regulator_bulk_free(ARRAY_SIZE(wm8731->supplies), wm8731->supplies); - kfree(wm8731); return ret; } -- cgit v1.2.3 From ce0df3d79a1b305cb39ea15a07235b5a6c3435b6 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Tue, 16 Nov 2010 16:11:37 +0800 Subject: ASoC: Fix incorrect kfree in wm8962_probe error path We allocated memory for wm8962 in wm8962_i2c_probe, and will free the memory in either wm8962_i2c_probe error path or wm8962_i2c_remove. Thus we should not call kfree(wm8962) in wm8962_probe, otherwise we have double free of wm8962. Signed-off-by: Axel Lin Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/codecs/wm8962.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c index e021866f5a85..9f6beca951c4 100644 --- a/sound/soc/codecs/wm8962.c +++ b/sound/soc/codecs/wm8962.c @@ -3874,7 +3874,6 @@ err_enable: err_get: regulator_bulk_free(ARRAY_SIZE(wm8962->supplies), wm8962->supplies); err: - kfree(wm8962); return ret; } -- cgit v1.2.3 From 84dab5671bff4516781c14f4fba5a1e2be13be1e Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 12 Nov 2010 15:28:42 +0000 Subject: ASoC: Use DAPM context rather than CODEC when constructing sequences DAPM widgets may be associated with non-CODEC devices so compare based on the DAPM context rather than the CODEC pointer. Signed-off-by: Mark Brown Acked-by: Jarkko Nikula Acked-by: Liam Girdwood --- sound/soc/soc-dapm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index 60c8dec49480..02b6ac46b278 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -710,8 +710,8 @@ static int dapm_seq_compare(struct snd_soc_dapm_widget *a, return sort[a->id] - sort[b->id]; if (a->reg != b->reg) return a->reg - b->reg; - if (a->codec != b->codec) - return (unsigned long)a->codec - (unsigned long)b->codec; + if (a->dapm != b->dapm) + return (unsigned long)a->dapm - (unsigned long)b->dapm; return 0; } -- cgit v1.2.3 From d07335e51df0c6dec202d315fc4f1f7e100eec4e Mon Sep 17 00:00:00 2001 From: Mike Snitzer Date: Tue, 16 Nov 2010 12:52:38 +0100 Subject: block: Rename "block_remap" tracepoint to "block_bio_remap" to clarify the event. Signed-off-by: Kiyoshi Ueda Signed-off-by: Jun'ichi Nomura Signed-off-by: Mike Snitzer Signed-off-by: Jens Axboe --- block/blk-core.c | 10 +++++----- drivers/md/dm.c | 4 ++-- include/trace/events/block.h | 6 +++--- kernel/trace/blktrace.c | 12 ++++++------ 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/block/blk-core.c b/block/blk-core.c index 4ce953f1b390..151070541e21 100644 --- a/block/blk-core.c +++ b/block/blk-core.c @@ -33,7 +33,7 @@ #include "blk.h" -EXPORT_TRACEPOINT_SYMBOL_GPL(block_remap); +EXPORT_TRACEPOINT_SYMBOL_GPL(block_bio_remap); EXPORT_TRACEPOINT_SYMBOL_GPL(block_rq_remap); EXPORT_TRACEPOINT_SYMBOL_GPL(block_bio_complete); @@ -1329,9 +1329,9 @@ static inline void blk_partition_remap(struct bio *bio) bio->bi_sector += p->start_sect; bio->bi_bdev = bdev->bd_contains; - trace_block_remap(bdev_get_queue(bio->bi_bdev), bio, - bdev->bd_dev, - bio->bi_sector - p->start_sect); + trace_block_bio_remap(bdev_get_queue(bio->bi_bdev), bio, + bdev->bd_dev, + bio->bi_sector - p->start_sect); } } @@ -1500,7 +1500,7 @@ static inline void __generic_make_request(struct bio *bio) goto end_io; if (old_sector != -1) - trace_block_remap(q, bio, old_dev, old_sector); + trace_block_bio_remap(q, bio, old_dev, old_sector); old_sector = bio->bi_sector; old_dev = bio->bi_bdev->bd_dev; diff --git a/drivers/md/dm.c b/drivers/md/dm.c index 7cb1352f7e7a..0a2b5516bc21 100644 --- a/drivers/md/dm.c +++ b/drivers/md/dm.c @@ -990,8 +990,8 @@ static void __map_bio(struct dm_target *ti, struct bio *clone, if (r == DM_MAPIO_REMAPPED) { /* the bio has been remapped so dispatch it */ - trace_block_remap(bdev_get_queue(clone->bi_bdev), clone, - tio->io->bio->bi_bdev->bd_dev, sector); + trace_block_bio_remap(bdev_get_queue(clone->bi_bdev), clone, + tio->io->bio->bi_bdev->bd_dev, sector); generic_make_request(clone); } else if (r < 0 || r == DM_MAPIO_REQUEUE) { diff --git a/include/trace/events/block.h b/include/trace/events/block.h index d8ce278515c3..b56c65dc105d 100644 --- a/include/trace/events/block.h +++ b/include/trace/events/block.h @@ -486,16 +486,16 @@ TRACE_EVENT(block_split, ); /** - * block_remap - map request for a partition to the raw device + * block_bio_remap - map request for a logical device to the raw device * @q: queue holding the operation * @bio: revised operation * @dev: device for the operation * @from: original sector for the operation * - * An operation for a partition on a block device has been mapped to the + * An operation for a logical device has been mapped to the * raw block device. */ -TRACE_EVENT(block_remap, +TRACE_EVENT(block_bio_remap, TP_PROTO(struct request_queue *q, struct bio *bio, dev_t dev, sector_t from), diff --git a/kernel/trace/blktrace.c b/kernel/trace/blktrace.c index 7b8ec0281548..2b8e2ee7c0ef 100644 --- a/kernel/trace/blktrace.c +++ b/kernel/trace/blktrace.c @@ -887,7 +887,7 @@ static void blk_add_trace_split(void *ignore, } /** - * blk_add_trace_remap - Add a trace for a remap operation + * blk_add_trace_bio_remap - Add a trace for a bio-remap operation * @ignore: trace callback data parameter (not used) * @q: queue the io is for * @bio: the source bio @@ -899,9 +899,9 @@ static void blk_add_trace_split(void *ignore, * it spans a stripe (or similar). Add a trace for that action. * **/ -static void blk_add_trace_remap(void *ignore, - struct request_queue *q, struct bio *bio, - dev_t dev, sector_t from) +static void blk_add_trace_bio_remap(void *ignore, + struct request_queue *q, struct bio *bio, + dev_t dev, sector_t from) { struct blk_trace *bt = q->blk_trace; struct blk_io_trace_remap r; @@ -1016,7 +1016,7 @@ static void blk_register_tracepoints(void) WARN_ON(ret); ret = register_trace_block_split(blk_add_trace_split, NULL); WARN_ON(ret); - ret = register_trace_block_remap(blk_add_trace_remap, NULL); + ret = register_trace_block_bio_remap(blk_add_trace_bio_remap, NULL); WARN_ON(ret); ret = register_trace_block_rq_remap(blk_add_trace_rq_remap, NULL); WARN_ON(ret); @@ -1025,7 +1025,7 @@ static void blk_register_tracepoints(void) static void blk_unregister_tracepoints(void) { unregister_trace_block_rq_remap(blk_add_trace_rq_remap, NULL); - unregister_trace_block_remap(blk_add_trace_remap, NULL); + unregister_trace_block_bio_remap(blk_add_trace_bio_remap, NULL); unregister_trace_block_split(blk_add_trace_split, NULL); unregister_trace_block_unplug_io(blk_add_trace_unplug_io, NULL); unregister_trace_block_unplug_timer(blk_add_trace_unplug_timer, NULL); -- cgit v1.2.3 From 073ef1f6e508688392580e4f35dcad9aabd1e100 Mon Sep 17 00:00:00 2001 From: Lionel Debroux Date: Tue, 9 Nov 2010 21:48:49 +0100 Subject: hibernation: constify platform_hibernation_ops Patch against mainline. Changes since v1: added one hunk; no longer adding "const" qualifier to pointers in platform_hibernation_ops after seeing b4144e4f6e3b448d322095ca08af393682a69e33. Signed-off-by: Jiri Kosina --- drivers/acpi/sleep.c | 4 ++-- include/linux/suspend.h | 4 ++-- kernel/power/hibernate.c | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index 721d93b3ceee..5149c9bf7015 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c @@ -498,7 +498,7 @@ static void acpi_pm_thaw(void) acpi_enable_all_runtime_gpes(); } -static struct platform_hibernation_ops acpi_hibernation_ops = { +static const struct platform_hibernation_ops acpi_hibernation_ops = { .begin = acpi_hibernation_begin, .end = acpi_pm_end, .pre_snapshot = acpi_pm_prepare, @@ -541,7 +541,7 @@ static int acpi_hibernation_begin_old(void) * The following callbacks are used if the pre-ACPI 2.0 suspend ordering has * been requested. */ -static struct platform_hibernation_ops acpi_hibernation_ops_old = { +static const struct platform_hibernation_ops acpi_hibernation_ops_old = { .begin = acpi_hibernation_begin_old, .end = acpi_pm_end, .pre_snapshot = acpi_pm_pre_suspend, diff --git a/include/linux/suspend.h b/include/linux/suspend.h index 26697514c5ec..40ead943fd6a 100644 --- a/include/linux/suspend.h +++ b/include/linux/suspend.h @@ -245,7 +245,7 @@ extern void swsusp_set_page_free(struct page *); extern void swsusp_unset_page_free(struct page *); extern unsigned long get_safe_page(gfp_t gfp_mask); -extern void hibernation_set_ops(struct platform_hibernation_ops *ops); +extern void hibernation_set_ops(const struct platform_hibernation_ops *ops); extern int hibernate(void); extern bool system_entering_hibernation(void); #else /* CONFIG_HIBERNATION */ @@ -253,7 +253,7 @@ static inline int swsusp_page_is_forbidden(struct page *p) { return 0; } static inline void swsusp_set_page_free(struct page *p) {} static inline void swsusp_unset_page_free(struct page *p) {} -static inline void hibernation_set_ops(struct platform_hibernation_ops *ops) {} +static inline void hibernation_set_ops(const struct platform_hibernation_ops *ops) {} static inline int hibernate(void) { return -ENOSYS; } static inline bool system_entering_hibernation(void) { return false; } #endif /* CONFIG_HIBERNATION */ diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c index 657272e91d0a..491b81a27111 100644 --- a/kernel/power/hibernate.c +++ b/kernel/power/hibernate.c @@ -51,14 +51,14 @@ enum { static int hibernation_mode = HIBERNATION_SHUTDOWN; -static struct platform_hibernation_ops *hibernation_ops; +static const struct platform_hibernation_ops *hibernation_ops; /** * hibernation_set_ops - set the global hibernate operations * @ops: the hibernation operations to use in subsequent hibernation transitions */ -void hibernation_set_ops(struct platform_hibernation_ops *ops) +void hibernation_set_ops(const struct platform_hibernation_ops *ops) { if (ops && !(ops->begin && ops->end && ops->pre_snapshot && ops->prepare && ops->finish && ops->enter && ops->pre_restore -- cgit v1.2.3 From acc2472ed33fc5e72482cc3b3b846077d97c2f8b Mon Sep 17 00:00:00 2001 From: Lionel Debroux Date: Tue, 16 Nov 2010 14:14:02 +0100 Subject: backlight: constify backlight_ops backlight_device_register has been expecting a const "ops" argument, and using it as such, since 9905a43b2d563e6f89e4c63c4278ada03f2ebb14. Let's make the remaining backlight_ops instances const. Inspired by hunks of the grsecurity patch, updated for newer kernels. Signed-off-by: Lionel Debroux Acked-by: Ingo Molnar Signed-off-by: Jiri Kosina --- drivers/acpi/video.c | 2 +- drivers/gpu/drm/nouveau/nouveau_backlight.c | 4 ++-- drivers/macintosh/via-pmu-backlight.c | 4 ++-- drivers/platform/x86/acer-wmi.c | 2 +- drivers/platform/x86/asus-laptop.c | 2 +- drivers/platform/x86/asus_acpi.c | 2 +- drivers/platform/x86/dell-laptop.c | 2 +- drivers/platform/x86/eeepc-laptop.c | 2 +- drivers/platform/x86/fujitsu-laptop.c | 2 +- drivers/platform/x86/sony-laptop.c | 2 +- drivers/platform/x86/thinkpad_acpi.c | 2 +- drivers/platform/x86/toshiba_acpi.c | 2 +- drivers/staging/msm/msm_fb_bl.c | 2 +- drivers/staging/olpc_dcon/olpc_dcon.c | 2 +- drivers/staging/samsung-laptop/samsung-laptop.c | 2 +- drivers/video/atmel_lcdfb.c | 2 +- drivers/video/aty/aty128fb.c | 2 +- drivers/video/aty/atyfb_base.c | 2 +- drivers/video/aty/radeon_backlight.c | 2 +- drivers/video/backlight/88pm860x_bl.c | 2 +- drivers/video/backlight/max8925_bl.c | 2 +- drivers/video/nvidia/nv_backlight.c | 2 +- drivers/video/omap2/displays/panel-taal.c | 2 +- drivers/video/riva/fbdev.c | 2 +- 24 files changed, 26 insertions(+), 26 deletions(-) diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index 5cd0228d2daa..15a0fde4b32a 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c @@ -260,7 +260,7 @@ static int acpi_video_set_brightness(struct backlight_device *bd) vd->brightness->levels[request_level]); } -static struct backlight_ops acpi_backlight_ops = { +static const struct backlight_ops acpi_backlight_ops = { .get_brightness = acpi_video_get_brightness, .update_status = acpi_video_set_brightness, }; diff --git a/drivers/gpu/drm/nouveau/nouveau_backlight.c b/drivers/gpu/drm/nouveau/nouveau_backlight.c index 406228f4a2a0..8933e985c227 100644 --- a/drivers/gpu/drm/nouveau/nouveau_backlight.c +++ b/drivers/gpu/drm/nouveau/nouveau_backlight.c @@ -58,7 +58,7 @@ static int nv40_set_intensity(struct backlight_device *bd) return 0; } -static struct backlight_ops nv40_bl_ops = { +static const struct backlight_ops nv40_bl_ops = { .options = BL_CORE_SUSPENDRESUME, .get_brightness = nv40_get_intensity, .update_status = nv40_set_intensity, @@ -81,7 +81,7 @@ static int nv50_set_intensity(struct backlight_device *bd) return 0; } -static struct backlight_ops nv50_bl_ops = { +static const struct backlight_ops nv50_bl_ops = { .options = BL_CORE_SUSPENDRESUME, .get_brightness = nv50_get_intensity, .update_status = nv50_set_intensity, diff --git a/drivers/macintosh/via-pmu-backlight.c b/drivers/macintosh/via-pmu-backlight.c index 1cec02f6c431..ade1e656bfb2 100644 --- a/drivers/macintosh/via-pmu-backlight.c +++ b/drivers/macintosh/via-pmu-backlight.c @@ -15,7 +15,7 @@ #define MAX_PMU_LEVEL 0xFF -static struct backlight_ops pmu_backlight_data; +static const struct backlight_ops pmu_backlight_data; static DEFINE_SPINLOCK(pmu_backlight_lock); static int sleeping, uses_pmu_bl; static u8 bl_curve[FB_BACKLIGHT_LEVELS]; @@ -115,7 +115,7 @@ static int pmu_backlight_get_brightness(struct backlight_device *bd) return bd->props.brightness; } -static struct backlight_ops pmu_backlight_data = { +static const struct backlight_ops pmu_backlight_data = { .get_brightness = pmu_backlight_get_brightness, .update_status = pmu_backlight_update_status, diff --git a/drivers/platform/x86/acer-wmi.c b/drivers/platform/x86/acer-wmi.c index c8c65375bfe2..1d0b707aeafc 100644 --- a/drivers/platform/x86/acer-wmi.c +++ b/drivers/platform/x86/acer-wmi.c @@ -915,7 +915,7 @@ static int update_bl_status(struct backlight_device *bd) return 0; } -static struct backlight_ops acer_bl_ops = { +static const struct backlight_ops acer_bl_ops = { .get_brightness = read_brightness, .update_status = update_bl_status, }; diff --git a/drivers/platform/x86/asus-laptop.c b/drivers/platform/x86/asus-laptop.c index 60a5a5c6b50a..3640599446fc 100644 --- a/drivers/platform/x86/asus-laptop.c +++ b/drivers/platform/x86/asus-laptop.c @@ -621,7 +621,7 @@ static int update_bl_status(struct backlight_device *bd) return asus_lcd_set(asus, value); } -static struct backlight_ops asusbl_ops = { +static const struct backlight_ops asusbl_ops = { .get_brightness = asus_read_brightness, .update_status = update_bl_status, }; diff --git a/drivers/platform/x86/asus_acpi.c b/drivers/platform/x86/asus_acpi.c index ca05aefd03bf..4633fd8532cc 100644 --- a/drivers/platform/x86/asus_acpi.c +++ b/drivers/platform/x86/asus_acpi.c @@ -1467,7 +1467,7 @@ static int asus_hotk_remove(struct acpi_device *device, int type) return 0; } -static struct backlight_ops asus_backlight_data = { +static const struct backlight_ops asus_backlight_data = { .get_brightness = read_brightness, .update_status = set_brightness_status, }; diff --git a/drivers/platform/x86/dell-laptop.c b/drivers/platform/x86/dell-laptop.c index cf8a89a0d8f5..34657f96b5a5 100644 --- a/drivers/platform/x86/dell-laptop.c +++ b/drivers/platform/x86/dell-laptop.c @@ -546,7 +546,7 @@ out: return buffer->output[1]; } -static struct backlight_ops dell_ops = { +static const struct backlight_ops dell_ops = { .get_brightness = dell_get_intensity, .update_status = dell_send_intensity, }; diff --git a/drivers/platform/x86/eeepc-laptop.c b/drivers/platform/x86/eeepc-laptop.c index b2edfdcdcb84..c062a6534590 100644 --- a/drivers/platform/x86/eeepc-laptop.c +++ b/drivers/platform/x86/eeepc-laptop.c @@ -1115,7 +1115,7 @@ static int update_bl_status(struct backlight_device *bd) return set_brightness(bd, bd->props.brightness); } -static struct backlight_ops eeepcbl_ops = { +static const struct backlight_ops eeepcbl_ops = { .get_brightness = read_brightness, .update_status = update_bl_status, }; diff --git a/drivers/platform/x86/fujitsu-laptop.c b/drivers/platform/x86/fujitsu-laptop.c index f44cd2620ff9..34d0dc590d76 100644 --- a/drivers/platform/x86/fujitsu-laptop.c +++ b/drivers/platform/x86/fujitsu-laptop.c @@ -437,7 +437,7 @@ static int bl_update_status(struct backlight_device *b) return ret; } -static struct backlight_ops fujitsubl_ops = { +static const struct backlight_ops fujitsubl_ops = { .get_brightness = bl_get_brightness, .update_status = bl_update_status, }; diff --git a/drivers/platform/x86/sony-laptop.c b/drivers/platform/x86/sony-laptop.c index f200677851b8..f8b2fc992276 100644 --- a/drivers/platform/x86/sony-laptop.c +++ b/drivers/platform/x86/sony-laptop.c @@ -856,7 +856,7 @@ static int sony_backlight_get_brightness(struct backlight_device *bd) } static struct backlight_device *sony_backlight_device; -static struct backlight_ops sony_backlight_ops = { +static const struct backlight_ops sony_backlight_ops = { .update_status = sony_backlight_update_status, .get_brightness = sony_backlight_get_brightness, }; diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index 304333faf441..efda9c54e0e2 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c @@ -6109,7 +6109,7 @@ static void tpacpi_brightness_notify_change(void) BACKLIGHT_UPDATE_HOTKEY); } -static struct backlight_ops ibm_backlight_data = { +static const struct backlight_ops ibm_backlight_data = { .get_brightness = brightness_get, .update_status = brightness_update_status, }; diff --git a/drivers/platform/x86/toshiba_acpi.c b/drivers/platform/x86/toshiba_acpi.c index 06f304f46e02..81bca5a4d8aa 100644 --- a/drivers/platform/x86/toshiba_acpi.c +++ b/drivers/platform/x86/toshiba_acpi.c @@ -840,7 +840,7 @@ static void remove_toshiba_proc_entries(void) remove_proc_entry("version", toshiba_proc_dir); } -static struct backlight_ops toshiba_backlight_data = { +static const struct backlight_ops toshiba_backlight_data = { .get_brightness = get_lcd, .update_status = set_lcd_status, }; diff --git a/drivers/staging/msm/msm_fb_bl.c b/drivers/staging/msm/msm_fb_bl.c index 033fc9486e01..2a8077511fc0 100644 --- a/drivers/staging/msm/msm_fb_bl.c +++ b/drivers/staging/msm/msm_fb_bl.c @@ -42,7 +42,7 @@ static int msm_fb_bl_update_status(struct backlight_device *pbd) return 0; } -static struct backlight_ops msm_fb_bl_ops = { +static const struct backlight_ops msm_fb_bl_ops = { .get_brightness = msm_fb_bl_get_brightness, .update_status = msm_fb_bl_update_status, }; diff --git a/drivers/staging/olpc_dcon/olpc_dcon.c b/drivers/staging/olpc_dcon/olpc_dcon.c index 75aa7a36307d..d40ff41774be 100644 --- a/drivers/staging/olpc_dcon/olpc_dcon.c +++ b/drivers/staging/olpc_dcon/olpc_dcon.c @@ -616,7 +616,7 @@ static struct device_attribute dcon_device_files[] = { __ATTR(resumeline, 0644, dcon_resumeline_show, dcon_resumeline_store), }; -static struct backlight_ops dcon_bl_ops = { +static const struct backlight_ops dcon_bl_ops = { .get_brightness = dconbl_get, .update_status = dconbl_set }; diff --git a/drivers/staging/samsung-laptop/samsung-laptop.c b/drivers/staging/samsung-laptop/samsung-laptop.c index eb44b60e1eb5..80eeec6d6719 100644 --- a/drivers/staging/samsung-laptop/samsung-laptop.c +++ b/drivers/staging/samsung-laptop/samsung-laptop.c @@ -269,7 +269,7 @@ static int update_status(struct backlight_device *bd) return 0; } -static struct backlight_ops backlight_ops = { +static const struct backlight_ops backlight_ops = { .get_brightness = get_brightness, .update_status = update_status, }; diff --git a/drivers/video/atmel_lcdfb.c b/drivers/video/atmel_lcdfb.c index 8dce25126330..bac163450216 100644 --- a/drivers/video/atmel_lcdfb.c +++ b/drivers/video/atmel_lcdfb.c @@ -111,7 +111,7 @@ static int atmel_bl_get_brightness(struct backlight_device *bl) return lcdc_readl(sinfo, ATMEL_LCDC_CONTRAST_VAL); } -static struct backlight_ops atmel_lcdc_bl_ops = { +static const struct backlight_ops atmel_lcdc_bl_ops = { .update_status = atmel_bl_update_status, .get_brightness = atmel_bl_get_brightness, }; diff --git a/drivers/video/aty/aty128fb.c b/drivers/video/aty/aty128fb.c index 34a0851bcbfa..dd9de2e80580 100644 --- a/drivers/video/aty/aty128fb.c +++ b/drivers/video/aty/aty128fb.c @@ -1786,7 +1786,7 @@ static int aty128_bl_get_brightness(struct backlight_device *bd) return bd->props.brightness; } -static struct backlight_ops aty128_bl_data = { +static const struct backlight_ops aty128_bl_data = { .get_brightness = aty128_bl_get_brightness, .update_status = aty128_bl_update_status, }; diff --git a/drivers/video/aty/atyfb_base.c b/drivers/video/aty/atyfb_base.c index 5bf91236c701..4d5c41371543 100644 --- a/drivers/video/aty/atyfb_base.c +++ b/drivers/video/aty/atyfb_base.c @@ -2221,7 +2221,7 @@ static int aty_bl_get_brightness(struct backlight_device *bd) return bd->props.brightness; } -static struct backlight_ops aty_bl_data = { +static const struct backlight_ops aty_bl_data = { .get_brightness = aty_bl_get_brightness, .update_status = aty_bl_update_status, }; diff --git a/drivers/video/aty/radeon_backlight.c b/drivers/video/aty/radeon_backlight.c index 256966e9667d..9b811ddbce83 100644 --- a/drivers/video/aty/radeon_backlight.c +++ b/drivers/video/aty/radeon_backlight.c @@ -128,7 +128,7 @@ static int radeon_bl_get_brightness(struct backlight_device *bd) return bd->props.brightness; } -static struct backlight_ops radeon_bl_data = { +static const struct backlight_ops radeon_bl_data = { .get_brightness = radeon_bl_get_brightness, .update_status = radeon_bl_update_status, }; diff --git a/drivers/video/backlight/88pm860x_bl.c b/drivers/video/backlight/88pm860x_bl.c index 38ffc3fbcbe4..c789c46e38af 100644 --- a/drivers/video/backlight/88pm860x_bl.c +++ b/drivers/video/backlight/88pm860x_bl.c @@ -155,7 +155,7 @@ out: return -EINVAL; } -static struct backlight_ops pm860x_backlight_ops = { +static const struct backlight_ops pm860x_backlight_ops = { .options = BL_CORE_SUSPENDRESUME, .update_status = pm860x_backlight_update_status, .get_brightness = pm860x_backlight_get_brightness, diff --git a/drivers/video/backlight/max8925_bl.c b/drivers/video/backlight/max8925_bl.c index b2b2c7ba1f63..209acc105cbc 100644 --- a/drivers/video/backlight/max8925_bl.c +++ b/drivers/video/backlight/max8925_bl.c @@ -92,7 +92,7 @@ static int max8925_backlight_get_brightness(struct backlight_device *bl) return ret; } -static struct backlight_ops max8925_backlight_ops = { +static const struct backlight_ops max8925_backlight_ops = { .options = BL_CORE_SUSPENDRESUME, .update_status = max8925_backlight_update_status, .get_brightness = max8925_backlight_get_brightness, diff --git a/drivers/video/nvidia/nv_backlight.c b/drivers/video/nvidia/nv_backlight.c index 2fb552a6f32c..6aac6d1b937b 100644 --- a/drivers/video/nvidia/nv_backlight.c +++ b/drivers/video/nvidia/nv_backlight.c @@ -87,7 +87,7 @@ static int nvidia_bl_get_brightness(struct backlight_device *bd) return bd->props.brightness; } -static struct backlight_ops nvidia_bl_ops = { +static const struct backlight_ops nvidia_bl_ops = { .get_brightness = nvidia_bl_get_brightness, .update_status = nvidia_bl_update_status, }; diff --git a/drivers/video/omap2/displays/panel-taal.c b/drivers/video/omap2/displays/panel-taal.c index e1c765d11419..61026f96ad20 100644 --- a/drivers/video/omap2/displays/panel-taal.c +++ b/drivers/video/omap2/displays/panel-taal.c @@ -465,7 +465,7 @@ static int taal_bl_get_intensity(struct backlight_device *dev) return 0; } -static struct backlight_ops taal_bl_ops = { +static const struct backlight_ops taal_bl_ops = { .get_brightness = taal_bl_get_intensity, .update_status = taal_bl_update_status, }; diff --git a/drivers/video/riva/fbdev.c b/drivers/video/riva/fbdev.c index 618f36bec10d..da388186d617 100644 --- a/drivers/video/riva/fbdev.c +++ b/drivers/video/riva/fbdev.c @@ -331,7 +331,7 @@ static int riva_bl_get_brightness(struct backlight_device *bd) return bd->props.brightness; } -static struct backlight_ops riva_bl_ops = { +static const struct backlight_ops riva_bl_ops = { .get_brightness = riva_bl_get_brightness, .update_status = riva_bl_update_status, }; -- cgit v1.2.3 From 2f55ac072f5344519348c0c94b3d2f4cca46847b Mon Sep 17 00:00:00 2001 From: Lionel Debroux Date: Tue, 16 Nov 2010 14:14:02 +0100 Subject: suspend: constify platform_suspend_ops While at it, fix two checkpatch errors. Several non-const struct instances constified by this patch were added after the introduction of platform_suspend_ops in checkpatch.pl's list of "should be const" structs (79404849e90a41ea2109bd0e2f7c7164b0c4ce73). Patch against mainline. Inspired by hunks of the grsecurity patch, updated for newer kernels. Signed-off-by: Lionel Debroux Acked-by: Ingo Molnar Signed-off-by: Jiri Kosina --- arch/arm/mach-at91/pm.c | 2 +- arch/arm/mach-davinci/pm.c | 2 +- arch/arm/mach-imx/pm-imx27.c | 2 +- arch/arm/mach-lpc32xx/pm.c | 2 +- arch/arm/mach-omap1/pm.c | 2 +- arch/arm/mach-omap2/pm24xx.c | 2 +- arch/arm/mach-omap2/pm34xx.c | 2 +- arch/arm/mach-omap2/pm44xx.c | 2 +- arch/arm/mach-pnx4008/pm.c | 2 +- arch/arm/mach-pxa/pm.c | 2 +- arch/arm/mach-pxa/sharpsl_pm.c | 2 +- arch/arm/mach-sa1100/pm.c | 2 +- arch/arm/plat-samsung/pm.c | 2 +- arch/avr32/mach-at32ap/pm.c | 2 +- arch/blackfin/mach-common/pm.c | 2 +- arch/mips/alchemy/devboards/pm.c | 2 +- arch/mips/jz4740/pm.c | 2 +- arch/mips/loongson/common/pm.c | 2 +- arch/powerpc/platforms/52xx/lite5200_pm.c | 2 +- arch/powerpc/platforms/52xx/mpc52xx_pm.c | 2 +- arch/powerpc/platforms/83xx/suspend.c | 2 +- arch/powerpc/platforms/pseries/suspend.c | 2 +- arch/powerpc/sysdev/fsl_pmc.c | 2 +- arch/sh/boards/mach-hp6xx/pm.c | 2 +- arch/sh/kernel/cpu/shmobile/pm.c | 2 +- drivers/acpi/sleep.c | 4 ++-- drivers/macintosh/via-pmu.c | 2 +- include/linux/suspend.h | 4 ++-- kernel/power/suspend.c | 4 ++-- 29 files changed, 32 insertions(+), 32 deletions(-) diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c index dafbacc25eb1..ea53f4d9b283 100644 --- a/arch/arm/mach-at91/pm.c +++ b/arch/arm/mach-at91/pm.c @@ -301,7 +301,7 @@ static void at91_pm_end(void) } -static struct platform_suspend_ops at91_pm_ops ={ +static const struct platform_suspend_ops at91_pm_ops = { .valid = at91_pm_valid_state, .begin = at91_pm_begin, .enter = at91_pm_enter, diff --git a/arch/arm/mach-davinci/pm.c b/arch/arm/mach-davinci/pm.c index fab953b43dea..1bd73a04be20 100644 --- a/arch/arm/mach-davinci/pm.c +++ b/arch/arm/mach-davinci/pm.c @@ -110,7 +110,7 @@ static int davinci_pm_enter(suspend_state_t state) return ret; } -static struct platform_suspend_ops davinci_pm_ops = { +static const struct platform_suspend_ops davinci_pm_ops = { .enter = davinci_pm_enter, .valid = suspend_valid_only_mem, }; diff --git a/arch/arm/mach-imx/pm-imx27.c b/arch/arm/mach-imx/pm-imx27.c index afc17ce0bb54..2153ca71bb82 100644 --- a/arch/arm/mach-imx/pm-imx27.c +++ b/arch/arm/mach-imx/pm-imx27.c @@ -32,7 +32,7 @@ static int mx27_suspend_enter(suspend_state_t state) return 0; } -static struct platform_suspend_ops mx27_suspend_ops = { +static const struct platform_suspend_ops mx27_suspend_ops = { .enter = mx27_suspend_enter, .valid = suspend_valid_only_mem, }; diff --git a/arch/arm/mach-lpc32xx/pm.c b/arch/arm/mach-lpc32xx/pm.c index a6e2aed9a49f..e76d41bb7056 100644 --- a/arch/arm/mach-lpc32xx/pm.c +++ b/arch/arm/mach-lpc32xx/pm.c @@ -123,7 +123,7 @@ static int lpc32xx_pm_enter(suspend_state_t state) return 0; } -static struct platform_suspend_ops lpc32xx_pm_ops = { +static const struct platform_suspend_ops lpc32xx_pm_ops = { .valid = suspend_valid_only_mem, .enter = lpc32xx_pm_enter, }; diff --git a/arch/arm/mach-omap1/pm.c b/arch/arm/mach-omap1/pm.c index b1d3f9fade23..4cf3b67dd998 100644 --- a/arch/arm/mach-omap1/pm.c +++ b/arch/arm/mach-omap1/pm.c @@ -647,7 +647,7 @@ static struct irqaction omap_wakeup_irq = { -static struct platform_suspend_ops omap_pm_ops ={ +static const struct platform_suspend_ops omap_pm_ops = { .prepare = omap_pm_prepare, .enter = omap_pm_enter, .finish = omap_pm_finish, diff --git a/arch/arm/mach-omap2/pm24xx.c b/arch/arm/mach-omap2/pm24xx.c index a40457d81927..aa9764eeb941 100644 --- a/arch/arm/mach-omap2/pm24xx.c +++ b/arch/arm/mach-omap2/pm24xx.c @@ -326,7 +326,7 @@ static void omap2_pm_finish(void) enable_hlt(); } -static struct platform_suspend_ops omap_pm_ops = { +static const struct platform_suspend_ops omap_pm_ops = { .prepare = omap2_pm_prepare, .enter = omap2_pm_enter, .finish = omap2_pm_finish, diff --git a/arch/arm/mach-omap2/pm34xx.c b/arch/arm/mach-omap2/pm34xx.c index 75c0cd13ad8e..4000c3c8bbd5 100644 --- a/arch/arm/mach-omap2/pm34xx.c +++ b/arch/arm/mach-omap2/pm34xx.c @@ -594,7 +594,7 @@ static void omap3_pm_end(void) return; } -static struct platform_suspend_ops omap_pm_ops = { +static const struct platform_suspend_ops omap_pm_ops = { .begin = omap3_pm_begin, .end = omap3_pm_end, .prepare = omap3_pm_prepare, diff --git a/arch/arm/mach-omap2/pm44xx.c b/arch/arm/mach-omap2/pm44xx.c index 54544b4fc76b..dc8b1ef9f84c 100644 --- a/arch/arm/mach-omap2/pm44xx.c +++ b/arch/arm/mach-omap2/pm44xx.c @@ -75,7 +75,7 @@ static void omap4_pm_end(void) return; } -static struct platform_suspend_ops omap_pm_ops = { +static const struct platform_suspend_ops omap_pm_ops = { .begin = omap4_pm_begin, .end = omap4_pm_end, .prepare = omap4_pm_prepare, diff --git a/arch/arm/mach-pnx4008/pm.c b/arch/arm/mach-pnx4008/pm.c index ee3c29c57ae3..f3e60a049f98 100644 --- a/arch/arm/mach-pnx4008/pm.c +++ b/arch/arm/mach-pnx4008/pm.c @@ -119,7 +119,7 @@ static int pnx4008_pm_valid(suspend_state_t state) (state == PM_SUSPEND_MEM); } -static struct platform_suspend_ops pnx4008_pm_ops = { +static const struct platform_suspend_ops pnx4008_pm_ops = { .enter = pnx4008_pm_enter, .valid = pnx4008_pm_valid, }; diff --git a/arch/arm/mach-pxa/pm.c b/arch/arm/mach-pxa/pm.c index 166c15f62916..978e1b289544 100644 --- a/arch/arm/mach-pxa/pm.c +++ b/arch/arm/mach-pxa/pm.c @@ -96,7 +96,7 @@ void pxa_pm_finish(void) pxa_cpu_pm_fns->finish(); } -static struct platform_suspend_ops pxa_pm_ops = { +static const struct platform_suspend_ops pxa_pm_ops = { .valid = pxa_pm_valid, .enter = pxa_pm_enter, .prepare = pxa_pm_prepare, diff --git a/arch/arm/mach-pxa/sharpsl_pm.c b/arch/arm/mach-pxa/sharpsl_pm.c index 8fed027b12dc..02874e96ec72 100644 --- a/arch/arm/mach-pxa/sharpsl_pm.c +++ b/arch/arm/mach-pxa/sharpsl_pm.c @@ -868,7 +868,7 @@ static void sharpsl_apm_get_power_status(struct apm_power_info *info) } #ifdef CONFIG_PM -static struct platform_suspend_ops sharpsl_pm_ops = { +static const struct platform_suspend_ops sharpsl_pm_ops = { .prepare = pxa_pm_prepare, .finish = pxa_pm_finish, .enter = corgi_pxa_pm_enter, diff --git a/arch/arm/mach-sa1100/pm.c b/arch/arm/mach-sa1100/pm.c index c83fdc80edfd..ab9fc4470d36 100644 --- a/arch/arm/mach-sa1100/pm.c +++ b/arch/arm/mach-sa1100/pm.c @@ -120,7 +120,7 @@ unsigned long sleep_phys_sp(void *sp) return virt_to_phys(sp); } -static struct platform_suspend_ops sa11x0_pm_ops = { +static const struct platform_suspend_ops sa11x0_pm_ops = { .enter = sa11x0_pm_enter, .valid = suspend_valid_only_mem, }; diff --git a/arch/arm/plat-samsung/pm.c b/arch/arm/plat-samsung/pm.c index 27cfca597699..5bf3f2f09e74 100644 --- a/arch/arm/plat-samsung/pm.c +++ b/arch/arm/plat-samsung/pm.c @@ -355,7 +355,7 @@ static void s3c_pm_finish(void) s3c_pm_check_cleanup(); } -static struct platform_suspend_ops s3c_pm_ops = { +static const struct platform_suspend_ops s3c_pm_ops = { .enter = s3c_pm_enter, .prepare = s3c_pm_prepare, .finish = s3c_pm_finish, diff --git a/arch/avr32/mach-at32ap/pm.c b/arch/avr32/mach-at32ap/pm.c index f021edfeaab0..32d680eb6f48 100644 --- a/arch/avr32/mach-at32ap/pm.c +++ b/arch/avr32/mach-at32ap/pm.c @@ -176,7 +176,7 @@ out: return 0; } -static struct platform_suspend_ops avr32_pm_ops = { +static const struct platform_suspend_ops avr32_pm_ops = { .valid = avr32_pm_valid_state, .enter = avr32_pm_enter, }; diff --git a/arch/blackfin/mach-common/pm.c b/arch/blackfin/mach-common/pm.c index 80884b136a0c..745af2d96553 100644 --- a/arch/blackfin/mach-common/pm.c +++ b/arch/blackfin/mach-common/pm.c @@ -233,7 +233,7 @@ static int bfin_pm_enter(suspend_state_t state) return 0; } -struct platform_suspend_ops bfin_pm_ops = { +static const struct platform_suspend_ops bfin_pm_ops = { .enter = bfin_pm_enter, .valid = bfin_pm_valid, }; diff --git a/arch/mips/alchemy/devboards/pm.c b/arch/mips/alchemy/devboards/pm.c index 4bbd3133e451..acaf91b5e461 100644 --- a/arch/mips/alchemy/devboards/pm.c +++ b/arch/mips/alchemy/devboards/pm.c @@ -110,7 +110,7 @@ static void db1x_pm_end(void) } -static struct platform_suspend_ops db1x_pm_ops = { +static const struct platform_suspend_ops db1x_pm_ops = { .valid = suspend_valid_only_mem, .begin = db1x_pm_begin, .enter = db1x_pm_enter, diff --git a/arch/mips/jz4740/pm.c b/arch/mips/jz4740/pm.c index a9994585424d..902d5b50124c 100644 --- a/arch/mips/jz4740/pm.c +++ b/arch/mips/jz4740/pm.c @@ -42,7 +42,7 @@ static int jz4740_pm_enter(suspend_state_t state) return 0; } -static struct platform_suspend_ops jz4740_pm_ops = { +static const struct platform_suspend_ops jz4740_pm_ops = { .valid = suspend_valid_only_mem, .enter = jz4740_pm_enter, }; diff --git a/arch/mips/loongson/common/pm.c b/arch/mips/loongson/common/pm.c index 6c1fd9001712..f55e07aee071 100644 --- a/arch/mips/loongson/common/pm.c +++ b/arch/mips/loongson/common/pm.c @@ -147,7 +147,7 @@ static int loongson_pm_valid_state(suspend_state_t state) } } -static struct platform_suspend_ops loongson_pm_ops = { +static const struct platform_suspend_ops loongson_pm_ops = { .valid = loongson_pm_valid_state, .enter = loongson_pm_enter, }; diff --git a/arch/powerpc/platforms/52xx/lite5200_pm.c b/arch/powerpc/platforms/52xx/lite5200_pm.c index 80234e5921f5..eda0fc2a3914 100644 --- a/arch/powerpc/platforms/52xx/lite5200_pm.c +++ b/arch/powerpc/platforms/52xx/lite5200_pm.c @@ -232,7 +232,7 @@ static void lite5200_pm_end(void) lite5200_pm_target_state = PM_SUSPEND_ON; } -static struct platform_suspend_ops lite5200_pm_ops = { +static const struct platform_suspend_ops lite5200_pm_ops = { .valid = lite5200_pm_valid, .begin = lite5200_pm_begin, .prepare = lite5200_pm_prepare, diff --git a/arch/powerpc/platforms/52xx/mpc52xx_pm.c b/arch/powerpc/platforms/52xx/mpc52xx_pm.c index 568cef636275..8310e8b5b57f 100644 --- a/arch/powerpc/platforms/52xx/mpc52xx_pm.c +++ b/arch/powerpc/platforms/52xx/mpc52xx_pm.c @@ -186,7 +186,7 @@ void mpc52xx_pm_finish(void) iounmap(mbar); } -static struct platform_suspend_ops mpc52xx_pm_ops = { +static const struct platform_suspend_ops mpc52xx_pm_ops = { .valid = mpc52xx_pm_valid, .prepare = mpc52xx_pm_prepare, .enter = mpc52xx_pm_enter, diff --git a/arch/powerpc/platforms/83xx/suspend.c b/arch/powerpc/platforms/83xx/suspend.c index 75ae77f1af6a..fd4f2f2f19e6 100644 --- a/arch/powerpc/platforms/83xx/suspend.c +++ b/arch/powerpc/platforms/83xx/suspend.c @@ -311,7 +311,7 @@ static int mpc83xx_is_pci_agent(void) return ret; } -static struct platform_suspend_ops mpc83xx_suspend_ops = { +static const struct platform_suspend_ops mpc83xx_suspend_ops = { .valid = mpc83xx_suspend_valid, .begin = mpc83xx_suspend_begin, .enter = mpc83xx_suspend_enter, diff --git a/arch/powerpc/platforms/pseries/suspend.c b/arch/powerpc/platforms/pseries/suspend.c index ed72098bb4e3..a8ca289ff267 100644 --- a/arch/powerpc/platforms/pseries/suspend.c +++ b/arch/powerpc/platforms/pseries/suspend.c @@ -153,7 +153,7 @@ static struct sysdev_class suspend_sysdev_class = { .name = "power", }; -static struct platform_suspend_ops pseries_suspend_ops = { +static const struct platform_suspend_ops pseries_suspend_ops = { .valid = suspend_valid_only_mem, .begin = pseries_suspend_begin, .prepare_late = pseries_prepare_late, diff --git a/arch/powerpc/sysdev/fsl_pmc.c b/arch/powerpc/sysdev/fsl_pmc.c index 44de8559c975..e9381bfefb21 100644 --- a/arch/powerpc/sysdev/fsl_pmc.c +++ b/arch/powerpc/sysdev/fsl_pmc.c @@ -53,7 +53,7 @@ static int pmc_suspend_valid(suspend_state_t state) return 1; } -static struct platform_suspend_ops pmc_suspend_ops = { +static const struct platform_suspend_ops pmc_suspend_ops = { .valid = pmc_suspend_valid, .enter = pmc_suspend_enter, }; diff --git a/arch/sh/boards/mach-hp6xx/pm.c b/arch/sh/boards/mach-hp6xx/pm.c index 4499a3749d40..adc9b4bba828 100644 --- a/arch/sh/boards/mach-hp6xx/pm.c +++ b/arch/sh/boards/mach-hp6xx/pm.c @@ -143,7 +143,7 @@ static int hp6x0_pm_enter(suspend_state_t state) return 0; } -static struct platform_suspend_ops hp6x0_pm_ops = { +static const struct platform_suspend_ops hp6x0_pm_ops = { .enter = hp6x0_pm_enter, .valid = suspend_valid_only_mem, }; diff --git a/arch/sh/kernel/cpu/shmobile/pm.c b/arch/sh/kernel/cpu/shmobile/pm.c index e55968712706..a6f95ae4aae7 100644 --- a/arch/sh/kernel/cpu/shmobile/pm.c +++ b/arch/sh/kernel/cpu/shmobile/pm.c @@ -141,7 +141,7 @@ static int sh_pm_enter(suspend_state_t state) return 0; } -static struct platform_suspend_ops sh_pm_ops = { +static const struct platform_suspend_ops sh_pm_ops = { .enter = sh_pm_enter, .valid = suspend_valid_only_mem, }; diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index 5149c9bf7015..ba1caf724a16 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c @@ -319,7 +319,7 @@ static int acpi_suspend_state_valid(suspend_state_t pm_state) } } -static struct platform_suspend_ops acpi_suspend_ops = { +static const struct platform_suspend_ops acpi_suspend_ops = { .valid = acpi_suspend_state_valid, .begin = acpi_suspend_begin, .prepare_late = acpi_pm_prepare, @@ -347,7 +347,7 @@ static int acpi_suspend_begin_old(suspend_state_t pm_state) * The following callbacks are used if the pre-ACPI 2.0 suspend ordering has * been requested. */ -static struct platform_suspend_ops acpi_suspend_ops_old = { +static const struct platform_suspend_ops acpi_suspend_ops_old = { .valid = acpi_suspend_state_valid, .begin = acpi_suspend_begin_old, .prepare_late = acpi_pm_pre_suspend, diff --git a/drivers/macintosh/via-pmu.c b/drivers/macintosh/via-pmu.c index cd29c8248386..8b021eb0d48c 100644 --- a/drivers/macintosh/via-pmu.c +++ b/drivers/macintosh/via-pmu.c @@ -2257,7 +2257,7 @@ static int pmu_sleep_valid(suspend_state_t state) && (pmac_call_feature(PMAC_FTR_SLEEP_STATE, NULL, 0, -1) >= 0); } -static struct platform_suspend_ops pmu_pm_ops = { +static const struct platform_suspend_ops pmu_pm_ops = { .enter = powerbook_sleep, .valid = pmu_sleep_valid, }; diff --git a/include/linux/suspend.h b/include/linux/suspend.h index 40ead943fd6a..f45f3ccfdfa9 100644 --- a/include/linux/suspend.h +++ b/include/linux/suspend.h @@ -122,7 +122,7 @@ struct platform_suspend_ops { * suspend_set_ops - set platform dependent suspend operations * @ops: The new suspend operations to set. */ -extern void suspend_set_ops(struct platform_suspend_ops *ops); +extern void suspend_set_ops(const struct platform_suspend_ops *ops); extern int suspend_valid_only_mem(suspend_state_t state); /** @@ -147,7 +147,7 @@ extern int pm_suspend(suspend_state_t state); #else /* !CONFIG_SUSPEND */ #define suspend_valid_only_mem NULL -static inline void suspend_set_ops(struct platform_suspend_ops *ops) {} +static inline void suspend_set_ops(const struct platform_suspend_ops *ops) {} static inline int pm_suspend(suspend_state_t state) { return -ENOSYS; } #endif /* !CONFIG_SUSPEND */ diff --git a/kernel/power/suspend.c b/kernel/power/suspend.c index 7335952ee473..80051bdde6f1 100644 --- a/kernel/power/suspend.c +++ b/kernel/power/suspend.c @@ -30,13 +30,13 @@ const char *const pm_states[PM_SUSPEND_MAX] = { [PM_SUSPEND_MEM] = "mem", }; -static struct platform_suspend_ops *suspend_ops; +static const struct platform_suspend_ops *suspend_ops; /** * suspend_set_ops - Set the global suspend method table. * @ops: Pointer to ops structure. */ -void suspend_set_ops(struct platform_suspend_ops *ops) +void suspend_set_ops(const struct platform_suspend_ops *ops) { mutex_lock(&pm_mutex); suspend_ops = ops; -- cgit v1.2.3 From 3143a2bf18d12545f77dafa5b9f7fee83b001223 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 16 Nov 2010 15:55:10 +0000 Subject: drm/i915: Convert (void)I915_READ to POSTING_READ ... and so hide the flushes from tracing. Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_irq.c | 48 ++++++++++++++++++++--------------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 21034527d3a4..ef3503733ebb 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -70,7 +70,7 @@ ironlake_enable_graphics_irq(drm_i915_private_t *dev_priv, u32 mask) if ((dev_priv->gt_irq_mask_reg & mask) != 0) { dev_priv->gt_irq_mask_reg &= ~mask; I915_WRITE(GTIMR, dev_priv->gt_irq_mask_reg); - (void) I915_READ(GTIMR); + POSTING_READ(GTIMR); } } @@ -80,7 +80,7 @@ ironlake_disable_graphics_irq(drm_i915_private_t *dev_priv, u32 mask) if ((dev_priv->gt_irq_mask_reg & mask) != mask) { dev_priv->gt_irq_mask_reg |= mask; I915_WRITE(GTIMR, dev_priv->gt_irq_mask_reg); - (void) I915_READ(GTIMR); + POSTING_READ(GTIMR); } } @@ -91,7 +91,7 @@ ironlake_enable_display_irq(drm_i915_private_t *dev_priv, u32 mask) if ((dev_priv->irq_mask_reg & mask) != 0) { dev_priv->irq_mask_reg &= ~mask; I915_WRITE(DEIMR, dev_priv->irq_mask_reg); - (void) I915_READ(DEIMR); + POSTING_READ(DEIMR); } } @@ -101,7 +101,7 @@ ironlake_disable_display_irq(drm_i915_private_t *dev_priv, u32 mask) if ((dev_priv->irq_mask_reg & mask) != mask) { dev_priv->irq_mask_reg |= mask; I915_WRITE(DEIMR, dev_priv->irq_mask_reg); - (void) I915_READ(DEIMR); + POSTING_READ(DEIMR); } } @@ -111,7 +111,7 @@ i915_enable_irq(drm_i915_private_t *dev_priv, u32 mask) if ((dev_priv->irq_mask_reg & mask) != 0) { dev_priv->irq_mask_reg &= ~mask; I915_WRITE(IMR, dev_priv->irq_mask_reg); - (void) I915_READ(IMR); + POSTING_READ(IMR); } } @@ -121,7 +121,7 @@ i915_disable_irq(drm_i915_private_t *dev_priv, u32 mask) if ((dev_priv->irq_mask_reg & mask) != mask) { dev_priv->irq_mask_reg |= mask; I915_WRITE(IMR, dev_priv->irq_mask_reg); - (void) I915_READ(IMR); + POSTING_READ(IMR); } } @@ -144,7 +144,7 @@ i915_enable_pipestat(drm_i915_private_t *dev_priv, int pipe, u32 mask) dev_priv->pipestat[pipe] |= mask; /* Enable the interrupt, clear any pending status */ I915_WRITE(reg, dev_priv->pipestat[pipe] | (mask >> 16)); - (void) I915_READ(reg); + POSTING_READ(reg); } } @@ -156,7 +156,7 @@ i915_disable_pipestat(drm_i915_private_t *dev_priv, int pipe, u32 mask) dev_priv->pipestat[pipe] &= ~mask; I915_WRITE(reg, dev_priv->pipestat[pipe]); - (void) I915_READ(reg); + POSTING_READ(reg); } } @@ -321,7 +321,7 @@ static irqreturn_t ironlake_irq_handler(struct drm_device *dev) /* disable master interrupt before clearing iir */ de_ier = I915_READ(DEIER); I915_WRITE(DEIER, de_ier & ~DE_MASTER_IRQ_CONTROL); - (void)I915_READ(DEIER); + POSTING_READ(DEIER); de_iir = I915_READ(DEIIR); gt_iir = I915_READ(GTIIR); @@ -386,7 +386,7 @@ static irqreturn_t ironlake_irq_handler(struct drm_device *dev) done: I915_WRITE(DEIER, de_ier); - (void)I915_READ(DEIER); + POSTING_READ(DEIER); return ret; } @@ -796,7 +796,7 @@ static void i915_report_and_clear_eir(struct drm_device *dev) printk(KERN_ERR " ACTHD: 0x%08x\n", I915_READ(ACTHD_I965)); I915_WRITE(IPEIR_I965, ipeir); - (void)I915_READ(IPEIR_I965); + POSTING_READ(IPEIR_I965); } if (eir & GM45_ERROR_PAGE_TABLE) { u32 pgtbl_err = I915_READ(PGTBL_ER); @@ -804,7 +804,7 @@ static void i915_report_and_clear_eir(struct drm_device *dev) printk(KERN_ERR " PGTBL_ER: 0x%08x\n", pgtbl_err); I915_WRITE(PGTBL_ER, pgtbl_err); - (void)I915_READ(PGTBL_ER); + POSTING_READ(PGTBL_ER); } } @@ -815,7 +815,7 @@ static void i915_report_and_clear_eir(struct drm_device *dev) printk(KERN_ERR " PGTBL_ER: 0x%08x\n", pgtbl_err); I915_WRITE(PGTBL_ER, pgtbl_err); - (void)I915_READ(PGTBL_ER); + POSTING_READ(PGTBL_ER); } } @@ -846,7 +846,7 @@ static void i915_report_and_clear_eir(struct drm_device *dev) printk(KERN_ERR " ACTHD: 0x%08x\n", I915_READ(ACTHD)); I915_WRITE(IPEIR, ipeir); - (void)I915_READ(IPEIR); + POSTING_READ(IPEIR); } else { u32 ipeir = I915_READ(IPEIR_I965); @@ -863,12 +863,12 @@ static void i915_report_and_clear_eir(struct drm_device *dev) printk(KERN_ERR " ACTHD: 0x%08x\n", I915_READ(ACTHD_I965)); I915_WRITE(IPEIR_I965, ipeir); - (void)I915_READ(IPEIR_I965); + POSTING_READ(IPEIR_I965); } } I915_WRITE(EIR, eir); - (void)I915_READ(EIR); + POSTING_READ(EIR); eir = I915_READ(EIR); if (eir) { /* @@ -1435,17 +1435,17 @@ static void ironlake_irq_preinstall(struct drm_device *dev) I915_WRITE(DEIMR, 0xffffffff); I915_WRITE(DEIER, 0x0); - (void) I915_READ(DEIER); + POSTING_READ(DEIER); /* and GT */ I915_WRITE(GTIMR, 0xffffffff); I915_WRITE(GTIER, 0x0); - (void) I915_READ(GTIER); + POSTING_READ(GTIER); /* south display irq */ I915_WRITE(SDEIMR, 0xffffffff); I915_WRITE(SDEIER, 0x0); - (void) I915_READ(SDEIER); + POSTING_READ(SDEIER); } static int ironlake_irq_postinstall(struct drm_device *dev) @@ -1464,7 +1464,7 @@ static int ironlake_irq_postinstall(struct drm_device *dev) I915_WRITE(DEIIR, I915_READ(DEIIR)); I915_WRITE(DEIMR, dev_priv->irq_mask_reg); I915_WRITE(DEIER, dev_priv->de_irq_enable_reg); - (void) I915_READ(DEIER); + POSTING_READ(DEIER); if (IS_GEN6(dev)) { render_mask = @@ -1485,7 +1485,7 @@ static int ironlake_irq_postinstall(struct drm_device *dev) } I915_WRITE(GTIER, dev_priv->gt_irq_enable_reg); - (void) I915_READ(GTIER); + POSTING_READ(GTIER); if (HAS_PCH_CPT(dev)) { hotplug_mask = SDE_CRT_HOTPLUG_CPT | SDE_PORTB_HOTPLUG_CPT | @@ -1501,7 +1501,7 @@ static int ironlake_irq_postinstall(struct drm_device *dev) I915_WRITE(SDEIIR, I915_READ(SDEIIR)); I915_WRITE(SDEIMR, dev_priv->pch_irq_mask_reg); I915_WRITE(SDEIER, dev_priv->pch_irq_enable_reg); - (void) I915_READ(SDEIER); + POSTING_READ(SDEIER); if (IS_IRONLAKE_M(dev)) { /* Clear & enable PCU event interrupts */ @@ -1537,7 +1537,7 @@ void i915_driver_irq_preinstall(struct drm_device * dev) I915_WRITE(PIPEBSTAT, 0); I915_WRITE(IMR, 0xffffffff); I915_WRITE(IER, 0x0); - (void) I915_READ(IER); + POSTING_READ(IER); } /* @@ -1591,7 +1591,7 @@ int i915_driver_irq_postinstall(struct drm_device *dev) I915_WRITE(IMR, dev_priv->irq_mask_reg); I915_WRITE(IER, enable_mask); - (void) I915_READ(IER); + POSTING_READ(IER); if (I915_HAS_HOTPLUG(dev)) { u32 hotplug_en = I915_READ(PORT_HOTPLUG_EN); -- cgit v1.2.3 From e72115bce326dc893bc1db96db72059a6a08148c Mon Sep 17 00:00:00 2001 From: Marek Belisko Date: Fri, 12 Nov 2010 10:27:44 +0100 Subject: staging: ft1000: Fix error goto statements. With commit 2dab1ac81b4767095f96503a9ac093a68c6e9c95 there was intruduced error which lead to stopping uninitialized kthread which leads to kernel panics. This patch fix problems with common entry point in correct way. Signed-off-by: Marek Belisko Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ft1000/ft1000-usb/ft1000_usb.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_usb.c b/drivers/staging/ft1000/ft1000-usb/ft1000_usb.c index 99e333902376..6925622795a5 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_usb.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_usb.c @@ -178,7 +178,7 @@ static int ft1000_probe(struct usb_interface *interface, if (IS_ERR(pft1000info->pPollThread)) { ret = PTR_ERR(pft1000info->pPollThread); - goto err_thread; + goto err_load; } msleep(500); @@ -186,7 +186,7 @@ static int ft1000_probe(struct usb_interface *interface, while (!pft1000info->CardReady) { if (gPollingfailed) { ret = -EIO; - goto err_load; + goto err_thread; } msleep(100); DEBUG("ft1000_probe::Waiting for Card Ready\n"); @@ -196,7 +196,7 @@ static int ft1000_probe(struct usb_interface *interface, ret = reg_ft1000_netdev(ft1000dev, interface); if (ret) - goto err_load; + goto err_thread; pft1000info->NetDevRegDone = 1; -- cgit v1.2.3 From 7f55f13c2ca82f6d998502df70f24deb550e5e0c Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Thu, 11 Nov 2010 11:29:25 -0500 Subject: staging: ft1000: Copy from user into correct data While doing a ktest.pl I used a MIN_CONFIG that had STAGING enabled, and a randconfig with CONFIG_DEBUG_STRICT_USER_COPY_CHECKS enabled caught the following bug: In file included from /home/rostedt/work/autotest/nobackup/linux-test.git/arch/x86/include/asm/uaccess.h:571:0, from /home/rostedt/work/autotest/nobackup/linux-test.git/include/linux/poll.h:14, from /home/rostedt/work/autotest/nobackup/linux-test.git/drivers/staging/ft1000/ft1000-usb/ft1000_chdev.c:32: In function 'copy_from_user', inlined from 'ft1000_ChIoctl' at /home/rostedt/work/autotest/nobackup/linux-test.git/drivers/staging/ft1000/ft1000-usb/ft1000_chdev.c:702:36: /home/rostedt/work/autotest/nobackup/linux-test.git/arch/x86/include/asm/uaccess_32.h:212:26: error: call to 'copy_from_user_overflow' declared with attribute error: copy_from_user() buffer size is not provably correct Looking at the code it was obvious what the problem was. The pointer dpram_data was being allocated but the address was being written to. Looking at the comment above the code shows that it use to write into an element of that pointer where the '&' is appropriate. But now that it writes to the pointer itself, we need to remove the '&' otherwise we write over the pointer and not into the data it points to. Signed-off-by: Steven Rostedt Cc: Marek Belisko Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ft1000/ft1000-usb/ft1000_chdev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_chdev.c b/drivers/staging/ft1000/ft1000-usb/ft1000_chdev.c index 197b3fb9462e..18c4c15c5aea 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_chdev.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_chdev.c @@ -698,7 +698,7 @@ static long ft1000_ChIoctl (struct file *File, unsigned int Command, break; //if ( copy_from_user(&(dpram_command.dpram_blk), (PIOCTL_DPRAM_BLK)Argument, msgsz+2) ) { - if ( copy_from_user(&dpram_data, argp, msgsz+2) ) { + if ( copy_from_user(dpram_data, argp, msgsz+2) ) { DEBUG("FT1000:ft1000_ChIoctl: copy fault occurred\n"); result = -EFAULT; } -- cgit v1.2.3 From 886953e9b70bcb6913716b49bdf21b69450a7cd6 Mon Sep 17 00:00:00 2001 From: "Emilio G. Cota" Date: Fri, 12 Nov 2010 11:14:07 +0000 Subject: staging: vme: style: convert '&(foo)' to '&foo' done with find . -name '*.c' | xargs perl -p -i -e 's/&\(([^()]+)\)/&$1/g' Signed-off-by: Emilio G. Cota Acked-by: Martyn Welch Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vme/bridges/vme_ca91cx42.c | 181 ++++++++++++------------- drivers/staging/vme/bridges/vme_tsi148.c | 204 ++++++++++++++--------------- drivers/staging/vme/devices/vme_user.c | 16 +-- drivers/staging/vme/vme.c | 114 ++++++++-------- 4 files changed, 258 insertions(+), 257 deletions(-) diff --git a/drivers/staging/vme/bridges/vme_ca91cx42.c b/drivers/staging/vme/bridges/vme_ca91cx42.c index 4d745623211b..1f2089ff7f9f 100644 --- a/drivers/staging/vme/bridges/vme_ca91cx42.c +++ b/drivers/staging/vme/bridges/vme_ca91cx42.c @@ -58,7 +58,7 @@ static struct pci_driver ca91cx42_driver = { static u32 ca91cx42_DMA_irqhandler(struct ca91cx42_driver *bridge) { - wake_up(&(bridge->dma_queue)); + wake_up(&bridge->dma_queue); return CA91CX42_LINT_DMA; } @@ -82,14 +82,14 @@ static u32 ca91cx42_LM_irqhandler(struct ca91cx42_driver *bridge, u32 stat) /* XXX This needs to be split into 4 queues */ static u32 ca91cx42_MB_irqhandler(struct ca91cx42_driver *bridge, int mbox_mask) { - wake_up(&(bridge->mbox_queue)); + wake_up(&bridge->mbox_queue); return CA91CX42_LINT_MBOX; } static u32 ca91cx42_IACK_irqhandler(struct ca91cx42_driver *bridge) { - wake_up(&(bridge->iack_queue)); + wake_up(&bridge->iack_queue); return CA91CX42_LINT_SW_IACK; } @@ -207,9 +207,9 @@ static int ca91cx42_irq_init(struct vme_bridge *ca91cx42_bridge) pdev = container_of(ca91cx42_bridge->parent, struct pci_dev, dev); /* Initialise list for VME bus errors */ - INIT_LIST_HEAD(&(ca91cx42_bridge->vme_errors)); + INIT_LIST_HEAD(&ca91cx42_bridge->vme_errors); - mutex_init(&(ca91cx42_bridge->irq_mtx)); + mutex_init(&ca91cx42_bridge->irq_mtx); /* Disable interrupts from PCI to VME */ iowrite32(0, bridge->base + VINT_EN); @@ -299,7 +299,7 @@ int ca91cx42_irq_generate(struct vme_bridge *ca91cx42_bridge, int level, if (statid & 1) return -EINVAL; - mutex_lock(&(bridge->vme_int)); + mutex_lock(&bridge->vme_int); tmp = ioread32(bridge->base + VINT_EN); @@ -318,7 +318,7 @@ int ca91cx42_irq_generate(struct vme_bridge *ca91cx42_bridge, int level, tmp = tmp & ~(1 << (level + 24)); iowrite32(tmp, bridge->base + VINT_EN); - mutex_unlock(&(bridge->vme_int)); + mutex_unlock(&bridge->vme_int); return 0; } @@ -518,8 +518,8 @@ static int ca91cx42_alloc_resource(struct vme_master_resource *image, image->kern_base = NULL; if (image->bus_resource.name != NULL) kfree(image->bus_resource.name); - release_resource(&(image->bus_resource)); - memset(&(image->bus_resource), 0, sizeof(struct resource)); + release_resource(&image->bus_resource); + memset(&image->bus_resource, 0, sizeof(struct resource)); } if (image->bus_resource.name == NULL) { @@ -540,7 +540,7 @@ static int ca91cx42_alloc_resource(struct vme_master_resource *image, image->bus_resource.flags = IORESOURCE_MEM; retval = pci_bus_alloc_resource(pdev->bus, - &(image->bus_resource), size, size, PCIBIOS_MIN_MEM, + &image->bus_resource, size, size, PCIBIOS_MIN_MEM, 0, NULL, NULL); if (retval) { dev_err(ca91cx42_bridge->parent, "Failed to allocate mem " @@ -563,10 +563,10 @@ static int ca91cx42_alloc_resource(struct vme_master_resource *image, iounmap(image->kern_base); image->kern_base = NULL; err_remap: - release_resource(&(image->bus_resource)); + release_resource(&image->bus_resource); err_resource: kfree(image->bus_resource.name); - memset(&(image->bus_resource), 0, sizeof(struct resource)); + memset(&image->bus_resource, 0, sizeof(struct resource)); err_name: return retval; } @@ -578,9 +578,9 @@ static void ca91cx42_free_resource(struct vme_master_resource *image) { iounmap(image->kern_base); image->kern_base = NULL; - release_resource(&(image->bus_resource)); + release_resource(&image->bus_resource); kfree(image->bus_resource.name); - memset(&(image->bus_resource), 0, sizeof(struct resource)); + memset(&image->bus_resource, 0, sizeof(struct resource)); } @@ -620,7 +620,7 @@ int ca91cx42_master_set(struct vme_master_resource *image, int enabled, goto err_window; } - spin_lock(&(image->lock)); + spin_lock(&image->lock); /* * Let's allocate the resource here rather than further up the stack as @@ -628,7 +628,7 @@ int ca91cx42_master_set(struct vme_master_resource *image, int enabled, */ retval = ca91cx42_alloc_resource(image, size); if (retval) { - spin_unlock(&(image->lock)); + spin_unlock(&image->lock); dev_err(ca91cx42_bridge->parent, "Unable to allocate memory " "for resource name\n"); retval = -ENOMEM; @@ -672,7 +672,7 @@ int ca91cx42_master_set(struct vme_master_resource *image, int enabled, temp_ctl |= CA91CX42_LSI_CTL_VDW_D64; break; default: - spin_unlock(&(image->lock)); + spin_unlock(&image->lock); dev_err(ca91cx42_bridge->parent, "Invalid data width\n"); retval = -EINVAL; goto err_dwidth; @@ -704,7 +704,7 @@ int ca91cx42_master_set(struct vme_master_resource *image, int enabled, case VME_USER3: case VME_USER4: default: - spin_unlock(&(image->lock)); + spin_unlock(&image->lock); dev_err(ca91cx42_bridge->parent, "Invalid address space\n"); retval = -EINVAL; goto err_aspace; @@ -730,7 +730,7 @@ int ca91cx42_master_set(struct vme_master_resource *image, int enabled, iowrite32(temp_ctl, bridge->base + CA91CX42_LSI_CTL[i]); - spin_unlock(&(image->lock)); + spin_unlock(&image->lock); return 0; err_aspace: @@ -834,12 +834,12 @@ int ca91cx42_master_get(struct vme_master_resource *image, int *enabled, { int retval; - spin_lock(&(image->lock)); + spin_lock(&image->lock); retval = __ca91cx42_master_get(image, enabled, vme_base, size, aspace, cycle, dwidth); - spin_unlock(&(image->lock)); + spin_unlock(&image->lock); return retval; } @@ -855,7 +855,7 @@ ssize_t ca91cx42_master_read(struct vme_master_resource *image, void *buf, if (count == 0) return 0; - spin_lock(&(image->lock)); + spin_lock(&image->lock); /* The following code handles VME address alignment problem * in order to assure the maximal data width cycle. @@ -899,7 +899,7 @@ ssize_t ca91cx42_master_read(struct vme_master_resource *image, void *buf, } out: retval = count; - spin_unlock(&(image->lock)); + spin_unlock(&image->lock); return retval; } @@ -915,7 +915,7 @@ ssize_t ca91cx42_master_write(struct vme_master_resource *image, void *buf, if (count == 0) return 0; - spin_lock(&(image->lock)); + spin_lock(&image->lock); /* Here we apply for the same strategy we do in master_read * function in order to assure D16 cycle when required. @@ -954,7 +954,8 @@ ssize_t ca91cx42_master_write(struct vme_master_resource *image, void *buf, out: retval = count; - spin_unlock(&(image->lock)); + spin_unlock(&image->lock); + return retval; } @@ -974,10 +975,10 @@ unsigned int ca91cx42_master_rmw(struct vme_master_resource *image, i = image->number; /* Locking as we can only do one of these at a time */ - mutex_lock(&(bridge->vme_rmw)); + mutex_lock(&bridge->vme_rmw); /* Lock image */ - spin_lock(&(image->lock)); + spin_lock(&image->lock); pci_addr = (u32)image->kern_base + offset; @@ -1007,9 +1008,9 @@ unsigned int ca91cx42_master_rmw(struct vme_master_resource *image, iowrite32(0, bridge->base + SCYC_CTL); out: - spin_unlock(&(image->lock)); + spin_unlock(&image->lock); - mutex_unlock(&(bridge->vme_rmw)); + mutex_unlock(&bridge->vme_rmw); return result; } @@ -1036,14 +1037,14 @@ int ca91cx42_dma_list_add(struct vme_dma_list *list, struct vme_dma_attr *src, } /* Test descriptor alignment */ - if ((unsigned long)&(entry->descriptor) & CA91CX42_DCPP_M) { + if ((unsigned long)&entry->descriptor & CA91CX42_DCPP_M) { dev_err(dev, "Descriptor not aligned to 16 byte boundary as " - "required: %p\n", &(entry->descriptor)); + "required: %p\n", &entry->descriptor); retval = -EINVAL; goto err_align; } - memset(&(entry->descriptor), 0, sizeof(struct ca91cx42_dma_descriptor)); + memset(&entry->descriptor, 0, sizeof(struct ca91cx42_dma_descriptor)); if (dest->type == VME_DMA_VME) { entry->descriptor.dctl |= CA91CX42_DCTL_L2V; @@ -1138,14 +1139,14 @@ int ca91cx42_dma_list_add(struct vme_dma_list *list, struct vme_dma_attr *src, entry->descriptor.dcpp = CA91CX42_DCPP_NULL; /* Add to list */ - list_add_tail(&(entry->list), &(list->entries)); + list_add_tail(&entry->list, &list->entries); /* Fill out previous descriptors "Next Address" */ - if (entry->list.prev != &(list->entries)) { + if (entry->list.prev != &list->entries) { prev = list_entry(entry->list.prev, struct ca91cx42_dma_entry, list); /* We need the bus address for the pointer */ - desc_ptr = virt_to_bus(&(entry->descriptor)); + desc_ptr = virt_to_bus(&entry->descriptor); prev->descriptor.dcpp = desc_ptr & ~CA91CX42_DCPP_M; } @@ -1190,28 +1191,28 @@ int ca91cx42_dma_list_exec(struct vme_dma_list *list) bridge = ctrlr->parent->driver_priv; dev = ctrlr->parent->parent; - mutex_lock(&(ctrlr->mtx)); + mutex_lock(&ctrlr->mtx); - if (!(list_empty(&(ctrlr->running)))) { + if (!(list_empty(&ctrlr->running))) { /* * XXX We have an active DMA transfer and currently haven't * sorted out the mechanism for "pending" DMA transfers. * Return busy. */ /* Need to add to pending here */ - mutex_unlock(&(ctrlr->mtx)); + mutex_unlock(&ctrlr->mtx); return -EBUSY; } else { - list_add(&(list->list), &(ctrlr->running)); + list_add(&list->list, &ctrlr->running); } /* Get first bus address and write into registers */ - entry = list_first_entry(&(list->entries), struct ca91cx42_dma_entry, + entry = list_first_entry(&list->entries, struct ca91cx42_dma_entry, list); - bus_addr = virt_to_bus(&(entry->descriptor)); + bus_addr = virt_to_bus(&entry->descriptor); - mutex_unlock(&(ctrlr->mtx)); + mutex_unlock(&ctrlr->mtx); iowrite32(0, bridge->base + DTBC); iowrite32(bus_addr & ~CA91CX42_DCPP_M, bridge->base + DCPP); @@ -1249,9 +1250,9 @@ int ca91cx42_dma_list_exec(struct vme_dma_list *list) } /* Remove list from running list */ - mutex_lock(&(ctrlr->mtx)); - list_del(&(list->list)); - mutex_unlock(&(ctrlr->mtx)); + mutex_lock(&ctrlr->mtx); + list_del(&list->list); + mutex_unlock(&ctrlr->mtx); return retval; @@ -1263,7 +1264,7 @@ int ca91cx42_dma_list_empty(struct vme_dma_list *list) struct ca91cx42_dma_entry *entry; /* detach and free each entry */ - list_for_each_safe(pos, temp, &(list->entries)) { + list_for_each_safe(pos, temp, &list->entries) { list_del(pos); entry = list_entry(pos, struct ca91cx42_dma_entry, list); kfree(entry); @@ -1298,12 +1299,12 @@ int ca91cx42_lm_set(struct vme_lm_resource *lm, unsigned long long lm_base, return -EINVAL; } - mutex_lock(&(lm->mtx)); + mutex_lock(&lm->mtx); /* If we already have a callback attached, we can't move it! */ for (i = 0; i < lm->monitors; i++) { if (bridge->lm_callback[i] != NULL) { - mutex_unlock(&(lm->mtx)); + mutex_unlock(&lm->mtx); dev_err(dev, "Location monitor callback attached, " "can't reset\n"); return -EBUSY; @@ -1321,7 +1322,7 @@ int ca91cx42_lm_set(struct vme_lm_resource *lm, unsigned long long lm_base, lm_ctl |= CA91CX42_LM_CTL_AS_A32; break; default: - mutex_unlock(&(lm->mtx)); + mutex_unlock(&lm->mtx); dev_err(dev, "Invalid address space\n"); return -EINVAL; break; @@ -1339,7 +1340,7 @@ int ca91cx42_lm_set(struct vme_lm_resource *lm, unsigned long long lm_base, iowrite32(lm_base, bridge->base + LM_BS); iowrite32(lm_ctl, bridge->base + LM_CTL); - mutex_unlock(&(lm->mtx)); + mutex_unlock(&lm->mtx); return 0; } @@ -1355,7 +1356,7 @@ int ca91cx42_lm_get(struct vme_lm_resource *lm, unsigned long long *lm_base, bridge = lm->parent->driver_priv; - mutex_lock(&(lm->mtx)); + mutex_lock(&lm->mtx); *lm_base = (unsigned long long)ioread32(bridge->base + LM_BS); lm_ctl = ioread32(bridge->base + LM_CTL); @@ -1380,7 +1381,7 @@ int ca91cx42_lm_get(struct vme_lm_resource *lm, unsigned long long *lm_base, if (lm_ctl & CA91CX42_LM_CTL_DATA) *cycle |= VME_DATA; - mutex_unlock(&(lm->mtx)); + mutex_unlock(&lm->mtx); return enabled; } @@ -1400,19 +1401,19 @@ int ca91cx42_lm_attach(struct vme_lm_resource *lm, int monitor, bridge = lm->parent->driver_priv; dev = lm->parent->parent; - mutex_lock(&(lm->mtx)); + mutex_lock(&lm->mtx); /* Ensure that the location monitor is configured - need PGM or DATA */ lm_ctl = ioread32(bridge->base + LM_CTL); if ((lm_ctl & (CA91CX42_LM_CTL_PGM | CA91CX42_LM_CTL_DATA)) == 0) { - mutex_unlock(&(lm->mtx)); + mutex_unlock(&lm->mtx); dev_err(dev, "Location monitor not properly configured\n"); return -EINVAL; } /* Check that a callback isn't already attached */ if (bridge->lm_callback[monitor] != NULL) { - mutex_unlock(&(lm->mtx)); + mutex_unlock(&lm->mtx); dev_err(dev, "Existing callback attached\n"); return -EBUSY; } @@ -1431,7 +1432,7 @@ int ca91cx42_lm_attach(struct vme_lm_resource *lm, int monitor, iowrite32(lm_ctl, bridge->base + LM_CTL); } - mutex_unlock(&(lm->mtx)); + mutex_unlock(&lm->mtx); return 0; } @@ -1446,7 +1447,7 @@ int ca91cx42_lm_detach(struct vme_lm_resource *lm, int monitor) bridge = lm->parent->driver_priv; - mutex_lock(&(lm->mtx)); + mutex_lock(&lm->mtx); /* Disable Location Monitor and ensure previous interrupts are clear */ tmp = ioread32(bridge->base + LINT_EN); @@ -1467,7 +1468,7 @@ int ca91cx42_lm_detach(struct vme_lm_resource *lm, int monitor) iowrite32(tmp, bridge->base + LM_CTL); } - mutex_unlock(&(lm->mtx)); + mutex_unlock(&lm->mtx); return 0; } @@ -1526,7 +1527,7 @@ static int ca91cx42_crcsr_init(struct vme_bridge *ca91cx42_bridge, /* Allocate mem for CR/CSR image */ bridge->crcsr_kernel = pci_alloc_consistent(pdev, VME_CRCSR_BUF_SIZE, - &(bridge->crcsr_bus)); + &bridge->crcsr_bus); if (bridge->crcsr_kernel == NULL) { dev_err(&pdev->dev, "Failed to allocate memory for CR/CSR " "image\n"); @@ -1632,12 +1633,12 @@ static int ca91cx42_probe(struct pci_dev *pdev, const struct pci_device_id *id) } /* Initialize wait queues & mutual exclusion flags */ - init_waitqueue_head(&(ca91cx42_device->dma_queue)); - init_waitqueue_head(&(ca91cx42_device->iack_queue)); - mutex_init(&(ca91cx42_device->vme_int)); - mutex_init(&(ca91cx42_device->vme_rmw)); + init_waitqueue_head(&ca91cx42_device->dma_queue); + init_waitqueue_head(&ca91cx42_device->iack_queue); + mutex_init(&ca91cx42_device->vme_int); + mutex_init(&ca91cx42_device->vme_rmw); - ca91cx42_bridge->parent = &(pdev->dev); + ca91cx42_bridge->parent = &pdev->dev; strcpy(ca91cx42_bridge->name, driver_name); /* Setup IRQ */ @@ -1648,7 +1649,7 @@ static int ca91cx42_probe(struct pci_dev *pdev, const struct pci_device_id *id) } /* Add master windows to list */ - INIT_LIST_HEAD(&(ca91cx42_bridge->master_resources)); + INIT_LIST_HEAD(&ca91cx42_bridge->master_resources); for (i = 0; i < CA91C142_MAX_MASTER; i++) { master_image = kmalloc(sizeof(struct vme_master_resource), GFP_KERNEL); @@ -1659,7 +1660,7 @@ static int ca91cx42_probe(struct pci_dev *pdev, const struct pci_device_id *id) goto err_master; } master_image->parent = ca91cx42_bridge; - spin_lock_init(&(master_image->lock)); + spin_lock_init(&master_image->lock); master_image->locked = 0; master_image->number = i; master_image->address_attr = VME_A16 | VME_A24 | VME_A32 | @@ -1667,15 +1668,15 @@ static int ca91cx42_probe(struct pci_dev *pdev, const struct pci_device_id *id) master_image->cycle_attr = VME_SCT | VME_BLT | VME_MBLT | VME_SUPER | VME_USER | VME_PROG | VME_DATA; master_image->width_attr = VME_D8 | VME_D16 | VME_D32 | VME_D64; - memset(&(master_image->bus_resource), 0, + memset(&master_image->bus_resource, 0, sizeof(struct resource)); master_image->kern_base = NULL; - list_add_tail(&(master_image->list), - &(ca91cx42_bridge->master_resources)); + list_add_tail(&master_image->list, + &ca91cx42_bridge->master_resources); } /* Add slave windows to list */ - INIT_LIST_HEAD(&(ca91cx42_bridge->slave_resources)); + INIT_LIST_HEAD(&ca91cx42_bridge->slave_resources); for (i = 0; i < CA91C142_MAX_SLAVE; i++) { slave_image = kmalloc(sizeof(struct vme_slave_resource), GFP_KERNEL); @@ -1686,7 +1687,7 @@ static int ca91cx42_probe(struct pci_dev *pdev, const struct pci_device_id *id) goto err_slave; } slave_image->parent = ca91cx42_bridge; - mutex_init(&(slave_image->mtx)); + mutex_init(&slave_image->mtx); slave_image->locked = 0; slave_image->number = i; slave_image->address_attr = VME_A24 | VME_A32 | VME_USER1 | @@ -1698,12 +1699,12 @@ static int ca91cx42_probe(struct pci_dev *pdev, const struct pci_device_id *id) slave_image->cycle_attr = VME_SCT | VME_BLT | VME_MBLT | VME_SUPER | VME_USER | VME_PROG | VME_DATA; - list_add_tail(&(slave_image->list), - &(ca91cx42_bridge->slave_resources)); + list_add_tail(&slave_image->list, + &ca91cx42_bridge->slave_resources); } /* Add dma engines to list */ - INIT_LIST_HEAD(&(ca91cx42_bridge->dma_resources)); + INIT_LIST_HEAD(&ca91cx42_bridge->dma_resources); for (i = 0; i < CA91C142_MAX_DMA; i++) { dma_ctrlr = kmalloc(sizeof(struct vme_dma_resource), GFP_KERNEL); @@ -1714,19 +1715,19 @@ static int ca91cx42_probe(struct pci_dev *pdev, const struct pci_device_id *id) goto err_dma; } dma_ctrlr->parent = ca91cx42_bridge; - mutex_init(&(dma_ctrlr->mtx)); + mutex_init(&dma_ctrlr->mtx); dma_ctrlr->locked = 0; dma_ctrlr->number = i; dma_ctrlr->route_attr = VME_DMA_VME_TO_MEM | VME_DMA_MEM_TO_VME; - INIT_LIST_HEAD(&(dma_ctrlr->pending)); - INIT_LIST_HEAD(&(dma_ctrlr->running)); - list_add_tail(&(dma_ctrlr->list), - &(ca91cx42_bridge->dma_resources)); + INIT_LIST_HEAD(&dma_ctrlr->pending); + INIT_LIST_HEAD(&dma_ctrlr->running); + list_add_tail(&dma_ctrlr->list, + &ca91cx42_bridge->dma_resources); } /* Add location monitor to list */ - INIT_LIST_HEAD(&(ca91cx42_bridge->lm_resources)); + INIT_LIST_HEAD(&ca91cx42_bridge->lm_resources); lm = kmalloc(sizeof(struct vme_lm_resource), GFP_KERNEL); if (lm == NULL) { dev_err(&pdev->dev, "Failed to allocate memory for " @@ -1735,11 +1736,11 @@ static int ca91cx42_probe(struct pci_dev *pdev, const struct pci_device_id *id) goto err_lm; } lm->parent = ca91cx42_bridge; - mutex_init(&(lm->mtx)); + mutex_init(&lm->mtx); lm->locked = 0; lm->number = 1; lm->monitors = 4; - list_add_tail(&(lm->list), &(ca91cx42_bridge->lm_resources)); + list_add_tail(&lm->list, &ca91cx42_bridge->lm_resources); ca91cx42_bridge->slave_get = ca91cx42_slave_get; ca91cx42_bridge->slave_set = ca91cx42_slave_set; @@ -1786,28 +1787,28 @@ err_reg: ca91cx42_crcsr_exit(ca91cx42_bridge, pdev); err_lm: /* resources are stored in link list */ - list_for_each(pos, &(ca91cx42_bridge->lm_resources)) { + list_for_each(pos, &ca91cx42_bridge->lm_resources) { lm = list_entry(pos, struct vme_lm_resource, list); list_del(pos); kfree(lm); } err_dma: /* resources are stored in link list */ - list_for_each(pos, &(ca91cx42_bridge->dma_resources)) { + list_for_each(pos, &ca91cx42_bridge->dma_resources) { dma_ctrlr = list_entry(pos, struct vme_dma_resource, list); list_del(pos); kfree(dma_ctrlr); } err_slave: /* resources are stored in link list */ - list_for_each(pos, &(ca91cx42_bridge->slave_resources)) { + list_for_each(pos, &ca91cx42_bridge->slave_resources) { slave_image = list_entry(pos, struct vme_slave_resource, list); list_del(pos); kfree(slave_image); } err_master: /* resources are stored in link list */ - list_for_each(pos, &(ca91cx42_bridge->master_resources)) { + list_for_each(pos, &ca91cx42_bridge->master_resources) { master_image = list_entry(pos, struct vme_master_resource, list); list_del(pos); @@ -1870,28 +1871,28 @@ void ca91cx42_remove(struct pci_dev *pdev) ca91cx42_crcsr_exit(ca91cx42_bridge, pdev); /* resources are stored in link list */ - list_for_each(pos, &(ca91cx42_bridge->lm_resources)) { + list_for_each(pos, &ca91cx42_bridge->lm_resources) { lm = list_entry(pos, struct vme_lm_resource, list); list_del(pos); kfree(lm); } /* resources are stored in link list */ - list_for_each(pos, &(ca91cx42_bridge->dma_resources)) { + list_for_each(pos, &ca91cx42_bridge->dma_resources) { dma_ctrlr = list_entry(pos, struct vme_dma_resource, list); list_del(pos); kfree(dma_ctrlr); } /* resources are stored in link list */ - list_for_each(pos, &(ca91cx42_bridge->slave_resources)) { + list_for_each(pos, &ca91cx42_bridge->slave_resources) { slave_image = list_entry(pos, struct vme_slave_resource, list); list_del(pos); kfree(slave_image); } /* resources are stored in link list */ - list_for_each(pos, &(ca91cx42_bridge->master_resources)) { + list_for_each(pos, &ca91cx42_bridge->master_resources) { master_image = list_entry(pos, struct vme_master_resource, list); list_del(pos); diff --git a/drivers/staging/vme/bridges/vme_tsi148.c b/drivers/staging/vme/bridges/vme_tsi148.c index 492ddb2d5108..1cba1fa16079 100644 --- a/drivers/staging/vme/bridges/vme_tsi148.c +++ b/drivers/staging/vme/bridges/vme_tsi148.c @@ -81,11 +81,11 @@ static u32 tsi148_DMA_irqhandler(struct tsi148_driver *bridge, u32 serviced = 0; if (channel_mask & TSI148_LCSR_INTS_DMA0S) { - wake_up(&(bridge->dma_queue[0])); + wake_up(&bridge->dma_queue[0]); serviced |= TSI148_LCSR_INTC_DMA0C; } if (channel_mask & TSI148_LCSR_INTS_DMA1S) { - wake_up(&(bridge->dma_queue[1])); + wake_up(&bridge->dma_queue[1]); serviced |= TSI148_LCSR_INTC_DMA1C; } @@ -191,7 +191,7 @@ static u32 tsi148_VERR_irqhandler(struct vme_bridge *tsi148_bridge) if (error) { error->address = error_addr; error->attributes = error_attrib; - list_add_tail(&(error->list), &(tsi148_bridge->vme_errors)); + list_add_tail(&error->list, &tsi148_bridge->vme_errors); } else { dev_err(tsi148_bridge->parent, "Unable to alloc memory for " "VMEbus Error reporting\n"); @@ -210,7 +210,7 @@ static u32 tsi148_VERR_irqhandler(struct vme_bridge *tsi148_bridge) */ static u32 tsi148_IACK_irqhandler(struct tsi148_driver *bridge) { - wake_up(&(bridge->iack_queue)); + wake_up(&bridge->iack_queue); return TSI148_LCSR_INTC_IACKC; } @@ -320,9 +320,9 @@ static int tsi148_irq_init(struct vme_bridge *tsi148_bridge) bridge = tsi148_bridge->driver_priv; /* Initialise list for VME bus errors */ - INIT_LIST_HEAD(&(tsi148_bridge->vme_errors)); + INIT_LIST_HEAD(&tsi148_bridge->vme_errors); - mutex_init(&(tsi148_bridge->irq_mtx)); + mutex_init(&tsi148_bridge->irq_mtx); result = request_irq(pdev->irq, tsi148_irqhandler, @@ -452,7 +452,7 @@ int tsi148_irq_generate(struct vme_bridge *tsi148_bridge, int level, int statid) bridge = tsi148_bridge->driver_priv; - mutex_lock(&(bridge->vme_int)); + mutex_lock(&bridge->vme_int); /* Read VICR register */ tmp = ioread32be(bridge->base + TSI148_LCSR_VICR); @@ -470,7 +470,7 @@ int tsi148_irq_generate(struct vme_bridge *tsi148_bridge, int level, int statid) wait_event_interruptible(bridge->iack_queue, tsi148_iack_received(bridge)); - mutex_unlock(&(bridge->vme_int)); + mutex_unlock(&bridge->vme_int); return 0; } @@ -496,7 +496,7 @@ static struct vme_bus_error *tsi148_find_error(struct vme_bridge *tsi148_bridge, */ err_pos = NULL; /* Iterate through errors */ - list_for_each(err_pos, &(tsi148_bridge->vme_errors)) { + list_for_each(err_pos, &tsi148_bridge->vme_errors) { vme_err = list_entry(err_pos, struct vme_bus_error, list); if ((vme_err->address >= address) && (vme_err->address < bound)) { @@ -530,7 +530,7 @@ static void tsi148_clear_errors(struct vme_bridge *tsi148_bridge, */ err_pos = NULL; /* Iterate through errors */ - list_for_each_safe(err_pos, temp, &(tsi148_bridge->vme_errors)) { + list_for_each_safe(err_pos, temp, &tsi148_bridge->vme_errors) { vme_err = list_entry(err_pos, struct vme_bus_error, list); if ((vme_err->address >= address) && @@ -819,8 +819,8 @@ static int tsi148_alloc_resource(struct vme_master_resource *image, image->kern_base = NULL; if (image->bus_resource.name != NULL) kfree(image->bus_resource.name); - release_resource(&(image->bus_resource)); - memset(&(image->bus_resource), 0, sizeof(struct resource)); + release_resource(&image->bus_resource); + memset(&image->bus_resource, 0, sizeof(struct resource)); } /* Exit here if size is zero */ @@ -845,7 +845,7 @@ static int tsi148_alloc_resource(struct vme_master_resource *image, image->bus_resource.flags = IORESOURCE_MEM; retval = pci_bus_alloc_resource(pdev->bus, - &(image->bus_resource), size, size, PCIBIOS_MIN_MEM, + &image->bus_resource, size, size, PCIBIOS_MIN_MEM, 0, NULL, NULL); if (retval) { dev_err(tsi148_bridge->parent, "Failed to allocate mem " @@ -868,10 +868,10 @@ static int tsi148_alloc_resource(struct vme_master_resource *image, iounmap(image->kern_base); image->kern_base = NULL; err_remap: - release_resource(&(image->bus_resource)); + release_resource(&image->bus_resource); err_resource: kfree(image->bus_resource.name); - memset(&(image->bus_resource), 0, sizeof(struct resource)); + memset(&image->bus_resource, 0, sizeof(struct resource)); err_name: return retval; } @@ -883,9 +883,9 @@ static void tsi148_free_resource(struct vme_master_resource *image) { iounmap(image->kern_base); image->kern_base = NULL; - release_resource(&(image->bus_resource)); + release_resource(&image->bus_resource); kfree(image->bus_resource.name); - memset(&(image->bus_resource), 0, sizeof(struct resource)); + memset(&image->bus_resource, 0, sizeof(struct resource)); } /* @@ -924,7 +924,7 @@ int tsi148_master_set(struct vme_master_resource *image, int enabled, goto err_window; } - spin_lock(&(image->lock)); + spin_lock(&image->lock); /* Let's allocate the resource here rather than further up the stack as * it avoids pushing loads of bus dependant stuff up the stack. If size @@ -932,7 +932,7 @@ int tsi148_master_set(struct vme_master_resource *image, int enabled, */ retval = tsi148_alloc_resource(image, size); if (retval) { - spin_unlock(&(image->lock)); + spin_unlock(&image->lock); dev_err(tsi148_bridge->parent, "Unable to allocate memory for " "resource\n"); goto err_res; @@ -959,19 +959,19 @@ int tsi148_master_set(struct vme_master_resource *image, int enabled, reg_split(vme_offset, &vme_offset_high, &vme_offset_low); if (pci_base_low & 0xFFFF) { - spin_unlock(&(image->lock)); + spin_unlock(&image->lock); dev_err(tsi148_bridge->parent, "Invalid PCI base alignment\n"); retval = -EINVAL; goto err_gran; } if (pci_bound_low & 0xFFFF) { - spin_unlock(&(image->lock)); + spin_unlock(&image->lock); dev_err(tsi148_bridge->parent, "Invalid PCI bound alignment\n"); retval = -EINVAL; goto err_gran; } if (vme_offset_low & 0xFFFF) { - spin_unlock(&(image->lock)); + spin_unlock(&image->lock); dev_err(tsi148_bridge->parent, "Invalid VME Offset " "alignment\n"); retval = -EINVAL; @@ -1035,7 +1035,7 @@ int tsi148_master_set(struct vme_master_resource *image, int enabled, temp_ctl |= TSI148_LCSR_OTAT_DBW_32; break; default: - spin_unlock(&(image->lock)); + spin_unlock(&image->lock); dev_err(tsi148_bridge->parent, "Invalid data width\n"); retval = -EINVAL; goto err_dwidth; @@ -1072,7 +1072,7 @@ int tsi148_master_set(struct vme_master_resource *image, int enabled, temp_ctl |= TSI148_LCSR_OTAT_AMODE_USER4; break; default: - spin_unlock(&(image->lock)); + spin_unlock(&image->lock); dev_err(tsi148_bridge->parent, "Invalid address space\n"); retval = -EINVAL; goto err_aspace; @@ -1109,7 +1109,7 @@ int tsi148_master_set(struct vme_master_resource *image, int enabled, iowrite32be(temp_ctl, bridge->base + TSI148_LCSR_OT[i] + TSI148_LCSR_OFFSET_OTAT); - spin_unlock(&(image->lock)); + spin_unlock(&image->lock); return 0; err_aspace: @@ -1243,12 +1243,12 @@ int tsi148_master_get(struct vme_master_resource *image, int *enabled, { int retval; - spin_lock(&(image->lock)); + spin_lock(&image->lock); retval = __tsi148_master_get(image, enabled, vme_base, size, aspace, cycle, dwidth); - spin_unlock(&(image->lock)); + spin_unlock(&image->lock); return retval; } @@ -1266,7 +1266,7 @@ ssize_t tsi148_master_read(struct vme_master_resource *image, void *buf, tsi148_bridge = image->parent; - spin_lock(&(image->lock)); + spin_lock(&image->lock); memcpy_fromio(buf, image->kern_base + offset, (unsigned int)count); retval = count; @@ -1289,7 +1289,7 @@ ssize_t tsi148_master_read(struct vme_master_resource *image, void *buf, } skip_chk: - spin_unlock(&(image->lock)); + spin_unlock(&image->lock); return retval; } @@ -1312,7 +1312,7 @@ ssize_t tsi148_master_write(struct vme_master_resource *image, void *buf, bridge = tsi148_bridge->driver_priv; - spin_lock(&(image->lock)); + spin_lock(&image->lock); memcpy_toio(image->kern_base + offset, buf, (unsigned int)count); retval = count; @@ -1352,7 +1352,7 @@ ssize_t tsi148_master_write(struct vme_master_resource *image, void *buf, } skip_chk: - spin_unlock(&(image->lock)); + spin_unlock(&image->lock); return retval; } @@ -1378,10 +1378,10 @@ unsigned int tsi148_master_rmw(struct vme_master_resource *image, i = image->number; /* Locking as we can only do one of these at a time */ - mutex_lock(&(bridge->vme_rmw)); + mutex_lock(&bridge->vme_rmw); /* Lock image */ - spin_lock(&(image->lock)); + spin_lock(&image->lock); pci_addr_high = ioread32be(bridge->base + TSI148_LCSR_OT[i] + TSI148_LCSR_OFFSET_OTSAU); @@ -1411,9 +1411,9 @@ unsigned int tsi148_master_rmw(struct vme_master_resource *image, tmp &= ~TSI148_LCSR_VMCTRL_RMWEN; iowrite32be(tmp, bridge->base + TSI148_LCSR_VMCTRL); - spin_unlock(&(image->lock)); + spin_unlock(&image->lock); - mutex_unlock(&(bridge->vme_rmw)); + mutex_unlock(&bridge->vme_rmw); return result; } @@ -1633,10 +1633,10 @@ int tsi148_dma_list_add(struct vme_dma_list *list, struct vme_dma_attr *src, } /* Test descriptor alignment */ - if ((unsigned long)&(entry->descriptor) & 0x7) { + if ((unsigned long)&entry->descriptor & 0x7) { dev_err(tsi148_bridge->parent, "Descriptor not aligned to 8 " "byte boundary as required: %p\n", - &(entry->descriptor)); + &entry->descriptor); retval = -EINVAL; goto err_align; } @@ -1644,7 +1644,7 @@ int tsi148_dma_list_add(struct vme_dma_list *list, struct vme_dma_attr *src, /* Given we are going to fill out the structure, we probably don't * need to zero it, but better safe than sorry for now. */ - memset(&(entry->descriptor), 0, sizeof(struct tsi148_dma_descriptor)); + memset(&entry->descriptor, 0, sizeof(struct tsi148_dma_descriptor)); /* Fill out source part */ switch (src->type) { @@ -1681,7 +1681,7 @@ int tsi148_dma_list_add(struct vme_dma_list *list, struct vme_dma_attr *src, entry->descriptor.dsat = TSI148_LCSR_DSAT_TYP_VME; retval = tsi148_dma_set_vme_src_attributes( - tsi148_bridge->parent, &(entry->descriptor.dsat), + tsi148_bridge->parent, &entry->descriptor.dsat, vme_attr->aspace, vme_attr->cycle, vme_attr->dwidth); if (retval < 0) goto err_source; @@ -1719,7 +1719,7 @@ int tsi148_dma_list_add(struct vme_dma_list *list, struct vme_dma_attr *src, entry->descriptor.ddat = TSI148_LCSR_DDAT_TYP_VME; retval = tsi148_dma_set_vme_dest_attributes( - tsi148_bridge->parent, &(entry->descriptor.ddat), + tsi148_bridge->parent, &entry->descriptor.ddat, vme_attr->aspace, vme_attr->cycle, vme_attr->dwidth); if (retval < 0) goto err_dest; @@ -1735,16 +1735,16 @@ int tsi148_dma_list_add(struct vme_dma_list *list, struct vme_dma_attr *src, entry->descriptor.dcnt = (u32)count; /* Add to list */ - list_add_tail(&(entry->list), &(list->entries)); + list_add_tail(&entry->list, &list->entries); /* Fill out previous descriptors "Next Address" */ - if (entry->list.prev != &(list->entries)) { + if (entry->list.prev != &list->entries) { prev = list_entry(entry->list.prev, struct tsi148_dma_entry, list); /* We need the bus address for the pointer */ - desc_ptr = virt_to_bus(&(entry->descriptor)); - reg_split(desc_ptr, &(prev->descriptor.dnlau), - &(prev->descriptor.dnlal)); + desc_ptr = virt_to_bus(&entry->descriptor); + reg_split(desc_ptr, &prev->descriptor.dnlau, + &prev->descriptor.dnlal); } return 0; @@ -1799,30 +1799,30 @@ int tsi148_dma_list_exec(struct vme_dma_list *list) bridge = tsi148_bridge->driver_priv; - mutex_lock(&(ctrlr->mtx)); + mutex_lock(&ctrlr->mtx); channel = ctrlr->number; - if (!list_empty(&(ctrlr->running))) { + if (!list_empty(&ctrlr->running)) { /* * XXX We have an active DMA transfer and currently haven't * sorted out the mechanism for "pending" DMA transfers. * Return busy. */ /* Need to add to pending here */ - mutex_unlock(&(ctrlr->mtx)); + mutex_unlock(&ctrlr->mtx); return -EBUSY; } else { - list_add(&(list->list), &(ctrlr->running)); + list_add(&list->list, &ctrlr->running); } /* Get first bus address and write into registers */ - entry = list_first_entry(&(list->entries), struct tsi148_dma_entry, + entry = list_first_entry(&list->entries, struct tsi148_dma_entry, list); - bus_addr = virt_to_bus(&(entry->descriptor)); + bus_addr = virt_to_bus(&entry->descriptor); - mutex_unlock(&(ctrlr->mtx)); + mutex_unlock(&ctrlr->mtx); reg_split(bus_addr, &bus_addr_high, &bus_addr_low); @@ -1850,9 +1850,9 @@ int tsi148_dma_list_exec(struct vme_dma_list *list) } /* Remove list from running list */ - mutex_lock(&(ctrlr->mtx)); - list_del(&(list->list)); - mutex_unlock(&(ctrlr->mtx)); + mutex_lock(&ctrlr->mtx); + list_del(&list->list); + mutex_unlock(&ctrlr->mtx); return retval; } @@ -1868,7 +1868,7 @@ int tsi148_dma_list_empty(struct vme_dma_list *list) struct tsi148_dma_entry *entry; /* detach and free each entry */ - list_for_each_safe(pos, temp, &(list->entries)) { + list_for_each_safe(pos, temp, &list->entries) { list_del(pos); entry = list_entry(pos, struct tsi148_dma_entry, list); kfree(entry); @@ -1896,12 +1896,12 @@ int tsi148_lm_set(struct vme_lm_resource *lm, unsigned long long lm_base, bridge = tsi148_bridge->driver_priv; - mutex_lock(&(lm->mtx)); + mutex_lock(&lm->mtx); /* If we already have a callback attached, we can't move it! */ for (i = 0; i < lm->monitors; i++) { if (bridge->lm_callback[i] != NULL) { - mutex_unlock(&(lm->mtx)); + mutex_unlock(&lm->mtx); dev_err(tsi148_bridge->parent, "Location monitor " "callback attached, can't reset\n"); return -EBUSY; @@ -1922,7 +1922,7 @@ int tsi148_lm_set(struct vme_lm_resource *lm, unsigned long long lm_base, lm_ctl |= TSI148_LCSR_LMAT_AS_A64; break; default: - mutex_unlock(&(lm->mtx)); + mutex_unlock(&lm->mtx); dev_err(tsi148_bridge->parent, "Invalid address space\n"); return -EINVAL; break; @@ -1943,7 +1943,7 @@ int tsi148_lm_set(struct vme_lm_resource *lm, unsigned long long lm_base, iowrite32be(lm_base_low, bridge->base + TSI148_LCSR_LMBAL); iowrite32be(lm_ctl, bridge->base + TSI148_LCSR_LMAT); - mutex_unlock(&(lm->mtx)); + mutex_unlock(&lm->mtx); return 0; } @@ -1959,7 +1959,7 @@ int tsi148_lm_get(struct vme_lm_resource *lm, unsigned long long *lm_base, bridge = lm->parent->driver_priv; - mutex_lock(&(lm->mtx)); + mutex_lock(&lm->mtx); lm_base_high = ioread32be(bridge->base + TSI148_LCSR_LMBAU); lm_base_low = ioread32be(bridge->base + TSI148_LCSR_LMBAL); @@ -1992,7 +1992,7 @@ int tsi148_lm_get(struct vme_lm_resource *lm, unsigned long long *lm_base, if (lm_ctl & TSI148_LCSR_LMAT_DATA) *cycle |= VME_DATA; - mutex_unlock(&(lm->mtx)); + mutex_unlock(&lm->mtx); return enabled; } @@ -2013,12 +2013,12 @@ int tsi148_lm_attach(struct vme_lm_resource *lm, int monitor, bridge = tsi148_bridge->driver_priv; - mutex_lock(&(lm->mtx)); + mutex_lock(&lm->mtx); /* Ensure that the location monitor is configured - need PGM or DATA */ lm_ctl = ioread32be(bridge->base + TSI148_LCSR_LMAT); if ((lm_ctl & (TSI148_LCSR_LMAT_PGM | TSI148_LCSR_LMAT_DATA)) == 0) { - mutex_unlock(&(lm->mtx)); + mutex_unlock(&lm->mtx); dev_err(tsi148_bridge->parent, "Location monitor not properly " "configured\n"); return -EINVAL; @@ -2026,7 +2026,7 @@ int tsi148_lm_attach(struct vme_lm_resource *lm, int monitor, /* Check that a callback isn't already attached */ if (bridge->lm_callback[monitor] != NULL) { - mutex_unlock(&(lm->mtx)); + mutex_unlock(&lm->mtx); dev_err(tsi148_bridge->parent, "Existing callback attached\n"); return -EBUSY; } @@ -2049,7 +2049,7 @@ int tsi148_lm_attach(struct vme_lm_resource *lm, int monitor, iowrite32be(lm_ctl, bridge->base + TSI148_LCSR_LMAT); } - mutex_unlock(&(lm->mtx)); + mutex_unlock(&lm->mtx); return 0; } @@ -2064,7 +2064,7 @@ int tsi148_lm_detach(struct vme_lm_resource *lm, int monitor) bridge = lm->parent->driver_priv; - mutex_lock(&(lm->mtx)); + mutex_lock(&lm->mtx); /* Disable Location Monitor and ensure previous interrupts are clear */ lm_en = ioread32be(bridge->base + TSI148_LCSR_INTEN); @@ -2089,7 +2089,7 @@ int tsi148_lm_detach(struct vme_lm_resource *lm, int monitor) iowrite32be(tmp, bridge->base + TSI148_LCSR_LMAT); } - mutex_unlock(&(lm->mtx)); + mutex_unlock(&lm->mtx); return 0; } @@ -2142,7 +2142,7 @@ static int tsi148_crcsr_init(struct vme_bridge *tsi148_bridge, /* Allocate mem for CR/CSR image */ bridge->crcsr_kernel = pci_alloc_consistent(pdev, VME_CRCSR_BUF_SIZE, - &(bridge->crcsr_bus)); + &bridge->crcsr_bus); if (bridge->crcsr_kernel == NULL) { dev_err(tsi148_bridge->parent, "Failed to allocate memory for " "CR/CSR image\n"); @@ -2280,13 +2280,13 @@ static int tsi148_probe(struct pci_dev *pdev, const struct pci_device_id *id) } /* Initialize wait queues & mutual exclusion flags */ - init_waitqueue_head(&(tsi148_device->dma_queue[0])); - init_waitqueue_head(&(tsi148_device->dma_queue[1])); - init_waitqueue_head(&(tsi148_device->iack_queue)); - mutex_init(&(tsi148_device->vme_int)); - mutex_init(&(tsi148_device->vme_rmw)); + init_waitqueue_head(&tsi148_device->dma_queue[0]); + init_waitqueue_head(&tsi148_device->dma_queue[1]); + init_waitqueue_head(&tsi148_device->iack_queue); + mutex_init(&tsi148_device->vme_int); + mutex_init(&tsi148_device->vme_rmw); - tsi148_bridge->parent = &(pdev->dev); + tsi148_bridge->parent = &pdev->dev; strcpy(tsi148_bridge->name, driver_name); /* Setup IRQ */ @@ -2314,7 +2314,7 @@ static int tsi148_probe(struct pci_dev *pdev, const struct pci_device_id *id) goto err_master; } tsi148_device->flush_image->parent = tsi148_bridge; - spin_lock_init(&(tsi148_device->flush_image->lock)); + spin_lock_init(&tsi148_device->flush_image->lock); tsi148_device->flush_image->locked = 1; tsi148_device->flush_image->number = master_num; tsi148_device->flush_image->address_attr = VME_A16 | VME_A24 | @@ -2324,13 +2324,13 @@ static int tsi148_probe(struct pci_dev *pdev, const struct pci_device_id *id) VME_2eSST160 | VME_2eSST267 | VME_2eSST320 | VME_SUPER | VME_USER | VME_PROG | VME_DATA; tsi148_device->flush_image->width_attr = VME_D16 | VME_D32; - memset(&(tsi148_device->flush_image->bus_resource), 0, + memset(&tsi148_device->flush_image->bus_resource, 0, sizeof(struct resource)); tsi148_device->flush_image->kern_base = NULL; } /* Add master windows to list */ - INIT_LIST_HEAD(&(tsi148_bridge->master_resources)); + INIT_LIST_HEAD(&tsi148_bridge->master_resources); for (i = 0; i < master_num; i++) { master_image = kmalloc(sizeof(struct vme_master_resource), GFP_KERNEL); @@ -2341,7 +2341,7 @@ static int tsi148_probe(struct pci_dev *pdev, const struct pci_device_id *id) goto err_master; } master_image->parent = tsi148_bridge; - spin_lock_init(&(master_image->lock)); + spin_lock_init(&master_image->lock); master_image->locked = 0; master_image->number = i; master_image->address_attr = VME_A16 | VME_A24 | VME_A32 | @@ -2351,15 +2351,15 @@ static int tsi148_probe(struct pci_dev *pdev, const struct pci_device_id *id) VME_2eSST267 | VME_2eSST320 | VME_SUPER | VME_USER | VME_PROG | VME_DATA; master_image->width_attr = VME_D16 | VME_D32; - memset(&(master_image->bus_resource), 0, + memset(&master_image->bus_resource, 0, sizeof(struct resource)); master_image->kern_base = NULL; - list_add_tail(&(master_image->list), - &(tsi148_bridge->master_resources)); + list_add_tail(&master_image->list, + &tsi148_bridge->master_resources); } /* Add slave windows to list */ - INIT_LIST_HEAD(&(tsi148_bridge->slave_resources)); + INIT_LIST_HEAD(&tsi148_bridge->slave_resources); for (i = 0; i < TSI148_MAX_SLAVE; i++) { slave_image = kmalloc(sizeof(struct vme_slave_resource), GFP_KERNEL); @@ -2370,7 +2370,7 @@ static int tsi148_probe(struct pci_dev *pdev, const struct pci_device_id *id) goto err_slave; } slave_image->parent = tsi148_bridge; - mutex_init(&(slave_image->mtx)); + mutex_init(&slave_image->mtx); slave_image->locked = 0; slave_image->number = i; slave_image->address_attr = VME_A16 | VME_A24 | VME_A32 | @@ -2380,12 +2380,12 @@ static int tsi148_probe(struct pci_dev *pdev, const struct pci_device_id *id) VME_2eVME | VME_2eSST | VME_2eSSTB | VME_2eSST160 | VME_2eSST267 | VME_2eSST320 | VME_SUPER | VME_USER | VME_PROG | VME_DATA; - list_add_tail(&(slave_image->list), - &(tsi148_bridge->slave_resources)); + list_add_tail(&slave_image->list, + &tsi148_bridge->slave_resources); } /* Add dma engines to list */ - INIT_LIST_HEAD(&(tsi148_bridge->dma_resources)); + INIT_LIST_HEAD(&tsi148_bridge->dma_resources); for (i = 0; i < TSI148_MAX_DMA; i++) { dma_ctrlr = kmalloc(sizeof(struct vme_dma_resource), GFP_KERNEL); @@ -2396,21 +2396,21 @@ static int tsi148_probe(struct pci_dev *pdev, const struct pci_device_id *id) goto err_dma; } dma_ctrlr->parent = tsi148_bridge; - mutex_init(&(dma_ctrlr->mtx)); + mutex_init(&dma_ctrlr->mtx); dma_ctrlr->locked = 0; dma_ctrlr->number = i; dma_ctrlr->route_attr = VME_DMA_VME_TO_MEM | VME_DMA_MEM_TO_VME | VME_DMA_VME_TO_VME | VME_DMA_MEM_TO_MEM | VME_DMA_PATTERN_TO_VME | VME_DMA_PATTERN_TO_MEM; - INIT_LIST_HEAD(&(dma_ctrlr->pending)); - INIT_LIST_HEAD(&(dma_ctrlr->running)); - list_add_tail(&(dma_ctrlr->list), - &(tsi148_bridge->dma_resources)); + INIT_LIST_HEAD(&dma_ctrlr->pending); + INIT_LIST_HEAD(&dma_ctrlr->running); + list_add_tail(&dma_ctrlr->list, + &tsi148_bridge->dma_resources); } /* Add location monitor to list */ - INIT_LIST_HEAD(&(tsi148_bridge->lm_resources)); + INIT_LIST_HEAD(&tsi148_bridge->lm_resources); lm = kmalloc(sizeof(struct vme_lm_resource), GFP_KERNEL); if (lm == NULL) { dev_err(&pdev->dev, "Failed to allocate memory for " @@ -2419,11 +2419,11 @@ static int tsi148_probe(struct pci_dev *pdev, const struct pci_device_id *id) goto err_lm; } lm->parent = tsi148_bridge; - mutex_init(&(lm->mtx)); + mutex_init(&lm->mtx); lm->locked = 0; lm->number = 1; lm->monitors = 4; - list_add_tail(&(lm->list), &(tsi148_bridge->lm_resources)); + list_add_tail(&lm->list, &tsi148_bridge->lm_resources); tsi148_bridge->slave_get = tsi148_slave_get; tsi148_bridge->slave_set = tsi148_slave_set; @@ -2483,28 +2483,28 @@ err_reg: err_crcsr: err_lm: /* resources are stored in link list */ - list_for_each(pos, &(tsi148_bridge->lm_resources)) { + list_for_each(pos, &tsi148_bridge->lm_resources) { lm = list_entry(pos, struct vme_lm_resource, list); list_del(pos); kfree(lm); } err_dma: /* resources are stored in link list */ - list_for_each(pos, &(tsi148_bridge->dma_resources)) { + list_for_each(pos, &tsi148_bridge->dma_resources) { dma_ctrlr = list_entry(pos, struct vme_dma_resource, list); list_del(pos); kfree(dma_ctrlr); } err_slave: /* resources are stored in link list */ - list_for_each(pos, &(tsi148_bridge->slave_resources)) { + list_for_each(pos, &tsi148_bridge->slave_resources) { slave_image = list_entry(pos, struct vme_slave_resource, list); list_del(pos); kfree(slave_image); } err_master: /* resources are stored in link list */ - list_for_each(pos, &(tsi148_bridge->master_resources)) { + list_for_each(pos, &tsi148_bridge->master_resources) { master_image = list_entry(pos, struct vme_master_resource, list); list_del(pos); @@ -2589,21 +2589,21 @@ static void tsi148_remove(struct pci_dev *pdev) tsi148_crcsr_exit(tsi148_bridge, pdev); /* resources are stored in link list */ - list_for_each(pos, &(tsi148_bridge->dma_resources)) { + list_for_each(pos, &tsi148_bridge->dma_resources) { dma_ctrlr = list_entry(pos, struct vme_dma_resource, list); list_del(pos); kfree(dma_ctrlr); } /* resources are stored in link list */ - list_for_each(pos, &(tsi148_bridge->slave_resources)) { + list_for_each(pos, &tsi148_bridge->slave_resources) { slave_image = list_entry(pos, struct vme_slave_resource, list); list_del(pos); kfree(slave_image); } /* resources are stored in link list */ - list_for_each(pos, &(tsi148_bridge->master_resources)) { + list_for_each(pos, &tsi148_bridge->master_resources) { master_image = list_entry(pos, struct vme_master_resource, list); list_del(pos); diff --git a/drivers/staging/vme/devices/vme_user.c b/drivers/staging/vme/devices/vme_user.c index 71bbc526626c..cbe2e11d9af7 100644 --- a/drivers/staging/vme/devices/vme_user.c +++ b/drivers/staging/vme/devices/vme_user.c @@ -470,9 +470,9 @@ static int vme_user_ioctl(struct inode *inode, struct file *file, * to userspace as they are */ retval = vme_master_get(image[minor].resource, - &(master.enable), &(master.vme_addr), - &(master.size), &(master.aspace), - &(master.cycle), &(master.dwidth)); + &master.enable, &master.vme_addr, + &master.size, &master.aspace, + &master.cycle, &master.dwidth); copied = copy_to_user((char *)arg, &master, sizeof(struct vme_master)); @@ -514,9 +514,9 @@ static int vme_user_ioctl(struct inode *inode, struct file *file, * to userspace as they are */ retval = vme_slave_get(image[minor].resource, - &(slave.enable), &(slave.vme_addr), - &(slave.size), &pci_addr, &(slave.aspace), - &(slave.cycle)); + &slave.enable, &slave.vme_addr, + &slave.size, &pci_addr, &slave.aspace, + &slave.cycle); copied = copy_to_user((char *)arg, &slave, sizeof(struct vme_slave)); @@ -683,7 +683,7 @@ static int __init vme_user_probe(struct device *dev, int cur_bus, int cur_slot) for (i = 0; i < VME_DEVS; i++) { image[i].kern_buf = NULL; image[i].pci_buf = 0; - sema_init(&(image[i].sem), 1); + sema_init(&image[i].sem, 1); image[i].device = NULL; image[i].resource = NULL; image[i].users = 0; @@ -727,7 +727,7 @@ static int __init vme_user_probe(struct device *dev, int cur_bus, int cur_slot) } image[i].size_buf = PCI_BUF_SIZE; image[i].kern_buf = vme_alloc_consistent(image[i].resource, - image[i].size_buf, &(image[i].pci_buf)); + image[i].size_buf, &image[i].pci_buf); if (image[i].kern_buf == NULL) { printk(KERN_WARNING "Unable to allocate memory for " "buffer\n"); diff --git a/drivers/staging/vme/vme.c b/drivers/staging/vme/vme.c index 093fbffbf557..47e9d5ccf784 100644 --- a/drivers/staging/vme/vme.c +++ b/drivers/staging/vme/vme.c @@ -245,7 +245,7 @@ struct vme_resource *vme_slave_request(struct device *dev, } /* Loop through slave resources */ - list_for_each(slave_pos, &(bridge->slave_resources)) { + list_for_each(slave_pos, &bridge->slave_resources) { slave_image = list_entry(slave_pos, struct vme_slave_resource, list); @@ -255,17 +255,17 @@ struct vme_resource *vme_slave_request(struct device *dev, } /* Find an unlocked and compatible image */ - mutex_lock(&(slave_image->mtx)); + mutex_lock(&slave_image->mtx); if (((slave_image->address_attr & address) == address) && ((slave_image->cycle_attr & cycle) == cycle) && (slave_image->locked == 0)) { slave_image->locked = 1; - mutex_unlock(&(slave_image->mtx)); + mutex_unlock(&slave_image->mtx); allocated_image = slave_image; break; } - mutex_unlock(&(slave_image->mtx)); + mutex_unlock(&slave_image->mtx); } /* No free image */ @@ -278,15 +278,15 @@ struct vme_resource *vme_slave_request(struct device *dev, goto err_alloc; } resource->type = VME_SLAVE; - resource->entry = &(allocated_image->list); + resource->entry = &allocated_image->list; return resource; err_alloc: /* Unlock image */ - mutex_lock(&(slave_image->mtx)); + mutex_lock(&slave_image->mtx); slave_image->locked = 0; - mutex_unlock(&(slave_image->mtx)); + mutex_unlock(&slave_image->mtx); err_image: err_bus: return NULL; @@ -369,12 +369,12 @@ void vme_slave_free(struct vme_resource *resource) } /* Unlock image */ - mutex_lock(&(slave_image->mtx)); + mutex_lock(&slave_image->mtx); if (slave_image->locked == 0) printk(KERN_ERR "Image is already free\n"); slave_image->locked = 0; - mutex_unlock(&(slave_image->mtx)); + mutex_unlock(&slave_image->mtx); /* Free up resource memory */ kfree(resource); @@ -401,7 +401,7 @@ struct vme_resource *vme_master_request(struct device *dev, } /* Loop through master resources */ - list_for_each(master_pos, &(bridge->master_resources)) { + list_for_each(master_pos, &bridge->master_resources) { master_image = list_entry(master_pos, struct vme_master_resource, list); @@ -411,18 +411,18 @@ struct vme_resource *vme_master_request(struct device *dev, } /* Find an unlocked and compatible image */ - spin_lock(&(master_image->lock)); + spin_lock(&master_image->lock); if (((master_image->address_attr & address) == address) && ((master_image->cycle_attr & cycle) == cycle) && ((master_image->width_attr & dwidth) == dwidth) && (master_image->locked == 0)) { master_image->locked = 1; - spin_unlock(&(master_image->lock)); + spin_unlock(&master_image->lock); allocated_image = master_image; break; } - spin_unlock(&(master_image->lock)); + spin_unlock(&master_image->lock); } /* Check to see if we found a resource */ @@ -437,16 +437,16 @@ struct vme_resource *vme_master_request(struct device *dev, goto err_alloc; } resource->type = VME_MASTER; - resource->entry = &(allocated_image->list); + resource->entry = &allocated_image->list; return resource; kfree(resource); err_alloc: /* Unlock image */ - spin_lock(&(master_image->lock)); + spin_lock(&master_image->lock); master_image->locked = 0; - spin_unlock(&(master_image->lock)); + spin_unlock(&master_image->lock); err_image: err_bus: return NULL; @@ -628,12 +628,12 @@ void vme_master_free(struct vme_resource *resource) } /* Unlock image */ - spin_lock(&(master_image->lock)); + spin_lock(&master_image->lock); if (master_image->locked == 0) printk(KERN_ERR "Image is already free\n"); master_image->locked = 0; - spin_unlock(&(master_image->lock)); + spin_unlock(&master_image->lock); /* Free up resource memory */ kfree(resource); @@ -662,7 +662,7 @@ struct vme_resource *vme_dma_request(struct device *dev, vme_dma_route_t route) } /* Loop through DMA resources */ - list_for_each(dma_pos, &(bridge->dma_resources)) { + list_for_each(dma_pos, &bridge->dma_resources) { dma_ctrlr = list_entry(dma_pos, struct vme_dma_resource, list); @@ -672,16 +672,16 @@ struct vme_resource *vme_dma_request(struct device *dev, vme_dma_route_t route) } /* Find an unlocked and compatible controller */ - mutex_lock(&(dma_ctrlr->mtx)); + mutex_lock(&dma_ctrlr->mtx); if (((dma_ctrlr->route_attr & route) == route) && (dma_ctrlr->locked == 0)) { dma_ctrlr->locked = 1; - mutex_unlock(&(dma_ctrlr->mtx)); + mutex_unlock(&dma_ctrlr->mtx); allocated_ctrlr = dma_ctrlr; break; } - mutex_unlock(&(dma_ctrlr->mtx)); + mutex_unlock(&dma_ctrlr->mtx); } /* Check to see if we found a resource */ @@ -694,15 +694,15 @@ struct vme_resource *vme_dma_request(struct device *dev, vme_dma_route_t route) goto err_alloc; } resource->type = VME_DMA; - resource->entry = &(allocated_ctrlr->list); + resource->entry = &allocated_ctrlr->list; return resource; err_alloc: /* Unlock image */ - mutex_lock(&(dma_ctrlr->mtx)); + mutex_lock(&dma_ctrlr->mtx); dma_ctrlr->locked = 0; - mutex_unlock(&(dma_ctrlr->mtx)); + mutex_unlock(&dma_ctrlr->mtx); err_ctrlr: err_bus: return NULL; @@ -729,9 +729,9 @@ struct vme_dma_list *vme_new_dma_list(struct vme_resource *resource) printk(KERN_ERR "Unable to allocate memory for new dma list\n"); return NULL; } - INIT_LIST_HEAD(&(dma_list->entries)); + INIT_LIST_HEAD(&dma_list->entries); dma_list->parent = ctrlr; - mutex_init(&(dma_list->mtx)); + mutex_init(&dma_list->mtx); return dma_list; } @@ -880,14 +880,14 @@ int vme_dma_list_add(struct vme_dma_list *list, struct vme_dma_attr *src, return -EINVAL; } - if (!mutex_trylock(&(list->mtx))) { + if (!mutex_trylock(&list->mtx)) { printk(KERN_ERR "Link List already submitted\n"); return -EINVAL; } retval = bridge->dma_list_add(list, src, dest, count); - mutex_unlock(&(list->mtx)); + mutex_unlock(&list->mtx); return retval; } @@ -903,11 +903,11 @@ int vme_dma_list_exec(struct vme_dma_list *list) return -EINVAL; } - mutex_lock(&(list->mtx)); + mutex_lock(&list->mtx); retval = bridge->dma_list_exec(list); - mutex_unlock(&(list->mtx)); + mutex_unlock(&list->mtx); return retval; } @@ -923,7 +923,7 @@ int vme_dma_list_free(struct vme_dma_list *list) return -EINVAL; } - if (!mutex_trylock(&(list->mtx))) { + if (!mutex_trylock(&list->mtx)) { printk(KERN_ERR "Link List in use\n"); return -EINVAL; } @@ -935,10 +935,10 @@ int vme_dma_list_free(struct vme_dma_list *list) retval = bridge->dma_list_empty(list); if (retval) { printk(KERN_ERR "Unable to empty link-list entries\n"); - mutex_unlock(&(list->mtx)); + mutex_unlock(&list->mtx); return retval; } - mutex_unlock(&(list->mtx)); + mutex_unlock(&list->mtx); kfree(list); return retval; @@ -956,20 +956,20 @@ int vme_dma_free(struct vme_resource *resource) ctrlr = list_entry(resource->entry, struct vme_dma_resource, list); - if (!mutex_trylock(&(ctrlr->mtx))) { + if (!mutex_trylock(&ctrlr->mtx)) { printk(KERN_ERR "Resource busy, can't free\n"); return -EBUSY; } - if (!(list_empty(&(ctrlr->pending)) && list_empty(&(ctrlr->running)))) { + if (!(list_empty(&ctrlr->pending) && list_empty(&ctrlr->running))) { printk(KERN_WARNING "Resource still processing transfers\n"); - mutex_unlock(&(ctrlr->mtx)); + mutex_unlock(&ctrlr->mtx); return -EBUSY; } ctrlr->locked = 0; - mutex_unlock(&(ctrlr->mtx)); + mutex_unlock(&ctrlr->mtx); return 0; } @@ -1013,10 +1013,10 @@ int vme_irq_request(struct device *dev, int level, int statid, return -EINVAL; } - mutex_lock(&(bridge->irq_mtx)); + mutex_lock(&bridge->irq_mtx); if (bridge->irq[level - 1].callback[statid].func) { - mutex_unlock(&(bridge->irq_mtx)); + mutex_unlock(&bridge->irq_mtx); printk(KERN_WARNING "VME Interrupt already taken\n"); return -EBUSY; } @@ -1028,7 +1028,7 @@ int vme_irq_request(struct device *dev, int level, int statid, /* Enable IRQ level */ bridge->irq_set(bridge, level, 1, 1); - mutex_unlock(&(bridge->irq_mtx)); + mutex_unlock(&bridge->irq_mtx); return 0; } @@ -1054,7 +1054,7 @@ void vme_irq_free(struct device *dev, int level, int statid) return; } - mutex_lock(&(bridge->irq_mtx)); + mutex_lock(&bridge->irq_mtx); bridge->irq[level - 1].count--; @@ -1065,7 +1065,7 @@ void vme_irq_free(struct device *dev, int level, int statid) bridge->irq[level - 1].callback[statid].func = NULL; bridge->irq[level - 1].callback[statid].priv_data = NULL; - mutex_unlock(&(bridge->irq_mtx)); + mutex_unlock(&bridge->irq_mtx); } EXPORT_SYMBOL(vme_irq_free); @@ -1111,7 +1111,7 @@ struct vme_resource *vme_lm_request(struct device *dev) } /* Loop through DMA resources */ - list_for_each(lm_pos, &(bridge->lm_resources)) { + list_for_each(lm_pos, &bridge->lm_resources) { lm = list_entry(lm_pos, struct vme_lm_resource, list); @@ -1122,14 +1122,14 @@ struct vme_resource *vme_lm_request(struct device *dev) } /* Find an unlocked controller */ - mutex_lock(&(lm->mtx)); + mutex_lock(&lm->mtx); if (lm->locked == 0) { lm->locked = 1; - mutex_unlock(&(lm->mtx)); + mutex_unlock(&lm->mtx); allocated_lm = lm; break; } - mutex_unlock(&(lm->mtx)); + mutex_unlock(&lm->mtx); } /* Check to see if we found a resource */ @@ -1142,15 +1142,15 @@ struct vme_resource *vme_lm_request(struct device *dev) goto err_alloc; } resource->type = VME_LM; - resource->entry = &(allocated_lm->list); + resource->entry = &allocated_lm->list; return resource; err_alloc: /* Unlock image */ - mutex_lock(&(lm->mtx)); + mutex_lock(&lm->mtx); lm->locked = 0; - mutex_unlock(&(lm->mtx)); + mutex_unlock(&lm->mtx); err_lm: err_bus: return NULL; @@ -1270,7 +1270,7 @@ void vme_lm_free(struct vme_resource *resource) lm = list_entry(resource->entry, struct vme_lm_resource, list); - mutex_lock(&(lm->mtx)); + mutex_lock(&lm->mtx); /* XXX * Check to see that there aren't any callbacks still attached, if @@ -1279,7 +1279,7 @@ void vme_lm_free(struct vme_resource *resource) lm->locked = 0; - mutex_unlock(&(lm->mtx)); + mutex_unlock(&lm->mtx); kfree(resource); } @@ -1343,11 +1343,11 @@ int vme_register_bridge(struct vme_bridge *bridge) * specification. */ for (i = 0; i < VME_SLOTS_MAX; i++) { - dev = &(bridge->dev[i]); + dev = &bridge->dev[i]; memset(dev, 0, sizeof(struct device)); dev->parent = bridge->parent; - dev->bus = &(vme_bus_type); + dev->bus = &vme_bus_type; /* * We save a pointer to the bridge in platform_data so that we * can get to it later. We keep driver_data for use by the @@ -1366,7 +1366,7 @@ int vme_register_bridge(struct vme_bridge *bridge) i = VME_SLOTS_MAX; err_reg: while (i > -1) { - dev = &(bridge->dev[i]); + dev = &bridge->dev[i]; device_unregister(dev); } vme_free_bus_num(bridge->num); @@ -1381,7 +1381,7 @@ void vme_unregister_bridge(struct vme_bridge *bridge) for (i = 0; i < VME_SLOTS_MAX; i++) { - dev = &(bridge->dev[i]); + dev = &bridge->dev[i]; device_unregister(dev); } vme_free_bus_num(bridge->num); @@ -1418,7 +1418,7 @@ static int vme_calc_slot(struct device *dev) /* Determine slot number */ num = 0; while (num < VME_SLOTS_MAX) { - if (&(bridge->dev[num]) == dev) + if (&bridge->dev[num] == dev) break; num++; -- cgit v1.2.3 From 55db50205adaf14db1bda07d0931b647b794de2f Mon Sep 17 00:00:00 2001 From: "Emilio G. Cota" Date: Fri, 12 Nov 2010 11:14:14 +0000 Subject: staging: vme_user: return the appropriate error code when module_init fails When init_module fails, 0 is returned anyway; the module is then installed and oopses when we try to remove it: [ 3236.368009] WARNING: at drivers/base/driver.c:262 driver_unregister+0x36/0x6f() [ 3236.368012] Hardware name: [ 3236.368014] Unexpected driver unregister! [ 3236.368016] Modules linked in: vme_user(-) vme_tsi148 vme e1000e iTCO_wdt iTCO_vendor_support [last unloaded: vme] [ 3236.368027] Pid: 16162, comm: rmmod Not tainted 2.6.35 #2 [ 3236.368029] Call Trace: [ 3236.368037] [] warn_slowpath_common+0x80/0x98 [ 3236.368044] [] ? __try_stop_module+0x0/0x58 [ 3236.368049] [] warn_slowpath_fmt+0x41/0x43 [ 3236.368054] [] ? __try_stop_module+0x0/0x58 [ 3236.368059] [] driver_unregister+0x36/0x6f [ 3236.368066] [] vme_unregister_driver+0xd/0xf [vme] [ 3236.368072] [] vme_user_exit+0x10/0x1e [vme_user] [ 3236.368076] [] sys_delete_module+0x1ba/0x226 [ 3236.368082] [] ? do_page_fault+0x25d/0x28a [ 3236.368088] [] system_call_fastpath+0x16/0x1b [ 3236.368092] ---[ end trace cab6d88ebc44c1de ]--- The appended fixes it by returning the appropriate error code in module_init whenever something goes wrong, thus cancelling the insertion of the module. Signed-off-by: Emilio G. Cota Acked-by: Martyn Welch Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vme/devices/vme_user.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/staging/vme/devices/vme_user.c b/drivers/staging/vme/devices/vme_user.c index cbe2e11d9af7..a6f61162af3f 100644 --- a/drivers/staging/vme/devices/vme_user.c +++ b/drivers/staging/vme/devices/vme_user.c @@ -611,6 +611,7 @@ static int __init vme_user_init(void) if (bus_num == 0) { printk(KERN_ERR "%s: No cards, skipping registration\n", driver_name); + retval = -ENODEV; goto err_nocard; } @@ -629,6 +630,7 @@ static int __init vme_user_init(void) if (ids == NULL) { printk(KERN_ERR "%s: Unable to allocate ID table\n", driver_name); + retval = -ENOMEM; goto err_id; } -- cgit v1.2.3 From c0779fd01df76b3097cc77e3a404e8bb067e5628 Mon Sep 17 00:00:00 2001 From: "Emilio G. Cota" Date: Fri, 12 Nov 2010 11:14:20 +0000 Subject: staging: vme_user: remove unreachable line Signed-off-by: Emilio G. Cota Acked-by: Martyn Welch Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vme/devices/vme_user.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/staging/vme/devices/vme_user.c b/drivers/staging/vme/devices/vme_user.c index a6f61162af3f..bdc4e1ecfaf3 100644 --- a/drivers/staging/vme/devices/vme_user.c +++ b/drivers/staging/vme/devices/vme_user.c @@ -654,7 +654,6 @@ static int __init vme_user_init(void) return retval; - vme_unregister_driver(&vme_user_driver); err_reg: kfree(ids); err_id: -- cgit v1.2.3 From db6d8fc5596ef866e64e9a7eef96bacdc6e51e11 Mon Sep 17 00:00:00 2001 From: "Emilio G. Cota" Date: Fri, 12 Nov 2010 11:14:27 +0000 Subject: staging: vme: fix bogus clearing of the bus number in vme_free_bus_num Signed-off-by: Emilio G. Cota Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vme/vme.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/vme/vme.c b/drivers/staging/vme/vme.c index 47e9d5ccf784..d9fc8644376e 100644 --- a/drivers/staging/vme/vme.c +++ b/drivers/staging/vme/vme.c @@ -1326,7 +1326,7 @@ static int vme_alloc_bus_num(void) static void vme_free_bus_num(int bus) { mutex_lock(&vme_bus_num_mtx); - vme_bus_numbers |= ~(0x1 << bus); + vme_bus_numbers &= ~(0x1 << bus); mutex_unlock(&vme_bus_num_mtx); } -- cgit v1.2.3 From b558ba2f356c28269de179c4f7f6f179a4fa6a1d Mon Sep 17 00:00:00 2001 From: "Emilio G. Cota" Date: Fri, 12 Nov 2010 11:14:34 +0000 Subject: staging: vme: tsi148: use list_for_each_safe when deleting resources in .remove This fixes an oops when removing the module. Signed-off-by: Emilio G. Cota Acked-by: Martyn Welch Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vme/bridges/vme_tsi148.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/staging/vme/bridges/vme_tsi148.c b/drivers/staging/vme/bridges/vme_tsi148.c index 1cba1fa16079..5c25cd8c9209 100644 --- a/drivers/staging/vme/bridges/vme_tsi148.c +++ b/drivers/staging/vme/bridges/vme_tsi148.c @@ -2531,6 +2531,7 @@ err_struct: static void tsi148_remove(struct pci_dev *pdev) { struct list_head *pos = NULL; + struct list_head *tmplist; struct vme_master_resource *master_image; struct vme_slave_resource *slave_image; struct vme_dma_resource *dma_ctrlr; @@ -2589,21 +2590,21 @@ static void tsi148_remove(struct pci_dev *pdev) tsi148_crcsr_exit(tsi148_bridge, pdev); /* resources are stored in link list */ - list_for_each(pos, &tsi148_bridge->dma_resources) { + list_for_each_safe(pos, tmplist, &tsi148_bridge->dma_resources) { dma_ctrlr = list_entry(pos, struct vme_dma_resource, list); list_del(pos); kfree(dma_ctrlr); } /* resources are stored in link list */ - list_for_each(pos, &tsi148_bridge->slave_resources) { + list_for_each_safe(pos, tmplist, &tsi148_bridge->slave_resources) { slave_image = list_entry(pos, struct vme_slave_resource, list); list_del(pos); kfree(slave_image); } /* resources are stored in link list */ - list_for_each(pos, &tsi148_bridge->master_resources) { + list_for_each_safe(pos, tmplist, &tsi148_bridge->master_resources) { master_image = list_entry(pos, struct vme_master_resource, list); list_del(pos); -- cgit v1.2.3 From b12ef0b1f5d0358bc13cc716155d6e9b5584af48 Mon Sep 17 00:00:00 2001 From: "Emilio G. Cota" Date: Fri, 12 Nov 2010 11:14:40 +0000 Subject: staging: vme: tsi148: remove double freeing of the IRQ in .remove tsi148_irq_exit is called twice in .remove, which causes an oops. Remove the second call, which apart from being redundant cannot possibly work; the CR/CSR space has been already unmapped. Signed-off-by: Emilio G. Cota Acked-by: Martyn Welch Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vme/bridges/vme_tsi148.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/staging/vme/bridges/vme_tsi148.c b/drivers/staging/vme/bridges/vme_tsi148.c index 5c25cd8c9209..2f8f399df85b 100644 --- a/drivers/staging/vme/bridges/vme_tsi148.c +++ b/drivers/staging/vme/bridges/vme_tsi148.c @@ -2611,8 +2611,6 @@ static void tsi148_remove(struct pci_dev *pdev) kfree(master_image); } - tsi148_irq_exit(bridge, pdev); - iounmap(bridge->base); pci_release_regions(pdev); -- cgit v1.2.3 From a82ad05ecd9dbd909509a332d3aa5f4ac439a054 Mon Sep 17 00:00:00 2001 From: "Emilio G. Cota" Date: Fri, 12 Nov 2010 11:14:47 +0000 Subject: staging: vme: tsi148: fix warning in free_irq The cookie passed to request_irq isn't the same as the one passed to free_irq, which results in the following warning: [ 63.243533] WARNING: at kernel/irq/manage.c:899 __free_irq+0x9b/0x17d() [ 63.243533] Hardware name: [ 63.243533] Trying to free already-free IRQ 17 [ 63.243533] Modules linked in: vme_tsi148(-) vme e1000e iTCO_wdt iTCO_vendor_support [last unloaded: scsi_wait_scan] [ 63.243533] Pid: 2013, comm: rmmod Not tainted 2.6.35 #2 [ 63.243533] Call Trace: [ 63.243533] [] warn_slowpath_common+0x80/0x98 [ 63.243533] [] warn_slowpath_fmt+0x41/0x43 [ 63.243533] [] __free_irq+0x9b/0x17d [ 63.243533] [] free_irq+0x33/0x4e [ 63.243533] [] tsi148_irq_exit+0x6b/0x70 [vme_tsi148] [...] [ 63.243533] ---[ end trace bbf92311d969efb4 ]--- Fix it by passing the same cookie to both functions. Signed-off-by: Emilio G. Cota [martyn.welch@ge.com: modified to remove checkpatch warnings] Signed-off-by: Martyn Welch Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vme/bridges/Module.symvers | 0 drivers/staging/vme/bridges/vme_tsi148.c | 11 +++++++---- 2 files changed, 7 insertions(+), 4 deletions(-) create mode 100644 drivers/staging/vme/bridges/Module.symvers diff --git a/drivers/staging/vme/bridges/Module.symvers b/drivers/staging/vme/bridges/Module.symvers new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/drivers/staging/vme/bridges/vme_tsi148.c b/drivers/staging/vme/bridges/vme_tsi148.c index 2f8f399df85b..70c9e41154e7 100644 --- a/drivers/staging/vme/bridges/vme_tsi148.c +++ b/drivers/staging/vme/bridges/vme_tsi148.c @@ -374,8 +374,11 @@ static int tsi148_irq_init(struct vme_bridge *tsi148_bridge) return 0; } -static void tsi148_irq_exit(struct tsi148_driver *bridge, struct pci_dev *pdev) +static void tsi148_irq_exit(struct vme_bridge *tsi148_bridge, + struct pci_dev *pdev) { + struct tsi148_driver *bridge = tsi148_bridge->driver_priv; + /* Turn off interrupts */ iowrite32be(0x0, bridge->base + TSI148_LCSR_INTEO); iowrite32be(0x0, bridge->base + TSI148_LCSR_INTEN); @@ -384,7 +387,7 @@ static void tsi148_irq_exit(struct tsi148_driver *bridge, struct pci_dev *pdev) iowrite32be(0xFFFFFFFF, bridge->base + TSI148_LCSR_INTC); /* Detach interrupt handler */ - free_irq(pdev->irq, pdev); + free_irq(pdev->irq, tsi148_bridge); } /* @@ -2511,7 +2514,7 @@ err_master: kfree(master_image); } - tsi148_irq_exit(tsi148_device, pdev); + tsi148_irq_exit(tsi148_bridge, pdev); err_irq: err_test: iounmap(tsi148_device->base); @@ -2583,7 +2586,7 @@ static void tsi148_remove(struct pci_dev *pdev) iowrite32be(0x0, bridge->base + TSI148_LCSR_INTM1); iowrite32be(0x0, bridge->base + TSI148_LCSR_INTM2); - tsi148_irq_exit(bridge, pdev); + tsi148_irq_exit(tsi148_bridge, pdev); vme_unregister_bridge(tsi148_bridge); -- cgit v1.2.3 From 84295e0b243cba070fcfe8be825c39827ea022e6 Mon Sep 17 00:00:00 2001 From: "Emilio G. Cota" Date: Fri, 12 Nov 2010 11:14:54 +0000 Subject: staging: vme: tsi148: remove unreachable line Signed-off-by: Emilio G. Cota Acked-by: Martyn Welch Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vme/bridges/vme_tsi148.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/staging/vme/bridges/vme_tsi148.c b/drivers/staging/vme/bridges/vme_tsi148.c index 70c9e41154e7..e79a5fad458c 100644 --- a/drivers/staging/vme/bridges/vme_tsi148.c +++ b/drivers/staging/vme/bridges/vme_tsi148.c @@ -2480,7 +2480,6 @@ static int tsi148_probe(struct pci_dev *pdev, const struct pci_device_id *id) return 0; - vme_unregister_bridge(tsi148_bridge); err_reg: tsi148_crcsr_exit(tsi148_bridge, pdev); err_crcsr: -- cgit v1.2.3 From 5ade6c4d79377efc371ac89db07e4f6594d1286a Mon Sep 17 00:00:00 2001 From: "Emilio G. Cota" Date: Fri, 12 Nov 2010 11:15:00 +0000 Subject: staging: vme: tsi148: declare static functions as such Signed-off-by: Emilio G. Cota [martyn.welch@ge.com: modified to remove checkpatch warnings] Signed-off-by: Martyn Welch Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vme/bridges/vme_tsi148.c | 43 ++++++++++++++++---------------- 1 file changed, 22 insertions(+), 21 deletions(-) diff --git a/drivers/staging/vme/bridges/vme_tsi148.c b/drivers/staging/vme/bridges/vme_tsi148.c index e79a5fad458c..9550b4a8f93a 100644 --- a/drivers/staging/vme/bridges/vme_tsi148.c +++ b/drivers/staging/vme/bridges/vme_tsi148.c @@ -393,7 +393,7 @@ static void tsi148_irq_exit(struct vme_bridge *tsi148_bridge, /* * Check to see if an IACk has been received, return true (1) or false (0). */ -int tsi148_iack_received(struct tsi148_driver *bridge) +static int tsi148_iack_received(struct tsi148_driver *bridge) { u32 tmp; @@ -408,7 +408,7 @@ int tsi148_iack_received(struct tsi148_driver *bridge) /* * Configure VME interrupt */ -void tsi148_irq_set(struct vme_bridge *tsi148_bridge, int level, +static void tsi148_irq_set(struct vme_bridge *tsi148_bridge, int level, int state, int sync) { struct pci_dev *pdev; @@ -448,7 +448,8 @@ void tsi148_irq_set(struct vme_bridge *tsi148_bridge, int level, * Generate a VME bus interrupt at the requested level & vector. Wait for * interrupt to be acked. */ -int tsi148_irq_generate(struct vme_bridge *tsi148_bridge, int level, int statid) +static int tsi148_irq_generate(struct vme_bridge *tsi148_bridge, int level, + int statid) { u32 tmp; struct tsi148_driver *bridge; @@ -548,7 +549,7 @@ static void tsi148_clear_errors(struct vme_bridge *tsi148_bridge, /* * Initialize a slave window with the requested attributes. */ -int tsi148_slave_set(struct vme_slave_resource *image, int enabled, +static int tsi148_slave_set(struct vme_slave_resource *image, int enabled, unsigned long long vme_base, unsigned long long size, dma_addr_t pci_base, vme_address_t aspace, vme_cycle_t cycle) { @@ -698,7 +699,7 @@ int tsi148_slave_set(struct vme_slave_resource *image, int enabled, /* * Get slave window configuration. */ -int tsi148_slave_get(struct vme_slave_resource *image, int *enabled, +static int tsi148_slave_get(struct vme_slave_resource *image, int *enabled, unsigned long long *vme_base, unsigned long long *size, dma_addr_t *pci_base, vme_address_t *aspace, vme_cycle_t *cycle) { @@ -894,7 +895,7 @@ static void tsi148_free_resource(struct vme_master_resource *image) /* * Set the attributes of an outbound window. */ -int tsi148_master_set(struct vme_master_resource *image, int enabled, +static int tsi148_master_set(struct vme_master_resource *image, int enabled, unsigned long long vme_base, unsigned long long size, vme_address_t aspace, vme_cycle_t cycle, vme_width_t dwidth) { @@ -1130,7 +1131,7 @@ err_window: * * XXX Not parsing prefetch information. */ -int __tsi148_master_get(struct vme_master_resource *image, int *enabled, +static int __tsi148_master_get(struct vme_master_resource *image, int *enabled, unsigned long long *vme_base, unsigned long long *size, vme_address_t *aspace, vme_cycle_t *cycle, vme_width_t *dwidth) { @@ -1240,7 +1241,7 @@ int __tsi148_master_get(struct vme_master_resource *image, int *enabled, } -int tsi148_master_get(struct vme_master_resource *image, int *enabled, +static int tsi148_master_get(struct vme_master_resource *image, int *enabled, unsigned long long *vme_base, unsigned long long *size, vme_address_t *aspace, vme_cycle_t *cycle, vme_width_t *dwidth) { @@ -1256,7 +1257,7 @@ int tsi148_master_get(struct vme_master_resource *image, int *enabled, return retval; } -ssize_t tsi148_master_read(struct vme_master_resource *image, void *buf, +static ssize_t tsi148_master_read(struct vme_master_resource *image, void *buf, size_t count, loff_t offset) { int retval, enabled; @@ -1298,7 +1299,7 @@ skip_chk: } -ssize_t tsi148_master_write(struct vme_master_resource *image, void *buf, +static ssize_t tsi148_master_write(struct vme_master_resource *image, void *buf, size_t count, loff_t offset) { int retval = 0, enabled; @@ -1365,7 +1366,7 @@ skip_chk: * * Requires a previously configured master window, returns final value. */ -unsigned int tsi148_master_rmw(struct vme_master_resource *image, +static unsigned int tsi148_master_rmw(struct vme_master_resource *image, unsigned int mask, unsigned int compare, unsigned int swap, loff_t offset) { @@ -1612,8 +1613,8 @@ static int tsi148_dma_set_vme_dest_attributes(struct device *dev, u32 *attr, /* * Add a link list descriptor to the list */ -int tsi148_dma_list_add(struct vme_dma_list *list, struct vme_dma_attr *src, - struct vme_dma_attr *dest, size_t count) +static int tsi148_dma_list_add(struct vme_dma_list *list, + struct vme_dma_attr *src, struct vme_dma_attr *dest, size_t count) { struct tsi148_dma_entry *entry, *prev; u32 address_high, address_low; @@ -1785,7 +1786,7 @@ static int tsi148_dma_busy(struct vme_bridge *tsi148_bridge, int channel) * * XXX Need to provide control register configuration. */ -int tsi148_dma_list_exec(struct vme_dma_list *list) +static int tsi148_dma_list_exec(struct vme_dma_list *list) { struct vme_dma_resource *ctrlr; int channel, retval = 0; @@ -1865,7 +1866,7 @@ int tsi148_dma_list_exec(struct vme_dma_list *list) * * We have a separate function, don't assume that the chain can't be reused. */ -int tsi148_dma_list_empty(struct vme_dma_list *list) +static int tsi148_dma_list_empty(struct vme_dma_list *list) { struct list_head *pos, *temp; struct tsi148_dma_entry *entry; @@ -1887,7 +1888,7 @@ int tsi148_dma_list_empty(struct vme_dma_list *list) * This does not enable the LM monitor - that should be done when the first * callback is attached and disabled when the last callback is removed. */ -int tsi148_lm_set(struct vme_lm_resource *lm, unsigned long long lm_base, +static int tsi148_lm_set(struct vme_lm_resource *lm, unsigned long long lm_base, vme_address_t aspace, vme_cycle_t cycle) { u32 lm_base_high, lm_base_low, lm_ctl = 0; @@ -1954,8 +1955,8 @@ int tsi148_lm_set(struct vme_lm_resource *lm, unsigned long long lm_base, /* Get configuration of the callback monitor and return whether it is enabled * or disabled. */ -int tsi148_lm_get(struct vme_lm_resource *lm, unsigned long long *lm_base, - vme_address_t *aspace, vme_cycle_t *cycle) +static int tsi148_lm_get(struct vme_lm_resource *lm, + unsigned long long *lm_base, vme_address_t *aspace, vme_cycle_t *cycle) { u32 lm_base_high, lm_base_low, lm_ctl, enabled = 0; struct tsi148_driver *bridge; @@ -2005,7 +2006,7 @@ int tsi148_lm_get(struct vme_lm_resource *lm, unsigned long long *lm_base, * * Callback will be passed the monitor triggered. */ -int tsi148_lm_attach(struct vme_lm_resource *lm, int monitor, +static int tsi148_lm_attach(struct vme_lm_resource *lm, int monitor, void (*callback)(int)) { u32 lm_ctl, tmp; @@ -2060,7 +2061,7 @@ int tsi148_lm_attach(struct vme_lm_resource *lm, int monitor, /* * Detach a callback function forn a specific location monitor. */ -int tsi148_lm_detach(struct vme_lm_resource *lm, int monitor) +static int tsi148_lm_detach(struct vme_lm_resource *lm, int monitor) { u32 lm_en, tmp; struct tsi148_driver *bridge; @@ -2100,7 +2101,7 @@ int tsi148_lm_detach(struct vme_lm_resource *lm, int monitor) /* * Determine Geographical Addressing */ -int tsi148_slot_get(struct vme_bridge *tsi148_bridge) +static int tsi148_slot_get(struct vme_bridge *tsi148_bridge) { u32 slot = 0; struct tsi148_driver *bridge; -- cgit v1.2.3 From efbb979d1b31638a95d76b5acf65cf00a3213fe4 Mon Sep 17 00:00:00 2001 From: "Emilio G. Cota" Date: Fri, 12 Nov 2010 11:15:07 +0000 Subject: staging: vme: ca91cx42: declare static functions as such Signed-off-by: Emilio G. Cota [martyn.welch@ge.com: modified to remove checkpatch warnings] Signed-off-by: Martyn Welch Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vme/bridges/vme_ca91cx42.c | 52 +++++++++++++++--------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/drivers/staging/vme/bridges/vme_ca91cx42.c b/drivers/staging/vme/bridges/vme_ca91cx42.c index 1f2089ff7f9f..3ddc93ba7049 100644 --- a/drivers/staging/vme/bridges/vme_ca91cx42.c +++ b/drivers/staging/vme/bridges/vme_ca91cx42.c @@ -259,8 +259,8 @@ static void ca91cx42_irq_exit(struct ca91cx42_driver *bridge, /* * Set up an VME interrupt */ -void ca91cx42_irq_set(struct vme_bridge *ca91cx42_bridge, int level, int state, - int sync) +static void ca91cx42_irq_set(struct vme_bridge *ca91cx42_bridge, int level, + int state, int sync) { struct pci_dev *pdev; @@ -287,7 +287,7 @@ void ca91cx42_irq_set(struct vme_bridge *ca91cx42_bridge, int level, int state, } } -int ca91cx42_irq_generate(struct vme_bridge *ca91cx42_bridge, int level, +static int ca91cx42_irq_generate(struct vme_bridge *ca91cx42_bridge, int level, int statid) { u32 tmp; @@ -323,7 +323,7 @@ int ca91cx42_irq_generate(struct vme_bridge *ca91cx42_bridge, int level, return 0; } -int ca91cx42_slave_set(struct vme_slave_resource *image, int enabled, +static int ca91cx42_slave_set(struct vme_slave_resource *image, int enabled, unsigned long long vme_base, unsigned long long size, dma_addr_t pci_base, vme_address_t aspace, vme_cycle_t cycle) { @@ -429,7 +429,7 @@ int ca91cx42_slave_set(struct vme_slave_resource *image, int enabled, return 0; } -int ca91cx42_slave_get(struct vme_slave_resource *image, int *enabled, +static int ca91cx42_slave_get(struct vme_slave_resource *image, int *enabled, unsigned long long *vme_base, unsigned long long *size, dma_addr_t *pci_base, vme_address_t *aspace, vme_cycle_t *cycle) { @@ -584,7 +584,7 @@ static void ca91cx42_free_resource(struct vme_master_resource *image) } -int ca91cx42_master_set(struct vme_master_resource *image, int enabled, +static int ca91cx42_master_set(struct vme_master_resource *image, int enabled, unsigned long long vme_base, unsigned long long size, vme_address_t aspace, vme_cycle_t cycle, vme_width_t dwidth) { @@ -741,8 +741,8 @@ err_window: return retval; } -int __ca91cx42_master_get(struct vme_master_resource *image, int *enabled, - unsigned long long *vme_base, unsigned long long *size, +static int __ca91cx42_master_get(struct vme_master_resource *image, + int *enabled, unsigned long long *vme_base, unsigned long long *size, vme_address_t *aspace, vme_cycle_t *cycle, vme_width_t *dwidth) { unsigned int i, ctl; @@ -828,7 +828,7 @@ int __ca91cx42_master_get(struct vme_master_resource *image, int *enabled, return 0; } -int ca91cx42_master_get(struct vme_master_resource *image, int *enabled, +static int ca91cx42_master_get(struct vme_master_resource *image, int *enabled, unsigned long long *vme_base, unsigned long long *size, vme_address_t *aspace, vme_cycle_t *cycle, vme_width_t *dwidth) { @@ -844,8 +844,8 @@ int ca91cx42_master_get(struct vme_master_resource *image, int *enabled, return retval; } -ssize_t ca91cx42_master_read(struct vme_master_resource *image, void *buf, - size_t count, loff_t offset) +static ssize_t ca91cx42_master_read(struct vme_master_resource *image, + void *buf, size_t count, loff_t offset) { ssize_t retval; void *addr = image->kern_base + offset; @@ -904,8 +904,8 @@ out: return retval; } -ssize_t ca91cx42_master_write(struct vme_master_resource *image, void *buf, - size_t count, loff_t offset) +static ssize_t ca91cx42_master_write(struct vme_master_resource *image, + void *buf, size_t count, loff_t offset) { ssize_t retval; void *addr = image->kern_base + offset; @@ -959,7 +959,7 @@ out: return retval; } -unsigned int ca91cx42_master_rmw(struct vme_master_resource *image, +static unsigned int ca91cx42_master_rmw(struct vme_master_resource *image, unsigned int mask, unsigned int compare, unsigned int swap, loff_t offset) { @@ -1015,8 +1015,8 @@ out: return result; } -int ca91cx42_dma_list_add(struct vme_dma_list *list, struct vme_dma_attr *src, - struct vme_dma_attr *dest, size_t count) +static int ca91cx42_dma_list_add(struct vme_dma_list *list, + struct vme_dma_attr *src, struct vme_dma_attr *dest, size_t count) { struct ca91cx42_dma_entry *entry, *prev; struct vme_dma_pci *pci_attr; @@ -1176,7 +1176,7 @@ static int ca91cx42_dma_busy(struct vme_bridge *ca91cx42_bridge) return 1; } -int ca91cx42_dma_list_exec(struct vme_dma_list *list) +static int ca91cx42_dma_list_exec(struct vme_dma_list *list) { struct vme_dma_resource *ctrlr; struct ca91cx42_dma_entry *entry; @@ -1258,7 +1258,7 @@ int ca91cx42_dma_list_exec(struct vme_dma_list *list) } -int ca91cx42_dma_list_empty(struct vme_dma_list *list) +static int ca91cx42_dma_list_empty(struct vme_dma_list *list) { struct list_head *pos, *temp; struct ca91cx42_dma_entry *entry; @@ -1280,8 +1280,8 @@ int ca91cx42_dma_list_empty(struct vme_dma_list *list) * This does not enable the LM monitor - that should be done when the first * callback is attached and disabled when the last callback is removed. */ -int ca91cx42_lm_set(struct vme_lm_resource *lm, unsigned long long lm_base, - vme_address_t aspace, vme_cycle_t cycle) +static int ca91cx42_lm_set(struct vme_lm_resource *lm, + unsigned long long lm_base, vme_address_t aspace, vme_cycle_t cycle) { u32 temp_base, lm_ctl = 0; int i; @@ -1348,8 +1348,8 @@ int ca91cx42_lm_set(struct vme_lm_resource *lm, unsigned long long lm_base, /* Get configuration of the callback monitor and return whether it is enabled * or disabled. */ -int ca91cx42_lm_get(struct vme_lm_resource *lm, unsigned long long *lm_base, - vme_address_t *aspace, vme_cycle_t *cycle) +static int ca91cx42_lm_get(struct vme_lm_resource *lm, + unsigned long long *lm_base, vme_address_t *aspace, vme_cycle_t *cycle) { u32 lm_ctl, enabled = 0; struct ca91cx42_driver *bridge; @@ -1391,7 +1391,7 @@ int ca91cx42_lm_get(struct vme_lm_resource *lm, unsigned long long *lm_base, * * Callback will be passed the monitor triggered. */ -int ca91cx42_lm_attach(struct vme_lm_resource *lm, int monitor, +static int ca91cx42_lm_attach(struct vme_lm_resource *lm, int monitor, void (*callback)(int)) { u32 lm_ctl, tmp; @@ -1440,7 +1440,7 @@ int ca91cx42_lm_attach(struct vme_lm_resource *lm, int monitor, /* * Detach a callback function forn a specific location monitor. */ -int ca91cx42_lm_detach(struct vme_lm_resource *lm, int monitor) +static int ca91cx42_lm_detach(struct vme_lm_resource *lm, int monitor) { u32 tmp; struct ca91cx42_driver *bridge; @@ -1473,7 +1473,7 @@ int ca91cx42_lm_detach(struct vme_lm_resource *lm, int monitor) return 0; } -int ca91cx42_slot_get(struct vme_bridge *ca91cx42_bridge) +static int ca91cx42_slot_get(struct vme_bridge *ca91cx42_bridge) { u32 slot = 0; struct ca91cx42_driver *bridge; @@ -1832,7 +1832,7 @@ err_struct: } -void ca91cx42_remove(struct pci_dev *pdev) +static void ca91cx42_remove(struct pci_dev *pdev) { struct list_head *pos = NULL; struct vme_master_resource *master_image; -- cgit v1.2.3 From b9cc293486e27f4d29a9813da6ebcb8574071dfa Mon Sep 17 00:00:00 2001 From: "Emilio G. Cota" Date: Fri, 12 Nov 2010 11:15:14 +0000 Subject: staging: vme_user: declare private variables as static Signed-off-by: Emilio G. Cota [martyn.welch@ge.com: modified to remove checkpatch warnings] Signed-off-by: Martyn Welch Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vme/devices/vme_user.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/vme/devices/vme_user.c b/drivers/staging/vme/devices/vme_user.c index bdc4e1ecfaf3..f7fa02d0d87b 100644 --- a/drivers/staging/vme/devices/vme_user.c +++ b/drivers/staging/vme/devices/vme_user.c @@ -114,9 +114,9 @@ typedef struct { } driver_stats_t; static driver_stats_t statistics; -struct cdev *vme_user_cdev; /* Character device */ -struct class *vme_user_sysfs_class; /* Sysfs class */ -struct device *vme_user_bridge; /* Pointer to the bridge device */ +static struct cdev *vme_user_cdev; /* Character device */ +static struct class *vme_user_sysfs_class; /* Sysfs class */ +static struct device *vme_user_bridge; /* Pointer to bridge device */ static const int type[VME_DEVS] = { MASTER_MINOR, MASTER_MINOR, -- cgit v1.2.3 From c949231838006d7de4ad38be38d9e112826862da Mon Sep 17 00:00:00 2001 From: "Emilio G. Cota" Date: Fri, 12 Nov 2010 11:15:21 +0000 Subject: staging: vme_user: use an unsigned int for counting the number of kparams unsigned int is what struct kparam_array internally uses. Signed-off-by: Emilio G. Cota Acked-by: Martyn Welch Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vme/devices/vme_user.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/vme/devices/vme_user.c b/drivers/staging/vme/devices/vme_user.c index f7fa02d0d87b..7c61adc8eb79 100644 --- a/drivers/staging/vme/devices/vme_user.c +++ b/drivers/staging/vme/devices/vme_user.c @@ -44,7 +44,7 @@ static DEFINE_MUTEX(vme_user_mutex); static char driver_name[] = "vme_user"; static int bus[USER_BUS_MAX]; -static int bus_num; +static unsigned int bus_num; /* Currently Documentation/devices.txt defines the following for VME: * -- cgit v1.2.3 From 0a81a0f768e5bb0c32db6e44440c5b7c1b4658e7 Mon Sep 17 00:00:00 2001 From: "Emilio G. Cota" Date: Fri, 12 Nov 2010 11:15:27 +0000 Subject: staging: vme_user: remove __iomem marking from kern_buf and derivates kern_buf is not iomem; it comes from kmalloc and is directly dereferenced. Signed-off-by: Emilio G. Cota Acked-by: Martyn Welch Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vme/devices/vme_user.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/vme/devices/vme_user.c b/drivers/staging/vme/devices/vme_user.c index 7c61adc8eb79..5d3a39bcd2a8 100644 --- a/drivers/staging/vme/devices/vme_user.c +++ b/drivers/staging/vme/devices/vme_user.c @@ -92,7 +92,7 @@ static unsigned int bus_num; * Structure to handle image related parameters. */ typedef struct { - void __iomem *kern_buf; /* Buffer address in kernel space */ + void *kern_buf; /* Buffer address in kernel space */ dma_addr_t pci_buf; /* Buffer address in PCI address space */ unsigned long long size_buf; /* Buffer size */ struct semaphore sem; /* Semaphore for locking image */ @@ -277,7 +277,7 @@ static ssize_t resource_from_user(unsigned int minor, const char *buf, static ssize_t buffer_to_user(unsigned int minor, char __user *buf, size_t count, loff_t *ppos) { - void __iomem *image_ptr; + void *image_ptr; ssize_t retval; image_ptr = image[minor].kern_buf + *ppos; @@ -296,7 +296,7 @@ static ssize_t buffer_to_user(unsigned int minor, char __user *buf, static ssize_t buffer_from_user(unsigned int minor, const char *buf, size_t count, loff_t *ppos) { - void __iomem *image_ptr; + void *image_ptr; size_t retval; image_ptr = image[minor].kern_buf + *ppos; -- cgit v1.2.3 From 1a85f2073d99080ea70962f767edca479c768b6e Mon Sep 17 00:00:00 2001 From: "Emilio G. Cota" Date: Fri, 12 Nov 2010 11:15:34 +0000 Subject: staging: vme_user: mark user-space buffers with __user Signed-off-by: Emilio G. Cota [martyn.welch@ge.com: modified to remove checkpatch warnings] Signed-off-by: Martyn Welch Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vme/devices/vme_user.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/drivers/staging/vme/devices/vme_user.c b/drivers/staging/vme/devices/vme_user.c index 5d3a39bcd2a8..36381489b797 100644 --- a/drivers/staging/vme/devices/vme_user.c +++ b/drivers/staging/vme/devices/vme_user.c @@ -129,8 +129,9 @@ static const int type[VME_DEVS] = { MASTER_MINOR, MASTER_MINOR, static int vme_user_open(struct inode *, struct file *); static int vme_user_release(struct inode *, struct file *); -static ssize_t vme_user_read(struct file *, char *, size_t, loff_t *); -static ssize_t vme_user_write(struct file *, const char *, size_t, loff_t *); +static ssize_t vme_user_read(struct file *, char __user *, size_t, loff_t *); +static ssize_t vme_user_write(struct file *, const char __user *, size_t, + loff_t *); static loff_t vme_user_llseek(struct file *, loff_t, int); static long vme_user_unlocked_ioctl(struct file *, unsigned int, unsigned long); @@ -246,7 +247,7 @@ static ssize_t resource_to_user(int minor, char __user *buf, size_t count, * page) transfers will lock the user space buffer into memory and then * transfer the data directly from the user space buffers out to VME. */ -static ssize_t resource_from_user(unsigned int minor, const char *buf, +static ssize_t resource_from_user(unsigned int minor, const char __user *buf, size_t count, loff_t *ppos) { ssize_t retval; @@ -293,7 +294,7 @@ static ssize_t buffer_to_user(unsigned int minor, char __user *buf, return retval; } -static ssize_t buffer_from_user(unsigned int minor, const char *buf, +static ssize_t buffer_from_user(unsigned int minor, const char __user *buf, size_t count, loff_t *ppos) { void *image_ptr; @@ -312,7 +313,7 @@ static ssize_t buffer_from_user(unsigned int minor, const char *buf, return retval; } -static ssize_t vme_user_read(struct file *file, char *buf, size_t count, +static ssize_t vme_user_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) { unsigned int minor = MINOR(file->f_dentry->d_inode->i_rdev); @@ -356,8 +357,8 @@ static ssize_t vme_user_read(struct file *file, char *buf, size_t count, return retval; } -static ssize_t vme_user_write(struct file *file, const char *buf, size_t count, - loff_t *ppos) +static ssize_t vme_user_write(struct file *file, const char __user *buf, + size_t count, loff_t *ppos) { unsigned int minor = MINOR(file->f_dentry->d_inode->i_rdev); ssize_t retval; @@ -455,6 +456,7 @@ static int vme_user_ioctl(struct inode *inode, struct file *file, unsigned int minor = MINOR(inode->i_rdev); int retval; dma_addr_t pci_addr; + void __user *argp = (void __user *)arg; statistics.ioctls++; @@ -474,7 +476,7 @@ static int vme_user_ioctl(struct inode *inode, struct file *file, &master.size, &master.aspace, &master.cycle, &master.dwidth); - copied = copy_to_user((char *)arg, &master, + copied = copy_to_user(argp, &master, sizeof(struct vme_master)); if (copied != 0) { printk(KERN_WARNING "Partial copy to " @@ -487,8 +489,7 @@ static int vme_user_ioctl(struct inode *inode, struct file *file, case VME_SET_MASTER: - copied = copy_from_user(&master, (char *)arg, - sizeof(master)); + copied = copy_from_user(&master, argp, sizeof(master)); if (copied != 0) { printk(KERN_WARNING "Partial copy from " "userspace\n"); @@ -518,7 +519,7 @@ static int vme_user_ioctl(struct inode *inode, struct file *file, &slave.size, &pci_addr, &slave.aspace, &slave.cycle); - copied = copy_to_user((char *)arg, &slave, + copied = copy_to_user(argp, &slave, sizeof(struct vme_slave)); if (copied != 0) { printk(KERN_WARNING "Partial copy to " @@ -531,8 +532,7 @@ static int vme_user_ioctl(struct inode *inode, struct file *file, case VME_SET_SLAVE: - copied = copy_from_user(&slave, (char *)arg, - sizeof(slave)); + copied = copy_from_user(&slave, argp, sizeof(slave)); if (copied != 0) { printk(KERN_WARNING "Partial copy from " "userspace\n"); -- cgit v1.2.3 From 0599726793d6dca6bd171cd4e497f9aac21e8f0c Mon Sep 17 00:00:00 2001 From: "Emilio G. Cota" Date: Fri, 12 Nov 2010 11:15:40 +0000 Subject: staging: vme: mark struct vme_master_resource's base address pointer as __iomem Signed-off-by: Emilio G. Cota Acked-by: Martyn Welch Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vme/vme_bridge.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/vme/vme_bridge.h b/drivers/staging/vme/vme_bridge.h index b653ec02e1fc..4c6ec31b01db 100644 --- a/drivers/staging/vme/vme_bridge.h +++ b/drivers/staging/vme/vme_bridge.h @@ -20,7 +20,7 @@ struct vme_master_resource { vme_cycle_t cycle_attr; vme_width_t width_attr; struct resource bus_resource; - void *kern_base; + void __iomem *kern_base; }; struct vme_slave_resource { -- cgit v1.2.3 From e20cbcf199e2c3e4a4822e890726c49b70a4d280 Mon Sep 17 00:00:00 2001 From: "Emilio G. Cota" Date: Fri, 12 Nov 2010 11:15:47 +0000 Subject: staging: vme: tsi148: mark the registers' base address pointer as __iomem Signed-off-by: Emilio G. Cota Acked-by: Martyn Welch Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vme/bridges/vme_tsi148.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/vme/bridges/vme_tsi148.h b/drivers/staging/vme/bridges/vme_tsi148.h index bda64ef85754..9f97fa8084e8 100644 --- a/drivers/staging/vme/bridges/vme_tsi148.h +++ b/drivers/staging/vme/bridges/vme_tsi148.h @@ -35,7 +35,7 @@ /* Structure used to hold driver specific information */ struct tsi148_driver { - void *base; /* Base Address of device registers */ + void __iomem *base; /* Base Address of device registers */ wait_queue_head_t dma_queue[2]; wait_queue_head_t iack_queue; void (*lm_callback[4])(int); /* Called in interrupt handler */ -- cgit v1.2.3 From e08e02faff68d33c938fd0322c0f8318a25ddb39 Mon Sep 17 00:00:00 2001 From: "Emilio G. Cota" Date: Fri, 12 Nov 2010 11:15:54 +0000 Subject: staging: vme: ca91cx42: mark the registers' base address pointer as __iomem Signed-off-by: Emilio G. Cota Acked-by: Martyn Welch Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vme/bridges/vme_ca91cx42.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/vme/bridges/vme_ca91cx42.h b/drivers/staging/vme/bridges/vme_ca91cx42.h index e72c65b193ec..02a7c794db05 100644 --- a/drivers/staging/vme/bridges/vme_ca91cx42.h +++ b/drivers/staging/vme/bridges/vme_ca91cx42.h @@ -39,7 +39,7 @@ /* Structure used to hold driver specific information */ struct ca91cx42_driver { - void *base; /* Base Address of device registers */ + void __iomem *base; /* Base Address of device registers */ wait_queue_head_t dma_queue; wait_queue_head_t iack_queue; wait_queue_head_t mbox_queue; -- cgit v1.2.3 From f96c377ead5ed308f0cf18b9156f86fdf207a288 Mon Sep 17 00:00:00 2001 From: Nicolas Kaiser Date: Sat, 13 Nov 2010 19:43:27 +0100 Subject: staging: comedi: fix typo in error message Fix typo in error message of dux commands allocation. Signed-off-by: Nicolas Kaiser Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/usbdux.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/comedi/drivers/usbdux.c b/drivers/staging/comedi/drivers/usbdux.c index 1f177a67ff11..aca4d140193b 100644 --- a/drivers/staging/comedi/drivers/usbdux.c +++ b/drivers/staging/comedi/drivers/usbdux.c @@ -2398,7 +2398,7 @@ static int usbduxsub_probe(struct usb_interface *uinterf, usbduxsub[index].dux_commands = kzalloc(SIZEOFDUXBUFFER, GFP_KERNEL); if (!usbduxsub[index].dux_commands) { dev_err(dev, "comedi_: usbdux: " - "error alloc space for dac commands\n"); + "error alloc space for dux commands\n"); tidy_up(&(usbduxsub[index])); up(&start_stop_sem); return -ENOMEM; -- cgit v1.2.3 From baebc160c12ba88baf201d35ecc22f1e250aad3f Mon Sep 17 00:00:00 2001 From: Brett Rudley Date: Fri, 12 Nov 2010 15:28:30 -0800 Subject: staging: brcm80211: simplify pci_config_read/write osl routines. Start simplifying osl with goal of purging it entirely. Signed-off-by: Brett Rudley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/util/linux_osl.c | 47 ++++-------------------------- 1 file changed, 5 insertions(+), 42 deletions(-) diff --git a/drivers/staging/brcm80211/util/linux_osl.c b/drivers/staging/brcm80211/util/linux_osl.c index 7211f8a383ff..461ecbaf8214 100644 --- a/drivers/staging/brcm80211/util/linux_osl.c +++ b/drivers/staging/brcm80211/util/linux_osl.c @@ -30,8 +30,6 @@ #include -#define PCI_CFG_RETRY 10 - #define OS_HANDLE_MAGIC 0x1234abcd /* Magic # to recognise osh */ #define BCM_MEM_FILENAME_LEN 24 /* Mem. filename length */ @@ -139,51 +137,16 @@ void BCMFASTPATH osl_pktfree(osl_t *osh, void *p, bool send) u32 osl_pci_read_config(osl_t *osh, uint offset, uint size) { - uint val = 0; - uint retry = PCI_CFG_RETRY; - - ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); - - /* only 4byte access supported */ - ASSERT(size == 4); - - do { - pci_read_config_dword(osh->pdev, offset, &val); - if (val != 0xffffffff) - break; - } while (retry--); - -#ifdef BCMDBG - if (retry < PCI_CFG_RETRY) - printk("PCI CONFIG READ access to %d required %d retries\n", - offset, (PCI_CFG_RETRY - retry)); -#endif /* BCMDBG */ - + uint val; + pci_read_config_dword(osh->pdev, offset, &val); return val; } void osl_pci_write_config(osl_t *osh, uint offset, uint size, uint val) { - uint retry = PCI_CFG_RETRY; - - ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); - - /* only 4byte access supported */ - ASSERT(size == 4); - - do { - pci_write_config_dword(osh->pdev, offset, val); - if (offset != PCI_BAR0_WIN) - break; - if (osl_pci_read_config(osh, offset, size) == val) - break; - } while (retry--); - -#if defined(BCMDBG) && !defined(BRCM_FULLMAC) - if (retry < PCI_CFG_RETRY) - printk("PCI CONFIG WRITE access to %d required %d retries\n", - offset, (PCI_CFG_RETRY - retry)); -#endif /* BCMDBG */ + pci_write_config_dword(osh->pdev, offset, val); + if (offset == PCI_BAR0_WIN) + ASSERT(osl_pci_read_config(osh, offset, size) == val); } /* return bus # for the pci device pointed by osh->pdev */ -- cgit v1.2.3 From a1dc08b7d95817faea5e6a358e22c6185b84163a Mon Sep 17 00:00:00 2001 From: Brett Rudley Date: Fri, 12 Nov 2010 18:10:17 -0800 Subject: staging: brcm80211: get rid of last bit of pci configspace workaround. Signed-off-by: Brett Rudley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/util/linux_osl.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/drivers/staging/brcm80211/util/linux_osl.c b/drivers/staging/brcm80211/util/linux_osl.c index 461ecbaf8214..625cbacc8665 100644 --- a/drivers/staging/brcm80211/util/linux_osl.c +++ b/drivers/staging/brcm80211/util/linux_osl.c @@ -145,8 +145,6 @@ u32 osl_pci_read_config(osl_t *osh, uint offset, uint size) void osl_pci_write_config(osl_t *osh, uint offset, uint size, uint val) { pci_write_config_dword(osh->pdev, offset, val); - if (offset == PCI_BAR0_WIN) - ASSERT(osl_pci_read_config(osh, offset, size) == val); } /* return bus # for the pci device pointed by osh->pdev */ -- cgit v1.2.3 From 5b93a8b8e0514ebacb49a50c67a8846139bcd1bd Mon Sep 17 00:00:00 2001 From: Mike Rapoport Date: Sun, 14 Nov 2010 13:36:21 +0200 Subject: staging: brcm80211: remove unused osl_pkt{get,free}_static Signed-off-by: Mike Rapoport Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/include/linux_osl.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/staging/brcm80211/include/linux_osl.h b/drivers/staging/brcm80211/include/linux_osl.h index 586e652e75c7..0fb6e1c86793 100644 --- a/drivers/staging/brcm80211/include/linux_osl.h +++ b/drivers/staging/brcm80211/include/linux_osl.h @@ -291,9 +291,6 @@ extern void *osl_pktget(osl_t *osh, uint len); extern void osl_pktfree(osl_t *osh, void *skb, bool send); #ifdef BRCM_FULLMAC -extern void *osl_pktget_static(osl_t *osh, uint len); -extern void osl_pktfree_static(osl_t *osh, void *skb, bool send); - static inline void * osl_pkt_frmnative(osl_pubinfo_t *osh, struct sk_buff *skb) { -- cgit v1.2.3 From ae0d9ebaffe47ed553e715ab5243660c33b6338c Mon Sep 17 00:00:00 2001 From: Mike Rapoport Date: Sun, 14 Nov 2010 13:36:23 +0200 Subject: staging: brcm80211: brcmfmac: remove PXA SDIO controller binding Signed-off-by: Mike Rapoport Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmfmac/bcmsdh_linux.c | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/drivers/staging/brcm80211/brcmfmac/bcmsdh_linux.c b/drivers/staging/brcm80211/brcmfmac/bcmsdh_linux.c index be33696b8f74..b021d97e59fa 100644 --- a/drivers/staging/brcm80211/brcmfmac/bcmsdh_linux.c +++ b/drivers/staging/brcm80211/brcmfmac/bcmsdh_linux.c @@ -137,17 +137,6 @@ static int __devinit bcmsdh_probe(struct device *dev); static int __devexit bcmsdh_remove(struct device *dev); #endif /* BCMLXSDMMC */ -#ifndef BCMLXSDMMC -static struct device_driver bcmsdh_driver = { - .name = "pxa2xx-mci", - .bus = &platform_bus_type, - .probe = bcmsdh_probe, - .remove = bcmsdh_remove, - .suspend = NULL, - .resume = NULL, -}; -#endif /* BCMLXSDMMC */ - #ifndef BCMLXSDMMC static #endif /* BCMLXSDMMC */ @@ -522,9 +511,6 @@ int bcmsdh_register(bcmsdh_driver_t *driver) #if defined(BCMLXSDMMC) SDLX_MSG(("Linux Kernel SDIO/MMC Driver\n")); error = sdio_function_init(); -#else - SDLX_MSG(("Intel PXA270 SDIO Driver\n")); - error = driver_register(&bcmsdh_driver); #endif /* defined(BCMLXSDMMC) */ return error; #endif /* defined(BCMPLATFORM_BUS) */ @@ -544,9 +530,6 @@ extern void sdio_function_cleanup(void); void bcmsdh_unregister(void) { -#if defined(BCMPLATFORM_BUS) && !defined(BCMLXSDMMC) - driver_unregister(&bcmsdh_driver); -#endif #if defined(BCMLXSDMMC) sdio_function_cleanup(); #endif /* BCMLXSDMMC */ -- cgit v1.2.3 From 859171ca92f2865453b4b2e17bf679c67044a833 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Sun, 14 Nov 2010 19:04:48 -0800 Subject: drivers/staging: Remove unnecessary semicolons Signed-off-by: Joe Perches Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c | 2 +- drivers/staging/ath6kl/os/linux/ar6000_drv.c | 2 +- drivers/staging/bcm/InterfaceInit.c | 2 +- drivers/staging/bcm/InterfaceIsr.c | 2 +- drivers/staging/bcm/Misc.c | 4 ++-- drivers/staging/comedi/drivers/addi-data/APCI1710_Tor.c | 2 +- drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.c | 2 +- drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.c | 2 +- drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.c | 2 +- drivers/staging/comedi/drivers/amplc_pci230.c | 2 +- drivers/staging/comedi/drivers/cb_das16_cs.c | 2 +- drivers/staging/comedi/drivers/comedi_bond.c | 2 +- drivers/staging/crystalhd/crystalhd_hw.c | 2 +- drivers/staging/go7007/go7007-driver.c | 2 +- drivers/staging/iio/accel/lis3l02dq_ring.c | 2 +- drivers/staging/intel_sst/intel_sst_drv_interface.c | 4 ++-- drivers/staging/keucr/smilmain.c | 4 ++-- drivers/staging/keucr/smilsub.c | 4 ++-- drivers/staging/msm/lcdc_toshiba_wvga_pt.c | 2 +- drivers/staging/rt2860/common/cmm_data_pci.c | 4 ++-- drivers/staging/rt2860/rt_linux.c | 2 +- drivers/staging/rt2860/rtmp.h | 2 +- drivers/staging/rtl8192e/ieee80211/ieee80211_tx.c | 2 +- drivers/staging/rtl8192e/r819xE_phy.c | 2 +- drivers/staging/rtl8192u/ieee80211/ieee80211_tx.c | 2 +- drivers/staging/rtl8192u/r8192U_core.c | 2 +- drivers/staging/rtl8192u/r819xU_phy.c | 2 +- drivers/staging/rtl8712/rtl8712_efuse.c | 2 +- drivers/staging/rtl8712/rtl8712_xmit.c | 2 +- drivers/staging/rtl8712/rtl871x_xmit.c | 2 +- drivers/staging/tidspbridge/core/tiomap3430.c | 4 ++-- drivers/staging/tidspbridge/rmgr/nldr.c | 2 +- drivers/staging/vt6655/card.c | 2 +- drivers/staging/vt6655/iwctl.c | 2 +- drivers/staging/vt6655/wpa2.c | 4 ++-- drivers/staging/vt6656/baseband.c | 2 +- drivers/staging/vt6656/iwctl.c | 2 +- drivers/staging/vt6656/power.c | 2 +- drivers/staging/vt6656/wpa2.c | 4 ++-- 39 files changed, 47 insertions(+), 47 deletions(-) diff --git a/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c b/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c index 6454a86c174c..e96662b84ed9 100644 --- a/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c +++ b/drivers/staging/ath6kl/hif/sdio/linux_sdio/src/hif.c @@ -876,7 +876,7 @@ HIFAckInterrupt(HIF_DEVICE *device) void HIFUnMaskInterrupt(HIF_DEVICE *device) { - int ret;; + int ret; AR_DEBUG_ASSERT(device != NULL); AR_DEBUG_ASSERT(device->func != NULL); diff --git a/drivers/staging/ath6kl/os/linux/ar6000_drv.c b/drivers/staging/ath6kl/os/linux/ar6000_drv.c index a659f7047373..126a36a2daa6 100644 --- a/drivers/staging/ath6kl/os/linux/ar6000_drv.c +++ b/drivers/staging/ath6kl/os/linux/ar6000_drv.c @@ -4439,7 +4439,7 @@ skip_key: for (i = assoc_req_ie_pos; i < assoc_req_ie_pos + assocReqLen - 4; i++) { AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("%2.2x ", assocInfo[i])); sprintf(pos, "%2.2x", assocInfo[i]); - pos += 2;; + pos += 2; } AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT,("\n")); diff --git a/drivers/staging/bcm/InterfaceInit.c b/drivers/staging/bcm/InterfaceInit.c index 869ebabfba77..7ffbfecaa117 100644 --- a/drivers/staging/bcm/InterfaceInit.c +++ b/drivers/staging/bcm/InterfaceInit.c @@ -236,7 +236,7 @@ usbbcm_device_probe(struct usb_interface *intf, const struct usb_device_id *id) uint32_t uiNackZeroLengthInt=4; if(wrmalt(psAdapter, DISABLE_USB_ZERO_LEN_INT, &uiNackZeroLengthInt, sizeof(uiNackZeroLengthInt))) { - return -EIO;; + return -EIO; } } diff --git a/drivers/staging/bcm/InterfaceIsr.c b/drivers/staging/bcm/InterfaceIsr.c index 423464765e59..220ff922bdcf 100644 --- a/drivers/staging/bcm/InterfaceIsr.c +++ b/drivers/staging/bcm/InterfaceIsr.c @@ -90,7 +90,7 @@ static void read_int_callback(struct urb *urb/*, struct pt_regs *regs*/) BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, INTF_INIT, DBG_LVL_ALL,"Interrupt IN endPoint has got halted/stalled...need to clear this"); Adapter->bEndPointHalted = TRUE ; wake_up(&Adapter->tx_packet_wait_queue); - urb->status = STATUS_SUCCESS ;; + urb->status = STATUS_SUCCESS ; return; } /* software-driven interface shutdown */ diff --git a/drivers/staging/bcm/Misc.c b/drivers/staging/bcm/Misc.c index 1bb6a1d97ce0..023c511c0001 100644 --- a/drivers/staging/bcm/Misc.c +++ b/drivers/staging/bcm/Misc.c @@ -706,7 +706,7 @@ void SendIdleModeResponse(PMINI_ADAPTER Adapter) /* Wake the LED Thread with IDLEMODE_ENTER State */ Adapter->DriverState = LOWPOWER_MODE_ENTER; - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL,"LED Thread is Running..Hence Setting LED Event as IDLEMODE_ENTER jiffies:%ld",jiffies);; + BCM_DEBUG_PRINT(Adapter,DBG_TYPE_RX, RX_DPC, DBG_LVL_ALL,"LED Thread is Running..Hence Setting LED Event as IDLEMODE_ENTER jiffies:%ld",jiffies); wake_up(&Adapter->LEDInfo.notify_led_event); /* Wait for 1 SEC for LED to OFF */ @@ -1277,7 +1277,7 @@ static int bcm_parse_target_params(PMINI_ADAPTER Adapter) void beceem_parse_target_struct(PMINI_ADAPTER Adapter) { - UINT uiHostDrvrCfg6 =0, uiEEPROMFlag = 0;; + UINT uiHostDrvrCfg6 =0, uiEEPROMFlag = 0; if(ntohl(Adapter->pstargetparams->m_u32PhyParameter2) & AUTO_SYNC_DISABLE) { diff --git a/drivers/staging/comedi/drivers/addi-data/APCI1710_Tor.c b/drivers/staging/comedi/drivers/addi-data/APCI1710_Tor.c index 7361d508bf37..0e6affd95962 100644 --- a/drivers/staging/comedi/drivers/addi-data/APCI1710_Tor.c +++ b/drivers/staging/comedi/drivers/addi-data/APCI1710_Tor.c @@ -1008,7 +1008,7 @@ int i_APCI1710_InsnWriteEnableDisableTorCounter(struct comedi_device *dev, b_ExternGate = (unsigned char) data[3]; b_CycleMode = (unsigned char) data[4]; b_InterruptEnable = (unsigned char) data[5]; - i_ReturnValue = insn->n;; + i_ReturnValue = insn->n; devpriv->tsk_Current = current; /* Save the current process task structure */ /**************************/ /* Test the module number */ diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.c index 2a8a6c730920..62f421a06f05 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1500.c @@ -2850,7 +2850,7 @@ static int i_APCI1500_Reset(struct comedi_device *dev) i_Logic = 0; i_CounterLogic = 0; i_InterruptMask = 0; - i_InputChannel = 0;; + i_InputChannel = 0; i_TimerCounter1Enabled = 0; i_TimerCounter2Enabled = 0; i_WatchdogCounter3Enabled = 0; diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.c index 12fcc35ecc52..8a584a014b0b 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci1516.c @@ -335,7 +335,7 @@ int i_APCI1516_WriteDigitalOutput(struct comedi_device *dev, struct comedi_subde return -EINVAL; } /* if else data[3]==1) */ } /* if else data[3]==0) */ - return (insn->n);; + return (insn->n); } /* diff --git a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.c b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.c index 356a1891e2e7..acaceb01629a 100644 --- a/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.c +++ b/drivers/staging/comedi/drivers/addi-data/hwdrv_apci3501.c @@ -339,7 +339,7 @@ int i_APCI3501_ConfigAnalogOutput(struct comedi_device *dev, struct comedi_subde int i_APCI3501_WriteAnalogOutput(struct comedi_device *dev, struct comedi_subdevice *s, struct comedi_insn *insn, unsigned int *data) { - unsigned int ul_Command1 = 0, ul_Channel_no, ul_Polarity, ul_DAC_Ready = 0;; + unsigned int ul_Command1 = 0, ul_Channel_no, ul_Polarity, ul_DAC_Ready = 0; ul_Channel_no = CR_CHAN(insn->chanspec); diff --git a/drivers/staging/comedi/drivers/amplc_pci230.c b/drivers/staging/comedi/drivers/amplc_pci230.c index 5d064577b2f1..7edeb1103dc8 100644 --- a/drivers/staging/comedi/drivers/amplc_pci230.c +++ b/drivers/staging/comedi/drivers/amplc_pci230.c @@ -971,7 +971,7 @@ static int pci230_attach(struct comedi_device *dev, struct comedi_devconfig *it) if (thisboard->ao_chans > 0) { s->type = COMEDI_SUBD_AO; s->subdev_flags = SDF_WRITABLE | SDF_GROUND; - s->n_chan = thisboard->ao_chans;; + s->n_chan = thisboard->ao_chans; s->maxdata = (1 << thisboard->ao_bits) - 1; s->range_table = &pci230_ao_range; s->insn_write = &pci230_ao_winsn; diff --git a/drivers/staging/comedi/drivers/cb_das16_cs.c b/drivers/staging/comedi/drivers/cb_das16_cs.c index 0345b4caba73..bb93685d8b93 100644 --- a/drivers/staging/comedi/drivers/cb_das16_cs.c +++ b/drivers/staging/comedi/drivers/cb_das16_cs.c @@ -169,7 +169,7 @@ static int das16cs_attach(struct comedi_device *dev, if (!link) return -EIO; - dev->iobase = link->resource[0]->start;; + dev->iobase = link->resource[0]->start; printk("I/O base=0x%04lx ", dev->iobase); printk("fingerprint:\n"); diff --git a/drivers/staging/comedi/drivers/comedi_bond.c b/drivers/staging/comedi/drivers/comedi_bond.c index cfcbd9b8f393..d8aefb23d6b9 100644 --- a/drivers/staging/comedi/drivers/comedi_bond.c +++ b/drivers/staging/comedi/drivers/comedi_bond.c @@ -370,7 +370,7 @@ static int doDevConfig(struct comedi_device *dev, struct comedi_devconfig *it) struct comedi_device *devs_opened[COMEDI_NUM_BOARD_MINORS]; memset(devs_opened, 0, sizeof(devs_opened)); - devpriv->name[0] = 0;; + devpriv->name[0] = 0; /* Loop through all comedi devices specified on the command-line, building our device list */ for (i = 0; i < COMEDI_NDEVCONFOPTS && (!i || it->options[i]); ++i) { diff --git a/drivers/staging/crystalhd/crystalhd_hw.c b/drivers/staging/crystalhd/crystalhd_hw.c index f63185790c48..153ddbf4247d 100644 --- a/drivers/staging/crystalhd/crystalhd_hw.c +++ b/drivers/staging/crystalhd/crystalhd_hw.c @@ -1711,7 +1711,7 @@ enum BC_STATUS crystalhd_download_fw(struct crystalhd_adp *adp, void *buffer, ui } BCMLOG(BCMLOG_INFO, "Firmware Downloaded Successfully\n"); - return BC_STS_SUCCESS;; + return BC_STS_SUCCESS; } enum BC_STATUS crystalhd_do_fw_cmd(struct crystalhd_hw *hw, diff --git a/drivers/staging/go7007/go7007-driver.c b/drivers/staging/go7007/go7007-driver.c index b3f42f37a313..8426a02b4bb2 100644 --- a/drivers/staging/go7007/go7007-driver.c +++ b/drivers/staging/go7007/go7007-driver.c @@ -624,7 +624,7 @@ struct go7007 *go7007_alloc(struct go7007_board_info *board, struct device *dev) go->dvd_mode = 0; go->interlace_coding = 0; for (i = 0; i < 4; ++i) - go->modet[i].enable = 0;; + go->modet[i].enable = 0; for (i = 0; i < 1624; ++i) go->modet_map[i] = 0; go->audio_deliver = NULL; diff --git a/drivers/staging/iio/accel/lis3l02dq_ring.c b/drivers/staging/iio/accel/lis3l02dq_ring.c index 330d5d6dbba4..1fd088a11076 100644 --- a/drivers/staging/iio/accel/lis3l02dq_ring.c +++ b/drivers/staging/iio/accel/lis3l02dq_ring.c @@ -517,7 +517,7 @@ int lis3l02dq_configure_ring(struct iio_dev *indio_dev) ret = iio_alloc_pollfunc(indio_dev, NULL, &lis3l02dq_poll_func_th); if (ret) - goto error_iio_sw_rb_free;; + goto error_iio_sw_rb_free; indio_dev->modes |= INDIO_RING_TRIGGERED; return 0; diff --git a/drivers/staging/intel_sst/intel_sst_drv_interface.c b/drivers/staging/intel_sst/intel_sst_drv_interface.c index 5b10ddf60092..1165303eeeb4 100644 --- a/drivers/staging/intel_sst/intel_sst_drv_interface.c +++ b/drivers/staging/intel_sst/intel_sst_drv_interface.c @@ -173,9 +173,9 @@ static int sst_get_sfreq(struct snd_sst_params *str_param) case SST_CODEC_TYPE_MP3: return str_param->sparams.uc.mp3_params.sfreq; case SST_CODEC_TYPE_AAC: - return str_param->sparams.uc.aac_params.sfreq;; + return str_param->sparams.uc.aac_params.sfreq; case SST_CODEC_TYPE_WMA9: - return str_param->sparams.uc.wma_params.sfreq;; + return str_param->sparams.uc.wma_params.sfreq; default: return 0; } diff --git a/drivers/staging/keucr/smilmain.c b/drivers/staging/keucr/smilmain.c index bdfbf76f8df9..2cbe9f897eef 100644 --- a/drivers/staging/keucr/smilmain.c +++ b/drivers/staging/keucr/smilmain.c @@ -153,9 +153,9 @@ int Media_D_ReadSector(struct us_data *us, DWORD start,WORD count,BYTE *buf) WORD len, bn; //if (Check_D_MediaPower()) ; ¦b 6250 don't care - // return(ErrCode); ; + // return(ErrCode); //if (Check_D_MediaFmt(fdoExt)) ; - // return(ErrCode); ; + // return(ErrCode); if (Conv_D_MediaAddr(us, start)) return(ErrCode); diff --git a/drivers/staging/keucr/smilsub.c b/drivers/staging/keucr/smilsub.c index 1b52535a388f..ce10cf215f51 100644 --- a/drivers/staging/keucr/smilsub.c +++ b/drivers/staging/keucr/smilsub.c @@ -763,8 +763,8 @@ int Ssfdc_D_WriteSectForCopy(struct us_data *us, BYTE *buf, BYTE *redundant) bcb->CDB[7] = (BYTE)addr; bcb->CDB[6] = (BYTE)(addr/0x0100); bcb->CDB[5] = Media.Zone/2; - bcb->CDB[8] = *(redundant+REDT_ADDR1H);; - bcb->CDB[9] = *(redundant+REDT_ADDR1L);; + bcb->CDB[8] = *(redundant+REDT_ADDR1H); + bcb->CDB[9] = *(redundant+REDT_ADDR1L); result = ENE_SendScsiCmd(us, FDIR_WRITE, buf, 0); if (result != USB_STOR_XFER_GOOD) diff --git a/drivers/staging/msm/lcdc_toshiba_wvga_pt.c b/drivers/staging/msm/lcdc_toshiba_wvga_pt.c index 864d7c18913d..edba78a3afcf 100644 --- a/drivers/staging/msm/lcdc_toshiba_wvga_pt.c +++ b/drivers/staging/msm/lcdc_toshiba_wvga_pt.c @@ -77,7 +77,7 @@ static void toshiba_spi_write(char cmd, uint32 data, int num) /* followed by parameter bytes */ if (num) { - bp = (char *)&data;; + bp = (char *)&data; bp += (num - 1); while (num) { toshiba_spi_write_byte(1, *bp); diff --git a/drivers/staging/rt2860/common/cmm_data_pci.c b/drivers/staging/rt2860/common/cmm_data_pci.c index 43d73a05c8eb..7af59ff9e220 100644 --- a/drivers/staging/rt2860/common/cmm_data_pci.c +++ b/drivers/staging/rt2860/common/cmm_data_pci.c @@ -137,7 +137,7 @@ u16 RtmpPCI_WriteSingleTxResource(struct rt_rtmp_adapter *pAd, pTxD->SDPtr0 = BufBasePaLow; pTxD->SDLen0 = TXINFO_SIZE + TXWI_SIZE + hwHeaderLen; /* include padding */ - pTxD->SDPtr1 = PCI_MAP_SINGLE(pAd, pTxBlk, 0, 1, PCI_DMA_TODEVICE);; + pTxD->SDPtr1 = PCI_MAP_SINGLE(pAd, pTxBlk, 0, 1, PCI_DMA_TODEVICE); pTxD->SDLen1 = pTxBlk->SrcBufLen; pTxD->LastSec0 = 0; pTxD->LastSec1 = (bIsLast) ? 1 : 0; @@ -215,7 +215,7 @@ u16 RtmpPCI_WriteMultiTxResource(struct rt_rtmp_adapter *pAd, pTxD->SDPtr0 = BufBasePaLow; pTxD->SDLen0 = firstDMALen; /* include padding */ - pTxD->SDPtr1 = PCI_MAP_SINGLE(pAd, pTxBlk, 0, 1, PCI_DMA_TODEVICE);; + pTxD->SDPtr1 = PCI_MAP_SINGLE(pAd, pTxBlk, 0, 1, PCI_DMA_TODEVICE); pTxD->SDLen1 = pTxBlk->SrcBufLen; pTxD->LastSec0 = 0; pTxD->LastSec1 = (bIsLast) ? 1 : 0; diff --git a/drivers/staging/rt2860/rt_linux.c b/drivers/staging/rt2860/rt_linux.c index e680b0d97f74..0bbd04a71a6a 100644 --- a/drivers/staging/rt2860/rt_linux.c +++ b/drivers/staging/rt2860/rt_linux.c @@ -854,7 +854,7 @@ void send_monitor_packets(struct rt_rtmp_adapter *pAd, struct rt_rx_blk *pRxBlk) RSSI1, RSSI_1), ConvertToRssi(pAd, pRxBlk->pRxWI->RSSI2, - RSSI_2));; + RSSI_2)); ph->signal.did = DIDmsg_lnxind_wlansniffrm_signal; ph->signal.status = 0; diff --git a/drivers/staging/rt2860/rtmp.h b/drivers/staging/rt2860/rtmp.h index caf466242a13..70daaa4f9ac2 100644 --- a/drivers/staging/rt2860/rtmp.h +++ b/drivers/staging/rt2860/rtmp.h @@ -2979,7 +2979,7 @@ void LinkDown(struct rt_rtmp_adapter *pAd, IN BOOLEAN IsReqFromAP); void IterateOnBssTab(struct rt_rtmp_adapter *pAd); -void IterateOnBssTab2(struct rt_rtmp_adapter *pAd);; +void IterateOnBssTab2(struct rt_rtmp_adapter *pAd); void JoinParmFill(struct rt_rtmp_adapter *pAd, struct rt_mlme_join_req *JoinReq, unsigned long BssIdx); diff --git a/drivers/staging/rtl8192e/ieee80211/ieee80211_tx.c b/drivers/staging/rtl8192e/ieee80211/ieee80211_tx.c index dd8a221e21ae..b26b5a8b5f6b 100644 --- a/drivers/staging/rtl8192e/ieee80211/ieee80211_tx.c +++ b/drivers/staging/rtl8192e/ieee80211/ieee80211_tx.c @@ -822,7 +822,7 @@ int ieee80211_rtl_xmit(struct sk_buff *skb, struct net_device *dev) { txb->queue_index = UP2AC(skb->priority); } else { - txb->queue_index = WME_AC_BK;; + txb->queue_index = WME_AC_BK; } diff --git a/drivers/staging/rtl8192e/r819xE_phy.c b/drivers/staging/rtl8192e/r819xE_phy.c index d83bcbcb20bd..50cd0e52b921 100644 --- a/drivers/staging/rtl8192e/r819xE_phy.c +++ b/drivers/staging/rtl8192e/r819xE_phy.c @@ -2596,7 +2596,7 @@ u8 rtl8192_phy_ConfigRFWithHeaderFile(struct net_device* dev, RF90_RADIO_PATH_E break; } - return ret;; + return ret; } /****************************************************************************** diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_tx.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_tx.c index 81aa2ed226ac..ec7845ecdb7e 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_tx.c +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_tx.c @@ -754,7 +754,7 @@ int ieee80211_xmit(struct sk_buff *skb, struct net_device *dev) { txb->queue_index = UP2AC(skb->priority); } else { - txb->queue_index = WME_AC_BK;; + txb->queue_index = WME_AC_BK; } diff --git a/drivers/staging/rtl8192u/r8192U_core.c b/drivers/staging/rtl8192u/r8192U_core.c index 4cc7b418c91e..cbfe1341d856 100644 --- a/drivers/staging/rtl8192u/r8192U_core.c +++ b/drivers/staging/rtl8192u/r8192U_core.c @@ -5085,7 +5085,7 @@ static void rtl8192_query_rxphystatus( //Get Rx snr value in DB tmp_rxsnr = pofdm_buf->rxsnr_X[i]; rx_snrX = (char)(tmp_rxsnr); - //rx_snrX >>= 1;; + //rx_snrX >>= 1; rx_snrX /= 2; priv->stats.rxSNRdB[i] = (long)rx_snrX; diff --git a/drivers/staging/rtl8192u/r819xU_phy.c b/drivers/staging/rtl8192u/r819xU_phy.c index a3adaedece9a..8e10992366fe 100644 --- a/drivers/staging/rtl8192u/r819xU_phy.c +++ b/drivers/staging/rtl8192u/r819xU_phy.c @@ -1011,7 +1011,7 @@ u8 rtl8192_phy_ConfigRFWithHeaderFile(struct net_device* dev, RF90_RADIO_PATH_E break; } - return ret;; + return ret; } /****************************************************************************** diff --git a/drivers/staging/rtl8712/rtl8712_efuse.c b/drivers/staging/rtl8712/rtl8712_efuse.c index 9730ae1c58d5..1dc12b7a2f52 100644 --- a/drivers/staging/rtl8712/rtl8712_efuse.c +++ b/drivers/staging/rtl8712/rtl8712_efuse.c @@ -428,7 +428,7 @@ u8 r8712_efuse_access(struct _adapter *padapter, u8 bRead, u16 start_addr, u16 cnts, u8 *data) { int i; - u8 res = true;; + u8 res = true; if (start_addr > EFUSE_MAX_SIZE) return false; diff --git a/drivers/staging/rtl8712/rtl8712_xmit.c b/drivers/staging/rtl8712/rtl8712_xmit.c index 8edc518536f9..88a15049bc2a 100644 --- a/drivers/staging/rtl8712/rtl8712_xmit.c +++ b/drivers/staging/rtl8712/rtl8712_xmit.c @@ -148,7 +148,7 @@ static u32 get_ff_hwaddr(struct xmit_frame *pxmitframe) case 0x11: case 0x12: case 0x13: - addr = RTL8712_DMA_H2CCMD;; + addr = RTL8712_DMA_H2CCMD; break; default: addr = RTL8712_DMA_BEQ;/*RTL8712_EP_LO;*/ diff --git a/drivers/staging/rtl8712/rtl871x_xmit.c b/drivers/staging/rtl8712/rtl871x_xmit.c index b8195e3a72d4..75f1a6bba2f6 100644 --- a/drivers/staging/rtl8712/rtl871x_xmit.c +++ b/drivers/staging/rtl8712/rtl871x_xmit.c @@ -372,7 +372,7 @@ static sint xmitframe_addmic(struct _adapter *padapter, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}; datalen = pattrib->pktlen - pattrib->hdrlen; - pframe = pxmitframe->buf_addr + TXDESC_OFFSET;; + pframe = pxmitframe->buf_addr + TXDESC_OFFSET; if (bmcst) { if (!memcmp(psecuritypriv->XGrptxmickey [psecuritypriv->XGrpKeyid].skey, diff --git a/drivers/staging/tidspbridge/core/tiomap3430.c b/drivers/staging/tidspbridge/core/tiomap3430.c index 1be081f917a7..a3b0a183d570 100644 --- a/drivers/staging/tidspbridge/core/tiomap3430.c +++ b/drivers/staging/tidspbridge/core/tiomap3430.c @@ -596,7 +596,7 @@ static int bridge_brd_start(struct bridge_dev_context *dev_ctxt, dev_dbg(bridge, "DSP c_int00 Address = 0x%x\n", dsp_addr); if (dsp_debug) while (__raw_readw(dw_sync_addr)) - ;; + ; /* Wait for DSP to clear word in shared memory */ /* Read the Location */ @@ -1671,7 +1671,7 @@ static int pte_set(struct pg_table_attrs *pt, u32 pa, u32 va, /* Find a free L2 PT. */ for (i = 0; (i < pt->l2_num_pages) && (pt->pg_info[i].num_entries != 0); i++) - ;; + ; if (i < pt->l2_num_pages) { l2_page_num = i; l2_base_pa = pt->l2_base_pa + (l2_page_num * diff --git a/drivers/staging/tidspbridge/rmgr/nldr.c b/drivers/staging/tidspbridge/rmgr/nldr.c index a6ae007015d0..28354bbf1aeb 100644 --- a/drivers/staging/tidspbridge/rmgr/nldr.c +++ b/drivers/staging/tidspbridge/rmgr/nldr.c @@ -943,7 +943,7 @@ static int add_ovly_info(void *handle, struct dbll_sect_info *sect_info, /* Determine which phase this section belongs to */ for (pch = sect_name + 1; *pch && *pch != seps; pch++) - ;; + ; if (*pch) { pch++; /* Skip over the ':' */ diff --git a/drivers/staging/vt6655/card.c b/drivers/staging/vt6655/card.c index 32d095c4d51c..951a3a8ddcb2 100644 --- a/drivers/staging/vt6655/card.c +++ b/drivers/staging/vt6655/card.c @@ -2058,7 +2058,7 @@ bool CARDbSoftwareReset (void *pDeviceHandler) QWORD CARDqGetTSFOffset (unsigned char byRxRate, QWORD qwTSF1, QWORD qwTSF2) { QWORD qwTSFOffset; - unsigned short wRxBcnTSFOffst= 0;; + unsigned short wRxBcnTSFOffst= 0; HIDWORD(qwTSFOffset) = 0; LODWORD(qwTSFOffset) = 0; diff --git a/drivers/staging/vt6655/iwctl.c b/drivers/staging/vt6655/iwctl.c index 92e33999054b..5e425d1476b8 100644 --- a/drivers/staging/vt6655/iwctl.c +++ b/drivers/staging/vt6655/iwctl.c @@ -2073,7 +2073,7 @@ int iwctl_giwencodeext(struct net_device *dev, struct iw_point *wrq, char *extra) { - return -EOPNOTSUPP;; + return -EOPNOTSUPP; } int iwctl_siwmlme(struct net_device *dev, diff --git a/drivers/staging/vt6655/wpa2.c b/drivers/staging/vt6655/wpa2.c index 805164bed7e4..744799cfe832 100644 --- a/drivers/staging/vt6655/wpa2.c +++ b/drivers/staging/vt6655/wpa2.c @@ -216,7 +216,7 @@ WPA2vParseRSN ( m = *((unsigned short *) &(pRSN->abyRSN[4])); if (pRSN->len >= 10+m*4) { // ver(2) + GK(4) + PK count(2) + PKS(4*m) + AKMSS count(2) - pBSSNode->wAKMSSAuthCount = *((unsigned short *) &(pRSN->abyRSN[6+4*m]));; + pBSSNode->wAKMSSAuthCount = *((unsigned short *) &(pRSN->abyRSN[6+4*m])); j = 0; pbyOUI = &(pRSN->abyRSN[8+4*m]); for (i = 0; (i < pBSSNode->wAKMSSAuthCount) && (j < sizeof(pBSSNode->abyAKMSSAuthType)/sizeof(unsigned char)); i++) { @@ -235,7 +235,7 @@ WPA2vParseRSN ( pBSSNode->wAKMSSAuthCount = (unsigned short)j; DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"wAKMSSAuthCount: %d\n", pBSSNode->wAKMSSAuthCount); - n = *((unsigned short *) &(pRSN->abyRSN[6+4*m]));; + n = *((unsigned short *) &(pRSN->abyRSN[6+4*m])); if (pRSN->len >= 12+4*m+4*n) { // ver(2)+GK(4)+PKCnt(2)+PKS(4*m)+AKMSSCnt(2)+AKMSS(4*n)+Cap(2) pBSSNode->sRSNCapObj.bRSNCapExist = true; pBSSNode->sRSNCapObj.wRSNCap = *((unsigned short *) &(pRSN->abyRSN[8+4*m+4*n])); diff --git a/drivers/staging/vt6656/baseband.c b/drivers/staging/vt6656/baseband.c index e5add2046375..0d11147f91c1 100644 --- a/drivers/staging/vt6656/baseband.c +++ b/drivers/staging/vt6656/baseband.c @@ -963,7 +963,7 @@ BBvSetAntennaMode (PSDevice pDevice, BYTE byAntennaMode) break; case ANT_RXB: pDevice->byBBRxConf &= 0xFE; - pDevice->byBBRxConf |= 0x02;; + pDevice->byBBRxConf |= 0x02; break; } diff --git a/drivers/staging/vt6656/iwctl.c b/drivers/staging/vt6656/iwctl.c index 0004be8e3957..2121205a912b 100644 --- a/drivers/staging/vt6656/iwctl.c +++ b/drivers/staging/vt6656/iwctl.c @@ -1883,7 +1883,7 @@ int iwctl_giwencodeext(struct net_device *dev, struct iw_point *wrq, char *extra) { - return -EOPNOTSUPP;; + return -EOPNOTSUPP; } int iwctl_siwmlme(struct net_device *dev, diff --git a/drivers/staging/vt6656/power.c b/drivers/staging/vt6656/power.c index 0c12fd36d0f9..e8c1b35e8128 100644 --- a/drivers/staging/vt6656/power.c +++ b/drivers/staging/vt6656/power.c @@ -192,7 +192,7 @@ BOOL PSbConsiderPowerDown(void *hDeviceContext, // check if already in Doze mode ControlvReadByte(pDevice, MESSAGE_REQUEST_MACREG, MAC_REG_PSCTL, &byData); if ( (byData & PSCTL_PS) != 0 ) - return TRUE;; + return TRUE; if (pMgmt->eCurrMode != WMAC_MODE_IBSS_STA) { // check if in TIM wake period diff --git a/drivers/staging/vt6656/wpa2.c b/drivers/staging/vt6656/wpa2.c index 6d13190885d1..d4f3f7530ee4 100644 --- a/drivers/staging/vt6656/wpa2.c +++ b/drivers/staging/vt6656/wpa2.c @@ -215,7 +215,7 @@ WPA2vParseRSN ( m = *((PWORD) &(pRSN->abyRSN[4])); if (pRSN->len >= 10+m*4) { // ver(2) + GK(4) + PK count(2) + PKS(4*m) + AKMSS count(2) - pBSSNode->wAKMSSAuthCount = *((PWORD) &(pRSN->abyRSN[6+4*m]));; + pBSSNode->wAKMSSAuthCount = *((PWORD) &(pRSN->abyRSN[6+4*m])); j = 0; pbyOUI = &(pRSN->abyRSN[8+4*m]); for (i = 0; (i < pBSSNode->wAKMSSAuthCount) && (j < sizeof(pBSSNode->abyAKMSSAuthType)/sizeof(BYTE)); i++) { @@ -234,7 +234,7 @@ WPA2vParseRSN ( pBSSNode->wAKMSSAuthCount = (WORD)j; DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"wAKMSSAuthCount: %d\n", pBSSNode->wAKMSSAuthCount); - n = *((PWORD) &(pRSN->abyRSN[6+4*m]));; + n = *((PWORD) &(pRSN->abyRSN[6+4*m])); if (pRSN->len >= 12+4*m+4*n) { // ver(2)+GK(4)+PKCnt(2)+PKS(4*m)+AKMSSCnt(2)+AKMSS(4*n)+Cap(2) pBSSNode->sRSNCapObj.bRSNCapExist = TRUE; pBSSNode->sRSNCapObj.wRSNCap = *((PWORD) &(pRSN->abyRSN[8+4*m+4*n])); -- cgit v1.2.3 From 345594d6ef696b8ad4b96cffe462c6cde2f27292 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 15 Nov 2010 12:14:00 -0800 Subject: drivers/staging: Remove unnecessary casts of pci_get_drvdata Signed-off-by: Joe Perches Signed-off-by: Greg Kroah-Hartman --- drivers/staging/crystalhd/crystalhd_lnx.c | 6 +++--- drivers/staging/et131x/et131x_initpci.c | 2 +- drivers/staging/wlags49_h2/wl_pci.c | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/staging/crystalhd/crystalhd_lnx.c b/drivers/staging/crystalhd/crystalhd_lnx.c index 28c6b8ced424..719e70bc871e 100644 --- a/drivers/staging/crystalhd/crystalhd_lnx.c +++ b/drivers/staging/crystalhd/crystalhd_lnx.c @@ -516,7 +516,7 @@ static void __devexit chd_dec_pci_remove(struct pci_dev *pdev) BCMLOG_ENTER; - pinfo = (struct crystalhd_adp *) pci_get_drvdata(pdev); + pinfo = pci_get_drvdata(pdev); if (!pinfo) { BCMLOG_ERR("could not get adp\n"); return; @@ -626,7 +626,7 @@ int chd_dec_pci_suspend(struct pci_dev *pdev, pm_message_t state) struct crystalhd_ioctl_data *temp; enum BC_STATUS sts = BC_STS_SUCCESS; - adp = (struct crystalhd_adp *)pci_get_drvdata(pdev); + adp = pci_get_drvdata(pdev); if (!adp) { BCMLOG_ERR("could not get adp\n"); return -ENODEV; @@ -660,7 +660,7 @@ int chd_dec_pci_resume(struct pci_dev *pdev) enum BC_STATUS sts = BC_STS_SUCCESS; int rc; - adp = (struct crystalhd_adp *)pci_get_drvdata(pdev); + adp = pci_get_drvdata(pdev); if (!adp) { BCMLOG_ERR("could not get adp\n"); return -ENODEV; diff --git a/drivers/staging/et131x/et131x_initpci.c b/drivers/staging/et131x/et131x_initpci.c index 10bcb45d73a3..f62ba7a68f34 100644 --- a/drivers/staging/et131x/et131x_initpci.c +++ b/drivers/staging/et131x/et131x_initpci.c @@ -783,7 +783,7 @@ static void __devexit et131x_pci_remove(struct pci_dev *pdev) /* Retrieve the net_device pointer from the pci_dev struct, as well * as the private adapter struct */ - netdev = (struct net_device *) pci_get_drvdata(pdev); + netdev = pci_get_drvdata(pdev); adapter = netdev_priv(netdev); /* Perform device cleanup */ diff --git a/drivers/staging/wlags49_h2/wl_pci.c b/drivers/staging/wlags49_h2/wl_pci.c index 020b17adee2d..28ae9dd1b44e 100644 --- a/drivers/staging/wlags49_h2/wl_pci.c +++ b/drivers/staging/wlags49_h2/wl_pci.c @@ -458,7 +458,7 @@ void __devexit wl_pci_remove(struct pci_dev *pdev) return; } - dev = (struct net_device *)pci_get_drvdata( pdev ); + dev = pci_get_drvdata( pdev ); if( dev == NULL ) { DBG_ERROR( DbgInfo, "Could not retrieve net_device structure\n" ); return; -- cgit v1.2.3 From e33196e108197e4a1f1a5331dc7740ad9263f4f5 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 15 Nov 2010 13:12:32 -0800 Subject: drivers/staging: Remove unnecessary casts of netdev_priv Signed-off-by: Joe Perches Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ft1000/ft1000-pcmcia/ft1000_hw.c | 54 +++++++++++----------- drivers/staging/ft1000/ft1000-pcmcia/ft1000_proc.c | 8 ++-- drivers/staging/ft1000/ft1000-usb/ft1000_chdev.c | 8 ++-- drivers/staging/ft1000/ft1000-usb/ft1000_hw.c | 16 +++---- drivers/staging/ft1000/ft1000-usb/ft1000_proc.c | 6 +-- drivers/staging/ft1000/ft1000-usb/ft1000_usb.c | 2 +- drivers/staging/rtl8712/usb_intf.c | 2 +- 7 files changed, 48 insertions(+), 48 deletions(-) diff --git a/drivers/staging/ft1000/ft1000-pcmcia/ft1000_hw.c b/drivers/staging/ft1000/ft1000-pcmcia/ft1000_hw.c index eed7e94308db..588afd5a5ddb 100644 --- a/drivers/staging/ft1000/ft1000-pcmcia/ft1000_hw.c +++ b/drivers/staging/ft1000/ft1000-pcmcia/ft1000_hw.c @@ -132,7 +132,7 @@ inline void ft1000_asic_write(struct net_device *dev, u16 offset, u16 value) //--------------------------------------------------------------------------- static inline u16 ft1000_read_fifo_len(struct net_device *dev) { - FT1000_INFO *info = (FT1000_INFO *) netdev_priv(dev); + FT1000_INFO *info = netdev_priv(dev); if (info->AsicID == ELECTRABUZZ_ID) { return (ft1000_read_reg(dev, FT1000_REG_UFIFO_STAT) - 16); @@ -155,7 +155,7 @@ static inline u16 ft1000_read_fifo_len(struct net_device *dev) //--------------------------------------------------------------------------- u16 ft1000_read_dpram(struct net_device * dev, int offset) { - FT1000_INFO *info = (FT1000_INFO *) netdev_priv(dev); + FT1000_INFO *info = netdev_priv(dev); unsigned long flags; u16 data; @@ -184,7 +184,7 @@ u16 ft1000_read_dpram(struct net_device * dev, int offset) static inline void ft1000_write_dpram(struct net_device *dev, int offset, u16 value) { - FT1000_INFO *info = (FT1000_INFO *) netdev_priv(dev); + FT1000_INFO *info = netdev_priv(dev); unsigned long flags; // Provide mutual exclusive access while reading ASIC registers. @@ -208,7 +208,7 @@ static inline void ft1000_write_dpram(struct net_device *dev, //--------------------------------------------------------------------------- u16 ft1000_read_dpram_mag_16(struct net_device *dev, int offset, int Index) { - FT1000_INFO *info = (FT1000_INFO *) netdev_priv(dev); + FT1000_INFO *info = netdev_priv(dev); unsigned long flags; u16 data; @@ -242,7 +242,7 @@ u16 ft1000_read_dpram_mag_16(struct net_device *dev, int offset, int Index) static inline void ft1000_write_dpram_mag_16(struct net_device *dev, int offset, u16 value, int Index) { - FT1000_INFO *info = (FT1000_INFO *) netdev_priv(dev); + FT1000_INFO *info = netdev_priv(dev); unsigned long flags; // Provide mutual exclusive access while reading ASIC registers. @@ -270,7 +270,7 @@ static inline void ft1000_write_dpram_mag_16(struct net_device *dev, //--------------------------------------------------------------------------- u32 ft1000_read_dpram_mag_32(struct net_device *dev, int offset) { - FT1000_INFO *info = (FT1000_INFO *) netdev_priv(dev); + FT1000_INFO *info = netdev_priv(dev); unsigned long flags; u32 data; @@ -298,7 +298,7 @@ u32 ft1000_read_dpram_mag_32(struct net_device *dev, int offset) //--------------------------------------------------------------------------- void ft1000_write_dpram_mag_32(struct net_device *dev, int offset, u32 value) { - FT1000_INFO *info = (FT1000_INFO *) netdev_priv(dev); + FT1000_INFO *info = netdev_priv(dev); unsigned long flags; // Provide mutual exclusive access while reading ASIC registers. @@ -320,7 +320,7 @@ void ft1000_write_dpram_mag_32(struct net_device *dev, int offset, u32 value) //--------------------------------------------------------------------------- static void ft1000_enable_interrupts(struct net_device *dev) { - FT1000_INFO *info = (FT1000_INFO *) netdev_priv(dev); + FT1000_INFO *info = netdev_priv(dev); u16 tempword; DEBUG(1, "ft1000_hw:ft1000_enable_interrupts()\n"); @@ -345,7 +345,7 @@ static void ft1000_enable_interrupts(struct net_device *dev) //--------------------------------------------------------------------------- static void ft1000_disable_interrupts(struct net_device *dev) { - FT1000_INFO *info = (FT1000_INFO *) netdev_priv(dev); + FT1000_INFO *info = netdev_priv(dev); u16 tempword; DEBUG(1, "ft1000_hw: ft1000_disable_interrupts()\n"); @@ -370,7 +370,7 @@ static void ft1000_disable_interrupts(struct net_device *dev) //--------------------------------------------------------------------------- static void ft1000_reset_asic(struct net_device *dev) { - FT1000_INFO *info = (FT1000_INFO *) netdev_priv(dev); + FT1000_INFO *info = netdev_priv(dev); u16 tempword; DEBUG(1, "ft1000_hw:ft1000_reset_asic called\n"); @@ -414,7 +414,7 @@ static void ft1000_reset_asic(struct net_device *dev) //--------------------------------------------------------------------------- static int ft1000_reset_card(struct net_device *dev) { - FT1000_INFO *info = (FT1000_INFO *) netdev_priv(dev); + FT1000_INFO *info = netdev_priv(dev); u16 tempword; int i; unsigned long flags; @@ -618,7 +618,7 @@ static void ft1000_hbchk(u_long data) FT1000_INFO *info; USHORT tempword; - info = (FT1000_INFO *) netdev_priv(dev); + info = netdev_priv(dev); if (info->CardReady == 1) { // Perform dsp heartbeat check @@ -831,7 +831,7 @@ static void ft1000_hbchk(u_long data) //--------------------------------------------------------------------------- void ft1000_send_cmd (struct net_device *dev, u16 *ptempbuffer, int size, u16 qtype) { - FT1000_INFO *info = (FT1000_INFO *) netdev_priv(dev); + FT1000_INFO *info = netdev_priv(dev); int i; u16 tempword; unsigned long flags; @@ -916,7 +916,7 @@ void ft1000_send_cmd (struct net_device *dev, u16 *ptempbuffer, int size, u16 qt //--------------------------------------------------------------------------- BOOLEAN ft1000_receive_cmd(struct net_device *dev, u16 * pbuffer, int maxsz, u16 *pnxtph) { - FT1000_INFO *info = (FT1000_INFO *) netdev_priv(dev); + FT1000_INFO *info = netdev_priv(dev); u16 size; u16 *ppseudohdr; int i; @@ -1009,7 +1009,7 @@ BOOLEAN ft1000_receive_cmd(struct net_device *dev, u16 * pbuffer, int maxsz, u16 //--------------------------------------------------------------------------- void ft1000_proc_drvmsg(struct net_device *dev) { - FT1000_INFO *info = (FT1000_INFO *) netdev_priv(dev); + FT1000_INFO *info = netdev_priv(dev); u16 msgtype; u16 tempword; PMEDIAMSG pmediamsg; @@ -1292,7 +1292,7 @@ void ft1000_proc_drvmsg(struct net_device *dev) //--------------------------------------------------------------------------- int ft1000_parse_dpram_msg(struct net_device *dev) { - FT1000_INFO *info = (FT1000_INFO *) netdev_priv(dev); + FT1000_INFO *info = netdev_priv(dev); u16 doorbell; u16 portid; u16 nxtph; @@ -1449,7 +1449,7 @@ int ft1000_parse_dpram_msg(struct net_device *dev) //--------------------------------------------------------------------------- static void ft1000_flush_fifo(struct net_device *dev, u16 DrvErrNum) { - FT1000_INFO *info = (FT1000_INFO *) netdev_priv(dev); + FT1000_INFO *info = netdev_priv(dev); u16 i; u32 templong; u16 tempword; @@ -1596,7 +1596,7 @@ static void ft1000_flush_fifo(struct net_device *dev, u16 DrvErrNum) int ft1000_copy_up_pkt(struct net_device *dev) { u16 tempword; - FT1000_INFO *info = (FT1000_INFO *) netdev_priv(dev); + FT1000_INFO *info = netdev_priv(dev); u16 len; struct sk_buff *skb; u16 i; @@ -1783,7 +1783,7 @@ int ft1000_copy_up_pkt(struct net_device *dev) //--------------------------------------------------------------------------- int ft1000_copy_down_pkt(struct net_device *dev, u16 * packet, u16 len) { - FT1000_INFO *info = (FT1000_INFO *) netdev_priv(dev); + FT1000_INFO *info = netdev_priv(dev); union { PSEUDO_HDR blk; u16 buff[sizeof(PSEUDO_HDR) >> 1]; @@ -1943,7 +1943,7 @@ int ft1000_copy_down_pkt(struct net_device *dev, u16 * packet, u16 len) static struct net_device_stats *ft1000_stats(struct net_device *dev) { - FT1000_INFO *info = (FT1000_INFO *) netdev_priv(dev); + FT1000_INFO *info = netdev_priv(dev); return (&info->stats); } @@ -1967,7 +1967,7 @@ static int ft1000_open(struct net_device *dev) static int ft1000_close(struct net_device *dev) { - FT1000_INFO *info = (FT1000_INFO *) netdev_priv(dev); + FT1000_INFO *info = netdev_priv(dev); DEBUG(0, "ft1000_hw: ft1000_close()\n"); @@ -1989,7 +1989,7 @@ static int ft1000_close(struct net_device *dev) static int ft1000_start_xmit(struct sk_buff *skb, struct net_device *dev) { - FT1000_INFO *info = (FT1000_INFO *) netdev_priv(dev); + FT1000_INFO *info = netdev_priv(dev); u8 *pdata; DEBUG(1, "ft1000_hw: ft1000_start_xmit()\n"); @@ -2026,7 +2026,7 @@ static int ft1000_start_xmit(struct sk_buff *skb, struct net_device *dev) static irqreturn_t ft1000_interrupt(int irq, void *dev_id) { struct net_device *dev = (struct net_device *)dev_id; - FT1000_INFO *info = (FT1000_INFO *) netdev_priv(dev); + FT1000_INFO *info = netdev_priv(dev); u16 tempword; u16 inttype; int cnt; @@ -2091,7 +2091,7 @@ static irqreturn_t ft1000_interrupt(int irq, void *dev_id) void stop_ft1000_card(struct net_device *dev) { - FT1000_INFO *info = (FT1000_INFO *) netdev_priv(dev); + FT1000_INFO *info = netdev_priv(dev); PPROV_RECORD ptr; // int cnt; @@ -2127,7 +2127,7 @@ static void ft1000_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) { FT1000_INFO *ft_info; - ft_info = (FT1000_INFO *) netdev_priv(dev); + ft_info = netdev_priv(dev); snprintf(info->driver, 32, "ft1000"); snprintf(info->bus_info, ETHTOOL_BUSINFO_LEN, "PCMCIA 0x%lx", @@ -2139,7 +2139,7 @@ static void ft1000_get_drvinfo(struct net_device *dev, static u32 ft1000_get_link(struct net_device *dev) { FT1000_INFO *info; - info = (FT1000_INFO *) netdev_priv(dev); + info = netdev_priv(dev); return info->mediastate; } @@ -2185,7 +2185,7 @@ struct net_device *init_ft1000_card(unsigned short irq, int port, } SET_NETDEV_DEV(dev, fdev); - info = (FT1000_INFO *) netdev_priv(dev); + info = netdev_priv(dev); memset(info, 0, sizeof(FT1000_INFO)); diff --git a/drivers/staging/ft1000/ft1000-pcmcia/ft1000_proc.c b/drivers/staging/ft1000/ft1000-pcmcia/ft1000_proc.c index b45de9bc1b20..935608e72007 100644 --- a/drivers/staging/ft1000/ft1000-pcmcia/ft1000_proc.c +++ b/drivers/staging/ft1000/ft1000-pcmcia/ft1000_proc.c @@ -65,7 +65,7 @@ int ft1000ReadProc(char *page, char **start, off_t off, time_t delta; dev = (struct net_device *)data; - info = (FT1000_INFO *) netdev_priv(dev); + info = netdev_priv(dev); if (off > 0) { *eof = 1; @@ -174,7 +174,7 @@ static int ft1000NotifyProc(struct notifier_block *this, unsigned long event, struct net_device *dev = ptr; FT1000_INFO *info; - info = (FT1000_INFO *) netdev_priv(dev); + info = netdev_priv(dev); switch (event) { case NETDEV_CHANGENAME: @@ -195,7 +195,7 @@ void ft1000InitProc(struct net_device *dev) { FT1000_INFO *info; - info = (FT1000_INFO *) netdev_priv(dev); + info = netdev_priv(dev); info->proc_ft1000 = proc_mkdir(FT1000_PROC, init_net.proc_net); create_proc_read_entry(dev->name, 0644, info->proc_ft1000, @@ -208,7 +208,7 @@ void ft1000CleanupProc(struct net_device *dev) { FT1000_INFO *info; - info = (FT1000_INFO *) netdev_priv(dev); + info = netdev_priv(dev); remove_proc_entry(dev->name, info->proc_ft1000); remove_proc_entry(FT1000_PROC, init_net.proc_net); diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_chdev.c b/drivers/staging/ft1000/ft1000-usb/ft1000_chdev.c index 18c4c15c5aea..7b4963326e8c 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_chdev.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_chdev.c @@ -423,7 +423,7 @@ static int ft1000_ChOpen (struct inode *Inode, struct file *File) if ( pdevobj[num] != NULL ) //info = (struct ft1000_info *)(pdevobj[num]->net->priv); - info = (struct ft1000_info *)netdev_priv(pdevobj[num]->net); + info = netdev_priv(pdevobj[num]->net); else { DEBUG("ft1000_ChOpen: can not find device object %d\n", num); @@ -488,7 +488,7 @@ static unsigned int ft1000_ChPoll(struct file *file, poll_table *wait) return (-EBADF); } - info = (struct ft1000_info *) netdev_priv(dev); + info = netdev_priv(dev); // Search for matching file object for (i=0; iprivate_data; - info = (struct ft1000_info *) netdev_priv(dev); + info = netdev_priv(dev); ft1000dev = info->pFt1000Dev; cmd = _IOC_NR(Command); //DEBUG("FT1000:ft1000_ChIoctl:cmd = 0x%x\n", cmd); @@ -900,7 +900,7 @@ static int ft1000_ChRelease (struct inode *Inode, struct file *File) DEBUG("ft1000_ChRelease called\n"); dev = File->private_data; - info = (struct ft1000_info *) netdev_priv(dev); + info = netdev_priv(dev); if (ft1000_flarion_cnt == 0) { info->appcnt--; diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c index b41884e60d07..1ca01e2ea361 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c @@ -786,7 +786,7 @@ u16 init_ft1000_netdev(struct ft1000_device *ft1000dev) return -ENOMEM; } - pInfo = (struct ft1000_info *) netdev_priv(netdev); + pInfo = netdev_priv(netdev); //DEBUG("init_ft1000_netdev: gFt1000Info=%x, netdev=%x, ft1000dev=%x\n", gFt1000Info, netdev, ft1000dev); @@ -1345,7 +1345,7 @@ static int ft1000_submit_rx_urb(struct ft1000_info *info) //--------------------------------------------------------------------------- static int ft1000_open (struct net_device *dev) { - struct ft1000_info *pInfo = (struct ft1000_info *)netdev_priv(dev); + struct ft1000_info *pInfo = netdev_priv(dev); struct timeval tv; //mbelian int ret; @@ -1386,7 +1386,7 @@ static int ft1000_open (struct net_device *dev) //--------------------------------------------------------------------------- int ft1000_close(struct net_device *net) { - struct ft1000_info *pInfo = (struct ft1000_info *) netdev_priv(net); + struct ft1000_info *pInfo = netdev_priv(net); struct ft1000_device *ft1000dev = pInfo->pFt1000Dev; //DEBUG ("ft1000_close: netdev->refcnt=%d\n", net->refcnt); @@ -1409,7 +1409,7 @@ int ft1000_close(struct net_device *net) static struct net_device_stats *ft1000_netdev_stats(struct net_device *dev) { - struct ft1000_info *info = (struct ft1000_info *) netdev_priv(dev); + struct ft1000_info *info = netdev_priv(dev); return &(info->stats); //mbelian } @@ -1435,7 +1435,7 @@ Jim static int ft1000_chkcard (struct ft1000_device *dev) { u16 tempword; u16 status; - struct ft1000_info *info = (struct ft1000_info *) netdev_priv(dev->net); + struct ft1000_info *info = netdev_priv(dev->net); if (info->fCondResetPend) { @@ -1535,7 +1535,7 @@ static bool ft1000_receive_cmd (struct ft1000_device *dev, u16 *pbuffer, int max static int ft1000_dsp_prov(void *arg) { struct ft1000_device *dev = (struct ft1000_device *)arg; - struct ft1000_info *info = (struct ft1000_info *) netdev_priv(dev->net); + struct ft1000_info *info = netdev_priv(dev->net); u16 tempword; u16 len; u16 i=0; @@ -1618,7 +1618,7 @@ static int ft1000_dsp_prov(void *arg) static int ft1000_proc_drvmsg (struct ft1000_device *dev, u16 size) { - struct ft1000_info *info = (struct ft1000_info *) netdev_priv(dev->net); + struct ft1000_info *info = netdev_priv(dev->net); u16 msgtype; u16 tempword; struct media_msg *pmediamsg; @@ -1901,7 +1901,7 @@ out: int ft1000_poll(void* dev_id) { struct ft1000_device *dev = (struct ft1000_device *)dev_id; - struct ft1000_info *info = (struct ft1000_info *) netdev_priv(dev->net); + struct ft1000_info *info = netdev_priv(dev->net); u16 tempword; u16 status; diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_proc.c b/drivers/staging/ft1000/ft1000-usb/ft1000_proc.c index f665640058ae..105846d104ff 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_proc.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_proc.c @@ -65,7 +65,7 @@ ft1000ReadProc (char *page, char **start, off_t off, int count, int *eof, time_t delta; dev = (struct net_device *) data; - info = (struct ft1000_info *) netdev_priv(dev); + info = netdev_priv(dev); if (off > 0) { @@ -172,7 +172,7 @@ ft1000NotifyProc (struct notifier_block *this, unsigned long event, void *ptr) struct ft1000_info *info; struct proc_dir_entry *ft1000_proc_file; -info = (struct ft1000_info *) netdev_priv(dev); +info = netdev_priv(dev); switch (event) @@ -198,7 +198,7 @@ ft1000InitProc (struct net_device *dev) { struct ft1000_info *info; struct proc_dir_entry *ft1000_proc_file; - info = (struct ft1000_info *) netdev_priv(dev); + info = netdev_priv(dev); info->ft1000_proc_dir = proc_mkdir (FT1000_PROC_DIR, FTNET_PROC); diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_usb.c b/drivers/staging/ft1000/ft1000-usb/ft1000_usb.c index 6925622795a5..1369f06cb0df 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_usb.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_usb.c @@ -163,7 +163,7 @@ static int ft1000_probe(struct usb_interface *interface, if (ret) goto err_load; - pft1000info = (struct ft1000_info *) netdev_priv(ft1000dev->net); + pft1000info = netdev_priv(ft1000dev->net); DEBUG("In probe: pft1000info=%p\n", pft1000info); ret = dsp_reload(ft1000dev); diff --git a/drivers/staging/rtl8712/usb_intf.c b/drivers/staging/rtl8712/usb_intf.c index f1f0c63e5bbc..a692ee88b9e9 100644 --- a/drivers/staging/rtl8712/usb_intf.c +++ b/drivers/staging/rtl8712/usb_intf.c @@ -527,7 +527,7 @@ error: static void r871xu_dev_remove(struct usb_interface *pusb_intf) { struct net_device *pnetdev = usb_get_intfdata(pusb_intf); - struct _adapter *padapter = (struct _adapter *)netdev_priv(pnetdev); + struct _adapter *padapter = netdev_priv(pnetdev); struct usb_device *udev = interface_to_usbdev(pusb_intf); if (padapter) { -- cgit v1.2.3 From 0ff36f69bd3e7846557880fe934dd0cdeee6a29e Mon Sep 17 00:00:00 2001 From: Brandon Philips Date: Mon, 15 Nov 2010 11:55:33 -0800 Subject: staging: hv: add explanation of no-op set_multicast_list I was going to remove netvsc_set_multicast_list() so I think it is worth adding a comment since it isn't immediately clear why you would want this. Signed-off-by: Brandon Philips Acked-by: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/netvsc_drv.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/staging/hv/netvsc_drv.c b/drivers/staging/hv/netvsc_drv.c index 141535295a41..f527e5f24f56 100644 --- a/drivers/staging/hv/netvsc_drv.c +++ b/drivers/staging/hv/netvsc_drv.c @@ -66,6 +66,9 @@ MODULE_PARM_DESC(ring_size, "Ring buffer size (# of pages)"); /* The one and only one */ static struct netvsc_driver_context g_netvsc_drv; +/* no-op so the netdev core doesn't return -EINVAL when modifying the the + * multicast address list in SIOCADDMULTI. hv is setup to get all multicast + * when it calls RndisFilterOnOpen() */ static void netvsc_set_multicast_list(struct net_device *net) { } -- cgit v1.2.3 From defc19cebc7f700cb05226f0c4496b9d50c84643 Mon Sep 17 00:00:00 2001 From: Tushar Mehta Date: Tue, 16 Nov 2010 12:13:50 +0530 Subject: Staging: autofs: fix coding style issue in dirhash.c This is a patch to the dirhash.c file that fixes up a number of issues found by the checkpatch.pl tool Signed-off-by: Tushar Mehta Signed-off-by: Greg Kroah-Hartman --- drivers/staging/autofs/dirhash.c | 87 ++++++++++++++++++++++------------------ 1 file changed, 49 insertions(+), 38 deletions(-) diff --git a/drivers/staging/autofs/dirhash.c b/drivers/staging/autofs/dirhash.c index 8f3e2b816129..d3f42c8325f7 100644 --- a/drivers/staging/autofs/dirhash.c +++ b/drivers/staging/autofs/dirhash.c @@ -30,7 +30,7 @@ void autofs_update_usage(struct autofs_dirhash *dh, struct autofs_dir_ent *ent) { autofs_delete_usage(ent); /* Unlink from current position */ - autofs_init_usage(dh,ent); /* Relink at queue tail */ + autofs_init_usage(dh, ent); /* Relink at queue tail */ } struct autofs_dir_ent *autofs_expire(struct super_block *sb, @@ -45,17 +45,18 @@ struct autofs_dir_ent *autofs_expire(struct super_block *sb, struct path path; int umount_ok; - if ( list_empty(&dh->expiry_head) || sbi->catatonic ) + if (list_empty(&dh->expiry_head) || sbi->catatonic) return NULL; /* No entries */ /* We keep the list sorted by last_usage and want old stuff */ - ent = list_entry(dh->expiry_head.next, struct autofs_dir_ent, exp); + ent = list_entry(dh->expiry_head.next, + struct autofs_dir_ent, exp); if (jiffies - ent->last_usage < timeout) break; /* Move to end of list in case expiry isn't desirable */ autofs_update_usage(dh, ent); /* Check to see that entry is expirable */ - if ( ent->ino < AUTOFS_FIRST_DIR_INO ) + if (ent->ino < AUTOFS_FIRST_DIR_INO) return ent; /* Symlinks are always expirable */ /* Get the dentry for the autofs subdirectory */ @@ -63,14 +64,15 @@ struct autofs_dir_ent *autofs_expire(struct super_block *sb, if (!path.dentry) { /* Should only happen in catatonic mode */ - printk("autofs: dentry == NULL but inode range is directory, entry %s\n", ent->name); + printk(KERN_DEBUG "autofs: dentry == NULL but inode \ + range is directory, entry %s\n", ent->name); autofs_delete_usage(ent); continue; } if (!path.dentry->d_inode) { dput(path.dentry); - printk("autofs: negative dentry on expiry queue: %s\n", + printk(KERN_DEBUG "autofs: negative dentry on expiry queue: %s\n", ent->name); autofs_delete_usage(ent); continue; @@ -80,14 +82,16 @@ struct autofs_dir_ent *autofs_expire(struct super_block *sb, point to the mounted-on-top root. */ if (!S_ISDIR(path.dentry->d_inode->i_mode) || !d_mountpoint(path.dentry)) { - DPRINTK(("autofs: not expirable (not a mounted directory): %s\n", ent->name)); + DPRINTK(("autofs: not expirable \ + (not a mounted directory): %s\n", ent->name)); continue; } path.mnt = mnt; path_get(&path); if (!follow_down(&path)) { path_put(&path); - DPRINTK(("autofs: not expirable (not a mounted directory): %s\n", ent->name)); + DPRINTK(("autofs: not expirable\ + (not a mounted directory): %s\n", ent->name)); continue; } while (d_mountpoint(path.dentry) && follow_down(&path)) @@ -96,30 +100,37 @@ struct autofs_dir_ent *autofs_expire(struct super_block *sb, path_put(&path); if (umount_ok) { - DPRINTK(("autofs: signaling expire on %s\n", ent->name)); + DPRINTK(("autofs: signaling expire on %s\n", + ent->name)); return ent; /* Expirable! */ } - DPRINTK(("autofs: didn't expire due to may_umount: %s\n", ent->name)); + + DPRINTK(("autofs: didn't expire due to may_umount: %s\n", + ent->name)); } return NULL; /* No expirable entries */ } -void autofs_initialize_hash(struct autofs_dirhash *dh) { +void autofs_initialize_hash(struct autofs_dirhash *dh) +{ memset(&dh->h, 0, AUTOFS_HASH_SIZE*sizeof(struct autofs_dir_ent *)); INIT_LIST_HEAD(&dh->expiry_head); } -struct autofs_dir_ent *autofs_hash_lookup(const struct autofs_dirhash *dh, struct qstr *name) +struct autofs_dir_ent *autofs_hash_lookup(const struct autofs_dirhash *dh, + struct qstr *name) { struct autofs_dir_ent *dhn; DPRINTK(("autofs_hash_lookup: hash = 0x%08x, name = ", name->hash)); - autofs_say(name->name,name->len); + autofs_say(name->name, name->len); - for ( dhn = dh->h[(unsigned) name->hash % AUTOFS_HASH_SIZE] ; dhn ; dhn = dhn->next ) { - if ( name->hash == dhn->hash && + for (dhn = dh->h[(unsigned) name->hash % AUTOFS_HASH_SIZE]; + dhn; + dhn = dhn->next) { + if (name->hash == dhn->hash && name->len == dhn->len && - !memcmp(name->name, dhn->name, name->len) ) + !memcmp(name->name, dhn->name, name->len)) break; } @@ -131,9 +142,9 @@ void autofs_hash_insert(struct autofs_dirhash *dh, struct autofs_dir_ent *ent) struct autofs_dir_ent **dhnp; DPRINTK(("autofs_hash_insert: hash = 0x%08x, name = ", ent->hash)); - autofs_say(ent->name,ent->len); + autofs_say(ent->name, ent->len); - autofs_init_usage(dh,ent); + autofs_init_usage(dh, ent); if (ent->dentry) dget(ent->dentry); @@ -141,19 +152,19 @@ void autofs_hash_insert(struct autofs_dirhash *dh, struct autofs_dir_ent *ent) ent->next = *dhnp; ent->back = dhnp; *dhnp = ent; - if ( ent->next ) + if (ent->next) ent->next->back = &(ent->next); } void autofs_hash_delete(struct autofs_dir_ent *ent) { *(ent->back) = ent->next; - if ( ent->next ) + if (ent->next) ent->next->back = ent->back; autofs_delete_usage(ent); - if ( ent->dentry ) + if (ent->dentry) dput(ent->dentry); kfree(ent->name); kfree(ent); @@ -176,37 +187,37 @@ struct autofs_dir_ent *autofs_hash_enum(const struct autofs_dirhash *dh, bucket = (*ptr >> 16) - 1; ecount = *ptr & 0xffff; - if ( bucket < 0 ) { + if (bucket < 0) bucket = ecount = 0; - } DPRINTK(("autofs_hash_enum: bucket %d, entry %d\n", bucket, ecount)); ent = last ? last->next : NULL; - if ( ent ) { + if (ent) { ecount++; } else { - while ( bucket < AUTOFS_HASH_SIZE ) { + while (bucket < AUTOFS_HASH_SIZE) { ent = dh->h[bucket]; - for ( i = ecount ; ent && i ; i-- ) + for (i = ecount ; ent && i ; i--) ent = ent->next; - + if (ent) { ecount++; /* Point to *next* entry */ break; } - + bucket++; ecount = 0; } } #ifdef DEBUG - if ( !ent ) - printk("autofs_hash_enum: nothing found\n"); + if (!ent) + printk(KERN_DEBUG "autofs_hash_enum: nothing found\n"); else { - printk("autofs_hash_enum: found hash %08x, name", ent->hash); - autofs_say(ent->name,ent->len); + printk(KERN_DEBUG "autofs_hash_enum: found hash %08x, name", + ent->hash); + autofs_say(ent->name, ent->len); } #endif @@ -221,9 +232,9 @@ void autofs_hash_dputall(struct autofs_dirhash *dh) int i; struct autofs_dir_ent *ent; - for ( i = 0 ; i < AUTOFS_HASH_SIZE ; i++ ) { - for ( ent = dh->h[i] ; ent ; ent = ent->next ) { - if ( ent->dentry ) { + for (i = 0 ; i < AUTOFS_HASH_SIZE ; i++) { + for (ent = dh->h[i] ; ent ; ent = ent->next) { + if (ent->dentry) { dput(ent->dentry); ent->dentry = NULL; } @@ -238,10 +249,10 @@ void autofs_hash_nuke(struct autofs_sb_info *sbi) int i; struct autofs_dir_ent *ent, *nent; - for ( i = 0 ; i < AUTOFS_HASH_SIZE ; i++ ) { - for ( ent = sbi->dirhash.h[i] ; ent ; ent = nent ) { + for (i = 0 ; i < AUTOFS_HASH_SIZE ; i++) { + for (ent = sbi->dirhash.h[i] ; ent ; ent = nent) { nent = ent->next; - if ( ent->dentry ) + if (ent->dentry) dput(ent->dentry); kfree(ent->name); kfree(ent); -- cgit v1.2.3 From a65e659d97bc652b2e14a63beaf9efbf5d4e18b2 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Fri, 12 Nov 2010 14:47:02 -0800 Subject: staging: fix ste_rmi4 build, depends on INPUT The synaptics_i2c_rmi4 driver uses input_*() interfaces, so it should depend on INPUT to fix its build errors: ERROR: "input_event" [drivers/staging/ste_rmi4/synaptics_i2c_rmi4.ko] undefined! ERROR: "input_free_device" [drivers/staging/ste_rmi4/synaptics_i2c_rmi4.ko] undefined! ERROR: "input_register_device" [drivers/staging/ste_rmi4/synaptics_i2c_rmi4.ko] undefined! ERROR: "input_set_abs_params" [drivers/staging/ste_rmi4/synaptics_i2c_rmi4.ko] undefined! ERROR: "input_allocate_device" [drivers/staging/ste_rmi4/synaptics_i2c_rmi4.ko] undefined! ERROR: "input_unregister_device" [drivers/staging/ste_rmi4/synaptics_i2c_rmi4.ko] undefined! Signed-off-by: Randy Dunlap Cc: naveen.gaddipati@stericsson.com, js.ha@stericsson.com Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ste_rmi4/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/ste_rmi4/Kconfig b/drivers/staging/ste_rmi4/Kconfig index 95fd5a915f0a..e8679509e525 100644 --- a/drivers/staging/ste_rmi4/Kconfig +++ b/drivers/staging/ste_rmi4/Kconfig @@ -1,6 +1,6 @@ config TOUCHSCREEN_SYNAPTICS_I2C_RMI4 tristate "Synaptics i2c rmi4 touchscreen" - depends on I2C + depends on I2C && INPUT help Say Y here if you have a Synaptics RMI4 and want to enable support for the built-in touchscreen. -- cgit v1.2.3 From 62af33ec6e73d658720ea1190861c8c0609a94b3 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Thu, 11 Nov 2010 10:44:22 -0800 Subject: staging/easycap: make module params private/static, fix build The easycap driver has module parameters (bars, gain, & debug) with global scope that intrude on the kernel namespace and cause build problems. Change the names of them to be driver-specific and make 2 of them static. drivers/built-in.o:(.bss+0x97c00): multiple definition of `debug' ld: Warning: size of symbol `debug' changed from 58 in arch/x86/built-in.o to 4 in drivers/built-in.o Signed-off-by: Randy Dunlap Cc: Mike Thomas Signed-off-by: Greg Kroah-Hartman --- drivers/staging/easycap/easycap.h | 4 ++-- drivers/staging/easycap/easycap_debug.h | 4 ++-- drivers/staging/easycap/easycap_low.c | 10 +++++----- drivers/staging/easycap/easycap_main.c | 18 +++++++++--------- 4 files changed, 18 insertions(+), 18 deletions(-) diff --git a/drivers/staging/easycap/easycap.h b/drivers/staging/easycap/easycap.h index cc8e8c581ae8..ea4259179325 100644 --- a/drivers/staging/easycap/easycap.h +++ b/drivers/staging/easycap/easycap.h @@ -630,13 +630,13 @@ unsigned long long int remainder; #if defined(EASYCAP_DEBUG) #define JOT(n, format, args...) do { \ - if (n <= debug) { \ + if (n <= easycap_debug) { \ printk(KERN_DEBUG "easycap:: %s: " \ format, __func__, ##args);\ } \ } while (0) #define JOM(n, format, args...) do { \ - if (n <= debug) { \ + if (n <= easycap_debug) { \ printk(KERN_DEBUG "easycap::%i%s: " \ format, peasycap->isdongle, __func__, ##args);\ } \ diff --git a/drivers/staging/easycap/easycap_debug.h b/drivers/staging/easycap/easycap_debug.h index 518392e0d72d..b6b571843125 100644 --- a/drivers/staging/easycap/easycap_debug.h +++ b/drivers/staging/easycap/easycap_debug.h @@ -24,6 +24,6 @@ * */ /*****************************************************************************/ -extern int debug; -extern int gain; +extern int easycap_debug; +extern int easycap_gain; extern struct easycap_dongle easycap_dongle[]; diff --git a/drivers/staging/easycap/easycap_low.c b/drivers/staging/easycap/easycap_low.c index b75db82bba73..28c4d1e3c02f 100644 --- a/drivers/staging/easycap/easycap_low.c +++ b/drivers/staging/easycap/easycap_low.c @@ -1082,11 +1082,11 @@ SAM("0x%04X:0x%04X is audio vendor id\n", id1, id2); * SELECT AUDIO SOURCE "LINE IN" AND SET THE AUDIO GAIN. */ /*---------------------------------------------------------------------------*/ -if (31 < gain) - gain = 31; -if (0 > gain) - gain = 0; -if (0 != audio_gainset(pusb_device, (__s8)gain)) +if (31 < easycap_gain) + easycap_gain = 31; +if (0 > easycap_gain) + easycap_gain = 0; +if (0 != audio_gainset(pusb_device, (__s8)easycap_gain)) SAY("ERROR: audio_gainset() failed\n"); check_vt(pusb_device); return 0; diff --git a/drivers/staging/easycap/easycap_main.c b/drivers/staging/easycap/easycap_main.c index 25e41784f4e5..acc1f56e6f29 100644 --- a/drivers/staging/easycap/easycap_main.c +++ b/drivers/staging/easycap/easycap_main.c @@ -32,12 +32,12 @@ #include "easycap_standard.h" #include "easycap_ioctl.h" -int debug; -int bars; -int gain = 16; -module_param(debug, int, S_IRUGO | S_IWUSR); -module_param(bars, int, S_IRUGO | S_IWUSR); -module_param(gain, int, S_IRUGO | S_IWUSR); +static int easycap_debug; +static int easycap_bars; +int easycap_gain = 16; +module_param_named(debug, easycap_debug, int, S_IRUGO | S_IWUSR); +module_param_named(bars, easycap_bars, int, S_IRUGO | S_IWUSR); +module_param_named(gain, easycap_gain, int, S_IRUGO | S_IWUSR); /*---------------------------------------------------------------------------*/ /* @@ -1464,7 +1464,7 @@ if (peasycap->field_read == peasycap->field_fill) { easycap_testcard(peasycap, peasycap->field_read); #else if (0 <= input && INPUT_MANY > input) { - if (bars && VIDEO_LOST_TOLERATE <= peasycap->lost[input]) + if (easycap_bars && VIDEO_LOST_TOLERATE <= peasycap->lost[input]) easycap_testcard(peasycap, peasycap->field_read); } #endif /*EASYCAP_TESTCARD*/ @@ -5008,8 +5008,8 @@ easycap_module_init(void) int result; SAY("========easycap=======\n"); -JOT(4, "begins. %i=debug %i=bars %i=gain\n", debug, bars, \ - gain); +JOT(4, "begins. %i=debug %i=bars %i=gain\n", easycap_debug, easycap_bars, \ + easycap_gain); SAY("version: " EASYCAP_DRIVER_VERSION "\n"); /*---------------------------------------------------------------------------*/ /* -- cgit v1.2.3 From a1a26e492c4a90466cb3e064ccf69db4dd66d63a Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Sat, 13 Nov 2010 11:34:16 +0300 Subject: Staging: cptm1217: move free under dereference We dereference "ts" in the printk so move the kfree() down a line. Signed-off-by: Dan Carpenter Acked-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/staging/cptm1217/clearpad_tm1217.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/cptm1217/clearpad_tm1217.c b/drivers/staging/cptm1217/clearpad_tm1217.c index 269503f9516f..76e4b782d2fb 100644 --- a/drivers/staging/cptm1217/clearpad_tm1217.c +++ b/drivers/staging/cptm1217/clearpad_tm1217.c @@ -460,9 +460,9 @@ static int cp_tm1217_probe(struct i2c_client *client, for (i = 0; i < TOUCH_SUPPORTED; i++) { input_dev = input_allocate_device(); if (input_dev == NULL) { - kfree(ts); dev_err(ts->dev, "cp_tm1217:Input Device Struct alloc failed\n"); + kfree(ts); return -ENOMEM; } input_info = &ts->cp_input_info[i]; -- cgit v1.2.3 From 59a126418b96e9f5337d431e6024a8d50bbd6e4e Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Sat, 13 Nov 2010 12:05:32 +0300 Subject: Staging: iio/dds: double locking bugs This is a static checker patch and I don't have this hardware. This code is unusual because while I've often seen a double lock, this is the first time I've seen code that takes a lock 11 times in a row. I feel like I must have missed something. But I've looked very carefully I don't see any way the original code is correct. Does spi_sync() somehow release the lock in a way that I can't see? Even if it does, the locking would still be wrong. Signed-off-by: Dan Carpenter Acked-by: Michael Hennerich Acked-by: Cliff Cai Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/dds/ad9832.c | 2 -- drivers/staging/iio/dds/ad9852.c | 11 +---------- drivers/staging/iio/dds/ad9910.c | 26 ++++++-------------------- drivers/staging/iio/dds/ad9951.c | 5 ----- 4 files changed, 7 insertions(+), 37 deletions(-) diff --git a/drivers/staging/iio/dds/ad9832.c b/drivers/staging/iio/dds/ad9832.c index a4bb0482ed5b..e911893b3db0 100644 --- a/drivers/staging/iio/dds/ad9832.c +++ b/drivers/staging/iio/dds/ad9832.c @@ -166,8 +166,6 @@ static void ad9832_init(struct ad9832_state *st) config = 0x3 << 14; - mutex_lock(&st->lock); - xfer.len = 2; xfer.tx_buf = &config; diff --git a/drivers/staging/iio/dds/ad9852.c b/drivers/staging/iio/dds/ad9852.c index 0a41d25583af..594fb6a94331 100644 --- a/drivers/staging/iio/dds/ad9852.c +++ b/drivers/staging/iio/dds/ad9852.c @@ -86,7 +86,6 @@ static ssize_t ad9852_set_parameter(struct device *dev, xfer.len = 3; xfer.tx_buf = &config->phajst1[0]; - mutex_lock(&st->lock); spi_message_init(&msg); spi_message_add_tail(&xfer, &msg); @@ -96,7 +95,6 @@ static ssize_t ad9852_set_parameter(struct device *dev, xfer.len = 6; xfer.tx_buf = &config->fretun1[0]; - mutex_lock(&st->lock); spi_message_init(&msg); spi_message_add_tail(&xfer, &msg); @@ -106,7 +104,6 @@ static ssize_t ad9852_set_parameter(struct device *dev, xfer.len = 6; xfer.tx_buf = &config->fretun2[0]; - mutex_lock(&st->lock); spi_message_init(&msg); spi_message_add_tail(&xfer, &msg); @@ -116,7 +113,6 @@ static ssize_t ad9852_set_parameter(struct device *dev, xfer.len = 6; xfer.tx_buf = &config->dltafre[0]; - mutex_lock(&st->lock); spi_message_init(&msg); spi_message_add_tail(&xfer, &msg); @@ -126,7 +122,6 @@ static ssize_t ad9852_set_parameter(struct device *dev, xfer.len = 5; xfer.tx_buf = &config->updtclk[0]; - mutex_lock(&st->lock); spi_message_init(&msg); spi_message_add_tail(&xfer, &msg); @@ -136,7 +131,6 @@ static ssize_t ad9852_set_parameter(struct device *dev, xfer.len = 4; xfer.tx_buf = &config->ramprat[0]; - mutex_lock(&st->lock); spi_message_init(&msg); spi_message_add_tail(&xfer, &msg); @@ -146,7 +140,6 @@ static ssize_t ad9852_set_parameter(struct device *dev, xfer.len = 5; xfer.tx_buf = &config->control[0]; - mutex_lock(&st->lock); spi_message_init(&msg); spi_message_add_tail(&xfer, &msg); @@ -156,7 +149,6 @@ static ssize_t ad9852_set_parameter(struct device *dev, xfer.len = 3; xfer.tx_buf = &config->outpskm[0]; - mutex_lock(&st->lock); spi_message_init(&msg); spi_message_add_tail(&xfer, &msg); @@ -166,16 +158,15 @@ static ssize_t ad9852_set_parameter(struct device *dev, xfer.len = 2; xfer.tx_buf = &config->outpskr[0]; - mutex_lock(&st->lock); spi_message_init(&msg); spi_message_add_tail(&xfer, &msg); ret = spi_sync(st->sdev, &msg); if (ret) goto error_ret; + xfer.len = 3; xfer.tx_buf = &config->daccntl[0]; - mutex_lock(&st->lock); spi_message_init(&msg); spi_message_add_tail(&xfer, &msg); diff --git a/drivers/staging/iio/dds/ad9910.c b/drivers/staging/iio/dds/ad9910.c index c59b40794768..e8fb75cb66ec 100644 --- a/drivers/staging/iio/dds/ad9910.c +++ b/drivers/staging/iio/dds/ad9910.c @@ -138,7 +138,6 @@ static ssize_t ad9910_set_parameter(struct device *dev, xfer.len = 5; xfer.tx_buf = &config->ioupd[0]; - mutex_lock(&st->lock); spi_message_init(&msg); spi_message_add_tail(&xfer, &msg); @@ -148,7 +147,6 @@ static ssize_t ad9910_set_parameter(struct device *dev, xfer.len = 5; xfer.tx_buf = &config->ftw[0]; - mutex_lock(&st->lock); spi_message_init(&msg); spi_message_add_tail(&xfer, &msg); @@ -158,7 +156,6 @@ static ssize_t ad9910_set_parameter(struct device *dev, xfer.len = 3; xfer.tx_buf = &config->pow[0]; - mutex_lock(&st->lock); spi_message_init(&msg); spi_message_add_tail(&xfer, &msg); @@ -168,7 +165,6 @@ static ssize_t ad9910_set_parameter(struct device *dev, xfer.len = 5; xfer.tx_buf = &config->asf[0]; - mutex_lock(&st->lock); spi_message_init(&msg); spi_message_add_tail(&xfer, &msg); @@ -178,7 +174,6 @@ static ssize_t ad9910_set_parameter(struct device *dev, xfer.len = 5; xfer.tx_buf = &config->multc[0]; - mutex_lock(&st->lock); spi_message_init(&msg); spi_message_add_tail(&xfer, &msg); @@ -188,7 +183,6 @@ static ssize_t ad9910_set_parameter(struct device *dev, xfer.len = 9; xfer.tx_buf = &config->dig_rampl[0]; - mutex_lock(&st->lock); spi_message_init(&msg); spi_message_add_tail(&xfer, &msg); @@ -198,7 +192,6 @@ static ssize_t ad9910_set_parameter(struct device *dev, xfer.len = 9; xfer.tx_buf = &config->dig_ramps[0]; - mutex_lock(&st->lock); spi_message_init(&msg); spi_message_add_tail(&xfer, &msg); @@ -208,7 +201,6 @@ static ssize_t ad9910_set_parameter(struct device *dev, xfer.len = 5; xfer.tx_buf = &config->dig_rampr[0]; - mutex_lock(&st->lock); spi_message_init(&msg); spi_message_add_tail(&xfer, &msg); @@ -218,25 +210,24 @@ static ssize_t ad9910_set_parameter(struct device *dev, xfer.len = 9; xfer.tx_buf = &config->sin_tonep0[0]; - mutex_lock(&st->lock); spi_message_init(&msg); spi_message_add_tail(&xfer, &msg); ret = spi_sync(st->sdev, &msg); if (ret) goto error_ret; + xfer.len = 9; xfer.tx_buf = &config->sin_tonep1[0]; - mutex_lock(&st->lock); spi_message_init(&msg); spi_message_add_tail(&xfer, &msg); ret = spi_sync(st->sdev, &msg); if (ret) goto error_ret; + xfer.len = 9; xfer.tx_buf = &config->sin_tonep2[0]; - mutex_lock(&st->lock); spi_message_init(&msg); spi_message_add_tail(&xfer, &msg); @@ -245,43 +236,42 @@ static ssize_t ad9910_set_parameter(struct device *dev, goto error_ret; xfer.len = 9; xfer.tx_buf = &config->sin_tonep3[0]; - mutex_lock(&st->lock); spi_message_init(&msg); spi_message_add_tail(&xfer, &msg); ret = spi_sync(st->sdev, &msg); if (ret) goto error_ret; + xfer.len = 9; xfer.tx_buf = &config->sin_tonep4[0]; - mutex_lock(&st->lock); spi_message_init(&msg); spi_message_add_tail(&xfer, &msg); ret = spi_sync(st->sdev, &msg); if (ret) goto error_ret; + xfer.len = 9; xfer.tx_buf = &config->sin_tonep5[0]; - mutex_lock(&st->lock); spi_message_init(&msg); spi_message_add_tail(&xfer, &msg); ret = spi_sync(st->sdev, &msg); if (ret) goto error_ret; + xfer.len = 9; xfer.tx_buf = &config->sin_tonep6[0]; - mutex_lock(&st->lock); spi_message_init(&msg); spi_message_add_tail(&xfer, &msg); ret = spi_sync(st->sdev, &msg); if (ret) goto error_ret; + xfer.len = 9; xfer.tx_buf = &config->sin_tonep7[0]; - mutex_lock(&st->lock); spi_message_init(&msg); spi_message_add_tail(&xfer, &msg); @@ -326,8 +316,6 @@ static void ad9910_init(struct ad9910_state *st) cfr[3] = TX_ENA | PDCLK_INV | PDCLK_ENB; cfr[4] = PARA_ENA; - mutex_lock(&st->lock); - xfer.len = 5; xfer.tx_buf = 𝔠 @@ -343,8 +331,6 @@ static void ad9910_init(struct ad9910_state *st) cfr[3] = REFCLK_RST | REFCLK_BYP; cfr[4] = 0; - mutex_lock(&st->lock); - xfer.len = 5; xfer.tx_buf = 𝔠 diff --git a/drivers/staging/iio/dds/ad9951.c b/drivers/staging/iio/dds/ad9951.c index bc3befff167a..57eddf6d4713 100644 --- a/drivers/staging/iio/dds/ad9951.c +++ b/drivers/staging/iio/dds/ad9951.c @@ -79,7 +79,6 @@ static ssize_t ad9951_set_parameter(struct device *dev, xfer.len = 2; xfer.tx_buf = &config->arr[0]; - mutex_lock(&st->lock); spi_message_init(&msg); spi_message_add_tail(&xfer, &msg); @@ -89,7 +88,6 @@ static ssize_t ad9951_set_parameter(struct device *dev, xfer.len = 5; xfer.tx_buf = &config->ftw0[0]; - mutex_lock(&st->lock); spi_message_init(&msg); spi_message_add_tail(&xfer, &msg); @@ -99,7 +97,6 @@ static ssize_t ad9951_set_parameter(struct device *dev, xfer.len = 3; xfer.tx_buf = &config->ftw1[0]; - mutex_lock(&st->lock); spi_message_init(&msg); spi_message_add_tail(&xfer, &msg); @@ -143,8 +140,6 @@ static void ad9951_init(struct ad9951_state *st) cfr[2] = HSPD_SYNC; cfr[3] = 0; - mutex_lock(&st->lock); - xfer.len = 4; xfer.tx_buf = 𝔠 -- cgit v1.2.3 From 0ebce2696305c3f49f54f3af25cb966ef1b24f71 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Sat, 13 Nov 2010 08:44:35 -0800 Subject: staging: fix iio/gyro typos, build errors Typo causes build errors. Did anyone even build this driver? Signed-off-by: Randy Dunlap Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/gyro/adis16251.h | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/staging/iio/gyro/adis16251.h b/drivers/staging/iio/gyro/adis16251.h index 999db4981413..d23852cf78e8 100644 --- a/drivers/staging/iio/gyro/adis16251.h +++ b/drivers/staging/iio/gyro/adis16251.h @@ -56,14 +56,14 @@ #define ADIS16251_DIAG_STAT_POWER_HIGH (1<<1) #define ADIS16251_DIAG_STAT_POWER_LOW (1<<0) -#define ADIS16251_DIAG_STAT_ERR_MASK (ADIS16261_DIAG_STAT_ALARM2 | \ - ADIS16261_DIAG_STAT_ALARM1 | \ - ADIS16261_DIAG_STAT_SELF_TEST | \ - ADIS16261_DIAG_STAT_OVERFLOW | \ - ADIS16261_DIAG_STAT_SPI_FAIL | \ - ADIS16261_DIAG_STAT_FLASH_UPT | \ - ADIS16261_DIAG_STAT_POWER_HIGH | \ - ADIS16261_DIAG_STAT_POWER_LOW) +#define ADIS16251_DIAG_STAT_ERR_MASK (ADIS16251_DIAG_STAT_ALARM2 | \ + ADIS16251_DIAG_STAT_ALARM1 | \ + ADIS16251_DIAG_STAT_SELF_TEST | \ + ADIS16251_DIAG_STAT_OVERFLOW | \ + ADIS16251_DIAG_STAT_SPI_FAIL | \ + ADIS16251_DIAG_STAT_FLASH_UPT | \ + ADIS16251_DIAG_STAT_POWER_HIGH | \ + ADIS16251_DIAG_STAT_POWER_LOW) /* GLOB_CMD */ #define ADIS16251_GLOB_CMD_SW_RESET (1<<7) -- cgit v1.2.3 From f05321cca53da7c7abad4bc726699e9f27bf4922 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Sat, 13 Nov 2010 07:37:49 +0300 Subject: Staging: bcm: signedness bug in StoreSFParam() wrm() returns negative error codes so "ret" needs to be signed here. There was place where wrm() returned positive EACCES instead of negative -EACCES so I fixed that as well. Also a few checkpatch.pl issues. Signed-off-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/CmHost.c | 8 ++++---- drivers/staging/bcm/InterfaceMisc.c | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/staging/bcm/CmHost.c b/drivers/staging/bcm/CmHost.c index a685cadb778d..5ac45820d564 100644 --- a/drivers/staging/bcm/CmHost.c +++ b/drivers/staging/bcm/CmHost.c @@ -1649,17 +1649,17 @@ static inline ULONG RestoreSFParam(PMINI_ADAPTER Adapter, ULONG ulAddrSFParamSet static ULONG StoreSFParam(PMINI_ADAPTER Adapter,PUCHAR pucSrcBuffer,ULONG ulAddrSFParamSet) { UINT nBytesToWrite = sizeof(stServiceFlowParamSI); - UINT uiRetVal =0; + int ret = 0; if(ulAddrSFParamSet == 0 || NULL == pucSrcBuffer) { return 0; } - uiRetVal = wrm(Adapter,ulAddrSFParamSet,(PUCHAR)pucSrcBuffer, nBytesToWrite); - if(uiRetVal < 0) { + ret = wrm(Adapter, ulAddrSFParamSet, (u8 *)pucSrcBuffer, nBytesToWrite); + if (ret < 0) { BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, CONN_MSG, DBG_LVL_ALL, "%s:%d WRM failed",__FUNCTION__, __LINE__); - return uiRetVal; + return ret; } return 1; } diff --git a/drivers/staging/bcm/InterfaceMisc.c b/drivers/staging/bcm/InterfaceMisc.c index b7d6e7a414a9..a51185b522cf 100644 --- a/drivers/staging/bcm/InterfaceMisc.c +++ b/drivers/staging/bcm/InterfaceMisc.c @@ -90,7 +90,7 @@ InterfaceWRM(PS_INTERFACE_ADAPTER psIntfAdapter, if((psIntfAdapter->psAdapter->StopAllXaction == TRUE) && (psIntfAdapter->psAdapter->chip_id >= T3LPB)) { BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_OTHERS, WRM, DBG_LVL_ALL,"Currently Xaction is not allowed on the bus..."); - return EACCES; + return -EACCES; } if(psIntfAdapter->bSuspended ==TRUE || psIntfAdapter->bPreparingForBusSuspend == TRUE) -- cgit v1.2.3 From 2e3161390130f50fdbb4b989c667f42e5008107f Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Sat, 13 Nov 2010 11:24:22 +0300 Subject: Staging: bcm: signedness bug in InitCardAndDownloadFirmware() status is used to store negative error codes throughout. The only place where this is a runtime bug is if create_worker_threads() fails. Signed-off-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/Misc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/bcm/Misc.c b/drivers/staging/bcm/Misc.c index 023c511c0001..9588fbe101d9 100644 --- a/drivers/staging/bcm/Misc.c +++ b/drivers/staging/bcm/Misc.c @@ -1079,7 +1079,7 @@ int run_card_proc(PMINI_ADAPTER ps_adapter ) int InitCardAndDownloadFirmware(PMINI_ADAPTER ps_adapter) { - UINT status = STATUS_SUCCESS; + int status; UINT value = 0; /* * Create the threads first and then download the -- cgit v1.2.3 From 1070137de3e3b0f3fdfedc420a06a43d05a6e705 Mon Sep 17 00:00:00 2001 From: Brett Rudley Date: Tue, 16 Nov 2010 13:16:58 -0800 Subject: staging: brcm80211: expose osl contents and start combining osl and pub_osl. Signed-off-by: Brett Rudley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/include/linux_osl.h | 13 ------------- drivers/staging/brcm80211/include/osl.h | 26 ++++++++++++++++++++++++-- drivers/staging/brcm80211/util/linux_osl.c | 7 ------- 3 files changed, 24 insertions(+), 22 deletions(-) diff --git a/drivers/staging/brcm80211/include/linux_osl.h b/drivers/staging/brcm80211/include/linux_osl.h index 0fb6e1c86793..1181f014a114 100644 --- a/drivers/staging/brcm80211/include/linux_osl.h +++ b/drivers/staging/brcm80211/include/linux_osl.h @@ -54,19 +54,6 @@ extern void osl_pci_write_config(osl_t *osh, uint offset, uint size, uint val); extern uint osl_pci_bus(osl_t *osh); extern uint osl_pci_slot(osl_t *osh); -/* Pkttag flag should be part of public information */ -typedef struct { - uint pktalloced; /* Number of allocated packet buffers */ - bool mmbus; /* Bus supports memory-mapped register accesses */ - pktfree_cb_fn_t tx_fn; /* Callback function for PKTFREE */ - void *tx_ctx; /* Context to the callback function */ -#if defined(BCMSDIO) && !defined(BRCM_FULLMAC) - osl_rreg_fn_t rreg_fn; /* Read Register function */ - osl_wreg_fn_t wreg_fn; /* Write Register function */ - void *reg_ctx; /* Context to the reg callback functions */ -#endif -} osl_pubinfo_t; - #define PKTFREESETCB(osh, _tx_fn, _tx_ctx) \ do { \ ((osl_pubinfo_t *)osh)->tx_fn = _tx_fn; \ diff --git a/drivers/staging/brcm80211/include/osl.h b/drivers/staging/brcm80211/include/osl.h index bcb56aa5dc96..0cdd15d992fa 100644 --- a/drivers/staging/brcm80211/include/osl.h +++ b/drivers/staging/brcm80211/include/osl.h @@ -17,12 +17,34 @@ #ifndef _osl_h_ #define _osl_h_ +/* Drivers use PKTFREESETCB to register a callback function + when a packet is freed by OSL */ +typedef void (*pktfree_cb_fn_t) (void *ctx, void *pkt, unsigned int status); + +struct osl_pubinfo { + uint pktalloced; /* Number of allocated packet buffers */ + bool mmbus; /* Bus supports memory-mapped registers */ + pktfree_cb_fn_t tx_fn; /* Callback function for PKTFREE */ + void *tx_ctx; /* Context to the callback function */ +#if defined(BCMSDIO) && !defined(BRCM_FULLMAC) + osl_rreg_fn_t rreg_fn; /* Read Register function */ + osl_wreg_fn_t wreg_fn; /* Write Register function */ + void *reg_ctx; /* Context to the reg callback functions */ +#endif +}; + /* osl handle type forward declaration */ +struct osl_info { + struct osl_pubinfo pub; + uint magic; + void *pdev; + uint bustype; +}; + typedef struct osl_info osl_t; +typedef struct osl_pubinfo osl_pubinfo_t; typedef struct osl_dmainfo osldma_t; -/* Drivers use PKTFREESETCB to register a callback function when a packet is freed by OSL */ -typedef void (*pktfree_cb_fn_t) (void *ctx, void *pkt, unsigned int status); #ifdef BCMSDIO /* Drivers use REGOPSSET() to register register read/write funcitons */ diff --git a/drivers/staging/brcm80211/util/linux_osl.c b/drivers/staging/brcm80211/util/linux_osl.c index 625cbacc8665..3869de75d8c8 100644 --- a/drivers/staging/brcm80211/util/linux_osl.c +++ b/drivers/staging/brcm80211/util/linux_osl.c @@ -33,13 +33,6 @@ #define OS_HANDLE_MAGIC 0x1234abcd /* Magic # to recognise osh */ #define BCM_MEM_FILENAME_LEN 24 /* Mem. filename length */ -struct osl_info { - osl_pubinfo_t pub; - uint magic; - void *pdev; - uint bustype; -}; - /* Global ASSERT type flag */ u32 g_assert_type; -- cgit v1.2.3 From e6a12a07d0b06f8e614a212e26002e62071242e8 Mon Sep 17 00:00:00 2001 From: Brett Rudley Date: Tue, 16 Nov 2010 13:16:59 -0800 Subject: staging: brcm80211: completely remove osl_pubinfo_t typedef Signed-off-by: Brett Rudley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/include/linux_osl.h | 29 ++++++++++++++------------- drivers/staging/brcm80211/include/osl.h | 1 - drivers/staging/brcm80211/util/linux_osl.c | 24 +++++++++++----------- 3 files changed, 27 insertions(+), 27 deletions(-) diff --git a/drivers/staging/brcm80211/include/linux_osl.h b/drivers/staging/brcm80211/include/linux_osl.h index 1181f014a114..124b579f87c5 100644 --- a/drivers/staging/brcm80211/include/linux_osl.h +++ b/drivers/staging/brcm80211/include/linux_osl.h @@ -56,16 +56,16 @@ extern uint osl_pci_slot(osl_t *osh); #define PKTFREESETCB(osh, _tx_fn, _tx_ctx) \ do { \ - ((osl_pubinfo_t *)osh)->tx_fn = _tx_fn; \ - ((osl_pubinfo_t *)osh)->tx_ctx = _tx_ctx; \ + ((struct osl_pubinfo *)osh)->tx_fn = _tx_fn; \ + ((struct osl_pubinfo *)osh)->tx_ctx = _tx_ctx; \ } while (0) #if defined(BCMSDIO) && !defined(BRCM_FULLMAC) #define REGOPSSET(osh, rreg, wreg, ctx) \ do { \ - ((osl_pubinfo_t *)osh)->rreg_fn = rreg; \ - ((osl_pubinfo_t *)osh)->wreg_fn = wreg; \ - ((osl_pubinfo_t *)osh)->reg_ctx = ctx; \ + ((struct osl_pubinfo *)osh)->rreg_fn = rreg; \ + ((struct osl_pubinfo *)osh)->wreg_fn = wreg; \ + ((struct osl_pubinfo *)osh)->reg_ctx = ctx; \ } while (0) #endif @@ -111,10 +111,11 @@ extern void osl_dma_unmap(osl_t *osh, uint pa, uint size, int direction); #endif #if defined(BCMSDIO) -#define SELECT_BUS_WRITE(osh, mmap_op, bus_op) if (((osl_pubinfo_t *)(osh))->mmbus) \ +#define SELECT_BUS_WRITE(osh, mmap_op, bus_op) \ + if (((struct osl_pubinfo *)(osh))->mmbus) \ mmap_op else bus_op -#define SELECT_BUS_READ(osh, mmap_op, bus_op) (((osl_pubinfo_t *)(osh))->mmbus) ? \ - mmap_op : bus_op +#define SELECT_BUS_READ(osh, mmap_op, bus_op) \ + (((struct osl_pubinfo *)(osh))->mmbus) ? mmap_op : bus_op #else #define SELECT_BUS_WRITE(osh, mmap_op, bus_op) mmap_op #define SELECT_BUS_READ(osh, mmap_op, bus_op) mmap_op @@ -271,7 +272,7 @@ extern void osl_dma_unmap(osl_t *osh, uint pa, uint size, int direction); #define PKTSETLEN(skb, len) __skb_trim((struct sk_buff *)(skb), (len)) #define PKTPUSH(skb, bytes) skb_push((struct sk_buff *)(skb), (bytes)) #define PKTPULL(skb, bytes) skb_pull((struct sk_buff *)(skb), (bytes)) -#define PKTALLOCED(osh) (((osl_pubinfo_t *)(osh))->pktalloced) +#define PKTALLOCED(osh) (((struct osl_pubinfo *)(osh))->pktalloced) #define PKTSETPOOL(osh, skb, x, y) do {} while (0) #define PKTPOOL(osh, skb) false extern void *osl_pktget(osl_t *osh, uint len); @@ -279,7 +280,7 @@ extern void osl_pktfree(osl_t *osh, void *skb, bool send); #ifdef BRCM_FULLMAC static inline void * -osl_pkt_frmnative(osl_pubinfo_t *osh, struct sk_buff *skb) +osl_pkt_frmnative(struct osl_pubinfo *osh, struct sk_buff *skb) { struct sk_buff *nskb; @@ -289,10 +290,10 @@ osl_pkt_frmnative(osl_pubinfo_t *osh, struct sk_buff *skb) return (void *)skb; } #define PKTFRMNATIVE(osh, skb) \ - osl_pkt_frmnative(((osl_pubinfo_t *)osh), (struct sk_buff*)(skb)) + osl_pkt_frmnative(((struct osl_pubinfo *)osh), (struct sk_buff*)(skb)) static inline struct sk_buff * -osl_pkt_tonative(osl_pubinfo_t *osh, void *pkt) +osl_pkt_tonative(struct osl_pubinfo *osh, void *pkt) { struct sk_buff *nskb; @@ -302,9 +303,9 @@ osl_pkt_tonative(osl_pubinfo_t *osh, void *pkt) return (struct sk_buff *)pkt; } #define PKTTONATIVE(osh, pkt) \ - osl_pkt_tonative((osl_pubinfo_t *)(osh), (pkt)) + osl_pkt_tonative((struct osl_pubinfo *)(osh), (pkt)) #else /* !BRCM_FULLMAC */ -#define PKTUNALLOC(osh) (((osl_pubinfo_t *)(osh))->pktalloced--) +#define PKTUNALLOC(osh) (((struct osl_pubinfo *)(osh))->pktalloced--) #define PKTSETSKIPCT(osh, skb) #define PKTCLRSKIPCT(osh, skb) diff --git a/drivers/staging/brcm80211/include/osl.h b/drivers/staging/brcm80211/include/osl.h index 0cdd15d992fa..5a9bc59e9217 100644 --- a/drivers/staging/brcm80211/include/osl.h +++ b/drivers/staging/brcm80211/include/osl.h @@ -42,7 +42,6 @@ struct osl_info { }; typedef struct osl_info osl_t; -typedef struct osl_pubinfo osl_pubinfo_t; typedef struct osl_dmainfo osldma_t; diff --git a/drivers/staging/brcm80211/util/linux_osl.c b/drivers/staging/brcm80211/util/linux_osl.c index 3869de75d8c8..eb5d285efc04 100644 --- a/drivers/staging/brcm80211/util/linux_osl.c +++ b/drivers/staging/brcm80211/util/linux_osl.c @@ -245,48 +245,48 @@ void osl_assert(char *exp, char *file, int line) #if defined(BCMSDIO) && !defined(BRCM_FULLMAC) u8 osl_readb(osl_t *osh, volatile u8 *r) { - osl_rreg_fn_t rreg = ((osl_pubinfo_t *) osh)->rreg_fn; - void *ctx = ((osl_pubinfo_t *) osh)->reg_ctx; + osl_rreg_fn_t rreg = ((struct osl_pubinfo *) osh)->rreg_fn; + void *ctx = ((struct osl_pubinfo *) osh)->reg_ctx; return (u8) ((rreg) (ctx, (void *)r, sizeof(u8))); } u16 osl_readw(osl_t *osh, volatile u16 *r) { - osl_rreg_fn_t rreg = ((osl_pubinfo_t *) osh)->rreg_fn; - void *ctx = ((osl_pubinfo_t *) osh)->reg_ctx; + osl_rreg_fn_t rreg = ((struct osl_pubinfo *) osh)->rreg_fn; + void *ctx = ((struct osl_pubinfo *) osh)->reg_ctx; return (u16) ((rreg) (ctx, (void *)r, sizeof(u16))); } u32 osl_readl(osl_t *osh, volatile u32 *r) { - osl_rreg_fn_t rreg = ((osl_pubinfo_t *) osh)->rreg_fn; - void *ctx = ((osl_pubinfo_t *) osh)->reg_ctx; + osl_rreg_fn_t rreg = ((struct osl_pubinfo *) osh)->rreg_fn; + void *ctx = ((struct osl_pubinfo *) osh)->reg_ctx; return (u32) ((rreg) (ctx, (void *)r, sizeof(u32))); } void osl_writeb(osl_t *osh, volatile u8 *r, u8 v) { - osl_wreg_fn_t wreg = ((osl_pubinfo_t *) osh)->wreg_fn; - void *ctx = ((osl_pubinfo_t *) osh)->reg_ctx; + osl_wreg_fn_t wreg = ((struct osl_pubinfo *) osh)->wreg_fn; + void *ctx = ((struct osl_pubinfo *) osh)->reg_ctx; ((wreg) (ctx, (void *)r, v, sizeof(u8))); } void osl_writew(osl_t *osh, volatile u16 *r, u16 v) { - osl_wreg_fn_t wreg = ((osl_pubinfo_t *) osh)->wreg_fn; - void *ctx = ((osl_pubinfo_t *) osh)->reg_ctx; + osl_wreg_fn_t wreg = ((struct osl_pubinfo *) osh)->wreg_fn; + void *ctx = ((struct osl_pubinfo *) osh)->reg_ctx; ((wreg) (ctx, (void *)r, v, sizeof(u16))); } void osl_writel(osl_t *osh, volatile u32 *r, u32 v) { - osl_wreg_fn_t wreg = ((osl_pubinfo_t *) osh)->wreg_fn; - void *ctx = ((osl_pubinfo_t *) osh)->reg_ctx; + osl_wreg_fn_t wreg = ((struct osl_pubinfo *) osh)->wreg_fn; + void *ctx = ((struct osl_pubinfo *) osh)->reg_ctx; ((wreg) (ctx, (void *)r, v, sizeof(u32))); } -- cgit v1.2.3 From e69284f24320e2589dbd78bf531ffa18d097ae4c Mon Sep 17 00:00:00 2001 From: Brett Rudley Date: Tue, 16 Nov 2010 15:45:48 -0800 Subject: staging: brcm80211: s/osl_t/struct osl_info/g Do the substitution (and then fix all the dang lines that were pushed past 80 columns.) Some of the touched lines triggered checkpatch warnings for completely unrelated reasons that were already there. Those will have to be addressed later. Signed-off-by: Brett Rudley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmfmac/bcmsdh.c | 7 ++- drivers/staging/brcm80211/brcmfmac/bcmsdh_linux.c | 10 ++-- drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c | 4 +- drivers/staging/brcm80211/brcmfmac/dhd.h | 9 +-- drivers/staging/brcm80211/brcmfmac/dhd_bus.h | 4 +- drivers/staging/brcm80211/brcmfmac/dhd_linux.c | 7 ++- drivers/staging/brcm80211/brcmfmac/dhd_sdio.c | 54 +++++++++-------- drivers/staging/brcm80211/include/bcm_rpc.h | 2 +- drivers/staging/brcm80211/include/bcm_rpc_tp.h | 2 +- drivers/staging/brcm80211/include/bcmsdbus.h | 4 +- drivers/staging/brcm80211/include/bcmsdh.h | 10 ++-- drivers/staging/brcm80211/include/bcmsdh_sdmmc.h | 6 +- drivers/staging/brcm80211/include/bcmsrom.h | 8 +-- drivers/staging/brcm80211/include/bcmutils.h | 18 +++--- drivers/staging/brcm80211/include/hnddma.h | 4 +- drivers/staging/brcm80211/include/hndpmu.h | 44 +++++++------- drivers/staging/brcm80211/include/linux_osl.h | 42 +++++++------ drivers/staging/brcm80211/include/nicpci.h | 10 ++-- drivers/staging/brcm80211/include/osl.h | 1 - drivers/staging/brcm80211/include/rpc_osl.h | 2 +- drivers/staging/brcm80211/include/siutils.h | 10 ++-- drivers/staging/brcm80211/phy/wlc_phy_cmn.c | 16 ++--- drivers/staging/brcm80211/phy/wlc_phy_int.h | 2 +- drivers/staging/brcm80211/sys/wl_export.h | 8 +-- drivers/staging/brcm80211/sys/wl_mac80211.c | 4 +- drivers/staging/brcm80211/sys/wl_mac80211.h | 2 +- drivers/staging/brcm80211/sys/wlc_alloc.c | 20 ++++--- drivers/staging/brcm80211/sys/wlc_alloc.h | 10 ++-- drivers/staging/brcm80211/sys/wlc_ampdu.c | 2 +- drivers/staging/brcm80211/sys/wlc_antsel.c | 2 +- drivers/staging/brcm80211/sys/wlc_antsel.h | 2 +- drivers/staging/brcm80211/sys/wlc_bmac.c | 46 +++++++------- drivers/staging/brcm80211/sys/wlc_bmac.h | 4 +- drivers/staging/brcm80211/sys/wlc_mac80211.c | 36 +++++------ drivers/staging/brcm80211/sys/wlc_mac80211.h | 4 +- drivers/staging/brcm80211/sys/wlc_pub.h | 6 +- drivers/staging/brcm80211/util/bcmotp.c | 10 ++-- drivers/staging/brcm80211/util/bcmsrom.c | 61 ++++++++++--------- drivers/staging/brcm80211/util/bcmutils.c | 18 +++--- drivers/staging/brcm80211/util/hnddma.c | 24 ++++---- drivers/staging/brcm80211/util/hndpmu.c | 73 ++++++++++++----------- drivers/staging/brcm80211/util/linux_osl.c | 46 +++++++------- drivers/staging/brcm80211/util/nicpci.c | 23 +++---- drivers/staging/brcm80211/util/nvram/nvram_ro.c | 2 +- drivers/staging/brcm80211/util/siutils.c | 10 ++-- 45 files changed, 356 insertions(+), 333 deletions(-) diff --git a/drivers/staging/brcm80211/brcmfmac/bcmsdh.c b/drivers/staging/brcm80211/brcmfmac/bcmsdh.c index 6738983e2d5c..6171ebf56ff1 100644 --- a/drivers/staging/brcm80211/brcmfmac/bcmsdh.c +++ b/drivers/staging/brcm80211/brcmfmac/bcmsdh.c @@ -39,7 +39,7 @@ struct bcmsdh_info { bool init_success; /* underlying driver successfully attached */ void *sdioh; /* handler for sdioh */ u32 vendevid; /* Target Vendor and Device ID on SD bus */ - osl_t *osh; + struct osl_info *osh; bool regfail; /* Save status of last reg_read/reg_write call */ u32 sbwad; /* Save backplane window address */ @@ -56,7 +56,8 @@ void bcmsdh_enable_hw_oob_intr(bcmsdh_info_t *sdh, bool enable) } #endif -bcmsdh_info_t *bcmsdh_attach(osl_t *osh, void *cfghdl, void **regsva, uint irq) +bcmsdh_info_t *bcmsdh_attach(struct osl_info *osh, void *cfghdl, + void **regsva, uint irq) { bcmsdh_info_t *bcmsdh; @@ -85,7 +86,7 @@ bcmsdh_info_t *bcmsdh_attach(osl_t *osh, void *cfghdl, void **regsva, uint irq) return bcmsdh; } -int bcmsdh_detach(osl_t *osh, void *sdh) +int bcmsdh_detach(struct osl_info *osh, void *sdh) { bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh; diff --git a/drivers/staging/brcm80211/brcmfmac/bcmsdh_linux.c b/drivers/staging/brcm80211/brcmfmac/bcmsdh_linux.c index b021d97e59fa..6e32056451f1 100644 --- a/drivers/staging/brcm80211/brcmfmac/bcmsdh_linux.c +++ b/drivers/staging/brcm80211/brcmfmac/bcmsdh_linux.c @@ -56,7 +56,7 @@ struct bcmsdh_hc { #else struct pci_dev *dev; /* pci device handle */ #endif /* BCMPLATFORM_BUS */ - osl_t *osh; + struct osl_info *osh; void *regs; /* SDIO Host Controller address */ bcmsdh_info_t *sdh; /* SDIO Host Controller handle */ void *ch; @@ -142,7 +142,7 @@ static #endif /* BCMLXSDMMC */ int bcmsdh_probe(struct device *dev) { - osl_t *osh = NULL; + struct osl_info *osh = NULL; bcmsdh_hc_t *sdhc = NULL; unsigned long regs = 0; bcmsdh_info_t *sdh = NULL; @@ -246,7 +246,7 @@ static int bcmsdh_remove(struct device *dev) { bcmsdh_hc_t *sdhc, *prev; - osl_t *osh; + struct osl_info *osh; sdhc = sdhcinfo; drvinfo.detach(sdhc->ch); @@ -339,7 +339,7 @@ module_param(sd_pci_slot, uint, 0); static int __devinit bcmsdh_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { - osl_t *osh = NULL; + struct osl_info *osh = NULL; bcmsdh_hc_t *sdhc = NULL; unsigned long regs; bcmsdh_info_t *sdh = NULL; @@ -470,7 +470,7 @@ err: static void __devexit bcmsdh_pci_remove(struct pci_dev *pdev) { bcmsdh_hc_t *sdhc, *prev; - osl_t *osh; + struct osl_info *osh; /* find the SDIO Host Controller state for this pdev and take it out from the list */ diff --git a/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c b/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c index 039f114130d2..babda77d9326 100644 --- a/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c +++ b/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c @@ -112,7 +112,7 @@ static int sdioh_sdmmc_card_enablefuncs(sdioh_info_t *sd) /* * Public entry points & extern's */ -extern sdioh_info_t *sdioh_attach(osl_t *osh, void *bar0, uint irq) +extern sdioh_info_t *sdioh_attach(struct osl_info *osh, void *bar0, uint irq) { sdioh_info_t *sd; int err_ret; @@ -175,7 +175,7 @@ extern sdioh_info_t *sdioh_attach(osl_t *osh, void *bar0, uint irq) return sd; } -extern SDIOH_API_RC sdioh_detach(osl_t *osh, sdioh_info_t *sd) +extern SDIOH_API_RC sdioh_detach(struct osl_info *osh, sdioh_info_t *sd) { sd_trace(("%s\n", __func__)); diff --git a/drivers/staging/brcm80211/brcmfmac/dhd.h b/drivers/staging/brcm80211/brcmfmac/dhd.h index 57d06b2da46f..7785772ed917 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd.h +++ b/drivers/staging/brcm80211/brcmfmac/dhd.h @@ -77,7 +77,7 @@ enum dhd_prealloc_index { /* Common structure for module and instance linkage */ typedef struct dhd_pub { /* Linkage ponters */ - osl_t *osh; /* OSL handle */ + struct osl_info *osh; /* OSL handle */ struct dhd_bus *bus; /* Bus module handle */ struct dhd_prot *prot; /* Protocol module handle */ struct dhd_info *info; /* Info module handle */ @@ -277,15 +277,16 @@ typedef struct dhd_if_event { */ /* To allow osl_attach/detach calls from os-independent modules */ -osl_t *dhd_osl_attach(void *pdev, uint bustype); -void dhd_osl_detach(osl_t *osh); +struct osl_info *dhd_osl_attach(void *pdev, uint bustype); +void dhd_osl_detach(struct osl_info *osh); /* Indication from bus module regarding presence/insertion of dongle. * Return dhd_pub_t pointer, used as handle to OS module in later calls. * Returned structure should have bus and prot pointers filled in. * bus_hdrlen specifies required headroom for bus module header. */ -extern dhd_pub_t *dhd_attach(osl_t *osh, struct dhd_bus *bus, uint bus_hdrlen); +extern dhd_pub_t *dhd_attach(struct osl_info *osh, struct dhd_bus *bus, + uint bus_hdrlen); extern int dhd_net_attach(dhd_pub_t *dhdp, int idx); /* Indication from bus module regarding removal/absence of dongle */ diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_bus.h b/drivers/staging/brcm80211/brcmfmac/dhd_bus.h index 3b39c9966f81..6629a229b4a1 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_bus.h +++ b/drivers/staging/brcm80211/brcmfmac/dhd_bus.h @@ -26,8 +26,8 @@ extern int dhd_bus_register(void); extern void dhd_bus_unregister(void); /* Download firmware image and nvram image */ -extern bool dhd_bus_download_firmware(struct dhd_bus *bus, osl_t * osh, - char *fw_path, char *nv_path); +extern bool dhd_bus_download_firmware(struct dhd_bus *bus, + struct osl_info *osh, char *fw_path, char *nv_path); /* Stop bus module: clear pending frames, disable data flow */ extern void dhd_bus_stop(struct dhd_bus *bus, bool enforce_mutex); diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_linux.c b/drivers/staging/brcm80211/brcmfmac/dhd_linux.c index 48f0e6c518b6..27d4e02d3aab 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_linux.c +++ b/drivers/staging/brcm80211/brcmfmac/dhd_linux.c @@ -1863,12 +1863,12 @@ static int dhd_open(struct net_device *net) return ret; } -osl_t *dhd_osl_attach(void *pdev, uint bustype) +struct osl_info *dhd_osl_attach(void *pdev, uint bustype) { return osl_attach(pdev, bustype); } -void dhd_osl_detach(osl_t *osh) +void dhd_osl_detach(struct osl_info *osh) { osl_detach(osh); } @@ -1926,7 +1926,8 @@ void dhd_del_if(dhd_info_t *dhd, int ifidx) up(&dhd->sysioc_sem); } -dhd_pub_t *dhd_attach(osl_t *osh, struct dhd_bus *bus, uint bus_hdrlen) +dhd_pub_t *dhd_attach(struct osl_info *osh, struct dhd_bus *bus, + uint bus_hdrlen) { dhd_info_t *dhd = NULL; struct net_device *net; diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c b/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c index 66884d47e834..bc8739665d66 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c +++ b/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c @@ -431,15 +431,16 @@ static int dhdsdio_mem_dump(dhd_bus_t *bus); #endif /* DHD_DEBUG */ static int dhdsdio_download_state(dhd_bus_t *bus, bool enter); -static void dhdsdio_release(dhd_bus_t *bus, osl_t *osh); -static void dhdsdio_release_malloc(dhd_bus_t *bus, osl_t *osh); +static void dhdsdio_release(dhd_bus_t *bus, struct osl_info *osh); +static void dhdsdio_release_malloc(dhd_bus_t *bus, struct osl_info *osh); static void dhdsdio_disconnect(void *ptr); static bool dhdsdio_chipmatch(u16 chipid); -static bool dhdsdio_probe_attach(dhd_bus_t *bus, osl_t *osh, void *sdh, - void *regsva, u16 devid); -static bool dhdsdio_probe_malloc(dhd_bus_t *bus, osl_t *osh, void *sdh); -static bool dhdsdio_probe_init(dhd_bus_t *bus, osl_t *osh, void *sdh); -static void dhdsdio_release_dongle(dhd_bus_t *bus, osl_t * osh); +static bool dhdsdio_probe_attach(dhd_bus_t *bus, struct osl_info *osh, + void *sdh, void *regsva, u16 devid); +static bool dhdsdio_probe_malloc(dhd_bus_t *bus, struct osl_info *osh, + void *sdh); +static bool dhdsdio_probe_init(dhd_bus_t *bus, struct osl_info *osh, void *sdh); +static void dhdsdio_release_dongle(dhd_bus_t *bus, struct osl_info * osh); static uint process_nvram_vars(char *varbuf, uint len); @@ -451,7 +452,7 @@ static int dhd_bcmsdh_send_buf(dhd_bus_t *bus, u32 addr, uint fn, uint flags, u8 *buf, uint nbytes, void *pkt, bcmsdh_cmplt_fn_t complete, void *handle); -static bool dhdsdio_download_firmware(struct dhd_bus *bus, osl_t *osh, +static bool dhdsdio_download_firmware(struct dhd_bus *bus, struct osl_info *osh, void *sdh); static int _dhdsdio_download_firmware(struct dhd_bus *bus); @@ -904,7 +905,7 @@ void dhd_enable_oob_intr(struct dhd_bus *bus, bool enable) static int dhdsdio_txpkt(dhd_bus_t *bus, void *pkt, uint chan, bool free_pkt) { int ret; - osl_t *osh; + struct osl_info *osh; u8 *frame; u16 len, pad = 0; u32 swheader; @@ -1065,7 +1066,7 @@ done: int dhd_bus_txdata(struct dhd_bus *bus, void *pkt) { int ret = BCME_ERROR; - osl_t *osh; + struct osl_info *osh; uint datalen, prec; DHD_TRACE(("%s: Enter\n", __func__)); @@ -2824,7 +2825,7 @@ exit: void dhd_bus_stop(struct dhd_bus *bus, bool enforce_mutex) { - osl_t *osh = bus->dhd->osh; + struct osl_info *osh = bus->dhd->osh; u32 local_hostintmask; u8 saveclk; uint retries; @@ -3180,7 +3181,7 @@ static u8 dhdsdio_rxglom(dhd_bus_t *bus, u8 rxseq) u16 sublen, check; void *pfirst, *plast, *pnext, *save_pfirst; - osl_t *osh = bus->dhd->osh; + struct osl_info *osh = bus->dhd->osh; int errcode; u8 chan, seq, doff, sfdoff; @@ -3581,7 +3582,7 @@ static u8 dhdsdio_rxglom(dhd_bus_t *bus, u8 rxseq) /* Return true if there may be more frames to read */ static uint dhdsdio_readframes(dhd_bus_t *bus, uint maxframes, bool *finished) { - osl_t *osh = bus->dhd->osh; + struct osl_info *osh = bus->dhd->osh; bcmsdh_info_t *sdh = bus->sdh; u16 len, check; /* Extracted hardware header fields */ @@ -4631,7 +4632,7 @@ static void dhdsdio_pktgen(dhd_bus_t *bus) u8 *data; uint pktcount; uint fillbyte; - osl_t *osh = bus->dhd->osh; + struct osl_info *osh = bus->dhd->osh; u16 len; /* Display current count if appropriate */ @@ -4736,7 +4737,7 @@ static void dhdsdio_sdtest_set(dhd_bus_t *bus, bool start) { void *pkt; u8 *data; - osl_t *osh = bus->dhd->osh; + struct osl_info *osh = bus->dhd->osh; /* Allocate the packet */ pkt = PKTGET(osh, SDPCM_HDRLEN + SDPCM_TEST_HDRLEN + DHD_SDALIGN, @@ -4761,7 +4762,7 @@ static void dhdsdio_sdtest_set(dhd_bus_t *bus, bool start) static void dhdsdio_testrcv(dhd_bus_t *bus, void *pkt, uint seq) { - osl_t *osh = bus->dhd->osh; + struct osl_info *osh = bus->dhd->osh; u8 *data; uint pktlen; @@ -5062,7 +5063,7 @@ static bool dhdsdio_chipmatch(u16 chipid) static void *dhdsdio_probe(u16 venid, u16 devid, u16 bus_no, u16 slot, u16 func, uint bustype, void *regsva, - osl_t *osh, void *sdh) + struct osl_info *osh, void *sdh) { int ret; dhd_bus_t *bus; @@ -5221,8 +5222,8 @@ fail: } static bool -dhdsdio_probe_attach(struct dhd_bus *bus, osl_t *osh, void *sdh, void *regsva, - u16 devid) +dhdsdio_probe_attach(struct dhd_bus *bus, struct osl_info *osh, void *sdh, + void *regsva, u16 devid) { u8 clkctl = 0; int err = 0; @@ -5379,7 +5380,8 @@ fail: return false; } -static bool dhdsdio_probe_malloc(dhd_bus_t *bus, osl_t *osh, void *sdh) +static bool dhdsdio_probe_malloc(dhd_bus_t *bus, struct osl_info *osh, + void *sdh) { DHD_TRACE(("%s: Enter\n", __func__)); @@ -5420,7 +5422,7 @@ fail: return false; } -static bool dhdsdio_probe_init(dhd_bus_t *bus, osl_t *osh, void *sdh) +static bool dhdsdio_probe_init(dhd_bus_t *bus, struct osl_info *osh, void *sdh) { s32 fnum; @@ -5497,7 +5499,7 @@ static bool dhdsdio_probe_init(dhd_bus_t *bus, osl_t *osh, void *sdh) } bool -dhd_bus_download_firmware(struct dhd_bus *bus, osl_t *osh, +dhd_bus_download_firmware(struct dhd_bus *bus, struct osl_info *osh, char *fw_path, char *nv_path) { bool ret; @@ -5510,7 +5512,7 @@ dhd_bus_download_firmware(struct dhd_bus *bus, osl_t *osh, } static bool -dhdsdio_download_firmware(struct dhd_bus *bus, osl_t *osh, void *sdh) +dhdsdio_download_firmware(struct dhd_bus *bus, struct osl_info *osh, void *sdh) { bool ret; @@ -5525,7 +5527,7 @@ dhdsdio_download_firmware(struct dhd_bus *bus, osl_t *osh, void *sdh) } /* Detach and free everything */ -static void dhdsdio_release(dhd_bus_t *bus, osl_t *osh) +static void dhdsdio_release(dhd_bus_t *bus, struct osl_info *osh) { DHD_TRACE(("%s: Enter\n", __func__)); @@ -5555,7 +5557,7 @@ static void dhdsdio_release(dhd_bus_t *bus, osl_t *osh) DHD_TRACE(("%s: Disconnected\n", __func__)); } -static void dhdsdio_release_malloc(dhd_bus_t *bus, osl_t *osh) +static void dhdsdio_release_malloc(dhd_bus_t *bus, struct osl_info *osh) { DHD_TRACE(("%s: Enter\n", __func__)); @@ -5574,7 +5576,7 @@ static void dhdsdio_release_malloc(dhd_bus_t *bus, osl_t *osh) } } -static void dhdsdio_release_dongle(dhd_bus_t *bus, osl_t *osh) +static void dhdsdio_release_dongle(dhd_bus_t *bus, struct osl_info *osh) { DHD_TRACE(("%s: Enter\n", __func__)); diff --git a/drivers/staging/brcm80211/include/bcm_rpc.h b/drivers/staging/brcm80211/include/bcm_rpc.h index 77e5d8f71966..7a379ba15ce1 100644 --- a/drivers/staging/brcm80211/include/bcm_rpc.h +++ b/drivers/staging/brcm80211/include/bcm_rpc.h @@ -26,7 +26,7 @@ typedef void (*rpc_dispatch_cb_t) (void *ctx, struct rpc_buf *buf); typedef void (*rpc_resync_cb_t) (void *ctx); typedef void (*rpc_down_cb_t) (void *ctx); typedef void (*rpc_txdone_cb_t) (void *ctx, struct rpc_buf *buf); -extern struct rpc_info *bcm_rpc_attach(void *pdev, osl_t *osh, +extern struct rpc_info *bcm_rpc_attach(void *pdev, struct osl_info *osh, struct rpc_transport_info *rpc_th); extern void bcm_rpc_detach(struct rpc_info *rpc); diff --git a/drivers/staging/brcm80211/include/bcm_rpc_tp.h b/drivers/staging/brcm80211/include/bcm_rpc_tp.h index bb8dc6dd6f44..0136118284f9 100644 --- a/drivers/staging/brcm80211/include/bcm_rpc_tp.h +++ b/drivers/staging/brcm80211/include/bcm_rpc_tp.h @@ -57,7 +57,7 @@ typedef void (*rpc_rx_fn_t) (void *, rpc_buf_t *); typedef void (*rpc_txflowctl_cb_t) (void *ctx, bool on); #endif -extern rpc_tp_info_t *bcm_rpc_tp_attach(osl_t *osh, void *bus); +extern rpc_tp_info_t *bcm_rpc_tp_attach(struct osl_info *osh, void *bus); extern void bcm_rpc_tp_detach(rpc_tp_info_t *rpcb); extern void bcm_rpc_tp_down(rpc_tp_info_t *rpcb); extern void bcm_rpc_tp_watchdog(rpc_tp_info_t *rpcb); diff --git a/drivers/staging/brcm80211/include/bcmsdbus.h b/drivers/staging/brcm80211/include/bcmsdbus.h index ca99495eaa89..4f040e41ae50 100644 --- a/drivers/staging/brcm80211/include/bcmsdbus.h +++ b/drivers/staging/brcm80211/include/bcmsdbus.h @@ -46,8 +46,8 @@ typedef void (*sdioh_cb_fn_t) (void *); * The handler shall be provided by all subsequent calls. No local cache * cfghdl points to the starting address of pci device mapped memory */ -extern sdioh_info_t *sdioh_attach(osl_t *osh, void *cfghdl, uint irq); -extern SDIOH_API_RC sdioh_detach(osl_t *osh, sdioh_info_t *si); +extern sdioh_info_t *sdioh_attach(struct osl_info *osh, void *cfghdl, uint irq); +extern SDIOH_API_RC sdioh_detach(struct osl_info *osh, sdioh_info_t *si); extern SDIOH_API_RC sdioh_interrupt_register(sdioh_info_t *si, sdioh_cb_fn_t fn, void *argh); extern SDIOH_API_RC sdioh_interrupt_deregister(sdioh_info_t *si); diff --git a/drivers/staging/brcm80211/include/bcmsdh.h b/drivers/staging/brcm80211/include/bcmsdh.h index 6b80983d43c9..69aa061bb524 100644 --- a/drivers/staging/brcm80211/include/bcmsdh.h +++ b/drivers/staging/brcm80211/include/bcmsdh.h @@ -40,11 +40,11 @@ typedef void (*bcmsdh_cb_fn_t) (void *); * implementation may maintain a single "default" handle (e.g. the first or * most recent one) to enable single-instance implementations to pass NULL. */ -extern bcmsdh_info_t *bcmsdh_attach(osl_t *osh, void *cfghdl, void **regsva, - uint irq); +extern bcmsdh_info_t *bcmsdh_attach(struct osl_info *osh, void *cfghdl, + void **regsva, uint irq); /* Detach - freeup resources allocated in attach */ -extern int bcmsdh_detach(osl_t *osh, void *sdh); +extern int bcmsdh_detach(struct osl_info *osh, void *sdh); /* Query if SD device interrupts are enabled */ extern bool bcmsdh_intr_query(void *sdh); @@ -174,8 +174,8 @@ extern void *bcmsdh_get_sdioh(bcmsdh_info_t *sdh); typedef struct { /* attach to device */ void *(*attach) (u16 vend_id, u16 dev_id, u16 bus, u16 slot, - u16 func, uint bustype, void *regsva, osl_t *osh, - void *param); + u16 func, uint bustype, void *regsva, + struct osl_info *osh, void *param); /* detach from device */ void (*detach) (void *ch); } bcmsdh_driver_t; diff --git a/drivers/staging/brcm80211/include/bcmsdh_sdmmc.h b/drivers/staging/brcm80211/include/bcmsdh_sdmmc.h index 7d5aa71a7dc7..4d671ddb3af1 100644 --- a/drivers/staging/brcm80211/include/bcmsdh_sdmmc.h +++ b/drivers/staging/brcm80211/include/bcmsdh_sdmmc.h @@ -51,7 +51,7 @@ extern void sdioh_sdmmc_osfree(sdioh_info_t *sd); #define CLIENT_INTR 0x100 /* Get rid of this! */ struct sdioh_info { - osl_t *osh; /* osh handler */ + struct osl_info *osh; /* osh handler */ bool client_intr_enabled; /* interrupt connnected flag */ bool intr_handler_valid; /* client driver interrupt handler valid */ sdioh_cb_fn_t intr_handler; /* registered interrupt handler */ @@ -94,8 +94,8 @@ extern void sdioh_sdmmc_devintr_off(sdioh_info_t *sd); */ /* Register mapping routines */ -extern u32 *sdioh_sdmmc_reg_map(osl_t *osh, s32 addr, int size); -extern void sdioh_sdmmc_reg_unmap(osl_t *osh, s32 addr, int size); +extern u32 *sdioh_sdmmc_reg_map(struct osl_info *osh, s32 addr, int size); +extern void sdioh_sdmmc_reg_unmap(struct osl_info *osh, s32 addr, int size); /* Interrupt (de)registration routines */ extern int sdioh_sdmmc_register_irq(sdioh_info_t *sd, uint irq); diff --git a/drivers/staging/brcm80211/include/bcmsrom.h b/drivers/staging/brcm80211/include/bcmsrom.h index 9d53657fdaa1..cdcef746284f 100644 --- a/drivers/staging/brcm80211/include/bcmsrom.h +++ b/drivers/staging/brcm80211/include/bcmsrom.h @@ -20,15 +20,15 @@ #include /* Prototypes */ -extern int srom_var_init(si_t *sih, uint bus, void *curmap, osl_t *osh, - char **vars, uint *count); +extern int srom_var_init(si_t *sih, uint bus, void *curmap, + struct osl_info *osh, char **vars, uint *count); -extern int srom_read(si_t *sih, uint bus, void *curmap, osl_t *osh, +extern int srom_read(si_t *sih, uint bus, void *curmap, struct osl_info *osh, uint byteoff, uint nbytes, u16 *buf, bool check_crc); /* parse standard PCMCIA cis, normally used by SB/PCMCIA/SDIO/SPI/OTP * and extract from it into name=value pairs */ -extern int srom_parsecis(osl_t *osh, u8 **pcis, uint ciscnt, +extern int srom_parsecis(struct osl_info *osh, u8 **pcis, uint ciscnt, char **vars, uint *count); #endif /* _bcmsrom_h_ */ diff --git a/drivers/staging/brcm80211/include/bcmutils.h b/drivers/staging/brcm80211/include/bcmutils.h index 7f1d33481ee8..4c1c111bac9b 100644 --- a/drivers/staging/brcm80211/include/bcmutils.h +++ b/drivers/staging/brcm80211/include/bcmutils.h @@ -110,10 +110,10 @@ extern void *pktq_pdeq_tail(struct pktq *pq, int prec); /* Empty the queue at particular precedence level */ #ifdef BRCM_FULLMAC - extern void pktq_pflush(osl_t *osh, struct pktq *pq, int prec, + extern void pktq_pflush(struct osl_info *osh, struct pktq *pq, int prec, bool dir); #else - extern void pktq_pflush(osl_t *osh, struct pktq *pq, int prec, + extern void pktq_pflush(struct osl_info *osh, struct pktq *pq, int prec, bool dir, ifpkt_cb_t fn, int arg); #endif /* BRCM_FULLMAC */ @@ -141,18 +141,18 @@ /* prec_out may be NULL if caller is not interested in return value */ extern void *pktq_peek_tail(struct pktq *pq, int *prec_out); #ifdef BRCM_FULLMAC - extern void pktq_flush(osl_t *osh, struct pktq *pq, bool dir); + extern void pktq_flush(struct osl_info *osh, struct pktq *pq, bool dir); #else - extern void pktq_flush(osl_t *osh, struct pktq *pq, bool dir, + extern void pktq_flush(struct osl_info *osh, struct pktq *pq, bool dir, ifpkt_cb_t fn, int arg); #endif /* externs */ /* packet */ - extern uint pktfrombuf(osl_t *osh, void *p, uint offset, int len, - unsigned char *buf); - extern uint pktsegcnt(osl_t *osh, void *p); - extern uint pkttotlen(osl_t *osh, void *p); + extern uint pktfrombuf(struct osl_info *osh, void *p, uint offset, + int len, unsigned char *buf); + extern uint pktsegcnt(struct osl_info *osh, void *p); + extern uint pkttotlen(struct osl_info *osh, void *p); /* ethernet address */ extern int bcm_ether_atoe(char *p, struct ether_addr *ea); @@ -165,7 +165,7 @@ extern char *getvar(char *vars, const char *name); extern int getintvar(char *vars, const char *name); #ifdef BCMDBG - extern void prpkt(const char *msg, osl_t *osh, void *p0); + extern void prpkt(const char *msg, struct osl_info *osh, void *p0); #endif /* BCMDBG */ #define bcm_perf_enable() #define bcmstats(fmt) diff --git a/drivers/staging/brcm80211/include/hnddma.h b/drivers/staging/brcm80211/include/hnddma.h index bee4c89be23d..854a3996baa8 100644 --- a/drivers/staging/brcm80211/include/hnddma.h +++ b/drivers/staging/brcm80211/include/hnddma.h @@ -141,7 +141,7 @@ struct hnddma_pub { uint txnobuf; /* tx out of dma descriptors */ }; -extern hnddma_t *dma_attach(osl_t *osh, char *name, si_t *sih, +extern hnddma_t *dma_attach(struct osl_info *osh, char *name, si_t *sih, void *dmaregstx, void *dmaregsrx, uint ntxd, uint nrxd, uint rxbufsize, int rxextheadroom, uint nrxpost, uint rxoffset, uint *msg_level); @@ -238,6 +238,6 @@ extern const di_fcn_t dma64proc; extern uint dma_addrwidth(si_t *sih, void *dmaregs); /* pio helpers */ -extern void dma_txpioloopback(osl_t *osh, dma32regs_t *); +extern void dma_txpioloopback(struct osl_info *osh, dma32regs_t *); #endif /* _hnddma_h_ */ diff --git a/drivers/staging/brcm80211/include/hndpmu.h b/drivers/staging/brcm80211/include/hndpmu.h index bbcf0eecd212..a0110e4c9ac4 100644 --- a/drivers/staging/brcm80211/include/hndpmu.h +++ b/drivers/staging/brcm80211/include/hndpmu.h @@ -28,44 +28,44 @@ #define SET_LDO_VOLTAGE_LNLDO1 9 #define SET_LDO_VOLTAGE_LNLDO2_SEL 10 -extern void si_pmu_init(si_t *sih, osl_t *osh); -extern void si_pmu_chip_init(si_t *sih, osl_t *osh); -extern void si_pmu_pll_init(si_t *sih, osl_t *osh, u32 xtalfreq); -extern void si_pmu_res_init(si_t *sih, osl_t *osh); -extern void si_pmu_swreg_init(si_t *sih, osl_t *osh); +extern void si_pmu_init(si_t *sih, struct osl_info *osh); +extern void si_pmu_chip_init(si_t *sih, struct osl_info *osh); +extern void si_pmu_pll_init(si_t *sih, struct osl_info *osh, u32 xtalfreq); +extern void si_pmu_res_init(si_t *sih, struct osl_info *osh); +extern void si_pmu_swreg_init(si_t *sih, struct osl_info *osh); -extern u32 si_pmu_force_ilp(si_t *sih, osl_t *osh, bool force); +extern u32 si_pmu_force_ilp(si_t *sih, struct osl_info *osh, bool force); -extern u32 si_pmu_si_clock(si_t *sih, osl_t *osh); -extern u32 si_pmu_cpu_clock(si_t *sih, osl_t *osh); -extern u32 si_pmu_mem_clock(si_t *sih, osl_t *osh); -extern u32 si_pmu_alp_clock(si_t *sih, osl_t *osh); -extern u32 si_pmu_ilp_clock(si_t *sih, osl_t *osh); +extern u32 si_pmu_si_clock(si_t *sih, struct osl_info *osh); +extern u32 si_pmu_cpu_clock(si_t *sih, struct osl_info *osh); +extern u32 si_pmu_mem_clock(si_t *sih, struct osl_info *osh); +extern u32 si_pmu_alp_clock(si_t *sih, struct osl_info *osh); +extern u32 si_pmu_ilp_clock(si_t *sih, struct osl_info *osh); -extern void si_pmu_set_switcher_voltage(si_t *sih, osl_t *osh, +extern void si_pmu_set_switcher_voltage(si_t *sih, struct osl_info *osh, u8 bb_voltage, u8 rf_voltage); -extern void si_pmu_set_ldo_voltage(si_t *sih, osl_t *osh, u8 ldo, +extern void si_pmu_set_ldo_voltage(si_t *sih, struct osl_info *osh, u8 ldo, u8 voltage); -extern u16 si_pmu_fast_pwrup_delay(si_t *sih, osl_t *osh); -extern void si_pmu_rcal(si_t *sih, osl_t *osh); +extern u16 si_pmu_fast_pwrup_delay(si_t *sih, struct osl_info *osh); +extern void si_pmu_rcal(si_t *sih, struct osl_info *osh); extern void si_pmu_pllupd(si_t *sih); -extern void si_pmu_spuravoid(si_t *sih, osl_t *osh, u8 spuravoid); +extern void si_pmu_spuravoid(si_t *sih, struct osl_info *osh, u8 spuravoid); -extern bool si_pmu_is_otp_powered(si_t *sih, osl_t *osh); -extern u32 si_pmu_measure_alpclk(si_t *sih, osl_t *osh); +extern bool si_pmu_is_otp_powered(si_t *sih, struct osl_info *osh); +extern u32 si_pmu_measure_alpclk(si_t *sih, struct osl_info *osh); extern u32 si_pmu_chipcontrol(si_t *sih, uint reg, u32 mask, u32 val); extern u32 si_pmu_regcontrol(si_t *sih, uint reg, u32 mask, u32 val); extern u32 si_pmu_pllcontrol(si_t *sih, uint reg, u32 mask, u32 val); extern void si_pmu_pllupd(si_t *sih); -extern void si_pmu_sprom_enable(si_t *sih, osl_t *osh, bool enable); +extern void si_pmu_sprom_enable(si_t *sih, struct osl_info *osh, bool enable); extern void si_pmu_radio_enable(si_t *sih, bool enable); -extern u32 si_pmu_waitforclk_on_backplane(si_t *sih, osl_t *osh, +extern u32 si_pmu_waitforclk_on_backplane(si_t *sih, struct osl_info *osh, u32 clk, u32 delay); -extern void si_pmu_otp_power(si_t *sih, osl_t *osh, bool on); -extern void si_sdiod_drive_strength_init(si_t *sih, osl_t *osh, +extern void si_pmu_otp_power(si_t *sih, struct osl_info *osh, bool on); +extern void si_sdiod_drive_strength_init(si_t *sih, struct osl_info *osh, u32 drivestrength); #endif /* _hndpmu_h_ */ diff --git a/drivers/staging/brcm80211/include/linux_osl.h b/drivers/staging/brcm80211/include/linux_osl.h index 124b579f87c5..70621692150a 100644 --- a/drivers/staging/brcm80211/include/linux_osl.h +++ b/drivers/staging/brcm80211/include/linux_osl.h @@ -18,8 +18,8 @@ #define _linux_osl_h_ -extern osl_t *osl_attach(void *pdev, uint bustype); -extern void osl_detach(osl_t *osh); +extern struct osl_info *osl_attach(void *pdev, uint bustype); +extern void osl_detach(struct osl_info *osh); extern u32 g_assert_type; @@ -45,14 +45,15 @@ extern void osl_assert(char *exp, char *file, int line); osl_pci_read_config((osh), (offset), (size)) #define OSL_PCI_WRITE_CONFIG(osh, offset, size, val) \ osl_pci_write_config((osh), (offset), (size), (val)) -extern u32 osl_pci_read_config(osl_t *osh, uint offset, uint size); -extern void osl_pci_write_config(osl_t *osh, uint offset, uint size, uint val); +extern u32 osl_pci_read_config(struct osl_info *osh, uint offset, uint size); +extern void osl_pci_write_config(struct osl_info *osh, uint offset, uint size, + uint val); /* PCI device bus # and slot # */ #define OSL_PCI_BUS(osh) osl_pci_bus(osh) #define OSL_PCI_SLOT(osh) osl_pci_slot(osh) -extern uint osl_pci_bus(osl_t *osh); -extern uint osl_pci_slot(osl_t *osh); +extern uint osl_pci_bus(struct osl_info *osh); +extern uint osl_pci_slot(struct osl_info *osh); #define PKTFREESETCB(osh, _tx_fn, _tx_ctx) \ do { \ @@ -71,8 +72,8 @@ extern uint osl_pci_slot(osl_t *osh); #define BUS_SWAP32(v) (v) -extern void *osl_dma_alloc_consistent(osl_t *osh, uint size, u16 align, - uint *tot, unsigned long *pap); +extern void *osl_dma_alloc_consistent(struct osl_info *osh, uint size, + u16 align, uint *tot, unsigned long *pap); #ifdef BRCM_FULLMAC #define DMA_ALLOC_CONSISTENT(osh, size, pap, dmah, alignbits) \ @@ -84,7 +85,8 @@ extern void *osl_dma_alloc_consistent(osl_t *osh, uint size, u16 align, #define DMA_FREE_CONSISTENT(osh, va, size, pa, dmah) \ osl_dma_free_consistent((osh), (void *)(va), (size), (pa)) -extern void osl_dma_free_consistent(osl_t *osh, void *va, uint size, unsigned long pa); +extern void osl_dma_free_consistent(struct osl_info *osh, void *va, + uint size, unsigned long pa); /* map/unmap direction */ #define DMA_TX 1 /* TX direction for DMA */ @@ -95,8 +97,10 @@ extern void osl_dma_free_consistent(osl_t *osh, void *va, uint size, unsigned lo osl_dma_map((osh), (va), (size), (direction)) #define DMA_UNMAP(osh, pa, size, direction, p, dmah) \ osl_dma_unmap((osh), (pa), (size), (direction)) -extern uint osl_dma_map(osl_t *osh, void *va, uint size, int direction); -extern void osl_dma_unmap(osl_t *osh, uint pa, uint size, int direction); +extern uint osl_dma_map(struct osl_info *osh, void *va, uint size, + int direction); +extern void osl_dma_unmap(struct osl_info *osh, uint pa, uint size, + int direction); /* API for DMA addressing capability */ #define OSL_DMADDRWIDTH(osh, addrwidth) do {} while (0) @@ -275,8 +279,8 @@ extern void osl_dma_unmap(osl_t *osh, uint pa, uint size, int direction); #define PKTALLOCED(osh) (((struct osl_pubinfo *)(osh))->pktalloced) #define PKTSETPOOL(osh, skb, x, y) do {} while (0) #define PKTPOOL(osh, skb) false -extern void *osl_pktget(osl_t *osh, uint len); -extern void osl_pktfree(osl_t *osh, void *skb, bool send); +extern void *osl_pktget(struct osl_info *osh, uint len); +extern void osl_pktfree(struct osl_info *osh, void *skb, bool send); #ifdef BRCM_FULLMAC static inline void * @@ -342,12 +346,12 @@ osl_pkt_tonative(struct osl_pubinfo *osh, void *pkt) } \ } while (0) -extern u8 osl_readb(osl_t *osh, volatile u8 *r); -extern u16 osl_readw(osl_t *osh, volatile u16 *r); -extern u32 osl_readl(osl_t *osh, volatile u32 *r); -extern void osl_writeb(osl_t *osh, volatile u8 *r, u8 v); -extern void osl_writew(osl_t *osh, volatile u16 *r, u16 v); -extern void osl_writel(osl_t *osh, volatile u32 *r, u32 v); +extern u8 osl_readb(struct osl_info *osh, volatile u8 *r); +extern u16 osl_readw(struct osl_info *osh, volatile u16 *r); +extern u32 osl_readl(struct osl_info *osh, volatile u32 *r); +extern void osl_writeb(struct osl_info *osh, volatile u8 *r, u8 v); +extern void osl_writew(struct osl_info *osh, volatile u16 *r, u16 v); +extern void osl_writel(struct osl_info *osh, volatile u32 *r, u32 v); #endif /* BCMSDIO */ #endif /* _linux_osl_h_ */ diff --git a/drivers/staging/brcm80211/include/nicpci.h b/drivers/staging/brcm80211/include/nicpci.h index ce146e88ffdf..7ea7daf7c2b6 100644 --- a/drivers/staging/brcm80211/include/nicpci.h +++ b/drivers/staging/brcm80211/include/nicpci.h @@ -45,17 +45,17 @@ #else struct sbpcieregs; -extern u8 pcicore_find_pci_capability(osl_t *osh, u8 req_cap_id, +extern u8 pcicore_find_pci_capability(struct osl_info *osh, u8 req_cap_id, unsigned char *buf, u32 *buflen); -extern uint pcie_readreg(osl_t *osh, struct sbpcieregs *pcieregs, +extern uint pcie_readreg(struct osl_info *osh, struct sbpcieregs *pcieregs, uint addrtype, uint offset); -extern uint pcie_writereg(osl_t *osh, struct sbpcieregs *pcieregs, +extern uint pcie_writereg(struct osl_info *osh, struct sbpcieregs *pcieregs, uint addrtype, uint offset, uint val); extern u8 pcie_clkreq(void *pch, u32 mask, u32 val); extern u32 pcie_lcreg(void *pch, u32 mask, u32 val); -extern void *pcicore_init(si_t *sih, osl_t *osh, void *regs); +extern void *pcicore_init(si_t *sih, struct osl_info *osh, void *regs); extern void pcicore_deinit(void *pch); extern void pcicore_attach(void *pch, char *pvars, int state); extern void pcicore_hwup(void *pch); @@ -70,7 +70,7 @@ extern u32 pcicore_pcieserdesreg(void *pch, u32 mdioslave, u32 offset, extern u32 pcicore_pciereg(void *pch, u32 offset, u32 mask, u32 val, uint type); -extern bool pcicore_pmecap_fast(osl_t *osh); +extern bool pcicore_pmecap_fast(struct osl_info *osh); extern void pcicore_pmeen(void *pch); extern void pcicore_pmeclr(void *pch); extern bool pcicore_pmestat(void *pch); diff --git a/drivers/staging/brcm80211/include/osl.h b/drivers/staging/brcm80211/include/osl.h index 5a9bc59e9217..e2205c481a3f 100644 --- a/drivers/staging/brcm80211/include/osl.h +++ b/drivers/staging/brcm80211/include/osl.h @@ -41,7 +41,6 @@ struct osl_info { uint bustype; }; -typedef struct osl_info osl_t; typedef struct osl_dmainfo osldma_t; diff --git a/drivers/staging/brcm80211/include/rpc_osl.h b/drivers/staging/brcm80211/include/rpc_osl.h index 4a2648001bf0..c59d9ed1397a 100644 --- a/drivers/staging/brcm80211/include/rpc_osl.h +++ b/drivers/staging/brcm80211/include/rpc_osl.h @@ -18,7 +18,7 @@ #define _rpcosl_h_ typedef struct rpc_osl rpc_osl_t; -extern rpc_osl_t *rpc_osl_attach(osl_t *osh); +extern rpc_osl_t *rpc_osl_attach(struct osl_info *osh); extern void rpc_osl_detach(rpc_osl_t *rpc_osh); #define RPC_OSL_LOCK(rpc_osh) rpc_osl_lock((rpc_osh)) diff --git a/drivers/staging/brcm80211/include/siutils.h b/drivers/staging/brcm80211/include/siutils.h index 57c36507a040..6f83e7e5b313 100644 --- a/drivers/staging/brcm80211/include/siutils.h +++ b/drivers/staging/brcm80211/include/siutils.h @@ -128,8 +128,8 @@ typedef void (*gpio_handler_t) (u32 stat, void *arg); #define GPIO_CTRL_EPA_EN_MASK 0x40 /* === exported functions === */ -extern si_t *si_attach(uint pcidev, osl_t *osh, void *regs, uint bustype, - void *sdh, char **vars, uint *varsz); +extern si_t *si_attach(uint pcidev, struct osl_info *osh, void *regs, + uint bustype, void *sdh, char **vars, uint *varsz); extern void si_detach(si_t *sih); extern bool si_pci_war16165(si_t *sih); @@ -344,9 +344,9 @@ extern void si_epa_4313war(si_t *sih); char *si_getnvramflvar(si_t *sih, const char *name); /* AMBA Interconnect exported externs */ -extern si_t *ai_attach(uint pcidev, osl_t *osh, void *regs, uint bustype, - void *sdh, char **vars, uint *varsz); -extern si_t *ai_kattach(osl_t *osh); +extern si_t *ai_attach(uint pcidev, struct osl_info *osh, void *regs, + uint bustype, void *sdh, char **vars, uint *varsz); +extern si_t *ai_kattach(struct osl_info *osh); extern void ai_scan(si_t *sih, void *regs, uint devid); extern uint ai_flag(si_t *sih); diff --git a/drivers/staging/brcm80211/phy/wlc_phy_cmn.c b/drivers/staging/brcm80211/phy/wlc_phy_cmn.c index 9e6bbcdf8b6f..e20c1f09f8bb 100644 --- a/drivers/staging/brcm80211/phy/wlc_phy_cmn.c +++ b/drivers/staging/brcm80211/phy/wlc_phy_cmn.c @@ -276,7 +276,7 @@ u16 read_radio_reg(phy_info_t *pi, u16 addr) void write_radio_reg(phy_info_t *pi, u16 addr, u16 val) { - osl_t *osh; + struct osl_info *osh; if (NORADIO_ENAB(pi->pubpi)) return; @@ -409,7 +409,7 @@ static bool wlc_phy_war41476(phy_info_t *pi) u16 read_phy_reg(phy_info_t *pi, u16 addr) { - osl_t *osh; + struct osl_info *osh; d11regs_t *regs; osh = pi->sh->osh; @@ -430,7 +430,7 @@ u16 read_phy_reg(phy_info_t *pi, u16 addr) void write_phy_reg(phy_info_t *pi, u16 addr, u16 val) { - osl_t *osh; + struct osl_info *osh; d11regs_t *regs; osh = pi->sh->osh; @@ -456,7 +456,7 @@ void write_phy_reg(phy_info_t *pi, u16 addr, u16 val) void and_phy_reg(phy_info_t *pi, u16 addr, u16 val) { - osl_t *osh; + struct osl_info *osh; d11regs_t *regs; osh = pi->sh->osh; @@ -477,7 +477,7 @@ void and_phy_reg(phy_info_t *pi, u16 addr, u16 val) void or_phy_reg(phy_info_t *pi, u16 addr, u16 val) { - osl_t *osh; + struct osl_info *osh; d11regs_t *regs; osh = pi->sh->osh; @@ -498,7 +498,7 @@ void or_phy_reg(phy_info_t *pi, u16 addr, u16 val) void mod_phy_reg(phy_info_t *pi, u16 addr, u16 mask, u16 val) { - osl_t *osh; + struct osl_info *osh; d11regs_t *regs; osh = pi->sh->osh; @@ -595,7 +595,7 @@ shared_phy_t *wlc_phy_shared_attach(shared_phy_params_t *shp) void wlc_phy_shared_detach(shared_phy_t *phy_sh) { - osl_t *osh; + struct osl_info *osh; if (phy_sh) { osh = phy_sh->osh; @@ -613,7 +613,7 @@ wlc_phy_t *wlc_phy_attach(shared_phy_t *sh, void *regs, int bandtype, char *vars u32 sflags = 0; uint phyversion; int i; - osl_t *osh; + struct osl_info *osh; osh = sh->osh; diff --git a/drivers/staging/brcm80211/phy/wlc_phy_int.h b/drivers/staging/brcm80211/phy/wlc_phy_int.h index 9513b87fa163..fb92c3bccb16 100644 --- a/drivers/staging/brcm80211/phy/wlc_phy_int.h +++ b/drivers/staging/brcm80211/phy/wlc_phy_int.h @@ -527,7 +527,7 @@ typedef struct { struct shared_phy { struct phy_info *phy_head; uint unit; - osl_t *osh; + struct osl_info *osh; si_t *sih; void *physhim; uint corerev; diff --git a/drivers/staging/brcm80211/sys/wl_export.h b/drivers/staging/brcm80211/sys/wl_export.h index 08442f8e84e0..aa8b5a3ed633 100644 --- a/drivers/staging/brcm80211/sys/wl_export.h +++ b/drivers/staging/brcm80211/sys/wl_export.h @@ -45,10 +45,10 @@ extern void wl_add_timer(struct wl_info *wl, struct wl_timer *timer, uint ms, int periodic); extern bool wl_del_timer(struct wl_info *wl, struct wl_timer *timer); -extern uint wl_buf_to_pktcopy(osl_t *osh, void *p, unsigned char *buf, int len, - uint offset); -extern void *wl_get_pktbuffer(osl_t *osh, int len); -extern int wl_set_pktlen(osl_t *osh, void *p, int len); +extern uint wl_buf_to_pktcopy(struct osl_info *osh, void *p, unsigned char *buf, + int len, uint offset); +extern void *wl_get_pktbuffer(struct osl_info *osh, int len); +extern int wl_set_pktlen(struct osl_info *osh, void *p, int len); #define wl_sort_bsslist(a, b) false diff --git a/drivers/staging/brcm80211/sys/wl_mac80211.c b/drivers/staging/brcm80211/sys/wl_mac80211.c index 4b59e073aa15..af6d7dea4697 100644 --- a/drivers/staging/brcm80211/sys/wl_mac80211.c +++ b/drivers/staging/brcm80211/sys/wl_mac80211.c @@ -743,7 +743,7 @@ static wl_info_t *wl_attach(u16 vendor, u16 device, unsigned long regs, uint bustype, void *btparam, uint irq) { wl_info_t *wl; - osl_t *osh; + struct osl_info *osh; int unit, err; unsigned long base_addr; @@ -1512,7 +1512,7 @@ module_exit(wl_module_exit); void wl_free(wl_info_t *wl) { wl_timer_t *t, *next; - osl_t *osh; + struct osl_info *osh; ASSERT(wl); #ifndef WLC_HIGH_ONLY diff --git a/drivers/staging/brcm80211/sys/wl_mac80211.h b/drivers/staging/brcm80211/sys/wl_mac80211.h index 78cee4454b0b..54bbb15d9585 100644 --- a/drivers/staging/brcm80211/sys/wl_mac80211.h +++ b/drivers/staging/brcm80211/sys/wl_mac80211.h @@ -62,7 +62,7 @@ struct wl_firmware { struct wl_info { wlc_pub_t *pub; /* pointer to public wlc state */ void *wlc; /* pointer to private common os-independent data */ - osl_t *osh; /* pointer to os handler */ + struct osl_info *osh; /* pointer to os handler */ u32 magic; int irq; diff --git a/drivers/staging/brcm80211/sys/wlc_alloc.c b/drivers/staging/brcm80211/sys/wlc_alloc.c index 8001dca44918..1fb9976ef8b4 100644 --- a/drivers/staging/brcm80211/sys/wlc_alloc.c +++ b/drivers/staging/brcm80211/sys/wlc_alloc.c @@ -32,12 +32,12 @@ #include #include -static wlc_pub_t *wlc_pub_malloc(osl_t *osh, uint unit, uint *err, +static wlc_pub_t *wlc_pub_malloc(struct osl_info *osh, uint unit, uint *err, uint devid); -static void wlc_pub_mfree(osl_t *osh, wlc_pub_t *pub); +static void wlc_pub_mfree(struct osl_info *osh, wlc_pub_t *pub); static void wlc_tunables_init(wlc_tunables_t *tunables, uint devid); -void *wlc_calloc(osl_t *osh, uint unit, uint size) +void *wlc_calloc(struct osl_info *osh, uint unit, uint size) { void *item; @@ -70,7 +70,8 @@ void wlc_tunables_init(wlc_tunables_t *tunables, uint devid) #endif /* WLC_HIGH_ONLY */ } -static wlc_pub_t *wlc_pub_malloc(osl_t *osh, uint unit, uint *err, uint devid) +static wlc_pub_t *wlc_pub_malloc(struct osl_info *osh, uint unit, uint *err, + uint devid) { wlc_pub_t *pub; @@ -104,7 +105,7 @@ static wlc_pub_t *wlc_pub_malloc(osl_t *osh, uint unit, uint *err, uint devid) return NULL; } -static void wlc_pub_mfree(osl_t *osh, wlc_pub_t *pub) +static void wlc_pub_mfree(struct osl_info *osh, wlc_pub_t *pub) { if (pub == NULL) return; @@ -119,7 +120,7 @@ static void wlc_pub_mfree(osl_t *osh, wlc_pub_t *pub) kfree(pub); } -wlc_bsscfg_t *wlc_bsscfg_malloc(osl_t *osh, uint unit) +wlc_bsscfg_t *wlc_bsscfg_malloc(struct osl_info *osh, uint unit) { wlc_bsscfg_t *cfg; @@ -139,7 +140,7 @@ wlc_bsscfg_t *wlc_bsscfg_malloc(osl_t *osh, uint unit) return NULL; } -void wlc_bsscfg_mfree(osl_t *osh, wlc_bsscfg_t *cfg) +void wlc_bsscfg_mfree(struct osl_info *osh, wlc_bsscfg_t *cfg) { if (cfg == NULL) return; @@ -169,7 +170,8 @@ void wlc_bsscfg_ID_assign(wlc_info_t *wlc, wlc_bsscfg_t *bsscfg) /* * The common driver entry routine. Error codes should be unique */ -wlc_info_t *wlc_attach_malloc(osl_t *osh, uint unit, uint *err, uint devid) +wlc_info_t *wlc_attach_malloc(struct osl_info *osh, uint unit, uint *err, + uint devid) { wlc_info_t *wlc; @@ -306,7 +308,7 @@ wlc_info_t *wlc_attach_malloc(osl_t *osh, uint unit, uint *err, uint devid) return NULL; } -void wlc_detach_mfree(wlc_info_t *wlc, osl_t *osh) +void wlc_detach_mfree(wlc_info_t *wlc, struct osl_info *osh) { if (wlc == NULL) return; diff --git a/drivers/staging/brcm80211/sys/wlc_alloc.h b/drivers/staging/brcm80211/sys/wlc_alloc.h index 678a2b9784f8..eedf62912698 100644 --- a/drivers/staging/brcm80211/sys/wlc_alloc.h +++ b/drivers/staging/brcm80211/sys/wlc_alloc.h @@ -14,12 +14,12 @@ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -extern void *wlc_calloc(osl_t *osh, uint unit, uint size); +extern void *wlc_calloc(struct osl_info *osh, uint unit, uint size); -extern wlc_info_t *wlc_attach_malloc(osl_t *osh, uint unit, uint *err, +extern wlc_info_t *wlc_attach_malloc(struct osl_info *osh, uint unit, uint *err, uint devid); -extern void wlc_detach_mfree(wlc_info_t *wlc, osl_t *osh); +extern void wlc_detach_mfree(wlc_info_t *wlc, struct osl_info *osh); struct wlc_bsscfg; -extern struct wlc_bsscfg *wlc_bsscfg_malloc(osl_t *osh, uint unit); -extern void wlc_bsscfg_mfree(osl_t *osh, struct wlc_bsscfg *cfg); +extern struct wlc_bsscfg *wlc_bsscfg_malloc(struct osl_info *osh, uint unit); +extern void wlc_bsscfg_mfree(struct osl_info *osh, struct wlc_bsscfg *cfg); diff --git a/drivers/staging/brcm80211/sys/wlc_ampdu.c b/drivers/staging/brcm80211/sys/wlc_ampdu.c index 0bd7069dc331..5d06105ba1f6 100644 --- a/drivers/staging/brcm80211/sys/wlc_ampdu.c +++ b/drivers/staging/brcm80211/sys/wlc_ampdu.c @@ -504,7 +504,7 @@ int BCMFASTPATH wlc_sendampdu(ampdu_info_t *ampdu, wlc_txq_info_t *qi, void **pdu, int prec) { wlc_info_t *wlc; - osl_t *osh; + struct osl_info *osh; void *p, *pkt[AMPDU_MAX_MPDU]; u8 tid, ndelim; int err = 0; diff --git a/drivers/staging/brcm80211/sys/wlc_antsel.c b/drivers/staging/brcm80211/sys/wlc_antsel.c index ecc35de77004..4e4571a098f7 100644 --- a/drivers/staging/brcm80211/sys/wlc_antsel.c +++ b/drivers/staging/brcm80211/sys/wlc_antsel.c @@ -93,7 +93,7 @@ const u8 mimo_2x3_div_antselid_tbl[16] = { 0, 0, 0, 0, 0, 0, 0, 0 /* pat to antselid */ }; -antsel_info_t *wlc_antsel_attach(wlc_info_t *wlc, osl_t *osh, +antsel_info_t *wlc_antsel_attach(wlc_info_t *wlc, struct osl_info *osh, wlc_pub_t *pub, wlc_hw_info_t *wlc_hw) { antsel_info_t *asi; diff --git a/drivers/staging/brcm80211/sys/wlc_antsel.h b/drivers/staging/brcm80211/sys/wlc_antsel.h index 1d048bbea946..f3361f8106e8 100644 --- a/drivers/staging/brcm80211/sys/wlc_antsel.h +++ b/drivers/staging/brcm80211/sys/wlc_antsel.h @@ -16,7 +16,7 @@ #ifndef _wlc_antsel_h_ #define _wlc_antsel_h_ -extern antsel_info_t *wlc_antsel_attach(wlc_info_t *wlc, osl_t *osh, +extern antsel_info_t *wlc_antsel_attach(wlc_info_t *wlc, struct osl_info *osh, wlc_pub_t *pub, wlc_hw_info_t *wlc_hw); extern void wlc_antsel_detach(antsel_info_t *asi); diff --git a/drivers/staging/brcm80211/sys/wlc_bmac.c b/drivers/staging/brcm80211/sys/wlc_bmac.c index fc5201d5171a..214b5d82ab23 100644 --- a/drivers/staging/brcm80211/sys/wlc_bmac.c +++ b/drivers/staging/brcm80211/sys/wlc_bmac.c @@ -193,7 +193,7 @@ void wlc_bmac_set_shortslot(wlc_hw_info_t *wlc_hw, bool shortslot) */ static void wlc_bmac_update_slot_timing(wlc_hw_info_t *wlc_hw, bool shortslot) { - osl_t *osh; + struct osl_info *osh; d11regs_t *regs; osh = wlc_hw->osh; @@ -586,7 +586,7 @@ static bool wlc_bmac_attach_dmapio(wlc_info_t *wlc, uint j, bool wme) if (wlc_hw->di[0] == 0) { /* Init FIFOs */ uint addrwidth; int dma_attach_err = 0; - osl_t *osh = wlc_hw->osh; + struct osl_info *osh = wlc_hw->osh; /* Find out the DMA addressing capability and let OS know * All the channels within one DMA core have 'common-minimum' same @@ -708,8 +708,8 @@ static void wlc_bmac_detach_dmapio(wlc_hw_info_t *wlc_hw) * put the whole chip in reset(driver down state), no clock */ int wlc_bmac_attach(wlc_info_t *wlc, u16 vendor, u16 device, uint unit, - bool piomode, osl_t *osh, void *regsva, uint bustype, - void *btparam) + bool piomode, struct osl_info *osh, void *regsva, + uint bustype, void *btparam) { wlc_hw_info_t *wlc_hw; d11regs_t *regs; @@ -1719,7 +1719,7 @@ wlc_bmac_set_rcmta(wlc_hw_info_t *wlc_hw, int idx, volatile u16 *objdata16 = (volatile u16 *)®s->objdata; u32 mac_hm; u16 mac_l; - osl_t *osh; + struct osl_info *osh; WL_TRACE(("wl%d: %s\n", wlc_hw->unit, __func__)); @@ -1752,7 +1752,7 @@ wlc_bmac_set_addrmatch(wlc_hw_info_t *wlc_hw, int match_reg_offset, u16 mac_l; u16 mac_m; u16 mac_h; - osl_t *osh; + struct osl_info *osh; WL_TRACE(("wl%d: wlc_bmac_set_addrmatch\n", wlc_hw->unit)); @@ -1783,7 +1783,7 @@ wlc_bmac_write_template_ram(wlc_hw_info_t *wlc_hw, int offset, int len, #ifdef IL_BIGENDIAN volatile u16 *dptr = NULL; #endif /* IL_BIGENDIAN */ - osl_t *osh; + struct osl_info *osh; WL_TRACE(("wl%d: wlc_bmac_write_template_ram\n", wlc_hw->unit)); @@ -1819,7 +1819,7 @@ wlc_bmac_write_template_ram(wlc_hw_info_t *wlc_hw, int offset, int len, void wlc_bmac_set_cwmin(wlc_hw_info_t *wlc_hw, u16 newmin) { - osl_t *osh; + struct osl_info *osh; osh = wlc_hw->osh; wlc_hw->band->CWmin = newmin; @@ -1831,7 +1831,7 @@ void wlc_bmac_set_cwmin(wlc_hw_info_t *wlc_hw, u16 newmin) void wlc_bmac_set_cwmax(wlc_hw_info_t *wlc_hw, u16 newmax) { - osl_t *osh; + struct osl_info *osh; osh = wlc_hw->osh; wlc_hw->band->CWmax = newmax; @@ -2299,7 +2299,7 @@ void wlc_bmac_hw_up(wlc_hw_info_t *wlc_hw) static bool wlc_dma_rxreset(wlc_hw_info_t *wlc_hw, uint fifo) { hnddma_t *di = wlc_hw->di[fifo]; - osl_t *osh; + struct osl_info *osh; if (D11REV_LT(wlc_hw->corerev, 12)) { bool rxidle = true; @@ -2425,7 +2425,7 @@ static void wlc_corerev_fifofixup(wlc_hw_info_t *wlc_hw) u16 txfifo_startblk = TXFIFO_START_BLK, txfifo_endblk; u16 txfifo_def, txfifo_def1; u16 txfifo_cmd; - osl_t *osh; + struct osl_info *osh; if (D11REV_LT(wlc_hw->corerev, 9)) goto exit; @@ -2486,7 +2486,7 @@ static void wlc_coreinit(wlc_info_t *wlc) uint bcnint_us; uint i = 0; bool fifosz_fixup = false; - osl_t *osh; + struct osl_info *osh; int err = 0; u16 buf[NFIFO]; @@ -2692,7 +2692,7 @@ static void wlc_coreinit(wlc_info_t *wlc) void wlc_bmac_switch_macfreq(wlc_hw_info_t *wlc_hw, u8 spurmode) { d11regs_t *regs; - osl_t *osh; + struct osl_info *osh; regs = wlc_hw->regs; osh = wlc_hw->osh; @@ -2725,7 +2725,7 @@ static void wlc_gpio_init(wlc_info_t *wlc) wlc_hw_info_t *wlc_hw = wlc->hw; d11regs_t *regs; u32 gc, gm; - osl_t *osh; + struct osl_info *osh; regs = wlc_hw->regs; osh = wlc_hw->osh; @@ -2815,7 +2815,7 @@ static void wlc_ucode_download(wlc_hw_info_t *wlc_hw) static void wlc_ucode_write(wlc_hw_info_t *wlc_hw, const u32 ucode[], const uint nbytes) { - osl_t *osh; + struct osl_info *osh; d11regs_t *regs = wlc_hw->regs; uint i; uint count; @@ -2837,7 +2837,7 @@ static void wlc_ucode_write(wlc_hw_info_t *wlc_hw, const u32 ucode[], static void wlc_write_inits(wlc_hw_info_t *wlc_hw, const d11init_t *inits) { int i; - osl_t *osh; + struct osl_info *osh; volatile u8 *base; WL_TRACE(("wl%d: wlc_write_inits\n", wlc_hw->unit)); @@ -3180,7 +3180,7 @@ static inline u32 wlc_intstatus(wlc_info_t *wlc, bool in_isr) d11regs_t *regs = wlc_hw->regs; u32 macintstatus; u32 intstatus_rxfifo, intstatus_txsfifo; - osl_t *osh; + struct osl_info *osh; osh = wlc_hw->osh; @@ -3326,7 +3326,7 @@ static bool wlc_bmac_txstatus_corerev4(wlc_hw_info_t *wlc_hw) { void *status_p; tx_status_t *txs; - osl_t *osh; + struct osl_info *osh; bool fatal = false; WL_TRACE(("wl%d: wlc_txstatusrecv\n", wlc_hw->unit)); @@ -3393,7 +3393,7 @@ wlc_bmac_txstatus(wlc_hw_info_t *wlc_hw, bool bound, bool *fatal) } else { /* corerev >= 5 */ d11regs_t *regs; - osl_t *osh; + struct osl_info *osh; tx_status_t txstatus, *txs; u32 s1, s2; uint n = 0; @@ -3446,7 +3446,7 @@ void wlc_suspend_mac_and_wait(wlc_info_t *wlc) wlc_hw_info_t *wlc_hw = wlc->hw; d11regs_t *regs = wlc_hw->regs; u32 mc, mi; - osl_t *osh; + struct osl_info *osh; WL_TRACE(("wl%d: wlc_suspend_mac_and_wait: bandunit %d\n", wlc_hw->unit, wlc_hw->band->bandunit)); @@ -3510,7 +3510,7 @@ void wlc_enable_mac(wlc_info_t *wlc) wlc_hw_info_t *wlc_hw = wlc->hw; d11regs_t *regs = wlc_hw->regs; u32 mc, mi; - osl_t *osh; + struct osl_info *osh; WL_TRACE(("wl%d: wlc_enable_mac: bandunit %d\n", wlc_hw->unit, wlc->band->bandunit)); @@ -3673,7 +3673,7 @@ bool wlc_bmac_validate_chip_access(wlc_hw_info_t *wlc_hw) d11regs_t *regs; u32 w, val; volatile u16 *reg16; - osl_t *osh; + struct osl_info *osh; WL_TRACE(("wl%d: validate_chip_access\n", wlc_hw->unit)); @@ -3766,7 +3766,7 @@ bool wlc_bmac_validate_chip_access(wlc_hw_info_t *wlc_hw) void wlc_bmac_core_phypll_ctl(wlc_hw_info_t *wlc_hw, bool on) { d11regs_t *regs; - osl_t *osh; + struct osl_info *osh; u32 tmp; WL_TRACE(("wl%d: wlc_bmac_core_phypll_ctl\n", wlc_hw->unit)); diff --git a/drivers/staging/brcm80211/sys/wlc_bmac.h b/drivers/staging/brcm80211/sys/wlc_bmac.h index 872bc8d866d2..4cc41f9f4619 100644 --- a/drivers/staging/brcm80211/sys/wlc_bmac.h +++ b/drivers/staging/brcm80211/sys/wlc_bmac.h @@ -131,8 +131,8 @@ typedef enum { } wlc_bmac_state_id_t; extern int wlc_bmac_attach(wlc_info_t *wlc, u16 vendor, u16 device, - uint unit, bool piomode, osl_t *osh, void *regsva, - uint bustype, void *btparam); + uint unit, bool piomode, struct osl_info *osh, + void *regsva, uint bustype, void *btparam); extern int wlc_bmac_detach(wlc_info_t *wlc); extern void wlc_bmac_watchdog(void *arg); extern void wlc_bmac_info_init(wlc_hw_info_t *wlc_hw); diff --git a/drivers/staging/brcm80211/sys/wlc_mac80211.c b/drivers/staging/brcm80211/sys/wlc_mac80211.c index a9fa48a14c5d..9e57dc3cde21 100644 --- a/drivers/staging/brcm80211/sys/wlc_mac80211.c +++ b/drivers/staging/brcm80211/sys/wlc_mac80211.c @@ -265,8 +265,9 @@ static int wlc_iovar_rangecheck(wlc_info_t *wlc, u32 val, static u8 wlc_local_constraint_qdbm(wlc_info_t *wlc); /* send and receive */ -static wlc_txq_info_t *wlc_txq_alloc(wlc_info_t *wlc, osl_t *osh); -static void wlc_txq_free(wlc_info_t *wlc, osl_t *osh, wlc_txq_info_t *qi); +static wlc_txq_info_t *wlc_txq_alloc(wlc_info_t *wlc, struct osl_info *osh); +static void wlc_txq_free(wlc_info_t *wlc, struct osl_info *osh, + wlc_txq_info_t *qi); static void wlc_txflowcontrol_signal(wlc_info_t *wlc, wlc_txq_info_t *qi, bool on, int prio); static void wlc_txflowcontrol_reset(wlc_info_t *wlc); @@ -277,7 +278,7 @@ static void wlc_compute_ofdm_plcp(ratespec_t rate, uint length, u8 *plcp); static void wlc_compute_mimo_plcp(ratespec_t rate, uint length, u8 *plcp); static u16 wlc_compute_frame_dur(wlc_info_t *wlc, ratespec_t rate, u8 preamble_type, uint next_frag_len); -static void wlc_recvctl(wlc_info_t *wlc, osl_t *osh, d11rxhdr_t *rxh, +static void wlc_recvctl(wlc_info_t *wlc, struct osl_info *osh, d11rxhdr_t *rxh, void *p); static uint wlc_calc_frame_len(wlc_info_t *wlc, ratespec_t rate, u8 preamble_type, uint dur); @@ -324,7 +325,7 @@ void wlc_get_rcmta(wlc_info_t *wlc, int idx, struct ether_addr *addr) { d11regs_t *regs = wlc->regs; u32 v32; - osl_t *osh; + struct osl_info *osh; WL_TRACE(("wl%d: %s\n", WLCWLUNIT(wlc), __func__)); @@ -1754,8 +1755,8 @@ wlc_pub_t *wlc_pub(void *wlc) * The common driver entry routine. Error codes should be unique */ void *wlc_attach(void *wl, u16 vendor, u16 device, uint unit, bool piomode, - osl_t *osh, void *regsva, uint bustype, void *btparam, - uint *perr) + struct osl_info *osh, void *regsva, uint bustype, + void *btparam, uint *perr) { wlc_info_t *wlc; uint err = 0; @@ -2141,8 +2142,8 @@ static bool wlc_attach_stf_ant_init(wlc_info_t *wlc) #ifdef WLC_HIGH_ONLY /* HIGH_ONLY bmac_attach, which sync over LOW_ONLY bmac_attach states */ int wlc_bmac_attach(wlc_info_t *wlc, u16 vendor, u16 device, uint unit, - bool piomode, osl_t *osh, void *regsva, uint bustype, - void *btparam) + bool piomode, struct osl_info *osh, void *regsva, + uint bustype, void *btparam) { wlc_bmac_revinfo_t revinfo; uint idx = 0; @@ -3271,7 +3272,7 @@ _wlc_ioctl(wlc_info_t *wlc, int cmd, void *arg, int len, struct wlc_if *wlcif) uint band; rw_reg_t *r; wlc_bsscfg_t *bsscfg; - osl_t *osh; + struct osl_info *osh; wlc_bss_info_t *current_bss; /* update bsscfg pointer */ @@ -5877,7 +5878,7 @@ wlc_d11hdrs_mac80211(wlc_info_t *wlc, struct ieee80211_hw *hw, struct dot11_header *h; d11txh_t *txh; u8 *plcp, plcp_fallback[D11_PHY_HDR_LEN]; - osl_t *osh; + struct osl_info *osh; int len, phylen, rts_phylen; u16 fc, type, frameid, mch, phyctl, xfts, mainrates; u16 seq = 0, mcl = 0, status = 0; @@ -6750,7 +6751,7 @@ wlc_dotxstatus(wlc_info_t *wlc, tx_status_t *txs, u32 frm_tx2) d11txh_t *txh; struct scb *scb = NULL; bool free_pdu; - osl_t *osh; + struct osl_info *osh; int tx_rts, tx_frame_count, tx_rts_count; uint totlen, supr_status; bool lastframe; @@ -7144,7 +7145,7 @@ prep_mac80211_status(wlc_info_t *wlc, d11rxhdr_t *rxh, void *p, } static void -wlc_recvctl(wlc_info_t *wlc, osl_t *osh, d11rxhdr_t *rxh, void *p) +wlc_recvctl(wlc_info_t *wlc, struct osl_info *osh, d11rxhdr_t *rxh, void *p) { int len_mpdu; struct ieee80211_rx_status rx_status; @@ -7211,7 +7212,7 @@ void BCMFASTPATH wlc_recv(wlc_info_t *wlc, void *p) { d11rxhdr_t *rxh; struct dot11_header *h; - osl_t *osh; + struct osl_info *osh; u16 fc; uint len; bool is_amsdu; @@ -7913,7 +7914,7 @@ void wlc_bss_update_beacon(wlc_info_t *wlc, wlc_bsscfg_t *cfg) u16 bcn[BCN_TMPL_LEN / 2]; u32 both_valid = MCMD_BCN0VLD | MCMD_BCN1VLD; d11regs_t *regs = wlc->regs; - osl_t *osh = NULL; + struct osl_info *osh = NULL; osh = wlc->osh; @@ -8035,7 +8036,7 @@ wlc_bss_update_probe_resp(wlc_info_t *wlc, wlc_bsscfg_t *cfg, bool suspend) /* prepares pdu for transmission. returns BCM error codes */ int wlc_prep_pdu(wlc_info_t *wlc, void *pdu, uint *fifop) { - osl_t *osh; + struct osl_info *osh; uint fifo; d11txh_t *txh; struct dot11_header *h; @@ -8628,7 +8629,7 @@ wlc_txflowcontrol_signal(wlc_info_t *wlc, wlc_txq_info_t *qi, bool on, } } -static wlc_txq_info_t *wlc_txq_alloc(wlc_info_t *wlc, osl_t *osh) +static wlc_txq_info_t *wlc_txq_alloc(wlc_info_t *wlc, struct osl_info *osh) { wlc_txq_info_t *qi, *p; @@ -8658,7 +8659,8 @@ static wlc_txq_info_t *wlc_txq_alloc(wlc_info_t *wlc, osl_t *osh) return qi; } -static void wlc_txq_free(wlc_info_t *wlc, osl_t *osh, wlc_txq_info_t *qi) +static void wlc_txq_free(wlc_info_t *wlc, struct osl_info *osh, + wlc_txq_info_t *qi) { wlc_txq_info_t *p; diff --git a/drivers/staging/brcm80211/sys/wlc_mac80211.h b/drivers/staging/brcm80211/sys/wlc_mac80211.h index a3c6fb884990..ee0081b307f1 100644 --- a/drivers/staging/brcm80211/sys/wlc_mac80211.h +++ b/drivers/staging/brcm80211/sys/wlc_mac80211.h @@ -433,7 +433,7 @@ struct wlc_hw_info { #ifdef WLC_SPLIT rpc_info_t *rpc; /* Handle to RPC module */ #endif - osl_t *osh; /* pointer to os handle */ + struct osl_info *osh; /* pointer to os handle */ bool _piomode; /* true if pio mode */ wlc_info_t *wlc; @@ -536,7 +536,7 @@ typedef struct wlc_txq_info { */ struct wlc_info { wlc_pub_t *pub; /* pointer to wlc public state */ - osl_t *osh; /* pointer to os handle */ + struct osl_info *osh; /* pointer to os handle */ struct wl_info *wl; /* pointer to os-specific private state */ d11regs_t *regs; /* pointer to device registers */ diff --git a/drivers/staging/brcm80211/sys/wlc_pub.h b/drivers/staging/brcm80211/sys/wlc_pub.h index f6ac5e99cf31..09be41d921c5 100644 --- a/drivers/staging/brcm80211/sys/wlc_pub.h +++ b/drivers/staging/brcm80211/sys/wlc_pub.h @@ -260,7 +260,7 @@ typedef struct wlc_pub { uint mac80211_state; uint unit; /* device instance number */ uint corerev; /* core revision */ - osl_t *osh; /* pointer to os handle */ + struct osl_info *osh; /* pointer to os handle */ si_t *sih; /* SB handle (cookie for siutils calls) */ char *vars; /* "environment" name=value */ bool up; /* interface up and running */ @@ -493,8 +493,8 @@ extern const u8 wme_fifo2ac[]; /* common functions for every port */ extern void *wlc_attach(void *wl, u16 vendor, u16 device, uint unit, - bool piomode, osl_t *osh, void *regsva, uint bustype, - void *btparam, uint *perr); + bool piomode, struct osl_info *osh, void *regsva, + uint bustype, void *btparam, uint *perr); extern uint wlc_detach(struct wlc_info *wlc); extern int wlc_up(struct wlc_info *wlc); extern uint wlc_down(struct wlc_info *wlc); diff --git a/drivers/staging/brcm80211/util/bcmotp.c b/drivers/staging/brcm80211/util/bcmotp.c index 9b1e6d961a72..499cf0366200 100644 --- a/drivers/staging/brcm80211/util/bcmotp.c +++ b/drivers/staging/brcm80211/util/bcmotp.c @@ -78,7 +78,7 @@ typedef struct { uint ccrev; /* chipc revision */ otp_fn_t *fn; /* OTP functions */ si_t *sih; /* Saved sb handle */ - osl_t *osh; + struct osl_info *osh; #ifdef BCMIPXOTP /* IPX OTP section */ @@ -570,7 +570,7 @@ static int hndotp_size(void *oh) static u16 hndotp_otpr(void *oh, chipcregs_t *cc, uint wn) { otpinfo_t *oi = (otpinfo_t *) oh; - osl_t *osh; + struct osl_info *osh; volatile u16 *ptr; ASSERT(wn < ((oi->size / 2) + OTP_RC_LIM_OFF)); @@ -585,7 +585,7 @@ static u16 hndotp_otpr(void *oh, chipcregs_t *cc, uint wn) static u16 hndotp_otproff(void *oh, chipcregs_t *cc, int woff) { otpinfo_t *oi = (otpinfo_t *) oh; - osl_t *osh; + struct osl_info *osh; volatile u16 *ptr; ASSERT(woff >= (-((int)oi->size / 2))); @@ -604,7 +604,7 @@ static u16 hndotp_read_bit(void *oh, chipcregs_t *cc, uint idx) otpinfo_t *oi = (otpinfo_t *) oh; uint k, row, col; u32 otpp, st; - osl_t *osh; + struct osl_info *osh; osh = si_osh(oi->sih); row = idx / 65; @@ -637,7 +637,7 @@ static void *hndotp_init(si_t *sih) otpinfo_t *oi; u32 cap = 0, clkdiv, otpdiv = 0; void *ret = NULL; - osl_t *osh; + struct osl_info *osh; oi = &otpinfo; diff --git a/drivers/staging/brcm80211/util/bcmsrom.c b/drivers/staging/brcm80211/util/bcmsrom.c index 4f3d3ca1af79..7240e3c11c5c 100644 --- a/drivers/staging/brcm80211/util/bcmsrom.c +++ b/drivers/staging/brcm80211/util/bcmsrom.c @@ -67,29 +67,30 @@ extern uint _varsz; #define SROM_CIS_SINGLE 1 -static int initvars_srom_si(si_t *sih, osl_t *osh, void *curmap, char **vars, - uint *count); +static int initvars_srom_si(si_t *sih, struct osl_info *osh, void *curmap, + char **vars, uint *count); static void _initvars_srom_pci(u8 sromrev, u16 *srom, uint off, varbuf_t *b); static int initvars_srom_pci(si_t *sih, void *curmap, char **vars, uint *count); static int initvars_flash_si(si_t *sih, char **vars, uint *count); #ifdef BCMSDIO -static int initvars_cis_sdio(osl_t *osh, char **vars, uint *count); -static int sprom_cmd_sdio(osl_t *osh, u8 cmd); -static int sprom_read_sdio(osl_t *osh, u16 addr, u16 *data); +static int initvars_cis_sdio(struct osl_info *osh, char **vars, uint *count); +static int sprom_cmd_sdio(struct osl_info *osh, u8 cmd); +static int sprom_read_sdio(struct osl_info *osh, u16 addr, u16 *data); #endif /* BCMSDIO */ -static int sprom_read_pci(osl_t *osh, si_t *sih, u16 *sprom, uint wordoff, - u16 *buf, uint nwords, bool check_crc); +static int sprom_read_pci(struct osl_info *osh, si_t *sih, u16 *sprom, + uint wordoff, u16 *buf, uint nwords, bool check_crc); #if defined(BCMNVRAMR) -static int otp_read_pci(osl_t *osh, si_t *sih, u16 *buf, uint bufsz); +static int otp_read_pci(struct osl_info *osh, si_t *sih, u16 *buf, uint bufsz); #endif -static u16 srom_cc_cmd(si_t *sih, osl_t *osh, void *ccregs, u32 cmd, +static u16 srom_cc_cmd(si_t *sih, struct osl_info *osh, void *ccregs, u32 cmd, uint wordoff, u16 data); -static int initvars_table(osl_t *osh, char *start, char *end, char **vars, - uint *count); -static int initvars_flash(si_t *sih, osl_t *osh, char **vp, uint len); +static int initvars_table(struct osl_info *osh, char *start, char *end, + char **vars, uint *count); +static int initvars_flash(si_t *sih, struct osl_info *osh, char **vp, + uint len); /* Initialization of varbuf structure */ static void varbuf_init(varbuf_t *b, char *buf, uint size) @@ -156,7 +157,7 @@ static int varbuf_append(varbuf_t *b, const char *fmt, ...) * Initialize local vars from the right source for this platform. * Return 0 on success, nonzero on error. */ -int srom_var_init(si_t *sih, uint bustype, void *curmap, osl_t *osh, +int srom_var_init(si_t *sih, uint bustype, void *curmap, struct osl_info *osh, char **vars, uint *count) { uint len; @@ -195,7 +196,7 @@ int srom_var_init(si_t *sih, uint bustype, void *curmap, osl_t *osh, /* support only 16-bit word read from srom */ int -srom_read(si_t *sih, uint bustype, void *curmap, osl_t *osh, +srom_read(si_t *sih, uint bustype, void *curmap, struct osl_info *osh, uint byteoff, uint nbytes, u16 *buf, bool check_crc) { uint off, nw; @@ -377,7 +378,8 @@ u8 patch_pair; /* For dongle HW, accept partial calibration parameters */ #define BCMDONGLECASE(n) -int srom_parsecis(osl_t *osh, u8 *pcis[], uint ciscnt, char **vars, uint *count) +int srom_parsecis(struct osl_info *osh, u8 *pcis[], uint ciscnt, char **vars, + uint *count) { char eabuf[32]; char *base; @@ -1406,8 +1408,8 @@ int srom_parsecis(osl_t *osh, u8 *pcis[], uint ciscnt, char **vars, uint *count) * not in the bus cores. */ static u16 -srom_cc_cmd(si_t *sih, osl_t *osh, void *ccregs, u32 cmd, uint wordoff, - u16 data) +srom_cc_cmd(si_t *sih, struct osl_info *osh, void *ccregs, u32 cmd, + uint wordoff, u16 data) { chipcregs_t *cc = (chipcregs_t *) ccregs; uint wait_cnt = 1000; @@ -1440,7 +1442,7 @@ srom_cc_cmd(si_t *sih, osl_t *osh, void *ccregs, u32 cmd, uint wordoff, * Return 0 on success, nonzero on error. */ static int -sprom_read_pci(osl_t *osh, si_t *sih, u16 *sprom, uint wordoff, +sprom_read_pci(struct osl_info *osh, si_t *sih, u16 *sprom, uint wordoff, u16 *buf, uint nwords, bool check_crc) { int err = 0; @@ -1500,7 +1502,7 @@ sprom_read_pci(osl_t *osh, si_t *sih, u16 *sprom, uint wordoff, } #if defined(BCMNVRAMR) -static int otp_read_pci(osl_t *osh, si_t *sih, u16 *buf, uint bufsz) +static int otp_read_pci(struct osl_info *osh, si_t *sih, u16 *buf, uint bufsz) { u8 *otp; uint sz = OTP_SZ_MAX / 2; /* size in words */ @@ -1548,8 +1550,8 @@ static int otp_read_pci(osl_t *osh, si_t *sih, u16 *buf, uint bufsz) * Create variable table from memory. * Return 0 on success, nonzero on error. */ -static int initvars_table(osl_t *osh, char *start, char *end, char **vars, - uint *count) +static int initvars_table(struct osl_info *osh, char *start, char *end, + char **vars, uint *count) { int c = (int)(end - start); @@ -1575,7 +1577,8 @@ static int initvars_table(osl_t *osh, char *start, char *end, char **vars, * of the table upon enter and to the end of the table upon exit when success. * Return 0 on success, nonzero on error. */ -static int initvars_flash(si_t *sih, osl_t *osh, char **base, uint len) +static int initvars_flash(si_t *sih, struct osl_info *osh, char **base, + uint len) { char *vp = *base; char *flash; @@ -1635,7 +1638,7 @@ static int initvars_flash(si_t *sih, osl_t *osh, char **base, uint len) */ static int initvars_flash_si(si_t *sih, char **vars, uint *count) { - osl_t *osh = si_osh(sih); + struct osl_info *osh = si_osh(sih); char *vp, *base; int err; @@ -1846,7 +1849,7 @@ static int initvars_srom_pci(si_t *sih, void *curmap, char **vars, uint *count) u32 sr; varbuf_t b; char *vp, *base = NULL; - osl_t *osh = si_osh(sih); + struct osl_info *osh = si_osh(sih); bool flash = false; int err = 0; @@ -1987,7 +1990,7 @@ static int initvars_srom_pci(si_t *sih, void *curmap, char **vars, uint *count) * Read the SDIO cis and call parsecis to initialize the vars. * Return 0 on success, nonzero on error. */ -static int initvars_cis_sdio(osl_t *osh, char **vars, uint *count) +static int initvars_cis_sdio(struct osl_info *osh, char **vars, uint *count) { u8 *cis[SBSDIO_NUM_FUNCTION + 1]; uint fn, numfn; @@ -2021,7 +2024,7 @@ static int initvars_cis_sdio(osl_t *osh, char **vars, uint *count) } /* set SDIO sprom command register */ -static int sprom_cmd_sdio(osl_t *osh, u8 cmd) +static int sprom_cmd_sdio(struct osl_info *osh, u8 cmd) { u8 status = 0; uint wait_cnt = 1000; @@ -2041,7 +2044,7 @@ static int sprom_cmd_sdio(osl_t *osh, u8 cmd) } /* read a word from the SDIO srom */ -static int sprom_read_sdio(osl_t *osh, u16 addr, u16 *data) +static int sprom_read_sdio(struct osl_info *osh, u16 addr, u16 *data) { u8 addr_l, addr_h, data_l, data_h; @@ -2069,8 +2072,8 @@ static int sprom_read_sdio(osl_t *osh, u16 addr, u16 *data) } #endif /* BCMSDIO */ -static int initvars_srom_si(si_t *sih, osl_t *osh, void *curmap, char **vars, - uint *varsz) +static int initvars_srom_si(si_t *sih, struct osl_info *osh, void *curmap, + char **vars, uint *varsz) { /* Search flash nvram section for srom variables */ return initvars_flash_si(sih, vars, varsz); diff --git a/drivers/staging/brcm80211/util/bcmutils.c b/drivers/staging/brcm80211/util/bcmutils.c index 869d34c420d2..83f96cdfe771 100644 --- a/drivers/staging/brcm80211/util/bcmutils.c +++ b/drivers/staging/brcm80211/util/bcmutils.c @@ -33,7 +33,8 @@ #include /* copy a buffer into a pkt buffer chain */ -uint pktfrombuf(osl_t *osh, void *p, uint offset, int len, unsigned char *buf) +uint pktfrombuf(struct osl_info *osh, void *p, uint offset, int len, + unsigned char *buf) { uint n, ret = 0; @@ -60,7 +61,7 @@ uint pktfrombuf(osl_t *osh, void *p, uint offset, int len, unsigned char *buf) return ret; } /* return total length of buffer chain */ -uint BCMFASTPATH pkttotlen(osl_t *osh, void *p) +uint BCMFASTPATH pkttotlen(struct osl_info *osh, void *p) { uint total; @@ -185,7 +186,7 @@ void *BCMFASTPATH pktq_pdeq_tail(struct pktq *pq, int prec) } #ifdef BRCM_FULLMAC -void pktq_pflush(osl_t *osh, struct pktq *pq, int prec, bool dir) +void pktq_pflush(struct osl_info *osh, struct pktq *pq, int prec, bool dir) { struct pktq_prec *q; void *p; @@ -204,7 +205,7 @@ void pktq_pflush(osl_t *osh, struct pktq *pq, int prec, bool dir) q->tail = NULL; } -void pktq_flush(osl_t *osh, struct pktq *pq, bool dir) +void pktq_flush(struct osl_info *osh, struct pktq *pq, bool dir) { int prec; for (prec = 0; prec < pq->num_prec; prec++) @@ -213,8 +214,8 @@ void pktq_flush(osl_t *osh, struct pktq *pq, bool dir) } #else /* !BRCM_FULLMAC */ void -pktq_pflush(osl_t *osh, struct pktq *pq, int prec, bool dir, ifpkt_cb_t fn, - int arg) +pktq_pflush(struct osl_info *osh, struct pktq *pq, int prec, bool dir, + ifpkt_cb_t fn, int arg) { struct pktq_prec *q; void *p, *prev = NULL; @@ -245,7 +246,8 @@ pktq_pflush(osl_t *osh, struct pktq *pq, int prec, bool dir, ifpkt_cb_t fn, } } -void pktq_flush(osl_t *osh, struct pktq *pq, bool dir, ifpkt_cb_t fn, int arg) +void pktq_flush(struct osl_info *osh, struct pktq *pq, bool dir, + ifpkt_cb_t fn, int arg) { int prec; for (prec = 0; prec < pq->num_prec; prec++) @@ -405,7 +407,7 @@ int getintvar(char *vars, const char *name) #if defined(BCMDBG) /* pretty hex print a pkt buffer chain */ -void prpkt(const char *msg, osl_t *osh, void *p0) +void prpkt(const char *msg, struct osl_info *osh, void *p0) { void *p; diff --git a/drivers/staging/brcm80211/util/hnddma.c b/drivers/staging/brcm80211/util/hnddma.c index b4dcb05705b3..a945156eb31f 100644 --- a/drivers/staging/brcm80211/util/hnddma.c +++ b/drivers/staging/brcm80211/util/hnddma.c @@ -223,7 +223,7 @@ static void _dma_counterreset(dma_info_t *di); static void _dma_fifoloopbackenable(dma_info_t *di); static uint _dma_ctrlflags(dma_info_t *di, uint mask, uint flags); static u8 dma_align_sizetobits(uint size); -static void *dma_ringalloc(osl_t *osh, u32 boundary, uint size, +static void *dma_ringalloc(struct osl_info *osh, u32 boundary, uint size, u16 *alignbits, uint *alloced, dmaaddr_t *descpa, osldma_t **dmah); @@ -247,7 +247,7 @@ static bool dma32_txstopped(dma_info_t *di); static bool dma32_rxstopped(dma_info_t *di); static bool dma32_rxenabled(dma_info_t *di); -static bool _dma32_addrext(osl_t *osh, dma32regs_t *dma32regs); +static bool _dma32_addrext(struct osl_info *osh, dma32regs_t *dma32regs); /* Prototypes for 64-bit routines */ static bool dma64_alloc(dma_info_t *di, uint direction); @@ -271,7 +271,7 @@ static void dma64_txreclaim(dma_info_t *di, txd_range_t range); static bool dma64_txstopped(dma_info_t *di); static bool dma64_rxstopped(dma_info_t *di); static bool dma64_rxenabled(dma_info_t *di); -static bool _dma64_addrext(osl_t *osh, dma64regs_t *dma64regs); +static bool _dma64_addrext(struct osl_info *osh, dma64regs_t *dma64regs); static inline u32 parity32(u32 data); @@ -369,10 +369,10 @@ static const di_fcn_t dma32proc = { 39 }; -hnddma_t *dma_attach(osl_t *osh, char *name, si_t *sih, void *dmaregstx, - void *dmaregsrx, uint ntxd, uint nrxd, uint rxbufsize, - int rxextheadroom, uint nrxpost, uint rxoffset, - uint *msg_level) +hnddma_t *dma_attach(struct osl_info *osh, char *name, si_t *sih, + void *dmaregstx, void *dmaregsrx, uint ntxd, + uint nrxd, uint rxbufsize, int rxextheadroom, + uint nrxpost, uint rxoffset, uint *msg_level) { dma_info_t *di; uint size; @@ -664,7 +664,7 @@ dma64_dd_upd(dma_info_t *di, dma64dd_t *ddring, dmaaddr_t pa, uint outidx, } } -static bool _dma32_addrext(osl_t *osh, dma32regs_t *dma32regs) +static bool _dma32_addrext(struct osl_info *osh, dma32regs_t *dma32regs) { u32 w; @@ -1373,7 +1373,7 @@ static unsigned long _dma_getvar(dma_info_t *di, const char *name) return 0; } -void dma_txpioloopback(osl_t *osh, dma32regs_t *regs) +void dma_txpioloopback(struct osl_info *osh, dma32regs_t *regs) { OR_REG(osh, ®s->control, XC_LE); } @@ -1396,7 +1396,7 @@ u8 dma_align_sizetobits(uint size) * descriptor ring size aligned location. This will ensure that the ring will * not cross page boundary */ -static void *dma_ringalloc(osl_t *osh, u32 boundary, uint size, +static void *dma_ringalloc(struct osl_info *osh, u32 boundary, uint size, u16 *alignbits, uint *alloced, dmaaddr_t *descpa, osldma_t **dmah) { @@ -2564,7 +2564,7 @@ static void *BCMFASTPATH dma64_getnextrxp(dma_info_t *di, bool forceall) return rxp; } -static bool _dma64_addrext(osl_t *osh, dma64regs_t * dma64regs) +static bool _dma64_addrext(struct osl_info *osh, dma64regs_t * dma64regs) { u32 w; OR_REG(osh, &dma64regs->control, D64_XC_AE); @@ -2655,7 +2655,7 @@ static void dma64_txrotate(dma_info_t *di) uint dma_addrwidth(si_t *sih, void *dmaregs) { dma32regs_t *dma32regs; - osl_t *osh; + struct osl_info *osh; osh = si_osh(sih); diff --git a/drivers/staging/brcm80211/util/hndpmu.c b/drivers/staging/brcm80211/util/hndpmu.c index 6fb256bc5549..5b6fa72b99e8 100644 --- a/drivers/staging/brcm80211/util/hndpmu.c +++ b/drivers/staging/brcm80211/util/hndpmu.c @@ -44,23 +44,23 @@ #define PMU_NONE(args) /* PLL controls/clocks */ -static void si_pmu1_pllinit0(si_t *sih, osl_t *osh, chipcregs_t *cc, +static void si_pmu1_pllinit0(si_t *sih, struct osl_info *osh, chipcregs_t *cc, u32 xtal); -static u32 si_pmu1_cpuclk0(si_t *sih, osl_t *osh, chipcregs_t *cc); -static u32 si_pmu1_alpclk0(si_t *sih, osl_t *osh, chipcregs_t *cc); +static u32 si_pmu1_cpuclk0(si_t *sih, struct osl_info *osh, chipcregs_t *cc); +static u32 si_pmu1_alpclk0(si_t *sih, struct osl_info *osh, chipcregs_t *cc); /* PMU resources */ static bool si_pmu_res_depfltr_bb(si_t *sih); static bool si_pmu_res_depfltr_ncb(si_t *sih); static bool si_pmu_res_depfltr_paldo(si_t *sih); static bool si_pmu_res_depfltr_npaldo(si_t *sih); -static u32 si_pmu_res_deps(si_t *sih, osl_t *osh, chipcregs_t *cc, +static u32 si_pmu_res_deps(si_t *sih, struct osl_info *osh, chipcregs_t *cc, u32 rsrcs, bool all); -static uint si_pmu_res_uptime(si_t *sih, osl_t *osh, chipcregs_t *cc, +static uint si_pmu_res_uptime(si_t *sih, struct osl_info *osh, chipcregs_t *cc, u8 rsrc); static void si_pmu_res_masks(si_t *sih, u32 * pmin, u32 * pmax); static void si_pmu_spuravoid_pllupdate(si_t *sih, chipcregs_t *cc, - osl_t *osh, u8 spuravoid); + struct osl_info *osh, u8 spuravoid); static void si_pmu_set_4330_plldivs(si_t *sih); @@ -105,7 +105,7 @@ void si_pmu_pllupd(si_t *sih) } /* Setup switcher voltage */ -void si_pmu_set_switcher_voltage(si_t *sih, osl_t *osh, u8 bb_voltage, +void si_pmu_set_switcher_voltage(si_t *sih, struct osl_info *osh, u8 bb_voltage, u8 rf_voltage) { chipcregs_t *cc; @@ -128,7 +128,7 @@ void si_pmu_set_switcher_voltage(si_t *sih, osl_t *osh, u8 bb_voltage, si_setcoreidx(sih, origidx); } -void si_pmu_set_ldo_voltage(si_t *sih, osl_t *osh, u8 ldo, u8 voltage) +void si_pmu_set_ldo_voltage(si_t *sih, struct osl_info *osh, u8 ldo, u8 voltage) { u8 sr_cntl_shift = 0, rc_shift = 0, shift = 0, mask = 0; u8 addr = 0; @@ -186,7 +186,7 @@ void si_pmu_set_ldo_voltage(si_t *sih, osl_t *osh, u8 ldo, u8 voltage) /* d11 slow to fast clock transition time in slow clock cycles */ #define D11SCC_SLOW2FAST_TRANSITION 2 -u16 si_pmu_fast_pwrup_delay(si_t *sih, osl_t *osh) +u16 si_pmu_fast_pwrup_delay(si_t *sih, struct osl_info *osh) { uint delay = PMU_MAX_TRANSITION_DLY; chipcregs_t *cc; @@ -263,7 +263,7 @@ u16 si_pmu_fast_pwrup_delay(si_t *sih, osl_t *osh) return (u16) delay; } -u32 si_pmu_force_ilp(si_t *sih, osl_t *osh, bool force) +u32 si_pmu_force_ilp(si_t *sih, struct osl_info *osh, bool force) { chipcregs_t *cc; uint origidx; @@ -681,7 +681,7 @@ static void si_pmu_res_masks(si_t *sih, u32 * pmin, u32 * pmax) } /* initialize PMU resources */ -void si_pmu_res_init(si_t *sih, osl_t *osh) +void si_pmu_res_init(si_t *sih, struct osl_info *osh) { chipcregs_t *cc; uint origidx; @@ -1182,7 +1182,7 @@ static u32 si_pmu1_pllfvco0(si_t *sih) /* query alp/xtal clock frequency */ static u32 -si_pmu1_alpclk0(si_t *sih, osl_t *osh, chipcregs_t *cc) +si_pmu1_alpclk0(si_t *sih, struct osl_info *osh, chipcregs_t *cc) { const pmu1_xtaltab0_t *xt; u32 xf; @@ -1207,7 +1207,8 @@ si_pmu1_alpclk0(si_t *sih, osl_t *osh, chipcregs_t *cc) * case the xtal frequency is unknown to the s/w so we need to call * si_pmu1_xtaldef0() wherever it is needed to return a default value. */ -static void si_pmu1_pllinit0(si_t *sih, osl_t *osh, chipcregs_t *cc, u32 xtal) +static void si_pmu1_pllinit0(si_t *sih, struct osl_info *osh, chipcregs_t *cc, + u32 xtal) { const pmu1_xtaltab0_t *xt; u32 tmp; @@ -1452,7 +1453,7 @@ static void si_pmu1_pllinit0(si_t *sih, osl_t *osh, chipcregs_t *cc, u32 xtal) /* query the CPU clock frequency */ static u32 -si_pmu1_cpuclk0(si_t *sih, osl_t *osh, chipcregs_t *cc) +si_pmu1_cpuclk0(si_t *sih, struct osl_info *osh, chipcregs_t *cc) { u32 tmp, m1div; #ifdef BCMDBG @@ -1506,7 +1507,7 @@ si_pmu1_cpuclk0(si_t *sih, osl_t *osh, chipcregs_t *cc) } /* initialize PLL */ -void si_pmu_pll_init(si_t *sih, osl_t *osh, uint xtalfreq) +void si_pmu_pll_init(si_t *sih, struct osl_info *osh, uint xtalfreq) { chipcregs_t *cc; uint origidx; @@ -1559,7 +1560,7 @@ void si_pmu_pll_init(si_t *sih, osl_t *osh, uint xtalfreq) } /* query alp/xtal clock frequency */ -u32 si_pmu_alp_clock(si_t *sih, osl_t *osh) +u32 si_pmu_alp_clock(si_t *sih, struct osl_info *osh) { chipcregs_t *cc; uint origidx; @@ -1620,7 +1621,7 @@ u32 si_pmu_alp_clock(si_t *sih, osl_t *osh) * pllreg "pll0" i.e. 12 for main 6 for phy, 0 for misc. */ static u32 -si_pmu5_clock(si_t *sih, osl_t *osh, chipcregs_t *cc, uint pll0, +si_pmu5_clock(si_t *sih, struct osl_info *osh, chipcregs_t *cc, uint pll0, uint m) { u32 tmp, div, ndiv, p1, p2, fc; @@ -1673,7 +1674,7 @@ si_pmu5_clock(si_t *sih, osl_t *osh, chipcregs_t *cc, uint pll0, /* For designs that feed the same clock to both backplane * and CPU just return the CPU clock speed. */ -u32 si_pmu_si_clock(si_t *sih, osl_t *osh) +u32 si_pmu_si_clock(si_t *sih, struct osl_info *osh) { chipcregs_t *cc; uint origidx; @@ -1752,7 +1753,7 @@ u32 si_pmu_si_clock(si_t *sih, osl_t *osh) } /* query CPU clock frequency */ -u32 si_pmu_cpu_clock(si_t *sih, osl_t *osh) +u32 si_pmu_cpu_clock(si_t *sih, struct osl_info *osh) { chipcregs_t *cc; uint origidx; @@ -1796,7 +1797,7 @@ u32 si_pmu_cpu_clock(si_t *sih, osl_t *osh) } /* query memory clock frequency */ -u32 si_pmu_mem_clock(si_t *sih, osl_t *osh) +u32 si_pmu_mem_clock(si_t *sih, struct osl_info *osh) { chipcregs_t *cc; uint origidx; @@ -1845,7 +1846,7 @@ u32 si_pmu_mem_clock(si_t *sih, osl_t *osh) static u32 ilpcycles_per_sec; -u32 si_pmu_ilp_clock(si_t *sih, osl_t *osh) +u32 si_pmu_ilp_clock(si_t *sih, struct osl_info *osh) { if (ISSIM_ENAB(sih)) return ILP_CLOCK; @@ -1909,7 +1910,7 @@ static const sdiod_drive_str_t sdiod_drive_strength_tab3[] = { #define SDIOD_DRVSTR_KEY(chip, pmu) (((chip) << 16) | (pmu)) void -si_sdiod_drive_strength_init(si_t *sih, osl_t *osh, +si_sdiod_drive_strength_init(si_t *sih, struct osl_info *osh, u32 drivestrength) { chipcregs_t *cc; uint origidx, intr_val = 0; @@ -1980,7 +1981,7 @@ si_sdiod_drive_strength_init(si_t *sih, osl_t *osh, } /* initialize PMU */ -void si_pmu_init(si_t *sih, osl_t *osh) +void si_pmu_init(si_t *sih, struct osl_info *osh) { chipcregs_t *cc; uint origidx; @@ -2012,7 +2013,7 @@ void si_pmu_init(si_t *sih, osl_t *osh) /* Return up time in ILP cycles for the given resource. */ static uint -si_pmu_res_uptime(si_t *sih, osl_t *osh, chipcregs_t *cc, +si_pmu_res_uptime(si_t *sih, struct osl_info *osh, chipcregs_t *cc, u8 rsrc) { u32 deps; uint up, i, dup, dmax; @@ -2049,7 +2050,7 @@ si_pmu_res_uptime(si_t *sih, osl_t *osh, chipcregs_t *cc, /* Return dependancies (direct or all/indirect) for the given resources */ static u32 -si_pmu_res_deps(si_t *sih, osl_t *osh, chipcregs_t *cc, u32 rsrcs, +si_pmu_res_deps(si_t *sih, struct osl_info *osh, chipcregs_t *cc, u32 rsrcs, bool all) { u32 deps = 0; @@ -2069,7 +2070,7 @@ si_pmu_res_deps(si_t *sih, osl_t *osh, chipcregs_t *cc, u32 rsrcs, } /* power up/down OTP through PMU resources */ -void si_pmu_otp_power(si_t *sih, osl_t *osh, bool on) +void si_pmu_otp_power(si_t *sih, struct osl_info *osh, bool on) { chipcregs_t *cc; uint origidx; @@ -2139,7 +2140,7 @@ void si_pmu_otp_power(si_t *sih, osl_t *osh, bool on) si_setcoreidx(sih, origidx); } -void si_pmu_rcal(si_t *sih, osl_t *osh) +void si_pmu_rcal(si_t *sih, struct osl_info *osh) { chipcregs_t *cc; uint origidx; @@ -2222,7 +2223,7 @@ void si_pmu_rcal(si_t *sih, osl_t *osh) si_setcoreidx(sih, origidx); } -void si_pmu_spuravoid(si_t *sih, osl_t *osh, u8 spuravoid) +void si_pmu_spuravoid(si_t *sih, struct osl_info *osh, u8 spuravoid) { chipcregs_t *cc; uint origidx, intr_val; @@ -2259,7 +2260,7 @@ void si_pmu_spuravoid(si_t *sih, osl_t *osh, u8 spuravoid) } static void -si_pmu_spuravoid_pllupdate(si_t *sih, chipcregs_t *cc, osl_t *osh, +si_pmu_spuravoid_pllupdate(si_t *sih, chipcregs_t *cc, struct osl_info *osh, u8 spuravoid) { u32 tmp = 0; @@ -2455,7 +2456,7 @@ si_pmu_spuravoid_pllupdate(si_t *sih, chipcregs_t *cc, osl_t *osh, W_REG(osh, &cc->pmucontrol, tmp); } -bool si_pmu_is_otp_powered(si_t *sih, osl_t *osh) +bool si_pmu_is_otp_powered(si_t *sih, struct osl_info *osh) { uint idx; chipcregs_t *cc; @@ -2507,9 +2508,9 @@ bool si_pmu_is_otp_powered(si_t *sih, osl_t *osh) void #if defined(BCMDBG) -si_pmu_sprom_enable(si_t *sih, osl_t *osh, bool enable) +si_pmu_sprom_enable(si_t *sih, struct osl_info *osh, bool enable) #else -si_pmu_sprom_enable(si_t *sih, osl_t *osh, bool enable) +si_pmu_sprom_enable(si_t *sih, struct osl_info *osh, bool enable) #endif { chipcregs_t *cc; @@ -2525,7 +2526,7 @@ si_pmu_sprom_enable(si_t *sih, osl_t *osh, bool enable) } /* initialize PMU chip controls and other chip level stuff */ -void si_pmu_chip_init(si_t *sih, osl_t *osh) +void si_pmu_chip_init(si_t *sih, struct osl_info *osh) { uint origidx; @@ -2547,7 +2548,7 @@ void si_pmu_chip_init(si_t *sih, osl_t *osh) } /* initialize PMU switch/regulators */ -void si_pmu_swreg_init(si_t *sih, osl_t *osh) +void si_pmu_swreg_init(si_t *sih, struct osl_info *osh) { ASSERT(sih->cccaps & CC_CAP_PMU); @@ -2591,7 +2592,7 @@ void si_pmu_radio_enable(si_t *sih, bool enable) /* Wait for a particular clock level to be on the backplane */ u32 -si_pmu_waitforclk_on_backplane(si_t *sih, osl_t *osh, u32 clk, +si_pmu_waitforclk_on_backplane(si_t *sih, struct osl_info *osh, u32 clk, u32 delay) { chipcregs_t *cc; @@ -2620,7 +2621,7 @@ si_pmu_waitforclk_on_backplane(si_t *sih, osl_t *osh, u32 clk, #define EXT_ILP_HZ 32768 -u32 si_pmu_measure_alpclk(si_t *sih, osl_t *osh) +u32 si_pmu_measure_alpclk(si_t *sih, struct osl_info *osh) { chipcregs_t *cc; uint origidx; diff --git a/drivers/staging/brcm80211/util/linux_osl.c b/drivers/staging/brcm80211/util/linux_osl.c index eb5d285efc04..e6e52f660780 100644 --- a/drivers/staging/brcm80211/util/linux_osl.c +++ b/drivers/staging/brcm80211/util/linux_osl.c @@ -36,14 +36,14 @@ /* Global ASSERT type flag */ u32 g_assert_type; -osl_t *osl_attach(void *pdev, uint bustype) +struct osl_info *osl_attach(void *pdev, uint bustype) { - osl_t *osh; + struct osl_info *osh; - osh = kmalloc(sizeof(osl_t), GFP_ATOMIC); + osh = kmalloc(sizeof(struct osl_info), GFP_ATOMIC); ASSERT(osh); - bzero(osh, sizeof(osl_t)); + bzero(osh, sizeof(struct osl_info)); osh->magic = OS_HANDLE_MAGIC; osh->pdev = pdev; @@ -70,7 +70,7 @@ osl_t *osl_attach(void *pdev, uint bustype) return osh; } -void osl_detach(osl_t *osh) +void osl_detach(struct osl_info *osh) { if (osh == NULL) return; @@ -79,7 +79,7 @@ void osl_detach(osl_t *osh) kfree(osh); } -void *BCMFASTPATH osl_pktget(osl_t *osh, uint len) +void *BCMFASTPATH osl_pktget(struct osl_info *osh, uint len) { struct sk_buff *skb; @@ -95,7 +95,7 @@ void *BCMFASTPATH osl_pktget(osl_t *osh, uint len) } /* Free the driver packet. Free the tag if present */ -void BCMFASTPATH osl_pktfree(osl_t *osh, void *p, bool send) +void BCMFASTPATH osl_pktfree(struct osl_info *osh, void *p, bool send) { struct sk_buff *skb, *nskb; int nest = 0; @@ -128,20 +128,21 @@ void BCMFASTPATH osl_pktfree(osl_t *osh, void *p, bool send) } } -u32 osl_pci_read_config(osl_t *osh, uint offset, uint size) +u32 osl_pci_read_config(struct osl_info *osh, uint offset, uint size) { uint val; pci_read_config_dword(osh->pdev, offset, &val); return val; } -void osl_pci_write_config(osl_t *osh, uint offset, uint size, uint val) +void osl_pci_write_config(struct osl_info *osh, uint offset, uint size, + uint val) { pci_write_config_dword(osh->pdev, offset, val); } /* return bus # for the pci device pointed by osh->pdev */ -uint osl_pci_bus(osl_t *osh) +uint osl_pci_bus(struct osl_info *osh) { ASSERT(osh && (osh->magic == OS_HANDLE_MAGIC) && osh->pdev); @@ -149,14 +150,14 @@ uint osl_pci_bus(osl_t *osh) } /* return slot # for the pci device pointed by osh->pdev */ -uint osl_pci_slot(osl_t *osh) +uint osl_pci_slot(struct osl_info *osh) { ASSERT(osh && (osh->magic == OS_HANDLE_MAGIC) && osh->pdev); return PCI_SLOT(((struct pci_dev *)osh->pdev)->devfn); } -void *osl_dma_alloc_consistent(osl_t *osh, uint size, u16 align_bits, +void *osl_dma_alloc_consistent(struct osl_info *osh, uint size, u16 align_bits, uint *alloced, unsigned long *pap) { ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); @@ -170,14 +171,16 @@ void *osl_dma_alloc_consistent(osl_t *osh, uint size, u16 align_bits, return pci_alloc_consistent(osh->pdev, size, (dma_addr_t *) pap); } -void osl_dma_free_consistent(osl_t *osh, void *va, uint size, unsigned long pa) +void osl_dma_free_consistent(struct osl_info *osh, void *va, uint size, + unsigned long pa) { ASSERT((osh && (osh->magic == OS_HANDLE_MAGIC))); pci_free_consistent(osh->pdev, size, va, (dma_addr_t) pa); } -uint BCMFASTPATH osl_dma_map(osl_t *osh, void *va, uint size, int direction) +uint BCMFASTPATH osl_dma_map(struct osl_info *osh, void *va, uint size, + int direction) { int dir; @@ -186,7 +189,8 @@ uint BCMFASTPATH osl_dma_map(osl_t *osh, void *va, uint size, int direction) return pci_map_single(osh->pdev, va, size, dir); } -void BCMFASTPATH osl_dma_unmap(osl_t *osh, uint pa, uint size, int direction) +void BCMFASTPATH osl_dma_unmap(struct osl_info *osh, uint pa, uint size, + int direction) { int dir; @@ -243,7 +247,7 @@ void osl_assert(char *exp, char *file, int line) #endif /* defined(BCMDBG_ASSERT) */ #if defined(BCMSDIO) && !defined(BRCM_FULLMAC) -u8 osl_readb(osl_t *osh, volatile u8 *r) +u8 osl_readb(struct osl_info *osh, volatile u8 *r) { osl_rreg_fn_t rreg = ((struct osl_pubinfo *) osh)->rreg_fn; void *ctx = ((struct osl_pubinfo *) osh)->reg_ctx; @@ -251,7 +255,7 @@ u8 osl_readb(osl_t *osh, volatile u8 *r) return (u8) ((rreg) (ctx, (void *)r, sizeof(u8))); } -u16 osl_readw(osl_t *osh, volatile u16 *r) +u16 osl_readw(struct osl_info *osh, volatile u16 *r) { osl_rreg_fn_t rreg = ((struct osl_pubinfo *) osh)->rreg_fn; void *ctx = ((struct osl_pubinfo *) osh)->reg_ctx; @@ -259,7 +263,7 @@ u16 osl_readw(osl_t *osh, volatile u16 *r) return (u16) ((rreg) (ctx, (void *)r, sizeof(u16))); } -u32 osl_readl(osl_t *osh, volatile u32 *r) +u32 osl_readl(struct osl_info *osh, volatile u32 *r) { osl_rreg_fn_t rreg = ((struct osl_pubinfo *) osh)->rreg_fn; void *ctx = ((struct osl_pubinfo *) osh)->reg_ctx; @@ -267,7 +271,7 @@ u32 osl_readl(osl_t *osh, volatile u32 *r) return (u32) ((rreg) (ctx, (void *)r, sizeof(u32))); } -void osl_writeb(osl_t *osh, volatile u8 *r, u8 v) +void osl_writeb(struct osl_info *osh, volatile u8 *r, u8 v) { osl_wreg_fn_t wreg = ((struct osl_pubinfo *) osh)->wreg_fn; void *ctx = ((struct osl_pubinfo *) osh)->reg_ctx; @@ -275,7 +279,7 @@ void osl_writeb(osl_t *osh, volatile u8 *r, u8 v) ((wreg) (ctx, (void *)r, v, sizeof(u8))); } -void osl_writew(osl_t *osh, volatile u16 *r, u16 v) +void osl_writew(struct osl_info *osh, volatile u16 *r, u16 v) { osl_wreg_fn_t wreg = ((struct osl_pubinfo *) osh)->wreg_fn; void *ctx = ((struct osl_pubinfo *) osh)->reg_ctx; @@ -283,7 +287,7 @@ void osl_writew(osl_t *osh, volatile u16 *r, u16 v) ((wreg) (ctx, (void *)r, v, sizeof(u16))); } -void osl_writel(osl_t *osh, volatile u32 *r, u32 v) +void osl_writel(struct osl_info *osh, volatile u32 *r, u32 v) { osl_wreg_fn_t wreg = ((struct osl_pubinfo *) osh)->wreg_fn; void *ctx = ((struct osl_pubinfo *) osh)->reg_ctx; diff --git a/drivers/staging/brcm80211/util/nicpci.c b/drivers/staging/brcm80211/util/nicpci.c index 169a4287ee63..8a7b71ee93d3 100644 --- a/drivers/staging/brcm80211/util/nicpci.c +++ b/drivers/staging/brcm80211/util/nicpci.c @@ -35,7 +35,7 @@ typedef struct { } regs; /* Memory mapped register to the core */ si_t *sih; /* System interconnect handle */ - osl_t *osh; /* OSL handle */ + struct osl_info *osh; /* OSL handle */ u8 pciecap_lcreg_offset; /* PCIE capability LCreg offset in the config space */ bool pcie_pr42767; u8 pcie_polarity; @@ -107,7 +107,7 @@ static bool pcicore_pmecap(pcicore_info_t *pi); /* Initialize the PCI core. It's caller's responsibility to make sure that this is done * only once */ -void *pcicore_init(si_t *sih, osl_t *osh, void *regs) +void *pcicore_init(si_t *sih, struct osl_info *osh, void *regs) { pcicore_info_t *pi; @@ -149,8 +149,8 @@ void pcicore_deinit(void *pch) /* return cap_offset if requested capability exists in the PCI config space */ /* Note that it's caller's responsibility to make sure it's a pci bus */ u8 -pcicore_find_pci_capability(osl_t *osh, u8 req_cap_id, unsigned char *buf, - u32 *buflen) +pcicore_find_pci_capability(struct osl_info *osh, u8 req_cap_id, + unsigned char *buf, u32 *buflen) { u8 cap_id; u8 cap_ptr = 0; @@ -210,7 +210,8 @@ pcicore_find_pci_capability(osl_t *osh, u8 req_cap_id, unsigned char *buf, /* ***** Register Access API */ uint -pcie_readreg(osl_t *osh, sbpcieregs_t *pcieregs, uint addrtype, uint offset) +pcie_readreg(struct osl_info *osh, sbpcieregs_t *pcieregs, uint addrtype, + uint offset) { uint retval = 0xFFFFFFFF; @@ -236,8 +237,8 @@ pcie_readreg(osl_t *osh, sbpcieregs_t *pcieregs, uint addrtype, uint offset) } uint -pcie_writereg(osl_t *osh, sbpcieregs_t *pcieregs, uint addrtype, uint offset, - uint val) +pcie_writereg(struct osl_info *osh, sbpcieregs_t *pcieregs, uint addrtype, + uint offset, uint val) { ASSERT(pcieregs != NULL); @@ -393,7 +394,7 @@ static void pcie_extendL1timer(pcicore_info_t *pi, bool extend) { u32 w; si_t *sih = pi->sih; - osl_t *osh = pi->osh; + struct osl_info *osh = pi->osh; sbpcieregs_t *pcieregs = pi->regs.pcieregs; if (!PCIE_PUB(sih) || sih->buscorerev < 7) @@ -577,7 +578,7 @@ static void pcie_war_noplldown(pcicore_info_t *pi) static void pcie_war_pci_setup(pcicore_info_t *pi) { si_t *sih = pi->sih; - osl_t *osh = pi->osh; + struct osl_info *osh = pi->osh; sbpcieregs_t *pcieregs = pi->regs.pcieregs; u32 w; @@ -718,7 +719,7 @@ void pcicore_down(void *pch, int state) /* ***** Wake-on-wireless-LAN (WOWL) support functions ***** */ /* Just uses PCI config accesses to find out, when needed before sb_attach is done */ -bool pcicore_pmecap_fast(osl_t *osh) +bool pcicore_pmecap_fast(struct osl_info *osh) { u8 cap_ptr; u32 pmecap; @@ -842,7 +843,7 @@ pcicore_pciereg(void *pch, u32 offset, u32 mask, u32 val, uint type) u32 reg_val = 0; pcicore_info_t *pi = (pcicore_info_t *) pch; sbpcieregs_t *pcieregs = pi->regs.pcieregs; - osl_t *osh = pi->osh; + struct osl_info *osh = pi->osh; if (mask) { PCI_ERROR(("PCIEREG: 0x%x writeval 0x%x\n", offset, val)); diff --git a/drivers/staging/brcm80211/util/nvram/nvram_ro.c b/drivers/staging/brcm80211/util/nvram/nvram_ro.c index f80375cd6801..2521c5b19192 100644 --- a/drivers/staging/brcm80211/util/nvram/nvram_ro.c +++ b/drivers/staging/brcm80211/util/nvram/nvram_ro.c @@ -49,7 +49,7 @@ static char *findvar(char *vars, char *lim, const char *name); /* copy flash to ram */ static void get_flash_nvram(si_t *sih, struct nvram_header *nvh) { - osl_t *osh; + struct osl_info *osh; uint nvs, bufsz; vars_t *new; diff --git a/drivers/staging/brcm80211/util/siutils.c b/drivers/staging/brcm80211/util/siutils.c index 3b99293307ea..4d2df4977727 100644 --- a/drivers/staging/brcm80211/util/siutils.c +++ b/drivers/staging/brcm80211/util/siutils.c @@ -57,7 +57,7 @@ #endif /* local prototypes */ -static si_info_t *si_doattach(si_info_t *sii, uint devid, osl_t *osh, +static si_info_t *si_doattach(si_info_t *sii, uint devid, struct osl_info *osh, void *regs, uint bustype, void *sdh, char **vars, uint *varsz); static bool si_buscore_prep(si_info_t *sii, uint bustype, uint devid, @@ -85,8 +85,8 @@ static u32 si_gpioreservation; * vars - pointer to a pointer area for "environment" variables * varsz - pointer to int to return the size of the vars */ -si_t *si_attach(uint devid, osl_t *osh, void *regs, uint bustype, void *sdh, - char **vars, uint *varsz) +si_t *si_attach(uint devid, struct osl_info *osh, void *regs, uint bustype, + void *sdh, char **vars, uint *varsz) { si_info_t *sii; @@ -368,7 +368,7 @@ static __used void si_nvram_process(si_info_t *sii, char *pvars) /* this is will make Sonics calls directly, since Sonics is no longer supported in the Si abstraction */ /* this has been customized for the bcm 4329 ONLY */ #ifdef BCMSDIO -static si_info_t *si_doattach(si_info_t *sii, uint devid, osl_t *osh, +static si_info_t *si_doattach(si_info_t *sii, uint devid, struct osl_info *osh, void *regs, uint bustype, void *sdh, char **vars, uint *varsz) { @@ -503,7 +503,7 @@ static si_info_t *si_doattach(si_info_t *sii, uint devid, osl_t *osh, } #else /* BCMSDIO */ -static si_info_t *si_doattach(si_info_t *sii, uint devid, osl_t *osh, +static si_info_t *si_doattach(si_info_t *sii, uint devid, struct osl_info *osh, void *regs, uint bustype, void *sdh, char **vars, uint *varsz) { -- cgit v1.2.3 From 93760716840a3feada381786f2defbd47a8099de Mon Sep 17 00:00:00 2001 From: Brett Rudley Date: Tue, 16 Nov 2010 17:41:15 -0800 Subject: staging: brcm80211: nicpci.c: replace osl based PCI calls with native linux pci calls Get rid of the private PCI access routines and replace with standard calls from linux/pci.h in nicpci.c (The private versions are still used in siutils.c... for now) Signed-off-by: Brett Rudley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/util/nicpci.c | 96 ++++++++++++--------------------- 1 file changed, 33 insertions(+), 63 deletions(-) diff --git a/drivers/staging/brcm80211/util/nicpci.c b/drivers/staging/brcm80211/util/nicpci.c index 8a7b71ee93d3..2127cc903223 100644 --- a/drivers/staging/brcm80211/util/nicpci.c +++ b/drivers/staging/brcm80211/util/nicpci.c @@ -71,35 +71,6 @@ static bool pcicore_pmecap(pcicore_info_t *pi); #define PCIE_ASPM(sih) ((PCIE_PUB(sih)) && (((sih)->buscorerev >= 3) && ((sih)->buscorerev <= 5))) -#define DWORD_ALIGN(x) (x & ~(0x03)) -#define BYTE_POS(x) (x & 0x3) -#define WORD_POS(x) (x & 0x1) - -#define BYTE_SHIFT(x) (8 * BYTE_POS(x)) -#define WORD_SHIFT(x) (16 * WORD_POS(x)) - -#define BYTE_VAL(a, x) ((a >> BYTE_SHIFT(x)) & 0xFF) -#define WORD_VAL(a, x) ((a >> WORD_SHIFT(x)) & 0xFFFF) - -#define read_pci_cfg_byte(a) \ - (BYTE_VAL(OSL_PCI_READ_CONFIG(osh, DWORD_ALIGN(a), 4), a) & 0xff) - -#define read_pci_cfg_word(a) \ - (WORD_VAL(OSL_PCI_READ_CONFIG(osh, DWORD_ALIGN(a), 4), a) & 0xffff) - -#define write_pci_cfg_byte(a, val) do { \ - u32 tmpval; \ - tmpval = (OSL_PCI_READ_CONFIG(osh, DWORD_ALIGN(a), 4) & ~0xFF << BYTE_POS(a)) | \ - val << BYTE_POS(a); \ - OSL_PCI_WRITE_CONFIG(osh, DWORD_ALIGN(a), 4, tmpval); \ - } while (0) - -#define write_pci_cfg_word(a, val) do { \ - u32 tmpval; \ - tmpval = (OSL_PCI_READ_CONFIG(osh, DWORD_ALIGN(a), 4) & ~0xFFFF << WORD_POS(a)) | \ - val << WORD_POS(a); \ - OSL_PCI_WRITE_CONFIG(osh, DWORD_ALIGN(a), 4, tmpval); \ - } while (0) /* delay needed between the mdio control/ mdiodata register data access */ #define PR28829_DELAY() udelay(10) @@ -158,29 +129,29 @@ pcicore_find_pci_capability(struct osl_info *osh, u8 req_cap_id, u8 byte_val; /* check for Header type 0 */ - byte_val = read_pci_cfg_byte(PCI_CFG_HDR); + pci_read_config_byte(osh->pdev, PCI_CFG_HDR, &byte_val); if ((byte_val & 0x7f) != PCI_HEADER_NORMAL) goto end; /* check if the capability pointer field exists */ - byte_val = read_pci_cfg_byte(PCI_CFG_STAT); + pci_read_config_byte(osh->pdev, PCI_CFG_STAT, &byte_val); if (!(byte_val & PCI_CAPPTR_PRESENT)) goto end; - cap_ptr = read_pci_cfg_byte(PCI_CFG_CAPPTR); + pci_read_config_byte(osh->pdev, PCI_CFG_CAPPTR, &cap_ptr); /* check if the capability pointer is 0x00 */ if (cap_ptr == 0x00) goto end; /* loop thr'u the capability list and see if the pcie capabilty exists */ - cap_id = read_pci_cfg_byte(cap_ptr); + pci_read_config_byte(osh->pdev, cap_ptr, &cap_id); while (cap_id != req_cap_id) { - cap_ptr = read_pci_cfg_byte((cap_ptr + 1)); + pci_read_config_byte(osh->pdev, cap_ptr + 1, &cap_ptr); if (cap_ptr == 0x00) break; - cap_id = read_pci_cfg_byte(cap_ptr); + pci_read_config_byte(osh->pdev, cap_ptr, &cap_id); } if (cap_id != req_cap_id) { goto end; @@ -199,7 +170,7 @@ pcicore_find_pci_capability(struct osl_info *osh, u8 req_cap_id, bufsize = SZPCR - cap_data; *buflen = bufsize; while (bufsize--) { - *buf = read_pci_cfg_byte(cap_data); + pci_read_config_byte(osh->pdev, cap_data, buf); cap_data++; buf++; } @@ -374,15 +345,15 @@ u8 pcie_clkreq(void *pch, u32 mask, u32 val) if (!offset) return 0; - reg_val = OSL_PCI_READ_CONFIG(pi->osh, offset, sizeof(u32)); + pci_read_config_dword(pi->osh->pdev, offset, ®_val); /* set operation */ if (mask) { if (val) reg_val |= PCIE_CLKREQ_ENAB; else reg_val &= ~PCIE_CLKREQ_ENAB; - OSL_PCI_WRITE_CONFIG(pi->osh, offset, sizeof(u32), reg_val); - reg_val = OSL_PCI_READ_CONFIG(pi->osh, offset, sizeof(u32)); + pci_write_config_dword(pi->osh->pdev, offset, reg_val); + pci_read_config_dword(pi->osh->pdev, offset, ®_val); } if (reg_val & PCIE_CLKREQ_ENAB) return 1; @@ -503,12 +474,12 @@ static void pcie_war_aspm_clkreq(pcicore_info_t *pi) W_REG(pi->osh, reg16, val16); - w = OSL_PCI_READ_CONFIG(pi->osh, pi->pciecap_lcreg_offset, - sizeof(u32)); + pci_read_config_dword(pi->osh->pdev, pi->pciecap_lcreg_offset, + &w); w &= ~PCIE_ASPM_ENAB; w |= pi->pcie_war_aspm_ovr; - OSL_PCI_WRITE_CONFIG(pi->osh, pi->pciecap_lcreg_offset, - sizeof(u32), w); + pci_write_config_dword(pi->osh->pdev, + pi->pciecap_lcreg_offset, w); } reg16 = &pcieregs->sprom[SRSH_CLKREQ_OFFSET_REV5]; @@ -695,11 +666,9 @@ void pcicore_sleep(void *pch) if (!pi || !PCIE_ASPM(pi->sih)) return; - w = OSL_PCI_READ_CONFIG(pi->osh, pi->pciecap_lcreg_offset, - sizeof(u32)); + pci_read_config_dword(pi->osh->pdev, pi->pciecap_lcreg_offset, &w); w &= ~PCIE_CAP_LCREG_ASPML1; - OSL_PCI_WRITE_CONFIG(pi->osh, pi->pciecap_lcreg_offset, sizeof(u32), - w); + pci_write_config_dword(pi->osh->pdev, pi->pciecap_lcreg_offset, w); pi->pcie_pr42767 = false; } @@ -731,7 +700,7 @@ bool pcicore_pmecap_fast(struct osl_info *osh) if (!cap_ptr) return false; - pmecap = OSL_PCI_READ_CONFIG(osh, cap_ptr, sizeof(u32)); + pci_read_config_dword(osh->pdev, cap_ptr, &pmecap); return (pmecap & PME_CAP_PM_STATES) != 0; } @@ -754,9 +723,8 @@ static bool pcicore_pmecap(pcicore_info_t *pi) pi->pmecap_offset = cap_ptr; - pmecap = - OSL_PCI_READ_CONFIG(pi->osh, pi->pmecap_offset, - sizeof(u32)); + pci_read_config_dword(pi->osh->pdev, pi->pmecap_offset, + &pmecap); /* At least one state can generate PME */ pi->pmecap = (pmecap & PME_CAP_PM_STATES) != 0; @@ -775,11 +743,11 @@ void pcicore_pmeen(void *pch) if (!pcicore_pmecap(pi)) return; - w = OSL_PCI_READ_CONFIG(pi->osh, pi->pmecap_offset + PME_CSR_OFFSET, - sizeof(u32)); + pci_read_config_dword(pi->osh->pdev, pi->pmecap_offset + PME_CSR_OFFSET, + &w); w |= (PME_CSR_PME_EN); - OSL_PCI_WRITE_CONFIG(pi->osh, pi->pmecap_offset + PME_CSR_OFFSET, - sizeof(u32), w); + pci_write_config_dword(pi->osh->pdev, + pi->pmecap_offset + PME_CSR_OFFSET, w); } /* @@ -793,8 +761,8 @@ bool pcicore_pmestat(void *pch) if (!pcicore_pmecap(pi)) return false; - w = OSL_PCI_READ_CONFIG(pi->osh, pi->pmecap_offset + PME_CSR_OFFSET, - sizeof(u32)); + pci_read_config_dword(pi->osh->pdev, pi->pmecap_offset + PME_CSR_OFFSET, + &w); return (w & PME_CSR_PME_STAT) == PME_CSR_PME_STAT; } @@ -809,22 +777,23 @@ void pcicore_pmeclr(void *pch) if (!pcicore_pmecap(pi)) return; - w = OSL_PCI_READ_CONFIG(pi->osh, pi->pmecap_offset + PME_CSR_OFFSET, - sizeof(u32)); + pci_read_config_dword(pi->osh->pdev, pi->pmecap_offset + PME_CSR_OFFSET, + &w); PCI_ERROR(("pcicore_pci_pmeclr PMECSR : 0x%x\n", w)); /* PMESTAT is cleared by writing 1 to it */ w &= ~(PME_CSR_PME_EN); - OSL_PCI_WRITE_CONFIG(pi->osh, pi->pmecap_offset + PME_CSR_OFFSET, - sizeof(u32), w); + pci_write_config_dword(pi->osh->pdev, + pi->pmecap_offset + PME_CSR_OFFSET, w); } u32 pcie_lcreg(void *pch, u32 mask, u32 val) { pcicore_info_t *pi = (pcicore_info_t *) pch; u8 offset; + u32 tmpval; offset = pi->pciecap_lcreg_offset; if (!offset) @@ -832,9 +801,10 @@ u32 pcie_lcreg(void *pch, u32 mask, u32 val) /* set operation */ if (mask) - OSL_PCI_WRITE_CONFIG(pi->osh, offset, sizeof(u32), val); + pci_write_config_dword(pi->osh->pdev, offset, val); - return OSL_PCI_READ_CONFIG(pi->osh, offset, sizeof(u32)); + pci_read_config_dword(pi->osh->pdev, offset, &tmpval); + return tmpval; } u32 -- cgit v1.2.3 From 237a1a1aef91ab654988cb459d783ac0ee09d2ea Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 17 Nov 2010 11:54:35 +0300 Subject: Staging: ft1000-usb: freeing uninitialized pointer GCC complains that if (info->CardReady) is false we kfree() an uninitialized pointer. Signed-off-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ft1000/ft1000-usb/ft1000_chdev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_chdev.c b/drivers/staging/ft1000/ft1000-usb/ft1000_chdev.c index 7b4963326e8c..76cee9e30624 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_chdev.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_chdev.c @@ -650,7 +650,7 @@ static long ft1000_ChIoctl (struct file *File, unsigned int Command, break; case IOCTL_SET_DPRAM_CMD: { - IOCTL_DPRAM_BLK *dpram_data; + IOCTL_DPRAM_BLK *dpram_data = NULL; //IOCTL_DPRAM_COMMAND dpram_command; u16 qtype; u16 msgsz; -- cgit v1.2.3 From 6f5a416216fe2c39171326897e074d417df1082b Mon Sep 17 00:00:00 2001 From: Yong Wang Date: Wed, 17 Nov 2010 22:08:28 +0800 Subject: staging: spectra: move all init logic into nand_pci_probe Currently there are some driver initialization logic that is not part of nand_pci_probe function. This will result in that part of driver initialization code executing even on platforms without the corresponding hardware which is always dangerous. Signed-off-by: Chuanxiao Dong Signed-off-by: Yong Wang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/spectra/ffsport.c | 56 ++++++------ drivers/staging/spectra/ffsport.h | 1 + drivers/staging/spectra/flash.c | 4 +- drivers/staging/spectra/lld_nand.c | 177 ++++++++++++++++++++----------------- 4 files changed, 127 insertions(+), 111 deletions(-) diff --git a/drivers/staging/spectra/ffsport.c b/drivers/staging/spectra/ffsport.c index c7932da03c56..c6b4a2d16850 100644 --- a/drivers/staging/spectra/ffsport.c +++ b/drivers/staging/spectra/ffsport.c @@ -729,34 +729,16 @@ static void create_sysfs_entry(struct device *dev) } */ -static int GLOB_SBD_init(void) +int register_spectra_ftl() { int i; - /* Set debug output level (0~3) here. 3 is most verbose */ - printk(KERN_ALERT "Spectra: %s\n", GLOB_version); - - mutex_init(&spectra_lock); - - GLOB_SBD_majornum = register_blkdev(0, GLOB_SBD_NAME); - if (GLOB_SBD_majornum <= 0) { - printk(KERN_ERR "Unable to get the major %d for Spectra", - GLOB_SBD_majornum); - return -EBUSY; - } - - if (PASS != GLOB_FTL_Flash_Init()) { - printk(KERN_ERR "Spectra: Unable to Initialize Flash Device. " - "Aborting\n"); - goto out_flash_register; - } - /* create_sysfs_entry(&dev->dev); */ if (PASS != GLOB_FTL_IdentifyDevice(&IdentifyDeviceData)) { printk(KERN_ERR "Spectra: Unable to Read Flash Device. " "Aborting\n"); - goto out_flash_register; + return -ENOMEM; } else { nand_dbg_print(NAND_DBG_WARN, "In GLOB_SBD_init: " "Num blocks=%d, pagesperblock=%d, " @@ -775,24 +757,46 @@ static int GLOB_SBD_init(void) } printk(KERN_ALERT "Spectra: block table has been found.\n"); + GLOB_SBD_majornum = register_blkdev(0, GLOB_SBD_NAME); + if (GLOB_SBD_majornum <= 0) { + printk(KERN_ERR "Unable to get the major %d for Spectra", + GLOB_SBD_majornum); + goto out_ftl_flash_register; + } + for (i = 0; i < NUM_DEVICES; i++) if (SBD_setup_device(&nand_device[i], i) == -ENOMEM) - goto out_ftl_flash_register; + goto out_blk_register; nand_dbg_print(NAND_DBG_DEBUG, "Spectra: module loaded with major number %d\n", GLOB_SBD_majornum); - return 0; + return PASS; +out_blk_register: + unregister_blkdev(GLOB_SBD_majornum, GLOB_SBD_NAME); out_ftl_flash_register: GLOB_FTL_Cache_Release(); -out_flash_register: - GLOB_FTL_Flash_Release(); - unregister_blkdev(GLOB_SBD_majornum, GLOB_SBD_NAME); printk(KERN_ERR "Spectra: Module load failed.\n"); - return -ENOMEM; + return FAIL; +} +EXPORT_SYMBOL_GPL(register_spectra_ftl); + +static int GLOB_SBD_init(void) +{ + /* Set debug output level (0~3) here. 3 is most verbose */ + printk(KERN_ALERT "Spectra: %s\n", GLOB_version); + + mutex_init(&spectra_lock); + + if (PASS != GLOB_FTL_Flash_Init()) { + printk(KERN_ERR "Spectra: Unable to Initialize Flash Device. " + "Aborting\n"); + return -ENODEV; + } + return 0; } static void __exit GLOB_SBD_exit(void) diff --git a/drivers/staging/spectra/ffsport.h b/drivers/staging/spectra/ffsport.h index 6c5d90c53430..85c0750612f6 100644 --- a/drivers/staging/spectra/ffsport.h +++ b/drivers/staging/spectra/ffsport.h @@ -80,5 +80,6 @@ extern int nand_debug_level; extern int GLOB_Calc_Used_Bits(u32 n); extern u64 GLOB_u64_Div(u64 addr, u32 divisor); extern u64 GLOB_u64_Remainder(u64 addr, u32 divisor_type); +extern int register_spectra_ftl(void); #endif /* _FFSPORT_ */ diff --git a/drivers/staging/spectra/flash.c b/drivers/staging/spectra/flash.c index 4e6e451cd5c8..fb39c8ecf596 100644 --- a/drivers/staging/spectra/flash.c +++ b/drivers/staging/spectra/flash.c @@ -1258,9 +1258,7 @@ int GLOB_FTL_Flash_Init(void) g_SBDCmdIndex = 0; - GLOB_LLD_Flash_Init(); - - status = GLOB_LLD_Read_Device_ID(); + status = GLOB_LLD_Flash_Init(); return status; } diff --git a/drivers/staging/spectra/lld_nand.c b/drivers/staging/spectra/lld_nand.c index 0d647a8fd2b6..2263d3ea5456 100644 --- a/drivers/staging/spectra/lld_nand.c +++ b/drivers/staging/spectra/lld_nand.c @@ -2395,14 +2395,94 @@ static int nand_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) unsigned long csr_base; unsigned long csr_len; struct mrst_nand_info *pndev = &info; + u32 int_mask; nand_dbg_print(NAND_DBG_WARN, "%s, Line %d, Function: %s\n", __FILE__, __LINE__, __func__); + FlashReg = ioremap_nocache(GLOB_HWCTL_REG_BASE, + GLOB_HWCTL_REG_SIZE); + if (!FlashReg) { + printk(KERN_ERR "Spectra: ioremap_nocache failed!"); + return -ENOMEM; + } + nand_dbg_print(NAND_DBG_WARN, + "Spectra: Remapped reg base address: " + "0x%p, len: %d\n", + FlashReg, GLOB_HWCTL_REG_SIZE); + + FlashMem = ioremap_nocache(GLOB_HWCTL_MEM_BASE, + GLOB_HWCTL_MEM_SIZE); + if (!FlashMem) { + printk(KERN_ERR "Spectra: ioremap_nocache failed!"); + iounmap(FlashReg); + return -ENOMEM; + } + nand_dbg_print(NAND_DBG_WARN, + "Spectra: Remapped flash base address: " + "0x%p, len: %d\n", + (void *)FlashMem, GLOB_HWCTL_MEM_SIZE); + + nand_dbg_print(NAND_DBG_DEBUG, "Dump timing register values:" + "acc_clks: %d, re_2_we: %d, we_2_re: %d," + "addr_2_data: %d, rdwr_en_lo_cnt: %d, " + "rdwr_en_hi_cnt: %d, cs_setup_cnt: %d\n", + ioread32(FlashReg + ACC_CLKS), + ioread32(FlashReg + RE_2_WE), + ioread32(FlashReg + WE_2_RE), + ioread32(FlashReg + ADDR_2_DATA), + ioread32(FlashReg + RDWR_EN_LO_CNT), + ioread32(FlashReg + RDWR_EN_HI_CNT), + ioread32(FlashReg + CS_SETUP_CNT)); + + NAND_Flash_Reset(); + + iowrite32(0, FlashReg + GLOBAL_INT_ENABLE); + +#if CMD_DMA + info.pcmds_num = 0; + info.flash_bank = 0; + info.cdma_num = 0; + int_mask = (DMA_INTR__DESC_COMP_CHANNEL0 | + DMA_INTR__DESC_COMP_CHANNEL1 | + DMA_INTR__DESC_COMP_CHANNEL2 | + DMA_INTR__DESC_COMP_CHANNEL3 | + DMA_INTR__MEMCOPY_DESC_COMP); + iowrite32(int_mask, FlashReg + DMA_INTR_EN); + iowrite32(0xFFFF, FlashReg + DMA_INTR); + + int_mask = (INTR_STATUS0__ECC_ERR | + INTR_STATUS0__PROGRAM_FAIL | + INTR_STATUS0__ERASE_FAIL); +#else + int_mask = INTR_STATUS0__DMA_CMD_COMP | + INTR_STATUS0__ECC_TRANSACTION_DONE | + INTR_STATUS0__ECC_ERR | + INTR_STATUS0__PROGRAM_FAIL | + INTR_STATUS0__ERASE_FAIL; +#endif + iowrite32(int_mask, FlashReg + INTR_EN0); + iowrite32(int_mask, FlashReg + INTR_EN1); + iowrite32(int_mask, FlashReg + INTR_EN2); + iowrite32(int_mask, FlashReg + INTR_EN3); + + /* Clear all status bits */ + iowrite32(0xFFFF, FlashReg + INTR_STATUS0); + iowrite32(0xFFFF, FlashReg + INTR_STATUS1); + iowrite32(0xFFFF, FlashReg + INTR_STATUS2); + iowrite32(0xFFFF, FlashReg + INTR_STATUS3); + + iowrite32(0x0F, FlashReg + RB_PIN_ENABLED); + iowrite32(CHIP_EN_DONT_CARE__FLAG, FlashReg + CHIP_ENABLE_DONT_CARE); + + /* Should set value for these registers when init */ + iowrite32(0, FlashReg + TWO_ROW_ADDR_CYCLES); + iowrite32(1, FlashReg + ECC_ENABLE); + enable_ecc = 1; ret = pci_enable_device(dev); if (ret) { printk(KERN_ERR "Spectra: pci_enable_device failed.\n"); - return ret; + goto failed_req_csr; } pci_set_master(dev); @@ -2461,12 +2541,26 @@ static int nand_pci_probe(struct pci_dev *dev, const struct pci_device_id *id) pci_set_drvdata(dev, pndev); + ret = GLOB_LLD_Read_Device_ID(); + if (ret) { + iounmap(pndev->ioaddr); + goto failed_remap_csr; + } + + ret = register_spectra_ftl(); + if (ret) { + iounmap(pndev->ioaddr); + goto failed_remap_csr; + } + return 0; failed_remap_csr: pci_release_regions(dev); failed_req_csr: pci_disable_device(dev); + iounmap(FlashMem); + iounmap(FlashReg); return ret; } @@ -2498,91 +2592,10 @@ static struct pci_driver nand_pci_driver = { int NAND_Flash_Init(void) { int retval; - u32 int_mask; nand_dbg_print(NAND_DBG_TRACE, "%s, Line %d, Function: %s\n", __FILE__, __LINE__, __func__); - FlashReg = ioremap_nocache(GLOB_HWCTL_REG_BASE, - GLOB_HWCTL_REG_SIZE); - if (!FlashReg) { - printk(KERN_ERR "Spectra: ioremap_nocache failed!"); - return -ENOMEM; - } - nand_dbg_print(NAND_DBG_WARN, - "Spectra: Remapped reg base address: " - "0x%p, len: %d\n", - FlashReg, GLOB_HWCTL_REG_SIZE); - - FlashMem = ioremap_nocache(GLOB_HWCTL_MEM_BASE, - GLOB_HWCTL_MEM_SIZE); - if (!FlashMem) { - printk(KERN_ERR "Spectra: ioremap_nocache failed!"); - iounmap(FlashReg); - return -ENOMEM; - } - nand_dbg_print(NAND_DBG_WARN, - "Spectra: Remapped flash base address: " - "0x%p, len: %d\n", - (void *)FlashMem, GLOB_HWCTL_MEM_SIZE); - - nand_dbg_print(NAND_DBG_DEBUG, "Dump timing register values:" - "acc_clks: %d, re_2_we: %d, we_2_re: %d," - "addr_2_data: %d, rdwr_en_lo_cnt: %d, " - "rdwr_en_hi_cnt: %d, cs_setup_cnt: %d\n", - ioread32(FlashReg + ACC_CLKS), - ioread32(FlashReg + RE_2_WE), - ioread32(FlashReg + WE_2_RE), - ioread32(FlashReg + ADDR_2_DATA), - ioread32(FlashReg + RDWR_EN_LO_CNT), - ioread32(FlashReg + RDWR_EN_HI_CNT), - ioread32(FlashReg + CS_SETUP_CNT)); - - NAND_Flash_Reset(); - - iowrite32(0, FlashReg + GLOBAL_INT_ENABLE); - -#if CMD_DMA - info.pcmds_num = 0; - info.flash_bank = 0; - info.cdma_num = 0; - int_mask = (DMA_INTR__DESC_COMP_CHANNEL0 | - DMA_INTR__DESC_COMP_CHANNEL1 | - DMA_INTR__DESC_COMP_CHANNEL2 | - DMA_INTR__DESC_COMP_CHANNEL3 | - DMA_INTR__MEMCOPY_DESC_COMP); - iowrite32(int_mask, FlashReg + DMA_INTR_EN); - iowrite32(0xFFFF, FlashReg + DMA_INTR); - - int_mask = (INTR_STATUS0__ECC_ERR | - INTR_STATUS0__PROGRAM_FAIL | - INTR_STATUS0__ERASE_FAIL); -#else - int_mask = INTR_STATUS0__DMA_CMD_COMP | - INTR_STATUS0__ECC_TRANSACTION_DONE | - INTR_STATUS0__ECC_ERR | - INTR_STATUS0__PROGRAM_FAIL | - INTR_STATUS0__ERASE_FAIL; -#endif - iowrite32(int_mask, FlashReg + INTR_EN0); - iowrite32(int_mask, FlashReg + INTR_EN1); - iowrite32(int_mask, FlashReg + INTR_EN2); - iowrite32(int_mask, FlashReg + INTR_EN3); - - /* Clear all status bits */ - iowrite32(0xFFFF, FlashReg + INTR_STATUS0); - iowrite32(0xFFFF, FlashReg + INTR_STATUS1); - iowrite32(0xFFFF, FlashReg + INTR_STATUS2); - iowrite32(0xFFFF, FlashReg + INTR_STATUS3); - - iowrite32(0x0F, FlashReg + RB_PIN_ENABLED); - iowrite32(CHIP_EN_DONT_CARE__FLAG, FlashReg + CHIP_ENABLE_DONT_CARE); - - /* Should set value for these registers when init */ - iowrite32(0, FlashReg + TWO_ROW_ADDR_CYCLES); - iowrite32(1, FlashReg + ECC_ENABLE); - enable_ecc = 1; - retval = pci_register_driver(&nand_pci_driver); if (retval) return -ENOMEM; -- cgit v1.2.3 From 63fcf10db218a89cbd1e34c47540c3e28706cff1 Mon Sep 17 00:00:00 2001 From: Yong Wang Date: Wed, 17 Nov 2010 22:09:54 +0800 Subject: staging: spectra: asynchronous init The spectra nand driver takes quite some time to initialize because it needs to scan the whole nand disk to find the latest block table. This patch initializes the spectra nand driver asynchronously so that other things in the kernel can initialize in parallel to the scanning operation. Signed-off-by: Yong Wang Signed-off-by: Greg Kroah-Hartman --- drivers/staging/spectra/ffsport.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/drivers/staging/spectra/ffsport.c b/drivers/staging/spectra/ffsport.c index c6b4a2d16850..c3849e9b66d3 100644 --- a/drivers/staging/spectra/ffsport.c +++ b/drivers/staging/spectra/ffsport.c @@ -28,6 +28,7 @@ #include #include #include +#include /**** Helper functions used for Div, Remainder operation on u64 ****/ @@ -729,7 +730,7 @@ static void create_sysfs_entry(struct device *dev) } */ -int register_spectra_ftl() +static void register_spectra_ftl_async(void *unused, async_cookie_t cookie) { int i; @@ -738,7 +739,7 @@ int register_spectra_ftl() if (PASS != GLOB_FTL_IdentifyDevice(&IdentifyDeviceData)) { printk(KERN_ERR "Spectra: Unable to Read Flash Device. " "Aborting\n"); - return -ENOMEM; + return; } else { nand_dbg_print(NAND_DBG_WARN, "In GLOB_SBD_init: " "Num blocks=%d, pagesperblock=%d, " @@ -772,15 +773,19 @@ int register_spectra_ftl() "Spectra: module loaded with major number %d\n", GLOB_SBD_majornum); - return PASS; + return; out_blk_register: unregister_blkdev(GLOB_SBD_majornum, GLOB_SBD_NAME); out_ftl_flash_register: GLOB_FTL_Cache_Release(); printk(KERN_ERR "Spectra: Module load failed.\n"); +} - return FAIL; +int register_spectra_ftl() +{ + async_schedule(register_spectra_ftl_async, NULL); + return 0; } EXPORT_SYMBOL_GPL(register_spectra_ftl); -- cgit v1.2.3 From 24aee93c37fe7fa2aa2381d3017be478e9c55c47 Mon Sep 17 00:00:00 2001 From: Vinod Koul Date: Wed, 17 Nov 2010 15:57:57 +0000 Subject: sst: remove rest of aava bits and aava related code This removes the remaining bit of aava dependent and related bits from driver Signed-off-by: Vinod Koul Signed-off-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/staging/intel_sst/intelmid.h | 5 --- drivers/staging/intel_sst/intelmid_v1_control.c | 50 ------------------------- drivers/staging/intel_sst/intelmid_v2_control.c | 2 +- 3 files changed, 1 insertion(+), 56 deletions(-) diff --git a/drivers/staging/intel_sst/intelmid.h b/drivers/staging/intel_sst/intelmid.h index 81e744816765..0ce103185848 100644 --- a/drivers/staging/intel_sst/intelmid.h +++ b/drivers/staging/intel_sst/intelmid.h @@ -178,9 +178,4 @@ extern struct snd_kcontrol_new snd_intelmad_controls_mrst[]; extern struct snd_kcontrol_new snd_intelmad_controls_mfld[]; extern struct snd_pmic_ops *intelmad_vendor_ops[]; -/* This is an enabler hook as the platform detection logic isn't yet - present and depends on some firmware and DMI support to detect AAVA - devices. It will vanish once the AAVA platform support is merged */ -#define is_aava() 0 - #endif /* __INTELMID_H */ diff --git a/drivers/staging/intel_sst/intelmid_v1_control.c b/drivers/staging/intel_sst/intelmid_v1_control.c index 62a932bf809a..478cfecdefd7 100644 --- a/drivers/staging/intel_sst/intelmid_v1_control.c +++ b/drivers/staging/intel_sst/intelmid_v1_control.c @@ -134,56 +134,6 @@ static int mx_init_card(void) return sst_sc_reg_access(sc_access, PMIC_WRITE, 47); } -static int mx_init_capture_card(void) -{ - struct sc_reg_access sc_access[] = { - {0x206, 0x5a, 0x0}, - {0x207, 0xbe, 0x0}, - {0x208, 0x90, 0x0}, - {0x209, 0x32, 0x0}, - {0x20e, 0x22, 0x0}, - {0x210, 0x84, 0x0}, - {0x223, 0x20, 0x0}, - {0x226, 0xC0, 0x0}, - }; - - int retval = 0; - - retval = sst_sc_reg_access(sc_access, PMIC_WRITE, 8); - if (0 != retval) { - /* pmic communication fails */ - pr_debug("pmic commn failed\n"); - return retval; - } - - pr_debug("Capture configuration complete!!\n"); - return 0; -} - -static int mx_init_playback_card(void) -{ - struct sc_reg_access sc_access[] = { - {0x206, 0x00, 0x0}, - {0x207, 0x00, 0x0}, - {0x208, 0x00, 0x0}, - {0x209, 0x51, 0x0}, - {0x20e, 0x51, 0x0}, - {0x210, 0x21, 0x0}, - {0x223, 0x01, 0x0}, - }; - int retval = 0; - - retval = sst_sc_reg_access(sc_access, PMIC_WRITE, 9); - if (0 != retval) { - /* pmic communication fails */ - pr_debug("pmic commn failed\n"); - return retval; - } - - pr_debug("Playback configuration complete!!\n"); - return 0; -} - static int mx_enable_audiodac(int value) { struct sc_reg_access sc_access[3]; diff --git a/drivers/staging/intel_sst/intelmid_v2_control.c b/drivers/staging/intel_sst/intelmid_v2_control.c index 81cb9d70870b..e38e89df6e84 100644 --- a/drivers/staging/intel_sst/intelmid_v2_control.c +++ b/drivers/staging/intel_sst/intelmid_v2_control.c @@ -873,7 +873,7 @@ static int nc_set_selected_input_dev(u8 value) sc_access[2].mask = MASK6; sc_access[3].reg_addr = 0x109; sc_access[3].mask = MASK6; - sc_access[3].value = 0x40; + sc_access[3].value = 0x00; num_val = 4; break; default: -- cgit v1.2.3 From 6b6e39a6a8da7234c538d14c43d3583da8875f9c Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Mon, 15 Nov 2010 23:13:18 +0100 Subject: driver-core: merge private parts of class and bus As classes and busses are pretty much the same thing, and we want to merge them together into a 'subsystem' in the future, let us share the same private data parts to make that merge easier. Signed-off-by: Kay Sievers Signed-off-by: Greg Kroah-Hartman --- drivers/base/base.h | 62 ++++++++++++++++++++------------------------------ drivers/base/bus.c | 13 +++++------ drivers/base/class.c | 38 +++++++++++++++---------------- drivers/base/core.c | 22 +++++++++--------- include/linux/device.h | 7 +++--- 5 files changed, 64 insertions(+), 78 deletions(-) diff --git a/drivers/base/base.h b/drivers/base/base.h index 2ca7f5b7b824..19f49e41ce5d 100644 --- a/drivers/base/base.h +++ b/drivers/base/base.h @@ -1,31 +1,46 @@ /** - * struct bus_type_private - structure to hold the private to the driver core portions of the bus_type structure. + * struct subsys_private - structure to hold the private to the driver core portions of the bus_type/class structure. * - * @subsys - the struct kset that defines this bus. This is the main kobject - * @drivers_kset - the list of drivers associated with this bus - * @devices_kset - the list of devices associated with this bus + * @subsys - the struct kset that defines this subsystem + * @devices_kset - the list of devices associated + * + * @drivers_kset - the list of drivers associated * @klist_devices - the klist to iterate over the @devices_kset * @klist_drivers - the klist to iterate over the @drivers_kset * @bus_notifier - the bus notifier list for anything that cares about things - * on this bus. + * on this bus. * @bus - pointer back to the struct bus_type that this structure is associated - * with. + * with. + * + * @class_interfaces - list of class_interfaces associated + * @glue_dirs - "glue" directory to put in-between the parent device to + * avoid namespace conflicts + * @class_mutex - mutex to protect the children, devices, and interfaces lists. + * @class - pointer back to the struct class that this structure is associated + * with. * * This structure is the one that is the actual kobject allowing struct - * bus_type to be statically allocated safely. Nothing outside of the driver - * core should ever touch these fields. + * bus_type/class to be statically allocated safely. Nothing outside of the + * driver core should ever touch these fields. */ -struct bus_type_private { +struct subsys_private { struct kset subsys; - struct kset *drivers_kset; struct kset *devices_kset; + + struct kset *drivers_kset; struct klist klist_devices; struct klist klist_drivers; struct blocking_notifier_head bus_notifier; unsigned int drivers_autoprobe:1; struct bus_type *bus; + + struct list_head class_interfaces; + struct kset glue_dirs; + struct mutex class_mutex; + struct class *class; }; +#define to_subsys_private(obj) container_of(obj, struct subsys_private, subsys.kobj) struct driver_private { struct kobject kobj; @@ -36,33 +51,6 @@ struct driver_private { }; #define to_driver(obj) container_of(obj, struct driver_private, kobj) - -/** - * struct class_private - structure to hold the private to the driver core portions of the class structure. - * - * @class_subsys - the struct kset that defines this class. This is the main kobject - * @class_devices - list of devices associated with this class - * @class_interfaces - list of class_interfaces associated with this class - * @class_dirs - "glue" directory for virtual devices associated with this class - * @class_mutex - mutex to protect the children, devices, and interfaces lists. - * @class - pointer back to the struct class that this structure is associated - * with. - * - * This structure is the one that is the actual kobject allowing struct - * class to be statically allocated safely. Nothing outside of the driver - * core should ever touch these fields. - */ -struct class_private { - struct kset class_subsys; - struct klist class_devices; - struct list_head class_interfaces; - struct kset class_dirs; - struct mutex class_mutex; - struct class *class; -}; -#define to_class(obj) \ - container_of(obj, struct class_private, class_subsys.kobj) - /** * struct device_private - structure to hold the private to the driver core portions of the device structure. * diff --git a/drivers/base/bus.c b/drivers/base/bus.c index 33c270a64db7..e243bd49764b 100644 --- a/drivers/base/bus.c +++ b/drivers/base/bus.c @@ -20,7 +20,6 @@ #include "power/power.h" #define to_bus_attr(_attr) container_of(_attr, struct bus_attribute, attr) -#define to_bus(obj) container_of(obj, struct bus_type_private, subsys.kobj) /* * sysfs bindings for drivers @@ -96,11 +95,11 @@ static ssize_t bus_attr_show(struct kobject *kobj, struct attribute *attr, char *buf) { struct bus_attribute *bus_attr = to_bus_attr(attr); - struct bus_type_private *bus_priv = to_bus(kobj); + struct subsys_private *subsys_priv = to_subsys_private(kobj); ssize_t ret = 0; if (bus_attr->show) - ret = bus_attr->show(bus_priv->bus, buf); + ret = bus_attr->show(subsys_priv->bus, buf); return ret; } @@ -108,11 +107,11 @@ static ssize_t bus_attr_store(struct kobject *kobj, struct attribute *attr, const char *buf, size_t count) { struct bus_attribute *bus_attr = to_bus_attr(attr); - struct bus_type_private *bus_priv = to_bus(kobj); + struct subsys_private *subsys_priv = to_subsys_private(kobj); ssize_t ret = 0; if (bus_attr->store) - ret = bus_attr->store(bus_priv->bus, buf, count); + ret = bus_attr->store(subsys_priv->bus, buf, count); return ret; } @@ -858,9 +857,9 @@ static BUS_ATTR(uevent, S_IWUSR, NULL, bus_uevent_store); int bus_register(struct bus_type *bus) { int retval; - struct bus_type_private *priv; + struct subsys_private *priv; - priv = kzalloc(sizeof(struct bus_type_private), GFP_KERNEL); + priv = kzalloc(sizeof(struct subsys_private), GFP_KERNEL); if (!priv) return -ENOMEM; diff --git a/drivers/base/class.c b/drivers/base/class.c index 7975a52bdf5b..4f1df2e8fd74 100644 --- a/drivers/base/class.c +++ b/drivers/base/class.c @@ -27,7 +27,7 @@ static ssize_t class_attr_show(struct kobject *kobj, struct attribute *attr, char *buf) { struct class_attribute *class_attr = to_class_attr(attr); - struct class_private *cp = to_class(kobj); + struct subsys_private *cp = to_subsys_private(kobj); ssize_t ret = -EIO; if (class_attr->show) @@ -39,7 +39,7 @@ static ssize_t class_attr_store(struct kobject *kobj, struct attribute *attr, const char *buf, size_t count) { struct class_attribute *class_attr = to_class_attr(attr); - struct class_private *cp = to_class(kobj); + struct subsys_private *cp = to_subsys_private(kobj); ssize_t ret = -EIO; if (class_attr->store) @@ -49,7 +49,7 @@ static ssize_t class_attr_store(struct kobject *kobj, struct attribute *attr, static void class_release(struct kobject *kobj) { - struct class_private *cp = to_class(kobj); + struct subsys_private *cp = to_subsys_private(kobj); struct class *class = cp->class; pr_debug("class '%s': release.\n", class->name); @@ -65,7 +65,7 @@ static void class_release(struct kobject *kobj) static const struct kobj_ns_type_operations *class_child_ns_type(struct kobject *kobj) { - struct class_private *cp = to_class(kobj); + struct subsys_private *cp = to_subsys_private(kobj); struct class *class = cp->class; return class->ns_type; @@ -82,7 +82,7 @@ static struct kobj_type class_ktype = { .child_ns_type = class_child_ns_type, }; -/* Hotplug events for classes go to the class class_subsys */ +/* Hotplug events for classes go to the class subsys */ static struct kset *class_kset; @@ -90,7 +90,7 @@ int class_create_file(struct class *cls, const struct class_attribute *attr) { int error; if (cls) - error = sysfs_create_file(&cls->p->class_subsys.kobj, + error = sysfs_create_file(&cls->p->subsys.kobj, &attr->attr); else error = -EINVAL; @@ -100,20 +100,20 @@ int class_create_file(struct class *cls, const struct class_attribute *attr) void class_remove_file(struct class *cls, const struct class_attribute *attr) { if (cls) - sysfs_remove_file(&cls->p->class_subsys.kobj, &attr->attr); + sysfs_remove_file(&cls->p->subsys.kobj, &attr->attr); } static struct class *class_get(struct class *cls) { if (cls) - kset_get(&cls->p->class_subsys); + kset_get(&cls->p->subsys); return cls; } static void class_put(struct class *cls) { if (cls) - kset_put(&cls->p->class_subsys); + kset_put(&cls->p->subsys); } static int add_class_attrs(struct class *cls) @@ -162,7 +162,7 @@ static void klist_class_dev_put(struct klist_node *n) int __class_register(struct class *cls, struct lock_class_key *key) { - struct class_private *cp; + struct subsys_private *cp; int error; pr_debug("device class '%s': registering\n", cls->name); @@ -170,11 +170,11 @@ int __class_register(struct class *cls, struct lock_class_key *key) cp = kzalloc(sizeof(*cp), GFP_KERNEL); if (!cp) return -ENOMEM; - klist_init(&cp->class_devices, klist_class_dev_get, klist_class_dev_put); + klist_init(&cp->klist_devices, klist_class_dev_get, klist_class_dev_put); INIT_LIST_HEAD(&cp->class_interfaces); - kset_init(&cp->class_dirs); + kset_init(&cp->glue_dirs); __mutex_init(&cp->class_mutex, "struct class mutex", key); - error = kobject_set_name(&cp->class_subsys.kobj, "%s", cls->name); + error = kobject_set_name(&cp->subsys.kobj, "%s", cls->name); if (error) { kfree(cp); return error; @@ -187,15 +187,15 @@ int __class_register(struct class *cls, struct lock_class_key *key) #if defined(CONFIG_BLOCK) /* let the block class directory show up in the root of sysfs */ if (!sysfs_deprecated || cls != &block_class) - cp->class_subsys.kobj.kset = class_kset; + cp->subsys.kobj.kset = class_kset; #else - cp->class_subsys.kobj.kset = class_kset; + cp->subsys.kobj.kset = class_kset; #endif - cp->class_subsys.kobj.ktype = &class_ktype; + cp->subsys.kobj.ktype = &class_ktype; cp->class = cls; cls->p = cp; - error = kset_register(&cp->class_subsys); + error = kset_register(&cp->subsys); if (error) { kfree(cp); return error; @@ -210,7 +210,7 @@ void class_unregister(struct class *cls) { pr_debug("device class '%s': unregistering\n", cls->name); remove_class_attrs(cls); - kset_unregister(&cls->p->class_subsys); + kset_unregister(&cls->p->subsys); } static void class_create_release(struct class *cls) @@ -295,7 +295,7 @@ void class_dev_iter_init(struct class_dev_iter *iter, struct class *class, if (start) start_knode = &start->knode_class; - klist_iter_init_node(&class->p->class_devices, &iter->ki, start_knode); + klist_iter_init_node(&class->p->klist_devices, &iter->ki, start_knode); iter->type = type; } EXPORT_SYMBOL_GPL(class_dev_iter_init); diff --git a/drivers/base/core.c b/drivers/base/core.c index 6ed645411c40..46ff6c251932 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -610,7 +610,7 @@ class_dir_create_and_add(struct class *class, struct kobject *parent_kobj) dir->class = class; kobject_init(&dir->kobj, &class_dir_ktype); - dir->kobj.kset = &class->p->class_dirs; + dir->kobj.kset = &class->p->glue_dirs; retval = kobject_add(&dir->kobj, parent_kobj, "%s", class->name); if (retval < 0) { @@ -635,7 +635,7 @@ static struct kobject *get_device_parent(struct device *dev, if (sysfs_deprecated && dev->class == &block_class) { if (parent && parent->class == &block_class) return &parent->kobj; - return &block_class.p->class_subsys.kobj; + return &block_class.p->subsys.kobj; } #endif @@ -654,13 +654,13 @@ static struct kobject *get_device_parent(struct device *dev, mutex_lock(&gdp_mutex); /* find our class-directory at the parent and reference it */ - spin_lock(&dev->class->p->class_dirs.list_lock); - list_for_each_entry(k, &dev->class->p->class_dirs.list, entry) + spin_lock(&dev->class->p->glue_dirs.list_lock); + list_for_each_entry(k, &dev->class->p->glue_dirs.list, entry) if (k->parent == parent_kobj) { kobj = kobject_get(k); break; } - spin_unlock(&dev->class->p->class_dirs.list_lock); + spin_unlock(&dev->class->p->glue_dirs.list_lock); if (kobj) { mutex_unlock(&gdp_mutex); return kobj; @@ -682,7 +682,7 @@ static void cleanup_glue_dir(struct device *dev, struct kobject *glue_dir) { /* see if we live in a "glue" directory */ if (!glue_dir || !dev->class || - glue_dir->kset != &dev->class->p->class_dirs) + glue_dir->kset != &dev->class->p->glue_dirs) return; kobject_put(glue_dir); @@ -709,7 +709,7 @@ static int device_add_class_symlinks(struct device *dev) return 0; error = sysfs_create_link(&dev->kobj, - &dev->class->p->class_subsys.kobj, + &dev->class->p->subsys.kobj, "subsystem"); if (error) goto out; @@ -728,7 +728,7 @@ static int device_add_class_symlinks(struct device *dev) #endif /* link in the class directory pointing to the device */ - error = sysfs_create_link(&dev->class->p->class_subsys.kobj, + error = sysfs_create_link(&dev->class->p->subsys.kobj, &dev->kobj, dev_name(dev)); if (error) goto out_device; @@ -756,7 +756,7 @@ static void device_remove_class_symlinks(struct device *dev) if (sysfs_deprecated && dev->class == &block_class) return; #endif - sysfs_delete_link(&dev->class->p->class_subsys.kobj, &dev->kobj, dev_name(dev)); + sysfs_delete_link(&dev->class->p->subsys.kobj, &dev->kobj, dev_name(dev)); } /** @@ -947,7 +947,7 @@ int device_add(struct device *dev) mutex_lock(&dev->class->p->class_mutex); /* tie the class to the device */ klist_add_tail(&dev->knode_class, - &dev->class->p->class_devices); + &dev->class->p->klist_devices); /* notify any interfaces that the device is here */ list_for_each_entry(class_intf, @@ -1535,7 +1535,7 @@ int device_rename(struct device *dev, const char *new_name) } if (dev->class) { - error = sysfs_rename_link(&dev->class->p->class_subsys.kobj, + error = sysfs_rename_link(&dev->class->p->subsys.kobj, &dev->kobj, old_device_name, new_name); if (error) goto out; diff --git a/include/linux/device.h b/include/linux/device.h index dd4895313468..1e2d335ab683 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -30,9 +30,8 @@ struct device_private; struct device_driver; struct driver_private; struct class; -struct class_private; +struct subsys_private; struct bus_type; -struct bus_type_private; struct device_node; struct bus_attribute { @@ -65,7 +64,7 @@ struct bus_type { const struct dev_pm_ops *pm; - struct bus_type_private *p; + struct subsys_private *p; }; extern int __must_check bus_register(struct bus_type *bus); @@ -213,7 +212,7 @@ struct class { const struct dev_pm_ops *pm; - struct class_private *p; + struct subsys_private *p; }; struct class_dev_iter { -- cgit v1.2.3 From d47d612459300510215fc54bf1283f81710745df Mon Sep 17 00:00:00 2001 From: Tracey Dent Date: Thu, 18 Nov 2010 10:42:30 +0100 Subject: HID: Clean up makefile (-y instead of -objs) Changed Makefile to use -y instead of -objs because -objs is deprecated and should now be switched. According to (documentation/kbuild/makefiles.txt). Signed-off-by: Tracey Dent Signed-off-by: Jiri Kosina --- drivers/hid/Makefile | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile index 86192f67d7c2..b406269d1bcb 100644 --- a/drivers/hid/Makefile +++ b/drivers/hid/Makefile @@ -1,7 +1,7 @@ # # Makefile for the HID driver # -hid-objs := hid-core.o hid-input.o +hid-y := hid-core.o hid-input.o ifdef CONFIG_DEBUG_FS hid-objs += hid-debug.o @@ -11,18 +11,18 @@ obj-$(CONFIG_HID) += hid.o hid-$(CONFIG_HIDRAW) += hidraw.o -hid-logitech-objs := hid-lg.o +hid-logitech-y := hid-lg.o ifdef CONFIG_LOGITECH_FF - hid-logitech-objs += hid-lgff.o + hid-logitech-y += hid-lgff.o endif ifdef CONFIG_LOGIRUMBLEPAD2_FF - hid-logitech-objs += hid-lg2ff.o + hid-logitech-y += hid-lg2ff.o endif ifdef CONFIG_LOGIG940_FF - hid-logitech-objs += hid-lg3ff.o + hid-logitech-y += hid-lg3ff.o endif ifdef CONFIG_LOGIWII_FF - hid-logitech-objs += hid-lg4ff.o + hid-logitech-y += hid-lg4ff.o endif obj-$(CONFIG_HID_3M_PCT) += hid-3m-pct.o -- cgit v1.2.3 From e9229faf920aba47dd1ba6940b3ca138024543d3 Mon Sep 17 00:00:00 2001 From: Tracey Dent Date: Sun, 7 Nov 2010 09:46:28 -0500 Subject: HID: usbhid: Clean up makefile (-y instead of -objs) Changed Makefile to use -y instead of -objs because -objs is deprecated and should now be switched. According to (documentation/kbuild/makefiles.txt). Signed-off-by: Tracey Dent Signed-off-by: Jiri Kosina --- drivers/hid/usbhid/Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/hid/usbhid/Makefile b/drivers/hid/usbhid/Makefile index 1329ecb37a1c..db3cf31c6fa1 100644 --- a/drivers/hid/usbhid/Makefile +++ b/drivers/hid/usbhid/Makefile @@ -3,15 +3,15 @@ # # Multipart objects. -usbhid-objs := hid-core.o hid-quirks.o +usbhid-y := hid-core.o hid-quirks.o # Optional parts of multipart objects. ifeq ($(CONFIG_USB_HIDDEV),y) - usbhid-objs += hiddev.o + usbhid-y += hiddev.o endif ifeq ($(CONFIG_HID_PID),y) - usbhid-objs += hid-pidff.o + usbhid-y += hid-pidff.o endif obj-$(CONFIG_USB_HID) += usbhid.o -- cgit v1.2.3 From 8cb473da3fe634fb30c1e5be8840b00f499103a8 Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Tue, 2 Nov 2010 18:04:04 +0100 Subject: microblaze: Fix initramfs Patch: initramfs: generalize initramfs_data.xxx.S variants (sha1 6ae64e428f74e7bacab898ef9665dda719ea6fde) requires hooks in linker script. Signed-off-by: Michal Simek --- arch/microblaze/kernel/vmlinux.lds.S | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/arch/microblaze/kernel/vmlinux.lds.S b/arch/microblaze/kernel/vmlinux.lds.S index 96a88c31fe48..3451bdec9f05 100644 --- a/arch/microblaze/kernel/vmlinux.lds.S +++ b/arch/microblaze/kernel/vmlinux.lds.S @@ -123,20 +123,10 @@ SECTIONS { __init_end_before_initramfs = .; - .init.ramfs ALIGN(PAGE_SIZE) : AT(ADDR(.init.ramfs) - LOAD_OFFSET) { - __initramfs_start = .; - *(.init.ramfs) - __initramfs_end = .; - . = ALIGN(4); - LONG(0); -/* - * FIXME this can break initramfs for MMU. - * Pad init.ramfs up to page boundary, - * so that __init_end == __bss_start. This will make image.elf - * consistent with the image.bin - */ - /* . = ALIGN(PAGE_SIZE); */ + .init.ramfs : AT(ADDR(.init.ramfs) - LOAD_OFFSET) { + INIT_RAM_FS } + __init_end = .; .bss ALIGN (PAGE_SIZE) : AT(ADDR(.bss) - LOAD_OFFSET) { -- cgit v1.2.3 From 9da6345885e4f33437d74314f9db592da157d65d Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Fri, 22 Oct 2010 15:48:58 +1000 Subject: Revert "microblaze: Simplify syscall rutine" This reverts commit 0e41c90908881a1b8205c66a66becec7d8d4eb4a. Break jffs2 rootfs because the patch removes syscall calling from kernel space. Signed-off-by: Michal Simek --- arch/microblaze/kernel/entry.S | 46 +++++++++++++++++++++++++++++++++++------- 1 file changed, 39 insertions(+), 7 deletions(-) diff --git a/arch/microblaze/kernel/entry.S b/arch/microblaze/kernel/entry.S index 819238b8a429..41c30cdb2704 100644 --- a/arch/microblaze/kernel/entry.S +++ b/arch/microblaze/kernel/entry.S @@ -287,25 +287,44 @@ * are masked. This is nice, means we don't have to CLI before state save */ C_ENTRY(_user_exception): - addi r14, r14, 4 /* return address is 4 byte after call */ swi r1, r0, TOPHYS(PER_CPU(ENTRY_SP)) /* save stack */ + addi r14, r14, 4 /* return address is 4 byte after call */ + + mfs r1, rmsr + nop + andi r1, r1, MSR_UMS + bnei r1, 1f + +/* Kernel-mode state save - kernel execve */ + lwi r1, r0, TOPHYS(PER_CPU(ENTRY_SP)); /* Reload kernel stack-ptr*/ + tophys(r1,r1); + + addik r1, r1, -STATE_SAVE_SIZE; /* Make room on the stack. */ + SAVE_REGS + swi r1, r1, PTO + PT_MODE; /* pt_regs -> kernel mode */ + brid 2f; + nop; /* Fill delay slot */ + +/* User-mode state save. */ +1: lwi r1, r0, TOPHYS(PER_CPU(CURRENT_SAVE)); /* get saved current */ tophys(r1,r1); lwi r1, r1, TS_THREAD_INFO; /* get stack from task_struct */ - /* MS these three instructions can be added to one */ - /* addik r1, r1, THREAD_SIZE; */ - /* tophys(r1,r1); */ - /* addik r1, r1, -STATE_SAVE_SIZE; */ - addik r1, r1, THREAD_SIZE + CONFIG_KERNEL_BASE_ADDR - CONFIG_KERNEL_START - STATE_SAVE_SIZE; +/* calculate kernel stack pointer from task struct 8k */ + addik r1, r1, THREAD_SIZE; + tophys(r1,r1); + + addik r1, r1, -STATE_SAVE_SIZE; /* Make room on the stack. */ SAVE_REGS swi r0, r1, PTO + PT_R3 swi r0, r1, PTO + PT_R4 + swi r0, r1, PTO + PT_MODE; /* Was in user-mode. */ lwi r11, r0, TOPHYS(PER_CPU(ENTRY_SP)); swi r11, r1, PTO+PT_R1; /* Store user SP. */ clear_ums; - lwi CURRENT_TASK, r0, TOPHYS(PER_CPU(CURRENT_SAVE)); +2: lwi CURRENT_TASK, r0, TOPHYS(PER_CPU(CURRENT_SAVE)); /* Save away the syscall number. */ swi r12, r1, PTO+PT_R0; tovirt(r1,r1) @@ -375,6 +394,9 @@ C_ENTRY(ret_from_trap): swi r3, r1, PTO + PT_R3 swi r4, r1, PTO + PT_R4 + lwi r11, r1, PTO + PT_MODE; +/* See if returning to kernel mode, if so, skip resched &c. */ + bnei r11, 2f; /* We're returning to user mode, so check for various conditions that * trigger rescheduling. */ /* FIXME: Restructure all these flag checks. */ @@ -417,6 +439,16 @@ C_ENTRY(ret_from_trap): RESTORE_REGS; addik r1, r1, STATE_SAVE_SIZE /* Clean up stack space. */ lwi r1, r1, PT_R1 - PT_SIZE;/* Restore user stack pointer. */ + bri 6f; + +/* Return to kernel state. */ +2: set_bip; /* Ints masked for state restore */ + VM_OFF; + tophys(r1,r1); + RESTORE_REGS; + addik r1, r1, STATE_SAVE_SIZE /* Clean up stack space. */ + tovirt(r1,r1); +6: TRAP_return: /* Make global symbol for debugging */ rtbd r14, 0; /* Instructions to return from an IRQ */ nop; -- cgit v1.2.3 From 86af95039b69a90db15294eb1f9c147f1df0a8ea Mon Sep 17 00:00:00 2001 From: Sven Neumann Date: Fri, 12 Nov 2010 11:36:22 +0100 Subject: ds2760_battery: Fix calculation of time_to_empty_now A check against division by zero was modified in commit b0525b48. Since this change time_to_empty_now is always reported as zero while the battery is discharging and as a negative value while the battery is charging. This is because current is negative while the battery is discharging. Fix the check introduced by commit b0525b48 so that time_to_empty_now is reported correctly during discharge and as zero while charging. Signed-off-by: Sven Neumann Acked-by: Daniel Mack Cc: stable@kernel.org [2.6.32..2.6.36] Signed-off-by: Anton Vorontsov --- drivers/power/ds2760_battery.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/power/ds2760_battery.c b/drivers/power/ds2760_battery.c index b3c01c16a164..11e1ac508e57 100644 --- a/drivers/power/ds2760_battery.c +++ b/drivers/power/ds2760_battery.c @@ -212,7 +212,7 @@ static int ds2760_battery_read_status(struct ds2760_device_info *di) if (di->rem_capacity > 100) di->rem_capacity = 100; - if (di->current_uA >= 100L) + if (di->current_uA < -100L) di->life_sec = -((di->accum_current_uAh - di->empty_uAh) * 36L) / (di->current_uA / 100L); else -- cgit v1.2.3 From 8ec98fe0b4ffdedce4c1caa9fb3d550f52ad1c6b Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Thu, 11 Nov 2010 19:00:52 +0100 Subject: jz4740-battery: Protect against concurrent battery readings We can not handle more then one ADC request at a time to the battery. The patch adds a mutex around the ADC read code to ensure this. Signed-off-by: Lars-Peter Clausen Cc: stable@kernel.org Signed-off-by: Anton Vorontsov --- drivers/power/jz4740-battery.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/power/jz4740-battery.c b/drivers/power/jz4740-battery.c index a8108a73593e..2bbe04ae13a7 100644 --- a/drivers/power/jz4740-battery.c +++ b/drivers/power/jz4740-battery.c @@ -47,6 +47,8 @@ struct jz_battery { struct power_supply battery; struct delayed_work work; + + struct mutex lock; }; static inline struct jz_battery *psy_to_jz_battery(struct power_supply *psy) @@ -68,6 +70,8 @@ static long jz_battery_read_voltage(struct jz_battery *battery) unsigned long val; long voltage; + mutex_lock(&battery->lock); + INIT_COMPLETION(battery->read_completion); enable_irq(battery->irq); @@ -91,6 +95,8 @@ static long jz_battery_read_voltage(struct jz_battery *battery) battery->cell->disable(battery->pdev); disable_irq(battery->irq); + mutex_unlock(&battery->lock); + return voltage; } @@ -291,6 +297,7 @@ static int __devinit jz_battery_probe(struct platform_device *pdev) jz_battery->pdev = pdev; init_completion(&jz_battery->read_completion); + mutex_init(&jz_battery->lock); INIT_DELAYED_WORK(&jz_battery->work, jz_battery_work); -- cgit v1.2.3 From 5070437cd99511f69ae561f2ab417142a47a85ec Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Thu, 21 Oct 2010 17:55:01 +0200 Subject: power_supply: Add gpio charger driver This patch adds a simple driver for chargers indicating their online status through a GPIO pin. Signed-off-by: Lars-Peter Clausen Signed-off-by: Anton Vorontsov --- drivers/power/Kconfig | 10 ++ drivers/power/Makefile | 1 + drivers/power/gpio-charger.c | 185 +++++++++++++++++++++++++++++++++++++ include/linux/power/gpio-charger.h | 41 ++++++++ 4 files changed, 237 insertions(+) create mode 100644 drivers/power/gpio-charger.c create mode 100644 include/linux/power/gpio-charger.h diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig index 60d83d983a36..32165295cb1b 100644 --- a/drivers/power/Kconfig +++ b/drivers/power/Kconfig @@ -185,4 +185,14 @@ config CHARGER_TWL4030 help Say Y here to enable support for TWL4030 Battery Charge Interface. +config CHARGER_GPIO + tristate "GPIO charger" + depends on GPIOLIB + help + Say Y to include support for chargers which report their online status + through a GPIO pin. + + This driver can be build as a module. If so, the module will be + called gpio-charger. + endif # POWER_SUPPLY diff --git a/drivers/power/Makefile b/drivers/power/Makefile index c75772eb157c..545459f9f356 100644 --- a/drivers/power/Makefile +++ b/drivers/power/Makefile @@ -32,3 +32,4 @@ obj-$(CONFIG_BATTERY_JZ4740) += jz4740-battery.o obj-$(CONFIG_BATTERY_INTEL_MID) += intel_mid_battery.o obj-$(CONFIG_CHARGER_ISP1704) += isp1704_charger.o obj-$(CONFIG_CHARGER_TWL4030) += twl4030_charger.o +obj-$(CONFIG_CHARGER_GPIO) += gpio-charger.o diff --git a/drivers/power/gpio-charger.c b/drivers/power/gpio-charger.c new file mode 100644 index 000000000000..fccbe99b619c --- /dev/null +++ b/drivers/power/gpio-charger.c @@ -0,0 +1,185 @@ +/* + * Copyright (C) 2010, Lars-Peter Clausen + * Driver for chargers which report their online status through a GPIO pin + * + * 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. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +struct gpio_charger { + const struct gpio_charger_platform_data *pdata; + unsigned int irq; + + struct power_supply charger; +}; + +static irqreturn_t gpio_charger_irq(int irq, void *devid) +{ + struct power_supply *charger = devid; + + power_supply_changed(charger); + + return IRQ_HANDLED; +} + +static inline struct gpio_charger *psy_to_gpio_charger(struct power_supply *psy) +{ + return container_of(psy, struct gpio_charger, charger); +} + +static int gpio_charger_get_property(struct power_supply *psy, + enum power_supply_property psp, union power_supply_propval *val) +{ + struct gpio_charger *gpio_charger = psy_to_gpio_charger(psy); + const struct gpio_charger_platform_data *pdata = gpio_charger->pdata; + + switch (psp) { + case POWER_SUPPLY_PROP_ONLINE: + val->intval = gpio_get_value(pdata->gpio); + val->intval ^= pdata->gpio_active_low; + break; + default: + return -EINVAL; + } + + return 0; +} + +static enum power_supply_property gpio_charger_properties[] = { + POWER_SUPPLY_PROP_ONLINE, +}; + +static int __devinit gpio_charger_probe(struct platform_device *pdev) +{ + const struct gpio_charger_platform_data *pdata = pdev->dev.platform_data; + struct gpio_charger *gpio_charger; + struct power_supply *charger; + int ret; + int irq; + + if (!pdata) { + dev_err(&pdev->dev, "No platform data\n"); + return -EINVAL; + } + + if (!gpio_is_valid(pdata->gpio)) { + dev_err(&pdev->dev, "Invalid gpio pin\n"); + return -EINVAL; + } + + gpio_charger = kzalloc(sizeof(*gpio_charger), GFP_KERNEL); + + charger = &gpio_charger->charger; + + charger->name = pdata->name; + charger->type = pdata->type; + charger->properties = gpio_charger_properties; + charger->num_properties = ARRAY_SIZE(gpio_charger_properties); + charger->get_property = gpio_charger_get_property; + charger->supplied_to = pdata->supplied_to; + charger->num_supplicants = pdata->num_supplicants; + + ret = gpio_request(pdata->gpio, dev_name(&pdev->dev)); + if (ret) { + dev_err(&pdev->dev, "Failed to request gpio pin: %d\n", ret); + goto err_free; + } + ret = gpio_direction_input(pdata->gpio); + if (ret) { + dev_err(&pdev->dev, "Failed to set gpio to input: %d\n", ret); + goto err_gpio_free; + } + + irq = gpio_to_irq(pdata->gpio); + if (irq > 0) { + ret = request_irq(irq, gpio_charger_irq, + IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, + dev_name(&pdev->dev), charger); + if (ret) + dev_warn(&pdev->dev, "Failed to request irq: %d\n", ret); + else + gpio_charger->irq = irq; + } + + gpio_charger->pdata = pdata; + + ret = power_supply_register(&pdev->dev, charger); + if (ret < 0) { + dev_err(&pdev->dev, "Failed to register power supply: %d\n", ret); + goto err_irq_free; + } + + platform_set_drvdata(pdev, gpio_charger); + + return 0; + +err_irq_free: + if (gpio_charger->irq) + free_irq(gpio_charger->irq, charger); +err_gpio_free: + gpio_free(pdata->gpio); +err_free: + kfree(gpio_charger); + return ret; +} + +static int __devexit gpio_charger_remove(struct platform_device *pdev) +{ + struct gpio_charger *gpio_charger = platform_get_drvdata(pdev); + + power_supply_unregister(&gpio_charger->charger); + + if (gpio_charger->irq) + free_irq(gpio_charger->irq, &gpio_charger->charger); + gpio_free(gpio_charger->pdata->gpio); + + platform_set_drvdata(pdev, NULL); + kfree(gpio_charger); + + return 0; +} + +static struct platform_driver gpio_charger_driver = { + .probe = gpio_charger_probe, + .remove = __devexit_p(gpio_charger_remove), + .driver = { + .name = "gpio-charger", + .owner = THIS_MODULE, + }, +}; + +static int __init gpio_charger_init(void) +{ + return platform_driver_register(&gpio_charger_driver); +} +module_init(gpio_charger_init); + +static void __exit gpio_charger_exit(void) +{ + platform_driver_unregister(&gpio_charger_driver); +} +module_exit(gpio_charger_exit); + +MODULE_AUTHOR("Lars-Peter Clausen "); +MODULE_DESCRIPTION("Driver for chargers which report their online status through a GPIO"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:gpio-charger"); diff --git a/include/linux/power/gpio-charger.h b/include/linux/power/gpio-charger.h new file mode 100644 index 000000000000..de1dfe09a03d --- /dev/null +++ b/include/linux/power/gpio-charger.h @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2010, Lars-Peter Clausen + * + * 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. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#ifndef __LINUX_POWER_GPIO_CHARGER_H__ +#define __LINUX_POWER_GPIO_CHARGER_H__ + +#include +#include + +/** + * struct gpio_charger_platform_data - platform_data for gpio_charger devices + * @name: Name for the chargers power_supply device + * @type: Type of the charger + * @gpio: GPIO which is used to indicate the chargers status + * @gpio_active_low: Should be set to 1 if the GPIO is active low otherwise 0 + * @supplied_to: Array of battery names to which this chargers supplies power + * @num_supplicants: Number of entries in the supplied_to array + */ +struct gpio_charger_platform_data { + const char *name; + enum power_supply_type type; + + int gpio; + int gpio_active_low; + + char **supplied_to; + size_t num_supplicants; +}; + +#endif -- cgit v1.2.3 From 746d8fb8c6933337c927f40c9ef90dcbddcfd39e Mon Sep 17 00:00:00 2001 From: Ameya Palande Date: Thu, 4 Nov 2010 16:31:46 +0200 Subject: isp1704_charger: Correct length for storing model Model should have room to accommodate the trailing null byte, "isp170[4|7]\0". Signed-off-by: Ameya Palande Acked-by: Heikki Krogerus Signed-off-by: Anton Vorontsov --- drivers/power/isp1704_charger.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/power/isp1704_charger.c b/drivers/power/isp1704_charger.c index 72512185f3e2..87252e13e29c 100644 --- a/drivers/power/isp1704_charger.c +++ b/drivers/power/isp1704_charger.c @@ -59,7 +59,7 @@ struct isp1704_charger { struct notifier_block nb; struct work_struct work; - char model[7]; + char model[8]; unsigned present:1; }; -- cgit v1.2.3 From bac43b20501058ab0728246acce3bb85f2e72648 Mon Sep 17 00:00:00 2001 From: Heikki Krogerus Date: Thu, 4 Nov 2010 16:31:47 +0200 Subject: isp1704_charger: Detect HUB/Host chargers To avoid breaking high speed chirp handshaking with CDP chargers, no more then 500mA should be drawn. To make sure of this, utilizing current_max property. After the device has enumerated, it's safe to draw the maximum 1800mA as defined in the Battery Charging Specification. This can be also used with normal USB connection if the controller sends ENUMERATED notification with the milliamps as data. From now on the online property indicates VBUS, present property if there is a charger and current_max the milliamps possible to draw from VBUS. Signed-off-by: Heikki Krogerus Signed-off-by: Anton Vorontsov --- drivers/power/isp1704_charger.c | 180 +++++++++++++++++++++++++++++++--------- 1 file changed, 142 insertions(+), 38 deletions(-) diff --git a/drivers/power/isp1704_charger.c b/drivers/power/isp1704_charger.c index 87252e13e29c..10c7cc5fb5f9 100644 --- a/drivers/power/isp1704_charger.c +++ b/drivers/power/isp1704_charger.c @@ -59,10 +59,60 @@ struct isp1704_charger { struct notifier_block nb; struct work_struct work; + /* properties */ char model[8]; unsigned present:1; + unsigned online:1; + unsigned current_max; + + /* temp storage variables */ + unsigned long event; + unsigned max_power; }; +/* + * Determine is the charging port DCP (dedicated charger) or CDP (Host/HUB + * chargers). + * + * REVISIT: The method is defined in Battery Charging Specification and is + * applicable to any ULPI transceiver. Nothing isp170x specific here. + */ +static inline int isp1704_charger_type(struct isp1704_charger *isp) +{ + u8 reg; + u8 func_ctrl; + u8 otg_ctrl; + int type = POWER_SUPPLY_TYPE_USB_DCP; + + func_ctrl = otg_io_read(isp->otg, ULPI_FUNC_CTRL); + otg_ctrl = otg_io_read(isp->otg, ULPI_OTG_CTRL); + + /* disable pulldowns */ + reg = ULPI_OTG_CTRL_DM_PULLDOWN | ULPI_OTG_CTRL_DP_PULLDOWN; + otg_io_write(isp->otg, ULPI_CLR(ULPI_OTG_CTRL), reg); + + /* full speed */ + otg_io_write(isp->otg, ULPI_CLR(ULPI_FUNC_CTRL), + ULPI_FUNC_CTRL_XCVRSEL_MASK); + otg_io_write(isp->otg, ULPI_SET(ULPI_FUNC_CTRL), + ULPI_FUNC_CTRL_FULL_SPEED); + + /* Enable strong pull-up on DP (1.5K) and reset */ + reg = ULPI_FUNC_CTRL_TERMSELECT | ULPI_FUNC_CTRL_RESET; + otg_io_write(isp->otg, ULPI_SET(ULPI_FUNC_CTRL), reg); + usleep_range(1000, 2000); + + reg = otg_io_read(isp->otg, ULPI_DEBUG); + if ((reg & 3) != 3) + type = POWER_SUPPLY_TYPE_USB_CDP; + + /* recover original state */ + otg_io_write(isp->otg, ULPI_FUNC_CTRL, func_ctrl); + otg_io_write(isp->otg, ULPI_OTG_CTRL, otg_ctrl); + + return type; +} + /* * ISP1704 detects PS/2 adapters as charger. To make sure the detected charger * is actually a dedicated charger, the following steps need to be taken. @@ -127,16 +177,19 @@ static inline int isp1704_charger_verify(struct isp1704_charger *isp) static inline int isp1704_charger_detect(struct isp1704_charger *isp) { unsigned long timeout; - u8 r; + u8 pwr_ctrl; int ret = 0; + pwr_ctrl = otg_io_read(isp->otg, ISP1704_PWR_CTRL); + /* set SW control bit in PWR_CTRL register */ otg_io_write(isp->otg, ISP1704_PWR_CTRL, ISP1704_PWR_CTRL_SWCTRL); /* enable manual charger detection */ - r = (ISP1704_PWR_CTRL_SWCTRL | ISP1704_PWR_CTRL_DPVSRC_EN); - otg_io_write(isp->otg, ULPI_SET(ISP1704_PWR_CTRL), r); + otg_io_write(isp->otg, ULPI_SET(ISP1704_PWR_CTRL), + ISP1704_PWR_CTRL_SWCTRL + | ISP1704_PWR_CTRL_DPVSRC_EN); usleep_range(1000, 2000); timeout = jiffies + msecs_to_jiffies(300); @@ -147,7 +200,10 @@ static inline int isp1704_charger_detect(struct isp1704_charger *isp) ret = isp1704_charger_verify(isp); break; } - } while (!time_after(jiffies, timeout)); + } while (!time_after(jiffies, timeout) && isp->online); + + /* recover original state */ + otg_io_write(isp->otg, ISP1704_PWR_CTRL, pwr_ctrl); return ret; } @@ -155,53 +211,93 @@ static inline int isp1704_charger_detect(struct isp1704_charger *isp) static void isp1704_charger_work(struct work_struct *data) { int detect; + unsigned long event; + unsigned power; struct isp1704_charger *isp = container_of(data, struct isp1704_charger, work); + static DEFINE_MUTEX(lock); - /* - * FIXME Only supporting dedicated chargers even though isp1704 can - * detect HUB and HOST chargers. If the device has already been - * enumerated, the detection will break the connection. - */ - if (isp->otg->state != OTG_STATE_B_IDLE) - return; - - /* disable data pullups */ - if (isp->otg->gadget) - usb_gadget_disconnect(isp->otg->gadget); - - /* detect charger */ - detect = isp1704_charger_detect(isp); - if (detect) { - isp->present = detect; - power_supply_changed(&isp->psy); - } + event = isp->event; + power = isp->max_power; - /* enable data pullups */ - if (isp->otg->gadget) - usb_gadget_connect(isp->otg->gadget); -} - -static int isp1704_notifier_call(struct notifier_block *nb, - unsigned long event, void *unused) -{ - struct isp1704_charger *isp = - container_of(nb, struct isp1704_charger, nb); + mutex_lock(&lock); switch (event) { case USB_EVENT_VBUS: - schedule_work(&isp->work); + isp->online = true; + + /* detect charger */ + detect = isp1704_charger_detect(isp); + + if (detect) { + isp->present = detect; + isp->psy.type = isp1704_charger_type(isp); + } + + switch (isp->psy.type) { + case POWER_SUPPLY_TYPE_USB_DCP: + isp->current_max = 1800; + break; + case POWER_SUPPLY_TYPE_USB_CDP: + /* + * Only 500mA here or high speed chirp + * handshaking may break + */ + isp->current_max = 500; + /* FALLTHROUGH */ + case POWER_SUPPLY_TYPE_USB: + default: + /* enable data pullups */ + if (isp->otg->gadget) + usb_gadget_connect(isp->otg->gadget); + } break; case USB_EVENT_NONE: - if (isp->present) { - isp->present = 0; - power_supply_changed(&isp->psy); - } + isp->online = false; + isp->current_max = 0; + isp->present = 0; + isp->current_max = 0; + isp->psy.type = POWER_SUPPLY_TYPE_USB; + + /* + * Disable data pullups. We need to prevent the controller from + * enumerating. + * + * FIXME: This is here to allow charger detection with Host/HUB + * chargers. The pullups may be enabled elsewhere, so this can + * not be the final solution. + */ + if (isp->otg->gadget) + usb_gadget_disconnect(isp->otg->gadget); + break; + case USB_EVENT_ENUMERATED: + if (isp->present) + isp->current_max = 1800; + else + isp->current_max = power; break; default: - return NOTIFY_DONE; + goto out; } + power_supply_changed(&isp->psy); +out: + mutex_unlock(&lock); +} + +static int isp1704_notifier_call(struct notifier_block *nb, + unsigned long event, void *power) +{ + struct isp1704_charger *isp = + container_of(nb, struct isp1704_charger, nb); + + isp->event = event; + + if (power) + isp->max_power = *((unsigned *)power); + + schedule_work(&isp->work); + return NOTIFY_OK; } @@ -216,6 +312,12 @@ static int isp1704_charger_get_property(struct power_supply *psy, case POWER_SUPPLY_PROP_PRESENT: val->intval = isp->present; break; + case POWER_SUPPLY_PROP_ONLINE: + val->intval = isp->online; + break; + case POWER_SUPPLY_PROP_CURRENT_MAX: + val->intval = isp->current_max; + break; case POWER_SUPPLY_PROP_MODEL_NAME: val->strval = isp->model; break; @@ -230,6 +332,8 @@ static int isp1704_charger_get_property(struct power_supply *psy, static enum power_supply_property power_props[] = { POWER_SUPPLY_PROP_PRESENT, + POWER_SUPPLY_PROP_ONLINE, + POWER_SUPPLY_PROP_CURRENT_MAX, POWER_SUPPLY_PROP_MODEL_NAME, POWER_SUPPLY_PROP_MANUFACTURER, }; -- cgit v1.2.3 From a4607d9f5cbae1aad7f86e8204b57d66c0e14e36 Mon Sep 17 00:00:00 2001 From: Heikki Krogerus Date: Thu, 4 Nov 2010 16:31:48 +0200 Subject: isp1704_charger: Set isp->dev before anything needs it isp1704_test_ulpi() is the first place that needs isp->dev member, so it must be set before calling the function. Signed-off-by: Heikki Krogerus Signed-off-by: Anton Vorontsov --- drivers/power/isp1704_charger.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/power/isp1704_charger.c b/drivers/power/isp1704_charger.c index 10c7cc5fb5f9..77c11f1d72e2 100644 --- a/drivers/power/isp1704_charger.c +++ b/drivers/power/isp1704_charger.c @@ -391,13 +391,13 @@ static int __devinit isp1704_charger_probe(struct platform_device *pdev) if (!isp->otg) goto fail0; + isp->dev = &pdev->dev; + platform_set_drvdata(pdev, isp); + ret = isp1704_test_ulpi(isp); if (ret < 0) goto fail1; - isp->dev = &pdev->dev; - platform_set_drvdata(pdev, isp); - isp->psy.name = "isp1704"; isp->psy.type = POWER_SUPPLY_TYPE_USB; isp->psy.properties = power_props; -- cgit v1.2.3 From e1a85694e08d03efae9e08fdb292dfd4870837bc Mon Sep 17 00:00:00 2001 From: Heikki Krogerus Date: Mon, 8 Nov 2010 12:22:40 +0200 Subject: isp1704_charger: Detect charger after probe If the device is booted up with cable connected, or the module is loaded after plugging in the cable, the notification has come and gone, so not relying on it at probe time. Instead this checks the VBUS level manually after probe. Signed-off-by: Heikki Krogerus Signed-off-by: Anton Vorontsov --- drivers/power/isp1704_charger.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/drivers/power/isp1704_charger.c b/drivers/power/isp1704_charger.c index 77c11f1d72e2..2ad9b14a5ce3 100644 --- a/drivers/power/isp1704_charger.c +++ b/drivers/power/isp1704_charger.c @@ -422,6 +422,23 @@ static int __devinit isp1704_charger_probe(struct platform_device *pdev) dev_info(isp->dev, "registered with product id %s\n", isp->model); + /* + * Taking over the D+ pullup. + * + * FIXME: The device will be disconnected if it was already + * enumerated. The charger driver should be always loaded before any + * gadget is loaded. + */ + if (isp->otg->gadget) + usb_gadget_disconnect(isp->otg->gadget); + + /* Detect charger if VBUS is valid (the cable was already plugged). */ + ret = otg_io_read(isp->otg, ULPI_USB_INT_STS); + if ((ret & ULPI_INT_VBUS_VALID) && !isp->otg->default_a) { + isp->event = USB_EVENT_VBUS; + schedule_work(&isp->work); + } + return 0; fail2: power_supply_unregister(&isp->psy); -- cgit v1.2.3 From 8477cedb49c69ce64b603d76c7776811eec0f9d7 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Thu, 11 Nov 2010 19:00:53 +0100 Subject: jz4740-battery: Check if platform_data is supplied Currently platform_data is dereferenced without checking whether it is actually set, which can lead to kernel crashes. This patch adds a check which will abort the drivers probe function gracefully if no platform_data is supplied. Signed-off-by: Lars-Peter Clausen Signed-off-by: Anton Vorontsov --- drivers/power/jz4740-battery.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/power/jz4740-battery.c b/drivers/power/jz4740-battery.c index 2bbe04ae13a7..5b4821593201 100644 --- a/drivers/power/jz4740-battery.c +++ b/drivers/power/jz4740-battery.c @@ -246,6 +246,11 @@ static int __devinit jz_battery_probe(struct platform_device *pdev) struct jz_battery *jz_battery; struct power_supply *battery; + if (!pdata) { + dev_err(&pdev->dev, "No platform_data supplied\n"); + return -ENXIO; + } + jz_battery = kzalloc(sizeof(*jz_battery), GFP_KERNEL); if (!jz_battery) { dev_err(&pdev->dev, "Failed to allocate driver structure\n"); -- cgit v1.2.3 From c311598b29f09c5092747a2603700f96a7daec2a Mon Sep 17 00:00:00 2001 From: Jiri Kosina Date: Thu, 18 Nov 2010 16:27:07 +0100 Subject: HID: prodikeys: make sysfs permissions more strict It's not really dangerous in this driver, but it's against general practice and worth fixing. Proper place for handling this correctly is udev. Reported-by: Linus Torvalds Signed-off-by: Jiri Kosina --- drivers/hid/hid-prodikeys.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/hid/hid-prodikeys.c b/drivers/hid/hid-prodikeys.c index 48eab84f53b5..5f0fa6c1bf87 100644 --- a/drivers/hid/hid-prodikeys.c +++ b/drivers/hid/hid-prodikeys.c @@ -130,7 +130,7 @@ static ssize_t store_channel(struct device *dev, return -EINVAL; } -static DEVICE_ATTR(channel, S_IRUGO | S_IWUGO, show_channel, +static DEVICE_ATTR(channel, S_IRUGO | S_IWUSR | S_IWGRP , show_channel, store_channel); static struct device_attribute *sysfs_device_attr_channel = { @@ -169,7 +169,7 @@ static ssize_t store_sustain(struct device *dev, return -EINVAL; } -static DEVICE_ATTR(sustain, S_IRUGO | S_IWUGO, show_sustain, +static DEVICE_ATTR(sustain, S_IRUGO | S_IWUSR | S_IWGRP, show_sustain, store_sustain); static struct device_attribute *sysfs_device_attr_sustain = { @@ -207,7 +207,7 @@ static ssize_t store_octave(struct device *dev, return -EINVAL; } -static DEVICE_ATTR(octave, S_IRUGO | S_IWUGO, show_octave, +static DEVICE_ATTR(octave, S_IRUGO | S_IWUSR | S_IWGRP, show_octave, store_octave); static struct device_attribute *sysfs_device_attr_octave = { -- cgit v1.2.3 From edd2126aa8aab8a87db7cc480d5047e9280d7acf Mon Sep 17 00:00:00 2001 From: Jiri Kosina Date: Thu, 18 Nov 2010 16:28:43 +0100 Subject: HID: wacom: make sysfs permissions more strict It's not really dangerous in this driver, but it's against general practice and worth fixing. Wacom uses the attribute for changing the reporting speed of the tablet (and this actually requires poking the device in the background) (still I wouldn't consider it a security issue though). udev is a proper place to handle this. Reported-by: Linus Torvalds Signed-off-by: Jiri Kosina --- drivers/hid/hid-wacom.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/hid/hid-wacom.c b/drivers/hid/hid-wacom.c index 724f46ed612f..94caae731381 100644 --- a/drivers/hid/hid-wacom.c +++ b/drivers/hid/hid-wacom.c @@ -172,7 +172,7 @@ static ssize_t wacom_store_speed(struct device *dev, return -EINVAL; } -static DEVICE_ATTR(speed, S_IRUGO | S_IWUGO, +static DEVICE_ATTR(speed, S_IRUGO | S_IWUSR | S_IWGRP, wacom_show_speed, wacom_store_speed); static int wacom_raw_event(struct hid_device *hdev, struct hid_report *report, -- cgit v1.2.3 From 2545eb6198e7e1ec50daa0cfc64a4cdfecf24ec9 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Tue, 2 Nov 2010 15:01:32 -0400 Subject: Initial start of ktest.pl Originally named autotest.pl, but renamed to ktest.pl now because the autotest name is used by other projects. Signed-off-by: Steven Rostedt --- tools/testing/ktest/ktest.pl | 334 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 334 insertions(+) create mode 100644 tools/testing/ktest/ktest.pl diff --git a/tools/testing/ktest/ktest.pl b/tools/testing/ktest/ktest.pl new file mode 100644 index 000000000000..81fb2e431058 --- /dev/null +++ b/tools/testing/ktest/ktest.pl @@ -0,0 +1,334 @@ +#!/usr/bin/perl -w + +use strict; +use IPC::Open2; +use Fcntl qw(F_GETFL F_SETFL O_NONBLOCK); +use FileHandle; + +$#ARGV >= 0 || die "usage: autotest.pl config-file\n"; + +$| = 1; + +my %opt; + +#default opts +$opt{"NUM_BUILDS"} = 5; +$opt{"DEFAULT_BUILD_TYPE"} = "randconfig"; +$opt{"MAKE_CMD"} = "make"; +$opt{"TIMEOUT"} = 50; +$opt{"TMP_DIR"} = "/tmp/autotest"; +$opt{"SLEEP_TIME"} = 60; # sleep time between tests + +my $version; +my $install_mods; +my $grub_number; +my $target; +my $make; + +sub read_config { + my ($config) = @_; + + open(IN, $config) || die "can't read file $config"; + + while () { + + # ignore blank lines and comments + next if (/^\s*$/ || /\s*\#/); + + if (/^\s*(\S+)\s*=\s*(.*?)\s*$/) { + my $lvalue = $1; + my $rvalue = $2; + + $opt{$lvalue} = $rvalue; + } + } + + close(IN); +} + +sub doprint { + print @_; + + if (defined($opt{"LOG_FILE"})) { + open(OUT, ">> $opt{LOG_FILE}") or die "Can't write to $opt{LOG_FILE}"; + print OUT @_; + close(OUT); + } +} + +sub run_command { + my ($command) = @_; + my $redirect = ""; + + if (defined($opt{"LOG_FILE"})) { + $redirect = " >> $opt{LOG_FILE} 2>&1"; + } + + doprint "$command ... "; + `$command $redirect`; + + my $failed = $?; + + if ($failed) { + doprint "FAILED!\n"; + } else { + doprint "SUCCESS\n"; + } + + return $failed; +} + +my $timeout = $opt{"TIMEOUT"}; + +sub wait_for_input +{ + my ($fp, $time) = @_; + my $rin; + my $ready; + my $line; + my $ch; + + if (!defined($time)) { + $time = $timeout; + } + + $rin = ''; + vec($rin, fileno($fp), 1) = 1; + $ready = select($rin, undef, undef, $time); + + $line = ""; + + # try to read one char at a time + while (sysread $fp, $ch, 1) { + $line .= $ch; + last if ($ch eq "\n"); + } + + if (!length($line)) { + return undef; + } + + return $line; +} + +sub reboot { + run_command "ssh $target '(echo \"savedefault --default=$grub_number --once\" | grub --batch; reboot)'"; +} + +sub monitor { + my $flags; + my $booted = 0; + my $bug = 0; + my $pid; + my $doopen2 = 0; + + if ($doopen2) { + $pid = open2(\*IN, \*OUT, $opt{CONSOLE}); + if ($pid < 0) { + die "Failed to connect to the console"; + } + } else { + $pid = open(IN, "$opt{CONSOLE} |"); + } + + $flags = fcntl(IN, F_GETFL, 0) or + die "Can't get flags for the socket: $!\n"; + + $flags = fcntl(IN, F_SETFL, $flags | O_NONBLOCK) or + die "Can't set flags for the socket: $!\n"; + + my $line; + my $full_line = ""; + + doprint "Wait for monitor to settle down.\n"; + # read the monitor and wait for the system to calm down + do { + $line = wait_for_input(\*IN, 5); + } while (defined($line)); + + reboot; + + for (;;) { + + $line = wait_for_input(\*IN); + + last if (!defined($line)); + + doprint $line; + + # we are not guaranteed to get a full line + $full_line .= $line; + + if ($full_line =~ /login:/) { + $booted = 1; + } + + if ($full_line =~ /call trace:/i) { + $bug = 1; + } + + if ($line =~ /\n/) { + $full_line = ""; + } + } + + doprint "kill child process $pid\n"; + kill 2, $pid; + + print "closing!\n"; + close(IN); + + if (!$booted) { + die "failed - never got a boot prompt.\n"; + } + + if ($bug) { + die "failed - got a bug report\n"; + } +} + +sub install { + + if (run_command "scp $opt{OUTPUT_DIR}/$opt{BUILD_TARGET} $target:$opt{TARGET_IMAGE}") { + die "failed to copy image"; + } + + if ($install_mods) { + my $modlib = "/lib/modules/$version"; + + if (run_command "ssh $target rm -rf $modlib") { + die "failed to remove old mods: $modlib"; + } + + if (run_command "scp -r $opt{TMP_DIR}/lib $target:/lib/modules/$version") { + die "failed to copy modules"; + } + } + +} + +sub build { + my ($type) = @_; + + unlink "$opt{OUTPUT_DIR}/.config"; + + run_command "$make mrproper"; + + # add something to distinguish this build + open(OUT, "> $opt{OUTPUT_DIR}/localversion") or die("Can't make localversion file"); + print OUT "$opt{LOCALVERSION}\n"; + close(OUT); + + if (run_command "$make $opt{$type}") { + die "failed make config"; + } + + if (defined($opt{"MIN_CONFIG"})) { + run_command "cat $opt{MIN_CONFIG} >> $opt{OUTPUT_DIR}/.config"; + run_command "yes '' | $make oldconfig"; + } + + if (run_command "$make $opt{BUILD_OPTIONS}") { + die "failed build"; + } +} + +read_config $ARGV[0]; + +# mandatory configs +die "MACHINE not defined\n" if (!defined($opt{"MACHINE"})); +die "SSH_USER not defined\n" if (!defined($opt{"SSH_USER"})); +die "BUILD_DIR not defined\n" if (!defined($opt{"BUILD_DIR"})); +die "OUTPUT_DIR not defined\n" if (!defined($opt{"OUTPUT_DIR"})); +die "BUILD_TARGET not defined\n" if (!defined($opt{"BUILD_TARGET"})); +die "POWER_CYCLE not defined\n" if (!defined($opt{"POWER_CYCLE"})); +die "CONSOLE not defined\n" if (!defined($opt{"CONSOLE"})); +die "LOCALVERSION not defined\n" if (!defined($opt{"LOCALVERSION"})); +die "GRUB_MENU not defined\n" if (!defined($opt{"GRUB_MENU"})); + +chdir $opt{"BUILD_DIR"} || die "can't change directory to $opt{BUILD_DIR}"; + +$target = "$opt{SSH_USER}\@$opt{MACHINE}"; + +doprint "\n\nSTARTING AUTOMATED TESTS\n"; + +doprint "Find grub menu ... "; +$grub_number = -1; +open(IN, "ssh $target cat /boot/grub/menu.lst |") + or die "unable to get menu.lst"; +while () { + if (/^\s*title\s+$opt{GRUB_MENU}\s*$/) { + $grub_number++; + last; + } elsif (/^\s*title\s/) { + $grub_number++; + } +} +close(IN); +die "Could not find '$opt{GRUB_MENU}' in /boot/grub/menu on $opt{MACHINE}" + if ($grub_number < 0); +doprint "$grub_number\n"; + +$make = "$opt{MAKE_CMD} O=$opt{OUTPUT_DIR}"; + +# First we need to do is the builds +for (my $i = 1; $i <= $opt{"NUM_BUILDS"}; $i++) { + my $type = "BUILD_TYPE[$i]"; + + if (!defined($opt{$type})) { + $opt{$type} = $opt{"DEFAULT_BUILD_TYPE"}; + } + + doprint "\n\n"; + doprint "RUNNING TEST $i of $opt{NUM_BUILDS} with option $opt{$type}\n\n"; + + if ($opt{$type} ne "nobuild") { + build $type; + } + + # get the release name + doprint "$make kernelrelease ... "; + $version = `$make kernelrelease | tail -1`; + chomp($version); + doprint "$version\n"; + + # should we process modules? + $install_mods = 0; + open(IN, "$opt{OUTPUT_DIR}/.config") or die("Can't read config file"); + while () { + if (/CONFIG_MODULES(=y)?/) { + $install_mods = 1 if (defined($1)); + last; + } + } + close(IN); + + if ($install_mods) { + if (run_command "$make INSTALL_MOD_PATH=$opt{TMP_DIR} modules_install") { + die "Failed to install modules"; + } + } else { + doprint "No modules needed\n"; + } + + install; + + monitor; + + doprint "\n\n*******************************************\n"; + doprint "*******************************************\n"; + doprint "** SUCCESS!!!! **\n"; + doprint "*******************************************\n"; + doprint "*******************************************\n"; + + # try to reboot normally + + if (run_command "ssh $target reboot") { + # nope? power cycle it. + run_command "$opt{POWER_CYCLE}"; + } + + sleep "$opt{SLEEP_TIME}"; +} + +exit 0; -- cgit v1.2.3 From 5c42fc5b975869e73bb8b6c279dd2da81eab5607 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Tue, 2 Nov 2010 14:57:01 -0400 Subject: ktest: New features: noclean, dodie, poweroff on error and success Added dodie function to have a bit more control over die calls. BUILD_NOCLEAN to not run make mrproper or remove .config. POWEROFF_ON_{SUCCESS,ERROR} to turn off the power after tests. Skip backtrace calls that were done by the backtrace tests. Signed-off-by: Steven Rostedt --- tools/testing/ktest/ktest.pl | 115 +++++++++++++++++++++++++++++++++++-------- 1 file changed, 94 insertions(+), 21 deletions(-) diff --git a/tools/testing/ktest/ktest.pl b/tools/testing/ktest/ktest.pl index 81fb2e431058..1acb0e1ab0f4 100644 --- a/tools/testing/ktest/ktest.pl +++ b/tools/testing/ktest/ktest.pl @@ -18,12 +18,16 @@ $opt{"MAKE_CMD"} = "make"; $opt{"TIMEOUT"} = 50; $opt{"TMP_DIR"} = "/tmp/autotest"; $opt{"SLEEP_TIME"} = 60; # sleep time between tests +$opt{"BUILD_NOCLEAN"} = 0; +$opt{"POWEROFF_ON_ERROR"} = 0; +$opt{"POWEROFF_ON_SUCCESS"} = 0; my $version; my $install_mods; my $grub_number; my $target; my $make; +my $noclean; sub read_config { my ($config) = @_; @@ -56,6 +60,16 @@ sub doprint { } } +sub dodie { + doprint "CRITICAL FAILURE... ", @_; + + if ($opt{"POWEROFF_ON_ERROR"} && defined($opt{"POWER_OFF"})) { + doprint "POWERING OFF\n"; + `$opt{"POWER_OFF"}`; + } + die @_; +} + sub run_command { my ($command) = @_; my $redirect = ""; @@ -121,21 +135,22 @@ sub monitor { my $bug = 0; my $pid; my $doopen2 = 0; + my $skip_call_trace = 0; if ($doopen2) { $pid = open2(\*IN, \*OUT, $opt{CONSOLE}); if ($pid < 0) { - die "Failed to connect to the console"; + dodie "Failed to connect to the console"; } } else { $pid = open(IN, "$opt{CONSOLE} |"); } $flags = fcntl(IN, F_GETFL, 0) or - die "Can't get flags for the socket: $!\n"; + dodie "Can't get flags for the socket: $!\n"; $flags = fcntl(IN, F_SETFL, $flags | O_NONBLOCK) or - die "Can't set flags for the socket: $!\n"; + dodie "Can't set flags for the socket: $!\n"; my $line; my $full_line = ""; @@ -163,7 +178,19 @@ sub monitor { $booted = 1; } + if ($full_line =~ /\[ backtrace testing \]/) { + $skip_call_trace = 1; + } + if ($full_line =~ /call trace:/i) { + $bug = 1 if (!$skip_call_trace); + } + + if ($full_line =~ /\[ end of backtrace testing \]/) { + $skip_call_trace = 0; + } + + if ($full_line =~ /Kernel panic -/) { $bug = 1; } @@ -179,57 +206,90 @@ sub monitor { close(IN); if (!$booted) { - die "failed - never got a boot prompt.\n"; + dodie "failed - never got a boot prompt.\n"; } if ($bug) { - die "failed - got a bug report\n"; + dodie "failed - got a bug report\n"; } } sub install { if (run_command "scp $opt{OUTPUT_DIR}/$opt{BUILD_TARGET} $target:$opt{TARGET_IMAGE}") { - die "failed to copy image"; + dodie "failed to copy image"; } if ($install_mods) { my $modlib = "/lib/modules/$version"; + my $modtar = "autotest-mods.tar.bz2"; if (run_command "ssh $target rm -rf $modlib") { - die "failed to remove old mods: $modlib"; + dodie "failed to remove old mods: $modlib"; + } + + # would be nice if scp -r did not follow symbolic links + if (run_command "cd $opt{TMP_DIR}; tar -cjf $modtar lib/modules/$version") { + dodie "making tarball"; } - if (run_command "scp -r $opt{TMP_DIR}/lib $target:/lib/modules/$version") { - die "failed to copy modules"; + if (run_command "scp $opt{TMP_DIR}/$modtar $target:/tmp") { + dodie "failed to copy modules"; + } + + unlink "$opt{TMP_DIR}/$modtar"; + + if (run_command "ssh $target '(cd / && tar xf /tmp/$modtar)'") { + dodie "failed to tar modules"; } + + run_command "ssh $target rm -f /tmp/$modtar"; } } sub build { my ($type) = @_; + my $defconfig = ""; + my $append = ""; + + # old config can ask questions + if ($type eq "oldconfig") { + $append = "yes ''|"; + if (run_command "mv $opt{OUTPUT_DIR}/.config $opt{OUTPUT_DIR}/config_temp") { + dodie "moving .config"; + } - unlink "$opt{OUTPUT_DIR}/.config"; + if (!$noclean && run_command "$make mrproper") { + dodie "make mrproper"; + } - run_command "$make mrproper"; + if (run_command "mv $opt{OUTPUT_DIR}/config_temp $opt{OUTPUT_DIR}/.config") { + dodie "moving config_temp"; + } + + } elsif (!$noclean) { + unlink "$opt{OUTPUT_DIR}/.config"; + if (run_command "$make mrproper") { + dodie "make mrproper"; + } + } # add something to distinguish this build - open(OUT, "> $opt{OUTPUT_DIR}/localversion") or die("Can't make localversion file"); + open(OUT, "> $opt{OUTPUT_DIR}/localversion") or dodie("Can't make localversion file"); print OUT "$opt{LOCALVERSION}\n"; close(OUT); - if (run_command "$make $opt{$type}") { - die "failed make config"; + if (defined($opt{"MIN_CONFIG"})) { + $defconfig = "KCONFIG_ALLCONFIG=$opt{MIN_CONFIG}"; } - if (defined($opt{"MIN_CONFIG"})) { - run_command "cat $opt{MIN_CONFIG} >> $opt{OUTPUT_DIR}/.config"; - run_command "yes '' | $make oldconfig"; + if (run_command "$defconfig $append $make $type") { + dodie "failed make config"; } if (run_command "$make $opt{BUILD_OPTIONS}") { - die "failed build"; + dodie "failed build"; } } @@ -275,6 +335,13 @@ $make = "$opt{MAKE_CMD} O=$opt{OUTPUT_DIR}"; for (my $i = 1; $i <= $opt{"NUM_BUILDS"}; $i++) { my $type = "BUILD_TYPE[$i]"; + if (defined($opt{"BUILD_NOCLEAN[$i]"}) && + $opt{"BUILD_NOCLEAN[$i]"} != 0) { + $noclean = 1; + } else { + $noclean = $opt{"BUILD_NOCLEAN"}; + } + if (!defined($opt{$type})) { $opt{$type} = $opt{"DEFAULT_BUILD_TYPE"}; } @@ -283,7 +350,7 @@ for (my $i = 1; $i <= $opt{"NUM_BUILDS"}; $i++) { doprint "RUNNING TEST $i of $opt{NUM_BUILDS} with option $opt{$type}\n\n"; if ($opt{$type} ne "nobuild") { - build $type; + build $opt{$type}; } # get the release name @@ -294,7 +361,7 @@ for (my $i = 1; $i <= $opt{"NUM_BUILDS"}; $i++) { # should we process modules? $install_mods = 0; - open(IN, "$opt{OUTPUT_DIR}/.config") or die("Can't read config file"); + open(IN, "$opt{OUTPUT_DIR}/.config") or dodie("Can't read config file"); while () { if (/CONFIG_MODULES(=y)?/) { $install_mods = 1 if (defined($1)); @@ -305,7 +372,7 @@ for (my $i = 1; $i <= $opt{"NUM_BUILDS"}; $i++) { if ($install_mods) { if (run_command "$make INSTALL_MOD_PATH=$opt{TMP_DIR} modules_install") { - die "Failed to install modules"; + dodie "Failed to install modules"; } } else { doprint "No modules needed\n"; @@ -331,4 +398,10 @@ for (my $i = 1; $i <= $opt{"NUM_BUILDS"}; $i++) { sleep "$opt{SLEEP_TIME}"; } +if ($opt{"POWEROFF_ON_SUCCESS"}) { + if (run_command "ssh $target halt" && defined($opt{"POWER_OFF"})) { + # nope? the zap it! + run_command "$opt{POWER_OFF}"; + } +} exit 0; -- cgit v1.2.3 From 75c3fda79e97b1e2c390e3623f19476e1e78ca0c Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Tue, 2 Nov 2010 14:57:21 -0400 Subject: ktest: New features reboot on error, make options REBOOT_ON_ERROR to reboot the box on error BUILD_OPTIONS to add options to the make build (like -j40) Added "useconfig:". Signed-off-by: Steven Rostedt --- tools/testing/ktest/ktest.pl | 62 ++++++++++++++++++++++++++++++++------------ 1 file changed, 46 insertions(+), 16 deletions(-) diff --git a/tools/testing/ktest/ktest.pl b/tools/testing/ktest/ktest.pl index 1acb0e1ab0f4..79da57f3023b 100644 --- a/tools/testing/ktest/ktest.pl +++ b/tools/testing/ktest/ktest.pl @@ -19,8 +19,10 @@ $opt{"TIMEOUT"} = 50; $opt{"TMP_DIR"} = "/tmp/autotest"; $opt{"SLEEP_TIME"} = 60; # sleep time between tests $opt{"BUILD_NOCLEAN"} = 0; +$opt{"REBOOT_ON_ERROR"} = 0; $opt{"POWEROFF_ON_ERROR"} = 0; $opt{"POWEROFF_ON_SUCCESS"} = 0; +$opt{"BUILD_OPTIONS"} = ""; my $version; my $install_mods; @@ -63,10 +65,15 @@ sub doprint { sub dodie { doprint "CRITICAL FAILURE... ", @_; - if ($opt{"POWEROFF_ON_ERROR"} && defined($opt{"POWER_OFF"})) { + if ($opt{"REBOOT_ON_ERROR"}) { + doprint "REBOOTING\n"; + `$opt{"POWER_CYCLE"}`; + + } elsif ($opt{"POWEROFF_ON_ERROR"} && defined($opt{"POWER_OFF"})) { doprint "POWERING OFF\n"; `$opt{"POWER_OFF"}`; } + die @_; } @@ -125,7 +132,7 @@ sub wait_for_input return $line; } -sub reboot { +sub reboot_to { run_command "ssh $target '(echo \"savedefault --default=$grub_number --once\" | grub --batch; reboot)'"; } @@ -138,7 +145,7 @@ sub monitor { my $skip_call_trace = 0; if ($doopen2) { - $pid = open2(\*IN, \*OUT, $opt{CONSOLE}); + $pid = open2(\*IN, \*OUT, $opt{"CONSOLE"}); if ($pid < 0) { dodie "Failed to connect to the console"; } @@ -161,7 +168,7 @@ sub monitor { $line = wait_for_input(\*IN, 5); } while (defined($line)); - reboot; + reboot_to; for (;;) { @@ -229,7 +236,7 @@ sub install { } # would be nice if scp -r did not follow symbolic links - if (run_command "cd $opt{TMP_DIR}; tar -cjf $modtar lib/modules/$version") { + if (run_command "cd $opt{TMP_DIR} && tar -cjf $modtar lib/modules/$version") { dodie "making tarball"; } @@ -253,9 +260,20 @@ sub build { my $defconfig = ""; my $append = ""; + if ($type =~ /^useconfig:(.*)/) { + if (run_command "cp $1 $opt{OUTPUT_DIR}/.config") { + dodie "could not copy $1 to .config"; + } + $type = "oldconfig"; + } + # old config can ask questions if ($type eq "oldconfig") { $append = "yes ''|"; + + # allow for empty configs + run_command "touch $opt{OUTPUT_DIR}/.config"; + if (run_command "mv $opt{OUTPUT_DIR}/.config $opt{OUTPUT_DIR}/config_temp") { dodie "moving .config"; } @@ -293,6 +311,21 @@ sub build { } } +sub reboot { + # try to reboot normally + if (run_command "ssh $target reboot") { + # nope? power cycle it. + run_command "$opt{POWER_CYCLE}"; + } +} + +sub halt { + if ((run_command "ssh $target halt") or defined($opt{"POWER_OFF"})) { + # nope? the zap it! + run_command "$opt{POWER_OFF}"; + } +} + read_config $ARGV[0]; # mandatory configs @@ -301,6 +334,7 @@ die "SSH_USER not defined\n" if (!defined($opt{"SSH_USER"})); die "BUILD_DIR not defined\n" if (!defined($opt{"BUILD_DIR"})); die "OUTPUT_DIR not defined\n" if (!defined($opt{"OUTPUT_DIR"})); die "BUILD_TARGET not defined\n" if (!defined($opt{"BUILD_TARGET"})); +die "TARGET_IMAGE not defined\n" if (!defined($opt{"TARGET_IMAGE"})); die "POWER_CYCLE not defined\n" if (!defined($opt{"POWER_CYCLE"})); die "CONSOLE not defined\n" if (!defined($opt{"CONSOLE"})); die "LOCALVERSION not defined\n" if (!defined($opt{"LOCALVERSION"})); @@ -388,20 +422,16 @@ for (my $i = 1; $i <= $opt{"NUM_BUILDS"}; $i++) { doprint "*******************************************\n"; doprint "*******************************************\n"; - # try to reboot normally - - if (run_command "ssh $target reboot") { - # nope? power cycle it. - run_command "$opt{POWER_CYCLE}"; + if ($i != $opt{"NUM_BUILDS"}) { + reboot; + sleep "$opt{SLEEP_TIME}"; } - - sleep "$opt{SLEEP_TIME}"; } if ($opt{"POWEROFF_ON_SUCCESS"}) { - if (run_command "ssh $target halt" && defined($opt{"POWER_OFF"})) { - # nope? the zap it! - run_command "$opt{POWER_OFF}"; - } + halt; +} else { + reboot; } + exit 0; -- cgit v1.2.3 From 5f9b6ced04a4e9c3ee6b4d4042ac5935ef5a8dbd Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Tue, 2 Nov 2010 14:57:33 -0400 Subject: ktest: Bisecting, install modules, add logging Added bisecting, modules, logging of the output. Banners that show success. Signed-off-by: Steven Rostedt --- tools/testing/ktest/ktest.pl | 321 ++++++++++++++++++++++++++++++------------- 1 file changed, 227 insertions(+), 94 deletions(-) diff --git a/tools/testing/ktest/ktest.pl b/tools/testing/ktest/ktest.pl index 79da57f3023b..a34f6f4193df 100644 --- a/tools/testing/ktest/ktest.pl +++ b/tools/testing/ktest/ktest.pl @@ -25,11 +25,13 @@ $opt{"POWEROFF_ON_SUCCESS"} = 0; $opt{"BUILD_OPTIONS"} = ""; my $version; -my $install_mods; my $grub_number; my $target; my $make; my $noclean; +my $minconfig; +my $in_bisect = 0; +my $bisect_bad = ""; sub read_config { my ($config) = @_; @@ -52,9 +54,7 @@ sub read_config { close(IN); } -sub doprint { - print @_; - +sub logit { if (defined($opt{"LOG_FILE"})) { open(OUT, ">> $opt{LOG_FILE}") or die "Can't write to $opt{LOG_FILE}"; print OUT @_; @@ -62,6 +62,11 @@ sub doprint { } } +sub doprint { + print @_; + logit @_; +} + sub dodie { doprint "CRITICAL FAILURE... ", @_; @@ -96,7 +101,30 @@ sub run_command { doprint "SUCCESS\n"; } - return $failed; + return !$failed; +} + +sub get_grub_index { + + return if ($grub_number >= 0); + + doprint "Find grub menu ... "; + $grub_number = -1; + open(IN, "ssh $target cat /boot/grub/menu.lst |") + or die "unable to get menu.lst"; + while () { + if (/^\s*title\s+$opt{GRUB_MENU}\s*$/) { + $grub_number++; + last; + } elsif (/^\s*title\s/) { + $grub_number++; + } + } + close(IN); + + die "Could not find '$opt{GRUB_MENU}' in /boot/grub/menu on $opt{MACHINE}" + if ($grub_number < 0); + doprint "$grub_number\n"; } my $timeout = $opt{"TIMEOUT"}; @@ -213,46 +241,63 @@ sub monitor { close(IN); if (!$booted) { + return 1 if (!$in_bisect); dodie "failed - never got a boot prompt.\n"; } if ($bug) { + return 1 if (!$in_bisect); dodie "failed - got a bug report\n"; } + + return 0; } sub install { - if (run_command "scp $opt{OUTPUT_DIR}/$opt{BUILD_TARGET} $target:$opt{TARGET_IMAGE}") { + run_command "scp $opt{OUTPUT_DIR}/$opt{BUILD_TARGET} $target:$opt{TARGET_IMAGE}" or dodie "failed to copy image"; - } - if ($install_mods) { - my $modlib = "/lib/modules/$version"; - my $modtar = "autotest-mods.tar.bz2"; + my $install_mods = 0; - if (run_command "ssh $target rm -rf $modlib") { - dodie "failed to remove old mods: $modlib"; + # should we process modules? + $install_mods = 0; + open(IN, "$opt{OUTPUT_DIR}/.config") or dodie("Can't read config file"); + while () { + if (/CONFIG_MODULES(=y)?/) { + $install_mods = 1 if (defined($1)); + last; } + } + close(IN); - # would be nice if scp -r did not follow symbolic links - if (run_command "cd $opt{TMP_DIR} && tar -cjf $modtar lib/modules/$version") { - dodie "making tarball"; - } + if (!$install_mods) { + doprint "No modules needed\n"; + return; + } - if (run_command "scp $opt{TMP_DIR}/$modtar $target:/tmp") { - dodie "failed to copy modules"; - } + run_command "$make INSTALL_MOD_PATH=$opt{TMP_DIR} modules_install" or + dodie "Failed to install modules"; - unlink "$opt{TMP_DIR}/$modtar"; + my $modlib = "/lib/modules/$version"; + my $modtar = "autotest-mods.tar.bz2"; - if (run_command "ssh $target '(cd / && tar xf /tmp/$modtar)'") { - dodie "failed to tar modules"; - } + run_command "ssh $target rm -rf $modlib" or + dodie "failed to remove old mods: $modlib"; - run_command "ssh $target rm -f /tmp/$modtar"; - } + # would be nice if scp -r did not follow symbolic links + run_command "cd $opt{TMP_DIR} && tar -cjf $modtar lib/modules/$version" or + dodie "making tarball"; + + run_command "scp $opt{TMP_DIR}/$modtar $target:/tmp" or + dodie "failed to copy modules"; + + unlink "$opt{TMP_DIR}/$modtar"; + + run_command "ssh $target '(cd / && tar xf /tmp/$modtar)'" or + dodie "failed to tar modules"; + run_command "ssh $target rm -f /tmp/$modtar"; } sub build { @@ -261,9 +306,9 @@ sub build { my $append = ""; if ($type =~ /^useconfig:(.*)/) { - if (run_command "cp $1 $opt{OUTPUT_DIR}/.config") { + run_command "cp $1 $opt{OUTPUT_DIR}/.config" or dodie "could not copy $1 to .config"; - } + $type = "oldconfig"; } @@ -274,23 +319,20 @@ sub build { # allow for empty configs run_command "touch $opt{OUTPUT_DIR}/.config"; - if (run_command "mv $opt{OUTPUT_DIR}/.config $opt{OUTPUT_DIR}/config_temp") { + run_command "mv $opt{OUTPUT_DIR}/.config $opt{OUTPUT_DIR}/config_temp" or dodie "moving .config"; - } - if (!$noclean && run_command "$make mrproper") { + if (!$noclean && !run_command "$make mrproper") { dodie "make mrproper"; } - if (run_command "mv $opt{OUTPUT_DIR}/config_temp $opt{OUTPUT_DIR}/.config") { + run_command "mv $opt{OUTPUT_DIR}/config_temp $opt{OUTPUT_DIR}/.config" or dodie "moving config_temp"; - } } elsif (!$noclean) { unlink "$opt{OUTPUT_DIR}/.config"; - if (run_command "$make mrproper") { + run_command "$make mrproper" or dodie "make mrproper"; - } } # add something to distinguish this build @@ -298,34 +340,162 @@ sub build { print OUT "$opt{LOCALVERSION}\n"; close(OUT); - if (defined($opt{"MIN_CONFIG"})) { - $defconfig = "KCONFIG_ALLCONFIG=$opt{MIN_CONFIG}"; + if (defined($minconfig)) { + $defconfig = "KCONFIG_ALLCONFIG=$minconfig"; } - if (run_command "$defconfig $append $make $type") { + run_command "$defconfig $append $make $type" or dodie "failed make config"; - } - if (run_command "$make $opt{BUILD_OPTIONS}") { + if (!run_command "$make $opt{BUILD_OPTIONS}") { + # bisect may need this to pass + return 1 if ($in_bisect); dodie "failed build"; } + + return 0; } sub reboot { # try to reboot normally - if (run_command "ssh $target reboot") { + if (!run_command "ssh $target reboot") { # nope? power cycle it. run_command "$opt{POWER_CYCLE}"; } } sub halt { - if ((run_command "ssh $target halt") or defined($opt{"POWER_OFF"})) { + if (!run_command "ssh $target halt" or defined($opt{"POWER_OFF"})) { # nope? the zap it! run_command "$opt{POWER_OFF}"; } } +sub success { + my ($i) = @_; + + doprint "\n\n*******************************************\n"; + doprint "*******************************************\n"; + doprint "** SUCCESS!!!! **\n"; + doprint "*******************************************\n"; + doprint "*******************************************\n"; + + if ($i != $opt{"NUM_BUILDS"}) { + reboot; + doprint "Sleeping $opt{SLEEP_TIME} seconds\n"; + sleep "$opt{SLEEP_TIME}"; + } +} + +sub get_version { + # get the release name + doprint "$make kernelrelease ... "; + $version = `$make kernelrelease | tail -1`; + chomp($version); + doprint "$version\n"; +} + +sub run_bisect { + my ($type) = @_; + + my $failed; + my $result; + my $output; + my $ret; + + + if (defined($minconfig)) { + $failed = build "useconfig:$minconfig"; + } else { + # ?? no config to use? + $failed = build "oldconfig"; + } + + if ($type ne "build") { + dodie "Failed on build" if $failed; + + # Now boot the box + get_grub_index; + get_version; + install; + $failed = monitor; + + if ($type ne "boot") { + dodie "Failed on boot" if $failed; + } + } + + if ($failed) { + $result = "bad"; + } else { + $result = "good"; + } + + doprint "git bisect $result ... "; + $output = `git bisect $result 2>&1`; + $ret = $?; + + logit $output; + + if ($ret) { + doprint "FAILED\n"; + dodie "Failed to git bisect"; + } + + doprint "SUCCESS\n"; + if ($output =~ m/^(Bisecting: .*\(roughly \d+ steps?\)) \[([[:xdigit:]]+)\]/) { + doprint "$1 [$2]\n"; + } elsif ($output =~ m/^([[:xdigit:]]+) is the first bad commit/) { + $bisect_bad = $1; + doprint "Found bad commit... $1\n"; + return 0; + } + + + return 1; +} + +sub bisect { + my ($i) = @_; + + my $result; + + die "BISECT_GOOD[$i] not defined\n" if (!defined($opt{"BISECT_GOOD[$i]"})); + die "BISECT_BAD[$i] not defined\n" if (!defined($opt{"BISECT_BAD[$i]"})); + die "BISECT_TYPE[$i] not defined\n" if (!defined($opt{"BISECT_TYPE[$i]"})); + + my $good = $opt{"BISECT_GOOD[$i]"}; + my $bad = $opt{"BISECT_BAD[$i]"}; + my $type = $opt{"BISECT_TYPE[$i]"}; + + $in_bisect = 1; + + run_command "git bisect start" or + dodie "could not start bisect"; + + run_command "git bisect good $good" or + dodie "could not set bisect good to $good"; + + run_command "git bisect bad $bad" or + dodie "could not set bisect good to $bad"; + + do { + $result = run_bisect $type; + } while ($result); + + run_command "git bisect log" or + dodie "could not capture git bisect log"; + + run_command "git bisect reset" or + dodie "could not reset git bisect"; + + doprint "Bad commit was [$bisect_bad]\n"; + + $in_bisect = 0; + + success $i; +} + read_config $ARGV[0]; # mandatory configs @@ -346,22 +516,6 @@ $target = "$opt{SSH_USER}\@$opt{MACHINE}"; doprint "\n\nSTARTING AUTOMATED TESTS\n"; -doprint "Find grub menu ... "; -$grub_number = -1; -open(IN, "ssh $target cat /boot/grub/menu.lst |") - or die "unable to get menu.lst"; -while () { - if (/^\s*title\s+$opt{GRUB_MENU}\s*$/) { - $grub_number++; - last; - } elsif (/^\s*title\s/) { - $grub_number++; - } -} -close(IN); -die "Could not find '$opt{GRUB_MENU}' in /boot/grub/menu on $opt{MACHINE}" - if ($grub_number < 0); -doprint "$grub_number\n"; $make = "$opt{MAKE_CMD} O=$opt{OUTPUT_DIR}"; @@ -376,6 +530,14 @@ for (my $i = 1; $i <= $opt{"NUM_BUILDS"}; $i++) { $noclean = $opt{"BUILD_NOCLEAN"}; } + if (defined($opt{"MIN_CONFIG[$i]"})) { + $minconfig = $opt{"MIN_CONFIG[$i]"}; + } elsif (defined($opt{"MIN_CONFIG"})) { + $minconfig = $opt{"MIN_CONFIG"}; + } else { + undef $minconfig; + } + if (!defined($opt{$type})) { $opt{$type} = $opt{"DEFAULT_BUILD_TYPE"}; } @@ -383,49 +545,20 @@ for (my $i = 1; $i <= $opt{"NUM_BUILDS"}; $i++) { doprint "\n\n"; doprint "RUNNING TEST $i of $opt{NUM_BUILDS} with option $opt{$type}\n\n"; - if ($opt{$type} ne "nobuild") { - build $opt{$type}; - } - - # get the release name - doprint "$make kernelrelease ... "; - $version = `$make kernelrelease | tail -1`; - chomp($version); - doprint "$version\n"; - - # should we process modules? - $install_mods = 0; - open(IN, "$opt{OUTPUT_DIR}/.config") or dodie("Can't read config file"); - while () { - if (/CONFIG_MODULES(=y)?/) { - $install_mods = 1 if (defined($1)); - last; - } + if ($opt{$type} eq "bisect") { + bisect $i; + next; } - close(IN); - if ($install_mods) { - if (run_command "$make INSTALL_MOD_PATH=$opt{TMP_DIR} modules_install") { - dodie "Failed to install modules"; - } - } else { - doprint "No modules needed\n"; + if ($opt{$type} ne "nobuild") { + build $opt{$type}; } + get_grub_index; + get_version; install; - monitor; - - doprint "\n\n*******************************************\n"; - doprint "*******************************************\n"; - doprint "** SUCCESS!!!! **\n"; - doprint "*******************************************\n"; - doprint "*******************************************\n"; - - if ($i != $opt{"NUM_BUILDS"}) { - reboot; - sleep "$opt{SLEEP_TIME}"; - } + success $i; } if ($opt{"POWEROFF_ON_SUCCESS"}) { -- cgit v1.2.3 From 5a391fbff8755592eb080784ef32ff818d2daa44 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Tue, 2 Nov 2010 14:57:43 -0400 Subject: ktest: Added better console, add test build Better reading of the console. Added running a script to do testing after build succeeds. Signed-off-by: Steven Rostedt --- tools/testing/ktest/ktest.pl | 207 +++++++++++++++++++++++++++++++++---------- 1 file changed, 159 insertions(+), 48 deletions(-) diff --git a/tools/testing/ktest/ktest.pl b/tools/testing/ktest/ktest.pl index a34f6f4193df..9eaf8d05c749 100644 --- a/tools/testing/ktest/ktest.pl +++ b/tools/testing/ktest/ktest.pl @@ -23,6 +23,7 @@ $opt{"REBOOT_ON_ERROR"} = 0; $opt{"POWEROFF_ON_ERROR"} = 0; $opt{"POWEROFF_ON_SUCCESS"} = 0; $opt{"BUILD_OPTIONS"} = ""; +$opt{"BISECT_SLEEP_TIME"} = 10; # sleep time between bisects my $version; my $grub_number; @@ -32,6 +33,7 @@ my $noclean; my $minconfig; my $in_bisect = 0; my $bisect_bad = ""; +my $run_test; sub read_config { my ($config) = @_; @@ -68,7 +70,7 @@ sub doprint { } sub dodie { - doprint "CRITICAL FAILURE... ", @_; + doprint "CRITICAL FAILURE... ", @_, "\n"; if ($opt{"REBOOT_ON_ERROR"}) { doprint "REBOOTING\n"; @@ -84,14 +86,14 @@ sub dodie { sub run_command { my ($command) = @_; - my $redirect = ""; + my $redirect_log = ""; if (defined($opt{"LOG_FILE"})) { - $redirect = " >> $opt{LOG_FILE} 2>&1"; + $redirect_log = " >> $opt{LOG_FILE} 2>&1"; } doprint "$command ... "; - `$command $redirect`; + `$command $redirect_log`; my $failed = $?; @@ -106,7 +108,7 @@ sub run_command { sub get_grub_index { - return if ($grub_number >= 0); + return if (defined($grub_number)); doprint "Find grub menu ... "; $grub_number = -1; @@ -164,28 +166,40 @@ sub reboot_to { run_command "ssh $target '(echo \"savedefault --default=$grub_number --once\" | grub --batch; reboot)'"; } -sub monitor { +sub open_console { + my ($fp) = @_; + my $flags; + + my $pid = open($fp, "$opt{CONSOLE}|") or + dodie "Can't open console $opt{CONSOLE}"; + + $flags = fcntl($fp, F_GETFL, 0) or + dodie "Can't get flags for the socket: $!\n"; + $flags = fcntl($fp, F_SETFL, $flags | O_NONBLOCK) or + dodie "Can't set flags for the socket: $!\n"; + + return $pid; +} + +sub close_console { + my ($fp, $pid) = @_; + + doprint "kill child process $pid\n"; + kill 2, $pid; + + print "closing!\n"; + close($fp); +} + +sub monitor { my $booted = 0; my $bug = 0; my $pid; - my $doopen2 = 0; my $skip_call_trace = 0; + my $fp = \*IN; - if ($doopen2) { - $pid = open2(\*IN, \*OUT, $opt{"CONSOLE"}); - if ($pid < 0) { - dodie "Failed to connect to the console"; - } - } else { - $pid = open(IN, "$opt{CONSOLE} |"); - } - - $flags = fcntl(IN, F_GETFL, 0) or - dodie "Can't get flags for the socket: $!\n"; - - $flags = fcntl(IN, F_SETFL, $flags | O_NONBLOCK) or - dodie "Can't set flags for the socket: $!\n"; + $pid = open_console($fp); my $line; my $full_line = ""; @@ -193,14 +207,14 @@ sub monitor { doprint "Wait for monitor to settle down.\n"; # read the monitor and wait for the system to calm down do { - $line = wait_for_input(\*IN, 5); + $line = wait_for_input($fp, 5); } while (defined($line)); reboot_to; for (;;) { - $line = wait_for_input(\*IN); + $line = wait_for_input($fp); last if (!defined($line)); @@ -234,19 +248,15 @@ sub monitor { } } - doprint "kill child process $pid\n"; - kill 2, $pid; - - print "closing!\n"; - close(IN); + close_console($fp, $pid); if (!$booted) { - return 1 if (!$in_bisect); + return 1 if ($in_bisect); dodie "failed - never got a boot prompt.\n"; } if ($bug) { - return 1 if (!$in_bisect); + return 1 if ($in_bisect); dodie "failed - got a bug report\n"; } @@ -395,6 +405,84 @@ sub get_version { doprint "$version\n"; } +sub child_run_test { + my $failed; + + $failed = !run_command $run_test; + exit $failed; +} + +my $child_done; + +sub child_finished { + $child_done = 1; +} + +sub do_run_test { + my $child_pid; + my $child_exit; + my $pid; + my $line; + my $full_line; + my $bug = 0; + my $fp = \*IN; + + $pid = open_console($fp); + + # read the monitor and wait for the system to calm down + do { + $line = wait_for_input($fp, 1); + } while (defined($line)); + + $child_done = 0; + + $SIG{CHLD} = qw(child_finished); + + $child_pid = fork; + + child_run_test if (!$child_pid); + + $full_line = ""; + + do { + $line = wait_for_input($fp, 1); + if (defined($line)) { + + # we are not guaranteed to get a full line + $full_line .= $line; + + if ($full_line =~ /call trace:/i) { + $bug = 1; + } + + if ($full_line =~ /Kernel panic -/) { + $bug = 1; + } + + if ($line =~ /\n/) { + $full_line = ""; + } + } + } while (!$child_done && !$bug); + + if ($bug) { + doprint "Detected kernel crash!\n"; + # kill the child with extreme prejudice + kill 9, $child_pid; + } + + waitpid $child_pid, 0; + $child_exit = $?; + + close_console($fp, $pid); + + if ($bug || $child_exit) { + return 1 if $in_bisect; + dodie "test failed"; + } + return 0; +} + sub run_bisect { my ($type) = @_; @@ -422,11 +510,20 @@ sub run_bisect { if ($type ne "boot") { dodie "Failed on boot" if $failed; + + $failed = do_run_test; } } if ($failed) { $result = "bad"; + + # reboot the box to a good kernel + if ($type eq "boot") { + reboot; + doprint "sleep a little for reboot\n"; + sleep $opt{"BISECT_SLEEP_TIME"}; + } } else { $result = "good"; } @@ -443,12 +540,15 @@ sub run_bisect { } doprint "SUCCESS\n"; - if ($output =~ m/^(Bisecting: .*\(roughly \d+ steps?\)) \[([[:xdigit:]]+)\]/) { + if ($output =~ m/^(Bisecting: .*\(roughly \d+ steps?\))\s+\[([[:xdigit:]]+)\]/) { doprint "$1 [$2]\n"; } elsif ($output =~ m/^([[:xdigit:]]+) is the first bad commit/) { $bisect_bad = $1; doprint "Found bad commit... $1\n"; return 0; + } else { + # we already logged it, just print it now. + print $output; } @@ -479,6 +579,11 @@ sub bisect { run_command "git bisect bad $bad" or dodie "could not set bisect good to $bad"; + # Can't have a test without having a test to run + if ($type eq "test" && !defined($run_test)) { + $type = "boot"; + } + do { $result = run_bisect $type; } while ($result); @@ -519,29 +624,30 @@ doprint "\n\nSTARTING AUTOMATED TESTS\n"; $make = "$opt{MAKE_CMD} O=$opt{OUTPUT_DIR}"; -# First we need to do is the builds -for (my $i = 1; $i <= $opt{"NUM_BUILDS"}; $i++) { - my $type = "BUILD_TYPE[$i]"; +sub set_build_option { + my ($name, $i) = @_; - if (defined($opt{"BUILD_NOCLEAN[$i]"}) && - $opt{"BUILD_NOCLEAN[$i]"} != 0) { - $noclean = 1; - } else { - $noclean = $opt{"BUILD_NOCLEAN"}; - } + my $option = "$name\[$i\]"; - if (defined($opt{"MIN_CONFIG[$i]"})) { - $minconfig = $opt{"MIN_CONFIG[$i]"}; - } elsif (defined($opt{"MIN_CONFIG"})) { - $minconfig = $opt{"MIN_CONFIG"}; - } else { - undef $minconfig; + if (defined($opt{$option})) { + return $opt{$option}; } - if (!defined($opt{$type})) { - $opt{$type} = $opt{"DEFAULT_BUILD_TYPE"}; + if (defined($opt{$name})) { + return $opt{$name}; } + return undef; +} + +# First we need to do is the builds +for (my $i = 1; $i <= $opt{"NUM_BUILDS"}; $i++) { + my $type = "BUILD_TYPE[$i]"; + + $noclean = set_build_option("BUILD_NOCLEAN", $i); + $minconfig = set_build_option("MIN_CONFIG", $i); + $run_test = set_build_option("TEST", $i); + doprint "\n\n"; doprint "RUNNING TEST $i of $opt{NUM_BUILDS} with option $opt{$type}\n\n"; @@ -558,6 +664,11 @@ for (my $i = 1; $i <= $opt{"NUM_BUILDS"}; $i++) { get_version; install; monitor; + + if (defined($run_test)) { + do_run_test; + } + success $i; } -- cgit v1.2.3 From 1a5cfce344711a541aa63bdff81a58db35e20564 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Tue, 2 Nov 2010 14:57:51 -0400 Subject: ktest: Added reboot on success Signed-off-by: Steven Rostedt --- tools/testing/ktest/ktest.pl | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tools/testing/ktest/ktest.pl b/tools/testing/ktest/ktest.pl index 9eaf8d05c749..f344fd0d4f28 100644 --- a/tools/testing/ktest/ktest.pl +++ b/tools/testing/ktest/ktest.pl @@ -21,6 +21,7 @@ $opt{"SLEEP_TIME"} = 60; # sleep time between tests $opt{"BUILD_NOCLEAN"} = 0; $opt{"REBOOT_ON_ERROR"} = 0; $opt{"POWEROFF_ON_ERROR"} = 0; +$opt{"REBOOT_ON_SUCCESS"} = 1; $opt{"POWEROFF_ON_SUCCESS"} = 0; $opt{"BUILD_OPTIONS"} = ""; $opt{"BISECT_SLEEP_TIME"} = 10; # sleep time between bisects @@ -644,6 +645,10 @@ sub set_build_option { for (my $i = 1; $i <= $opt{"NUM_BUILDS"}; $i++) { my $type = "BUILD_TYPE[$i]"; + if (!defined($opt{$type})) { + $opt{$type} = $opt{"DEFAULT_BUILD_TYPE"}; + } + $noclean = set_build_option("BUILD_NOCLEAN", $i); $minconfig = set_build_option("MIN_CONFIG", $i); $run_test = set_build_option("TEST", $i); @@ -674,7 +679,7 @@ for (my $i = 1; $i <= $opt{"NUM_BUILDS"}; $i++) { if ($opt{"POWEROFF_ON_SUCCESS"}) { halt; -} else { +} elsif ($opt{"REBOOT_ON_SUCCESS"}) { reboot; } -- cgit v1.2.3 From 6c5ee0be02f73ebd70eb50b84013e8830f08a6da Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Tue, 2 Nov 2010 14:57:58 -0400 Subject: ktest: Added patchcheck Added patchcheck functionality. It will checkout a given SHA1 and test that commit and all commits to another given SHA1. Signed-off-by: Steven Rostedt --- tools/testing/ktest/ktest.pl | 142 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 140 insertions(+), 2 deletions(-) diff --git a/tools/testing/ktest/ktest.pl b/tools/testing/ktest/ktest.pl index f344fd0d4f28..e0ded14b5477 100644 --- a/tools/testing/ktest/ktest.pl +++ b/tools/testing/ktest/ktest.pl @@ -34,7 +34,9 @@ my $noclean; my $minconfig; my $in_bisect = 0; my $bisect_bad = ""; +my $in_patchcheck = 0; my $run_test; +my $redirect; sub read_config { my ($config) = @_; @@ -88,13 +90,18 @@ sub dodie { sub run_command { my ($command) = @_; my $redirect_log = ""; + my $redirect_tee = ""; if (defined($opt{"LOG_FILE"})) { - $redirect_log = " >> $opt{LOG_FILE} 2>&1"; + $redirect_log = "| tee -a $opt{LOG_FILE}"; + } + + if (defined($redirect)) { + $redirect_tee = "| tee $redirect" } doprint "$command ... "; - `$command $redirect_log`; + `$command 2>&1 $redirect_tee $redirect_log > /dev/null`; my $failed = $?; @@ -311,6 +318,37 @@ sub install { run_command "ssh $target rm -f /tmp/$modtar"; } +sub check_buildlog { + my ($patch) = @_; + + my $buildlog = "$opt{TMP_DIR}/buildlog"; + my @files = `git show $patch | diffstat -l`; + + open(IN, "git show $patch |") or + dodie "failed to show $patch"; + while () { + if (m,^--- a/(.*),) { + chomp $1; + $files[$#files] = $1; + } + } + close(IN); + + open(IN, $buildlog) or dodie "Can't open $buildlog"; + while () { + if (/^\s*(.*?):.*(warning|error)/) { + my $err = $1; + foreach my $file (@files) { + my $fullpath = "$opt{BUILD_DIR}/$file"; + if ($file eq $err || $fullpath eq $err) { + dodie "$file built with warnings"; + } + } + } + } + close(IN); +} + sub build { my ($type) = @_; my $defconfig = ""; @@ -358,11 +396,18 @@ sub build { run_command "$defconfig $append $make $type" or dodie "failed make config"; + # patch check will examine the log + if ($in_patchcheck) { + $redirect = "$opt{TMP_DIR}/buildlog"; + } + if (!run_command "$make $opt{BUILD_OPTIONS}") { + undef $redirect; # bisect may need this to pass return 1 if ($in_bisect); dodie "failed build"; } + undef $redirect; return 0; } @@ -602,6 +647,90 @@ sub bisect { success $i; } +sub patchcheck { + my ($i) = @_; + + die "PATCHCHECK_START[$i] not defined\n" + if (!defined($opt{"PATCHCHECK_START[$i]"})); + die "PATCHCHECK_TYPE[$i] not defined\n" + if (!defined($opt{"PATCHCHECK_TYPE[$i]"})); + + my $start = $opt{"PATCHCHECK_START[$i]"}; + + my $end = "HEAD"; + if (defined($opt{"PATCHCHECK_END[$i]"})) { + $end = $opt{"PATCHCHECK_END[$i]"}; + } + + my $type = $opt{"PATCHCHECK_TYPE[$i]"}; + + # Can't have a test without having a test to run + if ($type eq "test" && !defined($run_test)) { + $type = "boot"; + } + + open (IN, "git log --pretty=oneline $end|") or + dodie "could not get git list"; + + my @list; + + while () { + chomp; + $list[$#list+1] = $_; + last if (/^$start/); + } + close(IN); + + if ($list[$#list] !~ /^$start/) { + dodie "SHA1 $start not found"; + } + + # go backwards in the list + @list = reverse @list; + + my $save_clean = $noclean; + + $in_patchcheck = 1; + foreach my $item (@list) { + my $sha1 = $item; + $sha1 =~ s/^([[:xdigit:]]+).*/$1/; + + doprint "\nProcessing commit $item\n\n"; + + run_command "git checkout $sha1" or + die "Failed to checkout $sha1"; + + # only clean on the first and last patch + if ($item eq $list[0] || + $item eq $list[$#list]) { + $noclean = $save_clean; + } else { + $noclean = 1; + } + + if (defined($minconfig)) { + build "useconfig:$minconfig"; + } else { + # ?? no config to use? + build "oldconfig"; + } + + check_buildlog $sha1; + + next if ($type eq "build"); + + get_grub_index; + get_version; + install; + monitor; + + next if ($type eq "boot"); + do_run_test; + } + $in_patchcheck = 0; + success $i; +} + read_config $ARGV[0]; # mandatory configs @@ -656,9 +785,18 @@ for (my $i = 1; $i <= $opt{"NUM_BUILDS"}; $i++) { doprint "\n\n"; doprint "RUNNING TEST $i of $opt{NUM_BUILDS} with option $opt{$type}\n\n"; + my $checkout = $opt{"CHECKOUT[$i]"}; + if (defined($checkout)) { + run_command "git checkout $checkout" or + die "failed to checkout $checkout"; + } + if ($opt{$type} eq "bisect") { bisect $i; next; + } elsif ($opt{$type} eq "patchcheck") { + patchcheck $i; + next; } if ($opt{$type} ne "nobuild") { -- cgit v1.2.3 From d6ce2a0b33eb71f6862dfb6cbddd0e842f8132de Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Tue, 2 Nov 2010 14:58:05 -0400 Subject: ktest: Add reverse bisect, better logging, copyright Added the ability to do a reverse bisect. Better logging of running commands. Added the copyright statement. Signed-off-by: Steven Rostedt --- tools/testing/ktest/ktest.pl | 51 ++++++++++++++++++++++++++++++++++++++------ 1 file changed, 45 insertions(+), 6 deletions(-) diff --git a/tools/testing/ktest/ktest.pl b/tools/testing/ktest/ktest.pl index e0ded14b5477..0dc403e7170c 100644 --- a/tools/testing/ktest/ktest.pl +++ b/tools/testing/ktest/ktest.pl @@ -1,4 +1,8 @@ #!/usr/bin/perl -w +# +# Copywrite 2010 - Steven Rostedt , Red Hat Inc. +# Licensed under the terms of the GNU GPL License version 2 +# use strict; use IPC::Open2; @@ -34,6 +38,7 @@ my $noclean; my $minconfig; my $in_bisect = 0; my $bisect_bad = ""; +my $reverse_bisect; my $in_patchcheck = 0; my $run_test; my $redirect; @@ -89,22 +94,39 @@ sub dodie { sub run_command { my ($command) = @_; - my $redirect_log = ""; - my $redirect_tee = ""; + my $dolog = 0; + my $dord = 0; + my $pid; + + doprint("$command ... "); + + $pid = open(CMD, "$command 2>&1 |") or + dodie "unable to exec $command"; if (defined($opt{"LOG_FILE"})) { - $redirect_log = "| tee -a $opt{LOG_FILE}"; + open(LOG, ">>$opt{LOG_FILE}") or + dodie "failed to write to log"; + $dolog = 1; } if (defined($redirect)) { - $redirect_tee = "| tee $redirect" + open (RD, ">$redirect") or + dodie "failed to write to redirect $redirect"; + $dord = 1; } - doprint "$command ... "; - `$command 2>&1 $redirect_tee $redirect_log > /dev/null`; + while () { + print LOG if ($dolog); + print RD if ($dord); + } + waitpid($pid, 0); my $failed = $?; + close(CMD); + close(LOG) if ($dolog); + close(RD) if ($dord); + if ($failed) { doprint "FAILED!\n"; } else { @@ -574,6 +596,15 @@ sub run_bisect { $result = "good"; } + # Are we looking for where it worked, not failed? + if ($reverse_bisect) { + if ($failed) { + $result = "good"; + } else { + $result = "bad"; + } + } + doprint "git bisect $result ... "; $output = `git bisect $result 2>&1`; $ret = $?; @@ -614,6 +645,14 @@ sub bisect { my $bad = $opt{"BISECT_BAD[$i]"}; my $type = $opt{"BISECT_TYPE[$i]"}; + if (defined($opt{"BISECT_REVERSE[$i]"}) && + $opt{"BISECT_REVERSE[$i]"} == 1) { + doprint "Performing a reverse bisect (bad is good, good is bad!)\n"; + $reverse_bisect = 1; + } else { + $reverse_bisect = 0; + } + $in_bisect = 1; run_command "git bisect start" or -- cgit v1.2.3 From 2b7d9b21426f10448cb047d1d7c3be05da848fd2 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Tue, 2 Nov 2010 14:58:15 -0400 Subject: ktest: Added continuing on success, clear log and timeout Add option to continue after a test fails. Add option to reset the log at start of running ktest. Update default timeout to 2 minutes. Signed-off-by: Steven Rostedt --- tools/testing/ktest/ktest.pl | 116 +++++++++++++++++++++++++++++-------------- 1 file changed, 78 insertions(+), 38 deletions(-) diff --git a/tools/testing/ktest/ktest.pl b/tools/testing/ktest/ktest.pl index 0dc403e7170c..0a0b1b16fccd 100644 --- a/tools/testing/ktest/ktest.pl +++ b/tools/testing/ktest/ktest.pl @@ -19,7 +19,7 @@ my %opt; $opt{"NUM_BUILDS"} = 5; $opt{"DEFAULT_BUILD_TYPE"} = "randconfig"; $opt{"MAKE_CMD"} = "make"; -$opt{"TIMEOUT"} = 50; +$opt{"TIMEOUT"} = 120; $opt{"TMP_DIR"} = "/tmp/autotest"; $opt{"SLEEP_TIME"} = 60; # sleep time between tests $opt{"BUILD_NOCLEAN"} = 0; @@ -29,6 +29,10 @@ $opt{"REBOOT_ON_SUCCESS"} = 1; $opt{"POWEROFF_ON_SUCCESS"} = 0; $opt{"BUILD_OPTIONS"} = ""; $opt{"BISECT_SLEEP_TIME"} = 10; # sleep time between bisects +$opt{"CLEAR_LOG"} = 0; +$opt{"SUCCESS_LINE"} = "login:"; +$opt{"BOOTED_TIMEOUT"} = 1; +$opt{"DIE_ON_FAILURE"} = 1; my $version; my $grub_number; @@ -36,6 +40,7 @@ my $target; my $make; my $noclean; my $minconfig; +my $addconfig; my $in_bisect = 0; my $bisect_bad = ""; my $reverse_bisect; @@ -92,6 +97,16 @@ sub dodie { die @_; } +sub fail { + + if ($opt{"DIE_ON_FAILURE"}) { + dodie @_; + } + + doprint "Failed: ", @_, "\n"; + return 1; +} + sub run_command { my ($command) = @_; my $dolog = 0; @@ -101,7 +116,7 @@ sub run_command { doprint("$command ... "); $pid = open(CMD, "$command 2>&1 |") or - dodie "unable to exec $command"; + (fail "unable to exec $command" and return 0); if (defined($opt{"LOG_FILE"})) { open(LOG, ">>$opt{LOG_FILE}") or @@ -228,6 +243,7 @@ sub monitor { my $pid; my $skip_call_trace = 0; my $fp = \*IN; + my $loops; $pid = open_console($fp); @@ -244,7 +260,11 @@ sub monitor { for (;;) { - $line = wait_for_input($fp); + if ($booted) { + $line = wait_for_input($fp, $opt{"BOOTED_TIMEOUT"}); + } else { + $line = wait_for_input($fp); + } last if (!defined($line)); @@ -253,7 +273,7 @@ sub monitor { # we are not guaranteed to get a full line $full_line .= $line; - if ($full_line =~ /login:/) { + if ($full_line =~ /$opt{"SUCCESS_LINE"}/) { $booted = 1; } @@ -281,16 +301,16 @@ sub monitor { close_console($fp, $pid); if (!$booted) { - return 1 if ($in_bisect); - dodie "failed - never got a boot prompt.\n"; + return 0 if ($in_bisect); + fail "failed - never got a boot prompt.\n" and return 0; } if ($bug) { - return 1 if ($in_bisect); - dodie "failed - got a bug report\n"; + return 0 if ($in_bisect); + fail "failed - got a bug report\n" and return 0; } - return 0; + return 1; } sub install { @@ -363,12 +383,14 @@ sub check_buildlog { foreach my $file (@files) { my $fullpath = "$opt{BUILD_DIR}/$file"; if ($file eq $err || $fullpath eq $err) { - dodie "$file built with warnings"; + fail "$file built with warnings" and return 0; } } } } close(IN); + + return 1; } sub build { @@ -426,12 +448,12 @@ sub build { if (!run_command "$make $opt{BUILD_OPTIONS}") { undef $redirect; # bisect may need this to pass - return 1 if ($in_bisect); - dodie "failed build"; + return 0 if ($in_bisect); + fail "failed build" and return 0; } undef $redirect; - return 0; + return 1; } sub reboot { @@ -545,41 +567,40 @@ sub do_run_test { close_console($fp, $pid); if ($bug || $child_exit) { - return 1 if $in_bisect; - dodie "test failed"; + return 0 if $in_bisect; + fail "test failed" and return 0; } - return 0; + return 1; } sub run_bisect { my ($type) = @_; - my $failed; + my $failed = 0; my $result; my $output; my $ret; - if (defined($minconfig)) { - $failed = build "useconfig:$minconfig"; + build "useconfig:$minconfig" or $failed = 1; } else { # ?? no config to use? - $failed = build "oldconfig"; + build "oldconfig" or $failed = 1; } if ($type ne "build") { - dodie "Failed on build" if $failed; + fail "Failed on build" if $failed; # Now boot the box get_grub_index; get_version; install; - $failed = monitor; + monitor or $failed = 1; if ($type ne "boot") { - dodie "Failed on boot" if $failed; + fail "Failed on boot" if $failed; - $failed = do_run_test; + do_run_test or $failed = 1; } } @@ -613,7 +634,7 @@ sub run_bisect { if ($ret) { doprint "FAILED\n"; - dodie "Failed to git bisect"; + fail "Failed to git bisect"; } doprint "SUCCESS\n"; @@ -656,13 +677,13 @@ sub bisect { $in_bisect = 1; run_command "git bisect start" or - dodie "could not start bisect"; + fail "could not start bisect"; run_command "git bisect good $good" or - dodie "could not set bisect good to $good"; + fail "could not set bisect good to $good"; run_command "git bisect bad $bad" or - dodie "could not set bisect good to $bad"; + fail "could not set bisect good to $bad"; # Can't have a test without having a test to run if ($type eq "test" && !defined($run_test)) { @@ -721,7 +742,7 @@ sub patchcheck { close(IN); if ($list[$#list] !~ /^$start/) { - dodie "SHA1 $start not found"; + fail "SHA1 $start not found"; } # go backwards in the list @@ -748,26 +769,28 @@ sub patchcheck { } if (defined($minconfig)) { - build "useconfig:$minconfig"; + build "useconfig:$minconfig" or return 0; } else { # ?? no config to use? - build "oldconfig"; + build "oldconfig" or return 0; } - check_buildlog $sha1; + check_buildlog $sha1 or return 0; next if ($type eq "build"); get_grub_index; get_version; install; - monitor; + monitor or return 0; next if ($type eq "boot"); - do_run_test; + do_run_test or next; } $in_patchcheck = 0; success $i; + + return 1; } read_config $ARGV[0]; @@ -788,8 +811,15 @@ chdir $opt{"BUILD_DIR"} || die "can't change directory to $opt{BUILD_DIR}"; $target = "$opt{SSH_USER}\@$opt{MACHINE}"; -doprint "\n\nSTARTING AUTOMATED TESTS\n"; +if ($opt{"CLEAR_LOG"} && defined($opt{"LOG_FILE"})) { + unlink $opt{"LOG_FILE"}; +} +doprint "\n\nSTARTING AUTOMATED TESTS\n\n"; + +foreach my $option (sort keys %opt) { + doprint "$option = $opt{$option}\n"; +} $make = "$opt{MAKE_CMD} O=$opt{OUTPUT_DIR}"; @@ -820,10 +850,20 @@ for (my $i = 1; $i <= $opt{"NUM_BUILDS"}; $i++) { $noclean = set_build_option("BUILD_NOCLEAN", $i); $minconfig = set_build_option("MIN_CONFIG", $i); $run_test = set_build_option("TEST", $i); + $addconfig = set_build_option("ADD_CONFIG", $i); doprint "\n\n"; doprint "RUNNING TEST $i of $opt{NUM_BUILDS} with option $opt{$type}\n\n"; + if (!defined($minconfig)) { + $minconfig = $addconfig; + + } elsif (defined($addconfig)) { + run_command "cat $addconfig $minconfig > $opt{TMP_DIR}/use_config" or + dodie "Failed to create temp config"; + $minconfig = "$opt{TMP_DIR}/use_config"; + } + my $checkout = $opt{"CHECKOUT[$i]"}; if (defined($checkout)) { run_command "git checkout $checkout" or @@ -839,16 +879,16 @@ for (my $i = 1; $i <= $opt{"NUM_BUILDS"}; $i++) { } if ($opt{$type} ne "nobuild") { - build $opt{$type}; + build $opt{$type} or next; } get_grub_index; get_version; install; - monitor; + monitor or next; if (defined($run_test)) { - do_run_test; + do_run_test or next; } success $i; -- cgit v1.2.3 From 7faafbd69639b53b6cc2d450c283d9cc12e62c70 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Tue, 2 Nov 2010 14:58:22 -0400 Subject: ktest: Add open and close console and start stop monitor It is much better to keep the monitor running throughout a test than to constantly start and stop it. Some console readers will show everything that has happened before when opening the console, and by opening it several times, causes the old content to be read multiple times in a single test. Signed-off-by: Steven Rostedt --- tools/testing/ktest/ktest.pl | 257 ++++++++++++++++++++++++++++--------------- 1 file changed, 170 insertions(+), 87 deletions(-) diff --git a/tools/testing/ktest/ktest.pl b/tools/testing/ktest/ktest.pl index 0a0b1b16fccd..ff6283a44847 100644 --- a/tools/testing/ktest/ktest.pl +++ b/tools/testing/ktest/ktest.pl @@ -7,6 +7,8 @@ use strict; use IPC::Open2; use Fcntl qw(F_GETFL F_SETFL O_NONBLOCK); +use File::Path qw(mkpath); +use File::Copy qw(cp); use FileHandle; $#ARGV >= 0 || die "usage: autotest.pl config-file\n"; @@ -17,7 +19,7 @@ my %opt; #default opts $opt{"NUM_BUILDS"} = 5; -$opt{"DEFAULT_BUILD_TYPE"} = "randconfig"; +$opt{"BUILD_TYPE"} = "randconfig"; $opt{"MAKE_CMD"} = "make"; $opt{"TIMEOUT"} = 120; $opt{"TMP_DIR"} = "/tmp/autotest"; @@ -35,6 +37,7 @@ $opt{"BOOTED_TIMEOUT"} = 1; $opt{"DIE_ON_FAILURE"} = 1; my $version; +my $build_type; my $grub_number; my $target; my $make; @@ -47,6 +50,11 @@ my $reverse_bisect; my $in_patchcheck = 0; my $run_test; my $redirect; +my $buildlog; +my $dmesg; +my $monitor_fp; +my $monitor_pid; +my $monitor_cnt = 0; sub read_config { my ($config) = @_; @@ -82,12 +90,22 @@ sub doprint { logit @_; } +sub run_command; + +sub reboot { + # try to reboot normally + if (!run_command "ssh $target reboot") { + # nope? power cycle it. + run_command "$opt{POWER_CYCLE}"; + } +} + sub dodie { doprint "CRITICAL FAILURE... ", @_, "\n"; if ($opt{"REBOOT_ON_ERROR"}) { doprint "REBOOTING\n"; - `$opt{"POWER_CYCLE"}`; + reboot; } elsif ($opt{"POWEROFF_ON_ERROR"} && defined($opt{"POWER_OFF"})) { doprint "POWERING OFF\n"; @@ -97,6 +115,59 @@ sub dodie { die @_; } +sub open_console { + my ($fp) = @_; + + my $flags; + + my $pid = open($fp, "$opt{CONSOLE}|") or + dodie "Can't open console $opt{CONSOLE}"; + + $flags = fcntl($fp, F_GETFL, 0) or + dodie "Can't get flags for the socket: $!\n"; + $flags = fcntl($fp, F_SETFL, $flags | O_NONBLOCK) or + dodie "Can't set flags for the socket: $!\n"; + + return $pid; +} + +sub close_console { + my ($fp, $pid) = @_; + + doprint "kill child process $pid\n"; + kill 2, $pid; + + print "closing!\n"; + close($fp); +} + +sub start_monitor { + if ($monitor_cnt++) { + return; + } + $monitor_fp = \*MONFD; + $monitor_pid = open_console $monitor_fp; +} + +sub end_monitor { + if (--$monitor_cnt) { + return; + } + close_console($monitor_fp, $monitor_pid); +} + +sub wait_for_monitor { + my ($time) = @_; + my $line; + + doprint "Wait for monitor to settle down.\n"; + + # read the monitor and wait for the system to calm down + do { + $line = wait_for_input($monitor_fp, $time); + } while (defined($line)); +} + sub fail { if ($opt{"DIE_ON_FAILURE"}) { @@ -104,6 +175,41 @@ sub fail { } doprint "Failed: ", @_, "\n"; + + doprint "REBOOTING\n"; + reboot; + start_monitor; + wait_for_monitor $opt{"SLEEP_TIME"}; + end_monitor; + + return 1 if (!defined($opt{"STORE_FAILURES"})); + + my @t = localtime; + my $date = sprintf "%04d%02d%02d%02d%02d%02d", + 1900+$t[5],$t[4],$t[3],$t[2],$t[1],$t[0]; + + my $dir = "$opt{MACHINE}-$build_type-fail-$date"; + my $faildir = "$opt{STORE_FAILURES}/$dir"; + + if (!-d $faildir) { + mkpath($faildir) or + die "can't create $opt{STORE_FAILURES}"; + } + if (-f "$opt{OUTPUT_DIR}/.config") { + cp "$opt{OUTPUT_DIR}/.config", "$faildir/config" or + die "failed to copy .config"; + } + if (-f $buildlog) { + cp $buildlog, "$faildir/buildlog" or + die "failed to move $buildlog"; + } + if (-f $dmesg) { + cp $dmesg, "$faildir/dmesg" or + die "failed to move $dmesg"; + } + + doprint "*** Saved info to $faildir ***\n"; + return 1; } @@ -211,64 +317,34 @@ sub reboot_to { run_command "ssh $target '(echo \"savedefault --default=$grub_number --once\" | grub --batch; reboot)'"; } -sub open_console { - my ($fp) = @_; - - my $flags; - - my $pid = open($fp, "$opt{CONSOLE}|") or - dodie "Can't open console $opt{CONSOLE}"; - - $flags = fcntl($fp, F_GETFL, 0) or - dodie "Can't get flags for the socket: $!\n"; - $flags = fcntl($fp, F_SETFL, $flags | O_NONBLOCK) or - dodie "Can't set flags for the socket: $!\n"; - - return $pid; -} - -sub close_console { - my ($fp, $pid) = @_; - - doprint "kill child process $pid\n"; - kill 2, $pid; - - print "closing!\n"; - close($fp); -} - sub monitor { my $booted = 0; my $bug = 0; - my $pid; my $skip_call_trace = 0; - my $fp = \*IN; my $loops; - $pid = open_console($fp); + wait_for_monitor 5; my $line; my $full_line = ""; - doprint "Wait for monitor to settle down.\n"; - # read the monitor and wait for the system to calm down - do { - $line = wait_for_input($fp, 5); - } while (defined($line)); + open(DMESG, "> $dmesg") or + die "unable to write to $dmesg"; reboot_to; for (;;) { if ($booted) { - $line = wait_for_input($fp, $opt{"BOOTED_TIMEOUT"}); + $line = wait_for_input($monitor_fp, $opt{"BOOTED_TIMEOUT"}); } else { - $line = wait_for_input($fp); + $line = wait_for_input($monitor_fp); } last if (!defined($line)); doprint $line; + print DMESG $line; # we are not guaranteed to get a full line $full_line .= $line; @@ -298,7 +374,7 @@ sub monitor { } } - close_console($fp, $pid); + close(DMESG); if (!$booted) { return 0 if ($in_bisect); @@ -363,7 +439,6 @@ sub install { sub check_buildlog { my ($patch) = @_; - my $buildlog = "$opt{TMP_DIR}/buildlog"; my @files = `git show $patch | diffstat -l`; open(IN, "git show $patch |") or @@ -398,6 +473,8 @@ sub build { my $defconfig = ""; my $append = ""; + unlink $buildlog; + if ($type =~ /^useconfig:(.*)/) { run_command "cp $1 $opt{OUTPUT_DIR}/.config" or dodie "could not copy $1 to .config"; @@ -440,11 +517,7 @@ sub build { run_command "$defconfig $append $make $type" or dodie "failed make config"; - # patch check will examine the log - if ($in_patchcheck) { - $redirect = "$opt{TMP_DIR}/buildlog"; - } - + $redirect = "$opt{TMP_DIR}/buildlog"; if (!run_command "$make $opt{BUILD_OPTIONS}") { undef $redirect; # bisect may need this to pass @@ -456,14 +529,6 @@ sub build { return 1; } -sub reboot { - # try to reboot normally - if (!run_command "ssh $target reboot") { - # nope? power cycle it. - run_command "$opt{POWER_CYCLE}"; - } -} - sub halt { if (!run_command "ssh $target halt" or defined($opt{"POWER_OFF"})) { # nope? the zap it! @@ -481,9 +546,11 @@ sub success { doprint "*******************************************\n"; if ($i != $opt{"NUM_BUILDS"}) { + doprint "Reboot and wait $opt{SLEEP_TIME} seconds\n"; reboot; - doprint "Sleeping $opt{SLEEP_TIME} seconds\n"; - sleep "$opt{SLEEP_TIME}"; + start_monitor; + wait_for_monitor $opt{"SLEEP_TIME"}; + end_monitor; } } @@ -496,9 +563,14 @@ sub get_version { } sub child_run_test { - my $failed; + my $failed = 0; - $failed = !run_command $run_test; + # child should have no power + $opt{"REBOOT_ON_ERROR"} = 0; + $opt{"POWEROFF_ON_ERROR"} = 0; + $opt{"DIE_ON_FAILURE"} = 1; + + run_command $run_test or $failed = 1; exit $failed; } @@ -511,18 +583,13 @@ sub child_finished { sub do_run_test { my $child_pid; my $child_exit; - my $pid; my $line; my $full_line; my $bug = 0; - my $fp = \*IN; - $pid = open_console($fp); + wait_for_monitor 1; - # read the monitor and wait for the system to calm down - do { - $line = wait_for_input($fp, 1); - } while (defined($line)); + doprint "run test $run_test\n"; $child_done = 0; @@ -535,7 +602,7 @@ sub do_run_test { $full_line = ""; do { - $line = wait_for_input($fp, 1); + $line = wait_for_input($monitor_fp, 1); if (defined($line)) { # we are not guaranteed to get a full line @@ -564,8 +631,6 @@ sub do_run_test { waitpid $child_pid, 0; $child_exit = $?; - close_console($fp, $pid); - if ($bug || $child_exit) { return 0 if $in_bisect; fail "test failed" and return 0; @@ -589,19 +654,22 @@ sub run_bisect { } if ($type ne "build") { - fail "Failed on build" if $failed; + dodie "Failed on build" if $failed; # Now boot the box get_grub_index; get_version; install; + + start_monitor; monitor or $failed = 1; if ($type ne "boot") { - fail "Failed on boot" if $failed; + dodie "Failed on boot" if $failed; do_run_test or $failed = 1; } + end_monitor; } if ($failed) { @@ -609,9 +677,11 @@ sub run_bisect { # reboot the box to a good kernel if ($type eq "boot") { + doprint "Reboot and sleep $opt{BISECT_SLEEP_TIME} seconds\n"; reboot; - doprint "sleep a little for reboot\n"; - sleep $opt{"BISECT_SLEEP_TIME"}; + start_monitor; + wait_for_monitor $opt{"BISECT_SLEEP_TIME"}; + end_monitor; } } else { $result = "good"; @@ -782,10 +852,18 @@ sub patchcheck { get_grub_index; get_version; install; - monitor or return 0; - next if ($type eq "boot"); - do_run_test or next; + my $failed = 0; + + start_monitor; + monitor or $failed = 1; + + if (!$failed && $type ne "boot"){ + do_run_test or $failed = 1; + } + end_monitor; + return 0 if ($failed); + } $in_patchcheck = 0; success $i; @@ -821,6 +899,8 @@ foreach my $option (sort keys %opt) { doprint "$option = $opt{$option}\n"; } +$buildlog = "$opt{TMP_DIR}/buildlog"; +$dmesg = "$opt{TMP_DIR}/dmesg"; $make = "$opt{MAKE_CMD} O=$opt{OUTPUT_DIR}"; sub set_build_option { @@ -841,19 +921,18 @@ sub set_build_option { # First we need to do is the builds for (my $i = 1; $i <= $opt{"NUM_BUILDS"}; $i++) { - my $type = "BUILD_TYPE[$i]"; - - if (!defined($opt{$type})) { - $opt{$type} = $opt{"DEFAULT_BUILD_TYPE"}; - } + $build_type = set_build_option("BUILD_TYPE", $i); $noclean = set_build_option("BUILD_NOCLEAN", $i); $minconfig = set_build_option("MIN_CONFIG", $i); $run_test = set_build_option("TEST", $i); $addconfig = set_build_option("ADD_CONFIG", $i); doprint "\n\n"; - doprint "RUNNING TEST $i of $opt{NUM_BUILDS} with option $opt{$type}\n\n"; + doprint "RUNNING TEST $i of $opt{NUM_BUILDS} with option $build_type\n\n"; + + unlink $dmesg; + unlink $buildlog; if (!defined($minconfig)) { $minconfig = $addconfig; @@ -870,26 +949,30 @@ for (my $i = 1; $i <= $opt{"NUM_BUILDS"}; $i++) { die "failed to checkout $checkout"; } - if ($opt{$type} eq "bisect") { + if ($build_type eq "bisect") { bisect $i; next; - } elsif ($opt{$type} eq "patchcheck") { + } elsif ($build_type eq "patchcheck") { patchcheck $i; next; } - if ($opt{$type} ne "nobuild") { - build $opt{$type} or next; + if ($build_type ne "nobuild") { + build $build_type or next; } get_grub_index; get_version; install; - monitor or next; - if (defined($run_test)) { - do_run_test or next; + my $failed = 0; + start_monitor; + monitor or $failed = 1;; + if (!$failed && defined($run_test)) { + do_run_test or $failed = 1; } + end_monitor; + next if ($failed); success $i; } -- cgit v1.2.3 From a75fececff3cc1e86d74e98de634ea2ed1b47697 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Tue, 2 Nov 2010 14:58:27 -0400 Subject: ktest: Added sample.conf, new %default option format Added sample.conf as a nice document to show new users. Use a %default hash to separate out the options that are default and allow us to complain about options being set twice. Signed-off-by: Steven Rostedt --- tools/testing/ktest/ktest.pl | 461 +++++++++++++++++++++++++++------------- tools/testing/ktest/sample.conf | 330 ++++++++++++++++++++++++++++ 2 files changed, 649 insertions(+), 142 deletions(-) create mode 100644 tools/testing/ktest/sample.conf diff --git a/tools/testing/ktest/ktest.pl b/tools/testing/ktest/ktest.pl index ff6283a44847..1f28c45f15b8 100644 --- a/tools/testing/ktest/ktest.pl +++ b/tools/testing/ktest/ktest.pl @@ -16,28 +16,45 @@ $#ARGV >= 0 || die "usage: autotest.pl config-file\n"; $| = 1; my %opt; +my %default; #default opts -$opt{"NUM_BUILDS"} = 5; -$opt{"BUILD_TYPE"} = "randconfig"; -$opt{"MAKE_CMD"} = "make"; -$opt{"TIMEOUT"} = 120; -$opt{"TMP_DIR"} = "/tmp/autotest"; -$opt{"SLEEP_TIME"} = 60; # sleep time between tests -$opt{"BUILD_NOCLEAN"} = 0; -$opt{"REBOOT_ON_ERROR"} = 0; -$opt{"POWEROFF_ON_ERROR"} = 0; -$opt{"REBOOT_ON_SUCCESS"} = 1; -$opt{"POWEROFF_ON_SUCCESS"} = 0; -$opt{"BUILD_OPTIONS"} = ""; -$opt{"BISECT_SLEEP_TIME"} = 10; # sleep time between bisects -$opt{"CLEAR_LOG"} = 0; -$opt{"SUCCESS_LINE"} = "login:"; -$opt{"BOOTED_TIMEOUT"} = 1; -$opt{"DIE_ON_FAILURE"} = 1; +$default{"NUM_TESTS"} = 5; +$default{"REBOOT_TYPE"} = "grub"; +$default{"TEST_TYPE"} = "test"; +$default{"BUILD_TYPE"} = "randconfig"; +$default{"MAKE_CMD"} = "make"; +$default{"TIMEOUT"} = 120; +$default{"TMP_DIR"} = "/tmp/autotest"; +$default{"SLEEP_TIME"} = 60; # sleep time between tests +$default{"BUILD_NOCLEAN"} = 0; +$default{"REBOOT_ON_ERROR"} = 0; +$default{"POWEROFF_ON_ERROR"} = 0; +$default{"REBOOT_ON_SUCCESS"} = 1; +$default{"POWEROFF_ON_SUCCESS"} = 0; +$default{"BUILD_OPTIONS"} = ""; +$default{"BISECT_SLEEP_TIME"} = 60; # sleep time between bisects +$default{"CLEAR_LOG"} = 0; +$default{"SUCCESS_LINE"} = "login:"; +$default{"BOOTED_TIMEOUT"} = 1; +$default{"DIE_ON_FAILURE"} = 1; my $version; +my $machine; +my $tmpdir; +my $builddir; +my $outputdir; +my $test_type; my $build_type; +my $build_options; +my $reboot_type; +my $reboot_script; +my $power_cycle; +my $reboot_on_error; +my $poweroff_on_error; +my $die_on_failure; +my $power_off; +my $grub_menu; my $grub_number; my $target; my $make; @@ -55,6 +72,16 @@ my $dmesg; my $monitor_fp; my $monitor_pid; my $monitor_cnt = 0; +my $sleep_time; +my $bisect_sleep_time; +my $store_failures; +my $timeout; +my $booted_timeout; +my $console; +my $success_line; +my $build_target; +my $target_image; +my $localversion; sub read_config { my ($config) = @_; @@ -70,11 +97,22 @@ sub read_config { my $lvalue = $1; my $rvalue = $2; + if (defined($opt{$lvalue})) { + die "Error: Option $lvalue defined more than once!\n"; + } $opt{$lvalue} = $rvalue; } } close(IN); + + # set any defaults + + foreach my $default (keys %default) { + if (!defined($opt{$default})) { + $opt{$default} = $default{$default}; + } + } } sub logit { @@ -96,20 +134,20 @@ sub reboot { # try to reboot normally if (!run_command "ssh $target reboot") { # nope? power cycle it. - run_command "$opt{POWER_CYCLE}"; + run_command "$power_cycle"; } } sub dodie { doprint "CRITICAL FAILURE... ", @_, "\n"; - if ($opt{"REBOOT_ON_ERROR"}) { + if ($reboot_on_error && $test_type ne "build") { doprint "REBOOTING\n"; reboot; - } elsif ($opt{"POWEROFF_ON_ERROR"} && defined($opt{"POWER_OFF"})) { + } elsif ($poweroff_on_error && defined($power_off)) { doprint "POWERING OFF\n"; - `$opt{"POWER_OFF"}`; + `$power_off`; } die @_; @@ -120,8 +158,8 @@ sub open_console { my $flags; - my $pid = open($fp, "$opt{CONSOLE}|") or - dodie "Can't open console $opt{CONSOLE}"; + my $pid = open($fp, "$console|") or + dodie "Can't open console $console"; $flags = fcntl($fp, F_GETFL, 0) or dodie "Can't get flags for the socket: $!\n"; @@ -147,6 +185,10 @@ sub start_monitor { } $monitor_fp = \*MONFD; $monitor_pid = open_console $monitor_fp; + + return; + + open(MONFD, "Stop perl from warning about single use of MONFD"); } sub end_monitor { @@ -160,43 +202,50 @@ sub wait_for_monitor { my ($time) = @_; my $line; - doprint "Wait for monitor to settle down.\n"; + doprint "** Wait for monitor to settle down **\n"; # read the monitor and wait for the system to calm down do { $line = wait_for_input($monitor_fp, $time); + print "$line" if (defined($line)); } while (defined($line)); + print "** Monitor flushed **\n"; } sub fail { - if ($opt{"DIE_ON_FAILURE"}) { + if ($die_on_failure) { dodie @_; } - doprint "Failed: ", @_, "\n"; + doprint "FAILED\n"; - doprint "REBOOTING\n"; - reboot; - start_monitor; - wait_for_monitor $opt{"SLEEP_TIME"}; - end_monitor; + # no need to reboot for just building. + if ($test_type ne "build") { + doprint "REBOOTING\n"; + reboot; + start_monitor; + wait_for_monitor $sleep_time; + end_monitor; + } - return 1 if (!defined($opt{"STORE_FAILURES"})); + doprint "**** Failed: ", @_, " ****\n"; + + return 1 if (!defined($store_failures)); my @t = localtime; my $date = sprintf "%04d%02d%02d%02d%02d%02d", 1900+$t[5],$t[4],$t[3],$t[2],$t[1],$t[0]; - my $dir = "$opt{MACHINE}-$build_type-fail-$date"; - my $faildir = "$opt{STORE_FAILURES}/$dir"; + my $dir = "$machine-$test_type-$build_type-fail-$date"; + my $faildir = "$store_failures/$dir"; if (!-d $faildir) { mkpath($faildir) or - die "can't create $opt{STORE_FAILURES}"; + die "can't create $faildir"; } - if (-f "$opt{OUTPUT_DIR}/.config") { - cp "$opt{OUTPUT_DIR}/.config", "$faildir/config" or + if (-f "$outputdir/.config") { + cp "$outputdir/.config", "$faildir/config" or die "failed to copy .config"; } if (-f $buildlog) { @@ -259,6 +308,9 @@ sub run_command { sub get_grub_index { + if ($reboot_type ne "grub") { + return; + } return if (defined($grub_number)); doprint "Find grub menu ... "; @@ -266,7 +318,7 @@ sub get_grub_index { open(IN, "ssh $target cat /boot/grub/menu.lst |") or die "unable to get menu.lst"; while () { - if (/^\s*title\s+$opt{GRUB_MENU}\s*$/) { + if (/^\s*title\s+$grub_menu\s*$/) { $grub_number++; last; } elsif (/^\s*title\s/) { @@ -275,13 +327,11 @@ sub get_grub_index { } close(IN); - die "Could not find '$opt{GRUB_MENU}' in /boot/grub/menu on $opt{MACHINE}" + die "Could not find '$grub_menu' in /boot/grub/menu on $machine" if ($grub_number < 0); doprint "$grub_number\n"; } -my $timeout = $opt{"TIMEOUT"}; - sub wait_for_input { my ($fp, $time) = @_; @@ -314,7 +364,12 @@ sub wait_for_input } sub reboot_to { - run_command "ssh $target '(echo \"savedefault --default=$grub_number --once\" | grub --batch; reboot)'"; + if ($reboot_type eq "grub") { + run_command "ssh $target '(echo \"savedefault --default=$grub_number --once\" | grub --batch; reboot)'"; + return; + } + + run_command "$reboot_script"; } sub monitor { @@ -336,7 +391,7 @@ sub monitor { for (;;) { if ($booted) { - $line = wait_for_input($monitor_fp, $opt{"BOOTED_TIMEOUT"}); + $line = wait_for_input($monitor_fp, $booted_timeout); } else { $line = wait_for_input($monitor_fp); } @@ -349,7 +404,7 @@ sub monitor { # we are not guaranteed to get a full line $full_line .= $line; - if ($full_line =~ /$opt{"SUCCESS_LINE"}/) { + if ($full_line =~ /$success_line/) { $booted = 1; } @@ -376,14 +431,14 @@ sub monitor { close(DMESG); - if (!$booted) { + if ($bug) { return 0 if ($in_bisect); - fail "failed - never got a boot prompt.\n" and return 0; + fail "failed - got a bug report\n" and return 0; } - if ($bug) { + if (!$booted) { return 0 if ($in_bisect); - fail "failed - got a bug report\n" and return 0; + fail "failed - never got a boot prompt.\n" and return 0; } return 1; @@ -391,14 +446,14 @@ sub monitor { sub install { - run_command "scp $opt{OUTPUT_DIR}/$opt{BUILD_TARGET} $target:$opt{TARGET_IMAGE}" or + run_command "scp $outputdir/$build_target $target:$target_image" or dodie "failed to copy image"; my $install_mods = 0; # should we process modules? $install_mods = 0; - open(IN, "$opt{OUTPUT_DIR}/.config") or dodie("Can't read config file"); + open(IN, "$outputdir/.config") or dodie("Can't read config file"); while () { if (/CONFIG_MODULES(=y)?/) { $install_mods = 1 if (defined($1)); @@ -412,7 +467,7 @@ sub install { return; } - run_command "$make INSTALL_MOD_PATH=$opt{TMP_DIR} modules_install" or + run_command "$make INSTALL_MOD_PATH=$tmpdir modules_install" or dodie "Failed to install modules"; my $modlib = "/lib/modules/$version"; @@ -422,13 +477,13 @@ sub install { dodie "failed to remove old mods: $modlib"; # would be nice if scp -r did not follow symbolic links - run_command "cd $opt{TMP_DIR} && tar -cjf $modtar lib/modules/$version" or + run_command "cd $tmpdir && tar -cjf $modtar lib/modules/$version" or dodie "making tarball"; - run_command "scp $opt{TMP_DIR}/$modtar $target:/tmp" or + run_command "scp $tmpdir/$modtar $target:/tmp" or dodie "failed to copy modules"; - unlink "$opt{TMP_DIR}/$modtar"; + unlink "$tmpdir/$modtar"; run_command "ssh $target '(cd / && tar xf /tmp/$modtar)'" or dodie "failed to tar modules"; @@ -456,7 +511,7 @@ sub check_buildlog { if (/^\s*(.*?):.*(warning|error)/) { my $err = $1; foreach my $file (@files) { - my $fullpath = "$opt{BUILD_DIR}/$file"; + my $fullpath = "$builddir/$file"; if ($file eq $err || $fullpath eq $err) { fail "$file built with warnings" and return 0; } @@ -476,7 +531,7 @@ sub build { unlink $buildlog; if ($type =~ /^useconfig:(.*)/) { - run_command "cp $1 $opt{OUTPUT_DIR}/.config" or + run_command "cp $1 $outputdir/.config" or dodie "could not copy $1 to .config"; $type = "oldconfig"; @@ -487,38 +542,38 @@ sub build { $append = "yes ''|"; # allow for empty configs - run_command "touch $opt{OUTPUT_DIR}/.config"; + run_command "touch $outputdir/.config"; - run_command "mv $opt{OUTPUT_DIR}/.config $opt{OUTPUT_DIR}/config_temp" or + run_command "mv $outputdir/.config $outputdir/config_temp" or dodie "moving .config"; if (!$noclean && !run_command "$make mrproper") { dodie "make mrproper"; } - run_command "mv $opt{OUTPUT_DIR}/config_temp $opt{OUTPUT_DIR}/.config" or + run_command "mv $outputdir/config_temp $outputdir/.config" or dodie "moving config_temp"; } elsif (!$noclean) { - unlink "$opt{OUTPUT_DIR}/.config"; + unlink "$outputdir/.config"; run_command "$make mrproper" or dodie "make mrproper"; } # add something to distinguish this build - open(OUT, "> $opt{OUTPUT_DIR}/localversion") or dodie("Can't make localversion file"); - print OUT "$opt{LOCALVERSION}\n"; + open(OUT, "> $outputdir/localversion") or dodie("Can't make localversion file"); + print OUT "$localversion\n"; close(OUT); if (defined($minconfig)) { $defconfig = "KCONFIG_ALLCONFIG=$minconfig"; } - run_command "$defconfig $append $make $type" or + run_command "$append $defconfig $make $type" or dodie "failed make config"; - $redirect = "$opt{TMP_DIR}/buildlog"; - if (!run_command "$make $opt{BUILD_OPTIONS}") { + $redirect = "$buildlog"; + if (!run_command "$make $build_options") { undef $redirect; # bisect may need this to pass return 0 if ($in_bisect); @@ -530,9 +585,9 @@ sub build { } sub halt { - if (!run_command "ssh $target halt" or defined($opt{"POWER_OFF"})) { + if (!run_command "ssh $target halt" or defined($power_off)) { # nope? the zap it! - run_command "$opt{POWER_OFF}"; + run_command "$power_off"; } } @@ -541,15 +596,17 @@ sub success { doprint "\n\n*******************************************\n"; doprint "*******************************************\n"; - doprint "** SUCCESS!!!! **\n"; + doprint "** TEST $i SUCCESS!!!! **\n"; doprint "*******************************************\n"; doprint "*******************************************\n"; - if ($i != $opt{"NUM_BUILDS"}) { - doprint "Reboot and wait $opt{SLEEP_TIME} seconds\n"; + if ($i != $opt{"NUM_TESTS"} && $test_type ne "build" && + !($test_type eq "patchcheck" && $opt{"PATCHCHECK_TYPE[$i]"} eq "build") && + !($test_type eq "bisect" && $opt{"BISECT_TYPE[$i]"} eq "build")) { + doprint "Reboot and wait $sleep_time seconds\n"; reboot; start_monitor; - wait_for_monitor $opt{"SLEEP_TIME"}; + wait_for_monitor $sleep_time; end_monitor; } } @@ -566,9 +623,9 @@ sub child_run_test { my $failed = 0; # child should have no power - $opt{"REBOOT_ON_ERROR"} = 0; - $opt{"POWEROFF_ON_ERROR"} = 0; - $opt{"DIE_ON_FAILURE"} = 1; + $reboot_on_error = 0; + $poweroff_on_error = 0; + $die_on_failure = 1; run_command $run_test or $failed = 1; exit $failed; @@ -638,6 +695,36 @@ sub do_run_test { return 1; } +sub run_git_bisect { + my ($command) = @_; + + doprint "$command ... "; + + my $output = `$command 2>&1`; + my $ret = $?; + + logit $output; + + if ($ret) { + doprint "FAILED\n"; + dodie "Failed to git bisect"; + } + + doprint "SUCCESS\n"; + if ($output =~ m/^(Bisecting: .*\(roughly \d+ steps?\))\s+\[([[:xdigit:]]+)\]/) { + doprint "$1 [$2]\n"; + } elsif ($output =~ m/^([[:xdigit:]]+) is the first bad commit/) { + $bisect_bad = $1; + doprint "Found bad commit... $1\n"; + return 0; + } else { + # we already logged it, just print it now. + print $output; + } + + return 1; +} + sub run_bisect { my ($type) = @_; @@ -676,11 +763,11 @@ sub run_bisect { $result = "bad"; # reboot the box to a good kernel - if ($type eq "boot") { - doprint "Reboot and sleep $opt{BISECT_SLEEP_TIME} seconds\n"; + if ($type ne "build") { + doprint "Reboot and sleep $bisect_sleep_time seconds\n"; reboot; start_monitor; - wait_for_monitor $opt{"BISECT_SLEEP_TIME"}; + wait_for_monitor $bisect_sleep_time; end_monitor; } } else { @@ -696,31 +783,7 @@ sub run_bisect { } } - doprint "git bisect $result ... "; - $output = `git bisect $result 2>&1`; - $ret = $?; - - logit $output; - - if ($ret) { - doprint "FAILED\n"; - fail "Failed to git bisect"; - } - - doprint "SUCCESS\n"; - if ($output =~ m/^(Bisecting: .*\(roughly \d+ steps?\))\s+\[([[:xdigit:]]+)\]/) { - doprint "$1 [$2]\n"; - } elsif ($output =~ m/^([[:xdigit:]]+) is the first bad commit/) { - $bisect_bad = $1; - doprint "Found bad commit... $1\n"; - return 0; - } else { - # we already logged it, just print it now. - print $output; - } - - - return 1; + return $result; } sub bisect { @@ -735,6 +798,8 @@ sub bisect { my $good = $opt{"BISECT_GOOD[$i]"}; my $bad = $opt{"BISECT_BAD[$i]"}; my $type = $opt{"BISECT_TYPE[$i]"}; + my $start = $opt{"BISECT_START[$i]"}; + my $replay = $opt{"BISECT_REPLAY[$i]"}; if (defined($opt{"BISECT_REVERSE[$i]"}) && $opt{"BISECT_REVERSE[$i]"} == 1) { @@ -746,23 +811,83 @@ sub bisect { $in_bisect = 1; + # Can't have a test without having a test to run + if ($type eq "test" && !defined($run_test)) { + $type = "boot"; + } + + my $check = $opt{"BISECT_CHECK[$i]"}; + if (defined($check) && $check ne "0") { + + # get current HEAD + doprint "git rev-list HEAD --max-count=1 ... "; + my $head = `git rev-list HEAD --max-count=1`; + my $ret = $?; + + logit $head; + + if ($ret) { + doprint "FAILED\n"; + dodie "Failed to get git HEAD"; + } + + print "SUCCESS\n"; + + chomp $head; + + if ($check ne "good") { + doprint "TESTING BISECT BAD [$bad]\n"; + run_command "git checkout $bad" or + die "Failed to checkout $bad"; + + $result = run_bisect $type; + + if ($result ne "bad") { + fail "Tested BISECT_BAD [$bad] and it succeeded" and return 0; + } + } + + if ($check ne "bad") { + doprint "TESTING BISECT GOOD [$good]\n"; + run_command "git checkout $good" or + die "Failed to checkout $good"; + + $result = run_bisect $type; + + if ($result ne "good") { + fail "Tested BISECT_GOOD [$good] and it failed" and return 0; + } + } + + # checkout where we started + run_command "git checkout $head" or + die "Failed to checkout $head"; + } + run_command "git bisect start" or - fail "could not start bisect"; + dodie "could not start bisect"; run_command "git bisect good $good" or - fail "could not set bisect good to $good"; + dodie "could not set bisect good to $good"; - run_command "git bisect bad $bad" or - fail "could not set bisect good to $bad"; + run_git_bisect "git bisect bad $bad" or + dodie "could not set bisect bad to $bad"; - # Can't have a test without having a test to run - if ($type eq "test" && !defined($run_test)) { - $type = "boot"; + if (defined($replay)) { + run_command "git bisect replay $replay" or + dodie "failed to run replay"; } + if (defined($start)) { + run_command "git checkout $start" or + dodie "failed to checkout $start"; + } + + my $test; do { $result = run_bisect $type; - } while ($result); + $test = run_git_bisect "git bisect $result"; + } while ($test); run_command "git bisect log" or dodie "could not capture git bisect log"; @@ -883,11 +1008,6 @@ die "TARGET_IMAGE not defined\n" if (!defined($opt{"TARGET_IMAGE"})); die "POWER_CYCLE not defined\n" if (!defined($opt{"POWER_CYCLE"})); die "CONSOLE not defined\n" if (!defined($opt{"CONSOLE"})); die "LOCALVERSION not defined\n" if (!defined($opt{"LOCALVERSION"})); -die "GRUB_MENU not defined\n" if (!defined($opt{"GRUB_MENU"})); - -chdir $opt{"BUILD_DIR"} || die "can't change directory to $opt{BUILD_DIR}"; - -$target = "$opt{SSH_USER}\@$opt{MACHINE}"; if ($opt{"CLEAR_LOG"} && defined($opt{"LOG_FILE"})) { unlink $opt{"LOG_FILE"}; @@ -899,11 +1019,7 @@ foreach my $option (sort keys %opt) { doprint "$option = $opt{$option}\n"; } -$buildlog = "$opt{TMP_DIR}/buildlog"; -$dmesg = "$opt{TMP_DIR}/dmesg"; -$make = "$opt{MAKE_CMD} O=$opt{OUTPUT_DIR}"; - -sub set_build_option { +sub set_test_option { my ($name, $i) = @_; my $option = "$name\[$i\]"; @@ -920,16 +1036,74 @@ sub set_build_option { } # First we need to do is the builds -for (my $i = 1; $i <= $opt{"NUM_BUILDS"}; $i++) { +for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) { + + my $ssh_user = set_test_option("SSH_USER", $i); + my $makecmd = set_test_option("MAKE_CMD", $i); + + $machine = set_test_option("MACHINE", $i); + $tmpdir = set_test_option("TMP_DIR", $i); + $outputdir = set_test_option("OUTPUT_DIR", $i); + $builddir = set_test_option("BUILD_DIR", $i); + $test_type = set_test_option("TEST_TYPE", $i); + $build_type = set_test_option("BUILD_TYPE", $i); + $build_options = set_test_option("BUILD_OPTIONS", $i); + $power_cycle = set_test_option("POWER_CYCLE", $i); + $noclean = set_test_option("BUILD_NOCLEAN", $i); + $minconfig = set_test_option("MIN_CONFIG", $i); + $run_test = set_test_option("TEST", $i); + $addconfig = set_test_option("ADD_CONFIG", $i); + $reboot_type = set_test_option("REBOOT_TYPE", $i); + $grub_menu = set_test_option("GRUB_MENU", $i); + $reboot_script = set_test_option("REBOOT_SCRIPT", $i); + $reboot_on_error = set_test_option("REBOOT_ON_ERROR", $i); + $poweroff_on_error = set_test_option("POWEROFF_ON_ERROR", $i); + $die_on_failure = set_test_option("DIE_ON_FAILURE", $i); + $power_off = set_test_option("POWER_OFF", $i); + $sleep_time = set_test_option("SLEEP_TIME", $i); + $bisect_sleep_time = set_test_option("BISECT_SLEEP_TIME", $i); + $store_failures = set_test_option("STORE_FAILURES", $i); + $timeout = set_test_option("TIMEOUT", $i); + $booted_timeout = set_test_option("BOOTED_TIMEOUT", $i); + $console = set_test_option("CONSOLE", $i); + $success_line = set_test_option("SUCCESS_LINE", $i); + $build_target = set_test_option("BUILD_TARGET", $i); + $target_image = set_test_option("TARGET_IMAGE", $i); + $localversion = set_test_option("LOCALVERSION", $i); + + chdir $builddir || die "can't change directory to $builddir"; + + if (!-d $tmpdir) { + mkpath($tmpdir) or + die "can't create $tmpdir"; + } - $build_type = set_build_option("BUILD_TYPE", $i); - $noclean = set_build_option("BUILD_NOCLEAN", $i); - $minconfig = set_build_option("MIN_CONFIG", $i); - $run_test = set_build_option("TEST", $i); - $addconfig = set_build_option("ADD_CONFIG", $i); + $target = "$ssh_user\@$machine"; + + $buildlog = "$tmpdir/buildlog-$machine"; + $dmesg = "$tmpdir/dmesg-$machine"; + $make = "$makecmd O=$outputdir"; + + if ($reboot_type eq "grub") { + dodie "GRUB_MENU not defined\n" if (!defined($grub_menu)); + } elsif (!defined($reboot_script)) { + dodie "REBOOT_SCRIPT not defined\n" + } + + my $run_type = $build_type; + if ($test_type eq "patchcheck") { + $run_type = $opt{"PATCHCHECK_TYPE[$i]"}; + } elsif ($test_type eq "bisect") { + $run_type = $opt{"BISECT_TYPE[$i]"}; + } + + # mistake in config file? + if (!defined($run_type)) { + $run_type = "ERROR"; + } doprint "\n\n"; - doprint "RUNNING TEST $i of $opt{NUM_BUILDS} with option $build_type\n\n"; + doprint "RUNNING TEST $i of $opt{NUM_TESTS} with option $test_type $run_type\n\n"; unlink $dmesg; unlink $buildlog; @@ -938,9 +1112,9 @@ for (my $i = 1; $i <= $opt{"NUM_BUILDS"}; $i++) { $minconfig = $addconfig; } elsif (defined($addconfig)) { - run_command "cat $addconfig $minconfig > $opt{TMP_DIR}/use_config" or + run_command "cat $addconfig $minconfig > $tmpdir/use_config" or dodie "Failed to create temp config"; - $minconfig = "$opt{TMP_DIR}/use_config"; + $minconfig = "$tmpdir/use_config"; } my $checkout = $opt{"CHECKOUT[$i]"}; @@ -949,10 +1123,10 @@ for (my $i = 1; $i <= $opt{"NUM_BUILDS"}; $i++) { die "failed to checkout $checkout"; } - if ($build_type eq "bisect") { + if ($test_type eq "bisect") { bisect $i; next; - } elsif ($build_type eq "patchcheck") { + } elsif ($test_type eq "patchcheck") { patchcheck $i; next; } @@ -961,25 +1135,28 @@ for (my $i = 1; $i <= $opt{"NUM_BUILDS"}; $i++) { build $build_type or next; } - get_grub_index; - get_version; - install; + if ($test_type ne "build") { + get_grub_index; + get_version; + install; - my $failed = 0; - start_monitor; - monitor or $failed = 1;; - if (!$failed && defined($run_test)) { - do_run_test or $failed = 1; + my $failed = 0; + start_monitor; + monitor or $failed = 1;; + + if (!$failed && $test_type ne "boot" && defined($run_test)) { + do_run_test or $failed = 1; + } + end_monitor; + next if ($failed); } - end_monitor; - next if ($failed); success $i; } if ($opt{"POWEROFF_ON_SUCCESS"}) { halt; -} elsif ($opt{"REBOOT_ON_SUCCESS"}) { +} elsif ($opt{"REBOOT_ON_SUCCESS"} && $test_type ne "build") { reboot; } diff --git a/tools/testing/ktest/sample.conf b/tools/testing/ktest/sample.conf new file mode 100644 index 000000000000..42f803fe4a8d --- /dev/null +++ b/tools/testing/ktest/sample.conf @@ -0,0 +1,330 @@ +# +# Config file for autotest.pl +# +# Note, all paths must be absolute +# + +# Almost all options may be overwritten per test run, by appending +# a [x] to the config. For example, to change the test type for +# the third iteration of tests, you can specify: +# (1 is for the first test, 2 for the second, and so on) +# +# TEST_TYPE[3] = build +# +# The options that can not be changed like this are: +# NUM_TESTS +# LOG_FILE +# CLEAR_LOG +# POWEROFF_ON_SUCCESS +# REBOOT_ON_SUCCESS +# + +#### Mandatory Config Options #### + +# The machine hostname that you will test +#MACHINE = target + +# The box is expected to have ssh on normal bootup, provide the user +# (most likely root, since you need privileged operations) +#SSH_USER = root + +# The directory that contains the Linux source code +#BUILD_DIR = /home/test/linux.git + +# The directory that the objects will be built +# (can not be same as BUILD_DIR) +#OUTPUT_DIR = /home/test/build/target + +# The location of the compiled file to copy to the target +# (relative to OUTPUT_DIR) +#BUILD_TARGET = arch/x86/boot/bzImage + +# The place to put your image on the test machine +#TARGET_IMAGE = /boot/vmlinuz-test + +# A script or command to reboot the box +# Here is a digital loggers power switch example +#POWER_CYCLE = wget --no-proxy -O /dev/null -q --auth-no-challenge 'http://admin:admin@power/outlet?5=CCL' +# Here is an example to reboot a virtual box on the current host +# with the name "Guest". +#POWER_CYCLE = virsh list | grep '\' | awk '{printf ("%d", $1)}' | xargs virsh destroy; sleep 5; virsh start Guest + +# The script or command that reads the console +# If you use ttywatch server, something like the following would work. +#CONSOLE = nc -d localhost 3001 +# For a virtual machine with guest name "Guest". +#CONSOLE = virsh console `virsh list | grep '\' | awk '{printf ("%d", $1)}'` + +# Required version ending to differentiate the test +# from other linux builds on the system. +#LOCALVERSION = -test + +# The grub title name for the test kernel to boot +# (Only mandatory if REBOOT_TYPE = grub) +# +# For example, if in the /boot/grub/menu.lst the test kernel title has: +# title Test Kernel +#GRUB_MENU = Test Kernel + +# A script to reboot the target into the test kernel +# (Only mandatory if REBOOT_TYPE = script) +#REBOOT_SCRIPT = + +#### Optional Config Options (all have defaults) #### + +# The number of tests to run (default 5) +#NUM_TESTS = 5 + +# The default test type (default test) +# The test types may be: +# build - only build the kernel, do nothing else +# boot - build and boot the kernel +# test - build, boot and if TEST is set, run the test script +# bisect - Perform a bisect on the kernel (see BISECT_TYPE below) +# patchcheck - Do a test on a series of commits in git (see PATCHCHECK below) +#TEST_TYPE = test + +# The build type is any make config type or a command. +# (default randconfig) +# nobuild - skip the clean and build step +#BUILD_TYPE = randconfig + +# The make command (default make) +# If you are building a 32bit x86 on a 64 bit host +#MAKE_CMD = CC=i386-gcc AS=i386-as make ARCH=i386 + +# Way to reboot the box to the test kernel. +# Only valid options so far are "grub" and "script" +# (default grub) +# If you specify grub, it will assume grub version 1 +# and will search in /boot/grub/menu.lst for the title $GRUB_MENU +# and select that target to reboot to the kernel. If this is not +# your setup, then specify "script" and have a command or script +# specified in REBOOT_SCRIPT to boot to the target. +#REBOOT_TYPE = grub + +# Line to define success in output. (default "login:") +# This is what the line contains, not the entire line. If you need +# the entire line to match, then use regural expression syntax like +# ^MyBox Login:$ +#SUCCESS_LINE = login: + +# As the test reads the console, after it hits the SUCCESS_LINE +# the time it waits for the monitor to settle down between reads +# can usually be lowered. +# (in seconds) (default 1) +#BOOTED_TIMEOUT = 1 + +# The timeout in seconds when we consider the box hung after +# the console stop producing output. +# (default 120) +#TIMEOUT = 120 + +# The location on the host where to write temp files +# (default /tmp/autotest) +#TMP_DIR = /tmp/autotest + +# In between tests, a reboot of the box may occur, and this +# is the time to wait for the console after it stops producing +# output. Some machines may not produce a large lag on reboot +# so this should accommodate it. +# (default 60) +#SLEEP_TIME = 60 + +# The time in between bisects to sleep (in seconds) +# Can be less than SLEEP_TIME since bisects do more work +# in between boots. (default 60) +#BISECT_SLEEP_TIME = 60 + +# Build without doing a make mrproper, or removing .config +# (default 0) +#BUILD_NOCLEAN = 0 + +# Reboot the target box on error (default 0) +#REBOOT_ON_ERROR = 0 + +# Power off the target on error (ignored if REBOOT_ON_ERROR is set) +# (default 0) +#POWEROFF_ON_ERROR = 0 + +# Power off the target after all tests have completed successfully +# (default 0) +#POWEROFF_ON_SUCCESS = 0 + +# Reboot the target after all test completed successfully (default 1) +# (ignored if POWEROFF_ON_SUCCESS is set) +#REBOOT_ON_SUCCESS = 1 + +# Stop testing if a build fails. If set, the script will end if +# a failure is detected, otherwise it will save off the .config, +# dmesg and bootlog in a directory called +# MACHINE-TEST_TYPE_BUILD_TYPE-fail-yyyymmddhhmmss +# if the STORE_FAILURES directory is set. +# (default 1) +# Note, even if this is set to zero, there are some errors that still +# stop the tests. +#DIE_ON_FAILURE = 1 + +# Directory to store failure directories on failure. If this is not +# set, DIE_ON_FAILURE=0 will not save off the .config, dmesg and +# bootlog. +#STORE_FAILURES = /home/test/failures + +# A script or command to power off the box (default undef) +# Needed for POWEROFF_ON_ERROR and SUCCESS +# Example for digital loggers power switch: +#POWER_OFF = wget --no-proxy -O /dev/null -q --auth-no-challenge 'http://admin:admin@power/outlet?5=OFF' +# Example for a virtual guest call "Guest". +#POWER_OFF = virsh list | grep '\' | awk '{printf ("%d", $1)}' | xargs virsh destroy + +# Any build options for the make (default "") +#BUILD_OPTIONS = -j20 + +# Optional log file to write the status (recommended) +# (default undef) +#LOG_FILE = /home/test/logfiles/target.log + +# Remove old logfile if it exists before starting all tests. +# (default 0) +#CLEAR_LOG = 0 + +# Test to run if there is a successful boot and TEST_TYPE is test. +# Must exit with 0 on success and non zero on error +# default (undef) +#TEST = ssh user@machine /root/run_test +#TEST[1] = ssh root@mxtest /root/run_test + +# The min config that is needed to build for the machine +# A nice way to get this to work, is to do a "lsmod > mymods" on the target +# copy it to the build server, and then run "make LSMOD=mymods localyesconfig". +# Then copy all the options that are set: "grep '^CONFIG' > /home/test/config-min" +# +# You might want to set: +# CONFIG_CMDLINE="" +# randconfig may set the above and override your real command +# line options. +# (default undef) +#MIN_CONFIG = /home/test/config-min + +# Sometimes there's options that just break the boot and +# you do not care about. Here are a few: +# # CONFIG_STAGING is not set +# Staging drivers are horrible, and can break the build. +# # CONFIG_SCSI_DEBUG is not set +# SCSI_DEBUG may change your root partition +# # CONFIG_KGDB_SERIAL_CONSOLE is not set +# KGDB may cause oops waiting for a connection that's not there. +# This option points to the file containing config options that will be prepended +# to the MIN_CONFIG (or be the MIN_CONFIG if it is not set) +# before running it through randconfig +# (default undef) +#ADD_CONFIG = /home/test/config-broken + +#### Per test run options #### +# These are options are per build only. The only exist with the [x] +# syntax, and there is no general option. +# +# All are optional and undef by default +# +# CHECKOUT[x] = branch +# +# If the BUILD_DIR is a git repository, then you can set this option +# to checkout the given branch before running the TEST. If you +# specify this for the first run, that branch will be used for +# all preceding tests until a new CHECKOUT[x] is set. +# +# For TEST_TYPE[x] = patchcheck +# +# This expects the BUILD_DIR to be a git repository, and +# will checkout the PATCHCHECK_START[x]. +# +# PATCHCHECK_START[x] is required and is the first patch to +# test (the SHA1 of the commit). +# +# PATCHCHECK_END[x] is the last patch to check (default HEAD) +# +# PATCHCHECK_TYPE[x] is required and is the type of test to run: +# build, boot, test. +# +# Note, the build test will look for warnings, if a warning occurred +# in a file that a commit touches, the build will fail. +# +# If BUILD_NOCLEAN is set, then make mrproper will not be run on +# any of the builds, just like all other TEST_TYPE tests. But +# what makes patchcheck different from the other tests, is if +# BUILD_NOCLEAN is not set, only the first and last patch run +# make mrproper. This helps speed up the test. +# +# Example: +# TEST_TYPE[1] = patchcheck +# CHECKOUT[1] = mybranch +# PATCHCHECK_TYPE[1] = boot +# PATCHCHECK_START[1] = 747e94ae3d1b4c9bf5380e569f614eb9040b79e7 +# PATCHCHEKC_END[1] = b8b2663bd7c9da04ac804659b9f617c199d0252c +# +# +# For TEST_TYPE[x] = bisect +# +# You can specify a git bisect if the BUILD_DIR is a git repository. +# The MIN_CONFIG will be used for all builds of the bisect. The build type +# used for bisecting is oldconfig. +# +# BISECT_TYPE[x] is the type of test to perform: +# build - bad fails to build +# boot - bad builds but fails to boot +# test - bad boots but fails a test +# +# BISECT_GOOD[x] is the commit (SHA1) to label as good +# BISECT_BAD[x] is the commit to label as bad +# +# The above three options are required for a bisect operation. +# +# BISECT_REPLAY[x] = /path/to/replay/file (optional, default undefined) +# +# If an operation failed in the bisect that was not expected to +# fail. Then the test ends. The state of the BUILD_DIR will be +# left off at where the failur occurred. You can examine the +# reason for the failure, and perhaps even find a git commit +# that would work to continue with. You can run: +# +# git bisect log > /path/to/replay/file +# +# and if BISECT_REPLAY[x] is set, the test will run git bisect replay +# before continuing with the bisect. +# +# BISECT_START[x] = commit (optional, default undefined) +# +# As with BISECT_REPLAY[x], if the test failed on a commit that +# just happen to have a bad commit in the middle of the bisect, +# and you need to skip it. If BISECT_START[x] is defined, it +# will checkout that commit before continuing with the bisect. +# +# Note, BISECT_REPLAY[x] is executed before BISECT_START[x]. +# +# BISECT_REVERSE[x] = 1 (optional, default 0) +# +# In those strange instances where it was broken forever +# and you are trying to find where it started to work! +# Set BISECT_GOOD[x] to the commit that was last known to fail +# Set BISECT_BAD[x] to the commit that is known where it started +# to work. With BISECT_REVERSE[x] = 1, The test will consider +# failures as good, and success as bad. +# +# BISECT_CHECK[x] = 1 (optional, default 0) +# +# Just to be sure the good is good and bad is bad, setting +# BISECT_CHECK[x] to 1 will start the bisect by first checking +# out BISECT_BAD[x] and makes sure it fails, then it will check +# out BISECT_GOOD[x] and makes sure it succeeds before starting +# the bisect (it works for BISECT_REVERSE[x] too). +# +# You can limit the test to just check BISECT_GOOD[x] or +# BISECT_BAD[x] with BISECT_CHECK[x] = good or +# BISECT_CHECK[x] = bad, respectively. +# +# Example: +# TEST_TYPE[1] = bisect +# BISECT_GOOD[1] = v2.6.36 +# BISECT_BAD[1] = b5153163ed580e00c67bdfecb02b2e3843817b3e +# BISECT_TYPE[1] = build +# MIN_CONFIG[1] = /home/test/config-bisect -- cgit v1.2.3 From 8b37ca8cac46b2c108386e3901cc8611dc81c7aa Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Tue, 2 Nov 2010 14:58:33 -0400 Subject: ktest: Add POST_INSTALL to allow initrds to be created Add a POST_INSTALL option that runs after the build and install but before rebooting to the test kernel. This alls the user to run a script that will install an initrd (or anything else that may be special) before booting. An environment variable KERNEL_VERSION is set. Signed-off-by: Steven Rostedt --- tools/testing/ktest/ktest.pl | 11 +++++++++++ tools/testing/ktest/sample.conf | 5 +++++ 2 files changed, 16 insertions(+) diff --git a/tools/testing/ktest/ktest.pl b/tools/testing/ktest/ktest.pl index 1f28c45f15b8..687a85475af5 100644 --- a/tools/testing/ktest/ktest.pl +++ b/tools/testing/ktest/ktest.pl @@ -58,6 +58,7 @@ my $grub_menu; my $grub_number; my $target; my $make; +my $post_install; my $noclean; my $minconfig; my $addconfig; @@ -489,6 +490,15 @@ sub install { dodie "failed to tar modules"; run_command "ssh $target rm -f /tmp/$modtar"; + + return if (!defined($post_install)); + + my $save_env = $ENV{KERNEL_VERSION}; + + $ENV{KERNEL_VERSION} = $version; + run_command "$post_install"; + + $ENV{KERNEL_VERSION} = $save_env; } sub check_buildlog { @@ -1055,6 +1065,7 @@ for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) { $addconfig = set_test_option("ADD_CONFIG", $i); $reboot_type = set_test_option("REBOOT_TYPE", $i); $grub_menu = set_test_option("GRUB_MENU", $i); + $post_install = set_test_option("POST_INSTALL", $i); $reboot_script = set_test_option("REBOOT_SCRIPT", $i); $reboot_on_error = set_test_option("REBOOT_ON_ERROR", $i); $poweroff_on_error = set_test_option("POWEROFF_ON_ERROR", $i); diff --git a/tools/testing/ktest/sample.conf b/tools/testing/ktest/sample.conf index 42f803fe4a8d..0115a6762a6d 100644 --- a/tools/testing/ktest/sample.conf +++ b/tools/testing/ktest/sample.conf @@ -93,6 +93,11 @@ # If you are building a 32bit x86 on a 64 bit host #MAKE_CMD = CC=i386-gcc AS=i386-as make ARCH=i386 +# If you need an initrd, you can add a script or code here to install +# it. The environment variable KERNEL_VERSION will be set to the +# kernel version that is used. +#POST_INSTALL = ssh user@target /sbin/mkinitrd --allow-missing -f /boot/initramfs-test.img $KERNEL_VERSION + # Way to reboot the box to the test kernel. # Only valid options so far are "grub" and "script" # (default grub) -- cgit v1.2.3 From 576f627c817dff0b7081374287a77247325b9cc0 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Tue, 2 Nov 2010 14:58:38 -0400 Subject: ktest: Add poweroff after halt and powercycle after reboot Added the options POWEROFF_AFTER_HALT to handle boxes that do not really shut off after a halt is called. Added POWERCYCLE_AFTER_REBOOT to force a power cycle for boxes that don't reboot but get stuck during the reboot. Signed-off-by: Steven Rostedt --- tools/testing/ktest/ktest.pl | 63 +++++++++++++++++++++++++++++++---------- tools/testing/ktest/sample.conf | 18 ++++++++++++ 2 files changed, 66 insertions(+), 15 deletions(-) diff --git a/tools/testing/ktest/ktest.pl b/tools/testing/ktest/ktest.pl index 687a85475af5..ef978171ecb7 100644 --- a/tools/testing/ktest/ktest.pl +++ b/tools/testing/ktest/ktest.pl @@ -53,6 +53,8 @@ my $power_cycle; my $reboot_on_error; my $poweroff_on_error; my $die_on_failure; +my $powercycle_after_reboot; +my $poweroff_after_halt; my $power_off; my $grub_menu; my $grub_number; @@ -83,6 +85,7 @@ my $success_line; my $build_target; my $target_image; my $localversion; +my $iteration = 0; sub read_config { my ($config) = @_; @@ -133,16 +136,32 @@ sub run_command; sub reboot { # try to reboot normally - if (!run_command "ssh $target reboot") { + if (run_command "ssh $target reboot") { + if (defined($powercycle_after_reboot)) { + sleep $powercycle_after_reboot; + run_command "$power_cycle"; + } + } else { # nope? power cycle it. run_command "$power_cycle"; } } +sub do_not_reboot { + my $i = $iteration; + + return $test_type eq "build" || + ($test_type eq "patchcheck" && $opt{"PATCHCHECK_TYPE[$i]"} eq "build") || + ($test_type eq "bisect" && $opt{"BISECT_TYPE[$i]"} eq "build"); +} + sub dodie { doprint "CRITICAL FAILURE... ", @_, "\n"; - if ($reboot_on_error && $test_type ne "build") { + my $i = $iteration; + + if ($reboot_on_error && !do_not_reboot) { + doprint "REBOOTING\n"; reboot; @@ -151,7 +170,7 @@ sub dodie { `$power_off`; } - die @_; + die @_, "\n"; } sub open_console { @@ -163,9 +182,9 @@ sub open_console { dodie "Can't open console $console"; $flags = fcntl($fp, F_GETFL, 0) or - dodie "Can't get flags for the socket: $!\n"; + dodie "Can't get flags for the socket: $!"; $flags = fcntl($fp, F_SETFL, $flags | O_NONBLOCK) or - dodie "Can't set flags for the socket: $!\n"; + dodie "Can't set flags for the socket: $!"; return $pid; } @@ -221,8 +240,10 @@ sub fail { doprint "FAILED\n"; + my $i = $iteration; + # no need to reboot for just building. - if ($test_type ne "build") { + if (!do_not_reboot) { doprint "REBOOTING\n"; reboot; start_monitor; @@ -230,7 +251,11 @@ sub fail { end_monitor; } + doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n"; + doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n"; doprint "**** Failed: ", @_, " ****\n"; + doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n"; + doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n"; return 1 if (!defined($store_failures)); @@ -434,12 +459,12 @@ sub monitor { if ($bug) { return 0 if ($in_bisect); - fail "failed - got a bug report\n" and return 0; + fail "failed - got a bug report" and return 0; } if (!$booted) { return 0 if ($in_bisect); - fail "failed - never got a boot prompt.\n" and return 0; + fail "failed - never got a boot prompt." and return 0; } return 1; @@ -496,7 +521,8 @@ sub install { my $save_env = $ENV{KERNEL_VERSION}; $ENV{KERNEL_VERSION} = $version; - run_command "$post_install"; + run_command "$post_install" or + dodie "Failed to run post install"; $ENV{KERNEL_VERSION} = $save_env; } @@ -596,6 +622,11 @@ sub build { sub halt { if (!run_command "ssh $target halt" or defined($power_off)) { + if (defined($poweroff_after_halt)) { + sleep $poweroff_after_halt; + run_command "$power_off"; + } + } else { # nope? the zap it! run_command "$power_off"; } @@ -610,9 +641,7 @@ sub success { doprint "*******************************************\n"; doprint "*******************************************\n"; - if ($i != $opt{"NUM_TESTS"} && $test_type ne "build" && - !($test_type eq "patchcheck" && $opt{"PATCHCHECK_TYPE[$i]"} eq "build") && - !($test_type eq "bisect" && $opt{"BISECT_TYPE[$i]"} eq "build")) { + if ($i != $opt{"NUM_TESTS"} && !do_not_reboot) { doprint "Reboot and wait $sleep_time seconds\n"; reboot; start_monitor; @@ -1048,6 +1077,8 @@ sub set_test_option { # First we need to do is the builds for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) { + $iteration = $i; + my $ssh_user = set_test_option("SSH_USER", $i); my $makecmd = set_test_option("MAKE_CMD", $i); @@ -1071,6 +1102,8 @@ for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) { $poweroff_on_error = set_test_option("POWEROFF_ON_ERROR", $i); $die_on_failure = set_test_option("DIE_ON_FAILURE", $i); $power_off = set_test_option("POWER_OFF", $i); + $powercycle_after_reboot = set_test_option("POWERCYCLE_AFTER_REBOOT", $i); + $poweroff_after_halt = set_test_option("POWEROFF_AFTER_HALT", $i); $sleep_time = set_test_option("SLEEP_TIME", $i); $bisect_sleep_time = set_test_option("BISECT_SLEEP_TIME", $i); $store_failures = set_test_option("STORE_FAILURES", $i); @@ -1096,9 +1129,9 @@ for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) { $make = "$makecmd O=$outputdir"; if ($reboot_type eq "grub") { - dodie "GRUB_MENU not defined\n" if (!defined($grub_menu)); + dodie "GRUB_MENU not defined" if (!defined($grub_menu)); } elsif (!defined($reboot_script)) { - dodie "REBOOT_SCRIPT not defined\n" + dodie "REBOOT_SCRIPT not defined" } my $run_type = $build_type; @@ -1167,7 +1200,7 @@ for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) { if ($opt{"POWEROFF_ON_SUCCESS"}) { halt; -} elsif ($opt{"REBOOT_ON_SUCCESS"} && $test_type ne "build") { +} elsif ($opt{"REBOOT_ON_SUCCESS"} && !do_not_reboot) { reboot; } diff --git a/tools/testing/ktest/sample.conf b/tools/testing/ktest/sample.conf index 0115a6762a6d..546014a6bb03 100644 --- a/tools/testing/ktest/sample.conf +++ b/tools/testing/ktest/sample.conf @@ -160,6 +160,24 @@ # (ignored if POWEROFF_ON_SUCCESS is set) #REBOOT_ON_SUCCESS = 1 +# In case there's isses with rebooting, you can specify this +# to always powercycle after this amount of time after calling +# reboot. +# Note, POWERCYCLE_AFTER_REBOOT = 0 does NOT disable it. It just +# makes it powercycle immediately after rebooting. Do not define +# it if you do not want it. +# (default undefined) +#POWERCYCLE_AFTER_REBOOT = 5 + +# In case there's isses with halting, you can specify this +# to always poweroff after this amount of time after calling +# halt. +# Note, POWEROFF_AFTER_HALT = 0 does NOT disable it. It just +# makes it poweroff immediately after halting. Do not define +# it if you do not want it. +# (default undefined) +#POWEROFF_AFTER_HALT = 20 + # Stop testing if a build fails. If set, the script will end if # a failure is detected, otherwise it will save off the .config, # dmesg and bootlog in a directory called -- cgit v1.2.3 From a57419b366a20009c9363c3cdad2449dc2fa8b9c Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Tue, 2 Nov 2010 15:13:54 -0400 Subject: ktest: New TEST_START instead of using [], and use real SHA1s Change the config to use TEST_START where the options after a TEST_START automatically get the [] as it is read and they do not need to exist in the config file; TEST_START MIN_CONFIG = myconfig is the same as MIN_CONFIG[1] = myconfig The benefit is that you no longer need to keep track of test numbers with tests. Also process the commit ids that are passed to the options to get the actually SHA1 so it is no longer relative to the branch. Ie, saying HEAD will get the current SHA1 and then that will be used, and will work even if another branch is checked out. Signed-off-by: Steven Rostedt --- tools/testing/ktest/ktest.pl | 206 +++++++++++++++++++++--- tools/testing/ktest/sample.conf | 345 +++++++++++++++++++++++++++++----------- 2 files changed, 433 insertions(+), 118 deletions(-) diff --git a/tools/testing/ktest/ktest.pl b/tools/testing/ktest/ktest.pl index ef978171ecb7..a7e86e391172 100644 --- a/tools/testing/ktest/ktest.pl +++ b/tools/testing/ktest/ktest.pl @@ -11,21 +11,23 @@ use File::Path qw(mkpath); use File::Copy qw(cp); use FileHandle; -$#ARGV >= 0 || die "usage: autotest.pl config-file\n"; +$#ARGV >= 0 || die "usage: ktest.pl config-file\n"; $| = 1; my %opt; +my %repeat_tests; +my %repeats; my %default; #default opts -$default{"NUM_TESTS"} = 5; +$default{"NUM_TESTS"} = 1; $default{"REBOOT_TYPE"} = "grub"; $default{"TEST_TYPE"} = "test"; $default{"BUILD_TYPE"} = "randconfig"; $default{"MAKE_CMD"} = "make"; $default{"TIMEOUT"} = 120; -$default{"TMP_DIR"} = "/tmp/autotest"; +$default{"TMP_DIR"} = "/tmp/ktest"; $default{"SLEEP_TIME"} = 60; # sleep time between tests $default{"BUILD_NOCLEAN"} = 0; $default{"REBOOT_ON_ERROR"} = 0; @@ -87,29 +89,138 @@ my $target_image; my $localversion; my $iteration = 0; +sub set_value { + my ($lvalue, $rvalue) = @_; + + if (defined($opt{$lvalue})) { + die "Error: Option $lvalue defined more than once!\n"; + } + $opt{$lvalue} = $rvalue; +} + sub read_config { my ($config) = @_; open(IN, $config) || die "can't read file $config"; + my $name = $config; + $name =~ s,.*/(.*),$1,; + + my $test_num = 0; + my $default = 1; + my $repeat = 1; + my $num_tests_set = 0; + my $skip = 0; + my $rest; + while () { # ignore blank lines and comments next if (/^\s*$/ || /\s*\#/); - if (/^\s*(\S+)\s*=\s*(.*?)\s*$/) { + if (/^\s*TEST_START(.*)/) { + + $rest = $1; + + if ($num_tests_set) { + die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n"; + } + + my $old_test_num = $test_num; + + $test_num += $repeat; + $default = 0; + $repeat = 1; + + if ($rest =~ /\s+SKIP(.*)/) { + $rest = $1; + $skip = 1; + } else { + $skip = 0; + } + + if ($rest =~ /\s+ITERATE\s+(\d+)(.*)$/) { + $repeat = $1; + $rest = $2; + $repeat_tests{"$test_num"} = $repeat; + } + + if ($rest =~ /\s+SKIP(.*)/) { + $rest = $1; + $skip = 1; + } + + if ($rest !~ /^\s*$/) { + die "$name: $.: Gargbage found after TEST_START\n$_"; + } + + if ($skip) { + $test_num = $old_test_num; + $repeat = 1; + } + + } elsif (/^\s*DEFAULTS(.*)$/) { + $default = 1; + + $rest = $1; + + if ($rest =~ /\s+SKIP(.*)/) { + $rest = $1; + $skip = 1; + } else { + $skip = 0; + } + + if ($rest !~ /^\s*$/) { + die "$name: $.: Gargbage found after DEFAULTS\n$_"; + } + + } elsif (/^\s*([A-Z_\[\]\d]+)\s*=\s*(.*?)\s*$/) { + + next if ($skip); + my $lvalue = $1; my $rvalue = $2; - if (defined($opt{$lvalue})) { - die "Error: Option $lvalue defined more than once!\n"; + if (!$default && + ($lvalue eq "NUM_TESTS" || + $lvalue eq "LOG_FILE" || + $lvalue eq "CLEAR_LOG")) { + die "$name: $.: $lvalue must be set in DEFAULTS section\n"; + } + + if ($lvalue eq "NUM_TESTS") { + if ($test_num) { + die "$name: $.: Can not specify both NUM_TESTS and TEST_START\n"; + } + if (!$default) { + die "$name: $.: NUM_TESTS must be set in default section\n"; + } + $num_tests_set = 1; + } + + if ($default || $lvalue =~ /\[\d+\]$/) { + set_value($lvalue, $rvalue); + } else { + my $val = "$lvalue\[$test_num\]"; + set_value($val, $rvalue); + + if ($repeat > 1) { + $repeats{$val} = $repeat; + } } - $opt{$lvalue} = $rvalue; + } else { + die "$name: $.: Garbage found in config\n$_"; } } close(IN); + if ($test_num) { + $test_num += $repeat - 1; + $opt{"NUM_TESTS"} = $test_num; + } + # set any defaults foreach my $default (keys %default) { @@ -398,6 +509,27 @@ sub reboot_to { run_command "$reboot_script"; } +sub get_sha1 { + my ($commit) = @_; + + doprint "git rev-list --max-count=1 $commit ... "; + my $sha1 = `git rev-list --max-count=1 $commit`; + my $ret = $?; + + logit $sha1; + + if ($ret) { + doprint "FAILED\n"; + dodie "Failed to get git $commit"; + } + + print "SUCCESS\n"; + + chomp $sha1; + + return $sha1; +} + sub monitor { my $booted = 0; my $bug = 0; @@ -497,7 +629,7 @@ sub install { dodie "Failed to install modules"; my $modlib = "/lib/modules/$version"; - my $modtar = "autotest-mods.tar.bz2"; + my $modtar = "ktest-mods.tar.bz2"; run_command "ssh $target rm -rf $modlib" or dodie "failed to remove old mods: $modlib"; @@ -840,6 +972,10 @@ sub bisect { my $start = $opt{"BISECT_START[$i]"}; my $replay = $opt{"BISECT_REPLAY[$i]"}; + # convert to true sha1's + $good = get_sha1($good); + $bad = get_sha1($bad); + if (defined($opt{"BISECT_REVERSE[$i]"}) && $opt{"BISECT_REVERSE[$i]"} == 1) { doprint "Performing a reverse bisect (bad is good, good is bad!)\n"; @@ -859,20 +995,7 @@ sub bisect { if (defined($check) && $check ne "0") { # get current HEAD - doprint "git rev-list HEAD --max-count=1 ... "; - my $head = `git rev-list HEAD --max-count=1`; - my $ret = $?; - - logit $head; - - if ($ret) { - doprint "FAILED\n"; - dodie "Failed to get git HEAD"; - } - - print "SUCCESS\n"; - - chomp $head; + my $head = get_sha1("HEAD"); if ($check ne "good") { doprint "TESTING BISECT BAD [$bad]\n"; @@ -956,6 +1079,10 @@ sub patchcheck { $end = $opt{"PATCHCHECK_END[$i]"}; } + # Get the true sha1's since we can use things like HEAD~3 + $start = get_sha1($start); + $end = get_sha1($end); + my $type = $opt{"PATCHCHECK_TYPE[$i]"}; # Can't have a test without having a test to run @@ -1054,8 +1181,29 @@ if ($opt{"CLEAR_LOG"} && defined($opt{"LOG_FILE"})) { doprint "\n\nSTARTING AUTOMATED TESTS\n\n"; -foreach my $option (sort keys %opt) { - doprint "$option = $opt{$option}\n"; +for (my $i = 0, my $repeat = 1; $i <= $opt{"NUM_TESTS"}; $i += $repeat) { + + if (!$i) { + doprint "DEFAULT OPTIONS:\n"; + } else { + doprint "\nTEST $i OPTIONS"; + if (defined($repeat_tests{$i})) { + $repeat = $repeat_tests{$i}; + doprint " ITERATE $repeat"; + } + doprint "\n"; + } + + foreach my $option (sort keys %opt) { + + if ($option =~ /\[(\d+)\]$/) { + next if ($i != $1); + } else { + next if ($i); + } + + doprint "$option = $opt{$option}\n"; + } } sub set_test_option { @@ -1067,6 +1215,16 @@ sub set_test_option { return $opt{$option}; } + foreach my $test (keys %repeat_tests) { + if ($i >= $test && + $i < $test + $repeat_tests{$test}) { + $option = "$name\[$test\]"; + if (defined($opt{$option})) { + return $opt{$option}; + } + } + } + if (defined($opt{$name})) { return $opt{$name}; } diff --git a/tools/testing/ktest/sample.conf b/tools/testing/ktest/sample.conf index 546014a6bb03..9236fe977fa2 100644 --- a/tools/testing/ktest/sample.conf +++ b/tools/testing/ktest/sample.conf @@ -1,25 +1,83 @@ # -# Config file for autotest.pl +# Config file for ktest.pl # # Note, all paths must be absolute # -# Almost all options may be overwritten per test run, by appending -# a [x] to the config. For example, to change the test type for -# the third iteration of tests, you can specify: -# (1 is for the first test, 2 for the second, and so on) +# Options set in the beginning of the file are considered to be +# default options. These options can be overriden by test specific +# options, with the following exceptions: # -# TEST_TYPE[3] = build -# -# The options that can not be changed like this are: -# NUM_TESTS # LOG_FILE # CLEAR_LOG # POWEROFF_ON_SUCCESS # REBOOT_ON_SUCCESS # +# Test specific options are set after the label: +# +# TEST_START +# +# The options after a TEST_START label are specific to that test. +# Each TEST_START label will set up a new test. If you want to +# perform a test more than once, you can add the ITERATE label +# to it followed by the number of times you want that test +# to iterate. If the ITERATE is left off, the test will only +# be performed once. +# +# TEST_START ITERATE 10 +# +# You can skip a test by adding SKIP (before or after the ITERATE +# and number) +# +# TEST_START SKIP +# +# TEST_START SKIP ITERATE 10 +# +# TEST_START ITERATE 10 SKIP +# +# The SKIP label causes the options and the test itself to be ignored. +# This is useful to set up several different tests in one config file, and +# only enabling the ones you want to use for a current test run. +# +# You can add default options anywhere in the file as well +# with the DEFAULTS tag. This allows you to have default options +# after the test options to keep the test options at the top +# of the file. You can even place the DEFAULTS tag between +# test cases (but not in the middle of a single test case) +# +# TEST_START +# MIN_CONFIG = /home/test/config-test1 +# +# DEFAULTS +# MIN_CONFIG = /home/test/config-default +# +# TEST_START ITERATE 10 +# +# The above will run the first test with MIN_CONFIG set to +# /home/test/config-test-1. Then 10 tests will be executed +# with MIN_CONFIG with /home/test/config-default. +# +# You can also disable defaults with the SKIP option +# +# DEFAULTS SKIP +# MIN_CONFIG = /home/test/config-use-sometimes +# +# DEFAULTS +# MIN_CONFIG = /home/test/config-most-times +# +# The above will ignore the first MIN_CONFIG. If you want to +# use the first MIN_CONFIG, remove the SKIP from the first +# DEFAULTS tag and add it to the second. Be careful, options +# may only be declared once per test or default. If you have +# the same option name under the same test or as default +# ktest will fail to execute, and no tests will run. +# + + +#### Mandatory Default Options #### -#### Mandatory Config Options #### +# These options must be in the default section, although most +# may be overridden by test options. # The machine hostname that you will test #MACHINE = target @@ -43,17 +101,21 @@ #TARGET_IMAGE = /boot/vmlinuz-test # A script or command to reboot the box +# # Here is a digital loggers power switch example #POWER_CYCLE = wget --no-proxy -O /dev/null -q --auth-no-challenge 'http://admin:admin@power/outlet?5=CCL' +# # Here is an example to reboot a virtual box on the current host # with the name "Guest". -#POWER_CYCLE = virsh list | grep '\' | awk '{printf ("%d", $1)}' | xargs virsh destroy; sleep 5; virsh start Guest +#POWER_CYCLE = virsh destroy Guest; sleep 5; virsh start Guest # The script or command that reads the console +# # If you use ttywatch server, something like the following would work. #CONSOLE = nc -d localhost 3001 +# # For a virtual machine with guest name "Guest". -#CONSOLE = virsh console `virsh list | grep '\' | awk '{printf ("%d", $1)}'` +#CONSOLE = virsh console Guest # Required version ending to differentiate the test # from other linux builds on the system. @@ -62,8 +124,14 @@ # The grub title name for the test kernel to boot # (Only mandatory if REBOOT_TYPE = grub) # +# Note, ktest.pl will not update the grub menu.lst, you need to +# manually add an option for the test. ktest.pl will search +# the grub menu.lst for this option to find what kernel to +# reboot into. +# # For example, if in the /boot/grub/menu.lst the test kernel title has: # title Test Kernel +# kernel vmlinuz-test #GRUB_MENU = Test Kernel # A script to reboot the target into the test kernel @@ -72,21 +140,37 @@ #### Optional Config Options (all have defaults) #### -# The number of tests to run (default 5) -#NUM_TESTS = 5 +# Start a test setup. If you leave this off, all options +# will be default and the test will run once. +# This is a label and not really an option (it takes no value). +# You can append ITERATE and a number after it to iterate the +# test a number of times, or SKIP to ignore this test. +# +#TEST_START +#TEST_START ITERATE 5 +#TEST_START SKIP # The default test type (default test) # The test types may be: # build - only build the kernel, do nothing else # boot - build and boot the kernel # test - build, boot and if TEST is set, run the test script +# (If TEST is not set, it defaults back to boot) # bisect - Perform a bisect on the kernel (see BISECT_TYPE below) # patchcheck - Do a test on a series of commits in git (see PATCHCHECK below) #TEST_TYPE = test -# The build type is any make config type or a command. +# Test to run if there is a successful boot and TEST_TYPE is test. +# Must exit with 0 on success and non zero on error +# default (undefined) +#TEST = ssh user@machine /root/run_test + +# The build type is any make config type or special command # (default randconfig) # nobuild - skip the clean and build step +# useconfig:/path/to/config - use the given config and run +# oldconfig on it. +# This option is ignored if TEST_TYPE is patchcheck or bisect #BUILD_TYPE = randconfig # The make command (default make) @@ -95,8 +179,14 @@ # If you need an initrd, you can add a script or code here to install # it. The environment variable KERNEL_VERSION will be set to the -# kernel version that is used. +# kernel version that is used. Remember to add the initrd line +# to your grub menu.lst file. +# +# Here's a couple of examples to use: #POST_INSTALL = ssh user@target /sbin/mkinitrd --allow-missing -f /boot/initramfs-test.img $KERNEL_VERSION +# +# or on some systems: +#POST_INSTALL = ssh user@target /sbin/dracut -f /boot/initramfs-test.img $KERNEL_VERSION # Way to reboot the box to the test kernel. # Only valid options so far are "grub" and "script" @@ -106,12 +196,19 @@ # and select that target to reboot to the kernel. If this is not # your setup, then specify "script" and have a command or script # specified in REBOOT_SCRIPT to boot to the target. +# +# The entry in /boot/grub/menu.lst must be entered in manually. +# The test will not modify that file. #REBOOT_TYPE = grub -# Line to define success in output. (default "login:") +# Line to define a successful boot up in console output. # This is what the line contains, not the entire line. If you need -# the entire line to match, then use regural expression syntax like -# ^MyBox Login:$ +# the entire line to match, then use regural expression syntax like: +# (do not add any quotes around it) +# +# SUCCESS_LINE = ^MyBox Login:$ +# +# (default "login:") #SUCCESS_LINE = login: # As the test reads the console, after it hits the SUCCESS_LINE @@ -121,24 +218,33 @@ #BOOTED_TIMEOUT = 1 # The timeout in seconds when we consider the box hung after -# the console stop producing output. +# the console stop producing output. Be sure to leave enough +# time here to get pass a reboot. Some machines may not produce +# any console output for a long time during a reboot. You do +# not want the test to fail just because the system was in +# the process of rebooting to the test kernel. # (default 120) #TIMEOUT = 120 # The location on the host where to write temp files -# (default /tmp/autotest) -#TMP_DIR = /tmp/autotest +# (default /tmp/ktest) +#TMP_DIR = /tmp/ktest # In between tests, a reboot of the box may occur, and this # is the time to wait for the console after it stops producing # output. Some machines may not produce a large lag on reboot # so this should accommodate it. +# The difference between this and TIMEOUT, is that TIMEOUT happens +# when rebooting to the test kernel. This sleep time happens +# after a test has completed and we are about to start running +# another test. If a reboot to the reliable kernel happens, +# we wait SLEEP_TIME for the console to stop producing output +# before starting the next test. # (default 60) #SLEEP_TIME = 60 # The time in between bisects to sleep (in seconds) -# Can be less than SLEEP_TIME since bisects do more work -# in between boots. (default 60) +# (default 60) #BISECT_SLEEP_TIME = 60 # Build without doing a make mrproper, or removing .config @@ -149,10 +255,12 @@ #REBOOT_ON_ERROR = 0 # Power off the target on error (ignored if REBOOT_ON_ERROR is set) +# Note, this is a DEFAULT section only option. # (default 0) #POWEROFF_ON_ERROR = 0 # Power off the target after all tests have completed successfully +# Note, this is a DEFAULT section only option. # (default 0) #POWEROFF_ON_SUCCESS = 0 @@ -160,7 +268,7 @@ # (ignored if POWEROFF_ON_SUCCESS is set) #REBOOT_ON_SUCCESS = 1 -# In case there's isses with rebooting, you can specify this +# In case there are isses with rebooting, you can specify this # to always powercycle after this amount of time after calling # reboot. # Note, POWERCYCLE_AFTER_REBOOT = 0 does NOT disable it. It just @@ -190,43 +298,68 @@ # Directory to store failure directories on failure. If this is not # set, DIE_ON_FAILURE=0 will not save off the .config, dmesg and -# bootlog. +# bootlog. This option is ignored if DIE_ON_FAILURE is not set. +# (default undefined) #STORE_FAILURES = /home/test/failures -# A script or command to power off the box (default undef) +# A script or command to power off the box (default undefined) # Needed for POWEROFF_ON_ERROR and SUCCESS +# # Example for digital loggers power switch: #POWER_OFF = wget --no-proxy -O /dev/null -q --auth-no-challenge 'http://admin:admin@power/outlet?5=OFF' +# # Example for a virtual guest call "Guest". -#POWER_OFF = virsh list | grep '\' | awk '{printf ("%d", $1)}' | xargs virsh destroy +#POWER_OFF = virsh destroy Guest -# Any build options for the make (default "") +# Any build options for the make of the kernel (not for other makes, like configs) +# (default "") #BUILD_OPTIONS = -j20 # Optional log file to write the status (recommended) -# (default undef) +# Note, this is a DEFAULT section only option. +# (default undefined) #LOG_FILE = /home/test/logfiles/target.log # Remove old logfile if it exists before starting all tests. +# Note, this is a DEFAULT section only option. # (default 0) #CLEAR_LOG = 0 -# Test to run if there is a successful boot and TEST_TYPE is test. -# Must exit with 0 on success and non zero on error -# default (undef) -#TEST = ssh user@machine /root/run_test -#TEST[1] = ssh root@mxtest /root/run_test - # The min config that is needed to build for the machine -# A nice way to get this to work, is to do a "lsmod > mymods" on the target -# copy it to the build server, and then run "make LSMOD=mymods localyesconfig". -# Then copy all the options that are set: "grep '^CONFIG' > /home/test/config-min" +# A nice way to create this is with the following: +# +# $ ssh target +# $ lsmod > mymods +# $ scp mymods host:/tmp +# $ exit +# $ cd linux.git +# $ rm .config +# $ make LSMOD=mymods localyesconfig +# $ grep '^CONFIG' .config > /home/test/config-min +# +# If you want even less configs: +# +# log in directly to target (do not ssh) +# +# $ su +# # lsmod | cut -d' ' -f1 | xargs rmmod +# +# repeat the above several times # -# You might want to set: +# # lsmod > mymods +# # reboot +# +# May need to reboot to get your network back to copy the mymods +# to the host, and then remove the previous .config and run the +# localyesconfig again. The CONFIG_MIN generated like this will +# not guarantee network activity to the box so the TEST_TYPE of +# test may fail. +# +# You might also want to set: # CONFIG_CMDLINE="" # randconfig may set the above and override your real command # line options. -# (default undef) +# (default undefined) #MIN_CONFIG = /home/test/config-min # Sometimes there's options that just break the boot and @@ -239,34 +372,47 @@ # KGDB may cause oops waiting for a connection that's not there. # This option points to the file containing config options that will be prepended # to the MIN_CONFIG (or be the MIN_CONFIG if it is not set) -# before running it through randconfig -# (default undef) +# +# Note, config options in MIN_CONFIG will override these options. +# +# (default undefined) #ADD_CONFIG = /home/test/config-broken #### Per test run options #### -# These are options are per build only. The only exist with the [x] -# syntax, and there is no general option. +# The following options are only allowed in TEST_START sections. +# They are ignored in the DEFAULTS sections. # -# All are optional and undef by default +# All of these are optional and undefined by default, although +# some of these options are required for TEST_TYPE of patchcheck +# and bisect. # -# CHECKOUT[x] = branch +# +# CHECKOUT = branch # # If the BUILD_DIR is a git repository, then you can set this option # to checkout the given branch before running the TEST. If you # specify this for the first run, that branch will be used for -# all preceding tests until a new CHECKOUT[x] is set. +# all preceding tests until a new CHECKOUT is set. +# # -# For TEST_TYPE[x] = patchcheck +# +# For TEST_TYPE = patchcheck # # This expects the BUILD_DIR to be a git repository, and -# will checkout the PATCHCHECK_START[x]. +# will checkout the PATCHCHECK_START commit. +# +# The option BUILD_TYPE will be ignored. # -# PATCHCHECK_START[x] is required and is the first patch to -# test (the SHA1 of the commit). +# The MIN_CONFIG will be used for all builds of the patchcheck. The build type +# used for patchcheck is oldconfig. # -# PATCHCHECK_END[x] is the last patch to check (default HEAD) +# PATCHCHECK_START is required and is the first patch to +# test (the SHA1 of the commit). You may also specify anything +# that git checkout allows (branch name, tage, HEAD~3). # -# PATCHCHECK_TYPE[x] is required and is the type of test to run: +# PATCHCHECK_END is the last patch to check (default HEAD) +# +# PATCHCHECK_TYPE is required and is the type of test to run: # build, boot, test. # # Note, the build test will look for warnings, if a warning occurred @@ -279,75 +425,86 @@ # make mrproper. This helps speed up the test. # # Example: -# TEST_TYPE[1] = patchcheck -# CHECKOUT[1] = mybranch -# PATCHCHECK_TYPE[1] = boot -# PATCHCHECK_START[1] = 747e94ae3d1b4c9bf5380e569f614eb9040b79e7 -# PATCHCHEKC_END[1] = b8b2663bd7c9da04ac804659b9f617c199d0252c +# TEST_START +# TEST_TYPE = patchcheck +# CHECKOUT = mybranch +# PATCHCHECK_TYPE = boot +# PATCHCHECK_START = 747e94ae3d1b4c9bf5380e569f614eb9040b79e7 +# PATCHCHEKC_END = HEAD~2 +# # # -# For TEST_TYPE[x] = bisect +# For TEST_TYPE = bisect # -# You can specify a git bisect if the BUILD_DIR is a git repository. -# The MIN_CONFIG will be used for all builds of the bisect. The build type -# used for bisecting is oldconfig. +# You can specify a git bisect if the BUILD_DIR is a git repository. +# The MIN_CONFIG will be used for all builds of the bisect. The build type +# used for bisecting is oldconfig. # -# BISECT_TYPE[x] is the type of test to perform: +# The option BUILD_TYPE will be ignored. +# +# BISECT_TYPE is the type of test to perform: # build - bad fails to build # boot - bad builds but fails to boot # test - bad boots but fails a test # -# BISECT_GOOD[x] is the commit (SHA1) to label as good -# BISECT_BAD[x] is the commit to label as bad +# BISECT_GOOD is the commit (SHA1) to label as good (accepts all git good commit types) +# BISECT_BAD is the commit to label as bad (accepts all git bad commit types) # # The above three options are required for a bisect operation. # -# BISECT_REPLAY[x] = /path/to/replay/file (optional, default undefined) +# BISECT_REPLAY = /path/to/replay/file (optional, default undefined) # # If an operation failed in the bisect that was not expected to # fail. Then the test ends. The state of the BUILD_DIR will be -# left off at where the failur occurred. You can examine the +# left off at where the failure occurred. You can examine the # reason for the failure, and perhaps even find a git commit # that would work to continue with. You can run: # # git bisect log > /path/to/replay/file # -# and if BISECT_REPLAY[x] is set, the test will run git bisect replay -# before continuing with the bisect. +# The adding: # -# BISECT_START[x] = commit (optional, default undefined) +# BISECT_REPLAY= /path/to/replay/file # -# As with BISECT_REPLAY[x], if the test failed on a commit that -# just happen to have a bad commit in the middle of the bisect, -# and you need to skip it. If BISECT_START[x] is defined, it -# will checkout that commit before continuing with the bisect. +# And running the test again. The test will perform the initial +# git bisect start, git bisect good, and git bisect bad, and +# then it will run git bisect replay on this file, before +# continuing with the bisect. # -# Note, BISECT_REPLAY[x] is executed before BISECT_START[x]. +# BISECT_START = commit (optional, default undefined) +# +# As with BISECT_REPLAY, if the test failed on a commit that +# just happen to have a bad commit in the middle of the bisect, +# and you need to skip it. If BISECT_START is defined, it +# will checkout that commit after doing the initial git bisect start, +# git bisect good, git bisect bad, and running the git bisect replay +# if the BISECT_REPLAY is set. # -# BISECT_REVERSE[x] = 1 (optional, default 0) +# BISECT_REVERSE = 1 (optional, default 0) # # In those strange instances where it was broken forever # and you are trying to find where it started to work! -# Set BISECT_GOOD[x] to the commit that was last known to fail -# Set BISECT_BAD[x] to the commit that is known where it started -# to work. With BISECT_REVERSE[x] = 1, The test will consider -# failures as good, and success as bad. +# Set BISECT_GOOD to the commit that was last known to fail +# Set BISECT_BAD to the commit that is known to start working. +# With BISECT_REVERSE = 1, The test will consider failures as +# good, and success as bad. # -# BISECT_CHECK[x] = 1 (optional, default 0) +# BISECT_CHECK = 1 (optional, default 0) # # Just to be sure the good is good and bad is bad, setting -# BISECT_CHECK[x] to 1 will start the bisect by first checking -# out BISECT_BAD[x] and makes sure it fails, then it will check -# out BISECT_GOOD[x] and makes sure it succeeds before starting -# the bisect (it works for BISECT_REVERSE[x] too). +# BISECT_CHECK to 1 will start the bisect by first checking +# out BISECT_BAD and makes sure it fails, then it will check +# out BISECT_GOOD and makes sure it succeeds before starting +# the bisect (it works for BISECT_REVERSE too). # -# You can limit the test to just check BISECT_GOOD[x] or -# BISECT_BAD[x] with BISECT_CHECK[x] = good or -# BISECT_CHECK[x] = bad, respectively. +# You can limit the test to just check BISECT_GOOD or +# BISECT_BAD with BISECT_CHECK = good or +# BISECT_CHECK = bad, respectively. # # Example: -# TEST_TYPE[1] = bisect -# BISECT_GOOD[1] = v2.6.36 -# BISECT_BAD[1] = b5153163ed580e00c67bdfecb02b2e3843817b3e -# BISECT_TYPE[1] = build -# MIN_CONFIG[1] = /home/test/config-bisect +# TEST_START +# TEST_TYPE = bisect +# BISECT_GOOD = v2.6.36 +# BISECT_BAD = b5153163ed580e00c67bdfecb02b2e3843817b3e +# BISECT_TYPE = build +# MIN_CONFIG = /home/test/config-bisect -- cgit v1.2.3 From dc89568884ae1b8b96ca6fffe83b404ae472750e Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Tue, 2 Nov 2010 15:22:53 -0400 Subject: ktest: Update the sample config file with more documentation Signed-off-by: Steven Rostedt --- tools/testing/ktest/sample.conf | 194 +++++++++++++++++++++------------------- 1 file changed, 103 insertions(+), 91 deletions(-) diff --git a/tools/testing/ktest/sample.conf b/tools/testing/ktest/sample.conf index 9236fe977fa2..03d6e91245fe 100644 --- a/tools/testing/ktest/sample.conf +++ b/tools/testing/ktest/sample.conf @@ -150,6 +150,18 @@ #TEST_START ITERATE 5 #TEST_START SKIP +# Have the following options as default again. Used after tests +# have already been defined by TEST_START. Optionally, you can +# just define all default options before the first TEST_START +# and you do not need this option. +# +# This is a label and not really an option (it takes no value). +# You can append SKIP to this label and the options within this +# section will be ignored. +# +# DEFAULTS +# DEFAULTS SKIP + # The default test type (default test) # The test types may be: # build - only build the kernel, do nothing else @@ -177,6 +189,10 @@ # If you are building a 32bit x86 on a 64 bit host #MAKE_CMD = CC=i386-gcc AS=i386-as make ARCH=i386 +# Any build options for the make of the kernel (not for other makes, like configs) +# (default "") +#BUILD_OPTIONS = -j20 + # If you need an initrd, you can add a script or code here to install # it. The environment variable KERNEL_VERSION will be set to the # kernel version that is used. Remember to add the initrd line @@ -201,6 +217,73 @@ # The test will not modify that file. #REBOOT_TYPE = grub +# The min config that is needed to build for the machine +# A nice way to create this is with the following: +# +# $ ssh target +# $ lsmod > mymods +# $ scp mymods host:/tmp +# $ exit +# $ cd linux.git +# $ rm .config +# $ make LSMOD=mymods localyesconfig +# $ grep '^CONFIG' .config > /home/test/config-min +# +# If you want even less configs: +# +# log in directly to target (do not ssh) +# +# $ su +# # lsmod | cut -d' ' -f1 | xargs rmmod +# +# repeat the above several times +# +# # lsmod > mymods +# # reboot +# +# May need to reboot to get your network back to copy the mymods +# to the host, and then remove the previous .config and run the +# localyesconfig again. The CONFIG_MIN generated like this will +# not guarantee network activity to the box so the TEST_TYPE of +# test may fail. +# +# You might also want to set: +# CONFIG_CMDLINE="" +# randconfig may set the above and override your real command +# line options. +# (default undefined) +#MIN_CONFIG = /home/test/config-min + +# Sometimes there's options that just break the boot and +# you do not care about. Here are a few: +# # CONFIG_STAGING is not set +# Staging drivers are horrible, and can break the build. +# # CONFIG_SCSI_DEBUG is not set +# SCSI_DEBUG may change your root partition +# # CONFIG_KGDB_SERIAL_CONSOLE is not set +# KGDB may cause oops waiting for a connection that's not there. +# This option points to the file containing config options that will be prepended +# to the MIN_CONFIG (or be the MIN_CONFIG if it is not set) +# +# Note, config options in MIN_CONFIG will override these options. +# +# (default undefined) +#ADD_CONFIG = /home/test/config-broken + +# The location on the host where to write temp files +# (default /tmp/ktest) +#TMP_DIR = /tmp/ktest + +# Optional log file to write the status (recommended) +# Note, this is a DEFAULT section only option. +# (default undefined) +#LOG_FILE = /home/test/logfiles/target.log + +# Remove old logfile if it exists before starting all tests. +# Note, this is a DEFAULT section only option. +# (default 0) +#CLEAR_LOG = 0 + # Line to define a successful boot up in console output. # This is what the line contains, not the entire line. If you need # the entire line to match, then use regural expression syntax like: @@ -211,6 +294,26 @@ # (default "login:") #SUCCESS_LINE = login: +# Stop testing if a build fails. If set, the script will end if +# a failure is detected, otherwise it will save off the .config, +# dmesg and bootlog in a directory called +# MACHINE-TEST_TYPE_BUILD_TYPE-fail-yyyymmddhhmmss +# if the STORE_FAILURES directory is set. +# (default 1) +# Note, even if this is set to zero, there are some errors that still +# stop the tests. +#DIE_ON_FAILURE = 1 + +# Directory to store failure directories on failure. If this is not +# set, DIE_ON_FAILURE=0 will not save off the .config, dmesg and +# bootlog. This option is ignored if DIE_ON_FAILURE is not set. +# (default undefined) +#STORE_FAILURES = /home/test/failures + +# Build without doing a make mrproper, or removing .config +# (default 0) +#BUILD_NOCLEAN = 0 + # As the test reads the console, after it hits the SUCCESS_LINE # the time it waits for the monitor to settle down between reads # can usually be lowered. @@ -226,10 +329,6 @@ # (default 120) #TIMEOUT = 120 -# The location on the host where to write temp files -# (default /tmp/ktest) -#TMP_DIR = /tmp/ktest - # In between tests, a reboot of the box may occur, and this # is the time to wait for the console after it stops producing # output. Some machines may not produce a large lag on reboot @@ -247,10 +346,6 @@ # (default 60) #BISECT_SLEEP_TIME = 60 -# Build without doing a make mrproper, or removing .config -# (default 0) -#BUILD_NOCLEAN = 0 - # Reboot the target box on error (default 0) #REBOOT_ON_ERROR = 0 @@ -286,22 +381,6 @@ # (default undefined) #POWEROFF_AFTER_HALT = 20 -# Stop testing if a build fails. If set, the script will end if -# a failure is detected, otherwise it will save off the .config, -# dmesg and bootlog in a directory called -# MACHINE-TEST_TYPE_BUILD_TYPE-fail-yyyymmddhhmmss -# if the STORE_FAILURES directory is set. -# (default 1) -# Note, even if this is set to zero, there are some errors that still -# stop the tests. -#DIE_ON_FAILURE = 1 - -# Directory to store failure directories on failure. If this is not -# set, DIE_ON_FAILURE=0 will not save off the .config, dmesg and -# bootlog. This option is ignored if DIE_ON_FAILURE is not set. -# (default undefined) -#STORE_FAILURES = /home/test/failures - # A script or command to power off the box (default undefined) # Needed for POWEROFF_ON_ERROR and SUCCESS # @@ -311,73 +390,6 @@ # Example for a virtual guest call "Guest". #POWER_OFF = virsh destroy Guest -# Any build options for the make of the kernel (not for other makes, like configs) -# (default "") -#BUILD_OPTIONS = -j20 - -# Optional log file to write the status (recommended) -# Note, this is a DEFAULT section only option. -# (default undefined) -#LOG_FILE = /home/test/logfiles/target.log - -# Remove old logfile if it exists before starting all tests. -# Note, this is a DEFAULT section only option. -# (default 0) -#CLEAR_LOG = 0 - -# The min config that is needed to build for the machine -# A nice way to create this is with the following: -# -# $ ssh target -# $ lsmod > mymods -# $ scp mymods host:/tmp -# $ exit -# $ cd linux.git -# $ rm .config -# $ make LSMOD=mymods localyesconfig -# $ grep '^CONFIG' .config > /home/test/config-min -# -# If you want even less configs: -# -# log in directly to target (do not ssh) -# -# $ su -# # lsmod | cut -d' ' -f1 | xargs rmmod -# -# repeat the above several times -# -# # lsmod > mymods -# # reboot -# -# May need to reboot to get your network back to copy the mymods -# to the host, and then remove the previous .config and run the -# localyesconfig again. The CONFIG_MIN generated like this will -# not guarantee network activity to the box so the TEST_TYPE of -# test may fail. -# -# You might also want to set: -# CONFIG_CMDLINE="" -# randconfig may set the above and override your real command -# line options. -# (default undefined) -#MIN_CONFIG = /home/test/config-min - -# Sometimes there's options that just break the boot and -# you do not care about. Here are a few: -# # CONFIG_STAGING is not set -# Staging drivers are horrible, and can break the build. -# # CONFIG_SCSI_DEBUG is not set -# SCSI_DEBUG may change your root partition -# # CONFIG_KGDB_SERIAL_CONSOLE is not set -# KGDB may cause oops waiting for a connection that's not there. -# This option points to the file containing config options that will be prepended -# to the MIN_CONFIG (or be the MIN_CONFIG if it is not set) -# -# Note, config options in MIN_CONFIG will override these options. -# -# (default undefined) -#ADD_CONFIG = /home/test/config-broken - #### Per test run options #### # The following options are only allowed in TEST_START sections. # They are ignored in the DEFAULTS sections. -- cgit v1.2.3 From 9386c6ab7a33044d9907b00fc80976292bb02c2d Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 8 Nov 2010 16:35:48 -0500 Subject: ktest: Use oldnoconfig instead of yes command Running the command "yes ''" through the make oldconfig may enable things we do not want enabled. If something is default enabled, the yes command with '' as an argument will enable it. Use oldnoconfig, which runs everything as if 'no' was used. Signed-off-by: Steven Rostedt --- tools/testing/ktest/ktest.pl | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tools/testing/ktest/ktest.pl b/tools/testing/ktest/ktest.pl index a7e86e391172..5bd00755727c 100644 --- a/tools/testing/ktest/ktest.pl +++ b/tools/testing/ktest/ktest.pl @@ -694,7 +694,6 @@ sub check_buildlog { sub build { my ($type) = @_; my $defconfig = ""; - my $append = ""; unlink $buildlog; @@ -707,7 +706,7 @@ sub build { # old config can ask questions if ($type eq "oldconfig") { - $append = "yes ''|"; + $type = "oldnoconfig"; # allow for empty configs run_command "touch $outputdir/.config"; @@ -737,7 +736,7 @@ sub build { $defconfig = "KCONFIG_ALLCONFIG=$minconfig"; } - run_command "$append $defconfig $make $type" or + run_command "$defconfig $make $type" or dodie "failed make config"; $redirect = "$buildlog"; -- cgit v1.2.3 From d1e2f22ad718c83ab19297e7717679c5ed17c020 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 8 Nov 2010 16:39:57 -0500 Subject: ktest: Write to stdout if no log file is given If no LOG_FILE option is set, then write what would be logged to that file to standard output. Signed-off-by: Steven Rostedt --- tools/testing/ktest/ktest.pl | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) mode change 100644 => 100755 tools/testing/ktest/ktest.pl diff --git a/tools/testing/ktest/ktest.pl b/tools/testing/ktest/ktest.pl old mode 100644 new mode 100755 index 5bd00755727c..0a5ed0db4ff3 --- a/tools/testing/ktest/ktest.pl +++ b/tools/testing/ktest/ktest.pl @@ -230,7 +230,7 @@ sub read_config { } } -sub logit { +sub _logit { if (defined($opt{"LOG_FILE"})) { open(OUT, ">> $opt{LOG_FILE}") or die "Can't write to $opt{LOG_FILE}"; print OUT @_; @@ -238,9 +238,17 @@ sub logit { } } +sub logit { + if (defined($opt{"LOG_FILE"})) { + _logit @_; + } else { + print @_; + } +} + sub doprint { print @_; - logit @_; + _logit @_; } sub run_command; -- cgit v1.2.3 From 51ad1dd1034684e9c490eb41c17cde8ffb682ab1 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 8 Nov 2010 16:43:21 -0500 Subject: ktest: Use $output_config instead of typing $outputdir/.config To help prevent typos, use $output_config as the reference to "$outputdir/.config". Signed-off-by: Steven Rostedt --- tools/testing/ktest/ktest.pl | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/tools/testing/ktest/ktest.pl b/tools/testing/ktest/ktest.pl index 0a5ed0db4ff3..3d88be784df0 100755 --- a/tools/testing/ktest/ktest.pl +++ b/tools/testing/ktest/ktest.pl @@ -46,6 +46,7 @@ my $machine; my $tmpdir; my $builddir; my $outputdir; +my $output_config; my $test_type; my $build_type; my $build_options; @@ -389,8 +390,8 @@ sub fail { mkpath($faildir) or die "can't create $faildir"; } - if (-f "$outputdir/.config") { - cp "$outputdir/.config", "$faildir/config" or + if (-f "$output_config") { + cp "$output_config", "$faildir/config" or die "failed to copy .config"; } if (-f $buildlog) { @@ -619,7 +620,7 @@ sub install { # should we process modules? $install_mods = 0; - open(IN, "$outputdir/.config") or dodie("Can't read config file"); + open(IN, "$output_config") or dodie("Can't read config file"); while () { if (/CONFIG_MODULES(=y)?/) { $install_mods = 1 if (defined($1)); @@ -706,7 +707,7 @@ sub build { unlink $buildlog; if ($type =~ /^useconfig:(.*)/) { - run_command "cp $1 $outputdir/.config" or + run_command "cp $1 $output_config" or dodie "could not copy $1 to .config"; $type = "oldconfig"; @@ -717,20 +718,20 @@ sub build { $type = "oldnoconfig"; # allow for empty configs - run_command "touch $outputdir/.config"; + run_command "touch $output_config"; - run_command "mv $outputdir/.config $outputdir/config_temp" or + run_command "mv $output_config $outputdir/config_temp" or dodie "moving .config"; if (!$noclean && !run_command "$make mrproper") { dodie "make mrproper"; } - run_command "mv $outputdir/config_temp $outputdir/.config" or + run_command "mv $outputdir/config_temp $output_config" or dodie "moving config_temp"; } elsif (!$noclean) { - unlink "$outputdir/.config"; + unlink "$output_config"; run_command "$make mrproper" or dodie "make mrproper"; } @@ -1292,6 +1293,7 @@ for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) { $buildlog = "$tmpdir/buildlog-$machine"; $dmesg = "$tmpdir/dmesg-$machine"; $make = "$makecmd O=$outputdir"; + $output_config = "$outputdir/.config"; if ($reboot_type eq "grub") { dodie "GRUB_MENU not defined" if (!defined($grub_menu)); -- cgit v1.2.3 From 21a9679feadf6b215c4f932b0df5d252b4822c45 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 8 Nov 2010 16:45:50 -0500 Subject: ktest: Allow a test case to undefine a default value Allow a test case in the config file to undefine a default value by specifying the option and equal sign but not assigning it a value: OPTION = Signed-off-by: Steven Rostedt --- tools/testing/ktest/ktest.pl | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tools/testing/ktest/ktest.pl b/tools/testing/ktest/ktest.pl index 3d88be784df0..962c0f773e20 100755 --- a/tools/testing/ktest/ktest.pl +++ b/tools/testing/ktest/ktest.pl @@ -97,6 +97,11 @@ sub set_value { die "Error: Option $lvalue defined more than once!\n"; } $opt{$lvalue} = $rvalue; + if ($rvalue =~ /^\s*$/) { + delete $opt{$lvalue}; + } else { + $opt{$lvalue} = $rvalue; + } } sub read_config { -- cgit v1.2.3 From 7a849cd93ad2cf7d32427f3dbf5f524d5f588d20 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 8 Nov 2010 16:49:25 -0500 Subject: ktest: Output something easy to parse for failure or success Have a easy way to parse the log file for success or failure. KTEST RESULT: ... Suggested-by: Tim Bird Signed-off-by: Steven Rostedt --- tools/testing/ktest/ktest.pl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/testing/ktest/ktest.pl b/tools/testing/ktest/ktest.pl index 962c0f773e20..e0e5935e94c8 100755 --- a/tools/testing/ktest/ktest.pl +++ b/tools/testing/ktest/ktest.pl @@ -378,7 +378,7 @@ sub fail { doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n"; doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n"; - doprint "**** Failed: ", @_, " ****\n"; + doprint "KTEST RESULT: TEST $i Failed: ", @_, "\n"; doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n"; doprint "%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n"; @@ -782,7 +782,7 @@ sub success { doprint "\n\n*******************************************\n"; doprint "*******************************************\n"; - doprint "** TEST $i SUCCESS!!!! **\n"; + doprint "KTEST RESULT: TEST $i SUCCESS!!!! **\n"; doprint "*******************************************\n"; doprint "*******************************************\n"; -- cgit v1.2.3 From e48c5293bde398e253f83fdd0247fb2bc71cc92f Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Tue, 2 Nov 2010 14:35:37 -0400 Subject: ktest/cleanups: Added version 0.2, ssh as options Updated to version 0.2. Now have SSH_EXEC options. Also added some cleanups for keeping track of success and reading the config file. Signed-off-by: Steven Rostedt --- tools/testing/ktest/ktest.pl | 81 ++++++++++++++++++++++++++++++++++---------- 1 file changed, 63 insertions(+), 18 deletions(-) diff --git a/tools/testing/ktest/ktest.pl b/tools/testing/ktest/ktest.pl index e0e5935e94c8..7b6f8e1a82a4 100755 --- a/tools/testing/ktest/ktest.pl +++ b/tools/testing/ktest/ktest.pl @@ -11,7 +11,9 @@ use File::Path qw(mkpath); use File::Copy qw(cp); use FileHandle; -$#ARGV >= 0 || die "usage: ktest.pl config-file\n"; +my $VERSION = "0.2"; + +$#ARGV >= 0 || die "ktest.pl version: $VERSION\n usage: ktest.pl config-file\n"; $| = 1; @@ -40,9 +42,13 @@ $default{"CLEAR_LOG"} = 0; $default{"SUCCESS_LINE"} = "login:"; $default{"BOOTED_TIMEOUT"} = 1; $default{"DIE_ON_FAILURE"} = 1; +$default{"SSH_EXEC"} = "ssh \$SSH_USER\@\$MACHINE \$SSH_COMMAND"; +$default{"SCP_TO_TARGET"} = "scp \$SRC_FILE \$SSH_USER\@\$MACHINE:\$DST_FILE"; +$default{"REBOOT"} = "ssh \$SSH_USER\@\$MACHINE reboot"; my $version; my $machine; +my $ssh_user; my $tmpdir; my $builddir; my $outputdir; @@ -53,11 +59,14 @@ my $build_options; my $reboot_type; my $reboot_script; my $power_cycle; +my $reboot; my $reboot_on_error; my $poweroff_on_error; my $die_on_failure; my $powercycle_after_reboot; my $poweroff_after_halt; +my $ssh_exec; +my $scp_to_target; my $power_off; my $grub_menu; my $grub_number; @@ -89,6 +98,7 @@ my $build_target; my $target_image; my $localversion; my $iteration = 0; +my $successes = 0; sub set_value { my ($lvalue, $rvalue) = @_; @@ -133,6 +143,7 @@ sub read_config { } my $old_test_num = $test_num; + my $old_repeat = $repeat; $test_num += $repeat; $default = 0; @@ -162,7 +173,7 @@ sub read_config { if ($skip) { $test_num = $old_test_num; - $repeat = 1; + $repeat = $old_repeat; } } elsif (/^\s*DEFAULTS(.*)$/) { @@ -261,7 +272,7 @@ sub run_command; sub reboot { # try to reboot normally - if (run_command "ssh $target reboot") { + if (run_command $reboot) { if (defined($powercycle_after_reboot)) { sleep $powercycle_after_reboot; run_command "$power_cycle"; @@ -419,6 +430,9 @@ sub run_command { my $dord = 0; my $pid; + $command =~ s/\$SSH_USER/$ssh_user/g; + $command =~ s/\$MACHINE/$machine/g; + doprint("$command ... "); $pid = open(CMD, "$command 2>&1 |") or @@ -457,6 +471,24 @@ sub run_command { return !$failed; } +sub run_ssh { + my ($cmd) = @_; + my $cp_exec = $ssh_exec; + + $cp_exec =~ s/\$SSH_COMMAND/$cmd/g; + return run_command "$cp_exec"; +} + +sub run_scp { + my ($src, $dst) = @_; + my $cp_scp = $scp_to_target; + + $cp_scp =~ s/\$SRC_FILE/$src/g; + $cp_scp =~ s/\$DST_FILE/$dst/g; + + return run_command "$cp_scp"; +} + sub get_grub_index { if ($reboot_type ne "grub") { @@ -466,8 +498,13 @@ sub get_grub_index { doprint "Find grub menu ... "; $grub_number = -1; - open(IN, "ssh $target cat /boot/grub/menu.lst |") + + my $ssh_grub = $ssh_exec; + $ssh_grub =~ s,\$SSH_COMMAND,cat /boot/grub/menu.lst,g; + + open(IN, "$ssh_grub |") or die "unable to get menu.lst"; + while () { if (/^\s*title\s+$grub_menu\s*$/) { $grub_number++; @@ -516,7 +553,7 @@ sub wait_for_input sub reboot_to { if ($reboot_type eq "grub") { - run_command "ssh $target '(echo \"savedefault --default=$grub_number --once\" | grub --batch; reboot)'"; + run_command "$ssh_exec '(echo \"savedefault --default=$grub_number --once\" | grub --batch; reboot)'"; return; } @@ -618,7 +655,7 @@ sub monitor { sub install { - run_command "scp $outputdir/$build_target $target:$target_image" or + run_scp "$outputdir/$build_target", "$target_image" or dodie "failed to copy image"; my $install_mods = 0; @@ -645,32 +682,29 @@ sub install { my $modlib = "/lib/modules/$version"; my $modtar = "ktest-mods.tar.bz2"; - run_command "ssh $target rm -rf $modlib" or + run_ssh "rm -rf $modlib" or dodie "failed to remove old mods: $modlib"; # would be nice if scp -r did not follow symbolic links run_command "cd $tmpdir && tar -cjf $modtar lib/modules/$version" or dodie "making tarball"; - run_command "scp $tmpdir/$modtar $target:/tmp" or + run_scp "$tmpdir/$modtar", "/tmp" or dodie "failed to copy modules"; unlink "$tmpdir/$modtar"; - run_command "ssh $target '(cd / && tar xf /tmp/$modtar)'" or + run_ssh "'(cd / && tar xf /tmp/$modtar)'" or dodie "failed to tar modules"; - run_command "ssh $target rm -f /tmp/$modtar"; + run_ssh "rm -f /tmp/$modtar"; return if (!defined($post_install)); - my $save_env = $ENV{KERNEL_VERSION}; - - $ENV{KERNEL_VERSION} = $version; - run_command "$post_install" or + my $cp_post_install = $post_install; + $cp_post_install = s/\$KERNEL_VERSION/$version/g; + run_command "$cp_post_install" or dodie "Failed to run post install"; - - $ENV{KERNEL_VERSION} = $save_env; } sub check_buildlog { @@ -766,7 +800,7 @@ sub build { } sub halt { - if (!run_command "ssh $target halt" or defined($power_off)) { + if (!run_ssh "halt" or defined($power_off)) { if (defined($poweroff_after_halt)) { sleep $poweroff_after_halt; run_command "$power_off"; @@ -780,6 +814,8 @@ sub halt { sub success { my ($i) = @_; + $successes++; + doprint "\n\n*******************************************\n"; doprint "*******************************************\n"; doprint "KTEST RESULT: TEST $i SUCCESS!!!! **\n"; @@ -1250,10 +1286,10 @@ for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) { $iteration = $i; - my $ssh_user = set_test_option("SSH_USER", $i); my $makecmd = set_test_option("MAKE_CMD", $i); $machine = set_test_option("MACHINE", $i); + $ssh_user = set_test_option("SSH_USER", $i); $tmpdir = set_test_option("TMP_DIR", $i); $outputdir = set_test_option("OUTPUT_DIR", $i); $builddir = set_test_option("BUILD_DIR", $i); @@ -1261,6 +1297,7 @@ for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) { $build_type = set_test_option("BUILD_TYPE", $i); $build_options = set_test_option("BUILD_OPTIONS", $i); $power_cycle = set_test_option("POWER_CYCLE", $i); + $reboot = set_test_option("REBOOT", $i); $noclean = set_test_option("BUILD_NOCLEAN", $i); $minconfig = set_test_option("MIN_CONFIG", $i); $run_test = set_test_option("TEST", $i); @@ -1283,6 +1320,8 @@ for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) { $console = set_test_option("CONSOLE", $i); $success_line = set_test_option("SUCCESS_LINE", $i); $build_target = set_test_option("BUILD_TARGET", $i); + $ssh_exec = set_test_option("SSH_EXEC", $i); + $scp_to_target = set_test_option("SCP_TO_TARGET", $i); $target_image = set_test_option("TARGET_IMAGE", $i); $localversion = set_test_option("LOCALVERSION", $i); @@ -1293,12 +1332,16 @@ for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) { die "can't create $tmpdir"; } + $ENV{"SSH_USER"} = $ssh_user; + $ENV{"MACHINE"} = $machine; + $target = "$ssh_user\@$machine"; $buildlog = "$tmpdir/buildlog-$machine"; $dmesg = "$tmpdir/dmesg-$machine"; $make = "$makecmd O=$outputdir"; $output_config = "$outputdir/.config"; + $output_config = "$outputdir/.config"; if ($reboot_type eq "grub") { dodie "GRUB_MENU not defined" if (!defined($grub_menu)); @@ -1376,4 +1419,6 @@ if ($opt{"POWEROFF_ON_SUCCESS"}) { reboot; } +doprint "\n $successes of $opt{NUM_TESTS} tests were successful\n\n"; + exit 0; -- cgit v1.2.3 From 0a05c769a9de554aefa773061c592c7054d5e7a0 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 8 Nov 2010 11:14:10 -0500 Subject: ktest: Added config_bisect test type Added the ability to do a config_bisect. It starts with a bad config and does the following loop. Enable half the configs. if none of the configs to check are not enabled (caused by missing dependencies) enable the other half. Run the test if the test passes, remove the configs from the check but enabled them for further tests (to satisfy dependencies). else Remove any config that was not enabled, as we have found a new config that can cause a failure. loop till we have only one config left. Signed-off-by: Steven Rostedt --- tools/testing/ktest/ktest.pl | 409 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 388 insertions(+), 21 deletions(-) diff --git a/tools/testing/ktest/ktest.pl b/tools/testing/ktest/ktest.pl index 7b6f8e1a82a4..0d1080548ea6 100755 --- a/tools/testing/ktest/ktest.pl +++ b/tools/testing/ktest/ktest.pl @@ -106,7 +106,6 @@ sub set_value { if (defined($opt{$lvalue})) { die "Error: Option $lvalue defined more than once!\n"; } - $opt{$lvalue} = $rvalue; if ($rvalue =~ /^\s*$/) { delete $opt{$lvalue}; } else { @@ -945,20 +944,18 @@ sub run_git_bisect { return 1; } -sub run_bisect { - my ($type) = @_; +# returns 1 on success, 0 on failure +sub run_bisect_test { + my ($type, $buildtype) = @_; my $failed = 0; my $result; my $output; my $ret; - if (defined($minconfig)) { - build "useconfig:$minconfig" or $failed = 1; - } else { - # ?? no config to use? - build "oldconfig" or $failed = 1; - } + $in_bisect = 1; + + build $buildtype or $failed = 1; if ($type ne "build") { dodie "Failed on build" if $failed; @@ -980,7 +977,7 @@ sub run_bisect { } if ($failed) { - $result = "bad"; + $result = 0; # reboot the box to a good kernel if ($type ne "build") { @@ -991,19 +988,35 @@ sub run_bisect { end_monitor; } } else { - $result = "good"; + $result = 1; + } + $in_bisect = 0; + + return $result; +} + +sub run_bisect { + my ($type) = @_; + my $buildtype = "oldconfig"; + + # We should have a minconfig to use? + if (defined($minconfig)) { + $buildtype = "useconfig:$minconfig"; } + my $ret = run_bisect_test $type, $buildtype; + + # Are we looking for where it worked, not failed? if ($reverse_bisect) { - if ($failed) { - $result = "good"; - } else { - $result = "bad"; - } + $ret = !$ret; } - return $result; + if ($ret) { + return "good"; + } else { + return "bad"; + } } sub bisect { @@ -1033,8 +1046,6 @@ sub bisect { $reverse_bisect = 0; } - $in_bisect = 1; - # Can't have a test without having a test to run if ($type eq "test" && !defined($run_test)) { $type = "boot"; @@ -1108,7 +1119,359 @@ sub bisect { doprint "Bad commit was [$bisect_bad]\n"; - $in_bisect = 0; + success $i; +} + +my %config_ignore; +my %config_set; + +my %config_list; +my %null_config; + +my %dependency; + +sub process_config_ignore { + my ($config) = @_; + + open (IN, $config) + or dodie "Failed to read $config"; + + while () { + if (/^(.*?(CONFIG\S*)(=.*| is not set))/) { + $config_ignore{$2} = $1; + } + } + + close(IN); +} + +sub read_current_config { + my ($config_ref) = @_; + + %{$config_ref} = (); + undef %{$config_ref}; + + my @key = keys %{$config_ref}; + if ($#key >= 0) { + print "did not delete!\n"; + exit; + } + open (IN, "$output_config"); + + while () { + if (/^(CONFIG\S+)=(.*)/) { + ${$config_ref}{$1} = $2; + } + } + close(IN); +} + +sub get_dependencies { + my ($config) = @_; + + my $arr = $dependency{$config}; + if (!defined($arr)) { + return (); + } + + my @deps = @{$arr}; + + foreach my $dep (@{$arr}) { + print "ADD DEP $dep\n"; + @deps = (@deps, get_dependencies $dep); + } + + return @deps; +} + +sub create_config { + my @configs = @_; + + open(OUT, ">$output_config") or dodie "Can not write to $output_config"; + + foreach my $config (@configs) { + print OUT "$config_set{$config}\n"; + my @deps = get_dependencies $config; + foreach my $dep (@deps) { + print OUT "$config_set{$dep}\n"; + } + } + + foreach my $config (keys %config_ignore) { + print OUT "$config_ignore{$config}\n"; + } + close(OUT); + +# exit; + run_command "$make oldnoconfig" or + dodie "failed make config oldconfig"; + +} + +sub compare_configs { + my (%a, %b) = @_; + + foreach my $item (keys %a) { + if (!defined($b{$item})) { + print "diff $item\n"; + return 1; + } + delete $b{$item}; + } + + my @keys = keys %b; + if ($#keys) { + print "diff2 $keys[0]\n"; + } + return -1 if ($#keys >= 0); + + return 0; +} + +sub run_config_bisect_test { + my ($type) = @_; + + return run_bisect_test $type, "oldconfig"; +} + +sub process_passed { + my (%configs) = @_; + + doprint "These configs had no failure: (Enabling them for further compiles)\n"; + # Passed! All these configs are part of a good compile. + # Add them to the min options. + foreach my $config (keys %configs) { + if (defined($config_list{$config})) { + doprint " removing $config\n"; + $config_ignore{$config} = $config_list{$config}; + delete $config_list{$config}; + } + } +} + +sub process_failed { + my ($config) = @_; + + doprint "\n\n***************************************\n"; + doprint "Found bad config: $config\n"; + doprint "***************************************\n\n"; +} + +sub run_config_bisect { + + my @start_list = keys %config_list; + + if ($#start_list < 0) { + doprint "No more configs to test!!!\n"; + return -1; + } + + doprint "***** RUN TEST ***\n"; + my $type = $opt{"CONFIG_BISECT_TYPE[$iteration]"}; + my $ret; + my %current_config; + + my $count = $#start_list + 1; + doprint " $count configs to test\n"; + + my $half = int($#start_list / 2); + + do { + my @tophalf = @start_list[0 .. $half]; + + create_config @tophalf; + read_current_config \%current_config; + + $count = $#tophalf + 1; + doprint "Testing $count configs\n"; + my $found = 0; + # make sure we test something + foreach my $config (@tophalf) { + if (defined($current_config{$config})) { + logit " $config\n"; + $found = 1; + } + } + if (!$found) { + # try the other half + doprint "Top half produced no set configs, trying bottom half\n"; + @tophalf = @start_list[$half .. $#start_list]; + create_config @tophalf; + read_current_config \%current_config; + foreach my $config (@tophalf) { + if (defined($current_config{$config})) { + logit " $config\n"; + $found = 1; + } + } + if (!$found) { + doprint "Failed: Can't make new config with current configs\n"; + foreach my $config (@start_list) { + doprint " CONFIG: $config\n"; + } + return -1; + } + $count = $#tophalf + 1; + doprint "Testing $count configs\n"; + } + + $ret = run_config_bisect_test $type; + + if ($ret) { + process_passed %current_config; + return 0; + } + + doprint "This config had a failure.\n"; + doprint "Removing these configs that were not set in this config:\n"; + + # A config exists in this group that was bad. + foreach my $config (keys %config_list) { + if (!defined($current_config{$config})) { + doprint " removing $config\n"; + delete $config_list{$config}; + } + } + + @start_list = @tophalf; + + if ($#start_list == 0) { + process_failed $start_list[0]; + return 1; + } + + # remove half the configs we are looking at and see if + # they are good. + $half = int($#start_list / 2); + } while ($half > 0); + + # we found a single config, try it again + my @tophalf = @start_list[0 .. 0]; + + $ret = run_config_bisect_test $type; + if ($ret) { + process_passed %current_config; + return 0; + } + + process_failed $start_list[0]; + return 1; +} + +sub config_bisect { + my ($i) = @_; + + my $start_config = $opt{"CONFIG_BISECT[$i]"}; + + my $tmpconfig = "$tmpdir/use_config"; + + # Make the file with the bad config and the min config + if (defined($minconfig)) { + # read the min config for things to ignore + run_command "cp $minconfig $tmpconfig" or + dodie "failed to copy $minconfig to $tmpconfig"; + } else { + unlink $tmpconfig; + } + + # Add other configs + if (defined($addconfig)) { + run_command "cat $addconfig >> $tmpconfig" or + dodie "failed to append $addconfig"; + } + + my $defconfig = ""; + if (-f $tmpconfig) { + $defconfig = "KCONFIG_ALLCONFIG=$tmpconfig"; + process_config_ignore $tmpconfig; + } + + # now process the start config + run_command "cp $start_config $output_config" or + dodie "failed to copy $start_config to $output_config"; + + # read directly what we want to check + my %config_check; + open (IN, $output_config) + or dodie "faied to open $output_config"; + + while () { + if (/^((CONFIG\S*)=.*)/) { + $config_check{$2} = $1; + } + } + close(IN); + + # Now run oldconfig with the minconfig (and addconfigs) + run_command "$defconfig $make oldnoconfig" or + dodie "failed make config oldconfig"; + + # check to see what we lost (or gained) + open (IN, $output_config) + or dodie "Failed to read $start_config"; + + my %removed_configs; + my %added_configs; + + while () { + if (/^((CONFIG\S*)=.*)/) { + # save off all options + $config_set{$2} = $1; + if (defined($config_check{$2})) { + if (defined($config_ignore{$2})) { + $removed_configs{$2} = $1; + } else { + $config_list{$2} = $1; + } + } elsif (!defined($config_ignore{$2})) { + $added_configs{$2} = $1; + $config_list{$2} = $1; + } + } + } + close(IN); + + my @confs = keys %removed_configs; + if ($#confs >= 0) { + doprint "Configs overridden by default configs and removed from check:\n"; + foreach my $config (@confs) { + doprint " $config\n"; + } + } + @confs = keys %added_configs; + if ($#confs >= 0) { + doprint "Configs appearing in make oldconfig and added:\n"; + foreach my $config (@confs) { + doprint " $config\n"; + } + } + + my %config_test; + my $once = 0; + + # Sometimes kconfig does weird things. We must make sure + # that the config we autocreate has everything we need + # to test, otherwise we may miss testing configs, or + # may not be able to create a new config. + # Here we create a config with everything set. + create_config (keys %config_list); + read_current_config \%config_test; + foreach my $config (keys %config_list) { + if (!defined($config_test{$config})) { + if (!$once) { + $once = 1; + doprint "Configs not produced by kconfig (will not be checked):\n"; + } + doprint " $config\n"; + delete $config_list{$config}; + } + } + my $ret; + do { + $ret = run_config_bisect; + } while (!$ret); + + return $ret if ($ret < 0); success $i; } @@ -1341,7 +1704,6 @@ for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) { $dmesg = "$tmpdir/dmesg-$machine"; $make = "$makecmd O=$outputdir"; $output_config = "$outputdir/.config"; - $output_config = "$outputdir/.config"; if ($reboot_type eq "grub") { dodie "GRUB_MENU not defined" if (!defined($grub_menu)); @@ -1354,6 +1716,8 @@ for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) { $run_type = $opt{"PATCHCHECK_TYPE[$i]"}; } elsif ($test_type eq "bisect") { $run_type = $opt{"BISECT_TYPE[$i]"}; + } elsif ($test_type eq "config_bisect") { + $run_type = $opt{"CONFIG_BISECT_TYPE[$i]"}; } # mistake in config file? @@ -1385,6 +1749,9 @@ for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) { if ($test_type eq "bisect") { bisect $i; next; + } elsif ($test_type eq "config_bisect") { + config_bisect $i; + next; } elsif ($test_type eq "patchcheck") { patchcheck $i; next; -- cgit v1.2.3 From dbc6d0aa8ae38cf9cfe39c6076cc5378ef4ca4a2 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 8 Nov 2010 17:18:37 -0500 Subject: ktest: Added compare script to test ktest.pl to sample.conf Add a compare script that makes sure that all the options in sample.conf are used in ktest.pl, and all the options in ktest.pl are described in sample.conf. Signed-off-by: Steven Rostedt --- tools/testing/ktest/compare-ktest-sample.pl | 30 +++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100755 tools/testing/ktest/compare-ktest-sample.pl diff --git a/tools/testing/ktest/compare-ktest-sample.pl b/tools/testing/ktest/compare-ktest-sample.pl new file mode 100755 index 000000000000..9a571e71683c --- /dev/null +++ b/tools/testing/ktest/compare-ktest-sample.pl @@ -0,0 +1,30 @@ +#!/usr/bin/perl + +open (IN,"ktest.pl"); +while () { + if (/\$opt\{"?([A-Z].*?)(\[.*\])?"?\}/ || + /set_test_option\("(.*?)"/) { + $opt{$1} = 1; + } +} +close IN; + +open (IN, "sample.conf"); +while () { + if (/^\s*#?\s*(\S+)\s*=/) { + $samp{$1} = 1; + } +} +close IN; + +foreach $opt (keys %opt) { + if (!defined($samp{$opt})) { + print "opt = $opt\n"; + } +} + +foreach $samp (keys %samp) { + if (!defined($opt{$samp})) { + print "samp = $samp\n"; + } +} -- cgit v1.2.3 From d1fbd7e6a6a4c67ab895a0219a2bbcf09d039c3a Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Mon, 8 Nov 2010 17:41:37 -0500 Subject: ktest: Updated the sample.conf for the latest options Added documentation for SSH_EXEC, SCP_TO_TARGET, REBOOT, and CONFIG_BISECT and friends. Signed-off-by: Steven Rostedt --- tools/testing/ktest/sample.conf | 90 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 89 insertions(+), 1 deletion(-) diff --git a/tools/testing/ktest/sample.conf b/tools/testing/ktest/sample.conf index 03d6e91245fe..e1272746ce8c 100644 --- a/tools/testing/ktest/sample.conf +++ b/tools/testing/ktest/sample.conf @@ -390,6 +390,21 @@ # Example for a virtual guest call "Guest". #POWER_OFF = virsh destroy Guest +# The way to execute a command on the target +# (default ssh $SSH_USER@$MACHINE $SSH_COMMAND";) +# The variables SSH_USER, MACHINE and SSH_COMMAND are defined +#SSH_EXEC = ssh $SSH_USER@$MACHINE $SSH_COMMAND"; + +# The way to copy a file to the target +# (default scp $SRC_FILE $SSH_USER@$MACHINE:$DST_FILE) +# The variables SSH_USER, MACHINE, SRC_FILE and DST_FILE are defined. +#SCP_TO_TARGET = scp $SRC_FILE $SSH_USER@$MACHINE:$DST_FILE + +# The nice way to reboot the target +# (default ssh $SSH_USER@$MACHINE reboot) +# The variables SSH_USER and MACHINE are defined. +#REBOOT = ssh $SSH_USER@$MACHINE reboot + #### Per test run options #### # The following options are only allowed in TEST_START sections. # They are ignored in the DEFAULTS sections. @@ -442,7 +457,7 @@ # CHECKOUT = mybranch # PATCHCHECK_TYPE = boot # PATCHCHECK_START = 747e94ae3d1b4c9bf5380e569f614eb9040b79e7 -# PATCHCHEKC_END = HEAD~2 +# PATCHCHECK_END = HEAD~2 # # # @@ -520,3 +535,76 @@ # BISECT_BAD = b5153163ed580e00c67bdfecb02b2e3843817b3e # BISECT_TYPE = build # MIN_CONFIG = /home/test/config-bisect +# +# +# +# For TEST_TYPE = config_bisect +# +# In those cases that you have two different configs. One of them +# work, the other does not, and you do not know what config causes +# the problem. +# The TEST_TYPE config_bisect will bisect the bad config looking for +# what config causes the failure. +# +# The way it works is this: +# +# First it finds a config to work with. Since a different version, or +# MIN_CONFIG may cause different dependecies, it must run through this +# preparation. +# +# Overwrites any config set in the bad config with a config set in +# either the MIN_CONFIG or ADD_CONFIG. Thus, make sure these configs +# are minimal and do not disable configs you want to test: +# (ie. # CONFIG_FOO is not set). +# +# An oldconfig is run on the bad config and any new config that +# appears will be added to the configs to test. +# +# Finally, it generates a config with the above result and runs it +# again through make oldconfig to produce a config that should be +# satisfied by kconfig. +# +# Then it starts the bisect. +# +# The configs to test are cut in half. If all the configs in this +# half depend on a config in the other half, then the other half +# is tested instead. If no configs are enabled by either half, then +# this means a circular dependency exists and the test fails. +# +# A config is created with the test half, and the bisect test is run. +# +# If the bisect succeeds, then all configs in the generated config +# are removed from the configs to test and added to the configs that +# will be enabled for all builds (they will be enabled, but not be part +# of the configs to examine). +# +# If the bisect fails, then all test configs that were not enabled by +# the config file are removed from the test. These configs will not +# be enabled in future tests. Since current config failed, we consider +# this to be a subset of the config that we started with. +# +# When we are down to one config, it is considered the bad config. +# +# Note, the config chosen may not be the true bad config. Due to +# dependencies and selections of the kbuild system, mulitple +# configs may be needed to cause a failure. If you disable the +# config that was found and restart the test, if the test fails +# again, it is recommended to rerun the config_bisect with a new +# bad config without the found config enabled. +# +# The option BUILD_TYPE will be ignored. +# +# CONFIG_BISECT_TYPE is the type of test to perform: +# build - bad fails to build +# boot - bad builds but fails to boot +# test - bad boots but fails a test +# +# CONFIG_BISECT is the config that failed to boot +# +# Example: +# TEST_START +# TEST_TYPE = config_bisect +# CONFIG_BISECT_TYPE = build +# CONFIG_BISECT = /home/test/¢onfig-bad +# MIN_CONFIG = /home/test/config-min +# -- cgit v1.2.3 From 9be2e6b590b5d9cb6d6e38b6362a552bbcb118e0 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Tue, 9 Nov 2010 12:20:21 -0500 Subject: ktest: Use different temp config name for minconfig By using the "use_config" for minconfig and addconfig we risk trying to copy itself to itself, which will cause an unexpected failure. Use a different name instead. Signed-off-by: Steven Rostedt --- tools/testing/ktest/ktest.pl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tools/testing/ktest/ktest.pl b/tools/testing/ktest/ktest.pl index 0d1080548ea6..a7a74f015ef3 100755 --- a/tools/testing/ktest/ktest.pl +++ b/tools/testing/ktest/ktest.pl @@ -1735,9 +1735,9 @@ for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) { $minconfig = $addconfig; } elsif (defined($addconfig)) { - run_command "cat $addconfig $minconfig > $tmpdir/use_config" or + run_command "cat $addconfig $minconfig > $tmpdir/add_config" or dodie "Failed to create temp config"; - $minconfig = "$tmpdir/use_config"; + $minconfig = "$tmpdir/add_config"; } my $checkout = $opt{"CHECKOUT[$i]"}; -- cgit v1.2.3 From cccae1a62a81dc8e32bf787024fdcf7ef71f1285 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Tue, 9 Nov 2010 12:21:32 -0500 Subject: ktest: Parse off the directory name in useconfig for failures When we store failures, we create a directory that has the build_type in it. For useconfig, it also contains the name path of the config file it uses. This unfortunately gets its own directory on failure. Parse off the directory name when creating the directory to store the failures. Signed-off-by: Steven Rostedt --- tools/testing/ktest/ktest.pl | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tools/testing/ktest/ktest.pl b/tools/testing/ktest/ktest.pl index a7a74f015ef3..52e45b8551e8 100755 --- a/tools/testing/ktest/ktest.pl +++ b/tools/testing/ktest/ktest.pl @@ -398,7 +398,12 @@ sub fail { my $date = sprintf "%04d%02d%02d%02d%02d%02d", 1900+$t[5],$t[4],$t[3],$t[2],$t[1],$t[0]; - my $dir = "$machine-$test_type-$build_type-fail-$date"; + my $type = $build_type; + if ($type =~ /useconfig/) { + $type = "useconfig"; + } + + my $dir = "$machine-$test_type-$type-fail-$date"; my $faildir = "$store_failures/$dir"; if (!-d $faildir) { -- cgit v1.2.3 From 1c8a617a274c4065681d964cd5a5afb921de4a87 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Tue, 9 Nov 2010 12:55:40 -0500 Subject: ktest: Added force stop after success and failure Added the options STOP_AFTER_SUCCESS and STOP_AFTER_FAILURE to allow the user to give a time (in seconds) to stop the monitor after a stack trace or login has been detected. Sometimes the kernel constantly prints out to the console and this may cause the test to run indefinitely. Signed-off-by: Steven Rostedt --- tools/testing/ktest/ktest.pl | 33 ++++++++++++++++++++++++++++++++- tools/testing/ktest/sample.conf | 12 ++++++++++++ 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/tools/testing/ktest/ktest.pl b/tools/testing/ktest/ktest.pl index 52e45b8551e8..6e8597398468 100755 --- a/tools/testing/ktest/ktest.pl +++ b/tools/testing/ktest/ktest.pl @@ -45,6 +45,8 @@ $default{"DIE_ON_FAILURE"} = 1; $default{"SSH_EXEC"} = "ssh \$SSH_USER\@\$MACHINE \$SSH_COMMAND"; $default{"SCP_TO_TARGET"} = "scp \$SRC_FILE \$SSH_USER\@\$MACHINE:\$DST_FILE"; $default{"REBOOT"} = "ssh \$SSH_USER\@\$MACHINE reboot"; +$default{"STOP_AFTER_SUCCESS"} = 10; +$default{"STOP_AFTER_FAILURE"} = 60; my $version; my $machine; @@ -94,6 +96,8 @@ my $timeout; my $booted_timeout; my $console; my $success_line; +my $stop_after_success; +my $stop_after_failure; my $build_target; my $target_image; my $localversion; @@ -601,6 +605,9 @@ sub monitor { reboot_to; + my $success_start; + my $failure_start; + for (;;) { if ($booted) { @@ -619,6 +626,16 @@ sub monitor { if ($full_line =~ /$success_line/) { $booted = 1; + $success_start = time; + } + + if ($booted && defined($stop_after_success) && + $stop_after_success >= 0) { + my $now = time; + if ($now - $success_start >= $stop_after_success) { + doprint "Test forced to stop after $stop_after_success seconds after success\n"; + last; + } } if ($full_line =~ /\[ backtrace testing \]/) { @@ -626,7 +643,19 @@ sub monitor { } if ($full_line =~ /call trace:/i) { - $bug = 1 if (!$skip_call_trace); + if (!$skip_call_trace) { + $bug = 1; + $failure_start = time; + } + } + + if ($bug && defined($stop_after_failure) && + $stop_after_failure >= 0) { + my $now = time; + if ($now - $failure_start >= $stop_after_failure) { + doprint "Test forced to stop after $stop_after_failure seconds after failure\n"; + last; + } } if ($full_line =~ /\[ end of backtrace testing \]/) { @@ -1687,6 +1716,8 @@ for (my $i = 1; $i <= $opt{"NUM_TESTS"}; $i++) { $booted_timeout = set_test_option("BOOTED_TIMEOUT", $i); $console = set_test_option("CONSOLE", $i); $success_line = set_test_option("SUCCESS_LINE", $i); + $stop_after_success = set_test_option("STOP_AFTER_SUCCESS", $i); + $stop_after_failure = set_test_option("STOP_AFTER_FAILURE", $i); $build_target = set_test_option("BUILD_TARGET", $i); $ssh_exec = set_test_option("SSH_EXEC", $i); $scp_to_target = set_test_option("SCP_TO_TARGET", $i); diff --git a/tools/testing/ktest/sample.conf b/tools/testing/ktest/sample.conf index e1272746ce8c..3408c594b2de 100644 --- a/tools/testing/ktest/sample.conf +++ b/tools/testing/ktest/sample.conf @@ -294,6 +294,18 @@ # (default "login:") #SUCCESS_LINE = login: +# In case the console constantly fills the screen, having +# a specified time to stop the test after success is recommended. +# (in seconds) +# (default 10) +#STOP_AFTER_SUCCESS = 10 + +# In case the console constantly fills the screen, having +# a specified time to stop the test after failure is recommended. +# (in seconds) +# (default 60) +#STOP_AFTER_FAILURE = 60 + # Stop testing if a build fails. If set, the script will end if # a failure is detected, otherwise it will save off the .config, # dmesg and bootlog in a directory called -- cgit v1.2.3 From eec5646031a54858362f7192a928511a23612f6b Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Wed, 10 Nov 2010 09:08:20 -0500 Subject: ktest: For grub reboot, use run_ssh instead of run_command The run_ssh handles the ssh variable $SSH_COMMAND, which was not being used by the run_command in reboot_to function. Signed-off-by: Steven Rostedt --- tools/testing/ktest/ktest.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/testing/ktest/ktest.pl b/tools/testing/ktest/ktest.pl index 6e8597398468..08a875fa4251 100755 --- a/tools/testing/ktest/ktest.pl +++ b/tools/testing/ktest/ktest.pl @@ -561,7 +561,7 @@ sub wait_for_input sub reboot_to { if ($reboot_type eq "grub") { - run_command "$ssh_exec '(echo \"savedefault --default=$grub_number --once\" | grub --batch; reboot)'"; + run_ssh "'(echo \"savedefault --default=$grub_number --once\" | grub --batch; reboot)'"; return; } -- cgit v1.2.3 From f1a27850095ebc66c138c940c1efedb8a95f92c4 Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Thu, 11 Nov 2010 11:34:38 -0500 Subject: ktest: Copy the last good and bad configs in config_bisect During the config_bisect, in case of failure, it is nice to have the last good and bad .configs that were used. This would let us restart the config_bisect from those configs. Copy the last good config into the output dir as config_good, and the last bad config as config_bad. Signed-off-by: Steven Rostedt --- tools/testing/ktest/ktest.pl | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tools/testing/ktest/ktest.pl b/tools/testing/ktest/ktest.pl index 08a875fa4251..04a3227ef5e0 100755 --- a/tools/testing/ktest/ktest.pl +++ b/tools/testing/ktest/ktest.pl @@ -1281,6 +1281,8 @@ sub process_passed { delete $config_list{$config}; } } + doprint "config copied to $outputdir/config_good\n"; + run_command "cp -f $output_config $outputdir/config_good"; } sub process_failed { @@ -1358,6 +1360,8 @@ sub run_config_bisect { doprint "This config had a failure.\n"; doprint "Removing these configs that were not set in this config:\n"; + doprint "config copied to $outputdir/config_bad\n"; + run_command "cp -f $output_config $outputdir/config_bad"; # A config exists in this group that was bad. foreach my $config (keys %config_list) { -- cgit v1.2.3 From 8d1491bae72e3500b74e1855afa10f0544068cea Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Thu, 18 Nov 2010 15:39:48 -0500 Subject: ktest: Ask for the manditory config options instead of just failing In keeping with the notion that all tools should be simple for all to use. I've changed ktest.pl to ask for mandatory options instead of just failing. It will append (or create) the options the user types in, onto the config file. Signed-off-by: Steven Rostedt --- tools/testing/ktest/ktest.pl | 220 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 206 insertions(+), 14 deletions(-) diff --git a/tools/testing/ktest/ktest.pl b/tools/testing/ktest/ktest.pl index 04a3227ef5e0..e1c62eeb88f5 100755 --- a/tools/testing/ktest/ktest.pl +++ b/tools/testing/ktest/ktest.pl @@ -13,8 +13,6 @@ use FileHandle; my $VERSION = "0.2"; -$#ARGV >= 0 || die "ktest.pl version: $VERSION\n usage: ktest.pl config-file\n"; - $| = 1; my %opt; @@ -47,7 +45,9 @@ $default{"SCP_TO_TARGET"} = "scp \$SRC_FILE \$SSH_USER\@\$MACHINE:\$DST_FILE"; $default{"REBOOT"} = "ssh \$SSH_USER\@\$MACHINE reboot"; $default{"STOP_AFTER_SUCCESS"} = 10; $default{"STOP_AFTER_FAILURE"} = 60; +$default{"LOCALVERSION"} = "-test"; +my $ktest_config; my $version; my $machine; my $ssh_user; @@ -104,6 +104,156 @@ my $localversion; my $iteration = 0; my $successes = 0; +my %entered_configs; +my %config_help; + +$config_help{"MACHINE"} = << "EOF" + The machine hostname that you will test. +EOF + ; +$config_help{"SSH_USER"} = << "EOF" + The box is expected to have ssh on normal bootup, provide the user + (most likely root, since you need privileged operations) +EOF + ; +$config_help{"BUILD_DIR"} = << "EOF" + The directory that contains the Linux source code (full path). +EOF + ; +$config_help{"OUTPUT_DIR"} = << "EOF" + The directory that the objects will be built (full path). + (can not be same as BUILD_DIR) +EOF + ; +$config_help{"BUILD_TARGET"} = << "EOF" + The location of the compiled file to copy to the target. + (relative to OUTPUT_DIR) +EOF + ; +$config_help{"TARGET_IMAGE"} = << "EOF" + The place to put your image on the test machine. +EOF + ; +$config_help{"POWER_CYCLE"} = << "EOF" + A script or command to reboot the box. + + Here is a digital loggers power switch example + POWER_CYCLE = wget --no-proxy -O /dev/null -q --auth-no-challenge 'http://admin:admin\@power/outlet?5=CCL' + + Here is an example to reboot a virtual box on the current host + with the name "Guest". + POWER_CYCLE = virsh destroy Guest; sleep 5; virsh start Guest +EOF + ; +$config_help{"CONSOLE"} = << "EOF" + The script or command that reads the console + + If you use ttywatch server, something like the following would work. +CONSOLE = nc -d localhost 3001 + + For a virtual machine with guest name "Guest". +CONSOLE = virsh console Guest +EOF + ; +$config_help{"LOCALVERSION"} = << "EOF" + Required version ending to differentiate the test + from other linux builds on the system. +EOF + ; +$config_help{"REBOOT_TYPE"} = << "EOF" + Way to reboot the box to the test kernel. + Only valid options so far are "grub" and "script". + + If you specify grub, it will assume grub version 1 + and will search in /boot/grub/menu.lst for the title \$GRUB_MENU + and select that target to reboot to the kernel. If this is not + your setup, then specify "script" and have a command or script + specified in REBOOT_SCRIPT to boot to the target. + + The entry in /boot/grub/menu.lst must be entered in manually. + The test will not modify that file. +EOF + ; +$config_help{"GRUB_MENU"} = << "EOF" + The grub title name for the test kernel to boot + (Only mandatory if REBOOT_TYPE = grub) + + Note, ktest.pl will not update the grub menu.lst, you need to + manually add an option for the test. ktest.pl will search + the grub menu.lst for this option to find what kernel to + reboot into. + + For example, if in the /boot/grub/menu.lst the test kernel title has: + title Test Kernel + kernel vmlinuz-test + GRUB_MENU = Test Kernel +EOF + ; +$config_help{"REBOOT_SCRIPT"} = << "EOF" + A script to reboot the target into the test kernel + (Only mandatory if REBOOT_TYPE = script) +EOF + ; + + +sub get_ktest_config { + my ($config) = @_; + + return if (defined($opt{$config})); + + if (defined($config_help{$config})) { + print "\n"; + print $config_help{$config}; + } + + for (;;) { + print "$config = "; + if (defined($default{$config})) { + print "\[$default{$config}\] "; + } + $entered_configs{$config} = ; + $entered_configs{$config} =~ s/^\s*(.*\S)\s*$/$1/; + if ($entered_configs{$config} =~ /^\s*$/) { + if ($default{$config}) { + $entered_configs{$config} = $default{$config}; + } else { + print "Your answer can not be blank\n"; + next; + } + } + last; + } +} + +sub get_ktest_configs { + get_ktest_config("MACHINE"); + get_ktest_config("SSH_USER"); + get_ktest_config("BUILD_DIR"); + get_ktest_config("OUTPUT_DIR"); + get_ktest_config("BUILD_TARGET"); + get_ktest_config("TARGET_IMAGE"); + get_ktest_config("POWER_CYCLE"); + get_ktest_config("CONSOLE"); + get_ktest_config("LOCALVERSION"); + + my $rtype = $opt{"REBOOT_TYPE"}; + + if (!defined($rtype)) { + if (!defined($opt{"GRUB_MENU"})) { + get_ktest_config("REBOOT_TYPE"); + $rtype = $entered_configs{"REBOOT_TYPE"}; + } else { + $rtype = "grub"; + } + } + + if ($rtype eq "grub") { + get_ktest_config("GRUB_MENU"); + } else { + get_ktest_config("REBOOT_SCRIPT"); + } +} + sub set_value { my ($lvalue, $rvalue) = @_; @@ -241,6 +391,9 @@ sub read_config { $opt{"NUM_TESTS"} = $test_num; } + # make sure we have all mandatory configs + get_ktest_configs; + # set any defaults foreach my $default (keys %default) { @@ -1612,18 +1765,57 @@ sub patchcheck { return 1; } -read_config $ARGV[0]; - -# mandatory configs -die "MACHINE not defined\n" if (!defined($opt{"MACHINE"})); -die "SSH_USER not defined\n" if (!defined($opt{"SSH_USER"})); -die "BUILD_DIR not defined\n" if (!defined($opt{"BUILD_DIR"})); -die "OUTPUT_DIR not defined\n" if (!defined($opt{"OUTPUT_DIR"})); -die "BUILD_TARGET not defined\n" if (!defined($opt{"BUILD_TARGET"})); -die "TARGET_IMAGE not defined\n" if (!defined($opt{"TARGET_IMAGE"})); -die "POWER_CYCLE not defined\n" if (!defined($opt{"POWER_CYCLE"})); -die "CONSOLE not defined\n" if (!defined($opt{"CONSOLE"})); -die "LOCALVERSION not defined\n" if (!defined($opt{"LOCALVERSION"})); +$#ARGV < 1 or die "ktest.pl version: $VERSION\n usage: ktest.pl config-file\n"; + +if ($#ARGV == 0) { + $ktest_config = $ARGV[0]; + if (! -f $ktest_config) { + print "$ktest_config does not exist.\n"; + my $ans; + for (;;) { + print "Create it? [Y/n] "; + $ans = ; + chomp $ans; + if ($ans =~ /^\s*$/) { + $ans = "y"; + } + last if ($ans =~ /^y$/i || $ans =~ /^n$/i); + print "Please answer either 'y' or 'n'.\n"; + } + if ($ans !~ /^y$/i) { + exit 0; + } + } +} else { + $ktest_config = "ktest.conf"; +} + +if (! -f $ktest_config) { + open(OUT, ">$ktest_config") or die "Can not create $ktest_config"; + print OUT << "EOF" +# Generated by ktest.pl +# +# Define each test with TEST_START +# The config options below it will override the defaults +TEST_START + +DEFAULTS +EOF +; + close(OUT); +} +read_config $ktest_config; + +# Append any configs entered in manually to the config file. +my @new_configs = keys %entered_configs; +if ($#new_configs >= 0) { + print "\nAppending entered in configs to $ktest_config\n"; + open(OUT, ">>$ktest_config") or die "Can not append to $ktest_config"; + foreach my $config (@new_configs) { + print OUT "$config = $entered_configs{$config}\n"; + $opt{$config} = $entered_configs{$config}; + } +} if ($opt{"CLEAR_LOG"} && defined($opt{"LOG_FILE"})) { unlink $opt{"LOG_FILE"}; -- cgit v1.2.3 From 8b0ae0b719d4ea9aee4ed3a7a09d5ff76557fadf Mon Sep 17 00:00:00 2001 From: Jassi Brar Date: Fri, 19 Nov 2010 08:49:43 +0900 Subject: ARM: S5PV310: Add platform devices for PL330 DMACs Samsung's Soc S5PV310 has three PL330 DMACs. First is dedicated for Memory->Memory data transfer while the other two meant for data transfer with peripherals. Define and add latter two PL330 DMACs as platform devices on the S5PV310 platform. Signed-off-by: Jassi Brar Acked-by: Mark Brown Acked-by: Liam Girdwood Signed-off-by: Kukjin Kim --- arch/arm/mach-s5pv310/Kconfig | 1 + arch/arm/mach-s5pv310/Makefile | 2 +- arch/arm/mach-s5pv310/dma.c | 168 ++++++++++++++++++++++++++++++ arch/arm/mach-s5pv310/include/mach/dma.h | 26 +++++ arch/arm/mach-s5pv310/include/mach/irqs.h | 3 + arch/arm/mach-s5pv310/include/mach/map.h | 5 + 6 files changed, 204 insertions(+), 1 deletion(-) create mode 100644 arch/arm/mach-s5pv310/dma.c create mode 100644 arch/arm/mach-s5pv310/include/mach/dma.h diff --git a/arch/arm/mach-s5pv310/Kconfig b/arch/arm/mach-s5pv310/Kconfig index 1150b360f38c..d64efe0d4c97 100644 --- a/arch/arm/mach-s5pv310/Kconfig +++ b/arch/arm/mach-s5pv310/Kconfig @@ -11,6 +11,7 @@ if ARCH_S5PV310 config CPU_S5PV310 bool + select S3C_PL330_DMA help Enable S5PV310 CPU support diff --git a/arch/arm/mach-s5pv310/Makefile b/arch/arm/mach-s5pv310/Makefile index 84afc64e7c01..d265adb178e6 100644 --- a/arch/arm/mach-s5pv310/Makefile +++ b/arch/arm/mach-s5pv310/Makefile @@ -13,7 +13,7 @@ obj- := # Core support for S5PV310 system obj-$(CONFIG_CPU_S5PV310) += cpu.o init.o clock.o irq-combiner.o -obj-$(CONFIG_CPU_S5PV310) += setup-i2c0.o time.o gpiolib.o irq-eint.o +obj-$(CONFIG_CPU_S5PV310) += setup-i2c0.o time.o gpiolib.o irq-eint.o dma.o obj-$(CONFIG_SMP) += platsmp.o headsmp.o obj-$(CONFIG_LOCAL_TIMERS) += localtimer.o diff --git a/arch/arm/mach-s5pv310/dma.c b/arch/arm/mach-s5pv310/dma.c new file mode 100644 index 000000000000..20066c7c9e56 --- /dev/null +++ b/arch/arm/mach-s5pv310/dma.c @@ -0,0 +1,168 @@ +/* + * Copyright (C) 2010 Samsung Electronics Co. Ltd. + * Jaswinder Singh + * + * 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. + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include + +#include +#include + +#include +#include + +#include + +static u64 dma_dmamask = DMA_BIT_MASK(32); + +static struct resource s5pv310_pdma0_resource[] = { + [0] = { + .start = S5PV310_PA_PDMA0, + .end = S5PV310_PA_PDMA0 + SZ_4K, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_PDMA0, + .end = IRQ_PDMA0, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct s3c_pl330_platdata s5pv310_pdma0_pdata = { + .peri = { + [0] = DMACH_PCM0_RX, + [1] = DMACH_PCM0_TX, + [2] = DMACH_PCM2_RX, + [3] = DMACH_PCM2_TX, + [4] = DMACH_MSM_REQ0, + [5] = DMACH_MSM_REQ2, + [6] = DMACH_SPI0_RX, + [7] = DMACH_SPI0_TX, + [8] = DMACH_SPI2_RX, + [9] = DMACH_SPI2_TX, + [10] = DMACH_I2S0S_TX, + [11] = DMACH_I2S0_RX, + [12] = DMACH_I2S0_TX, + [13] = DMACH_I2S2_RX, + [14] = DMACH_I2S2_TX, + [15] = DMACH_UART0_RX, + [16] = DMACH_UART0_TX, + [17] = DMACH_UART2_RX, + [18] = DMACH_UART2_TX, + [19] = DMACH_UART4_RX, + [20] = DMACH_UART4_TX, + [21] = DMACH_SLIMBUS0_RX, + [22] = DMACH_SLIMBUS0_TX, + [23] = DMACH_SLIMBUS2_RX, + [24] = DMACH_SLIMBUS2_TX, + [25] = DMACH_SLIMBUS4_RX, + [26] = DMACH_SLIMBUS4_TX, + [27] = DMACH_AC97_MICIN, + [28] = DMACH_AC97_PCMIN, + [29] = DMACH_AC97_PCMOUT, + [30] = DMACH_MAX, + [31] = DMACH_MAX, + }, +}; + +static struct platform_device s5pv310_device_pdma0 = { + .name = "s3c-pl330", + .id = 0, + .num_resources = ARRAY_SIZE(s5pv310_pdma0_resource), + .resource = s5pv310_pdma0_resource, + .dev = { + .dma_mask = &dma_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &s5pv310_pdma0_pdata, + }, +}; + +static struct resource s5pv310_pdma1_resource[] = { + [0] = { + .start = S5PV310_PA_PDMA1, + .end = S5PV310_PA_PDMA1 + SZ_4K, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = IRQ_PDMA1, + .end = IRQ_PDMA1, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct s3c_pl330_platdata s5pv310_pdma1_pdata = { + .peri = { + [0] = DMACH_PCM0_RX, + [1] = DMACH_PCM0_TX, + [2] = DMACH_PCM1_RX, + [3] = DMACH_PCM1_TX, + [4] = DMACH_MSM_REQ1, + [5] = DMACH_MSM_REQ3, + [6] = DMACH_SPI1_RX, + [7] = DMACH_SPI1_TX, + [8] = DMACH_I2S0S_TX, + [9] = DMACH_I2S0_RX, + [10] = DMACH_I2S0_TX, + [11] = DMACH_I2S1_RX, + [12] = DMACH_I2S1_TX, + [13] = DMACH_UART0_RX, + [14] = DMACH_UART0_TX, + [15] = DMACH_UART1_RX, + [16] = DMACH_UART1_TX, + [17] = DMACH_UART3_RX, + [18] = DMACH_UART3_TX, + [19] = DMACH_SLIMBUS1_RX, + [20] = DMACH_SLIMBUS1_TX, + [21] = DMACH_SLIMBUS3_RX, + [22] = DMACH_SLIMBUS3_TX, + [23] = DMACH_SLIMBUS5_RX, + [24] = DMACH_SLIMBUS5_TX, + [25] = DMACH_SLIMBUS0AUX_RX, + [26] = DMACH_SLIMBUS0AUX_TX, + [27] = DMACH_SPDIF, + [28] = DMACH_MAX, + [29] = DMACH_MAX, + [30] = DMACH_MAX, + [31] = DMACH_MAX, + }, +}; + +static struct platform_device s5pv310_device_pdma1 = { + .name = "s3c-pl330", + .id = 1, + .num_resources = ARRAY_SIZE(s5pv310_pdma1_resource), + .resource = s5pv310_pdma1_resource, + .dev = { + .dma_mask = &dma_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &s5pv310_pdma1_pdata, + }, +}; + +static struct platform_device *s5pv310_dmacs[] __initdata = { + &s5pv310_device_pdma0, + &s5pv310_device_pdma1, +}; + +static int __init s5pv310_dma_init(void) +{ + platform_add_devices(s5pv310_dmacs, ARRAY_SIZE(s5pv310_dmacs)); + + return 0; +} +arch_initcall(s5pv310_dma_init); diff --git a/arch/arm/mach-s5pv310/include/mach/dma.h b/arch/arm/mach-s5pv310/include/mach/dma.h new file mode 100644 index 000000000000..81209eb1409b --- /dev/null +++ b/arch/arm/mach-s5pv310/include/mach/dma.h @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2010 Samsung Electronics Co. Ltd. + * Jaswinder Singh + * + * 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. + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef __MACH_DMA_H +#define __MACH_DMA_H + +/* This platform uses the common S3C DMA API driver for PL330 */ +#include + +#endif /* __MACH_DMA_H */ diff --git a/arch/arm/mach-s5pv310/include/mach/irqs.h b/arch/arm/mach-s5pv310/include/mach/irqs.h index 99e7dad8a85a..3c05c58b5392 100644 --- a/arch/arm/mach-s5pv310/include/mach/irqs.h +++ b/arch/arm/mach-s5pv310/include/mach/irqs.h @@ -54,6 +54,9 @@ #define COMBINER_GROUP(x) ((x) * MAX_IRQ_IN_COMBINER + IRQ_SPI(64)) #define COMBINER_IRQ(x, y) (COMBINER_GROUP(x) + y) +#define IRQ_PDMA0 COMBINER_IRQ(21, 0) +#define IRQ_PDMA1 COMBINER_IRQ(21, 1) + #define IRQ_TIMER0_VIC COMBINER_IRQ(22, 0) #define IRQ_TIMER1_VIC COMBINER_IRQ(22, 1) #define IRQ_TIMER2_VIC COMBINER_IRQ(22, 2) diff --git a/arch/arm/mach-s5pv310/include/mach/map.h b/arch/arm/mach-s5pv310/include/mach/map.h index 7acf4e77e92e..169fac2899f0 100644 --- a/arch/arm/mach-s5pv310/include/mach/map.h +++ b/arch/arm/mach-s5pv310/include/mach/map.h @@ -52,6 +52,11 @@ #define S5PV310_PA_GIC_DIST (0x10501000) #define S5PV310_PA_L2CC (0x10502000) +/* DMA */ +#define S5PV310_PA_MDMA 0x10810000 +#define S5PV310_PA_PDMA0 0x12680000 +#define S5PV310_PA_PDMA1 0x12690000 + #define S5PV310_PA_GPIO1 (0x11400000) #define S5PV310_PA_GPIO2 (0x11000000) #define S5PV310_PA_GPIO3 (0x03860000) -- cgit v1.2.3 From daea9b4f4416384dfcd0021a9461717974ed4354 Mon Sep 17 00:00:00 2001 From: Jassi Brar Date: Fri, 19 Nov 2010 08:49:43 +0900 Subject: ARM: SAMSUNG: Rename s3c64xx I2S platform device Since the I2S of S3C64XX and newer SoCs are incremental versions of each other with changes managable in a single driver, rename the 's3c64xx-iis' -> 'samsung-i2s' Signed-off-by: Jassi Brar Acked-by: Mark Brown Acked-by: Liam Girdwood Signed-off-by: Kukjin Kim --- arch/arm/mach-s3c64xx/dev-audio.c | 6 +++--- arch/arm/mach-s5p6442/dev-audio.c | 4 ++-- arch/arm/mach-s5p64x0/dev-audio.c | 4 ++-- arch/arm/mach-s5pc100/dev-audio.c | 6 +++--- arch/arm/mach-s5pv210/dev-audio.c | 6 +++--- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/arch/arm/mach-s3c64xx/dev-audio.c b/arch/arm/mach-s3c64xx/dev-audio.c index 76426a32c013..447e4e7179ac 100644 --- a/arch/arm/mach-s3c64xx/dev-audio.c +++ b/arch/arm/mach-s3c64xx/dev-audio.c @@ -77,7 +77,7 @@ static struct s3c_audio_pdata s3c_i2s0_pdata = { }; struct platform_device s3c64xx_device_iis0 = { - .name = "s3c64xx-iis", + .name = "samsung-i2s", .id = 0, .num_resources = ARRAY_SIZE(s3c64xx_iis0_resource), .resource = s3c64xx_iis0_resource, @@ -110,7 +110,7 @@ static struct s3c_audio_pdata s3c_i2s1_pdata = { }; struct platform_device s3c64xx_device_iis1 = { - .name = "s3c64xx-iis", + .name = "samsung-i2s", .id = 1, .num_resources = ARRAY_SIZE(s3c64xx_iis1_resource), .resource = s3c64xx_iis1_resource, @@ -143,7 +143,7 @@ static struct s3c_audio_pdata s3c_i2sv4_pdata = { }; struct platform_device s3c64xx_device_iisv4 = { - .name = "s3c64xx-iis-v4", + .name = "samsung-i2s-v4", .id = -1, .num_resources = ARRAY_SIZE(s3c64xx_iisv4_resource), .resource = s3c64xx_iisv4_resource, diff --git a/arch/arm/mach-s5p6442/dev-audio.c b/arch/arm/mach-s5p6442/dev-audio.c index 3462197ff352..d0207b7634b6 100644 --- a/arch/arm/mach-s5p6442/dev-audio.c +++ b/arch/arm/mach-s5p6442/dev-audio.c @@ -65,7 +65,7 @@ static struct resource s5p6442_iis0_resource[] = { }; struct platform_device s5p6442_device_iis0 = { - .name = "s3c64xx-iis-v4", + .name = "samsung-i2s-v4", .id = -1, .num_resources = ARRAY_SIZE(s5p6442_iis0_resource), .resource = s5p6442_iis0_resource, @@ -93,7 +93,7 @@ static struct resource s5p6442_iis1_resource[] = { }; struct platform_device s5p6442_device_iis1 = { - .name = "s3c64xx-iis", + .name = "samsung-i2s", .id = 1, .num_resources = ARRAY_SIZE(s5p6442_iis1_resource), .resource = s5p6442_iis1_resource, diff --git a/arch/arm/mach-s5p64x0/dev-audio.c b/arch/arm/mach-s5p64x0/dev-audio.c index 396bacc0a39a..fb613d0f3808 100644 --- a/arch/arm/mach-s5p64x0/dev-audio.c +++ b/arch/arm/mach-s5p64x0/dev-audio.c @@ -82,7 +82,7 @@ static struct resource s5p64x0_iis0_resource[] = { }; struct platform_device s5p6440_device_iis = { - .name = "s3c64xx-iis-v4", + .name = "samsung-i2s-v4", .id = -1, .num_resources = ARRAY_SIZE(s5p64x0_iis0_resource), .resource = s5p64x0_iis0_resource, @@ -92,7 +92,7 @@ struct platform_device s5p6440_device_iis = { }; struct platform_device s5p6450_device_iis0 = { - .name = "s3c64xx-iis-v4", + .name = "samsung-i2s-v4", .id = -1, .num_resources = ARRAY_SIZE(s5p64x0_iis0_resource), .resource = s5p64x0_iis0_resource, diff --git a/arch/arm/mach-s5pc100/dev-audio.c b/arch/arm/mach-s5pc100/dev-audio.c index 564e195ec493..bf0c90fa4a98 100644 --- a/arch/arm/mach-s5pc100/dev-audio.c +++ b/arch/arm/mach-s5pc100/dev-audio.c @@ -65,7 +65,7 @@ static struct resource s5pc100_iis0_resource[] = { }; struct platform_device s5pc100_device_iis0 = { - .name = "s3c64xx-iis-v4", + .name = "samsung-i2s-v4", .id = -1, .num_resources = ARRAY_SIZE(s5pc100_iis0_resource), .resource = s5pc100_iis0_resource, @@ -93,7 +93,7 @@ static struct resource s5pc100_iis1_resource[] = { }; struct platform_device s5pc100_device_iis1 = { - .name = "s3c64xx-iis", + .name = "samsung-i2s", .id = 1, .num_resources = ARRAY_SIZE(s5pc100_iis1_resource), .resource = s5pc100_iis1_resource, @@ -121,7 +121,7 @@ static struct resource s5pc100_iis2_resource[] = { }; struct platform_device s5pc100_device_iis2 = { - .name = "s3c64xx-iis", + .name = "samsung-i2s", .id = 2, .num_resources = ARRAY_SIZE(s5pc100_iis2_resource), .resource = s5pc100_iis2_resource, diff --git a/arch/arm/mach-s5pv210/dev-audio.c b/arch/arm/mach-s5pv210/dev-audio.c index 1303fcb12b51..961477ac5baa 100644 --- a/arch/arm/mach-s5pv210/dev-audio.c +++ b/arch/arm/mach-s5pv210/dev-audio.c @@ -66,7 +66,7 @@ static struct resource s5pv210_iis0_resource[] = { }; struct platform_device s5pv210_device_iis0 = { - .name = "s3c64xx-iis-v4", + .name = "samsung-i2s-v4", .id = -1, .num_resources = ARRAY_SIZE(s5pv210_iis0_resource), .resource = s5pv210_iis0_resource, @@ -94,7 +94,7 @@ static struct resource s5pv210_iis1_resource[] = { }; struct platform_device s5pv210_device_iis1 = { - .name = "s3c64xx-iis", + .name = "samsung-i2s", .id = 1, .num_resources = ARRAY_SIZE(s5pv210_iis1_resource), .resource = s5pv210_iis1_resource, @@ -122,7 +122,7 @@ static struct resource s5pv210_iis2_resource[] = { }; struct platform_device s5pv210_device_iis2 = { - .name = "s3c64xx-iis", + .name = "samsung-i2s", .id = 2, .num_resources = ARRAY_SIZE(s5pv210_iis2_resource), .resource = s5pv210_iis2_resource, -- cgit v1.2.3 From 498c08805fdbfc0d8a3538bf288475fa3a064fb7 Mon Sep 17 00:00:00 2001 From: Jassi Brar Date: Fri, 19 Nov 2010 08:49:44 +0900 Subject: ARM: SAMSUNG: Prepare audio header for new I2S driver Add new defined and data structures in order to prepare for new I2S driver. Signed-off-by: Jassi Brar Acked-by: Mark Brown Acked-by: Liam Girdwood Signed-off-by: Kukjin Kim --- arch/arm/plat-samsung/include/plat/audio.h | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/arch/arm/plat-samsung/include/plat/audio.h b/arch/arm/plat-samsung/include/plat/audio.h index 7712ff6336f4..a0826ed2f9fe 100644 --- a/arch/arm/plat-samsung/include/plat/audio.h +++ b/arch/arm/plat-samsung/include/plat/audio.h @@ -25,10 +25,34 @@ extern void s3c64xx_ac97_setup_gpio(int); #define S5PC100_SPDIF_GPG3 1 extern void s5pc100_spdif_setup_gpio(int); +struct samsung_i2s { +/* If the Primary DAI has 5.1 Channels */ +#define QUIRK_PRI_6CHAN (1 << 0) +/* If the I2S block has a Stereo Overlay Channel */ +#define QUIRK_SEC_DAI (1 << 1) +/* + * If the I2S block has no internal prescalar or MUX (I2SMOD[10] bit) + * The Machine driver must provide suitably set clock to the I2S block. + */ +#define QUIRK_NO_MUXPSR (1 << 2) +#define QUIRK_NEED_RSTCLR (1 << 3) + /* Quirks of the I2S controller */ + u32 quirks; + + /* + * Array of clock names that can be used to generate I2S signals. + * Also corresponds to clocks of I2SMOD[10] + */ + const char **src_clk; +}; + /** * struct s3c_audio_pdata - common platform data for audio device drivers * @cfg_gpio: Callback function to setup mux'ed pins in I2S/PCM/AC97 mode */ struct s3c_audio_pdata { int (*cfg_gpio)(struct platform_device *); + union { + struct samsung_i2s i2s; + } type; }; -- cgit v1.2.3 From 6a62bee2105250ac02bf3c96b7f35e28dac36888 Mon Sep 17 00:00:00 2001 From: Jassi Brar Date: Fri, 19 Nov 2010 08:49:44 +0900 Subject: ARM: S3C64XX: Upgrade platform device for I2S Add more information to I2S platform_devices in order to prepare them for new controller driver. Signed-off-by: Jassi Brar Acked-by: Mark Brown Acked-by: Liam Girdwood Signed-off-by: Kukjin Kim --- arch/arm/mach-s3c64xx/clock.c | 2 +- arch/arm/mach-s3c64xx/dev-audio.c | 56 ++++++++++++++++++++++----------------- 2 files changed, 33 insertions(+), 25 deletions(-) diff --git a/arch/arm/mach-s3c64xx/clock.c b/arch/arm/mach-s3c64xx/clock.c index 7e03f0ae2fc8..1c98d2ff2ed6 100644 --- a/arch/arm/mach-s3c64xx/clock.c +++ b/arch/arm/mach-s3c64xx/clock.c @@ -695,7 +695,7 @@ static struct clksrc_clk clksrcs[] = { }, { .clk = { .name = "audio-bus", - .id = -1, /* There's only one IISv4 port */ + .id = 2, .ctrlbit = S3C6410_CLKCON_SCLK_AUDIO2, .enable = s3c64xx_sclk_ctrl, }, diff --git a/arch/arm/mach-s3c64xx/dev-audio.c b/arch/arm/mach-s3c64xx/dev-audio.c index 447e4e7179ac..7618627b98f5 100644 --- a/arch/arm/mach-s3c64xx/dev-audio.c +++ b/arch/arm/mach-s3c64xx/dev-audio.c @@ -22,7 +22,12 @@ #include #include -static int s3c64xx_i2sv3_cfg_gpio(struct platform_device *pdev) +static const char *rclksrc[] = { + [0] = "iis", + [1] = "audio-bus", +}; + +static int s3c64xx_i2s_cfg_gpio(struct platform_device *pdev) { unsigned int base; @@ -33,6 +38,12 @@ static int s3c64xx_i2sv3_cfg_gpio(struct platform_device *pdev) case 1: base = S3C64XX_GPE(0); break; + case 2: + s3c_gpio_cfgpin(S3C64XX_GPC(4), S3C_GPIO_SFN(5)); + s3c_gpio_cfgpin(S3C64XX_GPC(5), S3C_GPIO_SFN(5)); + s3c_gpio_cfgpin(S3C64XX_GPC(7), S3C_GPIO_SFN(5)); + s3c_gpio_cfgpin_range(S3C64XX_GPH(6), 4, S3C_GPIO_SFN(5)); + return 0; default: printk(KERN_DEBUG "Invalid I2S Controller number: %d\n", pdev->id); @@ -44,16 +55,6 @@ static int s3c64xx_i2sv3_cfg_gpio(struct platform_device *pdev) return 0; } -static int s3c64xx_i2sv4_cfg_gpio(struct platform_device *pdev) -{ - s3c_gpio_cfgpin(S3C64XX_GPC(4), S3C_GPIO_SFN(5)); - s3c_gpio_cfgpin(S3C64XX_GPC(5), S3C_GPIO_SFN(5)); - s3c_gpio_cfgpin(S3C64XX_GPC(7), S3C_GPIO_SFN(5)); - s3c_gpio_cfgpin_range(S3C64XX_GPH(6), 4, S3C_GPIO_SFN(5)); - - return 0; -} - static struct resource s3c64xx_iis0_resource[] = { [0] = { .start = S3C64XX_PA_IIS0, @@ -72,8 +73,13 @@ static struct resource s3c64xx_iis0_resource[] = { }, }; -static struct s3c_audio_pdata s3c_i2s0_pdata = { - .cfg_gpio = s3c64xx_i2sv3_cfg_gpio, +static struct s3c_audio_pdata i2sv3_pdata = { + .cfg_gpio = s3c64xx_i2s_cfg_gpio, + .type = { + .i2s = { + .src_clk = rclksrc, + }, + }, }; struct platform_device s3c64xx_device_iis0 = { @@ -82,7 +88,7 @@ struct platform_device s3c64xx_device_iis0 = { .num_resources = ARRAY_SIZE(s3c64xx_iis0_resource), .resource = s3c64xx_iis0_resource, .dev = { - .platform_data = &s3c_i2s0_pdata, + .platform_data = &i2sv3_pdata, }, }; EXPORT_SYMBOL(s3c64xx_device_iis0); @@ -105,17 +111,13 @@ static struct resource s3c64xx_iis1_resource[] = { }, }; -static struct s3c_audio_pdata s3c_i2s1_pdata = { - .cfg_gpio = s3c64xx_i2sv3_cfg_gpio, -}; - struct platform_device s3c64xx_device_iis1 = { .name = "samsung-i2s", .id = 1, .num_resources = ARRAY_SIZE(s3c64xx_iis1_resource), .resource = s3c64xx_iis1_resource, .dev = { - .platform_data = &s3c_i2s1_pdata, + .platform_data = &i2sv3_pdata, }, }; EXPORT_SYMBOL(s3c64xx_device_iis1); @@ -138,17 +140,23 @@ static struct resource s3c64xx_iisv4_resource[] = { }, }; -static struct s3c_audio_pdata s3c_i2sv4_pdata = { - .cfg_gpio = s3c64xx_i2sv4_cfg_gpio, +static struct s3c_audio_pdata i2sv4_pdata = { + .cfg_gpio = s3c64xx_i2s_cfg_gpio, + .type = { + .i2s = { + .quirks = QUIRK_PRI_6CHAN, + .src_clk = rclksrc, + }, + }, }; struct platform_device s3c64xx_device_iisv4 = { - .name = "samsung-i2s-v4", - .id = -1, + .name = "samsung-i2s", + .id = 2, .num_resources = ARRAY_SIZE(s3c64xx_iisv4_resource), .resource = s3c64xx_iisv4_resource, .dev = { - .platform_data = &s3c_i2sv4_pdata, + .platform_data = &i2sv4_pdata, }, }; EXPORT_SYMBOL(s3c64xx_device_iisv4); -- cgit v1.2.3 From d9a93c345a5503668ca2b3a75be0eba1131c90e4 Mon Sep 17 00:00:00 2001 From: Jassi Brar Date: Fri, 19 Nov 2010 08:49:44 +0900 Subject: ARM: S5P64X0: Upgrade platform device for I2S Add more information to I2S platform_devices in order to prepare them for new controller driver. Also, discard duplicated gpio-cfg. Signed-off-by: Jassi Brar Acked-by: Mark Brown Acked-by: Liam Girdwood Signed-off-by: Kukjin Kim --- arch/arm/mach-s5p64x0/clock-s5p6440.c | 2 +- arch/arm/mach-s5p64x0/clock-s5p6450.c | 2 +- arch/arm/mach-s5p64x0/dev-audio.c | 55 +++++++++++++---------------------- 3 files changed, 23 insertions(+), 36 deletions(-) diff --git a/arch/arm/mach-s5p64x0/clock-s5p6440.c b/arch/arm/mach-s5p64x0/clock-s5p6440.c index e4883dc1c8d7..409c5fc3670d 100644 --- a/arch/arm/mach-s5p64x0/clock-s5p6440.c +++ b/arch/arm/mach-s5p64x0/clock-s5p6440.c @@ -261,7 +261,7 @@ static struct clk init_clocks_disable[] = { .enable = s5p64x0_pclk_ctrl, .ctrlbit = (1 << 25), }, { - .name = "i2s_v40", + .name = "iis", .id = 0, .parent = &clk_pclk_low.clk, .enable = s5p64x0_pclk_ctrl, diff --git a/arch/arm/mach-s5p64x0/clock-s5p6450.c b/arch/arm/mach-s5p64x0/clock-s5p6450.c index 7dbf3c968f53..7fc6abd35914 100644 --- a/arch/arm/mach-s5p64x0/clock-s5p6450.c +++ b/arch/arm/mach-s5p64x0/clock-s5p6450.c @@ -256,7 +256,7 @@ static struct clk init_clocks_disable[] = { .ctrlbit = (1 << 22), }, { .name = "iis", - .id = -1, + .id = 0, .parent = &clk_pclk_low.clk, .enable = s5p64x0_pclk_ctrl, .ctrlbit = (1 << 26), diff --git a/arch/arm/mach-s5p64x0/dev-audio.c b/arch/arm/mach-s5p64x0/dev-audio.c index fb613d0f3808..14f89e73b8de 100644 --- a/arch/arm/mach-s5p64x0/dev-audio.c +++ b/arch/arm/mach-s5p64x0/dev-audio.c @@ -19,15 +19,19 @@ #include #include -static int s5p6440_cfg_i2s(struct platform_device *pdev) +static const char *rclksrc[] = { + [0] = "iis", + [1] = "sclk_audio2", +}; + +static int s5p64x0_cfg_i2s(struct platform_device *pdev) { /* configure GPIO for i2s port */ switch (pdev->id) { - case -1: + case 0: s3c_gpio_cfgpin_range(S5P6440_GPR(4), 5, S3C_GPIO_SFN(5)); s3c_gpio_cfgpin_range(S5P6440_GPR(13), 2, S3C_GPIO_SFN(5)); break; - default: printk(KERN_ERR "Invalid Device %d\n", pdev->id); return -EINVAL; @@ -36,31 +40,14 @@ static int s5p6440_cfg_i2s(struct platform_device *pdev) return 0; } -static int s5p6450_cfg_i2s(struct platform_device *pdev) -{ - /* configure GPIO for i2s port */ - switch (pdev->id) { - case -1: - s3c_gpio_cfgpin(S5P6450_GPB(4), S3C_GPIO_SFN(5)); - s3c_gpio_cfgpin_range(S5P6450_GPR(4), 5, S3C_GPIO_SFN(5)); - s3c_gpio_cfgpin_range(S5P6450_GPR(13), 2, S3C_GPIO_SFN(5)); - - break; - - default: - printk(KERN_ERR "Invalid Device %d\n", pdev->id); - return -EINVAL; - } - - return 0; -} - -static struct s3c_audio_pdata s5p6440_i2s_pdata = { - .cfg_gpio = s5p6440_cfg_i2s, -}; - -static struct s3c_audio_pdata s5p6450_i2s_pdata = { - .cfg_gpio = s5p6450_cfg_i2s, +static struct s3c_audio_pdata s5p64x0_i2s_pdata = { + .cfg_gpio = s5p64x0_cfg_i2s, + .type = { + .i2s = { + .quirks = QUIRK_PRI_6CHAN, + .src_clk = rclksrc, + }, + }, }; static struct resource s5p64x0_iis0_resource[] = { @@ -82,22 +69,22 @@ static struct resource s5p64x0_iis0_resource[] = { }; struct platform_device s5p6440_device_iis = { - .name = "samsung-i2s-v4", - .id = -1, + .name = "samsung-i2s", + .id = 0, .num_resources = ARRAY_SIZE(s5p64x0_iis0_resource), .resource = s5p64x0_iis0_resource, .dev = { - .platform_data = &s5p6440_i2s_pdata, + .platform_data = &s5p64x0_i2s_pdata, }, }; struct platform_device s5p6450_device_iis0 = { - .name = "samsung-i2s-v4", - .id = -1, + .name = "samsung-i2s", + .id = 0, .num_resources = ARRAY_SIZE(s5p64x0_iis0_resource), .resource = s5p64x0_iis0_resource, .dev = { - .platform_data = &s5p6450_i2s_pdata, + .platform_data = &s5p64x0_i2s_pdata, }, }; -- cgit v1.2.3 From 4f2e4e124c91bb5105b8ecc8928e5fc0f2b2af0f Mon Sep 17 00:00:00 2001 From: Jassi Brar Date: Fri, 19 Nov 2010 08:49:44 +0900 Subject: ARM: S5P6442: Upgrade platform device for I2S Add more information to I2S platform_devices in order to prepare them for new controller driver. Signed-off-by: Jassi Brar Acked-by: Mark Brown Acked-by: Liam Girdwood Signed-off-by: Kukjin Kim --- arch/arm/mach-s5p6442/dev-audio.c | 42 +++++++++++++++++++++++++++++++++------ 1 file changed, 36 insertions(+), 6 deletions(-) diff --git a/arch/arm/mach-s5p6442/dev-audio.c b/arch/arm/mach-s5p6442/dev-audio.c index d0207b7634b6..8719dc41fe32 100644 --- a/arch/arm/mach-s5p6442/dev-audio.c +++ b/arch/arm/mach-s5p6442/dev-audio.c @@ -29,7 +29,7 @@ static int s5p6442_cfg_i2s(struct platform_device *pdev) base = S5P6442_GPC1(0); break; - case -1: + case 0: base = S5P6442_GPC0(0); break; @@ -42,8 +42,19 @@ static int s5p6442_cfg_i2s(struct platform_device *pdev) return 0; } -static struct s3c_audio_pdata s3c_i2s_pdata = { +static const char *rclksrc_v35[] = { + [0] = "busclk", + [1] = "i2sclk", +}; + +static struct s3c_audio_pdata i2sv35_pdata = { .cfg_gpio = s5p6442_cfg_i2s, + .type = { + .i2s = { + .quirks = QUIRK_SEC_DAI | QUIRK_NEED_RSTCLR, + .src_clk = rclksrc_v35, + }, + }, }; static struct resource s5p6442_iis0_resource[] = { @@ -62,15 +73,34 @@ static struct resource s5p6442_iis0_resource[] = { .end = DMACH_I2S0_RX, .flags = IORESOURCE_DMA, }, + [3] = { + .start = DMACH_I2S0S_TX, + .end = DMACH_I2S0S_TX, + .flags = IORESOURCE_DMA, + }, }; struct platform_device s5p6442_device_iis0 = { - .name = "samsung-i2s-v4", - .id = -1, + .name = "samsung-i2s", + .id = 0, .num_resources = ARRAY_SIZE(s5p6442_iis0_resource), .resource = s5p6442_iis0_resource, .dev = { - .platform_data = &s3c_i2s_pdata, + .platform_data = &i2sv35_pdata, + }, +}; + +static const char *rclksrc_v3[] = { + [0] = "iis", + [1] = "sclk_audio", +}; + +static struct s3c_audio_pdata i2sv3_pdata = { + .cfg_gpio = s5p6442_cfg_i2s, + .type = { + .i2s = { + .src_clk = rclksrc_v3, + }, }, }; @@ -98,7 +128,7 @@ struct platform_device s5p6442_device_iis1 = { .num_resources = ARRAY_SIZE(s5p6442_iis1_resource), .resource = s5p6442_iis1_resource, .dev = { - .platform_data = &s3c_i2s_pdata, + .platform_data = &i2sv3_pdata, }, }; -- cgit v1.2.3 From 651cba5d17564e684584e544ff9111a3cb409c94 Mon Sep 17 00:00:00 2001 From: Jassi Brar Date: Fri, 19 Nov 2010 08:49:44 +0900 Subject: ARM: S5PC100: Upgrade platform device for I2S Add more information to I2S platform_devices in order to prepare them for new controller driver. Signed-off-by: Jassi Brar Acked-by: Mark Brown Acked-by: Liam Girdwood Signed-off-by: Kukjin Kim --- arch/arm/mach-s5pc100/dev-audio.c | 50 ++++++++++++++++++++++++++++++--------- 1 file changed, 39 insertions(+), 11 deletions(-) diff --git a/arch/arm/mach-s5pc100/dev-audio.c b/arch/arm/mach-s5pc100/dev-audio.c index bf0c90fa4a98..10ab275ebd63 100644 --- a/arch/arm/mach-s5pc100/dev-audio.c +++ b/arch/arm/mach-s5pc100/dev-audio.c @@ -23,17 +23,14 @@ static int s5pc100_cfg_i2s(struct platform_device *pdev) { /* configure GPIO for i2s port */ switch (pdev->id) { + case 0: /* Dedicated pins */ + break; case 1: s3c_gpio_cfgpin_range(S5PC100_GPC(0), 5, S3C_GPIO_SFN(2)); break; - case 2: s3c_gpio_cfgpin_range(S5PC100_GPG3(0), 5, S3C_GPIO_SFN(4)); break; - - case -1: /* Dedicated pins */ - break; - default: printk(KERN_ERR "Invalid Device %d\n", pdev->id); return -EINVAL; @@ -42,8 +39,20 @@ static int s5pc100_cfg_i2s(struct platform_device *pdev) return 0; } -static struct s3c_audio_pdata s3c_i2s_pdata = { +static const char *rclksrc_v5[] = { + [0] = "iis", + [1] = "i2sclkd2", +}; + +static struct s3c_audio_pdata i2sv5_pdata = { .cfg_gpio = s5pc100_cfg_i2s, + .type = { + .i2s = { + .quirks = QUIRK_PRI_6CHAN | QUIRK_SEC_DAI + | QUIRK_NEED_RSTCLR, + .src_clk = rclksrc_v5, + }, + }, }; static struct resource s5pc100_iis0_resource[] = { @@ -62,15 +71,34 @@ static struct resource s5pc100_iis0_resource[] = { .end = DMACH_I2S0_RX, .flags = IORESOURCE_DMA, }, + [3] = { + .start = DMACH_I2S0S_TX, + .end = DMACH_I2S0S_TX, + .flags = IORESOURCE_DMA, + }, }; struct platform_device s5pc100_device_iis0 = { - .name = "samsung-i2s-v4", - .id = -1, + .name = "samsung-i2s", + .id = 0, .num_resources = ARRAY_SIZE(s5pc100_iis0_resource), .resource = s5pc100_iis0_resource, .dev = { - .platform_data = &s3c_i2s_pdata, + .platform_data = &i2sv5_pdata, + }, +}; + +static const char *rclksrc_v3[] = { + [0] = "iis", + [1] = "sclk_audio", +}; + +static struct s3c_audio_pdata i2sv3_pdata = { + .cfg_gpio = s5pc100_cfg_i2s, + .type = { + .i2s = { + .src_clk = rclksrc_v3, + }, }, }; @@ -98,7 +126,7 @@ struct platform_device s5pc100_device_iis1 = { .num_resources = ARRAY_SIZE(s5pc100_iis1_resource), .resource = s5pc100_iis1_resource, .dev = { - .platform_data = &s3c_i2s_pdata, + .platform_data = &i2sv3_pdata, }, }; @@ -126,7 +154,7 @@ struct platform_device s5pc100_device_iis2 = { .num_resources = ARRAY_SIZE(s5pc100_iis2_resource), .resource = s5pc100_iis2_resource, .dev = { - .platform_data = &s3c_i2s_pdata, + .platform_data = &i2sv3_pdata, }, }; -- cgit v1.2.3 From 9aa2570e9be4bc43a0ea6abb637d525088ed22b9 Mon Sep 17 00:00:00 2001 From: Jassi Brar Date: Fri, 19 Nov 2010 08:49:44 +0900 Subject: ARM: S5PV210: Upgrade platform device for I2S Add more information to I2S platform_devices in order to prepare them for new controller driver. Signed-off-by: Jassi Brar Acked-by: Mark Brown Acked-by: Liam Girdwood Signed-off-by: Kukjin Kim --- arch/arm/mach-s5pv210/clock.c | 10 ++++---- arch/arm/mach-s5pv210/dev-audio.c | 52 ++++++++++++++++++++++++++++++--------- 2 files changed, 45 insertions(+), 17 deletions(-) diff --git a/arch/arm/mach-s5pv210/clock.c b/arch/arm/mach-s5pv210/clock.c index 019c3a69b0e4..b774ff1805db 100644 --- a/arch/arm/mach-s5pv210/clock.c +++ b/arch/arm/mach-s5pv210/clock.c @@ -467,20 +467,20 @@ static struct clk init_clocks_disable[] = { .enable = s5pv210_clk_ip3_ctrl, .ctrlbit = (1<<21), }, { - .name = "i2s_v50", + .name = "iis", .id = 0, .parent = &clk_p, .enable = s5pv210_clk_ip3_ctrl, .ctrlbit = (1<<4), }, { - .name = "i2s_v32", - .id = 0, + .name = "iis", + .id = 1, .parent = &clk_p, .enable = s5pv210_clk_ip3_ctrl, .ctrlbit = (1 << 5), }, { - .name = "i2s_v32", - .id = 1, + .name = "iis", + .id = 2, .parent = &clk_p, .enable = s5pv210_clk_ip3_ctrl, .ctrlbit = (1 << 6), diff --git a/arch/arm/mach-s5pv210/dev-audio.c b/arch/arm/mach-s5pv210/dev-audio.c index 961477ac5baa..ddd2704b3467 100644 --- a/arch/arm/mach-s5pv210/dev-audio.c +++ b/arch/arm/mach-s5pv210/dev-audio.c @@ -19,22 +19,24 @@ #include #include +static const char *rclksrc[] = { + [0] = "busclk", + [1] = "i2sclk", +}; + static int s5pv210_cfg_i2s(struct platform_device *pdev) { /* configure GPIO for i2s port */ switch (pdev->id) { + case 0: + s3c_gpio_cfgpin_range(S5PV210_GPI(0), 7, S3C_GPIO_SFN(2)); + break; case 1: s3c_gpio_cfgpin_range(S5PV210_GPC0(0), 5, S3C_GPIO_SFN(2)); break; - case 2: s3c_gpio_cfgpin_range(S5PV210_GPC1(0), 5, S3C_GPIO_SFN(4)); break; - - case -1: - s3c_gpio_cfgpin_range(S5PV210_GPI(0), 7, S3C_GPIO_SFN(2)); - break; - default: printk(KERN_ERR "Invalid Device %d\n", pdev->id); return -EINVAL; @@ -43,8 +45,15 @@ static int s5pv210_cfg_i2s(struct platform_device *pdev) return 0; } -static struct s3c_audio_pdata s3c_i2s_pdata = { +static struct s3c_audio_pdata i2sv5_pdata = { .cfg_gpio = s5pv210_cfg_i2s, + .type = { + .i2s = { + .quirks = QUIRK_PRI_6CHAN | QUIRK_SEC_DAI + | QUIRK_NEED_RSTCLR, + .src_clk = rclksrc, + }, + }, }; static struct resource s5pv210_iis0_resource[] = { @@ -63,15 +72,34 @@ static struct resource s5pv210_iis0_resource[] = { .end = DMACH_I2S0_RX, .flags = IORESOURCE_DMA, }, + [3] = { + .start = DMACH_I2S0S_TX, + .end = DMACH_I2S0S_TX, + .flags = IORESOURCE_DMA, + }, }; struct platform_device s5pv210_device_iis0 = { - .name = "samsung-i2s-v4", - .id = -1, + .name = "samsung-i2s", + .id = 0, .num_resources = ARRAY_SIZE(s5pv210_iis0_resource), .resource = s5pv210_iis0_resource, .dev = { - .platform_data = &s3c_i2s_pdata, + .platform_data = &i2sv5_pdata, + }, +}; + +static const char *rclksrc_v3[] = { + [0] = "iis", + [1] = "audio-bus", +}; + +static struct s3c_audio_pdata i2sv3_pdata = { + .cfg_gpio = s5pv210_cfg_i2s, + .type = { + .i2s = { + .src_clk = rclksrc_v3, + }, }, }; @@ -99,7 +127,7 @@ struct platform_device s5pv210_device_iis1 = { .num_resources = ARRAY_SIZE(s5pv210_iis1_resource), .resource = s5pv210_iis1_resource, .dev = { - .platform_data = &s3c_i2s_pdata, + .platform_data = &i2sv3_pdata, }, }; @@ -127,7 +155,7 @@ struct platform_device s5pv210_device_iis2 = { .num_resources = ARRAY_SIZE(s5pv210_iis2_resource), .resource = s5pv210_iis2_resource, .dev = { - .platform_data = &s3c_i2s_pdata, + .platform_data = &i2sv3_pdata, }, }; -- cgit v1.2.3 From 460ed699f4c943e1ec4a8458869eb532fe31fd16 Mon Sep 17 00:00:00 2001 From: Jassi Brar Date: Fri, 19 Nov 2010 08:49:44 +0900 Subject: ARM: S5PV310: Add audio platform devices Define platform devices for all audio devices found on S5PV310 Signed-off-by: Jassi Brar Acked-by: Mark Brown Acked-by: Liam Girdwood Signed-off-by: Kukjin Kim --- arch/arm/mach-s5pv310/Makefile | 1 + arch/arm/mach-s5pv310/dev-audio.c | 364 ++++++++++++++++++++++++++++++ arch/arm/mach-s5pv310/include/mach/map.h | 16 ++ arch/arm/plat-samsung/include/plat/devs.h | 9 + 4 files changed, 390 insertions(+) create mode 100644 arch/arm/mach-s5pv310/dev-audio.c diff --git a/arch/arm/mach-s5pv310/Makefile b/arch/arm/mach-s5pv310/Makefile index d265adb178e6..61e3cb654269 100644 --- a/arch/arm/mach-s5pv310/Makefile +++ b/arch/arm/mach-s5pv310/Makefile @@ -27,6 +27,7 @@ obj-$(CONFIG_MACH_UNIVERSAL_C210) += mach-universal_c210.o # device support +obj-y += dev-audio.o obj-$(CONFIG_S5PV310_SETUP_I2C1) += setup-i2c1.o obj-$(CONFIG_S5PV310_SETUP_I2C2) += setup-i2c2.o obj-$(CONFIG_S5PV310_SETUP_I2C3) += setup-i2c3.o diff --git a/arch/arm/mach-s5pv310/dev-audio.c b/arch/arm/mach-s5pv310/dev-audio.c new file mode 100644 index 000000000000..a1964242f0fa --- /dev/null +++ b/arch/arm/mach-s5pv310/dev-audio.c @@ -0,0 +1,364 @@ +/* linux/arch/arm/mach-s5pv310/dev-audio.c + * + * Copyright (c) 2010 Samsung Electronics Co. Ltd + * Jaswinder Singh + * + * 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 +#include + +#include +#include +#include + +static const char *rclksrc[] = { + [0] = "busclk", + [1] = "i2sclk", +}; + +static int s5pv310_cfg_i2s(struct platform_device *pdev) +{ + /* configure GPIO for i2s port */ + switch (pdev->id) { + case 0: + s3c_gpio_cfgpin_range(S5PV310_GPZ(0), 7, S3C_GPIO_SFN(2)); + break; + case 1: + s3c_gpio_cfgpin_range(S5PV310_GPC0(0), 5, S3C_GPIO_SFN(2)); + break; + case 2: + s3c_gpio_cfgpin_range(S5PV310_GPC1(0), 5, S3C_GPIO_SFN(4)); + break; + default: + printk(KERN_ERR "Invalid Device %d\n", pdev->id); + return -EINVAL; + } + + return 0; +} + +static struct s3c_audio_pdata i2sv5_pdata = { + .cfg_gpio = s5pv310_cfg_i2s, + .type = { + .i2s = { + .quirks = QUIRK_PRI_6CHAN | QUIRK_SEC_DAI + | QUIRK_NEED_RSTCLR, + .src_clk = rclksrc, + }, + }, +}; + +static struct resource s5pv310_i2s0_resource[] = { + [0] = { + .start = S5PV310_PA_I2S0, + .end = S5PV310_PA_I2S0 + 0x100 - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = DMACH_I2S0_TX, + .end = DMACH_I2S0_TX, + .flags = IORESOURCE_DMA, + }, + [2] = { + .start = DMACH_I2S0_RX, + .end = DMACH_I2S0_RX, + .flags = IORESOURCE_DMA, + }, + [3] = { + .start = DMACH_I2S0S_TX, + .end = DMACH_I2S0S_TX, + .flags = IORESOURCE_DMA, + }, +}; + +struct platform_device s5pv310_device_i2s0 = { + .name = "samsung-i2s", + .id = 0, + .num_resources = ARRAY_SIZE(s5pv310_i2s0_resource), + .resource = s5pv310_i2s0_resource, + .dev = { + .platform_data = &i2sv5_pdata, + }, +}; + +static const char *rclksrc_v3[] = { + [0] = "sclk_i2s", + [1] = "no_such_clock", +}; + +static struct s3c_audio_pdata i2sv3_pdata = { + .cfg_gpio = s5pv310_cfg_i2s, + .type = { + .i2s = { + .quirks = QUIRK_NO_MUXPSR, + .src_clk = rclksrc_v3, + }, + }, +}; + +static struct resource s5pv310_i2s1_resource[] = { + [0] = { + .start = S5PV310_PA_I2S1, + .end = S5PV310_PA_I2S1 + 0x100 - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = DMACH_I2S1_TX, + .end = DMACH_I2S1_TX, + .flags = IORESOURCE_DMA, + }, + [2] = { + .start = DMACH_I2S1_RX, + .end = DMACH_I2S1_RX, + .flags = IORESOURCE_DMA, + }, +}; + +struct platform_device s5pv310_device_i2s1 = { + .name = "samsung-i2s", + .id = 1, + .num_resources = ARRAY_SIZE(s5pv310_i2s1_resource), + .resource = s5pv310_i2s1_resource, + .dev = { + .platform_data = &i2sv3_pdata, + }, +}; + +static struct resource s5pv310_i2s2_resource[] = { + [0] = { + .start = S5PV310_PA_I2S2, + .end = S5PV310_PA_I2S2 + 0x100 - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = DMACH_I2S2_TX, + .end = DMACH_I2S2_TX, + .flags = IORESOURCE_DMA, + }, + [2] = { + .start = DMACH_I2S2_RX, + .end = DMACH_I2S2_RX, + .flags = IORESOURCE_DMA, + }, +}; + +struct platform_device s5pv310_device_i2s2 = { + .name = "samsung-i2s", + .id = 2, + .num_resources = ARRAY_SIZE(s5pv310_i2s2_resource), + .resource = s5pv310_i2s2_resource, + .dev = { + .platform_data = &i2sv3_pdata, + }, +}; + +/* PCM Controller platform_devices */ + +static int s5pv310_pcm_cfg_gpio(struct platform_device *pdev) +{ + switch (pdev->id) { + case 0: + s3c_gpio_cfgpin_range(S5PV310_GPZ(0), 5, S3C_GPIO_SFN(3)); + break; + case 1: + s3c_gpio_cfgpin_range(S5PV310_GPC0(0), 5, S3C_GPIO_SFN(3)); + break; + case 2: + s3c_gpio_cfgpin_range(S5PV310_GPC1(0), 5, S3C_GPIO_SFN(3)); + break; + default: + printk(KERN_DEBUG "Invalid PCM Controller number!"); + return -EINVAL; + } + + return 0; +} + +static struct s3c_audio_pdata s3c_pcm_pdata = { + .cfg_gpio = s5pv310_pcm_cfg_gpio, +}; + +static struct resource s5pv310_pcm0_resource[] = { + [0] = { + .start = S5PV310_PA_PCM0, + .end = S5PV310_PA_PCM0 + 0x100 - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = DMACH_PCM0_TX, + .end = DMACH_PCM0_TX, + .flags = IORESOURCE_DMA, + }, + [2] = { + .start = DMACH_PCM0_RX, + .end = DMACH_PCM0_RX, + .flags = IORESOURCE_DMA, + }, +}; + +struct platform_device s5pv310_device_pcm0 = { + .name = "samsung-pcm", + .id = 0, + .num_resources = ARRAY_SIZE(s5pv310_pcm0_resource), + .resource = s5pv310_pcm0_resource, + .dev = { + .platform_data = &s3c_pcm_pdata, + }, +}; + +static struct resource s5pv310_pcm1_resource[] = { + [0] = { + .start = S5PV310_PA_PCM1, + .end = S5PV310_PA_PCM1 + 0x100 - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = DMACH_PCM1_TX, + .end = DMACH_PCM1_TX, + .flags = IORESOURCE_DMA, + }, + [2] = { + .start = DMACH_PCM1_RX, + .end = DMACH_PCM1_RX, + .flags = IORESOURCE_DMA, + }, +}; + +struct platform_device s5pv310_device_pcm1 = { + .name = "samsung-pcm", + .id = 1, + .num_resources = ARRAY_SIZE(s5pv310_pcm1_resource), + .resource = s5pv310_pcm1_resource, + .dev = { + .platform_data = &s3c_pcm_pdata, + }, +}; + +static struct resource s5pv310_pcm2_resource[] = { + [0] = { + .start = S5PV310_PA_PCM2, + .end = S5PV310_PA_PCM2 + 0x100 - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = DMACH_PCM2_TX, + .end = DMACH_PCM2_TX, + .flags = IORESOURCE_DMA, + }, + [2] = { + .start = DMACH_PCM2_RX, + .end = DMACH_PCM2_RX, + .flags = IORESOURCE_DMA, + }, +}; + +struct platform_device s5pv310_device_pcm2 = { + .name = "samsung-pcm", + .id = 2, + .num_resources = ARRAY_SIZE(s5pv310_pcm2_resource), + .resource = s5pv310_pcm2_resource, + .dev = { + .platform_data = &s3c_pcm_pdata, + }, +}; + +/* AC97 Controller platform devices */ + +static int s5pv310_ac97_cfg_gpio(struct platform_device *pdev) +{ + return s3c_gpio_cfgpin_range(S5PV310_GPC0(0), 5, S3C_GPIO_SFN(4)); +} + +static struct resource s5pv310_ac97_resource[] = { + [0] = { + .start = S5PV310_PA_AC97, + .end = S5PV310_PA_AC97 + 0x100 - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = DMACH_AC97_PCMOUT, + .end = DMACH_AC97_PCMOUT, + .flags = IORESOURCE_DMA, + }, + [2] = { + .start = DMACH_AC97_PCMIN, + .end = DMACH_AC97_PCMIN, + .flags = IORESOURCE_DMA, + }, + [3] = { + .start = DMACH_AC97_MICIN, + .end = DMACH_AC97_MICIN, + .flags = IORESOURCE_DMA, + }, + [4] = { + .start = IRQ_AC97, + .end = IRQ_AC97, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct s3c_audio_pdata s3c_ac97_pdata = { + .cfg_gpio = s5pv310_ac97_cfg_gpio, +}; + +static u64 s5pv310_ac97_dmamask = DMA_BIT_MASK(32); + +struct platform_device s5pv310_device_ac97 = { + .name = "samsung-ac97", + .id = -1, + .num_resources = ARRAY_SIZE(s5pv310_ac97_resource), + .resource = s5pv310_ac97_resource, + .dev = { + .platform_data = &s3c_ac97_pdata, + .dma_mask = &s5pv310_ac97_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, +}; + +/* S/PDIF Controller platform_device */ + +static int s5pv310_spdif_cfg_gpio(struct platform_device *pdev) +{ + s3c_gpio_cfgpin_range(S5PV310_GPC1(0), 2, S3C_GPIO_SFN(3)); + + return 0; +} + +static struct resource s5pv310_spdif_resource[] = { + [0] = { + .start = S5PV310_PA_SPDIF, + .end = S5PV310_PA_SPDIF + 0x100 - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = DMACH_SPDIF, + .end = DMACH_SPDIF, + .flags = IORESOURCE_DMA, + }, +}; + +static struct s3c_audio_pdata samsung_spdif_pdata = { + .cfg_gpio = s5pv310_spdif_cfg_gpio, +}; + +static u64 s5pv310_spdif_dmamask = DMA_BIT_MASK(32); + +struct platform_device s5pv310_device_spdif = { + .name = "samsung-spdif", + .id = -1, + .num_resources = ARRAY_SIZE(s5pv310_spdif_resource), + .resource = s5pv310_spdif_resource, + .dev = { + .platform_data = &samsung_spdif_pdata, + .dma_mask = &s5pv310_spdif_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + }, +}; diff --git a/arch/arm/mach-s5pv310/include/mach/map.h b/arch/arm/mach-s5pv310/include/mach/map.h index 169fac2899f0..53994467605d 100644 --- a/arch/arm/mach-s5pv310/include/mach/map.h +++ b/arch/arm/mach-s5pv310/include/mach/map.h @@ -65,6 +65,22 @@ #define S5PV310_PA_SROMC (0x12570000) +/* S/PDIF */ +#define S5PV310_PA_SPDIF 0xE1100000 + +/* I2S */ +#define S5PV310_PA_I2S0 0x03830000 +#define S5PV310_PA_I2S1 0xE3100000 +#define S5PV310_PA_I2S2 0xE2A00000 + +/* PCM */ +#define S5PV310_PA_PCM0 0x03840000 +#define S5PV310_PA_PCM1 0x13980000 +#define S5PV310_PA_PCM2 0x13990000 + +/* AC97 */ +#define S5PV310_PA_AC97 0x139A0000 + #define S5PV310_PA_UART (0x13800000) #define S5P_PA_UART(x) (S5PV310_PA_UART + ((x) * S3C_UART_OFFSET)) diff --git a/arch/arm/plat-samsung/include/plat/devs.h b/arch/arm/plat-samsung/include/plat/devs.h index 2d82a6cb1444..dec0ded6a5ee 100644 --- a/arch/arm/plat-samsung/include/plat/devs.h +++ b/arch/arm/plat-samsung/include/plat/devs.h @@ -96,6 +96,15 @@ extern struct platform_device s5pv210_device_iis1; extern struct platform_device s5pv210_device_iis2; extern struct platform_device s5pv210_device_spdif; +extern struct platform_device s5pv310_device_ac97; +extern struct platform_device s5pv310_device_pcm0; +extern struct platform_device s5pv310_device_pcm1; +extern struct platform_device s5pv310_device_pcm2; +extern struct platform_device s5pv310_device_i2s0; +extern struct platform_device s5pv310_device_i2s1; +extern struct platform_device s5pv310_device_i2s2; +extern struct platform_device s5pv310_device_spdif; + extern struct platform_device s5p6442_device_pcm0; extern struct platform_device s5p6442_device_pcm1; extern struct platform_device s5p6442_device_iis0; -- cgit v1.2.3 From c2f9bff5ace07fbea03a53c6c3253f6c3a81e9f9 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Tue, 19 Oct 2010 21:04:42 +0800 Subject: net - Add AF_ALG macros This patch adds the socket family/level macros for the yet-to-be-born AF_ALG family. The AF_ALG family provides the user-space interface for the kernel crypto API. Signed-off-by: Herbert Xu Acked-by: David S. Miller --- include/linux/socket.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/include/linux/socket.h b/include/linux/socket.h index 5146b50202ce..ebc081b18da6 100644 --- a/include/linux/socket.h +++ b/include/linux/socket.h @@ -193,7 +193,8 @@ struct ucred { #define AF_PHONET 35 /* Phonet sockets */ #define AF_IEEE802154 36 /* IEEE802154 sockets */ #define AF_CAIF 37 /* CAIF sockets */ -#define AF_MAX 38 /* For now.. */ +#define AF_ALG 38 /* Algorithm sockets */ +#define AF_MAX 39 /* For now.. */ /* Protocol families, same as address families. */ #define PF_UNSPEC AF_UNSPEC @@ -234,6 +235,7 @@ struct ucred { #define PF_PHONET AF_PHONET #define PF_IEEE802154 AF_IEEE802154 #define PF_CAIF AF_CAIF +#define PF_ALG AF_ALG #define PF_MAX AF_MAX /* Maximum queue length specifiable by listen. */ @@ -307,6 +309,7 @@ struct ucred { #define SOL_RDS 276 #define SOL_IUCV 277 #define SOL_CAIF 278 +#define SOL_ALG 279 /* IPX options */ #define IPX_TYPE 1 -- cgit v1.2.3 From 8f2535d9d9c8d87bfbbddab3a5b27abe48213ad2 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 16 Nov 2010 10:58:37 +0000 Subject: drm/i915/crt: Introduce struct intel_crt We will use this structure in future patches to store CRT specific information on the encoder. Split out and tweaked from a patch by Keith Packard. Signed-off-by: Keith Packard Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/intel_crt.c | 64 +++++++++++++++++++++++----------------- 1 file changed, 37 insertions(+), 27 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c index c55c77043357..e38bc6769180 100644 --- a/drivers/gpu/drm/i915/intel_crt.c +++ b/drivers/gpu/drm/i915/intel_crt.c @@ -34,6 +34,16 @@ #include "i915_drm.h" #include "i915_drv.h" +struct intel_crt { + struct intel_encoder base; +}; + +static struct intel_crt *intel_attached_crt(struct drm_connector *connector) +{ + return container_of(intel_attached_encoder(connector), + struct intel_crt, base); +} + static void intel_crt_dpms(struct drm_encoder *encoder, int mode) { struct drm_device *dev = encoder->dev; @@ -277,13 +287,12 @@ static bool intel_crt_ddc_probe(struct drm_i915_private *dev_priv, int ddc_bus) return i2c_transfer(&dev_priv->gmbus[ddc_bus].adapter, msgs, 1) == 1; } -static bool intel_crt_detect_ddc(struct drm_encoder *encoder) +static bool intel_crt_detect_ddc(struct intel_crt *crt) { - struct intel_encoder *intel_encoder = to_intel_encoder(encoder); - struct drm_i915_private *dev_priv = encoder->dev->dev_private; + struct drm_i915_private *dev_priv = crt->base.base.dev->dev_private; /* CRT should always be at 0, but check anyway */ - if (intel_encoder->type != INTEL_OUTPUT_ANALOG) + if (crt->base.type != INTEL_OUTPUT_ANALOG) return false; if (intel_crt_ddc_probe(dev_priv, dev_priv->crt_ddc_pin)) { @@ -291,7 +300,7 @@ static bool intel_crt_detect_ddc(struct drm_encoder *encoder) return true; } - if (intel_ddc_probe(intel_encoder, dev_priv->crt_ddc_pin)) { + if (intel_ddc_probe(&crt->base, dev_priv->crt_ddc_pin)) { DRM_DEBUG_KMS("CRT detected via DDC:0x50 [EDID]\n"); return true; } @@ -300,9 +309,9 @@ static bool intel_crt_detect_ddc(struct drm_encoder *encoder) } static enum drm_connector_status -intel_crt_load_detect(struct drm_crtc *crtc, struct intel_encoder *intel_encoder) +intel_crt_load_detect(struct drm_crtc *crtc, struct intel_crt *crt) { - struct drm_encoder *encoder = &intel_encoder->base; + struct drm_encoder *encoder = &crt->base.base; struct drm_device *dev = encoder->dev; struct drm_i915_private *dev_priv = dev->dev_private; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); @@ -434,7 +443,7 @@ static enum drm_connector_status intel_crt_detect(struct drm_connector *connector, bool force) { struct drm_device *dev = connector->dev; - struct intel_encoder *encoder = intel_attached_encoder(connector); + struct intel_crt *crt = intel_attached_crt(connector); struct drm_crtc *crtc; int dpms_mode; enum drm_connector_status status; @@ -447,24 +456,25 @@ intel_crt_detect(struct drm_connector *connector, bool force) return connector_status_disconnected; } - if (intel_crt_detect_ddc(&encoder->base)) + if (intel_crt_detect_ddc(crt)) return connector_status_connected; if (!force) return connector->status; /* for pre-945g platforms use load detect */ - if (encoder->base.crtc && encoder->base.crtc->enabled) { - status = intel_crt_load_detect(encoder->base.crtc, encoder); + crtc = crt->base.base.crtc; + if (crtc && crtc->enabled) { + status = intel_crt_load_detect(crtc, crt); } else { - crtc = intel_get_load_detect_pipe(encoder, connector, + crtc = intel_get_load_detect_pipe(&crt->base, connector, NULL, &dpms_mode); if (crtc) { - if (intel_crt_detect_ddc(&encoder->base)) + if (intel_crt_detect_ddc(crt)) status = connector_status_connected; else - status = intel_crt_load_detect(crtc, encoder); - intel_release_load_detect_pipe(encoder, + status = intel_crt_load_detect(crtc, crt); + intel_release_load_detect_pipe(&crt->base, connector, dpms_mode); } else status = connector_status_unknown; @@ -536,17 +546,17 @@ static const struct drm_encoder_funcs intel_crt_enc_funcs = { void intel_crt_init(struct drm_device *dev) { struct drm_connector *connector; - struct intel_encoder *intel_encoder; + struct intel_crt *crt; struct intel_connector *intel_connector; struct drm_i915_private *dev_priv = dev->dev_private; - intel_encoder = kzalloc(sizeof(struct intel_encoder), GFP_KERNEL); - if (!intel_encoder) + crt = kzalloc(sizeof(struct intel_crt), GFP_KERNEL); + if (!crt) return; intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL); if (!intel_connector) { - kfree(intel_encoder); + kfree(crt); return; } @@ -554,20 +564,20 @@ void intel_crt_init(struct drm_device *dev) drm_connector_init(dev, &intel_connector->base, &intel_crt_connector_funcs, DRM_MODE_CONNECTOR_VGA); - drm_encoder_init(dev, &intel_encoder->base, &intel_crt_enc_funcs, + drm_encoder_init(dev, &crt->base.base, &intel_crt_enc_funcs, DRM_MODE_ENCODER_DAC); - intel_connector_attach_encoder(intel_connector, intel_encoder); + intel_connector_attach_encoder(intel_connector, &crt->base); - intel_encoder->type = INTEL_OUTPUT_ANALOG; - intel_encoder->clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT) | - (1 << INTEL_ANALOG_CLONE_BIT) | - (1 << INTEL_SDVO_LVDS_CLONE_BIT); - intel_encoder->crtc_mask = (1 << 0) | (1 << 1); + crt->base.type = INTEL_OUTPUT_ANALOG; + crt->base.clone_mask = (1 << INTEL_SDVO_NON_TV_CLONE_BIT | + 1 << INTEL_ANALOG_CLONE_BIT | + 1 << INTEL_SDVO_LVDS_CLONE_BIT); + crt->base.crtc_mask = (1 << 0) | (1 << 1); connector->interlace_allowed = 1; connector->doublescan_allowed = 0; - drm_encoder_helper_add(&intel_encoder->base, &intel_crt_helper_funcs); + drm_encoder_helper_add(&crt->base.base, &intel_crt_helper_funcs); drm_connector_helper_add(connector, &intel_crt_connector_helper_funcs); drm_sysfs_connector_add(connector); -- cgit v1.2.3 From 8b5abbe0683f285e1311c4cc29c79da07d18d0af Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Tue, 16 Nov 2010 16:03:53 +0800 Subject: drm/i915: Take advantage of auto-polling CRT hotplug detection on PCH hardware Both IBX and CPT have an automatic hotplug detection mode which appears to work reliably enough that we can dispense with the manual force hotplug trigger stuff. This means that hotplug detection is as simple as reading the current hotplug register values. The first time the hotplug detection is activated, the code synchronously waits for a hotplug sequence in case the hardware hasn't bothered to do a detection cycle since being initialized. Signed-off-by: Keith Packard Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/intel_crt.c | 95 ++++++++++++++++++++++++---------------- 1 file changed, 57 insertions(+), 38 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c index e38bc6769180..8df574316063 100644 --- a/drivers/gpu/drm/i915/intel_crt.c +++ b/drivers/gpu/drm/i915/intel_crt.c @@ -34,8 +34,17 @@ #include "i915_drm.h" #include "i915_drv.h" +/* Here's the desired hotplug mode */ +#define ADPA_HOTPLUG_BITS (ADPA_CRT_HOTPLUG_PERIOD_128 | \ + ADPA_CRT_HOTPLUG_WARMUP_10MS | \ + ADPA_CRT_HOTPLUG_SAMPLE_4S | \ + ADPA_CRT_HOTPLUG_VOLTAGE_50 | \ + ADPA_CRT_HOTPLUG_VOLREF_325MV | \ + ADPA_CRT_HOTPLUG_ENABLE) + struct intel_crt { struct intel_encoder base; + bool force_hotplug_required; }; static struct intel_crt *intel_attached_crt(struct drm_connector *connector) @@ -139,7 +148,7 @@ static void intel_crt_mode_set(struct drm_encoder *encoder, dpll_md & ~DPLL_MD_UDI_MULTIPLIER_MASK); } - adpa = 0; + adpa = ADPA_HOTPLUG_BITS; if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC) adpa |= ADPA_HSYNC_ACTIVE_HIGH; if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC) @@ -167,53 +176,44 @@ static void intel_crt_mode_set(struct drm_encoder *encoder, static bool intel_ironlake_crt_detect_hotplug(struct drm_connector *connector) { struct drm_device *dev = connector->dev; + struct intel_crt *crt = intel_attached_crt(connector); struct drm_i915_private *dev_priv = dev->dev_private; - u32 adpa, temp; + u32 adpa; bool ret; - bool turn_off_dac = false; - temp = adpa = I915_READ(PCH_ADPA); + /* The first time through, trigger an explicit detection cycle */ + if (crt->force_hotplug_required) { + bool turn_off_dac = HAS_PCH_SPLIT(dev); + u32 save_adpa; - if (HAS_PCH_SPLIT(dev)) - turn_off_dac = true; - - adpa &= ~ADPA_CRT_HOTPLUG_MASK; - if (turn_off_dac) - adpa &= ~ADPA_DAC_ENABLE; - - /* disable HPD first */ - I915_WRITE(PCH_ADPA, adpa); - (void)I915_READ(PCH_ADPA); - - adpa |= (ADPA_CRT_HOTPLUG_PERIOD_128 | - ADPA_CRT_HOTPLUG_WARMUP_10MS | - ADPA_CRT_HOTPLUG_SAMPLE_4S | - ADPA_CRT_HOTPLUG_VOLTAGE_50 | /* default */ - ADPA_CRT_HOTPLUG_VOLREF_325MV | - ADPA_CRT_HOTPLUG_ENABLE | - ADPA_CRT_HOTPLUG_FORCE_TRIGGER); - - DRM_DEBUG_KMS("pch crt adpa 0x%x", adpa); - I915_WRITE(PCH_ADPA, adpa); - - if (wait_for((I915_READ(PCH_ADPA) & ADPA_CRT_HOTPLUG_FORCE_TRIGGER) == 0, - 1000)) - DRM_DEBUG_KMS("timed out waiting for FORCE_TRIGGER"); - - if (turn_off_dac) { - /* Make sure hotplug is enabled */ - I915_WRITE(PCH_ADPA, temp | ADPA_CRT_HOTPLUG_ENABLE); - (void)I915_READ(PCH_ADPA); + crt->force_hotplug_required = 0; + + save_adpa = adpa = I915_READ(PCH_ADPA); + DRM_DEBUG_KMS("trigger hotplug detect cycle: adpa=0x%x\n", adpa); + + adpa |= ADPA_CRT_HOTPLUG_FORCE_TRIGGER; + if (turn_off_dac) + adpa &= ~ADPA_DAC_ENABLE; + + I915_WRITE(PCH_ADPA, adpa); + + if (wait_for((I915_READ(PCH_ADPA) & ADPA_CRT_HOTPLUG_FORCE_TRIGGER) == 0, + 1000)) + DRM_DEBUG_KMS("timed out waiting for FORCE_TRIGGER"); + + if (turn_off_dac) { + I915_WRITE(PCH_ADPA, save_adpa); + POSTING_READ(PCH_ADPA); + } } /* Check the status to see if both blue and green are on now */ adpa = I915_READ(PCH_ADPA); - adpa &= ADPA_CRT_HOTPLUG_MONITOR_MASK; - if ((adpa == ADPA_CRT_HOTPLUG_MONITOR_COLOR) || - (adpa == ADPA_CRT_HOTPLUG_MONITOR_MONO)) + if ((adpa & ADPA_CRT_HOTPLUG_MONITOR_MASK) != 0) ret = true; else ret = false; + DRM_DEBUG_KMS("ironlake hotplug adpa=0x%x, result %d\n", adpa, ret); return ret; } @@ -452,8 +452,10 @@ intel_crt_detect(struct drm_connector *connector, bool force) if (intel_crt_detect_hotplug(connector)) { DRM_DEBUG_KMS("CRT detected via hotplug\n"); return connector_status_connected; - } else + } else { + DRM_DEBUG_KMS("CRT not detected via hotplug\n"); return connector_status_disconnected; + } } if (intel_crt_detect_ddc(crt)) @@ -587,5 +589,22 @@ void intel_crt_init(struct drm_device *dev) else connector->polled = DRM_CONNECTOR_POLL_CONNECT; + /* + * Configure the automatic hotplug detection stuff + */ + crt->force_hotplug_required = 0; + if (HAS_PCH_SPLIT(dev)) { + u32 adpa; + + adpa = I915_READ(PCH_ADPA); + adpa &= ~ADPA_CRT_HOTPLUG_MASK; + adpa |= ADPA_HOTPLUG_BITS; + I915_WRITE(PCH_ADPA, adpa); + POSTING_READ(PCH_ADPA); + + DRM_DEBUG_KMS("pch crt adpa set to 0x%x\n", adpa); + crt->force_hotplug_required = 1; + } + dev_priv->hotplug_supported_mask |= CRT_HOTPLUG_INT_STATUS; } -- cgit v1.2.3 From 03c8efc1ffeb6b82a22c1af8dd908af349563314 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Tue, 19 Oct 2010 21:12:39 +0800 Subject: crypto: af_alg - User-space interface for Crypto API This patch creates the backbone of the user-space interface for the Crypto API, through a new socket family AF_ALG. Each session corresponds to one or more connections obtained from that socket. The number depends on the number of inputs/outputs of that particular type of operation. For most types there will be a s ingle connection/file descriptor that is used for both input and output. AEAD is one of the few that require two inputs. Each algorithm type will provide its own implementation that plugs into af_alg. They're keyed using a string such as "skcipher" or "hash". IOW this patch only contains the boring bits that is required to hold everything together. Thakns to Miloslav Trmac for reviewing this and contributing fixes and improvements. Signed-off-by: Herbert Xu Acked-by: David S. Miller Tested-by: Martin Willi --- crypto/Kconfig | 3 + crypto/Makefile | 1 + crypto/af_alg.c | 482 ++++++++++++++++++++++++++++++++++++++++++++++++ include/crypto/if_alg.h | 92 +++++++++ include/linux/if_alg.h | 40 ++++ 5 files changed, 618 insertions(+) create mode 100644 crypto/af_alg.c create mode 100644 include/crypto/if_alg.h create mode 100644 include/linux/if_alg.h diff --git a/crypto/Kconfig b/crypto/Kconfig index e4bac29a32e7..357e3caf4cbe 100644 --- a/crypto/Kconfig +++ b/crypto/Kconfig @@ -841,6 +841,9 @@ config CRYPTO_ANSI_CPRNG ANSI X9.31 A.2.4. Note that this option must be enabled if CRYPTO_FIPS is selected +config CRYPTO_USER_API + tristate + source "drivers/crypto/Kconfig" endif # if CRYPTO diff --git a/crypto/Makefile b/crypto/Makefile index 423b7de61f93..0b1319734bc0 100644 --- a/crypto/Makefile +++ b/crypto/Makefile @@ -85,6 +85,7 @@ obj-$(CONFIG_CRYPTO_RNG2) += krng.o obj-$(CONFIG_CRYPTO_ANSI_CPRNG) += ansi_cprng.o obj-$(CONFIG_CRYPTO_TEST) += tcrypt.o obj-$(CONFIG_CRYPTO_GHASH) += ghash-generic.o +obj-$(CONFIG_CRYPTO_USER_API) += af_alg.o # # generic algorithms and the async_tx api diff --git a/crypto/af_alg.c b/crypto/af_alg.c new file mode 100644 index 000000000000..cabed0e9c9d8 --- /dev/null +++ b/crypto/af_alg.c @@ -0,0 +1,482 @@ +/* + * af_alg: User-space algorithm interface + * + * This file provides the user-space API for algorithms. + * + * Copyright (c) 2010 Herbert Xu + * + * 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. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct alg_type_list { + const struct af_alg_type *type; + struct list_head list; +}; + +static atomic_t alg_memory_allocated; + +static struct proto alg_proto = { + .name = "ALG", + .owner = THIS_MODULE, + .memory_allocated = &alg_memory_allocated, + .obj_size = sizeof(struct alg_sock), +}; + +static LIST_HEAD(alg_types); +static DECLARE_RWSEM(alg_types_sem); + +static const struct af_alg_type *alg_get_type(const char *name) +{ + const struct af_alg_type *type = ERR_PTR(-ENOENT); + struct alg_type_list *node; + + down_read(&alg_types_sem); + list_for_each_entry(node, &alg_types, list) { + if (strcmp(node->type->name, name)) + continue; + + if (try_module_get(node->type->owner)) + type = node->type; + break; + } + up_read(&alg_types_sem); + + return type; +} + +int af_alg_register_type(const struct af_alg_type *type) +{ + struct alg_type_list *node; + int err = -EEXIST; + + down_write(&alg_types_sem); + list_for_each_entry(node, &alg_types, list) { + if (!strcmp(node->type->name, type->name)) + goto unlock; + } + + node = kmalloc(sizeof(*node), GFP_KERNEL); + err = -ENOMEM; + if (!node) + goto unlock; + + type->ops->owner = THIS_MODULE; + node->type = type; + list_add(&node->list, &alg_types); + err = 0; + +unlock: + up_write(&alg_types_sem); + + return err; +} +EXPORT_SYMBOL_GPL(af_alg_register_type); + +int af_alg_unregister_type(const struct af_alg_type *type) +{ + struct alg_type_list *node; + int err = -ENOENT; + + down_write(&alg_types_sem); + list_for_each_entry(node, &alg_types, list) { + if (strcmp(node->type->name, type->name)) + continue; + + list_del(&node->list); + kfree(node); + err = 0; + break; + } + up_write(&alg_types_sem); + + return err; +} +EXPORT_SYMBOL_GPL(af_alg_unregister_type); + +static void alg_do_release(const struct af_alg_type *type, void *private) +{ + if (!type) + return; + + type->release(private); + module_put(type->owner); +} + +int af_alg_release(struct socket *sock) +{ + if (sock->sk) + sock_put(sock->sk); + return 0; +} +EXPORT_SYMBOL_GPL(af_alg_release); + +static int alg_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) +{ + struct sock *sk = sock->sk; + struct alg_sock *ask = alg_sk(sk); + struct sockaddr_alg *sa = (void *)uaddr; + const struct af_alg_type *type; + void *private; + + if (sock->state == SS_CONNECTED) + return -EINVAL; + + if (addr_len != sizeof(*sa)) + return -EINVAL; + + sa->salg_type[sizeof(sa->salg_type) - 1] = 0; + sa->salg_name[sizeof(sa->salg_name) - 1] = 0; + + type = alg_get_type(sa->salg_type); + if (IS_ERR(type) && PTR_ERR(type) == -ENOENT) { + request_module("algif-%s", sa->salg_type); + type = alg_get_type(sa->salg_type); + } + + if (IS_ERR(type)) + return PTR_ERR(type); + + private = type->bind(sa->salg_name, sa->salg_feat, sa->salg_mask); + if (IS_ERR(private)) { + module_put(type->owner); + return PTR_ERR(private); + } + + lock_sock(sk); + + swap(ask->type, type); + swap(ask->private, private); + + release_sock(sk); + + alg_do_release(type, private); + + return 0; +} + +static int alg_setkey(struct sock *sk, char __user *ukey, + unsigned int keylen) +{ + struct alg_sock *ask = alg_sk(sk); + const struct af_alg_type *type = ask->type; + u8 *key; + int err; + + key = sock_kmalloc(sk, keylen, GFP_KERNEL); + if (!key) + return -ENOMEM; + + err = -EFAULT; + if (copy_from_user(key, ukey, keylen)) + goto out; + + err = type->setkey(ask->private, key, keylen); + +out: + sock_kfree_s(sk, key, keylen); + + return err; +} + +static int alg_setsockopt(struct socket *sock, int level, int optname, + char __user *optval, unsigned int optlen) +{ + struct sock *sk = sock->sk; + struct alg_sock *ask = alg_sk(sk); + const struct af_alg_type *type; + int err = -ENOPROTOOPT; + + lock_sock(sk); + type = ask->type; + + if (level != SOL_ALG || !type) + goto unlock; + + switch (optname) { + case ALG_SET_KEY: + if (sock->state == SS_CONNECTED) + goto unlock; + if (!type->setkey) + goto unlock; + + err = alg_setkey(sk, optval, optlen); + } + +unlock: + release_sock(sk); + + return err; +} + +int af_alg_accept(struct sock *sk, struct socket *newsock) +{ + struct alg_sock *ask = alg_sk(sk); + const struct af_alg_type *type; + struct sock *sk2; + int err; + + lock_sock(sk); + type = ask->type; + + err = -EINVAL; + if (!type) + goto unlock; + + sk2 = sk_alloc(sock_net(sk), PF_ALG, GFP_KERNEL, &alg_proto); + err = -ENOMEM; + if (!sk2) + goto unlock; + + sock_init_data(newsock, sk2); + + err = type->accept(ask->private, sk2); + if (err) { + sk_free(sk2); + goto unlock; + } + + sk2->sk_family = PF_ALG; + + sock_hold(sk); + alg_sk(sk2)->parent = sk; + alg_sk(sk2)->type = type; + + newsock->ops = type->ops; + newsock->state = SS_CONNECTED; + + err = 0; + +unlock: + release_sock(sk); + + return err; +} +EXPORT_SYMBOL_GPL(af_alg_accept); + +static int alg_accept(struct socket *sock, struct socket *newsock, int flags) +{ + return af_alg_accept(sock->sk, newsock); +} + +static const struct proto_ops alg_proto_ops = { + .family = PF_ALG, + .owner = THIS_MODULE, + + .connect = sock_no_connect, + .socketpair = sock_no_socketpair, + .getname = sock_no_getname, + .ioctl = sock_no_ioctl, + .listen = sock_no_listen, + .shutdown = sock_no_shutdown, + .getsockopt = sock_no_getsockopt, + .mmap = sock_no_mmap, + .sendpage = sock_no_sendpage, + .sendmsg = sock_no_sendmsg, + .recvmsg = sock_no_recvmsg, + .poll = sock_no_poll, + + .bind = alg_bind, + .release = af_alg_release, + .setsockopt = alg_setsockopt, + .accept = alg_accept, +}; + +static void alg_sock_destruct(struct sock *sk) +{ + struct alg_sock *ask = alg_sk(sk); + + alg_do_release(ask->type, ask->private); +} + +static int alg_create(struct net *net, struct socket *sock, int protocol, + int kern) +{ + struct sock *sk; + int err; + + if (sock->type != SOCK_SEQPACKET) + return -ESOCKTNOSUPPORT; + if (protocol != 0) + return -EPROTONOSUPPORT; + + err = -ENOMEM; + sk = sk_alloc(net, PF_ALG, GFP_KERNEL, &alg_proto); + if (!sk) + goto out; + + sock->ops = &alg_proto_ops; + sock_init_data(sock, sk); + + sk->sk_family = PF_ALG; + sk->sk_destruct = alg_sock_destruct; + + return 0; +out: + return err; +} + +static const struct net_proto_family alg_family = { + .family = PF_ALG, + .create = alg_create, + .owner = THIS_MODULE, +}; + +int af_alg_make_sg(struct af_alg_sgl *sgl, void __user *addr, int len, + int write) +{ + unsigned long from = (unsigned long)addr; + unsigned long npages; + unsigned off; + int err; + int i; + + err = -EFAULT; + if (!access_ok(write ? VERIFY_READ : VERIFY_WRITE, addr, len)) + goto out; + + off = from & ~PAGE_MASK; + npages = (off + len + PAGE_SIZE - 1) >> PAGE_SHIFT; + if (npages > ALG_MAX_PAGES) + npages = ALG_MAX_PAGES; + + err = get_user_pages_fast(from, npages, write, sgl->pages); + if (err < 0) + goto out; + + npages = err; + err = -EINVAL; + if (WARN_ON(npages == 0)) + goto out; + + err = 0; + + sg_init_table(sgl->sg, npages); + + for (i = 0; i < npages; i++) { + int plen = min_t(int, len, PAGE_SIZE - off); + + sg_set_page(sgl->sg + i, sgl->pages[i], plen, off); + + off = 0; + len -= plen; + err += plen; + } + +out: + return err; +} +EXPORT_SYMBOL_GPL(af_alg_make_sg); + +void af_alg_free_sg(struct af_alg_sgl *sgl) +{ + int i; + + i = 0; + do { + put_page(sgl->pages[i]); + } while (!sg_is_last(sgl->sg + (i++))); +} +EXPORT_SYMBOL_GPL(af_alg_free_sg); + +int af_alg_cmsg_send(struct msghdr *msg, struct af_alg_control *con) +{ + struct cmsghdr *cmsg; + + for (cmsg = CMSG_FIRSTHDR(msg); cmsg; cmsg = CMSG_NXTHDR(msg, cmsg)) { + if (!CMSG_OK(msg, cmsg)) + return -EINVAL; + if (cmsg->cmsg_level != SOL_ALG) + continue; + + switch(cmsg->cmsg_type) { + case ALG_SET_IV: + if (cmsg->cmsg_len < CMSG_LEN(sizeof(*con->iv))) + return -EINVAL; + con->iv = (void *)CMSG_DATA(cmsg); + if (cmsg->cmsg_len < CMSG_LEN(con->iv->ivlen + + sizeof(*con->iv))) + return -EINVAL; + break; + + case ALG_SET_OP: + if (cmsg->cmsg_len < CMSG_LEN(sizeof(u32))) + return -EINVAL; + con->op = *(u32 *)CMSG_DATA(cmsg); + break; + + default: + return -EINVAL; + } + } + + return 0; +} +EXPORT_SYMBOL_GPL(af_alg_cmsg_send); + +int af_alg_wait_for_completion(int err, struct af_alg_completion *completion) +{ + switch (err) { + case -EINPROGRESS: + case -EBUSY: + wait_for_completion(&completion->completion); + INIT_COMPLETION(completion->completion); + err = completion->err; + break; + }; + + return err; +} +EXPORT_SYMBOL_GPL(af_alg_wait_for_completion); + +void af_alg_complete(struct crypto_async_request *req, int err) +{ + struct af_alg_completion *completion = req->data; + + completion->err = err; + complete(&completion->completion); +} +EXPORT_SYMBOL_GPL(af_alg_complete); + +static int __init af_alg_init(void) +{ + int err = proto_register(&alg_proto, 0); + + if (err) + goto out; + + err = sock_register(&alg_family); + if (err != 0) + goto out_unregister_proto; + +out: + return err; + +out_unregister_proto: + proto_unregister(&alg_proto); + goto out; +} + +static void __exit af_alg_exit(void) +{ + sock_unregister(PF_ALG); + proto_unregister(&alg_proto); +} + +module_init(af_alg_init); +module_exit(af_alg_exit); +MODULE_LICENSE("GPL"); +MODULE_ALIAS_NETPROTO(AF_ALG); diff --git a/include/crypto/if_alg.h b/include/crypto/if_alg.h new file mode 100644 index 000000000000..c5813c87de06 --- /dev/null +++ b/include/crypto/if_alg.h @@ -0,0 +1,92 @@ +/* + * if_alg: User-space algorithm interface + * + * Copyright (c) 2010 Herbert Xu + * + * 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 _CRYPTO_IF_ALG_H +#define _CRYPTO_IF_ALG_H + +#include +#include +#include +#include +#include + +#define ALG_MAX_PAGES 16 + +struct crypto_async_request; + +struct alg_sock { + /* struct sock must be the first member of struct alg_sock */ + struct sock sk; + + struct sock *parent; + + const struct af_alg_type *type; + void *private; +}; + +struct af_alg_completion { + struct completion completion; + int err; +}; + +struct af_alg_control { + struct af_alg_iv *iv; + int op; +}; + +struct af_alg_type { + void *(*bind)(const char *name, u32 type, u32 mask); + void (*release)(void *private); + int (*setkey)(void *private, const u8 *key, unsigned int keylen); + int (*accept)(void *private, struct sock *sk); + + struct proto_ops *ops; + struct module *owner; + char name[14]; +}; + +struct af_alg_sgl { + struct scatterlist sg[ALG_MAX_PAGES]; + struct page *pages[ALG_MAX_PAGES]; +}; + +int af_alg_register_type(const struct af_alg_type *type); +int af_alg_unregister_type(const struct af_alg_type *type); + +int af_alg_release(struct socket *sock); +int af_alg_accept(struct sock *sk, struct socket *newsock); + +int af_alg_make_sg(struct af_alg_sgl *sgl, void __user *addr, int len, + int write); +void af_alg_free_sg(struct af_alg_sgl *sgl); + +int af_alg_cmsg_send(struct msghdr *msg, struct af_alg_control *con); + +int af_alg_wait_for_completion(int err, struct af_alg_completion *completion); +void af_alg_complete(struct crypto_async_request *req, int err); + +static inline struct alg_sock *alg_sk(struct sock *sk) +{ + return (struct alg_sock *)sk; +} + +static inline void af_alg_release_parent(struct sock *sk) +{ + sock_put(alg_sk(sk)->parent); +} + +static inline void af_alg_init_completion(struct af_alg_completion *completion) +{ + init_completion(&completion->completion); +} + +#endif /* _CRYPTO_IF_ALG_H */ diff --git a/include/linux/if_alg.h b/include/linux/if_alg.h new file mode 100644 index 000000000000..0f9acce5b1ff --- /dev/null +++ b/include/linux/if_alg.h @@ -0,0 +1,40 @@ +/* + * if_alg: User-space algorithm interface + * + * Copyright (c) 2010 Herbert Xu + * + * 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_IF_ALG_H +#define _LINUX_IF_ALG_H + +#include + +struct sockaddr_alg { + __u16 salg_family; + __u8 salg_type[14]; + __u32 salg_feat; + __u32 salg_mask; + __u8 salg_name[64]; +}; + +struct af_alg_iv { + __u32 ivlen; + __u8 iv[0]; +}; + +/* Socket options */ +#define ALG_SET_KEY 1 +#define ALG_SET_IV 2 +#define ALG_SET_OP 3 + +/* Operations */ +#define ALG_OP_DECRYPT 0 +#define ALG_OP_ENCRYPT 1 + +#endif /* _LINUX_IF_ALG_H */ -- cgit v1.2.3 From fe869cdb89c95d060c77eea20204d6c91f233b53 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Tue, 19 Oct 2010 21:23:00 +0800 Subject: crypto: algif_hash - User-space interface for hash operations This patch adds the af_alg plugin for hash, corresponding to the ahash kernel operation type. Keys can optionally be set through the setsockopt interface. Each sendmsg call will finalise the hash unless sent with a MSG_MORE flag. Partial hash states can be cloned using accept(2). The interface is completely synchronous, all operations will complete prior to the system call returning. Both sendmsg(2) and splice(2) support reading the user-space data directly without copying (except that the Crypto API itself may copy the data if alignment is off). For now only the splice(2) interface supports performing digest instead of init/update/final. In future the sendmsg(2) interface will also be modified to use digest/finup where possible so that hardware that cannot return a partial hash state can still benefit from this interface. Thakns to Miloslav Trmac for reviewing this and contributing fixes and improvements. Signed-off-by: Herbert Xu Acked-by: David S. Miller Tested-by: Martin Willi --- crypto/Kconfig | 8 ++ crypto/Makefile | 1 + crypto/algif_hash.c | 319 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 328 insertions(+) create mode 100644 crypto/algif_hash.c diff --git a/crypto/Kconfig b/crypto/Kconfig index 357e3caf4cbe..6db27d7ff8b3 100644 --- a/crypto/Kconfig +++ b/crypto/Kconfig @@ -844,6 +844,14 @@ config CRYPTO_ANSI_CPRNG config CRYPTO_USER_API tristate +config CRYPTO_USER_API_HASH + tristate "User-space interface for hash algorithms" + select CRYPTO_HASH + select CRYPTO_USER_API + help + This option enables the user-spaces interface for hash + algorithms. + source "drivers/crypto/Kconfig" endif # if CRYPTO diff --git a/crypto/Makefile b/crypto/Makefile index 0b1319734bc0..14ab4052a9c8 100644 --- a/crypto/Makefile +++ b/crypto/Makefile @@ -86,6 +86,7 @@ obj-$(CONFIG_CRYPTO_ANSI_CPRNG) += ansi_cprng.o obj-$(CONFIG_CRYPTO_TEST) += tcrypt.o obj-$(CONFIG_CRYPTO_GHASH) += ghash-generic.o obj-$(CONFIG_CRYPTO_USER_API) += af_alg.o +obj-$(CONFIG_CRYPTO_USER_API_HASH) += algif_hash.o # # generic algorithms and the async_tx api diff --git a/crypto/algif_hash.c b/crypto/algif_hash.c new file mode 100644 index 000000000000..62122a1a2f7a --- /dev/null +++ b/crypto/algif_hash.c @@ -0,0 +1,319 @@ +/* + * algif_hash: User-space interface for hash algorithms + * + * This file provides the user-space API for hash algorithms. + * + * Copyright (c) 2010 Herbert Xu + * + * 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. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +struct hash_ctx { + struct af_alg_sgl sgl; + + u8 *result; + + struct af_alg_completion completion; + + unsigned int len; + bool more; + + struct ahash_request req; +}; + +static int hash_sendmsg(struct kiocb *unused, struct socket *sock, + struct msghdr *msg, size_t ignored) +{ + int limit = ALG_MAX_PAGES * PAGE_SIZE; + struct sock *sk = sock->sk; + struct alg_sock *ask = alg_sk(sk); + struct hash_ctx *ctx = ask->private; + unsigned long iovlen; + struct iovec *iov; + long copied = 0; + int err; + + if (limit > sk->sk_sndbuf) + limit = sk->sk_sndbuf; + + lock_sock(sk); + if (!ctx->more) { + err = crypto_ahash_init(&ctx->req); + if (err) + goto unlock; + } + + ctx->more = 0; + + for (iov = msg->msg_iov, iovlen = msg->msg_iovlen; iovlen > 0; + iovlen--, iov++) { + unsigned long seglen = iov->iov_len; + char __user *from = iov->iov_base; + + while (seglen) { + int len = min_t(unsigned long, seglen, limit); + int newlen; + + newlen = af_alg_make_sg(&ctx->sgl, from, len, 0); + if (newlen < 0) + goto unlock; + + ahash_request_set_crypt(&ctx->req, ctx->sgl.sg, NULL, + newlen); + + err = af_alg_wait_for_completion( + crypto_ahash_update(&ctx->req), + &ctx->completion); + + af_alg_free_sg(&ctx->sgl); + + if (err) + goto unlock; + + seglen -= newlen; + from += newlen; + copied += newlen; + } + } + + err = 0; + + ctx->more = msg->msg_flags & MSG_MORE; + if (!ctx->more) { + ahash_request_set_crypt(&ctx->req, NULL, ctx->result, 0); + err = af_alg_wait_for_completion(crypto_ahash_final(&ctx->req), + &ctx->completion); + } + +unlock: + release_sock(sk); + + return err ?: copied; +} + +static ssize_t hash_sendpage(struct socket *sock, struct page *page, + int offset, size_t size, int flags) +{ + struct sock *sk = sock->sk; + struct alg_sock *ask = alg_sk(sk); + struct hash_ctx *ctx = ask->private; + int err; + + lock_sock(sk); + sg_init_table(ctx->sgl.sg, 1); + sg_set_page(ctx->sgl.sg, page, size, offset); + + ahash_request_set_crypt(&ctx->req, ctx->sgl.sg, ctx->result, size); + + if (!(flags & MSG_MORE)) { + if (ctx->more) + err = crypto_ahash_finup(&ctx->req); + else + err = crypto_ahash_digest(&ctx->req); + } else { + if (!ctx->more) { + err = crypto_ahash_init(&ctx->req); + if (err) + goto unlock; + } + + err = crypto_ahash_update(&ctx->req); + } + + err = af_alg_wait_for_completion(err, &ctx->completion); + if (err) + goto unlock; + + ctx->more = flags & MSG_MORE; + +unlock: + release_sock(sk); + + return err ?: size; +} + +static int hash_recvmsg(struct kiocb *unused, struct socket *sock, + struct msghdr *msg, size_t len, int flags) +{ + struct sock *sk = sock->sk; + struct alg_sock *ask = alg_sk(sk); + struct hash_ctx *ctx = ask->private; + unsigned ds = crypto_ahash_digestsize(crypto_ahash_reqtfm(&ctx->req)); + int err; + + if (len > ds) + len = ds; + else if (len < ds) + msg->msg_flags |= MSG_TRUNC; + + lock_sock(sk); + if (ctx->more) { + ctx->more = 0; + ahash_request_set_crypt(&ctx->req, NULL, ctx->result, 0); + err = af_alg_wait_for_completion(crypto_ahash_final(&ctx->req), + &ctx->completion); + if (err) + goto unlock; + } + + err = memcpy_toiovec(msg->msg_iov, ctx->result, len); + +unlock: + release_sock(sk); + + return err ?: len; +} + +static int hash_accept(struct socket *sock, struct socket *newsock, int flags) +{ + struct sock *sk = sock->sk; + struct alg_sock *ask = alg_sk(sk); + struct hash_ctx *ctx = ask->private; + struct ahash_request *req = &ctx->req; + char state[crypto_ahash_statesize(crypto_ahash_reqtfm(req))]; + struct sock *sk2; + struct alg_sock *ask2; + struct hash_ctx *ctx2; + int err; + + err = crypto_ahash_export(req, state); + if (err) + return err; + + err = af_alg_accept(ask->parent, newsock); + if (err) + return err; + + sk2 = newsock->sk; + ask2 = alg_sk(sk2); + ctx2 = ask2->private; + ctx2->more = 1; + + err = crypto_ahash_import(&ctx2->req, state); + if (err) { + sock_orphan(sk2); + sock_put(sk2); + } + + return err; +} + +static struct proto_ops algif_hash_ops = { + .family = PF_ALG, + + .connect = sock_no_connect, + .socketpair = sock_no_socketpair, + .getname = sock_no_getname, + .ioctl = sock_no_ioctl, + .listen = sock_no_listen, + .shutdown = sock_no_shutdown, + .getsockopt = sock_no_getsockopt, + .mmap = sock_no_mmap, + .bind = sock_no_bind, + .setsockopt = sock_no_setsockopt, + .poll = sock_no_poll, + + .release = af_alg_release, + .sendmsg = hash_sendmsg, + .sendpage = hash_sendpage, + .recvmsg = hash_recvmsg, + .accept = hash_accept, +}; + +static void *hash_bind(const char *name, u32 type, u32 mask) +{ + return crypto_alloc_ahash(name, type, mask); +} + +static void hash_release(void *private) +{ + crypto_free_ahash(private); +} + +static int hash_setkey(void *private, const u8 *key, unsigned int keylen) +{ + return crypto_ahash_setkey(private, key, keylen); +} + +static void hash_sock_destruct(struct sock *sk) +{ + struct alg_sock *ask = alg_sk(sk); + struct hash_ctx *ctx = ask->private; + + sock_kfree_s(sk, ctx->result, + crypto_ahash_digestsize(crypto_ahash_reqtfm(&ctx->req))); + sock_kfree_s(sk, ctx, ctx->len); + af_alg_release_parent(sk); +} + +static int hash_accept_parent(void *private, struct sock *sk) +{ + struct hash_ctx *ctx; + struct alg_sock *ask = alg_sk(sk); + unsigned len = sizeof(*ctx) + crypto_ahash_reqsize(private); + unsigned ds = crypto_ahash_digestsize(private); + + ctx = sock_kmalloc(sk, len, GFP_KERNEL); + if (!ctx) + return -ENOMEM; + + ctx->result = sock_kmalloc(sk, ds, GFP_KERNEL); + if (!ctx->result) { + sock_kfree_s(sk, ctx, len); + return -ENOMEM; + } + + memset(ctx->result, 0, ds); + + ctx->len = len; + ctx->more = 0; + af_alg_init_completion(&ctx->completion); + + ask->private = ctx; + + ahash_request_set_tfm(&ctx->req, private); + ahash_request_set_callback(&ctx->req, CRYPTO_TFM_REQ_MAY_BACKLOG, + af_alg_complete, &ctx->completion); + + sk->sk_destruct = hash_sock_destruct; + + return 0; +} + +static const struct af_alg_type algif_type_hash = { + .bind = hash_bind, + .release = hash_release, + .setkey = hash_setkey, + .accept = hash_accept_parent, + .ops = &algif_hash_ops, + .name = "hash", + .owner = THIS_MODULE +}; + +static int __init algif_hash_init(void) +{ + return af_alg_register_type(&algif_type_hash); +} + +static void __exit algif_hash_exit(void) +{ + int err = af_alg_unregister_type(&algif_type_hash); + BUG_ON(err); +} + +module_init(algif_hash_init); +module_exit(algif_hash_exit); +MODULE_LICENSE("GPL"); -- cgit v1.2.3 From 96b101efae0ab68b6510fdbb30384849d211da2c Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 18 Nov 2010 15:49:38 +0000 Subject: ASoC: Provide ADC left/right channel source selection on WM8994 Allow the application to choose if the ADC data presented on the left and right channels is sourced from the internal left or right channel. This allows a mono recording to be presented as stereo on the external bus. Signed-off-by: Mark Brown Acked-by: Liam Girdwood --- sound/soc/codecs/wm8994.c | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index bfdb7daeed2d..7d2f488de6a7 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c @@ -2069,21 +2069,33 @@ static int wm8994_get_retune_mobile_enum(struct snd_kcontrol *kcontrol, return 0; } -static const char *aifdac_src_text[] = { +static const char *aif_chan_src_text[] = { "Left", "Right" }; +static const struct soc_enum aif1adcl_src = + SOC_ENUM_SINGLE(WM8994_AIF1_CONTROL_1, 15, 2, aif_chan_src_text); + +static const struct soc_enum aif1adcr_src = + SOC_ENUM_SINGLE(WM8994_AIF1_CONTROL_1, 14, 2, aif_chan_src_text); + +static const struct soc_enum aif2adcl_src = + SOC_ENUM_SINGLE(WM8994_AIF2_CONTROL_1, 15, 2, aif_chan_src_text); + +static const struct soc_enum aif2adcr_src = + SOC_ENUM_SINGLE(WM8994_AIF2_CONTROL_1, 14, 2, aif_chan_src_text); + static const struct soc_enum aif1dacl_src = - SOC_ENUM_SINGLE(WM8994_AIF1_CONTROL_2, 15, 2, aifdac_src_text); + SOC_ENUM_SINGLE(WM8994_AIF1_CONTROL_2, 15, 2, aif_chan_src_text); static const struct soc_enum aif1dacr_src = - SOC_ENUM_SINGLE(WM8994_AIF1_CONTROL_2, 14, 2, aifdac_src_text); + SOC_ENUM_SINGLE(WM8994_AIF1_CONTROL_2, 14, 2, aif_chan_src_text); static const struct soc_enum aif2dacl_src = - SOC_ENUM_SINGLE(WM8994_AIF2_CONTROL_2, 15, 2, aifdac_src_text); + SOC_ENUM_SINGLE(WM8994_AIF2_CONTROL_2, 15, 2, aif_chan_src_text); static const struct soc_enum aif2dacr_src = - SOC_ENUM_SINGLE(WM8994_AIF2_CONTROL_2, 14, 2, aifdac_src_text); + SOC_ENUM_SINGLE(WM8994_AIF2_CONTROL_2, 14, 2, aif_chan_src_text); static const struct snd_kcontrol_new wm8994_snd_controls[] = { SOC_DOUBLE_R_TLV("AIF1ADC1 Volume", WM8994_AIF1_ADC1_LEFT_VOLUME, @@ -2096,6 +2108,11 @@ SOC_DOUBLE_R_TLV("AIF2ADC Volume", WM8994_AIF2_ADC_LEFT_VOLUME, WM8994_AIF2_ADC_RIGHT_VOLUME, 1, 119, 0, digital_tlv), +SOC_ENUM("AIF1ADCL Source", aif1adcl_src), +SOC_ENUM("AIF1ADCR Source", aif1adcr_src), +SOC_ENUM("AIF2ADCL Source", aif1adcl_src), +SOC_ENUM("AIF2ADCR Source", aif1adcr_src), + SOC_ENUM("AIF1DACL Source", aif1dacl_src), SOC_ENUM("AIF1DACR Source", aif1dacr_src), SOC_ENUM("AIF2DACL Source", aif1dacl_src), -- cgit v1.2.3 From 7b306dae22ca377ea0020261ef13aea85b8f5f3f Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 16 Nov 2010 20:11:40 +0000 Subject: ASoC: Move WM8994 read/write access data into separate file Makes the WM8994 driver file itself substantially smaller. Signed-off-by: Mark Brown Acked-by: Liam Girdwood --- sound/soc/codecs/Makefile | 2 +- sound/soc/codecs/wm8994-tables.c | 1575 +++++++++++++++++++++++++++++++++++++ sound/soc/codecs/wm8994.c | 1582 +------------------------------------- sound/soc/codecs/wm8994.h | 9 + 4 files changed, 1588 insertions(+), 1580 deletions(-) create mode 100644 sound/soc/codecs/wm8994-tables.c diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index 42f185d233f3..3469fab2863a 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile @@ -60,7 +60,7 @@ snd-soc-wm8985-objs := wm8985.o snd-soc-wm8988-objs := wm8988.o snd-soc-wm8990-objs := wm8990.o snd-soc-wm8993-objs := wm8993.o -snd-soc-wm8994-objs := wm8994.o +snd-soc-wm8994-objs := wm8994.o wm8994-tables.o snd-soc-wm9081-objs := wm9081.o snd-soc-wm9705-objs := wm9705.o snd-soc-wm9712-objs := wm9712.o diff --git a/sound/soc/codecs/wm8994-tables.c b/sound/soc/codecs/wm8994-tables.c new file mode 100644 index 000000000000..7b935387aeef --- /dev/null +++ b/sound/soc/codecs/wm8994-tables.c @@ -0,0 +1,1575 @@ +#include "wm8994.h" + +const struct wm8994_access_mask wm8994_access_masks[WM8994_CACHE_SIZE] = { + { 0xFFFF, 0xFFFF }, /* R0 - Software Reset */ + { 0x3B37, 0x3B37 }, /* R1 - Power Management (1) */ + { 0x6BF0, 0x6BF0 }, /* R2 - Power Management (2) */ + { 0x3FF0, 0x3FF0 }, /* R3 - Power Management (3) */ + { 0x3F3F, 0x3F3F }, /* R4 - Power Management (4) */ + { 0x3F0F, 0x3F0F }, /* R5 - Power Management (5) */ + { 0x003F, 0x003F }, /* R6 - Power Management (6) */ + { 0x0000, 0x0000 }, /* R7 */ + { 0x0000, 0x0000 }, /* R8 */ + { 0x0000, 0x0000 }, /* R9 */ + { 0x0000, 0x0000 }, /* R10 */ + { 0x0000, 0x0000 }, /* R11 */ + { 0x0000, 0x0000 }, /* R12 */ + { 0x0000, 0x0000 }, /* R13 */ + { 0x0000, 0x0000 }, /* R14 */ + { 0x0000, 0x0000 }, /* R15 */ + { 0x0000, 0x0000 }, /* R16 */ + { 0x0000, 0x0000 }, /* R17 */ + { 0x0000, 0x0000 }, /* R18 */ + { 0x0000, 0x0000 }, /* R19 */ + { 0x0000, 0x0000 }, /* R20 */ + { 0x01C0, 0x01C0 }, /* R21 - Input Mixer (1) */ + { 0x0000, 0x0000 }, /* R22 */ + { 0x0000, 0x0000 }, /* R23 */ + { 0x00DF, 0x01DF }, /* R24 - Left Line Input 1&2 Volume */ + { 0x00DF, 0x01DF }, /* R25 - Left Line Input 3&4 Volume */ + { 0x00DF, 0x01DF }, /* R26 - Right Line Input 1&2 Volume */ + { 0x00DF, 0x01DF }, /* R27 - Right Line Input 3&4 Volume */ + { 0x00FF, 0x01FF }, /* R28 - Left Output Volume */ + { 0x00FF, 0x01FF }, /* R29 - Right Output Volume */ + { 0x0077, 0x0077 }, /* R30 - Line Outputs Volume */ + { 0x0030, 0x0030 }, /* R31 - HPOUT2 Volume */ + { 0x00FF, 0x01FF }, /* R32 - Left OPGA Volume */ + { 0x00FF, 0x01FF }, /* R33 - Right OPGA Volume */ + { 0x007F, 0x007F }, /* R34 - SPKMIXL Attenuation */ + { 0x017F, 0x017F }, /* R35 - SPKMIXR Attenuation */ + { 0x003F, 0x003F }, /* R36 - SPKOUT Mixers */ + { 0x003F, 0x003F }, /* R37 - ClassD */ + { 0x00FF, 0x01FF }, /* R38 - Speaker Volume Left */ + { 0x00FF, 0x01FF }, /* R39 - Speaker Volume Right */ + { 0x00FF, 0x00FF }, /* R40 - Input Mixer (2) */ + { 0x01B7, 0x01B7 }, /* R41 - Input Mixer (3) */ + { 0x01B7, 0x01B7 }, /* R42 - Input Mixer (4) */ + { 0x01C7, 0x01C7 }, /* R43 - Input Mixer (5) */ + { 0x01C7, 0x01C7 }, /* R44 - Input Mixer (6) */ + { 0x01FF, 0x01FF }, /* R45 - Output Mixer (1) */ + { 0x01FF, 0x01FF }, /* R46 - Output Mixer (2) */ + { 0x0FFF, 0x0FFF }, /* R47 - Output Mixer (3) */ + { 0x0FFF, 0x0FFF }, /* R48 - Output Mixer (4) */ + { 0x0FFF, 0x0FFF }, /* R49 - Output Mixer (5) */ + { 0x0FFF, 0x0FFF }, /* R50 - Output Mixer (6) */ + { 0x0038, 0x0038 }, /* R51 - HPOUT2 Mixer */ + { 0x0077, 0x0077 }, /* R52 - Line Mixer (1) */ + { 0x0077, 0x0077 }, /* R53 - Line Mixer (2) */ + { 0x03FF, 0x03FF }, /* R54 - Speaker Mixer */ + { 0x00C1, 0x00C1 }, /* R55 - Additional Control */ + { 0x00F0, 0x00F0 }, /* R56 - AntiPOP (1) */ + { 0x01EF, 0x01EF }, /* R57 - AntiPOP (2) */ + { 0x00FF, 0x00FF }, /* R58 - MICBIAS */ + { 0x000F, 0x000F }, /* R59 - LDO 1 */ + { 0x0007, 0x0007 }, /* R60 - LDO 2 */ + { 0x0000, 0x0000 }, /* R61 */ + { 0x0000, 0x0000 }, /* R62 */ + { 0x0000, 0x0000 }, /* R63 */ + { 0x0000, 0x0000 }, /* R64 */ + { 0x0000, 0x0000 }, /* R65 */ + { 0x0000, 0x0000 }, /* R66 */ + { 0x0000, 0x0000 }, /* R67 */ + { 0x0000, 0x0000 }, /* R68 */ + { 0x0000, 0x0000 }, /* R69 */ + { 0x0000, 0x0000 }, /* R70 */ + { 0x0000, 0x0000 }, /* R71 */ + { 0x0000, 0x0000 }, /* R72 */ + { 0x0000, 0x0000 }, /* R73 */ + { 0x0000, 0x0000 }, /* R74 */ + { 0x0000, 0x0000 }, /* R75 */ + { 0x8000, 0x8000 }, /* R76 - Charge Pump (1) */ + { 0x0000, 0x0000 }, /* R77 */ + { 0x0000, 0x0000 }, /* R78 */ + { 0x0000, 0x0000 }, /* R79 */ + { 0x0000, 0x0000 }, /* R80 */ + { 0x0301, 0x0301 }, /* R81 - Class W (1) */ + { 0x0000, 0x0000 }, /* R82 */ + { 0x0000, 0x0000 }, /* R83 */ + { 0x333F, 0x333F }, /* R84 - DC Servo (1) */ + { 0x0FEF, 0x0FEF }, /* R85 - DC Servo (2) */ + { 0x0000, 0x0000 }, /* R86 */ + { 0xFFFF, 0xFFFF }, /* R87 - DC Servo (4) */ + { 0x0333, 0x0000 }, /* R88 - DC Servo Readback */ + { 0x0000, 0x0000 }, /* R89 */ + { 0x0000, 0x0000 }, /* R90 */ + { 0x0000, 0x0000 }, /* R91 */ + { 0x0000, 0x0000 }, /* R92 */ + { 0x0000, 0x0000 }, /* R93 */ + { 0x0000, 0x0000 }, /* R94 */ + { 0x0000, 0x0000 }, /* R95 */ + { 0x00EE, 0x00EE }, /* R96 - Analogue HP (1) */ + { 0x0000, 0x0000 }, /* R97 */ + { 0x0000, 0x0000 }, /* R98 */ + { 0x0000, 0x0000 }, /* R99 */ + { 0x0000, 0x0000 }, /* R100 */ + { 0x0000, 0x0000 }, /* R101 */ + { 0x0000, 0x0000 }, /* R102 */ + { 0x0000, 0x0000 }, /* R103 */ + { 0x0000, 0x0000 }, /* R104 */ + { 0x0000, 0x0000 }, /* R105 */ + { 0x0000, 0x0000 }, /* R106 */ + { 0x0000, 0x0000 }, /* R107 */ + { 0x0000, 0x0000 }, /* R108 */ + { 0x0000, 0x0000 }, /* R109 */ + { 0x0000, 0x0000 }, /* R110 */ + { 0x0000, 0x0000 }, /* R111 */ + { 0x0000, 0x0000 }, /* R112 */ + { 0x0000, 0x0000 }, /* R113 */ + { 0x0000, 0x0000 }, /* R114 */ + { 0x0000, 0x0000 }, /* R115 */ + { 0x0000, 0x0000 }, /* R116 */ + { 0x0000, 0x0000 }, /* R117 */ + { 0x0000, 0x0000 }, /* R118 */ + { 0x0000, 0x0000 }, /* R119 */ + { 0x0000, 0x0000 }, /* R120 */ + { 0x0000, 0x0000 }, /* R121 */ + { 0x0000, 0x0000 }, /* R122 */ + { 0x0000, 0x0000 }, /* R123 */ + { 0x0000, 0x0000 }, /* R124 */ + { 0x0000, 0x0000 }, /* R125 */ + { 0x0000, 0x0000 }, /* R126 */ + { 0x0000, 0x0000 }, /* R127 */ + { 0x0000, 0x0000 }, /* R128 */ + { 0x0000, 0x0000 }, /* R129 */ + { 0x0000, 0x0000 }, /* R130 */ + { 0x0000, 0x0000 }, /* R131 */ + { 0x0000, 0x0000 }, /* R132 */ + { 0x0000, 0x0000 }, /* R133 */ + { 0x0000, 0x0000 }, /* R134 */ + { 0x0000, 0x0000 }, /* R135 */ + { 0x0000, 0x0000 }, /* R136 */ + { 0x0000, 0x0000 }, /* R137 */ + { 0x0000, 0x0000 }, /* R138 */ + { 0x0000, 0x0000 }, /* R139 */ + { 0x0000, 0x0000 }, /* R140 */ + { 0x0000, 0x0000 }, /* R141 */ + { 0x0000, 0x0000 }, /* R142 */ + { 0x0000, 0x0000 }, /* R143 */ + { 0x0000, 0x0000 }, /* R144 */ + { 0x0000, 0x0000 }, /* R145 */ + { 0x0000, 0x0000 }, /* R146 */ + { 0x0000, 0x0000 }, /* R147 */ + { 0x0000, 0x0000 }, /* R148 */ + { 0x0000, 0x0000 }, /* R149 */ + { 0x0000, 0x0000 }, /* R150 */ + { 0x0000, 0x0000 }, /* R151 */ + { 0x0000, 0x0000 }, /* R152 */ + { 0x0000, 0x0000 }, /* R153 */ + { 0x0000, 0x0000 }, /* R154 */ + { 0x0000, 0x0000 }, /* R155 */ + { 0x0000, 0x0000 }, /* R156 */ + { 0x0000, 0x0000 }, /* R157 */ + { 0x0000, 0x0000 }, /* R158 */ + { 0x0000, 0x0000 }, /* R159 */ + { 0x0000, 0x0000 }, /* R160 */ + { 0x0000, 0x0000 }, /* R161 */ + { 0x0000, 0x0000 }, /* R162 */ + { 0x0000, 0x0000 }, /* R163 */ + { 0x0000, 0x0000 }, /* R164 */ + { 0x0000, 0x0000 }, /* R165 */ + { 0x0000, 0x0000 }, /* R166 */ + { 0x0000, 0x0000 }, /* R167 */ + { 0x0000, 0x0000 }, /* R168 */ + { 0x0000, 0x0000 }, /* R169 */ + { 0x0000, 0x0000 }, /* R170 */ + { 0x0000, 0x0000 }, /* R171 */ + { 0x0000, 0x0000 }, /* R172 */ + { 0x0000, 0x0000 }, /* R173 */ + { 0x0000, 0x0000 }, /* R174 */ + { 0x0000, 0x0000 }, /* R175 */ + { 0x0000, 0x0000 }, /* R176 */ + { 0x0000, 0x0000 }, /* R177 */ + { 0x0000, 0x0000 }, /* R178 */ + { 0x0000, 0x0000 }, /* R179 */ + { 0x0000, 0x0000 }, /* R180 */ + { 0x0000, 0x0000 }, /* R181 */ + { 0x0000, 0x0000 }, /* R182 */ + { 0x0000, 0x0000 }, /* R183 */ + { 0x0000, 0x0000 }, /* R184 */ + { 0x0000, 0x0000 }, /* R185 */ + { 0x0000, 0x0000 }, /* R186 */ + { 0x0000, 0x0000 }, /* R187 */ + { 0x0000, 0x0000 }, /* R188 */ + { 0x0000, 0x0000 }, /* R189 */ + { 0x0000, 0x0000 }, /* R190 */ + { 0x0000, 0x0000 }, /* R191 */ + { 0x0000, 0x0000 }, /* R192 */ + { 0x0000, 0x0000 }, /* R193 */ + { 0x0000, 0x0000 }, /* R194 */ + { 0x0000, 0x0000 }, /* R195 */ + { 0x0000, 0x0000 }, /* R196 */ + { 0x0000, 0x0000 }, /* R197 */ + { 0x0000, 0x0000 }, /* R198 */ + { 0x0000, 0x0000 }, /* R199 */ + { 0x0000, 0x0000 }, /* R200 */ + { 0x0000, 0x0000 }, /* R201 */ + { 0x0000, 0x0000 }, /* R202 */ + { 0x0000, 0x0000 }, /* R203 */ + { 0x0000, 0x0000 }, /* R204 */ + { 0x0000, 0x0000 }, /* R205 */ + { 0x0000, 0x0000 }, /* R206 */ + { 0x0000, 0x0000 }, /* R207 */ + { 0x0000, 0x0000 }, /* R208 */ + { 0x0000, 0x0000 }, /* R209 */ + { 0x0000, 0x0000 }, /* R210 */ + { 0x0000, 0x0000 }, /* R211 */ + { 0x0000, 0x0000 }, /* R212 */ + { 0x0000, 0x0000 }, /* R213 */ + { 0x0000, 0x0000 }, /* R214 */ + { 0x0000, 0x0000 }, /* R215 */ + { 0x0000, 0x0000 }, /* R216 */ + { 0x0000, 0x0000 }, /* R217 */ + { 0x0000, 0x0000 }, /* R218 */ + { 0x0000, 0x0000 }, /* R219 */ + { 0x0000, 0x0000 }, /* R220 */ + { 0x0000, 0x0000 }, /* R221 */ + { 0x0000, 0x0000 }, /* R222 */ + { 0x0000, 0x0000 }, /* R223 */ + { 0x0000, 0x0000 }, /* R224 */ + { 0x0000, 0x0000 }, /* R225 */ + { 0x0000, 0x0000 }, /* R226 */ + { 0x0000, 0x0000 }, /* R227 */ + { 0x0000, 0x0000 }, /* R228 */ + { 0x0000, 0x0000 }, /* R229 */ + { 0x0000, 0x0000 }, /* R230 */ + { 0x0000, 0x0000 }, /* R231 */ + { 0x0000, 0x0000 }, /* R232 */ + { 0x0000, 0x0000 }, /* R233 */ + { 0x0000, 0x0000 }, /* R234 */ + { 0x0000, 0x0000 }, /* R235 */ + { 0x0000, 0x0000 }, /* R236 */ + { 0x0000, 0x0000 }, /* R237 */ + { 0x0000, 0x0000 }, /* R238 */ + { 0x0000, 0x0000 }, /* R239 */ + { 0x0000, 0x0000 }, /* R240 */ + { 0x0000, 0x0000 }, /* R241 */ + { 0x0000, 0x0000 }, /* R242 */ + { 0x0000, 0x0000 }, /* R243 */ + { 0x0000, 0x0000 }, /* R244 */ + { 0x0000, 0x0000 }, /* R245 */ + { 0x0000, 0x0000 }, /* R246 */ + { 0x0000, 0x0000 }, /* R247 */ + { 0x0000, 0x0000 }, /* R248 */ + { 0x0000, 0x0000 }, /* R249 */ + { 0x0000, 0x0000 }, /* R250 */ + { 0x0000, 0x0000 }, /* R251 */ + { 0x0000, 0x0000 }, /* R252 */ + { 0x0000, 0x0000 }, /* R253 */ + { 0x0000, 0x0000 }, /* R254 */ + { 0x0000, 0x0000 }, /* R255 */ + { 0x000F, 0x0000 }, /* R256 - Chip Revision */ + { 0x0074, 0x0074 }, /* R257 - Control Interface */ + { 0x0000, 0x0000 }, /* R258 */ + { 0x0000, 0x0000 }, /* R259 */ + { 0x0000, 0x0000 }, /* R260 */ + { 0x0000, 0x0000 }, /* R261 */ + { 0x0000, 0x0000 }, /* R262 */ + { 0x0000, 0x0000 }, /* R263 */ + { 0x0000, 0x0000 }, /* R264 */ + { 0x0000, 0x0000 }, /* R265 */ + { 0x0000, 0x0000 }, /* R266 */ + { 0x0000, 0x0000 }, /* R267 */ + { 0x0000, 0x0000 }, /* R268 */ + { 0x0000, 0x0000 }, /* R269 */ + { 0x0000, 0x0000 }, /* R270 */ + { 0x0000, 0x0000 }, /* R271 */ + { 0x807F, 0x837F }, /* R272 - Write Sequencer Ctrl (1) */ + { 0x017F, 0x0000 }, /* R273 - Write Sequencer Ctrl (2) */ + { 0x0000, 0x0000 }, /* R274 */ + { 0x0000, 0x0000 }, /* R275 */ + { 0x0000, 0x0000 }, /* R276 */ + { 0x0000, 0x0000 }, /* R277 */ + { 0x0000, 0x0000 }, /* R278 */ + { 0x0000, 0x0000 }, /* R279 */ + { 0x0000, 0x0000 }, /* R280 */ + { 0x0000, 0x0000 }, /* R281 */ + { 0x0000, 0x0000 }, /* R282 */ + { 0x0000, 0x0000 }, /* R283 */ + { 0x0000, 0x0000 }, /* R284 */ + { 0x0000, 0x0000 }, /* R285 */ + { 0x0000, 0x0000 }, /* R286 */ + { 0x0000, 0x0000 }, /* R287 */ + { 0x0000, 0x0000 }, /* R288 */ + { 0x0000, 0x0000 }, /* R289 */ + { 0x0000, 0x0000 }, /* R290 */ + { 0x0000, 0x0000 }, /* R291 */ + { 0x0000, 0x0000 }, /* R292 */ + { 0x0000, 0x0000 }, /* R293 */ + { 0x0000, 0x0000 }, /* R294 */ + { 0x0000, 0x0000 }, /* R295 */ + { 0x0000, 0x0000 }, /* R296 */ + { 0x0000, 0x0000 }, /* R297 */ + { 0x0000, 0x0000 }, /* R298 */ + { 0x0000, 0x0000 }, /* R299 */ + { 0x0000, 0x0000 }, /* R300 */ + { 0x0000, 0x0000 }, /* R301 */ + { 0x0000, 0x0000 }, /* R302 */ + { 0x0000, 0x0000 }, /* R303 */ + { 0x0000, 0x0000 }, /* R304 */ + { 0x0000, 0x0000 }, /* R305 */ + { 0x0000, 0x0000 }, /* R306 */ + { 0x0000, 0x0000 }, /* R307 */ + { 0x0000, 0x0000 }, /* R308 */ + { 0x0000, 0x0000 }, /* R309 */ + { 0x0000, 0x0000 }, /* R310 */ + { 0x0000, 0x0000 }, /* R311 */ + { 0x0000, 0x0000 }, /* R312 */ + { 0x0000, 0x0000 }, /* R313 */ + { 0x0000, 0x0000 }, /* R314 */ + { 0x0000, 0x0000 }, /* R315 */ + { 0x0000, 0x0000 }, /* R316 */ + { 0x0000, 0x0000 }, /* R317 */ + { 0x0000, 0x0000 }, /* R318 */ + { 0x0000, 0x0000 }, /* R319 */ + { 0x0000, 0x0000 }, /* R320 */ + { 0x0000, 0x0000 }, /* R321 */ + { 0x0000, 0x0000 }, /* R322 */ + { 0x0000, 0x0000 }, /* R323 */ + { 0x0000, 0x0000 }, /* R324 */ + { 0x0000, 0x0000 }, /* R325 */ + { 0x0000, 0x0000 }, /* R326 */ + { 0x0000, 0x0000 }, /* R327 */ + { 0x0000, 0x0000 }, /* R328 */ + { 0x0000, 0x0000 }, /* R329 */ + { 0x0000, 0x0000 }, /* R330 */ + { 0x0000, 0x0000 }, /* R331 */ + { 0x0000, 0x0000 }, /* R332 */ + { 0x0000, 0x0000 }, /* R333 */ + { 0x0000, 0x0000 }, /* R334 */ + { 0x0000, 0x0000 }, /* R335 */ + { 0x0000, 0x0000 }, /* R336 */ + { 0x0000, 0x0000 }, /* R337 */ + { 0x0000, 0x0000 }, /* R338 */ + { 0x0000, 0x0000 }, /* R339 */ + { 0x0000, 0x0000 }, /* R340 */ + { 0x0000, 0x0000 }, /* R341 */ + { 0x0000, 0x0000 }, /* R342 */ + { 0x0000, 0x0000 }, /* R343 */ + { 0x0000, 0x0000 }, /* R344 */ + { 0x0000, 0x0000 }, /* R345 */ + { 0x0000, 0x0000 }, /* R346 */ + { 0x0000, 0x0000 }, /* R347 */ + { 0x0000, 0x0000 }, /* R348 */ + { 0x0000, 0x0000 }, /* R349 */ + { 0x0000, 0x0000 }, /* R350 */ + { 0x0000, 0x0000 }, /* R351 */ + { 0x0000, 0x0000 }, /* R352 */ + { 0x0000, 0x0000 }, /* R353 */ + { 0x0000, 0x0000 }, /* R354 */ + { 0x0000, 0x0000 }, /* R355 */ + { 0x0000, 0x0000 }, /* R356 */ + { 0x0000, 0x0000 }, /* R357 */ + { 0x0000, 0x0000 }, /* R358 */ + { 0x0000, 0x0000 }, /* R359 */ + { 0x0000, 0x0000 }, /* R360 */ + { 0x0000, 0x0000 }, /* R361 */ + { 0x0000, 0x0000 }, /* R362 */ + { 0x0000, 0x0000 }, /* R363 */ + { 0x0000, 0x0000 }, /* R364 */ + { 0x0000, 0x0000 }, /* R365 */ + { 0x0000, 0x0000 }, /* R366 */ + { 0x0000, 0x0000 }, /* R367 */ + { 0x0000, 0x0000 }, /* R368 */ + { 0x0000, 0x0000 }, /* R369 */ + { 0x0000, 0x0000 }, /* R370 */ + { 0x0000, 0x0000 }, /* R371 */ + { 0x0000, 0x0000 }, /* R372 */ + { 0x0000, 0x0000 }, /* R373 */ + { 0x0000, 0x0000 }, /* R374 */ + { 0x0000, 0x0000 }, /* R375 */ + { 0x0000, 0x0000 }, /* R376 */ + { 0x0000, 0x0000 }, /* R377 */ + { 0x0000, 0x0000 }, /* R378 */ + { 0x0000, 0x0000 }, /* R379 */ + { 0x0000, 0x0000 }, /* R380 */ + { 0x0000, 0x0000 }, /* R381 */ + { 0x0000, 0x0000 }, /* R382 */ + { 0x0000, 0x0000 }, /* R383 */ + { 0x0000, 0x0000 }, /* R384 */ + { 0x0000, 0x0000 }, /* R385 */ + { 0x0000, 0x0000 }, /* R386 */ + { 0x0000, 0x0000 }, /* R387 */ + { 0x0000, 0x0000 }, /* R388 */ + { 0x0000, 0x0000 }, /* R389 */ + { 0x0000, 0x0000 }, /* R390 */ + { 0x0000, 0x0000 }, /* R391 */ + { 0x0000, 0x0000 }, /* R392 */ + { 0x0000, 0x0000 }, /* R393 */ + { 0x0000, 0x0000 }, /* R394 */ + { 0x0000, 0x0000 }, /* R395 */ + { 0x0000, 0x0000 }, /* R396 */ + { 0x0000, 0x0000 }, /* R397 */ + { 0x0000, 0x0000 }, /* R398 */ + { 0x0000, 0x0000 }, /* R399 */ + { 0x0000, 0x0000 }, /* R400 */ + { 0x0000, 0x0000 }, /* R401 */ + { 0x0000, 0x0000 }, /* R402 */ + { 0x0000, 0x0000 }, /* R403 */ + { 0x0000, 0x0000 }, /* R404 */ + { 0x0000, 0x0000 }, /* R405 */ + { 0x0000, 0x0000 }, /* R406 */ + { 0x0000, 0x0000 }, /* R407 */ + { 0x0000, 0x0000 }, /* R408 */ + { 0x0000, 0x0000 }, /* R409 */ + { 0x0000, 0x0000 }, /* R410 */ + { 0x0000, 0x0000 }, /* R411 */ + { 0x0000, 0x0000 }, /* R412 */ + { 0x0000, 0x0000 }, /* R413 */ + { 0x0000, 0x0000 }, /* R414 */ + { 0x0000, 0x0000 }, /* R415 */ + { 0x0000, 0x0000 }, /* R416 */ + { 0x0000, 0x0000 }, /* R417 */ + { 0x0000, 0x0000 }, /* R418 */ + { 0x0000, 0x0000 }, /* R419 */ + { 0x0000, 0x0000 }, /* R420 */ + { 0x0000, 0x0000 }, /* R421 */ + { 0x0000, 0x0000 }, /* R422 */ + { 0x0000, 0x0000 }, /* R423 */ + { 0x0000, 0x0000 }, /* R424 */ + { 0x0000, 0x0000 }, /* R425 */ + { 0x0000, 0x0000 }, /* R426 */ + { 0x0000, 0x0000 }, /* R427 */ + { 0x0000, 0x0000 }, /* R428 */ + { 0x0000, 0x0000 }, /* R429 */ + { 0x0000, 0x0000 }, /* R430 */ + { 0x0000, 0x0000 }, /* R431 */ + { 0x0000, 0x0000 }, /* R432 */ + { 0x0000, 0x0000 }, /* R433 */ + { 0x0000, 0x0000 }, /* R434 */ + { 0x0000, 0x0000 }, /* R435 */ + { 0x0000, 0x0000 }, /* R436 */ + { 0x0000, 0x0000 }, /* R437 */ + { 0x0000, 0x0000 }, /* R438 */ + { 0x0000, 0x0000 }, /* R439 */ + { 0x0000, 0x0000 }, /* R440 */ + { 0x0000, 0x0000 }, /* R441 */ + { 0x0000, 0x0000 }, /* R442 */ + { 0x0000, 0x0000 }, /* R443 */ + { 0x0000, 0x0000 }, /* R444 */ + { 0x0000, 0x0000 }, /* R445 */ + { 0x0000, 0x0000 }, /* R446 */ + { 0x0000, 0x0000 }, /* R447 */ + { 0x0000, 0x0000 }, /* R448 */ + { 0x0000, 0x0000 }, /* R449 */ + { 0x0000, 0x0000 }, /* R450 */ + { 0x0000, 0x0000 }, /* R451 */ + { 0x0000, 0x0000 }, /* R452 */ + { 0x0000, 0x0000 }, /* R453 */ + { 0x0000, 0x0000 }, /* R454 */ + { 0x0000, 0x0000 }, /* R455 */ + { 0x0000, 0x0000 }, /* R456 */ + { 0x0000, 0x0000 }, /* R457 */ + { 0x0000, 0x0000 }, /* R458 */ + { 0x0000, 0x0000 }, /* R459 */ + { 0x0000, 0x0000 }, /* R460 */ + { 0x0000, 0x0000 }, /* R461 */ + { 0x0000, 0x0000 }, /* R462 */ + { 0x0000, 0x0000 }, /* R463 */ + { 0x0000, 0x0000 }, /* R464 */ + { 0x0000, 0x0000 }, /* R465 */ + { 0x0000, 0x0000 }, /* R466 */ + { 0x0000, 0x0000 }, /* R467 */ + { 0x0000, 0x0000 }, /* R468 */ + { 0x0000, 0x0000 }, /* R469 */ + { 0x0000, 0x0000 }, /* R470 */ + { 0x0000, 0x0000 }, /* R471 */ + { 0x0000, 0x0000 }, /* R472 */ + { 0x0000, 0x0000 }, /* R473 */ + { 0x0000, 0x0000 }, /* R474 */ + { 0x0000, 0x0000 }, /* R475 */ + { 0x0000, 0x0000 }, /* R476 */ + { 0x0000, 0x0000 }, /* R477 */ + { 0x0000, 0x0000 }, /* R478 */ + { 0x0000, 0x0000 }, /* R479 */ + { 0x0000, 0x0000 }, /* R480 */ + { 0x0000, 0x0000 }, /* R481 */ + { 0x0000, 0x0000 }, /* R482 */ + { 0x0000, 0x0000 }, /* R483 */ + { 0x0000, 0x0000 }, /* R484 */ + { 0x0000, 0x0000 }, /* R485 */ + { 0x0000, 0x0000 }, /* R486 */ + { 0x0000, 0x0000 }, /* R487 */ + { 0x0000, 0x0000 }, /* R488 */ + { 0x0000, 0x0000 }, /* R489 */ + { 0x0000, 0x0000 }, /* R490 */ + { 0x0000, 0x0000 }, /* R491 */ + { 0x0000, 0x0000 }, /* R492 */ + { 0x0000, 0x0000 }, /* R493 */ + { 0x0000, 0x0000 }, /* R494 */ + { 0x0000, 0x0000 }, /* R495 */ + { 0x0000, 0x0000 }, /* R496 */ + { 0x0000, 0x0000 }, /* R497 */ + { 0x0000, 0x0000 }, /* R498 */ + { 0x0000, 0x0000 }, /* R499 */ + { 0x0000, 0x0000 }, /* R500 */ + { 0x0000, 0x0000 }, /* R501 */ + { 0x0000, 0x0000 }, /* R502 */ + { 0x0000, 0x0000 }, /* R503 */ + { 0x0000, 0x0000 }, /* R504 */ + { 0x0000, 0x0000 }, /* R505 */ + { 0x0000, 0x0000 }, /* R506 */ + { 0x0000, 0x0000 }, /* R507 */ + { 0x0000, 0x0000 }, /* R508 */ + { 0x0000, 0x0000 }, /* R509 */ + { 0x0000, 0x0000 }, /* R510 */ + { 0x0000, 0x0000 }, /* R511 */ + { 0x001F, 0x001F }, /* R512 - AIF1 Clocking (1) */ + { 0x003F, 0x003F }, /* R513 - AIF1 Clocking (2) */ + { 0x0000, 0x0000 }, /* R514 */ + { 0x0000, 0x0000 }, /* R515 */ + { 0x001F, 0x001F }, /* R516 - AIF2 Clocking (1) */ + { 0x003F, 0x003F }, /* R517 - AIF2 Clocking (2) */ + { 0x0000, 0x0000 }, /* R518 */ + { 0x0000, 0x0000 }, /* R519 */ + { 0x001F, 0x001F }, /* R520 - Clocking (1) */ + { 0x0777, 0x0777 }, /* R521 - Clocking (2) */ + { 0x0000, 0x0000 }, /* R522 */ + { 0x0000, 0x0000 }, /* R523 */ + { 0x0000, 0x0000 }, /* R524 */ + { 0x0000, 0x0000 }, /* R525 */ + { 0x0000, 0x0000 }, /* R526 */ + { 0x0000, 0x0000 }, /* R527 */ + { 0x00FF, 0x00FF }, /* R528 - AIF1 Rate */ + { 0x00FF, 0x00FF }, /* R529 - AIF2 Rate */ + { 0x000F, 0x0000 }, /* R530 - Rate Status */ + { 0x0000, 0x0000 }, /* R531 */ + { 0x0000, 0x0000 }, /* R532 */ + { 0x0000, 0x0000 }, /* R533 */ + { 0x0000, 0x0000 }, /* R534 */ + { 0x0000, 0x0000 }, /* R535 */ + { 0x0000, 0x0000 }, /* R536 */ + { 0x0000, 0x0000 }, /* R537 */ + { 0x0000, 0x0000 }, /* R538 */ + { 0x0000, 0x0000 }, /* R539 */ + { 0x0000, 0x0000 }, /* R540 */ + { 0x0000, 0x0000 }, /* R541 */ + { 0x0000, 0x0000 }, /* R542 */ + { 0x0000, 0x0000 }, /* R543 */ + { 0x0007, 0x0007 }, /* R544 - FLL1 Control (1) */ + { 0x3F77, 0x3F77 }, /* R545 - FLL1 Control (2) */ + { 0xFFFF, 0xFFFF }, /* R546 - FLL1 Control (3) */ + { 0x7FEF, 0x7FEF }, /* R547 - FLL1 Control (4) */ + { 0x1FDB, 0x1FDB }, /* R548 - FLL1 Control (5) */ + { 0x0000, 0x0000 }, /* R549 */ + { 0x0000, 0x0000 }, /* R550 */ + { 0x0000, 0x0000 }, /* R551 */ + { 0x0000, 0x0000 }, /* R552 */ + { 0x0000, 0x0000 }, /* R553 */ + { 0x0000, 0x0000 }, /* R554 */ + { 0x0000, 0x0000 }, /* R555 */ + { 0x0000, 0x0000 }, /* R556 */ + { 0x0000, 0x0000 }, /* R557 */ + { 0x0000, 0x0000 }, /* R558 */ + { 0x0000, 0x0000 }, /* R559 */ + { 0x0000, 0x0000 }, /* R560 */ + { 0x0000, 0x0000 }, /* R561 */ + { 0x0000, 0x0000 }, /* R562 */ + { 0x0000, 0x0000 }, /* R563 */ + { 0x0000, 0x0000 }, /* R564 */ + { 0x0000, 0x0000 }, /* R565 */ + { 0x0000, 0x0000 }, /* R566 */ + { 0x0000, 0x0000 }, /* R567 */ + { 0x0000, 0x0000 }, /* R568 */ + { 0x0000, 0x0000 }, /* R569 */ + { 0x0000, 0x0000 }, /* R570 */ + { 0x0000, 0x0000 }, /* R571 */ + { 0x0000, 0x0000 }, /* R572 */ + { 0x0000, 0x0000 }, /* R573 */ + { 0x0000, 0x0000 }, /* R574 */ + { 0x0000, 0x0000 }, /* R575 */ + { 0x0007, 0x0007 }, /* R576 - FLL2 Control (1) */ + { 0x3F77, 0x3F77 }, /* R577 - FLL2 Control (2) */ + { 0xFFFF, 0xFFFF }, /* R578 - FLL2 Control (3) */ + { 0x7FEF, 0x7FEF }, /* R579 - FLL2 Control (4) */ + { 0x1FDB, 0x1FDB }, /* R580 - FLL2 Control (5) */ + { 0x0000, 0x0000 }, /* R581 */ + { 0x0000, 0x0000 }, /* R582 */ + { 0x0000, 0x0000 }, /* R583 */ + { 0x0000, 0x0000 }, /* R584 */ + { 0x0000, 0x0000 }, /* R585 */ + { 0x0000, 0x0000 }, /* R586 */ + { 0x0000, 0x0000 }, /* R587 */ + { 0x0000, 0x0000 }, /* R588 */ + { 0x0000, 0x0000 }, /* R589 */ + { 0x0000, 0x0000 }, /* R590 */ + { 0x0000, 0x0000 }, /* R591 */ + { 0x0000, 0x0000 }, /* R592 */ + { 0x0000, 0x0000 }, /* R593 */ + { 0x0000, 0x0000 }, /* R594 */ + { 0x0000, 0x0000 }, /* R595 */ + { 0x0000, 0x0000 }, /* R596 */ + { 0x0000, 0x0000 }, /* R597 */ + { 0x0000, 0x0000 }, /* R598 */ + { 0x0000, 0x0000 }, /* R599 */ + { 0x0000, 0x0000 }, /* R600 */ + { 0x0000, 0x0000 }, /* R601 */ + { 0x0000, 0x0000 }, /* R602 */ + { 0x0000, 0x0000 }, /* R603 */ + { 0x0000, 0x0000 }, /* R604 */ + { 0x0000, 0x0000 }, /* R605 */ + { 0x0000, 0x0000 }, /* R606 */ + { 0x0000, 0x0000 }, /* R607 */ + { 0x0000, 0x0000 }, /* R608 */ + { 0x0000, 0x0000 }, /* R609 */ + { 0x0000, 0x0000 }, /* R610 */ + { 0x0000, 0x0000 }, /* R611 */ + { 0x0000, 0x0000 }, /* R612 */ + { 0x0000, 0x0000 }, /* R613 */ + { 0x0000, 0x0000 }, /* R614 */ + { 0x0000, 0x0000 }, /* R615 */ + { 0x0000, 0x0000 }, /* R616 */ + { 0x0000, 0x0000 }, /* R617 */ + { 0x0000, 0x0000 }, /* R618 */ + { 0x0000, 0x0000 }, /* R619 */ + { 0x0000, 0x0000 }, /* R620 */ + { 0x0000, 0x0000 }, /* R621 */ + { 0x0000, 0x0000 }, /* R622 */ + { 0x0000, 0x0000 }, /* R623 */ + { 0x0000, 0x0000 }, /* R624 */ + { 0x0000, 0x0000 }, /* R625 */ + { 0x0000, 0x0000 }, /* R626 */ + { 0x0000, 0x0000 }, /* R627 */ + { 0x0000, 0x0000 }, /* R628 */ + { 0x0000, 0x0000 }, /* R629 */ + { 0x0000, 0x0000 }, /* R630 */ + { 0x0000, 0x0000 }, /* R631 */ + { 0x0000, 0x0000 }, /* R632 */ + { 0x0000, 0x0000 }, /* R633 */ + { 0x0000, 0x0000 }, /* R634 */ + { 0x0000, 0x0000 }, /* R635 */ + { 0x0000, 0x0000 }, /* R636 */ + { 0x0000, 0x0000 }, /* R637 */ + { 0x0000, 0x0000 }, /* R638 */ + { 0x0000, 0x0000 }, /* R639 */ + { 0x0000, 0x0000 }, /* R640 */ + { 0x0000, 0x0000 }, /* R641 */ + { 0x0000, 0x0000 }, /* R642 */ + { 0x0000, 0x0000 }, /* R643 */ + { 0x0000, 0x0000 }, /* R644 */ + { 0x0000, 0x0000 }, /* R645 */ + { 0x0000, 0x0000 }, /* R646 */ + { 0x0000, 0x0000 }, /* R647 */ + { 0x0000, 0x0000 }, /* R648 */ + { 0x0000, 0x0000 }, /* R649 */ + { 0x0000, 0x0000 }, /* R650 */ + { 0x0000, 0x0000 }, /* R651 */ + { 0x0000, 0x0000 }, /* R652 */ + { 0x0000, 0x0000 }, /* R653 */ + { 0x0000, 0x0000 }, /* R654 */ + { 0x0000, 0x0000 }, /* R655 */ + { 0x0000, 0x0000 }, /* R656 */ + { 0x0000, 0x0000 }, /* R657 */ + { 0x0000, 0x0000 }, /* R658 */ + { 0x0000, 0x0000 }, /* R659 */ + { 0x0000, 0x0000 }, /* R660 */ + { 0x0000, 0x0000 }, /* R661 */ + { 0x0000, 0x0000 }, /* R662 */ + { 0x0000, 0x0000 }, /* R663 */ + { 0x0000, 0x0000 }, /* R664 */ + { 0x0000, 0x0000 }, /* R665 */ + { 0x0000, 0x0000 }, /* R666 */ + { 0x0000, 0x0000 }, /* R667 */ + { 0x0000, 0x0000 }, /* R668 */ + { 0x0000, 0x0000 }, /* R669 */ + { 0x0000, 0x0000 }, /* R670 */ + { 0x0000, 0x0000 }, /* R671 */ + { 0x0000, 0x0000 }, /* R672 */ + { 0x0000, 0x0000 }, /* R673 */ + { 0x0000, 0x0000 }, /* R674 */ + { 0x0000, 0x0000 }, /* R675 */ + { 0x0000, 0x0000 }, /* R676 */ + { 0x0000, 0x0000 }, /* R677 */ + { 0x0000, 0x0000 }, /* R678 */ + { 0x0000, 0x0000 }, /* R679 */ + { 0x0000, 0x0000 }, /* R680 */ + { 0x0000, 0x0000 }, /* R681 */ + { 0x0000, 0x0000 }, /* R682 */ + { 0x0000, 0x0000 }, /* R683 */ + { 0x0000, 0x0000 }, /* R684 */ + { 0x0000, 0x0000 }, /* R685 */ + { 0x0000, 0x0000 }, /* R686 */ + { 0x0000, 0x0000 }, /* R687 */ + { 0x0000, 0x0000 }, /* R688 */ + { 0x0000, 0x0000 }, /* R689 */ + { 0x0000, 0x0000 }, /* R690 */ + { 0x0000, 0x0000 }, /* R691 */ + { 0x0000, 0x0000 }, /* R692 */ + { 0x0000, 0x0000 }, /* R693 */ + { 0x0000, 0x0000 }, /* R694 */ + { 0x0000, 0x0000 }, /* R695 */ + { 0x0000, 0x0000 }, /* R696 */ + { 0x0000, 0x0000 }, /* R697 */ + { 0x0000, 0x0000 }, /* R698 */ + { 0x0000, 0x0000 }, /* R699 */ + { 0x0000, 0x0000 }, /* R700 */ + { 0x0000, 0x0000 }, /* R701 */ + { 0x0000, 0x0000 }, /* R702 */ + { 0x0000, 0x0000 }, /* R703 */ + { 0x0000, 0x0000 }, /* R704 */ + { 0x0000, 0x0000 }, /* R705 */ + { 0x0000, 0x0000 }, /* R706 */ + { 0x0000, 0x0000 }, /* R707 */ + { 0x0000, 0x0000 }, /* R708 */ + { 0x0000, 0x0000 }, /* R709 */ + { 0x0000, 0x0000 }, /* R710 */ + { 0x0000, 0x0000 }, /* R711 */ + { 0x0000, 0x0000 }, /* R712 */ + { 0x0000, 0x0000 }, /* R713 */ + { 0x0000, 0x0000 }, /* R714 */ + { 0x0000, 0x0000 }, /* R715 */ + { 0x0000, 0x0000 }, /* R716 */ + { 0x0000, 0x0000 }, /* R717 */ + { 0x0000, 0x0000 }, /* R718 */ + { 0x0000, 0x0000 }, /* R719 */ + { 0x0000, 0x0000 }, /* R720 */ + { 0x0000, 0x0000 }, /* R721 */ + { 0x0000, 0x0000 }, /* R722 */ + { 0x0000, 0x0000 }, /* R723 */ + { 0x0000, 0x0000 }, /* R724 */ + { 0x0000, 0x0000 }, /* R725 */ + { 0x0000, 0x0000 }, /* R726 */ + { 0x0000, 0x0000 }, /* R727 */ + { 0x0000, 0x0000 }, /* R728 */ + { 0x0000, 0x0000 }, /* R729 */ + { 0x0000, 0x0000 }, /* R730 */ + { 0x0000, 0x0000 }, /* R731 */ + { 0x0000, 0x0000 }, /* R732 */ + { 0x0000, 0x0000 }, /* R733 */ + { 0x0000, 0x0000 }, /* R734 */ + { 0x0000, 0x0000 }, /* R735 */ + { 0x0000, 0x0000 }, /* R736 */ + { 0x0000, 0x0000 }, /* R737 */ + { 0x0000, 0x0000 }, /* R738 */ + { 0x0000, 0x0000 }, /* R739 */ + { 0x0000, 0x0000 }, /* R740 */ + { 0x0000, 0x0000 }, /* R741 */ + { 0x0000, 0x0000 }, /* R742 */ + { 0x0000, 0x0000 }, /* R743 */ + { 0x0000, 0x0000 }, /* R744 */ + { 0x0000, 0x0000 }, /* R745 */ + { 0x0000, 0x0000 }, /* R746 */ + { 0x0000, 0x0000 }, /* R747 */ + { 0x0000, 0x0000 }, /* R748 */ + { 0x0000, 0x0000 }, /* R749 */ + { 0x0000, 0x0000 }, /* R750 */ + { 0x0000, 0x0000 }, /* R751 */ + { 0x0000, 0x0000 }, /* R752 */ + { 0x0000, 0x0000 }, /* R753 */ + { 0x0000, 0x0000 }, /* R754 */ + { 0x0000, 0x0000 }, /* R755 */ + { 0x0000, 0x0000 }, /* R756 */ + { 0x0000, 0x0000 }, /* R757 */ + { 0x0000, 0x0000 }, /* R758 */ + { 0x0000, 0x0000 }, /* R759 */ + { 0x0000, 0x0000 }, /* R760 */ + { 0x0000, 0x0000 }, /* R761 */ + { 0x0000, 0x0000 }, /* R762 */ + { 0x0000, 0x0000 }, /* R763 */ + { 0x0000, 0x0000 }, /* R764 */ + { 0x0000, 0x0000 }, /* R765 */ + { 0x0000, 0x0000 }, /* R766 */ + { 0x0000, 0x0000 }, /* R767 */ + { 0xE1F8, 0xE1F8 }, /* R768 - AIF1 Control (1) */ + { 0xCD1F, 0xCD1F }, /* R769 - AIF1 Control (2) */ + { 0xF000, 0xF000 }, /* R770 - AIF1 Master/Slave */ + { 0x01F0, 0x01F0 }, /* R771 - AIF1 BCLK */ + { 0x0FFF, 0x0FFF }, /* R772 - AIF1ADC LRCLK */ + { 0x0FFF, 0x0FFF }, /* R773 - AIF1DAC LRCLK */ + { 0x0003, 0x0003 }, /* R774 - AIF1DAC Data */ + { 0x0003, 0x0003 }, /* R775 - AIF1ADC Data */ + { 0x0000, 0x0000 }, /* R776 */ + { 0x0000, 0x0000 }, /* R777 */ + { 0x0000, 0x0000 }, /* R778 */ + { 0x0000, 0x0000 }, /* R779 */ + { 0x0000, 0x0000 }, /* R780 */ + { 0x0000, 0x0000 }, /* R781 */ + { 0x0000, 0x0000 }, /* R782 */ + { 0x0000, 0x0000 }, /* R783 */ + { 0xF1F8, 0xF1F8 }, /* R784 - AIF2 Control (1) */ + { 0xFD1F, 0xFD1F }, /* R785 - AIF2 Control (2) */ + { 0xF000, 0xF000 }, /* R786 - AIF2 Master/Slave */ + { 0x01F0, 0x01F0 }, /* R787 - AIF2 BCLK */ + { 0x0FFF, 0x0FFF }, /* R788 - AIF2ADC LRCLK */ + { 0x0FFF, 0x0FFF }, /* R789 - AIF2DAC LRCLK */ + { 0x0003, 0x0003 }, /* R790 - AIF2DAC Data */ + { 0x0003, 0x0003 }, /* R791 - AIF2ADC Data */ + { 0x0000, 0x0000 }, /* R792 */ + { 0x0000, 0x0000 }, /* R793 */ + { 0x0000, 0x0000 }, /* R794 */ + { 0x0000, 0x0000 }, /* R795 */ + { 0x0000, 0x0000 }, /* R796 */ + { 0x0000, 0x0000 }, /* R797 */ + { 0x0000, 0x0000 }, /* R798 */ + { 0x0000, 0x0000 }, /* R799 */ + { 0x0000, 0x0000 }, /* R800 */ + { 0x0000, 0x0000 }, /* R801 */ + { 0x0000, 0x0000 }, /* R802 */ + { 0x0000, 0x0000 }, /* R803 */ + { 0x0000, 0x0000 }, /* R804 */ + { 0x0000, 0x0000 }, /* R805 */ + { 0x0000, 0x0000 }, /* R806 */ + { 0x0000, 0x0000 }, /* R807 */ + { 0x0000, 0x0000 }, /* R808 */ + { 0x0000, 0x0000 }, /* R809 */ + { 0x0000, 0x0000 }, /* R810 */ + { 0x0000, 0x0000 }, /* R811 */ + { 0x0000, 0x0000 }, /* R812 */ + { 0x0000, 0x0000 }, /* R813 */ + { 0x0000, 0x0000 }, /* R814 */ + { 0x0000, 0x0000 }, /* R815 */ + { 0x0000, 0x0000 }, /* R816 */ + { 0x0000, 0x0000 }, /* R817 */ + { 0x0000, 0x0000 }, /* R818 */ + { 0x0000, 0x0000 }, /* R819 */ + { 0x0000, 0x0000 }, /* R820 */ + { 0x0000, 0x0000 }, /* R821 */ + { 0x0000, 0x0000 }, /* R822 */ + { 0x0000, 0x0000 }, /* R823 */ + { 0x0000, 0x0000 }, /* R824 */ + { 0x0000, 0x0000 }, /* R825 */ + { 0x0000, 0x0000 }, /* R826 */ + { 0x0000, 0x0000 }, /* R827 */ + { 0x0000, 0x0000 }, /* R828 */ + { 0x0000, 0x0000 }, /* R829 */ + { 0x0000, 0x0000 }, /* R830 */ + { 0x0000, 0x0000 }, /* R831 */ + { 0x0000, 0x0000 }, /* R832 */ + { 0x0000, 0x0000 }, /* R833 */ + { 0x0000, 0x0000 }, /* R834 */ + { 0x0000, 0x0000 }, /* R835 */ + { 0x0000, 0x0000 }, /* R836 */ + { 0x0000, 0x0000 }, /* R837 */ + { 0x0000, 0x0000 }, /* R838 */ + { 0x0000, 0x0000 }, /* R839 */ + { 0x0000, 0x0000 }, /* R840 */ + { 0x0000, 0x0000 }, /* R841 */ + { 0x0000, 0x0000 }, /* R842 */ + { 0x0000, 0x0000 }, /* R843 */ + { 0x0000, 0x0000 }, /* R844 */ + { 0x0000, 0x0000 }, /* R845 */ + { 0x0000, 0x0000 }, /* R846 */ + { 0x0000, 0x0000 }, /* R847 */ + { 0x0000, 0x0000 }, /* R848 */ + { 0x0000, 0x0000 }, /* R849 */ + { 0x0000, 0x0000 }, /* R850 */ + { 0x0000, 0x0000 }, /* R851 */ + { 0x0000, 0x0000 }, /* R852 */ + { 0x0000, 0x0000 }, /* R853 */ + { 0x0000, 0x0000 }, /* R854 */ + { 0x0000, 0x0000 }, /* R855 */ + { 0x0000, 0x0000 }, /* R856 */ + { 0x0000, 0x0000 }, /* R857 */ + { 0x0000, 0x0000 }, /* R858 */ + { 0x0000, 0x0000 }, /* R859 */ + { 0x0000, 0x0000 }, /* R860 */ + { 0x0000, 0x0000 }, /* R861 */ + { 0x0000, 0x0000 }, /* R862 */ + { 0x0000, 0x0000 }, /* R863 */ + { 0x0000, 0x0000 }, /* R864 */ + { 0x0000, 0x0000 }, /* R865 */ + { 0x0000, 0x0000 }, /* R866 */ + { 0x0000, 0x0000 }, /* R867 */ + { 0x0000, 0x0000 }, /* R868 */ + { 0x0000, 0x0000 }, /* R869 */ + { 0x0000, 0x0000 }, /* R870 */ + { 0x0000, 0x0000 }, /* R871 */ + { 0x0000, 0x0000 }, /* R872 */ + { 0x0000, 0x0000 }, /* R873 */ + { 0x0000, 0x0000 }, /* R874 */ + { 0x0000, 0x0000 }, /* R875 */ + { 0x0000, 0x0000 }, /* R876 */ + { 0x0000, 0x0000 }, /* R877 */ + { 0x0000, 0x0000 }, /* R878 */ + { 0x0000, 0x0000 }, /* R879 */ + { 0x0000, 0x0000 }, /* R880 */ + { 0x0000, 0x0000 }, /* R881 */ + { 0x0000, 0x0000 }, /* R882 */ + { 0x0000, 0x0000 }, /* R883 */ + { 0x0000, 0x0000 }, /* R884 */ + { 0x0000, 0x0000 }, /* R885 */ + { 0x0000, 0x0000 }, /* R886 */ + { 0x0000, 0x0000 }, /* R887 */ + { 0x0000, 0x0000 }, /* R888 */ + { 0x0000, 0x0000 }, /* R889 */ + { 0x0000, 0x0000 }, /* R890 */ + { 0x0000, 0x0000 }, /* R891 */ + { 0x0000, 0x0000 }, /* R892 */ + { 0x0000, 0x0000 }, /* R893 */ + { 0x0000, 0x0000 }, /* R894 */ + { 0x0000, 0x0000 }, /* R895 */ + { 0x0000, 0x0000 }, /* R896 */ + { 0x0000, 0x0000 }, /* R897 */ + { 0x0000, 0x0000 }, /* R898 */ + { 0x0000, 0x0000 }, /* R899 */ + { 0x0000, 0x0000 }, /* R900 */ + { 0x0000, 0x0000 }, /* R901 */ + { 0x0000, 0x0000 }, /* R902 */ + { 0x0000, 0x0000 }, /* R903 */ + { 0x0000, 0x0000 }, /* R904 */ + { 0x0000, 0x0000 }, /* R905 */ + { 0x0000, 0x0000 }, /* R906 */ + { 0x0000, 0x0000 }, /* R907 */ + { 0x0000, 0x0000 }, /* R908 */ + { 0x0000, 0x0000 }, /* R909 */ + { 0x0000, 0x0000 }, /* R910 */ + { 0x0000, 0x0000 }, /* R911 */ + { 0x0000, 0x0000 }, /* R912 */ + { 0x0000, 0x0000 }, /* R913 */ + { 0x0000, 0x0000 }, /* R914 */ + { 0x0000, 0x0000 }, /* R915 */ + { 0x0000, 0x0000 }, /* R916 */ + { 0x0000, 0x0000 }, /* R917 */ + { 0x0000, 0x0000 }, /* R918 */ + { 0x0000, 0x0000 }, /* R919 */ + { 0x0000, 0x0000 }, /* R920 */ + { 0x0000, 0x0000 }, /* R921 */ + { 0x0000, 0x0000 }, /* R922 */ + { 0x0000, 0x0000 }, /* R923 */ + { 0x0000, 0x0000 }, /* R924 */ + { 0x0000, 0x0000 }, /* R925 */ + { 0x0000, 0x0000 }, /* R926 */ + { 0x0000, 0x0000 }, /* R927 */ + { 0x0000, 0x0000 }, /* R928 */ + { 0x0000, 0x0000 }, /* R929 */ + { 0x0000, 0x0000 }, /* R930 */ + { 0x0000, 0x0000 }, /* R931 */ + { 0x0000, 0x0000 }, /* R932 */ + { 0x0000, 0x0000 }, /* R933 */ + { 0x0000, 0x0000 }, /* R934 */ + { 0x0000, 0x0000 }, /* R935 */ + { 0x0000, 0x0000 }, /* R936 */ + { 0x0000, 0x0000 }, /* R937 */ + { 0x0000, 0x0000 }, /* R938 */ + { 0x0000, 0x0000 }, /* R939 */ + { 0x0000, 0x0000 }, /* R940 */ + { 0x0000, 0x0000 }, /* R941 */ + { 0x0000, 0x0000 }, /* R942 */ + { 0x0000, 0x0000 }, /* R943 */ + { 0x0000, 0x0000 }, /* R944 */ + { 0x0000, 0x0000 }, /* R945 */ + { 0x0000, 0x0000 }, /* R946 */ + { 0x0000, 0x0000 }, /* R947 */ + { 0x0000, 0x0000 }, /* R948 */ + { 0x0000, 0x0000 }, /* R949 */ + { 0x0000, 0x0000 }, /* R950 */ + { 0x0000, 0x0000 }, /* R951 */ + { 0x0000, 0x0000 }, /* R952 */ + { 0x0000, 0x0000 }, /* R953 */ + { 0x0000, 0x0000 }, /* R954 */ + { 0x0000, 0x0000 }, /* R955 */ + { 0x0000, 0x0000 }, /* R956 */ + { 0x0000, 0x0000 }, /* R957 */ + { 0x0000, 0x0000 }, /* R958 */ + { 0x0000, 0x0000 }, /* R959 */ + { 0x0000, 0x0000 }, /* R960 */ + { 0x0000, 0x0000 }, /* R961 */ + { 0x0000, 0x0000 }, /* R962 */ + { 0x0000, 0x0000 }, /* R963 */ + { 0x0000, 0x0000 }, /* R964 */ + { 0x0000, 0x0000 }, /* R965 */ + { 0x0000, 0x0000 }, /* R966 */ + { 0x0000, 0x0000 }, /* R967 */ + { 0x0000, 0x0000 }, /* R968 */ + { 0x0000, 0x0000 }, /* R969 */ + { 0x0000, 0x0000 }, /* R970 */ + { 0x0000, 0x0000 }, /* R971 */ + { 0x0000, 0x0000 }, /* R972 */ + { 0x0000, 0x0000 }, /* R973 */ + { 0x0000, 0x0000 }, /* R974 */ + { 0x0000, 0x0000 }, /* R975 */ + { 0x0000, 0x0000 }, /* R976 */ + { 0x0000, 0x0000 }, /* R977 */ + { 0x0000, 0x0000 }, /* R978 */ + { 0x0000, 0x0000 }, /* R979 */ + { 0x0000, 0x0000 }, /* R980 */ + { 0x0000, 0x0000 }, /* R981 */ + { 0x0000, 0x0000 }, /* R982 */ + { 0x0000, 0x0000 }, /* R983 */ + { 0x0000, 0x0000 }, /* R984 */ + { 0x0000, 0x0000 }, /* R985 */ + { 0x0000, 0x0000 }, /* R986 */ + { 0x0000, 0x0000 }, /* R987 */ + { 0x0000, 0x0000 }, /* R988 */ + { 0x0000, 0x0000 }, /* R989 */ + { 0x0000, 0x0000 }, /* R990 */ + { 0x0000, 0x0000 }, /* R991 */ + { 0x0000, 0x0000 }, /* R992 */ + { 0x0000, 0x0000 }, /* R993 */ + { 0x0000, 0x0000 }, /* R994 */ + { 0x0000, 0x0000 }, /* R995 */ + { 0x0000, 0x0000 }, /* R996 */ + { 0x0000, 0x0000 }, /* R997 */ + { 0x0000, 0x0000 }, /* R998 */ + { 0x0000, 0x0000 }, /* R999 */ + { 0x0000, 0x0000 }, /* R1000 */ + { 0x0000, 0x0000 }, /* R1001 */ + { 0x0000, 0x0000 }, /* R1002 */ + { 0x0000, 0x0000 }, /* R1003 */ + { 0x0000, 0x0000 }, /* R1004 */ + { 0x0000, 0x0000 }, /* R1005 */ + { 0x0000, 0x0000 }, /* R1006 */ + { 0x0000, 0x0000 }, /* R1007 */ + { 0x0000, 0x0000 }, /* R1008 */ + { 0x0000, 0x0000 }, /* R1009 */ + { 0x0000, 0x0000 }, /* R1010 */ + { 0x0000, 0x0000 }, /* R1011 */ + { 0x0000, 0x0000 }, /* R1012 */ + { 0x0000, 0x0000 }, /* R1013 */ + { 0x0000, 0x0000 }, /* R1014 */ + { 0x0000, 0x0000 }, /* R1015 */ + { 0x0000, 0x0000 }, /* R1016 */ + { 0x0000, 0x0000 }, /* R1017 */ + { 0x0000, 0x0000 }, /* R1018 */ + { 0x0000, 0x0000 }, /* R1019 */ + { 0x0000, 0x0000 }, /* R1020 */ + { 0x0000, 0x0000 }, /* R1021 */ + { 0x0000, 0x0000 }, /* R1022 */ + { 0x0000, 0x0000 }, /* R1023 */ + { 0x00FF, 0x01FF }, /* R1024 - AIF1 ADC1 Left Volume */ + { 0x00FF, 0x01FF }, /* R1025 - AIF1 ADC1 Right Volume */ + { 0x00FF, 0x01FF }, /* R1026 - AIF1 DAC1 Left Volume */ + { 0x00FF, 0x01FF }, /* R1027 - AIF1 DAC1 Right Volume */ + { 0x00FF, 0x01FF }, /* R1028 - AIF1 ADC2 Left Volume */ + { 0x00FF, 0x01FF }, /* R1029 - AIF1 ADC2 Right Volume */ + { 0x00FF, 0x01FF }, /* R1030 - AIF1 DAC2 Left Volume */ + { 0x00FF, 0x01FF }, /* R1031 - AIF1 DAC2 Right Volume */ + { 0x0000, 0x0000 }, /* R1032 */ + { 0x0000, 0x0000 }, /* R1033 */ + { 0x0000, 0x0000 }, /* R1034 */ + { 0x0000, 0x0000 }, /* R1035 */ + { 0x0000, 0x0000 }, /* R1036 */ + { 0x0000, 0x0000 }, /* R1037 */ + { 0x0000, 0x0000 }, /* R1038 */ + { 0x0000, 0x0000 }, /* R1039 */ + { 0xF800, 0xF800 }, /* R1040 - AIF1 ADC1 Filters */ + { 0x7800, 0x7800 }, /* R1041 - AIF1 ADC2 Filters */ + { 0x0000, 0x0000 }, /* R1042 */ + { 0x0000, 0x0000 }, /* R1043 */ + { 0x0000, 0x0000 }, /* R1044 */ + { 0x0000, 0x0000 }, /* R1045 */ + { 0x0000, 0x0000 }, /* R1046 */ + { 0x0000, 0x0000 }, /* R1047 */ + { 0x0000, 0x0000 }, /* R1048 */ + { 0x0000, 0x0000 }, /* R1049 */ + { 0x0000, 0x0000 }, /* R1050 */ + { 0x0000, 0x0000 }, /* R1051 */ + { 0x0000, 0x0000 }, /* R1052 */ + { 0x0000, 0x0000 }, /* R1053 */ + { 0x0000, 0x0000 }, /* R1054 */ + { 0x0000, 0x0000 }, /* R1055 */ + { 0x02B6, 0x02B6 }, /* R1056 - AIF1 DAC1 Filters (1) */ + { 0x3F00, 0x3F00 }, /* R1057 - AIF1 DAC1 Filters (2) */ + { 0x02B6, 0x02B6 }, /* R1058 - AIF1 DAC2 Filters (1) */ + { 0x3F00, 0x3F00 }, /* R1059 - AIF1 DAC2 Filters (2) */ + { 0x0000, 0x0000 }, /* R1060 */ + { 0x0000, 0x0000 }, /* R1061 */ + { 0x0000, 0x0000 }, /* R1062 */ + { 0x0000, 0x0000 }, /* R1063 */ + { 0x0000, 0x0000 }, /* R1064 */ + { 0x0000, 0x0000 }, /* R1065 */ + { 0x0000, 0x0000 }, /* R1066 */ + { 0x0000, 0x0000 }, /* R1067 */ + { 0x0000, 0x0000 }, /* R1068 */ + { 0x0000, 0x0000 }, /* R1069 */ + { 0x0000, 0x0000 }, /* R1070 */ + { 0x0000, 0x0000 }, /* R1071 */ + { 0x0000, 0x0000 }, /* R1072 */ + { 0x0000, 0x0000 }, /* R1073 */ + { 0x0000, 0x0000 }, /* R1074 */ + { 0x0000, 0x0000 }, /* R1075 */ + { 0x0000, 0x0000 }, /* R1076 */ + { 0x0000, 0x0000 }, /* R1077 */ + { 0x0000, 0x0000 }, /* R1078 */ + { 0x0000, 0x0000 }, /* R1079 */ + { 0x0000, 0x0000 }, /* R1080 */ + { 0x0000, 0x0000 }, /* R1081 */ + { 0x0000, 0x0000 }, /* R1082 */ + { 0x0000, 0x0000 }, /* R1083 */ + { 0x0000, 0x0000 }, /* R1084 */ + { 0x0000, 0x0000 }, /* R1085 */ + { 0x0000, 0x0000 }, /* R1086 */ + { 0x0000, 0x0000 }, /* R1087 */ + { 0xFFFF, 0xFFFF }, /* R1088 - AIF1 DRC1 (1) */ + { 0x1FFF, 0x1FFF }, /* R1089 - AIF1 DRC1 (2) */ + { 0xFFFF, 0xFFFF }, /* R1090 - AIF1 DRC1 (3) */ + { 0x07FF, 0x07FF }, /* R1091 - AIF1 DRC1 (4) */ + { 0x03FF, 0x03FF }, /* R1092 - AIF1 DRC1 (5) */ + { 0x0000, 0x0000 }, /* R1093 */ + { 0x0000, 0x0000 }, /* R1094 */ + { 0x0000, 0x0000 }, /* R1095 */ + { 0x0000, 0x0000 }, /* R1096 */ + { 0x0000, 0x0000 }, /* R1097 */ + { 0x0000, 0x0000 }, /* R1098 */ + { 0x0000, 0x0000 }, /* R1099 */ + { 0x0000, 0x0000 }, /* R1100 */ + { 0x0000, 0x0000 }, /* R1101 */ + { 0x0000, 0x0000 }, /* R1102 */ + { 0x0000, 0x0000 }, /* R1103 */ + { 0xFFFF, 0xFFFF }, /* R1104 - AIF1 DRC2 (1) */ + { 0x1FFF, 0x1FFF }, /* R1105 - AIF1 DRC2 (2) */ + { 0xFFFF, 0xFFFF }, /* R1106 - AIF1 DRC2 (3) */ + { 0x07FF, 0x07FF }, /* R1107 - AIF1 DRC2 (4) */ + { 0x03FF, 0x03FF }, /* R1108 - AIF1 DRC2 (5) */ + { 0x0000, 0x0000 }, /* R1109 */ + { 0x0000, 0x0000 }, /* R1110 */ + { 0x0000, 0x0000 }, /* R1111 */ + { 0x0000, 0x0000 }, /* R1112 */ + { 0x0000, 0x0000 }, /* R1113 */ + { 0x0000, 0x0000 }, /* R1114 */ + { 0x0000, 0x0000 }, /* R1115 */ + { 0x0000, 0x0000 }, /* R1116 */ + { 0x0000, 0x0000 }, /* R1117 */ + { 0x0000, 0x0000 }, /* R1118 */ + { 0x0000, 0x0000 }, /* R1119 */ + { 0x0000, 0x0000 }, /* R1120 */ + { 0x0000, 0x0000 }, /* R1121 */ + { 0x0000, 0x0000 }, /* R1122 */ + { 0x0000, 0x0000 }, /* R1123 */ + { 0x0000, 0x0000 }, /* R1124 */ + { 0x0000, 0x0000 }, /* R1125 */ + { 0x0000, 0x0000 }, /* R1126 */ + { 0x0000, 0x0000 }, /* R1127 */ + { 0x0000, 0x0000 }, /* R1128 */ + { 0x0000, 0x0000 }, /* R1129 */ + { 0x0000, 0x0000 }, /* R1130 */ + { 0x0000, 0x0000 }, /* R1131 */ + { 0x0000, 0x0000 }, /* R1132 */ + { 0x0000, 0x0000 }, /* R1133 */ + { 0x0000, 0x0000 }, /* R1134 */ + { 0x0000, 0x0000 }, /* R1135 */ + { 0x0000, 0x0000 }, /* R1136 */ + { 0x0000, 0x0000 }, /* R1137 */ + { 0x0000, 0x0000 }, /* R1138 */ + { 0x0000, 0x0000 }, /* R1139 */ + { 0x0000, 0x0000 }, /* R1140 */ + { 0x0000, 0x0000 }, /* R1141 */ + { 0x0000, 0x0000 }, /* R1142 */ + { 0x0000, 0x0000 }, /* R1143 */ + { 0x0000, 0x0000 }, /* R1144 */ + { 0x0000, 0x0000 }, /* R1145 */ + { 0x0000, 0x0000 }, /* R1146 */ + { 0x0000, 0x0000 }, /* R1147 */ + { 0x0000, 0x0000 }, /* R1148 */ + { 0x0000, 0x0000 }, /* R1149 */ + { 0x0000, 0x0000 }, /* R1150 */ + { 0x0000, 0x0000 }, /* R1151 */ + { 0xFFFF, 0xFFFF }, /* R1152 - AIF1 DAC1 EQ Gains (1) */ + { 0xFFC0, 0xFFC0 }, /* R1153 - AIF1 DAC1 EQ Gains (2) */ + { 0xFFFF, 0xFFFF }, /* R1154 - AIF1 DAC1 EQ Band 1 A */ + { 0xFFFF, 0xFFFF }, /* R1155 - AIF1 DAC1 EQ Band 1 B */ + { 0xFFFF, 0xFFFF }, /* R1156 - AIF1 DAC1 EQ Band 1 PG */ + { 0xFFFF, 0xFFFF }, /* R1157 - AIF1 DAC1 EQ Band 2 A */ + { 0xFFFF, 0xFFFF }, /* R1158 - AIF1 DAC1 EQ Band 2 B */ + { 0xFFFF, 0xFFFF }, /* R1159 - AIF1 DAC1 EQ Band 2 C */ + { 0xFFFF, 0xFFFF }, /* R1160 - AIF1 DAC1 EQ Band 2 PG */ + { 0xFFFF, 0xFFFF }, /* R1161 - AIF1 DAC1 EQ Band 3 A */ + { 0xFFFF, 0xFFFF }, /* R1162 - AIF1 DAC1 EQ Band 3 B */ + { 0xFFFF, 0xFFFF }, /* R1163 - AIF1 DAC1 EQ Band 3 C */ + { 0xFFFF, 0xFFFF }, /* R1164 - AIF1 DAC1 EQ Band 3 PG */ + { 0xFFFF, 0xFFFF }, /* R1165 - AIF1 DAC1 EQ Band 4 A */ + { 0xFFFF, 0xFFFF }, /* R1166 - AIF1 DAC1 EQ Band 4 B */ + { 0xFFFF, 0xFFFF }, /* R1167 - AIF1 DAC1 EQ Band 4 C */ + { 0xFFFF, 0xFFFF }, /* R1168 - AIF1 DAC1 EQ Band 4 PG */ + { 0xFFFF, 0xFFFF }, /* R1169 - AIF1 DAC1 EQ Band 5 A */ + { 0xFFFF, 0xFFFF }, /* R1170 - AIF1 DAC1 EQ Band 5 B */ + { 0xFFFF, 0xFFFF }, /* R1171 - AIF1 DAC1 EQ Band 5 PG */ + { 0x0000, 0x0000 }, /* R1172 */ + { 0x0000, 0x0000 }, /* R1173 */ + { 0x0000, 0x0000 }, /* R1174 */ + { 0x0000, 0x0000 }, /* R1175 */ + { 0x0000, 0x0000 }, /* R1176 */ + { 0x0000, 0x0000 }, /* R1177 */ + { 0x0000, 0x0000 }, /* R1178 */ + { 0x0000, 0x0000 }, /* R1179 */ + { 0x0000, 0x0000 }, /* R1180 */ + { 0x0000, 0x0000 }, /* R1181 */ + { 0x0000, 0x0000 }, /* R1182 */ + { 0x0000, 0x0000 }, /* R1183 */ + { 0xFFFF, 0xFFFF }, /* R1184 - AIF1 DAC2 EQ Gains (1) */ + { 0xFFC0, 0xFFC0 }, /* R1185 - AIF1 DAC2 EQ Gains (2) */ + { 0xFFFF, 0xFFFF }, /* R1186 - AIF1 DAC2 EQ Band 1 A */ + { 0xFFFF, 0xFFFF }, /* R1187 - AIF1 DAC2 EQ Band 1 B */ + { 0xFFFF, 0xFFFF }, /* R1188 - AIF1 DAC2 EQ Band 1 PG */ + { 0xFFFF, 0xFFFF }, /* R1189 - AIF1 DAC2 EQ Band 2 A */ + { 0xFFFF, 0xFFFF }, /* R1190 - AIF1 DAC2 EQ Band 2 B */ + { 0xFFFF, 0xFFFF }, /* R1191 - AIF1 DAC2 EQ Band 2 C */ + { 0xFFFF, 0xFFFF }, /* R1192 - AIF1 DAC2 EQ Band 2 PG */ + { 0xFFFF, 0xFFFF }, /* R1193 - AIF1 DAC2 EQ Band 3 A */ + { 0xFFFF, 0xFFFF }, /* R1194 - AIF1 DAC2 EQ Band 3 B */ + { 0xFFFF, 0xFFFF }, /* R1195 - AIF1 DAC2 EQ Band 3 C */ + { 0xFFFF, 0xFFFF }, /* R1196 - AIF1 DAC2 EQ Band 3 PG */ + { 0xFFFF, 0xFFFF }, /* R1197 - AIF1 DAC2 EQ Band 4 A */ + { 0xFFFF, 0xFFFF }, /* R1198 - AIF1 DAC2 EQ Band 4 B */ + { 0xFFFF, 0xFFFF }, /* R1199 - AIF1 DAC2 EQ Band 4 C */ + { 0xFFFF, 0xFFFF }, /* R1200 - AIF1 DAC2 EQ Band 4 PG */ + { 0xFFFF, 0xFFFF }, /* R1201 - AIF1 DAC2 EQ Band 5 A */ + { 0xFFFF, 0xFFFF }, /* R1202 - AIF1 DAC2 EQ Band 5 B */ + { 0xFFFF, 0xFFFF }, /* R1203 - AIF1 DAC2 EQ Band 5 PG */ + { 0x0000, 0x0000 }, /* R1204 */ + { 0x0000, 0x0000 }, /* R1205 */ + { 0x0000, 0x0000 }, /* R1206 */ + { 0x0000, 0x0000 }, /* R1207 */ + { 0x0000, 0x0000 }, /* R1208 */ + { 0x0000, 0x0000 }, /* R1209 */ + { 0x0000, 0x0000 }, /* R1210 */ + { 0x0000, 0x0000 }, /* R1211 */ + { 0x0000, 0x0000 }, /* R1212 */ + { 0x0000, 0x0000 }, /* R1213 */ + { 0x0000, 0x0000 }, /* R1214 */ + { 0x0000, 0x0000 }, /* R1215 */ + { 0x0000, 0x0000 }, /* R1216 */ + { 0x0000, 0x0000 }, /* R1217 */ + { 0x0000, 0x0000 }, /* R1218 */ + { 0x0000, 0x0000 }, /* R1219 */ + { 0x0000, 0x0000 }, /* R1220 */ + { 0x0000, 0x0000 }, /* R1221 */ + { 0x0000, 0x0000 }, /* R1222 */ + { 0x0000, 0x0000 }, /* R1223 */ + { 0x0000, 0x0000 }, /* R1224 */ + { 0x0000, 0x0000 }, /* R1225 */ + { 0x0000, 0x0000 }, /* R1226 */ + { 0x0000, 0x0000 }, /* R1227 */ + { 0x0000, 0x0000 }, /* R1228 */ + { 0x0000, 0x0000 }, /* R1229 */ + { 0x0000, 0x0000 }, /* R1230 */ + { 0x0000, 0x0000 }, /* R1231 */ + { 0x0000, 0x0000 }, /* R1232 */ + { 0x0000, 0x0000 }, /* R1233 */ + { 0x0000, 0x0000 }, /* R1234 */ + { 0x0000, 0x0000 }, /* R1235 */ + { 0x0000, 0x0000 }, /* R1236 */ + { 0x0000, 0x0000 }, /* R1237 */ + { 0x0000, 0x0000 }, /* R1238 */ + { 0x0000, 0x0000 }, /* R1239 */ + { 0x0000, 0x0000 }, /* R1240 */ + { 0x0000, 0x0000 }, /* R1241 */ + { 0x0000, 0x0000 }, /* R1242 */ + { 0x0000, 0x0000 }, /* R1243 */ + { 0x0000, 0x0000 }, /* R1244 */ + { 0x0000, 0x0000 }, /* R1245 */ + { 0x0000, 0x0000 }, /* R1246 */ + { 0x0000, 0x0000 }, /* R1247 */ + { 0x0000, 0x0000 }, /* R1248 */ + { 0x0000, 0x0000 }, /* R1249 */ + { 0x0000, 0x0000 }, /* R1250 */ + { 0x0000, 0x0000 }, /* R1251 */ + { 0x0000, 0x0000 }, /* R1252 */ + { 0x0000, 0x0000 }, /* R1253 */ + { 0x0000, 0x0000 }, /* R1254 */ + { 0x0000, 0x0000 }, /* R1255 */ + { 0x0000, 0x0000 }, /* R1256 */ + { 0x0000, 0x0000 }, /* R1257 */ + { 0x0000, 0x0000 }, /* R1258 */ + { 0x0000, 0x0000 }, /* R1259 */ + { 0x0000, 0x0000 }, /* R1260 */ + { 0x0000, 0x0000 }, /* R1261 */ + { 0x0000, 0x0000 }, /* R1262 */ + { 0x0000, 0x0000 }, /* R1263 */ + { 0x0000, 0x0000 }, /* R1264 */ + { 0x0000, 0x0000 }, /* R1265 */ + { 0x0000, 0x0000 }, /* R1266 */ + { 0x0000, 0x0000 }, /* R1267 */ + { 0x0000, 0x0000 }, /* R1268 */ + { 0x0000, 0x0000 }, /* R1269 */ + { 0x0000, 0x0000 }, /* R1270 */ + { 0x0000, 0x0000 }, /* R1271 */ + { 0x0000, 0x0000 }, /* R1272 */ + { 0x0000, 0x0000 }, /* R1273 */ + { 0x0000, 0x0000 }, /* R1274 */ + { 0x0000, 0x0000 }, /* R1275 */ + { 0x0000, 0x0000 }, /* R1276 */ + { 0x0000, 0x0000 }, /* R1277 */ + { 0x0000, 0x0000 }, /* R1278 */ + { 0x0000, 0x0000 }, /* R1279 */ + { 0x00FF, 0x01FF }, /* R1280 - AIF2 ADC Left Volume */ + { 0x00FF, 0x01FF }, /* R1281 - AIF2 ADC Right Volume */ + { 0x00FF, 0x01FF }, /* R1282 - AIF2 DAC Left Volume */ + { 0x00FF, 0x01FF }, /* R1283 - AIF2 DAC Right Volume */ + { 0x0000, 0x0000 }, /* R1284 */ + { 0x0000, 0x0000 }, /* R1285 */ + { 0x0000, 0x0000 }, /* R1286 */ + { 0x0000, 0x0000 }, /* R1287 */ + { 0x0000, 0x0000 }, /* R1288 */ + { 0x0000, 0x0000 }, /* R1289 */ + { 0x0000, 0x0000 }, /* R1290 */ + { 0x0000, 0x0000 }, /* R1291 */ + { 0x0000, 0x0000 }, /* R1292 */ + { 0x0000, 0x0000 }, /* R1293 */ + { 0x0000, 0x0000 }, /* R1294 */ + { 0x0000, 0x0000 }, /* R1295 */ + { 0xF800, 0xF800 }, /* R1296 - AIF2 ADC Filters */ + { 0x0000, 0x0000 }, /* R1297 */ + { 0x0000, 0x0000 }, /* R1298 */ + { 0x0000, 0x0000 }, /* R1299 */ + { 0x0000, 0x0000 }, /* R1300 */ + { 0x0000, 0x0000 }, /* R1301 */ + { 0x0000, 0x0000 }, /* R1302 */ + { 0x0000, 0x0000 }, /* R1303 */ + { 0x0000, 0x0000 }, /* R1304 */ + { 0x0000, 0x0000 }, /* R1305 */ + { 0x0000, 0x0000 }, /* R1306 */ + { 0x0000, 0x0000 }, /* R1307 */ + { 0x0000, 0x0000 }, /* R1308 */ + { 0x0000, 0x0000 }, /* R1309 */ + { 0x0000, 0x0000 }, /* R1310 */ + { 0x0000, 0x0000 }, /* R1311 */ + { 0x02B6, 0x02B6 }, /* R1312 - AIF2 DAC Filters (1) */ + { 0x3F00, 0x3F00 }, /* R1313 - AIF2 DAC Filters (2) */ + { 0x0000, 0x0000 }, /* R1314 */ + { 0x0000, 0x0000 }, /* R1315 */ + { 0x0000, 0x0000 }, /* R1316 */ + { 0x0000, 0x0000 }, /* R1317 */ + { 0x0000, 0x0000 }, /* R1318 */ + { 0x0000, 0x0000 }, /* R1319 */ + { 0x0000, 0x0000 }, /* R1320 */ + { 0x0000, 0x0000 }, /* R1321 */ + { 0x0000, 0x0000 }, /* R1322 */ + { 0x0000, 0x0000 }, /* R1323 */ + { 0x0000, 0x0000 }, /* R1324 */ + { 0x0000, 0x0000 }, /* R1325 */ + { 0x0000, 0x0000 }, /* R1326 */ + { 0x0000, 0x0000 }, /* R1327 */ + { 0x0000, 0x0000 }, /* R1328 */ + { 0x0000, 0x0000 }, /* R1329 */ + { 0x0000, 0x0000 }, /* R1330 */ + { 0x0000, 0x0000 }, /* R1331 */ + { 0x0000, 0x0000 }, /* R1332 */ + { 0x0000, 0x0000 }, /* R1333 */ + { 0x0000, 0x0000 }, /* R1334 */ + { 0x0000, 0x0000 }, /* R1335 */ + { 0x0000, 0x0000 }, /* R1336 */ + { 0x0000, 0x0000 }, /* R1337 */ + { 0x0000, 0x0000 }, /* R1338 */ + { 0x0000, 0x0000 }, /* R1339 */ + { 0x0000, 0x0000 }, /* R1340 */ + { 0x0000, 0x0000 }, /* R1341 */ + { 0x0000, 0x0000 }, /* R1342 */ + { 0x0000, 0x0000 }, /* R1343 */ + { 0xFFFF, 0xFFFF }, /* R1344 - AIF2 DRC (1) */ + { 0x1FFF, 0x1FFF }, /* R1345 - AIF2 DRC (2) */ + { 0xFFFF, 0xFFFF }, /* R1346 - AIF2 DRC (3) */ + { 0x07FF, 0x07FF }, /* R1347 - AIF2 DRC (4) */ + { 0x03FF, 0x03FF }, /* R1348 - AIF2 DRC (5) */ + { 0x0000, 0x0000 }, /* R1349 */ + { 0x0000, 0x0000 }, /* R1350 */ + { 0x0000, 0x0000 }, /* R1351 */ + { 0x0000, 0x0000 }, /* R1352 */ + { 0x0000, 0x0000 }, /* R1353 */ + { 0x0000, 0x0000 }, /* R1354 */ + { 0x0000, 0x0000 }, /* R1355 */ + { 0x0000, 0x0000 }, /* R1356 */ + { 0x0000, 0x0000 }, /* R1357 */ + { 0x0000, 0x0000 }, /* R1358 */ + { 0x0000, 0x0000 }, /* R1359 */ + { 0x0000, 0x0000 }, /* R1360 */ + { 0x0000, 0x0000 }, /* R1361 */ + { 0x0000, 0x0000 }, /* R1362 */ + { 0x0000, 0x0000 }, /* R1363 */ + { 0x0000, 0x0000 }, /* R1364 */ + { 0x0000, 0x0000 }, /* R1365 */ + { 0x0000, 0x0000 }, /* R1366 */ + { 0x0000, 0x0000 }, /* R1367 */ + { 0x0000, 0x0000 }, /* R1368 */ + { 0x0000, 0x0000 }, /* R1369 */ + { 0x0000, 0x0000 }, /* R1370 */ + { 0x0000, 0x0000 }, /* R1371 */ + { 0x0000, 0x0000 }, /* R1372 */ + { 0x0000, 0x0000 }, /* R1373 */ + { 0x0000, 0x0000 }, /* R1374 */ + { 0x0000, 0x0000 }, /* R1375 */ + { 0x0000, 0x0000 }, /* R1376 */ + { 0x0000, 0x0000 }, /* R1377 */ + { 0x0000, 0x0000 }, /* R1378 */ + { 0x0000, 0x0000 }, /* R1379 */ + { 0x0000, 0x0000 }, /* R1380 */ + { 0x0000, 0x0000 }, /* R1381 */ + { 0x0000, 0x0000 }, /* R1382 */ + { 0x0000, 0x0000 }, /* R1383 */ + { 0x0000, 0x0000 }, /* R1384 */ + { 0x0000, 0x0000 }, /* R1385 */ + { 0x0000, 0x0000 }, /* R1386 */ + { 0x0000, 0x0000 }, /* R1387 */ + { 0x0000, 0x0000 }, /* R1388 */ + { 0x0000, 0x0000 }, /* R1389 */ + { 0x0000, 0x0000 }, /* R1390 */ + { 0x0000, 0x0000 }, /* R1391 */ + { 0x0000, 0x0000 }, /* R1392 */ + { 0x0000, 0x0000 }, /* R1393 */ + { 0x0000, 0x0000 }, /* R1394 */ + { 0x0000, 0x0000 }, /* R1395 */ + { 0x0000, 0x0000 }, /* R1396 */ + { 0x0000, 0x0000 }, /* R1397 */ + { 0x0000, 0x0000 }, /* R1398 */ + { 0x0000, 0x0000 }, /* R1399 */ + { 0x0000, 0x0000 }, /* R1400 */ + { 0x0000, 0x0000 }, /* R1401 */ + { 0x0000, 0x0000 }, /* R1402 */ + { 0x0000, 0x0000 }, /* R1403 */ + { 0x0000, 0x0000 }, /* R1404 */ + { 0x0000, 0x0000 }, /* R1405 */ + { 0x0000, 0x0000 }, /* R1406 */ + { 0x0000, 0x0000 }, /* R1407 */ + { 0xFFFF, 0xFFFF }, /* R1408 - AIF2 EQ Gains (1) */ + { 0xFFC0, 0xFFC0 }, /* R1409 - AIF2 EQ Gains (2) */ + { 0xFFFF, 0xFFFF }, /* R1410 - AIF2 EQ Band 1 A */ + { 0xFFFF, 0xFFFF }, /* R1411 - AIF2 EQ Band 1 B */ + { 0xFFFF, 0xFFFF }, /* R1412 - AIF2 EQ Band 1 PG */ + { 0xFFFF, 0xFFFF }, /* R1413 - AIF2 EQ Band 2 A */ + { 0xFFFF, 0xFFFF }, /* R1414 - AIF2 EQ Band 2 B */ + { 0xFFFF, 0xFFFF }, /* R1415 - AIF2 EQ Band 2 C */ + { 0xFFFF, 0xFFFF }, /* R1416 - AIF2 EQ Band 2 PG */ + { 0xFFFF, 0xFFFF }, /* R1417 - AIF2 EQ Band 3 A */ + { 0xFFFF, 0xFFFF }, /* R1418 - AIF2 EQ Band 3 B */ + { 0xFFFF, 0xFFFF }, /* R1419 - AIF2 EQ Band 3 C */ + { 0xFFFF, 0xFFFF }, /* R1420 - AIF2 EQ Band 3 PG */ + { 0xFFFF, 0xFFFF }, /* R1421 - AIF2 EQ Band 4 A */ + { 0xFFFF, 0xFFFF }, /* R1422 - AIF2 EQ Band 4 B */ + { 0xFFFF, 0xFFFF }, /* R1423 - AIF2 EQ Band 4 C */ + { 0xFFFF, 0xFFFF }, /* R1424 - AIF2 EQ Band 4 PG */ + { 0xFFFF, 0xFFFF }, /* R1425 - AIF2 EQ Band 5 A */ + { 0xFFFF, 0xFFFF }, /* R1426 - AIF2 EQ Band 5 B */ + { 0xFFFF, 0xFFFF }, /* R1427 - AIF2 EQ Band 5 PG */ + { 0x0000, 0x0000 }, /* R1428 */ + { 0x0000, 0x0000 }, /* R1429 */ + { 0x0000, 0x0000 }, /* R1430 */ + { 0x0000, 0x0000 }, /* R1431 */ + { 0x0000, 0x0000 }, /* R1432 */ + { 0x0000, 0x0000 }, /* R1433 */ + { 0x0000, 0x0000 }, /* R1434 */ + { 0x0000, 0x0000 }, /* R1435 */ + { 0x0000, 0x0000 }, /* R1436 */ + { 0x0000, 0x0000 }, /* R1437 */ + { 0x0000, 0x0000 }, /* R1438 */ + { 0x0000, 0x0000 }, /* R1439 */ + { 0x0000, 0x0000 }, /* R1440 */ + { 0x0000, 0x0000 }, /* R1441 */ + { 0x0000, 0x0000 }, /* R1442 */ + { 0x0000, 0x0000 }, /* R1443 */ + { 0x0000, 0x0000 }, /* R1444 */ + { 0x0000, 0x0000 }, /* R1445 */ + { 0x0000, 0x0000 }, /* R1446 */ + { 0x0000, 0x0000 }, /* R1447 */ + { 0x0000, 0x0000 }, /* R1448 */ + { 0x0000, 0x0000 }, /* R1449 */ + { 0x0000, 0x0000 }, /* R1450 */ + { 0x0000, 0x0000 }, /* R1451 */ + { 0x0000, 0x0000 }, /* R1452 */ + { 0x0000, 0x0000 }, /* R1453 */ + { 0x0000, 0x0000 }, /* R1454 */ + { 0x0000, 0x0000 }, /* R1455 */ + { 0x0000, 0x0000 }, /* R1456 */ + { 0x0000, 0x0000 }, /* R1457 */ + { 0x0000, 0x0000 }, /* R1458 */ + { 0x0000, 0x0000 }, /* R1459 */ + { 0x0000, 0x0000 }, /* R1460 */ + { 0x0000, 0x0000 }, /* R1461 */ + { 0x0000, 0x0000 }, /* R1462 */ + { 0x0000, 0x0000 }, /* R1463 */ + { 0x0000, 0x0000 }, /* R1464 */ + { 0x0000, 0x0000 }, /* R1465 */ + { 0x0000, 0x0000 }, /* R1466 */ + { 0x0000, 0x0000 }, /* R1467 */ + { 0x0000, 0x0000 }, /* R1468 */ + { 0x0000, 0x0000 }, /* R1469 */ + { 0x0000, 0x0000 }, /* R1470 */ + { 0x0000, 0x0000 }, /* R1471 */ + { 0x0000, 0x0000 }, /* R1472 */ + { 0x0000, 0x0000 }, /* R1473 */ + { 0x0000, 0x0000 }, /* R1474 */ + { 0x0000, 0x0000 }, /* R1475 */ + { 0x0000, 0x0000 }, /* R1476 */ + { 0x0000, 0x0000 }, /* R1477 */ + { 0x0000, 0x0000 }, /* R1478 */ + { 0x0000, 0x0000 }, /* R1479 */ + { 0x0000, 0x0000 }, /* R1480 */ + { 0x0000, 0x0000 }, /* R1481 */ + { 0x0000, 0x0000 }, /* R1482 */ + { 0x0000, 0x0000 }, /* R1483 */ + { 0x0000, 0x0000 }, /* R1484 */ + { 0x0000, 0x0000 }, /* R1485 */ + { 0x0000, 0x0000 }, /* R1486 */ + { 0x0000, 0x0000 }, /* R1487 */ + { 0x0000, 0x0000 }, /* R1488 */ + { 0x0000, 0x0000 }, /* R1489 */ + { 0x0000, 0x0000 }, /* R1490 */ + { 0x0000, 0x0000 }, /* R1491 */ + { 0x0000, 0x0000 }, /* R1492 */ + { 0x0000, 0x0000 }, /* R1493 */ + { 0x0000, 0x0000 }, /* R1494 */ + { 0x0000, 0x0000 }, /* R1495 */ + { 0x0000, 0x0000 }, /* R1496 */ + { 0x0000, 0x0000 }, /* R1497 */ + { 0x0000, 0x0000 }, /* R1498 */ + { 0x0000, 0x0000 }, /* R1499 */ + { 0x0000, 0x0000 }, /* R1500 */ + { 0x0000, 0x0000 }, /* R1501 */ + { 0x0000, 0x0000 }, /* R1502 */ + { 0x0000, 0x0000 }, /* R1503 */ + { 0x0000, 0x0000 }, /* R1504 */ + { 0x0000, 0x0000 }, /* R1505 */ + { 0x0000, 0x0000 }, /* R1506 */ + { 0x0000, 0x0000 }, /* R1507 */ + { 0x0000, 0x0000 }, /* R1508 */ + { 0x0000, 0x0000 }, /* R1509 */ + { 0x0000, 0x0000 }, /* R1510 */ + { 0x0000, 0x0000 }, /* R1511 */ + { 0x0000, 0x0000 }, /* R1512 */ + { 0x0000, 0x0000 }, /* R1513 */ + { 0x0000, 0x0000 }, /* R1514 */ + { 0x0000, 0x0000 }, /* R1515 */ + { 0x0000, 0x0000 }, /* R1516 */ + { 0x0000, 0x0000 }, /* R1517 */ + { 0x0000, 0x0000 }, /* R1518 */ + { 0x0000, 0x0000 }, /* R1519 */ + { 0x0000, 0x0000 }, /* R1520 */ + { 0x0000, 0x0000 }, /* R1521 */ + { 0x0000, 0x0000 }, /* R1522 */ + { 0x0000, 0x0000 }, /* R1523 */ + { 0x0000, 0x0000 }, /* R1524 */ + { 0x0000, 0x0000 }, /* R1525 */ + { 0x0000, 0x0000 }, /* R1526 */ + { 0x0000, 0x0000 }, /* R1527 */ + { 0x0000, 0x0000 }, /* R1528 */ + { 0x0000, 0x0000 }, /* R1529 */ + { 0x0000, 0x0000 }, /* R1530 */ + { 0x0000, 0x0000 }, /* R1531 */ + { 0x0000, 0x0000 }, /* R1532 */ + { 0x0000, 0x0000 }, /* R1533 */ + { 0x0000, 0x0000 }, /* R1534 */ + { 0x0000, 0x0000 }, /* R1535 */ + { 0x01EF, 0x01EF }, /* R1536 - DAC1 Mixer Volumes */ + { 0x0037, 0x0037 }, /* R1537 - DAC1 Left Mixer Routing */ + { 0x0037, 0x0037 }, /* R1538 - DAC1 Right Mixer Routing */ + { 0x01EF, 0x01EF }, /* R1539 - DAC2 Mixer Volumes */ + { 0x0037, 0x0037 }, /* R1540 - DAC2 Left Mixer Routing */ + { 0x0037, 0x0037 }, /* R1541 - DAC2 Right Mixer Routing */ + { 0x0003, 0x0003 }, /* R1542 - AIF1 ADC1 Left Mixer Routing */ + { 0x0003, 0x0003 }, /* R1543 - AIF1 ADC1 Right Mixer Routing */ + { 0x0003, 0x0003 }, /* R1544 - AIF1 ADC2 Left Mixer Routing */ + { 0x0003, 0x0003 }, /* R1545 - AIF1 ADC2 Right mixer Routing */ + { 0x0000, 0x0000 }, /* R1546 */ + { 0x0000, 0x0000 }, /* R1547 */ + { 0x0000, 0x0000 }, /* R1548 */ + { 0x0000, 0x0000 }, /* R1549 */ + { 0x0000, 0x0000 }, /* R1550 */ + { 0x0000, 0x0000 }, /* R1551 */ + { 0x02FF, 0x03FF }, /* R1552 - DAC1 Left Volume */ + { 0x02FF, 0x03FF }, /* R1553 - DAC1 Right Volume */ + { 0x02FF, 0x03FF }, /* R1554 - DAC2 Left Volume */ + { 0x02FF, 0x03FF }, /* R1555 - DAC2 Right Volume */ + { 0x0003, 0x0003 }, /* R1556 - DAC Softmute */ + { 0x0000, 0x0000 }, /* R1557 */ + { 0x0000, 0x0000 }, /* R1558 */ + { 0x0000, 0x0000 }, /* R1559 */ + { 0x0000, 0x0000 }, /* R1560 */ + { 0x0000, 0x0000 }, /* R1561 */ + { 0x0000, 0x0000 }, /* R1562 */ + { 0x0000, 0x0000 }, /* R1563 */ + { 0x0000, 0x0000 }, /* R1564 */ + { 0x0000, 0x0000 }, /* R1565 */ + { 0x0000, 0x0000 }, /* R1566 */ + { 0x0000, 0x0000 }, /* R1567 */ + { 0x0003, 0x0003 }, /* R1568 - Oversampling */ + { 0x03C3, 0x03C3 }, /* R1569 - Sidetone */ +}; + diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index 7d2f488de6a7..189f00079d31 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c @@ -98,1582 +98,6 @@ struct wm8994_priv { struct wm8994_pdata *pdata; }; -static const struct { - unsigned short readable; /* Mask of readable bits */ - unsigned short writable; /* Mask of writable bits */ -} access_masks[] = { - { 0xFFFF, 0xFFFF }, /* R0 - Software Reset */ - { 0x3B37, 0x3B37 }, /* R1 - Power Management (1) */ - { 0x6BF0, 0x6BF0 }, /* R2 - Power Management (2) */ - { 0x3FF0, 0x3FF0 }, /* R3 - Power Management (3) */ - { 0x3F3F, 0x3F3F }, /* R4 - Power Management (4) */ - { 0x3F0F, 0x3F0F }, /* R5 - Power Management (5) */ - { 0x003F, 0x003F }, /* R6 - Power Management (6) */ - { 0x0000, 0x0000 }, /* R7 */ - { 0x0000, 0x0000 }, /* R8 */ - { 0x0000, 0x0000 }, /* R9 */ - { 0x0000, 0x0000 }, /* R10 */ - { 0x0000, 0x0000 }, /* R11 */ - { 0x0000, 0x0000 }, /* R12 */ - { 0x0000, 0x0000 }, /* R13 */ - { 0x0000, 0x0000 }, /* R14 */ - { 0x0000, 0x0000 }, /* R15 */ - { 0x0000, 0x0000 }, /* R16 */ - { 0x0000, 0x0000 }, /* R17 */ - { 0x0000, 0x0000 }, /* R18 */ - { 0x0000, 0x0000 }, /* R19 */ - { 0x0000, 0x0000 }, /* R20 */ - { 0x01C0, 0x01C0 }, /* R21 - Input Mixer (1) */ - { 0x0000, 0x0000 }, /* R22 */ - { 0x0000, 0x0000 }, /* R23 */ - { 0x00DF, 0x01DF }, /* R24 - Left Line Input 1&2 Volume */ - { 0x00DF, 0x01DF }, /* R25 - Left Line Input 3&4 Volume */ - { 0x00DF, 0x01DF }, /* R26 - Right Line Input 1&2 Volume */ - { 0x00DF, 0x01DF }, /* R27 - Right Line Input 3&4 Volume */ - { 0x00FF, 0x01FF }, /* R28 - Left Output Volume */ - { 0x00FF, 0x01FF }, /* R29 - Right Output Volume */ - { 0x0077, 0x0077 }, /* R30 - Line Outputs Volume */ - { 0x0030, 0x0030 }, /* R31 - HPOUT2 Volume */ - { 0x00FF, 0x01FF }, /* R32 - Left OPGA Volume */ - { 0x00FF, 0x01FF }, /* R33 - Right OPGA Volume */ - { 0x007F, 0x007F }, /* R34 - SPKMIXL Attenuation */ - { 0x017F, 0x017F }, /* R35 - SPKMIXR Attenuation */ - { 0x003F, 0x003F }, /* R36 - SPKOUT Mixers */ - { 0x003F, 0x003F }, /* R37 - ClassD */ - { 0x00FF, 0x01FF }, /* R38 - Speaker Volume Left */ - { 0x00FF, 0x01FF }, /* R39 - Speaker Volume Right */ - { 0x00FF, 0x00FF }, /* R40 - Input Mixer (2) */ - { 0x01B7, 0x01B7 }, /* R41 - Input Mixer (3) */ - { 0x01B7, 0x01B7 }, /* R42 - Input Mixer (4) */ - { 0x01C7, 0x01C7 }, /* R43 - Input Mixer (5) */ - { 0x01C7, 0x01C7 }, /* R44 - Input Mixer (6) */ - { 0x01FF, 0x01FF }, /* R45 - Output Mixer (1) */ - { 0x01FF, 0x01FF }, /* R46 - Output Mixer (2) */ - { 0x0FFF, 0x0FFF }, /* R47 - Output Mixer (3) */ - { 0x0FFF, 0x0FFF }, /* R48 - Output Mixer (4) */ - { 0x0FFF, 0x0FFF }, /* R49 - Output Mixer (5) */ - { 0x0FFF, 0x0FFF }, /* R50 - Output Mixer (6) */ - { 0x0038, 0x0038 }, /* R51 - HPOUT2 Mixer */ - { 0x0077, 0x0077 }, /* R52 - Line Mixer (1) */ - { 0x0077, 0x0077 }, /* R53 - Line Mixer (2) */ - { 0x03FF, 0x03FF }, /* R54 - Speaker Mixer */ - { 0x00C1, 0x00C1 }, /* R55 - Additional Control */ - { 0x00F0, 0x00F0 }, /* R56 - AntiPOP (1) */ - { 0x01EF, 0x01EF }, /* R57 - AntiPOP (2) */ - { 0x00FF, 0x00FF }, /* R58 - MICBIAS */ - { 0x000F, 0x000F }, /* R59 - LDO 1 */ - { 0x0007, 0x0007 }, /* R60 - LDO 2 */ - { 0x0000, 0x0000 }, /* R61 */ - { 0x0000, 0x0000 }, /* R62 */ - { 0x0000, 0x0000 }, /* R63 */ - { 0x0000, 0x0000 }, /* R64 */ - { 0x0000, 0x0000 }, /* R65 */ - { 0x0000, 0x0000 }, /* R66 */ - { 0x0000, 0x0000 }, /* R67 */ - { 0x0000, 0x0000 }, /* R68 */ - { 0x0000, 0x0000 }, /* R69 */ - { 0x0000, 0x0000 }, /* R70 */ - { 0x0000, 0x0000 }, /* R71 */ - { 0x0000, 0x0000 }, /* R72 */ - { 0x0000, 0x0000 }, /* R73 */ - { 0x0000, 0x0000 }, /* R74 */ - { 0x0000, 0x0000 }, /* R75 */ - { 0x8000, 0x8000 }, /* R76 - Charge Pump (1) */ - { 0x0000, 0x0000 }, /* R77 */ - { 0x0000, 0x0000 }, /* R78 */ - { 0x0000, 0x0000 }, /* R79 */ - { 0x0000, 0x0000 }, /* R80 */ - { 0x0301, 0x0301 }, /* R81 - Class W (1) */ - { 0x0000, 0x0000 }, /* R82 */ - { 0x0000, 0x0000 }, /* R83 */ - { 0x333F, 0x333F }, /* R84 - DC Servo (1) */ - { 0x0FEF, 0x0FEF }, /* R85 - DC Servo (2) */ - { 0x0000, 0x0000 }, /* R86 */ - { 0xFFFF, 0xFFFF }, /* R87 - DC Servo (4) */ - { 0x0333, 0x0000 }, /* R88 - DC Servo Readback */ - { 0x0000, 0x0000 }, /* R89 */ - { 0x0000, 0x0000 }, /* R90 */ - { 0x0000, 0x0000 }, /* R91 */ - { 0x0000, 0x0000 }, /* R92 */ - { 0x0000, 0x0000 }, /* R93 */ - { 0x0000, 0x0000 }, /* R94 */ - { 0x0000, 0x0000 }, /* R95 */ - { 0x00EE, 0x00EE }, /* R96 - Analogue HP (1) */ - { 0x0000, 0x0000 }, /* R97 */ - { 0x0000, 0x0000 }, /* R98 */ - { 0x0000, 0x0000 }, /* R99 */ - { 0x0000, 0x0000 }, /* R100 */ - { 0x0000, 0x0000 }, /* R101 */ - { 0x0000, 0x0000 }, /* R102 */ - { 0x0000, 0x0000 }, /* R103 */ - { 0x0000, 0x0000 }, /* R104 */ - { 0x0000, 0x0000 }, /* R105 */ - { 0x0000, 0x0000 }, /* R106 */ - { 0x0000, 0x0000 }, /* R107 */ - { 0x0000, 0x0000 }, /* R108 */ - { 0x0000, 0x0000 }, /* R109 */ - { 0x0000, 0x0000 }, /* R110 */ - { 0x0000, 0x0000 }, /* R111 */ - { 0x0000, 0x0000 }, /* R112 */ - { 0x0000, 0x0000 }, /* R113 */ - { 0x0000, 0x0000 }, /* R114 */ - { 0x0000, 0x0000 }, /* R115 */ - { 0x0000, 0x0000 }, /* R116 */ - { 0x0000, 0x0000 }, /* R117 */ - { 0x0000, 0x0000 }, /* R118 */ - { 0x0000, 0x0000 }, /* R119 */ - { 0x0000, 0x0000 }, /* R120 */ - { 0x0000, 0x0000 }, /* R121 */ - { 0x0000, 0x0000 }, /* R122 */ - { 0x0000, 0x0000 }, /* R123 */ - { 0x0000, 0x0000 }, /* R124 */ - { 0x0000, 0x0000 }, /* R125 */ - { 0x0000, 0x0000 }, /* R126 */ - { 0x0000, 0x0000 }, /* R127 */ - { 0x0000, 0x0000 }, /* R128 */ - { 0x0000, 0x0000 }, /* R129 */ - { 0x0000, 0x0000 }, /* R130 */ - { 0x0000, 0x0000 }, /* R131 */ - { 0x0000, 0x0000 }, /* R132 */ - { 0x0000, 0x0000 }, /* R133 */ - { 0x0000, 0x0000 }, /* R134 */ - { 0x0000, 0x0000 }, /* R135 */ - { 0x0000, 0x0000 }, /* R136 */ - { 0x0000, 0x0000 }, /* R137 */ - { 0x0000, 0x0000 }, /* R138 */ - { 0x0000, 0x0000 }, /* R139 */ - { 0x0000, 0x0000 }, /* R140 */ - { 0x0000, 0x0000 }, /* R141 */ - { 0x0000, 0x0000 }, /* R142 */ - { 0x0000, 0x0000 }, /* R143 */ - { 0x0000, 0x0000 }, /* R144 */ - { 0x0000, 0x0000 }, /* R145 */ - { 0x0000, 0x0000 }, /* R146 */ - { 0x0000, 0x0000 }, /* R147 */ - { 0x0000, 0x0000 }, /* R148 */ - { 0x0000, 0x0000 }, /* R149 */ - { 0x0000, 0x0000 }, /* R150 */ - { 0x0000, 0x0000 }, /* R151 */ - { 0x0000, 0x0000 }, /* R152 */ - { 0x0000, 0x0000 }, /* R153 */ - { 0x0000, 0x0000 }, /* R154 */ - { 0x0000, 0x0000 }, /* R155 */ - { 0x0000, 0x0000 }, /* R156 */ - { 0x0000, 0x0000 }, /* R157 */ - { 0x0000, 0x0000 }, /* R158 */ - { 0x0000, 0x0000 }, /* R159 */ - { 0x0000, 0x0000 }, /* R160 */ - { 0x0000, 0x0000 }, /* R161 */ - { 0x0000, 0x0000 }, /* R162 */ - { 0x0000, 0x0000 }, /* R163 */ - { 0x0000, 0x0000 }, /* R164 */ - { 0x0000, 0x0000 }, /* R165 */ - { 0x0000, 0x0000 }, /* R166 */ - { 0x0000, 0x0000 }, /* R167 */ - { 0x0000, 0x0000 }, /* R168 */ - { 0x0000, 0x0000 }, /* R169 */ - { 0x0000, 0x0000 }, /* R170 */ - { 0x0000, 0x0000 }, /* R171 */ - { 0x0000, 0x0000 }, /* R172 */ - { 0x0000, 0x0000 }, /* R173 */ - { 0x0000, 0x0000 }, /* R174 */ - { 0x0000, 0x0000 }, /* R175 */ - { 0x0000, 0x0000 }, /* R176 */ - { 0x0000, 0x0000 }, /* R177 */ - { 0x0000, 0x0000 }, /* R178 */ - { 0x0000, 0x0000 }, /* R179 */ - { 0x0000, 0x0000 }, /* R180 */ - { 0x0000, 0x0000 }, /* R181 */ - { 0x0000, 0x0000 }, /* R182 */ - { 0x0000, 0x0000 }, /* R183 */ - { 0x0000, 0x0000 }, /* R184 */ - { 0x0000, 0x0000 }, /* R185 */ - { 0x0000, 0x0000 }, /* R186 */ - { 0x0000, 0x0000 }, /* R187 */ - { 0x0000, 0x0000 }, /* R188 */ - { 0x0000, 0x0000 }, /* R189 */ - { 0x0000, 0x0000 }, /* R190 */ - { 0x0000, 0x0000 }, /* R191 */ - { 0x0000, 0x0000 }, /* R192 */ - { 0x0000, 0x0000 }, /* R193 */ - { 0x0000, 0x0000 }, /* R194 */ - { 0x0000, 0x0000 }, /* R195 */ - { 0x0000, 0x0000 }, /* R196 */ - { 0x0000, 0x0000 }, /* R197 */ - { 0x0000, 0x0000 }, /* R198 */ - { 0x0000, 0x0000 }, /* R199 */ - { 0x0000, 0x0000 }, /* R200 */ - { 0x0000, 0x0000 }, /* R201 */ - { 0x0000, 0x0000 }, /* R202 */ - { 0x0000, 0x0000 }, /* R203 */ - { 0x0000, 0x0000 }, /* R204 */ - { 0x0000, 0x0000 }, /* R205 */ - { 0x0000, 0x0000 }, /* R206 */ - { 0x0000, 0x0000 }, /* R207 */ - { 0x0000, 0x0000 }, /* R208 */ - { 0x0000, 0x0000 }, /* R209 */ - { 0x0000, 0x0000 }, /* R210 */ - { 0x0000, 0x0000 }, /* R211 */ - { 0x0000, 0x0000 }, /* R212 */ - { 0x0000, 0x0000 }, /* R213 */ - { 0x0000, 0x0000 }, /* R214 */ - { 0x0000, 0x0000 }, /* R215 */ - { 0x0000, 0x0000 }, /* R216 */ - { 0x0000, 0x0000 }, /* R217 */ - { 0x0000, 0x0000 }, /* R218 */ - { 0x0000, 0x0000 }, /* R219 */ - { 0x0000, 0x0000 }, /* R220 */ - { 0x0000, 0x0000 }, /* R221 */ - { 0x0000, 0x0000 }, /* R222 */ - { 0x0000, 0x0000 }, /* R223 */ - { 0x0000, 0x0000 }, /* R224 */ - { 0x0000, 0x0000 }, /* R225 */ - { 0x0000, 0x0000 }, /* R226 */ - { 0x0000, 0x0000 }, /* R227 */ - { 0x0000, 0x0000 }, /* R228 */ - { 0x0000, 0x0000 }, /* R229 */ - { 0x0000, 0x0000 }, /* R230 */ - { 0x0000, 0x0000 }, /* R231 */ - { 0x0000, 0x0000 }, /* R232 */ - { 0x0000, 0x0000 }, /* R233 */ - { 0x0000, 0x0000 }, /* R234 */ - { 0x0000, 0x0000 }, /* R235 */ - { 0x0000, 0x0000 }, /* R236 */ - { 0x0000, 0x0000 }, /* R237 */ - { 0x0000, 0x0000 }, /* R238 */ - { 0x0000, 0x0000 }, /* R239 */ - { 0x0000, 0x0000 }, /* R240 */ - { 0x0000, 0x0000 }, /* R241 */ - { 0x0000, 0x0000 }, /* R242 */ - { 0x0000, 0x0000 }, /* R243 */ - { 0x0000, 0x0000 }, /* R244 */ - { 0x0000, 0x0000 }, /* R245 */ - { 0x0000, 0x0000 }, /* R246 */ - { 0x0000, 0x0000 }, /* R247 */ - { 0x0000, 0x0000 }, /* R248 */ - { 0x0000, 0x0000 }, /* R249 */ - { 0x0000, 0x0000 }, /* R250 */ - { 0x0000, 0x0000 }, /* R251 */ - { 0x0000, 0x0000 }, /* R252 */ - { 0x0000, 0x0000 }, /* R253 */ - { 0x0000, 0x0000 }, /* R254 */ - { 0x0000, 0x0000 }, /* R255 */ - { 0x000F, 0x0000 }, /* R256 - Chip Revision */ - { 0x0074, 0x0074 }, /* R257 - Control Interface */ - { 0x0000, 0x0000 }, /* R258 */ - { 0x0000, 0x0000 }, /* R259 */ - { 0x0000, 0x0000 }, /* R260 */ - { 0x0000, 0x0000 }, /* R261 */ - { 0x0000, 0x0000 }, /* R262 */ - { 0x0000, 0x0000 }, /* R263 */ - { 0x0000, 0x0000 }, /* R264 */ - { 0x0000, 0x0000 }, /* R265 */ - { 0x0000, 0x0000 }, /* R266 */ - { 0x0000, 0x0000 }, /* R267 */ - { 0x0000, 0x0000 }, /* R268 */ - { 0x0000, 0x0000 }, /* R269 */ - { 0x0000, 0x0000 }, /* R270 */ - { 0x0000, 0x0000 }, /* R271 */ - { 0x807F, 0x837F }, /* R272 - Write Sequencer Ctrl (1) */ - { 0x017F, 0x0000 }, /* R273 - Write Sequencer Ctrl (2) */ - { 0x0000, 0x0000 }, /* R274 */ - { 0x0000, 0x0000 }, /* R275 */ - { 0x0000, 0x0000 }, /* R276 */ - { 0x0000, 0x0000 }, /* R277 */ - { 0x0000, 0x0000 }, /* R278 */ - { 0x0000, 0x0000 }, /* R279 */ - { 0x0000, 0x0000 }, /* R280 */ - { 0x0000, 0x0000 }, /* R281 */ - { 0x0000, 0x0000 }, /* R282 */ - { 0x0000, 0x0000 }, /* R283 */ - { 0x0000, 0x0000 }, /* R284 */ - { 0x0000, 0x0000 }, /* R285 */ - { 0x0000, 0x0000 }, /* R286 */ - { 0x0000, 0x0000 }, /* R287 */ - { 0x0000, 0x0000 }, /* R288 */ - { 0x0000, 0x0000 }, /* R289 */ - { 0x0000, 0x0000 }, /* R290 */ - { 0x0000, 0x0000 }, /* R291 */ - { 0x0000, 0x0000 }, /* R292 */ - { 0x0000, 0x0000 }, /* R293 */ - { 0x0000, 0x0000 }, /* R294 */ - { 0x0000, 0x0000 }, /* R295 */ - { 0x0000, 0x0000 }, /* R296 */ - { 0x0000, 0x0000 }, /* R297 */ - { 0x0000, 0x0000 }, /* R298 */ - { 0x0000, 0x0000 }, /* R299 */ - { 0x0000, 0x0000 }, /* R300 */ - { 0x0000, 0x0000 }, /* R301 */ - { 0x0000, 0x0000 }, /* R302 */ - { 0x0000, 0x0000 }, /* R303 */ - { 0x0000, 0x0000 }, /* R304 */ - { 0x0000, 0x0000 }, /* R305 */ - { 0x0000, 0x0000 }, /* R306 */ - { 0x0000, 0x0000 }, /* R307 */ - { 0x0000, 0x0000 }, /* R308 */ - { 0x0000, 0x0000 }, /* R309 */ - { 0x0000, 0x0000 }, /* R310 */ - { 0x0000, 0x0000 }, /* R311 */ - { 0x0000, 0x0000 }, /* R312 */ - { 0x0000, 0x0000 }, /* R313 */ - { 0x0000, 0x0000 }, /* R314 */ - { 0x0000, 0x0000 }, /* R315 */ - { 0x0000, 0x0000 }, /* R316 */ - { 0x0000, 0x0000 }, /* R317 */ - { 0x0000, 0x0000 }, /* R318 */ - { 0x0000, 0x0000 }, /* R319 */ - { 0x0000, 0x0000 }, /* R320 */ - { 0x0000, 0x0000 }, /* R321 */ - { 0x0000, 0x0000 }, /* R322 */ - { 0x0000, 0x0000 }, /* R323 */ - { 0x0000, 0x0000 }, /* R324 */ - { 0x0000, 0x0000 }, /* R325 */ - { 0x0000, 0x0000 }, /* R326 */ - { 0x0000, 0x0000 }, /* R327 */ - { 0x0000, 0x0000 }, /* R328 */ - { 0x0000, 0x0000 }, /* R329 */ - { 0x0000, 0x0000 }, /* R330 */ - { 0x0000, 0x0000 }, /* R331 */ - { 0x0000, 0x0000 }, /* R332 */ - { 0x0000, 0x0000 }, /* R333 */ - { 0x0000, 0x0000 }, /* R334 */ - { 0x0000, 0x0000 }, /* R335 */ - { 0x0000, 0x0000 }, /* R336 */ - { 0x0000, 0x0000 }, /* R337 */ - { 0x0000, 0x0000 }, /* R338 */ - { 0x0000, 0x0000 }, /* R339 */ - { 0x0000, 0x0000 }, /* R340 */ - { 0x0000, 0x0000 }, /* R341 */ - { 0x0000, 0x0000 }, /* R342 */ - { 0x0000, 0x0000 }, /* R343 */ - { 0x0000, 0x0000 }, /* R344 */ - { 0x0000, 0x0000 }, /* R345 */ - { 0x0000, 0x0000 }, /* R346 */ - { 0x0000, 0x0000 }, /* R347 */ - { 0x0000, 0x0000 }, /* R348 */ - { 0x0000, 0x0000 }, /* R349 */ - { 0x0000, 0x0000 }, /* R350 */ - { 0x0000, 0x0000 }, /* R351 */ - { 0x0000, 0x0000 }, /* R352 */ - { 0x0000, 0x0000 }, /* R353 */ - { 0x0000, 0x0000 }, /* R354 */ - { 0x0000, 0x0000 }, /* R355 */ - { 0x0000, 0x0000 }, /* R356 */ - { 0x0000, 0x0000 }, /* R357 */ - { 0x0000, 0x0000 }, /* R358 */ - { 0x0000, 0x0000 }, /* R359 */ - { 0x0000, 0x0000 }, /* R360 */ - { 0x0000, 0x0000 }, /* R361 */ - { 0x0000, 0x0000 }, /* R362 */ - { 0x0000, 0x0000 }, /* R363 */ - { 0x0000, 0x0000 }, /* R364 */ - { 0x0000, 0x0000 }, /* R365 */ - { 0x0000, 0x0000 }, /* R366 */ - { 0x0000, 0x0000 }, /* R367 */ - { 0x0000, 0x0000 }, /* R368 */ - { 0x0000, 0x0000 }, /* R369 */ - { 0x0000, 0x0000 }, /* R370 */ - { 0x0000, 0x0000 }, /* R371 */ - { 0x0000, 0x0000 }, /* R372 */ - { 0x0000, 0x0000 }, /* R373 */ - { 0x0000, 0x0000 }, /* R374 */ - { 0x0000, 0x0000 }, /* R375 */ - { 0x0000, 0x0000 }, /* R376 */ - { 0x0000, 0x0000 }, /* R377 */ - { 0x0000, 0x0000 }, /* R378 */ - { 0x0000, 0x0000 }, /* R379 */ - { 0x0000, 0x0000 }, /* R380 */ - { 0x0000, 0x0000 }, /* R381 */ - { 0x0000, 0x0000 }, /* R382 */ - { 0x0000, 0x0000 }, /* R383 */ - { 0x0000, 0x0000 }, /* R384 */ - { 0x0000, 0x0000 }, /* R385 */ - { 0x0000, 0x0000 }, /* R386 */ - { 0x0000, 0x0000 }, /* R387 */ - { 0x0000, 0x0000 }, /* R388 */ - { 0x0000, 0x0000 }, /* R389 */ - { 0x0000, 0x0000 }, /* R390 */ - { 0x0000, 0x0000 }, /* R391 */ - { 0x0000, 0x0000 }, /* R392 */ - { 0x0000, 0x0000 }, /* R393 */ - { 0x0000, 0x0000 }, /* R394 */ - { 0x0000, 0x0000 }, /* R395 */ - { 0x0000, 0x0000 }, /* R396 */ - { 0x0000, 0x0000 }, /* R397 */ - { 0x0000, 0x0000 }, /* R398 */ - { 0x0000, 0x0000 }, /* R399 */ - { 0x0000, 0x0000 }, /* R400 */ - { 0x0000, 0x0000 }, /* R401 */ - { 0x0000, 0x0000 }, /* R402 */ - { 0x0000, 0x0000 }, /* R403 */ - { 0x0000, 0x0000 }, /* R404 */ - { 0x0000, 0x0000 }, /* R405 */ - { 0x0000, 0x0000 }, /* R406 */ - { 0x0000, 0x0000 }, /* R407 */ - { 0x0000, 0x0000 }, /* R408 */ - { 0x0000, 0x0000 }, /* R409 */ - { 0x0000, 0x0000 }, /* R410 */ - { 0x0000, 0x0000 }, /* R411 */ - { 0x0000, 0x0000 }, /* R412 */ - { 0x0000, 0x0000 }, /* R413 */ - { 0x0000, 0x0000 }, /* R414 */ - { 0x0000, 0x0000 }, /* R415 */ - { 0x0000, 0x0000 }, /* R416 */ - { 0x0000, 0x0000 }, /* R417 */ - { 0x0000, 0x0000 }, /* R418 */ - { 0x0000, 0x0000 }, /* R419 */ - { 0x0000, 0x0000 }, /* R420 */ - { 0x0000, 0x0000 }, /* R421 */ - { 0x0000, 0x0000 }, /* R422 */ - { 0x0000, 0x0000 }, /* R423 */ - { 0x0000, 0x0000 }, /* R424 */ - { 0x0000, 0x0000 }, /* R425 */ - { 0x0000, 0x0000 }, /* R426 */ - { 0x0000, 0x0000 }, /* R427 */ - { 0x0000, 0x0000 }, /* R428 */ - { 0x0000, 0x0000 }, /* R429 */ - { 0x0000, 0x0000 }, /* R430 */ - { 0x0000, 0x0000 }, /* R431 */ - { 0x0000, 0x0000 }, /* R432 */ - { 0x0000, 0x0000 }, /* R433 */ - { 0x0000, 0x0000 }, /* R434 */ - { 0x0000, 0x0000 }, /* R435 */ - { 0x0000, 0x0000 }, /* R436 */ - { 0x0000, 0x0000 }, /* R437 */ - { 0x0000, 0x0000 }, /* R438 */ - { 0x0000, 0x0000 }, /* R439 */ - { 0x0000, 0x0000 }, /* R440 */ - { 0x0000, 0x0000 }, /* R441 */ - { 0x0000, 0x0000 }, /* R442 */ - { 0x0000, 0x0000 }, /* R443 */ - { 0x0000, 0x0000 }, /* R444 */ - { 0x0000, 0x0000 }, /* R445 */ - { 0x0000, 0x0000 }, /* R446 */ - { 0x0000, 0x0000 }, /* R447 */ - { 0x0000, 0x0000 }, /* R448 */ - { 0x0000, 0x0000 }, /* R449 */ - { 0x0000, 0x0000 }, /* R450 */ - { 0x0000, 0x0000 }, /* R451 */ - { 0x0000, 0x0000 }, /* R452 */ - { 0x0000, 0x0000 }, /* R453 */ - { 0x0000, 0x0000 }, /* R454 */ - { 0x0000, 0x0000 }, /* R455 */ - { 0x0000, 0x0000 }, /* R456 */ - { 0x0000, 0x0000 }, /* R457 */ - { 0x0000, 0x0000 }, /* R458 */ - { 0x0000, 0x0000 }, /* R459 */ - { 0x0000, 0x0000 }, /* R460 */ - { 0x0000, 0x0000 }, /* R461 */ - { 0x0000, 0x0000 }, /* R462 */ - { 0x0000, 0x0000 }, /* R463 */ - { 0x0000, 0x0000 }, /* R464 */ - { 0x0000, 0x0000 }, /* R465 */ - { 0x0000, 0x0000 }, /* R466 */ - { 0x0000, 0x0000 }, /* R467 */ - { 0x0000, 0x0000 }, /* R468 */ - { 0x0000, 0x0000 }, /* R469 */ - { 0x0000, 0x0000 }, /* R470 */ - { 0x0000, 0x0000 }, /* R471 */ - { 0x0000, 0x0000 }, /* R472 */ - { 0x0000, 0x0000 }, /* R473 */ - { 0x0000, 0x0000 }, /* R474 */ - { 0x0000, 0x0000 }, /* R475 */ - { 0x0000, 0x0000 }, /* R476 */ - { 0x0000, 0x0000 }, /* R477 */ - { 0x0000, 0x0000 }, /* R478 */ - { 0x0000, 0x0000 }, /* R479 */ - { 0x0000, 0x0000 }, /* R480 */ - { 0x0000, 0x0000 }, /* R481 */ - { 0x0000, 0x0000 }, /* R482 */ - { 0x0000, 0x0000 }, /* R483 */ - { 0x0000, 0x0000 }, /* R484 */ - { 0x0000, 0x0000 }, /* R485 */ - { 0x0000, 0x0000 }, /* R486 */ - { 0x0000, 0x0000 }, /* R487 */ - { 0x0000, 0x0000 }, /* R488 */ - { 0x0000, 0x0000 }, /* R489 */ - { 0x0000, 0x0000 }, /* R490 */ - { 0x0000, 0x0000 }, /* R491 */ - { 0x0000, 0x0000 }, /* R492 */ - { 0x0000, 0x0000 }, /* R493 */ - { 0x0000, 0x0000 }, /* R494 */ - { 0x0000, 0x0000 }, /* R495 */ - { 0x0000, 0x0000 }, /* R496 */ - { 0x0000, 0x0000 }, /* R497 */ - { 0x0000, 0x0000 }, /* R498 */ - { 0x0000, 0x0000 }, /* R499 */ - { 0x0000, 0x0000 }, /* R500 */ - { 0x0000, 0x0000 }, /* R501 */ - { 0x0000, 0x0000 }, /* R502 */ - { 0x0000, 0x0000 }, /* R503 */ - { 0x0000, 0x0000 }, /* R504 */ - { 0x0000, 0x0000 }, /* R505 */ - { 0x0000, 0x0000 }, /* R506 */ - { 0x0000, 0x0000 }, /* R507 */ - { 0x0000, 0x0000 }, /* R508 */ - { 0x0000, 0x0000 }, /* R509 */ - { 0x0000, 0x0000 }, /* R510 */ - { 0x0000, 0x0000 }, /* R511 */ - { 0x001F, 0x001F }, /* R512 - AIF1 Clocking (1) */ - { 0x003F, 0x003F }, /* R513 - AIF1 Clocking (2) */ - { 0x0000, 0x0000 }, /* R514 */ - { 0x0000, 0x0000 }, /* R515 */ - { 0x001F, 0x001F }, /* R516 - AIF2 Clocking (1) */ - { 0x003F, 0x003F }, /* R517 - AIF2 Clocking (2) */ - { 0x0000, 0x0000 }, /* R518 */ - { 0x0000, 0x0000 }, /* R519 */ - { 0x001F, 0x001F }, /* R520 - Clocking (1) */ - { 0x0777, 0x0777 }, /* R521 - Clocking (2) */ - { 0x0000, 0x0000 }, /* R522 */ - { 0x0000, 0x0000 }, /* R523 */ - { 0x0000, 0x0000 }, /* R524 */ - { 0x0000, 0x0000 }, /* R525 */ - { 0x0000, 0x0000 }, /* R526 */ - { 0x0000, 0x0000 }, /* R527 */ - { 0x00FF, 0x00FF }, /* R528 - AIF1 Rate */ - { 0x00FF, 0x00FF }, /* R529 - AIF2 Rate */ - { 0x000F, 0x0000 }, /* R530 - Rate Status */ - { 0x0000, 0x0000 }, /* R531 */ - { 0x0000, 0x0000 }, /* R532 */ - { 0x0000, 0x0000 }, /* R533 */ - { 0x0000, 0x0000 }, /* R534 */ - { 0x0000, 0x0000 }, /* R535 */ - { 0x0000, 0x0000 }, /* R536 */ - { 0x0000, 0x0000 }, /* R537 */ - { 0x0000, 0x0000 }, /* R538 */ - { 0x0000, 0x0000 }, /* R539 */ - { 0x0000, 0x0000 }, /* R540 */ - { 0x0000, 0x0000 }, /* R541 */ - { 0x0000, 0x0000 }, /* R542 */ - { 0x0000, 0x0000 }, /* R543 */ - { 0x0007, 0x0007 }, /* R544 - FLL1 Control (1) */ - { 0x3F77, 0x3F77 }, /* R545 - FLL1 Control (2) */ - { 0xFFFF, 0xFFFF }, /* R546 - FLL1 Control (3) */ - { 0x7FEF, 0x7FEF }, /* R547 - FLL1 Control (4) */ - { 0x1FDB, 0x1FDB }, /* R548 - FLL1 Control (5) */ - { 0x0000, 0x0000 }, /* R549 */ - { 0x0000, 0x0000 }, /* R550 */ - { 0x0000, 0x0000 }, /* R551 */ - { 0x0000, 0x0000 }, /* R552 */ - { 0x0000, 0x0000 }, /* R553 */ - { 0x0000, 0x0000 }, /* R554 */ - { 0x0000, 0x0000 }, /* R555 */ - { 0x0000, 0x0000 }, /* R556 */ - { 0x0000, 0x0000 }, /* R557 */ - { 0x0000, 0x0000 }, /* R558 */ - { 0x0000, 0x0000 }, /* R559 */ - { 0x0000, 0x0000 }, /* R560 */ - { 0x0000, 0x0000 }, /* R561 */ - { 0x0000, 0x0000 }, /* R562 */ - { 0x0000, 0x0000 }, /* R563 */ - { 0x0000, 0x0000 }, /* R564 */ - { 0x0000, 0x0000 }, /* R565 */ - { 0x0000, 0x0000 }, /* R566 */ - { 0x0000, 0x0000 }, /* R567 */ - { 0x0000, 0x0000 }, /* R568 */ - { 0x0000, 0x0000 }, /* R569 */ - { 0x0000, 0x0000 }, /* R570 */ - { 0x0000, 0x0000 }, /* R571 */ - { 0x0000, 0x0000 }, /* R572 */ - { 0x0000, 0x0000 }, /* R573 */ - { 0x0000, 0x0000 }, /* R574 */ - { 0x0000, 0x0000 }, /* R575 */ - { 0x0007, 0x0007 }, /* R576 - FLL2 Control (1) */ - { 0x3F77, 0x3F77 }, /* R577 - FLL2 Control (2) */ - { 0xFFFF, 0xFFFF }, /* R578 - FLL2 Control (3) */ - { 0x7FEF, 0x7FEF }, /* R579 - FLL2 Control (4) */ - { 0x1FDB, 0x1FDB }, /* R580 - FLL2 Control (5) */ - { 0x0000, 0x0000 }, /* R581 */ - { 0x0000, 0x0000 }, /* R582 */ - { 0x0000, 0x0000 }, /* R583 */ - { 0x0000, 0x0000 }, /* R584 */ - { 0x0000, 0x0000 }, /* R585 */ - { 0x0000, 0x0000 }, /* R586 */ - { 0x0000, 0x0000 }, /* R587 */ - { 0x0000, 0x0000 }, /* R588 */ - { 0x0000, 0x0000 }, /* R589 */ - { 0x0000, 0x0000 }, /* R590 */ - { 0x0000, 0x0000 }, /* R591 */ - { 0x0000, 0x0000 }, /* R592 */ - { 0x0000, 0x0000 }, /* R593 */ - { 0x0000, 0x0000 }, /* R594 */ - { 0x0000, 0x0000 }, /* R595 */ - { 0x0000, 0x0000 }, /* R596 */ - { 0x0000, 0x0000 }, /* R597 */ - { 0x0000, 0x0000 }, /* R598 */ - { 0x0000, 0x0000 }, /* R599 */ - { 0x0000, 0x0000 }, /* R600 */ - { 0x0000, 0x0000 }, /* R601 */ - { 0x0000, 0x0000 }, /* R602 */ - { 0x0000, 0x0000 }, /* R603 */ - { 0x0000, 0x0000 }, /* R604 */ - { 0x0000, 0x0000 }, /* R605 */ - { 0x0000, 0x0000 }, /* R606 */ - { 0x0000, 0x0000 }, /* R607 */ - { 0x0000, 0x0000 }, /* R608 */ - { 0x0000, 0x0000 }, /* R609 */ - { 0x0000, 0x0000 }, /* R610 */ - { 0x0000, 0x0000 }, /* R611 */ - { 0x0000, 0x0000 }, /* R612 */ - { 0x0000, 0x0000 }, /* R613 */ - { 0x0000, 0x0000 }, /* R614 */ - { 0x0000, 0x0000 }, /* R615 */ - { 0x0000, 0x0000 }, /* R616 */ - { 0x0000, 0x0000 }, /* R617 */ - { 0x0000, 0x0000 }, /* R618 */ - { 0x0000, 0x0000 }, /* R619 */ - { 0x0000, 0x0000 }, /* R620 */ - { 0x0000, 0x0000 }, /* R621 */ - { 0x0000, 0x0000 }, /* R622 */ - { 0x0000, 0x0000 }, /* R623 */ - { 0x0000, 0x0000 }, /* R624 */ - { 0x0000, 0x0000 }, /* R625 */ - { 0x0000, 0x0000 }, /* R626 */ - { 0x0000, 0x0000 }, /* R627 */ - { 0x0000, 0x0000 }, /* R628 */ - { 0x0000, 0x0000 }, /* R629 */ - { 0x0000, 0x0000 }, /* R630 */ - { 0x0000, 0x0000 }, /* R631 */ - { 0x0000, 0x0000 }, /* R632 */ - { 0x0000, 0x0000 }, /* R633 */ - { 0x0000, 0x0000 }, /* R634 */ - { 0x0000, 0x0000 }, /* R635 */ - { 0x0000, 0x0000 }, /* R636 */ - { 0x0000, 0x0000 }, /* R637 */ - { 0x0000, 0x0000 }, /* R638 */ - { 0x0000, 0x0000 }, /* R639 */ - { 0x0000, 0x0000 }, /* R640 */ - { 0x0000, 0x0000 }, /* R641 */ - { 0x0000, 0x0000 }, /* R642 */ - { 0x0000, 0x0000 }, /* R643 */ - { 0x0000, 0x0000 }, /* R644 */ - { 0x0000, 0x0000 }, /* R645 */ - { 0x0000, 0x0000 }, /* R646 */ - { 0x0000, 0x0000 }, /* R647 */ - { 0x0000, 0x0000 }, /* R648 */ - { 0x0000, 0x0000 }, /* R649 */ - { 0x0000, 0x0000 }, /* R650 */ - { 0x0000, 0x0000 }, /* R651 */ - { 0x0000, 0x0000 }, /* R652 */ - { 0x0000, 0x0000 }, /* R653 */ - { 0x0000, 0x0000 }, /* R654 */ - { 0x0000, 0x0000 }, /* R655 */ - { 0x0000, 0x0000 }, /* R656 */ - { 0x0000, 0x0000 }, /* R657 */ - { 0x0000, 0x0000 }, /* R658 */ - { 0x0000, 0x0000 }, /* R659 */ - { 0x0000, 0x0000 }, /* R660 */ - { 0x0000, 0x0000 }, /* R661 */ - { 0x0000, 0x0000 }, /* R662 */ - { 0x0000, 0x0000 }, /* R663 */ - { 0x0000, 0x0000 }, /* R664 */ - { 0x0000, 0x0000 }, /* R665 */ - { 0x0000, 0x0000 }, /* R666 */ - { 0x0000, 0x0000 }, /* R667 */ - { 0x0000, 0x0000 }, /* R668 */ - { 0x0000, 0x0000 }, /* R669 */ - { 0x0000, 0x0000 }, /* R670 */ - { 0x0000, 0x0000 }, /* R671 */ - { 0x0000, 0x0000 }, /* R672 */ - { 0x0000, 0x0000 }, /* R673 */ - { 0x0000, 0x0000 }, /* R674 */ - { 0x0000, 0x0000 }, /* R675 */ - { 0x0000, 0x0000 }, /* R676 */ - { 0x0000, 0x0000 }, /* R677 */ - { 0x0000, 0x0000 }, /* R678 */ - { 0x0000, 0x0000 }, /* R679 */ - { 0x0000, 0x0000 }, /* R680 */ - { 0x0000, 0x0000 }, /* R681 */ - { 0x0000, 0x0000 }, /* R682 */ - { 0x0000, 0x0000 }, /* R683 */ - { 0x0000, 0x0000 }, /* R684 */ - { 0x0000, 0x0000 }, /* R685 */ - { 0x0000, 0x0000 }, /* R686 */ - { 0x0000, 0x0000 }, /* R687 */ - { 0x0000, 0x0000 }, /* R688 */ - { 0x0000, 0x0000 }, /* R689 */ - { 0x0000, 0x0000 }, /* R690 */ - { 0x0000, 0x0000 }, /* R691 */ - { 0x0000, 0x0000 }, /* R692 */ - { 0x0000, 0x0000 }, /* R693 */ - { 0x0000, 0x0000 }, /* R694 */ - { 0x0000, 0x0000 }, /* R695 */ - { 0x0000, 0x0000 }, /* R696 */ - { 0x0000, 0x0000 }, /* R697 */ - { 0x0000, 0x0000 }, /* R698 */ - { 0x0000, 0x0000 }, /* R699 */ - { 0x0000, 0x0000 }, /* R700 */ - { 0x0000, 0x0000 }, /* R701 */ - { 0x0000, 0x0000 }, /* R702 */ - { 0x0000, 0x0000 }, /* R703 */ - { 0x0000, 0x0000 }, /* R704 */ - { 0x0000, 0x0000 }, /* R705 */ - { 0x0000, 0x0000 }, /* R706 */ - { 0x0000, 0x0000 }, /* R707 */ - { 0x0000, 0x0000 }, /* R708 */ - { 0x0000, 0x0000 }, /* R709 */ - { 0x0000, 0x0000 }, /* R710 */ - { 0x0000, 0x0000 }, /* R711 */ - { 0x0000, 0x0000 }, /* R712 */ - { 0x0000, 0x0000 }, /* R713 */ - { 0x0000, 0x0000 }, /* R714 */ - { 0x0000, 0x0000 }, /* R715 */ - { 0x0000, 0x0000 }, /* R716 */ - { 0x0000, 0x0000 }, /* R717 */ - { 0x0000, 0x0000 }, /* R718 */ - { 0x0000, 0x0000 }, /* R719 */ - { 0x0000, 0x0000 }, /* R720 */ - { 0x0000, 0x0000 }, /* R721 */ - { 0x0000, 0x0000 }, /* R722 */ - { 0x0000, 0x0000 }, /* R723 */ - { 0x0000, 0x0000 }, /* R724 */ - { 0x0000, 0x0000 }, /* R725 */ - { 0x0000, 0x0000 }, /* R726 */ - { 0x0000, 0x0000 }, /* R727 */ - { 0x0000, 0x0000 }, /* R728 */ - { 0x0000, 0x0000 }, /* R729 */ - { 0x0000, 0x0000 }, /* R730 */ - { 0x0000, 0x0000 }, /* R731 */ - { 0x0000, 0x0000 }, /* R732 */ - { 0x0000, 0x0000 }, /* R733 */ - { 0x0000, 0x0000 }, /* R734 */ - { 0x0000, 0x0000 }, /* R735 */ - { 0x0000, 0x0000 }, /* R736 */ - { 0x0000, 0x0000 }, /* R737 */ - { 0x0000, 0x0000 }, /* R738 */ - { 0x0000, 0x0000 }, /* R739 */ - { 0x0000, 0x0000 }, /* R740 */ - { 0x0000, 0x0000 }, /* R741 */ - { 0x0000, 0x0000 }, /* R742 */ - { 0x0000, 0x0000 }, /* R743 */ - { 0x0000, 0x0000 }, /* R744 */ - { 0x0000, 0x0000 }, /* R745 */ - { 0x0000, 0x0000 }, /* R746 */ - { 0x0000, 0x0000 }, /* R747 */ - { 0x0000, 0x0000 }, /* R748 */ - { 0x0000, 0x0000 }, /* R749 */ - { 0x0000, 0x0000 }, /* R750 */ - { 0x0000, 0x0000 }, /* R751 */ - { 0x0000, 0x0000 }, /* R752 */ - { 0x0000, 0x0000 }, /* R753 */ - { 0x0000, 0x0000 }, /* R754 */ - { 0x0000, 0x0000 }, /* R755 */ - { 0x0000, 0x0000 }, /* R756 */ - { 0x0000, 0x0000 }, /* R757 */ - { 0x0000, 0x0000 }, /* R758 */ - { 0x0000, 0x0000 }, /* R759 */ - { 0x0000, 0x0000 }, /* R760 */ - { 0x0000, 0x0000 }, /* R761 */ - { 0x0000, 0x0000 }, /* R762 */ - { 0x0000, 0x0000 }, /* R763 */ - { 0x0000, 0x0000 }, /* R764 */ - { 0x0000, 0x0000 }, /* R765 */ - { 0x0000, 0x0000 }, /* R766 */ - { 0x0000, 0x0000 }, /* R767 */ - { 0xE1F8, 0xE1F8 }, /* R768 - AIF1 Control (1) */ - { 0xCD1F, 0xCD1F }, /* R769 - AIF1 Control (2) */ - { 0xF000, 0xF000 }, /* R770 - AIF1 Master/Slave */ - { 0x01F0, 0x01F0 }, /* R771 - AIF1 BCLK */ - { 0x0FFF, 0x0FFF }, /* R772 - AIF1ADC LRCLK */ - { 0x0FFF, 0x0FFF }, /* R773 - AIF1DAC LRCLK */ - { 0x0003, 0x0003 }, /* R774 - AIF1DAC Data */ - { 0x0003, 0x0003 }, /* R775 - AIF1ADC Data */ - { 0x0000, 0x0000 }, /* R776 */ - { 0x0000, 0x0000 }, /* R777 */ - { 0x0000, 0x0000 }, /* R778 */ - { 0x0000, 0x0000 }, /* R779 */ - { 0x0000, 0x0000 }, /* R780 */ - { 0x0000, 0x0000 }, /* R781 */ - { 0x0000, 0x0000 }, /* R782 */ - { 0x0000, 0x0000 }, /* R783 */ - { 0xF1F8, 0xF1F8 }, /* R784 - AIF2 Control (1) */ - { 0xFD1F, 0xFD1F }, /* R785 - AIF2 Control (2) */ - { 0xF000, 0xF000 }, /* R786 - AIF2 Master/Slave */ - { 0x01F0, 0x01F0 }, /* R787 - AIF2 BCLK */ - { 0x0FFF, 0x0FFF }, /* R788 - AIF2ADC LRCLK */ - { 0x0FFF, 0x0FFF }, /* R789 - AIF2DAC LRCLK */ - { 0x0003, 0x0003 }, /* R790 - AIF2DAC Data */ - { 0x0003, 0x0003 }, /* R791 - AIF2ADC Data */ - { 0x0000, 0x0000 }, /* R792 */ - { 0x0000, 0x0000 }, /* R793 */ - { 0x0000, 0x0000 }, /* R794 */ - { 0x0000, 0x0000 }, /* R795 */ - { 0x0000, 0x0000 }, /* R796 */ - { 0x0000, 0x0000 }, /* R797 */ - { 0x0000, 0x0000 }, /* R798 */ - { 0x0000, 0x0000 }, /* R799 */ - { 0x0000, 0x0000 }, /* R800 */ - { 0x0000, 0x0000 }, /* R801 */ - { 0x0000, 0x0000 }, /* R802 */ - { 0x0000, 0x0000 }, /* R803 */ - { 0x0000, 0x0000 }, /* R804 */ - { 0x0000, 0x0000 }, /* R805 */ - { 0x0000, 0x0000 }, /* R806 */ - { 0x0000, 0x0000 }, /* R807 */ - { 0x0000, 0x0000 }, /* R808 */ - { 0x0000, 0x0000 }, /* R809 */ - { 0x0000, 0x0000 }, /* R810 */ - { 0x0000, 0x0000 }, /* R811 */ - { 0x0000, 0x0000 }, /* R812 */ - { 0x0000, 0x0000 }, /* R813 */ - { 0x0000, 0x0000 }, /* R814 */ - { 0x0000, 0x0000 }, /* R815 */ - { 0x0000, 0x0000 }, /* R816 */ - { 0x0000, 0x0000 }, /* R817 */ - { 0x0000, 0x0000 }, /* R818 */ - { 0x0000, 0x0000 }, /* R819 */ - { 0x0000, 0x0000 }, /* R820 */ - { 0x0000, 0x0000 }, /* R821 */ - { 0x0000, 0x0000 }, /* R822 */ - { 0x0000, 0x0000 }, /* R823 */ - { 0x0000, 0x0000 }, /* R824 */ - { 0x0000, 0x0000 }, /* R825 */ - { 0x0000, 0x0000 }, /* R826 */ - { 0x0000, 0x0000 }, /* R827 */ - { 0x0000, 0x0000 }, /* R828 */ - { 0x0000, 0x0000 }, /* R829 */ - { 0x0000, 0x0000 }, /* R830 */ - { 0x0000, 0x0000 }, /* R831 */ - { 0x0000, 0x0000 }, /* R832 */ - { 0x0000, 0x0000 }, /* R833 */ - { 0x0000, 0x0000 }, /* R834 */ - { 0x0000, 0x0000 }, /* R835 */ - { 0x0000, 0x0000 }, /* R836 */ - { 0x0000, 0x0000 }, /* R837 */ - { 0x0000, 0x0000 }, /* R838 */ - { 0x0000, 0x0000 }, /* R839 */ - { 0x0000, 0x0000 }, /* R840 */ - { 0x0000, 0x0000 }, /* R841 */ - { 0x0000, 0x0000 }, /* R842 */ - { 0x0000, 0x0000 }, /* R843 */ - { 0x0000, 0x0000 }, /* R844 */ - { 0x0000, 0x0000 }, /* R845 */ - { 0x0000, 0x0000 }, /* R846 */ - { 0x0000, 0x0000 }, /* R847 */ - { 0x0000, 0x0000 }, /* R848 */ - { 0x0000, 0x0000 }, /* R849 */ - { 0x0000, 0x0000 }, /* R850 */ - { 0x0000, 0x0000 }, /* R851 */ - { 0x0000, 0x0000 }, /* R852 */ - { 0x0000, 0x0000 }, /* R853 */ - { 0x0000, 0x0000 }, /* R854 */ - { 0x0000, 0x0000 }, /* R855 */ - { 0x0000, 0x0000 }, /* R856 */ - { 0x0000, 0x0000 }, /* R857 */ - { 0x0000, 0x0000 }, /* R858 */ - { 0x0000, 0x0000 }, /* R859 */ - { 0x0000, 0x0000 }, /* R860 */ - { 0x0000, 0x0000 }, /* R861 */ - { 0x0000, 0x0000 }, /* R862 */ - { 0x0000, 0x0000 }, /* R863 */ - { 0x0000, 0x0000 }, /* R864 */ - { 0x0000, 0x0000 }, /* R865 */ - { 0x0000, 0x0000 }, /* R866 */ - { 0x0000, 0x0000 }, /* R867 */ - { 0x0000, 0x0000 }, /* R868 */ - { 0x0000, 0x0000 }, /* R869 */ - { 0x0000, 0x0000 }, /* R870 */ - { 0x0000, 0x0000 }, /* R871 */ - { 0x0000, 0x0000 }, /* R872 */ - { 0x0000, 0x0000 }, /* R873 */ - { 0x0000, 0x0000 }, /* R874 */ - { 0x0000, 0x0000 }, /* R875 */ - { 0x0000, 0x0000 }, /* R876 */ - { 0x0000, 0x0000 }, /* R877 */ - { 0x0000, 0x0000 }, /* R878 */ - { 0x0000, 0x0000 }, /* R879 */ - { 0x0000, 0x0000 }, /* R880 */ - { 0x0000, 0x0000 }, /* R881 */ - { 0x0000, 0x0000 }, /* R882 */ - { 0x0000, 0x0000 }, /* R883 */ - { 0x0000, 0x0000 }, /* R884 */ - { 0x0000, 0x0000 }, /* R885 */ - { 0x0000, 0x0000 }, /* R886 */ - { 0x0000, 0x0000 }, /* R887 */ - { 0x0000, 0x0000 }, /* R888 */ - { 0x0000, 0x0000 }, /* R889 */ - { 0x0000, 0x0000 }, /* R890 */ - { 0x0000, 0x0000 }, /* R891 */ - { 0x0000, 0x0000 }, /* R892 */ - { 0x0000, 0x0000 }, /* R893 */ - { 0x0000, 0x0000 }, /* R894 */ - { 0x0000, 0x0000 }, /* R895 */ - { 0x0000, 0x0000 }, /* R896 */ - { 0x0000, 0x0000 }, /* R897 */ - { 0x0000, 0x0000 }, /* R898 */ - { 0x0000, 0x0000 }, /* R899 */ - { 0x0000, 0x0000 }, /* R900 */ - { 0x0000, 0x0000 }, /* R901 */ - { 0x0000, 0x0000 }, /* R902 */ - { 0x0000, 0x0000 }, /* R903 */ - { 0x0000, 0x0000 }, /* R904 */ - { 0x0000, 0x0000 }, /* R905 */ - { 0x0000, 0x0000 }, /* R906 */ - { 0x0000, 0x0000 }, /* R907 */ - { 0x0000, 0x0000 }, /* R908 */ - { 0x0000, 0x0000 }, /* R909 */ - { 0x0000, 0x0000 }, /* R910 */ - { 0x0000, 0x0000 }, /* R911 */ - { 0x0000, 0x0000 }, /* R912 */ - { 0x0000, 0x0000 }, /* R913 */ - { 0x0000, 0x0000 }, /* R914 */ - { 0x0000, 0x0000 }, /* R915 */ - { 0x0000, 0x0000 }, /* R916 */ - { 0x0000, 0x0000 }, /* R917 */ - { 0x0000, 0x0000 }, /* R918 */ - { 0x0000, 0x0000 }, /* R919 */ - { 0x0000, 0x0000 }, /* R920 */ - { 0x0000, 0x0000 }, /* R921 */ - { 0x0000, 0x0000 }, /* R922 */ - { 0x0000, 0x0000 }, /* R923 */ - { 0x0000, 0x0000 }, /* R924 */ - { 0x0000, 0x0000 }, /* R925 */ - { 0x0000, 0x0000 }, /* R926 */ - { 0x0000, 0x0000 }, /* R927 */ - { 0x0000, 0x0000 }, /* R928 */ - { 0x0000, 0x0000 }, /* R929 */ - { 0x0000, 0x0000 }, /* R930 */ - { 0x0000, 0x0000 }, /* R931 */ - { 0x0000, 0x0000 }, /* R932 */ - { 0x0000, 0x0000 }, /* R933 */ - { 0x0000, 0x0000 }, /* R934 */ - { 0x0000, 0x0000 }, /* R935 */ - { 0x0000, 0x0000 }, /* R936 */ - { 0x0000, 0x0000 }, /* R937 */ - { 0x0000, 0x0000 }, /* R938 */ - { 0x0000, 0x0000 }, /* R939 */ - { 0x0000, 0x0000 }, /* R940 */ - { 0x0000, 0x0000 }, /* R941 */ - { 0x0000, 0x0000 }, /* R942 */ - { 0x0000, 0x0000 }, /* R943 */ - { 0x0000, 0x0000 }, /* R944 */ - { 0x0000, 0x0000 }, /* R945 */ - { 0x0000, 0x0000 }, /* R946 */ - { 0x0000, 0x0000 }, /* R947 */ - { 0x0000, 0x0000 }, /* R948 */ - { 0x0000, 0x0000 }, /* R949 */ - { 0x0000, 0x0000 }, /* R950 */ - { 0x0000, 0x0000 }, /* R951 */ - { 0x0000, 0x0000 }, /* R952 */ - { 0x0000, 0x0000 }, /* R953 */ - { 0x0000, 0x0000 }, /* R954 */ - { 0x0000, 0x0000 }, /* R955 */ - { 0x0000, 0x0000 }, /* R956 */ - { 0x0000, 0x0000 }, /* R957 */ - { 0x0000, 0x0000 }, /* R958 */ - { 0x0000, 0x0000 }, /* R959 */ - { 0x0000, 0x0000 }, /* R960 */ - { 0x0000, 0x0000 }, /* R961 */ - { 0x0000, 0x0000 }, /* R962 */ - { 0x0000, 0x0000 }, /* R963 */ - { 0x0000, 0x0000 }, /* R964 */ - { 0x0000, 0x0000 }, /* R965 */ - { 0x0000, 0x0000 }, /* R966 */ - { 0x0000, 0x0000 }, /* R967 */ - { 0x0000, 0x0000 }, /* R968 */ - { 0x0000, 0x0000 }, /* R969 */ - { 0x0000, 0x0000 }, /* R970 */ - { 0x0000, 0x0000 }, /* R971 */ - { 0x0000, 0x0000 }, /* R972 */ - { 0x0000, 0x0000 }, /* R973 */ - { 0x0000, 0x0000 }, /* R974 */ - { 0x0000, 0x0000 }, /* R975 */ - { 0x0000, 0x0000 }, /* R976 */ - { 0x0000, 0x0000 }, /* R977 */ - { 0x0000, 0x0000 }, /* R978 */ - { 0x0000, 0x0000 }, /* R979 */ - { 0x0000, 0x0000 }, /* R980 */ - { 0x0000, 0x0000 }, /* R981 */ - { 0x0000, 0x0000 }, /* R982 */ - { 0x0000, 0x0000 }, /* R983 */ - { 0x0000, 0x0000 }, /* R984 */ - { 0x0000, 0x0000 }, /* R985 */ - { 0x0000, 0x0000 }, /* R986 */ - { 0x0000, 0x0000 }, /* R987 */ - { 0x0000, 0x0000 }, /* R988 */ - { 0x0000, 0x0000 }, /* R989 */ - { 0x0000, 0x0000 }, /* R990 */ - { 0x0000, 0x0000 }, /* R991 */ - { 0x0000, 0x0000 }, /* R992 */ - { 0x0000, 0x0000 }, /* R993 */ - { 0x0000, 0x0000 }, /* R994 */ - { 0x0000, 0x0000 }, /* R995 */ - { 0x0000, 0x0000 }, /* R996 */ - { 0x0000, 0x0000 }, /* R997 */ - { 0x0000, 0x0000 }, /* R998 */ - { 0x0000, 0x0000 }, /* R999 */ - { 0x0000, 0x0000 }, /* R1000 */ - { 0x0000, 0x0000 }, /* R1001 */ - { 0x0000, 0x0000 }, /* R1002 */ - { 0x0000, 0x0000 }, /* R1003 */ - { 0x0000, 0x0000 }, /* R1004 */ - { 0x0000, 0x0000 }, /* R1005 */ - { 0x0000, 0x0000 }, /* R1006 */ - { 0x0000, 0x0000 }, /* R1007 */ - { 0x0000, 0x0000 }, /* R1008 */ - { 0x0000, 0x0000 }, /* R1009 */ - { 0x0000, 0x0000 }, /* R1010 */ - { 0x0000, 0x0000 }, /* R1011 */ - { 0x0000, 0x0000 }, /* R1012 */ - { 0x0000, 0x0000 }, /* R1013 */ - { 0x0000, 0x0000 }, /* R1014 */ - { 0x0000, 0x0000 }, /* R1015 */ - { 0x0000, 0x0000 }, /* R1016 */ - { 0x0000, 0x0000 }, /* R1017 */ - { 0x0000, 0x0000 }, /* R1018 */ - { 0x0000, 0x0000 }, /* R1019 */ - { 0x0000, 0x0000 }, /* R1020 */ - { 0x0000, 0x0000 }, /* R1021 */ - { 0x0000, 0x0000 }, /* R1022 */ - { 0x0000, 0x0000 }, /* R1023 */ - { 0x00FF, 0x01FF }, /* R1024 - AIF1 ADC1 Left Volume */ - { 0x00FF, 0x01FF }, /* R1025 - AIF1 ADC1 Right Volume */ - { 0x00FF, 0x01FF }, /* R1026 - AIF1 DAC1 Left Volume */ - { 0x00FF, 0x01FF }, /* R1027 - AIF1 DAC1 Right Volume */ - { 0x00FF, 0x01FF }, /* R1028 - AIF1 ADC2 Left Volume */ - { 0x00FF, 0x01FF }, /* R1029 - AIF1 ADC2 Right Volume */ - { 0x00FF, 0x01FF }, /* R1030 - AIF1 DAC2 Left Volume */ - { 0x00FF, 0x01FF }, /* R1031 - AIF1 DAC2 Right Volume */ - { 0x0000, 0x0000 }, /* R1032 */ - { 0x0000, 0x0000 }, /* R1033 */ - { 0x0000, 0x0000 }, /* R1034 */ - { 0x0000, 0x0000 }, /* R1035 */ - { 0x0000, 0x0000 }, /* R1036 */ - { 0x0000, 0x0000 }, /* R1037 */ - { 0x0000, 0x0000 }, /* R1038 */ - { 0x0000, 0x0000 }, /* R1039 */ - { 0xF800, 0xF800 }, /* R1040 - AIF1 ADC1 Filters */ - { 0x7800, 0x7800 }, /* R1041 - AIF1 ADC2 Filters */ - { 0x0000, 0x0000 }, /* R1042 */ - { 0x0000, 0x0000 }, /* R1043 */ - { 0x0000, 0x0000 }, /* R1044 */ - { 0x0000, 0x0000 }, /* R1045 */ - { 0x0000, 0x0000 }, /* R1046 */ - { 0x0000, 0x0000 }, /* R1047 */ - { 0x0000, 0x0000 }, /* R1048 */ - { 0x0000, 0x0000 }, /* R1049 */ - { 0x0000, 0x0000 }, /* R1050 */ - { 0x0000, 0x0000 }, /* R1051 */ - { 0x0000, 0x0000 }, /* R1052 */ - { 0x0000, 0x0000 }, /* R1053 */ - { 0x0000, 0x0000 }, /* R1054 */ - { 0x0000, 0x0000 }, /* R1055 */ - { 0x02B6, 0x02B6 }, /* R1056 - AIF1 DAC1 Filters (1) */ - { 0x3F00, 0x3F00 }, /* R1057 - AIF1 DAC1 Filters (2) */ - { 0x02B6, 0x02B6 }, /* R1058 - AIF1 DAC2 Filters (1) */ - { 0x3F00, 0x3F00 }, /* R1059 - AIF1 DAC2 Filters (2) */ - { 0x0000, 0x0000 }, /* R1060 */ - { 0x0000, 0x0000 }, /* R1061 */ - { 0x0000, 0x0000 }, /* R1062 */ - { 0x0000, 0x0000 }, /* R1063 */ - { 0x0000, 0x0000 }, /* R1064 */ - { 0x0000, 0x0000 }, /* R1065 */ - { 0x0000, 0x0000 }, /* R1066 */ - { 0x0000, 0x0000 }, /* R1067 */ - { 0x0000, 0x0000 }, /* R1068 */ - { 0x0000, 0x0000 }, /* R1069 */ - { 0x0000, 0x0000 }, /* R1070 */ - { 0x0000, 0x0000 }, /* R1071 */ - { 0x0000, 0x0000 }, /* R1072 */ - { 0x0000, 0x0000 }, /* R1073 */ - { 0x0000, 0x0000 }, /* R1074 */ - { 0x0000, 0x0000 }, /* R1075 */ - { 0x0000, 0x0000 }, /* R1076 */ - { 0x0000, 0x0000 }, /* R1077 */ - { 0x0000, 0x0000 }, /* R1078 */ - { 0x0000, 0x0000 }, /* R1079 */ - { 0x0000, 0x0000 }, /* R1080 */ - { 0x0000, 0x0000 }, /* R1081 */ - { 0x0000, 0x0000 }, /* R1082 */ - { 0x0000, 0x0000 }, /* R1083 */ - { 0x0000, 0x0000 }, /* R1084 */ - { 0x0000, 0x0000 }, /* R1085 */ - { 0x0000, 0x0000 }, /* R1086 */ - { 0x0000, 0x0000 }, /* R1087 */ - { 0xFFFF, 0xFFFF }, /* R1088 - AIF1 DRC1 (1) */ - { 0x1FFF, 0x1FFF }, /* R1089 - AIF1 DRC1 (2) */ - { 0xFFFF, 0xFFFF }, /* R1090 - AIF1 DRC1 (3) */ - { 0x07FF, 0x07FF }, /* R1091 - AIF1 DRC1 (4) */ - { 0x03FF, 0x03FF }, /* R1092 - AIF1 DRC1 (5) */ - { 0x0000, 0x0000 }, /* R1093 */ - { 0x0000, 0x0000 }, /* R1094 */ - { 0x0000, 0x0000 }, /* R1095 */ - { 0x0000, 0x0000 }, /* R1096 */ - { 0x0000, 0x0000 }, /* R1097 */ - { 0x0000, 0x0000 }, /* R1098 */ - { 0x0000, 0x0000 }, /* R1099 */ - { 0x0000, 0x0000 }, /* R1100 */ - { 0x0000, 0x0000 }, /* R1101 */ - { 0x0000, 0x0000 }, /* R1102 */ - { 0x0000, 0x0000 }, /* R1103 */ - { 0xFFFF, 0xFFFF }, /* R1104 - AIF1 DRC2 (1) */ - { 0x1FFF, 0x1FFF }, /* R1105 - AIF1 DRC2 (2) */ - { 0xFFFF, 0xFFFF }, /* R1106 - AIF1 DRC2 (3) */ - { 0x07FF, 0x07FF }, /* R1107 - AIF1 DRC2 (4) */ - { 0x03FF, 0x03FF }, /* R1108 - AIF1 DRC2 (5) */ - { 0x0000, 0x0000 }, /* R1109 */ - { 0x0000, 0x0000 }, /* R1110 */ - { 0x0000, 0x0000 }, /* R1111 */ - { 0x0000, 0x0000 }, /* R1112 */ - { 0x0000, 0x0000 }, /* R1113 */ - { 0x0000, 0x0000 }, /* R1114 */ - { 0x0000, 0x0000 }, /* R1115 */ - { 0x0000, 0x0000 }, /* R1116 */ - { 0x0000, 0x0000 }, /* R1117 */ - { 0x0000, 0x0000 }, /* R1118 */ - { 0x0000, 0x0000 }, /* R1119 */ - { 0x0000, 0x0000 }, /* R1120 */ - { 0x0000, 0x0000 }, /* R1121 */ - { 0x0000, 0x0000 }, /* R1122 */ - { 0x0000, 0x0000 }, /* R1123 */ - { 0x0000, 0x0000 }, /* R1124 */ - { 0x0000, 0x0000 }, /* R1125 */ - { 0x0000, 0x0000 }, /* R1126 */ - { 0x0000, 0x0000 }, /* R1127 */ - { 0x0000, 0x0000 }, /* R1128 */ - { 0x0000, 0x0000 }, /* R1129 */ - { 0x0000, 0x0000 }, /* R1130 */ - { 0x0000, 0x0000 }, /* R1131 */ - { 0x0000, 0x0000 }, /* R1132 */ - { 0x0000, 0x0000 }, /* R1133 */ - { 0x0000, 0x0000 }, /* R1134 */ - { 0x0000, 0x0000 }, /* R1135 */ - { 0x0000, 0x0000 }, /* R1136 */ - { 0x0000, 0x0000 }, /* R1137 */ - { 0x0000, 0x0000 }, /* R1138 */ - { 0x0000, 0x0000 }, /* R1139 */ - { 0x0000, 0x0000 }, /* R1140 */ - { 0x0000, 0x0000 }, /* R1141 */ - { 0x0000, 0x0000 }, /* R1142 */ - { 0x0000, 0x0000 }, /* R1143 */ - { 0x0000, 0x0000 }, /* R1144 */ - { 0x0000, 0x0000 }, /* R1145 */ - { 0x0000, 0x0000 }, /* R1146 */ - { 0x0000, 0x0000 }, /* R1147 */ - { 0x0000, 0x0000 }, /* R1148 */ - { 0x0000, 0x0000 }, /* R1149 */ - { 0x0000, 0x0000 }, /* R1150 */ - { 0x0000, 0x0000 }, /* R1151 */ - { 0xFFFF, 0xFFFF }, /* R1152 - AIF1 DAC1 EQ Gains (1) */ - { 0xFFC0, 0xFFC0 }, /* R1153 - AIF1 DAC1 EQ Gains (2) */ - { 0xFFFF, 0xFFFF }, /* R1154 - AIF1 DAC1 EQ Band 1 A */ - { 0xFFFF, 0xFFFF }, /* R1155 - AIF1 DAC1 EQ Band 1 B */ - { 0xFFFF, 0xFFFF }, /* R1156 - AIF1 DAC1 EQ Band 1 PG */ - { 0xFFFF, 0xFFFF }, /* R1157 - AIF1 DAC1 EQ Band 2 A */ - { 0xFFFF, 0xFFFF }, /* R1158 - AIF1 DAC1 EQ Band 2 B */ - { 0xFFFF, 0xFFFF }, /* R1159 - AIF1 DAC1 EQ Band 2 C */ - { 0xFFFF, 0xFFFF }, /* R1160 - AIF1 DAC1 EQ Band 2 PG */ - { 0xFFFF, 0xFFFF }, /* R1161 - AIF1 DAC1 EQ Band 3 A */ - { 0xFFFF, 0xFFFF }, /* R1162 - AIF1 DAC1 EQ Band 3 B */ - { 0xFFFF, 0xFFFF }, /* R1163 - AIF1 DAC1 EQ Band 3 C */ - { 0xFFFF, 0xFFFF }, /* R1164 - AIF1 DAC1 EQ Band 3 PG */ - { 0xFFFF, 0xFFFF }, /* R1165 - AIF1 DAC1 EQ Band 4 A */ - { 0xFFFF, 0xFFFF }, /* R1166 - AIF1 DAC1 EQ Band 4 B */ - { 0xFFFF, 0xFFFF }, /* R1167 - AIF1 DAC1 EQ Band 4 C */ - { 0xFFFF, 0xFFFF }, /* R1168 - AIF1 DAC1 EQ Band 4 PG */ - { 0xFFFF, 0xFFFF }, /* R1169 - AIF1 DAC1 EQ Band 5 A */ - { 0xFFFF, 0xFFFF }, /* R1170 - AIF1 DAC1 EQ Band 5 B */ - { 0xFFFF, 0xFFFF }, /* R1171 - AIF1 DAC1 EQ Band 5 PG */ - { 0x0000, 0x0000 }, /* R1172 */ - { 0x0000, 0x0000 }, /* R1173 */ - { 0x0000, 0x0000 }, /* R1174 */ - { 0x0000, 0x0000 }, /* R1175 */ - { 0x0000, 0x0000 }, /* R1176 */ - { 0x0000, 0x0000 }, /* R1177 */ - { 0x0000, 0x0000 }, /* R1178 */ - { 0x0000, 0x0000 }, /* R1179 */ - { 0x0000, 0x0000 }, /* R1180 */ - { 0x0000, 0x0000 }, /* R1181 */ - { 0x0000, 0x0000 }, /* R1182 */ - { 0x0000, 0x0000 }, /* R1183 */ - { 0xFFFF, 0xFFFF }, /* R1184 - AIF1 DAC2 EQ Gains (1) */ - { 0xFFC0, 0xFFC0 }, /* R1185 - AIF1 DAC2 EQ Gains (2) */ - { 0xFFFF, 0xFFFF }, /* R1186 - AIF1 DAC2 EQ Band 1 A */ - { 0xFFFF, 0xFFFF }, /* R1187 - AIF1 DAC2 EQ Band 1 B */ - { 0xFFFF, 0xFFFF }, /* R1188 - AIF1 DAC2 EQ Band 1 PG */ - { 0xFFFF, 0xFFFF }, /* R1189 - AIF1 DAC2 EQ Band 2 A */ - { 0xFFFF, 0xFFFF }, /* R1190 - AIF1 DAC2 EQ Band 2 B */ - { 0xFFFF, 0xFFFF }, /* R1191 - AIF1 DAC2 EQ Band 2 C */ - { 0xFFFF, 0xFFFF }, /* R1192 - AIF1 DAC2 EQ Band 2 PG */ - { 0xFFFF, 0xFFFF }, /* R1193 - AIF1 DAC2 EQ Band 3 A */ - { 0xFFFF, 0xFFFF }, /* R1194 - AIF1 DAC2 EQ Band 3 B */ - { 0xFFFF, 0xFFFF }, /* R1195 - AIF1 DAC2 EQ Band 3 C */ - { 0xFFFF, 0xFFFF }, /* R1196 - AIF1 DAC2 EQ Band 3 PG */ - { 0xFFFF, 0xFFFF }, /* R1197 - AIF1 DAC2 EQ Band 4 A */ - { 0xFFFF, 0xFFFF }, /* R1198 - AIF1 DAC2 EQ Band 4 B */ - { 0xFFFF, 0xFFFF }, /* R1199 - AIF1 DAC2 EQ Band 4 C */ - { 0xFFFF, 0xFFFF }, /* R1200 - AIF1 DAC2 EQ Band 4 PG */ - { 0xFFFF, 0xFFFF }, /* R1201 - AIF1 DAC2 EQ Band 5 A */ - { 0xFFFF, 0xFFFF }, /* R1202 - AIF1 DAC2 EQ Band 5 B */ - { 0xFFFF, 0xFFFF }, /* R1203 - AIF1 DAC2 EQ Band 5 PG */ - { 0x0000, 0x0000 }, /* R1204 */ - { 0x0000, 0x0000 }, /* R1205 */ - { 0x0000, 0x0000 }, /* R1206 */ - { 0x0000, 0x0000 }, /* R1207 */ - { 0x0000, 0x0000 }, /* R1208 */ - { 0x0000, 0x0000 }, /* R1209 */ - { 0x0000, 0x0000 }, /* R1210 */ - { 0x0000, 0x0000 }, /* R1211 */ - { 0x0000, 0x0000 }, /* R1212 */ - { 0x0000, 0x0000 }, /* R1213 */ - { 0x0000, 0x0000 }, /* R1214 */ - { 0x0000, 0x0000 }, /* R1215 */ - { 0x0000, 0x0000 }, /* R1216 */ - { 0x0000, 0x0000 }, /* R1217 */ - { 0x0000, 0x0000 }, /* R1218 */ - { 0x0000, 0x0000 }, /* R1219 */ - { 0x0000, 0x0000 }, /* R1220 */ - { 0x0000, 0x0000 }, /* R1221 */ - { 0x0000, 0x0000 }, /* R1222 */ - { 0x0000, 0x0000 }, /* R1223 */ - { 0x0000, 0x0000 }, /* R1224 */ - { 0x0000, 0x0000 }, /* R1225 */ - { 0x0000, 0x0000 }, /* R1226 */ - { 0x0000, 0x0000 }, /* R1227 */ - { 0x0000, 0x0000 }, /* R1228 */ - { 0x0000, 0x0000 }, /* R1229 */ - { 0x0000, 0x0000 }, /* R1230 */ - { 0x0000, 0x0000 }, /* R1231 */ - { 0x0000, 0x0000 }, /* R1232 */ - { 0x0000, 0x0000 }, /* R1233 */ - { 0x0000, 0x0000 }, /* R1234 */ - { 0x0000, 0x0000 }, /* R1235 */ - { 0x0000, 0x0000 }, /* R1236 */ - { 0x0000, 0x0000 }, /* R1237 */ - { 0x0000, 0x0000 }, /* R1238 */ - { 0x0000, 0x0000 }, /* R1239 */ - { 0x0000, 0x0000 }, /* R1240 */ - { 0x0000, 0x0000 }, /* R1241 */ - { 0x0000, 0x0000 }, /* R1242 */ - { 0x0000, 0x0000 }, /* R1243 */ - { 0x0000, 0x0000 }, /* R1244 */ - { 0x0000, 0x0000 }, /* R1245 */ - { 0x0000, 0x0000 }, /* R1246 */ - { 0x0000, 0x0000 }, /* R1247 */ - { 0x0000, 0x0000 }, /* R1248 */ - { 0x0000, 0x0000 }, /* R1249 */ - { 0x0000, 0x0000 }, /* R1250 */ - { 0x0000, 0x0000 }, /* R1251 */ - { 0x0000, 0x0000 }, /* R1252 */ - { 0x0000, 0x0000 }, /* R1253 */ - { 0x0000, 0x0000 }, /* R1254 */ - { 0x0000, 0x0000 }, /* R1255 */ - { 0x0000, 0x0000 }, /* R1256 */ - { 0x0000, 0x0000 }, /* R1257 */ - { 0x0000, 0x0000 }, /* R1258 */ - { 0x0000, 0x0000 }, /* R1259 */ - { 0x0000, 0x0000 }, /* R1260 */ - { 0x0000, 0x0000 }, /* R1261 */ - { 0x0000, 0x0000 }, /* R1262 */ - { 0x0000, 0x0000 }, /* R1263 */ - { 0x0000, 0x0000 }, /* R1264 */ - { 0x0000, 0x0000 }, /* R1265 */ - { 0x0000, 0x0000 }, /* R1266 */ - { 0x0000, 0x0000 }, /* R1267 */ - { 0x0000, 0x0000 }, /* R1268 */ - { 0x0000, 0x0000 }, /* R1269 */ - { 0x0000, 0x0000 }, /* R1270 */ - { 0x0000, 0x0000 }, /* R1271 */ - { 0x0000, 0x0000 }, /* R1272 */ - { 0x0000, 0x0000 }, /* R1273 */ - { 0x0000, 0x0000 }, /* R1274 */ - { 0x0000, 0x0000 }, /* R1275 */ - { 0x0000, 0x0000 }, /* R1276 */ - { 0x0000, 0x0000 }, /* R1277 */ - { 0x0000, 0x0000 }, /* R1278 */ - { 0x0000, 0x0000 }, /* R1279 */ - { 0x00FF, 0x01FF }, /* R1280 - AIF2 ADC Left Volume */ - { 0x00FF, 0x01FF }, /* R1281 - AIF2 ADC Right Volume */ - { 0x00FF, 0x01FF }, /* R1282 - AIF2 DAC Left Volume */ - { 0x00FF, 0x01FF }, /* R1283 - AIF2 DAC Right Volume */ - { 0x0000, 0x0000 }, /* R1284 */ - { 0x0000, 0x0000 }, /* R1285 */ - { 0x0000, 0x0000 }, /* R1286 */ - { 0x0000, 0x0000 }, /* R1287 */ - { 0x0000, 0x0000 }, /* R1288 */ - { 0x0000, 0x0000 }, /* R1289 */ - { 0x0000, 0x0000 }, /* R1290 */ - { 0x0000, 0x0000 }, /* R1291 */ - { 0x0000, 0x0000 }, /* R1292 */ - { 0x0000, 0x0000 }, /* R1293 */ - { 0x0000, 0x0000 }, /* R1294 */ - { 0x0000, 0x0000 }, /* R1295 */ - { 0xF800, 0xF800 }, /* R1296 - AIF2 ADC Filters */ - { 0x0000, 0x0000 }, /* R1297 */ - { 0x0000, 0x0000 }, /* R1298 */ - { 0x0000, 0x0000 }, /* R1299 */ - { 0x0000, 0x0000 }, /* R1300 */ - { 0x0000, 0x0000 }, /* R1301 */ - { 0x0000, 0x0000 }, /* R1302 */ - { 0x0000, 0x0000 }, /* R1303 */ - { 0x0000, 0x0000 }, /* R1304 */ - { 0x0000, 0x0000 }, /* R1305 */ - { 0x0000, 0x0000 }, /* R1306 */ - { 0x0000, 0x0000 }, /* R1307 */ - { 0x0000, 0x0000 }, /* R1308 */ - { 0x0000, 0x0000 }, /* R1309 */ - { 0x0000, 0x0000 }, /* R1310 */ - { 0x0000, 0x0000 }, /* R1311 */ - { 0x02B6, 0x02B6 }, /* R1312 - AIF2 DAC Filters (1) */ - { 0x3F00, 0x3F00 }, /* R1313 - AIF2 DAC Filters (2) */ - { 0x0000, 0x0000 }, /* R1314 */ - { 0x0000, 0x0000 }, /* R1315 */ - { 0x0000, 0x0000 }, /* R1316 */ - { 0x0000, 0x0000 }, /* R1317 */ - { 0x0000, 0x0000 }, /* R1318 */ - { 0x0000, 0x0000 }, /* R1319 */ - { 0x0000, 0x0000 }, /* R1320 */ - { 0x0000, 0x0000 }, /* R1321 */ - { 0x0000, 0x0000 }, /* R1322 */ - { 0x0000, 0x0000 }, /* R1323 */ - { 0x0000, 0x0000 }, /* R1324 */ - { 0x0000, 0x0000 }, /* R1325 */ - { 0x0000, 0x0000 }, /* R1326 */ - { 0x0000, 0x0000 }, /* R1327 */ - { 0x0000, 0x0000 }, /* R1328 */ - { 0x0000, 0x0000 }, /* R1329 */ - { 0x0000, 0x0000 }, /* R1330 */ - { 0x0000, 0x0000 }, /* R1331 */ - { 0x0000, 0x0000 }, /* R1332 */ - { 0x0000, 0x0000 }, /* R1333 */ - { 0x0000, 0x0000 }, /* R1334 */ - { 0x0000, 0x0000 }, /* R1335 */ - { 0x0000, 0x0000 }, /* R1336 */ - { 0x0000, 0x0000 }, /* R1337 */ - { 0x0000, 0x0000 }, /* R1338 */ - { 0x0000, 0x0000 }, /* R1339 */ - { 0x0000, 0x0000 }, /* R1340 */ - { 0x0000, 0x0000 }, /* R1341 */ - { 0x0000, 0x0000 }, /* R1342 */ - { 0x0000, 0x0000 }, /* R1343 */ - { 0xFFFF, 0xFFFF }, /* R1344 - AIF2 DRC (1) */ - { 0x1FFF, 0x1FFF }, /* R1345 - AIF2 DRC (2) */ - { 0xFFFF, 0xFFFF }, /* R1346 - AIF2 DRC (3) */ - { 0x07FF, 0x07FF }, /* R1347 - AIF2 DRC (4) */ - { 0x03FF, 0x03FF }, /* R1348 - AIF2 DRC (5) */ - { 0x0000, 0x0000 }, /* R1349 */ - { 0x0000, 0x0000 }, /* R1350 */ - { 0x0000, 0x0000 }, /* R1351 */ - { 0x0000, 0x0000 }, /* R1352 */ - { 0x0000, 0x0000 }, /* R1353 */ - { 0x0000, 0x0000 }, /* R1354 */ - { 0x0000, 0x0000 }, /* R1355 */ - { 0x0000, 0x0000 }, /* R1356 */ - { 0x0000, 0x0000 }, /* R1357 */ - { 0x0000, 0x0000 }, /* R1358 */ - { 0x0000, 0x0000 }, /* R1359 */ - { 0x0000, 0x0000 }, /* R1360 */ - { 0x0000, 0x0000 }, /* R1361 */ - { 0x0000, 0x0000 }, /* R1362 */ - { 0x0000, 0x0000 }, /* R1363 */ - { 0x0000, 0x0000 }, /* R1364 */ - { 0x0000, 0x0000 }, /* R1365 */ - { 0x0000, 0x0000 }, /* R1366 */ - { 0x0000, 0x0000 }, /* R1367 */ - { 0x0000, 0x0000 }, /* R1368 */ - { 0x0000, 0x0000 }, /* R1369 */ - { 0x0000, 0x0000 }, /* R1370 */ - { 0x0000, 0x0000 }, /* R1371 */ - { 0x0000, 0x0000 }, /* R1372 */ - { 0x0000, 0x0000 }, /* R1373 */ - { 0x0000, 0x0000 }, /* R1374 */ - { 0x0000, 0x0000 }, /* R1375 */ - { 0x0000, 0x0000 }, /* R1376 */ - { 0x0000, 0x0000 }, /* R1377 */ - { 0x0000, 0x0000 }, /* R1378 */ - { 0x0000, 0x0000 }, /* R1379 */ - { 0x0000, 0x0000 }, /* R1380 */ - { 0x0000, 0x0000 }, /* R1381 */ - { 0x0000, 0x0000 }, /* R1382 */ - { 0x0000, 0x0000 }, /* R1383 */ - { 0x0000, 0x0000 }, /* R1384 */ - { 0x0000, 0x0000 }, /* R1385 */ - { 0x0000, 0x0000 }, /* R1386 */ - { 0x0000, 0x0000 }, /* R1387 */ - { 0x0000, 0x0000 }, /* R1388 */ - { 0x0000, 0x0000 }, /* R1389 */ - { 0x0000, 0x0000 }, /* R1390 */ - { 0x0000, 0x0000 }, /* R1391 */ - { 0x0000, 0x0000 }, /* R1392 */ - { 0x0000, 0x0000 }, /* R1393 */ - { 0x0000, 0x0000 }, /* R1394 */ - { 0x0000, 0x0000 }, /* R1395 */ - { 0x0000, 0x0000 }, /* R1396 */ - { 0x0000, 0x0000 }, /* R1397 */ - { 0x0000, 0x0000 }, /* R1398 */ - { 0x0000, 0x0000 }, /* R1399 */ - { 0x0000, 0x0000 }, /* R1400 */ - { 0x0000, 0x0000 }, /* R1401 */ - { 0x0000, 0x0000 }, /* R1402 */ - { 0x0000, 0x0000 }, /* R1403 */ - { 0x0000, 0x0000 }, /* R1404 */ - { 0x0000, 0x0000 }, /* R1405 */ - { 0x0000, 0x0000 }, /* R1406 */ - { 0x0000, 0x0000 }, /* R1407 */ - { 0xFFFF, 0xFFFF }, /* R1408 - AIF2 EQ Gains (1) */ - { 0xFFC0, 0xFFC0 }, /* R1409 - AIF2 EQ Gains (2) */ - { 0xFFFF, 0xFFFF }, /* R1410 - AIF2 EQ Band 1 A */ - { 0xFFFF, 0xFFFF }, /* R1411 - AIF2 EQ Band 1 B */ - { 0xFFFF, 0xFFFF }, /* R1412 - AIF2 EQ Band 1 PG */ - { 0xFFFF, 0xFFFF }, /* R1413 - AIF2 EQ Band 2 A */ - { 0xFFFF, 0xFFFF }, /* R1414 - AIF2 EQ Band 2 B */ - { 0xFFFF, 0xFFFF }, /* R1415 - AIF2 EQ Band 2 C */ - { 0xFFFF, 0xFFFF }, /* R1416 - AIF2 EQ Band 2 PG */ - { 0xFFFF, 0xFFFF }, /* R1417 - AIF2 EQ Band 3 A */ - { 0xFFFF, 0xFFFF }, /* R1418 - AIF2 EQ Band 3 B */ - { 0xFFFF, 0xFFFF }, /* R1419 - AIF2 EQ Band 3 C */ - { 0xFFFF, 0xFFFF }, /* R1420 - AIF2 EQ Band 3 PG */ - { 0xFFFF, 0xFFFF }, /* R1421 - AIF2 EQ Band 4 A */ - { 0xFFFF, 0xFFFF }, /* R1422 - AIF2 EQ Band 4 B */ - { 0xFFFF, 0xFFFF }, /* R1423 - AIF2 EQ Band 4 C */ - { 0xFFFF, 0xFFFF }, /* R1424 - AIF2 EQ Band 4 PG */ - { 0xFFFF, 0xFFFF }, /* R1425 - AIF2 EQ Band 5 A */ - { 0xFFFF, 0xFFFF }, /* R1426 - AIF2 EQ Band 5 B */ - { 0xFFFF, 0xFFFF }, /* R1427 - AIF2 EQ Band 5 PG */ - { 0x0000, 0x0000 }, /* R1428 */ - { 0x0000, 0x0000 }, /* R1429 */ - { 0x0000, 0x0000 }, /* R1430 */ - { 0x0000, 0x0000 }, /* R1431 */ - { 0x0000, 0x0000 }, /* R1432 */ - { 0x0000, 0x0000 }, /* R1433 */ - { 0x0000, 0x0000 }, /* R1434 */ - { 0x0000, 0x0000 }, /* R1435 */ - { 0x0000, 0x0000 }, /* R1436 */ - { 0x0000, 0x0000 }, /* R1437 */ - { 0x0000, 0x0000 }, /* R1438 */ - { 0x0000, 0x0000 }, /* R1439 */ - { 0x0000, 0x0000 }, /* R1440 */ - { 0x0000, 0x0000 }, /* R1441 */ - { 0x0000, 0x0000 }, /* R1442 */ - { 0x0000, 0x0000 }, /* R1443 */ - { 0x0000, 0x0000 }, /* R1444 */ - { 0x0000, 0x0000 }, /* R1445 */ - { 0x0000, 0x0000 }, /* R1446 */ - { 0x0000, 0x0000 }, /* R1447 */ - { 0x0000, 0x0000 }, /* R1448 */ - { 0x0000, 0x0000 }, /* R1449 */ - { 0x0000, 0x0000 }, /* R1450 */ - { 0x0000, 0x0000 }, /* R1451 */ - { 0x0000, 0x0000 }, /* R1452 */ - { 0x0000, 0x0000 }, /* R1453 */ - { 0x0000, 0x0000 }, /* R1454 */ - { 0x0000, 0x0000 }, /* R1455 */ - { 0x0000, 0x0000 }, /* R1456 */ - { 0x0000, 0x0000 }, /* R1457 */ - { 0x0000, 0x0000 }, /* R1458 */ - { 0x0000, 0x0000 }, /* R1459 */ - { 0x0000, 0x0000 }, /* R1460 */ - { 0x0000, 0x0000 }, /* R1461 */ - { 0x0000, 0x0000 }, /* R1462 */ - { 0x0000, 0x0000 }, /* R1463 */ - { 0x0000, 0x0000 }, /* R1464 */ - { 0x0000, 0x0000 }, /* R1465 */ - { 0x0000, 0x0000 }, /* R1466 */ - { 0x0000, 0x0000 }, /* R1467 */ - { 0x0000, 0x0000 }, /* R1468 */ - { 0x0000, 0x0000 }, /* R1469 */ - { 0x0000, 0x0000 }, /* R1470 */ - { 0x0000, 0x0000 }, /* R1471 */ - { 0x0000, 0x0000 }, /* R1472 */ - { 0x0000, 0x0000 }, /* R1473 */ - { 0x0000, 0x0000 }, /* R1474 */ - { 0x0000, 0x0000 }, /* R1475 */ - { 0x0000, 0x0000 }, /* R1476 */ - { 0x0000, 0x0000 }, /* R1477 */ - { 0x0000, 0x0000 }, /* R1478 */ - { 0x0000, 0x0000 }, /* R1479 */ - { 0x0000, 0x0000 }, /* R1480 */ - { 0x0000, 0x0000 }, /* R1481 */ - { 0x0000, 0x0000 }, /* R1482 */ - { 0x0000, 0x0000 }, /* R1483 */ - { 0x0000, 0x0000 }, /* R1484 */ - { 0x0000, 0x0000 }, /* R1485 */ - { 0x0000, 0x0000 }, /* R1486 */ - { 0x0000, 0x0000 }, /* R1487 */ - { 0x0000, 0x0000 }, /* R1488 */ - { 0x0000, 0x0000 }, /* R1489 */ - { 0x0000, 0x0000 }, /* R1490 */ - { 0x0000, 0x0000 }, /* R1491 */ - { 0x0000, 0x0000 }, /* R1492 */ - { 0x0000, 0x0000 }, /* R1493 */ - { 0x0000, 0x0000 }, /* R1494 */ - { 0x0000, 0x0000 }, /* R1495 */ - { 0x0000, 0x0000 }, /* R1496 */ - { 0x0000, 0x0000 }, /* R1497 */ - { 0x0000, 0x0000 }, /* R1498 */ - { 0x0000, 0x0000 }, /* R1499 */ - { 0x0000, 0x0000 }, /* R1500 */ - { 0x0000, 0x0000 }, /* R1501 */ - { 0x0000, 0x0000 }, /* R1502 */ - { 0x0000, 0x0000 }, /* R1503 */ - { 0x0000, 0x0000 }, /* R1504 */ - { 0x0000, 0x0000 }, /* R1505 */ - { 0x0000, 0x0000 }, /* R1506 */ - { 0x0000, 0x0000 }, /* R1507 */ - { 0x0000, 0x0000 }, /* R1508 */ - { 0x0000, 0x0000 }, /* R1509 */ - { 0x0000, 0x0000 }, /* R1510 */ - { 0x0000, 0x0000 }, /* R1511 */ - { 0x0000, 0x0000 }, /* R1512 */ - { 0x0000, 0x0000 }, /* R1513 */ - { 0x0000, 0x0000 }, /* R1514 */ - { 0x0000, 0x0000 }, /* R1515 */ - { 0x0000, 0x0000 }, /* R1516 */ - { 0x0000, 0x0000 }, /* R1517 */ - { 0x0000, 0x0000 }, /* R1518 */ - { 0x0000, 0x0000 }, /* R1519 */ - { 0x0000, 0x0000 }, /* R1520 */ - { 0x0000, 0x0000 }, /* R1521 */ - { 0x0000, 0x0000 }, /* R1522 */ - { 0x0000, 0x0000 }, /* R1523 */ - { 0x0000, 0x0000 }, /* R1524 */ - { 0x0000, 0x0000 }, /* R1525 */ - { 0x0000, 0x0000 }, /* R1526 */ - { 0x0000, 0x0000 }, /* R1527 */ - { 0x0000, 0x0000 }, /* R1528 */ - { 0x0000, 0x0000 }, /* R1529 */ - { 0x0000, 0x0000 }, /* R1530 */ - { 0x0000, 0x0000 }, /* R1531 */ - { 0x0000, 0x0000 }, /* R1532 */ - { 0x0000, 0x0000 }, /* R1533 */ - { 0x0000, 0x0000 }, /* R1534 */ - { 0x0000, 0x0000 }, /* R1535 */ - { 0x01EF, 0x01EF }, /* R1536 - DAC1 Mixer Volumes */ - { 0x0037, 0x0037 }, /* R1537 - DAC1 Left Mixer Routing */ - { 0x0037, 0x0037 }, /* R1538 - DAC1 Right Mixer Routing */ - { 0x01EF, 0x01EF }, /* R1539 - DAC2 Mixer Volumes */ - { 0x0037, 0x0037 }, /* R1540 - DAC2 Left Mixer Routing */ - { 0x0037, 0x0037 }, /* R1541 - DAC2 Right Mixer Routing */ - { 0x0003, 0x0003 }, /* R1542 - AIF1 ADC1 Left Mixer Routing */ - { 0x0003, 0x0003 }, /* R1543 - AIF1 ADC1 Right Mixer Routing */ - { 0x0003, 0x0003 }, /* R1544 - AIF1 ADC2 Left Mixer Routing */ - { 0x0003, 0x0003 }, /* R1545 - AIF1 ADC2 Right mixer Routing */ - { 0x0000, 0x0000 }, /* R1546 */ - { 0x0000, 0x0000 }, /* R1547 */ - { 0x0000, 0x0000 }, /* R1548 */ - { 0x0000, 0x0000 }, /* R1549 */ - { 0x0000, 0x0000 }, /* R1550 */ - { 0x0000, 0x0000 }, /* R1551 */ - { 0x02FF, 0x03FF }, /* R1552 - DAC1 Left Volume */ - { 0x02FF, 0x03FF }, /* R1553 - DAC1 Right Volume */ - { 0x02FF, 0x03FF }, /* R1554 - DAC2 Left Volume */ - { 0x02FF, 0x03FF }, /* R1555 - DAC2 Right Volume */ - { 0x0003, 0x0003 }, /* R1556 - DAC Softmute */ - { 0x0000, 0x0000 }, /* R1557 */ - { 0x0000, 0x0000 }, /* R1558 */ - { 0x0000, 0x0000 }, /* R1559 */ - { 0x0000, 0x0000 }, /* R1560 */ - { 0x0000, 0x0000 }, /* R1561 */ - { 0x0000, 0x0000 }, /* R1562 */ - { 0x0000, 0x0000 }, /* R1563 */ - { 0x0000, 0x0000 }, /* R1564 */ - { 0x0000, 0x0000 }, /* R1565 */ - { 0x0000, 0x0000 }, /* R1566 */ - { 0x0000, 0x0000 }, /* R1567 */ - { 0x0003, 0x0003 }, /* R1568 - Oversampling */ - { 0x03C3, 0x03C3 }, /* R1569 - Sidetone */ -}; - static int wm8994_readable(unsigned int reg) { switch (reg) { @@ -1696,9 +120,9 @@ static int wm8994_readable(unsigned int reg) break; } - if (reg >= ARRAY_SIZE(access_masks)) + if (reg >= WM8994_CACHE_SIZE) return 0; - return access_masks[reg].readable != 0; + return wm8994_access_masks[reg].readable != 0; } static int wm8994_volatile(unsigned int reg) @@ -3658,7 +2082,7 @@ static int wm8994_resume(struct snd_soc_codec *codec) break; } - if (!access_masks[i].writable) + if (!wm8994_access_masks[i].writable) continue; wm8994_reg_write(codec->control_data, i, reg_cache[i]); diff --git a/sound/soc/codecs/wm8994.h b/sound/soc/codecs/wm8994.h index d8dce260c430..b8b3166e1f03 100644 --- a/sound/soc/codecs/wm8994.h +++ b/sound/soc/codecs/wm8994.h @@ -31,4 +31,13 @@ int wm8994_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack, int micbias, int det, int shrt); +#define WM8994_CACHE_SIZE 1570 + +struct wm8994_access_mask { + unsigned short readable; /* Mask of readable bits */ + unsigned short writable; /* Mask of writable bits */ +}; + +extern const struct wm8994_access_mask wm8994_access_masks[WM8994_CACHE_SIZE]; + #endif -- cgit v1.2.3 From 5b3b0fa8fb0db9645b56361cdc9a9d0ddbc35e4d Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Fri, 19 Nov 2010 17:31:08 +0800 Subject: ASoC: Move kfree(twl4030) to twl4030_soc_remove() As we allocate memory for twl4030 in twl4030_codec_probe(), twl4030_codec_remove() is a better place to free the memory. Signed-off-by: Axel Lin Acked-by: Mark Brown Signed-off-by: Liam Girdwood --- sound/soc/codecs/twl4030.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c index a6ceddb0bb7d..3820885c8c2a 100644 --- a/sound/soc/codecs/twl4030.c +++ b/sound/soc/codecs/twl4030.c @@ -2272,9 +2272,12 @@ static int twl4030_soc_probe(struct snd_soc_codec *codec) static int twl4030_soc_remove(struct snd_soc_codec *codec) { + struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); + /* Reset registers to their chip default before leaving */ twl4030_reset_registers(codec); twl4030_set_bias_level(codec, SND_SOC_BIAS_OFF); + kfree(twl4030); return 0; } @@ -2306,10 +2309,7 @@ static int __devinit twl4030_codec_probe(struct platform_device *pdev) static int __devexit twl4030_codec_remove(struct platform_device *pdev) { - struct twl4030_priv *twl4030 = dev_get_drvdata(&pdev->dev); - snd_soc_unregister_codec(&pdev->dev); - kfree(twl4030); return 0; } -- cgit v1.2.3 From 4d23033dfdbb0409dfebaf748ba37ac00ef39825 Mon Sep 17 00:00:00 2001 From: Jiri Kosina Date: Fri, 19 Nov 2010 17:06:41 +0100 Subject: Don't touch blackfin with printk typo fixes This is a partial revert of b595076a ("tree-wide: fix comment/printk typos"), as blackfin tree is going to have completely different version of the code. Reported-by: Stephen Rothwell Signed-off-by: Jiri Kosina --- arch/blackfin/mach-bf518/include/mach/defBF51x_base.h | 2 +- arch/blackfin/mach-bf527/include/mach/defBF52x_base.h | 2 +- arch/blackfin/mach-bf538/include/mach/defBF539.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/blackfin/mach-bf518/include/mach/defBF51x_base.h b/arch/blackfin/mach-bf518/include/mach/defBF51x_base.h index 750f4d803845..5f84913dcd91 100644 --- a/arch/blackfin/mach-bf518/include/mach/defBF51x_base.h +++ b/arch/blackfin/mach-bf518/include/mach/defBF51x_base.h @@ -1197,7 +1197,7 @@ #define SADD_LEN 0x0002 /* Slave Address Length */ #define STDVAL 0x0004 /* Slave Transmit Data Valid */ #define NAK 0x0008 /* NAK/ACK* Generated At Conclusion Of Transfer */ -#define GEN 0x0010 /* General Call Address Matching Enabled */ +#define GEN 0x0010 /* General Call Adrress Matching Enabled */ /* TWI_SLAVE_STAT Masks */ #define SDIR 0x0001 /* Slave Transfer Direction (Transmit/Receive*) */ diff --git a/arch/blackfin/mach-bf527/include/mach/defBF52x_base.h b/arch/blackfin/mach-bf527/include/mach/defBF52x_base.h index e3ab78ef9001..09475034c6a1 100644 --- a/arch/blackfin/mach-bf527/include/mach/defBF52x_base.h +++ b/arch/blackfin/mach-bf527/include/mach/defBF52x_base.h @@ -1206,7 +1206,7 @@ #define SADD_LEN 0x0002 /* Slave Address Length */ #define STDVAL 0x0004 /* Slave Transmit Data Valid */ #define NAK 0x0008 /* NAK/ACK* Generated At Conclusion Of Transfer */ -#define GEN 0x0010 /* General Call Address Matching Enabled */ +#define GEN 0x0010 /* General Call Adrress Matching Enabled */ /* TWI_SLAVE_STAT Masks */ #define SDIR 0x0001 /* Slave Transfer Direction (Transmit/Receive*) */ diff --git a/arch/blackfin/mach-bf538/include/mach/defBF539.h b/arch/blackfin/mach-bf538/include/mach/defBF539.h index d85d128c97ca..7a8ac5f44204 100644 --- a/arch/blackfin/mach-bf538/include/mach/defBF539.h +++ b/arch/blackfin/mach-bf538/include/mach/defBF539.h @@ -2185,7 +2185,7 @@ #define SADD_LEN 0x0002 /* Slave Address Length */ #define STDVAL 0x0004 /* Slave Transmit Data Valid */ #define NAK 0x0008 /* NAK/ACK* Generated At Conclusion Of Transfer */ -#define GEN 0x0010 /* General Call Address Matching Enabled */ +#define GEN 0x0010 /* General Call Adrress Matching Enabled */ /* TWIx_SLAVE_STAT Masks */ #define SDIR 0x0001 /* Slave Transfer Direction (Transmit/Receive*) */ -- cgit v1.2.3 From 43b0178eda1e7e5d1e205bbfd076ab5d6ecacc02 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Wed, 27 Oct 2010 23:19:04 +0200 Subject: nfsd: fix NULL dereference in setattr() The original code would oops if this were called from nfsd4_setattr() because "filpp" is NULL. (Note this case is currently impossible, as long as we only give out read delegations.) Signed-off-by: Dan Carpenter Signed-off-by: J. Bruce Fields --- fs/nfsd/nfs4state.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index ad2bfa68d534..2d191293e6aa 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -3081,9 +3081,10 @@ nfs4_preprocess_stateid_op(struct nfsd4_compound_state *cstate, if (status) goto out; renew_client(dp->dl_client); - if (filpp) + if (filpp) { *filpp = find_readable_file(dp->dl_file); - BUG_ON(!*filpp); + BUG_ON(!*filpp); + } } else { /* open or lock stateid */ stp = find_stateid(stateid, flags); if (!stp) -- cgit v1.2.3 From 62bac4af3d778f6d06d351c0442008967c512588 Mon Sep 17 00:00:00 2001 From: "J. Bruce Fields" Date: Mon, 25 Oct 2010 12:50:15 -0400 Subject: svcrpc: don't set then immediately clear XPT_DEFERRED There's no harm to doing this, since the only caller will immediately call svc_enqueue() afterwards, ensuring we don't miss the remaining deferred requests just because XPT_DEFERRED was briefly cleared. But why not just do this the simple way? Signed-off-by: J. Bruce Fields --- net/sunrpc/svc_xprt.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c index c82fe739fbdc..a74cb67f15bf 100644 --- a/net/sunrpc/svc_xprt.c +++ b/net/sunrpc/svc_xprt.c @@ -1059,14 +1059,13 @@ static struct svc_deferred_req *svc_deferred_dequeue(struct svc_xprt *xprt) if (!test_bit(XPT_DEFERRED, &xprt->xpt_flags)) return NULL; spin_lock(&xprt->xpt_lock); - clear_bit(XPT_DEFERRED, &xprt->xpt_flags); if (!list_empty(&xprt->xpt_deferred)) { dr = list_entry(xprt->xpt_deferred.next, struct svc_deferred_req, handle.recent); list_del_init(&dr->handle.recent); - set_bit(XPT_DEFERRED, &xprt->xpt_flags); - } + } else + clear_bit(XPT_DEFERRED, &xprt->xpt_flags); spin_unlock(&xprt->xpt_lock); return dr; } -- cgit v1.2.3 From ca7896cd83456082b1e78816cdf7e41658ef7bcd Mon Sep 17 00:00:00 2001 From: "J. Bruce Fields" Date: Mon, 25 Oct 2010 14:12:40 -0400 Subject: nfsd4: centralize more calls to svc_xprt_received Follow up on b48fa6b99100dc7772af3cd276035fcec9719ceb by moving all the svc_xprt_received() calls for the main xprt to one place. The clearing of XPT_BUSY here is critical to the correctness of the server, so I'd prefer it to be obvious where we do it. The only substantive result is moving svc_xprt_received() after svc_receive_deferred(). Other than a (likely insignificant) delay waking up the next thread, that should be harmless. Also reshuffle the exit code a little to skip a few other steps that we don't care about the in the svc_delete_xprt() case. Signed-off-by: J. Bruce Fields --- net/sunrpc/svc_xprt.c | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c index a74cb67f15bf..dd61cd02461f 100644 --- a/net/sunrpc/svc_xprt.c +++ b/net/sunrpc/svc_xprt.c @@ -716,7 +716,10 @@ int svc_recv(struct svc_rqst *rqstp, long timeout) if (test_bit(XPT_CLOSE, &xprt->xpt_flags)) { dprintk("svc_recv: found XPT_CLOSE\n"); svc_delete_xprt(xprt); - } else if (test_bit(XPT_LISTENER, &xprt->xpt_flags)) { + /* Leave XPT_BUSY set on the dead xprt: */ + goto out; + } + if (test_bit(XPT_LISTENER, &xprt->xpt_flags)) { struct svc_xprt *newxpt; newxpt = xprt->xpt_ops->xpo_accept(xprt); if (newxpt) { @@ -741,28 +744,23 @@ int svc_recv(struct svc_rqst *rqstp, long timeout) spin_unlock_bh(&serv->sv_lock); svc_xprt_received(newxpt); } - svc_xprt_received(xprt); } else { dprintk("svc: server %p, pool %u, transport %p, inuse=%d\n", rqstp, pool->sp_id, xprt, atomic_read(&xprt->xpt_ref.refcount)); rqstp->rq_deferred = svc_deferred_dequeue(xprt); - if (rqstp->rq_deferred) { - svc_xprt_received(xprt); + if (rqstp->rq_deferred) len = svc_deferred_recv(rqstp); - } else { + else len = xprt->xpt_ops->xpo_recvfrom(rqstp); - svc_xprt_received(xprt); - } dprintk("svc: got len=%d\n", len); } + svc_xprt_received(xprt); /* No data, incomplete (TCP) read, or accept() */ - if (len == 0 || len == -EAGAIN) { - rqstp->rq_res.len = 0; - svc_xprt_release(rqstp); - return -EAGAIN; - } + if (len == 0 || len == -EAGAIN) + goto out; + clear_bit(XPT_OLD, &xprt->xpt_flags); rqstp->rq_secure = svc_port_is_privileged(svc_addr(rqstp)); @@ -771,6 +769,10 @@ int svc_recv(struct svc_rqst *rqstp, long timeout) if (serv->sv_stats) serv->sv_stats->netcnt++; return len; +out: + rqstp->rq_res.len = 0; + svc_xprt_release(rqstp); + return -EAGAIN; } EXPORT_SYMBOL_GPL(svc_recv); -- cgit v1.2.3 From f8c0d226fef05226ff1a85055c8ed663022f40c1 Mon Sep 17 00:00:00 2001 From: "J. Bruce Fields" Date: Mon, 25 Oct 2010 18:11:21 -0400 Subject: svcrpc: simplify svc_close_all There's no need to be fooling with XPT_BUSY now that all the threads are gone. The list_del_init() here could execute at the same time as the svc_xprt_enqueue()'s list_add_tail(), with undefined results. We don't really care at this point, but it might result in a spurious list-corruption warning or something. And svc_close() isn't adding any value; just call svc_delete_xprt() directly. Signed-off-by: J. Bruce Fields --- net/sunrpc/svc_xprt.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c index dd61cd02461f..8c018df80692 100644 --- a/net/sunrpc/svc_xprt.c +++ b/net/sunrpc/svc_xprt.c @@ -941,16 +941,16 @@ void svc_close_all(struct list_head *xprt_list) struct svc_xprt *xprt; struct svc_xprt *tmp; + /* + * The server is shutting down, and no more threads are running. + * svc_xprt_enqueue() might still be running, but at worst it + * will re-add the xprt to sp_sockets, which will soon get + * freed. So we don't bother with any more locking, and don't + * leave the close to the (nonexistent) server threads: + */ list_for_each_entry_safe(xprt, tmp, xprt_list, xpt_list) { set_bit(XPT_CLOSE, &xprt->xpt_flags); - if (test_bit(XPT_BUSY, &xprt->xpt_flags)) { - /* Waiting to be processed, but no threads left, - * So just remove it from the waiting list - */ - list_del_init(&xprt->xpt_ready); - clear_bit(XPT_BUSY, &xprt->xpt_flags); - } - svc_close_xprt(xprt); + svc_delete_xprt(xprt); } } -- cgit v1.2.3 From b176331627fccc726d28f4fc4a357d1f3c19dbf0 Mon Sep 17 00:00:00 2001 From: "J. Bruce Fields" Date: Mon, 25 Oct 2010 20:24:48 -0400 Subject: svcrpc: svc_close_xprt comment Neil Brown had to explain to me why we do this here; record the answer for posterity. Signed-off-by: J. Bruce Fields --- net/sunrpc/svc_xprt.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c index 8c018df80692..bfbda676574a 100644 --- a/net/sunrpc/svc_xprt.c +++ b/net/sunrpc/svc_xprt.c @@ -931,7 +931,12 @@ void svc_close_xprt(struct svc_xprt *xprt) if (test_and_set_bit(XPT_BUSY, &xprt->xpt_flags)) /* someone else will have to effect the close */ return; - + /* + * We expect svc_close_xprt() to work even when no threads are + * running (e.g., while configuring the server before starting + * any threads), so if the transport isn't busy, we delete + * it ourself: + */ svc_delete_xprt(xprt); } EXPORT_SYMBOL_GPL(svc_close_xprt); -- cgit v1.2.3 From 9c335c0b8daf56b9f73479d00b1dd726e1fcca09 Mon Sep 17 00:00:00 2001 From: "J. Bruce Fields" Date: Tue, 26 Oct 2010 11:32:03 -0400 Subject: svcrpc: fix wspace-checking race We call svc_xprt_enqueue() after something happens which we think may require handling from a server thread. To avoid such events being lost, svc_xprt_enqueue() must guarantee that there will be a svc_serv() call from a server thread following any such event. It does that by either waking up a server thread itself, or checking that XPT_BUSY is set (in which case somebody else is doing it). But the check of XPT_BUSY could occur just as someone finishes processing some other event, and just before they clear XPT_BUSY. Therefore it's important not to clear XPT_BUSY without subsequently doing another svc_export_enqueue() to check whether the xprt should be requeued. The xpo_wspace() check in svc_xprt_enqueue() breaks this rule, allowing an event to be missed in situations like: data arrives call svc_tcp_data_ready(): call svc_xprt_enqueue(): set BUSY find no write space svc_reserve(): free up write space call svc_enqueue(): test BUSY clear BUSY So, instead, check wspace in the same places that the state flags are checked: before taking BUSY, and in svc_receive(). Signed-off-by: J. Bruce Fields --- net/sunrpc/svc_xprt.c | 33 +++++++++++---------------------- 1 file changed, 11 insertions(+), 22 deletions(-) diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c index bfbda676574a..b6f47da170b3 100644 --- a/net/sunrpc/svc_xprt.c +++ b/net/sunrpc/svc_xprt.c @@ -302,6 +302,15 @@ static void svc_thread_dequeue(struct svc_pool *pool, struct svc_rqst *rqstp) list_del(&rqstp->rq_list); } +static bool svc_xprt_has_something_to_do(struct svc_xprt *xprt) +{ + if (xprt->xpt_flags & ((1<xpt_flags & ((1<xpt_ops->xpo_has_wspace(xprt); + return false; +} + /* * Queue up a transport with data pending. If there are idle nfsd * processes, wake 'em up. @@ -314,8 +323,7 @@ void svc_xprt_enqueue(struct svc_xprt *xprt) struct svc_rqst *rqstp; int cpu; - if (!(xprt->xpt_flags & - ((1<xpt_pool != NULL); xprt->xpt_pool = pool; - /* Handle pending connection */ - if (test_bit(XPT_CONN, &xprt->xpt_flags)) - goto process; - - /* Handle close in-progress */ - if (test_bit(XPT_CLOSE, &xprt->xpt_flags)) - goto process; - - /* Check if we have space to reply to a request */ - if (!xprt->xpt_ops->xpo_has_wspace(xprt)) { - /* Don't enqueue while not enough space for reply */ - dprintk("svc: no write space, transport %p not enqueued\n", - xprt); - xprt->xpt_pool = NULL; - clear_bit(XPT_BUSY, &xprt->xpt_flags); - goto out_unlock; - } - - process: if (!list_empty(&pool->sp_threads)) { rqstp = list_entry(pool->sp_threads.next, struct svc_rqst, @@ -744,7 +733,7 @@ int svc_recv(struct svc_rqst *rqstp, long timeout) spin_unlock_bh(&serv->sv_lock); svc_xprt_received(newxpt); } - } else { + } else if (xprt->xpt_ops->xpo_has_wspace(xprt)) { dprintk("svc: server %p, pool %u, transport %p, inuse=%d\n", rqstp, pool->sp_id, xprt, atomic_read(&xprt->xpt_ref.refcount)); -- cgit v1.2.3 From 5afa040b307952bb804eba34b21646da2842e14d Mon Sep 17 00:00:00 2001 From: Mi Jinlong Date: Tue, 9 Nov 2010 09:39:23 +0800 Subject: NFSv4.1: Make sure nfsd can decode SP4_SSV correctly at exchange_id According to RFC, the argument of ssv_sp_parms4 is: struct ssv_sp_parms4 { state_protect_ops4 ssp_ops; sec_oid4 ssp_hash_algs<>; sec_oid4 ssp_encr_algs<>; uint32_t ssp_window; uint32_t ssp_num_gss_handles; }; If client send a exchange_id with SP4_SSV, server cann't decode the SP4_SSV's ssp_hash_algs and ssp_encr_algs arguments correctly. Because the kernel treat the two arguments as a signal sec_oid4 struct, but should be a set of sec_oid4 struct. Signed-off-by: Mi Jinlong Signed-off-by: J. Bruce Fields --- fs/nfsd/nfs4xdr.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index f35a94a04026..71d7d339e44a 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -1005,7 +1005,7 @@ static __be32 nfsd4_decode_exchange_id(struct nfsd4_compoundargs *argp, struct nfsd4_exchange_id *exid) { - int dummy; + int dummy, tmp; DECODE_HEAD; READ_BUF(NFS4_VERIFIER_SIZE); @@ -1053,15 +1053,23 @@ nfsd4_decode_exchange_id(struct nfsd4_compoundargs *argp, /* ssp_hash_algs<> */ READ_BUF(4); - READ32(dummy); - READ_BUF(dummy); - p += XDR_QUADLEN(dummy); + READ32(tmp); + while (tmp--) { + READ_BUF(4); + READ32(dummy); + READ_BUF(dummy); + p += XDR_QUADLEN(dummy); + } /* ssp_encr_algs<> */ READ_BUF(4); - READ32(dummy); - READ_BUF(dummy); - p += XDR_QUADLEN(dummy); + READ32(tmp); + while (tmp--) { + READ_BUF(4); + READ32(dummy); + READ_BUF(dummy); + p += XDR_QUADLEN(dummy); + } /* ssp_window and ssp_num_gss_handles */ READ_BUF(8); -- cgit v1.2.3 From 044bc1d4324bfb34761cb361e404cb8d39c68777 Mon Sep 17 00:00:00 2001 From: "J. Bruce Fields" Date: Fri, 12 Nov 2010 14:36:06 -0500 Subject: nfsd4: return serverfault on request for ssv We're refusing to support a mandatory features of 4.1, so serverfault seems the better error; see e.g.: http://www.ietf.org/mail-archive/web/nfsv4/current/msg07638.html Signed-off-by: J. Bruce Fields --- fs/nfsd/nfs4state.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 2d191293e6aa..9e7f8af12f8f 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -1344,7 +1344,7 @@ nfsd4_exchange_id(struct svc_rqst *rqstp, case SP4_NONE: break; case SP4_SSV: - return nfserr_encr_alg_unsupp; + return nfserr_serverfault; default: BUG(); /* checked by xdr code */ case SP4_MACH_CRED: -- cgit v1.2.3 From ced6dfe9fc7128995c6d60627938944b430d82c8 Mon Sep 17 00:00:00 2001 From: Mi Jinlong Date: Thu, 11 Nov 2010 18:03:50 +0800 Subject: NFS4.1: server gets drc mem fail should reply error at create_session When server gets drc mem fail, it should reply error to client. Signed-off-by: Mi Jinlong Signed-off-by: J. Bruce Fields --- fs/nfsd/nfs4state.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 9e7f8af12f8f..5d0ee0f0cb0e 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -749,6 +749,8 @@ static struct nfsd4_session *alloc_init_session(struct svc_rqst *rqstp, struct n */ slotsize = nfsd4_sanitize_slot_size(fchan->maxresp_cached); numslots = nfsd4_get_drc_mem(slotsize, fchan->maxreqs); + if (numslots < 1) + return NULL; new = alloc_session(slotsize, numslots); if (!new) { -- cgit v1.2.3 From 1205065764f2eda3216ebe213143f69891ee3460 Mon Sep 17 00:00:00 2001 From: Mi Jinlong Date: Thu, 11 Nov 2010 18:03:40 +0800 Subject: NFS4.1: Fix bug server don't reply the right fore_channel to client at create_session At the latest kernel(2.6.37-rc1), server just initialize the forechannel at init_forechannel_attrs, but don't reflect it to reply. After initialize the session success, we should copy the forechannel info to nfsd4_create_session struct. Reviewed-by: Benny Halevy Signed-off-by: Mi Jinlong Signed-off-by: J. Bruce Fields --- fs/nfsd/nfs4state.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 5d0ee0f0cb0e..afa7525a86be 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -1562,6 +1562,8 @@ nfsd4_create_session(struct svc_rqst *rqstp, status = nfs_ok; memcpy(cr_ses->sessionid.data, new->se_sessionid.data, NFS4_MAX_SESSIONID_LEN); + memcpy(&cr_ses->fore_channel, &new->se_fchannel, + sizeof(struct nfsd4_channel_attrs)); cs_slot->sl_seqid++; cr_ses->seqid = cs_slot->sl_seqid; -- cgit v1.2.3 From 5dc177da85a813ff73c35f2d9edfb0bc2fe8271c Mon Sep 17 00:00:00 2001 From: Mike Rapoport Date: Wed, 17 Nov 2010 09:58:46 +0200 Subject: staging: brcm80211: brcmfmac: remove PCI SDIO controller binding Signed-off-by: Mike Rapoport Signed-off-by: Brett Rudley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmfmac/bcmsdh_linux.c | 229 ---------------------- 1 file changed, 229 deletions(-) diff --git a/drivers/staging/brcm80211/brcmfmac/bcmsdh_linux.c b/drivers/staging/brcm80211/brcmfmac/bcmsdh_linux.c index 6e32056451f1..9527e2959608 100644 --- a/drivers/staging/brcm80211/brcmfmac/bcmsdh_linux.c +++ b/drivers/staging/brcm80211/brcmfmac/bcmsdh_linux.c @@ -279,224 +279,6 @@ int bcmsdh_remove(struct device *dev) return 0; } - -#else /* BCMPLATFORM_BUS */ - -#if !defined(BCMLXSDMMC) -/* forward declarations for PCI probe and remove functions. */ -static int __devinit bcmsdh_pci_probe(struct pci_dev *pdev, - const struct pci_device_id *ent); -static void __devexit bcmsdh_pci_remove(struct pci_dev *pdev); - -/** - * pci id table - */ -static struct pci_device_id bcmsdh_pci_devid[] __devinitdata = { -{ - .vendor = PCI_ANY_ID, - .device = PCI_ANY_ID, - .subvendor = PCI_ANY_ID, - .subdevice = PCI_ANY_ID, - .class = 0, - .class_mask = 0, - .driver_data = 0, -}, -{0,} -}; - -MODULE_DEVICE_TABLE(pci, bcmsdh_pci_devid); - -/** - * SDIO Host Controller pci driver info - */ -static struct pci_driver bcmsdh_pci_driver = { - .node = {}, - .name = "bcmsdh", - .id_table = bcmsdh_pci_devid, - .probe = bcmsdh_pci_probe, - .remove = bcmsdh_pci_remove, - .suspend = NULL, - .resume = NULL, -}; - -extern uint sd_pci_slot; /* Force detection to a particular PCI */ - /* slot only . Allows for having multiple */ - /* WL devices at once in a PC */ - /* Only one instance of dhd will be */ - /* usable at a time */ - /* Upper word is bus number, */ - /* lower word is slot number */ - /* Default value of 0xFFFFffff turns this */ - /* off */ -module_param(sd_pci_slot, uint, 0); - -/** - * Detect supported SDIO Host Controller and attach if found. - * - * Determine if the device described by pdev is a supported SDIO Host - * Controller. If so, attach to it and attach to the target device. - */ -static int __devinit -bcmsdh_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) -{ - struct osl_info *osh = NULL; - bcmsdh_hc_t *sdhc = NULL; - unsigned long regs; - bcmsdh_info_t *sdh = NULL; - int rc; - - if (sd_pci_slot != 0xFFFFffff) { - if (pdev->bus->number != (sd_pci_slot >> 16) || - PCI_SLOT(pdev->devfn) != (sd_pci_slot & 0xffff)) { - SDLX_MSG(("%s: %s: bus %X, slot %X, vend %X, dev %X\n", - __func__, - bcmsdh_chipmatch(pdev->vendor, pdev->device) ? - "Found compatible SDIOHC" : - "Probing unknown device", - pdev->bus->number, PCI_SLOT(pdev->devfn), - pdev->vendor, pdev->device)); - return -ENODEV; - } - SDLX_MSG(("%s: %s: bus %X, slot %X, vendor %X, device %X " - "(good PCI location)\n", __func__, - bcmsdh_chipmatch(pdev->vendor, pdev->device) ? - "Using compatible SDIOHC" : "WARNING, forced use " - "of unkown device", - pdev->bus->number, PCI_SLOT(pdev->devfn), pdev->vendor, - pdev->device)); - } - - if ((pdev->vendor == VENDOR_TI) - && ((pdev->device == PCIXX21_FLASHMEDIA_ID) - || (pdev->device == PCIXX21_FLASHMEDIA0_ID))) { - u32 config_reg; - - SDLX_MSG(("%s: Disabling TI FlashMedia Controller.\n", - __func__)); - osh = osl_attach(pdev, PCI_BUS); - if (!osh) { - SDLX_MSG(("%s: osl_attach failed\n", __func__)); - goto err; - } - - config_reg = OSL_PCI_READ_CONFIG(osh, 0x4c, 4); - - /* - * Set MMC_SD_DIS bit in FlashMedia Controller. - * Disbling the SD/MMC Controller in the FlashMedia Controller - * allows the Standard SD Host Controller to take over control - * of the SD Slot. - */ - config_reg |= 0x02; - OSL_PCI_WRITE_CONFIG(osh, 0x4c, 4, config_reg); - osl_detach(osh); - } - /* match this pci device with what we support */ - /* we can't solely rely on this to believe it is - our SDIO Host Controller! */ - if (!bcmsdh_chipmatch(pdev->vendor, pdev->device)) - return -ENODEV; - - /* this is a pci device we might support */ - SDLX_MSG(("%s: Found possible SDIO Host Controller: " - "bus %d slot %d func %d irq %d\n", __func__, - pdev->bus->number, PCI_SLOT(pdev->devfn), - PCI_FUNC(pdev->devfn), pdev->irq)); - - /* use bcmsdh_query_device() to get the vendor ID of the target device - * so it will eventually appear in the Broadcom string on the console - */ - - /* allocate SDIO Host Controller state info */ - osh = osl_attach(pdev, PCI_BUS); - if (!osh) { - SDLX_MSG(("%s: osl_attach failed\n", __func__)); - goto err; - } - sdhc = kzalloc(sizeof(bcmsdh_hc_t), GFP_ATOMIC); - if (!sdhc) { - SDLX_MSG(("%s: out of memory\n", __func__)); - goto err; - } - sdhc->osh = osh; - - sdhc->dev = pdev; - - /* map to address where host can access */ - pci_set_master(pdev); - rc = pci_enable_device(pdev); - if (rc) { - SDLX_MSG(("%s: Cannot enable PCI device\n", __func__)); - goto err; - } - sdh = bcmsdh_attach(osh, (void *)(unsigned long)pci_resource_start(pdev, 0), - (void **)®s, pdev->irq); - if (!sdh) { - SDLX_MSG(("%s: bcmsdh_attach failed\n", __func__)); - goto err; - } - - sdhc->sdh = sdh; - - /* try to attach to the target device */ - sdhc->ch = drvinfo.attach(VENDOR_BROADCOM, /* pdev->vendor, */ - bcmsdh_query_device(sdh) & 0xFFFF, 0, 0, 0, 0, - (void *)regs, NULL, sdh); - if (!sdhc->ch) { - SDLX_MSG(("%s: device attach failed\n", __func__)); - goto err; - } - - /* chain SDIO Host Controller info together */ - sdhc->next = sdhcinfo; - sdhcinfo = sdhc; - - return 0; - - /* error handling */ -err: - if (sdhc->sdh) - bcmsdh_detach(sdhc->osh, sdhc->sdh); - if (sdhc) - kfree(sdhc); - if (osh) - osl_detach(osh); - return -ENODEV; -} - -/** - * Detach from target devices and SDIO Host Controller - */ -static void __devexit bcmsdh_pci_remove(struct pci_dev *pdev) -{ - bcmsdh_hc_t *sdhc, *prev; - struct osl_info *osh; - - /* find the SDIO Host Controller state for this - pdev and take it out from the list */ - for (sdhc = sdhcinfo, prev = NULL; sdhc; sdhc = sdhc->next) { - if (sdhc->dev == pdev) { - if (prev) - prev->next = sdhc->next; - else - sdhcinfo = NULL; - break; - } - prev = sdhc; - } - if (!sdhc) - return; - - drvinfo.detach(sdhc->ch); - - bcmsdh_detach(sdhc->osh, sdhc->sdh); - - /* release SDIO Host Controller info */ - osh = sdhc->osh; - kfree(sdhc); - osl_detach(osh); -} -#endif /* BCMLXSDMMC */ #endif /* BCMPLATFORM_BUS */ extern int sdio_function_init(void); @@ -515,14 +297,6 @@ int bcmsdh_register(bcmsdh_driver_t *driver) return error; #endif /* defined(BCMPLATFORM_BUS) */ -#if !defined(BCMPLATFORM_BUS) && !defined(BCMLXSDMMC) - error = pci_register_driver(&bcmsdh_pci_driver); - if (!error) - return 0; - - SDLX_MSG(("%s: pci_register_driver failed 0x%x\n", __func__, error)); -#endif /* BCMPLATFORM_BUS */ - return error; } @@ -533,9 +307,6 @@ void bcmsdh_unregister(void) #if defined(BCMLXSDMMC) sdio_function_cleanup(); #endif /* BCMLXSDMMC */ -#if !defined(BCMPLATFORM_BUS) && !defined(BCMLXSDMMC) - pci_unregister_driver(&bcmsdh_pci_driver); -#endif /* BCMPLATFORM_BUS */ } #if defined(OOB_INTR_ONLY) -- cgit v1.2.3 From 26361116d7c94984a5fbdc1b6a11555a9dc33cf0 Mon Sep 17 00:00:00 2001 From: Mike Rapoport Date: Wed, 17 Nov 2010 10:00:00 +0200 Subject: staging: brcm80211: brcmfmac: cleanup bcmsdh_(un)register Signed-off-by: Mike Rapoport Signed-off-by: Brett Rudley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmfmac/bcmsdh_linux.c | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/drivers/staging/brcm80211/brcmfmac/bcmsdh_linux.c b/drivers/staging/brcm80211/brcmfmac/bcmsdh_linux.c index 9527e2959608..d24b5e7d753c 100644 --- a/drivers/staging/brcm80211/brcmfmac/bcmsdh_linux.c +++ b/drivers/staging/brcm80211/brcmfmac/bcmsdh_linux.c @@ -285,28 +285,17 @@ extern int sdio_function_init(void); int bcmsdh_register(bcmsdh_driver_t *driver) { - int error = 0; - drvinfo = *driver; -#if defined(BCMPLATFORM_BUS) -#if defined(BCMLXSDMMC) SDLX_MSG(("Linux Kernel SDIO/MMC Driver\n")); - error = sdio_function_init(); -#endif /* defined(BCMLXSDMMC) */ - return error; -#endif /* defined(BCMPLATFORM_BUS) */ - - return error; + return sdio_function_init(); } extern void sdio_function_cleanup(void); void bcmsdh_unregister(void) { -#if defined(BCMLXSDMMC) sdio_function_cleanup(); -#endif /* BCMLXSDMMC */ } #if defined(OOB_INTR_ONLY) -- cgit v1.2.3 From c303ecbda8b7c86975c4ba23f56b8cbe297cd060 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Thu, 18 Nov 2010 20:46:43 +0100 Subject: staging: brcm80211: replace PKTPUSH and PKTPULL macros with native skbuff calls Replacing PKTPUSH by skb_push() call and PKTPULL by skb_pull() call to make it obvious what the operation is doing with the packet. Reviewed-by: Henry Ptasinski Reviewed-by: Brett Rudley Signed-off-by: Arend van Spriel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmfmac/dhd_cdc.c | 4 ++-- drivers/staging/brcm80211/brcmfmac/dhd_sdio.c | 26 +++++++++++++------------- drivers/staging/brcm80211/include/linux_osl.h | 2 -- drivers/staging/brcm80211/sys/wlc_ampdu.c | 8 ++++---- drivers/staging/brcm80211/sys/wlc_mac80211.c | 14 +++++++------- drivers/staging/brcm80211/util/hnddma.c | 2 +- 6 files changed, 27 insertions(+), 29 deletions(-) diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_cdc.c b/drivers/staging/brcm80211/brcmfmac/dhd_cdc.c index 0d14f6c1fcfa..8e4e10794dce 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_cdc.c +++ b/drivers/staging/brcm80211/brcmfmac/dhd_cdc.c @@ -321,7 +321,7 @@ void dhd_prot_hdrpush(dhd_pub_t *dhd, int ifidx, void *pktbuf) #ifdef BDC /* Push BDC header used to convey priority for buses that don't */ - PKTPUSH(pktbuf, BDC_HEADER_LEN); + skb_push(pktbuf, BDC_HEADER_LEN); h = (struct bdc_header *)PKTDATA(pktbuf); @@ -398,7 +398,7 @@ int dhd_prot_hdrpull(dhd_pub_t *dhd, int *ifidx, void *pktbuf) PKTSETPRIO(pktbuf, (h->priority & BDC_PRIORITY_MASK)); - PKTPULL(pktbuf, BDC_HEADER_LEN); + skb_pull(pktbuf, BDC_HEADER_LEN); #endif /* BDC */ return 0; diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c b/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c index bc8739665d66..db649a038938 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c +++ b/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c @@ -365,7 +365,7 @@ extern void bcmsdh_enable_hw_oob_intr(void *sdh, bool enable); ASSERT(datalign < (align)); \ ASSERT(PKTLEN((p)) >= ((len) + datalign)); \ if (datalign) \ - PKTPULL((p), datalign); \ + skb_pull((p), datalign); \ PKTSETLEN((p), (len)); \ } while (0) @@ -953,7 +953,7 @@ static int dhdsdio_txpkt(dhd_bus_t *bus, void *pkt, uint chan, bool free_pkt) ASSERT(((unsigned long)frame % DHD_SDALIGN) == 0); pad = 0; } else { - PKTPUSH(pkt, pad); + skb_push(pkt, pad); frame = (u8 *) PKTDATA(pkt); ASSERT((pad + SDPCM_HDRLEN) <= (int)PKTLEN(pkt)); @@ -1052,7 +1052,7 @@ static int dhdsdio_txpkt(dhd_bus_t *bus, void *pkt, uint chan, bool free_pkt) done: /* restore pkt buffer pointer before calling tx complete routine */ - PKTPULL(pkt, SDPCM_HDRLEN + pad); + skb_pull(pkt, SDPCM_HDRLEN + pad); dhd_os_sdunlock(bus->dhd); dhd_txcomplete(bus->dhd, pkt, ret != 0); dhd_os_sdlock(bus->dhd); @@ -1078,7 +1078,7 @@ int dhd_bus_txdata(struct dhd_bus *bus, void *pkt) /* Push the test header if doing loopback */ if (bus->ext_loop) { u8 *data; - PKTPUSH(pkt, SDPCM_TEST_HDRLEN); + skb_push(pkt, SDPCM_TEST_HDRLEN); data = PKTDATA(pkt); *data++ = SDPCM_TEST_ECHOREQ; *data++ = (u8) bus->loopid++; @@ -1089,7 +1089,7 @@ int dhd_bus_txdata(struct dhd_bus *bus, void *pkt) #endif /* SDTEST */ /* Add space for the header */ - PKTPUSH(pkt, SDPCM_HDRLEN); + skb_push(pkt, SDPCM_HDRLEN); ASSERT(IS_ALIGNED((unsigned long)PKTDATA(pkt), 2)); prec = PRIO2PREC((PKTPRIO(pkt) & PRIOMASK)); @@ -1107,7 +1107,7 @@ int dhd_bus_txdata(struct dhd_bus *bus, void *pkt) /* Priority based enq */ dhd_os_sdlock_txq(bus->dhd); if (dhd_prec_enq(bus->dhd, &bus->txq, pkt, prec) == false) { - PKTPULL(pkt, SDPCM_HDRLEN); + skb_pull(pkt, SDPCM_HDRLEN); dhd_txcomplete(bus->dhd, pkt, false); PKTFREE(osh, pkt, true); DHD_ERROR(("%s: out of bus->txq !!!\n", __func__)); @@ -3426,7 +3426,7 @@ static u8 dhdsdio_rxglom(dhd_bus_t *bus, u8 rxseq) bus->tx_max = txmax; /* Remove superframe header, remember offset */ - PKTPULL(pfirst, doff); + skb_pull(pfirst, doff); sfdoff = doff; /* Validate all the subframe headers */ @@ -3471,7 +3471,7 @@ static u8 dhdsdio_rxglom(dhd_bus_t *bus, u8 rxseq) a couple retries */ if (bus->glomerr++ < 3) { /* Restore superframe header space */ - PKTPUSH(pfirst, sfdoff); + skb_push(pfirst, sfdoff); dhdsdio_rxfail(bus, true, true); } else { bus->glomerr = 0; @@ -3522,7 +3522,7 @@ static u8 dhdsdio_rxglom(dhd_bus_t *bus, u8 rxseq) #endif PKTSETLEN(pfirst, sublen); - PKTPULL(pfirst, doff); + skb_pull(pfirst, doff); if (PKTLEN(pfirst) == 0) { PKTFREE(bus->dhd->osh, pfirst, false); @@ -4104,7 +4104,7 @@ static uint dhdsdio_readframes(dhd_bus_t *bus, uint maxframes, bool *finished) /* Leave room for what we already read, and align remainder */ ASSERT(firstread < (PKTLEN(pkt))); - PKTPULL(pkt, firstread); + skb_pull(pkt, firstread); PKTALIGN(osh, pkt, rdlen, DHD_SDALIGN); /* Read the remaining frame data */ @@ -4132,7 +4132,7 @@ static uint dhdsdio_readframes(dhd_bus_t *bus, uint maxframes, bool *finished) } /* Copy the already-read portion */ - PKTPUSH(pkt, firstread); + skb_push(pkt, firstread); bcopy(bus->rxhdr, PKTDATA(pkt), firstread); #ifdef DHD_DEBUG @@ -4153,7 +4153,7 @@ deliver: #endif PKTSETLEN(pkt, len); ASSERT(doff == SDPCM_HDRLEN); - PKTPULL(pkt, SDPCM_HDRLEN); + skb_pull(pkt, SDPCM_HDRLEN); bus->glomd = pkt; } else { DHD_ERROR(("%s: glom superframe w/o " @@ -4165,7 +4165,7 @@ deliver: /* Fill in packet len and prio, deliver upward */ PKTSETLEN(pkt, len); - PKTPULL(pkt, doff); + skb_pull(pkt, doff); #ifdef SDTEST /* Test channel packets are processed separately */ diff --git a/drivers/staging/brcm80211/include/linux_osl.h b/drivers/staging/brcm80211/include/linux_osl.h index 70621692150a..a7f0da271001 100644 --- a/drivers/staging/brcm80211/include/linux_osl.h +++ b/drivers/staging/brcm80211/include/linux_osl.h @@ -274,8 +274,6 @@ extern void osl_dma_unmap(struct osl_info *osh, uint pa, uint size, #define PKTSETNEXT(skb, x) \ (((struct sk_buff *)(skb))->next = (struct sk_buff *)(x)) #define PKTSETLEN(skb, len) __skb_trim((struct sk_buff *)(skb), (len)) -#define PKTPUSH(skb, bytes) skb_push((struct sk_buff *)(skb), (bytes)) -#define PKTPULL(skb, bytes) skb_pull((struct sk_buff *)(skb), (bytes)) #define PKTALLOCED(osh) (((struct osl_pubinfo *)(osh))->pktalloced) #define PKTSETPOOL(osh, skb, x, y) do {} while (0) #define PKTPOOL(osh, skb) false diff --git a/drivers/staging/brcm80211/sys/wlc_ampdu.c b/drivers/staging/brcm80211/sys/wlc_ampdu.c index 5d06105ba1f6..dc327026a0f0 100644 --- a/drivers/staging/brcm80211/sys/wlc_ampdu.c +++ b/drivers/staging/brcm80211/sys/wlc_ampdu.c @@ -1187,8 +1187,8 @@ wlc_ampdu_dotxstatus_complete(ampdu_info_t *ampdu, struct scb *scb, void *p, status & TX_STATUS_FRM_RTX_MASK) >> TX_STATUS_FRM_RTX_SHIFT; - PKTPULL(p, D11_PHY_HDR_LEN); - PKTPULL(p, D11_TXH_LEN); + skb_pull(p, D11_PHY_HDR_LEN); + skb_pull(p, D11_TXH_LEN); ieee80211_tx_status_irqsafe(wlc->pub->ieee_hw, p); @@ -1213,8 +1213,8 @@ wlc_ampdu_dotxstatus_complete(ampdu_info_t *ampdu, struct scb *scb, void *p, ieee80211_tx_info_clear_status(tx_info); tx_info->flags |= IEEE80211_TX_STAT_AMPDU_NO_BACK; - PKTPULL(p, D11_PHY_HDR_LEN); - PKTPULL(p, D11_TXH_LEN); + skb_pull(p, D11_PHY_HDR_LEN); + skb_pull(p, D11_TXH_LEN); WL_ERROR(("%s: BA Timeout, seq %d, in_transit %d\n", SHORTNAME, seq, ini->tx_in_transit)); ieee80211_tx_status_irqsafe(wlc->pub->ieee_hw, p); diff --git a/drivers/staging/brcm80211/sys/wlc_mac80211.c b/drivers/staging/brcm80211/sys/wlc_mac80211.c index 9e57dc3cde21..94b809c24783 100644 --- a/drivers/staging/brcm80211/sys/wlc_mac80211.c +++ b/drivers/staging/brcm80211/sys/wlc_mac80211.c @@ -5942,10 +5942,10 @@ wlc_d11hdrs_mac80211(wlc_info_t *wlc, struct ieee80211_hw *hw, ASSERT(tx_info); /* add PLCP */ - plcp = PKTPUSH(p, D11_PHY_HDR_LEN); + plcp = skb_push(p, D11_PHY_HDR_LEN); /* add Broadcom tx descriptor header */ - txh = (d11txh_t *) PKTPUSH(p, D11_TXH_LEN); + txh = (d11txh_t *) skb_push(p, D11_TXH_LEN); bzero((char *)txh, D11_TXH_LEN); /* setup frameid */ @@ -6890,8 +6890,8 @@ wlc_dotxstatus(wlc_info_t *wlc, tx_status_t *txs, u32 frm_tx2) PKTSETLINK(p, NULL); wlc->txretried = 0; /* remove PLCP & Broadcom tx descriptor header */ - PKTPULL(p, D11_PHY_HDR_LEN); - PKTPULL(p, D11_TXH_LEN); + skb_pull(p, D11_PHY_HDR_LEN); + skb_pull(p, D11_TXH_LEN); ieee80211_tx_status_irqsafe(wlc->pub->ieee_hw, p); WLCNTINCR(wlc->pub->_cnt->ieee_tx_status); } else { @@ -7163,7 +7163,7 @@ wlc_recvctl(wlc_info_t *wlc, struct osl_info *osh, d11rxhdr_t *rxh, void *p) /* mac header+body length, exclude CRC and plcp header */ len_mpdu = PKTLEN(p) - D11_PHY_HDR_LEN - DOT11_FCS_LEN; - PKTPULL(p, D11_PHY_HDR_LEN); + skb_pull(p, D11_PHY_HDR_LEN); PKTSETLEN(p, len_mpdu); ASSERT(!PKTNEXT(p)); @@ -7225,7 +7225,7 @@ void BCMFASTPATH wlc_recv(wlc_info_t *wlc, void *p) rxh = (d11rxhdr_t *) PKTDATA(p); /* strip off rxhdr */ - PKTPULL(p, wlc->hwrxoff); + skb_pull(p, wlc->hwrxoff); /* fixup rx header endianness */ ltoh16_buf((void *)rxh, sizeof(d11rxhdr_t)); @@ -7238,7 +7238,7 @@ void BCMFASTPATH wlc_recv(wlc_info_t *wlc, void *p) wlc->pub->unit, PKTLEN(p))); goto toss; } - PKTPULL(p, 2); + skb_pull(p, 2); } h = (struct dot11_header *)(PKTDATA(p) + D11_PHY_HDR_LEN); diff --git a/drivers/staging/brcm80211/util/hnddma.c b/drivers/staging/brcm80211/util/hnddma.c index a945156eb31f..7fdcdcacab0f 100644 --- a/drivers/staging/brcm80211/util/hnddma.c +++ b/drivers/staging/brcm80211/util/hnddma.c @@ -1110,7 +1110,7 @@ static bool BCMFASTPATH _dma_rxfill(dma_info_t *di) } /* reserve an extra headroom, if applicable */ if (extra_offset) - PKTPULL(p, extra_offset); + skb_pull(p, extra_offset); /* Do a cached write instead of uncached write since DMA_MAP * will flush the cache. -- cgit v1.2.3 From 2cb8ada64f209c5c033f1821bbbc0e8d388cbf7f Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Thu, 18 Nov 2010 20:46:44 +0100 Subject: staging: brcm80211: replaced PKTSETLEN macro by native __skb_trim call - removed PKTSETLEN macro and used __skb_trim call instead. - removed unused macros PKTSETPOOL and PKTPOOL Reviewed-by: Henry Ptasinski Reviewed-by: Brett Rudley Signed-off-by: Arend van Spriel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmfmac/dhd_sdio.c | 8 ++++---- drivers/staging/brcm80211/include/linux_osl.h | 3 --- drivers/staging/brcm80211/sys/wlc_mac80211.c | 2 +- drivers/staging/brcm80211/util/hnddma.c | 4 ++-- 4 files changed, 7 insertions(+), 10 deletions(-) diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c b/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c index db649a038938..d94b11a3271b 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c +++ b/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c @@ -366,7 +366,7 @@ extern void bcmsdh_enable_hw_oob_intr(void *sdh, bool enable); ASSERT(PKTLEN((p)) >= ((len) + datalign)); \ if (datalign) \ skb_pull((p), datalign); \ - PKTSETLEN((p), (len)); \ + __skb_trim((p), (len)); \ } while (0) /* Limit on rounding up frames */ @@ -3521,7 +3521,7 @@ static u8 dhdsdio_rxglom(dhd_bus_t *bus, u8 rxseq) prhex("Rx Subframe Data", dptr, dlen); #endif - PKTSETLEN(pfirst, sublen); + __skb_trim(pfirst, sublen); skb_pull(pfirst, doff); if (PKTLEN(pfirst) == 0) { @@ -4151,7 +4151,7 @@ deliver: prhex("Glom Data", PKTDATA(pkt), len); } #endif - PKTSETLEN(pkt, len); + __skb_trim(pkt, len); ASSERT(doff == SDPCM_HDRLEN); skb_pull(pkt, SDPCM_HDRLEN); bus->glomd = pkt; @@ -4164,7 +4164,7 @@ deliver: } /* Fill in packet len and prio, deliver upward */ - PKTSETLEN(pkt, len); + __skb_trim(pkt, len); skb_pull(pkt, doff); #ifdef SDTEST diff --git a/drivers/staging/brcm80211/include/linux_osl.h b/drivers/staging/brcm80211/include/linux_osl.h index a7f0da271001..11239fbba766 100644 --- a/drivers/staging/brcm80211/include/linux_osl.h +++ b/drivers/staging/brcm80211/include/linux_osl.h @@ -273,10 +273,7 @@ extern void osl_dma_unmap(struct osl_info *osh, uint pa, uint size, #define PKTNEXT(skb) (((struct sk_buff *)(skb))->next) #define PKTSETNEXT(skb, x) \ (((struct sk_buff *)(skb))->next = (struct sk_buff *)(x)) -#define PKTSETLEN(skb, len) __skb_trim((struct sk_buff *)(skb), (len)) #define PKTALLOCED(osh) (((struct osl_pubinfo *)(osh))->pktalloced) -#define PKTSETPOOL(osh, skb, x, y) do {} while (0) -#define PKTPOOL(osh, skb) false extern void *osl_pktget(struct osl_info *osh, uint len); extern void osl_pktfree(struct osl_info *osh, void *skb, bool send); diff --git a/drivers/staging/brcm80211/sys/wlc_mac80211.c b/drivers/staging/brcm80211/sys/wlc_mac80211.c index 94b809c24783..513e4d9a1ad2 100644 --- a/drivers/staging/brcm80211/sys/wlc_mac80211.c +++ b/drivers/staging/brcm80211/sys/wlc_mac80211.c @@ -7164,7 +7164,7 @@ wlc_recvctl(wlc_info_t *wlc, struct osl_info *osh, d11rxhdr_t *rxh, void *p) /* mac header+body length, exclude CRC and plcp header */ len_mpdu = PKTLEN(p) - D11_PHY_HDR_LEN - DOT11_FCS_LEN; skb_pull(p, D11_PHY_HDR_LEN); - PKTSETLEN(p, len_mpdu); + __skb_trim(p, len_mpdu); ASSERT(!PKTNEXT(p)); ASSERT(!PKTLINK(p)); diff --git a/drivers/staging/brcm80211/util/hnddma.c b/drivers/staging/brcm80211/util/hnddma.c index 7fdcdcacab0f..f1e9cfcca991 100644 --- a/drivers/staging/brcm80211/util/hnddma.c +++ b/drivers/staging/brcm80211/util/hnddma.c @@ -1003,7 +1003,7 @@ static void *BCMFASTPATH _dma_rx(dma_info_t *di) /* set actual length */ pkt_len = min((di->rxoffset + len), di->rxbufsize); - PKTSETLEN(head, pkt_len); + __skb_trim(head, pkt_len); resid = len - (di->rxbufsize - di->rxoffset); /* check for single or multi-buffer rx */ @@ -1012,7 +1012,7 @@ static void *BCMFASTPATH _dma_rx(dma_info_t *di) while ((resid > 0) && (p = _dma_getnextrxp(di, false))) { PKTSETNEXT(tail, p); pkt_len = min(resid, (int)di->rxbufsize); - PKTSETLEN(p, pkt_len); + __skb_trim(p, pkt_len); tail = p; resid -= di->rxbufsize; -- cgit v1.2.3 From 29efb1a9f450450e764d9901b434557349c3af53 Mon Sep 17 00:00:00 2001 From: Brett Rudley Date: Fri, 19 Nov 2010 14:30:52 -0800 Subject: staging: brcm80211: unifdef -UWLC_HIGH_ONLY Part of BMAC removal. Signed-off-by: Brett Rudley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/phy/wlc_phy_hal.h | 4 - drivers/staging/brcm80211/sys/wl_mac80211.c | 498 --------------------------- drivers/staging/brcm80211/sys/wl_mac80211.h | 30 -- drivers/staging/brcm80211/sys/wlc_alloc.c | 5 - drivers/staging/brcm80211/sys/wlc_ampdu.c | 53 --- drivers/staging/brcm80211/sys/wlc_ampdu.h | 4 - drivers/staging/brcm80211/sys/wlc_bmac.h | 10 - drivers/staging/brcm80211/sys/wlc_mac80211.c | 226 ------------ drivers/staging/brcm80211/sys/wlc_mac80211.h | 21 -- drivers/staging/brcm80211/sys/wlc_rpctx.h | 24 -- 10 files changed, 875 deletions(-) diff --git a/drivers/staging/brcm80211/phy/wlc_phy_hal.h b/drivers/staging/brcm80211/phy/wlc_phy_hal.h index 52260b2d0eba..c462387d20b9 100644 --- a/drivers/staging/brcm80211/phy/wlc_phy_hal.h +++ b/drivers/staging/brcm80211/phy/wlc_phy_hal.h @@ -122,11 +122,7 @@ typedef struct shared_phy shared_phy_t; struct phy_pub; -#ifdef WLC_HIGH_ONLY -typedef struct wlc_rpc_phy wlc_phy_t; -#else typedef struct phy_pub wlc_phy_t; -#endif typedef struct shared_phy_params { void *osh; diff --git a/drivers/staging/brcm80211/sys/wl_mac80211.c b/drivers/staging/brcm80211/sys/wl_mac80211.c index af6d7dea4697..e336fef111e5 100644 --- a/drivers/staging/brcm80211/sys/wl_mac80211.c +++ b/drivers/staging/brcm80211/sys/wl_mac80211.c @@ -29,9 +29,7 @@ #include #include -#ifndef WLC_HIGH_ONLY #include -#endif #include #include #include @@ -46,20 +44,11 @@ #include #endif #include -#ifdef WLC_HIGH_ONLY -#include "dbus.h" -#include "bcm_rpc_tp.h" -#include "bcm_rpc.h" -#include "bcm_xdr.h" -#include "wlc_rpc.h" -#endif #include #include -#ifndef WLC_HIGH_ONLY #include #include -#endif #ifdef BCMSDIO extern struct device *sdiommc_dev; @@ -75,21 +64,6 @@ void wlc_set_addrmatch(wlc_info_t *wlc, int match_reg_offset, static void wl_timer(unsigned long data); static void _wl_timer(wl_timer_t *t); -#ifdef WLC_HIGH_ONLY -#define RPCQ_LOCK(_wl, _flags) spin_lock_irqsave(&(_wl)->rpcq_lock, (_flags)) -#define RPCQ_UNLOCK(_wl, _flags) spin_unlock_irqrestore(&(_wl)->rpcq_lock, (_flags)) -#define TXQ_LOCK(_wl, _flags) spin_lock_irqsave(&(_wl)->txq_lock, (_flags)) -#define TXQ_UNLOCK(_wl, _flags) spin_unlock_irqrestore(&(_wl)->txq_lock, (_flags)) -static void wl_rpc_down(void *wlh); -static void wl_rpcq_free(wl_info_t *wl); -static void wl_rpcq_dispatch(struct wl_task *task); -static void wl_rpc_dispatch_schedule(void *ctx, struct rpc_buf *buf); -static void wl_start_txqwork(struct wl_task *task); -static void wl_txq_free(wl_info_t *wl); -static void wl_timer_task(wl_task_t *task); -static int wl_schedule_task(wl_info_t *wl, void (*fn) (struct wl_task *), - void *context); -#endif /* WLC_HIGH_ONLY */ static int ieee_hw_init(struct ieee80211_hw *hw); static int ieee_hw_rate_init(struct ieee80211_hw *hw); @@ -137,12 +111,10 @@ struct ieee80211_tkip_data { u8 rx_hdr[16], tx_hdr[16]; }; -#ifndef WLC_HIGH_ONLY #define WL_DEV_IF(dev) ((wl_if_t *)netdev_priv(dev)) #define WL_INFO(dev) ((wl_info_t *)(WL_DEV_IF(dev)->wl)) /* points to wl */ static int wl_request_fw(wl_info_t *wl, struct pci_dev *pdev); static void wl_release_fw(wl_info_t *wl); -#endif /* local prototypes */ static int wl_start(struct sk_buff *skb, wl_info_t *wl); @@ -176,19 +148,13 @@ module_param(sd_drivestrength, uint, 0); #ifdef BCMDBG static int msglevel = 0xdeadbeef; module_param(msglevel, int, 0); -#ifndef WLC_HIGH_ONLY static int phymsglevel = 0xdeadbeef; module_param(phymsglevel, int, 0); -#endif /* WLC_HIGH_ONLY */ #endif /* BCMDBG */ #define HW_TO_WL(hw) (hw->priv) #define WL_TO_HW(wl) (wl->pub->ieee_hw) -#ifdef WLC_HIGH_ONLY -static int wl_ops_tx_nl(struct ieee80211_hw *hw, struct sk_buff *skb); -#else static int wl_ops_tx(struct ieee80211_hw *hw, struct sk_buff *skb); -#endif static int wl_ops_start(struct ieee80211_hw *hw); static void wl_ops_stop(struct ieee80211_hw *hw); static int wl_ops_add_interface(struct ieee80211_hw *hw, @@ -226,21 +192,6 @@ static int wl_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, enum ieee80211_ampdu_mlme_action action, struct ieee80211_sta *sta, u16 tid, u16 *ssn); -#ifdef WLC_HIGH_ONLY -static int wl_ops_tx_nl(struct ieee80211_hw *hw, struct sk_buff *skb) -{ - int status; - wl_info_t *wl = hw->priv; - if (!wl->pub->up) { - WL_ERROR(("ops->tx called while down\n")); - status = -ENETDOWN; - goto done; - } - status = wl_start(skb, wl); - done: - return status; -} -#else static int wl_ops_tx(struct ieee80211_hw *hw, struct sk_buff *skb) { int status; @@ -256,7 +207,6 @@ static int wl_ops_tx(struct ieee80211_hw *hw, struct sk_buff *skb) WL_UNLOCK(wl); return status; } -#endif /* WLC_HIGH_ONLY */ static int wl_ops_start(struct ieee80211_hw *hw) { @@ -415,9 +365,6 @@ wl_ops_bss_info_changed(struct ieee80211_hw *hw, wl_info_t *wl = HW_TO_WL(hw); int val; -#ifdef WLC_HIGH_ONLY - WL_LOCK(wl); -#endif if (changed & BSS_CHANGED_ASSOC) { WL_ERROR(("Associated:\t%s\n", info->assoc ? "True" : "False")); @@ -477,9 +424,6 @@ wl_ops_bss_info_changed(struct ieee80211_hw *hw, info->enable_beacon ? "True" : "False")); /* Beaconing should be enabled/disabled (beaconing modes) */ } -#ifdef WLC_HIGH_ONLY - WL_UNLOCK(wl); -#endif return; } @@ -488,9 +432,7 @@ wl_ops_configure_filter(struct ieee80211_hw *hw, unsigned int changed_flags, unsigned int *total_flags, u64 multicast) { -#ifndef WLC_HIGH_ONLY wl_info_t *wl = hw->priv; -#endif changed_flags &= MAC_FILTERS; *total_flags &= MAC_FILTERS; @@ -508,7 +450,6 @@ wl_ops_configure_filter(struct ieee80211_hw *hw, WL_ERROR(("FIF_OTHER_BSS\n")); if (changed_flags & FIF_BCN_PRBRESP_PROMISC) { WL_NONE(("FIF_BCN_PRBRESP_PROMISC\n")); -#ifndef WLC_HIGH_ONLY WL_LOCK(wl); if (*total_flags & FIF_BCN_PRBRESP_PROMISC) { wl->pub->mac80211_state |= MAC80211_PROMISC_BCNS; @@ -518,7 +459,6 @@ wl_ops_configure_filter(struct ieee80211_hw *hw, wl->pub->mac80211_state &= ~MAC80211_PROMISC_BCNS; } WL_UNLOCK(wl); -#endif } return; } @@ -618,20 +558,12 @@ wl_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif, wl->pub->global_scb = scb; wl->pub->global_ampdu = &(scb->scb_ampdu); wl->pub->global_ampdu->scb = scb; -#ifdef WLC_HIGH_ONLY - wl->pub->global_ampdu->max_pdu = AMPDU_NUM_MPDU; -#else wl->pub->global_ampdu->max_pdu = 16; -#endif pktq_init(&scb->scb_ampdu.txq, AMPDU_MAX_SCB_TID, AMPDU_MAX_SCB_TID * PKTQ_LEN_DEFAULT); sta->ht_cap.ht_supported = true; -#ifdef WLC_HIGH_ONLY - sta->ht_cap.ampdu_factor = AMPDU_RX_FACTOR_16K; -#else sta->ht_cap.ampdu_factor = AMPDU_RX_FACTOR_64K; -#endif sta->ht_cap.ampdu_density = AMPDU_DEF_MPDU_DENSITY; sta->ht_cap.cap = IEEE80211_HT_CAP_GRN_FLD | IEEE80211_HT_CAP_SGI_20 | @@ -695,11 +627,7 @@ wl_ampdu_action(struct ieee80211_hw *hw, } static const struct ieee80211_ops wl_ops = { -#ifdef WLC_HIGH_ONLY - .tx = wl_ops_tx_nl, -#else .tx = wl_ops_tx, -#endif .start = wl_ops_start, .stop = wl_ops_stop, .add_interface = wl_ops_add_interface, @@ -761,20 +689,9 @@ static wl_info_t *wl_attach(u16 vendor, u16 device, unsigned long regs, osh = osl_attach(btparam, bustype); ASSERT(osh); -#ifdef WLC_HIGH_ONLY - hw = ieee80211_alloc_hw(sizeof(wl_info_t), &wl_ops); - if (!hw) { - WL_ERROR(("%s: ieee80211_alloc_hw failed\n", __func__)); - ASSERT(0); - } - - bzero(hw->priv, sizeof(*wl)); - wl = hw->priv; -#else /* allocate private info */ hw = pci_get_drvdata(btparam); /* btparam == pdev */ wl = hw->priv; -#endif ASSERT(wl); wl->osh = osh; @@ -783,25 +700,6 @@ static wl_info_t *wl_attach(u16 vendor, u16 device, unsigned long regs, /* setup the bottom half handler */ tasklet_init(&wl->tasklet, wl_dpc, (unsigned long) wl); -#ifdef WLC_HIGH_ONLY - wl->rpc_th = bcm_rpc_tp_attach(osh, NULL); - if (wl->rpc_th == NULL) { - WL_ERROR(("wl%d: %s: bcm_rpc_tp_attach failed!\n", unit, - __func__)); - goto fail; - } - - wl->rpc = bcm_rpc_attach(NULL, osh, wl->rpc_th); - if (wl->rpc == NULL) { - WL_ERROR(("wl%d: %s: bcm_rpc_attach failed!\n", unit, - __func__)); - goto fail; - } - - /* init tx work queue for wl_start/send pkt; no need to destroy workitem */ - INIT_WORK(&wl->txq_task.work, (work_func_t) wl_start_txqwork); - wl->txq_task.context = wl; -#endif /* WLC_HIGH_ONLY */ #ifdef BCMSDIO SET_IEEE80211_DEV(hw, sdiommc_dev); @@ -819,28 +717,14 @@ static wl_info_t *wl_attach(u16 vendor, u16 device, unsigned long regs, } wl->bcm_bustype = bustype; -#ifdef WLC_HIGH_ONLY - if (wl->bcm_bustype == RPC_BUS) { - wl->regsva = (void *)0; - btparam = wl->rpc; - } else -#endif wl->regsva = ioremap_nocache(base_addr, PCI_BAR0_WINSZ); if (wl->regsva == NULL) { WL_ERROR(("wl%d: ioremap() failed\n", unit)); goto fail; } -#ifdef WLC_HIGH_ONLY - spin_lock_init(&wl->rpcq_lock); - spin_lock_init(&wl->txq_lock); - - sema_init(&wl->sem, 1); -#else spin_lock_init(&wl->lock); spin_lock_init(&wl->isr_lock); -#endif -#ifndef WLC_HIGH_ONLY /* prepare ucode */ if (wl_request_fw(wl, (struct pci_dev *)btparam)) { printf("%s: Failed to find firmware usually in %s\n", @@ -849,14 +733,11 @@ static wl_info_t *wl_attach(u16 vendor, u16 device, unsigned long regs, wl_remove((struct pci_dev *)btparam); goto fail1; } -#endif /* common load-time initialization */ wl->wlc = wlc_attach((void *)wl, vendor, device, unit, wl->piomode, osh, wl->regsva, wl->bcm_bustype, btparam, &err); -#ifndef WLC_HIGH_ONLY wl_release_fw(wl); -#endif if (!wl->wlc) { printf("%s: wlc_attach() failed with code %d\n", KBUILD_MODNAME, err); @@ -868,14 +749,6 @@ static wl_info_t *wl_attach(u16 vendor, u16 device, unsigned long regs, ASSERT(wl->pub->ieee_hw); ASSERT(wl->pub->ieee_hw->priv == wl); -#ifdef WLC_HIGH_ONLY - REGOPSSET(osh, (osl_rreg_fn_t) wlc_reg_read, - (osl_wreg_fn_t) wlc_reg_write, wl->wlc); - wl->rpc_dispatch_ctx.rpc = wl->rpc; - wl->rpc_dispatch_ctx.wlc = wl->wlc; - bcm_rpc_rxcb_init(wl->rpc, wl, wl_rpc_dispatch_schedule, wl, - wl_rpc_down, NULL, NULL); -#endif /* WLC_HIGH_ONLY */ if (wlc_iovar_setint(wl->wlc, "mpc", 0)) { WL_ERROR(("wl%d: Error setting MPC variable to 0\n", @@ -922,13 +795,8 @@ static wl_info_t *wl_attach(u16 vendor, u16 device, unsigned long regs, WL_ERROR(("%s: regulatory_hint failed, status %d\n", __func__, err)); } -#ifndef WLC_HIGH_ONLY WL_ERROR(("wl%d: Broadcom BCM43xx 802.11 MAC80211 Driver " " (" PHY_VERSION_STR ")", unit)); -#else - WL_ERROR(("wl%d: Broadcom BCM43xx 802.11 Splitmac MAC80211 Driver " - , unit)); -#endif #ifdef BCMDBG printf(" (Compiled at " __TIME__ " on " __DATE__ ")"); @@ -944,54 +812,6 @@ fail1: return NULL; } -#ifdef WLC_HIGH_ONLY -static void *wl_dbus_probe_cb(void *arg, const char *desc, u32 bustype, - u32 hdrlen) -{ - wl_info_t *wl; - WL_ERROR(("%s:\n", __func__)); - - wl = wl_attach(BCM_DNGL_VID, BCM_DNGL_BDC_PID, (unsigned long) NULL, RPC_BUS, - NULL, 0); - if (!wl) { - WL_ERROR(("%s: wl_attach failed\n", __func__)); - } - - /* This is later passed to wl_dbus_disconnect_cb */ - return wl; -} - -static void wl_dbus_disconnect_cb(void *arg) -{ - wl_info_t *wl = arg; - - WL_ERROR(("%s:\n", __func__)); - - if (wl) { -#ifdef WLC_HIGH_ONLY - if (wl->pub->ieee_hw) { - ieee80211_unregister_hw(wl->pub->ieee_hw); - WL_ERROR(("%s: Back from down\n", __func__)); - } - wlc_device_removed(wl->wlc); - wlc_bmac_dngl_reboot(wl->rpc); - bcm_rpc_down(wl->rpc); -#endif - WL_LOCK(wl); - wl_down(wl); - WL_UNLOCK(wl); -#ifdef WLC_HIGH_ONLY - if (wl->pub->ieee_hw) { - ieee80211_free_hw(wl->pub->ieee_hw); - WL_ERROR(("%s: Back from ieee80211_free_hw\n", - __func__)); - wl->pub->ieee_hw = NULL; - } -#endif - wl_free(wl); - } -} -#endif /* WLC_HIGH_ONLY */ #define CHAN2GHZ(channel, freqency, chflags) { \ @@ -1129,29 +949,13 @@ static struct ieee80211_supported_band wl_band_2GHz_nphy = { .cap = IEEE80211_HT_CAP_GRN_FLD | IEEE80211_HT_CAP_SGI_20 | IEEE80211_HT_CAP_SGI_40 | IEEE80211_HT_CAP_40MHZ_INTOLERANT, -#ifdef WLC_HIGH_ONLY - .ht_supported = true, - .ampdu_factor = AMPDU_RX_FACTOR_16K, -#else .ht_supported = true, .ampdu_factor = AMPDU_RX_FACTOR_64K, -#endif .ampdu_density = AMPDU_DEF_MPDU_DENSITY, .mcs = { /* placeholders for now */ -#ifdef WLC_HIGH_ONLY - /* - * rx_mask[0] = 0xff by default - * rx_mask[1] = 0xff if number of rx chain >=2 - * rx_mask[2] = 0xff if number of rx chain >=3 - * rx_mask[4] = 1 if 40Mhz is supported - */ - .rx_mask = {0xff, 0, 0, 0, 0, 0, 0, 0, 0, 0}, - .rx_highest = 72, /* max rate of single stream */ -#else .rx_mask = {0xff, 0xff, 0, 0, 0, 0, 0, 0, 0, 0}, .rx_highest = 500, -#endif .tx_params = IEEE80211_HT_MCS_TX_DEFINED} } }; @@ -1192,16 +996,12 @@ static int ieee_hw_rate_init(struct ieee80211_hw *hw) } WL_NONE(("%s: phylist = %c\n", __func__, phy_list[0])); -#ifndef WLC_HIGH_ONLY if (phy_list[0] == 'n' || phy_list[0] == 'c') { if (phy_list[0] == 'c') { /* Single stream */ wl_band_2GHz_nphy.ht_cap.mcs.rx_mask[1] = 0; wl_band_2GHz_nphy.ht_cap.mcs.rx_highest = 72; } -#else - if (phy_list[0] == 's') { -#endif hw->wiphy->bands[IEEE80211_BAND_2GHZ] = &wl_band_2GHz_nphy; } else { BUG(); @@ -1211,11 +1011,7 @@ static int ieee_hw_rate_init(struct ieee80211_hw *hw) /* Assume all bands use the same phy. True for 11n devices. */ if (NBANDS_PUB(wl->pub) > 1) { has_5g++; -#ifndef WLC_HIGH_ONLY if (phy_list[0] == 'n' || phy_list[0] == 'c') { -#else - if (phy_list[0] == 's') { -#endif hw->wiphy->bands[IEEE80211_BAND_5GHZ] = &wl_band_5GHz_nphy; } else { @@ -1446,7 +1242,6 @@ static int __init wl_module_init(void) if (var) wl_msg_level = simple_strtoul(var, NULL, 0); } -#ifndef WLC_HIGH_ONLY { extern u32 phyhal_msg_level; @@ -1458,7 +1253,6 @@ static int __init wl_module_init(void) phyhal_msg_level = simple_strtoul(var, NULL, 0); } } -#endif /* WLC_HIGH_ONLY */ #endif /* BCMDBG */ #ifndef BCMSDIO @@ -1468,15 +1262,6 @@ static int __init wl_module_init(void) #endif /* !BCMSDIO */ -#ifdef WLC_HIGH_ONLY - /* BMAC_NOTE: define hardcode number, why NODEVICE is ok ? */ - error = - dbus_register(BCM_DNGL_VID, 0, wl_dbus_probe_cb, - wl_dbus_disconnect_cb, NULL, NULL, NULL); - if (error == DBUS_ERR_NODEVICE) { - error = DBUS_OK; - } -#endif /* WLC_HIGH_ONLY */ return error; } @@ -1494,9 +1279,6 @@ static void __exit wl_module_exit(void) pci_unregister_driver(&wl_pci_driver); #endif /* !BCMSDIO */ -#ifdef WLC_HIGH_ONLY - dbus_deregister(); -#endif /* WLC_HIGH_ONLY */ } module_init(wl_module_init); @@ -1515,13 +1297,11 @@ void wl_free(wl_info_t *wl) struct osl_info *osh; ASSERT(wl); -#ifndef WLC_HIGH_ONLY /* free ucode data */ if (wl->fw.fw_cnt) wl_ucode_data_free(); if (wl->irq) free_irq(wl->irq, wl); -#endif /* kill dpc */ tasklet_kill(&wl->tasklet); @@ -1565,21 +1345,6 @@ void wl_free(wl_info_t *wl) } wl->regsva = NULL; -#ifdef WLC_HIGH_ONLY - wl_rpcq_free(wl); - - wl_txq_free(wl); - - if (wl->rpc) { - bcm_rpc_detach(wl->rpc); - wl->rpc = NULL; - } - - if (wl->rpc_th) { - bcm_rpc_tp_detach(wl->rpc_th); - wl->rpc_th = NULL; - } -#endif /* WLC_HIGH_ONLY */ osl_detach(osh); } @@ -1598,13 +1363,7 @@ static int BCMFASTPATH wl_start(struct sk_buff *skb, wl_info_t *wl) static int BCMFASTPATH wl_start_int(wl_info_t *wl, struct ieee80211_hw *hw, struct sk_buff *skb) { -#ifdef WLC_HIGH_ONLY - WL_LOCK(wl); -#endif wlc_sendpkt_mac80211(wl->wlc, skb, hw); -#ifdef WLC_HIGH_ONLY - WL_UNLOCK(wl); -#endif return NETDEV_TX_OK; } @@ -1613,36 +1372,6 @@ void wl_txflowcontrol(wl_info_t *wl, struct wl_if *wlif, bool state, int prio) WL_ERROR(("Shouldn't be here %s\n", __func__)); } -#if defined(WLC_HIGH_ONLY) -/* Schedule a completion handler to run at safe time */ -static int -wl_schedule_task(wl_info_t *wl, void (*fn) (struct wl_task *task), - void *context) -{ - wl_task_t *task; - - WL_TRACE(("wl%d: wl_schedule_task\n", wl->pub->unit)); - - task = kmalloc(sizeof(wl_task_t), GFP_ATOMIC); - if (!task) { - WL_ERROR(("wl%d: wl_schedule_task: out of memory\n", wl->pub->unit)); - return -ENOMEM; - } - - INIT_WORK(&task->work, (work_func_t) fn); - task->context = context; - - if (!schedule_work(&task->work)) { - WL_ERROR(("wl%d: schedule_work() failed\n", wl->pub->unit)); - kfree(task); - return -ENOMEM; - } - - atomic_inc(&wl->callbacks); - - return 0; -} -#endif /* defined(WLC_HIGH_ONLY) */ void wl_init(wl_info_t *wl) { @@ -1734,12 +1463,10 @@ void wl_down(wl_info_t *wl) /* wait for down callbacks to complete */ WL_UNLOCK(wl); -#ifndef WLC_HIGH_ONLY /* For HIGH_only driver, it's important to actually schedule other work, * not just spin wait since everything runs at schedule level */ SPINWAIT((atomic_read(&wl->callbacks) > callbacks), 100 * 1000); -#endif /* WLC_HIGH_ONLY */ WL_LOCK(wl); } @@ -1843,12 +1570,7 @@ void wl_event(wl_info_t *wl, char *ifname, wlc_event_t *e) static void wl_timer(unsigned long data) { -#ifndef WLC_HIGH_ONLY _wl_timer((wl_timer_t *) data); -#else - wl_timer_t *t = (wl_timer_t *) data; - wl_schedule_task(t->wl, wl_timer_task, t); -#endif /* WLC_HIGH_ONLY */ } static void _wl_timer(wl_timer_t *t) @@ -2015,226 +1737,7 @@ struct wl_fw_hdr { u32 idx; }; -#ifdef WLC_HIGH_ONLY -static void wl_rpc_down(void *wlh) -{ - wl_info_t *wl = (wl_info_t *) (wlh); - - wlc_device_removed(wl->wlc); - - wl_rpcq_free(wl); -} - -static int BCMFASTPATH wl_start(struct sk_buff *skb, wl_info_t *wl) -{ - - unsigned long flags; - - skb->prev = NULL; - - /* Lock the queue as tasklet could be running at this time */ - TXQ_LOCK(wl, flags); - if (wl->txq_head == NULL) - wl->txq_head = skb; - else { - wl->txq_tail->prev = skb; - } - wl->txq_tail = skb; - - if (wl->txq_dispatched == false) { - wl->txq_dispatched = true; - - if (schedule_work(&wl->txq_task.work)) { - atomic_inc(&wl->callbacks); - } else { - WL_ERROR(("wl%d: wl_start/schedule_work failed\n", - wl->pub->unit)); - } - } - - TXQ_UNLOCK(wl, flags); - - return 0; - -} - -static void wl_start_txqwork(struct wl_task *task) -{ - wl_info_t *wl = (wl_info_t *) task->context; - struct sk_buff *skb; - unsigned long flags; - uint count = 0; - - WL_TRACE(("wl%d: wl_start_txqwork\n", wl->pub->unit)); - - /* First remove an entry then go for execution */ - TXQ_LOCK(wl, flags); - while (wl->txq_head) { - skb = wl->txq_head; - wl->txq_head = skb->prev; - skb->prev = NULL; - if (wl->txq_head == NULL) - wl->txq_tail = NULL; - TXQ_UNLOCK(wl, flags); - - /* it has WL_LOCK/WL_UNLOCK inside */ - wl_start_int(wl, WL_TO_HW(wl), skb); - - /* bounded our execution, reshedule ourself next */ - if (++count >= 10) - break; - - TXQ_LOCK(wl, flags); - } - - if (count >= 10) { - if (!schedule_work(&wl->txq_task.work)) { - WL_ERROR(("wl%d: wl_start/schedule_work failed\n", - wl->pub->unit)); - atomic_dec(&wl->callbacks); - } - } else { - wl->txq_dispatched = false; - TXQ_UNLOCK(wl, flags); - atomic_dec(&wl->callbacks); - } - - return; -} - -static void wl_txq_free(wl_info_t *wl) -{ - struct sk_buff *skb; - - if (wl->txq_head == NULL) { - ASSERT(wl->txq_tail == NULL); - return; - } - - while (wl->txq_head) { - skb = wl->txq_head; - wl->txq_head = skb->prev; - PKTFREE(wl->osh, skb, true); - } - - wl->txq_tail = NULL; -} - -static void wl_rpcq_free(wl_info_t *wl) -{ - rpc_buf_t *buf; - - if (wl->rpcq_head == NULL) { - ASSERT(wl->rpcq_tail == NULL); - return; - } - - while (wl->rpcq_head) { - buf = wl->rpcq_head; - wl->rpcq_head = bcm_rpc_buf_next_get(wl->rpc_th, buf); - bcm_rpc_buf_free(wl->rpc_dispatch_ctx.rpc, buf); - } - - wl->rpcq_tail = NULL; -} - -static void wl_rpcq_dispatch(struct wl_task *task) -{ - wl_info_t *wl = (wl_info_t *) task->context; - rpc_buf_t *buf; - unsigned long flags; - - /* First remove an entry then go for execution */ - RPCQ_LOCK(wl, flags); - while (wl->rpcq_head) { - buf = wl->rpcq_head; - wl->rpcq_head = bcm_rpc_buf_next_get(wl->rpc_th, buf); - - if (wl->rpcq_head == NULL) - wl->rpcq_tail = NULL; - RPCQ_UNLOCK(wl, flags); - - WL_LOCK(wl); - wlc_rpc_high_dispatch(&wl->rpc_dispatch_ctx, buf); - WL_UNLOCK(wl); - - RPCQ_LOCK(wl, flags); - } - - wl->rpcq_dispatched = false; - - RPCQ_UNLOCK(wl, flags); - - kfree(task); - atomic_dec(&wl->callbacks); -} - -static void wl_rpcq_add(wl_info_t *wl, rpc_buf_t *buf) -{ - unsigned long flags; - - bcm_rpc_buf_next_set(wl->rpc_th, buf, NULL); - - /* Lock the queue as tasklet could be running at this time */ - RPCQ_LOCK(wl, flags); - if (wl->rpcq_head == NULL) - wl->rpcq_head = buf; - else - bcm_rpc_buf_next_set(wl->rpc_th, wl->rpcq_tail, buf); - - wl->rpcq_tail = buf; - - if (wl->rpcq_dispatched == false) { - wl->rpcq_dispatched = true; - wl_schedule_task(wl, wl_rpcq_dispatch, wl); - } - - RPCQ_UNLOCK(wl, flags); -} - -#if defined(BCMDBG) -static const struct name_entry rpc_name_tbl[] = RPC_ID_TABLE; -#endif /* BCMDBG */ - -/* dongle-side rpc dispatch routine */ -static void wl_rpc_dispatch_schedule(void *ctx, struct rpc_buf *buf) -{ - bcm_xdr_buf_t b; - wl_info_t *wl = (wl_info_t *) ctx; - wlc_rpc_id_t rpc_id; - int err; - - bcm_xdr_buf_init(&b, bcm_rpc_buf_data(wl->rpc_th, buf), - bcm_rpc_buf_len_get(wl->rpc_th, buf)); - - err = bcm_xdr_unpack_u32(&b, &rpc_id); - ASSERT(!err); - WL_TRACE(("%s: Dispatch id %s\n", __func__, - WLC_RPC_ID_LOOKUP(rpc_name_tbl, rpc_id))); - - /* Handle few emergency ones */ - switch (rpc_id) { - default: - wl_rpcq_add(wl, buf); - break; - } -} - -static void wl_timer_task(wl_task_t *task) -{ - wl_timer_t *t = (wl_timer_t *) task->context; - - _wl_timer(t); - kfree(task); - - /* This dec is for the task_schedule. The timer related - * callback is decremented in _wl_timer - */ - atomic_dec(&t->wl->callbacks); -} -#endif /* WLC_HIGH_ONLY */ -#ifndef WLC_HIGH_ONLY char *wl_firmwares[WL_MAX_FW] = { "brcm/bcm43xx", NULL @@ -2345,4 +1848,3 @@ static void wl_release_fw(wl_info_t *wl) release_firmware(wl->fw.fw_hdr[i]); } } -#endif /* WLC_HIGH_ONLY */ diff --git a/drivers/staging/brcm80211/sys/wl_mac80211.h b/drivers/staging/brcm80211/sys/wl_mac80211.h index 54bbb15d9585..ba9d48cd0193 100644 --- a/drivers/staging/brcm80211/sys/wl_mac80211.h +++ b/drivers/staging/brcm80211/sys/wl_mac80211.h @@ -67,12 +67,8 @@ struct wl_info { int irq; -#ifdef WLC_HIGH_ONLY - struct semaphore sem; /* use semaphore to allow sleep */ -#else spinlock_t lock; /* per-device perimeter lock */ spinlock_t isr_lock; /* per-device ISR synchronization lock */ -#endif uint bcm_bustype; /* bus type */ bool piomode; /* set from insmod argument */ void *regsva; /* opaque chip registers virtual address */ @@ -88,30 +84,12 @@ struct wl_info { u32 pci_psstate[16]; /* pci ps-state save/restore */ #endif /* RPC, handle, lock, txq, workitem */ -#ifdef WLC_HIGH_ONLY - rpc_info_t *rpc; /* RPC handle */ - rpc_tp_info_t *rpc_th; /* RPC transport handle */ - wlc_rpc_ctx_t rpc_dispatch_ctx; - - bool rpcq_dispatched; /* Avoid scheduling multiple tasks */ - spinlock_t rpcq_lock; /* Lock for the queue */ - rpc_buf_t *rpcq_head; /* RPC Q */ - rpc_buf_t *rpcq_tail; /* Points to the last buf */ - - bool txq_dispatched; /* Avoid scheduling multiple tasks */ - spinlock_t txq_lock; /* Lock for the queue */ - struct sk_buff *txq_head; /* TX Q */ - struct sk_buff *txq_tail; /* Points to the last buf */ - - wl_task_t txq_task; /* work queue for wl_start() */ -#endif /* WLC_HIGH_ONLY */ uint stats_id; /* the current set of stats */ /* ping-pong stats counters updated by Linux watchdog */ struct net_device_stats stats_watchdog[2]; struct wl_firmware fw; }; -#ifndef WLC_HIGH_ONLY #define WL_LOCK(wl) spin_lock_bh(&(wl)->lock) #define WL_UNLOCK(wl) spin_unlock_bh(&(wl)->lock) @@ -122,14 +100,6 @@ struct wl_info { /* locking under WL_LOCK() to synchronize with wl_isr */ #define INT_LOCK(wl, flags) spin_lock_irqsave(&(wl)->isr_lock, flags) #define INT_UNLOCK(wl, flags) spin_unlock_irqrestore(&(wl)->isr_lock, flags) -#else /* BCMSDIO */ - -#define WL_LOCK(wl) down(&(wl)->sem) -#define WL_UNLOCK(wl) up(&(wl)->sem) - -#define WL_ISRLOCK(wl) -#define WL_ISRUNLOCK(wl) -#endif /* WLC_HIGH_ONLY */ /* handle forward declaration */ typedef struct wl_info wl_info_t; diff --git a/drivers/staging/brcm80211/sys/wlc_alloc.c b/drivers/staging/brcm80211/sys/wlc_alloc.c index 1fb9976ef8b4..e863a81e045c 100644 --- a/drivers/staging/brcm80211/sys/wlc_alloc.c +++ b/drivers/staging/brcm80211/sys/wlc_alloc.c @@ -63,11 +63,6 @@ void wlc_tunables_init(wlc_tunables_t *tunables, uint devid) tunables->ampdudatahiwat = WLC_AMPDUDATAHIWAT; tunables->rxbnd = RXBND; tunables->txsbnd = TXSBND; -#if defined(WLC_HIGH_ONLY) && defined(NTXD_USB_4319) - if (devid == BCM4319_CHIP_ID) { - tunables->ntxd = NTXD_USB_4319; - } -#endif /* WLC_HIGH_ONLY */ } static wlc_pub_t *wlc_pub_malloc(struct osl_info *osh, uint unit, uint *err, diff --git a/drivers/staging/brcm80211/sys/wlc_ampdu.c b/drivers/staging/brcm80211/sys/wlc_ampdu.c index dc327026a0f0..ab883ba76def 100644 --- a/drivers/staging/brcm80211/sys/wlc_ampdu.c +++ b/drivers/staging/brcm80211/sys/wlc_ampdu.c @@ -38,10 +38,6 @@ #include #include -#ifdef WLC_HIGH_ONLY -#include -#include -#endif #define AMPDU_MAX_MPDU 32 /* max number of mpdus in an ampdu */ #define AMPDU_NUM_MPDU_LEGACY 16 /* max number of mpdus in an ampdu to a legacy */ @@ -126,11 +122,6 @@ struct ampdu_info { */ wlc_fifo_info_t fifo_tb[NUM_FFPLD_FIFO]; /* table of fifo infos */ -#ifdef WLC_HIGH_ONLY - void *p; - tx_status_t txs; - bool waiting_status; /* To help sanity checks */ -#endif }; #define AMPDU_CLEANUPFLAG_RX (0x1) @@ -210,10 +201,6 @@ ampdu_info_t *wlc_ampdu_attach(wlc_info_t *wlc) ampdu->rx_factor = AMPDU_RX_FACTOR_32K; else ampdu->rx_factor = AMPDU_RX_FACTOR_64K; -#ifdef WLC_HIGH_ONLY - /* Restrict to smaller rcv size for BMAC dongle */ - ampdu->rx_factor = AMPDU_RX_FACTOR_32K; -#endif ampdu->retry_limit = AMPDU_DEF_RETRY_LIMIT; ampdu->rr_retry_limit = AMPDU_DEF_RR_RETRY_LIMIT; @@ -887,19 +874,9 @@ wlc_sendampdu(ampdu_info_t *ampdu, wlc_txq_info_t *qi, void **pdu, int prec) if (frameid & TXFID_RATE_PROBE_MASK) { WL_ERROR(("%s: XXX what to do with TXFID_RATE_PROBE_MASK!?\n", __func__)); } -#ifdef WLC_HIGH_ONLY - if (wlc->rpc_agg & BCM_RPC_TP_HOST_AGG_AMPDU) - bcm_rpc_tp_agg_set(bcm_rpc_tp_get(wlc->rpc), - BCM_RPC_TP_HOST_AGG_AMPDU, true); -#endif for (i = 0; i < count; i++) wlc_txfifo(wlc, fifo, pkt[i], i == (count - 1), ampdu->txpkt_weight); -#ifdef WLC_HIGH_ONLY - if (wlc->rpc_agg & BCM_RPC_TP_HOST_AGG_AMPDU) - bcm_rpc_tp_agg_set(bcm_rpc_tp_get(wlc->rpc), - BCM_RPC_TP_HOST_AGG_AMPDU, false); -#endif } /* endif (count) */ @@ -967,31 +944,6 @@ wlc_ampdu_dotxstatus(ampdu_info_t *ampdu, struct scb *scb, void *p, wlc_ampdu_txflowcontrol(wlc, scb_ampdu, ini); } -#ifdef WLC_HIGH_ONLY -void wlc_ampdu_txstatus_complete(ampdu_info_t *ampdu, u32 s1, u32 s2) -{ - WL_AMPDU_TX(("wl%d: wlc_ampdu_txstatus_complete: High Recvd 0x%x 0x%x p:%p\n", ampdu->wlc->pub->unit, s1, s2, ampdu->p)); - - ASSERT(ampdu->waiting_status); - - /* The packet may have been freed if the SCB went away, if so, then still free the - * DMA chain - */ - if (ampdu->p) { - struct ieee80211_tx_info *tx_info; - struct scb *scb; - - tx_info = IEEE80211_SKB_CB(ampdu->p); - scb = (struct scb *)tx_info->control.sta->drv_priv; - - wlc_ampdu_dotxstatus_complete(ampdu, scb, ampdu->p, &du->txs, - s1, s2); - ampdu->p = NULL; - } - - ampdu->waiting_status = false; -} -#endif /* WLC_HIGH_ONLY */ void rate_status(wlc_info_t *wlc, struct ieee80211_tx_info *tx_info, tx_status_t *txs, u8 mcs); @@ -1117,11 +1069,6 @@ wlc_ampdu_dotxstatus_complete(ampdu_info_t *ampdu, struct scb *scb, void *p, if (wlc_ffpld_check_txfunfl(wlc, prio2fifo[tid]) > 0) { tx_error = true; -#ifdef WLC_HIGH_ONLY - /* With BMAC, TX Underflows should not happen */ - WL_ERROR(("wl%d: BMAC TX Underflow?", - wlc->pub->unit)); -#endif } } } else if (txs->phyerr) { diff --git a/drivers/staging/brcm80211/sys/wlc_ampdu.h b/drivers/staging/brcm80211/sys/wlc_ampdu.h index c721b16cc706..939cae0d7b4f 100644 --- a/drivers/staging/brcm80211/sys/wlc_ampdu.h +++ b/drivers/staging/brcm80211/sys/wlc_ampdu.h @@ -32,9 +32,5 @@ extern void wlc_ampdu_shm_upd(ampdu_info_t *ampdu); extern u8 wlc_ampdu_null_delim_cnt(ampdu_info_t *ampdu, struct scb *scb, ratespec_t rspec, int phylen); extern void scb_ampdu_cleanup(ampdu_info_t *ampdu, struct scb *scb); -#ifdef WLC_HIGH_ONLY -extern void wlc_ampdu_txstatus_complete(ampdu_info_t *ampdu, u32 s1, - u32 s2); -#endif #endif /* _wlc_ampdu_h_ */ diff --git a/drivers/staging/brcm80211/sys/wlc_bmac.h b/drivers/staging/brcm80211/sys/wlc_bmac.h index 4cc41f9f4619..c3d251a6417a 100644 --- a/drivers/staging/brcm80211/sys/wlc_bmac.h +++ b/drivers/staging/brcm80211/sys/wlc_bmac.h @@ -242,16 +242,6 @@ extern void wlc_bmac_retrylimit_upd(wlc_hw_info_t *wlc_hw, u16 SRL, extern void wlc_bmac_fifoerrors(wlc_hw_info_t *wlc_hw); -#ifdef WLC_HIGH_ONLY -extern void wlc_bmac_dngl_reboot(rpc_info_t *); -extern void wlc_bmac_dngl_rpc_agg(rpc_info_t *, u16 agg); -extern void wlc_bmac_dngl_rpc_msglevel(rpc_info_t *, u16 level); -extern void wlc_bmac_dngl_rpc_txq_wm_set(rpc_info_t *rpc, u32 wm); -extern void wlc_bmac_dngl_rpc_txq_wm_get(rpc_info_t *rpc, u32 *wm); -extern void wlc_bmac_dngl_rpc_agg_limit_set(rpc_info_t *rpc, u32 val); -extern void wlc_bmac_dngl_rpc_agg_limit_get(rpc_info_t *rpc, u32 *pval); -extern int wlc_bmac_debug_template(wlc_hw_info_t *wlc_hw); -#endif /* API for BMAC driver (e.g. wlc_phy.c etc) */ diff --git a/drivers/staging/brcm80211/sys/wlc_mac80211.c b/drivers/staging/brcm80211/sys/wlc_mac80211.c index 513e4d9a1ad2..c270d3f4072f 100644 --- a/drivers/staging/brcm80211/sys/wlc_mac80211.c +++ b/drivers/staging/brcm80211/sys/wlc_mac80211.c @@ -53,23 +53,10 @@ #else #include "d11ucode_ext.h" #endif -#ifdef WLC_HIGH_ONLY -#include -#include -#include -#include -#include -#endif /* WLC_HIGH_ONLY */ #include #include #include -#ifdef WLC_HIGH_ONLY -#undef R_REG -#undef W_REG -#define R_REG(osh, r) RPC_READ_REG(osh, r) -#define W_REG(osh, r, v) RPC_WRITE_REG(osh, r, v) -#endif /* * buffer length needed for wlc_format_ssid @@ -109,12 +96,8 @@ /* To inform the ucode of the last mcast frame posted so that it can clear moredata bit */ #define BCMCFID(wlc, fid) wlc_bmac_write_shm((wlc)->hw, M_BCMC_FID, (fid)) -#ifndef WLC_HIGH_ONLY #define WLC_WAR16165(wlc) (BUSTYPE(wlc->pub->sih->bustype) == PCI_BUS && \ (!AP_ENAB(wlc->pub)) && (wlc->war16165)) -#else -#define WLC_WAR16165(wlc) (false) -#endif /* WLC_HIGH_ONLY */ /* debug/trace */ uint wl_msg_level = @@ -401,22 +384,6 @@ void wlc_reset(wlc_info_t *wlc) wlc_ampdu_reset(wlc->ampdu); wlc->txretried = 0; -#ifdef WLC_HIGH_ONLY - /* Need to set a flag(to be cleared asynchronously by BMAC driver with high call) - * in order to prevent wlc_rpctx_txreclaim() from screwing wlc_rpctx_getnexttxp(), - * which could be invoked by already QUEUED high call(s) from BMAC driver before - * wlc_bmac_reset() finishes. - * It's not needed before in monolithic driver model because d11core interrupts would - * have been cleared instantly in wlc_bmac_reset() and no txstatus interrupt - * will come to driver to fetch those flushed dma pkt pointers. - */ - wlc->reset_bmac_pending = true; - - wlc_rpctx_txreclaim(wlc->rpctx); - - wlc_stf_phy_txant_upd(wlc); - wlc_phy_ant_rxdiv_set(wlc->band->pi, wlc->stf->ant_rx_ovr); -#endif } void wlc_fatal_error(wlc_info_t *wlc) @@ -1858,10 +1825,6 @@ void *wlc_attach(void *wl, u16 vendor, u16 device, uint unit, bool piomode, /* propagate *vars* from BMAC driver to high driver */ wlc_bmac_copyfrom_vars(wlc->hw, &pub->vars, &wlc->vars_size); -#ifdef WLC_HIGH_ONLY - WL_TRACE(("nvram : vars %p , vars_size %d\n", pub->vars, - wlc->vars_size)); -#endif /* set maximum allowed duty cycle */ wlc->tx_duty_cycle_ofdm = @@ -2139,134 +2102,6 @@ static bool wlc_attach_stf_ant_init(wlc_info_t *wlc) return true; } -#ifdef WLC_HIGH_ONLY -/* HIGH_ONLY bmac_attach, which sync over LOW_ONLY bmac_attach states */ -int wlc_bmac_attach(wlc_info_t *wlc, u16 vendor, u16 device, uint unit, - bool piomode, struct osl_info *osh, void *regsva, - uint bustype, void *btparam) -{ - wlc_bmac_revinfo_t revinfo; - uint idx = 0; - rpc_info_t *rpc = (rpc_info_t *) btparam; - - ASSERT(bustype == RPC_BUS); - - /* install the rpc handle in the various state structures used by stub RPC functions */ - wlc->rpc = rpc; - wlc->hw->rpc = rpc; - wlc->hw->osh = osh; - - wlc->regs = 0; - - wlc->rpctx = wlc_rpctx_attach(wlc->pub, wlc); - if (wlc->rpctx == NULL) - return -1; - - /* - * FIFO 0 - * TX: TX_AC_BK_FIFO (TX AC Background data packets) - */ - /* Always initialized */ - ASSERT(NRPCTXBUFPOST <= NTXD); - wlc_rpctx_fifoinit(wlc->rpctx, TX_DATA_FIFO, NRPCTXBUFPOST); - wlc_rpctx_fifoinit(wlc->rpctx, TX_CTL_FIFO, NRPCTXBUFPOST); - wlc_rpctx_fifoinit(wlc->rpctx, TX_BCMC_FIFO, NRPCTXBUFPOST); - - /* VI and BK inited only if WME */ - if (WME_ENAB(wlc->pub)) { - wlc_rpctx_fifoinit(wlc->rpctx, TX_AC_BK_FIFO, NRPCTXBUFPOST); - wlc_rpctx_fifoinit(wlc->rpctx, TX_AC_VI_FIFO, NRPCTXBUFPOST); - } - - /* Allocate SB handle */ - wlc->pub->sih = osl_malloc(wlc->osh, sizeof(si_t)); - if (!wlc->pub->sih) - return -1; - bzero(wlc->pub->sih, sizeof(si_t)); - - /* sync up revinfo with BMAC */ - bzero(&revinfo, sizeof(wlc_bmac_revinfo_t)); - if (wlc_bmac_revinfo_get(wlc->hw, &revinfo) != 0) - return -1; - wlc->vendorid = (u16) revinfo.vendorid; - wlc->deviceid = (u16) revinfo.deviceid; - - wlc->pub->boardrev = (u16) revinfo.boardrev; - wlc->pub->corerev = revinfo.corerev; - wlc->pub->sromrev = (u8) revinfo.sromrev; - wlc->pub->sih->chiprev = revinfo.chiprev; - wlc->pub->sih->chip = revinfo.chip; - wlc->pub->sih->chippkg = revinfo.chippkg; - wlc->pub->sih->boardtype = revinfo.boardtype; - wlc->pub->sih->boardvendor = revinfo.boardvendor; - wlc->pub->sih->bustype = revinfo.bustype; - wlc->pub->sih->buscoretype = revinfo.buscoretype; - wlc->pub->sih->buscorerev = revinfo.buscorerev; - wlc->pub->sih->issim = (bool) revinfo.issim; - wlc->pub->sih->rpc = rpc; - - if (revinfo.nbands == 0 || revinfo.nbands > 2) - return -1; - wlc->pub->_nbands = revinfo.nbands; - - for (idx = 0; idx < wlc->pub->_nbands; idx++) { - uint bandunit, bandtype; /* To access bandstate */ - wlc_phy_t *pi = osl_malloc(wlc->osh, sizeof(wlc_phy_t)); - - if (!pi) - return -1; - bzero(pi, sizeof(wlc_phy_t)); - pi->rpc = rpc; - - bandunit = revinfo.band[idx].bandunit; - bandtype = revinfo.band[idx].bandtype; - wlc->bandstate[bandunit]->radiorev = - (u8) revinfo.band[idx].radiorev; - wlc->bandstate[bandunit]->phytype = - (u16) revinfo.band[idx].phytype; - wlc->bandstate[bandunit]->phyrev = - (u16) revinfo.band[idx].phyrev; - wlc->bandstate[bandunit]->radioid = - (u16) revinfo.band[idx].radioid; - wlc->bandstate[bandunit]->abgphy_encore = - revinfo.band[idx].abgphy_encore; - - wlc->bandstate[bandunit]->pi = pi; - wlc->bandstate[bandunit]->bandunit = bandunit; - wlc->bandstate[bandunit]->bandtype = bandtype; - } - - /* misc stuff */ - - return 0; -} - -/* Free the convenience handles */ -int wlc_bmac_detach(wlc_info_t *wlc) -{ - uint idx; - - if (wlc->pub->sih) { - osl_mfree(wlc->osh, (void *)wlc->pub->sih, sizeof(si_t)); - wlc->pub->sih = NULL; - } - - for (idx = 0; idx < MAXBANDS; idx++) - if (wlc->bandstate[idx]->pi) { - kfree(wlc->bandstate[idx]->pi); - wlc->bandstate[idx]->pi = NULL; - } - - if (wlc->rpctx) { - wlc_rpctx_detach(wlc->rpctx); - wlc->rpctx = NULL; - } - - return 0; - -} - -#endif /* WLC_HIGH_ONLY */ static void wlc_timers_deinit(wlc_info_t *wlc) { @@ -2335,15 +2170,6 @@ uint wlc_detach(wlc_info_t *wlc) /* free other state */ -#ifdef WLC_HIGH_ONLY - /* High-Only driver has an allocated copy of vars, monolithic just - * references the wlc->hw->vars which is freed in wlc_bmac_detach() - */ - if (wlc->pub->vars) { - kfree(wlc->pub->vars); - wlc->pub->vars = NULL; - } -#endif #ifdef BCMDBG if (wlc->country_ie_override) { @@ -2677,10 +2503,6 @@ static void wlc_watchdog(void *arg) #ifdef WLC_LOW wlc_bmac_watchdog(wlc); #endif -#ifdef WLC_HIGH_ONLY - /* maintenance */ - wlc_bmac_rpc_watchdog(wlc); -#endif /* occasionally sample mac stat counters to detect 16-bit counter wrap */ if ((WLC_UPDATE_STATS(wlc)) @@ -2929,9 +2751,6 @@ uint wlc_down(wlc_info_t *wlc) /* wlc_bmac_down_finish has done wlc_coredisable(). so clk is off */ wlc->clk = false; -#ifdef WLC_HIGH_ONLY - wlc_rpctx_txreclaim(wlc->rpctx); -#endif /* Verify all packets are flushed from the driver */ if (PKTALLOCED(wlc->osh) != 0) { @@ -3395,10 +3214,6 @@ _wlc_ioctl(wlc_info_t *wlc, int cmd, void *arg, int len, struct wlc_if *wlcif) wlc_set_chanspec(wlc, chspec); wlc_enable_mac(wlc); } -#ifdef WLC_HIGH_ONLY - /* delay for channel change */ - msleep(50); -#endif break; } @@ -4629,11 +4444,6 @@ wlc_iovar_op(wlc_info_t *wlc, const char *name, /* iovar name not found */ if (i >= WLC_MAXMODULES) { err = BCME_UNSUPPORTED; -#ifdef WLC_HIGH_ONLY - err = - bcmsdh_iovar_op(wlc->btparam, name, params, p_len, arg, len, - set); -#endif goto exit; } @@ -5195,14 +5005,6 @@ u16 wlc_rate_shm_offset(wlc_info_t *wlc, u8 rate) } /* Callback for device removed */ -#if defined(WLC_HIGH_ONLY) -void wlc_device_removed(void *arg) -{ - wlc_info_t *wlc = (wlc_info_t *) arg; - - wlc->device_present = false; -} -#endif /* WLC_HIGH_ONLY */ /* * Attempts to queue a packet onto a multiple-precedence queue, @@ -5467,13 +5269,6 @@ wlc_txfifo(wlc_info_t *wlc, uint fifo, void *p, bool commit, s8 txpktpend) if (WLC_WAR16165(wlc)) wlc_war16165(wlc, true); -#ifdef WLC_HIGH_ONLY - if (RPCTX_ENAB(wlc->pub)) { - (void)wlc_rpctx_tx(wlc->rpctx, fifo, p, commit, frameid, - txpktpend); - return; - } -#else /* Bump up pending count for if not using rpc. If rpc is used, this will be handled * in wlc_bmac_txfifo() @@ -5491,7 +5286,6 @@ wlc_txfifo(wlc_info_t *wlc, uint fifo, void *p, bool commit, s8 txpktpend) if (dma_txfast(wlc->hw->di[fifo], p, commit) < 0) { WL_ERROR(("wlc_txfifo: fatal, toss frames !!!\n")); } -#endif /* WLC_HIGH_ONLY */ } static u16 @@ -5805,9 +5599,7 @@ u16 BCMFASTPATH wlc_phytxctl1_calc(wlc_info_t *wlc, ratespec_t rspec) /* phy clock must support 40Mhz if tx descriptor uses it */ if ((phyctl1 & PHY_TXC1_BW_MASK) >= PHY_TXC1_BW_40MHZ) { ASSERT(CHSPEC_WLC_BW(wlc->chanspec) == WLC_40_MHZ); -#ifndef WLC_HIGH_ONLY ASSERT(wlc->chanspec == wlc_phy_chanspec_get(wlc->band->pi)); -#endif } #endif /* BCMDBG */ return phyctl1; @@ -5988,13 +5780,6 @@ wlc_d11hdrs_mac80211(wlc_info_t *wlc, struct ieee80211_hw *hw, if (txrate[1]->idx < 0) { txrate[1] = txrate[0]; } -#ifdef WLC_HIGH_ONLY - /* Double protection , just in case */ - if (txrate[0]->idx > HIGHEST_SINGLE_STREAM_MCS) - txrate[0]->idx = HIGHEST_SINGLE_STREAM_MCS; - if (txrate[1]->idx > HIGHEST_SINGLE_STREAM_MCS) - txrate[1]->idx = HIGHEST_SINGLE_STREAM_MCS; -#endif for (k = 0; k < hw->max_rates; k++) { is_mcs[k] = @@ -6693,9 +6478,7 @@ void wlc_high_dpc(wlc_info_t *wlc, u32 macintstatus) if (!pktq_empty(&wlc->active_queue->q)) wlc_send_q(wlc, wlc->active_queue); -#ifndef WLC_HIGH_ONLY ASSERT(wlc_ps_check(wlc)); -#endif } static void *wlc_15420war(wlc_info_t *wlc, uint queue) @@ -6906,12 +6689,6 @@ wlc_dotxstatus(wlc_info_t *wlc, tx_status_t *txs, u32 frm_tx2) if (p) PKTFREE(osh, p, true); -#ifdef WLC_HIGH_ONLY - /* If this is a split driver, do the big-hammer here. - * If this is a monolithic driver, wlc_bmac.c:wlc_dpc() will do the big-hammer. - */ - wl_init(wlc->wl); -#endif return true; } @@ -8483,9 +8260,6 @@ void wlc_pllreq(wlc_info_t *wlc, bool set, mbool req_bit) void wlc_reset_bmac_done(wlc_info_t *wlc) { -#ifdef WLC_HIGH_ONLY - wlc->reset_bmac_pending = false; -#endif } void wlc_ht_mimops_cap_update(wlc_info_t *wlc, u8 mimops_mode) diff --git a/drivers/staging/brcm80211/sys/wlc_mac80211.h b/drivers/staging/brcm80211/sys/wlc_mac80211.h index ee0081b307f1..cb142101c0c2 100644 --- a/drivers/staging/brcm80211/sys/wlc_mac80211.h +++ b/drivers/staging/brcm80211/sys/wlc_mac80211.h @@ -214,15 +214,11 @@ extern const u8 prio2fifo[]; * (some platforms return all 0). * If clocks are present, call the sb routine which will figure out if the device is removed. */ -#ifdef WLC_HIGH_ONLY -#define DEVICEREMOVED(wlc) (!wlc->device_present) -#else #define DEVICEREMOVED(wlc) \ ((wlc->hw->clk) ? \ ((R_REG(wlc->hw->osh, &wlc->hw->regs->maccontrol) & \ (MCTL_PSM_JMP_0 | MCTL_IHR_EN)) != MCTL_IHR_EN) : \ (si_deviceremoved(wlc->hw->sih))) -#endif /* WLC_HIGH_ONLY */ #define WLCWLUNIT(wlc) ((wlc)->pub->unit) @@ -578,12 +574,6 @@ struct wlc_info { s8 txpwr_local_max; /* regulatory local txpwr max */ u8 txpwr_local_constraint; /* local power contraint in dB */ -#ifdef WLC_HIGH_ONLY - rpctx_info_t *rpctx; /* RPC TX module */ - bool reset_bmac_pending; /* bmac reset is in progressing */ - u32 rpc_agg; /* host agg: bit 16-31, bmac agg: bit 0-15 */ - u32 rpc_msglevel; /* host rpc: bit 16-31, bmac rpc: bit 0-15 */ -#endif ampdu_info_t *ampdu; /* ampdu module handler */ antsel_info_t *asi; /* antsel module handler */ @@ -843,16 +833,6 @@ struct antsel_info { #endif /* sum the individual fifo tx pending packet counts */ -#if defined(WLC_HIGH_ONLY) -#define TXPKTPENDTOT(wlc) (wlc_rpctx_txpktpend((wlc)->rpctx, 0, true)) -#define TXPKTPENDGET(wlc, fifo) (wlc_rpctx_txpktpend((wlc)->rpctx, (fifo), false)) -#define TXPKTPENDINC(wlc, fifo, val) (wlc_rpctx_txpktpendinc((wlc)->rpctx, (fifo), (val))) -#define TXPKTPENDDEC(wlc, fifo, val) (wlc_rpctx_txpktpenddec((wlc)->rpctx, (fifo), (val))) -#define TXPKTPENDCLR(wlc, fifo) (wlc_rpctx_txpktpendclr((wlc)->rpctx, (fifo))) -#define TXAVAIL(wlc, fifo) (wlc_rpctx_txavail((wlc)->rpctx, (fifo))) -#define GETNEXTTXP(wlc, _queue) (wlc_rpctx_getnexttxp((wlc)->rpctx, (_queue))) - -#else #define TXPKTPENDTOT(wlc) ((wlc)->core->txpktpend[0] + (wlc)->core->txpktpend[1] + \ (wlc)->core->txpktpend[2] + (wlc)->core->txpktpend[3]) #define TXPKTPENDGET(wlc, fifo) ((wlc)->core->txpktpend[(fifo)]) @@ -862,7 +842,6 @@ struct antsel_info { #define TXAVAIL(wlc, fifo) (*(wlc)->core->txavail[(fifo)]) #define GETNEXTTXP(wlc, _queue) \ dma_getnexttxp((wlc)->hw->di[(_queue)], HNDDMA_RANGE_TRANSMITTED) -#endif /* WLC_HIGH_ONLY */ #define WLC_IS_MATCH_SSID(wlc, ssid1, ssid2, len1, len2) \ ((len1 == len2) && !bcmp(ssid1, ssid2, len1)) diff --git a/drivers/staging/brcm80211/sys/wlc_rpctx.h b/drivers/staging/brcm80211/sys/wlc_rpctx.h index 7427154a4bd4..58ce5438632f 100644 --- a/drivers/staging/brcm80211/sys/wlc_rpctx.h +++ b/drivers/staging/brcm80211/sys/wlc_rpctx.h @@ -28,29 +28,6 @@ struct wlc_info; #define NRPCTXBUFPOST NTXD #endif -#if defined(WLC_HIGH_ONLY) - -struct wlc_rpc_phy { - struct rpc_info *rpc; -}; - -#define RPCTX_ENAB(pub) (true) -extern rpctx_info_t *wlc_rpctx_attach(wlc_pub_t *pub, struct wlc_info *wlc); -extern int wlc_rpctx_fifoinit(rpctx_info_t *rpctx, uint fifo, uint ntxd); -extern void wlc_rpctx_detach(rpctx_info_t *rpctx); -extern int wlc_rpctx_dump(rpctx_info_t *rpctx, struct bcmstrbuf *b); -extern void *wlc_rpctx_getnexttxp(rpctx_info_t *rpctx, uint fifo); -extern void wlc_rpctx_txreclaim(rpctx_info_t *rpctx); -extern uint wlc_rpctx_txavail(rpctx_info_t *rpctx, uint fifo); -extern int wlc_rpctx_pkteng(rpctx_info_t *rpctx, uint fifo, void *p); -extern int wlc_rpctx_tx(rpctx_info_t *rpctx, uint fifo, void *p, bool commit, - u16 frameid, u8 txpktpend); -extern void wlc_rpctx_txpktpendinc(rpctx_info_t *rpctx, uint fifo, u8 val); -extern void wlc_rpctx_txpktpenddec(rpctx_info_t *rpctx, uint fifo, u8 val); -extern void wlc_rpctx_txpktpendclr(rpctx_info_t *rpctx, uint fifo); -extern int wlc_rpctx_txpktpend(rpctx_info_t *rpctx, uint fifo, bool all); - -#else #define RPCTX_ENAB(pub) (false) #define wlc_rpctx_attach(pub, wlc) (NULL) #define wlc_rpctx_fifoinit(rpctx, fifo, ntxd) (0) @@ -66,6 +43,5 @@ extern int wlc_rpctx_txpktpend(rpctx_info_t *rpctx, uint fifo, bool all); #define wlc_rpctx_txpktpendclr(rpctx, f) do { } while (0) #define wlc_rpctx_txpktpend(rpctx, f, all) (0) -#endif /* WLC_HIGH */ #endif /* _wlc_rpctx_h_ */ -- cgit v1.2.3 From 02db6b4769e2465b872a6cd87465a3e20d4573ce Mon Sep 17 00:00:00 2001 From: Brett Rudley Date: Fri, 19 Nov 2010 14:30:53 -0800 Subject: staging: brcm80211: unifdef -UWLC_LOW_ONLY Part of BMAC removal. Signed-off-by: Brett Rudley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/sys/wlc_mac80211.h | 9 --------- 1 file changed, 9 deletions(-) diff --git a/drivers/staging/brcm80211/sys/wlc_mac80211.h b/drivers/staging/brcm80211/sys/wlc_mac80211.h index cb142101c0c2..9d0d8f336dde 100644 --- a/drivers/staging/brcm80211/sys/wlc_mac80211.h +++ b/drivers/staging/brcm80211/sys/wlc_mac80211.h @@ -496,15 +496,6 @@ struct wlc_hw_info { #endif bool ucode_loaded; /* true after ucode downloaded */ -#ifdef WLC_LOW_ONLY - struct wl_timer *wdtimer; /* timer for watchdog routine */ - struct ether_addr orig_etheraddr; /* original hw ethernet address */ - u16 rpc_dngl_agg; /* rpc agg control for dongle */ - u32 mem_required_def; /* memory required to replenish RX DMA ring */ - u32 mem_required_lower; /* memory required with lower RX bound */ - u32 mem_required_least; /* minimum memory requirement to handle RX */ - -#endif /* WLC_LOW_ONLY */ u8 hw_stf_ss_opmode; /* STF single stream operation mode */ u8 antsel_type; /* Type of boardlevel mimo antenna switch-logic -- cgit v1.2.3 From 501c09346ce74ec688113d5c6b8a321514935228 Mon Sep 17 00:00:00 2001 From: Brett Rudley Date: Fri, 19 Nov 2010 14:30:54 -0800 Subject: staging: brcm80211: unifdef -DWLC_LOW Part of BMAC removal. Signed-off-by: Brett Rudley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/include/bcm_rpc_tp.h | 4 ---- drivers/staging/brcm80211/include/siutils.h | 10 ---------- drivers/staging/brcm80211/phy/wlc_phy_hal.h | 2 -- drivers/staging/brcm80211/sys/wl_mac80211.c | 22 ---------------------- drivers/staging/brcm80211/sys/wl_mac80211.h | 2 -- drivers/staging/brcm80211/sys/wlc_alloc.c | 4 ---- drivers/staging/brcm80211/sys/wlc_ampdu.c | 13 ------------- drivers/staging/brcm80211/sys/wlc_bmac.c | 3 --- drivers/staging/brcm80211/sys/wlc_bmac.h | 2 -- drivers/staging/brcm80211/sys/wlc_cfg.h | 6 ------ drivers/staging/brcm80211/sys/wlc_mac80211.c | 18 ------------------ drivers/staging/brcm80211/sys/wlc_mac80211.h | 12 ------------ drivers/staging/brcm80211/sys/wlc_rpc.h | 4 ---- drivers/staging/brcm80211/sys/wlc_types.h | 5 ----- 14 files changed, 107 deletions(-) diff --git a/drivers/staging/brcm80211/include/bcm_rpc_tp.h b/drivers/staging/brcm80211/include/bcm_rpc_tp.h index 0136118284f9..6102a495f3bd 100644 --- a/drivers/staging/brcm80211/include/bcm_rpc_tp.h +++ b/drivers/staging/brcm80211/include/bcm_rpc_tp.h @@ -53,9 +53,7 @@ typedef struct rpc_transport_info rpc_tp_info_t; typedef void (*rpc_tx_complete_fn_t) (void *, rpc_buf_t *, int status); typedef void (*rpc_rx_fn_t) (void *, rpc_buf_t *); -#ifdef WLC_LOW typedef void (*rpc_txflowctl_cb_t) (void *ctx, bool on); -#endif extern rpc_tp_info_t *bcm_rpc_tp_attach(struct osl_info *osh, void *bus); extern void bcm_rpc_tp_detach(rpc_tp_info_t *rpcb); @@ -94,7 +92,6 @@ extern int bcm_rpc_tp_get_device_speed(rpc_tp_info_t *rpc_th); extern int bcm_rpc_tp_dump(rpc_tp_info_t *rpcb, struct bcmstrbuf *b); #endif -#ifdef WLC_LOW /* intercept USB pkt to parse RPC header: USB driver rx-> wl_send -> this -> wl driver */ extern void bcm_rpc_tp_rx_from_dnglbus(rpc_tp_info_t *rpc_th, struct lbuf *lb); @@ -110,7 +107,6 @@ extern void bcm_rpc_tp_txq_wm_set(rpc_tp_info_t *rpc_th, u8 hiwm, u8 lowm); extern void bcm_rpc_tp_txq_wm_get(rpc_tp_info_t *rpc_th, u8 *hiwm, u8 *lowm); -#endif /* WLC_LOW */ extern void bcm_rpc_tp_agg_set(rpc_tp_info_t *rpcb, u32 reason, bool set); extern void bcm_rpc_tp_agg_limit_set(rpc_tp_info_t *rpc_th, u8 sf, diff --git a/drivers/staging/brcm80211/include/siutils.h b/drivers/staging/brcm80211/include/siutils.h index 6f83e7e5b313..6a074ab9f34b 100644 --- a/drivers/staging/brcm80211/include/siutils.h +++ b/drivers/staging/brcm80211/include/siutils.h @@ -19,9 +19,6 @@ #include -#if !defined(WLC_LOW) -#include "bcm_rpc.h" -#endif /* * Data structure to export all chip specific common variables * public (read-only) portion of siutils handle returned by si_attach() @@ -50,19 +47,12 @@ struct si_pub { uint socirev; /* SOC interconnect rev */ bool pci_pr32414; -#if !defined(WLC_LOW) - rpc_info_t *rpc; -#endif }; /* for HIGH_ONLY driver, the si_t must be writable to allow states sync from BMAC to HIGH driver * for monolithic driver, it is readonly to prevent accident change */ -#if !defined(WLC_LOW) -typedef struct si_pub si_t; -#else typedef const struct si_pub si_t; -#endif /* * Many of the routines below take an 'sih' handle as their first arg. diff --git a/drivers/staging/brcm80211/phy/wlc_phy_hal.h b/drivers/staging/brcm80211/phy/wlc_phy_hal.h index c462387d20b9..514e15e00283 100644 --- a/drivers/staging/brcm80211/phy/wlc_phy_hal.h +++ b/drivers/staging/brcm80211/phy/wlc_phy_hal.h @@ -146,7 +146,6 @@ typedef struct shared_phy_params { u32 boardflags2; } shared_phy_params_t; -#ifdef WLC_LOW extern shared_phy_t *wlc_phy_shared_attach(shared_phy_params_t *shp); extern void wlc_phy_shared_detach(shared_phy_t *phy_sh); @@ -185,7 +184,6 @@ extern void wlc_phy_set_deaf(wlc_phy_t *ppi, bool user_flag); extern void wlc_phy_switch_radio(wlc_phy_t *ppi, bool on); extern void wlc_phy_anacore(wlc_phy_t *ppi, bool on); -#endif /* WLC_LOW */ extern void wlc_phy_BSSinit(wlc_phy_t *ppi, bool bonlyap, int rssi); diff --git a/drivers/staging/brcm80211/sys/wl_mac80211.c b/drivers/staging/brcm80211/sys/wl_mac80211.c index e336fef111e5..37e6ced84db5 100644 --- a/drivers/staging/brcm80211/sys/wl_mac80211.c +++ b/drivers/staging/brcm80211/sys/wl_mac80211.c @@ -759,14 +759,12 @@ static wl_info_t *wl_attach(u16 vendor, u16 device, unsigned long regs, wlc_iovar_setint(wl->wlc, "sd_drivestrength", sd_drivestrength); #endif -#ifdef WLC_LOW /* register our interrupt handler */ if (request_irq(irq, wl_isr, IRQF_SHARED, KBUILD_MODNAME, wl)) { WL_ERROR(("wl%d: request_irq() failed\n", unit)); goto fail; } wl->irq = irq; -#endif /* WLC_LOW */ /* register module */ wlc_module_register(wl->pub, NULL, "linux", wl, NULL, wl_linux_watchdog, @@ -1349,7 +1347,6 @@ void wl_free(wl_info_t *wl) osl_detach(osh); } -#ifdef WLC_LOW /* transmit a packet */ static int BCMFASTPATH wl_start(struct sk_buff *skb, wl_info_t *wl) { @@ -1358,7 +1355,6 @@ static int BCMFASTPATH wl_start(struct sk_buff *skb, wl_info_t *wl) return wl_start_int(wl, WL_TO_HW(wl), skb); } -#endif /* WLC_LOW */ static int BCMFASTPATH wl_start_int(wl_info_t *wl, struct ieee80211_hw *hw, struct sk_buff *skb) @@ -1400,13 +1396,11 @@ uint wl_reset(wl_info_t *wl) */ void BCMFASTPATH wl_intrson(wl_info_t *wl) { -#if defined(WLC_LOW) unsigned long flags; INT_LOCK(wl, flags); wlc_intrson(wl->wlc); INT_UNLOCK(wl, flags); -#endif /* WLC_LOW */ } bool wl_alloc_dma_resources(wl_info_t *wl, uint addrwidth) @@ -1416,7 +1410,6 @@ bool wl_alloc_dma_resources(wl_info_t *wl, uint addrwidth) u32 BCMFASTPATH wl_intrsoff(wl_info_t *wl) { -#if defined(WLC_LOW) unsigned long flags; u32 status; @@ -1424,20 +1417,15 @@ u32 BCMFASTPATH wl_intrsoff(wl_info_t *wl) status = wlc_intrsoff(wl->wlc); INT_UNLOCK(wl, flags); return status; -#else - return 0; -#endif /* WLC_LOW */ } void wl_intrsrestore(wl_info_t *wl, u32 macintmask) { -#if defined(WLC_LOW) unsigned long flags; INT_LOCK(wl, flags); wlc_intrsrestore(wl->wlc, macintmask); INT_UNLOCK(wl, flags); -#endif /* WLC_LOW */ } int wl_up(wl_info_t *wl) @@ -1473,7 +1461,6 @@ void wl_down(wl_info_t *wl) irqreturn_t BCMFASTPATH wl_isr(int irq, void *dev_id) { -#if defined(WLC_LOW) wl_info_t *wl; bool ours, wantdpc; unsigned long flags; @@ -1498,14 +1485,10 @@ irqreturn_t BCMFASTPATH wl_isr(int irq, void *dev_id) WL_ISRUNLOCK(wl, flags); return IRQ_RETVAL(ours); -#else - return IRQ_RETVAL(0); -#endif /* WLC_LOW */ } static void BCMFASTPATH wl_dpc(unsigned long data) { -#ifdef WLC_LOW wl_info_t *wl; wl = (wl_info_t *) data; @@ -1539,7 +1522,6 @@ static void BCMFASTPATH wl_dpc(unsigned long data) done: WL_UNLOCK(wl); -#endif /* WLC_LOW */ } static void wl_link_up(wl_info_t *wl, char *ifname) @@ -1743,7 +1725,6 @@ char *wl_firmwares[WL_MAX_FW] = { NULL }; -#ifdef WLC_LOW int wl_ucode_init_buf(wl_info_t *wl, void **pbuf, u32 idx) { int i, entry; @@ -1790,7 +1771,6 @@ int wl_ucode_init_uint(wl_info_t *wl, u32 *data, u32 idx) printf("ERROR: ucode tag:%d can not be found!\n", idx); return -1; } -#endif /* WLC_LOW */ static int wl_request_fw(wl_info_t *wl, struct pci_dev *pdev) { @@ -1833,12 +1813,10 @@ static int wl_request_fw(wl_info_t *wl, struct pci_dev *pdev) return 0; } -#ifdef WLC_LOW void wl_ucode_free_buf(void *p) { kfree(p); } -#endif /* WLC_LOW */ static void wl_release_fw(wl_info_t *wl) { diff --git a/drivers/staging/brcm80211/sys/wl_mac80211.h b/drivers/staging/brcm80211/sys/wl_mac80211.h index ba9d48cd0193..220d570710cb 100644 --- a/drivers/staging/brcm80211/sys/wl_mac80211.h +++ b/drivers/staging/brcm80211/sys/wl_mac80211.h @@ -122,10 +122,8 @@ extern void wl_free(wl_info_t *wl); extern int wl_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd); extern int wl_ucode_data_init(wl_info_t *wl); extern void wl_ucode_data_free(void); -#ifdef WLC_LOW extern void wl_ucode_free_buf(void *); extern int wl_ucode_init_buf(wl_info_t *wl, void **pbuf, u32 idx); extern int wl_ucode_init_uint(wl_info_t *wl, u32 *data, u32 idx); -#endif /* WLC_LOW */ #endif /* _wl_mac80211_h_ */ diff --git a/drivers/staging/brcm80211/sys/wlc_alloc.c b/drivers/staging/brcm80211/sys/wlc_alloc.c index e863a81e045c..659ebd0ee2de 100644 --- a/drivers/staging/brcm80211/sys/wlc_alloc.c +++ b/drivers/staging/brcm80211/sys/wlc_alloc.c @@ -196,7 +196,6 @@ wlc_info_t *wlc_attach_malloc(struct osl_info *osh, uint unit, uint *err, } wlc->hw->wlc = wlc; -#ifdef WLC_LOW wlc->hw->bandstate[0] = (wlc_hwband_t *)wlc_calloc(osh, unit, (sizeof(wlc_hwband_t) * MAXBANDS)); if (wlc->hw->bandstate[0] == NULL) { @@ -211,7 +210,6 @@ wlc_info_t *wlc_attach_malloc(struct osl_info *osh, uint unit, uint *err, (sizeof(wlc_hwband_t) * i)); } } -#endif /* WLC_LOW */ wlc->modulecb = (modulecb_t *)wlc_calloc(osh, unit, sizeof(modulecb_t) * WLC_MAXMODULES); @@ -357,12 +355,10 @@ void wlc_detach_mfree(wlc_info_t *wlc, struct osl_info *osh) } if (wlc->hw) { -#ifdef WLC_LOW if (wlc->hw->bandstate[0]) { kfree(wlc->hw->bandstate[0]); wlc->hw->bandstate[0] = NULL; } -#endif /* free hw struct */ kfree(wlc->hw); diff --git a/drivers/staging/brcm80211/sys/wlc_ampdu.c b/drivers/staging/brcm80211/sys/wlc_ampdu.c index ab883ba76def..1fa56cefeed9 100644 --- a/drivers/staging/brcm80211/sys/wlc_ampdu.c +++ b/drivers/staging/brcm80211/sys/wlc_ampdu.c @@ -908,7 +908,6 @@ wlc_ampdu_dotxstatus(ampdu_info_t *ampdu, struct scb *scb, void *p, * call the first one */ if (txs->status & TX_STATUS_ACK_RCV) { -#ifdef WLC_LOW u8 status_delay = 0; /* wait till the next 8 bytes of txstatus is available */ @@ -926,18 +925,6 @@ wlc_ampdu_dotxstatus(ampdu_info_t *ampdu, struct scb *scb, void *p, ASSERT(!(s1 & TX_STATUS_INTERMEDIATE)); ASSERT(s1 & TX_STATUS_AMPDU); s2 = R_REG(wlc->osh, &wlc->regs->frmtxstatus2); -#else /* WLC_LOW */ - - /* Store the relevant information in ampdu structure */ - WL_AMPDU_TX(("wl%d: wlc_ampdu_dotxstatus: High Recvd\n", - wlc->pub->unit)); - - ASSERT(!ampdu->p); - ampdu->p = p; - bcopy(txs, &du->txs, sizeof(tx_status_t)); - ampdu->waiting_status = true; - return; -#endif /* WLC_LOW */ } wlc_ampdu_dotxstatus_complete(ampdu, scb, p, txs, s1, s2); diff --git a/drivers/staging/brcm80211/sys/wlc_bmac.c b/drivers/staging/brcm80211/sys/wlc_bmac.c index 214b5d82ab23..110710ad6e78 100644 --- a/drivers/staging/brcm80211/sys/wlc_bmac.c +++ b/drivers/staging/brcm80211/sys/wlc_bmac.c @@ -14,9 +14,6 @@ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#ifndef WLC_LOW -#error "This file needs WLC_LOW" -#endif #include #include diff --git a/drivers/staging/brcm80211/sys/wlc_bmac.h b/drivers/staging/brcm80211/sys/wlc_bmac.h index c3d251a6417a..c705f667469c 100644 --- a/drivers/staging/brcm80211/sys/wlc_bmac.h +++ b/drivers/staging/brcm80211/sys/wlc_bmac.h @@ -138,9 +138,7 @@ extern void wlc_bmac_watchdog(void *arg); extern void wlc_bmac_info_init(wlc_hw_info_t *wlc_hw); /* up/down, reset, clk */ -#ifdef WLC_LOW extern void wlc_bmac_xtal(wlc_hw_info_t *wlc_hw, bool want); -#endif extern void wlc_bmac_copyto_objmem(wlc_hw_info_t *wlc_hw, uint offset, const void *buf, int len, diff --git a/drivers/staging/brcm80211/sys/wlc_cfg.h b/drivers/staging/brcm80211/sys/wlc_cfg.h index a415e1fd2c05..e36d209c72fd 100644 --- a/drivers/staging/brcm80211/sys/wlc_cfg.h +++ b/drivers/staging/brcm80211/sys/wlc_cfg.h @@ -24,12 +24,6 @@ #define IS_SINGLEBAND_5G(device) 0 /* Keep WLC_HIGH_ONLY, WLC_SPLIT for USB extension later on */ -#if !defined(WLC_LOW) -#define WLC_HIGH_ONLY -#endif -#if !defined(WLC_LOW) -#define WLC_SPLIT -#endif /* **** Core type/rev defaults **** */ #define D11_DEFAULT 0x0fffffb0 /* Supported D11 revs: 4, 5, 7-27 diff --git a/drivers/staging/brcm80211/sys/wlc_mac80211.c b/drivers/staging/brcm80211/sys/wlc_mac80211.c index c270d3f4072f..c6f64c2e461a 100644 --- a/drivers/staging/brcm80211/sys/wlc_mac80211.c +++ b/drivers/staging/brcm80211/sys/wlc_mac80211.c @@ -626,21 +626,11 @@ bool wlc_ps_check(wlc_info_t *wlc) res = false; } -#ifdef WLC_LOW /* For a monolithic build the wake check can be exact since it looks at wake * override bits. The MCTL_WAKE bit should match the 'wake' value. */ wake = STAY_AWAKE(wlc) || wlc->hw->wake_override; wake_ok = (wake == ((tmp & MCTL_WAKE) != 0)); -#else - /* For a split build we will not have access to any wake overrides from the low - * level. The check can only make sure the MCTL_WAKE bit is on if the high - * level 'wake' value is true. If the high level 'wake' is false, the MCTL_WAKE - * may be either true or false due to the low level override. - */ - wake = STAY_AWAKE(wlc); - wake_ok = ((tmp & MCTL_WAKE) != 0) || !wake; -#endif if (hps && !wake_ok) { WL_ERROR(("wl%d: wake not sync, sw %d maccontrol 0x%x\n", wlc->pub->unit, wake, tmp)); res = false; @@ -1842,14 +1832,12 @@ void *wlc_attach(void *wl, u16 vendor, u16 device, uint unit, bool piomode, wlc_phy_stf_chain_init(wlc->band->pi, wlc->stf->hw_txchain, wlc->stf->hw_rxchain); -#ifdef WLC_LOW /* pull up some info resulting from the low attach */ { int i; for (i = 0; i < NFIFO; i++) wlc->core->txavail[i] = wlc->hw->txavail[i]; } -#endif /* WLC_LOW */ wlc_bmac_hw_etheraddr(wlc->hw, &wlc->perm_etheraddr); @@ -2500,9 +2488,7 @@ static void wlc_watchdog(void *arg) if (wlc->pub->radio_disabled) return; -#ifdef WLC_LOW wlc_bmac_watchdog(wlc); -#endif /* occasionally sample mac stat counters to detect 16-bit counter wrap */ if ((WLC_UPDATE_STATS(wlc)) @@ -2531,10 +2517,8 @@ static void wlc_watchdog(void *arg) wlc->tempsense_lasttime = wlc->pub->now; wlc_tempsense_upd(wlc); } -#ifdef WLC_LOW /* BMAC_NOTE: for HIGH_ONLY driver, this seems being called after RPC bus failed */ ASSERT(wlc_bmac_taclear(wlc->hw, true)); -#endif /* Verify that tx_prec_map and fifos are in sync to avoid lock ups */ ASSERT(wlc_tx_prec_map_verify(wlc)); @@ -4228,14 +4212,12 @@ _wlc_ioctl(wlc_info_t *wlc, int cmd, void *arg, int len, struct wlc_if *wlcif) } } -#ifdef WLC_LOW /* BMAC_NOTE: for HIGH_ONLY driver, this seems being called after RPC bus failed */ /* In hw_off condition, IOCTLs that reach here are deemed safe but taclear would * certainly result in getting -1 for register reads. So skip ta_clear altogether */ if (!(wlc->pub->hw_off)) ASSERT(wlc_bmac_taclear(wlc->hw, ta_ok) || !ta_ok); -#endif return bcmerror; } diff --git a/drivers/staging/brcm80211/sys/wlc_mac80211.h b/drivers/staging/brcm80211/sys/wlc_mac80211.h index 9d0d8f336dde..046158813115 100644 --- a/drivers/staging/brcm80211/sys/wlc_mac80211.h +++ b/drivers/staging/brcm80211/sys/wlc_mac80211.h @@ -306,13 +306,11 @@ typedef struct wlc_stf { * core state (mac) */ typedef struct wlccore { -#ifdef WLC_LOW uint coreidx; /* # sb enumerated core */ /* fifo */ uint *txavail[NFIFO]; /* # tx descriptors available */ s16 txpktpend[NFIFO]; /* tx admission control */ -#endif /* WLC_LOW */ macstat_t *macstat_snapshot; /* mac hw prev read values */ } wlccore_t; @@ -406,7 +404,6 @@ struct wlc_if { /* flags for the interface */ #define WLC_IF_LINKED 0x02 /* this interface is linked to a wl_if */ -#ifdef WLC_LOW typedef struct wlc_hwband { int bandtype; /* WLC_BAND_2G, WLC_BAND_5G */ uint bandunit; /* bandstate[] index */ @@ -423,7 +420,6 @@ typedef struct wlc_hwband { wlc_phy_t *pi; /* pointer to phy specific information */ bool abgphy_encore; } wlc_hwband_t; -#endif /* WLC_LOW */ struct wlc_hw_info { #ifdef WLC_SPLIT @@ -436,7 +432,6 @@ struct wlc_hw_info { /* fifo */ hnddma_t *di[NFIFO]; /* hnddma handles, per fifo */ -#ifdef WLC_LOW uint unit; /* device instance number */ /* version info */ @@ -502,7 +497,6 @@ struct wlc_hw_info { * 0 = N/A, 1 = 2x4 board, 2 = 2x3 CB2 board */ u32 antsel_avail; /* put antsel_info_t here if more info is needed */ -#endif /* WLC_LOW */ }; /* TX Queue information @@ -817,11 +811,7 @@ struct antsel_info { #define IS_MBAND_UNLOCKED(wlc) \ ((NBANDS(wlc) > 1) && !(wlc)->bandlocked) -#ifdef WLC_LOW #define WLC_BAND_PI_RADIO_CHANSPEC wlc_phy_chanspec_get(wlc->band->pi) -#else -#define WLC_BAND_PI_RADIO_CHANSPEC (wlc->chanspec) -#endif /* sum the individual fifo tx pending packet counts */ #define TXPKTPENDTOT(wlc) ((wlc)->core->txpktpend[0] + (wlc)->core->txpktpend[1] + \ @@ -881,10 +871,8 @@ extern void wlc_print_txdesc(d11txh_t *txh); extern void wlc_print_dot11_mac_hdr(u8 *buf, int len); #endif -#ifdef WLC_LOW extern void wlc_setxband(wlc_hw_info_t *wlc_hw, uint bandunit); extern void wlc_coredisable(wlc_hw_info_t *wlc_hw); -#endif extern bool wlc_valid_rate(wlc_info_t *wlc, ratespec_t rate, int band, bool verbose); diff --git a/drivers/staging/brcm80211/sys/wlc_rpc.h b/drivers/staging/brcm80211/sys/wlc_rpc.h index db39645ccbdc..e3f31d42dd80 100644 --- a/drivers/staging/brcm80211/sys/wlc_rpc.h +++ b/drivers/staging/brcm80211/sys/wlc_rpc.h @@ -480,13 +480,9 @@ static __inline int _wlc_rpc_call(struct rpc_info *rpc, rpc_buf_t *send) #include #include -#ifdef WLC_LOW extern void wlc_rpc_bmac_dispatch(wlc_rpc_ctx_t *rpc_ctx, struct rpc_buf *buf); extern void wlc_rpc_bmac_dump_txfifohist(wlc_hw_info_t *wlc_hw, bool dump_clear); -#else -extern void wlc_rpc_high_dispatch(wlc_rpc_ctx_t *ctx, struct rpc_buf *buf); -#endif /* Packed structure for ease of transport across RPC bus along u32 boundary */ typedef struct wlc_rpc_txstatus { diff --git a/drivers/staging/brcm80211/sys/wlc_types.h b/drivers/staging/brcm80211/sys/wlc_types.h index 33047ebab979..dffba3e8b62f 100644 --- a/drivers/staging/brcm80211/sys/wlc_types.h +++ b/drivers/staging/brcm80211/sys/wlc_types.h @@ -35,12 +35,7 @@ typedef struct wlc_auth_info wlc_auth_info_t; typedef struct supplicant supplicant_t; typedef struct authenticator authenticator_t; typedef struct antsel_info antsel_info_t; -#if !defined(WLC_LOW) -typedef struct rpctx_info rpctx_info_t; -#endif -#ifdef WLC_LOW typedef struct bmac_pmq bmac_pmq_t; -#endif struct d11init; -- cgit v1.2.3 From f3ce1ef2f80627c2b6339bfc96ee5c1b189cac06 Mon Sep 17 00:00:00 2001 From: Brett Rudley Date: Fri, 19 Nov 2010 14:30:55 -0800 Subject: staging: brcm80211: unifdef -UWLC_SPLIT Part of BMAC removal. Signed-off-by: Brett Rudley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/sys/wlc_mac80211.h | 9 --------- 1 file changed, 9 deletions(-) diff --git a/drivers/staging/brcm80211/sys/wlc_mac80211.h b/drivers/staging/brcm80211/sys/wlc_mac80211.h index 046158813115..459e3cfc84aa 100644 --- a/drivers/staging/brcm80211/sys/wlc_mac80211.h +++ b/drivers/staging/brcm80211/sys/wlc_mac80211.h @@ -20,9 +20,6 @@ #include #include #include -#ifdef WLC_SPLIT -#include -#endif #include #include @@ -422,9 +419,6 @@ typedef struct wlc_hwband { } wlc_hwband_t; struct wlc_hw_info { -#ifdef WLC_SPLIT - rpc_info_t *rpc; /* Handle to RPC module */ -#endif struct osl_info *osh; /* pointer to os handle */ bool _piomode; /* true if pio mode */ wlc_info_t *wlc; @@ -522,9 +516,6 @@ struct wlc_info { d11regs_t *regs; /* pointer to device registers */ wlc_hw_info_t *hw; /* HW related state used primarily by BMAC */ -#ifdef WLC_SPLIT - rpc_info_t *rpc; /* Handle to RPC module */ -#endif /* clock */ int clkreq_override; /* setting for clkreq for PCIE : Auto, 0, 1 */ -- cgit v1.2.3 From c73b9d6759993f521e3b0cb24abf74c4527469e3 Mon Sep 17 00:00:00 2001 From: Brett Rudley Date: Fri, 19 Nov 2010 14:30:56 -0800 Subject: staging: brcm80211: remove bmac-only header files Part of BMAC removal. Signed-off-by: Brett Rudley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/include/bcm_rpc.h | 79 ---- drivers/staging/brcm80211/include/bcm_rpc_tp.h | 133 ------- drivers/staging/brcm80211/include/bcm_xdr.h | 60 --- drivers/staging/brcm80211/include/dbus.h | 353 ----------------- drivers/staging/brcm80211/sys/wlc_rpc.h | 523 ------------------------- drivers/staging/brcm80211/sys/wlc_rpctx.h | 47 --- 6 files changed, 1195 deletions(-) delete mode 100644 drivers/staging/brcm80211/include/bcm_rpc.h delete mode 100644 drivers/staging/brcm80211/include/bcm_rpc_tp.h delete mode 100644 drivers/staging/brcm80211/include/bcm_xdr.h delete mode 100644 drivers/staging/brcm80211/include/dbus.h delete mode 100644 drivers/staging/brcm80211/sys/wlc_rpc.h delete mode 100644 drivers/staging/brcm80211/sys/wlc_rpctx.h diff --git a/drivers/staging/brcm80211/include/bcm_rpc.h b/drivers/staging/brcm80211/include/bcm_rpc.h deleted file mode 100644 index 7a379ba15ce1..000000000000 --- a/drivers/staging/brcm80211/include/bcm_rpc.h +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _BCM_RPC_H_ -#define _BCM_RPC_H_ - -#include - -typedef struct rpc_info rpc_info_t; -typedef struct rpc_buf rpc_buf_t; -struct rpc_transport_info; -typedef void (*rpc_dispatch_cb_t) (void *ctx, struct rpc_buf *buf); -typedef void (*rpc_resync_cb_t) (void *ctx); -typedef void (*rpc_down_cb_t) (void *ctx); -typedef void (*rpc_txdone_cb_t) (void *ctx, struct rpc_buf *buf); -extern struct rpc_info *bcm_rpc_attach(void *pdev, struct osl_info *osh, - struct rpc_transport_info *rpc_th); - -extern void bcm_rpc_detach(struct rpc_info *rpc); -extern void bcm_rpc_down(struct rpc_info *rpc); -extern void bcm_rpc_watchdog(struct rpc_info *rpc); - -extern struct rpc_buf *bcm_rpc_buf_alloc(struct rpc_info *rpc, int len); -extern void bcm_rpc_buf_free(struct rpc_info *rpc, struct rpc_buf *b); -/* get rpc transport handle */ -extern struct rpc_transport_info *bcm_rpc_tp_get(struct rpc_info *rpc); - -/* callback for: data_rx, down, resync */ -extern void bcm_rpc_rxcb_init(struct rpc_info *rpc, void *ctx, - rpc_dispatch_cb_t cb, void *dnctx, - rpc_down_cb_t dncb, rpc_resync_cb_t resync_cb, - rpc_txdone_cb_t); -extern void bcm_rpc_rxcb_deinit(struct rpc_info *rpci); - -/* HOST or CLIENT rpc call, requiring no return value */ -extern int bcm_rpc_call(struct rpc_info *rpc, struct rpc_buf *b); - -/* HOST rpc call, demanding return. - * The thread may be suspended and control returns back to OS - * The thread will resume(waked up) on either the return signal received or timeout - * The implementation details depend on OS - */ -extern struct rpc_buf *bcm_rpc_call_with_return(struct rpc_info *rpc, - struct rpc_buf *b); - -/* CLIENT rpc call to respond to bcm_rpc_call_with_return, requiring no return value */ -extern int bcm_rpc_call_return(struct rpc_info *rpc, struct rpc_buf *retb); - -extern uint bcm_rpc_buf_header_len(struct rpc_info *rpci); - -#define RPC_PKTLOG_SIZE 50 /* Depth of the history */ -#define RPC_PKTLOG_RD_LEN 3 -#define RPC_PKTLOG_DUMP_SIZE 150 /* dump size should be more than the product of above two */ -extern int bcm_rpc_pktlog_get(struct rpc_info *rpci, u32 *buf, - uint buf_size, bool send); -extern int bcm_rpc_dump(rpc_info_t *rpci, struct bcmstrbuf *b); - -/* HIGH/BMAC: bit 15-8: RPC module, bit 7-0: TP module */ -#define RPC_ERROR_VAL 0x0001 -#define RPC_TRACE_VAL 0x0002 -#define RPC_PKTTRACE_VAL 0x0004 -#define RPC_PKTLOG_VAL 0x0008 -extern void bcm_rpc_msglevel_set(struct rpc_info *rpci, u16 msglevel, - bool high_low); - -#endif /* _BCM_RPC_H_ */ diff --git a/drivers/staging/brcm80211/include/bcm_rpc_tp.h b/drivers/staging/brcm80211/include/bcm_rpc_tp.h deleted file mode 100644 index 6102a495f3bd..000000000000 --- a/drivers/staging/brcm80211/include/bcm_rpc_tp.h +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _bcm_rpc_tp_h_ -#define _bcm_rpc_tp_h_ -#include - -#define DBUS_RX_BUFFER_SIZE_RPC (2100) /* rxbufsize for dbus_attach, linux only for now */ - -#define BCM_RPC_TP_ENCAP_LEN 4 /* TP header is 4 bytes */ - -#define BCM_RPC_TP_HOST_AGG_MASK 0xffff0000 -#define BCM_RPC_TP_HOST_AGG_SHIFT 16 -#define BCM_RPC_TP_HOST_AGG_AMPDU 0x00010000 /* HOST->DNGL ampdu aggregation */ -#define BCM_RPC_TP_HOST_AGG_TEST 0x00100000 /* HOST->DNGL test aggregation */ -#define BCM_RPC_TP_DNGL_AGG_MASK 0x0000ffff -#define BCM_RPC_TP_DNGL_AGG_DPC 0x00000001 /* DNGL->HOST data aggregation */ -#define BCM_RPC_TP_DNGL_AGG_FLOWCTL 0x00000002 /* DNGL->HOST tx flowcontrol agg */ -#define BCM_RPC_TP_DNGL_AGG_TEST 0x00000010 /* DNGL->HOST test agg */ - -#define BCM_RPC_TP_DNGL_AGG_MAX_SFRAME 3 /* max agg subframes, must be <= USB_NTXD */ -#define BCM_RPC_TP_DNGL_AGG_MAX_BYTE 4000 /* max agg bytes */ - -#define BCM_RPC_TP_HOST_AGG_MAX_SFRAME 3 /* max agg subframes, AMPDU only, 3 is enough */ -#define BCM_RPC_TP_HOST_AGG_MAX_BYTE 3400 /* max agg bytes; to fit 2+ tcp/udp pkts. Each one: - * 802.3pkt + 802.11 hdr + rpc hdr + tp hdr < 1700B - * Need to be in sync with dongle usb rx dma - * rxbufsize(USBBULK_RXBUF_GIANT in usbdev_sb.c) - */ -/* TP-DBUS pkts flowcontrol */ -#define BCM_RPC_TP_DBUS_NTXQ 50 /* queue size for TX on bulk OUT, aggregation possible */ -#define BCM_RPC_TP_DBUS_NRXQ 50 /* queue size for RX on bulk IN, aggregation possible */ -#define BCM_RPC_TP_DBUS_NRXQ_CTRL 1 /* queue size for RX on ctl EP0 */ - -#define BCM_RPC_TP_DBUS_NRXQ_PKT (BCM_RPC_TP_DBUS_NRXQ * BCM_RPC_TP_DNGL_AGG_MAX_SFRAME) -#define BCM_RPC_TP_DBUS_NTXQ_PKT (BCM_RPC_TP_DBUS_NTXQ * BCM_RPC_TP_HOST_AGG_MAX_SFRAME) - -typedef struct rpc_transport_info rpc_tp_info_t; - -typedef void (*rpc_tx_complete_fn_t) (void *, rpc_buf_t *, int status); -typedef void (*rpc_rx_fn_t) (void *, rpc_buf_t *); - -typedef void (*rpc_txflowctl_cb_t) (void *ctx, bool on); - -extern rpc_tp_info_t *bcm_rpc_tp_attach(struct osl_info *osh, void *bus); -extern void bcm_rpc_tp_detach(rpc_tp_info_t *rpcb); -extern void bcm_rpc_tp_down(rpc_tp_info_t *rpcb); -extern void bcm_rpc_tp_watchdog(rpc_tp_info_t *rpcb); - -extern int bcm_rpc_tp_buf_send(rpc_tp_info_t *rpcb, rpc_buf_t *buf); - -/* callback for tx_complete, rx_pkt */ -extern void bcm_rpc_tp_register_cb(rpc_tp_info_t *rpcb, - rpc_tx_complete_fn_t txcmplt, - void *tx_context, rpc_rx_fn_t rxpkt, - void *rx_context, rpc_osl_t *rpc_osh); -extern void bcm_rpc_tp_deregister_cb(rpc_tp_info_t *rpcb); - -/* Buffer manipulation */ -extern uint bcm_rpc_buf_tp_header_len(rpc_tp_info_t *rpcb); -extern rpc_buf_t *bcm_rpc_tp_buf_alloc(rpc_tp_info_t *rpcb, int len); -extern void bcm_rpc_tp_buf_free(rpc_tp_info_t *rpcb, rpc_buf_t *buf); -extern int bcm_rpc_buf_len_get(rpc_tp_info_t *rpcb, rpc_buf_t *b); -extern int bcm_rpc_buf_len_set(rpc_tp_info_t *rpcb, rpc_buf_t *b, uint len); -extern rpc_buf_t *bcm_rpc_buf_next_get(rpc_tp_info_t *rpcb, rpc_buf_t *b); -extern void bcm_rpc_buf_next_set(rpc_tp_info_t *rpcb, rpc_buf_t *b, - rpc_buf_t *nextb); -extern unsigned char *bcm_rpc_buf_data(rpc_tp_info_t *rpcb, rpc_buf_t *b); -extern unsigned char *bcm_rpc_buf_push(rpc_tp_info_t *rpcb, rpc_buf_t *b, - uint delta); -extern unsigned char *bcm_rpc_buf_pull(rpc_tp_info_t *rpcb, rpc_buf_t *b, - uint delta); -extern void bcm_rpc_tp_buf_release(rpc_tp_info_t *rpcb, rpc_buf_t *buf); -extern void bcm_rpc_tp_buf_cnt_adjust(rpc_tp_info_t *rpcb, int adjust); -/* RPC call_with_return */ -extern int bcm_rpc_tp_recv_rtn(rpc_tp_info_t *rpcb); -extern int bcm_rpc_tp_get_device_speed(rpc_tp_info_t *rpc_th); -#ifdef BCMDBG -extern int bcm_rpc_tp_dump(rpc_tp_info_t *rpcb, struct bcmstrbuf *b); -#endif - -/* intercept USB pkt to parse RPC header: USB driver rx-> wl_send -> this -> wl driver */ -extern void bcm_rpc_tp_rx_from_dnglbus(rpc_tp_info_t *rpc_th, struct lbuf *lb); - -/* RPC callreturn pkt, go to USB driver tx */ -extern int bcm_rpc_tp_send_callreturn(rpc_tp_info_t *rpc_th, rpc_buf_t *b); - -extern void bcm_rpc_tp_dump(rpc_tp_info_t *rpcb); -extern void bcm_rpc_tp_txflowctl(rpc_tp_info_t *rpcb, bool state, int prio); -extern void bcm_rpc_tp_txflowctlcb_init(rpc_tp_info_t *rpc_th, void *ctx, - rpc_txflowctl_cb_t cb); -extern void bcm_rpc_tp_txflowctlcb_deinit(rpc_tp_info_t *rpc_th); -extern void bcm_rpc_tp_txq_wm_set(rpc_tp_info_t *rpc_th, u8 hiwm, - u8 lowm); -extern void bcm_rpc_tp_txq_wm_get(rpc_tp_info_t *rpc_th, u8 *hiwm, - u8 *lowm); - -extern void bcm_rpc_tp_agg_set(rpc_tp_info_t *rpcb, u32 reason, bool set); -extern void bcm_rpc_tp_agg_limit_set(rpc_tp_info_t *rpc_th, u8 sf, - u16 bytes); -extern void bcm_rpc_tp_agg_limit_get(rpc_tp_info_t *rpc_th, u8 *sf, - u16 *bytes); - -#define BCM_RPC_TP_MSG_LEVEL_MASK 0x00ff -/* dongle msg level */ -#define RPC_TP_MSG_DNGL_ERR_VAL 0x0001 /* DNGL TP error msg */ -#define RPC_TP_MSG_DNGL_DBG_VAL 0x0002 /* DNGL TP dbg msg */ -#define RPC_TP_MSG_DNGL_AGG_VAL 0x0004 /* DNGL TP agg msg */ -#define RPC_TP_MSG_DNGL_DEA_VAL 0x0008 /* DNGL TP deag msg */ - -/* host msg level */ -#define RPC_TP_MSG_HOST_ERR_VAL 0x0001 /* DNGL TP error msg */ -#define RPC_TP_MSG_HOST_DBG_VAL 0x0002 /* DNGL TP dbg msg */ -#define RPC_TP_MSG_HOST_AGG_VAL 0x0004 /* DNGL TP agg msg */ -#define RPC_TP_MSG_HOST_DEA_VAL 0x0008 /* DNGL TP deag msg */ - -extern void bcm_rpc_tp_msglevel_set(rpc_tp_info_t *rpc_th, u8 msglevel, - bool high_low); - -#endif /* _bcm_rpc_tp_h_ */ diff --git a/drivers/staging/brcm80211/include/bcm_xdr.h b/drivers/staging/brcm80211/include/bcm_xdr.h deleted file mode 100644 index 50fbd78a8804..000000000000 --- a/drivers/staging/brcm80211/include/bcm_xdr.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _BCM_XDR_H -#define _BCM_XDR_H - -/* - * bcm_xdr_buf_t - * Structure used for bookkeeping of a buffer being packed or unpacked. - * Keeps a current read/write pointer and size as well as - * the original buffer pointer and size. - * - */ -typedef struct { - u8 *buf; /* pointer to current position in origbuf */ - uint size; /* current (residual) size in bytes */ - u8 *origbuf; /* unmodified pointer to orignal buffer */ - uint origsize; /* unmodified orignal buffer size in bytes */ -} bcm_xdr_buf_t; - -void bcm_xdr_buf_init(bcm_xdr_buf_t *b, void *buf, size_t len); - -int bcm_xdr_pack_u32(bcm_xdr_buf_t *b, u32 val); -int bcm_xdr_unpack_u32(bcm_xdr_buf_t *b, u32 *pval); -int bcm_xdr_pack_s32(bcm_xdr_buf_t *b, s32 val); -int bcm_xdr_unpack_s32(bcm_xdr_buf_t *b, s32 *pval); -int bcm_xdr_pack_s8(bcm_xdr_buf_t *b, s8 val); -int bcm_xdr_unpack_s8(bcm_xdr_buf_t *b, s8 *pval); -int bcm_xdr_pack_opaque(bcm_xdr_buf_t *b, uint len, void *data); -int bcm_xdr_unpack_opaque(bcm_xdr_buf_t *b, uint len, void **pdata); -int bcm_xdr_unpack_opaque_cpy(bcm_xdr_buf_t *b, uint len, void *data); -int bcm_xdr_pack_opaque_varlen(bcm_xdr_buf_t *b, uint len, void *data); -int bcm_xdr_unpack_opaque_varlen(bcm_xdr_buf_t *b, uint *plen, void **pdata); -int bcm_xdr_pack_string(bcm_xdr_buf_t *b, char *str); -int bcm_xdr_unpack_string(bcm_xdr_buf_t *b, uint *plen, char **pstr); - -int bcm_xdr_pack_u8_vec(bcm_xdr_buf_t *, u8 *vec, u32 elems); -int bcm_xdr_unpack_u8_vec(bcm_xdr_buf_t *, u8 *vec, u32 elems); -int bcm_xdr_pack_u16_vec(bcm_xdr_buf_t *b, uint len, void *vec); -int bcm_xdr_unpack_u16_vec(bcm_xdr_buf_t *b, uint len, void *vec); -int bcm_xdr_pack_u32_vec(bcm_xdr_buf_t *b, uint len, void *vec); -int bcm_xdr_unpack_u32_vec(bcm_xdr_buf_t *b, uint len, void *vec); - -int bcm_xdr_pack_opaque_raw(bcm_xdr_buf_t *b, uint len, void *data); -int bcm_xdr_pack_opaque_pad(bcm_xdr_buf_t *b); - -#endif /* _BCM_XDR_H */ diff --git a/drivers/staging/brcm80211/include/dbus.h b/drivers/staging/brcm80211/include/dbus.h deleted file mode 100644 index 81ffea79d008..000000000000 --- a/drivers/staging/brcm80211/include/dbus.h +++ /dev/null @@ -1,353 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef __DBUS_H__ -#define __DBUS_H__ - -#ifdef BCMDBG -#define DBUSERR(args) do { if (net_ratelimit()) printf args; } while (0) -#define DBUSTRACE(args) -#define DBUSDBGLOCK(args) - -#else -#define DBUSTRACE(args) -#define DBUSERR(args) -#define DBUSDBGLOCK(args) -#endif - -enum { - DBUS_OK = 0, - DBUS_ERR = -200, - DBUS_ERR_TIMEOUT, - DBUS_ERR_DISCONNECT, - DBUS_ERR_NODEVICE, - DBUS_ERR_UNSUPPORTED, - DBUS_ERR_PENDING, - DBUS_ERR_NOMEM, - DBUS_ERR_TXFAIL, - DBUS_ERR_TXTIMEOUT, - DBUS_ERR_TXDROP, - DBUS_ERR_RXFAIL, - DBUS_ERR_RXDROP, - DBUS_ERR_TXCTLFAIL, - DBUS_ERR_RXCTLFAIL, - DBUS_ERR_REG_PARAM, - DBUS_STATUS_CANCELLED -}; - -#define ERR_CBMASK_TXFAIL 0x00000001 -#define ERR_CBMASK_RXFAIL 0x00000002 -#define ERR_CBMASK_ALL 0xFFFFFFFF - -#define DBUS_CBCTL_WRITE 0 -#define DBUS_CBCTL_READ 1 - -#define DBUS_TX_RETRY_LIMIT 3 /* retries for failed txirb */ -#define DBUS_TX_TIMEOUT_INTERVAL 250 /* timeout for txirb complete, in ms */ - -#define DBUS_BUFFER_SIZE_TX 5000 -#define DBUS_BUFFER_SIZE_RX 5000 - -#define DBUS_BUFFER_SIZE_TX_NOAGG 2048 -#define DBUS_BUFFER_SIZE_RX_NOAGG 2048 - -/* DBUS types */ -enum { - DBUS_USB, - DBUS_SDIO, - DBUS_SPI, - DBUS_UNKNOWN -}; - -enum dbus_state { - DBUS_STATE_DL_PENDING, - DBUS_STATE_DL_DONE, - DBUS_STATE_UP, - DBUS_STATE_DOWN, - DBUS_STATE_PNP_FWDL, - DBUS_STATE_DISCONNECT -}; - -enum dbus_pnp_state { - DBUS_PNP_DISCONNECT, - DBUS_PNP_SLEEP, - DBUS_PNP_RESUME -}; - -typedef enum _DEVICE_SPEED { - INVALID_SPEED = -1, - LOW_SPEED = 1, /* USB 1.1: 1.5 Mbps */ - FULL_SPEED, /* USB 1.1: 12 Mbps */ - HIGH_SPEED, /* USB 2.0: 480 Mbps */ - SUPER_SPEED, /* USB 3.0: 4.8 Gbps */ -} DEVICE_SPEED; - -typedef struct { - int bustype; - int vid; - int pid; - int devid; - int chiprev; /* chip revsion number */ - int mtu; - int nchan; /* Data Channels */ -} dbus_attrib_t; - -/* FIX: Account for errors related to DBUS; - * Let upper layer account for packets/bytes - */ -typedef struct { - u32 rx_errors; - u32 tx_errors; - u32 rx_dropped; - u32 tx_dropped; -} dbus_stats_t; - -/* - * Configurable BUS parameters - */ -typedef struct { - bool rxctl_deferrespok; -} dbus_config_t; - -struct dbus_callbacks; -struct exec_parms; - -typedef void *(*probe_cb_t) (void *arg, const char *desc, u32 bustype, - u32 hdrlen); -typedef void (*disconnect_cb_t) (void *arg); -typedef void *(*exec_cb_t) (struct exec_parms *args); - -/* Client callbacks registered during dbus_attach() */ -typedef struct dbus_callbacks { - void (*send_complete) (void *cbarg, void *info, int status); - void (*recv_buf) (void *cbarg, u8 *buf, int len); - void (*recv_pkt) (void *cbarg, void *pkt); - void (*txflowcontrol) (void *cbarg, bool onoff); - void (*errhandler) (void *cbarg, int err); - void (*ctl_complete) (void *cbarg, int type, int status); - void (*state_change) (void *cbarg, int state); - void *(*pktget) (void *cbarg, uint len, bool send); - void (*pktfree) (void *cbarg, void *p, bool send); -} dbus_callbacks_t; - -struct dbus_pub; -struct bcmstrbuf; -struct dbus_irb; -struct dbus_irb_rx; -struct dbus_irb_tx; -struct dbus_intf_callbacks; - -typedef struct { - void *(*attach) (struct dbus_pub *pub, void *cbarg, - struct dbus_intf_callbacks *cbs); - void (*detach) (struct dbus_pub *pub, void *bus); - - int (*up) (void *bus); - int (*down) (void *bus); - int (*send_irb) (void *bus, struct dbus_irb_tx *txirb); - int (*recv_irb) (void *bus, struct dbus_irb_rx *rxirb); - int (*cancel_irb) (void *bus, struct dbus_irb_tx *txirb); - int (*send_ctl) (void *bus, u8 *buf, int len); - int (*recv_ctl) (void *bus, u8 *buf, int len); - int (*get_stats) (void *bus, dbus_stats_t *stats); - int (*get_attrib) (void *bus, dbus_attrib_t *attrib); - - int (*pnp) (void *bus, int event); - int (*remove) (void *bus); - int (*resume) (void *bus); - int (*suspend) (void *bus); - int (*stop) (void *bus); - int (*reset) (void *bus); - - /* Access to bus buffers directly */ - void *(*pktget) (void *bus, int len); - void (*pktfree) (void *bus, void *pkt); - - int (*iovar_op) (void *bus, const char *name, void *params, int plen, - void *arg, int len, bool set); - void (*dump) (void *bus, struct bcmstrbuf *strbuf); - int (*set_config) (void *bus, dbus_config_t *config); - int (*get_config) (void *bus, dbus_config_t *config); - - bool(*device_exists) (void *bus); - bool(*dlneeded) (void *bus); - int (*dlstart) (void *bus, u8 *fw, int len); - int (*dlrun) (void *bus); - bool(*recv_needed) (void *bus); - - void *(*exec_rxlock) (void *bus, exec_cb_t func, - struct exec_parms *args); - void *(*exec_txlock) (void *bus, exec_cb_t func, - struct exec_parms *args); - - int (*tx_timer_init) (void *bus); - int (*tx_timer_start) (void *bus, uint timeout); - int (*tx_timer_stop) (void *bus); - - int (*sched_dpc) (void *bus); - int (*lock) (void *bus); - int (*unlock) (void *bus); - int (*sched_probe_cb) (void *bus); - - int (*shutdown) (void *bus); - - int (*recv_stop) (void *bus); - int (*recv_resume) (void *bus); - - /* Add from the bottom */ -} dbus_intf_t; - -typedef struct dbus_pub { - struct osl_info *osh; - dbus_stats_t stats; - dbus_attrib_t attrib; - enum dbus_state busstate; - DEVICE_SPEED device_speed; - int ntxq, nrxq, rxsize; - void *bus; - struct shared_info *sh; -} dbus_pub_t; - -#define BUS_INFO(bus, type) (((type *) bus)->pub->bus) - -/* - * Public Bus Function Interface - */ -extern int dbus_register(int vid, int pid, probe_cb_t prcb, - disconnect_cb_t discb, void *prarg, void *param1, - void *param2); -extern int dbus_deregister(void); - -extern const dbus_pub_t *dbus_attach(struct osl_info *osh, int rxsize, int nrxq, - int ntxq, void *cbarg, - dbus_callbacks_t *cbs, - struct shared_info *sh); -extern void dbus_detach(const dbus_pub_t *pub); - -extern int dbus_up(const dbus_pub_t *pub); -extern int dbus_down(const dbus_pub_t *pub); -extern int dbus_stop(const dbus_pub_t *pub); -extern int dbus_shutdown(const dbus_pub_t *pub); -extern void dbus_flowctrl_rx(const dbus_pub_t *pub, bool on); - -extern int dbus_send_buf(const dbus_pub_t *pub, u8 *buf, int len, - void *info); -extern int dbus_send_pkt(const dbus_pub_t *pub, void *pkt, void *info); -extern int dbus_send_ctl(const dbus_pub_t *pub, u8 *buf, int len); -extern int dbus_recv_ctl(const dbus_pub_t *pub, u8 *buf, int len); - -extern int dbus_get_stats(const dbus_pub_t *pub, dbus_stats_t *stats); -extern int dbus_get_attrib(const dbus_pub_t *pub, dbus_attrib_t *attrib); -extern int dbus_get_device_speed(const dbus_pub_t *pub); -extern int dbus_set_config(const dbus_pub_t *pub, dbus_config_t *config); -extern int dbus_get_config(const dbus_pub_t *pub, dbus_config_t *config); - -extern void *dbus_pktget(const dbus_pub_t *pub, int len); -extern void dbus_pktfree(const dbus_pub_t *pub, void *pkt); - -extern int dbus_set_errmask(const dbus_pub_t *pub, u32 mask); -extern int dbus_pnp_sleep(const dbus_pub_t *pub); -extern int dbus_pnp_resume(const dbus_pub_t *pub, int *fw_reload); -extern int dbus_pnp_disconnect(const dbus_pub_t *pub); - -extern int dbus_iovar_op(const dbus_pub_t *pub, const char *name, - void *params, int plen, void *arg, int len, bool set); -#ifdef BCMDBG -extern void dbus_hist_dump(const dbus_pub_t *pub, struct bcmstrbuf *b); -#endif /* BCMDBG */ -/* - * Private Common Bus Interface - */ - -/* IO Request Block (IRB) */ -typedef struct dbus_irb { - struct dbus_irb *next; /* it's casted from dbus_irb_tx or dbus_irb_rx struct */ -} dbus_irb_t; - -typedef struct dbus_irb_rx { - struct dbus_irb irb; /* Must be first */ - u8 *buf; - int buf_len; - int actual_len; - void *pkt; - void *info; - void *arg; -} dbus_irb_rx_t; - -typedef struct dbus_irb_tx { - struct dbus_irb irb; /* Must be first */ - u8 *buf; - int len; - void *pkt; - int retry_count; - void *info; - void *arg; -} dbus_irb_tx_t; - -/* DBUS interface callbacks are different from user callbacks - * so, internally, different info can be passed to upper layer - */ -typedef struct dbus_intf_callbacks { - void (*send_irb_timeout) (void *cbarg, dbus_irb_tx_t *txirb); - void (*send_irb_complete) (void *cbarg, dbus_irb_tx_t *txirb, - int status); - void (*recv_irb_complete) (void *cbarg, dbus_irb_rx_t *rxirb, - int status); - void (*errhandler) (void *cbarg, int err); - void (*ctl_complete) (void *cbarg, int type, int status); - void (*state_change) (void *cbarg, int state); - bool(*isr) (void *cbarg, bool *wantdpc); - bool(*dpc) (void *cbarg, bool bounded); - void (*watchdog) (void *cbarg); - void *(*pktget) (void *cbarg, uint len, bool send); - void (*pktfree) (void *cbarg, void *p, bool send); - struct dbus_irb *(*getirb) (void *cbarg, bool send); - void (*rxerr_indicate) (void *cbarg, bool on); -} dbus_intf_callbacks_t; - -/* - * Porting: To support new bus, port these functions below - */ - -/* - * Bus specific Interface - * Implemented by dbus_usb.c/dbus_sdio.c - */ -extern int dbus_bus_register(int vid, int pid, probe_cb_t prcb, - disconnect_cb_t discb, void *prarg, - dbus_intf_t **intf, void *param1, void *param2); -extern int dbus_bus_deregister(void); - -/* - * Bus-specific and OS-specific Interface - * Implemented by dbus_usb_[linux/ndis].c/dbus_sdio_[linux/ndis].c - */ -extern int dbus_bus_osl_register(int vid, int pid, probe_cb_t prcb, - disconnect_cb_t discb, void *prarg, - dbus_intf_t **intf, void *param1, - void *param2); -extern int dbus_bus_osl_deregister(void); - -/* - * Bus-specific, OS-specific, HW-specific Interface - * Mainly for SDIO Host HW controller - */ -extern int dbus_bus_osl_hw_register(int vid, int pid, probe_cb_t prcb, - disconnect_cb_t discb, void *prarg, - dbus_intf_t **intf); -extern int dbus_bus_osl_hw_deregister(void); - -#endif /* __DBUS_H__ */ diff --git a/drivers/staging/brcm80211/sys/wlc_rpc.h b/drivers/staging/brcm80211/sys/wlc_rpc.h deleted file mode 100644 index e3f31d42dd80..000000000000 --- a/drivers/staging/brcm80211/sys/wlc_rpc.h +++ /dev/null @@ -1,523 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _WLC_RPC_H_ -#define _WLC_RPC_H_ - -#include - -/* RPC IDs, reordering is OK. This needs to be in sync with RPC_ID_TABLE below */ -typedef enum { - WLRPC_NULL_ID = 0, - WLRPC_WLC_REG_READ_ID, - WLRPC_WLC_REG_WRITE_ID, - WLRPC_WLC_MHF_SET_ID, - WLRPC_WLC_MHF_GET_ID, - WLRPC_WLC_BMAC_UP_PREP_ID, - WLRPC_WLC_BMAC_UP_FINISH_ID, - WLRPC_WLC_BMAC_DOWN_PREP_ID, - WLRPC_WLC_BMAC_DOWN_FINISH_ID, - WLRPC_WLC_BMAC_WRITE_HW_BCNTEMPLATES_ID, - WLRPC_WLC_BMAC_RESET_ID, - WLRPC_WLC_DNGL_REBOOT_ID, - WLRPC_WLC_BMAC_RPC_TXQ_WM_SET_ID, - WLRPC_WLC_BMAC_RPC_TXQ_WM_GET_ID, - WLRPC_WLC_BMAC_RPC_AGG_SET_ID, - WLRPC_WLC_BMAC_RPC_MSGLEVEL_SET_ID, - WLRPC_WLC_BMAC_RPC_AGG_LIMIT_SET_ID, - WLRPC_WLC_BMAC_RPC_AGG_LIMIT_GET_ID, - WLRPC_WLC_BMAC_INIT_ID, - WLRPC_WLC_BMAC_SET_CWMIN_ID, - WLRPC_WLC_BMAC_MUTE_ID, - WLRPC_WLC_PHY_DOIOVAR_ID, - WLRPC_WLC_PHY_HOLD_UPD_ID, - WLRPC_WLC_PHY_MUTE_UPD_ID, - WLRPC_WLC_PHY_CLEAR_TSSI_ID, - WLRPC_WLC_PHY_ANT_RXDIV_GET_ID, - WLRPC_WLC_PHY_ANT_RXDIV_SET_ID, - WLRPC_WLC_PHY_PREAMBLE_SET_ID, - WLRPC_WLC_PHY_FREQTRACK_END_ID, - WLRPC_WLC_PHY_FREQTRACK_START_ID, - WLRPC_WLC_PHY_IOCTL_ID, - WLRPC_WLC_PHY_NOISE_SAMPLE_REQUEST_ID, - WLRPC_WLC_PHY_CAL_PERICAL_ID, - WLRPC_WLC_PHY_TXPOWER_GET_ID, - WLRPC_WLC_PHY_TXPOWER_SET_ID, - WLRPC_WLC_PHY_TXPOWER_SROMLIMIT_ID, - WLRPC_WLC_PHY_RADAR_DETECT_ENABLE_ID, - WLRPC_WLC_PHY_RADAR_DETECT_RUN_ID, - WLRPC_WLC_PHY_TEST_ISON_ID, - WLRPC_WLC_BMAC_COPYFROM_OBJMEM_ID, - WLRPC_WLC_BMAC_COPYTO_OBJMEM_ID, - WLRPC_WLC_ENABLE_MAC_ID, - WLRPC_WLC_MCTRL_ID, - WLRPC_WLC_CORERESET_ID, - WLRPC_WLC_BMAC_READ_SHM_ID, - WLRPC_WLC_BMAC_READ_TSF_ID, - WLRPC_WLC_BMAC_SET_ADDRMATCH_ID, - WLRPC_WLC_BMAC_SET_CWMAX_ID, - WLRPC_WLC_BMAC_SET_RCMTA_ID, - WLRPC_WLC_BMAC_SET_SHM_ID, - WLRPC_WLC_SUSPEND_MAC_AND_WAIT_ID, - WLRPC_WLC_BMAC_WRITE_SHM_ID, - WLRPC_WLC_BMAC_WRITE_TEMPLATE_RAM_ID, - WLRPC_WLC_TX_FIFO_SUSPEND_ID, - WLRPC_WLC_TX_FIFO_RESUME_ID, - WLRPC_WLC_TX_FIFO_SUSPENDED_ID, - WLRPC_WLC_HW_ETHERADDR_ID, - WLRPC_WLC_SET_HW_ETHERADDR_ID, - WLRPC_WLC_BMAC_CHANSPEC_SET_ID, - WLRPC_WLC_BMAC_TXANT_SET_ID, - WLRPC_WLC_BMAC_ANTSEL_TYPE_SET_ID, - WLRPC_WLC_BMAC_TXFIFO_ID, - WLRPC_WLC_RADIO_READ_HWDISABLED_ID, - WLRPC_WLC_RM_CCA_MEASURE_ID, - WLRPC_WLC_SET_SHORTSLOT_ID, - WLRPC_WLC_WAIT_FOR_WAKE_ID, - WLRPC_WLC_PHY_TXPOWER_GET_CURRENT_ID, - WLRPC_WLC_PHY_TXPOWER_HW_CTRL_GET_ID, - WLRPC_WLC_PHY_TXPOWER_HW_CTRL_SET_ID, - WLRPC_WLC_PHY_BSSINIT_ID, - WLRPC_WLC_BAND_STF_SS_SET_ID, - WLRPC_WLC_PHY_BAND_FIRST_CHANSPEC_ID, - WLRPC_WLC_PHY_TXPOWER_LIMIT_SET_ID, - WLRPC_WLC_PHY_BAND_CHANNELS_ID, - WLRPC_WLC_BMAC_REVINFO_GET_ID, - WLRPC_WLC_BMAC_STATE_GET_ID, - WLRPC_WLC_BMAC_XMTFIFO_SZ_GET_ID, - WLRPC_WLC_BMAC_XMTFIFO_SZ_SET_ID, - WLRPC_WLC_BMAC_VALIDATE_CHIP_ACCESS_ID, - WLRPC_WLC_RM_CCA_COMPLETE_ID, - WLRPC_WLC_RECV_ID, - WLRPC_WLC_DOTXSTATUS_ID, - WLRPC_WLC_HIGH_DPC_ID, - WLRPC_WLC_FATAL_ERROR_ID, - WLRPC_WLC_PHY_SET_CHANNEL_14_WIDE_FILTER_ID, - WLRPC_WLC_PHY_NOISE_AVG_ID, - WLRPC_WLC_PHYCHAIN_INIT_ID, - WLRPC_WLC_PHYCHAIN_SET_ID, - WLRPC_WLC_PHYCHAIN_GET_ID, - WLRPC_WLC_PHY_TKIP_RIFS_WAR_ID, - WLRPC_WLC_BMAC_COPYFROM_VARS_ID, - WLRPC_WLC_BMAC_RETRYLIMIT_UPD_ID, - WLRPC_WLC_BMAC_BTC_MODE_SET_ID, - WLRPC_WLC_BMAC_BTC_MODE_GET_ID, - WLRPC_WLC_BMAC_BTC_WIRE_SET_ID, - WLRPC_WLC_BMAC_BTC_WIRE_GET_ID, - WLRPC_WLC_BMAC_SET_NORESET_ID, - WLRPC_WLC_AMPDU_TXSTATUS_COMPLETE_ID, - WLRPC_WLC_BMAC_FIFOERRORS_ID, - WLRPC_WLC_PHY_TXPOWER_GET_TARGET_MIN_ID, - WLRPC_WLC_PHY_TXPOWER_GET_TARGET_MAX_ID, - WLRPC_WLC_NOISE_CB_ID, - WLRPC_WLC_BMAC_LED_HW_DEINIT_ID, - WLRPC_WLC_BMAC_LED_HW_MASK_INIT_ID, - WLRPC_WLC_PLLREQ_ID, - WLRPC_WLC_BMAC_TACLEAR_ID, - WLRPC_WLC_BMAC_SET_CLK_ID, - WLRPC_WLC_PHY_OFDM_RATESET_WAR_ID, - WLRPC_WLC_PHY_BF_PREEMPT_ENABLE_ID, - WLRPC_WLC_BMAC_DOIOVARS_ID, - WLRPC_WLC_BMAC_DUMP_ID, - WLRPC_WLC_CISWRITE_ID, - WLRPC_WLC_CISDUMP_ID, - WLRPC_WLC_UPDATE_PHY_MODE_ID, - WLRPC_WLC_RESET_BMAC_DONE_ID, - WLRPC_WLC_BMAC_LED_BLINK_EVENT_ID, - WLRPC_WLC_BMAC_LED_SET_ID, - WLRPC_WLC_BMAC_LED_BLINK_ID, - WLRPC_WLC_BMAC_LED_ID, - WLRPC_WLC_BMAC_RATE_SHM_OFFSET_ID, - WLRPC_SI_ISCORE_UP_ID, - WLRPC_WLC_BMAC_PS_SWITCH_ID, - WLRPC_WLC_PHY_STF_SSMODE_GET_ID, - WLRPC_WLC_BMAC_DEBUG_ID, - WLRPC_WLC_EXTLOG_MSG_ID, - WLRPC_WLC_EXTLOG_CFG_ID, - WLRPC_BCM_ASSERT_LOG_ID, - WLRPC_BCM_ASSERT_TYPE_ID, - WLRPC_WLC_BMAC_SET_PHYCAL_CACHE_FLAG_ID, - WLRPC_WLC_BMAC_GET_PHYCAL_CACHE_FLAG_ID, - WLRPC_WLC_PHY_CAL_CACHE_INIT_ID, - WLRPC_WLC_PHY_CAL_CACHE_DEINIT_ID, - WLRPC_WLC_BMAC_HW_UP_ID, - WLRPC_WLC_BMAC_SET_TXPWR_PERCENT_ID, - WLRPC_WLC_PHYCHAIN_ACTIVE_GET_ID, - WLRPC_WLC_BMAC_BLINK_SYNC_ID, - WLRPC_WLC_BMAC_UCODE_DBGSEL_SET_ID, - WLRPC_WLC_BMAC_UCODE_DBGSEL_GET_ID, - WLRPC_WLC_PHY_RADAR_DETECT_MODE_SET_ID, - WLRPC_WLC_PHY_ACIM_NOISEM_RESET_NPHY_ID, - WLRPC_WLC_PHY_INTERFER_SET_NPHY_ID, - WLRPC_WLC_BMAC_IFSCTL_EDCRS_SET_ID, - WLRPC_WLC_PKTENGTX, - WLRPC_WLC_BMAC_SET_DEAF, - WLRPC_WLC_BMAC_CLEAR_DEAF, - WLRPC_WLC_BMAC_BTC_FLAGS_SET_ID, - WLRPC_WLC_BMAC_BTC_FLAGS_GET_ID, - WLRPC_WLC_BMAC_SET_RCMTA_TYPE_ID, - WLRPC_WLC_BMAC_BTC_FLAGS_UPD_ID, - WLRPC_WLC_BMAC_BTC_STUCKWAR_ID, - WLRPC_WLC_BMAC_CCA_STATS_READ_ID, - WLRPC_WLC_BMAC_ANTSEL_SET_ID, - WLRPC_WLC_BMAC_SET_UCODE_LOADED, - WLRPC_WLC_PHY_LDPC_SET_ID, - - WLRPC_LAST -} wlc_rpc_id_t; - -#if defined(BCMDBG) | 0 -struct name_entry { - int id; - char *name; -}; - -#define NAME_ENTRY(x) {x, #x} - -#define RPC_ID_TABLE { \ - NAME_ENTRY(WLRPC_WLC_REG_READ_ID), \ - NAME_ENTRY(WLRPC_WLC_REG_WRITE_ID), \ - NAME_ENTRY(WLRPC_WLC_MHF_SET_ID), \ - NAME_ENTRY(WLRPC_WLC_MHF_GET_ID), \ - NAME_ENTRY(WLRPC_WLC_BMAC_UP_PREP_ID), \ - NAME_ENTRY(WLRPC_WLC_BMAC_UP_FINISH_ID), \ - NAME_ENTRY(WLRPC_WLC_BMAC_DOWN_PREP_ID), \ - NAME_ENTRY(WLRPC_WLC_BMAC_DOWN_FINISH_ID), \ - NAME_ENTRY(WLRPC_WLC_BMAC_WRITE_HW_BCNTEMPLATES_ID), \ - NAME_ENTRY(WLRPC_WLC_BMAC_RESET_ID), \ - NAME_ENTRY(WLRPC_WLC_DNGL_REBOOT_ID), \ - NAME_ENTRY(WLRPC_WLC_BMAC_RPC_TXQ_WM_SET_ID), \ - NAME_ENTRY(WLRPC_WLC_BMAC_RPC_TXQ_WM_GET_ID), \ - NAME_ENTRY(WLRPC_WLC_BMAC_RPC_AGG_SET_ID), \ - NAME_ENTRY(WLRPC_WLC_BMAC_RPC_MSGLEVEL_SET_ID), \ - NAME_ENTRY(WLRPC_WLC_BMAC_RPC_AGG_LIMIT_SET_ID), \ - NAME_ENTRY(WLRPC_WLC_BMAC_RPC_AGG_LIMIT_GET_ID), \ - NAME_ENTRY(WLRPC_WLC_BMAC_INIT_ID), \ - NAME_ENTRY(WLRPC_WLC_BMAC_SET_CWMIN_ID), \ - NAME_ENTRY(WLRPC_WLC_BMAC_MUTE_ID), \ - NAME_ENTRY(WLRPC_WLC_PHY_DOIOVAR_ID), \ - NAME_ENTRY(WLRPC_WLC_PHY_HOLD_UPD_ID), \ - NAME_ENTRY(WLRPC_WLC_PHY_MUTE_UPD_ID), \ - NAME_ENTRY(WLRPC_WLC_PHY_CLEAR_TSSI_ID), \ - NAME_ENTRY(WLRPC_WLC_PHY_ANT_RXDIV_GET_ID), \ - NAME_ENTRY(WLRPC_WLC_PHY_ANT_RXDIV_SET_ID), \ - NAME_ENTRY(WLRPC_WLC_PHY_PREAMBLE_SET_ID), \ - NAME_ENTRY(WLRPC_WLC_PHY_FREQTRACK_END_ID), \ - NAME_ENTRY(WLRPC_WLC_PHY_FREQTRACK_START_ID), \ - NAME_ENTRY(WLRPC_WLC_PHY_IOCTL_ID), \ - NAME_ENTRY(WLRPC_WLC_PHY_NOISE_SAMPLE_REQUEST_ID), \ - NAME_ENTRY(WLRPC_WLC_PHY_CAL_PERICAL_ID), \ - NAME_ENTRY(WLRPC_WLC_PHY_TXPOWER_GET_ID), \ - NAME_ENTRY(WLRPC_WLC_PHY_TXPOWER_SET_ID), \ - NAME_ENTRY(WLRPC_WLC_PHY_TXPOWER_SROMLIMIT_ID), \ - NAME_ENTRY(WLRPC_WLC_PHY_RADAR_DETECT_ENABLE_ID), \ - NAME_ENTRY(WLRPC_WLC_PHY_RADAR_DETECT_RUN_ID), \ - NAME_ENTRY(WLRPC_WLC_PHY_TEST_ISON_ID), \ - NAME_ENTRY(WLRPC_WLC_BMAC_COPYFROM_OBJMEM_ID), \ - NAME_ENTRY(WLRPC_WLC_BMAC_COPYTO_OBJMEM_ID), \ - NAME_ENTRY(WLRPC_WLC_ENABLE_MAC_ID), \ - NAME_ENTRY(WLRPC_WLC_MCTRL_ID), \ - NAME_ENTRY(WLRPC_WLC_CORERESET_ID), \ - NAME_ENTRY(WLRPC_WLC_BMAC_READ_SHM_ID), \ - NAME_ENTRY(WLRPC_WLC_BMAC_READ_TSF_ID), \ - NAME_ENTRY(WLRPC_WLC_BMAC_SET_ADDRMATCH_ID), \ - NAME_ENTRY(WLRPC_WLC_BMAC_SET_CWMAX_ID), \ - NAME_ENTRY(WLRPC_WLC_BMAC_SET_RCMTA_ID), \ - NAME_ENTRY(WLRPC_WLC_BMAC_SET_SHM_ID), \ - NAME_ENTRY(WLRPC_WLC_SUSPEND_MAC_AND_WAIT_ID), \ - NAME_ENTRY(WLRPC_WLC_BMAC_WRITE_SHM_ID), \ - NAME_ENTRY(WLRPC_WLC_BMAC_WRITE_TEMPLATE_RAM_ID), \ - NAME_ENTRY(WLRPC_WLC_TX_FIFO_SUSPEND_ID), \ - NAME_ENTRY(WLRPC_WLC_TX_FIFO_RESUME_ID), \ - NAME_ENTRY(WLRPC_WLC_TX_FIFO_SUSPENDED_ID), \ - NAME_ENTRY(WLRPC_WLC_HW_ETHERADDR_ID), \ - NAME_ENTRY(WLRPC_WLC_SET_HW_ETHERADDR_ID), \ - NAME_ENTRY(WLRPC_WLC_BMAC_CHANSPEC_SET_ID), \ - NAME_ENTRY(WLRPC_WLC_BMAC_TXANT_SET_ID), \ - NAME_ENTRY(WLRPC_WLC_BMAC_ANTSEL_TYPE_SET_ID), \ - NAME_ENTRY(WLRPC_WLC_BMAC_TXFIFO_ID), \ - NAME_ENTRY(WLRPC_WLC_RADIO_READ_HWDISABLED_ID), \ - NAME_ENTRY(WLRPC_WLC_RM_CCA_MEASURE_ID), \ - NAME_ENTRY(WLRPC_WLC_SET_SHORTSLOT_ID), \ - NAME_ENTRY(WLRPC_WLC_WAIT_FOR_WAKE_ID), \ - NAME_ENTRY(WLRPC_WLC_PHY_TXPOWER_GET_CURRENT_ID), \ - NAME_ENTRY(WLRPC_WLC_PHY_TXPOWER_HW_CTRL_GET_ID), \ - NAME_ENTRY(WLRPC_WLC_PHY_TXPOWER_HW_CTRL_SET_ID), \ - NAME_ENTRY(WLRPC_WLC_PHY_BSSINIT_ID), \ - NAME_ENTRY(WLRPC_WLC_BAND_STF_SS_SET_ID), \ - NAME_ENTRY(WLRPC_WLC_PHY_BAND_FIRST_CHANSPEC_ID), \ - NAME_ENTRY(WLRPC_WLC_PHY_TXPOWER_LIMIT_SET_ID), \ - NAME_ENTRY(WLRPC_WLC_PHY_BAND_CHANNELS_ID), \ - NAME_ENTRY(WLRPC_WLC_BMAC_REVINFO_GET_ID), \ - NAME_ENTRY(WLRPC_WLC_BMAC_STATE_GET_ID), \ - NAME_ENTRY(WLRPC_WLC_BMAC_XMTFIFO_SZ_GET_ID), \ - NAME_ENTRY(WLRPC_WLC_BMAC_XMTFIFO_SZ_SET_ID), \ - NAME_ENTRY(WLRPC_WLC_BMAC_VALIDATE_CHIP_ACCESS_ID), \ - NAME_ENTRY(WLRPC_WLC_RM_CCA_COMPLETE_ID), \ - NAME_ENTRY(WLRPC_WLC_RECV_ID), \ - NAME_ENTRY(WLRPC_WLC_DOTXSTATUS_ID), \ - NAME_ENTRY(WLRPC_WLC_HIGH_DPC_ID), \ - NAME_ENTRY(WLRPC_WLC_FATAL_ERROR_ID), \ - NAME_ENTRY(WLRPC_WLC_PHY_SET_CHANNEL_14_WIDE_FILTER_ID), \ - NAME_ENTRY(WLRPC_WLC_PHY_NOISE_AVG_ID), \ - NAME_ENTRY(WLRPC_WLC_PHYCHAIN_INIT_ID), \ - NAME_ENTRY(WLRPC_WLC_PHYCHAIN_SET_ID), \ - NAME_ENTRY(WLRPC_WLC_PHYCHAIN_GET_ID), \ - NAME_ENTRY(WLRPC_WLC_PHY_TKIP_RIFS_WAR_ID), \ - NAME_ENTRY(WLRPC_WLC_BMAC_COPYFROM_VARS_ID), \ - NAME_ENTRY(WLRPC_WLC_BMAC_RETRYLIMIT_UPD_ID), \ - NAME_ENTRY(WLRPC_WLC_BMAC_BTC_MODE_SET_ID), \ - NAME_ENTRY(WLRPC_WLC_BMAC_BTC_MODE_GET_ID), \ - NAME_ENTRY(WLRPC_WLC_BMAC_BTC_WIRE_SET_ID), \ - NAME_ENTRY(WLRPC_WLC_BMAC_BTC_WIRE_GET_ID), \ - NAME_ENTRY(WLRPC_WLC_BMAC_SET_NORESET_ID), \ - NAME_ENTRY(WLRPC_WLC_AMPDU_TXSTATUS_COMPLETE_ID), \ - NAME_ENTRY(WLRPC_WLC_BMAC_FIFOERRORS_ID), \ - NAME_ENTRY(WLRPC_WLC_PHY_TXPOWER_GET_TARGET_MIN_ID), \ - NAME_ENTRY(WLRPC_WLC_PHY_TXPOWER_GET_TARGET_MAX_ID), \ - NAME_ENTRY(WLRPC_WLC_NOISE_CB_ID), \ - NAME_ENTRY(WLRPC_WLC_BMAC_LED_HW_DEINIT_ID), \ - NAME_ENTRY(WLRPC_WLC_BMAC_LED_HW_MASK_INIT_ID), \ - NAME_ENTRY(WLRPC_WLC_PLLREQ_ID), \ - NAME_ENTRY(WLRPC_WLC_BMAC_TACLEAR_ID), \ - NAME_ENTRY(WLRPC_WLC_BMAC_SET_CLK_ID), \ - NAME_ENTRY(WLRPC_WLC_PHY_OFDM_RATESET_WAR_ID), \ - NAME_ENTRY(WLRPC_WLC_PHY_BF_PREEMPT_ENABLE_ID), \ - NAME_ENTRY(WLRPC_WLC_BMAC_DOIOVARS_ID), \ - NAME_ENTRY(WLRPC_WLC_BMAC_DUMP_ID), \ - NAME_ENTRY(WLRPC_WLC_CISWRITE_ID), \ - NAME_ENTRY(WLRPC_WLC_CISDUMP_ID), \ - NAME_ENTRY(WLRPC_WLC_UPDATE_PHY_MODE_ID), \ - NAME_ENTRY(WLRPC_WLC_RESET_BMAC_DONE_ID), \ - NAME_ENTRY(WLRPC_WLC_BMAC_LED_BLINK_EVENT_ID), \ - NAME_ENTRY(WLRPC_WLC_BMAC_LED_SET_ID), \ - NAME_ENTRY(WLRPC_WLC_BMAC_LED_BLINK_ID), \ - NAME_ENTRY(WLRPC_WLC_BMAC_LED_ID), \ - NAME_ENTRY(WLRPC_WLC_BMAC_RATE_SHM_OFFSET_ID), \ - NAME_ENTRY(WLRPC_SI_ISCORE_UP_ID), \ - NAME_ENTRY(WLRPC_WLC_BMAC_PS_SWITCH_ID), \ - NAME_ENTRY(WLRPC_WLC_PHY_STF_SSMODE_GET_ID), \ - NAME_ENTRY(WLRPC_WLC_BMAC_DEBUG_ID), \ - NAME_ENTRY(WLRPC_WLC_EXTLOG_MSG_ID), \ - NAME_ENTRY(WLRPC_WLC_EXTLOG_CFG_ID), \ - NAME_ENTRY(WLRPC_BCM_ASSERT_LOG_ID), \ - NAME_ENTRY(WLRPC_BCM_ASSERT_TYPE_ID), \ - NAME_ENTRY(WLRPC_WLC_BMAC_SET_PHYCAL_CACHE_FLAG_ID), \ - NAME_ENTRY(WLRPC_WLC_BMAC_GET_PHYCAL_CACHE_FLAG_ID), \ - NAME_ENTRY(WLRPC_WLC_PHY_CAL_CACHE_INIT_ID), \ - NAME_ENTRY(WLRPC_WLC_PHY_CAL_CACHE_DEINIT_ID), \ - NAME_ENTRY(WLRPC_WLC_BMAC_HW_UP_ID), \ - NAME_ENTRY(WLRPC_WLC_BMAC_SET_TXPWR_PERCENT_ID), \ - NAME_ENTRY(WLRPC_WLC_PHYCHAIN_ACTIVE_GET_ID), \ - NAME_ENTRY(WLRPC_WLC_BMAC_BLINK_SYNC_ID), \ - NAME_ENTRY(WLRPC_WLC_BMAC_UCODE_DBGSEL_SET_ID), \ - NAME_ENTRY(WLRPC_WLC_BMAC_UCODE_DBGSEL_GET_ID), \ - NAME_ENTRY(WLRPC_WLC_PHY_RADAR_DETECT_MODE_SET_ID), \ - NAME_ENTRY(WLRPC_WLC_PHY_ACIM_NOISEM_RESET_NPHY_ID), \ - NAME_ENTRY(WLRPC_WLC_PHY_INTERFER_SET_NPHY_ID), \ - NAME_ENTRY(WLRPC_WLC_BMAC_IFSCTL_EDCRS_SET_ID), \ - NAME_ENTRY(WLRPC_WLC_PKTENGTX), \ - NAME_ENTRY(WLRPC_WLC_BMAC_SET_DEAF), \ - NAME_ENTRY(WLRPC_WLC_BMAC_CLEAR_DEAF), \ - NAME_ENTRY(WLRPC_WLC_BMAC_BTC_FLAGS_SET_ID), \ - NAME_ENTRY(WLRPC_WLC_BMAC_BTC_FLAGS_GET_ID), \ - NAME_ENTRY(WLRPC_WLC_BMAC_SET_RCMTA_TYPE_ID), \ - NAME_ENTRY(WLRPC_WLC_BMAC_CCA_STATS_READ_ID), \ - NAME_ENTRY(WLRPC_WLC_BMAC_ANTSEL_SET_ID), \ - NAME_ENTRY(WLRPC_WLC_BMAC_SET_UCODE_LOADED), \ - NAME_ENTRY(WLRPC_WLC_PHY_LDPC_SET_ID), \ - {0, NULL} \ - } - -static __inline char *_wlc_rpc_id_lookup(const struct name_entry *tbl, int _id) -{ - const struct name_entry *elt = tbl; - static char __unknown[64]; - for (; elt->name != NULL; elt++) { - if (_id == elt->id) - break; - } - if (_id == elt->id) - strncpy(__unknown, elt->name, sizeof(__unknown)); - else - snprintf(__unknown, sizeof(__unknown), "ID:%d", _id); - return __unknown; -} - -#define WLC_RPC_ID_LOOKUP(tbl, _id) (_wlc_rpc_id_lookup(tbl, _id)) - -#endif /* BCMDBG */ - -/* refer to txpwr_limits_t for each elements, mcs32 is the at the end for 1 byte */ -#define TXPOWER_XDR_SZ (roundup(WLC_NUM_RATES_CCK, 4) + roundup(WLC_NUM_RATES_OFDM, 4) * 4 + \ - roundup(WLC_NUM_RATES_MCS_1_STREAM, 4) * 6 + roundup(WLC_NUM_RATES_MCS_2_STREAM, 4) * 2 + \ - roundup(1, 4)) - -#define wlc_rpc_txpwr_limits(b, txpwr, op, err) \ - do { \ - (err) = bcm_xdr_##op##_u8_vec((b), (txpwr)->cck, WLC_NUM_RATES_CCK); \ - ASSERT(!(err)); \ - \ - /* 20 MHz Legacy OFDM rates with SISO transmission */ \ - (err) = bcm_xdr_##op##_u8_vec((b), (txpwr)->ofdm, WLC_NUM_RATES_OFDM); \ - ASSERT(!(err)); \ - \ - /* 20 MHz Legacy OFDM rates with CDD transmission */ \ - (err) = bcm_xdr_##op##_u8_vec((b), (txpwr)->ofdm_cdd, WLC_NUM_RATES_OFDM); \ - ASSERT(!(err)); \ - \ - /* 40 MHz Legacy OFDM rates with SISO transmission */ \ - (err) = bcm_xdr_##op##_u8_vec((b), (txpwr)->ofdm_40_siso, WLC_NUM_RATES_OFDM); \ - ASSERT(!(err)); \ - \ - /* 40 MHz Legacy OFDM rates with CDD transmission */ \ - (err) = bcm_xdr_##op##_u8_vec((b), (txpwr)->ofdm_40_cdd, WLC_NUM_RATES_OFDM); \ - ASSERT(!(err)); \ - \ - /* 20MHz MCS rates SISO/CDD/STBC/SDM */ \ - (err) = bcm_xdr_##op##_u8_vec((b), (txpwr)->mcs_20_siso, WLC_NUM_RATES_MCS_1_STREAM); \ - ASSERT(!(err)); \ - \ - (err) = bcm_xdr_##op##_u8_vec((b), (txpwr)->mcs_20_cdd, WLC_NUM_RATES_MCS_1_STREAM); \ - ASSERT(!(err)); \ - \ - (err) = bcm_xdr_##op##_u8_vec((b), (txpwr)->mcs_20_stbc, WLC_NUM_RATES_MCS_1_STREAM); \ - ASSERT(!(err)); \ - \ - (err) = bcm_xdr_##op##_u8_vec((b), (txpwr)->mcs_20_mimo, WLC_NUM_RATES_MCS_2_STREAM); \ - ASSERT(!(err)); \ - \ - /* 40MHz MCS rates SISO/CDD/STBC/SDM */ \ - (err) = bcm_xdr_##op##_u8_vec((b), (txpwr)->mcs_40_siso, WLC_NUM_RATES_MCS_1_STREAM); \ - ASSERT(!(err)); \ - \ - (err) = bcm_xdr_##op##_u8_vec((b), (txpwr)->mcs_40_cdd, WLC_NUM_RATES_MCS_1_STREAM); \ - ASSERT(!(err)); \ - \ - (err) = bcm_xdr_##op##_u8_vec((b), (txpwr)->mcs_40_stbc, WLC_NUM_RATES_MCS_1_STREAM); \ - ASSERT(!(err)); \ - \ - (err) = bcm_xdr_##op##_u8_vec((b), (txpwr)->mcs_40_mimo, WLC_NUM_RATES_MCS_2_STREAM); \ - ASSERT(!(err)); \ - } while (0) - -typedef struct wlc_rpc_ctx { - rpc_info_t *rpc; - wlc_info_t *wlc; - wlc_hw_info_t *wlc_hw; -} wlc_rpc_ctx_t; - -static inline rpc_buf_t *wlc_rpc_buf_alloc(rpc_info_t *rpc, bcm_xdr_buf_t *b, - uint len, wlc_rpc_id_t rpc_id) -{ - rpc_buf_t *rpc_buf; - - rpc_buf = bcm_rpc_buf_alloc(rpc, len + sizeof(u32)); - - if (!rpc_buf) - return NULL; - - bcm_xdr_buf_init(b, bcm_rpc_buf_data(bcm_rpc_tp_get(rpc), rpc_buf), - len + sizeof(u32)); - - bcm_xdr_pack_u32(b, rpc_id); - - return rpc_buf; -} - -#if defined(BCMDBG) -static __inline wlc_rpc_id_t -wlc_rpc_id_get(struct rpc_info *rpc, rpc_buf_t *buf) -{ - wlc_rpc_id_t rpc_id; - bcm_xdr_buf_t b; - - bcm_xdr_buf_init(&b, bcm_rpc_buf_data(bcm_rpc_tp_get(rpc), buf), - sizeof(u32)); - - bcm_xdr_unpack_u32(&b, (u32 *)((unsigned long) & rpc_id)); - return rpc_id; -} -#endif - -static __inline int _wlc_rpc_call(struct rpc_info *rpc, rpc_buf_t *send) -{ - int _err = 0; -#if defined(BCMDBG) - wlc_rpc_id_t rpc_id = wlc_rpc_id_get(rpc, send); - /* const struct name_entry rpc_name_tbl[] = RPC_ID_TABLE; */ - static struct name_entry rpc_name_tbl[] = RPC_ID_TABLE; - WL_TRACE(("%s: Called id %s\n", __func__, - WLC_RPC_ID_LOOKUP(rpc_name_tbl, rpc_id))); -#endif - _err = bcm_rpc_call(rpc, send); - if (_err) { -#if defined(BCMDBG) - WL_ERROR(("%s: Call id %s FAILED\n", __func__, - WLC_RPC_ID_LOOKUP(rpc_name_tbl, rpc_id))); -#endif - _err = 0; - } - return _err; -} - -#define wlc_rpc_call(rpc, send) (_wlc_rpc_call(rpc, send)) - -#include -#include -#include - -extern void wlc_rpc_bmac_dispatch(wlc_rpc_ctx_t *rpc_ctx, struct rpc_buf *buf); -extern void wlc_rpc_bmac_dump_txfifohist(wlc_hw_info_t *wlc_hw, - bool dump_clear); - -/* Packed structure for ease of transport across RPC bus along u32 boundary */ -typedef struct wlc_rpc_txstatus { - u32 PAD_framelen; - u32 status_frameid; - u32 sequence_lasttxtime; - u32 ackphyrxsh_phyerr; -} wlc_rpc_txstatus_t; - -static inline - void txstatus2rpc_txstatus(tx_status_t *txstatus, - wlc_rpc_txstatus_t *rpc_txstatus) -{ - rpc_txstatus->PAD_framelen = txstatus->framelen; - rpc_txstatus->status_frameid = - (txstatus->status << 16) | txstatus->frameid; - rpc_txstatus->sequence_lasttxtime = - (txstatus->sequence << 16) | txstatus->lasttxtime; - rpc_txstatus->ackphyrxsh_phyerr = - (txstatus->ackphyrxsh << 16) | txstatus->phyerr; -} - -static inline - void rpc_txstatus2txstatus(wlc_rpc_txstatus_t *rpc_txstatus, - tx_status_t *txstatus) -{ - txstatus->framelen = rpc_txstatus->PAD_framelen & 0xffff; - txstatus->status = (rpc_txstatus->status_frameid >> 16) & 0xffff; - txstatus->frameid = rpc_txstatus->status_frameid & 0xffff; - txstatus->sequence = (rpc_txstatus->sequence_lasttxtime >> 16) & 0xffff; - txstatus->lasttxtime = rpc_txstatus->sequence_lasttxtime & 0xffff; - txstatus->ackphyrxsh = (rpc_txstatus->ackphyrxsh_phyerr >> 16) & 0xffff; - txstatus->phyerr = rpc_txstatus->ackphyrxsh_phyerr & 0xffff; -} - -extern void wlc_bmac_dngl_reboot(rpc_info_t *rpc); - -#endif /* WLC_RPC_H */ diff --git a/drivers/staging/brcm80211/sys/wlc_rpctx.h b/drivers/staging/brcm80211/sys/wlc_rpctx.h deleted file mode 100644 index 58ce5438632f..000000000000 --- a/drivers/staging/brcm80211/sys/wlc_rpctx.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _wlc_rpctx_h_ -#define _wlc_rpctx_h_ - -/* forward declaration */ -struct wlc_info; - -/* This controls how many packets are given to the dongle. This is required as - * NTXD needs to be power of 2 but we may not have enough memory to absorb that - * large number of frames - */ -#ifndef NRPCTXBUFPOST -#define NRPCTXBUFPOST NTXD -#endif - -#define RPCTX_ENAB(pub) (false) -#define wlc_rpctx_attach(pub, wlc) (NULL) -#define wlc_rpctx_fifoinit(rpctx, fifo, ntxd) (0) -#define wlc_rpctx_detach(rpctx) ASSERT(0) -#define wlc_rpctx_txavail(rpctx, f) (false) -#define wlc_rpctx_dump(rpctx, b) (0) -#define wlc_rpctx_getnexttxp(rpctx, f) (NULL) -#define wlc_rpctx_txreclaim(rpctx) ASSERT(0) -#define wlc_rpctx_pkteng(rpctx, fifo, p) do { } while (0) -#define wlc_rpctx_tx(rpctx, f, p, c, fid, t) (0) -#define wlc_rpctx_txpktpendinc(rpctx, f, val) do { } while (0) -#define wlc_rpctx_txpktpenddec(rpctx, f, val) do { } while (0) -#define wlc_rpctx_txpktpendclr(rpctx, f) do { } while (0) -#define wlc_rpctx_txpktpend(rpctx, f, all) (0) - - -#endif /* _wlc_rpctx_h_ */ -- cgit v1.2.3 From f9ec972793fb61f6ec612ecee5b1cc6efeacfbd6 Mon Sep 17 00:00:00 2001 From: Brett Rudley Date: Fri, 19 Nov 2010 14:30:57 -0800 Subject: staging: brcm80211: unifdef -UBCMSDIO Part of BMAC removal. Signed-off-by: Brett Rudley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/sys/wl_mac80211.c | 25 ------------------------- drivers/staging/brcm80211/sys/wl_mac80211.h | 4 ---- drivers/staging/brcm80211/sys/wlc_bmac.c | 5 ----- drivers/staging/brcm80211/sys/wlc_cfg.h | 16 ---------------- drivers/staging/brcm80211/sys/wlc_mac80211.c | 4 ---- drivers/staging/brcm80211/sys/wlc_mac80211.h | 3 --- drivers/staging/brcm80211/sys/wlc_pub.h | 3 --- 7 files changed, 60 deletions(-) diff --git a/drivers/staging/brcm80211/sys/wl_mac80211.c b/drivers/staging/brcm80211/sys/wl_mac80211.c index 37e6ced84db5..6c162b9f864a 100644 --- a/drivers/staging/brcm80211/sys/wl_mac80211.c +++ b/drivers/staging/brcm80211/sys/wl_mac80211.c @@ -40,9 +40,6 @@ #include #include #include -#ifdef BCMSDIO -#include -#endif #include #include @@ -50,9 +47,6 @@ #include #include -#ifdef BCMSDIO -extern struct device *sdiommc_dev; -#endif extern void wlc_wme_setparams(wlc_info_t *wlc, u16 aci, void *arg, bool suspend); @@ -127,7 +121,6 @@ MODULE_DESCRIPTION("Broadcom 802.11n wireless LAN driver."); MODULE_SUPPORTED_DEVICE("Broadcom 802.11n WLAN cards"); MODULE_LICENSE("Dual BSD/GPL"); -#ifndef BCMSDIO /* recognized PCI IDs */ static struct pci_device_id wl_id_table[] = { {PCI_VENDOR_ID_BROADCOM, 0x4357, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, /* 43225 2G */ @@ -138,12 +131,7 @@ static struct pci_device_id wl_id_table[] = { MODULE_DEVICE_TABLE(pci, wl_id_table); static void wl_remove(struct pci_dev *pdev); -#endif /* !BCMSDIO */ -#ifdef BCMSDIO -static uint sd_drivestrength = 6; -module_param(sd_drivestrength, uint, 0); -#endif #ifdef BCMDBG static int msglevel = 0xdeadbeef; @@ -701,9 +689,6 @@ static wl_info_t *wl_attach(u16 vendor, u16 device, unsigned long regs, tasklet_init(&wl->tasklet, wl_dpc, (unsigned long) wl); -#ifdef BCMSDIO - SET_IEEE80211_DEV(hw, sdiommc_dev); -#endif base_addr = regs; @@ -754,10 +739,6 @@ static wl_info_t *wl_attach(u16 vendor, u16 device, unsigned long regs, WL_ERROR(("wl%d: Error setting MPC variable to 0\n", unit)); } -#ifdef BCMSDIO - /* Set SDIO drive strength */ - wlc_iovar_setint(wl->wlc, "sd_drivestrength", sd_drivestrength); -#endif /* register our interrupt handler */ if (request_irq(irq, wl_isr, IRQF_SHARED, KBUILD_MODNAME, wl)) { @@ -1048,7 +1029,6 @@ static int ieee_hw_init(struct ieee80211_hw *hw) return ieee_hw_rate_init(hw); } -#ifndef BCMSDIO /** * determines if a device is a WL device, and if so, attaches it. * @@ -1219,7 +1199,6 @@ static struct pci_driver wl_pci_driver = { .remove = __devexit_p(wl_remove), .id_table = wl_id_table, }; -#endif /* !BCMSDIO */ /** * This is the main entry point for the WL driver. @@ -1253,12 +1232,10 @@ static int __init wl_module_init(void) } #endif /* BCMDBG */ -#ifndef BCMSDIO error = pci_register_driver(&wl_pci_driver); if (!error) return 0; -#endif /* !BCMSDIO */ return error; @@ -1273,9 +1250,7 @@ static int __init wl_module_init(void) */ static void __exit wl_module_exit(void) { -#ifndef BCMSDIO pci_unregister_driver(&wl_pci_driver); -#endif /* !BCMSDIO */ } diff --git a/drivers/staging/brcm80211/sys/wl_mac80211.h b/drivers/staging/brcm80211/sys/wl_mac80211.h index 220d570710cb..239ef3a0ed9b 100644 --- a/drivers/staging/brcm80211/sys/wl_mac80211.h +++ b/drivers/staging/brcm80211/sys/wl_mac80211.h @@ -75,10 +75,6 @@ struct wl_info { atomic_t callbacks; /* # outstanding callback functions */ struct wl_timer *timers; /* timer cleanup queue */ struct tasklet_struct tasklet; /* dpc tasklet */ -#ifdef BCMSDIO - bcmsdh_info_t *sdh; /* pointer to sdio bus handler */ - unsigned long flags; /* current irq flags */ -#endif /* BCMSDIO */ bool resched; /* dpc needs to be and is rescheduled */ #ifdef LINUXSTA_PS u32 pci_psstate[16]; /* pci ps-state save/restore */ diff --git a/drivers/staging/brcm80211/sys/wlc_bmac.c b/drivers/staging/brcm80211/sys/wlc_bmac.c index 110710ad6e78..4b2708620049 100644 --- a/drivers/staging/brcm80211/sys/wlc_bmac.c +++ b/drivers/staging/brcm80211/sys/wlc_bmac.c @@ -56,9 +56,6 @@ #include #include "wl_ucode.h" #include "d11ucode_ext.h" -#ifdef BCMSDIO -#include -#endif #include /* BMAC_NOTE: With WLC_HIGH defined, some fns in this file make calls to high level @@ -3209,9 +3206,7 @@ static inline u32 wlc_intstatus(wlc_info_t *wlc, bool in_isr) */ /* turn off the interrupts */ W_REG(osh, ®s->macintmask, 0); -#ifndef BCMSDIO (void)R_REG(osh, ®s->macintmask); /* sync readback */ -#endif wlc->macintmask = 0; /* clear device interrupts */ diff --git a/drivers/staging/brcm80211/sys/wlc_cfg.h b/drivers/staging/brcm80211/sys/wlc_cfg.h index e36d209c72fd..e56adb78f4fa 100644 --- a/drivers/staging/brcm80211/sys/wlc_cfg.h +++ b/drivers/staging/brcm80211/sys/wlc_cfg.h @@ -55,22 +55,6 @@ * 3 5356a0 */ -#ifdef BCMSDIO -#define D11CONF 0x100000 -#define SSLPNCONF 2 -#define GCCONF 0 -#define ACCONF 0 -#define NCONF 0 -#define LPCONF 0 -#define LCNCONF 0 -#define NTXD 32 -#define NRXD 16 -#define NRXBUFPOST 8 -#define WLC_DATAHIWAT 32 -#define RXBND 8 -#define MAXPKTCB 64 -#define AMPDU_NUM_MPDU 8 -#endif /* For undefined values, use defaults */ #ifndef D11CONF diff --git a/drivers/staging/brcm80211/sys/wlc_mac80211.c b/drivers/staging/brcm80211/sys/wlc_mac80211.c index c6f64c2e461a..37a87d8f23c8 100644 --- a/drivers/staging/brcm80211/sys/wlc_mac80211.c +++ b/drivers/staging/brcm80211/sys/wlc_mac80211.c @@ -48,11 +48,7 @@ #include #include #include -#ifdef BCMSDIO -#include -#else #include "d11ucode_ext.h" -#endif #include #include #include diff --git a/drivers/staging/brcm80211/sys/wlc_mac80211.h b/drivers/staging/brcm80211/sys/wlc_mac80211.h index 459e3cfc84aa..8c961e21002f 100644 --- a/drivers/staging/brcm80211/sys/wlc_mac80211.h +++ b/drivers/staging/brcm80211/sys/wlc_mac80211.h @@ -480,9 +480,6 @@ struct wlc_hw_info { bool phyclk; /* phy is out of reset and has clock */ bool dma_lpbk; /* core is in DMA loopback */ -#ifdef BCMSDIO - void *sdh; -#endif bool ucode_loaded; /* true after ucode downloaded */ diff --git a/drivers/staging/brcm80211/sys/wlc_pub.h b/drivers/staging/brcm80211/sys/wlc_pub.h index 09be41d921c5..2f4b899f0fe1 100644 --- a/drivers/staging/brcm80211/sys/wlc_pub.h +++ b/drivers/staging/brcm80211/sys/wlc_pub.h @@ -318,9 +318,6 @@ typedef struct wlc_pub { * is implemented properly in osl of that port * when it enables this Power Save feature. */ -#ifdef BCMSDIO - uint sdiod_drive_strength; /* SDIO drive strength */ -#endif /* BCMSDIO */ u16 boardrev; /* version # of particular board */ u8 sromrev; /* version # of the srom */ -- cgit v1.2.3 From 861f67031899b8ab909d672eaea85070317855c9 Mon Sep 17 00:00:00 2001 From: Brett Rudley Date: Fri, 19 Nov 2010 14:30:58 -0800 Subject: staging: brcm80211: stragglers not handled by unifdef Part of BMAC removal. Signed-off-by: Brett Rudley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/include/linux_osl.h | 37 -------------------- drivers/staging/brcm80211/include/osl.h | 5 --- drivers/staging/brcm80211/sys/wlc_cfg.h | 2 -- drivers/staging/brcm80211/sys/wlc_mac80211.h | 1 - drivers/staging/brcm80211/sys/wlc_pub.h | 4 --- drivers/staging/brcm80211/util/linux_osl.c | 49 --------------------------- 6 files changed, 98 deletions(-) diff --git a/drivers/staging/brcm80211/include/linux_osl.h b/drivers/staging/brcm80211/include/linux_osl.h index 11239fbba766..d314dfb2b62f 100644 --- a/drivers/staging/brcm80211/include/linux_osl.h +++ b/drivers/staging/brcm80211/include/linux_osl.h @@ -61,15 +61,6 @@ extern uint osl_pci_slot(struct osl_info *osh); ((struct osl_pubinfo *)osh)->tx_ctx = _tx_ctx; \ } while (0) -#if defined(BCMSDIO) && !defined(BRCM_FULLMAC) -#define REGOPSSET(osh, rreg, wreg, ctx) \ - do { \ - ((struct osl_pubinfo *)osh)->rreg_fn = rreg; \ - ((struct osl_pubinfo *)osh)->wreg_fn = wreg; \ - ((struct osl_pubinfo *)osh)->reg_ctx = ctx; \ - } while (0) -#endif - #define BUS_SWAP32(v) (v) extern void *osl_dma_alloc_consistent(struct osl_info *osh, uint size, @@ -321,32 +312,4 @@ osl_pkt_tonative(struct osl_pubinfo *osh, void *pkt) /* PKTSETSUMNEEDED and PKTSUMGOOD are not possible because skb->ip_summed is overloaded */ #define PKTSHARED(skb) (((struct sk_buff *)(skb))->cloned) -#if defined(BCMSDIO) && !defined(BRCM_FULLMAC) -#define RPC_READ_REG(osh, r) (\ - sizeof(*(r)) == sizeof(u8) ? osl_readb((osh), (volatile u8*)(r)) : \ - sizeof(*(r)) == sizeof(u16) ? osl_readw((osh), (volatile u16*)(r)) : \ - osl_readl((osh), (volatile u32*)(r)) \ -) -#define RPC_WRITE_REG(osh, r, v) do { \ - switch (sizeof(*(r))) { \ - case sizeof(u8): \ - osl_writeb((osh), (volatile u8*)(r), (u8)(v)); \ - break; \ - case sizeof(u16): \ - osl_writew((osh), (volatile u16*)(r), (u16)(v)); \ - break; \ - case sizeof(u32): \ - osl_writel((osh), (volatile u32*)(r), (u32)(v)); \ - break; \ - } \ -} while (0) - -extern u8 osl_readb(struct osl_info *osh, volatile u8 *r); -extern u16 osl_readw(struct osl_info *osh, volatile u16 *r); -extern u32 osl_readl(struct osl_info *osh, volatile u32 *r); -extern void osl_writeb(struct osl_info *osh, volatile u8 *r, u8 v); -extern void osl_writew(struct osl_info *osh, volatile u16 *r, u16 v); -extern void osl_writel(struct osl_info *osh, volatile u32 *r, u32 v); -#endif /* BCMSDIO */ - #endif /* _linux_osl_h_ */ diff --git a/drivers/staging/brcm80211/include/osl.h b/drivers/staging/brcm80211/include/osl.h index e2205c481a3f..4d0ce9705500 100644 --- a/drivers/staging/brcm80211/include/osl.h +++ b/drivers/staging/brcm80211/include/osl.h @@ -26,11 +26,6 @@ struct osl_pubinfo { bool mmbus; /* Bus supports memory-mapped registers */ pktfree_cb_fn_t tx_fn; /* Callback function for PKTFREE */ void *tx_ctx; /* Context to the callback function */ -#if defined(BCMSDIO) && !defined(BRCM_FULLMAC) - osl_rreg_fn_t rreg_fn; /* Read Register function */ - osl_wreg_fn_t wreg_fn; /* Write Register function */ - void *reg_ctx; /* Context to the reg callback functions */ -#endif }; /* osl handle type forward declaration */ diff --git a/drivers/staging/brcm80211/sys/wlc_cfg.h b/drivers/staging/brcm80211/sys/wlc_cfg.h index e56adb78f4fa..3decb7d1a5e5 100644 --- a/drivers/staging/brcm80211/sys/wlc_cfg.h +++ b/drivers/staging/brcm80211/sys/wlc_cfg.h @@ -23,8 +23,6 @@ #define IS_SINGLEBAND_5G(device) 0 -/* Keep WLC_HIGH_ONLY, WLC_SPLIT for USB extension later on */ - /* **** Core type/rev defaults **** */ #define D11_DEFAULT 0x0fffffb0 /* Supported D11 revs: 4, 5, 7-27 * also need to update wlc.h MAXCOREREV diff --git a/drivers/staging/brcm80211/sys/wlc_mac80211.h b/drivers/staging/brcm80211/sys/wlc_mac80211.h index 8c961e21002f..006880049f37 100644 --- a/drivers/staging/brcm80211/sys/wlc_mac80211.h +++ b/drivers/staging/brcm80211/sys/wlc_mac80211.h @@ -815,7 +815,6 @@ struct antsel_info { #define WLC_IS_MATCH_SSID(wlc, ssid1, ssid2, len1, len2) \ ((len1 == len2) && !bcmp(ssid1, ssid2, len1)) -/* API shared by both WLC_HIGH and WLC_LOW driver */ extern void wlc_high_dpc(wlc_info_t *wlc, u32 macintstatus); extern void wlc_fatal_error(wlc_info_t *wlc); extern void wlc_bmac_rpc_watchdog(wlc_info_t *wlc); diff --git a/drivers/staging/brcm80211/sys/wlc_pub.h b/drivers/staging/brcm80211/sys/wlc_pub.h index 2f4b899f0fe1..4b1ab1d1c2ce 100644 --- a/drivers/staging/brcm80211/sys/wlc_pub.h +++ b/drivers/staging/brcm80211/sys/wlc_pub.h @@ -610,10 +610,6 @@ extern void wlc_pmkid_event(struct wlc_bsscfg *cfg); #define BAND_2G_NAME "2.4G" #define BAND_5G_NAME "5G" -#if defined(BCMSDIO) || defined(WLC_HIGH_ONLY) -void wlc_device_removed(void *arg); -#endif - /* BMAC RPC: 7 u32 params: pkttotlen, fifo, commit, fid, txpktpend, pktflag, rpc_id */ #define WLC_RPCTX_PARAMS 32 diff --git a/drivers/staging/brcm80211/util/linux_osl.c b/drivers/staging/brcm80211/util/linux_osl.c index e6e52f660780..a07eada14d08 100644 --- a/drivers/staging/brcm80211/util/linux_osl.c +++ b/drivers/staging/brcm80211/util/linux_osl.c @@ -246,52 +246,3 @@ void osl_assert(char *exp, char *file, int line) } #endif /* defined(BCMDBG_ASSERT) */ -#if defined(BCMSDIO) && !defined(BRCM_FULLMAC) -u8 osl_readb(struct osl_info *osh, volatile u8 *r) -{ - osl_rreg_fn_t rreg = ((struct osl_pubinfo *) osh)->rreg_fn; - void *ctx = ((struct osl_pubinfo *) osh)->reg_ctx; - - return (u8) ((rreg) (ctx, (void *)r, sizeof(u8))); -} - -u16 osl_readw(struct osl_info *osh, volatile u16 *r) -{ - osl_rreg_fn_t rreg = ((struct osl_pubinfo *) osh)->rreg_fn; - void *ctx = ((struct osl_pubinfo *) osh)->reg_ctx; - - return (u16) ((rreg) (ctx, (void *)r, sizeof(u16))); -} - -u32 osl_readl(struct osl_info *osh, volatile u32 *r) -{ - osl_rreg_fn_t rreg = ((struct osl_pubinfo *) osh)->rreg_fn; - void *ctx = ((struct osl_pubinfo *) osh)->reg_ctx; - - return (u32) ((rreg) (ctx, (void *)r, sizeof(u32))); -} - -void osl_writeb(struct osl_info *osh, volatile u8 *r, u8 v) -{ - osl_wreg_fn_t wreg = ((struct osl_pubinfo *) osh)->wreg_fn; - void *ctx = ((struct osl_pubinfo *) osh)->reg_ctx; - - ((wreg) (ctx, (void *)r, v, sizeof(u8))); -} - -void osl_writew(struct osl_info *osh, volatile u16 *r, u16 v) -{ - osl_wreg_fn_t wreg = ((struct osl_pubinfo *) osh)->wreg_fn; - void *ctx = ((struct osl_pubinfo *) osh)->reg_ctx; - - ((wreg) (ctx, (void *)r, v, sizeof(u16))); -} - -void osl_writel(struct osl_info *osh, volatile u32 *r, u32 v) -{ - osl_wreg_fn_t wreg = ((struct osl_pubinfo *) osh)->wreg_fn; - void *ctx = ((struct osl_pubinfo *) osh)->reg_ctx; - - ((wreg) (ctx, (void *)r, v, sizeof(u32))); -} -#endif /* BCMSDIO */ -- cgit v1.2.3 From 5a7f4fddae8a50d076b5714f47936ea78e0c0858 Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Fri, 19 Nov 2010 13:32:38 +0100 Subject: staging: iio: dac: more consistent DAC sysfs attributes naming Align DAC sysfs attributes naming with the convention used by ADC Signed-off-by: Michael Hennerich Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/dac/dac.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/staging/iio/dac/dac.h b/drivers/staging/iio/dac/dac.h index 55005eec1214..d9384c9a3e85 100644 --- a/drivers/staging/iio/dac/dac.h +++ b/drivers/staging/iio/dac/dac.h @@ -2,5 +2,9 @@ * dac.h - sysfs attributes associated with DACs */ +/* Deprecated */ #define IIO_DEV_ATTR_DAC(_num, _store, _addr) \ IIO_DEVICE_ATTR(dac_##_num, S_IWUSR, NULL, _store, _addr) + +#define IIO_DEV_ATTR_OUT_RAW(_num, _store, _addr) \ + IIO_DEVICE_ATTR(out##_num##_raw, S_IWUSR, NULL, _store, _addr) -- cgit v1.2.3 From 51f8ad36022e880019e79a9dea2351cc47c739d7 Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Fri, 19 Nov 2010 15:16:43 +0100 Subject: staging: iio: dac: Update drivers to use new attribute naming Remove depreciated macro from header Signed-off-by: Michael Hennerich Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/dac/ad5624r_spi.c | 16 ++++++++-------- drivers/staging/iio/dac/dac.h | 4 ---- 2 files changed, 8 insertions(+), 12 deletions(-) diff --git a/drivers/staging/iio/dac/ad5624r_spi.c b/drivers/staging/iio/dac/ad5624r_spi.c index 705ff505bf25..c0d7de90b784 100644 --- a/drivers/staging/iio/dac/ad5624r_spi.c +++ b/drivers/staging/iio/dac/ad5624r_spi.c @@ -180,10 +180,10 @@ static ssize_t ad5624r_write_internal_ref_mode(struct device *dev, return ret ? ret : len; } -static IIO_DEV_ATTR_DAC(0, ad5624r_write_dac, AD5624R_ADDR_DAC0); -static IIO_DEV_ATTR_DAC(1, ad5624r_write_dac, AD5624R_ADDR_DAC1); -static IIO_DEV_ATTR_DAC(2, ad5624r_write_dac, AD5624R_ADDR_DAC2); -static IIO_DEV_ATTR_DAC(3, ad5624r_write_dac, AD5624R_ADDR_DAC3); +static IIO_DEV_ATTR_OUT_RAW(0, ad5624r_write_dac, AD5624R_ADDR_DAC0); +static IIO_DEV_ATTR_OUT_RAW(1, ad5624r_write_dac, AD5624R_ADDR_DAC1); +static IIO_DEV_ATTR_OUT_RAW(2, ad5624r_write_dac, AD5624R_ADDR_DAC2); +static IIO_DEV_ATTR_OUT_RAW(3, ad5624r_write_dac, AD5624R_ADDR_DAC3); static IIO_DEVICE_ATTR(ldac_mode, S_IRUGO | S_IWUSR, ad5624r_read_ldac_mode, ad5624r_write_ldac_mode, 0); @@ -199,10 +199,10 @@ static IIO_DEV_ATTR_DAC_POWER_MODE(2, ad5624r_read_dac_power_mode, ad5624r_write static IIO_DEV_ATTR_DAC_POWER_MODE(3, ad5624r_read_dac_power_mode, ad5624r_write_dac_power_mode, 3); static struct attribute *ad5624r_attributes[] = { - &iio_dev_attr_dac_0.dev_attr.attr, - &iio_dev_attr_dac_1.dev_attr.attr, - &iio_dev_attr_dac_2.dev_attr.attr, - &iio_dev_attr_dac_3.dev_attr.attr, + &iio_dev_attr_out0_raw.dev_attr.attr, + &iio_dev_attr_out1_raw.dev_attr.attr, + &iio_dev_attr_out2_raw.dev_attr.attr, + &iio_dev_attr_out3_raw.dev_attr.attr, &iio_dev_attr_dac_power_mode_0.dev_attr.attr, &iio_dev_attr_dac_power_mode_1.dev_attr.attr, &iio_dev_attr_dac_power_mode_2.dev_attr.attr, diff --git a/drivers/staging/iio/dac/dac.h b/drivers/staging/iio/dac/dac.h index d9384c9a3e85..1d82f353241c 100644 --- a/drivers/staging/iio/dac/dac.h +++ b/drivers/staging/iio/dac/dac.h @@ -2,9 +2,5 @@ * dac.h - sysfs attributes associated with DACs */ -/* Deprecated */ -#define IIO_DEV_ATTR_DAC(_num, _store, _addr) \ - IIO_DEVICE_ATTR(dac_##_num, S_IWUSR, NULL, _store, _addr) - #define IIO_DEV_ATTR_OUT_RAW(_num, _store, _addr) \ IIO_DEVICE_ATTR(out##_num##_raw, S_IWUSR, NULL, _store, _addr) -- cgit v1.2.3 From df9cd1052079e5d0f88ed230276a17a49cc41045 Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Fri, 19 Nov 2010 15:16:44 +0100 Subject: staging: iio: dac: Use spi_write() and handle return value Signed-off-by: Michael Hennerich Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/dac/ad5624r_spi.c | 23 +++++++---------------- 1 file changed, 7 insertions(+), 16 deletions(-) diff --git a/drivers/staging/iio/dac/ad5624r_spi.c b/drivers/staging/iio/dac/ad5624r_spi.c index c0d7de90b784..17588b4b055d 100644 --- a/drivers/staging/iio/dac/ad5624r_spi.c +++ b/drivers/staging/iio/dac/ad5624r_spi.c @@ -35,10 +35,9 @@ struct ad5624r_state { int internal_ref; }; -static int ad5624r_spi_write(struct spi_device *spi, u8 cmd, u8 addr, u16 val, u8 len) +static int ad5624r_spi_write(struct spi_device *spi, + u8 cmd, u8 addr, u16 val, u8 len) { - struct spi_transfer t; - struct spi_message m; u32 data; u8 msg[3]; @@ -54,15 +53,7 @@ static int ad5624r_spi_write(struct spi_device *spi, u8 cmd, u8 addr, u16 val, u msg[1] = data >> 8; msg[2] = data; - spi_message_init(&m); - memset(&t, 0, (sizeof t)); - t.tx_buf = &msg[0]; - t.len = 3; - - spi_message_add_tail(&t, &m); - spi_sync(spi, &m); - - return len; + return spi_write(spi, msg, 3); } static ssize_t ad5624r_write_dac(struct device *dev, @@ -80,7 +71,7 @@ static ssize_t ad5624r_write_dac(struct device *dev, if (ret) return ret; - ad5624r_spi_write(st->us, AD5624R_CMD_WRITE_INPUT_N_UPDATE_N, + ret = ad5624r_spi_write(st->us, AD5624R_CMD_WRITE_INPUT_N_UPDATE_N, this_attr->address, readin, st->data_len); return ret ? ret : len; } @@ -109,7 +100,7 @@ static ssize_t ad5624r_write_ldac_mode(struct device *dev, if (ret) return ret; - ad5624r_spi_write(st->us, AD5624R_CMD_LDAC_SETUP, 0, readin & 0xF, 16); + ret = ad5624r_spi_write(st->us, AD5624R_CMD_LDAC_SETUP, 0, readin & 0xF, 16); st->ldac_mode = readin & 0xF; return ret ? ret : len; @@ -141,7 +132,7 @@ static ssize_t ad5624r_write_dac_power_mode(struct device *dev, if (ret) return ret; - ad5624r_spi_write(st->us, AD5624R_CMD_POWERDOWN_DAC, 0, + ret = ad5624r_spi_write(st->us, AD5624R_CMD_POWERDOWN_DAC, 0, ((readin & 0x3) << 4) | (1 << this_attr->address), 16); st->dac_power_mode[this_attr->address] = readin & 0x3; @@ -173,7 +164,7 @@ static ssize_t ad5624r_write_internal_ref_mode(struct device *dev, if (ret) return ret; - ad5624r_spi_write(st->us, AD5624R_CMD_INTERNAL_REFER_SETUP, 0, !!readin, 16); + ret = ad5624r_spi_write(st->us, AD5624R_CMD_INTERNAL_REFER_SETUP, 0, !!readin, 16); st->internal_ref = !!readin; -- cgit v1.2.3 From ece30c15921f94c1d58c494507f528c9482db409 Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Fri, 19 Nov 2010 15:16:45 +0100 Subject: staging: iio: dac: Use spi_device_id Signed-off-by: Michael Hennerich Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/dac/ad5624r_spi.c | 25 +++++++++---------------- 1 file changed, 9 insertions(+), 16 deletions(-) diff --git a/drivers/staging/iio/dac/ad5624r_spi.c b/drivers/staging/iio/dac/ad5624r_spi.c index 17588b4b055d..b7c1661f6872 100644 --- a/drivers/staging/iio/dac/ad5624r_spi.c +++ b/drivers/staging/iio/dac/ad5624r_spi.c @@ -209,13 +209,8 @@ static const struct attribute_group ad5624r_attribute_group = { static int __devinit ad5624r_probe(struct spi_device *spi) { - struct ad5624r_state *st; int ret = 0; - char *chip_name = spi->dev.platform_data; - - if (!chip_name) - return -ENODEV; st = kzalloc(sizeof(*st), GFP_KERNEL); if (st == NULL) { @@ -224,17 +219,7 @@ static int __devinit ad5624r_probe(struct spi_device *spi) } spi_set_drvdata(spi, st); - if (strcmp(chip_name, "ad5624r") == 0) - st->data_len = 12; - else if (strcmp(chip_name, "ad5644r") == 0) - st->data_len = 14; - else if (strcmp(chip_name, "ad5664r") == 0) - st->data_len = 16; - else { - dev_err(&spi->dev, "not supported chip type\n"); - ret = -EINVAL; - goto error_ret; - } + st->data_len = spi_get_device_id(spi)->driver_data; st->us = spi; st->indio_dev = iio_allocate_device(); @@ -278,6 +263,13 @@ static int __devexit ad5624r_remove(struct spi_device *spi) return 0; } +static const struct spi_device_id ad5624r_id[] = { + {"ad5624r", 12}, + {"ad5644r", 14}, + {"ad5664r", 16}, + {} +}; + static struct spi_driver ad5624r_driver = { .driver = { .name = "ad5624r", @@ -285,6 +277,7 @@ static struct spi_driver ad5624r_driver = { }, .probe = ad5624r_probe, .remove = __devexit_p(ad5624r_remove), + .id_table = ad5624r_id, }; static __init int ad5624r_spi_init(void) -- cgit v1.2.3 From 24d6050b352aa76364bd344c41b3e3e0f51466cc Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Fri, 19 Nov 2010 15:16:46 +0100 Subject: staging: iio: dac: Cleanup style - no functional changes Stick to the 80 character line limit at least for code Signed-off-by: Michael Hennerich Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/dac/ad5624r_spi.c | 67 ++++++++++++++++++----------------- 1 file changed, 35 insertions(+), 32 deletions(-) diff --git a/drivers/staging/iio/dac/ad5624r_spi.c b/drivers/staging/iio/dac/ad5624r_spi.c index b7c1661f6872..2b1c6dde4fdd 100644 --- a/drivers/staging/iio/dac/ad5624r_spi.c +++ b/drivers/staging/iio/dac/ad5624r_spi.c @@ -57,9 +57,8 @@ static int ad5624r_spi_write(struct spi_device *spi, } static ssize_t ad5624r_write_dac(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t len) + struct device_attribute *attr, + const char *buf, size_t len) { long readin; int ret; @@ -72,13 +71,12 @@ static ssize_t ad5624r_write_dac(struct device *dev, return ret; ret = ad5624r_spi_write(st->us, AD5624R_CMD_WRITE_INPUT_N_UPDATE_N, - this_attr->address, readin, st->data_len); + this_attr->address, readin, st->data_len); return ret ? ret : len; } static ssize_t ad5624r_read_ldac_mode(struct device *dev, - struct device_attribute *attr, - char *buf) + struct device_attribute *attr, char *buf) { struct iio_dev *indio_dev = dev_get_drvdata(dev); struct ad5624r_state *st = indio_dev->dev_data; @@ -87,9 +85,8 @@ static ssize_t ad5624r_read_ldac_mode(struct device *dev, } static ssize_t ad5624r_write_ldac_mode(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t len) + struct device_attribute *attr, + const char *buf, size_t len) { long readin; int ret; @@ -100,15 +97,16 @@ static ssize_t ad5624r_write_ldac_mode(struct device *dev, if (ret) return ret; - ret = ad5624r_spi_write(st->us, AD5624R_CMD_LDAC_SETUP, 0, readin & 0xF, 16); + ret = ad5624r_spi_write(st->us, AD5624R_CMD_LDAC_SETUP, 0, + readin & 0xF, 16); st->ldac_mode = readin & 0xF; return ret ? ret : len; } static ssize_t ad5624r_read_dac_power_mode(struct device *dev, - struct device_attribute *attr, - char *buf) + struct device_attribute *attr, + char *buf) { struct iio_dev *indio_dev = dev_get_drvdata(dev); struct ad5624r_state *st = indio_dev->dev_data; @@ -118,9 +116,8 @@ static ssize_t ad5624r_read_dac_power_mode(struct device *dev, } static ssize_t ad5624r_write_dac_power_mode(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t len) + struct device_attribute *attr, + const char *buf, size_t len) { long readin; int ret; @@ -133,7 +130,8 @@ static ssize_t ad5624r_write_dac_power_mode(struct device *dev, return ret; ret = ad5624r_spi_write(st->us, AD5624R_CMD_POWERDOWN_DAC, 0, - ((readin & 0x3) << 4) | (1 << this_attr->address), 16); + ((readin & 0x3) << 4) | + (1 << this_attr->address), 16); st->dac_power_mode[this_attr->address] = readin & 0x3; @@ -141,8 +139,8 @@ static ssize_t ad5624r_write_dac_power_mode(struct device *dev, } static ssize_t ad5624r_read_internal_ref_mode(struct device *dev, - struct device_attribute *attr, - char *buf) + struct device_attribute *attr, + char *buf) { struct iio_dev *indio_dev = dev_get_drvdata(dev); struct ad5624r_state *st = indio_dev->dev_data; @@ -151,9 +149,8 @@ static ssize_t ad5624r_read_internal_ref_mode(struct device *dev, } static ssize_t ad5624r_write_internal_ref_mode(struct device *dev, - struct device_attribute *attr, - const char *buf, - size_t len) + struct device_attribute *attr, + const char *buf, size_t len) { long readin; int ret; @@ -164,7 +161,8 @@ static ssize_t ad5624r_write_internal_ref_mode(struct device *dev, if (ret) return ret; - ret = ad5624r_spi_write(st->us, AD5624R_CMD_INTERNAL_REFER_SETUP, 0, !!readin, 16); + ret = ad5624r_spi_write(st->us, AD5624R_CMD_INTERNAL_REFER_SETUP, 0, + !!readin, 16); st->internal_ref = !!readin; @@ -177,17 +175,22 @@ static IIO_DEV_ATTR_OUT_RAW(2, ad5624r_write_dac, AD5624R_ADDR_DAC2); static IIO_DEV_ATTR_OUT_RAW(3, ad5624r_write_dac, AD5624R_ADDR_DAC3); static IIO_DEVICE_ATTR(ldac_mode, S_IRUGO | S_IWUSR, ad5624r_read_ldac_mode, - ad5624r_write_ldac_mode, 0); -static IIO_DEVICE_ATTR(internal_ref, S_IRUGO | S_IWUSR, ad5624r_read_internal_ref_mode, - ad5624r_write_internal_ref_mode, 0); + ad5624r_write_ldac_mode, 0); +static IIO_DEVICE_ATTR(internal_ref, S_IRUGO | S_IWUSR, + ad5624r_read_internal_ref_mode, + ad5624r_write_internal_ref_mode, 0); #define IIO_DEV_ATTR_DAC_POWER_MODE(_num, _show, _store, _addr) \ IIO_DEVICE_ATTR(dac_power_mode_##_num, S_IRUGO | S_IWUSR, _show, _store, _addr) -static IIO_DEV_ATTR_DAC_POWER_MODE(0, ad5624r_read_dac_power_mode, ad5624r_write_dac_power_mode, 0); -static IIO_DEV_ATTR_DAC_POWER_MODE(1, ad5624r_read_dac_power_mode, ad5624r_write_dac_power_mode, 1); -static IIO_DEV_ATTR_DAC_POWER_MODE(2, ad5624r_read_dac_power_mode, ad5624r_write_dac_power_mode, 2); -static IIO_DEV_ATTR_DAC_POWER_MODE(3, ad5624r_read_dac_power_mode, ad5624r_write_dac_power_mode, 3); +static IIO_DEV_ATTR_DAC_POWER_MODE(0, ad5624r_read_dac_power_mode, + ad5624r_write_dac_power_mode, 0); +static IIO_DEV_ATTR_DAC_POWER_MODE(1, ad5624r_read_dac_power_mode, + ad5624r_write_dac_power_mode, 1); +static IIO_DEV_ATTR_DAC_POWER_MODE(2, ad5624r_read_dac_power_mode, + ad5624r_write_dac_power_mode, 2); +static IIO_DEV_ATTR_DAC_POWER_MODE(3, ad5624r_read_dac_power_mode, + ad5624r_write_dac_power_mode, 3); static struct attribute *ad5624r_attributes[] = { &iio_dev_attr_out0_raw.dev_attr.attr, @@ -272,9 +275,9 @@ static const struct spi_device_id ad5624r_id[] = { static struct spi_driver ad5624r_driver = { .driver = { - .name = "ad5624r", - .owner = THIS_MODULE, - }, + .name = "ad5624r", + .owner = THIS_MODULE, + }, .probe = ad5624r_probe, .remove = __devexit_p(ad5624r_remove), .id_table = ad5624r_id, -- cgit v1.2.3 From 7716090be5603f1ad4df1379652b8d107c207f5c Mon Sep 17 00:00:00 2001 From: Marek Belisko Date: Thu, 18 Nov 2010 09:49:09 +0100 Subject: staging: ft1000: Fix compilation warning. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch fix following warning: drivers/staging/ft1000/ft1000-usb/ft1000_usb.c:67:22: warning: ‘pft1000info’ may be used uninitialized in this function Signed-off-by: Marek Belisko Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ft1000/ft1000-usb/ft1000_usb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_usb.c b/drivers/staging/ft1000/ft1000-usb/ft1000_usb.c index 1369f06cb0df..f88ff86df177 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_usb.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_usb.c @@ -64,7 +64,7 @@ static int ft1000_probe(struct usb_interface *interface, int i, ret = 0, size; struct ft1000_device *ft1000dev; - struct ft1000_info *pft1000info; + struct ft1000_info *pft1000info = NULL; const struct firmware *dsp_fw; ft1000dev = kmalloc(sizeof(struct ft1000_device), GFP_KERNEL); -- cgit v1.2.3 From d948d5f96a4b5923599a7a657dbbd8660b0f9fa5 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Wed, 17 Nov 2010 15:38:46 -0800 Subject: staging: clearpad_tm1217 depends on INPUT clearpad_tm1217 driver uses many input_() interfaces, so it should depend on INPUT. clearpad_tm1217.c:(.text+0xf19ac): undefined reference to `input_unregister_device' clearpad_tm1217.c:(.text+0xf1b19): undefined reference to `input_event' clearpad_tm1217.c:(.text+0xf1b31): undefined reference to `input_event' clearpad_tm1217.c:(.text+0xf1bb4): undefined reference to `input_event' clearpad_tm1217.c:(.text+0xf1bf2): undefined reference to `input_event' drivers/built-in.o:clearpad_tm1217.c:(.text+0xf1c08): more undefined references to `input_event' follow clearpad_tm1217.c:(.text+0xf1df3): undefined reference to `input_allocate_device' clearpad_tm1217.c:(.text+0xf1eac): undefined reference to `input_set_abs_params' clearpad_tm1217.c:(.text+0xf1ed1): undefined reference to `input_set_abs_params' clearpad_tm1217.c:(.text+0xf1ed8): undefined reference to `input_register_device' clearpad_tm1217.c:(.text+0xf2040): undefined reference to `input_unregister_device' clearpad_tm1217.c:(.text+0xf204b): undefined reference to `input_free_device' Signed-off-by: Randy Dunlap Cc: Ramesh Agarwal Signed-off-by: Greg Kroah-Hartman --- drivers/staging/cptm1217/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/staging/cptm1217/Kconfig b/drivers/staging/cptm1217/Kconfig index f90545d78f93..43b1cc0a50a5 100644 --- a/drivers/staging/cptm1217/Kconfig +++ b/drivers/staging/cptm1217/Kconfig @@ -2,6 +2,7 @@ config TOUCHSCREEN_CLEARPAD_TM1217 tristate "Synaptics Clearpad TM1217" depends on I2C depends on GPIOLIB + depends on INPUT help Say Y here if you have a Synaptics Clearpad TM1217 Controller -- cgit v1.2.3 From 4856ab33eb5c33bdf17a5a1bd8d720bffe5f6110 Mon Sep 17 00:00:00 2001 From: Mark Allyn Date: Wed, 17 Nov 2010 15:45:36 -0800 Subject: Staging: sep: Introduce sep driver This driver is for the Security Processor, a dedicated encryption and decryption driver that is used on the Intel mobile platform. This has been checked with checkpatch and there are four warnings for lines over 80 charactors. There is one compile warning. This is for a function that is only used if the rar register driver is needed. There is an ifdef in a header file that stubs out the rar register driver if the rar register is not configured. This driver does add a configuration, which is CONFIG_DX_SEP. Signed-off-by: Mark Allyn Signed-off-by: Greg Kroah-Hartman --- drivers/staging/Kconfig | 2 + drivers/staging/Makefile | 1 + drivers/staging/sep/Kconfig | 11 + drivers/staging/sep/Makefile | 2 + drivers/staging/sep/TODO | 12 + drivers/staging/sep/sep_dev.h | 156 ++ drivers/staging/sep/sep_driver.c | 4152 ++++++++++++++++++++++++++++++ drivers/staging/sep/sep_driver_api.h | 309 +++ drivers/staging/sep/sep_driver_config.h | 428 +++ drivers/staging/sep/sep_driver_hw_defs.h | 234 ++ 10 files changed, 5307 insertions(+) create mode 100644 drivers/staging/sep/Kconfig create mode 100644 drivers/staging/sep/Makefile create mode 100644 drivers/staging/sep/TODO create mode 100644 drivers/staging/sep/sep_dev.h create mode 100644 drivers/staging/sep/sep_driver.c create mode 100644 drivers/staging/sep/sep_driver_api.h create mode 100644 drivers/staging/sep/sep_driver_config.h create mode 100644 drivers/staging/sep/sep_driver_hw_defs.h diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index 49aee27b296d..1f61914a3ab8 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -119,6 +119,8 @@ source "drivers/staging/vme/Kconfig" source "drivers/staging/memrar/Kconfig" +source "drivers/staging/sep/Kconfig" + source "drivers/staging/iio/Kconfig" source "drivers/staging/zram/Kconfig" diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index 20c5641b6cd7..75c0c1ff1cf5 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -42,6 +42,7 @@ obj-$(CONFIG_FB_UDL) += udlfb/ obj-$(CONFIG_HYPERV) += hv/ obj-$(CONFIG_VME_BUS) += vme/ obj-$(CONFIG_MRST_RAR_HANDLER) += memrar/ +obj-$(CONFIG_DX_SEP) += sep/ obj-$(CONFIG_IIO) += iio/ obj-$(CONFIG_ZRAM) += zram/ obj-$(CONFIG_WLAGS49_H2) += wlags49_h2/ diff --git a/drivers/staging/sep/Kconfig b/drivers/staging/sep/Kconfig new file mode 100644 index 000000000000..34f3ef5f9df8 --- /dev/null +++ b/drivers/staging/sep/Kconfig @@ -0,0 +1,11 @@ +config DX_SEP + tristate "Discretix SEP driver" + depends on PCI + default y + help + Discretix SEP driver; used for the security processor subsystem + on bard the Intel Mobile Internet Device. + + The driver's name is sep_driver. + + If unsure, select N. diff --git a/drivers/staging/sep/Makefile b/drivers/staging/sep/Makefile new file mode 100644 index 000000000000..628d5f919414 --- /dev/null +++ b/drivers/staging/sep/Makefile @@ -0,0 +1,2 @@ +obj-$(CONFIG_DX_SEP) := sep_driver.o + diff --git a/drivers/staging/sep/TODO b/drivers/staging/sep/TODO new file mode 100644 index 000000000000..371ee279f327 --- /dev/null +++ b/drivers/staging/sep/TODO @@ -0,0 +1,12 @@ +Todo's so far (from Alan Cox) +- Fix firmware loading - Done 09/10 M. Allyn +- Get firmware into firmware git tree - Firmware is non open source +- Review and tidy each algorithm function - Done 09/10 M. Allyn +- Check whether it can be plugged into any of the kernel crypto API + interfaces - Crypto API 'glue' is still not ready to submit +- Do something about the magic shared memory interface and replace it + with something saner (in Linux terms) - Done 09/10 M. Allyn +- Clean up unused ioctls - Needs vendor help +- Clean up unused fields in ioctl structures - Needs vendor help +- 64 bit size to be used for all user space addresses passed + to ioctl - Done 10/10 M. Allyn diff --git a/drivers/staging/sep/sep_dev.h b/drivers/staging/sep/sep_dev.h new file mode 100644 index 000000000000..7b4993b3650d --- /dev/null +++ b/drivers/staging/sep/sep_dev.h @@ -0,0 +1,156 @@ +#ifndef __SEP_DEV_H__ +#define __SEP_DEV_H__ + +/* + * + * sep_dev.h - Security Processor Device Structures + * + * Copyright(c) 2009,2010 Intel Corporation. All rights reserved. + * Contributions(c) 2009,2010 Discretix. All rights reserved. + * + * 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; version 2 of the License. + * + * 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. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * CONTACTS: + * + * Mark Allyn mark.a.allyn@intel.com + * Jayant Mangalampalli jayant.mangalampalli@intel.com + * + * CHANGES + * 2010.09.14 upgrade to Medfield + */ + +struct sep_device { + /* pointer to pci dev */ + struct pci_dev *pdev; + + /* character device file */ + struct cdev sep_cdev; + struct cdev sep_daemon_cdev; + struct cdev sep_singleton_cdev; + + /* devices (using misc dev) */ + struct miscdevice miscdev_sep; + struct miscdevice miscdev_singleton; + struct miscdevice miscdev_daemon; + + /* major / minor numbers of device */ + dev_t sep_devno; + dev_t sep_daemon_devno; + dev_t sep_singleton_devno; + + struct mutex sep_mutex; + struct mutex ioctl_mutex; + spinlock_t snd_rply_lck; + + /* flags to indicate use and lock status of sep */ + u32 pid_doing_transaction; + unsigned long in_use_flags; + + /* request daemon alread open */ + unsigned long request_daemon_open; + + /* 1 = Moorestown; 0 = Medfield */ + int mrst; + + /* address of the shared memory allocated during init for SEP driver + (coherent alloc) */ + dma_addr_t shared_bus; + size_t shared_size; + void *shared_addr; + + /* restricted access region (coherent alloc) */ + dma_addr_t rar_bus; + size_t rar_size; + void *rar_addr; + + /* Firmware regions; cache is at rar for Moorestown and + resident is at rar for Medfield */ + dma_addr_t cache_bus; + size_t cache_size; + void *cache_addr; + + dma_addr_t resident_bus; + size_t resident_size; + void *resident_addr; + + /* sep's scratchpad */ + dma_addr_t dcache_bus; + size_t dcache_size; + void *dcache_addr; + + /* Only used on Medfield */ + dma_addr_t extapp_bus; + size_t extapp_size; + void *extapp_addr; + + /* start address of the access to the SEP registers from driver */ + dma_addr_t reg_physical_addr; + dma_addr_t reg_physical_end; + void __iomem *reg_addr; + + /* wait queue head (event) of the driver */ + wait_queue_head_t event; + wait_queue_head_t event_request_daemon; + wait_queue_head_t event_mmap; + + struct sep_caller_id_entry + caller_id_table[SEP_CALLER_ID_TABLE_NUM_ENTRIES]; + + /* access flag for singleton device */ + unsigned long singleton_access_flag; + + /* transaction counter that coordinates the + transactions between SEP and HOST */ + unsigned long send_ct; + /* counter for the messages from sep */ + unsigned long reply_ct; + /* counter for the number of bytes allocated in the pool for the + current transaction */ + long data_pool_bytes_allocated; + + u32 num_of_data_allocations; + + /* number of the lli tables created in the current transaction */ + u32 num_lli_tables_created; + + /* number of data control blocks */ + u32 nr_dcb_creat; + + struct sep_dma_resource dma_res_arr[SEP_MAX_NUM_SYNC_DMA_OPS]; + +}; + +static inline void sep_write_reg(struct sep_device *dev, int reg, u32 value) +{ + void __iomem *addr = dev->reg_addr + reg; + writel(value, addr); +} + +static inline u32 sep_read_reg(struct sep_device *dev, int reg) +{ + void __iomem *addr = dev->reg_addr + reg; + return readl(addr); +} + +/* wait for SRAM write complete(indirect write */ +static inline void sep_wait_sram_write(struct sep_device *dev) +{ + u32 reg_val; + do + reg_val = sep_read_reg(dev, HW_SRAM_DATA_READY_REG_ADDR); + while (!(reg_val & 1)); +} + + +#endif diff --git a/drivers/staging/sep/sep_driver.c b/drivers/staging/sep/sep_driver.c new file mode 100644 index 000000000000..ef36239c7b24 --- /dev/null +++ b/drivers/staging/sep/sep_driver.c @@ -0,0 +1,4152 @@ +/* + * + * sep_driver.c - Security Processor Driver main group of functions + * + * Copyright(c) 2009,2010 Intel Corporation. All rights reserved. + * Contributions(c) 2009,2010 Discretix. All rights reserved. + * + * 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; version 2 of the License. + * + * 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. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * CONTACTS: + * + * Mark Allyn mark.a.allyn@intel.com + * Jayant Mangalampalli jayant.mangalampalli@intel.com + * + * CHANGES: + * + * 2009.06.26 Initial publish + * 2010.09.14 Upgrade to Medfield + * + */ +#define DEBUG +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "sep_driver_hw_defs.h" +#include "sep_driver_config.h" +#include "sep_driver_api.h" +#include "sep_dev.h" + +/*---------------------------------------- + DEFINES +-----------------------------------------*/ + +#define SEP_RAR_IO_MEM_REGION_SIZE 0x40000 + +/*-------------------------------------------- + GLOBAL variables +--------------------------------------------*/ + +/* Keep this a single static object for now to keep the conversion easy */ + +static struct sep_device *sep_dev; + +/** + * sep_load_firmware - copy firmware cache/resident + * This functions copies the cache and resident from their source + * location into destination shared memory. + * @sep: pointer to struct sep_device + */ + +static int sep_load_firmware(struct sep_device *sep) +{ + const struct firmware *fw; + char *cache_name = "cache.image.bin"; + char *res_name = "resident.image.bin"; + char *extapp_name = "extapp.image.bin"; + + int error = 0; + unsigned int work1, work2, work3; + + /* set addresses and load resident */ + sep->resident_bus = sep->rar_bus; + sep->resident_addr = sep->rar_addr; + + error = request_firmware(&fw, res_name, &sep->pdev->dev); + if (error) { + dev_warn(&sep->pdev->dev, "cant request resident fw\n"); + return error; + } + + memcpy(sep->resident_addr, (void *)fw->data, fw->size); + sep->resident_size = fw->size; + release_firmware(fw); + + dev_dbg(&sep->pdev->dev, "resident virtual is %p\n", + sep->resident_addr); + dev_dbg(&sep->pdev->dev, "residnet bus is %lx\n", + (unsigned long)sep->resident_bus); + dev_dbg(&sep->pdev->dev, "resident size is %08x\n", + sep->resident_size); + + /* set addresses for dcache (no loading needed) */ + work1 = (unsigned int)sep->resident_bus; + work2 = (unsigned int)sep->resident_size; + work3 = (work1 + work2 + (1024 * 4)) & 0xfffff000; + sep->dcache_bus = (dma_addr_t)work3; + + work1 = (unsigned int)sep->resident_addr; + work2 = (unsigned int)sep->resident_size; + work3 = (work1 + work2 + (1024 * 4)) & 0xfffff000; + sep->dcache_addr = (void *)work3; + + sep->dcache_size = 1024 * 128; + + /* set addresses and load cache */ + sep->cache_bus = sep->dcache_bus + sep->dcache_size; + sep->cache_addr = sep->dcache_addr + sep->dcache_size; + + error = request_firmware(&fw, cache_name, &sep->pdev->dev); + if (error) { + dev_warn(&sep->pdev->dev, "cant request cache fw\n"); + return error; + } + + memcpy(sep->cache_addr, (void *)fw->data, fw->size); + sep->cache_size = fw->size; + release_firmware(fw); + + dev_dbg(&sep->pdev->dev, "cache virtual is %p\n", + sep->cache_addr); + dev_dbg(&sep->pdev->dev, "cache bus is %08lx\n", + (unsigned long)sep->cache_bus); + dev_dbg(&sep->pdev->dev, "cache size is %08x\n", + sep->cache_size); + + /* set addresses and load extapp */ + sep->extapp_bus = sep->cache_bus + (1024 * 370); + sep->extapp_addr = sep->cache_addr + (1024 * 370); + + error = request_firmware(&fw, extapp_name, &sep->pdev->dev); + if (error) { + dev_warn(&sep->pdev->dev, "cant request extapp fw\n"); + return error; + } + + memcpy(sep->extapp_addr, (void *)fw->data, fw->size); + sep->extapp_size = fw->size; + release_firmware(fw); + + dev_dbg(&sep->pdev->dev, "extapp virtual is %p\n", + sep->extapp_addr); + dev_dbg(&sep->pdev->dev, "extapp bus is %08llx\n", + (unsigned long long)sep->extapp_bus); + dev_dbg(&sep->pdev->dev, "extapp size is %08x\n", + sep->extapp_size); + + return error; +} + +MODULE_FIRMWARE("sep/cache.image.bin"); +MODULE_FIRMWARE("sep/resident.image.bin"); +MODULE_FIRMWARE("sep/extapp.image.bin"); + +/** + * sep_dump_message - dump the message that is pending + * @sep: sep device + */ + +static void sep_dump_message(struct sep_device *sep) +{ + int count; + u32 *p = sep->shared_addr; + for (count = 0; count < 12 * 4; count += 4) + dev_dbg(&sep->pdev->dev, + "Word %d of the message is %x\n", + count, *p++); +} + +/** + * sep_map_and_alloc_shared_area - allocate shared block + * @sep: security processor + * @size: size of shared area + */ + +static int sep_map_and_alloc_shared_area(struct sep_device *sep) +{ + sep->shared_addr = dma_alloc_coherent(&sep->pdev->dev, + sep->shared_size, + &sep->shared_bus, GFP_KERNEL); + + if (!sep->shared_addr) { + dev_warn(&sep->pdev->dev, + "shared memory dma_alloc_coherent failed\n"); + return -ENOMEM; + } + dev_dbg(&sep->pdev->dev, + "sep: shared_addr %x bytes @%p (bus %llx)\n", + sep->shared_size, sep->shared_addr, + (unsigned long long)sep->shared_bus); + return 0; +} + +/** + * sep_unmap_and_free_shared_area - free shared block + * @sep: security processor + */ +static void sep_unmap_and_free_shared_area(struct sep_device *sep) +{ + dev_dbg(&sep->pdev->dev, "shared area unmap and free\n"); + dma_free_coherent(&sep->pdev->dev, sep->shared_size, + sep->shared_addr, sep->shared_bus); +} + +/** + * sep_shared_bus_to_virt - convert bus/virt addresses + * Returns virtual address inside the shared area according + * to the bus address. + * @sep: pointer to struct sep_device + * @bus_address: address to convert + */ + +static void *sep_shared_bus_to_virt(struct sep_device *sep, + dma_addr_t bus_address) +{ + return sep->shared_addr + (bus_address - sep->shared_bus); +} + +/** + * open function for the singleton driver + * @inode_ptr struct inode * + * @file_ptr struct file * + */ + +static int sep_singleton_open(struct inode *inode_ptr, struct file *file_ptr) +{ + int error = 0; + + struct sep_device *sep; + + /** + * get the sep device structure and use it for the + * private_data field in filp for other methods + */ + sep = sep_dev; + + file_ptr->private_data = sep; + + dev_dbg(&sep->pdev->dev, "Singleton open for pid %d\n", + current->pid); + + dev_dbg(&sep->pdev->dev, "calling test and set for singleton 0\n"); + if (test_and_set_bit(0, &sep->singleton_access_flag)) { + error = -EBUSY; + goto end_function; + } + + dev_dbg(&sep->pdev->dev, + "sep_singleton_open end\n"); +end_function: + + return error; +} + +/** + * sep_open - device open method + * @inode: inode of sep device + * @filp: file handle to sep device + * + * Open method for the SEP device. Called when userspace opens + * the SEP device node. Must also release the memory data pool + * allocations. + * + * Returns zero on success otherwise an error code. + */ + +static int sep_open(struct inode *inode, struct file *filp) +{ + struct sep_device *sep; + + /** + * get the sep device structure and use it for the + * private_data field in filp for other methods + */ + sep = sep_dev; + filp->private_data = sep; + + dev_dbg(&sep->pdev->dev, "Open for pid %d\n", current->pid); + + /* anyone can open; locking takes place at transaction level */ + return 0; +} + +/** + * sep_singleton_release - close a SEP singleton device + * @inode: inode of SEP device + * @filp: file handle being closed + * + * Called on the final close of a SEP device. As the open protects against + * multiple simultaenous opens that means this method is called when the + * final reference to the open handle is dropped. + */ + +static int sep_singleton_release(struct inode *inode, struct file *filp) +{ + struct sep_device *sep = filp->private_data; + + dev_dbg(&sep->pdev->dev, "Singleton release for pid %d\n", + current->pid); + + clear_bit(0, &sep->singleton_access_flag); + + return 0; +} + +/** + * sep_request_daemonopen - request daemon open method + * @inode: inode of sep device + * @filp: file handle to sep device + * + * Open method for the SEP request daemon. Called when + * request daemon in userspace opens + * the SEP device node. + * + * Returns zero on success otherwise an error code. + */ + +static int sep_request_daemon_open(struct inode *inode, struct file *filp) +{ + struct sep_device *sep; + + int error = 0; + + sep = sep_dev; + filp->private_data = sep; + + dev_dbg(&sep->pdev->dev, "Request daemon open for pid %d\n", + current->pid); + + /* There is supposed to be only one request daemon */ + dev_dbg(&sep->pdev->dev, "calling test and set for req_dmon open 0\n"); + if (test_and_set_bit(0, &sep->request_daemon_open)) { + error = -EBUSY; + goto end_function; + } + +end_function: + + return error; +} + +/** + * sep_request_daemon_release - close a SEP daemon + * @inode: inode of SEP device + * @filp: file handle being closed + * + * Called on the final close of a SEP daemon. + */ + +static int sep_request_daemon_release(struct inode *inode, struct file *filp) +{ + struct sep_device *sep = filp->private_data; + + dev_dbg(&sep->pdev->dev, "Reques daemon release for pid %d\n", + current->pid); + + /* clear the request_daemon_open flag */ + clear_bit(0, &sep->request_daemon_open); + + return 0; +} + +/** + * This function raises interrupt to SEPm that signals that is has a + * new command from HOST + * @sep: struct sep_device * + */ +static int sep_req_daemon_send_reply_command_handler(struct sep_device *sep) +{ + int error = 0; + + unsigned long lck_flags; + + dev_dbg(&sep->pdev->dev, + "sep_req_daemon_send_reply_command_handler start\n"); + + error = 0; + + sep_dump_message(sep); + + /* counters are lockable region */ + spin_lock_irqsave(&sep->snd_rply_lck, lck_flags); + sep->send_ct++; + sep->reply_ct++; + + /* send the interrupt to SEP */ + sep_write_reg(sep, HW_HOST_HOST_SEP_GPR2_REG_ADDR, + sep->send_ct); + + sep->send_ct++; + + spin_unlock_irqrestore(&sep->snd_rply_lck, lck_flags); + + dev_dbg(&sep->pdev->dev, + "sep_req_daemon_send_reply send_ct %lx reply_ct %lx\n", + sep->send_ct, sep->reply_ct); + + dev_dbg(&sep->pdev->dev, + "sep_req_daemon_send_reply_command_handler end\n"); + + return error; +} + + +/** + * sep_free_dma_table_data_handler - handles the request + * for freeing dma table for synhronic actions + * @sep: pointere to struct sep_device + */ + +static int sep_free_dma_table_data_handler(struct sep_device *sep) +{ + /* counter */ + int count = 0; + + /* dcb counter */ + int dcb_counter = 0; + + /* pointer to the current dma_resource struct */ + struct sep_dma_resource *dma; + + dev_dbg(&sep->pdev->dev, + "sep_free_dma_table_data_handler start\n"); + + + for (dcb_counter = 0; dcb_counter < sep->nr_dcb_creat; + dcb_counter++) { + + dma = &sep->dma_res_arr[dcb_counter]; + + /* unmap and free input map array */ + if (dma->in_map_array) { + + for (count = 0; count < dma->in_num_pages; + count++) { + + dma_unmap_page(&sep->pdev->dev, + dma->in_map_array[count].dma_addr, + dma->in_map_array[count].size, + DMA_TO_DEVICE); + } + + kfree(dma->in_map_array); + } + + /* unmap output map array, DON'T free it yet */ + if (dma->out_map_array) { + for (count = 0; count < dma->out_num_pages; + count++) { + + dma_unmap_page(&sep->pdev->dev, + dma->out_map_array[count].dma_addr, + dma->out_map_array[count].size, + DMA_FROM_DEVICE); + } + + kfree(dma->out_map_array); + } + + /* free page cache for output */ + if (dma->in_page_array) { + for (count = 0; count < dma->in_num_pages; + count++) { + + flush_dcache_page(dma->in_page_array[count]); + page_cache_release(dma->in_page_array[count]); + } + + kfree(dma->in_page_array); + + } + + if (dma->out_page_array) { + for (count = 0; count < dma->out_num_pages; + count++) { + + if (!PageReserved(dma->out_page_array[count])) + SetPageDirty(dma->out_page_array[count]); + + flush_dcache_page(dma->out_page_array[count]); + page_cache_release(dma->out_page_array[count]); + } + + kfree(dma->out_page_array); + } + + /* reset all the values */ + dma->in_page_array = 0; + dma->out_page_array = 0; + dma->in_num_pages = 0; + dma->out_num_pages = 0; + dma->in_map_array = 0; + dma->out_map_array = 0; + dma->in_map_num_entries = 0; + dma->out_map_num_entries = 0; + + } + + sep->nr_dcb_creat = 0; + sep->num_lli_tables_created = 0; + + dev_dbg(&sep->pdev->dev, + "sep_free_dma_table_data_handler end\n"); + + return 0; +} + + +/** + * sep_request_daemon_mmap - maps the + * shared area to user space + * @filp: pointer to struct file + * @vma: pointer to vm_area_struct + */ +static int sep_request_daemon_mmap(struct file *filp, + struct vm_area_struct *vma) +{ + /* device */ + struct sep_device *sep = filp->private_data; + + dma_addr_t bus_address; + + int error = 0; + + dev_dbg(&sep->pdev->dev, "daemon mmap start\n"); + + if ((vma->vm_end - vma->vm_start) > SEP_DRIVER_MMMAP_AREA_SIZE) { + error = -EINVAL; + goto end_function; + } + + /* get physical address */ + bus_address = sep->shared_bus; + + dev_dbg(&sep->pdev->dev, + "bus_address is %08lx\n", + (unsigned long)bus_address); + + if (remap_pfn_range(vma, vma->vm_start, bus_address >> PAGE_SHIFT, + vma->vm_end - vma->vm_start, vma->vm_page_prot)) { + + dev_warn(&sep->pdev->dev, + "remap_page_range failed\n"); + error = -EAGAIN; + goto end_function; + } + +end_function: + + dev_dbg(&sep->pdev->dev, "daemon mmap end\n"); + + return error; +} + +/** + * sep_request_daemon_poll - + * @sep: struct sep_device * for current sep device + * @filp: struct file * for open file + * @wait: poll_table * for poll + */ +static unsigned int sep_request_daemon_poll(struct file *filp, + poll_table *wait) +{ + u32 mask = 0; + + /* GPR2 register */ + u32 retval2; + + unsigned long lck_flags; + + struct sep_device *sep = filp->private_data; + + dev_dbg(&sep->pdev->dev, + "daemon poll: start\n"); + + dev_dbg(&sep->pdev->dev, "daemon poll: calling poll wait sep_event\n"); + + poll_wait(filp, &sep->event_request_daemon, wait); + + dev_dbg(&sep->pdev->dev, "daemon poll: exit poll wait sep_event\n"); + + dev_dbg(&sep->pdev->dev, + "daemon poll: send_ct is %lx reply ct is %lx\n", + sep->send_ct, sep->reply_ct); + + spin_lock_irqsave(&sep->snd_rply_lck, lck_flags); + /* check if the data is ready */ + if (sep->send_ct == sep->reply_ct) { + + spin_unlock_irqrestore(&sep->snd_rply_lck, lck_flags); + + retval2 = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR2_REG_ADDR); + + dev_dbg(&sep->pdev->dev, + "daemon poll: data check (GPR2) is %x\n", retval2); + + /* check if PRINT request */ + if ((retval2 >> 30) & 0x1) { + + dev_dbg(&sep->pdev->dev, + "daemon poll: PRINTF request in\n"); + mask |= POLLIN; + goto end_function; + } + + /* check if NVS request */ + if (retval2 >> 31) { + + dev_dbg(&sep->pdev->dev, + "daemon poll: NVS request in\n"); + mask |= POLLPRI | POLLWRNORM; + } + } + + else { + + spin_unlock_irqrestore(&sep->snd_rply_lck, lck_flags); + + dev_dbg(&sep->pdev->dev, + "daemon poll: no reply received; returning 0\n"); + mask = 0; + } + +end_function: + + dev_dbg(&sep->pdev->dev, + "daemon poll: exit\n"); + return mask; +} + +/** + * sep_release - close a SEP device + * @inode: inode of SEP device + * @filp: file handle being closed + * + * Called on the final close of a SEP device. + */ + +static int sep_release(struct inode *inode, struct file *filp) +{ + struct sep_device *sep = filp->private_data; + + dev_dbg(&sep->pdev->dev, "Release for pid %d\n", current->pid); + + mutex_lock(&sep->sep_mutex); + /* is this the process that has a transaction open? + * If so, lets reset pid_doing_transaction to 0 and + * clear the in use flags, and then wake up sep_event + * so that other processes can do transactions + */ + dev_dbg(&sep->pdev->dev, "waking up event and mmap_event\n"); + if (sep->pid_doing_transaction == current->pid) { + clear_bit(SEP_MMAP_LOCK_BIT, &sep->in_use_flags); + clear_bit(SEP_SEND_MSG_LOCK_BIT, &sep->in_use_flags); + sep_free_dma_table_data_handler(sep); + wake_up(&sep->event); + sep->pid_doing_transaction = 0; + } + + mutex_unlock(&sep->sep_mutex); + return 0; +} + +/** + * sep_mmap - maps the shared area to user space + * @filp: pointer to struct file + * @vma: pointer to vm_area_struct + */ +static int sep_mmap(struct file *filp, struct vm_area_struct *vma) +{ + dma_addr_t bus_addr; + struct sep_device *sep = filp->private_data; + unsigned long error = 0; + + dev_dbg(&sep->pdev->dev, "mmap start\n"); + + + dev_dbg(&sep->pdev->dev, "calling wait on event_mmap, tsetbit" + " SEP_MMAP_LOCK_BIT in_use_flags 0\n"); + /* Set the transaction busy (own the device) */ + wait_event_interruptible(sep->event, + test_and_set_bit(SEP_MMAP_LOCK_BIT, + &sep->in_use_flags) == 0); + + if (signal_pending(current)) { + error = -EINTR; + goto end_function_with_error; + } + /* + * The pid_doing_transaction indicates that this process + * now owns the facilities to performa a transaction with + * the sep. While this process is performing a transaction, + * no other process who has the sep device open can perform + * any transactions. This method allows more than one process + * to have the device open at any given time, which provides + * finer granularity for device utilization by multiple + * processes. + */ + mutex_lock(&sep->sep_mutex); + sep->pid_doing_transaction = current->pid; + mutex_unlock(&sep->sep_mutex); + + /* zero the pools and the number of data pool alocation pointers */ + sep->data_pool_bytes_allocated = 0; + sep->num_of_data_allocations = 0; + + /* + * check that the size of the mapped range is as the size of the message + * shared area + */ + if ((vma->vm_end - vma->vm_start) > SEP_DRIVER_MMMAP_AREA_SIZE) { + error = -EINVAL; + goto end_function_with_error; + } + + dev_dbg(&sep->pdev->dev, + "shared_addr is %p\n", sep->shared_addr); + + /* get bus address */ + bus_addr = sep->shared_bus; + + dev_dbg(&sep->pdev->dev, + "bus_address is %lx\n", (unsigned long)bus_addr); + + if (remap_pfn_range(vma, vma->vm_start, bus_addr >> PAGE_SHIFT, + vma->vm_end - vma->vm_start, vma->vm_page_prot)) { + dev_warn(&sep->pdev->dev, + "remap_page_range failed\n"); + error = -EAGAIN; + goto end_function_with_error; + } + + dev_dbg(&sep->pdev->dev, "mmap end\n"); + goto end_function; + +end_function_with_error: + + /* clear the bit */ + clear_bit(SEP_MMAP_LOCK_BIT, &sep->in_use_flags); + mutex_lock(&sep->sep_mutex); + sep->pid_doing_transaction = 0; + mutex_unlock(&sep->sep_mutex); + + /* raise event for stuck contextes */ + + dev_warn(&sep->pdev->dev, "mmap error - waking up event\n"); + wake_up(&sep->event); + +end_function: + + return error; +} + +/** + * sep_poll - + * @filp: pointer to struct file + * @wait: pointer to poll_table + */ +static unsigned int sep_poll(struct file *filp, poll_table *wait) +{ + u32 mask = 0; + u32 retval = 0; + u32 retval2 = 0; + + unsigned long lck_flags; + + struct sep_device *sep = filp->private_data; + + dev_dbg(&sep->pdev->dev, "poll: start\n"); + + /* am I the process that own the transaction? */ + mutex_lock(&sep->sep_mutex); + if (current->pid != sep->pid_doing_transaction) { + dev_warn(&sep->pdev->dev, "poll; wrong pid\n"); + mask = POLLERR; + mutex_unlock(&sep->sep_mutex); + goto end_function; + } + + mutex_unlock(&sep->sep_mutex); + + /* check if send command or send_reply were activated previously */ + if (!test_bit(SEP_SEND_MSG_LOCK_BIT, &sep->in_use_flags)) { + dev_warn(&sep->pdev->dev, "poll; lock bit set\n"); + mask = POLLERR; + goto end_function; + } + + /* add the event to the polling wait table */ + dev_dbg(&sep->pdev->dev, "poll: calling wait sep_event\n"); + + poll_wait(filp, &sep->event, wait); + + dev_dbg(&sep->pdev->dev, "poll: exit wait sep_event\n"); + + dev_dbg(&sep->pdev->dev, "poll: send_ct is %lx reply ct is %lx\n", + sep->send_ct, sep->reply_ct); + + /* check if error occured during poll */ + retval2 = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR3_REG_ADDR); + + if (retval2 != 0x0) { + + dev_warn(&sep->pdev->dev, "poll; poll error %x\n", + retval2); + mask |= POLLERR; + goto end_function; + } + + spin_lock_irqsave(&sep->snd_rply_lck, lck_flags); + + if (sep->send_ct == sep->reply_ct) { + + spin_unlock_irqrestore(&sep->snd_rply_lck, lck_flags); + retval = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR2_REG_ADDR); + dev_dbg(&sep->pdev->dev, "poll: data ready check (GPR2) %x\n", + retval); + + /* check if printf request */ + if ((retval >> 30) & 0x1) { + + dev_dbg(&sep->pdev->dev, "poll: sep printf request\n"); + wake_up(&sep->event_request_daemon); + goto end_function; + + } + + /* check if the this is sep reply or request */ + if (retval >> 31) { + + dev_dbg(&sep->pdev->dev, "poll: sep request\n"); + wake_up(&sep->event_request_daemon); + + } else { + + dev_dbg(&sep->pdev->dev, "poll: normal return\n"); + + /* in case it is again by send_reply_comand */ + + clear_bit(SEP_SEND_MSG_LOCK_BIT, &sep->in_use_flags); + + sep_dump_message(sep); + + dev_dbg(&sep->pdev->dev, + "poll; sep reply POLLIN | POLLRDNORM\n"); + + mask |= POLLIN | POLLRDNORM; + } + + } else { + + spin_unlock_irqrestore(&sep->snd_rply_lck, lck_flags); + + dev_dbg(&sep->pdev->dev, + "poll; no reply received; returning mask of 0\n"); + mask = 0; + } + +end_function: + + dev_dbg(&sep->pdev->dev, "poll: end\n"); + return mask; +} + +/** + * sep_time_address - address in SEP memory of time + * @sep: SEP device we want the address from + * + * Return the address of the two dwords in memory used for time + * setting. + */ + +static u32 *sep_time_address(struct sep_device *sep) +{ + return sep->shared_addr + SEP_DRIVER_SYSTEM_TIME_MEMORY_OFFSET_IN_BYTES; +} + +/** + * sep_set_time - set the SEP time + * @sep: the SEP we are setting the time for + * + * Calculates time and sets it at the predefined address. + * Called with the sep mutex held. + */ +static unsigned long sep_set_time(struct sep_device *sep) +{ + struct timeval time; + u32 *time_addr; /* address of time as seen by the kernel */ + + + dev_dbg(&sep->pdev->dev, + "sep:sep_set_time start\n"); + + do_gettimeofday(&time); + + /* set value in the SYSTEM MEMORY offset */ + time_addr = sep_time_address(sep); + + time_addr[0] = SEP_TIME_VAL_TOKEN; + time_addr[1] = time.tv_sec; + + dev_dbg(&sep->pdev->dev, + "time.tv_sec is %lu\n", time.tv_sec); + dev_dbg(&sep->pdev->dev, + "time_addr is %p\n", time_addr); + dev_dbg(&sep->pdev->dev, + "sep->shared_addr is %p\n", sep->shared_addr); + + return time.tv_sec; +} + +/** + * sep_init_caller_id - initializes the caller id functionality + * @sep: pointer to struct sep_device + */ +static int sep_init_caller_id(struct sep_device *sep) +{ + /* return value */ + int ret_val; + + /* counter */ + int counter; + + struct cb_id caller_id; + + dev_dbg(&sep->pdev->dev, + "sep_init_caller_id start\n"); + + ret_val = 0; + + /* init cb_id struct */ + caller_id.idx = CN_IDX_PROC; + caller_id.val = CN_VAL_PROC; + + /** + * init caller id table + * note that locking is not needed here as this function is + * called prior to registering the device file + */ + for (counter = 0; counter < SEP_CALLER_ID_TABLE_NUM_ENTRIES; counter++) + sep->caller_id_table[counter].pid = 0; + + + /* init access flag */ + sep->singleton_access_flag = 0; + + dev_dbg(&sep->pdev->dev, + "caller id table init finished\n"); + + /* register to netlink connector */ + + if (ret_val) + dev_warn(&sep->pdev->dev, + "cn_add_callback failed %x\n", ret_val); + + dev_dbg(&sep->pdev->dev, + "sep_init_caller_id end\n"); + + return ret_val; +} + +/** + * sep_set_caller_id_handler - inserts the data into the caller id table + * note that this function does fall under the ioctl lock + * @sep: sep device + * @arg: pointer to struct caller_id_struct + */ +static int sep_set_caller_id_handler(struct sep_device *sep, u32 arg) +{ + void __user *hash; + int error; + int i; + struct caller_id_struct command_args; + + dev_dbg(&sep->pdev->dev, + "sep_set_caller_id_handler start\n"); + + error = 0; + + for (i = 0; i < SEP_CALLER_ID_TABLE_NUM_ENTRIES; i++) { + if (sep->caller_id_table[i].pid == 0) + break; + } + + if (i == SEP_CALLER_ID_TABLE_NUM_ENTRIES) { + dev_warn(&sep->pdev->dev, + "no more caller id entries left\n"); + dev_warn(&sep->pdev->dev, + "maximum number is %d\n", + SEP_CALLER_ID_TABLE_NUM_ENTRIES); + + error = -EUSERS; + goto end_function; + } + + /* copy the data */ + if (copy_from_user(&command_args, (void __user *)arg, + sizeof(command_args))) { + error = -EFAULT; + goto end_function; + } + + hash = (void __user *)(unsigned long)command_args.callerIdAddress; + + if (!command_args.pid || !command_args.callerIdSizeInBytes) { + error = -EINVAL; + goto end_function; + } + + dev_dbg(&sep->pdev->dev, "pid is %x\n", command_args.pid); + dev_dbg(&sep->pdev->dev, "callerIdSizeInBytes is %x\n", + command_args.callerIdSizeInBytes); + + if (command_args.callerIdSizeInBytes > + SEP_CALLER_ID_HASH_SIZE_IN_BYTES) { + error = -EMSGSIZE; + goto end_function; + } + + sep->caller_id_table[i].pid = command_args.pid; + + if (copy_from_user(sep->caller_id_table[i].callerIdHash, + hash, command_args.callerIdSizeInBytes)) + error = -EFAULT; +end_function: + dev_dbg(&sep->pdev->dev, + "sep_set_caller_id_handler end\n"); + return error; +} + +/** + * sep_set_current_caller_id - set the caller id (if exists) to the sep + * note that this function does fall under the ioctl lock + * @sep: pointer to struct_sep + */ +static int sep_set_current_caller_id(struct sep_device *sep) +{ + int i; + + dev_dbg(&sep->pdev->dev, "sep_set_current_caller_id start\n"); + + dev_dbg(&sep->pdev->dev, "current process is %d\n", current->pid); + + /* zero the previous value */ + memset((void *)(sep->shared_addr + + (SEP_CALLER_ID_OFFSET_BYTES)), + 0, + SEP_CALLER_ID_HASH_SIZE_IN_BYTES); + + for (i = 0; i < SEP_CALLER_ID_TABLE_NUM_ENTRIES; i++) { + if (sep->caller_id_table[i].pid == current->pid) { + dev_dbg(&sep->pdev->dev, "Caller Id found\n"); + + memcpy((void *)(sep->shared_addr + + (SEP_CALLER_ID_OFFSET_BYTES)), + (void *)(sep->caller_id_table[i].callerIdHash), + SEP_CALLER_ID_HASH_SIZE_IN_BYTES); + break; + } + } + + dev_dbg(&sep->pdev->dev, "sep_set_current_caller_id end\n"); + + return 0; +} + +/** + * sep_send_command_handler - kick off a command + * note that this function does fall under the ioctl lock + * This function raises interrupt to SEP that signals that is has a new + * command from the host + * @sep: sep being signalled + */ + +static int sep_send_command_handler(struct sep_device *sep) +{ + unsigned long lck_flags; + int error = 0; + + dev_dbg(&sep->pdev->dev, "sep_send_command_handler start\n"); + + dev_dbg(&sep->pdev->dev, "calling test and set for " + " in_use_flags SEP_SEND_MSG_LOCK_BIT 0\n"); + if (test_and_set_bit(SEP_SEND_MSG_LOCK_BIT, &sep->in_use_flags)) { + error = -EPROTO; + goto end_function; + } + + sep_set_time(sep); + + /* only Medfield has caller id */ + if (sep->mrst == 0) + sep_set_current_caller_id(sep); + + sep_dump_message(sep); + + /* update counter */ + spin_lock_irqsave(&sep->snd_rply_lck, lck_flags); + sep->send_ct++; + spin_unlock_irqrestore(&sep->snd_rply_lck, lck_flags); + + dev_dbg(&sep->pdev->dev, "sep_send_command_handler" + "send_ct %lx reply_ct %lx\n", sep->send_ct, sep->reply_ct); + + /* send interrupt to SEP */ + sep_write_reg(sep, HW_HOST_HOST_SEP_GPR0_REG_ADDR, 0x2); + +end_function: + dev_dbg(&sep->pdev->dev, "sep_send_command_handler end\n"); + return error; +} + +/** + * sep_allocate_data_pool_memory_handler - + * This function handles the allocate data pool memory request + * This function returns calculates the bus address of the + * allocated memory, and the offset of this area from the mapped address. + * Therefore, the FVOs in user space can calculate the exact virtual + * address of this allocated memory + * @sep: pointer to struct_sep + * @arg: pointer to struct alloc_struct + */ +static int sep_allocate_data_pool_memory_handler(struct sep_device *sep, + unsigned long arg) +{ + int error = 0; + struct alloc_struct command_args; + + /* holds the allocated buffer address in the system memory pool */ + u32 *token_addr; + + dev_dbg(&sep->pdev->dev, + "sep_allocate_data_pool_memory_handler start\n"); + + if (copy_from_user(&command_args, (void __user *)arg, + sizeof(struct alloc_struct))) { + error = -EFAULT; + goto end_function; + } + + /* allocate memory */ + if ((sep->data_pool_bytes_allocated + command_args.num_bytes) > + SEP_DRIVER_DATA_POOL_SHARED_AREA_SIZE_IN_BYTES) { + error = -ENOMEM; + goto end_function; + } + + dev_dbg(&sep->pdev->dev, + "bytes_allocated: %x\n", (int)sep->data_pool_bytes_allocated); + dev_dbg(&sep->pdev->dev, + "offset: %x\n", SEP_DRIVER_DATA_POOL_AREA_OFFSET_IN_BYTES); + /* set the virtual and bus address */ + command_args.offset = SEP_DRIVER_DATA_POOL_AREA_OFFSET_IN_BYTES + + sep->data_pool_bytes_allocated; + + dev_dbg(&sep->pdev->dev, + "command_args.offset: %x\n", command_args.offset); + + /* place in the shared area that is known by the sep */ + token_addr = (u32 *)(sep->shared_addr + + SEP_DRIVER_DATA_POOL_ALLOCATION_OFFSET_IN_BYTES + + (sep->num_of_data_allocations)*2*sizeof(u32)); + + dev_dbg(&sep->pdev->dev, + "allocation offset: %x\n", + SEP_DRIVER_DATA_POOL_ALLOCATION_OFFSET_IN_BYTES); + dev_dbg(&sep->pdev->dev, "data pool token addr is %p\n", token_addr); + + token_addr[0] = SEP_DATA_POOL_POINTERS_VAL_TOKEN; + token_addr[1] = (u32)sep->shared_bus + + SEP_DRIVER_DATA_POOL_AREA_OFFSET_IN_BYTES + + sep->data_pool_bytes_allocated; + + dev_dbg(&sep->pdev->dev, "data pool token [0] %x\n", token_addr[0]); + dev_dbg(&sep->pdev->dev, "data pool token [1] %x\n", token_addr[1]); + + /* write the memory back to the user space */ + error = copy_to_user((void *)arg, (void *)&command_args, + sizeof(struct alloc_struct)); + if (error) { + + dev_warn(&sep->pdev->dev, + "allocate data pool copy to user error\n"); + goto end_function; + } + + /* update the allocation */ + sep->data_pool_bytes_allocated += command_args.num_bytes; + sep->num_of_data_allocations += 1; + + dev_dbg(&sep->pdev->dev, "data_allocations %d\n", + sep->num_of_data_allocations); + dev_dbg(&sep->pdev->dev, "bytes allocated %d\n", + (int)sep->data_pool_bytes_allocated); + +end_function: + + dev_dbg(&sep->pdev->dev, + "sep_allocate_data_pool_memory_handler end\n"); + return error; +} + +/** + * sep_lock_kernel_pages - + * This function locks all the physical pages of the kernel virtual buffer + * and construct a basic lli array, where each entry holds the physical + * page address and the size that application data holds in this page + * This function is used only during kernel crypto mod calls from within + * the kernel (when ioctl is not used) + * @sep: pointer to struct sep_device + * @kernel_virt_addr: address of data buffer in kernel + * @data_size: size of data + * @lli_array_ptr: lli array + * @in_out_flag: input into device or output from device + */ +static int sep_lock_kernel_pages(struct sep_device *sep, + u32 kernel_virt_addr, + u32 data_size, + struct sep_lli_entry **lli_array_ptr, + int in_out_flag) + +{ + /* error */ + int error = 0; + + /* array of lli */ + struct sep_lli_entry *lli_array; + + /* map array */ + struct sep_dma_map *map_array; + + dev_dbg(&sep->pdev->dev, + "sep_lock_kernel_pages start\n"); + + dev_dbg(&sep->pdev->dev, + "kernel_virt_addr is %08x\n", kernel_virt_addr); + dev_dbg(&sep->pdev->dev, + "data_size is %x\n", data_size); + + lli_array = kmalloc(sizeof(struct sep_lli_entry), GFP_ATOMIC); + if (!lli_array) { + + error = -ENOMEM; + goto end_function; + } + + map_array = kmalloc(sizeof(struct sep_dma_map), GFP_ATOMIC); + if (!map_array) { + error = -ENOMEM; + goto end_function_with_error; + } + + map_array[0].dma_addr = + dma_map_single(&sep->pdev->dev, (void *)kernel_virt_addr, + data_size, DMA_BIDIRECTIONAL); + map_array[0].size = data_size; + + + /* + * set the start address of the first page - app data may start not at + * the beginning of the page + */ + lli_array[0].bus_address = (u32)map_array[0].dma_addr; + lli_array[0].block_size = map_array[0].size; + + dev_dbg(&sep->pdev->dev, + "lli_array[0].bus_address is %08lx," + " lli_array[0].block_size is %x\n", + (unsigned long)lli_array[0].bus_address, + lli_array[0].block_size); + + /* set the output parameters */ + if (in_out_flag == SEP_DRIVER_IN_FLAG) { + *lli_array_ptr = lli_array; + sep->dma_res_arr[sep->nr_dcb_creat].in_num_pages = 1; + sep->dma_res_arr[sep->nr_dcb_creat].in_page_array = 0; + sep->dma_res_arr[sep->nr_dcb_creat].in_map_array = map_array; + sep->dma_res_arr[sep->nr_dcb_creat].in_map_num_entries = 1; + } else { + *lli_array_ptr = lli_array; + sep->dma_res_arr[sep->nr_dcb_creat].out_num_pages = 1; + sep->dma_res_arr[sep->nr_dcb_creat].out_page_array = 0; + sep->dma_res_arr[sep->nr_dcb_creat].out_map_array = map_array; + sep->dma_res_arr[sep->nr_dcb_creat].out_map_num_entries = 1; + } + + goto end_function; + +end_function_with_error: + + kfree(lli_array); + +end_function: + + dev_dbg(&sep->pdev->dev, + "sep_lock_kernel_pages end\n"); + + return error; +} + +/** + * sep_lock_user_pages - + * This function locks all the physical pages of the application + * virtual buffer and construct a basic lli array, where each entry + * holds the physical page address and the size that application + * data holds in this physical pages + * @sep: pointer to struct sep_device + * @app_virt_addr: user memory data buffer + * @data_size: size of data buffer + * @lli_array_ptr: lli array + * @in_out_flag: input or output to device + */ +static int sep_lock_user_pages(struct sep_device *sep, + u32 app_virt_addr, + u32 data_size, + struct sep_lli_entry **lli_array_ptr, + int in_out_flag) + +{ + /* error */ + int error; + + /* the the page of the end address of the user space buffer */ + u32 end_page; + + /* the page of the start address of the user space buffer */ + u32 start_page; + + /* the range in pages */ + u32 num_pages; + + /* array of pointers ot page */ + struct page **page_array; + + /* array of lli */ + struct sep_lli_entry *lli_array; + + /* map array */ + struct sep_dma_map *map_array; + + /* direction of the DMA mapping for locked pages */ + enum dma_data_direction dir; + + /* count */ + u32 count; + + /* result */ + int result; + + dev_dbg(&sep->pdev->dev, + "sep_lock_user_pages start\n"); + + error = 0; + + /* set start and end pages and num pages */ + end_page = (app_virt_addr + data_size - 1) >> PAGE_SHIFT; + start_page = app_virt_addr >> PAGE_SHIFT; + num_pages = end_page - start_page + 1; + + dev_dbg(&sep->pdev->dev, + "app_virt_addr is %x\n", app_virt_addr); + dev_dbg(&sep->pdev->dev, + "data_size is %x\n", data_size); + dev_dbg(&sep->pdev->dev, + "start_page is %x\n", start_page); + dev_dbg(&sep->pdev->dev, + "end_page is %x\n", end_page); + dev_dbg(&sep->pdev->dev, + "num_pages is %x\n", num_pages); + + dev_dbg(&sep->pdev->dev, + "starting page_array malloc\n"); + + /* allocate array of pages structure pointers */ + page_array = kmalloc(sizeof(struct page *) * num_pages, GFP_ATOMIC); + if (!page_array) { + error = -ENOMEM; + goto end_function; + } + + map_array = kmalloc(sizeof(struct sep_dma_map) * num_pages, GFP_ATOMIC); + if (!map_array) { + dev_warn(&sep->pdev->dev, + "kmalloc for map_array failed\n"); + error = -ENOMEM; + goto end_function_with_error1; + } + + lli_array = kmalloc(sizeof(struct sep_lli_entry) * num_pages, + GFP_ATOMIC); + + if (!lli_array) { + + dev_warn(&sep->pdev->dev, + "kmalloc for lli_array failed\n"); + error = -ENOMEM; + goto end_function_with_error2; + } + + dev_dbg(&sep->pdev->dev, + "starting get_user_pages\n"); + + /* convert the application virtual address into a set of physical */ + down_read(¤t->mm->mmap_sem); + result = get_user_pages(current, current->mm, app_virt_addr, + num_pages, + ((in_out_flag == SEP_DRIVER_IN_FLAG) ? 0 : 1), + 0, page_array, 0); + + up_read(¤t->mm->mmap_sem); + + /* check the number of pages locked - if not all then exit with error */ + if (result != num_pages) { + + dev_warn(&sep->pdev->dev, + "not all pages locked by get_user_pages\n"); + error = -ENOMEM; + goto end_function_with_error3; + } + + dev_dbg(&sep->pdev->dev, + "get_user_pages succeeded\n"); + + /* set direction */ + if (in_out_flag == SEP_DRIVER_IN_FLAG) + dir = DMA_TO_DEVICE; + else + dir = DMA_FROM_DEVICE; + + /* + * fill the array using page array data and + * map the pages - this action + * will also flush the cache as needed + */ + for (count = 0; count < num_pages; count++) { + /* fill the map array */ + map_array[count].dma_addr = + dma_map_page(&sep->pdev->dev, page_array[count], + 0, PAGE_SIZE, /*dir*/DMA_BIDIRECTIONAL); + + map_array[count].size = PAGE_SIZE; + + /* fill the lli array entry */ + lli_array[count].bus_address = (u32)map_array[count].dma_addr; + lli_array[count].block_size = PAGE_SIZE; + + dev_warn(&sep->pdev->dev, + "lli_array[%x].bus_address is %08lx, \ + lli_array[%x].block_size is %x\n", + count, (unsigned long)lli_array[count].bus_address, + count, lli_array[count].block_size); + } + + /* check the offset for the first page */ + lli_array[0].bus_address = + lli_array[0].bus_address + (app_virt_addr & (~PAGE_MASK)); + + /* check that not all the data is in the first page only */ + if ((PAGE_SIZE - (app_virt_addr & (~PAGE_MASK))) >= data_size) + lli_array[0].block_size = data_size; + else + lli_array[0].block_size = + PAGE_SIZE - (app_virt_addr & (~PAGE_MASK)); + + dev_dbg(&sep->pdev->dev, + "lli_array[0].bus_address is %08lx, \ + lli_array[0].block_size is %x\n", + (unsigned long)lli_array[count].bus_address, + lli_array[count].block_size); + + /* check the size of the last page */ + if (num_pages > 1) { + + lli_array[num_pages - 1].block_size = + (app_virt_addr + data_size) & (~PAGE_MASK); + + dev_warn(&sep->pdev->dev, + "lli_array[%x].bus_address is %08lx, \ + lli_array[%x].block_size is %x\n", + num_pages - 1, + (unsigned long)lli_array[count].bus_address, + num_pages - 1, + lli_array[count].block_size); + } + + /* set output params acording to the in_out flag */ + if (in_out_flag == SEP_DRIVER_IN_FLAG) { + *lli_array_ptr = lli_array; + sep->dma_res_arr[sep->nr_dcb_creat].in_num_pages = + num_pages; + sep->dma_res_arr[sep->nr_dcb_creat].in_page_array = + page_array; + sep->dma_res_arr[sep->nr_dcb_creat].in_map_array = + map_array; + sep->dma_res_arr[sep->nr_dcb_creat].in_map_num_entries = + num_pages; + } else { + *lli_array_ptr = lli_array; + sep->dma_res_arr[sep->nr_dcb_creat].out_num_pages = + num_pages; + sep->dma_res_arr[sep->nr_dcb_creat].out_page_array = + page_array; + sep->dma_res_arr[sep->nr_dcb_creat].out_map_array = + map_array; + sep->dma_res_arr[sep->nr_dcb_creat].out_map_num_entries = + num_pages; + } + + goto end_function; + +end_function_with_error3: + + /* free lli array */ + kfree(lli_array); + +end_function_with_error2: + + kfree(map_array); + +end_function_with_error1: + + /* free page array */ + kfree(page_array); + +end_function: + + dev_dbg(&sep->pdev->dev, + "sep_lock_user_pages end\n"); + + return error; +} + +/** + * u32 sep_calculate_lli_table_max_size - + * this function calculates the size of data + * that can be inserted into the lli + * table from this array the condition is that + * either the table is full + * (all etnries are entered), or there are no more + * entries in the lli array + * @sep: pointer to struct sep_device + * @lli_in_array_ptr + * @num_array_entries + * @last_table_flag + */ +static u32 sep_calculate_lli_table_max_size(struct sep_device *sep, + struct sep_lli_entry *lli_in_array_ptr, + u32 num_array_entries, + u32 *last_table_flag) +{ + /* table data size */ + u32 table_data_size; + + /* data size for the next table */ + u32 next_table_data_size; + + /* counter */ + u32 counter; + + table_data_size = 0; + *last_table_flag = 0; + + /* + * calculate the data in the out lli table till we fill the whole + * table or till the data has ended + */ + for (counter = 0; + (counter < (SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP - 1)) && + (counter < num_array_entries); counter++) + table_data_size += lli_in_array_ptr[counter].block_size; + + /* + * check if we reached the last entry, + * meaning this ia the last table to build, + * and no need to check the block alignment + */ + if (counter == num_array_entries) { + + /* set the last table flag */ + *last_table_flag = 1; + goto end_function; + } + + /* + * calculate the data size of the next table. + * Stop if no entries left or + * if data size is more the DMA restriction + */ + next_table_data_size = 0; + for (; counter < num_array_entries; counter++) { + + next_table_data_size += lli_in_array_ptr[counter].block_size; + + if (next_table_data_size >= SEP_DRIVER_MIN_DATA_SIZE_PER_TABLE) + + break; + } + + /* + * check if the next table data size is less then DMA rstriction. + * if it is - recalculate the current table size, so that the next + * table data size will be adaquete for DMA + */ + if (next_table_data_size && + next_table_data_size < SEP_DRIVER_MIN_DATA_SIZE_PER_TABLE) + + table_data_size -= (SEP_DRIVER_MIN_DATA_SIZE_PER_TABLE - + next_table_data_size); + + dev_dbg(&sep->pdev->dev, + "table data size is %x\n", table_data_size); + +end_function: + + return table_data_size; +} + +/** + * sep_build_lli_table - + * this functions builds ont lli table from the lli_array according to + * the given size of data + * @sep: pointer to struct sep_device + * @lli_array_ptr: pointer to lli array + * @lli_table_ptr: pointer to lli table + * @num_processed_entries_ptr: pointer to number of entries + * @num_table_entries_ptr: pointer to number of tables + * @table_data_size: total data size + */ +static void sep_build_lli_table(struct sep_device *sep, + struct sep_lli_entry *lli_array_ptr, + struct sep_lli_entry *lli_table_ptr, + u32 *num_processed_entries_ptr, + u32 *num_table_entries_ptr, + u32 table_data_size) +{ + /* current table data size */ + u32 curr_table_data_size; + + /* counter of lli array entry */ + u32 array_counter; + + dev_dbg(&sep->pdev->dev, + "sep_build_lli_table start\n"); + + /* init currrent table data size and lli array entry counter */ + curr_table_data_size = 0; + array_counter = 0; + *num_table_entries_ptr = 1; + + dev_dbg(&sep->pdev->dev, + "table_data_size is %x\n", table_data_size); + + /* fill the table till table size reaches the needed amount */ + while (curr_table_data_size < table_data_size) { + /* update the number of entries in table */ + (*num_table_entries_ptr)++; + + lli_table_ptr->bus_address = + cpu_to_le32(lli_array_ptr[array_counter].bus_address); + + lli_table_ptr->block_size = + cpu_to_le32(lli_array_ptr[array_counter].block_size); + + curr_table_data_size += lli_array_ptr[array_counter].block_size; + + dev_dbg(&sep->pdev->dev, + "lli_table_ptr is %p\n", lli_table_ptr); + dev_dbg(&sep->pdev->dev, + "lli_table_ptr->bus_address is %08lx\n", + (unsigned long)lli_table_ptr->bus_address); + dev_dbg(&sep->pdev->dev, + "lli_table_ptr->block_size is %x\n", + lli_table_ptr->block_size); + + /* check for overflow of the table data */ + if (curr_table_data_size > table_data_size) { + + dev_dbg(&sep->pdev->dev, + "curr_table_data_size too large\n"); + + /* update the size of block in the table */ + lli_table_ptr->block_size -= + cpu_to_le32((curr_table_data_size - table_data_size)); + + /* update the physical address in the lli array */ + lli_array_ptr[array_counter].bus_address += + cpu_to_le32(lli_table_ptr->block_size); + + /* update the block size left in the lli array */ + lli_array_ptr[array_counter].block_size = + (curr_table_data_size - table_data_size); + + } else + + /* advance to the next entry in the lli_array */ + array_counter++; + + dev_dbg(&sep->pdev->dev, + "lli_table_ptr->bus_address is %08lx\n", + (unsigned long)lli_table_ptr->bus_address); + dev_dbg(&sep->pdev->dev, + "lli_table_ptr->block_size is %x\n", + lli_table_ptr->block_size); + + /* move to the next entry in table */ + lli_table_ptr++; + } + + /* set the info entry to default */ + lli_table_ptr->bus_address = 0xffffffff; + lli_table_ptr->block_size = 0; + + dev_dbg(&sep->pdev->dev, + "lli_table_ptr is %p\n", lli_table_ptr); + dev_dbg(&sep->pdev->dev, + "lli_table_ptr->bus_address is %08lx\n", + (unsigned long)lli_table_ptr->bus_address); + dev_dbg(&sep->pdev->dev, + "lli_table_ptr->block_size is %x\n", + lli_table_ptr->block_size); + + /* set the output parameter */ + *num_processed_entries_ptr += array_counter; + + dev_dbg(&sep->pdev->dev, + "num_processed_entries_ptr is %x\n", + *num_processed_entries_ptr); + + dev_dbg(&sep->pdev->dev, + "sep_build_lli_table end\n"); + + return; +} + +/** + * sep_shared_area_virt_to_bus - + * This functions returns the physical address inside shared area according + * to the virtual address. It can be either on the externa RAM device + * (ioremapped), or on the system RAM + * This implementation is for the external RAM + * @sep: pointer to struct sep_device + * @virt_address: virtual address to convert + */ +static dma_addr_t sep_shared_area_virt_to_bus(struct sep_device *sep, + void *virt_address) +{ + dev_dbg(&sep->pdev->dev, + "sh virt to phys v %08lx\n", + (unsigned long)virt_address); + dev_dbg(&sep->pdev->dev, + "sh virt to phys p %08lx\n", + (unsigned long)(sep->shared_bus + + (virt_address - sep->shared_addr))); + + return sep->shared_bus + + (size_t)(virt_address - sep->shared_addr); +} + +/** + * sep_shared_area_bus_to_virt - + * This functions returns the virtual address inside shared area + * according to the physical address. It can be either on the + * externa RAM device (ioremapped), or on the system RAM + * This implementation is for the external RAM + * @sep: pointer to struct sep_device + * @bus_address: bus address to convert + */ + +static void *sep_shared_area_bus_to_virt(struct sep_device *sep, + dma_addr_t bus_address) +{ + dev_dbg(&sep->pdev->dev, + "shared bus to virt b=%x v=%x\n", + (u32)bus_address, + (u32)(sep->shared_addr + + (size_t)(bus_address - sep->shared_bus))); + + return sep->shared_addr + + (size_t)(bus_address - sep->shared_bus); +} + +/** + * sep_debug_print_lli_tables - + * this function goes over the list of the print created tables and + * prints all the data + * @sep: pointer to struct sep_device + * @lli_table_ptr: pointer to sep_lli_entry + * @num_table_entries: number of entries + * @table_data_size: total data size + */ +static void sep_debug_print_lli_tables(struct sep_device *sep, + struct sep_lli_entry *lli_table_ptr, + unsigned long num_table_entries, + unsigned long table_data_size) +{ + unsigned long table_count = 0; + unsigned long entries_count = 0; + + dev_dbg(&sep->pdev->dev, + "sep_debug_print_lli_tables start\n"); + + table_count = 1; + while ((unsigned long) lli_table_ptr != 0xffffffff) { + dev_dbg(&sep->pdev->dev, + "lli table %08lx, table_data_size is %lu\n", + table_count, table_data_size); + dev_dbg(&sep->pdev->dev, + "num_table_entries is %lu\n", + num_table_entries); + + /* print entries of the table (without info entry) */ + for (entries_count = 0; entries_count < num_table_entries; + entries_count++, lli_table_ptr++) { + + dev_dbg(&sep->pdev->dev, + "lli_table_ptr address is %08lx\n", + (unsigned long) lli_table_ptr); + + dev_dbg(&sep->pdev->dev, + "phys address is %08lx block size is %x\n", + (unsigned long)lli_table_ptr->bus_address, + lli_table_ptr->block_size); + } + + /* point to the info entry */ + lli_table_ptr--; + + dev_dbg(&sep->pdev->dev, + "phys lli_table_ptr->block_size is %x\n", + lli_table_ptr->block_size); + + dev_dbg(&sep->pdev->dev, + "phys lli_table_ptr->physical_address is %08lu\n", + (unsigned long)lli_table_ptr->bus_address); + + + table_data_size = lli_table_ptr->block_size & 0xffffff; + num_table_entries = (lli_table_ptr->block_size >> 24) & 0xff; + lli_table_ptr = (struct sep_lli_entry *) + (lli_table_ptr->bus_address); + + dev_dbg(&sep->pdev->dev, + "phys table_data_size is %lu num_table_entries is" + " %lu lli_table_ptr is%lu\n", table_data_size, + num_table_entries, (unsigned long)lli_table_ptr); + + if ((unsigned long)lli_table_ptr != 0xffffffff) + lli_table_ptr = (struct sep_lli_entry *) + sep_shared_bus_to_virt(sep, + (unsigned long)lli_table_ptr); + + table_count++; + } + dev_dbg(&sep->pdev->dev, + "sep_debug_print_lli_tables end\n"); +} + + +/** + * sep_prepare_empty_lli_table - + * This function creates empty lli tables when there is no data + * @sep: pointer to struct sep_device + * @lli_table_addr_ptr: pointer to lli table + * @num_entries_ptr: pointer to number of entries + * @table_data_size_ptr: point to table data size + */ +static void sep_prepare_empty_lli_table(struct sep_device *sep, + dma_addr_t *lli_table_addr_ptr, + u32 *num_entries_ptr, + u32 *table_data_size_ptr) +{ + struct sep_lli_entry *lli_table_ptr; + + dev_dbg(&sep->pdev->dev, "sep_prepare_empty_lli_table start\n"); + + /* find the area for new table */ + lli_table_ptr = + (struct sep_lli_entry *)(sep->shared_addr + + SYNCHRONIC_DMA_TABLES_AREA_OFFSET_BYTES + + sep->num_lli_tables_created * + sizeof(struct sep_lli_entry) * + SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP); + + lli_table_ptr->bus_address = 0; + lli_table_ptr->block_size = 0; + + lli_table_ptr++; + lli_table_ptr->bus_address = 0xFFFFFFFF; + lli_table_ptr->block_size = 0; + + /* set the output parameter value */ + *lli_table_addr_ptr = sep->shared_bus + + SYNCHRONIC_DMA_TABLES_AREA_OFFSET_BYTES + + sep->num_lli_tables_created * + sizeof(struct sep_lli_entry) * + SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP; + + /* set the num of entries and table data size for empty table */ + *num_entries_ptr = 2; + *table_data_size_ptr = 0; + + /* update the number of created tables */ + sep->num_lli_tables_created++; + + dev_dbg(&sep->pdev->dev, "sep_prepare_empty_lli_table start\n"); + +} + +/** + * sep_prepare_input_dma_table - + * This function prepares only input DMA table for synhronic symmetric + * operations (HASH) + * Note that all bus addresses that are passed to the sep + * are in 32 bit format; the SEP is a 32 bit device + * @sep: pointer to struct sep_device + * @data_size: + * @block_size: + * @lli_table_ptr: + * @num_entries_ptr: + * @table_data_size_ptr: + * @is_kva: set for kernel data (kernel cryptio call) + */ +static int sep_prepare_input_dma_table(struct sep_device *sep, + unsigned long app_virt_addr, + u32 data_size, + u32 block_size, + dma_addr_t *lli_table_ptr, + u32 *num_entries_ptr, + u32 *table_data_size_ptr, + bool is_kva) +{ + /* pointer to the info entry of the table - the last entry */ + struct sep_lli_entry *info_entry_ptr; + + /* array of pointers ot page */ + struct sep_lli_entry *lli_array_ptr; + + /* points to the first entry to be processed in the lli_in_array */ + u32 current_entry = 0; + + /* num entries in the virtual buffer */ + u32 sep_lli_entries = 0; + + /* lli table pointer */ + struct sep_lli_entry *in_lli_table_ptr; + + /* the total data in one table */ + u32 table_data_size = 0; + + /* flag for last table */ + u32 last_table_flag = 0; + + /* number of entries in lli table */ + u32 num_entries_in_table = 0; + + /* next table address */ + u32 lli_table_alloc_addr = 0; + + /* error */ + int error = 0; + + dev_dbg(&sep->pdev->dev, + "sep_prepare_input_dma_table start\n"); + + dev_dbg(&sep->pdev->dev, + "data_size is %x\n", data_size); + dev_dbg(&sep->pdev->dev, + "block_size is %x\n", block_size); + + /* initialize the pages pointers */ + sep->dma_res_arr[sep->nr_dcb_creat].in_page_array = 0; + sep->dma_res_arr[sep->nr_dcb_creat].in_num_pages = 0; + + /* set the kernel address for first table to be allocated */ + lli_table_alloc_addr = (u32)(sep->shared_addr + + SYNCHRONIC_DMA_TABLES_AREA_OFFSET_BYTES + + sep->num_lli_tables_created * + sizeof(struct sep_lli_entry) * + SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP); + + if (data_size == 0) { + + /* special case - create meptu table - 2 entries, zero data */ + sep_prepare_empty_lli_table(sep, lli_table_ptr, + num_entries_ptr, + table_data_size_ptr); + + goto update_dcb_counter; + } + + /* check if the pages are in Kernel Virtual Address layout */ + if (is_kva == true) + + /* lock the pages in the kernel */ + error = sep_lock_kernel_pages(sep, app_virt_addr, + data_size, &lli_array_ptr, SEP_DRIVER_IN_FLAG); + + else + + /* + * lock the pages of the user buffer + * and translate them to pages + */ + error = sep_lock_user_pages(sep, app_virt_addr, + data_size, &lli_array_ptr, SEP_DRIVER_IN_FLAG); + + if (error) + goto end_function; + + dev_dbg(&sep->pdev->dev, + "output sep_in_num_pages is %x\n", + sep->dma_res_arr[sep->nr_dcb_creat].in_num_pages); + + current_entry = 0; + info_entry_ptr = 0; + + sep_lli_entries = + sep->dma_res_arr[sep->nr_dcb_creat].in_num_pages; + + /* loop till all the entries in in array are not processed */ + while (current_entry < sep_lli_entries) { + + /* set the new input and output tables */ + in_lli_table_ptr = + (struct sep_lli_entry *)lli_table_alloc_addr; + + lli_table_alloc_addr += sizeof(struct sep_lli_entry) * + SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP; + + if (lli_table_alloc_addr > + ((u32)sep->shared_addr + + SYNCHRONIC_DMA_TABLES_AREA_OFFSET_BYTES + + SYNCHRONIC_DMA_TABLES_AREA_SIZE_BYTES)) { + + error = -ENOMEM; + goto end_function_error; + + } + + /* update the number of created tables */ + sep->num_lli_tables_created++; + + /* calculate the maximum size of data for input table */ + table_data_size = sep_calculate_lli_table_max_size(sep, + &lli_array_ptr[current_entry], + (sep_lli_entries - current_entry), + &last_table_flag); + + /** + * if this is not the last table - + * then allign it to the block size + */ + if (!last_table_flag) + table_data_size = + (table_data_size / block_size) * block_size; + + dev_dbg(&sep->pdev->dev, + "output table_data_size is %x\n", + table_data_size); + + /* construct input lli table */ + sep_build_lli_table(sep, &lli_array_ptr[current_entry], + in_lli_table_ptr, + ¤t_entry, &num_entries_in_table, table_data_size); + + if (info_entry_ptr == 0) { + + /* set the output parameters to physical addresses */ + *lli_table_ptr = sep_shared_area_virt_to_bus(sep, + in_lli_table_ptr); + *num_entries_ptr = num_entries_in_table; + *table_data_size_ptr = table_data_size; + + dev_dbg(&sep->pdev->dev, + "output lli_table_in_ptr is %08lx\n", + (unsigned long)*lli_table_ptr); + + } + + else { + + /* update the info entry of the previous in table */ + info_entry_ptr->bus_address = + sep_shared_area_virt_to_bus(sep, + in_lli_table_ptr); + info_entry_ptr->block_size = + ((num_entries_in_table) << 24) | + (table_data_size); + } + + /* save the pointer to the info entry of the current tables */ + info_entry_ptr = in_lli_table_ptr + num_entries_in_table - 1; + + } + + /* print input tables */ + sep_debug_print_lli_tables(sep, (struct sep_lli_entry *) + sep_shared_area_bus_to_virt(sep, *lli_table_ptr), + *num_entries_ptr, + *table_data_size_ptr); + + /* the array of the pages */ + kfree(lli_array_ptr); + +update_dcb_counter: + + /* update dcb counter */ + sep->nr_dcb_creat++; + + goto end_function; + +end_function_error: + + /* free all the allocated resources */ + kfree(sep->dma_res_arr[sep->nr_dcb_creat].in_map_array); + kfree(lli_array_ptr); + kfree(sep->dma_res_arr[sep->nr_dcb_creat].in_page_array); + +end_function: + + dev_dbg(&sep->pdev->dev, + "sep_prepare_input_dma_table end\n"); + + return error; + +} +/** + * sep_construct_dma_tables_from_lli - + * This function creates the input and output dma tables for + * symmetric operations (AES/DES) according to the block + * size from LLI arays + * Note that all bus addresses that are passed to the sep + * are in 32 bit format; the SEP is a 32 bit device + * @sep: pointer to struct_sep + * @lli_in_array: + * @sep_in_lli_entries: + * @lli_out_array: + * @sep_out_lli_entries + * @block_size + * @lli_table_in_ptr + * @lli_table_out_ptr + * @in_num_entries_ptr + * @out_num_entries_ptr + * @table_data_size_ptr + */ +static int sep_construct_dma_tables_from_lli( + struct sep_device *sep, + struct sep_lli_entry *lli_in_array, + u32 sep_in_lli_entries, + struct sep_lli_entry *lli_out_array, + u32 sep_out_lli_entries, + u32 block_size, + dma_addr_t *lli_table_in_ptr, + dma_addr_t *lli_table_out_ptr, + u32 *in_num_entries_ptr, + u32 *out_num_entries_ptr, + u32 *table_data_size_ptr) +{ + /* points to the area where next lli table can be allocated */ + u32 lli_table_alloc_addr = 0; + + /* input lli table */ + struct sep_lli_entry *in_lli_table_ptr = 0; + + /* output lli table */ + struct sep_lli_entry *out_lli_table_ptr = 0; + + /* pointer to the info entry of the table - the last entry */ + struct sep_lli_entry *info_in_entry_ptr = 0; + + /* pointer to the info entry of the table - the last entry */ + struct sep_lli_entry *info_out_entry_ptr = 0; + + /* points to the first entry to be processed in the lli_in_array */ + u32 current_in_entry = 0; + + /* points to the first entry to be processed in the lli_out_array */ + u32 current_out_entry = 0; + + /* max size of the input table */ + u32 in_table_data_size = 0; + + /* max size of the output table */ + u32 out_table_data_size = 0; + + /* flag te signifies if this is the last tables build */ + u32 last_table_flag = 0; + + /* the data size that should be in table */ + u32 table_data_size = 0; + + /* number of etnries in the input table */ + u32 num_entries_in_table = 0; + + /* number of etnries in the output table */ + u32 num_entries_out_table = 0; + + dev_dbg(&sep->pdev->dev, + "sep_construct_dma_tables_from_lli start\n"); + + /* initiate to point after the message area */ + lli_table_alloc_addr = (u32)(sep->shared_addr + + SYNCHRONIC_DMA_TABLES_AREA_OFFSET_BYTES + + (sep->num_lli_tables_created * + (sizeof(struct sep_lli_entry) * + SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP))); + + /* loop till all the entries in in array are not processed */ + while (current_in_entry < sep_in_lli_entries) { + + /* set the new input and output tables */ + in_lli_table_ptr = + (struct sep_lli_entry *)lli_table_alloc_addr; + + lli_table_alloc_addr += sizeof(struct sep_lli_entry) * + SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP; + + /* set the first output tables */ + out_lli_table_ptr = + (struct sep_lli_entry *)lli_table_alloc_addr; + + /* check if the DMA table area limit was overrun */ + if ((lli_table_alloc_addr + sizeof(struct sep_lli_entry) * + SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP) > + ((u32)sep->shared_addr + + SYNCHRONIC_DMA_TABLES_AREA_OFFSET_BYTES + + SYNCHRONIC_DMA_TABLES_AREA_SIZE_BYTES)) { + + dev_warn(&sep->pdev->dev, + "dma table limit overrun\n"); + return -ENOMEM; + } + + /* update the number of the lli tables created */ + sep->num_lli_tables_created += 2; + + lli_table_alloc_addr += sizeof(struct sep_lli_entry) * + SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP; + + /* calculate the maximum size of data for input table */ + in_table_data_size = + sep_calculate_lli_table_max_size(sep, + &lli_in_array[current_in_entry], + (sep_in_lli_entries - current_in_entry), + &last_table_flag); + + /* calculate the maximum size of data for output table */ + out_table_data_size = + sep_calculate_lli_table_max_size(sep, + &lli_out_array[current_out_entry], + (sep_out_lli_entries - current_out_entry), + &last_table_flag); + + dev_dbg(&sep->pdev->dev, + "in_table_data_size is %x\n", + in_table_data_size); + + dev_dbg(&sep->pdev->dev, + "out_table_data_size is %x\n", + out_table_data_size); + + table_data_size = in_table_data_size; + + if (!last_table_flag) { + /* + * if this is not the last table, + * then must check where the data is smallest + * and then align it to the block size + */ + if (table_data_size > out_table_data_size) + table_data_size = out_table_data_size; + + /* + * now calculate the table size so that + * it will be module block size + */ + table_data_size = (table_data_size / block_size) * + block_size; + } + + dev_dbg(&sep->pdev->dev, + "table_data_size is %x\n", table_data_size); + + /* construct input lli table */ + sep_build_lli_table(sep, &lli_in_array[current_in_entry], + in_lli_table_ptr, + ¤t_in_entry, + &num_entries_in_table, + table_data_size); + + /* construct output lli table */ + sep_build_lli_table(sep, &lli_out_array[current_out_entry], + out_lli_table_ptr, + ¤t_out_entry, + &num_entries_out_table, + table_data_size); + + /* if info entry is null - this is the first table built */ + if (info_in_entry_ptr == 0) { + /* set the output parameters to physical addresses */ + *lli_table_in_ptr = + sep_shared_area_virt_to_bus(sep, in_lli_table_ptr); + + *in_num_entries_ptr = num_entries_in_table; + + *lli_table_out_ptr = + sep_shared_area_virt_to_bus(sep, + out_lli_table_ptr); + + *out_num_entries_ptr = num_entries_out_table; + *table_data_size_ptr = table_data_size; + + dev_dbg(&sep->pdev->dev, + "output lli_table_in_ptr is %08lx\n", + (unsigned long)*lli_table_in_ptr); + dev_dbg(&sep->pdev->dev, + "output lli_table_out_ptr is %08lx\n", + (unsigned long)*lli_table_out_ptr); + } else { + /* update the info entry of the previous in table */ + info_in_entry_ptr->bus_address = + sep_shared_area_virt_to_bus(sep, + in_lli_table_ptr); + + info_in_entry_ptr->block_size = + ((num_entries_in_table) << 24) | + (table_data_size); + + /* update the info entry of the previous in table */ + info_out_entry_ptr->bus_address = + sep_shared_area_virt_to_bus(sep, + out_lli_table_ptr); + + info_out_entry_ptr->block_size = + ((num_entries_out_table) << 24) | + (table_data_size); + + dev_dbg(&sep->pdev->dev, + "output lli_table_in_ptr:%08lx %08x\n", + (unsigned long)info_in_entry_ptr->bus_address, + info_in_entry_ptr->block_size); + + dev_dbg(&sep->pdev->dev, + "output lli_table_out_ptr:%08lx %08x\n", + (unsigned long)info_out_entry_ptr->bus_address, + info_out_entry_ptr->block_size); + } + + /* save the pointer to the info entry of the current tables */ + info_in_entry_ptr = in_lli_table_ptr + + num_entries_in_table - 1; + info_out_entry_ptr = out_lli_table_ptr + + num_entries_out_table - 1; + + dev_dbg(&sep->pdev->dev, + "output num_entries_out_table is %x\n", + (u32)num_entries_out_table); + dev_dbg(&sep->pdev->dev, + "output info_in_entry_ptr is %lx\n", + (unsigned long)info_in_entry_ptr); + dev_dbg(&sep->pdev->dev, + "output info_out_entry_ptr is %lx\n", + (unsigned long)info_out_entry_ptr); + } + + /* print input tables */ + sep_debug_print_lli_tables(sep, + (struct sep_lli_entry *) + sep_shared_area_bus_to_virt(sep, *lli_table_in_ptr), + *in_num_entries_ptr, + *table_data_size_ptr); + + /* print output tables */ + sep_debug_print_lli_tables(sep, + (struct sep_lli_entry *) + sep_shared_area_bus_to_virt(sep, *lli_table_out_ptr), + *out_num_entries_ptr, + *table_data_size_ptr); + + dev_dbg(&sep->pdev->dev, + "sep_construct_dma_tables_from_lli end\n"); + + return 0; +} + +/** + * sep_prepare_input_output_dma_table - + * This function builds input and output DMA tables for synhronic + * symmetric operations (AES, DES, HASH). It also checks that each table + * is of the modular block size + * Note that all bus addresses that are passed to the sep + * are in 32 bit format; the SEP is a 32 bit device + * @app_virt_in_addr: + * @app_virt_out_addr: + * @data_size: + * @block_size: + * @lli_table_in_ptr: + * @lli_table_out_ptr: + * @in_num_entries_ptr: + * @out_num_entries_ptr: + * @table_data_size_ptr: + * @is_kva: set for kernel data; used only for kernel crypto module + */ +static int sep_prepare_input_output_dma_table(struct sep_device *sep, + unsigned long app_virt_in_addr, + unsigned long app_virt_out_addr, + u32 data_size, + u32 block_size, + dma_addr_t *lli_table_in_ptr, + dma_addr_t *lli_table_out_ptr, + u32 *in_num_entries_ptr, + u32 *out_num_entries_ptr, + u32 *table_data_size_ptr, + bool is_kva) + +{ + /* array of pointers of page */ + struct sep_lli_entry *lli_in_array; + + /* array of pointers of page */ + struct sep_lli_entry *lli_out_array; + + /* error */ + int error = 0; + + dev_dbg(&sep->pdev->dev, + "sep_prepare_input_output_dma_table start\n"); + + if (data_size == 0) { + + /* prepare empty table for input and output */ + sep_prepare_empty_lli_table(sep, lli_table_in_ptr, + in_num_entries_ptr, table_data_size_ptr); + + sep_prepare_empty_lli_table(sep, lli_table_out_ptr, + out_num_entries_ptr, table_data_size_ptr); + + goto update_dcb_counter; + } + + /* initialize the pages pointers */ + sep->dma_res_arr[sep->nr_dcb_creat].in_page_array = 0; + sep->dma_res_arr[sep->nr_dcb_creat].out_page_array = 0; + + /* lock the pages of the buffer and translate them to pages */ + if (is_kva == true) { + error = sep_lock_kernel_pages(sep, app_virt_in_addr, + data_size, &lli_in_array, SEP_DRIVER_IN_FLAG); + + if (error) { + dev_warn(&sep->pdev->dev, + "lock kernel for in failed\n"); + goto end_function; + } + + error = sep_lock_kernel_pages(sep, app_virt_out_addr, + data_size, &lli_out_array, SEP_DRIVER_OUT_FLAG); + + if (error) { + dev_warn(&sep->pdev->dev, + "lock kernel for out failed\n"); + goto end_function; + } + } + + else { + error = sep_lock_user_pages(sep, app_virt_in_addr, + data_size, &lli_in_array, SEP_DRIVER_IN_FLAG); + if (error) { + dev_warn(&sep->pdev->dev, "sep_lock_user_pages for " + "input virtual buffer failed\n"); + goto end_function; + } + + error = sep_lock_user_pages(sep, app_virt_out_addr, + data_size, &lli_out_array, SEP_DRIVER_OUT_FLAG); + + if (error) { + dev_warn(&sep->pdev->dev, "sep_lock_user_pages for " + "output virtual buffer failed\n"); + goto end_function_free_lli_in; + } + } + + dev_dbg(&sep->pdev->dev, + "sep_in_num_pages is %x\n", + sep->dma_res_arr[sep->nr_dcb_creat].in_num_pages); + dev_dbg(&sep->pdev->dev, + "sep_out_num_pages is %x\n", + sep->dma_res_arr[sep->nr_dcb_creat].out_num_pages); + dev_dbg(&sep->pdev->dev, + "SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP is %x\n", + SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP); + + /* call the fucntion that creates table from the lli arrays */ + error = sep_construct_dma_tables_from_lli(sep, lli_in_array, + sep->dma_res_arr[sep->nr_dcb_creat].in_num_pages, + lli_out_array, + sep->dma_res_arr[sep->nr_dcb_creat].out_num_pages, + block_size, lli_table_in_ptr, lli_table_out_ptr, + in_num_entries_ptr, out_num_entries_ptr, table_data_size_ptr); + + if (error) { + dev_warn(&sep->pdev->dev, + "sep_construct_dma_tables_from_lli failed\n"); + goto end_function_with_error; + } + + kfree(lli_out_array); + kfree(lli_in_array); + +update_dcb_counter: + + /* update dcb counter */ + sep->nr_dcb_creat++; + + /* fall through - free the lli entry arrays */ + dev_dbg(&sep->pdev->dev, + "in_num_entries_ptr is %08x\n", *in_num_entries_ptr); + dev_dbg(&sep->pdev->dev, + "out_num_entries_ptr is %08x\n", *out_num_entries_ptr); + dev_dbg(&sep->pdev->dev, + "table_data_size_ptr is %08x\n", *table_data_size_ptr); + + goto end_function; + +end_function_with_error: + + kfree(sep->dma_res_arr[sep->nr_dcb_creat].out_map_array); + kfree(sep->dma_res_arr[sep->nr_dcb_creat].out_page_array); + kfree(lli_out_array); + + +end_function_free_lli_in: + + kfree(sep->dma_res_arr[sep->nr_dcb_creat].in_map_array); + kfree(sep->dma_res_arr[sep->nr_dcb_creat].in_page_array); + kfree(lli_in_array); + +end_function: + + dev_dbg(&sep->pdev->dev, + "sep_prepare_input_output_dma_table" + " end result = %d\n", error); + + return error; + +} + +/** + * sep_prepare_input_output_dma_table_in_dcb - + * This function prepares the linked dma tables and puts the + * address for the linked list of tables inta a dcb (data control + * block) the address of which is known by the sep hardware + * Note that all bus addresses that are passed to the sep + * are in 32 bit format; the SEP is a 32 bit device + * @app_in_address: unsigned long; for data buffer in (user space) + * @app_out_address: unsigned long; for data buffer out (user space) + * @data_in_size: u32; for size of data + * @block_size: u32; for block size + * @tail_block_size: u32; for size of tail block + * @isapplet: bool; to indicate external app + * @is_kva: bool; kernel buffer; only used for kernel crypto module + */ +static int sep_prepare_input_output_dma_table_in_dcb(struct sep_device *sep, + u32 app_in_address, + u32 app_out_address, + u32 data_in_size, + u32 block_size, + u32 tail_block_size, + bool isapplet, + bool is_kva) +{ + /* error */ + int error = 0; + + /* size of tail */ + u32 tail_size = 0; + + /* address of the created dcb table */ + struct sep_dcblock *dcb_table_ptr = 0; + + /* the physical address of the first input DMA table */ + dma_addr_t in_first_mlli_address = 0; + + /* number of entries in the first input DMA table */ + u32 in_first_num_entries = 0; + + /* the physical address of the first output DMA table */ + dma_addr_t out_first_mlli_address = 0; + + /* number of entries in the first output DMA table */ + u32 out_first_num_entries = 0; + + /* data in the first input/output table */ + u32 first_data_size = 0; + + dev_dbg(&sep->pdev->dev, + "prepare_input_output_dma_table_in_dcb start\n"); + + if (sep->nr_dcb_creat == SEP_MAX_NUM_SYNC_DMA_OPS) { + /*No more DCBS to allocate*/ + dev_warn(&sep->pdev->dev, "no more dcb's available\n"); + error = -ENOSPC; + goto end_function; + } + + /* allocate new DCB */ + dcb_table_ptr = (struct sep_dcblock *)(sep->shared_addr + + SEP_DRIVER_SYSTEM_DCB_MEMORY_OFFSET_IN_BYTES + + (sep->nr_dcb_creat * sizeof(struct sep_dcblock))); + + /* set the default values in the dcb */ + dcb_table_ptr->input_mlli_address = 0; + dcb_table_ptr->input_mlli_num_entries = 0; + dcb_table_ptr->input_mlli_data_size = 0; + dcb_table_ptr->output_mlli_address = 0; + dcb_table_ptr->output_mlli_num_entries = 0; + dcb_table_ptr->output_mlli_data_size = 0; + dcb_table_ptr->tail_data_size = 0; + dcb_table_ptr->out_vr_tail_pt = 0; + + if (isapplet == true) { + tail_size = data_in_size % block_size; + + if (tail_size) { + + if (data_in_size < tail_block_size) { + dev_warn(&sep->pdev->dev, + "data in size smaller than tail" + " block size\n"); + error = -ENOSPC; + goto end_function; + } + + if (tail_block_size) + /* + * case the tail size should be + * bigger than the real block size + */ + tail_size = tail_block_size + + ((data_in_size - + tail_block_size) % block_size); + } + + /* check if there is enough data for dma operation */ + if (data_in_size < SEP_DRIVER_MIN_DATA_SIZE_PER_TABLE) { + if (is_kva == true) { + memcpy(dcb_table_ptr->tail_data, + (void *)app_in_address, data_in_size); + } + + else { + if (copy_from_user(dcb_table_ptr->tail_data, + (void __user *)app_in_address, + data_in_size)) { + error = -EFAULT; + goto end_function; + } + } + + dcb_table_ptr->tail_data_size = data_in_size; + + /* set the output user-space address for mem2mem op */ + if (app_out_address) + dcb_table_ptr->out_vr_tail_pt = + (u32)app_out_address; + + /* + * Update both data length parameters in order to avoid + * second data copy and allow building of empty mlli + * tables + */ + tail_size = 0x0; + data_in_size = 0x0; + } + + if (tail_size) { + if (is_kva == true) { + memcpy(dcb_table_ptr->tail_data, + (void *)(app_in_address + data_in_size - + tail_size), tail_size); + } + + else { + /* we have tail data - copy it to dcb */ + if (copy_from_user(dcb_table_ptr->tail_data, + (void *)(app_in_address + + data_in_size - tail_size), tail_size)) { + error = -EFAULT; + goto end_function; + } + } + + if (app_out_address) + /* + * Caclulate the output address + * according to tail data size + */ + dcb_table_ptr->out_vr_tail_pt = + app_out_address + data_in_size + - tail_size; + + /*save the real tail data size*/ + dcb_table_ptr->tail_data_size = tail_size; + /* + * Update the data size without the tail + * data size AKA data for the dma + */ + data_in_size = (data_in_size - tail_size); + } + } + + /* check if we need to build only input table or input/output */ + if (app_out_address) { + /* prepare input/output tables */ + error = sep_prepare_input_output_dma_table(sep, + app_in_address, + app_out_address, + data_in_size, + block_size, + &in_first_mlli_address, + &out_first_mlli_address, + &in_first_num_entries, + &out_first_num_entries, + &first_data_size, + is_kva); + } + + else { + /* prepare input tables */ + error = sep_prepare_input_dma_table(sep, + app_in_address, + data_in_size, + block_size, + &in_first_mlli_address, + &in_first_num_entries, + &first_data_size, + is_kva); + } + + if (error) { + dev_warn(&sep->pdev->dev, "prepare dma table call failed" + " from prepare dcb call\n"); + goto end_function; + } + + /* set the dcb values */ + dcb_table_ptr->input_mlli_address = in_first_mlli_address; + dcb_table_ptr->input_mlli_num_entries = in_first_num_entries; + dcb_table_ptr->input_mlli_data_size = first_data_size; + dcb_table_ptr->output_mlli_address = out_first_mlli_address; + dcb_table_ptr->output_mlli_num_entries = out_first_num_entries; + dcb_table_ptr->output_mlli_data_size = first_data_size; + +end_function: + + dev_dbg(&sep->pdev->dev, + "sep_prepare_input_output_dma_table_in_dcb end\n"); + return error; + +} + + +/** + * sep_create_sync_dma_tables_handler - + * this function handles tha request for creation of the DMA table + * for the synchronic symmetric operations (AES,DES) + * Note that all bus addresses that are passed to the sep + * are in 32 bit format; the SEP is a 32 bit device + * @sep: pointer to struct sep_device + * @arg: pointer to struct bld_syn_tab_struct +*/ +static int sep_create_sync_dma_tables_handler(struct sep_device *sep, + unsigned long arg) +{ + int error = 0; + + /* command arguments */ + struct bld_syn_tab_struct command_args; + + dev_dbg(&sep->pdev->dev, + "sep_create_sync_dma_tables_handler start\n"); + + if (copy_from_user(&command_args, (void __user *)arg, + sizeof(struct bld_syn_tab_struct))) { + error = -EFAULT; + dev_warn(&sep->pdev->dev, "create dma tables;" + " copy_from_user fails\n"); + goto end_function; + } + + dev_dbg(&sep->pdev->dev, + "app_in_address is %08llx\n", command_args.app_in_address); + dev_dbg(&sep->pdev->dev, + "app_out_address is %08llx\n", command_args.app_out_address); + dev_dbg(&sep->pdev->dev, + "data_size is %u\n", command_args.data_in_size); + dev_dbg(&sep->pdev->dev, + "block_size is %u\n", command_args.block_size); + + /* validate user parameters */ + if (!command_args.app_in_address) { + + dev_warn(&sep->pdev->dev, + "params validation error\n"); + + error = -EINVAL; + goto end_function; + } + + error = sep_prepare_input_output_dma_table_in_dcb(sep, + command_args.app_in_address, + command_args.app_out_address, + command_args.data_in_size, + command_args.block_size, + 0x0, + false, + false); + +end_function: + + dev_dbg(&sep->pdev->dev, "sep_create_sync_dma_tables_handler end\n"); + return error; +} + +/** + * sep_free_dma_tables_and_dcb - + * This function frees the dma tables and dcb block + * @sep: pointer to struct sep_device + * @isapplet: indicates external application (used for kernel access) + * @is_kva: indicates kernel addresses (only used for kernel crypto) + */ +static int sep_free_dma_tables_and_dcb(struct sep_device *sep, bool isapplet, + bool is_kva) +{ + + int i = 0; + int error = 0; + int error_temp = 0; + + struct sep_dcblock *dcb_table_ptr; + + dev_dbg(&sep->pdev->dev, "sep_free_dma_tables_and_dcb start\n"); + + if (isapplet == true) { + + /* set pointer to first dcb table */ + dcb_table_ptr = (struct sep_dcblock *) + (sep->shared_addr + + SEP_DRIVER_SYSTEM_DCB_MEMORY_OFFSET_IN_BYTES); + + /* go over each dcb and see if tail pointer must be updated */ + for (i = 0; i < sep->nr_dcb_creat; i++, dcb_table_ptr++) { + + if (dcb_table_ptr->out_vr_tail_pt) { + + if (is_kva == true) { + memcpy((void *)dcb_table_ptr->out_vr_tail_pt, + dcb_table_ptr->tail_data, + dcb_table_ptr->tail_data_size); + } + + else { + error_temp = copy_to_user( + (void *)dcb_table_ptr->out_vr_tail_pt, + dcb_table_ptr->tail_data, + dcb_table_ptr->tail_data_size); + } + + if (error_temp) { + /* release the dma resource */ + error = error_temp; + } + } + } + } + + /* free the output pages, if any */ + sep_free_dma_table_data_handler(sep); + + dev_dbg(&sep->pdev->dev, "sep_free_dma_tables_and_dcb end\n"); + return error; +} + +/** + * sep_get_static_pool_addr_handler - + * this function sets the bus and virtual addresses of the static pool + * and returns the virtual address + * @sep: pointer to struct sep_device + * @arg: parameters from user space application + */ +static int sep_get_static_pool_addr_handler(struct sep_device *sep, + unsigned long arg) +{ + struct stat_pool_addr_struct command_args; + + u32 *static_pool_addr = 0; + + unsigned long addr_hold; + + dev_dbg(&sep->pdev->dev, "sep_get_static_pool_addr_handler start\n"); + + static_pool_addr = (u32 *)(sep->shared_addr + + SEP_DRIVER_SYSTEM_RAR_MEMORY_OFFSET_IN_BYTES); + + static_pool_addr[0] = SEP_STATIC_POOL_VAL_TOKEN; + static_pool_addr[1] = sep->shared_bus + + SEP_DRIVER_STATIC_AREA_OFFSET_IN_BYTES; + + addr_hold = (unsigned long) + (sep->shared_addr + SEP_DRIVER_STATIC_AREA_OFFSET_IN_BYTES); + command_args.static_virt_address = (aligned_u64)addr_hold; + + dev_dbg(&sep->pdev->dev, "static pool: physical %x virtual %x\n", + (u32)static_pool_addr[1], + (u32)command_args.static_virt_address); + + /* send the parameters to user application */ + if (copy_to_user((void __user *) arg, &command_args, + sizeof(struct stat_pool_addr_struct))) + return -EFAULT; + + dev_dbg(&sep->pdev->dev, "sep_get_static_pool_addr_handler end\n"); + + return 0; +} + +/** + * sep_start_handler - + * This function starts the sep device + * @sep: pointer to struct sep_device + */ +static int sep_start_handler(struct sep_device *sep) +{ + unsigned long reg_val; + unsigned long error = 0; + + dev_dbg(&sep->pdev->dev, "sep_start_handler start\n"); + + /* wait in polling for message from SEP */ + do + reg_val = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR3_REG_ADDR); + while (!reg_val); + + /* check the value */ + if (reg_val == 0x1) + /* fatal error - read error status from GPRO */ + error = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR0_REG_ADDR); + dev_dbg(&sep->pdev->dev, "sep_start_handler end\n"); + return error; +} + +/** + * ep_check_sum_calc - + * This function performs a checsum for messages that are sent + * to the sep + * @data: + * @length: + */ +static u32 sep_check_sum_calc(u8 *data, u32 length) +{ + u32 sum = 0; + u16 *Tdata = (u16 *)data; + + while (length > 1) { + /* This is the inner loop */ + sum += *Tdata++; + length -= 2; + } + + /* Add left-over byte, if any */ + if (length > 0) + sum += *(u8 *)Tdata; + + /* Fold 32-bit sum to 16 bits */ + while (sum>>16) + sum = (sum & 0xffff) + (sum >> 16); + + return ~sum & 0xFFFF; +} + +/** + * sep_init_handler - + * this function handles the request for SEP initialization + * Note that this will go away for Medfield once the SCU + * SEP initialization is complete + * Also note that the message to the sep has components + * from user space as well as components written by the driver + * This is becuase the portions of the message that partain to + * physical addresses must be set by the driver after the message + * leaves custody of the user space application for security + * reasons. + * @sep: pointer to struct sep_device + * @arg: parameters from user space application + */ +static int sep_init_handler(struct sep_device *sep, unsigned long arg) +{ + u32 message_buff[14]; + u32 counter; + int error = 0; + u32 reg_val; + dma_addr_t new_base_addr; + unsigned long addr_hold; + struct init_struct command_args; + + dev_dbg(&sep->pdev->dev, "sep_init_handler start\n"); + error = 0; + + /* make sure that we have not initialized already */ + reg_val = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR3_REG_ADDR); + + if (reg_val != 0x2) { + error = SEP_ALREADY_INITIALIZED_ERR; + dev_warn(&sep->pdev->dev, + "init; device already initialized\n"); + goto end_function; + } + + /* only root can initialize */ + if (!capable(CAP_SYS_ADMIN)) { + dev_warn(&sep->pdev->dev, + "init; only root can init\n"); + error = -EACCES; + goto end_function; + } + + /* copy in the parameters */ + error = copy_from_user(&command_args, (void __user *)arg, + sizeof(struct init_struct)); + + if (error) { + dev_warn(&sep->pdev->dev, + "init; copy_from_user failed %x\n", error); + goto end_function; + } + + /* validate parameters */ + if (!command_args.message_addr || !command_args.sep_sram_addr || + command_args.message_size_in_words > 14) { + + dev_warn(&sep->pdev->dev, + "init; parameter error\n"); + error = -EINVAL; + goto end_function; + } + + /* copy in the sep init message */ + addr_hold = (unsigned long)command_args.message_addr; + error = copy_from_user(message_buff, + (void __user *)addr_hold, + command_args.message_size_in_words*sizeof(u32)); + + if (error) { + + dev_warn(&sep->pdev->dev, + "init; copy sep init message failed %x\n", error); + goto end_function; + } + + /* load resident, cache, and extapp firmware */ + error = sep_load_firmware(sep); + + if (error) { + + dev_warn(&sep->pdev->dev, + "init; copy sep init message failed %x\n", error); + goto end_function; + } + + /* compute the base address */ + new_base_addr = sep->shared_bus; + + if (sep->resident_bus < new_base_addr) + new_base_addr = sep->resident_bus; + + if (sep->cache_bus < new_base_addr) + new_base_addr = sep->cache_bus; + + if (sep->dcache_bus < new_base_addr) + new_base_addr = sep->dcache_bus; + + /* put physical addresses in sep message */ + message_buff[3] = (u32)new_base_addr; + message_buff[4] = (u32)sep->shared_bus; + message_buff[6] = (u32)sep->resident_bus; + message_buff[7] = (u32)sep->cache_bus; + message_buff[8] = (u32)sep->dcache_bus; + + message_buff[command_args.message_size_in_words - 1] = 0x0; + message_buff[command_args.message_size_in_words - 1] = + sep_check_sum_calc((u8 *)message_buff, + command_args.message_size_in_words*sizeof(u32)); + + /* debug print of message */ + for (counter = 0; counter < command_args.message_size_in_words; + counter++) + + dev_dbg(&sep->pdev->dev, + "init; sep message word %d is %x\n", + counter, message_buff[counter]); + + /* tell the sep the sram address */ + sep_write_reg(sep, HW_SRAM_ADDR_REG_ADDR, command_args.sep_sram_addr); + + /* push the message to the sep */ + for (counter = 0; counter < command_args.message_size_in_words; + counter++) { + + sep_write_reg(sep, HW_SRAM_DATA_REG_ADDR, + message_buff[counter]); + + sep_wait_sram_write(sep); + } + + /* signal sep that message is ready and to init */ + sep_write_reg(sep, HW_HOST_HOST_SEP_GPR0_REG_ADDR, 0x1); + + /* wait for acknowledge */ + dev_dbg(&sep->pdev->dev, "init; waiting for msg response\n"); + + do + reg_val = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR3_REG_ADDR); + while (!(reg_val & 0xFFFFFFFD)); + + if (reg_val == 0x1) { + + dev_warn(&sep->pdev->dev, "init; device int failed\n"); + error = sep_read_reg(sep, 0x8060); + dev_warn(&sep->pdev->dev, "init; sw monitor is %x\n", error); + error = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR0_REG_ADDR); + dev_warn(&sep->pdev->dev, "init; error is %x\n", error); + goto end_function; + } + + dev_dbg(&sep->pdev->dev, "init; end CC INIT, reg_val is %x\n", + reg_val); + + /* signal sep to zero the GPR3 */ + sep_write_reg(sep, HW_HOST_HOST_SEP_GPR0_REG_ADDR, 0x10); + + /* wait for response */ + dev_dbg(&sep->pdev->dev, "init; waiting for zero set response\n"); + + do + reg_val = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR3_REG_ADDR); + while (reg_val != 0); + + +end_function: + dev_dbg(&sep->pdev->dev, "init is done\n"); + return error; +} + +/** + * sep_end_transaction_handler - + * This API handles the end transaction request + * @sep: pointer to struct sep_device + */ +static int sep_end_transaction_handler(struct sep_device *sep) +{ + dev_dbg(&sep->pdev->dev, "sep_end_transaction_handler start\n"); + + /* clear the data pool pointers Token */ + memset((void *)(sep->shared_addr + + SEP_DRIVER_DATA_POOL_ALLOCATION_OFFSET_IN_BYTES), + 0, sep->num_of_data_allocations*2*sizeof(u32)); + + /* check that all the dma resources were freed */ + sep_free_dma_table_data_handler(sep); + + clear_bit(SEP_MMAP_LOCK_BIT, &sep->in_use_flags); + + /* + * we are now through with the transaction. Let's + * allow other processes who have the device open + * to perform transactions + */ + mutex_lock(&sep->sep_mutex); + sep->pid_doing_transaction = 0; + mutex_unlock(&sep->sep_mutex); + /* raise event for stuck contextes */ + wake_up(&sep->event); + + dev_dbg(&sep->pdev->dev, "waking up event\n"); + dev_dbg(&sep->pdev->dev, "sep_end_transaction_handler end\n"); + + return 0; +} + +/** + * sep_prepare_dcb_handler - + * This function will retrieve the RAR buffer physical addresses, type + * & size corresponding to the RAR handles provided in the buffers vector. + * @sep: pointer to struct sep_device + * @arg: pointer to user parameters + */ + +static int sep_prepare_dcb_handler(struct sep_device *sep, unsigned long arg) +{ + /* error */ + int error = 0; + + /* command arguments */ + struct build_dcb_struct command_args; + + dev_dbg(&sep->pdev->dev, "sep_prepare_dcb_handler start\n"); + + /* get the command arguments */ + if (copy_from_user(&command_args, (void __user *)arg, + sizeof(struct build_dcb_struct))) { + error = -EFAULT; + goto end_function; + } + + dev_dbg(&sep->pdev->dev, + "app_in_address is %08llx\n", command_args.app_in_address); + dev_dbg(&sep->pdev->dev, + "app_out_address is %08llx\n", command_args.app_out_address); + dev_dbg(&sep->pdev->dev, + "data_size is %x\n", command_args.data_in_size); + dev_dbg(&sep->pdev->dev, + "block_size is %x\n", command_args.block_size); + dev_dbg(&sep->pdev->dev, + "tail block_size is %x\n", command_args.tail_block_size); + + error = sep_prepare_input_output_dma_table_in_dcb(sep, + command_args.app_in_address, command_args.app_out_address, + command_args.data_in_size, command_args.block_size, + command_args.tail_block_size, true, false); + +end_function: + + dev_dbg(&sep->pdev->dev, "sep_prepare_dcb_handler end\n"); + return error; + +} + +/** + * sep_free_dcb_handler - + * this function frees the DCB resources + * and updates the needed user-space buffers + * @sep: pointer to struct sep_device + */ +static int sep_free_dcb_handler(struct sep_device *sep) +{ + int error ; + + dev_dbg(&sep->pdev->dev, "sep_prepare_dcb_handler start\n"); + dev_dbg(&sep->pdev->dev, "num of DCBs %x\n", sep->nr_dcb_creat); + + error = sep_free_dma_tables_and_dcb(sep, false, false); + + dev_dbg(&sep->pdev->dev, "sep_free_dcb_handler end\n"); + return error; +} + +/** + * sep_rar_prepare_output_msg_handler - + * This function will retrieve the RAR buffer physical addresses, type + * & size corresponding to the RAR handles provided in the buffers vector. + * @sep: pointer to struct sep_device + * @arg: pointer to user parameters + */ + +static int sep_rar_prepare_output_msg_handler(struct sep_device *sep, + unsigned long arg) +{ + /* error return code */ + int error = 0; + + /* command args */ + struct rar_hndl_to_bus_struct command_args; + struct RAR_buffer rar_buf; + + /* bus address */ + dma_addr_t rar_bus = 0; + + /* holds the RAR address in the system memory offset */ + u32 *rar_addr; + + dev_dbg(&sep->pdev->dev, + "sep_rar_prepare_output_msg_handler start\n"); + + /* copy the data */ + if (copy_from_user(&command_args, + (void __user *)arg, + sizeof(command_args))) { + error = -EFAULT; + goto end_function; + } + + /* call to translation function only if user handle is not NULL */ + if (command_args.rar_handle) { + + memset(&rar_buf, 0, sizeof(rar_buf)); + rar_buf.info.handle = (u32)command_args.rar_handle; + + if (rar_handle_to_bus(&rar_buf, 1) != 1) { + dev_dbg(&sep->pdev->dev, + "rar_handle_to_bus failure\n"); + error = -EFAULT; + goto end_function; + } + + rar_bus = rar_buf.bus_address; + } + + dev_dbg(&sep->pdev->dev, "rar msg; rar_addr_bus = %x\n", + (u32)rar_bus); + + /* set value in the SYSTEM MEMORY offset */ + rar_addr = (u32 *)(sep->shared_addr + + SEP_DRIVER_SYSTEM_RAR_MEMORY_OFFSET_IN_BYTES); + + /* copy the physical address to the System Area for the sep */ + rar_addr[0] = SEP_RAR_VAL_TOKEN; + rar_addr[1] = rar_bus; + +end_function: + + dev_dbg(&sep->pdev->dev, + "sep_rar_prepare_output_msg_handler start\n"); + + return error; +} + +/** + * sep_realloc_ext_cache_handler - + * This function tells the sep where the extapp is located + * @sep: pointer to struct sep_device + * @arg: pointer to user parameters + */ +static int sep_realloc_ext_cache_handler(struct sep_device *sep, + unsigned long arg) +{ + /* holds the new ext cache address in the system memory offset */ + u32 *system_addr; + + /* set value in the SYSTEM MEMORY offset */ + system_addr = (u32 *)(sep->shared_addr + + SEP_DRIVER_SYSTEM_EXT_CACHE_ADDR_OFFSET_IN_BYTES); + + /* copy the physical address to the System Area for the sep */ + + system_addr[0] = SEP_EXT_CACHE_ADDR_VAL_TOKEN; + dev_dbg(&sep->pdev->dev, + "ext cache init; system addr 0 is %x\n", system_addr[0]); + system_addr[1] = sep->extapp_bus; + dev_dbg(&sep->pdev->dev, + "ext cache init; system addr 1 is %x\n", system_addr[1]); + + return 0; +} + +/** + * sep_ioctl - ioctl api + * @filp: pointer to struct file + * @cmd: command + * @arg: pointer to argument structure + */ +static long sep_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) +{ + int error = 0; + struct sep_device *sep = filp->private_data; + + dev_dbg(&sep->pdev->dev, "ioctl start\n"); + + dev_dbg(&sep->pdev->dev, "cmd is %x\n", cmd); + dev_dbg(&sep->pdev->dev, + "SEP_IOCSENDSEPCOMMAND is %x\n", SEP_IOCSENDSEPCOMMAND); + dev_dbg(&sep->pdev->dev, + "SEP_IOCALLOCDATAPOLL is %x\n", SEP_IOCALLOCDATAPOLL); + dev_dbg(&sep->pdev->dev, + "SEP_IOCCREATESYMDMATABLE is %x\n", SEP_IOCCREATESYMDMATABLE); + dev_dbg(&sep->pdev->dev, + "SEP_IOCFREEDMATABLEDATA is %x\n", SEP_IOCFREEDMATABLEDATA); + dev_dbg(&sep->pdev->dev, + "SEP_IOCSEPSTART is %x\n", SEP_IOCSEPSTART); + dev_dbg(&sep->pdev->dev, + "SEP_IOCSEPINIT is %x\n", SEP_IOCSEPINIT); + dev_dbg(&sep->pdev->dev, + "SEP_IOCGETSTATICPOOLADDR is %x\n", SEP_IOCGETSTATICPOOLADDR); + dev_dbg(&sep->pdev->dev, + "SEP_IOCENDTRANSACTION is %x\n", SEP_IOCENDTRANSACTION); + dev_dbg(&sep->pdev->dev, + "SEP_IOCREALLOCEXTCACHE is %x\n", SEP_IOCREALLOCEXTCACHE); + dev_dbg(&sep->pdev->dev, + "SEP_IOCRARPREPAREMESSAGE is %x\n", SEP_IOCRARPREPAREMESSAGE); + dev_dbg(&sep->pdev->dev, + "SEP_IOCPREPAREDCB is %x\n", SEP_IOCPREPAREDCB); + dev_dbg(&sep->pdev->dev, + "SEP_IOCFREEDCB is %x\n", SEP_IOCFREEDCB); + + /* make sure we own this device */ + mutex_lock(&sep->sep_mutex); + if ((current->pid != sep->pid_doing_transaction) && + (sep->pid_doing_transaction != 0)) { + + dev_dbg(&sep->pdev->dev, "ioctl pid is not owner\n"); + mutex_unlock(&sep->sep_mutex); + error = -EACCES; + goto end_function; + } + + mutex_unlock(&sep->sep_mutex); + + /* check that the command is for sep device */ + if (_IOC_TYPE(cmd) != SEP_IOC_MAGIC_NUMBER) { + error = -ENOTTY; + goto end_function; + } + + /* lock to prevent the daemon to interfere with operation */ + mutex_lock(&sep->ioctl_mutex); + + switch (cmd) { + case SEP_IOCSENDSEPCOMMAND: + /* send command to SEP */ + error = sep_send_command_handler(sep); + break; + case SEP_IOCALLOCDATAPOLL: + /* allocate data pool */ + error = sep_allocate_data_pool_memory_handler(sep, arg); + break; + case SEP_IOCCREATESYMDMATABLE: + /* create dma table for synhronic operation */ + error = sep_create_sync_dma_tables_handler(sep, arg); + break; + case SEP_IOCFREEDMATABLEDATA: + /* free the pages */ + error = sep_free_dma_table_data_handler(sep); + break; + case SEP_IOCSEPSTART: + /* start command to sep */ + if (sep->pdev->revision == 0) /* only for old chip */ + error = sep_start_handler(sep); + else + error = -EPERM; /* not permitted on new chip */ + break; + case SEP_IOCSEPINIT: + /* init command to sep */ + if (sep->pdev->revision == 0) /* only for old chip */ + error = sep_init_handler(sep, arg); + else + error = -EPERM; /* not permitted on new chip */ + break; + case SEP_IOCGETSTATICPOOLADDR: + /* get the physical and virtual addresses of the static pool */ + error = sep_get_static_pool_addr_handler(sep, arg); + break; + case SEP_IOCENDTRANSACTION: + error = sep_end_transaction_handler(sep); + break; + case SEP_IOCREALLOCEXTCACHE: + if (sep->mrst) + error = -ENODEV; + if (sep->pdev->revision == 0) /* only for old chip */ + error = sep_realloc_ext_cache_handler(sep, arg); + else + error = -EPERM; /* not permitted on new chip */ + break; + case SEP_IOCRARPREPAREMESSAGE: + error = sep_rar_prepare_output_msg_handler(sep, arg); + break; + case SEP_IOCPREPAREDCB: + error = sep_prepare_dcb_handler(sep, arg); + break; + case SEP_IOCFREEDCB: + error = sep_free_dcb_handler(sep); + break; + default: + dev_warn(&sep->pdev->dev, "invalid ioctl %x\n", cmd); + error = -ENOTTY; + break; + } + + mutex_unlock(&sep->ioctl_mutex); + +end_function: + + dev_dbg(&sep->pdev->dev, "ioctl end\n"); + return error; +} + +/** + * sep_singleton_ioctl - ioctl api for singleton interface + * @filp: pointer to struct file + * @cmd: command + * @arg: pointer to argument structure + */ +static long sep_singleton_ioctl(struct file *filp, u32 cmd, unsigned long arg) +{ + + /* error */ + long error; + struct sep_device *sep = filp->private_data; + + error = 0; + + dev_dbg(&sep->pdev->dev, + "singleton_ioctl start\n"); + + dev_dbg(&sep->pdev->dev, + "cmd is %x\n", cmd); + + /* check that the command is for sep device */ + if (_IOC_TYPE(cmd) != SEP_IOC_MAGIC_NUMBER) { + error = -ENOTTY; + goto end_function; + } + + /* make sure we own this device */ + mutex_lock(&sep->sep_mutex); + if ((current->pid != sep->pid_doing_transaction) && + (sep->pid_doing_transaction != 0)) { + + dev_dbg(&sep->pdev->dev, "singleton ioctl pid is not owner\n"); + mutex_unlock(&sep->sep_mutex); + error = -EACCES; + goto end_function; + } + + mutex_unlock(&sep->sep_mutex); + + switch (cmd) { + + case SEP_IOCTLSETCALLERID: + mutex_lock(&sep->ioctl_mutex); + error = sep_set_caller_id_handler(sep, arg); + mutex_unlock(&sep->ioctl_mutex); + break; + + default: + error = sep_ioctl(filp, cmd, arg); + break; + + } + +end_function: + + dev_dbg(&sep->pdev->dev, "singleton ioctl end\n"); + return error; +} + +/** + * sep_request_daemon_ioctl - ioctl for daemon + * @filp: pointer to struct file + * @cmd: command + * @arg: pointer to argument structure + * Called by the request daemon to perform ioctls on the daemon device + */ + +static long sep_request_daemon_ioctl(struct file *filp, u32 cmd, + unsigned long arg) +{ + + long error; + + struct sep_device *sep = filp->private_data; + + dev_dbg(&sep->pdev->dev, + "daemon ioctl: start\n"); + + dev_dbg(&sep->pdev->dev, + "daemon ioctl: cmd is %x\n", cmd); + + /* check that the command is for sep device */ + if (_IOC_TYPE(cmd) != SEP_IOC_MAGIC_NUMBER) { + error = -ENOTTY; + goto end_function; + } + + /* only one process can access ioctl at any given time */ + mutex_lock(&sep->ioctl_mutex); + + switch (cmd) { + case SEP_IOCSENDSEPRPLYCOMMAND: + + /* send reply command to SEP */ + error = sep_req_daemon_send_reply_command_handler(sep); + break; + + case SEP_IOCENDTRANSACTION: + + /* + * end req daemon transaction, do nothing + * will be removed upon update in middleware + * API library + */ + error = 0; + break; + + default: + dev_dbg(&sep->pdev->dev, + "daemon ioctl: no such IOCTL\n"); + error = -ENOTTY; + } + + mutex_unlock(&sep->ioctl_mutex); + +end_function: + + dev_dbg(&sep->pdev->dev, + "daemon ioctl: end\n"); + return error; + +} + +/** + * sep_inthandler - Interrupt Handler + * @irq: interrupt + * @dev_id: device id + */ + +static irqreturn_t sep_inthandler(int irq, void *dev_id) +{ + irqreturn_t int_error = IRQ_HANDLED; + unsigned long lck_flags; + u32 reg_val, reg_val2 = 0; + struct sep_device *sep = dev_id; + + /* read the IRR register to check if this is SEP interrupt */ + reg_val = sep_read_reg(sep, HW_HOST_IRR_REG_ADDR); + dev_dbg(&sep->pdev->dev, + "SEP Interrupt - reg is %08x\n", reg_val); + + if (reg_val & (0x1 << 13)) { + + /* lock and update the counter of reply messages */ + spin_lock_irqsave(&sep->snd_rply_lck, lck_flags); + sep->reply_ct++; + spin_unlock_irqrestore(&sep->snd_rply_lck, lck_flags); + + dev_dbg(&sep->pdev->dev, "sep int: send_ct %lx reply_ct %lx\n", + sep->send_ct, sep->reply_ct); + + /* is this printf or daemon request? */ + reg_val2 = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR2_REG_ADDR); + dev_dbg(&sep->pdev->dev, + "SEP Interrupt - reg2 is %08x\n", reg_val2); + + if ((reg_val2 >> 30) & 0x1) { + + dev_dbg(&sep->pdev->dev, "int: printf request\n"); + wake_up(&sep->event_request_daemon); + } + + else if (reg_val2 >> 31) { + + dev_dbg(&sep->pdev->dev, "int: daemon request\n"); + wake_up(&sep->event_request_daemon); + } else { + + dev_dbg(&sep->pdev->dev, "int: sep reply\n"); + wake_up(&sep->event); + } + + } else { + + dev_dbg(&sep->pdev->dev, "int: not sep interrupt\n"); + int_error = IRQ_NONE; + } + + if (int_error == IRQ_HANDLED) + sep_write_reg(sep, HW_HOST_ICR_REG_ADDR, reg_val); + + return int_error; +} + +/** + * sep_callback - + * Function that is called by rar_register when it is ready with + * a region (only for Moorestown) + * @sep_context_pointer: pointer to struct sep_device + */ +static int sep_callback(unsigned long sep_context_pointer) +{ + int error = 0; + struct sep_device *sep = + (struct sep_device *)sep_context_pointer; + + dma_addr_t rar_end_address = 0; + + dev_dbg(&sep->pdev->dev, "callback start\n"); + + error = rar_get_address(RAR_TYPE_IMAGE, &sep->rar_bus, + &rar_end_address); + + if (error) { + dev_warn(&sep->pdev->dev, "mrst cant get rar region\n"); + goto end_function; + } + + sep->rar_size = (size_t)(rar_end_address - sep->rar_bus + 1); + + if (!request_mem_region(sep->rar_bus, sep->rar_size, + "sep_sec_driver")) { + dev_warn(&sep->pdev->dev, + "request mem region for mrst failed\n"); + error = -1; + goto end_function; + } + + sep->rar_addr = ioremap_nocache(sep->rar_bus, sep->rar_size); + if (!sep->rar_addr) { + dev_warn(&sep->pdev->dev, + "ioremap nocache for mrst rar failed\n"); + error = -1; + goto end_function; + } + + dev_dbg(&sep->pdev->dev, "rar start is %p, phy is %llx," + " size is %x\n", + sep->rar_addr, (unsigned long long)sep->rar_bus, + sep->rar_size); + +end_function: + + dev_dbg(&sep->pdev->dev, "callback end\n"); + return error; +} + +/** + * sep_probe - + * Function that is activated on the successful probe of the SEP device + * @pdev: pci_device + * @end: pci_device_id + */ +static int __devinit sep_probe(struct pci_dev *pdev, + const struct pci_device_id *ent) +{ + int error = 0; + struct sep_device *sep; + + pr_debug("Sep pci probe starting\n"); + if (sep_dev != NULL) { + dev_warn(&pdev->dev, "only one SEP supported.\n"); + return -EBUSY; + } + + /* enable the device */ + error = pci_enable_device(pdev); + if (error) { + dev_warn(&pdev->dev, "error enabling pci device\n"); + goto end_function; + } + + /* allocate the sep_device structure for this device */ + sep_dev = kmalloc(sizeof(struct sep_device), GFP_ATOMIC); + + if (sep_dev == NULL) { + dev_warn(&pdev->dev, + "can't kmalloc the sep_device structure\n"); + return -ENOMEM; + } + + /* zero out sep structure */ + memset((void *)sep_dev, 0, sizeof(struct sep_device)); + + /* + * we're going to use another variable for actually + * working with the device; this way, if we have + * multiple devices in the future, it would be easier + * to make appropriate changes + */ + sep = sep_dev; + + sep->pdev = pdev; + + if (pdev->device == MRST_PCI_DEVICE_ID) + sep->mrst = 1; + else + sep->mrst = 0; + + dev_dbg(&sep->pdev->dev, "PCI obtained, device being prepared\n"); + dev_dbg(&sep->pdev->dev, "revision is %d\n", sep->pdev->revision); + + /* set up our register area */ + sep->reg_physical_addr = pci_resource_start(sep->pdev, 0); + if (!sep->reg_physical_addr) { + dev_warn(&sep->pdev->dev, "Error getting register start\n"); + pci_dev_put(sep->pdev); + return -ENODEV; + } + + sep->reg_physical_end = pci_resource_end(sep->pdev, 0); + if (!sep->reg_physical_end) { + dev_warn(&sep->pdev->dev, "Error getting register end\n"); + pci_dev_put(sep->pdev); + return -ENODEV; + } + + sep->reg_addr = ioremap_nocache(sep->reg_physical_addr, + (size_t)(sep->reg_physical_end - sep->reg_physical_addr + 1)); + if (!sep->reg_addr) { + dev_warn(&sep->pdev->dev, "Error getting register virtual\n"); + pci_dev_put(sep->pdev); + return -ENODEV; + } + + dev_dbg(&sep->pdev->dev, + "Register area start %llx end %llx virtual %p\n", + (unsigned long long)sep->reg_physical_addr, + (unsigned long long)sep->reg_physical_end, + sep->reg_addr); + + /* allocate the shared area */ + sep->shared_size = SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES + + SYNCHRONIC_DMA_TABLES_AREA_SIZE_BYTES + + SEP_DRIVER_DATA_POOL_SHARED_AREA_SIZE_IN_BYTES + + SEP_DRIVER_STATIC_AREA_SIZE_IN_BYTES + + SEP_DRIVER_SYSTEM_DATA_MEMORY_SIZE_IN_BYTES; + + if (sep_map_and_alloc_shared_area(sep)) { + error = -ENOMEM; + /* allocation failed */ + goto end_function_error; + } + + /* the next section depends on type of unit */ + if (sep->mrst) { + error = register_rar(RAR_TYPE_IMAGE, &sep_callback, + (unsigned long)sep); + if (error) { + dev_dbg(&sep->pdev->dev, + "error register_rar\n"); + goto end_function_deallocate_sep_shared_area; + } + } else { + + sep->rar_size = FAKE_RAR_SIZE; + sep->rar_addr = dma_alloc_coherent(NULL, + sep->rar_size, &sep->rar_bus, GFP_KERNEL); + if (sep->rar_addr == NULL) { + dev_warn(&sep->pdev->dev, "cant allocate mfld rar\n"); + error = -ENOMEM; + goto end_function_deallocate_sep_shared_area; + } + + dev_dbg(&sep->pdev->dev, "rar start is %p, phy is %llx," + " size is %x\n", sep->rar_addr, + (unsigned long long)sep->rar_bus, + sep->rar_size); + } + + dev_dbg(&sep->pdev->dev, + "about to write IMR and ICR REG_ADDR\n"); + + /* clear ICR register */ + sep_write_reg(sep, HW_HOST_ICR_REG_ADDR, 0xFFFFFFFF); + + /* set the IMR register - open only GPR 2 */ + sep_write_reg(sep, HW_HOST_IMR_REG_ADDR, (~(0x1 << 13))); + + dev_dbg(&sep->pdev->dev, + "about to call request_irq\n"); + /* get the interrupt line */ + error = request_irq(pdev->irq, sep_inthandler, IRQF_SHARED, + "sep_driver", sep); + + if (error) + goto end_function_free_res; + + goto end_function; + +end_function_free_res: + if (sep->rar_addr) + dma_free_coherent(&sep->pdev->dev, sep->rar_size, + sep->rar_addr, sep->rar_bus); + goto end_function; + +end_function_deallocate_sep_shared_area: + /* de-allocate shared area */ + sep_unmap_and_free_shared_area(sep); + +end_function_error: + iounmap(sep->reg_addr); + kfree(sep_dev); + sep_dev = NULL; + +end_function: + return error; +} + +static DEFINE_PCI_DEVICE_TABLE(sep_pci_id_tbl) = { + {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MRST_PCI_DEVICE_ID)}, + {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MFLD_PCI_DEVICE_ID)}, + {0} +}; + +MODULE_DEVICE_TABLE(pci, sep_pci_id_tbl); + +/* field for registering driver to PCI device */ +static struct pci_driver sep_pci_driver = { + .name = "sep_sec_driver", + .id_table = sep_pci_id_tbl, + .probe = sep_probe + /* FIXME: remove handler */ +}; + +/* file operation for singleton sep operations */ +static const struct file_operations singleton_file_operations = { + .owner = THIS_MODULE, + .unlocked_ioctl = sep_singleton_ioctl, + .poll = sep_poll, + .open = sep_singleton_open, + .release = sep_singleton_release, + .mmap = sep_mmap, +}; + +/* file operation for daemon operations */ +static const struct file_operations daemon_file_operations = { + .owner = THIS_MODULE, + .unlocked_ioctl = sep_request_daemon_ioctl, + .poll = sep_request_daemon_poll, + .open = sep_request_daemon_open, + .release = sep_request_daemon_release, + .mmap = sep_request_daemon_mmap, +}; + +/* the files operations structure of the driver */ +static const struct file_operations sep_file_operations = { + .owner = THIS_MODULE, + .unlocked_ioctl = sep_ioctl, + .poll = sep_poll, + .open = sep_open, + .release = sep_release, + .mmap = sep_mmap, +}; + +/** + * sep_reconfig_shared_area - + * reconfig the shared area between HOST and SEP - needed in case + * the DX_CC_Init function was called before OS loading + * @sep: pointer to struct sep_device + */ +static int sep_reconfig_shared_area(struct sep_device *sep) +{ + int ret_val = 0; + + dev_dbg(&sep->pdev->dev, "reconfig shared area start\n"); + + /* send the new SHARED MESSAGE AREA to the SEP */ + dev_dbg(&sep->pdev->dev, "sending %08llx to sep\n", + (unsigned long long)sep->shared_bus); + + sep_write_reg(sep, HW_HOST_HOST_SEP_GPR1_REG_ADDR, + sep->shared_bus); + + /* poll for SEP response */ + ret_val = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR1_REG_ADDR); + + while (ret_val != 0xffffffff && + ret_val != sep->shared_bus) { + + ret_val = sep_read_reg(sep, + HW_HOST_SEP_HOST_GPR1_REG_ADDR); + } + + /* check the return value (register) */ + if (ret_val != sep->shared_bus) { + dev_warn(&sep->pdev->dev, "could not reconfig shared area\n"); + dev_warn(&sep->pdev->dev, "result was %x\n", ret_val); + ret_val = -ENOMEM; + } + + else { + ret_val = 0; + } + + dev_dbg(&sep->pdev->dev, "reconfig shared area end\n"); + return ret_val; +} + +/** + * sep_register_driver_to_fs - + * This function registers the driver to the file system + * @sep: pointer to struct sep_device + */ +static int sep_register_driver_to_fs(struct sep_device *sep) +{ + int ret_val = 0; + + sep->miscdev_sep.minor = MISC_DYNAMIC_MINOR; + sep->miscdev_sep.name = SEP_DEV_NAME; + sep->miscdev_sep.fops = &sep_file_operations; + + sep->miscdev_singleton.minor = MISC_DYNAMIC_MINOR; + sep->miscdev_singleton.name = SEP_DEV_SINGLETON; + sep->miscdev_singleton.fops = &singleton_file_operations; + + sep->miscdev_daemon.minor = MISC_DYNAMIC_MINOR; + sep->miscdev_daemon.name = SEP_DEV_DAEMON; + sep->miscdev_daemon.fops = &daemon_file_operations; + + ret_val = misc_register(&sep->miscdev_sep); + if (ret_val) { + dev_warn(&sep->pdev->dev, "misc reg fails for sep %x\n", + ret_val); + return ret_val; + } + + ret_val = misc_register(&sep->miscdev_singleton); + if (ret_val) { + dev_warn(&sep->pdev->dev, "misc reg fails for sing %x\n", + ret_val); + misc_deregister(&sep->miscdev_sep); + return ret_val; + } + + if (!sep->mrst) { + ret_val = misc_register(&sep->miscdev_daemon); + if (ret_val) { + dev_warn(&sep->pdev->dev, + "misc reg fails for dmn %x\n", + ret_val); + misc_deregister(&sep->miscdev_sep); + misc_deregister(&sep->miscdev_singleton); + + return ret_val; + } + } + + return ret_val; +} + +/** + * sep_init - init function; this is the first thing called on boot + */ +static int __init sep_init(void) +{ + int ret_val = 0; + struct sep_device *sep = NULL; + + pr_debug("Sep driver: Init start\n"); + + ret_val = pci_register_driver(&sep_pci_driver); + if (ret_val) { + pr_debug("sep_driver:sep_driver_to_device failed," + " ret_val is %d\n", ret_val); + goto end_function; + } + + sep = sep_dev; + + init_waitqueue_head(&sep->event); + init_waitqueue_head(&sep->event_request_daemon); + spin_lock_init(&sep->snd_rply_lck); + mutex_init(&sep->sep_mutex); + mutex_init(&sep->ioctl_mutex); + + if (sep->mrst == 0) { + ret_val = sep_init_caller_id(sep); + if (ret_val) { + dev_warn(&sep->pdev->dev, + "cant init caller id\n"); + goto end_function_unregister_pci; + } + + } + + /* new chip requires share area reconfigure */ + if (sep->pdev->revision == 4) { /* only for new chip */ + ret_val = sep_reconfig_shared_area(sep); + if (ret_val) + goto end_function_unregister_pci; + } + + /* register driver to fs */ + ret_val = sep_register_driver_to_fs(sep); + if (ret_val) { + dev_warn(&sep->pdev->dev, + "error registering device to file\n"); + goto end_function_unregister_pci; + } + + goto end_function; + +end_function_unregister_pci: + pci_unregister_driver(&sep_pci_driver); + +end_function: + dev_dbg(&sep->pdev->dev, "Init end\n"); + return ret_val; +} + + +/** + * sep_exit - called to unload driver (never called on static compile) + */ +static void __exit sep_exit(void) +{ + struct sep_device *sep; + + sep = sep_dev; + pr_debug("Exit start\n"); + + /* unregister from fs */ + misc_deregister(&sep->miscdev_sep); + misc_deregister(&sep->miscdev_singleton); + misc_deregister(&sep->miscdev_daemon); + + /* free the irq */ + free_irq(sep->pdev->irq, sep); + + /* unregister the driver */ + pci_unregister_driver(&sep_pci_driver); + + /* free shared area */ + if (sep_dev) { + sep_unmap_and_free_shared_area(sep_dev); + dev_dbg(&sep->pdev->dev, + "free pages SEP SHARED AREA\n"); + iounmap((void *) sep_dev->reg_addr); + dev_dbg(&sep->pdev->dev, + "iounmap\n"); + } + pr_debug("release_mem_region\n"); + pr_debug("Exit end\n"); +} + + +module_init(sep_init); +module_exit(sep_exit); + +MODULE_LICENSE("GPL"); diff --git a/drivers/staging/sep/sep_driver_api.h b/drivers/staging/sep/sep_driver_api.h new file mode 100644 index 000000000000..1207722d8b6a --- /dev/null +++ b/drivers/staging/sep/sep_driver_api.h @@ -0,0 +1,309 @@ +/* + * + * sep_driver_api.h - Security Processor Driver api definitions + * + * Copyright(c) 2009,2010 Intel Corporation. All rights reserved. + * Contributions(c) 2009,2010 Discretix. All rights reserved. + * + * 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; version 2 of the License. + * + * 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. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * CONTACTS: + * + * Mark Allyn mark.a.allyn@intel.com + * Jayant Mangalampalli jayant.mangalampalli@intel.com + * + * CHANGES: + * + * 2010.09.14 Upgrade to Medfield + * + */ + +#ifndef __SEP_DRIVER_API_H__ +#define __SEP_DRIVER_API_H__ + +/* Type of request from device */ +#define SEP_DRIVER_SRC_REPLY 1 +#define SEP_DRIVER_SRC_REQ 2 +#define SEP_DRIVER_SRC_PRINTF 3 + + +/*------------------------------------------- + TYPEDEFS +----------------------------------------------*/ + +/* + * Note that several members of these structres are only here + * for campatability with the middleware; they are not used + * by this driver. + * All user space buffer addresses are set to aligned u64 + * in order to ensure compatibility with 64 bit systems + */ + +/* + init command struct; this will go away when SCU does init +*/ +struct init_struct { + /* address that SEP can access for message */ + aligned_u64 message_addr; + + /* message size */ + u32 message_size_in_words; + + /* offset of the init message in the sep sram */ + aligned_u64 sep_sram_addr; + + /* -not used- resident size in bytes*/ + u32 unused_resident_size_in_bytes; + + /* -not used- cache size in bytes*/ + u32 unused_cache_size_in_bytes; + + /* -not used- ext cache current address */ + aligned_u64 unused_extcache_addr; + + /* -not used- ext cache size in bytes*/ + u32 unused_extcache_size_in_bytes; +}; + +struct realloc_ext_struct { + /* -not used- current external cache address */ + aligned_u64 unused_ext_cache_addr; + + /* -not used- external cache size in bytes*/ + u32 unused_ext_cache_size_in_bytes; +}; + +struct alloc_struct { + /* offset from start of shared pool area */ + u32 offset; + /* number of bytes to allocate */ + u32 num_bytes; +}; + +/* + Note that all app addresses are cast as u32; the sep + middleware sends them as fixed 32 bit words +*/ +struct bld_syn_tab_struct { + /* address value of the data in (user space addr) */ + aligned_u64 app_in_address; + + /* size of data in */ + u32 data_in_size; + + /* address of the data out (user space addr) */ + aligned_u64 app_out_address; + + /* the size of the block of the operation - if needed, + every table will be modulo this parameter */ + u32 block_size; + + /* -not used- distinct user/kernel layout */ + bool isKernelVirtualAddress; + +}; + +/* + * command struct for static pool addresses + * Please note that this is a kernel virtual + * address; this will be removed at the next + * release of the Discretix middleware + */ +struct stat_pool_addr_struct { + /* virtual address of the static pool */ + aligned_u64 static_virt_address; +}; + + +/* command struct for getting caller id value and address */ +struct caller_id_struct { + /* pid of the process */ + u32 pid; + /* virtual address of the caller id hash */ + aligned_u64 callerIdAddress; + /* caller id hash size in bytes */ + u32 callerIdSizeInBytes; +}; + +/* + structure that represents DCB +*/ +struct sep_dcblock { + /* physical address of the first input mlli */ + u32 input_mlli_address; + /* num of entries in the first input mlli */ + u32 input_mlli_num_entries; + /* size of data in the first input mlli */ + u32 input_mlli_data_size; + /* physical address of the first output mlli */ + u32 output_mlli_address; + /* num of entries in the first output mlli */ + u32 output_mlli_num_entries; + /* size of data in the first output mlli */ + u32 output_mlli_data_size; + /* pointer to the output virtual tail */ + u32 out_vr_tail_pt; + /* size of tail data */ + u32 tail_data_size; + /* input tail data array */ + u8 tail_data[64]; +}; + +struct sep_caller_id_entry { + int pid; + unsigned char callerIdHash[SEP_CALLER_ID_HASH_SIZE_IN_BYTES]; +}; + +/* + command structure for building dcb block (currently for ext app only +*/ +struct build_dcb_struct { + /* address value of the data in */ + aligned_u64 app_in_address; + /* size of data in */ + u32 data_in_size; + /* address of the data out */ + aligned_u64 app_out_address; + /* the size of the block of the operation - if needed, + every table will be modulo this parameter */ + u32 block_size; + /* the size of the block of the operation - if needed, + every table will be modulo this parameter */ + u32 tail_block_size; +}; + +/** + * @struct sep_dma_map + * + * Structure that contains all information needed for mapping the user pages + * or kernel buffers for dma operations + * + * + */ +struct sep_dma_map { + /* mapped dma address */ + dma_addr_t dma_addr; + /* size of the mapped data */ + size_t size; +}; + +struct sep_dma_resource { + /* array of pointers to the pages that represent + input data for the synchronic DMA action */ + struct page **in_page_array; + + /* array of pointers to the pages that represent out + data for the synchronic DMA action */ + struct page **out_page_array; + + /* number of pages in the sep_in_page_array */ + u32 in_num_pages; + + /* number of pages in the sep_out_page_array */ + u32 out_num_pages; + + /* map array of the input data */ + struct sep_dma_map *in_map_array; + + /* map array of the output data */ + struct sep_dma_map *out_map_array; + + /* number of entries of the input mapp array */ + u32 in_map_num_entries; + + /* number of entries of the output mapp array */ + u32 out_map_num_entries; +}; + + +/* command struct for translating rar handle to bus address + and setting it at predefined location */ +struct rar_hndl_to_bus_struct { + + /* rar handle */ + aligned_u64 rar_handle; +}; + +/* + structure that represent one entry in the DMA LLI table +*/ +struct sep_lli_entry { + /* physical address */ + u32 bus_address; + + /* block size */ + u32 block_size; +}; + +/*---------------------------------------------------------------- + IOCTL command defines + -----------------------------------------------------------------*/ + +/* magic number 1 of the sep IOCTL command */ +#define SEP_IOC_MAGIC_NUMBER 's' + +/* sends interrupt to sep that message is ready */ +#define SEP_IOCSENDSEPCOMMAND \ + _IO(SEP_IOC_MAGIC_NUMBER, 0) + +/* sends interrupt to sep that message is ready */ +#define SEP_IOCSENDSEPRPLYCOMMAND \ + _IO(SEP_IOC_MAGIC_NUMBER, 1) + +/* allocate memory in data pool */ +#define SEP_IOCALLOCDATAPOLL \ + _IOW(SEP_IOC_MAGIC_NUMBER, 2, struct alloc_struct) + +/* create sym dma lli tables */ +#define SEP_IOCCREATESYMDMATABLE \ + _IOW(SEP_IOC_MAGIC_NUMBER, 5, struct bld_syn_tab_struct) + +/* free dynamic data aalocated during table creation */ +#define SEP_IOCFREEDMATABLEDATA \ + _IO(SEP_IOC_MAGIC_NUMBER, 7) + +/* get the static pool area addersses (physical and virtual) */ +#define SEP_IOCGETSTATICPOOLADDR \ + _IOR(SEP_IOC_MAGIC_NUMBER, 8, struct stat_pool_addr_struct) + +/* start sep command */ +#define SEP_IOCSEPSTART \ + _IO(SEP_IOC_MAGIC_NUMBER, 12) + +/* init sep command */ +#define SEP_IOCSEPINIT \ + _IOW(SEP_IOC_MAGIC_NUMBER, 13, struct init_struct) + +/* end transaction command */ +#define SEP_IOCENDTRANSACTION \ + _IO(SEP_IOC_MAGIC_NUMBER, 15) + +/* reallocate external app; unused structure still needed for + * compatability with middleware */ +#define SEP_IOCREALLOCEXTCACHE \ + _IOW(SEP_IOC_MAGIC_NUMBER, 18, struct realloc_ext_struct) + +#define SEP_IOCRARPREPAREMESSAGE \ + _IOW(SEP_IOC_MAGIC_NUMBER, 20, struct rar_hndl_to_bus_struct) + +#define SEP_IOCTLSETCALLERID \ + _IOW(SEP_IOC_MAGIC_NUMBER, 34, struct caller_id_struct) + +#define SEP_IOCPREPAREDCB \ + _IOW(SEP_IOC_MAGIC_NUMBER, 35, struct build_dcb_struct) + +#define SEP_IOCFREEDCB \ + _IO(SEP_IOC_MAGIC_NUMBER, 36) + +#endif diff --git a/drivers/staging/sep/sep_driver_config.h b/drivers/staging/sep/sep_driver_config.h new file mode 100644 index 000000000000..686a353c8c98 --- /dev/null +++ b/drivers/staging/sep/sep_driver_config.h @@ -0,0 +1,428 @@ +/* + * + * sep_driver_config.h - Security Processor Driver configuration + * + * Copyright(c) 2009,2010 Intel Corporation. All rights reserved. + * Contributions(c) 2009,2010 Discretix. All rights reserved. + * + * 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; version 2 of the License. + * + * 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. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * CONTACTS: + * + * Mark Allyn mark.a.allyn@intel.com + * Jayant Mangalampalli jayant.mangalampalli@intel.com + * + * CHANGES: + * + * 2010.06.26 Upgrade to Medfield + * + */ + +#ifndef __SEP_DRIVER_CONFIG_H__ +#define __SEP_DRIVER_CONFIG_H__ + + +/*-------------------------------------- + DRIVER CONFIGURATION FLAGS + -------------------------------------*/ + +/* if flag is on , then the driver is running in polling and + not interrupt mode */ +#define SEP_DRIVER_POLLING_MODE 0 + +/* flag which defines if the shared area address should be + reconfiged (send to SEP anew) during init of the driver */ +#define SEP_DRIVER_RECONFIG_MESSAGE_AREA 0 + +/* the mode for running on the ARM1172 Evaluation platform (flag is 1) */ +#define SEP_DRIVER_ARM_DEBUG_MODE 0 + +/*------------------------------------------- + INTERNAL DATA CONFIGURATION + -------------------------------------------*/ + +/* flag for the input array */ +#define SEP_DRIVER_IN_FLAG 0 + +/* flag for output array */ +#define SEP_DRIVER_OUT_FLAG 1 + +/* maximum number of entries in one LLI tables */ +#define SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP 31 + +/* minimum data size of the MLLI table */ +#define SEP_DRIVER_MIN_DATA_SIZE_PER_TABLE 16 + +/* flag that signifies tah the lock is +currently held by the proccess (struct file) */ +#define SEP_DRIVER_OWN_LOCK_FLAG 1 + +/* flag that signifies tah the lock is currently NOT +held by the proccess (struct file) */ +#define SEP_DRIVER_DISOWN_LOCK_FLAG 0 + +/* indicates whether driver has mapped/unmapped shared area */ +#define SEP_REQUEST_DAEMON_MAPPED 1 +#define SEP_REQUEST_DAEMON_UNMAPPED 0 + +/*-------------------------------------------------------- + SHARED AREA memory total size is 36K + it is divided is following: + + SHARED_MESSAGE_AREA 8K } + } + STATIC_POOL_AREA 4K } MAPPED AREA ( 24 K) + } + DATA_POOL_AREA 12K } + + SYNCHRONIC_DMA_TABLES_AREA 5K + + placeholder until drver changes + FLOW_DMA_TABLES_AREA 4K + + SYSTEM_MEMORY_AREA 3k + + SYSTEM_MEMORY total size is 3k + it is divided as following: + + TIME_MEMORY_AREA 8B +-----------------------------------------------------------*/ + +#define SEP_DEV_NAME "sep_sec_driver" +#define SEP_DEV_SINGLETON "sep_sec_singleton_driver" +#define SEP_DEV_DAEMON "sep_req_daemon_driver" + + +/* + the maximum length of the message - the rest of the message shared + area will be dedicated to the dma lli tables +*/ +#define SEP_DRIVER_MAX_MESSAGE_SIZE_IN_BYTES (8 * 1024) + +/* the size of the message shared area in pages */ +#define SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES (8 * 1024) + +/* the size of the data pool static area in pages */ +#define SEP_DRIVER_STATIC_AREA_SIZE_IN_BYTES (4 * 1024) + +/* the size of the data pool shared area size in pages */ +#define SEP_DRIVER_DATA_POOL_SHARED_AREA_SIZE_IN_BYTES (16 * 1024) + +/* the size of the message shared area in pages */ +#define SYNCHRONIC_DMA_TABLES_AREA_SIZE_BYTES (1024 * 5) + +/* Placeholder until driver changes */ +#define SEP_DRIVER_FLOW_DMA_TABLES_AREA_SIZE_IN_BYTES (1024 * 4) + +/* system data (time, caller id etc') pool */ +#define SEP_DRIVER_SYSTEM_DATA_MEMORY_SIZE_IN_BYTES (1024 * 3) + +/* the size in bytes of the time memory */ +#define SEP_DRIVER_TIME_MEMORY_SIZE_IN_BYTES 8 + +/* the size in bytes of the RAR parameters memory */ +#define SEP_DRIVER_SYSTEM_RAR_MEMORY_SIZE_IN_BYTES 8 + +/* area size that is mapped - we map the MESSAGE AREA, STATIC POOL and + DATA POOL areas. area must be module 4k */ +#define SEP_DRIVER_MMMAP_AREA_SIZE (1024 * 28) + +/*----------------------------------------------- + offsets of the areas starting from the shared area start address +*/ + +/* message area offset */ +#define SEP_DRIVER_MESSAGE_AREA_OFFSET_IN_BYTES 0 + +/* static pool area offset */ +#define SEP_DRIVER_STATIC_AREA_OFFSET_IN_BYTES \ + (SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES) + +/* data pool area offset */ +#define SEP_DRIVER_DATA_POOL_AREA_OFFSET_IN_BYTES \ + (SEP_DRIVER_STATIC_AREA_OFFSET_IN_BYTES + \ + SEP_DRIVER_STATIC_AREA_SIZE_IN_BYTES) + +/* synhronic dma tables area offset */ +#define SYNCHRONIC_DMA_TABLES_AREA_OFFSET_BYTES \ + (SEP_DRIVER_DATA_POOL_AREA_OFFSET_IN_BYTES + \ + SEP_DRIVER_DATA_POOL_SHARED_AREA_SIZE_IN_BYTES) + +/* system memory offset in bytes */ +#define SEP_DRIVER_SYSTEM_DATA_MEMORY_OFFSET_IN_BYTES \ + (SYNCHRONIC_DMA_TABLES_AREA_OFFSET_BYTES + \ + SYNCHRONIC_DMA_TABLES_AREA_SIZE_BYTES) + +/* offset of the time area */ +#define SEP_DRIVER_SYSTEM_TIME_MEMORY_OFFSET_IN_BYTES \ + (SEP_DRIVER_SYSTEM_DATA_MEMORY_OFFSET_IN_BYTES) + +/* offset of the RAR area */ +#define SEP_DRIVER_SYSTEM_RAR_MEMORY_OFFSET_IN_BYTES \ + (SEP_DRIVER_SYSTEM_TIME_MEMORY_OFFSET_IN_BYTES + \ + SEP_DRIVER_TIME_MEMORY_SIZE_IN_BYTES) + +/* offset of the caller id area */ +#define SEP_CALLER_ID_OFFSET_BYTES \ + (SEP_DRIVER_SYSTEM_RAR_MEMORY_OFFSET_IN_BYTES + \ + SEP_DRIVER_SYSTEM_RAR_MEMORY_SIZE_IN_BYTES) + +/* offset of the DCB area */ +#define SEP_DRIVER_SYSTEM_DCB_MEMORY_OFFSET_IN_BYTES \ + (SEP_DRIVER_SYSTEM_DATA_MEMORY_OFFSET_IN_BYTES + \ + 0x400) + +/* offset of the ext cache area */ +#define SEP_DRIVER_SYSTEM_EXT_CACHE_ADDR_OFFSET_IN_BYTES \ + SEP_DRIVER_SYSTEM_RAR_MEMORY_OFFSET_IN_BYTES + +/* offset of the allocation data pointer area */ +#define SEP_DRIVER_DATA_POOL_ALLOCATION_OFFSET_IN_BYTES \ + (SEP_CALLER_ID_OFFSET_BYTES + \ + SEP_CALLER_ID_HASH_SIZE_IN_BYTES) + +/* the token that defines the start of time address */ +#define SEP_TIME_VAL_TOKEN 0x12345678 + +#define FAKE_RAR_SIZE (1024*1024) /* used only for mfld */ +/* DEBUG LEVEL MASKS */ + +/* size of the caller id hash (sha2) */ +#define SEP_CALLER_ID_HASH_SIZE_IN_BYTES 32 + +/* maximum number of entries in the caller id table */ +#define SEP_CALLER_ID_TABLE_NUM_ENTRIES 20 + +/* maximum number of symetric operation (that require DMA resource) + per one message */ +#define SEP_MAX_NUM_SYNC_DMA_OPS 16 + +/* the token that defines the start of time address */ +#define SEP_RAR_VAL_TOKEN 0xABABABAB + +/* ioctl error that should be returned when trying + to realloc the cache/resident second time */ +#define SEP_ALREADY_INITIALIZED_ERR 12 + +/* bit that locks access to the shared area */ +#define SEP_MMAP_LOCK_BIT 0 + +/* bit that lock access to the poll - after send_command */ +#define SEP_SEND_MSG_LOCK_BIT 1 + +/* the token that defines the static pool address address */ +#define SEP_STATIC_POOL_VAL_TOKEN 0xABBAABBA + +/* the token that defines the data pool pointers address */ +#define SEP_DATA_POOL_POINTERS_VAL_TOKEN 0xEDDEEDDE + +/* the token that defines the data pool pointers address */ +#define SEP_EXT_CACHE_ADDR_VAL_TOKEN 0xBABABABA + +/* rar handler */ +#ifndef CONFIG_MRST_RAR_HANDLER + +/* This stub header is for non Moorestown driver only */ + +/* + * Constants that specify different kinds of RAR regions that could be + * set up. + */ +static __u32 const RAR_TYPE_VIDEO; /* 0 */ +static __u32 const RAR_TYPE_AUDIO = 1; +static __u32 const RAR_TYPE_IMAGE = 2; +static __u32 const RAR_TYPE_DATA = 3; + +/* + * @struct RAR_stat + * + * @brief This structure is used for @c RAR_HANDLER_STAT ioctl and for + * @c RAR_get_stat() user space wrapper function. + */ +struct RAR_stat { + /* Type of RAR memory (e.g., audio vs. video) */ + __u32 type; + + /* + * Total size of RAR memory region. + */ + __u32 capacity; + + /* Size of the largest reservable block. */ + __u32 largest_block_size; +}; + + +/* + * @struct RAR_block_info + * + * @brief The argument for the @c RAR_HANDLER_RESERVE @c ioctl. + * + */ +struct RAR_block_info { + /* Type of RAR memory (e.g., audio vs. video) */ + __u32 type; + + /* Requested size of a block to be reserved in RAR. */ + __u32 size; + + /* Handle that can be used to refer to reserved block. */ + __u32 handle; +}; + +/* + * @struct RAR_buffer + * + * Structure that contains all information related to a given block of + * memory in RAR. It is generally only used when retrieving bus + * addresses. + * + * @note This structure is used only by RAR-enabled drivers, and is + * not intended to be exposed to the user space. + */ +struct RAR_buffer { + /* Structure containing base RAR buffer information */ + struct RAR_block_info info; + + /* Buffer bus address */ + __u32 bus_address; +}; + + +#define RAR_IOCTL_BASE 0xE0 + +/* Reserve RAR block. */ +#define RAR_HANDLER_RESERVE _IOWR(RAR_IOCTL_BASE, 0x00, struct RAR_block_info) + +/* Release previously reserved RAR block. */ +#define RAR_HANDLER_RELEASE _IOW(RAR_IOCTL_BASE, 0x01, __u32) + +/* Get RAR stats. */ +#define RAR_HANDLER_STAT _IOWR(RAR_IOCTL_BASE, 0x02, struct RAR_stat) + + +/* -------------------------------------------------------------- */ +/* Kernel Side RAR Handler Interface */ +/* -------------------------------------------------------------- */ + +/* + * @function rar_reserve + * + * @brief Reserve RAR buffers. + * + * This function will reserve buffers in the restricted access regions + * of given types. + * + * @return Number of successfully reserved buffers. + * Successful buffer reservations will have the corresponding + * @c bus_address field set to a non-zero value in the + * given @a buffers vector. + */ +#define rar_reserve(a, b) ((size_t)NULL) + +/* + * @function rar_release + * + * @brief Release RAR buffers retrieved through call to + * @c rar_reserve() or @c rar_handle_to_bus(). + * + * This function will release RAR buffers that were retrieved through + * a call to @c rar_reserve() or @c rar_handle_to_bus() by + * decrementing the reference count. The RAR buffer will be reclaimed + * when the reference count drops to zero. + * + * @return Number of successfully released buffers. + * Successful releases will have their handle field set to + * zero in the given @a buffers vector. + */ +#define rar_release(a, b) ((size_t)NULL) + +/* + * @function rar_handle_to_bus + * + * @brief Convert a vector of RAR handles to bus addresses. + * + * This function will retrieve the RAR buffer bus addresses, type and + * size corresponding to the RAR handles provided in the @a buffers + * vector. + * + * @return Number of successfully converted buffers. + * The bus address will be set to @c 0 for unrecognized + * handles. + * + * @note The reference count for each corresponding buffer in RAR will + * be incremented. Call @c rar_release() when done with the + * buffers. + */ +#define rar_handle_to_bus(a, b) ((size_t)NULL) + +#else /* using rear memrar */ + +#include "../memrar/memrar.h" + +#endif /* MEMRAR */ + +/* rar_register */ +#ifndef CONFIG_RAR_REGISTER +/* This stub header is for non Moorestown driver only */ + +/* The register_rar function is to used by other device drivers + * to ensure that this driver is ready. As we cannot be sure of + * the compile/execute order of dirvers in ther kernel, it is + * best to give this driver a callback function to call when + * it is ready to give out addresses. The callback function + * would have those steps that continue the initialization of + * a driver that do require a valid RAR address. One of those + * steps would be to call get_rar_address() + * This function return 0 on success an -1 on failure. + */ +#define register_rar(a, b, c) (-ENODEV) + +/* The get_rar_address function is used by other device drivers + * to obtain RAR address information on a RAR. It takes two + * parameter: + * + * int rar_index + * The rar_index is an index to the rar for which you wish to retrieve + * the address information. + * Values can be 0,1, or 2. + * + * struct RAR_address_struct is a pointer to a place to which the function + * can return the address structure for the RAR. + * + * The function returns a 0 upon success or a -1 if there is no RAR + * facility on this system. + */ +#define rar_get_address(a, b, c) (-ENODEV) + +/* The lock_rar function is ued by other device drivers to lock an RAR. + * once an RAR is locked, it stays locked until the next system reboot. + * The function takes one parameter: + * + * int rar_index + * The rar_index is an index to the rar that you want to lock. + * Values can be 0,1, or 2. + * + * The function returns a 0 upon success or a -1 if there is no RAR + * facility on this system. + */ +#define rar_lock(a) (-1) + +#else /* using real RAR_REGISTER */ + +#include "../rar_register/rar_register.h" + +#endif /* CONFIG_RAR_REGISTER */ + +#endif /* SEP DRIVER CONFIG */ diff --git a/drivers/staging/sep/sep_driver_hw_defs.h b/drivers/staging/sep/sep_driver_hw_defs.h new file mode 100644 index 000000000000..29addd7b5dd3 --- /dev/null +++ b/drivers/staging/sep/sep_driver_hw_defs.h @@ -0,0 +1,234 @@ +/* + * + * sep_driver_hw_defs.h - Security Processor Driver hardware definitions + * + * Copyright(c) 2009,2010 Intel Corporation. All rights reserved. + * Contributions(c) 2009,2010 Discretix. All rights reserved. + * + * 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; version 2 of the License. + * + * 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. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * CONTACTS: + * + * Mark Allyn mark.a.allyn@intel.com + * Jayant Mangalampalli jayant.mangalampalli@intel.com + * + * CHANGES: + * + * 2010.09.20 Upgrade to Medfield + * + */ + +#ifndef SEP_DRIVER_HW_DEFS__H +#define SEP_DRIVER_HW_DEFS__H + +/* PCI ID's */ +#define MRST_PCI_DEVICE_ID 0x080c +#define MFLD_PCI_DEVICE_ID 0x0826 + +/*----------------------- */ +/* HW Registers Defines. */ +/* */ +/*---------------------- -*/ + + +/* cf registers */ +#define HW_R0B_ADDR_0_REG_ADDR 0x0000UL +#define HW_R0B_ADDR_1_REG_ADDR 0x0004UL +#define HW_R0B_ADDR_2_REG_ADDR 0x0008UL +#define HW_R0B_ADDR_3_REG_ADDR 0x000cUL +#define HW_R0B_ADDR_4_REG_ADDR 0x0010UL +#define HW_R0B_ADDR_5_REG_ADDR 0x0014UL +#define HW_R0B_ADDR_6_REG_ADDR 0x0018UL +#define HW_R0B_ADDR_7_REG_ADDR 0x001cUL +#define HW_R0B_ADDR_8_REG_ADDR 0x0020UL +#define HW_R2B_ADDR_0_REG_ADDR 0x0080UL +#define HW_R2B_ADDR_1_REG_ADDR 0x0084UL +#define HW_R2B_ADDR_2_REG_ADDR 0x0088UL +#define HW_R2B_ADDR_3_REG_ADDR 0x008cUL +#define HW_R2B_ADDR_4_REG_ADDR 0x0090UL +#define HW_R2B_ADDR_5_REG_ADDR 0x0094UL +#define HW_R2B_ADDR_6_REG_ADDR 0x0098UL +#define HW_R2B_ADDR_7_REG_ADDR 0x009cUL +#define HW_R2B_ADDR_8_REG_ADDR 0x00a0UL +#define HW_R3B_REG_ADDR 0x00C0UL +#define HW_R4B_REG_ADDR 0x0100UL +#define HW_CSA_ADDR_0_REG_ADDR 0x0140UL +#define HW_CSA_ADDR_1_REG_ADDR 0x0144UL +#define HW_CSA_ADDR_2_REG_ADDR 0x0148UL +#define HW_CSA_ADDR_3_REG_ADDR 0x014cUL +#define HW_CSA_ADDR_4_REG_ADDR 0x0150UL +#define HW_CSA_ADDR_5_REG_ADDR 0x0154UL +#define HW_CSA_ADDR_6_REG_ADDR 0x0158UL +#define HW_CSA_ADDR_7_REG_ADDR 0x015cUL +#define HW_CSA_ADDR_8_REG_ADDR 0x0160UL +#define HW_CSA_REG_ADDR 0x0140UL +#define HW_SINB_REG_ADDR 0x0180UL +#define HW_SOUTB_REG_ADDR 0x0184UL +#define HW_PKI_CONTROL_REG_ADDR 0x01C0UL +#define HW_PKI_STATUS_REG_ADDR 0x01C4UL +#define HW_PKI_BUSY_REG_ADDR 0x01C8UL +#define HW_PKI_A_1025_REG_ADDR 0x01CCUL +#define HW_PKI_SDMA_CTL_REG_ADDR 0x01D0UL +#define HW_PKI_SDMA_OFFSET_REG_ADDR 0x01D4UL +#define HW_PKI_SDMA_POINTERS_REG_ADDR 0x01D8UL +#define HW_PKI_SDMA_DLENG_REG_ADDR 0x01DCUL +#define HW_PKI_SDMA_EXP_POINTERS_REG_ADDR 0x01E0UL +#define HW_PKI_SDMA_RES_POINTERS_REG_ADDR 0x01E4UL +#define HW_PKI_CLR_REG_ADDR 0x01E8UL +#define HW_PKI_SDMA_BUSY_REG_ADDR 0x01E8UL +#define HW_PKI_SDMA_FIRST_EXP_N_REG_ADDR 0x01ECUL +#define HW_PKI_SDMA_MUL_BY1_REG_ADDR 0x01F0UL +#define HW_PKI_SDMA_RMUL_SEL_REG_ADDR 0x01F4UL +#define HW_DES_KEY_0_REG_ADDR 0x0208UL +#define HW_DES_KEY_1_REG_ADDR 0x020CUL +#define HW_DES_KEY_2_REG_ADDR 0x0210UL +#define HW_DES_KEY_3_REG_ADDR 0x0214UL +#define HW_DES_KEY_4_REG_ADDR 0x0218UL +#define HW_DES_KEY_5_REG_ADDR 0x021CUL +#define HW_DES_CONTROL_0_REG_ADDR 0x0220UL +#define HW_DES_CONTROL_1_REG_ADDR 0x0224UL +#define HW_DES_IV_0_REG_ADDR 0x0228UL +#define HW_DES_IV_1_REG_ADDR 0x022CUL +#define HW_AES_KEY_0_ADDR_0_REG_ADDR 0x0400UL +#define HW_AES_KEY_0_ADDR_1_REG_ADDR 0x0404UL +#define HW_AES_KEY_0_ADDR_2_REG_ADDR 0x0408UL +#define HW_AES_KEY_0_ADDR_3_REG_ADDR 0x040cUL +#define HW_AES_KEY_0_ADDR_4_REG_ADDR 0x0410UL +#define HW_AES_KEY_0_ADDR_5_REG_ADDR 0x0414UL +#define HW_AES_KEY_0_ADDR_6_REG_ADDR 0x0418UL +#define HW_AES_KEY_0_ADDR_7_REG_ADDR 0x041cUL +#define HW_AES_KEY_0_REG_ADDR 0x0400UL +#define HW_AES_IV_0_ADDR_0_REG_ADDR 0x0440UL +#define HW_AES_IV_0_ADDR_1_REG_ADDR 0x0444UL +#define HW_AES_IV_0_ADDR_2_REG_ADDR 0x0448UL +#define HW_AES_IV_0_ADDR_3_REG_ADDR 0x044cUL +#define HW_AES_IV_0_REG_ADDR 0x0440UL +#define HW_AES_CTR1_ADDR_0_REG_ADDR 0x0460UL +#define HW_AES_CTR1_ADDR_1_REG_ADDR 0x0464UL +#define HW_AES_CTR1_ADDR_2_REG_ADDR 0x0468UL +#define HW_AES_CTR1_ADDR_3_REG_ADDR 0x046cUL +#define HW_AES_CTR1_REG_ADDR 0x0460UL +#define HW_AES_SK_REG_ADDR 0x0478UL +#define HW_AES_MAC_OK_REG_ADDR 0x0480UL +#define HW_AES_PREV_IV_0_ADDR_0_REG_ADDR 0x0490UL +#define HW_AES_PREV_IV_0_ADDR_1_REG_ADDR 0x0494UL +#define HW_AES_PREV_IV_0_ADDR_2_REG_ADDR 0x0498UL +#define HW_AES_PREV_IV_0_ADDR_3_REG_ADDR 0x049cUL +#define HW_AES_PREV_IV_0_REG_ADDR 0x0490UL +#define HW_AES_CONTROL_REG_ADDR 0x04C0UL +#define HW_HASH_H0_REG_ADDR 0x0640UL +#define HW_HASH_H1_REG_ADDR 0x0644UL +#define HW_HASH_H2_REG_ADDR 0x0648UL +#define HW_HASH_H3_REG_ADDR 0x064CUL +#define HW_HASH_H4_REG_ADDR 0x0650UL +#define HW_HASH_H5_REG_ADDR 0x0654UL +#define HW_HASH_H6_REG_ADDR 0x0658UL +#define HW_HASH_H7_REG_ADDR 0x065CUL +#define HW_HASH_H8_REG_ADDR 0x0660UL +#define HW_HASH_H9_REG_ADDR 0x0664UL +#define HW_HASH_H10_REG_ADDR 0x0668UL +#define HW_HASH_H11_REG_ADDR 0x066CUL +#define HW_HASH_H12_REG_ADDR 0x0670UL +#define HW_HASH_H13_REG_ADDR 0x0674UL +#define HW_HASH_H14_REG_ADDR 0x0678UL +#define HW_HASH_H15_REG_ADDR 0x067CUL +#define HW_HASH_CONTROL_REG_ADDR 0x07C0UL +#define HW_HASH_PAD_EN_REG_ADDR 0x07C4UL +#define HW_HASH_PAD_CFG_REG_ADDR 0x07C8UL +#define HW_HASH_CUR_LEN_0_REG_ADDR 0x07CCUL +#define HW_HASH_CUR_LEN_1_REG_ADDR 0x07D0UL +#define HW_HASH_CUR_LEN_2_REG_ADDR 0x07D4UL +#define HW_HASH_CUR_LEN_3_REG_ADDR 0x07D8UL +#define HW_HASH_PARAM_REG_ADDR 0x07DCUL +#define HW_HASH_INT_BUSY_REG_ADDR 0x07E0UL +#define HW_HASH_SW_RESET_REG_ADDR 0x07E4UL +#define HW_HASH_ENDIANESS_REG_ADDR 0x07E8UL +#define HW_HASH_DATA_REG_ADDR 0x07ECUL +#define HW_DRNG_CONTROL_REG_ADDR 0x0800UL +#define HW_DRNG_VALID_REG_ADDR 0x0804UL +#define HW_DRNG_DATA_REG_ADDR 0x0808UL +#define HW_RND_SRC_EN_REG_ADDR 0x080CUL +#define HW_AES_CLK_ENABLE_REG_ADDR 0x0810UL +#define HW_DES_CLK_ENABLE_REG_ADDR 0x0814UL +#define HW_HASH_CLK_ENABLE_REG_ADDR 0x0818UL +#define HW_PKI_CLK_ENABLE_REG_ADDR 0x081CUL +#define HW_CLK_STATUS_REG_ADDR 0x0824UL +#define HW_CLK_ENABLE_REG_ADDR 0x0828UL +#define HW_DRNG_SAMPLE_REG_ADDR 0x0850UL +#define HW_RND_SRC_CTL_REG_ADDR 0x0858UL +#define HW_CRYPTO_CTL_REG_ADDR 0x0900UL +#define HW_CRYPTO_STATUS_REG_ADDR 0x090CUL +#define HW_CRYPTO_BUSY_REG_ADDR 0x0910UL +#define HW_AES_BUSY_REG_ADDR 0x0914UL +#define HW_DES_BUSY_REG_ADDR 0x0918UL +#define HW_HASH_BUSY_REG_ADDR 0x091CUL +#define HW_CONTENT_REG_ADDR 0x0924UL +#define HW_VERSION_REG_ADDR 0x0928UL +#define HW_CONTEXT_ID_REG_ADDR 0x0930UL +#define HW_DIN_BUFFER_REG_ADDR 0x0C00UL +#define HW_DIN_MEM_DMA_BUSY_REG_ADDR 0x0c20UL +#define HW_SRC_LLI_MEM_ADDR_REG_ADDR 0x0c24UL +#define HW_SRC_LLI_WORD0_REG_ADDR 0x0C28UL +#define HW_SRC_LLI_WORD1_REG_ADDR 0x0C2CUL +#define HW_SRAM_SRC_ADDR_REG_ADDR 0x0c30UL +#define HW_DIN_SRAM_BYTES_LEN_REG_ADDR 0x0c34UL +#define HW_DIN_SRAM_DMA_BUSY_REG_ADDR 0x0C38UL +#define HW_WRITE_ALIGN_REG_ADDR 0x0C3CUL +#define HW_OLD_DATA_REG_ADDR 0x0C48UL +#define HW_WRITE_ALIGN_LAST_REG_ADDR 0x0C4CUL +#define HW_DOUT_BUFFER_REG_ADDR 0x0C00UL +#define HW_DST_LLI_WORD0_REG_ADDR 0x0D28UL +#define HW_DST_LLI_WORD1_REG_ADDR 0x0D2CUL +#define HW_DST_LLI_MEM_ADDR_REG_ADDR 0x0D24UL +#define HW_DOUT_MEM_DMA_BUSY_REG_ADDR 0x0D20UL +#define HW_SRAM_DEST_ADDR_REG_ADDR 0x0D30UL +#define HW_DOUT_SRAM_BYTES_LEN_REG_ADDR 0x0D34UL +#define HW_DOUT_SRAM_DMA_BUSY_REG_ADDR 0x0D38UL +#define HW_READ_ALIGN_REG_ADDR 0x0D3CUL +#define HW_READ_LAST_DATA_REG_ADDR 0x0D44UL +#define HW_RC4_THRU_CPU_REG_ADDR 0x0D4CUL +#define HW_AHB_SINGLE_REG_ADDR 0x0E00UL +#define HW_SRAM_DATA_REG_ADDR 0x0F00UL +#define HW_SRAM_ADDR_REG_ADDR 0x0F04UL +#define HW_SRAM_DATA_READY_REG_ADDR 0x0F08UL +#define HW_HOST_IRR_REG_ADDR 0x0A00UL +#define HW_HOST_IMR_REG_ADDR 0x0A04UL +#define HW_HOST_ICR_REG_ADDR 0x0A08UL +#define HW_HOST_SEP_SRAM_THRESHOLD_REG_ADDR 0x0A10UL +#define HW_HOST_SEP_BUSY_REG_ADDR 0x0A14UL +#define HW_HOST_SEP_LCS_REG_ADDR 0x0A18UL +#define HW_HOST_CC_SW_RST_REG_ADDR 0x0A40UL +#define HW_HOST_SEP_SW_RST_REG_ADDR 0x0A44UL +#define HW_HOST_FLOW_DMA_SW_INT0_REG_ADDR 0x0A80UL +#define HW_HOST_FLOW_DMA_SW_INT1_REG_ADDR 0x0A84UL +#define HW_HOST_FLOW_DMA_SW_INT2_REG_ADDR 0x0A88UL +#define HW_HOST_FLOW_DMA_SW_INT3_REG_ADDR 0x0A8cUL +#define HW_HOST_FLOW_DMA_SW_INT4_REG_ADDR 0x0A90UL +#define HW_HOST_FLOW_DMA_SW_INT5_REG_ADDR 0x0A94UL +#define HW_HOST_FLOW_DMA_SW_INT6_REG_ADDR 0x0A98UL +#define HW_HOST_FLOW_DMA_SW_INT7_REG_ADDR 0x0A9cUL +#define HW_HOST_SEP_HOST_GPR0_REG_ADDR 0x0B00UL +#define HW_HOST_SEP_HOST_GPR1_REG_ADDR 0x0B04UL +#define HW_HOST_SEP_HOST_GPR2_REG_ADDR 0x0B08UL +#define HW_HOST_SEP_HOST_GPR3_REG_ADDR 0x0B0CUL +#define HW_HOST_HOST_SEP_GPR0_REG_ADDR 0x0B80UL +#define HW_HOST_HOST_SEP_GPR1_REG_ADDR 0x0B84UL +#define HW_HOST_HOST_SEP_GPR2_REG_ADDR 0x0B88UL +#define HW_HOST_HOST_SEP_GPR3_REG_ADDR 0x0B8CUL +#define HW_HOST_HOST_ENDIAN_REG_ADDR 0x0B90UL +#define HW_HOST_HOST_COMM_CLK_EN_REG_ADDR 0x0B94UL +#define HW_CLR_SRAM_BUSY_REG_REG_ADDR 0x0F0CUL +#define HW_CC_SRAM_BASE_ADDRESS 0x5800UL + +#endif /* ifndef HW_DEFS */ -- cgit v1.2.3 From 6f6ffec188b5416642b20ef14034d40cfeb3256e Mon Sep 17 00:00:00 2001 From: Vinod Koul Date: Fri, 19 Nov 2010 15:06:31 +0000 Subject: sst: Change the SST driver PCM interface The PCM interface in SST driver is cmds only, this patch changes the interface to open, close and cmd interface. This allows SST driver to keep easy track of handles open Signed-off-by: Vinod Koul Signed-off-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/staging/intel_sst/intel_sst.h | 8 +- .../staging/intel_sst/intel_sst_app_interface.c | 20 ++-- drivers/staging/intel_sst/intel_sst_common.h | 4 +- .../staging/intel_sst/intel_sst_drv_interface.c | 118 ++++++++++++++------- drivers/staging/intel_sst/intel_sst_fw_ipc.h | 1 + drivers/staging/intel_sst/intel_sst_stream.c | 2 +- .../staging/intel_sst/intel_sst_stream_encoded.c | 9 +- drivers/staging/intel_sst/intelmid.c | 37 +++---- drivers/staging/intel_sst/intelmid_ctrl.c | 13 ++- drivers/staging/intel_sst/intelmid_pvt.c | 10 +- 10 files changed, 134 insertions(+), 88 deletions(-) diff --git a/drivers/staging/intel_sst/intel_sst.h b/drivers/staging/intel_sst/intel_sst.h index 1f19f0d1d316..cb03ff7d1a21 100644 --- a/drivers/staging/intel_sst/intel_sst.h +++ b/drivers/staging/intel_sst/intel_sst.h @@ -29,6 +29,7 @@ * and middleware. * This file is shared between the SST and MAD drivers */ +#include "intel_sst_ioctl.h" #define SST_CARD_NAMES "intel_mid_card" @@ -107,10 +108,15 @@ struct snd_pmic_ops { int (*power_down_pmic) (void); }; +struct intel_sst_pcm_control { + int (*open) (struct snd_sst_params *str_param); + int (*device_control) (int cmd, void *arg); + int (*close) (unsigned int str_id); +}; struct intel_sst_card_ops { char *module_name; unsigned int vendor_id; - int (*control_set) (int control_element, void *value); + struct intel_sst_pcm_control *pcm_control; struct snd_pmic_ops *scard_ops; }; diff --git a/drivers/staging/intel_sst/intel_sst_app_interface.c b/drivers/staging/intel_sst/intel_sst_app_interface.c index 09909559a922..c1ca39ef3646 100644 --- a/drivers/staging/intel_sst/intel_sst_app_interface.c +++ b/drivers/staging/intel_sst/intel_sst_app_interface.c @@ -100,11 +100,15 @@ static int intel_sst_check_device(void) */ int intel_sst_open(struct inode *i_node, struct file *file_ptr) { - int retval = intel_sst_check_device(); - if (retval) - return retval; + unsigned int retval; mutex_lock(&sst_drv_ctx->stream_lock); + retval = intel_sst_check_device(); + if (retval) { + mutex_unlock(&sst_drv_ctx->stream_lock); + return retval; + } + if (sst_drv_ctx->encoded_cnt < MAX_ENC_STREAM) { struct ioctl_pvt_data *data = kzalloc(sizeof(struct ioctl_pvt_data), GFP_KERNEL); @@ -139,12 +143,16 @@ int intel_sst_open(struct inode *i_node, struct file *file_ptr) */ int intel_sst_open_cntrl(struct inode *i_node, struct file *file_ptr) { - int retval = intel_sst_check_device(); - if (retval) - return retval; + unsigned int retval; /* audio manager open */ mutex_lock(&sst_drv_ctx->stream_lock); + retval = intel_sst_check_device(); + if (retval) { + mutex_unlock(&sst_drv_ctx->stream_lock); + return retval; + } + if (sst_drv_ctx->am_cnt < MAX_AM_HANDLES) { sst_drv_ctx->am_cnt++; pr_debug("AM handle opened...\n"); diff --git a/drivers/staging/intel_sst/intel_sst_common.h b/drivers/staging/intel_sst/intel_sst_common.h index bf0ead78bfae..dcc1ebbe1ac6 100644 --- a/drivers/staging/intel_sst/intel_sst_common.h +++ b/drivers/staging/intel_sst/intel_sst_common.h @@ -28,8 +28,8 @@ * Common private declarations for SST */ -#define SST_DRIVER_VERSION "1.2.05" -#define SST_VERSION_NUM 0x1205 +#define SST_DRIVER_VERSION "1.2.09" +#define SST_VERSION_NUM 0x1209 /* driver names */ #define SST_DRV_NAME "intel_sst_driver" diff --git a/drivers/staging/intel_sst/intel_sst_drv_interface.c b/drivers/staging/intel_sst/intel_sst_drv_interface.c index 1165303eeeb4..9ecbff60cacf 100644 --- a/drivers/staging/intel_sst/intel_sst_drv_interface.c +++ b/drivers/staging/intel_sst/intel_sst_drv_interface.c @@ -288,18 +288,27 @@ void sst_process_mad_ops(struct work_struct *work) } return; } + +void send_intial_rx_timeslot(void) +{ + if (sst_drv_ctx->pci_id == SST_MRST_PCI_ID && + sst_drv_ctx->rx_time_slot_status != RX_TIMESLOT_UNINIT + && sst_drv_ctx->pmic_vendor != SND_NC) + sst_enable_rx_timeslot(sst_drv_ctx->rx_time_slot_status); +} + /* - * sst_control_set - Set Control params + * sst_open_pcm_stream - Open PCM interface * - * @control_list: list of controls to be set + * @str_param: parameters of pcm stream * - * This function is called by MID sound card driver to set - * SST/Sound card controls. This is registered with MID driver + * This function is called by MID sound card driver to open + * a new pcm interface */ -int sst_control_set(int control_element, void *value) +int sst_open_pcm_stream(struct snd_sst_params *str_param) { - int retval = 0, str_id = 0; - struct stream_info *stream; + struct stream_info *str_info; + int retval; if (sst_drv_ctx->sst_state == SST_SUSPENDED) { /*LPE is suspended, resume it before proceding*/ @@ -318,53 +327,76 @@ int sst_control_set(int control_element, void *value) pr_err("FW download fail %x, abort\n", retval); return retval; } - if (sst_drv_ctx->pci_id == SST_MRST_PCI_ID && - sst_drv_ctx->rx_time_slot_status != RX_TIMESLOT_UNINIT - && sst_drv_ctx->pmic_vendor != SND_NC) - sst_enable_rx_timeslot( - sst_drv_ctx->rx_time_slot_status); + send_intial_rx_timeslot(); } - switch (control_element) { - case SST_SND_ALLOC: { - struct snd_sst_params *str_param; - struct stream_info *str_info; + if (!str_param) + return -EINVAL; - str_param = (struct snd_sst_params *)value; - BUG_ON(!str_param); - retval = sst_get_stream(str_param); - if (retval >= 0) - sst_drv_ctx->stream_cnt++; + retval = sst_get_stream(str_param); + if (retval > 0) { + sst_drv_ctx->stream_cnt++; str_info = &sst_drv_ctx->streams[retval]; str_info->src = MAD_DRV; - break; } + return retval; +} +/* + * sst_close_pcm_stream - Close PCM interface + * + * @str_id: stream id to be closed + * + * This function is called by MID sound card driver to close + * an existing pcm interface + */ +int sst_close_pcm_stream(unsigned int str_id) +{ + struct stream_info *stream; + + pr_debug("sst: stream free called\n"); + if (sst_validate_strid(str_id)) + return -EINVAL; + stream = &sst_drv_ctx->streams[str_id]; + free_stream_context(str_id); + stream->pcm_substream = NULL; + stream->status = STREAM_UN_INIT; + stream->period_elapsed = NULL; + sst_drv_ctx->stream_cnt--; + pr_debug("sst: will call runtime put now\n"); + return 0; +} + +/* + * sst_device_control - Set Control params + * + * @cmd: control cmd to be set + * @arg: command argument + * + * This function is called by MID sound card driver to set + * SST/Sound card controls for an opened stream. + * This is registered with MID driver + */ +int sst_device_control(int cmd, void *arg) +{ + int retval = 0, str_id = 0; + + switch (cmd) { case SST_SND_PAUSE: case SST_SND_RESUME: case SST_SND_DROP: case SST_SND_START: - sst_drv_ctx->mad_ops.control_op = control_element; - sst_drv_ctx->mad_ops.stream_id = *(int *)value; + sst_drv_ctx->mad_ops.control_op = cmd; + sst_drv_ctx->mad_ops.stream_id = *(int *)arg; queue_work(sst_drv_ctx->mad_wq, &sst_drv_ctx->mad_ops.wq); break; - case SST_SND_FREE: - str_id = *(int *)value; - stream = &sst_drv_ctx->streams[str_id]; - free_stream_context(str_id); - stream->pcm_substream = NULL; - stream->status = STREAM_UN_INIT; - stream->period_elapsed = NULL; - sst_drv_ctx->stream_cnt--; - break; - case SST_SND_STREAM_INIT: { struct pcm_stream_info *str_info; struct stream_info *stream; pr_debug("stream init called\n"); - str_info = (struct pcm_stream_info *)value; + str_info = (struct pcm_stream_info *)arg; str_id = str_info->str_id; retval = sst_validate_strid(str_id); if (retval) @@ -386,7 +418,7 @@ int sst_control_set(int control_element, void *value) struct stream_info *stream; - stream_info = (struct pcm_stream_info *)value; + stream_info = (struct pcm_stream_info *)arg; str_id = stream_info->str_id; retval = sst_validate_strid(str_id); if (retval) @@ -412,7 +444,7 @@ int sst_control_set(int control_element, void *value) break; } case SST_ENABLE_RX_TIME_SLOT: { - int status = *(int *)value; + int status = *(int *)arg; sst_drv_ctx->rx_time_slot_status = status ; sst_enable_rx_timeslot(status); break; @@ -427,8 +459,14 @@ int sst_control_set(int control_element, void *value) } +struct intel_sst_pcm_control pcm_ops = { + .open = sst_open_pcm_stream, + .device_control = sst_device_control, + .close = sst_close_pcm_stream, +}; + struct intel_sst_card_ops sst_pmic_ops = { - .control_set = sst_control_set, + .pcm_control = &pcm_ops, }; /* @@ -458,7 +496,7 @@ int register_sst_card(struct intel_sst_card_ops *card) sst_pmic_ops.module_name = card->module_name; sst_drv_ctx->pmic_state = SND_MAD_INIT_DONE; sst_drv_ctx->rx_time_slot_status = 0; /*default AMIC*/ - card->control_set = sst_pmic_ops.control_set; + card->pcm_control = sst_pmic_ops.pcm_control; sst_drv_ctx->scard_ops->card_status = SND_CARD_UN_INIT; return 0; } else { @@ -484,7 +522,7 @@ EXPORT_SYMBOL_GPL(register_sst_card); */ void unregister_sst_card(struct intel_sst_card_ops *card) { - if (sst_pmic_ops.control_set == card->control_set) { + if (sst_pmic_ops.pcm_control == card->pcm_control) { /* unreg */ sst_pmic_ops.module_name = ""; sst_drv_ctx->pmic_state = SND_MAD_UN_INIT; diff --git a/drivers/staging/intel_sst/intel_sst_fw_ipc.h b/drivers/staging/intel_sst/intel_sst_fw_ipc.h index 9d3c36807e07..1a2f67f0aedc 100644 --- a/drivers/staging/intel_sst/intel_sst_fw_ipc.h +++ b/drivers/staging/intel_sst/intel_sst_fw_ipc.h @@ -31,6 +31,7 @@ */ #define MAX_NUM_STREAMS_MRST 3 +#define MAX_NUM_STREAMS_MFLD 6 #define MAX_NUM_STREAMS 6 #define MAX_DBG_RW_BYTES 80 #define MAX_NUM_SCATTER_BUFFERS 8 diff --git a/drivers/staging/intel_sst/intel_sst_stream.c b/drivers/staging/intel_sst/intel_sst_stream.c index 8f6e1005371d..795e42ab7360 100644 --- a/drivers/staging/intel_sst/intel_sst_stream.c +++ b/drivers/staging/intel_sst/intel_sst_stream.c @@ -47,7 +47,7 @@ */ int sst_check_device_type(u32 device, u32 num_chan, u32 *pcm_slot) { - if (device >= MAX_NUM_STREAMS) { + if (device > MAX_NUM_STREAMS_MFLD) { pr_debug("device type invalid %d\n", device); return -EINVAL; } diff --git a/drivers/staging/intel_sst/intel_sst_stream_encoded.c b/drivers/staging/intel_sst/intel_sst_stream_encoded.c index d4e94f1ec830..028ef8ea9bef 100644 --- a/drivers/staging/intel_sst/intel_sst_stream_encoded.c +++ b/drivers/staging/intel_sst/intel_sst_stream_encoded.c @@ -32,9 +32,9 @@ #include #include #include -#include #ifdef CONFIG_MRST_RAR_HANDLER -#include "../../../drivers/staging/memrar/memrar.h" +#include +#include "../memrar/memrar.h" #endif #include "intel_sst_ioctl.h" #include "intel_sst.h" @@ -880,13 +880,13 @@ static int sst_send_decode_mess(int str_id, struct stream_info *str_info, return retval; } +#ifdef CONFIG_MRST_RAR_HANDLER static int sst_prepare_input_buffers_rar(struct stream_info *str_info, struct snd_sst_dbufs *dbufs, int *input_index, int *in_copied, int *input_index_valid_size, int *new_entry_flag) { int retval = 0; -#ifdef CONFIG_MRST_RAR_HANDLER int i; if (str_info->ops == STREAM_OPS_PLAYBACK_DRM) { @@ -921,9 +921,10 @@ static int sst_prepare_input_buffers_rar(struct stream_info *str_info, str_info->decode_ibuf_type = dbufs->ibufs->type; *in_copied = str_info->decode_isize; } -#endif return retval; } +#endif + /*This function is used to prepare the kernel input buffers with contents before sending for decode*/ static int sst_prepare_input_buffers(struct stream_info *str_info, diff --git a/drivers/staging/intel_sst/intelmid.c b/drivers/staging/intel_sst/intelmid.c index 47b91e500c3c..fb2292186703 100644 --- a/drivers/staging/intel_sst/intelmid.c +++ b/drivers/staging/intel_sst/intelmid.c @@ -104,12 +104,10 @@ static struct snd_pcm_hardware snd_intelmad_stream = { static int snd_intelmad_pcm_trigger(struct snd_pcm_substream *substream, int cmd) { - int ret_val = 0; + int ret_val = 0, str_id; struct snd_intelmad *intelmaddata; struct mad_stream_pvt *stream; - /*struct stream_buffer buffer_to_sst;*/ - - + struct intel_sst_pcm_control *sst_ops; WARN_ON(!substream); @@ -118,38 +116,35 @@ static int snd_intelmad_pcm_trigger(struct snd_pcm_substream *substream, WARN_ON(!intelmaddata->sstdrv_ops); WARN_ON(!intelmaddata->sstdrv_ops->scard_ops); + sst_ops = intelmaddata->sstdrv_ops->pcm_control; + str_id = stream->stream_info.str_id; switch (cmd) { case SNDRV_PCM_TRIGGER_START: pr_debug("Trigger Start\n"); - ret_val = intelmaddata->sstdrv_ops->control_set(SST_SND_START, - &stream->stream_info.str_id); + ret_val = sst_ops->device_control(SST_SND_START, &str_id); if (ret_val) return ret_val; stream->stream_status = RUNNING; stream->substream = substream; - stream->stream_status = RUNNING; break; case SNDRV_PCM_TRIGGER_STOP: pr_debug("in stop\n"); - ret_val = intelmaddata->sstdrv_ops->control_set(SST_SND_DROP, - &stream->stream_info.str_id); + ret_val = sst_ops->device_control(SST_SND_DROP, &str_id); if (ret_val) return ret_val; stream->stream_status = DROPPED; break; case SNDRV_PCM_TRIGGER_PAUSE_PUSH: pr_debug("in pause\n"); - ret_val = intelmaddata->sstdrv_ops->control_set(SST_SND_PAUSE, - &stream->stream_info.str_id); + ret_val = sst_ops->device_control(SST_SND_PAUSE, &str_id); if (ret_val) return ret_val; stream->stream_status = PAUSED; break; case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: pr_debug("in pause release\n"); - ret_val = intelmaddata->sstdrv_ops->control_set(SST_SND_RESUME, - &stream->stream_info.str_id); + ret_val = sst_ops->device_control(SST_SND_RESUME, &str_id); if (ret_val) return ret_val; stream->stream_status = RUNNING; @@ -184,8 +179,8 @@ static int snd_intelmad_pcm_prepare(struct snd_pcm_substream *substream) if (stream->stream_info.str_id) { pr_debug("Prepare called for already set stream\n"); - ret_val = intelmaddata->sstdrv_ops->control_set(SST_SND_DROP, - &stream->stream_info.str_id); + ret_val = intelmaddata->sstdrv_ops->pcm_control->device_control( + SST_SND_DROP, &stream->stream_info.str_id); return ret_val; } @@ -253,8 +248,8 @@ static snd_pcm_uframes_t snd_intelmad_pcm_pointer if (stream->stream_status == INIT) return 0; - ret_val = intelmaddata->sstdrv_ops->control_set(SST_SND_BUFFER_POINTER, - &stream->stream_info); + ret_val = intelmaddata->sstdrv_ops->pcm_control->device_control( + SST_SND_BUFFER_POINTER, &stream->stream_info); if (ret_val) { pr_err("error code = 0x%x\n", ret_val); return ret_val; @@ -280,20 +275,20 @@ static int snd_intelmad_close(struct snd_pcm_substream *substream) { struct snd_intelmad *intelmaddata; struct mad_stream_pvt *stream; - int ret_val = 0; + int ret_val = 0, str_id; WARN_ON(!substream); stream = substream->runtime->private_data; + str_id = stream->stream_info.str_id; - pr_debug("snd_intelmad_close called\n"); + pr_debug("sst: snd_intelmad_close called for %d\n", str_id); intelmaddata = snd_pcm_substream_chip(substream); pr_debug("str id = %d\n", stream->stream_info.str_id); if (stream->stream_info.str_id) { /* SST API to actually stop/free the stream */ - ret_val = intelmaddata->sstdrv_ops->control_set(SST_SND_FREE, - &stream->stream_info.str_id); + ret_val = intelmaddata->sstdrv_ops->pcm_control->close(str_id); if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) intelmaddata->playback_cnt--; else diff --git a/drivers/staging/intel_sst/intelmid_ctrl.c b/drivers/staging/intel_sst/intelmid_ctrl.c index 0d9135715c74..69af0704ce94 100644 --- a/drivers/staging/intel_sst/intelmid_ctrl.c +++ b/drivers/staging/intel_sst/intelmid_ctrl.c @@ -494,6 +494,7 @@ static int snd_intelmad_device_set(struct snd_kcontrol *kcontrol, struct snd_intelmad *intelmaddata; struct snd_pmic_ops *scard_ops; int ret_val = 0, vendor, status; + struct intel_sst_pcm_control *pcm_control; pr_debug("snd_intelmad_device_set called\n"); @@ -521,15 +522,13 @@ static int snd_intelmad_device_set(struct snd_kcontrol *kcontrol, case INPUT_SEL: vendor = intelmaddata->sstdrv_ops->vendor_id; if ((vendor == SND_MX) || (vendor == SND_FS)) { - if (uval->value.enumerated.item[0] == HS_MIC) { + pcm_control = intelmaddata->sstdrv_ops->pcm_control; + if (uval->value.enumerated.item[0] == HS_MIC) status = 1; - intelmaddata->sstdrv_ops-> - control_set(SST_ENABLE_RX_TIME_SLOT, &status); - } else { + else status = 0; - intelmaddata->sstdrv_ops-> - control_set(SST_ENABLE_RX_TIME_SLOT, &status); - } + pcm_control->device_control( + SST_ENABLE_RX_TIME_SLOT, &status); } ret_val = scard_ops->set_input_dev( uval->value.enumerated.item[0]); diff --git a/drivers/staging/intel_sst/intelmid_pvt.c b/drivers/staging/intel_sst/intelmid_pvt.c index 4f9bdf364dca..cb71fe028333 100644 --- a/drivers/staging/intel_sst/intelmid_pvt.c +++ b/drivers/staging/intel_sst/intelmid_pvt.c @@ -95,10 +95,8 @@ int snd_intelmad_alloc_stream(struct snd_pcm_substream *substream) pr_debug("Capture stream,Device %d\n", stream->device); } str_params.device_type = stream->device; - ret_val = intelmaddata->sstdrv_ops->control_set(SST_SND_ALLOC, - &str_params); - pr_debug("SST_SND_PLAY/CAPTURE ret_val = %x\n", - ret_val); + ret_val = intelmaddata->sstdrv_ops->pcm_control->open(&str_params); + pr_debug("sst: SST_SND_PLAY/CAPTURE ret_val = %x\n", ret_val); if (ret_val < 0) return ret_val; @@ -121,8 +119,8 @@ int snd_intelmad_init_stream(struct snd_pcm_substream *substream) stream->stream_info.mad_substream = substream; stream->stream_info.buffer_ptr = 0; stream->stream_info.sfreq = substream->runtime->rate; - ret_val = intelmaddata->sstdrv_ops->control_set(SST_SND_STREAM_INIT, - &stream->stream_info); + ret_val = intelmaddata->sstdrv_ops->pcm_control->device_control( + SST_SND_STREAM_INIT, &stream->stream_info); if (ret_val) pr_err("control_set ret error %d\n", ret_val); return ret_val; -- cgit v1.2.3 From 90abe60b32a4762fff9bef33295e08bc9bb355af Mon Sep 17 00:00:00 2001 From: Vinod Koul Date: Fri, 19 Nov 2010 15:09:50 +0000 Subject: sst: Firmware error codes force number values To avoid mismatch in driver and firmware error codes assign specfic values to each enum. Signed-off-by: Vinod Koul Signed-off-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/staging/intel_sst/intel_sst_fw_ipc.h | 110 +++++++++++++++------------ 1 file changed, 62 insertions(+), 48 deletions(-) diff --git a/drivers/staging/intel_sst/intel_sst_fw_ipc.h b/drivers/staging/intel_sst/intel_sst_fw_ipc.h index 1a2f67f0aedc..75c187672450 100644 --- a/drivers/staging/intel_sst/intel_sst_fw_ipc.h +++ b/drivers/staging/intel_sst/intel_sst_fw_ipc.h @@ -142,73 +142,87 @@ enum sst_error_codes { /* Error code,response to msgId: Description */ /* Common error codes */ SST_SUCCESS = 0, /* Success */ - SST_ERR_INVALID_STREAM_ID, /* Invalid stream ID */ - SST_ERR_INVALID_MSG_ID, /* Invalid message ID */ - SST_ERR_INVALID_STREAM_OP, /* Invalid stream operation request */ - SST_ERR_INVALID_PARAMS, /* Invalid params */ - SST_ERR_INVALID_CODEC, /* Invalid codec type */ - SST_ERR_INVALID_MEDIA_TYPE, /* Invalid media type */ - SST_ERR_STREAM_ERR, /* ANY: Stream control or config or - processing error */ + SST_ERR_INVALID_STREAM_ID = 1, + SST_ERR_INVALID_MSG_ID = 2, + SST_ERR_INVALID_STREAM_OP = 3, + SST_ERR_INVALID_PARAMS = 4, + SST_ERR_INVALID_CODEC = 5, + SST_ERR_INVALID_MEDIA_TYPE = 6, + SST_ERR_STREAM_ERR = 7, /* IPC specific error codes */ - SST_IPC_ERR_CALL_BACK_NOT_REGD, /* Call back for msg not regd */ - SST_IPC_ERR_STREAM_NOT_ALLOCATED, /* Stream is not allocated */ - SST_IPC_ERR_STREAM_ALLOC_FAILED, /* ALLOC:Stream alloc failed */ - SST_IPC_ERR_GET_STREAM_FAILED, /* ALLOC:Get stream id failed*/ - SST_ERR_MOD_NOT_AVAIL, /* SET/GET: Mod(AEC/AGC/ALC) not available */ - SST_ERR_MOD_DNLD_RQD, /* SET/GET: Mod(AEC/AGC/ALC) download required */ - SST_ERR_STREAM_STOPPED, /* ANY: Stream is in stopped state */ - SST_ERR_STREAM_IN_USE, /* ANY: Stream is already in use */ + SST_IPC_ERR_CALL_BACK_NOT_REGD = 8, + SST_IPC_ERR_STREAM_NOT_ALLOCATED = 9, + SST_IPC_ERR_STREAM_ALLOC_FAILED = 10, + SST_IPC_ERR_GET_STREAM_FAILED = 11, + SST_ERR_MOD_NOT_AVAIL = 12, + SST_ERR_MOD_DNLD_RQD = 13, + SST_ERR_STREAM_STOPPED = 14, + SST_ERR_STREAM_IN_USE = 15, /* Capture specific error codes */ - SST_CAP_ERR_INCMPLTE_CAPTURE_MSG,/* ANY:Incomplete message */ - SST_CAP_ERR_CAPTURE_FAIL, /* ANY:Capture op failed */ - SST_CAP_ERR_GET_DDR_NEW_SGLIST, - SST_CAP_ERR_UNDER_RUN, /* lack of input data */ - SST_CAP_ERR_OVERFLOW, /* lack of output space */ + SST_CAP_ERR_INCMPLTE_CAPTURE_MSG = 16, + SST_CAP_ERR_CAPTURE_FAIL = 17, + SST_CAP_ERR_GET_DDR_NEW_SGLIST = 18, + SST_CAP_ERR_UNDER_RUN = 19, + SST_CAP_ERR_OVERFLOW = 20, /* Playback specific error codes*/ - SST_PB_ERR_INCMPLTE_PLAY_MSG, /* ANY: Incomplete message */ - SST_PB_ERR_PLAY_FAIL, /* ANY: Playback operation failed */ - SST_PB_ERR_GET_DDR_NEW_SGLIST, + SST_PB_ERR_INCMPLTE_PLAY_MSG = 21, + SST_PB_ERR_PLAY_FAIL = 22, + SST_PB_ERR_GET_DDR_NEW_SGLIST = 23, /* Codec manager specific error codes */ - SST_LIB_ERR_LIB_DNLD_REQUIRED, /* ALLOC: Codec download required */ - SST_LIB_ERR_LIB_NOT_SUPPORTED, /* Library is not supported */ + SST_LIB_ERR_LIB_DNLD_REQUIRED = 24, + SST_LIB_ERR_LIB_NOT_SUPPORTED = 25, /* Library manager specific error codes */ - SST_SCC_ERR_PREP_DNLD_FAILED, /* Failed to prepare for codec download */ - SST_SCC_ERR_LIB_DNLD_RES_FAILED, /* Lib download resume failed */ + SST_SCC_ERR_PREP_DNLD_FAILED = 26, + SST_SCC_ERR_LIB_DNLD_RES_FAILED = 27, /* Scheduler specific error codes */ - SST_SCH_ERR_FAIL, /* REPORT: */ + SST_SCH_ERR_FAIL = 28, /* DMA specific error codes */ - SST_DMA_ERR_NO_CHNL_AVAILABLE, /* DMA Ch not available */ - SST_DMA_ERR_INVALID_INPUT_PARAMS, /* Invalid input params */ - SST_DMA_ERR_CHNL_ALREADY_SUSPENDED, /* Ch is suspended */ - SST_DMA_ERR_CHNL_ALREADY_STARTED, /* Ch already started */ - SST_DMA_ERR_CHNL_NOT_ENABLED, /* Ch not enabled */ - SST_DMA_ERR_TRANSFER_FAILED, /* Transfer failed */ - SST_SSP_ERR_ALREADY_ENABLED, /* REPORT: SSP already enabled */ - SST_SSP_ERR_ALREADY_DISABLED, /* REPORT: SSP already disabled */ - SST_SSP_ERR_NOT_INITIALIZED, + SST_DMA_ERR_NO_CHNL_AVAILABLE = 29, + SST_DMA_ERR_INVALID_INPUT_PARAMS = 30, + SST_DMA_ERR_CHNL_ALREADY_SUSPENDED = 31, + SST_DMA_ERR_CHNL_ALREADY_STARTED = 32, + SST_DMA_ERR_CHNL_NOT_ENABLED = 33, + SST_DMA_ERR_TRANSFER_FAILED = 34, + + SST_SSP_ERR_ALREADY_ENABLED = 35, + SST_SSP_ERR_ALREADY_DISABLED = 36, + SST_SSP_ERR_NOT_INITIALIZED = 37, + SST_SSP_ERR_SRAM_NO_DMA_DATA = 38, /* Other error codes */ - SST_ERR_MOD_INIT_FAIL, /* Firmware Module init failed */ + SST_ERR_MOD_INIT_FAIL = 39, /* FW init error codes */ - SST_RDR_ERR_IO_DEV_SEL_NOT_ALLOWED, - SST_RDR_ERR_ROUTE_ALREADY_STARTED, - SST_RDR_PREP_CODEC_DNLD_FAILED, + SST_RDR_ERR_IO_DEV_SEL_NOT_ALLOWED = 40, + SST_RDR_ERR_ROUTE_ALREADY_STARTED = 41, + SST_RDR_ERR_IO_DEV_SEL_FAILED = 42, + SST_RDR_PREP_CODEC_DNLD_FAILED = 43, /* Memory debug error codes */ - SST_ERR_DBG_MEM_READ_FAIL, - SST_ERR_DBG_MEM_WRITE_FAIL, - - /* Decode error codes */ - SST_ERR_DEC_NEED_INPUT_BUF, - + SST_ERR_DBG_MEM_READ_FAIL = 44, + SST_ERR_DBG_MEM_WRITE_FAIL = 45, + SST_ERR_INSUFFICIENT_INPUT_SG_LIST = 46, + SST_ERR_INSUFFICIENT_OUTPUT_SG_LIST = 47, + + SST_ERR_BUFFER_NOT_AVAILABLE = 48, + SST_ERR_BUFFER_NOT_ALLOCATED = 49, + SST_ERR_INVALID_REGION_TYPE = 50, + SST_ERR_NULL_PTR = 51, + SST_ERR_INVALID_BUFFER_SIZE = 52, + SST_ERR_INVALID_BUFFER_INDEX = 53, + + /*IIPC specific error codes */ + SST_IIPC_QUEUE_FULL = 54, + SST_IIPC_ERR_MSG_SND_FAILED = 55, + SST_PB_ERR_UNDERRUN_OCCURED = 56, + SST_RDR_INSUFFICIENT_MIXER_BUFFER = 57, + SST_INVALID_TIME_SLOTS = 58, }; enum dbg_mem_data_type { -- cgit v1.2.3 From b21bded7c006a29ccda0b8515c4ae3b49e3b599b Mon Sep 17 00:00:00 2001 From: Vinod Koul Date: Fri, 19 Nov 2010 15:10:39 +0000 Subject: sst: log error returned by scu ipc read/write scu ipc driver fails sometimes to read/write. This add logs with register addr and ret code when these errors occur. Signed-off-by: Vinod Koul Signed-off-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/staging/intel_sst/intelmid_pvt.c | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/drivers/staging/intel_sst/intelmid_pvt.c b/drivers/staging/intel_sst/intelmid_pvt.c index cb71fe028333..3ba9daf67526 100644 --- a/drivers/staging/intel_sst/intelmid_pvt.c +++ b/drivers/staging/intel_sst/intelmid_pvt.c @@ -146,30 +146,29 @@ int sst_sc_reg_access(struct sc_reg_access *sc_access, for (i = 0; i < num_val; i++) { retval = intel_scu_ipc_iowrite8(sc_access[i].reg_addr, sc_access[i].value); - if (retval) { - pr_err("IPC write failed!!! %d\n", retval); - return retval; - } + if (retval) + goto err; } } else if (type == PMIC_READ) { for (i = 0; i < num_val; i++) { retval = intel_scu_ipc_ioread8(sc_access[i].reg_addr, &(sc_access[i].value)); - if (retval) { - pr_err("IPC read failed!!!!!%d\n", retval); - return retval; - } + if (retval) + goto err; } } else { for (i = 0; i < num_val; i++) { retval = intel_scu_ipc_update_register( sc_access[i].reg_addr, sc_access[i].value, sc_access[i].mask); - if (retval) { - pr_err("IPC Modify failed!!!%d\n", retval); - return retval; - } + if (retval) + goto err; } } - return retval; + return 0; +err: + pr_err("IPC failed for cmd %d, %d\n", retval, type); + pr_err("reg:0x%2x addr:0x%2x\n", + sc_access[i].reg_addr, sc_access[i].value); + return retval; } -- cgit v1.2.3 From dca25ebdd09c7aa877f00c2bdbd58c74a909c6f8 Mon Sep 17 00:00:00 2001 From: "Robert P. J. Day" Date: Sun, 21 Nov 2010 08:15:01 -0500 Subject: Fix "forcably" comment typo Signed-off-by: Robert P. J. Day Signed-off-by: Jiri Kosina --- drivers/base/bus.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/base/bus.c b/drivers/base/bus.c index 33c270a64db7..8f0b1ba522f0 100644 --- a/drivers/base/bus.c +++ b/drivers/base/bus.c @@ -976,7 +976,7 @@ struct klist *bus_get_device_klist(struct bus_type *bus) EXPORT_SYMBOL_GPL(bus_get_device_klist); /* - * Yes, this forcably breaks the klist abstraction temporarily. It + * Yes, this forcibly breaks the klist abstraction temporarily. It * just wants to sort the klist, not change reference counts and * take/drop locks rapidly in the process. It does all this while * holding the lock for the list, so objects can't otherwise be -- cgit v1.2.3 From 27641c3f003e7f3b6585c01d8a788883603eb262 Mon Sep 17 00:00:00 2001 From: Mario Kleiner Date: Sat, 23 Oct 2010 04:20:23 +0200 Subject: drm/vblank: Add support for precise vblank timestamping. The DRI2 swap & sync implementation needs precise vblank counts and precise timestamps corresponding to those vblank counts. For conformance to the OpenML OML_sync_control extension specification the DRM timestamp associated with a vblank count should correspond to the start of video scanout of the first scanline of the video frame following the vblank interval for that vblank count. Therefore we need to carry around precise timestamps for vblanks. Currently the DRM and KMS drivers generate timestamps ad-hoc via do_gettimeofday() in some places. The resulting timestamps are sometimes not very precise due to interrupt handling delays, they don't conform to OML_sync_control and some are wrong, as they aren't taken synchronized to the vblank. This patch implements support inside the drm core for precise and robust timestamping. It consists of the following interrelated pieces. 1. Vblank timestamp caching: A per-crtc ringbuffer stores the most recent vblank timestamps corresponding to vblank counts. The ringbuffer can be read out lock-free via the accessor function: struct timeval timestamp; vblankcount = drm_vblank_count_and_time(dev, crtcid, ×tamp). The function returns the current vblank count and the corresponding timestamp for start of video scanout following the vblank interval. It can be used anywhere between enclosing drm_vblank_get(dev, crtcid) and drm_vblank_put(dev,crtcid) statements. It is used inside the drmWaitVblank ioctl and in the vblank event queueing and handling. It should be used by kms drivers for timestamping of bufferswap completion. The timestamp ringbuffer is reinitialized each time vblank irq's get reenabled in drm_vblank_get()/ drm_update_vblank_count(). It is invalidated when vblank irq's get disabled. The ringbuffer is updated inside drm_handle_vblank() at each vblank irq. 2. Calculation of precise vblank timestamps: drm_get_last_vbltimestamp() is used to compute the timestamp for the end of the most recent vblank (if inside active scanout), or the expected end of the current vblank interval (if called inside a vblank interval). The function calls into a new optional kms driver entry point dev->driver->get_vblank_timestamp() which is supposed to provide the precise timestamp. If a kms driver doesn't implement the entry point or if the call fails, a simple do_gettimeofday() timestamp is returned as crude approximation of the true vblank time. A new drm module parameter drm.timestamp_precision_usec allows to disable high precision timestamps (if set to zero) or to specify the maximum acceptable error in the timestamps in microseconds. Kms drivers could implement their get_vblank_timestamp() function in a gpu specific way, as long as returned timestamps conform to OML_sync_control, e.g., by use of gpu specific hardware timestamps. Optionally, kms drivers can simply wrap and use the new utility function drm_calc_vbltimestamp_from_scanoutpos(). This function calls a new optional kms driver function dev->driver->get_scanout_position() which returns the current horizontal and vertical video scanout position of the crtc. The scanout position together with the drm_display_timing of the current video mode is used to calculate elapsed time relative to start of active scanout for the current video frame. This elapsed time is subtracted from the current do_gettimeofday() time to get the timestamp corresponding to start of video scanout. Currently non-interlaced, non-doublescan video modes, with or without panel scaling are handled correctly. Interlaced/ doublescan modes are tbd in a future patch. 3. Filtering of redundant vblank irq's and removal of some race-conditions in the vblank irq enable/disable path: Some gpu's (e.g., Radeon R500/R600) send spurious vblank irq's outside the vblank if vblank irq's get reenabled. These get detected by use of the vblank timestamps and filtered out to avoid miscounting of vblanks. Some race-conditions between the vblank irq enable/disable functions, the vblank irq handler and the gpu itself (updating its hardware vblank counter in the "wrong" moment) are fixed inside vblank_disable_and_save() and drm_update_vblank_count() by use of the vblank timestamps and a new spinlock dev->vblank_time_lock. The time until vblank irq disable is now configurable via a new drm module parameter drm.vblankoffdelay to allow experimentation with timeouts that are much shorter than the current 5 seconds and should allow longer vblank off periods for better power savings. Followup patches will use these new functions to implement precise timestamping for the intel and radeon kms drivers. Signed-off-by: Mario Kleiner Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_crtc_helper.c | 13 +- drivers/gpu/drm/drm_irq.c | 563 ++++++++++++++++++++++++++++++++++++-- drivers/gpu/drm/drm_stub.c | 10 + include/drm/drmP.h | 93 +++++++ include/drm/drm_crtc.h | 9 + 5 files changed, 662 insertions(+), 26 deletions(-) diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c index f7af91cb273d..4c200931a6bc 100644 --- a/drivers/gpu/drm/drm_crtc_helper.c +++ b/drivers/gpu/drm/drm_crtc_helper.c @@ -336,7 +336,7 @@ bool drm_crtc_helper_set_mode(struct drm_crtc *crtc, struct drm_framebuffer *old_fb) { struct drm_device *dev = crtc->dev; - struct drm_display_mode *adjusted_mode, saved_mode; + struct drm_display_mode *adjusted_mode, saved_mode, saved_hwmode; struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private; struct drm_encoder_helper_funcs *encoder_funcs; int saved_x, saved_y; @@ -350,6 +350,7 @@ bool drm_crtc_helper_set_mode(struct drm_crtc *crtc, if (!crtc->enabled) return true; + saved_hwmode = crtc->hwmode; saved_mode = crtc->mode; saved_x = crtc->x; saved_y = crtc->y; @@ -427,11 +428,21 @@ bool drm_crtc_helper_set_mode(struct drm_crtc *crtc, } + /* Store real post-adjustment hardware mode. */ + crtc->hwmode = *adjusted_mode; + + /* Calculate and store various constants which + * are later needed by vblank and swap-completion + * timestamping. They are derived from true hwmode. + */ + drm_calc_timestamping_constants(crtc); + /* XXX free adjustedmode */ drm_mode_destroy(dev, adjusted_mode); /* FIXME: add subpixel order */ done: if (!ret) { + crtc->hwmode = saved_hwmode; crtc->mode = saved_mode; crtc->x = saved_x; crtc->y = saved_y; diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index 9d3a5030b6e1..4e82d0d3c378 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c @@ -40,6 +40,22 @@ #include #include + +/* Access macro for slots in vblank timestamp ringbuffer. */ +#define vblanktimestamp(dev, crtc, count) ( \ + (dev)->_vblank_time[(crtc) * DRM_VBLANKTIME_RBSIZE + \ + ((count) % DRM_VBLANKTIME_RBSIZE)]) + +/* Retry timestamp calculation up to 3 times to satisfy + * drm_timestamp_precision before giving up. + */ +#define DRM_TIMESTAMP_MAXRETRIES 3 + +/* Threshold in nanoseconds for detection of redundant + * vblank irq in drm_handle_vblank(). 1 msec should be ok. + */ +#define DRM_REDUNDANT_VBLIRQ_THRESH_NS 1000000 + /** * Get interrupt from bus id. * @@ -77,6 +93,87 @@ int drm_irq_by_busid(struct drm_device *dev, void *data, return 0; } +/* + * Clear vblank timestamp buffer for a crtc. + */ +static void clear_vblank_timestamps(struct drm_device *dev, int crtc) +{ + memset(&dev->_vblank_time[crtc * DRM_VBLANKTIME_RBSIZE], 0, + DRM_VBLANKTIME_RBSIZE * sizeof(struct timeval)); +} + +/* + * Disable vblank irq's on crtc, make sure that last vblank count + * of hardware and corresponding consistent software vblank counter + * are preserved, even if there are any spurious vblank irq's after + * disable. + */ +static void vblank_disable_and_save(struct drm_device *dev, int crtc) +{ + unsigned long irqflags; + u32 vblcount; + s64 diff_ns; + int vblrc; + struct timeval tvblank; + + /* Prevent vblank irq processing while disabling vblank irqs, + * so no updates of timestamps or count can happen after we've + * disabled. Needed to prevent races in case of delayed irq's. + * Disable preemption, so vblank_time_lock is held as short as + * possible, even under a kernel with PREEMPT_RT patches. + */ + preempt_disable(); + spin_lock_irqsave(&dev->vblank_time_lock, irqflags); + + dev->driver->disable_vblank(dev, crtc); + dev->vblank_enabled[crtc] = 0; + + /* No further vblank irq's will be processed after + * this point. Get current hardware vblank count and + * vblank timestamp, repeat until they are consistent. + * + * FIXME: There is still a race condition here and in + * drm_update_vblank_count() which can cause off-by-one + * reinitialization of software vblank counter. If gpu + * vblank counter doesn't increment exactly at the leading + * edge of a vblank interval, then we can lose 1 count if + * we happen to execute between start of vblank and the + * delayed gpu counter increment. + */ + do { + dev->last_vblank[crtc] = dev->driver->get_vblank_counter(dev, crtc); + vblrc = drm_get_last_vbltimestamp(dev, crtc, &tvblank, 0); + } while (dev->last_vblank[crtc] != dev->driver->get_vblank_counter(dev, crtc)); + + /* Compute time difference to stored timestamp of last vblank + * as updated by last invocation of drm_handle_vblank() in vblank irq. + */ + vblcount = atomic_read(&dev->_vblank_count[crtc]); + diff_ns = timeval_to_ns(&tvblank) - + timeval_to_ns(&vblanktimestamp(dev, crtc, vblcount)); + + /* If there is at least 1 msec difference between the last stored + * timestamp and tvblank, then we are currently executing our + * disable inside a new vblank interval, the tvblank timestamp + * corresponds to this new vblank interval and the irq handler + * for this vblank didn't run yet and won't run due to our disable. + * Therefore we need to do the job of drm_handle_vblank() and + * increment the vblank counter by one to account for this vblank. + * + * Skip this step if there isn't any high precision timestamp + * available. In that case we can't account for this and just + * hope for the best. + */ + if ((vblrc > 0) && (abs(diff_ns) > 1000000)) + atomic_inc(&dev->_vblank_count[crtc]); + + /* Invalidate all timestamps while vblank irq's are off. */ + clear_vblank_timestamps(dev, crtc); + + spin_unlock_irqrestore(&dev->vblank_time_lock, irqflags); + preempt_enable(); +} + static void vblank_disable_fn(unsigned long arg) { struct drm_device *dev = (struct drm_device *)arg; @@ -91,10 +188,7 @@ static void vblank_disable_fn(unsigned long arg) if (atomic_read(&dev->vblank_refcount[i]) == 0 && dev->vblank_enabled[i]) { DRM_DEBUG("disabling vblank on crtc %d\n", i); - dev->last_vblank[i] = - dev->driver->get_vblank_counter(dev, i); - dev->driver->disable_vblank(dev, i); - dev->vblank_enabled[i] = 0; + vblank_disable_and_save(dev, i); } spin_unlock_irqrestore(&dev->vbl_lock, irqflags); } @@ -117,6 +211,7 @@ void drm_vblank_cleanup(struct drm_device *dev) kfree(dev->last_vblank); kfree(dev->last_vblank_wait); kfree(dev->vblank_inmodeset); + kfree(dev->_vblank_time); dev->num_crtcs = 0; } @@ -129,6 +224,8 @@ int drm_vblank_init(struct drm_device *dev, int num_crtcs) setup_timer(&dev->vblank_disable_timer, vblank_disable_fn, (unsigned long)dev); spin_lock_init(&dev->vbl_lock); + spin_lock_init(&dev->vblank_time_lock); + dev->num_crtcs = num_crtcs; dev->vbl_queue = kmalloc(sizeof(wait_queue_head_t) * num_crtcs, @@ -161,6 +258,19 @@ int drm_vblank_init(struct drm_device *dev, int num_crtcs) if (!dev->vblank_inmodeset) goto err; + dev->_vblank_time = kcalloc(num_crtcs * DRM_VBLANKTIME_RBSIZE, + sizeof(struct timeval), GFP_KERNEL); + if (!dev->_vblank_time) + goto err; + + DRM_INFO("Supports vblank timestamp caching Rev 1 (10.10.2010).\n"); + + /* Driver specific high-precision vblank timestamping supported? */ + if (dev->driver->get_vblank_timestamp) + DRM_INFO("Driver supports precise vblank timestamp query.\n"); + else + DRM_INFO("No driver support for vblank timestamp query.\n"); + /* Zero per-crtc vblank stuff */ for (i = 0; i < num_crtcs; i++) { init_waitqueue_head(&dev->vbl_queue[i]); @@ -279,7 +389,7 @@ EXPORT_SYMBOL(drm_irq_install); * * Calls the driver's \c drm_driver_irq_uninstall() function, and stops the irq. */ -int drm_irq_uninstall(struct drm_device * dev) +int drm_irq_uninstall(struct drm_device *dev) { unsigned long irqflags; int irq_enabled, i; @@ -335,7 +445,9 @@ int drm_control(struct drm_device *dev, void *data, { struct drm_control *ctl = data; - /* if we haven't irq we fallback for compatibility reasons - this used to be a separate function in drm_dma.h */ + /* if we haven't irq we fallback for compatibility reasons - + * this used to be a separate function in drm_dma.h + */ switch (ctl->func) { @@ -359,6 +471,287 @@ int drm_control(struct drm_device *dev, void *data, } } +/** + * drm_calc_timestamping_constants - Calculate and + * store various constants which are later needed by + * vblank and swap-completion timestamping, e.g, by + * drm_calc_vbltimestamp_from_scanoutpos(). + * They are derived from crtc's true scanout timing, + * so they take things like panel scaling or other + * adjustments into account. + * + * @crtc drm_crtc whose timestamp constants should be updated. + * + */ +void drm_calc_timestamping_constants(struct drm_crtc *crtc) +{ + s64 linedur_ns = 0, pixeldur_ns = 0, framedur_ns = 0; + u64 dotclock; + + /* Dot clock in Hz: */ + dotclock = (u64) crtc->hwmode.clock * 1000; + + /* Valid dotclock? */ + if (dotclock > 0) { + /* Convert scanline length in pixels and video dot clock to + * line duration, frame duration and pixel duration in + * nanoseconds: + */ + pixeldur_ns = (s64) div64_u64(1000000000, dotclock); + linedur_ns = (s64) div64_u64(((u64) crtc->hwmode.crtc_htotal * + 1000000000), dotclock); + framedur_ns = (s64) crtc->hwmode.crtc_vtotal * linedur_ns; + } else + DRM_ERROR("crtc %d: Can't calculate constants, dotclock = 0!\n", + crtc->base.id); + + crtc->pixeldur_ns = pixeldur_ns; + crtc->linedur_ns = linedur_ns; + crtc->framedur_ns = framedur_ns; + + DRM_DEBUG("crtc %d: hwmode: htotal %d, vtotal %d, vdisplay %d\n", + crtc->base.id, crtc->hwmode.crtc_htotal, + crtc->hwmode.crtc_vtotal, crtc->hwmode.crtc_vdisplay); + DRM_DEBUG("crtc %d: clock %d kHz framedur %d linedur %d, pixeldur %d\n", + crtc->base.id, (int) dotclock/1000, (int) framedur_ns, + (int) linedur_ns, (int) pixeldur_ns); +} +EXPORT_SYMBOL(drm_calc_timestamping_constants); + +/** + * drm_calc_vbltimestamp_from_scanoutpos - helper routine for kms + * drivers. Implements calculation of exact vblank timestamps from + * given drm_display_mode timings and current video scanout position + * of a crtc. This can be called from within get_vblank_timestamp() + * implementation of a kms driver to implement the actual timestamping. + * + * Should return timestamps conforming to the OML_sync_control OpenML + * extension specification. The timestamp corresponds to the end of + * the vblank interval, aka start of scanout of topmost-leftmost display + * pixel in the following video frame. + * + * Requires support for optional dev->driver->get_scanout_position() + * in kms driver, plus a bit of setup code to provide a drm_display_mode + * that corresponds to the true scanout timing. + * + * The current implementation only handles standard video modes. It + * returns as no operation if a doublescan or interlaced video mode is + * active. Higher level code is expected to handle this. + * + * @dev: DRM device. + * @crtc: Which crtc's vblank timestamp to retrieve. + * @max_error: Desired maximum allowable error in timestamps (nanosecs). + * On return contains true maximum error of timestamp. + * @vblank_time: Pointer to struct timeval which should receive the timestamp. + * @flags: Flags to pass to driver: + * 0 = Default. + * DRM_CALLED_FROM_VBLIRQ = If function is called from vbl irq handler. + * @refcrtc: drm_crtc* of crtc which defines scanout timing. + * + * Returns negative value on error, failure or if not supported in current + * video mode: + * + * -EINVAL - Invalid crtc. + * -EAGAIN - Temporary unavailable, e.g., called before initial modeset. + * -ENOTSUPP - Function not supported in current display mode. + * -EIO - Failed, e.g., due to failed scanout position query. + * + * Returns or'ed positive status flags on success: + * + * DRM_VBLANKTIME_SCANOUTPOS_METHOD - Signal this method used for timestamping. + * DRM_VBLANKTIME_INVBL - Timestamp taken while scanout was in vblank interval. + * + */ +int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, int crtc, + int *max_error, + struct timeval *vblank_time, + unsigned flags, + struct drm_crtc *refcrtc) +{ + struct timeval stime, raw_time; + struct drm_display_mode *mode; + int vbl_status, vtotal, vdisplay; + int vpos, hpos, i; + s64 framedur_ns, linedur_ns, pixeldur_ns, delta_ns, duration_ns; + bool invbl; + + if (crtc < 0 || crtc >= dev->num_crtcs) { + DRM_ERROR("Invalid crtc %d\n", crtc); + return -EINVAL; + } + + /* Scanout position query not supported? Should not happen. */ + if (!dev->driver->get_scanout_position) { + DRM_ERROR("Called from driver w/o get_scanout_position()!?\n"); + return -EIO; + } + + mode = &refcrtc->hwmode; + vtotal = mode->crtc_vtotal; + vdisplay = mode->crtc_vdisplay; + + /* Durations of frames, lines, pixels in nanoseconds. */ + framedur_ns = refcrtc->framedur_ns; + linedur_ns = refcrtc->linedur_ns; + pixeldur_ns = refcrtc->pixeldur_ns; + + /* If mode timing undefined, just return as no-op: + * Happens during initial modesetting of a crtc. + */ + if (vtotal <= 0 || vdisplay <= 0 || framedur_ns == 0) { + DRM_DEBUG("crtc %d: Noop due to uninitialized mode.\n", crtc); + return -EAGAIN; + } + + /* Don't know yet how to handle interlaced or + * double scan modes. Just no-op for now. + */ + if (mode->flags & (DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLSCAN)) { + DRM_DEBUG("crtc %d: Noop due to unsupported mode.\n", crtc); + return -ENOTSUPP; + } + + /* Get current scanout position with system timestamp. + * Repeat query up to DRM_TIMESTAMP_MAXRETRIES times + * if single query takes longer than max_error nanoseconds. + * + * This guarantees a tight bound on maximum error if + * code gets preempted or delayed for some reason. + */ + for (i = 0; i < DRM_TIMESTAMP_MAXRETRIES; i++) { + /* Disable preemption to make it very likely to + * succeed in the first iteration even on PREEMPT_RT kernel. + */ + preempt_disable(); + + /* Get system timestamp before query. */ + do_gettimeofday(&stime); + + /* Get vertical and horizontal scanout pos. vpos, hpos. */ + vbl_status = dev->driver->get_scanout_position(dev, crtc, &vpos, &hpos); + + /* Get system timestamp after query. */ + do_gettimeofday(&raw_time); + + preempt_enable(); + + /* Return as no-op if scanout query unsupported or failed. */ + if (!(vbl_status & DRM_SCANOUTPOS_VALID)) { + DRM_DEBUG("crtc %d : scanoutpos query failed [%d].\n", + crtc, vbl_status); + return -EIO; + } + + duration_ns = timeval_to_ns(&raw_time) - timeval_to_ns(&stime); + + /* Accept result with < max_error nsecs timing uncertainty. */ + if (duration_ns <= (s64) *max_error) + break; + } + + /* Noisy system timing? */ + if (i == DRM_TIMESTAMP_MAXRETRIES) { + DRM_DEBUG("crtc %d: Noisy timestamp %d us > %d us [%d reps].\n", + crtc, (int) duration_ns/1000, *max_error/1000, i); + } + + /* Return upper bound of timestamp precision error. */ + *max_error = (int) duration_ns; + + /* Check if in vblank area: + * vpos is >=0 in video scanout area, but negative + * within vblank area, counting down the number of lines until + * start of scanout. + */ + invbl = vbl_status & DRM_SCANOUTPOS_INVBL; + + /* Convert scanout position into elapsed time at raw_time query + * since start of scanout at first display scanline. delta_ns + * can be negative if start of scanout hasn't happened yet. + */ + delta_ns = (s64) vpos * linedur_ns + (s64) hpos * pixeldur_ns; + + /* Is vpos outside nominal vblank area, but less than + * 1/100 of a frame height away from start of vblank? + * If so, assume this isn't a massively delayed vblank + * interrupt, but a vblank interrupt that fired a few + * microseconds before true start of vblank. Compensate + * by adding a full frame duration to the final timestamp. + * Happens, e.g., on ATI R500, R600. + * + * We only do this if DRM_CALLED_FROM_VBLIRQ. + */ + if ((flags & DRM_CALLED_FROM_VBLIRQ) && !invbl && + ((vdisplay - vpos) < vtotal / 100)) { + delta_ns = delta_ns - framedur_ns; + + /* Signal this correction as "applied". */ + vbl_status |= 0x8; + } + + /* Subtract time delta from raw timestamp to get final + * vblank_time timestamp for end of vblank. + */ + *vblank_time = ns_to_timeval(timeval_to_ns(&raw_time) - delta_ns); + + DRM_DEBUG("crtc %d : v %d p(%d,%d)@ %d.%d -> %d.%d [e %d us, %d rep]\n", + crtc, (int) vbl_status, hpos, vpos, raw_time.tv_sec, + raw_time.tv_usec, vblank_time->tv_sec, vblank_time->tv_usec, + (int) duration_ns/1000, i); + + vbl_status = DRM_VBLANKTIME_SCANOUTPOS_METHOD; + if (invbl) + vbl_status |= DRM_VBLANKTIME_INVBL; + + return vbl_status; +} +EXPORT_SYMBOL(drm_calc_vbltimestamp_from_scanoutpos); + +/** + * drm_get_last_vbltimestamp - retrieve raw timestamp for the most recent + * vblank interval. + * + * @dev: DRM device + * @crtc: which crtc's vblank timestamp to retrieve + * @tvblank: Pointer to target struct timeval which should receive the timestamp + * @flags: Flags to pass to driver: + * 0 = Default. + * DRM_CALLED_FROM_VBLIRQ = If function is called from vbl irq handler. + * + * Fetches the system timestamp corresponding to the time of the most recent + * vblank interval on specified crtc. May call into kms-driver to + * compute the timestamp with a high-precision GPU specific method. + * + * Returns zero if timestamp originates from uncorrected do_gettimeofday() + * call, i.e., it isn't very precisely locked to the true vblank. + * + * Returns non-zero if timestamp is considered to be very precise. + */ +u32 drm_get_last_vbltimestamp(struct drm_device *dev, int crtc, + struct timeval *tvblank, unsigned flags) +{ + int ret = 0; + + /* Define requested maximum error on timestamps (nanoseconds). */ + int max_error = (int) drm_timestamp_precision * 1000; + + /* Query driver if possible and precision timestamping enabled. */ + if (dev->driver->get_vblank_timestamp && (max_error > 0)) { + ret = dev->driver->get_vblank_timestamp(dev, crtc, &max_error, + tvblank, flags); + if (ret > 0) + return (u32) ret; + } + + /* GPU high precision timestamp query unsupported or failed. + * Return gettimeofday timestamp as best estimate. + */ + do_gettimeofday(tvblank); + + return 0; +} +EXPORT_SYMBOL(drm_get_last_vbltimestamp); + /** * drm_vblank_count - retrieve "cooked" vblank counter value * @dev: DRM device @@ -374,6 +767,40 @@ u32 drm_vblank_count(struct drm_device *dev, int crtc) } EXPORT_SYMBOL(drm_vblank_count); +/** + * drm_vblank_count_and_time - retrieve "cooked" vblank counter value + * and the system timestamp corresponding to that vblank counter value. + * + * @dev: DRM device + * @crtc: which counter to retrieve + * @vblanktime: Pointer to struct timeval to receive the vblank timestamp. + * + * Fetches the "cooked" vblank count value that represents the number of + * vblank events since the system was booted, including lost events due to + * modesetting activity. Returns corresponding system timestamp of the time + * of the vblank interval that corresponds to the current value vblank counter + * value. + */ +u32 drm_vblank_count_and_time(struct drm_device *dev, int crtc, + struct timeval *vblanktime) +{ + u32 cur_vblank; + + /* Read timestamp from slot of _vblank_time ringbuffer + * that corresponds to current vblank count. Retry if + * count has incremented during readout. This works like + * a seqlock. + */ + do { + cur_vblank = atomic_read(&dev->_vblank_count[crtc]); + *vblanktime = vblanktimestamp(dev, crtc, cur_vblank); + smp_rmb(); + } while (cur_vblank != atomic_read(&dev->_vblank_count[crtc])); + + return cur_vblank; +} +EXPORT_SYMBOL(drm_vblank_count_and_time); + /** * drm_update_vblank_count - update the master vblank counter * @dev: DRM device @@ -392,7 +819,8 @@ EXPORT_SYMBOL(drm_vblank_count); */ static void drm_update_vblank_count(struct drm_device *dev, int crtc) { - u32 cur_vblank, diff; + u32 cur_vblank, diff, tslot, rc; + struct timeval t_vblank; /* * Interrupts were disabled prior to this call, so deal with counter @@ -400,8 +828,18 @@ static void drm_update_vblank_count(struct drm_device *dev, int crtc) * NOTE! It's possible we lost a full dev->max_vblank_count events * here if the register is small or we had vblank interrupts off for * a long time. + * + * We repeat the hardware vblank counter & timestamp query until + * we get consistent results. This to prevent races between gpu + * updating its hardware counter while we are retrieving the + * corresponding vblank timestamp. */ - cur_vblank = dev->driver->get_vblank_counter(dev, crtc); + do { + cur_vblank = dev->driver->get_vblank_counter(dev, crtc); + rc = drm_get_last_vbltimestamp(dev, crtc, &t_vblank, 0); + } while (cur_vblank != dev->driver->get_vblank_counter(dev, crtc)); + + /* Deal with counter wrap */ diff = cur_vblank - dev->last_vblank[crtc]; if (cur_vblank < dev->last_vblank[crtc]) { diff += dev->max_vblank_count; @@ -413,6 +851,16 @@ static void drm_update_vblank_count(struct drm_device *dev, int crtc) DRM_DEBUG("enabling vblank interrupts on crtc %d, missed %d\n", crtc, diff); + /* Reinitialize corresponding vblank timestamp if high-precision query + * available. Skip this step if query unsupported or failed. Will + * reinitialize delayed at next vblank interrupt in that case. + */ + if (rc) { + tslot = atomic_read(&dev->_vblank_count[crtc]) + diff; + vblanktimestamp(dev, crtc, tslot) = t_vblank; + smp_wmb(); + } + atomic_add(diff, &dev->_vblank_count[crtc]); } @@ -429,15 +877,27 @@ static void drm_update_vblank_count(struct drm_device *dev, int crtc) */ int drm_vblank_get(struct drm_device *dev, int crtc) { - unsigned long irqflags; + unsigned long irqflags, irqflags2; int ret = 0; spin_lock_irqsave(&dev->vbl_lock, irqflags); /* Going from 0->1 means we have to enable interrupts again */ if (atomic_add_return(1, &dev->vblank_refcount[crtc]) == 1) { + /* Disable preemption while holding vblank_time_lock. Do + * it explicitely to guard against PREEMPT_RT kernel. + */ + preempt_disable(); + spin_lock_irqsave(&dev->vblank_time_lock, irqflags2); if (!dev->vblank_enabled[crtc]) { + /* Enable vblank irqs under vblank_time_lock protection. + * All vblank count & timestamp updates are held off + * until we are done reinitializing master counter and + * timestamps. Filtercode in drm_handle_vblank() will + * prevent double-accounting of same vblank interval. + */ ret = dev->driver->enable_vblank(dev, crtc); - DRM_DEBUG("enabling vblank on crtc %d, ret: %d\n", crtc, ret); + DRM_DEBUG("enabling vblank on crtc %d, ret: %d\n", + crtc, ret); if (ret) atomic_dec(&dev->vblank_refcount[crtc]); else { @@ -445,6 +905,8 @@ int drm_vblank_get(struct drm_device *dev, int crtc) drm_update_vblank_count(dev, crtc); } } + spin_unlock_irqrestore(&dev->vblank_time_lock, irqflags2); + preempt_enable(); } else { if (!dev->vblank_enabled[crtc]) { atomic_dec(&dev->vblank_refcount[crtc]); @@ -463,15 +925,17 @@ EXPORT_SYMBOL(drm_vblank_get); * @crtc: which counter to give up * * Release ownership of a given vblank counter, turning off interrupts - * if possible. + * if possible. Disable interrupts after drm_vblank_offdelay milliseconds. */ void drm_vblank_put(struct drm_device *dev, int crtc) { - BUG_ON (atomic_read (&dev->vblank_refcount[crtc]) == 0); + BUG_ON(atomic_read(&dev->vblank_refcount[crtc]) == 0); /* Last user schedules interrupt disable */ - if (atomic_dec_and_test(&dev->vblank_refcount[crtc])) - mod_timer(&dev->vblank_disable_timer, jiffies + 5*DRM_HZ); + if (atomic_dec_and_test(&dev->vblank_refcount[crtc]) && + (drm_vblank_offdelay > 0)) + mod_timer(&dev->vblank_disable_timer, + jiffies + ((drm_vblank_offdelay * DRM_HZ)/1000)); } EXPORT_SYMBOL(drm_vblank_put); @@ -480,10 +944,8 @@ void drm_vblank_off(struct drm_device *dev, int crtc) unsigned long irqflags; spin_lock_irqsave(&dev->vbl_lock, irqflags); - dev->driver->disable_vblank(dev, crtc); + vblank_disable_and_save(dev, crtc); DRM_WAKEUP(&dev->vbl_queue[crtc]); - dev->vblank_enabled[crtc] = 0; - dev->last_vblank[crtc] = dev->driver->get_vblank_counter(dev, crtc); spin_unlock_irqrestore(&dev->vbl_lock, irqflags); } EXPORT_SYMBOL(drm_vblank_off); @@ -599,7 +1061,6 @@ static int drm_queue_vblank_event(struct drm_device *dev, int pipe, e->base.file_priv = file_priv; e->base.destroy = (void (*) (struct drm_pending_event *)) kfree; - do_gettimeofday(&now); spin_lock_irqsave(&dev->event_lock, flags); if (file_priv->event_space < sizeof e->event) { @@ -609,7 +1070,8 @@ static int drm_queue_vblank_event(struct drm_device *dev, int pipe, } file_priv->event_space -= sizeof e->event; - seq = drm_vblank_count(dev, pipe); + seq = drm_vblank_count_and_time(dev, pipe, &now); + if ((vblwait->request.type & _DRM_VBLANK_NEXTONMISS) && (seq - vblwait->request.sequence) <= (1 << 23)) { vblwait->request.sequence = seq + 1; @@ -718,11 +1180,10 @@ int drm_wait_vblank(struct drm_device *dev, void *data, if (ret != -EINTR) { struct timeval now; - do_gettimeofday(&now); - + vblwait->reply.sequence = drm_vblank_count_and_time(dev, crtc, &now); vblwait->reply.tval_sec = now.tv_sec; vblwait->reply.tval_usec = now.tv_usec; - vblwait->reply.sequence = drm_vblank_count(dev, crtc); + DRM_DEBUG("returning %d to client\n", vblwait->reply.sequence); } else { @@ -741,8 +1202,7 @@ void drm_handle_vblank_events(struct drm_device *dev, int crtc) unsigned long flags; unsigned int seq; - do_gettimeofday(&now); - seq = drm_vblank_count(dev, crtc); + seq = drm_vblank_count_and_time(dev, crtc, &now); spin_lock_irqsave(&dev->event_lock, flags); @@ -780,11 +1240,64 @@ void drm_handle_vblank_events(struct drm_device *dev, int crtc) */ void drm_handle_vblank(struct drm_device *dev, int crtc) { + u32 vblcount; + s64 diff_ns; + struct timeval tvblank; + unsigned long irqflags; + if (!dev->num_crtcs) return; - atomic_inc(&dev->_vblank_count[crtc]); + /* Need timestamp lock to prevent concurrent execution with + * vblank enable/disable, as this would cause inconsistent + * or corrupted timestamps and vblank counts. + */ + spin_lock_irqsave(&dev->vblank_time_lock, irqflags); + + /* Vblank irq handling disabled. Nothing to do. */ + if (!dev->vblank_enabled[crtc]) { + spin_unlock_irqrestore(&dev->vblank_time_lock, irqflags); + return; + } + + /* Fetch corresponding timestamp for this vblank interval from + * driver and store it in proper slot of timestamp ringbuffer. + */ + + /* Get current timestamp and count. */ + vblcount = atomic_read(&dev->_vblank_count[crtc]); + drm_get_last_vbltimestamp(dev, crtc, &tvblank, DRM_CALLED_FROM_VBLIRQ); + + /* Compute time difference to timestamp of last vblank */ + diff_ns = timeval_to_ns(&tvblank) - + timeval_to_ns(&vblanktimestamp(dev, crtc, vblcount)); + + /* Update vblank timestamp and count if at least + * DRM_REDUNDANT_VBLIRQ_THRESH_NS nanoseconds + * difference between last stored timestamp and current + * timestamp. A smaller difference means basically + * identical timestamps. Happens if this vblank has + * been already processed and this is a redundant call, + * e.g., due to spurious vblank interrupts. We need to + * ignore those for accounting. + */ + if (abs(diff_ns) > DRM_REDUNDANT_VBLIRQ_THRESH_NS) { + /* Store new timestamp in ringbuffer. */ + vblanktimestamp(dev, crtc, vblcount + 1) = tvblank; + smp_wmb(); + + /* Increment cooked vblank count. This also atomically commits + * the timestamp computed above. + */ + atomic_inc(&dev->_vblank_count[crtc]); + } else { + DRM_DEBUG("crtc %d: Redundant vblirq ignored. diff_ns = %d\n", + crtc, (int) diff_ns); + } + DRM_WAKEUP(&dev->vbl_queue[crtc]); drm_handle_vblank_events(dev, crtc); + + spin_unlock_irqrestore(&dev->vblank_time_lock, irqflags); } EXPORT_SYMBOL(drm_handle_vblank); diff --git a/drivers/gpu/drm/drm_stub.c b/drivers/gpu/drm/drm_stub.c index cdc89ee042cc..d59edc18301f 100644 --- a/drivers/gpu/drm/drm_stub.c +++ b/drivers/gpu/drm/drm_stub.c @@ -40,12 +40,22 @@ unsigned int drm_debug = 0; /* 1 to enable debug output */ EXPORT_SYMBOL(drm_debug); +unsigned int drm_vblank_offdelay = 5000; /* Default to 5000 msecs. */ +EXPORT_SYMBOL(drm_vblank_offdelay); + +unsigned int drm_timestamp_precision = 20; /* Default to 20 usecs. */ +EXPORT_SYMBOL(drm_timestamp_precision); + MODULE_AUTHOR(CORE_AUTHOR); MODULE_DESCRIPTION(CORE_DESC); MODULE_LICENSE("GPL and additional rights"); MODULE_PARM_DESC(debug, "Enable debug output"); +MODULE_PARM_DESC(vblankoffdelay, "Delay until vblank irq auto-disable [msecs]"); +MODULE_PARM_DESC(timestamp_precision_usec, "Max. error on timestamps [usecs]"); module_param_named(debug, drm_debug, int, 0600); +module_param_named(vblankoffdelay, drm_vblank_offdelay, int, 0600); +module_param_named(timestamp_precision_usec, drm_timestamp_precision, int, 0600); struct idr drm_minors_idr; diff --git a/include/drm/drmP.h b/include/drm/drmP.h index 274eaaa15c36..2b3398004aa5 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -683,6 +683,21 @@ struct drm_master { void *driver_priv; /**< Private structure for driver to use */ }; +/* Size of ringbuffer for vblank timestamps. Just double-buffer + * in initial implementation. + */ +#define DRM_VBLANKTIME_RBSIZE 2 + +/* Flags and return codes for get_vblank_timestamp() driver function. */ +#define DRM_CALLED_FROM_VBLIRQ 1 +#define DRM_VBLANKTIME_SCANOUTPOS_METHOD (1 << 0) +#define DRM_VBLANKTIME_INVBL (1 << 1) + +/* get_scanout_position() return flags */ +#define DRM_SCANOUTPOS_VALID (1 << 0) +#define DRM_SCANOUTPOS_INVBL (1 << 1) +#define DRM_SCANOUTPOS_ACCURATE (1 << 2) + /** * DRM driver structure. This structure represent the common code for * a family of cards. There will one drm_device for each card present @@ -760,6 +775,68 @@ struct drm_driver { */ int (*device_is_agp) (struct drm_device *dev); + /** + * Called by vblank timestamping code. + * + * Return the current display scanout position from a crtc. + * + * \param dev DRM device. + * \param crtc Id of the crtc to query. + * \param *vpos Target location for current vertical scanout position. + * \param *hpos Target location for current horizontal scanout position. + * + * Returns vpos as a positive number while in active scanout area. + * Returns vpos as a negative number inside vblank, counting the number + * of scanlines to go until end of vblank, e.g., -1 means "one scanline + * until start of active scanout / end of vblank." + * + * \return Flags, or'ed together as follows: + * + * DRM_SCANOUTPOS_VALID = Query successfull. + * DRM_SCANOUTPOS_INVBL = Inside vblank. + * DRM_SCANOUTPOS_ACCURATE = Returned position is accurate. A lack of + * this flag means that returned position may be offset by a constant + * but unknown small number of scanlines wrt. real scanout position. + * + */ + int (*get_scanout_position) (struct drm_device *dev, int crtc, + int *vpos, int *hpos); + + /** + * Called by \c drm_get_last_vbltimestamp. Should return a precise + * timestamp when the most recent VBLANK interval ended or will end. + * + * Specifically, the timestamp in @vblank_time should correspond as + * closely as possible to the time when the first video scanline of + * the video frame after the end of VBLANK will start scanning out, + * the time immmediately after end of the VBLANK interval. If the + * @crtc is currently inside VBLANK, this will be a time in the future. + * If the @crtc is currently scanning out a frame, this will be the + * past start time of the current scanout. This is meant to adhere + * to the OpenML OML_sync_control extension specification. + * + * \param dev dev DRM device handle. + * \param crtc crtc for which timestamp should be returned. + * \param *max_error Maximum allowable timestamp error in nanoseconds. + * Implementation should strive to provide timestamp + * with an error of at most *max_error nanoseconds. + * Returns true upper bound on error for timestamp. + * \param *vblank_time Target location for returned vblank timestamp. + * \param flags 0 = Defaults, no special treatment needed. + * \param DRM_CALLED_FROM_VBLIRQ = Function is called from vblank + * irq handler. Some drivers need to apply some workarounds + * for gpu-specific vblank irq quirks if flag is set. + * + * \returns + * Zero if timestamping isn't supported in current display mode or a + * negative number on failure. A positive status code on success, + * which describes how the vblank_time timestamp was computed. + */ + int (*get_vblank_timestamp) (struct drm_device *dev, int crtc, + int *max_error, + struct timeval *vblank_time, + unsigned flags); + /* these have to be filled in */ irqreturn_t(*irq_handler) (DRM_IRQ_ARGS); @@ -983,6 +1060,8 @@ struct drm_device { wait_queue_head_t *vbl_queue; /**< VBLANK wait queue */ atomic_t *_vblank_count; /**< number of VBLANK interrupts (driver must alloc the right number of counters) */ + struct timeval *_vblank_time; /**< timestamp of current vblank_count (drivers must alloc right number of fields) */ + spinlock_t vblank_time_lock; /**< Protects vblank count and time updates during vblank enable/disable */ spinlock_t vbl_lock; atomic_t *vblank_refcount; /* number of users of vblank interruptsper crtc */ u32 *last_vblank; /* protected by dev->vbl_lock, used */ @@ -1284,11 +1363,22 @@ extern int drm_wait_vblank(struct drm_device *dev, void *data, struct drm_file *filp); extern int drm_vblank_wait(struct drm_device *dev, unsigned int *vbl_seq); extern u32 drm_vblank_count(struct drm_device *dev, int crtc); +extern u32 drm_vblank_count_and_time(struct drm_device *dev, int crtc, + struct timeval *vblanktime); extern void drm_handle_vblank(struct drm_device *dev, int crtc); extern int drm_vblank_get(struct drm_device *dev, int crtc); extern void drm_vblank_put(struct drm_device *dev, int crtc); extern void drm_vblank_off(struct drm_device *dev, int crtc); extern void drm_vblank_cleanup(struct drm_device *dev); +extern u32 drm_get_last_vbltimestamp(struct drm_device *dev, int crtc, + struct timeval *tvblank, unsigned flags); +extern int drm_calc_vbltimestamp_from_scanoutpos(struct drm_device *dev, + int crtc, int *max_error, + struct timeval *vblank_time, + unsigned flags, + struct drm_crtc *refcrtc); +extern void drm_calc_timestamping_constants(struct drm_crtc *crtc); + /* Modesetting support */ extern void drm_vblank_pre_modeset(struct drm_device *dev, int crtc); extern void drm_vblank_post_modeset(struct drm_device *dev, int crtc); @@ -1340,6 +1430,9 @@ extern void drm_put_dev(struct drm_device *dev); extern int drm_put_minor(struct drm_minor **minor); extern unsigned int drm_debug; +extern unsigned int drm_vblank_offdelay; +extern unsigned int drm_timestamp_precision; + extern struct class *drm_class; extern struct proc_dir_entry *drm_proc_root; extern struct dentry *drm_debugfs_root; diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h index 029aa688e787..acd7fade160d 100644 --- a/include/drm/drm_crtc.h +++ b/include/drm/drm_crtc.h @@ -351,8 +351,14 @@ struct drm_crtc { bool enabled; + /* Requested mode from modesetting. */ struct drm_display_mode mode; + /* Programmed mode in hw, after adjustments for encoders, + * crtc, panel scaling etc. Needed for timestamping etc. + */ + struct drm_display_mode hwmode; + int x, y; const struct drm_crtc_funcs *funcs; @@ -360,6 +366,9 @@ struct drm_crtc { uint32_t gamma_size; uint16_t *gamma_store; + /* Constants needed for precise vblank and swap timestamping. */ + s64 framedur_ns, linedur_ns, pixeldur_ns; + /* if you are using the helper */ void *helper_private; }; -- cgit v1.2.3 From f5a8020903932624cf020dc72455a10a3e005087 Mon Sep 17 00:00:00 2001 From: Mario Kleiner Date: Sat, 23 Oct 2010 04:42:17 +0200 Subject: drm/kms/radeon: Add support for precise vblank timestamping. This patch adds new functions for use by the drm core: .get_vblank_timestamp() provides a precise timestamp for the end of the most recent (or current) vblank interval of a given crtc, as needed for the DRI2 implementation of the OML_sync_control extension. It is a thin wrapper around the drm function drm_calc_vbltimestamp_from_scanoutpos() which does almost all the work and is shared across drivers. .get_scanout_position() provides the current horizontal and vertical video scanout position and "in vblank" status of a given crtc, as needed by the drm for use by drm_calc_vbltimestamp_from_scanoutpos(). The function is also used by the dynamic gpu reclocking code to determine when it is safe to reclock inside vblank. For that purpose radeon_pm_in_vbl() is modified to accomodate a small change in the function prototype of the radeon_get_crtc_scanoutpos() which is hooked up to .get_scanout_position(). This code has been tested on AVIVO hardware, a RV530 (ATI Mobility Radeon X1600) in a Intel Core-2 Duo MacBookPro and some R600 variant (FireGL V7600) in a single cpu AMD Athlon 64 PC. Signed-off-by: Mario Kleiner Reviewed-by: Alex Deucher Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/radeon_display.c | 40 +++++++++++++++++---------------- drivers/gpu/drm/radeon/radeon_drv.c | 8 +++++++ drivers/gpu/drm/radeon/radeon_kms.c | 21 +++++++++++++++++ drivers/gpu/drm/radeon/radeon_mode.h | 7 ++---- drivers/gpu/drm/radeon/radeon_pm.c | 6 ++--- 5 files changed, 55 insertions(+), 27 deletions(-) diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c index 1df4dc6c063c..eeea7cbb9517 100644 --- a/drivers/gpu/drm/radeon/radeon_display.c +++ b/drivers/gpu/drm/radeon/radeon_display.c @@ -1019,7 +1019,7 @@ bool radeon_crtc_scaling_mode_fixup(struct drm_crtc *crtc, /* * Retrieve current video scanout position of crtc on a given gpu. * - * \param rdev Device to query. + * \param dev Device to query. * \param crtc Crtc to query. * \param *vpos Location where vertical scanout position should be stored. * \param *hpos Location where horizontal scanout position should go. @@ -1031,72 +1031,74 @@ bool radeon_crtc_scaling_mode_fixup(struct drm_crtc *crtc, * * \return Flags, or'ed together as follows: * - * RADEON_SCANOUTPOS_VALID = Query successfull. - * RADEON_SCANOUTPOS_INVBL = Inside vblank. - * RADEON_SCANOUTPOS_ACCURATE = Returned position is accurate. A lack of + * DRM_SCANOUTPOS_VALID = Query successfull. + * DRM_SCANOUTPOS_INVBL = Inside vblank. + * DRM_SCANOUTPOS_ACCURATE = Returned position is accurate. A lack of * this flag means that returned position may be offset by a constant but * unknown small number of scanlines wrt. real scanout position. * */ -int radeon_get_crtc_scanoutpos(struct radeon_device *rdev, int crtc, int *vpos, int *hpos) +int radeon_get_crtc_scanoutpos(struct drm_device *dev, int crtc, int *vpos, int *hpos) { u32 stat_crtc = 0, vbl = 0, position = 0; int vbl_start, vbl_end, vtotal, ret = 0; bool in_vbl = true; + struct radeon_device *rdev = dev->dev_private; + if (ASIC_IS_DCE4(rdev)) { if (crtc == 0) { vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END + EVERGREEN_CRTC0_REGISTER_OFFSET); position = RREG32(EVERGREEN_CRTC_STATUS_POSITION + EVERGREEN_CRTC0_REGISTER_OFFSET); - ret |= RADEON_SCANOUTPOS_VALID; + ret |= DRM_SCANOUTPOS_VALID; } if (crtc == 1) { vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END + EVERGREEN_CRTC1_REGISTER_OFFSET); position = RREG32(EVERGREEN_CRTC_STATUS_POSITION + EVERGREEN_CRTC1_REGISTER_OFFSET); - ret |= RADEON_SCANOUTPOS_VALID; + ret |= DRM_SCANOUTPOS_VALID; } if (crtc == 2) { vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END + EVERGREEN_CRTC2_REGISTER_OFFSET); position = RREG32(EVERGREEN_CRTC_STATUS_POSITION + EVERGREEN_CRTC2_REGISTER_OFFSET); - ret |= RADEON_SCANOUTPOS_VALID; + ret |= DRM_SCANOUTPOS_VALID; } if (crtc == 3) { vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END + EVERGREEN_CRTC3_REGISTER_OFFSET); position = RREG32(EVERGREEN_CRTC_STATUS_POSITION + EVERGREEN_CRTC3_REGISTER_OFFSET); - ret |= RADEON_SCANOUTPOS_VALID; + ret |= DRM_SCANOUTPOS_VALID; } if (crtc == 4) { vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END + EVERGREEN_CRTC4_REGISTER_OFFSET); position = RREG32(EVERGREEN_CRTC_STATUS_POSITION + EVERGREEN_CRTC4_REGISTER_OFFSET); - ret |= RADEON_SCANOUTPOS_VALID; + ret |= DRM_SCANOUTPOS_VALID; } if (crtc == 5) { vbl = RREG32(EVERGREEN_CRTC_V_BLANK_START_END + EVERGREEN_CRTC5_REGISTER_OFFSET); position = RREG32(EVERGREEN_CRTC_STATUS_POSITION + EVERGREEN_CRTC5_REGISTER_OFFSET); - ret |= RADEON_SCANOUTPOS_VALID; + ret |= DRM_SCANOUTPOS_VALID; } } else if (ASIC_IS_AVIVO(rdev)) { if (crtc == 0) { vbl = RREG32(AVIVO_D1CRTC_V_BLANK_START_END); position = RREG32(AVIVO_D1CRTC_STATUS_POSITION); - ret |= RADEON_SCANOUTPOS_VALID; + ret |= DRM_SCANOUTPOS_VALID; } if (crtc == 1) { vbl = RREG32(AVIVO_D2CRTC_V_BLANK_START_END); position = RREG32(AVIVO_D2CRTC_STATUS_POSITION); - ret |= RADEON_SCANOUTPOS_VALID; + ret |= DRM_SCANOUTPOS_VALID; } } else { /* Pre-AVIVO: Different encoding of scanout pos and vblank interval. */ @@ -1112,7 +1114,7 @@ int radeon_get_crtc_scanoutpos(struct radeon_device *rdev, int crtc, int *vpos, if (!(stat_crtc & 1)) in_vbl = false; - ret |= RADEON_SCANOUTPOS_VALID; + ret |= DRM_SCANOUTPOS_VALID; } if (crtc == 1) { vbl = (RREG32(RADEON_CRTC2_V_TOTAL_DISP) & @@ -1122,7 +1124,7 @@ int radeon_get_crtc_scanoutpos(struct radeon_device *rdev, int crtc, int *vpos, if (!(stat_crtc & 1)) in_vbl = false; - ret |= RADEON_SCANOUTPOS_VALID; + ret |= DRM_SCANOUTPOS_VALID; } } @@ -1133,13 +1135,13 @@ int radeon_get_crtc_scanoutpos(struct radeon_device *rdev, int crtc, int *vpos, /* Valid vblank area boundaries from gpu retrieved? */ if (vbl > 0) { /* Yes: Decode. */ - ret |= RADEON_SCANOUTPOS_ACCURATE; + ret |= DRM_SCANOUTPOS_ACCURATE; vbl_start = vbl & 0x1fff; vbl_end = (vbl >> 16) & 0x1fff; } else { /* No: Fake something reasonable which gives at least ok results. */ - vbl_start = rdev->mode_info.crtcs[crtc]->base.mode.crtc_vdisplay; + vbl_start = rdev->mode_info.crtcs[crtc]->base.hwmode.crtc_vdisplay; vbl_end = 0; } @@ -1155,7 +1157,7 @@ int radeon_get_crtc_scanoutpos(struct radeon_device *rdev, int crtc, int *vpos, /* Inside "upper part" of vblank area? Apply corrective offset if so: */ if (in_vbl && (*vpos >= vbl_start)) { - vtotal = rdev->mode_info.crtcs[crtc]->base.mode.crtc_vtotal; + vtotal = rdev->mode_info.crtcs[crtc]->base.hwmode.crtc_vtotal; *vpos = *vpos - vtotal; } @@ -1164,7 +1166,7 @@ int radeon_get_crtc_scanoutpos(struct radeon_device *rdev, int crtc, int *vpos, /* In vblank? */ if (in_vbl) - ret |= RADEON_SCANOUTPOS_INVBL; + ret |= DRM_SCANOUTPOS_INVBL; return ret; } diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index 88e4ea925900..32ec0cc6be92 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c @@ -66,6 +66,10 @@ int radeon_resume_kms(struct drm_device *dev); u32 radeon_get_vblank_counter_kms(struct drm_device *dev, int crtc); int radeon_enable_vblank_kms(struct drm_device *dev, int crtc); void radeon_disable_vblank_kms(struct drm_device *dev, int crtc); +int radeon_get_vblank_timestamp_kms(struct drm_device *dev, int crtc, + int *max_error, + struct timeval *vblank_time, + unsigned flags); void radeon_driver_irq_preinstall_kms(struct drm_device *dev); int radeon_driver_irq_postinstall_kms(struct drm_device *dev); void radeon_driver_irq_uninstall_kms(struct drm_device *dev); @@ -74,6 +78,8 @@ int radeon_dma_ioctl_kms(struct drm_device *dev, void *data, struct drm_file *file_priv); int radeon_gem_object_init(struct drm_gem_object *obj); void radeon_gem_object_free(struct drm_gem_object *obj); +extern int radeon_get_crtc_scanoutpos(struct drm_device *dev, int crtc, + int *vpos, int *hpos); extern struct drm_ioctl_desc radeon_ioctls_kms[]; extern int radeon_max_kms_ioctl; int radeon_mmap(struct file *filp, struct vm_area_struct *vma); @@ -277,6 +283,8 @@ static struct drm_driver kms_driver = { .get_vblank_counter = radeon_get_vblank_counter_kms, .enable_vblank = radeon_enable_vblank_kms, .disable_vblank = radeon_disable_vblank_kms, + .get_vblank_timestamp = radeon_get_vblank_timestamp_kms, + .get_scanout_position = radeon_get_crtc_scanoutpos, #if defined(CONFIG_DEBUG_FS) .debugfs_init = radeon_debugfs_init, .debugfs_cleanup = radeon_debugfs_cleanup, diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c index 8fbbe1c6ebbd..4bf423ca4c12 100644 --- a/drivers/gpu/drm/radeon/radeon_kms.c +++ b/drivers/gpu/drm/radeon/radeon_kms.c @@ -277,6 +277,27 @@ void radeon_disable_vblank_kms(struct drm_device *dev, int crtc) radeon_irq_set(rdev); } +int radeon_get_vblank_timestamp_kms(struct drm_device *dev, int crtc, + int *max_error, + struct timeval *vblank_time, + unsigned flags) +{ + struct drm_crtc *drmcrtc; + struct radeon_device *rdev = dev->dev_private; + + if (crtc < 0 || crtc >= dev->num_crtcs) { + DRM_ERROR("Invalid crtc %d\n", crtc); + return -EINVAL; + } + + /* Get associated drm_crtc: */ + drmcrtc = &rdev->mode_info.crtcs[crtc]->base; + + /* Helper routine in DRM core does all the work: */ + return drm_calc_vbltimestamp_from_scanoutpos(dev, crtc, max_error, + vblank_time, flags, + drmcrtc); +} /* * IOCTL. diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h index e301c6f9e059..55856ad0ac41 100644 --- a/drivers/gpu/drm/radeon/radeon_mode.h +++ b/drivers/gpu/drm/radeon/radeon_mode.h @@ -442,10 +442,6 @@ struct radeon_framebuffer { struct drm_gem_object *obj; }; -/* radeon_get_crtc_scanoutpos() return flags */ -#define RADEON_SCANOUTPOS_VALID (1 << 0) -#define RADEON_SCANOUTPOS_INVBL (1 << 1) -#define RADEON_SCANOUTPOS_ACCURATE (1 << 2) extern enum radeon_tv_std radeon_combios_get_tv_info(struct radeon_device *rdev); @@ -562,7 +558,8 @@ extern int radeon_crtc_cursor_set(struct drm_crtc *crtc, extern int radeon_crtc_cursor_move(struct drm_crtc *crtc, int x, int y); -extern int radeon_get_crtc_scanoutpos(struct radeon_device *rdev, int crtc, int *vpos, int *hpos); +extern int radeon_get_crtc_scanoutpos(struct drm_device *dev, int crtc, + int *vpos, int *hpos); extern bool radeon_combios_check_hardcoded_edid(struct radeon_device *rdev); extern struct edid * diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c index 8c9b2ef32c68..5eda5e471980 100644 --- a/drivers/gpu/drm/radeon/radeon_pm.c +++ b/drivers/gpu/drm/radeon/radeon_pm.c @@ -720,9 +720,9 @@ static bool radeon_pm_in_vbl(struct radeon_device *rdev) */ for (crtc = 0; (crtc < rdev->num_crtc) && in_vbl; crtc++) { if (rdev->pm.active_crtcs & (1 << crtc)) { - vbl_status = radeon_get_crtc_scanoutpos(rdev, crtc, &vpos, &hpos); - if ((vbl_status & RADEON_SCANOUTPOS_VALID) && - !(vbl_status & RADEON_SCANOUTPOS_INVBL)) + vbl_status = radeon_get_crtc_scanoutpos(rdev->ddev, crtc, &vpos, &hpos); + if ((vbl_status & DRM_SCANOUTPOS_VALID) && + !(vbl_status & DRM_SCANOUTPOS_INVBL)) in_vbl = false; } } -- cgit v1.2.3 From 6f34be50bd1bdd2ff3c955940e033a80d05f248a Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Sun, 21 Nov 2010 10:59:01 -0500 Subject: drm/radeon/kms: add pageflip ioctl support (v3) This adds support for dri2 pageflipping. v2: precision updates from Mario Kleiner. v3: Multihead fixes from Mario Kleiner; missing crtc offset add note about update pending bit on pre-avivo chips Signed-off-by: Alex Deucher Signed-off-by: Mario Kleiner Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/evergreen.c | 301 +++++++++++++++++++++----------- drivers/gpu/drm/radeon/evergreen_reg.h | 6 + drivers/gpu/drm/radeon/r100.c | 74 +++++++- drivers/gpu/drm/radeon/r500_reg.h | 4 + drivers/gpu/drm/radeon/r600.c | 126 +++++++------ drivers/gpu/drm/radeon/r600d.h | 9 + drivers/gpu/drm/radeon/radeon.h | 57 ++++++ drivers/gpu/drm/radeon/radeon_asic.c | 42 +++++ drivers/gpu/drm/radeon/radeon_asic.h | 10 ++ drivers/gpu/drm/radeon/radeon_display.c | 261 +++++++++++++++++++++++++++ drivers/gpu/drm/radeon/radeon_drv.c | 3 +- drivers/gpu/drm/radeon/radeon_irq_kms.c | 39 ++++- drivers/gpu/drm/radeon/radeon_mode.h | 6 + drivers/gpu/drm/radeon/radeon_reg.h | 1 + drivers/gpu/drm/radeon/rs600.c | 116 +++++++++--- drivers/gpu/drm/radeon/rv770.c | 34 ++++ drivers/gpu/drm/radeon/rv770d.h | 7 + 17 files changed, 900 insertions(+), 196 deletions(-) diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index 4dc5b4714c5a..df3f37243222 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c @@ -40,6 +40,61 @@ static void evergreen_gpu_init(struct radeon_device *rdev); void evergreen_fini(struct radeon_device *rdev); +void evergreen_pre_page_flip(struct radeon_device *rdev, int crtc) +{ + struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc]; + u32 tmp; + + /* make sure flip is at vb rather than hb */ + tmp = RREG32(EVERGREEN_GRPH_FLIP_CONTROL + radeon_crtc->crtc_offset); + tmp &= ~EVERGREEN_GRPH_SURFACE_UPDATE_H_RETRACE_EN; + WREG32(EVERGREEN_GRPH_FLIP_CONTROL + radeon_crtc->crtc_offset, tmp); + + /* set pageflip to happen anywhere in vblank interval */ + WREG32(EVERGREEN_MASTER_UPDATE_MODE + radeon_crtc->crtc_offset, 0); + + /* enable the pflip int */ + radeon_irq_kms_pflip_irq_get(rdev, crtc); +} + +void evergreen_post_page_flip(struct radeon_device *rdev, int crtc) +{ + /* disable the pflip int */ + radeon_irq_kms_pflip_irq_put(rdev, crtc); +} + +u32 evergreen_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base) +{ + struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id]; + u32 tmp = RREG32(EVERGREEN_GRPH_UPDATE + radeon_crtc->crtc_offset); + + /* Lock the graphics update lock */ + tmp |= EVERGREEN_GRPH_UPDATE_LOCK; + WREG32(EVERGREEN_GRPH_UPDATE + radeon_crtc->crtc_offset, tmp); + + /* update the scanout addresses */ + WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH + radeon_crtc->crtc_offset, + upper_32_bits(crtc_base)); + WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + radeon_crtc->crtc_offset, + (u32)crtc_base); + + WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + radeon_crtc->crtc_offset, + upper_32_bits(crtc_base)); + WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS + radeon_crtc->crtc_offset, + (u32)crtc_base); + + /* Wait for update_pending to go high. */ + while (!(RREG32(EVERGREEN_GRPH_UPDATE + radeon_crtc->crtc_offset) & EVERGREEN_GRPH_SURFACE_UPDATE_PENDING)); + DRM_DEBUG("Update pending now high. Unlocking vupdate_lock.\n"); + + /* Unlock the lock, so double-buffering can take place inside vblank */ + tmp &= ~EVERGREEN_GRPH_UPDATE_LOCK; + WREG32(EVERGREEN_GRPH_UPDATE + radeon_crtc->crtc_offset, tmp); + + /* Return current update_pending status: */ + return RREG32(EVERGREEN_GRPH_UPDATE + radeon_crtc->crtc_offset) & EVERGREEN_GRPH_SURFACE_UPDATE_PENDING; +} + /* get temperature in millidegrees */ u32 evergreen_get_temp(struct radeon_device *rdev) { @@ -2060,6 +2115,7 @@ int evergreen_irq_set(struct radeon_device *rdev) u32 crtc1 = 0, crtc2 = 0, crtc3 = 0, crtc4 = 0, crtc5 = 0, crtc6 = 0; u32 hpd1, hpd2, hpd3, hpd4, hpd5, hpd6; u32 grbm_int_cntl = 0; + u32 grph1 = 0, grph2 = 0, grph3 = 0, grph4 = 0, grph5 = 0, grph6 = 0; if (!rdev->irq.installed) { WARN(1, "Can't enable IRQ/MSI because no handler is installed\n"); @@ -2085,27 +2141,33 @@ int evergreen_irq_set(struct radeon_device *rdev) cp_int_cntl |= RB_INT_ENABLE; cp_int_cntl |= TIME_STAMP_INT_ENABLE; } - if (rdev->irq.crtc_vblank_int[0]) { + if (rdev->irq.crtc_vblank_int[0] || + rdev->irq.pflip[0]) { DRM_DEBUG("evergreen_irq_set: vblank 0\n"); crtc1 |= VBLANK_INT_MASK; } - if (rdev->irq.crtc_vblank_int[1]) { + if (rdev->irq.crtc_vblank_int[1] || + rdev->irq.pflip[1]) { DRM_DEBUG("evergreen_irq_set: vblank 1\n"); crtc2 |= VBLANK_INT_MASK; } - if (rdev->irq.crtc_vblank_int[2]) { + if (rdev->irq.crtc_vblank_int[2] || + rdev->irq.pflip[2]) { DRM_DEBUG("evergreen_irq_set: vblank 2\n"); crtc3 |= VBLANK_INT_MASK; } - if (rdev->irq.crtc_vblank_int[3]) { + if (rdev->irq.crtc_vblank_int[3] || + rdev->irq.pflip[3]) { DRM_DEBUG("evergreen_irq_set: vblank 3\n"); crtc4 |= VBLANK_INT_MASK; } - if (rdev->irq.crtc_vblank_int[4]) { + if (rdev->irq.crtc_vblank_int[4] || + rdev->irq.pflip[4]) { DRM_DEBUG("evergreen_irq_set: vblank 4\n"); crtc5 |= VBLANK_INT_MASK; } - if (rdev->irq.crtc_vblank_int[5]) { + if (rdev->irq.crtc_vblank_int[5] || + rdev->irq.pflip[5]) { DRM_DEBUG("evergreen_irq_set: vblank 5\n"); crtc6 |= VBLANK_INT_MASK; } @@ -2148,6 +2210,13 @@ int evergreen_irq_set(struct radeon_device *rdev) WREG32(INT_MASK + EVERGREEN_CRTC4_REGISTER_OFFSET, crtc5); WREG32(INT_MASK + EVERGREEN_CRTC5_REGISTER_OFFSET, crtc6); + WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, grph1); + WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, grph2); + WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, grph3); + WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, grph4); + WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET, grph5); + WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, grph6); + WREG32(DC_HPD1_INT_CONTROL, hpd1); WREG32(DC_HPD2_INT_CONTROL, hpd2); WREG32(DC_HPD3_INT_CONTROL, hpd3); @@ -2158,79 +2227,92 @@ int evergreen_irq_set(struct radeon_device *rdev) return 0; } -static inline void evergreen_irq_ack(struct radeon_device *rdev, - u32 *disp_int, - u32 *disp_int_cont, - u32 *disp_int_cont2, - u32 *disp_int_cont3, - u32 *disp_int_cont4, - u32 *disp_int_cont5) +static inline void evergreen_irq_ack(struct radeon_device *rdev) { u32 tmp; - *disp_int = RREG32(DISP_INTERRUPT_STATUS); - *disp_int_cont = RREG32(DISP_INTERRUPT_STATUS_CONTINUE); - *disp_int_cont2 = RREG32(DISP_INTERRUPT_STATUS_CONTINUE2); - *disp_int_cont3 = RREG32(DISP_INTERRUPT_STATUS_CONTINUE3); - *disp_int_cont4 = RREG32(DISP_INTERRUPT_STATUS_CONTINUE4); - *disp_int_cont5 = RREG32(DISP_INTERRUPT_STATUS_CONTINUE5); - - if (*disp_int & LB_D1_VBLANK_INTERRUPT) + rdev->irq.stat_regs.evergreen.disp_int = RREG32(DISP_INTERRUPT_STATUS); + rdev->irq.stat_regs.evergreen.disp_int_cont = RREG32(DISP_INTERRUPT_STATUS_CONTINUE); + rdev->irq.stat_regs.evergreen.disp_int_cont2 = RREG32(DISP_INTERRUPT_STATUS_CONTINUE2); + rdev->irq.stat_regs.evergreen.disp_int_cont3 = RREG32(DISP_INTERRUPT_STATUS_CONTINUE3); + rdev->irq.stat_regs.evergreen.disp_int_cont4 = RREG32(DISP_INTERRUPT_STATUS_CONTINUE4); + rdev->irq.stat_regs.evergreen.disp_int_cont5 = RREG32(DISP_INTERRUPT_STATUS_CONTINUE5); + rdev->irq.stat_regs.evergreen.d1grph_int = RREG32(GRPH_INT_STATUS + EVERGREEN_CRTC0_REGISTER_OFFSET); + rdev->irq.stat_regs.evergreen.d2grph_int = RREG32(GRPH_INT_STATUS + EVERGREEN_CRTC1_REGISTER_OFFSET); + rdev->irq.stat_regs.evergreen.d3grph_int = RREG32(GRPH_INT_STATUS + EVERGREEN_CRTC2_REGISTER_OFFSET); + rdev->irq.stat_regs.evergreen.d4grph_int = RREG32(GRPH_INT_STATUS + EVERGREEN_CRTC3_REGISTER_OFFSET); + rdev->irq.stat_regs.evergreen.d5grph_int = RREG32(GRPH_INT_STATUS + EVERGREEN_CRTC4_REGISTER_OFFSET); + rdev->irq.stat_regs.evergreen.d6grph_int = RREG32(GRPH_INT_STATUS + EVERGREEN_CRTC5_REGISTER_OFFSET); + + if (rdev->irq.stat_regs.evergreen.d1grph_int & GRPH_PFLIP_INT_OCCURRED) + WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC0_REGISTER_OFFSET, GRPH_PFLIP_INT_CLEAR); + if (rdev->irq.stat_regs.evergreen.d2grph_int & GRPH_PFLIP_INT_OCCURRED) + WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC1_REGISTER_OFFSET, GRPH_PFLIP_INT_CLEAR); + if (rdev->irq.stat_regs.evergreen.d3grph_int & GRPH_PFLIP_INT_OCCURRED) + WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC2_REGISTER_OFFSET, GRPH_PFLIP_INT_CLEAR); + if (rdev->irq.stat_regs.evergreen.d4grph_int & GRPH_PFLIP_INT_OCCURRED) + WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC3_REGISTER_OFFSET, GRPH_PFLIP_INT_CLEAR); + if (rdev->irq.stat_regs.evergreen.d5grph_int & GRPH_PFLIP_INT_OCCURRED) + WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC4_REGISTER_OFFSET, GRPH_PFLIP_INT_CLEAR); + if (rdev->irq.stat_regs.evergreen.d6grph_int & GRPH_PFLIP_INT_OCCURRED) + WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC5_REGISTER_OFFSET, GRPH_PFLIP_INT_CLEAR); + + if (rdev->irq.stat_regs.evergreen.disp_int & LB_D1_VBLANK_INTERRUPT) WREG32(VBLANK_STATUS + EVERGREEN_CRTC0_REGISTER_OFFSET, VBLANK_ACK); - if (*disp_int & LB_D1_VLINE_INTERRUPT) + if (rdev->irq.stat_regs.evergreen.disp_int & LB_D1_VLINE_INTERRUPT) WREG32(VLINE_STATUS + EVERGREEN_CRTC0_REGISTER_OFFSET, VLINE_ACK); - if (*disp_int_cont & LB_D2_VBLANK_INTERRUPT) + if (rdev->irq.stat_regs.evergreen.disp_int_cont & LB_D2_VBLANK_INTERRUPT) WREG32(VBLANK_STATUS + EVERGREEN_CRTC1_REGISTER_OFFSET, VBLANK_ACK); - if (*disp_int_cont & LB_D2_VLINE_INTERRUPT) + if (rdev->irq.stat_regs.evergreen.disp_int_cont & LB_D2_VLINE_INTERRUPT) WREG32(VLINE_STATUS + EVERGREEN_CRTC1_REGISTER_OFFSET, VLINE_ACK); - if (*disp_int_cont2 & LB_D3_VBLANK_INTERRUPT) + if (rdev->irq.stat_regs.evergreen.disp_int_cont2 & LB_D3_VBLANK_INTERRUPT) WREG32(VBLANK_STATUS + EVERGREEN_CRTC2_REGISTER_OFFSET, VBLANK_ACK); - if (*disp_int_cont2 & LB_D3_VLINE_INTERRUPT) + if (rdev->irq.stat_regs.evergreen.disp_int_cont2 & LB_D3_VLINE_INTERRUPT) WREG32(VLINE_STATUS + EVERGREEN_CRTC2_REGISTER_OFFSET, VLINE_ACK); - if (*disp_int_cont3 & LB_D4_VBLANK_INTERRUPT) + if (rdev->irq.stat_regs.evergreen.disp_int_cont3 & LB_D4_VBLANK_INTERRUPT) WREG32(VBLANK_STATUS + EVERGREEN_CRTC3_REGISTER_OFFSET, VBLANK_ACK); - if (*disp_int_cont3 & LB_D4_VLINE_INTERRUPT) + if (rdev->irq.stat_regs.evergreen.disp_int_cont3 & LB_D4_VLINE_INTERRUPT) WREG32(VLINE_STATUS + EVERGREEN_CRTC3_REGISTER_OFFSET, VLINE_ACK); - if (*disp_int_cont4 & LB_D5_VBLANK_INTERRUPT) + if (rdev->irq.stat_regs.evergreen.disp_int_cont4 & LB_D5_VBLANK_INTERRUPT) WREG32(VBLANK_STATUS + EVERGREEN_CRTC4_REGISTER_OFFSET, VBLANK_ACK); - if (*disp_int_cont4 & LB_D5_VLINE_INTERRUPT) + if (rdev->irq.stat_regs.evergreen.disp_int_cont4 & LB_D5_VLINE_INTERRUPT) WREG32(VLINE_STATUS + EVERGREEN_CRTC4_REGISTER_OFFSET, VLINE_ACK); - if (*disp_int_cont5 & LB_D6_VBLANK_INTERRUPT) + if (rdev->irq.stat_regs.evergreen.disp_int_cont5 & LB_D6_VBLANK_INTERRUPT) WREG32(VBLANK_STATUS + EVERGREEN_CRTC5_REGISTER_OFFSET, VBLANK_ACK); - if (*disp_int_cont5 & LB_D6_VLINE_INTERRUPT) + if (rdev->irq.stat_regs.evergreen.disp_int_cont5 & LB_D6_VLINE_INTERRUPT) WREG32(VLINE_STATUS + EVERGREEN_CRTC5_REGISTER_OFFSET, VLINE_ACK); - if (*disp_int & DC_HPD1_INTERRUPT) { + if (rdev->irq.stat_regs.evergreen.disp_int & DC_HPD1_INTERRUPT) { tmp = RREG32(DC_HPD1_INT_CONTROL); tmp |= DC_HPDx_INT_ACK; WREG32(DC_HPD1_INT_CONTROL, tmp); } - if (*disp_int_cont & DC_HPD2_INTERRUPT) { + if (rdev->irq.stat_regs.evergreen.disp_int_cont & DC_HPD2_INTERRUPT) { tmp = RREG32(DC_HPD2_INT_CONTROL); tmp |= DC_HPDx_INT_ACK; WREG32(DC_HPD2_INT_CONTROL, tmp); } - if (*disp_int_cont2 & DC_HPD3_INTERRUPT) { + if (rdev->irq.stat_regs.evergreen.disp_int_cont2 & DC_HPD3_INTERRUPT) { tmp = RREG32(DC_HPD3_INT_CONTROL); tmp |= DC_HPDx_INT_ACK; WREG32(DC_HPD3_INT_CONTROL, tmp); } - if (*disp_int_cont3 & DC_HPD4_INTERRUPT) { + if (rdev->irq.stat_regs.evergreen.disp_int_cont3 & DC_HPD4_INTERRUPT) { tmp = RREG32(DC_HPD4_INT_CONTROL); tmp |= DC_HPDx_INT_ACK; WREG32(DC_HPD4_INT_CONTROL, tmp); } - if (*disp_int_cont4 & DC_HPD5_INTERRUPT) { + if (rdev->irq.stat_regs.evergreen.disp_int_cont4 & DC_HPD5_INTERRUPT) { tmp = RREG32(DC_HPD5_INT_CONTROL); tmp |= DC_HPDx_INT_ACK; WREG32(DC_HPD5_INT_CONTROL, tmp); } - if (*disp_int_cont5 & DC_HPD6_INTERRUPT) { + if (rdev->irq.stat_regs.evergreen.disp_int_cont5 & DC_HPD6_INTERRUPT) { tmp = RREG32(DC_HPD5_INT_CONTROL); tmp |= DC_HPDx_INT_ACK; WREG32(DC_HPD6_INT_CONTROL, tmp); @@ -2239,14 +2321,10 @@ static inline void evergreen_irq_ack(struct radeon_device *rdev, void evergreen_irq_disable(struct radeon_device *rdev) { - u32 disp_int, disp_int_cont, disp_int_cont2; - u32 disp_int_cont3, disp_int_cont4, disp_int_cont5; - r600_disable_interrupts(rdev); /* Wait and acknowledge irq */ mdelay(1); - evergreen_irq_ack(rdev, &disp_int, &disp_int_cont, &disp_int_cont2, - &disp_int_cont3, &disp_int_cont4, &disp_int_cont5); + evergreen_irq_ack(rdev); evergreen_disable_interrupt_state(rdev); } @@ -2286,8 +2364,6 @@ int evergreen_irq_process(struct radeon_device *rdev) u32 rptr = rdev->ih.rptr; u32 src_id, src_data; u32 ring_index; - u32 disp_int, disp_int_cont, disp_int_cont2; - u32 disp_int_cont3, disp_int_cont4, disp_int_cont5; unsigned long flags; bool queue_hotplug = false; @@ -2308,8 +2384,7 @@ int evergreen_irq_process(struct radeon_device *rdev) restart_ih: /* display interrupts */ - evergreen_irq_ack(rdev, &disp_int, &disp_int_cont, &disp_int_cont2, - &disp_int_cont3, &disp_int_cont4, &disp_int_cont5); + evergreen_irq_ack(rdev); rdev->ih.wptr = wptr; while (rptr != wptr) { @@ -2322,17 +2397,21 @@ restart_ih: case 1: /* D1 vblank/vline */ switch (src_data) { case 0: /* D1 vblank */ - if (disp_int & LB_D1_VBLANK_INTERRUPT) { - drm_handle_vblank(rdev->ddev, 0); - rdev->pm.vblank_sync = true; - wake_up(&rdev->irq.vblank_queue); - disp_int &= ~LB_D1_VBLANK_INTERRUPT; + if (rdev->irq.stat_regs.evergreen.disp_int & LB_D1_VBLANK_INTERRUPT) { + if (rdev->irq.pflip[0]) + radeon_crtc_handle_flip(rdev, 0); + if (rdev->irq.crtc_vblank_int[0]) { + drm_handle_vblank(rdev->ddev, 0); + rdev->pm.vblank_sync = true; + wake_up(&rdev->irq.vblank_queue); + } + rdev->irq.stat_regs.evergreen.disp_int &= ~LB_D1_VBLANK_INTERRUPT; DRM_DEBUG("IH: D1 vblank\n"); } break; case 1: /* D1 vline */ - if (disp_int & LB_D1_VLINE_INTERRUPT) { - disp_int &= ~LB_D1_VLINE_INTERRUPT; + if (rdev->irq.stat_regs.evergreen.disp_int & LB_D1_VLINE_INTERRUPT) { + rdev->irq.stat_regs.evergreen.disp_int &= ~LB_D1_VLINE_INTERRUPT; DRM_DEBUG("IH: D1 vline\n"); } break; @@ -2344,17 +2423,21 @@ restart_ih: case 2: /* D2 vblank/vline */ switch (src_data) { case 0: /* D2 vblank */ - if (disp_int_cont & LB_D2_VBLANK_INTERRUPT) { - drm_handle_vblank(rdev->ddev, 1); - rdev->pm.vblank_sync = true; - wake_up(&rdev->irq.vblank_queue); - disp_int_cont &= ~LB_D2_VBLANK_INTERRUPT; + if (rdev->irq.stat_regs.evergreen.disp_int_cont & LB_D2_VBLANK_INTERRUPT) { + if (rdev->irq.pflip[1]) + radeon_crtc_handle_flip(rdev, 1); + if (rdev->irq.crtc_vblank_int[1]) { + drm_handle_vblank(rdev->ddev, 1); + rdev->pm.vblank_sync = true; + wake_up(&rdev->irq.vblank_queue); + } + rdev->irq.stat_regs.evergreen.disp_int_cont &= ~LB_D2_VBLANK_INTERRUPT; DRM_DEBUG("IH: D2 vblank\n"); } break; case 1: /* D2 vline */ - if (disp_int_cont & LB_D2_VLINE_INTERRUPT) { - disp_int_cont &= ~LB_D2_VLINE_INTERRUPT; + if (rdev->irq.stat_regs.evergreen.disp_int_cont & LB_D2_VLINE_INTERRUPT) { + rdev->irq.stat_regs.evergreen.disp_int_cont &= ~LB_D2_VLINE_INTERRUPT; DRM_DEBUG("IH: D2 vline\n"); } break; @@ -2366,17 +2449,21 @@ restart_ih: case 3: /* D3 vblank/vline */ switch (src_data) { case 0: /* D3 vblank */ - if (disp_int_cont2 & LB_D3_VBLANK_INTERRUPT) { - drm_handle_vblank(rdev->ddev, 2); - rdev->pm.vblank_sync = true; - wake_up(&rdev->irq.vblank_queue); - disp_int_cont2 &= ~LB_D3_VBLANK_INTERRUPT; + if (rdev->irq.stat_regs.evergreen.disp_int_cont2 & LB_D3_VBLANK_INTERRUPT) { + if (rdev->irq.crtc_vblank_int[2]) { + drm_handle_vblank(rdev->ddev, 2); + rdev->pm.vblank_sync = true; + wake_up(&rdev->irq.vblank_queue); + } + if (rdev->irq.pflip[2]) + radeon_crtc_handle_flip(rdev, 2); + rdev->irq.stat_regs.evergreen.disp_int_cont2 &= ~LB_D3_VBLANK_INTERRUPT; DRM_DEBUG("IH: D3 vblank\n"); } break; case 1: /* D3 vline */ - if (disp_int_cont2 & LB_D3_VLINE_INTERRUPT) { - disp_int_cont2 &= ~LB_D3_VLINE_INTERRUPT; + if (rdev->irq.stat_regs.evergreen.disp_int_cont2 & LB_D3_VLINE_INTERRUPT) { + rdev->irq.stat_regs.evergreen.disp_int_cont2 &= ~LB_D3_VLINE_INTERRUPT; DRM_DEBUG("IH: D3 vline\n"); } break; @@ -2388,17 +2475,21 @@ restart_ih: case 4: /* D4 vblank/vline */ switch (src_data) { case 0: /* D4 vblank */ - if (disp_int_cont3 & LB_D4_VBLANK_INTERRUPT) { - drm_handle_vblank(rdev->ddev, 3); - rdev->pm.vblank_sync = true; - wake_up(&rdev->irq.vblank_queue); - disp_int_cont3 &= ~LB_D4_VBLANK_INTERRUPT; + if (rdev->irq.stat_regs.evergreen.disp_int_cont3 & LB_D4_VBLANK_INTERRUPT) { + if (rdev->irq.crtc_vblank_int[3]) { + drm_handle_vblank(rdev->ddev, 3); + rdev->pm.vblank_sync = true; + wake_up(&rdev->irq.vblank_queue); + } + if (rdev->irq.pflip[3]) + radeon_crtc_handle_flip(rdev, 3); + rdev->irq.stat_regs.evergreen.disp_int_cont3 &= ~LB_D4_VBLANK_INTERRUPT; DRM_DEBUG("IH: D4 vblank\n"); } break; case 1: /* D4 vline */ - if (disp_int_cont3 & LB_D4_VLINE_INTERRUPT) { - disp_int_cont3 &= ~LB_D4_VLINE_INTERRUPT; + if (rdev->irq.stat_regs.evergreen.disp_int_cont3 & LB_D4_VLINE_INTERRUPT) { + rdev->irq.stat_regs.evergreen.disp_int_cont3 &= ~LB_D4_VLINE_INTERRUPT; DRM_DEBUG("IH: D4 vline\n"); } break; @@ -2410,17 +2501,21 @@ restart_ih: case 5: /* D5 vblank/vline */ switch (src_data) { case 0: /* D5 vblank */ - if (disp_int_cont4 & LB_D5_VBLANK_INTERRUPT) { - drm_handle_vblank(rdev->ddev, 4); - rdev->pm.vblank_sync = true; - wake_up(&rdev->irq.vblank_queue); - disp_int_cont4 &= ~LB_D5_VBLANK_INTERRUPT; + if (rdev->irq.stat_regs.evergreen.disp_int_cont4 & LB_D5_VBLANK_INTERRUPT) { + if (rdev->irq.crtc_vblank_int[4]) { + drm_handle_vblank(rdev->ddev, 4); + rdev->pm.vblank_sync = true; + wake_up(&rdev->irq.vblank_queue); + } + if (rdev->irq.pflip[4]) + radeon_crtc_handle_flip(rdev, 4); + rdev->irq.stat_regs.evergreen.disp_int_cont4 &= ~LB_D5_VBLANK_INTERRUPT; DRM_DEBUG("IH: D5 vblank\n"); } break; case 1: /* D5 vline */ - if (disp_int_cont4 & LB_D5_VLINE_INTERRUPT) { - disp_int_cont4 &= ~LB_D5_VLINE_INTERRUPT; + if (rdev->irq.stat_regs.evergreen.disp_int_cont4 & LB_D5_VLINE_INTERRUPT) { + rdev->irq.stat_regs.evergreen.disp_int_cont4 &= ~LB_D5_VLINE_INTERRUPT; DRM_DEBUG("IH: D5 vline\n"); } break; @@ -2432,17 +2527,21 @@ restart_ih: case 6: /* D6 vblank/vline */ switch (src_data) { case 0: /* D6 vblank */ - if (disp_int_cont5 & LB_D6_VBLANK_INTERRUPT) { - drm_handle_vblank(rdev->ddev, 5); - rdev->pm.vblank_sync = true; - wake_up(&rdev->irq.vblank_queue); - disp_int_cont5 &= ~LB_D6_VBLANK_INTERRUPT; + if (rdev->irq.stat_regs.evergreen.disp_int_cont5 & LB_D6_VBLANK_INTERRUPT) { + if (rdev->irq.crtc_vblank_int[5]) { + drm_handle_vblank(rdev->ddev, 5); + rdev->pm.vblank_sync = true; + wake_up(&rdev->irq.vblank_queue); + } + if (rdev->irq.pflip[5]) + radeon_crtc_handle_flip(rdev, 5); + rdev->irq.stat_regs.evergreen.disp_int_cont5 &= ~LB_D6_VBLANK_INTERRUPT; DRM_DEBUG("IH: D6 vblank\n"); } break; case 1: /* D6 vline */ - if (disp_int_cont5 & LB_D6_VLINE_INTERRUPT) { - disp_int_cont5 &= ~LB_D6_VLINE_INTERRUPT; + if (rdev->irq.stat_regs.evergreen.disp_int_cont5 & LB_D6_VLINE_INTERRUPT) { + rdev->irq.stat_regs.evergreen.disp_int_cont5 &= ~LB_D6_VLINE_INTERRUPT; DRM_DEBUG("IH: D6 vline\n"); } break; @@ -2454,43 +2553,43 @@ restart_ih: case 42: /* HPD hotplug */ switch (src_data) { case 0: - if (disp_int & DC_HPD1_INTERRUPT) { - disp_int &= ~DC_HPD1_INTERRUPT; + if (rdev->irq.stat_regs.evergreen.disp_int & DC_HPD1_INTERRUPT) { + rdev->irq.stat_regs.evergreen.disp_int &= ~DC_HPD1_INTERRUPT; queue_hotplug = true; DRM_DEBUG("IH: HPD1\n"); } break; case 1: - if (disp_int_cont & DC_HPD2_INTERRUPT) { - disp_int_cont &= ~DC_HPD2_INTERRUPT; + if (rdev->irq.stat_regs.evergreen.disp_int_cont & DC_HPD2_INTERRUPT) { + rdev->irq.stat_regs.evergreen.disp_int_cont &= ~DC_HPD2_INTERRUPT; queue_hotplug = true; DRM_DEBUG("IH: HPD2\n"); } break; case 2: - if (disp_int_cont2 & DC_HPD3_INTERRUPT) { - disp_int_cont2 &= ~DC_HPD3_INTERRUPT; + if (rdev->irq.stat_regs.evergreen.disp_int_cont2 & DC_HPD3_INTERRUPT) { + rdev->irq.stat_regs.evergreen.disp_int_cont2 &= ~DC_HPD3_INTERRUPT; queue_hotplug = true; DRM_DEBUG("IH: HPD3\n"); } break; case 3: - if (disp_int_cont3 & DC_HPD4_INTERRUPT) { - disp_int_cont3 &= ~DC_HPD4_INTERRUPT; + if (rdev->irq.stat_regs.evergreen.disp_int_cont3 & DC_HPD4_INTERRUPT) { + rdev->irq.stat_regs.evergreen.disp_int_cont3 &= ~DC_HPD4_INTERRUPT; queue_hotplug = true; DRM_DEBUG("IH: HPD4\n"); } break; case 4: - if (disp_int_cont4 & DC_HPD5_INTERRUPT) { - disp_int_cont4 &= ~DC_HPD5_INTERRUPT; + if (rdev->irq.stat_regs.evergreen.disp_int_cont4 & DC_HPD5_INTERRUPT) { + rdev->irq.stat_regs.evergreen.disp_int_cont4 &= ~DC_HPD5_INTERRUPT; queue_hotplug = true; DRM_DEBUG("IH: HPD5\n"); } break; case 5: - if (disp_int_cont5 & DC_HPD6_INTERRUPT) { - disp_int_cont5 &= ~DC_HPD6_INTERRUPT; + if (rdev->irq.stat_regs.evergreen.disp_int_cont5 & DC_HPD6_INTERRUPT) { + rdev->irq.stat_regs.evergreen.disp_int_cont5 &= ~DC_HPD6_INTERRUPT; queue_hotplug = true; DRM_DEBUG("IH: HPD6\n"); } diff --git a/drivers/gpu/drm/radeon/evergreen_reg.h b/drivers/gpu/drm/radeon/evergreen_reg.h index 2330f3a36fd5..c781c92c3451 100644 --- a/drivers/gpu/drm/radeon/evergreen_reg.h +++ b/drivers/gpu/drm/radeon/evergreen_reg.h @@ -105,6 +105,11 @@ #define EVERGREEN_GRPH_Y_START 0x6830 #define EVERGREEN_GRPH_X_END 0x6834 #define EVERGREEN_GRPH_Y_END 0x6838 +#define EVERGREEN_GRPH_UPDATE 0x6844 +# define EVERGREEN_GRPH_SURFACE_UPDATE_PENDING (1 << 2) +# define EVERGREEN_GRPH_UPDATE_LOCK (1 << 16) +#define EVERGREEN_GRPH_FLIP_CONTROL 0x6848 +# define EVERGREEN_GRPH_SURFACE_UPDATE_H_RETRACE_EN (1 << 0) /* CUR blocks at 0x6998, 0x7598, 0x10198, 0x10d98, 0x11998, 0x12598 */ #define EVERGREEN_CUR_CONTROL 0x6998 @@ -178,6 +183,7 @@ # define EVERGREEN_CRTC_DISP_READ_REQUEST_DISABLE (1 << 24) #define EVERGREEN_CRTC_STATUS 0x6e8c #define EVERGREEN_CRTC_STATUS_POSITION 0x6e90 +#define EVERGREEN_MASTER_UPDATE_MODE 0x6ef8 #define EVERGREEN_CRTC_UPDATE_LOCK 0x6ed4 #define EVERGREEN_DC_GPIO_HPD_MASK 0x64b0 diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index 8e10aa9f74b0..b2e29798a99d 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c @@ -68,6 +68,54 @@ MODULE_FIRMWARE(FIRMWARE_R520); * r100,rv100,rs100,rv200,rs200,r200,rv250,rs300,rv280 */ +void r100_pre_page_flip(struct radeon_device *rdev, int crtc) +{ + struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc]; + u32 tmp; + + /* make sure flip is at vb rather than hb */ + tmp = RREG32(RADEON_CRTC_OFFSET_CNTL + radeon_crtc->crtc_offset); + tmp &= ~RADEON_CRTC_OFFSET_FLIP_CNTL; + WREG32(RADEON_CRTC_OFFSET_CNTL + radeon_crtc->crtc_offset, tmp); + + /* set pageflip to happen as late as possible in the vblank interval. + * same field for crtc1/2 + */ + tmp = RREG32(RADEON_CRTC_GEN_CNTL); + tmp &= ~RADEON_CRTC_VSTAT_MODE_MASK; + WREG32(RADEON_CRTC_GEN_CNTL, tmp); + + /* enable the pflip int */ + radeon_irq_kms_pflip_irq_get(rdev, crtc); +} + +void r100_post_page_flip(struct radeon_device *rdev, int crtc) +{ + /* disable the pflip int */ + radeon_irq_kms_pflip_irq_put(rdev, crtc); +} + +u32 r100_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base) +{ + struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id]; + u32 tmp = ((u32)crtc_base) | RADEON_CRTC_OFFSET__OFFSET_LOCK; + + /* Lock the graphics update lock */ + /* update the scanout addresses */ + WREG32(RADEON_CRTC_OFFSET + radeon_crtc->crtc_offset, tmp); + + /* Note: We don't wait for update_pending to assert, as this never + * happens for some reason on R1xx - R4xx. Adds a bit of imprecision. + */ + + /* Unlock the lock, so double-buffering can take place inside vblank */ + tmp &= ~RADEON_CRTC_OFFSET__OFFSET_LOCK; + WREG32(RADEON_CRTC_OFFSET + radeon_crtc->crtc_offset, tmp); + + /* Return current update_pending status: */ + return RREG32(RADEON_CRTC_OFFSET + radeon_crtc->crtc_offset) & RADEON_CRTC_OFFSET__GUI_TRIG_OFFSET; +} + void r100_pm_get_dynpm_state(struct radeon_device *rdev) { int i; @@ -526,10 +574,12 @@ int r100_irq_set(struct radeon_device *rdev) if (rdev->irq.gui_idle) { tmp |= RADEON_GUI_IDLE_MASK; } - if (rdev->irq.crtc_vblank_int[0]) { + if (rdev->irq.crtc_vblank_int[0] || + rdev->irq.pflip[0]) { tmp |= RADEON_CRTC_VBLANK_MASK; } - if (rdev->irq.crtc_vblank_int[1]) { + if (rdev->irq.crtc_vblank_int[1] || + rdev->irq.pflip[1]) { tmp |= RADEON_CRTC2_VBLANK_MASK; } if (rdev->irq.hpd[0]) { @@ -600,14 +650,22 @@ int r100_irq_process(struct radeon_device *rdev) } /* Vertical blank interrupts */ if (status & RADEON_CRTC_VBLANK_STAT) { - drm_handle_vblank(rdev->ddev, 0); - rdev->pm.vblank_sync = true; - wake_up(&rdev->irq.vblank_queue); + if (rdev->irq.pflip[0]) + radeon_crtc_handle_flip(rdev, 0); + if (rdev->irq.crtc_vblank_int[0]) { + drm_handle_vblank(rdev->ddev, 0); + rdev->pm.vblank_sync = true; + wake_up(&rdev->irq.vblank_queue); + } } if (status & RADEON_CRTC2_VBLANK_STAT) { - drm_handle_vblank(rdev->ddev, 1); - rdev->pm.vblank_sync = true; - wake_up(&rdev->irq.vblank_queue); + if (rdev->irq.pflip[1]) + radeon_crtc_handle_flip(rdev, 1); + if (rdev->irq.crtc_vblank_int[1]) { + drm_handle_vblank(rdev->ddev, 1); + rdev->pm.vblank_sync = true; + wake_up(&rdev->irq.vblank_queue); + } } if (status & RADEON_FP_DETECT_STAT) { queue_hotplug = true; diff --git a/drivers/gpu/drm/radeon/r500_reg.h b/drivers/gpu/drm/radeon/r500_reg.h index 6ac1f604e29b..fc437059918f 100644 --- a/drivers/gpu/drm/radeon/r500_reg.h +++ b/drivers/gpu/drm/radeon/r500_reg.h @@ -355,6 +355,8 @@ #define AVIVO_D1CRTC_FRAME_COUNT 0x60a4 #define AVIVO_D1CRTC_STEREO_CONTROL 0x60c4 +#define AVIVO_D1MODE_MASTER_UPDATE_MODE 0x60e4 + /* master controls */ #define AVIVO_DC_CRTC_MASTER_EN 0x60f8 #define AVIVO_DC_CRTC_TV_CONTROL 0x60fc @@ -409,8 +411,10 @@ #define AVIVO_D1GRPH_X_END 0x6134 #define AVIVO_D1GRPH_Y_END 0x6138 #define AVIVO_D1GRPH_UPDATE 0x6144 +# define AVIVO_D1GRPH_SURFACE_UPDATE_PENDING (1 << 2) # define AVIVO_D1GRPH_UPDATE_LOCK (1 << 16) #define AVIVO_D1GRPH_FLIP_CONTROL 0x6148 +# define AVIVO_D1GRPH_SURFACE_UPDATE_H_RETRACE_EN (1 << 0) #define AVIVO_D1CUR_CONTROL 0x6400 # define AVIVO_D1CURSOR_EN (1 << 0) diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index a3552594ccc4..15b95724c408 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c @@ -2863,6 +2863,8 @@ static void r600_disable_interrupt_state(struct radeon_device *rdev) WREG32(CP_INT_CNTL, CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE); WREG32(GRBM_INT_CNTL, 0); WREG32(DxMODE_INT_MASK, 0); + WREG32(D1GRPH_INTERRUPT_CONTROL, 0); + WREG32(D2GRPH_INTERRUPT_CONTROL, 0); if (ASIC_IS_DCE3(rdev)) { WREG32(DCE3_DACA_AUTODETECT_INT_CONTROL, 0); WREG32(DCE3_DACB_AUTODETECT_INT_CONTROL, 0); @@ -2987,6 +2989,7 @@ int r600_irq_set(struct radeon_device *rdev) u32 hpd1, hpd2, hpd3, hpd4 = 0, hpd5 = 0, hpd6 = 0; u32 grbm_int_cntl = 0; u32 hdmi1, hdmi2; + u32 d1grph = 0, d2grph = 0; if (!rdev->irq.installed) { WARN(1, "Can't enable IRQ/MSI because no handler is installed\n"); @@ -3023,11 +3026,13 @@ int r600_irq_set(struct radeon_device *rdev) cp_int_cntl |= RB_INT_ENABLE; cp_int_cntl |= TIME_STAMP_INT_ENABLE; } - if (rdev->irq.crtc_vblank_int[0]) { + if (rdev->irq.crtc_vblank_int[0] || + rdev->irq.pflip[0]) { DRM_DEBUG("r600_irq_set: vblank 0\n"); mode_int |= D1MODE_VBLANK_INT_MASK; } - if (rdev->irq.crtc_vblank_int[1]) { + if (rdev->irq.crtc_vblank_int[1] || + rdev->irq.pflip[1]) { DRM_DEBUG("r600_irq_set: vblank 1\n"); mode_int |= D2MODE_VBLANK_INT_MASK; } @@ -3070,6 +3075,8 @@ int r600_irq_set(struct radeon_device *rdev) WREG32(CP_INT_CNTL, cp_int_cntl); WREG32(DxMODE_INT_MASK, mode_int); + WREG32(D1GRPH_INTERRUPT_CONTROL, d1grph); + WREG32(D2GRPH_INTERRUPT_CONTROL, d2grph); WREG32(GRBM_INT_CNTL, grbm_int_cntl); WREG32(R600_HDMI_BLOCK1 + R600_HDMI_CNTL, hdmi1); if (ASIC_IS_DCE3(rdev)) { @@ -3092,32 +3099,35 @@ int r600_irq_set(struct radeon_device *rdev) return 0; } -static inline void r600_irq_ack(struct radeon_device *rdev, - u32 *disp_int, - u32 *disp_int_cont, - u32 *disp_int_cont2) +static inline void r600_irq_ack(struct radeon_device *rdev) { u32 tmp; if (ASIC_IS_DCE3(rdev)) { - *disp_int = RREG32(DCE3_DISP_INTERRUPT_STATUS); - *disp_int_cont = RREG32(DCE3_DISP_INTERRUPT_STATUS_CONTINUE); - *disp_int_cont2 = RREG32(DCE3_DISP_INTERRUPT_STATUS_CONTINUE2); + rdev->irq.stat_regs.r600.disp_int = RREG32(DCE3_DISP_INTERRUPT_STATUS); + rdev->irq.stat_regs.r600.disp_int_cont = RREG32(DCE3_DISP_INTERRUPT_STATUS_CONTINUE); + rdev->irq.stat_regs.r600.disp_int_cont2 = RREG32(DCE3_DISP_INTERRUPT_STATUS_CONTINUE2); } else { - *disp_int = RREG32(DISP_INTERRUPT_STATUS); - *disp_int_cont = RREG32(DISP_INTERRUPT_STATUS_CONTINUE); - *disp_int_cont2 = 0; - } - - if (*disp_int & LB_D1_VBLANK_INTERRUPT) + rdev->irq.stat_regs.r600.disp_int = RREG32(DISP_INTERRUPT_STATUS); + rdev->irq.stat_regs.r600.disp_int_cont = RREG32(DISP_INTERRUPT_STATUS_CONTINUE); + rdev->irq.stat_regs.r600.disp_int_cont2 = 0; + } + rdev->irq.stat_regs.r600.d1grph_int = RREG32(D1GRPH_INTERRUPT_STATUS); + rdev->irq.stat_regs.r600.d2grph_int = RREG32(D2GRPH_INTERRUPT_STATUS); + + if (rdev->irq.stat_regs.r600.d1grph_int & DxGRPH_PFLIP_INT_OCCURRED) + WREG32(D1GRPH_INTERRUPT_STATUS, DxGRPH_PFLIP_INT_CLEAR); + if (rdev->irq.stat_regs.r600.d2grph_int & DxGRPH_PFLIP_INT_OCCURRED) + WREG32(D2GRPH_INTERRUPT_STATUS, DxGRPH_PFLIP_INT_CLEAR); + if (rdev->irq.stat_regs.r600.disp_int & LB_D1_VBLANK_INTERRUPT) WREG32(D1MODE_VBLANK_STATUS, DxMODE_VBLANK_ACK); - if (*disp_int & LB_D1_VLINE_INTERRUPT) + if (rdev->irq.stat_regs.r600.disp_int & LB_D1_VLINE_INTERRUPT) WREG32(D1MODE_VLINE_STATUS, DxMODE_VLINE_ACK); - if (*disp_int & LB_D2_VBLANK_INTERRUPT) + if (rdev->irq.stat_regs.r600.disp_int & LB_D2_VBLANK_INTERRUPT) WREG32(D2MODE_VBLANK_STATUS, DxMODE_VBLANK_ACK); - if (*disp_int & LB_D2_VLINE_INTERRUPT) + if (rdev->irq.stat_regs.r600.disp_int & LB_D2_VLINE_INTERRUPT) WREG32(D2MODE_VLINE_STATUS, DxMODE_VLINE_ACK); - if (*disp_int & DC_HPD1_INTERRUPT) { + if (rdev->irq.stat_regs.r600.disp_int & DC_HPD1_INTERRUPT) { if (ASIC_IS_DCE3(rdev)) { tmp = RREG32(DC_HPD1_INT_CONTROL); tmp |= DC_HPDx_INT_ACK; @@ -3128,7 +3138,7 @@ static inline void r600_irq_ack(struct radeon_device *rdev, WREG32(DC_HOT_PLUG_DETECT1_INT_CONTROL, tmp); } } - if (*disp_int & DC_HPD2_INTERRUPT) { + if (rdev->irq.stat_regs.r600.disp_int & DC_HPD2_INTERRUPT) { if (ASIC_IS_DCE3(rdev)) { tmp = RREG32(DC_HPD2_INT_CONTROL); tmp |= DC_HPDx_INT_ACK; @@ -3139,7 +3149,7 @@ static inline void r600_irq_ack(struct radeon_device *rdev, WREG32(DC_HOT_PLUG_DETECT2_INT_CONTROL, tmp); } } - if (*disp_int_cont & DC_HPD3_INTERRUPT) { + if (rdev->irq.stat_regs.r600.disp_int_cont & DC_HPD3_INTERRUPT) { if (ASIC_IS_DCE3(rdev)) { tmp = RREG32(DC_HPD3_INT_CONTROL); tmp |= DC_HPDx_INT_ACK; @@ -3150,18 +3160,18 @@ static inline void r600_irq_ack(struct radeon_device *rdev, WREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL, tmp); } } - if (*disp_int_cont & DC_HPD4_INTERRUPT) { + if (rdev->irq.stat_regs.r600.disp_int_cont & DC_HPD4_INTERRUPT) { tmp = RREG32(DC_HPD4_INT_CONTROL); tmp |= DC_HPDx_INT_ACK; WREG32(DC_HPD4_INT_CONTROL, tmp); } if (ASIC_IS_DCE32(rdev)) { - if (*disp_int_cont2 & DC_HPD5_INTERRUPT) { + if (rdev->irq.stat_regs.r600.disp_int_cont2 & DC_HPD5_INTERRUPT) { tmp = RREG32(DC_HPD5_INT_CONTROL); tmp |= DC_HPDx_INT_ACK; WREG32(DC_HPD5_INT_CONTROL, tmp); } - if (*disp_int_cont2 & DC_HPD6_INTERRUPT) { + if (rdev->irq.stat_regs.r600.disp_int_cont2 & DC_HPD6_INTERRUPT) { tmp = RREG32(DC_HPD5_INT_CONTROL); tmp |= DC_HPDx_INT_ACK; WREG32(DC_HPD6_INT_CONTROL, tmp); @@ -3183,12 +3193,10 @@ static inline void r600_irq_ack(struct radeon_device *rdev, void r600_irq_disable(struct radeon_device *rdev) { - u32 disp_int, disp_int_cont, disp_int_cont2; - r600_disable_interrupts(rdev); /* Wait and acknowledge irq */ mdelay(1); - r600_irq_ack(rdev, &disp_int, &disp_int_cont, &disp_int_cont2); + r600_irq_ack(rdev); r600_disable_interrupt_state(rdev); } @@ -3251,7 +3259,7 @@ int r600_irq_process(struct radeon_device *rdev) u32 wptr = r600_get_ih_wptr(rdev); u32 rptr = rdev->ih.rptr; u32 src_id, src_data; - u32 ring_index, disp_int, disp_int_cont, disp_int_cont2; + u32 ring_index; unsigned long flags; bool queue_hotplug = false; @@ -3272,7 +3280,7 @@ int r600_irq_process(struct radeon_device *rdev) restart_ih: /* display interrupts */ - r600_irq_ack(rdev, &disp_int, &disp_int_cont, &disp_int_cont2); + r600_irq_ack(rdev); rdev->ih.wptr = wptr; while (rptr != wptr) { @@ -3285,17 +3293,21 @@ restart_ih: case 1: /* D1 vblank/vline */ switch (src_data) { case 0: /* D1 vblank */ - if (disp_int & LB_D1_VBLANK_INTERRUPT) { - drm_handle_vblank(rdev->ddev, 0); - rdev->pm.vblank_sync = true; - wake_up(&rdev->irq.vblank_queue); - disp_int &= ~LB_D1_VBLANK_INTERRUPT; + if (rdev->irq.stat_regs.r600.disp_int & LB_D1_VBLANK_INTERRUPT) { + if (rdev->irq.pflip[0]) + radeon_crtc_handle_flip(rdev, 0); + if (rdev->irq.crtc_vblank_int[0]) { + drm_handle_vblank(rdev->ddev, 0); + rdev->pm.vblank_sync = true; + wake_up(&rdev->irq.vblank_queue); + } + rdev->irq.stat_regs.r600.disp_int &= ~LB_D1_VBLANK_INTERRUPT; DRM_DEBUG("IH: D1 vblank\n"); } break; case 1: /* D1 vline */ - if (disp_int & LB_D1_VLINE_INTERRUPT) { - disp_int &= ~LB_D1_VLINE_INTERRUPT; + if (rdev->irq.stat_regs.r600.disp_int & LB_D1_VLINE_INTERRUPT) { + rdev->irq.stat_regs.r600.disp_int &= ~LB_D1_VLINE_INTERRUPT; DRM_DEBUG("IH: D1 vline\n"); } break; @@ -3307,17 +3319,21 @@ restart_ih: case 5: /* D2 vblank/vline */ switch (src_data) { case 0: /* D2 vblank */ - if (disp_int & LB_D2_VBLANK_INTERRUPT) { - drm_handle_vblank(rdev->ddev, 1); - rdev->pm.vblank_sync = true; - wake_up(&rdev->irq.vblank_queue); - disp_int &= ~LB_D2_VBLANK_INTERRUPT; + if (rdev->irq.stat_regs.r600.disp_int & LB_D2_VBLANK_INTERRUPT) { + if (rdev->irq.pflip[1]) + radeon_crtc_handle_flip(rdev, 1); + if (rdev->irq.crtc_vblank_int[1]) { + drm_handle_vblank(rdev->ddev, 1); + rdev->pm.vblank_sync = true; + wake_up(&rdev->irq.vblank_queue); + } + rdev->irq.stat_regs.r600.disp_int &= ~LB_D2_VBLANK_INTERRUPT; DRM_DEBUG("IH: D2 vblank\n"); } break; case 1: /* D1 vline */ - if (disp_int & LB_D2_VLINE_INTERRUPT) { - disp_int &= ~LB_D2_VLINE_INTERRUPT; + if (rdev->irq.stat_regs.r600.disp_int & LB_D2_VLINE_INTERRUPT) { + rdev->irq.stat_regs.r600.disp_int &= ~LB_D2_VLINE_INTERRUPT; DRM_DEBUG("IH: D2 vline\n"); } break; @@ -3329,43 +3345,43 @@ restart_ih: case 19: /* HPD/DAC hotplug */ switch (src_data) { case 0: - if (disp_int & DC_HPD1_INTERRUPT) { - disp_int &= ~DC_HPD1_INTERRUPT; + if (rdev->irq.stat_regs.r600.disp_int & DC_HPD1_INTERRUPT) { + rdev->irq.stat_regs.r600.disp_int &= ~DC_HPD1_INTERRUPT; queue_hotplug = true; DRM_DEBUG("IH: HPD1\n"); } break; case 1: - if (disp_int & DC_HPD2_INTERRUPT) { - disp_int &= ~DC_HPD2_INTERRUPT; + if (rdev->irq.stat_regs.r600.disp_int & DC_HPD2_INTERRUPT) { + rdev->irq.stat_regs.r600.disp_int &= ~DC_HPD2_INTERRUPT; queue_hotplug = true; DRM_DEBUG("IH: HPD2\n"); } break; case 4: - if (disp_int_cont & DC_HPD3_INTERRUPT) { - disp_int_cont &= ~DC_HPD3_INTERRUPT; + if (rdev->irq.stat_regs.r600.disp_int_cont & DC_HPD3_INTERRUPT) { + rdev->irq.stat_regs.r600.disp_int_cont &= ~DC_HPD3_INTERRUPT; queue_hotplug = true; DRM_DEBUG("IH: HPD3\n"); } break; case 5: - if (disp_int_cont & DC_HPD4_INTERRUPT) { - disp_int_cont &= ~DC_HPD4_INTERRUPT; + if (rdev->irq.stat_regs.r600.disp_int_cont & DC_HPD4_INTERRUPT) { + rdev->irq.stat_regs.r600.disp_int_cont &= ~DC_HPD4_INTERRUPT; queue_hotplug = true; DRM_DEBUG("IH: HPD4\n"); } break; case 10: - if (disp_int_cont2 & DC_HPD5_INTERRUPT) { - disp_int_cont2 &= ~DC_HPD5_INTERRUPT; + if (rdev->irq.stat_regs.r600.disp_int_cont2 & DC_HPD5_INTERRUPT) { + rdev->irq.stat_regs.r600.disp_int_cont2 &= ~DC_HPD5_INTERRUPT; queue_hotplug = true; DRM_DEBUG("IH: HPD5\n"); } break; case 12: - if (disp_int_cont2 & DC_HPD6_INTERRUPT) { - disp_int_cont2 &= ~DC_HPD6_INTERRUPT; + if (rdev->irq.stat_regs.r600.disp_int_cont2 & DC_HPD6_INTERRUPT) { + rdev->irq.stat_regs.r600.disp_int_cont2 &= ~DC_HPD6_INTERRUPT; queue_hotplug = true; DRM_DEBUG("IH: HPD6\n"); } diff --git a/drivers/gpu/drm/radeon/r600d.h b/drivers/gpu/drm/radeon/r600d.h index bff4dc4f410f..c89cfa8e0c05 100644 --- a/drivers/gpu/drm/radeon/r600d.h +++ b/drivers/gpu/drm/radeon/r600d.h @@ -728,6 +728,15 @@ /* DCE 3.2 */ # define DC_HPDx_EN (1 << 28) +#define D1GRPH_INTERRUPT_STATUS 0x6158 +#define D2GRPH_INTERRUPT_STATUS 0x6958 +# define DxGRPH_PFLIP_INT_OCCURRED (1 << 0) +# define DxGRPH_PFLIP_INT_CLEAR (1 << 8) +#define D1GRPH_INTERRUPT_CONTROL 0x615c +#define D2GRPH_INTERRUPT_CONTROL 0x695c +# define DxGRPH_PFLIP_INT_MASK (1 << 0) +# define DxGRPH_PFLIP_INT_TYPE (1 << 8) + /* * PM4 */ diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 3a7095743d44..ddf1eca13401 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -377,11 +377,56 @@ void radeon_scratch_free(struct radeon_device *rdev, uint32_t reg); /* * IRQS. */ + +struct radeon_unpin_work { + struct work_struct work; + struct radeon_device *rdev; + int crtc_id; + struct radeon_fence *fence; + struct drm_pending_vblank_event *event; + struct radeon_bo *old_rbo; + u64 new_crtc_base; +}; + +struct r500_irq_stat_regs { + u32 disp_int; +}; + +struct r600_irq_stat_regs { + u32 disp_int; + u32 disp_int_cont; + u32 disp_int_cont2; + u32 d1grph_int; + u32 d2grph_int; +}; + +struct evergreen_irq_stat_regs { + u32 disp_int; + u32 disp_int_cont; + u32 disp_int_cont2; + u32 disp_int_cont3; + u32 disp_int_cont4; + u32 disp_int_cont5; + u32 d1grph_int; + u32 d2grph_int; + u32 d3grph_int; + u32 d4grph_int; + u32 d5grph_int; + u32 d6grph_int; +}; + +union radeon_irq_stat_regs { + struct r500_irq_stat_regs r500; + struct r600_irq_stat_regs r600; + struct evergreen_irq_stat_regs evergreen; +}; + struct radeon_irq { bool installed; bool sw_int; /* FIXME: use a define max crtc rather than hardcode it */ bool crtc_vblank_int[6]; + bool pflip[6]; wait_queue_head_t vblank_queue; /* FIXME: use defines for max hpd/dacs */ bool hpd[6]; @@ -392,12 +437,17 @@ struct radeon_irq { bool hdmi[2]; spinlock_t sw_lock; int sw_refcount; + union radeon_irq_stat_regs stat_regs; + spinlock_t pflip_lock[6]; + int pflip_refcount[6]; }; int radeon_irq_kms_init(struct radeon_device *rdev); void radeon_irq_kms_fini(struct radeon_device *rdev); void radeon_irq_kms_sw_irq_get(struct radeon_device *rdev); void radeon_irq_kms_sw_irq_put(struct radeon_device *rdev); +void radeon_irq_kms_pflip_irq_get(struct radeon_device *rdev, int crtc); +void radeon_irq_kms_pflip_irq_put(struct radeon_device *rdev, int crtc); /* * CP & ring. @@ -881,6 +931,10 @@ struct radeon_asic { void (*pm_finish)(struct radeon_device *rdev); void (*pm_init_profile)(struct radeon_device *rdev); void (*pm_get_dynpm_state)(struct radeon_device *rdev); + /* pageflipping */ + void (*pre_page_flip)(struct radeon_device *rdev, int crtc); + u32 (*page_flip)(struct radeon_device *rdev, int crtc, u64 crtc_base); + void (*post_page_flip)(struct radeon_device *rdev, int crtc); }; /* @@ -1344,6 +1398,9 @@ static inline void radeon_ring_write(struct radeon_device *rdev, uint32_t v) #define radeon_pm_finish(rdev) (rdev)->asic->pm_finish((rdev)) #define radeon_pm_init_profile(rdev) (rdev)->asic->pm_init_profile((rdev)) #define radeon_pm_get_dynpm_state(rdev) (rdev)->asic->pm_get_dynpm_state((rdev)) +#define radeon_pre_page_flip(rdev, crtc) rdev->asic->pre_page_flip((rdev), (crtc)) +#define radeon_page_flip(rdev, crtc, base) rdev->asic->page_flip((rdev), (crtc), (base)) +#define radeon_post_page_flip(rdev, crtc) rdev->asic->post_page_flip((rdev), (crtc)) /* Common functions */ /* AGP */ diff --git a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c index 64fb89ecbf74..6b126b3f5fa9 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.c +++ b/drivers/gpu/drm/radeon/radeon_asic.c @@ -171,6 +171,9 @@ static struct radeon_asic r100_asic = { .pm_finish = &r100_pm_finish, .pm_init_profile = &r100_pm_init_profile, .pm_get_dynpm_state = &r100_pm_get_dynpm_state, + .pre_page_flip = &r100_pre_page_flip, + .page_flip = &r100_page_flip, + .post_page_flip = &r100_post_page_flip, }; static struct radeon_asic r200_asic = { @@ -215,6 +218,9 @@ static struct radeon_asic r200_asic = { .pm_finish = &r100_pm_finish, .pm_init_profile = &r100_pm_init_profile, .pm_get_dynpm_state = &r100_pm_get_dynpm_state, + .pre_page_flip = &r100_pre_page_flip, + .page_flip = &r100_page_flip, + .post_page_flip = &r100_post_page_flip, }; static struct radeon_asic r300_asic = { @@ -260,6 +266,9 @@ static struct radeon_asic r300_asic = { .pm_finish = &r100_pm_finish, .pm_init_profile = &r100_pm_init_profile, .pm_get_dynpm_state = &r100_pm_get_dynpm_state, + .pre_page_flip = &r100_pre_page_flip, + .page_flip = &r100_page_flip, + .post_page_flip = &r100_post_page_flip, }; static struct radeon_asic r300_asic_pcie = { @@ -304,6 +313,9 @@ static struct radeon_asic r300_asic_pcie = { .pm_finish = &r100_pm_finish, .pm_init_profile = &r100_pm_init_profile, .pm_get_dynpm_state = &r100_pm_get_dynpm_state, + .pre_page_flip = &r100_pre_page_flip, + .page_flip = &r100_page_flip, + .post_page_flip = &r100_post_page_flip, }; static struct radeon_asic r420_asic = { @@ -349,6 +361,9 @@ static struct radeon_asic r420_asic = { .pm_finish = &r100_pm_finish, .pm_init_profile = &r420_pm_init_profile, .pm_get_dynpm_state = &r100_pm_get_dynpm_state, + .pre_page_flip = &r100_pre_page_flip, + .page_flip = &r100_page_flip, + .post_page_flip = &r100_post_page_flip, }; static struct radeon_asic rs400_asic = { @@ -394,6 +409,9 @@ static struct radeon_asic rs400_asic = { .pm_finish = &r100_pm_finish, .pm_init_profile = &r100_pm_init_profile, .pm_get_dynpm_state = &r100_pm_get_dynpm_state, + .pre_page_flip = &r100_pre_page_flip, + .page_flip = &r100_page_flip, + .post_page_flip = &r100_post_page_flip, }; static struct radeon_asic rs600_asic = { @@ -439,6 +457,9 @@ static struct radeon_asic rs600_asic = { .pm_finish = &rs600_pm_finish, .pm_init_profile = &r420_pm_init_profile, .pm_get_dynpm_state = &r100_pm_get_dynpm_state, + .pre_page_flip = &rs600_pre_page_flip, + .page_flip = &rs600_page_flip, + .post_page_flip = &rs600_post_page_flip, }; static struct radeon_asic rs690_asic = { @@ -484,6 +505,9 @@ static struct radeon_asic rs690_asic = { .pm_finish = &rs600_pm_finish, .pm_init_profile = &r420_pm_init_profile, .pm_get_dynpm_state = &r100_pm_get_dynpm_state, + .pre_page_flip = &rs600_pre_page_flip, + .page_flip = &rs600_page_flip, + .post_page_flip = &rs600_post_page_flip, }; static struct radeon_asic rv515_asic = { @@ -529,6 +553,9 @@ static struct radeon_asic rv515_asic = { .pm_finish = &rs600_pm_finish, .pm_init_profile = &r420_pm_init_profile, .pm_get_dynpm_state = &r100_pm_get_dynpm_state, + .pre_page_flip = &rs600_pre_page_flip, + .page_flip = &rs600_page_flip, + .post_page_flip = &rs600_post_page_flip, }; static struct radeon_asic r520_asic = { @@ -574,6 +601,9 @@ static struct radeon_asic r520_asic = { .pm_finish = &rs600_pm_finish, .pm_init_profile = &r420_pm_init_profile, .pm_get_dynpm_state = &r100_pm_get_dynpm_state, + .pre_page_flip = &rs600_pre_page_flip, + .page_flip = &rs600_page_flip, + .post_page_flip = &rs600_post_page_flip, }; static struct radeon_asic r600_asic = { @@ -618,6 +648,9 @@ static struct radeon_asic r600_asic = { .pm_finish = &rs600_pm_finish, .pm_init_profile = &r600_pm_init_profile, .pm_get_dynpm_state = &r600_pm_get_dynpm_state, + .pre_page_flip = &rs600_pre_page_flip, + .page_flip = &rs600_page_flip, + .post_page_flip = &rs600_post_page_flip, }; static struct radeon_asic rs780_asic = { @@ -662,6 +695,9 @@ static struct radeon_asic rs780_asic = { .pm_finish = &rs600_pm_finish, .pm_init_profile = &rs780_pm_init_profile, .pm_get_dynpm_state = &r600_pm_get_dynpm_state, + .pre_page_flip = &rs600_pre_page_flip, + .page_flip = &rs600_page_flip, + .post_page_flip = &rs600_post_page_flip, }; static struct radeon_asic rv770_asic = { @@ -706,6 +742,9 @@ static struct radeon_asic rv770_asic = { .pm_finish = &rs600_pm_finish, .pm_init_profile = &r600_pm_init_profile, .pm_get_dynpm_state = &r600_pm_get_dynpm_state, + .pre_page_flip = &rs600_pre_page_flip, + .page_flip = &rv770_page_flip, + .post_page_flip = &rs600_post_page_flip, }; static struct radeon_asic evergreen_asic = { @@ -749,6 +788,9 @@ static struct radeon_asic evergreen_asic = { .pm_finish = &evergreen_pm_finish, .pm_init_profile = &r600_pm_init_profile, .pm_get_dynpm_state = &r600_pm_get_dynpm_state, + .pre_page_flip = &evergreen_pre_page_flip, + .page_flip = &evergreen_page_flip, + .post_page_flip = &evergreen_post_page_flip, }; int radeon_asic_init(struct radeon_device *rdev) diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h index 740988244143..4970eda1bd41 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.h +++ b/drivers/gpu/drm/radeon/radeon_asic.h @@ -130,6 +130,9 @@ extern void r100_pm_prepare(struct radeon_device *rdev); extern void r100_pm_finish(struct radeon_device *rdev); extern void r100_pm_init_profile(struct radeon_device *rdev); extern void r100_pm_get_dynpm_state(struct radeon_device *rdev); +extern void r100_pre_page_flip(struct radeon_device *rdev, int crtc); +extern u32 r100_page_flip(struct radeon_device *rdev, int crtc, u64 crtc_base); +extern void r100_post_page_flip(struct radeon_device *rdev, int crtc); /* * r200,rv250,rs300,rv280 @@ -205,6 +208,9 @@ void rs600_hpd_set_polarity(struct radeon_device *rdev, extern void rs600_pm_misc(struct radeon_device *rdev); extern void rs600_pm_prepare(struct radeon_device *rdev); extern void rs600_pm_finish(struct radeon_device *rdev); +extern void rs600_pre_page_flip(struct radeon_device *rdev, int crtc); +extern u32 rs600_page_flip(struct radeon_device *rdev, int crtc, u64 crtc_base); +extern void rs600_post_page_flip(struct radeon_device *rdev, int crtc); /* * rs690,rs740 @@ -287,6 +293,7 @@ void rv770_fini(struct radeon_device *rdev); int rv770_suspend(struct radeon_device *rdev); int rv770_resume(struct radeon_device *rdev); extern void rv770_pm_misc(struct radeon_device *rdev); +extern u32 rv770_page_flip(struct radeon_device *rdev, int crtc, u64 crtc_base); /* * evergreen @@ -314,5 +321,8 @@ extern int evergreen_cs_parse(struct radeon_cs_parser *p); extern void evergreen_pm_misc(struct radeon_device *rdev); extern void evergreen_pm_prepare(struct radeon_device *rdev); extern void evergreen_pm_finish(struct radeon_device *rdev); +extern void evergreen_pre_page_flip(struct radeon_device *rdev, int crtc); +extern u32 evergreen_page_flip(struct radeon_device *rdev, int crtc, u64 crtc_base); +extern void evergreen_post_page_flip(struct radeon_device *rdev, int crtc); #endif diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c index eeea7cbb9517..f6493f444faa 100644 --- a/drivers/gpu/drm/radeon/radeon_display.c +++ b/drivers/gpu/drm/radeon/radeon_display.c @@ -183,12 +183,273 @@ static void radeon_crtc_destroy(struct drm_crtc *crtc) kfree(radeon_crtc); } +/* + * Handle unpin events outside the interrupt handler proper. + */ +static void radeon_unpin_work_func(struct work_struct *__work) +{ + struct radeon_unpin_work *work = + container_of(__work, struct radeon_unpin_work, work); + int r; + + /* unpin of the old buffer */ + r = radeon_bo_reserve(work->old_rbo, false); + if (likely(r == 0)) { + r = radeon_bo_unpin(work->old_rbo); + if (unlikely(r != 0)) { + DRM_ERROR("failed to unpin buffer after flip\n"); + } + radeon_bo_unreserve(work->old_rbo); + } else + DRM_ERROR("failed to reserve buffer after flip\n"); + kfree(work); +} + +void radeon_crtc_handle_flip(struct radeon_device *rdev, int crtc_id) +{ + struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id]; + struct radeon_unpin_work *work; + struct drm_pending_vblank_event *e; + struct timeval now; + unsigned long flags; + u32 update_pending; + int vpos, hpos; + + spin_lock_irqsave(&rdev->ddev->event_lock, flags); + work = radeon_crtc->unpin_work; + if (work == NULL || + !radeon_fence_signaled(work->fence)) { + spin_unlock_irqrestore(&rdev->ddev->event_lock, flags); + return; + } + /* New pageflip, or just completion of a previous one? */ + if (!radeon_crtc->deferred_flip_completion) { + /* do the flip (mmio) */ + update_pending = radeon_page_flip(rdev, crtc_id, work->new_crtc_base); + } else { + /* This is just a completion of a flip queued in crtc + * at last invocation. Make sure we go directly to + * completion routine. + */ + update_pending = 0; + radeon_crtc->deferred_flip_completion = 0; + } + + /* Has the pageflip already completed in crtc, or is it certain + * to complete in this vblank? + */ + if (update_pending && + (DRM_SCANOUTPOS_VALID & radeon_get_crtc_scanoutpos(rdev->ddev, crtc_id, + &vpos, &hpos)) && + (vpos >=0) && + (vpos < (99 * rdev->mode_info.crtcs[crtc_id]->base.hwmode.crtc_vdisplay)/100)) { + /* crtc didn't flip in this target vblank interval, + * but flip is pending in crtc. It will complete it + * in next vblank interval, so complete the flip at + * next vblank irq. + */ + radeon_crtc->deferred_flip_completion = 1; + spin_unlock_irqrestore(&rdev->ddev->event_lock, flags); + return; + } + + /* Pageflip (will be) certainly completed in this vblank. Clean up. */ + radeon_crtc->unpin_work = NULL; + + /* wakeup userspace */ + if (work->event) { + e = work->event; + do_gettimeofday(&now); + e->event.sequence = drm_vblank_count(rdev->ddev, radeon_crtc->crtc_id); + e->event.tv_sec = now.tv_sec; + e->event.tv_usec = now.tv_usec; + list_add_tail(&e->base.link, &e->base.file_priv->event_list); + wake_up_interruptible(&e->base.file_priv->event_wait); + } + spin_unlock_irqrestore(&rdev->ddev->event_lock, flags); + + drm_vblank_put(rdev->ddev, radeon_crtc->crtc_id); + radeon_fence_unref(&work->fence); + radeon_post_page_flip(work->rdev, work->crtc_id); + schedule_work(&work->work); +} + +static int radeon_crtc_page_flip(struct drm_crtc *crtc, + struct drm_framebuffer *fb, + struct drm_pending_vblank_event *event) +{ + struct drm_device *dev = crtc->dev; + struct radeon_device *rdev = dev->dev_private; + struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); + struct radeon_framebuffer *old_radeon_fb; + struct radeon_framebuffer *new_radeon_fb; + struct drm_gem_object *obj; + struct radeon_bo *rbo; + struct radeon_fence *fence; + struct radeon_unpin_work *work; + unsigned long flags; + u32 tiling_flags, pitch_pixels; + u64 base; + int r; + + work = kzalloc(sizeof *work, GFP_KERNEL); + if (work == NULL) + return -ENOMEM; + + r = radeon_fence_create(rdev, &fence); + if (unlikely(r != 0)) { + kfree(work); + DRM_ERROR("flip queue: failed to create fence.\n"); + return -ENOMEM; + } + work->event = event; + work->rdev = rdev; + work->crtc_id = radeon_crtc->crtc_id; + work->fence = radeon_fence_ref(fence); + old_radeon_fb = to_radeon_framebuffer(crtc->fb); + new_radeon_fb = to_radeon_framebuffer(fb); + /* schedule unpin of the old buffer */ + obj = old_radeon_fb->obj; + rbo = obj->driver_private; + work->old_rbo = rbo; + INIT_WORK(&work->work, radeon_unpin_work_func); + + /* We borrow the event spin lock for protecting unpin_work */ + spin_lock_irqsave(&dev->event_lock, flags); + if (radeon_crtc->unpin_work) { + spin_unlock_irqrestore(&dev->event_lock, flags); + kfree(work); + radeon_fence_unref(&fence); + + DRM_DEBUG_DRIVER("flip queue: crtc already busy\n"); + return -EBUSY; + } + radeon_crtc->unpin_work = work; + radeon_crtc->deferred_flip_completion = 0; + spin_unlock_irqrestore(&dev->event_lock, flags); + + /* pin the new buffer */ + obj = new_radeon_fb->obj; + rbo = obj->driver_private; + + DRM_DEBUG_DRIVER("flip-ioctl() cur_fbo = %p, cur_bbo = %p\n", + work->old_rbo, rbo); + + r = radeon_bo_reserve(rbo, false); + if (unlikely(r != 0)) { + DRM_ERROR("failed to reserve new rbo buffer before flip\n"); + goto pflip_cleanup; + } + r = radeon_bo_pin(rbo, RADEON_GEM_DOMAIN_VRAM, &base); + if (unlikely(r != 0)) { + radeon_bo_unreserve(rbo); + r = -EINVAL; + DRM_ERROR("failed to pin new rbo buffer before flip\n"); + goto pflip_cleanup; + } + radeon_bo_get_tiling_flags(rbo, &tiling_flags, NULL); + radeon_bo_unreserve(rbo); + + if (!ASIC_IS_AVIVO(rdev)) { + /* crtc offset is from display base addr not FB location */ + base -= radeon_crtc->legacy_display_base_addr; + pitch_pixels = fb->pitch / (fb->bits_per_pixel / 8); + + if (tiling_flags & RADEON_TILING_MACRO) { + if (ASIC_IS_R300(rdev)) { + base &= ~0x7ff; + } else { + int byteshift = fb->bits_per_pixel >> 4; + int tile_addr = (((crtc->y >> 3) * pitch_pixels + crtc->x) >> (8 - byteshift)) << 11; + base += tile_addr + ((crtc->x << byteshift) % 256) + ((crtc->y % 8) << 8); + } + } else { + int offset = crtc->y * pitch_pixels + crtc->x; + switch (fb->bits_per_pixel) { + case 8: + default: + offset *= 1; + break; + case 15: + case 16: + offset *= 2; + break; + case 24: + offset *= 3; + break; + case 32: + offset *= 4; + break; + } + base += offset; + } + base &= ~7; + } + + spin_lock_irqsave(&dev->event_lock, flags); + work->new_crtc_base = base; + spin_unlock_irqrestore(&dev->event_lock, flags); + + /* update crtc fb */ + crtc->fb = fb; + + r = drm_vblank_get(dev, radeon_crtc->crtc_id); + if (r) { + DRM_ERROR("failed to get vblank before flip\n"); + goto pflip_cleanup1; + } + + /* 32 ought to cover us */ + r = radeon_ring_lock(rdev, 32); + if (r) { + DRM_ERROR("failed to lock the ring before flip\n"); + goto pflip_cleanup2; + } + + /* emit the fence */ + radeon_fence_emit(rdev, fence); + /* set the proper interrupt */ + radeon_pre_page_flip(rdev, radeon_crtc->crtc_id); + /* fire the ring */ + radeon_ring_unlock_commit(rdev); + + return 0; + +pflip_cleanup2: + drm_vblank_put(dev, radeon_crtc->crtc_id); + +pflip_cleanup1: + r = radeon_bo_reserve(rbo, false); + if (unlikely(r != 0)) { + DRM_ERROR("failed to reserve new rbo in error path\n"); + goto pflip_cleanup; + } + r = radeon_bo_unpin(rbo); + if (unlikely(r != 0)) { + radeon_bo_unreserve(rbo); + r = -EINVAL; + DRM_ERROR("failed to unpin new rbo in error path\n"); + goto pflip_cleanup; + } + radeon_bo_unreserve(rbo); + +pflip_cleanup: + spin_lock_irqsave(&dev->event_lock, flags); + radeon_crtc->unpin_work = NULL; + spin_unlock_irqrestore(&dev->event_lock, flags); + radeon_fence_unref(&fence); + kfree(work); + + return r; +} + static const struct drm_crtc_funcs radeon_crtc_funcs = { .cursor_set = radeon_crtc_cursor_set, .cursor_move = radeon_crtc_cursor_move, .gamma_set = radeon_crtc_gamma_set, .set_config = drm_crtc_helper_set_config, .destroy = radeon_crtc_destroy, + .page_flip = radeon_crtc_page_flip, }; static void radeon_crtc_init(struct drm_device *dev, int index) diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index 32ec0cc6be92..a92d2a5cea90 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c @@ -48,9 +48,10 @@ * - 2.5.0 - add get accel 2 to work around ddx breakage for evergreen * - 2.6.0 - add tiling config query (r6xx+), add initial HiZ support (r300->r500) * 2.7.0 - fixups for r600 2D tiling support. (no external ABI change), add eg dyn gpr regs + * 2.8.0 - pageflip support */ #define KMS_DRIVER_MAJOR 2 -#define KMS_DRIVER_MINOR 7 +#define KMS_DRIVER_MINOR 8 #define KMS_DRIVER_PATCHLEVEL 0 int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags); int radeon_driver_unload_kms(struct drm_device *dev); diff --git a/drivers/gpu/drm/radeon/radeon_irq_kms.c b/drivers/gpu/drm/radeon/radeon_irq_kms.c index a108c7ed14f5..e0d1c6d1b9c7 100644 --- a/drivers/gpu/drm/radeon/radeon_irq_kms.c +++ b/drivers/gpu/drm/radeon/radeon_irq_kms.c @@ -71,8 +71,10 @@ void radeon_driver_irq_preinstall_kms(struct drm_device *dev) rdev->irq.gui_idle = false; for (i = 0; i < rdev->num_crtc; i++) rdev->irq.crtc_vblank_int[i] = false; - for (i = 0; i < 6; i++) + for (i = 0; i < 6; i++) { rdev->irq.hpd[i] = false; + rdev->irq.pflip[i] = false; + } radeon_irq_set(rdev); /* Clear bits */ radeon_irq_process(rdev); @@ -101,8 +103,10 @@ void radeon_driver_irq_uninstall_kms(struct drm_device *dev) rdev->irq.gui_idle = false; for (i = 0; i < rdev->num_crtc; i++) rdev->irq.crtc_vblank_int[i] = false; - for (i = 0; i < 6; i++) + for (i = 0; i < 6; i++) { rdev->irq.hpd[i] = false; + rdev->irq.pflip[i] = false; + } radeon_irq_set(rdev); } @@ -175,3 +179,34 @@ void radeon_irq_kms_sw_irq_put(struct radeon_device *rdev) spin_unlock_irqrestore(&rdev->irq.sw_lock, irqflags); } +void radeon_irq_kms_pflip_irq_get(struct radeon_device *rdev, int crtc) +{ + unsigned long irqflags; + + if (crtc < 0 || crtc >= rdev->num_crtc) + return; + + spin_lock_irqsave(&rdev->irq.pflip_lock[crtc], irqflags); + if (rdev->ddev->irq_enabled && (++rdev->irq.pflip_refcount[crtc] == 1)) { + rdev->irq.pflip[crtc] = true; + radeon_irq_set(rdev); + } + spin_unlock_irqrestore(&rdev->irq.pflip_lock[crtc], irqflags); +} + +void radeon_irq_kms_pflip_irq_put(struct radeon_device *rdev, int crtc) +{ + unsigned long irqflags; + + if (crtc < 0 || crtc >= rdev->num_crtc) + return; + + spin_lock_irqsave(&rdev->irq.pflip_lock[crtc], irqflags); + BUG_ON(rdev->ddev->irq_enabled && rdev->irq.pflip_refcount[crtc] <= 0); + if (rdev->ddev->irq_enabled && (--rdev->irq.pflip_refcount[crtc] == 0)) { + rdev->irq.pflip[crtc] = false; + radeon_irq_set(rdev); + } + spin_unlock_irqrestore(&rdev->irq.pflip_lock[crtc], irqflags); +} + diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h index 55856ad0ac41..f406f02bf14e 100644 --- a/drivers/gpu/drm/radeon/radeon_mode.h +++ b/drivers/gpu/drm/radeon/radeon_mode.h @@ -277,6 +277,9 @@ struct radeon_crtc { fixed20_12 hsc; struct drm_display_mode native_mode; int pll_id; + /* page flipping */ + struct radeon_unpin_work *unpin_work; + int deferred_flip_completion; }; struct radeon_encoder_primary_dac { @@ -659,4 +662,7 @@ int radeon_fbdev_total_size(struct radeon_device *rdev); bool radeon_fbdev_robj_is_fb(struct radeon_device *rdev, struct radeon_bo *robj); void radeon_fb_output_poll_changed(struct radeon_device *rdev); + +void radeon_crtc_handle_flip(struct radeon_device *rdev, int crtc_id); + #endif diff --git a/drivers/gpu/drm/radeon/radeon_reg.h b/drivers/gpu/drm/radeon/radeon_reg.h index 64928814de53..26c43e234350 100644 --- a/drivers/gpu/drm/radeon/radeon_reg.h +++ b/drivers/gpu/drm/radeon/radeon_reg.h @@ -422,6 +422,7 @@ # define RADEON_CRTC_CSYNC_EN (1 << 4) # define RADEON_CRTC_ICON_EN (1 << 15) # define RADEON_CRTC_CUR_EN (1 << 16) +# define RADEON_CRTC_VSTAT_MODE_MASK (3 << 17) # define RADEON_CRTC_CUR_MODE_MASK (7 << 20) # define RADEON_CRTC_CUR_MODE_SHIFT 20 # define RADEON_CRTC_CUR_MODE_MONO 0 diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c index f1c6e02c2e6b..683652bea17c 100644 --- a/drivers/gpu/drm/radeon/rs600.c +++ b/drivers/gpu/drm/radeon/rs600.c @@ -46,6 +46,56 @@ void rs600_gpu_init(struct radeon_device *rdev); int rs600_mc_wait_for_idle(struct radeon_device *rdev); +void rs600_pre_page_flip(struct radeon_device *rdev, int crtc) +{ + struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc]; + u32 tmp; + + /* make sure flip is at vb rather than hb */ + tmp = RREG32(AVIVO_D1GRPH_FLIP_CONTROL + radeon_crtc->crtc_offset); + tmp &= ~AVIVO_D1GRPH_SURFACE_UPDATE_H_RETRACE_EN; + WREG32(AVIVO_D1GRPH_FLIP_CONTROL + radeon_crtc->crtc_offset, tmp); + + /* set pageflip to happen anywhere in vblank interval */ + WREG32(AVIVO_D1MODE_MASTER_UPDATE_MODE + radeon_crtc->crtc_offset, 0); + + /* enable the pflip int */ + radeon_irq_kms_pflip_irq_get(rdev, crtc); +} + +void rs600_post_page_flip(struct radeon_device *rdev, int crtc) +{ + /* disable the pflip int */ + radeon_irq_kms_pflip_irq_put(rdev, crtc); +} + +u32 rs600_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base) +{ + struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id]; + u32 tmp = RREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset); + + /* Lock the graphics update lock */ + tmp |= AVIVO_D1GRPH_UPDATE_LOCK; + WREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset, tmp); + + /* update the scanout addresses */ + WREG32(AVIVO_D1GRPH_SECONDARY_SURFACE_ADDRESS + radeon_crtc->crtc_offset, + (u32)crtc_base); + WREG32(AVIVO_D1GRPH_PRIMARY_SURFACE_ADDRESS + radeon_crtc->crtc_offset, + (u32)crtc_base); + + /* Wait for update_pending to go high. */ + while (!(RREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset) & AVIVO_D1GRPH_SURFACE_UPDATE_PENDING)); + DRM_DEBUG("Update pending now high. Unlocking vupdate_lock.\n"); + + /* Unlock the lock, so double-buffering can take place inside vblank */ + tmp &= ~AVIVO_D1GRPH_UPDATE_LOCK; + WREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset, tmp); + + /* Return current update_pending status: */ + return RREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset) & AVIVO_D1GRPH_SURFACE_UPDATE_PENDING; +} + void rs600_pm_misc(struct radeon_device *rdev) { int requested_index = rdev->pm.requested_power_state_index; @@ -515,10 +565,12 @@ int rs600_irq_set(struct radeon_device *rdev) if (rdev->irq.gui_idle) { tmp |= S_000040_GUI_IDLE(1); } - if (rdev->irq.crtc_vblank_int[0]) { + if (rdev->irq.crtc_vblank_int[0] || + rdev->irq.pflip[0]) { mode_int |= S_006540_D1MODE_VBLANK_INT_MASK(1); } - if (rdev->irq.crtc_vblank_int[1]) { + if (rdev->irq.crtc_vblank_int[1] || + rdev->irq.pflip[1]) { mode_int |= S_006540_D2MODE_VBLANK_INT_MASK(1); } if (rdev->irq.hpd[0]) { @@ -534,7 +586,7 @@ int rs600_irq_set(struct radeon_device *rdev) return 0; } -static inline uint32_t rs600_irq_ack(struct radeon_device *rdev, u32 *r500_disp_int) +static inline u32 rs600_irq_ack(struct radeon_device *rdev) { uint32_t irqs = RREG32(R_000044_GEN_INT_STATUS); uint32_t irq_mask = S_000044_SW_INT(1); @@ -547,27 +599,27 @@ static inline uint32_t rs600_irq_ack(struct radeon_device *rdev, u32 *r500_disp_ } if (G_000044_DISPLAY_INT_STAT(irqs)) { - *r500_disp_int = RREG32(R_007EDC_DISP_INTERRUPT_STATUS); - if (G_007EDC_LB_D1_VBLANK_INTERRUPT(*r500_disp_int)) { + rdev->irq.stat_regs.r500.disp_int = RREG32(R_007EDC_DISP_INTERRUPT_STATUS); + if (G_007EDC_LB_D1_VBLANK_INTERRUPT(rdev->irq.stat_regs.r500.disp_int)) { WREG32(R_006534_D1MODE_VBLANK_STATUS, S_006534_D1MODE_VBLANK_ACK(1)); } - if (G_007EDC_LB_D2_VBLANK_INTERRUPT(*r500_disp_int)) { + if (G_007EDC_LB_D2_VBLANK_INTERRUPT(rdev->irq.stat_regs.r500.disp_int)) { WREG32(R_006D34_D2MODE_VBLANK_STATUS, S_006D34_D2MODE_VBLANK_ACK(1)); } - if (G_007EDC_DC_HOT_PLUG_DETECT1_INTERRUPT(*r500_disp_int)) { + if (G_007EDC_DC_HOT_PLUG_DETECT1_INTERRUPT(rdev->irq.stat_regs.r500.disp_int)) { tmp = RREG32(R_007D08_DC_HOT_PLUG_DETECT1_INT_CONTROL); tmp |= S_007D08_DC_HOT_PLUG_DETECT1_INT_ACK(1); WREG32(R_007D08_DC_HOT_PLUG_DETECT1_INT_CONTROL, tmp); } - if (G_007EDC_DC_HOT_PLUG_DETECT2_INTERRUPT(*r500_disp_int)) { + if (G_007EDC_DC_HOT_PLUG_DETECT2_INTERRUPT(rdev->irq.stat_regs.r500.disp_int)) { tmp = RREG32(R_007D18_DC_HOT_PLUG_DETECT2_INT_CONTROL); tmp |= S_007D18_DC_HOT_PLUG_DETECT2_INT_ACK(1); WREG32(R_007D18_DC_HOT_PLUG_DETECT2_INT_CONTROL, tmp); } } else { - *r500_disp_int = 0; + rdev->irq.stat_regs.r500.disp_int = 0; } if (irqs) { @@ -578,32 +630,30 @@ static inline uint32_t rs600_irq_ack(struct radeon_device *rdev, u32 *r500_disp_ void rs600_irq_disable(struct radeon_device *rdev) { - u32 tmp; - WREG32(R_000040_GEN_INT_CNTL, 0); WREG32(R_006540_DxMODE_INT_MASK, 0); /* Wait and acknowledge irq */ mdelay(1); - rs600_irq_ack(rdev, &tmp); + rs600_irq_ack(rdev); } int rs600_irq_process(struct radeon_device *rdev) { - uint32_t status, msi_rearm; - uint32_t r500_disp_int; + u32 status, msi_rearm; bool queue_hotplug = false; /* reset gui idle ack. the status bit is broken */ rdev->irq.gui_idle_acked = false; - status = rs600_irq_ack(rdev, &r500_disp_int); - if (!status && !r500_disp_int) { + status = rs600_irq_ack(rdev); + if (!status && !rdev->irq.stat_regs.r500.disp_int) { return IRQ_NONE; } - while (status || r500_disp_int) { + while (status || rdev->irq.stat_regs.r500.disp_int) { /* SW interrupt */ - if (G_000044_SW_INT(status)) + if (G_000044_SW_INT(status)) { radeon_fence_process(rdev); + } /* GUI idle */ if (G_000040_GUI_IDLE(status)) { rdev->irq.gui_idle_acked = true; @@ -611,25 +661,33 @@ int rs600_irq_process(struct radeon_device *rdev) wake_up(&rdev->irq.idle_queue); } /* Vertical blank interrupts */ - if (G_007EDC_LB_D1_VBLANK_INTERRUPT(r500_disp_int)) { - drm_handle_vblank(rdev->ddev, 0); - rdev->pm.vblank_sync = true; - wake_up(&rdev->irq.vblank_queue); + if (G_007EDC_LB_D1_VBLANK_INTERRUPT(rdev->irq.stat_regs.r500.disp_int)) { + if (rdev->irq.pflip[0]) + radeon_crtc_handle_flip(rdev, 0); + if (rdev->irq.crtc_vblank_int[0]) { + drm_handle_vblank(rdev->ddev, 0); + rdev->pm.vblank_sync = true; + wake_up(&rdev->irq.vblank_queue); + } } - if (G_007EDC_LB_D2_VBLANK_INTERRUPT(r500_disp_int)) { - drm_handle_vblank(rdev->ddev, 1); - rdev->pm.vblank_sync = true; - wake_up(&rdev->irq.vblank_queue); + if (G_007EDC_LB_D2_VBLANK_INTERRUPT(rdev->irq.stat_regs.r500.disp_int)) { + if (rdev->irq.pflip[1]) + radeon_crtc_handle_flip(rdev, 1); + if (rdev->irq.crtc_vblank_int[1]) { + drm_handle_vblank(rdev->ddev, 1); + rdev->pm.vblank_sync = true; + wake_up(&rdev->irq.vblank_queue); + } } - if (G_007EDC_DC_HOT_PLUG_DETECT1_INTERRUPT(r500_disp_int)) { + if (G_007EDC_DC_HOT_PLUG_DETECT1_INTERRUPT(rdev->irq.stat_regs.r500.disp_int)) { queue_hotplug = true; DRM_DEBUG("HPD1\n"); } - if (G_007EDC_DC_HOT_PLUG_DETECT2_INTERRUPT(r500_disp_int)) { + if (G_007EDC_DC_HOT_PLUG_DETECT2_INTERRUPT(rdev->irq.stat_regs.r500.disp_int)) { queue_hotplug = true; DRM_DEBUG("HPD2\n"); } - status = rs600_irq_ack(rdev, &r500_disp_int); + status = rs600_irq_ack(rdev); } /* reset gui idle ack. the status bit is broken */ rdev->irq.gui_idle_acked = false; diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c index 4dfead8cee33..42ff07893f3a 100644 --- a/drivers/gpu/drm/radeon/rv770.c +++ b/drivers/gpu/drm/radeon/rv770.c @@ -42,6 +42,40 @@ static void rv770_gpu_init(struct radeon_device *rdev); void rv770_fini(struct radeon_device *rdev); +u32 rv770_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base) +{ + struct radeon_crtc *radeon_crtc = rdev->mode_info.crtcs[crtc_id]; + u32 tmp = RREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset); + + /* Lock the graphics update lock */ + tmp |= AVIVO_D1GRPH_UPDATE_LOCK; + WREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset, tmp); + + /* update the scanout addresses */ + if (radeon_crtc->crtc_id) { + WREG32(D2GRPH_SECONDARY_SURFACE_ADDRESS_HIGH, upper_32_bits(crtc_base)); + WREG32(D2GRPH_PRIMARY_SURFACE_ADDRESS_HIGH, upper_32_bits(crtc_base)); + } else { + WREG32(D1GRPH_SECONDARY_SURFACE_ADDRESS_HIGH, upper_32_bits(crtc_base)); + WREG32(D1GRPH_PRIMARY_SURFACE_ADDRESS_HIGH, upper_32_bits(crtc_base)); + } + WREG32(D1GRPH_SECONDARY_SURFACE_ADDRESS + radeon_crtc->crtc_offset, + (u32)crtc_base); + WREG32(D1GRPH_PRIMARY_SURFACE_ADDRESS + radeon_crtc->crtc_offset, + (u32)crtc_base); + + /* Wait for update_pending to go high. */ + while (!(RREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset) & AVIVO_D1GRPH_SURFACE_UPDATE_PENDING)); + DRM_DEBUG("Update pending now high. Unlocking vupdate_lock.\n"); + + /* Unlock the lock, so double-buffering can take place inside vblank */ + tmp &= ~AVIVO_D1GRPH_UPDATE_LOCK; + WREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset, tmp); + + /* Return current update_pending status: */ + return RREG32(AVIVO_D1GRPH_UPDATE + radeon_crtc->crtc_offset) & AVIVO_D1GRPH_SURFACE_UPDATE_PENDING; +} + /* get temperature in millidegrees */ u32 rv770_get_temp(struct radeon_device *rdev) { diff --git a/drivers/gpu/drm/radeon/rv770d.h b/drivers/gpu/drm/radeon/rv770d.h index b7a5a20e81dc..11955c685ad1 100644 --- a/drivers/gpu/drm/radeon/rv770d.h +++ b/drivers/gpu/drm/radeon/rv770d.h @@ -351,4 +351,11 @@ #define SRBM_STATUS 0x0E50 +#define D1GRPH_PRIMARY_SURFACE_ADDRESS 0x6110 +#define D1GRPH_PRIMARY_SURFACE_ADDRESS_HIGH 0x6914 +#define D2GRPH_PRIMARY_SURFACE_ADDRESS_HIGH 0x6114 +#define D1GRPH_SECONDARY_SURFACE_ADDRESS 0x6118 +#define D1GRPH_SECONDARY_SURFACE_ADDRESS_HIGH 0x691c +#define D2GRPH_SECONDARY_SURFACE_ADDRESS_HIGH 0x611c + #endif -- cgit v1.2.3 From 3e4ea7421f45966c93c8cbe81569e8dc93a58b87 Mon Sep 17 00:00:00 2001 From: Mario Kleiner Date: Sun, 21 Nov 2010 10:59:02 -0500 Subject: drm/kms/radeon: Reorder vblank and pageflip interrupt handling. In the vblank irq handler, calls to actual vblank handling, or at least drm_handle_vblank(), need to happen before calls to radeon_crtc_handle_flip(). Reason: The high precision pageflip timestamping and some other pageflip optimizations will need the updated vblank count and timestamps for the current vblank interval. These are calculated in drm_handle_vblank(), therefore it must go first. Signed-off-by: Mario Kleiner Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/evergreen.c | 8 ++++---- drivers/gpu/drm/radeon/r100.c | 8 ++++---- drivers/gpu/drm/radeon/r600.c | 8 ++++---- drivers/gpu/drm/radeon/rs600.c | 8 ++++---- 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index df3f37243222..25e84379e7c6 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c @@ -2398,13 +2398,13 @@ restart_ih: switch (src_data) { case 0: /* D1 vblank */ if (rdev->irq.stat_regs.evergreen.disp_int & LB_D1_VBLANK_INTERRUPT) { - if (rdev->irq.pflip[0]) - radeon_crtc_handle_flip(rdev, 0); if (rdev->irq.crtc_vblank_int[0]) { drm_handle_vblank(rdev->ddev, 0); rdev->pm.vblank_sync = true; wake_up(&rdev->irq.vblank_queue); } + if (rdev->irq.pflip[0]) + radeon_crtc_handle_flip(rdev, 0); rdev->irq.stat_regs.evergreen.disp_int &= ~LB_D1_VBLANK_INTERRUPT; DRM_DEBUG("IH: D1 vblank\n"); } @@ -2424,13 +2424,13 @@ restart_ih: switch (src_data) { case 0: /* D2 vblank */ if (rdev->irq.stat_regs.evergreen.disp_int_cont & LB_D2_VBLANK_INTERRUPT) { - if (rdev->irq.pflip[1]) - radeon_crtc_handle_flip(rdev, 1); if (rdev->irq.crtc_vblank_int[1]) { drm_handle_vblank(rdev->ddev, 1); rdev->pm.vblank_sync = true; wake_up(&rdev->irq.vblank_queue); } + if (rdev->irq.pflip[1]) + radeon_crtc_handle_flip(rdev, 1); rdev->irq.stat_regs.evergreen.disp_int_cont &= ~LB_D2_VBLANK_INTERRUPT; DRM_DEBUG("IH: D2 vblank\n"); } diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index b2e29798a99d..2316f73db6c0 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c @@ -650,22 +650,22 @@ int r100_irq_process(struct radeon_device *rdev) } /* Vertical blank interrupts */ if (status & RADEON_CRTC_VBLANK_STAT) { - if (rdev->irq.pflip[0]) - radeon_crtc_handle_flip(rdev, 0); if (rdev->irq.crtc_vblank_int[0]) { drm_handle_vblank(rdev->ddev, 0); rdev->pm.vblank_sync = true; wake_up(&rdev->irq.vblank_queue); } + if (rdev->irq.pflip[0]) + radeon_crtc_handle_flip(rdev, 0); } if (status & RADEON_CRTC2_VBLANK_STAT) { - if (rdev->irq.pflip[1]) - radeon_crtc_handle_flip(rdev, 1); if (rdev->irq.crtc_vblank_int[1]) { drm_handle_vblank(rdev->ddev, 1); rdev->pm.vblank_sync = true; wake_up(&rdev->irq.vblank_queue); } + if (rdev->irq.pflip[1]) + radeon_crtc_handle_flip(rdev, 1); } if (status & RADEON_FP_DETECT_STAT) { queue_hotplug = true; diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index 15b95724c408..7057b392e005 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c @@ -3294,13 +3294,13 @@ restart_ih: switch (src_data) { case 0: /* D1 vblank */ if (rdev->irq.stat_regs.r600.disp_int & LB_D1_VBLANK_INTERRUPT) { - if (rdev->irq.pflip[0]) - radeon_crtc_handle_flip(rdev, 0); if (rdev->irq.crtc_vblank_int[0]) { drm_handle_vblank(rdev->ddev, 0); rdev->pm.vblank_sync = true; wake_up(&rdev->irq.vblank_queue); } + if (rdev->irq.pflip[0]) + radeon_crtc_handle_flip(rdev, 0); rdev->irq.stat_regs.r600.disp_int &= ~LB_D1_VBLANK_INTERRUPT; DRM_DEBUG("IH: D1 vblank\n"); } @@ -3320,13 +3320,13 @@ restart_ih: switch (src_data) { case 0: /* D2 vblank */ if (rdev->irq.stat_regs.r600.disp_int & LB_D2_VBLANK_INTERRUPT) { - if (rdev->irq.pflip[1]) - radeon_crtc_handle_flip(rdev, 1); if (rdev->irq.crtc_vblank_int[1]) { drm_handle_vblank(rdev->ddev, 1); rdev->pm.vblank_sync = true; wake_up(&rdev->irq.vblank_queue); } + if (rdev->irq.pflip[1]) + radeon_crtc_handle_flip(rdev, 1); rdev->irq.stat_regs.r600.disp_int &= ~LB_D2_VBLANK_INTERRUPT; DRM_DEBUG("IH: D2 vblank\n"); } diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c index 683652bea17c..9a85b1614c86 100644 --- a/drivers/gpu/drm/radeon/rs600.c +++ b/drivers/gpu/drm/radeon/rs600.c @@ -662,22 +662,22 @@ int rs600_irq_process(struct radeon_device *rdev) } /* Vertical blank interrupts */ if (G_007EDC_LB_D1_VBLANK_INTERRUPT(rdev->irq.stat_regs.r500.disp_int)) { - if (rdev->irq.pflip[0]) - radeon_crtc_handle_flip(rdev, 0); if (rdev->irq.crtc_vblank_int[0]) { drm_handle_vblank(rdev->ddev, 0); rdev->pm.vblank_sync = true; wake_up(&rdev->irq.vblank_queue); } + if (rdev->irq.pflip[0]) + radeon_crtc_handle_flip(rdev, 0); } if (G_007EDC_LB_D2_VBLANK_INTERRUPT(rdev->irq.stat_regs.r500.disp_int)) { - if (rdev->irq.pflip[1]) - radeon_crtc_handle_flip(rdev, 1); if (rdev->irq.crtc_vblank_int[1]) { drm_handle_vblank(rdev->ddev, 1); rdev->pm.vblank_sync = true; wake_up(&rdev->irq.vblank_queue); } + if (rdev->irq.pflip[1]) + radeon_crtc_handle_flip(rdev, 1); } if (G_007EDC_DC_HOT_PLUG_DETECT1_INTERRUPT(rdev->irq.stat_regs.r500.disp_int)) { queue_hotplug = true; -- cgit v1.2.3 From b6724405bc67ef3ae1318002085cde382b12345f Mon Sep 17 00:00:00 2001 From: Mario Kleiner Date: Sun, 21 Nov 2010 10:59:03 -0500 Subject: drm/kms/radeon: Use high precision timestamps for pageflip completion events. Signed-off-by: Mario Kleiner Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/radeon_display.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c index f6493f444faa..15f24f2ee04d 100644 --- a/drivers/gpu/drm/radeon/radeon_display.c +++ b/drivers/gpu/drm/radeon/radeon_display.c @@ -259,8 +259,7 @@ void radeon_crtc_handle_flip(struct radeon_device *rdev, int crtc_id) /* wakeup userspace */ if (work->event) { e = work->event; - do_gettimeofday(&now); - e->event.sequence = drm_vblank_count(rdev->ddev, radeon_crtc->crtc_id); + e->event.sequence = drm_vblank_count_and_time(rdev->ddev, crtc_id, &now); e->event.tv_sec = now.tv_sec; e->event.tv_usec = now.tv_usec; list_add_tail(&e->base.link, &e->base.file_priv->event_list); -- cgit v1.2.3 From d6ea88865d3e5b0c62040531310c1f2c6a994f46 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 22 Nov 2010 13:24:40 +1000 Subject: drm/ttm: Add a bo list reserve fastpath (v2) Makes it possible to reserve a list of buffer objects with a single spin lock / unlock if there is no contention. Should improve cpu usage on SMP kernels. v2: Initialize private list members on reserve and don't call ttm_bo_list_ref_sub() with zero put_count. Signed-off-by: Thomas Hellstrom Signed-off-by: Dave Airlie --- drivers/gpu/drm/ttm/ttm_bo.c | 32 ++++----- drivers/gpu/drm/ttm/ttm_execbuf_util.c | 124 ++++++++++++++++++++++++++++++--- include/drm/ttm/ttm_bo_api.h | 38 ++++++++++ include/drm/ttm/ttm_bo_driver.h | 14 ++++ include/drm/ttm/ttm_execbuf_util.h | 6 +- 5 files changed, 186 insertions(+), 28 deletions(-) diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c index 148a322d8f5d..a586378b1b2b 100644 --- a/drivers/gpu/drm/ttm/ttm_bo.c +++ b/drivers/gpu/drm/ttm/ttm_bo.c @@ -169,7 +169,7 @@ int ttm_bo_wait_unreserved(struct ttm_buffer_object *bo, bool interruptible) } EXPORT_SYMBOL(ttm_bo_wait_unreserved); -static void ttm_bo_add_to_lru(struct ttm_buffer_object *bo) +void ttm_bo_add_to_lru(struct ttm_buffer_object *bo) { struct ttm_bo_device *bdev = bo->bdev; struct ttm_mem_type_manager *man; @@ -191,11 +191,7 @@ static void ttm_bo_add_to_lru(struct ttm_buffer_object *bo) } } -/** - * Call with the lru_lock held. - */ - -static int ttm_bo_del_from_lru(struct ttm_buffer_object *bo) +int ttm_bo_del_from_lru(struct ttm_buffer_object *bo) { int put_count = 0; @@ -267,6 +263,15 @@ static void ttm_bo_ref_bug(struct kref *list_kref) BUG(); } +void ttm_bo_list_ref_sub(struct ttm_buffer_object *bo, int count, + bool never_free) +{ + while (count--) + kref_put(&bo->list_kref, + (never_free || (count >= 0)) ? ttm_bo_ref_bug : + ttm_bo_release_list); +} + int ttm_bo_reserve(struct ttm_buffer_object *bo, bool interruptible, bool no_wait, bool use_sequence, uint32_t sequence) @@ -282,8 +287,7 @@ int ttm_bo_reserve(struct ttm_buffer_object *bo, put_count = ttm_bo_del_from_lru(bo); spin_unlock(&glob->lru_lock); - while (put_count--) - kref_put(&bo->list_kref, ttm_bo_ref_bug); + ttm_bo_list_ref_sub(bo, put_count, true); return ret; } @@ -496,8 +500,7 @@ static void ttm_bo_cleanup_refs_or_queue(struct ttm_buffer_object *bo) spin_unlock(&glob->lru_lock); ttm_bo_cleanup_memtype_use(bo); - while (put_count--) - kref_put(&bo->list_kref, ttm_bo_ref_bug); + ttm_bo_list_ref_sub(bo, put_count, true); return; } else { @@ -580,8 +583,7 @@ retry: spin_unlock(&glob->lru_lock); ttm_bo_cleanup_memtype_use(bo); - while (put_count--) - kref_put(&bo->list_kref, ttm_bo_ref_bug); + ttm_bo_list_ref_sub(bo, put_count, true); return 0; } @@ -802,8 +804,7 @@ retry: BUG_ON(ret != 0); - while (put_count--) - kref_put(&bo->list_kref, ttm_bo_ref_bug); + ttm_bo_list_ref_sub(bo, put_count, true); ret = ttm_bo_evict(bo, interruptible, no_wait_reserve, no_wait_gpu); ttm_bo_unreserve(bo); @@ -1783,8 +1784,7 @@ static int ttm_bo_swapout(struct ttm_mem_shrink *shrink) put_count = ttm_bo_del_from_lru(bo); spin_unlock(&glob->lru_lock); - while (put_count--) - kref_put(&bo->list_kref, ttm_bo_ref_bug); + ttm_bo_list_ref_sub(bo, put_count, true); /** * Wait for GPU, then move to system cached. diff --git a/drivers/gpu/drm/ttm/ttm_execbuf_util.c b/drivers/gpu/drm/ttm/ttm_execbuf_util.c index c285c2902d15..201a71d111ec 100644 --- a/drivers/gpu/drm/ttm/ttm_execbuf_util.c +++ b/drivers/gpu/drm/ttm/ttm_execbuf_util.c @@ -32,6 +32,72 @@ #include #include +static void ttm_eu_backoff_reservation_locked(struct list_head *list) +{ + struct ttm_validate_buffer *entry; + + list_for_each_entry(entry, list, head) { + struct ttm_buffer_object *bo = entry->bo; + if (!entry->reserved) + continue; + + if (entry->removed) { + ttm_bo_add_to_lru(bo); + entry->removed = false; + + } + entry->reserved = false; + atomic_set(&bo->reserved, 0); + wake_up_all(&bo->event_queue); + } +} + +static void ttm_eu_del_from_lru_locked(struct list_head *list) +{ + struct ttm_validate_buffer *entry; + + list_for_each_entry(entry, list, head) { + struct ttm_buffer_object *bo = entry->bo; + if (!entry->reserved) + continue; + + if (!entry->removed) { + entry->put_count = ttm_bo_del_from_lru(bo); + entry->removed = true; + } + } +} + +static void ttm_eu_list_ref_sub(struct list_head *list) +{ + struct ttm_validate_buffer *entry; + + list_for_each_entry(entry, list, head) { + struct ttm_buffer_object *bo = entry->bo; + + if (entry->put_count) { + ttm_bo_list_ref_sub(bo, entry->put_count, true); + entry->put_count = 0; + } + } +} + +static int ttm_eu_wait_unreserved_locked(struct list_head *list, + struct ttm_buffer_object *bo) +{ + struct ttm_bo_global *glob = bo->glob; + int ret; + + ttm_eu_del_from_lru_locked(list); + spin_unlock(&glob->lru_lock); + ret = ttm_bo_wait_unreserved(bo, true); + spin_lock(&glob->lru_lock); + if (unlikely(ret != 0)) + ttm_eu_backoff_reservation_locked(list); + return ret; +} + + void ttm_eu_backoff_reservation(struct list_head *list) { struct ttm_validate_buffer *entry; @@ -61,35 +127,71 @@ EXPORT_SYMBOL(ttm_eu_backoff_reservation); int ttm_eu_reserve_buffers(struct list_head *list, uint32_t val_seq) { + struct ttm_bo_global *glob; struct ttm_validate_buffer *entry; int ret; + if (list_empty(list)) + return 0; + + list_for_each_entry(entry, list, head) { + entry->reserved = false; + entry->put_count = 0; + entry->removed = false; + } + + entry = list_first_entry(list, struct ttm_validate_buffer, head); + glob = entry->bo->glob; + retry: + spin_lock(&glob->lru_lock); list_for_each_entry(entry, list, head) { struct ttm_buffer_object *bo = entry->bo; - entry->reserved = false; - ret = ttm_bo_reserve(bo, true, false, true, val_seq); - if (ret != 0) { - ttm_eu_backoff_reservation(list); - if (ret == -EAGAIN) { - ret = ttm_bo_wait_unreserved(bo, true); - if (unlikely(ret != 0)) - return ret; - goto retry; - } else +retry_this_bo: + ret = ttm_bo_reserve_locked(bo, true, true, true, val_seq); + switch (ret) { + case 0: + break; + case -EBUSY: + ret = ttm_eu_wait_unreserved_locked(list, bo); + if (unlikely(ret != 0)) { + spin_unlock(&glob->lru_lock); + ttm_eu_list_ref_sub(list); + return ret; + } + goto retry_this_bo; + case -EAGAIN: + ttm_eu_backoff_reservation_locked(list); + spin_unlock(&glob->lru_lock); + ttm_eu_list_ref_sub(list); + ret = ttm_bo_wait_unreserved(bo, true); + if (unlikely(ret != 0)) return ret; + goto retry; + default: + ttm_eu_backoff_reservation_locked(list); + spin_unlock(&glob->lru_lock); + ttm_eu_list_ref_sub(list); + return ret; } entry->reserved = true; if (unlikely(atomic_read(&bo->cpu_writers) > 0)) { - ttm_eu_backoff_reservation(list); + ttm_eu_backoff_reservation_locked(list); + spin_unlock(&glob->lru_lock); + ttm_eu_list_ref_sub(list); ret = ttm_bo_wait_cpu(bo, false); if (ret) return ret; goto retry; } } + + ttm_eu_del_from_lru_locked(list); + spin_unlock(&glob->lru_lock); + ttm_eu_list_ref_sub(list); + return 0; } EXPORT_SYMBOL(ttm_eu_reserve_buffers); diff --git a/include/drm/ttm/ttm_bo_api.h b/include/drm/ttm/ttm_bo_api.h index beafc156a535..b0fc9c12554b 100644 --- a/include/drm/ttm/ttm_bo_api.h +++ b/include/drm/ttm/ttm_bo_api.h @@ -364,6 +364,44 @@ extern int ttm_bo_validate(struct ttm_buffer_object *bo, */ extern void ttm_bo_unref(struct ttm_buffer_object **bo); + +/** + * ttm_bo_list_ref_sub + * + * @bo: The buffer object. + * @count: The number of references with which to decrease @bo::list_kref; + * @never_free: The refcount should not reach zero with this operation. + * + * Release @count lru list references to this buffer object. + */ +extern void ttm_bo_list_ref_sub(struct ttm_buffer_object *bo, int count, + bool never_free); + +/** + * ttm_bo_add_to_lru + * + * @bo: The buffer object. + * + * Add this bo to the relevant mem type lru and, if it's backed by + * system pages (ttms) to the swap list. + * This function must be called with struct ttm_bo_global::lru_lock held, and + * is typically called immediately prior to unreserving a bo. + */ +extern void ttm_bo_add_to_lru(struct ttm_buffer_object *bo); + +/** + * ttm_bo_del_from_lru + * + * @bo: The buffer object. + * + * Remove this bo from all lru lists used to lookup and reserve an object. + * This function must be called with struct ttm_bo_global::lru_lock held, + * and is usually called just immediately after the bo has been reserved to + * avoid recursive reservation from lru lists. + */ +extern int ttm_bo_del_from_lru(struct ttm_buffer_object *bo); + + /** * ttm_bo_lock_delayed_workqueue * diff --git a/include/drm/ttm/ttm_bo_driver.h b/include/drm/ttm/ttm_bo_driver.h index 8e0c848326b6..95068e6024db 100644 --- a/include/drm/ttm/ttm_bo_driver.h +++ b/include/drm/ttm/ttm_bo_driver.h @@ -864,6 +864,20 @@ extern int ttm_bo_reserve(struct ttm_buffer_object *bo, bool interruptible, bool no_wait, bool use_sequence, uint32_t sequence); + +/** + * ttm_bo_reserve_locked: + * + * Similar to ttm_bo_reserve, but must be called with the glob::lru_lock + * spinlock held, and will not remove reserved buffers from the lru lists. + * The function may release the LRU spinlock if it needs to sleep. + */ + +extern int ttm_bo_reserve_locked(struct ttm_buffer_object *bo, + bool interruptible, + bool no_wait, bool use_sequence, + uint32_t sequence); + /** * ttm_bo_unreserve * diff --git a/include/drm/ttm/ttm_execbuf_util.h b/include/drm/ttm/ttm_execbuf_util.h index cd2c475da9ea..fd09b8438977 100644 --- a/include/drm/ttm/ttm_execbuf_util.h +++ b/include/drm/ttm/ttm_execbuf_util.h @@ -41,7 +41,9 @@ * @bo: refcounted buffer object pointer. * @new_sync_obj_arg: New sync_obj_arg for @bo, to be used once * adding a new sync object. - * @reservied: Indicates whether @bo has been reserved for validation. + * @reserved: Indicates whether @bo has been reserved for validation. + * @removed: Indicates whether @bo has been removed from lru lists. + * @put_count: Number of outstanding references on bo::list_kref. */ struct ttm_validate_buffer { @@ -49,6 +51,8 @@ struct ttm_validate_buffer { struct ttm_buffer_object *bo; void *new_sync_obj_arg; bool reserved; + bool removed; + int put_count; }; /** -- cgit v1.2.3 From ecf7ace9a8450303a987aa8364e53860cd50e554 Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Tue, 16 Nov 2010 15:21:07 +0100 Subject: kref: Add a kref_sub function Makes it possible to optimize batched multiple unrefs. Initial user will be drivers/gpu/ttm which accumulates unrefs to be processed outside of atomic code. Signed-off-by: Thomas Hellstrom Signed-off-by: Dave Airlie --- include/linux/kref.h | 2 ++ lib/kref.c | 30 ++++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/include/linux/kref.h b/include/linux/kref.h index 6cc38fc07ab7..d4a62ab2ee5e 100644 --- a/include/linux/kref.h +++ b/include/linux/kref.h @@ -24,5 +24,7 @@ struct kref { void kref_init(struct kref *kref); void kref_get(struct kref *kref); int kref_put(struct kref *kref, void (*release) (struct kref *kref)); +int kref_sub(struct kref *kref, unsigned int count, + void (*release) (struct kref *kref)); #endif /* _KREF_H_ */ diff --git a/lib/kref.c b/lib/kref.c index d3d227a08a4b..3efb882b11db 100644 --- a/lib/kref.c +++ b/lib/kref.c @@ -62,6 +62,36 @@ int kref_put(struct kref *kref, void (*release)(struct kref *kref)) return 0; } + +/** + * kref_sub - subtract a number of refcounts for object. + * @kref: object. + * @count: Number of recounts to subtract. + * @release: pointer to the function that will clean up the object when the + * last reference to the object is released. + * This pointer is required, and it is not acceptable to pass kfree + * in as this function. + * + * Subtract @count from the refcount, and if 0, call release(). + * Return 1 if the object was removed, otherwise return 0. Beware, if this + * function returns 0, you still can not count on the kref from remaining in + * memory. Only use the return value if you want to see if the kref is now + * gone, not present. + */ +int kref_sub(struct kref *kref, unsigned int count, + void (*release)(struct kref *kref)) +{ + WARN_ON(release == NULL); + WARN_ON(release == (void (*)(struct kref *))kfree); + + if (atomic_sub_and_test((int) count, &kref->refcount)) { + release(kref); + return 1; + } + return 0; +} + EXPORT_SYMBOL(kref_init); EXPORT_SYMBOL(kref_get); EXPORT_SYMBOL(kref_put); +EXPORT_SYMBOL(kref_sub); -- cgit v1.2.3 From 2357cbe5f4ca8a52329c2c2a26b68839870d5d43 Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Tue, 16 Nov 2010 15:21:08 +0100 Subject: drm/ttm: Use kref_sub instead of repeatedly calling kref_put Signed-off-by: Thomas Hellstrom Signed-off-by: Dave Airlie --- drivers/gpu/drm/ttm/ttm_bo.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c index a586378b1b2b..9ef893d5da88 100644 --- a/drivers/gpu/drm/ttm/ttm_bo.c +++ b/drivers/gpu/drm/ttm/ttm_bo.c @@ -266,10 +266,8 @@ static void ttm_bo_ref_bug(struct kref *list_kref) void ttm_bo_list_ref_sub(struct ttm_buffer_object *bo, int count, bool never_free) { - while (count--) - kref_put(&bo->list_kref, - (never_free || (count >= 0)) ? ttm_bo_ref_bug : - ttm_bo_release_list); + kref_sub(&bo->list_kref, count, + (never_free) ? ttm_bo_ref_bug : ttm_bo_release_list); } int ttm_bo_reserve(struct ttm_buffer_object *bo, -- cgit v1.2.3 From 68c4fa31aa52765314b4285a7835368ea35b509c Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Wed, 17 Nov 2010 12:28:27 +0000 Subject: drm/ttm: Optimize ttm_eu_backoff_reservation Avoid the ttm_bo_unreserve() spinlocks by calling ttm_eu_backoff_reservation_locked under the lru spinlock. Signed-off-by: Thomas Hellstrom Reviewed-by: Jerome Glisse Signed-off-by: Dave Airlie --- drivers/gpu/drm/ttm/ttm_execbuf_util.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/ttm/ttm_execbuf_util.c b/drivers/gpu/drm/ttm/ttm_execbuf_util.c index 201a71d111ec..7dcc6470e2f5 100644 --- a/drivers/gpu/drm/ttm/ttm_execbuf_util.c +++ b/drivers/gpu/drm/ttm/ttm_execbuf_util.c @@ -101,15 +101,16 @@ static int ttm_eu_wait_unreserved_locked(struct list_head *list, void ttm_eu_backoff_reservation(struct list_head *list) { struct ttm_validate_buffer *entry; + struct ttm_bo_global *glob; - list_for_each_entry(entry, list, head) { - struct ttm_buffer_object *bo = entry->bo; - if (!entry->reserved) - continue; + if (list_empty(list)) + return; - entry->reserved = false; - ttm_bo_unreserve(bo); - } + entry = list_first_entry(list, struct ttm_validate_buffer, head); + glob = entry->bo->glob; + spin_lock(&glob->lru_lock); + ttm_eu_backoff_reservation_locked(list); + spin_unlock(&glob->lru_lock); } EXPORT_SYMBOL(ttm_eu_backoff_reservation); -- cgit v1.2.3 From 96726fe50feae74812a2ccf5d5da23cb01c0a413 Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Wed, 17 Nov 2010 12:28:28 +0000 Subject: drm/ttm: Don't deadlock on recursive multi-bo reservations Add an aid for the driver to detect deadlocks on multi-bo reservations Update documentation. Signed-off-by: Thomas Hellstrom Reviewed-by: Jerome Glisse Signed-off-by: Dave Airlie --- drivers/gpu/drm/ttm/ttm_bo.c | 15 ++++++++++++--- include/drm/ttm/ttm_bo_driver.h | 25 ++++++++++++++++++++++--- 2 files changed, 34 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c index 9ef893d5da88..5d8750830dc3 100644 --- a/drivers/gpu/drm/ttm/ttm_bo.c +++ b/drivers/gpu/drm/ttm/ttm_bo.c @@ -223,9 +223,18 @@ int ttm_bo_reserve_locked(struct ttm_buffer_object *bo, /** * Deadlock avoidance for multi-bo reserving. */ - if (use_sequence && bo->seq_valid && - (sequence - bo->val_seq < (1 << 31))) { - return -EAGAIN; + if (use_sequence && bo->seq_valid) { + /** + * We've already reserved this one. + */ + if (unlikely(sequence == bo->val_seq)) + return -EDEADLK; + /** + * Already reserved by a thread that will not back + * off for us. We need to back off. + */ + if (unlikely(sequence - bo->val_seq < (1 << 31))) + return -EAGAIN; } if (no_wait) diff --git a/include/drm/ttm/ttm_bo_driver.h b/include/drm/ttm/ttm_bo_driver.h index 95068e6024db..1e25a40c688e 100644 --- a/include/drm/ttm/ttm_bo_driver.h +++ b/include/drm/ttm/ttm_bo_driver.h @@ -859,6 +859,9 @@ extern void ttm_bo_unmap_virtual(struct ttm_buffer_object *bo); * try again. (only if use_sequence == 1). * -ERESTARTSYS: A wait for the buffer to become unreserved was interrupted by * a signal. Release all buffer reservations and return to user-space. + * -EBUSY: The function needed to sleep, but @no_wait was true + * -EDEADLK: Bo already reserved using @sequence. This error code will only + * be returned if @use_sequence is set to true. */ extern int ttm_bo_reserve(struct ttm_buffer_object *bo, bool interruptible, @@ -868,11 +871,27 @@ extern int ttm_bo_reserve(struct ttm_buffer_object *bo, /** * ttm_bo_reserve_locked: * - * Similar to ttm_bo_reserve, but must be called with the glob::lru_lock - * spinlock held, and will not remove reserved buffers from the lru lists. + * @bo: A pointer to a struct ttm_buffer_object. + * @interruptible: Sleep interruptible if waiting. + * @no_wait: Don't sleep while trying to reserve, rather return -EBUSY. + * @use_sequence: If @bo is already reserved, Only sleep waiting for + * it to become unreserved if @sequence < (@bo)->sequence. + * + * Must be called with struct ttm_bo_global::lru_lock held, + * and will not remove reserved buffers from the lru lists. * The function may release the LRU spinlock if it needs to sleep. + * Otherwise identical to ttm_bo_reserve. + * + * Returns: + * -EAGAIN: The reservation may cause a deadlock. + * Release all buffer reservations, wait for @bo to become unreserved and + * try again. (only if use_sequence == 1). + * -ERESTARTSYS: A wait for the buffer to become unreserved was interrupted by + * a signal. Release all buffer reservations and return to user-space. + * -EBUSY: The function needed to sleep, but @no_wait was true + * -EDEADLK: Bo already reserved using @sequence. This error code will only + * be returned if @use_sequence is set to true. */ - extern int ttm_bo_reserve_locked(struct ttm_buffer_object *bo, bool interruptible, bool no_wait, bool use_sequence, -- cgit v1.2.3 From 702adba22433c175e8429a47760f35ca16caf1cd Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Wed, 17 Nov 2010 12:28:29 +0000 Subject: drm/ttm/radeon/nouveau: Kill the bo lock in favour of a bo device fence_lock The bo lock used only to protect the bo sync object members, and since it is a per bo lock, fencing a buffer list will see a lot of locks and unlocks. Replace it with a per-device lock that protects the sync object members on *all* bos. Reading and setting these members will always be very quick, so the risc of heavy lock contention is microscopic. Note that waiting for sync objects will always take place outside of this lock. The bo device fence lock will eventually be replaced with a seqlock / rcu mechanism so we can determine that a bo is idle under a rcu / read seqlock. However this change will allow us to batch fencing and unreserving of buffers with a minimal amount of locking. Signed-off-by: Thomas Hellstrom Reviewed-by: Jerome Glisse Signed-off-by: Dave Airlie --- drivers/gpu/drm/nouveau/nouveau_gem.c | 12 ++++---- drivers/gpu/drm/radeon/radeon_object.c | 4 +-- drivers/gpu/drm/radeon/radeon_object.h | 4 +-- drivers/gpu/drm/ttm/ttm_bo.c | 55 +++++++++++++++++----------------- drivers/gpu/drm/ttm/ttm_bo_util.c | 7 ++--- drivers/gpu/drm/ttm/ttm_bo_vm.c | 6 ++-- drivers/gpu/drm/ttm/ttm_execbuf_util.c | 7 +++-- include/drm/ttm/ttm_bo_api.h | 6 ++-- include/drm/ttm/ttm_bo_driver.h | 3 ++ 9 files changed, 53 insertions(+), 51 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c index 9a1fdcf400c2..1f2301d26c0a 100644 --- a/drivers/gpu/drm/nouveau/nouveau_gem.c +++ b/drivers/gpu/drm/nouveau/nouveau_gem.c @@ -234,10 +234,10 @@ validate_fini_list(struct list_head *list, struct nouveau_fence *fence) if (likely(fence)) { struct nouveau_fence *prev_fence; - spin_lock(&nvbo->bo.lock); + spin_lock(&nvbo->bo.bdev->fence_lock); prev_fence = nvbo->bo.sync_obj; nvbo->bo.sync_obj = nouveau_fence_ref(fence); - spin_unlock(&nvbo->bo.lock); + spin_unlock(&nvbo->bo.bdev->fence_lock); nouveau_fence_unref((void *)&prev_fence); } @@ -557,9 +557,9 @@ nouveau_gem_pushbuf_reloc_apply(struct drm_device *dev, data |= r->vor; } - spin_lock(&nvbo->bo.lock); + spin_lock(&nvbo->bo.bdev->fence_lock); ret = ttm_bo_wait(&nvbo->bo, false, false, false); - spin_unlock(&nvbo->bo.lock); + spin_unlock(&nvbo->bo.bdev->fence_lock); if (ret) { NV_ERROR(dev, "reloc wait_idle failed: %d\n", ret); break; @@ -791,9 +791,9 @@ nouveau_gem_ioctl_cpu_prep(struct drm_device *dev, void *data, } if (req->flags & NOUVEAU_GEM_CPU_PREP_NOBLOCK) { - spin_lock(&nvbo->bo.lock); + spin_lock(&nvbo->bo.bdev->fence_lock); ret = ttm_bo_wait(&nvbo->bo, false, false, no_wait); - spin_unlock(&nvbo->bo.lock); + spin_unlock(&nvbo->bo.bdev->fence_lock); } else { ret = ttm_bo_synccpu_write_grab(&nvbo->bo, no_wait); if (ret == 0) diff --git a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/radeon/radeon_object.c index 1d067743fee0..e939cb6a91cc 100644 --- a/drivers/gpu/drm/radeon/radeon_object.c +++ b/drivers/gpu/drm/radeon/radeon_object.c @@ -369,11 +369,11 @@ void radeon_bo_list_fence(struct list_head *head, void *fence) list_for_each_entry(lobj, head, list) { bo = lobj->bo; - spin_lock(&bo->tbo.lock); + spin_lock(&bo->tbo.bdev->fence_lock); old_fence = (struct radeon_fence *)bo->tbo.sync_obj; bo->tbo.sync_obj = radeon_fence_ref(fence); bo->tbo.sync_obj_arg = NULL; - spin_unlock(&bo->tbo.lock); + spin_unlock(&bo->tbo.bdev->fence_lock); if (old_fence) { radeon_fence_unref(&old_fence); } diff --git a/drivers/gpu/drm/radeon/radeon_object.h b/drivers/gpu/drm/radeon/radeon_object.h index d143702b244a..fd536751f865 100644 --- a/drivers/gpu/drm/radeon/radeon_object.h +++ b/drivers/gpu/drm/radeon/radeon_object.h @@ -126,12 +126,12 @@ static inline int radeon_bo_wait(struct radeon_bo *bo, u32 *mem_type, r = ttm_bo_reserve(&bo->tbo, true, no_wait, false, 0); if (unlikely(r != 0)) return r; - spin_lock(&bo->tbo.lock); + spin_lock(&bo->tbo.bdev->fence_lock); if (mem_type) *mem_type = bo->tbo.mem.mem_type; if (bo->tbo.sync_obj) r = ttm_bo_wait(&bo->tbo, true, true, no_wait); - spin_unlock(&bo->tbo.lock); + spin_unlock(&bo->tbo.bdev->fence_lock); ttm_bo_unreserve(&bo->tbo); return r; } diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c index 5d8750830dc3..d93c73b1c471 100644 --- a/drivers/gpu/drm/ttm/ttm_bo.c +++ b/drivers/gpu/drm/ttm/ttm_bo.c @@ -427,11 +427,9 @@ moved: } if (bo->mem.mm_node) { - spin_lock(&bo->lock); bo->offset = (bo->mem.start << PAGE_SHIFT) + bdev->man[bo->mem.mem_type].gpu_offset; bo->cur_placement = bo->mem.placement; - spin_unlock(&bo->lock); } else bo->offset = 0; @@ -485,14 +483,14 @@ static void ttm_bo_cleanup_refs_or_queue(struct ttm_buffer_object *bo) int put_count; int ret; - spin_lock(&bo->lock); + spin_lock(&bdev->fence_lock); (void) ttm_bo_wait(bo, false, false, true); if (!bo->sync_obj) { spin_lock(&glob->lru_lock); /** - * Lock inversion between bo::reserve and bo::lock here, + * Lock inversion between bo:reserve and bdev::fence_lock here, * but that's OK, since we're only trylocking. */ @@ -501,7 +499,7 @@ static void ttm_bo_cleanup_refs_or_queue(struct ttm_buffer_object *bo) if (unlikely(ret == -EBUSY)) goto queue; - spin_unlock(&bo->lock); + spin_unlock(&bdev->fence_lock); put_count = ttm_bo_del_from_lru(bo); spin_unlock(&glob->lru_lock); @@ -522,7 +520,7 @@ queue: kref_get(&bo->list_kref); list_add_tail(&bo->ddestroy, &bdev->ddestroy); spin_unlock(&glob->lru_lock); - spin_unlock(&bo->lock); + spin_unlock(&bdev->fence_lock); if (sync_obj) { driver->sync_obj_flush(sync_obj, sync_obj_arg); @@ -547,14 +545,15 @@ static int ttm_bo_cleanup_refs(struct ttm_buffer_object *bo, bool no_wait_reserve, bool no_wait_gpu) { + struct ttm_bo_device *bdev = bo->bdev; struct ttm_bo_global *glob = bo->glob; int put_count; int ret = 0; retry: - spin_lock(&bo->lock); + spin_lock(&bdev->fence_lock); ret = ttm_bo_wait(bo, false, interruptible, no_wait_gpu); - spin_unlock(&bo->lock); + spin_unlock(&bdev->fence_lock); if (unlikely(ret != 0)) return ret; @@ -707,9 +706,9 @@ static int ttm_bo_evict(struct ttm_buffer_object *bo, bool interruptible, struct ttm_placement placement; int ret = 0; - spin_lock(&bo->lock); + spin_lock(&bdev->fence_lock); ret = ttm_bo_wait(bo, false, interruptible, no_wait_gpu); - spin_unlock(&bo->lock); + spin_unlock(&bdev->fence_lock); if (unlikely(ret != 0)) { if (ret != -ERESTARTSYS) { @@ -1044,6 +1043,7 @@ int ttm_bo_move_buffer(struct ttm_buffer_object *bo, { int ret = 0; struct ttm_mem_reg mem; + struct ttm_bo_device *bdev = bo->bdev; BUG_ON(!atomic_read(&bo->reserved)); @@ -1052,9 +1052,9 @@ int ttm_bo_move_buffer(struct ttm_buffer_object *bo, * Have the driver move function wait for idle when necessary, * instead of doing it here. */ - spin_lock(&bo->lock); + spin_lock(&bdev->fence_lock); ret = ttm_bo_wait(bo, false, interruptible, no_wait_gpu); - spin_unlock(&bo->lock); + spin_unlock(&bdev->fence_lock); if (ret) return ret; mem.num_pages = bo->num_pages; @@ -1171,7 +1171,6 @@ int ttm_bo_init(struct ttm_bo_device *bdev, } bo->destroy = destroy; - spin_lock_init(&bo->lock); kref_init(&bo->kref); kref_init(&bo->list_kref); atomic_set(&bo->cpu_writers, 0); @@ -1535,7 +1534,7 @@ int ttm_bo_device_init(struct ttm_bo_device *bdev, bdev->dev_mapping = NULL; bdev->glob = glob; bdev->need_dma32 = need_dma32; - + spin_lock_init(&bdev->fence_lock); mutex_lock(&glob->device_list_mutex); list_add_tail(&bdev->device_list, &glob->device_list); mutex_unlock(&glob->device_list_mutex); @@ -1659,6 +1658,7 @@ int ttm_bo_wait(struct ttm_buffer_object *bo, bool lazy, bool interruptible, bool no_wait) { struct ttm_bo_driver *driver = bo->bdev->driver; + struct ttm_bo_device *bdev = bo->bdev; void *sync_obj; void *sync_obj_arg; int ret = 0; @@ -1672,9 +1672,9 @@ int ttm_bo_wait(struct ttm_buffer_object *bo, void *tmp_obj = bo->sync_obj; bo->sync_obj = NULL; clear_bit(TTM_BO_PRIV_FLAG_MOVING, &bo->priv_flags); - spin_unlock(&bo->lock); + spin_unlock(&bdev->fence_lock); driver->sync_obj_unref(&tmp_obj); - spin_lock(&bo->lock); + spin_lock(&bdev->fence_lock); continue; } @@ -1683,29 +1683,29 @@ int ttm_bo_wait(struct ttm_buffer_object *bo, sync_obj = driver->sync_obj_ref(bo->sync_obj); sync_obj_arg = bo->sync_obj_arg; - spin_unlock(&bo->lock); + spin_unlock(&bdev->fence_lock); ret = driver->sync_obj_wait(sync_obj, sync_obj_arg, lazy, interruptible); if (unlikely(ret != 0)) { driver->sync_obj_unref(&sync_obj); - spin_lock(&bo->lock); + spin_lock(&bdev->fence_lock); return ret; } - spin_lock(&bo->lock); + spin_lock(&bdev->fence_lock); if (likely(bo->sync_obj == sync_obj && bo->sync_obj_arg == sync_obj_arg)) { void *tmp_obj = bo->sync_obj; bo->sync_obj = NULL; clear_bit(TTM_BO_PRIV_FLAG_MOVING, &bo->priv_flags); - spin_unlock(&bo->lock); + spin_unlock(&bdev->fence_lock); driver->sync_obj_unref(&sync_obj); driver->sync_obj_unref(&tmp_obj); - spin_lock(&bo->lock); + spin_lock(&bdev->fence_lock); } else { - spin_unlock(&bo->lock); + spin_unlock(&bdev->fence_lock); driver->sync_obj_unref(&sync_obj); - spin_lock(&bo->lock); + spin_lock(&bdev->fence_lock); } } return 0; @@ -1714,6 +1714,7 @@ EXPORT_SYMBOL(ttm_bo_wait); int ttm_bo_synccpu_write_grab(struct ttm_buffer_object *bo, bool no_wait) { + struct ttm_bo_device *bdev = bo->bdev; int ret = 0; /* @@ -1723,9 +1724,9 @@ int ttm_bo_synccpu_write_grab(struct ttm_buffer_object *bo, bool no_wait) ret = ttm_bo_reserve(bo, true, no_wait, false, 0); if (unlikely(ret != 0)) return ret; - spin_lock(&bo->lock); + spin_lock(&bdev->fence_lock); ret = ttm_bo_wait(bo, false, true, no_wait); - spin_unlock(&bo->lock); + spin_unlock(&bdev->fence_lock); if (likely(ret == 0)) atomic_inc(&bo->cpu_writers); ttm_bo_unreserve(bo); @@ -1797,9 +1798,9 @@ static int ttm_bo_swapout(struct ttm_mem_shrink *shrink) * Wait for GPU, then move to system cached. */ - spin_lock(&bo->lock); + spin_lock(&bo->bdev->fence_lock); ret = ttm_bo_wait(bo, false, false, false); - spin_unlock(&bo->lock); + spin_unlock(&bo->bdev->fence_lock); if (unlikely(ret != 0)) goto out; diff --git a/drivers/gpu/drm/ttm/ttm_bo_util.c b/drivers/gpu/drm/ttm/ttm_bo_util.c index 3106d5bcce32..4b75133d6606 100644 --- a/drivers/gpu/drm/ttm/ttm_bo_util.c +++ b/drivers/gpu/drm/ttm/ttm_bo_util.c @@ -337,7 +337,6 @@ static int ttm_buffer_object_transfer(struct ttm_buffer_object *bo, * TODO: Explicit member copy would probably be better here. */ - spin_lock_init(&fbo->lock); init_waitqueue_head(&fbo->event_queue); INIT_LIST_HEAD(&fbo->ddestroy); INIT_LIST_HEAD(&fbo->lru); @@ -520,7 +519,7 @@ int ttm_bo_move_accel_cleanup(struct ttm_buffer_object *bo, struct ttm_buffer_object *ghost_obj; void *tmp_obj = NULL; - spin_lock(&bo->lock); + spin_lock(&bdev->fence_lock); if (bo->sync_obj) { tmp_obj = bo->sync_obj; bo->sync_obj = NULL; @@ -529,7 +528,7 @@ int ttm_bo_move_accel_cleanup(struct ttm_buffer_object *bo, bo->sync_obj_arg = sync_obj_arg; if (evict) { ret = ttm_bo_wait(bo, false, false, false); - spin_unlock(&bo->lock); + spin_unlock(&bdev->fence_lock); if (tmp_obj) driver->sync_obj_unref(&tmp_obj); if (ret) @@ -552,7 +551,7 @@ int ttm_bo_move_accel_cleanup(struct ttm_buffer_object *bo, */ set_bit(TTM_BO_PRIV_FLAG_MOVING, &bo->priv_flags); - spin_unlock(&bo->lock); + spin_unlock(&bdev->fence_lock); if (tmp_obj) driver->sync_obj_unref(&tmp_obj); diff --git a/drivers/gpu/drm/ttm/ttm_bo_vm.c b/drivers/gpu/drm/ttm/ttm_bo_vm.c index fe6cb77899f4..8dd446cb778e 100644 --- a/drivers/gpu/drm/ttm/ttm_bo_vm.c +++ b/drivers/gpu/drm/ttm/ttm_bo_vm.c @@ -118,17 +118,17 @@ static int ttm_bo_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf) * move. */ - spin_lock(&bo->lock); + spin_lock(&bdev->fence_lock); if (test_bit(TTM_BO_PRIV_FLAG_MOVING, &bo->priv_flags)) { ret = ttm_bo_wait(bo, false, true, false); - spin_unlock(&bo->lock); + spin_unlock(&bdev->fence_lock); if (unlikely(ret != 0)) { retval = (ret != -ERESTARTSYS) ? VM_FAULT_SIGBUS : VM_FAULT_NOPAGE; goto out_unlock; } } else - spin_unlock(&bo->lock); + spin_unlock(&bdev->fence_lock); ret = ttm_mem_io_reserve(bdev, &bo->mem); diff --git a/drivers/gpu/drm/ttm/ttm_execbuf_util.c b/drivers/gpu/drm/ttm/ttm_execbuf_util.c index 7dcc6470e2f5..c3a2100bace6 100644 --- a/drivers/gpu/drm/ttm/ttm_execbuf_util.c +++ b/drivers/gpu/drm/ttm/ttm_execbuf_util.c @@ -203,14 +203,15 @@ void ttm_eu_fence_buffer_objects(struct list_head *list, void *sync_obj) list_for_each_entry(entry, list, head) { struct ttm_buffer_object *bo = entry->bo; - struct ttm_bo_driver *driver = bo->bdev->driver; + struct ttm_bo_device *bdev = bo->bdev; + struct ttm_bo_driver *driver = bdev->driver; void *old_sync_obj; - spin_lock(&bo->lock); + spin_lock(&bdev->fence_lock); old_sync_obj = bo->sync_obj; bo->sync_obj = driver->sync_obj_ref(sync_obj); bo->sync_obj_arg = entry->new_sync_obj_arg; - spin_unlock(&bo->lock); + spin_unlock(&bdev->fence_lock); ttm_bo_unreserve(bo); entry->reserved = false; if (old_sync_obj) diff --git a/include/drm/ttm/ttm_bo_api.h b/include/drm/ttm/ttm_bo_api.h index b0fc9c12554b..edacd483c59c 100644 --- a/include/drm/ttm/ttm_bo_api.h +++ b/include/drm/ttm/ttm_bo_api.h @@ -154,7 +154,6 @@ struct ttm_tt; * keeps one refcount. When this refcount reaches zero, * the object is destroyed. * @event_queue: Queue for processes waiting on buffer object status change. - * @lock: spinlock protecting mostly synchronization members. * @mem: structure describing current placement. * @persistant_swap_storage: Usually the swap storage is deleted for buffers * pinned in physical memory. If this behaviour is not desired, this member @@ -213,7 +212,6 @@ struct ttm_buffer_object { struct kref kref; struct kref list_kref; wait_queue_head_t event_queue; - spinlock_t lock; /** * Members protected by the bo::reserved lock. @@ -248,10 +246,10 @@ struct ttm_buffer_object { atomic_t reserved; /** - * Members protected by the bo::lock + * Members protected by struct buffer_object_device::fence_lock * In addition, setting sync_obj to anything else * than NULL requires bo::reserved to be held. This allows for - * checking NULL while reserved but not holding bo::lock. + * checking NULL while reserved but not holding the mentioned lock. */ void *sync_obj_arg; diff --git a/include/drm/ttm/ttm_bo_driver.h b/include/drm/ttm/ttm_bo_driver.h index 1e25a40c688e..ca8131e98300 100644 --- a/include/drm/ttm/ttm_bo_driver.h +++ b/include/drm/ttm/ttm_bo_driver.h @@ -510,6 +510,8 @@ struct ttm_bo_global { * * @driver: Pointer to a struct ttm_bo_driver struct setup by the driver. * @man: An array of mem_type_managers. + * @fence_lock: Protects the synchronizing members on *all* bos belonging + * to this device. * @addr_space_mm: Range manager for the device address space. * lru_lock: Spinlock that protects the buffer+device lru lists and * ddestroy lists. @@ -531,6 +533,7 @@ struct ttm_bo_device { struct ttm_bo_driver *driver; rwlock_t vm_lock; struct ttm_mem_type_manager man[TTM_NUM_MEM_TYPES]; + spinlock_t fence_lock; /* * Protected by the vm lock. */ -- cgit v1.2.3 From 95762c2b34069bf4adb7929969f1f5f5fc8a38df Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Wed, 17 Nov 2010 12:28:30 +0000 Subject: drm/ttm: Improved fencing of buffer object lists Drastically reduce the number of spin lock / unlock operations by performing unreserving and fencing under global locks. Signed-off-by: Thomas Hellstrom Reviewed-by: Jerome Glisse Signed-off-by: Dave Airlie --- drivers/gpu/drm/ttm/ttm_bo.c | 11 ++++++++--- drivers/gpu/drm/ttm/ttm_execbuf_util.c | 36 +++++++++++++++++++++++----------- include/drm/ttm/ttm_bo_driver.h | 10 ++++++++++ include/drm/ttm/ttm_execbuf_util.h | 2 ++ 4 files changed, 45 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c index d93c73b1c471..551a5d31cadf 100644 --- a/drivers/gpu/drm/ttm/ttm_bo.c +++ b/drivers/gpu/drm/ttm/ttm_bo.c @@ -299,14 +299,19 @@ int ttm_bo_reserve(struct ttm_buffer_object *bo, return ret; } +void ttm_bo_unreserve_locked(struct ttm_buffer_object *bo) +{ + ttm_bo_add_to_lru(bo); + atomic_set(&bo->reserved, 0); + wake_up_all(&bo->event_queue); +} + void ttm_bo_unreserve(struct ttm_buffer_object *bo) { struct ttm_bo_global *glob = bo->glob; spin_lock(&glob->lru_lock); - ttm_bo_add_to_lru(bo); - atomic_set(&bo->reserved, 0); - wake_up_all(&bo->event_queue); + ttm_bo_unreserve_locked(bo); spin_unlock(&glob->lru_lock); } EXPORT_SYMBOL(ttm_bo_unreserve); diff --git a/drivers/gpu/drm/ttm/ttm_execbuf_util.c b/drivers/gpu/drm/ttm/ttm_execbuf_util.c index c3a2100bace6..b6da65cc502a 100644 --- a/drivers/gpu/drm/ttm/ttm_execbuf_util.c +++ b/drivers/gpu/drm/ttm/ttm_execbuf_util.c @@ -200,22 +200,36 @@ EXPORT_SYMBOL(ttm_eu_reserve_buffers); void ttm_eu_fence_buffer_objects(struct list_head *list, void *sync_obj) { struct ttm_validate_buffer *entry; + struct ttm_buffer_object *bo; + struct ttm_bo_global *glob; + struct ttm_bo_device *bdev; + struct ttm_bo_driver *driver; - list_for_each_entry(entry, list, head) { - struct ttm_buffer_object *bo = entry->bo; - struct ttm_bo_device *bdev = bo->bdev; - struct ttm_bo_driver *driver = bdev->driver; - void *old_sync_obj; + if (list_empty(list)) + return; + + bo = list_first_entry(list, struct ttm_validate_buffer, head)->bo; + bdev = bo->bdev; + driver = bdev->driver; + glob = bo->glob; - spin_lock(&bdev->fence_lock); - old_sync_obj = bo->sync_obj; + spin_lock(&bdev->fence_lock); + spin_lock(&glob->lru_lock); + + list_for_each_entry(entry, list, head) { + bo = entry->bo; + entry->old_sync_obj = bo->sync_obj; bo->sync_obj = driver->sync_obj_ref(sync_obj); bo->sync_obj_arg = entry->new_sync_obj_arg; - spin_unlock(&bdev->fence_lock); - ttm_bo_unreserve(bo); + ttm_bo_unreserve_locked(bo); entry->reserved = false; - if (old_sync_obj) - driver->sync_obj_unref(&old_sync_obj); + } + spin_unlock(&glob->lru_lock); + spin_unlock(&bdev->fence_lock); + + list_for_each_entry(entry, list, head) { + if (entry->old_sync_obj) + driver->sync_obj_unref(&entry->old_sync_obj); } } EXPORT_SYMBOL(ttm_eu_fence_buffer_objects); diff --git a/include/drm/ttm/ttm_bo_driver.h b/include/drm/ttm/ttm_bo_driver.h index ca8131e98300..cfb9ca4ec1c4 100644 --- a/include/drm/ttm/ttm_bo_driver.h +++ b/include/drm/ttm/ttm_bo_driver.h @@ -909,6 +909,16 @@ extern int ttm_bo_reserve_locked(struct ttm_buffer_object *bo, */ extern void ttm_bo_unreserve(struct ttm_buffer_object *bo); +/** + * ttm_bo_unreserve_locked + * + * @bo: A pointer to a struct ttm_buffer_object. + * + * Unreserve a previous reservation of @bo. + * Needs to be called with struct ttm_bo_global::lru_lock held. + */ +extern void ttm_bo_unreserve_locked(struct ttm_buffer_object *bo); + /** * ttm_bo_wait_unreserved * diff --git a/include/drm/ttm/ttm_execbuf_util.h b/include/drm/ttm/ttm_execbuf_util.h index fd09b8438977..535ab00407e0 100644 --- a/include/drm/ttm/ttm_execbuf_util.h +++ b/include/drm/ttm/ttm_execbuf_util.h @@ -44,6 +44,7 @@ * @reserved: Indicates whether @bo has been reserved for validation. * @removed: Indicates whether @bo has been removed from lru lists. * @put_count: Number of outstanding references on bo::list_kref. + * @old_sync_obj: Pointer to a sync object about to be unreferenced */ struct ttm_validate_buffer { @@ -53,6 +54,7 @@ struct ttm_validate_buffer { bool reserved; bool removed; int put_count; + void *old_sync_obj; }; /** -- cgit v1.2.3 From 65705962025df490d13df59ec57c5329d1bd0a16 Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Wed, 17 Nov 2010 12:28:31 +0000 Subject: drm/ttm/vmwgfx: Have TTM manage the validation sequence. Rather than having the driver supply the validation sequence, leave that responsibility to TTM. This saves some confusion and a function argument. Signed-off-by: Thomas Hellstrom Signed-off-by: Dave Airlie --- drivers/gpu/drm/ttm/ttm_bo.c | 1 + drivers/gpu/drm/ttm/ttm_execbuf_util.c | 5 ++++- drivers/gpu/drm/vmwgfx/vmwgfx_drv.h | 1 - drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c | 3 +-- include/drm/ttm/ttm_bo_driver.h | 2 ++ include/drm/ttm/ttm_execbuf_util.h | 3 +-- 6 files changed, 9 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c index 551a5d31cadf..25e4c2a1d1d8 100644 --- a/drivers/gpu/drm/ttm/ttm_bo.c +++ b/drivers/gpu/drm/ttm/ttm_bo.c @@ -1539,6 +1539,7 @@ int ttm_bo_device_init(struct ttm_bo_device *bdev, bdev->dev_mapping = NULL; bdev->glob = glob; bdev->need_dma32 = need_dma32; + bdev->val_seq = 0; spin_lock_init(&bdev->fence_lock); mutex_lock(&glob->device_list_mutex); list_add_tail(&bdev->device_list, &glob->device_list); diff --git a/drivers/gpu/drm/ttm/ttm_execbuf_util.c b/drivers/gpu/drm/ttm/ttm_execbuf_util.c index b6da65cc502a..3832fe10b4df 100644 --- a/drivers/gpu/drm/ttm/ttm_execbuf_util.c +++ b/drivers/gpu/drm/ttm/ttm_execbuf_util.c @@ -126,11 +126,12 @@ EXPORT_SYMBOL(ttm_eu_backoff_reservation); * buffers in different orders. */ -int ttm_eu_reserve_buffers(struct list_head *list, uint32_t val_seq) +int ttm_eu_reserve_buffers(struct list_head *list) { struct ttm_bo_global *glob; struct ttm_validate_buffer *entry; int ret; + uint32_t val_seq; if (list_empty(list)) return 0; @@ -146,6 +147,8 @@ int ttm_eu_reserve_buffers(struct list_head *list, uint32_t val_seq) retry: spin_lock(&glob->lru_lock); + val_seq = entry->bo->bdev->val_seq++; + list_for_each_entry(entry, list, head) { struct ttm_buffer_object *bo = entry->bo; diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h index e7a58d055041..10fc01f69c40 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h @@ -264,7 +264,6 @@ struct vmw_private { */ struct vmw_sw_context ctx; - uint32_t val_seq; struct mutex cmdbuf_mutex; /** diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c index 76954e3528c1..41b95ed6dbcd 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c @@ -653,8 +653,7 @@ int vmw_execbuf_ioctl(struct drm_device *dev, void *data, ret = vmw_cmd_check_all(dev_priv, sw_context, cmd, arg->command_size); if (unlikely(ret != 0)) goto out_err; - ret = ttm_eu_reserve_buffers(&sw_context->validate_nodes, - dev_priv->val_seq++); + ret = ttm_eu_reserve_buffers(&sw_context->validate_nodes); if (unlikely(ret != 0)) goto out_err; diff --git a/include/drm/ttm/ttm_bo_driver.h b/include/drm/ttm/ttm_bo_driver.h index cfb9ca4ec1c4..e3b2e245db1b 100644 --- a/include/drm/ttm/ttm_bo_driver.h +++ b/include/drm/ttm/ttm_bo_driver.h @@ -515,6 +515,7 @@ struct ttm_bo_global { * @addr_space_mm: Range manager for the device address space. * lru_lock: Spinlock that protects the buffer+device lru lists and * ddestroy lists. + * @val_seq: Current validation sequence. * @nice_mode: Try nicely to wait for buffer idle when cleaning a manager. * If a GPU lockup has been detected, this is forced to 0. * @dev_mapping: A pointer to the struct address_space representing the @@ -544,6 +545,7 @@ struct ttm_bo_device { * Protected by the global:lru lock. */ struct list_head ddestroy; + uint32_t val_seq; /* * Protected by load / firstopen / lastclose /unload sync. diff --git a/include/drm/ttm/ttm_execbuf_util.h b/include/drm/ttm/ttm_execbuf_util.h index 535ab00407e0..26cc7f9ffa41 100644 --- a/include/drm/ttm/ttm_execbuf_util.h +++ b/include/drm/ttm/ttm_execbuf_util.h @@ -72,7 +72,6 @@ extern void ttm_eu_backoff_reservation(struct list_head *list); * function ttm_eu_reserve_buffers * * @list: thread private list of ttm_validate_buffer structs. - * @val_seq: A unique sequence number. * * Tries to reserve bos pointed to by the list entries for validation. * If the function returns 0, all buffers are marked as "unfenced", @@ -94,7 +93,7 @@ extern void ttm_eu_backoff_reservation(struct list_head *list); * has failed. */ -extern int ttm_eu_reserve_buffers(struct list_head *list, uint32_t val_seq); +extern int ttm_eu_reserve_buffers(struct list_head *list); /** * function ttm_eu_fence_buffer_objects. -- cgit v1.2.3 From eba67093f535322cb4f1c4b737319c0907a0c81d Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Thu, 11 Nov 2010 09:41:57 +0100 Subject: drm/ttm: Fix up io_mem_reserve / io_mem_free calling This patch attempts to fix up shortcomings with the current calling sequences. 1) There's a fastpath where no locking occurs and only io_mem_reserved is called to obtain needed info for mapping. The fastpath is set per memory type manager. 2) If the fastpath is disabled, io_mem_reserve and io_mem_free will be exactly balanced and not called recursively for the same struct ttm_mem_reg. 3) Optionally the driver can choose to enable a per memory type manager LRU eviction mechanism that, when io_mem_reserve returns -EAGAIN will attempt to kill user-space mappings of memory in that manager to free up needed resources Signed-off-by: Thomas Hellstrom Reviewed-by: Ben Skeggs Signed-off-by: Dave Airlie --- drivers/gpu/drm/ttm/ttm_bo.c | 44 ++++++++++--- drivers/gpu/drm/ttm/ttm_bo_util.c | 129 +++++++++++++++++++++++++++++++++----- drivers/gpu/drm/ttm/ttm_bo_vm.c | 23 ++++--- include/drm/ttm/ttm_bo_api.h | 6 +- include/drm/ttm/ttm_bo_driver.h | 104 +++++++++++++++--------------- 5 files changed, 226 insertions(+), 80 deletions(-) diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c index 25e4c2a1d1d8..cf2ec562550e 100644 --- a/drivers/gpu/drm/ttm/ttm_bo.c +++ b/drivers/gpu/drm/ttm/ttm_bo.c @@ -378,8 +378,13 @@ static int ttm_bo_handle_move_mem(struct ttm_buffer_object *bo, int ret = 0; if (old_is_pci || new_is_pci || - ((mem->placement & bo->mem.placement & TTM_PL_MASK_CACHING) == 0)) - ttm_bo_unmap_virtual(bo); + ((mem->placement & bo->mem.placement & TTM_PL_MASK_CACHING) == 0)) { + ret = ttm_mem_io_lock(old_man, true); + if (unlikely(ret != 0)) + goto out_err; + ttm_bo_unmap_virtual_locked(bo); + ttm_mem_io_unlock(old_man); + } /* * Create and bind a ttm if required. @@ -466,7 +471,6 @@ static void ttm_bo_cleanup_memtype_use(struct ttm_buffer_object *bo) ttm_tt_destroy(bo->ttm); bo->ttm = NULL; } - ttm_bo_mem_put(bo, &bo->mem); atomic_set(&bo->reserved, 0); @@ -665,6 +669,7 @@ static void ttm_bo_release(struct kref *kref) struct ttm_buffer_object *bo = container_of(kref, struct ttm_buffer_object, kref); struct ttm_bo_device *bdev = bo->bdev; + struct ttm_mem_type_manager *man = &bdev->man[bo->mem.mem_type]; if (likely(bo->vm_node != NULL)) { rb_erase(&bo->vm_rb, &bdev->addr_space_rb); @@ -672,6 +677,9 @@ static void ttm_bo_release(struct kref *kref) bo->vm_node = NULL; } write_unlock(&bdev->vm_lock); + ttm_mem_io_lock(man, false); + ttm_mem_io_free_vm(bo); + ttm_mem_io_unlock(man); ttm_bo_cleanup_refs_or_queue(bo); kref_put(&bo->list_kref, ttm_bo_release_list); write_lock(&bdev->vm_lock); @@ -728,7 +736,8 @@ static int ttm_bo_evict(struct ttm_buffer_object *bo, bool interruptible, evict_mem = bo->mem; evict_mem.mm_node = NULL; - evict_mem.bus.io_reserved = false; + evict_mem.bus.io_reserved_vm = false; + evict_mem.bus.io_reserved_count = 0; placement.fpfn = 0; placement.lpfn = 0; @@ -1065,7 +1074,8 @@ int ttm_bo_move_buffer(struct ttm_buffer_object *bo, mem.num_pages = bo->num_pages; mem.size = mem.num_pages << PAGE_SHIFT; mem.page_alignment = bo->mem.page_alignment; - mem.bus.io_reserved = false; + mem.bus.io_reserved_vm = false; + mem.bus.io_reserved_count = 0; /* * Determine where to move the buffer. */ @@ -1184,6 +1194,7 @@ int ttm_bo_init(struct ttm_bo_device *bdev, INIT_LIST_HEAD(&bo->lru); INIT_LIST_HEAD(&bo->ddestroy); INIT_LIST_HEAD(&bo->swap); + INIT_LIST_HEAD(&bo->io_reserve_lru); bo->bdev = bdev; bo->glob = bdev->glob; bo->type = type; @@ -1193,7 +1204,8 @@ int ttm_bo_init(struct ttm_bo_device *bdev, bo->mem.num_pages = bo->num_pages; bo->mem.mm_node = NULL; bo->mem.page_alignment = page_alignment; - bo->mem.bus.io_reserved = false; + bo->mem.bus.io_reserved_vm = false; + bo->mem.bus.io_reserved_count = 0; bo->buffer_start = buffer_start & PAGE_MASK; bo->priv_flags = 0; bo->mem.placement = (TTM_PL_FLAG_SYSTEM | TTM_PL_FLAG_CACHED); @@ -1367,6 +1379,10 @@ int ttm_bo_init_mm(struct ttm_bo_device *bdev, unsigned type, BUG_ON(type >= TTM_NUM_MEM_TYPES); man = &bdev->man[type]; BUG_ON(man->has_type); + man->io_reserve_fastpath = true; + man->use_io_reserve_lru = false; + mutex_init(&man->io_reserve_mutex); + INIT_LIST_HEAD(&man->io_reserve_lru); ret = bdev->driver->init_mem_type(bdev, type, man); if (ret) @@ -1574,7 +1590,7 @@ bool ttm_mem_reg_is_pci(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem) return true; } -void ttm_bo_unmap_virtual(struct ttm_buffer_object *bo) +void ttm_bo_unmap_virtual_locked(struct ttm_buffer_object *bo) { struct ttm_bo_device *bdev = bo->bdev; loff_t offset = (loff_t) bo->addr_space_offset; @@ -1583,8 +1599,20 @@ void ttm_bo_unmap_virtual(struct ttm_buffer_object *bo) if (!bdev->dev_mapping) return; unmap_mapping_range(bdev->dev_mapping, offset, holelen, 1); - ttm_mem_io_free(bdev, &bo->mem); + ttm_mem_io_free_vm(bo); } + +void ttm_bo_unmap_virtual(struct ttm_buffer_object *bo) +{ + struct ttm_bo_device *bdev = bo->bdev; + struct ttm_mem_type_manager *man = &bdev->man[bo->mem.mem_type]; + + ttm_mem_io_lock(man, false); + ttm_bo_unmap_virtual_locked(bo); + ttm_mem_io_unlock(man); +} + + EXPORT_SYMBOL(ttm_bo_unmap_virtual); static void ttm_bo_vm_insert_rb(struct ttm_buffer_object *bo) diff --git a/drivers/gpu/drm/ttm/ttm_bo_util.c b/drivers/gpu/drm/ttm/ttm_bo_util.c index 4b75133d6606..a89839f83f6c 100644 --- a/drivers/gpu/drm/ttm/ttm_bo_util.c +++ b/drivers/gpu/drm/ttm/ttm_bo_util.c @@ -75,37 +75,123 @@ int ttm_bo_move_ttm(struct ttm_buffer_object *bo, } EXPORT_SYMBOL(ttm_bo_move_ttm); -int ttm_mem_io_reserve(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem) +int ttm_mem_io_lock(struct ttm_mem_type_manager *man, bool interruptible) { - int ret; + if (likely(man->io_reserve_fastpath)) + return 0; + + if (interruptible) + return mutex_lock_interruptible(&man->io_reserve_mutex); + + mutex_lock(&man->io_reserve_mutex); + return 0; +} - if (!mem->bus.io_reserved) { - mem->bus.io_reserved = true; +void ttm_mem_io_unlock(struct ttm_mem_type_manager *man) +{ + if (likely(man->io_reserve_fastpath)) + return; + + mutex_unlock(&man->io_reserve_mutex); +} + +static int ttm_mem_io_evict(struct ttm_mem_type_manager *man) +{ + struct ttm_buffer_object *bo; + + if (!man->use_io_reserve_lru || list_empty(&man->io_reserve_lru)) + return -EAGAIN; + + bo = list_first_entry(&man->io_reserve_lru, + struct ttm_buffer_object, + io_reserve_lru); + list_del_init(&bo->io_reserve_lru); + ttm_bo_unmap_virtual_locked(bo); + + return 0; +} + +static int ttm_mem_io_reserve(struct ttm_bo_device *bdev, + struct ttm_mem_reg *mem) +{ + struct ttm_mem_type_manager *man = &bdev->man[mem->mem_type]; + int ret = 0; + + if (!bdev->driver->io_mem_reserve) + return 0; + if (likely(man->io_reserve_fastpath)) + return bdev->driver->io_mem_reserve(bdev, mem); + + if (bdev->driver->io_mem_reserve && + mem->bus.io_reserved_count++ == 0) { +retry: ret = bdev->driver->io_mem_reserve(bdev, mem); + if (ret == -EAGAIN) { + ret = ttm_mem_io_evict(man); + if (ret == 0) + goto retry; + } + } + return ret; +} + +static void ttm_mem_io_free(struct ttm_bo_device *bdev, + struct ttm_mem_reg *mem) +{ + struct ttm_mem_type_manager *man = &bdev->man[mem->mem_type]; + + if (likely(man->io_reserve_fastpath)) + return; + + if (bdev->driver->io_mem_reserve && + --mem->bus.io_reserved_count == 0 && + bdev->driver->io_mem_free) + bdev->driver->io_mem_free(bdev, mem); + +} + +int ttm_mem_io_reserve_vm(struct ttm_buffer_object *bo) +{ + struct ttm_mem_reg *mem = &bo->mem; + int ret; + + if (!mem->bus.io_reserved_vm) { + struct ttm_mem_type_manager *man = + &bo->bdev->man[mem->mem_type]; + + ret = ttm_mem_io_reserve(bo->bdev, mem); if (unlikely(ret != 0)) return ret; + mem->bus.io_reserved_vm = true; + if (man->use_io_reserve_lru) + list_add_tail(&bo->io_reserve_lru, + &man->io_reserve_lru); } return 0; } -void ttm_mem_io_free(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem) +void ttm_mem_io_free_vm(struct ttm_buffer_object *bo) { - if (bdev->driver->io_mem_reserve) { - if (mem->bus.io_reserved) { - mem->bus.io_reserved = false; - bdev->driver->io_mem_free(bdev, mem); - } + struct ttm_mem_reg *mem = &bo->mem; + + if (mem->bus.io_reserved_vm) { + mem->bus.io_reserved_vm = false; + list_del_init(&bo->io_reserve_lru); + ttm_mem_io_free(bo->bdev, mem); } } int ttm_mem_reg_ioremap(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem, void **virtual) { + struct ttm_mem_type_manager *man = &bdev->man[mem->mem_type]; int ret; void *addr; *virtual = NULL; + (void) ttm_mem_io_lock(man, false); ret = ttm_mem_io_reserve(bdev, mem); + ttm_mem_io_unlock(man); if (ret || !mem->bus.is_iomem) return ret; @@ -117,7 +203,9 @@ int ttm_mem_reg_ioremap(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem, else addr = ioremap_nocache(mem->bus.base + mem->bus.offset, mem->bus.size); if (!addr) { + (void) ttm_mem_io_lock(man, false); ttm_mem_io_free(bdev, mem); + ttm_mem_io_unlock(man); return -ENOMEM; } } @@ -134,7 +222,9 @@ void ttm_mem_reg_iounmap(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem, if (virtual && mem->bus.addr == NULL) iounmap(virtual); + (void) ttm_mem_io_lock(man, false); ttm_mem_io_free(bdev, mem); + ttm_mem_io_unlock(man); } static int ttm_copy_io_page(void *dst, void *src, unsigned long page) @@ -231,7 +321,7 @@ int ttm_bo_move_memcpy(struct ttm_buffer_object *bo, struct ttm_mem_type_manager *man = &bdev->man[new_mem->mem_type]; struct ttm_tt *ttm = bo->ttm; struct ttm_mem_reg *old_mem = &bo->mem; - struct ttm_mem_reg old_copy = *old_mem; + struct ttm_mem_reg old_copy; void *old_iomap; void *new_iomap; int ret; @@ -281,7 +371,7 @@ int ttm_bo_move_memcpy(struct ttm_buffer_object *bo, mb(); out2: ttm_bo_free_old_node(bo); - + old_copy = *old_mem; *old_mem = *new_mem; new_mem->mm_node = NULL; @@ -292,7 +382,7 @@ out2: } out1: - ttm_mem_reg_iounmap(bdev, new_mem, new_iomap); + ttm_mem_reg_iounmap(bdev, old_mem, new_iomap); out: ttm_mem_reg_iounmap(bdev, &old_copy, old_iomap); return ret; @@ -341,6 +431,7 @@ static int ttm_buffer_object_transfer(struct ttm_buffer_object *bo, INIT_LIST_HEAD(&fbo->ddestroy); INIT_LIST_HEAD(&fbo->lru); INIT_LIST_HEAD(&fbo->swap); + INIT_LIST_HEAD(&fbo->io_reserve_lru); fbo->vm_node = NULL; atomic_set(&fbo->cpu_writers, 0); @@ -452,6 +543,8 @@ int ttm_bo_kmap(struct ttm_buffer_object *bo, unsigned long start_page, unsigned long num_pages, struct ttm_bo_kmap_obj *map) { + struct ttm_mem_type_manager *man = + &bo->bdev->man[bo->mem.mem_type]; unsigned long offset, size; int ret; @@ -466,7 +559,9 @@ int ttm_bo_kmap(struct ttm_buffer_object *bo, if (num_pages > 1 && !DRM_SUSER(DRM_CURPROC)) return -EPERM; #endif + (void) ttm_mem_io_lock(man, false); ret = ttm_mem_io_reserve(bo->bdev, &bo->mem); + ttm_mem_io_unlock(man); if (ret) return ret; if (!bo->mem.bus.is_iomem) { @@ -481,12 +576,15 @@ EXPORT_SYMBOL(ttm_bo_kmap); void ttm_bo_kunmap(struct ttm_bo_kmap_obj *map) { + struct ttm_buffer_object *bo = map->bo; + struct ttm_mem_type_manager *man = + &bo->bdev->man[bo->mem.mem_type]; + if (!map->virtual) return; switch (map->bo_kmap_type) { case ttm_bo_map_iomap: iounmap(map->virtual); - ttm_mem_io_free(map->bo->bdev, &map->bo->mem); break; case ttm_bo_map_vmap: vunmap(map->virtual); @@ -499,6 +597,9 @@ void ttm_bo_kunmap(struct ttm_bo_kmap_obj *map) default: BUG(); } + (void) ttm_mem_io_lock(man, false); + ttm_mem_io_free(map->bo->bdev, &map->bo->mem); + ttm_mem_io_unlock(man); map->virtual = NULL; map->page = NULL; } diff --git a/drivers/gpu/drm/ttm/ttm_bo_vm.c b/drivers/gpu/drm/ttm/ttm_bo_vm.c index 8dd446cb778e..221b924acebe 100644 --- a/drivers/gpu/drm/ttm/ttm_bo_vm.c +++ b/drivers/gpu/drm/ttm/ttm_bo_vm.c @@ -83,6 +83,8 @@ static int ttm_bo_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf) int i; unsigned long address = (unsigned long)vmf->virtual_address; int retval = VM_FAULT_NOPAGE; + struct ttm_mem_type_manager *man = + &bdev->man[bo->mem.mem_type]; /* * Work around locking order reversal in fault / nopfn @@ -130,12 +132,16 @@ static int ttm_bo_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf) } else spin_unlock(&bdev->fence_lock); - - ret = ttm_mem_io_reserve(bdev, &bo->mem); - if (ret) { - retval = VM_FAULT_SIGBUS; + ret = ttm_mem_io_lock(man, true); + if (unlikely(ret != 0)) { + retval = VM_FAULT_NOPAGE; goto out_unlock; } + ret = ttm_mem_io_reserve_vm(bo); + if (unlikely(ret != 0)) { + retval = VM_FAULT_SIGBUS; + goto out_io_unlock; + } page_offset = ((address - vma->vm_start) >> PAGE_SHIFT) + bo->vm_node->start - vma->vm_pgoff; @@ -144,7 +150,7 @@ static int ttm_bo_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf) if (unlikely(page_offset >= bo->num_pages)) { retval = VM_FAULT_SIGBUS; - goto out_unlock; + goto out_io_unlock; } /* @@ -182,7 +188,7 @@ static int ttm_bo_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf) page = ttm_tt_get_page(ttm, page_offset); if (unlikely(!page && i == 0)) { retval = VM_FAULT_OOM; - goto out_unlock; + goto out_io_unlock; } else if (unlikely(!page)) { break; } @@ -200,14 +206,15 @@ static int ttm_bo_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf) else if (unlikely(ret != 0)) { retval = (ret == -ENOMEM) ? VM_FAULT_OOM : VM_FAULT_SIGBUS; - goto out_unlock; + goto out_io_unlock; } address += PAGE_SIZE; if (unlikely(++page_offset >= page_last)) break; } - +out_io_unlock: + ttm_mem_io_unlock(man); out_unlock: ttm_bo_unreserve(bo); return retval; diff --git a/include/drm/ttm/ttm_bo_api.h b/include/drm/ttm/ttm_bo_api.h index edacd483c59c..50852aad260a 100644 --- a/include/drm/ttm/ttm_bo_api.h +++ b/include/drm/ttm/ttm_bo_api.h @@ -74,6 +74,8 @@ struct ttm_placement { * @is_iomem: is this io memory ? * @size: size in byte * @offset: offset from the base address + * @io_reserved_vm: The VM system has a refcount in @io_reserved_count + * @io_reserved_count: Refcounting the numbers of callers to ttm_mem_io_reserve * * Structure indicating the bus placement of an object. */ @@ -83,7 +85,8 @@ struct ttm_bus_placement { unsigned long size; unsigned long offset; bool is_iomem; - bool io_reserved; + bool io_reserved_vm; + uint64_t io_reserved_count; }; @@ -235,6 +238,7 @@ struct ttm_buffer_object { struct list_head lru; struct list_head ddestroy; struct list_head swap; + struct list_head io_reserve_lru; uint32_t val_seq; bool seq_valid; diff --git a/include/drm/ttm/ttm_bo_driver.h b/include/drm/ttm/ttm_bo_driver.h index e3b2e245db1b..1da8af6ac884 100644 --- a/include/drm/ttm/ttm_bo_driver.h +++ b/include/drm/ttm/ttm_bo_driver.h @@ -179,30 +179,6 @@ struct ttm_tt { #define TTM_MEMTYPE_FLAG_MAPPABLE (1 << 1) /* Memory mappable */ #define TTM_MEMTYPE_FLAG_CMA (1 << 3) /* Can't map aperture */ -/** - * struct ttm_mem_type_manager - * - * @has_type: The memory type has been initialized. - * @use_type: The memory type is enabled. - * @flags: TTM_MEMTYPE_XX flags identifying the traits of the memory - * managed by this memory type. - * @gpu_offset: If used, the GPU offset of the first managed page of - * fixed memory or the first managed location in an aperture. - * @size: Size of the managed region. - * @available_caching: A mask of available caching types, TTM_PL_FLAG_XX, - * as defined in ttm_placement_common.h - * @default_caching: The default caching policy used for a buffer object - * placed in this memory type if the user doesn't provide one. - * @manager: The range manager used for this memory type. FIXME: If the aperture - * has a page size different from the underlying system, the granularity - * of this manager should take care of this. But the range allocating code - * in ttm_bo.c needs to be modified for this. - * @lru: The lru list for this memory type. - * - * This structure is used to identify and manage memory types for a device. - * It's set up by the ttm_bo_driver::init_mem_type method. - */ - struct ttm_mem_type_manager; struct ttm_mem_type_manager_func { @@ -287,6 +263,36 @@ struct ttm_mem_type_manager_func { void (*debug)(struct ttm_mem_type_manager *man, const char *prefix); }; +/** + * struct ttm_mem_type_manager + * + * @has_type: The memory type has been initialized. + * @use_type: The memory type is enabled. + * @flags: TTM_MEMTYPE_XX flags identifying the traits of the memory + * managed by this memory type. + * @gpu_offset: If used, the GPU offset of the first managed page of + * fixed memory or the first managed location in an aperture. + * @size: Size of the managed region. + * @available_caching: A mask of available caching types, TTM_PL_FLAG_XX, + * as defined in ttm_placement_common.h + * @default_caching: The default caching policy used for a buffer object + * placed in this memory type if the user doesn't provide one. + * @func: structure pointer implementing the range manager. See above + * @priv: Driver private closure for @func. + * @io_reserve_mutex: Mutex optionally protecting shared io_reserve structures + * @use_io_reserve_lru: Use an lru list to try to unreserve io_mem_regions + * reserved by the TTM vm system. + * @io_reserve_lru: Optional lru list for unreserving io mem regions. + * @io_reserve_fastpath: Only use bdev::driver::io_mem_reserve to obtain + * static information. bdev::driver::io_mem_free is never used. + * @lru: The lru list for this memory type. + * + * This structure is used to identify and manage memory types for a device. + * It's set up by the ttm_bo_driver::init_mem_type method. + */ + + + struct ttm_mem_type_manager { struct ttm_bo_device *bdev; @@ -303,6 +309,15 @@ struct ttm_mem_type_manager { uint32_t default_caching; const struct ttm_mem_type_manager_func *func; void *priv; + struct mutex io_reserve_mutex; + bool use_io_reserve_lru; + bool io_reserve_fastpath; + + /* + * Protected by @io_reserve_mutex: + */ + + struct list_head io_reserve_lru; /* * Protected by the global->lru_lock. @@ -758,31 +773,6 @@ extern void ttm_bo_mem_put_locked(struct ttm_buffer_object *bo, extern int ttm_bo_wait_cpu(struct ttm_buffer_object *bo, bool no_wait); -/** - * ttm_bo_pci_offset - Get the PCI offset for the buffer object memory. - * - * @bo Pointer to a struct ttm_buffer_object. - * @bus_base On return the base of the PCI region - * @bus_offset On return the byte offset into the PCI region - * @bus_size On return the byte size of the buffer object or zero if - * the buffer object memory is not accessible through a PCI region. - * - * Returns: - * -EINVAL if the buffer object is currently not mappable. - * 0 otherwise. - */ - -extern int ttm_bo_pci_offset(struct ttm_bo_device *bdev, - struct ttm_mem_reg *mem, - unsigned long *bus_base, - unsigned long *bus_offset, - unsigned long *bus_size); - -extern int ttm_mem_io_reserve(struct ttm_bo_device *bdev, - struct ttm_mem_reg *mem); -extern void ttm_mem_io_free(struct ttm_bo_device *bdev, - struct ttm_mem_reg *mem); - extern void ttm_bo_global_release(struct drm_global_reference *ref); extern int ttm_bo_global_init(struct drm_global_reference *ref); @@ -814,6 +804,22 @@ extern int ttm_bo_device_init(struct ttm_bo_device *bdev, */ extern void ttm_bo_unmap_virtual(struct ttm_buffer_object *bo); +/** + * ttm_bo_unmap_virtual + * + * @bo: tear down the virtual mappings for this BO + * + * The caller must take ttm_mem_io_lock before calling this function. + */ +extern void ttm_bo_unmap_virtual_locked(struct ttm_buffer_object *bo); + +extern int ttm_mem_io_reserve_vm(struct ttm_buffer_object *bo); +extern void ttm_mem_io_free_vm(struct ttm_buffer_object *bo); +extern int ttm_mem_io_lock(struct ttm_mem_type_manager *man, + bool interruptible); +extern void ttm_mem_io_unlock(struct ttm_mem_type_manager *man); + + /** * ttm_bo_reserve: * -- cgit v1.2.3 From 147666fb3b93b8c484f562da33a37f886ddff768 Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Wed, 17 Nov 2010 12:38:32 +0000 Subject: drm/radeon: Use the ttm execbuf utilities Rather than re-implementing in the Radeon driver, Use the execbuf / cs / pushbuf utilities that comes with TTM. This comes with an even greater benefit now that many spinlocks have been optimized away... Signed-off-by: Thomas Hellstrom Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/radeon.h | 4 +-- drivers/gpu/drm/radeon/radeon_cs.c | 17 ++++++----- drivers/gpu/drm/radeon/radeon_object.c | 55 +++------------------------------- drivers/gpu/drm/radeon/radeon_object.h | 3 -- 4 files changed, 16 insertions(+), 63 deletions(-) diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 3a7095743d44..b1e073b7381f 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -69,6 +69,7 @@ #include #include #include +#include #include "radeon_family.h" #include "radeon_mode.h" @@ -259,13 +260,12 @@ struct radeon_bo { }; struct radeon_bo_list { - struct list_head list; + struct ttm_validate_buffer tv; struct radeon_bo *bo; uint64_t gpu_offset; unsigned rdomain; unsigned wdomain; u32 tiling_flags; - bool reserved; }; /* diff --git a/drivers/gpu/drm/radeon/radeon_cs.c b/drivers/gpu/drm/radeon/radeon_cs.c index 6d64a2705f12..35b5eb8fbe2a 100644 --- a/drivers/gpu/drm/radeon/radeon_cs.c +++ b/drivers/gpu/drm/radeon/radeon_cs.c @@ -77,13 +77,13 @@ int radeon_cs_parser_relocs(struct radeon_cs_parser *p) p->relocs_ptr[i] = &p->relocs[i]; p->relocs[i].robj = p->relocs[i].gobj->driver_private; p->relocs[i].lobj.bo = p->relocs[i].robj; - p->relocs[i].lobj.rdomain = r->read_domains; p->relocs[i].lobj.wdomain = r->write_domain; + p->relocs[i].lobj.rdomain = r->read_domains; + p->relocs[i].lobj.tv.bo = &p->relocs[i].robj->tbo; p->relocs[i].handle = r->handle; p->relocs[i].flags = r->flags; - INIT_LIST_HEAD(&p->relocs[i].lobj.list); radeon_bo_list_add_object(&p->relocs[i].lobj, - &p->validated); + &p->validated); } } return radeon_bo_list_validate(&p->validated); @@ -189,10 +189,13 @@ static void radeon_cs_parser_fini(struct radeon_cs_parser *parser, int error) { unsigned i; - if (!error && parser->ib) { - radeon_bo_list_fence(&parser->validated, parser->ib->fence); - } - radeon_bo_list_unreserve(&parser->validated); + + if (!error && parser->ib) + ttm_eu_fence_buffer_objects(&parser->validated, + parser->ib->fence); + else + ttm_eu_backoff_reservation(&parser->validated); + if (parser->relocs != NULL) { for (i = 0; i < parser->nrelocs; i++) { if (parser->relocs[i].gobj) diff --git a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/radeon/radeon_object.c index e939cb6a91cc..a8594d289bcf 100644 --- a/drivers/gpu/drm/radeon/radeon_object.c +++ b/drivers/gpu/drm/radeon/radeon_object.c @@ -293,34 +293,9 @@ void radeon_bo_list_add_object(struct radeon_bo_list *lobj, struct list_head *head) { if (lobj->wdomain) { - list_add(&lobj->list, head); + list_add(&lobj->tv.head, head); } else { - list_add_tail(&lobj->list, head); - } -} - -int radeon_bo_list_reserve(struct list_head *head) -{ - struct radeon_bo_list *lobj; - int r; - - list_for_each_entry(lobj, head, list){ - r = radeon_bo_reserve(lobj->bo, false); - if (unlikely(r != 0)) - return r; - lobj->reserved = true; - } - return 0; -} - -void radeon_bo_list_unreserve(struct list_head *head) -{ - struct radeon_bo_list *lobj; - - list_for_each_entry(lobj, head, list) { - /* only unreserve object we successfully reserved */ - if (lobj->reserved && radeon_bo_is_reserved(lobj->bo)) - radeon_bo_unreserve(lobj->bo); + list_add_tail(&lobj->tv.head, head); } } @@ -331,14 +306,11 @@ int radeon_bo_list_validate(struct list_head *head) u32 domain; int r; - list_for_each_entry(lobj, head, list) { - lobj->reserved = false; - } - r = radeon_bo_list_reserve(head); + r = ttm_eu_reserve_buffers(head); if (unlikely(r != 0)) { return r; } - list_for_each_entry(lobj, head, list) { + list_for_each_entry(lobj, head, tv.head) { bo = lobj->bo; if (!bo->pin_count) { domain = lobj->wdomain ? lobj->wdomain : lobj->rdomain; @@ -361,25 +333,6 @@ int radeon_bo_list_validate(struct list_head *head) return 0; } -void radeon_bo_list_fence(struct list_head *head, void *fence) -{ - struct radeon_bo_list *lobj; - struct radeon_bo *bo; - struct radeon_fence *old_fence = NULL; - - list_for_each_entry(lobj, head, list) { - bo = lobj->bo; - spin_lock(&bo->tbo.bdev->fence_lock); - old_fence = (struct radeon_fence *)bo->tbo.sync_obj; - bo->tbo.sync_obj = radeon_fence_ref(fence); - bo->tbo.sync_obj_arg = NULL; - spin_unlock(&bo->tbo.bdev->fence_lock); - if (old_fence) { - radeon_fence_unref(&old_fence); - } - } -} - int radeon_bo_fbdev_mmap(struct radeon_bo *bo, struct vm_area_struct *vma) { diff --git a/drivers/gpu/drm/radeon/radeon_object.h b/drivers/gpu/drm/radeon/radeon_object.h index fd536751f865..22d4c237dea5 100644 --- a/drivers/gpu/drm/radeon/radeon_object.h +++ b/drivers/gpu/drm/radeon/radeon_object.h @@ -152,10 +152,7 @@ extern int radeon_bo_init(struct radeon_device *rdev); extern void radeon_bo_fini(struct radeon_device *rdev); extern void radeon_bo_list_add_object(struct radeon_bo_list *lobj, struct list_head *head); -extern int radeon_bo_list_reserve(struct list_head *head); -extern void radeon_bo_list_unreserve(struct list_head *head); extern int radeon_bo_list_validate(struct list_head *head); -extern void radeon_bo_list_fence(struct list_head *head, void *fence); extern int radeon_bo_fbdev_mmap(struct radeon_bo *bo, struct vm_area_struct *vma); extern int radeon_bo_set_tiling_flags(struct radeon_bo *bo, -- cgit v1.2.3 From 03b7a1ab557efe34e8f79b78660e514bd7374248 Mon Sep 17 00:00:00 2001 From: David Henningsson Date: Tue, 9 Nov 2010 14:35:30 +0100 Subject: ALSA: HDA: Create mixers on ALC887 BugLink: http://launchpad.net/bugs/669092 ALC887 does not have any volume control ability on the mixer NIDs, so put the volume controls on the dac NIDs instead. Without this patch, ALC887 users cannot use alsamixer at all. Cc: stable@kernel.org Signed-off-by: David Henningsson Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 5f00589cb791..74029b5e7a62 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -10816,6 +10816,9 @@ static int alc_auto_add_mic_boost(struct hda_codec *codec) return 0; } +static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec, + const struct auto_pin_cfg *cfg); + /* almost identical with ALC880 parser... */ static int alc882_parse_auto_config(struct hda_codec *codec) { @@ -10833,7 +10836,10 @@ static int alc882_parse_auto_config(struct hda_codec *codec) err = alc880_auto_fill_dac_nids(spec, &spec->autocfg); if (err < 0) return err; - err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg); + if (codec->vendor_id == 0x10ec0887) + err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg); + else + err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg); if (err < 0) return err; err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0], @@ -16963,7 +16969,7 @@ static void alc861vd_auto_init_analog_input(struct hda_codec *codec) #define alc861vd_idx_to_mixer_switch(nid) ((nid) + 0x0c) /* add playback controls from the parsed DAC table */ -/* Based on ALC880 version. But ALC861VD has separate, +/* Based on ALC880 version. But ALC861VD and ALC887 have separate, * different NIDs for mute/unmute switch and volume control */ static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec, const struct auto_pin_cfg *cfg) -- cgit v1.2.3 From 86cbbad2b6712fbd25c07a17e86b4345cee82c6d Mon Sep 17 00:00:00 2001 From: Daniel T Chen Date: Sat, 20 Nov 2010 10:20:35 -0500 Subject: ALSA: hda: Add Samsung R720 SSID for subwoofer pin fixup BugLink: https://launchpad.net/bugs/677830 The original reporter states that the subwoofer does not mute when inserting headphones. We need an entry for his machine's SSID in the subwoofer pin fixup list, so add it there (verified using hda_analyzer). Reported-and-tested-by: i-NoD Cc: Signed-off-by: Daniel T Chen Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 74029b5e7a62..b7e234898fd8 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -19304,6 +19304,7 @@ static const struct alc_fixup alc662_fixups[] = { static struct snd_pci_quirk alc662_fixup_tbl[] = { SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE), + SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD), SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD), SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD), {} -- cgit v1.2.3 From 7974150c8524423f878e8269010e911c3cc7ddb8 Mon Sep 17 00:00:00 2001 From: Andreas Mohr Date: Sun, 21 Nov 2010 12:09:32 +0100 Subject: ALSA: azt3328: period bug fix (for PA), add missing ACK on stop timer . Fix PulseAudio "ALSA driver bug" issue (if we have two alternated areas within a 64k DMA buffer, then max period size should obviously be 32k only). Back references: http://pulseaudio.org/wiki/AlsaIssues http://fedoraproject.org/wiki/Features/GlitchFreeAudio . In stop timer function, need to supply ACK in the timer control byte. . Minor log output correction When I did my first PA testing recently, the period size bug resulted in quite precisely observeable half-period-based playback distortion. PA-based operation is quite a bit more underrun-prone (despite its zero-copy optimizations etc.) than raw ALSA with this rather spartan sound hardware implementation on my puny Athlon. Note that even with this patch, azt3328 still doesn't work for both cases yet, PA tsched=0 and tsched (on tsched=0 it will playback tiny fragments of periods, leading to tiny stuttering sounds with some pauses in between, whereas with timer-scheduled operation playback works fine - minus some quite increased underrun trouble on PA vs. ALSA, that is). Signed-off-by: Andreas Mohr Signed-off-by: Takashi Iwai --- sound/pci/azt3328.c | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/sound/pci/azt3328.c b/sound/pci/azt3328.c index 4679ed83a43b..2f3cacbd5528 100644 --- a/sound/pci/azt3328.c +++ b/sound/pci/azt3328.c @@ -1129,10 +1129,11 @@ snd_azf3328_codec_setdmaa(struct snd_azf3328 *chip, count_areas = size/2; addr_area2 = addr+count_areas; - count_areas--; /* max. index */ snd_azf3328_dbgcodec("setdma: buffers %08lx[%u] / %08lx[%u]\n", addr, count_areas, addr_area2, count_areas); + count_areas--; /* max. index */ + /* build combined I/O buffer length word */ lengths = (count_areas << 16) | (count_areas); spin_lock_irqsave(&chip->reg_lock, flags); @@ -1740,11 +1741,15 @@ static const struct snd_pcm_hardware snd_azf3328_hardware = .rate_max = AZF_FREQ_66200, .channels_min = 1, .channels_max = 2, - .buffer_bytes_max = 65536, - .period_bytes_min = 64, - .period_bytes_max = 65536, - .periods_min = 1, - .periods_max = 1024, + .buffer_bytes_max = (64*1024), + .period_bytes_min = 1024, + .period_bytes_max = (32*1024), + /* We simply have two DMA areas (instead of a list of descriptors + such as other cards); I believe that this is a fixed hardware + attribute and there isn't much driver magic to be done to expand it. + Thus indicate that we have at least and at most 2 periods. */ + .periods_min = 2, + .periods_max = 2, /* FIXME: maybe that card actually has a FIFO? * Hmm, it seems newer revisions do have one, but we still don't know * its size... */ @@ -1980,8 +1985,13 @@ snd_azf3328_timer_stop(struct snd_timer *timer) chip = snd_timer_chip(timer); spin_lock_irqsave(&chip->reg_lock, flags); /* disable timer countdown and interrupt */ - /* FIXME: should we write TIMER_IRQ_ACK here? */ - snd_azf3328_ctrl_outb(chip, IDX_IO_TIMER_VALUE + 3, 0); + /* Hmm, should we write TIMER_IRQ_ACK here? + YES indeed, otherwise a rogue timer operation - which prompts + ALSA(?) to call repeated stop() in vain, but NOT start() - + will never end (value 0x03 is kept shown in control byte). + Simply manually poking 0x04 _once_ immediately successfully stops + the hardware/ALSA interrupt activity. */ + snd_azf3328_ctrl_outb(chip, IDX_IO_TIMER_VALUE + 3, 0x04); spin_unlock_irqrestore(&chip->reg_lock, flags); snd_azf3328_dbgcallleave(); return 0; -- cgit v1.2.3 From 5ad57d20c91bdaf743bd8e3015df5a388314df8d Mon Sep 17 00:00:00 2001 From: Vasiliy Kulikov Date: Sun, 21 Nov 2010 20:40:07 +0300 Subject: ALSA: snd-atmel-abdac: test wrong variable After clk_get() pclk is checked second time instead of sample_clk check. Signed-off-by: Vasiliy Kulikov Signed-off-by: Takashi Iwai --- sound/atmel/abdac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/atmel/abdac.c b/sound/atmel/abdac.c index f2f41c854221..4e47baada66f 100644 --- a/sound/atmel/abdac.c +++ b/sound/atmel/abdac.c @@ -420,7 +420,7 @@ static int __devinit atmel_abdac_probe(struct platform_device *pdev) return PTR_ERR(pclk); } sample_clk = clk_get(&pdev->dev, "sample_clk"); - if (IS_ERR(pclk)) { + if (IS_ERR(sample_clk)) { dev_dbg(&pdev->dev, "no sample clock\n"); retval = PTR_ERR(pclk); goto out_put_pclk; -- cgit v1.2.3 From a1d71a2c91239ecc1c1f9c97a081d71ebd30bfe5 Mon Sep 17 00:00:00 2001 From: Daniel T Chen Date: Sun, 21 Nov 2010 14:01:14 -0500 Subject: ALSA: hda: Use hp-laptop quirk to enable headphones automute for Asus A52J BugLink: https://launchpad.net/bugs/677652 The original reporter states that, in 2.6.35, headphones do not appear to work, nor does inserting them mute the A52J's onboard speakers. Upon inspecting the codec dump, it appears that the newly committed hp-laptop quirk will suffice to enable this basic functionality. Testing was done with an alsa-driver build from 2010-11-21. Reported-and-tested-by: Joan Creus Cc: [2.6.35+] Signed-off-by: Daniel T Chen Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_conexant.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index 6361f752b5f3..3cfb31e77b16 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c @@ -3100,6 +3100,7 @@ static struct snd_pci_quirk cxt5066_cfg_tbl[] = { SND_PCI_QUIRK(0x1028, 0x0402, "Dell Vostro", CXT5066_DELL_VOSTRO), SND_PCI_QUIRK(0x1028, 0x0408, "Dell Inspiron One 19T", CXT5066_IDEAPAD), SND_PCI_QUIRK(0x103c, 0x360b, "HP G60", CXT5066_HP_LAPTOP), + SND_PCI_QUIRK(0x1043, 0x13f3, "Asus A52J", CXT5066_HP_LAPTOP), SND_PCI_QUIRK(0x1179, 0xff1e, "Toshiba Satellite C650D", CXT5066_IDEAPAD), SND_PCI_QUIRK(0x1179, 0xff50, "Toshiba Satellite P500-PSPGSC-01800T", CXT5066_OLPC_XO_1_5), SND_PCI_QUIRK(0x1179, 0xffe0, "Toshiba Satellite Pro T130-15F", CXT5066_OLPC_XO_1_5), -- cgit v1.2.3 From ab69a4904b5dd4d7cd6996587ba066bca8d13838 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Mon, 15 Nov 2010 10:46:23 +0100 Subject: ALSA: pcm: support for period wakeup disabling This patch allows to disable period interrupts which are not needed when the application relies on a system timer to wake-up and refill the ring buffer. The behavior of the driver is left unchanged, and interrupts are only disabled if the application requests this configuration. The behavior in case of underruns is slightly different, instead of being detected during the period interrupts the underruns are detected when the application calls snd_pcm_update_avail, which in turns forces a refresh of the hw pointer and shows the buffer is empty. More specifically this patch makes a lot of sense when PulseAudio relies on timer-based scheduling to access audio devices such as HDAudio or Intel SST. Disabling interrupts removes two unwanted wake-ups due to period elapsed events in low-power playback modes. It also simplifies PulseAudio voice modules used for speech calls. To quote Lennart "This patch looks very interesting and desirable. This is something have long been waiting for." Support for this in hardware drivers is optional. Signed-off-by: Pierre-Louis Bossart Signed-off-by: Clemens Ladisch Signed-off-by: Takashi Iwai --- include/sound/asound.h | 3 +++ include/sound/pcm.h | 1 + sound/core/pcm_lib.c | 6 ++++++ sound/core/pcm_native.c | 3 +++ 4 files changed, 13 insertions(+) diff --git a/include/sound/asound.h b/include/sound/asound.h index a1803ecea34d..5d6074faa279 100644 --- a/include/sound/asound.h +++ b/include/sound/asound.h @@ -259,6 +259,7 @@ typedef int __bitwise snd_pcm_subformat_t; #define SNDRV_PCM_INFO_HALF_DUPLEX 0x00100000 /* only half duplex */ #define SNDRV_PCM_INFO_JOINT_DUPLEX 0x00200000 /* playback and capture stream are somewhat correlated */ #define SNDRV_PCM_INFO_SYNC_START 0x00400000 /* pcm support some kind of sync go */ +#define SNDRV_PCM_INFO_NO_PERIOD_WAKEUP 0x00800000 /* period wakeup can be disabled */ #define SNDRV_PCM_INFO_FIFO_IN_FRAMES 0x80000000 /* internal kernel flag - FIFO size is in frames */ typedef int __bitwise snd_pcm_state_t; @@ -334,6 +335,8 @@ typedef int snd_pcm_hw_param_t; #define SNDRV_PCM_HW_PARAM_LAST_INTERVAL SNDRV_PCM_HW_PARAM_TICK_TIME #define SNDRV_PCM_HW_PARAMS_NORESAMPLE (1<<0) /* avoid rate resampling */ +#define SNDRV_PCM_HW_PARAMS_EXPORT_BUFFER (1<<1) /* export buffer */ +#define SNDRV_PCM_HW_PARAMS_NO_PERIOD_WAKEUP (1<<2) /* disable period wakeups */ struct snd_interval { unsigned int min, max; diff --git a/include/sound/pcm.h b/include/sound/pcm.h index dfd9b76b1853..e731f8d71934 100644 --- a/include/sound/pcm.h +++ b/include/sound/pcm.h @@ -297,6 +297,7 @@ struct snd_pcm_runtime { unsigned int info; unsigned int rate_num; unsigned int rate_den; + unsigned int no_period_wakeup: 1; /* -- SW params -- */ int tstamp_mode; /* mmap timestamp is updated */ diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c index b75db8e9cc0f..bc57501c584a 100644 --- a/sound/core/pcm_lib.c +++ b/sound/core/pcm_lib.c @@ -373,6 +373,11 @@ static int snd_pcm_update_hw_ptr0(struct snd_pcm_substream *substream, (unsigned long)new_hw_ptr, (unsigned long)runtime->hw_ptr_base); } + + /* without period interrupts, there are no regular pointer updates */ + if (runtime->no_period_wakeup) + goto no_delta_check; + /* something must be really wrong */ if (delta >= runtime->buffer_size + runtime->period_size) { hw_ptr_error(substream, @@ -442,6 +447,7 @@ static int snd_pcm_update_hw_ptr0(struct snd_pcm_substream *substream, (long)old_hw_ptr); } + no_delta_check: if (runtime->status->hw_ptr == new_hw_ptr) return 0; diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c index 8bc7cb3db330..f91a439f675c 100644 --- a/sound/core/pcm_native.c +++ b/sound/core/pcm_native.c @@ -423,6 +423,9 @@ static int snd_pcm_hw_params(struct snd_pcm_substream *substream, runtime->info = params->info; runtime->rate_num = params->rate_num; runtime->rate_den = params->rate_den; + runtime->no_period_wakeup = + (params->info & SNDRV_PCM_INFO_NO_PERIOD_WAKEUP) && + (params->flags & SNDRV_PCM_HW_PARAMS_NO_PERIOD_WAKEUP); bits = snd_pcm_format_physical_width(runtime->format); runtime->sample_bits = bits; -- cgit v1.2.3 From 7bb8fb70c491bd6f5ec99728db8d1b5f43b95471 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Mon, 15 Nov 2010 10:49:47 +0100 Subject: ALSA: hda-intel: support for period wakeup disabling Allow disabling period wakeup interrupts for HDA PCM streams. Signed-off-by: Pierre-Louis Bossart Signed-off-by: Clemens Ladisch Signed-off-by: Takashi Iwai --- sound/pci/hda/hda_intel.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 21aa9b0e28f6..a78ea34863ee 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -1235,7 +1235,8 @@ static int azx_setup_periods(struct azx *chip, pos_adj = 0; } else { ofs = setup_bdle(substream, azx_dev, - &bdl, ofs, pos_adj, 1); + &bdl, ofs, pos_adj, + !substream->runtime->no_period_wakeup); if (ofs < 0) goto error; } @@ -1247,7 +1248,8 @@ static int azx_setup_periods(struct azx *chip, period_bytes - pos_adj, 0); else ofs = setup_bdle(substream, azx_dev, &bdl, ofs, - period_bytes, 1); + period_bytes, + !substream->runtime->no_period_wakeup); if (ofs < 0) goto error; } @@ -1515,7 +1517,8 @@ static struct snd_pcm_hardware azx_pcm_hw = { /* No full-resume yet implemented */ /* SNDRV_PCM_INFO_RESUME |*/ SNDRV_PCM_INFO_PAUSE | - SNDRV_PCM_INFO_SYNC_START), + SNDRV_PCM_INFO_SYNC_START | + SNDRV_PCM_INFO_NO_PERIOD_WAKEUP), .formats = SNDRV_PCM_FMTBIT_S16_LE, .rates = SNDRV_PCM_RATE_48000, .rate_min = 48000, -- cgit v1.2.3 From 075140ea8bf1405057c072a84ccf4e0d3f2c76f5 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Mon, 15 Nov 2010 10:50:37 +0100 Subject: ALSA: oxygen: support for period wakeup disabling Allow disabling period wakeup interrupts for all PCM streams. Signed-off-by: Clemens Ladisch Signed-off-by: Takashi Iwai --- sound/pci/oxygen/oxygen_pcm.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/sound/pci/oxygen/oxygen_pcm.c b/sound/pci/oxygen/oxygen_pcm.c index 814667442eb0..60e4aa00c042 100644 --- a/sound/pci/oxygen/oxygen_pcm.c +++ b/sound/pci/oxygen/oxygen_pcm.c @@ -39,7 +39,8 @@ static const struct snd_pcm_hardware oxygen_stereo_hardware = { SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_PAUSE | - SNDRV_PCM_INFO_SYNC_START, + SNDRV_PCM_INFO_SYNC_START | + SNDRV_PCM_INFO_NO_PERIOD_WAKEUP, .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE, .rates = SNDRV_PCM_RATE_32000 | @@ -65,7 +66,8 @@ static const struct snd_pcm_hardware oxygen_multichannel_hardware = { SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_PAUSE | - SNDRV_PCM_INFO_SYNC_START, + SNDRV_PCM_INFO_SYNC_START | + SNDRV_PCM_INFO_NO_PERIOD_WAKEUP, .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE, .rates = SNDRV_PCM_RATE_32000 | @@ -91,7 +93,8 @@ static const struct snd_pcm_hardware oxygen_ac97_hardware = { SNDRV_PCM_INFO_MMAP_VALID | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_PAUSE | - SNDRV_PCM_INFO_SYNC_START, + SNDRV_PCM_INFO_SYNC_START | + SNDRV_PCM_INFO_NO_PERIOD_WAKEUP, .formats = SNDRV_PCM_FMTBIT_S16_LE, .rates = SNDRV_PCM_RATE_48000, .rate_min = 48000, @@ -530,7 +533,10 @@ static int oxygen_prepare(struct snd_pcm_substream *substream) oxygen_set_bits8(chip, OXYGEN_DMA_FLUSH, channel_mask); oxygen_clear_bits8(chip, OXYGEN_DMA_FLUSH, channel_mask); - chip->interrupt_mask |= channel_mask; + if (substream->runtime->no_period_wakeup) + chip->interrupt_mask &= ~channel_mask; + else + chip->interrupt_mask |= channel_mask; oxygen_write16(chip, OXYGEN_INTERRUPT_MASK, chip->interrupt_mask); spin_unlock_irq(&chip->reg_lock); return 0; -- cgit v1.2.3 From 59ff878ffb26bc0be812ca8295799164f413ae88 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Thu, 18 Nov 2010 09:43:52 +0100 Subject: ALSA: pcm: detect xruns in no-period-wakeup mode When period wakeups are disabled, successive calls to the pointer update function do not have a maximum allowed distance, so xruns cannot be detected with the pointer value only. To detect xruns, compare the actually elapsed time with the time that should have theoretically elapsed since the last update. When the hardware pointer has wrapped around due to an xrun, the actually elapsed time will be too big by about hw_ptr_buffer_jiffies. Signed-off-by: Clemens Ladisch Signed-off-by: Takashi Iwai --- sound/core/pcm_lib.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c index bc57501c584a..e9debaabf376 100644 --- a/sound/core/pcm_lib.c +++ b/sound/core/pcm_lib.c @@ -374,9 +374,23 @@ static int snd_pcm_update_hw_ptr0(struct snd_pcm_substream *substream, (unsigned long)runtime->hw_ptr_base); } - /* without period interrupts, there are no regular pointer updates */ - if (runtime->no_period_wakeup) + if (runtime->no_period_wakeup) { + /* + * Without regular period interrupts, we have to check + * the elapsed time to detect xruns. + */ + jdelta = jiffies - runtime->hw_ptr_jiffies; + hdelta = jdelta - delta * HZ / runtime->rate; + while (hdelta > runtime->hw_ptr_buffer_jiffies / 2 + 1) { + delta += runtime->buffer_size; + hw_base += runtime->buffer_size; + if (hw_base >= runtime->boundary) + hw_base = 0; + new_hw_ptr = hw_base + pos; + hdelta -= runtime->hw_ptr_buffer_jiffies; + } goto no_delta_check; + } /* something must be really wrong */ if (delta >= runtime->buffer_size + runtime->period_size) { -- cgit v1.2.3 From 47228e48aecdbec423a1275a5e27697d47f1f912 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Thu, 18 Nov 2010 09:53:07 +0100 Subject: ALSA: pcm: optimize xrun detection in no-period-wakeup mode Add a lightweight condition on top of the xrun checking so that we can avoid the division when the application is calling the update function often enough. Suggested-by: Jaroslav Kysela Signed-off-by: Clemens Ladisch Signed-off-by: Takashi Iwai --- sound/core/pcm_lib.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c index e9debaabf376..fd18c3c6484f 100644 --- a/sound/core/pcm_lib.c +++ b/sound/core/pcm_lib.c @@ -380,6 +380,8 @@ static int snd_pcm_update_hw_ptr0(struct snd_pcm_substream *substream, * the elapsed time to detect xruns. */ jdelta = jiffies - runtime->hw_ptr_jiffies; + if (jdelta < runtime->hw_ptr_buffer_jiffies / 2) + goto no_delta_check; hdelta = jdelta - delta * HZ / runtime->rate; while (hdelta > runtime->hw_ptr_buffer_jiffies / 2 + 1) { delta += runtime->buffer_size; -- cgit v1.2.3 From 109fef9edcc100952eec980acbc2e1295627fbab Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Thu, 18 Nov 2010 09:53:54 +0100 Subject: ALSA: timer: automatically load the high-resolution timer Increase the default timer limit so that snd-hrtimer.ko can be automatically loaded when needed, e.g., when used as the default sequencer timer. This replaces the check for the obsolete CONFIG_SND_HPET. Signed-off-by: Clemens Ladisch Signed-off-by: Takashi Iwai --- sound/core/timer.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/core/timer.c b/sound/core/timer.c index 13afb60999b9..b3aaa600dcc2 100644 --- a/sound/core/timer.c +++ b/sound/core/timer.c @@ -34,8 +34,8 @@ #include #include -#if defined(CONFIG_SND_HPET) || defined(CONFIG_SND_HPET_MODULE) -#define DEFAULT_TIMER_LIMIT 3 +#if defined(CONFIG_SND_HRTIMER) || defined(CONFIG_SND_HRTIMER_MODULE) +#define DEFAULT_TIMER_LIMIT 4 #elif defined(CONFIG_SND_RTCTIMER) || defined(CONFIG_SND_RTCTIMER_MODULE) #define DEFAULT_TIMER_LIMIT 2 #else -- cgit v1.2.3 From c724e8a9407683a8a2ee8eb00b972badf237bbe1 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 22 Nov 2010 08:07:02 +0000 Subject: drm/i915: Capture pinned buffers on error The pinned buffers are useful for diagnosing errors in setting up state for the chipset, which may not necessarily be 'active' at the time of the error, e.g. the cursor buffer object. Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_debugfs.c | 63 +++++++++++++++++---------- drivers/gpu/drm/i915/i915_drv.h | 4 +- drivers/gpu/drm/i915/i915_irq.c | 87 ++++++++++++++++++++++++------------- 3 files changed, 98 insertions(+), 56 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 4c8fae9baaad..24a88ac63212 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -609,6 +609,36 @@ static const char *purgeable_flag(int purgeable) return purgeable ? " purgeable" : ""; } +static void print_error_buffers(struct seq_file *m, + const char *name, + struct drm_i915_error_buffer *err, + int count) +{ + seq_printf(m, "%s [%d]:\n", name, count); + + while (count--) { + seq_printf(m, " %08x %8zd %04x %04x %08x%s%s%s%s%s", + err->gtt_offset, + err->size, + err->read_domains, + err->write_domain, + err->seqno, + pin_flag(err->pinned), + tiling_flag(err->tiling), + dirty_flag(err->dirty), + purgeable_flag(err->purgeable), + ring_str(err->ring)); + + if (err->name) + seq_printf(m, " (name: %d)", err->name); + if (err->fence_reg != I915_FENCE_REG_NONE) + seq_printf(m, " (fence: %d)", err->fence_reg); + + seq_printf(m, "\n"); + err++; + } +} + static int i915_error_state(struct seq_file *m, void *unused) { struct drm_info_node *node = (struct drm_info_node *) m->private; @@ -658,30 +688,15 @@ static int i915_error_state(struct seq_file *m, void *unused) seq_printf(m, " INSTPM: 0x%08x\n", error->instpm); seq_printf(m, " seqno: 0x%08x\n", error->seqno); - if (error->active_bo_count) { - seq_printf(m, "Buffers [%d]:\n", error->active_bo_count); - - for (i = 0; i < error->active_bo_count; i++) { - seq_printf(m, " %08x %8zd %08x %08x %08x%s%s%s%s %s", - error->active_bo[i].gtt_offset, - error->active_bo[i].size, - error->active_bo[i].read_domains, - error->active_bo[i].write_domain, - error->active_bo[i].seqno, - pin_flag(error->active_bo[i].pinned), - tiling_flag(error->active_bo[i].tiling), - dirty_flag(error->active_bo[i].dirty), - purgeable_flag(error->active_bo[i].purgeable), - ring_str(error->active_bo[i].ring)); - - if (error->active_bo[i].name) - seq_printf(m, " (name: %d)", error->active_bo[i].name); - if (error->active_bo[i].fence_reg != I915_FENCE_REG_NONE) - seq_printf(m, " (fence: %d)", error->active_bo[i].fence_reg); - - seq_printf(m, "\n"); - } - } + if (error->active_bo) + print_error_buffers(m, "Active", + error->active_bo, + error->active_bo_count); + + if (error->pinned_bo) + print_error_buffers(m, "Pinned", + error->pinned_bo, + error->pinned_bo_count); for (i = 0; i < ARRAY_SIZE(error->batchbuffer); i++) { if (error->batchbuffer[i]) { diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 73a41f7ab8c6..826c7237409b 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -184,8 +184,8 @@ struct drm_i915_error_state { u32 dirty:1; u32 purgeable:1; u32 ring:4; - } *active_bo; - u32 active_bo_count; + } *active_bo, *pinned_bo; + u32 active_bo_count, pinned_bo_count; struct intel_overlay_error_state *overlay; }; diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index ef3503733ebb..bbcd5da89ba5 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -552,6 +552,40 @@ i915_ringbuffer_last_batch(struct drm_device *dev, return bbaddr; } +static u32 capture_bo_list(struct drm_i915_error_buffer *err, + int count, + struct list_head *head) +{ + struct drm_i915_gem_object *obj; + int i = 0; + + list_for_each_entry(obj, head, mm_list) { + err->size = obj->base.size; + err->name = obj->base.name; + err->seqno = obj->last_rendering_seqno; + err->gtt_offset = obj->gtt_offset; + err->read_domains = obj->base.read_domains; + err->write_domain = obj->base.write_domain; + err->fence_reg = obj->fence_reg; + err->pinned = 0; + if (obj->pin_count > 0) + err->pinned = 1; + if (obj->user_pin_count > 0) + err->pinned = -1; + err->tiling = obj->tiling_mode; + err->dirty = obj->dirty; + err->purgeable = obj->madv != I915_MADV_WILLNEED; + err->ring = obj->ring->id; + + if (++i == count) + break; + + err++; + } + + return i; +} + /** * i915_capture_error_state - capture an error record for later analysis * @dev: drm device @@ -700,42 +734,35 @@ static void i915_capture_error_state(struct drm_device *dev) error->ringbuffer = i915_error_object_create(dev, dev_priv->render_ring.gem_object); - /* Record buffers on the active list. */ + /* Record buffers on the active and pinned lists. */ error->active_bo = NULL; - error->active_bo_count = 0; + error->pinned_bo = NULL; - if (count) + error->active_bo_count = count; + list_for_each_entry(obj_priv, &dev_priv->mm.pinned_list, mm_list) + count++; + error->pinned_bo_count = count - error->active_bo_count; + + if (count) { error->active_bo = kmalloc(sizeof(*error->active_bo)*count, GFP_ATOMIC); - - if (error->active_bo) { - int i = 0; - list_for_each_entry(obj_priv, &dev_priv->mm.active_list, mm_list) { - struct drm_gem_object *obj = &obj_priv->base; - - error->active_bo[i].size = obj->size; - error->active_bo[i].name = obj->name; - error->active_bo[i].seqno = obj_priv->last_rendering_seqno; - error->active_bo[i].gtt_offset = obj_priv->gtt_offset; - error->active_bo[i].read_domains = obj->read_domains; - error->active_bo[i].write_domain = obj->write_domain; - error->active_bo[i].fence_reg = obj_priv->fence_reg; - error->active_bo[i].pinned = 0; - if (obj_priv->pin_count > 0) - error->active_bo[i].pinned = 1; - if (obj_priv->user_pin_count > 0) - error->active_bo[i].pinned = -1; - error->active_bo[i].tiling = obj_priv->tiling_mode; - error->active_bo[i].dirty = obj_priv->dirty; - error->active_bo[i].purgeable = obj_priv->madv != I915_MADV_WILLNEED; - error->active_bo[i].ring = obj_priv->ring->id; - - if (++i == count) - break; - } - error->active_bo_count = i; + if (error->active_bo) + error->pinned_bo = + error->active_bo + error->active_bo_count; } + if (error->active_bo) + error->active_bo_count = + capture_bo_list(error->active_bo, + error->active_bo_count, + &dev_priv->mm.active_list); + + if (error->pinned_bo) + error->pinned_bo_count = + capture_bo_list(error->pinned_bo, + error->pinned_bo_count, + &dev_priv->mm.pinned_list); + do_gettimeofday(&error->time); error->overlay = intel_overlay_capture_error_state(dev); -- cgit v1.2.3 From c4a1d9e4dc5d5313cfec2cc0c9d630efe8a6f287 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sun, 21 Nov 2010 13:12:35 +0000 Subject: drm/i915: Capture interesting display registers on error When trying to diagnose mysterious errors on resume, capture the display register contents as well. Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_debugfs.c | 3 + drivers/gpu/drm/i915/i915_drv.h | 8 +++ drivers/gpu/drm/i915/i915_irq.c | 1 + drivers/gpu/drm/i915/i915_reg.h | 6 +- drivers/gpu/drm/i915/intel_display.c | 110 +++++++++++++++++++++++++++++++++++ 5 files changed, 127 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 24a88ac63212..421b8414b577 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -729,6 +729,9 @@ static int i915_error_state(struct seq_file *m, void *unused) if (error->overlay) intel_overlay_print_error_state(m, error->overlay); + if (error->display) + intel_display_print_error_state(m, dev, error->display); + out: spin_unlock_irqrestore(&dev_priv->error_lock, flags); diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 826c7237409b..4c20ad92c0f3 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -140,6 +140,8 @@ struct sdvo_device_mapping { u8 ddc_pin; }; +struct intel_display_error_state; + struct drm_i915_error_state { u32 eir; u32 pgtbl_er; @@ -187,6 +189,7 @@ struct drm_i915_error_state { } *active_bo, *pinned_bo; u32 active_bo_count, pinned_bo_count; struct intel_overlay_error_state *overlay; + struct intel_display_error_state *display; }; struct drm_i915_display_funcs { @@ -1223,6 +1226,11 @@ extern int intel_trans_dp_port_sel (struct drm_crtc *crtc); #ifdef CONFIG_DEBUG_FS extern struct intel_overlay_error_state *intel_overlay_capture_error_state(struct drm_device *dev); extern void intel_overlay_print_error_state(struct seq_file *m, struct intel_overlay_error_state *error); + +extern struct intel_display_error_state *intel_display_capture_error_state(struct drm_device *dev); +extern void intel_display_print_error_state(struct seq_file *m, + struct drm_device *dev, + struct intel_display_error_state *error); #endif /** diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index bbcd5da89ba5..0b6052abedd1 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -766,6 +766,7 @@ static void i915_capture_error_state(struct drm_device *dev) do_gettimeofday(&error->time); error->overlay = intel_overlay_capture_error_state(dev); + error->display = intel_display_capture_error_state(dev); spin_lock_irqsave(&dev_priv->error_lock, flags); if (dev_priv->first_error == NULL) { diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 886c0e072490..ec2a8b07ba5b 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -1193,7 +1193,6 @@ #define VTOTAL(pipe) _PIPE(pipe, VTOTAL_A, VTOTAL_B) #define VBLANK(pipe) _PIPE(pipe, VBLANK_A, VBLANK_B) #define VSYNC(pipe) _PIPE(pipe, VSYNC_A, VSYNC_B) -#define PIPESRC(pipe) _PIPE(pipe, PIPEASRC, PIPEBSRC) #define BCLRPAT(pipe) _PIPE(pipe, BCLRPAT_A, BCLRPAT_B) /* VGA port control */ @@ -2207,6 +2206,7 @@ #define PIPE_6BPC (2 << 5) #define PIPE_12BPC (3 << 5) +#define PIPESRC(pipe) _PIPE(pipe, PIPEASRC, PIPEBSRC) #define PIPECONF(pipe) _PIPE(pipe, PIPEACONF, PIPEBCONF) #define PIPEDSL(pipe) _PIPE(pipe, PIPEADSL, PIPEBDSL) @@ -2376,6 +2376,10 @@ #define CURBBASE 0x700c4 #define CURBPOS 0x700c8 +#define CURCNTR(pipe) _PIPE(pipe, CURACNTR, CURBCNTR) +#define CURBASE(pipe) _PIPE(pipe, CURABASE, CURBBASE) +#define CURPOS(pipe) _PIPE(pipe, CURAPOS, CURBPOS) + /* Display A control */ #define DSPACNTR 0x70180 #define DISPLAY_PLANE_ENABLE (1<<31) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 3fa5aaa941d2..d4bc443f43fc 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -6269,3 +6269,113 @@ int intel_modeset_vga_set_state(struct drm_device *dev, bool state) pci_write_config_word(dev_priv->bridge_dev, INTEL_GMCH_CTRL, gmch_ctrl); return 0; } + +#ifdef CONFIG_DEBUG_FS +#include + +struct intel_display_error_state { + struct intel_cursor_error_state { + u32 control; + u32 position; + u32 base; + u32 size; + } cursor[2]; + + struct intel_pipe_error_state { + u32 conf; + u32 source; + + u32 htotal; + u32 hblank; + u32 hsync; + u32 vtotal; + u32 vblank; + u32 vsync; + } pipe[2]; + + struct intel_plane_error_state { + u32 control; + u32 stride; + u32 size; + u32 pos; + u32 addr; + u32 surface; + u32 tile_offset; + } plane[2]; +}; + +struct intel_display_error_state * +intel_display_capture_error_state(struct drm_device *dev) +{ + drm_i915_private_t *dev_priv = dev->dev_private; + struct intel_display_error_state *error; + int i; + + error = kmalloc(sizeof(*error), GFP_ATOMIC); + if (error == NULL) + return NULL; + + for (i = 0; i < 2; i++) { + error->cursor[i].control = I915_READ(CURCNTR(i)); + error->cursor[i].position = I915_READ(CURPOS(i)); + error->cursor[i].base = I915_READ(CURBASE(i)); + + error->plane[i].control = I915_READ(DSPCNTR(i)); + error->plane[i].stride = I915_READ(DSPSTRIDE(i)); + error->plane[i].size = I915_READ(DSPSIZE(i)); + error->plane[i].pos= I915_READ(DSPPOS(i)); + error->plane[i].addr = I915_READ(DSPADDR(i)); + if (INTEL_INFO(dev)->gen >= 4) { + error->plane[i].surface = I915_READ(DSPSURF(i)); + error->plane[i].tile_offset = I915_READ(DSPTILEOFF(i)); + } + + error->pipe[i].conf = I915_READ(PIPECONF(i)); + error->pipe[i].source = I915_READ(PIPESRC(i)); + error->pipe[i].htotal = I915_READ(HTOTAL(i)); + error->pipe[i].hblank = I915_READ(HBLANK(i)); + error->pipe[i].hsync = I915_READ(HSYNC(i)); + error->pipe[i].vtotal = I915_READ(VTOTAL(i)); + error->pipe[i].vblank = I915_READ(VBLANK(i)); + error->pipe[i].vsync = I915_READ(VSYNC(i)); + } + + return error; +} + +void +intel_display_print_error_state(struct seq_file *m, + struct drm_device *dev, + struct intel_display_error_state *error) +{ + int i; + + for (i = 0; i < 2; i++) { + seq_printf(m, "Pipe [%d]:\n", i); + seq_printf(m, " CONF: %08x\n", error->pipe[i].conf); + seq_printf(m, " SRC: %08x\n", error->pipe[i].source); + seq_printf(m, " HTOTAL: %08x\n", error->pipe[i].htotal); + seq_printf(m, " HBLANK: %08x\n", error->pipe[i].hblank); + seq_printf(m, " HSYNC: %08x\n", error->pipe[i].hsync); + seq_printf(m, " VTOTAL: %08x\n", error->pipe[i].vtotal); + seq_printf(m, " VBLANK: %08x\n", error->pipe[i].vblank); + seq_printf(m, " VSYNC: %08x\n", error->pipe[i].vsync); + + seq_printf(m, "Plane [%d]:\n", i); + seq_printf(m, " CNTR: %08x\n", error->plane[i].control); + seq_printf(m, " STRIDE: %08x\n", error->plane[i].stride); + seq_printf(m, " SIZE: %08x\n", error->plane[i].size); + seq_printf(m, " POS: %08x\n", error->plane[i].pos); + seq_printf(m, " ADDR: %08x\n", error->plane[i].addr); + if (INTEL_INFO(dev)->gen >= 4) { + seq_printf(m, " SURF: %08x\n", error->plane[i].surface); + seq_printf(m, " TILEOFF: %08x\n", error->plane[i].tile_offset); + } + + seq_printf(m, "Cursor [%d]:\n", i); + seq_printf(m, " CNTR: %08x\n", error->cursor[i].control); + seq_printf(m, " POS: %08x\n", error->cursor[i].position); + seq_printf(m, " BASE: %08x\n", error->cursor[i].base); + } +} +#endif -- cgit v1.2.3 From df9c2042858e85ab46731c13e708a5b0799db848 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 18 Nov 2010 09:31:12 +0800 Subject: drm/i915: Correct a comment about the use of the workqueue. It isn't used for the hangcheck, which does its work right from the timer trigger, but hangcheck can lead to error state recording, which is run off of the workqueue. Signed-off-by: Eric Anholt Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_dma.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 4cd04917868d..cf4e06a9417a 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -1962,7 +1962,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) * bo. * * It is also used for periodic low-priority events, such as - * idle-timers and hangcheck. + * idle-timers and recording error state. * * All tasks on the workqueue are expected to acquire the dev mutex * so there is no point in running more than one instance of the -- cgit v1.2.3 From 75a6898ffd20a13aba8d03f005eb4ab940134fcb Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 18 Nov 2010 09:31:13 +0800 Subject: drm/i915: Also reinit the BSD and BLT rings after a GPU reset. Signed-off-by: Eric Anholt Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_drv.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index f0e6bd06fc0e..99b574050fde 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -472,9 +472,14 @@ int i915_reset(struct drm_device *dev, u8 flags) */ if (drm_core_check_feature(dev, DRIVER_MODESET) || !dev_priv->mm.suspended) { - struct intel_ring_buffer *ring = &dev_priv->render_ring; dev_priv->mm.suspended = 0; - ring->init(ring); + + dev_priv->render_ring.init(&dev_priv->render_ring); + if (HAS_BSD(dev)) + dev_priv->bsd_ring.init(&dev_priv->bsd_ring); + if (HAS_BLT(dev)) + dev_priv->blt_ring.init(&dev_priv->blt_ring); + mutex_unlock(&dev->struct_mutex); drm_irq_uninstall(dev); drm_irq_install(dev); -- cgit v1.2.3 From cff458c21063de960bde0e39770a0f4cd0477d95 Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 18 Nov 2010 09:31:14 +0800 Subject: drm/i915: Add support for GPU reset on gen6. This has proven sufficient to recover from a hang of the GPU using the gem_bad_blit test while at the KMS console then starting X. When attempting the same during an X session, the timer doesn't appear to trigger. Signed-off-by: Eric Anholt Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_drv.c | 11 +++++++++++ drivers/gpu/drm/i915/i915_reg.h | 6 ++++++ 2 files changed, 17 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 99b574050fde..8c5541950b8d 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -405,6 +405,14 @@ static int ironlake_do_reset(struct drm_device *dev, u8 flags) return wait_for(I915_READ(MCHBAR_MIRROR_BASE + ILK_GDSR) & 0x1, 500); } +static int gen6_do_reset(struct drm_device *dev, u8 flags) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + + I915_WRITE(GEN6_GDRST, GEN6_GRDOM_FULL); + return wait_for((I915_READ(GEN6_GDRST) & GEN6_GRDOM_FULL) == 0, 500); +} + /** * i965_reset - reset chip after a hang * @dev: drm device to reset @@ -439,6 +447,9 @@ int i915_reset(struct drm_device *dev, u8 flags) if (get_seconds() - dev_priv->last_gpu_reset < 5) { DRM_ERROR("GPU hanging too fast, declaring wedged!\n"); } else switch (INTEL_INFO(dev)->gen) { + case 6: + ret = gen6_do_reset(dev, flags); + break; case 5: ret = ironlake_do_reset(dev, flags); break; diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index ec2a8b07ba5b..c668b2fb7e3d 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -78,6 +78,12 @@ #define GRDOM_RENDER (1<<2) #define GRDOM_MEDIA (3<<2) +#define GEN6_GDRST 0x941c +#define GEN6_GRDOM_FULL (1 << 0) +#define GEN6_GRDOM_RENDER (1 << 1) +#define GEN6_GRDOM_MEDIA (1 << 2) +#define GEN6_GRDOM_BLT (1 << 3) + /* VGA stuff */ #define VGA_ST01_MDA 0x3ba -- cgit v1.2.3 From 5f75377db4d8d81ca4465b54d3c339c70c6a0fa2 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 22 Nov 2010 09:24:22 +0000 Subject: drm/i915: Fix restore of 965 fence regs since the register tracing change. We were reading our 64-bit value in I915_READ64 and returning 32 bits of it. The restoration of fence regs at resume then had a zero end value, and the fence had no effect. Version 2: Split register access functions into per-size versions Sharing code between different sizes seemed reasonable when we only needed a single copy, but as 64-bit access requires its own version, it makes sense to just split them out for each size. Reported-by: Peter Clifton Signed-off-by: Eric Anholt Signed-off-by: Keith Packard [ickle: use a macro to create the various read/write routines] Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_drv.h | 68 ++++++++++++++++++++++------------------- 1 file changed, 36 insertions(+), 32 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 4c20ad92c0f3..db79df376b86 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1245,45 +1245,49 @@ extern void intel_display_print_error_state(struct seq_file *m, LOCK_TEST_WITH_RETURN(dev, file_priv); \ } while (0) -#define I915_READ(reg) i915_read(dev_priv, (reg), 4) -#define I915_WRITE(reg, val) i915_write(dev_priv, (reg), (val), 4) -#define I915_READ16(reg) i915_read(dev_priv, (reg), 2) -#define I915_WRITE16(reg, val) i915_write(dev_priv, (reg), (val), 2) -#define I915_READ8(reg) i915_read(dev_priv, (reg), 1) -#define I915_WRITE8(reg, val) i915_write(dev_priv, (reg), (val), 1) -#define I915_WRITE64(reg, val) i915_write(dev_priv, (reg), (val), 8) -#define I915_READ64(reg) i915_read(dev_priv, (reg), 8) +#define __i915_read(x, y) \ +static inline u##x i915_read##x(struct drm_i915_private *dev_priv, u32 reg) { \ + u##x val = read##y(dev_priv->regs + reg); \ + trace_i915_reg_rw('R', reg, val, sizeof(val)); \ + return val; \ +} +__i915_read(8, b) +__i915_read(16, w) +__i915_read(32, l) +__i915_read(64, q) +#undef __i915_read + +#define __i915_write(x, y) \ +static inline void i915_write##x(struct drm_i915_private *dev_priv, u32 reg, u##x val) { \ + trace_i915_reg_rw('W', reg, val, sizeof(val)); \ + write##y(val, dev_priv->regs + reg); \ +} +__i915_write(8, b) +__i915_write(16, w) +__i915_write(32, l) +__i915_write(64, q) +#undef __i915_write + +#define I915_READ8(reg) i915_read8(dev_priv, (reg)) +#define I915_WRITE8(reg, val) i915_write8(dev_priv, (reg), (val)) + +#define I915_READ16(reg) i915_read16(dev_priv, (reg)) +#define I915_WRITE16(reg, val) i915_write16(dev_priv, (reg), (val)) +#define I915_READ16_NOTRACE(reg) readw(dev_priv->regs + (reg)) +#define I915_WRITE16_NOTRACE(reg, val) writew(val, dev_priv->regs + (reg)) + +#define I915_READ(reg) i915_read32(dev_priv, (reg)) +#define I915_WRITE(reg, val) i915_write32(dev_priv, (reg), (val)) #define I915_READ_NOTRACE(reg) readl(dev_priv->regs + (reg)) #define I915_WRITE_NOTRACE(reg, val) writel(val, dev_priv->regs + (reg)) -#define I915_READ16_NOTRACE(reg) readw(dev_priv->regs + (reg)) -#define I915_WRITE16_NOTRACE(reg, val) writew(val, dev_priv->regs + (reg)) + +#define I915_WRITE64(reg, val) i915_write64(dev_priv, (reg), (val)) +#define I915_READ64(reg) i915_read64(dev_priv, (reg)) #define POSTING_READ(reg) (void)I915_READ_NOTRACE(reg) #define POSTING_READ16(reg) (void)I915_READ16_NOTRACE(reg) -static inline u32 i915_read(struct drm_i915_private *dev_priv, u32 reg, int len) -{ - u64 val = 0; - - switch (len) { - case 8: - val = readq(dev_priv->regs + reg); - break; - case 4: - val = readl(dev_priv->regs + reg); - break; - case 2: - val = readw(dev_priv->regs + reg); - break; - case 1: - val = readb(dev_priv->regs + reg); - break; - } - trace_i915_reg_rw('R', reg, val, len); - - return val; -} /* On SNB platform, before reading ring registers forcewake bit * must be set to prevent GT core from power down and stale values being -- cgit v1.2.3 From 9d57883f08d3c0c111b50bf185dfee9731a12c76 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 22 Nov 2010 13:29:19 +0100 Subject: ALSA: hda - Add a generic fixup callback for Realtek codecs Add a generic callback function for fixup elements. This can be used to do some unusual things like overriding the AMP cache, etc. Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 564e6c136ddd..f10c613c530f 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -1681,6 +1681,8 @@ struct alc_fixup { unsigned int sku; const struct alc_pincfg *pins; const struct hda_verb *verbs; + void (*func)(struct hda_codec *codec, const struct alc_fixup *fix, + int pre_init); }; static void alc_pick_fixup(struct hda_codec *codec, @@ -1720,6 +1722,13 @@ static void alc_pick_fixup(struct hda_codec *codec, #endif add_verb(codec->spec, fix->verbs); } + if (fix->func) { +#ifdef CONFIG_SND_DEBUG_VERBOSE + snd_printdd(KERN_INFO "hda_codec: %s: Apply fix-func for %s\n", + codec->chip_name, quirk->name); +#endif + fix->func(codec, fix, pre_init); + } } static int alc_read_coef_idx(struct hda_codec *codec, -- cgit v1.2.3 From 1c8f2c4287bcc1eb596149b2b36be5c809598926 Mon Sep 17 00:00:00 2001 From: Jarkko Nikula Date: Sun, 21 Nov 2010 19:48:44 +0200 Subject: ASoC: Fix compile breakage in jz4740.c and smartq_wm8987.c Commit ce6120c require that soc-dapm.h cannot be included before soc.h but these two drivers were not checked. Fix them by including only soc.h as it includes soc-dapm.h. Signed-off-by: Jarkko Nikula Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/codecs/jz4740.c | 1 - sound/soc/s3c24xx/smartq_wm8987.c | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/sound/soc/codecs/jz4740.c b/sound/soc/codecs/jz4740.c index 8a45562a96d4..f7cd346fd727 100644 --- a/sound/soc/codecs/jz4740.c +++ b/sound/soc/codecs/jz4740.c @@ -22,7 +22,6 @@ #include #include #include -#include #include #define JZ4740_REG_CODEC_1 0x0 diff --git a/sound/soc/s3c24xx/smartq_wm8987.c b/sound/soc/s3c24xx/smartq_wm8987.c index 1f6da1e27b1e..5b07bb9802ee 100644 --- a/sound/soc/s3c24xx/smartq_wm8987.c +++ b/sound/soc/s3c24xx/smartq_wm8987.c @@ -19,7 +19,7 @@ #include #include -#include +#include #include #include -- cgit v1.2.3 From 505fb824e754efcc9702ce68d3911e7b86d3c690 Mon Sep 17 00:00:00 2001 From: Jarkko Nikula Date: Sun, 21 Nov 2010 19:48:45 +0200 Subject: ASoC: Do not include soc-dapm.h There is no need to include soc-dapm.h since soc.h includes it. Signed-off-by: Jarkko Nikula Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/atmel/playpaq_wm8510.c | 1 - sound/soc/atmel/sam9g20_wm8731.c | 1 - sound/soc/atmel/snd-soc-afeb9260.c | 1 - sound/soc/au1x/db1200.c | 1 - sound/soc/blackfin/bf5xx-ad1836.c | 1 - sound/soc/blackfin/bf5xx-ad193x.c | 1 - sound/soc/blackfin/bf5xx-ad73311.c | 1 - sound/soc/blackfin/bf5xx-ssm2602.c | 1 - sound/soc/codecs/88pm860x-codec.c | 1 - sound/soc/codecs/ad1836.c | 1 - sound/soc/codecs/ad193x.c | 1 - sound/soc/codecs/ad1980.c | 1 - sound/soc/codecs/ak4535.c | 1 - sound/soc/codecs/ak4671.c | 1 - sound/soc/codecs/alc5623.c | 1 - sound/soc/codecs/cq93vc.c | 1 - sound/soc/codecs/cs42l51.c | 1 - sound/soc/codecs/max98088.c | 1 - sound/soc/codecs/ssm2602.c | 1 - sound/soc/codecs/stac9766.c | 1 - sound/soc/codecs/tlv320aic23.c | 1 - sound/soc/codecs/tlv320aic26.c | 1 - sound/soc/codecs/tlv320aic3x.c | 1 - sound/soc/codecs/tlv320dac33.c | 1 - sound/soc/codecs/tpa6130a2.c | 1 - sound/soc/codecs/twl4030.c | 1 - sound/soc/codecs/twl6040.c | 1 - sound/soc/codecs/uda134x.c | 1 - sound/soc/codecs/uda1380.c | 1 - sound/soc/codecs/wl1273.c | 1 - sound/soc/codecs/wm2000.c | 1 - sound/soc/codecs/wm8350.c | 1 - sound/soc/codecs/wm8400.c | 1 - sound/soc/codecs/wm8510.c | 1 - sound/soc/codecs/wm8523.c | 1 - sound/soc/codecs/wm8580.c | 1 - sound/soc/codecs/wm8711.c | 1 - sound/soc/codecs/wm8728.c | 1 - sound/soc/codecs/wm8731.c | 1 - sound/soc/codecs/wm8741.c | 1 - sound/soc/codecs/wm8750.c | 1 - sound/soc/codecs/wm8753.c | 1 - sound/soc/codecs/wm8770.c | 1 - sound/soc/codecs/wm8776.c | 1 - sound/soc/codecs/wm8804.c | 1 - sound/soc/codecs/wm8900.c | 1 - sound/soc/codecs/wm8903.c | 1 - sound/soc/codecs/wm8904.c | 1 - sound/soc/codecs/wm8940.c | 1 - sound/soc/codecs/wm8955.c | 1 - sound/soc/codecs/wm8960.c | 1 - sound/soc/codecs/wm8961.c | 1 - sound/soc/codecs/wm8962.c | 1 - sound/soc/codecs/wm8971.c | 1 - sound/soc/codecs/wm8974.c | 1 - sound/soc/codecs/wm8978.c | 1 - sound/soc/codecs/wm8985.c | 1 - sound/soc/codecs/wm8988.c | 1 - sound/soc/codecs/wm8990.c | 1 - sound/soc/codecs/wm8993.c | 1 - sound/soc/codecs/wm8994.c | 1 - sound/soc/codecs/wm9081.c | 1 - sound/soc/codecs/wm9090.c | 1 - sound/soc/codecs/wm9705.c | 1 - sound/soc/codecs/wm9712.c | 1 - sound/soc/codecs/wm9713.c | 1 - sound/soc/codecs/wm_hubs.c | 1 - sound/soc/davinci/davinci-evm.c | 1 - sound/soc/davinci/davinci-sffsdr.c | 1 - sound/soc/ep93xx/snappercl15.c | 1 - sound/soc/imx/eukrea-tlv320.c | 1 - sound/soc/imx/phycore-ac97.c | 1 - sound/soc/imx/wm1133-ev1.c | 1 - sound/soc/jz4740/jz4740-i2s.c | 1 - sound/soc/jz4740/qi_lb60.c | 1 - sound/soc/kirkwood/kirkwood-t5325.c | 1 - sound/soc/nuc900/nuc900-audio.c | 1 - sound/soc/omap/am3517evm.c | 1 - sound/soc/omap/igep0020.c | 1 - sound/soc/omap/n810.c | 1 - sound/soc/omap/omap2evm.c | 1 - sound/soc/omap/omap3beagle.c | 1 - sound/soc/omap/omap3evm.c | 1 - sound/soc/omap/omap3pandora.c | 1 - sound/soc/omap/osk5912.c | 1 - sound/soc/omap/overo.c | 1 - sound/soc/omap/rx51.c | 1 - sound/soc/omap/sdp3430.c | 1 - sound/soc/omap/sdp4430.c | 1 - sound/soc/omap/zoom2.c | 1 - sound/soc/pxa/corgi.c | 1 - sound/soc/pxa/e740_wm9705.c | 1 - sound/soc/pxa/e750_wm9705.c | 1 - sound/soc/pxa/e800_wm9712.c | 1 - sound/soc/pxa/em-x270.c | 1 - sound/soc/pxa/magician.c | 1 - sound/soc/pxa/mioa701_wm9713.c | 1 - sound/soc/pxa/palm27x.c | 1 - sound/soc/pxa/poodle.c | 1 - sound/soc/pxa/raumfeld.c | 1 - sound/soc/pxa/saarb.c | 1 - sound/soc/pxa/spitz.c | 1 - sound/soc/pxa/tavorevb3.c | 1 - sound/soc/pxa/tosa.c | 1 - sound/soc/pxa/z2.c | 1 - sound/soc/pxa/zylonite.c | 1 - sound/soc/s3c24xx/aquila_wm8994.c | 1 - sound/soc/s3c24xx/goni_wm8994.c | 1 - sound/soc/s3c24xx/jive_wm8750.c | 1 - sound/soc/s3c24xx/ln2440sbc_alc650.c | 1 - sound/soc/s3c24xx/neo1973_gta02_wm8753.c | 1 - sound/soc/s3c24xx/neo1973_wm8753.c | 1 - sound/soc/s3c24xx/rx1950_uda1380.c | 1 - sound/soc/s3c24xx/s3c24xx_simtec.c | 1 - sound/soc/s3c24xx/s3c24xx_simtec_hermes.c | 1 - sound/soc/s3c24xx/s3c24xx_simtec_tlv320aic23.c | 1 - sound/soc/s3c24xx/s3c24xx_uda134x.c | 1 - sound/soc/s3c24xx/smdk2443_wm9710.c | 1 - sound/soc/s3c24xx/smdk64xx_wm8580.c | 1 - sound/soc/s6000/s6105-ipcam.c | 1 - sound/soc/sh/migor.c | 1 - sound/soc/sh/sh7760-ac97.c | 1 - sound/soc/soc-core.c | 1 - sound/soc/soc-dapm.c | 1 - sound/soc/soc-jack.c | 1 - 125 files changed, 125 deletions(-) diff --git a/sound/soc/atmel/playpaq_wm8510.c b/sound/soc/atmel/playpaq_wm8510.c index aede7e74ec34..1aac2f4dbcf6 100644 --- a/sound/soc/atmel/playpaq_wm8510.c +++ b/sound/soc/atmel/playpaq_wm8510.c @@ -33,7 +33,6 @@ #include #include #include -#include #include #include diff --git a/sound/soc/atmel/sam9g20_wm8731.c b/sound/soc/atmel/sam9g20_wm8731.c index da9c3037496f..da3796190b2a 100644 --- a/sound/soc/atmel/sam9g20_wm8731.c +++ b/sound/soc/atmel/sam9g20_wm8731.c @@ -44,7 +44,6 @@ #include #include #include -#include #include #include diff --git a/sound/soc/atmel/snd-soc-afeb9260.c b/sound/soc/atmel/snd-soc-afeb9260.c index 92c709ed0965..1202f5e4894a 100644 --- a/sound/soc/atmel/snd-soc-afeb9260.c +++ b/sound/soc/atmel/snd-soc-afeb9260.c @@ -30,7 +30,6 @@ #include #include #include -#include #include #include diff --git a/sound/soc/au1x/db1200.c b/sound/soc/au1x/db1200.c index b62fcd33e586..cb99f04abe88 100644 --- a/sound/soc/au1x/db1200.c +++ b/sound/soc/au1x/db1200.c @@ -13,7 +13,6 @@ #include #include #include -#include #include #include #include diff --git a/sound/soc/blackfin/bf5xx-ad1836.c b/sound/soc/blackfin/bf5xx-ad1836.c index 2394bff2b655..83012da9dfc2 100644 --- a/sound/soc/blackfin/bf5xx-ad1836.c +++ b/sound/soc/blackfin/bf5xx-ad1836.c @@ -20,7 +20,6 @@ #include #include #include -#include #include #include diff --git a/sound/soc/blackfin/bf5xx-ad193x.c b/sound/soc/blackfin/bf5xx-ad193x.c index e4a625317a1a..d3ccb926b5e4 100644 --- a/sound/soc/blackfin/bf5xx-ad193x.c +++ b/sound/soc/blackfin/bf5xx-ad193x.c @@ -29,7 +29,6 @@ #include #include #include -#include #include #include diff --git a/sound/soc/blackfin/bf5xx-ad73311.c b/sound/soc/blackfin/bf5xx-ad73311.c index 900ced54ac79..732fb8bad076 100644 --- a/sound/soc/blackfin/bf5xx-ad73311.c +++ b/sound/soc/blackfin/bf5xx-ad73311.c @@ -35,7 +35,6 @@ #include #include #include -#include #include #include diff --git a/sound/soc/blackfin/bf5xx-ssm2602.c b/sound/soc/blackfin/bf5xx-ssm2602.c index 36f2769eb912..e902b24c1856 100644 --- a/sound/soc/blackfin/bf5xx-ssm2602.c +++ b/sound/soc/blackfin/bf5xx-ssm2602.c @@ -33,7 +33,6 @@ #include #include #include -#include #include #include diff --git a/sound/soc/codecs/88pm860x-codec.c b/sound/soc/codecs/88pm860x-codec.c index a15a3e974f0d..7e4d88007d4f 100644 --- a/sound/soc/codecs/88pm860x-codec.c +++ b/sound/soc/codecs/88pm860x-codec.c @@ -19,7 +19,6 @@ #include #include #include -#include #include #include #include diff --git a/sound/soc/codecs/ad1836.c b/sound/soc/codecs/ad1836.c index e5d3db950a08..ab63d52e36e1 100644 --- a/sound/soc/codecs/ad1836.c +++ b/sound/soc/codecs/ad1836.c @@ -27,7 +27,6 @@ #include #include #include -#include #include #include "ad1836.h" diff --git a/sound/soc/codecs/ad193x.c b/sound/soc/codecs/ad193x.c index fd3e659f90b1..a007bd7326fd 100644 --- a/sound/soc/codecs/ad193x.c +++ b/sound/soc/codecs/ad193x.c @@ -19,7 +19,6 @@ #include #include #include -#include #include "ad193x.h" /* codec private data */ diff --git a/sound/soc/codecs/ad1980.c b/sound/soc/codecs/ad1980.c index 410ccd5d41cd..34cb51ef2156 100644 --- a/sound/soc/codecs/ad1980.c +++ b/sound/soc/codecs/ad1980.c @@ -29,7 +29,6 @@ #include #include #include -#include #include "ad1980.h" diff --git a/sound/soc/codecs/ak4535.c b/sound/soc/codecs/ak4535.c index 52abb93a7dce..73675458076d 100644 --- a/sound/soc/codecs/ak4535.c +++ b/sound/soc/codecs/ak4535.c @@ -24,7 +24,6 @@ #include #include #include -#include #include #include "ak4535.h" diff --git a/sound/soc/codecs/ak4671.c b/sound/soc/codecs/ak4671.c index 1d6573c38af4..4faf10553a30 100644 --- a/sound/soc/codecs/ak4671.c +++ b/sound/soc/codecs/ak4671.c @@ -17,7 +17,6 @@ #include #include #include -#include #include #include diff --git a/sound/soc/codecs/alc5623.c b/sound/soc/codecs/alc5623.c index 5a45067b43ba..e84b26b0ce9e 100644 --- a/sound/soc/codecs/alc5623.c +++ b/sound/soc/codecs/alc5623.c @@ -28,7 +28,6 @@ #include #include #include -#include #include #include diff --git a/sound/soc/codecs/cq93vc.c b/sound/soc/codecs/cq93vc.c index 98b9e5294cbe..1a6f511051b6 100644 --- a/sound/soc/codecs/cq93vc.c +++ b/sound/soc/codecs/cq93vc.c @@ -37,7 +37,6 @@ #include #include #include -#include #include #include diff --git a/sound/soc/codecs/cs42l51.c b/sound/soc/codecs/cs42l51.c index a7fdca36b490..d4e60dc45bf6 100644 --- a/sound/soc/codecs/cs42l51.c +++ b/sound/soc/codecs/cs42l51.c @@ -26,7 +26,6 @@ #include #include #include -#include #include #include #include diff --git a/sound/soc/codecs/max98088.c b/sound/soc/codecs/max98088.c index 9c322373d5de..c44b5f70b5e0 100644 --- a/sound/soc/codecs/max98088.c +++ b/sound/soc/codecs/max98088.c @@ -20,7 +20,6 @@ #include #include #include -#include #include #include #include diff --git a/sound/soc/codecs/ssm2602.c b/sound/soc/codecs/ssm2602.c index adbc3e8dafc8..2727befd158e 100644 --- a/sound/soc/codecs/ssm2602.c +++ b/sound/soc/codecs/ssm2602.c @@ -38,7 +38,6 @@ #include #include #include -#include #include #include "ssm2602.h" diff --git a/sound/soc/codecs/stac9766.c b/sound/soc/codecs/stac9766.c index 8aad3a2c4f3d..7f2773038242 100644 --- a/sound/soc/codecs/stac9766.c +++ b/sound/soc/codecs/stac9766.c @@ -24,7 +24,6 @@ #include #include #include -#include #include #include "stac9766.h" diff --git a/sound/soc/codecs/tlv320aic23.c b/sound/soc/codecs/tlv320aic23.c index d9d8e844d63f..54a30ef0ec8b 100644 --- a/sound/soc/codecs/tlv320aic23.c +++ b/sound/soc/codecs/tlv320aic23.c @@ -30,7 +30,6 @@ #include #include #include -#include #include #include diff --git a/sound/soc/codecs/tlv320aic26.c b/sound/soc/codecs/tlv320aic26.c index 6b7d71ec0004..68f0ae47f608 100644 --- a/sound/soc/codecs/tlv320aic26.c +++ b/sound/soc/codecs/tlv320aic26.c @@ -18,7 +18,6 @@ #include #include #include -#include #include #include "tlv320aic26.h" diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c index df726a5066e8..49b797ccc8d6 100644 --- a/sound/soc/codecs/tlv320aic3x.c +++ b/sound/soc/codecs/tlv320aic3x.c @@ -46,7 +46,6 @@ #include #include #include -#include #include #include #include diff --git a/sound/soc/codecs/tlv320dac33.c b/sound/soc/codecs/tlv320dac33.c index 7149c14b289e..ccb267f4e968 100644 --- a/sound/soc/codecs/tlv320dac33.c +++ b/sound/soc/codecs/tlv320dac33.c @@ -36,7 +36,6 @@ #include #include #include -#include #include #include diff --git a/sound/soc/codecs/tpa6130a2.c b/sound/soc/codecs/tpa6130a2.c index f9a92ea6b50a..bfef3da95f58 100644 --- a/sound/soc/codecs/tpa6130a2.c +++ b/sound/soc/codecs/tpa6130a2.c @@ -29,7 +29,6 @@ #include #include #include -#include #include #include "tpa6130a2.h" diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c index f4602e8b67cc..0488d5514cd8 100644 --- a/sound/soc/codecs/twl4030.c +++ b/sound/soc/codecs/twl4030.c @@ -32,7 +32,6 @@ #include #include #include -#include #include #include diff --git a/sound/soc/codecs/twl6040.c b/sound/soc/codecs/twl6040.c index 0dd2d5397264..b92f2b737e4c 100644 --- a/sound/soc/codecs/twl6040.c +++ b/sound/soc/codecs/twl6040.c @@ -34,7 +34,6 @@ #include #include #include -#include #include #include diff --git a/sound/soc/codecs/uda134x.c b/sound/soc/codecs/uda134x.c index 6b6c0d291abf..e76847a9438b 100644 --- a/sound/soc/codecs/uda134x.c +++ b/sound/soc/codecs/uda134x.c @@ -19,7 +19,6 @@ #include #include #include -#include #include #include diff --git a/sound/soc/codecs/uda1380.c b/sound/soc/codecs/uda1380.c index cd6dd19fa1aa..800980e2e9ab 100644 --- a/sound/soc/codecs/uda1380.c +++ b/sound/soc/codecs/uda1380.c @@ -27,7 +27,6 @@ #include #include #include -#include #include #include diff --git a/sound/soc/codecs/wl1273.c b/sound/soc/codecs/wl1273.c index 0c47c788ccdf..c606b3e235fa 100644 --- a/sound/soc/codecs/wl1273.c +++ b/sound/soc/codecs/wl1273.c @@ -26,7 +26,6 @@ #include #include #include -#include #include #include "wl1273.h" diff --git a/sound/soc/codecs/wm2000.c b/sound/soc/codecs/wm2000.c index 9277d8d7474e..80ddf4fd23db 100644 --- a/sound/soc/codecs/wm2000.c +++ b/sound/soc/codecs/wm2000.c @@ -36,7 +36,6 @@ #include #include #include -#include #include #include diff --git a/sound/soc/codecs/wm8350.c b/sound/soc/codecs/wm8350.c index d5e6e02ff350..dc6912e9b667 100644 --- a/sound/soc/codecs/wm8350.c +++ b/sound/soc/codecs/wm8350.c @@ -24,7 +24,6 @@ #include #include #include -#include #include #include diff --git a/sound/soc/codecs/wm8400.c b/sound/soc/codecs/wm8400.c index 96927a457a34..3c3bc079167e 100644 --- a/sound/soc/codecs/wm8400.c +++ b/sound/soc/codecs/wm8400.c @@ -26,7 +26,6 @@ #include #include #include -#include #include #include diff --git a/sound/soc/codecs/wm8510.c b/sound/soc/codecs/wm8510.c index 6b3833c7bdf3..db0dced74843 100644 --- a/sound/soc/codecs/wm8510.c +++ b/sound/soc/codecs/wm8510.c @@ -24,7 +24,6 @@ #include #include #include -#include #include #include "wm8510.h" diff --git a/sound/soc/codecs/wm8523.c b/sound/soc/codecs/wm8523.c index d3318886f43e..1bda09baa851 100644 --- a/sound/soc/codecs/wm8523.c +++ b/sound/soc/codecs/wm8523.c @@ -24,7 +24,6 @@ #include #include #include -#include #include #include diff --git a/sound/soc/codecs/wm8580.c b/sound/soc/codecs/wm8580.c index 36c035bf4e42..e2a927684b48 100644 --- a/sound/soc/codecs/wm8580.c +++ b/sound/soc/codecs/wm8580.c @@ -31,7 +31,6 @@ #include #include #include -#include #include #include #include diff --git a/sound/soc/codecs/wm8711.c b/sound/soc/codecs/wm8711.c index ea2daf4da57c..fec37ebfdb34 100644 --- a/sound/soc/codecs/wm8711.c +++ b/sound/soc/codecs/wm8711.c @@ -25,7 +25,6 @@ #include #include #include -#include #include #include diff --git a/sound/soc/codecs/wm8728.c b/sound/soc/codecs/wm8728.c index 23939976c3cc..736b0352d0a7 100644 --- a/sound/soc/codecs/wm8728.c +++ b/sound/soc/codecs/wm8728.c @@ -23,7 +23,6 @@ #include #include #include -#include #include #include diff --git a/sound/soc/codecs/wm8731.c b/sound/soc/codecs/wm8731.c index 4b709589e26c..a1041450d9bb 100644 --- a/sound/soc/codecs/wm8731.c +++ b/sound/soc/codecs/wm8731.c @@ -26,7 +26,6 @@ #include #include #include -#include #include #include diff --git a/sound/soc/codecs/wm8741.c b/sound/soc/codecs/wm8741.c index 2543a26513fb..35789b7dcacf 100644 --- a/sound/soc/codecs/wm8741.c +++ b/sound/soc/codecs/wm8741.c @@ -24,7 +24,6 @@ #include #include #include -#include #include #include diff --git a/sound/soc/codecs/wm8750.c b/sound/soc/codecs/wm8750.c index 178b967af73f..51280e96d721 100644 --- a/sound/soc/codecs/wm8750.c +++ b/sound/soc/codecs/wm8750.c @@ -25,7 +25,6 @@ #include #include #include -#include #include #include "wm8750.h" diff --git a/sound/soc/codecs/wm8753.c b/sound/soc/codecs/wm8753.c index 26096b47a493..57bf9468d39a 100644 --- a/sound/soc/codecs/wm8753.c +++ b/sound/soc/codecs/wm8753.c @@ -45,7 +45,6 @@ #include #include #include -#include #include #include #include diff --git a/sound/soc/codecs/wm8770.c b/sound/soc/codecs/wm8770.c index 8608b4a10b0a..19b92baa9e8c 100644 --- a/sound/soc/codecs/wm8770.c +++ b/sound/soc/codecs/wm8770.c @@ -23,7 +23,6 @@ #include #include #include -#include #include #include diff --git a/sound/soc/codecs/wm8776.c b/sound/soc/codecs/wm8776.c index e09ed65e0868..8e7953b1b790 100644 --- a/sound/soc/codecs/wm8776.c +++ b/sound/soc/codecs/wm8776.c @@ -25,7 +25,6 @@ #include #include #include -#include #include #include diff --git a/sound/soc/codecs/wm8804.c b/sound/soc/codecs/wm8804.c index 031a0d421108..6dae1b40c9f7 100644 --- a/sound/soc/codecs/wm8804.c +++ b/sound/soc/codecs/wm8804.c @@ -23,7 +23,6 @@ #include #include #include -#include #include #include diff --git a/sound/soc/codecs/wm8900.c b/sound/soc/codecs/wm8900.c index 06ea9c0f863b..cfbaac1a0ead 100644 --- a/sound/soc/codecs/wm8900.c +++ b/sound/soc/codecs/wm8900.c @@ -30,7 +30,6 @@ #include #include #include -#include #include #include diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c index 4a6df4b69a04..620793e51666 100644 --- a/sound/soc/codecs/wm8903.c +++ b/sound/soc/codecs/wm8903.c @@ -29,7 +29,6 @@ #include #include #include -#include #include #include diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c index 5e57bd2483e8..da9192890187 100644 --- a/sound/soc/codecs/wm8904.c +++ b/sound/soc/codecs/wm8904.c @@ -24,7 +24,6 @@ #include #include #include -#include #include #include #include diff --git a/sound/soc/codecs/wm8940.c b/sound/soc/codecs/wm8940.c index caed0849e005..381934fff4ec 100644 --- a/sound/soc/codecs/wm8940.c +++ b/sound/soc/codecs/wm8940.c @@ -35,7 +35,6 @@ #include #include #include -#include #include #include diff --git a/sound/soc/codecs/wm8955.c b/sound/soc/codecs/wm8955.c index df1940fdbf69..6200beb082b2 100644 --- a/sound/soc/codecs/wm8955.c +++ b/sound/soc/codecs/wm8955.c @@ -23,7 +23,6 @@ #include #include #include -#include #include #include #include diff --git a/sound/soc/codecs/wm8960.c b/sound/soc/codecs/wm8960.c index 0ea578815003..0bcf36ee29bc 100644 --- a/sound/soc/codecs/wm8960.c +++ b/sound/soc/codecs/wm8960.c @@ -20,7 +20,6 @@ #include #include #include -#include #include #include #include diff --git a/sound/soc/codecs/wm8961.c b/sound/soc/codecs/wm8961.c index 79b650945bb2..a0bb972420b3 100644 --- a/sound/soc/codecs/wm8961.c +++ b/sound/soc/codecs/wm8961.c @@ -23,7 +23,6 @@ #include #include #include -#include #include #include diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c index 9f6beca951c4..cf4b2722648a 100644 --- a/sound/soc/codecs/wm8962.c +++ b/sound/soc/codecs/wm8962.c @@ -29,7 +29,6 @@ #include #include #include -#include #include #include #include diff --git a/sound/soc/codecs/wm8971.c b/sound/soc/codecs/wm8971.c index 84b2dcb18aea..8805636bda53 100644 --- a/sound/soc/codecs/wm8971.c +++ b/sound/soc/codecs/wm8971.c @@ -25,7 +25,6 @@ #include #include #include -#include #include #include "wm8971.h" diff --git a/sound/soc/codecs/wm8974.c b/sound/soc/codecs/wm8974.c index d19bb14842d4..5d286427532a 100644 --- a/sound/soc/codecs/wm8974.c +++ b/sound/soc/codecs/wm8974.c @@ -23,7 +23,6 @@ #include #include #include -#include #include #include diff --git a/sound/soc/codecs/wm8978.c b/sound/soc/codecs/wm8978.c index ac43b6088e2e..a195af92b425 100644 --- a/sound/soc/codecs/wm8978.c +++ b/sound/soc/codecs/wm8978.c @@ -24,7 +24,6 @@ #include #include #include -#include #include #include #include diff --git a/sound/soc/codecs/wm8985.c b/sound/soc/codecs/wm8985.c index c3c8fd23d503..bae510acdec8 100644 --- a/sound/soc/codecs/wm8985.c +++ b/sound/soc/codecs/wm8985.c @@ -26,7 +26,6 @@ #include #include #include -#include #include #include diff --git a/sound/soc/codecs/wm8988.c b/sound/soc/codecs/wm8988.c index 0bc2eb530c7a..65807b15a2cc 100644 --- a/sound/soc/codecs/wm8988.c +++ b/sound/soc/codecs/wm8988.c @@ -25,7 +25,6 @@ #include #include #include -#include #include #include "wm8988.h" diff --git a/sound/soc/codecs/wm8990.c b/sound/soc/codecs/wm8990.c index 309664ea7dc3..5c87a634fc04 100644 --- a/sound/soc/codecs/wm8990.c +++ b/sound/soc/codecs/wm8990.c @@ -23,7 +23,6 @@ #include #include #include -#include #include #include #include diff --git a/sound/soc/codecs/wm8993.c b/sound/soc/codecs/wm8993.c index 991d90c79dd2..77b1d441c3d0 100644 --- a/sound/soc/codecs/wm8993.c +++ b/sound/soc/codecs/wm8993.c @@ -24,7 +24,6 @@ #include #include #include -#include #include #include diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index 189f00079d31..435508fd6137 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c @@ -24,7 +24,6 @@ #include #include #include -#include #include #include diff --git a/sound/soc/codecs/wm9081.c b/sound/soc/codecs/wm9081.c index c03e2c3e24e1..c7060775e88b 100644 --- a/sound/soc/codecs/wm9081.c +++ b/sound/soc/codecs/wm9081.c @@ -23,7 +23,6 @@ #include #include #include -#include #include #include diff --git a/sound/soc/codecs/wm9090.c b/sound/soc/codecs/wm9090.c index b5afa01aa383..7ba5807cac36 100644 --- a/sound/soc/codecs/wm9090.c +++ b/sound/soc/codecs/wm9090.c @@ -28,7 +28,6 @@ #include #include #include -#include #include #include diff --git a/sound/soc/codecs/wm9705.c b/sound/soc/codecs/wm9705.c index 58d120824498..47b357adabdd 100644 --- a/sound/soc/codecs/wm9705.c +++ b/sound/soc/codecs/wm9705.c @@ -19,7 +19,6 @@ #include #include #include -#include #include "wm9705.h" diff --git a/sound/soc/codecs/wm9712.c b/sound/soc/codecs/wm9712.c index 3ca42a35e03a..bf5d4ef1a2a6 100644 --- a/sound/soc/codecs/wm9712.c +++ b/sound/soc/codecs/wm9712.c @@ -20,7 +20,6 @@ #include #include #include -#include #include "wm9712.h" #define WM9712_VERSION "0.4" diff --git a/sound/soc/codecs/wm9713.c b/sound/soc/codecs/wm9713.c index 87b236b16016..38ed98558718 100644 --- a/sound/soc/codecs/wm9713.c +++ b/sound/soc/codecs/wm9713.c @@ -26,7 +26,6 @@ #include #include #include -#include #include "wm9713.h" diff --git a/sound/soc/codecs/wm_hubs.c b/sound/soc/codecs/wm_hubs.c index 422c7fb383eb..e7a19d6ada50 100644 --- a/sound/soc/codecs/wm_hubs.c +++ b/sound/soc/codecs/wm_hubs.c @@ -22,7 +22,6 @@ #include #include #include -#include #include #include diff --git a/sound/soc/davinci/davinci-evm.c b/sound/soc/davinci/davinci-evm.c index fd969057344d..24b031e26342 100644 --- a/sound/soc/davinci/davinci-evm.c +++ b/sound/soc/davinci/davinci-evm.c @@ -18,7 +18,6 @@ #include #include #include -#include #include #include diff --git a/sound/soc/davinci/davinci-sffsdr.c b/sound/soc/davinci/davinci-sffsdr.c index 6c6666a1f942..0fe558c65145 100644 --- a/sound/soc/davinci/davinci-sffsdr.c +++ b/sound/soc/davinci/davinci-sffsdr.c @@ -21,7 +21,6 @@ #include #include #include -#include #include #include diff --git a/sound/soc/ep93xx/snappercl15.c b/sound/soc/ep93xx/snappercl15.c index f1c78516ccac..dfe1d7f74ea6 100644 --- a/sound/soc/ep93xx/snappercl15.c +++ b/sound/soc/ep93xx/snappercl15.c @@ -15,7 +15,6 @@ #include #include #include -#include #include #include diff --git a/sound/soc/imx/eukrea-tlv320.c b/sound/soc/imx/eukrea-tlv320.c index dd4fffdbd177..e20c9e1457c0 100644 --- a/sound/soc/imx/eukrea-tlv320.c +++ b/sound/soc/imx/eukrea-tlv320.c @@ -22,7 +22,6 @@ #include #include #include -#include #include #include "../codecs/tlv320aic23.h" diff --git a/sound/soc/imx/phycore-ac97.c b/sound/soc/imx/phycore-ac97.c index 39f23734781a..db157f773c15 100644 --- a/sound/soc/imx/phycore-ac97.c +++ b/sound/soc/imx/phycore-ac97.c @@ -17,7 +17,6 @@ #include #include #include -#include #include static struct snd_soc_card imx_phycore; diff --git a/sound/soc/imx/wm1133-ev1.c b/sound/soc/imx/wm1133-ev1.c index 46fadf497243..75b4c72787e2 100644 --- a/sound/soc/imx/wm1133-ev1.c +++ b/sound/soc/imx/wm1133-ev1.c @@ -19,7 +19,6 @@ #include #include #include -#include #include diff --git a/sound/soc/jz4740/jz4740-i2s.c b/sound/soc/jz4740/jz4740-i2s.c index f3cffd183401..419bf4f5534a 100644 --- a/sound/soc/jz4740/jz4740-i2s.c +++ b/sound/soc/jz4740/jz4740-i2s.c @@ -28,7 +28,6 @@ #include #include #include -#include #include #include "jz4740-i2s.h" diff --git a/sound/soc/jz4740/qi_lb60.c b/sound/soc/jz4740/qi_lb60.c index 70afbfada9fd..49723e3e7e38 100644 --- a/sound/soc/jz4740/qi_lb60.c +++ b/sound/soc/jz4740/qi_lb60.c @@ -19,7 +19,6 @@ #include #include #include -#include #include #define QI_LB60_SND_GPIO JZ_GPIO_PORTB(29) diff --git a/sound/soc/kirkwood/kirkwood-t5325.c b/sound/soc/kirkwood/kirkwood-t5325.c index 07b6ecaed2f2..c8d21956ab52 100644 --- a/sound/soc/kirkwood/kirkwood-t5325.c +++ b/sound/soc/kirkwood/kirkwood-t5325.c @@ -15,7 +15,6 @@ #include #include #include -#include #include #include #include diff --git a/sound/soc/nuc900/nuc900-audio.c b/sound/soc/nuc900/nuc900-audio.c index 161f5b667d7b..38a2d0d883b5 100644 --- a/sound/soc/nuc900/nuc900-audio.c +++ b/sound/soc/nuc900/nuc900-audio.c @@ -18,7 +18,6 @@ #include #include #include -#include #include "nuc900-audio.h" diff --git a/sound/soc/omap/am3517evm.c b/sound/soc/omap/am3517evm.c index 668773def0dc..161750443ebc 100644 --- a/sound/soc/omap/am3517evm.c +++ b/sound/soc/omap/am3517evm.c @@ -22,7 +22,6 @@ #include #include #include -#include #include #include diff --git a/sound/soc/omap/igep0020.c b/sound/soc/omap/igep0020.c index fd3a40f309c8..0ae34702995b 100644 --- a/sound/soc/omap/igep0020.c +++ b/sound/soc/omap/igep0020.c @@ -24,7 +24,6 @@ #include #include #include -#include #include #include diff --git a/sound/soc/omap/n810.c b/sound/soc/omap/n810.c index 296cd9b7eecb..fe215f3e8afc 100644 --- a/sound/soc/omap/n810.c +++ b/sound/soc/omap/n810.c @@ -27,7 +27,6 @@ #include #include #include -#include #include #include diff --git a/sound/soc/omap/omap2evm.c b/sound/soc/omap/omap2evm.c index cf3fc8a675b5..29b60d6796e7 100644 --- a/sound/soc/omap/omap2evm.c +++ b/sound/soc/omap/omap2evm.c @@ -26,7 +26,6 @@ #include #include #include -#include #include #include diff --git a/sound/soc/omap/omap3beagle.c b/sound/soc/omap/omap3beagle.c index e56832b0c444..40db813c0795 100644 --- a/sound/soc/omap/omap3beagle.c +++ b/sound/soc/omap/omap3beagle.c @@ -24,7 +24,6 @@ #include #include #include -#include #include #include diff --git a/sound/soc/omap/omap3evm.c b/sound/soc/omap/omap3evm.c index 810f1e36da21..0daa04469836 100644 --- a/sound/soc/omap/omap3evm.c +++ b/sound/soc/omap/omap3evm.c @@ -22,7 +22,6 @@ #include #include #include -#include #include #include diff --git a/sound/soc/omap/omap3pandora.c b/sound/soc/omap/omap3pandora.c index 93e83c0f6660..bff9864e7615 100644 --- a/sound/soc/omap/omap3pandora.c +++ b/sound/soc/omap/omap3pandora.c @@ -28,7 +28,6 @@ #include #include #include -#include #include #include diff --git a/sound/soc/omap/osk5912.c b/sound/soc/omap/osk5912.c index c2a54204559d..18d053d2ba8c 100644 --- a/sound/soc/omap/osk5912.c +++ b/sound/soc/omap/osk5912.c @@ -26,7 +26,6 @@ #include #include #include -#include #include #include diff --git a/sound/soc/omap/overo.c b/sound/soc/omap/overo.c index e95a607937de..bbcf380bfb56 100644 --- a/sound/soc/omap/overo.c +++ b/sound/soc/omap/overo.c @@ -24,7 +24,6 @@ #include #include #include -#include #include #include diff --git a/sound/soc/omap/rx51.c b/sound/soc/omap/rx51.c index 62fc7a4f306b..150042a785d0 100644 --- a/sound/soc/omap/rx51.c +++ b/sound/soc/omap/rx51.c @@ -30,7 +30,6 @@ #include #include #include -#include #include #include diff --git a/sound/soc/omap/sdp3430.c b/sound/soc/omap/sdp3430.c index a3dd07a39fec..3f72d17d1ef0 100644 --- a/sound/soc/omap/sdp3430.c +++ b/sound/soc/omap/sdp3430.c @@ -28,7 +28,6 @@ #include #include #include -#include #include #include diff --git a/sound/soc/omap/sdp4430.c b/sound/soc/omap/sdp4430.c index 3ce17318a291..ebbd62fc447c 100644 --- a/sound/soc/omap/sdp4430.c +++ b/sound/soc/omap/sdp4430.c @@ -24,7 +24,6 @@ #include #include #include -#include #include #include diff --git a/sound/soc/omap/zoom2.c b/sound/soc/omap/zoom2.c index cc5bc523b302..01709940a43c 100644 --- a/sound/soc/omap/zoom2.c +++ b/sound/soc/omap/zoom2.c @@ -24,7 +24,6 @@ #include #include #include -#include #include #include diff --git a/sound/soc/pxa/corgi.c b/sound/soc/pxa/corgi.c index 85956ff8783e..fc592f0d5fc7 100644 --- a/sound/soc/pxa/corgi.c +++ b/sound/soc/pxa/corgi.c @@ -23,7 +23,6 @@ #include #include #include -#include #include #include diff --git a/sound/soc/pxa/e740_wm9705.c b/sound/soc/pxa/e740_wm9705.c index 38a84b821ff4..28333e7d9c50 100644 --- a/sound/soc/pxa/e740_wm9705.c +++ b/sound/soc/pxa/e740_wm9705.c @@ -16,7 +16,6 @@ #include #include #include -#include #include #include diff --git a/sound/soc/pxa/e750_wm9705.c b/sound/soc/pxa/e750_wm9705.c index 2bc97e92446b..01bf31675c55 100644 --- a/sound/soc/pxa/e750_wm9705.c +++ b/sound/soc/pxa/e750_wm9705.c @@ -16,7 +16,6 @@ #include #include #include -#include #include #include diff --git a/sound/soc/pxa/e800_wm9712.c b/sound/soc/pxa/e800_wm9712.c index eac846c7bd9c..c6a37c6ef23b 100644 --- a/sound/soc/pxa/e800_wm9712.c +++ b/sound/soc/pxa/e800_wm9712.c @@ -16,7 +16,6 @@ #include #include #include -#include #include #include diff --git a/sound/soc/pxa/em-x270.c b/sound/soc/pxa/em-x270.c index eadf9d351a04..fc22e6eefc98 100644 --- a/sound/soc/pxa/em-x270.c +++ b/sound/soc/pxa/em-x270.c @@ -26,7 +26,6 @@ #include #include #include -#include #include #include diff --git a/sound/soc/pxa/magician.c b/sound/soc/pxa/magician.c index 98cb9906e795..67dcc36cd621 100644 --- a/sound/soc/pxa/magician.c +++ b/sound/soc/pxa/magician.c @@ -26,7 +26,6 @@ #include #include #include -#include #include #include diff --git a/sound/soc/pxa/mioa701_wm9713.c b/sound/soc/pxa/mioa701_wm9713.c index f7a1e8f09f9a..0d70fc8c12bd 100644 --- a/sound/soc/pxa/mioa701_wm9713.c +++ b/sound/soc/pxa/mioa701_wm9713.c @@ -50,7 +50,6 @@ #include #include #include -#include #include #include diff --git a/sound/soc/pxa/palm27x.c b/sound/soc/pxa/palm27x.c index 530064dd06a9..857db96d4a4f 100644 --- a/sound/soc/pxa/palm27x.c +++ b/sound/soc/pxa/palm27x.c @@ -21,7 +21,6 @@ #include #include #include -#include #include #include diff --git a/sound/soc/pxa/poodle.c b/sound/soc/pxa/poodle.c index f45ea408852b..6298ee115e27 100644 --- a/sound/soc/pxa/poodle.c +++ b/sound/soc/pxa/poodle.c @@ -23,7 +23,6 @@ #include #include #include -#include #include #include diff --git a/sound/soc/pxa/raumfeld.c b/sound/soc/pxa/raumfeld.c index 2cda82bc5d2e..0fd60f423036 100644 --- a/sound/soc/pxa/raumfeld.c +++ b/sound/soc/pxa/raumfeld.c @@ -22,7 +22,6 @@ #include #include #include -#include #include diff --git a/sound/soc/pxa/saarb.c b/sound/soc/pxa/saarb.c index ee06f9982c09..9595189fc681 100644 --- a/sound/soc/pxa/saarb.c +++ b/sound/soc/pxa/saarb.c @@ -18,7 +18,6 @@ #include #include #include -#include #include #include diff --git a/sound/soc/pxa/spitz.c b/sound/soc/pxa/spitz.c index 7e13440cca41..c2acb69b957a 100644 --- a/sound/soc/pxa/spitz.c +++ b/sound/soc/pxa/spitz.c @@ -23,7 +23,6 @@ #include #include #include -#include #include #include diff --git a/sound/soc/pxa/tavorevb3.c b/sound/soc/pxa/tavorevb3.c index 18cbe0e7c223..f881f65ec172 100644 --- a/sound/soc/pxa/tavorevb3.c +++ b/sound/soc/pxa/tavorevb3.c @@ -18,7 +18,6 @@ #include #include #include -#include #include #include diff --git a/sound/soc/pxa/tosa.c b/sound/soc/pxa/tosa.c index 7f81f82ba788..f75804ef0897 100644 --- a/sound/soc/pxa/tosa.c +++ b/sound/soc/pxa/tosa.c @@ -26,7 +26,6 @@ #include #include #include -#include #include #include diff --git a/sound/soc/pxa/z2.c b/sound/soc/pxa/z2.c index cacbcd4a55eb..2d4f896d7fec 100644 --- a/sound/soc/pxa/z2.c +++ b/sound/soc/pxa/z2.c @@ -21,7 +21,6 @@ #include #include #include -#include #include #include diff --git a/sound/soc/pxa/zylonite.c b/sound/soc/pxa/zylonite.c index c74eac30ebff..b222a7d72027 100644 --- a/sound/soc/pxa/zylonite.c +++ b/sound/soc/pxa/zylonite.c @@ -20,7 +20,6 @@ #include #include #include -#include #include "../codecs/wm9713.h" #include "pxa2xx-ac97.h" diff --git a/sound/soc/s3c24xx/aquila_wm8994.c b/sound/soc/s3c24xx/aquila_wm8994.c index 33bebdae08a7..0043e6296c9c 100644 --- a/sound/soc/s3c24xx/aquila_wm8994.c +++ b/sound/soc/s3c24xx/aquila_wm8994.c @@ -16,7 +16,6 @@ #include #include #include -#include #include #include #include diff --git a/sound/soc/s3c24xx/goni_wm8994.c b/sound/soc/s3c24xx/goni_wm8994.c index 052729c6540d..bcbfe8534f32 100644 --- a/sound/soc/s3c24xx/goni_wm8994.c +++ b/sound/soc/s3c24xx/goni_wm8994.c @@ -16,7 +16,6 @@ #include #include #include -#include #include #include #include diff --git a/sound/soc/s3c24xx/jive_wm8750.c b/sound/soc/s3c24xx/jive_wm8750.c index e3599e283568..100f0f0eabef 100644 --- a/sound/soc/s3c24xx/jive_wm8750.c +++ b/sound/soc/s3c24xx/jive_wm8750.c @@ -21,7 +21,6 @@ #include #include #include -#include #include diff --git a/sound/soc/s3c24xx/ln2440sbc_alc650.c b/sound/soc/s3c24xx/ln2440sbc_alc650.c index abe64abe8c84..dd4fad8c7b50 100644 --- a/sound/soc/s3c24xx/ln2440sbc_alc650.c +++ b/sound/soc/s3c24xx/ln2440sbc_alc650.c @@ -21,7 +21,6 @@ #include #include #include -#include #include "s3c-dma.h" #include "s3c-ac97.h" diff --git a/sound/soc/s3c24xx/neo1973_gta02_wm8753.c b/sound/soc/s3c24xx/neo1973_gta02_wm8753.c index c3f63ef8ab12..64c98e5d648d 100644 --- a/sound/soc/s3c24xx/neo1973_gta02_wm8753.c +++ b/sound/soc/s3c24xx/neo1973_gta02_wm8753.c @@ -22,7 +22,6 @@ #include #include #include -#include #include diff --git a/sound/soc/s3c24xx/neo1973_wm8753.c b/sound/soc/s3c24xx/neo1973_wm8753.c index e94ffe01a4a5..11e3c905bd87 100644 --- a/sound/soc/s3c24xx/neo1973_wm8753.c +++ b/sound/soc/s3c24xx/neo1973_wm8753.c @@ -21,7 +21,6 @@ #include #include #include -#include #include #include diff --git a/sound/soc/s3c24xx/rx1950_uda1380.c b/sound/soc/s3c24xx/rx1950_uda1380.c index b2a741a7288b..5dfd4dbddca2 100644 --- a/sound/soc/s3c24xx/rx1950_uda1380.c +++ b/sound/soc/s3c24xx/rx1950_uda1380.c @@ -25,7 +25,6 @@ #include #include -#include #include #include diff --git a/sound/soc/s3c24xx/s3c24xx_simtec.c b/sound/soc/s3c24xx/s3c24xx_simtec.c index c4c111442010..8d3bbc6385a7 100644 --- a/sound/soc/s3c24xx/s3c24xx_simtec.c +++ b/sound/soc/s3c24xx/s3c24xx_simtec.c @@ -17,7 +17,6 @@ #include #include #include -#include #include diff --git a/sound/soc/s3c24xx/s3c24xx_simtec_hermes.c b/sound/soc/s3c24xx/s3c24xx_simtec_hermes.c index 05c793705d90..044a0b241642 100644 --- a/sound/soc/s3c24xx/s3c24xx_simtec_hermes.c +++ b/sound/soc/s3c24xx/s3c24xx_simtec_hermes.c @@ -14,7 +14,6 @@ #include #include #include -#include #include diff --git a/sound/soc/s3c24xx/s3c24xx_simtec_tlv320aic23.c b/sound/soc/s3c24xx/s3c24xx_simtec_tlv320aic23.c index 653dc7592e81..f2f70a937110 100644 --- a/sound/soc/s3c24xx/s3c24xx_simtec_tlv320aic23.c +++ b/sound/soc/s3c24xx/s3c24xx_simtec_tlv320aic23.c @@ -14,7 +14,6 @@ #include #include #include -#include #include diff --git a/sound/soc/s3c24xx/s3c24xx_uda134x.c b/sound/soc/s3c24xx/s3c24xx_uda134x.c index bd48ffbde880..4f1eeb64b4c4 100644 --- a/sound/soc/s3c24xx/s3c24xx_uda134x.c +++ b/sound/soc/s3c24xx/s3c24xx_uda134x.c @@ -18,7 +18,6 @@ #include #include #include -#include #include #include diff --git a/sound/soc/s3c24xx/smdk2443_wm9710.c b/sound/soc/s3c24xx/smdk2443_wm9710.c index 4613288c2772..ec05df92234b 100644 --- a/sound/soc/s3c24xx/smdk2443_wm9710.c +++ b/sound/soc/s3c24xx/smdk2443_wm9710.c @@ -17,7 +17,6 @@ #include #include #include -#include #include "s3c-dma.h" #include "s3c-ac97.h" diff --git a/sound/soc/s3c24xx/smdk64xx_wm8580.c b/sound/soc/s3c24xx/smdk64xx_wm8580.c index 291939cf8483..e6b461cce191 100644 --- a/sound/soc/s3c24xx/smdk64xx_wm8580.c +++ b/sound/soc/s3c24xx/smdk64xx_wm8580.c @@ -16,7 +16,6 @@ #include #include #include -#include #include "../codecs/wm8580.h" #include "s3c-dma.h" diff --git a/sound/soc/s6000/s6105-ipcam.c b/sound/soc/s6000/s6105-ipcam.c index db1803d9665a..2e977e4d65e7 100644 --- a/sound/soc/s6000/s6105-ipcam.c +++ b/sound/soc/s6000/s6105-ipcam.c @@ -18,7 +18,6 @@ #include #include #include -#include #include diff --git a/sound/soc/sh/migor.c b/sound/soc/sh/migor.c index c61fc188394d..df13338cb3e2 100644 --- a/sound/soc/sh/migor.c +++ b/sound/soc/sh/migor.c @@ -20,7 +20,6 @@ #include #include #include -#include #include "../codecs/wm8978.h" #include "siu.h" diff --git a/sound/soc/sh/sh7760-ac97.c b/sound/soc/sh/sh7760-ac97.c index 105d4112e3ba..917d3ceadc9d 100644 --- a/sound/soc/sh/sh7760-ac97.c +++ b/sound/soc/sh/sh7760-ac97.c @@ -12,7 +12,6 @@ #include #include #include -#include #include #define IPSEL 0xFE400034 diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 2540efd67ee7..c8d8dde7f4dd 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -36,7 +36,6 @@ #include #include #include -#include #include #define CREATE_TRACE_POINTS diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index 02b6ac46b278..6a29d59dabaf 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -43,7 +43,6 @@ #include #include #include -#include #include #include diff --git a/sound/soc/soc-jack.c b/sound/soc/soc-jack.c index 619061d689a3..0e9b0710928b 100644 --- a/sound/soc/soc-jack.c +++ b/sound/soc/soc-jack.c @@ -13,7 +13,6 @@ #include #include -#include #include #include #include -- cgit v1.2.3 From 0d911baebf983931cb37e25b36c3371d9e4b5196 Mon Sep 17 00:00:00 2001 From: Jarkko Nikula Date: Sun, 21 Nov 2010 19:48:46 +0200 Subject: ASoC: Do not include soc-dai.h There is no need to include soc-dai.h since soc.h includes it. Convert drivers to include only soc.h. Signed-off-by: Jarkko Nikula Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/codecs/cq93vc.c | 1 - sound/soc/codecs/wl1273.c | 2 +- sound/soc/sh/siu.h | 2 +- sound/soc/sh/siu_dai.c | 2 +- sound/soc/sh/siu_pcm.c | 2 +- 5 files changed, 4 insertions(+), 5 deletions(-) diff --git a/sound/soc/codecs/cq93vc.c b/sound/soc/codecs/cq93vc.c index 1a6f511051b6..46dbfd067f79 100644 --- a/sound/soc/codecs/cq93vc.c +++ b/sound/soc/codecs/cq93vc.c @@ -36,7 +36,6 @@ #include #include #include -#include #include #include diff --git a/sound/soc/codecs/wl1273.c b/sound/soc/codecs/wl1273.c index c606b3e235fa..d3ffa2f0122a 100644 --- a/sound/soc/codecs/wl1273.c +++ b/sound/soc/codecs/wl1273.c @@ -25,7 +25,7 @@ #include #include #include -#include +#include #include #include "wl1273.h" diff --git a/sound/soc/sh/siu.h b/sound/soc/sh/siu.h index 9f4dcb921ff0..83c3430ad797 100644 --- a/sound/soc/sh/siu.h +++ b/sound/soc/sh/siu.h @@ -75,7 +75,7 @@ struct siu_firmware { #include #include -#include +#include #define SIU_PERIOD_BYTES_MAX 8192 /* DMA transfer/period size */ #define SIU_PERIOD_BYTES_MIN 256 /* DMA transfer/period size */ diff --git a/sound/soc/sh/siu_dai.c b/sound/soc/sh/siu_dai.c index af53b64d8af2..4973c2939d79 100644 --- a/sound/soc/sh/siu_dai.c +++ b/sound/soc/sh/siu_dai.c @@ -28,7 +28,7 @@ #include #include -#include +#include #include "siu.h" diff --git a/sound/soc/sh/siu_pcm.c b/sound/soc/sh/siu_pcm.c index ed29c9e1ed4e..a423babcf145 100644 --- a/sound/soc/sh/siu_pcm.c +++ b/sound/soc/sh/siu_pcm.c @@ -29,7 +29,7 @@ #include #include #include -#include +#include #include -- cgit v1.2.3 From 851cad5aa11a0692c4c92ebbfa94d06564034dcc Mon Sep 17 00:00:00 2001 From: Jarkko Nikula Date: Sun, 21 Nov 2010 19:48:47 +0200 Subject: ASoC: Remove cyclic dependency between soc.h and soc-dapm.h/soc-dai.h There is no need anymore to include soc.h in soc-dapm.h and soc-dai.h as drivers are converted to include only soc.h. Thanks to Lars-Peter Clausen for pointing out the issue. Signed-off-by: Jarkko Nikula Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- include/sound/soc-dai.h | 2 -- include/sound/soc-dapm.h | 1 - 2 files changed, 3 deletions(-) diff --git a/include/sound/soc-dai.h b/include/sound/soc-dai.h index e7b680248006..0195b7ee17e1 100644 --- a/include/sound/soc-dai.h +++ b/include/sound/soc-dai.h @@ -16,8 +16,6 @@ #include -#include - struct snd_pcm_substream; /* diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h index 78d3560fa25a..041e98b493b7 100644 --- a/include/sound/soc-dapm.h +++ b/include/sound/soc-dapm.h @@ -16,7 +16,6 @@ #include #include #include -#include /* widget has no PM register bit */ #define SND_SOC_NOPM -1 -- cgit v1.2.3 From c7b642911ea0fa9168425757752f094a1255209a Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Mon, 22 Nov 2010 08:34:07 +0800 Subject: ASoC: Fix a memory leak in alc5623_i2c_probe error path Signed-off-by: Axel Lin Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/codecs/alc5623.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/sound/soc/codecs/alc5623.c b/sound/soc/codecs/alc5623.c index e84b26b0ce9e..9783e7e2eb93 100644 --- a/sound/soc/codecs/alc5623.c +++ b/sound/soc/codecs/alc5623.c @@ -1022,10 +1022,8 @@ static int alc5623_i2c_probe(struct i2c_client *client, dev_dbg(&client->dev, "Found codec id : alc56%02x\n", vid2); alc5623 = kzalloc(sizeof(struct alc5623_priv), GFP_KERNEL); - if (alc5623 == NULL) { - ret = -ENOMEM; - goto err; - } + if (alc5623 == NULL) + return -ENOMEM; pdata = client->dev.platform_data; if (pdata) { @@ -1056,12 +1054,9 @@ static int alc5623_i2c_probe(struct i2c_client *client, &soc_codec_device_alc5623, &alc5623_dai, 1); if (ret != 0) { dev_err(&client->dev, "Failed to register codec: %d\n", ret); - goto err; + kfree(alc5623); } - return 0; - -err: return ret; } -- cgit v1.2.3 From 9535ab7323351bacf02d82af79921df1d6594969 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Mon, 22 Nov 2010 17:56:18 -0500 Subject: drm/radeon/kms: setup mc chremap properly on r7xx/evergreen Should improve performance slightly and possibly fix some issues. Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/evergreen.c | 38 +++++++++++++++++++++++++++++++ drivers/gpu/drm/radeon/evergreend.h | 4 ++++ drivers/gpu/drm/radeon/rv770.c | 45 +++++++++++++++++++++++++++++++++++++ drivers/gpu/drm/radeon/rv770d.h | 2 ++ 4 files changed, 89 insertions(+) diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index 4dc5b4714c5a..728358e6b798 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c @@ -1382,6 +1382,42 @@ static u32 evergreen_get_tile_pipe_to_backend_map(struct radeon_device *rdev, return backend_map; } +static void evergreen_program_channel_remap(struct radeon_device *rdev) +{ + u32 tcp_chan_steer_lo, tcp_chan_steer_hi, mc_shared_chremap, tmp; + + tmp = RREG32(MC_SHARED_CHMAP); + switch ((tmp & NOOFCHAN_MASK) >> NOOFCHAN_SHIFT) { + case 0: + case 1: + case 2: + case 3: + default: + /* default mapping */ + mc_shared_chremap = 0x00fac688; + break; + } + + switch (rdev->family) { + case CHIP_HEMLOCK: + case CHIP_CYPRESS: + tcp_chan_steer_lo = 0x54763210; + tcp_chan_steer_hi = 0x0000ba98; + break; + case CHIP_JUNIPER: + case CHIP_REDWOOD: + case CHIP_CEDAR: + default: + tcp_chan_steer_lo = 0x76543210; + tcp_chan_steer_hi = 0x0000ba98; + break; + } + + WREG32(TCP_CHAN_STEER_LO, tcp_chan_steer_lo); + WREG32(TCP_CHAN_STEER_HI, tcp_chan_steer_hi); + WREG32(MC_SHARED_CHREMAP, mc_shared_chremap); +} + static void evergreen_gpu_init(struct radeon_device *rdev) { u32 cc_rb_backend_disable = 0; @@ -1685,6 +1721,8 @@ static void evergreen_gpu_init(struct radeon_device *rdev) WREG32(DMIF_ADDR_CONFIG, gb_addr_config); WREG32(HDP_ADDR_CONFIG, gb_addr_config); + evergreen_program_channel_remap(rdev); + num_shader_engines = ((RREG32(GB_ADDR_CONFIG) & NUM_SHADER_ENGINES(3)) >> 12) + 1; grbm_gfx_index = INSTANCE_BROADCAST_WRITES; diff --git a/drivers/gpu/drm/radeon/evergreend.h b/drivers/gpu/drm/radeon/evergreend.h index 113c70cc8b39..9644b1cbfb09 100644 --- a/drivers/gpu/drm/radeon/evergreend.h +++ b/drivers/gpu/drm/radeon/evergreend.h @@ -180,6 +180,7 @@ #define MC_SHARED_CHMAP 0x2004 #define NOOFCHAN_SHIFT 12 #define NOOFCHAN_MASK 0x00003000 +#define MC_SHARED_CHREMAP 0x2008 #define MC_ARB_RAMCFG 0x2760 #define NOOFBANK_SHIFT 0 @@ -348,6 +349,9 @@ #define SYNC_WALKER (1 << 25) #define SYNC_ALIGNER (1 << 26) +#define TCP_CHAN_STEER_LO 0x960c +#define TCP_CHAN_STEER_HI 0x9610 + #define VGT_CACHE_INVALIDATION 0x88C4 #define CACHE_INVALIDATION(x) ((x) << 0) #define VC_ONLY 0 diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c index 4dfead8cee33..24ebd0879c4b 100644 --- a/drivers/gpu/drm/radeon/rv770.c +++ b/drivers/gpu/drm/radeon/rv770.c @@ -489,6 +489,49 @@ static u32 r700_get_tile_pipe_to_backend_map(struct radeon_device *rdev, return backend_map; } +static void rv770_program_channel_remap(struct radeon_device *rdev) +{ + u32 tcp_chan_steer, mc_shared_chremap, tmp; + bool force_no_swizzle; + + switch (rdev->family) { + case CHIP_RV770: + case CHIP_RV730: + force_no_swizzle = false; + break; + case CHIP_RV710: + case CHIP_RV740: + default: + force_no_swizzle = true; + break; + } + + tmp = RREG32(MC_SHARED_CHMAP); + switch ((tmp & NOOFCHAN_MASK) >> NOOFCHAN_SHIFT) { + case 0: + case 1: + default: + /* default mapping */ + mc_shared_chremap = 0x00fac688; + break; + case 2: + case 3: + if (force_no_swizzle) + mc_shared_chremap = 0x00fac688; + else + mc_shared_chremap = 0x00bbc298; + break; + } + + if (rdev->family == CHIP_RV740) + tcp_chan_steer = 0x00ef2a60; + else + tcp_chan_steer = 0x00fac688; + + WREG32(TCP_CHAN_STEER, tcp_chan_steer); + WREG32(MC_SHARED_CHREMAP, mc_shared_chremap); +} + static void rv770_gpu_init(struct radeon_device *rdev) { int i, j, num_qd_pipes; @@ -688,6 +731,8 @@ static void rv770_gpu_init(struct radeon_device *rdev) WREG32(DCP_TILING_CONFIG, (gb_tiling_config & 0xffff)); WREG32(HDP_TILING_CONFIG, (gb_tiling_config & 0xffff)); + rv770_program_channel_remap(rdev); + WREG32(CC_RB_BACKEND_DISABLE, cc_rb_backend_disable); WREG32(CC_GC_SHADER_PIPE_CONFIG, cc_gc_shader_pipe_config); WREG32(GC_USER_SHADER_PIPE_CONFIG, cc_gc_shader_pipe_config); diff --git a/drivers/gpu/drm/radeon/rv770d.h b/drivers/gpu/drm/radeon/rv770d.h index b7a5a20e81dc..7b1c8f8f4074 100644 --- a/drivers/gpu/drm/radeon/rv770d.h +++ b/drivers/gpu/drm/radeon/rv770d.h @@ -138,6 +138,7 @@ #define MC_SHARED_CHMAP 0x2004 #define NOOFCHAN_SHIFT 12 #define NOOFCHAN_MASK 0x00003000 +#define MC_SHARED_CHREMAP 0x2008 #define MC_ARB_RAMCFG 0x2760 #define NOOFBANK_SHIFT 0 @@ -303,6 +304,7 @@ #define BILINEAR_PRECISION_8_BIT (1 << 31) #define TCP_CNTL 0x9610 +#define TCP_CHAN_STEER 0x9614 #define VGT_CACHE_INVALIDATION 0x88C4 #define CACHE_INVALIDATION(x) ((x)<<0) -- cgit v1.2.3 From 5d68e501bf000b8b1696875455c7a556ce2e9c43 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Mon, 22 Nov 2010 17:56:19 -0500 Subject: drm/radeon/kms: upstream ObjectID.h updates Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/ObjectID.h | 48 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/drivers/gpu/drm/radeon/ObjectID.h b/drivers/gpu/drm/radeon/ObjectID.h index c714179d1bfa..c61c3fe9fb98 100644 --- a/drivers/gpu/drm/radeon/ObjectID.h +++ b/drivers/gpu/drm/radeon/ObjectID.h @@ -37,6 +37,8 @@ #define GRAPH_OBJECT_TYPE_CONNECTOR 0x3 #define GRAPH_OBJECT_TYPE_ROUTER 0x4 /* deleted */ +#define GRAPH_OBJECT_TYPE_DISPLAY_PATH 0x6 +#define GRAPH_OBJECT_TYPE_GENERIC 0x7 /****************************************************/ /* Encoder Object ID Definition */ @@ -64,6 +66,9 @@ #define ENCODER_OBJECT_ID_VT1623 0x10 #define ENCODER_OBJECT_ID_HDMI_SI1930 0x11 #define ENCODER_OBJECT_ID_HDMI_INTERNAL 0x12 +#define ENCODER_OBJECT_ID_ALMOND 0x22 +#define ENCODER_OBJECT_ID_TRAVIS 0x23 +#define ENCODER_OBJECT_ID_NUTMEG 0x22 /* Kaleidoscope (KLDSCP) Class Display Hardware (internal) */ #define ENCODER_OBJECT_ID_INTERNAL_KLDSCP_TMDS1 0x13 #define ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DVO1 0x14 @@ -108,6 +113,7 @@ #define CONNECTOR_OBJECT_ID_DISPLAYPORT 0x13 #define CONNECTOR_OBJECT_ID_eDP 0x14 #define CONNECTOR_OBJECT_ID_MXM 0x15 +#define CONNECTOR_OBJECT_ID_LVDS_eDP 0x16 /* deleted */ @@ -124,6 +130,7 @@ #define GENERIC_OBJECT_ID_GLSYNC 0x01 #define GENERIC_OBJECT_ID_PX2_NON_DRIVABLE 0x02 #define GENERIC_OBJECT_ID_MXM_OPM 0x03 +#define GENERIC_OBJECT_ID_STEREO_PIN 0x04 //This object could show up from Misc Object table, it follows ATOM_OBJECT format, and contains one ATOM_OBJECT_GPIO_CNTL_RECORD for the stereo pin /****************************************************/ /* Graphics Object ENUM ID Definition */ @@ -360,6 +367,26 @@ GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ ENCODER_OBJECT_ID_GENERAL_EXTERNAL_DVO << OBJECT_ID_SHIFT) +#define ENCODER_ALMOND_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ + GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ + ENCODER_OBJECT_ID_ALMOND << OBJECT_ID_SHIFT) + +#define ENCODER_ALMOND_ENUM_ID2 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ + GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ + ENCODER_OBJECT_ID_ALMOND << OBJECT_ID_SHIFT) + +#define ENCODER_TRAVIS_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ + GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ + ENCODER_OBJECT_ID_TRAVIS << OBJECT_ID_SHIFT) + +#define ENCODER_TRAVIS_ENUM_ID2 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ + GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ + ENCODER_OBJECT_ID_TRAVIS << OBJECT_ID_SHIFT) + +#define ENCODER_NUTMEG_ENUM_ID1 ( GRAPH_OBJECT_TYPE_ENCODER << OBJECT_TYPE_SHIFT |\ + GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ + ENCODER_OBJECT_ID_NUTMEG << OBJECT_ID_SHIFT) + /****************************************************/ /* Connector Object ID definition - Shared with BIOS */ /****************************************************/ @@ -421,6 +448,14 @@ GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D << OBJECT_ID_SHIFT) +#define CONNECTOR_SINGLE_LINK_DVI_D_ENUM_ID3 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ + GRAPH_OBJECT_ENUM_ID3 << ENUM_ID_SHIFT |\ + CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D << OBJECT_ID_SHIFT) + +#define CONNECTOR_SINGLE_LINK_DVI_D_ENUM_ID4 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ + GRAPH_OBJECT_ENUM_ID4 << ENUM_ID_SHIFT |\ + CONNECTOR_OBJECT_ID_SINGLE_LINK_DVI_D << OBJECT_ID_SHIFT) + #define CONNECTOR_DUAL_LINK_DVI_D_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ CONNECTOR_OBJECT_ID_DUAL_LINK_DVI_D << OBJECT_ID_SHIFT) @@ -512,6 +547,7 @@ #define CONNECTOR_7PIN_DIN_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ CONNECTOR_OBJECT_ID_7PIN_DIN << OBJECT_ID_SHIFT) + #define CONNECTOR_7PIN_DIN_ENUM_ID2 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ CONNECTOR_OBJECT_ID_7PIN_DIN << OBJECT_ID_SHIFT) @@ -593,6 +629,14 @@ GRAPH_OBJECT_ENUM_ID7 << ENUM_ID_SHIFT |\ CONNECTOR_OBJECT_ID_MXM << OBJECT_ID_SHIFT) //Mapping to MXM_DAC +#define CONNECTOR_LVDS_eDP_ENUM_ID1 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ + GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ + CONNECTOR_OBJECT_ID_LVDS_eDP << OBJECT_ID_SHIFT) + +#define CONNECTOR_LVDS_eDP_ENUM_ID2 ( GRAPH_OBJECT_TYPE_CONNECTOR << OBJECT_TYPE_SHIFT |\ + GRAPH_OBJECT_ENUM_ID2 << ENUM_ID_SHIFT |\ + CONNECTOR_OBJECT_ID_LVDS_eDP << OBJECT_ID_SHIFT) + /****************************************************/ /* Router Object ID definition - Shared with BIOS */ /****************************************************/ @@ -621,6 +665,10 @@ GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ GENERIC_OBJECT_ID_MXM_OPM << OBJECT_ID_SHIFT) +#define GENERICOBJECT_STEREO_PIN_ENUM_ID1 (GRAPH_OBJECT_TYPE_GENERIC << OBJECT_TYPE_SHIFT |\ + GRAPH_OBJECT_ENUM_ID1 << ENUM_ID_SHIFT |\ + GENERIC_OBJECT_ID_STEREO_PIN << OBJECT_ID_SHIFT) + /****************************************************/ /* Object Cap definition - Shared with BIOS */ /****************************************************/ -- cgit v1.2.3 From 1422ef52efa2b9abcf8e9d4d641f3a12579f1027 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Mon, 22 Nov 2010 17:56:20 -0500 Subject: drm/radeon/kms: upstream atombios.h updates Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/atombios.h | 853 +++++++++++++++++++++++++++++++++++--- 1 file changed, 792 insertions(+), 61 deletions(-) diff --git a/drivers/gpu/drm/radeon/atombios.h b/drivers/gpu/drm/radeon/atombios.h index fe359a239df3..6a9baa2443f8 100644 --- a/drivers/gpu/drm/radeon/atombios.h +++ b/drivers/gpu/drm/radeon/atombios.h @@ -73,8 +73,18 @@ #define ATOM_PPLL1 0 #define ATOM_PPLL2 1 #define ATOM_DCPLL 2 +#define ATOM_PPLL0 2 +#define ATOM_EXT_PLL1 8 +#define ATOM_EXT_PLL2 9 +#define ATOM_EXT_CLOCK 10 #define ATOM_PPLL_INVALID 0xFF +#define ENCODER_REFCLK_SRC_P1PLL 0 +#define ENCODER_REFCLK_SRC_P2PLL 1 +#define ENCODER_REFCLK_SRC_DCPLL 2 +#define ENCODER_REFCLK_SRC_EXTCLK 3 +#define ENCODER_REFCLK_SRC_INVALID 0xFF + #define ATOM_SCALER1 0 #define ATOM_SCALER2 1 @@ -192,6 +202,9 @@ typedef struct _ATOM_COMMON_TABLE_HEADER /*Image can't be updated, while Driver needs to carry the new table! */ }ATOM_COMMON_TABLE_HEADER; +/****************************************************************************/ +// Structure stores the ROM header. +/****************************************************************************/ typedef struct _ATOM_ROM_HEADER { ATOM_COMMON_TABLE_HEADER sHeader; @@ -221,6 +234,9 @@ typedef struct _ATOM_ROM_HEADER #define USHORT void* #endif +/****************************************************************************/ +// Structures used in Command.mtb +/****************************************************************************/ typedef struct _ATOM_MASTER_LIST_OF_COMMAND_TABLES{ USHORT ASIC_Init; //Function Table, used by various SW components,latest version 1.1 USHORT GetDisplaySurfaceSize; //Atomic Table, Used by Bios when enabling HW ICON @@ -312,6 +328,7 @@ typedef struct _ATOM_MASTER_LIST_OF_COMMAND_TABLES{ #define SetUniphyInstance ASIC_StaticPwrMgtStatusChange #define HPDInterruptService ReadHWAssistedI2CStatus #define EnableVGA_Access GetSCLKOverMCLKRatio +#define GetDispObjectInfo EnableYUV typedef struct _ATOM_MASTER_COMMAND_TABLE { @@ -357,6 +374,24 @@ typedef struct _ATOM_COMMON_ROM_COMMAND_TABLE_HEADER /****************************************************************************/ #define COMPUTE_MEMORY_PLL_PARAM 1 #define COMPUTE_ENGINE_PLL_PARAM 2 +#define ADJUST_MC_SETTING_PARAM 3 + +/****************************************************************************/ +// Structures used by AdjustMemoryControllerTable +/****************************************************************************/ +typedef struct _ATOM_ADJUST_MEMORY_CLOCK_FREQ +{ +#if ATOM_BIG_ENDIAN + ULONG ulPointerReturnFlag:1; // BYTE_3[7]=1 - Return the pointer to the right Data Block; BYTE_3[7]=0 - Program the right Data Block + ULONG ulMemoryModuleNumber:7; // BYTE_3[6:0] + ULONG ulClockFreq:24; +#else + ULONG ulClockFreq:24; + ULONG ulMemoryModuleNumber:7; // BYTE_3[6:0] + ULONG ulPointerReturnFlag:1; // BYTE_3[7]=1 - Return the pointer to the right Data Block; BYTE_3[7]=0 - Program the right Data Block +#endif +}ATOM_ADJUST_MEMORY_CLOCK_FREQ; +#define POINTER_RETURN_FLAG 0x80 typedef struct _COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS { @@ -440,6 +475,26 @@ typedef struct _COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_V4 #endif }COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_V4; +typedef struct _COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_V5 +{ + union + { + ATOM_COMPUTE_CLOCK_FREQ ulClock; //Input Parameter + ATOM_S_MPLL_FB_DIVIDER ulFbDiv; //Output Parameter + }; + UCHAR ucRefDiv; //Output Parameter + UCHAR ucPostDiv; //Output Parameter + union + { + UCHAR ucCntlFlag; //Output Flags + UCHAR ucInputFlag; //Input Flags. ucInputFlag[0] - Strobe(1)/Performance(0) mode + }; + UCHAR ucReserved; +}COMPUTE_MEMORY_ENGINE_PLL_PARAMETERS_V5; + +// ucInputFlag +#define ATOM_PLL_INPUT_FLAG_PLL_STROBE_MODE_EN 1 // 1-StrobeMode, 0-PerformanceMode + typedef struct _DYNAMICE_MEMORY_SETTINGS_PARAMETER { ATOM_COMPUTE_CLOCK_FREQ ulClock; @@ -583,6 +638,7 @@ typedef struct _DIG_ENCODER_CONTROL_PARAMETERS #define ATOM_ENCODER_CONFIG_DPLINKRATE_MASK 0x01 #define ATOM_ENCODER_CONFIG_DPLINKRATE_1_62GHZ 0x00 #define ATOM_ENCODER_CONFIG_DPLINKRATE_2_70GHZ 0x01 +#define ATOM_ENCODER_CONFIG_DPLINKRATE_5_40GHZ 0x02 #define ATOM_ENCODER_CONFIG_LINK_SEL_MASK 0x04 #define ATOM_ENCODER_CONFIG_LINKA 0x00 #define ATOM_ENCODER_CONFIG_LINKB 0x04 @@ -608,6 +664,9 @@ typedef struct _DIG_ENCODER_CONTROL_PARAMETERS #define ATOM_ENCODER_MODE_TV 13 #define ATOM_ENCODER_MODE_CV 14 #define ATOM_ENCODER_MODE_CRT 15 +#define ATOM_ENCODER_MODE_DVO 16 +#define ATOM_ENCODER_MODE_DP_SST ATOM_ENCODER_MODE_DP // For DP1.2 +#define ATOM_ENCODER_MODE_DP_MST 5 // For DP1.2 typedef struct _ATOM_DIG_ENCODER_CONFIG_V2 { @@ -661,6 +720,7 @@ typedef struct _DIG_ENCODER_CONTROL_PARAMETERS_V2 #define ATOM_ENCODER_CMD_DP_LINK_TRAINING_START 0x08 #define ATOM_ENCODER_CMD_DP_LINK_TRAINING_PATTERN1 0x09 #define ATOM_ENCODER_CMD_DP_LINK_TRAINING_PATTERN2 0x0a +#define ATOM_ENCODER_CMD_DP_LINK_TRAINING_PATTERN3 0x13 #define ATOM_ENCODER_CMD_DP_LINK_TRAINING_COMPLETE 0x0b #define ATOM_ENCODER_CMD_DP_VIDEO_OFF 0x0c #define ATOM_ENCODER_CMD_DP_VIDEO_ON 0x0d @@ -671,24 +731,34 @@ typedef struct _DIG_ENCODER_CONTROL_PARAMETERS_V2 #define ATOM_ENCODER_STATUS_LINK_TRAINING_COMPLETE 0x10 #define ATOM_ENCODER_STATUS_LINK_TRAINING_INCOMPLETE 0x00 +//ucTableFormatRevision=1 +//ucTableContentRevision=3 // Following function ENABLE sub-function will be used by driver when TMDS/HDMI/LVDS is used, disable function will be used by driver typedef struct _ATOM_DIG_ENCODER_CONFIG_V3 { #if ATOM_BIG_ENDIAN UCHAR ucReserved1:1; - UCHAR ucDigSel:3; // =0: DIGA/B/C/D/E/F + UCHAR ucDigSel:3; // =0/1/2/3/4/5: DIG0/1/2/3/4/5 (In register spec also refered as DIGA/B/C/D/E/F) UCHAR ucReserved:3; UCHAR ucDPLinkRate:1; // =0: 1.62Ghz, =1: 2.7Ghz #else UCHAR ucDPLinkRate:1; // =0: 1.62Ghz, =1: 2.7Ghz UCHAR ucReserved:3; - UCHAR ucDigSel:3; // =0: DIGA/B/C/D/E/F + UCHAR ucDigSel:3; // =0/1/2/3/4/5: DIG0/1/2/3/4/5 (In register spec also refered as DIGA/B/C/D/E/F) UCHAR ucReserved1:1; #endif }ATOM_DIG_ENCODER_CONFIG_V3; +#define ATOM_ENCODER_CONFIG_V3_DPLINKRATE_MASK 0x03 +#define ATOM_ENCODER_CONFIG_V3_DPLINKRATE_1_62GHZ 0x00 +#define ATOM_ENCODER_CONFIG_V3_DPLINKRATE_2_70GHZ 0x01 #define ATOM_ENCODER_CONFIG_V3_ENCODER_SEL 0x70 - +#define ATOM_ENCODER_CONFIG_V3_DIG0_ENCODER 0x00 +#define ATOM_ENCODER_CONFIG_V3_DIG1_ENCODER 0x10 +#define ATOM_ENCODER_CONFIG_V3_DIG2_ENCODER 0x20 +#define ATOM_ENCODER_CONFIG_V3_DIG3_ENCODER 0x30 +#define ATOM_ENCODER_CONFIG_V3_DIG4_ENCODER 0x40 +#define ATOM_ENCODER_CONFIG_V3_DIG5_ENCODER 0x50 typedef struct _DIG_ENCODER_CONTROL_PARAMETERS_V3 { @@ -707,6 +777,56 @@ typedef struct _DIG_ENCODER_CONTROL_PARAMETERS_V3 UCHAR ucReserved; }DIG_ENCODER_CONTROL_PARAMETERS_V3; +//ucTableFormatRevision=1 +//ucTableContentRevision=4 +// start from NI +// Following function ENABLE sub-function will be used by driver when TMDS/HDMI/LVDS is used, disable function will be used by driver +typedef struct _ATOM_DIG_ENCODER_CONFIG_V4 +{ +#if ATOM_BIG_ENDIAN + UCHAR ucReserved1:1; + UCHAR ucDigSel:3; // =0/1/2/3/4/5: DIG0/1/2/3/4/5 (In register spec also refered as DIGA/B/C/D/E/F) + UCHAR ucReserved:2; + UCHAR ucDPLinkRate:2; // =0: 1.62Ghz, =1: 2.7Ghz, 2=5.4Ghz <= Changed comparing to previous version +#else + UCHAR ucDPLinkRate:2; // =0: 1.62Ghz, =1: 2.7Ghz, 2=5.4Ghz <= Changed comparing to previous version + UCHAR ucReserved:2; + UCHAR ucDigSel:3; // =0/1/2/3/4/5: DIG0/1/2/3/4/5 (In register spec also refered as DIGA/B/C/D/E/F) + UCHAR ucReserved1:1; +#endif +}ATOM_DIG_ENCODER_CONFIG_V4; + +#define ATOM_ENCODER_CONFIG_V4_DPLINKRATE_MASK 0x03 +#define ATOM_ENCODER_CONFIG_V4_DPLINKRATE_1_62GHZ 0x00 +#define ATOM_ENCODER_CONFIG_V4_DPLINKRATE_2_70GHZ 0x01 +#define ATOM_ENCODER_CONFIG_V4_DPLINKRATE_5_40GHZ 0x02 +#define ATOM_ENCODER_CONFIG_V4_ENCODER_SEL 0x70 +#define ATOM_ENCODER_CONFIG_V4_DIG0_ENCODER 0x00 +#define ATOM_ENCODER_CONFIG_V4_DIG1_ENCODER 0x10 +#define ATOM_ENCODER_CONFIG_V4_DIG2_ENCODER 0x20 +#define ATOM_ENCODER_CONFIG_V4_DIG3_ENCODER 0x30 +#define ATOM_ENCODER_CONFIG_V4_DIG4_ENCODER 0x40 +#define ATOM_ENCODER_CONFIG_V4_DIG5_ENCODER 0x50 + +typedef struct _DIG_ENCODER_CONTROL_PARAMETERS_V4 +{ + USHORT usPixelClock; // in 10KHz; for bios convenient + union{ + ATOM_DIG_ENCODER_CONFIG_V4 acConfig; + UCHAR ucConfig; + }; + UCHAR ucAction; + UCHAR ucEncoderMode; + // =0: DP encoder + // =1: LVDS encoder + // =2: DVI encoder + // =3: HDMI encoder + // =4: SDVO encoder + // =5: DP audio + UCHAR ucLaneNum; // how many lanes to enable + UCHAR ucBitPerColor; // only valid for DP mode when ucAction = ATOM_ENCODER_CMD_SETUP + UCHAR ucHPD_ID; // HPD ID (1-6). =0 means to skip HDP programming. New comparing to previous version +}DIG_ENCODER_CONTROL_PARAMETERS_V4; // define ucBitPerColor: #define PANEL_BPC_UNDEFINE 0x00 @@ -893,6 +1013,7 @@ typedef struct _ATOM_DIG_TRANSMITTER_CONFIG_V3 #endif }ATOM_DIG_TRANSMITTER_CONFIG_V3; + typedef struct _DIG_TRANSMITTER_CONTROL_PARAMETERS_V3 { union @@ -936,6 +1057,149 @@ typedef struct _DIG_TRANSMITTER_CONTROL_PARAMETERS_V3 #define ATOM_TRANSMITTER_CONFIG_V3_TRANSMITTER2 0x40 //CD #define ATOM_TRANSMITTER_CONFIG_V3_TRANSMITTER3 0x80 //EF + +/****************************************************************************/ +// Structures used by UNIPHYTransmitterControlTable V1.4 +// ASIC Families: NI +// ucTableFormatRevision=1 +// ucTableContentRevision=4 +/****************************************************************************/ +typedef struct _ATOM_DP_VS_MODE_V4 +{ + UCHAR ucLaneSel; + union + { + UCHAR ucLaneSet; + struct { +#if ATOM_BIG_ENDIAN + UCHAR ucPOST_CURSOR2:2; //Bit[7:6] Post Cursor2 Level <= New in V4 + UCHAR ucPRE_EMPHASIS:3; //Bit[5:3] Pre-emphasis Level + UCHAR ucVOLTAGE_SWING:3; //Bit[2:0] Voltage Swing Level +#else + UCHAR ucVOLTAGE_SWING:3; //Bit[2:0] Voltage Swing Level + UCHAR ucPRE_EMPHASIS:3; //Bit[5:3] Pre-emphasis Level + UCHAR ucPOST_CURSOR2:2; //Bit[7:6] Post Cursor2 Level <= New in V4 +#endif + }; + }; +}ATOM_DP_VS_MODE_V4; + +typedef struct _ATOM_DIG_TRANSMITTER_CONFIG_V4 +{ +#if ATOM_BIG_ENDIAN + UCHAR ucTransmitterSel:2; //bit7:6: =0 Dig Transmitter 1 ( Uniphy AB ) + // =1 Dig Transmitter 2 ( Uniphy CD ) + // =2 Dig Transmitter 3 ( Uniphy EF ) + UCHAR ucRefClkSource:2; //bit5:4: PPLL1 =0, PPLL2=1, DCPLL=2, EXT_CLK=3 <= New + UCHAR ucEncoderSel:1; //bit3=0: Data/Clk path source from DIGA/C/E. =1: Data/clk path source from DIGB/D/F + UCHAR ucLinkSel:1; //bit2=0: Uniphy LINKA or C or E when fDualLinkConnector=0. when fDualLinkConnector=1, it means master link of dual link is A or C or E + // =1: Uniphy LINKB or D or F when fDualLinkConnector=0. when fDualLinkConnector=1, it means master link of dual link is B or D or F + UCHAR fCoherentMode:1; //bit1=1: Coherent Mode ( for DVI/HDMI mode ) + UCHAR fDualLinkConnector:1; //bit0=1: Dual Link DVI connector +#else + UCHAR fDualLinkConnector:1; //bit0=1: Dual Link DVI connector + UCHAR fCoherentMode:1; //bit1=1: Coherent Mode ( for DVI/HDMI mode ) + UCHAR ucLinkSel:1; //bit2=0: Uniphy LINKA or C or E when fDualLinkConnector=0. when fDualLinkConnector=1, it means master link of dual link is A or C or E + // =1: Uniphy LINKB or D or F when fDualLinkConnector=0. when fDualLinkConnector=1, it means master link of dual link is B or D or F + UCHAR ucEncoderSel:1; //bit3=0: Data/Clk path source from DIGA/C/E. =1: Data/clk path source from DIGB/D/F + UCHAR ucRefClkSource:2; //bit5:4: PPLL1 =0, PPLL2=1, DCPLL=2, EXT_CLK=3 <= New + UCHAR ucTransmitterSel:2; //bit7:6: =0 Dig Transmitter 1 ( Uniphy AB ) + // =1 Dig Transmitter 2 ( Uniphy CD ) + // =2 Dig Transmitter 3 ( Uniphy EF ) +#endif +}ATOM_DIG_TRANSMITTER_CONFIG_V4; + +typedef struct _DIG_TRANSMITTER_CONTROL_PARAMETERS_V4 +{ + union + { + USHORT usPixelClock; // in 10KHz; for bios convenient + USHORT usInitInfo; // when init uniphy,lower 8bit is used for connector type defined in objectid.h + ATOM_DP_VS_MODE_V4 asMode; // DP Voltage swing mode Redefined comparing to previous version + }; + union + { + ATOM_DIG_TRANSMITTER_CONFIG_V4 acConfig; + UCHAR ucConfig; + }; + UCHAR ucAction; // define as ATOM_TRANSMITER_ACTION_XXX + UCHAR ucLaneNum; + UCHAR ucReserved[3]; +}DIG_TRANSMITTER_CONTROL_PARAMETERS_V4; + +//ucConfig +//Bit0 +#define ATOM_TRANSMITTER_CONFIG_V4_DUAL_LINK_CONNECTOR 0x01 +//Bit1 +#define ATOM_TRANSMITTER_CONFIG_V4_COHERENT 0x02 +//Bit2 +#define ATOM_TRANSMITTER_CONFIG_V4_LINK_SEL_MASK 0x04 +#define ATOM_TRANSMITTER_CONFIG_V4_LINKA 0x00 +#define ATOM_TRANSMITTER_CONFIG_V4_LINKB 0x04 +// Bit3 +#define ATOM_TRANSMITTER_CONFIG_V4_ENCODER_SEL_MASK 0x08 +#define ATOM_TRANSMITTER_CONFIG_V4_DIG1_ENCODER 0x00 +#define ATOM_TRANSMITTER_CONFIG_V4_DIG2_ENCODER 0x08 +// Bit5:4 +#define ATOM_TRANSMITTER_CONFIG_V4_REFCLK_SEL_MASK 0x30 +#define ATOM_TRANSMITTER_CONFIG_V4_P1PLL 0x00 +#define ATOM_TRANSMITTER_CONFIG_V4_P2PLL 0x10 +#define ATOM_TRANSMITTER_CONFIG_V4_DCPLL 0x20 // New in _V4 +#define ATOM_TRANSMITTER_CONFIG_V4_REFCLK_SRC_EXT 0x30 // Changed comparing to V3 +// Bit7:6 +#define ATOM_TRANSMITTER_CONFIG_V4_TRANSMITTER_SEL_MASK 0xC0 +#define ATOM_TRANSMITTER_CONFIG_V4_TRANSMITTER1 0x00 //AB +#define ATOM_TRANSMITTER_CONFIG_V4_TRANSMITTER2 0x40 //CD +#define ATOM_TRANSMITTER_CONFIG_V4_TRANSMITTER3 0x80 //EF + + +/****************************************************************************/ +// Structures used by ExternalEncoderControlTable V1.3 +// ASIC Families: Evergreen, Llano, NI +// ucTableFormatRevision=1 +// ucTableContentRevision=3 +/****************************************************************************/ + +typedef struct _EXTERNAL_ENCODER_CONTROL_PARAMETERS_V3 +{ + union{ + USHORT usPixelClock; // pixel clock in 10Khz, valid when ucAction=SETUP/ENABLE_OUTPUT + USHORT usConnectorId; // connector id, valid when ucAction = INIT + }; + UCHAR ucConfig; // indicate which encoder, and DP link rate when ucAction = SETUP/ENABLE_OUTPUT + UCHAR ucAction; // + UCHAR ucEncoderMode; // encoder mode, only used when ucAction = SETUP/ENABLE_OUTPUT + UCHAR ucLaneNum; // lane number, only used when ucAction = SETUP/ENABLE_OUTPUT + UCHAR ucBitPerColor; // output bit per color, only valid when ucAction = SETUP/ENABLE_OUTPUT and ucEncodeMode= DP + UCHAR ucReserved; +}EXTERNAL_ENCODER_CONTROL_PARAMETERS_V3; + +// ucAction +#define EXTERNAL_ENCODER_ACTION_V3_DISABLE_OUTPUT 0x00 +#define EXTERNAL_ENCODER_ACTION_V3_ENABLE_OUTPUT 0x01 +#define EXTERNAL_ENCODER_ACTION_V3_ENCODER_INIT 0x07 +#define EXTERNAL_ENCODER_ACTION_V3_ENCODER_SETUP 0x0f +#define EXTERNAL_ENCODER_ACTION_V3_ENCODER_BLANKING_OFF 0x10 +#define EXTERNAL_ENCODER_ACTION_V3_ENCODER_BLANKING 0x11 +#define EXTERNAL_ENCODER_ACTION_V3_DACLOAD_DETECTION 0x12 + +// ucConfig +#define EXTERNAL_ENCODER_CONFIG_V3_DPLINKRATE_MASK 0x03 +#define EXTERNAL_ENCODER_CONFIG_V3_DPLINKRATE_1_62GHZ 0x00 +#define EXTERNAL_ENCODER_CONFIG_V3_DPLINKRATE_2_70GHZ 0x01 +#define EXTERNAL_ENCODER_CONFIG_V3_DPLINKRATE_5_40GHZ 0x02 +#define EXTERNAL_ENCODER_CONFIG_V3_ENCODER_SEL_MASK 0x70 +#define EXTERNAL_ENCODER_CONFIG_V3_ENCODER1 0x00 +#define EXTERNAL_ENCODER_CONFIG_V3_ENCODER2 0x10 +#define EXTERNAL_ENCODER_CONFIG_V3_ENCODER3 0x20 + +typedef struct _EXTERNAL_ENCODER_CONTROL_PS_ALLOCATION_V3 +{ + EXTERNAL_ENCODER_CONTROL_PARAMETERS_V3 sExtEncoder; + ULONG ulReserved[2]; +}EXTERNAL_ENCODER_CONTROL_PS_ALLOCATION_V3; + + /****************************************************************************/ // Structures used by DAC1OuputControlTable // DAC2OuputControlTable @@ -1142,6 +1406,7 @@ typedef struct _PIXEL_CLOCK_PARAMETERS_V2 #define PIXEL_CLOCK_V4_MISC_SS_ENABLE 0x10 #define PIXEL_CLOCK_V4_MISC_COHERENT_MODE 0x20 + typedef struct _PIXEL_CLOCK_PARAMETERS_V3 { USHORT usPixelClock; // in 10kHz unit; for bios convenient = (RefClk*FB_Div)/(Ref_Div*Post_Div) @@ -1202,6 +1467,55 @@ typedef struct _PIXEL_CLOCK_PARAMETERS_V5 #define PIXEL_CLOCK_V5_MISC_HDMI_32BPP 0x08 #define PIXEL_CLOCK_V5_MISC_REF_DIV_SRC 0x10 +typedef struct _CRTC_PIXEL_CLOCK_FREQ +{ +#if ATOM_BIG_ENDIAN + ULONG ucCRTC:8; // ATOM_CRTC1~6, indicate the CRTC controller to + // drive the pixel clock. not used for DCPLL case. + ULONG ulPixelClock:24; // target the pixel clock to drive the CRTC timing. + // 0 means disable PPLL/DCPLL. Expanded to 24 bits comparing to previous version. +#else + ULONG ulPixelClock:24; // target the pixel clock to drive the CRTC timing. + // 0 means disable PPLL/DCPLL. Expanded to 24 bits comparing to previous version. + ULONG ucCRTC:8; // ATOM_CRTC1~6, indicate the CRTC controller to + // drive the pixel clock. not used for DCPLL case. +#endif +}CRTC_PIXEL_CLOCK_FREQ; + +typedef struct _PIXEL_CLOCK_PARAMETERS_V6 +{ + union{ + CRTC_PIXEL_CLOCK_FREQ ulCrtcPclkFreq; // pixel clock and CRTC id frequency + ULONG ulDispEngClkFreq; // dispclk frequency + }; + USHORT usFbDiv; // feedback divider integer part. + UCHAR ucPostDiv; // post divider. + UCHAR ucRefDiv; // Reference divider + UCHAR ucPpll; // ATOM_PPLL1/ATOM_PPLL2/ATOM_DCPLL + UCHAR ucTransmitterID; // ASIC encoder id defined in objectId.h, + // indicate which graphic encoder will be used. + UCHAR ucEncoderMode; // Encoder mode: + UCHAR ucMiscInfo; // bit[0]= Force program PPLL + // bit[1]= when VGA timing is used. + // bit[3:2]= HDMI panel bit depth: =0: 24bpp =1:30bpp, =2:32bpp + // bit[4]= RefClock source for PPLL. + // =0: XTLAIN( default mode ) + // =1: other external clock source, which is pre-defined + // by VBIOS depend on the feature required. + // bit[7:5]: reserved. + ULONG ulFbDivDecFrac; // 20 bit feedback divider decimal fraction part, range from 1~999999 ( 0.000001 to 0.999999 ) + +}PIXEL_CLOCK_PARAMETERS_V6; + +#define PIXEL_CLOCK_V6_MISC_FORCE_PROG_PPLL 0x01 +#define PIXEL_CLOCK_V6_MISC_VGA_MODE 0x02 +#define PIXEL_CLOCK_V6_MISC_HDMI_BPP_MASK 0x0c +#define PIXEL_CLOCK_V6_MISC_HDMI_24BPP 0x00 +#define PIXEL_CLOCK_V6_MISC_HDMI_36BPP 0x04 +#define PIXEL_CLOCK_V6_MISC_HDMI_30BPP 0x08 +#define PIXEL_CLOCK_V6_MISC_HDMI_48BPP 0x0c +#define PIXEL_CLOCK_V6_MISC_REF_DIV_SRC 0x10 + typedef struct _GET_DISP_PLL_STATUS_INPUT_PARAMETERS_V2 { PIXEL_CLOCK_PARAMETERS_V3 sDispClkInput; @@ -1241,10 +1555,11 @@ typedef struct _ADJUST_DISPLAY_PLL_PARAMETERS typedef struct _ADJUST_DISPLAY_PLL_INPUT_PARAMETERS_V3 { USHORT usPixelClock; // target pixel clock - UCHAR ucTransmitterID; // transmitter id defined in objectid.h + UCHAR ucTransmitterID; // GPU transmitter id defined in objectid.h UCHAR ucEncodeMode; // encoder mode: CRT, LVDS, DP, TMDS or HDMI UCHAR ucDispPllConfig; // display pll configure parameter defined as following DISPPLL_CONFIG_XXXX - UCHAR ucReserved[3]; + UCHAR ucExtTransmitterID; // external encoder id. + UCHAR ucReserved[2]; }ADJUST_DISPLAY_PLL_INPUT_PARAMETERS_V3; // usDispPllConfig v1.2 for RoadRunner @@ -1358,6 +1673,7 @@ typedef struct _SET_UP_HW_I2C_DATA_PARAMETERS /**************************************************************************/ #define SPEED_FAN_CONTROL_PS_ALLOCATION WRITE_ONE_BYTE_HW_I2C_DATA_PARAMETERS + /****************************************************************************/ // Structures used by PowerConnectorDetectionTable /****************************************************************************/ @@ -1438,6 +1754,31 @@ typedef struct _ENABLE_SPREAD_SPECTRUM_ON_PPLL_V2 #define ATOM_PPLL_SS_AMOUNT_V2_NFRAC_MASK 0x0F00 #define ATOM_PPLL_SS_AMOUNT_V2_NFRAC_SHIFT 8 +// Used by DCE5.0 + typedef struct _ENABLE_SPREAD_SPECTRUM_ON_PPLL_V3 +{ + USHORT usSpreadSpectrumAmountFrac; // SS_AMOUNT_DSFRAC New in DCE5.0 + UCHAR ucSpreadSpectrumType; // Bit[0]: 0-Down Spread,1-Center Spread. + // Bit[1]: 1-Ext. 0-Int. + // Bit[3:2]: =0 P1PLL =1 P2PLL =2 DCPLL + // Bits[7:4] reserved + UCHAR ucEnable; // ATOM_ENABLE or ATOM_DISABLE + USHORT usSpreadSpectrumAmount; // Includes SS_AMOUNT_FBDIV[7:0] and SS_AMOUNT_NFRAC_SLIP[11:8] + USHORT usSpreadSpectrumStep; // SS_STEP_SIZE_DSFRAC +}ENABLE_SPREAD_SPECTRUM_ON_PPLL_V3; + +#define ATOM_PPLL_SS_TYPE_V3_DOWN_SPREAD 0x00 +#define ATOM_PPLL_SS_TYPE_V3_CENTRE_SPREAD 0x01 +#define ATOM_PPLL_SS_TYPE_V3_EXT_SPREAD 0x02 +#define ATOM_PPLL_SS_TYPE_V3_PPLL_SEL_MASK 0x0c +#define ATOM_PPLL_SS_TYPE_V3_P1PLL 0x00 +#define ATOM_PPLL_SS_TYPE_V3_P2PLL 0x04 +#define ATOM_PPLL_SS_TYPE_V3_DCPLL 0x08 +#define ATOM_PPLL_SS_AMOUNT_V3_FBDIV_MASK 0x00FF +#define ATOM_PPLL_SS_AMOUNT_V3_FBDIV_SHIFT 0 +#define ATOM_PPLL_SS_AMOUNT_V3_NFRAC_MASK 0x0F00 +#define ATOM_PPLL_SS_AMOUNT_V3_NFRAC_SHIFT 8 + #define ENABLE_SPREAD_SPECTRUM_ON_PPLL_PS_ALLOCATION ENABLE_SPREAD_SPECTRUM_ON_PPLL /**************************************************************************/ @@ -1706,7 +2047,7 @@ typedef struct _ATOM_MASTER_LIST_OF_DATA_TABLES USHORT StandardVESA_Timing; // Only used by Bios USHORT FirmwareInfo; // Shared by various SW components,latest version 1.4 USHORT DAC_Info; // Will be obsolete from R600 - USHORT LVDS_Info; // Shared by various SW components,latest version 1.1 + USHORT LCD_Info; // Shared by various SW components,latest version 1.3, was called LVDS_Info USHORT TMDS_Info; // Will be obsolete from R600 USHORT AnalogTV_Info; // Shared by various SW components,latest version 1.1 USHORT SupportedDevicesInfo; // Will be obsolete from R600 @@ -1736,12 +2077,16 @@ typedef struct _ATOM_MASTER_LIST_OF_DATA_TABLES USHORT PowerSourceInfo; // Shared by various SW components, latest versoin 1.1 }ATOM_MASTER_LIST_OF_DATA_TABLES; +// For backward compatible +#define LVDS_Info LCD_Info + typedef struct _ATOM_MASTER_DATA_TABLE { ATOM_COMMON_TABLE_HEADER sHeader; ATOM_MASTER_LIST_OF_DATA_TABLES ListOfDataTables; }ATOM_MASTER_DATA_TABLE; + /****************************************************************************/ // Structure used in MultimediaCapabilityInfoTable /****************************************************************************/ @@ -1776,6 +2121,7 @@ typedef struct _ATOM_MULTIMEDIA_CONFIG_INFO UCHAR ucVideoInput4Info;// Video Input 4 Type (1:0) F/B setting (2) physical connector ID (5:3) reserved (7:6) }ATOM_MULTIMEDIA_CONFIG_INFO; + /****************************************************************************/ // Structures used in FirmwareInfoTable /****************************************************************************/ @@ -2031,8 +2377,47 @@ typedef struct _ATOM_FIRMWARE_INFO_V2_1 UCHAR ucReserved4[3]; }ATOM_FIRMWARE_INFO_V2_1; +//the structure below to be used from NI +//ucTableFormatRevision=2 +//ucTableContentRevision=2 +typedef struct _ATOM_FIRMWARE_INFO_V2_2 +{ + ATOM_COMMON_TABLE_HEADER sHeader; + ULONG ulFirmwareRevision; + ULONG ulDefaultEngineClock; //In 10Khz unit + ULONG ulDefaultMemoryClock; //In 10Khz unit + ULONG ulReserved[2]; + ULONG ulReserved1; //Was ulMaxEngineClockPLL_Output; //In 10Khz unit* + ULONG ulReserved2; //Was ulMaxMemoryClockPLL_Output; //In 10Khz unit* + ULONG ulMaxPixelClockPLL_Output; //In 10Khz unit + ULONG ulBinaryAlteredInfo; //Was ulASICMaxEngineClock ? + ULONG ulDefaultDispEngineClkFreq; //In 10Khz unit. This is the frequency before DCDTO, corresponding to usBootUpVDDCVoltage. + UCHAR ucReserved3; //Was ucASICMaxTemperature; + UCHAR ucMinAllowedBL_Level; + USHORT usBootUpVDDCVoltage; //In MV unit + USHORT usLcdMinPixelClockPLL_Output; // In MHz unit + USHORT usLcdMaxPixelClockPLL_Output; // In MHz unit + ULONG ulReserved4; //Was ulAsicMaximumVoltage + ULONG ulMinPixelClockPLL_Output; //In 10Khz unit + ULONG ulReserved5; //Was usMinEngineClockPLL_Input and usMaxEngineClockPLL_Input + ULONG ulReserved6; //Was usMinEngineClockPLL_Output and usMinMemoryClockPLL_Input + ULONG ulReserved7; //Was usMaxMemoryClockPLL_Input and usMinMemoryClockPLL_Output + USHORT usReserved11; //Was usMaxPixelClock; //In 10Khz unit, Max. Pclk used only for DAC + USHORT usMinPixelClockPLL_Input; //In 10Khz unit + USHORT usMaxPixelClockPLL_Input; //In 10Khz unit + USHORT usBootUpVDDCIVoltage; //In unit of mv; Was usMinPixelClockPLL_Output; + ATOM_FIRMWARE_CAPABILITY_ACCESS usFirmwareCapability; + USHORT usCoreReferenceClock; //In 10Khz unit + USHORT usMemoryReferenceClock; //In 10Khz unit + USHORT usUniphyDPModeExtClkFreq; //In 10Khz unit, if it is 0, In DP Mode Uniphy Input clock from internal PPLL, otherwise Input clock from external Spread clock + UCHAR ucMemoryModule_ID; //Indicate what is the board design + UCHAR ucReserved9[3]; + USHORT usBootUpMVDDCVoltage; //In unit of mv; Was usMinPixelClockPLL_Output; + USHORT usReserved12; + ULONG ulReserved10[3]; // New added comparing to previous version +}ATOM_FIRMWARE_INFO_V2_2; -#define ATOM_FIRMWARE_INFO_LAST ATOM_FIRMWARE_INFO_V2_1 +#define ATOM_FIRMWARE_INFO_LAST ATOM_FIRMWARE_INFO_V2_2 /****************************************************************************/ // Structures used in IntegratedSystemInfoTable @@ -2212,7 +2597,7 @@ ulDockingPinCFGInfo: [15:0]-Bus/Device/Function # to CFG to read this Docking Pi ucDockingPinBit: which bit in this register to read the pin status; ucDockingPinPolarity:Polarity of the pin when docked; -ulCPUCapInfo: [7:0]=1:Griffin;[7:0]=2:Greyhound;[7:0]=3:K8, other bits reserved for now and must be 0x0 +ulCPUCapInfo: [7:0]=1:Griffin;[7:0]=2:Greyhound;[7:0]=3:K8, [7:0]=4:Pharaoh, other bits reserved for now and must be 0x0 usNumberOfCyclesInPeriod:Indicate how many cycles when PWM duty is 100%. @@ -2250,6 +2635,14 @@ usMinUpStreamHTLinkWidth: Asymmetric link width support in the future, to rep usMinDownStreamHTLinkWidth: same as above. */ +// ATOM_INTEGRATED_SYSTEM_INFO::ulCPUCapInfo - CPU type definition +#define INTEGRATED_SYSTEM_INFO__UNKNOWN_CPU 0 +#define INTEGRATED_SYSTEM_INFO__AMD_CPU__GRIFFIN 1 +#define INTEGRATED_SYSTEM_INFO__AMD_CPU__GREYHOUND 2 +#define INTEGRATED_SYSTEM_INFO__AMD_CPU__K8 3 +#define INTEGRATED_SYSTEM_INFO__AMD_CPU__PHARAOH 4 + +#define INTEGRATED_SYSTEM_INFO__AMD_CPU__MAX_CODE INTEGRATED_SYSTEM_INFO__AMD_CPU__PHARAOH // this deff reflects max defined CPU code #define SYSTEM_CONFIG_POWEREXPRESS_ENABLE 0x00000001 #define SYSTEM_CONFIG_RUN_AT_OVERDRIVE_ENGINE 0x00000002 @@ -2778,8 +3171,88 @@ typedef struct _ATOM_LVDS_INFO_V12 #define PANEL_RANDOM_DITHER 0x80 #define PANEL_RANDOM_DITHER_MASK 0x80 +#define ATOM_LVDS_INFO_LAST ATOM_LVDS_INFO_V12 // no need to change this + +/****************************************************************************/ +// Structures used by LCD_InfoTable V1.3 Note: previous version was called ATOM_LVDS_INFO_V12 +// ASIC Families: NI +// ucTableFormatRevision=1 +// ucTableContentRevision=3 +/****************************************************************************/ +typedef struct _ATOM_LCD_INFO_V13 +{ + ATOM_COMMON_TABLE_HEADER sHeader; + ATOM_DTD_FORMAT sLCDTiming; + USHORT usExtInfoTableOffset; + USHORT usSupportedRefreshRate; //Refer to panel info table in ATOMBIOS extension Spec. + ULONG ulReserved0; + UCHAR ucLCD_Misc; // Reorganized in V13 + // Bit0: {=0:single, =1:dual}, + // Bit1: {=0:LDI format for RGB888, =1 FPDI format for RGB888} // was {=0:666RGB, =1:888RGB}, + // Bit3:2: {Grey level} + // Bit6:4 Color Bit Depth definition (see below definition in EDID V1.4 @BYTE 14h) + // Bit7 Reserved. was for ATOM_PANEL_MISC_API_ENABLED, still need it? + UCHAR ucPanelDefaultRefreshRate; + UCHAR ucPanelIdentification; + UCHAR ucSS_Id; + USHORT usLCDVenderID; + USHORT usLCDProductID; + UCHAR ucLCDPanel_SpecialHandlingCap; // Reorganized in V13 + // Bit0: Once DAL sees this CAP is set, it will read EDID from LCD on its own + // Bit1: See LCDPANEL_CAP_DRR_SUPPORTED + // Bit2: a quick reference whether an embadded panel (LCD1 ) is LVDS (0) or eDP (1) + // Bit7-3: Reserved + UCHAR ucPanelInfoSize; // start from ATOM_DTD_FORMAT to end of panel info, include ExtInfoTable + USHORT usBacklightPWM; // Backlight PWM in Hz. New in _V13 + + UCHAR ucPowerSequenceDIGONtoDE_in4Ms; + UCHAR ucPowerSequenceDEtoVARY_BL_in4Ms; + UCHAR ucPowerSequenceDEtoDIGON_in4Ms; + UCHAR ucPowerSequenceVARY_BLtoDE_in4Ms; + + UCHAR ucOffDelay_in4Ms; + UCHAR ucPowerSequenceVARY_BLtoBLON_in4Ms; + UCHAR ucPowerSequenceBLONtoVARY_BL_in4Ms; + UCHAR ucReserved1; + + ULONG ulReserved[4]; +}ATOM_LCD_INFO_V13; + +#define ATOM_LCD_INFO_LAST ATOM_LCD_INFO_V13 + +//Definitions for ucLCD_Misc +#define ATOM_PANEL_MISC_V13_DUAL 0x00000001 +#define ATOM_PANEL_MISC_V13_FPDI 0x00000002 +#define ATOM_PANEL_MISC_V13_GREY_LEVEL 0x0000000C +#define ATOM_PANEL_MISC_V13_GREY_LEVEL_SHIFT 2 +#define ATOM_PANEL_MISC_V13_COLOR_BIT_DEPTH_MASK 0x70 +#define ATOM_PANEL_MISC_V13_6BIT_PER_COLOR 0x10 +#define ATOM_PANEL_MISC_V13_8BIT_PER_COLOR 0x20 + +//Color Bit Depth definition in EDID V1.4 @BYTE 14h +//Bit 6 5 4 + // 0 0 0 - Color bit depth is undefined + // 0 0 1 - 6 Bits per Primary Color + // 0 1 0 - 8 Bits per Primary Color + // 0 1 1 - 10 Bits per Primary Color + // 1 0 0 - 12 Bits per Primary Color + // 1 0 1 - 14 Bits per Primary Color + // 1 1 0 - 16 Bits per Primary Color + // 1 1 1 - Reserved + +//Definitions for ucLCDPanel_SpecialHandlingCap: + +//Once DAL sees this CAP is set, it will read EDID from LCD on its own instead of using sLCDTiming in ATOM_LVDS_INFO_V12. +//Other entries in ATOM_LVDS_INFO_V12 are still valid/useful to DAL +#define LCDPANEL_CAP_V13_READ_EDID 0x1 // = LCDPANEL_CAP_READ_EDID no change comparing to previous version -#define ATOM_LVDS_INFO_LAST ATOM_LVDS_INFO_V12 +//If a design supports DRR (dynamic refresh rate) on internal panels (LVDS or EDP), this cap is set in ucLCDPanel_SpecialHandlingCap together +//with multiple supported refresh rates@usSupportedRefreshRate. This cap should not be set when only slow refresh rate is supported (static +//refresh rate switch by SW. This is only valid from ATOM_LVDS_INFO_V12 +#define LCDPANEL_CAP_V13_DRR_SUPPORTED 0x2 // = LCDPANEL_CAP_DRR_SUPPORTED no change comparing to previous version + +//Use this cap bit for a quick reference whether an embadded panel (LCD1 ) is LVDS or eDP. +#define LCDPANEL_CAP_V13_eDP 0x4 // = LCDPANEL_CAP_eDP no change comparing to previous version typedef struct _ATOM_PATCH_RECORD_MODE { @@ -2944,9 +3417,9 @@ typedef struct _ATOM_DPCD_INFO #define MAX_DTD_MODE_IN_VRAM 6 #define ATOM_DTD_MODE_SUPPORT_TBL_SIZE (MAX_DTD_MODE_IN_VRAM*28) //28= (SIZEOF ATOM_DTD_FORMAT) #define ATOM_STD_MODE_SUPPORT_TBL_SIZE 32*8 //32 is a predefined number,8= (SIZEOF ATOM_STD_FORMAT) -#define DFP_ENCODER_TYPE_OFFSET 0x80 -#define DP_ENCODER_LANE_NUM_OFFSET 0x84 -#define DP_ENCODER_LINK_RATE_OFFSET 0x88 +//20 bytes for Encoder Type and DPCD in STD EDID area +#define DFP_ENCODER_TYPE_OFFSET (ATOM_EDID_RAW_DATASIZE + ATOM_DTD_MODE_SUPPORT_TBL_SIZE + ATOM_STD_MODE_SUPPORT_TBL_SIZE - 20) +#define ATOM_DP_DPCD_OFFSET (DFP_ENCODER_TYPE_OFFSET + 4 ) #define ATOM_HWICON1_SURFACE_ADDR 0 #define ATOM_HWICON2_SURFACE_ADDR (ATOM_HWICON1_SURFACE_ADDR + ATOM_HWICON_SURFACE_SIZE) @@ -2997,14 +3470,16 @@ typedef struct _ATOM_DPCD_INFO #define ATOM_DFP5_DTD_MODE_TBL_ADDR (ATOM_DFP5_EDID_ADDR + ATOM_EDID_RAW_DATASIZE) #define ATOM_DFP5_STD_MODE_TBL_ADDR (ATOM_DFP5_DTD_MODE_TBL_ADDR + ATOM_DTD_MODE_SUPPORT_TBL_SIZE) -#define ATOM_DP_TRAINING_TBL_ADDR (ATOM_DFP5_STD_MODE_TBL_ADDR+ATOM_STD_MODE_SUPPORT_TBL_SIZE) +#define ATOM_DP_TRAINING_TBL_ADDR (ATOM_DFP5_STD_MODE_TBL_ADDR + ATOM_STD_MODE_SUPPORT_TBL_SIZE) -#define ATOM_STACK_STORAGE_START (ATOM_DP_TRAINING_TBL_ADDR+256) -#define ATOM_STACK_STORAGE_END ATOM_STACK_STORAGE_START+512 +#define ATOM_STACK_STORAGE_START (ATOM_DP_TRAINING_TBL_ADDR + 1024) +#define ATOM_STACK_STORAGE_END ATOM_STACK_STORAGE_START + 512 //The size below is in Kb! #define ATOM_VRAM_RESERVE_SIZE ((((ATOM_STACK_STORAGE_END - ATOM_HWICON1_SURFACE_ADDR)>>10)+4)&0xFFFC) +#define ATOM_VRAM_RESERVE_V2_SIZE 32 + #define ATOM_VRAM_OPERATION_FLAGS_MASK 0xC0000000L #define ATOM_VRAM_OPERATION_FLAGS_SHIFT 30 #define ATOM_VRAM_BLOCK_NEEDS_NO_RESERVATION 0x1 @@ -3206,6 +3681,15 @@ typedef struct _ATOM_DISPLAY_OBJECT_PATH USHORT usGraphicObjIds[1]; //1st Encoder Obj source from GPU to last Graphic Obj destinate to connector. }ATOM_DISPLAY_OBJECT_PATH; +typedef struct _ATOM_DISPLAY_EXTERNAL_OBJECT_PATH +{ + USHORT usDeviceTag; //supported device + USHORT usSize; //the size of ATOM_DISPLAY_OBJECT_PATH + USHORT usConnObjectId; //Connector Object ID + USHORT usGPUObjectId; //GPU ID + USHORT usGraphicObjIds[2]; //usGraphicObjIds[0]= GPU internal encoder, usGraphicObjIds[1]= external encoder +}ATOM_DISPLAY_EXTERNAL_OBJECT_PATH; + typedef struct _ATOM_DISPLAY_OBJECT_PATH_TABLE { UCHAR ucNumOfDispPath; @@ -3261,6 +3745,47 @@ typedef struct _ATOM_SRC_DST_TABLE_FOR_ONE_OBJECT //usSrcDstTableOffset #define EXT_AUXDDC_LUTINDEX_7 7 #define MAX_NUMBER_OF_EXT_AUXDDC_LUT_ENTRIES (EXT_AUXDDC_LUTINDEX_7+1) +//ucChannelMapping are defined as following +//for DP connector, eDP, DP to VGA/LVDS +//Bit[1:0]: Define which pin connect to DP connector DP_Lane0, =0: source from GPU pin TX0, =1: from GPU pin TX1, =2: from GPU pin TX2, =3 from GPU pin TX3 +//Bit[3:2]: Define which pin connect to DP connector DP_Lane1, =0: source from GPU pin TX0, =1: from GPU pin TX1, =2: from GPU pin TX2, =3 from GPU pin TX3 +//Bit[5:4]: Define which pin connect to DP connector DP_Lane2, =0: source from GPU pin TX0, =1: from GPU pin TX1, =2: from GPU pin TX2, =3 from GPU pin TX3 +//Bit[7:6]: Define which pin connect to DP connector DP_Lane3, =0: source from GPU pin TX0, =1: from GPU pin TX1, =2: from GPU pin TX2, =3 from GPU pin TX3 +typedef struct _ATOM_DP_CONN_CHANNEL_MAPPING +{ +#if ATOM_BIG_ENDIAN + UCHAR ucDP_Lane3_Source:2; + UCHAR ucDP_Lane2_Source:2; + UCHAR ucDP_Lane1_Source:2; + UCHAR ucDP_Lane0_Source:2; +#else + UCHAR ucDP_Lane0_Source:2; + UCHAR ucDP_Lane1_Source:2; + UCHAR ucDP_Lane2_Source:2; + UCHAR ucDP_Lane3_Source:2; +#endif +}ATOM_DP_CONN_CHANNEL_MAPPING; + +//for DVI/HDMI, in dual link case, both links have to have same mapping. +//Bit[1:0]: Define which pin connect to DVI connector data Lane2, =0: source from GPU pin TX0, =1: from GPU pin TX1, =2: from GPU pin TX2, =3 from GPU pin TX3 +//Bit[3:2]: Define which pin connect to DVI connector data Lane1, =0: source from GPU pin TX0, =1: from GPU pin TX1, =2: from GPU pin TX2, =3 from GPU pin TX3 +//Bit[5:4]: Define which pin connect to DVI connector data Lane0, =0: source from GPU pin TX0, =1: from GPU pin TX1, =2: from GPU pin TX2, =3 from GPU pin TX3 +//Bit[7:6]: Define which pin connect to DVI connector clock lane, =0: source from GPU pin TX0, =1: from GPU pin TX1, =2: from GPU pin TX2, =3 from GPU pin TX3 +typedef struct _ATOM_DVI_CONN_CHANNEL_MAPPING +{ +#if ATOM_BIG_ENDIAN + UCHAR ucDVI_CLK_Source:2; + UCHAR ucDVI_DATA0_Source:2; + UCHAR ucDVI_DATA1_Source:2; + UCHAR ucDVI_DATA2_Source:2; +#else + UCHAR ucDVI_DATA2_Source:2; + UCHAR ucDVI_DATA1_Source:2; + UCHAR ucDVI_DATA0_Source:2; + UCHAR ucDVI_CLK_Source:2; +#endif +}ATOM_DVI_CONN_CHANNEL_MAPPING; + typedef struct _EXT_DISPLAY_PATH { USHORT usDeviceTag; //A bit vector to show what devices are supported @@ -3269,7 +3794,13 @@ typedef struct _EXT_DISPLAY_PATH UCHAR ucExtAUXDDCLutIndex; //An index into external AUX/DDC channel LUT UCHAR ucExtHPDPINLutIndex; //An index into external HPD pin LUT USHORT usExtEncoderObjId; //external encoder object id - USHORT usReserved[3]; + union{ + UCHAR ucChannelMapping; // if ucChannelMapping=0, using default one to one mapping + ATOM_DP_CONN_CHANNEL_MAPPING asDPMapping; + ATOM_DVI_CONN_CHANNEL_MAPPING asDVIMapping; + }; + UCHAR ucReserved; + USHORT usReserved[2]; }EXT_DISPLAY_PATH; #define NUMBER_OF_UCHAR_FOR_GUID 16 @@ -3281,7 +3812,8 @@ typedef struct _ATOM_EXTERNAL_DISPLAY_CONNECTION_INFO UCHAR ucGuid [NUMBER_OF_UCHAR_FOR_GUID]; // a GUID is a 16 byte long string EXT_DISPLAY_PATH sPath[MAX_NUMBER_OF_EXT_DISPLAY_PATH]; // total of fixed 7 entries. UCHAR ucChecksum; // a simple Checksum of the sum of whole structure equal to 0x0. - UCHAR Reserved [7]; // for potential expansion + UCHAR uc3DStereoPinId; // use for eDP panel + UCHAR Reserved [6]; // for potential expansion }ATOM_EXTERNAL_DISPLAY_CONNECTION_INFO; //Related definitions, all records are differnt but they have a commond header @@ -3311,10 +3843,11 @@ typedef struct _ATOM_COMMON_RECORD_HEADER #define ATOM_CONNECTOR_AUXDDC_LUT_RECORD_TYPE 17 //This is for the case when connectors are not known to object table #define ATOM_OBJECT_LINK_RECORD_TYPE 18 //Once this record is present under one object, it indicats the oobject is linked to another obj described by the record #define ATOM_CONNECTOR_REMOTE_CAP_RECORD_TYPE 19 +#define ATOM_ENCODER_CAP_RECORD_TYPE 20 //Must be updated when new record type is added,equal to that record definition! -#define ATOM_MAX_OBJECT_RECORD_NUMBER ATOM_CONNECTOR_REMOTE_CAP_RECORD_TYPE +#define ATOM_MAX_OBJECT_RECORD_NUMBER ATOM_ENCODER_CAP_RECORD_TYPE typedef struct _ATOM_I2C_RECORD { @@ -3441,6 +3974,26 @@ typedef struct _ATOM_ENCODER_DVO_CF_RECORD UCHAR ucPadding[2]; }ATOM_ENCODER_DVO_CF_RECORD; +// Bit maps for ATOM_ENCODER_CAP_RECORD.ucEncoderCap +#define ATOM_ENCODER_CAP_RECORD_HBR2 0x01 // DP1.2 HBR2 is supported by this path + +typedef struct _ATOM_ENCODER_CAP_RECORD +{ + ATOM_COMMON_RECORD_HEADER sheader; + union { + USHORT usEncoderCap; + struct { +#if ATOM_BIG_ENDIAN + USHORT usReserved:15; // Bit1-15 may be defined for other capability in future + USHORT usHBR2Cap:1; // Bit0 is for DP1.2 HBR2 capability. +#else + USHORT usHBR2Cap:1; // Bit0 is for DP1.2 HBR2 capability. + USHORT usReserved:15; // Bit1-15 may be defined for other capability in future +#endif + }; + }; +}ATOM_ENCODER_CAP_RECORD; + // value for ATOM_CONNECTOR_CF_RECORD.ucConnectedDvoBundle #define ATOM_CONNECTOR_CF_RECORD_CONNECTED_UPPER12BITBUNDLEA 1 #define ATOM_CONNECTOR_CF_RECORD_CONNECTED_LOWER12BITBUNDLEB 2 @@ -3580,6 +4133,11 @@ typedef struct _ATOM_VOLTAGE_CONTROL #define VOLTAGE_CONTROL_ID_DAC 0x02 //I2C control, used for R5xx/R6xx MVDDC,MVDDQ or VDDCI #define VOLTAGE_CONTROL_ID_VT116xM 0x03 //I2C control, used for R6xx Core Voltage #define VOLTAGE_CONTROL_ID_DS4402 0x04 +#define VOLTAGE_CONTROL_ID_UP6266 0x05 +#define VOLTAGE_CONTROL_ID_SCORPIO 0x06 +#define VOLTAGE_CONTROL_ID_VT1556M 0x07 +#define VOLTAGE_CONTROL_ID_CHL822x 0x08 +#define VOLTAGE_CONTROL_ID_VT1586M 0x09 typedef struct _ATOM_VOLTAGE_OBJECT { @@ -3670,66 +4228,157 @@ typedef struct _ATOM_POWER_SOURCE_INFO #define POWER_SENSOR_GPIO 0x01 #define POWER_SENSOR_I2C 0x02 +typedef struct _ATOM_CLK_VOLT_CAPABILITY +{ + ULONG ulVoltageIndex; // The Voltage Index indicated by FUSE, same voltage index shared with SCLK DPM fuse table + ULONG ulMaximumSupportedCLK; // Maximum clock supported with specified voltage index, unit in 10kHz +}ATOM_CLK_VOLT_CAPABILITY; + +typedef struct _ATOM_AVAILABLE_SCLK_LIST +{ + ULONG ulSupportedSCLK; // Maximum clock supported with specified voltage index, unit in 10kHz + USHORT usVoltageIndex; // The Voltage Index indicated by FUSE for specified SCLK + USHORT usVoltageID; // The Voltage ID indicated by FUSE for specified SCLK +}ATOM_AVAILABLE_SCLK_LIST; + +// ATOM_INTEGRATED_SYSTEM_INFO_V6 ulSystemConfig cap definition +#define ATOM_IGP_INFO_V6_SYSTEM_CONFIG__PCIE_POWER_GATING_ENABLE 1 // refer to ulSystemConfig bit[0] + +// this IntegrateSystemInfoTable is used for Liano/Ontario APU typedef struct _ATOM_INTEGRATED_SYSTEM_INFO_V6 { ATOM_COMMON_TABLE_HEADER sHeader; ULONG ulBootUpEngineClock; ULONG ulDentistVCOFreq; ULONG ulBootUpUMAClock; - ULONG ulReserved1[8]; + ATOM_CLK_VOLT_CAPABILITY sDISPCLK_Voltage[4]; ULONG ulBootUpReqDisplayVector; ULONG ulOtherDisplayMisc; ULONG ulGPUCapInfo; - ULONG ulReserved2[3]; + ULONG ulSB_MMIO_Base_Addr; + USHORT usRequestedPWMFreqInHz; + UCHAR ucHtcTmpLmt; + UCHAR ucHtcHystLmt; + ULONG ulMinEngineClock; ULONG ulSystemConfig; ULONG ulCPUCapInfo; - USHORT usMaxNBVoltage; - USHORT usMinNBVoltage; - USHORT usBootUpNBVoltage; - USHORT usExtDispConnInfoOffset; - UCHAR ucHtcTmpLmt; - UCHAR ucTjOffset; + USHORT usNBP0Voltage; + USHORT usNBP1Voltage; + USHORT usBootUpNBVoltage; + USHORT usExtDispConnInfoOffset; + USHORT usPanelRefreshRateRange; UCHAR ucMemoryType; UCHAR ucUMAChannelNumber; ULONG ulCSR_M3_ARB_CNTL_DEFAULT[10]; ULONG ulCSR_M3_ARB_CNTL_UVD[10]; ULONG ulCSR_M3_ARB_CNTL_FS3D[10]; - ULONG ulReserved3[42]; + ATOM_AVAILABLE_SCLK_LIST sAvail_SCLK[5]; + ULONG ulGMCRestoreResetTime; + ULONG ulMinimumNClk; + ULONG ulIdleNClk; + ULONG ulDDR_DLL_PowerUpTime; + ULONG ulDDR_PLL_PowerUpTime; + USHORT usPCIEClkSSPercentage; + USHORT usPCIEClkSSType; + USHORT usLvdsSSPercentage; + USHORT usLvdsSSpreadRateIn10Hz; + USHORT usHDMISSPercentage; + USHORT usHDMISSpreadRateIn10Hz; + USHORT usDVISSPercentage; + USHORT usDVISSpreadRateIn10Hz; + ULONG ulReserved3[21]; ATOM_EXTERNAL_DISPLAY_CONNECTION_INFO sExtDispConnInfo; }ATOM_INTEGRATED_SYSTEM_INFO_V6; +// ulGPUCapInfo +#define INTEGRATED_SYSTEM_INFO_V6_GPUCAPINFO__TMDSHDMI_COHERENT_SINGLEPLL_MODE 0x01 +#define INTEGRATED_SYSTEM_INFO_V6_GPUCAPINFO__DISABLE_AUX_HW_MODE_DETECTION 0x08 + +// ulOtherDisplayMisc +#define INTEGRATED_SYSTEM_INFO__GET_EDID_CALLBACK_FUNC_SUPPORT 0x01 + + /********************************************************************************************************************** -// ATOM_INTEGRATED_SYSTEM_INFO_V6 Description -//ulBootUpEngineClock: VBIOS bootup Engine clock frequency, in 10kHz unit. -//ulDentistVCOFreq: Dentist VCO clock in 10kHz unit. -//ulBootUpUMAClock: System memory boot up clock frequency in 10Khz unit. -//ulReserved1[8] Reserved by now, must be 0x0. -//ulBootUpReqDisplayVector VBIOS boot up display IDs -// ATOM_DEVICE_CRT1_SUPPORT 0x0001 -// ATOM_DEVICE_CRT2_SUPPORT 0x0010 -// ATOM_DEVICE_DFP1_SUPPORT 0x0008 -// ATOM_DEVICE_DFP6_SUPPORT 0x0040 -// ATOM_DEVICE_DFP2_SUPPORT 0x0080 -// ATOM_DEVICE_DFP3_SUPPORT 0x0200 -// ATOM_DEVICE_DFP4_SUPPORT 0x0400 -// ATOM_DEVICE_DFP5_SUPPORT 0x0800 -// ATOM_DEVICE_LCD1_SUPPORT 0x0002 -//ulOtherDisplayMisc Other display related flags, not defined yet. -//ulGPUCapInfo TBD -//ulReserved2[3] must be 0x0 for the reserved. -//ulSystemConfig TBD -//ulCPUCapInfo TBD -//usMaxNBVoltage High NB voltage in unit of mv, calculated using current VDDNB (D24F2xDC) and VDDNB offset fuse. -//usMinNBVoltage Low NB voltage in unit of mv, calculated using current VDDNB (D24F2xDC) and VDDNB offset fuse. -//usBootUpNBVoltage Boot up NB voltage in unit of mv. -//ucHtcTmpLmt Bit [22:16] of D24F3x64 Thermal Control (HTC) Register. -//ucTjOffset Bit [28:22] of D24F3xE4 Thermtrip Status Register,may not be needed. -//ucMemoryType [3:0]=1:DDR1;=2:DDR2;=3:DDR3.[7:4] is reserved. -//ucUMAChannelNumber System memory channel numbers. -//usExtDispConnectionInfoOffset ATOM_EXTERNAL_DISPLAY_CONNECTION_INFO offset relative to beginning of this table. -//ulCSR_M3_ARB_CNTL_DEFAULT[10] Arrays with values for CSR M3 arbiter for default -//ulCSR_M3_ARB_CNTL_UVD[10] Arrays with values for CSR M3 arbiter for UVD playback. -//ulCSR_M3_ARB_CNTL_FS3D[10] Arrays with values for CSR M3 arbiter for Full Screen 3D applications. + ATOM_INTEGRATED_SYSTEM_INFO_V6 Description +ulBootUpEngineClock: VBIOS bootup Engine clock frequency, in 10kHz unit. if it is equal 0, then VBIOS use pre-defined bootup engine clock +ulDentistVCOFreq: Dentist VCO clock in 10kHz unit. +ulBootUpUMAClock: System memory boot up clock frequency in 10Khz unit. +sDISPCLK_Voltage: Report Display clock voltage requirement. + +ulBootUpReqDisplayVector: VBIOS boot up display IDs, following are supported devices in Liano/Ontaio projects: + ATOM_DEVICE_CRT1_SUPPORT 0x0001 + ATOM_DEVICE_CRT2_SUPPORT 0x0010 + ATOM_DEVICE_DFP1_SUPPORT 0x0008 + ATOM_DEVICE_DFP6_SUPPORT 0x0040 + ATOM_DEVICE_DFP2_SUPPORT 0x0080 + ATOM_DEVICE_DFP3_SUPPORT 0x0200 + ATOM_DEVICE_DFP4_SUPPORT 0x0400 + ATOM_DEVICE_DFP5_SUPPORT 0x0800 + ATOM_DEVICE_LCD1_SUPPORT 0x0002 +ulOtherDisplayMisc: Other display related flags, not defined yet. +ulGPUCapInfo: bit[0]=0: TMDS/HDMI Coherent Mode use cascade PLL mode. + =1: TMDS/HDMI Coherent Mode use signel PLL mode. + bit[3]=0: Enable HW AUX mode detection logic + =1: Disable HW AUX mode dettion logic +ulSB_MMIO_Base_Addr: Physical Base address to SB MMIO space. Driver needs to initialize it for SMU usage. + +usRequestedPWMFreqInHz: When it's set to 0x0 by SBIOS: the LCD BackLight is not controlled by GPU(SW). + Any attempt to change BL using VBIOS function or enable VariBri from PP table is not effective since ATOM_BIOS_INFO_BL_CONTROLLED_BY_GPU==0; + + When it's set to a non-zero frequency, the BackLight is controlled by GPU (SW) in one of two ways below: + 1. SW uses the GPU BL PWM output to control the BL, in chis case, this non-zero frequency determines what freq GPU should use; + VBIOS will set up proper PWM frequency and ATOM_BIOS_INFO_BL_CONTROLLED_BY_GPU==1,as the result, + Changing BL using VBIOS function is functional in both driver and non-driver present environment; + and enabling VariBri under the driver environment from PP table is optional. + + 2. SW uses other means to control BL (like DPCD),this non-zero frequency serves as a flag only indicating + that BL control from GPU is expected. + VBIOS will NOT set up PWM frequency but make ATOM_BIOS_INFO_BL_CONTROLLED_BY_GPU==1 + Changing BL using VBIOS function could be functional in both driver and non-driver present environment,but + it's per platform + and enabling VariBri under the driver environment from PP table is optional. + +ucHtcTmpLmt: Refer to D18F3x64 bit[22:16], HtcTmpLmt. + Threshold on value to enter HTC_active state. +ucHtcHystLmt: Refer to D18F3x64 bit[27:24], HtcHystLmt. + To calculate threshold off value to exit HTC_active state, which is Threshold on vlaue minus ucHtcHystLmt. +ulMinEngineClock: Minimum SCLK allowed in 10kHz unit. This is calculated based on WRCK Fuse settings. +ulSystemConfig: Bit[0]=0: PCIE Power Gating Disabled + =1: PCIE Power Gating Enabled + Bit[1]=0: DDR-DLL shut-down feature disabled. + 1: DDR-DLL shut-down feature enabled. + Bit[2]=0: DDR-PLL Power down feature disabled. + 1: DDR-PLL Power down feature enabled. +ulCPUCapInfo: TBD +usNBP0Voltage: VID for voltage on NB P0 State +usNBP1Voltage: VID for voltage on NB P1 State +usBootUpNBVoltage: Voltage Index of GNB voltage configured by SBIOS, which is suffcient to support VBIOS DISPCLK requirement. +usExtDispConnInfoOffset: Offset to sExtDispConnInfo inside the structure +usPanelRefreshRateRange: Bit vector for LCD supported refresh rate range. If DRR is requestd by the platform, at least two bits need to be set + to indicate a range. + SUPPORTED_LCD_REFRESHRATE_30Hz 0x0004 + SUPPORTED_LCD_REFRESHRATE_40Hz 0x0008 + SUPPORTED_LCD_REFRESHRATE_50Hz 0x0010 + SUPPORTED_LCD_REFRESHRATE_60Hz 0x0020 +ucMemoryType: [3:0]=1:DDR1;=2:DDR2;=3:DDR3.[7:4] is reserved. +ucUMAChannelNumber: System memory channel numbers. +ulCSR_M3_ARB_CNTL_DEFAULT[10]: Arrays with values for CSR M3 arbiter for default +ulCSR_M3_ARB_CNTL_UVD[10]: Arrays with values for CSR M3 arbiter for UVD playback. +ulCSR_M3_ARB_CNTL_FS3D[10]: Arrays with values for CSR M3 arbiter for Full Screen 3D applications. +sAvail_SCLK[5]: Arrays to provide availabe list of SLCK and corresponding voltage, order from low to high +ulGMCRestoreResetTime: GMC power restore and GMC reset time to calculate data reconnection latency. Unit in ns. +ulMinimumNClk: Minimum NCLK speed among all NB-Pstates to calcualte data reconnection latency. Unit in 10kHz. +ulIdleNClk: NCLK speed while memory runs in self-refresh state. Unit in 10kHz. +ulDDR_DLL_PowerUpTime: DDR PHY DLL power up time. Unit in ns. +ulDDR_PLL_PowerUpTime: DDR PHY PLL power up time. Unit in ns. +usPCIEClkSSPercentage: PCIE Clock Spred Spectrum Percentage in unit 0.01%; 100 mean 1%. +usPCIEClkSSType: PCIE Clock Spred Spectrum Type. 0 for Down spread(default); 1 for Center spread. +usLvdsSSPercentage: LVDS panel ( not include eDP ) Spread Spectrum Percentage in unit of 0.01%, =0, use VBIOS default setting. +usLvdsSSpreadRateIn10Hz: LVDS panel ( not include eDP ) Spread Spectrum frequency in unit of 10Hz, =0, use VBIOS default setting. +usHDMISSPercentage: HDMI Spread Spectrum Percentage in unit 0.01%; 100 mean 1%, =0, use VBIOS default setting. +usHDMISSpreadRateIn10Hz: HDMI Spread Spectrum frequency in unit of 10Hz, =0, use VBIOS default setting. +usDVISSPercentage: DVI Spread Spectrum Percentage in unit 0.01%; 100 mean 1%, =0, use VBIOS default setting. +usDVISSpreadRateIn10Hz: DVI Spread Spectrum frequency in unit of 10Hz, =0, use VBIOS default setting. **********************************************************************************************************************/ /**************************************************************************/ @@ -3790,6 +4439,7 @@ typedef struct _ATOM_ASIC_SS_ASSIGNMENT #define ASIC_INTERNAL_SS_ON_LVDS 6 #define ASIC_INTERNAL_SS_ON_DP 7 #define ASIC_INTERNAL_SS_ON_DCPLL 8 +#define ASIC_EXTERNAL_SS_ON_DP_CLOCK 9 typedef struct _ATOM_ASIC_SS_ASSIGNMENT_V2 { @@ -3903,6 +4553,7 @@ typedef struct _ATOM_ASIC_INTERNAL_SS_INFO_V3 #define ATOM_S0_SYSTEM_POWER_STATE_VALUE_AC 1 #define ATOM_S0_SYSTEM_POWER_STATE_VALUE_DC 2 #define ATOM_S0_SYSTEM_POWER_STATE_VALUE_LITEAC 3 +#define ATOM_S0_SYSTEM_POWER_STATE_VALUE_LIT2AC 4 //Byte aligned defintion for BIOS usage #define ATOM_S0_CRT1_MONOb0 0x01 @@ -4529,7 +5180,8 @@ typedef struct _ATOM_INIT_REG_BLOCK{ #define INDEX_ACCESS_RANGE_BEGIN (VALUE_DWORD + 1) #define INDEX_ACCESS_RANGE_END (INDEX_ACCESS_RANGE_BEGIN + 1) #define VALUE_INDEX_ACCESS_SINGLE (INDEX_ACCESS_RANGE_END + 1) - +//#define ACCESS_MCIODEBUGIND 0x40 //defined in BIOS code +#define ACCESS_PLACEHOLDER 0x80 typedef struct _ATOM_MC_INIT_PARAM_TABLE { @@ -4554,6 +5206,10 @@ typedef struct _ATOM_MC_INIT_PARAM_TABLE #define _32Mx32 0x33 #define _64Mx8 0x41 #define _64Mx16 0x42 +#define _64Mx32 0x43 +#define _128Mx8 0x51 +#define _128Mx16 0x52 +#define _256Mx8 0x61 #define SAMSUNG 0x1 #define INFINEON 0x2 @@ -4569,10 +5225,11 @@ typedef struct _ATOM_MC_INIT_PARAM_TABLE #define QIMONDA INFINEON #define PROMOS MOSEL #define KRETON INFINEON +#define ELIXIR NANYA /////////////Support for GDDR5 MC uCode to reside in upper 64K of ROM///////////// -#define UCODE_ROM_START_ADDRESS 0x1c000 +#define UCODE_ROM_START_ADDRESS 0x1b800 #define UCODE_SIGNATURE 0x4375434d // 'MCuC' - MC uCode //uCode block header for reference @@ -4903,7 +5560,34 @@ typedef struct _ATOM_VRAM_MODULE_V6 ATOM_MEMORY_TIMING_FORMAT_V2 asMemTiming[5];//Memory Timing block sort from lower clock to higher clock }ATOM_VRAM_MODULE_V6; - +typedef struct _ATOM_VRAM_MODULE_V7 +{ +// Design Specific Values + ULONG ulChannelMapCfg; // mmMC_SHARED_CHREMAP + USHORT usModuleSize; // Size of ATOM_VRAM_MODULE_V7 + USHORT usPrivateReserved; // MC_ARB_RAMCFG (includes NOOFBANK,NOOFRANKS,NOOFROWS,NOOFCOLS) + USHORT usReserved; + UCHAR ucExtMemoryID; // Current memory module ID + UCHAR ucMemoryType; // MEM_TYPE_DDR2/DDR3/GDDR3/GDDR5 + UCHAR ucChannelNum; // Number of mem. channels supported in this module + UCHAR ucChannelWidth; // CHANNEL_16BIT/CHANNEL_32BIT/CHANNEL_64BIT + UCHAR ucDensity; // _8Mx32, _16Mx32, _16Mx16, _32Mx16 + UCHAR ucReserve; // Former container for Mx_FLAGS like DBI_AC_MODE_ENABLE_ASIC for GDDR4. Not used now. + UCHAR ucMisc; // RANK_OF_THISMEMORY etc. + UCHAR ucVREFI; // Not used. + UCHAR ucNPL_RT; // Round trip delay (MC_SEQ_CAS_TIMING [28:24]:TCL=CL+NPL_RT-2). Always 2. + UCHAR ucPreamble; // [7:4] Write Preamble, [3:0] Read Preamble + UCHAR ucMemorySize; // Total memory size in unit of 16MB for CONFIG_MEMSIZE - bit[23:0] zeros + UCHAR ucReserved[3]; +// Memory Module specific values + USHORT usEMRS2Value; // EMRS2/MR2 Value. + USHORT usEMRS3Value; // EMRS3/MR3 Value. + UCHAR ucMemoryVenderID; // [7:4] Revision, [3:0] Vendor code + UCHAR ucRefreshRateFactor; // [1:0]=RefreshFactor (00=8ms, 01=16ms, 10=32ms,11=64ms) + UCHAR ucFIFODepth; // FIFO depth can be detected during vendor detection, here is hardcoded per memory + UCHAR ucCDR_Bandwidth; // [0:3]=Read CDR bandwidth, [4:7] - Write CDR Bandwidth + char strMemPNString[20]; // part number end with '0'. +}ATOM_VRAM_MODULE_V7; typedef struct _ATOM_VRAM_INFO_V2 { @@ -4942,6 +5626,20 @@ typedef struct _ATOM_VRAM_INFO_V4 // ATOM_INIT_REG_BLOCK aMemAdjust; }ATOM_VRAM_INFO_V4; +typedef struct _ATOM_VRAM_INFO_HEADER_V2_1 +{ + ATOM_COMMON_TABLE_HEADER sHeader; + USHORT usMemAdjustTblOffset; // offset of ATOM_INIT_REG_BLOCK structure for memory vendor specific MC adjust setting + USHORT usMemClkPatchTblOffset; // offset of ATOM_INIT_REG_BLOCK structure for memory clock specific MC setting + USHORT usReserved[4]; + UCHAR ucNumOfVRAMModule; // indicate number of VRAM module + UCHAR ucMemoryClkPatchTblVer; // version of memory AC timing register list + UCHAR ucVramModuleVer; // indicate ATOM_VRAM_MODUE version + UCHAR ucReserved; + ATOM_VRAM_MODULE_V7 aVramInfo[ATOM_MAX_NUMBER_OF_VRAM_MODULE]; // just for allocation, real number of blocks is in ucNumOfVRAMModule; +}ATOM_VRAM_INFO_HEADER_V2_1; + + typedef struct _ATOM_VRAM_GPIO_DETECTION_INFO { ATOM_COMMON_TABLE_HEADER sHeader; @@ -5182,6 +5880,16 @@ typedef struct _ASIC_TRANSMITTER_INFO UCHAR ucReserved; }ASIC_TRANSMITTER_INFO; +#define ASIC_TRANSMITTER_INFO_CONFIG__DVO_SDR_MODE 0x01 +#define ASIC_TRANSMITTER_INFO_CONFIG__COHERENT_MODE 0x02 +#define ASIC_TRANSMITTER_INFO_CONFIG__ENCODEROBJ_ID_MASK 0xc4 +#define ASIC_TRANSMITTER_INFO_CONFIG__ENCODER_A 0x00 +#define ASIC_TRANSMITTER_INFO_CONFIG__ENCODER_B 0x04 +#define ASIC_TRANSMITTER_INFO_CONFIG__ENCODER_C 0x40 +#define ASIC_TRANSMITTER_INFO_CONFIG__ENCODER_D 0x44 +#define ASIC_TRANSMITTER_INFO_CONFIG__ENCODER_E 0x80 +#define ASIC_TRANSMITTER_INFO_CONFIG__ENCODER_F 0x84 + typedef struct _ASIC_ENCODER_INFO { UCHAR ucEncoderID; @@ -5284,6 +5992,28 @@ typedef struct _DP_ENCODER_SERVICE_PARAMETERS /* /obselete */ #define DP_ENCODER_SERVICE_PS_ALLOCATION WRITE_ONE_BYTE_HW_I2C_DATA_PARAMETERS + +typedef struct _DP_ENCODER_SERVICE_PARAMETERS_V2 +{ + USHORT usExtEncoderObjId; // External Encoder Object Id, output parameter only, use when ucAction = DP_SERVICE_V2_ACTION_DET_EXT_CONNECTION + UCHAR ucAuxId; + UCHAR ucAction; + UCHAR ucSinkType; // Iput and Output parameters. + UCHAR ucHPDId; // Input parameter, used when ucAction = DP_SERVICE_V2_ACTION_DET_EXT_CONNECTION + UCHAR ucReserved[2]; +}DP_ENCODER_SERVICE_PARAMETERS_V2; + +typedef struct _DP_ENCODER_SERVICE_PS_ALLOCATION_V2 +{ + DP_ENCODER_SERVICE_PARAMETERS_V2 asDPServiceParam; + PROCESS_AUX_CHANNEL_TRANSACTION_PARAMETERS_V2 asAuxParam; +}DP_ENCODER_SERVICE_PS_ALLOCATION_V2; + +// ucAction +#define DP_SERVICE_V2_ACTION_GET_SINK_TYPE 0x01 +#define DP_SERVICE_V2_ACTION_DET_LCD_CONNECTION 0x02 + + // DP_TRAINING_TABLE #define DPCD_SET_LINKRATE_LANENUM_PATTERN1_TBL_ADDR ATOM_DP_TRAINING_TBL_ADDR #define DPCD_SET_SS_CNTL_TBL_ADDR (ATOM_DP_TRAINING_TBL_ADDR + 8 ) @@ -5339,6 +6069,7 @@ typedef struct _SET_HWBLOCK_INSTANCE_PARAMETER_V2 #define SELECT_DCIO_IMPCAL 4 #define SELECT_DCIO_DIG 6 #define SELECT_CRTC_PIXEL_RATE 7 +#define SELECT_VGA_BLK 8 /****************************************************************************/ //Portion VI: Definitinos for vbios MC scratch registers that driver used -- cgit v1.2.3 From 603a9da37b83c2b4cc4495ecab7916f45cf5837e Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Mon, 22 Nov 2010 17:56:21 -0500 Subject: drm/radeon/kms: upstream power table updates Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/atombios.h | 144 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 140 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/radeon/atombios.h b/drivers/gpu/drm/radeon/atombios.h index 6a9baa2443f8..58a0cd02c0a2 100644 --- a/drivers/gpu/drm/radeon/atombios.h +++ b/drivers/gpu/drm/radeon/atombios.h @@ -6475,7 +6475,17 @@ typedef struct _ATOM_PPLIB_THERMALCONTROLLER #define ATOM_PP_THERMALCONTROLLER_ADT7473 9 #define ATOM_PP_THERMALCONTROLLER_EXTERNAL_GPIO 11 #define ATOM_PP_THERMALCONTROLLER_EVERGREEN 12 +#define ATOM_PP_THERMALCONTROLLER_EMC2103 13 /* 0x0D */ // Only fan control will be implemented, do NOT show this in PPGen. +#define ATOM_PP_THERMALCONTROLLER_SUMO 14 /* 0x0E */ // Sumo type, used internally +#define ATOM_PP_THERMALCONTROLLER_NISLANDS 15 + +// Thermal controller 'combo type' to use an external controller for Fan control and an internal controller for thermal. +// We probably should reserve the bit 0x80 for this use. +// To keep the number of these types low we should also use the same code for all ASICs (i.e. do not distinguish RV6xx and RV7xx Internal here). +// The driver can pick the correct internal controller based on the ASIC. + #define ATOM_PP_THERMALCONTROLLER_ADT7473_WITH_INTERNAL 0x89 // ADT7473 Fan Control + Internal Thermal Controller +#define ATOM_PP_THERMALCONTROLLER_EMC2103_WITH_INTERNAL 0x8D // EMC2103 Fan Control + Internal Thermal Controller typedef struct _ATOM_PPLIB_STATE { @@ -6572,6 +6582,29 @@ typedef struct _ATOM_PPLIB_POWERPLAYTABLE3 USHORT usExtendendedHeaderOffset; } ATOM_PPLIB_POWERPLAYTABLE3, *LPATOM_PPLIB_POWERPLAYTABLE3; +typedef struct _ATOM_PPLIB_POWERPLAYTABLE4 +{ + ATOM_PPLIB_POWERPLAYTABLE3 basicTable3; + ULONG ulGoldenPPID; // PPGen use only + ULONG ulGoldenRevision; // PPGen use only + USHORT usVddcDependencyOnSCLKOffset; + USHORT usVddciDependencyOnMCLKOffset; + USHORT usVddcDependencyOnMCLKOffset; + USHORT usMaxClockVoltageOnDCOffset; + USHORT usReserved[2]; +} ATOM_PPLIB_POWERPLAYTABLE4, *LPATOM_PPLIB_POWERPLAYTABLE4; + +typedef struct _ATOM_PPLIB_POWERPLAYTABLE5 +{ + ATOM_PPLIB_POWERPLAYTABLE4 basicTable4; + ULONG ulTDPLimit; + ULONG ulNearTDPLimit; + ULONG ulSQRampingThreshold; + USHORT usCACLeakageTableOffset; // Points to ATOM_PPLIB_CAC_Leakage_Table + ULONG ulCACLeakage; // TBD, this parameter is still under discussion. Change to ulReserved if not needed. + ULONG ulReserved; +} ATOM_PPLIB_POWERPLAYTABLE5, *LPATOM_PPLIB_POWERPLAYTABLE5; + //// ATOM_PPLIB_NONCLOCK_INFO::usClassification #define ATOM_PPLIB_CLASSIFICATION_UI_MASK 0x0007 #define ATOM_PPLIB_CLASSIFICATION_UI_SHIFT 0 @@ -6595,6 +6628,10 @@ typedef struct _ATOM_PPLIB_POWERPLAYTABLE3 #define ATOM_PPLIB_CLASSIFICATION_HDSTATE 0x4000 #define ATOM_PPLIB_CLASSIFICATION_SDSTATE 0x8000 +//// ATOM_PPLIB_NONCLOCK_INFO::usClassification2 +#define ATOM_PPLIB_CLASSIFICATION2_LIMITEDPOWERSOURCE_2 0x0001 +#define ATOM_PPLIB_CLASSIFICATION2_ULV 0x0002 + //// ATOM_PPLIB_NONCLOCK_INFO::ulCapsAndSettings #define ATOM_PPLIB_SINGLE_DISPLAY_ONLY 0x00000001 #define ATOM_PPLIB_SUPPORTS_VIDEO_PLAYBACK 0x00000002 @@ -6627,9 +6664,21 @@ typedef struct _ATOM_PPLIB_POWERPLAYTABLE3 #define ATOM_PPLIB_M3ARB_MASK 0x00060000 #define ATOM_PPLIB_M3ARB_SHIFT 17 +#define ATOM_PPLIB_ENABLE_DRR 0x00080000 + +// remaining 16 bits are reserved +typedef struct _ATOM_PPLIB_THERMAL_STATE +{ + UCHAR ucMinTemperature; + UCHAR ucMaxTemperature; + UCHAR ucThermalAction; +}ATOM_PPLIB_THERMAL_STATE, *LPATOM_PPLIB_THERMAL_STATE; + // Contained in an array starting at the offset // in ATOM_PPLIB_POWERPLAYTABLE::usNonClockInfoArrayOffset. // referenced from ATOM_PPLIB_STATE_INFO::ucNonClockStateIndex +#define ATOM_PPLIB_NONCLOCKINFO_VER1 12 +#define ATOM_PPLIB_NONCLOCKINFO_VER2 24 typedef struct _ATOM_PPLIB_NONCLOCK_INFO { USHORT usClassification; @@ -6637,15 +6686,15 @@ typedef struct _ATOM_PPLIB_NONCLOCK_INFO UCHAR ucMaxTemperature; ULONG ulCapsAndSettings; UCHAR ucRequiredPower; - UCHAR ucUnused1[3]; + USHORT usClassification2; + ULONG ulVCLK; + ULONG ulDCLK; + UCHAR ucUnused[5]; } ATOM_PPLIB_NONCLOCK_INFO; // Contained in an array starting at the offset // in ATOM_PPLIB_POWERPLAYTABLE::usClockInfoArrayOffset. // referenced from ATOM_PPLIB_STATE::ucClockStateIndices -#define ATOM_PPLIB_NONCLOCKINFO_VER1 12 -#define ATOM_PPLIB_NONCLOCKINFO_VER2 24 - typedef struct _ATOM_PPLIB_R600_CLOCK_INFO { USHORT usEngineClockLow; @@ -6716,6 +6765,93 @@ typedef struct _ATOM_PPLIB_RS780_CLOCK_INFO #define ATOM_PPLIB_RS780_HTLINKFREQ_LOW 1 #define ATOM_PPLIB_RS780_HTLINKFREQ_HIGH 2 +typedef struct _ATOM_PPLIB_SUMO_CLOCK_INFO{ + USHORT usEngineClockLow; //clockfrequency & 0xFFFF. The unit is in 10khz + UCHAR ucEngineClockHigh; //clockfrequency >> 16. + UCHAR vddcIndex; //2-bit vddc index; + UCHAR leakage; //please use 8-bit absolute value, not the 6-bit % value + //please initalize to 0 + UCHAR rsv; + //please initalize to 0 + USHORT rsv1; + //please initialize to 0s + ULONG rsv2[2]; +}ATOM_PPLIB_SUMO_CLOCK_INFO; + + + +typedef struct _ATOM_PPLIB_STATE_V2 +{ + //number of valid dpm levels in this state; Driver uses it to calculate the whole + //size of the state: sizeof(ATOM_PPLIB_STATE_V2) + (ucNumDPMLevels - 1) * sizeof(UCHAR) + UCHAR ucNumDPMLevels; + + //a index to the array of nonClockInfos + UCHAR nonClockInfoIndex; + /** + * Driver will read the first ucNumDPMLevels in this array + */ + UCHAR clockInfoIndex[1]; +} ATOM_PPLIB_STATE_V2; + +typedef struct StateArray{ + //how many states we have + UCHAR ucNumEntries; + + ATOM_PPLIB_STATE_V2 states[1]; +}StateArray; + + +typedef struct ClockInfoArray{ + //how many clock levels we have + UCHAR ucNumEntries; + + //sizeof(ATOM_PPLIB_SUMO_CLOCK_INFO) + UCHAR ucEntrySize; + + //this is for Sumo + ATOM_PPLIB_SUMO_CLOCK_INFO clockInfo[1]; +}ClockInfoArray; + +typedef struct NonClockInfoArray{ + + //how many non-clock levels we have. normally should be same as number of states + UCHAR ucNumEntries; + //sizeof(ATOM_PPLIB_NONCLOCK_INFO) + UCHAR ucEntrySize; + + ATOM_PPLIB_NONCLOCK_INFO nonClockInfo[1]; +}NonClockInfoArray; + +typedef struct _ATOM_PPLIB_Clock_Voltage_Dependency_Record +{ + USHORT usClockLow; + UCHAR ucClockHigh; + USHORT usVoltage; +}ATOM_PPLIB_Clock_Voltage_Dependency_Record; + +typedef struct _ATOM_PPLIB_Clock_Voltage_Dependency_Table +{ + UCHAR ucNumEntries; // Number of entries. + ATOM_PPLIB_Clock_Voltage_Dependency_Record entries[1]; // Dynamically allocate entries. +}ATOM_PPLIB_Clock_Voltage_Dependency_Table; + +typedef struct _ATOM_PPLIB_Clock_Voltage_Limit_Record +{ + USHORT usSclkLow; + UCHAR ucSclkHigh; + USHORT usMclkLow; + UCHAR ucMclkHigh; + USHORT usVddc; + USHORT usVddci; +}ATOM_PPLIB_Clock_Voltage_Limit_Record; + +typedef struct _ATOM_PPLIB_Clock_Voltage_Limit_Table +{ + UCHAR ucNumEntries; // Number of entries. + ATOM_PPLIB_Clock_Voltage_Limit_Record entries[1]; // Dynamically allocate entries. +}ATOM_PPLIB_Clock_Voltage_Limit_Table; + /**************************************************************************/ -- cgit v1.2.3 From 2f062fda4f83932b87b3b6c903eeade43422245a Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Mon, 22 Nov 2010 17:56:22 -0500 Subject: drm/radeon/kms: add new family id for AMD Ontario APUs Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/radeon.h | 1 + drivers/gpu/drm/radeon/radeon_family.h | 1 + 2 files changed, 2 insertions(+) diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 3a7095743d44..cfaf71323491 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -1269,6 +1269,7 @@ void r100_pll_errata_after_index(struct radeon_device *rdev); #define ASIC_IS_DCE3(rdev) ((rdev->family >= CHIP_RV620)) #define ASIC_IS_DCE32(rdev) ((rdev->family >= CHIP_RV730)) #define ASIC_IS_DCE4(rdev) ((rdev->family >= CHIP_CEDAR)) +#define ASIC_IS_DCE41(rdev) ((rdev->family >= CHIP_PALM)) /* * BIOS helpers. diff --git a/drivers/gpu/drm/radeon/radeon_family.h b/drivers/gpu/drm/radeon/radeon_family.h index e329066dcabd..4c222d5437d1 100644 --- a/drivers/gpu/drm/radeon/radeon_family.h +++ b/drivers/gpu/drm/radeon/radeon_family.h @@ -80,6 +80,7 @@ enum radeon_family { CHIP_JUNIPER, CHIP_CYPRESS, CHIP_HEMLOCK, + CHIP_PALM, CHIP_LAST, }; -- cgit v1.2.3 From 4e8c65a1f9ee1a976d95c1d5d2027761aba2f1c3 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Mon, 22 Nov 2010 17:56:23 -0500 Subject: drm/radeon/kms: atom changes for DCE4.1 devices Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/radeon_asic.c | 4 +++- drivers/gpu/drm/radeon/radeon_encoders.c | 25 +++++++++++++++++++++---- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c index 64fb89ecbf74..bf7ec0441e63 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.c +++ b/drivers/gpu/drm/radeon/radeon_asic.c @@ -849,7 +849,9 @@ int radeon_asic_init(struct radeon_device *rdev) if (rdev->flags & RADEON_SINGLE_CRTC) rdev->num_crtc = 1; else { - if (ASIC_IS_DCE4(rdev)) + if (ASIC_IS_DCE41(rdev)) + rdev->num_crtc = 2; + else if (ASIC_IS_DCE4(rdev)) rdev->num_crtc = 6; else rdev->num_crtc = 2; diff --git a/drivers/gpu/drm/radeon/radeon_encoders.c b/drivers/gpu/drm/radeon/radeon_encoders.c index 041943df966b..806d552299bf 100644 --- a/drivers/gpu/drm/radeon/radeon_encoders.c +++ b/drivers/gpu/drm/radeon/radeon_encoders.c @@ -713,7 +713,7 @@ atombios_get_encoder_mode(struct drm_encoder *encoder) * DIG1/2 can drive UNIPHY0/1/2 link A or link B * * DCE 4.0 - * - 3 DIG transmitter blocks UNPHY0/1/2 (links A and B). + * - 3 DIG transmitter blocks UNIPHY0/1/2 (links A and B). * Supports up to 6 digital outputs * - 6 DIG encoder blocks. * - DIG to PHY mapping is hardcoded @@ -724,6 +724,12 @@ atombios_get_encoder_mode(struct drm_encoder *encoder) * DIG5 drives UNIPHY2 link A, A+B * DIG6 drives UNIPHY2 link B * + * DCE 4.1 + * - 3 DIG transmitter blocks UNIPHY0/1/2 (links A and B). + * Supports up to 6 digital outputs + * - 2 DIG encoder blocks. + * DIG1/2 can drive UNIPHY0/1/2 link A or link B + * * Routing * crtc -> dig encoder -> UNIPHY/LVTMA (1 or 2 links) * Examples: @@ -904,9 +910,15 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t else args.v3.ucLaneNum = 4; - if (dig->linkb) { - args.v3.acConfig.ucLinkSel = 1; - args.v3.acConfig.ucEncoderSel = 1; + if (ASIC_IS_DCE41(rdev)) { + args.v3.acConfig.ucEncoderSel = dig->dig_encoder; + if (dig->linkb) + args.v3.acConfig.ucLinkSel = 1; + } else { + if (dig->linkb) { + args.v3.acConfig.ucLinkSel = 1; + args.v3.acConfig.ucEncoderSel = 1; + } } /* Select the PLL for the PHY @@ -1483,6 +1495,11 @@ static int radeon_atom_pick_dig_encoder(struct drm_encoder *encoder) struct radeon_encoder_atom_dig *dig; uint32_t dig_enc_in_use = 0; + /* on DCE41 and encoder can driver any phy so just crtc id */ + if (ASIC_IS_DCE41(rdev)) { + return radeon_crtc->crtc_id; + } + if (ASIC_IS_DCE4(rdev)) { dig = radeon_encoder->enc_priv; switch (radeon_encoder->encoder_id) { -- cgit v1.2.3 From bf982ebf22d5d84dd4a2a8d8f1a11f75920020a7 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Mon, 22 Nov 2010 17:56:24 -0500 Subject: drm/radeon/kms: Add support for external encoders on fusion APUs Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/radeon_display.c | 4 ++- drivers/gpu/drm/radeon/radeon_encoders.c | 54 ++++++++++++++++++++++++++++++-- 2 files changed, 54 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c index 1df4dc6c063c..2697801e36e7 100644 --- a/drivers/gpu/drm/radeon/radeon_display.c +++ b/drivers/gpu/drm/radeon/radeon_display.c @@ -225,7 +225,7 @@ static void radeon_crtc_init(struct drm_device *dev, int index) radeon_legacy_init_crtc(dev, radeon_crtc); } -static const char *encoder_names[34] = { +static const char *encoder_names[36] = { "NONE", "INTERNAL_LVDS", "INTERNAL_TMDS1", @@ -260,6 +260,8 @@ static const char *encoder_names[34] = { "INTERNAL_KLDSCP_LVTMA", "INTERNAL_UNIPHY1", "INTERNAL_UNIPHY2", + "NUTMEG", + "TRAVIS", }; static const char *connector_names[15] = { diff --git a/drivers/gpu/drm/radeon/radeon_encoders.c b/drivers/gpu/drm/radeon/radeon_encoders.c index 806d552299bf..e4e64a80b58d 100644 --- a/drivers/gpu/drm/radeon/radeon_encoders.c +++ b/drivers/gpu/drm/radeon/radeon_encoders.c @@ -1056,6 +1056,7 @@ atombios_set_edp_panel_power(struct drm_connector *connector, int action) union external_encoder_control { EXTERNAL_ENCODER_CONTROL_PS_ALLOCATION v1; + EXTERNAL_ENCODER_CONTROL_PS_ALLOCATION_V3 v3; }; static void @@ -1066,6 +1067,7 @@ atombios_external_encoder_setup(struct drm_encoder *encoder, struct drm_device *dev = encoder->dev; struct radeon_device *rdev = dev->dev_private; struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); + struct radeon_encoder *ext_radeon_encoder = to_radeon_encoder(ext_encoder); union external_encoder_control args; struct drm_connector *connector = radeon_get_connector_for_encoder(encoder); int index = GetIndexIntoMasterTable(COMMAND, ExternalEncoderControl); @@ -1073,6 +1075,7 @@ atombios_external_encoder_setup(struct drm_encoder *encoder, int dp_clock = 0; int dp_lane_count = 0; int connector_object_id = 0; + u32 ext_enum = (ext_radeon_encoder->encoder_enum & ENUM_ID_MASK) >> ENUM_ID_SHIFT; if (connector) { struct radeon_connector *radeon_connector = to_radeon_connector(connector); @@ -1111,6 +1114,37 @@ atombios_external_encoder_setup(struct drm_encoder *encoder, else args.v1.sDigEncoder.ucLaneNum = 4; break; + case 3: + args.v3.sExtEncoder.ucAction = action; + if (action == EXTERNAL_ENCODER_ACTION_V3_ENCODER_INIT) + args.v3.sExtEncoder.usConnectorId = connector_object_id; + else + args.v3.sExtEncoder.usPixelClock = cpu_to_le16(radeon_encoder->pixel_clock / 10); + args.v3.sExtEncoder.ucEncoderMode = atombios_get_encoder_mode(encoder); + + if (args.v3.sExtEncoder.ucEncoderMode == ATOM_ENCODER_MODE_DP) { + if (dp_clock == 270000) + args.v3.sExtEncoder.ucConfig |= EXTERNAL_ENCODER_CONFIG_V3_DPLINKRATE_2_70GHZ; + else if (dp_clock == 540000) + args.v3.sExtEncoder.ucConfig |= EXTERNAL_ENCODER_CONFIG_V3_DPLINKRATE_5_40GHZ; + args.v3.sExtEncoder.ucLaneNum = dp_lane_count; + } else if (radeon_encoder->pixel_clock > 165000) + args.v3.sExtEncoder.ucLaneNum = 8; + else + args.v3.sExtEncoder.ucLaneNum = 4; + switch (ext_enum) { + case GRAPH_OBJECT_ENUM_ID1: + args.v3.sExtEncoder.ucConfig |= EXTERNAL_ENCODER_CONFIG_V3_ENCODER1; + break; + case GRAPH_OBJECT_ENUM_ID2: + args.v3.sExtEncoder.ucConfig |= EXTERNAL_ENCODER_CONFIG_V3_ENCODER2; + break; + case GRAPH_OBJECT_ENUM_ID3: + args.v3.sExtEncoder.ucConfig |= EXTERNAL_ENCODER_CONFIG_V3_ENCODER3; + break; + } + args.v3.sExtEncoder.ucBitPerColor = PANEL_8BIT_PER_COLOR; + break; default: DRM_ERROR("Unknown table version: %d, %d\n", frev, crev); return; @@ -1301,12 +1335,18 @@ radeon_atom_encoder_dpms(struct drm_encoder *encoder, int mode) switch (mode) { case DRM_MODE_DPMS_ON: default: - action = ATOM_ENABLE; + if (ASIC_IS_DCE41(rdev) && (rdev->flags & RADEON_IS_IGP)) + action = EXTERNAL_ENCODER_ACTION_V3_ENABLE_OUTPUT; + else + action = ATOM_ENABLE; break; case DRM_MODE_DPMS_STANDBY: case DRM_MODE_DPMS_SUSPEND: case DRM_MODE_DPMS_OFF: - action = ATOM_DISABLE; + if (ASIC_IS_DCE41(rdev) && (rdev->flags & RADEON_IS_IGP)) + action = EXTERNAL_ENCODER_ACTION_V3_DISABLE_OUTPUT; + else + action = ATOM_DISABLE; break; } atombios_external_encoder_setup(encoder, ext_encoder, action); @@ -1627,7 +1667,13 @@ radeon_atom_encoder_mode_set(struct drm_encoder *encoder, } if (ext_encoder) { - atombios_external_encoder_setup(encoder, ext_encoder, ATOM_ENABLE); + if (ASIC_IS_DCE41(rdev) && (rdev->flags & RADEON_IS_IGP)) { + atombios_external_encoder_setup(encoder, ext_encoder, + EXTERNAL_ENCODER_ACTION_V3_ENCODER_INIT); + atombios_external_encoder_setup(encoder, ext_encoder, + EXTERNAL_ENCODER_ACTION_V3_ENCODER_SETUP); + } else + atombios_external_encoder_setup(encoder, ext_encoder, ATOM_ENABLE); } atombios_apply_encoder_quirks(encoder, adjusted_mode); @@ -2046,6 +2092,8 @@ radeon_add_atom_encoder(struct drm_device *dev, uint32_t encoder_enum, uint32_t case ENCODER_OBJECT_ID_TITFP513: case ENCODER_OBJECT_ID_VT1623: case ENCODER_OBJECT_ID_HDMI_SI1930: + case ENCODER_OBJECT_ID_TRAVIS: + case ENCODER_OBJECT_ID_NUTMEG: /* these are handled by the primary encoders */ radeon_encoder->is_ext_encoder = true; if (radeon_encoder->devices & (ATOM_DEVICE_LCD_SUPPORT)) -- cgit v1.2.3 From 4339c442c0736db42329b68602308e95bcc75a30 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Mon, 22 Nov 2010 17:56:25 -0500 Subject: drm/radeon/kms: add support for ss overrides on Fusion APUs System specific spread spectrum overrides can be specified in the integrated system info table for Fusion APUs. This adds support for using those overrides. Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/radeon_atombios.c | 39 ++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c index 87ead090c7d5..4d37b2d1ba74 100644 --- a/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/drivers/gpu/drm/radeon/radeon_atombios.c @@ -1321,6 +1321,43 @@ bool radeon_atombios_get_ppll_ss_info(struct radeon_device *rdev, return false; } +static void radeon_atombios_get_igp_ss_overrides(struct radeon_device *rdev, + struct radeon_atom_ss *ss, + int id) +{ + struct radeon_mode_info *mode_info = &rdev->mode_info; + int index = GetIndexIntoMasterTable(DATA, IntegratedSystemInfo); + u16 data_offset, size; + struct _ATOM_INTEGRATED_SYSTEM_INFO_V6 *igp_info; + u8 frev, crev; + u16 percentage = 0, rate = 0; + + /* get any igp specific overrides */ + if (atom_parse_data_header(mode_info->atom_context, index, &size, + &frev, &crev, &data_offset)) { + igp_info = (struct _ATOM_INTEGRATED_SYSTEM_INFO_V6 *) + (mode_info->atom_context->bios + data_offset); + switch (id) { + case ASIC_INTERNAL_SS_ON_TMDS: + percentage = le16_to_cpu(igp_info->usDVISSPercentage); + rate = le16_to_cpu(igp_info->usDVISSpreadRateIn10Hz); + break; + case ASIC_INTERNAL_SS_ON_HDMI: + percentage = le16_to_cpu(igp_info->usHDMISSPercentage); + rate = le16_to_cpu(igp_info->usHDMISSpreadRateIn10Hz); + break; + case ASIC_INTERNAL_SS_ON_LVDS: + percentage = le16_to_cpu(igp_info->usLvdsSSPercentage); + rate = le16_to_cpu(igp_info->usLvdsSSpreadRateIn10Hz); + break; + } + if (percentage) + ss->percentage = percentage; + if (rate) + ss->rate = rate; + } +} + union asic_ss_info { struct _ATOM_ASIC_INTERNAL_SS_INFO info; struct _ATOM_ASIC_INTERNAL_SS_INFO_V2 info_2; @@ -1385,6 +1422,8 @@ bool radeon_atombios_get_asic_ss_info(struct radeon_device *rdev, le16_to_cpu(ss_info->info_3.asSpreadSpectrum[i].usSpreadSpectrumPercentage); ss->type = ss_info->info_3.asSpreadSpectrum[i].ucSpreadSpectrumMode; ss->rate = le16_to_cpu(ss_info->info_3.asSpreadSpectrum[i].usSpreadRateIn10Hz); + if (rdev->flags & RADEON_IS_IGP) + radeon_atombios_get_igp_ss_overrides(rdev, ss, id); return true; } } -- cgit v1.2.3 From 0ef0c1f7349e782f6c79cb7e4bf8a4c3ce3371c6 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Mon, 22 Nov 2010 17:56:26 -0500 Subject: drm/radeon/kms: move r7xx/evergreen to its own vram_gtt setup function MC_VM_FB_LOCATION is at a different offset between r6xx and r7xx/evergreen. The location is needed for vram setup on fusion chips. Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/evergreen.c | 2 +- drivers/gpu/drm/radeon/r600.c | 2 +- drivers/gpu/drm/radeon/radeon.h | 2 +- drivers/gpu/drm/radeon/rv770.c | 44 +++++++++++++++++++++++++++++++++++++- 4 files changed, 46 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index 728358e6b798..e9b262fdaa2c 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c @@ -1945,7 +1945,7 @@ int evergreen_mc_init(struct radeon_device *rdev) rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE) * 1024 * 1024; rdev->mc.visible_vram_size = rdev->mc.aper_size; rdev->mc.active_vram_size = rdev->mc.visible_vram_size; - r600_vram_gtt_location(rdev, &rdev->mc); + r700_vram_gtt_location(rdev, &rdev->mc); radeon_update_bandwidth_info(rdev); return 0; diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index a3552594ccc4..93b1c687328b 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c @@ -1161,7 +1161,7 @@ static void r600_mc_program(struct radeon_device *rdev) * Note: GTT start, end, size should be initialized before calling this * function on AGP platform. */ -void r600_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc) +static void r600_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc) { u64 size_bf, size_af; diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index cfaf71323491..bf3a4fc82964 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -1433,7 +1433,6 @@ extern void rs690_line_buffer_adjust(struct radeon_device *rdev, struct drm_display_mode *mode2); /* r600, rv610, rv630, rv620, rv635, rv670, rs780, rs880 */ -extern void r600_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc); extern bool r600_card_posted(struct radeon_device *rdev); extern void r600_cp_stop(struct radeon_device *rdev); extern int r600_cp_start(struct radeon_device *rdev); @@ -1479,6 +1478,7 @@ extern void r600_hdmi_setmode(struct drm_encoder *encoder, struct drm_display_mo extern int r600_hdmi_buffer_status_changed(struct drm_encoder *encoder); extern void r600_hdmi_update_audio_settings(struct drm_encoder *encoder); +extern void r700_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc); extern void r700_cp_stop(struct radeon_device *rdev); extern void r700_cp_fini(struct radeon_device *rdev); extern void evergreen_disable_interrupt_state(struct radeon_device *rdev); diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c index 24ebd0879c4b..c23349a46fd2 100644 --- a/drivers/gpu/drm/radeon/rv770.c +++ b/drivers/gpu/drm/radeon/rv770.c @@ -1001,6 +1001,48 @@ static void rv770_vram_scratch_fini(struct radeon_device *rdev) radeon_bo_unref(&rdev->vram_scratch.robj); } +void r700_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc) +{ + u64 size_bf, size_af; + + if (mc->mc_vram_size > 0xE0000000) { + /* leave room for at least 512M GTT */ + dev_warn(rdev->dev, "limiting VRAM\n"); + mc->real_vram_size = 0xE0000000; + mc->mc_vram_size = 0xE0000000; + } + if (rdev->flags & RADEON_IS_AGP) { + size_bf = mc->gtt_start; + size_af = 0xFFFFFFFF - mc->gtt_end + 1; + if (size_bf > size_af) { + if (mc->mc_vram_size > size_bf) { + dev_warn(rdev->dev, "limiting VRAM\n"); + mc->real_vram_size = size_bf; + mc->mc_vram_size = size_bf; + } + mc->vram_start = mc->gtt_start - mc->mc_vram_size; + } else { + if (mc->mc_vram_size > size_af) { + dev_warn(rdev->dev, "limiting VRAM\n"); + mc->real_vram_size = size_af; + mc->mc_vram_size = size_af; + } + mc->vram_start = mc->gtt_end; + } + mc->vram_end = mc->vram_start + mc->mc_vram_size - 1; + dev_info(rdev->dev, "VRAM: %lluM 0x%08llX - 0x%08llX (%lluM used)\n", + mc->mc_vram_size >> 20, mc->vram_start, + mc->vram_end, mc->real_vram_size >> 20); + } else { + u64 base = 0; + if (rdev->flags & RADEON_IS_IGP) + base = (RREG32(MC_VM_FB_LOCATION) & 0xFFFF) << 24; + radeon_vram_location(rdev, &rdev->mc, base); + rdev->mc.gtt_base_align = 0; + radeon_gtt_location(rdev, mc); + } +} + int rv770_mc_init(struct radeon_device *rdev) { u32 tmp; @@ -1041,7 +1083,7 @@ int rv770_mc_init(struct radeon_device *rdev) rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE); rdev->mc.visible_vram_size = rdev->mc.aper_size; rdev->mc.active_vram_size = rdev->mc.visible_vram_size; - r600_vram_gtt_location(rdev, &rdev->mc); + r700_vram_gtt_location(rdev, &rdev->mc); radeon_update_bandwidth_info(rdev); return 0; -- cgit v1.2.3 From 6eb18f8b6006b0e869a8484b1daaa63adce1b73e Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Mon, 22 Nov 2010 17:56:27 -0500 Subject: drm/radeon/kms: MC setup changes for fusion APUs - CONFIG_MEMSIZE is in bytes on fusion. - FB_BASE and FB_TOP are finer grained. Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/evergreen.c | 12 +++++++++--- drivers/gpu/drm/radeon/rv770.c | 10 +++++++++- drivers/gpu/drm/radeon/rv770d.h | 1 + 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index e9b262fdaa2c..090f74700081 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c @@ -1940,9 +1940,15 @@ int evergreen_mc_init(struct radeon_device *rdev) rdev->mc.aper_base = pci_resource_start(rdev->pdev, 0); rdev->mc.aper_size = pci_resource_len(rdev->pdev, 0); /* Setup GPU memory space */ - /* size in MB on evergreen */ - rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE) * 1024 * 1024; - rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE) * 1024 * 1024; + if (rdev->flags & RADEON_IS_IGP) { + /* size in bytes on fusion */ + rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE); + rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE); + } else { + /* size in MB on evergreen */ + rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE) * 1024 * 1024; + rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE) * 1024 * 1024; + } rdev->mc.visible_vram_size = rdev->mc.aper_size; rdev->mc.active_vram_size = rdev->mc.visible_vram_size; r700_vram_gtt_location(rdev, &rdev->mc); diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c index c23349a46fd2..2b66af9066b2 100644 --- a/drivers/gpu/drm/radeon/rv770.c +++ b/drivers/gpu/drm/radeon/rv770.c @@ -237,6 +237,12 @@ static void rv770_mc_program(struct radeon_device *rdev) rdev->mc.vram_end >> 12); } WREG32(MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR, 0); + if (rdev->flags & RADEON_IS_IGP) { + tmp = RREG32(MC_FUS_VM_FB_OFFSET) & 0x000FFFFF; + tmp |= ((rdev->mc.vram_end >> 20) & 0xF) << 24; + tmp |= ((rdev->mc.vram_start >> 20) & 0xF) << 20; + WREG32(MC_FUS_VM_FB_OFFSET, tmp); + } tmp = ((rdev->mc.vram_end >> 24) & 0xFFFF) << 16; tmp |= ((rdev->mc.vram_start >> 24) & 0xFFFF); WREG32(MC_VM_FB_LOCATION, tmp); @@ -1035,8 +1041,10 @@ void r700_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc) mc->vram_end, mc->real_vram_size >> 20); } else { u64 base = 0; - if (rdev->flags & RADEON_IS_IGP) + if (rdev->flags & RADEON_IS_IGP) { base = (RREG32(MC_VM_FB_LOCATION) & 0xFFFF) << 24; + base |= RREG32(MC_FUS_VM_FB_OFFSET) & 0x00F00000; + } radeon_vram_location(rdev, &rdev->mc, base); rdev->mc.gtt_base_align = 0; radeon_gtt_location(rdev, mc); diff --git a/drivers/gpu/drm/radeon/rv770d.h b/drivers/gpu/drm/radeon/rv770d.h index 7b1c8f8f4074..e09a403f1c64 100644 --- a/drivers/gpu/drm/radeon/rv770d.h +++ b/drivers/gpu/drm/radeon/rv770d.h @@ -158,6 +158,7 @@ #define MC_VM_AGP_BOT 0x202C #define MC_VM_AGP_BASE 0x2030 #define MC_VM_FB_LOCATION 0x2024 +#define MC_FUS_VM_FB_OFFSET 0x2898 #define MC_VM_MB_L1_TLB0_CNTL 0x2234 #define MC_VM_MB_L1_TLB1_CNTL 0x2238 #define MC_VM_MB_L1_TLB2_CNTL 0x223C -- cgit v1.2.3 From 180074010c6a8d1948638b4a136d2bd8111f4459 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Mon, 22 Nov 2010 17:56:28 -0500 Subject: drm/radeon/kms: evergreen.c updates for fusion fusion chips only have 2 crtcs. Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/evergreen.c | 188 +++++++++++++++++++-------------- drivers/gpu/drm/radeon/radeon_device.c | 7 +- 2 files changed, 113 insertions(+), 82 deletions(-) diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index 090f74700081..07c4c6f216f0 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c @@ -888,31 +888,39 @@ static void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_sa save->vga_hdp_control = RREG32(VGA_HDP_CONTROL); save->crtc_control[0] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET); save->crtc_control[1] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET); - save->crtc_control[2] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET); - save->crtc_control[3] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET); - save->crtc_control[4] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET); - save->crtc_control[5] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET); + if (!(rdev->flags & RADEON_IS_IGP)) { + save->crtc_control[2] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET); + save->crtc_control[3] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET); + save->crtc_control[4] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET); + save->crtc_control[5] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET); + } /* Stop all video */ WREG32(VGA_RENDER_CONTROL, 0); WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC0_REGISTER_OFFSET, 1); WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC1_REGISTER_OFFSET, 1); - WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC2_REGISTER_OFFSET, 1); - WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC3_REGISTER_OFFSET, 1); - WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC4_REGISTER_OFFSET, 1); - WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC5_REGISTER_OFFSET, 1); + if (!(rdev->flags & RADEON_IS_IGP)) { + WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC2_REGISTER_OFFSET, 1); + WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC3_REGISTER_OFFSET, 1); + WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC4_REGISTER_OFFSET, 1); + WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC5_REGISTER_OFFSET, 1); + } WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, 0); WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, 0); - WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, 0); - WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, 0); - WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET, 0); - WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, 0); + if (!(rdev->flags & RADEON_IS_IGP)) { + WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, 0); + WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, 0); + WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET, 0); + WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, 0); + } WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC0_REGISTER_OFFSET, 0); WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC1_REGISTER_OFFSET, 0); - WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC2_REGISTER_OFFSET, 0); - WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC3_REGISTER_OFFSET, 0); - WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC4_REGISTER_OFFSET, 0); - WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC5_REGISTER_OFFSET, 0); + if (!(rdev->flags & RADEON_IS_IGP)) { + WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC2_REGISTER_OFFSET, 0); + WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC3_REGISTER_OFFSET, 0); + WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC4_REGISTER_OFFSET, 0); + WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC5_REGISTER_OFFSET, 0); + } WREG32(D1VGA_CONTROL, 0); WREG32(D2VGA_CONTROL, 0); @@ -942,41 +950,43 @@ static void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_ WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + EVERGREEN_CRTC1_REGISTER_OFFSET, (u32)rdev->mc.vram_start); - WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC2_REGISTER_OFFSET, - upper_32_bits(rdev->mc.vram_start)); - WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC2_REGISTER_OFFSET, - upper_32_bits(rdev->mc.vram_start)); - WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS + EVERGREEN_CRTC2_REGISTER_OFFSET, - (u32)rdev->mc.vram_start); - WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + EVERGREEN_CRTC2_REGISTER_OFFSET, - (u32)rdev->mc.vram_start); - - WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC3_REGISTER_OFFSET, - upper_32_bits(rdev->mc.vram_start)); - WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC3_REGISTER_OFFSET, - upper_32_bits(rdev->mc.vram_start)); - WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS + EVERGREEN_CRTC3_REGISTER_OFFSET, - (u32)rdev->mc.vram_start); - WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + EVERGREEN_CRTC3_REGISTER_OFFSET, - (u32)rdev->mc.vram_start); - - WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC4_REGISTER_OFFSET, - upper_32_bits(rdev->mc.vram_start)); - WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC4_REGISTER_OFFSET, - upper_32_bits(rdev->mc.vram_start)); - WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS + EVERGREEN_CRTC4_REGISTER_OFFSET, - (u32)rdev->mc.vram_start); - WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + EVERGREEN_CRTC4_REGISTER_OFFSET, - (u32)rdev->mc.vram_start); - - WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC5_REGISTER_OFFSET, - upper_32_bits(rdev->mc.vram_start)); - WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC5_REGISTER_OFFSET, - upper_32_bits(rdev->mc.vram_start)); - WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS + EVERGREEN_CRTC5_REGISTER_OFFSET, - (u32)rdev->mc.vram_start); - WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + EVERGREEN_CRTC5_REGISTER_OFFSET, - (u32)rdev->mc.vram_start); + if (!(rdev->flags & RADEON_IS_IGP)) { + WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC2_REGISTER_OFFSET, + upper_32_bits(rdev->mc.vram_start)); + WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC2_REGISTER_OFFSET, + upper_32_bits(rdev->mc.vram_start)); + WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS + EVERGREEN_CRTC2_REGISTER_OFFSET, + (u32)rdev->mc.vram_start); + WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + EVERGREEN_CRTC2_REGISTER_OFFSET, + (u32)rdev->mc.vram_start); + + WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC3_REGISTER_OFFSET, + upper_32_bits(rdev->mc.vram_start)); + WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC3_REGISTER_OFFSET, + upper_32_bits(rdev->mc.vram_start)); + WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS + EVERGREEN_CRTC3_REGISTER_OFFSET, + (u32)rdev->mc.vram_start); + WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + EVERGREEN_CRTC3_REGISTER_OFFSET, + (u32)rdev->mc.vram_start); + + WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC4_REGISTER_OFFSET, + upper_32_bits(rdev->mc.vram_start)); + WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC4_REGISTER_OFFSET, + upper_32_bits(rdev->mc.vram_start)); + WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS + EVERGREEN_CRTC4_REGISTER_OFFSET, + (u32)rdev->mc.vram_start); + WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + EVERGREEN_CRTC4_REGISTER_OFFSET, + (u32)rdev->mc.vram_start); + + WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC5_REGISTER_OFFSET, + upper_32_bits(rdev->mc.vram_start)); + WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS_HIGH + EVERGREEN_CRTC5_REGISTER_OFFSET, + upper_32_bits(rdev->mc.vram_start)); + WREG32(EVERGREEN_GRPH_PRIMARY_SURFACE_ADDRESS + EVERGREEN_CRTC5_REGISTER_OFFSET, + (u32)rdev->mc.vram_start); + WREG32(EVERGREEN_GRPH_SECONDARY_SURFACE_ADDRESS + EVERGREEN_CRTC5_REGISTER_OFFSET, + (u32)rdev->mc.vram_start); + } WREG32(EVERGREEN_VGA_MEMORY_BASE_ADDRESS_HIGH, upper_32_bits(rdev->mc.vram_start)); WREG32(EVERGREEN_VGA_MEMORY_BASE_ADDRESS, (u32)rdev->mc.vram_start); @@ -992,22 +1002,28 @@ static void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_ WREG32(EVERGREEN_D6VGA_CONTROL, save->vga_control[5]); WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC0_REGISTER_OFFSET, 1); WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC1_REGISTER_OFFSET, 1); - WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC2_REGISTER_OFFSET, 1); - WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC3_REGISTER_OFFSET, 1); - WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC4_REGISTER_OFFSET, 1); - WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC5_REGISTER_OFFSET, 1); + if (!(rdev->flags & RADEON_IS_IGP)) { + WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC2_REGISTER_OFFSET, 1); + WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC3_REGISTER_OFFSET, 1); + WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC4_REGISTER_OFFSET, 1); + WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC5_REGISTER_OFFSET, 1); + } WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, save->crtc_control[0]); WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, save->crtc_control[1]); - WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, save->crtc_control[2]); - WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, save->crtc_control[3]); - WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET, save->crtc_control[4]); - WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, save->crtc_control[5]); + if (!(rdev->flags & RADEON_IS_IGP)) { + WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, save->crtc_control[2]); + WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, save->crtc_control[3]); + WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET, save->crtc_control[4]); + WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, save->crtc_control[5]); + } WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC0_REGISTER_OFFSET, 0); WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC1_REGISTER_OFFSET, 0); - WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC2_REGISTER_OFFSET, 0); - WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC3_REGISTER_OFFSET, 0); - WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC4_REGISTER_OFFSET, 0); - WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC5_REGISTER_OFFSET, 0); + if (!(rdev->flags & RADEON_IS_IGP)) { + WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC2_REGISTER_OFFSET, 0); + WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC3_REGISTER_OFFSET, 0); + WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC4_REGISTER_OFFSET, 0); + WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC5_REGISTER_OFFSET, 0); + } WREG32(VGA_RENDER_CONTROL, save->vga_render_control); } @@ -2068,17 +2084,21 @@ void evergreen_disable_interrupt_state(struct radeon_device *rdev) WREG32(GRBM_INT_CNTL, 0); WREG32(INT_MASK + EVERGREEN_CRTC0_REGISTER_OFFSET, 0); WREG32(INT_MASK + EVERGREEN_CRTC1_REGISTER_OFFSET, 0); - WREG32(INT_MASK + EVERGREEN_CRTC2_REGISTER_OFFSET, 0); - WREG32(INT_MASK + EVERGREEN_CRTC3_REGISTER_OFFSET, 0); - WREG32(INT_MASK + EVERGREEN_CRTC4_REGISTER_OFFSET, 0); - WREG32(INT_MASK + EVERGREEN_CRTC5_REGISTER_OFFSET, 0); + if (!(rdev->flags & RADEON_IS_IGP)) { + WREG32(INT_MASK + EVERGREEN_CRTC2_REGISTER_OFFSET, 0); + WREG32(INT_MASK + EVERGREEN_CRTC3_REGISTER_OFFSET, 0); + WREG32(INT_MASK + EVERGREEN_CRTC4_REGISTER_OFFSET, 0); + WREG32(INT_MASK + EVERGREEN_CRTC5_REGISTER_OFFSET, 0); + } WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, 0); WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, 0); - WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, 0); - WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, 0); - WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET, 0); - WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, 0); + if (!(rdev->flags & RADEON_IS_IGP)) { + WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, 0); + WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, 0); + WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET, 0); + WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, 0); + } WREG32(DACA_AUTODETECT_INT_CONTROL, 0); WREG32(DACB_AUTODETECT_INT_CONTROL, 0); @@ -2187,10 +2207,12 @@ int evergreen_irq_set(struct radeon_device *rdev) WREG32(INT_MASK + EVERGREEN_CRTC0_REGISTER_OFFSET, crtc1); WREG32(INT_MASK + EVERGREEN_CRTC1_REGISTER_OFFSET, crtc2); - WREG32(INT_MASK + EVERGREEN_CRTC2_REGISTER_OFFSET, crtc3); - WREG32(INT_MASK + EVERGREEN_CRTC3_REGISTER_OFFSET, crtc4); - WREG32(INT_MASK + EVERGREEN_CRTC4_REGISTER_OFFSET, crtc5); - WREG32(INT_MASK + EVERGREEN_CRTC5_REGISTER_OFFSET, crtc6); + if (!(rdev->flags & RADEON_IS_IGP)) { + WREG32(INT_MASK + EVERGREEN_CRTC2_REGISTER_OFFSET, crtc3); + WREG32(INT_MASK + EVERGREEN_CRTC3_REGISTER_OFFSET, crtc4); + WREG32(INT_MASK + EVERGREEN_CRTC4_REGISTER_OFFSET, crtc5); + WREG32(INT_MASK + EVERGREEN_CRTC5_REGISTER_OFFSET, crtc6); + } WREG32(DC_HPD1_INT_CONTROL, hpd1); WREG32(DC_HPD2_INT_CONTROL, hpd2); @@ -2710,12 +2732,16 @@ static bool evergreen_card_posted(struct radeon_device *rdev) u32 reg; /* first check CRTCs */ - reg = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET) | - RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET) | - RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET) | - RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET) | - RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET) | - RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET); + if (rdev->flags & RADEON_IS_IGP) + reg = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET) | + RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET); + else + reg = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET) | + RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET) | + RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET) | + RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET) | + RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET) | + RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET); if (reg & EVERGREEN_CRTC_MASTER_EN) return true; diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index d8ac1849180d..dd93c9c94144 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c @@ -335,7 +335,12 @@ bool radeon_card_posted(struct radeon_device *rdev) uint32_t reg; /* first check CRTCs */ - if (ASIC_IS_DCE4(rdev)) { + if (ASIC_IS_DCE41(rdev)) { + reg = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET) | + RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET); + if (reg & EVERGREEN_CRTC_MASTER_EN) + return true; + } else if (ASIC_IS_DCE4(rdev)) { reg = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET) | RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET) | RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET) | -- cgit v1.2.3 From 958261d1e8755d1423beb0951ed0b9552c96f638 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Mon, 22 Nov 2010 17:56:30 -0500 Subject: drm/radeon/kms: add radeon_asic struct for AMD Ontario fusion APUs Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/radeon_asic.c | 46 ++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c index bf7ec0441e63..4e487cc16e7f 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.c +++ b/drivers/gpu/drm/radeon/radeon_asic.c @@ -751,6 +751,49 @@ static struct radeon_asic evergreen_asic = { .pm_get_dynpm_state = &r600_pm_get_dynpm_state, }; +static struct radeon_asic sumo_asic = { + .init = &evergreen_init, + .fini = &evergreen_fini, + .suspend = &evergreen_suspend, + .resume = &evergreen_resume, + .cp_commit = &r600_cp_commit, + .gpu_is_lockup = &evergreen_gpu_is_lockup, + .asic_reset = &evergreen_asic_reset, + .vga_set_state = &r600_vga_set_state, + .gart_tlb_flush = &evergreen_pcie_gart_tlb_flush, + .gart_set_page = &rs600_gart_set_page, + .ring_test = &r600_ring_test, + .ring_ib_execute = &r600_ring_ib_execute, + .irq_set = &evergreen_irq_set, + .irq_process = &evergreen_irq_process, + .get_vblank_counter = &evergreen_get_vblank_counter, + .fence_ring_emit = &r600_fence_ring_emit, + .cs_parse = &evergreen_cs_parse, + .copy_blit = NULL, + .copy_dma = NULL, + .copy = NULL, + .get_engine_clock = &radeon_atom_get_engine_clock, + .set_engine_clock = &radeon_atom_set_engine_clock, + .get_memory_clock = NULL, + .set_memory_clock = NULL, + .get_pcie_lanes = NULL, + .set_pcie_lanes = NULL, + .set_clock_gating = NULL, + .set_surface_reg = r600_set_surface_reg, + .clear_surface_reg = r600_clear_surface_reg, + .bandwidth_update = &evergreen_bandwidth_update, + .hpd_init = &evergreen_hpd_init, + .hpd_fini = &evergreen_hpd_fini, + .hpd_sense = &evergreen_hpd_sense, + .hpd_set_polarity = &evergreen_hpd_set_polarity, + .gui_idle = &r600_gui_idle, + .pm_misc = &evergreen_pm_misc, + .pm_prepare = &evergreen_pm_prepare, + .pm_finish = &evergreen_pm_finish, + .pm_init_profile = &rs780_pm_init_profile, + .pm_get_dynpm_state = &r600_pm_get_dynpm_state, +}; + int radeon_asic_init(struct radeon_device *rdev) { radeon_register_accessor_init(rdev); @@ -835,6 +878,9 @@ int radeon_asic_init(struct radeon_device *rdev) case CHIP_HEMLOCK: rdev->asic = &evergreen_asic; break; + case CHIP_PALM: + rdev->asic = &sumo_asic; + break; default: /* FIXME: not supported yet */ return -EINVAL; -- cgit v1.2.3 From d5e455e48b095df7f5381dff028f8523aaf565a9 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Mon, 22 Nov 2010 17:56:29 -0500 Subject: drm/radeon/kms: fill in GPU init for AMD Ontario Fusion APUs Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/evergreen.c | 49 ++++++++++++++++++++++++++++++++++---- 1 file changed, 44 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index 07c4c6f216f0..7f859ffe99ce 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c @@ -1299,6 +1299,7 @@ static u32 evergreen_get_tile_pipe_to_backend_map(struct radeon_device *rdev, switch (rdev->family) { case CHIP_CEDAR: case CHIP_REDWOOD: + case CHIP_PALM: force_no_swizzle = false; break; case CHIP_CYPRESS: @@ -1423,6 +1424,7 @@ static void evergreen_program_channel_remap(struct radeon_device *rdev) case CHIP_JUNIPER: case CHIP_REDWOOD: case CHIP_CEDAR: + case CHIP_PALM: default: tcp_chan_steer_lo = 0x76543210; tcp_chan_steer_hi = 0x0000ba98; @@ -1541,6 +1543,27 @@ static void evergreen_gpu_init(struct radeon_device *rdev) rdev->config.evergreen.max_hw_contexts = 4; rdev->config.evergreen.sq_num_cf_insts = 1; + rdev->config.evergreen.sc_prim_fifo_size = 0x40; + rdev->config.evergreen.sc_hiz_tile_fifo_size = 0x30; + rdev->config.evergreen.sc_earlyz_tile_fifo_size = 0x130; + break; + case CHIP_PALM: + rdev->config.evergreen.num_ses = 1; + rdev->config.evergreen.max_pipes = 2; + rdev->config.evergreen.max_tile_pipes = 2; + rdev->config.evergreen.max_simds = 2; + rdev->config.evergreen.max_backends = 1 * rdev->config.evergreen.num_ses; + rdev->config.evergreen.max_gprs = 256; + rdev->config.evergreen.max_threads = 192; + rdev->config.evergreen.max_gs_threads = 16; + rdev->config.evergreen.max_stack_entries = 256; + rdev->config.evergreen.sx_num_of_sets = 4; + rdev->config.evergreen.sx_max_export_size = 128; + rdev->config.evergreen.sx_max_export_pos_size = 32; + rdev->config.evergreen.sx_max_export_smx_size = 96; + rdev->config.evergreen.max_hw_contexts = 4; + rdev->config.evergreen.sq_num_cf_insts = 1; + rdev->config.evergreen.sc_prim_fifo_size = 0x40; rdev->config.evergreen.sc_hiz_tile_fifo_size = 0x30; rdev->config.evergreen.sc_earlyz_tile_fifo_size = 0x130; @@ -1821,9 +1844,15 @@ static void evergreen_gpu_init(struct radeon_device *rdev) GS_PRIO(2) | ES_PRIO(3)); - if (rdev->family == CHIP_CEDAR) + switch (rdev->family) { + case CHIP_CEDAR: + case CHIP_PALM: /* no vertex cache */ sq_config &= ~VC_ENABLE; + break; + default: + break; + } sq_lds_resource_mgmt = RREG32(SQ_LDS_RESOURCE_MGMT); @@ -1835,10 +1864,15 @@ static void evergreen_gpu_init(struct radeon_device *rdev) sq_gpr_resource_mgmt_3 = NUM_HS_GPRS((rdev->config.evergreen.max_gprs - (4 * 2)) * 3 / 32); sq_gpr_resource_mgmt_3 |= NUM_LS_GPRS((rdev->config.evergreen.max_gprs - (4 * 2)) * 3 / 32); - if (rdev->family == CHIP_CEDAR) + switch (rdev->family) { + case CHIP_CEDAR: + case CHIP_PALM: ps_thread_count = 96; - else + break; + default: ps_thread_count = 128; + break; + } sq_thread_resource_mgmt = NUM_PS_THREADS(ps_thread_count); sq_thread_resource_mgmt |= NUM_VS_THREADS((((rdev->config.evergreen.max_threads - ps_thread_count) / 6) / 8) * 8); @@ -1869,10 +1903,15 @@ static void evergreen_gpu_init(struct radeon_device *rdev) WREG32(PA_SC_FORCE_EOV_MAX_CNTS, (FORCE_EOV_MAX_CLK_CNT(4095) | FORCE_EOV_MAX_REZ_CNT(255))); - if (rdev->family == CHIP_CEDAR) + switch (rdev->family) { + case CHIP_CEDAR: + case CHIP_PALM: vgt_cache_invalidation = CACHE_INVALIDATION(TC_ONLY); - else + break; + default: vgt_cache_invalidation = CACHE_INVALIDATION(VC_AND_TC); + break; + } vgt_cache_invalidation |= AUTO_INVLD_EN(ES_AND_GS_AUTO); WREG32(VGT_CACHE_INVALIDATION, vgt_cache_invalidation); -- cgit v1.2.3 From e33df25fecd31be889a878bc75313817bc292bac Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Mon, 22 Nov 2010 17:56:32 -0500 Subject: drm/radeon/kms: add thermal sensor support for fusion APUs Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/evergreen.c | 8 ++++++++ drivers/gpu/drm/radeon/evergreend.h | 4 +++- drivers/gpu/drm/radeon/radeon.h | 2 ++ drivers/gpu/drm/radeon/radeon_pm.c | 4 ++++ 4 files changed, 17 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index 7f859ffe99ce..075d6c172595 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c @@ -57,6 +57,14 @@ u32 evergreen_get_temp(struct radeon_device *rdev) return actual_temp * 1000; } +u32 sumo_get_temp(struct radeon_device *rdev) +{ + u32 temp = RREG32(CG_THERMAL_STATUS) & 0xff; + u32 actual_temp = (temp >> 1) & 0xff; + + return actual_temp * 1000; +} + void evergreen_pm_misc(struct radeon_device *rdev) { int req_ps_idx = rdev->pm.requested_power_state_index; diff --git a/drivers/gpu/drm/radeon/evergreend.h b/drivers/gpu/drm/radeon/evergreend.h index 9644b1cbfb09..87fcaba76695 100644 --- a/drivers/gpu/drm/radeon/evergreend.h +++ b/drivers/gpu/drm/radeon/evergreend.h @@ -164,11 +164,13 @@ #define SE_SC_BUSY (1 << 29) #define SE_DB_BUSY (1 << 30) #define SE_CB_BUSY (1 << 31) - +/* evergreen */ #define CG_MULT_THERMAL_STATUS 0x740 #define ASIC_T(x) ((x) << 16) #define ASIC_T_MASK 0x7FF0000 #define ASIC_T_SHIFT 16 +/* APU */ +#define CG_THERMAL_STATUS 0x678 #define HDP_HOST_PATH_CNTL 0x2C00 #define HDP_NONSURFACE_BASE 0x2C04 diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index bf3a4fc82964..0507ee7e16eb 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h @@ -180,6 +180,7 @@ void rs690_pm_info(struct radeon_device *rdev); extern u32 rv6xx_get_temp(struct radeon_device *rdev); extern u32 rv770_get_temp(struct radeon_device *rdev); extern u32 evergreen_get_temp(struct radeon_device *rdev); +extern u32 sumo_get_temp(struct radeon_device *rdev); /* * Fences. @@ -687,6 +688,7 @@ enum radeon_int_thermal_type { THERMAL_TYPE_RV6XX, THERMAL_TYPE_RV770, THERMAL_TYPE_EVERGREEN, + THERMAL_TYPE_SUMO, }; struct radeon_voltage { diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c index 8c9b2ef32c68..ac4efb0f1cb4 100644 --- a/drivers/gpu/drm/radeon/radeon_pm.c +++ b/drivers/gpu/drm/radeon/radeon_pm.c @@ -449,6 +449,9 @@ static ssize_t radeon_hwmon_show_temp(struct device *dev, case THERMAL_TYPE_EVERGREEN: temp = evergreen_get_temp(rdev); break; + case THERMAL_TYPE_SUMO: + temp = sumo_get_temp(rdev); + break; default: temp = 0; break; @@ -487,6 +490,7 @@ static int radeon_hwmon_init(struct radeon_device *rdev) case THERMAL_TYPE_RV6XX: case THERMAL_TYPE_RV770: case THERMAL_TYPE_EVERGREEN: + case THERMAL_TYPE_SUMO: rdev->pm.int_hwmon_dev = hwmon_device_register(rdev->dev); if (IS_ERR(rdev->pm.int_hwmon_dev)) { err = PTR_ERR(rdev->pm.int_hwmon_dev); -- cgit v1.2.3 From e719ebd916c2ecee072affc9e7f0b92aa33c2f94 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Mon, 22 Nov 2010 17:56:33 -0500 Subject: drm/radeon/kms: add bo blit support for Ontario fusion APUs Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/evergreen_blit_kms.c | 27 +++++++++++++++++++++++++-- drivers/gpu/drm/radeon/radeon_asic.c | 6 +++--- 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/radeon/evergreen_blit_kms.c b/drivers/gpu/drm/radeon/evergreen_blit_kms.c index e0e590110dd4..2ccd1f0545fe 100644 --- a/drivers/gpu/drm/radeon/evergreen_blit_kms.c +++ b/drivers/gpu/drm/radeon/evergreen_blit_kms.c @@ -147,7 +147,8 @@ set_vtx_resource(struct radeon_device *rdev, u64 gpu_addr) radeon_ring_write(rdev, 0); radeon_ring_write(rdev, SQ_TEX_VTX_VALID_BUFFER << 30); - if (rdev->family == CHIP_CEDAR) + if ((rdev->family == CHIP_CEDAR) || + (rdev->family == CHIP_PALM)) cp_set_surface_sync(rdev, PACKET3_TC_ACTION_ENA, 48, gpu_addr); else @@ -331,9 +332,31 @@ set_default_state(struct radeon_device *rdev) num_hs_stack_entries = 85; num_ls_stack_entries = 85; break; + case CHIP_PALM: + num_ps_gprs = 93; + num_vs_gprs = 46; + num_temp_gprs = 4; + num_gs_gprs = 31; + num_es_gprs = 31; + num_hs_gprs = 23; + num_ls_gprs = 23; + num_ps_threads = 96; + num_vs_threads = 16; + num_gs_threads = 16; + num_es_threads = 16; + num_hs_threads = 16; + num_ls_threads = 16; + num_ps_stack_entries = 42; + num_vs_stack_entries = 42; + num_gs_stack_entries = 42; + num_es_stack_entries = 42; + num_hs_stack_entries = 42; + num_ls_stack_entries = 42; + break; } - if (rdev->family == CHIP_CEDAR) + if ((rdev->family == CHIP_CEDAR) || + (rdev->family == CHIP_PALM)) sq_config = 0; else sq_config = VC_ENABLE; diff --git a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c index 4e487cc16e7f..de7bfbcd09c9 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.c +++ b/drivers/gpu/drm/radeon/radeon_asic.c @@ -769,9 +769,9 @@ static struct radeon_asic sumo_asic = { .get_vblank_counter = &evergreen_get_vblank_counter, .fence_ring_emit = &r600_fence_ring_emit, .cs_parse = &evergreen_cs_parse, - .copy_blit = NULL, - .copy_dma = NULL, - .copy = NULL, + .copy_blit = &evergreen_copy_blit, + .copy_dma = &evergreen_copy_blit, + .copy = &evergreen_copy_blit, .get_engine_clock = &radeon_atom_get_engine_clock, .set_engine_clock = &radeon_atom_set_engine_clock, .get_memory_clock = NULL, -- cgit v1.2.3 From 560154e9a27f2f260fcb2dd18c488203246f257e Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Mon, 22 Nov 2010 17:56:34 -0500 Subject: drm/radeon/kms: refactor atombios power state fetching The function was getting too large. Rework it to share more state better handle new power table formats. Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/radeon_atombios.c | 941 ++++++++++++++++--------------- 1 file changed, 475 insertions(+), 466 deletions(-) diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c index 4d37b2d1ba74..7056e20d329d 100644 --- a/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/drivers/gpu/drm/radeon/radeon_atombios.c @@ -1763,495 +1763,504 @@ static const char *pp_lib_thermal_controller_names[] = { "RV6xx", "RV770", "adt7473", + "NONE", "External GPIO", "Evergreen", "adt7473 with internal", - }; union power_info { struct _ATOM_POWERPLAY_INFO info; struct _ATOM_POWERPLAY_INFO_V2 info_2; struct _ATOM_POWERPLAY_INFO_V3 info_3; - struct _ATOM_PPLIB_POWERPLAYTABLE info_4; + struct _ATOM_PPLIB_POWERPLAYTABLE pplib; }; -void radeon_atombios_get_power_modes(struct radeon_device *rdev) +union pplib_clock_info { + struct _ATOM_PPLIB_R600_CLOCK_INFO r600; + struct _ATOM_PPLIB_RS780_CLOCK_INFO rs780; + struct _ATOM_PPLIB_EVERGREEN_CLOCK_INFO evergreen; +}; + +union pplib_power_state { + struct _ATOM_PPLIB_STATE v1; + struct _ATOM_PPLIB_STATE_V2 v2; +}; + +static void radeon_atombios_parse_misc_flags_1_3(struct radeon_device *rdev, + int state_index, + u32 misc, u32 misc2) +{ + rdev->pm.power_state[state_index].misc = misc; + rdev->pm.power_state[state_index].misc2 = misc2; + /* order matters! */ + if (misc & ATOM_PM_MISCINFO_POWER_SAVING_MODE) + rdev->pm.power_state[state_index].type = + POWER_STATE_TYPE_POWERSAVE; + if (misc & ATOM_PM_MISCINFO_DEFAULT_DC_STATE_ENTRY_TRUE) + rdev->pm.power_state[state_index].type = + POWER_STATE_TYPE_BATTERY; + if (misc & ATOM_PM_MISCINFO_DEFAULT_LOW_DC_STATE_ENTRY_TRUE) + rdev->pm.power_state[state_index].type = + POWER_STATE_TYPE_BATTERY; + if (misc & ATOM_PM_MISCINFO_LOAD_BALANCE_EN) + rdev->pm.power_state[state_index].type = + POWER_STATE_TYPE_BALANCED; + if (misc & ATOM_PM_MISCINFO_3D_ACCELERATION_EN) { + rdev->pm.power_state[state_index].type = + POWER_STATE_TYPE_PERFORMANCE; + rdev->pm.power_state[state_index].flags &= + ~RADEON_PM_STATE_SINGLE_DISPLAY_ONLY; + } + if (misc2 & ATOM_PM_MISCINFO2_SYSTEM_AC_LITE_MODE) + rdev->pm.power_state[state_index].type = + POWER_STATE_TYPE_BALANCED; + if (misc & ATOM_PM_MISCINFO_DRIVER_DEFAULT_MODE) { + rdev->pm.power_state[state_index].type = + POWER_STATE_TYPE_DEFAULT; + rdev->pm.default_power_state_index = state_index; + rdev->pm.power_state[state_index].default_clock_mode = + &rdev->pm.power_state[state_index].clock_info[0]; + } else if (state_index == 0) { + rdev->pm.power_state[state_index].clock_info[0].flags |= + RADEON_PM_MODE_NO_DISPLAY; + } +} + +static int radeon_atombios_parse_power_table_1_3(struct radeon_device *rdev) { struct radeon_mode_info *mode_info = &rdev->mode_info; + u32 misc, misc2 = 0; + int num_modes = 0, i; + int state_index = 0; + struct radeon_i2c_bus_rec i2c_bus; + union power_info *power_info; int index = GetIndexIntoMasterTable(DATA, PowerPlayInfo); - u16 data_offset; + u16 data_offset; u8 frev, crev; - u32 misc, misc2 = 0, sclk, mclk; - union power_info *power_info; - struct _ATOM_PPLIB_NONCLOCK_INFO *non_clock_info; - struct _ATOM_PPLIB_STATE *power_state; - int num_modes = 0, i, j; - int state_index = 0, mode_index = 0; - struct radeon_i2c_bus_rec i2c_bus; - - rdev->pm.default_power_state_index = -1; - if (atom_parse_data_header(mode_info->atom_context, index, NULL, - &frev, &crev, &data_offset)) { - power_info = (union power_info *)(mode_info->atom_context->bios + data_offset); - if (frev < 4) { - /* add the i2c bus for thermal/fan chip */ - if (power_info->info.ucOverdriveThermalController > 0) { - DRM_INFO("Possible %s thermal controller at 0x%02x\n", - thermal_controller_names[power_info->info.ucOverdriveThermalController], - power_info->info.ucOverdriveControllerAddress >> 1); - i2c_bus = radeon_lookup_i2c_gpio(rdev, power_info->info.ucOverdriveI2cLine); - rdev->pm.i2c_bus = radeon_i2c_lookup(rdev, &i2c_bus); - if (rdev->pm.i2c_bus) { - struct i2c_board_info info = { }; - const char *name = thermal_controller_names[power_info->info. - ucOverdriveThermalController]; - info.addr = power_info->info.ucOverdriveControllerAddress >> 1; - strlcpy(info.type, name, sizeof(info.type)); - i2c_new_device(&rdev->pm.i2c_bus->adapter, &info); - } + if (!atom_parse_data_header(mode_info->atom_context, index, NULL, + &frev, &crev, &data_offset)) + return state_index; + power_info = (union power_info *)(mode_info->atom_context->bios + data_offset); + + /* add the i2c bus for thermal/fan chip */ + if (power_info->info.ucOverdriveThermalController > 0) { + DRM_INFO("Possible %s thermal controller at 0x%02x\n", + thermal_controller_names[power_info->info.ucOverdriveThermalController], + power_info->info.ucOverdriveControllerAddress >> 1); + i2c_bus = radeon_lookup_i2c_gpio(rdev, power_info->info.ucOverdriveI2cLine); + rdev->pm.i2c_bus = radeon_i2c_lookup(rdev, &i2c_bus); + if (rdev->pm.i2c_bus) { + struct i2c_board_info info = { }; + const char *name = thermal_controller_names[power_info->info. + ucOverdriveThermalController]; + info.addr = power_info->info.ucOverdriveControllerAddress >> 1; + strlcpy(info.type, name, sizeof(info.type)); + i2c_new_device(&rdev->pm.i2c_bus->adapter, &info); + } + } + num_modes = power_info->info.ucNumOfPowerModeEntries; + if (num_modes > ATOM_MAX_NUMBEROF_POWER_BLOCK) + num_modes = ATOM_MAX_NUMBEROF_POWER_BLOCK; + /* last mode is usually default, array is low to high */ + for (i = 0; i < num_modes; i++) { + rdev->pm.power_state[state_index].clock_info[0].voltage.type = VOLTAGE_NONE; + switch (frev) { + case 1: + rdev->pm.power_state[state_index].num_clock_modes = 1; + rdev->pm.power_state[state_index].clock_info[0].mclk = + le16_to_cpu(power_info->info.asPowerPlayInfo[i].usMemoryClock); + rdev->pm.power_state[state_index].clock_info[0].sclk = + le16_to_cpu(power_info->info.asPowerPlayInfo[i].usEngineClock); + /* skip invalid modes */ + if ((rdev->pm.power_state[state_index].clock_info[0].mclk == 0) || + (rdev->pm.power_state[state_index].clock_info[0].sclk == 0)) + continue; + rdev->pm.power_state[state_index].pcie_lanes = + power_info->info.asPowerPlayInfo[i].ucNumPciELanes; + misc = le32_to_cpu(power_info->info.asPowerPlayInfo[i].ulMiscInfo); + if ((misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_SUPPORT) || + (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_ACTIVE_HIGH)) { + rdev->pm.power_state[state_index].clock_info[0].voltage.type = + VOLTAGE_GPIO; + rdev->pm.power_state[state_index].clock_info[0].voltage.gpio = + radeon_lookup_gpio(rdev, + power_info->info.asPowerPlayInfo[i].ucVoltageDropIndex); + if (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_ACTIVE_HIGH) + rdev->pm.power_state[state_index].clock_info[0].voltage.active_high = + true; + else + rdev->pm.power_state[state_index].clock_info[0].voltage.active_high = + false; + } else if (misc & ATOM_PM_MISCINFO_PROGRAM_VOLTAGE) { + rdev->pm.power_state[state_index].clock_info[0].voltage.type = + VOLTAGE_VDDC; + rdev->pm.power_state[state_index].clock_info[0].voltage.vddc_id = + power_info->info.asPowerPlayInfo[i].ucVoltageDropIndex; } - num_modes = power_info->info.ucNumOfPowerModeEntries; - if (num_modes > ATOM_MAX_NUMBEROF_POWER_BLOCK) - num_modes = ATOM_MAX_NUMBEROF_POWER_BLOCK; - /* last mode is usually default, array is low to high */ - for (i = 0; i < num_modes; i++) { - rdev->pm.power_state[state_index].clock_info[0].voltage.type = VOLTAGE_NONE; - switch (frev) { - case 1: - rdev->pm.power_state[state_index].num_clock_modes = 1; - rdev->pm.power_state[state_index].clock_info[0].mclk = - le16_to_cpu(power_info->info.asPowerPlayInfo[i].usMemoryClock); - rdev->pm.power_state[state_index].clock_info[0].sclk = - le16_to_cpu(power_info->info.asPowerPlayInfo[i].usEngineClock); - /* skip invalid modes */ - if ((rdev->pm.power_state[state_index].clock_info[0].mclk == 0) || - (rdev->pm.power_state[state_index].clock_info[0].sclk == 0)) - continue; - rdev->pm.power_state[state_index].pcie_lanes = - power_info->info.asPowerPlayInfo[i].ucNumPciELanes; - misc = le32_to_cpu(power_info->info.asPowerPlayInfo[i].ulMiscInfo); - if ((misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_SUPPORT) || - (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_ACTIVE_HIGH)) { - rdev->pm.power_state[state_index].clock_info[0].voltage.type = - VOLTAGE_GPIO; - rdev->pm.power_state[state_index].clock_info[0].voltage.gpio = - radeon_lookup_gpio(rdev, - power_info->info.asPowerPlayInfo[i].ucVoltageDropIndex); - if (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_ACTIVE_HIGH) - rdev->pm.power_state[state_index].clock_info[0].voltage.active_high = - true; - else - rdev->pm.power_state[state_index].clock_info[0].voltage.active_high = - false; - } else if (misc & ATOM_PM_MISCINFO_PROGRAM_VOLTAGE) { - rdev->pm.power_state[state_index].clock_info[0].voltage.type = - VOLTAGE_VDDC; - rdev->pm.power_state[state_index].clock_info[0].voltage.vddc_id = - power_info->info.asPowerPlayInfo[i].ucVoltageDropIndex; - } - rdev->pm.power_state[state_index].flags = RADEON_PM_STATE_SINGLE_DISPLAY_ONLY; - rdev->pm.power_state[state_index].misc = misc; - /* order matters! */ - if (misc & ATOM_PM_MISCINFO_POWER_SAVING_MODE) - rdev->pm.power_state[state_index].type = - POWER_STATE_TYPE_POWERSAVE; - if (misc & ATOM_PM_MISCINFO_DEFAULT_DC_STATE_ENTRY_TRUE) - rdev->pm.power_state[state_index].type = - POWER_STATE_TYPE_BATTERY; - if (misc & ATOM_PM_MISCINFO_DEFAULT_LOW_DC_STATE_ENTRY_TRUE) - rdev->pm.power_state[state_index].type = - POWER_STATE_TYPE_BATTERY; - if (misc & ATOM_PM_MISCINFO_LOAD_BALANCE_EN) - rdev->pm.power_state[state_index].type = - POWER_STATE_TYPE_BALANCED; - if (misc & ATOM_PM_MISCINFO_3D_ACCELERATION_EN) { - rdev->pm.power_state[state_index].type = - POWER_STATE_TYPE_PERFORMANCE; - rdev->pm.power_state[state_index].flags &= - ~RADEON_PM_STATE_SINGLE_DISPLAY_ONLY; - } - if (misc & ATOM_PM_MISCINFO_DRIVER_DEFAULT_MODE) { - rdev->pm.power_state[state_index].type = - POWER_STATE_TYPE_DEFAULT; - rdev->pm.default_power_state_index = state_index; - rdev->pm.power_state[state_index].default_clock_mode = - &rdev->pm.power_state[state_index].clock_info[0]; - rdev->pm.power_state[state_index].flags &= - ~RADEON_PM_STATE_SINGLE_DISPLAY_ONLY; - } else if (state_index == 0) { - rdev->pm.power_state[state_index].clock_info[0].flags |= - RADEON_PM_MODE_NO_DISPLAY; - } - state_index++; - break; - case 2: - rdev->pm.power_state[state_index].num_clock_modes = 1; - rdev->pm.power_state[state_index].clock_info[0].mclk = - le32_to_cpu(power_info->info_2.asPowerPlayInfo[i].ulMemoryClock); - rdev->pm.power_state[state_index].clock_info[0].sclk = - le32_to_cpu(power_info->info_2.asPowerPlayInfo[i].ulEngineClock); - /* skip invalid modes */ - if ((rdev->pm.power_state[state_index].clock_info[0].mclk == 0) || - (rdev->pm.power_state[state_index].clock_info[0].sclk == 0)) - continue; - rdev->pm.power_state[state_index].pcie_lanes = - power_info->info_2.asPowerPlayInfo[i].ucNumPciELanes; - misc = le32_to_cpu(power_info->info_2.asPowerPlayInfo[i].ulMiscInfo); - misc2 = le32_to_cpu(power_info->info_2.asPowerPlayInfo[i].ulMiscInfo2); - if ((misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_SUPPORT) || - (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_ACTIVE_HIGH)) { - rdev->pm.power_state[state_index].clock_info[0].voltage.type = - VOLTAGE_GPIO; - rdev->pm.power_state[state_index].clock_info[0].voltage.gpio = - radeon_lookup_gpio(rdev, - power_info->info_2.asPowerPlayInfo[i].ucVoltageDropIndex); - if (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_ACTIVE_HIGH) - rdev->pm.power_state[state_index].clock_info[0].voltage.active_high = - true; - else - rdev->pm.power_state[state_index].clock_info[0].voltage.active_high = - false; - } else if (misc & ATOM_PM_MISCINFO_PROGRAM_VOLTAGE) { - rdev->pm.power_state[state_index].clock_info[0].voltage.type = - VOLTAGE_VDDC; - rdev->pm.power_state[state_index].clock_info[0].voltage.vddc_id = - power_info->info_2.asPowerPlayInfo[i].ucVoltageDropIndex; - } - rdev->pm.power_state[state_index].flags = RADEON_PM_STATE_SINGLE_DISPLAY_ONLY; - rdev->pm.power_state[state_index].misc = misc; - rdev->pm.power_state[state_index].misc2 = misc2; - /* order matters! */ - if (misc & ATOM_PM_MISCINFO_POWER_SAVING_MODE) - rdev->pm.power_state[state_index].type = - POWER_STATE_TYPE_POWERSAVE; - if (misc & ATOM_PM_MISCINFO_DEFAULT_DC_STATE_ENTRY_TRUE) - rdev->pm.power_state[state_index].type = - POWER_STATE_TYPE_BATTERY; - if (misc & ATOM_PM_MISCINFO_DEFAULT_LOW_DC_STATE_ENTRY_TRUE) - rdev->pm.power_state[state_index].type = - POWER_STATE_TYPE_BATTERY; - if (misc & ATOM_PM_MISCINFO_LOAD_BALANCE_EN) - rdev->pm.power_state[state_index].type = - POWER_STATE_TYPE_BALANCED; - if (misc & ATOM_PM_MISCINFO_3D_ACCELERATION_EN) { - rdev->pm.power_state[state_index].type = - POWER_STATE_TYPE_PERFORMANCE; - rdev->pm.power_state[state_index].flags &= - ~RADEON_PM_STATE_SINGLE_DISPLAY_ONLY; - } - if (misc2 & ATOM_PM_MISCINFO2_SYSTEM_AC_LITE_MODE) - rdev->pm.power_state[state_index].type = - POWER_STATE_TYPE_BALANCED; - if (misc2 & ATOM_PM_MISCINFO2_MULTI_DISPLAY_SUPPORT) - rdev->pm.power_state[state_index].flags &= - ~RADEON_PM_STATE_SINGLE_DISPLAY_ONLY; - if (misc & ATOM_PM_MISCINFO_DRIVER_DEFAULT_MODE) { - rdev->pm.power_state[state_index].type = - POWER_STATE_TYPE_DEFAULT; - rdev->pm.default_power_state_index = state_index; - rdev->pm.power_state[state_index].default_clock_mode = - &rdev->pm.power_state[state_index].clock_info[0]; - rdev->pm.power_state[state_index].flags &= - ~RADEON_PM_STATE_SINGLE_DISPLAY_ONLY; - } else if (state_index == 0) { - rdev->pm.power_state[state_index].clock_info[0].flags |= - RADEON_PM_MODE_NO_DISPLAY; - } - state_index++; - break; - case 3: - rdev->pm.power_state[state_index].num_clock_modes = 1; - rdev->pm.power_state[state_index].clock_info[0].mclk = - le32_to_cpu(power_info->info_3.asPowerPlayInfo[i].ulMemoryClock); - rdev->pm.power_state[state_index].clock_info[0].sclk = - le32_to_cpu(power_info->info_3.asPowerPlayInfo[i].ulEngineClock); - /* skip invalid modes */ - if ((rdev->pm.power_state[state_index].clock_info[0].mclk == 0) || - (rdev->pm.power_state[state_index].clock_info[0].sclk == 0)) - continue; - rdev->pm.power_state[state_index].pcie_lanes = - power_info->info_3.asPowerPlayInfo[i].ucNumPciELanes; - misc = le32_to_cpu(power_info->info_3.asPowerPlayInfo[i].ulMiscInfo); - misc2 = le32_to_cpu(power_info->info_3.asPowerPlayInfo[i].ulMiscInfo2); - if ((misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_SUPPORT) || - (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_ACTIVE_HIGH)) { - rdev->pm.power_state[state_index].clock_info[0].voltage.type = - VOLTAGE_GPIO; - rdev->pm.power_state[state_index].clock_info[0].voltage.gpio = - radeon_lookup_gpio(rdev, - power_info->info_3.asPowerPlayInfo[i].ucVoltageDropIndex); - if (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_ACTIVE_HIGH) - rdev->pm.power_state[state_index].clock_info[0].voltage.active_high = - true; - else - rdev->pm.power_state[state_index].clock_info[0].voltage.active_high = - false; - } else if (misc & ATOM_PM_MISCINFO_PROGRAM_VOLTAGE) { - rdev->pm.power_state[state_index].clock_info[0].voltage.type = - VOLTAGE_VDDC; - rdev->pm.power_state[state_index].clock_info[0].voltage.vddc_id = - power_info->info_3.asPowerPlayInfo[i].ucVoltageDropIndex; - if (misc2 & ATOM_PM_MISCINFO2_VDDCI_DYNAMIC_VOLTAGE_EN) { - rdev->pm.power_state[state_index].clock_info[0].voltage.vddci_enabled = - true; - rdev->pm.power_state[state_index].clock_info[0].voltage.vddci_id = - power_info->info_3.asPowerPlayInfo[i].ucVDDCI_VoltageDropIndex; - } - } - rdev->pm.power_state[state_index].flags = RADEON_PM_STATE_SINGLE_DISPLAY_ONLY; - rdev->pm.power_state[state_index].misc = misc; - rdev->pm.power_state[state_index].misc2 = misc2; - /* order matters! */ - if (misc & ATOM_PM_MISCINFO_POWER_SAVING_MODE) - rdev->pm.power_state[state_index].type = - POWER_STATE_TYPE_POWERSAVE; - if (misc & ATOM_PM_MISCINFO_DEFAULT_DC_STATE_ENTRY_TRUE) - rdev->pm.power_state[state_index].type = - POWER_STATE_TYPE_BATTERY; - if (misc & ATOM_PM_MISCINFO_DEFAULT_LOW_DC_STATE_ENTRY_TRUE) - rdev->pm.power_state[state_index].type = - POWER_STATE_TYPE_BATTERY; - if (misc & ATOM_PM_MISCINFO_LOAD_BALANCE_EN) - rdev->pm.power_state[state_index].type = - POWER_STATE_TYPE_BALANCED; - if (misc & ATOM_PM_MISCINFO_3D_ACCELERATION_EN) { - rdev->pm.power_state[state_index].type = - POWER_STATE_TYPE_PERFORMANCE; - rdev->pm.power_state[state_index].flags &= - ~RADEON_PM_STATE_SINGLE_DISPLAY_ONLY; - } - if (misc2 & ATOM_PM_MISCINFO2_SYSTEM_AC_LITE_MODE) - rdev->pm.power_state[state_index].type = - POWER_STATE_TYPE_BALANCED; - if (misc & ATOM_PM_MISCINFO_DRIVER_DEFAULT_MODE) { - rdev->pm.power_state[state_index].type = - POWER_STATE_TYPE_DEFAULT; - rdev->pm.default_power_state_index = state_index; - rdev->pm.power_state[state_index].default_clock_mode = - &rdev->pm.power_state[state_index].clock_info[0]; - } else if (state_index == 0) { - rdev->pm.power_state[state_index].clock_info[0].flags |= - RADEON_PM_MODE_NO_DISPLAY; - } - state_index++; - break; - } + rdev->pm.power_state[state_index].flags = RADEON_PM_STATE_SINGLE_DISPLAY_ONLY; + radeon_atombios_parse_misc_flags_1_3(rdev, state_index, misc, 0); + state_index++; + break; + case 2: + rdev->pm.power_state[state_index].num_clock_modes = 1; + rdev->pm.power_state[state_index].clock_info[0].mclk = + le32_to_cpu(power_info->info_2.asPowerPlayInfo[i].ulMemoryClock); + rdev->pm.power_state[state_index].clock_info[0].sclk = + le32_to_cpu(power_info->info_2.asPowerPlayInfo[i].ulEngineClock); + /* skip invalid modes */ + if ((rdev->pm.power_state[state_index].clock_info[0].mclk == 0) || + (rdev->pm.power_state[state_index].clock_info[0].sclk == 0)) + continue; + rdev->pm.power_state[state_index].pcie_lanes = + power_info->info_2.asPowerPlayInfo[i].ucNumPciELanes; + misc = le32_to_cpu(power_info->info_2.asPowerPlayInfo[i].ulMiscInfo); + misc2 = le32_to_cpu(power_info->info_2.asPowerPlayInfo[i].ulMiscInfo2); + if ((misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_SUPPORT) || + (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_ACTIVE_HIGH)) { + rdev->pm.power_state[state_index].clock_info[0].voltage.type = + VOLTAGE_GPIO; + rdev->pm.power_state[state_index].clock_info[0].voltage.gpio = + radeon_lookup_gpio(rdev, + power_info->info_2.asPowerPlayInfo[i].ucVoltageDropIndex); + if (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_ACTIVE_HIGH) + rdev->pm.power_state[state_index].clock_info[0].voltage.active_high = + true; + else + rdev->pm.power_state[state_index].clock_info[0].voltage.active_high = + false; + } else if (misc & ATOM_PM_MISCINFO_PROGRAM_VOLTAGE) { + rdev->pm.power_state[state_index].clock_info[0].voltage.type = + VOLTAGE_VDDC; + rdev->pm.power_state[state_index].clock_info[0].voltage.vddc_id = + power_info->info_2.asPowerPlayInfo[i].ucVoltageDropIndex; } - /* last mode is usually default */ - if (rdev->pm.default_power_state_index == -1) { - rdev->pm.power_state[state_index - 1].type = - POWER_STATE_TYPE_DEFAULT; - rdev->pm.default_power_state_index = state_index - 1; - rdev->pm.power_state[state_index - 1].default_clock_mode = - &rdev->pm.power_state[state_index - 1].clock_info[0]; - rdev->pm.power_state[state_index].flags &= - ~RADEON_PM_STATE_SINGLE_DISPLAY_ONLY; - rdev->pm.power_state[state_index].misc = 0; - rdev->pm.power_state[state_index].misc2 = 0; + rdev->pm.power_state[state_index].flags = RADEON_PM_STATE_SINGLE_DISPLAY_ONLY; + radeon_atombios_parse_misc_flags_1_3(rdev, state_index, misc, misc2); + state_index++; + break; + case 3: + rdev->pm.power_state[state_index].num_clock_modes = 1; + rdev->pm.power_state[state_index].clock_info[0].mclk = + le32_to_cpu(power_info->info_3.asPowerPlayInfo[i].ulMemoryClock); + rdev->pm.power_state[state_index].clock_info[0].sclk = + le32_to_cpu(power_info->info_3.asPowerPlayInfo[i].ulEngineClock); + /* skip invalid modes */ + if ((rdev->pm.power_state[state_index].clock_info[0].mclk == 0) || + (rdev->pm.power_state[state_index].clock_info[0].sclk == 0)) + continue; + rdev->pm.power_state[state_index].pcie_lanes = + power_info->info_3.asPowerPlayInfo[i].ucNumPciELanes; + misc = le32_to_cpu(power_info->info_3.asPowerPlayInfo[i].ulMiscInfo); + misc2 = le32_to_cpu(power_info->info_3.asPowerPlayInfo[i].ulMiscInfo2); + if ((misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_SUPPORT) || + (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_ACTIVE_HIGH)) { + rdev->pm.power_state[state_index].clock_info[0].voltage.type = + VOLTAGE_GPIO; + rdev->pm.power_state[state_index].clock_info[0].voltage.gpio = + radeon_lookup_gpio(rdev, + power_info->info_3.asPowerPlayInfo[i].ucVoltageDropIndex); + if (misc & ATOM_PM_MISCINFO_VOLTAGE_DROP_ACTIVE_HIGH) + rdev->pm.power_state[state_index].clock_info[0].voltage.active_high = + true; + else + rdev->pm.power_state[state_index].clock_info[0].voltage.active_high = + false; + } else if (misc & ATOM_PM_MISCINFO_PROGRAM_VOLTAGE) { + rdev->pm.power_state[state_index].clock_info[0].voltage.type = + VOLTAGE_VDDC; + rdev->pm.power_state[state_index].clock_info[0].voltage.vddc_id = + power_info->info_3.asPowerPlayInfo[i].ucVoltageDropIndex; + if (misc2 & ATOM_PM_MISCINFO2_VDDCI_DYNAMIC_VOLTAGE_EN) { + rdev->pm.power_state[state_index].clock_info[0].voltage.vddci_enabled = + true; + rdev->pm.power_state[state_index].clock_info[0].voltage.vddci_id = + power_info->info_3.asPowerPlayInfo[i].ucVDDCI_VoltageDropIndex; + } } + rdev->pm.power_state[state_index].flags = RADEON_PM_STATE_SINGLE_DISPLAY_ONLY; + radeon_atombios_parse_misc_flags_1_3(rdev, state_index, misc, misc2); + state_index++; + break; + } + } + /* last mode is usually default */ + if (rdev->pm.default_power_state_index == -1) { + rdev->pm.power_state[state_index - 1].type = + POWER_STATE_TYPE_DEFAULT; + rdev->pm.default_power_state_index = state_index - 1; + rdev->pm.power_state[state_index - 1].default_clock_mode = + &rdev->pm.power_state[state_index - 1].clock_info[0]; + rdev->pm.power_state[state_index].flags &= + ~RADEON_PM_STATE_SINGLE_DISPLAY_ONLY; + rdev->pm.power_state[state_index].misc = 0; + rdev->pm.power_state[state_index].misc2 = 0; + } + return state_index; +} + +static void radeon_atombios_add_pplib_thermal_controller(struct radeon_device *rdev, + ATOM_PPLIB_THERMALCONTROLLER *controller) +{ + struct radeon_i2c_bus_rec i2c_bus; + + /* add the i2c bus for thermal/fan chip */ + if (controller->ucType > 0) { + if (controller->ucType == ATOM_PP_THERMALCONTROLLER_RV6xx) { + DRM_INFO("Internal thermal controller %s fan control\n", + (controller->ucFanParameters & + ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with"); + rdev->pm.int_thermal_type = THERMAL_TYPE_RV6XX; + } else if (controller->ucType == ATOM_PP_THERMALCONTROLLER_RV770) { + DRM_INFO("Internal thermal controller %s fan control\n", + (controller->ucFanParameters & + ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with"); + rdev->pm.int_thermal_type = THERMAL_TYPE_RV770; + } else if (controller->ucType == ATOM_PP_THERMALCONTROLLER_EVERGREEN) { + DRM_INFO("Internal thermal controller %s fan control\n", + (controller->ucFanParameters & + ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with"); + rdev->pm.int_thermal_type = THERMAL_TYPE_EVERGREEN; + } else if ((controller->ucType == + ATOM_PP_THERMALCONTROLLER_EXTERNAL_GPIO) || + (controller->ucType == + ATOM_PP_THERMALCONTROLLER_ADT7473_WITH_INTERNAL)) { + DRM_INFO("Special thermal controller config\n"); } else { - int fw_index = GetIndexIntoMasterTable(DATA, FirmwareInfo); - uint8_t fw_frev, fw_crev; - uint16_t fw_data_offset, vddc = 0; - union firmware_info *firmware_info; - ATOM_PPLIB_THERMALCONTROLLER *controller = &power_info->info_4.sThermalController; - - if (atom_parse_data_header(mode_info->atom_context, fw_index, NULL, - &fw_frev, &fw_crev, &fw_data_offset)) { - firmware_info = - (union firmware_info *)(mode_info->atom_context->bios + - fw_data_offset); - vddc = firmware_info->info_14.usBootUpVDDCVoltage; + DRM_INFO("Possible %s thermal controller at 0x%02x %s fan control\n", + pp_lib_thermal_controller_names[controller->ucType], + controller->ucI2cAddress >> 1, + (controller->ucFanParameters & + ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with"); + i2c_bus = radeon_lookup_i2c_gpio(rdev, controller->ucI2cLine); + rdev->pm.i2c_bus = radeon_i2c_lookup(rdev, &i2c_bus); + if (rdev->pm.i2c_bus) { + struct i2c_board_info info = { }; + const char *name = pp_lib_thermal_controller_names[controller->ucType]; + info.addr = controller->ucI2cAddress >> 1; + strlcpy(info.type, name, sizeof(info.type)); + i2c_new_device(&rdev->pm.i2c_bus->adapter, &info); } + } + } +} - /* add the i2c bus for thermal/fan chip */ - if (controller->ucType > 0) { - if (controller->ucType == ATOM_PP_THERMALCONTROLLER_RV6xx) { - DRM_INFO("Internal thermal controller %s fan control\n", - (controller->ucFanParameters & - ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with"); - rdev->pm.int_thermal_type = THERMAL_TYPE_RV6XX; - } else if (controller->ucType == ATOM_PP_THERMALCONTROLLER_RV770) { - DRM_INFO("Internal thermal controller %s fan control\n", - (controller->ucFanParameters & - ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with"); - rdev->pm.int_thermal_type = THERMAL_TYPE_RV770; - } else if (controller->ucType == ATOM_PP_THERMALCONTROLLER_EVERGREEN) { - DRM_INFO("Internal thermal controller %s fan control\n", - (controller->ucFanParameters & - ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with"); - rdev->pm.int_thermal_type = THERMAL_TYPE_EVERGREEN; - } else if ((controller->ucType == - ATOM_PP_THERMALCONTROLLER_EXTERNAL_GPIO) || - (controller->ucType == - ATOM_PP_THERMALCONTROLLER_ADT7473_WITH_INTERNAL)) { - DRM_INFO("Special thermal controller config\n"); - } else { - DRM_INFO("Possible %s thermal controller at 0x%02x %s fan control\n", - pp_lib_thermal_controller_names[controller->ucType], - controller->ucI2cAddress >> 1, - (controller->ucFanParameters & - ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with"); - i2c_bus = radeon_lookup_i2c_gpio(rdev, controller->ucI2cLine); - rdev->pm.i2c_bus = radeon_i2c_lookup(rdev, &i2c_bus); - if (rdev->pm.i2c_bus) { - struct i2c_board_info info = { }; - const char *name = pp_lib_thermal_controller_names[controller->ucType]; - info.addr = controller->ucI2cAddress >> 1; - strlcpy(info.type, name, sizeof(info.type)); - i2c_new_device(&rdev->pm.i2c_bus->adapter, &info); - } +static u16 radeon_atombios_get_default_vddc(struct radeon_device *rdev) +{ + struct radeon_mode_info *mode_info = &rdev->mode_info; + int index = GetIndexIntoMasterTable(DATA, FirmwareInfo); + u8 frev, crev; + u16 data_offset; + union firmware_info *firmware_info; + u16 vddc = 0; - } - } - /* first mode is usually default, followed by low to high */ - for (i = 0; i < power_info->info_4.ucNumStates; i++) { - mode_index = 0; - power_state = (struct _ATOM_PPLIB_STATE *) - (mode_info->atom_context->bios + - data_offset + - le16_to_cpu(power_info->info_4.usStateArrayOffset) + - i * power_info->info_4.ucStateEntrySize); - non_clock_info = (struct _ATOM_PPLIB_NONCLOCK_INFO *) - (mode_info->atom_context->bios + - data_offset + - le16_to_cpu(power_info->info_4.usNonClockInfoArrayOffset) + - (power_state->ucNonClockStateIndex * - power_info->info_4.ucNonClockSize)); - for (j = 0; j < (power_info->info_4.ucStateEntrySize - 1); j++) { - if (rdev->flags & RADEON_IS_IGP) { - struct _ATOM_PPLIB_RS780_CLOCK_INFO *clock_info = - (struct _ATOM_PPLIB_RS780_CLOCK_INFO *) - (mode_info->atom_context->bios + - data_offset + - le16_to_cpu(power_info->info_4.usClockInfoArrayOffset) + - (power_state->ucClockStateIndices[j] * - power_info->info_4.ucClockInfoSize)); - sclk = le16_to_cpu(clock_info->usLowEngineClockLow); - sclk |= clock_info->ucLowEngineClockHigh << 16; - rdev->pm.power_state[state_index].clock_info[mode_index].sclk = sclk; - /* skip invalid modes */ - if (rdev->pm.power_state[state_index].clock_info[mode_index].sclk == 0) - continue; - /* voltage works differently on IGPs */ - mode_index++; - } else if (ASIC_IS_DCE4(rdev)) { - struct _ATOM_PPLIB_EVERGREEN_CLOCK_INFO *clock_info = - (struct _ATOM_PPLIB_EVERGREEN_CLOCK_INFO *) - (mode_info->atom_context->bios + - data_offset + - le16_to_cpu(power_info->info_4.usClockInfoArrayOffset) + - (power_state->ucClockStateIndices[j] * - power_info->info_4.ucClockInfoSize)); - sclk = le16_to_cpu(clock_info->usEngineClockLow); - sclk |= clock_info->ucEngineClockHigh << 16; - mclk = le16_to_cpu(clock_info->usMemoryClockLow); - mclk |= clock_info->ucMemoryClockHigh << 16; - rdev->pm.power_state[state_index].clock_info[mode_index].mclk = mclk; - rdev->pm.power_state[state_index].clock_info[mode_index].sclk = sclk; - /* skip invalid modes */ - if ((rdev->pm.power_state[state_index].clock_info[mode_index].mclk == 0) || - (rdev->pm.power_state[state_index].clock_info[mode_index].sclk == 0)) - continue; - rdev->pm.power_state[state_index].clock_info[mode_index].voltage.type = - VOLTAGE_SW; - rdev->pm.power_state[state_index].clock_info[mode_index].voltage.voltage = - clock_info->usVDDC; - /* XXX usVDDCI */ - mode_index++; - } else { - struct _ATOM_PPLIB_R600_CLOCK_INFO *clock_info = - (struct _ATOM_PPLIB_R600_CLOCK_INFO *) - (mode_info->atom_context->bios + - data_offset + - le16_to_cpu(power_info->info_4.usClockInfoArrayOffset) + - (power_state->ucClockStateIndices[j] * - power_info->info_4.ucClockInfoSize)); - sclk = le16_to_cpu(clock_info->usEngineClockLow); - sclk |= clock_info->ucEngineClockHigh << 16; - mclk = le16_to_cpu(clock_info->usMemoryClockLow); - mclk |= clock_info->ucMemoryClockHigh << 16; - rdev->pm.power_state[state_index].clock_info[mode_index].mclk = mclk; - rdev->pm.power_state[state_index].clock_info[mode_index].sclk = sclk; - /* skip invalid modes */ - if ((rdev->pm.power_state[state_index].clock_info[mode_index].mclk == 0) || - (rdev->pm.power_state[state_index].clock_info[mode_index].sclk == 0)) - continue; - rdev->pm.power_state[state_index].clock_info[mode_index].voltage.type = - VOLTAGE_SW; - rdev->pm.power_state[state_index].clock_info[mode_index].voltage.voltage = - clock_info->usVDDC; - mode_index++; - } - } - rdev->pm.power_state[state_index].num_clock_modes = mode_index; - if (mode_index) { - misc = le32_to_cpu(non_clock_info->ulCapsAndSettings); - misc2 = le16_to_cpu(non_clock_info->usClassification); - rdev->pm.power_state[state_index].misc = misc; - rdev->pm.power_state[state_index].misc2 = misc2; - rdev->pm.power_state[state_index].pcie_lanes = - ((misc & ATOM_PPLIB_PCIE_LINK_WIDTH_MASK) >> - ATOM_PPLIB_PCIE_LINK_WIDTH_SHIFT) + 1; - switch (misc2 & ATOM_PPLIB_CLASSIFICATION_UI_MASK) { - case ATOM_PPLIB_CLASSIFICATION_UI_BATTERY: - rdev->pm.power_state[state_index].type = - POWER_STATE_TYPE_BATTERY; - break; - case ATOM_PPLIB_CLASSIFICATION_UI_BALANCED: - rdev->pm.power_state[state_index].type = - POWER_STATE_TYPE_BALANCED; - break; - case ATOM_PPLIB_CLASSIFICATION_UI_PERFORMANCE: - rdev->pm.power_state[state_index].type = - POWER_STATE_TYPE_PERFORMANCE; - break; - case ATOM_PPLIB_CLASSIFICATION_UI_NONE: - if (misc2 & ATOM_PPLIB_CLASSIFICATION_3DPERFORMANCE) - rdev->pm.power_state[state_index].type = - POWER_STATE_TYPE_PERFORMANCE; - break; - } - rdev->pm.power_state[state_index].flags = 0; - if (misc & ATOM_PPLIB_SINGLE_DISPLAY_ONLY) - rdev->pm.power_state[state_index].flags |= - RADEON_PM_STATE_SINGLE_DISPLAY_ONLY; - if (misc2 & ATOM_PPLIB_CLASSIFICATION_BOOT) { - rdev->pm.power_state[state_index].type = - POWER_STATE_TYPE_DEFAULT; - rdev->pm.default_power_state_index = state_index; - rdev->pm.power_state[state_index].default_clock_mode = - &rdev->pm.power_state[state_index].clock_info[mode_index - 1]; - /* patch the table values with the default slck/mclk from firmware info */ - for (j = 0; j < mode_index; j++) { - rdev->pm.power_state[state_index].clock_info[j].mclk = - rdev->clock.default_mclk; - rdev->pm.power_state[state_index].clock_info[j].sclk = - rdev->clock.default_sclk; - if (vddc) - rdev->pm.power_state[state_index].clock_info[j].voltage.voltage = - vddc; - } - } - state_index++; - } - } - /* if multiple clock modes, mark the lowest as no display */ - for (i = 0; i < state_index; i++) { - if (rdev->pm.power_state[i].num_clock_modes > 1) - rdev->pm.power_state[i].clock_info[0].flags |= - RADEON_PM_MODE_NO_DISPLAY; - } - /* first mode is usually default */ - if (rdev->pm.default_power_state_index == -1) { - rdev->pm.power_state[0].type = - POWER_STATE_TYPE_DEFAULT; - rdev->pm.default_power_state_index = 0; - rdev->pm.power_state[0].default_clock_mode = - &rdev->pm.power_state[0].clock_info[0]; - } + if (atom_parse_data_header(mode_info->atom_context, index, NULL, + &frev, &crev, &data_offset)) { + firmware_info = + (union firmware_info *)(mode_info->atom_context->bios + + data_offset); + vddc = firmware_info->info_14.usBootUpVDDCVoltage; + } + + return vddc; +} + +static void radeon_atombios_parse_pplib_non_clock_info(struct radeon_device *rdev, + int state_index, int mode_index, + struct _ATOM_PPLIB_NONCLOCK_INFO *non_clock_info) +{ + int j; + u32 misc = le32_to_cpu(non_clock_info->ulCapsAndSettings); + u32 misc2 = le16_to_cpu(non_clock_info->usClassification); + u16 vddc = radeon_atombios_get_default_vddc(rdev); + + rdev->pm.power_state[state_index].misc = misc; + rdev->pm.power_state[state_index].misc2 = misc2; + rdev->pm.power_state[state_index].pcie_lanes = + ((misc & ATOM_PPLIB_PCIE_LINK_WIDTH_MASK) >> + ATOM_PPLIB_PCIE_LINK_WIDTH_SHIFT) + 1; + switch (misc2 & ATOM_PPLIB_CLASSIFICATION_UI_MASK) { + case ATOM_PPLIB_CLASSIFICATION_UI_BATTERY: + rdev->pm.power_state[state_index].type = + POWER_STATE_TYPE_BATTERY; + break; + case ATOM_PPLIB_CLASSIFICATION_UI_BALANCED: + rdev->pm.power_state[state_index].type = + POWER_STATE_TYPE_BALANCED; + break; + case ATOM_PPLIB_CLASSIFICATION_UI_PERFORMANCE: + rdev->pm.power_state[state_index].type = + POWER_STATE_TYPE_PERFORMANCE; + break; + case ATOM_PPLIB_CLASSIFICATION_UI_NONE: + if (misc2 & ATOM_PPLIB_CLASSIFICATION_3DPERFORMANCE) + rdev->pm.power_state[state_index].type = + POWER_STATE_TYPE_PERFORMANCE; + break; + } + rdev->pm.power_state[state_index].flags = 0; + if (misc & ATOM_PPLIB_SINGLE_DISPLAY_ONLY) + rdev->pm.power_state[state_index].flags |= + RADEON_PM_STATE_SINGLE_DISPLAY_ONLY; + if (misc2 & ATOM_PPLIB_CLASSIFICATION_BOOT) { + rdev->pm.power_state[state_index].type = + POWER_STATE_TYPE_DEFAULT; + rdev->pm.default_power_state_index = state_index; + rdev->pm.power_state[state_index].default_clock_mode = + &rdev->pm.power_state[state_index].clock_info[mode_index - 1]; + /* patch the table values with the default slck/mclk from firmware info */ + for (j = 0; j < mode_index; j++) { + rdev->pm.power_state[state_index].clock_info[j].mclk = + rdev->clock.default_mclk; + rdev->pm.power_state[state_index].clock_info[j].sclk = + rdev->clock.default_sclk; + if (vddc) + rdev->pm.power_state[state_index].clock_info[j].voltage.voltage = + vddc; + } + } +} + +static bool radeon_atombios_parse_pplib_clock_info(struct radeon_device *rdev, + int state_index, int mode_index, + union pplib_clock_info *clock_info) +{ + u32 sclk, mclk; + + if (rdev->flags & RADEON_IS_IGP) { + sclk = le16_to_cpu(clock_info->rs780.usLowEngineClockLow); + sclk |= clock_info->rs780.ucLowEngineClockHigh << 16; + rdev->pm.power_state[state_index].clock_info[mode_index].sclk = sclk; + } else if (ASIC_IS_DCE4(rdev)) { + sclk = le16_to_cpu(clock_info->evergreen.usEngineClockLow); + sclk |= clock_info->evergreen.ucEngineClockHigh << 16; + mclk = le16_to_cpu(clock_info->evergreen.usMemoryClockLow); + mclk |= clock_info->evergreen.ucMemoryClockHigh << 16; + rdev->pm.power_state[state_index].clock_info[mode_index].mclk = mclk; + rdev->pm.power_state[state_index].clock_info[mode_index].sclk = sclk; + rdev->pm.power_state[state_index].clock_info[mode_index].voltage.type = + VOLTAGE_SW; + rdev->pm.power_state[state_index].clock_info[mode_index].voltage.voltage = + clock_info->evergreen.usVDDC; + } else { + sclk = le16_to_cpu(clock_info->r600.usEngineClockLow); + sclk |= clock_info->r600.ucEngineClockHigh << 16; + mclk = le16_to_cpu(clock_info->r600.usMemoryClockLow); + mclk |= clock_info->r600.ucMemoryClockHigh << 16; + rdev->pm.power_state[state_index].clock_info[mode_index].mclk = mclk; + rdev->pm.power_state[state_index].clock_info[mode_index].sclk = sclk; + rdev->pm.power_state[state_index].clock_info[mode_index].voltage.type = + VOLTAGE_SW; + rdev->pm.power_state[state_index].clock_info[mode_index].voltage.voltage = + clock_info->r600.usVDDC; + } + + if (rdev->flags & RADEON_IS_IGP) { + /* skip invalid modes */ + if (rdev->pm.power_state[state_index].clock_info[mode_index].sclk == 0) + return false; + } else { + /* skip invalid modes */ + if ((rdev->pm.power_state[state_index].clock_info[mode_index].mclk == 0) || + (rdev->pm.power_state[state_index].clock_info[mode_index].sclk == 0)) + return false; + } + return true; +} + +static int radeon_atombios_parse_power_table_4_5(struct radeon_device *rdev) +{ + struct radeon_mode_info *mode_info = &rdev->mode_info; + struct _ATOM_PPLIB_NONCLOCK_INFO *non_clock_info; + union pplib_power_state *power_state; + int i, j; + int state_index = 0, mode_index = 0; + union pplib_clock_info *clock_info; + bool valid; + union power_info *power_info; + int index = GetIndexIntoMasterTable(DATA, PowerPlayInfo); + u16 data_offset; + u8 frev, crev; + + if (!atom_parse_data_header(mode_info->atom_context, index, NULL, + &frev, &crev, &data_offset)) + return state_index; + power_info = (union power_info *)(mode_info->atom_context->bios + data_offset); + + radeon_atombios_add_pplib_thermal_controller(rdev, &power_info->pplib.sThermalController); + /* first mode is usually default, followed by low to high */ + for (i = 0; i < power_info->pplib.ucNumStates; i++) { + mode_index = 0; + power_state = (union pplib_power_state *) + (mode_info->atom_context->bios + data_offset + + le16_to_cpu(power_info->pplib.usStateArrayOffset) + + i * power_info->pplib.ucStateEntrySize); + non_clock_info = (struct _ATOM_PPLIB_NONCLOCK_INFO *) + (mode_info->atom_context->bios + data_offset + + le16_to_cpu(power_info->pplib.usNonClockInfoArrayOffset) + + (power_state->v1.ucNonClockStateIndex * + power_info->pplib.ucNonClockSize)); + for (j = 0; j < (power_info->pplib.ucStateEntrySize - 1); j++) { + clock_info = (union pplib_clock_info *) + (mode_info->atom_context->bios + data_offset + + le16_to_cpu(power_info->pplib.usClockInfoArrayOffset) + + (power_state->v1.ucClockStateIndices[j] * + power_info->pplib.ucClockInfoSize)); + valid = radeon_atombios_parse_pplib_clock_info(rdev, + state_index, mode_index, + clock_info); + if (valid) + mode_index++; + } + rdev->pm.power_state[state_index].num_clock_modes = mode_index; + if (mode_index) { + radeon_atombios_parse_pplib_non_clock_info(rdev, state_index, mode_index, + non_clock_info); + state_index++; + } + } + /* if multiple clock modes, mark the lowest as no display */ + for (i = 0; i < state_index; i++) { + if (rdev->pm.power_state[i].num_clock_modes > 1) + rdev->pm.power_state[i].clock_info[0].flags |= + RADEON_PM_MODE_NO_DISPLAY; + } + /* first mode is usually default */ + if (rdev->pm.default_power_state_index == -1) { + rdev->pm.power_state[0].type = + POWER_STATE_TYPE_DEFAULT; + rdev->pm.default_power_state_index = 0; + rdev->pm.power_state[0].default_clock_mode = + &rdev->pm.power_state[0].clock_info[0]; + } + return state_index; +} + +void radeon_atombios_get_power_modes(struct radeon_device *rdev) +{ + struct radeon_mode_info *mode_info = &rdev->mode_info; + int index = GetIndexIntoMasterTable(DATA, PowerPlayInfo); + u16 data_offset; + u8 frev, crev; + int state_index = 0; + + rdev->pm.default_power_state_index = -1; + + if (atom_parse_data_header(mode_info->atom_context, index, NULL, + &frev, &crev, &data_offset)) { + switch (frev) { + case 1: + case 2: + case 3: + state_index = radeon_atombios_parse_power_table_1_3(rdev); + break; + case 4: + case 5: + state_index = radeon_atombios_parse_power_table_4_5(rdev); + break; + default: + break; } } else { /* add the default mode */ -- cgit v1.2.3 From b0e664140a170382531a8c8b5396bf7e6903d5e3 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Mon, 22 Nov 2010 17:56:35 -0500 Subject: drm/radeon/kms: add power table parsing support for Ontario fusion APUs The vbios power tables on my inagua board seem a bit funky... Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/radeon_atombios.c | 106 +++++++++++++++++++++++++++++-- 1 file changed, 101 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c index 7056e20d329d..ac882639b3ed 100644 --- a/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/drivers/gpu/drm/radeon/radeon_atombios.c @@ -1766,7 +1766,8 @@ static const char *pp_lib_thermal_controller_names[] = { "NONE", "External GPIO", "Evergreen", - "adt7473 with internal", + "emc2103", + "Sumo", }; union power_info { @@ -1774,12 +1775,15 @@ union power_info { struct _ATOM_POWERPLAY_INFO_V2 info_2; struct _ATOM_POWERPLAY_INFO_V3 info_3; struct _ATOM_PPLIB_POWERPLAYTABLE pplib; + struct _ATOM_PPLIB_POWERPLAYTABLE2 pplib2; + struct _ATOM_PPLIB_POWERPLAYTABLE3 pplib3; }; union pplib_clock_info { struct _ATOM_PPLIB_R600_CLOCK_INFO r600; struct _ATOM_PPLIB_RS780_CLOCK_INFO rs780; struct _ATOM_PPLIB_EVERGREEN_CLOCK_INFO evergreen; + struct _ATOM_PPLIB_SUMO_CLOCK_INFO sumo; }; union pplib_power_state { @@ -2022,10 +2026,17 @@ static void radeon_atombios_add_pplib_thermal_controller(struct radeon_device *r (controller->ucFanParameters & ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with"); rdev->pm.int_thermal_type = THERMAL_TYPE_EVERGREEN; + } else if (controller->ucType == ATOM_PP_THERMALCONTROLLER_SUMO) { + DRM_INFO("Internal thermal controller %s fan control\n", + (controller->ucFanParameters & + ATOM_PP_FANPARAMETERS_NOFAN) ? "without" : "with"); + rdev->pm.int_thermal_type = THERMAL_TYPE_SUMO; } else if ((controller->ucType == ATOM_PP_THERMALCONTROLLER_EXTERNAL_GPIO) || (controller->ucType == - ATOM_PP_THERMALCONTROLLER_ADT7473_WITH_INTERNAL)) { + ATOM_PP_THERMALCONTROLLER_ADT7473_WITH_INTERNAL) || + (controller->ucType == + ATOM_PP_THERMALCONTROLLER_EMC2103_WITH_INTERNAL)) { DRM_INFO("Special thermal controller config\n"); } else { DRM_INFO("Possible %s thermal controller at 0x%02x %s fan control\n", @@ -2129,9 +2140,15 @@ static bool radeon_atombios_parse_pplib_clock_info(struct radeon_device *rdev, u32 sclk, mclk; if (rdev->flags & RADEON_IS_IGP) { - sclk = le16_to_cpu(clock_info->rs780.usLowEngineClockLow); - sclk |= clock_info->rs780.ucLowEngineClockHigh << 16; - rdev->pm.power_state[state_index].clock_info[mode_index].sclk = sclk; + if (rdev->family >= CHIP_PALM) { + sclk = le16_to_cpu(clock_info->sumo.usEngineClockLow); + sclk |= clock_info->sumo.ucEngineClockHigh << 16; + rdev->pm.power_state[state_index].clock_info[mode_index].sclk = sclk; + } else { + sclk = le16_to_cpu(clock_info->rs780.usLowEngineClockLow); + sclk |= clock_info->rs780.ucLowEngineClockHigh << 16; + rdev->pm.power_state[state_index].clock_info[mode_index].sclk = sclk; + } } else if (ASIC_IS_DCE4(rdev)) { sclk = le16_to_cpu(clock_info->evergreen.usEngineClockLow); sclk |= clock_info->evergreen.ucEngineClockHigh << 16; @@ -2237,6 +2254,82 @@ static int radeon_atombios_parse_power_table_4_5(struct radeon_device *rdev) return state_index; } +static int radeon_atombios_parse_power_table_6(struct radeon_device *rdev) +{ + struct radeon_mode_info *mode_info = &rdev->mode_info; + struct _ATOM_PPLIB_NONCLOCK_INFO *non_clock_info; + union pplib_power_state *power_state; + int i, j, non_clock_array_index, clock_array_index; + int state_index = 0, mode_index = 0; + union pplib_clock_info *clock_info; + struct StateArray *state_array; + struct ClockInfoArray *clock_info_array; + struct NonClockInfoArray *non_clock_info_array; + bool valid; + union power_info *power_info; + int index = GetIndexIntoMasterTable(DATA, PowerPlayInfo); + u16 data_offset; + u8 frev, crev; + + if (!atom_parse_data_header(mode_info->atom_context, index, NULL, + &frev, &crev, &data_offset)) + return state_index; + power_info = (union power_info *)(mode_info->atom_context->bios + data_offset); + + radeon_atombios_add_pplib_thermal_controller(rdev, &power_info->pplib.sThermalController); + state_array = (struct StateArray *) + (mode_info->atom_context->bios + data_offset + + power_info->pplib.usStateArrayOffset); + clock_info_array = (struct ClockInfoArray *) + (mode_info->atom_context->bios + data_offset + + power_info->pplib.usClockInfoArrayOffset); + non_clock_info_array = (struct NonClockInfoArray *) + (mode_info->atom_context->bios + data_offset + + power_info->pplib.usNonClockInfoArrayOffset); + for (i = 0; i < state_array->ucNumEntries; i++) { + mode_index = 0; + power_state = (union pplib_power_state *)&state_array->states[i]; + /* XXX this might be an inagua bug... */ + non_clock_array_index = i; /* power_state->v2.nonClockInfoIndex */ + non_clock_info = (struct _ATOM_PPLIB_NONCLOCK_INFO *) + &non_clock_info_array->nonClockInfo[non_clock_array_index]; + for (j = 0; j < power_state->v2.ucNumDPMLevels; j++) { + clock_array_index = power_state->v2.clockInfoIndex[j]; + /* XXX this might be an inagua bug... */ + if (clock_array_index >= clock_info_array->ucNumEntries) + continue; + clock_info = (union pplib_clock_info *) + &clock_info_array->clockInfo[clock_array_index]; + valid = radeon_atombios_parse_pplib_clock_info(rdev, + state_index, mode_index, + clock_info); + if (valid) + mode_index++; + } + rdev->pm.power_state[state_index].num_clock_modes = mode_index; + if (mode_index) { + radeon_atombios_parse_pplib_non_clock_info(rdev, state_index, mode_index, + non_clock_info); + state_index++; + } + } + /* if multiple clock modes, mark the lowest as no display */ + for (i = 0; i < state_index; i++) { + if (rdev->pm.power_state[i].num_clock_modes > 1) + rdev->pm.power_state[i].clock_info[0].flags |= + RADEON_PM_MODE_NO_DISPLAY; + } + /* first mode is usually default */ + if (rdev->pm.default_power_state_index == -1) { + rdev->pm.power_state[0].type = + POWER_STATE_TYPE_DEFAULT; + rdev->pm.default_power_state_index = 0; + rdev->pm.power_state[0].default_clock_mode = + &rdev->pm.power_state[0].clock_info[0]; + } + return state_index; +} + void radeon_atombios_get_power_modes(struct radeon_device *rdev) { struct radeon_mode_info *mode_info = &rdev->mode_info; @@ -2259,6 +2352,9 @@ void radeon_atombios_get_power_modes(struct radeon_device *rdev) case 5: state_index = radeon_atombios_parse_power_table_4_5(rdev); break; + case 6: + state_index = radeon_atombios_parse_power_table_6(rdev); + break; default: break; } -- cgit v1.2.3 From bbbf9b7b02e0090d91c422398089c9f22361dc94 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Mon, 22 Nov 2010 17:56:36 -0500 Subject: drm/radeon/kms: enable MSIs on fusion APUs Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/radeon_irq_kms.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/radeon/radeon_irq_kms.c b/drivers/gpu/drm/radeon/radeon_irq_kms.c index a108c7ed14f5..b492b7dc63ac 100644 --- a/drivers/gpu/drm/radeon/radeon_irq_kms.c +++ b/drivers/gpu/drm/radeon/radeon_irq_kms.c @@ -121,7 +121,7 @@ int radeon_irq_kms_init(struct radeon_device *rdev) * chips. Disable MSI on them for now. */ if ((rdev->family >= CHIP_RV380) && - (!(rdev->flags & RADEON_IS_IGP)) && + ((!(rdev->flags & RADEON_IS_IGP)) || (rdev->family >= CHIP_PALM)) && (!(rdev->flags & RADEON_IS_AGP))) { int ret = pci_enable_msi(rdev->pdev); if (!ret) { -- cgit v1.2.3 From 11fa1618e327af7f08085e134b3325de9caf7a94 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Mon, 22 Nov 2010 17:56:37 -0500 Subject: drm/radeon/kms: add Ontario Fusion APU pci ids Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie --- include/drm/drm_pciids.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/include/drm/drm_pciids.h b/include/drm/drm_pciids.h index 883c1d439899..e6b28a39942f 100644 --- a/include/drm/drm_pciids.h +++ b/include/drm/drm_pciids.h @@ -419,6 +419,10 @@ {0x1002, 0x9713, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS880|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ {0x1002, 0x9714, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS880|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ {0x1002, 0x9715, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS880|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ + {0x1002, 0x9802, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PALM|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ + {0x1002, 0x9803, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PALM|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ + {0x1002, 0x9804, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PALM|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ + {0x1002, 0x9805, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PALM|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ {0, 0, 0} #define r128_PCI_IDS \ -- cgit v1.2.3 From 439bd6cde45d0bff4f97513b01b976b9f72ae1f0 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Mon, 22 Nov 2010 17:56:31 -0500 Subject: drm/radeon/kms: add Ontario APU ucode loading support Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/r600.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index 93b1c687328b..b37361b69ad5 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c @@ -83,6 +83,9 @@ MODULE_FIRMWARE("radeon/JUNIPER_rlc.bin"); MODULE_FIRMWARE("radeon/CYPRESS_pfp.bin"); MODULE_FIRMWARE("radeon/CYPRESS_me.bin"); MODULE_FIRMWARE("radeon/CYPRESS_rlc.bin"); +MODULE_FIRMWARE("radeon/PALM_pfp.bin"); +MODULE_FIRMWARE("radeon/PALM_me.bin"); +MODULE_FIRMWARE("radeon/SUMO_rlc.bin"); int r600_debugfs_mc_info_init(struct radeon_device *rdev); @@ -1998,6 +2001,10 @@ int r600_init_microcode(struct radeon_device *rdev) chip_name = "CYPRESS"; rlc_chip_name = "CYPRESS"; break; + case CHIP_PALM: + chip_name = "PALM"; + rlc_chip_name = "SUMO"; + break; default: BUG(); } -- cgit v1.2.3 From 3685092b717882bb9b6801bf3e4b02a106e3b129 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 23 Nov 2010 08:49:38 +0000 Subject: drm/i915: Avoid oops when capturing NULL ring for inactive pinned buffers Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_debugfs.c | 6 +++--- drivers/gpu/drm/i915/i915_irq.c | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 421b8414b577..4fe49e0228ef 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -572,9 +572,9 @@ static int i915_ringbuffer_info(struct seq_file *m, void *data) static const char *ring_str(int ring) { switch (ring) { - case RING_RENDER: return "render"; - case RING_BSD: return "bsd"; - case RING_BLT: return "blt"; + case RING_RENDER: return " render"; + case RING_BSD: return " bsd"; + case RING_BLT: return " blt"; default: return ""; } } diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 0b6052abedd1..a8f55f061f6d 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -575,7 +575,7 @@ static u32 capture_bo_list(struct drm_i915_error_buffer *err, err->tiling = obj->tiling_mode; err->dirty = obj->dirty; err->purgeable = obj->madv != I915_MADV_WILLNEED; - err->ring = obj->ring->id; + err->ring = obj->ring ? obj->ring->id : 0; if (++i == count) break; -- cgit v1.2.3 From 0b0b053a3949f5c467c3b3ba135d4c161f9fbd00 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 23 Nov 2010 09:45:50 +0000 Subject: drm/i915/panel: Restore saved value of BLC_PWM_CTL After a GPU reset, the backlight controller registers may be also reset to 0. In that case we should restore those to the original values programmed by the BIOS. Note that we still lack the code to handle the case where the BIOS failed to program those registers at all... Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/intel_panel.c | 52 ++++++++++++++++++++++++++++++-------- 1 file changed, 42 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index 92ff8f385278..7350ec2515c6 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c @@ -125,15 +125,55 @@ static int is_backlight_combination_mode(struct drm_device *dev) return 0; } +static u32 i915_read_blc_pwm_ctl(struct drm_i915_private *dev_priv) +{ + u32 val; + + /* Restore the CTL value if it lost, e.g. GPU reset */ + + if (HAS_PCH_SPLIT(dev_priv->dev)) { + val = I915_READ(BLC_PWM_PCH_CTL2); + if (dev_priv->saveBLC_PWM_CTL2 == 0) { + dev_priv->saveBLC_PWM_CTL2 = val; + } else if (val == 0) { + I915_WRITE(BLC_PWM_PCH_CTL2, + dev_priv->saveBLC_PWM_CTL); + val = dev_priv->saveBLC_PWM_CTL; + } + } else { + val = I915_READ(BLC_PWM_CTL); + if (dev_priv->saveBLC_PWM_CTL == 0) { + dev_priv->saveBLC_PWM_CTL = val; + dev_priv->saveBLC_PWM_CTL2 = I915_READ(BLC_PWM_CTL2); + } else if (val == 0) { + I915_WRITE(BLC_PWM_CTL, + dev_priv->saveBLC_PWM_CTL); + I915_WRITE(BLC_PWM_CTL2, + dev_priv->saveBLC_PWM_CTL2); + val = dev_priv->saveBLC_PWM_CTL; + } + } + + return val; +} + u32 intel_panel_get_max_backlight(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; u32 max; + max = i915_read_blc_pwm_ctl(dev_priv); + if (max == 0) { + /* XXX add code here to query mode clock or hardware clock + * and program max PWM appropriately. + */ + printk_once(KERN_WARNING "fixme: max PWM is zero.\n"); + return 1; + } + if (HAS_PCH_SPLIT(dev)) { - max = I915_READ(BLC_PWM_PCH_CTL2) >> 16; + max >>= 16; } else { - max = I915_READ(BLC_PWM_CTL); if (IS_PINEVIEW(dev)) { max >>= 17; } else { @@ -146,14 +186,6 @@ u32 intel_panel_get_max_backlight(struct drm_device *dev) max *= 0xff; } - if (max == 0) { - /* XXX add code here to query mode clock or hardware clock - * and program max PWM appropriately. - */ - DRM_ERROR("fixme: max PWM is zero.\n"); - max = 1; - } - DRM_DEBUG_DRIVER("max backlight PWM = %d\n", max); return max; } -- cgit v1.2.3 From 3a56d0ca72f8fc47240849b83acacd1c92283b99 Mon Sep 17 00:00:00 2001 From: Jassi Brar Date: Mon, 22 Nov 2010 15:35:36 +0900 Subject: ASoC: Samsung: Remove redundant AQUILA driver AQUILA and GONI are essentially the same h/w w.r.t ASoC. They only differ by the fact that GONI has stereo speaker-out whereas AQUILA has mono. The difference can easily be handled in the same MACHINE driver by making machine-specific runtime changes. Signed-off-by: Jassi Brar Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/s3c24xx/Kconfig | 17 +-- sound/soc/s3c24xx/Makefile | 4 +- sound/soc/s3c24xx/aquila_wm8994.c | 295 -------------------------------------- sound/soc/s3c24xx/goni_wm8994.c | 19 ++- 4 files changed, 23 insertions(+), 312 deletions(-) delete mode 100644 sound/soc/s3c24xx/aquila_wm8994.c diff --git a/sound/soc/s3c24xx/Kconfig b/sound/soc/s3c24xx/Kconfig index d85bf8a0abb2..226f831d46f7 100644 --- a/sound/soc/s3c24xx/Kconfig +++ b/sound/soc/s3c24xx/Kconfig @@ -145,22 +145,13 @@ config SND_S3C64XX_SOC_SMARTQ select SND_S3C64XX_SOC_I2S select SND_SOC_WM8750 -config SND_S5PC110_SOC_AQUILA_WM8994 - tristate "SoC I2S Audio support for AQUILA - WM8994" - depends on SND_S3C24XX_SOC && MACH_AQUILA +config SND_SOC_GONI_AQUILA_WM8994 + tristate "SoC I2S Audio support for AQUILA/GONI - WM8994" + depends on SND_S3C24XX_SOC && (MACH_GONI || MACH_AQUILA) select SND_S3C64XX_SOC_I2S_V4 select SND_SOC_WM8994 help - Say Y if you want to add support for SoC audio on aquila - with the WM8994. - -config SND_S5PV210_SOC_GONI_WM8994 - tristate "SoC I2S Audio support for GONI - WM8994" - depends on SND_S3C24XX_SOC && MACH_GONI - select SND_S3C64XX_SOC_I2S_V4 - select SND_SOC_WM8994 - help - Say Y if you want to add support for SoC audio on goni + Say Y if you want to add support for SoC audio on goni or aquila with the WM8994. config SND_SOC_SMDK_SPDIF diff --git a/sound/soc/s3c24xx/Makefile b/sound/soc/s3c24xx/Makefile index ee8f41d6df99..4e232f112435 100644 --- a/sound/soc/s3c24xx/Makefile +++ b/sound/soc/s3c24xx/Makefile @@ -33,7 +33,6 @@ snd-soc-rx1950-uda1380-objs := rx1950_uda1380.o snd-soc-smdk64xx-wm8580-objs := smdk64xx_wm8580.o snd-soc-smdk-wm9713-objs := smdk_wm9713.o snd-soc-s3c64xx-smartq-wm8987-objs := smartq_wm8987.o -snd-soc-aquila-wm8994-objs := aquila_wm8994.o snd-soc-goni-wm8994-objs := goni_wm8994.o snd-soc-smdk-spdif-objs := smdk_spdif.o @@ -50,6 +49,5 @@ obj-$(CONFIG_SND_S3C24XX_SOC_RX1950_UDA1380) += snd-soc-rx1950-uda1380.o obj-$(CONFIG_SND_S3C64XX_SOC_WM8580) += snd-soc-smdk64xx-wm8580.o obj-$(CONFIG_SND_SOC_SMDK_WM9713) += snd-soc-smdk-wm9713.o obj-$(CONFIG_SND_S3C64XX_SOC_SMARTQ) += snd-soc-s3c64xx-smartq-wm8987.o -obj-$(CONFIG_SND_S5PC110_SOC_AQUILA_WM8994) += snd-soc-aquila-wm8994.o -obj-$(CONFIG_SND_S5PV210_SOC_GONI_WM8994) += snd-soc-goni-wm8994.o obj-$(CONFIG_SND_SOC_SMDK_SPDIF) += snd-soc-smdk-spdif.o +obj-$(CONFIG_SND_SOC_GONI_AQUILA_WM8994) += snd-soc-goni-wm8994.o diff --git a/sound/soc/s3c24xx/aquila_wm8994.c b/sound/soc/s3c24xx/aquila_wm8994.c deleted file mode 100644 index 0043e6296c9c..000000000000 --- a/sound/soc/s3c24xx/aquila_wm8994.c +++ /dev/null @@ -1,295 +0,0 @@ -/* - * aquila_wm8994.c - * - * Copyright (C) 2010 Samsung Electronics Co.Ltd - * Author: Chanwoo Choi - * - * 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. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include "../codecs/wm8994.h" -#include "s3c-dma.h" -#include "s3c64xx-i2s.h" - -static struct snd_soc_card aquila; -static struct platform_device *aquila_snd_device; - -/* 3.5 pie jack */ -static struct snd_soc_jack jack; - -/* 3.5 pie jack detection DAPM pins */ -static struct snd_soc_jack_pin jack_pins[] = { - { - .pin = "Headset Mic", - .mask = SND_JACK_MICROPHONE, - }, { - .pin = "Headset Stereophone", - .mask = SND_JACK_HEADPHONE | SND_JACK_MECHANICAL | - SND_JACK_AVOUT, - }, -}; - -/* 3.5 pie jack detection gpios */ -static struct snd_soc_jack_gpio jack_gpios[] = { - { - .gpio = S5PV210_GPH0(6), - .name = "DET_3.5", - .report = SND_JACK_HEADSET | SND_JACK_MECHANICAL | - SND_JACK_AVOUT, - .debounce_time = 200, - }, -}; - -static const struct snd_soc_dapm_widget aquila_dapm_widgets[] = { - SND_SOC_DAPM_SPK("Ext Spk", NULL), - SND_SOC_DAPM_SPK("Ext Rcv", NULL), - SND_SOC_DAPM_HP("Headset Stereophone", NULL), - SND_SOC_DAPM_MIC("Headset Mic", NULL), - SND_SOC_DAPM_MIC("Main Mic", NULL), - SND_SOC_DAPM_MIC("2nd Mic", NULL), - SND_SOC_DAPM_LINE("Radio In", NULL), -}; - -static const struct snd_soc_dapm_route aquila_dapm_routes[] = { - {"Ext Spk", NULL, "SPKOUTLP"}, - {"Ext Spk", NULL, "SPKOUTLN"}, - - {"Ext Rcv", NULL, "HPOUT2N"}, - {"Ext Rcv", NULL, "HPOUT2P"}, - - {"Headset Stereophone", NULL, "HPOUT1L"}, - {"Headset Stereophone", NULL, "HPOUT1R"}, - - {"IN1RN", NULL, "Headset Mic"}, - {"IN1RP", NULL, "Headset Mic"}, - - {"IN1RN", NULL, "2nd Mic"}, - {"IN1RP", NULL, "2nd Mic"}, - - {"IN1LN", NULL, "Main Mic"}, - {"IN1LP", NULL, "Main Mic"}, - - {"IN2LN", NULL, "Radio In"}, - {"IN2RN", NULL, "Radio In"}, -}; - -static int aquila_wm8994_init(struct snd_soc_pcm_runtime *rtd) -{ - struct snd_soc_codec *codec = rtd->codec; - struct snd_soc_dapm_context *dapm = &codec->dapm; - int ret; - - /* add aquila specific widgets */ - snd_soc_dapm_new_controls(dapm, aquila_dapm_widgets, - ARRAY_SIZE(aquila_dapm_widgets)); - - /* set up aquila specific audio routes */ - snd_soc_dapm_add_routes(dapm, aquila_dapm_routes, - ARRAY_SIZE(aquila_dapm_routes)); - - /* set endpoints to not connected */ - snd_soc_dapm_nc_pin(dapm, "IN2LP:VXRN"); - snd_soc_dapm_nc_pin(dapm, "IN2RP:VXRP"); - snd_soc_dapm_nc_pin(dapm, "LINEOUT1N"); - snd_soc_dapm_nc_pin(dapm, "LINEOUT1P"); - snd_soc_dapm_nc_pin(dapm, "LINEOUT2N"); - snd_soc_dapm_nc_pin(dapm, "LINEOUT2P"); - snd_soc_dapm_nc_pin(dapm, "SPKOUTRN"); - snd_soc_dapm_nc_pin(dapm, "SPKOUTRP"); - - snd_soc_dapm_sync(dapm); - - /* Headset jack detection */ - ret = snd_soc_jack_new(&aquila, "Headset Jack", - SND_JACK_HEADSET | SND_JACK_MECHANICAL | SND_JACK_AVOUT, - &jack); - if (ret) - return ret; - - ret = snd_soc_jack_add_pins(&jack, ARRAY_SIZE(jack_pins), jack_pins); - if (ret) - return ret; - - ret = snd_soc_jack_add_gpios(&jack, ARRAY_SIZE(jack_gpios), jack_gpios); - if (ret) - return ret; - - return 0; -} - -static int aquila_hifi_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *codec_dai = rtd->codec_dai; - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; - unsigned int pll_out = 24000000; - int ret = 0; - - /* set the cpu DAI configuration */ - ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S | - SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM); - if (ret < 0) - return ret; - - /* set the cpu system clock */ - ret = snd_soc_dai_set_sysclk(cpu_dai, S3C64XX_CLKSRC_PCLK, - 0, SND_SOC_CLOCK_IN); - if (ret < 0) - return ret; - - /* set codec DAI configuration */ - ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | - SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM); - if (ret < 0) - return ret; - - /* set the codec FLL */ - ret = snd_soc_dai_set_pll(codec_dai, WM8994_FLL1, 0, pll_out, - params_rate(params) * 256); - if (ret < 0) - return ret; - - /* set the codec system clock */ - ret = snd_soc_dai_set_sysclk(codec_dai, WM8994_SYSCLK_FLL1, - params_rate(params) * 256, SND_SOC_CLOCK_IN); - if (ret < 0) - return ret; - - return 0; -} - -static struct snd_soc_ops aquila_hifi_ops = { - .hw_params = aquila_hifi_hw_params, -}; - -static int aquila_voice_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *codec_dai = rtd->codec_dai; - unsigned int pll_out = 24000000; - int ret = 0; - - if (params_rate(params) != 8000) - return -EINVAL; - - /* set codec DAI configuration */ - ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_LEFT_J | - SND_SOC_DAIFMT_IB_IF | SND_SOC_DAIFMT_CBM_CFM); - if (ret < 0) - return ret; - - /* set the codec FLL */ - ret = snd_soc_dai_set_pll(codec_dai, WM8994_FLL2, 0, pll_out, - params_rate(params) * 256); - if (ret < 0) - return ret; - - /* set the codec system clock */ - ret = snd_soc_dai_set_sysclk(codec_dai, WM8994_SYSCLK_FLL2, - params_rate(params) * 256, SND_SOC_CLOCK_IN); - if (ret < 0) - return ret; - - return 0; -} - -static struct snd_soc_dai_driver voice_dai = { - .name = "aquila-voice-dai", - .playback = { - .channels_min = 1, - .channels_max = 2, - .rates = SNDRV_PCM_RATE_8000, - .formats = SNDRV_PCM_FMTBIT_S16_LE,}, - .capture = { - .channels_min = 1, - .channels_max = 2, - .rates = SNDRV_PCM_RATE_8000, - .formats = SNDRV_PCM_FMTBIT_S16_LE,}, -}; - -static struct snd_soc_ops aquila_voice_ops = { - .hw_params = aquila_voice_hw_params, -}; - -static struct snd_soc_dai_link aquila_dai[] = { -{ - .name = "WM8994", - .stream_name = "WM8994 HiFi", - .cpu_dai_name = "s3c64xx-i2s-v4", - .codec_dai_name = "wm8994-hifi", - .platform_name = "s3c24xx-pcm-audio", - .codec_name = "wm8994-codec.0-0x1a", - .init = aquila_wm8994_init, - .ops = &aquila_hifi_ops, -}, { - .name = "WM8994 Voice", - .stream_name = "Voice", - .cpu_dai_name = "aquila-voice-dai", - .codec_dai_name = "wm8994-voice", - .platform_name = "s3c24xx-pcm-audio", - .codec_name = "wm8994-codec.0-0x1a", - .ops = &aquila_voice_ops, -}, -}; - -static struct snd_soc_card aquila = { - .name = "aquila", - .dai_link = aquila_dai, - .num_links = ARRAY_SIZE(aquila_dai), -}; - -static int __init aquila_init(void) -{ - int ret; - - if (!machine_is_aquila()) - return -ENODEV; - - aquila_snd_device = platform_device_alloc("soc-audio", -1); - if (!aquila_snd_device) - return -ENOMEM; - - /* register voice DAI here */ - ret = snd_soc_register_dai(&aquila_snd_device->dev, &voice_dai); - if (ret) - return ret; - - platform_set_drvdata(aquila_snd_device, &aquila); - ret = platform_device_add(aquila_snd_device); - - if (ret) - platform_device_put(aquila_snd_device); - - return ret; -} - -static void __exit aquila_exit(void) -{ - platform_device_unregister(aquila_snd_device); -} - -module_init(aquila_init); -module_exit(aquila_exit); - -/* Module information */ -MODULE_DESCRIPTION("ALSA SoC WM8994 Aquila(S5PC110)"); -MODULE_AUTHOR("Chanwoo Choi "); -MODULE_LICENSE("GPL"); diff --git a/sound/soc/s3c24xx/goni_wm8994.c b/sound/soc/s3c24xx/goni_wm8994.c index bcbfe8534f32..62134ed3aa57 100644 --- a/sound/soc/s3c24xx/goni_wm8994.c +++ b/sound/soc/s3c24xx/goni_wm8994.c @@ -27,6 +27,14 @@ #include "s3c-dma.h" #include "s3c64xx-i2s.h" +#define MACHINE_NAME 0 +#define CPU_VOICE_DAI 1 + +static const char *aquila_str[] = { + [MACHINE_NAME] = "aquila", + [CPU_VOICE_DAI] = "aquila-voice-dai", +}; + static struct snd_soc_card goni; static struct platform_device *goni_snd_device; @@ -115,6 +123,11 @@ static int goni_wm8994_init(struct snd_soc_pcm_runtime *rtd) snd_soc_dapm_nc_pin(dapm, "LINEOUT2N"); snd_soc_dapm_nc_pin(dapm, "LINEOUT2P"); + if (machine_is_aquila()) { + snd_soc_dapm_nc_pin(dapm, "SPKOUTRN"); + snd_soc_dapm_nc_pin(dapm, "SPKOUTRP"); + } + snd_soc_dapm_sync(dapm); /* Headset jack detection */ @@ -263,7 +276,11 @@ static int __init goni_init(void) { int ret; - if (!machine_is_goni()) + if (machine_is_aquila()) { + voice_dai.name = aquila_str[CPU_VOICE_DAI]; + goni_dai[1].cpu_dai_name = aquila_str[CPU_VOICE_DAI]; + goni.name = aquila_str[MACHINE_NAME]; + } else if (!machine_is_goni()) return -ENODEV; goni_snd_device = platform_device_alloc("soc-audio", -1); -- cgit v1.2.3 From 58bb4072132c54d832082cc6eac396a6db009cbd Mon Sep 17 00:00:00 2001 From: Jassi Brar Date: Mon, 22 Nov 2010 15:35:50 +0900 Subject: ASoC: Samsung: Rename DMA device Some Samsung SoCs have a PCM(DSP) controller. So the name s3c24xx-pcm-audio for DMA driver is not very appropraite. This patch moves :- s3c24xx-pcm-audio -> samsung-audio Signed-off-by: Jassi Brar Acked-by: Kukjin Kim Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- arch/arm/mach-s3c64xx/dev-audio.c | 2 +- arch/arm/plat-s3c24xx/devs.c | 2 +- sound/soc/s3c24xx/goni_wm8994.c | 4 ++-- sound/soc/s3c24xx/jive_wm8750.c | 2 +- sound/soc/s3c24xx/ln2440sbc_alc650.c | 2 +- sound/soc/s3c24xx/neo1973_gta02_wm8753.c | 4 ++-- sound/soc/s3c24xx/neo1973_wm8753.c | 4 ++-- sound/soc/s3c24xx/rx1950_uda1380.c | 2 +- sound/soc/s3c24xx/s3c-dma.c | 4 ++-- sound/soc/s3c24xx/s3c24xx_simtec_hermes.c | 2 +- sound/soc/s3c24xx/s3c24xx_simtec_tlv320aic23.c | 2 +- sound/soc/s3c24xx/s3c24xx_uda134x.c | 2 +- sound/soc/s3c24xx/smartq_wm8987.c | 2 +- sound/soc/s3c24xx/smdk2443_wm9710.c | 2 +- sound/soc/s3c24xx/smdk64xx_wm8580.c | 4 ++-- sound/soc/s3c24xx/smdk_spdif.c | 2 +- sound/soc/s3c24xx/smdk_wm9713.c | 2 +- 17 files changed, 22 insertions(+), 22 deletions(-) diff --git a/arch/arm/mach-s3c64xx/dev-audio.c b/arch/arm/mach-s3c64xx/dev-audio.c index 7618627b98f5..bbaf7b3fa8ae 100644 --- a/arch/arm/mach-s3c64xx/dev-audio.c +++ b/arch/arm/mach-s3c64xx/dev-audio.c @@ -319,7 +319,7 @@ void __init s3c64xx_ac97_setup_gpio(int num) static u64 s3c_device_audio_dmamask = 0xffffffffUL; struct platform_device s3c_device_pcm = { - .name = "s3c24xx-pcm-audio", + .name = "samsung-audio", .id = -1, .dev = { .dma_mask = &s3c_device_audio_dmamask, diff --git a/arch/arm/plat-s3c24xx/devs.c b/arch/arm/plat-s3c24xx/devs.c index 2f91057a0c02..4bf0b3912a69 100644 --- a/arch/arm/plat-s3c24xx/devs.c +++ b/arch/arm/plat-s3c24xx/devs.c @@ -264,7 +264,7 @@ EXPORT_SYMBOL(s3c_device_iis); static u64 s3c_device_audio_dmamask = 0xffffffffUL; struct platform_device s3c_device_pcm = { - .name = "s3c24xx-pcm-audio", + .name = "samsung-audio", .id = -1, .dev = { .dma_mask = &s3c_device_audio_dmamask, diff --git a/sound/soc/s3c24xx/goni_wm8994.c b/sound/soc/s3c24xx/goni_wm8994.c index 62134ed3aa57..b43ab3349585 100644 --- a/sound/soc/s3c24xx/goni_wm8994.c +++ b/sound/soc/s3c24xx/goni_wm8994.c @@ -251,7 +251,7 @@ static struct snd_soc_dai_link goni_dai[] = { .stream_name = "WM8994 HiFi", .cpu_dai_name = "s3c64xx-i2s-v4", .codec_dai_name = "wm8994-hifi", - .platform_name = "s3c24xx-pcm-audio", + .platform_name = "samsung-audio", .codec_name = "wm8994-codec.0-0x1a", .init = goni_wm8994_init, .ops = &goni_hifi_ops, @@ -260,7 +260,7 @@ static struct snd_soc_dai_link goni_dai[] = { .stream_name = "Voice", .cpu_dai_name = "goni-voice-dai", .codec_dai_name = "wm8994-voice", - .platform_name = "s3c24xx-pcm-audio", + .platform_name = "samsung-audio", .codec_name = "wm8994-codec.0-0x1a", .ops = &goni_voice_ops, }, diff --git a/sound/soc/s3c24xx/jive_wm8750.c b/sound/soc/s3c24xx/jive_wm8750.c index 100f0f0eabef..0bf0b99daa8d 100644 --- a/sound/soc/s3c24xx/jive_wm8750.c +++ b/sound/soc/s3c24xx/jive_wm8750.c @@ -141,7 +141,7 @@ static struct snd_soc_dai_link jive_dai = { .stream_name = "WM8750", .cpu_dai_name = "s3c2412-i2s", .codec_dai_name = "wm8750-hifi", - .platform_name = "s3c24xx-pcm-audio", + .platform_name = "samsung-audio", .codec_name = "wm8750-codec.0-0x1a", .init = jive_wm8750_init, .ops = &jive_ops, diff --git a/sound/soc/s3c24xx/ln2440sbc_alc650.c b/sound/soc/s3c24xx/ln2440sbc_alc650.c index dd4fad8c7b50..d04c0f2da090 100644 --- a/sound/soc/s3c24xx/ln2440sbc_alc650.c +++ b/sound/soc/s3c24xx/ln2440sbc_alc650.c @@ -34,7 +34,7 @@ static struct snd_soc_dai_link ln2440sbc_dai[] = { .cpu_dai_name = "s3c-ac97", .codec_dai_name = "ac97-hifi", .codec_name = "ac97-codec", - .platform_name = "s3c24xx-pcm-audio", + .platform_name = "samsung-audio", }, }; diff --git a/sound/soc/s3c24xx/neo1973_gta02_wm8753.c b/sound/soc/s3c24xx/neo1973_gta02_wm8753.c index 64c98e5d648d..0451d0f28d0c 100644 --- a/sound/soc/s3c24xx/neo1973_gta02_wm8753.c +++ b/sound/soc/s3c24xx/neo1973_gta02_wm8753.c @@ -400,7 +400,7 @@ static struct snd_soc_dai_link neo1973_gta02_dai[] = { .cpu_dai_name = "s3c24xx-i2s", .codec_dai_name = "wm8753-hifi", .init = neo1973_gta02_wm8753_init, - .platform_name = "s3c24xx-pcm-audio", + .platform_name = "samsung-audio", .codec_name = "wm8753-codec.0-0x1a", .ops = &neo1973_gta02_hifi_ops, }, @@ -411,7 +411,7 @@ static struct snd_soc_dai_link neo1973_gta02_dai[] = { .codec_dai_name = "wm8753-voice", .ops = &neo1973_gta02_voice_ops, .codec_name = "wm8753-codec.0-0x1a", - .platform_name = "s3c24xx-pcm-audio", + .platform_name = "samsung-audio", }, }; diff --git a/sound/soc/s3c24xx/neo1973_wm8753.c b/sound/soc/s3c24xx/neo1973_wm8753.c index 11e3c905bd87..000ed5f50723 100644 --- a/sound/soc/s3c24xx/neo1973_wm8753.c +++ b/sound/soc/s3c24xx/neo1973_wm8753.c @@ -558,7 +558,7 @@ static struct snd_soc_dai_link neo1973_dai[] = { { /* Hifi Playback - for similatious use with voice below */ .name = "WM8753", .stream_name = "WM8753 HiFi", - .platform_name = "s3c24xx-pcm-audio", + .platform_name = "samsung-audio", .cpu_dai_name = "s3c24xx-i2s", .codec_dai_name = "wm8753-hifi", .codec_name = "wm8753-codec.0-0x1a", @@ -568,7 +568,7 @@ static struct snd_soc_dai_link neo1973_dai[] = { { /* Voice via BT */ .name = "Bluetooth", .stream_name = "Voice", - .platform_name = "s3c24xx-pcm-audio", + .platform_name = "samsung-audio", .cpu_dai_name = "bluetooth-dai", .codec_dai_name = "wm8753-voice", .codec_name = "wm8753-codec.0-0x1a", diff --git a/sound/soc/s3c24xx/rx1950_uda1380.c b/sound/soc/s3c24xx/rx1950_uda1380.c index 5dfd4dbddca2..6e7912eb19f2 100644 --- a/sound/soc/s3c24xx/rx1950_uda1380.c +++ b/sound/soc/s3c24xx/rx1950_uda1380.c @@ -94,7 +94,7 @@ static struct snd_soc_dai_link rx1950_uda1380_dai[] = { .cpu_dai_name = "s3c24xx-iis", .codec_dai_name = "uda1380-hifi", .init = rx1950_uda1380_init, - .platform_name = "s3c24xx-pcm-audio", + .platform_name = "samsung-audio", .codec_name = "uda1380-codec.0-001a", .ops = &rx1950_ops, }, diff --git a/sound/soc/s3c24xx/s3c-dma.c b/sound/soc/s3c24xx/s3c-dma.c index 243f79bf43bb..19bcfa431075 100644 --- a/sound/soc/s3c24xx/s3c-dma.c +++ b/sound/soc/s3c24xx/s3c-dma.c @@ -476,7 +476,7 @@ static int __devexit s3c24xx_soc_platform_remove(struct platform_device *pdev) static struct platform_driver s3c24xx_pcm_driver = { .driver = { - .name = "s3c24xx-pcm-audio", + .name = "samsung-audio", .owner = THIS_MODULE, }, @@ -499,4 +499,4 @@ module_exit(snd_s3c24xx_pcm_exit); MODULE_AUTHOR("Ben Dooks, "); MODULE_DESCRIPTION("Samsung S3C Audio DMA module"); MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:s3c24xx-pcm-audio"); +MODULE_ALIAS("platform:samsung-audio"); diff --git a/sound/soc/s3c24xx/s3c24xx_simtec_hermes.c b/sound/soc/s3c24xx/s3c24xx_simtec_hermes.c index 044a0b241642..c1abd43bb9d1 100644 --- a/sound/soc/s3c24xx/s3c24xx_simtec_hermes.c +++ b/sound/soc/s3c24xx/s3c24xx_simtec_hermes.c @@ -99,7 +99,7 @@ static struct snd_soc_dai_link simtec_dai_aic33 = { .codec_name = "tlv320aic3x-codec.0-0x1a", .cpu_dai_name = "s3c24xx-i2s", .codec_dai_name = "tlv320aic3x-hifi", - .platform_name = "s3c24xx-pcm-audio", + .platform_name = "samsung-audio", .init = simtec_hermes_init, }; diff --git a/sound/soc/s3c24xx/s3c24xx_simtec_tlv320aic23.c b/sound/soc/s3c24xx/s3c24xx_simtec_tlv320aic23.c index f2f70a937110..1de58571aa56 100644 --- a/sound/soc/s3c24xx/s3c24xx_simtec_tlv320aic23.c +++ b/sound/soc/s3c24xx/s3c24xx_simtec_tlv320aic23.c @@ -88,7 +88,7 @@ static struct snd_soc_dai_link simtec_dai_aic23 = { .codec_name = "tlv320aic3x-codec.0-0x1a", .cpu_dai_name = "s3c24xx-i2s", .codec_dai_name = "tlv320aic3x-hifi", - .platform_name = "s3c24xx-pcm-audio", + .platform_name = "samsung-audio", .init = simtec_tlv320aic23_init, }; diff --git a/sound/soc/s3c24xx/s3c24xx_uda134x.c b/sound/soc/s3c24xx/s3c24xx_uda134x.c index 4f1eeb64b4c4..0bdfc6bbf778 100644 --- a/sound/soc/s3c24xx/s3c24xx_uda134x.c +++ b/sound/soc/s3c24xx/s3c24xx_uda134x.c @@ -230,7 +230,7 @@ static struct snd_soc_dai_link s3c24xx_uda134x_dai_link = { .codec_dai_name = "uda134x-hifi", .cpu_dai_name = "s3c24xx-i2s", .ops = &s3c24xx_uda134x_ops, - .platform_name = "s3c24xx-pcm-audio", + .platform_name = "samsung-audio", }; static struct snd_soc_card snd_soc_s3c24xx_uda134x = { diff --git a/sound/soc/s3c24xx/smartq_wm8987.c b/sound/soc/s3c24xx/smartq_wm8987.c index 5b07bb9802ee..ca83e1878666 100644 --- a/sound/soc/s3c24xx/smartq_wm8987.c +++ b/sound/soc/s3c24xx/smartq_wm8987.c @@ -214,7 +214,7 @@ static struct snd_soc_dai_link smartq_dai[] = { .stream_name = "SmartQ Hi-Fi", .cpu_dai_name = "s3c64xx-i2s.0", .codec_dai_name = "wm8750-hifi", - .platform_name = "s3c24xx-pcm-audio", + .platform_name = "samsung-audio", .codec_name = "wm8750-codec.0-0x1a", .init = smartq_wm8987_init, .ops = &smartq_hifi_ops, diff --git a/sound/soc/s3c24xx/smdk2443_wm9710.c b/sound/soc/s3c24xx/smdk2443_wm9710.c index ec05df92234b..50d707793511 100644 --- a/sound/soc/s3c24xx/smdk2443_wm9710.c +++ b/sound/soc/s3c24xx/smdk2443_wm9710.c @@ -30,7 +30,7 @@ static struct snd_soc_dai_link smdk2443_dai[] = { .cpu_dai_name = "s3c-ac97", .codec_dai_name = "ac97-hifi", .codec_name = "ac97-codec", - .platform_name = "s3c24xx-pcm-audio", + .platform_name = "samsung-audio", }, }; diff --git a/sound/soc/s3c24xx/smdk64xx_wm8580.c b/sound/soc/s3c24xx/smdk64xx_wm8580.c index e6b461cce191..3ed8bd098c4b 100644 --- a/sound/soc/s3c24xx/smdk64xx_wm8580.c +++ b/sound/soc/s3c24xx/smdk64xx_wm8580.c @@ -225,7 +225,7 @@ static struct snd_soc_dai_link smdk64xx_dai[] = { .stream_name = "Playback", .cpu_dai_name = "s3c64xx-iis-v4", .codec_dai_name = "wm8580-hifi-playback", - .platform_name = "s3c24xx-pcm-audio", + .platform_name = "samsung-audio", .codec_name = "wm8580-codec.0-001b", .init = smdk64xx_wm8580_init_paifrx, .ops = &smdk64xx_ops, @@ -235,7 +235,7 @@ static struct snd_soc_dai_link smdk64xx_dai[] = { .stream_name = "Capture", .cpu_dai_name = "s3c64xx-iis-v4", .codec_dai_name = "wm8580-hifi-capture", - .platform_name = "s3c24xx-pcm-audio", + .platform_name = "samsung-audio", .codec_name = "wm8580-codec.0-001b", .init = smdk64xx_wm8580_init_paiftx, .ops = &smdk64xx_ops, diff --git a/sound/soc/s3c24xx/smdk_spdif.c b/sound/soc/s3c24xx/smdk_spdif.c index c8bd90488a87..362957942994 100644 --- a/sound/soc/s3c24xx/smdk_spdif.c +++ b/sound/soc/s3c24xx/smdk_spdif.c @@ -157,7 +157,7 @@ static struct snd_soc_card smdk; static struct snd_soc_dai_link smdk_dai = { .name = "S/PDIF", .stream_name = "S/PDIF PCM Playback", - .platform_name = "s3c24xx-pcm-audio", + .platform_name = "samsung-audio", .cpu_dai_name = "samsung-spdif", .codec_dai_name = "dit-hifi", .codec_name = "spdif-dit", diff --git a/sound/soc/s3c24xx/smdk_wm9713.c b/sound/soc/s3c24xx/smdk_wm9713.c index 33ba8fdbcf07..ea96a519e02f 100644 --- a/sound/soc/s3c24xx/smdk_wm9713.c +++ b/sound/soc/s3c24xx/smdk_wm9713.c @@ -45,7 +45,7 @@ static struct snd_soc_card smdk; static struct snd_soc_dai_link smdk_dai = { .name = "AC97", .stream_name = "AC97 PCM", - .platform_name = "s3c24xx-pcm-audio", + .platform_name = "samsung-audio", .cpu_dai_name = "s3c-ac97", .codec_dai_name = "wm9713-hifi", .codec_name = "wm9713-codec", -- cgit v1.2.3 From 83e37b8e400ca51cc97946815b3055daacd92fa8 Mon Sep 17 00:00:00 2001 From: Jassi Brar Date: Mon, 22 Nov 2010 15:35:53 +0900 Subject: ARM: Samsung: Define common audio-dma device The ASoC uses common DMA driver for Audio devices. So it makes sense to a common audio-dma device shared across all platforms. Signed-off-by: Jassi Brar Acked-by: Kukjin Kim Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- arch/arm/mach-s3c2410/mach-h1940.c | 2 +- arch/arm/mach-s3c2440/mach-rx1950.c | 2 +- arch/arm/mach-s3c64xx/dev-audio.c | 13 ------------- arch/arm/mach-s3c64xx/mach-smdk6410.c | 2 +- arch/arm/plat-s3c24xx/devs.c | 17 ++--------------- arch/arm/plat-samsung/Makefile | 1 + arch/arm/plat-samsung/dev-asocdma.c | 24 ++++++++++++++++++++++++ arch/arm/plat-samsung/include/plat/devs.h | 2 +- 8 files changed, 31 insertions(+), 32 deletions(-) create mode 100644 arch/arm/plat-samsung/dev-asocdma.c diff --git a/arch/arm/mach-s3c2410/mach-h1940.c b/arch/arm/mach-s3c2410/mach-h1940.c index d7ada8c7e41f..1a81fe12ccd7 100644 --- a/arch/arm/mach-s3c2410/mach-h1940.c +++ b/arch/arm/mach-s3c2410/mach-h1940.c @@ -387,7 +387,7 @@ static struct platform_device *h1940_devices[] __initdata = { &s3c_device_wdt, &s3c_device_i2c0, &s3c_device_iis, - &s3c_device_pcm, + &samsung_asoc_dma, &s3c_device_usbgadget, &h1940_device_leds, &h1940_device_bluetooth, diff --git a/arch/arm/mach-s3c2440/mach-rx1950.c b/arch/arm/mach-s3c2440/mach-rx1950.c index e0622bbb6dfa..eab6ae50683c 100644 --- a/arch/arm/mach-s3c2440/mach-rx1950.c +++ b/arch/arm/mach-s3c2440/mach-rx1950.c @@ -692,7 +692,7 @@ static struct platform_device *rx1950_devices[] __initdata = { &s3c_device_wdt, &s3c_device_i2c0, &s3c_device_iis, - &s3c_device_pcm, + &samsung_asoc_dma, &s3c_device_usbgadget, &s3c_device_rtc, &s3c_device_nand, diff --git a/arch/arm/mach-s3c64xx/dev-audio.c b/arch/arm/mach-s3c64xx/dev-audio.c index bbaf7b3fa8ae..4a4b8a505ff9 100644 --- a/arch/arm/mach-s3c64xx/dev-audio.c +++ b/arch/arm/mach-s3c64xx/dev-audio.c @@ -315,16 +315,3 @@ void __init s3c64xx_ac97_setup_gpio(int num) else s3c_ac97_pdata.cfg_gpio = s3c64xx_ac97_cfg_gpe; } - -static u64 s3c_device_audio_dmamask = 0xffffffffUL; - -struct platform_device s3c_device_pcm = { - .name = "samsung-audio", - .id = -1, - .dev = { - .dma_mask = &s3c_device_audio_dmamask, - .coherent_dma_mask = 0xffffffffUL - } -}; -EXPORT_SYMBOL(s3c_device_pcm); - diff --git a/arch/arm/mach-s3c64xx/mach-smdk6410.c b/arch/arm/mach-s3c64xx/mach-smdk6410.c index 77488facfe4c..e85192a86fbe 100644 --- a/arch/arm/mach-s3c64xx/mach-smdk6410.c +++ b/arch/arm/mach-s3c64xx/mach-smdk6410.c @@ -283,7 +283,7 @@ static struct platform_device *smdk6410_devices[] __initdata = { &s3c_device_fb, &s3c_device_ohci, &s3c_device_usb_hsotg, - &s3c_device_pcm, + &samsung_asoc_dma, &s3c64xx_device_iisv4, &samsung_device_keypad, diff --git a/arch/arm/plat-s3c24xx/devs.c b/arch/arm/plat-s3c24xx/devs.c index 4bf0b3912a69..5987f949e167 100644 --- a/arch/arm/plat-s3c24xx/devs.c +++ b/arch/arm/plat-s3c24xx/devs.c @@ -259,21 +259,6 @@ struct platform_device s3c_device_iis = { EXPORT_SYMBOL(s3c_device_iis); -/* ASoC PCM DMA */ - -static u64 s3c_device_audio_dmamask = 0xffffffffUL; - -struct platform_device s3c_device_pcm = { - .name = "samsung-audio", - .id = -1, - .dev = { - .dma_mask = &s3c_device_audio_dmamask, - .coherent_dma_mask = 0xffffffffUL - } -}; - -EXPORT_SYMBOL(s3c_device_pcm); - /* RTC */ static struct resource s3c_rtc_resource[] = { @@ -496,6 +481,8 @@ static struct resource s3c_ac97_resource[] = { }, }; +static u64 s3c_device_audio_dmamask = 0xffffffffUL; + struct platform_device s3c_device_ac97 = { .name = "s3c-ac97", .id = -1, diff --git a/arch/arm/plat-samsung/Makefile b/arch/arm/plat-samsung/Makefile index afcce474af8e..19d8a16c3066 100644 --- a/arch/arm/plat-samsung/Makefile +++ b/arch/arm/plat-samsung/Makefile @@ -17,6 +17,7 @@ obj-y += clock.o obj-y += pwm-clock.o obj-y += gpio.o obj-y += gpio-config.o +obj-y += dev-asocdma.o obj-$(CONFIG_SAMSUNG_GPIOLIB_4BIT) += gpiolib.o obj-$(CONFIG_SAMSUNG_CLKSRC) += clock-clksrc.o diff --git a/arch/arm/plat-samsung/dev-asocdma.c b/arch/arm/plat-samsung/dev-asocdma.c new file mode 100644 index 000000000000..b7b1fcaab814 --- /dev/null +++ b/arch/arm/plat-samsung/dev-asocdma.c @@ -0,0 +1,24 @@ +/* linux/arch/arm/plat-samsung/dev-asocdma.c + * + * Copyright (c) 2010 Samsung Electronics Co. Ltd + * Jaswinder Singh + * + * 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 + +static u64 audio_dmamask = DMA_BIT_MASK(32); + +struct platform_device samsung_asoc_dma = { + .name = "samsung-audio", + .id = -1, + .dev = { + .dma_mask = &audio_dmamask, + .coherent_dma_mask = DMA_BIT_MASK(32), + } +}; +EXPORT_SYMBOL(samsung_asoc_dma); diff --git a/arch/arm/plat-samsung/include/plat/devs.h b/arch/arm/plat-samsung/include/plat/devs.h index dec0ded6a5ee..e9e3b6e3ec74 100644 --- a/arch/arm/plat-samsung/include/plat/devs.h +++ b/arch/arm/plat-samsung/include/plat/devs.h @@ -32,7 +32,7 @@ extern struct platform_device s3c64xx_device_iisv4; extern struct platform_device s3c64xx_device_spi0; extern struct platform_device s3c64xx_device_spi1; -extern struct platform_device s3c_device_pcm; +extern struct platform_device samsung_asoc_dma; extern struct platform_device s3c64xx_device_pcm0; extern struct platform_device s3c64xx_device_pcm1; -- cgit v1.2.3 From 4b640cf309e517f1ea5ab308fc7b24352612f535 Mon Sep 17 00:00:00 2001 From: Jassi Brar Date: Mon, 22 Nov 2010 15:35:57 +0900 Subject: ASoC: Samsung: Rename ASoC DMA driver Rename Samsung ASoC DMA driver s3c-dma.[c/h] -> dma.[c/h] Signed-off-by: Jassi Brar Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/s3c24xx/Makefile | 2 +- sound/soc/s3c24xx/dma.c | 502 +++++++++++++++++++++++++ sound/soc/s3c24xx/dma.h | 30 ++ sound/soc/s3c24xx/goni_wm8994.c | 2 +- sound/soc/s3c24xx/jive_wm8750.c | 2 +- sound/soc/s3c24xx/ln2440sbc_alc650.c | 2 +- sound/soc/s3c24xx/neo1973_gta02_wm8753.c | 2 +- sound/soc/s3c24xx/neo1973_wm8753.c | 2 +- sound/soc/s3c24xx/rx1950_uda1380.c | 2 +- sound/soc/s3c24xx/s3c-ac97.c | 2 +- sound/soc/s3c24xx/s3c-dma.c | 502 ------------------------- sound/soc/s3c24xx/s3c-dma.h | 30 -- sound/soc/s3c24xx/s3c-i2s-v2.c | 2 +- sound/soc/s3c24xx/s3c-pcm.c | 2 +- sound/soc/s3c24xx/s3c2412-i2s.c | 2 +- sound/soc/s3c24xx/s3c24xx-i2s.c | 2 +- sound/soc/s3c24xx/s3c24xx_simtec.c | 2 +- sound/soc/s3c24xx/s3c24xx_simtec_hermes.c | 2 +- sound/soc/s3c24xx/s3c24xx_simtec_tlv320aic23.c | 2 +- sound/soc/s3c24xx/s3c24xx_uda134x.c | 2 +- sound/soc/s3c24xx/s3c64xx-i2s-v4.c | 2 +- sound/soc/s3c24xx/s3c64xx-i2s.c | 2 +- sound/soc/s3c24xx/smartq_wm8987.c | 2 +- sound/soc/s3c24xx/smdk2443_wm9710.c | 2 +- sound/soc/s3c24xx/smdk64xx_wm8580.c | 2 +- sound/soc/s3c24xx/smdk_spdif.c | 2 +- sound/soc/s3c24xx/smdk_wm9713.c | 2 +- sound/soc/s3c24xx/spdif.c | 2 +- 28 files changed, 556 insertions(+), 556 deletions(-) create mode 100644 sound/soc/s3c24xx/dma.c create mode 100644 sound/soc/s3c24xx/dma.h delete mode 100644 sound/soc/s3c24xx/s3c-dma.c delete mode 100644 sound/soc/s3c24xx/s3c-dma.h diff --git a/sound/soc/s3c24xx/Makefile b/sound/soc/s3c24xx/Makefile index 4e232f112435..20aac4531f11 100644 --- a/sound/soc/s3c24xx/Makefile +++ b/sound/soc/s3c24xx/Makefile @@ -1,5 +1,5 @@ # S3c24XX Platform Support -snd-soc-s3c24xx-objs := s3c-dma.o +snd-soc-s3c24xx-objs := dma.o snd-soc-s3c24xx-i2s-objs := s3c24xx-i2s.o snd-soc-s3c2412-i2s-objs := s3c2412-i2s.o snd-soc-s3c64xx-i2s-objs := s3c64xx-i2s.o diff --git a/sound/soc/s3c24xx/dma.c b/sound/soc/s3c24xx/dma.c new file mode 100644 index 000000000000..c5eb1a2c72fd --- /dev/null +++ b/sound/soc/s3c24xx/dma.c @@ -0,0 +1,502 @@ +/* + * dma.c -- ALSA Soc Audio Layer + * + * (c) 2006 Wolfson Microelectronics PLC. + * Graeme Gregory graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com + * + * Copyright 2004-2005 Simtec Electronics + * http://armlinux.simtec.co.uk/ + * Ben Dooks + * + * 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. + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include "dma.h" + +static const struct snd_pcm_hardware s3c_dma_hardware = { + .info = SNDRV_PCM_INFO_INTERLEAVED | + SNDRV_PCM_INFO_BLOCK_TRANSFER | + SNDRV_PCM_INFO_MMAP | + SNDRV_PCM_INFO_MMAP_VALID | + SNDRV_PCM_INFO_PAUSE | + SNDRV_PCM_INFO_RESUME, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_U16_LE | + SNDRV_PCM_FMTBIT_U8 | + SNDRV_PCM_FMTBIT_S8, + .channels_min = 2, + .channels_max = 2, + .buffer_bytes_max = 128*1024, + .period_bytes_min = PAGE_SIZE, + .period_bytes_max = PAGE_SIZE*2, + .periods_min = 2, + .periods_max = 128, + .fifo_size = 32, +}; + +struct s3c24xx_runtime_data { + spinlock_t lock; + int state; + unsigned int dma_loaded; + unsigned int dma_limit; + unsigned int dma_period; + dma_addr_t dma_start; + dma_addr_t dma_pos; + dma_addr_t dma_end; + struct s3c_dma_params *params; +}; + +/* s3c_dma_enqueue + * + * place a dma buffer onto the queue for the dma system + * to handle. +*/ +static void s3c_dma_enqueue(struct snd_pcm_substream *substream) +{ + struct s3c24xx_runtime_data *prtd = substream->runtime->private_data; + dma_addr_t pos = prtd->dma_pos; + unsigned int limit; + int ret; + + pr_debug("Entered %s\n", __func__); + + if (s3c_dma_has_circular()) + limit = (prtd->dma_end - prtd->dma_start) / prtd->dma_period; + else + limit = prtd->dma_limit; + + pr_debug("%s: loaded %d, limit %d\n", + __func__, prtd->dma_loaded, limit); + + while (prtd->dma_loaded < limit) { + unsigned long len = prtd->dma_period; + + pr_debug("dma_loaded: %d\n", prtd->dma_loaded); + + if ((pos + len) > prtd->dma_end) { + len = prtd->dma_end - pos; + pr_debug("%s: corrected dma len %ld\n", __func__, len); + } + + ret = s3c2410_dma_enqueue(prtd->params->channel, + substream, pos, len); + + if (ret == 0) { + prtd->dma_loaded++; + pos += prtd->dma_period; + if (pos >= prtd->dma_end) + pos = prtd->dma_start; + } else + break; + } + + prtd->dma_pos = pos; +} + +static void s3c24xx_audio_buffdone(struct s3c2410_dma_chan *channel, + void *dev_id, int size, + enum s3c2410_dma_buffresult result) +{ + struct snd_pcm_substream *substream = dev_id; + struct s3c24xx_runtime_data *prtd; + + pr_debug("Entered %s\n", __func__); + + if (result == S3C2410_RES_ABORT || result == S3C2410_RES_ERR) + return; + + prtd = substream->runtime->private_data; + + if (substream) + snd_pcm_period_elapsed(substream); + + spin_lock(&prtd->lock); + if (prtd->state & ST_RUNNING && !s3c_dma_has_circular()) { + prtd->dma_loaded--; + s3c_dma_enqueue(substream); + } + + spin_unlock(&prtd->lock); +} + +static int s3c_dma_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct s3c24xx_runtime_data *prtd = runtime->private_data; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + unsigned long totbytes = params_buffer_bytes(params); + struct s3c_dma_params *dma = + snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); + int ret = 0; + + + pr_debug("Entered %s\n", __func__); + + /* return if this is a bufferless transfer e.g. + * codec <--> BT codec or GSM modem -- lg FIXME */ + if (!dma) + return 0; + + /* this may get called several times by oss emulation + * with different params -HW */ + if (prtd->params == NULL) { + /* prepare DMA */ + prtd->params = dma; + + pr_debug("params %p, client %p, channel %d\n", prtd->params, + prtd->params->client, prtd->params->channel); + + ret = s3c2410_dma_request(prtd->params->channel, + prtd->params->client, NULL); + + if (ret < 0) { + printk(KERN_ERR "failed to get dma channel\n"); + return ret; + } + + /* use the circular buffering if we have it available. */ + if (s3c_dma_has_circular()) + s3c2410_dma_setflags(prtd->params->channel, + S3C2410_DMAF_CIRCULAR); + } + + s3c2410_dma_set_buffdone_fn(prtd->params->channel, + s3c24xx_audio_buffdone); + + snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); + + runtime->dma_bytes = totbytes; + + spin_lock_irq(&prtd->lock); + prtd->dma_loaded = 0; + prtd->dma_limit = runtime->hw.periods_min; + prtd->dma_period = params_period_bytes(params); + prtd->dma_start = runtime->dma_addr; + prtd->dma_pos = prtd->dma_start; + prtd->dma_end = prtd->dma_start + totbytes; + spin_unlock_irq(&prtd->lock); + + return 0; +} + +static int s3c_dma_hw_free(struct snd_pcm_substream *substream) +{ + struct s3c24xx_runtime_data *prtd = substream->runtime->private_data; + + pr_debug("Entered %s\n", __func__); + + /* TODO - do we need to ensure DMA flushed */ + snd_pcm_set_runtime_buffer(substream, NULL); + + if (prtd->params) { + s3c2410_dma_free(prtd->params->channel, prtd->params->client); + prtd->params = NULL; + } + + return 0; +} + +static int s3c_dma_prepare(struct snd_pcm_substream *substream) +{ + struct s3c24xx_runtime_data *prtd = substream->runtime->private_data; + int ret = 0; + + pr_debug("Entered %s\n", __func__); + + /* return if this is a bufferless transfer e.g. + * codec <--> BT codec or GSM modem -- lg FIXME */ + if (!prtd->params) + return 0; + + /* channel needs configuring for mem=>device, increment memory addr, + * sync to pclk, half-word transfers to the IIS-FIFO. */ + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + s3c2410_dma_devconfig(prtd->params->channel, + S3C2410_DMASRC_MEM, + prtd->params->dma_addr); + } else { + s3c2410_dma_devconfig(prtd->params->channel, + S3C2410_DMASRC_HW, + prtd->params->dma_addr); + } + + s3c2410_dma_config(prtd->params->channel, + prtd->params->dma_size); + + /* flush the DMA channel */ + s3c2410_dma_ctrl(prtd->params->channel, S3C2410_DMAOP_FLUSH); + prtd->dma_loaded = 0; + prtd->dma_pos = prtd->dma_start; + + /* enqueue dma buffers */ + s3c_dma_enqueue(substream); + + return ret; +} + +static int s3c_dma_trigger(struct snd_pcm_substream *substream, int cmd) +{ + struct s3c24xx_runtime_data *prtd = substream->runtime->private_data; + int ret = 0; + + pr_debug("Entered %s\n", __func__); + + spin_lock(&prtd->lock); + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + case SNDRV_PCM_TRIGGER_RESUME: + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: + prtd->state |= ST_RUNNING; + s3c2410_dma_ctrl(prtd->params->channel, S3C2410_DMAOP_START); + break; + + case SNDRV_PCM_TRIGGER_STOP: + case SNDRV_PCM_TRIGGER_SUSPEND: + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + prtd->state &= ~ST_RUNNING; + s3c2410_dma_ctrl(prtd->params->channel, S3C2410_DMAOP_STOP); + break; + + default: + ret = -EINVAL; + break; + } + + spin_unlock(&prtd->lock); + + return ret; +} + +static snd_pcm_uframes_t +s3c_dma_pointer(struct snd_pcm_substream *substream) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct s3c24xx_runtime_data *prtd = runtime->private_data; + unsigned long res; + dma_addr_t src, dst; + + pr_debug("Entered %s\n", __func__); + + spin_lock(&prtd->lock); + s3c2410_dma_getposition(prtd->params->channel, &src, &dst); + + if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) + res = dst - prtd->dma_start; + else + res = src - prtd->dma_start; + + spin_unlock(&prtd->lock); + + pr_debug("Pointer %x %x\n", src, dst); + + /* we seem to be getting the odd error from the pcm library due + * to out-of-bounds pointers. this is maybe due to the dma engine + * not having loaded the new values for the channel before being + * callled... (todo - fix ) + */ + + if (res >= snd_pcm_lib_buffer_bytes(substream)) { + if (res == snd_pcm_lib_buffer_bytes(substream)) + res = 0; + } + + return bytes_to_frames(substream->runtime, res); +} + +static int s3c_dma_open(struct snd_pcm_substream *substream) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct s3c24xx_runtime_data *prtd; + + pr_debug("Entered %s\n", __func__); + + snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS); + snd_soc_set_runtime_hwparams(substream, &s3c_dma_hardware); + + prtd = kzalloc(sizeof(struct s3c24xx_runtime_data), GFP_KERNEL); + if (prtd == NULL) + return -ENOMEM; + + spin_lock_init(&prtd->lock); + + runtime->private_data = prtd; + return 0; +} + +static int s3c_dma_close(struct snd_pcm_substream *substream) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct s3c24xx_runtime_data *prtd = runtime->private_data; + + pr_debug("Entered %s\n", __func__); + + if (!prtd) + pr_debug("s3c_dma_close called with prtd == NULL\n"); + + kfree(prtd); + + return 0; +} + +static int s3c_dma_mmap(struct snd_pcm_substream *substream, + struct vm_area_struct *vma) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + + pr_debug("Entered %s\n", __func__); + + return dma_mmap_writecombine(substream->pcm->card->dev, vma, + runtime->dma_area, + runtime->dma_addr, + runtime->dma_bytes); +} + +static struct snd_pcm_ops s3c_dma_ops = { + .open = s3c_dma_open, + .close = s3c_dma_close, + .ioctl = snd_pcm_lib_ioctl, + .hw_params = s3c_dma_hw_params, + .hw_free = s3c_dma_hw_free, + .prepare = s3c_dma_prepare, + .trigger = s3c_dma_trigger, + .pointer = s3c_dma_pointer, + .mmap = s3c_dma_mmap, +}; + +static int s3c_preallocate_dma_buffer(struct snd_pcm *pcm, int stream) +{ + struct snd_pcm_substream *substream = pcm->streams[stream].substream; + struct snd_dma_buffer *buf = &substream->dma_buffer; + size_t size = s3c_dma_hardware.buffer_bytes_max; + + pr_debug("Entered %s\n", __func__); + + buf->dev.type = SNDRV_DMA_TYPE_DEV; + buf->dev.dev = pcm->card->dev; + buf->private_data = NULL; + buf->area = dma_alloc_writecombine(pcm->card->dev, size, + &buf->addr, GFP_KERNEL); + if (!buf->area) + return -ENOMEM; + buf->bytes = size; + return 0; +} + +static void s3c_dma_free_dma_buffers(struct snd_pcm *pcm) +{ + struct snd_pcm_substream *substream; + struct snd_dma_buffer *buf; + int stream; + + pr_debug("Entered %s\n", __func__); + + for (stream = 0; stream < 2; stream++) { + substream = pcm->streams[stream].substream; + if (!substream) + continue; + + buf = &substream->dma_buffer; + if (!buf->area) + continue; + + dma_free_writecombine(pcm->card->dev, buf->bytes, + buf->area, buf->addr); + buf->area = NULL; + } +} + +static u64 s3c_dma_mask = DMA_BIT_MASK(32); + +static int s3c_dma_new(struct snd_card *card, + struct snd_soc_dai *dai, struct snd_pcm *pcm) +{ + int ret = 0; + + pr_debug("Entered %s\n", __func__); + + if (!card->dev->dma_mask) + card->dev->dma_mask = &s3c_dma_mask; + if (!card->dev->coherent_dma_mask) + card->dev->coherent_dma_mask = 0xffffffff; + + if (dai->driver->playback.channels_min) { + ret = s3c_preallocate_dma_buffer(pcm, + SNDRV_PCM_STREAM_PLAYBACK); + if (ret) + goto out; + } + + if (dai->driver->capture.channels_min) { + ret = s3c_preallocate_dma_buffer(pcm, + SNDRV_PCM_STREAM_CAPTURE); + if (ret) + goto out; + } +out: + return ret; +} + +static struct snd_soc_platform_driver s3c24xx_soc_platform = { + .ops = &s3c_dma_ops, + .pcm_new = s3c_dma_new, + .pcm_free = s3c_dma_free_dma_buffers, +}; + +static int __devinit s3c24xx_soc_platform_probe(struct platform_device *pdev) +{ + return snd_soc_register_platform(&pdev->dev, &s3c24xx_soc_platform); +} + +static int __devexit s3c24xx_soc_platform_remove(struct platform_device *pdev) +{ + snd_soc_unregister_platform(&pdev->dev); + return 0; +} + +static struct platform_driver s3c24xx_pcm_driver = { + .driver = { + .name = "samsung-audio", + .owner = THIS_MODULE, + }, + + .probe = s3c24xx_soc_platform_probe, + .remove = __devexit_p(s3c24xx_soc_platform_remove), +}; + +static int __init snd_s3c24xx_pcm_init(void) +{ + return platform_driver_register(&s3c24xx_pcm_driver); +} +module_init(snd_s3c24xx_pcm_init); + +static void __exit snd_s3c24xx_pcm_exit(void) +{ + platform_driver_unregister(&s3c24xx_pcm_driver); +} +module_exit(snd_s3c24xx_pcm_exit); + +MODULE_AUTHOR("Ben Dooks, "); +MODULE_DESCRIPTION("Samsung S3C Audio DMA module"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:samsung-audio"); diff --git a/sound/soc/s3c24xx/dma.h b/sound/soc/s3c24xx/dma.h new file mode 100644 index 000000000000..f8cd2b4223af --- /dev/null +++ b/sound/soc/s3c24xx/dma.h @@ -0,0 +1,30 @@ +/* + * dma.h -- + * + * 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. + * + * ALSA PCM interface for the Samsung S3C24xx CPU + */ + +#ifndef _S3C_AUDIO_H +#define _S3C_AUDIO_H + +#define ST_RUNNING (1<<0) +#define ST_OPENED (1<<1) + +struct s3c_dma_params { + struct s3c2410_dma_client *client; /* stream identifier */ + int channel; /* Channel ID */ + dma_addr_t dma_addr; + int dma_size; /* Size of the DMA transfer */ +}; + +#define S3C24XX_DAI_I2S 0 + +/* platform data */ +extern struct snd_ac97_bus_ops s3c24xx_ac97_ops; + +#endif diff --git a/sound/soc/s3c24xx/goni_wm8994.c b/sound/soc/s3c24xx/goni_wm8994.c index b43ab3349585..0badcc56e93c 100644 --- a/sound/soc/s3c24xx/goni_wm8994.c +++ b/sound/soc/s3c24xx/goni_wm8994.c @@ -24,7 +24,7 @@ #include #include #include "../codecs/wm8994.h" -#include "s3c-dma.h" +#include "dma.h" #include "s3c64xx-i2s.h" #define MACHINE_NAME 0 diff --git a/sound/soc/s3c24xx/jive_wm8750.c b/sound/soc/s3c24xx/jive_wm8750.c index 0bf0b99daa8d..9e318dcb673b 100644 --- a/sound/soc/s3c24xx/jive_wm8750.c +++ b/sound/soc/s3c24xx/jive_wm8750.c @@ -24,7 +24,7 @@ #include -#include "s3c-dma.h" +#include "dma.h" #include "s3c2412-i2s.h" #include "../codecs/wm8750.h" diff --git a/sound/soc/s3c24xx/ln2440sbc_alc650.c b/sound/soc/s3c24xx/ln2440sbc_alc650.c index d04c0f2da090..340263e60f0c 100644 --- a/sound/soc/s3c24xx/ln2440sbc_alc650.c +++ b/sound/soc/s3c24xx/ln2440sbc_alc650.c @@ -22,7 +22,7 @@ #include #include -#include "s3c-dma.h" +#include "dma.h" #include "s3c-ac97.h" static struct snd_soc_card ln2440sbc; diff --git a/sound/soc/s3c24xx/neo1973_gta02_wm8753.c b/sound/soc/s3c24xx/neo1973_gta02_wm8753.c index 0451d0f28d0c..920e8d1f8841 100644 --- a/sound/soc/s3c24xx/neo1973_gta02_wm8753.c +++ b/sound/soc/s3c24xx/neo1973_gta02_wm8753.c @@ -31,7 +31,7 @@ #include #include #include "../codecs/wm8753.h" -#include "s3c-dma.h" +#include "dma.h" #include "s3c24xx-i2s.h" static struct snd_soc_card neo1973_gta02; diff --git a/sound/soc/s3c24xx/neo1973_wm8753.c b/sound/soc/s3c24xx/neo1973_wm8753.c index 000ed5f50723..c7a24514beb5 100644 --- a/sound/soc/s3c24xx/neo1973_wm8753.c +++ b/sound/soc/s3c24xx/neo1973_wm8753.c @@ -35,7 +35,7 @@ #include "../codecs/wm8753.h" #include "lm4857.h" -#include "s3c-dma.h" +#include "dma.h" #include "s3c24xx-i2s.h" /* define the scenarios */ diff --git a/sound/soc/s3c24xx/rx1950_uda1380.c b/sound/soc/s3c24xx/rx1950_uda1380.c index 6e7912eb19f2..5a4587e02886 100644 --- a/sound/soc/s3c24xx/rx1950_uda1380.c +++ b/sound/soc/s3c24xx/rx1950_uda1380.c @@ -34,7 +34,7 @@ #include -#include "s3c-dma.h" +#include "dma.h" #include "s3c24xx-i2s.h" #include "../codecs/uda1380.h" diff --git a/sound/soc/s3c24xx/s3c-ac97.c b/sound/soc/s3c24xx/s3c-ac97.c index f891eb79b575..408f9c9ff805 100644 --- a/sound/soc/s3c24xx/s3c-ac97.c +++ b/sound/soc/s3c24xx/s3c-ac97.c @@ -24,7 +24,7 @@ #include #include -#include "s3c-dma.h" +#include "dma.h" #include "s3c-ac97.h" #define AC_CMD_ADDR(x) (x << 16) diff --git a/sound/soc/s3c24xx/s3c-dma.c b/sound/soc/s3c24xx/s3c-dma.c deleted file mode 100644 index 19bcfa431075..000000000000 --- a/sound/soc/s3c24xx/s3c-dma.c +++ /dev/null @@ -1,502 +0,0 @@ -/* - * s3c-dma.c -- ALSA Soc Audio Layer - * - * (c) 2006 Wolfson Microelectronics PLC. - * Graeme Gregory graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com - * - * Copyright 2004-2005 Simtec Electronics - * http://armlinux.simtec.co.uk/ - * Ben Dooks - * - * 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. - */ - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include -#include - -#include "s3c-dma.h" - -static const struct snd_pcm_hardware s3c_dma_hardware = { - .info = SNDRV_PCM_INFO_INTERLEAVED | - SNDRV_PCM_INFO_BLOCK_TRANSFER | - SNDRV_PCM_INFO_MMAP | - SNDRV_PCM_INFO_MMAP_VALID | - SNDRV_PCM_INFO_PAUSE | - SNDRV_PCM_INFO_RESUME, - .formats = SNDRV_PCM_FMTBIT_S16_LE | - SNDRV_PCM_FMTBIT_U16_LE | - SNDRV_PCM_FMTBIT_U8 | - SNDRV_PCM_FMTBIT_S8, - .channels_min = 2, - .channels_max = 2, - .buffer_bytes_max = 128*1024, - .period_bytes_min = PAGE_SIZE, - .period_bytes_max = PAGE_SIZE*2, - .periods_min = 2, - .periods_max = 128, - .fifo_size = 32, -}; - -struct s3c24xx_runtime_data { - spinlock_t lock; - int state; - unsigned int dma_loaded; - unsigned int dma_limit; - unsigned int dma_period; - dma_addr_t dma_start; - dma_addr_t dma_pos; - dma_addr_t dma_end; - struct s3c_dma_params *params; -}; - -/* s3c_dma_enqueue - * - * place a dma buffer onto the queue for the dma system - * to handle. -*/ -static void s3c_dma_enqueue(struct snd_pcm_substream *substream) -{ - struct s3c24xx_runtime_data *prtd = substream->runtime->private_data; - dma_addr_t pos = prtd->dma_pos; - unsigned int limit; - int ret; - - pr_debug("Entered %s\n", __func__); - - if (s3c_dma_has_circular()) - limit = (prtd->dma_end - prtd->dma_start) / prtd->dma_period; - else - limit = prtd->dma_limit; - - pr_debug("%s: loaded %d, limit %d\n", - __func__, prtd->dma_loaded, limit); - - while (prtd->dma_loaded < limit) { - unsigned long len = prtd->dma_period; - - pr_debug("dma_loaded: %d\n", prtd->dma_loaded); - - if ((pos + len) > prtd->dma_end) { - len = prtd->dma_end - pos; - pr_debug("%s: corrected dma len %ld\n", __func__, len); - } - - ret = s3c2410_dma_enqueue(prtd->params->channel, - substream, pos, len); - - if (ret == 0) { - prtd->dma_loaded++; - pos += prtd->dma_period; - if (pos >= prtd->dma_end) - pos = prtd->dma_start; - } else - break; - } - - prtd->dma_pos = pos; -} - -static void s3c24xx_audio_buffdone(struct s3c2410_dma_chan *channel, - void *dev_id, int size, - enum s3c2410_dma_buffresult result) -{ - struct snd_pcm_substream *substream = dev_id; - struct s3c24xx_runtime_data *prtd; - - pr_debug("Entered %s\n", __func__); - - if (result == S3C2410_RES_ABORT || result == S3C2410_RES_ERR) - return; - - prtd = substream->runtime->private_data; - - if (substream) - snd_pcm_period_elapsed(substream); - - spin_lock(&prtd->lock); - if (prtd->state & ST_RUNNING && !s3c_dma_has_circular()) { - prtd->dma_loaded--; - s3c_dma_enqueue(substream); - } - - spin_unlock(&prtd->lock); -} - -static int s3c_dma_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - struct s3c24xx_runtime_data *prtd = runtime->private_data; - struct snd_soc_pcm_runtime *rtd = substream->private_data; - unsigned long totbytes = params_buffer_bytes(params); - struct s3c_dma_params *dma = - snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); - int ret = 0; - - - pr_debug("Entered %s\n", __func__); - - /* return if this is a bufferless transfer e.g. - * codec <--> BT codec or GSM modem -- lg FIXME */ - if (!dma) - return 0; - - /* this may get called several times by oss emulation - * with different params -HW */ - if (prtd->params == NULL) { - /* prepare DMA */ - prtd->params = dma; - - pr_debug("params %p, client %p, channel %d\n", prtd->params, - prtd->params->client, prtd->params->channel); - - ret = s3c2410_dma_request(prtd->params->channel, - prtd->params->client, NULL); - - if (ret < 0) { - printk(KERN_ERR "failed to get dma channel\n"); - return ret; - } - - /* use the circular buffering if we have it available. */ - if (s3c_dma_has_circular()) - s3c2410_dma_setflags(prtd->params->channel, - S3C2410_DMAF_CIRCULAR); - } - - s3c2410_dma_set_buffdone_fn(prtd->params->channel, - s3c24xx_audio_buffdone); - - snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); - - runtime->dma_bytes = totbytes; - - spin_lock_irq(&prtd->lock); - prtd->dma_loaded = 0; - prtd->dma_limit = runtime->hw.periods_min; - prtd->dma_period = params_period_bytes(params); - prtd->dma_start = runtime->dma_addr; - prtd->dma_pos = prtd->dma_start; - prtd->dma_end = prtd->dma_start + totbytes; - spin_unlock_irq(&prtd->lock); - - return 0; -} - -static int s3c_dma_hw_free(struct snd_pcm_substream *substream) -{ - struct s3c24xx_runtime_data *prtd = substream->runtime->private_data; - - pr_debug("Entered %s\n", __func__); - - /* TODO - do we need to ensure DMA flushed */ - snd_pcm_set_runtime_buffer(substream, NULL); - - if (prtd->params) { - s3c2410_dma_free(prtd->params->channel, prtd->params->client); - prtd->params = NULL; - } - - return 0; -} - -static int s3c_dma_prepare(struct snd_pcm_substream *substream) -{ - struct s3c24xx_runtime_data *prtd = substream->runtime->private_data; - int ret = 0; - - pr_debug("Entered %s\n", __func__); - - /* return if this is a bufferless transfer e.g. - * codec <--> BT codec or GSM modem -- lg FIXME */ - if (!prtd->params) - return 0; - - /* channel needs configuring for mem=>device, increment memory addr, - * sync to pclk, half-word transfers to the IIS-FIFO. */ - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - s3c2410_dma_devconfig(prtd->params->channel, - S3C2410_DMASRC_MEM, - prtd->params->dma_addr); - } else { - s3c2410_dma_devconfig(prtd->params->channel, - S3C2410_DMASRC_HW, - prtd->params->dma_addr); - } - - s3c2410_dma_config(prtd->params->channel, - prtd->params->dma_size); - - /* flush the DMA channel */ - s3c2410_dma_ctrl(prtd->params->channel, S3C2410_DMAOP_FLUSH); - prtd->dma_loaded = 0; - prtd->dma_pos = prtd->dma_start; - - /* enqueue dma buffers */ - s3c_dma_enqueue(substream); - - return ret; -} - -static int s3c_dma_trigger(struct snd_pcm_substream *substream, int cmd) -{ - struct s3c24xx_runtime_data *prtd = substream->runtime->private_data; - int ret = 0; - - pr_debug("Entered %s\n", __func__); - - spin_lock(&prtd->lock); - - switch (cmd) { - case SNDRV_PCM_TRIGGER_START: - case SNDRV_PCM_TRIGGER_RESUME: - case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - prtd->state |= ST_RUNNING; - s3c2410_dma_ctrl(prtd->params->channel, S3C2410_DMAOP_START); - break; - - case SNDRV_PCM_TRIGGER_STOP: - case SNDRV_PCM_TRIGGER_SUSPEND: - case SNDRV_PCM_TRIGGER_PAUSE_PUSH: - prtd->state &= ~ST_RUNNING; - s3c2410_dma_ctrl(prtd->params->channel, S3C2410_DMAOP_STOP); - break; - - default: - ret = -EINVAL; - break; - } - - spin_unlock(&prtd->lock); - - return ret; -} - -static snd_pcm_uframes_t -s3c_dma_pointer(struct snd_pcm_substream *substream) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - struct s3c24xx_runtime_data *prtd = runtime->private_data; - unsigned long res; - dma_addr_t src, dst; - - pr_debug("Entered %s\n", __func__); - - spin_lock(&prtd->lock); - s3c2410_dma_getposition(prtd->params->channel, &src, &dst); - - if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) - res = dst - prtd->dma_start; - else - res = src - prtd->dma_start; - - spin_unlock(&prtd->lock); - - pr_debug("Pointer %x %x\n", src, dst); - - /* we seem to be getting the odd error from the pcm library due - * to out-of-bounds pointers. this is maybe due to the dma engine - * not having loaded the new values for the channel before being - * callled... (todo - fix ) - */ - - if (res >= snd_pcm_lib_buffer_bytes(substream)) { - if (res == snd_pcm_lib_buffer_bytes(substream)) - res = 0; - } - - return bytes_to_frames(substream->runtime, res); -} - -static int s3c_dma_open(struct snd_pcm_substream *substream) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - struct s3c24xx_runtime_data *prtd; - - pr_debug("Entered %s\n", __func__); - - snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS); - snd_soc_set_runtime_hwparams(substream, &s3c_dma_hardware); - - prtd = kzalloc(sizeof(struct s3c24xx_runtime_data), GFP_KERNEL); - if (prtd == NULL) - return -ENOMEM; - - spin_lock_init(&prtd->lock); - - runtime->private_data = prtd; - return 0; -} - -static int s3c_dma_close(struct snd_pcm_substream *substream) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - struct s3c24xx_runtime_data *prtd = runtime->private_data; - - pr_debug("Entered %s\n", __func__); - - if (!prtd) - pr_debug("s3c_dma_close called with prtd == NULL\n"); - - kfree(prtd); - - return 0; -} - -static int s3c_dma_mmap(struct snd_pcm_substream *substream, - struct vm_area_struct *vma) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - - pr_debug("Entered %s\n", __func__); - - return dma_mmap_writecombine(substream->pcm->card->dev, vma, - runtime->dma_area, - runtime->dma_addr, - runtime->dma_bytes); -} - -static struct snd_pcm_ops s3c_dma_ops = { - .open = s3c_dma_open, - .close = s3c_dma_close, - .ioctl = snd_pcm_lib_ioctl, - .hw_params = s3c_dma_hw_params, - .hw_free = s3c_dma_hw_free, - .prepare = s3c_dma_prepare, - .trigger = s3c_dma_trigger, - .pointer = s3c_dma_pointer, - .mmap = s3c_dma_mmap, -}; - -static int s3c_preallocate_dma_buffer(struct snd_pcm *pcm, int stream) -{ - struct snd_pcm_substream *substream = pcm->streams[stream].substream; - struct snd_dma_buffer *buf = &substream->dma_buffer; - size_t size = s3c_dma_hardware.buffer_bytes_max; - - pr_debug("Entered %s\n", __func__); - - buf->dev.type = SNDRV_DMA_TYPE_DEV; - buf->dev.dev = pcm->card->dev; - buf->private_data = NULL; - buf->area = dma_alloc_writecombine(pcm->card->dev, size, - &buf->addr, GFP_KERNEL); - if (!buf->area) - return -ENOMEM; - buf->bytes = size; - return 0; -} - -static void s3c_dma_free_dma_buffers(struct snd_pcm *pcm) -{ - struct snd_pcm_substream *substream; - struct snd_dma_buffer *buf; - int stream; - - pr_debug("Entered %s\n", __func__); - - for (stream = 0; stream < 2; stream++) { - substream = pcm->streams[stream].substream; - if (!substream) - continue; - - buf = &substream->dma_buffer; - if (!buf->area) - continue; - - dma_free_writecombine(pcm->card->dev, buf->bytes, - buf->area, buf->addr); - buf->area = NULL; - } -} - -static u64 s3c_dma_mask = DMA_BIT_MASK(32); - -static int s3c_dma_new(struct snd_card *card, - struct snd_soc_dai *dai, struct snd_pcm *pcm) -{ - int ret = 0; - - pr_debug("Entered %s\n", __func__); - - if (!card->dev->dma_mask) - card->dev->dma_mask = &s3c_dma_mask; - if (!card->dev->coherent_dma_mask) - card->dev->coherent_dma_mask = 0xffffffff; - - if (dai->driver->playback.channels_min) { - ret = s3c_preallocate_dma_buffer(pcm, - SNDRV_PCM_STREAM_PLAYBACK); - if (ret) - goto out; - } - - if (dai->driver->capture.channels_min) { - ret = s3c_preallocate_dma_buffer(pcm, - SNDRV_PCM_STREAM_CAPTURE); - if (ret) - goto out; - } - out: - return ret; -} - -static struct snd_soc_platform_driver s3c24xx_soc_platform = { - .ops = &s3c_dma_ops, - .pcm_new = s3c_dma_new, - .pcm_free = s3c_dma_free_dma_buffers, -}; - -static int __devinit s3c24xx_soc_platform_probe(struct platform_device *pdev) -{ - return snd_soc_register_platform(&pdev->dev, &s3c24xx_soc_platform); -} - -static int __devexit s3c24xx_soc_platform_remove(struct platform_device *pdev) -{ - snd_soc_unregister_platform(&pdev->dev); - return 0; -} - -static struct platform_driver s3c24xx_pcm_driver = { - .driver = { - .name = "samsung-audio", - .owner = THIS_MODULE, - }, - - .probe = s3c24xx_soc_platform_probe, - .remove = __devexit_p(s3c24xx_soc_platform_remove), -}; - -static int __init snd_s3c24xx_pcm_init(void) -{ - return platform_driver_register(&s3c24xx_pcm_driver); -} -module_init(snd_s3c24xx_pcm_init); - -static void __exit snd_s3c24xx_pcm_exit(void) -{ - platform_driver_unregister(&s3c24xx_pcm_driver); -} -module_exit(snd_s3c24xx_pcm_exit); - -MODULE_AUTHOR("Ben Dooks, "); -MODULE_DESCRIPTION("Samsung S3C Audio DMA module"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:samsung-audio"); diff --git a/sound/soc/s3c24xx/s3c-dma.h b/sound/soc/s3c24xx/s3c-dma.h deleted file mode 100644 index 748c07d7c075..000000000000 --- a/sound/soc/s3c24xx/s3c-dma.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * s3c-dma.h -- - * - * 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. - * - * ALSA PCM interface for the Samsung S3C24xx CPU - */ - -#ifndef _S3C_AUDIO_H -#define _S3C_AUDIO_H - -#define ST_RUNNING (1<<0) -#define ST_OPENED (1<<1) - -struct s3c_dma_params { - struct s3c2410_dma_client *client; /* stream identifier */ - int channel; /* Channel ID */ - dma_addr_t dma_addr; - int dma_size; /* Size of the DMA transfer */ -}; - -#define S3C24XX_DAI_I2S 0 - -/* platform data */ -extern struct snd_ac97_bus_ops s3c24xx_ac97_ops; - -#endif diff --git a/sound/soc/s3c24xx/s3c-i2s-v2.c b/sound/soc/s3c24xx/s3c-i2s-v2.c index b3866d5b19e9..c4714319216c 100644 --- a/sound/soc/s3c24xx/s3c-i2s-v2.c +++ b/sound/soc/s3c24xx/s3c-i2s-v2.c @@ -28,7 +28,7 @@ #include "regs-i2s-v2.h" #include "s3c-i2s-v2.h" -#include "s3c-dma.h" +#include "dma.h" #undef S3C_IIS_V2_SUPPORTED diff --git a/sound/soc/s3c24xx/s3c-pcm.c b/sound/soc/s3c24xx/s3c-pcm.c index 2e020e1b4eab..e111d23f8886 100644 --- a/sound/soc/s3c24xx/s3c-pcm.c +++ b/sound/soc/s3c24xx/s3c-pcm.c @@ -29,7 +29,7 @@ #include #include -#include "s3c-dma.h" +#include "dma.h" #include "s3c-pcm.h" static struct s3c2410_dma_client s3c_pcm_dma_client_out = { diff --git a/sound/soc/s3c24xx/s3c2412-i2s.c b/sound/soc/s3c24xx/s3c2412-i2s.c index 4a861cfa52c5..d953ff4ba2db 100644 --- a/sound/soc/s3c24xx/s3c2412-i2s.c +++ b/sound/soc/s3c24xx/s3c2412-i2s.c @@ -35,7 +35,7 @@ #include #include -#include "s3c-dma.h" +#include "dma.h" #include "regs-i2s-v2.h" #include "s3c2412-i2s.h" diff --git a/sound/soc/s3c24xx/s3c24xx-i2s.c b/sound/soc/s3c24xx/s3c24xx-i2s.c index e060daaa458f..13e41ed8e22b 100644 --- a/sound/soc/s3c24xx/s3c24xx-i2s.c +++ b/sound/soc/s3c24xx/s3c24xx-i2s.c @@ -38,7 +38,7 @@ #include -#include "s3c-dma.h" +#include "dma.h" #include "s3c24xx-i2s.h" static struct s3c2410_dma_client s3c24xx_dma_client_out = { diff --git a/sound/soc/s3c24xx/s3c24xx_simtec.c b/sound/soc/s3c24xx/s3c24xx_simtec.c index 8d3bbc6385a7..2c7e2a8f49a1 100644 --- a/sound/soc/s3c24xx/s3c24xx_simtec.c +++ b/sound/soc/s3c24xx/s3c24xx_simtec.c @@ -20,7 +20,7 @@ #include -#include "s3c-dma.h" +#include "dma.h" #include "s3c24xx-i2s.h" #include "s3c24xx_simtec.h" diff --git a/sound/soc/s3c24xx/s3c24xx_simtec_hermes.c b/sound/soc/s3c24xx/s3c24xx_simtec_hermes.c index c1abd43bb9d1..3509403fb64d 100644 --- a/sound/soc/s3c24xx/s3c24xx_simtec_hermes.c +++ b/sound/soc/s3c24xx/s3c24xx_simtec_hermes.c @@ -17,7 +17,7 @@ #include -#include "s3c-dma.h" +#include "dma.h" #include "s3c24xx-i2s.h" #include "s3c24xx_simtec.h" diff --git a/sound/soc/s3c24xx/s3c24xx_simtec_tlv320aic23.c b/sound/soc/s3c24xx/s3c24xx_simtec_tlv320aic23.c index 1de58571aa56..b45e0b70cc28 100644 --- a/sound/soc/s3c24xx/s3c24xx_simtec_tlv320aic23.c +++ b/sound/soc/s3c24xx/s3c24xx_simtec_tlv320aic23.c @@ -17,7 +17,7 @@ #include -#include "s3c-dma.h" +#include "dma.h" #include "s3c24xx-i2s.h" #include "s3c24xx_simtec.h" diff --git a/sound/soc/s3c24xx/s3c24xx_uda134x.c b/sound/soc/s3c24xx/s3c24xx_uda134x.c index 0bdfc6bbf778..cdc8ecbcb8ef 100644 --- a/sound/soc/s3c24xx/s3c24xx_uda134x.c +++ b/sound/soc/s3c24xx/s3c24xx_uda134x.c @@ -23,7 +23,7 @@ #include -#include "s3c-dma.h" +#include "dma.h" #include "s3c24xx-i2s.h" #include "../codecs/uda134x.h" diff --git a/sound/soc/s3c24xx/s3c64xx-i2s-v4.c b/sound/soc/s3c24xx/s3c64xx-i2s-v4.c index a9628472ebfe..46b65d7cb630 100644 --- a/sound/soc/s3c24xx/s3c64xx-i2s-v4.c +++ b/sound/soc/s3c24xx/s3c64xx-i2s-v4.c @@ -21,7 +21,7 @@ #include #include -#include "s3c-dma.h" +#include "dma.h" #include "regs-i2s-v2.h" #include "s3c64xx-i2s.h" diff --git a/sound/soc/s3c24xx/s3c64xx-i2s.c b/sound/soc/s3c24xx/s3c64xx-i2s.c index ae7acb6c4f1d..0288d4ef14b3 100644 --- a/sound/soc/s3c24xx/s3c64xx-i2s.c +++ b/sound/soc/s3c24xx/s3c64xx-i2s.c @@ -25,7 +25,7 @@ #include #include -#include "s3c-dma.h" +#include "dma.h" #include "regs-i2s-v2.h" #include "s3c64xx-i2s.h" diff --git a/sound/soc/s3c24xx/smartq_wm8987.c b/sound/soc/s3c24xx/smartq_wm8987.c index ca83e1878666..968902e8e469 100644 --- a/sound/soc/s3c24xx/smartq_wm8987.c +++ b/sound/soc/s3c24xx/smartq_wm8987.c @@ -24,7 +24,7 @@ #include -#include "s3c-dma.h" +#include "dma.h" #include "s3c64xx-i2s.h" #include "../codecs/wm8750.h" diff --git a/sound/soc/s3c24xx/smdk2443_wm9710.c b/sound/soc/s3c24xx/smdk2443_wm9710.c index 50d707793511..2e9dd290941b 100644 --- a/sound/soc/s3c24xx/smdk2443_wm9710.c +++ b/sound/soc/s3c24xx/smdk2443_wm9710.c @@ -18,7 +18,7 @@ #include #include -#include "s3c-dma.h" +#include "dma.h" #include "s3c-ac97.h" static struct snd_soc_card smdk2443; diff --git a/sound/soc/s3c24xx/smdk64xx_wm8580.c b/sound/soc/s3c24xx/smdk64xx_wm8580.c index 3ed8bd098c4b..5125bc14fc0f 100644 --- a/sound/soc/s3c24xx/smdk64xx_wm8580.c +++ b/sound/soc/s3c24xx/smdk64xx_wm8580.c @@ -18,7 +18,7 @@ #include #include "../codecs/wm8580.h" -#include "s3c-dma.h" +#include "dma.h" #include "s3c64xx-i2s.h" /* diff --git a/sound/soc/s3c24xx/smdk_spdif.c b/sound/soc/s3c24xx/smdk_spdif.c index 362957942994..cd29da089c8f 100644 --- a/sound/soc/s3c24xx/smdk_spdif.c +++ b/sound/soc/s3c24xx/smdk_spdif.c @@ -18,7 +18,7 @@ #include -#include "s3c-dma.h" +#include "dma.h" #include "spdif.h" /* Audio clock settings are belonged to board specific part. Every diff --git a/sound/soc/s3c24xx/smdk_wm9713.c b/sound/soc/s3c24xx/smdk_wm9713.c index ea96a519e02f..80f2aef55c3d 100644 --- a/sound/soc/s3c24xx/smdk_wm9713.c +++ b/sound/soc/s3c24xx/smdk_wm9713.c @@ -15,7 +15,7 @@ #include #include -#include "s3c-dma.h" +#include "dma.h" #include "s3c-ac97.h" static struct snd_soc_card smdk; diff --git a/sound/soc/s3c24xx/spdif.c b/sound/soc/s3c24xx/spdif.c index ce554e9cabcc..dc85df32ebf2 100644 --- a/sound/soc/s3c24xx/spdif.c +++ b/sound/soc/s3c24xx/spdif.c @@ -20,7 +20,7 @@ #include #include -#include "s3c-dma.h" +#include "dma.h" #include "spdif.h" /* Registers */ -- cgit v1.2.3 From e6104673d28823e33bfc3dfb046a117f2575c9a8 Mon Sep 17 00:00:00 2001 From: Jassi Brar Date: Mon, 22 Nov 2010 15:36:00 +0900 Subject: ASoC: Samsung: Rename AC97 platform device Call the AC97 controller devices found in S3C, S5P and newer SoCs as 'samsung-ac97' rather than 's3c-ac97'. Signed-off-by: Jassi Brar Acked-by: Kukjin Kim Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- arch/arm/mach-s3c64xx/dev-audio.c | 2 +- arch/arm/mach-s5pc100/dev-audio.c | 2 +- arch/arm/mach-s5pv210/dev-audio.c | 2 +- arch/arm/plat-s3c24xx/devs.c | 2 +- sound/soc/s3c24xx/ln2440sbc_alc650.c | 2 +- sound/soc/s3c24xx/s3c-ac97.c | 4 ++-- sound/soc/s3c24xx/smdk2443_wm9710.c | 2 +- sound/soc/s3c24xx/smdk_wm9713.c | 2 +- 8 files changed, 9 insertions(+), 9 deletions(-) diff --git a/arch/arm/mach-s3c64xx/dev-audio.c b/arch/arm/mach-s3c64xx/dev-audio.c index 4a4b8a505ff9..cad67022fa25 100644 --- a/arch/arm/mach-s3c64xx/dev-audio.c +++ b/arch/arm/mach-s3c64xx/dev-audio.c @@ -296,7 +296,7 @@ static struct s3c_audio_pdata s3c_ac97_pdata; static u64 s3c64xx_ac97_dmamask = DMA_BIT_MASK(32); struct platform_device s3c64xx_device_ac97 = { - .name = "s3c-ac97", + .name = "samsung-ac97", .id = -1, .num_resources = ARRAY_SIZE(s3c64xx_ac97_resource), .resource = s3c64xx_ac97_resource, diff --git a/arch/arm/mach-s5pc100/dev-audio.c b/arch/arm/mach-s5pc100/dev-audio.c index 10ab275ebd63..ab2d27172cbc 100644 --- a/arch/arm/mach-s5pc100/dev-audio.c +++ b/arch/arm/mach-s5pc100/dev-audio.c @@ -281,7 +281,7 @@ static struct s3c_audio_pdata s3c_ac97_pdata = { static u64 s5pc100_ac97_dmamask = DMA_BIT_MASK(32); struct platform_device s5pc100_device_ac97 = { - .name = "s3c-ac97", + .name = "samsung-ac97", .id = -1, .num_resources = ARRAY_SIZE(s5pc100_ac97_resource), .resource = s5pc100_ac97_resource, diff --git a/arch/arm/mach-s5pv210/dev-audio.c b/arch/arm/mach-s5pv210/dev-audio.c index ddd2704b3467..8d58f1926241 100644 --- a/arch/arm/mach-s5pv210/dev-audio.c +++ b/arch/arm/mach-s5pv210/dev-audio.c @@ -311,7 +311,7 @@ static struct s3c_audio_pdata s3c_ac97_pdata = { static u64 s5pv210_ac97_dmamask = DMA_BIT_MASK(32); struct platform_device s5pv210_device_ac97 = { - .name = "s3c-ac97", + .name = "samsung-ac97", .id = -1, .num_resources = ARRAY_SIZE(s5pv210_ac97_resource), .resource = s5pv210_ac97_resource, diff --git a/arch/arm/plat-s3c24xx/devs.c b/arch/arm/plat-s3c24xx/devs.c index 5987f949e167..8a42bc48dbf0 100644 --- a/arch/arm/plat-s3c24xx/devs.c +++ b/arch/arm/plat-s3c24xx/devs.c @@ -484,7 +484,7 @@ static struct resource s3c_ac97_resource[] = { static u64 s3c_device_audio_dmamask = 0xffffffffUL; struct platform_device s3c_device_ac97 = { - .name = "s3c-ac97", + .name = "samsung-ac97", .id = -1, .num_resources = ARRAY_SIZE(s3c_ac97_resource), .resource = s3c_ac97_resource, diff --git a/sound/soc/s3c24xx/ln2440sbc_alc650.c b/sound/soc/s3c24xx/ln2440sbc_alc650.c index 340263e60f0c..1a0dd313afbd 100644 --- a/sound/soc/s3c24xx/ln2440sbc_alc650.c +++ b/sound/soc/s3c24xx/ln2440sbc_alc650.c @@ -31,7 +31,7 @@ static struct snd_soc_dai_link ln2440sbc_dai[] = { { .name = "AC97", .stream_name = "AC97 HiFi", - .cpu_dai_name = "s3c-ac97", + .cpu_dai_name = "samsung-ac97", .codec_dai_name = "ac97-hifi", .codec_name = "ac97-codec", .platform_name = "samsung-audio", diff --git a/sound/soc/s3c24xx/s3c-ac97.c b/sound/soc/s3c24xx/s3c-ac97.c index 408f9c9ff805..5352cacd9c17 100644 --- a/sound/soc/s3c24xx/s3c-ac97.c +++ b/sound/soc/s3c24xx/s3c-ac97.c @@ -497,7 +497,7 @@ static struct platform_driver s3c_ac97_driver = { .probe = s3c_ac97_probe, .remove = s3c_ac97_remove, .driver = { - .name = "s3c-ac97", + .name = "samsung-ac97", .owner = THIS_MODULE, }, }; @@ -517,4 +517,4 @@ module_exit(s3c_ac97_exit); MODULE_AUTHOR("Jaswinder Singh, "); MODULE_DESCRIPTION("AC97 driver for the Samsung SoC"); MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:s3c-ac97"); +MODULE_ALIAS("platform:samsung-ac97"); diff --git a/sound/soc/s3c24xx/smdk2443_wm9710.c b/sound/soc/s3c24xx/smdk2443_wm9710.c index 2e9dd290941b..e8787ad0a73e 100644 --- a/sound/soc/s3c24xx/smdk2443_wm9710.c +++ b/sound/soc/s3c24xx/smdk2443_wm9710.c @@ -27,7 +27,7 @@ static struct snd_soc_dai_link smdk2443_dai[] = { { .name = "AC97", .stream_name = "AC97 HiFi", - .cpu_dai_name = "s3c-ac97", + .cpu_dai_name = "samsung-ac97", .codec_dai_name = "ac97-hifi", .codec_name = "ac97-codec", .platform_name = "samsung-audio", diff --git a/sound/soc/s3c24xx/smdk_wm9713.c b/sound/soc/s3c24xx/smdk_wm9713.c index 80f2aef55c3d..56b448d49609 100644 --- a/sound/soc/s3c24xx/smdk_wm9713.c +++ b/sound/soc/s3c24xx/smdk_wm9713.c @@ -46,7 +46,7 @@ static struct snd_soc_dai_link smdk_dai = { .name = "AC97", .stream_name = "AC97 PCM", .platform_name = "samsung-audio", - .cpu_dai_name = "s3c-ac97", + .cpu_dai_name = "samsung-ac97", .codec_dai_name = "wm9713-hifi", .codec_name = "wm9713-codec", }; -- cgit v1.2.3 From 99ce3a3f3748f39ab6447c246b675f182ee761da Mon Sep 17 00:00:00 2001 From: Jassi Brar Date: Mon, 22 Nov 2010 15:36:03 +0900 Subject: ASoC: Samsung: Rename AC97 driver Rename Samsung AC97 driver s3c-ac97.[c/h] -> ac97.[c/h] Signed-off-by: Jassi Brar Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/s3c24xx/Makefile | 4 +- sound/soc/s3c24xx/ac97.c | 520 +++++++++++++++++++++++++++++++++++ sound/soc/s3c24xx/ac97.h | 21 ++ sound/soc/s3c24xx/ln2440sbc_alc650.c | 2 +- sound/soc/s3c24xx/s3c-ac97.c | 520 ----------------------------------- sound/soc/s3c24xx/s3c-ac97.h | 21 -- sound/soc/s3c24xx/smdk2443_wm9710.c | 2 +- sound/soc/s3c24xx/smdk_wm9713.c | 2 +- 8 files changed, 546 insertions(+), 546 deletions(-) create mode 100644 sound/soc/s3c24xx/ac97.c create mode 100644 sound/soc/s3c24xx/ac97.h delete mode 100644 sound/soc/s3c24xx/s3c-ac97.c delete mode 100644 sound/soc/s3c24xx/s3c-ac97.h diff --git a/sound/soc/s3c24xx/Makefile b/sound/soc/s3c24xx/Makefile index 20aac4531f11..551a63d65d73 100644 --- a/sound/soc/s3c24xx/Makefile +++ b/sound/soc/s3c24xx/Makefile @@ -3,7 +3,7 @@ snd-soc-s3c24xx-objs := dma.o snd-soc-s3c24xx-i2s-objs := s3c24xx-i2s.o snd-soc-s3c2412-i2s-objs := s3c2412-i2s.o snd-soc-s3c64xx-i2s-objs := s3c64xx-i2s.o -snd-soc-s3c-ac97-objs := s3c-ac97.o +snd-soc-ac97-objs := ac97.o snd-soc-s3c64xx-i2s-v4-objs := s3c64xx-i2s-v4.o snd-soc-s3c-i2s-v2-objs := s3c-i2s-v2.o snd-soc-s3c-pcm-objs := s3c-pcm.o @@ -11,7 +11,7 @@ snd-soc-samsung-spdif-objs := spdif.o obj-$(CONFIG_SND_S3C24XX_SOC) += snd-soc-s3c24xx.o obj-$(CONFIG_SND_S3C24XX_SOC_I2S) += snd-soc-s3c24xx-i2s.o -obj-$(CONFIG_SND_S3C_SOC_AC97) += snd-soc-s3c-ac97.o +obj-$(CONFIG_SND_S3C_SOC_AC97) += snd-soc-ac97.o obj-$(CONFIG_SND_S3C2412_SOC_I2S) += snd-soc-s3c2412-i2s.o obj-$(CONFIG_SND_S3C64XX_SOC_I2S) += snd-soc-s3c64xx-i2s.o obj-$(CONFIG_SND_S3C64XX_SOC_I2S_V4) += snd-soc-s3c64xx-i2s-v4.o diff --git a/sound/soc/s3c24xx/ac97.c b/sound/soc/s3c24xx/ac97.c new file mode 100644 index 000000000000..4f999d1bb330 --- /dev/null +++ b/sound/soc/s3c24xx/ac97.c @@ -0,0 +1,520 @@ +/* sound/soc/s3c24xx/ac97.c + * + * ALSA SoC Audio Layer - S3C AC97 Controller driver + * Evolved from s3c2443-ac97.c + * + * Copyright (c) 2010 Samsung Electronics Co. Ltd + * Author: Jaswinder Singh + * Credits: Graeme Gregory, Sean Choi + * + * 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 +#include + +#include + +#include +#include +#include + +#include "dma.h" +#include "ac97.h" + +#define AC_CMD_ADDR(x) (x << 16) +#define AC_CMD_DATA(x) (x & 0xffff) + +struct s3c_ac97_info { + struct clk *ac97_clk; + void __iomem *regs; + struct mutex lock; + struct completion done; +}; +static struct s3c_ac97_info s3c_ac97; + +static struct s3c2410_dma_client s3c_dma_client_out = { + .name = "AC97 PCMOut" +}; + +static struct s3c2410_dma_client s3c_dma_client_in = { + .name = "AC97 PCMIn" +}; + +static struct s3c2410_dma_client s3c_dma_client_micin = { + .name = "AC97 MicIn" +}; + +static struct s3c_dma_params s3c_ac97_pcm_out = { + .client = &s3c_dma_client_out, + .dma_size = 4, +}; + +static struct s3c_dma_params s3c_ac97_pcm_in = { + .client = &s3c_dma_client_in, + .dma_size = 4, +}; + +static struct s3c_dma_params s3c_ac97_mic_in = { + .client = &s3c_dma_client_micin, + .dma_size = 4, +}; + +static void s3c_ac97_activate(struct snd_ac97 *ac97) +{ + u32 ac_glbctrl, stat; + + stat = readl(s3c_ac97.regs + S3C_AC97_GLBSTAT) & 0x7; + if (stat == S3C_AC97_GLBSTAT_MAINSTATE_ACTIVE) + return; /* Return if already active */ + + INIT_COMPLETION(s3c_ac97.done); + + ac_glbctrl = readl(s3c_ac97.regs + S3C_AC97_GLBCTRL); + ac_glbctrl = S3C_AC97_GLBCTRL_ACLINKON; + writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL); + msleep(1); + + ac_glbctrl |= S3C_AC97_GLBCTRL_TRANSFERDATAENABLE; + writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL); + msleep(1); + + ac_glbctrl = readl(s3c_ac97.regs + S3C_AC97_GLBCTRL); + ac_glbctrl |= S3C_AC97_GLBCTRL_CODECREADYIE; + writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL); + + if (!wait_for_completion_timeout(&s3c_ac97.done, HZ)) + pr_err("AC97: Unable to activate!"); +} + +static unsigned short s3c_ac97_read(struct snd_ac97 *ac97, + unsigned short reg) +{ + u32 ac_glbctrl, ac_codec_cmd; + u32 stat, addr, data; + + mutex_lock(&s3c_ac97.lock); + + s3c_ac97_activate(ac97); + + INIT_COMPLETION(s3c_ac97.done); + + ac_codec_cmd = readl(s3c_ac97.regs + S3C_AC97_CODEC_CMD); + ac_codec_cmd = S3C_AC97_CODEC_CMD_READ | AC_CMD_ADDR(reg); + writel(ac_codec_cmd, s3c_ac97.regs + S3C_AC97_CODEC_CMD); + + udelay(50); + + ac_glbctrl = readl(s3c_ac97.regs + S3C_AC97_GLBCTRL); + ac_glbctrl |= S3C_AC97_GLBCTRL_CODECREADYIE; + writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL); + + if (!wait_for_completion_timeout(&s3c_ac97.done, HZ)) + pr_err("AC97: Unable to read!"); + + stat = readl(s3c_ac97.regs + S3C_AC97_STAT); + addr = (stat >> 16) & 0x7f; + data = (stat & 0xffff); + + if (addr != reg) + pr_err("ac97: req addr = %02x, rep addr = %02x\n", + reg, addr); + + mutex_unlock(&s3c_ac97.lock); + + return (unsigned short)data; +} + +static void s3c_ac97_write(struct snd_ac97 *ac97, unsigned short reg, + unsigned short val) +{ + u32 ac_glbctrl, ac_codec_cmd; + + mutex_lock(&s3c_ac97.lock); + + s3c_ac97_activate(ac97); + + INIT_COMPLETION(s3c_ac97.done); + + ac_codec_cmd = readl(s3c_ac97.regs + S3C_AC97_CODEC_CMD); + ac_codec_cmd = AC_CMD_ADDR(reg) | AC_CMD_DATA(val); + writel(ac_codec_cmd, s3c_ac97.regs + S3C_AC97_CODEC_CMD); + + udelay(50); + + ac_glbctrl = readl(s3c_ac97.regs + S3C_AC97_GLBCTRL); + ac_glbctrl |= S3C_AC97_GLBCTRL_CODECREADYIE; + writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL); + + if (!wait_for_completion_timeout(&s3c_ac97.done, HZ)) + pr_err("AC97: Unable to write!"); + + ac_codec_cmd = readl(s3c_ac97.regs + S3C_AC97_CODEC_CMD); + ac_codec_cmd |= S3C_AC97_CODEC_CMD_READ; + writel(ac_codec_cmd, s3c_ac97.regs + S3C_AC97_CODEC_CMD); + + mutex_unlock(&s3c_ac97.lock); +} + +static void s3c_ac97_cold_reset(struct snd_ac97 *ac97) +{ + pr_debug("AC97: Cold reset\n"); + writel(S3C_AC97_GLBCTRL_COLDRESET, + s3c_ac97.regs + S3C_AC97_GLBCTRL); + msleep(1); + + writel(0, s3c_ac97.regs + S3C_AC97_GLBCTRL); + msleep(1); +} + +static void s3c_ac97_warm_reset(struct snd_ac97 *ac97) +{ + u32 stat; + + stat = readl(s3c_ac97.regs + S3C_AC97_GLBSTAT) & 0x7; + if (stat == S3C_AC97_GLBSTAT_MAINSTATE_ACTIVE) + return; /* Return if already active */ + + pr_debug("AC97: Warm reset\n"); + + writel(S3C_AC97_GLBCTRL_WARMRESET, s3c_ac97.regs + S3C_AC97_GLBCTRL); + msleep(1); + + writel(0, s3c_ac97.regs + S3C_AC97_GLBCTRL); + msleep(1); + + s3c_ac97_activate(ac97); +} + +static irqreturn_t s3c_ac97_irq(int irq, void *dev_id) +{ + u32 ac_glbctrl, ac_glbstat; + + ac_glbstat = readl(s3c_ac97.regs + S3C_AC97_GLBSTAT); + + if (ac_glbstat & S3C_AC97_GLBSTAT_CODECREADY) { + + ac_glbctrl = readl(s3c_ac97.regs + S3C_AC97_GLBCTRL); + ac_glbctrl &= ~S3C_AC97_GLBCTRL_CODECREADYIE; + writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL); + + complete(&s3c_ac97.done); + } + + ac_glbctrl = readl(s3c_ac97.regs + S3C_AC97_GLBCTRL); + ac_glbctrl |= (1<<30); /* Clear interrupt */ + writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL); + + return IRQ_HANDLED; +} + +struct snd_ac97_bus_ops soc_ac97_ops = { + .read = s3c_ac97_read, + .write = s3c_ac97_write, + .warm_reset = s3c_ac97_warm_reset, + .reset = s3c_ac97_cold_reset, +}; +EXPORT_SYMBOL_GPL(soc_ac97_ops); + +static int s3c_ac97_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + struct s3c_dma_params *dma_data; + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + dma_data = &s3c_ac97_pcm_out; + else + dma_data = &s3c_ac97_pcm_in; + + snd_soc_dai_set_dma_data(cpu_dai, substream, dma_data); + + return 0; +} + +static int s3c_ac97_trigger(struct snd_pcm_substream *substream, int cmd, + struct snd_soc_dai *dai) +{ + u32 ac_glbctrl; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct s3c_dma_params *dma_data = + snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); + + ac_glbctrl = readl(s3c_ac97.regs + S3C_AC97_GLBCTRL); + if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) + ac_glbctrl &= ~S3C_AC97_GLBCTRL_PCMINTM_MASK; + else + ac_glbctrl &= ~S3C_AC97_GLBCTRL_PCMOUTTM_MASK; + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + case SNDRV_PCM_TRIGGER_RESUME: + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: + if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) + ac_glbctrl |= S3C_AC97_GLBCTRL_PCMINTM_DMA; + else + ac_glbctrl |= S3C_AC97_GLBCTRL_PCMOUTTM_DMA; + break; + + case SNDRV_PCM_TRIGGER_STOP: + case SNDRV_PCM_TRIGGER_SUSPEND: + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + break; + } + + writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL); + + s3c2410_dma_ctrl(dma_data->channel, S3C2410_DMAOP_STARTED); + + return 0; +} + +static int s3c_ac97_hw_mic_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + return -ENODEV; + else + snd_soc_dai_set_dma_data(cpu_dai, substream, &s3c_ac97_mic_in); + + return 0; +} + +static int s3c_ac97_mic_trigger(struct snd_pcm_substream *substream, + int cmd, struct snd_soc_dai *dai) +{ + u32 ac_glbctrl; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct s3c_dma_params *dma_data = + snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); + + ac_glbctrl = readl(s3c_ac97.regs + S3C_AC97_GLBCTRL); + ac_glbctrl &= ~S3C_AC97_GLBCTRL_MICINTM_MASK; + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + case SNDRV_PCM_TRIGGER_RESUME: + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: + ac_glbctrl |= S3C_AC97_GLBCTRL_MICINTM_DMA; + break; + + case SNDRV_PCM_TRIGGER_STOP: + case SNDRV_PCM_TRIGGER_SUSPEND: + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + break; + } + + writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL); + + s3c2410_dma_ctrl(dma_data->channel, S3C2410_DMAOP_STARTED); + + return 0; +} + +static struct snd_soc_dai_ops s3c_ac97_dai_ops = { + .hw_params = s3c_ac97_hw_params, + .trigger = s3c_ac97_trigger, +}; + +static struct snd_soc_dai_ops s3c_ac97_mic_dai_ops = { + .hw_params = s3c_ac97_hw_mic_params, + .trigger = s3c_ac97_mic_trigger, +}; + +static struct snd_soc_dai_driver s3c_ac97_dai[] = { + [S3C_AC97_DAI_PCM] = { + .name = "samsung-ac97", + .ac97_control = 1, + .playback = { + .stream_name = "AC97 Playback", + .channels_min = 2, + .channels_max = 2, + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = SNDRV_PCM_FMTBIT_S16_LE,}, + .capture = { + .stream_name = "AC97 Capture", + .channels_min = 2, + .channels_max = 2, + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = SNDRV_PCM_FMTBIT_S16_LE,}, + .ops = &s3c_ac97_dai_ops, + }, + [S3C_AC97_DAI_MIC] = { + .name = "samsung-ac97-mic", + .ac97_control = 1, + .capture = { + .stream_name = "AC97 Mic Capture", + .channels_min = 1, + .channels_max = 1, + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = SNDRV_PCM_FMTBIT_S16_LE,}, + .ops = &s3c_ac97_mic_dai_ops, + }, +}; + +static __devinit int s3c_ac97_probe(struct platform_device *pdev) +{ + struct resource *mem_res, *dmatx_res, *dmarx_res, *dmamic_res, *irq_res; + struct s3c_audio_pdata *ac97_pdata; + int ret; + + ac97_pdata = pdev->dev.platform_data; + if (!ac97_pdata || !ac97_pdata->cfg_gpio) { + dev_err(&pdev->dev, "cfg_gpio callback not provided!\n"); + return -EINVAL; + } + + /* Check for availability of necessary resource */ + dmatx_res = platform_get_resource(pdev, IORESOURCE_DMA, 0); + if (!dmatx_res) { + dev_err(&pdev->dev, "Unable to get AC97-TX dma resource\n"); + return -ENXIO; + } + + dmarx_res = platform_get_resource(pdev, IORESOURCE_DMA, 1); + if (!dmarx_res) { + dev_err(&pdev->dev, "Unable to get AC97-RX dma resource\n"); + return -ENXIO; + } + + dmamic_res = platform_get_resource(pdev, IORESOURCE_DMA, 2); + if (!dmamic_res) { + dev_err(&pdev->dev, "Unable to get AC97-MIC dma resource\n"); + return -ENXIO; + } + + mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!mem_res) { + dev_err(&pdev->dev, "Unable to get register resource\n"); + return -ENXIO; + } + + irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); + if (!irq_res) { + dev_err(&pdev->dev, "AC97 IRQ not provided!\n"); + return -ENXIO; + } + + if (!request_mem_region(mem_res->start, + resource_size(mem_res), "ac97")) { + dev_err(&pdev->dev, "Unable to request register region\n"); + return -EBUSY; + } + + s3c_ac97_pcm_out.channel = dmatx_res->start; + s3c_ac97_pcm_out.dma_addr = mem_res->start + S3C_AC97_PCM_DATA; + s3c_ac97_pcm_in.channel = dmarx_res->start; + s3c_ac97_pcm_in.dma_addr = mem_res->start + S3C_AC97_PCM_DATA; + s3c_ac97_mic_in.channel = dmamic_res->start; + s3c_ac97_mic_in.dma_addr = mem_res->start + S3C_AC97_MIC_DATA; + + init_completion(&s3c_ac97.done); + mutex_init(&s3c_ac97.lock); + + s3c_ac97.regs = ioremap(mem_res->start, resource_size(mem_res)); + if (s3c_ac97.regs == NULL) { + dev_err(&pdev->dev, "Unable to ioremap register region\n"); + ret = -ENXIO; + goto err1; + } + + s3c_ac97.ac97_clk = clk_get(&pdev->dev, "ac97"); + if (IS_ERR(s3c_ac97.ac97_clk)) { + dev_err(&pdev->dev, "ac97 failed to get ac97_clock\n"); + ret = -ENODEV; + goto err2; + } + clk_enable(s3c_ac97.ac97_clk); + + if (ac97_pdata->cfg_gpio(pdev)) { + dev_err(&pdev->dev, "Unable to configure gpio\n"); + ret = -EINVAL; + goto err3; + } + + ret = request_irq(irq_res->start, s3c_ac97_irq, + IRQF_DISABLED, "AC97", NULL); + if (ret < 0) { + dev_err(&pdev->dev, "ac97: interrupt request failed.\n"); + goto err4; + } + + ret = snd_soc_register_dais(&pdev->dev, s3c_ac97_dai, + ARRAY_SIZE(s3c_ac97_dai)); + if (ret) + goto err5; + + return 0; + +err5: + free_irq(irq_res->start, NULL); +err4: +err3: + clk_disable(s3c_ac97.ac97_clk); + clk_put(s3c_ac97.ac97_clk); +err2: + iounmap(s3c_ac97.regs); +err1: + release_mem_region(mem_res->start, resource_size(mem_res)); + + return ret; +} + +static __devexit int s3c_ac97_remove(struct platform_device *pdev) +{ + struct resource *mem_res, *irq_res; + + snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(s3c_ac97_dai)); + + irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); + if (irq_res) + free_irq(irq_res->start, NULL); + + clk_disable(s3c_ac97.ac97_clk); + clk_put(s3c_ac97.ac97_clk); + + iounmap(s3c_ac97.regs); + + mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (mem_res) + release_mem_region(mem_res->start, resource_size(mem_res)); + + return 0; +} + +static struct platform_driver s3c_ac97_driver = { + .probe = s3c_ac97_probe, + .remove = s3c_ac97_remove, + .driver = { + .name = "samsung-ac97", + .owner = THIS_MODULE, + }, +}; + +static int __init s3c_ac97_init(void) +{ + return platform_driver_register(&s3c_ac97_driver); +} +module_init(s3c_ac97_init); + +static void __exit s3c_ac97_exit(void) +{ + platform_driver_unregister(&s3c_ac97_driver); +} +module_exit(s3c_ac97_exit); + +MODULE_AUTHOR("Jaswinder Singh, "); +MODULE_DESCRIPTION("AC97 driver for the Samsung SoC"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:samsung-ac97"); diff --git a/sound/soc/s3c24xx/ac97.h b/sound/soc/s3c24xx/ac97.h new file mode 100644 index 000000000000..a8f01b788878 --- /dev/null +++ b/sound/soc/s3c24xx/ac97.h @@ -0,0 +1,21 @@ +/* sound/soc/s3c24xx/ac97.h + * + * ALSA SoC Audio Layer - S3C AC97 Controller driver + * Evolved from s3c2443-ac97.h + * + * Copyright (c) 2010 Samsung Electronics Co. Ltd + * Author: Jaswinder Singh + * Credits: Graeme Gregory, Sean Choi + * + * 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. + */ + +#ifndef __S3C_AC97_H_ +#define __S3C_AC97_H_ + +#define S3C_AC97_DAI_PCM 0 +#define S3C_AC97_DAI_MIC 1 + +#endif /* __S3C_AC97_H_ */ diff --git a/sound/soc/s3c24xx/ln2440sbc_alc650.c b/sound/soc/s3c24xx/ln2440sbc_alc650.c index 1a0dd313afbd..a2bb34def740 100644 --- a/sound/soc/s3c24xx/ln2440sbc_alc650.c +++ b/sound/soc/s3c24xx/ln2440sbc_alc650.c @@ -23,7 +23,7 @@ #include #include "dma.h" -#include "s3c-ac97.h" +#include "ac97.h" static struct snd_soc_card ln2440sbc; diff --git a/sound/soc/s3c24xx/s3c-ac97.c b/sound/soc/s3c24xx/s3c-ac97.c deleted file mode 100644 index 5352cacd9c17..000000000000 --- a/sound/soc/s3c24xx/s3c-ac97.c +++ /dev/null @@ -1,520 +0,0 @@ -/* sound/soc/s3c24xx/s3c-ac97.c - * - * ALSA SoC Audio Layer - S3C AC97 Controller driver - * Evolved from s3c2443-ac97.c - * - * Copyright (c) 2010 Samsung Electronics Co. Ltd - * Author: Jaswinder Singh - * Credits: Graeme Gregory, Sean Choi - * - * 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 -#include - -#include - -#include -#include -#include - -#include "dma.h" -#include "s3c-ac97.h" - -#define AC_CMD_ADDR(x) (x << 16) -#define AC_CMD_DATA(x) (x & 0xffff) - -struct s3c_ac97_info { - struct clk *ac97_clk; - void __iomem *regs; - struct mutex lock; - struct completion done; -}; -static struct s3c_ac97_info s3c_ac97; - -static struct s3c2410_dma_client s3c_dma_client_out = { - .name = "AC97 PCMOut" -}; - -static struct s3c2410_dma_client s3c_dma_client_in = { - .name = "AC97 PCMIn" -}; - -static struct s3c2410_dma_client s3c_dma_client_micin = { - .name = "AC97 MicIn" -}; - -static struct s3c_dma_params s3c_ac97_pcm_out = { - .client = &s3c_dma_client_out, - .dma_size = 4, -}; - -static struct s3c_dma_params s3c_ac97_pcm_in = { - .client = &s3c_dma_client_in, - .dma_size = 4, -}; - -static struct s3c_dma_params s3c_ac97_mic_in = { - .client = &s3c_dma_client_micin, - .dma_size = 4, -}; - -static void s3c_ac97_activate(struct snd_ac97 *ac97) -{ - u32 ac_glbctrl, stat; - - stat = readl(s3c_ac97.regs + S3C_AC97_GLBSTAT) & 0x7; - if (stat == S3C_AC97_GLBSTAT_MAINSTATE_ACTIVE) - return; /* Return if already active */ - - INIT_COMPLETION(s3c_ac97.done); - - ac_glbctrl = readl(s3c_ac97.regs + S3C_AC97_GLBCTRL); - ac_glbctrl = S3C_AC97_GLBCTRL_ACLINKON; - writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL); - msleep(1); - - ac_glbctrl |= S3C_AC97_GLBCTRL_TRANSFERDATAENABLE; - writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL); - msleep(1); - - ac_glbctrl = readl(s3c_ac97.regs + S3C_AC97_GLBCTRL); - ac_glbctrl |= S3C_AC97_GLBCTRL_CODECREADYIE; - writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL); - - if (!wait_for_completion_timeout(&s3c_ac97.done, HZ)) - pr_err("AC97: Unable to activate!"); -} - -static unsigned short s3c_ac97_read(struct snd_ac97 *ac97, - unsigned short reg) -{ - u32 ac_glbctrl, ac_codec_cmd; - u32 stat, addr, data; - - mutex_lock(&s3c_ac97.lock); - - s3c_ac97_activate(ac97); - - INIT_COMPLETION(s3c_ac97.done); - - ac_codec_cmd = readl(s3c_ac97.regs + S3C_AC97_CODEC_CMD); - ac_codec_cmd = S3C_AC97_CODEC_CMD_READ | AC_CMD_ADDR(reg); - writel(ac_codec_cmd, s3c_ac97.regs + S3C_AC97_CODEC_CMD); - - udelay(50); - - ac_glbctrl = readl(s3c_ac97.regs + S3C_AC97_GLBCTRL); - ac_glbctrl |= S3C_AC97_GLBCTRL_CODECREADYIE; - writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL); - - if (!wait_for_completion_timeout(&s3c_ac97.done, HZ)) - pr_err("AC97: Unable to read!"); - - stat = readl(s3c_ac97.regs + S3C_AC97_STAT); - addr = (stat >> 16) & 0x7f; - data = (stat & 0xffff); - - if (addr != reg) - pr_err("s3c-ac97: req addr = %02x, rep addr = %02x\n", - reg, addr); - - mutex_unlock(&s3c_ac97.lock); - - return (unsigned short)data; -} - -static void s3c_ac97_write(struct snd_ac97 *ac97, unsigned short reg, - unsigned short val) -{ - u32 ac_glbctrl, ac_codec_cmd; - - mutex_lock(&s3c_ac97.lock); - - s3c_ac97_activate(ac97); - - INIT_COMPLETION(s3c_ac97.done); - - ac_codec_cmd = readl(s3c_ac97.regs + S3C_AC97_CODEC_CMD); - ac_codec_cmd = AC_CMD_ADDR(reg) | AC_CMD_DATA(val); - writel(ac_codec_cmd, s3c_ac97.regs + S3C_AC97_CODEC_CMD); - - udelay(50); - - ac_glbctrl = readl(s3c_ac97.regs + S3C_AC97_GLBCTRL); - ac_glbctrl |= S3C_AC97_GLBCTRL_CODECREADYIE; - writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL); - - if (!wait_for_completion_timeout(&s3c_ac97.done, HZ)) - pr_err("AC97: Unable to write!"); - - ac_codec_cmd = readl(s3c_ac97.regs + S3C_AC97_CODEC_CMD); - ac_codec_cmd |= S3C_AC97_CODEC_CMD_READ; - writel(ac_codec_cmd, s3c_ac97.regs + S3C_AC97_CODEC_CMD); - - mutex_unlock(&s3c_ac97.lock); -} - -static void s3c_ac97_cold_reset(struct snd_ac97 *ac97) -{ - pr_debug("AC97: Cold reset\n"); - writel(S3C_AC97_GLBCTRL_COLDRESET, - s3c_ac97.regs + S3C_AC97_GLBCTRL); - msleep(1); - - writel(0, s3c_ac97.regs + S3C_AC97_GLBCTRL); - msleep(1); -} - -static void s3c_ac97_warm_reset(struct snd_ac97 *ac97) -{ - u32 stat; - - stat = readl(s3c_ac97.regs + S3C_AC97_GLBSTAT) & 0x7; - if (stat == S3C_AC97_GLBSTAT_MAINSTATE_ACTIVE) - return; /* Return if already active */ - - pr_debug("AC97: Warm reset\n"); - - writel(S3C_AC97_GLBCTRL_WARMRESET, s3c_ac97.regs + S3C_AC97_GLBCTRL); - msleep(1); - - writel(0, s3c_ac97.regs + S3C_AC97_GLBCTRL); - msleep(1); - - s3c_ac97_activate(ac97); -} - -static irqreturn_t s3c_ac97_irq(int irq, void *dev_id) -{ - u32 ac_glbctrl, ac_glbstat; - - ac_glbstat = readl(s3c_ac97.regs + S3C_AC97_GLBSTAT); - - if (ac_glbstat & S3C_AC97_GLBSTAT_CODECREADY) { - - ac_glbctrl = readl(s3c_ac97.regs + S3C_AC97_GLBCTRL); - ac_glbctrl &= ~S3C_AC97_GLBCTRL_CODECREADYIE; - writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL); - - complete(&s3c_ac97.done); - } - - ac_glbctrl = readl(s3c_ac97.regs + S3C_AC97_GLBCTRL); - ac_glbctrl |= (1<<30); /* Clear interrupt */ - writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL); - - return IRQ_HANDLED; -} - -struct snd_ac97_bus_ops soc_ac97_ops = { - .read = s3c_ac97_read, - .write = s3c_ac97_write, - .warm_reset = s3c_ac97_warm_reset, - .reset = s3c_ac97_cold_reset, -}; -EXPORT_SYMBOL_GPL(soc_ac97_ops); - -static int s3c_ac97_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params, - struct snd_soc_dai *dai) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; - struct s3c_dma_params *dma_data; - - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - dma_data = &s3c_ac97_pcm_out; - else - dma_data = &s3c_ac97_pcm_in; - - snd_soc_dai_set_dma_data(cpu_dai, substream, dma_data); - - return 0; -} - -static int s3c_ac97_trigger(struct snd_pcm_substream *substream, int cmd, - struct snd_soc_dai *dai) -{ - u32 ac_glbctrl; - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct s3c_dma_params *dma_data = - snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); - - ac_glbctrl = readl(s3c_ac97.regs + S3C_AC97_GLBCTRL); - if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) - ac_glbctrl &= ~S3C_AC97_GLBCTRL_PCMINTM_MASK; - else - ac_glbctrl &= ~S3C_AC97_GLBCTRL_PCMOUTTM_MASK; - - switch (cmd) { - case SNDRV_PCM_TRIGGER_START: - case SNDRV_PCM_TRIGGER_RESUME: - case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) - ac_glbctrl |= S3C_AC97_GLBCTRL_PCMINTM_DMA; - else - ac_glbctrl |= S3C_AC97_GLBCTRL_PCMOUTTM_DMA; - break; - - case SNDRV_PCM_TRIGGER_STOP: - case SNDRV_PCM_TRIGGER_SUSPEND: - case SNDRV_PCM_TRIGGER_PAUSE_PUSH: - break; - } - - writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL); - - s3c2410_dma_ctrl(dma_data->channel, S3C2410_DMAOP_STARTED); - - return 0; -} - -static int s3c_ac97_hw_mic_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params, - struct snd_soc_dai *dai) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; - - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - return -ENODEV; - else - snd_soc_dai_set_dma_data(cpu_dai, substream, &s3c_ac97_mic_in); - - return 0; -} - -static int s3c_ac97_mic_trigger(struct snd_pcm_substream *substream, - int cmd, struct snd_soc_dai *dai) -{ - u32 ac_glbctrl; - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct s3c_dma_params *dma_data = - snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); - - ac_glbctrl = readl(s3c_ac97.regs + S3C_AC97_GLBCTRL); - ac_glbctrl &= ~S3C_AC97_GLBCTRL_MICINTM_MASK; - - switch (cmd) { - case SNDRV_PCM_TRIGGER_START: - case SNDRV_PCM_TRIGGER_RESUME: - case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - ac_glbctrl |= S3C_AC97_GLBCTRL_MICINTM_DMA; - break; - - case SNDRV_PCM_TRIGGER_STOP: - case SNDRV_PCM_TRIGGER_SUSPEND: - case SNDRV_PCM_TRIGGER_PAUSE_PUSH: - break; - } - - writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL); - - s3c2410_dma_ctrl(dma_data->channel, S3C2410_DMAOP_STARTED); - - return 0; -} - -static struct snd_soc_dai_ops s3c_ac97_dai_ops = { - .hw_params = s3c_ac97_hw_params, - .trigger = s3c_ac97_trigger, -}; - -static struct snd_soc_dai_ops s3c_ac97_mic_dai_ops = { - .hw_params = s3c_ac97_hw_mic_params, - .trigger = s3c_ac97_mic_trigger, -}; - -static struct snd_soc_dai_driver s3c_ac97_dai[] = { - [S3C_AC97_DAI_PCM] = { - .name = "s3c-ac97", - .ac97_control = 1, - .playback = { - .stream_name = "AC97 Playback", - .channels_min = 2, - .channels_max = 2, - .rates = SNDRV_PCM_RATE_8000_48000, - .formats = SNDRV_PCM_FMTBIT_S16_LE,}, - .capture = { - .stream_name = "AC97 Capture", - .channels_min = 2, - .channels_max = 2, - .rates = SNDRV_PCM_RATE_8000_48000, - .formats = SNDRV_PCM_FMTBIT_S16_LE,}, - .ops = &s3c_ac97_dai_ops, - }, - [S3C_AC97_DAI_MIC] = { - .name = "s3c-ac97-mic", - .ac97_control = 1, - .capture = { - .stream_name = "AC97 Mic Capture", - .channels_min = 1, - .channels_max = 1, - .rates = SNDRV_PCM_RATE_8000_48000, - .formats = SNDRV_PCM_FMTBIT_S16_LE,}, - .ops = &s3c_ac97_mic_dai_ops, - }, -}; - -static __devinit int s3c_ac97_probe(struct platform_device *pdev) -{ - struct resource *mem_res, *dmatx_res, *dmarx_res, *dmamic_res, *irq_res; - struct s3c_audio_pdata *ac97_pdata; - int ret; - - ac97_pdata = pdev->dev.platform_data; - if (!ac97_pdata || !ac97_pdata->cfg_gpio) { - dev_err(&pdev->dev, "cfg_gpio callback not provided!\n"); - return -EINVAL; - } - - /* Check for availability of necessary resource */ - dmatx_res = platform_get_resource(pdev, IORESOURCE_DMA, 0); - if (!dmatx_res) { - dev_err(&pdev->dev, "Unable to get AC97-TX dma resource\n"); - return -ENXIO; - } - - dmarx_res = platform_get_resource(pdev, IORESOURCE_DMA, 1); - if (!dmarx_res) { - dev_err(&pdev->dev, "Unable to get AC97-RX dma resource\n"); - return -ENXIO; - } - - dmamic_res = platform_get_resource(pdev, IORESOURCE_DMA, 2); - if (!dmamic_res) { - dev_err(&pdev->dev, "Unable to get AC97-MIC dma resource\n"); - return -ENXIO; - } - - mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!mem_res) { - dev_err(&pdev->dev, "Unable to get register resource\n"); - return -ENXIO; - } - - irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); - if (!irq_res) { - dev_err(&pdev->dev, "AC97 IRQ not provided!\n"); - return -ENXIO; - } - - if (!request_mem_region(mem_res->start, - resource_size(mem_res), "s3c-ac97")) { - dev_err(&pdev->dev, "Unable to request register region\n"); - return -EBUSY; - } - - s3c_ac97_pcm_out.channel = dmatx_res->start; - s3c_ac97_pcm_out.dma_addr = mem_res->start + S3C_AC97_PCM_DATA; - s3c_ac97_pcm_in.channel = dmarx_res->start; - s3c_ac97_pcm_in.dma_addr = mem_res->start + S3C_AC97_PCM_DATA; - s3c_ac97_mic_in.channel = dmamic_res->start; - s3c_ac97_mic_in.dma_addr = mem_res->start + S3C_AC97_MIC_DATA; - - init_completion(&s3c_ac97.done); - mutex_init(&s3c_ac97.lock); - - s3c_ac97.regs = ioremap(mem_res->start, resource_size(mem_res)); - if (s3c_ac97.regs == NULL) { - dev_err(&pdev->dev, "Unable to ioremap register region\n"); - ret = -ENXIO; - goto err1; - } - - s3c_ac97.ac97_clk = clk_get(&pdev->dev, "ac97"); - if (IS_ERR(s3c_ac97.ac97_clk)) { - dev_err(&pdev->dev, "s3c-ac97 failed to get ac97_clock\n"); - ret = -ENODEV; - goto err2; - } - clk_enable(s3c_ac97.ac97_clk); - - if (ac97_pdata->cfg_gpio(pdev)) { - dev_err(&pdev->dev, "Unable to configure gpio\n"); - ret = -EINVAL; - goto err3; - } - - ret = request_irq(irq_res->start, s3c_ac97_irq, - IRQF_DISABLED, "AC97", NULL); - if (ret < 0) { - dev_err(&pdev->dev, "s3c-ac97: interrupt request failed.\n"); - goto err4; - } - - ret = snd_soc_register_dais(&pdev->dev, s3c_ac97_dai, - ARRAY_SIZE(s3c_ac97_dai)); - if (ret) - goto err5; - - return 0; - -err5: - free_irq(irq_res->start, NULL); -err4: -err3: - clk_disable(s3c_ac97.ac97_clk); - clk_put(s3c_ac97.ac97_clk); -err2: - iounmap(s3c_ac97.regs); -err1: - release_mem_region(mem_res->start, resource_size(mem_res)); - - return ret; -} - -static __devexit int s3c_ac97_remove(struct platform_device *pdev) -{ - struct resource *mem_res, *irq_res; - - snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(s3c_ac97_dai)); - - irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); - if (irq_res) - free_irq(irq_res->start, NULL); - - clk_disable(s3c_ac97.ac97_clk); - clk_put(s3c_ac97.ac97_clk); - - iounmap(s3c_ac97.regs); - - mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (mem_res) - release_mem_region(mem_res->start, resource_size(mem_res)); - - return 0; -} - -static struct platform_driver s3c_ac97_driver = { - .probe = s3c_ac97_probe, - .remove = s3c_ac97_remove, - .driver = { - .name = "samsung-ac97", - .owner = THIS_MODULE, - }, -}; - -static int __init s3c_ac97_init(void) -{ - return platform_driver_register(&s3c_ac97_driver); -} -module_init(s3c_ac97_init); - -static void __exit s3c_ac97_exit(void) -{ - platform_driver_unregister(&s3c_ac97_driver); -} -module_exit(s3c_ac97_exit); - -MODULE_AUTHOR("Jaswinder Singh, "); -MODULE_DESCRIPTION("AC97 driver for the Samsung SoC"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:samsung-ac97"); diff --git a/sound/soc/s3c24xx/s3c-ac97.h b/sound/soc/s3c24xx/s3c-ac97.h deleted file mode 100644 index 5dcedd07fdbb..000000000000 --- a/sound/soc/s3c24xx/s3c-ac97.h +++ /dev/null @@ -1,21 +0,0 @@ -/* sound/soc/s3c24xx/s3c-ac97.h - * - * ALSA SoC Audio Layer - S3C AC97 Controller driver - * Evolved from s3c2443-ac97.h - * - * Copyright (c) 2010 Samsung Electronics Co. Ltd - * Author: Jaswinder Singh - * Credits: Graeme Gregory, Sean Choi - * - * 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. - */ - -#ifndef __S3C_AC97_H_ -#define __S3C_AC97_H_ - -#define S3C_AC97_DAI_PCM 0 -#define S3C_AC97_DAI_MIC 1 - -#endif /* __S3C_AC97_H_ */ diff --git a/sound/soc/s3c24xx/smdk2443_wm9710.c b/sound/soc/s3c24xx/smdk2443_wm9710.c index e8787ad0a73e..3be7e7e92d6e 100644 --- a/sound/soc/s3c24xx/smdk2443_wm9710.c +++ b/sound/soc/s3c24xx/smdk2443_wm9710.c @@ -19,7 +19,7 @@ #include #include "dma.h" -#include "s3c-ac97.h" +#include "ac97.h" static struct snd_soc_card smdk2443; diff --git a/sound/soc/s3c24xx/smdk_wm9713.c b/sound/soc/s3c24xx/smdk_wm9713.c index 56b448d49609..7ce243086e7d 100644 --- a/sound/soc/s3c24xx/smdk_wm9713.c +++ b/sound/soc/s3c24xx/smdk_wm9713.c @@ -16,7 +16,7 @@ #include #include "dma.h" -#include "s3c-ac97.h" +#include "ac97.h" static struct snd_soc_card smdk; -- cgit v1.2.3 From 158a782843f9b0716c9fecf14a0563b07cf84da4 Mon Sep 17 00:00:00 2001 From: Jassi Brar Date: Mon, 22 Nov 2010 15:36:44 +0900 Subject: ASoC: Samsung: Rename PCM driver Rename Samsung PCM Controller driver s3c-pcm.[c/h] -> pcm.[c/h] Signed-off-by: Jassi Brar Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/s3c24xx/Makefile | 4 +- sound/soc/s3c24xx/pcm.c | 552 ++++++++++++++++++++++++++++++++++++++++++++ sound/soc/s3c24xx/pcm.h | 124 ++++++++++ sound/soc/s3c24xx/s3c-pcm.c | 552 -------------------------------------------- sound/soc/s3c24xx/s3c-pcm.h | 124 ---------- 5 files changed, 678 insertions(+), 678 deletions(-) create mode 100644 sound/soc/s3c24xx/pcm.c create mode 100644 sound/soc/s3c24xx/pcm.h delete mode 100644 sound/soc/s3c24xx/s3c-pcm.c delete mode 100644 sound/soc/s3c24xx/s3c-pcm.h diff --git a/sound/soc/s3c24xx/Makefile b/sound/soc/s3c24xx/Makefile index 551a63d65d73..93de2a00df1f 100644 --- a/sound/soc/s3c24xx/Makefile +++ b/sound/soc/s3c24xx/Makefile @@ -6,8 +6,8 @@ snd-soc-s3c64xx-i2s-objs := s3c64xx-i2s.o snd-soc-ac97-objs := ac97.o snd-soc-s3c64xx-i2s-v4-objs := s3c64xx-i2s-v4.o snd-soc-s3c-i2s-v2-objs := s3c-i2s-v2.o -snd-soc-s3c-pcm-objs := s3c-pcm.o snd-soc-samsung-spdif-objs := spdif.o +snd-soc-pcm-objs := pcm.o obj-$(CONFIG_SND_S3C24XX_SOC) += snd-soc-s3c24xx.o obj-$(CONFIG_SND_S3C24XX_SOC_I2S) += snd-soc-s3c24xx-i2s.o @@ -16,8 +16,8 @@ obj-$(CONFIG_SND_S3C2412_SOC_I2S) += snd-soc-s3c2412-i2s.o obj-$(CONFIG_SND_S3C64XX_SOC_I2S) += snd-soc-s3c64xx-i2s.o obj-$(CONFIG_SND_S3C64XX_SOC_I2S_V4) += snd-soc-s3c64xx-i2s-v4.o obj-$(CONFIG_SND_S3C_I2SV2_SOC) += snd-soc-s3c-i2s-v2.o -obj-$(CONFIG_SND_S3C_SOC_PCM) += snd-soc-s3c-pcm.o obj-$(CONFIG_SND_S5P_SOC_SPDIF) += snd-soc-samsung-spdif.o +obj-$(CONFIG_SND_S3C_SOC_PCM) += snd-soc-pcm.o # S3C24XX Machine Support snd-soc-jive-wm8750-objs := jive_wm8750.o diff --git a/sound/soc/s3c24xx/pcm.c b/sound/soc/s3c24xx/pcm.c new file mode 100644 index 000000000000..4d0f6e4f65bc --- /dev/null +++ b/sound/soc/s3c24xx/pcm.c @@ -0,0 +1,552 @@ +/* sound/soc/s3c24xx/pcm.c + * + * ALSA SoC Audio Layer - S3C PCM-Controller driver + * + * Copyright (c) 2009 Samsung Electronics Co. Ltd + * Author: Jaswinder Singh + * based upon I2S drivers by Ben Dooks. + * + * 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 +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include "dma.h" +#include "pcm.h" + +static struct s3c2410_dma_client s3c_pcm_dma_client_out = { + .name = "PCM Stereo out" +}; + +static struct s3c2410_dma_client s3c_pcm_dma_client_in = { + .name = "PCM Stereo in" +}; + +static struct s3c_dma_params s3c_pcm_stereo_out[] = { + [0] = { + .client = &s3c_pcm_dma_client_out, + .dma_size = 4, + }, + [1] = { + .client = &s3c_pcm_dma_client_out, + .dma_size = 4, + }, +}; + +static struct s3c_dma_params s3c_pcm_stereo_in[] = { + [0] = { + .client = &s3c_pcm_dma_client_in, + .dma_size = 4, + }, + [1] = { + .client = &s3c_pcm_dma_client_in, + .dma_size = 4, + }, +}; + +static struct s3c_pcm_info s3c_pcm[2]; + +static void s3c_pcm_snd_txctrl(struct s3c_pcm_info *pcm, int on) +{ + void __iomem *regs = pcm->regs; + u32 ctl, clkctl; + + clkctl = readl(regs + S3C_PCM_CLKCTL); + ctl = readl(regs + S3C_PCM_CTL); + ctl &= ~(S3C_PCM_CTL_TXDIPSTICK_MASK + << S3C_PCM_CTL_TXDIPSTICK_SHIFT); + + if (on) { + ctl |= S3C_PCM_CTL_TXDMA_EN; + ctl |= S3C_PCM_CTL_TXFIFO_EN; + ctl |= S3C_PCM_CTL_ENABLE; + ctl |= (0x4<idleclk) + clkctl |= S3C_PCM_CLKCTL_SERCLK_EN; + } + } + + writel(clkctl, regs + S3C_PCM_CLKCTL); + writel(ctl, regs + S3C_PCM_CTL); +} + +static void s3c_pcm_snd_rxctrl(struct s3c_pcm_info *pcm, int on) +{ + void __iomem *regs = pcm->regs; + u32 ctl, clkctl; + + ctl = readl(regs + S3C_PCM_CTL); + clkctl = readl(regs + S3C_PCM_CLKCTL); + ctl &= ~(S3C_PCM_CTL_RXDIPSTICK_MASK + << S3C_PCM_CTL_RXDIPSTICK_SHIFT); + + if (on) { + ctl |= S3C_PCM_CTL_RXDMA_EN; + ctl |= S3C_PCM_CTL_RXFIFO_EN; + ctl |= S3C_PCM_CTL_ENABLE; + ctl |= (0x20<idleclk) + clkctl |= S3C_PCM_CLKCTL_SERCLK_EN; + } + } + + writel(clkctl, regs + S3C_PCM_CLKCTL); + writel(ctl, regs + S3C_PCM_CTL); +} + +static int s3c_pcm_trigger(struct snd_pcm_substream *substream, int cmd, + struct snd_soc_dai *dai) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct s3c_pcm_info *pcm = snd_soc_dai_get_drvdata(rtd->cpu_dai); + unsigned long flags; + + dev_dbg(pcm->dev, "Entered %s\n", __func__); + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + case SNDRV_PCM_TRIGGER_RESUME: + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: + spin_lock_irqsave(&pcm->lock, flags); + + if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) + s3c_pcm_snd_rxctrl(pcm, 1); + else + s3c_pcm_snd_txctrl(pcm, 1); + + spin_unlock_irqrestore(&pcm->lock, flags); + break; + + case SNDRV_PCM_TRIGGER_STOP: + case SNDRV_PCM_TRIGGER_SUSPEND: + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + spin_lock_irqsave(&pcm->lock, flags); + + if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) + s3c_pcm_snd_rxctrl(pcm, 0); + else + s3c_pcm_snd_txctrl(pcm, 0); + + spin_unlock_irqrestore(&pcm->lock, flags); + break; + + default: + return -EINVAL; + } + + return 0; +} + +static int s3c_pcm_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *socdai) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct s3c_pcm_info *pcm = snd_soc_dai_get_drvdata(rtd->cpu_dai); + struct s3c_dma_params *dma_data; + void __iomem *regs = pcm->regs; + struct clk *clk; + int sclk_div, sync_div; + unsigned long flags; + u32 clkctl; + + dev_dbg(pcm->dev, "Entered %s\n", __func__); + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + dma_data = pcm->dma_playback; + else + dma_data = pcm->dma_capture; + + snd_soc_dai_set_dma_data(rtd->cpu_dai, substream, dma_data); + + /* Strictly check for sample size */ + switch (params_format(params)) { + case SNDRV_PCM_FORMAT_S16_LE: + break; + default: + return -EINVAL; + } + + spin_lock_irqsave(&pcm->lock, flags); + + /* Get hold of the PCMSOURCE_CLK */ + clkctl = readl(regs + S3C_PCM_CLKCTL); + if (clkctl & S3C_PCM_CLKCTL_SERCLKSEL_PCLK) + clk = pcm->pclk; + else + clk = pcm->cclk; + + /* Set the SCLK divider */ + sclk_div = clk_get_rate(clk) / pcm->sclk_per_fs / + params_rate(params) / 2 - 1; + + clkctl &= ~(S3C_PCM_CLKCTL_SCLKDIV_MASK + << S3C_PCM_CLKCTL_SCLKDIV_SHIFT); + clkctl |= ((sclk_div & S3C_PCM_CLKCTL_SCLKDIV_MASK) + << S3C_PCM_CLKCTL_SCLKDIV_SHIFT); + + /* Set the SYNC divider */ + sync_div = pcm->sclk_per_fs - 1; + + clkctl &= ~(S3C_PCM_CLKCTL_SYNCDIV_MASK + << S3C_PCM_CLKCTL_SYNCDIV_SHIFT); + clkctl |= ((sync_div & S3C_PCM_CLKCTL_SYNCDIV_MASK) + << S3C_PCM_CLKCTL_SYNCDIV_SHIFT); + + writel(clkctl, regs + S3C_PCM_CLKCTL); + + spin_unlock_irqrestore(&pcm->lock, flags); + + dev_dbg(pcm->dev, "PCMSOURCE_CLK-%lu SCLK=%ufs SCLK_DIV=%d SYNC_DIV=%d\n", + clk_get_rate(clk), pcm->sclk_per_fs, + sclk_div, sync_div); + + return 0; +} + +static int s3c_pcm_set_fmt(struct snd_soc_dai *cpu_dai, + unsigned int fmt) +{ + struct s3c_pcm_info *pcm = snd_soc_dai_get_drvdata(cpu_dai); + void __iomem *regs = pcm->regs; + unsigned long flags; + int ret = 0; + u32 ctl; + + dev_dbg(pcm->dev, "Entered %s\n", __func__); + + spin_lock_irqsave(&pcm->lock, flags); + + ctl = readl(regs + S3C_PCM_CTL); + + switch (fmt & SND_SOC_DAIFMT_INV_MASK) { + case SND_SOC_DAIFMT_NB_NF: + /* Nothing to do, NB_NF by default */ + break; + default: + dev_err(pcm->dev, "Unsupported clock inversion!\n"); + ret = -EINVAL; + goto exit; + } + + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { + case SND_SOC_DAIFMT_CBS_CFS: + /* Nothing to do, Master by default */ + break; + default: + dev_err(pcm->dev, "Unsupported master/slave format!\n"); + ret = -EINVAL; + goto exit; + } + + switch (fmt & SND_SOC_DAIFMT_CLOCK_MASK) { + case SND_SOC_DAIFMT_CONT: + pcm->idleclk = 1; + break; + case SND_SOC_DAIFMT_GATED: + pcm->idleclk = 0; + break; + default: + dev_err(pcm->dev, "Invalid Clock gating request!\n"); + ret = -EINVAL; + goto exit; + } + + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { + case SND_SOC_DAIFMT_DSP_A: + ctl |= S3C_PCM_CTL_TXMSB_AFTER_FSYNC; + ctl |= S3C_PCM_CTL_RXMSB_AFTER_FSYNC; + break; + case SND_SOC_DAIFMT_DSP_B: + ctl &= ~S3C_PCM_CTL_TXMSB_AFTER_FSYNC; + ctl &= ~S3C_PCM_CTL_RXMSB_AFTER_FSYNC; + break; + default: + dev_err(pcm->dev, "Unsupported data format!\n"); + ret = -EINVAL; + goto exit; + } + + writel(ctl, regs + S3C_PCM_CTL); + +exit: + spin_unlock_irqrestore(&pcm->lock, flags); + + return ret; +} + +static int s3c_pcm_set_clkdiv(struct snd_soc_dai *cpu_dai, + int div_id, int div) +{ + struct s3c_pcm_info *pcm = snd_soc_dai_get_drvdata(cpu_dai); + + switch (div_id) { + case S3C_PCM_SCLK_PER_FS: + pcm->sclk_per_fs = div; + break; + + default: + return -EINVAL; + } + + return 0; +} + +static int s3c_pcm_set_sysclk(struct snd_soc_dai *cpu_dai, + int clk_id, unsigned int freq, int dir) +{ + struct s3c_pcm_info *pcm = snd_soc_dai_get_drvdata(cpu_dai); + void __iomem *regs = pcm->regs; + u32 clkctl = readl(regs + S3C_PCM_CLKCTL); + + switch (clk_id) { + case S3C_PCM_CLKSRC_PCLK: + clkctl |= S3C_PCM_CLKCTL_SERCLKSEL_PCLK; + break; + + case S3C_PCM_CLKSRC_MUX: + clkctl &= ~S3C_PCM_CLKCTL_SERCLKSEL_PCLK; + + if (clk_get_rate(pcm->cclk) != freq) + clk_set_rate(pcm->cclk, freq); + + break; + + default: + return -EINVAL; + } + + writel(clkctl, regs + S3C_PCM_CLKCTL); + + return 0; +} + +static struct snd_soc_dai_ops s3c_pcm_dai_ops = { + .set_sysclk = s3c_pcm_set_sysclk, + .set_clkdiv = s3c_pcm_set_clkdiv, + .trigger = s3c_pcm_trigger, + .hw_params = s3c_pcm_hw_params, + .set_fmt = s3c_pcm_set_fmt, +}; + +#define S3C_PCM_RATES SNDRV_PCM_RATE_8000_96000 + +#define S3C_PCM_DAI_DECLARE \ + .symmetric_rates = 1, \ + .ops = &s3c_pcm_dai_ops, \ + .playback = { \ + .channels_min = 2, \ + .channels_max = 2, \ + .rates = S3C_PCM_RATES, \ + .formats = SNDRV_PCM_FMTBIT_S16_LE, \ + }, \ + .capture = { \ + .channels_min = 2, \ + .channels_max = 2, \ + .rates = S3C_PCM_RATES, \ + .formats = SNDRV_PCM_FMTBIT_S16_LE, \ + } + +struct snd_soc_dai_driver s3c_pcm_dai[] = { + [0] = { + .name = "samsung-pcm.0", + S3C_PCM_DAI_DECLARE, + }, + [1] = { + .name = "samsung-pcm.1", + S3C_PCM_DAI_DECLARE, + }, +}; +EXPORT_SYMBOL_GPL(s3c_pcm_dai); + +static __devinit int s3c_pcm_dev_probe(struct platform_device *pdev) +{ + struct s3c_pcm_info *pcm; + struct resource *mem_res, *dmatx_res, *dmarx_res; + struct s3c_audio_pdata *pcm_pdata; + int ret; + + /* Check for valid device index */ + if ((pdev->id < 0) || pdev->id >= ARRAY_SIZE(s3c_pcm)) { + dev_err(&pdev->dev, "id %d out of range\n", pdev->id); + return -EINVAL; + } + + pcm_pdata = pdev->dev.platform_data; + + /* Check for availability of necessary resource */ + dmatx_res = platform_get_resource(pdev, IORESOURCE_DMA, 0); + if (!dmatx_res) { + dev_err(&pdev->dev, "Unable to get PCM-TX dma resource\n"); + return -ENXIO; + } + + dmarx_res = platform_get_resource(pdev, IORESOURCE_DMA, 1); + if (!dmarx_res) { + dev_err(&pdev->dev, "Unable to get PCM-RX dma resource\n"); + return -ENXIO; + } + + mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!mem_res) { + dev_err(&pdev->dev, "Unable to get register resource\n"); + return -ENXIO; + } + + if (pcm_pdata && pcm_pdata->cfg_gpio && pcm_pdata->cfg_gpio(pdev)) { + dev_err(&pdev->dev, "Unable to configure gpio\n"); + return -EINVAL; + } + + pcm = &s3c_pcm[pdev->id]; + pcm->dev = &pdev->dev; + + spin_lock_init(&pcm->lock); + + /* Default is 128fs */ + pcm->sclk_per_fs = 128; + + pcm->cclk = clk_get(&pdev->dev, "audio-bus"); + if (IS_ERR(pcm->cclk)) { + dev_err(&pdev->dev, "failed to get audio-bus\n"); + ret = PTR_ERR(pcm->cclk); + goto err1; + } + clk_enable(pcm->cclk); + + /* record our pcm structure for later use in the callbacks */ + dev_set_drvdata(&pdev->dev, pcm); + + if (!request_mem_region(mem_res->start, + resource_size(mem_res), "samsung-pcm")) { + dev_err(&pdev->dev, "Unable to request register region\n"); + ret = -EBUSY; + goto err2; + } + + pcm->regs = ioremap(mem_res->start, 0x100); + if (pcm->regs == NULL) { + dev_err(&pdev->dev, "cannot ioremap registers\n"); + ret = -ENXIO; + goto err3; + } + + pcm->pclk = clk_get(&pdev->dev, "pcm"); + if (IS_ERR(pcm->pclk)) { + dev_err(&pdev->dev, "failed to get pcm_clock\n"); + ret = -ENOENT; + goto err4; + } + clk_enable(pcm->pclk); + + ret = snd_soc_register_dai(&pdev->dev, &s3c_pcm_dai[pdev->id]); + if (ret != 0) { + dev_err(&pdev->dev, "failed to get pcm_clock\n"); + goto err5; + } + + s3c_pcm_stereo_in[pdev->id].dma_addr = mem_res->start + + S3C_PCM_RXFIFO; + s3c_pcm_stereo_out[pdev->id].dma_addr = mem_res->start + + S3C_PCM_TXFIFO; + + s3c_pcm_stereo_in[pdev->id].channel = dmarx_res->start; + s3c_pcm_stereo_out[pdev->id].channel = dmatx_res->start; + + pcm->dma_capture = &s3c_pcm_stereo_in[pdev->id]; + pcm->dma_playback = &s3c_pcm_stereo_out[pdev->id]; + + return 0; + +err5: + clk_disable(pcm->pclk); + clk_put(pcm->pclk); +err4: + iounmap(pcm->regs); +err3: + release_mem_region(mem_res->start, resource_size(mem_res)); +err2: + clk_disable(pcm->cclk); + clk_put(pcm->cclk); +err1: + return ret; +} + +static __devexit int s3c_pcm_dev_remove(struct platform_device *pdev) +{ + struct s3c_pcm_info *pcm = &s3c_pcm[pdev->id]; + struct resource *mem_res; + + snd_soc_unregister_dai(&pdev->dev); + + iounmap(pcm->regs); + + mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + release_mem_region(mem_res->start, resource_size(mem_res)); + + clk_disable(pcm->cclk); + clk_disable(pcm->pclk); + clk_put(pcm->pclk); + clk_put(pcm->cclk); + + return 0; +} + +static struct platform_driver s3c_pcm_driver = { + .probe = s3c_pcm_dev_probe, + .remove = s3c_pcm_dev_remove, + .driver = { + .name = "samsung-pcm", + .owner = THIS_MODULE, + }, +}; + +static int __init s3c_pcm_init(void) +{ + return platform_driver_register(&s3c_pcm_driver); +} +module_init(s3c_pcm_init); + +static void __exit s3c_pcm_exit(void) +{ + platform_driver_unregister(&s3c_pcm_driver); +} +module_exit(s3c_pcm_exit); + +/* Module information */ +MODULE_AUTHOR("Jaswinder Singh, "); +MODULE_DESCRIPTION("S3C PCM Controller Driver"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:samsung-pcm"); diff --git a/sound/soc/s3c24xx/pcm.h b/sound/soc/s3c24xx/pcm.h new file mode 100644 index 000000000000..3775216ffda8 --- /dev/null +++ b/sound/soc/s3c24xx/pcm.h @@ -0,0 +1,124 @@ +/* sound/soc/s3c24xx/pcm.h + * + * 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. + * + */ + +#ifndef __S3C_PCM_H +#define __S3C_PCM_H __FILE__ + +/*Register Offsets */ +#define S3C_PCM_CTL (0x00) +#define S3C_PCM_CLKCTL (0x04) +#define S3C_PCM_TXFIFO (0x08) +#define S3C_PCM_RXFIFO (0x0C) +#define S3C_PCM_IRQCTL (0x10) +#define S3C_PCM_IRQSTAT (0x14) +#define S3C_PCM_FIFOSTAT (0x18) +#define S3C_PCM_CLRINT (0x20) + +/* PCM_CTL Bit-Fields */ +#define S3C_PCM_CTL_TXDIPSTICK_MASK (0x3f) +#define S3C_PCM_CTL_TXDIPSTICK_SHIFT (13) +#define S3C_PCM_CTL_RXDIPSTICK_MASK (0x3f) +#define S3C_PCM_CTL_RXDIPSTICK_SHIFT (7) +#define S3C_PCM_CTL_TXDMA_EN (0x1<<6) +#define S3C_PCM_CTL_RXDMA_EN (0x1<<5) +#define S3C_PCM_CTL_TXMSB_AFTER_FSYNC (0x1<<4) +#define S3C_PCM_CTL_RXMSB_AFTER_FSYNC (0x1<<3) +#define S3C_PCM_CTL_TXFIFO_EN (0x1<<2) +#define S3C_PCM_CTL_RXFIFO_EN (0x1<<1) +#define S3C_PCM_CTL_ENABLE (0x1<<0) + +/* PCM_CLKCTL Bit-Fields */ +#define S3C_PCM_CLKCTL_SERCLK_EN (0x1<<19) +#define S3C_PCM_CLKCTL_SERCLKSEL_PCLK (0x1<<18) +#define S3C_PCM_CLKCTL_SCLKDIV_MASK (0x1ff) +#define S3C_PCM_CLKCTL_SYNCDIV_MASK (0x1ff) +#define S3C_PCM_CLKCTL_SCLKDIV_SHIFT (9) +#define S3C_PCM_CLKCTL_SYNCDIV_SHIFT (0) + +/* PCM_TXFIFO Bit-Fields */ +#define S3C_PCM_TXFIFO_DVALID (0x1<<16) +#define S3C_PCM_TXFIFO_DATA_MSK (0xffff<<0) + +/* PCM_RXFIFO Bit-Fields */ +#define S3C_PCM_RXFIFO_DVALID (0x1<<16) +#define S3C_PCM_RXFIFO_DATA_MSK (0xffff<<0) + +/* PCM_IRQCTL Bit-Fields */ +#define S3C_PCM_IRQCTL_IRQEN (0x1<<14) +#define S3C_PCM_IRQCTL_WRDEN (0x1<<12) +#define S3C_PCM_IRQCTL_TXEMPTYEN (0x1<<11) +#define S3C_PCM_IRQCTL_TXALMSTEMPTYEN (0x1<<10) +#define S3C_PCM_IRQCTL_TXFULLEN (0x1<<9) +#define S3C_PCM_IRQCTL_TXALMSTFULLEN (0x1<<8) +#define S3C_PCM_IRQCTL_TXSTARVEN (0x1<<7) +#define S3C_PCM_IRQCTL_TXERROVRFLEN (0x1<<6) +#define S3C_PCM_IRQCTL_RXEMPTEN (0x1<<5) +#define S3C_PCM_IRQCTL_RXALMSTEMPTEN (0x1<<4) +#define S3C_PCM_IRQCTL_RXFULLEN (0x1<<3) +#define S3C_PCM_IRQCTL_RXALMSTFULLEN (0x1<<2) +#define S3C_PCM_IRQCTL_RXSTARVEN (0x1<<1) +#define S3C_PCM_IRQCTL_RXERROVRFLEN (0x1<<0) + +/* PCM_IRQSTAT Bit-Fields */ +#define S3C_PCM_IRQSTAT_IRQPND (0x1<<13) +#define S3C_PCM_IRQSTAT_WRD_XFER (0x1<<12) +#define S3C_PCM_IRQSTAT_TXEMPTY (0x1<<11) +#define S3C_PCM_IRQSTAT_TXALMSTEMPTY (0x1<<10) +#define S3C_PCM_IRQSTAT_TXFULL (0x1<<9) +#define S3C_PCM_IRQSTAT_TXALMSTFULL (0x1<<8) +#define S3C_PCM_IRQSTAT_TXSTARV (0x1<<7) +#define S3C_PCM_IRQSTAT_TXERROVRFL (0x1<<6) +#define S3C_PCM_IRQSTAT_RXEMPT (0x1<<5) +#define S3C_PCM_IRQSTAT_RXALMSTEMPT (0x1<<4) +#define S3C_PCM_IRQSTAT_RXFULL (0x1<<3) +#define S3C_PCM_IRQSTAT_RXALMSTFULL (0x1<<2) +#define S3C_PCM_IRQSTAT_RXSTARV (0x1<<1) +#define S3C_PCM_IRQSTAT_RXERROVRFL (0x1<<0) + +/* PCM_FIFOSTAT Bit-Fields */ +#define S3C_PCM_FIFOSTAT_TXCNT_MSK (0x3f<<14) +#define S3C_PCM_FIFOSTAT_TXFIFOEMPTY (0x1<<13) +#define S3C_PCM_FIFOSTAT_TXFIFOALMSTEMPTY (0x1<<12) +#define S3C_PCM_FIFOSTAT_TXFIFOFULL (0x1<<11) +#define S3C_PCM_FIFOSTAT_TXFIFOALMSTFULL (0x1<<10) +#define S3C_PCM_FIFOSTAT_RXCNT_MSK (0x3f<<4) +#define S3C_PCM_FIFOSTAT_RXFIFOEMPTY (0x1<<3) +#define S3C_PCM_FIFOSTAT_RXFIFOALMSTEMPTY (0x1<<2) +#define S3C_PCM_FIFOSTAT_RXFIFOFULL (0x1<<1) +#define S3C_PCM_FIFOSTAT_RXFIFOALMSTFULL (0x1<<0) + +#define S3C_PCM_CLKSRC_PCLK 0 +#define S3C_PCM_CLKSRC_MUX 1 + +#define S3C_PCM_SCLK_PER_FS 0 + +/** + * struct s3c_pcm_info - S3C PCM Controller information + * @dev: The parent device passed to use from the probe. + * @regs: The pointer to the device register block. + * @dma_playback: DMA information for playback channel. + * @dma_capture: DMA information for capture channel. + */ +struct s3c_pcm_info { + spinlock_t lock; + struct device *dev; + void __iomem *regs; + + unsigned int sclk_per_fs; + + /* Whether to keep PCMSCLK enabled even when idle(no active xfer) */ + unsigned int idleclk; + + struct clk *pclk; + struct clk *cclk; + + struct s3c_dma_params *dma_playback; + struct s3c_dma_params *dma_capture; +}; + +#endif /* __S3C_PCM_H */ diff --git a/sound/soc/s3c24xx/s3c-pcm.c b/sound/soc/s3c24xx/s3c-pcm.c deleted file mode 100644 index e111d23f8886..000000000000 --- a/sound/soc/s3c24xx/s3c-pcm.c +++ /dev/null @@ -1,552 +0,0 @@ -/* sound/soc/s3c24xx/s3c-pcm.c - * - * ALSA SoC Audio Layer - S3C PCM-Controller driver - * - * Copyright (c) 2009 Samsung Electronics Co. Ltd - * Author: Jaswinder Singh - * based upon I2S drivers by Ben Dooks. - * - * 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 -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include -#include - -#include "dma.h" -#include "s3c-pcm.h" - -static struct s3c2410_dma_client s3c_pcm_dma_client_out = { - .name = "PCM Stereo out" -}; - -static struct s3c2410_dma_client s3c_pcm_dma_client_in = { - .name = "PCM Stereo in" -}; - -static struct s3c_dma_params s3c_pcm_stereo_out[] = { - [0] = { - .client = &s3c_pcm_dma_client_out, - .dma_size = 4, - }, - [1] = { - .client = &s3c_pcm_dma_client_out, - .dma_size = 4, - }, -}; - -static struct s3c_dma_params s3c_pcm_stereo_in[] = { - [0] = { - .client = &s3c_pcm_dma_client_in, - .dma_size = 4, - }, - [1] = { - .client = &s3c_pcm_dma_client_in, - .dma_size = 4, - }, -}; - -static struct s3c_pcm_info s3c_pcm[2]; - -static void s3c_pcm_snd_txctrl(struct s3c_pcm_info *pcm, int on) -{ - void __iomem *regs = pcm->regs; - u32 ctl, clkctl; - - clkctl = readl(regs + S3C_PCM_CLKCTL); - ctl = readl(regs + S3C_PCM_CTL); - ctl &= ~(S3C_PCM_CTL_TXDIPSTICK_MASK - << S3C_PCM_CTL_TXDIPSTICK_SHIFT); - - if (on) { - ctl |= S3C_PCM_CTL_TXDMA_EN; - ctl |= S3C_PCM_CTL_TXFIFO_EN; - ctl |= S3C_PCM_CTL_ENABLE; - ctl |= (0x4<idleclk) - clkctl |= S3C_PCM_CLKCTL_SERCLK_EN; - } - } - - writel(clkctl, regs + S3C_PCM_CLKCTL); - writel(ctl, regs + S3C_PCM_CTL); -} - -static void s3c_pcm_snd_rxctrl(struct s3c_pcm_info *pcm, int on) -{ - void __iomem *regs = pcm->regs; - u32 ctl, clkctl; - - ctl = readl(regs + S3C_PCM_CTL); - clkctl = readl(regs + S3C_PCM_CLKCTL); - ctl &= ~(S3C_PCM_CTL_RXDIPSTICK_MASK - << S3C_PCM_CTL_RXDIPSTICK_SHIFT); - - if (on) { - ctl |= S3C_PCM_CTL_RXDMA_EN; - ctl |= S3C_PCM_CTL_RXFIFO_EN; - ctl |= S3C_PCM_CTL_ENABLE; - ctl |= (0x20<idleclk) - clkctl |= S3C_PCM_CLKCTL_SERCLK_EN; - } - } - - writel(clkctl, regs + S3C_PCM_CLKCTL); - writel(ctl, regs + S3C_PCM_CTL); -} - -static int s3c_pcm_trigger(struct snd_pcm_substream *substream, int cmd, - struct snd_soc_dai *dai) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct s3c_pcm_info *pcm = snd_soc_dai_get_drvdata(rtd->cpu_dai); - unsigned long flags; - - dev_dbg(pcm->dev, "Entered %s\n", __func__); - - switch (cmd) { - case SNDRV_PCM_TRIGGER_START: - case SNDRV_PCM_TRIGGER_RESUME: - case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - spin_lock_irqsave(&pcm->lock, flags); - - if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) - s3c_pcm_snd_rxctrl(pcm, 1); - else - s3c_pcm_snd_txctrl(pcm, 1); - - spin_unlock_irqrestore(&pcm->lock, flags); - break; - - case SNDRV_PCM_TRIGGER_STOP: - case SNDRV_PCM_TRIGGER_SUSPEND: - case SNDRV_PCM_TRIGGER_PAUSE_PUSH: - spin_lock_irqsave(&pcm->lock, flags); - - if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) - s3c_pcm_snd_rxctrl(pcm, 0); - else - s3c_pcm_snd_txctrl(pcm, 0); - - spin_unlock_irqrestore(&pcm->lock, flags); - break; - - default: - return -EINVAL; - } - - return 0; -} - -static int s3c_pcm_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params, - struct snd_soc_dai *socdai) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct s3c_pcm_info *pcm = snd_soc_dai_get_drvdata(rtd->cpu_dai); - struct s3c_dma_params *dma_data; - void __iomem *regs = pcm->regs; - struct clk *clk; - int sclk_div, sync_div; - unsigned long flags; - u32 clkctl; - - dev_dbg(pcm->dev, "Entered %s\n", __func__); - - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - dma_data = pcm->dma_playback; - else - dma_data = pcm->dma_capture; - - snd_soc_dai_set_dma_data(rtd->cpu_dai, substream, dma_data); - - /* Strictly check for sample size */ - switch (params_format(params)) { - case SNDRV_PCM_FORMAT_S16_LE: - break; - default: - return -EINVAL; - } - - spin_lock_irqsave(&pcm->lock, flags); - - /* Get hold of the PCMSOURCE_CLK */ - clkctl = readl(regs + S3C_PCM_CLKCTL); - if (clkctl & S3C_PCM_CLKCTL_SERCLKSEL_PCLK) - clk = pcm->pclk; - else - clk = pcm->cclk; - - /* Set the SCLK divider */ - sclk_div = clk_get_rate(clk) / pcm->sclk_per_fs / - params_rate(params) / 2 - 1; - - clkctl &= ~(S3C_PCM_CLKCTL_SCLKDIV_MASK - << S3C_PCM_CLKCTL_SCLKDIV_SHIFT); - clkctl |= ((sclk_div & S3C_PCM_CLKCTL_SCLKDIV_MASK) - << S3C_PCM_CLKCTL_SCLKDIV_SHIFT); - - /* Set the SYNC divider */ - sync_div = pcm->sclk_per_fs - 1; - - clkctl &= ~(S3C_PCM_CLKCTL_SYNCDIV_MASK - << S3C_PCM_CLKCTL_SYNCDIV_SHIFT); - clkctl |= ((sync_div & S3C_PCM_CLKCTL_SYNCDIV_MASK) - << S3C_PCM_CLKCTL_SYNCDIV_SHIFT); - - writel(clkctl, regs + S3C_PCM_CLKCTL); - - spin_unlock_irqrestore(&pcm->lock, flags); - - dev_dbg(pcm->dev, "PCMSOURCE_CLK-%lu SCLK=%ufs SCLK_DIV=%d SYNC_DIV=%d\n", - clk_get_rate(clk), pcm->sclk_per_fs, - sclk_div, sync_div); - - return 0; -} - -static int s3c_pcm_set_fmt(struct snd_soc_dai *cpu_dai, - unsigned int fmt) -{ - struct s3c_pcm_info *pcm = snd_soc_dai_get_drvdata(cpu_dai); - void __iomem *regs = pcm->regs; - unsigned long flags; - int ret = 0; - u32 ctl; - - dev_dbg(pcm->dev, "Entered %s\n", __func__); - - spin_lock_irqsave(&pcm->lock, flags); - - ctl = readl(regs + S3C_PCM_CTL); - - switch (fmt & SND_SOC_DAIFMT_INV_MASK) { - case SND_SOC_DAIFMT_NB_NF: - /* Nothing to do, NB_NF by default */ - break; - default: - dev_err(pcm->dev, "Unsupported clock inversion!\n"); - ret = -EINVAL; - goto exit; - } - - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBS_CFS: - /* Nothing to do, Master by default */ - break; - default: - dev_err(pcm->dev, "Unsupported master/slave format!\n"); - ret = -EINVAL; - goto exit; - } - - switch (fmt & SND_SOC_DAIFMT_CLOCK_MASK) { - case SND_SOC_DAIFMT_CONT: - pcm->idleclk = 1; - break; - case SND_SOC_DAIFMT_GATED: - pcm->idleclk = 0; - break; - default: - dev_err(pcm->dev, "Invalid Clock gating request!\n"); - ret = -EINVAL; - goto exit; - } - - switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { - case SND_SOC_DAIFMT_DSP_A: - ctl |= S3C_PCM_CTL_TXMSB_AFTER_FSYNC; - ctl |= S3C_PCM_CTL_RXMSB_AFTER_FSYNC; - break; - case SND_SOC_DAIFMT_DSP_B: - ctl &= ~S3C_PCM_CTL_TXMSB_AFTER_FSYNC; - ctl &= ~S3C_PCM_CTL_RXMSB_AFTER_FSYNC; - break; - default: - dev_err(pcm->dev, "Unsupported data format!\n"); - ret = -EINVAL; - goto exit; - } - - writel(ctl, regs + S3C_PCM_CTL); - -exit: - spin_unlock_irqrestore(&pcm->lock, flags); - - return ret; -} - -static int s3c_pcm_set_clkdiv(struct snd_soc_dai *cpu_dai, - int div_id, int div) -{ - struct s3c_pcm_info *pcm = snd_soc_dai_get_drvdata(cpu_dai); - - switch (div_id) { - case S3C_PCM_SCLK_PER_FS: - pcm->sclk_per_fs = div; - break; - - default: - return -EINVAL; - } - - return 0; -} - -static int s3c_pcm_set_sysclk(struct snd_soc_dai *cpu_dai, - int clk_id, unsigned int freq, int dir) -{ - struct s3c_pcm_info *pcm = snd_soc_dai_get_drvdata(cpu_dai); - void __iomem *regs = pcm->regs; - u32 clkctl = readl(regs + S3C_PCM_CLKCTL); - - switch (clk_id) { - case S3C_PCM_CLKSRC_PCLK: - clkctl |= S3C_PCM_CLKCTL_SERCLKSEL_PCLK; - break; - - case S3C_PCM_CLKSRC_MUX: - clkctl &= ~S3C_PCM_CLKCTL_SERCLKSEL_PCLK; - - if (clk_get_rate(pcm->cclk) != freq) - clk_set_rate(pcm->cclk, freq); - - break; - - default: - return -EINVAL; - } - - writel(clkctl, regs + S3C_PCM_CLKCTL); - - return 0; -} - -static struct snd_soc_dai_ops s3c_pcm_dai_ops = { - .set_sysclk = s3c_pcm_set_sysclk, - .set_clkdiv = s3c_pcm_set_clkdiv, - .trigger = s3c_pcm_trigger, - .hw_params = s3c_pcm_hw_params, - .set_fmt = s3c_pcm_set_fmt, -}; - -#define S3C_PCM_RATES SNDRV_PCM_RATE_8000_96000 - -#define S3C_PCM_DAI_DECLARE \ - .symmetric_rates = 1, \ - .ops = &s3c_pcm_dai_ops, \ - .playback = { \ - .channels_min = 2, \ - .channels_max = 2, \ - .rates = S3C_PCM_RATES, \ - .formats = SNDRV_PCM_FMTBIT_S16_LE, \ - }, \ - .capture = { \ - .channels_min = 2, \ - .channels_max = 2, \ - .rates = S3C_PCM_RATES, \ - .formats = SNDRV_PCM_FMTBIT_S16_LE, \ - } - -struct snd_soc_dai_driver s3c_pcm_dai[] = { - [0] = { - .name = "samsung-pcm.0", - S3C_PCM_DAI_DECLARE, - }, - [1] = { - .name = "samsung-pcm.1", - S3C_PCM_DAI_DECLARE, - }, -}; -EXPORT_SYMBOL_GPL(s3c_pcm_dai); - -static __devinit int s3c_pcm_dev_probe(struct platform_device *pdev) -{ - struct s3c_pcm_info *pcm; - struct resource *mem_res, *dmatx_res, *dmarx_res; - struct s3c_audio_pdata *pcm_pdata; - int ret; - - /* Check for valid device index */ - if ((pdev->id < 0) || pdev->id >= ARRAY_SIZE(s3c_pcm)) { - dev_err(&pdev->dev, "id %d out of range\n", pdev->id); - return -EINVAL; - } - - pcm_pdata = pdev->dev.platform_data; - - /* Check for availability of necessary resource */ - dmatx_res = platform_get_resource(pdev, IORESOURCE_DMA, 0); - if (!dmatx_res) { - dev_err(&pdev->dev, "Unable to get PCM-TX dma resource\n"); - return -ENXIO; - } - - dmarx_res = platform_get_resource(pdev, IORESOURCE_DMA, 1); - if (!dmarx_res) { - dev_err(&pdev->dev, "Unable to get PCM-RX dma resource\n"); - return -ENXIO; - } - - mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!mem_res) { - dev_err(&pdev->dev, "Unable to get register resource\n"); - return -ENXIO; - } - - if (pcm_pdata && pcm_pdata->cfg_gpio && pcm_pdata->cfg_gpio(pdev)) { - dev_err(&pdev->dev, "Unable to configure gpio\n"); - return -EINVAL; - } - - pcm = &s3c_pcm[pdev->id]; - pcm->dev = &pdev->dev; - - spin_lock_init(&pcm->lock); - - /* Default is 128fs */ - pcm->sclk_per_fs = 128; - - pcm->cclk = clk_get(&pdev->dev, "audio-bus"); - if (IS_ERR(pcm->cclk)) { - dev_err(&pdev->dev, "failed to get audio-bus\n"); - ret = PTR_ERR(pcm->cclk); - goto err1; - } - clk_enable(pcm->cclk); - - /* record our pcm structure for later use in the callbacks */ - dev_set_drvdata(&pdev->dev, pcm); - - if (!request_mem_region(mem_res->start, - resource_size(mem_res), "samsung-pcm")) { - dev_err(&pdev->dev, "Unable to request register region\n"); - ret = -EBUSY; - goto err2; - } - - pcm->regs = ioremap(mem_res->start, 0x100); - if (pcm->regs == NULL) { - dev_err(&pdev->dev, "cannot ioremap registers\n"); - ret = -ENXIO; - goto err3; - } - - pcm->pclk = clk_get(&pdev->dev, "pcm"); - if (IS_ERR(pcm->pclk)) { - dev_err(&pdev->dev, "failed to get pcm_clock\n"); - ret = -ENOENT; - goto err4; - } - clk_enable(pcm->pclk); - - ret = snd_soc_register_dai(&pdev->dev, &s3c_pcm_dai[pdev->id]); - if (ret != 0) { - dev_err(&pdev->dev, "failed to get pcm_clock\n"); - goto err5; - } - - s3c_pcm_stereo_in[pdev->id].dma_addr = mem_res->start - + S3C_PCM_RXFIFO; - s3c_pcm_stereo_out[pdev->id].dma_addr = mem_res->start - + S3C_PCM_TXFIFO; - - s3c_pcm_stereo_in[pdev->id].channel = dmarx_res->start; - s3c_pcm_stereo_out[pdev->id].channel = dmatx_res->start; - - pcm->dma_capture = &s3c_pcm_stereo_in[pdev->id]; - pcm->dma_playback = &s3c_pcm_stereo_out[pdev->id]; - - return 0; - -err5: - clk_disable(pcm->pclk); - clk_put(pcm->pclk); -err4: - iounmap(pcm->regs); -err3: - release_mem_region(mem_res->start, resource_size(mem_res)); -err2: - clk_disable(pcm->cclk); - clk_put(pcm->cclk); -err1: - return ret; -} - -static __devexit int s3c_pcm_dev_remove(struct platform_device *pdev) -{ - struct s3c_pcm_info *pcm = &s3c_pcm[pdev->id]; - struct resource *mem_res; - - snd_soc_unregister_dai(&pdev->dev); - - iounmap(pcm->regs); - - mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - release_mem_region(mem_res->start, resource_size(mem_res)); - - clk_disable(pcm->cclk); - clk_disable(pcm->pclk); - clk_put(pcm->pclk); - clk_put(pcm->cclk); - - return 0; -} - -static struct platform_driver s3c_pcm_driver = { - .probe = s3c_pcm_dev_probe, - .remove = s3c_pcm_dev_remove, - .driver = { - .name = "samsung-pcm", - .owner = THIS_MODULE, - }, -}; - -static int __init s3c_pcm_init(void) -{ - return platform_driver_register(&s3c_pcm_driver); -} -module_init(s3c_pcm_init); - -static void __exit s3c_pcm_exit(void) -{ - platform_driver_unregister(&s3c_pcm_driver); -} -module_exit(s3c_pcm_exit); - -/* Module information */ -MODULE_AUTHOR("Jaswinder Singh, "); -MODULE_DESCRIPTION("S3C PCM Controller Driver"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:samsung-pcm"); diff --git a/sound/soc/s3c24xx/s3c-pcm.h b/sound/soc/s3c24xx/s3c-pcm.h deleted file mode 100644 index f60baa19387d..000000000000 --- a/sound/soc/s3c24xx/s3c-pcm.h +++ /dev/null @@ -1,124 +0,0 @@ -/* sound/soc/s3c24xx/s3c-pcm.h - * - * 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. - * - */ - -#ifndef __S3C_PCM_H -#define __S3C_PCM_H __FILE__ - -/*Register Offsets */ -#define S3C_PCM_CTL (0x00) -#define S3C_PCM_CLKCTL (0x04) -#define S3C_PCM_TXFIFO (0x08) -#define S3C_PCM_RXFIFO (0x0C) -#define S3C_PCM_IRQCTL (0x10) -#define S3C_PCM_IRQSTAT (0x14) -#define S3C_PCM_FIFOSTAT (0x18) -#define S3C_PCM_CLRINT (0x20) - -/* PCM_CTL Bit-Fields */ -#define S3C_PCM_CTL_TXDIPSTICK_MASK (0x3f) -#define S3C_PCM_CTL_TXDIPSTICK_SHIFT (13) -#define S3C_PCM_CTL_RXDIPSTICK_MASK (0x3f) -#define S3C_PCM_CTL_RXDIPSTICK_SHIFT (7) -#define S3C_PCM_CTL_TXDMA_EN (0x1<<6) -#define S3C_PCM_CTL_RXDMA_EN (0x1<<5) -#define S3C_PCM_CTL_TXMSB_AFTER_FSYNC (0x1<<4) -#define S3C_PCM_CTL_RXMSB_AFTER_FSYNC (0x1<<3) -#define S3C_PCM_CTL_TXFIFO_EN (0x1<<2) -#define S3C_PCM_CTL_RXFIFO_EN (0x1<<1) -#define S3C_PCM_CTL_ENABLE (0x1<<0) - -/* PCM_CLKCTL Bit-Fields */ -#define S3C_PCM_CLKCTL_SERCLK_EN (0x1<<19) -#define S3C_PCM_CLKCTL_SERCLKSEL_PCLK (0x1<<18) -#define S3C_PCM_CLKCTL_SCLKDIV_MASK (0x1ff) -#define S3C_PCM_CLKCTL_SYNCDIV_MASK (0x1ff) -#define S3C_PCM_CLKCTL_SCLKDIV_SHIFT (9) -#define S3C_PCM_CLKCTL_SYNCDIV_SHIFT (0) - -/* PCM_TXFIFO Bit-Fields */ -#define S3C_PCM_TXFIFO_DVALID (0x1<<16) -#define S3C_PCM_TXFIFO_DATA_MSK (0xffff<<0) - -/* PCM_RXFIFO Bit-Fields */ -#define S3C_PCM_RXFIFO_DVALID (0x1<<16) -#define S3C_PCM_RXFIFO_DATA_MSK (0xffff<<0) - -/* PCM_IRQCTL Bit-Fields */ -#define S3C_PCM_IRQCTL_IRQEN (0x1<<14) -#define S3C_PCM_IRQCTL_WRDEN (0x1<<12) -#define S3C_PCM_IRQCTL_TXEMPTYEN (0x1<<11) -#define S3C_PCM_IRQCTL_TXALMSTEMPTYEN (0x1<<10) -#define S3C_PCM_IRQCTL_TXFULLEN (0x1<<9) -#define S3C_PCM_IRQCTL_TXALMSTFULLEN (0x1<<8) -#define S3C_PCM_IRQCTL_TXSTARVEN (0x1<<7) -#define S3C_PCM_IRQCTL_TXERROVRFLEN (0x1<<6) -#define S3C_PCM_IRQCTL_RXEMPTEN (0x1<<5) -#define S3C_PCM_IRQCTL_RXALMSTEMPTEN (0x1<<4) -#define S3C_PCM_IRQCTL_RXFULLEN (0x1<<3) -#define S3C_PCM_IRQCTL_RXALMSTFULLEN (0x1<<2) -#define S3C_PCM_IRQCTL_RXSTARVEN (0x1<<1) -#define S3C_PCM_IRQCTL_RXERROVRFLEN (0x1<<0) - -/* PCM_IRQSTAT Bit-Fields */ -#define S3C_PCM_IRQSTAT_IRQPND (0x1<<13) -#define S3C_PCM_IRQSTAT_WRD_XFER (0x1<<12) -#define S3C_PCM_IRQSTAT_TXEMPTY (0x1<<11) -#define S3C_PCM_IRQSTAT_TXALMSTEMPTY (0x1<<10) -#define S3C_PCM_IRQSTAT_TXFULL (0x1<<9) -#define S3C_PCM_IRQSTAT_TXALMSTFULL (0x1<<8) -#define S3C_PCM_IRQSTAT_TXSTARV (0x1<<7) -#define S3C_PCM_IRQSTAT_TXERROVRFL (0x1<<6) -#define S3C_PCM_IRQSTAT_RXEMPT (0x1<<5) -#define S3C_PCM_IRQSTAT_RXALMSTEMPT (0x1<<4) -#define S3C_PCM_IRQSTAT_RXFULL (0x1<<3) -#define S3C_PCM_IRQSTAT_RXALMSTFULL (0x1<<2) -#define S3C_PCM_IRQSTAT_RXSTARV (0x1<<1) -#define S3C_PCM_IRQSTAT_RXERROVRFL (0x1<<0) - -/* PCM_FIFOSTAT Bit-Fields */ -#define S3C_PCM_FIFOSTAT_TXCNT_MSK (0x3f<<14) -#define S3C_PCM_FIFOSTAT_TXFIFOEMPTY (0x1<<13) -#define S3C_PCM_FIFOSTAT_TXFIFOALMSTEMPTY (0x1<<12) -#define S3C_PCM_FIFOSTAT_TXFIFOFULL (0x1<<11) -#define S3C_PCM_FIFOSTAT_TXFIFOALMSTFULL (0x1<<10) -#define S3C_PCM_FIFOSTAT_RXCNT_MSK (0x3f<<4) -#define S3C_PCM_FIFOSTAT_RXFIFOEMPTY (0x1<<3) -#define S3C_PCM_FIFOSTAT_RXFIFOALMSTEMPTY (0x1<<2) -#define S3C_PCM_FIFOSTAT_RXFIFOFULL (0x1<<1) -#define S3C_PCM_FIFOSTAT_RXFIFOALMSTFULL (0x1<<0) - -#define S3C_PCM_CLKSRC_PCLK 0 -#define S3C_PCM_CLKSRC_MUX 1 - -#define S3C_PCM_SCLK_PER_FS 0 - -/** - * struct s3c_pcm_info - S3C PCM Controller information - * @dev: The parent device passed to use from the probe. - * @regs: The pointer to the device register block. - * @dma_playback: DMA information for playback channel. - * @dma_capture: DMA information for capture channel. - */ -struct s3c_pcm_info { - spinlock_t lock; - struct device *dev; - void __iomem *regs; - - unsigned int sclk_per_fs; - - /* Whether to keep PCMSCLK enabled even when idle(no active xfer) */ - unsigned int idleclk; - - struct clk *pclk; - struct clk *cclk; - - struct s3c_dma_params *dma_playback; - struct s3c_dma_params *dma_capture; -}; - -#endif /* __S3C_PCM_H */ -- cgit v1.2.3 From c3f2028b5b15c6799d84b29a07fb92934b10a4d2 Mon Sep 17 00:00:00 2001 From: Jassi Brar Date: Mon, 22 Nov 2010 15:36:50 +0900 Subject: ASoC: Samsung: Generalize DMA driver namespace Remove S3C,s3c from static defines. s3c_dma_ -> dma_ s3c24xx_runtime_ -> runtime_ s3c24xx_audio_ -> audio_ s3c_preallocate_ -> preallocate_ s3c24xx_soc_platform -> samsung_asoc_platform s3c24xx_pcm_driver -> asoc_dma_driver snd_s3c24xx_pcm_ -> samsung_asoc_ Signed-off-by: Jassi Brar Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/s3c24xx/dma.c | 124 ++++++++++++++++++++++++------------------------ 1 file changed, 62 insertions(+), 62 deletions(-) diff --git a/sound/soc/s3c24xx/dma.c b/sound/soc/s3c24xx/dma.c index c5eb1a2c72fd..21240198c5d6 100644 --- a/sound/soc/s3c24xx/dma.c +++ b/sound/soc/s3c24xx/dma.c @@ -32,7 +32,7 @@ #include "dma.h" -static const struct snd_pcm_hardware s3c_dma_hardware = { +static const struct snd_pcm_hardware dma_hardware = { .info = SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_MMAP | @@ -53,7 +53,7 @@ static const struct snd_pcm_hardware s3c_dma_hardware = { .fifo_size = 32, }; -struct s3c24xx_runtime_data { +struct runtime_data { spinlock_t lock; int state; unsigned int dma_loaded; @@ -65,14 +65,14 @@ struct s3c24xx_runtime_data { struct s3c_dma_params *params; }; -/* s3c_dma_enqueue +/* dma_enqueue * * place a dma buffer onto the queue for the dma system * to handle. */ -static void s3c_dma_enqueue(struct snd_pcm_substream *substream) +static void dma_enqueue(struct snd_pcm_substream *substream) { - struct s3c24xx_runtime_data *prtd = substream->runtime->private_data; + struct runtime_data *prtd = substream->runtime->private_data; dma_addr_t pos = prtd->dma_pos; unsigned int limit; int ret; @@ -112,12 +112,12 @@ static void s3c_dma_enqueue(struct snd_pcm_substream *substream) prtd->dma_pos = pos; } -static void s3c24xx_audio_buffdone(struct s3c2410_dma_chan *channel, +static void audio_buffdone(struct s3c2410_dma_chan *channel, void *dev_id, int size, enum s3c2410_dma_buffresult result) { struct snd_pcm_substream *substream = dev_id; - struct s3c24xx_runtime_data *prtd; + struct runtime_data *prtd; pr_debug("Entered %s\n", __func__); @@ -132,17 +132,17 @@ static void s3c24xx_audio_buffdone(struct s3c2410_dma_chan *channel, spin_lock(&prtd->lock); if (prtd->state & ST_RUNNING && !s3c_dma_has_circular()) { prtd->dma_loaded--; - s3c_dma_enqueue(substream); + dma_enqueue(substream); } spin_unlock(&prtd->lock); } -static int s3c_dma_hw_params(struct snd_pcm_substream *substream, +static int dma_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { struct snd_pcm_runtime *runtime = substream->runtime; - struct s3c24xx_runtime_data *prtd = runtime->private_data; + struct runtime_data *prtd = runtime->private_data; struct snd_soc_pcm_runtime *rtd = substream->private_data; unsigned long totbytes = params_buffer_bytes(params); struct s3c_dma_params *dma = @@ -181,7 +181,7 @@ static int s3c_dma_hw_params(struct snd_pcm_substream *substream, } s3c2410_dma_set_buffdone_fn(prtd->params->channel, - s3c24xx_audio_buffdone); + audio_buffdone); snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); @@ -199,9 +199,9 @@ static int s3c_dma_hw_params(struct snd_pcm_substream *substream, return 0; } -static int s3c_dma_hw_free(struct snd_pcm_substream *substream) +static int dma_hw_free(struct snd_pcm_substream *substream) { - struct s3c24xx_runtime_data *prtd = substream->runtime->private_data; + struct runtime_data *prtd = substream->runtime->private_data; pr_debug("Entered %s\n", __func__); @@ -216,9 +216,9 @@ static int s3c_dma_hw_free(struct snd_pcm_substream *substream) return 0; } -static int s3c_dma_prepare(struct snd_pcm_substream *substream) +static int dma_prepare(struct snd_pcm_substream *substream) { - struct s3c24xx_runtime_data *prtd = substream->runtime->private_data; + struct runtime_data *prtd = substream->runtime->private_data; int ret = 0; pr_debug("Entered %s\n", __func__); @@ -249,14 +249,14 @@ static int s3c_dma_prepare(struct snd_pcm_substream *substream) prtd->dma_pos = prtd->dma_start; /* enqueue dma buffers */ - s3c_dma_enqueue(substream); + dma_enqueue(substream); return ret; } -static int s3c_dma_trigger(struct snd_pcm_substream *substream, int cmd) +static int dma_trigger(struct snd_pcm_substream *substream, int cmd) { - struct s3c24xx_runtime_data *prtd = substream->runtime->private_data; + struct runtime_data *prtd = substream->runtime->private_data; int ret = 0; pr_debug("Entered %s\n", __func__); @@ -289,10 +289,10 @@ static int s3c_dma_trigger(struct snd_pcm_substream *substream, int cmd) } static snd_pcm_uframes_t -s3c_dma_pointer(struct snd_pcm_substream *substream) +dma_pointer(struct snd_pcm_substream *substream) { struct snd_pcm_runtime *runtime = substream->runtime; - struct s3c24xx_runtime_data *prtd = runtime->private_data; + struct runtime_data *prtd = runtime->private_data; unsigned long res; dma_addr_t src, dst; @@ -324,17 +324,17 @@ s3c_dma_pointer(struct snd_pcm_substream *substream) return bytes_to_frames(substream->runtime, res); } -static int s3c_dma_open(struct snd_pcm_substream *substream) +static int dma_open(struct snd_pcm_substream *substream) { struct snd_pcm_runtime *runtime = substream->runtime; - struct s3c24xx_runtime_data *prtd; + struct runtime_data *prtd; pr_debug("Entered %s\n", __func__); snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS); - snd_soc_set_runtime_hwparams(substream, &s3c_dma_hardware); + snd_soc_set_runtime_hwparams(substream, &dma_hardware); - prtd = kzalloc(sizeof(struct s3c24xx_runtime_data), GFP_KERNEL); + prtd = kzalloc(sizeof(struct runtime_data), GFP_KERNEL); if (prtd == NULL) return -ENOMEM; @@ -344,22 +344,22 @@ static int s3c_dma_open(struct snd_pcm_substream *substream) return 0; } -static int s3c_dma_close(struct snd_pcm_substream *substream) +static int dma_close(struct snd_pcm_substream *substream) { struct snd_pcm_runtime *runtime = substream->runtime; - struct s3c24xx_runtime_data *prtd = runtime->private_data; + struct runtime_data *prtd = runtime->private_data; pr_debug("Entered %s\n", __func__); if (!prtd) - pr_debug("s3c_dma_close called with prtd == NULL\n"); + pr_debug("dma_close called with prtd == NULL\n"); kfree(prtd); return 0; } -static int s3c_dma_mmap(struct snd_pcm_substream *substream, +static int dma_mmap(struct snd_pcm_substream *substream, struct vm_area_struct *vma) { struct snd_pcm_runtime *runtime = substream->runtime; @@ -372,23 +372,23 @@ static int s3c_dma_mmap(struct snd_pcm_substream *substream, runtime->dma_bytes); } -static struct snd_pcm_ops s3c_dma_ops = { - .open = s3c_dma_open, - .close = s3c_dma_close, +static struct snd_pcm_ops dma_ops = { + .open = dma_open, + .close = dma_close, .ioctl = snd_pcm_lib_ioctl, - .hw_params = s3c_dma_hw_params, - .hw_free = s3c_dma_hw_free, - .prepare = s3c_dma_prepare, - .trigger = s3c_dma_trigger, - .pointer = s3c_dma_pointer, - .mmap = s3c_dma_mmap, + .hw_params = dma_hw_params, + .hw_free = dma_hw_free, + .prepare = dma_prepare, + .trigger = dma_trigger, + .pointer = dma_pointer, + .mmap = dma_mmap, }; -static int s3c_preallocate_dma_buffer(struct snd_pcm *pcm, int stream) +static int preallocate_dma_buffer(struct snd_pcm *pcm, int stream) { struct snd_pcm_substream *substream = pcm->streams[stream].substream; struct snd_dma_buffer *buf = &substream->dma_buffer; - size_t size = s3c_dma_hardware.buffer_bytes_max; + size_t size = dma_hardware.buffer_bytes_max; pr_debug("Entered %s\n", __func__); @@ -403,7 +403,7 @@ static int s3c_preallocate_dma_buffer(struct snd_pcm *pcm, int stream) return 0; } -static void s3c_dma_free_dma_buffers(struct snd_pcm *pcm) +static void dma_free_dma_buffers(struct snd_pcm *pcm) { struct snd_pcm_substream *substream; struct snd_dma_buffer *buf; @@ -426,9 +426,9 @@ static void s3c_dma_free_dma_buffers(struct snd_pcm *pcm) } } -static u64 s3c_dma_mask = DMA_BIT_MASK(32); +static u64 dma_mask = DMA_BIT_MASK(32); -static int s3c_dma_new(struct snd_card *card, +static int dma_new(struct snd_card *card, struct snd_soc_dai *dai, struct snd_pcm *pcm) { int ret = 0; @@ -436,19 +436,19 @@ static int s3c_dma_new(struct snd_card *card, pr_debug("Entered %s\n", __func__); if (!card->dev->dma_mask) - card->dev->dma_mask = &s3c_dma_mask; + card->dev->dma_mask = &dma_mask; if (!card->dev->coherent_dma_mask) card->dev->coherent_dma_mask = 0xffffffff; if (dai->driver->playback.channels_min) { - ret = s3c_preallocate_dma_buffer(pcm, + ret = preallocate_dma_buffer(pcm, SNDRV_PCM_STREAM_PLAYBACK); if (ret) goto out; } if (dai->driver->capture.channels_min) { - ret = s3c_preallocate_dma_buffer(pcm, + ret = preallocate_dma_buffer(pcm, SNDRV_PCM_STREAM_CAPTURE); if (ret) goto out; @@ -457,46 +457,46 @@ out: return ret; } -static struct snd_soc_platform_driver s3c24xx_soc_platform = { - .ops = &s3c_dma_ops, - .pcm_new = s3c_dma_new, - .pcm_free = s3c_dma_free_dma_buffers, +static struct snd_soc_platform_driver samsung_asoc_platform = { + .ops = &dma_ops, + .pcm_new = dma_new, + .pcm_free = dma_free_dma_buffers, }; -static int __devinit s3c24xx_soc_platform_probe(struct platform_device *pdev) +static int __devinit samsung_asoc_platform_probe(struct platform_device *pdev) { - return snd_soc_register_platform(&pdev->dev, &s3c24xx_soc_platform); + return snd_soc_register_platform(&pdev->dev, &samsung_asoc_platform); } -static int __devexit s3c24xx_soc_platform_remove(struct platform_device *pdev) +static int __devexit samsung_asoc_platform_remove(struct platform_device *pdev) { snd_soc_unregister_platform(&pdev->dev); return 0; } -static struct platform_driver s3c24xx_pcm_driver = { +static struct platform_driver asoc_dma_driver = { .driver = { .name = "samsung-audio", .owner = THIS_MODULE, }, - .probe = s3c24xx_soc_platform_probe, - .remove = __devexit_p(s3c24xx_soc_platform_remove), + .probe = samsung_asoc_platform_probe, + .remove = __devexit_p(samsung_asoc_platform_remove), }; -static int __init snd_s3c24xx_pcm_init(void) +static int __init samsung_asoc_init(void) { - return platform_driver_register(&s3c24xx_pcm_driver); + return platform_driver_register(&asoc_dma_driver); } -module_init(snd_s3c24xx_pcm_init); +module_init(samsung_asoc_init); -static void __exit snd_s3c24xx_pcm_exit(void) +static void __exit samsung_asoc_exit(void) { - platform_driver_unregister(&s3c24xx_pcm_driver); + platform_driver_unregister(&asoc_dma_driver); } -module_exit(snd_s3c24xx_pcm_exit); +module_exit(samsung_asoc_exit); MODULE_AUTHOR("Ben Dooks, "); -MODULE_DESCRIPTION("Samsung S3C Audio DMA module"); +MODULE_DESCRIPTION("Samsung ASoC DMA Driver"); MODULE_LICENSE("GPL"); MODULE_ALIAS("platform:samsung-audio"); -- cgit v1.2.3 From 0068402c58d5f3e21b863de881508248f29b464f Mon Sep 17 00:00:00 2001 From: Jassi Brar Date: Mon, 22 Nov 2010 15:36:54 +0900 Subject: ASoC: Samsung: Rename s3c64xx I2S device Since the I2S of S3C64XX and newer SoCs are incremental versions of each other with changes managable in a single driver, rename the 's3c64xx-iis' -> 'samsung-i2s' Signed-off-by: Jassi Brar Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/s3c24xx/s3c64xx-i2s-v4.c | 4 ++-- sound/soc/s3c24xx/s3c64xx-i2s.c | 4 ++-- sound/soc/s3c24xx/smdk64xx_wm8580.c | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/sound/soc/s3c24xx/s3c64xx-i2s-v4.c b/sound/soc/s3c24xx/s3c64xx-i2s-v4.c index 46b65d7cb630..8a080416ce85 100644 --- a/sound/soc/s3c24xx/s3c64xx-i2s-v4.c +++ b/sound/soc/s3c24xx/s3c64xx-i2s-v4.c @@ -206,7 +206,7 @@ static struct platform_driver s3c64xx_i2sv4_driver = { .probe = s3c64xx_i2sv4_dev_probe, .remove = s3c64xx_i2sv4_dev_remove, .driver = { - .name = "s3c64xx-iis-v4", + .name = "samsung-i2s-v4", .owner = THIS_MODULE, }, }; @@ -227,4 +227,4 @@ module_exit(s3c64xx_i2sv4_exit); MODULE_AUTHOR("Jaswinder Singh, "); MODULE_DESCRIPTION("S3C64XX I2Sv4 SoC Interface"); MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:s3c64xx-iis-v4"); +MODULE_ALIAS("platform:samsung-i2s-v4"); diff --git a/sound/soc/s3c24xx/s3c64xx-i2s.c b/sound/soc/s3c24xx/s3c64xx-i2s.c index 0288d4ef14b3..0fefbb545947 100644 --- a/sound/soc/s3c24xx/s3c64xx-i2s.c +++ b/sound/soc/s3c24xx/s3c64xx-i2s.c @@ -218,7 +218,7 @@ static struct platform_driver s3c64xx_iis_driver = { .probe = s3c64xx_iis_dev_probe, .remove = s3c64xx_iis_dev_remove, .driver = { - .name = "s3c64xx-iis", + .name = "samsung-i2s", .owner = THIS_MODULE, }, }; @@ -239,4 +239,4 @@ module_exit(s3c64xx_i2s_exit); MODULE_AUTHOR("Ben Dooks, "); MODULE_DESCRIPTION("S3C64XX I2S SoC Interface"); MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:s3c64xx-iis"); +MODULE_ALIAS("platform:samsung-i2s"); diff --git a/sound/soc/s3c24xx/smdk64xx_wm8580.c b/sound/soc/s3c24xx/smdk64xx_wm8580.c index 5125bc14fc0f..095379126435 100644 --- a/sound/soc/s3c24xx/smdk64xx_wm8580.c +++ b/sound/soc/s3c24xx/smdk64xx_wm8580.c @@ -223,7 +223,7 @@ static struct snd_soc_dai_link smdk64xx_dai[] = { { /* Primary Playback i/f */ .name = "WM8580 PAIF RX", .stream_name = "Playback", - .cpu_dai_name = "s3c64xx-iis-v4", + .cpu_dai_name = "samsung-i2s-v4", .codec_dai_name = "wm8580-hifi-playback", .platform_name = "samsung-audio", .codec_name = "wm8580-codec.0-001b", @@ -233,7 +233,7 @@ static struct snd_soc_dai_link smdk64xx_dai[] = { { /* Primary Capture i/f */ .name = "WM8580 PAIF TX", .stream_name = "Capture", - .cpu_dai_name = "s3c64xx-iis-v4", + .cpu_dai_name = "samsung-i2s-v4", .codec_dai_name = "wm8580-hifi-capture", .platform_name = "samsung-audio", .codec_name = "wm8580-codec.0-001b", -- cgit v1.2.3 From 1c7ac01807ac89dee5e2ebf8f43fbc4cbba24af6 Mon Sep 17 00:00:00 2001 From: Jassi Brar Date: Mon, 22 Nov 2010 15:36:59 +0900 Subject: ASoC: Samsung: Add common I2S driver The I2S controllers since S3C64XX are incremental revisions, with a new feature added to the last one. The programming i/f doesn't conflict between these revisions, so it is possible to have one common driver that could manage various versions of I2S (v3, 4 & 5) Signed-off-by: Jassi Brar Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/s3c24xx/Kconfig | 3 + sound/soc/s3c24xx/Makefile | 2 + sound/soc/s3c24xx/i2s.c | 1256 ++++++++++++++++++++++++++++++++++++++++++++ sound/soc/s3c24xx/i2s.h | 29 + 4 files changed, 1290 insertions(+) create mode 100644 sound/soc/s3c24xx/i2s.c create mode 100644 sound/soc/s3c24xx/i2s.h diff --git a/sound/soc/s3c24xx/Kconfig b/sound/soc/s3c24xx/Kconfig index 226f831d46f7..ec870baf6d7a 100644 --- a/sound/soc/s3c24xx/Kconfig +++ b/sound/soc/s3c24xx/Kconfig @@ -41,6 +41,9 @@ config SND_S5P_SOC_SPDIF tristate select SND_SOC_SPDIF +config SND_SAMSUNG_I2S + tristate + config SND_S3C24XX_SOC_NEO1973_WM8753 tristate "SoC I2S Audio support for NEO1973 - WM8753" depends on SND_S3C24XX_SOC && MACH_NEO1973_GTA01 diff --git a/sound/soc/s3c24xx/Makefile b/sound/soc/s3c24xx/Makefile index 93de2a00df1f..1d6fc0736102 100644 --- a/sound/soc/s3c24xx/Makefile +++ b/sound/soc/s3c24xx/Makefile @@ -8,6 +8,7 @@ snd-soc-s3c64xx-i2s-v4-objs := s3c64xx-i2s-v4.o snd-soc-s3c-i2s-v2-objs := s3c-i2s-v2.o snd-soc-samsung-spdif-objs := spdif.o snd-soc-pcm-objs := pcm.o +snd-soc-i2s-objs := i2s.o obj-$(CONFIG_SND_S3C24XX_SOC) += snd-soc-s3c24xx.o obj-$(CONFIG_SND_S3C24XX_SOC_I2S) += snd-soc-s3c24xx-i2s.o @@ -18,6 +19,7 @@ obj-$(CONFIG_SND_S3C64XX_SOC_I2S_V4) += snd-soc-s3c64xx-i2s-v4.o obj-$(CONFIG_SND_S3C_I2SV2_SOC) += snd-soc-s3c-i2s-v2.o obj-$(CONFIG_SND_S5P_SOC_SPDIF) += snd-soc-samsung-spdif.o obj-$(CONFIG_SND_S3C_SOC_PCM) += snd-soc-pcm.o +obj-$(CONFIG_SND_SAMSUNG_I2S) += snd-soc-i2s.o # S3C24XX Machine Support snd-soc-jive-wm8750-objs := jive_wm8750.o diff --git a/sound/soc/s3c24xx/i2s.c b/sound/soc/s3c24xx/i2s.c new file mode 100644 index 000000000000..7e6ddfab76b1 --- /dev/null +++ b/sound/soc/s3c24xx/i2s.c @@ -0,0 +1,1256 @@ +/* sound/soc/s3c24xx/i2s.c + * + * ALSA SoC Audio Layer - Samsung I2S Controller driver + * + * Copyright (c) 2010 Samsung Electronics Co. Ltd. + * Jaswinder Singh + * + * 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 + +#include +#include +#include + +#include + +#include "dma.h" +#include "i2s.h" + +#define I2SCON 0x0 +#define I2SMOD 0x4 +#define I2SFIC 0x8 +#define I2SPSR 0xc +#define I2STXD 0x10 +#define I2SRXD 0x14 +#define I2SFICS 0x18 +#define I2STXDS 0x1c + +#define CON_RSTCLR (1 << 31) +#define CON_FRXOFSTATUS (1 << 26) +#define CON_FRXORINTEN (1 << 25) +#define CON_FTXSURSTAT (1 << 24) +#define CON_FTXSURINTEN (1 << 23) +#define CON_TXSDMA_PAUSE (1 << 20) +#define CON_TXSDMA_ACTIVE (1 << 18) + +#define CON_FTXURSTATUS (1 << 17) +#define CON_FTXURINTEN (1 << 16) +#define CON_TXFIFO2_EMPTY (1 << 15) +#define CON_TXFIFO1_EMPTY (1 << 14) +#define CON_TXFIFO2_FULL (1 << 13) +#define CON_TXFIFO1_FULL (1 << 12) + +#define CON_LRINDEX (1 << 11) +#define CON_TXFIFO_EMPTY (1 << 10) +#define CON_RXFIFO_EMPTY (1 << 9) +#define CON_TXFIFO_FULL (1 << 8) +#define CON_RXFIFO_FULL (1 << 7) +#define CON_TXDMA_PAUSE (1 << 6) +#define CON_RXDMA_PAUSE (1 << 5) +#define CON_TXCH_PAUSE (1 << 4) +#define CON_RXCH_PAUSE (1 << 3) +#define CON_TXDMA_ACTIVE (1 << 2) +#define CON_RXDMA_ACTIVE (1 << 1) +#define CON_ACTIVE (1 << 0) + +#define MOD_OPCLK_CDCLK_OUT (0 << 30) +#define MOD_OPCLK_CDCLK_IN (1 << 30) +#define MOD_OPCLK_BCLK_OUT (2 << 30) +#define MOD_OPCLK_PCLK (3 << 30) +#define MOD_OPCLK_MASK (3 << 30) +#define MOD_TXS_IDMA (1 << 28) /* Sec_TXFIFO use I-DMA */ + +#define MOD_BLCS_SHIFT 26 +#define MOD_BLCS_16BIT (0 << MOD_BLCS_SHIFT) +#define MOD_BLCS_8BIT (1 << MOD_BLCS_SHIFT) +#define MOD_BLCS_24BIT (2 << MOD_BLCS_SHIFT) +#define MOD_BLCS_MASK (3 << MOD_BLCS_SHIFT) +#define MOD_BLCP_SHIFT 24 +#define MOD_BLCP_16BIT (0 << MOD_BLCP_SHIFT) +#define MOD_BLCP_8BIT (1 << MOD_BLCP_SHIFT) +#define MOD_BLCP_24BIT (2 << MOD_BLCP_SHIFT) +#define MOD_BLCP_MASK (3 << MOD_BLCP_SHIFT) + +#define MOD_C2DD_HHALF (1 << 21) /* Discard Higher-half */ +#define MOD_C2DD_LHALF (1 << 20) /* Discard Lower-half */ +#define MOD_C1DD_HHALF (1 << 19) +#define MOD_C1DD_LHALF (1 << 18) +#define MOD_DC2_EN (1 << 17) +#define MOD_DC1_EN (1 << 16) +#define MOD_BLC_16BIT (0 << 13) +#define MOD_BLC_8BIT (1 << 13) +#define MOD_BLC_24BIT (2 << 13) +#define MOD_BLC_MASK (3 << 13) + +#define MOD_IMS_SYSMUX (1 << 10) +#define MOD_SLAVE (1 << 11) +#define MOD_TXONLY (0 << 8) +#define MOD_RXONLY (1 << 8) +#define MOD_TXRX (2 << 8) +#define MOD_MASK (3 << 8) +#define MOD_LR_LLOW (0 << 7) +#define MOD_LR_RLOW (1 << 7) +#define MOD_SDF_IIS (0 << 5) +#define MOD_SDF_MSB (1 << 5) +#define MOD_SDF_LSB (2 << 5) +#define MOD_SDF_MASK (3 << 5) +#define MOD_RCLK_256FS (0 << 3) +#define MOD_RCLK_512FS (1 << 3) +#define MOD_RCLK_384FS (2 << 3) +#define MOD_RCLK_768FS (3 << 3) +#define MOD_RCLK_MASK (3 << 3) +#define MOD_BCLK_32FS (0 << 1) +#define MOD_BCLK_48FS (1 << 1) +#define MOD_BCLK_16FS (2 << 1) +#define MOD_BCLK_24FS (3 << 1) +#define MOD_BCLK_MASK (3 << 1) +#define MOD_8BIT (1 << 0) + +#define MOD_CDCLKCON (1 << 12) + +#define PSR_PSREN (1 << 15) + +#define FIC_TX2COUNT(x) (((x) >> 24) & 0xf) +#define FIC_TX1COUNT(x) (((x) >> 16) & 0xf) + +#define FIC_TXFLUSH (1 << 15) +#define FIC_RXFLUSH (1 << 7) +#define FIC_TXCOUNT(x) (((x) >> 8) & 0xf) +#define FIC_RXCOUNT(x) (((x) >> 0) & 0xf) +#define FICS_TXCOUNT(x) (((x) >> 8) & 0x7f) + +#define msecs_to_loops(t) (loops_per_jiffy / 1000 * HZ * t) + +struct i2s_dai { + /* Platform device for this DAI */ + struct platform_device *pdev; + /* IOREMAP'd SFRs */ + void __iomem *addr; + /* Physical base address of SFRs */ + u32 base; + /* Rate of RCLK source clock */ + unsigned long rclk_srcrate; + /* Frame Clock */ + unsigned frmclk; + /* + * Specifically requested RCLK,BCLK by MACHINE Driver. + * 0 indicates CPU driver is free to choose any value. + */ + unsigned rfs, bfs; + /* I2S Controller's core clock */ + struct clk *clk; + /* Clock for generating I2S signals */ + struct clk *op_clk; + /* Array of clock names for op_clk */ + const char **src_clk; + /* Pointer to the Primary_Fifo if this is Sec_Fifo, NULL otherwise */ + struct i2s_dai *pri_dai; + /* Pointer to the Secondary_Fifo if it has one, NULL otherwise */ + struct i2s_dai *sec_dai; +#define DAI_OPENED (1 << 0) /* Dai is opened */ +#define DAI_MANAGER (1 << 1) /* Dai is the manager */ + unsigned mode; + /* Driver for this DAI */ + struct snd_soc_dai_driver i2s_dai_drv; + /* DMA parameters */ + struct s3c_dma_params dma_playback; + struct s3c_dma_params dma_capture; + u32 quirks; + u32 suspend_i2smod; + u32 suspend_i2scon; + u32 suspend_i2spsr; +}; + +/* Lock for cross i/f checks */ +static DEFINE_SPINLOCK(lock); + +/* If this is the 'overlay' stereo DAI */ +static inline bool is_secondary(struct i2s_dai *i2s) +{ + return i2s->pri_dai ? true : false; +} + +/* If operating in SoC-Slave mode */ +static inline bool is_slave(struct i2s_dai *i2s) +{ + return (readl(i2s->addr + I2SMOD) & MOD_SLAVE) ? true : false; +} + +/* If this interface of the controller is transmitting data */ +static inline bool tx_active(struct i2s_dai *i2s) +{ + u32 active; + + if (!i2s) + return false; + + active = readl(i2s->addr + I2SMOD); + + if (is_secondary(i2s)) + active &= CON_TXSDMA_ACTIVE; + else + active &= CON_TXDMA_ACTIVE; + + return active ? true : false; +} + +/* If the other interface of the controller is transmitting data */ +static inline bool other_tx_active(struct i2s_dai *i2s) +{ + struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai; + + return tx_active(other); +} + +/* If any interface of the controller is transmitting data */ +static inline bool any_tx_active(struct i2s_dai *i2s) +{ + return tx_active(i2s) || other_tx_active(i2s); +} + +/* If this interface of the controller is receiving data */ +static inline bool rx_active(struct i2s_dai *i2s) +{ + u32 active; + + if (!i2s) + return false; + + active = readl(i2s->addr + I2SMOD) & CON_RXDMA_ACTIVE; + + return active ? true : false; +} + +/* If the other interface of the controller is receiving data */ +static inline bool other_rx_active(struct i2s_dai *i2s) +{ + struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai; + + return rx_active(other); +} + +/* If any interface of the controller is receiving data */ +static inline bool any_rx_active(struct i2s_dai *i2s) +{ + return rx_active(i2s) || other_rx_active(i2s); +} + +/* If the other DAI is transmitting or receiving data */ +static inline bool other_active(struct i2s_dai *i2s) +{ + return other_rx_active(i2s) || other_tx_active(i2s); +} + +/* If this DAI is transmitting or receiving data */ +static inline bool this_active(struct i2s_dai *i2s) +{ + return tx_active(i2s) || rx_active(i2s); +} + +/* If the controller is active anyway */ +static inline bool any_active(struct i2s_dai *i2s) +{ + return this_active(i2s) || other_active(i2s); +} + +static inline struct i2s_dai *to_info(struct snd_soc_dai *dai) +{ + return snd_soc_dai_get_drvdata(dai); +} + +static inline bool is_opened(struct i2s_dai *i2s) +{ + if (i2s && (i2s->mode & DAI_OPENED)) + return true; + else + return false; +} + +static inline bool is_manager(struct i2s_dai *i2s) +{ + if (is_opened(i2s) && (i2s->mode & DAI_MANAGER)) + return true; + else + return false; +} + +/* Read RCLK of I2S (in multiples of LRCLK) */ +static inline unsigned get_rfs(struct i2s_dai *i2s) +{ + u32 rfs = (readl(i2s->addr + I2SMOD) >> 3) & 0x3; + + switch (rfs) { + case 3: return 768; + case 2: return 384; + case 1: return 512; + default: return 256; + } +} + +/* Write RCLK of I2S (in multiples of LRCLK) */ +static inline void set_rfs(struct i2s_dai *i2s, unsigned rfs) +{ + u32 mod = readl(i2s->addr + I2SMOD); + + mod &= ~MOD_RCLK_MASK; + + switch (rfs) { + case 768: + mod |= MOD_RCLK_768FS; + break; + case 512: + mod |= MOD_RCLK_512FS; + break; + case 384: + mod |= MOD_RCLK_384FS; + break; + default: + mod |= MOD_RCLK_256FS; + break; + } + + writel(mod, i2s->addr + I2SMOD); +} + +/* Read Bit-Clock of I2S (in multiples of LRCLK) */ +static inline unsigned get_bfs(struct i2s_dai *i2s) +{ + u32 bfs = (readl(i2s->addr + I2SMOD) >> 1) & 0x3; + + switch (bfs) { + case 3: return 24; + case 2: return 16; + case 1: return 48; + default: return 32; + } +} + +/* Write Bit-Clock of I2S (in multiples of LRCLK) */ +static inline void set_bfs(struct i2s_dai *i2s, unsigned bfs) +{ + u32 mod = readl(i2s->addr + I2SMOD); + + mod &= ~MOD_BCLK_MASK; + + switch (bfs) { + case 48: + mod |= MOD_BCLK_48FS; + break; + case 32: + mod |= MOD_BCLK_32FS; + break; + case 24: + mod |= MOD_BCLK_24FS; + break; + case 16: + mod |= MOD_BCLK_16FS; + break; + default: + dev_err(&i2s->pdev->dev, "Wrong BCLK Divider!\n"); + return; + } + + writel(mod, i2s->addr + I2SMOD); +} + +/* Sample-Size */ +static inline int get_blc(struct i2s_dai *i2s) +{ + int blc = readl(i2s->addr + I2SMOD); + + blc = (blc >> 13) & 0x3; + + switch (blc) { + case 2: return 24; + case 1: return 8; + default: return 16; + } +} + +/* TX Channel Control */ +static void i2s_txctrl(struct i2s_dai *i2s, int on) +{ + void __iomem *addr = i2s->addr; + u32 con = readl(addr + I2SCON); + u32 mod = readl(addr + I2SMOD) & ~MOD_MASK; + + if (on) { + con |= CON_ACTIVE; + con &= ~CON_TXCH_PAUSE; + + if (is_secondary(i2s)) { + con |= CON_TXSDMA_ACTIVE; + con &= ~CON_TXSDMA_PAUSE; + } else { + con |= CON_TXDMA_ACTIVE; + con &= ~CON_TXDMA_PAUSE; + } + + if (any_rx_active(i2s)) + mod |= MOD_TXRX; + else + mod |= MOD_TXONLY; + } else { + if (is_secondary(i2s)) { + con |= CON_TXSDMA_PAUSE; + con &= ~CON_TXSDMA_ACTIVE; + } else { + con |= CON_TXDMA_PAUSE; + con &= ~CON_TXDMA_ACTIVE; + } + + if (other_tx_active(i2s)) { + writel(con, addr + I2SCON); + return; + } + + con |= CON_TXCH_PAUSE; + + if (any_rx_active(i2s)) + mod |= MOD_RXONLY; + else + con &= ~CON_ACTIVE; + } + + writel(mod, addr + I2SMOD); + writel(con, addr + I2SCON); +} + +/* RX Channel Control */ +static void i2s_rxctrl(struct i2s_dai *i2s, int on) +{ + void __iomem *addr = i2s->addr; + u32 con = readl(addr + I2SCON); + u32 mod = readl(addr + I2SMOD) & ~MOD_MASK; + + if (on) { + con |= CON_RXDMA_ACTIVE | CON_ACTIVE; + con &= ~(CON_RXDMA_PAUSE | CON_RXCH_PAUSE); + + if (any_tx_active(i2s)) + mod |= MOD_TXRX; + else + mod |= MOD_RXONLY; + } else { + con |= CON_RXDMA_PAUSE | CON_RXCH_PAUSE; + con &= ~CON_RXDMA_ACTIVE; + + if (any_tx_active(i2s)) + mod |= MOD_TXONLY; + else + con &= ~CON_ACTIVE; + } + + writel(mod, addr + I2SMOD); + writel(con, addr + I2SCON); +} + +/* Flush FIFO of an interface */ +static inline void i2s_fifo(struct i2s_dai *i2s, u32 flush) +{ + void __iomem *fic; + u32 val; + + if (!i2s) + return; + + if (is_secondary(i2s)) + fic = i2s->addr + I2SFICS; + else + fic = i2s->addr + I2SFIC; + + /* Flush the FIFO */ + writel(readl(fic) | flush, fic); + + /* Be patient */ + val = msecs_to_loops(1) / 1000; /* 1 usec */ + while (--val) + cpu_relax(); + + writel(readl(fic) & ~flush, fic); +} + +static int i2s_set_sysclk(struct snd_soc_dai *dai, + int clk_id, unsigned int rfs, int dir) +{ + struct i2s_dai *i2s = to_info(dai); + struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai; + u32 mod = readl(i2s->addr + I2SMOD); + + switch (clk_id) { + case SAMSUNG_I2S_CDCLK: + /* Shouldn't matter in GATING(CLOCK_IN) mode */ + if (dir == SND_SOC_CLOCK_IN) + rfs = 0; + + if ((rfs && other->rfs && (other->rfs != rfs)) || + (any_active(i2s) && + (((dir == SND_SOC_CLOCK_IN) + && !(mod & MOD_CDCLKCON)) || + ((dir == SND_SOC_CLOCK_OUT) + && (mod & MOD_CDCLKCON))))) { + dev_err(&i2s->pdev->dev, + "%s:%d Other DAI busy\n", __func__, __LINE__); + return -EAGAIN; + } + + if (dir == SND_SOC_CLOCK_IN) + mod |= MOD_CDCLKCON; + else + mod &= ~MOD_CDCLKCON; + + i2s->rfs = rfs; + break; + + case SAMSUNG_I2S_RCLKSRC_0: /* clock corrsponding to IISMOD[10] := 0 */ + case SAMSUNG_I2S_RCLKSRC_1: /* clock corrsponding to IISMOD[10] := 1 */ + if ((i2s->quirks & QUIRK_NO_MUXPSR) + || (clk_id == SAMSUNG_I2S_RCLKSRC_0)) + clk_id = 0; + else + clk_id = 1; + + if (!any_active(i2s)) { + if (i2s->op_clk) { + if ((clk_id && !(mod & MOD_IMS_SYSMUX)) || + (!clk_id && (mod & MOD_IMS_SYSMUX))) { + clk_disable(i2s->op_clk); + clk_put(i2s->op_clk); + } else { + return 0; + } + } + + i2s->op_clk = clk_get(&i2s->pdev->dev, + i2s->src_clk[clk_id]); + clk_enable(i2s->op_clk); + i2s->rclk_srcrate = clk_get_rate(i2s->op_clk); + + /* Over-ride the other's */ + if (other) { + other->op_clk = i2s->op_clk; + other->rclk_srcrate = i2s->rclk_srcrate; + } + } else if ((!clk_id && (mod & MOD_IMS_SYSMUX)) + || (clk_id && !(mod & MOD_IMS_SYSMUX))) { + dev_err(&i2s->pdev->dev, + "%s:%d Other DAI busy\n", __func__, __LINE__); + return -EAGAIN; + } else { + /* Call can't be on the active DAI */ + i2s->op_clk = other->op_clk; + i2s->rclk_srcrate = other->rclk_srcrate; + return 0; + } + + if (clk_id == 0) + mod &= ~MOD_IMS_SYSMUX; + else + mod |= MOD_IMS_SYSMUX; + break; + + default: + dev_err(&i2s->pdev->dev, "We don't serve that!\n"); + return -EINVAL; + } + + writel(mod, i2s->addr + I2SMOD); + + return 0; +} + +static int i2s_set_fmt(struct snd_soc_dai *dai, + unsigned int fmt) +{ + struct i2s_dai *i2s = to_info(dai); + u32 mod = readl(i2s->addr + I2SMOD); + u32 tmp = 0; + + /* Format is priority */ + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { + case SND_SOC_DAIFMT_RIGHT_J: + tmp |= MOD_LR_RLOW; + tmp |= MOD_SDF_MSB; + break; + case SND_SOC_DAIFMT_LEFT_J: + tmp |= MOD_LR_RLOW; + tmp |= MOD_SDF_LSB; + break; + case SND_SOC_DAIFMT_I2S: + tmp |= MOD_SDF_IIS; + break; + default: + dev_err(&i2s->pdev->dev, "Format not supported\n"); + return -EINVAL; + } + + /* + * INV flag is relative to the FORMAT flag - if set it simply + * flips the polarity specified by the Standard + */ + switch (fmt & SND_SOC_DAIFMT_INV_MASK) { + case SND_SOC_DAIFMT_NB_NF: + break; + case SND_SOC_DAIFMT_NB_IF: + if (tmp & MOD_LR_RLOW) + tmp &= ~MOD_LR_RLOW; + else + tmp |= MOD_LR_RLOW; + break; + default: + dev_err(&i2s->pdev->dev, "Polarity not supported\n"); + return -EINVAL; + } + + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { + case SND_SOC_DAIFMT_CBM_CFM: + tmp |= MOD_SLAVE; + break; + case SND_SOC_DAIFMT_CBS_CFS: + /* Set default source clock in Master mode */ + if (i2s->rclk_srcrate == 0) + i2s_set_sysclk(dai, SAMSUNG_I2S_RCLKSRC_0, + 0, SND_SOC_CLOCK_IN); + break; + default: + dev_err(&i2s->pdev->dev, "master/slave format not supported\n"); + return -EINVAL; + } + + if (any_active(i2s) && + ((mod & (MOD_SDF_MASK | MOD_LR_RLOW + | MOD_SLAVE)) != tmp)) { + dev_err(&i2s->pdev->dev, + "%s:%d Other DAI busy\n", __func__, __LINE__); + return -EAGAIN; + } + + mod &= ~(MOD_SDF_MASK | MOD_LR_RLOW | MOD_SLAVE); + mod |= tmp; + writel(mod, i2s->addr + I2SMOD); + + return 0; +} + +static int i2s_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) +{ + struct i2s_dai *i2s = to_info(dai); + u32 mod = readl(i2s->addr + I2SMOD); + + if (!is_secondary(i2s)) + mod &= ~(MOD_DC2_EN | MOD_DC1_EN); + + switch (params_channels(params)) { + case 6: + mod |= MOD_DC2_EN; + case 4: + mod |= MOD_DC1_EN; + break; + case 2: + break; + default: + dev_err(&i2s->pdev->dev, "%d channels not supported\n", + params_channels(params)); + return -EINVAL; + } + + if (is_secondary(i2s)) + mod &= ~MOD_BLCS_MASK; + else + mod &= ~MOD_BLCP_MASK; + + if (is_manager(i2s)) + mod &= ~MOD_BLC_MASK; + + switch (params_format(params)) { + case SNDRV_PCM_FORMAT_S8: + if (is_secondary(i2s)) + mod |= MOD_BLCS_8BIT; + else + mod |= MOD_BLCP_8BIT; + if (is_manager(i2s)) + mod |= MOD_BLC_8BIT; + break; + case SNDRV_PCM_FORMAT_S16_LE: + if (is_secondary(i2s)) + mod |= MOD_BLCS_16BIT; + else + mod |= MOD_BLCP_16BIT; + if (is_manager(i2s)) + mod |= MOD_BLC_16BIT; + break; + case SNDRV_PCM_FORMAT_S24_LE: + if (is_secondary(i2s)) + mod |= MOD_BLCS_24BIT; + else + mod |= MOD_BLCP_24BIT; + if (is_manager(i2s)) + mod |= MOD_BLC_24BIT; + break; + default: + dev_err(&i2s->pdev->dev, "Format(%d) not supported\n", + params_format(params)); + return -EINVAL; + } + writel(mod, i2s->addr + I2SMOD); + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + snd_soc_dai_set_dma_data(dai, substream, + (void *)&i2s->dma_playback); + else + snd_soc_dai_set_dma_data(dai, substream, + (void *)&i2s->dma_capture); + + i2s->frmclk = params_rate(params); + + return 0; +} + +/* We set constraints on the substream acc to the version of I2S */ +static int i2s_startup(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct i2s_dai *i2s = to_info(dai); + struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai; + unsigned long flags; + + spin_lock_irqsave(&lock, flags); + + i2s->mode |= DAI_OPENED; + + if (is_manager(other)) + i2s->mode &= ~DAI_MANAGER; + else + i2s->mode |= DAI_MANAGER; + + /* Enforce set_sysclk in Master mode */ + i2s->rclk_srcrate = 0; + + spin_unlock_irqrestore(&lock, flags); + + return 0; +} + +static void i2s_shutdown(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct i2s_dai *i2s = to_info(dai); + struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai; + unsigned long flags; + + spin_lock_irqsave(&lock, flags); + + i2s->mode &= ~DAI_OPENED; + i2s->mode &= ~DAI_MANAGER; + + if (is_opened(other)) + other->mode |= DAI_MANAGER; + + /* Reset any constraint on RFS and BFS */ + i2s->rfs = 0; + i2s->bfs = 0; + + spin_unlock_irqrestore(&lock, flags); + + /* Gate CDCLK by default */ + if (!is_opened(other)) + i2s_set_sysclk(dai, SAMSUNG_I2S_CDCLK, + 0, SND_SOC_CLOCK_IN); +} + +static int config_setup(struct i2s_dai *i2s) +{ + struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai; + unsigned rfs, bfs, blc; + u32 psr; + + blc = get_blc(i2s); + + bfs = i2s->bfs; + + if (!bfs && other) + bfs = other->bfs; + + /* Select least possible multiple(2) if no constraint set */ + if (!bfs) + bfs = blc * 2; + + rfs = i2s->rfs; + + if (!rfs && other) + rfs = other->rfs; + + if ((rfs == 256 || rfs == 512) && (blc == 24)) { + dev_err(&i2s->pdev->dev, + "%d-RFS not supported for 24-blc\n", rfs); + return -EINVAL; + } + + if (!rfs) { + if (bfs == 16 || bfs == 32) + rfs = 256; + else + rfs = 384; + } + + /* If already setup and running */ + if (any_active(i2s) && (get_rfs(i2s) != rfs || get_bfs(i2s) != bfs)) { + dev_err(&i2s->pdev->dev, + "%s:%d Other DAI busy\n", __func__, __LINE__); + return -EAGAIN; + } + + /* Don't bother RFS, BFS & PSR in Slave mode */ + if (is_slave(i2s)) + return 0; + + set_bfs(i2s, bfs); + set_rfs(i2s, rfs); + + if (!(i2s->quirks & QUIRK_NO_MUXPSR)) { + psr = i2s->rclk_srcrate / i2s->frmclk / rfs; + writel(((psr - 1) << 8) | PSR_PSREN, i2s->addr + I2SPSR); + dev_dbg(&i2s->pdev->dev, + "RCLK_SRC=%luHz PSR=%u, RCLK=%dfs, BCLK=%dfs\n", + i2s->rclk_srcrate, psr, rfs, bfs); + } + + return 0; +} + +static int i2s_trigger(struct snd_pcm_substream *substream, + int cmd, struct snd_soc_dai *dai) +{ + int capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE); + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct i2s_dai *i2s = to_info(rtd->cpu_dai); + unsigned long flags; + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + case SNDRV_PCM_TRIGGER_RESUME: + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: + local_irq_save(flags); + + if (capture) + i2s_fifo(i2s, FIC_RXFLUSH); + else + i2s_fifo(i2s, FIC_TXFLUSH); + + if (config_setup(i2s)) { + local_irq_restore(flags); + return -EINVAL; + } + + if (capture) + i2s_rxctrl(i2s, 1); + else + i2s_txctrl(i2s, 1); + + local_irq_restore(flags); + break; + case SNDRV_PCM_TRIGGER_STOP: + case SNDRV_PCM_TRIGGER_SUSPEND: + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + local_irq_save(flags); + + if (capture) + i2s_rxctrl(i2s, 0); + else + i2s_txctrl(i2s, 0); + + local_irq_restore(flags); + break; + } + + return 0; +} + +static int i2s_set_clkdiv(struct snd_soc_dai *dai, + int div_id, int div) +{ + struct i2s_dai *i2s = to_info(dai); + struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai; + + switch (div_id) { + case SAMSUNG_I2S_DIV_BCLK: + if ((any_active(i2s) && div && (get_bfs(i2s) != div)) + || (other && other->bfs && (other->bfs != div))) { + dev_err(&i2s->pdev->dev, + "%s:%d Other DAI busy\n", __func__, __LINE__); + return -EAGAIN; + } + i2s->bfs = div; + break; + default: + dev_err(&i2s->pdev->dev, + "Invalid clock divider(%d)\n", div_id); + return -EINVAL; + } + + return 0; +} + +static snd_pcm_sframes_t +i2s_delay(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) +{ + struct i2s_dai *i2s = to_info(dai); + u32 reg = readl(i2s->addr + I2SFIC); + snd_pcm_sframes_t delay; + + if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) + delay = FIC_RXCOUNT(reg); + else if (is_secondary(i2s)) + delay = FICS_TXCOUNT(readl(i2s->addr + I2SFICS)); + else + delay = FIC_TXCOUNT(reg); + + return delay; +} + +#ifdef CONFIG_PM +static int i2s_suspend(struct snd_soc_dai *dai) +{ + struct i2s_dai *i2s = to_info(dai); + + if (dai->active) { + i2s->suspend_i2smod = readl(i2s->addr + I2SMOD); + i2s->suspend_i2scon = readl(i2s->addr + I2SCON); + i2s->suspend_i2spsr = readl(i2s->addr + I2SPSR); + } + + return 0; +} + +static int i2s_resume(struct snd_soc_dai *dai) +{ + struct i2s_dai *i2s = to_info(dai); + + if (dai->active) { + writel(i2s->suspend_i2scon, i2s->addr + I2SCON); + writel(i2s->suspend_i2smod, i2s->addr + I2SMOD); + writel(i2s->suspend_i2spsr, i2s->addr + I2SPSR); + } + + return 0; +} +#else +#define i2s_suspend NULL +#define i2s_resume NULL +#endif + +static int samsung_i2s_dai_probe(struct snd_soc_dai *dai) +{ + struct i2s_dai *i2s = to_info(dai); + struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai; + + if (other && other->clk) /* If this is probe on secondary */ + goto probe_exit; + + i2s->addr = ioremap(i2s->base, 0x100); + if (i2s->addr == NULL) { + dev_err(&i2s->pdev->dev, "cannot ioremap registers\n"); + return -ENXIO; + } + + i2s->clk = clk_get(&i2s->pdev->dev, "iis"); + if (IS_ERR(i2s->clk)) { + dev_err(&i2s->pdev->dev, "failed to get i2s_clock\n"); + iounmap(i2s->addr); + return -ENOENT; + } + clk_enable(i2s->clk); + + if (other) { + other->addr = i2s->addr; + other->clk = i2s->clk; + } + + if (i2s->quirks & QUIRK_NEED_RSTCLR) + writel(CON_RSTCLR, i2s->addr + I2SCON); + +probe_exit: + /* Reset any constraint on RFS and BFS */ + i2s->rfs = 0; + i2s->bfs = 0; + i2s_txctrl(i2s, 0); + i2s_rxctrl(i2s, 0); + i2s_fifo(i2s, FIC_TXFLUSH); + i2s_fifo(other, FIC_TXFLUSH); + i2s_fifo(i2s, FIC_RXFLUSH); + + /* Gate CDCLK by default */ + if (!is_opened(other)) + i2s_set_sysclk(dai, SAMSUNG_I2S_CDCLK, + 0, SND_SOC_CLOCK_IN); + + return 0; +} + +static int samsung_i2s_dai_remove(struct snd_soc_dai *dai) +{ + struct i2s_dai *i2s = snd_soc_dai_get_drvdata(dai); + struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai; + + if (!other || !other->clk) { + + if (i2s->quirks & QUIRK_NEED_RSTCLR) + writel(0, i2s->addr + I2SCON); + + clk_disable(i2s->clk); + clk_put(i2s->clk); + + iounmap(i2s->addr); + } + + i2s->clk = NULL; + + return 0; +} + +static struct snd_soc_dai_ops samsung_i2s_dai_ops = { + .trigger = i2s_trigger, + .hw_params = i2s_hw_params, + .set_fmt = i2s_set_fmt, + .set_clkdiv = i2s_set_clkdiv, + .set_sysclk = i2s_set_sysclk, + .startup = i2s_startup, + .shutdown = i2s_shutdown, + .delay = i2s_delay, +}; + +#define SAMSUNG_I2S_RATES SNDRV_PCM_RATE_8000_96000 + +#define SAMSUNG_I2S_FMTS (SNDRV_PCM_FMTBIT_S8 | \ + SNDRV_PCM_FMTBIT_S16_LE | \ + SNDRV_PCM_FMTBIT_S24_LE) + +static __devinit +struct i2s_dai *i2s_alloc_dai(struct platform_device *pdev, bool sec) +{ + struct i2s_dai *i2s; + + i2s = kzalloc(sizeof(struct i2s_dai), GFP_KERNEL); + if (i2s == NULL) + return NULL; + + i2s->pdev = pdev; + i2s->pri_dai = NULL; + i2s->sec_dai = NULL; + i2s->i2s_dai_drv.symmetric_rates = 1; + i2s->i2s_dai_drv.probe = samsung_i2s_dai_probe; + i2s->i2s_dai_drv.remove = samsung_i2s_dai_remove; + i2s->i2s_dai_drv.ops = &samsung_i2s_dai_ops; + i2s->i2s_dai_drv.suspend = i2s_suspend; + i2s->i2s_dai_drv.resume = i2s_resume; + i2s->i2s_dai_drv.playback.channels_min = 2; + i2s->i2s_dai_drv.playback.channels_max = 2; + i2s->i2s_dai_drv.playback.rates = SAMSUNG_I2S_RATES; + i2s->i2s_dai_drv.playback.formats = SAMSUNG_I2S_FMTS; + + if (!sec) { + i2s->i2s_dai_drv.capture.channels_min = 2; + i2s->i2s_dai_drv.capture.channels_max = 2; + i2s->i2s_dai_drv.capture.rates = SAMSUNG_I2S_RATES; + i2s->i2s_dai_drv.capture.formats = SAMSUNG_I2S_FMTS; + } else { /* Create a new platform_device for Secondary */ + i2s->pdev = platform_device_register_resndata(NULL, + pdev->name, pdev->id + SAMSUNG_I2S_SECOFF, + NULL, 0, NULL, 0); + if (IS_ERR(i2s->pdev)) { + kfree(i2s); + return NULL; + } + } + + /* Pre-assign snd_soc_dai_set_drvdata */ + dev_set_drvdata(&i2s->pdev->dev, i2s); + + return i2s; +} + +static __devinit int samsung_i2s_probe(struct platform_device *pdev) +{ + u32 dma_pl_chan, dma_cp_chan, dma_pl_sec_chan; + struct i2s_dai *pri_dai, *sec_dai = NULL; + struct s3c_audio_pdata *i2s_pdata; + struct samsung_i2s *i2s_cfg; + struct resource *res; + u32 regs_base, quirks; + int ret = 0; + + /* Call during Seconday interface registration */ + if (pdev->id >= SAMSUNG_I2S_SECOFF) { + sec_dai = dev_get_drvdata(&pdev->dev); + snd_soc_register_dai(&sec_dai->pdev->dev, + &sec_dai->i2s_dai_drv); + return 0; + } + + i2s_pdata = pdev->dev.platform_data; + if (i2s_pdata == NULL) { + dev_err(&pdev->dev, "Can't work without s3c_audio_pdata\n"); + return -EINVAL; + } + + res = platform_get_resource(pdev, IORESOURCE_DMA, 0); + if (!res) { + dev_err(&pdev->dev, "Unable to get I2S-TX dma resource\n"); + return -ENXIO; + } + dma_pl_chan = res->start; + + res = platform_get_resource(pdev, IORESOURCE_DMA, 1); + if (!res) { + dev_err(&pdev->dev, "Unable to get I2S-RX dma resource\n"); + return -ENXIO; + } + dma_cp_chan = res->start; + + res = platform_get_resource(pdev, IORESOURCE_DMA, 2); + if (res) + dma_pl_sec_chan = res->start; + else + dma_pl_sec_chan = 0; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + dev_err(&pdev->dev, "Unable to get I2S SFR address\n"); + return -ENXIO; + } + + if (!request_mem_region(res->start, resource_size(res), + "samsung-i2s")) { + dev_err(&pdev->dev, "Unable to request SFR region\n"); + return -EBUSY; + } + regs_base = res->start; + + i2s_cfg = &i2s_pdata->type.i2s; + quirks = i2s_cfg->quirks; + + pri_dai = i2s_alloc_dai(pdev, false); + if (!pri_dai) { + dev_err(&pdev->dev, "Unable to alloc I2S_pri\n"); + ret = -ENOMEM; + goto err1; + } + + pri_dai->dma_playback.dma_addr = regs_base + I2STXD; + pri_dai->dma_capture.dma_addr = regs_base + I2SRXD; + pri_dai->dma_playback.client = + (struct s3c2410_dma_client *)&pri_dai->dma_playback; + pri_dai->dma_capture.client = + (struct s3c2410_dma_client *)&pri_dai->dma_capture; + pri_dai->dma_playback.channel = dma_pl_chan; + pri_dai->dma_capture.channel = dma_cp_chan; + pri_dai->src_clk = i2s_cfg->src_clk; + pri_dai->dma_playback.dma_size = 4; + pri_dai->dma_capture.dma_size = 4; + pri_dai->base = regs_base; + pri_dai->quirks = quirks; + + if (quirks & QUIRK_PRI_6CHAN) + pri_dai->i2s_dai_drv.playback.channels_max = 6; + + if (quirks & QUIRK_SEC_DAI) { + sec_dai = i2s_alloc_dai(pdev, true); + if (!sec_dai) { + dev_err(&pdev->dev, "Unable to alloc I2S_sec\n"); + ret = -ENOMEM; + goto err2; + } + sec_dai->dma_playback.dma_addr = regs_base + I2STXDS; + sec_dai->dma_playback.client = + (struct s3c2410_dma_client *)&sec_dai->dma_playback; + /* Use iDMA always if SysDMA not provided */ + sec_dai->dma_playback.channel = dma_pl_sec_chan ? : -1; + sec_dai->src_clk = i2s_cfg->src_clk; + sec_dai->dma_playback.dma_size = 4; + sec_dai->base = regs_base; + sec_dai->quirks = quirks; + sec_dai->pri_dai = pri_dai; + pri_dai->sec_dai = sec_dai; + } + + if (i2s_pdata->cfg_gpio && i2s_pdata->cfg_gpio(pdev)) { + dev_err(&pdev->dev, "Unable to configure gpio\n"); + ret = -EINVAL; + goto err3; + } + + snd_soc_register_dai(&pri_dai->pdev->dev, &pri_dai->i2s_dai_drv); + + return 0; +err3: + kfree(sec_dai); +err2: + kfree(pri_dai); +err1: + release_mem_region(regs_base, resource_size(res)); + + return ret; +} + +static __devexit int samsung_i2s_remove(struct platform_device *pdev) +{ + struct i2s_dai *i2s, *other; + + i2s = dev_get_drvdata(&pdev->dev); + other = i2s->pri_dai ? : i2s->sec_dai; + + if (other) { + other->pri_dai = NULL; + other->sec_dai = NULL; + } else { + struct resource *res; + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (res) + release_mem_region(res->start, resource_size(res)); + } + + i2s->pri_dai = NULL; + i2s->sec_dai = NULL; + + kfree(i2s); + + snd_soc_unregister_dai(&pdev->dev); + + return 0; +} + +static struct platform_driver samsung_i2s_driver = { + .probe = samsung_i2s_probe, + .remove = samsung_i2s_remove, + .driver = { + .name = "samsung-i2s", + .owner = THIS_MODULE, + }, +}; + +static int __init samsung_i2s_init(void) +{ + return platform_driver_register(&samsung_i2s_driver); +} +module_init(samsung_i2s_init); + +static void __exit samsung_i2s_exit(void) +{ + platform_driver_unregister(&samsung_i2s_driver); +} +module_exit(samsung_i2s_exit); + +/* Module information */ +MODULE_AUTHOR("Jaswinder Singh, "); +MODULE_DESCRIPTION("Samsung I2S Interface"); +MODULE_ALIAS("platform:samsung-i2s"); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/s3c24xx/i2s.h b/sound/soc/s3c24xx/i2s.h new file mode 100644 index 000000000000..d3180b37dc10 --- /dev/null +++ b/sound/soc/s3c24xx/i2s.h @@ -0,0 +1,29 @@ +/* sound/soc/s3c24xx/i2s.h + * + * ALSA SoC Audio Layer - Samsung I2S Controller driver + * + * Copyright (c) 2010 Samsung Electronics Co. Ltd. + * Jaswinder Singh + * + * 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. + */ + +#ifndef __SND_SOC_SAMSUNG_I2S_H +#define __SND_SOC_SAMSUNG_I2S_H + +/* + * Maximum number of I2S blocks that any SoC can have. + * The secondary interface of a CPU dai(if there exists any), + * is indexed at [cpu-dai's ID + SAMSUNG_I2S_SECOFF] + */ +#define SAMSUNG_I2S_SECOFF 4 + +#define SAMSUNG_I2S_DIV_BCLK 1 + +#define SAMSUNG_I2S_RCLKSRC_0 0 +#define SAMSUNG_I2S_RCLKSRC_1 1 +#define SAMSUNG_I2S_CDCLK 2 + +#endif /* __SND_SOC_SAMSUNG_I2S_H */ -- cgit v1.2.3 From b9493d6c3308b6bd0867d7175df03b111cda1afc Mon Sep 17 00:00:00 2001 From: Jassi Brar Date: Mon, 22 Nov 2010 15:37:02 +0900 Subject: ASoC: SMARTQ: Move to use new I2S driver Modify the smartq_wm8987.c to use new i2s controller driver. Signed-off-by: Jassi Brar Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/s3c24xx/Kconfig | 2 +- sound/soc/s3c24xx/smartq_wm8987.c | 25 +++++++++++-------------- 2 files changed, 12 insertions(+), 15 deletions(-) diff --git a/sound/soc/s3c24xx/Kconfig b/sound/soc/s3c24xx/Kconfig index ec870baf6d7a..3b9736bd7a7e 100644 --- a/sound/soc/s3c24xx/Kconfig +++ b/sound/soc/s3c24xx/Kconfig @@ -145,7 +145,7 @@ config SND_SOC_SMDK_WM9713 config SND_S3C64XX_SOC_SMARTQ tristate "SoC I2S Audio support for SmartQ board" depends on SND_S3C24XX_SOC && MACH_SMARTQ - select SND_S3C64XX_SOC_I2S + select SND_SAMSUNG_I2S select SND_SOC_WM8750 config SND_SOC_GONI_AQUILA_WM8994 diff --git a/sound/soc/s3c24xx/smartq_wm8987.c b/sound/soc/s3c24xx/smartq_wm8987.c index 968902e8e469..bcb69820f1cc 100644 --- a/sound/soc/s3c24xx/smartq_wm8987.c +++ b/sound/soc/s3c24xx/smartq_wm8987.c @@ -25,7 +25,7 @@ #include #include "dma.h" -#include "s3c64xx-i2s.h" +#include "i2s.h" #include "../codecs/wm8750.h" @@ -41,13 +41,9 @@ static int smartq_hifi_hw_params(struct snd_pcm_substream *substream, struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; - struct s3c_i2sv2_rate_calc div; unsigned int clk = 0; int ret; - s3c_i2sv2_iis_calc_rate(&div, NULL, params_rate(params), - s3c_i2sv2_get_clock(cpu_dai)); - switch (params_rate(params)) { case 8000: case 16000: @@ -78,20 +74,21 @@ static int smartq_hifi_hw_params(struct snd_pcm_substream *substream, if (ret < 0) return ret; - /* set the codec system clock for DAC and ADC */ - ret = snd_soc_dai_set_sysclk(codec_dai, WM8750_SYSCLK, clk, - SND_SOC_CLOCK_IN); + /* Use PCLK for I2S signal generation */ + ret = snd_soc_dai_set_sysclk(cpu_dai, SAMSUNG_I2S_RCLKSRC_0, + 0, SND_SOC_CLOCK_IN); if (ret < 0) return ret; - /* set MCLK division for sample rate */ - ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C_I2SV2_DIV_RCLK, div.fs_div); + /* Gate the RCLK output on PAD */ + ret = snd_soc_dai_set_sysclk(cpu_dai, SAMSUNG_I2S_CDCLK, + 0, SND_SOC_CLOCK_IN); if (ret < 0) return ret; - /* set prescaler division for sample rate */ - ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C_I2SV2_DIV_PRESCALER, - div.clk_div - 1); + /* set the codec system clock for DAC and ADC */ + ret = snd_soc_dai_set_sysclk(codec_dai, WM8750_SYSCLK, clk, + SND_SOC_CLOCK_IN); if (ret < 0) return ret; @@ -212,7 +209,7 @@ static struct snd_soc_dai_link smartq_dai[] = { { .name = "wm8987", .stream_name = "SmartQ Hi-Fi", - .cpu_dai_name = "s3c64xx-i2s.0", + .cpu_dai_name = "samsung-i2s.0", .codec_dai_name = "wm8750-hifi", .platform_name = "samsung-audio", .codec_name = "wm8750-codec.0-0x1a", -- cgit v1.2.3 From fcd8c742b92d834dee804b2a394cc575dd3a4084 Mon Sep 17 00:00:00 2001 From: Jassi Brar Date: Mon, 22 Nov 2010 15:37:04 +0900 Subject: ASoC: GONI: Move to use new I2S driver Modify the goni_wm8994.c to use new i2s controller driver. Signed-off-by: Jassi Brar Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/s3c24xx/Kconfig | 2 +- sound/soc/s3c24xx/goni_wm8994.c | 10 ++-------- 2 files changed, 3 insertions(+), 9 deletions(-) diff --git a/sound/soc/s3c24xx/Kconfig b/sound/soc/s3c24xx/Kconfig index 3b9736bd7a7e..749f630475eb 100644 --- a/sound/soc/s3c24xx/Kconfig +++ b/sound/soc/s3c24xx/Kconfig @@ -151,7 +151,7 @@ config SND_S3C64XX_SOC_SMARTQ config SND_SOC_GONI_AQUILA_WM8994 tristate "SoC I2S Audio support for AQUILA/GONI - WM8994" depends on SND_S3C24XX_SOC && (MACH_GONI || MACH_AQUILA) - select SND_S3C64XX_SOC_I2S_V4 + select SND_SAMSUNG_I2S select SND_SOC_WM8994 help Say Y if you want to add support for SoC audio on goni or aquila diff --git a/sound/soc/s3c24xx/goni_wm8994.c b/sound/soc/s3c24xx/goni_wm8994.c index 0badcc56e93c..dcfac546cb81 100644 --- a/sound/soc/s3c24xx/goni_wm8994.c +++ b/sound/soc/s3c24xx/goni_wm8994.c @@ -25,7 +25,7 @@ #include #include "../codecs/wm8994.h" #include "dma.h" -#include "s3c64xx-i2s.h" +#include "i2s.h" #define MACHINE_NAME 0 #define CPU_VOICE_DAI 1 @@ -163,12 +163,6 @@ static int goni_hifi_hw_params(struct snd_pcm_substream *substream, if (ret < 0) return ret; - /* set the cpu system clock */ - ret = snd_soc_dai_set_sysclk(cpu_dai, S3C64XX_CLKSRC_PCLK, - 0, SND_SOC_CLOCK_IN); - if (ret < 0) - return ret; - /* set codec DAI configuration */ ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM); @@ -249,7 +243,7 @@ static struct snd_soc_dai_link goni_dai[] = { { .name = "WM8994", .stream_name = "WM8994 HiFi", - .cpu_dai_name = "s3c64xx-i2s-v4", + .cpu_dai_name = "samsung-i2s.0", .codec_dai_name = "wm8994-hifi", .platform_name = "samsung-audio", .codec_name = "wm8994-codec.0-0x1a", -- cgit v1.2.3 From 0fff21a86c1ada9e9eba0d11fb91797bf2c73d46 Mon Sep 17 00:00:00 2001 From: Jassi Brar Date: Mon, 22 Nov 2010 15:37:07 +0900 Subject: ASoC: SMDK64XX: Move to use new I2S driver Modify the smdk64xx_wm8580.c to use new i2s controller driver. Signed-off-by: Jassi Brar Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/s3c24xx/Kconfig | 2 +- sound/soc/s3c24xx/smdk64xx_wm8580.c | 25 +++---------------------- 2 files changed, 4 insertions(+), 23 deletions(-) diff --git a/sound/soc/s3c24xx/Kconfig b/sound/soc/s3c24xx/Kconfig index 749f630475eb..597626389e81 100644 --- a/sound/soc/s3c24xx/Kconfig +++ b/sound/soc/s3c24xx/Kconfig @@ -74,7 +74,7 @@ config SND_S3C64XX_SOC_WM8580 tristate "SoC I2S Audio support for WM8580 on SMDK64XX" depends on SND_S3C24XX_SOC && MACH_SMDK6410 select SND_SOC_WM8580 - select SND_S3C64XX_SOC_I2S_V4 + select SND_SAMSUNG_I2S help Say Y if you want to add support for SoC audio on the SMDK6410. diff --git a/sound/soc/s3c24xx/smdk64xx_wm8580.c b/sound/soc/s3c24xx/smdk64xx_wm8580.c index 095379126435..1b3a97697cbf 100644 --- a/sound/soc/s3c24xx/smdk64xx_wm8580.c +++ b/sound/soc/s3c24xx/smdk64xx_wm8580.c @@ -19,7 +19,7 @@ #include "../codecs/wm8580.h" #include "dma.h" -#include "s3c64xx-i2s.h" +#include "i2s.h" /* * Default CFG switch settings to use this driver: @@ -95,17 +95,6 @@ static int smdk64xx_hw_params(struct snd_pcm_substream *substream, if (ret < 0) return ret; - ret = snd_soc_dai_set_sysclk(cpu_dai, S3C64XX_CLKSRC_CDCLK, - 0, SND_SOC_CLOCK_IN); - if (ret < 0) - return ret; - - /* We use PCLK for basic ops in SoC-Slave mode */ - ret = snd_soc_dai_set_sysclk(cpu_dai, S3C64XX_CLKSRC_PCLK, - 0, SND_SOC_CLOCK_IN); - if (ret < 0) - return ret; - /* Set WM8580 to drive MCLK from its PLLA */ ret = snd_soc_dai_set_clkdiv(codec_dai, WM8580_MCLK, WM8580_CLKSRC_PLLA); @@ -122,14 +111,6 @@ static int smdk64xx_hw_params(struct snd_pcm_substream *substream, if (ret < 0) return ret; - ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C_I2SV2_DIV_BCLK, bfs); - if (ret < 0) - return ret; - - ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C_I2SV2_DIV_RCLK, rfs); - if (ret < 0) - return ret; - return 0; } @@ -223,7 +204,7 @@ static struct snd_soc_dai_link smdk64xx_dai[] = { { /* Primary Playback i/f */ .name = "WM8580 PAIF RX", .stream_name = "Playback", - .cpu_dai_name = "samsung-i2s-v4", + .cpu_dai_name = "samsung-i2s.2", .codec_dai_name = "wm8580-hifi-playback", .platform_name = "samsung-audio", .codec_name = "wm8580-codec.0-001b", @@ -233,7 +214,7 @@ static struct snd_soc_dai_link smdk64xx_dai[] = { { /* Primary Capture i/f */ .name = "WM8580 PAIF TX", .stream_name = "Capture", - .cpu_dai_name = "samsung-i2s-v4", + .cpu_dai_name = "samsung-i2s.2", .codec_dai_name = "wm8580-hifi-capture", .platform_name = "samsung-audio", .codec_name = "wm8580-codec.0-001b", -- cgit v1.2.3 From 03e6a88897f923ae2608569e66afba4766e1abf7 Mon Sep 17 00:00:00 2001 From: Jassi Brar Date: Mon, 22 Nov 2010 15:37:13 +0900 Subject: ASoC: S3C64XX: Remove obsoleted I2S drivers Now that we have better I2S CPU drivers and no need for the old ones, discard them. Signed-off-by: Jassi Brar Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/s3c24xx/Kconfig | 10 -- sound/soc/s3c24xx/Makefile | 4 - sound/soc/s3c24xx/s3c64xx-i2s-v4.c | 230 ----------------------------------- sound/soc/s3c24xx/s3c64xx-i2s.c | 242 ------------------------------------- sound/soc/s3c24xx/s3c64xx-i2s.h | 41 ------- 5 files changed, 527 deletions(-) delete mode 100644 sound/soc/s3c24xx/s3c64xx-i2s-v4.c delete mode 100644 sound/soc/s3c24xx/s3c64xx-i2s.c delete mode 100644 sound/soc/s3c24xx/s3c64xx-i2s.h diff --git a/sound/soc/s3c24xx/Kconfig b/sound/soc/s3c24xx/Kconfig index 597626389e81..15f5f9103a0c 100644 --- a/sound/soc/s3c24xx/Kconfig +++ b/sound/soc/s3c24xx/Kconfig @@ -20,16 +20,6 @@ config SND_S3C2412_SOC_I2S select SND_S3C_I2SV2_SOC select S3C2410_DMA -config SND_S3C64XX_SOC_I2S - tristate - select SND_S3C_I2SV2_SOC - select S3C64XX_DMA - -config SND_S3C64XX_SOC_I2S_V4 - tristate - select SND_S3C_I2SV2_SOC - select S3C64XX_DMA - config SND_S3C_SOC_PCM tristate diff --git a/sound/soc/s3c24xx/Makefile b/sound/soc/s3c24xx/Makefile index 1d6fc0736102..dac41eefafc4 100644 --- a/sound/soc/s3c24xx/Makefile +++ b/sound/soc/s3c24xx/Makefile @@ -2,9 +2,7 @@ snd-soc-s3c24xx-objs := dma.o snd-soc-s3c24xx-i2s-objs := s3c24xx-i2s.o snd-soc-s3c2412-i2s-objs := s3c2412-i2s.o -snd-soc-s3c64xx-i2s-objs := s3c64xx-i2s.o snd-soc-ac97-objs := ac97.o -snd-soc-s3c64xx-i2s-v4-objs := s3c64xx-i2s-v4.o snd-soc-s3c-i2s-v2-objs := s3c-i2s-v2.o snd-soc-samsung-spdif-objs := spdif.o snd-soc-pcm-objs := pcm.o @@ -14,8 +12,6 @@ obj-$(CONFIG_SND_S3C24XX_SOC) += snd-soc-s3c24xx.o obj-$(CONFIG_SND_S3C24XX_SOC_I2S) += snd-soc-s3c24xx-i2s.o obj-$(CONFIG_SND_S3C_SOC_AC97) += snd-soc-ac97.o obj-$(CONFIG_SND_S3C2412_SOC_I2S) += snd-soc-s3c2412-i2s.o -obj-$(CONFIG_SND_S3C64XX_SOC_I2S) += snd-soc-s3c64xx-i2s.o -obj-$(CONFIG_SND_S3C64XX_SOC_I2S_V4) += snd-soc-s3c64xx-i2s-v4.o obj-$(CONFIG_SND_S3C_I2SV2_SOC) += snd-soc-s3c-i2s-v2.o obj-$(CONFIG_SND_S5P_SOC_SPDIF) += snd-soc-samsung-spdif.o obj-$(CONFIG_SND_S3C_SOC_PCM) += snd-soc-pcm.o diff --git a/sound/soc/s3c24xx/s3c64xx-i2s-v4.c b/sound/soc/s3c24xx/s3c64xx-i2s-v4.c deleted file mode 100644 index 8a080416ce85..000000000000 --- a/sound/soc/s3c24xx/s3c64xx-i2s-v4.c +++ /dev/null @@ -1,230 +0,0 @@ -/* sound/soc/s3c24xx/s3c64xx-i2s-v4.c - * - * ALSA SoC Audio Layer - S3C64XX I2Sv4 driver - * Copyright (c) 2010 Samsung Electronics Co. Ltd - * Author: Jaswinder Singh - * - * 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 -#include - -#include - -#include -#include - -#include "dma.h" -#include "regs-i2s-v2.h" -#include "s3c64xx-i2s.h" - -static struct s3c2410_dma_client s3c64xx_dma_client_out = { - .name = "I2Sv4 PCM Stereo out" -}; - -static struct s3c2410_dma_client s3c64xx_dma_client_in = { - .name = "I2Sv4 PCM Stereo in" -}; - -static struct s3c_dma_params s3c64xx_i2sv4_pcm_stereo_out; -static struct s3c_dma_params s3c64xx_i2sv4_pcm_stereo_in; -static struct s3c_i2sv2_info s3c64xx_i2sv4; - -static int s3c64xx_i2sv4_probe(struct snd_soc_dai *dai) -{ - struct s3c_i2sv2_info *i2s = &s3c64xx_i2sv4; - int ret = 0; - - snd_soc_dai_set_drvdata(dai, i2s); - - ret = s3c_i2sv2_probe(dai, i2s, i2s->base); - - return ret; -} - -static int s3c_i2sv4_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params, - struct snd_soc_dai *cpu_dai) -{ - struct s3c_i2sv2_info *i2s = snd_soc_dai_get_drvdata(cpu_dai); - struct s3c_dma_params *dma_data; - u32 iismod; - - dev_dbg(cpu_dai->dev, "Entered %s\n", __func__); - - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - dma_data = i2s->dma_playback; - else - dma_data = i2s->dma_capture; - - snd_soc_dai_set_dma_data(cpu_dai, substream, dma_data); - - iismod = readl(i2s->regs + S3C2412_IISMOD); - dev_dbg(cpu_dai->dev, "%s: r: IISMOD: %x\n", __func__, iismod); - - iismod &= ~S3C64XX_IISMOD_BLC_MASK; - switch (params_format(params)) { - case SNDRV_PCM_FORMAT_S8: - iismod |= S3C64XX_IISMOD_BLC_8BIT; - break; - case SNDRV_PCM_FORMAT_S16_LE: - break; - case SNDRV_PCM_FORMAT_S24_LE: - iismod |= S3C64XX_IISMOD_BLC_24BIT; - break; - } - - writel(iismod, i2s->regs + S3C2412_IISMOD); - dev_dbg(cpu_dai->dev, "%s: w: IISMOD: %x\n", __func__, iismod); - - return 0; -} - -static struct snd_soc_dai_ops s3c64xx_i2sv4_dai_ops = { - .hw_params = s3c_i2sv4_hw_params, -}; - -static struct snd_soc_dai_driver s3c64xx_i2s_v4_dai = { - .symmetric_rates = 1, - .playback = { - .channels_min = 2, - .channels_max = 2, - .rates = S3C64XX_I2S_RATES, - .formats = S3C64XX_I2S_FMTS, - }, - .capture = { - .channels_min = 2, - .channels_max = 2, - .rates = S3C64XX_I2S_RATES, - .formats = S3C64XX_I2S_FMTS, - }, - .probe = s3c64xx_i2sv4_probe, - .ops = &s3c64xx_i2sv4_dai_ops, -}; - -static __devinit int s3c64xx_i2sv4_dev_probe(struct platform_device *pdev) -{ - struct s3c_audio_pdata *i2s_pdata; - struct s3c_i2sv2_info *i2s; - struct resource *res; - int ret; - - i2s = &s3c64xx_i2sv4; - - i2s->feature |= S3C_FEATURE_CDCLKCON; - - i2s->dma_capture = &s3c64xx_i2sv4_pcm_stereo_in; - i2s->dma_playback = &s3c64xx_i2sv4_pcm_stereo_out; - - res = platform_get_resource(pdev, IORESOURCE_DMA, 0); - if (!res) { - dev_err(&pdev->dev, "Unable to get I2S-TX dma resource\n"); - return -ENXIO; - } - i2s->dma_playback->channel = res->start; - - res = platform_get_resource(pdev, IORESOURCE_DMA, 1); - if (!res) { - dev_err(&pdev->dev, "Unable to get I2S-RX dma resource\n"); - return -ENXIO; - } - i2s->dma_capture->channel = res->start; - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - dev_err(&pdev->dev, "Unable to get I2S SFR address\n"); - return -ENXIO; - } - - if (!request_mem_region(res->start, resource_size(res), - "s3c64xx-i2s-v4")) { - dev_err(&pdev->dev, "Unable to request SFR region\n"); - return -EBUSY; - } - i2s->dma_capture->dma_addr = res->start + S3C2412_IISRXD; - i2s->dma_playback->dma_addr = res->start + S3C2412_IISTXD; - - i2s->dma_capture->client = &s3c64xx_dma_client_in; - i2s->dma_capture->dma_size = 4; - i2s->dma_playback->client = &s3c64xx_dma_client_out; - i2s->dma_playback->dma_size = 4; - - i2s->base = res->start; - - i2s_pdata = pdev->dev.platform_data; - if (i2s_pdata && i2s_pdata->cfg_gpio && i2s_pdata->cfg_gpio(pdev)) { - dev_err(&pdev->dev, "Unable to configure gpio\n"); - return -EINVAL; - } - - i2s->iis_cclk = clk_get(&pdev->dev, "audio-bus"); - if (IS_ERR(i2s->iis_cclk)) { - dev_err(&pdev->dev, "failed to get audio-bus\n"); - ret = PTR_ERR(i2s->iis_cclk); - goto err; - } - - clk_enable(i2s->iis_cclk); - - ret = s3c_i2sv2_register_dai(&pdev->dev, pdev->id, &s3c64xx_i2s_v4_dai); - if (ret != 0) - goto err_i2sv2; - - return 0; - -err_i2sv2: - clk_put(i2s->iis_cclk); -err: - return ret; -} - -static __devexit int s3c64xx_i2sv4_dev_remove(struct platform_device *pdev) -{ - struct s3c_i2sv2_info *i2s = &s3c64xx_i2sv4; - struct resource *res; - - snd_soc_unregister_dai(&pdev->dev); - clk_put(i2s->iis_cclk); - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (res) - release_mem_region(res->start, resource_size(res)); - else - dev_warn(&pdev->dev, "Unable to get I2S SFR address\n"); - - return 0; -} - -static struct platform_driver s3c64xx_i2sv4_driver = { - .probe = s3c64xx_i2sv4_dev_probe, - .remove = s3c64xx_i2sv4_dev_remove, - .driver = { - .name = "samsung-i2s-v4", - .owner = THIS_MODULE, - }, -}; - -static int __init s3c64xx_i2sv4_init(void) -{ - return platform_driver_register(&s3c64xx_i2sv4_driver); -} -module_init(s3c64xx_i2sv4_init); - -static void __exit s3c64xx_i2sv4_exit(void) -{ - platform_driver_unregister(&s3c64xx_i2sv4_driver); -} -module_exit(s3c64xx_i2sv4_exit); - -/* Module information */ -MODULE_AUTHOR("Jaswinder Singh, "); -MODULE_DESCRIPTION("S3C64XX I2Sv4 SoC Interface"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:samsung-i2s-v4"); diff --git a/sound/soc/s3c24xx/s3c64xx-i2s.c b/sound/soc/s3c24xx/s3c64xx-i2s.c deleted file mode 100644 index 0fefbb545947..000000000000 --- a/sound/soc/s3c24xx/s3c64xx-i2s.c +++ /dev/null @@ -1,242 +0,0 @@ -/* sound/soc/s3c24xx/s3c64xx-i2s.c - * - * ALSA SoC Audio Layer - S3C64XX I2S driver - * - * Copyright 2008 Openmoko, Inc. - * Copyright 2008 Simtec Electronics - * Ben Dooks - * http://armlinux.simtec.co.uk/ - * - * 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 -#include - -#include - -#include - -#include -#include - -#include "dma.h" -#include "regs-i2s-v2.h" -#include "s3c64xx-i2s.h" - -/* The value should be set to maximum of the total number - * of I2Sv3 controllers that any supported SoC has. - */ -#define MAX_I2SV3 2 - -static struct s3c2410_dma_client s3c64xx_dma_client_out = { - .name = "I2S PCM Stereo out" -}; - -static struct s3c2410_dma_client s3c64xx_dma_client_in = { - .name = "I2S PCM Stereo in" -}; - -static struct s3c_dma_params s3c64xx_i2s_pcm_stereo_out[MAX_I2SV3]; -static struct s3c_dma_params s3c64xx_i2s_pcm_stereo_in[MAX_I2SV3]; -static struct s3c_i2sv2_info s3c64xx_i2s[MAX_I2SV3]; - -struct clk *s3c64xx_i2s_get_clock(struct snd_soc_dai *dai) -{ - struct s3c_i2sv2_info *i2s = snd_soc_dai_get_drvdata(dai); - u32 iismod = readl(i2s->regs + S3C2412_IISMOD); - - if (iismod & S3C2412_IISMOD_IMS_SYSMUX) - return i2s->iis_cclk; - else - return i2s->iis_pclk; -} -EXPORT_SYMBOL_GPL(s3c64xx_i2s_get_clock); - -static int s3c64xx_i2s_probe(struct snd_soc_dai *dai) -{ - struct s3c_i2sv2_info *i2s; - int ret; - - if (dai->id >= MAX_I2SV3) { - dev_err(dai->dev, "id %d out of range\n", dai->id); - return -EINVAL; - } - - i2s = &s3c64xx_i2s[dai->id]; - snd_soc_dai_set_drvdata(dai, i2s); - - i2s->iis_cclk = clk_get(dai->dev, "audio-bus"); - if (IS_ERR(i2s->iis_cclk)) { - dev_err(dai->dev, "failed to get audio-bus\n"); - ret = PTR_ERR(i2s->iis_cclk); - goto err; - } - - clk_enable(i2s->iis_cclk); - - ret = s3c_i2sv2_probe(dai, i2s, i2s->base); - if (ret) - goto err_clk; - - return 0; - -err_clk: - clk_disable(i2s->iis_cclk); - clk_put(i2s->iis_cclk); -err: - kfree(i2s); - return ret; -} - -static int s3c64xx_i2s_remove(struct snd_soc_dai *dai) -{ - struct s3c_i2sv2_info *i2s = snd_soc_dai_get_drvdata(dai); - - clk_disable(i2s->iis_cclk); - clk_put(i2s->iis_cclk); - kfree(i2s); - return 0; -} - -static struct snd_soc_dai_ops s3c64xx_i2s_dai_ops; - -static struct snd_soc_dai_driver s3c64xx_i2s_dai[MAX_I2SV3] = { -{ - .name = "s3c64xx-i2s-0", - .probe = s3c64xx_i2s_probe, - .remove = s3c64xx_i2s_remove, - .playback = { - .channels_min = 2, - .channels_max = 2, - .rates = S3C64XX_I2S_RATES, - .formats = S3C64XX_I2S_FMTS,}, - .capture = { - .channels_min = 2, - .channels_max = 2, - .rates = S3C64XX_I2S_RATES, - .formats = S3C64XX_I2S_FMTS,}, - .ops = &s3c64xx_i2s_dai_ops, - .symmetric_rates = 1, -}, { - .name = "s3c64xx-i2s-1", - .probe = s3c64xx_i2s_probe, - .remove = s3c64xx_i2s_remove, - .playback = { - .channels_min = 2, - .channels_max = 2, - .rates = S3C64XX_I2S_RATES, - .formats = S3C64XX_I2S_FMTS,}, - .capture = { - .channels_min = 2, - .channels_max = 2, - .rates = S3C64XX_I2S_RATES, - .formats = S3C64XX_I2S_FMTS,}, - .ops = &s3c64xx_i2s_dai_ops, - .symmetric_rates = 1, -},}; - -static __devinit int s3c64xx_iis_dev_probe(struct platform_device *pdev) -{ - struct s3c_audio_pdata *i2s_pdata; - struct s3c_i2sv2_info *i2s; - struct resource *res; - int i, ret; - - if (pdev->id >= MAX_I2SV3) { - dev_err(&pdev->dev, "id %d out of range\n", pdev->id); - return -EINVAL; - } - - i2s = &s3c64xx_i2s[pdev->id]; - - i2s->dma_capture = &s3c64xx_i2s_pcm_stereo_in[pdev->id]; - i2s->dma_playback = &s3c64xx_i2s_pcm_stereo_out[pdev->id]; - - res = platform_get_resource(pdev, IORESOURCE_DMA, 0); - if (!res) { - dev_err(&pdev->dev, "Unable to get I2S-TX dma resource\n"); - return -ENXIO; - } - i2s->dma_playback->channel = res->start; - - res = platform_get_resource(pdev, IORESOURCE_DMA, 1); - if (!res) { - dev_err(&pdev->dev, "Unable to get I2S-RX dma resource\n"); - return -ENXIO; - } - i2s->dma_capture->channel = res->start; - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - dev_err(&pdev->dev, "Unable to get I2S SFR address\n"); - return -ENXIO; - } - - if (!request_mem_region(res->start, resource_size(res), - "s3c64xx-i2s")) { - dev_err(&pdev->dev, "Unable to request SFR region\n"); - return -EBUSY; - } - i2s->base = res->start; - - i2s_pdata = pdev->dev.platform_data; - if (i2s_pdata && i2s_pdata->cfg_gpio && i2s_pdata->cfg_gpio(pdev)) { - dev_err(&pdev->dev, "Unable to configure gpio\n"); - return -EINVAL; - } - i2s->dma_capture->dma_addr = res->start + S3C2412_IISRXD; - i2s->dma_playback->dma_addr = res->start + S3C2412_IISTXD; - - i2s->dma_capture->client = &s3c64xx_dma_client_in; - i2s->dma_capture->dma_size = 4; - i2s->dma_playback->client = &s3c64xx_dma_client_out; - i2s->dma_playback->dma_size = 4; - - for (i = 0; i < ARRAY_SIZE(s3c64xx_i2s_dai); i++) { - ret = s3c_i2sv2_register_dai(&pdev->dev, i, - &s3c64xx_i2s_dai[i]); - if (ret != 0) - return ret; - } - - return 0; -} - -static __devexit int s3c64xx_iis_dev_remove(struct platform_device *pdev) -{ - snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(s3c64xx_i2s_dai)); - return 0; -} - -static struct platform_driver s3c64xx_iis_driver = { - .probe = s3c64xx_iis_dev_probe, - .remove = s3c64xx_iis_dev_remove, - .driver = { - .name = "samsung-i2s", - .owner = THIS_MODULE, - }, -}; - -static int __init s3c64xx_i2s_init(void) -{ - return platform_driver_register(&s3c64xx_iis_driver); -} -module_init(s3c64xx_i2s_init); - -static void __exit s3c64xx_i2s_exit(void) -{ - platform_driver_unregister(&s3c64xx_iis_driver); -} -module_exit(s3c64xx_i2s_exit); - -/* Module information */ -MODULE_AUTHOR("Ben Dooks, "); -MODULE_DESCRIPTION("S3C64XX I2S SoC Interface"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:samsung-i2s"); diff --git a/sound/soc/s3c24xx/s3c64xx-i2s.h b/sound/soc/s3c24xx/s3c64xx-i2s.h deleted file mode 100644 index de4075d26f0c..000000000000 --- a/sound/soc/s3c24xx/s3c64xx-i2s.h +++ /dev/null @@ -1,41 +0,0 @@ -/* sound/soc/s3c24xx/s3c64xx-i2s.h - * - * ALSA SoC Audio Layer - S3C64XX I2S driver - * - * Copyright 2008 Openmoko, Inc. - * Copyright 2008 Simtec Electronics - * Ben Dooks - * http://armlinux.simtec.co.uk/ - * - * 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. - */ - -#ifndef __SND_SOC_S3C24XX_S3C64XX_I2S_H -#define __SND_SOC_S3C24XX_S3C64XX_I2S_H __FILE__ - -struct clk; - -#include "s3c-i2s-v2.h" - -#define S3C64XX_DIV_BCLK S3C_I2SV2_DIV_BCLK -#define S3C64XX_DIV_RCLK S3C_I2SV2_DIV_RCLK -#define S3C64XX_DIV_PRESCALER S3C_I2SV2_DIV_PRESCALER - -#define S3C64XX_CLKSRC_PCLK S3C_I2SV2_CLKSRC_PCLK -#define S3C64XX_CLKSRC_MUX S3C_I2SV2_CLKSRC_AUDIOBUS -#define S3C64XX_CLKSRC_CDCLK S3C_I2SV2_CLKSRC_CDCLK - -#define S3C64XX_I2S_RATES \ - (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | SNDRV_PCM_RATE_16000 | \ - SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \ - SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000) - -#define S3C64XX_I2S_FMTS \ - (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE |\ - SNDRV_PCM_FMTBIT_S24_LE) - -struct clk *s3c64xx_i2s_get_clock(struct snd_soc_dai *dai); - -#endif /* __SND_SOC_S3C24XX_S3C64XX_I2S_H */ -- cgit v1.2.3 From d98ce6cf0303dc8edc9fdc18f84e4d7dafbb61a2 Mon Sep 17 00:00:00 2001 From: Jassi Brar Date: Mon, 22 Nov 2010 15:37:16 +0900 Subject: ASoC: SMDK64XX: Rename for other platforms We plan to use the same ASoC Machine driver for most of latest SMDK platforms. So rename the 64XX specific driver to generic named. Signed-off-by: Jassi Brar Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/s3c24xx/Kconfig | 6 +- sound/soc/s3c24xx/Makefile | 4 +- sound/soc/s3c24xx/smdk64xx_wm8580.c | 254 ------------------------------------ sound/soc/s3c24xx/smdk_wm8580.c | 254 ++++++++++++++++++++++++++++++++++++ 4 files changed, 259 insertions(+), 259 deletions(-) delete mode 100644 sound/soc/s3c24xx/smdk64xx_wm8580.c create mode 100644 sound/soc/s3c24xx/smdk_wm8580.c diff --git a/sound/soc/s3c24xx/Kconfig b/sound/soc/s3c24xx/Kconfig index 15f5f9103a0c..396f678d1af5 100644 --- a/sound/soc/s3c24xx/Kconfig +++ b/sound/soc/s3c24xx/Kconfig @@ -60,13 +60,13 @@ config SND_S3C24XX_SOC_JIVE_WM8750 help Sat Y if you want to add support for SoC audio on the Jive. -config SND_S3C64XX_SOC_WM8580 - tristate "SoC I2S Audio support for WM8580 on SMDK64XX" +config SND_SOC_SMDK_WM8580 + tristate "SoC I2S Audio support for WM8580 on SMDK" depends on SND_S3C24XX_SOC && MACH_SMDK6410 select SND_SOC_WM8580 select SND_SAMSUNG_I2S help - Say Y if you want to add support for SoC audio on the SMDK6410. + Say Y if you want to add support for SoC audio on the SMDKs. config SND_S3C24XX_SOC_SMDK2443_WM9710 tristate "SoC AC97 Audio support for SMDK2443 - WM9710" diff --git a/sound/soc/s3c24xx/Makefile b/sound/soc/s3c24xx/Makefile index dac41eefafc4..7eee57fe0d61 100644 --- a/sound/soc/s3c24xx/Makefile +++ b/sound/soc/s3c24xx/Makefile @@ -28,7 +28,7 @@ snd-soc-s3c24xx-simtec-objs := s3c24xx_simtec.o snd-soc-s3c24xx-simtec-hermes-objs := s3c24xx_simtec_hermes.o snd-soc-s3c24xx-simtec-tlv320aic23-objs := s3c24xx_simtec_tlv320aic23.o snd-soc-rx1950-uda1380-objs := rx1950_uda1380.o -snd-soc-smdk64xx-wm8580-objs := smdk64xx_wm8580.o +snd-soc-smdk-wm8580-objs := smdk_wm8580.o snd-soc-smdk-wm9713-objs := smdk_wm9713.o snd-soc-s3c64xx-smartq-wm8987-objs := smartq_wm8987.o snd-soc-goni-wm8994-objs := goni_wm8994.o @@ -44,7 +44,7 @@ obj-$(CONFIG_SND_S3C24XX_SOC_SIMTEC) += snd-soc-s3c24xx-simtec.o obj-$(CONFIG_SND_S3C24XX_SOC_SIMTEC_HERMES) += snd-soc-s3c24xx-simtec-hermes.o obj-$(CONFIG_SND_S3C24XX_SOC_SIMTEC_TLV320AIC23) += snd-soc-s3c24xx-simtec-tlv320aic23.o obj-$(CONFIG_SND_S3C24XX_SOC_RX1950_UDA1380) += snd-soc-rx1950-uda1380.o -obj-$(CONFIG_SND_S3C64XX_SOC_WM8580) += snd-soc-smdk64xx-wm8580.o +obj-$(CONFIG_SND_SOC_SMDK_WM8580) += snd-soc-smdk-wm8580.o obj-$(CONFIG_SND_SOC_SMDK_WM9713) += snd-soc-smdk-wm9713.o obj-$(CONFIG_SND_S3C64XX_SOC_SMARTQ) += snd-soc-s3c64xx-smartq-wm8987.o obj-$(CONFIG_SND_SOC_SMDK_SPDIF) += snd-soc-smdk-spdif.o diff --git a/sound/soc/s3c24xx/smdk64xx_wm8580.c b/sound/soc/s3c24xx/smdk64xx_wm8580.c deleted file mode 100644 index 1b3a97697cbf..000000000000 --- a/sound/soc/s3c24xx/smdk64xx_wm8580.c +++ /dev/null @@ -1,254 +0,0 @@ -/* - * smdk64xx_wm8580.c - * - * Copyright (c) 2009 Samsung Electronics Co. Ltd - * Author: Jaswinder Singh - * - * 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. - */ - -#include -#include -#include -#include -#include -#include - -#include "../codecs/wm8580.h" -#include "dma.h" -#include "i2s.h" - -/* - * Default CFG switch settings to use this driver: - * - * SMDK6410: Set CFG1 1-3 Off, CFG2 1-4 On - */ - -/* SMDK64XX has a 12MHZ crystal attached to WM8580 */ -#define SMDK64XX_WM8580_FREQ 12000000 - -static int smdk64xx_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; - struct snd_soc_dai *codec_dai = rtd->codec_dai; - unsigned int pll_out; - int bfs, rfs, ret; - - switch (params_format(params)) { - case SNDRV_PCM_FORMAT_U8: - case SNDRV_PCM_FORMAT_S8: - bfs = 16; - break; - case SNDRV_PCM_FORMAT_U16_LE: - case SNDRV_PCM_FORMAT_S16_LE: - bfs = 32; - break; - default: - return -EINVAL; - } - - /* The Fvco for WM8580 PLLs must fall within [90,100]MHz. - * This criterion can't be met if we request PLL output - * as {8000x256, 64000x256, 11025x256}Hz. - * As a wayout, we rather change rfs to a minimum value that - * results in (params_rate(params) * rfs), and itself, acceptable - * to both - the CODEC and the CPU. - */ - switch (params_rate(params)) { - case 16000: - case 22050: - case 32000: - case 44100: - case 48000: - case 88200: - case 96000: - rfs = 256; - break; - case 64000: - rfs = 384; - break; - case 8000: - case 11025: - rfs = 512; - break; - default: - return -EINVAL; - } - pll_out = params_rate(params) * rfs; - - /* Set the Codec DAI configuration */ - ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S - | SND_SOC_DAIFMT_NB_NF - | SND_SOC_DAIFMT_CBM_CFM); - if (ret < 0) - return ret; - - /* Set the AP DAI configuration */ - ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S - | SND_SOC_DAIFMT_NB_NF - | SND_SOC_DAIFMT_CBM_CFM); - if (ret < 0) - return ret; - - /* Set WM8580 to drive MCLK from its PLLA */ - ret = snd_soc_dai_set_clkdiv(codec_dai, WM8580_MCLK, - WM8580_CLKSRC_PLLA); - if (ret < 0) - return ret; - - ret = snd_soc_dai_set_pll(codec_dai, WM8580_PLLA, 0, - SMDK64XX_WM8580_FREQ, pll_out); - if (ret < 0) - return ret; - - ret = snd_soc_dai_set_sysclk(codec_dai, WM8580_CLKSRC_PLLA, - pll_out, SND_SOC_CLOCK_IN); - if (ret < 0) - return ret; - - return 0; -} - -/* - * SMDK64XX WM8580 DAI operations. - */ -static struct snd_soc_ops smdk64xx_ops = { - .hw_params = smdk64xx_hw_params, -}; - -/* SMDK64xx Playback widgets */ -static const struct snd_soc_dapm_widget wm8580_dapm_widgets_pbk[] = { - SND_SOC_DAPM_HP("Front", NULL), - SND_SOC_DAPM_HP("Center+Sub", NULL), - SND_SOC_DAPM_HP("Rear", NULL), -}; - -/* SMDK64xx Capture widgets */ -static const struct snd_soc_dapm_widget wm8580_dapm_widgets_cpt[] = { - SND_SOC_DAPM_MIC("MicIn", NULL), - SND_SOC_DAPM_LINE("LineIn", NULL), -}; - -/* SMDK-PAIFTX connections */ -static const struct snd_soc_dapm_route audio_map_tx[] = { - /* MicIn feeds AINL */ - {"AINL", NULL, "MicIn"}, - - /* LineIn feeds AINL/R */ - {"AINL", NULL, "LineIn"}, - {"AINR", NULL, "LineIn"}, -}; - -/* SMDK-PAIFRX connections */ -static const struct snd_soc_dapm_route audio_map_rx[] = { - /* Front Left/Right are fed VOUT1L/R */ - {"Front", NULL, "VOUT1L"}, - {"Front", NULL, "VOUT1R"}, - - /* Center/Sub are fed VOUT2L/R */ - {"Center+Sub", NULL, "VOUT2L"}, - {"Center+Sub", NULL, "VOUT2R"}, - - /* Rear Left/Right are fed VOUT3L/R */ - {"Rear", NULL, "VOUT3L"}, - {"Rear", NULL, "VOUT3R"}, -}; - -static int smdk64xx_wm8580_init_paiftx(struct snd_soc_pcm_runtime *rtd) -{ - struct snd_soc_codec *codec = rtd->codec; - struct snd_soc_dapm_context *dapm = &codec->dapm; - - /* Add smdk64xx specific Capture widgets */ - snd_soc_dapm_new_controls(dapm, wm8580_dapm_widgets_cpt, - ARRAY_SIZE(wm8580_dapm_widgets_cpt)); - - /* Set up PAIFTX audio path */ - snd_soc_dapm_add_routes(dapm, audio_map_tx, ARRAY_SIZE(audio_map_tx)); - - /* Enabling the microphone requires the fitting of a 0R - * resistor to connect the line from the microphone jack. - */ - snd_soc_dapm_disable_pin(dapm, "MicIn"); - - /* signal a DAPM event */ - snd_soc_dapm_sync(dapm); - - return 0; -} - -static int smdk64xx_wm8580_init_paifrx(struct snd_soc_pcm_runtime *rtd) -{ - struct snd_soc_codec *codec = rtd->codec; - struct snd_soc_dapm_context *dapm = &codec->dapm; - - /* Add smdk64xx specific Playback widgets */ - snd_soc_dapm_new_controls(dapm, wm8580_dapm_widgets_pbk, - ARRAY_SIZE(wm8580_dapm_widgets_pbk)); - - /* Set up PAIFRX audio path */ - snd_soc_dapm_add_routes(dapm, audio_map_rx, ARRAY_SIZE(audio_map_rx)); - - /* signal a DAPM event */ - snd_soc_dapm_sync(dapm); - - return 0; -} - -static struct snd_soc_dai_link smdk64xx_dai[] = { -{ /* Primary Playback i/f */ - .name = "WM8580 PAIF RX", - .stream_name = "Playback", - .cpu_dai_name = "samsung-i2s.2", - .codec_dai_name = "wm8580-hifi-playback", - .platform_name = "samsung-audio", - .codec_name = "wm8580-codec.0-001b", - .init = smdk64xx_wm8580_init_paifrx, - .ops = &smdk64xx_ops, -}, -{ /* Primary Capture i/f */ - .name = "WM8580 PAIF TX", - .stream_name = "Capture", - .cpu_dai_name = "samsung-i2s.2", - .codec_dai_name = "wm8580-hifi-capture", - .platform_name = "samsung-audio", - .codec_name = "wm8580-codec.0-001b", - .init = smdk64xx_wm8580_init_paiftx, - .ops = &smdk64xx_ops, -}, -}; - -static struct snd_soc_card smdk64xx = { - .name = "SMDK64xx 5.1", - .dai_link = smdk64xx_dai, - .num_links = ARRAY_SIZE(smdk64xx_dai), -}; - -static struct platform_device *smdk64xx_snd_device; - -static int __init smdk64xx_audio_init(void) -{ - int ret; - - smdk64xx_snd_device = platform_device_alloc("soc-audio", -1); - if (!smdk64xx_snd_device) - return -ENOMEM; - - platform_set_drvdata(smdk64xx_snd_device, &smdk64xx); - ret = platform_device_add(smdk64xx_snd_device); - - if (ret) - platform_device_put(smdk64xx_snd_device); - - return ret; -} -module_init(smdk64xx_audio_init); - -MODULE_AUTHOR("Jaswinder Singh, jassi.brar@samsung.com"); -MODULE_DESCRIPTION("ALSA SoC SMDK64XX WM8580"); -MODULE_LICENSE("GPL"); diff --git a/sound/soc/s3c24xx/smdk_wm8580.c b/sound/soc/s3c24xx/smdk_wm8580.c new file mode 100644 index 000000000000..b1b3d12abcb9 --- /dev/null +++ b/sound/soc/s3c24xx/smdk_wm8580.c @@ -0,0 +1,254 @@ +/* + * smdk_wm8580.c + * + * Copyright (c) 2009 Samsung Electronics Co. Ltd + * Author: Jaswinder Singh + * + * 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. + */ + +#include +#include +#include +#include +#include +#include + +#include "../codecs/wm8580.h" +#include "dma.h" +#include "i2s.h" + +/* + * Default CFG switch settings to use this driver: + * + * SMDK6410: Set CFG1 1-3 Off, CFG2 1-4 On + */ + +/* SMDK has a 12MHZ crystal attached to WM8580 */ +#define SMDK_WM8580_FREQ 12000000 + +static int smdk_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + struct snd_soc_dai *codec_dai = rtd->codec_dai; + unsigned int pll_out; + int bfs, rfs, ret; + + switch (params_format(params)) { + case SNDRV_PCM_FORMAT_U8: + case SNDRV_PCM_FORMAT_S8: + bfs = 16; + break; + case SNDRV_PCM_FORMAT_U16_LE: + case SNDRV_PCM_FORMAT_S16_LE: + bfs = 32; + break; + default: + return -EINVAL; + } + + /* The Fvco for WM8580 PLLs must fall within [90,100]MHz. + * This criterion can't be met if we request PLL output + * as {8000x256, 64000x256, 11025x256}Hz. + * As a wayout, we rather change rfs to a minimum value that + * results in (params_rate(params) * rfs), and itself, acceptable + * to both - the CODEC and the CPU. + */ + switch (params_rate(params)) { + case 16000: + case 22050: + case 32000: + case 44100: + case 48000: + case 88200: + case 96000: + rfs = 256; + break; + case 64000: + rfs = 384; + break; + case 8000: + case 11025: + rfs = 512; + break; + default: + return -EINVAL; + } + pll_out = params_rate(params) * rfs; + + /* Set the Codec DAI configuration */ + ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S + | SND_SOC_DAIFMT_NB_NF + | SND_SOC_DAIFMT_CBM_CFM); + if (ret < 0) + return ret; + + /* Set the AP DAI configuration */ + ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S + | SND_SOC_DAIFMT_NB_NF + | SND_SOC_DAIFMT_CBM_CFM); + if (ret < 0) + return ret; + + /* Set WM8580 to drive MCLK from its PLLA */ + ret = snd_soc_dai_set_clkdiv(codec_dai, WM8580_MCLK, + WM8580_CLKSRC_PLLA); + if (ret < 0) + return ret; + + ret = snd_soc_dai_set_pll(codec_dai, WM8580_PLLA, 0, + SMDK_WM8580_FREQ, pll_out); + if (ret < 0) + return ret; + + ret = snd_soc_dai_set_sysclk(codec_dai, WM8580_CLKSRC_PLLA, + pll_out, SND_SOC_CLOCK_IN); + if (ret < 0) + return ret; + + return 0; +} + +/* + * SMDK WM8580 DAI operations. + */ +static struct snd_soc_ops smdk_ops = { + .hw_params = smdk_hw_params, +}; + +/* SMDK Playback widgets */ +static const struct snd_soc_dapm_widget wm8580_dapm_widgets_pbk[] = { + SND_SOC_DAPM_HP("Front", NULL), + SND_SOC_DAPM_HP("Center+Sub", NULL), + SND_SOC_DAPM_HP("Rear", NULL), +}; + +/* SMDK Capture widgets */ +static const struct snd_soc_dapm_widget wm8580_dapm_widgets_cpt[] = { + SND_SOC_DAPM_MIC("MicIn", NULL), + SND_SOC_DAPM_LINE("LineIn", NULL), +}; + +/* SMDK-PAIFTX connections */ +static const struct snd_soc_dapm_route audio_map_tx[] = { + /* MicIn feeds AINL */ + {"AINL", NULL, "MicIn"}, + + /* LineIn feeds AINL/R */ + {"AINL", NULL, "LineIn"}, + {"AINR", NULL, "LineIn"}, +}; + +/* SMDK-PAIFRX connections */ +static const struct snd_soc_dapm_route audio_map_rx[] = { + /* Front Left/Right are fed VOUT1L/R */ + {"Front", NULL, "VOUT1L"}, + {"Front", NULL, "VOUT1R"}, + + /* Center/Sub are fed VOUT2L/R */ + {"Center+Sub", NULL, "VOUT2L"}, + {"Center+Sub", NULL, "VOUT2R"}, + + /* Rear Left/Right are fed VOUT3L/R */ + {"Rear", NULL, "VOUT3L"}, + {"Rear", NULL, "VOUT3R"}, +}; + +static int smdk_wm8580_init_paiftx(struct snd_soc_pcm_runtime *rtd) +{ + struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_dapm_context *dapm = &codec->dapm; + + /* Add smdk specific Capture widgets */ + snd_soc_dapm_new_controls(dapm, wm8580_dapm_widgets_cpt, + ARRAY_SIZE(wm8580_dapm_widgets_cpt)); + + /* Set up PAIFTX audio path */ + snd_soc_dapm_add_routes(dapm, audio_map_tx, ARRAY_SIZE(audio_map_tx)); + + /* Enabling the microphone requires the fitting of a 0R + * resistor to connect the line from the microphone jack. + */ + snd_soc_dapm_disable_pin(dapm, "MicIn"); + + /* signal a DAPM event */ + snd_soc_dapm_sync(dapm); + + return 0; +} + +static int smdk_wm8580_init_paifrx(struct snd_soc_pcm_runtime *rtd) +{ + struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_dapm_context *dapm = &codec->dapm; + + /* Add smdk specific Playback widgets */ + snd_soc_dapm_new_controls(dapm, wm8580_dapm_widgets_pbk, + ARRAY_SIZE(wm8580_dapm_widgets_pbk)); + + /* Set up PAIFRX audio path */ + snd_soc_dapm_add_routes(dapm, audio_map_rx, ARRAY_SIZE(audio_map_rx)); + + /* signal a DAPM event */ + snd_soc_dapm_sync(dapm); + + return 0; +} + +static struct snd_soc_dai_link smdk_dai[] = { +{ /* Primary Playback i/f */ + .name = "WM8580 PAIF RX", + .stream_name = "Playback", + .cpu_dai_name = "samsung-i2s.2", + .codec_dai_name = "wm8580-hifi-playback", + .platform_name = "samsung-audio", + .codec_name = "wm8580-codec.0-001b", + .init = smdk_wm8580_init_paifrx, + .ops = &smdk_ops, +}, +{ /* Primary Capture i/f */ + .name = "WM8580 PAIF TX", + .stream_name = "Capture", + .cpu_dai_name = "samsung-i2s.2", + .codec_dai_name = "wm8580-hifi-capture", + .platform_name = "samsung-audio", + .codec_name = "wm8580-codec.0-001b", + .init = smdk_wm8580_init_paiftx, + .ops = &smdk_ops, +}, +}; + +static struct snd_soc_card smdk = { + .name = "SMDK-I2S", + .dai_link = smdk_dai, + .num_links = ARRAY_SIZE(smdk_dai), +}; + +static struct platform_device *smdk_snd_device; + +static int __init smdk_audio_init(void) +{ + int ret; + + smdk_snd_device = platform_device_alloc("soc-audio", -1); + if (!smdk_snd_device) + return -ENOMEM; + + platform_set_drvdata(smdk_snd_device, &smdk); + ret = platform_device_add(smdk_snd_device); + + if (ret) + platform_device_put(smdk_snd_device); + + return ret; +} +module_init(smdk_audio_init); + +MODULE_AUTHOR("Jaswinder Singh, jassi.brar@samsung.com"); +MODULE_DESCRIPTION("ALSA SoC SMDK WM8580"); +MODULE_LICENSE("GPL"); -- cgit v1.2.3 From b0f39c25a1bf6b4c81c183dfd0920e76f8e43488 Mon Sep 17 00:00:00 2001 From: Jassi Brar Date: Mon, 22 Nov 2010 15:37:19 +0900 Subject: ASoC: SMDK_WM8580: Enable for SMDKC100 Enable the ASoC Machine driver to run on SMDKC100 as well. Signed-off-by: Jassi Brar Acked-by: Kukjin Kim Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- arch/arm/mach-s5pc100/mach-smdkc100.c | 2 + sound/soc/s3c24xx/Kconfig | 2 +- sound/soc/s3c24xx/smdk_wm8580.c | 73 +++++++++++++++++++++++++---------- 3 files changed, 55 insertions(+), 22 deletions(-) diff --git a/arch/arm/mach-s5pc100/mach-smdkc100.c b/arch/arm/mach-s5pc100/mach-smdkc100.c index 18b405d514d6..dd192a27524d 100644 --- a/arch/arm/mach-s5pc100/mach-smdkc100.c +++ b/arch/arm/mach-s5pc100/mach-smdkc100.c @@ -96,6 +96,7 @@ static struct s3c2410_uartcfg smdkc100_uartcfgs[] __initdata = { /* I2C0 */ static struct i2c_board_info i2c_devs0[] __initdata = { + {I2C_BOARD_INFO("wm8580", 0x1b),}, }; /* I2C1 */ @@ -190,6 +191,7 @@ static struct platform_device *smdkc100_devices[] __initdata = { &s3c_device_ts, &s3c_device_wdt, &smdkc100_lcd_powerdev, + &samsung_asoc_dma, &s5pc100_device_iis0, &samsung_device_keypad, &s5pc100_device_ac97, diff --git a/sound/soc/s3c24xx/Kconfig b/sound/soc/s3c24xx/Kconfig index 396f678d1af5..4989fad83563 100644 --- a/sound/soc/s3c24xx/Kconfig +++ b/sound/soc/s3c24xx/Kconfig @@ -62,7 +62,7 @@ config SND_S3C24XX_SOC_JIVE_WM8750 config SND_SOC_SMDK_WM8580 tristate "SoC I2S Audio support for WM8580 on SMDK" - depends on SND_S3C24XX_SOC && MACH_SMDK6410 + depends on SND_S3C24XX_SOC && (MACH_SMDK6410 || MACH_SMDKC100) select SND_SOC_WM8580 select SND_SAMSUNG_I2S help diff --git a/sound/soc/s3c24xx/smdk_wm8580.c b/sound/soc/s3c24xx/smdk_wm8580.c index b1b3d12abcb9..0ae3d57d79e6 100644 --- a/sound/soc/s3c24xx/smdk_wm8580.c +++ b/sound/soc/s3c24xx/smdk_wm8580.c @@ -17,6 +17,8 @@ #include #include +#include + #include "../codecs/wm8580.h" #include "dma.h" #include "i2s.h" @@ -200,33 +202,49 @@ static int smdk_wm8580_init_paifrx(struct snd_soc_pcm_runtime *rtd) return 0; } +enum { + PRI_PLAYBACK = 0, + PRI_CAPTURE, + SEC_PLAYBACK, +}; + static struct snd_soc_dai_link smdk_dai[] = { -{ /* Primary Playback i/f */ - .name = "WM8580 PAIF RX", - .stream_name = "Playback", - .cpu_dai_name = "samsung-i2s.2", - .codec_dai_name = "wm8580-hifi-playback", - .platform_name = "samsung-audio", - .codec_name = "wm8580-codec.0-001b", - .init = smdk_wm8580_init_paifrx, - .ops = &smdk_ops, -}, -{ /* Primary Capture i/f */ - .name = "WM8580 PAIF TX", - .stream_name = "Capture", - .cpu_dai_name = "samsung-i2s.2", - .codec_dai_name = "wm8580-hifi-capture", - .platform_name = "samsung-audio", - .codec_name = "wm8580-codec.0-001b", - .init = smdk_wm8580_init_paiftx, - .ops = &smdk_ops, -}, + [PRI_PLAYBACK] = { /* Primary Playback i/f */ + .name = "WM8580 PAIF RX", + .stream_name = "Playback", + .cpu_dai_name = "samsung-i2s.2", + .codec_dai_name = "wm8580-hifi-playback", + .platform_name = "samsung-audio", + .codec_name = "wm8580-codec.0-001b", + .init = smdk_wm8580_init_paifrx, + .ops = &smdk_ops, + }, + [PRI_CAPTURE] = { /* Primary Capture i/f */ + .name = "WM8580 PAIF TX", + .stream_name = "Capture", + .cpu_dai_name = "samsung-i2s.2", + .codec_dai_name = "wm8580-hifi-capture", + .platform_name = "samsung-audio", + .codec_name = "wm8580-codec.0-001b", + .init = smdk_wm8580_init_paiftx, + .ops = &smdk_ops, + }, + [SEC_PLAYBACK] = { /* Sec_Fifo Playback i/f */ + .name = "Sec_FIFO TX", + .stream_name = "Playback", + .cpu_dai_name = "samsung-i2s.x", + .codec_dai_name = "wm8580-hifi-playback", + .platform_name = "samsung-audio", + .codec_name = "wm8580-codec.0-001b", + .init = smdk_wm8580_init_paifrx, + .ops = &smdk_ops, + }, }; static struct snd_soc_card smdk = { .name = "SMDK-I2S", .dai_link = smdk_dai, - .num_links = ARRAY_SIZE(smdk_dai), + .num_links = 2, }; static struct platform_device *smdk_snd_device; @@ -234,6 +252,19 @@ static struct platform_device *smdk_snd_device; static int __init smdk_audio_init(void) { int ret; + char *str; + + if (machine_is_smdkc100()) { + smdk.num_links = 3; + /* S5PC100 has I2S0 as v5 */ + str = (char *)smdk_dai[PRI_PLAYBACK].cpu_dai_name; + str[strlen(str) - 1] = '0'; + str = (char *)smdk_dai[PRI_CAPTURE].cpu_dai_name; + str[strlen(str) - 1] = '0'; + /* Secondary is at offset SAMSUNG_I2S_SECOFF from Primary */ + str = (char *)smdk_dai[SEC_PLAYBACK].cpu_dai_name; + str[strlen(str) - 1] = '0' + SAMSUNG_I2S_SECOFF; + } smdk_snd_device = platform_device_alloc("soc-audio", -1); if (!smdk_snd_device) -- cgit v1.2.3 From a964f34d8b516633d471191156963bae0d1bf730 Mon Sep 17 00:00:00 2001 From: Jassi Brar Date: Mon, 22 Nov 2010 15:37:22 +0900 Subject: ASoC: Samsung: Generalize Kconfig symbols Move prefixes to repesent the nature of Samsung ASoC suitably. SND_S3C24XX_SOC -> ASOC_SAMSUNG SND_S3C_SOC_PCM -> SND_SAMSUNG_PCM SND_S3C_SOC_AC97 -> SND_SAMSUNG_AC97 SND_S5P_SOC_SPDIF -> SND_SAMSUNG_SPDIF SND_S3C24XX_SOC_I2S -> SND_S3C24XX_I2S SND_S3C64XX_SOC_SMARTQ -> ASOC_SMARTQ SND_SOC_SMDK_SPDIF -> ASOC_SAMSUNG_SMDK_SPDIF SND_SOC_SMDK_WM8580 -> ASOC_SAMSUNG_SMDK_WM8580 SND_SOC_SMDK_WM9713 -> ASOC_SAMSUNG_SMDK_WM9713 SND_SOC_GONI_AQUILA_WM8994 -> ASOC_GONI_AQUILA_WM8994 Signed-off-by: Jassi Brar Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/s3c24xx/Kconfig | 98 +++++++++++++++++++++++----------------------- sound/soc/s3c24xx/Makefile | 40 +++++++++---------- 2 files changed, 69 insertions(+), 69 deletions(-) diff --git a/sound/soc/s3c24xx/Kconfig b/sound/soc/s3c24xx/Kconfig index 4989fad83563..eb45cf90d4e2 100644 --- a/sound/soc/s3c24xx/Kconfig +++ b/sound/soc/s3c24xx/Kconfig @@ -1,14 +1,14 @@ -config SND_S3C24XX_SOC - tristate "SoC Audio for the Samsung S3CXXXX chips" +config ASOC_SAMSUNG + tristate "ASoC support for Samsung" depends on ARCH_S3C2410 || ARCH_S3C64XX || ARCH_S5PC100 || ARCH_S5PV210 select S3C64XX_DMA if ARCH_S3C64XX select S3C2410_DMA if ARCH_S3C2410 help Say Y or M if you want to add support for codecs attached to - the S3C24XX AC97 or I2S interfaces. You will also need to + the Samsung SoCs' Audio interfaces. You will also need to select the audio interfaces to support below. -config SND_S3C24XX_SOC_I2S +config SND_S3C24XX_I2S tristate select S3C2410_DMA @@ -20,136 +20,136 @@ config SND_S3C2412_SOC_I2S select SND_S3C_I2SV2_SOC select S3C2410_DMA -config SND_S3C_SOC_PCM +config SND_SAMSUNG_PCM tristate -config SND_S3C_SOC_AC97 +config SND_SAMSUNG_AC97 tristate select SND_SOC_AC97_BUS -config SND_S5P_SOC_SPDIF +config SND_SAMSUNG_SPDIF tristate select SND_SOC_SPDIF config SND_SAMSUNG_I2S tristate -config SND_S3C24XX_SOC_NEO1973_WM8753 +config ASOC_SAMSUNG_NEO1973_WM8753 tristate "SoC I2S Audio support for NEO1973 - WM8753" - depends on SND_S3C24XX_SOC && MACH_NEO1973_GTA01 - select SND_S3C24XX_SOC_I2S + depends on ASOC_SAMSUNG && MACH_NEO1973_GTA01 + select SND_S3C24XX_I2S select SND_SOC_WM8753 help Say Y if you want to add support for SoC audio on smdk2440 with the WM8753. -config SND_S3C24XX_SOC_NEO1973_GTA02_WM8753 +config ASOC_SAMSUNG_NEO1973_GTA02_WM8753 tristate "Audio support for the Openmoko Neo FreeRunner (GTA02)" - depends on SND_S3C24XX_SOC && MACH_NEO1973_GTA02 - select SND_S3C24XX_SOC_I2S + depends on ASOC_SAMSUNG && MACH_NEO1973_GTA02 + select SND_S3C24XX_I2S select SND_SOC_WM8753 help This driver provides audio support for the Openmoko Neo FreeRunner smartphone. -config SND_S3C24XX_SOC_JIVE_WM8750 +config ASOC_SAMSUNG_JIVE_WM8750 tristate "SoC I2S Audio support for Jive" - depends on SND_S3C24XX_SOC && MACH_JIVE + depends on ASOC_SAMSUNG && MACH_JIVE select SND_SOC_WM8750 select SND_S3C2412_SOC_I2S help Sat Y if you want to add support for SoC audio on the Jive. -config SND_SOC_SMDK_WM8580 +config ASOC_SAMSUNG_SMDK_WM8580 tristate "SoC I2S Audio support for WM8580 on SMDK" - depends on SND_S3C24XX_SOC && (MACH_SMDK6410 || MACH_SMDKC100) + depends on ASOC_SAMSUNG && (MACH_SMDK6410 || MACH_SMDKC100) select SND_SOC_WM8580 select SND_SAMSUNG_I2S help Say Y if you want to add support for SoC audio on the SMDKs. -config SND_S3C24XX_SOC_SMDK2443_WM9710 +config ASOC_SAMSUNG_SMDK2443_WM9710 tristate "SoC AC97 Audio support for SMDK2443 - WM9710" - depends on SND_S3C24XX_SOC && MACH_SMDK2443 + depends on ASOC_SAMSUNG && MACH_SMDK2443 select S3C2410_DMA select AC97_BUS select SND_SOC_AC97_CODEC - select SND_S3C_SOC_AC97 + select SND_SAMSUNG_AC97 help Say Y if you want to add support for SoC audio on smdk2443 with the WM9710. -config SND_S3C24XX_SOC_LN2440SBC_ALC650 +config ASOC_SAMSUNG_LN2440SBC_ALC650 tristate "SoC AC97 Audio support for LN2440SBC - ALC650" - depends on SND_S3C24XX_SOC && ARCH_S3C2410 + depends on ASOC_SAMSUNG && ARCH_S3C2410 select S3C2410_DMA select AC97_BUS select SND_SOC_AC97_CODEC - select SND_S3C_SOC_AC97 + select SND_SAMSUNG_AC97 help Say Y if you want to add support for SoC audio on ln2440sbc with the ALC650. -config SND_S3C24XX_SOC_S3C24XX_UDA134X +config ASOC_SAMSUNG_S3C24XX_UDA134X tristate "SoC I2S Audio support UDA134X wired to a S3C24XX" - depends on SND_S3C24XX_SOC && ARCH_S3C2410 - select SND_S3C24XX_SOC_I2S + depends on ASOC_SAMSUNG && ARCH_S3C2410 + select SND_S3C24XX_I2S select SND_SOC_L3 - select SND_SOC_UDA134X + select SND_SOC_UDA134X -config SND_S3C24XX_SOC_SIMTEC +config ASOC_SAMSUNG_SIMTEC tristate help Internal node for common S3C24XX/Simtec suppor -config SND_S3C24XX_SOC_SIMTEC_TLV320AIC23 +config ASOC_SAMSUNG_SIMTEC_TLV320AIC23 tristate "SoC I2S Audio support for TLV320AIC23 on Simtec boards" - depends on SND_S3C24XX_SOC && ARCH_S3C2410 - select SND_S3C24XX_SOC_I2S + depends on ASOC_SAMSUNG && ARCH_S3C2410 + select SND_S3C24XX_I2S select SND_SOC_TLV320AIC23 - select SND_S3C24XX_SOC_SIMTEC + select ASOC_SAMSUNG_SIMTEC -config SND_S3C24XX_SOC_SIMTEC_HERMES +config ASOC_SAMSUNG_SIMTEC_HERMES tristate "SoC I2S Audio support for Simtec Hermes board" - depends on SND_S3C24XX_SOC && ARCH_S3C2410 - select SND_S3C24XX_SOC_I2S + depends on ASOC_SAMSUNG && ARCH_S3C2410 + select SND_S3C24XX_I2S select SND_SOC_TLV320AIC3X - select SND_S3C24XX_SOC_SIMTEC + select ASOC_SAMSUNG_SIMTEC -config SND_S3C24XX_SOC_RX1950_UDA1380 +config ASOC_SAMSUNG_RX1950_UDA1380 tristate "Audio support for the HP iPAQ RX1950" - depends on SND_S3C24XX_SOC && MACH_RX1950 - select SND_S3C24XX_SOC_I2S + depends on ASOC_SAMSUNG && MACH_RX1950 + select SND_S3C24XX_I2S select SND_SOC_UDA1380 help This driver provides audio support for HP iPAQ RX1950 PDA. -config SND_SOC_SMDK_WM9713 +config ASOC_SAMSUNG_SMDK_WM9713 tristate "SoC AC97 Audio support for SMDK with WM9713" - depends on SND_S3C24XX_SOC && (MACH_SMDK6410 || MACH_SMDKC100 || MACH_SMDKV210 || MACH_SMDKC110) + depends on ASOC_SAMSUNG && (MACH_SMDK6410 || MACH_SMDKC100 || MACH_SMDKV210 || MACH_SMDKC110) select SND_SOC_WM9713 - select SND_S3C_SOC_AC97 + select SND_SAMSUNG_AC97 help Sat Y if you want to add support for SoC audio on the SMDK. -config SND_S3C64XX_SOC_SMARTQ +config ASOC_SMARTQ tristate "SoC I2S Audio support for SmartQ board" - depends on SND_S3C24XX_SOC && MACH_SMARTQ + depends on ASOC_SAMSUNG && MACH_SMARTQ select SND_SAMSUNG_I2S select SND_SOC_WM8750 -config SND_SOC_GONI_AQUILA_WM8994 +config ASOC_GONI_AQUILA_WM8994 tristate "SoC I2S Audio support for AQUILA/GONI - WM8994" - depends on SND_S3C24XX_SOC && (MACH_GONI || MACH_AQUILA) + depends on ASOC_SAMSUNG && (MACH_GONI || MACH_AQUILA) select SND_SAMSUNG_I2S select SND_SOC_WM8994 help Say Y if you want to add support for SoC audio on goni or aquila with the WM8994. -config SND_SOC_SMDK_SPDIF +config ASOC_SAMSUNG_SMDK_SPDIF tristate "SoC S/PDIF Audio support for SMDK" - depends on SND_S3C24XX_SOC && (MACH_SMDKC100 || MACH_SMDKC110 || MACH_SMDKV210) - select SND_S5P_SOC_SPDIF + depends on ASOC_SAMSUNG && (MACH_SMDKC100 || MACH_SMDKC110 || MACH_SMDKV210) + select SND_SAMSUNG_SPDIF help Say Y if you want to add support for SoC S/PDIF audio on the SMDK. diff --git a/sound/soc/s3c24xx/Makefile b/sound/soc/s3c24xx/Makefile index 7eee57fe0d61..0d24f95c8b1c 100644 --- a/sound/soc/s3c24xx/Makefile +++ b/sound/soc/s3c24xx/Makefile @@ -8,13 +8,13 @@ snd-soc-samsung-spdif-objs := spdif.o snd-soc-pcm-objs := pcm.o snd-soc-i2s-objs := i2s.o -obj-$(CONFIG_SND_S3C24XX_SOC) += snd-soc-s3c24xx.o -obj-$(CONFIG_SND_S3C24XX_SOC_I2S) += snd-soc-s3c24xx-i2s.o -obj-$(CONFIG_SND_S3C_SOC_AC97) += snd-soc-ac97.o +obj-$(CONFIG_ASOC_SAMSUNG) += snd-soc-s3c24xx.o +obj-$(CONFIG_SND_S3C24XX_I2S) += snd-soc-s3c24xx-i2s.o +obj-$(CONFIG_SND_SAMSUNG_AC97) += snd-soc-ac97.o obj-$(CONFIG_SND_S3C2412_SOC_I2S) += snd-soc-s3c2412-i2s.o obj-$(CONFIG_SND_S3C_I2SV2_SOC) += snd-soc-s3c-i2s-v2.o -obj-$(CONFIG_SND_S5P_SOC_SPDIF) += snd-soc-samsung-spdif.o -obj-$(CONFIG_SND_S3C_SOC_PCM) += snd-soc-pcm.o +obj-$(CONFIG_SND_SAMSUNG_SPDIF) += snd-soc-samsung-spdif.o +obj-$(CONFIG_SND_SAMSUNG_PCM) += snd-soc-pcm.o obj-$(CONFIG_SND_SAMSUNG_I2S) += snd-soc-i2s.o # S3C24XX Machine Support @@ -34,18 +34,18 @@ snd-soc-s3c64xx-smartq-wm8987-objs := smartq_wm8987.o snd-soc-goni-wm8994-objs := goni_wm8994.o snd-soc-smdk-spdif-objs := smdk_spdif.o -obj-$(CONFIG_SND_S3C24XX_SOC_JIVE_WM8750) += snd-soc-jive-wm8750.o -obj-$(CONFIG_SND_S3C24XX_SOC_NEO1973_WM8753) += snd-soc-neo1973-wm8753.o -obj-$(CONFIG_SND_S3C24XX_SOC_NEO1973_GTA02_WM8753) += snd-soc-neo1973-gta02-wm8753.o -obj-$(CONFIG_SND_S3C24XX_SOC_SMDK2443_WM9710) += snd-soc-smdk2443-wm9710.o -obj-$(CONFIG_SND_S3C24XX_SOC_LN2440SBC_ALC650) += snd-soc-ln2440sbc-alc650.o -obj-$(CONFIG_SND_S3C24XX_SOC_S3C24XX_UDA134X) += snd-soc-s3c24xx-uda134x.o -obj-$(CONFIG_SND_S3C24XX_SOC_SIMTEC) += snd-soc-s3c24xx-simtec.o -obj-$(CONFIG_SND_S3C24XX_SOC_SIMTEC_HERMES) += snd-soc-s3c24xx-simtec-hermes.o -obj-$(CONFIG_SND_S3C24XX_SOC_SIMTEC_TLV320AIC23) += snd-soc-s3c24xx-simtec-tlv320aic23.o -obj-$(CONFIG_SND_S3C24XX_SOC_RX1950_UDA1380) += snd-soc-rx1950-uda1380.o -obj-$(CONFIG_SND_SOC_SMDK_WM8580) += snd-soc-smdk-wm8580.o -obj-$(CONFIG_SND_SOC_SMDK_WM9713) += snd-soc-smdk-wm9713.o -obj-$(CONFIG_SND_S3C64XX_SOC_SMARTQ) += snd-soc-s3c64xx-smartq-wm8987.o -obj-$(CONFIG_SND_SOC_SMDK_SPDIF) += snd-soc-smdk-spdif.o -obj-$(CONFIG_SND_SOC_GONI_AQUILA_WM8994) += snd-soc-goni-wm8994.o +obj-$(CONFIG_ASOC_SAMSUNG_JIVE_WM8750) += snd-soc-jive-wm8750.o +obj-$(CONFIG_ASOC_SAMSUNG_NEO1973_WM8753) += snd-soc-neo1973-wm8753.o +obj-$(CONFIG_ASOC_SAMSUNG_NEO1973_GTA02_WM8753) += snd-soc-neo1973-gta02-wm8753.o +obj-$(CONFIG_ASOC_SAMSUNG_SMDK2443_WM9710) += snd-soc-smdk2443-wm9710.o +obj-$(CONFIG_ASOC_SAMSUNG_LN2440SBC_ALC650) += snd-soc-ln2440sbc-alc650.o +obj-$(CONFIG_ASOC_SAMSUNG_S3C24XX_UDA134X) += snd-soc-s3c24xx-uda134x.o +obj-$(CONFIG_ASOC_SAMSUNG_SIMTEC) += snd-soc-s3c24xx-simtec.o +obj-$(CONFIG_ASOC_SAMSUNG_SIMTEC_HERMES) += snd-soc-s3c24xx-simtec-hermes.o +obj-$(CONFIG_ASOC_SAMSUNG_SIMTEC_TLV320AIC23) += snd-soc-s3c24xx-simtec-tlv320aic23.o +obj-$(CONFIG_ASOC_SAMSUNG_RX1950_UDA1380) += snd-soc-rx1950-uda1380.o +obj-$(CONFIG_ASOC_SAMSUNG_SMDK_WM8580) += snd-soc-smdk-wm8580.o +obj-$(CONFIG_ASOC_SAMSUNG_SMDK_WM9713) += snd-soc-smdk-wm9713.o +obj-$(CONFIG_ASOC_SMARTQ) += snd-soc-s3c64xx-smartq-wm8987.o +obj-$(CONFIG_ASOC_SAMSUNG_SMDK_SPDIF) += snd-soc-smdk-spdif.o +obj-$(CONFIG_ASOC_GONI_AQUILA_WM8994) += snd-soc-goni-wm8994.o -- cgit v1.2.3 From 5033f43c66754296dfb0ac5c895208e4a7f93aac Mon Sep 17 00:00:00 2001 From: Jassi Brar Date: Mon, 22 Nov 2010 15:37:25 +0900 Subject: ASoC: Samsung: Rename from s3c24xx to samsung Finally, move the 's3c24xx' directory to 'samsung' Signed-off-by: Jassi Brar Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/Kconfig | 2 +- sound/soc/Makefile | 2 +- sound/soc/s3c24xx/Kconfig | 155 --- sound/soc/s3c24xx/Makefile | 51 - sound/soc/s3c24xx/ac97.c | 520 ---------- sound/soc/s3c24xx/ac97.h | 21 - sound/soc/s3c24xx/dma.c | 502 ---------- sound/soc/s3c24xx/dma.h | 30 - sound/soc/s3c24xx/goni_wm8994.c | 309 ------ sound/soc/s3c24xx/i2s.c | 1256 ------------------------ sound/soc/s3c24xx/i2s.h | 29 - sound/soc/s3c24xx/jive_wm8750.c | 191 ---- sound/soc/s3c24xx/lm4857.h | 32 - sound/soc/s3c24xx/ln2440sbc_alc650.c | 77 -- sound/soc/s3c24xx/neo1973_gta02_wm8753.c | 504 ---------- sound/soc/s3c24xx/neo1973_wm8753.c | 706 ------------- sound/soc/s3c24xx/pcm.c | 552 ----------- sound/soc/s3c24xx/pcm.h | 124 --- sound/soc/s3c24xx/regs-i2s-v2.h | 115 --- sound/soc/s3c24xx/rx1950_uda1380.c | 319 ------ sound/soc/s3c24xx/s3c-i2s-v2.c | 757 -------------- sound/soc/s3c24xx/s3c-i2s-v2.h | 106 -- sound/soc/s3c24xx/s3c2412-i2s.c | 212 ---- sound/soc/s3c24xx/s3c2412-i2s.h | 27 - sound/soc/s3c24xx/s3c24xx-i2s.c | 519 ---------- sound/soc/s3c24xx/s3c24xx-i2s.h | 35 - sound/soc/s3c24xx/s3c24xx_simtec.c | 394 -------- sound/soc/s3c24xx/s3c24xx_simtec.h | 22 - sound/soc/s3c24xx/s3c24xx_simtec_hermes.c | 146 --- sound/soc/s3c24xx/s3c24xx_simtec_tlv320aic23.c | 134 --- sound/soc/s3c24xx/s3c24xx_uda134x.c | 367 ------- sound/soc/s3c24xx/smartq_wm8987.c | 288 ------ sound/soc/s3c24xx/smdk2443_wm9710.c | 73 -- sound/soc/s3c24xx/smdk_spdif.c | 223 ----- sound/soc/s3c24xx/smdk_wm8580.c | 285 ------ sound/soc/s3c24xx/smdk_wm9713.c | 107 -- sound/soc/s3c24xx/spdif.c | 501 ---------- sound/soc/s3c24xx/spdif.h | 19 - sound/soc/samsung/Kconfig | 155 +++ sound/soc/samsung/Makefile | 51 + sound/soc/samsung/ac97.c | 520 ++++++++++ sound/soc/samsung/ac97.h | 21 + sound/soc/samsung/dma.c | 502 ++++++++++ sound/soc/samsung/dma.h | 30 + sound/soc/samsung/goni_wm8994.c | 309 ++++++ sound/soc/samsung/i2s.c | 1256 ++++++++++++++++++++++++ sound/soc/samsung/i2s.h | 29 + sound/soc/samsung/jive_wm8750.c | 191 ++++ sound/soc/samsung/lm4857.h | 32 + sound/soc/samsung/ln2440sbc_alc650.c | 77 ++ sound/soc/samsung/neo1973_gta02_wm8753.c | 504 ++++++++++ sound/soc/samsung/neo1973_wm8753.c | 706 +++++++++++++ sound/soc/samsung/pcm.c | 552 +++++++++++ sound/soc/samsung/pcm.h | 124 +++ sound/soc/samsung/regs-i2s-v2.h | 115 +++ sound/soc/samsung/rx1950_uda1380.c | 319 ++++++ sound/soc/samsung/s3c-i2s-v2.c | 757 ++++++++++++++ sound/soc/samsung/s3c-i2s-v2.h | 106 ++ sound/soc/samsung/s3c2412-i2s.c | 212 ++++ sound/soc/samsung/s3c2412-i2s.h | 27 + sound/soc/samsung/s3c24xx-i2s.c | 519 ++++++++++ sound/soc/samsung/s3c24xx-i2s.h | 35 + sound/soc/samsung/s3c24xx_simtec.c | 394 ++++++++ sound/soc/samsung/s3c24xx_simtec.h | 22 + sound/soc/samsung/s3c24xx_simtec_hermes.c | 146 +++ sound/soc/samsung/s3c24xx_simtec_tlv320aic23.c | 134 +++ sound/soc/samsung/s3c24xx_uda134x.c | 367 +++++++ sound/soc/samsung/smartq_wm8987.c | 288 ++++++ sound/soc/samsung/smdk2443_wm9710.c | 73 ++ sound/soc/samsung/smdk_spdif.c | 223 +++++ sound/soc/samsung/smdk_wm8580.c | 285 ++++++ sound/soc/samsung/smdk_wm9713.c | 107 ++ sound/soc/samsung/spdif.c | 501 ++++++++++ sound/soc/samsung/spdif.h | 19 + 74 files changed, 9710 insertions(+), 9710 deletions(-) delete mode 100644 sound/soc/s3c24xx/Kconfig delete mode 100644 sound/soc/s3c24xx/Makefile delete mode 100644 sound/soc/s3c24xx/ac97.c delete mode 100644 sound/soc/s3c24xx/ac97.h delete mode 100644 sound/soc/s3c24xx/dma.c delete mode 100644 sound/soc/s3c24xx/dma.h delete mode 100644 sound/soc/s3c24xx/goni_wm8994.c delete mode 100644 sound/soc/s3c24xx/i2s.c delete mode 100644 sound/soc/s3c24xx/i2s.h delete mode 100644 sound/soc/s3c24xx/jive_wm8750.c delete mode 100644 sound/soc/s3c24xx/lm4857.h delete mode 100644 sound/soc/s3c24xx/ln2440sbc_alc650.c delete mode 100644 sound/soc/s3c24xx/neo1973_gta02_wm8753.c delete mode 100644 sound/soc/s3c24xx/neo1973_wm8753.c delete mode 100644 sound/soc/s3c24xx/pcm.c delete mode 100644 sound/soc/s3c24xx/pcm.h delete mode 100644 sound/soc/s3c24xx/regs-i2s-v2.h delete mode 100644 sound/soc/s3c24xx/rx1950_uda1380.c delete mode 100644 sound/soc/s3c24xx/s3c-i2s-v2.c delete mode 100644 sound/soc/s3c24xx/s3c-i2s-v2.h delete mode 100644 sound/soc/s3c24xx/s3c2412-i2s.c delete mode 100644 sound/soc/s3c24xx/s3c2412-i2s.h delete mode 100644 sound/soc/s3c24xx/s3c24xx-i2s.c delete mode 100644 sound/soc/s3c24xx/s3c24xx-i2s.h delete mode 100644 sound/soc/s3c24xx/s3c24xx_simtec.c delete mode 100644 sound/soc/s3c24xx/s3c24xx_simtec.h delete mode 100644 sound/soc/s3c24xx/s3c24xx_simtec_hermes.c delete mode 100644 sound/soc/s3c24xx/s3c24xx_simtec_tlv320aic23.c delete mode 100644 sound/soc/s3c24xx/s3c24xx_uda134x.c delete mode 100644 sound/soc/s3c24xx/smartq_wm8987.c delete mode 100644 sound/soc/s3c24xx/smdk2443_wm9710.c delete mode 100644 sound/soc/s3c24xx/smdk_spdif.c delete mode 100644 sound/soc/s3c24xx/smdk_wm8580.c delete mode 100644 sound/soc/s3c24xx/smdk_wm9713.c delete mode 100644 sound/soc/s3c24xx/spdif.c delete mode 100644 sound/soc/s3c24xx/spdif.h create mode 100644 sound/soc/samsung/Kconfig create mode 100644 sound/soc/samsung/Makefile create mode 100644 sound/soc/samsung/ac97.c create mode 100644 sound/soc/samsung/ac97.h create mode 100644 sound/soc/samsung/dma.c create mode 100644 sound/soc/samsung/dma.h create mode 100644 sound/soc/samsung/goni_wm8994.c create mode 100644 sound/soc/samsung/i2s.c create mode 100644 sound/soc/samsung/i2s.h create mode 100644 sound/soc/samsung/jive_wm8750.c create mode 100644 sound/soc/samsung/lm4857.h create mode 100644 sound/soc/samsung/ln2440sbc_alc650.c create mode 100644 sound/soc/samsung/neo1973_gta02_wm8753.c create mode 100644 sound/soc/samsung/neo1973_wm8753.c create mode 100644 sound/soc/samsung/pcm.c create mode 100644 sound/soc/samsung/pcm.h create mode 100644 sound/soc/samsung/regs-i2s-v2.h create mode 100644 sound/soc/samsung/rx1950_uda1380.c create mode 100644 sound/soc/samsung/s3c-i2s-v2.c create mode 100644 sound/soc/samsung/s3c-i2s-v2.h create mode 100644 sound/soc/samsung/s3c2412-i2s.c create mode 100644 sound/soc/samsung/s3c2412-i2s.h create mode 100644 sound/soc/samsung/s3c24xx-i2s.c create mode 100644 sound/soc/samsung/s3c24xx-i2s.h create mode 100644 sound/soc/samsung/s3c24xx_simtec.c create mode 100644 sound/soc/samsung/s3c24xx_simtec.h create mode 100644 sound/soc/samsung/s3c24xx_simtec_hermes.c create mode 100644 sound/soc/samsung/s3c24xx_simtec_tlv320aic23.c create mode 100644 sound/soc/samsung/s3c24xx_uda134x.c create mode 100644 sound/soc/samsung/smartq_wm8987.c create mode 100644 sound/soc/samsung/smdk2443_wm9710.c create mode 100644 sound/soc/samsung/smdk_spdif.c create mode 100644 sound/soc/samsung/smdk_wm8580.c create mode 100644 sound/soc/samsung/smdk_wm9713.c create mode 100644 sound/soc/samsung/spdif.c create mode 100644 sound/soc/samsung/spdif.h diff --git a/sound/soc/Kconfig b/sound/soc/Kconfig index 4562c898a7ef..21a5465ceb65 100644 --- a/sound/soc/Kconfig +++ b/sound/soc/Kconfig @@ -38,7 +38,7 @@ source "sound/soc/nuc900/Kconfig" source "sound/soc/omap/Kconfig" source "sound/soc/kirkwood/Kconfig" source "sound/soc/pxa/Kconfig" -source "sound/soc/s3c24xx/Kconfig" +source "sound/soc/samsung/Kconfig" source "sound/soc/s6000/Kconfig" source "sound/soc/sh/Kconfig" source "sound/soc/txx9/Kconfig" diff --git a/sound/soc/Makefile b/sound/soc/Makefile index eb183443eee4..ce913bf5213c 100644 --- a/sound/soc/Makefile +++ b/sound/soc/Makefile @@ -14,7 +14,7 @@ obj-$(CONFIG_SND_SOC) += nuc900/ obj-$(CONFIG_SND_SOC) += omap/ obj-$(CONFIG_SND_SOC) += kirkwood/ obj-$(CONFIG_SND_SOC) += pxa/ -obj-$(CONFIG_SND_SOC) += s3c24xx/ +obj-$(CONFIG_SND_SOC) += samsung/ obj-$(CONFIG_SND_SOC) += s6000/ obj-$(CONFIG_SND_SOC) += sh/ obj-$(CONFIG_SND_SOC) += txx9/ diff --git a/sound/soc/s3c24xx/Kconfig b/sound/soc/s3c24xx/Kconfig deleted file mode 100644 index eb45cf90d4e2..000000000000 --- a/sound/soc/s3c24xx/Kconfig +++ /dev/null @@ -1,155 +0,0 @@ -config ASOC_SAMSUNG - tristate "ASoC support for Samsung" - depends on ARCH_S3C2410 || ARCH_S3C64XX || ARCH_S5PC100 || ARCH_S5PV210 - select S3C64XX_DMA if ARCH_S3C64XX - select S3C2410_DMA if ARCH_S3C2410 - help - Say Y or M if you want to add support for codecs attached to - the Samsung SoCs' Audio interfaces. You will also need to - select the audio interfaces to support below. - -config SND_S3C24XX_I2S - tristate - select S3C2410_DMA - -config SND_S3C_I2SV2_SOC - tristate - -config SND_S3C2412_SOC_I2S - tristate - select SND_S3C_I2SV2_SOC - select S3C2410_DMA - -config SND_SAMSUNG_PCM - tristate - -config SND_SAMSUNG_AC97 - tristate - select SND_SOC_AC97_BUS - -config SND_SAMSUNG_SPDIF - tristate - select SND_SOC_SPDIF - -config SND_SAMSUNG_I2S - tristate - -config ASOC_SAMSUNG_NEO1973_WM8753 - tristate "SoC I2S Audio support for NEO1973 - WM8753" - depends on ASOC_SAMSUNG && MACH_NEO1973_GTA01 - select SND_S3C24XX_I2S - select SND_SOC_WM8753 - help - Say Y if you want to add support for SoC audio on smdk2440 - with the WM8753. - -config ASOC_SAMSUNG_NEO1973_GTA02_WM8753 - tristate "Audio support for the Openmoko Neo FreeRunner (GTA02)" - depends on ASOC_SAMSUNG && MACH_NEO1973_GTA02 - select SND_S3C24XX_I2S - select SND_SOC_WM8753 - help - This driver provides audio support for the Openmoko Neo FreeRunner - smartphone. - -config ASOC_SAMSUNG_JIVE_WM8750 - tristate "SoC I2S Audio support for Jive" - depends on ASOC_SAMSUNG && MACH_JIVE - select SND_SOC_WM8750 - select SND_S3C2412_SOC_I2S - help - Sat Y if you want to add support for SoC audio on the Jive. - -config ASOC_SAMSUNG_SMDK_WM8580 - tristate "SoC I2S Audio support for WM8580 on SMDK" - depends on ASOC_SAMSUNG && (MACH_SMDK6410 || MACH_SMDKC100) - select SND_SOC_WM8580 - select SND_SAMSUNG_I2S - help - Say Y if you want to add support for SoC audio on the SMDKs. - -config ASOC_SAMSUNG_SMDK2443_WM9710 - tristate "SoC AC97 Audio support for SMDK2443 - WM9710" - depends on ASOC_SAMSUNG && MACH_SMDK2443 - select S3C2410_DMA - select AC97_BUS - select SND_SOC_AC97_CODEC - select SND_SAMSUNG_AC97 - help - Say Y if you want to add support for SoC audio on smdk2443 - with the WM9710. - -config ASOC_SAMSUNG_LN2440SBC_ALC650 - tristate "SoC AC97 Audio support for LN2440SBC - ALC650" - depends on ASOC_SAMSUNG && ARCH_S3C2410 - select S3C2410_DMA - select AC97_BUS - select SND_SOC_AC97_CODEC - select SND_SAMSUNG_AC97 - help - Say Y if you want to add support for SoC audio on ln2440sbc - with the ALC650. - -config ASOC_SAMSUNG_S3C24XX_UDA134X - tristate "SoC I2S Audio support UDA134X wired to a S3C24XX" - depends on ASOC_SAMSUNG && ARCH_S3C2410 - select SND_S3C24XX_I2S - select SND_SOC_L3 - select SND_SOC_UDA134X - -config ASOC_SAMSUNG_SIMTEC - tristate - help - Internal node for common S3C24XX/Simtec suppor - -config ASOC_SAMSUNG_SIMTEC_TLV320AIC23 - tristate "SoC I2S Audio support for TLV320AIC23 on Simtec boards" - depends on ASOC_SAMSUNG && ARCH_S3C2410 - select SND_S3C24XX_I2S - select SND_SOC_TLV320AIC23 - select ASOC_SAMSUNG_SIMTEC - -config ASOC_SAMSUNG_SIMTEC_HERMES - tristate "SoC I2S Audio support for Simtec Hermes board" - depends on ASOC_SAMSUNG && ARCH_S3C2410 - select SND_S3C24XX_I2S - select SND_SOC_TLV320AIC3X - select ASOC_SAMSUNG_SIMTEC - -config ASOC_SAMSUNG_RX1950_UDA1380 - tristate "Audio support for the HP iPAQ RX1950" - depends on ASOC_SAMSUNG && MACH_RX1950 - select SND_S3C24XX_I2S - select SND_SOC_UDA1380 - help - This driver provides audio support for HP iPAQ RX1950 PDA. - -config ASOC_SAMSUNG_SMDK_WM9713 - tristate "SoC AC97 Audio support for SMDK with WM9713" - depends on ASOC_SAMSUNG && (MACH_SMDK6410 || MACH_SMDKC100 || MACH_SMDKV210 || MACH_SMDKC110) - select SND_SOC_WM9713 - select SND_SAMSUNG_AC97 - help - Sat Y if you want to add support for SoC audio on the SMDK. - -config ASOC_SMARTQ - tristate "SoC I2S Audio support for SmartQ board" - depends on ASOC_SAMSUNG && MACH_SMARTQ - select SND_SAMSUNG_I2S - select SND_SOC_WM8750 - -config ASOC_GONI_AQUILA_WM8994 - tristate "SoC I2S Audio support for AQUILA/GONI - WM8994" - depends on ASOC_SAMSUNG && (MACH_GONI || MACH_AQUILA) - select SND_SAMSUNG_I2S - select SND_SOC_WM8994 - help - Say Y if you want to add support for SoC audio on goni or aquila - with the WM8994. - -config ASOC_SAMSUNG_SMDK_SPDIF - tristate "SoC S/PDIF Audio support for SMDK" - depends on ASOC_SAMSUNG && (MACH_SMDKC100 || MACH_SMDKC110 || MACH_SMDKV210) - select SND_SAMSUNG_SPDIF - help - Say Y if you want to add support for SoC S/PDIF audio on the SMDK. diff --git a/sound/soc/s3c24xx/Makefile b/sound/soc/s3c24xx/Makefile deleted file mode 100644 index 0d24f95c8b1c..000000000000 --- a/sound/soc/s3c24xx/Makefile +++ /dev/null @@ -1,51 +0,0 @@ -# S3c24XX Platform Support -snd-soc-s3c24xx-objs := dma.o -snd-soc-s3c24xx-i2s-objs := s3c24xx-i2s.o -snd-soc-s3c2412-i2s-objs := s3c2412-i2s.o -snd-soc-ac97-objs := ac97.o -snd-soc-s3c-i2s-v2-objs := s3c-i2s-v2.o -snd-soc-samsung-spdif-objs := spdif.o -snd-soc-pcm-objs := pcm.o -snd-soc-i2s-objs := i2s.o - -obj-$(CONFIG_ASOC_SAMSUNG) += snd-soc-s3c24xx.o -obj-$(CONFIG_SND_S3C24XX_I2S) += snd-soc-s3c24xx-i2s.o -obj-$(CONFIG_SND_SAMSUNG_AC97) += snd-soc-ac97.o -obj-$(CONFIG_SND_S3C2412_SOC_I2S) += snd-soc-s3c2412-i2s.o -obj-$(CONFIG_SND_S3C_I2SV2_SOC) += snd-soc-s3c-i2s-v2.o -obj-$(CONFIG_SND_SAMSUNG_SPDIF) += snd-soc-samsung-spdif.o -obj-$(CONFIG_SND_SAMSUNG_PCM) += snd-soc-pcm.o -obj-$(CONFIG_SND_SAMSUNG_I2S) += snd-soc-i2s.o - -# S3C24XX Machine Support -snd-soc-jive-wm8750-objs := jive_wm8750.o -snd-soc-neo1973-wm8753-objs := neo1973_wm8753.o -snd-soc-neo1973-gta02-wm8753-objs := neo1973_gta02_wm8753.o -snd-soc-smdk2443-wm9710-objs := smdk2443_wm9710.o -snd-soc-ln2440sbc-alc650-objs := ln2440sbc_alc650.o -snd-soc-s3c24xx-uda134x-objs := s3c24xx_uda134x.o -snd-soc-s3c24xx-simtec-objs := s3c24xx_simtec.o -snd-soc-s3c24xx-simtec-hermes-objs := s3c24xx_simtec_hermes.o -snd-soc-s3c24xx-simtec-tlv320aic23-objs := s3c24xx_simtec_tlv320aic23.o -snd-soc-rx1950-uda1380-objs := rx1950_uda1380.o -snd-soc-smdk-wm8580-objs := smdk_wm8580.o -snd-soc-smdk-wm9713-objs := smdk_wm9713.o -snd-soc-s3c64xx-smartq-wm8987-objs := smartq_wm8987.o -snd-soc-goni-wm8994-objs := goni_wm8994.o -snd-soc-smdk-spdif-objs := smdk_spdif.o - -obj-$(CONFIG_ASOC_SAMSUNG_JIVE_WM8750) += snd-soc-jive-wm8750.o -obj-$(CONFIG_ASOC_SAMSUNG_NEO1973_WM8753) += snd-soc-neo1973-wm8753.o -obj-$(CONFIG_ASOC_SAMSUNG_NEO1973_GTA02_WM8753) += snd-soc-neo1973-gta02-wm8753.o -obj-$(CONFIG_ASOC_SAMSUNG_SMDK2443_WM9710) += snd-soc-smdk2443-wm9710.o -obj-$(CONFIG_ASOC_SAMSUNG_LN2440SBC_ALC650) += snd-soc-ln2440sbc-alc650.o -obj-$(CONFIG_ASOC_SAMSUNG_S3C24XX_UDA134X) += snd-soc-s3c24xx-uda134x.o -obj-$(CONFIG_ASOC_SAMSUNG_SIMTEC) += snd-soc-s3c24xx-simtec.o -obj-$(CONFIG_ASOC_SAMSUNG_SIMTEC_HERMES) += snd-soc-s3c24xx-simtec-hermes.o -obj-$(CONFIG_ASOC_SAMSUNG_SIMTEC_TLV320AIC23) += snd-soc-s3c24xx-simtec-tlv320aic23.o -obj-$(CONFIG_ASOC_SAMSUNG_RX1950_UDA1380) += snd-soc-rx1950-uda1380.o -obj-$(CONFIG_ASOC_SAMSUNG_SMDK_WM8580) += snd-soc-smdk-wm8580.o -obj-$(CONFIG_ASOC_SAMSUNG_SMDK_WM9713) += snd-soc-smdk-wm9713.o -obj-$(CONFIG_ASOC_SMARTQ) += snd-soc-s3c64xx-smartq-wm8987.o -obj-$(CONFIG_ASOC_SAMSUNG_SMDK_SPDIF) += snd-soc-smdk-spdif.o -obj-$(CONFIG_ASOC_GONI_AQUILA_WM8994) += snd-soc-goni-wm8994.o diff --git a/sound/soc/s3c24xx/ac97.c b/sound/soc/s3c24xx/ac97.c deleted file mode 100644 index 4f999d1bb330..000000000000 --- a/sound/soc/s3c24xx/ac97.c +++ /dev/null @@ -1,520 +0,0 @@ -/* sound/soc/s3c24xx/ac97.c - * - * ALSA SoC Audio Layer - S3C AC97 Controller driver - * Evolved from s3c2443-ac97.c - * - * Copyright (c) 2010 Samsung Electronics Co. Ltd - * Author: Jaswinder Singh - * Credits: Graeme Gregory, Sean Choi - * - * 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 -#include - -#include - -#include -#include -#include - -#include "dma.h" -#include "ac97.h" - -#define AC_CMD_ADDR(x) (x << 16) -#define AC_CMD_DATA(x) (x & 0xffff) - -struct s3c_ac97_info { - struct clk *ac97_clk; - void __iomem *regs; - struct mutex lock; - struct completion done; -}; -static struct s3c_ac97_info s3c_ac97; - -static struct s3c2410_dma_client s3c_dma_client_out = { - .name = "AC97 PCMOut" -}; - -static struct s3c2410_dma_client s3c_dma_client_in = { - .name = "AC97 PCMIn" -}; - -static struct s3c2410_dma_client s3c_dma_client_micin = { - .name = "AC97 MicIn" -}; - -static struct s3c_dma_params s3c_ac97_pcm_out = { - .client = &s3c_dma_client_out, - .dma_size = 4, -}; - -static struct s3c_dma_params s3c_ac97_pcm_in = { - .client = &s3c_dma_client_in, - .dma_size = 4, -}; - -static struct s3c_dma_params s3c_ac97_mic_in = { - .client = &s3c_dma_client_micin, - .dma_size = 4, -}; - -static void s3c_ac97_activate(struct snd_ac97 *ac97) -{ - u32 ac_glbctrl, stat; - - stat = readl(s3c_ac97.regs + S3C_AC97_GLBSTAT) & 0x7; - if (stat == S3C_AC97_GLBSTAT_MAINSTATE_ACTIVE) - return; /* Return if already active */ - - INIT_COMPLETION(s3c_ac97.done); - - ac_glbctrl = readl(s3c_ac97.regs + S3C_AC97_GLBCTRL); - ac_glbctrl = S3C_AC97_GLBCTRL_ACLINKON; - writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL); - msleep(1); - - ac_glbctrl |= S3C_AC97_GLBCTRL_TRANSFERDATAENABLE; - writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL); - msleep(1); - - ac_glbctrl = readl(s3c_ac97.regs + S3C_AC97_GLBCTRL); - ac_glbctrl |= S3C_AC97_GLBCTRL_CODECREADYIE; - writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL); - - if (!wait_for_completion_timeout(&s3c_ac97.done, HZ)) - pr_err("AC97: Unable to activate!"); -} - -static unsigned short s3c_ac97_read(struct snd_ac97 *ac97, - unsigned short reg) -{ - u32 ac_glbctrl, ac_codec_cmd; - u32 stat, addr, data; - - mutex_lock(&s3c_ac97.lock); - - s3c_ac97_activate(ac97); - - INIT_COMPLETION(s3c_ac97.done); - - ac_codec_cmd = readl(s3c_ac97.regs + S3C_AC97_CODEC_CMD); - ac_codec_cmd = S3C_AC97_CODEC_CMD_READ | AC_CMD_ADDR(reg); - writel(ac_codec_cmd, s3c_ac97.regs + S3C_AC97_CODEC_CMD); - - udelay(50); - - ac_glbctrl = readl(s3c_ac97.regs + S3C_AC97_GLBCTRL); - ac_glbctrl |= S3C_AC97_GLBCTRL_CODECREADYIE; - writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL); - - if (!wait_for_completion_timeout(&s3c_ac97.done, HZ)) - pr_err("AC97: Unable to read!"); - - stat = readl(s3c_ac97.regs + S3C_AC97_STAT); - addr = (stat >> 16) & 0x7f; - data = (stat & 0xffff); - - if (addr != reg) - pr_err("ac97: req addr = %02x, rep addr = %02x\n", - reg, addr); - - mutex_unlock(&s3c_ac97.lock); - - return (unsigned short)data; -} - -static void s3c_ac97_write(struct snd_ac97 *ac97, unsigned short reg, - unsigned short val) -{ - u32 ac_glbctrl, ac_codec_cmd; - - mutex_lock(&s3c_ac97.lock); - - s3c_ac97_activate(ac97); - - INIT_COMPLETION(s3c_ac97.done); - - ac_codec_cmd = readl(s3c_ac97.regs + S3C_AC97_CODEC_CMD); - ac_codec_cmd = AC_CMD_ADDR(reg) | AC_CMD_DATA(val); - writel(ac_codec_cmd, s3c_ac97.regs + S3C_AC97_CODEC_CMD); - - udelay(50); - - ac_glbctrl = readl(s3c_ac97.regs + S3C_AC97_GLBCTRL); - ac_glbctrl |= S3C_AC97_GLBCTRL_CODECREADYIE; - writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL); - - if (!wait_for_completion_timeout(&s3c_ac97.done, HZ)) - pr_err("AC97: Unable to write!"); - - ac_codec_cmd = readl(s3c_ac97.regs + S3C_AC97_CODEC_CMD); - ac_codec_cmd |= S3C_AC97_CODEC_CMD_READ; - writel(ac_codec_cmd, s3c_ac97.regs + S3C_AC97_CODEC_CMD); - - mutex_unlock(&s3c_ac97.lock); -} - -static void s3c_ac97_cold_reset(struct snd_ac97 *ac97) -{ - pr_debug("AC97: Cold reset\n"); - writel(S3C_AC97_GLBCTRL_COLDRESET, - s3c_ac97.regs + S3C_AC97_GLBCTRL); - msleep(1); - - writel(0, s3c_ac97.regs + S3C_AC97_GLBCTRL); - msleep(1); -} - -static void s3c_ac97_warm_reset(struct snd_ac97 *ac97) -{ - u32 stat; - - stat = readl(s3c_ac97.regs + S3C_AC97_GLBSTAT) & 0x7; - if (stat == S3C_AC97_GLBSTAT_MAINSTATE_ACTIVE) - return; /* Return if already active */ - - pr_debug("AC97: Warm reset\n"); - - writel(S3C_AC97_GLBCTRL_WARMRESET, s3c_ac97.regs + S3C_AC97_GLBCTRL); - msleep(1); - - writel(0, s3c_ac97.regs + S3C_AC97_GLBCTRL); - msleep(1); - - s3c_ac97_activate(ac97); -} - -static irqreturn_t s3c_ac97_irq(int irq, void *dev_id) -{ - u32 ac_glbctrl, ac_glbstat; - - ac_glbstat = readl(s3c_ac97.regs + S3C_AC97_GLBSTAT); - - if (ac_glbstat & S3C_AC97_GLBSTAT_CODECREADY) { - - ac_glbctrl = readl(s3c_ac97.regs + S3C_AC97_GLBCTRL); - ac_glbctrl &= ~S3C_AC97_GLBCTRL_CODECREADYIE; - writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL); - - complete(&s3c_ac97.done); - } - - ac_glbctrl = readl(s3c_ac97.regs + S3C_AC97_GLBCTRL); - ac_glbctrl |= (1<<30); /* Clear interrupt */ - writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL); - - return IRQ_HANDLED; -} - -struct snd_ac97_bus_ops soc_ac97_ops = { - .read = s3c_ac97_read, - .write = s3c_ac97_write, - .warm_reset = s3c_ac97_warm_reset, - .reset = s3c_ac97_cold_reset, -}; -EXPORT_SYMBOL_GPL(soc_ac97_ops); - -static int s3c_ac97_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params, - struct snd_soc_dai *dai) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; - struct s3c_dma_params *dma_data; - - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - dma_data = &s3c_ac97_pcm_out; - else - dma_data = &s3c_ac97_pcm_in; - - snd_soc_dai_set_dma_data(cpu_dai, substream, dma_data); - - return 0; -} - -static int s3c_ac97_trigger(struct snd_pcm_substream *substream, int cmd, - struct snd_soc_dai *dai) -{ - u32 ac_glbctrl; - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct s3c_dma_params *dma_data = - snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); - - ac_glbctrl = readl(s3c_ac97.regs + S3C_AC97_GLBCTRL); - if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) - ac_glbctrl &= ~S3C_AC97_GLBCTRL_PCMINTM_MASK; - else - ac_glbctrl &= ~S3C_AC97_GLBCTRL_PCMOUTTM_MASK; - - switch (cmd) { - case SNDRV_PCM_TRIGGER_START: - case SNDRV_PCM_TRIGGER_RESUME: - case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) - ac_glbctrl |= S3C_AC97_GLBCTRL_PCMINTM_DMA; - else - ac_glbctrl |= S3C_AC97_GLBCTRL_PCMOUTTM_DMA; - break; - - case SNDRV_PCM_TRIGGER_STOP: - case SNDRV_PCM_TRIGGER_SUSPEND: - case SNDRV_PCM_TRIGGER_PAUSE_PUSH: - break; - } - - writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL); - - s3c2410_dma_ctrl(dma_data->channel, S3C2410_DMAOP_STARTED); - - return 0; -} - -static int s3c_ac97_hw_mic_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params, - struct snd_soc_dai *dai) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; - - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - return -ENODEV; - else - snd_soc_dai_set_dma_data(cpu_dai, substream, &s3c_ac97_mic_in); - - return 0; -} - -static int s3c_ac97_mic_trigger(struct snd_pcm_substream *substream, - int cmd, struct snd_soc_dai *dai) -{ - u32 ac_glbctrl; - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct s3c_dma_params *dma_data = - snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); - - ac_glbctrl = readl(s3c_ac97.regs + S3C_AC97_GLBCTRL); - ac_glbctrl &= ~S3C_AC97_GLBCTRL_MICINTM_MASK; - - switch (cmd) { - case SNDRV_PCM_TRIGGER_START: - case SNDRV_PCM_TRIGGER_RESUME: - case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - ac_glbctrl |= S3C_AC97_GLBCTRL_MICINTM_DMA; - break; - - case SNDRV_PCM_TRIGGER_STOP: - case SNDRV_PCM_TRIGGER_SUSPEND: - case SNDRV_PCM_TRIGGER_PAUSE_PUSH: - break; - } - - writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL); - - s3c2410_dma_ctrl(dma_data->channel, S3C2410_DMAOP_STARTED); - - return 0; -} - -static struct snd_soc_dai_ops s3c_ac97_dai_ops = { - .hw_params = s3c_ac97_hw_params, - .trigger = s3c_ac97_trigger, -}; - -static struct snd_soc_dai_ops s3c_ac97_mic_dai_ops = { - .hw_params = s3c_ac97_hw_mic_params, - .trigger = s3c_ac97_mic_trigger, -}; - -static struct snd_soc_dai_driver s3c_ac97_dai[] = { - [S3C_AC97_DAI_PCM] = { - .name = "samsung-ac97", - .ac97_control = 1, - .playback = { - .stream_name = "AC97 Playback", - .channels_min = 2, - .channels_max = 2, - .rates = SNDRV_PCM_RATE_8000_48000, - .formats = SNDRV_PCM_FMTBIT_S16_LE,}, - .capture = { - .stream_name = "AC97 Capture", - .channels_min = 2, - .channels_max = 2, - .rates = SNDRV_PCM_RATE_8000_48000, - .formats = SNDRV_PCM_FMTBIT_S16_LE,}, - .ops = &s3c_ac97_dai_ops, - }, - [S3C_AC97_DAI_MIC] = { - .name = "samsung-ac97-mic", - .ac97_control = 1, - .capture = { - .stream_name = "AC97 Mic Capture", - .channels_min = 1, - .channels_max = 1, - .rates = SNDRV_PCM_RATE_8000_48000, - .formats = SNDRV_PCM_FMTBIT_S16_LE,}, - .ops = &s3c_ac97_mic_dai_ops, - }, -}; - -static __devinit int s3c_ac97_probe(struct platform_device *pdev) -{ - struct resource *mem_res, *dmatx_res, *dmarx_res, *dmamic_res, *irq_res; - struct s3c_audio_pdata *ac97_pdata; - int ret; - - ac97_pdata = pdev->dev.platform_data; - if (!ac97_pdata || !ac97_pdata->cfg_gpio) { - dev_err(&pdev->dev, "cfg_gpio callback not provided!\n"); - return -EINVAL; - } - - /* Check for availability of necessary resource */ - dmatx_res = platform_get_resource(pdev, IORESOURCE_DMA, 0); - if (!dmatx_res) { - dev_err(&pdev->dev, "Unable to get AC97-TX dma resource\n"); - return -ENXIO; - } - - dmarx_res = platform_get_resource(pdev, IORESOURCE_DMA, 1); - if (!dmarx_res) { - dev_err(&pdev->dev, "Unable to get AC97-RX dma resource\n"); - return -ENXIO; - } - - dmamic_res = platform_get_resource(pdev, IORESOURCE_DMA, 2); - if (!dmamic_res) { - dev_err(&pdev->dev, "Unable to get AC97-MIC dma resource\n"); - return -ENXIO; - } - - mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!mem_res) { - dev_err(&pdev->dev, "Unable to get register resource\n"); - return -ENXIO; - } - - irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); - if (!irq_res) { - dev_err(&pdev->dev, "AC97 IRQ not provided!\n"); - return -ENXIO; - } - - if (!request_mem_region(mem_res->start, - resource_size(mem_res), "ac97")) { - dev_err(&pdev->dev, "Unable to request register region\n"); - return -EBUSY; - } - - s3c_ac97_pcm_out.channel = dmatx_res->start; - s3c_ac97_pcm_out.dma_addr = mem_res->start + S3C_AC97_PCM_DATA; - s3c_ac97_pcm_in.channel = dmarx_res->start; - s3c_ac97_pcm_in.dma_addr = mem_res->start + S3C_AC97_PCM_DATA; - s3c_ac97_mic_in.channel = dmamic_res->start; - s3c_ac97_mic_in.dma_addr = mem_res->start + S3C_AC97_MIC_DATA; - - init_completion(&s3c_ac97.done); - mutex_init(&s3c_ac97.lock); - - s3c_ac97.regs = ioremap(mem_res->start, resource_size(mem_res)); - if (s3c_ac97.regs == NULL) { - dev_err(&pdev->dev, "Unable to ioremap register region\n"); - ret = -ENXIO; - goto err1; - } - - s3c_ac97.ac97_clk = clk_get(&pdev->dev, "ac97"); - if (IS_ERR(s3c_ac97.ac97_clk)) { - dev_err(&pdev->dev, "ac97 failed to get ac97_clock\n"); - ret = -ENODEV; - goto err2; - } - clk_enable(s3c_ac97.ac97_clk); - - if (ac97_pdata->cfg_gpio(pdev)) { - dev_err(&pdev->dev, "Unable to configure gpio\n"); - ret = -EINVAL; - goto err3; - } - - ret = request_irq(irq_res->start, s3c_ac97_irq, - IRQF_DISABLED, "AC97", NULL); - if (ret < 0) { - dev_err(&pdev->dev, "ac97: interrupt request failed.\n"); - goto err4; - } - - ret = snd_soc_register_dais(&pdev->dev, s3c_ac97_dai, - ARRAY_SIZE(s3c_ac97_dai)); - if (ret) - goto err5; - - return 0; - -err5: - free_irq(irq_res->start, NULL); -err4: -err3: - clk_disable(s3c_ac97.ac97_clk); - clk_put(s3c_ac97.ac97_clk); -err2: - iounmap(s3c_ac97.regs); -err1: - release_mem_region(mem_res->start, resource_size(mem_res)); - - return ret; -} - -static __devexit int s3c_ac97_remove(struct platform_device *pdev) -{ - struct resource *mem_res, *irq_res; - - snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(s3c_ac97_dai)); - - irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); - if (irq_res) - free_irq(irq_res->start, NULL); - - clk_disable(s3c_ac97.ac97_clk); - clk_put(s3c_ac97.ac97_clk); - - iounmap(s3c_ac97.regs); - - mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (mem_res) - release_mem_region(mem_res->start, resource_size(mem_res)); - - return 0; -} - -static struct platform_driver s3c_ac97_driver = { - .probe = s3c_ac97_probe, - .remove = s3c_ac97_remove, - .driver = { - .name = "samsung-ac97", - .owner = THIS_MODULE, - }, -}; - -static int __init s3c_ac97_init(void) -{ - return platform_driver_register(&s3c_ac97_driver); -} -module_init(s3c_ac97_init); - -static void __exit s3c_ac97_exit(void) -{ - platform_driver_unregister(&s3c_ac97_driver); -} -module_exit(s3c_ac97_exit); - -MODULE_AUTHOR("Jaswinder Singh, "); -MODULE_DESCRIPTION("AC97 driver for the Samsung SoC"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:samsung-ac97"); diff --git a/sound/soc/s3c24xx/ac97.h b/sound/soc/s3c24xx/ac97.h deleted file mode 100644 index a8f01b788878..000000000000 --- a/sound/soc/s3c24xx/ac97.h +++ /dev/null @@ -1,21 +0,0 @@ -/* sound/soc/s3c24xx/ac97.h - * - * ALSA SoC Audio Layer - S3C AC97 Controller driver - * Evolved from s3c2443-ac97.h - * - * Copyright (c) 2010 Samsung Electronics Co. Ltd - * Author: Jaswinder Singh - * Credits: Graeme Gregory, Sean Choi - * - * 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. - */ - -#ifndef __S3C_AC97_H_ -#define __S3C_AC97_H_ - -#define S3C_AC97_DAI_PCM 0 -#define S3C_AC97_DAI_MIC 1 - -#endif /* __S3C_AC97_H_ */ diff --git a/sound/soc/s3c24xx/dma.c b/sound/soc/s3c24xx/dma.c deleted file mode 100644 index 21240198c5d6..000000000000 --- a/sound/soc/s3c24xx/dma.c +++ /dev/null @@ -1,502 +0,0 @@ -/* - * dma.c -- ALSA Soc Audio Layer - * - * (c) 2006 Wolfson Microelectronics PLC. - * Graeme Gregory graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com - * - * Copyright 2004-2005 Simtec Electronics - * http://armlinux.simtec.co.uk/ - * Ben Dooks - * - * 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. - */ - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include -#include - -#include "dma.h" - -static const struct snd_pcm_hardware dma_hardware = { - .info = SNDRV_PCM_INFO_INTERLEAVED | - SNDRV_PCM_INFO_BLOCK_TRANSFER | - SNDRV_PCM_INFO_MMAP | - SNDRV_PCM_INFO_MMAP_VALID | - SNDRV_PCM_INFO_PAUSE | - SNDRV_PCM_INFO_RESUME, - .formats = SNDRV_PCM_FMTBIT_S16_LE | - SNDRV_PCM_FMTBIT_U16_LE | - SNDRV_PCM_FMTBIT_U8 | - SNDRV_PCM_FMTBIT_S8, - .channels_min = 2, - .channels_max = 2, - .buffer_bytes_max = 128*1024, - .period_bytes_min = PAGE_SIZE, - .period_bytes_max = PAGE_SIZE*2, - .periods_min = 2, - .periods_max = 128, - .fifo_size = 32, -}; - -struct runtime_data { - spinlock_t lock; - int state; - unsigned int dma_loaded; - unsigned int dma_limit; - unsigned int dma_period; - dma_addr_t dma_start; - dma_addr_t dma_pos; - dma_addr_t dma_end; - struct s3c_dma_params *params; -}; - -/* dma_enqueue - * - * place a dma buffer onto the queue for the dma system - * to handle. -*/ -static void dma_enqueue(struct snd_pcm_substream *substream) -{ - struct runtime_data *prtd = substream->runtime->private_data; - dma_addr_t pos = prtd->dma_pos; - unsigned int limit; - int ret; - - pr_debug("Entered %s\n", __func__); - - if (s3c_dma_has_circular()) - limit = (prtd->dma_end - prtd->dma_start) / prtd->dma_period; - else - limit = prtd->dma_limit; - - pr_debug("%s: loaded %d, limit %d\n", - __func__, prtd->dma_loaded, limit); - - while (prtd->dma_loaded < limit) { - unsigned long len = prtd->dma_period; - - pr_debug("dma_loaded: %d\n", prtd->dma_loaded); - - if ((pos + len) > prtd->dma_end) { - len = prtd->dma_end - pos; - pr_debug("%s: corrected dma len %ld\n", __func__, len); - } - - ret = s3c2410_dma_enqueue(prtd->params->channel, - substream, pos, len); - - if (ret == 0) { - prtd->dma_loaded++; - pos += prtd->dma_period; - if (pos >= prtd->dma_end) - pos = prtd->dma_start; - } else - break; - } - - prtd->dma_pos = pos; -} - -static void audio_buffdone(struct s3c2410_dma_chan *channel, - void *dev_id, int size, - enum s3c2410_dma_buffresult result) -{ - struct snd_pcm_substream *substream = dev_id; - struct runtime_data *prtd; - - pr_debug("Entered %s\n", __func__); - - if (result == S3C2410_RES_ABORT || result == S3C2410_RES_ERR) - return; - - prtd = substream->runtime->private_data; - - if (substream) - snd_pcm_period_elapsed(substream); - - spin_lock(&prtd->lock); - if (prtd->state & ST_RUNNING && !s3c_dma_has_circular()) { - prtd->dma_loaded--; - dma_enqueue(substream); - } - - spin_unlock(&prtd->lock); -} - -static int dma_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - struct runtime_data *prtd = runtime->private_data; - struct snd_soc_pcm_runtime *rtd = substream->private_data; - unsigned long totbytes = params_buffer_bytes(params); - struct s3c_dma_params *dma = - snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); - int ret = 0; - - - pr_debug("Entered %s\n", __func__); - - /* return if this is a bufferless transfer e.g. - * codec <--> BT codec or GSM modem -- lg FIXME */ - if (!dma) - return 0; - - /* this may get called several times by oss emulation - * with different params -HW */ - if (prtd->params == NULL) { - /* prepare DMA */ - prtd->params = dma; - - pr_debug("params %p, client %p, channel %d\n", prtd->params, - prtd->params->client, prtd->params->channel); - - ret = s3c2410_dma_request(prtd->params->channel, - prtd->params->client, NULL); - - if (ret < 0) { - printk(KERN_ERR "failed to get dma channel\n"); - return ret; - } - - /* use the circular buffering if we have it available. */ - if (s3c_dma_has_circular()) - s3c2410_dma_setflags(prtd->params->channel, - S3C2410_DMAF_CIRCULAR); - } - - s3c2410_dma_set_buffdone_fn(prtd->params->channel, - audio_buffdone); - - snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); - - runtime->dma_bytes = totbytes; - - spin_lock_irq(&prtd->lock); - prtd->dma_loaded = 0; - prtd->dma_limit = runtime->hw.periods_min; - prtd->dma_period = params_period_bytes(params); - prtd->dma_start = runtime->dma_addr; - prtd->dma_pos = prtd->dma_start; - prtd->dma_end = prtd->dma_start + totbytes; - spin_unlock_irq(&prtd->lock); - - return 0; -} - -static int dma_hw_free(struct snd_pcm_substream *substream) -{ - struct runtime_data *prtd = substream->runtime->private_data; - - pr_debug("Entered %s\n", __func__); - - /* TODO - do we need to ensure DMA flushed */ - snd_pcm_set_runtime_buffer(substream, NULL); - - if (prtd->params) { - s3c2410_dma_free(prtd->params->channel, prtd->params->client); - prtd->params = NULL; - } - - return 0; -} - -static int dma_prepare(struct snd_pcm_substream *substream) -{ - struct runtime_data *prtd = substream->runtime->private_data; - int ret = 0; - - pr_debug("Entered %s\n", __func__); - - /* return if this is a bufferless transfer e.g. - * codec <--> BT codec or GSM modem -- lg FIXME */ - if (!prtd->params) - return 0; - - /* channel needs configuring for mem=>device, increment memory addr, - * sync to pclk, half-word transfers to the IIS-FIFO. */ - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - s3c2410_dma_devconfig(prtd->params->channel, - S3C2410_DMASRC_MEM, - prtd->params->dma_addr); - } else { - s3c2410_dma_devconfig(prtd->params->channel, - S3C2410_DMASRC_HW, - prtd->params->dma_addr); - } - - s3c2410_dma_config(prtd->params->channel, - prtd->params->dma_size); - - /* flush the DMA channel */ - s3c2410_dma_ctrl(prtd->params->channel, S3C2410_DMAOP_FLUSH); - prtd->dma_loaded = 0; - prtd->dma_pos = prtd->dma_start; - - /* enqueue dma buffers */ - dma_enqueue(substream); - - return ret; -} - -static int dma_trigger(struct snd_pcm_substream *substream, int cmd) -{ - struct runtime_data *prtd = substream->runtime->private_data; - int ret = 0; - - pr_debug("Entered %s\n", __func__); - - spin_lock(&prtd->lock); - - switch (cmd) { - case SNDRV_PCM_TRIGGER_START: - case SNDRV_PCM_TRIGGER_RESUME: - case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - prtd->state |= ST_RUNNING; - s3c2410_dma_ctrl(prtd->params->channel, S3C2410_DMAOP_START); - break; - - case SNDRV_PCM_TRIGGER_STOP: - case SNDRV_PCM_TRIGGER_SUSPEND: - case SNDRV_PCM_TRIGGER_PAUSE_PUSH: - prtd->state &= ~ST_RUNNING; - s3c2410_dma_ctrl(prtd->params->channel, S3C2410_DMAOP_STOP); - break; - - default: - ret = -EINVAL; - break; - } - - spin_unlock(&prtd->lock); - - return ret; -} - -static snd_pcm_uframes_t -dma_pointer(struct snd_pcm_substream *substream) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - struct runtime_data *prtd = runtime->private_data; - unsigned long res; - dma_addr_t src, dst; - - pr_debug("Entered %s\n", __func__); - - spin_lock(&prtd->lock); - s3c2410_dma_getposition(prtd->params->channel, &src, &dst); - - if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) - res = dst - prtd->dma_start; - else - res = src - prtd->dma_start; - - spin_unlock(&prtd->lock); - - pr_debug("Pointer %x %x\n", src, dst); - - /* we seem to be getting the odd error from the pcm library due - * to out-of-bounds pointers. this is maybe due to the dma engine - * not having loaded the new values for the channel before being - * callled... (todo - fix ) - */ - - if (res >= snd_pcm_lib_buffer_bytes(substream)) { - if (res == snd_pcm_lib_buffer_bytes(substream)) - res = 0; - } - - return bytes_to_frames(substream->runtime, res); -} - -static int dma_open(struct snd_pcm_substream *substream) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - struct runtime_data *prtd; - - pr_debug("Entered %s\n", __func__); - - snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS); - snd_soc_set_runtime_hwparams(substream, &dma_hardware); - - prtd = kzalloc(sizeof(struct runtime_data), GFP_KERNEL); - if (prtd == NULL) - return -ENOMEM; - - spin_lock_init(&prtd->lock); - - runtime->private_data = prtd; - return 0; -} - -static int dma_close(struct snd_pcm_substream *substream) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - struct runtime_data *prtd = runtime->private_data; - - pr_debug("Entered %s\n", __func__); - - if (!prtd) - pr_debug("dma_close called with prtd == NULL\n"); - - kfree(prtd); - - return 0; -} - -static int dma_mmap(struct snd_pcm_substream *substream, - struct vm_area_struct *vma) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - - pr_debug("Entered %s\n", __func__); - - return dma_mmap_writecombine(substream->pcm->card->dev, vma, - runtime->dma_area, - runtime->dma_addr, - runtime->dma_bytes); -} - -static struct snd_pcm_ops dma_ops = { - .open = dma_open, - .close = dma_close, - .ioctl = snd_pcm_lib_ioctl, - .hw_params = dma_hw_params, - .hw_free = dma_hw_free, - .prepare = dma_prepare, - .trigger = dma_trigger, - .pointer = dma_pointer, - .mmap = dma_mmap, -}; - -static int preallocate_dma_buffer(struct snd_pcm *pcm, int stream) -{ - struct snd_pcm_substream *substream = pcm->streams[stream].substream; - struct snd_dma_buffer *buf = &substream->dma_buffer; - size_t size = dma_hardware.buffer_bytes_max; - - pr_debug("Entered %s\n", __func__); - - buf->dev.type = SNDRV_DMA_TYPE_DEV; - buf->dev.dev = pcm->card->dev; - buf->private_data = NULL; - buf->area = dma_alloc_writecombine(pcm->card->dev, size, - &buf->addr, GFP_KERNEL); - if (!buf->area) - return -ENOMEM; - buf->bytes = size; - return 0; -} - -static void dma_free_dma_buffers(struct snd_pcm *pcm) -{ - struct snd_pcm_substream *substream; - struct snd_dma_buffer *buf; - int stream; - - pr_debug("Entered %s\n", __func__); - - for (stream = 0; stream < 2; stream++) { - substream = pcm->streams[stream].substream; - if (!substream) - continue; - - buf = &substream->dma_buffer; - if (!buf->area) - continue; - - dma_free_writecombine(pcm->card->dev, buf->bytes, - buf->area, buf->addr); - buf->area = NULL; - } -} - -static u64 dma_mask = DMA_BIT_MASK(32); - -static int dma_new(struct snd_card *card, - struct snd_soc_dai *dai, struct snd_pcm *pcm) -{ - int ret = 0; - - pr_debug("Entered %s\n", __func__); - - if (!card->dev->dma_mask) - card->dev->dma_mask = &dma_mask; - if (!card->dev->coherent_dma_mask) - card->dev->coherent_dma_mask = 0xffffffff; - - if (dai->driver->playback.channels_min) { - ret = preallocate_dma_buffer(pcm, - SNDRV_PCM_STREAM_PLAYBACK); - if (ret) - goto out; - } - - if (dai->driver->capture.channels_min) { - ret = preallocate_dma_buffer(pcm, - SNDRV_PCM_STREAM_CAPTURE); - if (ret) - goto out; - } -out: - return ret; -} - -static struct snd_soc_platform_driver samsung_asoc_platform = { - .ops = &dma_ops, - .pcm_new = dma_new, - .pcm_free = dma_free_dma_buffers, -}; - -static int __devinit samsung_asoc_platform_probe(struct platform_device *pdev) -{ - return snd_soc_register_platform(&pdev->dev, &samsung_asoc_platform); -} - -static int __devexit samsung_asoc_platform_remove(struct platform_device *pdev) -{ - snd_soc_unregister_platform(&pdev->dev); - return 0; -} - -static struct platform_driver asoc_dma_driver = { - .driver = { - .name = "samsung-audio", - .owner = THIS_MODULE, - }, - - .probe = samsung_asoc_platform_probe, - .remove = __devexit_p(samsung_asoc_platform_remove), -}; - -static int __init samsung_asoc_init(void) -{ - return platform_driver_register(&asoc_dma_driver); -} -module_init(samsung_asoc_init); - -static void __exit samsung_asoc_exit(void) -{ - platform_driver_unregister(&asoc_dma_driver); -} -module_exit(samsung_asoc_exit); - -MODULE_AUTHOR("Ben Dooks, "); -MODULE_DESCRIPTION("Samsung ASoC DMA Driver"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:samsung-audio"); diff --git a/sound/soc/s3c24xx/dma.h b/sound/soc/s3c24xx/dma.h deleted file mode 100644 index f8cd2b4223af..000000000000 --- a/sound/soc/s3c24xx/dma.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * dma.h -- - * - * 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. - * - * ALSA PCM interface for the Samsung S3C24xx CPU - */ - -#ifndef _S3C_AUDIO_H -#define _S3C_AUDIO_H - -#define ST_RUNNING (1<<0) -#define ST_OPENED (1<<1) - -struct s3c_dma_params { - struct s3c2410_dma_client *client; /* stream identifier */ - int channel; /* Channel ID */ - dma_addr_t dma_addr; - int dma_size; /* Size of the DMA transfer */ -}; - -#define S3C24XX_DAI_I2S 0 - -/* platform data */ -extern struct snd_ac97_bus_ops s3c24xx_ac97_ops; - -#endif diff --git a/sound/soc/s3c24xx/goni_wm8994.c b/sound/soc/s3c24xx/goni_wm8994.c deleted file mode 100644 index dcfac546cb81..000000000000 --- a/sound/soc/s3c24xx/goni_wm8994.c +++ /dev/null @@ -1,309 +0,0 @@ -/* - * goni_wm8994.c - * - * Copyright (C) 2010 Samsung Electronics Co.Ltd - * Author: Chanwoo Choi - * - * 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. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include "../codecs/wm8994.h" -#include "dma.h" -#include "i2s.h" - -#define MACHINE_NAME 0 -#define CPU_VOICE_DAI 1 - -static const char *aquila_str[] = { - [MACHINE_NAME] = "aquila", - [CPU_VOICE_DAI] = "aquila-voice-dai", -}; - -static struct snd_soc_card goni; -static struct platform_device *goni_snd_device; - -/* 3.5 pie jack */ -static struct snd_soc_jack jack; - -/* 3.5 pie jack detection DAPM pins */ -static struct snd_soc_jack_pin jack_pins[] = { - { - .pin = "Headset Mic", - .mask = SND_JACK_MICROPHONE, - }, { - .pin = "Headset Stereophone", - .mask = SND_JACK_HEADPHONE | SND_JACK_MECHANICAL | - SND_JACK_AVOUT, - }, -}; - -/* 3.5 pie jack detection gpios */ -static struct snd_soc_jack_gpio jack_gpios[] = { - { - .gpio = S5PV210_GPH0(6), - .name = "DET_3.5", - .report = SND_JACK_HEADSET | SND_JACK_MECHANICAL | - SND_JACK_AVOUT, - .debounce_time = 200, - }, -}; - -static const struct snd_soc_dapm_widget goni_dapm_widgets[] = { - SND_SOC_DAPM_SPK("Ext Left Spk", NULL), - SND_SOC_DAPM_SPK("Ext Right Spk", NULL), - SND_SOC_DAPM_SPK("Ext Rcv", NULL), - SND_SOC_DAPM_HP("Headset Stereophone", NULL), - SND_SOC_DAPM_MIC("Headset Mic", NULL), - SND_SOC_DAPM_MIC("Main Mic", NULL), - SND_SOC_DAPM_MIC("2nd Mic", NULL), - SND_SOC_DAPM_LINE("Radio In", NULL), -}; - -static const struct snd_soc_dapm_route goni_dapm_routes[] = { - {"Ext Left Spk", NULL, "SPKOUTLP"}, - {"Ext Left Spk", NULL, "SPKOUTLN"}, - - {"Ext Right Spk", NULL, "SPKOUTRP"}, - {"Ext Right Spk", NULL, "SPKOUTRN"}, - - {"Ext Rcv", NULL, "HPOUT2N"}, - {"Ext Rcv", NULL, "HPOUT2P"}, - - {"Headset Stereophone", NULL, "HPOUT1L"}, - {"Headset Stereophone", NULL, "HPOUT1R"}, - - {"IN1RN", NULL, "Headset Mic"}, - {"IN1RP", NULL, "Headset Mic"}, - - {"IN1RN", NULL, "2nd Mic"}, - {"IN1RP", NULL, "2nd Mic"}, - - {"IN1LN", NULL, "Main Mic"}, - {"IN1LP", NULL, "Main Mic"}, - - {"IN2LN", NULL, "Radio In"}, - {"IN2RN", NULL, "Radio In"}, -}; - -static int goni_wm8994_init(struct snd_soc_pcm_runtime *rtd) -{ - struct snd_soc_codec *codec = rtd->codec; - struct snd_soc_dapm_context *dapm = &codec->dapm; - int ret; - - /* add goni specific widgets */ - snd_soc_dapm_new_controls(dapm, goni_dapm_widgets, - ARRAY_SIZE(goni_dapm_widgets)); - - /* set up goni specific audio routes */ - snd_soc_dapm_add_routes(dapm, goni_dapm_routes, - ARRAY_SIZE(goni_dapm_routes)); - - /* set endpoints to not connected */ - snd_soc_dapm_nc_pin(dapm, "IN2LP:VXRN"); - snd_soc_dapm_nc_pin(dapm, "IN2RP:VXRP"); - snd_soc_dapm_nc_pin(dapm, "LINEOUT1N"); - snd_soc_dapm_nc_pin(dapm, "LINEOUT1P"); - snd_soc_dapm_nc_pin(dapm, "LINEOUT2N"); - snd_soc_dapm_nc_pin(dapm, "LINEOUT2P"); - - if (machine_is_aquila()) { - snd_soc_dapm_nc_pin(dapm, "SPKOUTRN"); - snd_soc_dapm_nc_pin(dapm, "SPKOUTRP"); - } - - snd_soc_dapm_sync(dapm); - - /* Headset jack detection */ - ret = snd_soc_jack_new(&goni, "Headset Jack", - SND_JACK_HEADSET | SND_JACK_MECHANICAL | SND_JACK_AVOUT, - &jack); - if (ret) - return ret; - - ret = snd_soc_jack_add_pins(&jack, ARRAY_SIZE(jack_pins), jack_pins); - if (ret) - return ret; - - ret = snd_soc_jack_add_gpios(&jack, ARRAY_SIZE(jack_gpios), jack_gpios); - if (ret) - return ret; - - return 0; -} - -static int goni_hifi_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *codec_dai = rtd->codec_dai; - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; - unsigned int pll_out = 24000000; - int ret = 0; - - /* set the cpu DAI configuration */ - ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S | - SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM); - if (ret < 0) - return ret; - - /* set codec DAI configuration */ - ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | - SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM); - if (ret < 0) - return ret; - - /* set the codec FLL */ - ret = snd_soc_dai_set_pll(codec_dai, WM8994_FLL1, 0, pll_out, - params_rate(params) * 256); - if (ret < 0) - return ret; - - /* set the codec system clock */ - ret = snd_soc_dai_set_sysclk(codec_dai, WM8994_SYSCLK_FLL1, - params_rate(params) * 256, SND_SOC_CLOCK_IN); - if (ret < 0) - return ret; - - return 0; -} - -static struct snd_soc_ops goni_hifi_ops = { - .hw_params = goni_hifi_hw_params, -}; - -static int goni_voice_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *codec_dai = rtd->codec_dai; - unsigned int pll_out = 24000000; - int ret = 0; - - if (params_rate(params) != 8000) - return -EINVAL; - - /* set codec DAI configuration */ - ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_LEFT_J | - SND_SOC_DAIFMT_IB_IF | SND_SOC_DAIFMT_CBM_CFM); - if (ret < 0) - return ret; - - /* set the codec FLL */ - ret = snd_soc_dai_set_pll(codec_dai, WM8994_FLL2, 0, pll_out, - params_rate(params) * 256); - if (ret < 0) - return ret; - - /* set the codec system clock */ - ret = snd_soc_dai_set_sysclk(codec_dai, WM8994_SYSCLK_FLL2, - params_rate(params) * 256, SND_SOC_CLOCK_IN); - if (ret < 0) - return ret; - - return 0; -} - -static struct snd_soc_dai_driver voice_dai = { - .name = "goni-voice-dai", - .id = 0, - .playback = { - .channels_min = 1, - .channels_max = 2, - .rates = SNDRV_PCM_RATE_8000, - .formats = SNDRV_PCM_FMTBIT_S16_LE,}, - .capture = { - .channels_min = 1, - .channels_max = 2, - .rates = SNDRV_PCM_RATE_8000, - .formats = SNDRV_PCM_FMTBIT_S16_LE,}, -}; - -static struct snd_soc_ops goni_voice_ops = { - .hw_params = goni_voice_hw_params, -}; - -static struct snd_soc_dai_link goni_dai[] = { -{ - .name = "WM8994", - .stream_name = "WM8994 HiFi", - .cpu_dai_name = "samsung-i2s.0", - .codec_dai_name = "wm8994-hifi", - .platform_name = "samsung-audio", - .codec_name = "wm8994-codec.0-0x1a", - .init = goni_wm8994_init, - .ops = &goni_hifi_ops, -}, { - .name = "WM8994 Voice", - .stream_name = "Voice", - .cpu_dai_name = "goni-voice-dai", - .codec_dai_name = "wm8994-voice", - .platform_name = "samsung-audio", - .codec_name = "wm8994-codec.0-0x1a", - .ops = &goni_voice_ops, -}, -}; - -static struct snd_soc_card goni = { - .name = "goni", - .dai_link = goni_dai, - .num_links = ARRAY_SIZE(goni_dai), -}; - -static int __init goni_init(void) -{ - int ret; - - if (machine_is_aquila()) { - voice_dai.name = aquila_str[CPU_VOICE_DAI]; - goni_dai[1].cpu_dai_name = aquila_str[CPU_VOICE_DAI]; - goni.name = aquila_str[MACHINE_NAME]; - } else if (!machine_is_goni()) - return -ENODEV; - - goni_snd_device = platform_device_alloc("soc-audio", -1); - if (!goni_snd_device) - return -ENOMEM; - - /* register voice DAI here */ - ret = snd_soc_register_dai(&goni_snd_device->dev, &voice_dai); - if (ret) - return ret; - - platform_set_drvdata(goni_snd_device, &goni); - ret = platform_device_add(goni_snd_device); - - if (ret) - platform_device_put(goni_snd_device); - - return ret; -} - -static void __exit goni_exit(void) -{ - platform_device_unregister(goni_snd_device); -} - -module_init(goni_init); -module_exit(goni_exit); - -/* Module information */ -MODULE_DESCRIPTION("ALSA SoC WM8994 GONI(S5PV210)"); -MODULE_AUTHOR("Chanwoo Choi "); -MODULE_LICENSE("GPL"); diff --git a/sound/soc/s3c24xx/i2s.c b/sound/soc/s3c24xx/i2s.c deleted file mode 100644 index 7e6ddfab76b1..000000000000 --- a/sound/soc/s3c24xx/i2s.c +++ /dev/null @@ -1,1256 +0,0 @@ -/* sound/soc/s3c24xx/i2s.c - * - * ALSA SoC Audio Layer - Samsung I2S Controller driver - * - * Copyright (c) 2010 Samsung Electronics Co. Ltd. - * Jaswinder Singh - * - * 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 - -#include -#include -#include - -#include - -#include "dma.h" -#include "i2s.h" - -#define I2SCON 0x0 -#define I2SMOD 0x4 -#define I2SFIC 0x8 -#define I2SPSR 0xc -#define I2STXD 0x10 -#define I2SRXD 0x14 -#define I2SFICS 0x18 -#define I2STXDS 0x1c - -#define CON_RSTCLR (1 << 31) -#define CON_FRXOFSTATUS (1 << 26) -#define CON_FRXORINTEN (1 << 25) -#define CON_FTXSURSTAT (1 << 24) -#define CON_FTXSURINTEN (1 << 23) -#define CON_TXSDMA_PAUSE (1 << 20) -#define CON_TXSDMA_ACTIVE (1 << 18) - -#define CON_FTXURSTATUS (1 << 17) -#define CON_FTXURINTEN (1 << 16) -#define CON_TXFIFO2_EMPTY (1 << 15) -#define CON_TXFIFO1_EMPTY (1 << 14) -#define CON_TXFIFO2_FULL (1 << 13) -#define CON_TXFIFO1_FULL (1 << 12) - -#define CON_LRINDEX (1 << 11) -#define CON_TXFIFO_EMPTY (1 << 10) -#define CON_RXFIFO_EMPTY (1 << 9) -#define CON_TXFIFO_FULL (1 << 8) -#define CON_RXFIFO_FULL (1 << 7) -#define CON_TXDMA_PAUSE (1 << 6) -#define CON_RXDMA_PAUSE (1 << 5) -#define CON_TXCH_PAUSE (1 << 4) -#define CON_RXCH_PAUSE (1 << 3) -#define CON_TXDMA_ACTIVE (1 << 2) -#define CON_RXDMA_ACTIVE (1 << 1) -#define CON_ACTIVE (1 << 0) - -#define MOD_OPCLK_CDCLK_OUT (0 << 30) -#define MOD_OPCLK_CDCLK_IN (1 << 30) -#define MOD_OPCLK_BCLK_OUT (2 << 30) -#define MOD_OPCLK_PCLK (3 << 30) -#define MOD_OPCLK_MASK (3 << 30) -#define MOD_TXS_IDMA (1 << 28) /* Sec_TXFIFO use I-DMA */ - -#define MOD_BLCS_SHIFT 26 -#define MOD_BLCS_16BIT (0 << MOD_BLCS_SHIFT) -#define MOD_BLCS_8BIT (1 << MOD_BLCS_SHIFT) -#define MOD_BLCS_24BIT (2 << MOD_BLCS_SHIFT) -#define MOD_BLCS_MASK (3 << MOD_BLCS_SHIFT) -#define MOD_BLCP_SHIFT 24 -#define MOD_BLCP_16BIT (0 << MOD_BLCP_SHIFT) -#define MOD_BLCP_8BIT (1 << MOD_BLCP_SHIFT) -#define MOD_BLCP_24BIT (2 << MOD_BLCP_SHIFT) -#define MOD_BLCP_MASK (3 << MOD_BLCP_SHIFT) - -#define MOD_C2DD_HHALF (1 << 21) /* Discard Higher-half */ -#define MOD_C2DD_LHALF (1 << 20) /* Discard Lower-half */ -#define MOD_C1DD_HHALF (1 << 19) -#define MOD_C1DD_LHALF (1 << 18) -#define MOD_DC2_EN (1 << 17) -#define MOD_DC1_EN (1 << 16) -#define MOD_BLC_16BIT (0 << 13) -#define MOD_BLC_8BIT (1 << 13) -#define MOD_BLC_24BIT (2 << 13) -#define MOD_BLC_MASK (3 << 13) - -#define MOD_IMS_SYSMUX (1 << 10) -#define MOD_SLAVE (1 << 11) -#define MOD_TXONLY (0 << 8) -#define MOD_RXONLY (1 << 8) -#define MOD_TXRX (2 << 8) -#define MOD_MASK (3 << 8) -#define MOD_LR_LLOW (0 << 7) -#define MOD_LR_RLOW (1 << 7) -#define MOD_SDF_IIS (0 << 5) -#define MOD_SDF_MSB (1 << 5) -#define MOD_SDF_LSB (2 << 5) -#define MOD_SDF_MASK (3 << 5) -#define MOD_RCLK_256FS (0 << 3) -#define MOD_RCLK_512FS (1 << 3) -#define MOD_RCLK_384FS (2 << 3) -#define MOD_RCLK_768FS (3 << 3) -#define MOD_RCLK_MASK (3 << 3) -#define MOD_BCLK_32FS (0 << 1) -#define MOD_BCLK_48FS (1 << 1) -#define MOD_BCLK_16FS (2 << 1) -#define MOD_BCLK_24FS (3 << 1) -#define MOD_BCLK_MASK (3 << 1) -#define MOD_8BIT (1 << 0) - -#define MOD_CDCLKCON (1 << 12) - -#define PSR_PSREN (1 << 15) - -#define FIC_TX2COUNT(x) (((x) >> 24) & 0xf) -#define FIC_TX1COUNT(x) (((x) >> 16) & 0xf) - -#define FIC_TXFLUSH (1 << 15) -#define FIC_RXFLUSH (1 << 7) -#define FIC_TXCOUNT(x) (((x) >> 8) & 0xf) -#define FIC_RXCOUNT(x) (((x) >> 0) & 0xf) -#define FICS_TXCOUNT(x) (((x) >> 8) & 0x7f) - -#define msecs_to_loops(t) (loops_per_jiffy / 1000 * HZ * t) - -struct i2s_dai { - /* Platform device for this DAI */ - struct platform_device *pdev; - /* IOREMAP'd SFRs */ - void __iomem *addr; - /* Physical base address of SFRs */ - u32 base; - /* Rate of RCLK source clock */ - unsigned long rclk_srcrate; - /* Frame Clock */ - unsigned frmclk; - /* - * Specifically requested RCLK,BCLK by MACHINE Driver. - * 0 indicates CPU driver is free to choose any value. - */ - unsigned rfs, bfs; - /* I2S Controller's core clock */ - struct clk *clk; - /* Clock for generating I2S signals */ - struct clk *op_clk; - /* Array of clock names for op_clk */ - const char **src_clk; - /* Pointer to the Primary_Fifo if this is Sec_Fifo, NULL otherwise */ - struct i2s_dai *pri_dai; - /* Pointer to the Secondary_Fifo if it has one, NULL otherwise */ - struct i2s_dai *sec_dai; -#define DAI_OPENED (1 << 0) /* Dai is opened */ -#define DAI_MANAGER (1 << 1) /* Dai is the manager */ - unsigned mode; - /* Driver for this DAI */ - struct snd_soc_dai_driver i2s_dai_drv; - /* DMA parameters */ - struct s3c_dma_params dma_playback; - struct s3c_dma_params dma_capture; - u32 quirks; - u32 suspend_i2smod; - u32 suspend_i2scon; - u32 suspend_i2spsr; -}; - -/* Lock for cross i/f checks */ -static DEFINE_SPINLOCK(lock); - -/* If this is the 'overlay' stereo DAI */ -static inline bool is_secondary(struct i2s_dai *i2s) -{ - return i2s->pri_dai ? true : false; -} - -/* If operating in SoC-Slave mode */ -static inline bool is_slave(struct i2s_dai *i2s) -{ - return (readl(i2s->addr + I2SMOD) & MOD_SLAVE) ? true : false; -} - -/* If this interface of the controller is transmitting data */ -static inline bool tx_active(struct i2s_dai *i2s) -{ - u32 active; - - if (!i2s) - return false; - - active = readl(i2s->addr + I2SMOD); - - if (is_secondary(i2s)) - active &= CON_TXSDMA_ACTIVE; - else - active &= CON_TXDMA_ACTIVE; - - return active ? true : false; -} - -/* If the other interface of the controller is transmitting data */ -static inline bool other_tx_active(struct i2s_dai *i2s) -{ - struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai; - - return tx_active(other); -} - -/* If any interface of the controller is transmitting data */ -static inline bool any_tx_active(struct i2s_dai *i2s) -{ - return tx_active(i2s) || other_tx_active(i2s); -} - -/* If this interface of the controller is receiving data */ -static inline bool rx_active(struct i2s_dai *i2s) -{ - u32 active; - - if (!i2s) - return false; - - active = readl(i2s->addr + I2SMOD) & CON_RXDMA_ACTIVE; - - return active ? true : false; -} - -/* If the other interface of the controller is receiving data */ -static inline bool other_rx_active(struct i2s_dai *i2s) -{ - struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai; - - return rx_active(other); -} - -/* If any interface of the controller is receiving data */ -static inline bool any_rx_active(struct i2s_dai *i2s) -{ - return rx_active(i2s) || other_rx_active(i2s); -} - -/* If the other DAI is transmitting or receiving data */ -static inline bool other_active(struct i2s_dai *i2s) -{ - return other_rx_active(i2s) || other_tx_active(i2s); -} - -/* If this DAI is transmitting or receiving data */ -static inline bool this_active(struct i2s_dai *i2s) -{ - return tx_active(i2s) || rx_active(i2s); -} - -/* If the controller is active anyway */ -static inline bool any_active(struct i2s_dai *i2s) -{ - return this_active(i2s) || other_active(i2s); -} - -static inline struct i2s_dai *to_info(struct snd_soc_dai *dai) -{ - return snd_soc_dai_get_drvdata(dai); -} - -static inline bool is_opened(struct i2s_dai *i2s) -{ - if (i2s && (i2s->mode & DAI_OPENED)) - return true; - else - return false; -} - -static inline bool is_manager(struct i2s_dai *i2s) -{ - if (is_opened(i2s) && (i2s->mode & DAI_MANAGER)) - return true; - else - return false; -} - -/* Read RCLK of I2S (in multiples of LRCLK) */ -static inline unsigned get_rfs(struct i2s_dai *i2s) -{ - u32 rfs = (readl(i2s->addr + I2SMOD) >> 3) & 0x3; - - switch (rfs) { - case 3: return 768; - case 2: return 384; - case 1: return 512; - default: return 256; - } -} - -/* Write RCLK of I2S (in multiples of LRCLK) */ -static inline void set_rfs(struct i2s_dai *i2s, unsigned rfs) -{ - u32 mod = readl(i2s->addr + I2SMOD); - - mod &= ~MOD_RCLK_MASK; - - switch (rfs) { - case 768: - mod |= MOD_RCLK_768FS; - break; - case 512: - mod |= MOD_RCLK_512FS; - break; - case 384: - mod |= MOD_RCLK_384FS; - break; - default: - mod |= MOD_RCLK_256FS; - break; - } - - writel(mod, i2s->addr + I2SMOD); -} - -/* Read Bit-Clock of I2S (in multiples of LRCLK) */ -static inline unsigned get_bfs(struct i2s_dai *i2s) -{ - u32 bfs = (readl(i2s->addr + I2SMOD) >> 1) & 0x3; - - switch (bfs) { - case 3: return 24; - case 2: return 16; - case 1: return 48; - default: return 32; - } -} - -/* Write Bit-Clock of I2S (in multiples of LRCLK) */ -static inline void set_bfs(struct i2s_dai *i2s, unsigned bfs) -{ - u32 mod = readl(i2s->addr + I2SMOD); - - mod &= ~MOD_BCLK_MASK; - - switch (bfs) { - case 48: - mod |= MOD_BCLK_48FS; - break; - case 32: - mod |= MOD_BCLK_32FS; - break; - case 24: - mod |= MOD_BCLK_24FS; - break; - case 16: - mod |= MOD_BCLK_16FS; - break; - default: - dev_err(&i2s->pdev->dev, "Wrong BCLK Divider!\n"); - return; - } - - writel(mod, i2s->addr + I2SMOD); -} - -/* Sample-Size */ -static inline int get_blc(struct i2s_dai *i2s) -{ - int blc = readl(i2s->addr + I2SMOD); - - blc = (blc >> 13) & 0x3; - - switch (blc) { - case 2: return 24; - case 1: return 8; - default: return 16; - } -} - -/* TX Channel Control */ -static void i2s_txctrl(struct i2s_dai *i2s, int on) -{ - void __iomem *addr = i2s->addr; - u32 con = readl(addr + I2SCON); - u32 mod = readl(addr + I2SMOD) & ~MOD_MASK; - - if (on) { - con |= CON_ACTIVE; - con &= ~CON_TXCH_PAUSE; - - if (is_secondary(i2s)) { - con |= CON_TXSDMA_ACTIVE; - con &= ~CON_TXSDMA_PAUSE; - } else { - con |= CON_TXDMA_ACTIVE; - con &= ~CON_TXDMA_PAUSE; - } - - if (any_rx_active(i2s)) - mod |= MOD_TXRX; - else - mod |= MOD_TXONLY; - } else { - if (is_secondary(i2s)) { - con |= CON_TXSDMA_PAUSE; - con &= ~CON_TXSDMA_ACTIVE; - } else { - con |= CON_TXDMA_PAUSE; - con &= ~CON_TXDMA_ACTIVE; - } - - if (other_tx_active(i2s)) { - writel(con, addr + I2SCON); - return; - } - - con |= CON_TXCH_PAUSE; - - if (any_rx_active(i2s)) - mod |= MOD_RXONLY; - else - con &= ~CON_ACTIVE; - } - - writel(mod, addr + I2SMOD); - writel(con, addr + I2SCON); -} - -/* RX Channel Control */ -static void i2s_rxctrl(struct i2s_dai *i2s, int on) -{ - void __iomem *addr = i2s->addr; - u32 con = readl(addr + I2SCON); - u32 mod = readl(addr + I2SMOD) & ~MOD_MASK; - - if (on) { - con |= CON_RXDMA_ACTIVE | CON_ACTIVE; - con &= ~(CON_RXDMA_PAUSE | CON_RXCH_PAUSE); - - if (any_tx_active(i2s)) - mod |= MOD_TXRX; - else - mod |= MOD_RXONLY; - } else { - con |= CON_RXDMA_PAUSE | CON_RXCH_PAUSE; - con &= ~CON_RXDMA_ACTIVE; - - if (any_tx_active(i2s)) - mod |= MOD_TXONLY; - else - con &= ~CON_ACTIVE; - } - - writel(mod, addr + I2SMOD); - writel(con, addr + I2SCON); -} - -/* Flush FIFO of an interface */ -static inline void i2s_fifo(struct i2s_dai *i2s, u32 flush) -{ - void __iomem *fic; - u32 val; - - if (!i2s) - return; - - if (is_secondary(i2s)) - fic = i2s->addr + I2SFICS; - else - fic = i2s->addr + I2SFIC; - - /* Flush the FIFO */ - writel(readl(fic) | flush, fic); - - /* Be patient */ - val = msecs_to_loops(1) / 1000; /* 1 usec */ - while (--val) - cpu_relax(); - - writel(readl(fic) & ~flush, fic); -} - -static int i2s_set_sysclk(struct snd_soc_dai *dai, - int clk_id, unsigned int rfs, int dir) -{ - struct i2s_dai *i2s = to_info(dai); - struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai; - u32 mod = readl(i2s->addr + I2SMOD); - - switch (clk_id) { - case SAMSUNG_I2S_CDCLK: - /* Shouldn't matter in GATING(CLOCK_IN) mode */ - if (dir == SND_SOC_CLOCK_IN) - rfs = 0; - - if ((rfs && other->rfs && (other->rfs != rfs)) || - (any_active(i2s) && - (((dir == SND_SOC_CLOCK_IN) - && !(mod & MOD_CDCLKCON)) || - ((dir == SND_SOC_CLOCK_OUT) - && (mod & MOD_CDCLKCON))))) { - dev_err(&i2s->pdev->dev, - "%s:%d Other DAI busy\n", __func__, __LINE__); - return -EAGAIN; - } - - if (dir == SND_SOC_CLOCK_IN) - mod |= MOD_CDCLKCON; - else - mod &= ~MOD_CDCLKCON; - - i2s->rfs = rfs; - break; - - case SAMSUNG_I2S_RCLKSRC_0: /* clock corrsponding to IISMOD[10] := 0 */ - case SAMSUNG_I2S_RCLKSRC_1: /* clock corrsponding to IISMOD[10] := 1 */ - if ((i2s->quirks & QUIRK_NO_MUXPSR) - || (clk_id == SAMSUNG_I2S_RCLKSRC_0)) - clk_id = 0; - else - clk_id = 1; - - if (!any_active(i2s)) { - if (i2s->op_clk) { - if ((clk_id && !(mod & MOD_IMS_SYSMUX)) || - (!clk_id && (mod & MOD_IMS_SYSMUX))) { - clk_disable(i2s->op_clk); - clk_put(i2s->op_clk); - } else { - return 0; - } - } - - i2s->op_clk = clk_get(&i2s->pdev->dev, - i2s->src_clk[clk_id]); - clk_enable(i2s->op_clk); - i2s->rclk_srcrate = clk_get_rate(i2s->op_clk); - - /* Over-ride the other's */ - if (other) { - other->op_clk = i2s->op_clk; - other->rclk_srcrate = i2s->rclk_srcrate; - } - } else if ((!clk_id && (mod & MOD_IMS_SYSMUX)) - || (clk_id && !(mod & MOD_IMS_SYSMUX))) { - dev_err(&i2s->pdev->dev, - "%s:%d Other DAI busy\n", __func__, __LINE__); - return -EAGAIN; - } else { - /* Call can't be on the active DAI */ - i2s->op_clk = other->op_clk; - i2s->rclk_srcrate = other->rclk_srcrate; - return 0; - } - - if (clk_id == 0) - mod &= ~MOD_IMS_SYSMUX; - else - mod |= MOD_IMS_SYSMUX; - break; - - default: - dev_err(&i2s->pdev->dev, "We don't serve that!\n"); - return -EINVAL; - } - - writel(mod, i2s->addr + I2SMOD); - - return 0; -} - -static int i2s_set_fmt(struct snd_soc_dai *dai, - unsigned int fmt) -{ - struct i2s_dai *i2s = to_info(dai); - u32 mod = readl(i2s->addr + I2SMOD); - u32 tmp = 0; - - /* Format is priority */ - switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { - case SND_SOC_DAIFMT_RIGHT_J: - tmp |= MOD_LR_RLOW; - tmp |= MOD_SDF_MSB; - break; - case SND_SOC_DAIFMT_LEFT_J: - tmp |= MOD_LR_RLOW; - tmp |= MOD_SDF_LSB; - break; - case SND_SOC_DAIFMT_I2S: - tmp |= MOD_SDF_IIS; - break; - default: - dev_err(&i2s->pdev->dev, "Format not supported\n"); - return -EINVAL; - } - - /* - * INV flag is relative to the FORMAT flag - if set it simply - * flips the polarity specified by the Standard - */ - switch (fmt & SND_SOC_DAIFMT_INV_MASK) { - case SND_SOC_DAIFMT_NB_NF: - break; - case SND_SOC_DAIFMT_NB_IF: - if (tmp & MOD_LR_RLOW) - tmp &= ~MOD_LR_RLOW; - else - tmp |= MOD_LR_RLOW; - break; - default: - dev_err(&i2s->pdev->dev, "Polarity not supported\n"); - return -EINVAL; - } - - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: - tmp |= MOD_SLAVE; - break; - case SND_SOC_DAIFMT_CBS_CFS: - /* Set default source clock in Master mode */ - if (i2s->rclk_srcrate == 0) - i2s_set_sysclk(dai, SAMSUNG_I2S_RCLKSRC_0, - 0, SND_SOC_CLOCK_IN); - break; - default: - dev_err(&i2s->pdev->dev, "master/slave format not supported\n"); - return -EINVAL; - } - - if (any_active(i2s) && - ((mod & (MOD_SDF_MASK | MOD_LR_RLOW - | MOD_SLAVE)) != tmp)) { - dev_err(&i2s->pdev->dev, - "%s:%d Other DAI busy\n", __func__, __LINE__); - return -EAGAIN; - } - - mod &= ~(MOD_SDF_MASK | MOD_LR_RLOW | MOD_SLAVE); - mod |= tmp; - writel(mod, i2s->addr + I2SMOD); - - return 0; -} - -static int i2s_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) -{ - struct i2s_dai *i2s = to_info(dai); - u32 mod = readl(i2s->addr + I2SMOD); - - if (!is_secondary(i2s)) - mod &= ~(MOD_DC2_EN | MOD_DC1_EN); - - switch (params_channels(params)) { - case 6: - mod |= MOD_DC2_EN; - case 4: - mod |= MOD_DC1_EN; - break; - case 2: - break; - default: - dev_err(&i2s->pdev->dev, "%d channels not supported\n", - params_channels(params)); - return -EINVAL; - } - - if (is_secondary(i2s)) - mod &= ~MOD_BLCS_MASK; - else - mod &= ~MOD_BLCP_MASK; - - if (is_manager(i2s)) - mod &= ~MOD_BLC_MASK; - - switch (params_format(params)) { - case SNDRV_PCM_FORMAT_S8: - if (is_secondary(i2s)) - mod |= MOD_BLCS_8BIT; - else - mod |= MOD_BLCP_8BIT; - if (is_manager(i2s)) - mod |= MOD_BLC_8BIT; - break; - case SNDRV_PCM_FORMAT_S16_LE: - if (is_secondary(i2s)) - mod |= MOD_BLCS_16BIT; - else - mod |= MOD_BLCP_16BIT; - if (is_manager(i2s)) - mod |= MOD_BLC_16BIT; - break; - case SNDRV_PCM_FORMAT_S24_LE: - if (is_secondary(i2s)) - mod |= MOD_BLCS_24BIT; - else - mod |= MOD_BLCP_24BIT; - if (is_manager(i2s)) - mod |= MOD_BLC_24BIT; - break; - default: - dev_err(&i2s->pdev->dev, "Format(%d) not supported\n", - params_format(params)); - return -EINVAL; - } - writel(mod, i2s->addr + I2SMOD); - - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - snd_soc_dai_set_dma_data(dai, substream, - (void *)&i2s->dma_playback); - else - snd_soc_dai_set_dma_data(dai, substream, - (void *)&i2s->dma_capture); - - i2s->frmclk = params_rate(params); - - return 0; -} - -/* We set constraints on the substream acc to the version of I2S */ -static int i2s_startup(struct snd_pcm_substream *substream, - struct snd_soc_dai *dai) -{ - struct i2s_dai *i2s = to_info(dai); - struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai; - unsigned long flags; - - spin_lock_irqsave(&lock, flags); - - i2s->mode |= DAI_OPENED; - - if (is_manager(other)) - i2s->mode &= ~DAI_MANAGER; - else - i2s->mode |= DAI_MANAGER; - - /* Enforce set_sysclk in Master mode */ - i2s->rclk_srcrate = 0; - - spin_unlock_irqrestore(&lock, flags); - - return 0; -} - -static void i2s_shutdown(struct snd_pcm_substream *substream, - struct snd_soc_dai *dai) -{ - struct i2s_dai *i2s = to_info(dai); - struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai; - unsigned long flags; - - spin_lock_irqsave(&lock, flags); - - i2s->mode &= ~DAI_OPENED; - i2s->mode &= ~DAI_MANAGER; - - if (is_opened(other)) - other->mode |= DAI_MANAGER; - - /* Reset any constraint on RFS and BFS */ - i2s->rfs = 0; - i2s->bfs = 0; - - spin_unlock_irqrestore(&lock, flags); - - /* Gate CDCLK by default */ - if (!is_opened(other)) - i2s_set_sysclk(dai, SAMSUNG_I2S_CDCLK, - 0, SND_SOC_CLOCK_IN); -} - -static int config_setup(struct i2s_dai *i2s) -{ - struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai; - unsigned rfs, bfs, blc; - u32 psr; - - blc = get_blc(i2s); - - bfs = i2s->bfs; - - if (!bfs && other) - bfs = other->bfs; - - /* Select least possible multiple(2) if no constraint set */ - if (!bfs) - bfs = blc * 2; - - rfs = i2s->rfs; - - if (!rfs && other) - rfs = other->rfs; - - if ((rfs == 256 || rfs == 512) && (blc == 24)) { - dev_err(&i2s->pdev->dev, - "%d-RFS not supported for 24-blc\n", rfs); - return -EINVAL; - } - - if (!rfs) { - if (bfs == 16 || bfs == 32) - rfs = 256; - else - rfs = 384; - } - - /* If already setup and running */ - if (any_active(i2s) && (get_rfs(i2s) != rfs || get_bfs(i2s) != bfs)) { - dev_err(&i2s->pdev->dev, - "%s:%d Other DAI busy\n", __func__, __LINE__); - return -EAGAIN; - } - - /* Don't bother RFS, BFS & PSR in Slave mode */ - if (is_slave(i2s)) - return 0; - - set_bfs(i2s, bfs); - set_rfs(i2s, rfs); - - if (!(i2s->quirks & QUIRK_NO_MUXPSR)) { - psr = i2s->rclk_srcrate / i2s->frmclk / rfs; - writel(((psr - 1) << 8) | PSR_PSREN, i2s->addr + I2SPSR); - dev_dbg(&i2s->pdev->dev, - "RCLK_SRC=%luHz PSR=%u, RCLK=%dfs, BCLK=%dfs\n", - i2s->rclk_srcrate, psr, rfs, bfs); - } - - return 0; -} - -static int i2s_trigger(struct snd_pcm_substream *substream, - int cmd, struct snd_soc_dai *dai) -{ - int capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE); - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct i2s_dai *i2s = to_info(rtd->cpu_dai); - unsigned long flags; - - switch (cmd) { - case SNDRV_PCM_TRIGGER_START: - case SNDRV_PCM_TRIGGER_RESUME: - case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - local_irq_save(flags); - - if (capture) - i2s_fifo(i2s, FIC_RXFLUSH); - else - i2s_fifo(i2s, FIC_TXFLUSH); - - if (config_setup(i2s)) { - local_irq_restore(flags); - return -EINVAL; - } - - if (capture) - i2s_rxctrl(i2s, 1); - else - i2s_txctrl(i2s, 1); - - local_irq_restore(flags); - break; - case SNDRV_PCM_TRIGGER_STOP: - case SNDRV_PCM_TRIGGER_SUSPEND: - case SNDRV_PCM_TRIGGER_PAUSE_PUSH: - local_irq_save(flags); - - if (capture) - i2s_rxctrl(i2s, 0); - else - i2s_txctrl(i2s, 0); - - local_irq_restore(flags); - break; - } - - return 0; -} - -static int i2s_set_clkdiv(struct snd_soc_dai *dai, - int div_id, int div) -{ - struct i2s_dai *i2s = to_info(dai); - struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai; - - switch (div_id) { - case SAMSUNG_I2S_DIV_BCLK: - if ((any_active(i2s) && div && (get_bfs(i2s) != div)) - || (other && other->bfs && (other->bfs != div))) { - dev_err(&i2s->pdev->dev, - "%s:%d Other DAI busy\n", __func__, __LINE__); - return -EAGAIN; - } - i2s->bfs = div; - break; - default: - dev_err(&i2s->pdev->dev, - "Invalid clock divider(%d)\n", div_id); - return -EINVAL; - } - - return 0; -} - -static snd_pcm_sframes_t -i2s_delay(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) -{ - struct i2s_dai *i2s = to_info(dai); - u32 reg = readl(i2s->addr + I2SFIC); - snd_pcm_sframes_t delay; - - if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) - delay = FIC_RXCOUNT(reg); - else if (is_secondary(i2s)) - delay = FICS_TXCOUNT(readl(i2s->addr + I2SFICS)); - else - delay = FIC_TXCOUNT(reg); - - return delay; -} - -#ifdef CONFIG_PM -static int i2s_suspend(struct snd_soc_dai *dai) -{ - struct i2s_dai *i2s = to_info(dai); - - if (dai->active) { - i2s->suspend_i2smod = readl(i2s->addr + I2SMOD); - i2s->suspend_i2scon = readl(i2s->addr + I2SCON); - i2s->suspend_i2spsr = readl(i2s->addr + I2SPSR); - } - - return 0; -} - -static int i2s_resume(struct snd_soc_dai *dai) -{ - struct i2s_dai *i2s = to_info(dai); - - if (dai->active) { - writel(i2s->suspend_i2scon, i2s->addr + I2SCON); - writel(i2s->suspend_i2smod, i2s->addr + I2SMOD); - writel(i2s->suspend_i2spsr, i2s->addr + I2SPSR); - } - - return 0; -} -#else -#define i2s_suspend NULL -#define i2s_resume NULL -#endif - -static int samsung_i2s_dai_probe(struct snd_soc_dai *dai) -{ - struct i2s_dai *i2s = to_info(dai); - struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai; - - if (other && other->clk) /* If this is probe on secondary */ - goto probe_exit; - - i2s->addr = ioremap(i2s->base, 0x100); - if (i2s->addr == NULL) { - dev_err(&i2s->pdev->dev, "cannot ioremap registers\n"); - return -ENXIO; - } - - i2s->clk = clk_get(&i2s->pdev->dev, "iis"); - if (IS_ERR(i2s->clk)) { - dev_err(&i2s->pdev->dev, "failed to get i2s_clock\n"); - iounmap(i2s->addr); - return -ENOENT; - } - clk_enable(i2s->clk); - - if (other) { - other->addr = i2s->addr; - other->clk = i2s->clk; - } - - if (i2s->quirks & QUIRK_NEED_RSTCLR) - writel(CON_RSTCLR, i2s->addr + I2SCON); - -probe_exit: - /* Reset any constraint on RFS and BFS */ - i2s->rfs = 0; - i2s->bfs = 0; - i2s_txctrl(i2s, 0); - i2s_rxctrl(i2s, 0); - i2s_fifo(i2s, FIC_TXFLUSH); - i2s_fifo(other, FIC_TXFLUSH); - i2s_fifo(i2s, FIC_RXFLUSH); - - /* Gate CDCLK by default */ - if (!is_opened(other)) - i2s_set_sysclk(dai, SAMSUNG_I2S_CDCLK, - 0, SND_SOC_CLOCK_IN); - - return 0; -} - -static int samsung_i2s_dai_remove(struct snd_soc_dai *dai) -{ - struct i2s_dai *i2s = snd_soc_dai_get_drvdata(dai); - struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai; - - if (!other || !other->clk) { - - if (i2s->quirks & QUIRK_NEED_RSTCLR) - writel(0, i2s->addr + I2SCON); - - clk_disable(i2s->clk); - clk_put(i2s->clk); - - iounmap(i2s->addr); - } - - i2s->clk = NULL; - - return 0; -} - -static struct snd_soc_dai_ops samsung_i2s_dai_ops = { - .trigger = i2s_trigger, - .hw_params = i2s_hw_params, - .set_fmt = i2s_set_fmt, - .set_clkdiv = i2s_set_clkdiv, - .set_sysclk = i2s_set_sysclk, - .startup = i2s_startup, - .shutdown = i2s_shutdown, - .delay = i2s_delay, -}; - -#define SAMSUNG_I2S_RATES SNDRV_PCM_RATE_8000_96000 - -#define SAMSUNG_I2S_FMTS (SNDRV_PCM_FMTBIT_S8 | \ - SNDRV_PCM_FMTBIT_S16_LE | \ - SNDRV_PCM_FMTBIT_S24_LE) - -static __devinit -struct i2s_dai *i2s_alloc_dai(struct platform_device *pdev, bool sec) -{ - struct i2s_dai *i2s; - - i2s = kzalloc(sizeof(struct i2s_dai), GFP_KERNEL); - if (i2s == NULL) - return NULL; - - i2s->pdev = pdev; - i2s->pri_dai = NULL; - i2s->sec_dai = NULL; - i2s->i2s_dai_drv.symmetric_rates = 1; - i2s->i2s_dai_drv.probe = samsung_i2s_dai_probe; - i2s->i2s_dai_drv.remove = samsung_i2s_dai_remove; - i2s->i2s_dai_drv.ops = &samsung_i2s_dai_ops; - i2s->i2s_dai_drv.suspend = i2s_suspend; - i2s->i2s_dai_drv.resume = i2s_resume; - i2s->i2s_dai_drv.playback.channels_min = 2; - i2s->i2s_dai_drv.playback.channels_max = 2; - i2s->i2s_dai_drv.playback.rates = SAMSUNG_I2S_RATES; - i2s->i2s_dai_drv.playback.formats = SAMSUNG_I2S_FMTS; - - if (!sec) { - i2s->i2s_dai_drv.capture.channels_min = 2; - i2s->i2s_dai_drv.capture.channels_max = 2; - i2s->i2s_dai_drv.capture.rates = SAMSUNG_I2S_RATES; - i2s->i2s_dai_drv.capture.formats = SAMSUNG_I2S_FMTS; - } else { /* Create a new platform_device for Secondary */ - i2s->pdev = platform_device_register_resndata(NULL, - pdev->name, pdev->id + SAMSUNG_I2S_SECOFF, - NULL, 0, NULL, 0); - if (IS_ERR(i2s->pdev)) { - kfree(i2s); - return NULL; - } - } - - /* Pre-assign snd_soc_dai_set_drvdata */ - dev_set_drvdata(&i2s->pdev->dev, i2s); - - return i2s; -} - -static __devinit int samsung_i2s_probe(struct platform_device *pdev) -{ - u32 dma_pl_chan, dma_cp_chan, dma_pl_sec_chan; - struct i2s_dai *pri_dai, *sec_dai = NULL; - struct s3c_audio_pdata *i2s_pdata; - struct samsung_i2s *i2s_cfg; - struct resource *res; - u32 regs_base, quirks; - int ret = 0; - - /* Call during Seconday interface registration */ - if (pdev->id >= SAMSUNG_I2S_SECOFF) { - sec_dai = dev_get_drvdata(&pdev->dev); - snd_soc_register_dai(&sec_dai->pdev->dev, - &sec_dai->i2s_dai_drv); - return 0; - } - - i2s_pdata = pdev->dev.platform_data; - if (i2s_pdata == NULL) { - dev_err(&pdev->dev, "Can't work without s3c_audio_pdata\n"); - return -EINVAL; - } - - res = platform_get_resource(pdev, IORESOURCE_DMA, 0); - if (!res) { - dev_err(&pdev->dev, "Unable to get I2S-TX dma resource\n"); - return -ENXIO; - } - dma_pl_chan = res->start; - - res = platform_get_resource(pdev, IORESOURCE_DMA, 1); - if (!res) { - dev_err(&pdev->dev, "Unable to get I2S-RX dma resource\n"); - return -ENXIO; - } - dma_cp_chan = res->start; - - res = platform_get_resource(pdev, IORESOURCE_DMA, 2); - if (res) - dma_pl_sec_chan = res->start; - else - dma_pl_sec_chan = 0; - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - dev_err(&pdev->dev, "Unable to get I2S SFR address\n"); - return -ENXIO; - } - - if (!request_mem_region(res->start, resource_size(res), - "samsung-i2s")) { - dev_err(&pdev->dev, "Unable to request SFR region\n"); - return -EBUSY; - } - regs_base = res->start; - - i2s_cfg = &i2s_pdata->type.i2s; - quirks = i2s_cfg->quirks; - - pri_dai = i2s_alloc_dai(pdev, false); - if (!pri_dai) { - dev_err(&pdev->dev, "Unable to alloc I2S_pri\n"); - ret = -ENOMEM; - goto err1; - } - - pri_dai->dma_playback.dma_addr = regs_base + I2STXD; - pri_dai->dma_capture.dma_addr = regs_base + I2SRXD; - pri_dai->dma_playback.client = - (struct s3c2410_dma_client *)&pri_dai->dma_playback; - pri_dai->dma_capture.client = - (struct s3c2410_dma_client *)&pri_dai->dma_capture; - pri_dai->dma_playback.channel = dma_pl_chan; - pri_dai->dma_capture.channel = dma_cp_chan; - pri_dai->src_clk = i2s_cfg->src_clk; - pri_dai->dma_playback.dma_size = 4; - pri_dai->dma_capture.dma_size = 4; - pri_dai->base = regs_base; - pri_dai->quirks = quirks; - - if (quirks & QUIRK_PRI_6CHAN) - pri_dai->i2s_dai_drv.playback.channels_max = 6; - - if (quirks & QUIRK_SEC_DAI) { - sec_dai = i2s_alloc_dai(pdev, true); - if (!sec_dai) { - dev_err(&pdev->dev, "Unable to alloc I2S_sec\n"); - ret = -ENOMEM; - goto err2; - } - sec_dai->dma_playback.dma_addr = regs_base + I2STXDS; - sec_dai->dma_playback.client = - (struct s3c2410_dma_client *)&sec_dai->dma_playback; - /* Use iDMA always if SysDMA not provided */ - sec_dai->dma_playback.channel = dma_pl_sec_chan ? : -1; - sec_dai->src_clk = i2s_cfg->src_clk; - sec_dai->dma_playback.dma_size = 4; - sec_dai->base = regs_base; - sec_dai->quirks = quirks; - sec_dai->pri_dai = pri_dai; - pri_dai->sec_dai = sec_dai; - } - - if (i2s_pdata->cfg_gpio && i2s_pdata->cfg_gpio(pdev)) { - dev_err(&pdev->dev, "Unable to configure gpio\n"); - ret = -EINVAL; - goto err3; - } - - snd_soc_register_dai(&pri_dai->pdev->dev, &pri_dai->i2s_dai_drv); - - return 0; -err3: - kfree(sec_dai); -err2: - kfree(pri_dai); -err1: - release_mem_region(regs_base, resource_size(res)); - - return ret; -} - -static __devexit int samsung_i2s_remove(struct platform_device *pdev) -{ - struct i2s_dai *i2s, *other; - - i2s = dev_get_drvdata(&pdev->dev); - other = i2s->pri_dai ? : i2s->sec_dai; - - if (other) { - other->pri_dai = NULL; - other->sec_dai = NULL; - } else { - struct resource *res; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (res) - release_mem_region(res->start, resource_size(res)); - } - - i2s->pri_dai = NULL; - i2s->sec_dai = NULL; - - kfree(i2s); - - snd_soc_unregister_dai(&pdev->dev); - - return 0; -} - -static struct platform_driver samsung_i2s_driver = { - .probe = samsung_i2s_probe, - .remove = samsung_i2s_remove, - .driver = { - .name = "samsung-i2s", - .owner = THIS_MODULE, - }, -}; - -static int __init samsung_i2s_init(void) -{ - return platform_driver_register(&samsung_i2s_driver); -} -module_init(samsung_i2s_init); - -static void __exit samsung_i2s_exit(void) -{ - platform_driver_unregister(&samsung_i2s_driver); -} -module_exit(samsung_i2s_exit); - -/* Module information */ -MODULE_AUTHOR("Jaswinder Singh, "); -MODULE_DESCRIPTION("Samsung I2S Interface"); -MODULE_ALIAS("platform:samsung-i2s"); -MODULE_LICENSE("GPL"); diff --git a/sound/soc/s3c24xx/i2s.h b/sound/soc/s3c24xx/i2s.h deleted file mode 100644 index d3180b37dc10..000000000000 --- a/sound/soc/s3c24xx/i2s.h +++ /dev/null @@ -1,29 +0,0 @@ -/* sound/soc/s3c24xx/i2s.h - * - * ALSA SoC Audio Layer - Samsung I2S Controller driver - * - * Copyright (c) 2010 Samsung Electronics Co. Ltd. - * Jaswinder Singh - * - * 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. - */ - -#ifndef __SND_SOC_SAMSUNG_I2S_H -#define __SND_SOC_SAMSUNG_I2S_H - -/* - * Maximum number of I2S blocks that any SoC can have. - * The secondary interface of a CPU dai(if there exists any), - * is indexed at [cpu-dai's ID + SAMSUNG_I2S_SECOFF] - */ -#define SAMSUNG_I2S_SECOFF 4 - -#define SAMSUNG_I2S_DIV_BCLK 1 - -#define SAMSUNG_I2S_RCLKSRC_0 0 -#define SAMSUNG_I2S_RCLKSRC_1 1 -#define SAMSUNG_I2S_CDCLK 2 - -#endif /* __SND_SOC_SAMSUNG_I2S_H */ diff --git a/sound/soc/s3c24xx/jive_wm8750.c b/sound/soc/s3c24xx/jive_wm8750.c deleted file mode 100644 index 9e318dcb673b..000000000000 --- a/sound/soc/s3c24xx/jive_wm8750.c +++ /dev/null @@ -1,191 +0,0 @@ -/* sound/soc/s3c24xx/jive_wm8750.c - * - * Copyright 2007,2008 Simtec Electronics - * - * Based on sound/soc/pxa/spitz.c - * Copyright 2005 Wolfson Microelectronics PLC. - * Copyright 2005 Openedhand Ltd. - * - * 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 -#include -#include - -#include -#include -#include - -#include - -#include "dma.h" -#include "s3c2412-i2s.h" - -#include "../codecs/wm8750.h" - -static const struct snd_soc_dapm_route audio_map[] = { - { "Headphone Jack", NULL, "LOUT1" }, - { "Headphone Jack", NULL, "ROUT1" }, - { "Internal Speaker", NULL, "LOUT2" }, - { "Internal Speaker", NULL, "ROUT2" }, - { "LINPUT1", NULL, "Line Input" }, - { "RINPUT1", NULL, "Line Input" }, -}; - -static const struct snd_soc_dapm_widget wm8750_dapm_widgets[] = { - SND_SOC_DAPM_HP("Headphone Jack", NULL), - SND_SOC_DAPM_SPK("Internal Speaker", NULL), - SND_SOC_DAPM_LINE("Line In", NULL), -}; - -static int jive_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *codec_dai = rtd->codec_dai; - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; - struct s3c_i2sv2_rate_calc div; - unsigned int clk = 0; - int ret = 0; - - switch (params_rate(params)) { - case 8000: - case 16000: - case 48000: - case 96000: - clk = 12288000; - break; - case 11025: - case 22050: - case 44100: - clk = 11289600; - break; - } - - s3c_i2sv2_iis_calc_rate(&div, NULL, params_rate(params), - s3c_i2sv2_get_clock(cpu_dai)); - - /* set codec DAI configuration */ - ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | - SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBS_CFS); - if (ret < 0) - return ret; - - /* set cpu DAI configuration */ - ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S | - SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBS_CFS); - if (ret < 0) - return ret; - - /* set the codec system clock for DAC and ADC */ - ret = snd_soc_dai_set_sysclk(codec_dai, WM8750_SYSCLK, clk, - SND_SOC_CLOCK_IN); - if (ret < 0) - return ret; - - ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C2412_DIV_RCLK, div.fs_div); - if (ret < 0) - return ret; - - ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C2412_DIV_PRESCALER, - div.clk_div - 1); - if (ret < 0) - return ret; - - return 0; -} - -static struct snd_soc_ops jive_ops = { - .hw_params = jive_hw_params, -}; - -static int jive_wm8750_init(struct snd_soc_pcm_runtime *rtd) -{ - struct snd_soc_codec *codec = rtd->codec; - struct snd_soc_dapm_context *dapm = &codec->dapm; - int err; - - /* These endpoints are not being used. */ - snd_soc_dapm_nc_pin(dapm, "LINPUT2"); - snd_soc_dapm_nc_pin(dapm, "RINPUT2"); - snd_soc_dapm_nc_pin(dapm, "LINPUT3"); - snd_soc_dapm_nc_pin(dapm, "RINPUT3"); - snd_soc_dapm_nc_pin(dapm, "OUT3"); - snd_soc_dapm_nc_pin(dapm, "MONO"); - - /* Add jive specific widgets */ - err = snd_soc_dapm_new_controls(dapm, wm8750_dapm_widgets, - ARRAY_SIZE(wm8750_dapm_widgets)); - if (err) { - printk(KERN_ERR "%s: failed to add widgets (%d)\n", - __func__, err); - return err; - } - - snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); - snd_soc_dapm_sync(dapm); - - return 0; -} - -static struct snd_soc_dai_link jive_dai = { - .name = "wm8750", - .stream_name = "WM8750", - .cpu_dai_name = "s3c2412-i2s", - .codec_dai_name = "wm8750-hifi", - .platform_name = "samsung-audio", - .codec_name = "wm8750-codec.0-0x1a", - .init = jive_wm8750_init, - .ops = &jive_ops, -}; - -/* jive audio machine driver */ -static struct snd_soc_card snd_soc_machine_jive = { - .name = "Jive", - .dai_link = &jive_dai, - .num_links = 1, -}; - -static struct platform_device *jive_snd_device; - -static int __init jive_init(void) -{ - int ret; - - if (!machine_is_jive()) - return 0; - - printk("JIVE WM8750 Audio support\n"); - - jive_snd_device = platform_device_alloc("soc-audio", -1); - if (!jive_snd_device) - return -ENOMEM; - - platform_set_drvdata(jive_snd_device, &snd_soc_machine_jive); - ret = platform_device_add(jive_snd_device); - - if (ret) - platform_device_put(jive_snd_device); - - return ret; -} - -static void __exit jive_exit(void) -{ - platform_device_unregister(jive_snd_device); -} - -module_init(jive_init); -module_exit(jive_exit); - -MODULE_AUTHOR("Ben Dooks "); -MODULE_DESCRIPTION("ALSA SoC Jive Audio support"); -MODULE_LICENSE("GPL"); diff --git a/sound/soc/s3c24xx/lm4857.h b/sound/soc/s3c24xx/lm4857.h deleted file mode 100644 index 0cf5b7011d6f..000000000000 --- a/sound/soc/s3c24xx/lm4857.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * lm4857.h -- ALSA Soc Audio Layer - * - * Copyright 2007 Wolfson Microelectronics PLC. - * Author: Graeme Gregory - * graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com - * - * 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. - * - * Revision history - * 18th Jun 2007 Initial version. - */ - -#ifndef LM4857_H_ -#define LM4857_H_ - -/* The register offsets in the cache array */ -#define LM4857_MVOL 0 -#define LM4857_LVOL 1 -#define LM4857_RVOL 2 -#define LM4857_CTRL 3 - -/* the shifts required to set these bits */ -#define LM4857_3D 5 -#define LM4857_WAKEUP 5 -#define LM4857_EPGAIN 4 - -#endif /*LM4857_H_*/ - diff --git a/sound/soc/s3c24xx/ln2440sbc_alc650.c b/sound/soc/s3c24xx/ln2440sbc_alc650.c deleted file mode 100644 index a2bb34def740..000000000000 --- a/sound/soc/s3c24xx/ln2440sbc_alc650.c +++ /dev/null @@ -1,77 +0,0 @@ -/* - * SoC audio for ln2440sbc - * - * Copyright 2007 KonekTel, a.s. - * Author: Ivan Kuten - * ivan.kuten@promwad.com - * - * Heavily based on smdk2443_wm9710.c - * Copyright 2007 Wolfson Microelectronics PLC. - * Author: Graeme Gregory - * graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com - * - * 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 -#include - -#include "dma.h" -#include "ac97.h" - -static struct snd_soc_card ln2440sbc; - -static struct snd_soc_dai_link ln2440sbc_dai[] = { -{ - .name = "AC97", - .stream_name = "AC97 HiFi", - .cpu_dai_name = "samsung-ac97", - .codec_dai_name = "ac97-hifi", - .codec_name = "ac97-codec", - .platform_name = "samsung-audio", -}, -}; - -static struct snd_soc_card ln2440sbc = { - .name = "LN2440SBC", - .dai_link = ln2440sbc_dai, - .num_links = ARRAY_SIZE(ln2440sbc_dai), -}; - -static struct platform_device *ln2440sbc_snd_ac97_device; - -static int __init ln2440sbc_init(void) -{ - int ret; - - ln2440sbc_snd_ac97_device = platform_device_alloc("soc-audio", -1); - if (!ln2440sbc_snd_ac97_device) - return -ENOMEM; - - platform_set_drvdata(ln2440sbc_snd_ac97_device, &ln2440sbc); - ret = platform_device_add(ln2440sbc_snd_ac97_device); - - if (ret) - platform_device_put(ln2440sbc_snd_ac97_device); - - return ret; -} - -static void __exit ln2440sbc_exit(void) -{ - platform_device_unregister(ln2440sbc_snd_ac97_device); -} - -module_init(ln2440sbc_init); -module_exit(ln2440sbc_exit); - -/* Module information */ -MODULE_AUTHOR("Ivan Kuten"); -MODULE_DESCRIPTION("ALSA SoC ALC650 LN2440SBC"); -MODULE_LICENSE("GPL"); diff --git a/sound/soc/s3c24xx/neo1973_gta02_wm8753.c b/sound/soc/s3c24xx/neo1973_gta02_wm8753.c deleted file mode 100644 index 920e8d1f8841..000000000000 --- a/sound/soc/s3c24xx/neo1973_gta02_wm8753.c +++ /dev/null @@ -1,504 +0,0 @@ -/* - * neo1973_gta02_wm8753.c -- SoC audio for Openmoko Freerunner(GTA02) - * - * Copyright 2007 Openmoko Inc - * Author: Graeme Gregory - * Copyright 2007 Wolfson Microelectronics PLC. - * Author: Graeme Gregory - * Copyright 2009 Wolfson Microelectronics - * - * 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. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include - -#include -#include -#include -#include "../codecs/wm8753.h" -#include "dma.h" -#include "s3c24xx-i2s.h" - -static struct snd_soc_card neo1973_gta02; - -static int neo1973_gta02_hifi_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *codec_dai = rtd->codec_dai; - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; - unsigned int pll_out = 0, bclk = 0; - int ret = 0; - unsigned long iis_clkrate; - - iis_clkrate = s3c24xx_i2s_get_clockrate(); - - switch (params_rate(params)) { - case 8000: - case 16000: - pll_out = 12288000; - break; - case 48000: - bclk = WM8753_BCLK_DIV_4; - pll_out = 12288000; - break; - case 96000: - bclk = WM8753_BCLK_DIV_2; - pll_out = 12288000; - break; - case 11025: - bclk = WM8753_BCLK_DIV_16; - pll_out = 11289600; - break; - case 22050: - bclk = WM8753_BCLK_DIV_8; - pll_out = 11289600; - break; - case 44100: - bclk = WM8753_BCLK_DIV_4; - pll_out = 11289600; - break; - case 88200: - bclk = WM8753_BCLK_DIV_2; - pll_out = 11289600; - break; - } - - /* set codec DAI configuration */ - ret = snd_soc_dai_set_fmt(codec_dai, - SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBM_CFM); - if (ret < 0) - return ret; - - /* set cpu DAI configuration */ - ret = snd_soc_dai_set_fmt(cpu_dai, - SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBM_CFM); - if (ret < 0) - return ret; - - /* set the codec system clock for DAC and ADC */ - ret = snd_soc_dai_set_sysclk(codec_dai, WM8753_MCLK, pll_out, - SND_SOC_CLOCK_IN); - if (ret < 0) - return ret; - - /* set MCLK division for sample rate */ - ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C24XX_DIV_MCLK, - S3C2410_IISMOD_32FS); - if (ret < 0) - return ret; - - /* set codec BCLK division for sample rate */ - ret = snd_soc_dai_set_clkdiv(codec_dai, - WM8753_BCLKDIV, bclk); - if (ret < 0) - return ret; - - /* set prescaler division for sample rate */ - ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C24XX_DIV_PRESCALER, - S3C24XX_PRESCALE(4, 4)); - if (ret < 0) - return ret; - - /* codec PLL input is PCLK/4 */ - ret = snd_soc_dai_set_pll(codec_dai, WM8753_PLL1, 0, - iis_clkrate / 4, pll_out); - if (ret < 0) - return ret; - - return 0; -} - -static int neo1973_gta02_hifi_hw_free(struct snd_pcm_substream *substream) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *codec_dai = rtd->codec_dai; - - /* disable the PLL */ - return snd_soc_dai_set_pll(codec_dai, WM8753_PLL1, 0, 0, 0); -} - -/* - * Neo1973 WM8753 HiFi DAI opserations. - */ -static struct snd_soc_ops neo1973_gta02_hifi_ops = { - .hw_params = neo1973_gta02_hifi_hw_params, - .hw_free = neo1973_gta02_hifi_hw_free, -}; - -static int neo1973_gta02_voice_hw_params( - struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *codec_dai = rtd->codec_dai; - unsigned int pcmdiv = 0; - int ret = 0; - unsigned long iis_clkrate; - - iis_clkrate = s3c24xx_i2s_get_clockrate(); - - if (params_rate(params) != 8000) - return -EINVAL; - if (params_channels(params) != 1) - return -EINVAL; - - pcmdiv = WM8753_PCM_DIV_6; /* 2.048 MHz */ - - /* todo: gg check mode (DSP_B) against CSR datasheet */ - /* set codec DAI configuration */ - ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_DSP_B | - SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); - if (ret < 0) - return ret; - - /* set the codec system clock for DAC and ADC */ - ret = snd_soc_dai_set_sysclk(codec_dai, WM8753_PCMCLK, - 12288000, SND_SOC_CLOCK_IN); - if (ret < 0) - return ret; - - /* set codec PCM division for sample rate */ - ret = snd_soc_dai_set_clkdiv(codec_dai, WM8753_PCMDIV, - pcmdiv); - if (ret < 0) - return ret; - - /* configure and enable PLL for 12.288MHz output */ - ret = snd_soc_dai_set_pll(codec_dai, WM8753_PLL2, 0, - iis_clkrate / 4, 12288000); - if (ret < 0) - return ret; - - return 0; -} - -static int neo1973_gta02_voice_hw_free(struct snd_pcm_substream *substream) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *codec_dai = rtd->codec_dai; - - /* disable the PLL */ - return snd_soc_dai_set_pll(codec_dai, WM8753_PLL2, 0, 0, 0); -} - -static struct snd_soc_ops neo1973_gta02_voice_ops = { - .hw_params = neo1973_gta02_voice_hw_params, - .hw_free = neo1973_gta02_voice_hw_free, -}; - -#define LM4853_AMP 1 -#define LM4853_SPK 2 - -static u8 lm4853_state; - -/* This has no effect, it exists only to maintain compatibility with - * existing ALSA state files. - */ -static int lm4853_set_state(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int val = ucontrol->value.integer.value[0]; - - if (val) - lm4853_state |= LM4853_AMP; - else - lm4853_state &= ~LM4853_AMP; - - return 0; -} - -static int lm4853_get_state(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - ucontrol->value.integer.value[0] = lm4853_state & LM4853_AMP; - - return 0; -} - -static int lm4853_set_spk(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int val = ucontrol->value.integer.value[0]; - - if (val) { - lm4853_state |= LM4853_SPK; - gpio_set_value(GTA02_GPIO_HP_IN, 0); - } else { - lm4853_state &= ~LM4853_SPK; - gpio_set_value(GTA02_GPIO_HP_IN, 1); - } - - return 0; -} - -static int lm4853_get_spk(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - ucontrol->value.integer.value[0] = (lm4853_state & LM4853_SPK) >> 1; - - return 0; -} - -static int lm4853_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *k, - int event) -{ - gpio_set_value(GTA02_GPIO_AMP_SHUT, SND_SOC_DAPM_EVENT_OFF(event)); - - return 0; -} - -static const struct snd_soc_dapm_widget wm8753_dapm_widgets[] = { - SND_SOC_DAPM_SPK("Stereo Out", lm4853_event), - SND_SOC_DAPM_LINE("GSM Line Out", NULL), - SND_SOC_DAPM_LINE("GSM Line In", NULL), - SND_SOC_DAPM_MIC("Headset Mic", NULL), - SND_SOC_DAPM_MIC("Handset Mic", NULL), - SND_SOC_DAPM_SPK("Handset Spk", NULL), -}; - - -/* example machine audio_mapnections */ -static const struct snd_soc_dapm_route audio_map[] = { - - /* Connections to the lm4853 amp */ - {"Stereo Out", NULL, "LOUT1"}, - {"Stereo Out", NULL, "ROUT1"}, - - /* Connections to the GSM Module */ - {"GSM Line Out", NULL, "MONO1"}, - {"GSM Line Out", NULL, "MONO2"}, - {"RXP", NULL, "GSM Line In"}, - {"RXN", NULL, "GSM Line In"}, - - /* Connections to Headset */ - {"MIC1", NULL, "Mic Bias"}, - {"Mic Bias", NULL, "Headset Mic"}, - - /* Call Mic */ - {"MIC2", NULL, "Mic Bias"}, - {"MIC2N", NULL, "Mic Bias"}, - {"Mic Bias", NULL, "Handset Mic"}, - - /* Call Speaker */ - {"Handset Spk", NULL, "LOUT2"}, - {"Handset Spk", NULL, "ROUT2"}, - - /* Connect the ALC pins */ - {"ACIN", NULL, "ACOP"}, -}; - -static const struct snd_kcontrol_new wm8753_neo1973_gta02_controls[] = { - SOC_DAPM_PIN_SWITCH("Stereo Out"), - SOC_DAPM_PIN_SWITCH("GSM Line Out"), - SOC_DAPM_PIN_SWITCH("GSM Line In"), - SOC_DAPM_PIN_SWITCH("Headset Mic"), - SOC_DAPM_PIN_SWITCH("Handset Mic"), - SOC_DAPM_PIN_SWITCH("Handset Spk"), - - /* This has no effect, it exists only to maintain compatibility with - * existing ALSA state files. - */ - SOC_SINGLE_EXT("Amp State Switch", 6, 0, 1, 0, - lm4853_get_state, - lm4853_set_state), - SOC_SINGLE_EXT("Amp Spk Switch", 7, 0, 1, 0, - lm4853_get_spk, - lm4853_set_spk), -}; - -/* - * This is an example machine initialisation for a wm8753 connected to a - * neo1973 GTA02. - */ -static int neo1973_gta02_wm8753_init(struct snd_soc_pcm_runtime *rtd) -{ - struct snd_soc_codec *codec = rtd->codec; - struct snd_soc_dapm_context *dapm = &codec->dapm; - int err; - - /* set up NC codec pins */ - snd_soc_dapm_nc_pin(dapm, "OUT3"); - snd_soc_dapm_nc_pin(dapm, "OUT4"); - snd_soc_dapm_nc_pin(dapm, "LINE1"); - snd_soc_dapm_nc_pin(dapm, "LINE2"); - - /* Add neo1973 gta02 specific widgets */ - snd_soc_dapm_new_controls(dapm, wm8753_dapm_widgets, - ARRAY_SIZE(wm8753_dapm_widgets)); - - /* add neo1973 gta02 specific controls */ - err = snd_soc_add_controls(codec, wm8753_neo1973_gta02_controls, - ARRAY_SIZE(wm8753_neo1973_gta02_controls)); - - if (err < 0) - return err; - - /* set up neo1973 gta02 specific audio path audio_map */ - snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); - - /* set endpoints to default off mode */ - snd_soc_dapm_disable_pin(dapm, "Stereo Out"); - snd_soc_dapm_disable_pin(dapm, "GSM Line Out"); - snd_soc_dapm_disable_pin(dapm, "GSM Line In"); - snd_soc_dapm_disable_pin(dapm, "Headset Mic"); - snd_soc_dapm_disable_pin(dapm, "Handset Mic"); - snd_soc_dapm_disable_pin(dapm, "Handset Spk"); - - /* allow audio paths from the GSM modem to run during suspend */ - snd_soc_dapm_ignore_suspend(dapm, "Stereo Out"); - snd_soc_dapm_ignore_suspend(dapm, "GSM Line Out"); - snd_soc_dapm_ignore_suspend(dapm, "GSM Line In"); - snd_soc_dapm_ignore_suspend(dapm, "Headset Mic"); - snd_soc_dapm_ignore_suspend(dapm, "Handset Mic"); - snd_soc_dapm_ignore_suspend(dapm, "Handset Spk"); - - snd_soc_dapm_sync(dapm); - - return 0; -} - -/* - * BT Codec DAI - */ -static struct snd_soc_dai_driver bt_dai = { - .name = "bluetooth-dai", - .playback = { - .channels_min = 1, - .channels_max = 1, - .rates = SNDRV_PCM_RATE_8000, - .formats = SNDRV_PCM_FMTBIT_S16_LE,}, - .capture = { - .channels_min = 1, - .channels_max = 1, - .rates = SNDRV_PCM_RATE_8000, - .formats = SNDRV_PCM_FMTBIT_S16_LE,}, -}; - -static struct snd_soc_dai_link neo1973_gta02_dai[] = { -{ /* Hifi Playback - for similatious use with voice below */ - .name = "WM8753", - .stream_name = "WM8753 HiFi", - .cpu_dai_name = "s3c24xx-i2s", - .codec_dai_name = "wm8753-hifi", - .init = neo1973_gta02_wm8753_init, - .platform_name = "samsung-audio", - .codec_name = "wm8753-codec.0-0x1a", - .ops = &neo1973_gta02_hifi_ops, -}, -{ /* Voice via BT */ - .name = "Bluetooth", - .stream_name = "Voice", - .cpu_dai_name = "bluetooth-dai", - .codec_dai_name = "wm8753-voice", - .ops = &neo1973_gta02_voice_ops, - .codec_name = "wm8753-codec.0-0x1a", - .platform_name = "samsung-audio", -}, -}; - -static struct snd_soc_card neo1973_gta02 = { - .name = "neo1973-gta02", - .dai_link = neo1973_gta02_dai, - .num_links = ARRAY_SIZE(neo1973_gta02_dai), -}; - -static struct platform_device *neo1973_gta02_snd_device; - -static int __init neo1973_gta02_init(void) -{ - int ret; - - if (!machine_is_neo1973_gta02()) { - printk(KERN_INFO - "Only GTA02 is supported by this ASoC driver\n"); - return -ENODEV; - } - - neo1973_gta02_snd_device = platform_device_alloc("soc-audio", -1); - if (!neo1973_gta02_snd_device) - return -ENOMEM; - - /* register bluetooth DAI here */ - ret = snd_soc_register_dai(&neo1973_gta02_snd_device->dev, -1, &bt_dai); - if (ret) { - platform_device_put(neo1973_gta02_snd_device); - return ret; - } - - platform_set_drvdata(neo1973_gta02_snd_device, &neo1973_gta02); - ret = platform_device_add(neo1973_gta02_snd_device); - - if (ret) { - platform_device_put(neo1973_gta02_snd_device); - return ret; - } - - /* Initialise GPIOs used by amp */ - ret = gpio_request(GTA02_GPIO_HP_IN, "GTA02_HP_IN"); - if (ret) { - pr_err("gta02_wm8753: Failed to register GPIO %d\n", GTA02_GPIO_HP_IN); - goto err_unregister_device; - } - - ret = gpio_direction_output(GTA02_GPIO_HP_IN, 1); - if (ret) { - pr_err("gta02_wm8753: Failed to configure GPIO %d\n", GTA02_GPIO_HP_IN); - goto err_free_gpio_hp_in; - } - - ret = gpio_request(GTA02_GPIO_AMP_SHUT, "GTA02_AMP_SHUT"); - if (ret) { - pr_err("gta02_wm8753: Failed to register GPIO %d\n", GTA02_GPIO_AMP_SHUT); - goto err_free_gpio_hp_in; - } - - ret = gpio_direction_output(GTA02_GPIO_AMP_SHUT, 1); - if (ret) { - pr_err("gta02_wm8753: Failed to configure GPIO %d\n", GTA02_GPIO_AMP_SHUT); - goto err_free_gpio_amp_shut; - } - - return 0; - -err_free_gpio_amp_shut: - gpio_free(GTA02_GPIO_AMP_SHUT); -err_free_gpio_hp_in: - gpio_free(GTA02_GPIO_HP_IN); -err_unregister_device: - platform_device_unregister(neo1973_gta02_snd_device); - return ret; -} -module_init(neo1973_gta02_init); - -static void __exit neo1973_gta02_exit(void) -{ - snd_soc_unregister_dai(&neo1973_gta02_snd_device->dev, -1); - platform_device_unregister(neo1973_gta02_snd_device); - gpio_free(GTA02_GPIO_HP_IN); - gpio_free(GTA02_GPIO_AMP_SHUT); -} -module_exit(neo1973_gta02_exit); - -/* Module information */ -MODULE_AUTHOR("Graeme Gregory, graeme@openmoko.org"); -MODULE_DESCRIPTION("ALSA SoC WM8753 Neo1973 GTA02"); -MODULE_LICENSE("GPL"); diff --git a/sound/soc/s3c24xx/neo1973_wm8753.c b/sound/soc/s3c24xx/neo1973_wm8753.c deleted file mode 100644 index c7a24514beb5..000000000000 --- a/sound/soc/s3c24xx/neo1973_wm8753.c +++ /dev/null @@ -1,706 +0,0 @@ -/* - * neo1973_wm8753.c -- SoC audio for Neo1973 - * - * Copyright 2007 Wolfson Microelectronics PLC. - * Author: Graeme Gregory - * graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com - * - * 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. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "../codecs/wm8753.h" -#include "lm4857.h" -#include "dma.h" -#include "s3c24xx-i2s.h" - -/* define the scenarios */ -#define NEO_AUDIO_OFF 0 -#define NEO_GSM_CALL_AUDIO_HANDSET 1 -#define NEO_GSM_CALL_AUDIO_HEADSET 2 -#define NEO_GSM_CALL_AUDIO_BLUETOOTH 3 -#define NEO_STEREO_TO_SPEAKERS 4 -#define NEO_STEREO_TO_HEADPHONES 5 -#define NEO_CAPTURE_HANDSET 6 -#define NEO_CAPTURE_HEADSET 7 -#define NEO_CAPTURE_BLUETOOTH 8 - -static struct snd_soc_card neo1973; -static struct i2c_client *i2c; - -static int neo1973_hifi_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *codec_dai = rtd->codec_dai; - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; - unsigned int pll_out = 0, bclk = 0; - int ret = 0; - unsigned long iis_clkrate; - - pr_debug("Entered %s\n", __func__); - - iis_clkrate = s3c24xx_i2s_get_clockrate(); - - switch (params_rate(params)) { - case 8000: - case 16000: - pll_out = 12288000; - break; - case 48000: - bclk = WM8753_BCLK_DIV_4; - pll_out = 12288000; - break; - case 96000: - bclk = WM8753_BCLK_DIV_2; - pll_out = 12288000; - break; - case 11025: - bclk = WM8753_BCLK_DIV_16; - pll_out = 11289600; - break; - case 22050: - bclk = WM8753_BCLK_DIV_8; - pll_out = 11289600; - break; - case 44100: - bclk = WM8753_BCLK_DIV_4; - pll_out = 11289600; - break; - case 88200: - bclk = WM8753_BCLK_DIV_2; - pll_out = 11289600; - break; - } - - /* set codec DAI configuration */ - ret = snd_soc_dai_set_fmt(codec_dai, - SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBM_CFM); - if (ret < 0) - return ret; - - /* set cpu DAI configuration */ - ret = snd_soc_dai_set_fmt(cpu_dai, - SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBM_CFM); - if (ret < 0) - return ret; - - /* set the codec system clock for DAC and ADC */ - ret = snd_soc_dai_set_sysclk(codec_dai, WM8753_MCLK, pll_out, - SND_SOC_CLOCK_IN); - if (ret < 0) - return ret; - - /* set MCLK division for sample rate */ - ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C24XX_DIV_MCLK, - S3C2410_IISMOD_32FS); - if (ret < 0) - return ret; - - /* set codec BCLK division for sample rate */ - ret = snd_soc_dai_set_clkdiv(codec_dai, WM8753_BCLKDIV, bclk); - if (ret < 0) - return ret; - - /* set prescaler division for sample rate */ - ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C24XX_DIV_PRESCALER, - S3C24XX_PRESCALE(4, 4)); - if (ret < 0) - return ret; - - /* codec PLL input is PCLK/4 */ - ret = snd_soc_dai_set_pll(codec_dai, WM8753_PLL1, 0, - iis_clkrate / 4, pll_out); - if (ret < 0) - return ret; - - return 0; -} - -static int neo1973_hifi_hw_free(struct snd_pcm_substream *substream) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *codec_dai = rtd->codec_dai; - - pr_debug("Entered %s\n", __func__); - - /* disable the PLL */ - return snd_soc_dai_set_pll(codec_dai, WM8753_PLL1, 0, 0, 0); -} - -/* - * Neo1973 WM8753 HiFi DAI opserations. - */ -static struct snd_soc_ops neo1973_hifi_ops = { - .hw_params = neo1973_hifi_hw_params, - .hw_free = neo1973_hifi_hw_free, -}; - -static int neo1973_voice_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *codec_dai = rtd->codec_dai; - unsigned int pcmdiv = 0; - int ret = 0; - unsigned long iis_clkrate; - - pr_debug("Entered %s\n", __func__); - - iis_clkrate = s3c24xx_i2s_get_clockrate(); - - if (params_rate(params) != 8000) - return -EINVAL; - if (params_channels(params) != 1) - return -EINVAL; - - pcmdiv = WM8753_PCM_DIV_6; /* 2.048 MHz */ - - /* todo: gg check mode (DSP_B) against CSR datasheet */ - /* set codec DAI configuration */ - ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_DSP_B | - SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); - if (ret < 0) - return ret; - - /* set the codec system clock for DAC and ADC */ - ret = snd_soc_dai_set_sysclk(codec_dai, WM8753_PCMCLK, 12288000, - SND_SOC_CLOCK_IN); - if (ret < 0) - return ret; - - /* set codec PCM division for sample rate */ - ret = snd_soc_dai_set_clkdiv(codec_dai, WM8753_PCMDIV, pcmdiv); - if (ret < 0) - return ret; - - /* configure and enable PLL for 12.288MHz output */ - ret = snd_soc_dai_set_pll(codec_dai, WM8753_PLL2, 0, - iis_clkrate / 4, 12288000); - if (ret < 0) - return ret; - - return 0; -} - -static int neo1973_voice_hw_free(struct snd_pcm_substream *substream) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *codec_dai = rtd->codec_dai; - - pr_debug("Entered %s\n", __func__); - - /* disable the PLL */ - return snd_soc_dai_set_pll(codec_dai, WM8753_PLL2, 0, 0, 0); -} - -static struct snd_soc_ops neo1973_voice_ops = { - .hw_params = neo1973_voice_hw_params, - .hw_free = neo1973_voice_hw_free, -}; - -static int neo1973_scenario; - -static int neo1973_get_scenario(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - ucontrol->value.integer.value[0] = neo1973_scenario; - return 0; -} - -static int set_scenario_endpoints(struct snd_soc_codec *codec, int scenario) -{ - struct snd_soc_dapm_context *dapm = &codec->dapm; - - pr_debug("Entered %s\n", __func__); - - switch (neo1973_scenario) { - case NEO_AUDIO_OFF: - snd_soc_dapm_disable_pin(dapm, "Audio Out"); - snd_soc_dapm_disable_pin(dapm, "GSM Line Out"); - snd_soc_dapm_disable_pin(dapm, "GSM Line In"); - snd_soc_dapm_disable_pin(dapm, "Headset Mic"); - snd_soc_dapm_disable_pin(dapm, "Call Mic"); - break; - case NEO_GSM_CALL_AUDIO_HANDSET: - snd_soc_dapm_enable_pin(dapm, "Audio Out"); - snd_soc_dapm_enable_pin(dapm, "GSM Line Out"); - snd_soc_dapm_enable_pin(dapm, "GSM Line In"); - snd_soc_dapm_disable_pin(dapm, "Headset Mic"); - snd_soc_dapm_enable_pin(dapm, "Call Mic"); - break; - case NEO_GSM_CALL_AUDIO_HEADSET: - snd_soc_dapm_enable_pin(dapm, "Audio Out"); - snd_soc_dapm_enable_pin(dapm, "GSM Line Out"); - snd_soc_dapm_enable_pin(dapm, "GSM Line In"); - snd_soc_dapm_enable_pin(dapm, "Headset Mic"); - snd_soc_dapm_disable_pin(dapm, "Call Mic"); - break; - case NEO_GSM_CALL_AUDIO_BLUETOOTH: - snd_soc_dapm_disable_pin(dapm, "Audio Out"); - snd_soc_dapm_enable_pin(dapm, "GSM Line Out"); - snd_soc_dapm_enable_pin(dapm, "GSM Line In"); - snd_soc_dapm_disable_pin(dapm, "Headset Mic"); - snd_soc_dapm_disable_pin(dapm, "Call Mic"); - break; - case NEO_STEREO_TO_SPEAKERS: - snd_soc_dapm_enable_pin(dapm, "Audio Out"); - snd_soc_dapm_disable_pin(dapm, "GSM Line Out"); - snd_soc_dapm_disable_pin(dapm, "GSM Line In"); - snd_soc_dapm_disable_pin(dapm, "Headset Mic"); - snd_soc_dapm_disable_pin(dapm, "Call Mic"); - break; - case NEO_STEREO_TO_HEADPHONES: - snd_soc_dapm_enable_pin(dapm, "Audio Out"); - snd_soc_dapm_disable_pin(dapm, "GSM Line Out"); - snd_soc_dapm_disable_pin(dapm, "GSM Line In"); - snd_soc_dapm_disable_pin(dapm, "Headset Mic"); - snd_soc_dapm_disable_pin(dapm, "Call Mic"); - break; - case NEO_CAPTURE_HANDSET: - snd_soc_dapm_disable_pin(dapm, "Audio Out"); - snd_soc_dapm_disable_pin(dapm, "GSM Line Out"); - snd_soc_dapm_disable_pin(dapm, "GSM Line In"); - snd_soc_dapm_disable_pin(dapm, "Headset Mic"); - snd_soc_dapm_enable_pin(dapm, "Call Mic"); - break; - case NEO_CAPTURE_HEADSET: - snd_soc_dapm_disable_pin(dapm, "Audio Out"); - snd_soc_dapm_disable_pin(dapm, "GSM Line Out"); - snd_soc_dapm_disable_pin(dapm, "GSM Line In"); - snd_soc_dapm_enable_pin(dapm, "Headset Mic"); - snd_soc_dapm_disable_pin(dapm, "Call Mic"); - break; - case NEO_CAPTURE_BLUETOOTH: - snd_soc_dapm_disable_pin(dapm, "Audio Out"); - snd_soc_dapm_disable_pin(dapm, "GSM Line Out"); - snd_soc_dapm_disable_pin(dapm, "GSM Line In"); - snd_soc_dapm_disable_pin(dapm, "Headset Mic"); - snd_soc_dapm_disable_pin(dapm, "Call Mic"); - break; - default: - snd_soc_dapm_disable_pin(dapm, "Audio Out"); - snd_soc_dapm_disable_pin(dapm, "GSM Line Out"); - snd_soc_dapm_disable_pin(dapm, "GSM Line In"); - snd_soc_dapm_disable_pin(dapm, "Headset Mic"); - snd_soc_dapm_disable_pin(dapm, "Call Mic"); - } - - snd_soc_dapm_sync(dapm); - - return 0; -} - -static int neo1973_set_scenario(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - - pr_debug("Entered %s\n", __func__); - - if (neo1973_scenario == ucontrol->value.integer.value[0]) - return 0; - - neo1973_scenario = ucontrol->value.integer.value[0]; - set_scenario_endpoints(codec, neo1973_scenario); - return 1; -} - -static u8 lm4857_regs[4] = {0x00, 0x40, 0x80, 0xC0}; - -static void lm4857_write_regs(void) -{ - pr_debug("Entered %s\n", __func__); - - if (i2c_master_send(i2c, lm4857_regs, 4) != 4) - printk(KERN_ERR "lm4857: i2c write failed\n"); -} - -static int lm4857_get_reg(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct soc_mixer_control *mc = - (struct soc_mixer_control *)kcontrol->private_value; - int reg = mc->reg; - int shift = mc->shift; - int mask = mc->max; - - pr_debug("Entered %s\n", __func__); - - ucontrol->value.integer.value[0] = (lm4857_regs[reg] >> shift) & mask; - return 0; -} - -static int lm4857_set_reg(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct soc_mixer_control *mc = - (struct soc_mixer_control *)kcontrol->private_value; - int reg = mc->reg; - int shift = mc->shift; - int mask = mc->max; - - if (((lm4857_regs[reg] >> shift) & mask) == - ucontrol->value.integer.value[0]) - return 0; - - lm4857_regs[reg] &= ~(mask << shift); - lm4857_regs[reg] |= ucontrol->value.integer.value[0] << shift; - lm4857_write_regs(); - return 1; -} - -static int lm4857_get_mode(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - u8 value = lm4857_regs[LM4857_CTRL] & 0x0F; - - pr_debug("Entered %s\n", __func__); - - if (value) - value -= 5; - - ucontrol->value.integer.value[0] = value; - return 0; -} - -static int lm4857_set_mode(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - u8 value = ucontrol->value.integer.value[0]; - - pr_debug("Entered %s\n", __func__); - - if (value) - value += 5; - - if ((lm4857_regs[LM4857_CTRL] & 0x0F) == value) - return 0; - - lm4857_regs[LM4857_CTRL] &= 0xF0; - lm4857_regs[LM4857_CTRL] |= value; - lm4857_write_regs(); - return 1; -} - -static const struct snd_soc_dapm_widget wm8753_dapm_widgets[] = { - SND_SOC_DAPM_LINE("Audio Out", NULL), - SND_SOC_DAPM_LINE("GSM Line Out", NULL), - SND_SOC_DAPM_LINE("GSM Line In", NULL), - SND_SOC_DAPM_MIC("Headset Mic", NULL), - SND_SOC_DAPM_MIC("Call Mic", NULL), -}; - - -static const struct snd_soc_dapm_route dapm_routes[] = { - - /* Connections to the lm4857 amp */ - {"Audio Out", NULL, "LOUT1"}, - {"Audio Out", NULL, "ROUT1"}, - - /* Connections to the GSM Module */ - {"GSM Line Out", NULL, "MONO1"}, - {"GSM Line Out", NULL, "MONO2"}, - {"RXP", NULL, "GSM Line In"}, - {"RXN", NULL, "GSM Line In"}, - - /* Connections to Headset */ - {"MIC1", NULL, "Mic Bias"}, - {"Mic Bias", NULL, "Headset Mic"}, - - /* Call Mic */ - {"MIC2", NULL, "Mic Bias"}, - {"MIC2N", NULL, "Mic Bias"}, - {"Mic Bias", NULL, "Call Mic"}, - - /* Connect the ALC pins */ - {"ACIN", NULL, "ACOP"}, -}; - -static const char *lm4857_mode[] = { - "Off", - "Call Speaker", - "Stereo Speakers", - "Stereo Speakers + Headphones", - "Headphones" -}; - -static const struct soc_enum lm4857_mode_enum[] = { - SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(lm4857_mode), lm4857_mode), -}; - -static const char *neo_scenarios[] = { - "Off", - "GSM Handset", - "GSM Headset", - "GSM Bluetooth", - "Speakers", - "Headphones", - "Capture Handset", - "Capture Headset", - "Capture Bluetooth" -}; - -static const struct soc_enum neo_scenario_enum[] = { - SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(neo_scenarios), neo_scenarios), -}; - -static const DECLARE_TLV_DB_SCALE(stereo_tlv, -4050, 150, 0); -static const DECLARE_TLV_DB_SCALE(mono_tlv, -3450, 150, 0); - -static const struct snd_kcontrol_new wm8753_neo1973_controls[] = { - SOC_SINGLE_EXT_TLV("Amp Left Playback Volume", LM4857_LVOL, 0, 31, 0, - lm4857_get_reg, lm4857_set_reg, stereo_tlv), - SOC_SINGLE_EXT_TLV("Amp Right Playback Volume", LM4857_RVOL, 0, 31, 0, - lm4857_get_reg, lm4857_set_reg, stereo_tlv), - SOC_SINGLE_EXT_TLV("Amp Mono Playback Volume", LM4857_MVOL, 0, 31, 0, - lm4857_get_reg, lm4857_set_reg, mono_tlv), - SOC_ENUM_EXT("Amp Mode", lm4857_mode_enum[0], - lm4857_get_mode, lm4857_set_mode), - SOC_ENUM_EXT("Neo Mode", neo_scenario_enum[0], - neo1973_get_scenario, neo1973_set_scenario), - SOC_SINGLE_EXT("Amp Spk 3D Playback Switch", LM4857_LVOL, 5, 1, 0, - lm4857_get_reg, lm4857_set_reg), - SOC_SINGLE_EXT("Amp HP 3d Playback Switch", LM4857_RVOL, 5, 1, 0, - lm4857_get_reg, lm4857_set_reg), - SOC_SINGLE_EXT("Amp Fast Wakeup Playback Switch", LM4857_CTRL, 5, 1, 0, - lm4857_get_reg, lm4857_set_reg), - SOC_SINGLE_EXT("Amp Earpiece 6dB Playback Switch", LM4857_CTRL, 4, 1, 0, - lm4857_get_reg, lm4857_set_reg), -}; - -/* - * This is an example machine initialisation for a wm8753 connected to a - * neo1973 II. It is missing logic to detect hp/mic insertions and logic - * to re-route the audio in such an event. - */ -static int neo1973_wm8753_init(struct snd_soc_pcm_runtime *rtd) -{ - struct snd_soc_codec *codec = rtd->codec; - struct snd_soc_dapm_context *dapm = &codec->dapm; - int err; - - pr_debug("Entered %s\n", __func__); - - /* set up NC codec pins */ - snd_soc_dapm_nc_pin(dapm, "LOUT2"); - snd_soc_dapm_nc_pin(dapm, "ROUT2"); - snd_soc_dapm_nc_pin(dapm, "OUT3"); - snd_soc_dapm_nc_pin(dapm, "OUT4"); - snd_soc_dapm_nc_pin(dapm, "LINE1"); - snd_soc_dapm_nc_pin(dapm, "LINE2"); - - /* Add neo1973 specific widgets */ - snd_soc_dapm_new_controls(dapm, wm8753_dapm_widgets, - ARRAY_SIZE(wm8753_dapm_widgets)); - - /* set endpoints to default mode */ - set_scenario_endpoints(codec, NEO_AUDIO_OFF); - - /* add neo1973 specific controls */ - err = snd_soc_add_controls(codec, wm8753_neo1973_controls, - ARRAY_SIZE(8753_neo1973_controls)); - if (err < 0) - return err; - - /* set up neo1973 specific audio routes */ - err = snd_soc_dapm_add_routes(dapm, dapm_routes, - ARRAY_SIZE(dapm_routes)); - - snd_soc_dapm_sync(dapm); - return 0; -} - -/* - * BT Codec DAI - */ -static struct snd_soc_dai bt_dai = { - .name = "bluetooth-dai", - .playback = { - .channels_min = 1, - .channels_max = 1, - .rates = SNDRV_PCM_RATE_8000, - .formats = SNDRV_PCM_FMTBIT_S16_LE,}, - .capture = { - .channels_min = 1, - .channels_max = 1, - .rates = SNDRV_PCM_RATE_8000, - .formats = SNDRV_PCM_FMTBIT_S16_LE,}, -}; - -static struct snd_soc_dai_link neo1973_dai[] = { -{ /* Hifi Playback - for similatious use with voice below */ - .name = "WM8753", - .stream_name = "WM8753 HiFi", - .platform_name = "samsung-audio", - .cpu_dai_name = "s3c24xx-i2s", - .codec_dai_name = "wm8753-hifi", - .codec_name = "wm8753-codec.0-0x1a", - .init = neo1973_wm8753_init, - .ops = &neo1973_hifi_ops, -}, -{ /* Voice via BT */ - .name = "Bluetooth", - .stream_name = "Voice", - .platform_name = "samsung-audio", - .cpu_dai_name = "bluetooth-dai", - .codec_dai_name = "wm8753-voice", - .codec_name = "wm8753-codec.0-0x1a", - .ops = &neo1973_voice_ops, -}, -}; - -static struct snd_soc_card neo1973 = { - .name = "neo1973", - .dai_link = neo1973_dai, - .num_links = ARRAY_SIZE(neo1973_dai), -}; - -static int lm4857_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) -{ - pr_debug("Entered %s\n", __func__); - - i2c = client; - - lm4857_write_regs(); - return 0; -} - -static int lm4857_i2c_remove(struct i2c_client *client) -{ - pr_debug("Entered %s\n", __func__); - - i2c = NULL; - - return 0; -} - -static u8 lm4857_state; - -static int lm4857_suspend(struct i2c_client *dev, pm_message_t state) -{ - pr_debug("Entered %s\n", __func__); - - dev_dbg(&dev->dev, "lm4857_suspend\n"); - lm4857_state = lm4857_regs[LM4857_CTRL] & 0xf; - if (lm4857_state) { - lm4857_regs[LM4857_CTRL] &= 0xf0; - lm4857_write_regs(); - } - return 0; -} - -static int lm4857_resume(struct i2c_client *dev) -{ - pr_debug("Entered %s\n", __func__); - - if (lm4857_state) { - lm4857_regs[LM4857_CTRL] |= (lm4857_state & 0x0f); - lm4857_write_regs(); - } - return 0; -} - -static void lm4857_shutdown(struct i2c_client *dev) -{ - pr_debug("Entered %s\n", __func__); - - dev_dbg(&dev->dev, "lm4857_shutdown\n"); - lm4857_regs[LM4857_CTRL] &= 0xf0; - lm4857_write_regs(); -} - -static const struct i2c_device_id lm4857_i2c_id[] = { - { "neo1973_lm4857", 0 }, - { } -}; - -static struct i2c_driver lm4857_i2c_driver = { - .driver = { - .name = "LM4857 I2C Amp", - .owner = THIS_MODULE, - }, - .suspend = lm4857_suspend, - .resume = lm4857_resume, - .shutdown = lm4857_shutdown, - .probe = lm4857_i2c_probe, - .remove = lm4857_i2c_remove, - .id_table = lm4857_i2c_id, -}; - -static struct platform_device *neo1973_snd_device; - -static int __init neo1973_init(void) -{ - int ret; - - pr_debug("Entered %s\n", __func__); - - if (!machine_is_neo1973_gta01()) { - printk(KERN_INFO - "Only GTA01 hardware supported by ASoC driver\n"); - return -ENODEV; - } - - neo1973_snd_device = platform_device_alloc("soc-audio", -1); - if (!neo1973_snd_device) - return -ENOMEM; - - platform_set_drvdata(neo1973_snd_device, &neo1973); - ret = platform_device_add(neo1973_snd_device); - - if (ret) { - platform_device_put(neo1973_snd_device); - return ret; - } - - ret = i2c_add_driver(&lm4857_i2c_driver); - - if (ret != 0) - platform_device_unregister(neo1973_snd_device); - - return ret; -} - -static void __exit neo1973_exit(void) -{ - pr_debug("Entered %s\n", __func__); - - i2c_del_driver(&lm4857_i2c_driver); - platform_device_unregister(neo1973_snd_device); -} - -module_init(neo1973_init); -module_exit(neo1973_exit); - -/* Module information */ -MODULE_AUTHOR("Graeme Gregory, graeme@openmoko.org, www.openmoko.org"); -MODULE_DESCRIPTION("ALSA SoC WM8753 Neo1973"); -MODULE_LICENSE("GPL"); diff --git a/sound/soc/s3c24xx/pcm.c b/sound/soc/s3c24xx/pcm.c deleted file mode 100644 index 4d0f6e4f65bc..000000000000 --- a/sound/soc/s3c24xx/pcm.c +++ /dev/null @@ -1,552 +0,0 @@ -/* sound/soc/s3c24xx/pcm.c - * - * ALSA SoC Audio Layer - S3C PCM-Controller driver - * - * Copyright (c) 2009 Samsung Electronics Co. Ltd - * Author: Jaswinder Singh - * based upon I2S drivers by Ben Dooks. - * - * 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 -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include -#include - -#include "dma.h" -#include "pcm.h" - -static struct s3c2410_dma_client s3c_pcm_dma_client_out = { - .name = "PCM Stereo out" -}; - -static struct s3c2410_dma_client s3c_pcm_dma_client_in = { - .name = "PCM Stereo in" -}; - -static struct s3c_dma_params s3c_pcm_stereo_out[] = { - [0] = { - .client = &s3c_pcm_dma_client_out, - .dma_size = 4, - }, - [1] = { - .client = &s3c_pcm_dma_client_out, - .dma_size = 4, - }, -}; - -static struct s3c_dma_params s3c_pcm_stereo_in[] = { - [0] = { - .client = &s3c_pcm_dma_client_in, - .dma_size = 4, - }, - [1] = { - .client = &s3c_pcm_dma_client_in, - .dma_size = 4, - }, -}; - -static struct s3c_pcm_info s3c_pcm[2]; - -static void s3c_pcm_snd_txctrl(struct s3c_pcm_info *pcm, int on) -{ - void __iomem *regs = pcm->regs; - u32 ctl, clkctl; - - clkctl = readl(regs + S3C_PCM_CLKCTL); - ctl = readl(regs + S3C_PCM_CTL); - ctl &= ~(S3C_PCM_CTL_TXDIPSTICK_MASK - << S3C_PCM_CTL_TXDIPSTICK_SHIFT); - - if (on) { - ctl |= S3C_PCM_CTL_TXDMA_EN; - ctl |= S3C_PCM_CTL_TXFIFO_EN; - ctl |= S3C_PCM_CTL_ENABLE; - ctl |= (0x4<idleclk) - clkctl |= S3C_PCM_CLKCTL_SERCLK_EN; - } - } - - writel(clkctl, regs + S3C_PCM_CLKCTL); - writel(ctl, regs + S3C_PCM_CTL); -} - -static void s3c_pcm_snd_rxctrl(struct s3c_pcm_info *pcm, int on) -{ - void __iomem *regs = pcm->regs; - u32 ctl, clkctl; - - ctl = readl(regs + S3C_PCM_CTL); - clkctl = readl(regs + S3C_PCM_CLKCTL); - ctl &= ~(S3C_PCM_CTL_RXDIPSTICK_MASK - << S3C_PCM_CTL_RXDIPSTICK_SHIFT); - - if (on) { - ctl |= S3C_PCM_CTL_RXDMA_EN; - ctl |= S3C_PCM_CTL_RXFIFO_EN; - ctl |= S3C_PCM_CTL_ENABLE; - ctl |= (0x20<idleclk) - clkctl |= S3C_PCM_CLKCTL_SERCLK_EN; - } - } - - writel(clkctl, regs + S3C_PCM_CLKCTL); - writel(ctl, regs + S3C_PCM_CTL); -} - -static int s3c_pcm_trigger(struct snd_pcm_substream *substream, int cmd, - struct snd_soc_dai *dai) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct s3c_pcm_info *pcm = snd_soc_dai_get_drvdata(rtd->cpu_dai); - unsigned long flags; - - dev_dbg(pcm->dev, "Entered %s\n", __func__); - - switch (cmd) { - case SNDRV_PCM_TRIGGER_START: - case SNDRV_PCM_TRIGGER_RESUME: - case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - spin_lock_irqsave(&pcm->lock, flags); - - if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) - s3c_pcm_snd_rxctrl(pcm, 1); - else - s3c_pcm_snd_txctrl(pcm, 1); - - spin_unlock_irqrestore(&pcm->lock, flags); - break; - - case SNDRV_PCM_TRIGGER_STOP: - case SNDRV_PCM_TRIGGER_SUSPEND: - case SNDRV_PCM_TRIGGER_PAUSE_PUSH: - spin_lock_irqsave(&pcm->lock, flags); - - if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) - s3c_pcm_snd_rxctrl(pcm, 0); - else - s3c_pcm_snd_txctrl(pcm, 0); - - spin_unlock_irqrestore(&pcm->lock, flags); - break; - - default: - return -EINVAL; - } - - return 0; -} - -static int s3c_pcm_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params, - struct snd_soc_dai *socdai) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct s3c_pcm_info *pcm = snd_soc_dai_get_drvdata(rtd->cpu_dai); - struct s3c_dma_params *dma_data; - void __iomem *regs = pcm->regs; - struct clk *clk; - int sclk_div, sync_div; - unsigned long flags; - u32 clkctl; - - dev_dbg(pcm->dev, "Entered %s\n", __func__); - - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - dma_data = pcm->dma_playback; - else - dma_data = pcm->dma_capture; - - snd_soc_dai_set_dma_data(rtd->cpu_dai, substream, dma_data); - - /* Strictly check for sample size */ - switch (params_format(params)) { - case SNDRV_PCM_FORMAT_S16_LE: - break; - default: - return -EINVAL; - } - - spin_lock_irqsave(&pcm->lock, flags); - - /* Get hold of the PCMSOURCE_CLK */ - clkctl = readl(regs + S3C_PCM_CLKCTL); - if (clkctl & S3C_PCM_CLKCTL_SERCLKSEL_PCLK) - clk = pcm->pclk; - else - clk = pcm->cclk; - - /* Set the SCLK divider */ - sclk_div = clk_get_rate(clk) / pcm->sclk_per_fs / - params_rate(params) / 2 - 1; - - clkctl &= ~(S3C_PCM_CLKCTL_SCLKDIV_MASK - << S3C_PCM_CLKCTL_SCLKDIV_SHIFT); - clkctl |= ((sclk_div & S3C_PCM_CLKCTL_SCLKDIV_MASK) - << S3C_PCM_CLKCTL_SCLKDIV_SHIFT); - - /* Set the SYNC divider */ - sync_div = pcm->sclk_per_fs - 1; - - clkctl &= ~(S3C_PCM_CLKCTL_SYNCDIV_MASK - << S3C_PCM_CLKCTL_SYNCDIV_SHIFT); - clkctl |= ((sync_div & S3C_PCM_CLKCTL_SYNCDIV_MASK) - << S3C_PCM_CLKCTL_SYNCDIV_SHIFT); - - writel(clkctl, regs + S3C_PCM_CLKCTL); - - spin_unlock_irqrestore(&pcm->lock, flags); - - dev_dbg(pcm->dev, "PCMSOURCE_CLK-%lu SCLK=%ufs SCLK_DIV=%d SYNC_DIV=%d\n", - clk_get_rate(clk), pcm->sclk_per_fs, - sclk_div, sync_div); - - return 0; -} - -static int s3c_pcm_set_fmt(struct snd_soc_dai *cpu_dai, - unsigned int fmt) -{ - struct s3c_pcm_info *pcm = snd_soc_dai_get_drvdata(cpu_dai); - void __iomem *regs = pcm->regs; - unsigned long flags; - int ret = 0; - u32 ctl; - - dev_dbg(pcm->dev, "Entered %s\n", __func__); - - spin_lock_irqsave(&pcm->lock, flags); - - ctl = readl(regs + S3C_PCM_CTL); - - switch (fmt & SND_SOC_DAIFMT_INV_MASK) { - case SND_SOC_DAIFMT_NB_NF: - /* Nothing to do, NB_NF by default */ - break; - default: - dev_err(pcm->dev, "Unsupported clock inversion!\n"); - ret = -EINVAL; - goto exit; - } - - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBS_CFS: - /* Nothing to do, Master by default */ - break; - default: - dev_err(pcm->dev, "Unsupported master/slave format!\n"); - ret = -EINVAL; - goto exit; - } - - switch (fmt & SND_SOC_DAIFMT_CLOCK_MASK) { - case SND_SOC_DAIFMT_CONT: - pcm->idleclk = 1; - break; - case SND_SOC_DAIFMT_GATED: - pcm->idleclk = 0; - break; - default: - dev_err(pcm->dev, "Invalid Clock gating request!\n"); - ret = -EINVAL; - goto exit; - } - - switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { - case SND_SOC_DAIFMT_DSP_A: - ctl |= S3C_PCM_CTL_TXMSB_AFTER_FSYNC; - ctl |= S3C_PCM_CTL_RXMSB_AFTER_FSYNC; - break; - case SND_SOC_DAIFMT_DSP_B: - ctl &= ~S3C_PCM_CTL_TXMSB_AFTER_FSYNC; - ctl &= ~S3C_PCM_CTL_RXMSB_AFTER_FSYNC; - break; - default: - dev_err(pcm->dev, "Unsupported data format!\n"); - ret = -EINVAL; - goto exit; - } - - writel(ctl, regs + S3C_PCM_CTL); - -exit: - spin_unlock_irqrestore(&pcm->lock, flags); - - return ret; -} - -static int s3c_pcm_set_clkdiv(struct snd_soc_dai *cpu_dai, - int div_id, int div) -{ - struct s3c_pcm_info *pcm = snd_soc_dai_get_drvdata(cpu_dai); - - switch (div_id) { - case S3C_PCM_SCLK_PER_FS: - pcm->sclk_per_fs = div; - break; - - default: - return -EINVAL; - } - - return 0; -} - -static int s3c_pcm_set_sysclk(struct snd_soc_dai *cpu_dai, - int clk_id, unsigned int freq, int dir) -{ - struct s3c_pcm_info *pcm = snd_soc_dai_get_drvdata(cpu_dai); - void __iomem *regs = pcm->regs; - u32 clkctl = readl(regs + S3C_PCM_CLKCTL); - - switch (clk_id) { - case S3C_PCM_CLKSRC_PCLK: - clkctl |= S3C_PCM_CLKCTL_SERCLKSEL_PCLK; - break; - - case S3C_PCM_CLKSRC_MUX: - clkctl &= ~S3C_PCM_CLKCTL_SERCLKSEL_PCLK; - - if (clk_get_rate(pcm->cclk) != freq) - clk_set_rate(pcm->cclk, freq); - - break; - - default: - return -EINVAL; - } - - writel(clkctl, regs + S3C_PCM_CLKCTL); - - return 0; -} - -static struct snd_soc_dai_ops s3c_pcm_dai_ops = { - .set_sysclk = s3c_pcm_set_sysclk, - .set_clkdiv = s3c_pcm_set_clkdiv, - .trigger = s3c_pcm_trigger, - .hw_params = s3c_pcm_hw_params, - .set_fmt = s3c_pcm_set_fmt, -}; - -#define S3C_PCM_RATES SNDRV_PCM_RATE_8000_96000 - -#define S3C_PCM_DAI_DECLARE \ - .symmetric_rates = 1, \ - .ops = &s3c_pcm_dai_ops, \ - .playback = { \ - .channels_min = 2, \ - .channels_max = 2, \ - .rates = S3C_PCM_RATES, \ - .formats = SNDRV_PCM_FMTBIT_S16_LE, \ - }, \ - .capture = { \ - .channels_min = 2, \ - .channels_max = 2, \ - .rates = S3C_PCM_RATES, \ - .formats = SNDRV_PCM_FMTBIT_S16_LE, \ - } - -struct snd_soc_dai_driver s3c_pcm_dai[] = { - [0] = { - .name = "samsung-pcm.0", - S3C_PCM_DAI_DECLARE, - }, - [1] = { - .name = "samsung-pcm.1", - S3C_PCM_DAI_DECLARE, - }, -}; -EXPORT_SYMBOL_GPL(s3c_pcm_dai); - -static __devinit int s3c_pcm_dev_probe(struct platform_device *pdev) -{ - struct s3c_pcm_info *pcm; - struct resource *mem_res, *dmatx_res, *dmarx_res; - struct s3c_audio_pdata *pcm_pdata; - int ret; - - /* Check for valid device index */ - if ((pdev->id < 0) || pdev->id >= ARRAY_SIZE(s3c_pcm)) { - dev_err(&pdev->dev, "id %d out of range\n", pdev->id); - return -EINVAL; - } - - pcm_pdata = pdev->dev.platform_data; - - /* Check for availability of necessary resource */ - dmatx_res = platform_get_resource(pdev, IORESOURCE_DMA, 0); - if (!dmatx_res) { - dev_err(&pdev->dev, "Unable to get PCM-TX dma resource\n"); - return -ENXIO; - } - - dmarx_res = platform_get_resource(pdev, IORESOURCE_DMA, 1); - if (!dmarx_res) { - dev_err(&pdev->dev, "Unable to get PCM-RX dma resource\n"); - return -ENXIO; - } - - mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!mem_res) { - dev_err(&pdev->dev, "Unable to get register resource\n"); - return -ENXIO; - } - - if (pcm_pdata && pcm_pdata->cfg_gpio && pcm_pdata->cfg_gpio(pdev)) { - dev_err(&pdev->dev, "Unable to configure gpio\n"); - return -EINVAL; - } - - pcm = &s3c_pcm[pdev->id]; - pcm->dev = &pdev->dev; - - spin_lock_init(&pcm->lock); - - /* Default is 128fs */ - pcm->sclk_per_fs = 128; - - pcm->cclk = clk_get(&pdev->dev, "audio-bus"); - if (IS_ERR(pcm->cclk)) { - dev_err(&pdev->dev, "failed to get audio-bus\n"); - ret = PTR_ERR(pcm->cclk); - goto err1; - } - clk_enable(pcm->cclk); - - /* record our pcm structure for later use in the callbacks */ - dev_set_drvdata(&pdev->dev, pcm); - - if (!request_mem_region(mem_res->start, - resource_size(mem_res), "samsung-pcm")) { - dev_err(&pdev->dev, "Unable to request register region\n"); - ret = -EBUSY; - goto err2; - } - - pcm->regs = ioremap(mem_res->start, 0x100); - if (pcm->regs == NULL) { - dev_err(&pdev->dev, "cannot ioremap registers\n"); - ret = -ENXIO; - goto err3; - } - - pcm->pclk = clk_get(&pdev->dev, "pcm"); - if (IS_ERR(pcm->pclk)) { - dev_err(&pdev->dev, "failed to get pcm_clock\n"); - ret = -ENOENT; - goto err4; - } - clk_enable(pcm->pclk); - - ret = snd_soc_register_dai(&pdev->dev, &s3c_pcm_dai[pdev->id]); - if (ret != 0) { - dev_err(&pdev->dev, "failed to get pcm_clock\n"); - goto err5; - } - - s3c_pcm_stereo_in[pdev->id].dma_addr = mem_res->start - + S3C_PCM_RXFIFO; - s3c_pcm_stereo_out[pdev->id].dma_addr = mem_res->start - + S3C_PCM_TXFIFO; - - s3c_pcm_stereo_in[pdev->id].channel = dmarx_res->start; - s3c_pcm_stereo_out[pdev->id].channel = dmatx_res->start; - - pcm->dma_capture = &s3c_pcm_stereo_in[pdev->id]; - pcm->dma_playback = &s3c_pcm_stereo_out[pdev->id]; - - return 0; - -err5: - clk_disable(pcm->pclk); - clk_put(pcm->pclk); -err4: - iounmap(pcm->regs); -err3: - release_mem_region(mem_res->start, resource_size(mem_res)); -err2: - clk_disable(pcm->cclk); - clk_put(pcm->cclk); -err1: - return ret; -} - -static __devexit int s3c_pcm_dev_remove(struct platform_device *pdev) -{ - struct s3c_pcm_info *pcm = &s3c_pcm[pdev->id]; - struct resource *mem_res; - - snd_soc_unregister_dai(&pdev->dev); - - iounmap(pcm->regs); - - mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - release_mem_region(mem_res->start, resource_size(mem_res)); - - clk_disable(pcm->cclk); - clk_disable(pcm->pclk); - clk_put(pcm->pclk); - clk_put(pcm->cclk); - - return 0; -} - -static struct platform_driver s3c_pcm_driver = { - .probe = s3c_pcm_dev_probe, - .remove = s3c_pcm_dev_remove, - .driver = { - .name = "samsung-pcm", - .owner = THIS_MODULE, - }, -}; - -static int __init s3c_pcm_init(void) -{ - return platform_driver_register(&s3c_pcm_driver); -} -module_init(s3c_pcm_init); - -static void __exit s3c_pcm_exit(void) -{ - platform_driver_unregister(&s3c_pcm_driver); -} -module_exit(s3c_pcm_exit); - -/* Module information */ -MODULE_AUTHOR("Jaswinder Singh, "); -MODULE_DESCRIPTION("S3C PCM Controller Driver"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:samsung-pcm"); diff --git a/sound/soc/s3c24xx/pcm.h b/sound/soc/s3c24xx/pcm.h deleted file mode 100644 index 3775216ffda8..000000000000 --- a/sound/soc/s3c24xx/pcm.h +++ /dev/null @@ -1,124 +0,0 @@ -/* sound/soc/s3c24xx/pcm.h - * - * 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. - * - */ - -#ifndef __S3C_PCM_H -#define __S3C_PCM_H __FILE__ - -/*Register Offsets */ -#define S3C_PCM_CTL (0x00) -#define S3C_PCM_CLKCTL (0x04) -#define S3C_PCM_TXFIFO (0x08) -#define S3C_PCM_RXFIFO (0x0C) -#define S3C_PCM_IRQCTL (0x10) -#define S3C_PCM_IRQSTAT (0x14) -#define S3C_PCM_FIFOSTAT (0x18) -#define S3C_PCM_CLRINT (0x20) - -/* PCM_CTL Bit-Fields */ -#define S3C_PCM_CTL_TXDIPSTICK_MASK (0x3f) -#define S3C_PCM_CTL_TXDIPSTICK_SHIFT (13) -#define S3C_PCM_CTL_RXDIPSTICK_MASK (0x3f) -#define S3C_PCM_CTL_RXDIPSTICK_SHIFT (7) -#define S3C_PCM_CTL_TXDMA_EN (0x1<<6) -#define S3C_PCM_CTL_RXDMA_EN (0x1<<5) -#define S3C_PCM_CTL_TXMSB_AFTER_FSYNC (0x1<<4) -#define S3C_PCM_CTL_RXMSB_AFTER_FSYNC (0x1<<3) -#define S3C_PCM_CTL_TXFIFO_EN (0x1<<2) -#define S3C_PCM_CTL_RXFIFO_EN (0x1<<1) -#define S3C_PCM_CTL_ENABLE (0x1<<0) - -/* PCM_CLKCTL Bit-Fields */ -#define S3C_PCM_CLKCTL_SERCLK_EN (0x1<<19) -#define S3C_PCM_CLKCTL_SERCLKSEL_PCLK (0x1<<18) -#define S3C_PCM_CLKCTL_SCLKDIV_MASK (0x1ff) -#define S3C_PCM_CLKCTL_SYNCDIV_MASK (0x1ff) -#define S3C_PCM_CLKCTL_SCLKDIV_SHIFT (9) -#define S3C_PCM_CLKCTL_SYNCDIV_SHIFT (0) - -/* PCM_TXFIFO Bit-Fields */ -#define S3C_PCM_TXFIFO_DVALID (0x1<<16) -#define S3C_PCM_TXFIFO_DATA_MSK (0xffff<<0) - -/* PCM_RXFIFO Bit-Fields */ -#define S3C_PCM_RXFIFO_DVALID (0x1<<16) -#define S3C_PCM_RXFIFO_DATA_MSK (0xffff<<0) - -/* PCM_IRQCTL Bit-Fields */ -#define S3C_PCM_IRQCTL_IRQEN (0x1<<14) -#define S3C_PCM_IRQCTL_WRDEN (0x1<<12) -#define S3C_PCM_IRQCTL_TXEMPTYEN (0x1<<11) -#define S3C_PCM_IRQCTL_TXALMSTEMPTYEN (0x1<<10) -#define S3C_PCM_IRQCTL_TXFULLEN (0x1<<9) -#define S3C_PCM_IRQCTL_TXALMSTFULLEN (0x1<<8) -#define S3C_PCM_IRQCTL_TXSTARVEN (0x1<<7) -#define S3C_PCM_IRQCTL_TXERROVRFLEN (0x1<<6) -#define S3C_PCM_IRQCTL_RXEMPTEN (0x1<<5) -#define S3C_PCM_IRQCTL_RXALMSTEMPTEN (0x1<<4) -#define S3C_PCM_IRQCTL_RXFULLEN (0x1<<3) -#define S3C_PCM_IRQCTL_RXALMSTFULLEN (0x1<<2) -#define S3C_PCM_IRQCTL_RXSTARVEN (0x1<<1) -#define S3C_PCM_IRQCTL_RXERROVRFLEN (0x1<<0) - -/* PCM_IRQSTAT Bit-Fields */ -#define S3C_PCM_IRQSTAT_IRQPND (0x1<<13) -#define S3C_PCM_IRQSTAT_WRD_XFER (0x1<<12) -#define S3C_PCM_IRQSTAT_TXEMPTY (0x1<<11) -#define S3C_PCM_IRQSTAT_TXALMSTEMPTY (0x1<<10) -#define S3C_PCM_IRQSTAT_TXFULL (0x1<<9) -#define S3C_PCM_IRQSTAT_TXALMSTFULL (0x1<<8) -#define S3C_PCM_IRQSTAT_TXSTARV (0x1<<7) -#define S3C_PCM_IRQSTAT_TXERROVRFL (0x1<<6) -#define S3C_PCM_IRQSTAT_RXEMPT (0x1<<5) -#define S3C_PCM_IRQSTAT_RXALMSTEMPT (0x1<<4) -#define S3C_PCM_IRQSTAT_RXFULL (0x1<<3) -#define S3C_PCM_IRQSTAT_RXALMSTFULL (0x1<<2) -#define S3C_PCM_IRQSTAT_RXSTARV (0x1<<1) -#define S3C_PCM_IRQSTAT_RXERROVRFL (0x1<<0) - -/* PCM_FIFOSTAT Bit-Fields */ -#define S3C_PCM_FIFOSTAT_TXCNT_MSK (0x3f<<14) -#define S3C_PCM_FIFOSTAT_TXFIFOEMPTY (0x1<<13) -#define S3C_PCM_FIFOSTAT_TXFIFOALMSTEMPTY (0x1<<12) -#define S3C_PCM_FIFOSTAT_TXFIFOFULL (0x1<<11) -#define S3C_PCM_FIFOSTAT_TXFIFOALMSTFULL (0x1<<10) -#define S3C_PCM_FIFOSTAT_RXCNT_MSK (0x3f<<4) -#define S3C_PCM_FIFOSTAT_RXFIFOEMPTY (0x1<<3) -#define S3C_PCM_FIFOSTAT_RXFIFOALMSTEMPTY (0x1<<2) -#define S3C_PCM_FIFOSTAT_RXFIFOFULL (0x1<<1) -#define S3C_PCM_FIFOSTAT_RXFIFOALMSTFULL (0x1<<0) - -#define S3C_PCM_CLKSRC_PCLK 0 -#define S3C_PCM_CLKSRC_MUX 1 - -#define S3C_PCM_SCLK_PER_FS 0 - -/** - * struct s3c_pcm_info - S3C PCM Controller information - * @dev: The parent device passed to use from the probe. - * @regs: The pointer to the device register block. - * @dma_playback: DMA information for playback channel. - * @dma_capture: DMA information for capture channel. - */ -struct s3c_pcm_info { - spinlock_t lock; - struct device *dev; - void __iomem *regs; - - unsigned int sclk_per_fs; - - /* Whether to keep PCMSCLK enabled even when idle(no active xfer) */ - unsigned int idleclk; - - struct clk *pclk; - struct clk *cclk; - - struct s3c_dma_params *dma_playback; - struct s3c_dma_params *dma_capture; -}; - -#endif /* __S3C_PCM_H */ diff --git a/sound/soc/s3c24xx/regs-i2s-v2.h b/sound/soc/s3c24xx/regs-i2s-v2.h deleted file mode 100644 index 5e5e5680580b..000000000000 --- a/sound/soc/s3c24xx/regs-i2s-v2.h +++ /dev/null @@ -1,115 +0,0 @@ -/* linux/include/asm-arm/plat-s3c24xx/regs-s3c2412-iis.h - * - * Copyright 2007 Simtec Electronics - * http://armlinux.simtec.co.uk/ - * - * 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. - * - * S3C2412 IIS register definition -*/ - -#ifndef __ASM_ARCH_REGS_S3C2412_IIS_H -#define __ASM_ARCH_REGS_S3C2412_IIS_H - -#define S3C2412_IISCON (0x00) -#define S3C2412_IISMOD (0x04) -#define S3C2412_IISFIC (0x08) -#define S3C2412_IISPSR (0x0C) -#define S3C2412_IISTXD (0x10) -#define S3C2412_IISRXD (0x14) - -#define S5PC1XX_IISFICS 0x18 -#define S5PC1XX_IISTXDS 0x1C - -#define S5PC1XX_IISCON_SW_RST (1 << 31) -#define S5PC1XX_IISCON_FRXOFSTATUS (1 << 26) -#define S5PC1XX_IISCON_FRXORINTEN (1 << 25) -#define S5PC1XX_IISCON_FTXSURSTAT (1 << 24) -#define S5PC1XX_IISCON_FTXSURINTEN (1 << 23) -#define S5PC1XX_IISCON_TXSDMAPAUSE (1 << 20) -#define S5PC1XX_IISCON_TXSDMACTIVE (1 << 18) - -#define S3C64XX_IISCON_FTXURSTATUS (1 << 17) -#define S3C64XX_IISCON_FTXURINTEN (1 << 16) -#define S3C64XX_IISCON_TXFIFO2_EMPTY (1 << 15) -#define S3C64XX_IISCON_TXFIFO1_EMPTY (1 << 14) -#define S3C64XX_IISCON_TXFIFO2_FULL (1 << 13) -#define S3C64XX_IISCON_TXFIFO1_FULL (1 << 12) - -#define S3C2412_IISCON_LRINDEX (1 << 11) -#define S3C2412_IISCON_TXFIFO_EMPTY (1 << 10) -#define S3C2412_IISCON_RXFIFO_EMPTY (1 << 9) -#define S3C2412_IISCON_TXFIFO_FULL (1 << 8) -#define S3C2412_IISCON_RXFIFO_FULL (1 << 7) -#define S3C2412_IISCON_TXDMA_PAUSE (1 << 6) -#define S3C2412_IISCON_RXDMA_PAUSE (1 << 5) -#define S3C2412_IISCON_TXCH_PAUSE (1 << 4) -#define S3C2412_IISCON_RXCH_PAUSE (1 << 3) -#define S3C2412_IISCON_TXDMA_ACTIVE (1 << 2) -#define S3C2412_IISCON_RXDMA_ACTIVE (1 << 1) -#define S3C2412_IISCON_IIS_ACTIVE (1 << 0) - -#define S5PC1XX_IISMOD_OPCLK_CDCLK_OUT (0 << 30) -#define S5PC1XX_IISMOD_OPCLK_CDCLK_IN (1 << 30) -#define S5PC1XX_IISMOD_OPCLK_BCLK_OUT (2 << 30) -#define S5PC1XX_IISMOD_OPCLK_PCLK (3 << 30) -#define S5PC1XX_IISMOD_OPCLK_MASK (3 << 30) -#define S5PC1XX_IISMOD_TXS_IDMA (1 << 28) /* Sec_TXFIFO use I-DMA */ -#define S5PC1XX_IISMOD_BLCS_MASK 0x3 -#define S5PC1XX_IISMOD_BLCS_SHIFT 26 -#define S5PC1XX_IISMOD_BLCP_MASK 0x3 -#define S5PC1XX_IISMOD_BLCP_SHIFT 24 - -#define S3C64XX_IISMOD_C2DD_HHALF (1 << 21) /* Discard Higher-half */ -#define S3C64XX_IISMOD_C2DD_LHALF (1 << 20) /* Discard Lower-half */ -#define S3C64XX_IISMOD_C1DD_HHALF (1 << 19) -#define S3C64XX_IISMOD_C1DD_LHALF (1 << 18) -#define S3C64XX_IISMOD_DC2_EN (1 << 17) -#define S3C64XX_IISMOD_DC1_EN (1 << 16) -#define S3C64XX_IISMOD_BLC_16BIT (0 << 13) -#define S3C64XX_IISMOD_BLC_8BIT (1 << 13) -#define S3C64XX_IISMOD_BLC_24BIT (2 << 13) -#define S3C64XX_IISMOD_BLC_MASK (3 << 13) - -#define S3C2412_IISMOD_IMS_SYSMUX (1 << 10) -#define S3C2412_IISMOD_SLAVE (1 << 11) -#define S3C2412_IISMOD_MODE_TXONLY (0 << 8) -#define S3C2412_IISMOD_MODE_RXONLY (1 << 8) -#define S3C2412_IISMOD_MODE_TXRX (2 << 8) -#define S3C2412_IISMOD_MODE_MASK (3 << 8) -#define S3C2412_IISMOD_LR_LLOW (0 << 7) -#define S3C2412_IISMOD_LR_RLOW (1 << 7) -#define S3C2412_IISMOD_SDF_IIS (0 << 5) -#define S3C2412_IISMOD_SDF_MSB (1 << 5) -#define S3C2412_IISMOD_SDF_LSB (2 << 5) -#define S3C2412_IISMOD_SDF_MASK (3 << 5) -#define S3C2412_IISMOD_RCLK_256FS (0 << 3) -#define S3C2412_IISMOD_RCLK_512FS (1 << 3) -#define S3C2412_IISMOD_RCLK_384FS (2 << 3) -#define S3C2412_IISMOD_RCLK_768FS (3 << 3) -#define S3C2412_IISMOD_RCLK_MASK (3 << 3) -#define S3C2412_IISMOD_BCLK_32FS (0 << 1) -#define S3C2412_IISMOD_BCLK_48FS (1 << 1) -#define S3C2412_IISMOD_BCLK_16FS (2 << 1) -#define S3C2412_IISMOD_BCLK_24FS (3 << 1) -#define S3C2412_IISMOD_BCLK_MASK (3 << 1) -#define S3C2412_IISMOD_8BIT (1 << 0) - -#define S3C64XX_IISMOD_CDCLKCON (1 << 12) - -#define S3C2412_IISPSR_PSREN (1 << 15) - -#define S3C64XX_IISFIC_TX2COUNT(x) (((x) >> 24) & 0xf) -#define S3C64XX_IISFIC_TX1COUNT(x) (((x) >> 16) & 0xf) - -#define S3C2412_IISFIC_TXFLUSH (1 << 15) -#define S3C2412_IISFIC_RXFLUSH (1 << 7) -#define S3C2412_IISFIC_TXCOUNT(x) (((x) >> 8) & 0xf) -#define S3C2412_IISFIC_RXCOUNT(x) (((x) >> 0) & 0xf) - -#define S5PC1XX_IISFICS_TXFLUSH (1 << 15) -#define S5PC1XX_IISFICS_TXCOUNT(x) (((x) >> 8) & 0x7f) - -#endif /* __ASM_ARCH_REGS_S3C2412_IIS_H */ diff --git a/sound/soc/s3c24xx/rx1950_uda1380.c b/sound/soc/s3c24xx/rx1950_uda1380.c deleted file mode 100644 index 5a4587e02886..000000000000 --- a/sound/soc/s3c24xx/rx1950_uda1380.c +++ /dev/null @@ -1,319 +0,0 @@ -/* - * rx1950.c -- ALSA Soc Audio Layer - * - * Copyright (c) 2010 Vasily Khoruzhick - * - * Based on smdk2440.c and magician.c - * - * Authors: Graeme Gregory graeme.gregory@wolfsonmicro.com - * Philipp Zabel - * Denis Grigoriev - * Vasily Khoruzhick - * - * 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. - * - */ - -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include - -#include - -#include - -#include "dma.h" -#include "s3c24xx-i2s.h" -#include "../codecs/uda1380.h" - -static int rx1950_uda1380_init(struct snd_soc_pcm_runtime *rtd); -static int rx1950_startup(struct snd_pcm_substream *substream); -static int rx1950_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params); -static int rx1950_spk_power(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event); - -static unsigned int rates[] = { - 16000, - 44100, - 48000, -}; - -static struct snd_pcm_hw_constraint_list hw_rates = { - .count = ARRAY_SIZE(rates), - .list = rates, - .mask = 0, -}; - -static struct snd_soc_jack hp_jack; - -static struct snd_soc_jack_pin hp_jack_pins[] = { - { - .pin = "Headphone Jack", - .mask = SND_JACK_HEADPHONE, - }, - { - .pin = "Speaker", - .mask = SND_JACK_HEADPHONE, - .invert = 1, - }, -}; - -static struct snd_soc_jack_gpio hp_jack_gpios[] = { - [0] = { - .gpio = S3C2410_GPG(12), - .name = "hp-gpio", - .report = SND_JACK_HEADPHONE, - .invert = 1, - .debounce_time = 200, - }, -}; - -static struct snd_soc_ops rx1950_ops = { - .startup = rx1950_startup, - .hw_params = rx1950_hw_params, -}; - -/* s3c24xx digital audio interface glue - connects codec <--> CPU */ -static struct snd_soc_dai_link rx1950_uda1380_dai[] = { - { - .name = "uda1380", - .stream_name = "UDA1380 Duplex", - .cpu_dai_name = "s3c24xx-iis", - .codec_dai_name = "uda1380-hifi", - .init = rx1950_uda1380_init, - .platform_name = "samsung-audio", - .codec_name = "uda1380-codec.0-001a", - .ops = &rx1950_ops, - }, -}; - -static struct snd_soc_card rx1950_asoc = { - .name = "rx1950", - .dai_link = rx1950_uda1380_dai, - .num_links = ARRAY_SIZE(rx1950_uda1380_dai), -}; - -/* rx1950 machine dapm widgets */ -static const struct snd_soc_dapm_widget uda1380_dapm_widgets[] = { - SND_SOC_DAPM_HP("Headphone Jack", NULL), - SND_SOC_DAPM_MIC("Mic Jack", NULL), - SND_SOC_DAPM_SPK("Speaker", rx1950_spk_power), -}; - -/* rx1950 machine audio_map */ -static const struct snd_soc_dapm_route audio_map[] = { - /* headphone connected to VOUTLHP, VOUTRHP */ - {"Headphone Jack", NULL, "VOUTLHP"}, - {"Headphone Jack", NULL, "VOUTRHP"}, - - /* ext speaker connected to VOUTL, VOUTR */ - {"Speaker", NULL, "VOUTL"}, - {"Speaker", NULL, "VOUTR"}, - - /* mic is connected to VINM */ - {"VINM", NULL, "Mic Jack"}, -}; - -static struct platform_device *s3c24xx_snd_device; - -static int rx1950_startup(struct snd_pcm_substream *substream) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - - runtime->hw.rate_min = hw_rates.list[0]; - runtime->hw.rate_max = hw_rates.list[hw_rates.count - 1]; - runtime->hw.rates = SNDRV_PCM_RATE_KNOT; - - return snd_pcm_hw_constraint_list(runtime, 0, - SNDRV_PCM_HW_PARAM_RATE, - &hw_rates); -} - -static int rx1950_spk_power(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - if (SND_SOC_DAPM_EVENT_ON(event)) - gpio_set_value(S3C2410_GPA(1), 1); - else - gpio_set_value(S3C2410_GPA(1), 0); - - return 0; -} - -static int rx1950_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; - struct snd_soc_dai *codec_dai = rtd->codec_dai; - int div; - int ret; - unsigned int rate = params_rate(params); - int clk_source, fs_mode; - - switch (rate) { - case 16000: - case 48000: - clk_source = S3C24XX_CLKSRC_PCLK; - fs_mode = S3C2410_IISMOD_256FS; - div = s3c24xx_i2s_get_clockrate() / (256 * rate); - if (s3c24xx_i2s_get_clockrate() % (256 * rate) > (128 * rate)) - div++; - break; - case 44100: - case 88200: - clk_source = S3C24XX_CLKSRC_MPLL; - fs_mode = S3C2410_IISMOD_384FS; - div = 1; - break; - default: - printk(KERN_ERR "%s: rate %d is not supported\n", - __func__, rate); - return -EINVAL; - } - - /* set codec DAI configuration */ - ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | - SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); - if (ret < 0) - return ret; - - /* set cpu DAI configuration */ - ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S | - SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); - if (ret < 0) - return ret; - - /* select clock source */ - ret = snd_soc_dai_set_sysclk(cpu_dai, clk_source, rate, - SND_SOC_CLOCK_OUT); - if (ret < 0) - return ret; - - /* set MCLK division for sample rate */ - ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C24XX_DIV_MCLK, - fs_mode); - if (ret < 0) - return ret; - - /* set BCLK division for sample rate */ - ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C24XX_DIV_BCLK, - S3C2410_IISMOD_32FS); - if (ret < 0) - return ret; - - /* set prescaler division for sample rate */ - ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C24XX_DIV_PRESCALER, - S3C24XX_PRESCALE(div, div)); - if (ret < 0) - return ret; - - return 0; -} - -static int rx1950_uda1380_init(struct snd_soc_pcm_runtime *rtd) -{ - struct snd_soc_codec *codec = rtd->codec; - struct snd_soc_dapm_context *dapm = &codec->dapm; - int err; - - /* Add rx1950 specific widgets */ - err = snd_soc_dapm_new_controls(dapm, uda1380_dapm_widgets, - ARRAY_SIZE(uda1380_dapm_widgets)); - - if (err) - return err; - - /* Set up rx1950 specific audio path audio_mapnects */ - err = snd_soc_dapm_add_routes(dapm, audio_map, - ARRAY_SIZE(audio_map)); - - if (err) - return err; - - snd_soc_dapm_enable_pin(dapm, "Headphone Jack"); - snd_soc_dapm_enable_pin(dapm, "Speaker"); - - snd_soc_dapm_sync(dapm); - - snd_soc_jack_new(codec, "Headphone Jack", SND_JACK_HEADPHONE, - &hp_jack); - - snd_soc_jack_add_pins(&hp_jack, ARRAY_SIZE(hp_jack_pins), - hp_jack_pins); - - snd_soc_jack_add_gpios(&hp_jack, ARRAY_SIZE(hp_jack_gpios), - hp_jack_gpios); - - return 0; -} - -static int __init rx1950_init(void) -{ - int ret; - - if (!machine_is_rx1950()) - return -ENODEV; - - /* configure some gpios */ - ret = gpio_request(S3C2410_GPA(1), "speaker-power"); - if (ret) - goto err_gpio; - - ret = gpio_direction_output(S3C2410_GPA(1), 0); - if (ret) - goto err_gpio_conf; - - s3c24xx_snd_device = platform_device_alloc("soc-audio", -1); - if (!s3c24xx_snd_device) { - ret = -ENOMEM; - goto err_plat_alloc; - } - - platform_set_drvdata(s3c24xx_snd_device, &rx1950_asoc); - ret = platform_device_add(s3c24xx_snd_device); - - if (ret) { - platform_device_put(s3c24xx_snd_device); - goto err_plat_add; - } - - return 0; - -err_plat_add: -err_plat_alloc: -err_gpio_conf: - gpio_free(S3C2410_GPA(1)); - -err_gpio: - return ret; -} - -static void __exit rx1950_exit(void) -{ - platform_device_unregister(s3c24xx_snd_device); - snd_soc_jack_free_gpios(&hp_jack, ARRAY_SIZE(hp_jack_gpios), - hp_jack_gpios); - gpio_free(S3C2410_GPA(1)); -} - -module_init(rx1950_init); -module_exit(rx1950_exit); - -/* Module information */ -MODULE_AUTHOR("Vasily Khoruzhick"); -MODULE_DESCRIPTION("ALSA SoC RX1950"); -MODULE_LICENSE("GPL"); diff --git a/sound/soc/s3c24xx/s3c-i2s-v2.c b/sound/soc/s3c24xx/s3c-i2s-v2.c deleted file mode 100644 index c4714319216c..000000000000 --- a/sound/soc/s3c24xx/s3c-i2s-v2.c +++ /dev/null @@ -1,757 +0,0 @@ -/* sound/soc/s3c24xx/s3c-i2c-v2.c - * - * ALSA Soc Audio Layer - I2S core for newer Samsung SoCs. - * - * Copyright (c) 2006 Wolfson Microelectronics PLC. - * Graeme Gregory graeme.gregory@wolfsonmicro.com - * linux@wolfsonmicro.com - * - * Copyright (c) 2008, 2007, 2004-2005 Simtec Electronics - * http://armlinux.simtec.co.uk/ - * Ben Dooks - * - * 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. - */ - -#include -#include -#include - -#include -#include -#include - -#include - -#include "regs-i2s-v2.h" -#include "s3c-i2s-v2.h" -#include "dma.h" - -#undef S3C_IIS_V2_SUPPORTED - -#if defined(CONFIG_CPU_S3C2412) || defined(CONFIG_CPU_S3C2413) \ - || defined(CONFIG_CPU_S5PV210) -#define S3C_IIS_V2_SUPPORTED -#endif - -#ifdef CONFIG_PLAT_S3C64XX -#define S3C_IIS_V2_SUPPORTED -#endif - -#ifndef S3C_IIS_V2_SUPPORTED -#error Unsupported CPU model -#endif - -#define S3C2412_I2S_DEBUG_CON 0 - -static inline struct s3c_i2sv2_info *to_info(struct snd_soc_dai *cpu_dai) -{ - return snd_soc_dai_get_drvdata(cpu_dai); -} - -#define bit_set(v, b) (((v) & (b)) ? 1 : 0) - -#if S3C2412_I2S_DEBUG_CON -static void dbg_showcon(const char *fn, u32 con) -{ - printk(KERN_DEBUG "%s: LRI=%d, TXFEMPT=%d, RXFEMPT=%d, TXFFULL=%d, RXFFULL=%d\n", fn, - bit_set(con, S3C2412_IISCON_LRINDEX), - bit_set(con, S3C2412_IISCON_TXFIFO_EMPTY), - bit_set(con, S3C2412_IISCON_RXFIFO_EMPTY), - bit_set(con, S3C2412_IISCON_TXFIFO_FULL), - bit_set(con, S3C2412_IISCON_RXFIFO_FULL)); - - printk(KERN_DEBUG "%s: PAUSE: TXDMA=%d, RXDMA=%d, TXCH=%d, RXCH=%d\n", - fn, - bit_set(con, S3C2412_IISCON_TXDMA_PAUSE), - bit_set(con, S3C2412_IISCON_RXDMA_PAUSE), - bit_set(con, S3C2412_IISCON_TXCH_PAUSE), - bit_set(con, S3C2412_IISCON_RXCH_PAUSE)); - printk(KERN_DEBUG "%s: ACTIVE: TXDMA=%d, RXDMA=%d, IIS=%d\n", fn, - bit_set(con, S3C2412_IISCON_TXDMA_ACTIVE), - bit_set(con, S3C2412_IISCON_RXDMA_ACTIVE), - bit_set(con, S3C2412_IISCON_IIS_ACTIVE)); -} -#else -static inline void dbg_showcon(const char *fn, u32 con) -{ -} -#endif - - -/* Turn on or off the transmission path. */ -static void s3c2412_snd_txctrl(struct s3c_i2sv2_info *i2s, int on) -{ - void __iomem *regs = i2s->regs; - u32 fic, con, mod; - - pr_debug("%s(%d)\n", __func__, on); - - fic = readl(regs + S3C2412_IISFIC); - con = readl(regs + S3C2412_IISCON); - mod = readl(regs + S3C2412_IISMOD); - - pr_debug("%s: IIS: CON=%x MOD=%x FIC=%x\n", __func__, con, mod, fic); - - if (on) { - con |= S3C2412_IISCON_TXDMA_ACTIVE | S3C2412_IISCON_IIS_ACTIVE; - con &= ~S3C2412_IISCON_TXDMA_PAUSE; - con &= ~S3C2412_IISCON_TXCH_PAUSE; - - switch (mod & S3C2412_IISMOD_MODE_MASK) { - case S3C2412_IISMOD_MODE_TXONLY: - case S3C2412_IISMOD_MODE_TXRX: - /* do nothing, we are in the right mode */ - break; - - case S3C2412_IISMOD_MODE_RXONLY: - mod &= ~S3C2412_IISMOD_MODE_MASK; - mod |= S3C2412_IISMOD_MODE_TXRX; - break; - - default: - dev_err(i2s->dev, "TXEN: Invalid MODE %x in IISMOD\n", - mod & S3C2412_IISMOD_MODE_MASK); - break; - } - - writel(con, regs + S3C2412_IISCON); - writel(mod, regs + S3C2412_IISMOD); - } else { - /* Note, we do not have any indication that the FIFO problems - * tha the S3C2410/2440 had apply here, so we should be able - * to disable the DMA and TX without resetting the FIFOS. - */ - - con |= S3C2412_IISCON_TXDMA_PAUSE; - con |= S3C2412_IISCON_TXCH_PAUSE; - con &= ~S3C2412_IISCON_TXDMA_ACTIVE; - - switch (mod & S3C2412_IISMOD_MODE_MASK) { - case S3C2412_IISMOD_MODE_TXRX: - mod &= ~S3C2412_IISMOD_MODE_MASK; - mod |= S3C2412_IISMOD_MODE_RXONLY; - break; - - case S3C2412_IISMOD_MODE_TXONLY: - mod &= ~S3C2412_IISMOD_MODE_MASK; - con &= ~S3C2412_IISCON_IIS_ACTIVE; - break; - - default: - dev_err(i2s->dev, "TXDIS: Invalid MODE %x in IISMOD\n", - mod & S3C2412_IISMOD_MODE_MASK); - break; - } - - writel(mod, regs + S3C2412_IISMOD); - writel(con, regs + S3C2412_IISCON); - } - - fic = readl(regs + S3C2412_IISFIC); - dbg_showcon(__func__, con); - pr_debug("%s: IIS: CON=%x MOD=%x FIC=%x\n", __func__, con, mod, fic); -} - -static void s3c2412_snd_rxctrl(struct s3c_i2sv2_info *i2s, int on) -{ - void __iomem *regs = i2s->regs; - u32 fic, con, mod; - - pr_debug("%s(%d)\n", __func__, on); - - fic = readl(regs + S3C2412_IISFIC); - con = readl(regs + S3C2412_IISCON); - mod = readl(regs + S3C2412_IISMOD); - - pr_debug("%s: IIS: CON=%x MOD=%x FIC=%x\n", __func__, con, mod, fic); - - if (on) { - con |= S3C2412_IISCON_RXDMA_ACTIVE | S3C2412_IISCON_IIS_ACTIVE; - con &= ~S3C2412_IISCON_RXDMA_PAUSE; - con &= ~S3C2412_IISCON_RXCH_PAUSE; - - switch (mod & S3C2412_IISMOD_MODE_MASK) { - case S3C2412_IISMOD_MODE_TXRX: - case S3C2412_IISMOD_MODE_RXONLY: - /* do nothing, we are in the right mode */ - break; - - case S3C2412_IISMOD_MODE_TXONLY: - mod &= ~S3C2412_IISMOD_MODE_MASK; - mod |= S3C2412_IISMOD_MODE_TXRX; - break; - - default: - dev_err(i2s->dev, "RXEN: Invalid MODE %x in IISMOD\n", - mod & S3C2412_IISMOD_MODE_MASK); - } - - writel(mod, regs + S3C2412_IISMOD); - writel(con, regs + S3C2412_IISCON); - } else { - /* See txctrl notes on FIFOs. */ - - con &= ~S3C2412_IISCON_RXDMA_ACTIVE; - con |= S3C2412_IISCON_RXDMA_PAUSE; - con |= S3C2412_IISCON_RXCH_PAUSE; - - switch (mod & S3C2412_IISMOD_MODE_MASK) { - case S3C2412_IISMOD_MODE_RXONLY: - con &= ~S3C2412_IISCON_IIS_ACTIVE; - mod &= ~S3C2412_IISMOD_MODE_MASK; - break; - - case S3C2412_IISMOD_MODE_TXRX: - mod &= ~S3C2412_IISMOD_MODE_MASK; - mod |= S3C2412_IISMOD_MODE_TXONLY; - break; - - default: - dev_err(i2s->dev, "RXDIS: Invalid MODE %x in IISMOD\n", - mod & S3C2412_IISMOD_MODE_MASK); - } - - writel(con, regs + S3C2412_IISCON); - writel(mod, regs + S3C2412_IISMOD); - } - - fic = readl(regs + S3C2412_IISFIC); - pr_debug("%s: IIS: CON=%x MOD=%x FIC=%x\n", __func__, con, mod, fic); -} - -#define msecs_to_loops(t) (loops_per_jiffy / 1000 * HZ * t) - -/* - * Wait for the LR signal to allow synchronisation to the L/R clock - * from the codec. May only be needed for slave mode. - */ -static int s3c2412_snd_lrsync(struct s3c_i2sv2_info *i2s) -{ - u32 iiscon; - unsigned long loops = msecs_to_loops(5); - - pr_debug("Entered %s\n", __func__); - - while (--loops) { - iiscon = readl(i2s->regs + S3C2412_IISCON); - if (iiscon & S3C2412_IISCON_LRINDEX) - break; - - cpu_relax(); - } - - if (!loops) { - printk(KERN_ERR "%s: timeout\n", __func__); - return -ETIMEDOUT; - } - - return 0; -} - -/* - * Set S3C2412 I2S DAI format - */ -static int s3c2412_i2s_set_fmt(struct snd_soc_dai *cpu_dai, - unsigned int fmt) -{ - struct s3c_i2sv2_info *i2s = to_info(cpu_dai); - u32 iismod; - - pr_debug("Entered %s\n", __func__); - - iismod = readl(i2s->regs + S3C2412_IISMOD); - pr_debug("hw_params r: IISMOD: %x \n", iismod); - - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: - i2s->master = 0; - iismod |= S3C2412_IISMOD_SLAVE; - break; - case SND_SOC_DAIFMT_CBS_CFS: - i2s->master = 1; - iismod &= ~S3C2412_IISMOD_SLAVE; - break; - default: - pr_err("unknwon master/slave format\n"); - return -EINVAL; - } - - iismod &= ~S3C2412_IISMOD_SDF_MASK; - - switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { - case SND_SOC_DAIFMT_RIGHT_J: - iismod |= S3C2412_IISMOD_LR_RLOW; - iismod |= S3C2412_IISMOD_SDF_MSB; - break; - case SND_SOC_DAIFMT_LEFT_J: - iismod |= S3C2412_IISMOD_LR_RLOW; - iismod |= S3C2412_IISMOD_SDF_LSB; - break; - case SND_SOC_DAIFMT_I2S: - iismod &= ~S3C2412_IISMOD_LR_RLOW; - iismod |= S3C2412_IISMOD_SDF_IIS; - break; - default: - pr_err("Unknown data format\n"); - return -EINVAL; - } - - writel(iismod, i2s->regs + S3C2412_IISMOD); - pr_debug("hw_params w: IISMOD: %x \n", iismod); - return 0; -} - -static int s3c_i2sv2_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params, - struct snd_soc_dai *dai) -{ - struct s3c_i2sv2_info *i2s = to_info(dai); - struct s3c_dma_params *dma_data; - u32 iismod; - - pr_debug("Entered %s\n", __func__); - - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - dma_data = i2s->dma_playback; - else - dma_data = i2s->dma_capture; - - snd_soc_dai_set_dma_data(dai, substream, dma_data); - - /* Working copies of register */ - iismod = readl(i2s->regs + S3C2412_IISMOD); - pr_debug("%s: r: IISMOD: %x\n", __func__, iismod); - - iismod &= ~S3C64XX_IISMOD_BLC_MASK; - /* Sample size */ - switch (params_format(params)) { - case SNDRV_PCM_FORMAT_S8: - iismod |= S3C64XX_IISMOD_BLC_8BIT; - break; - case SNDRV_PCM_FORMAT_S16_LE: - break; - case SNDRV_PCM_FORMAT_S24_LE: - iismod |= S3C64XX_IISMOD_BLC_24BIT; - break; - } - - writel(iismod, i2s->regs + S3C2412_IISMOD); - pr_debug("%s: w: IISMOD: %x\n", __func__, iismod); - - return 0; -} - -static int s3c_i2sv2_set_sysclk(struct snd_soc_dai *cpu_dai, - int clk_id, unsigned int freq, int dir) -{ - struct s3c_i2sv2_info *i2s = to_info(cpu_dai); - u32 iismod = readl(i2s->regs + S3C2412_IISMOD); - - pr_debug("Entered %s\n", __func__); - pr_debug("%s r: IISMOD: %x\n", __func__, iismod); - - switch (clk_id) { - case S3C_I2SV2_CLKSRC_PCLK: - iismod &= ~S3C2412_IISMOD_IMS_SYSMUX; - break; - - case S3C_I2SV2_CLKSRC_AUDIOBUS: - iismod |= S3C2412_IISMOD_IMS_SYSMUX; - break; - - case S3C_I2SV2_CLKSRC_CDCLK: - /* Error if controller doesn't have the CDCLKCON bit */ - if (!(i2s->feature & S3C_FEATURE_CDCLKCON)) - return -EINVAL; - - switch (dir) { - case SND_SOC_CLOCK_IN: - iismod |= S3C64XX_IISMOD_CDCLKCON; - break; - case SND_SOC_CLOCK_OUT: - iismod &= ~S3C64XX_IISMOD_CDCLKCON; - break; - default: - return -EINVAL; - } - break; - - default: - return -EINVAL; - } - - writel(iismod, i2s->regs + S3C2412_IISMOD); - pr_debug("%s w: IISMOD: %x\n", __func__, iismod); - - return 0; -} - -static int s3c2412_i2s_trigger(struct snd_pcm_substream *substream, int cmd, - struct snd_soc_dai *dai) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct s3c_i2sv2_info *i2s = to_info(rtd->cpu_dai); - int capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE); - unsigned long irqs; - int ret = 0; - struct s3c_dma_params *dma_data = - snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); - - pr_debug("Entered %s\n", __func__); - - switch (cmd) { - case SNDRV_PCM_TRIGGER_START: - /* On start, ensure that the FIFOs are cleared and reset. */ - - writel(capture ? S3C2412_IISFIC_RXFLUSH : S3C2412_IISFIC_TXFLUSH, - i2s->regs + S3C2412_IISFIC); - - /* clear again, just in case */ - writel(0x0, i2s->regs + S3C2412_IISFIC); - - case SNDRV_PCM_TRIGGER_RESUME: - case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - if (!i2s->master) { - ret = s3c2412_snd_lrsync(i2s); - if (ret) - goto exit_err; - } - - local_irq_save(irqs); - - if (capture) - s3c2412_snd_rxctrl(i2s, 1); - else - s3c2412_snd_txctrl(i2s, 1); - - local_irq_restore(irqs); - - /* - * Load the next buffer to DMA to meet the reqirement - * of the auto reload mechanism of S3C24XX. - * This call won't bother S3C64XX. - */ - s3c2410_dma_ctrl(dma_data->channel, S3C2410_DMAOP_STARTED); - - break; - - case SNDRV_PCM_TRIGGER_STOP: - case SNDRV_PCM_TRIGGER_SUSPEND: - case SNDRV_PCM_TRIGGER_PAUSE_PUSH: - local_irq_save(irqs); - - if (capture) - s3c2412_snd_rxctrl(i2s, 0); - else - s3c2412_snd_txctrl(i2s, 0); - - local_irq_restore(irqs); - break; - default: - ret = -EINVAL; - break; - } - -exit_err: - return ret; -} - -/* - * Set S3C2412 Clock dividers - */ -static int s3c2412_i2s_set_clkdiv(struct snd_soc_dai *cpu_dai, - int div_id, int div) -{ - struct s3c_i2sv2_info *i2s = to_info(cpu_dai); - u32 reg; - - pr_debug("%s(%p, %d, %d)\n", __func__, cpu_dai, div_id, div); - - switch (div_id) { - case S3C_I2SV2_DIV_BCLK: - switch (div) { - case 16: - div = S3C2412_IISMOD_BCLK_16FS; - break; - - case 32: - div = S3C2412_IISMOD_BCLK_32FS; - break; - - case 24: - div = S3C2412_IISMOD_BCLK_24FS; - break; - - case 48: - div = S3C2412_IISMOD_BCLK_48FS; - break; - - default: - return -EINVAL; - } - - reg = readl(i2s->regs + S3C2412_IISMOD); - reg &= ~S3C2412_IISMOD_BCLK_MASK; - writel(reg | div, i2s->regs + S3C2412_IISMOD); - - pr_debug("%s: MOD=%08x\n", __func__, readl(i2s->regs + S3C2412_IISMOD)); - break; - - case S3C_I2SV2_DIV_RCLK: - switch (div) { - case 256: - div = S3C2412_IISMOD_RCLK_256FS; - break; - - case 384: - div = S3C2412_IISMOD_RCLK_384FS; - break; - - case 512: - div = S3C2412_IISMOD_RCLK_512FS; - break; - - case 768: - div = S3C2412_IISMOD_RCLK_768FS; - break; - - default: - return -EINVAL; - } - - reg = readl(i2s->regs + S3C2412_IISMOD); - reg &= ~S3C2412_IISMOD_RCLK_MASK; - writel(reg | div, i2s->regs + S3C2412_IISMOD); - pr_debug("%s: MOD=%08x\n", __func__, readl(i2s->regs + S3C2412_IISMOD)); - break; - - case S3C_I2SV2_DIV_PRESCALER: - if (div >= 0) { - writel((div << 8) | S3C2412_IISPSR_PSREN, - i2s->regs + S3C2412_IISPSR); - } else { - writel(0x0, i2s->regs + S3C2412_IISPSR); - } - pr_debug("%s: PSR=%08x\n", __func__, readl(i2s->regs + S3C2412_IISPSR)); - break; - - default: - return -EINVAL; - } - - return 0; -} - -static snd_pcm_sframes_t s3c2412_i2s_delay(struct snd_pcm_substream *substream, - struct snd_soc_dai *dai) -{ - struct s3c_i2sv2_info *i2s = to_info(dai); - u32 reg = readl(i2s->regs + S3C2412_IISFIC); - snd_pcm_sframes_t delay; - - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - delay = S3C2412_IISFIC_TXCOUNT(reg); - else - delay = S3C2412_IISFIC_RXCOUNT(reg); - - return delay; -} - -struct clk *s3c_i2sv2_get_clock(struct snd_soc_dai *cpu_dai) -{ - struct s3c_i2sv2_info *i2s = to_info(cpu_dai); - u32 iismod = readl(i2s->regs + S3C2412_IISMOD); - - if (iismod & S3C2412_IISMOD_IMS_SYSMUX) - return i2s->iis_cclk; - else - return i2s->iis_pclk; -} -EXPORT_SYMBOL_GPL(s3c_i2sv2_get_clock); - -/* default table of all avaialable root fs divisors */ -static unsigned int iis_fs_tab[] = { 256, 512, 384, 768 }; - -int s3c_i2sv2_iis_calc_rate(struct s3c_i2sv2_rate_calc *info, - unsigned int *fstab, - unsigned int rate, struct clk *clk) -{ - unsigned long clkrate = clk_get_rate(clk); - unsigned int div; - unsigned int fsclk; - unsigned int actual; - unsigned int fs; - unsigned int fsdiv; - signed int deviation = 0; - unsigned int best_fs = 0; - unsigned int best_div = 0; - unsigned int best_rate = 0; - unsigned int best_deviation = INT_MAX; - - pr_debug("Input clock rate %ldHz\n", clkrate); - - if (fstab == NULL) - fstab = iis_fs_tab; - - for (fs = 0; fs < ARRAY_SIZE(iis_fs_tab); fs++) { - fsdiv = iis_fs_tab[fs]; - - fsclk = clkrate / fsdiv; - div = fsclk / rate; - - if ((fsclk % rate) > (rate / 2)) - div++; - - if (div <= 1) - continue; - - actual = clkrate / (fsdiv * div); - deviation = actual - rate; - - printk(KERN_DEBUG "%ufs: div %u => result %u, deviation %d\n", - fsdiv, div, actual, deviation); - - deviation = abs(deviation); - - if (deviation < best_deviation) { - best_fs = fsdiv; - best_div = div; - best_rate = actual; - best_deviation = deviation; - } - - if (deviation == 0) - break; - } - - printk(KERN_DEBUG "best: fs=%u, div=%u, rate=%u\n", - best_fs, best_div, best_rate); - - info->fs_div = best_fs; - info->clk_div = best_div; - - return 0; -} -EXPORT_SYMBOL_GPL(s3c_i2sv2_iis_calc_rate); - -int s3c_i2sv2_probe(struct snd_soc_dai *dai, - struct s3c_i2sv2_info *i2s, - unsigned long base) -{ - struct device *dev = dai->dev; - unsigned int iismod; - - i2s->dev = dev; - - /* record our i2s structure for later use in the callbacks */ - snd_soc_dai_set_drvdata(dai, i2s); - - i2s->regs = ioremap(base, 0x100); - if (i2s->regs == NULL) { - dev_err(dev, "cannot ioremap registers\n"); - return -ENXIO; - } - - i2s->iis_pclk = clk_get(dev, "iis"); - if (IS_ERR(i2s->iis_pclk)) { - dev_err(dev, "failed to get iis_clock\n"); - iounmap(i2s->regs); - return -ENOENT; - } - - clk_enable(i2s->iis_pclk); - - /* Mark ourselves as in TXRX mode so we can run through our cleanup - * process without warnings. */ - iismod = readl(i2s->regs + S3C2412_IISMOD); - iismod |= S3C2412_IISMOD_MODE_TXRX; - writel(iismod, i2s->regs + S3C2412_IISMOD); - s3c2412_snd_txctrl(i2s, 0); - s3c2412_snd_rxctrl(i2s, 0); - - return 0; -} -EXPORT_SYMBOL_GPL(s3c_i2sv2_probe); - -#ifdef CONFIG_PM -static int s3c2412_i2s_suspend(struct snd_soc_dai *dai) -{ - struct s3c_i2sv2_info *i2s = to_info(dai); - u32 iismod; - - if (dai->active) { - i2s->suspend_iismod = readl(i2s->regs + S3C2412_IISMOD); - i2s->suspend_iiscon = readl(i2s->regs + S3C2412_IISCON); - i2s->suspend_iispsr = readl(i2s->regs + S3C2412_IISPSR); - - /* some basic suspend checks */ - - iismod = readl(i2s->regs + S3C2412_IISMOD); - - if (iismod & S3C2412_IISCON_RXDMA_ACTIVE) - pr_warning("%s: RXDMA active?\n", __func__); - - if (iismod & S3C2412_IISCON_TXDMA_ACTIVE) - pr_warning("%s: TXDMA active?\n", __func__); - - if (iismod & S3C2412_IISCON_IIS_ACTIVE) - pr_warning("%s: IIS active\n", __func__); - } - - return 0; -} - -static int s3c2412_i2s_resume(struct snd_soc_dai *dai) -{ - struct s3c_i2sv2_info *i2s = to_info(dai); - - pr_info("dai_active %d, IISMOD %08x, IISCON %08x\n", - dai->active, i2s->suspend_iismod, i2s->suspend_iiscon); - - if (dai->active) { - writel(i2s->suspend_iiscon, i2s->regs + S3C2412_IISCON); - writel(i2s->suspend_iismod, i2s->regs + S3C2412_IISMOD); - writel(i2s->suspend_iispsr, i2s->regs + S3C2412_IISPSR); - - writel(S3C2412_IISFIC_RXFLUSH | S3C2412_IISFIC_TXFLUSH, - i2s->regs + S3C2412_IISFIC); - - ndelay(250); - writel(0x0, i2s->regs + S3C2412_IISFIC); - } - - return 0; -} -#else -#define s3c2412_i2s_suspend NULL -#define s3c2412_i2s_resume NULL -#endif - -int s3c_i2sv2_register_dai(struct device *dev, int id, - struct snd_soc_dai_driver *drv) -{ - struct snd_soc_dai_ops *ops = drv->ops; - - ops->trigger = s3c2412_i2s_trigger; - if (!ops->hw_params) - ops->hw_params = s3c_i2sv2_hw_params; - ops->set_fmt = s3c2412_i2s_set_fmt; - ops->set_clkdiv = s3c2412_i2s_set_clkdiv; - ops->set_sysclk = s3c_i2sv2_set_sysclk; - - /* Allow overriding by (for example) IISv4 */ - if (!ops->delay) - ops->delay = s3c2412_i2s_delay; - - drv->suspend = s3c2412_i2s_suspend; - drv->resume = s3c2412_i2s_resume; - - return snd_soc_register_dai(dev, drv); -} -EXPORT_SYMBOL_GPL(s3c_i2sv2_register_dai); - -MODULE_LICENSE("GPL"); diff --git a/sound/soc/s3c24xx/s3c-i2s-v2.h b/sound/soc/s3c24xx/s3c-i2s-v2.h deleted file mode 100644 index d45830151484..000000000000 --- a/sound/soc/s3c24xx/s3c-i2s-v2.h +++ /dev/null @@ -1,106 +0,0 @@ -/* sound/soc/s3c24xx/s3c-i2s-v2.h - * - * ALSA Soc Audio Layer - S3C_I2SV2 I2S driver - * - * Copyright (c) 2007 Simtec Electronics - * http://armlinux.simtec.co.uk/ - * Ben Dooks - * - * 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. -*/ - -/* This code is the core support for the I2S block found in a number of - * Samsung SoC devices which is unofficially named I2S-V2. Currently the - * S3C2412 and the S3C64XX series use this block to provide 1 or 2 I2S - * channels via configurable GPIO. - */ - -#ifndef __SND_SOC_S3C24XX_S3C_I2SV2_I2S_H -#define __SND_SOC_S3C24XX_S3C_I2SV2_I2S_H __FILE__ - -#define S3C_I2SV2_DIV_BCLK (1) -#define S3C_I2SV2_DIV_RCLK (2) -#define S3C_I2SV2_DIV_PRESCALER (3) - -#define S3C_I2SV2_CLKSRC_PCLK 0 -#define S3C_I2SV2_CLKSRC_AUDIOBUS 1 -#define S3C_I2SV2_CLKSRC_CDCLK 2 - -/* Set this flag for I2S controllers that have the bit IISMOD[12] - * bridge/break RCLK signal and external Xi2sCDCLK pin. - */ -#define S3C_FEATURE_CDCLKCON (1 << 0) - -/** - * struct s3c_i2sv2_info - S3C I2S-V2 information - * @dev: The parent device passed to use from the probe. - * @regs: The pointer to the device registe block. - * @feature: Set of bit-flags indicating features of the controller. - * @master: True if the I2S core is the I2S bit clock master. - * @dma_playback: DMA information for playback channel. - * @dma_capture: DMA information for capture channel. - * @suspend_iismod: PM save for the IISMOD register. - * @suspend_iiscon: PM save for the IISCON register. - * @suspend_iispsr: PM save for the IISPSR register. - * - * This is the private codec state for the hardware associated with an - * I2S channel such as the register mappings and clock sources. - */ -struct s3c_i2sv2_info { - struct device *dev; - void __iomem *regs; - - u32 feature; - - struct clk *iis_pclk; - struct clk *iis_cclk; - - unsigned char master; - - struct s3c_dma_params *dma_playback; - struct s3c_dma_params *dma_capture; - - u32 suspend_iismod; - u32 suspend_iiscon; - u32 suspend_iispsr; - - unsigned long base; -}; - -extern struct clk *s3c_i2sv2_get_clock(struct snd_soc_dai *cpu_dai); - -struct s3c_i2sv2_rate_calc { - unsigned int clk_div; /* for prescaler */ - unsigned int fs_div; /* for root frame clock */ -}; - -extern int s3c_i2sv2_iis_calc_rate(struct s3c_i2sv2_rate_calc *info, - unsigned int *fstab, - unsigned int rate, struct clk *clk); - -/** - * s3c_i2sv2_probe - probe for i2s device helper - * @dai: The ASoC DAI structure supplied to the original probe. - * @i2s: Our local i2s structure to fill in. - * @base: The base address for the registers. - */ -extern int s3c_i2sv2_probe(struct snd_soc_dai *dai, - struct s3c_i2sv2_info *i2s, - unsigned long base); - -/** - * s3c_i2sv2_register_dai - register dai with soc core - * @dev: DAI device - * @id: DAI ID - * @drv: The driver structure to register - * - * Fill in any missing fields and then register the given dai with the - * soc core. - */ -extern int s3c_i2sv2_register_dai(struct device *dev, int id, - struct snd_soc_dai_driver *drv); - -#endif /* __SND_SOC_S3C24XX_S3C_I2SV2_I2S_H */ diff --git a/sound/soc/s3c24xx/s3c2412-i2s.c b/sound/soc/s3c24xx/s3c2412-i2s.c deleted file mode 100644 index d953ff4ba2db..000000000000 --- a/sound/soc/s3c24xx/s3c2412-i2s.c +++ /dev/null @@ -1,212 +0,0 @@ -/* sound/soc/s3c24xx/s3c2412-i2s.c - * - * ALSA Soc Audio Layer - S3C2412 I2S driver - * - * Copyright (c) 2006 Wolfson Microelectronics PLC. - * Graeme Gregory graeme.gregory@wolfsonmicro.com - * linux@wolfsonmicro.com - * - * Copyright (c) 2007, 2004-2005 Simtec Electronics - * http://armlinux.simtec.co.uk/ - * Ben Dooks - * - * 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. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "dma.h" -#include "regs-i2s-v2.h" -#include "s3c2412-i2s.h" - -#define S3C2412_I2S_DEBUG 0 - -static struct s3c2410_dma_client s3c2412_dma_client_out = { - .name = "I2S PCM Stereo out" -}; - -static struct s3c2410_dma_client s3c2412_dma_client_in = { - .name = "I2S PCM Stereo in" -}; - -static struct s3c_dma_params s3c2412_i2s_pcm_stereo_out = { - .client = &s3c2412_dma_client_out, - .channel = DMACH_I2S_OUT, - .dma_addr = S3C2410_PA_IIS + S3C2412_IISTXD, - .dma_size = 4, -}; - -static struct s3c_dma_params s3c2412_i2s_pcm_stereo_in = { - .client = &s3c2412_dma_client_in, - .channel = DMACH_I2S_IN, - .dma_addr = S3C2410_PA_IIS + S3C2412_IISRXD, - .dma_size = 4, -}; - -static struct s3c_i2sv2_info s3c2412_i2s; - -static int s3c2412_i2s_probe(struct snd_soc_dai *dai) -{ - int ret; - - pr_debug("Entered %s\n", __func__); - - ret = s3c_i2sv2_probe(dai, &s3c2412_i2s, S3C2410_PA_IIS); - if (ret) - return ret; - - s3c2412_i2s.dma_capture = &s3c2412_i2s_pcm_stereo_in; - s3c2412_i2s.dma_playback = &s3c2412_i2s_pcm_stereo_out; - - s3c2412_i2s.iis_cclk = clk_get(dai->dev, "i2sclk"); - if (s3c2412_i2s.iis_cclk == NULL) { - pr_err("failed to get i2sclk clock\n"); - iounmap(s3c2412_i2s.regs); - return -ENODEV; - } - - /* Set MPLL as the source for IIS CLK */ - - clk_set_parent(s3c2412_i2s.iis_cclk, clk_get(NULL, "mpll")); - clk_enable(s3c2412_i2s.iis_cclk); - - s3c2412_i2s.iis_cclk = s3c2412_i2s.iis_pclk; - - /* Configure the I2S pins in correct mode */ - s3c2410_gpio_cfgpin(S3C2410_GPE0, S3C2410_GPE0_I2SLRCK); - s3c2410_gpio_cfgpin(S3C2410_GPE1, S3C2410_GPE1_I2SSCLK); - s3c2410_gpio_cfgpin(S3C2410_GPE2, S3C2410_GPE2_CDCLK); - s3c2410_gpio_cfgpin(S3C2410_GPE3, S3C2410_GPE3_I2SSDI); - s3c2410_gpio_cfgpin(S3C2410_GPE4, S3C2410_GPE4_I2SSDO); - - return 0; -} - -static int s3c2412_i2s_remove(struct snd_soc_dai *dai) -{ - clk_disable(s3c2412_i2s.iis_cclk); - clk_put(s3c2412_i2s.iis_cclk); - iounmap(s3c2412_i2s.regs); - - return 0; -} - -static int s3c2412_i2s_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params, - struct snd_soc_dai *cpu_dai) -{ - struct s3c_i2sv2_info *i2s = snd_soc_dai_get_drvdata(cpu_dai); - struct s3c_dma_params *dma_data; - u32 iismod; - - pr_debug("Entered %s\n", __func__); - - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - dma_data = i2s->dma_playback; - else - dma_data = i2s->dma_capture; - - snd_soc_dai_set_dma_data(cpu_dai, substream, dma_data); - - iismod = readl(i2s->regs + S3C2412_IISMOD); - pr_debug("%s: r: IISMOD: %x\n", __func__, iismod); - - switch (params_format(params)) { - case SNDRV_PCM_FORMAT_S8: - iismod |= S3C2412_IISMOD_8BIT; - break; - case SNDRV_PCM_FORMAT_S16_LE: - iismod &= ~S3C2412_IISMOD_8BIT; - break; - } - - writel(iismod, i2s->regs + S3C2412_IISMOD); - pr_debug("%s: w: IISMOD: %x\n", __func__, iismod); - - return 0; -} - -#define S3C2412_I2S_RATES \ - (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | SNDRV_PCM_RATE_16000 | \ - SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \ - SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000) - -static struct snd_soc_dai_ops s3c2412_i2s_dai_ops = { - .hw_params = s3c2412_i2s_hw_params, -}; - -static struct snd_soc_dai_driver s3c2412_i2s_dai = { - .probe = s3c2412_i2s_probe, - .remove = s3c2412_i2s_remove, - .playback = { - .channels_min = 2, - .channels_max = 2, - .rates = S3C2412_I2S_RATES, - .formats = SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE, - }, - .capture = { - .channels_min = 2, - .channels_max = 2, - .rates = S3C2412_I2S_RATES, - .formats = SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE, - }, - .ops = &s3c2412_i2s_dai_ops, -}; - -static __devinit int s3c2412_iis_dev_probe(struct platform_device *pdev) -{ - return snd_soc_register_dai(&pdev->dev, &s3c2412_i2s_dai); -} - -static __devexit int s3c2412_iis_dev_remove(struct platform_device *pdev) -{ - snd_soc_unregister_dai(&pdev->dev); - return 0; -} - -static struct platform_driver s3c2412_iis_driver = { - .probe = s3c2412_iis_dev_probe, - .remove = s3c2412_iis_dev_remove, - .driver = { - .name = "s3c2412-iis", - .owner = THIS_MODULE, - }, -}; - -static int __init s3c2412_i2s_init(void) -{ - return platform_driver_register(&s3c2412_iis_driver); -} -module_init(s3c2412_i2s_init); - -static void __exit s3c2412_i2s_exit(void) -{ - platform_driver_unregister(&s3c2412_iis_driver); -} -module_exit(s3c2412_i2s_exit); - -/* Module information */ -MODULE_AUTHOR("Ben Dooks, "); -MODULE_DESCRIPTION("S3C2412 I2S SoC Interface"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:s3c2412-iis"); diff --git a/sound/soc/s3c24xx/s3c2412-i2s.h b/sound/soc/s3c24xx/s3c2412-i2s.h deleted file mode 100644 index 01a0471ac65c..000000000000 --- a/sound/soc/s3c24xx/s3c2412-i2s.h +++ /dev/null @@ -1,27 +0,0 @@ -/* sound/soc/s3c24xx/s3c2412-i2s.c - * - * ALSA Soc Audio Layer - S3C2412 I2S driver - * - * Copyright (c) 2007 Simtec Electronics - * http://armlinux.simtec.co.uk/ - * Ben Dooks - * - * 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 __SND_SOC_S3C24XX_S3C2412_I2S_H -#define __SND_SOC_S3C24XX_S3C2412_I2S_H __FILE__ - -#include "s3c-i2s-v2.h" - -#define S3C2412_DIV_BCLK S3C_I2SV2_DIV_BCLK -#define S3C2412_DIV_RCLK S3C_I2SV2_DIV_RCLK -#define S3C2412_DIV_PRESCALER S3C_I2SV2_DIV_PRESCALER - -#define S3C2412_CLKSRC_PCLK S3C_I2SV2_CLKSRC_PCLK -#define S3C2412_CLKSRC_I2SCLK S3C_I2SV2_CLKSRC_AUDIOBUS - -#endif /* __SND_SOC_S3C24XX_S3C2412_I2S_H */ diff --git a/sound/soc/s3c24xx/s3c24xx-i2s.c b/sound/soc/s3c24xx/s3c24xx-i2s.c deleted file mode 100644 index 13e41ed8e22b..000000000000 --- a/sound/soc/s3c24xx/s3c24xx-i2s.c +++ /dev/null @@ -1,519 +0,0 @@ -/* - * s3c24xx-i2s.c -- ALSA Soc Audio Layer - * - * (c) 2006 Wolfson Microelectronics PLC. - * Graeme Gregory graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com - * - * Copyright 2004-2005 Simtec Electronics - * http://armlinux.simtec.co.uk/ - * Ben Dooks - * - * 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. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include - -#include - -#include "dma.h" -#include "s3c24xx-i2s.h" - -static struct s3c2410_dma_client s3c24xx_dma_client_out = { - .name = "I2S PCM Stereo out" -}; - -static struct s3c2410_dma_client s3c24xx_dma_client_in = { - .name = "I2S PCM Stereo in" -}; - -static struct s3c_dma_params s3c24xx_i2s_pcm_stereo_out = { - .client = &s3c24xx_dma_client_out, - .channel = DMACH_I2S_OUT, - .dma_addr = S3C2410_PA_IIS + S3C2410_IISFIFO, - .dma_size = 2, -}; - -static struct s3c_dma_params s3c24xx_i2s_pcm_stereo_in = { - .client = &s3c24xx_dma_client_in, - .channel = DMACH_I2S_IN, - .dma_addr = S3C2410_PA_IIS + S3C2410_IISFIFO, - .dma_size = 2, -}; - -struct s3c24xx_i2s_info { - void __iomem *regs; - struct clk *iis_clk; - u32 iiscon; - u32 iismod; - u32 iisfcon; - u32 iispsr; -}; -static struct s3c24xx_i2s_info s3c24xx_i2s; - -static void s3c24xx_snd_txctrl(int on) -{ - u32 iisfcon; - u32 iiscon; - u32 iismod; - - pr_debug("Entered %s\n", __func__); - - iisfcon = readl(s3c24xx_i2s.regs + S3C2410_IISFCON); - iiscon = readl(s3c24xx_i2s.regs + S3C2410_IISCON); - iismod = readl(s3c24xx_i2s.regs + S3C2410_IISMOD); - - pr_debug("r: IISCON: %x IISMOD: %x IISFCON: %x\n", iiscon, iismod, iisfcon); - - if (on) { - iisfcon |= S3C2410_IISFCON_TXDMA | S3C2410_IISFCON_TXENABLE; - iiscon |= S3C2410_IISCON_TXDMAEN | S3C2410_IISCON_IISEN; - iiscon &= ~S3C2410_IISCON_TXIDLE; - iismod |= S3C2410_IISMOD_TXMODE; - - writel(iismod, s3c24xx_i2s.regs + S3C2410_IISMOD); - writel(iisfcon, s3c24xx_i2s.regs + S3C2410_IISFCON); - writel(iiscon, s3c24xx_i2s.regs + S3C2410_IISCON); - } else { - /* note, we have to disable the FIFOs otherwise bad things - * seem to happen when the DMA stops. According to the - * Samsung supplied kernel, this should allow the DMA - * engine and FIFOs to reset. If this isn't allowed, the - * DMA engine will simply freeze randomly. - */ - - iisfcon &= ~S3C2410_IISFCON_TXENABLE; - iisfcon &= ~S3C2410_IISFCON_TXDMA; - iiscon |= S3C2410_IISCON_TXIDLE; - iiscon &= ~S3C2410_IISCON_TXDMAEN; - iismod &= ~S3C2410_IISMOD_TXMODE; - - writel(iiscon, s3c24xx_i2s.regs + S3C2410_IISCON); - writel(iisfcon, s3c24xx_i2s.regs + S3C2410_IISFCON); - writel(iismod, s3c24xx_i2s.regs + S3C2410_IISMOD); - } - - pr_debug("w: IISCON: %x IISMOD: %x IISFCON: %x\n", iiscon, iismod, iisfcon); -} - -static void s3c24xx_snd_rxctrl(int on) -{ - u32 iisfcon; - u32 iiscon; - u32 iismod; - - pr_debug("Entered %s\n", __func__); - - iisfcon = readl(s3c24xx_i2s.regs + S3C2410_IISFCON); - iiscon = readl(s3c24xx_i2s.regs + S3C2410_IISCON); - iismod = readl(s3c24xx_i2s.regs + S3C2410_IISMOD); - - pr_debug("r: IISCON: %x IISMOD: %x IISFCON: %x\n", iiscon, iismod, iisfcon); - - if (on) { - iisfcon |= S3C2410_IISFCON_RXDMA | S3C2410_IISFCON_RXENABLE; - iiscon |= S3C2410_IISCON_RXDMAEN | S3C2410_IISCON_IISEN; - iiscon &= ~S3C2410_IISCON_RXIDLE; - iismod |= S3C2410_IISMOD_RXMODE; - - writel(iismod, s3c24xx_i2s.regs + S3C2410_IISMOD); - writel(iisfcon, s3c24xx_i2s.regs + S3C2410_IISFCON); - writel(iiscon, s3c24xx_i2s.regs + S3C2410_IISCON); - } else { - /* note, we have to disable the FIFOs otherwise bad things - * seem to happen when the DMA stops. According to the - * Samsung supplied kernel, this should allow the DMA - * engine and FIFOs to reset. If this isn't allowed, the - * DMA engine will simply freeze randomly. - */ - - iisfcon &= ~S3C2410_IISFCON_RXENABLE; - iisfcon &= ~S3C2410_IISFCON_RXDMA; - iiscon |= S3C2410_IISCON_RXIDLE; - iiscon &= ~S3C2410_IISCON_RXDMAEN; - iismod &= ~S3C2410_IISMOD_RXMODE; - - writel(iisfcon, s3c24xx_i2s.regs + S3C2410_IISFCON); - writel(iiscon, s3c24xx_i2s.regs + S3C2410_IISCON); - writel(iismod, s3c24xx_i2s.regs + S3C2410_IISMOD); - } - - pr_debug("w: IISCON: %x IISMOD: %x IISFCON: %x\n", iiscon, iismod, iisfcon); -} - -/* - * Wait for the LR signal to allow synchronisation to the L/R clock - * from the codec. May only be needed for slave mode. - */ -static int s3c24xx_snd_lrsync(void) -{ - u32 iiscon; - int timeout = 50; /* 5ms */ - - pr_debug("Entered %s\n", __func__); - - while (1) { - iiscon = readl(s3c24xx_i2s.regs + S3C2410_IISCON); - if (iiscon & S3C2410_IISCON_LRINDEX) - break; - - if (!timeout--) - return -ETIMEDOUT; - udelay(100); - } - - return 0; -} - -/* - * Check whether CPU is the master or slave - */ -static inline int s3c24xx_snd_is_clkmaster(void) -{ - pr_debug("Entered %s\n", __func__); - - return (readl(s3c24xx_i2s.regs + S3C2410_IISMOD) & S3C2410_IISMOD_SLAVE) ? 0:1; -} - -/* - * Set S3C24xx I2S DAI format - */ -static int s3c24xx_i2s_set_fmt(struct snd_soc_dai *cpu_dai, - unsigned int fmt) -{ - u32 iismod; - - pr_debug("Entered %s\n", __func__); - - iismod = readl(s3c24xx_i2s.regs + S3C2410_IISMOD); - pr_debug("hw_params r: IISMOD: %x \n", iismod); - - switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { - case SND_SOC_DAIFMT_CBM_CFM: - iismod |= S3C2410_IISMOD_SLAVE; - break; - case SND_SOC_DAIFMT_CBS_CFS: - iismod &= ~S3C2410_IISMOD_SLAVE; - break; - default: - return -EINVAL; - } - - switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { - case SND_SOC_DAIFMT_LEFT_J: - iismod |= S3C2410_IISMOD_MSB; - break; - case SND_SOC_DAIFMT_I2S: - iismod &= ~S3C2410_IISMOD_MSB; - break; - default: - return -EINVAL; - } - - writel(iismod, s3c24xx_i2s.regs + S3C2410_IISMOD); - pr_debug("hw_params w: IISMOD: %x \n", iismod); - return 0; -} - -static int s3c24xx_i2s_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params, - struct snd_soc_dai *dai) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct s3c_dma_params *dma_data; - u32 iismod; - - pr_debug("Entered %s\n", __func__); - - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - dma_data = &s3c24xx_i2s_pcm_stereo_out; - else - dma_data = &s3c24xx_i2s_pcm_stereo_in; - - snd_soc_dai_set_dma_data(rtd->cpu_dai, substream, dma_data); - - /* Working copies of register */ - iismod = readl(s3c24xx_i2s.regs + S3C2410_IISMOD); - pr_debug("hw_params r: IISMOD: %x\n", iismod); - - switch (params_format(params)) { - case SNDRV_PCM_FORMAT_S8: - iismod &= ~S3C2410_IISMOD_16BIT; - dma_data->dma_size = 1; - break; - case SNDRV_PCM_FORMAT_S16_LE: - iismod |= S3C2410_IISMOD_16BIT; - dma_data->dma_size = 2; - break; - default: - return -EINVAL; - } - - writel(iismod, s3c24xx_i2s.regs + S3C2410_IISMOD); - pr_debug("hw_params w: IISMOD: %x\n", iismod); - return 0; -} - -static int s3c24xx_i2s_trigger(struct snd_pcm_substream *substream, int cmd, - struct snd_soc_dai *dai) -{ - int ret = 0; - struct s3c_dma_params *dma_data = - snd_soc_dai_get_dma_data(dai, substream); - - pr_debug("Entered %s\n", __func__); - - switch (cmd) { - case SNDRV_PCM_TRIGGER_START: - case SNDRV_PCM_TRIGGER_RESUME: - case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - if (!s3c24xx_snd_is_clkmaster()) { - ret = s3c24xx_snd_lrsync(); - if (ret) - goto exit_err; - } - - if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) - s3c24xx_snd_rxctrl(1); - else - s3c24xx_snd_txctrl(1); - - s3c2410_dma_ctrl(dma_data->channel, S3C2410_DMAOP_STARTED); - break; - case SNDRV_PCM_TRIGGER_STOP: - case SNDRV_PCM_TRIGGER_SUSPEND: - case SNDRV_PCM_TRIGGER_PAUSE_PUSH: - if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) - s3c24xx_snd_rxctrl(0); - else - s3c24xx_snd_txctrl(0); - break; - default: - ret = -EINVAL; - break; - } - -exit_err: - return ret; -} - -/* - * Set S3C24xx Clock source - */ -static int s3c24xx_i2s_set_sysclk(struct snd_soc_dai *cpu_dai, - int clk_id, unsigned int freq, int dir) -{ - u32 iismod = readl(s3c24xx_i2s.regs + S3C2410_IISMOD); - - pr_debug("Entered %s\n", __func__); - - iismod &= ~S3C2440_IISMOD_MPLL; - - switch (clk_id) { - case S3C24XX_CLKSRC_PCLK: - break; - case S3C24XX_CLKSRC_MPLL: - iismod |= S3C2440_IISMOD_MPLL; - break; - default: - return -EINVAL; - } - - writel(iismod, s3c24xx_i2s.regs + S3C2410_IISMOD); - return 0; -} - -/* - * Set S3C24xx Clock dividers - */ -static int s3c24xx_i2s_set_clkdiv(struct snd_soc_dai *cpu_dai, - int div_id, int div) -{ - u32 reg; - - pr_debug("Entered %s\n", __func__); - - switch (div_id) { - case S3C24XX_DIV_BCLK: - reg = readl(s3c24xx_i2s.regs + S3C2410_IISMOD) & ~S3C2410_IISMOD_FS_MASK; - writel(reg | div, s3c24xx_i2s.regs + S3C2410_IISMOD); - break; - case S3C24XX_DIV_MCLK: - reg = readl(s3c24xx_i2s.regs + S3C2410_IISMOD) & ~(S3C2410_IISMOD_384FS); - writel(reg | div, s3c24xx_i2s.regs + S3C2410_IISMOD); - break; - case S3C24XX_DIV_PRESCALER: - writel(div, s3c24xx_i2s.regs + S3C2410_IISPSR); - reg = readl(s3c24xx_i2s.regs + S3C2410_IISCON); - writel(reg | S3C2410_IISCON_PSCEN, s3c24xx_i2s.regs + S3C2410_IISCON); - break; - default: - return -EINVAL; - } - - return 0; -} - -/* - * To avoid duplicating clock code, allow machine driver to - * get the clockrate from here. - */ -u32 s3c24xx_i2s_get_clockrate(void) -{ - return clk_get_rate(s3c24xx_i2s.iis_clk); -} -EXPORT_SYMBOL_GPL(s3c24xx_i2s_get_clockrate); - -static int s3c24xx_i2s_probe(struct snd_soc_dai *dai) -{ - pr_debug("Entered %s\n", __func__); - - s3c24xx_i2s.regs = ioremap(S3C2410_PA_IIS, 0x100); - if (s3c24xx_i2s.regs == NULL) - return -ENXIO; - - s3c24xx_i2s.iis_clk = clk_get(dai->dev, "iis"); - if (s3c24xx_i2s.iis_clk == NULL) { - pr_err("failed to get iis_clock\n"); - iounmap(s3c24xx_i2s.regs); - return -ENODEV; - } - clk_enable(s3c24xx_i2s.iis_clk); - - /* Configure the I2S pins in correct mode */ - s3c2410_gpio_cfgpin(S3C2410_GPE0, S3C2410_GPE0_I2SLRCK); - s3c2410_gpio_cfgpin(S3C2410_GPE1, S3C2410_GPE1_I2SSCLK); - s3c2410_gpio_cfgpin(S3C2410_GPE2, S3C2410_GPE2_CDCLK); - s3c2410_gpio_cfgpin(S3C2410_GPE3, S3C2410_GPE3_I2SSDI); - s3c2410_gpio_cfgpin(S3C2410_GPE4, S3C2410_GPE4_I2SSDO); - - writel(S3C2410_IISCON_IISEN, s3c24xx_i2s.regs + S3C2410_IISCON); - - s3c24xx_snd_txctrl(0); - s3c24xx_snd_rxctrl(0); - - return 0; -} - -#ifdef CONFIG_PM -static int s3c24xx_i2s_suspend(struct snd_soc_dai *cpu_dai) -{ - pr_debug("Entered %s\n", __func__); - - s3c24xx_i2s.iiscon = readl(s3c24xx_i2s.regs + S3C2410_IISCON); - s3c24xx_i2s.iismod = readl(s3c24xx_i2s.regs + S3C2410_IISMOD); - s3c24xx_i2s.iisfcon = readl(s3c24xx_i2s.regs + S3C2410_IISFCON); - s3c24xx_i2s.iispsr = readl(s3c24xx_i2s.regs + S3C2410_IISPSR); - - clk_disable(s3c24xx_i2s.iis_clk); - - return 0; -} - -static int s3c24xx_i2s_resume(struct snd_soc_dai *cpu_dai) -{ - pr_debug("Entered %s\n", __func__); - clk_enable(s3c24xx_i2s.iis_clk); - - writel(s3c24xx_i2s.iiscon, s3c24xx_i2s.regs + S3C2410_IISCON); - writel(s3c24xx_i2s.iismod, s3c24xx_i2s.regs + S3C2410_IISMOD); - writel(s3c24xx_i2s.iisfcon, s3c24xx_i2s.regs + S3C2410_IISFCON); - writel(s3c24xx_i2s.iispsr, s3c24xx_i2s.regs + S3C2410_IISPSR); - - return 0; -} -#else -#define s3c24xx_i2s_suspend NULL -#define s3c24xx_i2s_resume NULL -#endif - - -#define S3C24XX_I2S_RATES \ - (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | SNDRV_PCM_RATE_16000 | \ - SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \ - SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000) - -static struct snd_soc_dai_ops s3c24xx_i2s_dai_ops = { - .trigger = s3c24xx_i2s_trigger, - .hw_params = s3c24xx_i2s_hw_params, - .set_fmt = s3c24xx_i2s_set_fmt, - .set_clkdiv = s3c24xx_i2s_set_clkdiv, - .set_sysclk = s3c24xx_i2s_set_sysclk, -}; - -static struct snd_soc_dai_driver s3c24xx_i2s_dai = { - .probe = s3c24xx_i2s_probe, - .suspend = s3c24xx_i2s_suspend, - .resume = s3c24xx_i2s_resume, - .playback = { - .channels_min = 2, - .channels_max = 2, - .rates = S3C24XX_I2S_RATES, - .formats = SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE,}, - .capture = { - .channels_min = 2, - .channels_max = 2, - .rates = S3C24XX_I2S_RATES, - .formats = SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE,}, - .ops = &s3c24xx_i2s_dai_ops, -}; - -static __devinit int s3c24xx_iis_dev_probe(struct platform_device *pdev) -{ - return snd_soc_register_dai(&pdev->dev, &s3c24xx_i2s_dai); -} - -static __devexit int s3c24xx_iis_dev_remove(struct platform_device *pdev) -{ - snd_soc_unregister_dai(&pdev->dev); - return 0; -} - -static struct platform_driver s3c24xx_iis_driver = { - .probe = s3c24xx_iis_dev_probe, - .remove = s3c24xx_iis_dev_remove, - .driver = { - .name = "s3c24xx-iis", - .owner = THIS_MODULE, - }, -}; - -static int __init s3c24xx_i2s_init(void) -{ - return platform_driver_register(&s3c24xx_iis_driver); -} -module_init(s3c24xx_i2s_init); - -static void __exit s3c24xx_i2s_exit(void) -{ - platform_driver_unregister(&s3c24xx_iis_driver); -} -module_exit(s3c24xx_i2s_exit); - -/* Module information */ -MODULE_AUTHOR("Ben Dooks, "); -MODULE_DESCRIPTION("s3c24xx I2S SoC Interface"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:s3c24xx-iis"); diff --git a/sound/soc/s3c24xx/s3c24xx-i2s.h b/sound/soc/s3c24xx/s3c24xx-i2s.h deleted file mode 100644 index f9ca04edacb7..000000000000 --- a/sound/soc/s3c24xx/s3c24xx-i2s.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * s3c24xx-i2s.c -- ALSA Soc Audio Layer - * - * Copyright 2005 Wolfson Microelectronics PLC. - * Author: Graeme Gregory - * graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com - * - * 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. - * - * Revision history - * 10th Nov 2006 Initial version. - */ - -#ifndef S3C24XXI2S_H_ -#define S3C24XXI2S_H_ - -/* clock sources */ -#define S3C24XX_CLKSRC_PCLK 0 -#define S3C24XX_CLKSRC_MPLL 1 - -/* Clock dividers */ -#define S3C24XX_DIV_MCLK 0 -#define S3C24XX_DIV_BCLK 1 -#define S3C24XX_DIV_PRESCALER 2 - -/* prescaler */ -#define S3C24XX_PRESCALE(a,b) \ - (((a - 1) << S3C2410_IISPSR_INTSHIFT) | ((b - 1) << S3C2410_IISPSR_EXTSHFIT)) - -u32 s3c24xx_i2s_get_clockrate(void); - -#endif /*S3C24XXI2S_H_*/ diff --git a/sound/soc/s3c24xx/s3c24xx_simtec.c b/sound/soc/s3c24xx/s3c24xx_simtec.c deleted file mode 100644 index 2c7e2a8f49a1..000000000000 --- a/sound/soc/s3c24xx/s3c24xx_simtec.c +++ /dev/null @@ -1,394 +0,0 @@ -/* sound/soc/s3c24xx/s3c24xx_simtec.c - * - * Copyright 2009 Simtec Electronics - * - * 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 -#include -#include - -#include -#include -#include - -#include - -#include "dma.h" -#include "s3c24xx-i2s.h" -#include "s3c24xx_simtec.h" - -static struct s3c24xx_audio_simtec_pdata *pdata; -static struct clk *xtal_clk; - -static int spk_gain; -static int spk_unmute; - -/** - * speaker_gain_get - read the speaker gain setting. - * @kcontrol: The control for the speaker gain. - * @ucontrol: The value that needs to be updated. - * - * Read the value for the AMP gain control. - */ -static int speaker_gain_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - ucontrol->value.integer.value[0] = spk_gain; - return 0; -} - -/** - * speaker_gain_set - set the value of the speaker amp gain - * @value: The value to write. - */ -static void speaker_gain_set(int value) -{ - gpio_set_value_cansleep(pdata->amp_gain[0], value & 1); - gpio_set_value_cansleep(pdata->amp_gain[1], value >> 1); -} - -/** - * speaker_gain_put - set the speaker gain setting. - * @kcontrol: The control for the speaker gain. - * @ucontrol: The value that needs to be set. - * - * Set the value of the speaker gain from the specified - * @ucontrol setting. - * - * Note, if the speaker amp is muted, then we do not set a gain value - * as at-least one of the ICs that is fitted will try and power up even - * if the main control is set to off. - */ -static int speaker_gain_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - int value = ucontrol->value.integer.value[0]; - - spk_gain = value; - - if (!spk_unmute) - speaker_gain_set(value); - - return 0; -} - -static const struct snd_kcontrol_new amp_gain_controls[] = { - SOC_SINGLE_EXT("Speaker Gain", 0, 0, 3, 0, - speaker_gain_get, speaker_gain_put), -}; - -/** - * spk_unmute_state - set the unmute state of the speaker - * @to: zero to unmute, non-zero to ununmute. - */ -static void spk_unmute_state(int to) -{ - pr_debug("%s: to=%d\n", __func__, to); - - spk_unmute = to; - gpio_set_value(pdata->amp_gpio, to); - - /* if we're umuting, also re-set the gain */ - if (to && pdata->amp_gain[0] > 0) - speaker_gain_set(spk_gain); -} - -/** - * speaker_unmute_get - read the speaker unmute setting. - * @kcontrol: The control for the speaker gain. - * @ucontrol: The value that needs to be updated. - * - * Read the value for the AMP gain control. - */ -static int speaker_unmute_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - ucontrol->value.integer.value[0] = spk_unmute; - return 0; -} - -/** - * speaker_unmute_put - set the speaker unmute setting. - * @kcontrol: The control for the speaker gain. - * @ucontrol: The value that needs to be set. - * - * Set the value of the speaker gain from the specified - * @ucontrol setting. - */ -static int speaker_unmute_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - spk_unmute_state(ucontrol->value.integer.value[0]); - return 0; -} - -/* This is added as a manual control as the speaker amps create clicks - * when their power state is changed, which are far more noticeable than - * anything produced by the CODEC itself. - */ -static const struct snd_kcontrol_new amp_unmute_controls[] = { - SOC_SINGLE_EXT("Speaker Switch", 0, 0, 1, 0, - speaker_unmute_get, speaker_unmute_put), -}; - -void simtec_audio_init(struct snd_soc_pcm_runtime *rtd) -{ - struct snd_soc_codec *codec = rtd->codec; - - if (pdata->amp_gpio > 0) { - pr_debug("%s: adding amp routes\n", __func__); - - snd_soc_add_controls(codec, amp_unmute_controls, - ARRAY_SIZE(amp_unmute_controls)); - } - - if (pdata->amp_gain[0] > 0) { - pr_debug("%s: adding amp controls\n", __func__); - snd_soc_add_controls(codec, amp_gain_controls, - ARRAY_SIZE(amp_gain_controls)); - } -} -EXPORT_SYMBOL_GPL(simtec_audio_init); - -#define CODEC_CLOCK 12000000 - -/** - * simtec_hw_params - update hardware parameters - * @substream: The audio substream instance. - * @params: The parameters requested. - * - * Update the codec data routing and configuration settings - * from the supplied data. - */ -static int simtec_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *codec_dai = rtd->codec_dai; - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; - int ret; - - /* Set the CODEC as the bus clock master, I2S */ - ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S | - SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBM_CFM); - if (ret) { - pr_err("%s: failed set cpu dai format\n", __func__); - return ret; - } - - /* Set the CODEC as the bus clock master */ - ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | - SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBM_CFM); - if (ret) { - pr_err("%s: failed set codec dai format\n", __func__); - return ret; - } - - ret = snd_soc_dai_set_sysclk(codec_dai, 0, - CODEC_CLOCK, SND_SOC_CLOCK_IN); - if (ret) { - pr_err( "%s: failed setting codec sysclk\n", __func__); - return ret; - } - - if (pdata->use_mpllin) { - ret = snd_soc_dai_set_sysclk(cpu_dai, S3C24XX_CLKSRC_MPLL, - 0, SND_SOC_CLOCK_OUT); - - if (ret) { - pr_err("%s: failed to set MPLLin as clksrc\n", - __func__); - return ret; - } - } - - if (pdata->output_cdclk) { - int cdclk_scale; - - cdclk_scale = clk_get_rate(xtal_clk) / CODEC_CLOCK; - cdclk_scale--; - - ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C24XX_DIV_PRESCALER, - cdclk_scale); - } - - return 0; -} - -static int simtec_call_startup(struct s3c24xx_audio_simtec_pdata *pd) -{ - /* call any board supplied startup code, this currently only - * covers the bast/vr1000 which have a CPLD in the way of the - * LRCLK */ - if (pd->startup) - pd->startup(); - - return 0; -} - -static struct snd_soc_ops simtec_snd_ops = { - .hw_params = simtec_hw_params, -}; - -/** - * attach_gpio_amp - get and configure the necessary gpios - * @dev: The device we're probing. - * @pd: The platform data supplied by the board. - * - * If there is a GPIO based amplifier attached to the board, claim - * the necessary GPIO lines for it, and set default values. - */ -static int attach_gpio_amp(struct device *dev, - struct s3c24xx_audio_simtec_pdata *pd) -{ - int ret; - - /* attach gpio amp gain (if any) */ - if (pdata->amp_gain[0] > 0) { - ret = gpio_request(pd->amp_gain[0], "gpio-amp-gain0"); - if (ret) { - dev_err(dev, "cannot get amp gpio gain0\n"); - return ret; - } - - ret = gpio_request(pd->amp_gain[1], "gpio-amp-gain1"); - if (ret) { - dev_err(dev, "cannot get amp gpio gain1\n"); - gpio_free(pdata->amp_gain[0]); - return ret; - } - - gpio_direction_output(pd->amp_gain[0], 0); - gpio_direction_output(pd->amp_gain[1], 0); - } - - /* note, currently we assume GPA0 isn't valid amp */ - if (pdata->amp_gpio > 0) { - ret = gpio_request(pd->amp_gpio, "gpio-amp"); - if (ret) { - dev_err(dev, "cannot get amp gpio %d (%d)\n", - pd->amp_gpio, ret); - goto err_amp; - } - - /* set the amp off at startup */ - spk_unmute_state(0); - } - - return 0; - -err_amp: - if (pd->amp_gain[0] > 0) { - gpio_free(pd->amp_gain[0]); - gpio_free(pd->amp_gain[1]); - } - - return ret; -} - -static void detach_gpio_amp(struct s3c24xx_audio_simtec_pdata *pd) -{ - if (pd->amp_gain[0] > 0) { - gpio_free(pd->amp_gain[0]); - gpio_free(pd->amp_gain[1]); - } - - if (pd->amp_gpio > 0) - gpio_free(pd->amp_gpio); -} - -#ifdef CONFIG_PM -int simtec_audio_resume(struct device *dev) -{ - simtec_call_startup(pdata); - return 0; -} - -const struct dev_pm_ops simtec_audio_pmops = { - .resume = simtec_audio_resume, -}; -EXPORT_SYMBOL_GPL(simtec_audio_pmops); -#endif - -int __devinit simtec_audio_core_probe(struct platform_device *pdev, - struct snd_soc_card *card) -{ - struct platform_device *snd_dev; - int ret; - - card->dai_link->ops = &simtec_snd_ops; - - pdata = pdev->dev.platform_data; - if (!pdata) { - dev_err(&pdev->dev, "no platform data supplied\n"); - return -EINVAL; - } - - simtec_call_startup(pdata); - - xtal_clk = clk_get(&pdev->dev, "xtal"); - if (IS_ERR(xtal_clk)) { - dev_err(&pdev->dev, "could not get clkout0\n"); - return -EINVAL; - } - - dev_info(&pdev->dev, "xtal rate is %ld\n", clk_get_rate(xtal_clk)); - - ret = attach_gpio_amp(&pdev->dev, pdata); - if (ret) - goto err_clk; - - snd_dev = platform_device_alloc("soc-audio", -1); - if (!snd_dev) { - dev_err(&pdev->dev, "failed to alloc soc-audio devicec\n"); - ret = -ENOMEM; - goto err_gpio; - } - - platform_set_drvdata(snd_dev, card); - - ret = platform_device_add(snd_dev); - if (ret) { - dev_err(&pdev->dev, "failed to add soc-audio dev\n"); - goto err_pdev; - } - - platform_set_drvdata(pdev, snd_dev); - return 0; - -err_pdev: - platform_device_put(snd_dev); - -err_gpio: - detach_gpio_amp(pdata); - -err_clk: - clk_put(xtal_clk); - return ret; -} -EXPORT_SYMBOL_GPL(simtec_audio_core_probe); - -int __devexit simtec_audio_remove(struct platform_device *pdev) -{ - struct platform_device *snd_dev = platform_get_drvdata(pdev); - - platform_device_unregister(snd_dev); - - detach_gpio_amp(pdata); - clk_put(xtal_clk); - return 0; -} -EXPORT_SYMBOL_GPL(simtec_audio_remove); - -MODULE_AUTHOR("Ben Dooks "); -MODULE_DESCRIPTION("ALSA SoC Simtec Audio common support"); -MODULE_LICENSE("GPL"); diff --git a/sound/soc/s3c24xx/s3c24xx_simtec.h b/sound/soc/s3c24xx/s3c24xx_simtec.h deleted file mode 100644 index e63d5ff9c41f..000000000000 --- a/sound/soc/s3c24xx/s3c24xx_simtec.h +++ /dev/null @@ -1,22 +0,0 @@ -/* sound/soc/s3c24xx/s3c24xx_simtec.h - * - * Copyright 2009 Simtec Electronics - * - * 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. -*/ - -extern void simtec_audio_init(struct snd_soc_pcm_runtime *rtd); - -extern int simtec_audio_core_probe(struct platform_device *pdev, - struct snd_soc_card *card); - -extern int simtec_audio_remove(struct platform_device *pdev); - -#ifdef CONFIG_PM -extern const struct dev_pm_ops simtec_audio_pmops; -#define simtec_audio_pm &simtec_audio_pmops -#else -#define simtec_audio_pm NULL -#endif diff --git a/sound/soc/s3c24xx/s3c24xx_simtec_hermes.c b/sound/soc/s3c24xx/s3c24xx_simtec_hermes.c deleted file mode 100644 index 3509403fb64d..000000000000 --- a/sound/soc/s3c24xx/s3c24xx_simtec_hermes.c +++ /dev/null @@ -1,146 +0,0 @@ -/* sound/soc/s3c24xx/s3c24xx_simtec_hermes.c - * - * Copyright 2009 Simtec Electronics - * - * 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 -#include -#include - -#include - -#include "dma.h" -#include "s3c24xx-i2s.h" -#include "s3c24xx_simtec.h" - -#include "../codecs/tlv320aic3x.h" - -static const struct snd_soc_dapm_widget dapm_widgets[] = { - SND_SOC_DAPM_LINE("GSM Out", NULL), - SND_SOC_DAPM_LINE("GSM In", NULL), - SND_SOC_DAPM_LINE("Line In", NULL), - SND_SOC_DAPM_LINE("Line Out", NULL), - SND_SOC_DAPM_LINE("ZV", NULL), - SND_SOC_DAPM_MIC("Mic Jack", NULL), - SND_SOC_DAPM_HP("Headphone Jack", NULL), -}; - -static const struct snd_soc_dapm_route base_map[] = { - /* Headphone connected to HP{L,R}OUT and HP{L,R}COM */ - - { "Headphone Jack", NULL, "HPLOUT" }, - { "Headphone Jack", NULL, "HPLCOM" }, - { "Headphone Jack", NULL, "HPROUT" }, - { "Headphone Jack", NULL, "HPRCOM" }, - - /* ZV connected to Line1 */ - - { "LINE1L", NULL, "ZV" }, - { "LINE1R", NULL, "ZV" }, - - /* Line In connected to Line2 */ - - { "LINE2L", NULL, "Line In" }, - { "LINE2R", NULL, "Line In" }, - - /* Microphone connected to MIC3R and MIC_BIAS */ - - { "MIC3L", NULL, "Mic Jack" }, - - /* GSM connected to MONO_LOUT and MIC3L (in) */ - - { "GSM Out", NULL, "MONO_LOUT" }, - { "MIC3L", NULL, "GSM In" }, - - /* Speaker is connected to LINEOUT{LN,LP,RN,RP}, however we are - * not using the DAPM to power it up and down as there it makes - * a click when powering up. */ -}; - -/** - * simtec_hermes_init - initialise and add controls - * @codec; The codec instance to attach to. - * - * Attach our controls and configure the necessary codec - * mappings for our sound card instance. -*/ -static int simtec_hermes_init(struct snd_soc_pcm_runtime *rtd) -{ - struct snd_soc_codec *codec = rtd->codec; - struct snd_soc_dapm_context *dapm = &codec->dapm; - - snd_soc_dapm_new_controls(dapm, dapm_widgets, - ARRAY_SIZE(dapm_widgets)); - - snd_soc_dapm_add_routes(dapm, base_map, ARRAY_SIZE(base_map)); - - snd_soc_dapm_enable_pin(dapm, "Headphone Jack"); - snd_soc_dapm_enable_pin(dapm, "Line In"); - snd_soc_dapm_enable_pin(dapm, "Line Out"); - snd_soc_dapm_enable_pin(dapm, "Mic Jack"); - - simtec_audio_init(rtd); - snd_soc_dapm_sync(dapm); - - return 0; -} - -static struct snd_soc_dai_link simtec_dai_aic33 = { - .name = "tlv320aic33", - .stream_name = "TLV320AIC33", - .codec_name = "tlv320aic3x-codec.0-0x1a", - .cpu_dai_name = "s3c24xx-i2s", - .codec_dai_name = "tlv320aic3x-hifi", - .platform_name = "samsung-audio", - .init = simtec_hermes_init, -}; - -/* simtec audio machine driver */ -static struct snd_soc_card snd_soc_machine_simtec_aic33 = { - .name = "Simtec-Hermes", - .dai_link = &simtec_dai_aic33, - .num_links = 1, -}; - -static int __devinit simtec_audio_hermes_probe(struct platform_device *pd) -{ - dev_info(&pd->dev, "probing....\n"); - return simtec_audio_core_probe(pd, &snd_soc_machine_simtec_aic33); -} - -static struct platform_driver simtec_audio_hermes_platdrv = { - .driver = { - .owner = THIS_MODULE, - .name = "s3c24xx-simtec-hermes-snd", - .pm = simtec_audio_pm, - }, - .probe = simtec_audio_hermes_probe, - .remove = __devexit_p(simtec_audio_remove), -}; - -MODULE_ALIAS("platform:s3c24xx-simtec-hermes-snd"); - -static int __init simtec_hermes_modinit(void) -{ - return platform_driver_register(&simtec_audio_hermes_platdrv); -} - -static void __exit simtec_hermes_modexit(void) -{ - platform_driver_unregister(&simtec_audio_hermes_platdrv); -} - -module_init(simtec_hermes_modinit); -module_exit(simtec_hermes_modexit); - -MODULE_AUTHOR("Ben Dooks "); -MODULE_DESCRIPTION("ALSA SoC Simtec Audio support"); -MODULE_LICENSE("GPL"); diff --git a/sound/soc/s3c24xx/s3c24xx_simtec_tlv320aic23.c b/sound/soc/s3c24xx/s3c24xx_simtec_tlv320aic23.c deleted file mode 100644 index b45e0b70cc28..000000000000 --- a/sound/soc/s3c24xx/s3c24xx_simtec_tlv320aic23.c +++ /dev/null @@ -1,134 +0,0 @@ -/* sound/soc/s3c24xx/s3c24xx_simtec_tlv320aic23.c - * - * Copyright 2009 Simtec Electronics - * - * 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 -#include -#include - -#include - -#include "dma.h" -#include "s3c24xx-i2s.h" -#include "s3c24xx_simtec.h" - -#include "../codecs/tlv320aic23.h" - -/* supported machines: - * - * Machine Connections AMP - * ------- ----------- --- - * BAST MIC, HPOUT, LOUT, LIN TPA2001D1 (HPOUTL,R) (gain hardwired) - * VR1000 HPOUT, LIN None - * VR2000 LIN, LOUT, MIC, HP LM4871 (HPOUTL,R) - * DePicture LIN, LOUT, MIC, HP LM4871 (HPOUTL,R) - * Anubis LIN, LOUT, MIC, HP TPA2001D1 (HPOUTL,R) - */ - -static const struct snd_soc_dapm_widget dapm_widgets[] = { - SND_SOC_DAPM_HP("Headphone Jack", NULL), - SND_SOC_DAPM_LINE("Line In", NULL), - SND_SOC_DAPM_LINE("Line Out", NULL), - SND_SOC_DAPM_MIC("Mic Jack", NULL), -}; - -static const struct snd_soc_dapm_route base_map[] = { - { "Headphone Jack", NULL, "LHPOUT"}, - { "Headphone Jack", NULL, "RHPOUT"}, - - { "Line Out", NULL, "LOUT" }, - { "Line Out", NULL, "ROUT" }, - - { "LLINEIN", NULL, "Line In"}, - { "RLINEIN", NULL, "Line In"}, - - { "MICIN", NULL, "Mic Jack"}, -}; - -/** - * simtec_tlv320aic23_init - initialise and add controls - * @codec; The codec instance to attach to. - * - * Attach our controls and configure the necessary codec - * mappings for our sound card instance. -*/ -static int simtec_tlv320aic23_init(struct snd_soc_pcm_runtime *rtd) -{ - struct snd_soc_codec *codec = rtd->codec; - struct snd_soc_dapm_context *dapm = &codec->dapm; - - snd_soc_dapm_new_controls(dapm, dapm_widgets, - ARRAY_SIZE(dapm_widgets)); - - snd_soc_dapm_add_routes(dapm, base_map, ARRAY_SIZE(base_map)); - - snd_soc_dapm_enable_pin(dapm, "Headphone Jack"); - snd_soc_dapm_enable_pin(dapm, "Line In"); - snd_soc_dapm_enable_pin(dapm, "Line Out"); - snd_soc_dapm_enable_pin(dapm, "Mic Jack"); - - simtec_audio_init(rtd); - snd_soc_dapm_sync(dapm); - - return 0; -} - -static struct snd_soc_dai_link simtec_dai_aic23 = { - .name = "tlv320aic23", - .stream_name = "TLV320AIC23", - .codec_name = "tlv320aic3x-codec.0-0x1a", - .cpu_dai_name = "s3c24xx-i2s", - .codec_dai_name = "tlv320aic3x-hifi", - .platform_name = "samsung-audio", - .init = simtec_tlv320aic23_init, -}; - -/* simtec audio machine driver */ -static struct snd_soc_card snd_soc_machine_simtec_aic23 = { - .name = "Simtec", - .dai_link = &simtec_dai_aic23, - .num_links = 1, -}; - -static int __devinit simtec_audio_tlv320aic23_probe(struct platform_device *pd) -{ - return simtec_audio_core_probe(pd, &snd_soc_machine_simtec_aic23); -} - -static struct platform_driver simtec_audio_tlv320aic23_platdrv = { - .driver = { - .owner = THIS_MODULE, - .name = "s3c24xx-simtec-tlv320aic23", - .pm = simtec_audio_pm, - }, - .probe = simtec_audio_tlv320aic23_probe, - .remove = __devexit_p(simtec_audio_remove), -}; - -MODULE_ALIAS("platform:s3c24xx-simtec-tlv320aic23"); - -static int __init simtec_tlv320aic23_modinit(void) -{ - return platform_driver_register(&simtec_audio_tlv320aic23_platdrv); -} - -static void __exit simtec_tlv320aic23_modexit(void) -{ - platform_driver_unregister(&simtec_audio_tlv320aic23_platdrv); -} - -module_init(simtec_tlv320aic23_modinit); -module_exit(simtec_tlv320aic23_modexit); - -MODULE_AUTHOR("Ben Dooks "); -MODULE_DESCRIPTION("ALSA SoC Simtec Audio support"); -MODULE_LICENSE("GPL"); diff --git a/sound/soc/s3c24xx/s3c24xx_uda134x.c b/sound/soc/s3c24xx/s3c24xx_uda134x.c deleted file mode 100644 index cdc8ecbcb8ef..000000000000 --- a/sound/soc/s3c24xx/s3c24xx_uda134x.c +++ /dev/null @@ -1,367 +0,0 @@ -/* - * Modifications by Christian Pellegrin - * - * s3c24xx_uda134x.c -- S3C24XX_UDA134X ALSA SoC Audio board driver - * - * Copyright 2007 Dension Audio Systems Ltd. - * Author: Zoltan Devai - * - * 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 -#include -#include -#include -#include -#include - -#include - -#include "dma.h" -#include "s3c24xx-i2s.h" -#include "../codecs/uda134x.h" - - -/* #define ENFORCE_RATES 1 */ -/* - Unfortunately the S3C24XX in master mode has a limited capacity of - generating the clock for the codec. If you define this only rates - that are really available will be enforced. But be careful, most - user level application just want the usual sampling frequencies (8, - 11.025, 22.050, 44.1 kHz) and anyway resampling is a costly - operation for embedded systems. So if you aren't very lucky or your - hardware engineer wasn't very forward-looking it's better to leave - this undefined. If you do so an approximate value for the requested - sampling rate in the range -/+ 5% will be chosen. If this in not - possible an error will be returned. -*/ - -static struct clk *xtal; -static struct clk *pclk; -/* this is need because we don't have a place where to keep the - * pointers to the clocks in each substream. We get the clocks only - * when we are actually using them so we don't block stuff like - * frequency change or oscillator power-off */ -static int clk_users; -static DEFINE_MUTEX(clk_lock); - -static unsigned int rates[33 * 2]; -#ifdef ENFORCE_RATES -static struct snd_pcm_hw_constraint_list hw_constraints_rates = { - .count = ARRAY_SIZE(rates), - .list = rates, - .mask = 0, -}; -#endif - -static struct platform_device *s3c24xx_uda134x_snd_device; - -static int s3c24xx_uda134x_startup(struct snd_pcm_substream *substream) -{ - int ret = 0; -#ifdef ENFORCE_RATES - struct snd_pcm_runtime *runtime = substream->runtime; -#endif - - mutex_lock(&clk_lock); - pr_debug("%s %d\n", __func__, clk_users); - if (clk_users == 0) { - xtal = clk_get(&s3c24xx_uda134x_snd_device->dev, "xtal"); - if (!xtal) { - printk(KERN_ERR "%s cannot get xtal\n", __func__); - ret = -EBUSY; - } else { - pclk = clk_get(&s3c24xx_uda134x_snd_device->dev, - "pclk"); - if (!pclk) { - printk(KERN_ERR "%s cannot get pclk\n", - __func__); - clk_put(xtal); - ret = -EBUSY; - } - } - if (!ret) { - int i, j; - - for (i = 0; i < 2; i++) { - int fs = i ? 256 : 384; - - rates[i*33] = clk_get_rate(xtal) / fs; - for (j = 1; j < 33; j++) - rates[i*33 + j] = clk_get_rate(pclk) / - (j * fs); - } - } - } - clk_users += 1; - mutex_unlock(&clk_lock); - if (!ret) { -#ifdef ENFORCE_RATES - ret = snd_pcm_hw_constraint_list(runtime, 0, - SNDRV_PCM_HW_PARAM_RATE, - &hw_constraints_rates); - if (ret < 0) - printk(KERN_ERR "%s cannot set constraints\n", - __func__); -#endif - } - return ret; -} - -static void s3c24xx_uda134x_shutdown(struct snd_pcm_substream *substream) -{ - mutex_lock(&clk_lock); - pr_debug("%s %d\n", __func__, clk_users); - clk_users -= 1; - if (clk_users == 0) { - clk_put(xtal); - xtal = NULL; - clk_put(pclk); - pclk = NULL; - } - mutex_unlock(&clk_lock); -} - -static int s3c24xx_uda134x_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *codec_dai = rtd->codec_dai; - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; - unsigned int clk = 0; - int ret = 0; - int clk_source, fs_mode; - unsigned long rate = params_rate(params); - long err, cerr; - unsigned int div; - int i, bi; - - err = 999999; - bi = 0; - for (i = 0; i < 2*33; i++) { - cerr = rates[i] - rate; - if (cerr < 0) - cerr = -cerr; - if (cerr < err) { - err = cerr; - bi = i; - } - } - if (bi / 33 == 1) - fs_mode = S3C2410_IISMOD_256FS; - else - fs_mode = S3C2410_IISMOD_384FS; - if (bi % 33 == 0) { - clk_source = S3C24XX_CLKSRC_MPLL; - div = 1; - } else { - clk_source = S3C24XX_CLKSRC_PCLK; - div = bi % 33; - } - pr_debug("%s desired rate %lu, %d\n", __func__, rate, bi); - - clk = (fs_mode == S3C2410_IISMOD_384FS ? 384 : 256) * rate; - pr_debug("%s will use: %s %s %d sysclk %d err %ld\n", __func__, - fs_mode == S3C2410_IISMOD_384FS ? "384FS" : "256FS", - clk_source == S3C24XX_CLKSRC_MPLL ? "MPLLin" : "PCLK", - div, clk, err); - - if ((err * 100 / rate) > 5) { - printk(KERN_ERR "S3C24XX_UDA134X: effective frequency " - "too different from desired (%ld%%)\n", - err * 100 / rate); - return -EINVAL; - } - - ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | - SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); - if (ret < 0) - return ret; - - ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S | - SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); - if (ret < 0) - return ret; - - ret = snd_soc_dai_set_sysclk(cpu_dai, clk_source , clk, - SND_SOC_CLOCK_IN); - if (ret < 0) - return ret; - - ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C24XX_DIV_MCLK, fs_mode); - if (ret < 0) - return ret; - - ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C24XX_DIV_BCLK, - S3C2410_IISMOD_32FS); - if (ret < 0) - return ret; - - ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C24XX_DIV_PRESCALER, - S3C24XX_PRESCALE(div, div)); - if (ret < 0) - return ret; - - /* set the codec system clock for DAC and ADC */ - ret = snd_soc_dai_set_sysclk(codec_dai, 0, clk, - SND_SOC_CLOCK_OUT); - if (ret < 0) - return ret; - - return 0; -} - -static struct snd_soc_ops s3c24xx_uda134x_ops = { - .startup = s3c24xx_uda134x_startup, - .shutdown = s3c24xx_uda134x_shutdown, - .hw_params = s3c24xx_uda134x_hw_params, -}; - -static struct snd_soc_dai_link s3c24xx_uda134x_dai_link = { - .name = "UDA134X", - .stream_name = "UDA134X", - .codec_name = "uda134x-hifi", - .codec_dai_name = "uda134x-hifi", - .cpu_dai_name = "s3c24xx-i2s", - .ops = &s3c24xx_uda134x_ops, - .platform_name = "samsung-audio", -}; - -static struct snd_soc_card snd_soc_s3c24xx_uda134x = { - .name = "S3C24XX_UDA134X", - .dai_link = &s3c24xx_uda134x_dai_link, - .num_links = 1, -}; - -static struct s3c24xx_uda134x_platform_data *s3c24xx_uda134x_l3_pins; - -static void setdat(int v) -{ - gpio_set_value(s3c24xx_uda134x_l3_pins->l3_data, v > 0); -} - -static void setclk(int v) -{ - gpio_set_value(s3c24xx_uda134x_l3_pins->l3_clk, v > 0); -} - -static void setmode(int v) -{ - gpio_set_value(s3c24xx_uda134x_l3_pins->l3_mode, v > 0); -} - -/* FIXME - This must be codec platform data but in which board file ?? */ -static struct uda134x_platform_data s3c24xx_uda134x = { - .l3 = { - .setdat = setdat, - .setclk = setclk, - .setmode = setmode, - .data_hold = 1, - .data_setup = 1, - .clock_high = 1, - .mode_hold = 1, - .mode = 1, - .mode_setup = 1, - }, -}; - -static int s3c24xx_uda134x_setup_pin(int pin, char *fun) -{ - if (gpio_request(pin, "s3c24xx_uda134x") < 0) { - printk(KERN_ERR "S3C24XX_UDA134X SoC Audio: " - "l3 %s pin already in use", fun); - return -EBUSY; - } - gpio_direction_output(pin, 0); - return 0; -} - -static int s3c24xx_uda134x_probe(struct platform_device *pdev) -{ - int ret; - - printk(KERN_INFO "S3C24XX_UDA134X SoC Audio driver\n"); - - s3c24xx_uda134x_l3_pins = pdev->dev.platform_data; - if (s3c24xx_uda134x_l3_pins == NULL) { - printk(KERN_ERR "S3C24XX_UDA134X SoC Audio: " - "unable to find platform data\n"); - return -ENODEV; - } - s3c24xx_uda134x.power = s3c24xx_uda134x_l3_pins->power; - s3c24xx_uda134x.model = s3c24xx_uda134x_l3_pins->model; - - if (s3c24xx_uda134x_setup_pin(s3c24xx_uda134x_l3_pins->l3_data, - "data") < 0) - return -EBUSY; - if (s3c24xx_uda134x_setup_pin(s3c24xx_uda134x_l3_pins->l3_clk, - "clk") < 0) { - gpio_free(s3c24xx_uda134x_l3_pins->l3_data); - return -EBUSY; - } - if (s3c24xx_uda134x_setup_pin(s3c24xx_uda134x_l3_pins->l3_mode, - "mode") < 0) { - gpio_free(s3c24xx_uda134x_l3_pins->l3_data); - gpio_free(s3c24xx_uda134x_l3_pins->l3_clk); - return -EBUSY; - } - - s3c24xx_uda134x_snd_device = platform_device_alloc("soc-audio", -1); - if (!s3c24xx_uda134x_snd_device) { - printk(KERN_ERR "S3C24XX_UDA134X SoC Audio: " - "Unable to register\n"); - return -ENOMEM; - } - - platform_set_drvdata(s3c24xx_uda134x_snd_device, - &snd_soc_s3c24xx_uda134x); - ret = platform_device_add(s3c24xx_uda134x_snd_device); - if (ret) { - printk(KERN_ERR "S3C24XX_UDA134X SoC Audio: Unable to add\n"); - platform_device_put(s3c24xx_uda134x_snd_device); - } - - return ret; -} - -static int s3c24xx_uda134x_remove(struct platform_device *pdev) -{ - platform_device_unregister(s3c24xx_uda134x_snd_device); - gpio_free(s3c24xx_uda134x_l3_pins->l3_data); - gpio_free(s3c24xx_uda134x_l3_pins->l3_clk); - gpio_free(s3c24xx_uda134x_l3_pins->l3_mode); - return 0; -} - -static struct platform_driver s3c24xx_uda134x_driver = { - .probe = s3c24xx_uda134x_probe, - .remove = s3c24xx_uda134x_remove, - .driver = { - .name = "s3c24xx_uda134x", - .owner = THIS_MODULE, - }, -}; - -static int __init s3c24xx_uda134x_init(void) -{ - return platform_driver_register(&s3c24xx_uda134x_driver); -} - -static void __exit s3c24xx_uda134x_exit(void) -{ - platform_driver_unregister(&s3c24xx_uda134x_driver); -} - - -module_init(s3c24xx_uda134x_init); -module_exit(s3c24xx_uda134x_exit); - -MODULE_AUTHOR("Zoltan Devai, Christian Pellegrin "); -MODULE_DESCRIPTION("S3C24XX_UDA134X ALSA SoC audio driver"); -MODULE_LICENSE("GPL"); diff --git a/sound/soc/s3c24xx/smartq_wm8987.c b/sound/soc/s3c24xx/smartq_wm8987.c deleted file mode 100644 index bcb69820f1cc..000000000000 --- a/sound/soc/s3c24xx/smartq_wm8987.c +++ /dev/null @@ -1,288 +0,0 @@ -/* sound/soc/s3c24xx/smartq_wm8987.c - * - * Copyright 2010 Maurus Cuelenaere - * - * Based on smdk6410_wm8987.c - * Copyright 2007 Wolfson Microelectronics PLC. - linux@wolfsonmicro.com - * Graeme Gregory - graeme.gregory@wolfsonmicro.com - * - * 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. - * - */ - -#include -#include -#include - -#include -#include -#include -#include - -#include - -#include "dma.h" -#include "i2s.h" - -#include "../codecs/wm8750.h" - -/* - * WM8987 is register compatible with WM8750, so using that as base driver. - */ - -static struct snd_soc_card snd_soc_smartq; - -static int smartq_hifi_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; - struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; - unsigned int clk = 0; - int ret; - - switch (params_rate(params)) { - case 8000: - case 16000: - case 32000: - case 48000: - case 96000: - clk = 12288000; - break; - case 11025: - case 22050: - case 44100: - case 88200: - clk = 11289600; - break; - } - - /* set codec DAI configuration */ - ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | - SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBS_CFS); - if (ret < 0) - return ret; - - /* set cpu DAI configuration */ - ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S | - SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBS_CFS); - if (ret < 0) - return ret; - - /* Use PCLK for I2S signal generation */ - ret = snd_soc_dai_set_sysclk(cpu_dai, SAMSUNG_I2S_RCLKSRC_0, - 0, SND_SOC_CLOCK_IN); - if (ret < 0) - return ret; - - /* Gate the RCLK output on PAD */ - ret = snd_soc_dai_set_sysclk(cpu_dai, SAMSUNG_I2S_CDCLK, - 0, SND_SOC_CLOCK_IN); - if (ret < 0) - return ret; - - /* set the codec system clock for DAC and ADC */ - ret = snd_soc_dai_set_sysclk(codec_dai, WM8750_SYSCLK, clk, - SND_SOC_CLOCK_IN); - if (ret < 0) - return ret; - - return 0; -} - -/* - * SmartQ WM8987 HiFi DAI operations. - */ -static struct snd_soc_ops smartq_hifi_ops = { - .hw_params = smartq_hifi_hw_params, -}; - -static struct snd_soc_jack smartq_jack; - -static struct snd_soc_jack_pin smartq_jack_pins[] = { - /* Disable speaker when headphone is plugged in */ - { - .pin = "Internal Speaker", - .mask = SND_JACK_HEADPHONE, - }, -}; - -static struct snd_soc_jack_gpio smartq_jack_gpios[] = { - { - .gpio = S3C64XX_GPL(12), - .name = "headphone detect", - .report = SND_JACK_HEADPHONE, - .debounce_time = 200, - }, -}; - -static const struct snd_kcontrol_new wm8987_smartq_controls[] = { - SOC_DAPM_PIN_SWITCH("Internal Speaker"), - SOC_DAPM_PIN_SWITCH("Headphone Jack"), - SOC_DAPM_PIN_SWITCH("Internal Mic"), -}; - -static int smartq_speaker_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *k, - int event) -{ - gpio_set_value(S3C64XX_GPK(12), SND_SOC_DAPM_EVENT_OFF(event)); - - return 0; -} - -static const struct snd_soc_dapm_widget wm8987_dapm_widgets[] = { - SND_SOC_DAPM_SPK("Internal Speaker", smartq_speaker_event), - SND_SOC_DAPM_HP("Headphone Jack", NULL), - SND_SOC_DAPM_MIC("Internal Mic", NULL), -}; - -static const struct snd_soc_dapm_route audio_map[] = { - {"Headphone Jack", NULL, "LOUT2"}, - {"Headphone Jack", NULL, "ROUT2"}, - - {"Internal Speaker", NULL, "LOUT2"}, - {"Internal Speaker", NULL, "ROUT2"}, - - {"Mic Bias", NULL, "Internal Mic"}, - {"LINPUT2", NULL, "Mic Bias"}, -}; - -static int smartq_wm8987_init(struct snd_soc_codec *codec) -{ - struct snd_soc_dapm_context *dapm = &codec->dapm; - int err = 0; - - /* Add SmartQ specific widgets */ - snd_soc_dapm_new_controls(dapm, wm8987_dapm_widgets, - ARRAY_SIZE(wm8987_dapm_widgets)); - - /* add SmartQ specific controls */ - err = snd_soc_add_controls(codec, wm8987_smartq_controls, - ARRAY_SIZE(wm8987_smartq_controls)); - - if (err < 0) - return err; - - /* setup SmartQ specific audio path */ - snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); - - /* set endpoints to not connected */ - snd_soc_dapm_nc_pin(dapm, "LINPUT1"); - snd_soc_dapm_nc_pin(dapm, "RINPUT1"); - snd_soc_dapm_nc_pin(dapm, "OUT3"); - snd_soc_dapm_nc_pin(dapm, "ROUT1"); - - /* set endpoints to default off mode */ - snd_soc_dapm_enable_pin(dapm, "Internal Speaker"); - snd_soc_dapm_enable_pin(dapm, "Internal Mic"); - snd_soc_dapm_disable_pin(dapm, "Headphone Jack"); - - err = snd_soc_dapm_sync(dapm); - if (err) - return err; - - /* Headphone jack detection */ - err = snd_soc_jack_new(&snd_soc_smartq, "Headphone Jack", - SND_JACK_HEADPHONE, &smartq_jack); - if (err) - return err; - - err = snd_soc_jack_add_pins(&smartq_jack, ARRAY_SIZE(smartq_jack_pins), - smartq_jack_pins); - if (err) - return err; - - err = snd_soc_jack_add_gpios(&smartq_jack, - ARRAY_SIZE(smartq_jack_gpios), - smartq_jack_gpios); - - return err; -} - -static struct snd_soc_dai_link smartq_dai[] = { - { - .name = "wm8987", - .stream_name = "SmartQ Hi-Fi", - .cpu_dai_name = "samsung-i2s.0", - .codec_dai_name = "wm8750-hifi", - .platform_name = "samsung-audio", - .codec_name = "wm8750-codec.0-0x1a", - .init = smartq_wm8987_init, - .ops = &smartq_hifi_ops, - }, -}; - -static struct snd_soc_card snd_soc_smartq = { - .name = "SmartQ", - .dai_link = smartq_dai, - .num_links = ARRAY_SIZE(smartq_dai), -}; - -static struct platform_device *smartq_snd_device; - -static int __init smartq_init(void) -{ - int ret; - - if (!machine_is_smartq7() && !machine_is_smartq5()) { - pr_info("Only SmartQ is supported by this ASoC driver\n"); - return -ENODEV; - } - - smartq_snd_device = platform_device_alloc("soc-audio", -1); - if (!smartq_snd_device) - return -ENOMEM; - - platform_set_drvdata(smartq_snd_device, &snd_soc_smartq); - - ret = platform_device_add(smartq_snd_device); - if (ret) { - platform_device_put(smartq_snd_device); - return ret; - } - - /* Initialise GPIOs used by amplifiers */ - ret = gpio_request(S3C64XX_GPK(12), "amplifiers shutdown"); - if (ret) { - dev_err(&smartq_snd_device->dev, "Failed to register GPK12\n"); - goto err_unregister_device; - } - - /* Disable amplifiers */ - ret = gpio_direction_output(S3C64XX_GPK(12), 1); - if (ret) { - dev_err(&smartq_snd_device->dev, "Failed to configure GPK12\n"); - goto err_free_gpio_amp_shut; - } - - return 0; - -err_free_gpio_amp_shut: - gpio_free(S3C64XX_GPK(12)); -err_unregister_device: - platform_device_unregister(smartq_snd_device); - - return ret; -} - -static void __exit smartq_exit(void) -{ - snd_soc_jack_free_gpios(&smartq_jack, ARRAY_SIZE(smartq_jack_gpios), - smartq_jack_gpios); - - platform_device_unregister(smartq_snd_device); -} - -module_init(smartq_init); -module_exit(smartq_exit); - -/* Module information */ -MODULE_AUTHOR("Maurus Cuelenaere "); -MODULE_DESCRIPTION("ALSA SoC SmartQ WM8987"); -MODULE_LICENSE("GPL"); diff --git a/sound/soc/s3c24xx/smdk2443_wm9710.c b/sound/soc/s3c24xx/smdk2443_wm9710.c deleted file mode 100644 index 3be7e7e92d6e..000000000000 --- a/sound/soc/s3c24xx/smdk2443_wm9710.c +++ /dev/null @@ -1,73 +0,0 @@ -/* - * smdk2443_wm9710.c -- SoC audio for smdk2443 - * - * Copyright 2007 Wolfson Microelectronics PLC. - * Author: Graeme Gregory - * graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com - * - * 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. - * - */ - -#include -#include -#include -#include -#include - -#include "dma.h" -#include "ac97.h" - -static struct snd_soc_card smdk2443; - -static struct snd_soc_dai_link smdk2443_dai[] = { -{ - .name = "AC97", - .stream_name = "AC97 HiFi", - .cpu_dai_name = "samsung-ac97", - .codec_dai_name = "ac97-hifi", - .codec_name = "ac97-codec", - .platform_name = "samsung-audio", -}, -}; - -static struct snd_soc_card smdk2443 = { - .name = "SMDK2443", - .dai_link = smdk2443_dai, - .num_links = ARRAY_SIZE(smdk2443_dai), -}; - -static struct platform_device *smdk2443_snd_ac97_device; - -static int __init smdk2443_init(void) -{ - int ret; - - smdk2443_snd_ac97_device = platform_device_alloc("soc-audio", -1); - if (!smdk2443_snd_ac97_device) - return -ENOMEM; - - platform_set_drvdata(smdk2443_snd_ac97_device, &smdk2443); - ret = platform_device_add(smdk2443_snd_ac97_device); - - if (ret) - platform_device_put(smdk2443_snd_ac97_device); - - return ret; -} - -static void __exit smdk2443_exit(void) -{ - platform_device_unregister(smdk2443_snd_ac97_device); -} - -module_init(smdk2443_init); -module_exit(smdk2443_exit); - -/* Module information */ -MODULE_AUTHOR("Graeme Gregory, graeme.gregory@wolfsonmicro.com, www.wolfsonmicro.com"); -MODULE_DESCRIPTION("ALSA SoC WM9710 SMDK2443"); -MODULE_LICENSE("GPL"); diff --git a/sound/soc/s3c24xx/smdk_spdif.c b/sound/soc/s3c24xx/smdk_spdif.c deleted file mode 100644 index cd29da089c8f..000000000000 --- a/sound/soc/s3c24xx/smdk_spdif.c +++ /dev/null @@ -1,223 +0,0 @@ -/* - * smdk_spdif.c -- S/PDIF audio for SMDK - * - * Copyright 2010 Samsung Electronics Co. Ltd. - * - * 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. - * - */ - -#include -#include -#include - -#include - -#include - -#include "dma.h" -#include "spdif.h" - -/* Audio clock settings are belonged to board specific part. Every - * board can set audio source clock setting which is matched with H/W - * like this function-'set_audio_clock_heirachy'. - */ -static int set_audio_clock_heirachy(struct platform_device *pdev) -{ - struct clk *fout_epll, *mout_epll, *sclk_audio0, *sclk_spdif; - int ret; - - fout_epll = clk_get(NULL, "fout_epll"); - if (IS_ERR(fout_epll)) { - printk(KERN_WARNING "%s: Cannot find fout_epll.\n", - __func__); - return -EINVAL; - } - - mout_epll = clk_get(NULL, "mout_epll"); - if (IS_ERR(mout_epll)) { - printk(KERN_WARNING "%s: Cannot find mout_epll.\n", - __func__); - ret = -EINVAL; - goto out1; - } - - sclk_audio0 = clk_get(&pdev->dev, "sclk_audio"); - if (IS_ERR(sclk_audio0)) { - printk(KERN_WARNING "%s: Cannot find sclk_audio.\n", - __func__); - ret = -EINVAL; - goto out2; - } - - sclk_spdif = clk_get(NULL, "sclk_spdif"); - if (IS_ERR(sclk_spdif)) { - printk(KERN_WARNING "%s: Cannot find sclk_spdif.\n", - __func__); - ret = -EINVAL; - goto out3; - } - - /* Set audio clock heirachy for S/PDIF */ - clk_set_parent(mout_epll, fout_epll); - clk_set_parent(sclk_audio0, mout_epll); - clk_set_parent(sclk_spdif, sclk_audio0); - - clk_put(sclk_spdif); -out3: - clk_put(sclk_audio0); -out2: - clk_put(mout_epll); -out1: - clk_put(fout_epll); - - return ret; -} - -/* We should haved to set clock directly on this part because of clock - * scheme of Samsudng SoCs did not support to set rates from abstrct - * clock of it's heirachy. - */ -static int set_audio_clock_rate(unsigned long epll_rate, - unsigned long audio_rate) -{ - struct clk *fout_epll, *sclk_spdif; - - fout_epll = clk_get(NULL, "fout_epll"); - if (IS_ERR(fout_epll)) { - printk(KERN_ERR "%s: failed to get fout_epll\n", __func__); - return -ENOENT; - } - - clk_set_rate(fout_epll, epll_rate); - clk_put(fout_epll); - - sclk_spdif = clk_get(NULL, "sclk_spdif"); - if (IS_ERR(sclk_spdif)) { - printk(KERN_ERR "%s: failed to get sclk_spdif\n", __func__); - return -ENOENT; - } - - clk_set_rate(sclk_spdif, audio_rate); - clk_put(sclk_spdif); - - return 0; -} - -static int smdk_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; - unsigned long pll_out, rclk_rate; - int ret, ratio; - - switch (params_rate(params)) { - case 44100: - pll_out = 45158400; - break; - case 32000: - case 48000: - case 96000: - pll_out = 49152000; - break; - default: - return -EINVAL; - } - - /* Setting ratio to 512fs helps to use S/PDIF with HDMI without - * modify S/PDIF ASoC machine driver. - */ - ratio = 512; - rclk_rate = params_rate(params) * ratio; - - /* Set audio source clock rates */ - ret = set_audio_clock_rate(pll_out, rclk_rate); - if (ret < 0) - return ret; - - /* Set S/PDIF uses internal source clock */ - ret = snd_soc_dai_set_sysclk(cpu_dai, SND_SOC_SPDIF_INT_MCLK, - rclk_rate, SND_SOC_CLOCK_IN); - if (ret < 0) - return ret; - - return ret; -} - -static struct snd_soc_ops smdk_spdif_ops = { - .hw_params = smdk_hw_params, -}; - -static struct snd_soc_card smdk; - -static struct snd_soc_dai_link smdk_dai = { - .name = "S/PDIF", - .stream_name = "S/PDIF PCM Playback", - .platform_name = "samsung-audio", - .cpu_dai_name = "samsung-spdif", - .codec_dai_name = "dit-hifi", - .codec_name = "spdif-dit", - .ops = &smdk_spdif_ops, -}; - -static struct snd_soc_card smdk = { - .name = "SMDK-S/PDIF", - .dai_link = &smdk_dai, - .num_links = 1, -}; - -static struct platform_device *smdk_snd_spdif_dit_device; -static struct platform_device *smdk_snd_spdif_device; - -static int __init smdk_init(void) -{ - int ret; - - smdk_snd_spdif_dit_device = platform_device_alloc("spdif-dit", -1); - if (!smdk_snd_spdif_dit_device) - return -ENOMEM; - - ret = platform_device_add(smdk_snd_spdif_dit_device); - if (ret) - goto err2; - - smdk_snd_spdif_device = platform_device_alloc("soc-audio", -1); - if (!smdk_snd_spdif_device) { - ret = -ENOMEM; - goto err2; - } - - platform_set_drvdata(smdk_snd_spdif_device, &smdk); - - ret = platform_device_add(smdk_snd_spdif_device); - if (ret) - goto err1; - - /* Set audio clock heirachy manually */ - ret = set_audio_clock_heirachy(smdk_snd_spdif_device); - if (ret) - goto err1; - - return 0; -err1: - platform_device_put(smdk_snd_spdif_device); -err2: - platform_device_put(smdk_snd_spdif_dit_device); - return ret; -} - -static void __exit smdk_exit(void) -{ - platform_device_unregister(smdk_snd_spdif_device); -} - -module_init(smdk_init); -module_exit(smdk_exit); - -MODULE_AUTHOR("Seungwhan Youn, "); -MODULE_DESCRIPTION("ALSA SoC SMDK+S/PDIF"); -MODULE_LICENSE("GPL"); diff --git a/sound/soc/s3c24xx/smdk_wm8580.c b/sound/soc/s3c24xx/smdk_wm8580.c deleted file mode 100644 index 0ae3d57d79e6..000000000000 --- a/sound/soc/s3c24xx/smdk_wm8580.c +++ /dev/null @@ -1,285 +0,0 @@ -/* - * smdk_wm8580.c - * - * Copyright (c) 2009 Samsung Electronics Co. Ltd - * Author: Jaswinder Singh - * - * 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. - */ - -#include -#include -#include -#include -#include -#include - -#include - -#include "../codecs/wm8580.h" -#include "dma.h" -#include "i2s.h" - -/* - * Default CFG switch settings to use this driver: - * - * SMDK6410: Set CFG1 1-3 Off, CFG2 1-4 On - */ - -/* SMDK has a 12MHZ crystal attached to WM8580 */ -#define SMDK_WM8580_FREQ 12000000 - -static int smdk_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *cpu_dai = rtd->cpu_dai; - struct snd_soc_dai *codec_dai = rtd->codec_dai; - unsigned int pll_out; - int bfs, rfs, ret; - - switch (params_format(params)) { - case SNDRV_PCM_FORMAT_U8: - case SNDRV_PCM_FORMAT_S8: - bfs = 16; - break; - case SNDRV_PCM_FORMAT_U16_LE: - case SNDRV_PCM_FORMAT_S16_LE: - bfs = 32; - break; - default: - return -EINVAL; - } - - /* The Fvco for WM8580 PLLs must fall within [90,100]MHz. - * This criterion can't be met if we request PLL output - * as {8000x256, 64000x256, 11025x256}Hz. - * As a wayout, we rather change rfs to a minimum value that - * results in (params_rate(params) * rfs), and itself, acceptable - * to both - the CODEC and the CPU. - */ - switch (params_rate(params)) { - case 16000: - case 22050: - case 32000: - case 44100: - case 48000: - case 88200: - case 96000: - rfs = 256; - break; - case 64000: - rfs = 384; - break; - case 8000: - case 11025: - rfs = 512; - break; - default: - return -EINVAL; - } - pll_out = params_rate(params) * rfs; - - /* Set the Codec DAI configuration */ - ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S - | SND_SOC_DAIFMT_NB_NF - | SND_SOC_DAIFMT_CBM_CFM); - if (ret < 0) - return ret; - - /* Set the AP DAI configuration */ - ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S - | SND_SOC_DAIFMT_NB_NF - | SND_SOC_DAIFMT_CBM_CFM); - if (ret < 0) - return ret; - - /* Set WM8580 to drive MCLK from its PLLA */ - ret = snd_soc_dai_set_clkdiv(codec_dai, WM8580_MCLK, - WM8580_CLKSRC_PLLA); - if (ret < 0) - return ret; - - ret = snd_soc_dai_set_pll(codec_dai, WM8580_PLLA, 0, - SMDK_WM8580_FREQ, pll_out); - if (ret < 0) - return ret; - - ret = snd_soc_dai_set_sysclk(codec_dai, WM8580_CLKSRC_PLLA, - pll_out, SND_SOC_CLOCK_IN); - if (ret < 0) - return ret; - - return 0; -} - -/* - * SMDK WM8580 DAI operations. - */ -static struct snd_soc_ops smdk_ops = { - .hw_params = smdk_hw_params, -}; - -/* SMDK Playback widgets */ -static const struct snd_soc_dapm_widget wm8580_dapm_widgets_pbk[] = { - SND_SOC_DAPM_HP("Front", NULL), - SND_SOC_DAPM_HP("Center+Sub", NULL), - SND_SOC_DAPM_HP("Rear", NULL), -}; - -/* SMDK Capture widgets */ -static const struct snd_soc_dapm_widget wm8580_dapm_widgets_cpt[] = { - SND_SOC_DAPM_MIC("MicIn", NULL), - SND_SOC_DAPM_LINE("LineIn", NULL), -}; - -/* SMDK-PAIFTX connections */ -static const struct snd_soc_dapm_route audio_map_tx[] = { - /* MicIn feeds AINL */ - {"AINL", NULL, "MicIn"}, - - /* LineIn feeds AINL/R */ - {"AINL", NULL, "LineIn"}, - {"AINR", NULL, "LineIn"}, -}; - -/* SMDK-PAIFRX connections */ -static const struct snd_soc_dapm_route audio_map_rx[] = { - /* Front Left/Right are fed VOUT1L/R */ - {"Front", NULL, "VOUT1L"}, - {"Front", NULL, "VOUT1R"}, - - /* Center/Sub are fed VOUT2L/R */ - {"Center+Sub", NULL, "VOUT2L"}, - {"Center+Sub", NULL, "VOUT2R"}, - - /* Rear Left/Right are fed VOUT3L/R */ - {"Rear", NULL, "VOUT3L"}, - {"Rear", NULL, "VOUT3R"}, -}; - -static int smdk_wm8580_init_paiftx(struct snd_soc_pcm_runtime *rtd) -{ - struct snd_soc_codec *codec = rtd->codec; - struct snd_soc_dapm_context *dapm = &codec->dapm; - - /* Add smdk specific Capture widgets */ - snd_soc_dapm_new_controls(dapm, wm8580_dapm_widgets_cpt, - ARRAY_SIZE(wm8580_dapm_widgets_cpt)); - - /* Set up PAIFTX audio path */ - snd_soc_dapm_add_routes(dapm, audio_map_tx, ARRAY_SIZE(audio_map_tx)); - - /* Enabling the microphone requires the fitting of a 0R - * resistor to connect the line from the microphone jack. - */ - snd_soc_dapm_disable_pin(dapm, "MicIn"); - - /* signal a DAPM event */ - snd_soc_dapm_sync(dapm); - - return 0; -} - -static int smdk_wm8580_init_paifrx(struct snd_soc_pcm_runtime *rtd) -{ - struct snd_soc_codec *codec = rtd->codec; - struct snd_soc_dapm_context *dapm = &codec->dapm; - - /* Add smdk specific Playback widgets */ - snd_soc_dapm_new_controls(dapm, wm8580_dapm_widgets_pbk, - ARRAY_SIZE(wm8580_dapm_widgets_pbk)); - - /* Set up PAIFRX audio path */ - snd_soc_dapm_add_routes(dapm, audio_map_rx, ARRAY_SIZE(audio_map_rx)); - - /* signal a DAPM event */ - snd_soc_dapm_sync(dapm); - - return 0; -} - -enum { - PRI_PLAYBACK = 0, - PRI_CAPTURE, - SEC_PLAYBACK, -}; - -static struct snd_soc_dai_link smdk_dai[] = { - [PRI_PLAYBACK] = { /* Primary Playback i/f */ - .name = "WM8580 PAIF RX", - .stream_name = "Playback", - .cpu_dai_name = "samsung-i2s.2", - .codec_dai_name = "wm8580-hifi-playback", - .platform_name = "samsung-audio", - .codec_name = "wm8580-codec.0-001b", - .init = smdk_wm8580_init_paifrx, - .ops = &smdk_ops, - }, - [PRI_CAPTURE] = { /* Primary Capture i/f */ - .name = "WM8580 PAIF TX", - .stream_name = "Capture", - .cpu_dai_name = "samsung-i2s.2", - .codec_dai_name = "wm8580-hifi-capture", - .platform_name = "samsung-audio", - .codec_name = "wm8580-codec.0-001b", - .init = smdk_wm8580_init_paiftx, - .ops = &smdk_ops, - }, - [SEC_PLAYBACK] = { /* Sec_Fifo Playback i/f */ - .name = "Sec_FIFO TX", - .stream_name = "Playback", - .cpu_dai_name = "samsung-i2s.x", - .codec_dai_name = "wm8580-hifi-playback", - .platform_name = "samsung-audio", - .codec_name = "wm8580-codec.0-001b", - .init = smdk_wm8580_init_paifrx, - .ops = &smdk_ops, - }, -}; - -static struct snd_soc_card smdk = { - .name = "SMDK-I2S", - .dai_link = smdk_dai, - .num_links = 2, -}; - -static struct platform_device *smdk_snd_device; - -static int __init smdk_audio_init(void) -{ - int ret; - char *str; - - if (machine_is_smdkc100()) { - smdk.num_links = 3; - /* S5PC100 has I2S0 as v5 */ - str = (char *)smdk_dai[PRI_PLAYBACK].cpu_dai_name; - str[strlen(str) - 1] = '0'; - str = (char *)smdk_dai[PRI_CAPTURE].cpu_dai_name; - str[strlen(str) - 1] = '0'; - /* Secondary is at offset SAMSUNG_I2S_SECOFF from Primary */ - str = (char *)smdk_dai[SEC_PLAYBACK].cpu_dai_name; - str[strlen(str) - 1] = '0' + SAMSUNG_I2S_SECOFF; - } - - smdk_snd_device = platform_device_alloc("soc-audio", -1); - if (!smdk_snd_device) - return -ENOMEM; - - platform_set_drvdata(smdk_snd_device, &smdk); - ret = platform_device_add(smdk_snd_device); - - if (ret) - platform_device_put(smdk_snd_device); - - return ret; -} -module_init(smdk_audio_init); - -MODULE_AUTHOR("Jaswinder Singh, jassi.brar@samsung.com"); -MODULE_DESCRIPTION("ALSA SoC SMDK WM8580"); -MODULE_LICENSE("GPL"); diff --git a/sound/soc/s3c24xx/smdk_wm9713.c b/sound/soc/s3c24xx/smdk_wm9713.c deleted file mode 100644 index 7ce243086e7d..000000000000 --- a/sound/soc/s3c24xx/smdk_wm9713.c +++ /dev/null @@ -1,107 +0,0 @@ -/* - * smdk_wm9713.c -- SoC audio for SMDK - * - * Copyright 2010 Samsung Electronics Co. Ltd. - * Author: Jaswinder Singh Brar - * - * 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. - * - */ - -#include -#include -#include - -#include "dma.h" -#include "ac97.h" - -static struct snd_soc_card smdk; - -/* - * Default CFG switch settings to use this driver: - * - * SMDK6410: Set CFG1 1-3 On, CFG2 1-4 Off - * SMDKC100: Set CFG6 1-3 On, CFG7 1 On - * SMDKC110: Set CFGB10 1-2 Off, CFGB12 1-3 On - * SMDKV210: Set CFGB10 1-2 Off, CFGB12 1-3 On - */ - -/* - Playback (HeadPhone):- - $ amixer sset 'Headphone' unmute - $ amixer sset 'Right Headphone Out Mux' 'Headphone' - $ amixer sset 'Left Headphone Out Mux' 'Headphone' - $ amixer sset 'Right HP Mixer PCM' unmute - $ amixer sset 'Left HP Mixer PCM' unmute - - Capture (LineIn):- - $ amixer sset 'Right Capture Source' 'Line' - $ amixer sset 'Left Capture Source' 'Line' -*/ - -static struct snd_soc_dai_link smdk_dai = { - .name = "AC97", - .stream_name = "AC97 PCM", - .platform_name = "samsung-audio", - .cpu_dai_name = "samsung-ac97", - .codec_dai_name = "wm9713-hifi", - .codec_name = "wm9713-codec", -}; - -static struct snd_soc_card smdk = { - .name = "SMDK WM9713", - .dai_link = &smdk_dai, - .num_links = 1, -}; - -static struct platform_device *smdk_snd_wm9713_device; -static struct platform_device *smdk_snd_ac97_device; - -static int __init smdk_init(void) -{ - int ret; - - smdk_snd_wm9713_device = platform_device_alloc("wm9713-codec", -1); - if (!smdk_snd_wm9713_device) - return -ENOMEM; - - ret = platform_device_add(smdk_snd_wm9713_device); - if (ret) - goto err; - - smdk_snd_ac97_device = platform_device_alloc("soc-audio", -1); - if (!smdk_snd_ac97_device) { - ret = -ENOMEM; - goto err; - } - - platform_set_drvdata(smdk_snd_ac97_device, &smdk); - - ret = platform_device_add(smdk_snd_ac97_device); - if (ret) { - platform_device_put(smdk_snd_ac97_device); - goto err; - } - - return 0; -err: - platform_device_put(smdk_snd_wm9713_device); - return ret; -} - -static void __exit smdk_exit(void) -{ - platform_device_unregister(smdk_snd_ac97_device); - platform_device_unregister(smdk_snd_wm9713_device); -} - -module_init(smdk_init); -module_exit(smdk_exit); - -/* Module information */ -MODULE_AUTHOR("Jaswinder Singh Brar, jassi.brar@samsung.com"); -MODULE_DESCRIPTION("ALSA SoC SMDK+WM9713"); -MODULE_LICENSE("GPL"); diff --git a/sound/soc/s3c24xx/spdif.c b/sound/soc/s3c24xx/spdif.c deleted file mode 100644 index dc85df32ebf2..000000000000 --- a/sound/soc/s3c24xx/spdif.c +++ /dev/null @@ -1,501 +0,0 @@ -/* sound/soc/s3c24xx/spdif.c - * - * ALSA SoC Audio Layer - Samsung S/PDIF Controller driver - * - * Copyright (c) 2010 Samsung Electronics Co. Ltd - * http://www.samsung.com/ - * - * 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 -#include - -#include -#include - -#include "dma.h" -#include "spdif.h" - -/* Registers */ -#define CLKCON 0x00 -#define CON 0x04 -#define BSTAS 0x08 -#define CSTAS 0x0C -#define DATA_OUTBUF 0x10 -#define DCNT 0x14 -#define BSTAS_S 0x18 -#define DCNT_S 0x1C - -#define CLKCTL_MASK 0x7 -#define CLKCTL_MCLK_EXT (0x1 << 2) -#define CLKCTL_PWR_ON (0x1 << 0) - -#define CON_MASK 0x3ffffff -#define CON_FIFO_TH_SHIFT 19 -#define CON_FIFO_TH_MASK (0x7 << 19) -#define CON_USERDATA_23RDBIT (0x1 << 12) - -#define CON_SW_RESET (0x1 << 5) - -#define CON_MCLKDIV_MASK (0x3 << 3) -#define CON_MCLKDIV_256FS (0x0 << 3) -#define CON_MCLKDIV_384FS (0x1 << 3) -#define CON_MCLKDIV_512FS (0x2 << 3) - -#define CON_PCM_MASK (0x3 << 1) -#define CON_PCM_16BIT (0x0 << 1) -#define CON_PCM_20BIT (0x1 << 1) -#define CON_PCM_24BIT (0x2 << 1) - -#define CON_PCM_DATA (0x1 << 0) - -#define CSTAS_MASK 0x3fffffff -#define CSTAS_SAMP_FREQ_MASK (0xF << 24) -#define CSTAS_SAMP_FREQ_44 (0x0 << 24) -#define CSTAS_SAMP_FREQ_48 (0x2 << 24) -#define CSTAS_SAMP_FREQ_32 (0x3 << 24) -#define CSTAS_SAMP_FREQ_96 (0xA << 24) - -#define CSTAS_CATEGORY_MASK (0xFF << 8) -#define CSTAS_CATEGORY_CODE_CDP (0x01 << 8) - -#define CSTAS_NO_COPYRIGHT (0x1 << 2) - -/** - * struct samsung_spdif_info - Samsung S/PDIF Controller information - * @lock: Spin lock for S/PDIF. - * @dev: The parent device passed to use from the probe. - * @regs: The pointer to the device register block. - * @clk_rate: Current clock rate for calcurate ratio. - * @pclk: The peri-clock pointer for spdif master operation. - * @sclk: The source clock pointer for making sync signals. - * @save_clkcon: Backup clkcon reg. in suspend. - * @save_con: Backup con reg. in suspend. - * @save_cstas: Backup cstas reg. in suspend. - * @dma_playback: DMA information for playback channel. - */ -struct samsung_spdif_info { - spinlock_t lock; - struct device *dev; - void __iomem *regs; - unsigned long clk_rate; - struct clk *pclk; - struct clk *sclk; - u32 saved_clkcon; - u32 saved_con; - u32 saved_cstas; - struct s3c_dma_params *dma_playback; -}; - -static struct s3c2410_dma_client spdif_dma_client_out = { - .name = "S/PDIF Stereo out", -}; - -static struct s3c_dma_params spdif_stereo_out; -static struct samsung_spdif_info spdif_info; - -static inline struct samsung_spdif_info *to_info(struct snd_soc_dai *cpu_dai) -{ - return snd_soc_dai_get_drvdata(cpu_dai); -} - -static void spdif_snd_txctrl(struct samsung_spdif_info *spdif, int on) -{ - void __iomem *regs = spdif->regs; - u32 clkcon; - - dev_dbg(spdif->dev, "Entered %s\n", __func__); - - clkcon = readl(regs + CLKCON) & CLKCTL_MASK; - if (on) - writel(clkcon | CLKCTL_PWR_ON, regs + CLKCON); - else - writel(clkcon & ~CLKCTL_PWR_ON, regs + CLKCON); -} - -static int spdif_set_sysclk(struct snd_soc_dai *cpu_dai, - int clk_id, unsigned int freq, int dir) -{ - struct samsung_spdif_info *spdif = to_info(cpu_dai); - u32 clkcon; - - dev_dbg(spdif->dev, "Entered %s\n", __func__); - - clkcon = readl(spdif->regs + CLKCON); - - if (clk_id == SND_SOC_SPDIF_INT_MCLK) - clkcon &= ~CLKCTL_MCLK_EXT; - else - clkcon |= CLKCTL_MCLK_EXT; - - writel(clkcon, spdif->regs + CLKCON); - - spdif->clk_rate = freq; - - return 0; -} - -static int spdif_trigger(struct snd_pcm_substream *substream, int cmd, - struct snd_soc_dai *dai) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct samsung_spdif_info *spdif = to_info(rtd->cpu_dai); - unsigned long flags; - - dev_dbg(spdif->dev, "Entered %s\n", __func__); - - switch (cmd) { - case SNDRV_PCM_TRIGGER_START: - case SNDRV_PCM_TRIGGER_RESUME: - case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - spin_lock_irqsave(&spdif->lock, flags); - spdif_snd_txctrl(spdif, 1); - spin_unlock_irqrestore(&spdif->lock, flags); - break; - case SNDRV_PCM_TRIGGER_STOP: - case SNDRV_PCM_TRIGGER_SUSPEND: - case SNDRV_PCM_TRIGGER_PAUSE_PUSH: - spin_lock_irqsave(&spdif->lock, flags); - spdif_snd_txctrl(spdif, 0); - spin_unlock_irqrestore(&spdif->lock, flags); - break; - default: - return -EINVAL; - } - - return 0; -} - -static int spdif_sysclk_ratios[] = { - 512, 384, 256, -}; - -static int spdif_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params, - struct snd_soc_dai *socdai) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct samsung_spdif_info *spdif = to_info(rtd->cpu_dai); - void __iomem *regs = spdif->regs; - struct s3c_dma_params *dma_data; - u32 con, clkcon, cstas; - unsigned long flags; - int i, ratio; - - dev_dbg(spdif->dev, "Entered %s\n", __func__); - - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - dma_data = spdif->dma_playback; - else { - dev_err(spdif->dev, "Capture is not supported\n"); - return -EINVAL; - } - - snd_soc_dai_set_dma_data(rtd->cpu_dai, substream, dma_data); - - spin_lock_irqsave(&spdif->lock, flags); - - con = readl(regs + CON) & CON_MASK; - cstas = readl(regs + CSTAS) & CSTAS_MASK; - clkcon = readl(regs + CLKCON) & CLKCTL_MASK; - - con &= ~CON_FIFO_TH_MASK; - con |= (0x7 << CON_FIFO_TH_SHIFT); - con |= CON_USERDATA_23RDBIT; - con |= CON_PCM_DATA; - - con &= ~CON_PCM_MASK; - switch (params_format(params)) { - case SNDRV_PCM_FORMAT_S16_LE: - con |= CON_PCM_16BIT; - break; - default: - dev_err(spdif->dev, "Unsupported data size.\n"); - goto err; - } - - ratio = spdif->clk_rate / params_rate(params); - for (i = 0; i < ARRAY_SIZE(spdif_sysclk_ratios); i++) - if (ratio == spdif_sysclk_ratios[i]) - break; - if (i == ARRAY_SIZE(spdif_sysclk_ratios)) { - dev_err(spdif->dev, "Invalid clock ratio %ld/%d\n", - spdif->clk_rate, params_rate(params)); - goto err; - } - - con &= ~CON_MCLKDIV_MASK; - switch (ratio) { - case 256: - con |= CON_MCLKDIV_256FS; - break; - case 384: - con |= CON_MCLKDIV_384FS; - break; - case 512: - con |= CON_MCLKDIV_512FS; - break; - } - - cstas &= ~CSTAS_SAMP_FREQ_MASK; - switch (params_rate(params)) { - case 44100: - cstas |= CSTAS_SAMP_FREQ_44; - break; - case 48000: - cstas |= CSTAS_SAMP_FREQ_48; - break; - case 32000: - cstas |= CSTAS_SAMP_FREQ_32; - break; - case 96000: - cstas |= CSTAS_SAMP_FREQ_96; - break; - default: - dev_err(spdif->dev, "Invalid sampling rate %d\n", - params_rate(params)); - goto err; - } - - cstas &= ~CSTAS_CATEGORY_MASK; - cstas |= CSTAS_CATEGORY_CODE_CDP; - cstas |= CSTAS_NO_COPYRIGHT; - - writel(con, regs + CON); - writel(cstas, regs + CSTAS); - writel(clkcon, regs + CLKCON); - - spin_unlock_irqrestore(&spdif->lock, flags); - - return 0; -err: - spin_unlock_irqrestore(&spdif->lock, flags); - return -EINVAL; -} - -static void spdif_shutdown(struct snd_pcm_substream *substream, - struct snd_soc_dai *dai) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct samsung_spdif_info *spdif = to_info(rtd->cpu_dai); - void __iomem *regs = spdif->regs; - u32 con, clkcon; - - dev_dbg(spdif->dev, "Entered %s\n", __func__); - - con = readl(regs + CON) & CON_MASK; - clkcon = readl(regs + CLKCON) & CLKCTL_MASK; - - writel(con | CON_SW_RESET, regs + CON); - cpu_relax(); - - writel(clkcon & ~CLKCTL_PWR_ON, regs + CLKCON); -} - -#ifdef CONFIG_PM -static int spdif_suspend(struct snd_soc_dai *cpu_dai) -{ - struct samsung_spdif_info *spdif = to_info(cpu_dai); - u32 con = spdif->saved_con; - - dev_dbg(spdif->dev, "Entered %s\n", __func__); - - spdif->saved_clkcon = readl(spdif->regs + CLKCON) & CLKCTL_MASK; - spdif->saved_con = readl(spdif->regs + CON) & CON_MASK; - spdif->saved_cstas = readl(spdif->regs + CSTAS) & CSTAS_MASK; - - writel(con | CON_SW_RESET, spdif->regs + CON); - cpu_relax(); - - return 0; -} - -static int spdif_resume(struct snd_soc_dai *cpu_dai) -{ - struct samsung_spdif_info *spdif = to_info(cpu_dai); - - dev_dbg(spdif->dev, "Entered %s\n", __func__); - - writel(spdif->saved_clkcon, spdif->regs + CLKCON); - writel(spdif->saved_con, spdif->regs + CON); - writel(spdif->saved_cstas, spdif->regs + CSTAS); - - return 0; -} -#else -#define spdif_suspend NULL -#define spdif_resume NULL -#endif - -static struct snd_soc_dai_ops spdif_dai_ops = { - .set_sysclk = spdif_set_sysclk, - .trigger = spdif_trigger, - .hw_params = spdif_hw_params, - .shutdown = spdif_shutdown, -}; - -struct snd_soc_dai_driver samsung_spdif_dai = { - .name = "samsung-spdif", - .playback = { - .stream_name = "S/PDIF Playback", - .channels_min = 2, - .channels_max = 2, - .rates = (SNDRV_PCM_RATE_32000 | - SNDRV_PCM_RATE_44100 | - SNDRV_PCM_RATE_48000 | - SNDRV_PCM_RATE_96000), - .formats = SNDRV_PCM_FMTBIT_S16_LE, }, - .ops = &spdif_dai_ops, - .suspend = spdif_suspend, - .resume = spdif_resume, -}; - -static __devinit int spdif_probe(struct platform_device *pdev) -{ - struct s3c_audio_pdata *spdif_pdata; - struct resource *mem_res, *dma_res; - struct samsung_spdif_info *spdif; - int ret; - - spdif_pdata = pdev->dev.platform_data; - - dev_dbg(&pdev->dev, "Entered %s\n", __func__); - - dma_res = platform_get_resource(pdev, IORESOURCE_DMA, 0); - if (!dma_res) { - dev_err(&pdev->dev, "Unable to get dma resource.\n"); - return -ENXIO; - } - - mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!mem_res) { - dev_err(&pdev->dev, "Unable to get register resource.\n"); - return -ENXIO; - } - - if (spdif_pdata && spdif_pdata->cfg_gpio - && spdif_pdata->cfg_gpio(pdev)) { - dev_err(&pdev->dev, "Unable to configure GPIO pins\n"); - return -EINVAL; - } - - spdif = &spdif_info; - spdif->dev = &pdev->dev; - - spin_lock_init(&spdif->lock); - - spdif->pclk = clk_get(&pdev->dev, "spdif"); - if (IS_ERR(spdif->pclk)) { - dev_err(&pdev->dev, "failed to get peri-clock\n"); - ret = -ENOENT; - goto err0; - } - clk_enable(spdif->pclk); - - spdif->sclk = clk_get(&pdev->dev, "sclk_spdif"); - if (IS_ERR(spdif->sclk)) { - dev_err(&pdev->dev, "failed to get internal source clock\n"); - ret = -ENOENT; - goto err1; - } - clk_enable(spdif->sclk); - - /* Request S/PDIF Register's memory region */ - if (!request_mem_region(mem_res->start, - resource_size(mem_res), "samsung-spdif")) { - dev_err(&pdev->dev, "Unable to request register region\n"); - ret = -EBUSY; - goto err2; - } - - spdif->regs = ioremap(mem_res->start, 0x100); - if (spdif->regs == NULL) { - dev_err(&pdev->dev, "Cannot ioremap registers\n"); - ret = -ENXIO; - goto err3; - } - - dev_set_drvdata(&pdev->dev, spdif); - - ret = snd_soc_register_dai(&pdev->dev, &samsung_spdif_dai); - if (ret != 0) { - dev_err(&pdev->dev, "fail to register dai\n"); - goto err4; - } - - spdif_stereo_out.dma_size = 2; - spdif_stereo_out.client = &spdif_dma_client_out; - spdif_stereo_out.dma_addr = mem_res->start + DATA_OUTBUF; - spdif_stereo_out.channel = dma_res->start; - - spdif->dma_playback = &spdif_stereo_out; - - return 0; - -err4: - iounmap(spdif->regs); -err3: - release_mem_region(mem_res->start, resource_size(mem_res)); -err2: - clk_disable(spdif->sclk); - clk_put(spdif->sclk); -err1: - clk_disable(spdif->pclk); - clk_put(spdif->pclk); -err0: - return ret; -} - -static __devexit int spdif_remove(struct platform_device *pdev) -{ - struct samsung_spdif_info *spdif = &spdif_info; - struct resource *mem_res; - - snd_soc_unregister_dai(&pdev->dev); - - iounmap(spdif->regs); - - mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (mem_res) - release_mem_region(mem_res->start, resource_size(mem_res)); - - clk_disable(spdif->sclk); - clk_put(spdif->sclk); - clk_disable(spdif->pclk); - clk_put(spdif->pclk); - - return 0; -} - -static struct platform_driver samsung_spdif_driver = { - .probe = spdif_probe, - .remove = spdif_remove, - .driver = { - .name = "samsung-spdif", - .owner = THIS_MODULE, - }, -}; - -static int __init spdif_init(void) -{ - return platform_driver_register(&samsung_spdif_driver); -} -module_init(spdif_init); - -static void __exit spdif_exit(void) -{ - platform_driver_unregister(&samsung_spdif_driver); -} -module_exit(spdif_exit); - -MODULE_AUTHOR("Seungwhan Youn, "); -MODULE_DESCRIPTION("Samsung S/PDIF Controller Driver"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:samsung-spdif"); diff --git a/sound/soc/s3c24xx/spdif.h b/sound/soc/s3c24xx/spdif.h deleted file mode 100644 index 3ed55592710f..000000000000 --- a/sound/soc/s3c24xx/spdif.h +++ /dev/null @@ -1,19 +0,0 @@ -/* sound/soc/s3c24xx/spdif.h - * - * ALSA SoC Audio Layer - Samsung S/PDIF Controller driver - * - * Copyright (c) 2010 Samsung Electronics Co. Ltd - * http://www.samsung.com/ - * - * 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. - */ - -#ifndef __SND_SOC_SAMSUNG_SPDIF_H -#define __SND_SOC_SAMSUNG_SPDIF_H __FILE__ - -#define SND_SOC_SPDIF_INT_MCLK 0 -#define SND_SOC_SPDIF_EXT_MCLK 1 - -#endif /* __SND_SOC_SAMSUNG_SPDIF_H */ diff --git a/sound/soc/samsung/Kconfig b/sound/soc/samsung/Kconfig new file mode 100644 index 000000000000..eb45cf90d4e2 --- /dev/null +++ b/sound/soc/samsung/Kconfig @@ -0,0 +1,155 @@ +config ASOC_SAMSUNG + tristate "ASoC support for Samsung" + depends on ARCH_S3C2410 || ARCH_S3C64XX || ARCH_S5PC100 || ARCH_S5PV210 + select S3C64XX_DMA if ARCH_S3C64XX + select S3C2410_DMA if ARCH_S3C2410 + help + Say Y or M if you want to add support for codecs attached to + the Samsung SoCs' Audio interfaces. You will also need to + select the audio interfaces to support below. + +config SND_S3C24XX_I2S + tristate + select S3C2410_DMA + +config SND_S3C_I2SV2_SOC + tristate + +config SND_S3C2412_SOC_I2S + tristate + select SND_S3C_I2SV2_SOC + select S3C2410_DMA + +config SND_SAMSUNG_PCM + tristate + +config SND_SAMSUNG_AC97 + tristate + select SND_SOC_AC97_BUS + +config SND_SAMSUNG_SPDIF + tristate + select SND_SOC_SPDIF + +config SND_SAMSUNG_I2S + tristate + +config ASOC_SAMSUNG_NEO1973_WM8753 + tristate "SoC I2S Audio support for NEO1973 - WM8753" + depends on ASOC_SAMSUNG && MACH_NEO1973_GTA01 + select SND_S3C24XX_I2S + select SND_SOC_WM8753 + help + Say Y if you want to add support for SoC audio on smdk2440 + with the WM8753. + +config ASOC_SAMSUNG_NEO1973_GTA02_WM8753 + tristate "Audio support for the Openmoko Neo FreeRunner (GTA02)" + depends on ASOC_SAMSUNG && MACH_NEO1973_GTA02 + select SND_S3C24XX_I2S + select SND_SOC_WM8753 + help + This driver provides audio support for the Openmoko Neo FreeRunner + smartphone. + +config ASOC_SAMSUNG_JIVE_WM8750 + tristate "SoC I2S Audio support for Jive" + depends on ASOC_SAMSUNG && MACH_JIVE + select SND_SOC_WM8750 + select SND_S3C2412_SOC_I2S + help + Sat Y if you want to add support for SoC audio on the Jive. + +config ASOC_SAMSUNG_SMDK_WM8580 + tristate "SoC I2S Audio support for WM8580 on SMDK" + depends on ASOC_SAMSUNG && (MACH_SMDK6410 || MACH_SMDKC100) + select SND_SOC_WM8580 + select SND_SAMSUNG_I2S + help + Say Y if you want to add support for SoC audio on the SMDKs. + +config ASOC_SAMSUNG_SMDK2443_WM9710 + tristate "SoC AC97 Audio support for SMDK2443 - WM9710" + depends on ASOC_SAMSUNG && MACH_SMDK2443 + select S3C2410_DMA + select AC97_BUS + select SND_SOC_AC97_CODEC + select SND_SAMSUNG_AC97 + help + Say Y if you want to add support for SoC audio on smdk2443 + with the WM9710. + +config ASOC_SAMSUNG_LN2440SBC_ALC650 + tristate "SoC AC97 Audio support for LN2440SBC - ALC650" + depends on ASOC_SAMSUNG && ARCH_S3C2410 + select S3C2410_DMA + select AC97_BUS + select SND_SOC_AC97_CODEC + select SND_SAMSUNG_AC97 + help + Say Y if you want to add support for SoC audio on ln2440sbc + with the ALC650. + +config ASOC_SAMSUNG_S3C24XX_UDA134X + tristate "SoC I2S Audio support UDA134X wired to a S3C24XX" + depends on ASOC_SAMSUNG && ARCH_S3C2410 + select SND_S3C24XX_I2S + select SND_SOC_L3 + select SND_SOC_UDA134X + +config ASOC_SAMSUNG_SIMTEC + tristate + help + Internal node for common S3C24XX/Simtec suppor + +config ASOC_SAMSUNG_SIMTEC_TLV320AIC23 + tristate "SoC I2S Audio support for TLV320AIC23 on Simtec boards" + depends on ASOC_SAMSUNG && ARCH_S3C2410 + select SND_S3C24XX_I2S + select SND_SOC_TLV320AIC23 + select ASOC_SAMSUNG_SIMTEC + +config ASOC_SAMSUNG_SIMTEC_HERMES + tristate "SoC I2S Audio support for Simtec Hermes board" + depends on ASOC_SAMSUNG && ARCH_S3C2410 + select SND_S3C24XX_I2S + select SND_SOC_TLV320AIC3X + select ASOC_SAMSUNG_SIMTEC + +config ASOC_SAMSUNG_RX1950_UDA1380 + tristate "Audio support for the HP iPAQ RX1950" + depends on ASOC_SAMSUNG && MACH_RX1950 + select SND_S3C24XX_I2S + select SND_SOC_UDA1380 + help + This driver provides audio support for HP iPAQ RX1950 PDA. + +config ASOC_SAMSUNG_SMDK_WM9713 + tristate "SoC AC97 Audio support for SMDK with WM9713" + depends on ASOC_SAMSUNG && (MACH_SMDK6410 || MACH_SMDKC100 || MACH_SMDKV210 || MACH_SMDKC110) + select SND_SOC_WM9713 + select SND_SAMSUNG_AC97 + help + Sat Y if you want to add support for SoC audio on the SMDK. + +config ASOC_SMARTQ + tristate "SoC I2S Audio support for SmartQ board" + depends on ASOC_SAMSUNG && MACH_SMARTQ + select SND_SAMSUNG_I2S + select SND_SOC_WM8750 + +config ASOC_GONI_AQUILA_WM8994 + tristate "SoC I2S Audio support for AQUILA/GONI - WM8994" + depends on ASOC_SAMSUNG && (MACH_GONI || MACH_AQUILA) + select SND_SAMSUNG_I2S + select SND_SOC_WM8994 + help + Say Y if you want to add support for SoC audio on goni or aquila + with the WM8994. + +config ASOC_SAMSUNG_SMDK_SPDIF + tristate "SoC S/PDIF Audio support for SMDK" + depends on ASOC_SAMSUNG && (MACH_SMDKC100 || MACH_SMDKC110 || MACH_SMDKV210) + select SND_SAMSUNG_SPDIF + help + Say Y if you want to add support for SoC S/PDIF audio on the SMDK. diff --git a/sound/soc/samsung/Makefile b/sound/soc/samsung/Makefile new file mode 100644 index 000000000000..0d24f95c8b1c --- /dev/null +++ b/sound/soc/samsung/Makefile @@ -0,0 +1,51 @@ +# S3c24XX Platform Support +snd-soc-s3c24xx-objs := dma.o +snd-soc-s3c24xx-i2s-objs := s3c24xx-i2s.o +snd-soc-s3c2412-i2s-objs := s3c2412-i2s.o +snd-soc-ac97-objs := ac97.o +snd-soc-s3c-i2s-v2-objs := s3c-i2s-v2.o +snd-soc-samsung-spdif-objs := spdif.o +snd-soc-pcm-objs := pcm.o +snd-soc-i2s-objs := i2s.o + +obj-$(CONFIG_ASOC_SAMSUNG) += snd-soc-s3c24xx.o +obj-$(CONFIG_SND_S3C24XX_I2S) += snd-soc-s3c24xx-i2s.o +obj-$(CONFIG_SND_SAMSUNG_AC97) += snd-soc-ac97.o +obj-$(CONFIG_SND_S3C2412_SOC_I2S) += snd-soc-s3c2412-i2s.o +obj-$(CONFIG_SND_S3C_I2SV2_SOC) += snd-soc-s3c-i2s-v2.o +obj-$(CONFIG_SND_SAMSUNG_SPDIF) += snd-soc-samsung-spdif.o +obj-$(CONFIG_SND_SAMSUNG_PCM) += snd-soc-pcm.o +obj-$(CONFIG_SND_SAMSUNG_I2S) += snd-soc-i2s.o + +# S3C24XX Machine Support +snd-soc-jive-wm8750-objs := jive_wm8750.o +snd-soc-neo1973-wm8753-objs := neo1973_wm8753.o +snd-soc-neo1973-gta02-wm8753-objs := neo1973_gta02_wm8753.o +snd-soc-smdk2443-wm9710-objs := smdk2443_wm9710.o +snd-soc-ln2440sbc-alc650-objs := ln2440sbc_alc650.o +snd-soc-s3c24xx-uda134x-objs := s3c24xx_uda134x.o +snd-soc-s3c24xx-simtec-objs := s3c24xx_simtec.o +snd-soc-s3c24xx-simtec-hermes-objs := s3c24xx_simtec_hermes.o +snd-soc-s3c24xx-simtec-tlv320aic23-objs := s3c24xx_simtec_tlv320aic23.o +snd-soc-rx1950-uda1380-objs := rx1950_uda1380.o +snd-soc-smdk-wm8580-objs := smdk_wm8580.o +snd-soc-smdk-wm9713-objs := smdk_wm9713.o +snd-soc-s3c64xx-smartq-wm8987-objs := smartq_wm8987.o +snd-soc-goni-wm8994-objs := goni_wm8994.o +snd-soc-smdk-spdif-objs := smdk_spdif.o + +obj-$(CONFIG_ASOC_SAMSUNG_JIVE_WM8750) += snd-soc-jive-wm8750.o +obj-$(CONFIG_ASOC_SAMSUNG_NEO1973_WM8753) += snd-soc-neo1973-wm8753.o +obj-$(CONFIG_ASOC_SAMSUNG_NEO1973_GTA02_WM8753) += snd-soc-neo1973-gta02-wm8753.o +obj-$(CONFIG_ASOC_SAMSUNG_SMDK2443_WM9710) += snd-soc-smdk2443-wm9710.o +obj-$(CONFIG_ASOC_SAMSUNG_LN2440SBC_ALC650) += snd-soc-ln2440sbc-alc650.o +obj-$(CONFIG_ASOC_SAMSUNG_S3C24XX_UDA134X) += snd-soc-s3c24xx-uda134x.o +obj-$(CONFIG_ASOC_SAMSUNG_SIMTEC) += snd-soc-s3c24xx-simtec.o +obj-$(CONFIG_ASOC_SAMSUNG_SIMTEC_HERMES) += snd-soc-s3c24xx-simtec-hermes.o +obj-$(CONFIG_ASOC_SAMSUNG_SIMTEC_TLV320AIC23) += snd-soc-s3c24xx-simtec-tlv320aic23.o +obj-$(CONFIG_ASOC_SAMSUNG_RX1950_UDA1380) += snd-soc-rx1950-uda1380.o +obj-$(CONFIG_ASOC_SAMSUNG_SMDK_WM8580) += snd-soc-smdk-wm8580.o +obj-$(CONFIG_ASOC_SAMSUNG_SMDK_WM9713) += snd-soc-smdk-wm9713.o +obj-$(CONFIG_ASOC_SMARTQ) += snd-soc-s3c64xx-smartq-wm8987.o +obj-$(CONFIG_ASOC_SAMSUNG_SMDK_SPDIF) += snd-soc-smdk-spdif.o +obj-$(CONFIG_ASOC_GONI_AQUILA_WM8994) += snd-soc-goni-wm8994.o diff --git a/sound/soc/samsung/ac97.c b/sound/soc/samsung/ac97.c new file mode 100644 index 000000000000..4770a9550341 --- /dev/null +++ b/sound/soc/samsung/ac97.c @@ -0,0 +1,520 @@ +/* sound/soc/samsung/ac97.c + * + * ALSA SoC Audio Layer - S3C AC97 Controller driver + * Evolved from s3c2443-ac97.c + * + * Copyright (c) 2010 Samsung Electronics Co. Ltd + * Author: Jaswinder Singh + * Credits: Graeme Gregory, Sean Choi + * + * 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 +#include + +#include + +#include +#include +#include + +#include "dma.h" +#include "ac97.h" + +#define AC_CMD_ADDR(x) (x << 16) +#define AC_CMD_DATA(x) (x & 0xffff) + +struct s3c_ac97_info { + struct clk *ac97_clk; + void __iomem *regs; + struct mutex lock; + struct completion done; +}; +static struct s3c_ac97_info s3c_ac97; + +static struct s3c2410_dma_client s3c_dma_client_out = { + .name = "AC97 PCMOut" +}; + +static struct s3c2410_dma_client s3c_dma_client_in = { + .name = "AC97 PCMIn" +}; + +static struct s3c2410_dma_client s3c_dma_client_micin = { + .name = "AC97 MicIn" +}; + +static struct s3c_dma_params s3c_ac97_pcm_out = { + .client = &s3c_dma_client_out, + .dma_size = 4, +}; + +static struct s3c_dma_params s3c_ac97_pcm_in = { + .client = &s3c_dma_client_in, + .dma_size = 4, +}; + +static struct s3c_dma_params s3c_ac97_mic_in = { + .client = &s3c_dma_client_micin, + .dma_size = 4, +}; + +static void s3c_ac97_activate(struct snd_ac97 *ac97) +{ + u32 ac_glbctrl, stat; + + stat = readl(s3c_ac97.regs + S3C_AC97_GLBSTAT) & 0x7; + if (stat == S3C_AC97_GLBSTAT_MAINSTATE_ACTIVE) + return; /* Return if already active */ + + INIT_COMPLETION(s3c_ac97.done); + + ac_glbctrl = readl(s3c_ac97.regs + S3C_AC97_GLBCTRL); + ac_glbctrl = S3C_AC97_GLBCTRL_ACLINKON; + writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL); + msleep(1); + + ac_glbctrl |= S3C_AC97_GLBCTRL_TRANSFERDATAENABLE; + writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL); + msleep(1); + + ac_glbctrl = readl(s3c_ac97.regs + S3C_AC97_GLBCTRL); + ac_glbctrl |= S3C_AC97_GLBCTRL_CODECREADYIE; + writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL); + + if (!wait_for_completion_timeout(&s3c_ac97.done, HZ)) + pr_err("AC97: Unable to activate!"); +} + +static unsigned short s3c_ac97_read(struct snd_ac97 *ac97, + unsigned short reg) +{ + u32 ac_glbctrl, ac_codec_cmd; + u32 stat, addr, data; + + mutex_lock(&s3c_ac97.lock); + + s3c_ac97_activate(ac97); + + INIT_COMPLETION(s3c_ac97.done); + + ac_codec_cmd = readl(s3c_ac97.regs + S3C_AC97_CODEC_CMD); + ac_codec_cmd = S3C_AC97_CODEC_CMD_READ | AC_CMD_ADDR(reg); + writel(ac_codec_cmd, s3c_ac97.regs + S3C_AC97_CODEC_CMD); + + udelay(50); + + ac_glbctrl = readl(s3c_ac97.regs + S3C_AC97_GLBCTRL); + ac_glbctrl |= S3C_AC97_GLBCTRL_CODECREADYIE; + writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL); + + if (!wait_for_completion_timeout(&s3c_ac97.done, HZ)) + pr_err("AC97: Unable to read!"); + + stat = readl(s3c_ac97.regs + S3C_AC97_STAT); + addr = (stat >> 16) & 0x7f; + data = (stat & 0xffff); + + if (addr != reg) + pr_err("ac97: req addr = %02x, rep addr = %02x\n", + reg, addr); + + mutex_unlock(&s3c_ac97.lock); + + return (unsigned short)data; +} + +static void s3c_ac97_write(struct snd_ac97 *ac97, unsigned short reg, + unsigned short val) +{ + u32 ac_glbctrl, ac_codec_cmd; + + mutex_lock(&s3c_ac97.lock); + + s3c_ac97_activate(ac97); + + INIT_COMPLETION(s3c_ac97.done); + + ac_codec_cmd = readl(s3c_ac97.regs + S3C_AC97_CODEC_CMD); + ac_codec_cmd = AC_CMD_ADDR(reg) | AC_CMD_DATA(val); + writel(ac_codec_cmd, s3c_ac97.regs + S3C_AC97_CODEC_CMD); + + udelay(50); + + ac_glbctrl = readl(s3c_ac97.regs + S3C_AC97_GLBCTRL); + ac_glbctrl |= S3C_AC97_GLBCTRL_CODECREADYIE; + writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL); + + if (!wait_for_completion_timeout(&s3c_ac97.done, HZ)) + pr_err("AC97: Unable to write!"); + + ac_codec_cmd = readl(s3c_ac97.regs + S3C_AC97_CODEC_CMD); + ac_codec_cmd |= S3C_AC97_CODEC_CMD_READ; + writel(ac_codec_cmd, s3c_ac97.regs + S3C_AC97_CODEC_CMD); + + mutex_unlock(&s3c_ac97.lock); +} + +static void s3c_ac97_cold_reset(struct snd_ac97 *ac97) +{ + pr_debug("AC97: Cold reset\n"); + writel(S3C_AC97_GLBCTRL_COLDRESET, + s3c_ac97.regs + S3C_AC97_GLBCTRL); + msleep(1); + + writel(0, s3c_ac97.regs + S3C_AC97_GLBCTRL); + msleep(1); +} + +static void s3c_ac97_warm_reset(struct snd_ac97 *ac97) +{ + u32 stat; + + stat = readl(s3c_ac97.regs + S3C_AC97_GLBSTAT) & 0x7; + if (stat == S3C_AC97_GLBSTAT_MAINSTATE_ACTIVE) + return; /* Return if already active */ + + pr_debug("AC97: Warm reset\n"); + + writel(S3C_AC97_GLBCTRL_WARMRESET, s3c_ac97.regs + S3C_AC97_GLBCTRL); + msleep(1); + + writel(0, s3c_ac97.regs + S3C_AC97_GLBCTRL); + msleep(1); + + s3c_ac97_activate(ac97); +} + +static irqreturn_t s3c_ac97_irq(int irq, void *dev_id) +{ + u32 ac_glbctrl, ac_glbstat; + + ac_glbstat = readl(s3c_ac97.regs + S3C_AC97_GLBSTAT); + + if (ac_glbstat & S3C_AC97_GLBSTAT_CODECREADY) { + + ac_glbctrl = readl(s3c_ac97.regs + S3C_AC97_GLBCTRL); + ac_glbctrl &= ~S3C_AC97_GLBCTRL_CODECREADYIE; + writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL); + + complete(&s3c_ac97.done); + } + + ac_glbctrl = readl(s3c_ac97.regs + S3C_AC97_GLBCTRL); + ac_glbctrl |= (1<<30); /* Clear interrupt */ + writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL); + + return IRQ_HANDLED; +} + +struct snd_ac97_bus_ops soc_ac97_ops = { + .read = s3c_ac97_read, + .write = s3c_ac97_write, + .warm_reset = s3c_ac97_warm_reset, + .reset = s3c_ac97_cold_reset, +}; +EXPORT_SYMBOL_GPL(soc_ac97_ops); + +static int s3c_ac97_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + struct s3c_dma_params *dma_data; + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + dma_data = &s3c_ac97_pcm_out; + else + dma_data = &s3c_ac97_pcm_in; + + snd_soc_dai_set_dma_data(cpu_dai, substream, dma_data); + + return 0; +} + +static int s3c_ac97_trigger(struct snd_pcm_substream *substream, int cmd, + struct snd_soc_dai *dai) +{ + u32 ac_glbctrl; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct s3c_dma_params *dma_data = + snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); + + ac_glbctrl = readl(s3c_ac97.regs + S3C_AC97_GLBCTRL); + if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) + ac_glbctrl &= ~S3C_AC97_GLBCTRL_PCMINTM_MASK; + else + ac_glbctrl &= ~S3C_AC97_GLBCTRL_PCMOUTTM_MASK; + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + case SNDRV_PCM_TRIGGER_RESUME: + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: + if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) + ac_glbctrl |= S3C_AC97_GLBCTRL_PCMINTM_DMA; + else + ac_glbctrl |= S3C_AC97_GLBCTRL_PCMOUTTM_DMA; + break; + + case SNDRV_PCM_TRIGGER_STOP: + case SNDRV_PCM_TRIGGER_SUSPEND: + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + break; + } + + writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL); + + s3c2410_dma_ctrl(dma_data->channel, S3C2410_DMAOP_STARTED); + + return 0; +} + +static int s3c_ac97_hw_mic_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + return -ENODEV; + else + snd_soc_dai_set_dma_data(cpu_dai, substream, &s3c_ac97_mic_in); + + return 0; +} + +static int s3c_ac97_mic_trigger(struct snd_pcm_substream *substream, + int cmd, struct snd_soc_dai *dai) +{ + u32 ac_glbctrl; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct s3c_dma_params *dma_data = + snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); + + ac_glbctrl = readl(s3c_ac97.regs + S3C_AC97_GLBCTRL); + ac_glbctrl &= ~S3C_AC97_GLBCTRL_MICINTM_MASK; + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + case SNDRV_PCM_TRIGGER_RESUME: + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: + ac_glbctrl |= S3C_AC97_GLBCTRL_MICINTM_DMA; + break; + + case SNDRV_PCM_TRIGGER_STOP: + case SNDRV_PCM_TRIGGER_SUSPEND: + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + break; + } + + writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL); + + s3c2410_dma_ctrl(dma_data->channel, S3C2410_DMAOP_STARTED); + + return 0; +} + +static struct snd_soc_dai_ops s3c_ac97_dai_ops = { + .hw_params = s3c_ac97_hw_params, + .trigger = s3c_ac97_trigger, +}; + +static struct snd_soc_dai_ops s3c_ac97_mic_dai_ops = { + .hw_params = s3c_ac97_hw_mic_params, + .trigger = s3c_ac97_mic_trigger, +}; + +static struct snd_soc_dai_driver s3c_ac97_dai[] = { + [S3C_AC97_DAI_PCM] = { + .name = "samsung-ac97", + .ac97_control = 1, + .playback = { + .stream_name = "AC97 Playback", + .channels_min = 2, + .channels_max = 2, + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = SNDRV_PCM_FMTBIT_S16_LE,}, + .capture = { + .stream_name = "AC97 Capture", + .channels_min = 2, + .channels_max = 2, + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = SNDRV_PCM_FMTBIT_S16_LE,}, + .ops = &s3c_ac97_dai_ops, + }, + [S3C_AC97_DAI_MIC] = { + .name = "samsung-ac97-mic", + .ac97_control = 1, + .capture = { + .stream_name = "AC97 Mic Capture", + .channels_min = 1, + .channels_max = 1, + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = SNDRV_PCM_FMTBIT_S16_LE,}, + .ops = &s3c_ac97_mic_dai_ops, + }, +}; + +static __devinit int s3c_ac97_probe(struct platform_device *pdev) +{ + struct resource *mem_res, *dmatx_res, *dmarx_res, *dmamic_res, *irq_res; + struct s3c_audio_pdata *ac97_pdata; + int ret; + + ac97_pdata = pdev->dev.platform_data; + if (!ac97_pdata || !ac97_pdata->cfg_gpio) { + dev_err(&pdev->dev, "cfg_gpio callback not provided!\n"); + return -EINVAL; + } + + /* Check for availability of necessary resource */ + dmatx_res = platform_get_resource(pdev, IORESOURCE_DMA, 0); + if (!dmatx_res) { + dev_err(&pdev->dev, "Unable to get AC97-TX dma resource\n"); + return -ENXIO; + } + + dmarx_res = platform_get_resource(pdev, IORESOURCE_DMA, 1); + if (!dmarx_res) { + dev_err(&pdev->dev, "Unable to get AC97-RX dma resource\n"); + return -ENXIO; + } + + dmamic_res = platform_get_resource(pdev, IORESOURCE_DMA, 2); + if (!dmamic_res) { + dev_err(&pdev->dev, "Unable to get AC97-MIC dma resource\n"); + return -ENXIO; + } + + mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!mem_res) { + dev_err(&pdev->dev, "Unable to get register resource\n"); + return -ENXIO; + } + + irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); + if (!irq_res) { + dev_err(&pdev->dev, "AC97 IRQ not provided!\n"); + return -ENXIO; + } + + if (!request_mem_region(mem_res->start, + resource_size(mem_res), "ac97")) { + dev_err(&pdev->dev, "Unable to request register region\n"); + return -EBUSY; + } + + s3c_ac97_pcm_out.channel = dmatx_res->start; + s3c_ac97_pcm_out.dma_addr = mem_res->start + S3C_AC97_PCM_DATA; + s3c_ac97_pcm_in.channel = dmarx_res->start; + s3c_ac97_pcm_in.dma_addr = mem_res->start + S3C_AC97_PCM_DATA; + s3c_ac97_mic_in.channel = dmamic_res->start; + s3c_ac97_mic_in.dma_addr = mem_res->start + S3C_AC97_MIC_DATA; + + init_completion(&s3c_ac97.done); + mutex_init(&s3c_ac97.lock); + + s3c_ac97.regs = ioremap(mem_res->start, resource_size(mem_res)); + if (s3c_ac97.regs == NULL) { + dev_err(&pdev->dev, "Unable to ioremap register region\n"); + ret = -ENXIO; + goto err1; + } + + s3c_ac97.ac97_clk = clk_get(&pdev->dev, "ac97"); + if (IS_ERR(s3c_ac97.ac97_clk)) { + dev_err(&pdev->dev, "ac97 failed to get ac97_clock\n"); + ret = -ENODEV; + goto err2; + } + clk_enable(s3c_ac97.ac97_clk); + + if (ac97_pdata->cfg_gpio(pdev)) { + dev_err(&pdev->dev, "Unable to configure gpio\n"); + ret = -EINVAL; + goto err3; + } + + ret = request_irq(irq_res->start, s3c_ac97_irq, + IRQF_DISABLED, "AC97", NULL); + if (ret < 0) { + dev_err(&pdev->dev, "ac97: interrupt request failed.\n"); + goto err4; + } + + ret = snd_soc_register_dais(&pdev->dev, s3c_ac97_dai, + ARRAY_SIZE(s3c_ac97_dai)); + if (ret) + goto err5; + + return 0; + +err5: + free_irq(irq_res->start, NULL); +err4: +err3: + clk_disable(s3c_ac97.ac97_clk); + clk_put(s3c_ac97.ac97_clk); +err2: + iounmap(s3c_ac97.regs); +err1: + release_mem_region(mem_res->start, resource_size(mem_res)); + + return ret; +} + +static __devexit int s3c_ac97_remove(struct platform_device *pdev) +{ + struct resource *mem_res, *irq_res; + + snd_soc_unregister_dais(&pdev->dev, ARRAY_SIZE(s3c_ac97_dai)); + + irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); + if (irq_res) + free_irq(irq_res->start, NULL); + + clk_disable(s3c_ac97.ac97_clk); + clk_put(s3c_ac97.ac97_clk); + + iounmap(s3c_ac97.regs); + + mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (mem_res) + release_mem_region(mem_res->start, resource_size(mem_res)); + + return 0; +} + +static struct platform_driver s3c_ac97_driver = { + .probe = s3c_ac97_probe, + .remove = s3c_ac97_remove, + .driver = { + .name = "samsung-ac97", + .owner = THIS_MODULE, + }, +}; + +static int __init s3c_ac97_init(void) +{ + return platform_driver_register(&s3c_ac97_driver); +} +module_init(s3c_ac97_init); + +static void __exit s3c_ac97_exit(void) +{ + platform_driver_unregister(&s3c_ac97_driver); +} +module_exit(s3c_ac97_exit); + +MODULE_AUTHOR("Jaswinder Singh, "); +MODULE_DESCRIPTION("AC97 driver for the Samsung SoC"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:samsung-ac97"); diff --git a/sound/soc/samsung/ac97.h b/sound/soc/samsung/ac97.h new file mode 100644 index 000000000000..0d0e1b511457 --- /dev/null +++ b/sound/soc/samsung/ac97.h @@ -0,0 +1,21 @@ +/* sound/soc/samsung/ac97.h + * + * ALSA SoC Audio Layer - S3C AC97 Controller driver + * Evolved from s3c2443-ac97.h + * + * Copyright (c) 2010 Samsung Electronics Co. Ltd + * Author: Jaswinder Singh + * Credits: Graeme Gregory, Sean Choi + * + * 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. + */ + +#ifndef __S3C_AC97_H_ +#define __S3C_AC97_H_ + +#define S3C_AC97_DAI_PCM 0 +#define S3C_AC97_DAI_MIC 1 + +#endif /* __S3C_AC97_H_ */ diff --git a/sound/soc/samsung/dma.c b/sound/soc/samsung/dma.c new file mode 100644 index 000000000000..21240198c5d6 --- /dev/null +++ b/sound/soc/samsung/dma.c @@ -0,0 +1,502 @@ +/* + * dma.c -- ALSA Soc Audio Layer + * + * (c) 2006 Wolfson Microelectronics PLC. + * Graeme Gregory graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com + * + * Copyright 2004-2005 Simtec Electronics + * http://armlinux.simtec.co.uk/ + * Ben Dooks + * + * 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. + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include "dma.h" + +static const struct snd_pcm_hardware dma_hardware = { + .info = SNDRV_PCM_INFO_INTERLEAVED | + SNDRV_PCM_INFO_BLOCK_TRANSFER | + SNDRV_PCM_INFO_MMAP | + SNDRV_PCM_INFO_MMAP_VALID | + SNDRV_PCM_INFO_PAUSE | + SNDRV_PCM_INFO_RESUME, + .formats = SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_U16_LE | + SNDRV_PCM_FMTBIT_U8 | + SNDRV_PCM_FMTBIT_S8, + .channels_min = 2, + .channels_max = 2, + .buffer_bytes_max = 128*1024, + .period_bytes_min = PAGE_SIZE, + .period_bytes_max = PAGE_SIZE*2, + .periods_min = 2, + .periods_max = 128, + .fifo_size = 32, +}; + +struct runtime_data { + spinlock_t lock; + int state; + unsigned int dma_loaded; + unsigned int dma_limit; + unsigned int dma_period; + dma_addr_t dma_start; + dma_addr_t dma_pos; + dma_addr_t dma_end; + struct s3c_dma_params *params; +}; + +/* dma_enqueue + * + * place a dma buffer onto the queue for the dma system + * to handle. +*/ +static void dma_enqueue(struct snd_pcm_substream *substream) +{ + struct runtime_data *prtd = substream->runtime->private_data; + dma_addr_t pos = prtd->dma_pos; + unsigned int limit; + int ret; + + pr_debug("Entered %s\n", __func__); + + if (s3c_dma_has_circular()) + limit = (prtd->dma_end - prtd->dma_start) / prtd->dma_period; + else + limit = prtd->dma_limit; + + pr_debug("%s: loaded %d, limit %d\n", + __func__, prtd->dma_loaded, limit); + + while (prtd->dma_loaded < limit) { + unsigned long len = prtd->dma_period; + + pr_debug("dma_loaded: %d\n", prtd->dma_loaded); + + if ((pos + len) > prtd->dma_end) { + len = prtd->dma_end - pos; + pr_debug("%s: corrected dma len %ld\n", __func__, len); + } + + ret = s3c2410_dma_enqueue(prtd->params->channel, + substream, pos, len); + + if (ret == 0) { + prtd->dma_loaded++; + pos += prtd->dma_period; + if (pos >= prtd->dma_end) + pos = prtd->dma_start; + } else + break; + } + + prtd->dma_pos = pos; +} + +static void audio_buffdone(struct s3c2410_dma_chan *channel, + void *dev_id, int size, + enum s3c2410_dma_buffresult result) +{ + struct snd_pcm_substream *substream = dev_id; + struct runtime_data *prtd; + + pr_debug("Entered %s\n", __func__); + + if (result == S3C2410_RES_ABORT || result == S3C2410_RES_ERR) + return; + + prtd = substream->runtime->private_data; + + if (substream) + snd_pcm_period_elapsed(substream); + + spin_lock(&prtd->lock); + if (prtd->state & ST_RUNNING && !s3c_dma_has_circular()) { + prtd->dma_loaded--; + dma_enqueue(substream); + } + + spin_unlock(&prtd->lock); +} + +static int dma_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct runtime_data *prtd = runtime->private_data; + struct snd_soc_pcm_runtime *rtd = substream->private_data; + unsigned long totbytes = params_buffer_bytes(params); + struct s3c_dma_params *dma = + snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); + int ret = 0; + + + pr_debug("Entered %s\n", __func__); + + /* return if this is a bufferless transfer e.g. + * codec <--> BT codec or GSM modem -- lg FIXME */ + if (!dma) + return 0; + + /* this may get called several times by oss emulation + * with different params -HW */ + if (prtd->params == NULL) { + /* prepare DMA */ + prtd->params = dma; + + pr_debug("params %p, client %p, channel %d\n", prtd->params, + prtd->params->client, prtd->params->channel); + + ret = s3c2410_dma_request(prtd->params->channel, + prtd->params->client, NULL); + + if (ret < 0) { + printk(KERN_ERR "failed to get dma channel\n"); + return ret; + } + + /* use the circular buffering if we have it available. */ + if (s3c_dma_has_circular()) + s3c2410_dma_setflags(prtd->params->channel, + S3C2410_DMAF_CIRCULAR); + } + + s3c2410_dma_set_buffdone_fn(prtd->params->channel, + audio_buffdone); + + snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); + + runtime->dma_bytes = totbytes; + + spin_lock_irq(&prtd->lock); + prtd->dma_loaded = 0; + prtd->dma_limit = runtime->hw.periods_min; + prtd->dma_period = params_period_bytes(params); + prtd->dma_start = runtime->dma_addr; + prtd->dma_pos = prtd->dma_start; + prtd->dma_end = prtd->dma_start + totbytes; + spin_unlock_irq(&prtd->lock); + + return 0; +} + +static int dma_hw_free(struct snd_pcm_substream *substream) +{ + struct runtime_data *prtd = substream->runtime->private_data; + + pr_debug("Entered %s\n", __func__); + + /* TODO - do we need to ensure DMA flushed */ + snd_pcm_set_runtime_buffer(substream, NULL); + + if (prtd->params) { + s3c2410_dma_free(prtd->params->channel, prtd->params->client); + prtd->params = NULL; + } + + return 0; +} + +static int dma_prepare(struct snd_pcm_substream *substream) +{ + struct runtime_data *prtd = substream->runtime->private_data; + int ret = 0; + + pr_debug("Entered %s\n", __func__); + + /* return if this is a bufferless transfer e.g. + * codec <--> BT codec or GSM modem -- lg FIXME */ + if (!prtd->params) + return 0; + + /* channel needs configuring for mem=>device, increment memory addr, + * sync to pclk, half-word transfers to the IIS-FIFO. */ + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { + s3c2410_dma_devconfig(prtd->params->channel, + S3C2410_DMASRC_MEM, + prtd->params->dma_addr); + } else { + s3c2410_dma_devconfig(prtd->params->channel, + S3C2410_DMASRC_HW, + prtd->params->dma_addr); + } + + s3c2410_dma_config(prtd->params->channel, + prtd->params->dma_size); + + /* flush the DMA channel */ + s3c2410_dma_ctrl(prtd->params->channel, S3C2410_DMAOP_FLUSH); + prtd->dma_loaded = 0; + prtd->dma_pos = prtd->dma_start; + + /* enqueue dma buffers */ + dma_enqueue(substream); + + return ret; +} + +static int dma_trigger(struct snd_pcm_substream *substream, int cmd) +{ + struct runtime_data *prtd = substream->runtime->private_data; + int ret = 0; + + pr_debug("Entered %s\n", __func__); + + spin_lock(&prtd->lock); + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + case SNDRV_PCM_TRIGGER_RESUME: + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: + prtd->state |= ST_RUNNING; + s3c2410_dma_ctrl(prtd->params->channel, S3C2410_DMAOP_START); + break; + + case SNDRV_PCM_TRIGGER_STOP: + case SNDRV_PCM_TRIGGER_SUSPEND: + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + prtd->state &= ~ST_RUNNING; + s3c2410_dma_ctrl(prtd->params->channel, S3C2410_DMAOP_STOP); + break; + + default: + ret = -EINVAL; + break; + } + + spin_unlock(&prtd->lock); + + return ret; +} + +static snd_pcm_uframes_t +dma_pointer(struct snd_pcm_substream *substream) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct runtime_data *prtd = runtime->private_data; + unsigned long res; + dma_addr_t src, dst; + + pr_debug("Entered %s\n", __func__); + + spin_lock(&prtd->lock); + s3c2410_dma_getposition(prtd->params->channel, &src, &dst); + + if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) + res = dst - prtd->dma_start; + else + res = src - prtd->dma_start; + + spin_unlock(&prtd->lock); + + pr_debug("Pointer %x %x\n", src, dst); + + /* we seem to be getting the odd error from the pcm library due + * to out-of-bounds pointers. this is maybe due to the dma engine + * not having loaded the new values for the channel before being + * callled... (todo - fix ) + */ + + if (res >= snd_pcm_lib_buffer_bytes(substream)) { + if (res == snd_pcm_lib_buffer_bytes(substream)) + res = 0; + } + + return bytes_to_frames(substream->runtime, res); +} + +static int dma_open(struct snd_pcm_substream *substream) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct runtime_data *prtd; + + pr_debug("Entered %s\n", __func__); + + snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS); + snd_soc_set_runtime_hwparams(substream, &dma_hardware); + + prtd = kzalloc(sizeof(struct runtime_data), GFP_KERNEL); + if (prtd == NULL) + return -ENOMEM; + + spin_lock_init(&prtd->lock); + + runtime->private_data = prtd; + return 0; +} + +static int dma_close(struct snd_pcm_substream *substream) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + struct runtime_data *prtd = runtime->private_data; + + pr_debug("Entered %s\n", __func__); + + if (!prtd) + pr_debug("dma_close called with prtd == NULL\n"); + + kfree(prtd); + + return 0; +} + +static int dma_mmap(struct snd_pcm_substream *substream, + struct vm_area_struct *vma) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + + pr_debug("Entered %s\n", __func__); + + return dma_mmap_writecombine(substream->pcm->card->dev, vma, + runtime->dma_area, + runtime->dma_addr, + runtime->dma_bytes); +} + +static struct snd_pcm_ops dma_ops = { + .open = dma_open, + .close = dma_close, + .ioctl = snd_pcm_lib_ioctl, + .hw_params = dma_hw_params, + .hw_free = dma_hw_free, + .prepare = dma_prepare, + .trigger = dma_trigger, + .pointer = dma_pointer, + .mmap = dma_mmap, +}; + +static int preallocate_dma_buffer(struct snd_pcm *pcm, int stream) +{ + struct snd_pcm_substream *substream = pcm->streams[stream].substream; + struct snd_dma_buffer *buf = &substream->dma_buffer; + size_t size = dma_hardware.buffer_bytes_max; + + pr_debug("Entered %s\n", __func__); + + buf->dev.type = SNDRV_DMA_TYPE_DEV; + buf->dev.dev = pcm->card->dev; + buf->private_data = NULL; + buf->area = dma_alloc_writecombine(pcm->card->dev, size, + &buf->addr, GFP_KERNEL); + if (!buf->area) + return -ENOMEM; + buf->bytes = size; + return 0; +} + +static void dma_free_dma_buffers(struct snd_pcm *pcm) +{ + struct snd_pcm_substream *substream; + struct snd_dma_buffer *buf; + int stream; + + pr_debug("Entered %s\n", __func__); + + for (stream = 0; stream < 2; stream++) { + substream = pcm->streams[stream].substream; + if (!substream) + continue; + + buf = &substream->dma_buffer; + if (!buf->area) + continue; + + dma_free_writecombine(pcm->card->dev, buf->bytes, + buf->area, buf->addr); + buf->area = NULL; + } +} + +static u64 dma_mask = DMA_BIT_MASK(32); + +static int dma_new(struct snd_card *card, + struct snd_soc_dai *dai, struct snd_pcm *pcm) +{ + int ret = 0; + + pr_debug("Entered %s\n", __func__); + + if (!card->dev->dma_mask) + card->dev->dma_mask = &dma_mask; + if (!card->dev->coherent_dma_mask) + card->dev->coherent_dma_mask = 0xffffffff; + + if (dai->driver->playback.channels_min) { + ret = preallocate_dma_buffer(pcm, + SNDRV_PCM_STREAM_PLAYBACK); + if (ret) + goto out; + } + + if (dai->driver->capture.channels_min) { + ret = preallocate_dma_buffer(pcm, + SNDRV_PCM_STREAM_CAPTURE); + if (ret) + goto out; + } +out: + return ret; +} + +static struct snd_soc_platform_driver samsung_asoc_platform = { + .ops = &dma_ops, + .pcm_new = dma_new, + .pcm_free = dma_free_dma_buffers, +}; + +static int __devinit samsung_asoc_platform_probe(struct platform_device *pdev) +{ + return snd_soc_register_platform(&pdev->dev, &samsung_asoc_platform); +} + +static int __devexit samsung_asoc_platform_remove(struct platform_device *pdev) +{ + snd_soc_unregister_platform(&pdev->dev); + return 0; +} + +static struct platform_driver asoc_dma_driver = { + .driver = { + .name = "samsung-audio", + .owner = THIS_MODULE, + }, + + .probe = samsung_asoc_platform_probe, + .remove = __devexit_p(samsung_asoc_platform_remove), +}; + +static int __init samsung_asoc_init(void) +{ + return platform_driver_register(&asoc_dma_driver); +} +module_init(samsung_asoc_init); + +static void __exit samsung_asoc_exit(void) +{ + platform_driver_unregister(&asoc_dma_driver); +} +module_exit(samsung_asoc_exit); + +MODULE_AUTHOR("Ben Dooks, "); +MODULE_DESCRIPTION("Samsung ASoC DMA Driver"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:samsung-audio"); diff --git a/sound/soc/samsung/dma.h b/sound/soc/samsung/dma.h new file mode 100644 index 000000000000..f8cd2b4223af --- /dev/null +++ b/sound/soc/samsung/dma.h @@ -0,0 +1,30 @@ +/* + * dma.h -- + * + * 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. + * + * ALSA PCM interface for the Samsung S3C24xx CPU + */ + +#ifndef _S3C_AUDIO_H +#define _S3C_AUDIO_H + +#define ST_RUNNING (1<<0) +#define ST_OPENED (1<<1) + +struct s3c_dma_params { + struct s3c2410_dma_client *client; /* stream identifier */ + int channel; /* Channel ID */ + dma_addr_t dma_addr; + int dma_size; /* Size of the DMA transfer */ +}; + +#define S3C24XX_DAI_I2S 0 + +/* platform data */ +extern struct snd_ac97_bus_ops s3c24xx_ac97_ops; + +#endif diff --git a/sound/soc/samsung/goni_wm8994.c b/sound/soc/samsung/goni_wm8994.c new file mode 100644 index 000000000000..dcfac546cb81 --- /dev/null +++ b/sound/soc/samsung/goni_wm8994.c @@ -0,0 +1,309 @@ +/* + * goni_wm8994.c + * + * Copyright (C) 2010 Samsung Electronics Co.Ltd + * Author: Chanwoo Choi + * + * 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. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include "../codecs/wm8994.h" +#include "dma.h" +#include "i2s.h" + +#define MACHINE_NAME 0 +#define CPU_VOICE_DAI 1 + +static const char *aquila_str[] = { + [MACHINE_NAME] = "aquila", + [CPU_VOICE_DAI] = "aquila-voice-dai", +}; + +static struct snd_soc_card goni; +static struct platform_device *goni_snd_device; + +/* 3.5 pie jack */ +static struct snd_soc_jack jack; + +/* 3.5 pie jack detection DAPM pins */ +static struct snd_soc_jack_pin jack_pins[] = { + { + .pin = "Headset Mic", + .mask = SND_JACK_MICROPHONE, + }, { + .pin = "Headset Stereophone", + .mask = SND_JACK_HEADPHONE | SND_JACK_MECHANICAL | + SND_JACK_AVOUT, + }, +}; + +/* 3.5 pie jack detection gpios */ +static struct snd_soc_jack_gpio jack_gpios[] = { + { + .gpio = S5PV210_GPH0(6), + .name = "DET_3.5", + .report = SND_JACK_HEADSET | SND_JACK_MECHANICAL | + SND_JACK_AVOUT, + .debounce_time = 200, + }, +}; + +static const struct snd_soc_dapm_widget goni_dapm_widgets[] = { + SND_SOC_DAPM_SPK("Ext Left Spk", NULL), + SND_SOC_DAPM_SPK("Ext Right Spk", NULL), + SND_SOC_DAPM_SPK("Ext Rcv", NULL), + SND_SOC_DAPM_HP("Headset Stereophone", NULL), + SND_SOC_DAPM_MIC("Headset Mic", NULL), + SND_SOC_DAPM_MIC("Main Mic", NULL), + SND_SOC_DAPM_MIC("2nd Mic", NULL), + SND_SOC_DAPM_LINE("Radio In", NULL), +}; + +static const struct snd_soc_dapm_route goni_dapm_routes[] = { + {"Ext Left Spk", NULL, "SPKOUTLP"}, + {"Ext Left Spk", NULL, "SPKOUTLN"}, + + {"Ext Right Spk", NULL, "SPKOUTRP"}, + {"Ext Right Spk", NULL, "SPKOUTRN"}, + + {"Ext Rcv", NULL, "HPOUT2N"}, + {"Ext Rcv", NULL, "HPOUT2P"}, + + {"Headset Stereophone", NULL, "HPOUT1L"}, + {"Headset Stereophone", NULL, "HPOUT1R"}, + + {"IN1RN", NULL, "Headset Mic"}, + {"IN1RP", NULL, "Headset Mic"}, + + {"IN1RN", NULL, "2nd Mic"}, + {"IN1RP", NULL, "2nd Mic"}, + + {"IN1LN", NULL, "Main Mic"}, + {"IN1LP", NULL, "Main Mic"}, + + {"IN2LN", NULL, "Radio In"}, + {"IN2RN", NULL, "Radio In"}, +}; + +static int goni_wm8994_init(struct snd_soc_pcm_runtime *rtd) +{ + struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_dapm_context *dapm = &codec->dapm; + int ret; + + /* add goni specific widgets */ + snd_soc_dapm_new_controls(dapm, goni_dapm_widgets, + ARRAY_SIZE(goni_dapm_widgets)); + + /* set up goni specific audio routes */ + snd_soc_dapm_add_routes(dapm, goni_dapm_routes, + ARRAY_SIZE(goni_dapm_routes)); + + /* set endpoints to not connected */ + snd_soc_dapm_nc_pin(dapm, "IN2LP:VXRN"); + snd_soc_dapm_nc_pin(dapm, "IN2RP:VXRP"); + snd_soc_dapm_nc_pin(dapm, "LINEOUT1N"); + snd_soc_dapm_nc_pin(dapm, "LINEOUT1P"); + snd_soc_dapm_nc_pin(dapm, "LINEOUT2N"); + snd_soc_dapm_nc_pin(dapm, "LINEOUT2P"); + + if (machine_is_aquila()) { + snd_soc_dapm_nc_pin(dapm, "SPKOUTRN"); + snd_soc_dapm_nc_pin(dapm, "SPKOUTRP"); + } + + snd_soc_dapm_sync(dapm); + + /* Headset jack detection */ + ret = snd_soc_jack_new(&goni, "Headset Jack", + SND_JACK_HEADSET | SND_JACK_MECHANICAL | SND_JACK_AVOUT, + &jack); + if (ret) + return ret; + + ret = snd_soc_jack_add_pins(&jack, ARRAY_SIZE(jack_pins), jack_pins); + if (ret) + return ret; + + ret = snd_soc_jack_add_gpios(&jack, ARRAY_SIZE(jack_gpios), jack_gpios); + if (ret) + return ret; + + return 0; +} + +static int goni_hifi_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *codec_dai = rtd->codec_dai; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + unsigned int pll_out = 24000000; + int ret = 0; + + /* set the cpu DAI configuration */ + ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S | + SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM); + if (ret < 0) + return ret; + + /* set codec DAI configuration */ + ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | + SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBM_CFM); + if (ret < 0) + return ret; + + /* set the codec FLL */ + ret = snd_soc_dai_set_pll(codec_dai, WM8994_FLL1, 0, pll_out, + params_rate(params) * 256); + if (ret < 0) + return ret; + + /* set the codec system clock */ + ret = snd_soc_dai_set_sysclk(codec_dai, WM8994_SYSCLK_FLL1, + params_rate(params) * 256, SND_SOC_CLOCK_IN); + if (ret < 0) + return ret; + + return 0; +} + +static struct snd_soc_ops goni_hifi_ops = { + .hw_params = goni_hifi_hw_params, +}; + +static int goni_voice_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *codec_dai = rtd->codec_dai; + unsigned int pll_out = 24000000; + int ret = 0; + + if (params_rate(params) != 8000) + return -EINVAL; + + /* set codec DAI configuration */ + ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_LEFT_J | + SND_SOC_DAIFMT_IB_IF | SND_SOC_DAIFMT_CBM_CFM); + if (ret < 0) + return ret; + + /* set the codec FLL */ + ret = snd_soc_dai_set_pll(codec_dai, WM8994_FLL2, 0, pll_out, + params_rate(params) * 256); + if (ret < 0) + return ret; + + /* set the codec system clock */ + ret = snd_soc_dai_set_sysclk(codec_dai, WM8994_SYSCLK_FLL2, + params_rate(params) * 256, SND_SOC_CLOCK_IN); + if (ret < 0) + return ret; + + return 0; +} + +static struct snd_soc_dai_driver voice_dai = { + .name = "goni-voice-dai", + .id = 0, + .playback = { + .channels_min = 1, + .channels_max = 2, + .rates = SNDRV_PCM_RATE_8000, + .formats = SNDRV_PCM_FMTBIT_S16_LE,}, + .capture = { + .channels_min = 1, + .channels_max = 2, + .rates = SNDRV_PCM_RATE_8000, + .formats = SNDRV_PCM_FMTBIT_S16_LE,}, +}; + +static struct snd_soc_ops goni_voice_ops = { + .hw_params = goni_voice_hw_params, +}; + +static struct snd_soc_dai_link goni_dai[] = { +{ + .name = "WM8994", + .stream_name = "WM8994 HiFi", + .cpu_dai_name = "samsung-i2s.0", + .codec_dai_name = "wm8994-hifi", + .platform_name = "samsung-audio", + .codec_name = "wm8994-codec.0-0x1a", + .init = goni_wm8994_init, + .ops = &goni_hifi_ops, +}, { + .name = "WM8994 Voice", + .stream_name = "Voice", + .cpu_dai_name = "goni-voice-dai", + .codec_dai_name = "wm8994-voice", + .platform_name = "samsung-audio", + .codec_name = "wm8994-codec.0-0x1a", + .ops = &goni_voice_ops, +}, +}; + +static struct snd_soc_card goni = { + .name = "goni", + .dai_link = goni_dai, + .num_links = ARRAY_SIZE(goni_dai), +}; + +static int __init goni_init(void) +{ + int ret; + + if (machine_is_aquila()) { + voice_dai.name = aquila_str[CPU_VOICE_DAI]; + goni_dai[1].cpu_dai_name = aquila_str[CPU_VOICE_DAI]; + goni.name = aquila_str[MACHINE_NAME]; + } else if (!machine_is_goni()) + return -ENODEV; + + goni_snd_device = platform_device_alloc("soc-audio", -1); + if (!goni_snd_device) + return -ENOMEM; + + /* register voice DAI here */ + ret = snd_soc_register_dai(&goni_snd_device->dev, &voice_dai); + if (ret) + return ret; + + platform_set_drvdata(goni_snd_device, &goni); + ret = platform_device_add(goni_snd_device); + + if (ret) + platform_device_put(goni_snd_device); + + return ret; +} + +static void __exit goni_exit(void) +{ + platform_device_unregister(goni_snd_device); +} + +module_init(goni_init); +module_exit(goni_exit); + +/* Module information */ +MODULE_DESCRIPTION("ALSA SoC WM8994 GONI(S5PV210)"); +MODULE_AUTHOR("Chanwoo Choi "); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c new file mode 100644 index 000000000000..d6de3f0eeff8 --- /dev/null +++ b/sound/soc/samsung/i2s.c @@ -0,0 +1,1256 @@ +/* sound/soc/samsung/i2s.c + * + * ALSA SoC Audio Layer - Samsung I2S Controller driver + * + * Copyright (c) 2010 Samsung Electronics Co. Ltd. + * Jaswinder Singh + * + * 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 + +#include +#include +#include + +#include + +#include "dma.h" +#include "i2s.h" + +#define I2SCON 0x0 +#define I2SMOD 0x4 +#define I2SFIC 0x8 +#define I2SPSR 0xc +#define I2STXD 0x10 +#define I2SRXD 0x14 +#define I2SFICS 0x18 +#define I2STXDS 0x1c + +#define CON_RSTCLR (1 << 31) +#define CON_FRXOFSTATUS (1 << 26) +#define CON_FRXORINTEN (1 << 25) +#define CON_FTXSURSTAT (1 << 24) +#define CON_FTXSURINTEN (1 << 23) +#define CON_TXSDMA_PAUSE (1 << 20) +#define CON_TXSDMA_ACTIVE (1 << 18) + +#define CON_FTXURSTATUS (1 << 17) +#define CON_FTXURINTEN (1 << 16) +#define CON_TXFIFO2_EMPTY (1 << 15) +#define CON_TXFIFO1_EMPTY (1 << 14) +#define CON_TXFIFO2_FULL (1 << 13) +#define CON_TXFIFO1_FULL (1 << 12) + +#define CON_LRINDEX (1 << 11) +#define CON_TXFIFO_EMPTY (1 << 10) +#define CON_RXFIFO_EMPTY (1 << 9) +#define CON_TXFIFO_FULL (1 << 8) +#define CON_RXFIFO_FULL (1 << 7) +#define CON_TXDMA_PAUSE (1 << 6) +#define CON_RXDMA_PAUSE (1 << 5) +#define CON_TXCH_PAUSE (1 << 4) +#define CON_RXCH_PAUSE (1 << 3) +#define CON_TXDMA_ACTIVE (1 << 2) +#define CON_RXDMA_ACTIVE (1 << 1) +#define CON_ACTIVE (1 << 0) + +#define MOD_OPCLK_CDCLK_OUT (0 << 30) +#define MOD_OPCLK_CDCLK_IN (1 << 30) +#define MOD_OPCLK_BCLK_OUT (2 << 30) +#define MOD_OPCLK_PCLK (3 << 30) +#define MOD_OPCLK_MASK (3 << 30) +#define MOD_TXS_IDMA (1 << 28) /* Sec_TXFIFO use I-DMA */ + +#define MOD_BLCS_SHIFT 26 +#define MOD_BLCS_16BIT (0 << MOD_BLCS_SHIFT) +#define MOD_BLCS_8BIT (1 << MOD_BLCS_SHIFT) +#define MOD_BLCS_24BIT (2 << MOD_BLCS_SHIFT) +#define MOD_BLCS_MASK (3 << MOD_BLCS_SHIFT) +#define MOD_BLCP_SHIFT 24 +#define MOD_BLCP_16BIT (0 << MOD_BLCP_SHIFT) +#define MOD_BLCP_8BIT (1 << MOD_BLCP_SHIFT) +#define MOD_BLCP_24BIT (2 << MOD_BLCP_SHIFT) +#define MOD_BLCP_MASK (3 << MOD_BLCP_SHIFT) + +#define MOD_C2DD_HHALF (1 << 21) /* Discard Higher-half */ +#define MOD_C2DD_LHALF (1 << 20) /* Discard Lower-half */ +#define MOD_C1DD_HHALF (1 << 19) +#define MOD_C1DD_LHALF (1 << 18) +#define MOD_DC2_EN (1 << 17) +#define MOD_DC1_EN (1 << 16) +#define MOD_BLC_16BIT (0 << 13) +#define MOD_BLC_8BIT (1 << 13) +#define MOD_BLC_24BIT (2 << 13) +#define MOD_BLC_MASK (3 << 13) + +#define MOD_IMS_SYSMUX (1 << 10) +#define MOD_SLAVE (1 << 11) +#define MOD_TXONLY (0 << 8) +#define MOD_RXONLY (1 << 8) +#define MOD_TXRX (2 << 8) +#define MOD_MASK (3 << 8) +#define MOD_LR_LLOW (0 << 7) +#define MOD_LR_RLOW (1 << 7) +#define MOD_SDF_IIS (0 << 5) +#define MOD_SDF_MSB (1 << 5) +#define MOD_SDF_LSB (2 << 5) +#define MOD_SDF_MASK (3 << 5) +#define MOD_RCLK_256FS (0 << 3) +#define MOD_RCLK_512FS (1 << 3) +#define MOD_RCLK_384FS (2 << 3) +#define MOD_RCLK_768FS (3 << 3) +#define MOD_RCLK_MASK (3 << 3) +#define MOD_BCLK_32FS (0 << 1) +#define MOD_BCLK_48FS (1 << 1) +#define MOD_BCLK_16FS (2 << 1) +#define MOD_BCLK_24FS (3 << 1) +#define MOD_BCLK_MASK (3 << 1) +#define MOD_8BIT (1 << 0) + +#define MOD_CDCLKCON (1 << 12) + +#define PSR_PSREN (1 << 15) + +#define FIC_TX2COUNT(x) (((x) >> 24) & 0xf) +#define FIC_TX1COUNT(x) (((x) >> 16) & 0xf) + +#define FIC_TXFLUSH (1 << 15) +#define FIC_RXFLUSH (1 << 7) +#define FIC_TXCOUNT(x) (((x) >> 8) & 0xf) +#define FIC_RXCOUNT(x) (((x) >> 0) & 0xf) +#define FICS_TXCOUNT(x) (((x) >> 8) & 0x7f) + +#define msecs_to_loops(t) (loops_per_jiffy / 1000 * HZ * t) + +struct i2s_dai { + /* Platform device for this DAI */ + struct platform_device *pdev; + /* IOREMAP'd SFRs */ + void __iomem *addr; + /* Physical base address of SFRs */ + u32 base; + /* Rate of RCLK source clock */ + unsigned long rclk_srcrate; + /* Frame Clock */ + unsigned frmclk; + /* + * Specifically requested RCLK,BCLK by MACHINE Driver. + * 0 indicates CPU driver is free to choose any value. + */ + unsigned rfs, bfs; + /* I2S Controller's core clock */ + struct clk *clk; + /* Clock for generating I2S signals */ + struct clk *op_clk; + /* Array of clock names for op_clk */ + const char **src_clk; + /* Pointer to the Primary_Fifo if this is Sec_Fifo, NULL otherwise */ + struct i2s_dai *pri_dai; + /* Pointer to the Secondary_Fifo if it has one, NULL otherwise */ + struct i2s_dai *sec_dai; +#define DAI_OPENED (1 << 0) /* Dai is opened */ +#define DAI_MANAGER (1 << 1) /* Dai is the manager */ + unsigned mode; + /* Driver for this DAI */ + struct snd_soc_dai_driver i2s_dai_drv; + /* DMA parameters */ + struct s3c_dma_params dma_playback; + struct s3c_dma_params dma_capture; + u32 quirks; + u32 suspend_i2smod; + u32 suspend_i2scon; + u32 suspend_i2spsr; +}; + +/* Lock for cross i/f checks */ +static DEFINE_SPINLOCK(lock); + +/* If this is the 'overlay' stereo DAI */ +static inline bool is_secondary(struct i2s_dai *i2s) +{ + return i2s->pri_dai ? true : false; +} + +/* If operating in SoC-Slave mode */ +static inline bool is_slave(struct i2s_dai *i2s) +{ + return (readl(i2s->addr + I2SMOD) & MOD_SLAVE) ? true : false; +} + +/* If this interface of the controller is transmitting data */ +static inline bool tx_active(struct i2s_dai *i2s) +{ + u32 active; + + if (!i2s) + return false; + + active = readl(i2s->addr + I2SMOD); + + if (is_secondary(i2s)) + active &= CON_TXSDMA_ACTIVE; + else + active &= CON_TXDMA_ACTIVE; + + return active ? true : false; +} + +/* If the other interface of the controller is transmitting data */ +static inline bool other_tx_active(struct i2s_dai *i2s) +{ + struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai; + + return tx_active(other); +} + +/* If any interface of the controller is transmitting data */ +static inline bool any_tx_active(struct i2s_dai *i2s) +{ + return tx_active(i2s) || other_tx_active(i2s); +} + +/* If this interface of the controller is receiving data */ +static inline bool rx_active(struct i2s_dai *i2s) +{ + u32 active; + + if (!i2s) + return false; + + active = readl(i2s->addr + I2SMOD) & CON_RXDMA_ACTIVE; + + return active ? true : false; +} + +/* If the other interface of the controller is receiving data */ +static inline bool other_rx_active(struct i2s_dai *i2s) +{ + struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai; + + return rx_active(other); +} + +/* If any interface of the controller is receiving data */ +static inline bool any_rx_active(struct i2s_dai *i2s) +{ + return rx_active(i2s) || other_rx_active(i2s); +} + +/* If the other DAI is transmitting or receiving data */ +static inline bool other_active(struct i2s_dai *i2s) +{ + return other_rx_active(i2s) || other_tx_active(i2s); +} + +/* If this DAI is transmitting or receiving data */ +static inline bool this_active(struct i2s_dai *i2s) +{ + return tx_active(i2s) || rx_active(i2s); +} + +/* If the controller is active anyway */ +static inline bool any_active(struct i2s_dai *i2s) +{ + return this_active(i2s) || other_active(i2s); +} + +static inline struct i2s_dai *to_info(struct snd_soc_dai *dai) +{ + return snd_soc_dai_get_drvdata(dai); +} + +static inline bool is_opened(struct i2s_dai *i2s) +{ + if (i2s && (i2s->mode & DAI_OPENED)) + return true; + else + return false; +} + +static inline bool is_manager(struct i2s_dai *i2s) +{ + if (is_opened(i2s) && (i2s->mode & DAI_MANAGER)) + return true; + else + return false; +} + +/* Read RCLK of I2S (in multiples of LRCLK) */ +static inline unsigned get_rfs(struct i2s_dai *i2s) +{ + u32 rfs = (readl(i2s->addr + I2SMOD) >> 3) & 0x3; + + switch (rfs) { + case 3: return 768; + case 2: return 384; + case 1: return 512; + default: return 256; + } +} + +/* Write RCLK of I2S (in multiples of LRCLK) */ +static inline void set_rfs(struct i2s_dai *i2s, unsigned rfs) +{ + u32 mod = readl(i2s->addr + I2SMOD); + + mod &= ~MOD_RCLK_MASK; + + switch (rfs) { + case 768: + mod |= MOD_RCLK_768FS; + break; + case 512: + mod |= MOD_RCLK_512FS; + break; + case 384: + mod |= MOD_RCLK_384FS; + break; + default: + mod |= MOD_RCLK_256FS; + break; + } + + writel(mod, i2s->addr + I2SMOD); +} + +/* Read Bit-Clock of I2S (in multiples of LRCLK) */ +static inline unsigned get_bfs(struct i2s_dai *i2s) +{ + u32 bfs = (readl(i2s->addr + I2SMOD) >> 1) & 0x3; + + switch (bfs) { + case 3: return 24; + case 2: return 16; + case 1: return 48; + default: return 32; + } +} + +/* Write Bit-Clock of I2S (in multiples of LRCLK) */ +static inline void set_bfs(struct i2s_dai *i2s, unsigned bfs) +{ + u32 mod = readl(i2s->addr + I2SMOD); + + mod &= ~MOD_BCLK_MASK; + + switch (bfs) { + case 48: + mod |= MOD_BCLK_48FS; + break; + case 32: + mod |= MOD_BCLK_32FS; + break; + case 24: + mod |= MOD_BCLK_24FS; + break; + case 16: + mod |= MOD_BCLK_16FS; + break; + default: + dev_err(&i2s->pdev->dev, "Wrong BCLK Divider!\n"); + return; + } + + writel(mod, i2s->addr + I2SMOD); +} + +/* Sample-Size */ +static inline int get_blc(struct i2s_dai *i2s) +{ + int blc = readl(i2s->addr + I2SMOD); + + blc = (blc >> 13) & 0x3; + + switch (blc) { + case 2: return 24; + case 1: return 8; + default: return 16; + } +} + +/* TX Channel Control */ +static void i2s_txctrl(struct i2s_dai *i2s, int on) +{ + void __iomem *addr = i2s->addr; + u32 con = readl(addr + I2SCON); + u32 mod = readl(addr + I2SMOD) & ~MOD_MASK; + + if (on) { + con |= CON_ACTIVE; + con &= ~CON_TXCH_PAUSE; + + if (is_secondary(i2s)) { + con |= CON_TXSDMA_ACTIVE; + con &= ~CON_TXSDMA_PAUSE; + } else { + con |= CON_TXDMA_ACTIVE; + con &= ~CON_TXDMA_PAUSE; + } + + if (any_rx_active(i2s)) + mod |= MOD_TXRX; + else + mod |= MOD_TXONLY; + } else { + if (is_secondary(i2s)) { + con |= CON_TXSDMA_PAUSE; + con &= ~CON_TXSDMA_ACTIVE; + } else { + con |= CON_TXDMA_PAUSE; + con &= ~CON_TXDMA_ACTIVE; + } + + if (other_tx_active(i2s)) { + writel(con, addr + I2SCON); + return; + } + + con |= CON_TXCH_PAUSE; + + if (any_rx_active(i2s)) + mod |= MOD_RXONLY; + else + con &= ~CON_ACTIVE; + } + + writel(mod, addr + I2SMOD); + writel(con, addr + I2SCON); +} + +/* RX Channel Control */ +static void i2s_rxctrl(struct i2s_dai *i2s, int on) +{ + void __iomem *addr = i2s->addr; + u32 con = readl(addr + I2SCON); + u32 mod = readl(addr + I2SMOD) & ~MOD_MASK; + + if (on) { + con |= CON_RXDMA_ACTIVE | CON_ACTIVE; + con &= ~(CON_RXDMA_PAUSE | CON_RXCH_PAUSE); + + if (any_tx_active(i2s)) + mod |= MOD_TXRX; + else + mod |= MOD_RXONLY; + } else { + con |= CON_RXDMA_PAUSE | CON_RXCH_PAUSE; + con &= ~CON_RXDMA_ACTIVE; + + if (any_tx_active(i2s)) + mod |= MOD_TXONLY; + else + con &= ~CON_ACTIVE; + } + + writel(mod, addr + I2SMOD); + writel(con, addr + I2SCON); +} + +/* Flush FIFO of an interface */ +static inline void i2s_fifo(struct i2s_dai *i2s, u32 flush) +{ + void __iomem *fic; + u32 val; + + if (!i2s) + return; + + if (is_secondary(i2s)) + fic = i2s->addr + I2SFICS; + else + fic = i2s->addr + I2SFIC; + + /* Flush the FIFO */ + writel(readl(fic) | flush, fic); + + /* Be patient */ + val = msecs_to_loops(1) / 1000; /* 1 usec */ + while (--val) + cpu_relax(); + + writel(readl(fic) & ~flush, fic); +} + +static int i2s_set_sysclk(struct snd_soc_dai *dai, + int clk_id, unsigned int rfs, int dir) +{ + struct i2s_dai *i2s = to_info(dai); + struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai; + u32 mod = readl(i2s->addr + I2SMOD); + + switch (clk_id) { + case SAMSUNG_I2S_CDCLK: + /* Shouldn't matter in GATING(CLOCK_IN) mode */ + if (dir == SND_SOC_CLOCK_IN) + rfs = 0; + + if ((rfs && other->rfs && (other->rfs != rfs)) || + (any_active(i2s) && + (((dir == SND_SOC_CLOCK_IN) + && !(mod & MOD_CDCLKCON)) || + ((dir == SND_SOC_CLOCK_OUT) + && (mod & MOD_CDCLKCON))))) { + dev_err(&i2s->pdev->dev, + "%s:%d Other DAI busy\n", __func__, __LINE__); + return -EAGAIN; + } + + if (dir == SND_SOC_CLOCK_IN) + mod |= MOD_CDCLKCON; + else + mod &= ~MOD_CDCLKCON; + + i2s->rfs = rfs; + break; + + case SAMSUNG_I2S_RCLKSRC_0: /* clock corrsponding to IISMOD[10] := 0 */ + case SAMSUNG_I2S_RCLKSRC_1: /* clock corrsponding to IISMOD[10] := 1 */ + if ((i2s->quirks & QUIRK_NO_MUXPSR) + || (clk_id == SAMSUNG_I2S_RCLKSRC_0)) + clk_id = 0; + else + clk_id = 1; + + if (!any_active(i2s)) { + if (i2s->op_clk) { + if ((clk_id && !(mod & MOD_IMS_SYSMUX)) || + (!clk_id && (mod & MOD_IMS_SYSMUX))) { + clk_disable(i2s->op_clk); + clk_put(i2s->op_clk); + } else { + return 0; + } + } + + i2s->op_clk = clk_get(&i2s->pdev->dev, + i2s->src_clk[clk_id]); + clk_enable(i2s->op_clk); + i2s->rclk_srcrate = clk_get_rate(i2s->op_clk); + + /* Over-ride the other's */ + if (other) { + other->op_clk = i2s->op_clk; + other->rclk_srcrate = i2s->rclk_srcrate; + } + } else if ((!clk_id && (mod & MOD_IMS_SYSMUX)) + || (clk_id && !(mod & MOD_IMS_SYSMUX))) { + dev_err(&i2s->pdev->dev, + "%s:%d Other DAI busy\n", __func__, __LINE__); + return -EAGAIN; + } else { + /* Call can't be on the active DAI */ + i2s->op_clk = other->op_clk; + i2s->rclk_srcrate = other->rclk_srcrate; + return 0; + } + + if (clk_id == 0) + mod &= ~MOD_IMS_SYSMUX; + else + mod |= MOD_IMS_SYSMUX; + break; + + default: + dev_err(&i2s->pdev->dev, "We don't serve that!\n"); + return -EINVAL; + } + + writel(mod, i2s->addr + I2SMOD); + + return 0; +} + +static int i2s_set_fmt(struct snd_soc_dai *dai, + unsigned int fmt) +{ + struct i2s_dai *i2s = to_info(dai); + u32 mod = readl(i2s->addr + I2SMOD); + u32 tmp = 0; + + /* Format is priority */ + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { + case SND_SOC_DAIFMT_RIGHT_J: + tmp |= MOD_LR_RLOW; + tmp |= MOD_SDF_MSB; + break; + case SND_SOC_DAIFMT_LEFT_J: + tmp |= MOD_LR_RLOW; + tmp |= MOD_SDF_LSB; + break; + case SND_SOC_DAIFMT_I2S: + tmp |= MOD_SDF_IIS; + break; + default: + dev_err(&i2s->pdev->dev, "Format not supported\n"); + return -EINVAL; + } + + /* + * INV flag is relative to the FORMAT flag - if set it simply + * flips the polarity specified by the Standard + */ + switch (fmt & SND_SOC_DAIFMT_INV_MASK) { + case SND_SOC_DAIFMT_NB_NF: + break; + case SND_SOC_DAIFMT_NB_IF: + if (tmp & MOD_LR_RLOW) + tmp &= ~MOD_LR_RLOW; + else + tmp |= MOD_LR_RLOW; + break; + default: + dev_err(&i2s->pdev->dev, "Polarity not supported\n"); + return -EINVAL; + } + + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { + case SND_SOC_DAIFMT_CBM_CFM: + tmp |= MOD_SLAVE; + break; + case SND_SOC_DAIFMT_CBS_CFS: + /* Set default source clock in Master mode */ + if (i2s->rclk_srcrate == 0) + i2s_set_sysclk(dai, SAMSUNG_I2S_RCLKSRC_0, + 0, SND_SOC_CLOCK_IN); + break; + default: + dev_err(&i2s->pdev->dev, "master/slave format not supported\n"); + return -EINVAL; + } + + if (any_active(i2s) && + ((mod & (MOD_SDF_MASK | MOD_LR_RLOW + | MOD_SLAVE)) != tmp)) { + dev_err(&i2s->pdev->dev, + "%s:%d Other DAI busy\n", __func__, __LINE__); + return -EAGAIN; + } + + mod &= ~(MOD_SDF_MASK | MOD_LR_RLOW | MOD_SLAVE); + mod |= tmp; + writel(mod, i2s->addr + I2SMOD); + + return 0; +} + +static int i2s_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) +{ + struct i2s_dai *i2s = to_info(dai); + u32 mod = readl(i2s->addr + I2SMOD); + + if (!is_secondary(i2s)) + mod &= ~(MOD_DC2_EN | MOD_DC1_EN); + + switch (params_channels(params)) { + case 6: + mod |= MOD_DC2_EN; + case 4: + mod |= MOD_DC1_EN; + break; + case 2: + break; + default: + dev_err(&i2s->pdev->dev, "%d channels not supported\n", + params_channels(params)); + return -EINVAL; + } + + if (is_secondary(i2s)) + mod &= ~MOD_BLCS_MASK; + else + mod &= ~MOD_BLCP_MASK; + + if (is_manager(i2s)) + mod &= ~MOD_BLC_MASK; + + switch (params_format(params)) { + case SNDRV_PCM_FORMAT_S8: + if (is_secondary(i2s)) + mod |= MOD_BLCS_8BIT; + else + mod |= MOD_BLCP_8BIT; + if (is_manager(i2s)) + mod |= MOD_BLC_8BIT; + break; + case SNDRV_PCM_FORMAT_S16_LE: + if (is_secondary(i2s)) + mod |= MOD_BLCS_16BIT; + else + mod |= MOD_BLCP_16BIT; + if (is_manager(i2s)) + mod |= MOD_BLC_16BIT; + break; + case SNDRV_PCM_FORMAT_S24_LE: + if (is_secondary(i2s)) + mod |= MOD_BLCS_24BIT; + else + mod |= MOD_BLCP_24BIT; + if (is_manager(i2s)) + mod |= MOD_BLC_24BIT; + break; + default: + dev_err(&i2s->pdev->dev, "Format(%d) not supported\n", + params_format(params)); + return -EINVAL; + } + writel(mod, i2s->addr + I2SMOD); + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + snd_soc_dai_set_dma_data(dai, substream, + (void *)&i2s->dma_playback); + else + snd_soc_dai_set_dma_data(dai, substream, + (void *)&i2s->dma_capture); + + i2s->frmclk = params_rate(params); + + return 0; +} + +/* We set constraints on the substream acc to the version of I2S */ +static int i2s_startup(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct i2s_dai *i2s = to_info(dai); + struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai; + unsigned long flags; + + spin_lock_irqsave(&lock, flags); + + i2s->mode |= DAI_OPENED; + + if (is_manager(other)) + i2s->mode &= ~DAI_MANAGER; + else + i2s->mode |= DAI_MANAGER; + + /* Enforce set_sysclk in Master mode */ + i2s->rclk_srcrate = 0; + + spin_unlock_irqrestore(&lock, flags); + + return 0; +} + +static void i2s_shutdown(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct i2s_dai *i2s = to_info(dai); + struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai; + unsigned long flags; + + spin_lock_irqsave(&lock, flags); + + i2s->mode &= ~DAI_OPENED; + i2s->mode &= ~DAI_MANAGER; + + if (is_opened(other)) + other->mode |= DAI_MANAGER; + + /* Reset any constraint on RFS and BFS */ + i2s->rfs = 0; + i2s->bfs = 0; + + spin_unlock_irqrestore(&lock, flags); + + /* Gate CDCLK by default */ + if (!is_opened(other)) + i2s_set_sysclk(dai, SAMSUNG_I2S_CDCLK, + 0, SND_SOC_CLOCK_IN); +} + +static int config_setup(struct i2s_dai *i2s) +{ + struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai; + unsigned rfs, bfs, blc; + u32 psr; + + blc = get_blc(i2s); + + bfs = i2s->bfs; + + if (!bfs && other) + bfs = other->bfs; + + /* Select least possible multiple(2) if no constraint set */ + if (!bfs) + bfs = blc * 2; + + rfs = i2s->rfs; + + if (!rfs && other) + rfs = other->rfs; + + if ((rfs == 256 || rfs == 512) && (blc == 24)) { + dev_err(&i2s->pdev->dev, + "%d-RFS not supported for 24-blc\n", rfs); + return -EINVAL; + } + + if (!rfs) { + if (bfs == 16 || bfs == 32) + rfs = 256; + else + rfs = 384; + } + + /* If already setup and running */ + if (any_active(i2s) && (get_rfs(i2s) != rfs || get_bfs(i2s) != bfs)) { + dev_err(&i2s->pdev->dev, + "%s:%d Other DAI busy\n", __func__, __LINE__); + return -EAGAIN; + } + + /* Don't bother RFS, BFS & PSR in Slave mode */ + if (is_slave(i2s)) + return 0; + + set_bfs(i2s, bfs); + set_rfs(i2s, rfs); + + if (!(i2s->quirks & QUIRK_NO_MUXPSR)) { + psr = i2s->rclk_srcrate / i2s->frmclk / rfs; + writel(((psr - 1) << 8) | PSR_PSREN, i2s->addr + I2SPSR); + dev_dbg(&i2s->pdev->dev, + "RCLK_SRC=%luHz PSR=%u, RCLK=%dfs, BCLK=%dfs\n", + i2s->rclk_srcrate, psr, rfs, bfs); + } + + return 0; +} + +static int i2s_trigger(struct snd_pcm_substream *substream, + int cmd, struct snd_soc_dai *dai) +{ + int capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE); + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct i2s_dai *i2s = to_info(rtd->cpu_dai); + unsigned long flags; + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + case SNDRV_PCM_TRIGGER_RESUME: + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: + local_irq_save(flags); + + if (capture) + i2s_fifo(i2s, FIC_RXFLUSH); + else + i2s_fifo(i2s, FIC_TXFLUSH); + + if (config_setup(i2s)) { + local_irq_restore(flags); + return -EINVAL; + } + + if (capture) + i2s_rxctrl(i2s, 1); + else + i2s_txctrl(i2s, 1); + + local_irq_restore(flags); + break; + case SNDRV_PCM_TRIGGER_STOP: + case SNDRV_PCM_TRIGGER_SUSPEND: + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + local_irq_save(flags); + + if (capture) + i2s_rxctrl(i2s, 0); + else + i2s_txctrl(i2s, 0); + + local_irq_restore(flags); + break; + } + + return 0; +} + +static int i2s_set_clkdiv(struct snd_soc_dai *dai, + int div_id, int div) +{ + struct i2s_dai *i2s = to_info(dai); + struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai; + + switch (div_id) { + case SAMSUNG_I2S_DIV_BCLK: + if ((any_active(i2s) && div && (get_bfs(i2s) != div)) + || (other && other->bfs && (other->bfs != div))) { + dev_err(&i2s->pdev->dev, + "%s:%d Other DAI busy\n", __func__, __LINE__); + return -EAGAIN; + } + i2s->bfs = div; + break; + default: + dev_err(&i2s->pdev->dev, + "Invalid clock divider(%d)\n", div_id); + return -EINVAL; + } + + return 0; +} + +static snd_pcm_sframes_t +i2s_delay(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) +{ + struct i2s_dai *i2s = to_info(dai); + u32 reg = readl(i2s->addr + I2SFIC); + snd_pcm_sframes_t delay; + + if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) + delay = FIC_RXCOUNT(reg); + else if (is_secondary(i2s)) + delay = FICS_TXCOUNT(readl(i2s->addr + I2SFICS)); + else + delay = FIC_TXCOUNT(reg); + + return delay; +} + +#ifdef CONFIG_PM +static int i2s_suspend(struct snd_soc_dai *dai) +{ + struct i2s_dai *i2s = to_info(dai); + + if (dai->active) { + i2s->suspend_i2smod = readl(i2s->addr + I2SMOD); + i2s->suspend_i2scon = readl(i2s->addr + I2SCON); + i2s->suspend_i2spsr = readl(i2s->addr + I2SPSR); + } + + return 0; +} + +static int i2s_resume(struct snd_soc_dai *dai) +{ + struct i2s_dai *i2s = to_info(dai); + + if (dai->active) { + writel(i2s->suspend_i2scon, i2s->addr + I2SCON); + writel(i2s->suspend_i2smod, i2s->addr + I2SMOD); + writel(i2s->suspend_i2spsr, i2s->addr + I2SPSR); + } + + return 0; +} +#else +#define i2s_suspend NULL +#define i2s_resume NULL +#endif + +static int samsung_i2s_dai_probe(struct snd_soc_dai *dai) +{ + struct i2s_dai *i2s = to_info(dai); + struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai; + + if (other && other->clk) /* If this is probe on secondary */ + goto probe_exit; + + i2s->addr = ioremap(i2s->base, 0x100); + if (i2s->addr == NULL) { + dev_err(&i2s->pdev->dev, "cannot ioremap registers\n"); + return -ENXIO; + } + + i2s->clk = clk_get(&i2s->pdev->dev, "iis"); + if (IS_ERR(i2s->clk)) { + dev_err(&i2s->pdev->dev, "failed to get i2s_clock\n"); + iounmap(i2s->addr); + return -ENOENT; + } + clk_enable(i2s->clk); + + if (other) { + other->addr = i2s->addr; + other->clk = i2s->clk; + } + + if (i2s->quirks & QUIRK_NEED_RSTCLR) + writel(CON_RSTCLR, i2s->addr + I2SCON); + +probe_exit: + /* Reset any constraint on RFS and BFS */ + i2s->rfs = 0; + i2s->bfs = 0; + i2s_txctrl(i2s, 0); + i2s_rxctrl(i2s, 0); + i2s_fifo(i2s, FIC_TXFLUSH); + i2s_fifo(other, FIC_TXFLUSH); + i2s_fifo(i2s, FIC_RXFLUSH); + + /* Gate CDCLK by default */ + if (!is_opened(other)) + i2s_set_sysclk(dai, SAMSUNG_I2S_CDCLK, + 0, SND_SOC_CLOCK_IN); + + return 0; +} + +static int samsung_i2s_dai_remove(struct snd_soc_dai *dai) +{ + struct i2s_dai *i2s = snd_soc_dai_get_drvdata(dai); + struct i2s_dai *other = i2s->pri_dai ? : i2s->sec_dai; + + if (!other || !other->clk) { + + if (i2s->quirks & QUIRK_NEED_RSTCLR) + writel(0, i2s->addr + I2SCON); + + clk_disable(i2s->clk); + clk_put(i2s->clk); + + iounmap(i2s->addr); + } + + i2s->clk = NULL; + + return 0; +} + +static struct snd_soc_dai_ops samsung_i2s_dai_ops = { + .trigger = i2s_trigger, + .hw_params = i2s_hw_params, + .set_fmt = i2s_set_fmt, + .set_clkdiv = i2s_set_clkdiv, + .set_sysclk = i2s_set_sysclk, + .startup = i2s_startup, + .shutdown = i2s_shutdown, + .delay = i2s_delay, +}; + +#define SAMSUNG_I2S_RATES SNDRV_PCM_RATE_8000_96000 + +#define SAMSUNG_I2S_FMTS (SNDRV_PCM_FMTBIT_S8 | \ + SNDRV_PCM_FMTBIT_S16_LE | \ + SNDRV_PCM_FMTBIT_S24_LE) + +static __devinit +struct i2s_dai *i2s_alloc_dai(struct platform_device *pdev, bool sec) +{ + struct i2s_dai *i2s; + + i2s = kzalloc(sizeof(struct i2s_dai), GFP_KERNEL); + if (i2s == NULL) + return NULL; + + i2s->pdev = pdev; + i2s->pri_dai = NULL; + i2s->sec_dai = NULL; + i2s->i2s_dai_drv.symmetric_rates = 1; + i2s->i2s_dai_drv.probe = samsung_i2s_dai_probe; + i2s->i2s_dai_drv.remove = samsung_i2s_dai_remove; + i2s->i2s_dai_drv.ops = &samsung_i2s_dai_ops; + i2s->i2s_dai_drv.suspend = i2s_suspend; + i2s->i2s_dai_drv.resume = i2s_resume; + i2s->i2s_dai_drv.playback.channels_min = 2; + i2s->i2s_dai_drv.playback.channels_max = 2; + i2s->i2s_dai_drv.playback.rates = SAMSUNG_I2S_RATES; + i2s->i2s_dai_drv.playback.formats = SAMSUNG_I2S_FMTS; + + if (!sec) { + i2s->i2s_dai_drv.capture.channels_min = 2; + i2s->i2s_dai_drv.capture.channels_max = 2; + i2s->i2s_dai_drv.capture.rates = SAMSUNG_I2S_RATES; + i2s->i2s_dai_drv.capture.formats = SAMSUNG_I2S_FMTS; + } else { /* Create a new platform_device for Secondary */ + i2s->pdev = platform_device_register_resndata(NULL, + pdev->name, pdev->id + SAMSUNG_I2S_SECOFF, + NULL, 0, NULL, 0); + if (IS_ERR(i2s->pdev)) { + kfree(i2s); + return NULL; + } + } + + /* Pre-assign snd_soc_dai_set_drvdata */ + dev_set_drvdata(&i2s->pdev->dev, i2s); + + return i2s; +} + +static __devinit int samsung_i2s_probe(struct platform_device *pdev) +{ + u32 dma_pl_chan, dma_cp_chan, dma_pl_sec_chan; + struct i2s_dai *pri_dai, *sec_dai = NULL; + struct s3c_audio_pdata *i2s_pdata; + struct samsung_i2s *i2s_cfg; + struct resource *res; + u32 regs_base, quirks; + int ret = 0; + + /* Call during Seconday interface registration */ + if (pdev->id >= SAMSUNG_I2S_SECOFF) { + sec_dai = dev_get_drvdata(&pdev->dev); + snd_soc_register_dai(&sec_dai->pdev->dev, + &sec_dai->i2s_dai_drv); + return 0; + } + + i2s_pdata = pdev->dev.platform_data; + if (i2s_pdata == NULL) { + dev_err(&pdev->dev, "Can't work without s3c_audio_pdata\n"); + return -EINVAL; + } + + res = platform_get_resource(pdev, IORESOURCE_DMA, 0); + if (!res) { + dev_err(&pdev->dev, "Unable to get I2S-TX dma resource\n"); + return -ENXIO; + } + dma_pl_chan = res->start; + + res = platform_get_resource(pdev, IORESOURCE_DMA, 1); + if (!res) { + dev_err(&pdev->dev, "Unable to get I2S-RX dma resource\n"); + return -ENXIO; + } + dma_cp_chan = res->start; + + res = platform_get_resource(pdev, IORESOURCE_DMA, 2); + if (res) + dma_pl_sec_chan = res->start; + else + dma_pl_sec_chan = 0; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + dev_err(&pdev->dev, "Unable to get I2S SFR address\n"); + return -ENXIO; + } + + if (!request_mem_region(res->start, resource_size(res), + "samsung-i2s")) { + dev_err(&pdev->dev, "Unable to request SFR region\n"); + return -EBUSY; + } + regs_base = res->start; + + i2s_cfg = &i2s_pdata->type.i2s; + quirks = i2s_cfg->quirks; + + pri_dai = i2s_alloc_dai(pdev, false); + if (!pri_dai) { + dev_err(&pdev->dev, "Unable to alloc I2S_pri\n"); + ret = -ENOMEM; + goto err1; + } + + pri_dai->dma_playback.dma_addr = regs_base + I2STXD; + pri_dai->dma_capture.dma_addr = regs_base + I2SRXD; + pri_dai->dma_playback.client = + (struct s3c2410_dma_client *)&pri_dai->dma_playback; + pri_dai->dma_capture.client = + (struct s3c2410_dma_client *)&pri_dai->dma_capture; + pri_dai->dma_playback.channel = dma_pl_chan; + pri_dai->dma_capture.channel = dma_cp_chan; + pri_dai->src_clk = i2s_cfg->src_clk; + pri_dai->dma_playback.dma_size = 4; + pri_dai->dma_capture.dma_size = 4; + pri_dai->base = regs_base; + pri_dai->quirks = quirks; + + if (quirks & QUIRK_PRI_6CHAN) + pri_dai->i2s_dai_drv.playback.channels_max = 6; + + if (quirks & QUIRK_SEC_DAI) { + sec_dai = i2s_alloc_dai(pdev, true); + if (!sec_dai) { + dev_err(&pdev->dev, "Unable to alloc I2S_sec\n"); + ret = -ENOMEM; + goto err2; + } + sec_dai->dma_playback.dma_addr = regs_base + I2STXDS; + sec_dai->dma_playback.client = + (struct s3c2410_dma_client *)&sec_dai->dma_playback; + /* Use iDMA always if SysDMA not provided */ + sec_dai->dma_playback.channel = dma_pl_sec_chan ? : -1; + sec_dai->src_clk = i2s_cfg->src_clk; + sec_dai->dma_playback.dma_size = 4; + sec_dai->base = regs_base; + sec_dai->quirks = quirks; + sec_dai->pri_dai = pri_dai; + pri_dai->sec_dai = sec_dai; + } + + if (i2s_pdata->cfg_gpio && i2s_pdata->cfg_gpio(pdev)) { + dev_err(&pdev->dev, "Unable to configure gpio\n"); + ret = -EINVAL; + goto err3; + } + + snd_soc_register_dai(&pri_dai->pdev->dev, &pri_dai->i2s_dai_drv); + + return 0; +err3: + kfree(sec_dai); +err2: + kfree(pri_dai); +err1: + release_mem_region(regs_base, resource_size(res)); + + return ret; +} + +static __devexit int samsung_i2s_remove(struct platform_device *pdev) +{ + struct i2s_dai *i2s, *other; + + i2s = dev_get_drvdata(&pdev->dev); + other = i2s->pri_dai ? : i2s->sec_dai; + + if (other) { + other->pri_dai = NULL; + other->sec_dai = NULL; + } else { + struct resource *res; + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (res) + release_mem_region(res->start, resource_size(res)); + } + + i2s->pri_dai = NULL; + i2s->sec_dai = NULL; + + kfree(i2s); + + snd_soc_unregister_dai(&pdev->dev); + + return 0; +} + +static struct platform_driver samsung_i2s_driver = { + .probe = samsung_i2s_probe, + .remove = samsung_i2s_remove, + .driver = { + .name = "samsung-i2s", + .owner = THIS_MODULE, + }, +}; + +static int __init samsung_i2s_init(void) +{ + return platform_driver_register(&samsung_i2s_driver); +} +module_init(samsung_i2s_init); + +static void __exit samsung_i2s_exit(void) +{ + platform_driver_unregister(&samsung_i2s_driver); +} +module_exit(samsung_i2s_exit); + +/* Module information */ +MODULE_AUTHOR("Jaswinder Singh, "); +MODULE_DESCRIPTION("Samsung I2S Interface"); +MODULE_ALIAS("platform:samsung-i2s"); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/samsung/i2s.h b/sound/soc/samsung/i2s.h new file mode 100644 index 000000000000..8e15f6a616d1 --- /dev/null +++ b/sound/soc/samsung/i2s.h @@ -0,0 +1,29 @@ +/* sound/soc/samsung/i2s.h + * + * ALSA SoC Audio Layer - Samsung I2S Controller driver + * + * Copyright (c) 2010 Samsung Electronics Co. Ltd. + * Jaswinder Singh + * + * 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. + */ + +#ifndef __SND_SOC_SAMSUNG_I2S_H +#define __SND_SOC_SAMSUNG_I2S_H + +/* + * Maximum number of I2S blocks that any SoC can have. + * The secondary interface of a CPU dai(if there exists any), + * is indexed at [cpu-dai's ID + SAMSUNG_I2S_SECOFF] + */ +#define SAMSUNG_I2S_SECOFF 4 + +#define SAMSUNG_I2S_DIV_BCLK 1 + +#define SAMSUNG_I2S_RCLKSRC_0 0 +#define SAMSUNG_I2S_RCLKSRC_1 1 +#define SAMSUNG_I2S_CDCLK 2 + +#endif /* __SND_SOC_SAMSUNG_I2S_H */ diff --git a/sound/soc/samsung/jive_wm8750.c b/sound/soc/samsung/jive_wm8750.c new file mode 100644 index 000000000000..08802520e014 --- /dev/null +++ b/sound/soc/samsung/jive_wm8750.c @@ -0,0 +1,191 @@ +/* sound/soc/samsung/jive_wm8750.c + * + * Copyright 2007,2008 Simtec Electronics + * + * Based on sound/soc/pxa/spitz.c + * Copyright 2005 Wolfson Microelectronics PLC. + * Copyright 2005 Openedhand Ltd. + * + * 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 +#include +#include + +#include +#include +#include + +#include + +#include "dma.h" +#include "s3c2412-i2s.h" + +#include "../codecs/wm8750.h" + +static const struct snd_soc_dapm_route audio_map[] = { + { "Headphone Jack", NULL, "LOUT1" }, + { "Headphone Jack", NULL, "ROUT1" }, + { "Internal Speaker", NULL, "LOUT2" }, + { "Internal Speaker", NULL, "ROUT2" }, + { "LINPUT1", NULL, "Line Input" }, + { "RINPUT1", NULL, "Line Input" }, +}; + +static const struct snd_soc_dapm_widget wm8750_dapm_widgets[] = { + SND_SOC_DAPM_HP("Headphone Jack", NULL), + SND_SOC_DAPM_SPK("Internal Speaker", NULL), + SND_SOC_DAPM_LINE("Line In", NULL), +}; + +static int jive_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *codec_dai = rtd->codec_dai; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + struct s3c_i2sv2_rate_calc div; + unsigned int clk = 0; + int ret = 0; + + switch (params_rate(params)) { + case 8000: + case 16000: + case 48000: + case 96000: + clk = 12288000; + break; + case 11025: + case 22050: + case 44100: + clk = 11289600; + break; + } + + s3c_i2sv2_iis_calc_rate(&div, NULL, params_rate(params), + s3c_i2sv2_get_clock(cpu_dai)); + + /* set codec DAI configuration */ + ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | + SND_SOC_DAIFMT_NB_NF | + SND_SOC_DAIFMT_CBS_CFS); + if (ret < 0) + return ret; + + /* set cpu DAI configuration */ + ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S | + SND_SOC_DAIFMT_NB_NF | + SND_SOC_DAIFMT_CBS_CFS); + if (ret < 0) + return ret; + + /* set the codec system clock for DAC and ADC */ + ret = snd_soc_dai_set_sysclk(codec_dai, WM8750_SYSCLK, clk, + SND_SOC_CLOCK_IN); + if (ret < 0) + return ret; + + ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C2412_DIV_RCLK, div.fs_div); + if (ret < 0) + return ret; + + ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C2412_DIV_PRESCALER, + div.clk_div - 1); + if (ret < 0) + return ret; + + return 0; +} + +static struct snd_soc_ops jive_ops = { + .hw_params = jive_hw_params, +}; + +static int jive_wm8750_init(struct snd_soc_pcm_runtime *rtd) +{ + struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_dapm_context *dapm = &codec->dapm; + int err; + + /* These endpoints are not being used. */ + snd_soc_dapm_nc_pin(dapm, "LINPUT2"); + snd_soc_dapm_nc_pin(dapm, "RINPUT2"); + snd_soc_dapm_nc_pin(dapm, "LINPUT3"); + snd_soc_dapm_nc_pin(dapm, "RINPUT3"); + snd_soc_dapm_nc_pin(dapm, "OUT3"); + snd_soc_dapm_nc_pin(dapm, "MONO"); + + /* Add jive specific widgets */ + err = snd_soc_dapm_new_controls(dapm, wm8750_dapm_widgets, + ARRAY_SIZE(wm8750_dapm_widgets)); + if (err) { + printk(KERN_ERR "%s: failed to add widgets (%d)\n", + __func__, err); + return err; + } + + snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); + snd_soc_dapm_sync(dapm); + + return 0; +} + +static struct snd_soc_dai_link jive_dai = { + .name = "wm8750", + .stream_name = "WM8750", + .cpu_dai_name = "s3c2412-i2s", + .codec_dai_name = "wm8750-hifi", + .platform_name = "samsung-audio", + .codec_name = "wm8750-codec.0-0x1a", + .init = jive_wm8750_init, + .ops = &jive_ops, +}; + +/* jive audio machine driver */ +static struct snd_soc_card snd_soc_machine_jive = { + .name = "Jive", + .dai_link = &jive_dai, + .num_links = 1, +}; + +static struct platform_device *jive_snd_device; + +static int __init jive_init(void) +{ + int ret; + + if (!machine_is_jive()) + return 0; + + printk("JIVE WM8750 Audio support\n"); + + jive_snd_device = platform_device_alloc("soc-audio", -1); + if (!jive_snd_device) + return -ENOMEM; + + platform_set_drvdata(jive_snd_device, &snd_soc_machine_jive); + ret = platform_device_add(jive_snd_device); + + if (ret) + platform_device_put(jive_snd_device); + + return ret; +} + +static void __exit jive_exit(void) +{ + platform_device_unregister(jive_snd_device); +} + +module_init(jive_init); +module_exit(jive_exit); + +MODULE_AUTHOR("Ben Dooks "); +MODULE_DESCRIPTION("ALSA SoC Jive Audio support"); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/samsung/lm4857.h b/sound/soc/samsung/lm4857.h new file mode 100644 index 000000000000..0cf5b7011d6f --- /dev/null +++ b/sound/soc/samsung/lm4857.h @@ -0,0 +1,32 @@ +/* + * lm4857.h -- ALSA Soc Audio Layer + * + * Copyright 2007 Wolfson Microelectronics PLC. + * Author: Graeme Gregory + * graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com + * + * 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. + * + * Revision history + * 18th Jun 2007 Initial version. + */ + +#ifndef LM4857_H_ +#define LM4857_H_ + +/* The register offsets in the cache array */ +#define LM4857_MVOL 0 +#define LM4857_LVOL 1 +#define LM4857_RVOL 2 +#define LM4857_CTRL 3 + +/* the shifts required to set these bits */ +#define LM4857_3D 5 +#define LM4857_WAKEUP 5 +#define LM4857_EPGAIN 4 + +#endif /*LM4857_H_*/ + diff --git a/sound/soc/samsung/ln2440sbc_alc650.c b/sound/soc/samsung/ln2440sbc_alc650.c new file mode 100644 index 000000000000..a2bb34def740 --- /dev/null +++ b/sound/soc/samsung/ln2440sbc_alc650.c @@ -0,0 +1,77 @@ +/* + * SoC audio for ln2440sbc + * + * Copyright 2007 KonekTel, a.s. + * Author: Ivan Kuten + * ivan.kuten@promwad.com + * + * Heavily based on smdk2443_wm9710.c + * Copyright 2007 Wolfson Microelectronics PLC. + * Author: Graeme Gregory + * graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com + * + * 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 +#include + +#include "dma.h" +#include "ac97.h" + +static struct snd_soc_card ln2440sbc; + +static struct snd_soc_dai_link ln2440sbc_dai[] = { +{ + .name = "AC97", + .stream_name = "AC97 HiFi", + .cpu_dai_name = "samsung-ac97", + .codec_dai_name = "ac97-hifi", + .codec_name = "ac97-codec", + .platform_name = "samsung-audio", +}, +}; + +static struct snd_soc_card ln2440sbc = { + .name = "LN2440SBC", + .dai_link = ln2440sbc_dai, + .num_links = ARRAY_SIZE(ln2440sbc_dai), +}; + +static struct platform_device *ln2440sbc_snd_ac97_device; + +static int __init ln2440sbc_init(void) +{ + int ret; + + ln2440sbc_snd_ac97_device = platform_device_alloc("soc-audio", -1); + if (!ln2440sbc_snd_ac97_device) + return -ENOMEM; + + platform_set_drvdata(ln2440sbc_snd_ac97_device, &ln2440sbc); + ret = platform_device_add(ln2440sbc_snd_ac97_device); + + if (ret) + platform_device_put(ln2440sbc_snd_ac97_device); + + return ret; +} + +static void __exit ln2440sbc_exit(void) +{ + platform_device_unregister(ln2440sbc_snd_ac97_device); +} + +module_init(ln2440sbc_init); +module_exit(ln2440sbc_exit); + +/* Module information */ +MODULE_AUTHOR("Ivan Kuten"); +MODULE_DESCRIPTION("ALSA SoC ALC650 LN2440SBC"); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/samsung/neo1973_gta02_wm8753.c b/sound/soc/samsung/neo1973_gta02_wm8753.c new file mode 100644 index 000000000000..920e8d1f8841 --- /dev/null +++ b/sound/soc/samsung/neo1973_gta02_wm8753.c @@ -0,0 +1,504 @@ +/* + * neo1973_gta02_wm8753.c -- SoC audio for Openmoko Freerunner(GTA02) + * + * Copyright 2007 Openmoko Inc + * Author: Graeme Gregory + * Copyright 2007 Wolfson Microelectronics PLC. + * Author: Graeme Gregory + * Copyright 2009 Wolfson Microelectronics + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include +#include +#include +#include "../codecs/wm8753.h" +#include "dma.h" +#include "s3c24xx-i2s.h" + +static struct snd_soc_card neo1973_gta02; + +static int neo1973_gta02_hifi_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *codec_dai = rtd->codec_dai; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + unsigned int pll_out = 0, bclk = 0; + int ret = 0; + unsigned long iis_clkrate; + + iis_clkrate = s3c24xx_i2s_get_clockrate(); + + switch (params_rate(params)) { + case 8000: + case 16000: + pll_out = 12288000; + break; + case 48000: + bclk = WM8753_BCLK_DIV_4; + pll_out = 12288000; + break; + case 96000: + bclk = WM8753_BCLK_DIV_2; + pll_out = 12288000; + break; + case 11025: + bclk = WM8753_BCLK_DIV_16; + pll_out = 11289600; + break; + case 22050: + bclk = WM8753_BCLK_DIV_8; + pll_out = 11289600; + break; + case 44100: + bclk = WM8753_BCLK_DIV_4; + pll_out = 11289600; + break; + case 88200: + bclk = WM8753_BCLK_DIV_2; + pll_out = 11289600; + break; + } + + /* set codec DAI configuration */ + ret = snd_soc_dai_set_fmt(codec_dai, + SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | + SND_SOC_DAIFMT_CBM_CFM); + if (ret < 0) + return ret; + + /* set cpu DAI configuration */ + ret = snd_soc_dai_set_fmt(cpu_dai, + SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | + SND_SOC_DAIFMT_CBM_CFM); + if (ret < 0) + return ret; + + /* set the codec system clock for DAC and ADC */ + ret = snd_soc_dai_set_sysclk(codec_dai, WM8753_MCLK, pll_out, + SND_SOC_CLOCK_IN); + if (ret < 0) + return ret; + + /* set MCLK division for sample rate */ + ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C24XX_DIV_MCLK, + S3C2410_IISMOD_32FS); + if (ret < 0) + return ret; + + /* set codec BCLK division for sample rate */ + ret = snd_soc_dai_set_clkdiv(codec_dai, + WM8753_BCLKDIV, bclk); + if (ret < 0) + return ret; + + /* set prescaler division for sample rate */ + ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C24XX_DIV_PRESCALER, + S3C24XX_PRESCALE(4, 4)); + if (ret < 0) + return ret; + + /* codec PLL input is PCLK/4 */ + ret = snd_soc_dai_set_pll(codec_dai, WM8753_PLL1, 0, + iis_clkrate / 4, pll_out); + if (ret < 0) + return ret; + + return 0; +} + +static int neo1973_gta02_hifi_hw_free(struct snd_pcm_substream *substream) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *codec_dai = rtd->codec_dai; + + /* disable the PLL */ + return snd_soc_dai_set_pll(codec_dai, WM8753_PLL1, 0, 0, 0); +} + +/* + * Neo1973 WM8753 HiFi DAI opserations. + */ +static struct snd_soc_ops neo1973_gta02_hifi_ops = { + .hw_params = neo1973_gta02_hifi_hw_params, + .hw_free = neo1973_gta02_hifi_hw_free, +}; + +static int neo1973_gta02_voice_hw_params( + struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *codec_dai = rtd->codec_dai; + unsigned int pcmdiv = 0; + int ret = 0; + unsigned long iis_clkrate; + + iis_clkrate = s3c24xx_i2s_get_clockrate(); + + if (params_rate(params) != 8000) + return -EINVAL; + if (params_channels(params) != 1) + return -EINVAL; + + pcmdiv = WM8753_PCM_DIV_6; /* 2.048 MHz */ + + /* todo: gg check mode (DSP_B) against CSR datasheet */ + /* set codec DAI configuration */ + ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_DSP_B | + SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); + if (ret < 0) + return ret; + + /* set the codec system clock for DAC and ADC */ + ret = snd_soc_dai_set_sysclk(codec_dai, WM8753_PCMCLK, + 12288000, SND_SOC_CLOCK_IN); + if (ret < 0) + return ret; + + /* set codec PCM division for sample rate */ + ret = snd_soc_dai_set_clkdiv(codec_dai, WM8753_PCMDIV, + pcmdiv); + if (ret < 0) + return ret; + + /* configure and enable PLL for 12.288MHz output */ + ret = snd_soc_dai_set_pll(codec_dai, WM8753_PLL2, 0, + iis_clkrate / 4, 12288000); + if (ret < 0) + return ret; + + return 0; +} + +static int neo1973_gta02_voice_hw_free(struct snd_pcm_substream *substream) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *codec_dai = rtd->codec_dai; + + /* disable the PLL */ + return snd_soc_dai_set_pll(codec_dai, WM8753_PLL2, 0, 0, 0); +} + +static struct snd_soc_ops neo1973_gta02_voice_ops = { + .hw_params = neo1973_gta02_voice_hw_params, + .hw_free = neo1973_gta02_voice_hw_free, +}; + +#define LM4853_AMP 1 +#define LM4853_SPK 2 + +static u8 lm4853_state; + +/* This has no effect, it exists only to maintain compatibility with + * existing ALSA state files. + */ +static int lm4853_set_state(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int val = ucontrol->value.integer.value[0]; + + if (val) + lm4853_state |= LM4853_AMP; + else + lm4853_state &= ~LM4853_AMP; + + return 0; +} + +static int lm4853_get_state(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = lm4853_state & LM4853_AMP; + + return 0; +} + +static int lm4853_set_spk(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int val = ucontrol->value.integer.value[0]; + + if (val) { + lm4853_state |= LM4853_SPK; + gpio_set_value(GTA02_GPIO_HP_IN, 0); + } else { + lm4853_state &= ~LM4853_SPK; + gpio_set_value(GTA02_GPIO_HP_IN, 1); + } + + return 0; +} + +static int lm4853_get_spk(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = (lm4853_state & LM4853_SPK) >> 1; + + return 0; +} + +static int lm4853_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *k, + int event) +{ + gpio_set_value(GTA02_GPIO_AMP_SHUT, SND_SOC_DAPM_EVENT_OFF(event)); + + return 0; +} + +static const struct snd_soc_dapm_widget wm8753_dapm_widgets[] = { + SND_SOC_DAPM_SPK("Stereo Out", lm4853_event), + SND_SOC_DAPM_LINE("GSM Line Out", NULL), + SND_SOC_DAPM_LINE("GSM Line In", NULL), + SND_SOC_DAPM_MIC("Headset Mic", NULL), + SND_SOC_DAPM_MIC("Handset Mic", NULL), + SND_SOC_DAPM_SPK("Handset Spk", NULL), +}; + + +/* example machine audio_mapnections */ +static const struct snd_soc_dapm_route audio_map[] = { + + /* Connections to the lm4853 amp */ + {"Stereo Out", NULL, "LOUT1"}, + {"Stereo Out", NULL, "ROUT1"}, + + /* Connections to the GSM Module */ + {"GSM Line Out", NULL, "MONO1"}, + {"GSM Line Out", NULL, "MONO2"}, + {"RXP", NULL, "GSM Line In"}, + {"RXN", NULL, "GSM Line In"}, + + /* Connections to Headset */ + {"MIC1", NULL, "Mic Bias"}, + {"Mic Bias", NULL, "Headset Mic"}, + + /* Call Mic */ + {"MIC2", NULL, "Mic Bias"}, + {"MIC2N", NULL, "Mic Bias"}, + {"Mic Bias", NULL, "Handset Mic"}, + + /* Call Speaker */ + {"Handset Spk", NULL, "LOUT2"}, + {"Handset Spk", NULL, "ROUT2"}, + + /* Connect the ALC pins */ + {"ACIN", NULL, "ACOP"}, +}; + +static const struct snd_kcontrol_new wm8753_neo1973_gta02_controls[] = { + SOC_DAPM_PIN_SWITCH("Stereo Out"), + SOC_DAPM_PIN_SWITCH("GSM Line Out"), + SOC_DAPM_PIN_SWITCH("GSM Line In"), + SOC_DAPM_PIN_SWITCH("Headset Mic"), + SOC_DAPM_PIN_SWITCH("Handset Mic"), + SOC_DAPM_PIN_SWITCH("Handset Spk"), + + /* This has no effect, it exists only to maintain compatibility with + * existing ALSA state files. + */ + SOC_SINGLE_EXT("Amp State Switch", 6, 0, 1, 0, + lm4853_get_state, + lm4853_set_state), + SOC_SINGLE_EXT("Amp Spk Switch", 7, 0, 1, 0, + lm4853_get_spk, + lm4853_set_spk), +}; + +/* + * This is an example machine initialisation for a wm8753 connected to a + * neo1973 GTA02. + */ +static int neo1973_gta02_wm8753_init(struct snd_soc_pcm_runtime *rtd) +{ + struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_dapm_context *dapm = &codec->dapm; + int err; + + /* set up NC codec pins */ + snd_soc_dapm_nc_pin(dapm, "OUT3"); + snd_soc_dapm_nc_pin(dapm, "OUT4"); + snd_soc_dapm_nc_pin(dapm, "LINE1"); + snd_soc_dapm_nc_pin(dapm, "LINE2"); + + /* Add neo1973 gta02 specific widgets */ + snd_soc_dapm_new_controls(dapm, wm8753_dapm_widgets, + ARRAY_SIZE(wm8753_dapm_widgets)); + + /* add neo1973 gta02 specific controls */ + err = snd_soc_add_controls(codec, wm8753_neo1973_gta02_controls, + ARRAY_SIZE(wm8753_neo1973_gta02_controls)); + + if (err < 0) + return err; + + /* set up neo1973 gta02 specific audio path audio_map */ + snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); + + /* set endpoints to default off mode */ + snd_soc_dapm_disable_pin(dapm, "Stereo Out"); + snd_soc_dapm_disable_pin(dapm, "GSM Line Out"); + snd_soc_dapm_disable_pin(dapm, "GSM Line In"); + snd_soc_dapm_disable_pin(dapm, "Headset Mic"); + snd_soc_dapm_disable_pin(dapm, "Handset Mic"); + snd_soc_dapm_disable_pin(dapm, "Handset Spk"); + + /* allow audio paths from the GSM modem to run during suspend */ + snd_soc_dapm_ignore_suspend(dapm, "Stereo Out"); + snd_soc_dapm_ignore_suspend(dapm, "GSM Line Out"); + snd_soc_dapm_ignore_suspend(dapm, "GSM Line In"); + snd_soc_dapm_ignore_suspend(dapm, "Headset Mic"); + snd_soc_dapm_ignore_suspend(dapm, "Handset Mic"); + snd_soc_dapm_ignore_suspend(dapm, "Handset Spk"); + + snd_soc_dapm_sync(dapm); + + return 0; +} + +/* + * BT Codec DAI + */ +static struct snd_soc_dai_driver bt_dai = { + .name = "bluetooth-dai", + .playback = { + .channels_min = 1, + .channels_max = 1, + .rates = SNDRV_PCM_RATE_8000, + .formats = SNDRV_PCM_FMTBIT_S16_LE,}, + .capture = { + .channels_min = 1, + .channels_max = 1, + .rates = SNDRV_PCM_RATE_8000, + .formats = SNDRV_PCM_FMTBIT_S16_LE,}, +}; + +static struct snd_soc_dai_link neo1973_gta02_dai[] = { +{ /* Hifi Playback - for similatious use with voice below */ + .name = "WM8753", + .stream_name = "WM8753 HiFi", + .cpu_dai_name = "s3c24xx-i2s", + .codec_dai_name = "wm8753-hifi", + .init = neo1973_gta02_wm8753_init, + .platform_name = "samsung-audio", + .codec_name = "wm8753-codec.0-0x1a", + .ops = &neo1973_gta02_hifi_ops, +}, +{ /* Voice via BT */ + .name = "Bluetooth", + .stream_name = "Voice", + .cpu_dai_name = "bluetooth-dai", + .codec_dai_name = "wm8753-voice", + .ops = &neo1973_gta02_voice_ops, + .codec_name = "wm8753-codec.0-0x1a", + .platform_name = "samsung-audio", +}, +}; + +static struct snd_soc_card neo1973_gta02 = { + .name = "neo1973-gta02", + .dai_link = neo1973_gta02_dai, + .num_links = ARRAY_SIZE(neo1973_gta02_dai), +}; + +static struct platform_device *neo1973_gta02_snd_device; + +static int __init neo1973_gta02_init(void) +{ + int ret; + + if (!machine_is_neo1973_gta02()) { + printk(KERN_INFO + "Only GTA02 is supported by this ASoC driver\n"); + return -ENODEV; + } + + neo1973_gta02_snd_device = platform_device_alloc("soc-audio", -1); + if (!neo1973_gta02_snd_device) + return -ENOMEM; + + /* register bluetooth DAI here */ + ret = snd_soc_register_dai(&neo1973_gta02_snd_device->dev, -1, &bt_dai); + if (ret) { + platform_device_put(neo1973_gta02_snd_device); + return ret; + } + + platform_set_drvdata(neo1973_gta02_snd_device, &neo1973_gta02); + ret = platform_device_add(neo1973_gta02_snd_device); + + if (ret) { + platform_device_put(neo1973_gta02_snd_device); + return ret; + } + + /* Initialise GPIOs used by amp */ + ret = gpio_request(GTA02_GPIO_HP_IN, "GTA02_HP_IN"); + if (ret) { + pr_err("gta02_wm8753: Failed to register GPIO %d\n", GTA02_GPIO_HP_IN); + goto err_unregister_device; + } + + ret = gpio_direction_output(GTA02_GPIO_HP_IN, 1); + if (ret) { + pr_err("gta02_wm8753: Failed to configure GPIO %d\n", GTA02_GPIO_HP_IN); + goto err_free_gpio_hp_in; + } + + ret = gpio_request(GTA02_GPIO_AMP_SHUT, "GTA02_AMP_SHUT"); + if (ret) { + pr_err("gta02_wm8753: Failed to register GPIO %d\n", GTA02_GPIO_AMP_SHUT); + goto err_free_gpio_hp_in; + } + + ret = gpio_direction_output(GTA02_GPIO_AMP_SHUT, 1); + if (ret) { + pr_err("gta02_wm8753: Failed to configure GPIO %d\n", GTA02_GPIO_AMP_SHUT); + goto err_free_gpio_amp_shut; + } + + return 0; + +err_free_gpio_amp_shut: + gpio_free(GTA02_GPIO_AMP_SHUT); +err_free_gpio_hp_in: + gpio_free(GTA02_GPIO_HP_IN); +err_unregister_device: + platform_device_unregister(neo1973_gta02_snd_device); + return ret; +} +module_init(neo1973_gta02_init); + +static void __exit neo1973_gta02_exit(void) +{ + snd_soc_unregister_dai(&neo1973_gta02_snd_device->dev, -1); + platform_device_unregister(neo1973_gta02_snd_device); + gpio_free(GTA02_GPIO_HP_IN); + gpio_free(GTA02_GPIO_AMP_SHUT); +} +module_exit(neo1973_gta02_exit); + +/* Module information */ +MODULE_AUTHOR("Graeme Gregory, graeme@openmoko.org"); +MODULE_DESCRIPTION("ALSA SoC WM8753 Neo1973 GTA02"); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/samsung/neo1973_wm8753.c b/sound/soc/samsung/neo1973_wm8753.c new file mode 100644 index 000000000000..c7a24514beb5 --- /dev/null +++ b/sound/soc/samsung/neo1973_wm8753.c @@ -0,0 +1,706 @@ +/* + * neo1973_wm8753.c -- SoC audio for Neo1973 + * + * Copyright 2007 Wolfson Microelectronics PLC. + * Author: Graeme Gregory + * graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com + * + * 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. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "../codecs/wm8753.h" +#include "lm4857.h" +#include "dma.h" +#include "s3c24xx-i2s.h" + +/* define the scenarios */ +#define NEO_AUDIO_OFF 0 +#define NEO_GSM_CALL_AUDIO_HANDSET 1 +#define NEO_GSM_CALL_AUDIO_HEADSET 2 +#define NEO_GSM_CALL_AUDIO_BLUETOOTH 3 +#define NEO_STEREO_TO_SPEAKERS 4 +#define NEO_STEREO_TO_HEADPHONES 5 +#define NEO_CAPTURE_HANDSET 6 +#define NEO_CAPTURE_HEADSET 7 +#define NEO_CAPTURE_BLUETOOTH 8 + +static struct snd_soc_card neo1973; +static struct i2c_client *i2c; + +static int neo1973_hifi_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *codec_dai = rtd->codec_dai; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + unsigned int pll_out = 0, bclk = 0; + int ret = 0; + unsigned long iis_clkrate; + + pr_debug("Entered %s\n", __func__); + + iis_clkrate = s3c24xx_i2s_get_clockrate(); + + switch (params_rate(params)) { + case 8000: + case 16000: + pll_out = 12288000; + break; + case 48000: + bclk = WM8753_BCLK_DIV_4; + pll_out = 12288000; + break; + case 96000: + bclk = WM8753_BCLK_DIV_2; + pll_out = 12288000; + break; + case 11025: + bclk = WM8753_BCLK_DIV_16; + pll_out = 11289600; + break; + case 22050: + bclk = WM8753_BCLK_DIV_8; + pll_out = 11289600; + break; + case 44100: + bclk = WM8753_BCLK_DIV_4; + pll_out = 11289600; + break; + case 88200: + bclk = WM8753_BCLK_DIV_2; + pll_out = 11289600; + break; + } + + /* set codec DAI configuration */ + ret = snd_soc_dai_set_fmt(codec_dai, + SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | + SND_SOC_DAIFMT_CBM_CFM); + if (ret < 0) + return ret; + + /* set cpu DAI configuration */ + ret = snd_soc_dai_set_fmt(cpu_dai, + SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF | + SND_SOC_DAIFMT_CBM_CFM); + if (ret < 0) + return ret; + + /* set the codec system clock for DAC and ADC */ + ret = snd_soc_dai_set_sysclk(codec_dai, WM8753_MCLK, pll_out, + SND_SOC_CLOCK_IN); + if (ret < 0) + return ret; + + /* set MCLK division for sample rate */ + ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C24XX_DIV_MCLK, + S3C2410_IISMOD_32FS); + if (ret < 0) + return ret; + + /* set codec BCLK division for sample rate */ + ret = snd_soc_dai_set_clkdiv(codec_dai, WM8753_BCLKDIV, bclk); + if (ret < 0) + return ret; + + /* set prescaler division for sample rate */ + ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C24XX_DIV_PRESCALER, + S3C24XX_PRESCALE(4, 4)); + if (ret < 0) + return ret; + + /* codec PLL input is PCLK/4 */ + ret = snd_soc_dai_set_pll(codec_dai, WM8753_PLL1, 0, + iis_clkrate / 4, pll_out); + if (ret < 0) + return ret; + + return 0; +} + +static int neo1973_hifi_hw_free(struct snd_pcm_substream *substream) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *codec_dai = rtd->codec_dai; + + pr_debug("Entered %s\n", __func__); + + /* disable the PLL */ + return snd_soc_dai_set_pll(codec_dai, WM8753_PLL1, 0, 0, 0); +} + +/* + * Neo1973 WM8753 HiFi DAI opserations. + */ +static struct snd_soc_ops neo1973_hifi_ops = { + .hw_params = neo1973_hifi_hw_params, + .hw_free = neo1973_hifi_hw_free, +}; + +static int neo1973_voice_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *codec_dai = rtd->codec_dai; + unsigned int pcmdiv = 0; + int ret = 0; + unsigned long iis_clkrate; + + pr_debug("Entered %s\n", __func__); + + iis_clkrate = s3c24xx_i2s_get_clockrate(); + + if (params_rate(params) != 8000) + return -EINVAL; + if (params_channels(params) != 1) + return -EINVAL; + + pcmdiv = WM8753_PCM_DIV_6; /* 2.048 MHz */ + + /* todo: gg check mode (DSP_B) against CSR datasheet */ + /* set codec DAI configuration */ + ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_DSP_B | + SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); + if (ret < 0) + return ret; + + /* set the codec system clock for DAC and ADC */ + ret = snd_soc_dai_set_sysclk(codec_dai, WM8753_PCMCLK, 12288000, + SND_SOC_CLOCK_IN); + if (ret < 0) + return ret; + + /* set codec PCM division for sample rate */ + ret = snd_soc_dai_set_clkdiv(codec_dai, WM8753_PCMDIV, pcmdiv); + if (ret < 0) + return ret; + + /* configure and enable PLL for 12.288MHz output */ + ret = snd_soc_dai_set_pll(codec_dai, WM8753_PLL2, 0, + iis_clkrate / 4, 12288000); + if (ret < 0) + return ret; + + return 0; +} + +static int neo1973_voice_hw_free(struct snd_pcm_substream *substream) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *codec_dai = rtd->codec_dai; + + pr_debug("Entered %s\n", __func__); + + /* disable the PLL */ + return snd_soc_dai_set_pll(codec_dai, WM8753_PLL2, 0, 0, 0); +} + +static struct snd_soc_ops neo1973_voice_ops = { + .hw_params = neo1973_voice_hw_params, + .hw_free = neo1973_voice_hw_free, +}; + +static int neo1973_scenario; + +static int neo1973_get_scenario(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = neo1973_scenario; + return 0; +} + +static int set_scenario_endpoints(struct snd_soc_codec *codec, int scenario) +{ + struct snd_soc_dapm_context *dapm = &codec->dapm; + + pr_debug("Entered %s\n", __func__); + + switch (neo1973_scenario) { + case NEO_AUDIO_OFF: + snd_soc_dapm_disable_pin(dapm, "Audio Out"); + snd_soc_dapm_disable_pin(dapm, "GSM Line Out"); + snd_soc_dapm_disable_pin(dapm, "GSM Line In"); + snd_soc_dapm_disable_pin(dapm, "Headset Mic"); + snd_soc_dapm_disable_pin(dapm, "Call Mic"); + break; + case NEO_GSM_CALL_AUDIO_HANDSET: + snd_soc_dapm_enable_pin(dapm, "Audio Out"); + snd_soc_dapm_enable_pin(dapm, "GSM Line Out"); + snd_soc_dapm_enable_pin(dapm, "GSM Line In"); + snd_soc_dapm_disable_pin(dapm, "Headset Mic"); + snd_soc_dapm_enable_pin(dapm, "Call Mic"); + break; + case NEO_GSM_CALL_AUDIO_HEADSET: + snd_soc_dapm_enable_pin(dapm, "Audio Out"); + snd_soc_dapm_enable_pin(dapm, "GSM Line Out"); + snd_soc_dapm_enable_pin(dapm, "GSM Line In"); + snd_soc_dapm_enable_pin(dapm, "Headset Mic"); + snd_soc_dapm_disable_pin(dapm, "Call Mic"); + break; + case NEO_GSM_CALL_AUDIO_BLUETOOTH: + snd_soc_dapm_disable_pin(dapm, "Audio Out"); + snd_soc_dapm_enable_pin(dapm, "GSM Line Out"); + snd_soc_dapm_enable_pin(dapm, "GSM Line In"); + snd_soc_dapm_disable_pin(dapm, "Headset Mic"); + snd_soc_dapm_disable_pin(dapm, "Call Mic"); + break; + case NEO_STEREO_TO_SPEAKERS: + snd_soc_dapm_enable_pin(dapm, "Audio Out"); + snd_soc_dapm_disable_pin(dapm, "GSM Line Out"); + snd_soc_dapm_disable_pin(dapm, "GSM Line In"); + snd_soc_dapm_disable_pin(dapm, "Headset Mic"); + snd_soc_dapm_disable_pin(dapm, "Call Mic"); + break; + case NEO_STEREO_TO_HEADPHONES: + snd_soc_dapm_enable_pin(dapm, "Audio Out"); + snd_soc_dapm_disable_pin(dapm, "GSM Line Out"); + snd_soc_dapm_disable_pin(dapm, "GSM Line In"); + snd_soc_dapm_disable_pin(dapm, "Headset Mic"); + snd_soc_dapm_disable_pin(dapm, "Call Mic"); + break; + case NEO_CAPTURE_HANDSET: + snd_soc_dapm_disable_pin(dapm, "Audio Out"); + snd_soc_dapm_disable_pin(dapm, "GSM Line Out"); + snd_soc_dapm_disable_pin(dapm, "GSM Line In"); + snd_soc_dapm_disable_pin(dapm, "Headset Mic"); + snd_soc_dapm_enable_pin(dapm, "Call Mic"); + break; + case NEO_CAPTURE_HEADSET: + snd_soc_dapm_disable_pin(dapm, "Audio Out"); + snd_soc_dapm_disable_pin(dapm, "GSM Line Out"); + snd_soc_dapm_disable_pin(dapm, "GSM Line In"); + snd_soc_dapm_enable_pin(dapm, "Headset Mic"); + snd_soc_dapm_disable_pin(dapm, "Call Mic"); + break; + case NEO_CAPTURE_BLUETOOTH: + snd_soc_dapm_disable_pin(dapm, "Audio Out"); + snd_soc_dapm_disable_pin(dapm, "GSM Line Out"); + snd_soc_dapm_disable_pin(dapm, "GSM Line In"); + snd_soc_dapm_disable_pin(dapm, "Headset Mic"); + snd_soc_dapm_disable_pin(dapm, "Call Mic"); + break; + default: + snd_soc_dapm_disable_pin(dapm, "Audio Out"); + snd_soc_dapm_disable_pin(dapm, "GSM Line Out"); + snd_soc_dapm_disable_pin(dapm, "GSM Line In"); + snd_soc_dapm_disable_pin(dapm, "Headset Mic"); + snd_soc_dapm_disable_pin(dapm, "Call Mic"); + } + + snd_soc_dapm_sync(dapm); + + return 0; +} + +static int neo1973_set_scenario(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + + pr_debug("Entered %s\n", __func__); + + if (neo1973_scenario == ucontrol->value.integer.value[0]) + return 0; + + neo1973_scenario = ucontrol->value.integer.value[0]; + set_scenario_endpoints(codec, neo1973_scenario); + return 1; +} + +static u8 lm4857_regs[4] = {0x00, 0x40, 0x80, 0xC0}; + +static void lm4857_write_regs(void) +{ + pr_debug("Entered %s\n", __func__); + + if (i2c_master_send(i2c, lm4857_regs, 4) != 4) + printk(KERN_ERR "lm4857: i2c write failed\n"); +} + +static int lm4857_get_reg(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct soc_mixer_control *mc = + (struct soc_mixer_control *)kcontrol->private_value; + int reg = mc->reg; + int shift = mc->shift; + int mask = mc->max; + + pr_debug("Entered %s\n", __func__); + + ucontrol->value.integer.value[0] = (lm4857_regs[reg] >> shift) & mask; + return 0; +} + +static int lm4857_set_reg(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct soc_mixer_control *mc = + (struct soc_mixer_control *)kcontrol->private_value; + int reg = mc->reg; + int shift = mc->shift; + int mask = mc->max; + + if (((lm4857_regs[reg] >> shift) & mask) == + ucontrol->value.integer.value[0]) + return 0; + + lm4857_regs[reg] &= ~(mask << shift); + lm4857_regs[reg] |= ucontrol->value.integer.value[0] << shift; + lm4857_write_regs(); + return 1; +} + +static int lm4857_get_mode(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + u8 value = lm4857_regs[LM4857_CTRL] & 0x0F; + + pr_debug("Entered %s\n", __func__); + + if (value) + value -= 5; + + ucontrol->value.integer.value[0] = value; + return 0; +} + +static int lm4857_set_mode(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + u8 value = ucontrol->value.integer.value[0]; + + pr_debug("Entered %s\n", __func__); + + if (value) + value += 5; + + if ((lm4857_regs[LM4857_CTRL] & 0x0F) == value) + return 0; + + lm4857_regs[LM4857_CTRL] &= 0xF0; + lm4857_regs[LM4857_CTRL] |= value; + lm4857_write_regs(); + return 1; +} + +static const struct snd_soc_dapm_widget wm8753_dapm_widgets[] = { + SND_SOC_DAPM_LINE("Audio Out", NULL), + SND_SOC_DAPM_LINE("GSM Line Out", NULL), + SND_SOC_DAPM_LINE("GSM Line In", NULL), + SND_SOC_DAPM_MIC("Headset Mic", NULL), + SND_SOC_DAPM_MIC("Call Mic", NULL), +}; + + +static const struct snd_soc_dapm_route dapm_routes[] = { + + /* Connections to the lm4857 amp */ + {"Audio Out", NULL, "LOUT1"}, + {"Audio Out", NULL, "ROUT1"}, + + /* Connections to the GSM Module */ + {"GSM Line Out", NULL, "MONO1"}, + {"GSM Line Out", NULL, "MONO2"}, + {"RXP", NULL, "GSM Line In"}, + {"RXN", NULL, "GSM Line In"}, + + /* Connections to Headset */ + {"MIC1", NULL, "Mic Bias"}, + {"Mic Bias", NULL, "Headset Mic"}, + + /* Call Mic */ + {"MIC2", NULL, "Mic Bias"}, + {"MIC2N", NULL, "Mic Bias"}, + {"Mic Bias", NULL, "Call Mic"}, + + /* Connect the ALC pins */ + {"ACIN", NULL, "ACOP"}, +}; + +static const char *lm4857_mode[] = { + "Off", + "Call Speaker", + "Stereo Speakers", + "Stereo Speakers + Headphones", + "Headphones" +}; + +static const struct soc_enum lm4857_mode_enum[] = { + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(lm4857_mode), lm4857_mode), +}; + +static const char *neo_scenarios[] = { + "Off", + "GSM Handset", + "GSM Headset", + "GSM Bluetooth", + "Speakers", + "Headphones", + "Capture Handset", + "Capture Headset", + "Capture Bluetooth" +}; + +static const struct soc_enum neo_scenario_enum[] = { + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(neo_scenarios), neo_scenarios), +}; + +static const DECLARE_TLV_DB_SCALE(stereo_tlv, -4050, 150, 0); +static const DECLARE_TLV_DB_SCALE(mono_tlv, -3450, 150, 0); + +static const struct snd_kcontrol_new wm8753_neo1973_controls[] = { + SOC_SINGLE_EXT_TLV("Amp Left Playback Volume", LM4857_LVOL, 0, 31, 0, + lm4857_get_reg, lm4857_set_reg, stereo_tlv), + SOC_SINGLE_EXT_TLV("Amp Right Playback Volume", LM4857_RVOL, 0, 31, 0, + lm4857_get_reg, lm4857_set_reg, stereo_tlv), + SOC_SINGLE_EXT_TLV("Amp Mono Playback Volume", LM4857_MVOL, 0, 31, 0, + lm4857_get_reg, lm4857_set_reg, mono_tlv), + SOC_ENUM_EXT("Amp Mode", lm4857_mode_enum[0], + lm4857_get_mode, lm4857_set_mode), + SOC_ENUM_EXT("Neo Mode", neo_scenario_enum[0], + neo1973_get_scenario, neo1973_set_scenario), + SOC_SINGLE_EXT("Amp Spk 3D Playback Switch", LM4857_LVOL, 5, 1, 0, + lm4857_get_reg, lm4857_set_reg), + SOC_SINGLE_EXT("Amp HP 3d Playback Switch", LM4857_RVOL, 5, 1, 0, + lm4857_get_reg, lm4857_set_reg), + SOC_SINGLE_EXT("Amp Fast Wakeup Playback Switch", LM4857_CTRL, 5, 1, 0, + lm4857_get_reg, lm4857_set_reg), + SOC_SINGLE_EXT("Amp Earpiece 6dB Playback Switch", LM4857_CTRL, 4, 1, 0, + lm4857_get_reg, lm4857_set_reg), +}; + +/* + * This is an example machine initialisation for a wm8753 connected to a + * neo1973 II. It is missing logic to detect hp/mic insertions and logic + * to re-route the audio in such an event. + */ +static int neo1973_wm8753_init(struct snd_soc_pcm_runtime *rtd) +{ + struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_dapm_context *dapm = &codec->dapm; + int err; + + pr_debug("Entered %s\n", __func__); + + /* set up NC codec pins */ + snd_soc_dapm_nc_pin(dapm, "LOUT2"); + snd_soc_dapm_nc_pin(dapm, "ROUT2"); + snd_soc_dapm_nc_pin(dapm, "OUT3"); + snd_soc_dapm_nc_pin(dapm, "OUT4"); + snd_soc_dapm_nc_pin(dapm, "LINE1"); + snd_soc_dapm_nc_pin(dapm, "LINE2"); + + /* Add neo1973 specific widgets */ + snd_soc_dapm_new_controls(dapm, wm8753_dapm_widgets, + ARRAY_SIZE(wm8753_dapm_widgets)); + + /* set endpoints to default mode */ + set_scenario_endpoints(codec, NEO_AUDIO_OFF); + + /* add neo1973 specific controls */ + err = snd_soc_add_controls(codec, wm8753_neo1973_controls, + ARRAY_SIZE(8753_neo1973_controls)); + if (err < 0) + return err; + + /* set up neo1973 specific audio routes */ + err = snd_soc_dapm_add_routes(dapm, dapm_routes, + ARRAY_SIZE(dapm_routes)); + + snd_soc_dapm_sync(dapm); + return 0; +} + +/* + * BT Codec DAI + */ +static struct snd_soc_dai bt_dai = { + .name = "bluetooth-dai", + .playback = { + .channels_min = 1, + .channels_max = 1, + .rates = SNDRV_PCM_RATE_8000, + .formats = SNDRV_PCM_FMTBIT_S16_LE,}, + .capture = { + .channels_min = 1, + .channels_max = 1, + .rates = SNDRV_PCM_RATE_8000, + .formats = SNDRV_PCM_FMTBIT_S16_LE,}, +}; + +static struct snd_soc_dai_link neo1973_dai[] = { +{ /* Hifi Playback - for similatious use with voice below */ + .name = "WM8753", + .stream_name = "WM8753 HiFi", + .platform_name = "samsung-audio", + .cpu_dai_name = "s3c24xx-i2s", + .codec_dai_name = "wm8753-hifi", + .codec_name = "wm8753-codec.0-0x1a", + .init = neo1973_wm8753_init, + .ops = &neo1973_hifi_ops, +}, +{ /* Voice via BT */ + .name = "Bluetooth", + .stream_name = "Voice", + .platform_name = "samsung-audio", + .cpu_dai_name = "bluetooth-dai", + .codec_dai_name = "wm8753-voice", + .codec_name = "wm8753-codec.0-0x1a", + .ops = &neo1973_voice_ops, +}, +}; + +static struct snd_soc_card neo1973 = { + .name = "neo1973", + .dai_link = neo1973_dai, + .num_links = ARRAY_SIZE(neo1973_dai), +}; + +static int lm4857_i2c_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + pr_debug("Entered %s\n", __func__); + + i2c = client; + + lm4857_write_regs(); + return 0; +} + +static int lm4857_i2c_remove(struct i2c_client *client) +{ + pr_debug("Entered %s\n", __func__); + + i2c = NULL; + + return 0; +} + +static u8 lm4857_state; + +static int lm4857_suspend(struct i2c_client *dev, pm_message_t state) +{ + pr_debug("Entered %s\n", __func__); + + dev_dbg(&dev->dev, "lm4857_suspend\n"); + lm4857_state = lm4857_regs[LM4857_CTRL] & 0xf; + if (lm4857_state) { + lm4857_regs[LM4857_CTRL] &= 0xf0; + lm4857_write_regs(); + } + return 0; +} + +static int lm4857_resume(struct i2c_client *dev) +{ + pr_debug("Entered %s\n", __func__); + + if (lm4857_state) { + lm4857_regs[LM4857_CTRL] |= (lm4857_state & 0x0f); + lm4857_write_regs(); + } + return 0; +} + +static void lm4857_shutdown(struct i2c_client *dev) +{ + pr_debug("Entered %s\n", __func__); + + dev_dbg(&dev->dev, "lm4857_shutdown\n"); + lm4857_regs[LM4857_CTRL] &= 0xf0; + lm4857_write_regs(); +} + +static const struct i2c_device_id lm4857_i2c_id[] = { + { "neo1973_lm4857", 0 }, + { } +}; + +static struct i2c_driver lm4857_i2c_driver = { + .driver = { + .name = "LM4857 I2C Amp", + .owner = THIS_MODULE, + }, + .suspend = lm4857_suspend, + .resume = lm4857_resume, + .shutdown = lm4857_shutdown, + .probe = lm4857_i2c_probe, + .remove = lm4857_i2c_remove, + .id_table = lm4857_i2c_id, +}; + +static struct platform_device *neo1973_snd_device; + +static int __init neo1973_init(void) +{ + int ret; + + pr_debug("Entered %s\n", __func__); + + if (!machine_is_neo1973_gta01()) { + printk(KERN_INFO + "Only GTA01 hardware supported by ASoC driver\n"); + return -ENODEV; + } + + neo1973_snd_device = platform_device_alloc("soc-audio", -1); + if (!neo1973_snd_device) + return -ENOMEM; + + platform_set_drvdata(neo1973_snd_device, &neo1973); + ret = platform_device_add(neo1973_snd_device); + + if (ret) { + platform_device_put(neo1973_snd_device); + return ret; + } + + ret = i2c_add_driver(&lm4857_i2c_driver); + + if (ret != 0) + platform_device_unregister(neo1973_snd_device); + + return ret; +} + +static void __exit neo1973_exit(void) +{ + pr_debug("Entered %s\n", __func__); + + i2c_del_driver(&lm4857_i2c_driver); + platform_device_unregister(neo1973_snd_device); +} + +module_init(neo1973_init); +module_exit(neo1973_exit); + +/* Module information */ +MODULE_AUTHOR("Graeme Gregory, graeme@openmoko.org, www.openmoko.org"); +MODULE_DESCRIPTION("ALSA SoC WM8753 Neo1973"); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/samsung/pcm.c b/sound/soc/samsung/pcm.c new file mode 100644 index 000000000000..48d0b750406b --- /dev/null +++ b/sound/soc/samsung/pcm.c @@ -0,0 +1,552 @@ +/* sound/soc/samsung/pcm.c + * + * ALSA SoC Audio Layer - S3C PCM-Controller driver + * + * Copyright (c) 2009 Samsung Electronics Co. Ltd + * Author: Jaswinder Singh + * based upon I2S drivers by Ben Dooks. + * + * 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 +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include "dma.h" +#include "pcm.h" + +static struct s3c2410_dma_client s3c_pcm_dma_client_out = { + .name = "PCM Stereo out" +}; + +static struct s3c2410_dma_client s3c_pcm_dma_client_in = { + .name = "PCM Stereo in" +}; + +static struct s3c_dma_params s3c_pcm_stereo_out[] = { + [0] = { + .client = &s3c_pcm_dma_client_out, + .dma_size = 4, + }, + [1] = { + .client = &s3c_pcm_dma_client_out, + .dma_size = 4, + }, +}; + +static struct s3c_dma_params s3c_pcm_stereo_in[] = { + [0] = { + .client = &s3c_pcm_dma_client_in, + .dma_size = 4, + }, + [1] = { + .client = &s3c_pcm_dma_client_in, + .dma_size = 4, + }, +}; + +static struct s3c_pcm_info s3c_pcm[2]; + +static void s3c_pcm_snd_txctrl(struct s3c_pcm_info *pcm, int on) +{ + void __iomem *regs = pcm->regs; + u32 ctl, clkctl; + + clkctl = readl(regs + S3C_PCM_CLKCTL); + ctl = readl(regs + S3C_PCM_CTL); + ctl &= ~(S3C_PCM_CTL_TXDIPSTICK_MASK + << S3C_PCM_CTL_TXDIPSTICK_SHIFT); + + if (on) { + ctl |= S3C_PCM_CTL_TXDMA_EN; + ctl |= S3C_PCM_CTL_TXFIFO_EN; + ctl |= S3C_PCM_CTL_ENABLE; + ctl |= (0x4<idleclk) + clkctl |= S3C_PCM_CLKCTL_SERCLK_EN; + } + } + + writel(clkctl, regs + S3C_PCM_CLKCTL); + writel(ctl, regs + S3C_PCM_CTL); +} + +static void s3c_pcm_snd_rxctrl(struct s3c_pcm_info *pcm, int on) +{ + void __iomem *regs = pcm->regs; + u32 ctl, clkctl; + + ctl = readl(regs + S3C_PCM_CTL); + clkctl = readl(regs + S3C_PCM_CLKCTL); + ctl &= ~(S3C_PCM_CTL_RXDIPSTICK_MASK + << S3C_PCM_CTL_RXDIPSTICK_SHIFT); + + if (on) { + ctl |= S3C_PCM_CTL_RXDMA_EN; + ctl |= S3C_PCM_CTL_RXFIFO_EN; + ctl |= S3C_PCM_CTL_ENABLE; + ctl |= (0x20<idleclk) + clkctl |= S3C_PCM_CLKCTL_SERCLK_EN; + } + } + + writel(clkctl, regs + S3C_PCM_CLKCTL); + writel(ctl, regs + S3C_PCM_CTL); +} + +static int s3c_pcm_trigger(struct snd_pcm_substream *substream, int cmd, + struct snd_soc_dai *dai) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct s3c_pcm_info *pcm = snd_soc_dai_get_drvdata(rtd->cpu_dai); + unsigned long flags; + + dev_dbg(pcm->dev, "Entered %s\n", __func__); + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + case SNDRV_PCM_TRIGGER_RESUME: + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: + spin_lock_irqsave(&pcm->lock, flags); + + if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) + s3c_pcm_snd_rxctrl(pcm, 1); + else + s3c_pcm_snd_txctrl(pcm, 1); + + spin_unlock_irqrestore(&pcm->lock, flags); + break; + + case SNDRV_PCM_TRIGGER_STOP: + case SNDRV_PCM_TRIGGER_SUSPEND: + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + spin_lock_irqsave(&pcm->lock, flags); + + if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) + s3c_pcm_snd_rxctrl(pcm, 0); + else + s3c_pcm_snd_txctrl(pcm, 0); + + spin_unlock_irqrestore(&pcm->lock, flags); + break; + + default: + return -EINVAL; + } + + return 0; +} + +static int s3c_pcm_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *socdai) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct s3c_pcm_info *pcm = snd_soc_dai_get_drvdata(rtd->cpu_dai); + struct s3c_dma_params *dma_data; + void __iomem *regs = pcm->regs; + struct clk *clk; + int sclk_div, sync_div; + unsigned long flags; + u32 clkctl; + + dev_dbg(pcm->dev, "Entered %s\n", __func__); + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + dma_data = pcm->dma_playback; + else + dma_data = pcm->dma_capture; + + snd_soc_dai_set_dma_data(rtd->cpu_dai, substream, dma_data); + + /* Strictly check for sample size */ + switch (params_format(params)) { + case SNDRV_PCM_FORMAT_S16_LE: + break; + default: + return -EINVAL; + } + + spin_lock_irqsave(&pcm->lock, flags); + + /* Get hold of the PCMSOURCE_CLK */ + clkctl = readl(regs + S3C_PCM_CLKCTL); + if (clkctl & S3C_PCM_CLKCTL_SERCLKSEL_PCLK) + clk = pcm->pclk; + else + clk = pcm->cclk; + + /* Set the SCLK divider */ + sclk_div = clk_get_rate(clk) / pcm->sclk_per_fs / + params_rate(params) / 2 - 1; + + clkctl &= ~(S3C_PCM_CLKCTL_SCLKDIV_MASK + << S3C_PCM_CLKCTL_SCLKDIV_SHIFT); + clkctl |= ((sclk_div & S3C_PCM_CLKCTL_SCLKDIV_MASK) + << S3C_PCM_CLKCTL_SCLKDIV_SHIFT); + + /* Set the SYNC divider */ + sync_div = pcm->sclk_per_fs - 1; + + clkctl &= ~(S3C_PCM_CLKCTL_SYNCDIV_MASK + << S3C_PCM_CLKCTL_SYNCDIV_SHIFT); + clkctl |= ((sync_div & S3C_PCM_CLKCTL_SYNCDIV_MASK) + << S3C_PCM_CLKCTL_SYNCDIV_SHIFT); + + writel(clkctl, regs + S3C_PCM_CLKCTL); + + spin_unlock_irqrestore(&pcm->lock, flags); + + dev_dbg(pcm->dev, "PCMSOURCE_CLK-%lu SCLK=%ufs SCLK_DIV=%d SYNC_DIV=%d\n", + clk_get_rate(clk), pcm->sclk_per_fs, + sclk_div, sync_div); + + return 0; +} + +static int s3c_pcm_set_fmt(struct snd_soc_dai *cpu_dai, + unsigned int fmt) +{ + struct s3c_pcm_info *pcm = snd_soc_dai_get_drvdata(cpu_dai); + void __iomem *regs = pcm->regs; + unsigned long flags; + int ret = 0; + u32 ctl; + + dev_dbg(pcm->dev, "Entered %s\n", __func__); + + spin_lock_irqsave(&pcm->lock, flags); + + ctl = readl(regs + S3C_PCM_CTL); + + switch (fmt & SND_SOC_DAIFMT_INV_MASK) { + case SND_SOC_DAIFMT_NB_NF: + /* Nothing to do, NB_NF by default */ + break; + default: + dev_err(pcm->dev, "Unsupported clock inversion!\n"); + ret = -EINVAL; + goto exit; + } + + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { + case SND_SOC_DAIFMT_CBS_CFS: + /* Nothing to do, Master by default */ + break; + default: + dev_err(pcm->dev, "Unsupported master/slave format!\n"); + ret = -EINVAL; + goto exit; + } + + switch (fmt & SND_SOC_DAIFMT_CLOCK_MASK) { + case SND_SOC_DAIFMT_CONT: + pcm->idleclk = 1; + break; + case SND_SOC_DAIFMT_GATED: + pcm->idleclk = 0; + break; + default: + dev_err(pcm->dev, "Invalid Clock gating request!\n"); + ret = -EINVAL; + goto exit; + } + + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { + case SND_SOC_DAIFMT_DSP_A: + ctl |= S3C_PCM_CTL_TXMSB_AFTER_FSYNC; + ctl |= S3C_PCM_CTL_RXMSB_AFTER_FSYNC; + break; + case SND_SOC_DAIFMT_DSP_B: + ctl &= ~S3C_PCM_CTL_TXMSB_AFTER_FSYNC; + ctl &= ~S3C_PCM_CTL_RXMSB_AFTER_FSYNC; + break; + default: + dev_err(pcm->dev, "Unsupported data format!\n"); + ret = -EINVAL; + goto exit; + } + + writel(ctl, regs + S3C_PCM_CTL); + +exit: + spin_unlock_irqrestore(&pcm->lock, flags); + + return ret; +} + +static int s3c_pcm_set_clkdiv(struct snd_soc_dai *cpu_dai, + int div_id, int div) +{ + struct s3c_pcm_info *pcm = snd_soc_dai_get_drvdata(cpu_dai); + + switch (div_id) { + case S3C_PCM_SCLK_PER_FS: + pcm->sclk_per_fs = div; + break; + + default: + return -EINVAL; + } + + return 0; +} + +static int s3c_pcm_set_sysclk(struct snd_soc_dai *cpu_dai, + int clk_id, unsigned int freq, int dir) +{ + struct s3c_pcm_info *pcm = snd_soc_dai_get_drvdata(cpu_dai); + void __iomem *regs = pcm->regs; + u32 clkctl = readl(regs + S3C_PCM_CLKCTL); + + switch (clk_id) { + case S3C_PCM_CLKSRC_PCLK: + clkctl |= S3C_PCM_CLKCTL_SERCLKSEL_PCLK; + break; + + case S3C_PCM_CLKSRC_MUX: + clkctl &= ~S3C_PCM_CLKCTL_SERCLKSEL_PCLK; + + if (clk_get_rate(pcm->cclk) != freq) + clk_set_rate(pcm->cclk, freq); + + break; + + default: + return -EINVAL; + } + + writel(clkctl, regs + S3C_PCM_CLKCTL); + + return 0; +} + +static struct snd_soc_dai_ops s3c_pcm_dai_ops = { + .set_sysclk = s3c_pcm_set_sysclk, + .set_clkdiv = s3c_pcm_set_clkdiv, + .trigger = s3c_pcm_trigger, + .hw_params = s3c_pcm_hw_params, + .set_fmt = s3c_pcm_set_fmt, +}; + +#define S3C_PCM_RATES SNDRV_PCM_RATE_8000_96000 + +#define S3C_PCM_DAI_DECLARE \ + .symmetric_rates = 1, \ + .ops = &s3c_pcm_dai_ops, \ + .playback = { \ + .channels_min = 2, \ + .channels_max = 2, \ + .rates = S3C_PCM_RATES, \ + .formats = SNDRV_PCM_FMTBIT_S16_LE, \ + }, \ + .capture = { \ + .channels_min = 2, \ + .channels_max = 2, \ + .rates = S3C_PCM_RATES, \ + .formats = SNDRV_PCM_FMTBIT_S16_LE, \ + } + +struct snd_soc_dai_driver s3c_pcm_dai[] = { + [0] = { + .name = "samsung-pcm.0", + S3C_PCM_DAI_DECLARE, + }, + [1] = { + .name = "samsung-pcm.1", + S3C_PCM_DAI_DECLARE, + }, +}; +EXPORT_SYMBOL_GPL(s3c_pcm_dai); + +static __devinit int s3c_pcm_dev_probe(struct platform_device *pdev) +{ + struct s3c_pcm_info *pcm; + struct resource *mem_res, *dmatx_res, *dmarx_res; + struct s3c_audio_pdata *pcm_pdata; + int ret; + + /* Check for valid device index */ + if ((pdev->id < 0) || pdev->id >= ARRAY_SIZE(s3c_pcm)) { + dev_err(&pdev->dev, "id %d out of range\n", pdev->id); + return -EINVAL; + } + + pcm_pdata = pdev->dev.platform_data; + + /* Check for availability of necessary resource */ + dmatx_res = platform_get_resource(pdev, IORESOURCE_DMA, 0); + if (!dmatx_res) { + dev_err(&pdev->dev, "Unable to get PCM-TX dma resource\n"); + return -ENXIO; + } + + dmarx_res = platform_get_resource(pdev, IORESOURCE_DMA, 1); + if (!dmarx_res) { + dev_err(&pdev->dev, "Unable to get PCM-RX dma resource\n"); + return -ENXIO; + } + + mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!mem_res) { + dev_err(&pdev->dev, "Unable to get register resource\n"); + return -ENXIO; + } + + if (pcm_pdata && pcm_pdata->cfg_gpio && pcm_pdata->cfg_gpio(pdev)) { + dev_err(&pdev->dev, "Unable to configure gpio\n"); + return -EINVAL; + } + + pcm = &s3c_pcm[pdev->id]; + pcm->dev = &pdev->dev; + + spin_lock_init(&pcm->lock); + + /* Default is 128fs */ + pcm->sclk_per_fs = 128; + + pcm->cclk = clk_get(&pdev->dev, "audio-bus"); + if (IS_ERR(pcm->cclk)) { + dev_err(&pdev->dev, "failed to get audio-bus\n"); + ret = PTR_ERR(pcm->cclk); + goto err1; + } + clk_enable(pcm->cclk); + + /* record our pcm structure for later use in the callbacks */ + dev_set_drvdata(&pdev->dev, pcm); + + if (!request_mem_region(mem_res->start, + resource_size(mem_res), "samsung-pcm")) { + dev_err(&pdev->dev, "Unable to request register region\n"); + ret = -EBUSY; + goto err2; + } + + pcm->regs = ioremap(mem_res->start, 0x100); + if (pcm->regs == NULL) { + dev_err(&pdev->dev, "cannot ioremap registers\n"); + ret = -ENXIO; + goto err3; + } + + pcm->pclk = clk_get(&pdev->dev, "pcm"); + if (IS_ERR(pcm->pclk)) { + dev_err(&pdev->dev, "failed to get pcm_clock\n"); + ret = -ENOENT; + goto err4; + } + clk_enable(pcm->pclk); + + ret = snd_soc_register_dai(&pdev->dev, &s3c_pcm_dai[pdev->id]); + if (ret != 0) { + dev_err(&pdev->dev, "failed to get pcm_clock\n"); + goto err5; + } + + s3c_pcm_stereo_in[pdev->id].dma_addr = mem_res->start + + S3C_PCM_RXFIFO; + s3c_pcm_stereo_out[pdev->id].dma_addr = mem_res->start + + S3C_PCM_TXFIFO; + + s3c_pcm_stereo_in[pdev->id].channel = dmarx_res->start; + s3c_pcm_stereo_out[pdev->id].channel = dmatx_res->start; + + pcm->dma_capture = &s3c_pcm_stereo_in[pdev->id]; + pcm->dma_playback = &s3c_pcm_stereo_out[pdev->id]; + + return 0; + +err5: + clk_disable(pcm->pclk); + clk_put(pcm->pclk); +err4: + iounmap(pcm->regs); +err3: + release_mem_region(mem_res->start, resource_size(mem_res)); +err2: + clk_disable(pcm->cclk); + clk_put(pcm->cclk); +err1: + return ret; +} + +static __devexit int s3c_pcm_dev_remove(struct platform_device *pdev) +{ + struct s3c_pcm_info *pcm = &s3c_pcm[pdev->id]; + struct resource *mem_res; + + snd_soc_unregister_dai(&pdev->dev); + + iounmap(pcm->regs); + + mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + release_mem_region(mem_res->start, resource_size(mem_res)); + + clk_disable(pcm->cclk); + clk_disable(pcm->pclk); + clk_put(pcm->pclk); + clk_put(pcm->cclk); + + return 0; +} + +static struct platform_driver s3c_pcm_driver = { + .probe = s3c_pcm_dev_probe, + .remove = s3c_pcm_dev_remove, + .driver = { + .name = "samsung-pcm", + .owner = THIS_MODULE, + }, +}; + +static int __init s3c_pcm_init(void) +{ + return platform_driver_register(&s3c_pcm_driver); +} +module_init(s3c_pcm_init); + +static void __exit s3c_pcm_exit(void) +{ + platform_driver_unregister(&s3c_pcm_driver); +} +module_exit(s3c_pcm_exit); + +/* Module information */ +MODULE_AUTHOR("Jaswinder Singh, "); +MODULE_DESCRIPTION("S3C PCM Controller Driver"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:samsung-pcm"); diff --git a/sound/soc/samsung/pcm.h b/sound/soc/samsung/pcm.h new file mode 100644 index 000000000000..03393dcf852d --- /dev/null +++ b/sound/soc/samsung/pcm.h @@ -0,0 +1,124 @@ +/* sound/soc/samsung/pcm.h + * + * 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. + * + */ + +#ifndef __S3C_PCM_H +#define __S3C_PCM_H __FILE__ + +/*Register Offsets */ +#define S3C_PCM_CTL (0x00) +#define S3C_PCM_CLKCTL (0x04) +#define S3C_PCM_TXFIFO (0x08) +#define S3C_PCM_RXFIFO (0x0C) +#define S3C_PCM_IRQCTL (0x10) +#define S3C_PCM_IRQSTAT (0x14) +#define S3C_PCM_FIFOSTAT (0x18) +#define S3C_PCM_CLRINT (0x20) + +/* PCM_CTL Bit-Fields */ +#define S3C_PCM_CTL_TXDIPSTICK_MASK (0x3f) +#define S3C_PCM_CTL_TXDIPSTICK_SHIFT (13) +#define S3C_PCM_CTL_RXDIPSTICK_MASK (0x3f) +#define S3C_PCM_CTL_RXDIPSTICK_SHIFT (7) +#define S3C_PCM_CTL_TXDMA_EN (0x1<<6) +#define S3C_PCM_CTL_RXDMA_EN (0x1<<5) +#define S3C_PCM_CTL_TXMSB_AFTER_FSYNC (0x1<<4) +#define S3C_PCM_CTL_RXMSB_AFTER_FSYNC (0x1<<3) +#define S3C_PCM_CTL_TXFIFO_EN (0x1<<2) +#define S3C_PCM_CTL_RXFIFO_EN (0x1<<1) +#define S3C_PCM_CTL_ENABLE (0x1<<0) + +/* PCM_CLKCTL Bit-Fields */ +#define S3C_PCM_CLKCTL_SERCLK_EN (0x1<<19) +#define S3C_PCM_CLKCTL_SERCLKSEL_PCLK (0x1<<18) +#define S3C_PCM_CLKCTL_SCLKDIV_MASK (0x1ff) +#define S3C_PCM_CLKCTL_SYNCDIV_MASK (0x1ff) +#define S3C_PCM_CLKCTL_SCLKDIV_SHIFT (9) +#define S3C_PCM_CLKCTL_SYNCDIV_SHIFT (0) + +/* PCM_TXFIFO Bit-Fields */ +#define S3C_PCM_TXFIFO_DVALID (0x1<<16) +#define S3C_PCM_TXFIFO_DATA_MSK (0xffff<<0) + +/* PCM_RXFIFO Bit-Fields */ +#define S3C_PCM_RXFIFO_DVALID (0x1<<16) +#define S3C_PCM_RXFIFO_DATA_MSK (0xffff<<0) + +/* PCM_IRQCTL Bit-Fields */ +#define S3C_PCM_IRQCTL_IRQEN (0x1<<14) +#define S3C_PCM_IRQCTL_WRDEN (0x1<<12) +#define S3C_PCM_IRQCTL_TXEMPTYEN (0x1<<11) +#define S3C_PCM_IRQCTL_TXALMSTEMPTYEN (0x1<<10) +#define S3C_PCM_IRQCTL_TXFULLEN (0x1<<9) +#define S3C_PCM_IRQCTL_TXALMSTFULLEN (0x1<<8) +#define S3C_PCM_IRQCTL_TXSTARVEN (0x1<<7) +#define S3C_PCM_IRQCTL_TXERROVRFLEN (0x1<<6) +#define S3C_PCM_IRQCTL_RXEMPTEN (0x1<<5) +#define S3C_PCM_IRQCTL_RXALMSTEMPTEN (0x1<<4) +#define S3C_PCM_IRQCTL_RXFULLEN (0x1<<3) +#define S3C_PCM_IRQCTL_RXALMSTFULLEN (0x1<<2) +#define S3C_PCM_IRQCTL_RXSTARVEN (0x1<<1) +#define S3C_PCM_IRQCTL_RXERROVRFLEN (0x1<<0) + +/* PCM_IRQSTAT Bit-Fields */ +#define S3C_PCM_IRQSTAT_IRQPND (0x1<<13) +#define S3C_PCM_IRQSTAT_WRD_XFER (0x1<<12) +#define S3C_PCM_IRQSTAT_TXEMPTY (0x1<<11) +#define S3C_PCM_IRQSTAT_TXALMSTEMPTY (0x1<<10) +#define S3C_PCM_IRQSTAT_TXFULL (0x1<<9) +#define S3C_PCM_IRQSTAT_TXALMSTFULL (0x1<<8) +#define S3C_PCM_IRQSTAT_TXSTARV (0x1<<7) +#define S3C_PCM_IRQSTAT_TXERROVRFL (0x1<<6) +#define S3C_PCM_IRQSTAT_RXEMPT (0x1<<5) +#define S3C_PCM_IRQSTAT_RXALMSTEMPT (0x1<<4) +#define S3C_PCM_IRQSTAT_RXFULL (0x1<<3) +#define S3C_PCM_IRQSTAT_RXALMSTFULL (0x1<<2) +#define S3C_PCM_IRQSTAT_RXSTARV (0x1<<1) +#define S3C_PCM_IRQSTAT_RXERROVRFL (0x1<<0) + +/* PCM_FIFOSTAT Bit-Fields */ +#define S3C_PCM_FIFOSTAT_TXCNT_MSK (0x3f<<14) +#define S3C_PCM_FIFOSTAT_TXFIFOEMPTY (0x1<<13) +#define S3C_PCM_FIFOSTAT_TXFIFOALMSTEMPTY (0x1<<12) +#define S3C_PCM_FIFOSTAT_TXFIFOFULL (0x1<<11) +#define S3C_PCM_FIFOSTAT_TXFIFOALMSTFULL (0x1<<10) +#define S3C_PCM_FIFOSTAT_RXCNT_MSK (0x3f<<4) +#define S3C_PCM_FIFOSTAT_RXFIFOEMPTY (0x1<<3) +#define S3C_PCM_FIFOSTAT_RXFIFOALMSTEMPTY (0x1<<2) +#define S3C_PCM_FIFOSTAT_RXFIFOFULL (0x1<<1) +#define S3C_PCM_FIFOSTAT_RXFIFOALMSTFULL (0x1<<0) + +#define S3C_PCM_CLKSRC_PCLK 0 +#define S3C_PCM_CLKSRC_MUX 1 + +#define S3C_PCM_SCLK_PER_FS 0 + +/** + * struct s3c_pcm_info - S3C PCM Controller information + * @dev: The parent device passed to use from the probe. + * @regs: The pointer to the device register block. + * @dma_playback: DMA information for playback channel. + * @dma_capture: DMA information for capture channel. + */ +struct s3c_pcm_info { + spinlock_t lock; + struct device *dev; + void __iomem *regs; + + unsigned int sclk_per_fs; + + /* Whether to keep PCMSCLK enabled even when idle(no active xfer) */ + unsigned int idleclk; + + struct clk *pclk; + struct clk *cclk; + + struct s3c_dma_params *dma_playback; + struct s3c_dma_params *dma_capture; +}; + +#endif /* __S3C_PCM_H */ diff --git a/sound/soc/samsung/regs-i2s-v2.h b/sound/soc/samsung/regs-i2s-v2.h new file mode 100644 index 000000000000..5e5e5680580b --- /dev/null +++ b/sound/soc/samsung/regs-i2s-v2.h @@ -0,0 +1,115 @@ +/* linux/include/asm-arm/plat-s3c24xx/regs-s3c2412-iis.h + * + * Copyright 2007 Simtec Electronics + * http://armlinux.simtec.co.uk/ + * + * 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. + * + * S3C2412 IIS register definition +*/ + +#ifndef __ASM_ARCH_REGS_S3C2412_IIS_H +#define __ASM_ARCH_REGS_S3C2412_IIS_H + +#define S3C2412_IISCON (0x00) +#define S3C2412_IISMOD (0x04) +#define S3C2412_IISFIC (0x08) +#define S3C2412_IISPSR (0x0C) +#define S3C2412_IISTXD (0x10) +#define S3C2412_IISRXD (0x14) + +#define S5PC1XX_IISFICS 0x18 +#define S5PC1XX_IISTXDS 0x1C + +#define S5PC1XX_IISCON_SW_RST (1 << 31) +#define S5PC1XX_IISCON_FRXOFSTATUS (1 << 26) +#define S5PC1XX_IISCON_FRXORINTEN (1 << 25) +#define S5PC1XX_IISCON_FTXSURSTAT (1 << 24) +#define S5PC1XX_IISCON_FTXSURINTEN (1 << 23) +#define S5PC1XX_IISCON_TXSDMAPAUSE (1 << 20) +#define S5PC1XX_IISCON_TXSDMACTIVE (1 << 18) + +#define S3C64XX_IISCON_FTXURSTATUS (1 << 17) +#define S3C64XX_IISCON_FTXURINTEN (1 << 16) +#define S3C64XX_IISCON_TXFIFO2_EMPTY (1 << 15) +#define S3C64XX_IISCON_TXFIFO1_EMPTY (1 << 14) +#define S3C64XX_IISCON_TXFIFO2_FULL (1 << 13) +#define S3C64XX_IISCON_TXFIFO1_FULL (1 << 12) + +#define S3C2412_IISCON_LRINDEX (1 << 11) +#define S3C2412_IISCON_TXFIFO_EMPTY (1 << 10) +#define S3C2412_IISCON_RXFIFO_EMPTY (1 << 9) +#define S3C2412_IISCON_TXFIFO_FULL (1 << 8) +#define S3C2412_IISCON_RXFIFO_FULL (1 << 7) +#define S3C2412_IISCON_TXDMA_PAUSE (1 << 6) +#define S3C2412_IISCON_RXDMA_PAUSE (1 << 5) +#define S3C2412_IISCON_TXCH_PAUSE (1 << 4) +#define S3C2412_IISCON_RXCH_PAUSE (1 << 3) +#define S3C2412_IISCON_TXDMA_ACTIVE (1 << 2) +#define S3C2412_IISCON_RXDMA_ACTIVE (1 << 1) +#define S3C2412_IISCON_IIS_ACTIVE (1 << 0) + +#define S5PC1XX_IISMOD_OPCLK_CDCLK_OUT (0 << 30) +#define S5PC1XX_IISMOD_OPCLK_CDCLK_IN (1 << 30) +#define S5PC1XX_IISMOD_OPCLK_BCLK_OUT (2 << 30) +#define S5PC1XX_IISMOD_OPCLK_PCLK (3 << 30) +#define S5PC1XX_IISMOD_OPCLK_MASK (3 << 30) +#define S5PC1XX_IISMOD_TXS_IDMA (1 << 28) /* Sec_TXFIFO use I-DMA */ +#define S5PC1XX_IISMOD_BLCS_MASK 0x3 +#define S5PC1XX_IISMOD_BLCS_SHIFT 26 +#define S5PC1XX_IISMOD_BLCP_MASK 0x3 +#define S5PC1XX_IISMOD_BLCP_SHIFT 24 + +#define S3C64XX_IISMOD_C2DD_HHALF (1 << 21) /* Discard Higher-half */ +#define S3C64XX_IISMOD_C2DD_LHALF (1 << 20) /* Discard Lower-half */ +#define S3C64XX_IISMOD_C1DD_HHALF (1 << 19) +#define S3C64XX_IISMOD_C1DD_LHALF (1 << 18) +#define S3C64XX_IISMOD_DC2_EN (1 << 17) +#define S3C64XX_IISMOD_DC1_EN (1 << 16) +#define S3C64XX_IISMOD_BLC_16BIT (0 << 13) +#define S3C64XX_IISMOD_BLC_8BIT (1 << 13) +#define S3C64XX_IISMOD_BLC_24BIT (2 << 13) +#define S3C64XX_IISMOD_BLC_MASK (3 << 13) + +#define S3C2412_IISMOD_IMS_SYSMUX (1 << 10) +#define S3C2412_IISMOD_SLAVE (1 << 11) +#define S3C2412_IISMOD_MODE_TXONLY (0 << 8) +#define S3C2412_IISMOD_MODE_RXONLY (1 << 8) +#define S3C2412_IISMOD_MODE_TXRX (2 << 8) +#define S3C2412_IISMOD_MODE_MASK (3 << 8) +#define S3C2412_IISMOD_LR_LLOW (0 << 7) +#define S3C2412_IISMOD_LR_RLOW (1 << 7) +#define S3C2412_IISMOD_SDF_IIS (0 << 5) +#define S3C2412_IISMOD_SDF_MSB (1 << 5) +#define S3C2412_IISMOD_SDF_LSB (2 << 5) +#define S3C2412_IISMOD_SDF_MASK (3 << 5) +#define S3C2412_IISMOD_RCLK_256FS (0 << 3) +#define S3C2412_IISMOD_RCLK_512FS (1 << 3) +#define S3C2412_IISMOD_RCLK_384FS (2 << 3) +#define S3C2412_IISMOD_RCLK_768FS (3 << 3) +#define S3C2412_IISMOD_RCLK_MASK (3 << 3) +#define S3C2412_IISMOD_BCLK_32FS (0 << 1) +#define S3C2412_IISMOD_BCLK_48FS (1 << 1) +#define S3C2412_IISMOD_BCLK_16FS (2 << 1) +#define S3C2412_IISMOD_BCLK_24FS (3 << 1) +#define S3C2412_IISMOD_BCLK_MASK (3 << 1) +#define S3C2412_IISMOD_8BIT (1 << 0) + +#define S3C64XX_IISMOD_CDCLKCON (1 << 12) + +#define S3C2412_IISPSR_PSREN (1 << 15) + +#define S3C64XX_IISFIC_TX2COUNT(x) (((x) >> 24) & 0xf) +#define S3C64XX_IISFIC_TX1COUNT(x) (((x) >> 16) & 0xf) + +#define S3C2412_IISFIC_TXFLUSH (1 << 15) +#define S3C2412_IISFIC_RXFLUSH (1 << 7) +#define S3C2412_IISFIC_TXCOUNT(x) (((x) >> 8) & 0xf) +#define S3C2412_IISFIC_RXCOUNT(x) (((x) >> 0) & 0xf) + +#define S5PC1XX_IISFICS_TXFLUSH (1 << 15) +#define S5PC1XX_IISFICS_TXCOUNT(x) (((x) >> 8) & 0x7f) + +#endif /* __ASM_ARCH_REGS_S3C2412_IIS_H */ diff --git a/sound/soc/samsung/rx1950_uda1380.c b/sound/soc/samsung/rx1950_uda1380.c new file mode 100644 index 000000000000..5a4587e02886 --- /dev/null +++ b/sound/soc/samsung/rx1950_uda1380.c @@ -0,0 +1,319 @@ +/* + * rx1950.c -- ALSA Soc Audio Layer + * + * Copyright (c) 2010 Vasily Khoruzhick + * + * Based on smdk2440.c and magician.c + * + * Authors: Graeme Gregory graeme.gregory@wolfsonmicro.com + * Philipp Zabel + * Denis Grigoriev + * Vasily Khoruzhick + * + * 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. + * + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include + +#include + +#include "dma.h" +#include "s3c24xx-i2s.h" +#include "../codecs/uda1380.h" + +static int rx1950_uda1380_init(struct snd_soc_pcm_runtime *rtd); +static int rx1950_startup(struct snd_pcm_substream *substream); +static int rx1950_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params); +static int rx1950_spk_power(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event); + +static unsigned int rates[] = { + 16000, + 44100, + 48000, +}; + +static struct snd_pcm_hw_constraint_list hw_rates = { + .count = ARRAY_SIZE(rates), + .list = rates, + .mask = 0, +}; + +static struct snd_soc_jack hp_jack; + +static struct snd_soc_jack_pin hp_jack_pins[] = { + { + .pin = "Headphone Jack", + .mask = SND_JACK_HEADPHONE, + }, + { + .pin = "Speaker", + .mask = SND_JACK_HEADPHONE, + .invert = 1, + }, +}; + +static struct snd_soc_jack_gpio hp_jack_gpios[] = { + [0] = { + .gpio = S3C2410_GPG(12), + .name = "hp-gpio", + .report = SND_JACK_HEADPHONE, + .invert = 1, + .debounce_time = 200, + }, +}; + +static struct snd_soc_ops rx1950_ops = { + .startup = rx1950_startup, + .hw_params = rx1950_hw_params, +}; + +/* s3c24xx digital audio interface glue - connects codec <--> CPU */ +static struct snd_soc_dai_link rx1950_uda1380_dai[] = { + { + .name = "uda1380", + .stream_name = "UDA1380 Duplex", + .cpu_dai_name = "s3c24xx-iis", + .codec_dai_name = "uda1380-hifi", + .init = rx1950_uda1380_init, + .platform_name = "samsung-audio", + .codec_name = "uda1380-codec.0-001a", + .ops = &rx1950_ops, + }, +}; + +static struct snd_soc_card rx1950_asoc = { + .name = "rx1950", + .dai_link = rx1950_uda1380_dai, + .num_links = ARRAY_SIZE(rx1950_uda1380_dai), +}; + +/* rx1950 machine dapm widgets */ +static const struct snd_soc_dapm_widget uda1380_dapm_widgets[] = { + SND_SOC_DAPM_HP("Headphone Jack", NULL), + SND_SOC_DAPM_MIC("Mic Jack", NULL), + SND_SOC_DAPM_SPK("Speaker", rx1950_spk_power), +}; + +/* rx1950 machine audio_map */ +static const struct snd_soc_dapm_route audio_map[] = { + /* headphone connected to VOUTLHP, VOUTRHP */ + {"Headphone Jack", NULL, "VOUTLHP"}, + {"Headphone Jack", NULL, "VOUTRHP"}, + + /* ext speaker connected to VOUTL, VOUTR */ + {"Speaker", NULL, "VOUTL"}, + {"Speaker", NULL, "VOUTR"}, + + /* mic is connected to VINM */ + {"VINM", NULL, "Mic Jack"}, +}; + +static struct platform_device *s3c24xx_snd_device; + +static int rx1950_startup(struct snd_pcm_substream *substream) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + + runtime->hw.rate_min = hw_rates.list[0]; + runtime->hw.rate_max = hw_rates.list[hw_rates.count - 1]; + runtime->hw.rates = SNDRV_PCM_RATE_KNOT; + + return snd_pcm_hw_constraint_list(runtime, 0, + SNDRV_PCM_HW_PARAM_RATE, + &hw_rates); +} + +static int rx1950_spk_power(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + if (SND_SOC_DAPM_EVENT_ON(event)) + gpio_set_value(S3C2410_GPA(1), 1); + else + gpio_set_value(S3C2410_GPA(1), 0); + + return 0; +} + +static int rx1950_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + struct snd_soc_dai *codec_dai = rtd->codec_dai; + int div; + int ret; + unsigned int rate = params_rate(params); + int clk_source, fs_mode; + + switch (rate) { + case 16000: + case 48000: + clk_source = S3C24XX_CLKSRC_PCLK; + fs_mode = S3C2410_IISMOD_256FS; + div = s3c24xx_i2s_get_clockrate() / (256 * rate); + if (s3c24xx_i2s_get_clockrate() % (256 * rate) > (128 * rate)) + div++; + break; + case 44100: + case 88200: + clk_source = S3C24XX_CLKSRC_MPLL; + fs_mode = S3C2410_IISMOD_384FS; + div = 1; + break; + default: + printk(KERN_ERR "%s: rate %d is not supported\n", + __func__, rate); + return -EINVAL; + } + + /* set codec DAI configuration */ + ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | + SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); + if (ret < 0) + return ret; + + /* set cpu DAI configuration */ + ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S | + SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); + if (ret < 0) + return ret; + + /* select clock source */ + ret = snd_soc_dai_set_sysclk(cpu_dai, clk_source, rate, + SND_SOC_CLOCK_OUT); + if (ret < 0) + return ret; + + /* set MCLK division for sample rate */ + ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C24XX_DIV_MCLK, + fs_mode); + if (ret < 0) + return ret; + + /* set BCLK division for sample rate */ + ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C24XX_DIV_BCLK, + S3C2410_IISMOD_32FS); + if (ret < 0) + return ret; + + /* set prescaler division for sample rate */ + ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C24XX_DIV_PRESCALER, + S3C24XX_PRESCALE(div, div)); + if (ret < 0) + return ret; + + return 0; +} + +static int rx1950_uda1380_init(struct snd_soc_pcm_runtime *rtd) +{ + struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_dapm_context *dapm = &codec->dapm; + int err; + + /* Add rx1950 specific widgets */ + err = snd_soc_dapm_new_controls(dapm, uda1380_dapm_widgets, + ARRAY_SIZE(uda1380_dapm_widgets)); + + if (err) + return err; + + /* Set up rx1950 specific audio path audio_mapnects */ + err = snd_soc_dapm_add_routes(dapm, audio_map, + ARRAY_SIZE(audio_map)); + + if (err) + return err; + + snd_soc_dapm_enable_pin(dapm, "Headphone Jack"); + snd_soc_dapm_enable_pin(dapm, "Speaker"); + + snd_soc_dapm_sync(dapm); + + snd_soc_jack_new(codec, "Headphone Jack", SND_JACK_HEADPHONE, + &hp_jack); + + snd_soc_jack_add_pins(&hp_jack, ARRAY_SIZE(hp_jack_pins), + hp_jack_pins); + + snd_soc_jack_add_gpios(&hp_jack, ARRAY_SIZE(hp_jack_gpios), + hp_jack_gpios); + + return 0; +} + +static int __init rx1950_init(void) +{ + int ret; + + if (!machine_is_rx1950()) + return -ENODEV; + + /* configure some gpios */ + ret = gpio_request(S3C2410_GPA(1), "speaker-power"); + if (ret) + goto err_gpio; + + ret = gpio_direction_output(S3C2410_GPA(1), 0); + if (ret) + goto err_gpio_conf; + + s3c24xx_snd_device = platform_device_alloc("soc-audio", -1); + if (!s3c24xx_snd_device) { + ret = -ENOMEM; + goto err_plat_alloc; + } + + platform_set_drvdata(s3c24xx_snd_device, &rx1950_asoc); + ret = platform_device_add(s3c24xx_snd_device); + + if (ret) { + platform_device_put(s3c24xx_snd_device); + goto err_plat_add; + } + + return 0; + +err_plat_add: +err_plat_alloc: +err_gpio_conf: + gpio_free(S3C2410_GPA(1)); + +err_gpio: + return ret; +} + +static void __exit rx1950_exit(void) +{ + platform_device_unregister(s3c24xx_snd_device); + snd_soc_jack_free_gpios(&hp_jack, ARRAY_SIZE(hp_jack_gpios), + hp_jack_gpios); + gpio_free(S3C2410_GPA(1)); +} + +module_init(rx1950_init); +module_exit(rx1950_exit); + +/* Module information */ +MODULE_AUTHOR("Vasily Khoruzhick"); +MODULE_DESCRIPTION("ALSA SoC RX1950"); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/samsung/s3c-i2s-v2.c b/sound/soc/samsung/s3c-i2s-v2.c new file mode 100644 index 000000000000..094f36e41e83 --- /dev/null +++ b/sound/soc/samsung/s3c-i2s-v2.c @@ -0,0 +1,757 @@ +/* sound/soc/samsung/s3c-i2c-v2.c + * + * ALSA Soc Audio Layer - I2S core for newer Samsung SoCs. + * + * Copyright (c) 2006 Wolfson Microelectronics PLC. + * Graeme Gregory graeme.gregory@wolfsonmicro.com + * linux@wolfsonmicro.com + * + * Copyright (c) 2008, 2007, 2004-2005 Simtec Electronics + * http://armlinux.simtec.co.uk/ + * Ben Dooks + * + * 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. + */ + +#include +#include +#include + +#include +#include +#include + +#include + +#include "regs-i2s-v2.h" +#include "s3c-i2s-v2.h" +#include "dma.h" + +#undef S3C_IIS_V2_SUPPORTED + +#if defined(CONFIG_CPU_S3C2412) || defined(CONFIG_CPU_S3C2413) \ + || defined(CONFIG_CPU_S5PV210) +#define S3C_IIS_V2_SUPPORTED +#endif + +#ifdef CONFIG_PLAT_S3C64XX +#define S3C_IIS_V2_SUPPORTED +#endif + +#ifndef S3C_IIS_V2_SUPPORTED +#error Unsupported CPU model +#endif + +#define S3C2412_I2S_DEBUG_CON 0 + +static inline struct s3c_i2sv2_info *to_info(struct snd_soc_dai *cpu_dai) +{ + return snd_soc_dai_get_drvdata(cpu_dai); +} + +#define bit_set(v, b) (((v) & (b)) ? 1 : 0) + +#if S3C2412_I2S_DEBUG_CON +static void dbg_showcon(const char *fn, u32 con) +{ + printk(KERN_DEBUG "%s: LRI=%d, TXFEMPT=%d, RXFEMPT=%d, TXFFULL=%d, RXFFULL=%d\n", fn, + bit_set(con, S3C2412_IISCON_LRINDEX), + bit_set(con, S3C2412_IISCON_TXFIFO_EMPTY), + bit_set(con, S3C2412_IISCON_RXFIFO_EMPTY), + bit_set(con, S3C2412_IISCON_TXFIFO_FULL), + bit_set(con, S3C2412_IISCON_RXFIFO_FULL)); + + printk(KERN_DEBUG "%s: PAUSE: TXDMA=%d, RXDMA=%d, TXCH=%d, RXCH=%d\n", + fn, + bit_set(con, S3C2412_IISCON_TXDMA_PAUSE), + bit_set(con, S3C2412_IISCON_RXDMA_PAUSE), + bit_set(con, S3C2412_IISCON_TXCH_PAUSE), + bit_set(con, S3C2412_IISCON_RXCH_PAUSE)); + printk(KERN_DEBUG "%s: ACTIVE: TXDMA=%d, RXDMA=%d, IIS=%d\n", fn, + bit_set(con, S3C2412_IISCON_TXDMA_ACTIVE), + bit_set(con, S3C2412_IISCON_RXDMA_ACTIVE), + bit_set(con, S3C2412_IISCON_IIS_ACTIVE)); +} +#else +static inline void dbg_showcon(const char *fn, u32 con) +{ +} +#endif + + +/* Turn on or off the transmission path. */ +static void s3c2412_snd_txctrl(struct s3c_i2sv2_info *i2s, int on) +{ + void __iomem *regs = i2s->regs; + u32 fic, con, mod; + + pr_debug("%s(%d)\n", __func__, on); + + fic = readl(regs + S3C2412_IISFIC); + con = readl(regs + S3C2412_IISCON); + mod = readl(regs + S3C2412_IISMOD); + + pr_debug("%s: IIS: CON=%x MOD=%x FIC=%x\n", __func__, con, mod, fic); + + if (on) { + con |= S3C2412_IISCON_TXDMA_ACTIVE | S3C2412_IISCON_IIS_ACTIVE; + con &= ~S3C2412_IISCON_TXDMA_PAUSE; + con &= ~S3C2412_IISCON_TXCH_PAUSE; + + switch (mod & S3C2412_IISMOD_MODE_MASK) { + case S3C2412_IISMOD_MODE_TXONLY: + case S3C2412_IISMOD_MODE_TXRX: + /* do nothing, we are in the right mode */ + break; + + case S3C2412_IISMOD_MODE_RXONLY: + mod &= ~S3C2412_IISMOD_MODE_MASK; + mod |= S3C2412_IISMOD_MODE_TXRX; + break; + + default: + dev_err(i2s->dev, "TXEN: Invalid MODE %x in IISMOD\n", + mod & S3C2412_IISMOD_MODE_MASK); + break; + } + + writel(con, regs + S3C2412_IISCON); + writel(mod, regs + S3C2412_IISMOD); + } else { + /* Note, we do not have any indication that the FIFO problems + * tha the S3C2410/2440 had apply here, so we should be able + * to disable the DMA and TX without resetting the FIFOS. + */ + + con |= S3C2412_IISCON_TXDMA_PAUSE; + con |= S3C2412_IISCON_TXCH_PAUSE; + con &= ~S3C2412_IISCON_TXDMA_ACTIVE; + + switch (mod & S3C2412_IISMOD_MODE_MASK) { + case S3C2412_IISMOD_MODE_TXRX: + mod &= ~S3C2412_IISMOD_MODE_MASK; + mod |= S3C2412_IISMOD_MODE_RXONLY; + break; + + case S3C2412_IISMOD_MODE_TXONLY: + mod &= ~S3C2412_IISMOD_MODE_MASK; + con &= ~S3C2412_IISCON_IIS_ACTIVE; + break; + + default: + dev_err(i2s->dev, "TXDIS: Invalid MODE %x in IISMOD\n", + mod & S3C2412_IISMOD_MODE_MASK); + break; + } + + writel(mod, regs + S3C2412_IISMOD); + writel(con, regs + S3C2412_IISCON); + } + + fic = readl(regs + S3C2412_IISFIC); + dbg_showcon(__func__, con); + pr_debug("%s: IIS: CON=%x MOD=%x FIC=%x\n", __func__, con, mod, fic); +} + +static void s3c2412_snd_rxctrl(struct s3c_i2sv2_info *i2s, int on) +{ + void __iomem *regs = i2s->regs; + u32 fic, con, mod; + + pr_debug("%s(%d)\n", __func__, on); + + fic = readl(regs + S3C2412_IISFIC); + con = readl(regs + S3C2412_IISCON); + mod = readl(regs + S3C2412_IISMOD); + + pr_debug("%s: IIS: CON=%x MOD=%x FIC=%x\n", __func__, con, mod, fic); + + if (on) { + con |= S3C2412_IISCON_RXDMA_ACTIVE | S3C2412_IISCON_IIS_ACTIVE; + con &= ~S3C2412_IISCON_RXDMA_PAUSE; + con &= ~S3C2412_IISCON_RXCH_PAUSE; + + switch (mod & S3C2412_IISMOD_MODE_MASK) { + case S3C2412_IISMOD_MODE_TXRX: + case S3C2412_IISMOD_MODE_RXONLY: + /* do nothing, we are in the right mode */ + break; + + case S3C2412_IISMOD_MODE_TXONLY: + mod &= ~S3C2412_IISMOD_MODE_MASK; + mod |= S3C2412_IISMOD_MODE_TXRX; + break; + + default: + dev_err(i2s->dev, "RXEN: Invalid MODE %x in IISMOD\n", + mod & S3C2412_IISMOD_MODE_MASK); + } + + writel(mod, regs + S3C2412_IISMOD); + writel(con, regs + S3C2412_IISCON); + } else { + /* See txctrl notes on FIFOs. */ + + con &= ~S3C2412_IISCON_RXDMA_ACTIVE; + con |= S3C2412_IISCON_RXDMA_PAUSE; + con |= S3C2412_IISCON_RXCH_PAUSE; + + switch (mod & S3C2412_IISMOD_MODE_MASK) { + case S3C2412_IISMOD_MODE_RXONLY: + con &= ~S3C2412_IISCON_IIS_ACTIVE; + mod &= ~S3C2412_IISMOD_MODE_MASK; + break; + + case S3C2412_IISMOD_MODE_TXRX: + mod &= ~S3C2412_IISMOD_MODE_MASK; + mod |= S3C2412_IISMOD_MODE_TXONLY; + break; + + default: + dev_err(i2s->dev, "RXDIS: Invalid MODE %x in IISMOD\n", + mod & S3C2412_IISMOD_MODE_MASK); + } + + writel(con, regs + S3C2412_IISCON); + writel(mod, regs + S3C2412_IISMOD); + } + + fic = readl(regs + S3C2412_IISFIC); + pr_debug("%s: IIS: CON=%x MOD=%x FIC=%x\n", __func__, con, mod, fic); +} + +#define msecs_to_loops(t) (loops_per_jiffy / 1000 * HZ * t) + +/* + * Wait for the LR signal to allow synchronisation to the L/R clock + * from the codec. May only be needed for slave mode. + */ +static int s3c2412_snd_lrsync(struct s3c_i2sv2_info *i2s) +{ + u32 iiscon; + unsigned long loops = msecs_to_loops(5); + + pr_debug("Entered %s\n", __func__); + + while (--loops) { + iiscon = readl(i2s->regs + S3C2412_IISCON); + if (iiscon & S3C2412_IISCON_LRINDEX) + break; + + cpu_relax(); + } + + if (!loops) { + printk(KERN_ERR "%s: timeout\n", __func__); + return -ETIMEDOUT; + } + + return 0; +} + +/* + * Set S3C2412 I2S DAI format + */ +static int s3c2412_i2s_set_fmt(struct snd_soc_dai *cpu_dai, + unsigned int fmt) +{ + struct s3c_i2sv2_info *i2s = to_info(cpu_dai); + u32 iismod; + + pr_debug("Entered %s\n", __func__); + + iismod = readl(i2s->regs + S3C2412_IISMOD); + pr_debug("hw_params r: IISMOD: %x \n", iismod); + + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { + case SND_SOC_DAIFMT_CBM_CFM: + i2s->master = 0; + iismod |= S3C2412_IISMOD_SLAVE; + break; + case SND_SOC_DAIFMT_CBS_CFS: + i2s->master = 1; + iismod &= ~S3C2412_IISMOD_SLAVE; + break; + default: + pr_err("unknwon master/slave format\n"); + return -EINVAL; + } + + iismod &= ~S3C2412_IISMOD_SDF_MASK; + + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { + case SND_SOC_DAIFMT_RIGHT_J: + iismod |= S3C2412_IISMOD_LR_RLOW; + iismod |= S3C2412_IISMOD_SDF_MSB; + break; + case SND_SOC_DAIFMT_LEFT_J: + iismod |= S3C2412_IISMOD_LR_RLOW; + iismod |= S3C2412_IISMOD_SDF_LSB; + break; + case SND_SOC_DAIFMT_I2S: + iismod &= ~S3C2412_IISMOD_LR_RLOW; + iismod |= S3C2412_IISMOD_SDF_IIS; + break; + default: + pr_err("Unknown data format\n"); + return -EINVAL; + } + + writel(iismod, i2s->regs + S3C2412_IISMOD); + pr_debug("hw_params w: IISMOD: %x \n", iismod); + return 0; +} + +static int s3c_i2sv2_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct s3c_i2sv2_info *i2s = to_info(dai); + struct s3c_dma_params *dma_data; + u32 iismod; + + pr_debug("Entered %s\n", __func__); + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + dma_data = i2s->dma_playback; + else + dma_data = i2s->dma_capture; + + snd_soc_dai_set_dma_data(dai, substream, dma_data); + + /* Working copies of register */ + iismod = readl(i2s->regs + S3C2412_IISMOD); + pr_debug("%s: r: IISMOD: %x\n", __func__, iismod); + + iismod &= ~S3C64XX_IISMOD_BLC_MASK; + /* Sample size */ + switch (params_format(params)) { + case SNDRV_PCM_FORMAT_S8: + iismod |= S3C64XX_IISMOD_BLC_8BIT; + break; + case SNDRV_PCM_FORMAT_S16_LE: + break; + case SNDRV_PCM_FORMAT_S24_LE: + iismod |= S3C64XX_IISMOD_BLC_24BIT; + break; + } + + writel(iismod, i2s->regs + S3C2412_IISMOD); + pr_debug("%s: w: IISMOD: %x\n", __func__, iismod); + + return 0; +} + +static int s3c_i2sv2_set_sysclk(struct snd_soc_dai *cpu_dai, + int clk_id, unsigned int freq, int dir) +{ + struct s3c_i2sv2_info *i2s = to_info(cpu_dai); + u32 iismod = readl(i2s->regs + S3C2412_IISMOD); + + pr_debug("Entered %s\n", __func__); + pr_debug("%s r: IISMOD: %x\n", __func__, iismod); + + switch (clk_id) { + case S3C_I2SV2_CLKSRC_PCLK: + iismod &= ~S3C2412_IISMOD_IMS_SYSMUX; + break; + + case S3C_I2SV2_CLKSRC_AUDIOBUS: + iismod |= S3C2412_IISMOD_IMS_SYSMUX; + break; + + case S3C_I2SV2_CLKSRC_CDCLK: + /* Error if controller doesn't have the CDCLKCON bit */ + if (!(i2s->feature & S3C_FEATURE_CDCLKCON)) + return -EINVAL; + + switch (dir) { + case SND_SOC_CLOCK_IN: + iismod |= S3C64XX_IISMOD_CDCLKCON; + break; + case SND_SOC_CLOCK_OUT: + iismod &= ~S3C64XX_IISMOD_CDCLKCON; + break; + default: + return -EINVAL; + } + break; + + default: + return -EINVAL; + } + + writel(iismod, i2s->regs + S3C2412_IISMOD); + pr_debug("%s w: IISMOD: %x\n", __func__, iismod); + + return 0; +} + +static int s3c2412_i2s_trigger(struct snd_pcm_substream *substream, int cmd, + struct snd_soc_dai *dai) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct s3c_i2sv2_info *i2s = to_info(rtd->cpu_dai); + int capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE); + unsigned long irqs; + int ret = 0; + struct s3c_dma_params *dma_data = + snd_soc_dai_get_dma_data(rtd->cpu_dai, substream); + + pr_debug("Entered %s\n", __func__); + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + /* On start, ensure that the FIFOs are cleared and reset. */ + + writel(capture ? S3C2412_IISFIC_RXFLUSH : S3C2412_IISFIC_TXFLUSH, + i2s->regs + S3C2412_IISFIC); + + /* clear again, just in case */ + writel(0x0, i2s->regs + S3C2412_IISFIC); + + case SNDRV_PCM_TRIGGER_RESUME: + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: + if (!i2s->master) { + ret = s3c2412_snd_lrsync(i2s); + if (ret) + goto exit_err; + } + + local_irq_save(irqs); + + if (capture) + s3c2412_snd_rxctrl(i2s, 1); + else + s3c2412_snd_txctrl(i2s, 1); + + local_irq_restore(irqs); + + /* + * Load the next buffer to DMA to meet the reqirement + * of the auto reload mechanism of S3C24XX. + * This call won't bother S3C64XX. + */ + s3c2410_dma_ctrl(dma_data->channel, S3C2410_DMAOP_STARTED); + + break; + + case SNDRV_PCM_TRIGGER_STOP: + case SNDRV_PCM_TRIGGER_SUSPEND: + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + local_irq_save(irqs); + + if (capture) + s3c2412_snd_rxctrl(i2s, 0); + else + s3c2412_snd_txctrl(i2s, 0); + + local_irq_restore(irqs); + break; + default: + ret = -EINVAL; + break; + } + +exit_err: + return ret; +} + +/* + * Set S3C2412 Clock dividers + */ +static int s3c2412_i2s_set_clkdiv(struct snd_soc_dai *cpu_dai, + int div_id, int div) +{ + struct s3c_i2sv2_info *i2s = to_info(cpu_dai); + u32 reg; + + pr_debug("%s(%p, %d, %d)\n", __func__, cpu_dai, div_id, div); + + switch (div_id) { + case S3C_I2SV2_DIV_BCLK: + switch (div) { + case 16: + div = S3C2412_IISMOD_BCLK_16FS; + break; + + case 32: + div = S3C2412_IISMOD_BCLK_32FS; + break; + + case 24: + div = S3C2412_IISMOD_BCLK_24FS; + break; + + case 48: + div = S3C2412_IISMOD_BCLK_48FS; + break; + + default: + return -EINVAL; + } + + reg = readl(i2s->regs + S3C2412_IISMOD); + reg &= ~S3C2412_IISMOD_BCLK_MASK; + writel(reg | div, i2s->regs + S3C2412_IISMOD); + + pr_debug("%s: MOD=%08x\n", __func__, readl(i2s->regs + S3C2412_IISMOD)); + break; + + case S3C_I2SV2_DIV_RCLK: + switch (div) { + case 256: + div = S3C2412_IISMOD_RCLK_256FS; + break; + + case 384: + div = S3C2412_IISMOD_RCLK_384FS; + break; + + case 512: + div = S3C2412_IISMOD_RCLK_512FS; + break; + + case 768: + div = S3C2412_IISMOD_RCLK_768FS; + break; + + default: + return -EINVAL; + } + + reg = readl(i2s->regs + S3C2412_IISMOD); + reg &= ~S3C2412_IISMOD_RCLK_MASK; + writel(reg | div, i2s->regs + S3C2412_IISMOD); + pr_debug("%s: MOD=%08x\n", __func__, readl(i2s->regs + S3C2412_IISMOD)); + break; + + case S3C_I2SV2_DIV_PRESCALER: + if (div >= 0) { + writel((div << 8) | S3C2412_IISPSR_PSREN, + i2s->regs + S3C2412_IISPSR); + } else { + writel(0x0, i2s->regs + S3C2412_IISPSR); + } + pr_debug("%s: PSR=%08x\n", __func__, readl(i2s->regs + S3C2412_IISPSR)); + break; + + default: + return -EINVAL; + } + + return 0; +} + +static snd_pcm_sframes_t s3c2412_i2s_delay(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct s3c_i2sv2_info *i2s = to_info(dai); + u32 reg = readl(i2s->regs + S3C2412_IISFIC); + snd_pcm_sframes_t delay; + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + delay = S3C2412_IISFIC_TXCOUNT(reg); + else + delay = S3C2412_IISFIC_RXCOUNT(reg); + + return delay; +} + +struct clk *s3c_i2sv2_get_clock(struct snd_soc_dai *cpu_dai) +{ + struct s3c_i2sv2_info *i2s = to_info(cpu_dai); + u32 iismod = readl(i2s->regs + S3C2412_IISMOD); + + if (iismod & S3C2412_IISMOD_IMS_SYSMUX) + return i2s->iis_cclk; + else + return i2s->iis_pclk; +} +EXPORT_SYMBOL_GPL(s3c_i2sv2_get_clock); + +/* default table of all avaialable root fs divisors */ +static unsigned int iis_fs_tab[] = { 256, 512, 384, 768 }; + +int s3c_i2sv2_iis_calc_rate(struct s3c_i2sv2_rate_calc *info, + unsigned int *fstab, + unsigned int rate, struct clk *clk) +{ + unsigned long clkrate = clk_get_rate(clk); + unsigned int div; + unsigned int fsclk; + unsigned int actual; + unsigned int fs; + unsigned int fsdiv; + signed int deviation = 0; + unsigned int best_fs = 0; + unsigned int best_div = 0; + unsigned int best_rate = 0; + unsigned int best_deviation = INT_MAX; + + pr_debug("Input clock rate %ldHz\n", clkrate); + + if (fstab == NULL) + fstab = iis_fs_tab; + + for (fs = 0; fs < ARRAY_SIZE(iis_fs_tab); fs++) { + fsdiv = iis_fs_tab[fs]; + + fsclk = clkrate / fsdiv; + div = fsclk / rate; + + if ((fsclk % rate) > (rate / 2)) + div++; + + if (div <= 1) + continue; + + actual = clkrate / (fsdiv * div); + deviation = actual - rate; + + printk(KERN_DEBUG "%ufs: div %u => result %u, deviation %d\n", + fsdiv, div, actual, deviation); + + deviation = abs(deviation); + + if (deviation < best_deviation) { + best_fs = fsdiv; + best_div = div; + best_rate = actual; + best_deviation = deviation; + } + + if (deviation == 0) + break; + } + + printk(KERN_DEBUG "best: fs=%u, div=%u, rate=%u\n", + best_fs, best_div, best_rate); + + info->fs_div = best_fs; + info->clk_div = best_div; + + return 0; +} +EXPORT_SYMBOL_GPL(s3c_i2sv2_iis_calc_rate); + +int s3c_i2sv2_probe(struct snd_soc_dai *dai, + struct s3c_i2sv2_info *i2s, + unsigned long base) +{ + struct device *dev = dai->dev; + unsigned int iismod; + + i2s->dev = dev; + + /* record our i2s structure for later use in the callbacks */ + snd_soc_dai_set_drvdata(dai, i2s); + + i2s->regs = ioremap(base, 0x100); + if (i2s->regs == NULL) { + dev_err(dev, "cannot ioremap registers\n"); + return -ENXIO; + } + + i2s->iis_pclk = clk_get(dev, "iis"); + if (IS_ERR(i2s->iis_pclk)) { + dev_err(dev, "failed to get iis_clock\n"); + iounmap(i2s->regs); + return -ENOENT; + } + + clk_enable(i2s->iis_pclk); + + /* Mark ourselves as in TXRX mode so we can run through our cleanup + * process without warnings. */ + iismod = readl(i2s->regs + S3C2412_IISMOD); + iismod |= S3C2412_IISMOD_MODE_TXRX; + writel(iismod, i2s->regs + S3C2412_IISMOD); + s3c2412_snd_txctrl(i2s, 0); + s3c2412_snd_rxctrl(i2s, 0); + + return 0; +} +EXPORT_SYMBOL_GPL(s3c_i2sv2_probe); + +#ifdef CONFIG_PM +static int s3c2412_i2s_suspend(struct snd_soc_dai *dai) +{ + struct s3c_i2sv2_info *i2s = to_info(dai); + u32 iismod; + + if (dai->active) { + i2s->suspend_iismod = readl(i2s->regs + S3C2412_IISMOD); + i2s->suspend_iiscon = readl(i2s->regs + S3C2412_IISCON); + i2s->suspend_iispsr = readl(i2s->regs + S3C2412_IISPSR); + + /* some basic suspend checks */ + + iismod = readl(i2s->regs + S3C2412_IISMOD); + + if (iismod & S3C2412_IISCON_RXDMA_ACTIVE) + pr_warning("%s: RXDMA active?\n", __func__); + + if (iismod & S3C2412_IISCON_TXDMA_ACTIVE) + pr_warning("%s: TXDMA active?\n", __func__); + + if (iismod & S3C2412_IISCON_IIS_ACTIVE) + pr_warning("%s: IIS active\n", __func__); + } + + return 0; +} + +static int s3c2412_i2s_resume(struct snd_soc_dai *dai) +{ + struct s3c_i2sv2_info *i2s = to_info(dai); + + pr_info("dai_active %d, IISMOD %08x, IISCON %08x\n", + dai->active, i2s->suspend_iismod, i2s->suspend_iiscon); + + if (dai->active) { + writel(i2s->suspend_iiscon, i2s->regs + S3C2412_IISCON); + writel(i2s->suspend_iismod, i2s->regs + S3C2412_IISMOD); + writel(i2s->suspend_iispsr, i2s->regs + S3C2412_IISPSR); + + writel(S3C2412_IISFIC_RXFLUSH | S3C2412_IISFIC_TXFLUSH, + i2s->regs + S3C2412_IISFIC); + + ndelay(250); + writel(0x0, i2s->regs + S3C2412_IISFIC); + } + + return 0; +} +#else +#define s3c2412_i2s_suspend NULL +#define s3c2412_i2s_resume NULL +#endif + +int s3c_i2sv2_register_dai(struct device *dev, int id, + struct snd_soc_dai_driver *drv) +{ + struct snd_soc_dai_ops *ops = drv->ops; + + ops->trigger = s3c2412_i2s_trigger; + if (!ops->hw_params) + ops->hw_params = s3c_i2sv2_hw_params; + ops->set_fmt = s3c2412_i2s_set_fmt; + ops->set_clkdiv = s3c2412_i2s_set_clkdiv; + ops->set_sysclk = s3c_i2sv2_set_sysclk; + + /* Allow overriding by (for example) IISv4 */ + if (!ops->delay) + ops->delay = s3c2412_i2s_delay; + + drv->suspend = s3c2412_i2s_suspend; + drv->resume = s3c2412_i2s_resume; + + return snd_soc_register_dai(dev, drv); +} +EXPORT_SYMBOL_GPL(s3c_i2sv2_register_dai); + +MODULE_LICENSE("GPL"); diff --git a/sound/soc/samsung/s3c-i2s-v2.h b/sound/soc/samsung/s3c-i2s-v2.h new file mode 100644 index 000000000000..f8297d9bb8a3 --- /dev/null +++ b/sound/soc/samsung/s3c-i2s-v2.h @@ -0,0 +1,106 @@ +/* sound/soc/samsung/s3c-i2s-v2.h + * + * ALSA Soc Audio Layer - S3C_I2SV2 I2S driver + * + * Copyright (c) 2007 Simtec Electronics + * http://armlinux.simtec.co.uk/ + * Ben Dooks + * + * 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. +*/ + +/* This code is the core support for the I2S block found in a number of + * Samsung SoC devices which is unofficially named I2S-V2. Currently the + * S3C2412 and the S3C64XX series use this block to provide 1 or 2 I2S + * channels via configurable GPIO. + */ + +#ifndef __SND_SOC_S3C24XX_S3C_I2SV2_I2S_H +#define __SND_SOC_S3C24XX_S3C_I2SV2_I2S_H __FILE__ + +#define S3C_I2SV2_DIV_BCLK (1) +#define S3C_I2SV2_DIV_RCLK (2) +#define S3C_I2SV2_DIV_PRESCALER (3) + +#define S3C_I2SV2_CLKSRC_PCLK 0 +#define S3C_I2SV2_CLKSRC_AUDIOBUS 1 +#define S3C_I2SV2_CLKSRC_CDCLK 2 + +/* Set this flag for I2S controllers that have the bit IISMOD[12] + * bridge/break RCLK signal and external Xi2sCDCLK pin. + */ +#define S3C_FEATURE_CDCLKCON (1 << 0) + +/** + * struct s3c_i2sv2_info - S3C I2S-V2 information + * @dev: The parent device passed to use from the probe. + * @regs: The pointer to the device registe block. + * @feature: Set of bit-flags indicating features of the controller. + * @master: True if the I2S core is the I2S bit clock master. + * @dma_playback: DMA information for playback channel. + * @dma_capture: DMA information for capture channel. + * @suspend_iismod: PM save for the IISMOD register. + * @suspend_iiscon: PM save for the IISCON register. + * @suspend_iispsr: PM save for the IISPSR register. + * + * This is the private codec state for the hardware associated with an + * I2S channel such as the register mappings and clock sources. + */ +struct s3c_i2sv2_info { + struct device *dev; + void __iomem *regs; + + u32 feature; + + struct clk *iis_pclk; + struct clk *iis_cclk; + + unsigned char master; + + struct s3c_dma_params *dma_playback; + struct s3c_dma_params *dma_capture; + + u32 suspend_iismod; + u32 suspend_iiscon; + u32 suspend_iispsr; + + unsigned long base; +}; + +extern struct clk *s3c_i2sv2_get_clock(struct snd_soc_dai *cpu_dai); + +struct s3c_i2sv2_rate_calc { + unsigned int clk_div; /* for prescaler */ + unsigned int fs_div; /* for root frame clock */ +}; + +extern int s3c_i2sv2_iis_calc_rate(struct s3c_i2sv2_rate_calc *info, + unsigned int *fstab, + unsigned int rate, struct clk *clk); + +/** + * s3c_i2sv2_probe - probe for i2s device helper + * @dai: The ASoC DAI structure supplied to the original probe. + * @i2s: Our local i2s structure to fill in. + * @base: The base address for the registers. + */ +extern int s3c_i2sv2_probe(struct snd_soc_dai *dai, + struct s3c_i2sv2_info *i2s, + unsigned long base); + +/** + * s3c_i2sv2_register_dai - register dai with soc core + * @dev: DAI device + * @id: DAI ID + * @drv: The driver structure to register + * + * Fill in any missing fields and then register the given dai with the + * soc core. + */ +extern int s3c_i2sv2_register_dai(struct device *dev, int id, + struct snd_soc_dai_driver *drv); + +#endif /* __SND_SOC_S3C24XX_S3C_I2SV2_I2S_H */ diff --git a/sound/soc/samsung/s3c2412-i2s.c b/sound/soc/samsung/s3c2412-i2s.c new file mode 100644 index 000000000000..7ea837867124 --- /dev/null +++ b/sound/soc/samsung/s3c2412-i2s.c @@ -0,0 +1,212 @@ +/* sound/soc/samsung/s3c2412-i2s.c + * + * ALSA Soc Audio Layer - S3C2412 I2S driver + * + * Copyright (c) 2006 Wolfson Microelectronics PLC. + * Graeme Gregory graeme.gregory@wolfsonmicro.com + * linux@wolfsonmicro.com + * + * Copyright (c) 2007, 2004-2005 Simtec Electronics + * http://armlinux.simtec.co.uk/ + * Ben Dooks + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "dma.h" +#include "regs-i2s-v2.h" +#include "s3c2412-i2s.h" + +#define S3C2412_I2S_DEBUG 0 + +static struct s3c2410_dma_client s3c2412_dma_client_out = { + .name = "I2S PCM Stereo out" +}; + +static struct s3c2410_dma_client s3c2412_dma_client_in = { + .name = "I2S PCM Stereo in" +}; + +static struct s3c_dma_params s3c2412_i2s_pcm_stereo_out = { + .client = &s3c2412_dma_client_out, + .channel = DMACH_I2S_OUT, + .dma_addr = S3C2410_PA_IIS + S3C2412_IISTXD, + .dma_size = 4, +}; + +static struct s3c_dma_params s3c2412_i2s_pcm_stereo_in = { + .client = &s3c2412_dma_client_in, + .channel = DMACH_I2S_IN, + .dma_addr = S3C2410_PA_IIS + S3C2412_IISRXD, + .dma_size = 4, +}; + +static struct s3c_i2sv2_info s3c2412_i2s; + +static int s3c2412_i2s_probe(struct snd_soc_dai *dai) +{ + int ret; + + pr_debug("Entered %s\n", __func__); + + ret = s3c_i2sv2_probe(dai, &s3c2412_i2s, S3C2410_PA_IIS); + if (ret) + return ret; + + s3c2412_i2s.dma_capture = &s3c2412_i2s_pcm_stereo_in; + s3c2412_i2s.dma_playback = &s3c2412_i2s_pcm_stereo_out; + + s3c2412_i2s.iis_cclk = clk_get(dai->dev, "i2sclk"); + if (s3c2412_i2s.iis_cclk == NULL) { + pr_err("failed to get i2sclk clock\n"); + iounmap(s3c2412_i2s.regs); + return -ENODEV; + } + + /* Set MPLL as the source for IIS CLK */ + + clk_set_parent(s3c2412_i2s.iis_cclk, clk_get(NULL, "mpll")); + clk_enable(s3c2412_i2s.iis_cclk); + + s3c2412_i2s.iis_cclk = s3c2412_i2s.iis_pclk; + + /* Configure the I2S pins in correct mode */ + s3c2410_gpio_cfgpin(S3C2410_GPE0, S3C2410_GPE0_I2SLRCK); + s3c2410_gpio_cfgpin(S3C2410_GPE1, S3C2410_GPE1_I2SSCLK); + s3c2410_gpio_cfgpin(S3C2410_GPE2, S3C2410_GPE2_CDCLK); + s3c2410_gpio_cfgpin(S3C2410_GPE3, S3C2410_GPE3_I2SSDI); + s3c2410_gpio_cfgpin(S3C2410_GPE4, S3C2410_GPE4_I2SSDO); + + return 0; +} + +static int s3c2412_i2s_remove(struct snd_soc_dai *dai) +{ + clk_disable(s3c2412_i2s.iis_cclk); + clk_put(s3c2412_i2s.iis_cclk); + iounmap(s3c2412_i2s.regs); + + return 0; +} + +static int s3c2412_i2s_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *cpu_dai) +{ + struct s3c_i2sv2_info *i2s = snd_soc_dai_get_drvdata(cpu_dai); + struct s3c_dma_params *dma_data; + u32 iismod; + + pr_debug("Entered %s\n", __func__); + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + dma_data = i2s->dma_playback; + else + dma_data = i2s->dma_capture; + + snd_soc_dai_set_dma_data(cpu_dai, substream, dma_data); + + iismod = readl(i2s->regs + S3C2412_IISMOD); + pr_debug("%s: r: IISMOD: %x\n", __func__, iismod); + + switch (params_format(params)) { + case SNDRV_PCM_FORMAT_S8: + iismod |= S3C2412_IISMOD_8BIT; + break; + case SNDRV_PCM_FORMAT_S16_LE: + iismod &= ~S3C2412_IISMOD_8BIT; + break; + } + + writel(iismod, i2s->regs + S3C2412_IISMOD); + pr_debug("%s: w: IISMOD: %x\n", __func__, iismod); + + return 0; +} + +#define S3C2412_I2S_RATES \ + (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | SNDRV_PCM_RATE_16000 | \ + SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \ + SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000) + +static struct snd_soc_dai_ops s3c2412_i2s_dai_ops = { + .hw_params = s3c2412_i2s_hw_params, +}; + +static struct snd_soc_dai_driver s3c2412_i2s_dai = { + .probe = s3c2412_i2s_probe, + .remove = s3c2412_i2s_remove, + .playback = { + .channels_min = 2, + .channels_max = 2, + .rates = S3C2412_I2S_RATES, + .formats = SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE, + }, + .capture = { + .channels_min = 2, + .channels_max = 2, + .rates = S3C2412_I2S_RATES, + .formats = SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE, + }, + .ops = &s3c2412_i2s_dai_ops, +}; + +static __devinit int s3c2412_iis_dev_probe(struct platform_device *pdev) +{ + return snd_soc_register_dai(&pdev->dev, &s3c2412_i2s_dai); +} + +static __devexit int s3c2412_iis_dev_remove(struct platform_device *pdev) +{ + snd_soc_unregister_dai(&pdev->dev); + return 0; +} + +static struct platform_driver s3c2412_iis_driver = { + .probe = s3c2412_iis_dev_probe, + .remove = s3c2412_iis_dev_remove, + .driver = { + .name = "s3c2412-iis", + .owner = THIS_MODULE, + }, +}; + +static int __init s3c2412_i2s_init(void) +{ + return platform_driver_register(&s3c2412_iis_driver); +} +module_init(s3c2412_i2s_init); + +static void __exit s3c2412_i2s_exit(void) +{ + platform_driver_unregister(&s3c2412_iis_driver); +} +module_exit(s3c2412_i2s_exit); + +/* Module information */ +MODULE_AUTHOR("Ben Dooks, "); +MODULE_DESCRIPTION("S3C2412 I2S SoC Interface"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:s3c2412-iis"); diff --git a/sound/soc/samsung/s3c2412-i2s.h b/sound/soc/samsung/s3c2412-i2s.h new file mode 100644 index 000000000000..02ad5794c0a9 --- /dev/null +++ b/sound/soc/samsung/s3c2412-i2s.h @@ -0,0 +1,27 @@ +/* sound/soc/samsung/s3c2412-i2s.c + * + * ALSA Soc Audio Layer - S3C2412 I2S driver + * + * Copyright (c) 2007 Simtec Electronics + * http://armlinux.simtec.co.uk/ + * Ben Dooks + * + * 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 __SND_SOC_S3C24XX_S3C2412_I2S_H +#define __SND_SOC_S3C24XX_S3C2412_I2S_H __FILE__ + +#include "s3c-i2s-v2.h" + +#define S3C2412_DIV_BCLK S3C_I2SV2_DIV_BCLK +#define S3C2412_DIV_RCLK S3C_I2SV2_DIV_RCLK +#define S3C2412_DIV_PRESCALER S3C_I2SV2_DIV_PRESCALER + +#define S3C2412_CLKSRC_PCLK S3C_I2SV2_CLKSRC_PCLK +#define S3C2412_CLKSRC_I2SCLK S3C_I2SV2_CLKSRC_AUDIOBUS + +#endif /* __SND_SOC_S3C24XX_S3C2412_I2S_H */ diff --git a/sound/soc/samsung/s3c24xx-i2s.c b/sound/soc/samsung/s3c24xx-i2s.c new file mode 100644 index 000000000000..13e41ed8e22b --- /dev/null +++ b/sound/soc/samsung/s3c24xx-i2s.c @@ -0,0 +1,519 @@ +/* + * s3c24xx-i2s.c -- ALSA Soc Audio Layer + * + * (c) 2006 Wolfson Microelectronics PLC. + * Graeme Gregory graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com + * + * Copyright 2004-2005 Simtec Electronics + * http://armlinux.simtec.co.uk/ + * Ben Dooks + * + * 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. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include + +#include "dma.h" +#include "s3c24xx-i2s.h" + +static struct s3c2410_dma_client s3c24xx_dma_client_out = { + .name = "I2S PCM Stereo out" +}; + +static struct s3c2410_dma_client s3c24xx_dma_client_in = { + .name = "I2S PCM Stereo in" +}; + +static struct s3c_dma_params s3c24xx_i2s_pcm_stereo_out = { + .client = &s3c24xx_dma_client_out, + .channel = DMACH_I2S_OUT, + .dma_addr = S3C2410_PA_IIS + S3C2410_IISFIFO, + .dma_size = 2, +}; + +static struct s3c_dma_params s3c24xx_i2s_pcm_stereo_in = { + .client = &s3c24xx_dma_client_in, + .channel = DMACH_I2S_IN, + .dma_addr = S3C2410_PA_IIS + S3C2410_IISFIFO, + .dma_size = 2, +}; + +struct s3c24xx_i2s_info { + void __iomem *regs; + struct clk *iis_clk; + u32 iiscon; + u32 iismod; + u32 iisfcon; + u32 iispsr; +}; +static struct s3c24xx_i2s_info s3c24xx_i2s; + +static void s3c24xx_snd_txctrl(int on) +{ + u32 iisfcon; + u32 iiscon; + u32 iismod; + + pr_debug("Entered %s\n", __func__); + + iisfcon = readl(s3c24xx_i2s.regs + S3C2410_IISFCON); + iiscon = readl(s3c24xx_i2s.regs + S3C2410_IISCON); + iismod = readl(s3c24xx_i2s.regs + S3C2410_IISMOD); + + pr_debug("r: IISCON: %x IISMOD: %x IISFCON: %x\n", iiscon, iismod, iisfcon); + + if (on) { + iisfcon |= S3C2410_IISFCON_TXDMA | S3C2410_IISFCON_TXENABLE; + iiscon |= S3C2410_IISCON_TXDMAEN | S3C2410_IISCON_IISEN; + iiscon &= ~S3C2410_IISCON_TXIDLE; + iismod |= S3C2410_IISMOD_TXMODE; + + writel(iismod, s3c24xx_i2s.regs + S3C2410_IISMOD); + writel(iisfcon, s3c24xx_i2s.regs + S3C2410_IISFCON); + writel(iiscon, s3c24xx_i2s.regs + S3C2410_IISCON); + } else { + /* note, we have to disable the FIFOs otherwise bad things + * seem to happen when the DMA stops. According to the + * Samsung supplied kernel, this should allow the DMA + * engine and FIFOs to reset. If this isn't allowed, the + * DMA engine will simply freeze randomly. + */ + + iisfcon &= ~S3C2410_IISFCON_TXENABLE; + iisfcon &= ~S3C2410_IISFCON_TXDMA; + iiscon |= S3C2410_IISCON_TXIDLE; + iiscon &= ~S3C2410_IISCON_TXDMAEN; + iismod &= ~S3C2410_IISMOD_TXMODE; + + writel(iiscon, s3c24xx_i2s.regs + S3C2410_IISCON); + writel(iisfcon, s3c24xx_i2s.regs + S3C2410_IISFCON); + writel(iismod, s3c24xx_i2s.regs + S3C2410_IISMOD); + } + + pr_debug("w: IISCON: %x IISMOD: %x IISFCON: %x\n", iiscon, iismod, iisfcon); +} + +static void s3c24xx_snd_rxctrl(int on) +{ + u32 iisfcon; + u32 iiscon; + u32 iismod; + + pr_debug("Entered %s\n", __func__); + + iisfcon = readl(s3c24xx_i2s.regs + S3C2410_IISFCON); + iiscon = readl(s3c24xx_i2s.regs + S3C2410_IISCON); + iismod = readl(s3c24xx_i2s.regs + S3C2410_IISMOD); + + pr_debug("r: IISCON: %x IISMOD: %x IISFCON: %x\n", iiscon, iismod, iisfcon); + + if (on) { + iisfcon |= S3C2410_IISFCON_RXDMA | S3C2410_IISFCON_RXENABLE; + iiscon |= S3C2410_IISCON_RXDMAEN | S3C2410_IISCON_IISEN; + iiscon &= ~S3C2410_IISCON_RXIDLE; + iismod |= S3C2410_IISMOD_RXMODE; + + writel(iismod, s3c24xx_i2s.regs + S3C2410_IISMOD); + writel(iisfcon, s3c24xx_i2s.regs + S3C2410_IISFCON); + writel(iiscon, s3c24xx_i2s.regs + S3C2410_IISCON); + } else { + /* note, we have to disable the FIFOs otherwise bad things + * seem to happen when the DMA stops. According to the + * Samsung supplied kernel, this should allow the DMA + * engine and FIFOs to reset. If this isn't allowed, the + * DMA engine will simply freeze randomly. + */ + + iisfcon &= ~S3C2410_IISFCON_RXENABLE; + iisfcon &= ~S3C2410_IISFCON_RXDMA; + iiscon |= S3C2410_IISCON_RXIDLE; + iiscon &= ~S3C2410_IISCON_RXDMAEN; + iismod &= ~S3C2410_IISMOD_RXMODE; + + writel(iisfcon, s3c24xx_i2s.regs + S3C2410_IISFCON); + writel(iiscon, s3c24xx_i2s.regs + S3C2410_IISCON); + writel(iismod, s3c24xx_i2s.regs + S3C2410_IISMOD); + } + + pr_debug("w: IISCON: %x IISMOD: %x IISFCON: %x\n", iiscon, iismod, iisfcon); +} + +/* + * Wait for the LR signal to allow synchronisation to the L/R clock + * from the codec. May only be needed for slave mode. + */ +static int s3c24xx_snd_lrsync(void) +{ + u32 iiscon; + int timeout = 50; /* 5ms */ + + pr_debug("Entered %s\n", __func__); + + while (1) { + iiscon = readl(s3c24xx_i2s.regs + S3C2410_IISCON); + if (iiscon & S3C2410_IISCON_LRINDEX) + break; + + if (!timeout--) + return -ETIMEDOUT; + udelay(100); + } + + return 0; +} + +/* + * Check whether CPU is the master or slave + */ +static inline int s3c24xx_snd_is_clkmaster(void) +{ + pr_debug("Entered %s\n", __func__); + + return (readl(s3c24xx_i2s.regs + S3C2410_IISMOD) & S3C2410_IISMOD_SLAVE) ? 0:1; +} + +/* + * Set S3C24xx I2S DAI format + */ +static int s3c24xx_i2s_set_fmt(struct snd_soc_dai *cpu_dai, + unsigned int fmt) +{ + u32 iismod; + + pr_debug("Entered %s\n", __func__); + + iismod = readl(s3c24xx_i2s.regs + S3C2410_IISMOD); + pr_debug("hw_params r: IISMOD: %x \n", iismod); + + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { + case SND_SOC_DAIFMT_CBM_CFM: + iismod |= S3C2410_IISMOD_SLAVE; + break; + case SND_SOC_DAIFMT_CBS_CFS: + iismod &= ~S3C2410_IISMOD_SLAVE; + break; + default: + return -EINVAL; + } + + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { + case SND_SOC_DAIFMT_LEFT_J: + iismod |= S3C2410_IISMOD_MSB; + break; + case SND_SOC_DAIFMT_I2S: + iismod &= ~S3C2410_IISMOD_MSB; + break; + default: + return -EINVAL; + } + + writel(iismod, s3c24xx_i2s.regs + S3C2410_IISMOD); + pr_debug("hw_params w: IISMOD: %x \n", iismod); + return 0; +} + +static int s3c24xx_i2s_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct s3c_dma_params *dma_data; + u32 iismod; + + pr_debug("Entered %s\n", __func__); + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + dma_data = &s3c24xx_i2s_pcm_stereo_out; + else + dma_data = &s3c24xx_i2s_pcm_stereo_in; + + snd_soc_dai_set_dma_data(rtd->cpu_dai, substream, dma_data); + + /* Working copies of register */ + iismod = readl(s3c24xx_i2s.regs + S3C2410_IISMOD); + pr_debug("hw_params r: IISMOD: %x\n", iismod); + + switch (params_format(params)) { + case SNDRV_PCM_FORMAT_S8: + iismod &= ~S3C2410_IISMOD_16BIT; + dma_data->dma_size = 1; + break; + case SNDRV_PCM_FORMAT_S16_LE: + iismod |= S3C2410_IISMOD_16BIT; + dma_data->dma_size = 2; + break; + default: + return -EINVAL; + } + + writel(iismod, s3c24xx_i2s.regs + S3C2410_IISMOD); + pr_debug("hw_params w: IISMOD: %x\n", iismod); + return 0; +} + +static int s3c24xx_i2s_trigger(struct snd_pcm_substream *substream, int cmd, + struct snd_soc_dai *dai) +{ + int ret = 0; + struct s3c_dma_params *dma_data = + snd_soc_dai_get_dma_data(dai, substream); + + pr_debug("Entered %s\n", __func__); + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + case SNDRV_PCM_TRIGGER_RESUME: + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: + if (!s3c24xx_snd_is_clkmaster()) { + ret = s3c24xx_snd_lrsync(); + if (ret) + goto exit_err; + } + + if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) + s3c24xx_snd_rxctrl(1); + else + s3c24xx_snd_txctrl(1); + + s3c2410_dma_ctrl(dma_data->channel, S3C2410_DMAOP_STARTED); + break; + case SNDRV_PCM_TRIGGER_STOP: + case SNDRV_PCM_TRIGGER_SUSPEND: + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) + s3c24xx_snd_rxctrl(0); + else + s3c24xx_snd_txctrl(0); + break; + default: + ret = -EINVAL; + break; + } + +exit_err: + return ret; +} + +/* + * Set S3C24xx Clock source + */ +static int s3c24xx_i2s_set_sysclk(struct snd_soc_dai *cpu_dai, + int clk_id, unsigned int freq, int dir) +{ + u32 iismod = readl(s3c24xx_i2s.regs + S3C2410_IISMOD); + + pr_debug("Entered %s\n", __func__); + + iismod &= ~S3C2440_IISMOD_MPLL; + + switch (clk_id) { + case S3C24XX_CLKSRC_PCLK: + break; + case S3C24XX_CLKSRC_MPLL: + iismod |= S3C2440_IISMOD_MPLL; + break; + default: + return -EINVAL; + } + + writel(iismod, s3c24xx_i2s.regs + S3C2410_IISMOD); + return 0; +} + +/* + * Set S3C24xx Clock dividers + */ +static int s3c24xx_i2s_set_clkdiv(struct snd_soc_dai *cpu_dai, + int div_id, int div) +{ + u32 reg; + + pr_debug("Entered %s\n", __func__); + + switch (div_id) { + case S3C24XX_DIV_BCLK: + reg = readl(s3c24xx_i2s.regs + S3C2410_IISMOD) & ~S3C2410_IISMOD_FS_MASK; + writel(reg | div, s3c24xx_i2s.regs + S3C2410_IISMOD); + break; + case S3C24XX_DIV_MCLK: + reg = readl(s3c24xx_i2s.regs + S3C2410_IISMOD) & ~(S3C2410_IISMOD_384FS); + writel(reg | div, s3c24xx_i2s.regs + S3C2410_IISMOD); + break; + case S3C24XX_DIV_PRESCALER: + writel(div, s3c24xx_i2s.regs + S3C2410_IISPSR); + reg = readl(s3c24xx_i2s.regs + S3C2410_IISCON); + writel(reg | S3C2410_IISCON_PSCEN, s3c24xx_i2s.regs + S3C2410_IISCON); + break; + default: + return -EINVAL; + } + + return 0; +} + +/* + * To avoid duplicating clock code, allow machine driver to + * get the clockrate from here. + */ +u32 s3c24xx_i2s_get_clockrate(void) +{ + return clk_get_rate(s3c24xx_i2s.iis_clk); +} +EXPORT_SYMBOL_GPL(s3c24xx_i2s_get_clockrate); + +static int s3c24xx_i2s_probe(struct snd_soc_dai *dai) +{ + pr_debug("Entered %s\n", __func__); + + s3c24xx_i2s.regs = ioremap(S3C2410_PA_IIS, 0x100); + if (s3c24xx_i2s.regs == NULL) + return -ENXIO; + + s3c24xx_i2s.iis_clk = clk_get(dai->dev, "iis"); + if (s3c24xx_i2s.iis_clk == NULL) { + pr_err("failed to get iis_clock\n"); + iounmap(s3c24xx_i2s.regs); + return -ENODEV; + } + clk_enable(s3c24xx_i2s.iis_clk); + + /* Configure the I2S pins in correct mode */ + s3c2410_gpio_cfgpin(S3C2410_GPE0, S3C2410_GPE0_I2SLRCK); + s3c2410_gpio_cfgpin(S3C2410_GPE1, S3C2410_GPE1_I2SSCLK); + s3c2410_gpio_cfgpin(S3C2410_GPE2, S3C2410_GPE2_CDCLK); + s3c2410_gpio_cfgpin(S3C2410_GPE3, S3C2410_GPE3_I2SSDI); + s3c2410_gpio_cfgpin(S3C2410_GPE4, S3C2410_GPE4_I2SSDO); + + writel(S3C2410_IISCON_IISEN, s3c24xx_i2s.regs + S3C2410_IISCON); + + s3c24xx_snd_txctrl(0); + s3c24xx_snd_rxctrl(0); + + return 0; +} + +#ifdef CONFIG_PM +static int s3c24xx_i2s_suspend(struct snd_soc_dai *cpu_dai) +{ + pr_debug("Entered %s\n", __func__); + + s3c24xx_i2s.iiscon = readl(s3c24xx_i2s.regs + S3C2410_IISCON); + s3c24xx_i2s.iismod = readl(s3c24xx_i2s.regs + S3C2410_IISMOD); + s3c24xx_i2s.iisfcon = readl(s3c24xx_i2s.regs + S3C2410_IISFCON); + s3c24xx_i2s.iispsr = readl(s3c24xx_i2s.regs + S3C2410_IISPSR); + + clk_disable(s3c24xx_i2s.iis_clk); + + return 0; +} + +static int s3c24xx_i2s_resume(struct snd_soc_dai *cpu_dai) +{ + pr_debug("Entered %s\n", __func__); + clk_enable(s3c24xx_i2s.iis_clk); + + writel(s3c24xx_i2s.iiscon, s3c24xx_i2s.regs + S3C2410_IISCON); + writel(s3c24xx_i2s.iismod, s3c24xx_i2s.regs + S3C2410_IISMOD); + writel(s3c24xx_i2s.iisfcon, s3c24xx_i2s.regs + S3C2410_IISFCON); + writel(s3c24xx_i2s.iispsr, s3c24xx_i2s.regs + S3C2410_IISPSR); + + return 0; +} +#else +#define s3c24xx_i2s_suspend NULL +#define s3c24xx_i2s_resume NULL +#endif + + +#define S3C24XX_I2S_RATES \ + (SNDRV_PCM_RATE_8000 | SNDRV_PCM_RATE_11025 | SNDRV_PCM_RATE_16000 | \ + SNDRV_PCM_RATE_22050 | SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 | \ + SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000) + +static struct snd_soc_dai_ops s3c24xx_i2s_dai_ops = { + .trigger = s3c24xx_i2s_trigger, + .hw_params = s3c24xx_i2s_hw_params, + .set_fmt = s3c24xx_i2s_set_fmt, + .set_clkdiv = s3c24xx_i2s_set_clkdiv, + .set_sysclk = s3c24xx_i2s_set_sysclk, +}; + +static struct snd_soc_dai_driver s3c24xx_i2s_dai = { + .probe = s3c24xx_i2s_probe, + .suspend = s3c24xx_i2s_suspend, + .resume = s3c24xx_i2s_resume, + .playback = { + .channels_min = 2, + .channels_max = 2, + .rates = S3C24XX_I2S_RATES, + .formats = SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE,}, + .capture = { + .channels_min = 2, + .channels_max = 2, + .rates = S3C24XX_I2S_RATES, + .formats = SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE,}, + .ops = &s3c24xx_i2s_dai_ops, +}; + +static __devinit int s3c24xx_iis_dev_probe(struct platform_device *pdev) +{ + return snd_soc_register_dai(&pdev->dev, &s3c24xx_i2s_dai); +} + +static __devexit int s3c24xx_iis_dev_remove(struct platform_device *pdev) +{ + snd_soc_unregister_dai(&pdev->dev); + return 0; +} + +static struct platform_driver s3c24xx_iis_driver = { + .probe = s3c24xx_iis_dev_probe, + .remove = s3c24xx_iis_dev_remove, + .driver = { + .name = "s3c24xx-iis", + .owner = THIS_MODULE, + }, +}; + +static int __init s3c24xx_i2s_init(void) +{ + return platform_driver_register(&s3c24xx_iis_driver); +} +module_init(s3c24xx_i2s_init); + +static void __exit s3c24xx_i2s_exit(void) +{ + platform_driver_unregister(&s3c24xx_iis_driver); +} +module_exit(s3c24xx_i2s_exit); + +/* Module information */ +MODULE_AUTHOR("Ben Dooks, "); +MODULE_DESCRIPTION("s3c24xx I2S SoC Interface"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:s3c24xx-iis"); diff --git a/sound/soc/samsung/s3c24xx-i2s.h b/sound/soc/samsung/s3c24xx-i2s.h new file mode 100644 index 000000000000..f9ca04edacb7 --- /dev/null +++ b/sound/soc/samsung/s3c24xx-i2s.h @@ -0,0 +1,35 @@ +/* + * s3c24xx-i2s.c -- ALSA Soc Audio Layer + * + * Copyright 2005 Wolfson Microelectronics PLC. + * Author: Graeme Gregory + * graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com + * + * 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. + * + * Revision history + * 10th Nov 2006 Initial version. + */ + +#ifndef S3C24XXI2S_H_ +#define S3C24XXI2S_H_ + +/* clock sources */ +#define S3C24XX_CLKSRC_PCLK 0 +#define S3C24XX_CLKSRC_MPLL 1 + +/* Clock dividers */ +#define S3C24XX_DIV_MCLK 0 +#define S3C24XX_DIV_BCLK 1 +#define S3C24XX_DIV_PRESCALER 2 + +/* prescaler */ +#define S3C24XX_PRESCALE(a,b) \ + (((a - 1) << S3C2410_IISPSR_INTSHIFT) | ((b - 1) << S3C2410_IISPSR_EXTSHFIT)) + +u32 s3c24xx_i2s_get_clockrate(void); + +#endif /*S3C24XXI2S_H_*/ diff --git a/sound/soc/samsung/s3c24xx_simtec.c b/sound/soc/samsung/s3c24xx_simtec.c new file mode 100644 index 000000000000..a434032d1832 --- /dev/null +++ b/sound/soc/samsung/s3c24xx_simtec.c @@ -0,0 +1,394 @@ +/* sound/soc/samsung/s3c24xx_simtec.c + * + * Copyright 2009 Simtec Electronics + * + * 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 +#include +#include + +#include +#include +#include + +#include + +#include "dma.h" +#include "s3c24xx-i2s.h" +#include "s3c24xx_simtec.h" + +static struct s3c24xx_audio_simtec_pdata *pdata; +static struct clk *xtal_clk; + +static int spk_gain; +static int spk_unmute; + +/** + * speaker_gain_get - read the speaker gain setting. + * @kcontrol: The control for the speaker gain. + * @ucontrol: The value that needs to be updated. + * + * Read the value for the AMP gain control. + */ +static int speaker_gain_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = spk_gain; + return 0; +} + +/** + * speaker_gain_set - set the value of the speaker amp gain + * @value: The value to write. + */ +static void speaker_gain_set(int value) +{ + gpio_set_value_cansleep(pdata->amp_gain[0], value & 1); + gpio_set_value_cansleep(pdata->amp_gain[1], value >> 1); +} + +/** + * speaker_gain_put - set the speaker gain setting. + * @kcontrol: The control for the speaker gain. + * @ucontrol: The value that needs to be set. + * + * Set the value of the speaker gain from the specified + * @ucontrol setting. + * + * Note, if the speaker amp is muted, then we do not set a gain value + * as at-least one of the ICs that is fitted will try and power up even + * if the main control is set to off. + */ +static int speaker_gain_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int value = ucontrol->value.integer.value[0]; + + spk_gain = value; + + if (!spk_unmute) + speaker_gain_set(value); + + return 0; +} + +static const struct snd_kcontrol_new amp_gain_controls[] = { + SOC_SINGLE_EXT("Speaker Gain", 0, 0, 3, 0, + speaker_gain_get, speaker_gain_put), +}; + +/** + * spk_unmute_state - set the unmute state of the speaker + * @to: zero to unmute, non-zero to ununmute. + */ +static void spk_unmute_state(int to) +{ + pr_debug("%s: to=%d\n", __func__, to); + + spk_unmute = to; + gpio_set_value(pdata->amp_gpio, to); + + /* if we're umuting, also re-set the gain */ + if (to && pdata->amp_gain[0] > 0) + speaker_gain_set(spk_gain); +} + +/** + * speaker_unmute_get - read the speaker unmute setting. + * @kcontrol: The control for the speaker gain. + * @ucontrol: The value that needs to be updated. + * + * Read the value for the AMP gain control. + */ +static int speaker_unmute_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.integer.value[0] = spk_unmute; + return 0; +} + +/** + * speaker_unmute_put - set the speaker unmute setting. + * @kcontrol: The control for the speaker gain. + * @ucontrol: The value that needs to be set. + * + * Set the value of the speaker gain from the specified + * @ucontrol setting. + */ +static int speaker_unmute_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + spk_unmute_state(ucontrol->value.integer.value[0]); + return 0; +} + +/* This is added as a manual control as the speaker amps create clicks + * when their power state is changed, which are far more noticeable than + * anything produced by the CODEC itself. + */ +static const struct snd_kcontrol_new amp_unmute_controls[] = { + SOC_SINGLE_EXT("Speaker Switch", 0, 0, 1, 0, + speaker_unmute_get, speaker_unmute_put), +}; + +void simtec_audio_init(struct snd_soc_pcm_runtime *rtd) +{ + struct snd_soc_codec *codec = rtd->codec; + + if (pdata->amp_gpio > 0) { + pr_debug("%s: adding amp routes\n", __func__); + + snd_soc_add_controls(codec, amp_unmute_controls, + ARRAY_SIZE(amp_unmute_controls)); + } + + if (pdata->amp_gain[0] > 0) { + pr_debug("%s: adding amp controls\n", __func__); + snd_soc_add_controls(codec, amp_gain_controls, + ARRAY_SIZE(amp_gain_controls)); + } +} +EXPORT_SYMBOL_GPL(simtec_audio_init); + +#define CODEC_CLOCK 12000000 + +/** + * simtec_hw_params - update hardware parameters + * @substream: The audio substream instance. + * @params: The parameters requested. + * + * Update the codec data routing and configuration settings + * from the supplied data. + */ +static int simtec_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *codec_dai = rtd->codec_dai; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + int ret; + + /* Set the CODEC as the bus clock master, I2S */ + ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S | + SND_SOC_DAIFMT_NB_NF | + SND_SOC_DAIFMT_CBM_CFM); + if (ret) { + pr_err("%s: failed set cpu dai format\n", __func__); + return ret; + } + + /* Set the CODEC as the bus clock master */ + ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | + SND_SOC_DAIFMT_NB_NF | + SND_SOC_DAIFMT_CBM_CFM); + if (ret) { + pr_err("%s: failed set codec dai format\n", __func__); + return ret; + } + + ret = snd_soc_dai_set_sysclk(codec_dai, 0, + CODEC_CLOCK, SND_SOC_CLOCK_IN); + if (ret) { + pr_err( "%s: failed setting codec sysclk\n", __func__); + return ret; + } + + if (pdata->use_mpllin) { + ret = snd_soc_dai_set_sysclk(cpu_dai, S3C24XX_CLKSRC_MPLL, + 0, SND_SOC_CLOCK_OUT); + + if (ret) { + pr_err("%s: failed to set MPLLin as clksrc\n", + __func__); + return ret; + } + } + + if (pdata->output_cdclk) { + int cdclk_scale; + + cdclk_scale = clk_get_rate(xtal_clk) / CODEC_CLOCK; + cdclk_scale--; + + ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C24XX_DIV_PRESCALER, + cdclk_scale); + } + + return 0; +} + +static int simtec_call_startup(struct s3c24xx_audio_simtec_pdata *pd) +{ + /* call any board supplied startup code, this currently only + * covers the bast/vr1000 which have a CPLD in the way of the + * LRCLK */ + if (pd->startup) + pd->startup(); + + return 0; +} + +static struct snd_soc_ops simtec_snd_ops = { + .hw_params = simtec_hw_params, +}; + +/** + * attach_gpio_amp - get and configure the necessary gpios + * @dev: The device we're probing. + * @pd: The platform data supplied by the board. + * + * If there is a GPIO based amplifier attached to the board, claim + * the necessary GPIO lines for it, and set default values. + */ +static int attach_gpio_amp(struct device *dev, + struct s3c24xx_audio_simtec_pdata *pd) +{ + int ret; + + /* attach gpio amp gain (if any) */ + if (pdata->amp_gain[0] > 0) { + ret = gpio_request(pd->amp_gain[0], "gpio-amp-gain0"); + if (ret) { + dev_err(dev, "cannot get amp gpio gain0\n"); + return ret; + } + + ret = gpio_request(pd->amp_gain[1], "gpio-amp-gain1"); + if (ret) { + dev_err(dev, "cannot get amp gpio gain1\n"); + gpio_free(pdata->amp_gain[0]); + return ret; + } + + gpio_direction_output(pd->amp_gain[0], 0); + gpio_direction_output(pd->amp_gain[1], 0); + } + + /* note, currently we assume GPA0 isn't valid amp */ + if (pdata->amp_gpio > 0) { + ret = gpio_request(pd->amp_gpio, "gpio-amp"); + if (ret) { + dev_err(dev, "cannot get amp gpio %d (%d)\n", + pd->amp_gpio, ret); + goto err_amp; + } + + /* set the amp off at startup */ + spk_unmute_state(0); + } + + return 0; + +err_amp: + if (pd->amp_gain[0] > 0) { + gpio_free(pd->amp_gain[0]); + gpio_free(pd->amp_gain[1]); + } + + return ret; +} + +static void detach_gpio_amp(struct s3c24xx_audio_simtec_pdata *pd) +{ + if (pd->amp_gain[0] > 0) { + gpio_free(pd->amp_gain[0]); + gpio_free(pd->amp_gain[1]); + } + + if (pd->amp_gpio > 0) + gpio_free(pd->amp_gpio); +} + +#ifdef CONFIG_PM +int simtec_audio_resume(struct device *dev) +{ + simtec_call_startup(pdata); + return 0; +} + +const struct dev_pm_ops simtec_audio_pmops = { + .resume = simtec_audio_resume, +}; +EXPORT_SYMBOL_GPL(simtec_audio_pmops); +#endif + +int __devinit simtec_audio_core_probe(struct platform_device *pdev, + struct snd_soc_card *card) +{ + struct platform_device *snd_dev; + int ret; + + card->dai_link->ops = &simtec_snd_ops; + + pdata = pdev->dev.platform_data; + if (!pdata) { + dev_err(&pdev->dev, "no platform data supplied\n"); + return -EINVAL; + } + + simtec_call_startup(pdata); + + xtal_clk = clk_get(&pdev->dev, "xtal"); + if (IS_ERR(xtal_clk)) { + dev_err(&pdev->dev, "could not get clkout0\n"); + return -EINVAL; + } + + dev_info(&pdev->dev, "xtal rate is %ld\n", clk_get_rate(xtal_clk)); + + ret = attach_gpio_amp(&pdev->dev, pdata); + if (ret) + goto err_clk; + + snd_dev = platform_device_alloc("soc-audio", -1); + if (!snd_dev) { + dev_err(&pdev->dev, "failed to alloc soc-audio devicec\n"); + ret = -ENOMEM; + goto err_gpio; + } + + platform_set_drvdata(snd_dev, card); + + ret = platform_device_add(snd_dev); + if (ret) { + dev_err(&pdev->dev, "failed to add soc-audio dev\n"); + goto err_pdev; + } + + platform_set_drvdata(pdev, snd_dev); + return 0; + +err_pdev: + platform_device_put(snd_dev); + +err_gpio: + detach_gpio_amp(pdata); + +err_clk: + clk_put(xtal_clk); + return ret; +} +EXPORT_SYMBOL_GPL(simtec_audio_core_probe); + +int __devexit simtec_audio_remove(struct platform_device *pdev) +{ + struct platform_device *snd_dev = platform_get_drvdata(pdev); + + platform_device_unregister(snd_dev); + + detach_gpio_amp(pdata); + clk_put(xtal_clk); + return 0; +} +EXPORT_SYMBOL_GPL(simtec_audio_remove); + +MODULE_AUTHOR("Ben Dooks "); +MODULE_DESCRIPTION("ALSA SoC Simtec Audio common support"); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/samsung/s3c24xx_simtec.h b/sound/soc/samsung/s3c24xx_simtec.h new file mode 100644 index 000000000000..8270748a2c41 --- /dev/null +++ b/sound/soc/samsung/s3c24xx_simtec.h @@ -0,0 +1,22 @@ +/* sound/soc/samsung/s3c24xx_simtec.h + * + * Copyright 2009 Simtec Electronics + * + * 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. +*/ + +extern void simtec_audio_init(struct snd_soc_pcm_runtime *rtd); + +extern int simtec_audio_core_probe(struct platform_device *pdev, + struct snd_soc_card *card); + +extern int simtec_audio_remove(struct platform_device *pdev); + +#ifdef CONFIG_PM +extern const struct dev_pm_ops simtec_audio_pmops; +#define simtec_audio_pm &simtec_audio_pmops +#else +#define simtec_audio_pm NULL +#endif diff --git a/sound/soc/samsung/s3c24xx_simtec_hermes.c b/sound/soc/samsung/s3c24xx_simtec_hermes.c new file mode 100644 index 000000000000..0083aff5a83d --- /dev/null +++ b/sound/soc/samsung/s3c24xx_simtec_hermes.c @@ -0,0 +1,146 @@ +/* sound/soc/samsung/s3c24xx_simtec_hermes.c + * + * Copyright 2009 Simtec Electronics + * + * 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 +#include +#include + +#include + +#include "dma.h" +#include "s3c24xx-i2s.h" +#include "s3c24xx_simtec.h" + +#include "../codecs/tlv320aic3x.h" + +static const struct snd_soc_dapm_widget dapm_widgets[] = { + SND_SOC_DAPM_LINE("GSM Out", NULL), + SND_SOC_DAPM_LINE("GSM In", NULL), + SND_SOC_DAPM_LINE("Line In", NULL), + SND_SOC_DAPM_LINE("Line Out", NULL), + SND_SOC_DAPM_LINE("ZV", NULL), + SND_SOC_DAPM_MIC("Mic Jack", NULL), + SND_SOC_DAPM_HP("Headphone Jack", NULL), +}; + +static const struct snd_soc_dapm_route base_map[] = { + /* Headphone connected to HP{L,R}OUT and HP{L,R}COM */ + + { "Headphone Jack", NULL, "HPLOUT" }, + { "Headphone Jack", NULL, "HPLCOM" }, + { "Headphone Jack", NULL, "HPROUT" }, + { "Headphone Jack", NULL, "HPRCOM" }, + + /* ZV connected to Line1 */ + + { "LINE1L", NULL, "ZV" }, + { "LINE1R", NULL, "ZV" }, + + /* Line In connected to Line2 */ + + { "LINE2L", NULL, "Line In" }, + { "LINE2R", NULL, "Line In" }, + + /* Microphone connected to MIC3R and MIC_BIAS */ + + { "MIC3L", NULL, "Mic Jack" }, + + /* GSM connected to MONO_LOUT and MIC3L (in) */ + + { "GSM Out", NULL, "MONO_LOUT" }, + { "MIC3L", NULL, "GSM In" }, + + /* Speaker is connected to LINEOUT{LN,LP,RN,RP}, however we are + * not using the DAPM to power it up and down as there it makes + * a click when powering up. */ +}; + +/** + * simtec_hermes_init - initialise and add controls + * @codec; The codec instance to attach to. + * + * Attach our controls and configure the necessary codec + * mappings for our sound card instance. +*/ +static int simtec_hermes_init(struct snd_soc_pcm_runtime *rtd) +{ + struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_dapm_context *dapm = &codec->dapm; + + snd_soc_dapm_new_controls(dapm, dapm_widgets, + ARRAY_SIZE(dapm_widgets)); + + snd_soc_dapm_add_routes(dapm, base_map, ARRAY_SIZE(base_map)); + + snd_soc_dapm_enable_pin(dapm, "Headphone Jack"); + snd_soc_dapm_enable_pin(dapm, "Line In"); + snd_soc_dapm_enable_pin(dapm, "Line Out"); + snd_soc_dapm_enable_pin(dapm, "Mic Jack"); + + simtec_audio_init(rtd); + snd_soc_dapm_sync(dapm); + + return 0; +} + +static struct snd_soc_dai_link simtec_dai_aic33 = { + .name = "tlv320aic33", + .stream_name = "TLV320AIC33", + .codec_name = "tlv320aic3x-codec.0-0x1a", + .cpu_dai_name = "s3c24xx-i2s", + .codec_dai_name = "tlv320aic3x-hifi", + .platform_name = "samsung-audio", + .init = simtec_hermes_init, +}; + +/* simtec audio machine driver */ +static struct snd_soc_card snd_soc_machine_simtec_aic33 = { + .name = "Simtec-Hermes", + .dai_link = &simtec_dai_aic33, + .num_links = 1, +}; + +static int __devinit simtec_audio_hermes_probe(struct platform_device *pd) +{ + dev_info(&pd->dev, "probing....\n"); + return simtec_audio_core_probe(pd, &snd_soc_machine_simtec_aic33); +} + +static struct platform_driver simtec_audio_hermes_platdrv = { + .driver = { + .owner = THIS_MODULE, + .name = "s3c24xx-simtec-hermes-snd", + .pm = simtec_audio_pm, + }, + .probe = simtec_audio_hermes_probe, + .remove = __devexit_p(simtec_audio_remove), +}; + +MODULE_ALIAS("platform:s3c24xx-simtec-hermes-snd"); + +static int __init simtec_hermes_modinit(void) +{ + return platform_driver_register(&simtec_audio_hermes_platdrv); +} + +static void __exit simtec_hermes_modexit(void) +{ + platform_driver_unregister(&simtec_audio_hermes_platdrv); +} + +module_init(simtec_hermes_modinit); +module_exit(simtec_hermes_modexit); + +MODULE_AUTHOR("Ben Dooks "); +MODULE_DESCRIPTION("ALSA SoC Simtec Audio support"); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/samsung/s3c24xx_simtec_tlv320aic23.c b/sound/soc/samsung/s3c24xx_simtec_tlv320aic23.c new file mode 100644 index 000000000000..fbba4e367729 --- /dev/null +++ b/sound/soc/samsung/s3c24xx_simtec_tlv320aic23.c @@ -0,0 +1,134 @@ +/* sound/soc/samsung/s3c24xx_simtec_tlv320aic23.c + * + * Copyright 2009 Simtec Electronics + * + * 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 +#include +#include + +#include + +#include "dma.h" +#include "s3c24xx-i2s.h" +#include "s3c24xx_simtec.h" + +#include "../codecs/tlv320aic23.h" + +/* supported machines: + * + * Machine Connections AMP + * ------- ----------- --- + * BAST MIC, HPOUT, LOUT, LIN TPA2001D1 (HPOUTL,R) (gain hardwired) + * VR1000 HPOUT, LIN None + * VR2000 LIN, LOUT, MIC, HP LM4871 (HPOUTL,R) + * DePicture LIN, LOUT, MIC, HP LM4871 (HPOUTL,R) + * Anubis LIN, LOUT, MIC, HP TPA2001D1 (HPOUTL,R) + */ + +static const struct snd_soc_dapm_widget dapm_widgets[] = { + SND_SOC_DAPM_HP("Headphone Jack", NULL), + SND_SOC_DAPM_LINE("Line In", NULL), + SND_SOC_DAPM_LINE("Line Out", NULL), + SND_SOC_DAPM_MIC("Mic Jack", NULL), +}; + +static const struct snd_soc_dapm_route base_map[] = { + { "Headphone Jack", NULL, "LHPOUT"}, + { "Headphone Jack", NULL, "RHPOUT"}, + + { "Line Out", NULL, "LOUT" }, + { "Line Out", NULL, "ROUT" }, + + { "LLINEIN", NULL, "Line In"}, + { "RLINEIN", NULL, "Line In"}, + + { "MICIN", NULL, "Mic Jack"}, +}; + +/** + * simtec_tlv320aic23_init - initialise and add controls + * @codec; The codec instance to attach to. + * + * Attach our controls and configure the necessary codec + * mappings for our sound card instance. +*/ +static int simtec_tlv320aic23_init(struct snd_soc_pcm_runtime *rtd) +{ + struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_dapm_context *dapm = &codec->dapm; + + snd_soc_dapm_new_controls(dapm, dapm_widgets, + ARRAY_SIZE(dapm_widgets)); + + snd_soc_dapm_add_routes(dapm, base_map, ARRAY_SIZE(base_map)); + + snd_soc_dapm_enable_pin(dapm, "Headphone Jack"); + snd_soc_dapm_enable_pin(dapm, "Line In"); + snd_soc_dapm_enable_pin(dapm, "Line Out"); + snd_soc_dapm_enable_pin(dapm, "Mic Jack"); + + simtec_audio_init(rtd); + snd_soc_dapm_sync(dapm); + + return 0; +} + +static struct snd_soc_dai_link simtec_dai_aic23 = { + .name = "tlv320aic23", + .stream_name = "TLV320AIC23", + .codec_name = "tlv320aic3x-codec.0-0x1a", + .cpu_dai_name = "s3c24xx-i2s", + .codec_dai_name = "tlv320aic3x-hifi", + .platform_name = "samsung-audio", + .init = simtec_tlv320aic23_init, +}; + +/* simtec audio machine driver */ +static struct snd_soc_card snd_soc_machine_simtec_aic23 = { + .name = "Simtec", + .dai_link = &simtec_dai_aic23, + .num_links = 1, +}; + +static int __devinit simtec_audio_tlv320aic23_probe(struct platform_device *pd) +{ + return simtec_audio_core_probe(pd, &snd_soc_machine_simtec_aic23); +} + +static struct platform_driver simtec_audio_tlv320aic23_platdrv = { + .driver = { + .owner = THIS_MODULE, + .name = "s3c24xx-simtec-tlv320aic23", + .pm = simtec_audio_pm, + }, + .probe = simtec_audio_tlv320aic23_probe, + .remove = __devexit_p(simtec_audio_remove), +}; + +MODULE_ALIAS("platform:s3c24xx-simtec-tlv320aic23"); + +static int __init simtec_tlv320aic23_modinit(void) +{ + return platform_driver_register(&simtec_audio_tlv320aic23_platdrv); +} + +static void __exit simtec_tlv320aic23_modexit(void) +{ + platform_driver_unregister(&simtec_audio_tlv320aic23_platdrv); +} + +module_init(simtec_tlv320aic23_modinit); +module_exit(simtec_tlv320aic23_modexit); + +MODULE_AUTHOR("Ben Dooks "); +MODULE_DESCRIPTION("ALSA SoC Simtec Audio support"); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/samsung/s3c24xx_uda134x.c b/sound/soc/samsung/s3c24xx_uda134x.c new file mode 100644 index 000000000000..cdc8ecbcb8ef --- /dev/null +++ b/sound/soc/samsung/s3c24xx_uda134x.c @@ -0,0 +1,367 @@ +/* + * Modifications by Christian Pellegrin + * + * s3c24xx_uda134x.c -- S3C24XX_UDA134X ALSA SoC Audio board driver + * + * Copyright 2007 Dension Audio Systems Ltd. + * Author: Zoltan Devai + * + * 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 +#include +#include +#include +#include +#include + +#include + +#include "dma.h" +#include "s3c24xx-i2s.h" +#include "../codecs/uda134x.h" + + +/* #define ENFORCE_RATES 1 */ +/* + Unfortunately the S3C24XX in master mode has a limited capacity of + generating the clock for the codec. If you define this only rates + that are really available will be enforced. But be careful, most + user level application just want the usual sampling frequencies (8, + 11.025, 22.050, 44.1 kHz) and anyway resampling is a costly + operation for embedded systems. So if you aren't very lucky or your + hardware engineer wasn't very forward-looking it's better to leave + this undefined. If you do so an approximate value for the requested + sampling rate in the range -/+ 5% will be chosen. If this in not + possible an error will be returned. +*/ + +static struct clk *xtal; +static struct clk *pclk; +/* this is need because we don't have a place where to keep the + * pointers to the clocks in each substream. We get the clocks only + * when we are actually using them so we don't block stuff like + * frequency change or oscillator power-off */ +static int clk_users; +static DEFINE_MUTEX(clk_lock); + +static unsigned int rates[33 * 2]; +#ifdef ENFORCE_RATES +static struct snd_pcm_hw_constraint_list hw_constraints_rates = { + .count = ARRAY_SIZE(rates), + .list = rates, + .mask = 0, +}; +#endif + +static struct platform_device *s3c24xx_uda134x_snd_device; + +static int s3c24xx_uda134x_startup(struct snd_pcm_substream *substream) +{ + int ret = 0; +#ifdef ENFORCE_RATES + struct snd_pcm_runtime *runtime = substream->runtime; +#endif + + mutex_lock(&clk_lock); + pr_debug("%s %d\n", __func__, clk_users); + if (clk_users == 0) { + xtal = clk_get(&s3c24xx_uda134x_snd_device->dev, "xtal"); + if (!xtal) { + printk(KERN_ERR "%s cannot get xtal\n", __func__); + ret = -EBUSY; + } else { + pclk = clk_get(&s3c24xx_uda134x_snd_device->dev, + "pclk"); + if (!pclk) { + printk(KERN_ERR "%s cannot get pclk\n", + __func__); + clk_put(xtal); + ret = -EBUSY; + } + } + if (!ret) { + int i, j; + + for (i = 0; i < 2; i++) { + int fs = i ? 256 : 384; + + rates[i*33] = clk_get_rate(xtal) / fs; + for (j = 1; j < 33; j++) + rates[i*33 + j] = clk_get_rate(pclk) / + (j * fs); + } + } + } + clk_users += 1; + mutex_unlock(&clk_lock); + if (!ret) { +#ifdef ENFORCE_RATES + ret = snd_pcm_hw_constraint_list(runtime, 0, + SNDRV_PCM_HW_PARAM_RATE, + &hw_constraints_rates); + if (ret < 0) + printk(KERN_ERR "%s cannot set constraints\n", + __func__); +#endif + } + return ret; +} + +static void s3c24xx_uda134x_shutdown(struct snd_pcm_substream *substream) +{ + mutex_lock(&clk_lock); + pr_debug("%s %d\n", __func__, clk_users); + clk_users -= 1; + if (clk_users == 0) { + clk_put(xtal); + xtal = NULL; + clk_put(pclk); + pclk = NULL; + } + mutex_unlock(&clk_lock); +} + +static int s3c24xx_uda134x_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *codec_dai = rtd->codec_dai; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + unsigned int clk = 0; + int ret = 0; + int clk_source, fs_mode; + unsigned long rate = params_rate(params); + long err, cerr; + unsigned int div; + int i, bi; + + err = 999999; + bi = 0; + for (i = 0; i < 2*33; i++) { + cerr = rates[i] - rate; + if (cerr < 0) + cerr = -cerr; + if (cerr < err) { + err = cerr; + bi = i; + } + } + if (bi / 33 == 1) + fs_mode = S3C2410_IISMOD_256FS; + else + fs_mode = S3C2410_IISMOD_384FS; + if (bi % 33 == 0) { + clk_source = S3C24XX_CLKSRC_MPLL; + div = 1; + } else { + clk_source = S3C24XX_CLKSRC_PCLK; + div = bi % 33; + } + pr_debug("%s desired rate %lu, %d\n", __func__, rate, bi); + + clk = (fs_mode == S3C2410_IISMOD_384FS ? 384 : 256) * rate; + pr_debug("%s will use: %s %s %d sysclk %d err %ld\n", __func__, + fs_mode == S3C2410_IISMOD_384FS ? "384FS" : "256FS", + clk_source == S3C24XX_CLKSRC_MPLL ? "MPLLin" : "PCLK", + div, clk, err); + + if ((err * 100 / rate) > 5) { + printk(KERN_ERR "S3C24XX_UDA134X: effective frequency " + "too different from desired (%ld%%)\n", + err * 100 / rate); + return -EINVAL; + } + + ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | + SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); + if (ret < 0) + return ret; + + ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S | + SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); + if (ret < 0) + return ret; + + ret = snd_soc_dai_set_sysclk(cpu_dai, clk_source , clk, + SND_SOC_CLOCK_IN); + if (ret < 0) + return ret; + + ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C24XX_DIV_MCLK, fs_mode); + if (ret < 0) + return ret; + + ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C24XX_DIV_BCLK, + S3C2410_IISMOD_32FS); + if (ret < 0) + return ret; + + ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C24XX_DIV_PRESCALER, + S3C24XX_PRESCALE(div, div)); + if (ret < 0) + return ret; + + /* set the codec system clock for DAC and ADC */ + ret = snd_soc_dai_set_sysclk(codec_dai, 0, clk, + SND_SOC_CLOCK_OUT); + if (ret < 0) + return ret; + + return 0; +} + +static struct snd_soc_ops s3c24xx_uda134x_ops = { + .startup = s3c24xx_uda134x_startup, + .shutdown = s3c24xx_uda134x_shutdown, + .hw_params = s3c24xx_uda134x_hw_params, +}; + +static struct snd_soc_dai_link s3c24xx_uda134x_dai_link = { + .name = "UDA134X", + .stream_name = "UDA134X", + .codec_name = "uda134x-hifi", + .codec_dai_name = "uda134x-hifi", + .cpu_dai_name = "s3c24xx-i2s", + .ops = &s3c24xx_uda134x_ops, + .platform_name = "samsung-audio", +}; + +static struct snd_soc_card snd_soc_s3c24xx_uda134x = { + .name = "S3C24XX_UDA134X", + .dai_link = &s3c24xx_uda134x_dai_link, + .num_links = 1, +}; + +static struct s3c24xx_uda134x_platform_data *s3c24xx_uda134x_l3_pins; + +static void setdat(int v) +{ + gpio_set_value(s3c24xx_uda134x_l3_pins->l3_data, v > 0); +} + +static void setclk(int v) +{ + gpio_set_value(s3c24xx_uda134x_l3_pins->l3_clk, v > 0); +} + +static void setmode(int v) +{ + gpio_set_value(s3c24xx_uda134x_l3_pins->l3_mode, v > 0); +} + +/* FIXME - This must be codec platform data but in which board file ?? */ +static struct uda134x_platform_data s3c24xx_uda134x = { + .l3 = { + .setdat = setdat, + .setclk = setclk, + .setmode = setmode, + .data_hold = 1, + .data_setup = 1, + .clock_high = 1, + .mode_hold = 1, + .mode = 1, + .mode_setup = 1, + }, +}; + +static int s3c24xx_uda134x_setup_pin(int pin, char *fun) +{ + if (gpio_request(pin, "s3c24xx_uda134x") < 0) { + printk(KERN_ERR "S3C24XX_UDA134X SoC Audio: " + "l3 %s pin already in use", fun); + return -EBUSY; + } + gpio_direction_output(pin, 0); + return 0; +} + +static int s3c24xx_uda134x_probe(struct platform_device *pdev) +{ + int ret; + + printk(KERN_INFO "S3C24XX_UDA134X SoC Audio driver\n"); + + s3c24xx_uda134x_l3_pins = pdev->dev.platform_data; + if (s3c24xx_uda134x_l3_pins == NULL) { + printk(KERN_ERR "S3C24XX_UDA134X SoC Audio: " + "unable to find platform data\n"); + return -ENODEV; + } + s3c24xx_uda134x.power = s3c24xx_uda134x_l3_pins->power; + s3c24xx_uda134x.model = s3c24xx_uda134x_l3_pins->model; + + if (s3c24xx_uda134x_setup_pin(s3c24xx_uda134x_l3_pins->l3_data, + "data") < 0) + return -EBUSY; + if (s3c24xx_uda134x_setup_pin(s3c24xx_uda134x_l3_pins->l3_clk, + "clk") < 0) { + gpio_free(s3c24xx_uda134x_l3_pins->l3_data); + return -EBUSY; + } + if (s3c24xx_uda134x_setup_pin(s3c24xx_uda134x_l3_pins->l3_mode, + "mode") < 0) { + gpio_free(s3c24xx_uda134x_l3_pins->l3_data); + gpio_free(s3c24xx_uda134x_l3_pins->l3_clk); + return -EBUSY; + } + + s3c24xx_uda134x_snd_device = platform_device_alloc("soc-audio", -1); + if (!s3c24xx_uda134x_snd_device) { + printk(KERN_ERR "S3C24XX_UDA134X SoC Audio: " + "Unable to register\n"); + return -ENOMEM; + } + + platform_set_drvdata(s3c24xx_uda134x_snd_device, + &snd_soc_s3c24xx_uda134x); + ret = platform_device_add(s3c24xx_uda134x_snd_device); + if (ret) { + printk(KERN_ERR "S3C24XX_UDA134X SoC Audio: Unable to add\n"); + platform_device_put(s3c24xx_uda134x_snd_device); + } + + return ret; +} + +static int s3c24xx_uda134x_remove(struct platform_device *pdev) +{ + platform_device_unregister(s3c24xx_uda134x_snd_device); + gpio_free(s3c24xx_uda134x_l3_pins->l3_data); + gpio_free(s3c24xx_uda134x_l3_pins->l3_clk); + gpio_free(s3c24xx_uda134x_l3_pins->l3_mode); + return 0; +} + +static struct platform_driver s3c24xx_uda134x_driver = { + .probe = s3c24xx_uda134x_probe, + .remove = s3c24xx_uda134x_remove, + .driver = { + .name = "s3c24xx_uda134x", + .owner = THIS_MODULE, + }, +}; + +static int __init s3c24xx_uda134x_init(void) +{ + return platform_driver_register(&s3c24xx_uda134x_driver); +} + +static void __exit s3c24xx_uda134x_exit(void) +{ + platform_driver_unregister(&s3c24xx_uda134x_driver); +} + + +module_init(s3c24xx_uda134x_init); +module_exit(s3c24xx_uda134x_exit); + +MODULE_AUTHOR("Zoltan Devai, Christian Pellegrin "); +MODULE_DESCRIPTION("S3C24XX_UDA134X ALSA SoC audio driver"); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/samsung/smartq_wm8987.c b/sound/soc/samsung/smartq_wm8987.c new file mode 100644 index 000000000000..d6a340b8c3f7 --- /dev/null +++ b/sound/soc/samsung/smartq_wm8987.c @@ -0,0 +1,288 @@ +/* sound/soc/samsung/smartq_wm8987.c + * + * Copyright 2010 Maurus Cuelenaere + * + * Based on smdk6410_wm8987.c + * Copyright 2007 Wolfson Microelectronics PLC. - linux@wolfsonmicro.com + * Graeme Gregory - graeme.gregory@wolfsonmicro.com + * + * 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. + * + */ + +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include "dma.h" +#include "i2s.h" + +#include "../codecs/wm8750.h" + +/* + * WM8987 is register compatible with WM8750, so using that as base driver. + */ + +static struct snd_soc_card snd_soc_smartq; + +static int smartq_hifi_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; + struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; + unsigned int clk = 0; + int ret; + + switch (params_rate(params)) { + case 8000: + case 16000: + case 32000: + case 48000: + case 96000: + clk = 12288000; + break; + case 11025: + case 22050: + case 44100: + case 88200: + clk = 11289600; + break; + } + + /* set codec DAI configuration */ + ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | + SND_SOC_DAIFMT_NB_NF | + SND_SOC_DAIFMT_CBS_CFS); + if (ret < 0) + return ret; + + /* set cpu DAI configuration */ + ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S | + SND_SOC_DAIFMT_NB_NF | + SND_SOC_DAIFMT_CBS_CFS); + if (ret < 0) + return ret; + + /* Use PCLK for I2S signal generation */ + ret = snd_soc_dai_set_sysclk(cpu_dai, SAMSUNG_I2S_RCLKSRC_0, + 0, SND_SOC_CLOCK_IN); + if (ret < 0) + return ret; + + /* Gate the RCLK output on PAD */ + ret = snd_soc_dai_set_sysclk(cpu_dai, SAMSUNG_I2S_CDCLK, + 0, SND_SOC_CLOCK_IN); + if (ret < 0) + return ret; + + /* set the codec system clock for DAC and ADC */ + ret = snd_soc_dai_set_sysclk(codec_dai, WM8750_SYSCLK, clk, + SND_SOC_CLOCK_IN); + if (ret < 0) + return ret; + + return 0; +} + +/* + * SmartQ WM8987 HiFi DAI operations. + */ +static struct snd_soc_ops smartq_hifi_ops = { + .hw_params = smartq_hifi_hw_params, +}; + +static struct snd_soc_jack smartq_jack; + +static struct snd_soc_jack_pin smartq_jack_pins[] = { + /* Disable speaker when headphone is plugged in */ + { + .pin = "Internal Speaker", + .mask = SND_JACK_HEADPHONE, + }, +}; + +static struct snd_soc_jack_gpio smartq_jack_gpios[] = { + { + .gpio = S3C64XX_GPL(12), + .name = "headphone detect", + .report = SND_JACK_HEADPHONE, + .debounce_time = 200, + }, +}; + +static const struct snd_kcontrol_new wm8987_smartq_controls[] = { + SOC_DAPM_PIN_SWITCH("Internal Speaker"), + SOC_DAPM_PIN_SWITCH("Headphone Jack"), + SOC_DAPM_PIN_SWITCH("Internal Mic"), +}; + +static int smartq_speaker_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *k, + int event) +{ + gpio_set_value(S3C64XX_GPK(12), SND_SOC_DAPM_EVENT_OFF(event)); + + return 0; +} + +static const struct snd_soc_dapm_widget wm8987_dapm_widgets[] = { + SND_SOC_DAPM_SPK("Internal Speaker", smartq_speaker_event), + SND_SOC_DAPM_HP("Headphone Jack", NULL), + SND_SOC_DAPM_MIC("Internal Mic", NULL), +}; + +static const struct snd_soc_dapm_route audio_map[] = { + {"Headphone Jack", NULL, "LOUT2"}, + {"Headphone Jack", NULL, "ROUT2"}, + + {"Internal Speaker", NULL, "LOUT2"}, + {"Internal Speaker", NULL, "ROUT2"}, + + {"Mic Bias", NULL, "Internal Mic"}, + {"LINPUT2", NULL, "Mic Bias"}, +}; + +static int smartq_wm8987_init(struct snd_soc_codec *codec) +{ + struct snd_soc_dapm_context *dapm = &codec->dapm; + int err = 0; + + /* Add SmartQ specific widgets */ + snd_soc_dapm_new_controls(dapm, wm8987_dapm_widgets, + ARRAY_SIZE(wm8987_dapm_widgets)); + + /* add SmartQ specific controls */ + err = snd_soc_add_controls(codec, wm8987_smartq_controls, + ARRAY_SIZE(wm8987_smartq_controls)); + + if (err < 0) + return err; + + /* setup SmartQ specific audio path */ + snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); + + /* set endpoints to not connected */ + snd_soc_dapm_nc_pin(dapm, "LINPUT1"); + snd_soc_dapm_nc_pin(dapm, "RINPUT1"); + snd_soc_dapm_nc_pin(dapm, "OUT3"); + snd_soc_dapm_nc_pin(dapm, "ROUT1"); + + /* set endpoints to default off mode */ + snd_soc_dapm_enable_pin(dapm, "Internal Speaker"); + snd_soc_dapm_enable_pin(dapm, "Internal Mic"); + snd_soc_dapm_disable_pin(dapm, "Headphone Jack"); + + err = snd_soc_dapm_sync(dapm); + if (err) + return err; + + /* Headphone jack detection */ + err = snd_soc_jack_new(&snd_soc_smartq, "Headphone Jack", + SND_JACK_HEADPHONE, &smartq_jack); + if (err) + return err; + + err = snd_soc_jack_add_pins(&smartq_jack, ARRAY_SIZE(smartq_jack_pins), + smartq_jack_pins); + if (err) + return err; + + err = snd_soc_jack_add_gpios(&smartq_jack, + ARRAY_SIZE(smartq_jack_gpios), + smartq_jack_gpios); + + return err; +} + +static struct snd_soc_dai_link smartq_dai[] = { + { + .name = "wm8987", + .stream_name = "SmartQ Hi-Fi", + .cpu_dai_name = "samsung-i2s.0", + .codec_dai_name = "wm8750-hifi", + .platform_name = "samsung-audio", + .codec_name = "wm8750-codec.0-0x1a", + .init = smartq_wm8987_init, + .ops = &smartq_hifi_ops, + }, +}; + +static struct snd_soc_card snd_soc_smartq = { + .name = "SmartQ", + .dai_link = smartq_dai, + .num_links = ARRAY_SIZE(smartq_dai), +}; + +static struct platform_device *smartq_snd_device; + +static int __init smartq_init(void) +{ + int ret; + + if (!machine_is_smartq7() && !machine_is_smartq5()) { + pr_info("Only SmartQ is supported by this ASoC driver\n"); + return -ENODEV; + } + + smartq_snd_device = platform_device_alloc("soc-audio", -1); + if (!smartq_snd_device) + return -ENOMEM; + + platform_set_drvdata(smartq_snd_device, &snd_soc_smartq); + + ret = platform_device_add(smartq_snd_device); + if (ret) { + platform_device_put(smartq_snd_device); + return ret; + } + + /* Initialise GPIOs used by amplifiers */ + ret = gpio_request(S3C64XX_GPK(12), "amplifiers shutdown"); + if (ret) { + dev_err(&smartq_snd_device->dev, "Failed to register GPK12\n"); + goto err_unregister_device; + } + + /* Disable amplifiers */ + ret = gpio_direction_output(S3C64XX_GPK(12), 1); + if (ret) { + dev_err(&smartq_snd_device->dev, "Failed to configure GPK12\n"); + goto err_free_gpio_amp_shut; + } + + return 0; + +err_free_gpio_amp_shut: + gpio_free(S3C64XX_GPK(12)); +err_unregister_device: + platform_device_unregister(smartq_snd_device); + + return ret; +} + +static void __exit smartq_exit(void) +{ + snd_soc_jack_free_gpios(&smartq_jack, ARRAY_SIZE(smartq_jack_gpios), + smartq_jack_gpios); + + platform_device_unregister(smartq_snd_device); +} + +module_init(smartq_init); +module_exit(smartq_exit); + +/* Module information */ +MODULE_AUTHOR("Maurus Cuelenaere "); +MODULE_DESCRIPTION("ALSA SoC SmartQ WM8987"); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/samsung/smdk2443_wm9710.c b/sound/soc/samsung/smdk2443_wm9710.c new file mode 100644 index 000000000000..3be7e7e92d6e --- /dev/null +++ b/sound/soc/samsung/smdk2443_wm9710.c @@ -0,0 +1,73 @@ +/* + * smdk2443_wm9710.c -- SoC audio for smdk2443 + * + * Copyright 2007 Wolfson Microelectronics PLC. + * Author: Graeme Gregory + * graeme.gregory@wolfsonmicro.com or linux@wolfsonmicro.com + * + * 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. + * + */ + +#include +#include +#include +#include +#include + +#include "dma.h" +#include "ac97.h" + +static struct snd_soc_card smdk2443; + +static struct snd_soc_dai_link smdk2443_dai[] = { +{ + .name = "AC97", + .stream_name = "AC97 HiFi", + .cpu_dai_name = "samsung-ac97", + .codec_dai_name = "ac97-hifi", + .codec_name = "ac97-codec", + .platform_name = "samsung-audio", +}, +}; + +static struct snd_soc_card smdk2443 = { + .name = "SMDK2443", + .dai_link = smdk2443_dai, + .num_links = ARRAY_SIZE(smdk2443_dai), +}; + +static struct platform_device *smdk2443_snd_ac97_device; + +static int __init smdk2443_init(void) +{ + int ret; + + smdk2443_snd_ac97_device = platform_device_alloc("soc-audio", -1); + if (!smdk2443_snd_ac97_device) + return -ENOMEM; + + platform_set_drvdata(smdk2443_snd_ac97_device, &smdk2443); + ret = platform_device_add(smdk2443_snd_ac97_device); + + if (ret) + platform_device_put(smdk2443_snd_ac97_device); + + return ret; +} + +static void __exit smdk2443_exit(void) +{ + platform_device_unregister(smdk2443_snd_ac97_device); +} + +module_init(smdk2443_init); +module_exit(smdk2443_exit); + +/* Module information */ +MODULE_AUTHOR("Graeme Gregory, graeme.gregory@wolfsonmicro.com, www.wolfsonmicro.com"); +MODULE_DESCRIPTION("ALSA SoC WM9710 SMDK2443"); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/samsung/smdk_spdif.c b/sound/soc/samsung/smdk_spdif.c new file mode 100644 index 000000000000..cd29da089c8f --- /dev/null +++ b/sound/soc/samsung/smdk_spdif.c @@ -0,0 +1,223 @@ +/* + * smdk_spdif.c -- S/PDIF audio for SMDK + * + * Copyright 2010 Samsung Electronics Co. Ltd. + * + * 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. + * + */ + +#include +#include +#include + +#include + +#include + +#include "dma.h" +#include "spdif.h" + +/* Audio clock settings are belonged to board specific part. Every + * board can set audio source clock setting which is matched with H/W + * like this function-'set_audio_clock_heirachy'. + */ +static int set_audio_clock_heirachy(struct platform_device *pdev) +{ + struct clk *fout_epll, *mout_epll, *sclk_audio0, *sclk_spdif; + int ret; + + fout_epll = clk_get(NULL, "fout_epll"); + if (IS_ERR(fout_epll)) { + printk(KERN_WARNING "%s: Cannot find fout_epll.\n", + __func__); + return -EINVAL; + } + + mout_epll = clk_get(NULL, "mout_epll"); + if (IS_ERR(mout_epll)) { + printk(KERN_WARNING "%s: Cannot find mout_epll.\n", + __func__); + ret = -EINVAL; + goto out1; + } + + sclk_audio0 = clk_get(&pdev->dev, "sclk_audio"); + if (IS_ERR(sclk_audio0)) { + printk(KERN_WARNING "%s: Cannot find sclk_audio.\n", + __func__); + ret = -EINVAL; + goto out2; + } + + sclk_spdif = clk_get(NULL, "sclk_spdif"); + if (IS_ERR(sclk_spdif)) { + printk(KERN_WARNING "%s: Cannot find sclk_spdif.\n", + __func__); + ret = -EINVAL; + goto out3; + } + + /* Set audio clock heirachy for S/PDIF */ + clk_set_parent(mout_epll, fout_epll); + clk_set_parent(sclk_audio0, mout_epll); + clk_set_parent(sclk_spdif, sclk_audio0); + + clk_put(sclk_spdif); +out3: + clk_put(sclk_audio0); +out2: + clk_put(mout_epll); +out1: + clk_put(fout_epll); + + return ret; +} + +/* We should haved to set clock directly on this part because of clock + * scheme of Samsudng SoCs did not support to set rates from abstrct + * clock of it's heirachy. + */ +static int set_audio_clock_rate(unsigned long epll_rate, + unsigned long audio_rate) +{ + struct clk *fout_epll, *sclk_spdif; + + fout_epll = clk_get(NULL, "fout_epll"); + if (IS_ERR(fout_epll)) { + printk(KERN_ERR "%s: failed to get fout_epll\n", __func__); + return -ENOENT; + } + + clk_set_rate(fout_epll, epll_rate); + clk_put(fout_epll); + + sclk_spdif = clk_get(NULL, "sclk_spdif"); + if (IS_ERR(sclk_spdif)) { + printk(KERN_ERR "%s: failed to get sclk_spdif\n", __func__); + return -ENOENT; + } + + clk_set_rate(sclk_spdif, audio_rate); + clk_put(sclk_spdif); + + return 0; +} + +static int smdk_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + unsigned long pll_out, rclk_rate; + int ret, ratio; + + switch (params_rate(params)) { + case 44100: + pll_out = 45158400; + break; + case 32000: + case 48000: + case 96000: + pll_out = 49152000; + break; + default: + return -EINVAL; + } + + /* Setting ratio to 512fs helps to use S/PDIF with HDMI without + * modify S/PDIF ASoC machine driver. + */ + ratio = 512; + rclk_rate = params_rate(params) * ratio; + + /* Set audio source clock rates */ + ret = set_audio_clock_rate(pll_out, rclk_rate); + if (ret < 0) + return ret; + + /* Set S/PDIF uses internal source clock */ + ret = snd_soc_dai_set_sysclk(cpu_dai, SND_SOC_SPDIF_INT_MCLK, + rclk_rate, SND_SOC_CLOCK_IN); + if (ret < 0) + return ret; + + return ret; +} + +static struct snd_soc_ops smdk_spdif_ops = { + .hw_params = smdk_hw_params, +}; + +static struct snd_soc_card smdk; + +static struct snd_soc_dai_link smdk_dai = { + .name = "S/PDIF", + .stream_name = "S/PDIF PCM Playback", + .platform_name = "samsung-audio", + .cpu_dai_name = "samsung-spdif", + .codec_dai_name = "dit-hifi", + .codec_name = "spdif-dit", + .ops = &smdk_spdif_ops, +}; + +static struct snd_soc_card smdk = { + .name = "SMDK-S/PDIF", + .dai_link = &smdk_dai, + .num_links = 1, +}; + +static struct platform_device *smdk_snd_spdif_dit_device; +static struct platform_device *smdk_snd_spdif_device; + +static int __init smdk_init(void) +{ + int ret; + + smdk_snd_spdif_dit_device = platform_device_alloc("spdif-dit", -1); + if (!smdk_snd_spdif_dit_device) + return -ENOMEM; + + ret = platform_device_add(smdk_snd_spdif_dit_device); + if (ret) + goto err2; + + smdk_snd_spdif_device = platform_device_alloc("soc-audio", -1); + if (!smdk_snd_spdif_device) { + ret = -ENOMEM; + goto err2; + } + + platform_set_drvdata(smdk_snd_spdif_device, &smdk); + + ret = platform_device_add(smdk_snd_spdif_device); + if (ret) + goto err1; + + /* Set audio clock heirachy manually */ + ret = set_audio_clock_heirachy(smdk_snd_spdif_device); + if (ret) + goto err1; + + return 0; +err1: + platform_device_put(smdk_snd_spdif_device); +err2: + platform_device_put(smdk_snd_spdif_dit_device); + return ret; +} + +static void __exit smdk_exit(void) +{ + platform_device_unregister(smdk_snd_spdif_device); +} + +module_init(smdk_init); +module_exit(smdk_exit); + +MODULE_AUTHOR("Seungwhan Youn, "); +MODULE_DESCRIPTION("ALSA SoC SMDK+S/PDIF"); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/samsung/smdk_wm8580.c b/sound/soc/samsung/smdk_wm8580.c new file mode 100644 index 000000000000..0ae3d57d79e6 --- /dev/null +++ b/sound/soc/samsung/smdk_wm8580.c @@ -0,0 +1,285 @@ +/* + * smdk_wm8580.c + * + * Copyright (c) 2009 Samsung Electronics Co. Ltd + * Author: Jaswinder Singh + * + * 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. + */ + +#include +#include +#include +#include +#include +#include + +#include + +#include "../codecs/wm8580.h" +#include "dma.h" +#include "i2s.h" + +/* + * Default CFG switch settings to use this driver: + * + * SMDK6410: Set CFG1 1-3 Off, CFG2 1-4 On + */ + +/* SMDK has a 12MHZ crystal attached to WM8580 */ +#define SMDK_WM8580_FREQ 12000000 + +static int smdk_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + struct snd_soc_dai *codec_dai = rtd->codec_dai; + unsigned int pll_out; + int bfs, rfs, ret; + + switch (params_format(params)) { + case SNDRV_PCM_FORMAT_U8: + case SNDRV_PCM_FORMAT_S8: + bfs = 16; + break; + case SNDRV_PCM_FORMAT_U16_LE: + case SNDRV_PCM_FORMAT_S16_LE: + bfs = 32; + break; + default: + return -EINVAL; + } + + /* The Fvco for WM8580 PLLs must fall within [90,100]MHz. + * This criterion can't be met if we request PLL output + * as {8000x256, 64000x256, 11025x256}Hz. + * As a wayout, we rather change rfs to a minimum value that + * results in (params_rate(params) * rfs), and itself, acceptable + * to both - the CODEC and the CPU. + */ + switch (params_rate(params)) { + case 16000: + case 22050: + case 32000: + case 44100: + case 48000: + case 88200: + case 96000: + rfs = 256; + break; + case 64000: + rfs = 384; + break; + case 8000: + case 11025: + rfs = 512; + break; + default: + return -EINVAL; + } + pll_out = params_rate(params) * rfs; + + /* Set the Codec DAI configuration */ + ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S + | SND_SOC_DAIFMT_NB_NF + | SND_SOC_DAIFMT_CBM_CFM); + if (ret < 0) + return ret; + + /* Set the AP DAI configuration */ + ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S + | SND_SOC_DAIFMT_NB_NF + | SND_SOC_DAIFMT_CBM_CFM); + if (ret < 0) + return ret; + + /* Set WM8580 to drive MCLK from its PLLA */ + ret = snd_soc_dai_set_clkdiv(codec_dai, WM8580_MCLK, + WM8580_CLKSRC_PLLA); + if (ret < 0) + return ret; + + ret = snd_soc_dai_set_pll(codec_dai, WM8580_PLLA, 0, + SMDK_WM8580_FREQ, pll_out); + if (ret < 0) + return ret; + + ret = snd_soc_dai_set_sysclk(codec_dai, WM8580_CLKSRC_PLLA, + pll_out, SND_SOC_CLOCK_IN); + if (ret < 0) + return ret; + + return 0; +} + +/* + * SMDK WM8580 DAI operations. + */ +static struct snd_soc_ops smdk_ops = { + .hw_params = smdk_hw_params, +}; + +/* SMDK Playback widgets */ +static const struct snd_soc_dapm_widget wm8580_dapm_widgets_pbk[] = { + SND_SOC_DAPM_HP("Front", NULL), + SND_SOC_DAPM_HP("Center+Sub", NULL), + SND_SOC_DAPM_HP("Rear", NULL), +}; + +/* SMDK Capture widgets */ +static const struct snd_soc_dapm_widget wm8580_dapm_widgets_cpt[] = { + SND_SOC_DAPM_MIC("MicIn", NULL), + SND_SOC_DAPM_LINE("LineIn", NULL), +}; + +/* SMDK-PAIFTX connections */ +static const struct snd_soc_dapm_route audio_map_tx[] = { + /* MicIn feeds AINL */ + {"AINL", NULL, "MicIn"}, + + /* LineIn feeds AINL/R */ + {"AINL", NULL, "LineIn"}, + {"AINR", NULL, "LineIn"}, +}; + +/* SMDK-PAIFRX connections */ +static const struct snd_soc_dapm_route audio_map_rx[] = { + /* Front Left/Right are fed VOUT1L/R */ + {"Front", NULL, "VOUT1L"}, + {"Front", NULL, "VOUT1R"}, + + /* Center/Sub are fed VOUT2L/R */ + {"Center+Sub", NULL, "VOUT2L"}, + {"Center+Sub", NULL, "VOUT2R"}, + + /* Rear Left/Right are fed VOUT3L/R */ + {"Rear", NULL, "VOUT3L"}, + {"Rear", NULL, "VOUT3R"}, +}; + +static int smdk_wm8580_init_paiftx(struct snd_soc_pcm_runtime *rtd) +{ + struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_dapm_context *dapm = &codec->dapm; + + /* Add smdk specific Capture widgets */ + snd_soc_dapm_new_controls(dapm, wm8580_dapm_widgets_cpt, + ARRAY_SIZE(wm8580_dapm_widgets_cpt)); + + /* Set up PAIFTX audio path */ + snd_soc_dapm_add_routes(dapm, audio_map_tx, ARRAY_SIZE(audio_map_tx)); + + /* Enabling the microphone requires the fitting of a 0R + * resistor to connect the line from the microphone jack. + */ + snd_soc_dapm_disable_pin(dapm, "MicIn"); + + /* signal a DAPM event */ + snd_soc_dapm_sync(dapm); + + return 0; +} + +static int smdk_wm8580_init_paifrx(struct snd_soc_pcm_runtime *rtd) +{ + struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_dapm_context *dapm = &codec->dapm; + + /* Add smdk specific Playback widgets */ + snd_soc_dapm_new_controls(dapm, wm8580_dapm_widgets_pbk, + ARRAY_SIZE(wm8580_dapm_widgets_pbk)); + + /* Set up PAIFRX audio path */ + snd_soc_dapm_add_routes(dapm, audio_map_rx, ARRAY_SIZE(audio_map_rx)); + + /* signal a DAPM event */ + snd_soc_dapm_sync(dapm); + + return 0; +} + +enum { + PRI_PLAYBACK = 0, + PRI_CAPTURE, + SEC_PLAYBACK, +}; + +static struct snd_soc_dai_link smdk_dai[] = { + [PRI_PLAYBACK] = { /* Primary Playback i/f */ + .name = "WM8580 PAIF RX", + .stream_name = "Playback", + .cpu_dai_name = "samsung-i2s.2", + .codec_dai_name = "wm8580-hifi-playback", + .platform_name = "samsung-audio", + .codec_name = "wm8580-codec.0-001b", + .init = smdk_wm8580_init_paifrx, + .ops = &smdk_ops, + }, + [PRI_CAPTURE] = { /* Primary Capture i/f */ + .name = "WM8580 PAIF TX", + .stream_name = "Capture", + .cpu_dai_name = "samsung-i2s.2", + .codec_dai_name = "wm8580-hifi-capture", + .platform_name = "samsung-audio", + .codec_name = "wm8580-codec.0-001b", + .init = smdk_wm8580_init_paiftx, + .ops = &smdk_ops, + }, + [SEC_PLAYBACK] = { /* Sec_Fifo Playback i/f */ + .name = "Sec_FIFO TX", + .stream_name = "Playback", + .cpu_dai_name = "samsung-i2s.x", + .codec_dai_name = "wm8580-hifi-playback", + .platform_name = "samsung-audio", + .codec_name = "wm8580-codec.0-001b", + .init = smdk_wm8580_init_paifrx, + .ops = &smdk_ops, + }, +}; + +static struct snd_soc_card smdk = { + .name = "SMDK-I2S", + .dai_link = smdk_dai, + .num_links = 2, +}; + +static struct platform_device *smdk_snd_device; + +static int __init smdk_audio_init(void) +{ + int ret; + char *str; + + if (machine_is_smdkc100()) { + smdk.num_links = 3; + /* S5PC100 has I2S0 as v5 */ + str = (char *)smdk_dai[PRI_PLAYBACK].cpu_dai_name; + str[strlen(str) - 1] = '0'; + str = (char *)smdk_dai[PRI_CAPTURE].cpu_dai_name; + str[strlen(str) - 1] = '0'; + /* Secondary is at offset SAMSUNG_I2S_SECOFF from Primary */ + str = (char *)smdk_dai[SEC_PLAYBACK].cpu_dai_name; + str[strlen(str) - 1] = '0' + SAMSUNG_I2S_SECOFF; + } + + smdk_snd_device = platform_device_alloc("soc-audio", -1); + if (!smdk_snd_device) + return -ENOMEM; + + platform_set_drvdata(smdk_snd_device, &smdk); + ret = platform_device_add(smdk_snd_device); + + if (ret) + platform_device_put(smdk_snd_device); + + return ret; +} +module_init(smdk_audio_init); + +MODULE_AUTHOR("Jaswinder Singh, jassi.brar@samsung.com"); +MODULE_DESCRIPTION("ALSA SoC SMDK WM8580"); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/samsung/smdk_wm9713.c b/sound/soc/samsung/smdk_wm9713.c new file mode 100644 index 000000000000..7ce243086e7d --- /dev/null +++ b/sound/soc/samsung/smdk_wm9713.c @@ -0,0 +1,107 @@ +/* + * smdk_wm9713.c -- SoC audio for SMDK + * + * Copyright 2010 Samsung Electronics Co. Ltd. + * Author: Jaswinder Singh Brar + * + * 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. + * + */ + +#include +#include +#include + +#include "dma.h" +#include "ac97.h" + +static struct snd_soc_card smdk; + +/* + * Default CFG switch settings to use this driver: + * + * SMDK6410: Set CFG1 1-3 On, CFG2 1-4 Off + * SMDKC100: Set CFG6 1-3 On, CFG7 1 On + * SMDKC110: Set CFGB10 1-2 Off, CFGB12 1-3 On + * SMDKV210: Set CFGB10 1-2 Off, CFGB12 1-3 On + */ + +/* + Playback (HeadPhone):- + $ amixer sset 'Headphone' unmute + $ amixer sset 'Right Headphone Out Mux' 'Headphone' + $ amixer sset 'Left Headphone Out Mux' 'Headphone' + $ amixer sset 'Right HP Mixer PCM' unmute + $ amixer sset 'Left HP Mixer PCM' unmute + + Capture (LineIn):- + $ amixer sset 'Right Capture Source' 'Line' + $ amixer sset 'Left Capture Source' 'Line' +*/ + +static struct snd_soc_dai_link smdk_dai = { + .name = "AC97", + .stream_name = "AC97 PCM", + .platform_name = "samsung-audio", + .cpu_dai_name = "samsung-ac97", + .codec_dai_name = "wm9713-hifi", + .codec_name = "wm9713-codec", +}; + +static struct snd_soc_card smdk = { + .name = "SMDK WM9713", + .dai_link = &smdk_dai, + .num_links = 1, +}; + +static struct platform_device *smdk_snd_wm9713_device; +static struct platform_device *smdk_snd_ac97_device; + +static int __init smdk_init(void) +{ + int ret; + + smdk_snd_wm9713_device = platform_device_alloc("wm9713-codec", -1); + if (!smdk_snd_wm9713_device) + return -ENOMEM; + + ret = platform_device_add(smdk_snd_wm9713_device); + if (ret) + goto err; + + smdk_snd_ac97_device = platform_device_alloc("soc-audio", -1); + if (!smdk_snd_ac97_device) { + ret = -ENOMEM; + goto err; + } + + platform_set_drvdata(smdk_snd_ac97_device, &smdk); + + ret = platform_device_add(smdk_snd_ac97_device); + if (ret) { + platform_device_put(smdk_snd_ac97_device); + goto err; + } + + return 0; +err: + platform_device_put(smdk_snd_wm9713_device); + return ret; +} + +static void __exit smdk_exit(void) +{ + platform_device_unregister(smdk_snd_ac97_device); + platform_device_unregister(smdk_snd_wm9713_device); +} + +module_init(smdk_init); +module_exit(smdk_exit); + +/* Module information */ +MODULE_AUTHOR("Jaswinder Singh Brar, jassi.brar@samsung.com"); +MODULE_DESCRIPTION("ALSA SoC SMDK+WM9713"); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/samsung/spdif.c b/sound/soc/samsung/spdif.c new file mode 100644 index 000000000000..f0816404ea3e --- /dev/null +++ b/sound/soc/samsung/spdif.c @@ -0,0 +1,501 @@ +/* sound/soc/samsung/spdif.c + * + * ALSA SoC Audio Layer - Samsung S/PDIF Controller driver + * + * Copyright (c) 2010 Samsung Electronics Co. Ltd + * http://www.samsung.com/ + * + * 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 +#include + +#include +#include + +#include "dma.h" +#include "spdif.h" + +/* Registers */ +#define CLKCON 0x00 +#define CON 0x04 +#define BSTAS 0x08 +#define CSTAS 0x0C +#define DATA_OUTBUF 0x10 +#define DCNT 0x14 +#define BSTAS_S 0x18 +#define DCNT_S 0x1C + +#define CLKCTL_MASK 0x7 +#define CLKCTL_MCLK_EXT (0x1 << 2) +#define CLKCTL_PWR_ON (0x1 << 0) + +#define CON_MASK 0x3ffffff +#define CON_FIFO_TH_SHIFT 19 +#define CON_FIFO_TH_MASK (0x7 << 19) +#define CON_USERDATA_23RDBIT (0x1 << 12) + +#define CON_SW_RESET (0x1 << 5) + +#define CON_MCLKDIV_MASK (0x3 << 3) +#define CON_MCLKDIV_256FS (0x0 << 3) +#define CON_MCLKDIV_384FS (0x1 << 3) +#define CON_MCLKDIV_512FS (0x2 << 3) + +#define CON_PCM_MASK (0x3 << 1) +#define CON_PCM_16BIT (0x0 << 1) +#define CON_PCM_20BIT (0x1 << 1) +#define CON_PCM_24BIT (0x2 << 1) + +#define CON_PCM_DATA (0x1 << 0) + +#define CSTAS_MASK 0x3fffffff +#define CSTAS_SAMP_FREQ_MASK (0xF << 24) +#define CSTAS_SAMP_FREQ_44 (0x0 << 24) +#define CSTAS_SAMP_FREQ_48 (0x2 << 24) +#define CSTAS_SAMP_FREQ_32 (0x3 << 24) +#define CSTAS_SAMP_FREQ_96 (0xA << 24) + +#define CSTAS_CATEGORY_MASK (0xFF << 8) +#define CSTAS_CATEGORY_CODE_CDP (0x01 << 8) + +#define CSTAS_NO_COPYRIGHT (0x1 << 2) + +/** + * struct samsung_spdif_info - Samsung S/PDIF Controller information + * @lock: Spin lock for S/PDIF. + * @dev: The parent device passed to use from the probe. + * @regs: The pointer to the device register block. + * @clk_rate: Current clock rate for calcurate ratio. + * @pclk: The peri-clock pointer for spdif master operation. + * @sclk: The source clock pointer for making sync signals. + * @save_clkcon: Backup clkcon reg. in suspend. + * @save_con: Backup con reg. in suspend. + * @save_cstas: Backup cstas reg. in suspend. + * @dma_playback: DMA information for playback channel. + */ +struct samsung_spdif_info { + spinlock_t lock; + struct device *dev; + void __iomem *regs; + unsigned long clk_rate; + struct clk *pclk; + struct clk *sclk; + u32 saved_clkcon; + u32 saved_con; + u32 saved_cstas; + struct s3c_dma_params *dma_playback; +}; + +static struct s3c2410_dma_client spdif_dma_client_out = { + .name = "S/PDIF Stereo out", +}; + +static struct s3c_dma_params spdif_stereo_out; +static struct samsung_spdif_info spdif_info; + +static inline struct samsung_spdif_info *to_info(struct snd_soc_dai *cpu_dai) +{ + return snd_soc_dai_get_drvdata(cpu_dai); +} + +static void spdif_snd_txctrl(struct samsung_spdif_info *spdif, int on) +{ + void __iomem *regs = spdif->regs; + u32 clkcon; + + dev_dbg(spdif->dev, "Entered %s\n", __func__); + + clkcon = readl(regs + CLKCON) & CLKCTL_MASK; + if (on) + writel(clkcon | CLKCTL_PWR_ON, regs + CLKCON); + else + writel(clkcon & ~CLKCTL_PWR_ON, regs + CLKCON); +} + +static int spdif_set_sysclk(struct snd_soc_dai *cpu_dai, + int clk_id, unsigned int freq, int dir) +{ + struct samsung_spdif_info *spdif = to_info(cpu_dai); + u32 clkcon; + + dev_dbg(spdif->dev, "Entered %s\n", __func__); + + clkcon = readl(spdif->regs + CLKCON); + + if (clk_id == SND_SOC_SPDIF_INT_MCLK) + clkcon &= ~CLKCTL_MCLK_EXT; + else + clkcon |= CLKCTL_MCLK_EXT; + + writel(clkcon, spdif->regs + CLKCON); + + spdif->clk_rate = freq; + + return 0; +} + +static int spdif_trigger(struct snd_pcm_substream *substream, int cmd, + struct snd_soc_dai *dai) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct samsung_spdif_info *spdif = to_info(rtd->cpu_dai); + unsigned long flags; + + dev_dbg(spdif->dev, "Entered %s\n", __func__); + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + case SNDRV_PCM_TRIGGER_RESUME: + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: + spin_lock_irqsave(&spdif->lock, flags); + spdif_snd_txctrl(spdif, 1); + spin_unlock_irqrestore(&spdif->lock, flags); + break; + case SNDRV_PCM_TRIGGER_STOP: + case SNDRV_PCM_TRIGGER_SUSPEND: + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + spin_lock_irqsave(&spdif->lock, flags); + spdif_snd_txctrl(spdif, 0); + spin_unlock_irqrestore(&spdif->lock, flags); + break; + default: + return -EINVAL; + } + + return 0; +} + +static int spdif_sysclk_ratios[] = { + 512, 384, 256, +}; + +static int spdif_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *socdai) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct samsung_spdif_info *spdif = to_info(rtd->cpu_dai); + void __iomem *regs = spdif->regs; + struct s3c_dma_params *dma_data; + u32 con, clkcon, cstas; + unsigned long flags; + int i, ratio; + + dev_dbg(spdif->dev, "Entered %s\n", __func__); + + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) + dma_data = spdif->dma_playback; + else { + dev_err(spdif->dev, "Capture is not supported\n"); + return -EINVAL; + } + + snd_soc_dai_set_dma_data(rtd->cpu_dai, substream, dma_data); + + spin_lock_irqsave(&spdif->lock, flags); + + con = readl(regs + CON) & CON_MASK; + cstas = readl(regs + CSTAS) & CSTAS_MASK; + clkcon = readl(regs + CLKCON) & CLKCTL_MASK; + + con &= ~CON_FIFO_TH_MASK; + con |= (0x7 << CON_FIFO_TH_SHIFT); + con |= CON_USERDATA_23RDBIT; + con |= CON_PCM_DATA; + + con &= ~CON_PCM_MASK; + switch (params_format(params)) { + case SNDRV_PCM_FORMAT_S16_LE: + con |= CON_PCM_16BIT; + break; + default: + dev_err(spdif->dev, "Unsupported data size.\n"); + goto err; + } + + ratio = spdif->clk_rate / params_rate(params); + for (i = 0; i < ARRAY_SIZE(spdif_sysclk_ratios); i++) + if (ratio == spdif_sysclk_ratios[i]) + break; + if (i == ARRAY_SIZE(spdif_sysclk_ratios)) { + dev_err(spdif->dev, "Invalid clock ratio %ld/%d\n", + spdif->clk_rate, params_rate(params)); + goto err; + } + + con &= ~CON_MCLKDIV_MASK; + switch (ratio) { + case 256: + con |= CON_MCLKDIV_256FS; + break; + case 384: + con |= CON_MCLKDIV_384FS; + break; + case 512: + con |= CON_MCLKDIV_512FS; + break; + } + + cstas &= ~CSTAS_SAMP_FREQ_MASK; + switch (params_rate(params)) { + case 44100: + cstas |= CSTAS_SAMP_FREQ_44; + break; + case 48000: + cstas |= CSTAS_SAMP_FREQ_48; + break; + case 32000: + cstas |= CSTAS_SAMP_FREQ_32; + break; + case 96000: + cstas |= CSTAS_SAMP_FREQ_96; + break; + default: + dev_err(spdif->dev, "Invalid sampling rate %d\n", + params_rate(params)); + goto err; + } + + cstas &= ~CSTAS_CATEGORY_MASK; + cstas |= CSTAS_CATEGORY_CODE_CDP; + cstas |= CSTAS_NO_COPYRIGHT; + + writel(con, regs + CON); + writel(cstas, regs + CSTAS); + writel(clkcon, regs + CLKCON); + + spin_unlock_irqrestore(&spdif->lock, flags); + + return 0; +err: + spin_unlock_irqrestore(&spdif->lock, flags); + return -EINVAL; +} + +static void spdif_shutdown(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct samsung_spdif_info *spdif = to_info(rtd->cpu_dai); + void __iomem *regs = spdif->regs; + u32 con, clkcon; + + dev_dbg(spdif->dev, "Entered %s\n", __func__); + + con = readl(regs + CON) & CON_MASK; + clkcon = readl(regs + CLKCON) & CLKCTL_MASK; + + writel(con | CON_SW_RESET, regs + CON); + cpu_relax(); + + writel(clkcon & ~CLKCTL_PWR_ON, regs + CLKCON); +} + +#ifdef CONFIG_PM +static int spdif_suspend(struct snd_soc_dai *cpu_dai) +{ + struct samsung_spdif_info *spdif = to_info(cpu_dai); + u32 con = spdif->saved_con; + + dev_dbg(spdif->dev, "Entered %s\n", __func__); + + spdif->saved_clkcon = readl(spdif->regs + CLKCON) & CLKCTL_MASK; + spdif->saved_con = readl(spdif->regs + CON) & CON_MASK; + spdif->saved_cstas = readl(spdif->regs + CSTAS) & CSTAS_MASK; + + writel(con | CON_SW_RESET, spdif->regs + CON); + cpu_relax(); + + return 0; +} + +static int spdif_resume(struct snd_soc_dai *cpu_dai) +{ + struct samsung_spdif_info *spdif = to_info(cpu_dai); + + dev_dbg(spdif->dev, "Entered %s\n", __func__); + + writel(spdif->saved_clkcon, spdif->regs + CLKCON); + writel(spdif->saved_con, spdif->regs + CON); + writel(spdif->saved_cstas, spdif->regs + CSTAS); + + return 0; +} +#else +#define spdif_suspend NULL +#define spdif_resume NULL +#endif + +static struct snd_soc_dai_ops spdif_dai_ops = { + .set_sysclk = spdif_set_sysclk, + .trigger = spdif_trigger, + .hw_params = spdif_hw_params, + .shutdown = spdif_shutdown, +}; + +struct snd_soc_dai_driver samsung_spdif_dai = { + .name = "samsung-spdif", + .playback = { + .stream_name = "S/PDIF Playback", + .channels_min = 2, + .channels_max = 2, + .rates = (SNDRV_PCM_RATE_32000 | + SNDRV_PCM_RATE_44100 | + SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_96000), + .formats = SNDRV_PCM_FMTBIT_S16_LE, }, + .ops = &spdif_dai_ops, + .suspend = spdif_suspend, + .resume = spdif_resume, +}; + +static __devinit int spdif_probe(struct platform_device *pdev) +{ + struct s3c_audio_pdata *spdif_pdata; + struct resource *mem_res, *dma_res; + struct samsung_spdif_info *spdif; + int ret; + + spdif_pdata = pdev->dev.platform_data; + + dev_dbg(&pdev->dev, "Entered %s\n", __func__); + + dma_res = platform_get_resource(pdev, IORESOURCE_DMA, 0); + if (!dma_res) { + dev_err(&pdev->dev, "Unable to get dma resource.\n"); + return -ENXIO; + } + + mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!mem_res) { + dev_err(&pdev->dev, "Unable to get register resource.\n"); + return -ENXIO; + } + + if (spdif_pdata && spdif_pdata->cfg_gpio + && spdif_pdata->cfg_gpio(pdev)) { + dev_err(&pdev->dev, "Unable to configure GPIO pins\n"); + return -EINVAL; + } + + spdif = &spdif_info; + spdif->dev = &pdev->dev; + + spin_lock_init(&spdif->lock); + + spdif->pclk = clk_get(&pdev->dev, "spdif"); + if (IS_ERR(spdif->pclk)) { + dev_err(&pdev->dev, "failed to get peri-clock\n"); + ret = -ENOENT; + goto err0; + } + clk_enable(spdif->pclk); + + spdif->sclk = clk_get(&pdev->dev, "sclk_spdif"); + if (IS_ERR(spdif->sclk)) { + dev_err(&pdev->dev, "failed to get internal source clock\n"); + ret = -ENOENT; + goto err1; + } + clk_enable(spdif->sclk); + + /* Request S/PDIF Register's memory region */ + if (!request_mem_region(mem_res->start, + resource_size(mem_res), "samsung-spdif")) { + dev_err(&pdev->dev, "Unable to request register region\n"); + ret = -EBUSY; + goto err2; + } + + spdif->regs = ioremap(mem_res->start, 0x100); + if (spdif->regs == NULL) { + dev_err(&pdev->dev, "Cannot ioremap registers\n"); + ret = -ENXIO; + goto err3; + } + + dev_set_drvdata(&pdev->dev, spdif); + + ret = snd_soc_register_dai(&pdev->dev, &samsung_spdif_dai); + if (ret != 0) { + dev_err(&pdev->dev, "fail to register dai\n"); + goto err4; + } + + spdif_stereo_out.dma_size = 2; + spdif_stereo_out.client = &spdif_dma_client_out; + spdif_stereo_out.dma_addr = mem_res->start + DATA_OUTBUF; + spdif_stereo_out.channel = dma_res->start; + + spdif->dma_playback = &spdif_stereo_out; + + return 0; + +err4: + iounmap(spdif->regs); +err3: + release_mem_region(mem_res->start, resource_size(mem_res)); +err2: + clk_disable(spdif->sclk); + clk_put(spdif->sclk); +err1: + clk_disable(spdif->pclk); + clk_put(spdif->pclk); +err0: + return ret; +} + +static __devexit int spdif_remove(struct platform_device *pdev) +{ + struct samsung_spdif_info *spdif = &spdif_info; + struct resource *mem_res; + + snd_soc_unregister_dai(&pdev->dev); + + iounmap(spdif->regs); + + mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (mem_res) + release_mem_region(mem_res->start, resource_size(mem_res)); + + clk_disable(spdif->sclk); + clk_put(spdif->sclk); + clk_disable(spdif->pclk); + clk_put(spdif->pclk); + + return 0; +} + +static struct platform_driver samsung_spdif_driver = { + .probe = spdif_probe, + .remove = spdif_remove, + .driver = { + .name = "samsung-spdif", + .owner = THIS_MODULE, + }, +}; + +static int __init spdif_init(void) +{ + return platform_driver_register(&samsung_spdif_driver); +} +module_init(spdif_init); + +static void __exit spdif_exit(void) +{ + platform_driver_unregister(&samsung_spdif_driver); +} +module_exit(spdif_exit); + +MODULE_AUTHOR("Seungwhan Youn, "); +MODULE_DESCRIPTION("Samsung S/PDIF Controller Driver"); +MODULE_LICENSE("GPL"); +MODULE_ALIAS("platform:samsung-spdif"); diff --git a/sound/soc/samsung/spdif.h b/sound/soc/samsung/spdif.h new file mode 100644 index 000000000000..4f72cb446dbf --- /dev/null +++ b/sound/soc/samsung/spdif.h @@ -0,0 +1,19 @@ +/* sound/soc/samsung/spdif.h + * + * ALSA SoC Audio Layer - Samsung S/PDIF Controller driver + * + * Copyright (c) 2010 Samsung Electronics Co. Ltd + * http://www.samsung.com/ + * + * 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. + */ + +#ifndef __SND_SOC_SAMSUNG_SPDIF_H +#define __SND_SOC_SAMSUNG_SPDIF_H __FILE__ + +#define SND_SOC_SPDIF_INT_MCLK 0 +#define SND_SOC_SPDIF_EXT_MCLK 1 + +#endif /* __SND_SOC_SAMSUNG_SPDIF_H */ -- cgit v1.2.3 From fe669bf88e9108b96a847385df08c9b1e98c1420 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 23 Nov 2010 12:09:30 +0000 Subject: drm/i915: Compute physical addresses from base of stolen memory The GATT is a write-only set of registers, reading from them in the manner of i915_gtt_to_phys() is supposed to be undefined. However a simple solution exists as we allocate linear memory from the stolen area, we can simply add the block offset to the base register. As a side-effect we recover all the unused stolen GTT entries and so enlarge our aperture. Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_dma.c | 197 ++++++++++++++++------------------------ drivers/gpu/drm/i915/i915_drv.h | 2 +- 2 files changed, 77 insertions(+), 122 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index cf4e06a9417a..3df271215ab9 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -1007,73 +1007,47 @@ intel_teardown_mchbar(struct drm_device *dev) #define PTE_VALID (1 << 0) /** - * i915_gtt_to_phys - take a GTT address and turn it into a physical one + * i915_stolen_to_phys - take an offset into stolen memory and turn it into + * a physical one * @dev: drm device - * @gtt_addr: address to translate + * @offset: address to translate * - * Some chip functions require allocations from stolen space but need the - * physical address of the memory in question. We use this routine - * to get a physical address suitable for register programming from a given - * GTT address. + * Some chip functions require allocations from stolen space and need the + * physical address of the memory in question. */ -static unsigned long i915_gtt_to_phys(struct drm_device *dev, - unsigned long gtt_addr) +static unsigned long i915_stolen_to_phys(struct drm_device *dev, u32 offset) { - unsigned long *gtt; - unsigned long entry, phys; - int gtt_bar = IS_GEN2(dev) ? 1 : 0; - int gtt_offset, gtt_size; - - if (INTEL_INFO(dev)->gen >= 4) { - if (IS_G4X(dev) || INTEL_INFO(dev)->gen > 4) { - gtt_offset = 2*1024*1024; - gtt_size = 2*1024*1024; - } else { - gtt_offset = 512*1024; - gtt_size = 512*1024; - } + struct drm_i915_private *dev_priv = dev->dev_private; + struct pci_dev *pdev = dev_priv->bridge_dev; + u32 base; + +#if 0 + /* On the machines I have tested the Graphics Base of Stolen Memory + * is unreliable, so compute the base by subtracting the stolen memory + * from the Top of Low Usable DRAM which is where the BIOS places + * the graphics stolen memory. + */ + if (INTEL_INFO(dev)->gen > 3 || IS_G33(dev)) { + /* top 32bits are reserved = 0 */ + pci_read_config_dword(pdev, 0xA4, &base); } else { - gtt_bar = 3; - gtt_offset = 0; - gtt_size = pci_resource_len(dev->pdev, gtt_bar); - } - - gtt = ioremap_wc(pci_resource_start(dev->pdev, gtt_bar) + gtt_offset, - gtt_size); - if (!gtt) { - DRM_ERROR("ioremap of GTT failed\n"); - return 0; - } - - entry = *(volatile u32 *)(gtt + (gtt_addr / 1024)); - - DRM_DEBUG_DRIVER("GTT addr: 0x%08lx, PTE: 0x%08lx\n", gtt_addr, entry); - - /* Mask out these reserved bits on this hardware. */ - if (INTEL_INFO(dev)->gen < 4 && !IS_G33(dev)) - entry &= ~PTE_ADDRESS_MASK_HIGH; - - /* If it's not a mapping type we know, then bail. */ - if ((entry & PTE_MAPPING_TYPE_MASK) != PTE_MAPPING_TYPE_UNCACHED && - (entry & PTE_MAPPING_TYPE_MASK) != PTE_MAPPING_TYPE_CACHED) { - iounmap(gtt); - return 0; - } - - if (!(entry & PTE_VALID)) { - DRM_ERROR("bad GTT entry in stolen space\n"); - iounmap(gtt); - return 0; + /* XXX presume 8xx is the same as i915 */ + pci_bus_read_config_dword(pdev->bus, 2, 0x5C, &base); + } +#else + if (INTEL_INFO(dev)->gen > 3 || IS_G33(dev)) { + u16 val; + pci_read_config_word(pdev, 0xb0, &val); + base = val >> 4 << 20; + } else { + u8 val; + pci_read_config_byte(pdev, 0x9c, &val); + base = val >> 3 << 27; } + base -= dev_priv->mm.gtt->gtt_stolen_entries << PAGE_SHIFT; +#endif - iounmap(gtt); - - phys =(entry & PTE_ADDRESS_MASK) | - ((uint64_t)(entry & PTE_ADDRESS_MASK_HIGH) << (32 - 4)); - - DRM_DEBUG_DRIVER("GTT addr: 0x%08lx, phys addr: 0x%08lx\n", gtt_addr, phys); - - return phys; + return base + offset; } static void i915_warn_stolen(struct drm_device *dev) @@ -1089,47 +1063,28 @@ static void i915_setup_compression(struct drm_device *dev, int size) unsigned long cfb_base; unsigned long ll_base = 0; - /* Leave 1M for line length buffer & misc. */ - compressed_fb = drm_mm_search_free(&dev_priv->mm.vram, size, 4096, 0); - if (!compressed_fb) { - dev_priv->no_fbc_reason = FBC_STOLEN_TOO_SMALL; - i915_warn_stolen(dev); - return; - } - - compressed_fb = drm_mm_get_block(compressed_fb, size, 4096); - if (!compressed_fb) { - i915_warn_stolen(dev); - dev_priv->no_fbc_reason = FBC_STOLEN_TOO_SMALL; - return; - } + compressed_fb = drm_mm_search_free(&dev_priv->mm.stolen, size, 4096, 0); + if (compressed_fb) + compressed_fb = drm_mm_get_block(compressed_fb, size, 4096); + if (!compressed_fb) + goto err; - cfb_base = i915_gtt_to_phys(dev, compressed_fb->start); - if (!cfb_base) { - DRM_ERROR("failed to get stolen phys addr, disabling FBC\n"); - drm_mm_put_block(compressed_fb); - } + cfb_base = i915_stolen_to_phys(dev, compressed_fb->start); + if (!cfb_base) + goto err_fb; if (!(IS_GM45(dev) || IS_IRONLAKE_M(dev))) { - compressed_llb = drm_mm_search_free(&dev_priv->mm.vram, 4096, - 4096, 0); - if (!compressed_llb) { - i915_warn_stolen(dev); - return; - } - - compressed_llb = drm_mm_get_block(compressed_llb, 4096, 4096); - if (!compressed_llb) { - i915_warn_stolen(dev); - return; - } + compressed_llb = drm_mm_search_free(&dev_priv->mm.stolen, + 4096, 4096, 0); + if (compressed_llb) + compressed_llb = drm_mm_get_block(compressed_llb, + 4096, 4096); + if (!compressed_llb) + goto err_fb; - ll_base = i915_gtt_to_phys(dev, compressed_llb->start); - if (!ll_base) { - DRM_ERROR("failed to get stolen phys addr, disabling FBC\n"); - drm_mm_put_block(compressed_fb); - drm_mm_put_block(compressed_llb); - } + ll_base = i915_stolen_to_phys(dev, compressed_llb->start); + if (!ll_base) + goto err_llb; } dev_priv->cfb_size = size; @@ -1146,8 +1101,17 @@ static void i915_setup_compression(struct drm_device *dev, int size) dev_priv->compressed_llb = compressed_llb; } - DRM_DEBUG_KMS("FBC base 0x%08lx, ll base 0x%08lx, size %dM\n", cfb_base, - ll_base, size >> 20); + DRM_DEBUG_KMS("FBC base 0x%08lx, ll base 0x%08lx, size %dM\n", + cfb_base, ll_base, size >> 20); + return; + +err_llb: + drm_mm_put_block(compressed_llb); +err_fb: + drm_mm_put_block(compressed_fb); +err: + dev_priv->no_fbc_reason = FBC_STOLEN_TOO_SMALL; + i915_warn_stolen(dev); } static void i915_cleanup_compression(struct drm_device *dev) @@ -1207,12 +1171,11 @@ static int i915_load_modeset_init(struct drm_device *dev) prealloc_size = dev_priv->mm.gtt->gtt_stolen_entries << PAGE_SHIFT; gtt_size = dev_priv->mm.gtt->gtt_total_entries << PAGE_SHIFT; mappable_size = dev_priv->mm.gtt->gtt_mappable_entries << PAGE_SHIFT; - gtt_size -= PAGE_SIZE; - /* Basic memrange allocator for stolen space (aka mm.vram) */ - drm_mm_init(&dev_priv->mm.vram, 0, prealloc_size); + /* Basic memrange allocator for stolen space */ + drm_mm_init(&dev_priv->mm.stolen, 0, prealloc_size); - /* Let GEM Manage from end of prealloc space to end of aperture. + /* Let GEM Manage all of the aperture. * * However, leave one page at the end still bound to the scratch page. * There are a number of places where the hardware apparently @@ -1221,7 +1184,7 @@ static int i915_load_modeset_init(struct drm_device *dev) * at the last page of the aperture. One page should be enough to * keep any prefetching inside of the aperture. */ - i915_gem_do_init(dev, prealloc_size, mappable_size, gtt_size); + i915_gem_do_init(dev, 0, mappable_size, gtt_size - PAGE_SIZE); mutex_lock(&dev->struct_mutex); ret = i915_gem_init_ringbuffer(dev); @@ -1233,16 +1196,17 @@ static int i915_load_modeset_init(struct drm_device *dev) if (I915_HAS_FBC(dev) && i915_powersave) { int cfb_size; - /* Try to get an 8M buffer... */ - if (prealloc_size > (9*1024*1024)) - cfb_size = 8*1024*1024; + /* Leave 1M for line length buffer & misc. */ + + /* Try to get a 32M buffer... */ + if (prealloc_size > (36*1024*1024)) + cfb_size = 32*1024*1024; else /* fall back to 7/8 of the stolen space */ cfb_size = prealloc_size * 7 / 8; i915_setup_compression(dev, cfb_size); } - /* Allow hardware batchbuffers unless told otherwise. - */ + /* Allow hardware batchbuffers unless told otherwise. */ dev_priv->allow_batchbuffer = 1; ret = intel_parse_bios(dev); @@ -1892,7 +1856,8 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) { struct drm_i915_private *dev_priv; int ret = 0, mmio_bar; - uint32_t agp_size, prealloc_size; + uint32_t agp_size; + /* i915 has 4 more counters */ dev->counters += 4; dev->types[6] = _DRM_STAT_IRQ; @@ -1932,7 +1897,6 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) goto out_iomapfree; } - prealloc_size = dev_priv->mm.gtt->gtt_stolen_entries << PAGE_SHIFT; agp_size = dev_priv->mm.gtt->gtt_mappable_entries << PAGE_SHIFT; dev_priv->mm.gtt_mapping = @@ -1980,15 +1944,6 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) /* enable GEM by default */ dev_priv->has_gem = 1; - if (prealloc_size > agp_size * 3 / 4) { - DRM_ERROR("Detected broken video BIOS with %d/%dkB of video " - "memory stolen.\n", - prealloc_size / 1024, agp_size / 1024); - DRM_ERROR("Disabling GEM. (try reducing stolen memory or " - "updating the BIOS to fix).\n"); - dev_priv->has_gem = 0; - } - if (dev_priv->has_gem == 0 && drm_core_check_feature(dev, DRIVER_MODESET)) { DRM_ERROR("kernel modesetting requires GEM, disabling driver.\n"); @@ -2162,7 +2117,7 @@ int i915_driver_unload(struct drm_device *dev) mutex_unlock(&dev->struct_mutex); if (I915_HAS_FBC(dev) && i915_powersave) i915_cleanup_compression(dev); - drm_mm_takedown(&dev_priv->mm.vram); + drm_mm_takedown(&dev_priv->mm.stolen); intel_cleanup_overlay(dev); diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index db79df376b86..745e46b0673f 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -544,7 +544,7 @@ typedef struct drm_i915_private { /** Bridge to intel-gtt-ko */ struct intel_gtt *gtt; /** Memory allocator for GTT stolen memory */ - struct drm_mm vram; + struct drm_mm stolen; /** Memory allocator for GTT */ struct drm_mm gtt_space; /** End of mappable part of GTT */ -- cgit v1.2.3 From 1b6064d79b9a1c5e5aa6fcc6855f3da5e639ff73 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 23 Nov 2010 12:33:54 +0000 Subject: agp/intel: Remove the artificial cap on stolen size Now that the stolen memory does not also steal entries from the GTT, we can use all the memory the BIOS set aside for the GPU. Signed-off-by: Chris Wilson --- drivers/char/agp/intel-gtt.c | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/drivers/char/agp/intel-gtt.c b/drivers/char/agp/intel-gtt.c index fc1637c32cb1..19919ef9d661 100644 --- a/drivers/char/agp/intel-gtt.c +++ b/drivers/char/agp/intel-gtt.c @@ -39,9 +39,6 @@ #define USE_PCI_DMA_API 0 #endif -/* Max amount of stolen space, anything above will be returned to Linux */ -int intel_max_stolen = 32 * 1024 * 1024; - static const struct aper_size_info_fixed intel_i810_sizes[] = { {64, 16384, 4}, @@ -486,7 +483,7 @@ static unsigned int intel_gtt_stolen_entries(void) u8 rdct; int local = 0; static const int ddt[4] = { 0, 16, 32, 64 }; - unsigned int overhead_entries, stolen_entries; + unsigned int overhead_entries; unsigned int stolen_size = 0; pci_read_config_word(intel_private.bridge_dev, @@ -625,12 +622,7 @@ static unsigned int intel_gtt_stolen_entries(void) } } - if (!local && stolen_size > intel_max_stolen) { - dev_info(&intel_private.bridge_dev->dev, - "detected %dK stolen memory, trimming to %dK\n", - stolen_size / KB(1), intel_max_stolen / KB(1)); - stolen_size = intel_max_stolen; - } else if (stolen_size > 0) { + if (stolen_size > 0) { dev_info(&intel_private.bridge_dev->dev, "detected %dK %s memory\n", stolen_size / KB(1), local ? "local" : "stolen"); } else { @@ -639,9 +631,7 @@ static unsigned int intel_gtt_stolen_entries(void) stolen_size = 0; } - stolen_entries = stolen_size/KB(4) - overhead_entries; - - return stolen_entries; + return stolen_size/KB(4) - overhead_entries; } static void i965_adjust_pgetbl_size(unsigned int size_flag) -- cgit v1.2.3 From c64f7ba5f1006d8c20eacafecf98d4d00a6902a0 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 23 Nov 2010 14:24:24 +0000 Subject: agp/intel: Remove confusion of stolen entries not stolen memory Signed-off-by: Chris Wilson --- drivers/char/agp/intel-gtt.c | 40 +++++++--------------------------------- drivers/gpu/drm/i915/i915_dma.c | 4 ++-- drivers/gpu/drm/i915/i915_drv.h | 2 +- include/drm/intel-gtt.h | 11 +++++------ 4 files changed, 15 insertions(+), 42 deletions(-) diff --git a/drivers/char/agp/intel-gtt.c b/drivers/char/agp/intel-gtt.c index 19919ef9d661..d2733e526a68 100644 --- a/drivers/char/agp/intel-gtt.c +++ b/drivers/char/agp/intel-gtt.c @@ -477,26 +477,17 @@ static const struct aper_size_info_fixed const intel_fake_agp_sizes[] = { {512, 131072, 7}, }; -static unsigned int intel_gtt_stolen_entries(void) +static unsigned int intel_gtt_stolen_size(void) { u16 gmch_ctrl; u8 rdct; int local = 0; static const int ddt[4] = { 0, 16, 32, 64 }; - unsigned int overhead_entries; unsigned int stolen_size = 0; pci_read_config_word(intel_private.bridge_dev, I830_GMCH_CTRL, &gmch_ctrl); - if (INTEL_GTT_GEN > 4 || IS_PINEVIEW) - overhead_entries = 0; - else - overhead_entries = intel_private.base.gtt_mappable_entries - / 1024; - - overhead_entries += 1; /* BIOS popup */ - if (intel_private.bridge_dev->device == PCI_DEVICE_ID_INTEL_82830_HB || intel_private.bridge_dev->device == PCI_DEVICE_ID_INTEL_82845G_HB) { switch (gmch_ctrl & I830_GMCH_GMS_MASK) { @@ -631,7 +622,7 @@ static unsigned int intel_gtt_stolen_entries(void) stolen_size = 0; } - return stolen_size/KB(4) - overhead_entries; + return stolen_size; } static void i965_adjust_pgetbl_size(unsigned int size_flag) @@ -817,8 +808,8 @@ static int intel_gtt_init(void) global_cache_flush(); /* FIXME: ? */ /* we have to call this as early as possible after the MMIO base address is known */ - intel_private.base.gtt_stolen_entries = intel_gtt_stolen_entries(); - if (intel_private.base.gtt_stolen_entries == 0) { + intel_private.base.stolen_size = intel_gtt_stolen_size(); + if (intel_private.base.stolen_size == 0) { intel_private.driver->cleanup(); iounmap(intel_private.registers); iounmap(intel_private.gtt); @@ -1006,8 +997,7 @@ static int intel_fake_agp_configure(void) agp_bridge->gart_bus_addr = intel_private.gma_bus_addr; - for (i = intel_private.base.gtt_stolen_entries; - i < intel_private.base.gtt_total_entries; i++) { + for (i = 0; i < intel_private.base.gtt_total_entries; i++) { intel_private.driver->write_entry(intel_private.scratch_page_dma, i, 0); } @@ -1065,17 +1055,7 @@ static int intel_fake_agp_insert_entries(struct agp_memory *mem, if (mem->page_count == 0) goto out; - if (pg_start < intel_private.base.gtt_stolen_entries) { - dev_printk(KERN_DEBUG, &intel_private.pcidev->dev, - "pg_start == 0x%.8lx, gtt_stolen_entries == 0x%.8x\n", - pg_start, intel_private.base.gtt_stolen_entries); - - dev_info(&intel_private.pcidev->dev, - "trying to insert into local/stolen memory\n"); - goto out_err; - } - - if ((pg_start + mem->page_count) > intel_private.base.gtt_total_entries) + if (pg_start + mem->page_count > intel_private.base.gtt_total_entries) goto out_err; if (type != mem->type) @@ -1118,12 +1098,6 @@ static int intel_fake_agp_remove_entries(struct agp_memory *mem, if (mem->page_count == 0) return 0; - if (pg_start < intel_private.base.gtt_stolen_entries) { - dev_info(&intel_private.pcidev->dev, - "trying to disable local/stolen memory\n"); - return -EINVAL; - } - if (USE_PCI_DMA_API && INTEL_GTT_GEN > 2) intel_agp_unmap_memory(mem); @@ -1629,7 +1603,7 @@ int intel_gmch_probe(struct pci_dev *pdev, } EXPORT_SYMBOL(intel_gmch_probe); -struct intel_gtt *intel_gtt_get(void) +const struct intel_gtt *intel_gtt_get(void) { return &intel_private.base; } diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 3df271215ab9..86b0e8052ec9 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -1044,7 +1044,7 @@ static unsigned long i915_stolen_to_phys(struct drm_device *dev, u32 offset) pci_read_config_byte(pdev, 0x9c, &val); base = val >> 3 << 27; } - base -= dev_priv->mm.gtt->gtt_stolen_entries << PAGE_SHIFT; + base -= dev_priv->mm.gtt->stolen_size; #endif return base + offset; @@ -1168,7 +1168,7 @@ static int i915_load_modeset_init(struct drm_device *dev) unsigned long prealloc_size, gtt_size, mappable_size; int ret = 0; - prealloc_size = dev_priv->mm.gtt->gtt_stolen_entries << PAGE_SHIFT; + prealloc_size = dev_priv->mm.gtt->stolen_size; gtt_size = dev_priv->mm.gtt->gtt_total_entries << PAGE_SHIFT; mappable_size = dev_priv->mm.gtt->gtt_mappable_entries << PAGE_SHIFT; diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 745e46b0673f..b62ff5d6fa7e 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -542,7 +542,7 @@ typedef struct drm_i915_private { struct { /** Bridge to intel-gtt-ko */ - struct intel_gtt *gtt; + const struct intel_gtt *gtt; /** Memory allocator for GTT stolen memory */ struct drm_mm stolen; /** Memory allocator for GTT */ diff --git a/include/drm/intel-gtt.h b/include/drm/intel-gtt.h index d3c81946f613..020f8aab7e5b 100644 --- a/include/drm/intel-gtt.h +++ b/include/drm/intel-gtt.h @@ -2,17 +2,16 @@ #ifndef _DRM_INTEL_GTT_H #define _DRM_INTEL_GTT_H -struct intel_gtt { - /* Number of stolen gtt entries at the beginning. */ - unsigned int gtt_stolen_entries; + +const struct intel_gtt { + /* Size of memory reserved for graphics by the BIOS */ + unsigned int stolen_size; /* Total number of gtt entries. */ unsigned int gtt_total_entries; /* Part of the gtt that is mappable by the cpu, for those chips where * this is not the full gtt. */ unsigned int gtt_mappable_entries; -}; - -struct intel_gtt *intel_gtt_get(void); +} *intel_gtt_get(void); #endif -- cgit v1.2.3 From faa60c4174d943696b9478c5de6438c4f0fecba6 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 23 Nov 2010 13:50:14 +0000 Subject: drm/i915: Contract the magic IPS constants into a direct LUT ... and no need to perform a linear search for the index. Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_dma.c | 304 +++++++++++++++++++--------------------- 1 file changed, 144 insertions(+), 160 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 86b0e8052ec9..7084de7c4c55 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -1396,152 +1396,12 @@ static void i915_ironlake_get_mem_freq(struct drm_device *dev) } } -struct v_table { - u8 vid; - unsigned long vd; /* in .1 mil */ - unsigned long vm; /* in .1 mil */ - u8 pvid; -}; - -static struct v_table v_table[] = { - { 0, 16125, 15000, 0x7f, }, - { 1, 16000, 14875, 0x7e, }, - { 2, 15875, 14750, 0x7d, }, - { 3, 15750, 14625, 0x7c, }, - { 4, 15625, 14500, 0x7b, }, - { 5, 15500, 14375, 0x7a, }, - { 6, 15375, 14250, 0x79, }, - { 7, 15250, 14125, 0x78, }, - { 8, 15125, 14000, 0x77, }, - { 9, 15000, 13875, 0x76, }, - { 10, 14875, 13750, 0x75, }, - { 11, 14750, 13625, 0x74, }, - { 12, 14625, 13500, 0x73, }, - { 13, 14500, 13375, 0x72, }, - { 14, 14375, 13250, 0x71, }, - { 15, 14250, 13125, 0x70, }, - { 16, 14125, 13000, 0x6f, }, - { 17, 14000, 12875, 0x6e, }, - { 18, 13875, 12750, 0x6d, }, - { 19, 13750, 12625, 0x6c, }, - { 20, 13625, 12500, 0x6b, }, - { 21, 13500, 12375, 0x6a, }, - { 22, 13375, 12250, 0x69, }, - { 23, 13250, 12125, 0x68, }, - { 24, 13125, 12000, 0x67, }, - { 25, 13000, 11875, 0x66, }, - { 26, 12875, 11750, 0x65, }, - { 27, 12750, 11625, 0x64, }, - { 28, 12625, 11500, 0x63, }, - { 29, 12500, 11375, 0x62, }, - { 30, 12375, 11250, 0x61, }, - { 31, 12250, 11125, 0x60, }, - { 32, 12125, 11000, 0x5f, }, - { 33, 12000, 10875, 0x5e, }, - { 34, 11875, 10750, 0x5d, }, - { 35, 11750, 10625, 0x5c, }, - { 36, 11625, 10500, 0x5b, }, - { 37, 11500, 10375, 0x5a, }, - { 38, 11375, 10250, 0x59, }, - { 39, 11250, 10125, 0x58, }, - { 40, 11125, 10000, 0x57, }, - { 41, 11000, 9875, 0x56, }, - { 42, 10875, 9750, 0x55, }, - { 43, 10750, 9625, 0x54, }, - { 44, 10625, 9500, 0x53, }, - { 45, 10500, 9375, 0x52, }, - { 46, 10375, 9250, 0x51, }, - { 47, 10250, 9125, 0x50, }, - { 48, 10125, 9000, 0x4f, }, - { 49, 10000, 8875, 0x4e, }, - { 50, 9875, 8750, 0x4d, }, - { 51, 9750, 8625, 0x4c, }, - { 52, 9625, 8500, 0x4b, }, - { 53, 9500, 8375, 0x4a, }, - { 54, 9375, 8250, 0x49, }, - { 55, 9250, 8125, 0x48, }, - { 56, 9125, 8000, 0x47, }, - { 57, 9000, 7875, 0x46, }, - { 58, 8875, 7750, 0x45, }, - { 59, 8750, 7625, 0x44, }, - { 60, 8625, 7500, 0x43, }, - { 61, 8500, 7375, 0x42, }, - { 62, 8375, 7250, 0x41, }, - { 63, 8250, 7125, 0x40, }, - { 64, 8125, 7000, 0x3f, }, - { 65, 8000, 6875, 0x3e, }, - { 66, 7875, 6750, 0x3d, }, - { 67, 7750, 6625, 0x3c, }, - { 68, 7625, 6500, 0x3b, }, - { 69, 7500, 6375, 0x3a, }, - { 70, 7375, 6250, 0x39, }, - { 71, 7250, 6125, 0x38, }, - { 72, 7125, 6000, 0x37, }, - { 73, 7000, 5875, 0x36, }, - { 74, 6875, 5750, 0x35, }, - { 75, 6750, 5625, 0x34, }, - { 76, 6625, 5500, 0x33, }, - { 77, 6500, 5375, 0x32, }, - { 78, 6375, 5250, 0x31, }, - { 79, 6250, 5125, 0x30, }, - { 80, 6125, 5000, 0x2f, }, - { 81, 6000, 4875, 0x2e, }, - { 82, 5875, 4750, 0x2d, }, - { 83, 5750, 4625, 0x2c, }, - { 84, 5625, 4500, 0x2b, }, - { 85, 5500, 4375, 0x2a, }, - { 86, 5375, 4250, 0x29, }, - { 87, 5250, 4125, 0x28, }, - { 88, 5125, 4000, 0x27, }, - { 89, 5000, 3875, 0x26, }, - { 90, 4875, 3750, 0x25, }, - { 91, 4750, 3625, 0x24, }, - { 92, 4625, 3500, 0x23, }, - { 93, 4500, 3375, 0x22, }, - { 94, 4375, 3250, 0x21, }, - { 95, 4250, 3125, 0x20, }, - { 96, 4125, 3000, 0x1f, }, - { 97, 4125, 3000, 0x1e, }, - { 98, 4125, 3000, 0x1d, }, - { 99, 4125, 3000, 0x1c, }, - { 100, 4125, 3000, 0x1b, }, - { 101, 4125, 3000, 0x1a, }, - { 102, 4125, 3000, 0x19, }, - { 103, 4125, 3000, 0x18, }, - { 104, 4125, 3000, 0x17, }, - { 105, 4125, 3000, 0x16, }, - { 106, 4125, 3000, 0x15, }, - { 107, 4125, 3000, 0x14, }, - { 108, 4125, 3000, 0x13, }, - { 109, 4125, 3000, 0x12, }, - { 110, 4125, 3000, 0x11, }, - { 111, 4125, 3000, 0x10, }, - { 112, 4125, 3000, 0x0f, }, - { 113, 4125, 3000, 0x0e, }, - { 114, 4125, 3000, 0x0d, }, - { 115, 4125, 3000, 0x0c, }, - { 116, 4125, 3000, 0x0b, }, - { 117, 4125, 3000, 0x0a, }, - { 118, 4125, 3000, 0x09, }, - { 119, 4125, 3000, 0x08, }, - { 120, 1125, 0, 0x07, }, - { 121, 1000, 0, 0x06, }, - { 122, 875, 0, 0x05, }, - { 123, 750, 0, 0x04, }, - { 124, 625, 0, 0x03, }, - { 125, 500, 0, 0x02, }, - { 126, 375, 0, 0x01, }, - { 127, 0, 0, 0x00, }, -}; - -struct cparams { - int i; - int t; - int m; - int c; -}; - -static struct cparams cparams[] = { +static const struct cparams { + u16 i; + u16 t; + u16 m; + u16 c; +} cparams[] = { { 1, 1333, 301, 28664 }, { 1, 1066, 294, 24460 }, { 1, 800, 294, 25192 }, @@ -1607,21 +1467,145 @@ unsigned long i915_mch_val(struct drm_i915_private *dev_priv) return ((m * x) / 127) - b; } -static unsigned long pvid_to_extvid(struct drm_i915_private *dev_priv, u8 pxvid) +static u16 pvid_to_extvid(struct drm_i915_private *dev_priv, u8 pxvid) { - unsigned long val = 0; - int i; - - for (i = 0; i < ARRAY_SIZE(v_table); i++) { - if (v_table[i].pvid == pxvid) { - if (IS_MOBILE(dev_priv->dev)) - val = v_table[i].vm; - else - val = v_table[i].vd; - } - } - - return val; + static const struct v_table { + u16 vd; /* in .1 mil */ + u16 vm; /* in .1 mil */ + } v_table[] = { + { 0, 0, }, + { 375, 0, }, + { 500, 0, }, + { 625, 0, }, + { 750, 0, }, + { 875, 0, }, + { 1000, 0, }, + { 1125, 0, }, + { 4125, 3000, }, + { 4125, 3000, }, + { 4125, 3000, }, + { 4125, 3000, }, + { 4125, 3000, }, + { 4125, 3000, }, + { 4125, 3000, }, + { 4125, 3000, }, + { 4125, 3000, }, + { 4125, 3000, }, + { 4125, 3000, }, + { 4125, 3000, }, + { 4125, 3000, }, + { 4125, 3000, }, + { 4125, 3000, }, + { 4125, 3000, }, + { 4125, 3000, }, + { 4125, 3000, }, + { 4125, 3000, }, + { 4125, 3000, }, + { 4125, 3000, }, + { 4125, 3000, }, + { 4125, 3000, }, + { 4125, 3000, }, + { 4250, 3125, }, + { 4375, 3250, }, + { 4500, 3375, }, + { 4625, 3500, }, + { 4750, 3625, }, + { 4875, 3750, }, + { 5000, 3875, }, + { 5125, 4000, }, + { 5250, 4125, }, + { 5375, 4250, }, + { 5500, 4375, }, + { 5625, 4500, }, + { 5750, 4625, }, + { 5875, 4750, }, + { 6000, 4875, }, + { 6125, 5000, }, + { 6250, 5125, }, + { 6375, 5250, }, + { 6500, 5375, }, + { 6625, 5500, }, + { 6750, 5625, }, + { 6875, 5750, }, + { 7000, 5875, }, + { 7125, 6000, }, + { 7250, 6125, }, + { 7375, 6250, }, + { 7500, 6375, }, + { 7625, 6500, }, + { 7750, 6625, }, + { 7875, 6750, }, + { 8000, 6875, }, + { 8125, 7000, }, + { 8250, 7125, }, + { 8375, 7250, }, + { 8500, 7375, }, + { 8625, 7500, }, + { 8750, 7625, }, + { 8875, 7750, }, + { 9000, 7875, }, + { 9125, 8000, }, + { 9250, 8125, }, + { 9375, 8250, }, + { 9500, 8375, }, + { 9625, 8500, }, + { 9750, 8625, }, + { 9875, 8750, }, + { 10000, 8875, }, + { 10125, 9000, }, + { 10250, 9125, }, + { 10375, 9250, }, + { 10500, 9375, }, + { 10625, 9500, }, + { 10750, 9625, }, + { 10875, 9750, }, + { 11000, 9875, }, + { 11125, 10000, }, + { 11250, 10125, }, + { 11375, 10250, }, + { 11500, 10375, }, + { 11625, 10500, }, + { 11750, 10625, }, + { 11875, 10750, }, + { 12000, 10875, }, + { 12125, 11000, }, + { 12250, 11125, }, + { 12375, 11250, }, + { 12500, 11375, }, + { 12625, 11500, }, + { 12750, 11625, }, + { 12875, 11750, }, + { 13000, 11875, }, + { 13125, 12000, }, + { 13250, 12125, }, + { 13375, 12250, }, + { 13500, 12375, }, + { 13625, 12500, }, + { 13750, 12625, }, + { 13875, 12750, }, + { 14000, 12875, }, + { 14125, 13000, }, + { 14250, 13125, }, + { 14375, 13250, }, + { 14500, 13375, }, + { 14625, 13500, }, + { 14750, 13625, }, + { 14875, 13750, }, + { 15000, 13875, }, + { 15125, 14000, }, + { 15250, 14125, }, + { 15375, 14250, }, + { 15500, 14375, }, + { 15625, 14500, }, + { 15750, 14625, }, + { 15875, 14750, }, + { 16000, 14875, }, + { 16125, 15000, }, + }; + if (dev_priv->info->is_mobile) + return v_table[pxvid].vm; + else + return v_table[pxvid].vd; } void i915_update_gfx_val(struct drm_i915_private *dev_priv) -- cgit v1.2.3 From b47cf66f315a258c458ed4345c443dba396fb787 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Thu, 4 Nov 2010 18:41:50 +0100 Subject: intel-gtt: drop dcache support for i830 and later i830_check_flags already disallows it, so no need to implement it in the write_entry function. Seems to be a remnant from i810 support. Signed-off-by: Daniel Vetter Signed-off-by: Chris Wilson --- drivers/char/agp/intel-gtt.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/drivers/char/agp/intel-gtt.c b/drivers/char/agp/intel-gtt.c index d2733e526a68..8a30a16c5706 100644 --- a/drivers/char/agp/intel-gtt.c +++ b/drivers/char/agp/intel-gtt.c @@ -896,14 +896,8 @@ static void i830_write_entry(dma_addr_t addr, unsigned int entry, { u32 pte_flags = I810_PTE_VALID; - switch (flags) { - case AGP_DCACHE_MEMORY: - pte_flags |= I810_PTE_LOCAL; - break; - case AGP_USER_CACHED_MEMORY: + if (flags == AGP_USER_CACHED_MEMORY) pte_flags |= I830_PTE_SYSTEM_CACHED; - break; - } writel(addr | pte_flags, intel_private.gtt + entry); } -- cgit v1.2.3 From 24a6b387af7cd5d1e0e5d15b15104644a5105de7 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Thu, 4 Nov 2010 20:14:15 +0100 Subject: intel-gtt: kill unneeded sandybridge memory types Used for the now dead agp type_to_mask stuff. Signed-off-by: Daniel Vetter Signed-off-by: Chris Wilson --- drivers/char/agp/intel-gtt.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/drivers/char/agp/intel-gtt.c b/drivers/char/agp/intel-gtt.c index 8a30a16c5706..2470040023d3 100644 --- a/drivers/char/agp/intel-gtt.c +++ b/drivers/char/agp/intel-gtt.c @@ -59,12 +59,6 @@ static struct gatt_mask intel_i810_masks[] = .type = INTEL_AGP_CACHED_MEMORY} }; -#define INTEL_AGP_UNCACHED_MEMORY 0 -#define INTEL_AGP_CACHED_MEMORY_LLC 1 -#define INTEL_AGP_CACHED_MEMORY_LLC_GFDT 2 -#define INTEL_AGP_CACHED_MEMORY_LLC_MLC 3 -#define INTEL_AGP_CACHED_MEMORY_LLC_MLC_GFDT 4 - struct intel_gtt_driver { unsigned int gen : 8; unsigned int is_g33 : 1; -- cgit v1.2.3 From 625dd9d331d8a1ce5ee4e9924a22f3e55b7ac615 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Thu, 4 Nov 2010 20:07:57 +0100 Subject: intel-gtt: switch i81x to the write_entry helpers Initialization is still done with the old code with a few added things sprinkled in to make the intel_fake_agp helper functions work. Signed-off-by: Daniel Vetter Signed-off-by: Chris Wilson --- drivers/char/agp/intel-gtt.c | 152 +++++++++++++++++-------------------------- 1 file changed, 60 insertions(+), 92 deletions(-) diff --git a/drivers/char/agp/intel-gtt.c b/drivers/char/agp/intel-gtt.c index 2470040023d3..9d17a6d51640 100644 --- a/drivers/char/agp/intel-gtt.c +++ b/drivers/char/agp/intel-gtt.c @@ -101,6 +101,9 @@ static struct _intel_private { dma_addr_t scratch_page_dma; } intel_private; +static int intel_fake_agp_insert_entries(struct agp_memory *mem, + off_t pg_start, int type); + #define INTEL_GTT_GEN intel_private.driver->gen #define IS_G33 intel_private.driver->is_g33 #define IS_PINEVIEW intel_private.driver->is_pineview @@ -176,10 +179,12 @@ static int intel_i810_fetch_size(void) if ((smram_miscc & I810_GFX_MEM_WIN_SIZE) == I810_GFX_MEM_WIN_32M) { agp_bridge->current_size = (void *) (values + 1); agp_bridge->aperture_size_idx = 1; + intel_private.base.gtt_total_entries = KB(32) / 4; return values[1].size; } else { agp_bridge->current_size = (void *) (values); agp_bridge->aperture_size_idx = 0; + intel_private.base.gtt_total_entries = KB(64) / 4; return values[0].size; } @@ -206,6 +211,9 @@ static int intel_i810_configure(void) } } + intel_private.gtt = intel_private.registers + I810_PTE_BASE; + intel_private.scratch_page_dma = agp_bridge->scratch_page & PAGE_MASK; + if ((readl(intel_private.registers+I810_DRAM_CTL) & I810_DRAM_ROW_0) == I810_DRAM_ROW_0_SDRAM) { /* This will need to be dynamically assigned */ @@ -273,79 +281,27 @@ static void i8xx_destroy_pages(struct page *page) static int intel_i810_insert_entries(struct agp_memory *mem, off_t pg_start, int type) { - int i, j, num_entries; - void *temp; - int ret = -EINVAL; - int mask_type; - - if (mem->page_count == 0) - goto out; - - temp = agp_bridge->current_size; - num_entries = A_SIZE_FIX(temp)->num_entries; - - if ((pg_start + mem->page_count) > num_entries) - goto out_err; - - - for (j = pg_start; j < (pg_start + mem->page_count); j++) { - if (!PGE_EMPTY(agp_bridge, readl(agp_bridge->gatt_table+j))) { - ret = -EBUSY; - goto out_err; - } - } - - if (type != mem->type) - goto out_err; + int i; - mask_type = agp_bridge->driver->agp_type_to_mask_type(agp_bridge, type); + if (type == AGP_DCACHE_MEMORY) { + if ((pg_start + mem->page_count) + > intel_private.num_dcache_entries) + return -EINVAL; - switch (mask_type) { - case AGP_DCACHE_MEMORY: if (!mem->is_flushed) global_cache_flush(); + for (i = pg_start; i < (pg_start + mem->page_count); i++) { - writel((i*4096)|I810_PTE_LOCAL|I810_PTE_VALID, - intel_private.registers+I810_PTE_BASE+(i*4)); - } - readl(intel_private.registers+I810_PTE_BASE+((i-1)*4)); - break; - case AGP_PHYS_MEMORY: - case AGP_NORMAL_MEMORY: - if (!mem->is_flushed) - global_cache_flush(); - for (i = 0, j = pg_start; i < mem->page_count; i++, j++) { - writel(agp_bridge->driver->mask_memory(agp_bridge, - page_to_phys(mem->pages[i]), mask_type), - intel_private.registers+I810_PTE_BASE+(j*4)); + dma_addr_t addr = i << PAGE_SHIFT; + intel_private.driver->write_entry(addr, + i, type); } - readl(intel_private.registers+I810_PTE_BASE+((j-1)*4)); - break; - default: - goto out_err; - } - -out: - ret = 0; -out_err: - mem->is_flushed = true; - return ret; -} + readl(intel_private.gtt+i-1); -static int intel_i810_remove_entries(struct agp_memory *mem, off_t pg_start, - int type) -{ - int i; - - if (mem->page_count == 0) return 0; - - for (i = pg_start; i < (mem->page_count + pg_start); i++) { - writel(agp_bridge->scratch_page, intel_private.registers+I810_PTE_BASE+(i*4)); } - readl(intel_private.registers+I810_PTE_BASE+((i-1)*4)); - return 0; + return intel_fake_agp_insert_entries(mem, pg_start, type); } /* @@ -390,29 +346,6 @@ static struct agp_memory *alloc_agpphysmem_i8xx(size_t pg_count, int type) return new; } -static struct agp_memory *intel_i810_alloc_by_type(size_t pg_count, int type) -{ - struct agp_memory *new; - - if (type == AGP_DCACHE_MEMORY) { - if (pg_count != intel_private.num_dcache_entries) - return NULL; - - new = agp_create_memory(1); - if (new == NULL) - return NULL; - - new->type = AGP_DCACHE_MEMORY; - new->page_count = pg_count; - new->num_scratch_pages = 0; - agp_free_page_array(new); - return new; - } - if (type == AGP_PHYS_MEMORY) - return alloc_agpphysmem_i8xx(pg_count, type); - return NULL; -} - static void intel_i810_free_by_type(struct agp_memory *curr) { agp_free_key(curr->key); @@ -463,6 +396,23 @@ static int intel_gtt_setup_scratch_page(void) return 0; } +static void i810_write_entry(dma_addr_t addr, unsigned int entry, + unsigned int flags) +{ + u32 pte_flags = I810_PTE_VALID; + + switch (flags) { + case AGP_DCACHE_MEMORY: + pte_flags |= I810_PTE_LOCAL; + break; + case AGP_USER_CACHED_MEMORY: + pte_flags |= I830_PTE_SYSTEM_CACHED; + break; + } + + writel(addr | pte_flags, intel_private.gtt + entry); +} + static const struct aper_size_info_fixed const intel_fake_agp_sizes[] = { {128, 32768, 5}, /* The 64M mode still requires a 128k gatt */ @@ -760,7 +710,7 @@ static void intel_gtt_cleanup(void) iounmap(intel_private.gtt); iounmap(intel_private.registers); - + intel_gtt_teardown_scratch_page(); } @@ -889,7 +839,7 @@ static void i830_write_entry(dma_addr_t addr, unsigned int entry, unsigned int flags) { u32 pte_flags = I810_PTE_VALID; - + if (flags == AGP_USER_CACHED_MEMORY) pte_flags |= I830_PTE_SYSTEM_CACHED; @@ -1106,6 +1056,22 @@ static void intel_fake_agp_chipset_flush(struct agp_bridge_data *bridge) static struct agp_memory *intel_fake_agp_alloc_by_type(size_t pg_count, int type) { + struct agp_memory *new; + + if (type == AGP_DCACHE_MEMORY && INTEL_GTT_GEN == 1) { + if (pg_count != intel_private.num_dcache_entries) + return NULL; + + new = agp_create_memory(1); + if (new == NULL) + return NULL; + + new->type = AGP_DCACHE_MEMORY; + new->page_count = pg_count; + new->num_scratch_pages = 0; + agp_free_page_array(new); + return new; + } if (type == AGP_PHYS_MEMORY) return alloc_agpphysmem_i8xx(pg_count, type); /* always return NULL for other allocation types for now */ @@ -1316,8 +1282,8 @@ static const struct agp_bridge_driver intel_810_driver = { .create_gatt_table = agp_generic_create_gatt_table, .free_gatt_table = agp_generic_free_gatt_table, .insert_memory = intel_i810_insert_entries, - .remove_memory = intel_i810_remove_entries, - .alloc_by_type = intel_i810_alloc_by_type, + .remove_memory = intel_fake_agp_remove_entries, + .alloc_by_type = intel_fake_agp_alloc_by_type, .free_by_type = intel_i810_free_by_type, .agp_alloc_page = agp_generic_alloc_page, .agp_alloc_pages = agp_generic_alloc_pages, @@ -1352,6 +1318,8 @@ static const struct agp_bridge_driver intel_fake_agp_driver = { static const struct intel_gtt_driver i81x_gtt_driver = { .gen = 1, .dma_mask_size = 32, + .check_flags = i830_check_flags, + .write_entry = i810_write_entry, }; static const struct intel_gtt_driver i8xx_gtt_driver = { .gen = 2, @@ -1369,7 +1337,7 @@ static const struct intel_gtt_driver i915_gtt_driver = { .setup = i9xx_setup, .cleanup = i9xx_cleanup, /* i945 is the last gpu to need phys mem (for overlay and cursors). */ - .write_entry = i830_write_entry, + .write_entry = i830_write_entry, .dma_mask_size = 32, .check_flags = i830_check_flags, .chipset_flush = i9xx_chipset_flush, @@ -1557,7 +1525,7 @@ int intel_gmch_probe(struct pci_dev *pdev, if (find_gmch(intel_gtt_chipsets[i].gmch_chip_id)) { bridge->driver = intel_gtt_chipsets[i].gmch_driver; - intel_private.driver = + intel_private.driver = intel_gtt_chipsets[i].gtt_driver; break; } -- cgit v1.2.3 From 820647b97a9cbdd976c7177f1b6047fc1f6dd5c0 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Fri, 5 Nov 2010 13:30:14 +0100 Subject: intel-gtt: switch i81x to the common initialization helpers Still a separate agp_bridge_driver because of the i81x-only dedicated vram support. Signed-off-by: Daniel Vetter Signed-off-by: Chris Wilson --- drivers/char/agp/intel-gtt.c | 198 ++++++++++++++++--------------------------- 1 file changed, 71 insertions(+), 127 deletions(-) diff --git a/drivers/char/agp/intel-gtt.c b/drivers/char/agp/intel-gtt.c index 9d17a6d51640..4b79a7b47522 100644 --- a/drivers/char/agp/intel-gtt.c +++ b/drivers/char/agp/intel-gtt.c @@ -39,26 +39,10 @@ #define USE_PCI_DMA_API 0 #endif -static const struct aper_size_info_fixed intel_i810_sizes[] = -{ - {64, 16384, 4}, - /* The 32M mode still requires a 64k gatt */ - {32, 8192, 4} -}; - #define AGP_DCACHE_MEMORY 1 #define AGP_PHYS_MEMORY 2 #define INTEL_AGP_CACHED_MEMORY 3 -static struct gatt_mask intel_i810_masks[] = -{ - {.mask = I810_PTE_VALID, .type = 0}, - {.mask = (I810_PTE_VALID | I810_PTE_LOCAL), .type = AGP_DCACHE_MEMORY}, - {.mask = I810_PTE_VALID, .type = 0}, - {.mask = I810_PTE_VALID | I830_PTE_SYSTEM_CACHED, - .type = INTEL_AGP_CACHED_MEMORY} -}; - struct intel_gtt_driver { unsigned int gen : 8; unsigned int is_g33 : 1; @@ -94,6 +78,7 @@ static struct _intel_private { void __iomem *i9xx_flush_page; void *i8xx_flush_page; }; + char *i81x_gtt_table; struct page *i8xx_page; struct resource ifp_resource; int resource_valid; @@ -163,86 +148,6 @@ static void intel_agp_unmap_memory(struct agp_memory *mem) intel_agp_free_sglist(mem); } -static int intel_i810_fetch_size(void) -{ - u32 smram_miscc; - struct aper_size_info_fixed *values; - - pci_read_config_dword(intel_private.bridge_dev, - I810_SMRAM_MISCC, &smram_miscc); - values = A_SIZE_FIX(agp_bridge->driver->aperture_sizes); - - if ((smram_miscc & I810_GMS) == I810_GMS_DISABLE) { - dev_warn(&intel_private.bridge_dev->dev, "i810 is disabled\n"); - return 0; - } - if ((smram_miscc & I810_GFX_MEM_WIN_SIZE) == I810_GFX_MEM_WIN_32M) { - agp_bridge->current_size = (void *) (values + 1); - agp_bridge->aperture_size_idx = 1; - intel_private.base.gtt_total_entries = KB(32) / 4; - return values[1].size; - } else { - agp_bridge->current_size = (void *) (values); - agp_bridge->aperture_size_idx = 0; - intel_private.base.gtt_total_entries = KB(64) / 4; - return values[0].size; - } - - return 0; -} - -static int intel_i810_configure(void) -{ - struct aper_size_info_fixed *current_size; - u32 temp; - int i; - - current_size = A_SIZE_FIX(agp_bridge->current_size); - - if (!intel_private.registers) { - pci_read_config_dword(intel_private.pcidev, I810_MMADDR, &temp); - temp &= 0xfff80000; - - intel_private.registers = ioremap(temp, 128 * 4096); - if (!intel_private.registers) { - dev_err(&intel_private.pcidev->dev, - "can't remap memory\n"); - return -ENOMEM; - } - } - - intel_private.gtt = intel_private.registers + I810_PTE_BASE; - intel_private.scratch_page_dma = agp_bridge->scratch_page & PAGE_MASK; - - if ((readl(intel_private.registers+I810_DRAM_CTL) - & I810_DRAM_ROW_0) == I810_DRAM_ROW_0_SDRAM) { - /* This will need to be dynamically assigned */ - dev_info(&intel_private.pcidev->dev, - "detected 4MB dedicated video ram\n"); - intel_private.num_dcache_entries = 1024; - } - pci_read_config_dword(intel_private.pcidev, I810_GMADDR, &temp); - agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK); - writel(agp_bridge->gatt_bus_addr | I810_PGETBL_ENABLED, intel_private.registers+I810_PGETBL_CTL); - readl(intel_private.registers+I810_PGETBL_CTL); /* PCI Posting. */ - - if (agp_bridge->driver->needs_scratch_page) { - for (i = 0; i < current_size->num_entries; i++) { - writel(agp_bridge->scratch_page, intel_private.registers+I810_PTE_BASE+(i*4)); - } - readl(intel_private.registers+I810_PTE_BASE+((i-1)*4)); /* PCI posting. */ - } - global_cache_flush(); - return 0; -} - -static void intel_i810_cleanup(void) -{ - writel(0, intel_private.registers+I810_PGETBL_CTL); - readl(intel_private.registers); /* PCI Posting. */ - iounmap(intel_private.registers); -} - static void intel_fake_agp_enable(struct agp_bridge_data *bridge, u32 mode) { return; @@ -278,6 +183,46 @@ static void i8xx_destroy_pages(struct page *page) atomic_dec(&agp_bridge->current_memory_agp); } +#define I810_GTT_ORDER 4 +static int i810_setup(void) +{ + u32 reg_addr; + char *gtt_table; + + /* i81x does not preallocate the gtt. It's always 64kb in size. */ + gtt_table = alloc_gatt_pages(I810_GTT_ORDER); + if (gtt_table == NULL) + return -ENOMEM; + intel_private.i81x_gtt_table = gtt_table; + + pci_read_config_dword(intel_private.pcidev, I810_MMADDR, ®_addr); + reg_addr &= 0xfff80000; + + intel_private.registers = ioremap(reg_addr, KB(64)); + if (!intel_private.registers) + return -ENOMEM; + + writel(virt_to_phys(gtt_table) | I810_PGETBL_ENABLED, + intel_private.registers+I810_PGETBL_CTL); + + intel_private.gtt_bus_addr = reg_addr + I810_PTE_BASE; + + if ((readl(intel_private.registers+I810_DRAM_CTL) + & I810_DRAM_ROW_0) == I810_DRAM_ROW_0_SDRAM) { + dev_info(&intel_private.pcidev->dev, + "detected 4MB dedicated video ram\n"); + intel_private.num_dcache_entries = 1024; + } + + return 0; +} + +static void i810_cleanup(void) +{ + writel(0, intel_private.registers+I810_PGETBL_CTL); + free_gatt_pages(intel_private.i81x_gtt_table, I810_GTT_ORDER); +} + static int intel_i810_insert_entries(struct agp_memory *mem, off_t pg_start, int type) { @@ -363,13 +308,6 @@ static void intel_i810_free_by_type(struct agp_memory *curr) kfree(curr); } -static unsigned long intel_i810_mask_memory(struct agp_bridge_data *bridge, - dma_addr_t addr, int type) -{ - /* Type checking must be done elsewhere */ - return addr | bridge->driver->masks[type].mask; -} - static int intel_gtt_setup_scratch_page(void) { struct page *page; @@ -414,9 +352,9 @@ static void i810_write_entry(dma_addr_t addr, unsigned int entry, } static const struct aper_size_info_fixed const intel_fake_agp_sizes[] = { + {32, 8192, 3}, + {64, 16384, 4}, {128, 32768, 5}, - /* The 64M mode still requires a 128k gatt */ - {64, 16384, 5}, {256, 65536, 6}, {512, 131072, 7}, }; @@ -429,6 +367,9 @@ static unsigned int intel_gtt_stolen_size(void) static const int ddt[4] = { 0, 16, 32, 64 }; unsigned int stolen_size = 0; + if (INTEL_GTT_GEN == 1) + return 0; /* no stolen mem on i81x */ + pci_read_config_word(intel_private.bridge_dev, I830_GMCH_CTRL, &gmch_ctrl); @@ -677,7 +618,18 @@ static unsigned int intel_gtt_mappable_entries(void) { unsigned int aperture_size; - if (INTEL_GTT_GEN == 2) { + if (INTEL_GTT_GEN == 1) { + u32 smram_miscc; + + pci_read_config_dword(intel_private.bridge_dev, + I810_SMRAM_MISCC, &smram_miscc); + + if ((smram_miscc & I810_GFX_MEM_WIN_SIZE) + == I810_GFX_MEM_WIN_32M) + aperture_size = MB(32); + else + aperture_size = MB(64); + } else if (INTEL_GTT_GEN == 2) { u16 gmch_ctrl; pci_read_config_word(intel_private.bridge_dev, @@ -751,14 +703,7 @@ static int intel_gtt_init(void) global_cache_flush(); /* FIXME: ? */ - /* we have to call this as early as possible after the MMIO base address is known */ intel_private.base.stolen_size = intel_gtt_stolen_size(); - if (intel_private.base.stolen_size == 0) { - intel_private.driver->cleanup(); - iounmap(intel_private.registers); - iounmap(intel_private.gtt); - return -ENOMEM; - } ret = intel_gtt_setup_scratch_page(); if (ret != 0) { @@ -851,7 +796,7 @@ static bool intel_enable_gtt(void) u32 gma_addr; u8 __iomem *reg; - if (INTEL_GTT_GEN == 2) + if (INTEL_GTT_GEN <= 2) pci_read_config_dword(intel_private.pcidev, I810_GMADDR, &gma_addr); else @@ -1268,19 +1213,16 @@ static int i9xx_setup(void) static const struct agp_bridge_driver intel_810_driver = { .owner = THIS_MODULE, - .aperture_sizes = intel_i810_sizes, .size_type = FIXED_APER_SIZE, - .num_aperture_sizes = 2, - .needs_scratch_page = true, - .configure = intel_i810_configure, - .fetch_size = intel_i810_fetch_size, - .cleanup = intel_i810_cleanup, - .mask_memory = intel_i810_mask_memory, - .masks = intel_i810_masks, + .aperture_sizes = intel_fake_agp_sizes, + .num_aperture_sizes = ARRAY_SIZE(intel_fake_agp_sizes), + .configure = intel_fake_agp_configure, + .fetch_size = intel_fake_agp_fetch_size, + .cleanup = intel_gtt_cleanup, .agp_enable = intel_fake_agp_enable, .cache_flush = global_cache_flush, - .create_gatt_table = agp_generic_create_gatt_table, - .free_gatt_table = agp_generic_free_gatt_table, + .create_gatt_table = intel_fake_agp_create_gatt_table, + .free_gatt_table = intel_fake_agp_free_gatt_table, .insert_memory = intel_i810_insert_entries, .remove_memory = intel_fake_agp_remove_entries, .alloc_by_type = intel_fake_agp_alloc_by_type, @@ -1289,7 +1231,6 @@ static const struct agp_bridge_driver intel_810_driver = { .agp_alloc_pages = agp_generic_alloc_pages, .agp_destroy_page = agp_generic_destroy_page, .agp_destroy_pages = agp_generic_destroy_pages, - .agp_type_to_mask_type = agp_generic_type_to_mask_type, }; static const struct agp_bridge_driver intel_fake_agp_driver = { @@ -1317,7 +1258,10 @@ static const struct agp_bridge_driver intel_fake_agp_driver = { static const struct intel_gtt_driver i81x_gtt_driver = { .gen = 1, + .has_pgtbl_enable = 1, .dma_mask_size = 32, + .setup = i810_setup, + .cleanup = i810_cleanup, .check_flags = i830_check_flags, .write_entry = i810_write_entry, }; @@ -1549,8 +1493,8 @@ int intel_gmch_probe(struct pci_dev *pdev, pci_set_consistent_dma_mask(intel_private.pcidev, DMA_BIT_MASK(mask)); - if (bridge->driver == &intel_810_driver) - return 1; + /*if (bridge->driver == &intel_810_driver) + return 1;*/ if (intel_gtt_init() != 0) return 0; -- cgit v1.2.3 From ff26860fb53f2dcfaaaf1bf017b09dbdfddff5ee Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Fri, 5 Nov 2010 15:43:35 +0100 Subject: intel-gtt: fold i81x-only dcache support into the generic driver Now the intel-gtt.c rewrite is complete! Signed-off-by: Daniel Vetter Signed-off-by: Chris Wilson --- drivers/char/agp/intel-gtt.c | 150 ++++++++++++++++++------------------------- 1 file changed, 61 insertions(+), 89 deletions(-) diff --git a/drivers/char/agp/intel-gtt.c b/drivers/char/agp/intel-gtt.c index 4b79a7b47522..72267c801637 100644 --- a/drivers/char/agp/intel-gtt.c +++ b/drivers/char/agp/intel-gtt.c @@ -86,9 +86,6 @@ static struct _intel_private { dma_addr_t scratch_page_dma; } intel_private; -static int intel_fake_agp_insert_entries(struct agp_memory *mem, - off_t pg_start, int type); - #define INTEL_GTT_GEN intel_private.driver->gen #define IS_G33 intel_private.driver->is_g33 #define IS_PINEVIEW intel_private.driver->is_pineview @@ -223,30 +220,26 @@ static void i810_cleanup(void) free_gatt_pages(intel_private.i81x_gtt_table, I810_GTT_ORDER); } -static int intel_i810_insert_entries(struct agp_memory *mem, off_t pg_start, - int type) +static int i810_insert_dcache_entries(struct agp_memory *mem, off_t pg_start, + int type) { int i; - if (type == AGP_DCACHE_MEMORY) { - if ((pg_start + mem->page_count) - > intel_private.num_dcache_entries) - return -EINVAL; - - if (!mem->is_flushed) - global_cache_flush(); + if ((pg_start + mem->page_count) + > intel_private.num_dcache_entries) + return -EINVAL; - for (i = pg_start; i < (pg_start + mem->page_count); i++) { - dma_addr_t addr = i << PAGE_SHIFT; - intel_private.driver->write_entry(addr, - i, type); - } - readl(intel_private.gtt+i-1); + if (!mem->is_flushed) + global_cache_flush(); - return 0; + for (i = pg_start; i < (pg_start + mem->page_count); i++) { + dma_addr_t addr = i << PAGE_SHIFT; + intel_private.driver->write_entry(addr, + i, type); } + readl(intel_private.gtt+i-1); - return intel_fake_agp_insert_entries(mem, pg_start, type); + return 0; } /* @@ -935,6 +928,9 @@ static int intel_fake_agp_insert_entries(struct agp_memory *mem, int i, j; int ret = -EINVAL; + if (INTEL_GTT_GEN == 1 && type == AGP_DCACHE_MEMORY) + return i810_insert_dcache_entries(mem, pg_start, type); + if (mem->page_count == 0) goto out; @@ -1211,28 +1207,6 @@ static int i9xx_setup(void) return 0; } -static const struct agp_bridge_driver intel_810_driver = { - .owner = THIS_MODULE, - .size_type = FIXED_APER_SIZE, - .aperture_sizes = intel_fake_agp_sizes, - .num_aperture_sizes = ARRAY_SIZE(intel_fake_agp_sizes), - .configure = intel_fake_agp_configure, - .fetch_size = intel_fake_agp_fetch_size, - .cleanup = intel_gtt_cleanup, - .agp_enable = intel_fake_agp_enable, - .cache_flush = global_cache_flush, - .create_gatt_table = intel_fake_agp_create_gatt_table, - .free_gatt_table = intel_fake_agp_free_gatt_table, - .insert_memory = intel_i810_insert_entries, - .remove_memory = intel_fake_agp_remove_entries, - .alloc_by_type = intel_fake_agp_alloc_by_type, - .free_by_type = intel_i810_free_by_type, - .agp_alloc_page = agp_generic_alloc_page, - .agp_alloc_pages = agp_generic_alloc_pages, - .agp_destroy_page = agp_generic_destroy_page, - .agp_destroy_pages = agp_generic_destroy_pages, -}; - static const struct agp_bridge_driver intel_fake_agp_driver = { .owner = THIS_MODULE, .size_type = FIXED_APER_SIZE, @@ -1352,93 +1326,92 @@ static const struct intel_gtt_driver sandybridge_gtt_driver = { static const struct intel_gtt_driver_description { unsigned int gmch_chip_id; char *name; - const struct agp_bridge_driver *gmch_driver; const struct intel_gtt_driver *gtt_driver; } intel_gtt_chipsets[] = { - { PCI_DEVICE_ID_INTEL_82810_IG1, "i810", &intel_810_driver, + { PCI_DEVICE_ID_INTEL_82810_IG1, "i810", &i81x_gtt_driver}, - { PCI_DEVICE_ID_INTEL_82810_IG3, "i810", &intel_810_driver, + { PCI_DEVICE_ID_INTEL_82810_IG3, "i810", &i81x_gtt_driver}, - { PCI_DEVICE_ID_INTEL_82810E_IG, "i810", &intel_810_driver, + { PCI_DEVICE_ID_INTEL_82810E_IG, "i810", &i81x_gtt_driver}, - { PCI_DEVICE_ID_INTEL_82815_CGC, "i815", &intel_810_driver, + { PCI_DEVICE_ID_INTEL_82815_CGC, "i815", &i81x_gtt_driver}, { PCI_DEVICE_ID_INTEL_82830_CGC, "830M", - &intel_fake_agp_driver, &i8xx_gtt_driver}, + &i8xx_gtt_driver}, { PCI_DEVICE_ID_INTEL_82845G_IG, "830M", - &intel_fake_agp_driver, &i8xx_gtt_driver}, + &i8xx_gtt_driver}, { PCI_DEVICE_ID_INTEL_82854_IG, "854", - &intel_fake_agp_driver, &i8xx_gtt_driver}, + &i8xx_gtt_driver}, { PCI_DEVICE_ID_INTEL_82855GM_IG, "855GM", - &intel_fake_agp_driver, &i8xx_gtt_driver}, + &i8xx_gtt_driver}, { PCI_DEVICE_ID_INTEL_82865_IG, "865", - &intel_fake_agp_driver, &i8xx_gtt_driver}, + &i8xx_gtt_driver}, { PCI_DEVICE_ID_INTEL_E7221_IG, "E7221 (i915)", - &intel_fake_agp_driver, &i915_gtt_driver }, + &i915_gtt_driver }, { PCI_DEVICE_ID_INTEL_82915G_IG, "915G", - &intel_fake_agp_driver, &i915_gtt_driver }, + &i915_gtt_driver }, { PCI_DEVICE_ID_INTEL_82915GM_IG, "915GM", - &intel_fake_agp_driver, &i915_gtt_driver }, + &i915_gtt_driver }, { PCI_DEVICE_ID_INTEL_82945G_IG, "945G", - &intel_fake_agp_driver, &i915_gtt_driver }, + &i915_gtt_driver }, { PCI_DEVICE_ID_INTEL_82945GM_IG, "945GM", - &intel_fake_agp_driver, &i915_gtt_driver }, + &i915_gtt_driver }, { PCI_DEVICE_ID_INTEL_82945GME_IG, "945GME", - &intel_fake_agp_driver, &i915_gtt_driver }, + &i915_gtt_driver }, { PCI_DEVICE_ID_INTEL_82946GZ_IG, "946GZ", - &intel_fake_agp_driver, &i965_gtt_driver }, + &i965_gtt_driver }, { PCI_DEVICE_ID_INTEL_82G35_IG, "G35", - &intel_fake_agp_driver, &i965_gtt_driver }, + &i965_gtt_driver }, { PCI_DEVICE_ID_INTEL_82965Q_IG, "965Q", - &intel_fake_agp_driver, &i965_gtt_driver }, + &i965_gtt_driver }, { PCI_DEVICE_ID_INTEL_82965G_IG, "965G", - &intel_fake_agp_driver, &i965_gtt_driver }, + &i965_gtt_driver }, { PCI_DEVICE_ID_INTEL_82965GM_IG, "965GM", - &intel_fake_agp_driver, &i965_gtt_driver }, + &i965_gtt_driver }, { PCI_DEVICE_ID_INTEL_82965GME_IG, "965GME/GLE", - &intel_fake_agp_driver, &i965_gtt_driver }, + &i965_gtt_driver }, { PCI_DEVICE_ID_INTEL_G33_IG, "G33", - &intel_fake_agp_driver, &g33_gtt_driver }, + &g33_gtt_driver }, { PCI_DEVICE_ID_INTEL_Q35_IG, "Q35", - &intel_fake_agp_driver, &g33_gtt_driver }, + &g33_gtt_driver }, { PCI_DEVICE_ID_INTEL_Q33_IG, "Q33", - &intel_fake_agp_driver, &g33_gtt_driver }, + &g33_gtt_driver }, { PCI_DEVICE_ID_INTEL_PINEVIEW_M_IG, "GMA3150", - &intel_fake_agp_driver, &pineview_gtt_driver }, + &pineview_gtt_driver }, { PCI_DEVICE_ID_INTEL_PINEVIEW_IG, "GMA3150", - &intel_fake_agp_driver, &pineview_gtt_driver }, + &pineview_gtt_driver }, { PCI_DEVICE_ID_INTEL_GM45_IG, "GM45", - &intel_fake_agp_driver, &g4x_gtt_driver }, + &g4x_gtt_driver }, { PCI_DEVICE_ID_INTEL_EAGLELAKE_IG, "Eaglelake", - &intel_fake_agp_driver, &g4x_gtt_driver }, + &g4x_gtt_driver }, { PCI_DEVICE_ID_INTEL_Q45_IG, "Q45/Q43", - &intel_fake_agp_driver, &g4x_gtt_driver }, + &g4x_gtt_driver }, { PCI_DEVICE_ID_INTEL_G45_IG, "G45/G43", - &intel_fake_agp_driver, &g4x_gtt_driver }, + &g4x_gtt_driver }, { PCI_DEVICE_ID_INTEL_B43_IG, "B43", - &intel_fake_agp_driver, &g4x_gtt_driver }, + &g4x_gtt_driver }, { PCI_DEVICE_ID_INTEL_B43_1_IG, "B43", - &intel_fake_agp_driver, &g4x_gtt_driver }, + &g4x_gtt_driver }, { PCI_DEVICE_ID_INTEL_G41_IG, "G41", - &intel_fake_agp_driver, &g4x_gtt_driver }, + &g4x_gtt_driver }, { PCI_DEVICE_ID_INTEL_IRONLAKE_D_IG, - "HD Graphics", &intel_fake_agp_driver, &ironlake_gtt_driver }, + "HD Graphics", &ironlake_gtt_driver }, { PCI_DEVICE_ID_INTEL_IRONLAKE_M_IG, - "HD Graphics", &intel_fake_agp_driver, &ironlake_gtt_driver }, + "HD Graphics", &ironlake_gtt_driver }, { PCI_DEVICE_ID_INTEL_SANDYBRIDGE_GT1_IG, - "Sandybridge", &intel_fake_agp_driver, &sandybridge_gtt_driver }, + "Sandybridge", &sandybridge_gtt_driver }, { PCI_DEVICE_ID_INTEL_SANDYBRIDGE_GT2_IG, - "Sandybridge", &intel_fake_agp_driver, &sandybridge_gtt_driver }, + "Sandybridge", &sandybridge_gtt_driver }, { PCI_DEVICE_ID_INTEL_SANDYBRIDGE_GT2_PLUS_IG, - "Sandybridge", &intel_fake_agp_driver, &sandybridge_gtt_driver }, + "Sandybridge", &sandybridge_gtt_driver }, { PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_GT1_IG, - "Sandybridge", &intel_fake_agp_driver, &sandybridge_gtt_driver }, + "Sandybridge", &sandybridge_gtt_driver }, { PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_GT2_IG, - "Sandybridge", &intel_fake_agp_driver, &sandybridge_gtt_driver }, + "Sandybridge", &sandybridge_gtt_driver }, { PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_GT2_PLUS_IG, - "Sandybridge", &intel_fake_agp_driver, &sandybridge_gtt_driver }, + "Sandybridge", &sandybridge_gtt_driver }, { PCI_DEVICE_ID_INTEL_SANDYBRIDGE_S_IG, - "Sandybridge", &intel_fake_agp_driver, &sandybridge_gtt_driver }, + "Sandybridge", &sandybridge_gtt_driver }, { 0, NULL, NULL } }; @@ -1463,21 +1436,20 @@ int intel_gmch_probe(struct pci_dev *pdev, struct agp_bridge_data *bridge) { int i, mask; - bridge->driver = NULL; + intel_private.driver = NULL; for (i = 0; intel_gtt_chipsets[i].name != NULL; i++) { if (find_gmch(intel_gtt_chipsets[i].gmch_chip_id)) { - bridge->driver = - intel_gtt_chipsets[i].gmch_driver; intel_private.driver = intel_gtt_chipsets[i].gtt_driver; break; } } - if (!bridge->driver) + if (!intel_private.driver) return 0; + bridge->driver = &intel_fake_agp_driver; bridge->dev_private_data = &intel_private; bridge->dev = pdev; -- cgit v1.2.3 From 23ed992a5ebe6964ebe312b54142fbc5e8185cdc Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Fri, 5 Nov 2010 18:04:52 +0100 Subject: drm/i915|intel-gtt: consolidate intel-gtt.h headers ... and a few other defines. Signed-off-by: Daniel Vetter Signed-off-by: Chris Wilson --- drivers/char/agp/intel-gtt.c | 5 ----- drivers/gpu/drm/i915/i915_gem.c | 1 - include/drm/intel-gtt.h | 12 ++++++++++++ include/linux/intel-gtt.h | 20 -------------------- 4 files changed, 12 insertions(+), 26 deletions(-) delete mode 100644 include/linux/intel-gtt.h diff --git a/drivers/char/agp/intel-gtt.c b/drivers/char/agp/intel-gtt.c index 72267c801637..291ac5113576 100644 --- a/drivers/char/agp/intel-gtt.c +++ b/drivers/char/agp/intel-gtt.c @@ -24,7 +24,6 @@ #include #include "agp.h" #include "intel-agp.h" -#include #include /* @@ -39,10 +38,6 @@ #define USE_PCI_DMA_API 0 #endif -#define AGP_DCACHE_MEMORY 1 -#define AGP_PHYS_MEMORY 2 -#define INTEL_AGP_CACHED_MEMORY 3 - struct intel_gtt_driver { unsigned int gen : 8; unsigned int is_g33 : 1; diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index bf05ac414b1f..68492357658c 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -34,7 +34,6 @@ #include #include #include -#include struct change_domains { uint32_t invalidate_domains; diff --git a/include/drm/intel-gtt.h b/include/drm/intel-gtt.h index 020f8aab7e5b..9f91cbe35157 100644 --- a/include/drm/intel-gtt.h +++ b/include/drm/intel-gtt.h @@ -13,5 +13,17 @@ const struct intel_gtt { unsigned int gtt_mappable_entries; } *intel_gtt_get(void); + +/* Special gtt memory types */ +#define AGP_DCACHE_MEMORY 1 +#define AGP_PHYS_MEMORY 2 + +/* New caching attributes for gen6/sandybridge */ +#define AGP_USER_CACHED_MEMORY_LLC_MLC (AGP_USER_TYPES + 2) +#define AGP_USER_UNCACHED_MEMORY (AGP_USER_TYPES + 4) + +/* flag for GFDT type */ +#define AGP_USER_CACHED_MEMORY_GFDT (1 << 3) + #endif diff --git a/include/linux/intel-gtt.h b/include/linux/intel-gtt.h deleted file mode 100644 index 1d19ab2afa39..000000000000 --- a/include/linux/intel-gtt.h +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Common Intel AGPGART and GTT definitions. - */ -#ifndef _INTEL_GTT_H -#define _INTEL_GTT_H - -#include - -/* This is for Intel only GTT controls. - * - * Sandybridge: AGP_USER_CACHED_MEMORY default to LLC only - */ - -#define AGP_USER_CACHED_MEMORY_LLC_MLC (AGP_USER_TYPES + 2) -#define AGP_USER_UNCACHED_MEMORY (AGP_USER_TYPES + 4) - -/* flag for GFDT type */ -#define AGP_USER_CACHED_MEMORY_GFDT (1 << 3) - -#endif -- cgit v1.2.3 From 40ce6575102b23e432932b5ce41c44bf7cc5023b Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Fri, 5 Nov 2010 18:12:18 +0100 Subject: drm/i915/gtt: call chipset flush directly Signed-off-by: Daniel Vetter Signed-off-by: Chris Wilson --- drivers/char/agp/intel-gtt.c | 7 +++++++ drivers/gpu/drm/i915/i915_gem.c | 9 ++++----- include/drm/intel-gtt.h | 2 +- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/drivers/char/agp/intel-gtt.c b/drivers/char/agp/intel-gtt.c index 291ac5113576..8e2e208c925b 100644 --- a/drivers/char/agp/intel-gtt.c +++ b/drivers/char/agp/intel-gtt.c @@ -1476,6 +1476,13 @@ const struct intel_gtt *intel_gtt_get(void) } EXPORT_SYMBOL(intel_gtt_get); +void intel_gtt_chipset_flush(void) +{ + if (intel_private.driver->chipset_flush) + intel_private.driver->chipset_flush(); +} +EXPORT_SYMBOL(intel_gtt_chipset_flush); + void intel_gmch_remove(struct pci_dev *pdev) { if (intel_private.pcidev) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 68492357658c..b663d2da1db3 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -2192,7 +2192,7 @@ i915_gem_flush(struct drm_device *dev, drm_i915_private_t *dev_priv = dev->dev_private; if (flush_domains & I915_GEM_DOMAIN_CPU) - drm_agp_chipset_flush(dev); + intel_gtt_chipset_flush(); if ((flush_domains | invalidate_domains) & I915_GEM_GPU_DOMAINS) { if (flush_rings & RING_RENDER) @@ -2920,14 +2920,13 @@ i915_gem_object_flush_gtt_write_domain(struct drm_gem_object *obj) static void i915_gem_object_flush_cpu_write_domain(struct drm_gem_object *obj) { - struct drm_device *dev = obj->dev; uint32_t old_write_domain; if (obj->write_domain != I915_GEM_DOMAIN_CPU) return; i915_gem_clflush_object(obj); - drm_agp_chipset_flush(dev); + intel_gtt_chipset_flush(); old_write_domain = obj->write_domain; obj->write_domain = 0; @@ -5069,7 +5068,7 @@ void i915_gem_detach_phys_object(struct drm_device *dev, page_cache_release(page); } } - drm_agp_chipset_flush(dev); + intel_gtt_chipset_flush(); obj_priv->phys_obj->cur_obj = NULL; obj_priv->phys_obj = NULL; @@ -5161,7 +5160,7 @@ i915_gem_phys_pwrite(struct drm_device *dev, struct drm_gem_object *obj, return -EFAULT; } - drm_agp_chipset_flush(dev); + intel_gtt_chipset_flush(); return 0; } diff --git a/include/drm/intel-gtt.h b/include/drm/intel-gtt.h index 9f91cbe35157..c35817a11690 100644 --- a/include/drm/intel-gtt.h +++ b/include/drm/intel-gtt.h @@ -13,6 +13,7 @@ const struct intel_gtt { unsigned int gtt_mappable_entries; } *intel_gtt_get(void); +void intel_gtt_chipset_flush(void); /* Special gtt memory types */ #define AGP_DCACHE_MEMORY 1 @@ -26,4 +27,3 @@ const struct intel_gtt { #define AGP_USER_CACHED_MEMORY_GFDT (1 << 3) #endif - -- cgit v1.2.3 From 4af72e2865a23ac090884a421bd1a8b19e247a22 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Fri, 5 Nov 2010 18:13:43 +0100 Subject: drm: kill drm_agp_chipset_flush No longer used. Cc: Dave Airlie Signed-off-by: Daniel Vetter Signed-off-by: Chris Wilson --- drivers/gpu/drm/drm_agpsupport.c | 6 ------ include/drm/drmP.h | 1 - 2 files changed, 7 deletions(-) diff --git a/drivers/gpu/drm/drm_agpsupport.c b/drivers/gpu/drm/drm_agpsupport.c index 252fdb98b73a..0cb2ba50af53 100644 --- a/drivers/gpu/drm/drm_agpsupport.c +++ b/drivers/gpu/drm/drm_agpsupport.c @@ -466,10 +466,4 @@ drm_agp_bind_pages(struct drm_device *dev, } EXPORT_SYMBOL(drm_agp_bind_pages); -void drm_agp_chipset_flush(struct drm_device *dev) -{ - agp_flush_chipset(dev->agp->bridge); -} -EXPORT_SYMBOL(drm_agp_chipset_flush); - #endif /* __OS_HAS_AGP */ diff --git a/include/drm/drmP.h b/include/drm/drmP.h index d4bc0f5cab8f..628f76772d22 100644 --- a/include/drm/drmP.h +++ b/include/drm/drmP.h @@ -1319,7 +1319,6 @@ extern int drm_agp_unbind_ioctl(struct drm_device *dev, void *data, extern int drm_agp_bind(struct drm_device *dev, struct drm_agp_binding *request); extern int drm_agp_bind_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); -extern void drm_agp_chipset_flush(struct drm_device *dev); /* Stub support (drm_stub.h) */ extern int drm_setmaster_ioctl(struct drm_device *dev, void *data, -- cgit v1.2.3 From f050a8abbda0efcd597c6b1825e3b9ce4d613383 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Fri, 5 Nov 2010 18:40:56 +0100 Subject: agp: kill agp_flush_chipset and corresponding ioctl The intel drm calls the chipset functions now directly. Userspace never called the corresponding ioctl, hence it can be killed, too. Cc: Dave Airlie Signed-off-by: Daniel Vetter Signed-off-by: Chris Wilson --- drivers/char/agp/agp.h | 1 - drivers/char/agp/compat_ioctl.c | 1 - drivers/char/agp/compat_ioctl.h | 1 - drivers/char/agp/frontend.c | 8 -------- drivers/char/agp/generic.c | 7 ------- drivers/char/agp/intel-gtt.c | 6 ------ include/linux/agp_backend.h | 1 - 7 files changed, 25 deletions(-) diff --git a/drivers/char/agp/agp.h b/drivers/char/agp/agp.h index 5259065f3c79..3e67ddde9e16 100644 --- a/drivers/char/agp/agp.h +++ b/drivers/char/agp/agp.h @@ -120,7 +120,6 @@ struct agp_bridge_driver { void (*agp_destroy_page)(struct page *, int flags); void (*agp_destroy_pages)(struct agp_memory *); int (*agp_type_to_mask_type) (struct agp_bridge_data *, int); - void (*chipset_flush)(struct agp_bridge_data *); }; struct agp_bridge_data { diff --git a/drivers/char/agp/compat_ioctl.c b/drivers/char/agp/compat_ioctl.c index 9d2c97a69cdd..a48e05b31593 100644 --- a/drivers/char/agp/compat_ioctl.c +++ b/drivers/char/agp/compat_ioctl.c @@ -276,7 +276,6 @@ long compat_agp_ioctl(struct file *file, unsigned int cmd, unsigned long arg) break; case AGPIOC_CHIPSET_FLUSH32: - ret_val = agpioc_chipset_flush_wrap(curr_priv); break; } diff --git a/drivers/char/agp/compat_ioctl.h b/drivers/char/agp/compat_ioctl.h index 0c9678ac0371..f30e0fd97963 100644 --- a/drivers/char/agp/compat_ioctl.h +++ b/drivers/char/agp/compat_ioctl.h @@ -102,6 +102,5 @@ void agp_free_memory_wrap(struct agp_memory *memory); struct agp_memory *agp_allocate_memory_wrap(size_t pg_count, u32 type); struct agp_memory *agp_find_mem_by_key(int key); struct agp_client *agp_find_client_by_pid(pid_t id); -int agpioc_chipset_flush_wrap(struct agp_file_private *priv); #endif /* _AGP_COMPAT_H */ diff --git a/drivers/char/agp/frontend.c b/drivers/char/agp/frontend.c index 3cb4539a98b2..2e044338753c 100644 --- a/drivers/char/agp/frontend.c +++ b/drivers/char/agp/frontend.c @@ -957,13 +957,6 @@ static int agpioc_unbind_wrap(struct agp_file_private *priv, void __user *arg) return agp_unbind_memory(memory); } -int agpioc_chipset_flush_wrap(struct agp_file_private *priv) -{ - DBG(""); - agp_flush_chipset(agp_bridge); - return 0; -} - static long agp_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { @@ -1039,7 +1032,6 @@ static long agp_ioctl(struct file *file, break; case AGPIOC_CHIPSET_FLUSH: - ret_val = agpioc_chipset_flush_wrap(curr_priv); break; } diff --git a/drivers/char/agp/generic.c b/drivers/char/agp/generic.c index 4956f1c8f9d5..78bc8de0f234 100644 --- a/drivers/char/agp/generic.c +++ b/drivers/char/agp/generic.c @@ -81,13 +81,6 @@ static int agp_get_key(void) return -1; } -void agp_flush_chipset(struct agp_bridge_data *bridge) -{ - if (bridge->driver->chipset_flush) - bridge->driver->chipset_flush(bridge); -} -EXPORT_SYMBOL(agp_flush_chipset); - /* * Use kmalloc if possible for the page list. Otherwise fall back to * vmalloc. This speeds things up and also saves memory for small AGP diff --git a/drivers/char/agp/intel-gtt.c b/drivers/char/agp/intel-gtt.c index 8e2e208c925b..1603e4f8ae73 100644 --- a/drivers/char/agp/intel-gtt.c +++ b/drivers/char/agp/intel-gtt.c @@ -984,11 +984,6 @@ static int intel_fake_agp_remove_entries(struct agp_memory *mem, return 0; } -static void intel_fake_agp_chipset_flush(struct agp_bridge_data *bridge) -{ - intel_private.driver->chipset_flush(); -} - static struct agp_memory *intel_fake_agp_alloc_by_type(size_t pg_count, int type) { @@ -1222,7 +1217,6 @@ static const struct agp_bridge_driver intel_fake_agp_driver = { .agp_alloc_pages = agp_generic_alloc_pages, .agp_destroy_page = agp_generic_destroy_page, .agp_destroy_pages = agp_generic_destroy_pages, - .chipset_flush = intel_fake_agp_chipset_flush, }; static const struct intel_gtt_driver i81x_gtt_driver = { diff --git a/include/linux/agp_backend.h b/include/linux/agp_backend.h index 09ea4a1e9505..a479b4885d25 100644 --- a/include/linux/agp_backend.h +++ b/include/linux/agp_backend.h @@ -106,6 +106,5 @@ extern int agp_rebind_memory(void); extern void agp_enable(struct agp_bridge_data *, u32); extern struct agp_bridge_data *agp_backend_acquire(struct pci_dev *); extern void agp_backend_release(struct agp_bridge_data *); -extern void agp_flush_chipset(struct agp_bridge_data *); #endif /* _AGP_BACKEND_H */ -- cgit v1.2.3 From 93a37f20eabeea4039130527b07453038c07f471 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Fri, 5 Nov 2010 20:24:53 +0100 Subject: drm/i915: track objects in the gtt This is required to restore gtt mappings on resume when agp is gone. The right way to do this would be to make sturct drm_mm_node embeddable and use the allocation list maintained by the drm memory manager. But that's a bigger project. Getting rid of the per bo agp_mem will save more memory than this wastes, anyway. Signed-off-by: Daniel Vetter Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_drv.h | 4 ++++ drivers/gpu/drm/i915/i915_gem.c | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index b62ff5d6fa7e..67ec046aeb90 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -547,6 +547,9 @@ typedef struct drm_i915_private { struct drm_mm stolen; /** Memory allocator for GTT */ struct drm_mm gtt_space; + /** List of all objects in gtt_space. Used to restore gtt + * mappings on resume */ + struct list_head gtt_list; /** End of mappable part of GTT */ unsigned long gtt_mappable_end; @@ -714,6 +717,7 @@ struct drm_i915_gem_object { /** Current space allocated to this object in the GTT, if any. */ struct drm_mm_node *gtt_space; + struct list_head gtt_list; /** This object's place on the active/flushing/inactive lists */ struct list_head ring_list; diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index b663d2da1db3..07e1b25f4a8a 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -95,6 +95,7 @@ static void i915_gem_info_add_gtt(struct drm_i915_private *dev_priv, min_t(size_t, obj->gtt_space->size, dev_priv->mm.gtt_mappable_end - obj->gtt_offset); } + list_add_tail(&obj->gtt_list, &dev_priv->mm.gtt_list); } static void i915_gem_info_remove_gtt(struct drm_i915_private *dev_priv, @@ -107,6 +108,7 @@ static void i915_gem_info_remove_gtt(struct drm_i915_private *dev_priv, min_t(size_t, obj->gtt_space->size, dev_priv->mm.gtt_mappable_end - obj->gtt_offset); } + list_del_init(&obj->gtt_list); } /** @@ -4604,6 +4606,7 @@ struct drm_gem_object * i915_gem_alloc_object(struct drm_device *dev, obj->base.driver_private = NULL; obj->fence_reg = I915_FENCE_REG_NONE; INIT_LIST_HEAD(&obj->mm_list); + INIT_LIST_HEAD(&obj->gtt_list); INIT_LIST_HEAD(&obj->ring_list); INIT_LIST_HEAD(&obj->gpu_write_list); obj->madv = I915_MADV_WILLNEED; @@ -4916,6 +4919,7 @@ i915_gem_load(struct drm_device *dev) INIT_LIST_HEAD(&dev_priv->mm.pinned_list); INIT_LIST_HEAD(&dev_priv->mm.fence_list); INIT_LIST_HEAD(&dev_priv->mm.deferred_free_list); + INIT_LIST_HEAD(&dev_priv->mm.gtt_list); init_ring_lists(&dev_priv->render_ring); init_ring_lists(&dev_priv->bsd_ring); init_ring_lists(&dev_priv->blt_ring); -- cgit v1.2.3 From 76aaf22016caa7764f40e792aaca7b4918312b22 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Fri, 5 Nov 2010 22:23:30 +0100 Subject: drm/i915: restore gtt on resume in the drm instead of in intel-gtt.ko This still uses the agp functions to actually reinstate the mappings (with a gross hack to make agp cooperate), but it wires everything up correctly for the switchover. The call to agp_rebind_memory can be dropped because all non-kms drivers do all their rebinding on EnterVT. v2: Be more paranoid and flush the chipset cache after restoring gtt mappings. Signed-off-by: Daniel Vetter Signed-off-by: Chris Wilson --- drivers/char/agp/intel-agp.c | 5 ---- drivers/gpu/drm/i915/Makefile | 1 + drivers/gpu/drm/i915/i915_drv.c | 1 + drivers/gpu/drm/i915/i915_drv.h | 3 +++ drivers/gpu/drm/i915/i915_gem_gtt.c | 49 +++++++++++++++++++++++++++++++++++++ 5 files changed, 54 insertions(+), 5 deletions(-) create mode 100644 drivers/gpu/drm/i915/i915_gem_gtt.c diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c index e72f49d52202..07e9796fead7 100644 --- a/drivers/char/agp/intel-agp.c +++ b/drivers/char/agp/intel-agp.c @@ -828,14 +828,9 @@ static void __devexit agp_intel_remove(struct pci_dev *pdev) static int agp_intel_resume(struct pci_dev *pdev) { struct agp_bridge_data *bridge = pci_get_drvdata(pdev); - int ret_val; bridge->driver->configure(); - ret_val = agp_rebind_memory(); - if (ret_val != 0) - return ret_val; - return 0; } #endif diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index fdc833d5cc7b..b3cdb4fe46e0 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile @@ -8,6 +8,7 @@ i915-y := i915_drv.o i915_dma.o i915_irq.o i915_mem.o \ i915_suspend.o \ i915_gem.o \ i915_gem_debug.o \ + i915_gem_gtt.o \ i915_gem_evict.o \ i915_gem_tiling.o \ i915_trace_points.o \ diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 8c5541950b8d..1a15b7886b8c 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -310,6 +310,7 @@ static int i915_drm_thaw(struct drm_device *dev) /* KMS EnterVT equivalent */ if (drm_core_check_feature(dev, DRIVER_MODESET)) { mutex_lock(&dev->struct_mutex); + i915_gem_restore_gtt_mappings(dev); dev_priv->mm.suspended = 0; error = i915_gem_init_ringbuffer(dev); diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 67ec046aeb90..b6b5d08c9956 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1141,6 +1141,9 @@ void i915_gem_detach_phys_object(struct drm_device *dev, void i915_gem_free_all_phys_object(struct drm_device *dev); void i915_gem_release(struct drm_device * dev, struct drm_file *file_priv); +/* i915_gem_gtt.c */ +void i915_gem_restore_gtt_mappings(struct drm_device *dev); + /* i915_gem_evict.c */ int i915_gem_evict_something(struct drm_device *dev, int min_size, unsigned alignment, bool mappable); diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c new file mode 100644 index 000000000000..5f21d0a962c4 --- /dev/null +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -0,0 +1,49 @@ +/* + * Copyright © 2010 Daniel Vetter + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + * + */ + +#include "drmP.h" +#include "drm.h" +#include "i915_drm.h" +#include "i915_drv.h" +#include "i915_trace.h" +#include "intel_drv.h" + +void i915_gem_restore_gtt_mappings(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_gem_object *obj_priv; + int ret; + + list_for_each_entry(obj_priv, + &dev_priv->mm.gtt_list, + gtt_list) { + /* Hack to force agp to reinsert buffer object. */ + obj_priv->agp_mem->is_bound = false; + ret = agp_bind_memory(obj_priv->agp_mem, obj_priv->gtt_space->start / PAGE_SIZE); + BUG_ON(ret != 0); + } + + /* Be paranoid and flush the chipset cache. */ + intel_gtt_chipset_flush(); +} -- cgit v1.2.3 From cb16b67b5cb33b7d6732e0c416d29d933eea13ce Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Fri, 5 Nov 2010 22:27:10 +0100 Subject: agp: kill agp_rebind_memory Its only user, intel-gtt.c is now gone. Cc: Dave Airlie Signed-off-by: Daniel Vetter Signed-off-by: Chris Wilson --- drivers/char/agp/generic.c | 20 -------------------- include/linux/agp_backend.h | 1 - 2 files changed, 21 deletions(-) diff --git a/drivers/char/agp/generic.c b/drivers/char/agp/generic.c index 78bc8de0f234..012cba0d6d96 100644 --- a/drivers/char/agp/generic.c +++ b/drivers/char/agp/generic.c @@ -480,26 +480,6 @@ int agp_unbind_memory(struct agp_memory *curr) } EXPORT_SYMBOL(agp_unbind_memory); -/** - * agp_rebind_emmory - Rewrite the entire GATT, useful on resume - */ -int agp_rebind_memory(void) -{ - struct agp_memory *curr; - int ret_val = 0; - - spin_lock(&agp_bridge->mapped_lock); - list_for_each_entry(curr, &agp_bridge->mapped_list, mapped_list) { - ret_val = curr->bridge->driver->insert_memory(curr, - curr->pg_start, - curr->type); - if (ret_val != 0) - break; - } - spin_unlock(&agp_bridge->mapped_lock); - return ret_val; -} -EXPORT_SYMBOL(agp_rebind_memory); /* End - Routines for handling swapping of agp_memory into the GATT */ diff --git a/include/linux/agp_backend.h b/include/linux/agp_backend.h index a479b4885d25..eaf6cd75a1b1 100644 --- a/include/linux/agp_backend.h +++ b/include/linux/agp_backend.h @@ -102,7 +102,6 @@ extern struct agp_memory *agp_allocate_memory(struct agp_bridge_data *, size_t, extern int agp_copy_info(struct agp_bridge_data *, struct agp_kern_info *); extern int agp_bind_memory(struct agp_memory *, off_t); extern int agp_unbind_memory(struct agp_memory *); -extern int agp_rebind_memory(void); extern void agp_enable(struct agp_bridge_data *, u32); extern struct agp_bridge_data *agp_backend_acquire(struct pci_dev *); extern void agp_backend_release(struct agp_bridge_data *); -- cgit v1.2.3 From 7c2e6fdf452cddeff6a8ee5156edba39e53246fc Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Sat, 6 Nov 2010 10:10:47 +0100 Subject: drm/i915: move gtt handling to i915_gem_gtt.c No more drm_*_agp in i915_gem.c! Signed-off-by: Daniel Vetter Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_drv.h | 2 ++ drivers/gpu/drm/i915/i915_gem.c | 14 +++----------- drivers/gpu/drm/i915/i915_gem_gtt.c | 28 ++++++++++++++++++++++++++++ 3 files changed, 33 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index b6b5d08c9956..b3bfab93e14c 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1143,6 +1143,8 @@ void i915_gem_release(struct drm_device * dev, struct drm_file *file_priv); /* i915_gem_gtt.c */ void i915_gem_restore_gtt_mappings(struct drm_device *dev); +int i915_gem_gtt_bind_object(struct drm_gem_object *obj); +void i915_gem_gtt_unbind_object(struct drm_gem_object *obj); /* i915_gem_evict.c */ int i915_gem_evict_something(struct drm_device *dev, int min_size, diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 07e1b25f4a8a..3cac366b3053 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -2288,8 +2288,7 @@ i915_gem_object_unbind(struct drm_gem_object *obj) if (obj_priv->fence_reg != I915_FENCE_REG_NONE) i915_gem_clear_fence_reg(obj); - drm_unbind_agp(obj_priv->agp_mem); - drm_free_agp(obj_priv->agp_mem, obj->size / PAGE_SIZE); + i915_gem_gtt_unbind_object(obj); i915_gem_object_put_pages_gtt(obj); @@ -2808,15 +2807,8 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, return ret; } - /* Create an AGP memory structure pointing at our pages, and bind it - * into the GTT. - */ - obj_priv->agp_mem = drm_agp_bind_pages(dev, - obj_priv->pages, - obj->size >> PAGE_SHIFT, - obj_priv->gtt_space->start, - obj_priv->agp_type); - if (obj_priv->agp_mem == NULL) { + ret = i915_gem_gtt_bind_object(obj); + if (ret) { i915_gem_object_put_pages_gtt(obj); drm_mm_put_block(obj_priv->gtt_space); obj_priv->gtt_space = NULL; diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index 5f21d0a962c4..f78c15f9e7f2 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -47,3 +47,31 @@ void i915_gem_restore_gtt_mappings(struct drm_device *dev) /* Be paranoid and flush the chipset cache. */ intel_gtt_chipset_flush(); } + +int i915_gem_gtt_bind_object(struct drm_gem_object *obj) +{ + struct drm_device *dev = obj->dev; + struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); + + /* Create an AGP memory structure pointing at our pages, and bind it + * into the GTT. + */ + obj_priv->agp_mem = drm_agp_bind_pages(dev, + obj_priv->pages, + obj->size >> PAGE_SHIFT, + obj_priv->gtt_space->start, + obj_priv->agp_type); + + if (obj_priv->agp_mem) + return 0; + else + return -ENOMEM; +} + +void i915_gem_gtt_unbind_object(struct drm_gem_object *obj) +{ + struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); + + drm_unbind_agp(obj_priv->agp_mem); + drm_free_agp(obj_priv->agp_mem, obj->size / PAGE_SIZE); +} -- cgit v1.2.3 From 4080775b60cc26044e7c4aba5e76e5041b0d7004 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Sat, 6 Nov 2010 11:18:58 +0100 Subject: intel-gtt: export api for drm/i915 Just some minor shuffling to get rid of any agp traces in the exported functions. Signed-off-by: Daniel Vetter Signed-off-by: Chris Wilson --- drivers/char/agp/intel-gtt.c | 120 ++++++++++++++++++++++++------------------- include/drm/intel-gtt.h | 12 +++++ 2 files changed, 80 insertions(+), 52 deletions(-) diff --git a/drivers/char/agp/intel-gtt.c b/drivers/char/agp/intel-gtt.c index 1603e4f8ae73..5a2b7360f5be 100644 --- a/drivers/char/agp/intel-gtt.c +++ b/drivers/char/agp/intel-gtt.c @@ -87,41 +87,29 @@ static struct _intel_private { #define IS_IRONLAKE intel_private.driver->is_ironlake #define HAS_PGTBL_EN intel_private.driver->has_pgtbl_enable -static void intel_agp_free_sglist(struct agp_memory *mem) -{ - struct sg_table st; - - st.sgl = mem->sg_list; - st.orig_nents = st.nents = mem->page_count; - - sg_free_table(&st); - - mem->sg_list = NULL; - mem->num_sg = 0; -} - -static int intel_agp_map_memory(struct agp_memory *mem) +int intel_gtt_map_memory(struct page **pages, unsigned int num_entries, + struct scatterlist **sg_list, int *num_sg) { struct sg_table st; struct scatterlist *sg; int i; - if (mem->sg_list) + if (*sg_list) return 0; /* already mapped (for e.g. resume */ - DBG("try mapping %lu pages\n", (unsigned long)mem->page_count); + DBG("try mapping %lu pages\n", (unsigned long)num_entries); - if (sg_alloc_table(&st, mem->page_count, GFP_KERNEL)) + if (sg_alloc_table(&st, num_entries, GFP_KERNEL)) goto err; - mem->sg_list = sg = st.sgl; + *sg_list = sg = st.sgl; - for (i = 0 ; i < mem->page_count; i++, sg = sg_next(sg)) - sg_set_page(sg, mem->pages[i], PAGE_SIZE, 0); + for (i = 0 ; i < num_entries; i++, sg = sg_next(sg)) + sg_set_page(sg, pages[i], PAGE_SIZE, 0); - mem->num_sg = pci_map_sg(intel_private.pcidev, mem->sg_list, - mem->page_count, PCI_DMA_BIDIRECTIONAL); - if (unlikely(!mem->num_sg)) + *num_sg = pci_map_sg(intel_private.pcidev, *sg_list, + num_entries, PCI_DMA_BIDIRECTIONAL); + if (unlikely(!*num_sg)) goto err; return 0; @@ -130,15 +118,22 @@ err: sg_free_table(&st); return -ENOMEM; } +EXPORT_SYMBOL(intel_gtt_map_memory); -static void intel_agp_unmap_memory(struct agp_memory *mem) +void intel_gtt_unmap_memory(struct scatterlist *sg_list, int num_sg) { + struct sg_table st; DBG("try unmapping %lu pages\n", (unsigned long)mem->page_count); - pci_unmap_sg(intel_private.pcidev, mem->sg_list, - mem->page_count, PCI_DMA_BIDIRECTIONAL); - intel_agp_free_sglist(mem); + pci_unmap_sg(intel_private.pcidev, sg_list, + num_sg, PCI_DMA_BIDIRECTIONAL); + + st.sgl = sg_list; + st.orig_nents = st.nents = num_sg; + + sg_free_table(&st); } +EXPORT_SYMBOL(intel_gtt_unmap_memory); static void intel_fake_agp_enable(struct agp_bridge_data *bridge, u32 mode) { @@ -307,7 +302,7 @@ static int intel_gtt_setup_scratch_page(void) get_page(page); set_pages_uc(page, 1); - if (USE_PCI_DMA_API && INTEL_GTT_GEN > 2) { + if (intel_private.base.needs_dmar) { dma_addr = pci_map_page(intel_private.pcidev, page, 0, PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); if (pci_dma_mapping_error(intel_private.pcidev, dma_addr)) @@ -699,6 +694,8 @@ static int intel_gtt_init(void) return ret; } + intel_private.base.needs_dmar = USE_PCI_DMA_API && INTEL_GTT_GEN > 2; + return 0; } @@ -892,10 +889,10 @@ static bool i830_check_flags(unsigned int flags) return false; } -static void intel_gtt_insert_sg_entries(struct scatterlist *sg_list, - unsigned int sg_len, - unsigned int pg_start, - unsigned int flags) +void intel_gtt_insert_sg_entries(struct scatterlist *sg_list, + unsigned int sg_len, + unsigned int pg_start, + unsigned int flags) { struct scatterlist *sg; unsigned int len, m; @@ -916,11 +913,25 @@ static void intel_gtt_insert_sg_entries(struct scatterlist *sg_list, } readl(intel_private.gtt+j-1); } +EXPORT_SYMBOL(intel_gtt_insert_sg_entries); + +void intel_gtt_insert_pages(unsigned int first_entry, unsigned int num_entries, + struct page **pages, unsigned int flags) +{ + int i, j; + + for (i = 0, j = first_entry; i < num_entries; i++, j++) { + dma_addr_t addr = page_to_phys(pages[i]); + intel_private.driver->write_entry(addr, + j, flags); + } + readl(intel_private.gtt+j-1); +} +EXPORT_SYMBOL(intel_gtt_insert_pages); static int intel_fake_agp_insert_entries(struct agp_memory *mem, off_t pg_start, int type) { - int i, j; int ret = -EINVAL; if (INTEL_GTT_GEN == 1 && type == AGP_DCACHE_MEMORY) @@ -941,21 +952,17 @@ static int intel_fake_agp_insert_entries(struct agp_memory *mem, if (!mem->is_flushed) global_cache_flush(); - if (USE_PCI_DMA_API && INTEL_GTT_GEN > 2) { - ret = intel_agp_map_memory(mem); + if (intel_private.base.needs_dmar) { + ret = intel_gtt_map_memory(mem->pages, mem->page_count, + &mem->sg_list, &mem->num_sg); if (ret != 0) return ret; intel_gtt_insert_sg_entries(mem->sg_list, mem->num_sg, pg_start, type); - } else { - for (i = 0, j = pg_start; i < mem->page_count; i++, j++) { - dma_addr_t addr = page_to_phys(mem->pages[i]); - intel_private.driver->write_entry(addr, - j, type); - } - readl(intel_private.gtt+j-1); - } + } else + intel_gtt_insert_pages(pg_start, mem->page_count, mem->pages, + type); out: ret = 0; @@ -964,22 +971,31 @@ out_err: return ret; } +void intel_gtt_clear_range(unsigned int first_entry, unsigned int num_entries) +{ + unsigned int i; + + for (i = first_entry; i < (first_entry + num_entries); i++) { + intel_private.driver->write_entry(intel_private.scratch_page_dma, + i, 0); + } + readl(intel_private.gtt+i-1); +} +EXPORT_SYMBOL(intel_gtt_clear_range); + static int intel_fake_agp_remove_entries(struct agp_memory *mem, off_t pg_start, int type) { - int i; - if (mem->page_count == 0) return 0; - if (USE_PCI_DMA_API && INTEL_GTT_GEN > 2) - intel_agp_unmap_memory(mem); - - for (i = pg_start; i < (mem->page_count + pg_start); i++) { - intel_private.driver->write_entry(intel_private.scratch_page_dma, - i, 0); + if (intel_private.base.needs_dmar) { + intel_gtt_unmap_memory(mem->sg_list, mem->num_sg); + mem->sg_list = NULL; + mem->num_sg = 0; } - readl(intel_private.gtt+i-1); + + intel_gtt_clear_range(pg_start, mem->page_count); return 0; } diff --git a/include/drm/intel-gtt.h b/include/drm/intel-gtt.h index c35817a11690..9e343c0998b4 100644 --- a/include/drm/intel-gtt.h +++ b/include/drm/intel-gtt.h @@ -11,9 +11,21 @@ const struct intel_gtt { /* Part of the gtt that is mappable by the cpu, for those chips where * this is not the full gtt. */ unsigned int gtt_mappable_entries; + /* Whether i915 needs to use the dmar apis or not. */ + unsigned int needs_dmar : 1; } *intel_gtt_get(void); void intel_gtt_chipset_flush(void); +void intel_gtt_unmap_memory(struct scatterlist *sg_list, int num_sg); +void intel_gtt_clear_range(unsigned int first_entry, unsigned int num_entries); +int intel_gtt_map_memory(struct page **pages, unsigned int num_entries, + struct scatterlist **sg_list, int *num_sg); +void intel_gtt_insert_sg_entries(struct scatterlist *sg_list, + unsigned int sg_len, + unsigned int pg_start, + unsigned int flags); +void intel_gtt_insert_pages(unsigned int first_entry, unsigned int num_entries, + struct page **pages, unsigned int flags); /* Special gtt memory types */ #define AGP_DCACHE_MEMORY 1 -- cgit v1.2.3 From 185cbcb304ba4dee55e39593fd86dcd7813f62ec Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Sat, 6 Nov 2010 12:12:35 +0100 Subject: drm/i915: no more agp for gem Signed-off-by: Daniel Vetter Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_drv.h | 9 ++++-- drivers/gpu/drm/i915/i915_gem_gtt.c | 63 ++++++++++++++++++++++++++----------- 2 files changed, 50 insertions(+), 22 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index b3bfab93e14c..dc371d987aa7 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -791,11 +791,14 @@ struct drm_i915_gem_object { unsigned int fault_mappable : 1; unsigned int pin_mappable : 1; - /** AGP memory structure for our GTT binding. */ - DRM_AGP_MEM *agp_mem; - struct page **pages; + /** + * DMAR support + */ + struct scatterlist *sg_list; + int num_sg; + /** * Current offset of the object in GTT space. * diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index f78c15f9e7f2..0b34a1aee9b6 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -33,15 +33,24 @@ void i915_gem_restore_gtt_mappings(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_gem_object *obj_priv; - int ret; list_for_each_entry(obj_priv, &dev_priv->mm.gtt_list, gtt_list) { - /* Hack to force agp to reinsert buffer object. */ - obj_priv->agp_mem->is_bound = false; - ret = agp_bind_memory(obj_priv->agp_mem, obj_priv->gtt_space->start / PAGE_SIZE); - BUG_ON(ret != 0); + if (dev_priv->mm.gtt->needs_dmar) { + BUG_ON(!obj_priv->sg_list); + + intel_gtt_insert_sg_entries(obj_priv->sg_list, + obj_priv->num_sg, + obj_priv->gtt_space->start + >> PAGE_SHIFT, + obj_priv->agp_type); + } else + intel_gtt_insert_pages(obj_priv->gtt_space->start + >> PAGE_SHIFT, + obj_priv->base.size >> PAGE_SHIFT, + obj_priv->pages, + obj_priv->agp_type); } /* Be paranoid and flush the chipset cache. */ @@ -51,27 +60,43 @@ void i915_gem_restore_gtt_mappings(struct drm_device *dev) int i915_gem_gtt_bind_object(struct drm_gem_object *obj) { struct drm_device *dev = obj->dev; + struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); + int ret; - /* Create an AGP memory structure pointing at our pages, and bind it - * into the GTT. - */ - obj_priv->agp_mem = drm_agp_bind_pages(dev, - obj_priv->pages, - obj->size >> PAGE_SHIFT, - obj_priv->gtt_space->start, - obj_priv->agp_type); + if (dev_priv->mm.gtt->needs_dmar) { + ret = intel_gtt_map_memory(obj_priv->pages, + obj->size >> PAGE_SHIFT, + &obj_priv->sg_list, + &obj_priv->num_sg); + if (ret != 0) + return ret; + + intel_gtt_insert_sg_entries(obj_priv->sg_list, obj_priv->num_sg, + obj_priv->gtt_space->start + >> PAGE_SHIFT, + obj_priv->agp_type); + } else + intel_gtt_insert_pages(obj_priv->gtt_space->start >> PAGE_SHIFT, + obj->size >> PAGE_SHIFT, + obj_priv->pages, + obj_priv->agp_type); - if (obj_priv->agp_mem) - return 0; - else - return -ENOMEM; + return 0; } void i915_gem_gtt_unbind_object(struct drm_gem_object *obj) { + struct drm_device *dev = obj->dev; + struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); - drm_unbind_agp(obj_priv->agp_mem); - drm_free_agp(obj_priv->agp_mem, obj->size / PAGE_SIZE); + if (dev_priv->mm.gtt->needs_dmar) { + intel_gtt_unmap_memory(obj_priv->sg_list, obj_priv->num_sg); + obj_priv->sg_list = NULL; + obj_priv->num_sg = 0; + } + + intel_gtt_clear_range(obj_priv->gtt_space->start >> PAGE_SHIFT, + obj->size >> PAGE_SHIFT); } -- cgit v1.2.3 From 05394f3975dceb107a5e1393e2244946e5b43660 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 8 Nov 2010 19:18:58 +0000 Subject: drm/i915: Use drm_i915_gem_object as the preferred type A glorified s/obj_priv/obj/ with a net reduction of over a 100 lines and many characters! Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_debugfs.c | 64 +- drivers/gpu/drm/i915/i915_dma.c | 2 +- drivers/gpu/drm/i915/i915_drv.h | 84 +- drivers/gpu/drm/i915/i915_gem.c | 1268 +++++++++++++++---------------- drivers/gpu/drm/i915/i915_gem_debug.c | 23 +- drivers/gpu/drm/i915/i915_gem_evict.c | 67 +- drivers/gpu/drm/i915/i915_gem_gtt.c | 68 +- drivers/gpu/drm/i915/i915_gem_tiling.c | 104 ++- drivers/gpu/drm/i915/i915_irq.c | 67 +- drivers/gpu/drm/i915/i915_trace.h | 41 +- drivers/gpu/drm/i915/intel_display.c | 242 +++--- drivers/gpu/drm/i915/intel_drv.h | 15 +- drivers/gpu/drm/i915/intel_fb.c | 25 +- drivers/gpu/drm/i915/intel_overlay.c | 48 +- drivers/gpu/drm/i915/intel_ringbuffer.c | 54 +- drivers/gpu/drm/i915/intel_ringbuffer.h | 4 +- 16 files changed, 1019 insertions(+), 1157 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 4fe49e0228ef..1e8cd74d18d5 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -87,19 +87,19 @@ static int i915_capabilities(struct seq_file *m, void *data) return 0; } -static const char *get_pin_flag(struct drm_i915_gem_object *obj_priv) +static const char *get_pin_flag(struct drm_i915_gem_object *obj) { - if (obj_priv->user_pin_count > 0) + if (obj->user_pin_count > 0) return "P"; - else if (obj_priv->pin_count > 0) + else if (obj->pin_count > 0) return "p"; else return " "; } -static const char *get_tiling_flag(struct drm_i915_gem_object *obj_priv) +static const char *get_tiling_flag(struct drm_i915_gem_object *obj) { - switch (obj_priv->tiling_mode) { + switch (obj->tiling_mode) { default: case I915_TILING_NONE: return " "; case I915_TILING_X: return "X"; @@ -140,7 +140,7 @@ static int i915_gem_object_list_info(struct seq_file *m, void *data) struct list_head *head; struct drm_device *dev = node->minor->dev; drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_i915_gem_object *obj_priv; + struct drm_i915_gem_object *obj; size_t total_obj_size, total_gtt_size; int count, ret; @@ -175,12 +175,12 @@ static int i915_gem_object_list_info(struct seq_file *m, void *data) } total_obj_size = total_gtt_size = count = 0; - list_for_each_entry(obj_priv, head, mm_list) { + list_for_each_entry(obj, head, mm_list) { seq_printf(m, " "); - describe_obj(m, obj_priv); + describe_obj(m, obj); seq_printf(m, "\n"); - total_obj_size += obj_priv->base.size; - total_gtt_size += obj_priv->gtt_space->size; + total_obj_size += obj->base.size; + total_gtt_size += obj->gtt_space->size; count++; } mutex_unlock(&dev->struct_mutex); @@ -251,14 +251,14 @@ static int i915_gem_pageflip_info(struct seq_file *m, void *data) seq_printf(m, "%d prepares\n", work->pending); if (work->old_fb_obj) { - struct drm_i915_gem_object *obj_priv = to_intel_bo(work->old_fb_obj); - if(obj_priv) - seq_printf(m, "Old framebuffer gtt_offset 0x%08x\n", obj_priv->gtt_offset ); + struct drm_i915_gem_object *obj = work->old_fb_obj; + if (obj) + seq_printf(m, "Old framebuffer gtt_offset 0x%08x\n", obj->gtt_offset); } if (work->pending_flip_obj) { - struct drm_i915_gem_object *obj_priv = to_intel_bo(work->pending_flip_obj); - if(obj_priv) - seq_printf(m, "New framebuffer gtt_offset 0x%08x\n", obj_priv->gtt_offset ); + struct drm_i915_gem_object *obj = work->pending_flip_obj; + if (obj) + seq_printf(m, "New framebuffer gtt_offset 0x%08x\n", obj->gtt_offset); } } spin_unlock_irqrestore(&dev->event_lock, flags); @@ -421,17 +421,17 @@ static int i915_gem_fence_regs_info(struct seq_file *m, void *data) seq_printf(m, "Reserved fences = %d\n", dev_priv->fence_reg_start); seq_printf(m, "Total fences = %d\n", dev_priv->num_fence_regs); for (i = 0; i < dev_priv->num_fence_regs; i++) { - struct drm_gem_object *obj = dev_priv->fence_regs[i].obj; + struct drm_i915_gem_object *obj = dev_priv->fence_regs[i].obj; seq_printf(m, "Fenced object[%2d] = ", i); if (obj == NULL) seq_printf(m, "unused"); else - describe_obj(m, to_intel_bo(obj)); + describe_obj(m, obj); seq_printf(m, "\n"); } - mutex_unlock(&dev->struct_mutex); + mutex_unlock(&dev->struct_mutex); return 0; } @@ -465,14 +465,14 @@ static int i915_hws_info(struct seq_file *m, void *data) static void i915_dump_object(struct seq_file *m, struct io_mapping *mapping, - struct drm_i915_gem_object *obj_priv) + struct drm_i915_gem_object *obj) { int page, page_count, i; - page_count = obj_priv->base.size / PAGE_SIZE; + page_count = obj->base.size / PAGE_SIZE; for (page = 0; page < page_count; page++) { u32 *mem = io_mapping_map_wc(mapping, - obj_priv->gtt_offset + page * PAGE_SIZE); + obj->gtt_offset + page * PAGE_SIZE); for (i = 0; i < PAGE_SIZE; i += 4) seq_printf(m, "%08x : %08x\n", i, mem[i / 4]); io_mapping_unmap(mem); @@ -484,25 +484,21 @@ static int i915_batchbuffer_info(struct seq_file *m, void *data) struct drm_info_node *node = (struct drm_info_node *) m->private; struct drm_device *dev = node->minor->dev; drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_gem_object *obj; - struct drm_i915_gem_object *obj_priv; + struct drm_i915_gem_object *obj; int ret; ret = mutex_lock_interruptible(&dev->struct_mutex); if (ret) return ret; - list_for_each_entry(obj_priv, &dev_priv->mm.active_list, mm_list) { - obj = &obj_priv->base; - if (obj->read_domains & I915_GEM_DOMAIN_COMMAND) { - seq_printf(m, "--- gtt_offset = 0x%08x\n", - obj_priv->gtt_offset); - i915_dump_object(m, dev_priv->mm.gtt_mapping, obj_priv); + list_for_each_entry(obj, &dev_priv->mm.active_list, mm_list) { + if (obj->base.read_domains & I915_GEM_DOMAIN_COMMAND) { + seq_printf(m, "--- gtt_offset = 0x%08x\n", obj->gtt_offset); + i915_dump_object(m, dev_priv->mm.gtt_mapping, obj); } } mutex_unlock(&dev->struct_mutex); - return 0; } @@ -525,7 +521,7 @@ static int i915_ringbuffer_data(struct seq_file *m, void *data) if (ret) return ret; - if (!ring->gem_object) { + if (!ring->obj) { seq_printf(m, "No ringbuffer setup\n"); } else { u8 *virt = ring->virtual_start; @@ -983,7 +979,7 @@ static int i915_gem_framebuffer_info(struct seq_file *m, void *data) fb->base.height, fb->base.depth, fb->base.bits_per_pixel); - describe_obj(m, to_intel_bo(fb->obj)); + describe_obj(m, fb->obj); seq_printf(m, "\n"); list_for_each_entry(fb, &dev->mode_config.fb_list, base.head) { @@ -995,7 +991,7 @@ static int i915_gem_framebuffer_info(struct seq_file *m, void *data) fb->base.height, fb->base.depth, fb->base.bits_per_pixel); - describe_obj(m, to_intel_bo(fb->obj)); + describe_obj(m, fb->obj); seq_printf(m, "\n"); } diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 7084de7c4c55..7960fd63ecb1 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -157,7 +157,7 @@ static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init) } if (init->ring_size != 0) { - if (dev_priv->render_ring.gem_object != NULL) { + if (dev_priv->render_ring.obj != NULL) { i915_dma_cleanup(dev); DRM_ERROR("Client tried to initialize ringbuffer in " "GEM mode\n"); diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index dc371d987aa7..22d6388b331f 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -32,7 +32,6 @@ #include "i915_reg.h" #include "intel_bios.h" -#include "i915_trace.h" #include "intel_ringbuffer.h" #include #include @@ -90,7 +89,7 @@ struct drm_i915_gem_phys_object { int id; struct page **page_list; drm_dma_handle_t *handle; - struct drm_gem_object *cur_obj; + struct drm_i915_gem_object *cur_obj; }; struct mem_block { @@ -125,7 +124,7 @@ struct drm_i915_master_private { #define I915_FENCE_REG_NONE -1 struct drm_i915_fence_reg { - struct drm_gem_object *obj; + struct drm_i915_gem_object *obj; struct list_head lru_list; bool gpu; }; @@ -280,9 +279,9 @@ typedef struct drm_i915_private { uint32_t counter; unsigned int seqno_gfx_addr; drm_local_map_t hws_map; - struct drm_gem_object *seqno_obj; - struct drm_gem_object *pwrctx; - struct drm_gem_object *renderctx; + struct drm_i915_gem_object *seqno_obj; + struct drm_i915_gem_object *pwrctx; + struct drm_i915_gem_object *renderctx; struct resource mch_res; @@ -690,14 +689,14 @@ typedef struct drm_i915_private { u8 fmax; u8 fstart; - u64 last_count1; - unsigned long last_time1; - u64 last_count2; - struct timespec last_time2; - unsigned long gfx_power; - int c_m; - int r_t; - u8 corr; + u64 last_count1; + unsigned long last_time1; + u64 last_count2; + struct timespec last_time2; + unsigned long gfx_power; + int c_m; + int r_t; + u8 corr; spinlock_t *mchdev_lock; enum no_fbc_reason no_fbc_reason; @@ -711,7 +710,6 @@ typedef struct drm_i915_private { struct intel_fbdev *fbdev; } drm_i915_private_t; -/** driver private structure attached to each drm_gem_object */ struct drm_i915_gem_object { struct drm_gem_object base; @@ -918,7 +916,7 @@ enum intel_chip_family { #define HAS_BLT(dev) (INTEL_INFO(dev)->has_blt_ring) #define I915_NEED_GFX_HWS(dev) (INTEL_INFO(dev)->need_gfx_hws) -#define HAS_OVERLAY(dev) (INTEL_INFO(dev)->has_overlay) +#define HAS_OVERLAY(dev) (INTEL_INFO(dev)->has_overlay) #define OVERLAY_NEEDS_PHYSICAL(dev) (INTEL_INFO(dev)->overlay_needs_physical) /* With the 945 and later, Y tiling got adjusted so that it was 32 128-byte @@ -947,6 +945,8 @@ enum intel_chip_family { #define HAS_PCH_CPT(dev) (INTEL_PCH_TYPE(dev) == PCH_CPT) #define HAS_PCH_IBX(dev) (INTEL_PCH_TYPE(dev) == PCH_IBX) +#include "i915_trace.h" + extern struct drm_ioctl_desc i915_ioctls[]; extern int i915_max_ioctl; extern unsigned int i915_fbpercrtc; @@ -1085,14 +1085,15 @@ int i915_gem_get_aperture_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); void i915_gem_load(struct drm_device *dev); int i915_gem_init_object(struct drm_gem_object *obj); -struct drm_gem_object * i915_gem_alloc_object(struct drm_device *dev, - size_t size); +struct drm_i915_gem_object *i915_gem_alloc_object(struct drm_device *dev, + size_t size); void i915_gem_free_object(struct drm_gem_object *obj); -int i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment, +int i915_gem_object_pin(struct drm_i915_gem_object *obj, + uint32_t alignment, bool map_and_fenceable); -void i915_gem_object_unpin(struct drm_gem_object *obj); -int i915_gem_object_unbind(struct drm_gem_object *obj); -void i915_gem_release_mmap(struct drm_gem_object *obj); +void i915_gem_object_unpin(struct drm_i915_gem_object *obj); +int i915_gem_object_unbind(struct drm_i915_gem_object *obj); +void i915_gem_release_mmap(struct drm_i915_gem_object *obj); void i915_gem_lastclose(struct drm_device *dev); /** @@ -1104,14 +1105,14 @@ i915_seqno_passed(uint32_t seq1, uint32_t seq2) return (int32_t)(seq1 - seq2) >= 0; } -int i915_gem_object_get_fence_reg(struct drm_gem_object *obj, +int i915_gem_object_get_fence_reg(struct drm_i915_gem_object *obj, bool interruptible); -int i915_gem_object_put_fence_reg(struct drm_gem_object *obj, +int i915_gem_object_put_fence_reg(struct drm_i915_gem_object *obj, bool interruptible); void i915_gem_retire_requests(struct drm_device *dev); void i915_gem_reset(struct drm_device *dev); -void i915_gem_clflush_object(struct drm_gem_object *obj); -int i915_gem_object_set_domain(struct drm_gem_object *obj, +void i915_gem_clflush_object(struct drm_i915_gem_object *obj); +int i915_gem_object_set_domain(struct drm_i915_gem_object *obj, uint32_t read_domains, uint32_t write_domain); int i915_gem_object_flush_gpu(struct drm_i915_gem_object *obj, @@ -1131,23 +1132,23 @@ int i915_do_wait_request(struct drm_device *dev, bool interruptible, struct intel_ring_buffer *ring); int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf); -int i915_gem_object_set_to_gtt_domain(struct drm_gem_object *obj, +int i915_gem_object_set_to_gtt_domain(struct drm_i915_gem_object *obj, int write); -int i915_gem_object_set_to_display_plane(struct drm_gem_object *obj, +int i915_gem_object_set_to_display_plane(struct drm_i915_gem_object *obj, bool pipelined); int i915_gem_attach_phys_object(struct drm_device *dev, - struct drm_gem_object *obj, + struct drm_i915_gem_object *obj, int id, int align); void i915_gem_detach_phys_object(struct drm_device *dev, - struct drm_gem_object *obj); + struct drm_i915_gem_object *obj); void i915_gem_free_all_phys_object(struct drm_device *dev); -void i915_gem_release(struct drm_device * dev, struct drm_file *file_priv); +void i915_gem_release(struct drm_device *dev, struct drm_file *file); /* i915_gem_gtt.c */ void i915_gem_restore_gtt_mappings(struct drm_device *dev); -int i915_gem_gtt_bind_object(struct drm_gem_object *obj); -void i915_gem_gtt_unbind_object(struct drm_gem_object *obj); +int i915_gem_gtt_bind_object(struct drm_i915_gem_object *obj); +void i915_gem_gtt_unbind_object(struct drm_i915_gem_object *obj); /* i915_gem_evict.c */ int i915_gem_evict_something(struct drm_device *dev, int min_size, @@ -1157,19 +1158,20 @@ int i915_gem_evict_inactive(struct drm_device *dev, bool purgeable_only); /* i915_gem_tiling.c */ void i915_gem_detect_bit_6_swizzle(struct drm_device *dev); -void i915_gem_object_do_bit_17_swizzle(struct drm_gem_object *obj); -void i915_gem_object_save_bit_17_swizzle(struct drm_gem_object *obj); +void i915_gem_object_do_bit_17_swizzle(struct drm_i915_gem_object *obj); +void i915_gem_object_save_bit_17_swizzle(struct drm_i915_gem_object *obj); /* i915_gem_debug.c */ -void i915_gem_dump_object(struct drm_gem_object *obj, int len, +void i915_gem_dump_object(struct drm_i915_gem_object *obj, int len, const char *where, uint32_t mark); #if WATCH_LISTS int i915_verify_lists(struct drm_device *dev); #else #define i915_verify_lists(dev) 0 #endif -void i915_gem_object_check_coherency(struct drm_gem_object *obj, int handle); -void i915_gem_dump_object(struct drm_gem_object *obj, int len, +void i915_gem_object_check_coherency(struct drm_i915_gem_object *obj, + int handle); +void i915_gem_dump_object(struct drm_i915_gem_object *obj, int len, const char *where, uint32_t mark); /* i915_debugfs.c */ @@ -1251,10 +1253,10 @@ extern void intel_display_print_error_state(struct seq_file *m, * In that case, we don't need to do it when GEM is initialized as nobody else * has access to the ring. */ -#define RING_LOCK_TEST_WITH_RETURN(dev, file_priv) do { \ - if (((drm_i915_private_t *)dev->dev_private)->render_ring.gem_object \ +#define RING_LOCK_TEST_WITH_RETURN(dev, file) do { \ + if (((drm_i915_private_t *)dev->dev_private)->render_ring.obj \ == NULL) \ - LOCK_TEST_WITH_RETURN(dev, file_priv); \ + LOCK_TEST_WITH_RETURN(dev, file); \ } while (0) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 3cac366b3053..d196895527a6 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -41,29 +41,30 @@ struct change_domains { uint32_t flush_rings; }; -static uint32_t i915_gem_get_gtt_alignment(struct drm_i915_gem_object *obj_priv); -static uint32_t i915_gem_get_gtt_size(struct drm_i915_gem_object *obj_priv); +static uint32_t i915_gem_get_gtt_alignment(struct drm_i915_gem_object *obj); +static uint32_t i915_gem_get_gtt_size(struct drm_i915_gem_object *obj); -static int i915_gem_object_flush_gpu_write_domain(struct drm_gem_object *obj, +static int i915_gem_object_flush_gpu_write_domain(struct drm_i915_gem_object *obj, bool pipelined); -static void i915_gem_object_flush_gtt_write_domain(struct drm_gem_object *obj); -static void i915_gem_object_flush_cpu_write_domain(struct drm_gem_object *obj); -static int i915_gem_object_set_to_cpu_domain(struct drm_gem_object *obj, +static void i915_gem_object_flush_gtt_write_domain(struct drm_i915_gem_object *obj); +static void i915_gem_object_flush_cpu_write_domain(struct drm_i915_gem_object *obj); +static int i915_gem_object_set_to_cpu_domain(struct drm_i915_gem_object *obj, int write); -static int i915_gem_object_set_cpu_read_domain_range(struct drm_gem_object *obj, +static int i915_gem_object_set_cpu_read_domain_range(struct drm_i915_gem_object *obj, uint64_t offset, uint64_t size); -static void i915_gem_object_set_to_full_cpu_read_domain(struct drm_gem_object *obj); -static int i915_gem_object_wait_rendering(struct drm_gem_object *obj, +static void i915_gem_object_set_to_full_cpu_read_domain(struct drm_i915_gem_object *obj); +static int i915_gem_object_wait_rendering(struct drm_i915_gem_object *obj, bool interruptible); -static int i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, +static int i915_gem_object_bind_to_gtt(struct drm_i915_gem_object *obj, unsigned alignment, bool map_and_fenceable); -static void i915_gem_clear_fence_reg(struct drm_gem_object *obj); -static int i915_gem_phys_pwrite(struct drm_device *dev, struct drm_gem_object *obj, +static void i915_gem_clear_fence_reg(struct drm_i915_gem_object *obj); +static int i915_gem_phys_pwrite(struct drm_device *dev, + struct drm_i915_gem_object *obj, struct drm_i915_gem_pwrite *args, - struct drm_file *file_priv); -static void i915_gem_free_object_tail(struct drm_gem_object *obj); + struct drm_file *file); +static void i915_gem_free_object_tail(struct drm_i915_gem_object *obj); static int i915_gem_inactive_shrink(struct shrinker *shrinker, int nr_to_scan, @@ -212,11 +213,9 @@ static int i915_mutex_lock_interruptible(struct drm_device *dev) } static inline bool -i915_gem_object_is_inactive(struct drm_i915_gem_object *obj_priv) +i915_gem_object_is_inactive(struct drm_i915_gem_object *obj) { - return obj_priv->gtt_space && - !obj_priv->active && - obj_priv->pin_count == 0; + return obj->gtt_space && !obj->active && obj->pin_count == 0; } int i915_gem_do_init(struct drm_device *dev, @@ -244,7 +243,7 @@ int i915_gem_do_init(struct drm_device *dev, int i915_gem_init_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) + struct drm_file *file) { struct drm_i915_gem_init *args = data; int ret; @@ -258,7 +257,7 @@ i915_gem_init_ioctl(struct drm_device *dev, void *data, int i915_gem_get_aperture_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) + struct drm_file *file) { struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_gem_get_aperture *args = data; @@ -280,10 +279,10 @@ i915_gem_get_aperture_ioctl(struct drm_device *dev, void *data, */ int i915_gem_create_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) + struct drm_file *file) { struct drm_i915_gem_create *args = data; - struct drm_gem_object *obj; + struct drm_i915_gem_object *obj; int ret; u32 handle; @@ -294,29 +293,28 @@ i915_gem_create_ioctl(struct drm_device *dev, void *data, if (obj == NULL) return -ENOMEM; - ret = drm_gem_handle_create(file_priv, obj, &handle); + ret = drm_gem_handle_create(file, &obj->base, &handle); if (ret) { - drm_gem_object_release(obj); - i915_gem_info_remove_obj(dev->dev_private, obj->size); + drm_gem_object_release(&obj->base); + i915_gem_info_remove_obj(dev->dev_private, obj->base.size); kfree(obj); return ret; } /* drop reference from allocate - handle holds it now */ - drm_gem_object_unreference(obj); + drm_gem_object_unreference(&obj->base); trace_i915_gem_object_create(obj); args->handle = handle; return 0; } -static int i915_gem_object_needs_bit17_swizzle(struct drm_gem_object *obj) +static int i915_gem_object_needs_bit17_swizzle(struct drm_i915_gem_object *obj) { - drm_i915_private_t *dev_priv = obj->dev->dev_private; - struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); + drm_i915_private_t *dev_priv = obj->base.dev->dev_private; return dev_priv->mm.bit_6_swizzle_x == I915_BIT_6_SWIZZLE_9_10_17 && - obj_priv->tiling_mode != I915_TILING_NONE; + obj->tiling_mode != I915_TILING_NONE; } static inline void @@ -392,12 +390,12 @@ slow_shmem_bit17_copy(struct page *gpu_page, * fault, it fails so we can fall back to i915_gem_shmem_pwrite_slow(). */ static int -i915_gem_shmem_pread_fast(struct drm_device *dev, struct drm_gem_object *obj, +i915_gem_shmem_pread_fast(struct drm_device *dev, + struct drm_i915_gem_object *obj, struct drm_i915_gem_pread *args, - struct drm_file *file_priv) + struct drm_file *file) { - struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); - struct address_space *mapping = obj->filp->f_path.dentry->d_inode->i_mapping; + struct address_space *mapping = obj->base.filp->f_path.dentry->d_inode->i_mapping; ssize_t remain; loff_t offset; char __user *user_data; @@ -406,7 +404,6 @@ i915_gem_shmem_pread_fast(struct drm_device *dev, struct drm_gem_object *obj, user_data = (char __user *) (uintptr_t) args->data_ptr; remain = args->size; - obj_priv = to_intel_bo(obj); offset = args->offset; while (remain > 0) { @@ -455,12 +452,12 @@ i915_gem_shmem_pread_fast(struct drm_device *dev, struct drm_gem_object *obj, * and not take page faults. */ static int -i915_gem_shmem_pread_slow(struct drm_device *dev, struct drm_gem_object *obj, +i915_gem_shmem_pread_slow(struct drm_device *dev, + struct drm_i915_gem_object *obj, struct drm_i915_gem_pread *args, - struct drm_file *file_priv) + struct drm_file *file) { - struct address_space *mapping = obj->filp->f_path.dentry->d_inode->i_mapping; - struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); + struct address_space *mapping = obj->base.filp->f_path.dentry->d_inode->i_mapping; struct mm_struct *mm = current->mm; struct page **user_pages; ssize_t remain; @@ -506,7 +503,6 @@ i915_gem_shmem_pread_slow(struct drm_device *dev, struct drm_gem_object *obj, do_bit17_swizzling = i915_gem_object_needs_bit17_swizzle(obj); - obj_priv = to_intel_bo(obj); offset = args->offset; while (remain > 0) { @@ -575,11 +571,10 @@ out: */ int i915_gem_pread_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) + struct drm_file *file) { struct drm_i915_gem_pread *args = data; - struct drm_gem_object *obj; - struct drm_i915_gem_object *obj_priv; + struct drm_i915_gem_object *obj; int ret = 0; if (args->size == 0) @@ -599,15 +594,15 @@ i915_gem_pread_ioctl(struct drm_device *dev, void *data, if (ret) return ret; - obj = drm_gem_object_lookup(dev, file_priv, args->handle); + obj = to_intel_bo(drm_gem_object_lookup(dev, file, args->handle)); if (obj == NULL) { ret = -ENOENT; goto unlock; } - obj_priv = to_intel_bo(obj); /* Bounds check source. */ - if (args->offset > obj->size || args->size > obj->size - args->offset) { + if (args->offset > obj->base.size || + args->size > obj->base.size - args->offset) { ret = -EINVAL; goto out; } @@ -620,12 +615,12 @@ i915_gem_pread_ioctl(struct drm_device *dev, void *data, ret = -EFAULT; if (!i915_gem_object_needs_bit17_swizzle(obj)) - ret = i915_gem_shmem_pread_fast(dev, obj, args, file_priv); + ret = i915_gem_shmem_pread_fast(dev, obj, args, file); if (ret == -EFAULT) - ret = i915_gem_shmem_pread_slow(dev, obj, args, file_priv); + ret = i915_gem_shmem_pread_slow(dev, obj, args, file); out: - drm_gem_object_unreference(obj); + drm_gem_object_unreference(&obj->base); unlock: mutex_unlock(&dev->struct_mutex); return ret; @@ -680,11 +675,11 @@ slow_kernel_write(struct io_mapping *mapping, * user into the GTT, uncached. */ static int -i915_gem_gtt_pwrite_fast(struct drm_device *dev, struct drm_gem_object *obj, +i915_gem_gtt_pwrite_fast(struct drm_device *dev, + struct drm_i915_gem_object *obj, struct drm_i915_gem_pwrite *args, - struct drm_file *file_priv) + struct drm_file *file) { - struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); drm_i915_private_t *dev_priv = dev->dev_private; ssize_t remain; loff_t offset, page_base; @@ -694,8 +689,7 @@ i915_gem_gtt_pwrite_fast(struct drm_device *dev, struct drm_gem_object *obj, user_data = (char __user *) (uintptr_t) args->data_ptr; remain = args->size; - obj_priv = to_intel_bo(obj); - offset = obj_priv->gtt_offset + args->offset; + offset = obj->gtt_offset + args->offset; while (remain > 0) { /* Operation in this page @@ -735,11 +729,11 @@ i915_gem_gtt_pwrite_fast(struct drm_device *dev, struct drm_gem_object *obj, * than using i915_gem_gtt_pwrite_fast on a G45 (32-bit). */ static int -i915_gem_gtt_pwrite_slow(struct drm_device *dev, struct drm_gem_object *obj, +i915_gem_gtt_pwrite_slow(struct drm_device *dev, + struct drm_i915_gem_object *obj, struct drm_i915_gem_pwrite *args, - struct drm_file *file_priv) + struct drm_file *file) { - struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); drm_i915_private_t *dev_priv = dev->dev_private; ssize_t remain; loff_t gtt_page_base, offset; @@ -780,8 +774,7 @@ i915_gem_gtt_pwrite_slow(struct drm_device *dev, struct drm_gem_object *obj, if (ret) goto out_unpin_pages; - obj_priv = to_intel_bo(obj); - offset = obj_priv->gtt_offset + args->offset; + offset = obj->gtt_offset + args->offset; while (remain > 0) { /* Operation in this page @@ -827,12 +820,12 @@ out_unpin_pages: * copy_from_user into the kmapped pages backing the object. */ static int -i915_gem_shmem_pwrite_fast(struct drm_device *dev, struct drm_gem_object *obj, +i915_gem_shmem_pwrite_fast(struct drm_device *dev, + struct drm_i915_gem_object *obj, struct drm_i915_gem_pwrite *args, - struct drm_file *file_priv) + struct drm_file *file) { - struct address_space *mapping = obj->filp->f_path.dentry->d_inode->i_mapping; - struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); + struct address_space *mapping = obj->base.filp->f_path.dentry->d_inode->i_mapping; ssize_t remain; loff_t offset; char __user *user_data; @@ -841,9 +834,8 @@ i915_gem_shmem_pwrite_fast(struct drm_device *dev, struct drm_gem_object *obj, user_data = (char __user *) (uintptr_t) args->data_ptr; remain = args->size; - obj_priv = to_intel_bo(obj); offset = args->offset; - obj_priv->dirty = 1; + obj->dirty = 1; while (remain > 0) { struct page *page; @@ -898,12 +890,12 @@ i915_gem_shmem_pwrite_fast(struct drm_device *dev, struct drm_gem_object *obj, * struct_mutex is held. */ static int -i915_gem_shmem_pwrite_slow(struct drm_device *dev, struct drm_gem_object *obj, +i915_gem_shmem_pwrite_slow(struct drm_device *dev, + struct drm_i915_gem_object *obj, struct drm_i915_gem_pwrite *args, - struct drm_file *file_priv) + struct drm_file *file) { - struct address_space *mapping = obj->filp->f_path.dentry->d_inode->i_mapping; - struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); + struct address_space *mapping = obj->base.filp->f_path.dentry->d_inode->i_mapping; struct mm_struct *mm = current->mm; struct page **user_pages; ssize_t remain; @@ -947,9 +939,8 @@ i915_gem_shmem_pwrite_slow(struct drm_device *dev, struct drm_gem_object *obj, do_bit17_swizzling = i915_gem_object_needs_bit17_swizzle(obj); - obj_priv = to_intel_bo(obj); offset = args->offset; - obj_priv->dirty = 1; + obj->dirty = 1; while (remain > 0) { struct page *page; @@ -1020,8 +1011,7 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data, struct drm_file *file) { struct drm_i915_gem_pwrite *args = data; - struct drm_gem_object *obj; - struct drm_i915_gem_object *obj_priv; + struct drm_i915_gem_object *obj; int ret; if (args->size == 0) @@ -1041,15 +1031,15 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data, if (ret) return ret; - obj = drm_gem_object_lookup(dev, file, args->handle); + obj = to_intel_bo(drm_gem_object_lookup(dev, file, args->handle)); if (obj == NULL) { ret = -ENOENT; goto unlock; } - obj_priv = to_intel_bo(obj); /* Bounds check destination. */ - if (args->offset > obj->size || args->size > obj->size - args->offset) { + if (args->offset > obj->base.size || + args->size > obj->base.size - args->offset) { ret = -EINVAL; goto out; } @@ -1060,11 +1050,11 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data, * pread/pwrite currently are reading and writing from the CPU * perspective, requiring manual detiling by the client. */ - if (obj_priv->phys_obj) + if (obj->phys_obj) ret = i915_gem_phys_pwrite(dev, obj, args, file); - else if (obj_priv->tiling_mode == I915_TILING_NONE && - obj_priv->gtt_space && - obj->write_domain != I915_GEM_DOMAIN_CPU) { + else if (obj->tiling_mode == I915_TILING_NONE && + obj->gtt_space && + obj->base.write_domain != I915_GEM_DOMAIN_CPU) { ret = i915_gem_object_pin(obj, 0, true); if (ret) goto out; @@ -1092,7 +1082,7 @@ out_unpin: } out: - drm_gem_object_unreference(obj); + drm_gem_object_unreference(&obj->base); unlock: mutex_unlock(&dev->struct_mutex); return ret; @@ -1104,12 +1094,11 @@ unlock: */ int i915_gem_set_domain_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) + struct drm_file *file) { struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_gem_set_domain *args = data; - struct drm_gem_object *obj; - struct drm_i915_gem_object *obj_priv; + struct drm_i915_gem_object *obj; uint32_t read_domains = args->read_domains; uint32_t write_domain = args->write_domain; int ret; @@ -1134,12 +1123,11 @@ i915_gem_set_domain_ioctl(struct drm_device *dev, void *data, if (ret) return ret; - obj = drm_gem_object_lookup(dev, file_priv, args->handle); + obj = to_intel_bo(drm_gem_object_lookup(dev, file, args->handle)); if (obj == NULL) { ret = -ENOENT; goto unlock; } - obj_priv = to_intel_bo(obj); intel_mark_busy(dev, obj); @@ -1149,9 +1137,9 @@ i915_gem_set_domain_ioctl(struct drm_device *dev, void *data, /* Update the LRU on the fence for the CPU access that's * about to occur. */ - if (obj_priv->fence_reg != I915_FENCE_REG_NONE) { + if (obj->fence_reg != I915_FENCE_REG_NONE) { struct drm_i915_fence_reg *reg = - &dev_priv->fence_regs[obj_priv->fence_reg]; + &dev_priv->fence_regs[obj->fence_reg]; list_move_tail(®->lru_list, &dev_priv->mm.fence_list); } @@ -1167,10 +1155,10 @@ i915_gem_set_domain_ioctl(struct drm_device *dev, void *data, } /* Maintain LRU order of "inactive" objects */ - if (ret == 0 && i915_gem_object_is_inactive(obj_priv)) - list_move_tail(&obj_priv->mm_list, &dev_priv->mm.inactive_list); + if (ret == 0 && i915_gem_object_is_inactive(obj)) + list_move_tail(&obj->mm_list, &dev_priv->mm.inactive_list); - drm_gem_object_unreference(obj); + drm_gem_object_unreference(&obj->base); unlock: mutex_unlock(&dev->struct_mutex); return ret; @@ -1181,10 +1169,10 @@ unlock: */ int i915_gem_sw_finish_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) + struct drm_file *file) { struct drm_i915_gem_sw_finish *args = data; - struct drm_gem_object *obj; + struct drm_i915_gem_object *obj; int ret = 0; if (!(dev->driver->driver_features & DRIVER_GEM)) @@ -1194,17 +1182,17 @@ i915_gem_sw_finish_ioctl(struct drm_device *dev, void *data, if (ret) return ret; - obj = drm_gem_object_lookup(dev, file_priv, args->handle); + obj = to_intel_bo(drm_gem_object_lookup(dev, file, args->handle)); if (obj == NULL) { ret = -ENOENT; goto unlock; } /* Pinned buffers may be scanout, so flush the cache */ - if (to_intel_bo(obj)->pin_count) + if (obj->pin_count) i915_gem_object_flush_cpu_write_domain(obj); - drm_gem_object_unreference(obj); + drm_gem_object_unreference(&obj->base); unlock: mutex_unlock(&dev->struct_mutex); return ret; @@ -1219,7 +1207,7 @@ unlock: */ int i915_gem_mmap_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) + struct drm_file *file) { struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_gem_mmap *args = data; @@ -1230,7 +1218,7 @@ i915_gem_mmap_ioctl(struct drm_device *dev, void *data, if (!(dev->driver->driver_features & DRIVER_GEM)) return -ENODEV; - obj = drm_gem_object_lookup(dev, file_priv, args->handle); + obj = drm_gem_object_lookup(dev, file, args->handle); if (obj == NULL) return -ENOENT; @@ -1273,10 +1261,9 @@ i915_gem_mmap_ioctl(struct drm_device *dev, void *data, */ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) { - struct drm_gem_object *obj = vma->vm_private_data; - struct drm_device *dev = obj->dev; + struct drm_i915_gem_object *obj = to_intel_bo(vma->vm_private_data); + struct drm_device *dev = obj->base.dev; drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); pgoff_t page_offset; unsigned long pfn; int ret = 0; @@ -1288,17 +1275,17 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) /* Now bind it into the GTT if needed */ mutex_lock(&dev->struct_mutex); - BUG_ON(obj_priv->pin_count && !obj_priv->pin_mappable); + BUG_ON(obj->pin_count && !obj->pin_mappable); - if (obj_priv->gtt_space) { - if (!obj_priv->map_and_fenceable) { + if (obj->gtt_space) { + if (!obj->map_and_fenceable) { ret = i915_gem_object_unbind(obj); if (ret) goto unlock; } } - if (!obj_priv->gtt_space) { + if (!obj->gtt_space) { ret = i915_gem_object_bind_to_gtt(obj, 0, true); if (ret) goto unlock; @@ -1308,22 +1295,22 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) if (ret) goto unlock; - if (!obj_priv->fault_mappable) { - obj_priv->fault_mappable = true; - i915_gem_info_update_mappable(dev_priv, obj_priv, true); + if (!obj->fault_mappable) { + obj->fault_mappable = true; + i915_gem_info_update_mappable(dev_priv, obj, true); } /* Need a new fence register? */ - if (obj_priv->tiling_mode != I915_TILING_NONE) { + if (obj->tiling_mode != I915_TILING_NONE) { ret = i915_gem_object_get_fence_reg(obj, true); if (ret) goto unlock; } - if (i915_gem_object_is_inactive(obj_priv)) - list_move_tail(&obj_priv->mm_list, &dev_priv->mm.inactive_list); + if (i915_gem_object_is_inactive(obj)) + list_move_tail(&obj->mm_list, &dev_priv->mm.inactive_list); - pfn = ((dev->agp->base + obj_priv->gtt_offset) >> PAGE_SHIFT) + + pfn = ((dev->agp->base + obj->gtt_offset) >> PAGE_SHIFT) + page_offset; /* Finally, remap it using the new GTT offset */ @@ -1356,36 +1343,39 @@ unlock: * This routine allocates and attaches a fake offset for @obj. */ static int -i915_gem_create_mmap_offset(struct drm_gem_object *obj) +i915_gem_create_mmap_offset(struct drm_i915_gem_object *obj) { - struct drm_device *dev = obj->dev; + struct drm_device *dev = obj->base.dev; struct drm_gem_mm *mm = dev->mm_private; struct drm_map_list *list; struct drm_local_map *map; int ret = 0; /* Set the object up for mmap'ing */ - list = &obj->map_list; + list = &obj->base.map_list; list->map = kzalloc(sizeof(struct drm_map_list), GFP_KERNEL); if (!list->map) return -ENOMEM; map = list->map; map->type = _DRM_GEM; - map->size = obj->size; + map->size = obj->base.size; map->handle = obj; /* Get a DRM GEM mmap offset allocated... */ list->file_offset_node = drm_mm_search_free(&mm->offset_manager, - obj->size / PAGE_SIZE, 0, 0); + obj->base.size / PAGE_SIZE, + 0, 0); if (!list->file_offset_node) { - DRM_ERROR("failed to allocate offset for bo %d\n", obj->name); + DRM_ERROR("failed to allocate offset for bo %d\n", + obj->base.name); ret = -ENOSPC; goto out_free_list; } list->file_offset_node = drm_mm_get_block(list->file_offset_node, - obj->size / PAGE_SIZE, 0); + obj->base.size / PAGE_SIZE, + 0); if (!list->file_offset_node) { ret = -ENOMEM; goto out_free_list; @@ -1424,29 +1414,28 @@ out_free_list: * fixup by i915_gem_fault(). */ void -i915_gem_release_mmap(struct drm_gem_object *obj) +i915_gem_release_mmap(struct drm_i915_gem_object *obj) { - struct drm_device *dev = obj->dev; + struct drm_device *dev = obj->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); - if (unlikely(obj->map_list.map && dev->dev_mapping)) + if (unlikely(obj->base.map_list.map && dev->dev_mapping)) unmap_mapping_range(dev->dev_mapping, - (loff_t)obj->map_list.hash.key<size, 1); + (loff_t)obj->base.map_list.hash.key<base.size, 1); - if (obj_priv->fault_mappable) { - obj_priv->fault_mappable = false; - i915_gem_info_update_mappable(dev_priv, obj_priv, false); + if (obj->fault_mappable) { + obj->fault_mappable = false; + i915_gem_info_update_mappable(dev_priv, obj, false); } } static void -i915_gem_free_mmap_offset(struct drm_gem_object *obj) +i915_gem_free_mmap_offset(struct drm_i915_gem_object *obj) { - struct drm_device *dev = obj->dev; + struct drm_device *dev = obj->base.dev; struct drm_gem_mm *mm = dev->mm_private; - struct drm_map_list *list = &obj->map_list; + struct drm_map_list *list = &obj->base.map_list; drm_ht_remove_item(&mm->offset_hash, &list->hash); drm_mm_put_block(list->file_offset_node); @@ -1462,23 +1451,23 @@ i915_gem_free_mmap_offset(struct drm_gem_object *obj) * potential fence register mapping. */ static uint32_t -i915_gem_get_gtt_alignment(struct drm_i915_gem_object *obj_priv) +i915_gem_get_gtt_alignment(struct drm_i915_gem_object *obj) { - struct drm_device *dev = obj_priv->base.dev; + struct drm_device *dev = obj->base.dev; /* * Minimum alignment is 4k (GTT page size), but might be greater * if a fence register is needed for the object. */ if (INTEL_INFO(dev)->gen >= 4 || - obj_priv->tiling_mode == I915_TILING_NONE) + obj->tiling_mode == I915_TILING_NONE) return 4096; /* * Previous chips need to be aligned to the size of the smallest * fence register that can contain the object. */ - return i915_gem_get_gtt_size(obj_priv); + return i915_gem_get_gtt_size(obj); } /** @@ -1490,16 +1479,16 @@ i915_gem_get_gtt_alignment(struct drm_i915_gem_object *obj_priv) * unfenced tiled surface requirements. */ static uint32_t -i915_gem_get_unfenced_gtt_alignment(struct drm_i915_gem_object *obj_priv) +i915_gem_get_unfenced_gtt_alignment(struct drm_i915_gem_object *obj) { - struct drm_device *dev = obj_priv->base.dev; + struct drm_device *dev = obj->base.dev; int tile_height; /* * Minimum alignment is 4k (GTT page size) for sane hw. */ if (INTEL_INFO(dev)->gen >= 4 || IS_G33(dev) || - obj_priv->tiling_mode == I915_TILING_NONE) + obj->tiling_mode == I915_TILING_NONE) return 4096; /* @@ -1508,18 +1497,18 @@ i915_gem_get_unfenced_gtt_alignment(struct drm_i915_gem_object *obj_priv) * placed in a fenced gtt region). */ if (IS_GEN2(dev) || - (obj_priv->tiling_mode == I915_TILING_Y && HAS_128_BYTE_Y_TILING(dev))) + (obj->tiling_mode == I915_TILING_Y && HAS_128_BYTE_Y_TILING(dev))) tile_height = 32; else tile_height = 8; - return tile_height * obj_priv->stride * 2; + return tile_height * obj->stride * 2; } static uint32_t -i915_gem_get_gtt_size(struct drm_i915_gem_object *obj_priv) +i915_gem_get_gtt_size(struct drm_i915_gem_object *obj) { - struct drm_device *dev = obj_priv->base.dev; + struct drm_device *dev = obj->base.dev; uint32_t size; /* @@ -1527,7 +1516,7 @@ i915_gem_get_gtt_size(struct drm_i915_gem_object *obj_priv) * if a fence register is needed for the object. */ if (INTEL_INFO(dev)->gen >= 4) - return obj_priv->base.size; + return obj->base.size; /* * Previous chips need to be aligned to the size of the smallest @@ -1538,7 +1527,7 @@ i915_gem_get_gtt_size(struct drm_i915_gem_object *obj_priv) else size = 512*1024; - while (size < obj_priv->base.size) + while (size < obj->base.size) size <<= 1; return size; @@ -1548,7 +1537,7 @@ i915_gem_get_gtt_size(struct drm_i915_gem_object *obj_priv) * i915_gem_mmap_gtt_ioctl - prepare an object for GTT mmap'ing * @dev: DRM device * @data: GTT mapping ioctl data - * @file_priv: GEM object info + * @file: GEM object info * * Simply returns the fake offset to userspace so it can mmap it. * The mmap call will end up in drm_gem_mmap(), which will set things @@ -1561,12 +1550,11 @@ i915_gem_get_gtt_size(struct drm_i915_gem_object *obj_priv) */ int i915_gem_mmap_gtt_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) + struct drm_file *file) { struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_gem_mmap_gtt *args = data; - struct drm_gem_object *obj; - struct drm_i915_gem_object *obj_priv; + struct drm_i915_gem_object *obj; int ret; if (!(dev->driver->driver_features & DRIVER_GEM)) @@ -1576,44 +1564,42 @@ i915_gem_mmap_gtt_ioctl(struct drm_device *dev, void *data, if (ret) return ret; - obj = drm_gem_object_lookup(dev, file_priv, args->handle); + obj = to_intel_bo(drm_gem_object_lookup(dev, file, args->handle)); if (obj == NULL) { ret = -ENOENT; goto unlock; } - obj_priv = to_intel_bo(obj); - if (obj->size > dev_priv->mm.gtt_mappable_end) { + if (obj->base.size > dev_priv->mm.gtt_mappable_end) { ret = -E2BIG; goto unlock; } - if (obj_priv->madv != I915_MADV_WILLNEED) { + if (obj->madv != I915_MADV_WILLNEED) { DRM_ERROR("Attempting to mmap a purgeable buffer\n"); ret = -EINVAL; goto out; } - if (!obj->map_list.map) { + if (!obj->base.map_list.map) { ret = i915_gem_create_mmap_offset(obj); if (ret) goto out; } - args->offset = (u64)obj->map_list.hash.key << PAGE_SHIFT; + args->offset = (u64)obj->base.map_list.hash.key << PAGE_SHIFT; out: - drm_gem_object_unreference(obj); + drm_gem_object_unreference(&obj->base); unlock: mutex_unlock(&dev->struct_mutex); return ret; } static int -i915_gem_object_get_pages_gtt(struct drm_gem_object *obj, +i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj, gfp_t gfpmask) { - struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); int page_count, i; struct address_space *mapping; struct inode *inode; @@ -1622,13 +1608,13 @@ i915_gem_object_get_pages_gtt(struct drm_gem_object *obj, /* Get the list of pages out of our struct file. They'll be pinned * at this point until we release them. */ - page_count = obj->size / PAGE_SIZE; - BUG_ON(obj_priv->pages != NULL); - obj_priv->pages = drm_malloc_ab(page_count, sizeof(struct page *)); - if (obj_priv->pages == NULL) + page_count = obj->base.size / PAGE_SIZE; + BUG_ON(obj->pages != NULL); + obj->pages = drm_malloc_ab(page_count, sizeof(struct page *)); + if (obj->pages == NULL) return -ENOMEM; - inode = obj->filp->f_path.dentry->d_inode; + inode = obj->base.filp->f_path.dentry->d_inode; mapping = inode->i_mapping; for (i = 0; i < page_count; i++) { page = read_cache_page_gfp(mapping, i, @@ -1639,51 +1625,50 @@ i915_gem_object_get_pages_gtt(struct drm_gem_object *obj, if (IS_ERR(page)) goto err_pages; - obj_priv->pages[i] = page; + obj->pages[i] = page; } - if (obj_priv->tiling_mode != I915_TILING_NONE) + if (obj->tiling_mode != I915_TILING_NONE) i915_gem_object_do_bit_17_swizzle(obj); return 0; err_pages: while (i--) - page_cache_release(obj_priv->pages[i]); + page_cache_release(obj->pages[i]); - drm_free_large(obj_priv->pages); - obj_priv->pages = NULL; + drm_free_large(obj->pages); + obj->pages = NULL; return PTR_ERR(page); } static void -i915_gem_object_put_pages_gtt(struct drm_gem_object *obj) +i915_gem_object_put_pages_gtt(struct drm_i915_gem_object *obj) { - struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); - int page_count = obj->size / PAGE_SIZE; + int page_count = obj->base.size / PAGE_SIZE; int i; - BUG_ON(obj_priv->madv == __I915_MADV_PURGED); + BUG_ON(obj->madv == __I915_MADV_PURGED); - if (obj_priv->tiling_mode != I915_TILING_NONE) + if (obj->tiling_mode != I915_TILING_NONE) i915_gem_object_save_bit_17_swizzle(obj); - if (obj_priv->madv == I915_MADV_DONTNEED) - obj_priv->dirty = 0; + if (obj->madv == I915_MADV_DONTNEED) + obj->dirty = 0; for (i = 0; i < page_count; i++) { - if (obj_priv->dirty) - set_page_dirty(obj_priv->pages[i]); + if (obj->dirty) + set_page_dirty(obj->pages[i]); - if (obj_priv->madv == I915_MADV_WILLNEED) - mark_page_accessed(obj_priv->pages[i]); + if (obj->madv == I915_MADV_WILLNEED) + mark_page_accessed(obj->pages[i]); - page_cache_release(obj_priv->pages[i]); + page_cache_release(obj->pages[i]); } - obj_priv->dirty = 0; + obj->dirty = 0; - drm_free_large(obj_priv->pages); - obj_priv->pages = NULL; + drm_free_large(obj->pages); + obj->pages = NULL; } static uint32_t @@ -1695,47 +1680,44 @@ i915_gem_next_request_seqno(struct drm_device *dev, } static void -i915_gem_object_move_to_active(struct drm_gem_object *obj, +i915_gem_object_move_to_active(struct drm_i915_gem_object *obj, struct intel_ring_buffer *ring) { - struct drm_device *dev = obj->dev; + struct drm_device *dev = obj->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); uint32_t seqno = i915_gem_next_request_seqno(dev, ring); BUG_ON(ring == NULL); - obj_priv->ring = ring; + obj->ring = ring; /* Add a reference if we're newly entering the active list. */ - if (!obj_priv->active) { - drm_gem_object_reference(obj); - obj_priv->active = 1; + if (!obj->active) { + drm_gem_object_reference(&obj->base); + obj->active = 1; } /* Move from whatever list we were on to the tail of execution. */ - list_move_tail(&obj_priv->mm_list, &dev_priv->mm.active_list); - list_move_tail(&obj_priv->ring_list, &ring->active_list); - obj_priv->last_rendering_seqno = seqno; + list_move_tail(&obj->mm_list, &dev_priv->mm.active_list); + list_move_tail(&obj->ring_list, &ring->active_list); + obj->last_rendering_seqno = seqno; } static void -i915_gem_object_move_to_flushing(struct drm_gem_object *obj) +i915_gem_object_move_to_flushing(struct drm_i915_gem_object *obj) { - struct drm_device *dev = obj->dev; + struct drm_device *dev = obj->base.dev; drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); - BUG_ON(!obj_priv->active); - list_move_tail(&obj_priv->mm_list, &dev_priv->mm.flushing_list); - list_del_init(&obj_priv->ring_list); - obj_priv->last_rendering_seqno = 0; + BUG_ON(!obj->active); + list_move_tail(&obj->mm_list, &dev_priv->mm.flushing_list); + list_del_init(&obj->ring_list); + obj->last_rendering_seqno = 0; } /* Immediately discard the backing storage */ static void -i915_gem_object_truncate(struct drm_gem_object *obj) +i915_gem_object_truncate(struct drm_i915_gem_object *obj) { - struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); struct inode *inode; /* Our goal here is to return as much of the memory as @@ -1744,40 +1726,39 @@ i915_gem_object_truncate(struct drm_gem_object *obj) * backing pages, *now*. Here we mirror the actions taken * when by shmem_delete_inode() to release the backing store. */ - inode = obj->filp->f_path.dentry->d_inode; + inode = obj->base.filp->f_path.dentry->d_inode; truncate_inode_pages(inode->i_mapping, 0); if (inode->i_op->truncate_range) inode->i_op->truncate_range(inode, 0, (loff_t)-1); - obj_priv->madv = __I915_MADV_PURGED; + obj->madv = __I915_MADV_PURGED; } static inline int -i915_gem_object_is_purgeable(struct drm_i915_gem_object *obj_priv) +i915_gem_object_is_purgeable(struct drm_i915_gem_object *obj) { - return obj_priv->madv == I915_MADV_DONTNEED; + return obj->madv == I915_MADV_DONTNEED; } static void -i915_gem_object_move_to_inactive(struct drm_gem_object *obj) +i915_gem_object_move_to_inactive(struct drm_i915_gem_object *obj) { - struct drm_device *dev = obj->dev; + struct drm_device *dev = obj->base.dev; drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); - if (obj_priv->pin_count != 0) - list_move_tail(&obj_priv->mm_list, &dev_priv->mm.pinned_list); + if (obj->pin_count != 0) + list_move_tail(&obj->mm_list, &dev_priv->mm.pinned_list); else - list_move_tail(&obj_priv->mm_list, &dev_priv->mm.inactive_list); - list_del_init(&obj_priv->ring_list); + list_move_tail(&obj->mm_list, &dev_priv->mm.inactive_list); + list_del_init(&obj->ring_list); - BUG_ON(!list_empty(&obj_priv->gpu_write_list)); + BUG_ON(!list_empty(&obj->gpu_write_list)); - obj_priv->last_rendering_seqno = 0; - obj_priv->ring = NULL; - if (obj_priv->active) { - obj_priv->active = 0; - drm_gem_object_unreference(obj); + obj->last_rendering_seqno = 0; + obj->ring = NULL; + if (obj->active) { + obj->active = 0; + drm_gem_object_unreference(&obj->base); } WARN_ON(i915_verify_lists(dev)); } @@ -1788,30 +1769,28 @@ i915_gem_process_flushing_list(struct drm_device *dev, struct intel_ring_buffer *ring) { drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_i915_gem_object *obj_priv, *next; + struct drm_i915_gem_object *obj, *next; - list_for_each_entry_safe(obj_priv, next, + list_for_each_entry_safe(obj, next, &ring->gpu_write_list, gpu_write_list) { - struct drm_gem_object *obj = &obj_priv->base; + if (obj->base.write_domain & flush_domains) { + uint32_t old_write_domain = obj->base.write_domain; - if (obj->write_domain & flush_domains) { - uint32_t old_write_domain = obj->write_domain; - - obj->write_domain = 0; - list_del_init(&obj_priv->gpu_write_list); + obj->base.write_domain = 0; + list_del_init(&obj->gpu_write_list); i915_gem_object_move_to_active(obj, ring); /* update the fence lru list */ - if (obj_priv->fence_reg != I915_FENCE_REG_NONE) { + if (obj->fence_reg != I915_FENCE_REG_NONE) { struct drm_i915_fence_reg *reg = - &dev_priv->fence_regs[obj_priv->fence_reg]; + &dev_priv->fence_regs[obj->fence_reg]; list_move_tail(®->lru_list, &dev_priv->mm.fence_list); } trace_i915_gem_object_change_domain(obj, - obj->read_domains, + obj->base.read_domains, old_write_domain); } } @@ -1912,22 +1891,22 @@ static void i915_gem_reset_ring_lists(struct drm_i915_private *dev_priv, } while (!list_empty(&ring->active_list)) { - struct drm_i915_gem_object *obj_priv; + struct drm_i915_gem_object *obj; - obj_priv = list_first_entry(&ring->active_list, - struct drm_i915_gem_object, - ring_list); + obj = list_first_entry(&ring->active_list, + struct drm_i915_gem_object, + ring_list); - obj_priv->base.write_domain = 0; - list_del_init(&obj_priv->gpu_write_list); - i915_gem_object_move_to_inactive(&obj_priv->base); + obj->base.write_domain = 0; + list_del_init(&obj->gpu_write_list); + i915_gem_object_move_to_inactive(obj); } } void i915_gem_reset(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; - struct drm_i915_gem_object *obj_priv; + struct drm_i915_gem_object *obj; int i; i915_gem_reset_ring_lists(dev_priv, &dev_priv->render_ring); @@ -1939,23 +1918,23 @@ void i915_gem_reset(struct drm_device *dev) * lost bo to the inactive list. */ while (!list_empty(&dev_priv->mm.flushing_list)) { - obj_priv = list_first_entry(&dev_priv->mm.flushing_list, - struct drm_i915_gem_object, - mm_list); + obj= list_first_entry(&dev_priv->mm.flushing_list, + struct drm_i915_gem_object, + mm_list); - obj_priv->base.write_domain = 0; - list_del_init(&obj_priv->gpu_write_list); - i915_gem_object_move_to_inactive(&obj_priv->base); + obj->base.write_domain = 0; + list_del_init(&obj->gpu_write_list); + i915_gem_object_move_to_inactive(obj); } /* Move everything out of the GPU domains to ensure we do any * necessary invalidation upon reuse. */ - list_for_each_entry(obj_priv, + list_for_each_entry(obj, &dev_priv->mm.inactive_list, mm_list) { - obj_priv->base.read_domains &= ~I915_GEM_GPU_DOMAINS; + obj->base.read_domains &= ~I915_GEM_GPU_DOMAINS; } /* The fence registers are invalidated so clear them out */ @@ -2008,18 +1987,16 @@ i915_gem_retire_requests_ring(struct drm_device *dev, * by the ringbuffer to the flushing/inactive lists as appropriate. */ while (!list_empty(&ring->active_list)) { - struct drm_gem_object *obj; - struct drm_i915_gem_object *obj_priv; + struct drm_i915_gem_object *obj; - obj_priv = list_first_entry(&ring->active_list, - struct drm_i915_gem_object, - ring_list); + obj= list_first_entry(&ring->active_list, + struct drm_i915_gem_object, + ring_list); - if (!i915_seqno_passed(seqno, obj_priv->last_rendering_seqno)) + if (!i915_seqno_passed(seqno, obj->last_rendering_seqno)) break; - obj = &obj_priv->base; - if (obj->write_domain != 0) + if (obj->base.write_domain != 0) i915_gem_object_move_to_flushing(obj); else i915_gem_object_move_to_inactive(obj); @@ -2040,17 +2017,17 @@ i915_gem_retire_requests(struct drm_device *dev) drm_i915_private_t *dev_priv = dev->dev_private; if (!list_empty(&dev_priv->mm.deferred_free_list)) { - struct drm_i915_gem_object *obj_priv, *tmp; + struct drm_i915_gem_object *obj, *next; /* We must be careful that during unbind() we do not * accidentally infinitely recurse into retire requests. * Currently: * retire -> free -> unbind -> wait -> retire_ring */ - list_for_each_entry_safe(obj_priv, tmp, + list_for_each_entry_safe(obj, next, &dev_priv->mm.deferred_free_list, mm_list) - i915_gem_free_object_tail(&obj_priv->base); + i915_gem_free_object_tail(obj); } i915_gem_retire_requests_ring(dev, &dev_priv->render_ring); @@ -2175,7 +2152,6 @@ i915_wait_request(struct drm_device *dev, uint32_t seqno, static void i915_gem_flush_ring(struct drm_device *dev, - struct drm_file *file_priv, struct intel_ring_buffer *ring, uint32_t invalidate_domains, uint32_t flush_domains) @@ -2186,7 +2162,6 @@ i915_gem_flush_ring(struct drm_device *dev, static void i915_gem_flush(struct drm_device *dev, - struct drm_file *file_priv, uint32_t invalidate_domains, uint32_t flush_domains, uint32_t flush_rings) @@ -2198,16 +2173,13 @@ i915_gem_flush(struct drm_device *dev, if ((flush_domains | invalidate_domains) & I915_GEM_GPU_DOMAINS) { if (flush_rings & RING_RENDER) - i915_gem_flush_ring(dev, file_priv, - &dev_priv->render_ring, + i915_gem_flush_ring(dev, &dev_priv->render_ring, invalidate_domains, flush_domains); if (flush_rings & RING_BSD) - i915_gem_flush_ring(dev, file_priv, - &dev_priv->bsd_ring, + i915_gem_flush_ring(dev, &dev_priv->bsd_ring, invalidate_domains, flush_domains); if (flush_rings & RING_BLT) - i915_gem_flush_ring(dev, file_priv, - &dev_priv->blt_ring, + i915_gem_flush_ring(dev, &dev_priv->blt_ring, invalidate_domains, flush_domains); } } @@ -2217,26 +2189,25 @@ i915_gem_flush(struct drm_device *dev, * safe to unbind from the GTT or access from the CPU. */ static int -i915_gem_object_wait_rendering(struct drm_gem_object *obj, +i915_gem_object_wait_rendering(struct drm_i915_gem_object *obj, bool interruptible) { - struct drm_device *dev = obj->dev; - struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); + struct drm_device *dev = obj->base.dev; int ret; /* This function only exists to support waiting for existing rendering, * not for emitting required flushes. */ - BUG_ON((obj->write_domain & I915_GEM_GPU_DOMAINS) != 0); + BUG_ON((obj->base.write_domain & I915_GEM_GPU_DOMAINS) != 0); /* If there is rendering queued on the buffer being evicted, wait for * it. */ - if (obj_priv->active) { + if (obj->active) { ret = i915_do_wait_request(dev, - obj_priv->last_rendering_seqno, + obj->last_rendering_seqno, interruptible, - obj_priv->ring); + obj->ring); if (ret) return ret; } @@ -2248,17 +2219,16 @@ i915_gem_object_wait_rendering(struct drm_gem_object *obj, * Unbinds an object from the GTT aperture. */ int -i915_gem_object_unbind(struct drm_gem_object *obj) +i915_gem_object_unbind(struct drm_i915_gem_object *obj) { - struct drm_device *dev = obj->dev; + struct drm_device *dev = obj->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); int ret = 0; - if (obj_priv->gtt_space == NULL) + if (obj->gtt_space == NULL) return 0; - if (obj_priv->pin_count != 0) { + if (obj->pin_count != 0) { DRM_ERROR("Attempting to unbind pinned buffer\n"); return -EINVAL; } @@ -2281,27 +2251,27 @@ i915_gem_object_unbind(struct drm_gem_object *obj) */ if (ret) { i915_gem_clflush_object(obj); - obj->read_domains = obj->write_domain = I915_GEM_DOMAIN_CPU; + obj->base.read_domains = obj->base.write_domain = I915_GEM_DOMAIN_CPU; } /* release the fence reg _after_ flushing */ - if (obj_priv->fence_reg != I915_FENCE_REG_NONE) + if (obj->fence_reg != I915_FENCE_REG_NONE) i915_gem_clear_fence_reg(obj); i915_gem_gtt_unbind_object(obj); i915_gem_object_put_pages_gtt(obj); - i915_gem_info_remove_gtt(dev_priv, obj_priv); - list_del_init(&obj_priv->mm_list); + i915_gem_info_remove_gtt(dev_priv, obj); + list_del_init(&obj->mm_list); /* Avoid an unnecessary call to unbind on rebind. */ - obj_priv->map_and_fenceable = true; + obj->map_and_fenceable = true; - drm_mm_put_block(obj_priv->gtt_space); - obj_priv->gtt_space = NULL; - obj_priv->gtt_offset = 0; + drm_mm_put_block(obj->gtt_space); + obj->gtt_space = NULL; + obj->gtt_offset = 0; - if (i915_gem_object_is_purgeable(obj_priv)) + if (i915_gem_object_is_purgeable(obj)) i915_gem_object_truncate(obj); trace_i915_gem_object_unbind(obj); @@ -2315,7 +2285,7 @@ static int i915_ring_idle(struct drm_device *dev, if (list_empty(&ring->gpu_write_list) && list_empty(&ring->active_list)) return 0; - i915_gem_flush_ring(dev, NULL, ring, + i915_gem_flush_ring(dev, ring, I915_GEM_GPU_DOMAINS, I915_GEM_GPU_DOMAINS); return i915_wait_request(dev, i915_gem_next_request_seqno(dev, ring), @@ -2350,89 +2320,86 @@ i915_gpu_idle(struct drm_device *dev) return 0; } -static void sandybridge_write_fence_reg(struct drm_gem_object *obj) +static void sandybridge_write_fence_reg(struct drm_i915_gem_object *obj) { - struct drm_device *dev = obj->dev; + struct drm_device *dev = obj->base.dev; drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); - u32 size = i915_gem_get_gtt_size(obj_priv); - int regnum = obj_priv->fence_reg; + u32 size = obj->gtt_space->size; + int regnum = obj->fence_reg; uint64_t val; - val = (uint64_t)((obj_priv->gtt_offset + size - 4096) & + val = (uint64_t)((obj->gtt_offset + size - 4096) & 0xfffff000) << 32; - val |= obj_priv->gtt_offset & 0xfffff000; - val |= (uint64_t)((obj_priv->stride / 128) - 1) << + val |= obj->gtt_offset & 0xfffff000; + val |= (uint64_t)((obj->stride / 128) - 1) << SANDYBRIDGE_FENCE_PITCH_SHIFT; - if (obj_priv->tiling_mode == I915_TILING_Y) + if (obj->tiling_mode == I915_TILING_Y) val |= 1 << I965_FENCE_TILING_Y_SHIFT; val |= I965_FENCE_REG_VALID; I915_WRITE64(FENCE_REG_SANDYBRIDGE_0 + (regnum * 8), val); } -static void i965_write_fence_reg(struct drm_gem_object *obj) +static void i965_write_fence_reg(struct drm_i915_gem_object *obj) { - struct drm_device *dev = obj->dev; + struct drm_device *dev = obj->base.dev; drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); - u32 size = i915_gem_get_gtt_size(obj_priv); - int regnum = obj_priv->fence_reg; + u32 size = obj->gtt_space->size; + int regnum = obj->fence_reg; uint64_t val; - val = (uint64_t)((obj_priv->gtt_offset + size - 4096) & + val = (uint64_t)((obj->gtt_offset + size - 4096) & 0xfffff000) << 32; - val |= obj_priv->gtt_offset & 0xfffff000; - val |= ((obj_priv->stride / 128) - 1) << I965_FENCE_PITCH_SHIFT; - if (obj_priv->tiling_mode == I915_TILING_Y) + val |= obj->gtt_offset & 0xfffff000; + val |= ((obj->stride / 128) - 1) << I965_FENCE_PITCH_SHIFT; + if (obj->tiling_mode == I915_TILING_Y) val |= 1 << I965_FENCE_TILING_Y_SHIFT; val |= I965_FENCE_REG_VALID; I915_WRITE64(FENCE_REG_965_0 + (regnum * 8), val); } -static void i915_write_fence_reg(struct drm_gem_object *obj) +static void i915_write_fence_reg(struct drm_i915_gem_object *obj) { - struct drm_device *dev = obj->dev; + struct drm_device *dev = obj->base.dev; drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); - u32 size = i915_gem_get_gtt_size(obj_priv); + u32 size = obj->gtt_space->size; uint32_t fence_reg, val, pitch_val; int tile_width; - if ((obj_priv->gtt_offset & ~I915_FENCE_START_MASK) || - (obj_priv->gtt_offset & (size - 1))) { + if ((obj->gtt_offset & ~I915_FENCE_START_MASK) || + (obj->gtt_offset & (size - 1))) { WARN(1, "%s: object 0x%08x [fenceable? %d] not 1M or size (0x%08x) aligned [gtt_space offset=%lx, size=%lx]\n", - __func__, obj_priv->gtt_offset, obj_priv->map_and_fenceable, size, - obj_priv->gtt_space->start, obj_priv->gtt_space->size); + __func__, obj->gtt_offset, obj->map_and_fenceable, size, + obj->gtt_space->start, obj->gtt_space->size); return; } - if (obj_priv->tiling_mode == I915_TILING_Y && + if (obj->tiling_mode == I915_TILING_Y && HAS_128_BYTE_Y_TILING(dev)) tile_width = 128; else tile_width = 512; /* Note: pitch better be a power of two tile widths */ - pitch_val = obj_priv->stride / tile_width; + pitch_val = obj->stride / tile_width; pitch_val = ffs(pitch_val) - 1; - if (obj_priv->tiling_mode == I915_TILING_Y && + if (obj->tiling_mode == I915_TILING_Y && HAS_128_BYTE_Y_TILING(dev)) WARN_ON(pitch_val > I830_FENCE_MAX_PITCH_VAL); else WARN_ON(pitch_val > I915_FENCE_MAX_PITCH_VAL); - val = obj_priv->gtt_offset; - if (obj_priv->tiling_mode == I915_TILING_Y) + val = obj->gtt_offset; + if (obj->tiling_mode == I915_TILING_Y) val |= 1 << I830_FENCE_TILING_Y_SHIFT; val |= I915_FENCE_SIZE_BITS(size); val |= pitch_val << I830_FENCE_PITCH_SHIFT; val |= I830_FENCE_REG_VALID; - fence_reg = obj_priv->fence_reg; + fence_reg = obj->fence_reg; if (fence_reg < 8) fence_reg = FENCE_REG_830_0 + fence_reg * 4; else @@ -2440,30 +2407,29 @@ static void i915_write_fence_reg(struct drm_gem_object *obj) I915_WRITE(fence_reg, val); } -static void i830_write_fence_reg(struct drm_gem_object *obj) +static void i830_write_fence_reg(struct drm_i915_gem_object *obj) { - struct drm_device *dev = obj->dev; + struct drm_device *dev = obj->base.dev; drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); - u32 size = i915_gem_get_gtt_size(obj_priv); - int regnum = obj_priv->fence_reg; + u32 size = obj->gtt_space->size; + int regnum = obj->fence_reg; uint32_t val; uint32_t pitch_val; uint32_t fence_size_bits; - if ((obj_priv->gtt_offset & ~I830_FENCE_START_MASK) || - (obj_priv->gtt_offset & (obj->size - 1))) { + if ((obj->gtt_offset & ~I830_FENCE_START_MASK) || + (obj->gtt_offset & (obj->base.size - 1))) { WARN(1, "%s: object 0x%08x not 512K or size aligned\n", - __func__, obj_priv->gtt_offset); + __func__, obj->gtt_offset); return; } - pitch_val = obj_priv->stride / 128; + pitch_val = obj->stride / 128; pitch_val = ffs(pitch_val) - 1; WARN_ON(pitch_val > I830_FENCE_MAX_PITCH_VAL); - val = obj_priv->gtt_offset; - if (obj_priv->tiling_mode == I915_TILING_Y) + val = obj->gtt_offset; + if (obj->tiling_mode == I915_TILING_Y) val |= 1 << I830_FENCE_TILING_Y_SHIFT; fence_size_bits = I830_FENCE_SIZE_BITS(size); WARN_ON(fence_size_bits & ~0x00000f00); @@ -2479,7 +2445,7 @@ static int i915_find_fence_reg(struct drm_device *dev, { struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_fence_reg *reg; - struct drm_i915_gem_object *obj_priv = NULL; + struct drm_i915_gem_object *obj = NULL; int i, avail, ret; /* First try to find a free reg */ @@ -2489,9 +2455,8 @@ static int i915_find_fence_reg(struct drm_device *dev, if (!reg->obj) return i; - obj_priv = to_intel_bo(reg->obj); - if (!obj_priv->pin_count) - avail++; + if (!reg->obj->pin_count) + avail++; } if (avail == 0) @@ -2501,12 +2466,12 @@ static int i915_find_fence_reg(struct drm_device *dev, avail = I915_FENCE_REG_NONE; list_for_each_entry(reg, &dev_priv->mm.fence_list, lru_list) { - obj_priv = to_intel_bo(reg->obj); - if (obj_priv->pin_count) + obj = reg->obj; + if (obj->pin_count) continue; /* found one! */ - avail = obj_priv->fence_reg; + avail = obj->fence_reg; break; } @@ -2516,9 +2481,9 @@ static int i915_find_fence_reg(struct drm_device *dev, * might drop that one, causing a use-after-free in it. So hold a * private reference to obj like the other callers of put_fence_reg * (set_tiling ioctl) do. */ - drm_gem_object_reference(&obj_priv->base); - ret = i915_gem_object_put_fence_reg(&obj_priv->base, interruptible); - drm_gem_object_unreference(&obj_priv->base); + drm_gem_object_reference(&obj->base); + ret = i915_gem_object_put_fence_reg(obj, interruptible); + drm_gem_object_unreference(&obj->base); if (ret != 0) return ret; @@ -2539,39 +2504,38 @@ static int i915_find_fence_reg(struct drm_device *dev, * and tiling format. */ int -i915_gem_object_get_fence_reg(struct drm_gem_object *obj, +i915_gem_object_get_fence_reg(struct drm_i915_gem_object *obj, bool interruptible) { - struct drm_device *dev = obj->dev; + struct drm_device *dev = obj->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); struct drm_i915_fence_reg *reg = NULL; int ret; /* Just update our place in the LRU if our fence is getting used. */ - if (obj_priv->fence_reg != I915_FENCE_REG_NONE) { - reg = &dev_priv->fence_regs[obj_priv->fence_reg]; + if (obj->fence_reg != I915_FENCE_REG_NONE) { + reg = &dev_priv->fence_regs[obj->fence_reg]; list_move_tail(®->lru_list, &dev_priv->mm.fence_list); return 0; } - switch (obj_priv->tiling_mode) { + switch (obj->tiling_mode) { case I915_TILING_NONE: WARN(1, "allocating a fence for non-tiled object?\n"); break; case I915_TILING_X: - if (!obj_priv->stride) + if (!obj->stride) return -EINVAL; - WARN((obj_priv->stride & (512 - 1)), + WARN((obj->stride & (512 - 1)), "object 0x%08x is X tiled but has non-512B pitch\n", - obj_priv->gtt_offset); + obj->gtt_offset); break; case I915_TILING_Y: - if (!obj_priv->stride) + if (!obj->stride) return -EINVAL; - WARN((obj_priv->stride & (128 - 1)), + WARN((obj->stride & (128 - 1)), "object 0x%08x is Y tiled but has non-128B pitch\n", - obj_priv->gtt_offset); + obj->gtt_offset); break; } @@ -2579,8 +2543,8 @@ i915_gem_object_get_fence_reg(struct drm_gem_object *obj, if (ret < 0) return ret; - obj_priv->fence_reg = ret; - reg = &dev_priv->fence_regs[obj_priv->fence_reg]; + obj->fence_reg = ret; + reg = &dev_priv->fence_regs[obj->fence_reg]; list_add_tail(®->lru_list, &dev_priv->mm.fence_list); reg->obj = obj; @@ -2602,8 +2566,8 @@ i915_gem_object_get_fence_reg(struct drm_gem_object *obj, } trace_i915_gem_object_get_fence(obj, - obj_priv->fence_reg, - obj_priv->tiling_mode); + obj->fence_reg, + obj->tiling_mode); return 0; } @@ -2613,40 +2577,38 @@ i915_gem_object_get_fence_reg(struct drm_gem_object *obj, * @obj: object to clear * * Zeroes out the fence register itself and clears out the associated - * data structures in dev_priv and obj_priv. + * data structures in dev_priv and obj. */ static void -i915_gem_clear_fence_reg(struct drm_gem_object *obj) +i915_gem_clear_fence_reg(struct drm_i915_gem_object *obj) { - struct drm_device *dev = obj->dev; + struct drm_device *dev = obj->base.dev; drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); - struct drm_i915_fence_reg *reg = - &dev_priv->fence_regs[obj_priv->fence_reg]; + struct drm_i915_fence_reg *reg = &dev_priv->fence_regs[obj->fence_reg]; uint32_t fence_reg; switch (INTEL_INFO(dev)->gen) { case 6: I915_WRITE64(FENCE_REG_SANDYBRIDGE_0 + - (obj_priv->fence_reg * 8), 0); + (obj->fence_reg * 8), 0); break; case 5: case 4: - I915_WRITE64(FENCE_REG_965_0 + (obj_priv->fence_reg * 8), 0); + I915_WRITE64(FENCE_REG_965_0 + (obj->fence_reg * 8), 0); break; case 3: - if (obj_priv->fence_reg >= 8) - fence_reg = FENCE_REG_945_8 + (obj_priv->fence_reg - 8) * 4; + if (obj->fence_reg >= 8) + fence_reg = FENCE_REG_945_8 + (obj->fence_reg - 8) * 4; else case 2: - fence_reg = FENCE_REG_830_0 + obj_priv->fence_reg * 4; + fence_reg = FENCE_REG_830_0 + obj->fence_reg * 4; I915_WRITE(fence_reg, 0); break; } reg->obj = NULL; - obj_priv->fence_reg = I915_FENCE_REG_NONE; + obj->fence_reg = I915_FENCE_REG_NONE; list_del_init(®->lru_list); } @@ -2657,18 +2619,17 @@ i915_gem_clear_fence_reg(struct drm_gem_object *obj) * @bool: whether the wait upon the fence is interruptible * * Zeroes out the fence register itself and clears out the associated - * data structures in dev_priv and obj_priv. + * data structures in dev_priv and obj. */ int -i915_gem_object_put_fence_reg(struct drm_gem_object *obj, +i915_gem_object_put_fence_reg(struct drm_i915_gem_object *obj, bool interruptible) { - struct drm_device *dev = obj->dev; + struct drm_device *dev = obj->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); struct drm_i915_fence_reg *reg; - if (obj_priv->fence_reg == I915_FENCE_REG_NONE) + if (obj->fence_reg == I915_FENCE_REG_NONE) return 0; /* If we've changed tiling, GTT-mappings of the object @@ -2681,7 +2642,7 @@ i915_gem_object_put_fence_reg(struct drm_gem_object *obj, * therefore we must wait for any outstanding access to complete * before clearing the fence. */ - reg = &dev_priv->fence_regs[obj_priv->fence_reg]; + reg = &dev_priv->fence_regs[obj->fence_reg]; if (reg->gpu) { int ret; @@ -2706,27 +2667,26 @@ i915_gem_object_put_fence_reg(struct drm_gem_object *obj, * Finds free space in the GTT aperture and binds the object there. */ static int -i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, +i915_gem_object_bind_to_gtt(struct drm_i915_gem_object *obj, unsigned alignment, bool map_and_fenceable) { - struct drm_device *dev = obj->dev; + struct drm_device *dev = obj->base.dev; drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); struct drm_mm_node *free_space; gfp_t gfpmask = __GFP_NORETRY | __GFP_NOWARN; u32 size, fence_size, fence_alignment, unfenced_alignment; bool mappable, fenceable; int ret; - if (obj_priv->madv != I915_MADV_WILLNEED) { + if (obj->madv != I915_MADV_WILLNEED) { DRM_ERROR("Attempting to bind a purgeable object\n"); return -EINVAL; } - fence_size = i915_gem_get_gtt_size(obj_priv); - fence_alignment = i915_gem_get_gtt_alignment(obj_priv); - unfenced_alignment = i915_gem_get_unfenced_gtt_alignment(obj_priv); + fence_size = i915_gem_get_gtt_size(obj); + fence_alignment = i915_gem_get_gtt_alignment(obj); + unfenced_alignment = i915_gem_get_unfenced_gtt_alignment(obj); if (alignment == 0) alignment = map_and_fenceable ? fence_alignment : @@ -2736,12 +2696,12 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, return -EINVAL; } - size = map_and_fenceable ? fence_size : obj->size; + size = map_and_fenceable ? fence_size : obj->base.size; /* If the object is bigger than the entire aperture, reject it early * before evicting everything in a vain attempt to find space. */ - if (obj->size > + if (obj->base.size > (map_and_fenceable ? dev_priv->mm.gtt_mappable_end : dev_priv->mm.gtt_total)) { DRM_ERROR("Attempting to bind an object larger than the aperture\n"); return -E2BIG; @@ -2760,16 +2720,16 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, if (free_space != NULL) { if (map_and_fenceable) - obj_priv->gtt_space = + obj->gtt_space = drm_mm_get_block_range_generic(free_space, size, alignment, 0, dev_priv->mm.gtt_mappable_end, 0); else - obj_priv->gtt_space = + obj->gtt_space = drm_mm_get_block(free_space, size, alignment); } - if (obj_priv->gtt_space == NULL) { + if (obj->gtt_space == NULL) { /* If the gtt is empty and we're still having trouble * fitting our object in, we're out of memory. */ @@ -2783,8 +2743,8 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, ret = i915_gem_object_get_pages_gtt(obj, gfpmask); if (ret) { - drm_mm_put_block(obj_priv->gtt_space); - obj_priv->gtt_space = NULL; + drm_mm_put_block(obj->gtt_space); + obj->gtt_space = NULL; if (ret == -ENOMEM) { /* first try to clear up some space from the GTT */ @@ -2810,8 +2770,8 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, ret = i915_gem_gtt_bind_object(obj); if (ret) { i915_gem_object_put_pages_gtt(obj); - drm_mm_put_block(obj_priv->gtt_space); - obj_priv->gtt_space = NULL; + drm_mm_put_block(obj->gtt_space); + obj->gtt_space = NULL; ret = i915_gem_evict_something(dev, size, alignment, map_and_fenceable); @@ -2821,65 +2781,61 @@ i915_gem_object_bind_to_gtt(struct drm_gem_object *obj, goto search_free; } - obj_priv->gtt_offset = obj_priv->gtt_space->start; + obj->gtt_offset = obj->gtt_space->start; /* keep track of bounds object by adding it to the inactive list */ - list_add_tail(&obj_priv->mm_list, &dev_priv->mm.inactive_list); - i915_gem_info_add_gtt(dev_priv, obj_priv); + list_add_tail(&obj->mm_list, &dev_priv->mm.inactive_list); + i915_gem_info_add_gtt(dev_priv, obj); /* Assert that the object is not currently in any GPU domain. As it * wasn't in the GTT, there shouldn't be any way it could have been in * a GPU cache */ - BUG_ON(obj->read_domains & I915_GEM_GPU_DOMAINS); - BUG_ON(obj->write_domain & I915_GEM_GPU_DOMAINS); + BUG_ON(obj->base.read_domains & I915_GEM_GPU_DOMAINS); + BUG_ON(obj->base.write_domain & I915_GEM_GPU_DOMAINS); - trace_i915_gem_object_bind(obj, obj_priv->gtt_offset, map_and_fenceable); + trace_i915_gem_object_bind(obj, obj->gtt_offset, map_and_fenceable); fenceable = - obj_priv->gtt_space->size == fence_size && - (obj_priv->gtt_space->start & (fence_alignment -1)) == 0; + obj->gtt_space->size == fence_size && + (obj->gtt_space->start & (fence_alignment -1)) == 0; mappable = - obj_priv->gtt_offset + obj->size <= dev_priv->mm.gtt_mappable_end; + obj->gtt_offset + obj->base.size <= dev_priv->mm.gtt_mappable_end; - obj_priv->map_and_fenceable = mappable && fenceable; + obj->map_and_fenceable = mappable && fenceable; return 0; } void -i915_gem_clflush_object(struct drm_gem_object *obj) +i915_gem_clflush_object(struct drm_i915_gem_object *obj) { - struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); - /* If we don't have a page list set up, then we're not pinned * to GPU, and we can ignore the cache flush because it'll happen * again at bind time. */ - if (obj_priv->pages == NULL) + if (obj->pages == NULL) return; trace_i915_gem_object_clflush(obj); - drm_clflush_pages(obj_priv->pages, obj->size / PAGE_SIZE); + drm_clflush_pages(obj->pages, obj->base.size / PAGE_SIZE); } /** Flushes any GPU write domain for the object if it's dirty. */ static int -i915_gem_object_flush_gpu_write_domain(struct drm_gem_object *obj, +i915_gem_object_flush_gpu_write_domain(struct drm_i915_gem_object *obj, bool pipelined) { - struct drm_device *dev = obj->dev; + struct drm_device *dev = obj->base.dev; - if ((obj->write_domain & I915_GEM_GPU_DOMAINS) == 0) + if ((obj->base.write_domain & I915_GEM_GPU_DOMAINS) == 0) return 0; /* Queue the GPU write cache flushing we need. */ - i915_gem_flush_ring(dev, NULL, - to_intel_bo(obj)->ring, - 0, obj->write_domain); - BUG_ON(obj->write_domain); + i915_gem_flush_ring(dev, obj->ring, 0, obj->base.write_domain); + BUG_ON(obj->base.write_domain); if (pipelined) return 0; @@ -2889,11 +2845,11 @@ i915_gem_object_flush_gpu_write_domain(struct drm_gem_object *obj, /** Flushes the GTT write domain for the object if it's dirty. */ static void -i915_gem_object_flush_gtt_write_domain(struct drm_gem_object *obj) +i915_gem_object_flush_gtt_write_domain(struct drm_i915_gem_object *obj) { uint32_t old_write_domain; - if (obj->write_domain != I915_GEM_DOMAIN_GTT) + if (obj->base.write_domain != I915_GEM_DOMAIN_GTT) return; /* No actual flushing is required for the GTT write domain. Writes @@ -2902,30 +2858,30 @@ i915_gem_object_flush_gtt_write_domain(struct drm_gem_object *obj) */ i915_gem_release_mmap(obj); - old_write_domain = obj->write_domain; - obj->write_domain = 0; + old_write_domain = obj->base.write_domain; + obj->base.write_domain = 0; trace_i915_gem_object_change_domain(obj, - obj->read_domains, + obj->base.read_domains, old_write_domain); } /** Flushes the CPU write domain for the object if it's dirty. */ static void -i915_gem_object_flush_cpu_write_domain(struct drm_gem_object *obj) +i915_gem_object_flush_cpu_write_domain(struct drm_i915_gem_object *obj) { uint32_t old_write_domain; - if (obj->write_domain != I915_GEM_DOMAIN_CPU) + if (obj->base.write_domain != I915_GEM_DOMAIN_CPU) return; i915_gem_clflush_object(obj); intel_gtt_chipset_flush(); - old_write_domain = obj->write_domain; - obj->write_domain = 0; + old_write_domain = obj->base.write_domain; + obj->base.write_domain = 0; trace_i915_gem_object_change_domain(obj, - obj->read_domains, + obj->base.read_domains, old_write_domain); } @@ -2936,14 +2892,13 @@ i915_gem_object_flush_cpu_write_domain(struct drm_gem_object *obj) * flushes to occur. */ int -i915_gem_object_set_to_gtt_domain(struct drm_gem_object *obj, int write) +i915_gem_object_set_to_gtt_domain(struct drm_i915_gem_object *obj, int write) { - struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); uint32_t old_write_domain, old_read_domains; int ret; /* Not valid to be called on unbound objects. */ - if (obj_priv->gtt_space == NULL) + if (obj->gtt_space == NULL) return -EINVAL; ret = i915_gem_object_flush_gpu_write_domain(obj, false); @@ -2958,18 +2913,18 @@ i915_gem_object_set_to_gtt_domain(struct drm_gem_object *obj, int write) return ret; } - old_write_domain = obj->write_domain; - old_read_domains = obj->read_domains; + old_write_domain = obj->base.write_domain; + old_read_domains = obj->base.read_domains; /* It should now be out of any other write domains, and we can update * the domain values for our changes. */ - BUG_ON((obj->write_domain & ~I915_GEM_DOMAIN_GTT) != 0); - obj->read_domains |= I915_GEM_DOMAIN_GTT; + BUG_ON((obj->base.write_domain & ~I915_GEM_DOMAIN_GTT) != 0); + obj->base.read_domains |= I915_GEM_DOMAIN_GTT; if (write) { - obj->read_domains = I915_GEM_DOMAIN_GTT; - obj->write_domain = I915_GEM_DOMAIN_GTT; - obj_priv->dirty = 1; + obj->base.read_domains = I915_GEM_DOMAIN_GTT; + obj->base.write_domain = I915_GEM_DOMAIN_GTT; + obj->dirty = 1; } trace_i915_gem_object_change_domain(obj, @@ -2984,15 +2939,14 @@ i915_gem_object_set_to_gtt_domain(struct drm_gem_object *obj, int write) * wait, as in modesetting process we're not supposed to be interrupted. */ int -i915_gem_object_set_to_display_plane(struct drm_gem_object *obj, +i915_gem_object_set_to_display_plane(struct drm_i915_gem_object *obj, bool pipelined) { - struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); uint32_t old_read_domains; int ret; /* Not valid to be called on unbound objects. */ - if (obj_priv->gtt_space == NULL) + if (obj->gtt_space == NULL) return -EINVAL; ret = i915_gem_object_flush_gpu_write_domain(obj, true); @@ -3008,12 +2962,12 @@ i915_gem_object_set_to_display_plane(struct drm_gem_object *obj, i915_gem_object_flush_cpu_write_domain(obj); - old_read_domains = obj->read_domains; - obj->read_domains |= I915_GEM_DOMAIN_GTT; + old_read_domains = obj->base.read_domains; + obj->base.read_domains |= I915_GEM_DOMAIN_GTT; trace_i915_gem_object_change_domain(obj, old_read_domains, - obj->write_domain); + obj->base.write_domain); return 0; } @@ -3026,10 +2980,10 @@ i915_gem_object_flush_gpu(struct drm_i915_gem_object *obj, return 0; if (obj->base.write_domain & I915_GEM_GPU_DOMAINS) - i915_gem_flush_ring(obj->base.dev, NULL, obj->ring, + i915_gem_flush_ring(obj->base.dev, obj->ring, 0, obj->base.write_domain); - return i915_gem_object_wait_rendering(&obj->base, interruptible); + return i915_gem_object_wait_rendering(obj, interruptible); } /** @@ -3039,7 +2993,7 @@ i915_gem_object_flush_gpu(struct drm_i915_gem_object *obj, * flushes to occur. */ static int -i915_gem_object_set_to_cpu_domain(struct drm_gem_object *obj, int write) +i915_gem_object_set_to_cpu_domain(struct drm_i915_gem_object *obj, int write) { uint32_t old_write_domain, old_read_domains; int ret; @@ -3061,27 +3015,27 @@ i915_gem_object_set_to_cpu_domain(struct drm_gem_object *obj, int write) return ret; } - old_write_domain = obj->write_domain; - old_read_domains = obj->read_domains; + old_write_domain = obj->base.write_domain; + old_read_domains = obj->base.read_domains; /* Flush the CPU cache if it's still invalid. */ - if ((obj->read_domains & I915_GEM_DOMAIN_CPU) == 0) { + if ((obj->base.read_domains & I915_GEM_DOMAIN_CPU) == 0) { i915_gem_clflush_object(obj); - obj->read_domains |= I915_GEM_DOMAIN_CPU; + obj->base.read_domains |= I915_GEM_DOMAIN_CPU; } /* It should now be out of any other write domains, and we can update * the domain values for our changes. */ - BUG_ON((obj->write_domain & ~I915_GEM_DOMAIN_CPU) != 0); + BUG_ON((obj->base.write_domain & ~I915_GEM_DOMAIN_CPU) != 0); /* If we're writing through the CPU, then the GPU read domains will * need to be invalidated at next use. */ if (write) { - obj->read_domains = I915_GEM_DOMAIN_CPU; - obj->write_domain = I915_GEM_DOMAIN_CPU; + obj->base.read_domains = I915_GEM_DOMAIN_CPU; + obj->base.write_domain = I915_GEM_DOMAIN_CPU; } trace_i915_gem_object_change_domain(obj, @@ -3203,20 +3157,18 @@ i915_gem_object_set_to_cpu_domain(struct drm_gem_object *obj, int write) * drm_agp_chipset_flush */ static void -i915_gem_object_set_to_gpu_domain(struct drm_gem_object *obj, +i915_gem_object_set_to_gpu_domain(struct drm_i915_gem_object *obj, struct intel_ring_buffer *ring, struct change_domains *cd) { - struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); - uint32_t invalidate_domains = 0; - uint32_t flush_domains = 0; + uint32_t invalidate_domains = 0, flush_domains = 0; /* * If the object isn't moving to a new write domain, * let the object stay in multiple read domains */ - if (obj->pending_write_domain == 0) - obj->pending_read_domains |= obj->read_domains; + if (obj->base.pending_write_domain == 0) + obj->base.pending_read_domains |= obj->base.read_domains; /* * Flush the current write domain if @@ -3224,18 +3176,18 @@ i915_gem_object_set_to_gpu_domain(struct drm_gem_object *obj, * any read domains which differ from the old * write domain */ - if (obj->write_domain && - (obj->write_domain != obj->pending_read_domains || - obj_priv->ring != ring)) { - flush_domains |= obj->write_domain; + if (obj->base.write_domain && + (obj->base.write_domain != obj->base.pending_read_domains || + obj->ring != ring)) { + flush_domains |= obj->base.write_domain; invalidate_domains |= - obj->pending_read_domains & ~obj->write_domain; + obj->base.pending_read_domains & ~obj->base.write_domain; } /* * Invalidate any read caches which may have * stale data. That is, any new read domains. */ - invalidate_domains |= obj->pending_read_domains & ~obj->read_domains; + invalidate_domains |= obj->base.pending_read_domains & ~obj->base.read_domains; if ((flush_domains | invalidate_domains) & I915_GEM_DOMAIN_CPU) i915_gem_clflush_object(obj); @@ -3249,13 +3201,13 @@ i915_gem_object_set_to_gpu_domain(struct drm_gem_object *obj, * write_domains). So if we have a current write domain that we * aren't changing, set pending_write_domain to that. */ - if (flush_domains == 0 && obj->pending_write_domain == 0) - obj->pending_write_domain = obj->write_domain; + if (flush_domains == 0 && obj->base.pending_write_domain == 0) + obj->base.pending_write_domain = obj->base.write_domain; cd->invalidate_domains |= invalidate_domains; cd->flush_domains |= flush_domains; if (flush_domains & I915_GEM_GPU_DOMAINS) - cd->flush_rings |= obj_priv->ring->id; + cd->flush_rings |= obj->ring->id; if (invalidate_domains & I915_GEM_GPU_DOMAINS) cd->flush_rings |= ring->id; } @@ -3267,30 +3219,28 @@ i915_gem_object_set_to_gpu_domain(struct drm_gem_object *obj, * and doesn't handle transitioning from !(read_domains & I915_GEM_DOMAIN_CPU). */ static void -i915_gem_object_set_to_full_cpu_read_domain(struct drm_gem_object *obj) +i915_gem_object_set_to_full_cpu_read_domain(struct drm_i915_gem_object *obj) { - struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); - - if (!obj_priv->page_cpu_valid) + if (!obj->page_cpu_valid) return; /* If we're partially in the CPU read domain, finish moving it in. */ - if (obj->read_domains & I915_GEM_DOMAIN_CPU) { + if (obj->base.read_domains & I915_GEM_DOMAIN_CPU) { int i; - for (i = 0; i <= (obj->size - 1) / PAGE_SIZE; i++) { - if (obj_priv->page_cpu_valid[i]) + for (i = 0; i <= (obj->base.size - 1) / PAGE_SIZE; i++) { + if (obj->page_cpu_valid[i]) continue; - drm_clflush_pages(obj_priv->pages + i, 1); + drm_clflush_pages(obj->pages + i, 1); } } /* Free the page_cpu_valid mappings which are now stale, whether * or not we've got I915_GEM_DOMAIN_CPU. */ - kfree(obj_priv->page_cpu_valid); - obj_priv->page_cpu_valid = NULL; + kfree(obj->page_cpu_valid); + obj->page_cpu_valid = NULL; } /** @@ -3306,14 +3256,13 @@ i915_gem_object_set_to_full_cpu_read_domain(struct drm_gem_object *obj) * flushes to occur. */ static int -i915_gem_object_set_cpu_read_domain_range(struct drm_gem_object *obj, +i915_gem_object_set_cpu_read_domain_range(struct drm_i915_gem_object *obj, uint64_t offset, uint64_t size) { - struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); uint32_t old_read_domains; int i, ret; - if (offset == 0 && size == obj->size) + if (offset == 0 && size == obj->base.size) return i915_gem_object_set_to_cpu_domain(obj, 0); ret = i915_gem_object_flush_gpu_write_domain(obj, false); @@ -3322,45 +3271,45 @@ i915_gem_object_set_cpu_read_domain_range(struct drm_gem_object *obj, i915_gem_object_flush_gtt_write_domain(obj); /* If we're already fully in the CPU read domain, we're done. */ - if (obj_priv->page_cpu_valid == NULL && - (obj->read_domains & I915_GEM_DOMAIN_CPU) != 0) + if (obj->page_cpu_valid == NULL && + (obj->base.read_domains & I915_GEM_DOMAIN_CPU) != 0) return 0; /* Otherwise, create/clear the per-page CPU read domain flag if we're * newly adding I915_GEM_DOMAIN_CPU */ - if (obj_priv->page_cpu_valid == NULL) { - obj_priv->page_cpu_valid = kzalloc(obj->size / PAGE_SIZE, - GFP_KERNEL); - if (obj_priv->page_cpu_valid == NULL) + if (obj->page_cpu_valid == NULL) { + obj->page_cpu_valid = kzalloc(obj->base.size / PAGE_SIZE, + GFP_KERNEL); + if (obj->page_cpu_valid == NULL) return -ENOMEM; - } else if ((obj->read_domains & I915_GEM_DOMAIN_CPU) == 0) - memset(obj_priv->page_cpu_valid, 0, obj->size / PAGE_SIZE); + } else if ((obj->base.read_domains & I915_GEM_DOMAIN_CPU) == 0) + memset(obj->page_cpu_valid, 0, obj->base.size / PAGE_SIZE); /* Flush the cache on any pages that are still invalid from the CPU's * perspective. */ for (i = offset / PAGE_SIZE; i <= (offset + size - 1) / PAGE_SIZE; i++) { - if (obj_priv->page_cpu_valid[i]) + if (obj->page_cpu_valid[i]) continue; - drm_clflush_pages(obj_priv->pages + i, 1); + drm_clflush_pages(obj->pages + i, 1); - obj_priv->page_cpu_valid[i] = 1; + obj->page_cpu_valid[i] = 1; } /* It should now be out of any other write domains, and we can update * the domain values for our changes. */ - BUG_ON((obj->write_domain & ~I915_GEM_DOMAIN_CPU) != 0); + BUG_ON((obj->base.write_domain & ~I915_GEM_DOMAIN_CPU) != 0); - old_read_domains = obj->read_domains; - obj->read_domains |= I915_GEM_DOMAIN_CPU; + old_read_domains = obj->base.read_domains; + obj->base.read_domains |= I915_GEM_DOMAIN_CPU; trace_i915_gem_object_change_domain(obj, old_read_domains, - obj->write_domain); + obj->base.write_domain); return 0; } @@ -3490,7 +3439,7 @@ i915_gem_execbuffer_relocate_entry(struct drm_i915_gem_object *obj, uint32_t __iomem *reloc_entry; void __iomem *reloc_page; - ret = i915_gem_object_set_to_gtt_domain(&obj->base, 1); + ret = i915_gem_object_set_to_gtt_domain(obj, 1); if (ret) goto err; @@ -3564,14 +3513,14 @@ i915_gem_execbuffer_relocate_object_slow(struct drm_i915_gem_object *obj, static int i915_gem_execbuffer_relocate(struct drm_device *dev, struct drm_file *file, - struct drm_gem_object **object_list, + struct drm_i915_gem_object **object_list, struct drm_i915_gem_exec_object2 *exec_list, int count) { int i, ret; for (i = 0; i < count; i++) { - struct drm_i915_gem_object *obj = to_intel_bo(object_list[i]); + struct drm_i915_gem_object *obj = object_list[i]; obj->base.pending_read_domains = 0; obj->base.pending_write_domain = 0; ret = i915_gem_execbuffer_relocate_object(obj, file, @@ -3586,7 +3535,7 @@ i915_gem_execbuffer_relocate(struct drm_device *dev, static int i915_gem_execbuffer_reserve(struct drm_device *dev, struct drm_file *file, - struct drm_gem_object **object_list, + struct drm_i915_gem_object **object_list, struct drm_i915_gem_exec_object2 *exec_list, int count) { @@ -3599,7 +3548,7 @@ i915_gem_execbuffer_reserve(struct drm_device *dev, ret = 0; for (i = 0; i < count; i++) { struct drm_i915_gem_exec_object2 *entry = &exec_list[i]; - struct drm_i915_gem_object *obj = to_intel_bo(object_list[i]); + struct drm_i915_gem_object *obj = object_list[i]; bool need_fence = entry->flags & EXEC_OBJECT_NEEDS_FENCE && obj->tiling_mode != I915_TILING_NONE; @@ -3610,12 +3559,12 @@ i915_gem_execbuffer_reserve(struct drm_device *dev, /* Check fence reg constraints and rebind if necessary */ if (need_mappable && !obj->map_and_fenceable) { - ret = i915_gem_object_unbind(&obj->base); + ret = i915_gem_object_unbind(obj); if (ret) break; } - ret = i915_gem_object_pin(&obj->base, + ret = i915_gem_object_pin(obj, entry->alignment, need_mappable); if (ret) @@ -3626,9 +3575,9 @@ i915_gem_execbuffer_reserve(struct drm_device *dev, * to properly handle blits to/from tiled surfaces. */ if (need_fence) { - ret = i915_gem_object_get_fence_reg(&obj->base, true); + ret = i915_gem_object_get_fence_reg(obj, true); if (ret) { - i915_gem_object_unpin(&obj->base); + i915_gem_object_unpin(obj); break; } @@ -3658,17 +3607,15 @@ i915_gem_execbuffer_reserve(struct drm_device *dev, static int i915_gem_execbuffer_relocate_slow(struct drm_device *dev, struct drm_file *file, - struct drm_gem_object **object_list, + struct drm_i915_gem_object **object_list, struct drm_i915_gem_exec_object2 *exec_list, int count) { struct drm_i915_gem_relocation_entry *reloc; int i, total, ret; - for (i = 0; i < count; i++) { - struct drm_i915_gem_object *obj = to_intel_bo(object_list[i]); - obj->in_execbuffer = false; - } + for (i = 0; i < count; i++) + object_list[i]->in_execbuffer = false; mutex_unlock(&dev->struct_mutex); @@ -3713,7 +3660,7 @@ i915_gem_execbuffer_relocate_slow(struct drm_device *dev, total = 0; for (i = 0; i < count; i++) { - struct drm_i915_gem_object *obj = to_intel_bo(object_list[i]); + struct drm_i915_gem_object *obj = object_list[i]; obj->base.pending_read_domains = 0; obj->base.pending_write_domain = 0; ret = i915_gem_execbuffer_relocate_object_slow(obj, file, @@ -3740,7 +3687,7 @@ static int i915_gem_execbuffer_move_to_gpu(struct drm_device *dev, struct drm_file *file, struct intel_ring_buffer *ring, - struct drm_gem_object **objects, + struct drm_i915_gem_object **objects, int count) { struct change_domains cd; @@ -3759,17 +3706,17 @@ i915_gem_execbuffer_move_to_gpu(struct drm_device *dev, cd.invalidate_domains, cd.flush_domains); #endif - i915_gem_flush(dev, file, + i915_gem_flush(dev, cd.invalidate_domains, cd.flush_domains, cd.flush_rings); } for (i = 0; i < count; i++) { - struct drm_i915_gem_object *obj = to_intel_bo(objects[i]); + struct drm_i915_gem_object *obj = objects[i]; /* XXX replace with semaphores */ if (obj->ring && ring != obj->ring) { - ret = i915_gem_object_wait_rendering(&obj->base, true); + ret = i915_gem_object_wait_rendering(obj, true); if (ret) return ret; } @@ -3891,8 +3838,8 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, struct drm_i915_gem_exec_object2 *exec_list) { drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_gem_object **object_list = NULL; - struct drm_gem_object *batch_obj; + struct drm_i915_gem_object **object_list = NULL; + struct drm_i915_gem_object *batch_obj; struct drm_clip_rect *cliprects = NULL; struct drm_i915_gem_request *request = NULL; int ret, i, flips; @@ -3987,29 +3934,29 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, /* Look up object handles */ for (i = 0; i < args->buffer_count; i++) { - struct drm_i915_gem_object *obj_priv; + struct drm_i915_gem_object *obj; - object_list[i] = drm_gem_object_lookup(dev, file, - exec_list[i].handle); - if (object_list[i] == NULL) { + obj = to_intel_bo (drm_gem_object_lookup(dev, file, + exec_list[i].handle)); + if (obj == NULL) { DRM_ERROR("Invalid object handle %d at index %d\n", exec_list[i].handle, i); /* prevent error path from reading uninitialized data */ - args->buffer_count = i + 1; + args->buffer_count = i; ret = -ENOENT; goto err; } + object_list[i] = obj; - obj_priv = to_intel_bo(object_list[i]); - if (obj_priv->in_execbuffer) { + if (obj->in_execbuffer) { DRM_ERROR("Object %p appears more than once in object list\n", - object_list[i]); + obj); /* prevent error path from reading uninitialized data */ args->buffer_count = i + 1; ret = -EINVAL; goto err; } - obj_priv->in_execbuffer = true; + obj->in_execbuffer = true; } /* Move the objects en-masse into the GTT, evicting if necessary. */ @@ -4037,15 +3984,15 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, /* Set the pending read domains for the batch buffer to COMMAND */ batch_obj = object_list[args->buffer_count-1]; - if (batch_obj->pending_write_domain) { + if (batch_obj->base.pending_write_domain) { DRM_ERROR("Attempting to use self-modifying batch buffer\n"); ret = -EINVAL; goto err; } - batch_obj->pending_read_domains |= I915_GEM_DOMAIN_COMMAND; + batch_obj->base.pending_read_domains |= I915_GEM_DOMAIN_COMMAND; /* Sanity check the batch buffer */ - exec_offset = to_intel_bo(batch_obj)->gtt_offset; + exec_offset = batch_obj->gtt_offset; ret = i915_gem_check_execbuffer(args, exec_offset); if (ret != 0) { DRM_ERROR("execbuf with invalid offset/length\n"); @@ -4077,8 +4024,8 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, */ flips = 0; for (i = 0; i < args->buffer_count; i++) { - if (object_list[i]->write_domain) - flips |= atomic_read(&to_intel_bo(object_list[i])->pending_flip); + if (object_list[i]->base.write_domain) + flips |= atomic_read(&object_list[i]->pending_flip); } if (flips) { int plane, flip_mask; @@ -4110,23 +4057,22 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, } for (i = 0; i < args->buffer_count; i++) { - struct drm_gem_object *obj = object_list[i]; + struct drm_i915_gem_object *obj = object_list[i]; - obj->read_domains = obj->pending_read_domains; - obj->write_domain = obj->pending_write_domain; + obj->base.read_domains = obj->base.pending_read_domains; + obj->base.write_domain = obj->base.pending_write_domain; i915_gem_object_move_to_active(obj, ring); - if (obj->write_domain) { - struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); - obj_priv->dirty = 1; - list_move_tail(&obj_priv->gpu_write_list, + if (obj->base.write_domain) { + obj->dirty = 1; + list_move_tail(&obj->gpu_write_list, &ring->gpu_write_list); intel_mark_busy(dev, obj); } trace_i915_gem_object_change_domain(obj, - obj->read_domains, - obj->write_domain); + obj->base.read_domains, + obj->base.write_domain); } /* @@ -4142,11 +4088,8 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, err: for (i = 0; i < args->buffer_count; i++) { - if (object_list[i] == NULL) - break; - - to_intel_bo(object_list[i])->in_execbuffer = false; - drm_gem_object_unreference(object_list[i]); + object_list[i]->in_execbuffer = false; + drm_gem_object_unreference(&object_list[i]->base); } mutex_unlock(&dev->struct_mutex); @@ -4165,7 +4108,7 @@ pre_mutex_err: */ int i915_gem_execbuffer(struct drm_device *dev, void *data, - struct drm_file *file_priv) + struct drm_file *file) { struct drm_i915_gem_execbuffer *args = data; struct drm_i915_gem_execbuffer2 exec2; @@ -4227,7 +4170,7 @@ i915_gem_execbuffer(struct drm_device *dev, void *data, exec2.cliprects_ptr = args->cliprects_ptr; exec2.flags = I915_EXEC_RENDER; - ret = i915_gem_do_execbuffer(dev, data, file_priv, &exec2, exec2_list); + ret = i915_gem_do_execbuffer(dev, data, file, &exec2, exec2_list); if (!ret) { /* Copy the new buffer offsets back to the user's exec list. */ for (i = 0; i < args->buffer_count; i++) @@ -4252,7 +4195,7 @@ i915_gem_execbuffer(struct drm_device *dev, void *data, int i915_gem_execbuffer2(struct drm_device *dev, void *data, - struct drm_file *file_priv) + struct drm_file *file) { struct drm_i915_gem_execbuffer2 *args = data; struct drm_i915_gem_exec_object2 *exec2_list = NULL; @@ -4285,7 +4228,7 @@ i915_gem_execbuffer2(struct drm_device *dev, void *data, return -EFAULT; } - ret = i915_gem_do_execbuffer(dev, data, file_priv, args, exec2_list); + ret = i915_gem_do_execbuffer(dev, data, file, args, exec2_list); if (!ret) { /* Copy the new buffer offsets back to the user's exec list. */ ret = copy_to_user((struct drm_i915_relocation_entry __user *) @@ -4305,109 +4248,106 @@ i915_gem_execbuffer2(struct drm_device *dev, void *data, } int -i915_gem_object_pin(struct drm_gem_object *obj, uint32_t alignment, +i915_gem_object_pin(struct drm_i915_gem_object *obj, + uint32_t alignment, bool map_and_fenceable) { - struct drm_device *dev = obj->dev; + struct drm_device *dev = obj->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); int ret; - BUG_ON(obj_priv->pin_count == DRM_I915_GEM_OBJECT_MAX_PIN_COUNT); + BUG_ON(obj->pin_count == DRM_I915_GEM_OBJECT_MAX_PIN_COUNT); BUG_ON(map_and_fenceable && !map_and_fenceable); WARN_ON(i915_verify_lists(dev)); - if (obj_priv->gtt_space != NULL) { - if ((alignment && obj_priv->gtt_offset & (alignment - 1)) || - (map_and_fenceable && !obj_priv->map_and_fenceable)) { - WARN(obj_priv->pin_count, + if (obj->gtt_space != NULL) { + if ((alignment && obj->gtt_offset & (alignment - 1)) || + (map_and_fenceable && !obj->map_and_fenceable)) { + WARN(obj->pin_count, "bo is already pinned with incorrect alignment:" " offset=%x, req.alignment=%x, req.map_and_fenceable=%d," " obj->map_and_fenceable=%d\n", - obj_priv->gtt_offset, alignment, + obj->gtt_offset, alignment, map_and_fenceable, - obj_priv->map_and_fenceable); + obj->map_and_fenceable); ret = i915_gem_object_unbind(obj); if (ret) return ret; } } - if (obj_priv->gtt_space == NULL) { + if (obj->gtt_space == NULL) { ret = i915_gem_object_bind_to_gtt(obj, alignment, map_and_fenceable); if (ret) return ret; } - if (obj_priv->pin_count++ == 0) { - i915_gem_info_add_pin(dev_priv, obj_priv, map_and_fenceable); - if (!obj_priv->active) - list_move_tail(&obj_priv->mm_list, + if (obj->pin_count++ == 0) { + i915_gem_info_add_pin(dev_priv, obj, map_and_fenceable); + if (!obj->active) + list_move_tail(&obj->mm_list, &dev_priv->mm.pinned_list); } - BUG_ON(!obj_priv->pin_mappable && map_and_fenceable); + BUG_ON(!obj->pin_mappable && map_and_fenceable); WARN_ON(i915_verify_lists(dev)); return 0; } void -i915_gem_object_unpin(struct drm_gem_object *obj) +i915_gem_object_unpin(struct drm_i915_gem_object *obj) { - struct drm_device *dev = obj->dev; + struct drm_device *dev = obj->base.dev; drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); WARN_ON(i915_verify_lists(dev)); - BUG_ON(obj_priv->pin_count == 0); - BUG_ON(obj_priv->gtt_space == NULL); + BUG_ON(obj->pin_count == 0); + BUG_ON(obj->gtt_space == NULL); - if (--obj_priv->pin_count == 0) { - if (!obj_priv->active) - list_move_tail(&obj_priv->mm_list, + if (--obj->pin_count == 0) { + if (!obj->active) + list_move_tail(&obj->mm_list, &dev_priv->mm.inactive_list); - i915_gem_info_remove_pin(dev_priv, obj_priv); + i915_gem_info_remove_pin(dev_priv, obj); } WARN_ON(i915_verify_lists(dev)); } int i915_gem_pin_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) + struct drm_file *file) { struct drm_i915_gem_pin *args = data; - struct drm_gem_object *obj; - struct drm_i915_gem_object *obj_priv; + struct drm_i915_gem_object *obj; int ret; ret = i915_mutex_lock_interruptible(dev); if (ret) return ret; - obj = drm_gem_object_lookup(dev, file_priv, args->handle); + obj = to_intel_bo(drm_gem_object_lookup(dev, file, args->handle)); if (obj == NULL) { ret = -ENOENT; goto unlock; } - obj_priv = to_intel_bo(obj); - if (obj_priv->madv != I915_MADV_WILLNEED) { + if (obj->madv != I915_MADV_WILLNEED) { DRM_ERROR("Attempting to pin a purgeable buffer\n"); ret = -EINVAL; goto out; } - if (obj_priv->pin_filp != NULL && obj_priv->pin_filp != file_priv) { + if (obj->pin_filp != NULL && obj->pin_filp != file) { DRM_ERROR("Already pinned in i915_gem_pin_ioctl(): %d\n", args->handle); ret = -EINVAL; goto out; } - obj_priv->user_pin_count++; - obj_priv->pin_filp = file_priv; - if (obj_priv->user_pin_count == 1) { + obj->user_pin_count++; + obj->pin_filp = file; + if (obj->user_pin_count == 1) { ret = i915_gem_object_pin(obj, args->alignment, true); if (ret) goto out; @@ -4417,9 +4357,9 @@ i915_gem_pin_ioctl(struct drm_device *dev, void *data, * as the X server doesn't manage domains yet */ i915_gem_object_flush_cpu_write_domain(obj); - args->offset = obj_priv->gtt_offset; + args->offset = obj->gtt_offset; out: - drm_gem_object_unreference(obj); + drm_gem_object_unreference(&obj->base); unlock: mutex_unlock(&dev->struct_mutex); return ret; @@ -4427,38 +4367,36 @@ unlock: int i915_gem_unpin_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) + struct drm_file *file) { struct drm_i915_gem_pin *args = data; - struct drm_gem_object *obj; - struct drm_i915_gem_object *obj_priv; + struct drm_i915_gem_object *obj; int ret; ret = i915_mutex_lock_interruptible(dev); if (ret) return ret; - obj = drm_gem_object_lookup(dev, file_priv, args->handle); + obj = to_intel_bo(drm_gem_object_lookup(dev, file, args->handle)); if (obj == NULL) { ret = -ENOENT; goto unlock; } - obj_priv = to_intel_bo(obj); - if (obj_priv->pin_filp != file_priv) { + if (obj->pin_filp != file) { DRM_ERROR("Not pinned by caller in i915_gem_pin_ioctl(): %d\n", args->handle); ret = -EINVAL; goto out; } - obj_priv->user_pin_count--; - if (obj_priv->user_pin_count == 0) { - obj_priv->pin_filp = NULL; + obj->user_pin_count--; + if (obj->user_pin_count == 0) { + obj->pin_filp = NULL; i915_gem_object_unpin(obj); } out: - drm_gem_object_unreference(obj); + drm_gem_object_unreference(&obj->base); unlock: mutex_unlock(&dev->struct_mutex); return ret; @@ -4466,52 +4404,49 @@ unlock: int i915_gem_busy_ioctl(struct drm_device *dev, void *data, - struct drm_file *file_priv) + struct drm_file *file) { struct drm_i915_gem_busy *args = data; - struct drm_gem_object *obj; - struct drm_i915_gem_object *obj_priv; + struct drm_i915_gem_object *obj; int ret; ret = i915_mutex_lock_interruptible(dev); if (ret) return ret; - obj = drm_gem_object_lookup(dev, file_priv, args->handle); + obj = to_intel_bo(drm_gem_object_lookup(dev, file, args->handle)); if (obj == NULL) { ret = -ENOENT; goto unlock; } - obj_priv = to_intel_bo(obj); /* Count all active objects as busy, even if they are currently not used * by the gpu. Users of this interface expect objects to eventually * become non-busy without any further actions, therefore emit any * necessary flushes here. */ - args->busy = obj_priv->active; + args->busy = obj->active; if (args->busy) { /* Unconditionally flush objects, even when the gpu still uses this * object. Userspace calling this function indicates that it wants to * use this buffer rather sooner than later, so issuing the required * flush earlier is beneficial. */ - if (obj->write_domain & I915_GEM_GPU_DOMAINS) - i915_gem_flush_ring(dev, file_priv, - obj_priv->ring, - 0, obj->write_domain); + if (obj->base.write_domain & I915_GEM_GPU_DOMAINS) + i915_gem_flush_ring(dev, obj->ring, + 0, obj->base.write_domain); /* Update the active list for the hardware's current position. * Otherwise this only updates on a delayed timer or when irqs * are actually unmasked, and our working set ends up being * larger than required. */ - i915_gem_retire_requests_ring(dev, obj_priv->ring); + i915_gem_retire_requests_ring(dev, obj->ring); - args->busy = obj_priv->active; + args->busy = obj->active; } - drm_gem_object_unreference(obj); + drm_gem_object_unreference(&obj->base); unlock: mutex_unlock(&dev->struct_mutex); return ret; @@ -4529,8 +4464,7 @@ i915_gem_madvise_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv) { struct drm_i915_gem_madvise *args = data; - struct drm_gem_object *obj; - struct drm_i915_gem_object *obj_priv; + struct drm_i915_gem_object *obj; int ret; switch (args->madv) { @@ -4545,37 +4479,36 @@ i915_gem_madvise_ioctl(struct drm_device *dev, void *data, if (ret) return ret; - obj = drm_gem_object_lookup(dev, file_priv, args->handle); + obj = to_intel_bo(drm_gem_object_lookup(dev, file_priv, args->handle)); if (obj == NULL) { ret = -ENOENT; goto unlock; } - obj_priv = to_intel_bo(obj); - if (obj_priv->pin_count) { + if (obj->pin_count) { ret = -EINVAL; goto out; } - if (obj_priv->madv != __I915_MADV_PURGED) - obj_priv->madv = args->madv; + if (obj->madv != __I915_MADV_PURGED) + obj->madv = args->madv; /* if the object is no longer bound, discard its backing storage */ - if (i915_gem_object_is_purgeable(obj_priv) && - obj_priv->gtt_space == NULL) + if (i915_gem_object_is_purgeable(obj) && + obj->gtt_space == NULL) i915_gem_object_truncate(obj); - args->retained = obj_priv->madv != __I915_MADV_PURGED; + args->retained = obj->madv != __I915_MADV_PURGED; out: - drm_gem_object_unreference(obj); + drm_gem_object_unreference(&obj->base); unlock: mutex_unlock(&dev->struct_mutex); return ret; } -struct drm_gem_object * i915_gem_alloc_object(struct drm_device *dev, - size_t size) +struct drm_i915_gem_object *i915_gem_alloc_object(struct drm_device *dev, + size_t size) { struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_gem_object *obj; @@ -4605,7 +4538,7 @@ struct drm_gem_object * i915_gem_alloc_object(struct drm_device *dev, /* Avoid an unnecessary call to unbind on the first bind. */ obj->map_and_fenceable = true; - return &obj->base; + return obj; } int i915_gem_init_object(struct drm_gem_object *obj) @@ -4615,42 +4548,41 @@ int i915_gem_init_object(struct drm_gem_object *obj) return 0; } -static void i915_gem_free_object_tail(struct drm_gem_object *obj) +static void i915_gem_free_object_tail(struct drm_i915_gem_object *obj) { - struct drm_device *dev = obj->dev; + struct drm_device *dev = obj->base.dev; drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); int ret; ret = i915_gem_object_unbind(obj); if (ret == -ERESTARTSYS) { - list_move(&obj_priv->mm_list, + list_move(&obj->mm_list, &dev_priv->mm.deferred_free_list); return; } - if (obj->map_list.map) + if (obj->base.map_list.map) i915_gem_free_mmap_offset(obj); - drm_gem_object_release(obj); - i915_gem_info_remove_obj(dev_priv, obj->size); + drm_gem_object_release(&obj->base); + i915_gem_info_remove_obj(dev_priv, obj->base.size); - kfree(obj_priv->page_cpu_valid); - kfree(obj_priv->bit_17); - kfree(obj_priv); + kfree(obj->page_cpu_valid); + kfree(obj->bit_17); + kfree(obj); } -void i915_gem_free_object(struct drm_gem_object *obj) +void i915_gem_free_object(struct drm_gem_object *gem_obj) { - struct drm_device *dev = obj->dev; - struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); + struct drm_i915_gem_object *obj = to_intel_bo(gem_obj); + struct drm_device *dev = obj->base.dev; trace_i915_gem_object_destroy(obj); - while (obj_priv->pin_count > 0) + while (obj->pin_count > 0) i915_gem_object_unpin(obj); - if (obj_priv->phys_obj) + if (obj->phys_obj) i915_gem_detach_phys_object(dev, obj); i915_gem_free_object_tail(obj); @@ -4710,8 +4642,7 @@ static int i915_gem_init_pipe_control(struct drm_device *dev) { drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_gem_object *obj; - struct drm_i915_gem_object *obj_priv; + struct drm_i915_gem_object *obj; int ret; obj = i915_gem_alloc_object(dev, 4096); @@ -4720,15 +4651,14 @@ i915_gem_init_pipe_control(struct drm_device *dev) ret = -ENOMEM; goto err; } - obj_priv = to_intel_bo(obj); - obj_priv->agp_type = AGP_USER_CACHED_MEMORY; + obj->agp_type = AGP_USER_CACHED_MEMORY; ret = i915_gem_object_pin(obj, 4096, true); if (ret) goto err_unref; - dev_priv->seqno_gfx_addr = obj_priv->gtt_offset; - dev_priv->seqno_page = kmap(obj_priv->pages[0]); + dev_priv->seqno_gfx_addr = obj->gtt_offset; + dev_priv->seqno_page = kmap(obj->pages[0]); if (dev_priv->seqno_page == NULL) goto err_unpin; @@ -4740,7 +4670,7 @@ i915_gem_init_pipe_control(struct drm_device *dev) err_unpin: i915_gem_object_unpin(obj); err_unref: - drm_gem_object_unreference(obj); + drm_gem_object_unreference(&obj->base); err: return ret; } @@ -4750,14 +4680,12 @@ static void i915_gem_cleanup_pipe_control(struct drm_device *dev) { drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_gem_object *obj; - struct drm_i915_gem_object *obj_priv; + struct drm_i915_gem_object *obj; obj = dev_priv->seqno_obj; - obj_priv = to_intel_bo(obj); - kunmap(obj_priv->pages[0]); + kunmap(obj->pages[0]); i915_gem_object_unpin(obj); - drm_gem_object_unreference(obj); + drm_gem_object_unreference(&obj->base); dev_priv->seqno_obj = NULL; dev_priv->seqno_page = NULL; @@ -5035,20 +4963,18 @@ void i915_gem_free_all_phys_object(struct drm_device *dev) } void i915_gem_detach_phys_object(struct drm_device *dev, - struct drm_gem_object *obj) + struct drm_i915_gem_object *obj) { - struct address_space *mapping = obj->filp->f_path.dentry->d_inode->i_mapping; - struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); + struct address_space *mapping = obj->base.filp->f_path.dentry->d_inode->i_mapping; char *vaddr; int i; int page_count; - if (!obj_priv->phys_obj) + if (!obj->phys_obj) return; - vaddr = obj_priv->phys_obj->handle->vaddr; - - page_count = obj->size / PAGE_SIZE; + vaddr = obj->phys_obj->handle->vaddr; + page_count = obj->base.size / PAGE_SIZE; for (i = 0; i < page_count; i++) { struct page *page = read_cache_page_gfp(mapping, i, GFP_HIGHUSER | __GFP_RECLAIMABLE); @@ -5066,19 +4992,18 @@ void i915_gem_detach_phys_object(struct drm_device *dev, } intel_gtt_chipset_flush(); - obj_priv->phys_obj->cur_obj = NULL; - obj_priv->phys_obj = NULL; + obj->phys_obj->cur_obj = NULL; + obj->phys_obj = NULL; } int i915_gem_attach_phys_object(struct drm_device *dev, - struct drm_gem_object *obj, + struct drm_i915_gem_object *obj, int id, int align) { - struct address_space *mapping = obj->filp->f_path.dentry->d_inode->i_mapping; + struct address_space *mapping = obj->base.filp->f_path.dentry->d_inode->i_mapping; drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_i915_gem_object *obj_priv; int ret = 0; int page_count; int i; @@ -5086,10 +5011,8 @@ i915_gem_attach_phys_object(struct drm_device *dev, if (id > I915_MAX_PHYS_OBJECT) return -EINVAL; - obj_priv = to_intel_bo(obj); - - if (obj_priv->phys_obj) { - if (obj_priv->phys_obj->id == id) + if (obj->phys_obj) { + if (obj->phys_obj->id == id) return 0; i915_gem_detach_phys_object(dev, obj); } @@ -5097,18 +5020,19 @@ i915_gem_attach_phys_object(struct drm_device *dev, /* create a new object */ if (!dev_priv->mm.phys_objs[id - 1]) { ret = i915_gem_init_phys_object(dev, id, - obj->size, align); + obj->base.size, align); if (ret) { - DRM_ERROR("failed to init phys object %d size: %zu\n", id, obj->size); + DRM_ERROR("failed to init phys object %d size: %zu\n", + id, obj->base.size); return ret; } } /* bind to the object */ - obj_priv->phys_obj = dev_priv->mm.phys_objs[id - 1]; - obj_priv->phys_obj->cur_obj = obj; + obj->phys_obj = dev_priv->mm.phys_objs[id - 1]; + obj->phys_obj->cur_obj = obj; - page_count = obj->size / PAGE_SIZE; + page_count = obj->base.size / PAGE_SIZE; for (i = 0; i < page_count; i++) { struct page *page; @@ -5120,7 +5044,7 @@ i915_gem_attach_phys_object(struct drm_device *dev, return PTR_ERR(page); src = kmap_atomic(page); - dst = obj_priv->phys_obj->handle->vaddr + (i * PAGE_SIZE); + dst = obj->phys_obj->handle->vaddr + (i * PAGE_SIZE); memcpy(dst, src, PAGE_SIZE); kunmap_atomic(src); @@ -5132,16 +5056,14 @@ i915_gem_attach_phys_object(struct drm_device *dev, } static int -i915_gem_phys_pwrite(struct drm_device *dev, struct drm_gem_object *obj, +i915_gem_phys_pwrite(struct drm_device *dev, + struct drm_i915_gem_object *obj, struct drm_i915_gem_pwrite *args, struct drm_file *file_priv) { - struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); - void *vaddr = obj_priv->phys_obj->handle->vaddr + args->offset; + void *vaddr = obj->phys_obj->handle->vaddr + args->offset; char __user *user_data = (char __user *) (uintptr_t) args->data_ptr; - DRM_DEBUG_DRIVER("vaddr %p, %lld\n", vaddr, args->size); - if (__copy_from_user_inatomic_nocache(vaddr, user_data, args->size)) { unsigned long unwritten; @@ -5228,7 +5150,7 @@ rescan: &dev_priv->mm.inactive_list, mm_list) { if (i915_gem_object_is_purgeable(obj)) { - i915_gem_object_unbind(&obj->base); + i915_gem_object_unbind(obj); if (--nr_to_scan == 0) break; } @@ -5240,7 +5162,7 @@ rescan: &dev_priv->mm.inactive_list, mm_list) { if (nr_to_scan) { - i915_gem_object_unbind(&obj->base); + i915_gem_object_unbind(obj); nr_to_scan--; } else cnt++; diff --git a/drivers/gpu/drm/i915/i915_gem_debug.c b/drivers/gpu/drm/i915/i915_gem_debug.c index 48644b840a8d..29d014c48ca2 100644 --- a/drivers/gpu/drm/i915/i915_gem_debug.c +++ b/drivers/gpu/drm/i915/i915_gem_debug.c @@ -152,13 +152,12 @@ i915_gem_dump_page(struct page *page, uint32_t start, uint32_t end, } void -i915_gem_dump_object(struct drm_gem_object *obj, int len, +i915_gem_dump_object(struct drm_i915_gem_object *obj, int len, const char *where, uint32_t mark) { - struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); int page; - DRM_INFO("%s: object at offset %08x\n", where, obj_priv->gtt_offset); + DRM_INFO("%s: object at offset %08x\n", where, obj->gtt_offset); for (page = 0; page < (len + PAGE_SIZE-1) / PAGE_SIZE; page++) { int page_len, chunk, chunk_len; @@ -170,9 +169,9 @@ i915_gem_dump_object(struct drm_gem_object *obj, int len, chunk_len = page_len - chunk; if (chunk_len > 128) chunk_len = 128; - i915_gem_dump_page(obj_priv->pages[page], + i915_gem_dump_page(obj->pages[page], chunk, chunk + chunk_len, - obj_priv->gtt_offset + + obj->gtt_offset + page * PAGE_SIZE, mark); } @@ -182,21 +181,19 @@ i915_gem_dump_object(struct drm_gem_object *obj, int len, #if WATCH_COHERENCY void -i915_gem_object_check_coherency(struct drm_gem_object *obj, int handle) +i915_gem_object_check_coherency(struct drm_i915_gem_object *obj, int handle) { - struct drm_device *dev = obj->dev; - struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); + struct drm_device *dev = obj->base.dev; int page; uint32_t *gtt_mapping; uint32_t *backing_map = NULL; int bad_count = 0; DRM_INFO("%s: checking coherency of object %p@0x%08x (%d, %zdkb):\n", - __func__, obj, obj_priv->gtt_offset, handle, + __func__, obj, obj->gtt_offset, handle, obj->size / 1024); - gtt_mapping = ioremap(dev->agp->base + obj_priv->gtt_offset, - obj->size); + gtt_mapping = ioremap(dev->agp->base + obj->gtt_offset, obj->base.size); if (gtt_mapping == NULL) { DRM_ERROR("failed to map GTT space\n"); return; @@ -205,7 +202,7 @@ i915_gem_object_check_coherency(struct drm_gem_object *obj, int handle) for (page = 0; page < obj->size / PAGE_SIZE; page++) { int i; - backing_map = kmap_atomic(obj_priv->pages[page], KM_USER0); + backing_map = kmap_atomic(obj->pages[page], KM_USER0); if (backing_map == NULL) { DRM_ERROR("failed to map backing page\n"); @@ -220,7 +217,7 @@ i915_gem_object_check_coherency(struct drm_gem_object *obj, int handle) if (cpuval != gttval) { DRM_INFO("incoherent CPU vs GPU at 0x%08x: " "0x%08x vs 0x%08x\n", - (int)(obj_priv->gtt_offset + + (int)(obj->gtt_offset + page * PAGE_SIZE + i * 4), cpuval, gttval); if (bad_count++ >= 8) { diff --git a/drivers/gpu/drm/i915/i915_gem_evict.c b/drivers/gpu/drm/i915/i915_gem_evict.c index 3f6f336bbb4d..03e15d37b550 100644 --- a/drivers/gpu/drm/i915/i915_gem_evict.c +++ b/drivers/gpu/drm/i915/i915_gem_evict.c @@ -32,12 +32,11 @@ #include "i915_drm.h" static bool -mark_free(struct drm_i915_gem_object *obj_priv, - struct list_head *unwind) +mark_free(struct drm_i915_gem_object *obj, struct list_head *unwind) { - list_add(&obj_priv->evict_list, unwind); - drm_gem_object_reference(&obj_priv->base); - return drm_mm_scan_add_block(obj_priv->gtt_space); + list_add(&obj->evict_list, unwind); + drm_gem_object_reference(&obj->base); + return drm_mm_scan_add_block(obj->gtt_space); } int @@ -46,7 +45,7 @@ i915_gem_evict_something(struct drm_device *dev, int min_size, { drm_i915_private_t *dev_priv = dev->dev_private; struct list_head eviction_list, unwind_list; - struct drm_i915_gem_object *obj_priv; + struct drm_i915_gem_object *obj; int ret = 0; i915_gem_retire_requests(dev); @@ -96,42 +95,42 @@ i915_gem_evict_something(struct drm_device *dev, int min_size, drm_mm_init_scan(&dev_priv->mm.gtt_space, min_size, alignment); /* First see if there is a large enough contiguous idle region... */ - list_for_each_entry(obj_priv, &dev_priv->mm.inactive_list, mm_list) { - if (mark_free(obj_priv, &unwind_list)) + list_for_each_entry(obj, &dev_priv->mm.inactive_list, mm_list) { + if (mark_free(obj, &unwind_list)) goto found; } /* Now merge in the soon-to-be-expired objects... */ - list_for_each_entry(obj_priv, &dev_priv->mm.active_list, mm_list) { + list_for_each_entry(obj, &dev_priv->mm.active_list, mm_list) { /* Does the object require an outstanding flush? */ - if (obj_priv->base.write_domain || obj_priv->pin_count) + if (obj->base.write_domain || obj->pin_count) continue; - if (mark_free(obj_priv, &unwind_list)) + if (mark_free(obj, &unwind_list)) goto found; } /* Finally add anything with a pending flush (in order of retirement) */ - list_for_each_entry(obj_priv, &dev_priv->mm.flushing_list, mm_list) { - if (obj_priv->pin_count) + list_for_each_entry(obj, &dev_priv->mm.flushing_list, mm_list) { + if (obj->pin_count) continue; - if (mark_free(obj_priv, &unwind_list)) + if (mark_free(obj, &unwind_list)) goto found; } - list_for_each_entry(obj_priv, &dev_priv->mm.active_list, mm_list) { - if (! obj_priv->base.write_domain || obj_priv->pin_count) + list_for_each_entry(obj, &dev_priv->mm.active_list, mm_list) { + if (! obj->base.write_domain || obj->pin_count) continue; - if (mark_free(obj_priv, &unwind_list)) + if (mark_free(obj, &unwind_list)) goto found; } /* Nothing found, clean up and bail out! */ - list_for_each_entry(obj_priv, &unwind_list, evict_list) { - ret = drm_mm_scan_remove_block(obj_priv->gtt_space); + list_for_each_entry(obj, &unwind_list, evict_list) { + ret = drm_mm_scan_remove_block(obj->gtt_space); BUG_ON(ret); - drm_gem_object_unreference(&obj_priv->base); + drm_gem_object_unreference(&obj->base); } /* We expect the caller to unpin, evict all and try again, or give up. @@ -145,26 +144,26 @@ found: * temporary list. */ INIT_LIST_HEAD(&eviction_list); while (!list_empty(&unwind_list)) { - obj_priv = list_first_entry(&unwind_list, - struct drm_i915_gem_object, - evict_list); - if (drm_mm_scan_remove_block(obj_priv->gtt_space)) { - list_move(&obj_priv->evict_list, &eviction_list); + obj = list_first_entry(&unwind_list, + struct drm_i915_gem_object, + evict_list); + if (drm_mm_scan_remove_block(obj->gtt_space)) { + list_move(&obj->evict_list, &eviction_list); continue; } - list_del(&obj_priv->evict_list); - drm_gem_object_unreference(&obj_priv->base); + list_del(&obj->evict_list); + drm_gem_object_unreference(&obj->base); } /* Unbinding will emit any required flushes */ while (!list_empty(&eviction_list)) { - obj_priv = list_first_entry(&eviction_list, - struct drm_i915_gem_object, - evict_list); + obj = list_first_entry(&eviction_list, + struct drm_i915_gem_object, + evict_list); if (ret == 0) - ret = i915_gem_object_unbind(&obj_priv->base); - list_del(&obj_priv->evict_list); - drm_gem_object_unreference(&obj_priv->base); + ret = i915_gem_object_unbind(obj); + list_del(&obj->evict_list); + drm_gem_object_unreference(&obj->base); } return ret; @@ -203,7 +202,7 @@ i915_gem_evict_inactive(struct drm_device *dev, bool purgeable_only) list_for_each_entry_safe(obj, next, &dev_priv->mm.inactive_list, mm_list) { if (!purgeable_only || obj->madv != I915_MADV_WILLNEED) { - int ret = i915_gem_object_unbind(&obj->base); + int ret = i915_gem_object_unbind(obj); if (ret) return ret; } diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index 0b34a1aee9b6..71c2b0f3747b 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -32,71 +32,67 @@ void i915_gem_restore_gtt_mappings(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; - struct drm_i915_gem_object *obj_priv; + struct drm_i915_gem_object *obj; - list_for_each_entry(obj_priv, - &dev_priv->mm.gtt_list, - gtt_list) { + list_for_each_entry(obj, &dev_priv->mm.gtt_list, gtt_list) { if (dev_priv->mm.gtt->needs_dmar) { - BUG_ON(!obj_priv->sg_list); + BUG_ON(!obj->sg_list); - intel_gtt_insert_sg_entries(obj_priv->sg_list, - obj_priv->num_sg, - obj_priv->gtt_space->start + intel_gtt_insert_sg_entries(obj->sg_list, + obj->num_sg, + obj->gtt_space->start >> PAGE_SHIFT, - obj_priv->agp_type); + obj->agp_type); } else - intel_gtt_insert_pages(obj_priv->gtt_space->start + intel_gtt_insert_pages(obj->gtt_space->start >> PAGE_SHIFT, - obj_priv->base.size >> PAGE_SHIFT, - obj_priv->pages, - obj_priv->agp_type); + obj->base.size >> PAGE_SHIFT, + obj->pages, + obj->agp_type); } /* Be paranoid and flush the chipset cache. */ intel_gtt_chipset_flush(); } -int i915_gem_gtt_bind_object(struct drm_gem_object *obj) +int i915_gem_gtt_bind_object(struct drm_i915_gem_object *obj) { - struct drm_device *dev = obj->dev; + struct drm_device *dev = obj->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); int ret; if (dev_priv->mm.gtt->needs_dmar) { - ret = intel_gtt_map_memory(obj_priv->pages, - obj->size >> PAGE_SHIFT, - &obj_priv->sg_list, - &obj_priv->num_sg); + ret = intel_gtt_map_memory(obj->pages, + obj->base.size >> PAGE_SHIFT, + &obj->sg_list, + &obj->num_sg); if (ret != 0) return ret; - intel_gtt_insert_sg_entries(obj_priv->sg_list, obj_priv->num_sg, - obj_priv->gtt_space->start - >> PAGE_SHIFT, - obj_priv->agp_type); + intel_gtt_insert_sg_entries(obj->sg_list, + obj->num_sg, + obj->gtt_space->start >> PAGE_SHIFT, + obj->agp_type); } else - intel_gtt_insert_pages(obj_priv->gtt_space->start >> PAGE_SHIFT, - obj->size >> PAGE_SHIFT, - obj_priv->pages, - obj_priv->agp_type); + intel_gtt_insert_pages(obj->gtt_space->start >> PAGE_SHIFT, + obj->base.size >> PAGE_SHIFT, + obj->pages, + obj->agp_type); return 0; } -void i915_gem_gtt_unbind_object(struct drm_gem_object *obj) +void i915_gem_gtt_unbind_object(struct drm_i915_gem_object *obj) { - struct drm_device *dev = obj->dev; + struct drm_device *dev = obj->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); if (dev_priv->mm.gtt->needs_dmar) { - intel_gtt_unmap_memory(obj_priv->sg_list, obj_priv->num_sg); - obj_priv->sg_list = NULL; - obj_priv->num_sg = 0; + intel_gtt_unmap_memory(obj->sg_list, obj->num_sg); + obj->sg_list = NULL; + obj->num_sg = 0; } - intel_gtt_clear_range(obj_priv->gtt_space->start >> PAGE_SHIFT, - obj->size >> PAGE_SHIFT); + intel_gtt_clear_range(obj->gtt_space->start >> PAGE_SHIFT, + obj->base.size >> PAGE_SHIFT); } diff --git a/drivers/gpu/drm/i915/i915_gem_tiling.c b/drivers/gpu/drm/i915/i915_gem_tiling.c index a517b48d441d..1c5fdb30f272 100644 --- a/drivers/gpu/drm/i915/i915_gem_tiling.c +++ b/drivers/gpu/drm/i915/i915_gem_tiling.c @@ -234,25 +234,24 @@ i915_tiling_ok(struct drm_device *dev, int stride, int size, int tiling_mode) /* Is the current GTT allocation valid for the change in tiling? */ static bool -i915_gem_object_fence_ok(struct drm_gem_object *obj, int tiling_mode) +i915_gem_object_fence_ok(struct drm_i915_gem_object *obj, int tiling_mode) { - struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); u32 size; if (tiling_mode == I915_TILING_NONE) return true; - if (INTEL_INFO(obj->dev)->gen >= 4) + if (INTEL_INFO(obj->base.dev)->gen >= 4) return true; - if (!obj_priv->gtt_space) + if (!obj->gtt_space) return true; - if (INTEL_INFO(obj->dev)->gen == 3) { - if (obj_priv->gtt_offset & ~I915_FENCE_START_MASK) + if (INTEL_INFO(obj->base.dev)->gen == 3) { + if (obj->gtt_offset & ~I915_FENCE_START_MASK) return false; } else { - if (obj_priv->gtt_offset & ~I830_FENCE_START_MASK) + if (obj->gtt_offset & ~I830_FENCE_START_MASK) return false; } @@ -260,18 +259,18 @@ i915_gem_object_fence_ok(struct drm_gem_object *obj, int tiling_mode) * Previous chips need to be aligned to the size of the smallest * fence register that can contain the object. */ - if (INTEL_INFO(obj->dev)->gen == 3) + if (INTEL_INFO(obj->base.dev)->gen == 3) size = 1024*1024; else size = 512*1024; - while (size < obj_priv->base.size) + while (size < obj->base.size) size <<= 1; - if (obj_priv->gtt_space->size != size) + if (obj->gtt_space->size != size) return false; - if (obj_priv->gtt_offset & (size - 1)) + if (obj->gtt_offset & (size - 1)) return false; return true; @@ -283,30 +282,29 @@ i915_gem_object_fence_ok(struct drm_gem_object *obj, int tiling_mode) */ int i915_gem_set_tiling(struct drm_device *dev, void *data, - struct drm_file *file_priv) + struct drm_file *file) { struct drm_i915_gem_set_tiling *args = data; drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_gem_object *obj; - struct drm_i915_gem_object *obj_priv; + struct drm_i915_gem_object *obj; int ret; ret = i915_gem_check_is_wedged(dev); if (ret) return ret; - obj = drm_gem_object_lookup(dev, file_priv, args->handle); + obj = to_intel_bo(drm_gem_object_lookup(dev, file, args->handle)); if (obj == NULL) return -ENOENT; - obj_priv = to_intel_bo(obj); - if (!i915_tiling_ok(dev, args->stride, obj->size, args->tiling_mode)) { - drm_gem_object_unreference_unlocked(obj); + if (!i915_tiling_ok(dev, + args->stride, obj->base.size, args->tiling_mode)) { + drm_gem_object_unreference_unlocked(&obj->base); return -EINVAL; } - if (obj_priv->pin_count) { - drm_gem_object_unreference_unlocked(obj); + if (obj->pin_count) { + drm_gem_object_unreference_unlocked(&obj->base); return -EBUSY; } @@ -340,8 +338,8 @@ i915_gem_set_tiling(struct drm_device *dev, void *data, } mutex_lock(&dev->struct_mutex); - if (args->tiling_mode != obj_priv->tiling_mode || - args->stride != obj_priv->stride) { + if (args->tiling_mode != obj->tiling_mode || + args->stride != obj->stride) { /* We need to rebind the object if its current allocation * no longer meets the alignment restrictions for its new * tiling mode. Otherwise we can just leave it alone, but @@ -349,22 +347,22 @@ i915_gem_set_tiling(struct drm_device *dev, void *data, */ if (!i915_gem_object_fence_ok(obj, args->tiling_mode)) ret = i915_gem_object_unbind(obj); - else if (obj_priv->fence_reg != I915_FENCE_REG_NONE) + else if (obj->fence_reg != I915_FENCE_REG_NONE) ret = i915_gem_object_put_fence_reg(obj, true); else i915_gem_release_mmap(obj); if (ret != 0) { - args->tiling_mode = obj_priv->tiling_mode; - args->stride = obj_priv->stride; + args->tiling_mode = obj->tiling_mode; + args->stride = obj->stride; goto err; } - obj_priv->tiling_mode = args->tiling_mode; - obj_priv->stride = args->stride; + obj->tiling_mode = args->tiling_mode; + obj->stride = args->stride; } err: - drm_gem_object_unreference(obj); + drm_gem_object_unreference(&obj->base); mutex_unlock(&dev->struct_mutex); return ret; @@ -375,22 +373,20 @@ err: */ int i915_gem_get_tiling(struct drm_device *dev, void *data, - struct drm_file *file_priv) + struct drm_file *file) { struct drm_i915_gem_get_tiling *args = data; drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_gem_object *obj; - struct drm_i915_gem_object *obj_priv; + struct drm_i915_gem_object *obj; - obj = drm_gem_object_lookup(dev, file_priv, args->handle); + obj = to_intel_bo(drm_gem_object_lookup(dev, file, args->handle)); if (obj == NULL) return -ENOENT; - obj_priv = to_intel_bo(obj); mutex_lock(&dev->struct_mutex); - args->tiling_mode = obj_priv->tiling_mode; - switch (obj_priv->tiling_mode) { + args->tiling_mode = obj->tiling_mode; + switch (obj->tiling_mode) { case I915_TILING_X: args->swizzle_mode = dev_priv->mm.bit_6_swizzle_x; break; @@ -410,7 +406,7 @@ i915_gem_get_tiling(struct drm_device *dev, void *data, if (args->swizzle_mode == I915_BIT_6_SWIZZLE_9_10_17) args->swizzle_mode = I915_BIT_6_SWIZZLE_9_10; - drm_gem_object_unreference(obj); + drm_gem_object_unreference(&obj->base); mutex_unlock(&dev->struct_mutex); return 0; @@ -440,46 +436,44 @@ i915_gem_swizzle_page(struct page *page) } void -i915_gem_object_do_bit_17_swizzle(struct drm_gem_object *obj) +i915_gem_object_do_bit_17_swizzle(struct drm_i915_gem_object *obj) { - struct drm_device *dev = obj->dev; + struct drm_device *dev = obj->base.dev; drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); - int page_count = obj->size >> PAGE_SHIFT; + int page_count = obj->base.size >> PAGE_SHIFT; int i; if (dev_priv->mm.bit_6_swizzle_x != I915_BIT_6_SWIZZLE_9_10_17) return; - if (obj_priv->bit_17 == NULL) + if (obj->bit_17 == NULL) return; for (i = 0; i < page_count; i++) { - char new_bit_17 = page_to_phys(obj_priv->pages[i]) >> 17; + char new_bit_17 = page_to_phys(obj->pages[i]) >> 17; if ((new_bit_17 & 0x1) != - (test_bit(i, obj_priv->bit_17) != 0)) { - i915_gem_swizzle_page(obj_priv->pages[i]); - set_page_dirty(obj_priv->pages[i]); + (test_bit(i, obj->bit_17) != 0)) { + i915_gem_swizzle_page(obj->pages[i]); + set_page_dirty(obj->pages[i]); } } } void -i915_gem_object_save_bit_17_swizzle(struct drm_gem_object *obj) +i915_gem_object_save_bit_17_swizzle(struct drm_i915_gem_object *obj) { - struct drm_device *dev = obj->dev; + struct drm_device *dev = obj->base.dev; drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); - int page_count = obj->size >> PAGE_SHIFT; + int page_count = obj->base.size >> PAGE_SHIFT; int i; if (dev_priv->mm.bit_6_swizzle_x != I915_BIT_6_SWIZZLE_9_10_17) return; - if (obj_priv->bit_17 == NULL) { - obj_priv->bit_17 = kmalloc(BITS_TO_LONGS(page_count) * + if (obj->bit_17 == NULL) { + obj->bit_17 = kmalloc(BITS_TO_LONGS(page_count) * sizeof(long), GFP_KERNEL); - if (obj_priv->bit_17 == NULL) { + if (obj->bit_17 == NULL) { DRM_ERROR("Failed to allocate memory for bit 17 " "record\n"); return; @@ -487,9 +481,9 @@ i915_gem_object_save_bit_17_swizzle(struct drm_gem_object *obj) } for (i = 0; i < page_count; i++) { - if (page_to_phys(obj_priv->pages[i]) & (1 << 17)) - __set_bit(i, obj_priv->bit_17); + if (page_to_phys(obj->pages[i]) & (1 << 17)) + __set_bit(i, obj->bit_17); else - __clear_bit(i, obj_priv->bit_17); + __clear_bit(i, obj->bit_17); } } diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index a8f55f061f6d..09ac3bbd8165 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -423,28 +423,23 @@ static void i915_error_work_func(struct work_struct *work) #ifdef CONFIG_DEBUG_FS static struct drm_i915_error_object * i915_error_object_create(struct drm_device *dev, - struct drm_gem_object *src) + struct drm_i915_gem_object *src) { drm_i915_private_t *dev_priv = dev->dev_private; struct drm_i915_error_object *dst; - struct drm_i915_gem_object *src_priv; int page, page_count; u32 reloc_offset; - if (src == NULL) + if (src == NULL || src->pages == NULL) return NULL; - src_priv = to_intel_bo(src); - if (src_priv->pages == NULL) - return NULL; - - page_count = src->size / PAGE_SIZE; + page_count = src->base.size / PAGE_SIZE; dst = kmalloc(sizeof(*dst) + page_count * sizeof (u32 *), GFP_ATOMIC); if (dst == NULL) return NULL; - reloc_offset = src_priv->gtt_offset; + reloc_offset = src->gtt_offset; for (page = 0; page < page_count; page++) { unsigned long flags; void __iomem *s; @@ -466,7 +461,7 @@ i915_error_object_create(struct drm_device *dev, reloc_offset += PAGE_SIZE; } dst->page_count = page_count; - dst->gtt_offset = src_priv->gtt_offset; + dst->gtt_offset = src->gtt_offset; return dst; @@ -598,9 +593,9 @@ static u32 capture_bo_list(struct drm_i915_error_buffer *err, static void i915_capture_error_state(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; - struct drm_i915_gem_object *obj_priv; + struct drm_i915_gem_object *obj; struct drm_i915_error_state *error; - struct drm_gem_object *batchbuffer[2]; + struct drm_i915_gem_object *batchbuffer[2]; unsigned long flags; u32 bbaddr; int count; @@ -668,34 +663,30 @@ static void i915_capture_error_state(struct drm_device *dev) batchbuffer[0] = NULL; batchbuffer[1] = NULL; count = 0; - list_for_each_entry(obj_priv, &dev_priv->mm.active_list, mm_list) { - struct drm_gem_object *obj = &obj_priv->base; - + list_for_each_entry(obj, &dev_priv->mm.active_list, mm_list) { if (batchbuffer[0] == NULL && - bbaddr >= obj_priv->gtt_offset && - bbaddr < obj_priv->gtt_offset + obj->size) + bbaddr >= obj->gtt_offset && + bbaddr < obj->gtt_offset + obj->base.size) batchbuffer[0] = obj; if (batchbuffer[1] == NULL && - error->acthd >= obj_priv->gtt_offset && - error->acthd < obj_priv->gtt_offset + obj->size) + error->acthd >= obj->gtt_offset && + error->acthd < obj->gtt_offset + obj->base.size) batchbuffer[1] = obj; count++; } /* Scan the other lists for completeness for those bizarre errors. */ if (batchbuffer[0] == NULL || batchbuffer[1] == NULL) { - list_for_each_entry(obj_priv, &dev_priv->mm.flushing_list, mm_list) { - struct drm_gem_object *obj = &obj_priv->base; - + list_for_each_entry(obj, &dev_priv->mm.flushing_list, mm_list) { if (batchbuffer[0] == NULL && - bbaddr >= obj_priv->gtt_offset && - bbaddr < obj_priv->gtt_offset + obj->size) + bbaddr >= obj->gtt_offset && + bbaddr < obj->gtt_offset + obj->base.size) batchbuffer[0] = obj; if (batchbuffer[1] == NULL && - error->acthd >= obj_priv->gtt_offset && - error->acthd < obj_priv->gtt_offset + obj->size) + error->acthd >= obj->gtt_offset && + error->acthd < obj->gtt_offset + obj->base.size) batchbuffer[1] = obj; if (batchbuffer[0] && batchbuffer[1]) @@ -703,17 +694,15 @@ static void i915_capture_error_state(struct drm_device *dev) } } if (batchbuffer[0] == NULL || batchbuffer[1] == NULL) { - list_for_each_entry(obj_priv, &dev_priv->mm.inactive_list, mm_list) { - struct drm_gem_object *obj = &obj_priv->base; - + list_for_each_entry(obj, &dev_priv->mm.inactive_list, mm_list) { if (batchbuffer[0] == NULL && - bbaddr >= obj_priv->gtt_offset && - bbaddr < obj_priv->gtt_offset + obj->size) + bbaddr >= obj->gtt_offset && + bbaddr < obj->gtt_offset + obj->base.size) batchbuffer[0] = obj; if (batchbuffer[1] == NULL && - error->acthd >= obj_priv->gtt_offset && - error->acthd < obj_priv->gtt_offset + obj->size) + error->acthd >= obj->gtt_offset && + error->acthd < obj->gtt_offset + obj->base.size) batchbuffer[1] = obj; if (batchbuffer[0] && batchbuffer[1]) @@ -732,14 +721,14 @@ static void i915_capture_error_state(struct drm_device *dev) /* Record the ringbuffer */ error->ringbuffer = i915_error_object_create(dev, - dev_priv->render_ring.gem_object); + dev_priv->render_ring.obj); /* Record buffers on the active and pinned lists. */ error->active_bo = NULL; error->pinned_bo = NULL; error->active_bo_count = count; - list_for_each_entry(obj_priv, &dev_priv->mm.pinned_list, mm_list) + list_for_each_entry(obj, &dev_priv->mm.pinned_list, mm_list) count++; error->pinned_bo_count = count - error->active_bo_count; @@ -948,7 +937,7 @@ static void i915_pageflip_stall_check(struct drm_device *dev, int pipe) drm_i915_private_t *dev_priv = dev->dev_private; struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe]; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - struct drm_i915_gem_object *obj_priv; + struct drm_i915_gem_object *obj; struct intel_unpin_work *work; unsigned long flags; bool stall_detected; @@ -967,13 +956,13 @@ static void i915_pageflip_stall_check(struct drm_device *dev, int pipe) } /* Potential stall - if we see that the flip has happened, assume a missed interrupt */ - obj_priv = to_intel_bo(work->pending_flip_obj); + obj = work->pending_flip_obj; if (INTEL_INFO(dev)->gen >= 4) { int dspsurf = intel_crtc->plane == 0 ? DSPASURF : DSPBSURF; - stall_detected = I915_READ(dspsurf) == obj_priv->gtt_offset; + stall_detected = I915_READ(dspsurf) == obj->gtt_offset; } else { int dspaddr = intel_crtc->plane == 0 ? DSPAADDR : DSPBADDR; - stall_detected = I915_READ(dspaddr) == (obj_priv->gtt_offset + + stall_detected = I915_READ(dspaddr) == (obj->gtt_offset + crtc->y * crtc->fb->pitch + crtc->x * crtc->fb->bits_per_pixel/8); } diff --git a/drivers/gpu/drm/i915/i915_trace.h b/drivers/gpu/drm/i915/i915_trace.h index 34ef49fd0377..1df7262ae077 100644 --- a/drivers/gpu/drm/i915/i915_trace.h +++ b/drivers/gpu/drm/i915/i915_trace.h @@ -6,6 +6,7 @@ #include #include +#include "i915_drv.h" #undef TRACE_SYSTEM #define TRACE_SYSTEM i915 @@ -16,18 +17,18 @@ TRACE_EVENT(i915_gem_object_create, - TP_PROTO(struct drm_gem_object *obj), + TP_PROTO(struct drm_i915_gem_object *obj), TP_ARGS(obj), TP_STRUCT__entry( - __field(struct drm_gem_object *, obj) + __field(struct drm_i915_gem_object *, obj) __field(u32, size) ), TP_fast_assign( __entry->obj = obj; - __entry->size = obj->size; + __entry->size = obj->base.size; ), TP_printk("obj=%p, size=%u", __entry->obj, __entry->size) @@ -35,12 +36,12 @@ TRACE_EVENT(i915_gem_object_create, TRACE_EVENT(i915_gem_object_bind, - TP_PROTO(struct drm_gem_object *obj, u32 gtt_offset, bool mappable), + TP_PROTO(struct drm_i915_gem_object *obj, u32 gtt_offset, bool mappable), TP_ARGS(obj, gtt_offset, mappable), TP_STRUCT__entry( - __field(struct drm_gem_object *, obj) + __field(struct drm_i915_gem_object *, obj) __field(u32, gtt_offset) __field(bool, mappable) ), @@ -58,20 +59,20 @@ TRACE_EVENT(i915_gem_object_bind, TRACE_EVENT(i915_gem_object_change_domain, - TP_PROTO(struct drm_gem_object *obj, uint32_t old_read_domains, uint32_t old_write_domain), + TP_PROTO(struct drm_i915_gem_object *obj, uint32_t old_read_domains, uint32_t old_write_domain), TP_ARGS(obj, old_read_domains, old_write_domain), TP_STRUCT__entry( - __field(struct drm_gem_object *, obj) + __field(struct drm_i915_gem_object *, obj) __field(u32, read_domains) __field(u32, write_domain) ), TP_fast_assign( __entry->obj = obj; - __entry->read_domains = obj->read_domains | (old_read_domains << 16); - __entry->write_domain = obj->write_domain | (old_write_domain << 16); + __entry->read_domains = obj->base.read_domains | (old_read_domains << 16); + __entry->write_domain = obj->base.write_domain | (old_write_domain << 16); ), TP_printk("obj=%p, read=%04x, write=%04x", @@ -81,12 +82,12 @@ TRACE_EVENT(i915_gem_object_change_domain, TRACE_EVENT(i915_gem_object_get_fence, - TP_PROTO(struct drm_gem_object *obj, int fence, int tiling_mode), + TP_PROTO(struct drm_i915_gem_object *obj, int fence, int tiling_mode), TP_ARGS(obj, fence, tiling_mode), TP_STRUCT__entry( - __field(struct drm_gem_object *, obj) + __field(struct drm_i915_gem_object *, obj) __field(int, fence) __field(int, tiling_mode) ), @@ -103,12 +104,12 @@ TRACE_EVENT(i915_gem_object_get_fence, DECLARE_EVENT_CLASS(i915_gem_object, - TP_PROTO(struct drm_gem_object *obj), + TP_PROTO(struct drm_i915_gem_object *obj), TP_ARGS(obj), TP_STRUCT__entry( - __field(struct drm_gem_object *, obj) + __field(struct drm_i915_gem_object *, obj) ), TP_fast_assign( @@ -120,21 +121,21 @@ DECLARE_EVENT_CLASS(i915_gem_object, DEFINE_EVENT(i915_gem_object, i915_gem_object_clflush, - TP_PROTO(struct drm_gem_object *obj), + TP_PROTO(struct drm_i915_gem_object *obj), TP_ARGS(obj) ); DEFINE_EVENT(i915_gem_object, i915_gem_object_unbind, - TP_PROTO(struct drm_gem_object *obj), + TP_PROTO(struct drm_i915_gem_object *obj), TP_ARGS(obj) ); DEFINE_EVENT(i915_gem_object, i915_gem_object_destroy, - TP_PROTO(struct drm_gem_object *obj), + TP_PROTO(struct drm_i915_gem_object *obj), TP_ARGS(obj) ); @@ -266,13 +267,13 @@ DEFINE_EVENT(i915_ring, i915_ring_wait_end, ); TRACE_EVENT(i915_flip_request, - TP_PROTO(int plane, struct drm_gem_object *obj), + TP_PROTO(int plane, struct drm_i915_gem_object *obj), TP_ARGS(plane, obj), TP_STRUCT__entry( __field(int, plane) - __field(struct drm_gem_object *, obj) + __field(struct drm_i915_gem_object *, obj) ), TP_fast_assign( @@ -284,13 +285,13 @@ TRACE_EVENT(i915_flip_request, ); TRACE_EVENT(i915_flip_complete, - TP_PROTO(int plane, struct drm_gem_object *obj), + TP_PROTO(int plane, struct drm_i915_gem_object *obj), TP_ARGS(plane, obj), TP_STRUCT__entry( __field(int, plane) - __field(struct drm_gem_object *, obj) + __field(struct drm_i915_gem_object *, obj) ), TP_fast_assign( diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index d4bc443f43fc..ae7d4f55ce07 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -1066,13 +1066,13 @@ static void i8xx_enable_fbc(struct drm_crtc *crtc, unsigned long interval) struct drm_i915_private *dev_priv = dev->dev_private; struct drm_framebuffer *fb = crtc->fb; struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb); - struct drm_i915_gem_object *obj_priv = to_intel_bo(intel_fb->obj); + struct drm_i915_gem_object *obj = intel_fb->obj; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); int plane, i; u32 fbc_ctl, fbc_ctl2; if (fb->pitch == dev_priv->cfb_pitch && - obj_priv->fence_reg == dev_priv->cfb_fence && + obj->fence_reg == dev_priv->cfb_fence && intel_crtc->plane == dev_priv->cfb_plane && I915_READ(FBC_CONTROL) & FBC_CTL_EN) return; @@ -1086,7 +1086,7 @@ static void i8xx_enable_fbc(struct drm_crtc *crtc, unsigned long interval) /* FBC_CTL wants 64B units */ dev_priv->cfb_pitch = (dev_priv->cfb_pitch / 64) - 1; - dev_priv->cfb_fence = obj_priv->fence_reg; + dev_priv->cfb_fence = obj->fence_reg; dev_priv->cfb_plane = intel_crtc->plane; plane = dev_priv->cfb_plane == 0 ? FBC_CTL_PLANEA : FBC_CTL_PLANEB; @@ -1096,7 +1096,7 @@ static void i8xx_enable_fbc(struct drm_crtc *crtc, unsigned long interval) /* Set it up... */ fbc_ctl2 = FBC_CTL_FENCE_DBL | FBC_CTL_IDLE_IMM | plane; - if (obj_priv->tiling_mode != I915_TILING_NONE) + if (obj->tiling_mode != I915_TILING_NONE) fbc_ctl2 |= FBC_CTL_CPU_FENCE; I915_WRITE(FBC_CONTROL2, fbc_ctl2); I915_WRITE(FBC_FENCE_OFF, crtc->y); @@ -1107,7 +1107,7 @@ static void i8xx_enable_fbc(struct drm_crtc *crtc, unsigned long interval) fbc_ctl |= FBC_CTL_C3_IDLE; /* 945 needs special SR handling */ fbc_ctl |= (dev_priv->cfb_pitch & 0xff) << FBC_CTL_STRIDE_SHIFT; fbc_ctl |= (interval & 0x2fff) << FBC_CTL_INTERVAL_SHIFT; - if (obj_priv->tiling_mode != I915_TILING_NONE) + if (obj->tiling_mode != I915_TILING_NONE) fbc_ctl |= dev_priv->cfb_fence; I915_WRITE(FBC_CONTROL, fbc_ctl); @@ -1150,7 +1150,7 @@ static void g4x_enable_fbc(struct drm_crtc *crtc, unsigned long interval) struct drm_i915_private *dev_priv = dev->dev_private; struct drm_framebuffer *fb = crtc->fb; struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb); - struct drm_i915_gem_object *obj_priv = to_intel_bo(intel_fb->obj); + struct drm_i915_gem_object *obj = intel_fb->obj; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); int plane = intel_crtc->plane == 0 ? DPFC_CTL_PLANEA : DPFC_CTL_PLANEB; unsigned long stall_watermark = 200; @@ -1159,7 +1159,7 @@ static void g4x_enable_fbc(struct drm_crtc *crtc, unsigned long interval) dpfc_ctl = I915_READ(DPFC_CONTROL); if (dpfc_ctl & DPFC_CTL_EN) { if (dev_priv->cfb_pitch == dev_priv->cfb_pitch / 64 - 1 && - dev_priv->cfb_fence == obj_priv->fence_reg && + dev_priv->cfb_fence == obj->fence_reg && dev_priv->cfb_plane == intel_crtc->plane && dev_priv->cfb_y == crtc->y) return; @@ -1170,12 +1170,12 @@ static void g4x_enable_fbc(struct drm_crtc *crtc, unsigned long interval) } dev_priv->cfb_pitch = (dev_priv->cfb_pitch / 64) - 1; - dev_priv->cfb_fence = obj_priv->fence_reg; + dev_priv->cfb_fence = obj->fence_reg; dev_priv->cfb_plane = intel_crtc->plane; dev_priv->cfb_y = crtc->y; dpfc_ctl = plane | DPFC_SR_EN | DPFC_CTL_LIMIT_1X; - if (obj_priv->tiling_mode != I915_TILING_NONE) { + if (obj->tiling_mode != I915_TILING_NONE) { dpfc_ctl |= DPFC_CTL_FENCE_EN | dev_priv->cfb_fence; I915_WRITE(DPFC_CHICKEN, DPFC_HT_MODIFY); } else { @@ -1221,7 +1221,7 @@ static void ironlake_enable_fbc(struct drm_crtc *crtc, unsigned long interval) struct drm_i915_private *dev_priv = dev->dev_private; struct drm_framebuffer *fb = crtc->fb; struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb); - struct drm_i915_gem_object *obj_priv = to_intel_bo(intel_fb->obj); + struct drm_i915_gem_object *obj = intel_fb->obj; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); int plane = intel_crtc->plane == 0 ? DPFC_CTL_PLANEA : DPFC_CTL_PLANEB; unsigned long stall_watermark = 200; @@ -1230,9 +1230,9 @@ static void ironlake_enable_fbc(struct drm_crtc *crtc, unsigned long interval) dpfc_ctl = I915_READ(ILK_DPFC_CONTROL); if (dpfc_ctl & DPFC_CTL_EN) { if (dev_priv->cfb_pitch == dev_priv->cfb_pitch / 64 - 1 && - dev_priv->cfb_fence == obj_priv->fence_reg && + dev_priv->cfb_fence == obj->fence_reg && dev_priv->cfb_plane == intel_crtc->plane && - dev_priv->cfb_offset == obj_priv->gtt_offset && + dev_priv->cfb_offset == obj->gtt_offset && dev_priv->cfb_y == crtc->y) return; @@ -1242,14 +1242,14 @@ static void ironlake_enable_fbc(struct drm_crtc *crtc, unsigned long interval) } dev_priv->cfb_pitch = (dev_priv->cfb_pitch / 64) - 1; - dev_priv->cfb_fence = obj_priv->fence_reg; + dev_priv->cfb_fence = obj->fence_reg; dev_priv->cfb_plane = intel_crtc->plane; - dev_priv->cfb_offset = obj_priv->gtt_offset; + dev_priv->cfb_offset = obj->gtt_offset; dev_priv->cfb_y = crtc->y; dpfc_ctl &= DPFC_RESERVED; dpfc_ctl |= (plane | DPFC_CTL_LIMIT_1X); - if (obj_priv->tiling_mode != I915_TILING_NONE) { + if (obj->tiling_mode != I915_TILING_NONE) { dpfc_ctl |= (DPFC_CTL_FENCE_EN | dev_priv->cfb_fence); I915_WRITE(ILK_DPFC_CHICKEN, DPFC_HT_MODIFY); } else { @@ -1260,7 +1260,7 @@ static void ironlake_enable_fbc(struct drm_crtc *crtc, unsigned long interval) (stall_watermark << DPFC_RECOMP_STALL_WM_SHIFT) | (interval << DPFC_RECOMP_TIMER_COUNT_SHIFT)); I915_WRITE(ILK_DPFC_FENCE_YOFF, crtc->y); - I915_WRITE(ILK_FBC_RT_BASE, obj_priv->gtt_offset | ILK_FBC_RT_VALID); + I915_WRITE(ILK_FBC_RT_BASE, obj->gtt_offset | ILK_FBC_RT_VALID); /* enable it... */ I915_WRITE(ILK_DPFC_CONTROL, dpfc_ctl | DPFC_CTL_EN); @@ -1345,7 +1345,7 @@ static void intel_update_fbc(struct drm_device *dev) struct intel_crtc *intel_crtc; struct drm_framebuffer *fb; struct intel_framebuffer *intel_fb; - struct drm_i915_gem_object *obj_priv; + struct drm_i915_gem_object *obj; DRM_DEBUG_KMS("\n"); @@ -1384,9 +1384,9 @@ static void intel_update_fbc(struct drm_device *dev) intel_crtc = to_intel_crtc(crtc); fb = crtc->fb; intel_fb = to_intel_framebuffer(fb); - obj_priv = to_intel_bo(intel_fb->obj); + obj = intel_fb->obj; - if (intel_fb->obj->size > dev_priv->cfb_size) { + if (intel_fb->obj->base.size > dev_priv->cfb_size) { DRM_DEBUG_KMS("framebuffer too large, disabling " "compression\n"); dev_priv->no_fbc_reason = FBC_STOLEN_TOO_SMALL; @@ -1410,7 +1410,7 @@ static void intel_update_fbc(struct drm_device *dev) dev_priv->no_fbc_reason = FBC_BAD_PLANE; goto out_disable; } - if (obj_priv->tiling_mode != I915_TILING_X) { + if (obj->tiling_mode != I915_TILING_X) { DRM_DEBUG_KMS("framebuffer not tiled, disabling compression\n"); dev_priv->no_fbc_reason = FBC_NOT_TILED; goto out_disable; @@ -1433,14 +1433,13 @@ out_disable: int intel_pin_and_fence_fb_obj(struct drm_device *dev, - struct drm_gem_object *obj, + struct drm_i915_gem_object *obj, bool pipelined) { - struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); u32 alignment; int ret; - switch (obj_priv->tiling_mode) { + switch (obj->tiling_mode) { case I915_TILING_NONE: if (IS_BROADWATER(dev) || IS_CRESTLINE(dev)) alignment = 128 * 1024; @@ -1474,7 +1473,7 @@ intel_pin_and_fence_fb_obj(struct drm_device *dev, * framebuffer compression. For simplicity, we always install * a fence as the cost is not that onerous. */ - if (obj_priv->tiling_mode != I915_TILING_NONE) { + if (obj->tiling_mode != I915_TILING_NONE) { ret = i915_gem_object_get_fence_reg(obj, false); if (ret) goto err_unpin; @@ -1496,8 +1495,7 @@ intel_pipe_set_base_atomic(struct drm_crtc *crtc, struct drm_framebuffer *fb, struct drm_i915_private *dev_priv = dev->dev_private; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); struct intel_framebuffer *intel_fb; - struct drm_i915_gem_object *obj_priv; - struct drm_gem_object *obj; + struct drm_i915_gem_object *obj; int plane = intel_crtc->plane; unsigned long Start, Offset; u32 dspcntr; @@ -1514,7 +1512,6 @@ intel_pipe_set_base_atomic(struct drm_crtc *crtc, struct drm_framebuffer *fb, intel_fb = to_intel_framebuffer(fb); obj = intel_fb->obj; - obj_priv = to_intel_bo(obj); reg = DSPCNTR(plane); dspcntr = I915_READ(reg); @@ -1539,7 +1536,7 @@ intel_pipe_set_base_atomic(struct drm_crtc *crtc, struct drm_framebuffer *fb, return -EINVAL; } if (INTEL_INFO(dev)->gen >= 4) { - if (obj_priv->tiling_mode != I915_TILING_NONE) + if (obj->tiling_mode != I915_TILING_NONE) dspcntr |= DISPPLANE_TILED; else dspcntr &= ~DISPPLANE_TILED; @@ -1551,7 +1548,7 @@ intel_pipe_set_base_atomic(struct drm_crtc *crtc, struct drm_framebuffer *fb, I915_WRITE(reg, dspcntr); - Start = obj_priv->gtt_offset; + Start = obj->gtt_offset; Offset = y * fb->pitch + x * (fb->bits_per_pixel / 8); DRM_DEBUG_KMS("Writing base %08lX %08lX %d %d %d\n", @@ -1605,18 +1602,17 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, if (old_fb) { struct drm_i915_private *dev_priv = dev->dev_private; - struct drm_gem_object *obj = to_intel_framebuffer(old_fb)->obj; - struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); + struct drm_i915_gem_object *obj = to_intel_framebuffer(old_fb)->obj; wait_event(dev_priv->pending_flip_queue, - atomic_read(&obj_priv->pending_flip) == 0); + atomic_read(&obj->pending_flip) == 0); /* Big Hammer, we also need to ensure that any pending * MI_WAIT_FOR_EVENT inside a user batch buffer on the * current scanout is retired before unpinning the old * framebuffer. */ - ret = i915_gem_object_flush_gpu(obj_priv, false); + ret = i915_gem_object_flush_gpu(obj, false); if (ret) { i915_gem_object_unpin(to_intel_framebuffer(crtc->fb)->obj); mutex_unlock(&dev->struct_mutex); @@ -2010,16 +2006,16 @@ static void intel_clear_scanline_wait(struct drm_device *dev) static void intel_crtc_wait_for_pending_flips(struct drm_crtc *crtc) { - struct drm_i915_gem_object *obj_priv; + struct drm_i915_gem_object *obj; struct drm_i915_private *dev_priv; if (crtc->fb == NULL) return; - obj_priv = to_intel_bo(to_intel_framebuffer(crtc->fb)->obj); + obj = to_intel_framebuffer(crtc->fb)->obj; dev_priv = crtc->dev->dev_private; wait_event(dev_priv->pending_flip_queue, - atomic_read(&obj_priv->pending_flip) == 0); + atomic_read(&obj->pending_flip) == 0); } static void ironlake_crtc_enable(struct drm_crtc *crtc) @@ -4333,15 +4329,14 @@ static void intel_crtc_update_cursor(struct drm_crtc *crtc, } static int intel_crtc_cursor_set(struct drm_crtc *crtc, - struct drm_file *file_priv, + struct drm_file *file, uint32_t handle, uint32_t width, uint32_t height) { struct drm_device *dev = crtc->dev; struct drm_i915_private *dev_priv = dev->dev_private; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); - struct drm_gem_object *bo; - struct drm_i915_gem_object *obj_priv; + struct drm_i915_gem_object *obj; uint32_t addr; int ret; @@ -4351,7 +4346,7 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc, if (!handle) { DRM_DEBUG_KMS("cursor off\n"); addr = 0; - bo = NULL; + obj = NULL; mutex_lock(&dev->struct_mutex); goto finish; } @@ -4362,13 +4357,11 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc, return -EINVAL; } - bo = drm_gem_object_lookup(dev, file_priv, handle); - if (!bo) + obj = to_intel_bo(drm_gem_object_lookup(dev, file, handle)); + if (!obj) return -ENOENT; - obj_priv = to_intel_bo(bo); - - if (bo->size < width * height * 4) { + if (obj->base.size < width * height * 4) { DRM_ERROR("buffer is to small\n"); ret = -ENOMEM; goto fail; @@ -4377,29 +4370,29 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc, /* we only need to pin inside GTT if cursor is non-phy */ mutex_lock(&dev->struct_mutex); if (!dev_priv->info->cursor_needs_physical) { - ret = i915_gem_object_pin(bo, PAGE_SIZE, true); + ret = i915_gem_object_pin(obj, PAGE_SIZE, true); if (ret) { DRM_ERROR("failed to pin cursor bo\n"); goto fail_locked; } - ret = i915_gem_object_set_to_gtt_domain(bo, 0); + ret = i915_gem_object_set_to_gtt_domain(obj, 0); if (ret) { DRM_ERROR("failed to move cursor bo into the GTT\n"); goto fail_unpin; } - addr = obj_priv->gtt_offset; + addr = obj->gtt_offset; } else { int align = IS_I830(dev) ? 16 * 1024 : 256; - ret = i915_gem_attach_phys_object(dev, bo, + ret = i915_gem_attach_phys_object(dev, obj, (intel_crtc->pipe == 0) ? I915_GEM_PHYS_CURSOR_0 : I915_GEM_PHYS_CURSOR_1, align); if (ret) { DRM_ERROR("failed to attach phys object\n"); goto fail_locked; } - addr = obj_priv->phys_obj->handle->busaddr; + addr = obj->phys_obj->handle->busaddr; } if (IS_GEN2(dev)) @@ -4408,17 +4401,17 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc, finish: if (intel_crtc->cursor_bo) { if (dev_priv->info->cursor_needs_physical) { - if (intel_crtc->cursor_bo != bo) + if (intel_crtc->cursor_bo != obj) i915_gem_detach_phys_object(dev, intel_crtc->cursor_bo); } else i915_gem_object_unpin(intel_crtc->cursor_bo); - drm_gem_object_unreference(intel_crtc->cursor_bo); + drm_gem_object_unreference(&intel_crtc->cursor_bo->base); } mutex_unlock(&dev->struct_mutex); intel_crtc->cursor_addr = addr; - intel_crtc->cursor_bo = bo; + intel_crtc->cursor_bo = obj; intel_crtc->cursor_width = width; intel_crtc->cursor_height = height; @@ -4426,11 +4419,11 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc, return 0; fail_unpin: - i915_gem_object_unpin(bo); + i915_gem_object_unpin(obj); fail_locked: mutex_unlock(&dev->struct_mutex); fail: - drm_gem_object_unreference_unlocked(bo); + drm_gem_object_unreference_unlocked(&obj->base); return ret; } @@ -4890,7 +4883,7 @@ static void intel_idle_update(struct work_struct *work) * buffer), we'll also mark the display as busy, so we know to increase its * clock frequency. */ -void intel_mark_busy(struct drm_device *dev, struct drm_gem_object *obj) +void intel_mark_busy(struct drm_device *dev, struct drm_i915_gem_object *obj) { drm_i915_private_t *dev_priv = dev->dev_private; struct drm_crtc *crtc = NULL; @@ -4971,8 +4964,8 @@ static void intel_unpin_work_fn(struct work_struct *__work) mutex_lock(&work->dev->struct_mutex); i915_gem_object_unpin(work->old_fb_obj); - drm_gem_object_unreference(work->pending_flip_obj); - drm_gem_object_unreference(work->old_fb_obj); + drm_gem_object_unreference(&work->pending_flip_obj->base); + drm_gem_object_unreference(&work->old_fb_obj->base); mutex_unlock(&work->dev->struct_mutex); kfree(work); } @@ -4983,7 +4976,7 @@ static void do_intel_finish_page_flip(struct drm_device *dev, drm_i915_private_t *dev_priv = dev->dev_private; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); struct intel_unpin_work *work; - struct drm_i915_gem_object *obj_priv; + struct drm_i915_gem_object *obj; struct drm_pending_vblank_event *e; struct timeval now; unsigned long flags; @@ -5015,10 +5008,10 @@ static void do_intel_finish_page_flip(struct drm_device *dev, spin_unlock_irqrestore(&dev->event_lock, flags); - obj_priv = to_intel_bo(work->old_fb_obj); + obj = work->old_fb_obj; atomic_clear_mask(1 << intel_crtc->plane, - &obj_priv->pending_flip.counter); - if (atomic_read(&obj_priv->pending_flip) == 0) + &obj->pending_flip.counter); + if (atomic_read(&obj->pending_flip) == 0) wake_up(&dev_priv->pending_flip_queue); schedule_work(&work->work); @@ -5065,8 +5058,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, struct drm_device *dev = crtc->dev; struct drm_i915_private *dev_priv = dev->dev_private; struct intel_framebuffer *intel_fb; - struct drm_i915_gem_object *obj_priv; - struct drm_gem_object *obj; + struct drm_i915_gem_object *obj; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); struct intel_unpin_work *work; unsigned long flags, offset; @@ -5105,8 +5097,8 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, goto cleanup_work; /* Reference the objects for the scheduled work. */ - drm_gem_object_reference(work->old_fb_obj); - drm_gem_object_reference(obj); + drm_gem_object_reference(&work->old_fb_obj->base); + drm_gem_object_reference(&obj->base); crtc->fb = fb; @@ -5134,7 +5126,6 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, } work->pending_flip_obj = obj; - obj_priv = to_intel_bo(obj); work->enable_stall_check = true; @@ -5148,15 +5139,14 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, /* Block clients from rendering to the new back buffer until * the flip occurs and the object is no longer visible. */ - atomic_add(1 << intel_crtc->plane, - &to_intel_bo(work->old_fb_obj)->pending_flip); + atomic_add(1 << intel_crtc->plane, &work->old_fb_obj->pending_flip); switch (INTEL_INFO(dev)->gen) { case 2: OUT_RING(MI_DISPLAY_FLIP | MI_DISPLAY_FLIP_PLANE(intel_crtc->plane)); OUT_RING(fb->pitch); - OUT_RING(obj_priv->gtt_offset + offset); + OUT_RING(obj->gtt_offset + offset); OUT_RING(MI_NOOP); break; @@ -5164,7 +5154,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, OUT_RING(MI_DISPLAY_FLIP_I915 | MI_DISPLAY_FLIP_PLANE(intel_crtc->plane)); OUT_RING(fb->pitch); - OUT_RING(obj_priv->gtt_offset + offset); + OUT_RING(obj->gtt_offset + offset); OUT_RING(MI_NOOP); break; @@ -5177,7 +5167,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, OUT_RING(MI_DISPLAY_FLIP | MI_DISPLAY_FLIP_PLANE(intel_crtc->plane)); OUT_RING(fb->pitch); - OUT_RING(obj_priv->gtt_offset | obj_priv->tiling_mode); + OUT_RING(obj->gtt_offset | obj->tiling_mode); /* XXX Enabling the panel-fitter across page-flip is so far * untested on non-native modes, so ignore it for now. @@ -5191,8 +5181,8 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, case 6: OUT_RING(MI_DISPLAY_FLIP | MI_DISPLAY_FLIP_PLANE(intel_crtc->plane)); - OUT_RING(fb->pitch | obj_priv->tiling_mode); - OUT_RING(obj_priv->gtt_offset); + OUT_RING(fb->pitch | obj->tiling_mode); + OUT_RING(obj->gtt_offset); pf = I915_READ(pipe == 0 ? PFA_CTL_1 : PFB_CTL_1) & PF_ENABLE; pipesrc = I915_READ(pipe == 0 ? PIPEASRC : PIPEBSRC) & 0x0fff0fff; @@ -5208,8 +5198,8 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, return 0; cleanup_objs: - drm_gem_object_unreference(work->old_fb_obj); - drm_gem_object_unreference(obj); + drm_gem_object_unreference(&work->old_fb_obj->base); + drm_gem_object_unreference(&obj->base); cleanup_work: mutex_unlock(&dev->struct_mutex); @@ -5295,7 +5285,7 @@ static void intel_crtc_init(struct drm_device *dev, int pipe) } int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data, - struct drm_file *file_priv) + struct drm_file *file) { drm_i915_private_t *dev_priv = dev->dev_private; struct drm_i915_get_pipe_from_crtc_id *pipe_from_crtc_id = data; @@ -5440,19 +5430,19 @@ static void intel_user_framebuffer_destroy(struct drm_framebuffer *fb) struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb); drm_framebuffer_cleanup(fb); - drm_gem_object_unreference_unlocked(intel_fb->obj); + drm_gem_object_unreference_unlocked(&intel_fb->obj->base); kfree(intel_fb); } static int intel_user_framebuffer_create_handle(struct drm_framebuffer *fb, - struct drm_file *file_priv, + struct drm_file *file, unsigned int *handle) { struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb); - struct drm_gem_object *object = intel_fb->obj; + struct drm_i915_gem_object *obj = intel_fb->obj; - return drm_gem_handle_create(file_priv, object, handle); + return drm_gem_handle_create(file, &obj->base, handle); } static const struct drm_framebuffer_funcs intel_fb_funcs = { @@ -5463,12 +5453,11 @@ static const struct drm_framebuffer_funcs intel_fb_funcs = { int intel_framebuffer_init(struct drm_device *dev, struct intel_framebuffer *intel_fb, struct drm_mode_fb_cmd *mode_cmd, - struct drm_gem_object *obj) + struct drm_i915_gem_object *obj) { - struct drm_i915_gem_object *obj_priv = to_intel_bo(obj); int ret; - if (obj_priv->tiling_mode == I915_TILING_Y) + if (obj->tiling_mode == I915_TILING_Y) return -EINVAL; if (mode_cmd->pitch & 63) @@ -5500,11 +5489,11 @@ intel_user_framebuffer_create(struct drm_device *dev, struct drm_file *filp, struct drm_mode_fb_cmd *mode_cmd) { - struct drm_gem_object *obj; + struct drm_i915_gem_object *obj; struct intel_framebuffer *intel_fb; int ret; - obj = drm_gem_object_lookup(dev, filp, mode_cmd->handle); + obj = to_intel_bo(drm_gem_object_lookup(dev, filp, mode_cmd->handle)); if (!obj) return ERR_PTR(-ENOENT); @@ -5512,10 +5501,9 @@ intel_user_framebuffer_create(struct drm_device *dev, if (!intel_fb) return ERR_PTR(-ENOMEM); - ret = intel_framebuffer_init(dev, intel_fb, - mode_cmd, obj); + ret = intel_framebuffer_init(dev, intel_fb, mode_cmd, obj); if (ret) { - drm_gem_object_unreference_unlocked(obj); + drm_gem_object_unreference_unlocked(&obj->base); kfree(intel_fb); return ERR_PTR(ret); } @@ -5528,10 +5516,10 @@ static const struct drm_mode_config_funcs intel_mode_funcs = { .output_poll_changed = intel_fb_output_poll_changed, }; -static struct drm_gem_object * +static struct drm_i915_gem_object * intel_alloc_context_page(struct drm_device *dev) { - struct drm_gem_object *ctx; + struct drm_i915_gem_object *ctx; int ret; ctx = i915_gem_alloc_object(dev, 4096); @@ -5559,7 +5547,7 @@ intel_alloc_context_page(struct drm_device *dev) err_unpin: i915_gem_object_unpin(ctx); err_unref: - drm_gem_object_unreference(ctx); + drm_gem_object_unreference(&ctx->base); mutex_unlock(&dev->struct_mutex); return NULL; } @@ -5886,20 +5874,17 @@ void intel_init_clock_gating(struct drm_device *dev) if (dev_priv->renderctx == NULL) dev_priv->renderctx = intel_alloc_context_page(dev); if (dev_priv->renderctx) { - struct drm_i915_gem_object *obj_priv; - obj_priv = to_intel_bo(dev_priv->renderctx); - if (obj_priv) { - if (BEGIN_LP_RING(4) == 0) { - OUT_RING(MI_SET_CONTEXT); - OUT_RING(obj_priv->gtt_offset | - MI_MM_SPACE_GTT | - MI_SAVE_EXT_STATE_EN | - MI_RESTORE_EXT_STATE_EN | - MI_RESTORE_INHIBIT); - OUT_RING(MI_NOOP); - OUT_RING(MI_FLUSH); - ADVANCE_LP_RING(); - } + struct drm_i915_gem_object *obj = dev_priv->renderctx; + if (BEGIN_LP_RING(4) == 0) { + OUT_RING(MI_SET_CONTEXT); + OUT_RING(obj->gtt_offset | + MI_MM_SPACE_GTT | + MI_SAVE_EXT_STATE_EN | + MI_RESTORE_EXT_STATE_EN | + MI_RESTORE_INHIBIT); + OUT_RING(MI_NOOP); + OUT_RING(MI_FLUSH); + ADVANCE_LP_RING(); } } else DRM_DEBUG_KMS("Failed to allocate render context." @@ -5907,22 +5892,11 @@ void intel_init_clock_gating(struct drm_device *dev) } if (I915_HAS_RC6(dev) && drm_core_check_feature(dev, DRIVER_MODESET)) { - struct drm_i915_gem_object *obj_priv = NULL; - + if (dev_priv->pwrctx == NULL) + dev_priv->pwrctx = intel_alloc_context_page(dev); if (dev_priv->pwrctx) { - obj_priv = to_intel_bo(dev_priv->pwrctx); - } else { - struct drm_gem_object *pwrctx; - - pwrctx = intel_alloc_context_page(dev); - if (pwrctx) { - dev_priv->pwrctx = pwrctx; - obj_priv = to_intel_bo(pwrctx); - } - } - - if (obj_priv) { - I915_WRITE(PWRCTXA, obj_priv->gtt_offset | PWRCTX_EN); + struct drm_i915_gem_object *obj = dev_priv->pwrctx; + I915_WRITE(PWRCTXA, obj->gtt_offset | PWRCTX_EN); I915_WRITE(MCHBAR_RENDER_STANDBY, I915_READ(MCHBAR_RENDER_STANDBY) & ~RCX_SW_EXIT); } @@ -6197,23 +6171,25 @@ void intel_modeset_cleanup(struct drm_device *dev) dev_priv->display.disable_fbc(dev); if (dev_priv->renderctx) { - struct drm_i915_gem_object *obj_priv; + struct drm_i915_gem_object *obj = dev_priv->renderctx; + + I915_WRITE(CCID, obj->gtt_offset &~ CCID_EN); + POSTING_READ(CCID); - obj_priv = to_intel_bo(dev_priv->renderctx); - I915_WRITE(CCID, obj_priv->gtt_offset &~ CCID_EN); - I915_READ(CCID); - i915_gem_object_unpin(dev_priv->renderctx); - drm_gem_object_unreference(dev_priv->renderctx); + i915_gem_object_unpin(obj); + drm_gem_object_unreference(&obj->base); + dev_priv->renderctx = NULL; } if (dev_priv->pwrctx) { - struct drm_i915_gem_object *obj_priv; + struct drm_i915_gem_object *obj = dev_priv->pwrctx; + + I915_WRITE(PWRCTXA, obj->gtt_offset &~ PWRCTX_EN); + POSTING_READ(PWRCTXA); - obj_priv = to_intel_bo(dev_priv->pwrctx); - I915_WRITE(PWRCTXA, obj_priv->gtt_offset &~ PWRCTX_EN); - I915_READ(PWRCTXA); - i915_gem_object_unpin(dev_priv->pwrctx); - drm_gem_object_unreference(dev_priv->pwrctx); + i915_gem_object_unpin(obj); + drm_gem_object_unreference(&obj->base); + dev_priv->pwrctx = NULL; } if (IS_IRONLAKE_M(dev)) diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 21551fe74541..5a4f14e36d6c 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -127,7 +127,7 @@ intel_mode_get_pixel_multiplier(const struct drm_display_mode *mode) struct intel_framebuffer { struct drm_framebuffer base; - struct drm_gem_object *obj; + struct drm_i915_gem_object *obj; }; struct intel_fbdev { @@ -166,7 +166,7 @@ struct intel_crtc { struct intel_unpin_work *unpin_work; int fdi_lanes; - struct drm_gem_object *cursor_bo; + struct drm_i915_gem_object *cursor_bo; uint32_t cursor_addr; int16_t cursor_x, cursor_y; int16_t cursor_width, cursor_height; @@ -220,8 +220,8 @@ intel_get_crtc_for_pipe(struct drm_device *dev, int pipe) struct intel_unpin_work { struct work_struct work; struct drm_device *dev; - struct drm_gem_object *old_fb_obj; - struct drm_gem_object *pending_flip_obj; + struct drm_i915_gem_object *old_fb_obj; + struct drm_i915_gem_object *pending_flip_obj; struct drm_pending_vblank_event *event; int pending; bool enable_stall_check; @@ -236,7 +236,8 @@ void intel_dip_infoframe_csum(struct dip_infoframe *avi_if); extern bool intel_sdvo_init(struct drm_device *dev, int output_device); extern void intel_dvo_init(struct drm_device *dev); extern void intel_tv_init(struct drm_device *dev); -extern void intel_mark_busy(struct drm_device *dev, struct drm_gem_object *obj); +extern void intel_mark_busy(struct drm_device *dev, + struct drm_i915_gem_object *obj); extern void intel_lvds_init(struct drm_device *dev); extern void intel_dp_init(struct drm_device *dev, int dp_reg); void @@ -299,13 +300,13 @@ extern void ironlake_disable_drps(struct drm_device *dev); extern void intel_init_emon(struct drm_device *dev); extern int intel_pin_and_fence_fb_obj(struct drm_device *dev, - struct drm_gem_object *obj, + struct drm_i915_gem_object *obj, bool pipelined); extern int intel_framebuffer_init(struct drm_device *dev, struct intel_framebuffer *ifb, struct drm_mode_fb_cmd *mode_cmd, - struct drm_gem_object *obj); + struct drm_i915_gem_object *obj); extern int intel_fbdev_init(struct drm_device *dev); extern void intel_fbdev_fini(struct drm_device *dev); diff --git a/drivers/gpu/drm/i915/intel_fb.c b/drivers/gpu/drm/i915/intel_fb.c index af2a1dddc28e..c2cffeb4fe89 100644 --- a/drivers/gpu/drm/i915/intel_fb.c +++ b/drivers/gpu/drm/i915/intel_fb.c @@ -65,8 +65,7 @@ static int intelfb_create(struct intel_fbdev *ifbdev, struct fb_info *info; struct drm_framebuffer *fb; struct drm_mode_fb_cmd mode_cmd; - struct drm_gem_object *fbo = NULL; - struct drm_i915_gem_object *obj_priv; + struct drm_i915_gem_object *obj; struct device *device = &dev->pdev->dev; int size, ret, mmio_bar = IS_GEN2(dev) ? 1 : 0; @@ -83,18 +82,17 @@ static int intelfb_create(struct intel_fbdev *ifbdev, size = mode_cmd.pitch * mode_cmd.height; size = ALIGN(size, PAGE_SIZE); - fbo = i915_gem_alloc_object(dev, size); - if (!fbo) { + obj = i915_gem_alloc_object(dev, size); + if (!obj) { DRM_ERROR("failed to allocate framebuffer\n"); ret = -ENOMEM; goto out; } - obj_priv = to_intel_bo(fbo); mutex_lock(&dev->struct_mutex); /* Flush everything out, we'll be doing GTT only from now on */ - ret = intel_pin_and_fence_fb_obj(dev, fbo, false); + ret = intel_pin_and_fence_fb_obj(dev, obj, false); if (ret) { DRM_ERROR("failed to pin fb: %d\n", ret); goto out_unref; @@ -108,7 +106,7 @@ static int intelfb_create(struct intel_fbdev *ifbdev, info->par = ifbdev; - ret = intel_framebuffer_init(dev, &ifbdev->ifb, &mode_cmd, fbo); + ret = intel_framebuffer_init(dev, &ifbdev->ifb, &mode_cmd, obj); if (ret) goto out_unpin; @@ -134,11 +132,10 @@ static int intelfb_create(struct intel_fbdev *ifbdev, else info->apertures->ranges[0].size = pci_resource_len(dev->pdev, 0); - info->fix.smem_start = dev->mode_config.fb_base + obj_priv->gtt_offset; + info->fix.smem_start = dev->mode_config.fb_base + obj->gtt_offset; info->fix.smem_len = size; - info->screen_base = ioremap_wc(dev->agp->base + obj_priv->gtt_offset, - size); + info->screen_base = ioremap_wc(dev->agp->base + obj->gtt_offset, size); if (!info->screen_base) { ret = -ENOSPC; goto out_unpin; @@ -168,7 +165,7 @@ static int intelfb_create(struct intel_fbdev *ifbdev, DRM_DEBUG_KMS("allocated %dx%d fb: 0x%08x, bo %p\n", fb->width, fb->height, - obj_priv->gtt_offset, fbo); + obj->gtt_offset, obj); mutex_unlock(&dev->struct_mutex); @@ -176,9 +173,9 @@ static int intelfb_create(struct intel_fbdev *ifbdev, return 0; out_unpin: - i915_gem_object_unpin(fbo); + i915_gem_object_unpin(obj); out_unref: - drm_gem_object_unreference(fbo); + drm_gem_object_unreference(&obj->base); mutex_unlock(&dev->struct_mutex); out: return ret; @@ -225,7 +222,7 @@ static void intel_fbdev_destroy(struct drm_device *dev, drm_framebuffer_cleanup(&ifb->base); if (ifb->obj) { - drm_gem_object_unreference_unlocked(ifb->obj); + drm_gem_object_unreference_unlocked(&ifb->obj->base); ifb->obj = NULL; } } diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c index ec8ffaccbbdb..af715cc03ee0 100644 --- a/drivers/gpu/drm/i915/intel_overlay.c +++ b/drivers/gpu/drm/i915/intel_overlay.c @@ -376,24 +376,23 @@ static int intel_overlay_continue(struct intel_overlay *overlay, static void intel_overlay_release_old_vid_tail(struct intel_overlay *overlay) { - struct drm_gem_object *obj = &overlay->old_vid_bo->base; + struct drm_i915_gem_object *obj = overlay->old_vid_bo; i915_gem_object_unpin(obj); - drm_gem_object_unreference(obj); + drm_gem_object_unreference(&obj->base); overlay->old_vid_bo = NULL; } static void intel_overlay_off_tail(struct intel_overlay *overlay) { - struct drm_gem_object *obj; + struct drm_i915_gem_object *obj = overlay->vid_bo; /* never have the overlay hw on without showing a frame */ BUG_ON(!overlay->vid_bo); - obj = &overlay->vid_bo->base; i915_gem_object_unpin(obj); - drm_gem_object_unreference(obj); + drm_gem_object_unreference(&obj->base); overlay->vid_bo = NULL; overlay->crtc->overlay = NULL; @@ -764,13 +763,12 @@ static u32 overlay_cmd_reg(struct put_image_params *params) } static int intel_overlay_do_put_image(struct intel_overlay *overlay, - struct drm_gem_object *new_bo, + struct drm_i915_gem_object *new_bo, struct put_image_params *params) { int ret, tmp_width; struct overlay_registers *regs; bool scale_changed = false; - struct drm_i915_gem_object *bo_priv = to_intel_bo(new_bo); struct drm_device *dev = overlay->dev; BUG_ON(!mutex_is_locked(&dev->struct_mutex)); @@ -825,7 +823,7 @@ static int intel_overlay_do_put_image(struct intel_overlay *overlay, regs->SWIDTHSW = calc_swidthsw(overlay->dev, params->offset_Y, tmp_width); regs->SHEIGHT = params->src_h; - regs->OBUF_0Y = bo_priv->gtt_offset + params-> offset_Y; + regs->OBUF_0Y = new_bo->gtt_offset + params-> offset_Y; regs->OSTRIDE = params->stride_Y; if (params->format & I915_OVERLAY_YUV_PLANAR) { @@ -839,8 +837,8 @@ static int intel_overlay_do_put_image(struct intel_overlay *overlay, params->src_w/uv_hscale); regs->SWIDTHSW |= max_t(u32, tmp_U, tmp_V) << 16; regs->SHEIGHT |= (params->src_h/uv_vscale) << 16; - regs->OBUF_0U = bo_priv->gtt_offset + params->offset_U; - regs->OBUF_0V = bo_priv->gtt_offset + params->offset_V; + regs->OBUF_0U = new_bo->gtt_offset + params->offset_U; + regs->OBUF_0V = new_bo->gtt_offset + params->offset_V; regs->OSTRIDE |= params->stride_UV << 16; } @@ -857,7 +855,7 @@ static int intel_overlay_do_put_image(struct intel_overlay *overlay, goto out_unpin; overlay->old_vid_bo = overlay->vid_bo; - overlay->vid_bo = to_intel_bo(new_bo); + overlay->vid_bo = new_bo; return 0; @@ -970,7 +968,7 @@ static int check_overlay_scaling(struct put_image_params *rec) static int check_overlay_src(struct drm_device *dev, struct drm_intel_overlay_put_image *rec, - struct drm_gem_object *new_bo) + struct drm_i915_gem_object *new_bo) { int uv_hscale = uv_hsubsampling(rec->flags); int uv_vscale = uv_vsubsampling(rec->flags); @@ -1055,7 +1053,7 @@ static int check_overlay_src(struct drm_device *dev, return -EINVAL; tmp = rec->stride_Y*rec->src_height; - if (rec->offset_Y + tmp > new_bo->size) + if (rec->offset_Y + tmp > new_bo->base.size) return -EINVAL; break; @@ -1066,12 +1064,12 @@ static int check_overlay_src(struct drm_device *dev, return -EINVAL; tmp = rec->stride_Y * rec->src_height; - if (rec->offset_Y + tmp > new_bo->size) + if (rec->offset_Y + tmp > new_bo->base.size) return -EINVAL; tmp = rec->stride_UV * (rec->src_height / uv_vscale); - if (rec->offset_U + tmp > new_bo->size || - rec->offset_V + tmp > new_bo->size) + if (rec->offset_U + tmp > new_bo->base.size || + rec->offset_V + tmp > new_bo->base.size) return -EINVAL; break; } @@ -1114,7 +1112,7 @@ int intel_overlay_put_image(struct drm_device *dev, void *data, struct intel_overlay *overlay; struct drm_mode_object *drmmode_obj; struct intel_crtc *crtc; - struct drm_gem_object *new_bo; + struct drm_i915_gem_object *new_bo; struct put_image_params *params; int ret; @@ -1153,8 +1151,8 @@ int intel_overlay_put_image(struct drm_device *dev, void *data, } crtc = to_intel_crtc(obj_to_crtc(drmmode_obj)); - new_bo = drm_gem_object_lookup(dev, file_priv, - put_image_rec->bo_handle); + new_bo = to_intel_bo(drm_gem_object_lookup(dev, file_priv, + put_image_rec->bo_handle)); if (!new_bo) { ret = -ENOENT; goto out_free; @@ -1245,7 +1243,7 @@ int intel_overlay_put_image(struct drm_device *dev, void *data, out_unlock: mutex_unlock(&dev->struct_mutex); mutex_unlock(&dev->mode_config.mutex); - drm_gem_object_unreference_unlocked(new_bo); + drm_gem_object_unreference_unlocked(&new_bo->base); out_free: kfree(params); @@ -1398,7 +1396,7 @@ void intel_setup_overlay(struct drm_device *dev) { drm_i915_private_t *dev_priv = dev->dev_private; struct intel_overlay *overlay; - struct drm_gem_object *reg_bo; + struct drm_i915_gem_object *reg_bo; struct overlay_registers *regs; int ret; @@ -1413,7 +1411,7 @@ void intel_setup_overlay(struct drm_device *dev) reg_bo = i915_gem_alloc_object(dev, PAGE_SIZE); if (!reg_bo) goto out_free; - overlay->reg_bo = to_intel_bo(reg_bo); + overlay->reg_bo = reg_bo; if (OVERLAY_NEEDS_PHYSICAL(dev)) { ret = i915_gem_attach_phys_object(dev, reg_bo, @@ -1423,14 +1421,14 @@ void intel_setup_overlay(struct drm_device *dev) DRM_ERROR("failed to attach phys overlay regs\n"); goto out_free_bo; } - overlay->flip_addr = overlay->reg_bo->phys_obj->handle->busaddr; + overlay->flip_addr = reg_bo->phys_obj->handle->busaddr; } else { ret = i915_gem_object_pin(reg_bo, PAGE_SIZE, true); if (ret) { DRM_ERROR("failed to pin overlay register bo\n"); goto out_free_bo; } - overlay->flip_addr = overlay->reg_bo->gtt_offset; + overlay->flip_addr = reg_bo->gtt_offset; ret = i915_gem_object_set_to_gtt_domain(reg_bo, true); if (ret) { @@ -1462,7 +1460,7 @@ void intel_setup_overlay(struct drm_device *dev) out_unpin_bo: i915_gem_object_unpin(reg_bo); out_free_bo: - drm_gem_object_unreference(reg_bo); + drm_gem_object_unreference(®_bo->base); out_free: kfree(overlay); return; diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 1db860d7989a..181aad31125d 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -139,7 +139,7 @@ u32 intel_ring_get_active_head(struct intel_ring_buffer *ring) static int init_ring_common(struct intel_ring_buffer *ring) { drm_i915_private_t *dev_priv = ring->dev->dev_private; - struct drm_i915_gem_object *obj_priv = to_intel_bo(ring->gem_object); + struct drm_i915_gem_object *obj = ring->obj; u32 head; /* Stop the ring if it's running. */ @@ -148,7 +148,7 @@ static int init_ring_common(struct intel_ring_buffer *ring) ring->write_tail(ring, 0); /* Initialize the ring. */ - I915_WRITE_START(ring, obj_priv->gtt_offset); + I915_WRITE_START(ring, obj->gtt_offset); head = I915_READ_HEAD(ring) & HEAD_ADDR; /* G45 ring initialization fails to reset head to zero */ @@ -178,7 +178,7 @@ static int init_ring_common(struct intel_ring_buffer *ring) /* If the head is still not zero, the ring is dead */ if ((I915_READ_CTL(ring) & RING_VALID) == 0 || - I915_READ_START(ring) != obj_priv->gtt_offset || + I915_READ_START(ring) != obj->gtt_offset || (I915_READ_HEAD(ring) & HEAD_ADDR) != 0) { DRM_ERROR("%s initialization failed " "ctl %08x head %08x tail %08x start %08x\n", @@ -514,17 +514,15 @@ render_ring_dispatch_execbuffer(struct intel_ring_buffer *ring, static void cleanup_status_page(struct intel_ring_buffer *ring) { drm_i915_private_t *dev_priv = ring->dev->dev_private; - struct drm_gem_object *obj; - struct drm_i915_gem_object *obj_priv; + struct drm_i915_gem_object *obj; obj = ring->status_page.obj; if (obj == NULL) return; - obj_priv = to_intel_bo(obj); - kunmap(obj_priv->pages[0]); + kunmap(obj->pages[0]); i915_gem_object_unpin(obj); - drm_gem_object_unreference(obj); + drm_gem_object_unreference(&obj->base); ring->status_page.obj = NULL; memset(&dev_priv->hws_map, 0, sizeof(dev_priv->hws_map)); @@ -534,8 +532,7 @@ static int init_status_page(struct intel_ring_buffer *ring) { struct drm_device *dev = ring->dev; drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_gem_object *obj; - struct drm_i915_gem_object *obj_priv; + struct drm_i915_gem_object *obj; int ret; obj = i915_gem_alloc_object(dev, 4096); @@ -544,16 +541,15 @@ static int init_status_page(struct intel_ring_buffer *ring) ret = -ENOMEM; goto err; } - obj_priv = to_intel_bo(obj); - obj_priv->agp_type = AGP_USER_CACHED_MEMORY; + obj->agp_type = AGP_USER_CACHED_MEMORY; ret = i915_gem_object_pin(obj, 4096, true); if (ret != 0) { goto err_unref; } - ring->status_page.gfx_addr = obj_priv->gtt_offset; - ring->status_page.page_addr = kmap(obj_priv->pages[0]); + ring->status_page.gfx_addr = obj->gtt_offset; + ring->status_page.page_addr = kmap(obj->pages[0]); if (ring->status_page.page_addr == NULL) { memset(&dev_priv->hws_map, 0, sizeof(dev_priv->hws_map)); goto err_unpin; @@ -570,7 +566,7 @@ static int init_status_page(struct intel_ring_buffer *ring) err_unpin: i915_gem_object_unpin(obj); err_unref: - drm_gem_object_unreference(obj); + drm_gem_object_unreference(&obj->base); err: return ret; } @@ -578,8 +574,7 @@ err: int intel_init_ring_buffer(struct drm_device *dev, struct intel_ring_buffer *ring) { - struct drm_i915_gem_object *obj_priv; - struct drm_gem_object *obj; + struct drm_i915_gem_object *obj; int ret; ring->dev = dev; @@ -600,15 +595,14 @@ int intel_init_ring_buffer(struct drm_device *dev, goto err_hws; } - ring->gem_object = obj; + ring->obj = obj; ret = i915_gem_object_pin(obj, PAGE_SIZE, true); if (ret) goto err_unref; - obj_priv = to_intel_bo(obj); ring->map.size = ring->size; - ring->map.offset = dev->agp->base + obj_priv->gtt_offset; + ring->map.offset = dev->agp->base + obj->gtt_offset; ring->map.type = 0; ring->map.flags = 0; ring->map.mtrr = 0; @@ -632,8 +626,8 @@ err_unmap: err_unpin: i915_gem_object_unpin(obj); err_unref: - drm_gem_object_unreference(obj); - ring->gem_object = NULL; + drm_gem_object_unreference(&obj->base); + ring->obj = NULL; err_hws: cleanup_status_page(ring); return ret; @@ -644,7 +638,7 @@ void intel_cleanup_ring_buffer(struct intel_ring_buffer *ring) struct drm_i915_private *dev_priv; int ret; - if (ring->gem_object == NULL) + if (ring->obj == NULL) return; /* Disable the ring buffer. The ring must be idle at this point */ @@ -654,9 +648,9 @@ void intel_cleanup_ring_buffer(struct intel_ring_buffer *ring) drm_core_ioremapfree(&ring->map, ring->dev); - i915_gem_object_unpin(ring->gem_object); - drm_gem_object_unreference(ring->gem_object); - ring->gem_object = NULL; + i915_gem_object_unpin(ring->obj); + drm_gem_object_unreference(&ring->obj->base); + ring->obj = NULL; if (ring->cleanup) ring->cleanup(ring); @@ -902,11 +896,11 @@ static int blt_ring_init(struct intel_ring_buffer *ring) u32 *ptr; int ret; - obj = to_intel_bo(i915_gem_alloc_object(ring->dev, 4096)); + obj = i915_gem_alloc_object(ring->dev, 4096); if (obj == NULL) return -ENOMEM; - ret = i915_gem_object_pin(&obj->base, 4096, true); + ret = i915_gem_object_pin(obj, 4096, true); if (ret) { drm_gem_object_unreference(&obj->base); return ret; @@ -917,9 +911,9 @@ static int blt_ring_init(struct intel_ring_buffer *ring) *ptr++ = MI_NOOP; kunmap(obj->pages[0]); - ret = i915_gem_object_set_to_gtt_domain(&obj->base, false); + ret = i915_gem_object_set_to_gtt_domain(obj, false); if (ret) { - i915_gem_object_unpin(&obj->base); + i915_gem_object_unpin(obj); drm_gem_object_unreference(&obj->base); return ret; } diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index 2565d65a625b..1747e329ee94 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -4,7 +4,7 @@ struct intel_hw_status_page { u32 __iomem *page_addr; unsigned int gfx_addr; - struct drm_gem_object *obj; + struct drm_i915_gem_object *obj; }; #define I915_RING_READ(reg) i915_safe_read(dev_priv, reg) @@ -32,7 +32,7 @@ struct intel_ring_buffer { u32 mmio_base; void *virtual_start; struct drm_device *dev; - struct drm_gem_object *gem_object; + struct drm_i915_gem_object *obj; unsigned int head; unsigned int tail; -- cgit v1.2.3 From 92b88aeb1ad67417c002fdd77409771ca7e5433a Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 9 Nov 2010 11:47:32 +0000 Subject: drm/i915: Not all mappable regions require GTT fence regions Combining map_and_fenceable revealed a bug in i915_gem_object_gtt_size() in that it always computed the appropriate fence size for the object regardless of tiling state which caused us to over-allocate linear buffers when binding to the GTT. Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_gem.c | 53 +++++++++++++++++------------------------ 1 file changed, 22 insertions(+), 31 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index d196895527a6..8e3f1de681ed 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -41,9 +41,6 @@ struct change_domains { uint32_t flush_rings; }; -static uint32_t i915_gem_get_gtt_alignment(struct drm_i915_gem_object *obj); -static uint32_t i915_gem_get_gtt_size(struct drm_i915_gem_object *obj); - static int i915_gem_object_flush_gpu_write_domain(struct drm_i915_gem_object *obj, bool pipelined); static void i915_gem_object_flush_gtt_write_domain(struct drm_i915_gem_object *obj); @@ -1443,6 +1440,28 @@ i915_gem_free_mmap_offset(struct drm_i915_gem_object *obj) list->map = NULL; } +static uint32_t +i915_gem_get_gtt_size(struct drm_i915_gem_object *obj) +{ + struct drm_device *dev = obj->base.dev; + uint32_t size; + + if (INTEL_INFO(dev)->gen >= 4 || + obj->tiling_mode == I915_TILING_NONE) + return obj->base.size; + + /* Previous chips need a power-of-two fence region when tiling */ + if (INTEL_INFO(dev)->gen == 3) + size = 1024*1024; + else + size = 512*1024; + + while (size < obj->base.size) + size <<= 1; + + return size; +} + /** * i915_gem_get_gtt_alignment - return required GTT alignment for an object * @obj: object to check @@ -1505,34 +1524,6 @@ i915_gem_get_unfenced_gtt_alignment(struct drm_i915_gem_object *obj) return tile_height * obj->stride * 2; } -static uint32_t -i915_gem_get_gtt_size(struct drm_i915_gem_object *obj) -{ - struct drm_device *dev = obj->base.dev; - uint32_t size; - - /* - * Minimum alignment is 4k (GTT page size), but might be greater - * if a fence register is needed for the object. - */ - if (INTEL_INFO(dev)->gen >= 4) - return obj->base.size; - - /* - * Previous chips need to be aligned to the size of the smallest - * fence register that can contain the object. - */ - if (INTEL_INFO(dev)->gen == 3) - size = 1024*1024; - else - size = 512*1024; - - while (size < obj->base.size) - size <<= 1; - - return size; -} - /** * i915_gem_mmap_gtt_ioctl - prepare an object for GTT mmap'ing * @dev: DRM device -- cgit v1.2.3 From 7bdc9ab00b1b0fdbb490f41c5c7c2fbc66fed9ee Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 9 Nov 2010 17:53:20 +0000 Subject: agp/intel: Remove duplicate const drivers/char/agp/intel-gtt.c:340:48: warning: duplicate const Signed-off-by: Chris Wilson --- drivers/char/agp/intel-gtt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/char/agp/intel-gtt.c b/drivers/char/agp/intel-gtt.c index 5a2b7360f5be..8cf600cdac06 100644 --- a/drivers/char/agp/intel-gtt.c +++ b/drivers/char/agp/intel-gtt.c @@ -334,7 +334,7 @@ static void i810_write_entry(dma_addr_t addr, unsigned int entry, writel(addr | pte_flags, intel_private.gtt + entry); } -static const struct aper_size_info_fixed const intel_fake_agp_sizes[] = { +static const struct aper_size_info_fixed intel_fake_agp_sizes[] = { {32, 8192, 3}, {64, 16384, 4}, {128, 32768, 5}, -- cgit v1.2.3 From 748ebc6017a943ec065e653e975a5e8dace77ac6 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sun, 24 Oct 2010 10:28:47 +0100 Subject: drm/i915: Record fence registers on error. Having seen the effects of erroneous fencing on the batchbuffer, a useful sanity check is to record the fence registers at the time of an error. Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_debugfs.c | 3 +++ drivers/gpu/drm/i915/i915_drv.h | 1 + drivers/gpu/drm/i915/i915_irq.c | 30 ++++++++++++++++++++++++++++++ 3 files changed, 34 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 1e8cd74d18d5..addb9392e1c4 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -684,6 +684,9 @@ static int i915_error_state(struct seq_file *m, void *unused) seq_printf(m, " INSTPM: 0x%08x\n", error->instpm); seq_printf(m, " seqno: 0x%08x\n", error->seqno); + for (i = 0; i < 16; i++) + seq_printf(m, " fence[%d] = %08llx\n", i, error->fence[i]); + if (error->active_bo) print_error_buffers(m, "Active", error->active_bo, diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 22d6388b331f..699e71a0dab7 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -166,6 +166,7 @@ struct drm_i915_error_state { u32 instdone1; u32 seqno; u64 bbaddr; + u64 fence[16]; struct timeval time; struct drm_i915_error_object { int page_count; diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 09ac3bbd8165..de95c7bb6dba 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -581,6 +581,35 @@ static u32 capture_bo_list(struct drm_i915_error_buffer *err, return i; } +static void i915_gem_record_fences(struct drm_device *dev, + struct drm_i915_error_state *error) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + int i; + + /* Fences */ + switch (INTEL_INFO(dev)->gen) { + case 6: + for (i = 0; i < 16; i++) + error->fence[i] = I915_READ64(FENCE_REG_SANDYBRIDGE_0 + (i * 8)); + break; + case 5: + case 4: + for (i = 0; i < 16; i++) + error->fence[i] = I915_READ64(FENCE_REG_965_0 + (i * 8)); + break; + case 3: + if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev)) + for (i = 0; i < 8; i++) + error->fence[i+8] = I915_READ(FENCE_REG_945_8 + (i * 4)); + case 2: + for (i = 0; i < 8; i++) + error->fence[i] = I915_READ(FENCE_REG_830_0 + (i * 4)); + break; + + } +} + /** * i915_capture_error_state - capture an error record for later analysis * @dev: drm device @@ -656,6 +685,7 @@ static void i915_capture_error_state(struct drm_device *dev) error->acthd = I915_READ(ACTHD); error->bbaddr = 0; } + i915_gem_record_fences(dev, error); bbaddr = i915_ringbuffer_last_batch(dev, &dev_priv->render_ring); -- cgit v1.2.3 From b6913e4bdb09134dbdccd613e880d413b5911591 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 12 Nov 2010 10:46:37 +0000 Subject: drm/i915: Move the implementation details of PIPE_CONTROL to the ringbuffer The pipe control object is allocated by the device for the sole use of the render ringbuffer. Move this detail from the general code to the render ring buffer initialisation. Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_drv.h | 3 - drivers/gpu/drm/i915/i915_gem.c | 70 +-------------------- drivers/gpu/drm/i915/intel_ringbuffer.c | 105 +++++++++++++++++++++++++++++--- 3 files changed, 97 insertions(+), 81 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 699e71a0dab7..5afcf2a07cfc 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -275,12 +275,9 @@ typedef struct drm_i915_private { uint32_t next_seqno; drm_dma_handle_t *status_page_dmah; - void *seqno_page; dma_addr_t dma_status_page; uint32_t counter; - unsigned int seqno_gfx_addr; drm_local_map_t hws_map; - struct drm_i915_gem_object *seqno_obj; struct drm_i915_gem_object *pwrctx; struct drm_i915_gem_object *renderctx; diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 8e3f1de681ed..027212e5c34a 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -4625,78 +4625,15 @@ i915_gem_idle(struct drm_device *dev) return 0; } -/* - * 965+ support PIPE_CONTROL commands, which provide finer grained control - * over cache flushing. - */ -static int -i915_gem_init_pipe_control(struct drm_device *dev) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_i915_gem_object *obj; - int ret; - - obj = i915_gem_alloc_object(dev, 4096); - if (obj == NULL) { - DRM_ERROR("Failed to allocate seqno page\n"); - ret = -ENOMEM; - goto err; - } - obj->agp_type = AGP_USER_CACHED_MEMORY; - - ret = i915_gem_object_pin(obj, 4096, true); - if (ret) - goto err_unref; - - dev_priv->seqno_gfx_addr = obj->gtt_offset; - dev_priv->seqno_page = kmap(obj->pages[0]); - if (dev_priv->seqno_page == NULL) - goto err_unpin; - - dev_priv->seqno_obj = obj; - memset(dev_priv->seqno_page, 0, PAGE_SIZE); - - return 0; - -err_unpin: - i915_gem_object_unpin(obj); -err_unref: - drm_gem_object_unreference(&obj->base); -err: - return ret; -} - - -static void -i915_gem_cleanup_pipe_control(struct drm_device *dev) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_i915_gem_object *obj; - - obj = dev_priv->seqno_obj; - kunmap(obj->pages[0]); - i915_gem_object_unpin(obj); - drm_gem_object_unreference(&obj->base); - dev_priv->seqno_obj = NULL; - - dev_priv->seqno_page = NULL; -} - int i915_gem_init_ringbuffer(struct drm_device *dev) { drm_i915_private_t *dev_priv = dev->dev_private; int ret; - if (HAS_PIPE_CONTROL(dev)) { - ret = i915_gem_init_pipe_control(dev); - if (ret) - return ret; - } - ret = intel_init_render_ring_buffer(dev); if (ret) - goto cleanup_pipe_control; + return ret; if (HAS_BSD(dev)) { ret = intel_init_bsd_ring_buffer(dev); @@ -4718,9 +4655,6 @@ cleanup_bsd_ring: intel_cleanup_ring_buffer(&dev_priv->bsd_ring); cleanup_render_ring: intel_cleanup_ring_buffer(&dev_priv->render_ring); -cleanup_pipe_control: - if (HAS_PIPE_CONTROL(dev)) - i915_gem_cleanup_pipe_control(dev); return ret; } @@ -4732,8 +4666,6 @@ i915_gem_cleanup_ringbuffer(struct drm_device *dev) intel_cleanup_ring_buffer(&dev_priv->render_ring); intel_cleanup_ring_buffer(&dev_priv->bsd_ring); intel_cleanup_ring_buffer(&dev_priv->blt_ring); - if (HAS_PIPE_CONTROL(dev)) - i915_gem_cleanup_pipe_control(dev); } int diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 181aad31125d..b12578558268 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -202,6 +202,78 @@ static int init_ring_common(struct intel_ring_buffer *ring) return 0; } +/* + * 965+ support PIPE_CONTROL commands, which provide finer grained control + * over cache flushing. + */ +struct pipe_control { + struct drm_i915_gem_object *obj; + volatile u32 *cpu_page; + u32 gtt_offset; +}; + +static int +init_pipe_control(struct intel_ring_buffer *ring) +{ + struct pipe_control *pc; + struct drm_i915_gem_object *obj; + int ret; + + if (ring->private) + return 0; + + pc = kmalloc(sizeof(*pc), GFP_KERNEL); + if (!pc) + return -ENOMEM; + + obj = i915_gem_alloc_object(ring->dev, 4096); + if (obj == NULL) { + DRM_ERROR("Failed to allocate seqno page\n"); + ret = -ENOMEM; + goto err; + } + obj->agp_type = AGP_USER_CACHED_MEMORY; + + ret = i915_gem_object_pin(obj, 4096, true); + if (ret) + goto err_unref; + + pc->gtt_offset = obj->gtt_offset; + pc->cpu_page = kmap(obj->pages[0]); + if (pc->cpu_page == NULL) + goto err_unpin; + + pc->obj = obj; + ring->private = pc; + return 0; + +err_unpin: + i915_gem_object_unpin(obj); +err_unref: + drm_gem_object_unreference(&obj->base); +err: + kfree(pc); + return ret; +} + +static void +cleanup_pipe_control(struct intel_ring_buffer *ring) +{ + struct pipe_control *pc = ring->private; + struct drm_i915_gem_object *obj; + + if (!ring->private) + return; + + obj = pc->obj; + kunmap(obj->pages[0]); + i915_gem_object_unpin(obj); + drm_gem_object_unreference(&obj->base); + + kfree(pc); + ring->private = NULL; +} + static int init_render_ring(struct intel_ring_buffer *ring) { struct drm_device *dev = ring->dev; @@ -215,9 +287,23 @@ static int init_render_ring(struct intel_ring_buffer *ring) I915_WRITE(MI_MODE, mode); } + if (HAS_PIPE_CONTROL(dev)) { + ret = init_pipe_control(ring); + if (ret) + return ret; + } + return ret; } +static void render_ring_cleanup(struct intel_ring_buffer *ring) +{ + if (!ring->private) + return; + + cleanup_pipe_control(ring); +} + #define PIPE_CONTROL_FLUSH(ring__, addr__) \ do { \ intel_ring_emit(ring__, GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE | \ @@ -240,8 +326,8 @@ render_ring_add_request(struct intel_ring_buffer *ring, u32 *result) { struct drm_device *dev = ring->dev; - drm_i915_private_t *dev_priv = dev->dev_private; u32 seqno = i915_gem_get_seqno(dev); + struct pipe_control *pc = ring->private; int ret; if (IS_GEN6(dev)) { @@ -253,12 +339,12 @@ render_ring_add_request(struct intel_ring_buffer *ring, intel_ring_emit(ring, PIPE_CONTROL_QW_WRITE | PIPE_CONTROL_WC_FLUSH | PIPE_CONTROL_IS_FLUSH | PIPE_CONTROL_NOTIFY); - intel_ring_emit(ring, dev_priv->seqno_gfx_addr | PIPE_CONTROL_GLOBAL_GTT); + intel_ring_emit(ring, pc->gtt_offset | PIPE_CONTROL_GLOBAL_GTT); intel_ring_emit(ring, seqno); intel_ring_emit(ring, 0); intel_ring_emit(ring, 0); } else if (HAS_PIPE_CONTROL(dev)) { - u32 scratch_addr = dev_priv->seqno_gfx_addr + 128; + u32 scratch_addr = pc->gtt_offset + 128; /* * Workaround qword write incoherence by flushing the @@ -271,7 +357,7 @@ render_ring_add_request(struct intel_ring_buffer *ring, intel_ring_emit(ring, GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE | PIPE_CONTROL_WC_FLUSH | PIPE_CONTROL_TC_FLUSH); - intel_ring_emit(ring, dev_priv->seqno_gfx_addr | PIPE_CONTROL_GLOBAL_GTT); + intel_ring_emit(ring, pc->gtt_offset | PIPE_CONTROL_GLOBAL_GTT); intel_ring_emit(ring, seqno); intel_ring_emit(ring, 0); PIPE_CONTROL_FLUSH(ring, scratch_addr); @@ -288,7 +374,7 @@ render_ring_add_request(struct intel_ring_buffer *ring, intel_ring_emit(ring, GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE | PIPE_CONTROL_WC_FLUSH | PIPE_CONTROL_TC_FLUSH | PIPE_CONTROL_NOTIFY); - intel_ring_emit(ring, dev_priv->seqno_gfx_addr | PIPE_CONTROL_GLOBAL_GTT); + intel_ring_emit(ring, pc->gtt_offset | PIPE_CONTROL_GLOBAL_GTT); intel_ring_emit(ring, seqno); intel_ring_emit(ring, 0); } else { @@ -312,10 +398,10 @@ static u32 render_ring_get_seqno(struct intel_ring_buffer *ring) { struct drm_device *dev = ring->dev; - drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; - if (HAS_PIPE_CONTROL(dev)) - return ((volatile u32 *)(dev_priv->seqno_page))[0]; - else + if (HAS_PIPE_CONTROL(dev)) { + struct pipe_control *pc = ring->private; + return pc->cpu_page[0]; + } else return intel_read_status_page(ring, I915_GEM_HWS_INDEX); } @@ -767,6 +853,7 @@ static const struct intel_ring_buffer render_ring = { .user_irq_get = render_ring_get_user_irq, .user_irq_put = render_ring_put_user_irq, .dispatch_execbuffer = render_ring_dispatch_execbuffer, + .cleanup = render_ring_cleanup, }; /* ring buffer for bit-stream decoder */ -- cgit v1.2.3 From dddbc0e5257572079602654258adc8d117e168ad Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 12 Nov 2010 13:56:11 +0000 Subject: drm/i915: Remove a defunct BUG_ON This used to check the precondition that all fences were to be located in a mappable area, redundant now as those two parameters are combined into one. After pinning, we assert that the buffer is bound into the desired region. Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_gem.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 027212e5c34a..7d6ce34789ca 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -4248,7 +4248,6 @@ i915_gem_object_pin(struct drm_i915_gem_object *obj, int ret; BUG_ON(obj->pin_count == DRM_I915_GEM_OBJECT_MAX_PIN_COUNT); - BUG_ON(map_and_fenceable && !map_and_fenceable); WARN_ON(i915_verify_lists(dev)); if (obj->gtt_space != NULL) { -- cgit v1.2.3 From 576ae4b8e46b4cb9d5390f4348c265329793d9bf Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 12 Nov 2010 13:36:26 +0000 Subject: drm/i915: Extend hangcheck timeout ... reduce the frequency of checking to further reduce the wakeups and CPU overhead. Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_drv.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 5afcf2a07cfc..eb3f1f756e81 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -315,7 +315,7 @@ typedef struct drm_i915_private { int num_pipe; /* For hangcheck timer */ -#define DRM_I915_HANGCHECK_PERIOD 250 /* in ms */ +#define DRM_I915_HANGCHECK_PERIOD 1500 /* in ms */ struct timer_list hangcheck_timer; int hangcheck_count; uint32_t last_acthd; -- cgit v1.2.3 From 919926aeb3e89825093c743dd54f04e42e7d9150 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 12 Nov 2010 13:42:53 +0000 Subject: drm/i915: Thread the pipelining ring through the callers. Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_drv.h | 2 +- drivers/gpu/drm/i915/i915_gem.c | 28 +++++++++++++--------------- drivers/gpu/drm/i915/intel_display.c | 6 +++--- drivers/gpu/drm/i915/intel_drv.h | 2 +- 4 files changed, 18 insertions(+), 20 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index eb3f1f756e81..42d3e901619d 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1133,7 +1133,7 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf); int i915_gem_object_set_to_gtt_domain(struct drm_i915_gem_object *obj, int write); int i915_gem_object_set_to_display_plane(struct drm_i915_gem_object *obj, - bool pipelined); + struct intel_ring_buffer *pipelined); int i915_gem_attach_phys_object(struct drm_device *dev, struct drm_i915_gem_object *obj, int id, diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 7d6ce34789ca..465e07abf5d0 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -42,11 +42,11 @@ struct change_domains { }; static int i915_gem_object_flush_gpu_write_domain(struct drm_i915_gem_object *obj, - bool pipelined); + struct intel_ring_buffer *pipelined); static void i915_gem_object_flush_gtt_write_domain(struct drm_i915_gem_object *obj); static void i915_gem_object_flush_cpu_write_domain(struct drm_i915_gem_object *obj); static int i915_gem_object_set_to_cpu_domain(struct drm_i915_gem_object *obj, - int write); + bool write); static int i915_gem_object_set_cpu_read_domain_range(struct drm_i915_gem_object *obj, uint64_t offset, uint64_t size); @@ -1274,12 +1274,10 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) mutex_lock(&dev->struct_mutex); BUG_ON(obj->pin_count && !obj->pin_mappable); - if (obj->gtt_space) { - if (!obj->map_and_fenceable) { - ret = i915_gem_object_unbind(obj); - if (ret) - goto unlock; - } + if (!obj->map_and_fenceable) { + ret = i915_gem_object_unbind(obj); + if (ret) + goto unlock; } if (!obj->gtt_space) { @@ -2637,7 +2635,7 @@ i915_gem_object_put_fence_reg(struct drm_i915_gem_object *obj, if (reg->gpu) { int ret; - ret = i915_gem_object_flush_gpu_write_domain(obj, true); + ret = i915_gem_object_flush_gpu_write_domain(obj, NULL); if (ret) return ret; @@ -2817,7 +2815,7 @@ i915_gem_clflush_object(struct drm_i915_gem_object *obj) /** Flushes any GPU write domain for the object if it's dirty. */ static int i915_gem_object_flush_gpu_write_domain(struct drm_i915_gem_object *obj, - bool pipelined) + struct intel_ring_buffer *pipelined) { struct drm_device *dev = obj->base.dev; @@ -2828,7 +2826,7 @@ i915_gem_object_flush_gpu_write_domain(struct drm_i915_gem_object *obj, i915_gem_flush_ring(dev, obj->ring, 0, obj->base.write_domain); BUG_ON(obj->base.write_domain); - if (pipelined) + if (pipelined && pipelined == obj->ring) return 0; return i915_gem_object_wait_rendering(obj, true); @@ -2892,7 +2890,7 @@ i915_gem_object_set_to_gtt_domain(struct drm_i915_gem_object *obj, int write) if (obj->gtt_space == NULL) return -EINVAL; - ret = i915_gem_object_flush_gpu_write_domain(obj, false); + ret = i915_gem_object_flush_gpu_write_domain(obj, NULL); if (ret != 0) return ret; @@ -2931,7 +2929,7 @@ i915_gem_object_set_to_gtt_domain(struct drm_i915_gem_object *obj, int write) */ int i915_gem_object_set_to_display_plane(struct drm_i915_gem_object *obj, - bool pipelined) + struct intel_ring_buffer *pipelined) { uint32_t old_read_domains; int ret; @@ -2940,7 +2938,7 @@ i915_gem_object_set_to_display_plane(struct drm_i915_gem_object *obj, if (obj->gtt_space == NULL) return -EINVAL; - ret = i915_gem_object_flush_gpu_write_domain(obj, true); + ret = i915_gem_object_flush_gpu_write_domain(obj, pipelined); if (ret) return ret; @@ -2984,7 +2982,7 @@ i915_gem_object_flush_gpu(struct drm_i915_gem_object *obj, * flushes to occur. */ static int -i915_gem_object_set_to_cpu_domain(struct drm_i915_gem_object *obj, int write) +i915_gem_object_set_to_cpu_domain(struct drm_i915_gem_object *obj, bool write) { uint32_t old_write_domain, old_read_domains; int ret; diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index ae7d4f55ce07..c2c94a26f92e 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -1434,7 +1434,7 @@ out_disable: int intel_pin_and_fence_fb_obj(struct drm_device *dev, struct drm_i915_gem_object *obj, - bool pipelined) + struct intel_ring_buffer *pipelined) { u32 alignment; int ret; @@ -1594,7 +1594,7 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, mutex_lock(&dev->struct_mutex); ret = intel_pin_and_fence_fb_obj(dev, to_intel_framebuffer(crtc->fb)->obj, - false); + NULL); if (ret != 0) { mutex_unlock(&dev->struct_mutex); return ret; @@ -5092,7 +5092,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, obj = intel_fb->obj; mutex_lock(&dev->struct_mutex); - ret = intel_pin_and_fence_fb_obj(dev, obj, true); + ret = intel_pin_and_fence_fb_obj(dev, obj, &dev_priv->render_ring); if (ret) goto cleanup_work; diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 5a4f14e36d6c..5154e315300d 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -301,7 +301,7 @@ extern void intel_init_emon(struct drm_device *dev); extern int intel_pin_and_fence_fb_obj(struct drm_device *dev, struct drm_i915_gem_object *obj, - bool pipelined); + struct intel_ring_buffer *pipelined); extern int intel_framebuffer_init(struct drm_device *dev, struct intel_framebuffer *ifb, -- cgit v1.2.3 From 03cfe6f57dc5c13ccdd235c23c80e3fa170f03d1 Mon Sep 17 00:00:00 2001 From: Kay Sievers Date: Tue, 23 Nov 2010 17:43:19 +0100 Subject: ALSA: support module on-demand loading for seq and timer If CONFIG_SND_DYNAMIC_MINORS is used, assign /dev/snd/seq and /dev/snd/timer the usual static minors, and export specific module aliases to generate udev module on-demand loading instructions: $ cat /lib/modules/2.6.33.4-smp/modules.devname # Device nodes to trigger on-demand module loading. microcode cpu/microcode c10:184 fuse fuse c10:229 ppp_generic ppp c108:0 tun net/tun c10:200 uinput uinput c10:223 dm_mod mapper/control c10:236 snd_timer snd/timer c116:33 snd_seq snd/seq c116:1 The last two lines instruct udev to create device nodes, even when the modules are not loaded at that time. As soon as userspace accesses any of these nodes, the in-kernel module-loader will load the module, and the device can be used. The header file minor calculation needed to be simplified to make __stringify() (supports only two indirections) in the MODULE_ALIAS macro work. This is part of systemd's effort to get rid of unconditional module load instructions and needless init scripts. Cc: Lennart Poettering Signed-off-by: Kay Sievers Signed-off-by: Clemens Ladisch Signed-off-by: Takashi Iwai --- include/sound/minors.h | 4 ++-- sound/core/seq/seq.c | 4 ++++ sound/core/sound.c | 18 +++++++++++++----- sound/core/timer.c | 3 +++ 4 files changed, 22 insertions(+), 7 deletions(-) diff --git a/include/sound/minors.h b/include/sound/minors.h index a81798ab73ed..8f764204a856 100644 --- a/include/sound/minors.h +++ b/include/sound/minors.h @@ -31,8 +31,8 @@ /* these minors can still be used for autoloading devices (/dev/aload*) */ #define SNDRV_MINOR_CONTROL 0 /* 0 */ #define SNDRV_MINOR_GLOBAL 1 /* 1 */ -#define SNDRV_MINOR_SEQUENCER (SNDRV_MINOR_GLOBAL + 0 * 32) -#define SNDRV_MINOR_TIMER (SNDRV_MINOR_GLOBAL + 1 * 32) +#define SNDRV_MINOR_SEQUENCER 1 /* SNDRV_MINOR_GLOBAL + 0 * 32 */ +#define SNDRV_MINOR_TIMER 33 /* SNDRV_MINOR_GLOBAL + 1 * 32 */ #ifndef CONFIG_SND_DYNAMIC_MINORS /* 2 - 3 (reserved) */ diff --git a/sound/core/seq/seq.c b/sound/core/seq/seq.c index bf09a5ad1865..119fddb6fc99 100644 --- a/sound/core/seq/seq.c +++ b/sound/core/seq/seq.c @@ -32,6 +32,7 @@ #include "seq_timer.h" #include "seq_system.h" #include "seq_info.h" +#include #include #if defined(CONFIG_SND_SEQ_DUMMY_MODULE) @@ -73,6 +74,9 @@ MODULE_PARM_DESC(seq_default_timer_subdevice, "The default timer subdevice numbe module_param(seq_default_timer_resolution, int, 0644); MODULE_PARM_DESC(seq_default_timer_resolution, "The default timer resolution in Hz."); +MODULE_ALIAS_CHARDEV(CONFIG_SND_MAJOR, SNDRV_MINOR_SEQUENCER); +MODULE_ALIAS("devname:snd/seq"); + /* * INIT PART */ diff --git a/sound/core/sound.c b/sound/core/sound.c index 62a093efb453..345caea2d749 100644 --- a/sound/core/sound.c +++ b/sound/core/sound.c @@ -189,14 +189,22 @@ static const struct file_operations snd_fops = }; #ifdef CONFIG_SND_DYNAMIC_MINORS -static int snd_find_free_minor(void) +static int snd_find_free_minor(int type) { int minor; + /* static minors for module auto loading */ + if (type == SNDRV_DEVICE_TYPE_SEQUENCER) + return SNDRV_MINOR_SEQUENCER; + if (type == SNDRV_DEVICE_TYPE_TIMER) + return SNDRV_MINOR_TIMER; + for (minor = 0; minor < ARRAY_SIZE(snd_minors); ++minor) { - /* skip minors still used statically for autoloading devices */ - if (SNDRV_MINOR_DEVICE(minor) == SNDRV_MINOR_CONTROL || - minor == SNDRV_MINOR_SEQUENCER) + /* skip static minors still used for module auto loading */ + if (SNDRV_MINOR_DEVICE(minor) == SNDRV_MINOR_CONTROL) + continue; + if (minor == SNDRV_MINOR_SEQUENCER || + minor == SNDRV_MINOR_TIMER) continue; if (!snd_minors[minor]) return minor; @@ -270,7 +278,7 @@ int snd_register_device_for_dev(int type, struct snd_card *card, int dev, preg->private_data = private_data; mutex_lock(&sound_mutex); #ifdef CONFIG_SND_DYNAMIC_MINORS - minor = snd_find_free_minor(); + minor = snd_find_free_minor(type); #else minor = snd_kernel_minor(type, card, dev); if (minor >= 0 && snd_minors[minor]) diff --git a/sound/core/timer.c b/sound/core/timer.c index b3aaa600dcc2..ed016329e911 100644 --- a/sound/core/timer.c +++ b/sound/core/timer.c @@ -52,6 +52,9 @@ MODULE_PARM_DESC(timer_limit, "Maximum global timers in system."); module_param(timer_tstamp_monotonic, int, 0444); MODULE_PARM_DESC(timer_tstamp_monotonic, "Use posix monotonic clock source for timestamps (default)."); +MODULE_ALIAS_CHARDEV(CONFIG_SND_MAJOR, SNDRV_MINOR_TIMER); +MODULE_ALIAS("devname:snd/timer"); + struct snd_timer_user { struct snd_timer_instance *timeri; int tread; /* enhanced read with timestamps and events */ -- cgit v1.2.3 From 2a9ae13a2641373d06e24f866c7427644c39bfea Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 23 Nov 2010 19:31:18 +0000 Subject: ASoC: Add initial WM8737 driver The WM8737 is a low power, flexible stereo ADC designed for portable applications. This driver supports most of the functionality of the WM8737, though some features such as the ALC are not yet implemented. Signed-off-by: Mark Brown --- sound/soc/codecs/Kconfig | 4 + sound/soc/codecs/Makefile | 2 + sound/soc/codecs/wm8737.c | 713 ++++++++++++++++++++++++++++++++++++++++++++++ sound/soc/codecs/wm8737.h | 322 +++++++++++++++++++++ 4 files changed, 1041 insertions(+) create mode 100644 sound/soc/codecs/wm8737.c create mode 100644 sound/soc/codecs/wm8737.h diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index 6ebd3a685b2c..0f33db2be25a 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -55,6 +55,7 @@ config SND_SOC_ALL_CODECS select SND_SOC_WM8727 select SND_SOC_WM8728 if SND_SOC_I2C_AND_SPI select SND_SOC_WM8731 if SND_SOC_I2C_AND_SPI + select SND_SOC_WM8737 if SND_SOC_I2C_AND_SPI select SND_SOC_WM8741 if SND_SOC_I2C_AND_SPI select SND_SOC_WM8750 if SND_SOC_I2C_AND_SPI select SND_SOC_WM8753 if SND_SOC_I2C_AND_SPI @@ -236,6 +237,9 @@ config SND_SOC_WM8728 config SND_SOC_WM8731 tristate +config SND_SOC_WM8737 + tristate + config SND_SOC_WM8741 tristate diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index 3469fab2863a..10e5e099334a 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile @@ -39,6 +39,7 @@ snd-soc-wm8711-objs := wm8711.o snd-soc-wm8727-objs := wm8727.o snd-soc-wm8728-objs := wm8728.o snd-soc-wm8731-objs := wm8731.o +snd-soc-wm8737-objs := wm8737.o snd-soc-wm8741-objs := wm8741.o snd-soc-wm8750-objs := wm8750.o snd-soc-wm8753-objs := wm8753.o @@ -116,6 +117,7 @@ obj-$(CONFIG_SND_SOC_WM8711) += snd-soc-wm8711.o obj-$(CONFIG_SND_SOC_WM8727) += snd-soc-wm8727.o obj-$(CONFIG_SND_SOC_WM8728) += snd-soc-wm8728.o obj-$(CONFIG_SND_SOC_WM8731) += snd-soc-wm8731.o +obj-$(CONFIG_SND_SOC_WM8737) += snd-soc-wm8737.o obj-$(CONFIG_SND_SOC_WM8741) += snd-soc-wm8741.o obj-$(CONFIG_SND_SOC_WM8750) += snd-soc-wm8750.o obj-$(CONFIG_SND_SOC_WM8753) += snd-soc-wm8753.o diff --git a/sound/soc/codecs/wm8737.c b/sound/soc/codecs/wm8737.c new file mode 100644 index 000000000000..a325fe60d26c --- /dev/null +++ b/sound/soc/codecs/wm8737.c @@ -0,0 +1,713 @@ +/* + * wm8737.c -- WM8737 ALSA SoC Audio driver + * + * Copyright 2010 Wolfson Microelectronics plc + * + * Author: Mark Brown + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "wm8737.h" + +#define WM8737_NUM_SUPPLIES 4 +static const char *wm8737_supply_names[WM8737_NUM_SUPPLIES] = { + "DCVDD", + "DBVDD", + "AVDD", + "MVDD", +}; + +/* codec private data */ +struct wm8737_priv { + enum snd_soc_control_type control_type; + struct regulator_bulk_data supplies[WM8737_NUM_SUPPLIES]; + unsigned int mclk; +}; + +static const u16 wm8737_reg[WM8737_REGISTER_COUNT] = { + 0x00C3, /* R0 - Left PGA volume */ + 0x00C3, /* R1 - Right PGA volume */ + 0x0007, /* R2 - AUDIO path L */ + 0x0007, /* R3 - AUDIO path R */ + 0x0000, /* R4 - 3D Enhance */ + 0x0000, /* R5 - ADC Control */ + 0x0000, /* R6 - Power Management */ + 0x000A, /* R7 - Audio Format */ + 0x0000, /* R8 - Clocking */ + 0x000F, /* R9 - MIC Preamp Control */ + 0x0003, /* R10 - Misc Bias Control */ + 0x0000, /* R11 - Noise Gate */ + 0x007C, /* R12 - ALC1 */ + 0x0000, /* R13 - ALC2 */ + 0x0032, /* R14 - ALC3 */ +}; + +static int wm8737_reset(struct snd_soc_codec *codec) +{ + return snd_soc_write(codec, WM8737_RESET, 0); +} + +static const unsigned int micboost_tlv[] = { + TLV_DB_RANGE_HEAD(4), + 0, 0, TLV_DB_SCALE_ITEM(1300, 0, 0), + 1, 1, TLV_DB_SCALE_ITEM(1800, 0, 0), + 2, 2, TLV_DB_SCALE_ITEM(2800, 0, 0), + 3, 3, TLV_DB_SCALE_ITEM(3300, 0, 0), +}; +static const DECLARE_TLV_DB_SCALE(pga_tlv, -9750, 50, 1); +static const DECLARE_TLV_DB_SCALE(adc_tlv, -600, 600, 0); +static const DECLARE_TLV_DB_SCALE(ng_tlv, -7800, 600, 0); + +static const char *micbias_enum_text[] = { + "25%", + "50%", + "75%", + "100%", +}; + +static const struct soc_enum micbias_enum = + SOC_ENUM_SINGLE(WM8737_MIC_PREAMP_CONTROL, 0, 4, micbias_enum_text); + +static const char *low_cutoff_text[] = { + "Low", "High" +}; + +static const struct soc_enum low_3d = + SOC_ENUM_SINGLE(WM8737_3D_ENHANCE, 6, 2, low_cutoff_text); + +static const char *high_cutoff_text[] = { + "High", "Low" +}; + +static const struct soc_enum high_3d = + SOC_ENUM_SINGLE(WM8737_3D_ENHANCE, 5, 2, high_cutoff_text); + +static const struct snd_kcontrol_new wm8737_snd_controls[] = { +SOC_DOUBLE_R_TLV("Mic Boost Volume", WM8737_AUDIO_PATH_L, WM8737_AUDIO_PATH_R, + 6, 3, 0, micboost_tlv), +SOC_DOUBLE_R("Mic Boost Switch", WM8737_AUDIO_PATH_L, WM8737_AUDIO_PATH_R, + 4, 1, 0), +SOC_DOUBLE("Mic ZC Switch", WM8737_AUDIO_PATH_L, WM8737_AUDIO_PATH_R, + 3, 1, 0), + +SOC_DOUBLE_R_TLV("Capture Volume", WM8737_LEFT_PGA_VOLUME, + WM8737_RIGHT_PGA_VOLUME, 0, 255, 0, pga_tlv), +SOC_DOUBLE("Capture ZC Switch", WM8737_AUDIO_PATH_L, WM8737_AUDIO_PATH_R, + 2, 1, 0), + +SOC_DOUBLE("INPUT1 DC Bias Switch", WM8737_MISC_BIAS_CONTROL, 0, 1, 1, 0), + +SOC_ENUM("Mic PGA Bias", micbias_enum), +SOC_SINGLE("ADC Low Power Switch", WM8737_ADC_CONTROL, 2, 1, 0), +SOC_SINGLE("High Pass Filter Switch", WM8737_ADC_CONTROL, 0, 1, 1), +SOC_DOUBLE("Polarity Invert Switch", WM8737_ADC_CONTROL, 5, 6, 1, 0), + +SOC_SINGLE("3D Switch", WM8737_3D_ENHANCE, 0, 1, 0), +SOC_SINGLE("3D Depth", WM8737_3D_ENHANCE, 1, 15, 0), +SOC_ENUM("3D Low Cut-off", low_3d), +SOC_ENUM("3D High Cut-off", low_3d), +SOC_SINGLE_TLV("3D ADC Volume", WM8737_3D_ENHANCE, 7, 1, 1, adc_tlv), + +SOC_SINGLE("Noise Gate Switch", WM8737_NOISE_GATE, 0, 1, 0), +SOC_SINGLE_TLV("Noise Gate Threshold Volume", WM8737_NOISE_GATE, 2, 7, 0, + ng_tlv), +}; + +static const char *linsel_text[] = { + "LINPUT1", "LINPUT2", "LINPUT3", "LINPUT1 DC", +}; + +static const struct soc_enum linsel_enum = + SOC_ENUM_SINGLE(WM8737_AUDIO_PATH_L, 7, 4, linsel_text); + +static const struct snd_kcontrol_new linsel_mux = + SOC_DAPM_ENUM("LINSEL", linsel_enum); + + +static const char *rinsel_text[] = { + "RINPUT1", "RINPUT2", "RINPUT3", "RINPUT1 DC", +}; + +static const struct soc_enum rinsel_enum = + SOC_ENUM_SINGLE(WM8737_AUDIO_PATH_R, 7, 4, rinsel_text); + +static const struct snd_kcontrol_new rinsel_mux = + SOC_DAPM_ENUM("RINSEL", rinsel_enum); + +static const char *bypass_text[] = { + "Direct", "Preamp" +}; + +static const struct soc_enum lbypass_enum = + SOC_ENUM_SINGLE(WM8737_MIC_PREAMP_CONTROL, 2, 2, bypass_text); + +static const struct snd_kcontrol_new lbypass_mux = + SOC_DAPM_ENUM("Left Bypass", lbypass_enum); + + +static const struct soc_enum rbypass_enum = + SOC_ENUM_SINGLE(WM8737_MIC_PREAMP_CONTROL, 3, 2, bypass_text); + +static const struct snd_kcontrol_new rbypass_mux = + SOC_DAPM_ENUM("Left Bypass", rbypass_enum); + +static const struct snd_soc_dapm_widget wm8737_dapm_widgets[] = { +SND_SOC_DAPM_INPUT("LINPUT1"), +SND_SOC_DAPM_INPUT("LINPUT2"), +SND_SOC_DAPM_INPUT("LINPUT3"), +SND_SOC_DAPM_INPUT("RINPUT1"), +SND_SOC_DAPM_INPUT("RINPUT2"), +SND_SOC_DAPM_INPUT("RINPUT3"), +SND_SOC_DAPM_INPUT("LACIN"), +SND_SOC_DAPM_INPUT("RACIN"), + +SND_SOC_DAPM_MUX("LINSEL", SND_SOC_NOPM, 0, 0, &linsel_mux), +SND_SOC_DAPM_MUX("RINSEL", SND_SOC_NOPM, 0, 0, &rinsel_mux), + +SND_SOC_DAPM_MUX("Left Preamp Mux", SND_SOC_NOPM, 0, 0, &lbypass_mux), +SND_SOC_DAPM_MUX("Right Preamp Mux", SND_SOC_NOPM, 0, 0, &rbypass_mux), + +SND_SOC_DAPM_PGA("PGAL", WM8737_POWER_MANAGEMENT, 5, 0, NULL, 0), +SND_SOC_DAPM_PGA("PGAR", WM8737_POWER_MANAGEMENT, 4, 0, NULL, 0), + +SND_SOC_DAPM_DAC("ADCL", NULL, WM8737_POWER_MANAGEMENT, 3, 0), +SND_SOC_DAPM_DAC("ADCR", NULL, WM8737_POWER_MANAGEMENT, 2, 0), + +SND_SOC_DAPM_AIF_OUT("AIF", "Capture", 0, WM8737_POWER_MANAGEMENT, 6, 0), +}; + +static const struct snd_soc_dapm_route intercon[] = { + { "LINSEL", "LINPUT1", "LINPUT1" }, + { "LINSEL", "LINPUT2", "LINPUT2" }, + { "LINSEL", "LINPUT3", "LINPUT3" }, + { "LINSEL", "LINPUT1 DC", "LINPUT1" }, + + { "RINSEL", "RINPUT1", "RINPUT1" }, + { "RINSEL", "RINPUT2", "RINPUT2" }, + { "RINSEL", "RINPUT3", "RINPUT3" }, + { "RINSEL", "RINPUT1 DC", "RINPUT1" }, + + { "Left Preamp Mux", "Preamp", "LINSEL" }, + { "Left Preamp Mux", "Direct", "LACIN" }, + + { "Right Preamp Mux", "Preamp", "RINSEL" }, + { "Right Preamp Mux", "Direct", "RACIN" }, + + { "PGAL", NULL, "Left Preamp Mux" }, + { "PGAR", NULL, "Right Preamp Mux" }, + + { "ADCL", NULL, "PGAL" }, + { "ADCR", NULL, "PGAR" }, + + { "AIF", NULL, "ADCL" }, + { "AIF", NULL, "ADCR" }, +}; + +static int wm8737_add_widgets(struct snd_soc_codec *codec) +{ + struct snd_soc_dapm_context *dapm = &codec->dapm; + + snd_soc_dapm_new_controls(dapm, wm8737_dapm_widgets, + ARRAY_SIZE(wm8737_dapm_widgets)); + snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon)); + + return 0; +} + +/* codec mclk clock divider coefficients */ +static const struct { + u32 mclk; + u32 rate; + u8 usb; + u8 sr; +} coeff_div[] = { + { 12288000, 8000, 0, 0x4 }, + { 12288000, 12000, 0, 0x8 }, + { 12288000, 16000, 0, 0xa }, + { 12288000, 24000, 0, 0x1c }, + { 12288000, 32000, 0, 0xc }, + { 12288000, 48000, 0, 0 }, + { 12288000, 96000, 0, 0xe }, + + { 11289600, 8000, 0, 0x14 }, + { 11289600, 11025, 0, 0x18 }, + { 11289600, 22050, 0, 0x1a }, + { 11289600, 44100, 0, 0x10 }, + { 11289600, 88200, 0, 0x1e }, + + { 18432000, 8000, 0, 0x5 }, + { 18432000, 12000, 0, 0x9 }, + { 18432000, 16000, 0, 0xb }, + { 18432000, 24000, 0, 0x1b }, + { 18432000, 32000, 0, 0xd }, + { 18432000, 48000, 0, 0x1 }, + { 18432000, 96000, 0, 0x1f }, + + { 16934400, 8000, 0, 0x15 }, + { 16934400, 11025, 0, 0x19 }, + { 16934400, 22050, 0, 0x1b }, + { 16934400, 44100, 0, 0x11 }, + { 16934400, 88200, 0, 0x1f }, + + { 12000000, 8000, 1, 0x4 }, + { 12000000, 11025, 1, 0x19 }, + { 12000000, 12000, 1, 0x8 }, + { 12000000, 16000, 1, 0xa }, + { 12000000, 22050, 1, 0x1b }, + { 12000000, 24000, 1, 0x1c }, + { 12000000, 32000, 1, 0xc }, + { 12000000, 44100, 1, 0x11 }, + { 12000000, 48000, 1, 0x0 }, + { 12000000, 88200, 1, 0x1f }, + { 12000000, 96000, 1, 0xe }, +}; + +static int wm8737_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_codec *codec = rtd->codec; + struct wm8737_priv *wm8737 = snd_soc_codec_get_drvdata(codec); + int i; + u16 clocking = 0; + u16 af = 0; + + for (i = 0; i < ARRAY_SIZE(coeff_div); i++) { + if (coeff_div[i].rate != params_rate(params)) + continue; + + if (coeff_div[i].mclk == wm8737->mclk) + break; + + if (coeff_div[i].mclk == wm8737->mclk * 2) { + clocking |= WM8737_CLKDIV2; + break; + } + } + + if (i == ARRAY_SIZE(coeff_div)) { + dev_err(codec->dev, "%dHz MCLK can't support %dHz\n", + wm8737->mclk, params_rate(params)); + return -EINVAL; + } + + clocking |= coeff_div[i].usb | (coeff_div[i].sr << WM8737_SR_SHIFT); + + switch (params_format(params)) { + case SNDRV_PCM_FORMAT_S16_LE: + break; + case SNDRV_PCM_FORMAT_S20_3LE: + af |= 0x8; + break; + case SNDRV_PCM_FORMAT_S24_LE: + af |= 0x10; + break; + case SNDRV_PCM_FORMAT_S32_LE: + af |= 0x18; + break; + default: + return -EINVAL; + } + + snd_soc_update_bits(codec, WM8737_AUDIO_FORMAT, WM8737_WL_MASK, af); + snd_soc_update_bits(codec, WM8737_CLOCKING, + WM8737_USB_MODE | WM8737_CLKDIV2 | WM8737_SR_MASK, + clocking); + + return 0; +} + +static int wm8737_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 wm8737_priv *wm8737 = snd_soc_codec_get_drvdata(codec); + int i; + + for (i = 0; i < ARRAY_SIZE(coeff_div); i++) { + if (freq == coeff_div[i].mclk || + freq == coeff_div[i].mclk * 2) { + wm8737->mclk = freq; + return 0; + } + } + + dev_err(codec->dev, "MCLK rate %dHz not supported\n", freq); + + return -EINVAL; +} + + +static int wm8737_set_dai_fmt(struct snd_soc_dai *codec_dai, + unsigned int fmt) +{ + struct snd_soc_codec *codec = codec_dai->codec; + u16 af = 0; + + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { + case SND_SOC_DAIFMT_CBM_CFM: + af |= WM8737_MS; + break; + case SND_SOC_DAIFMT_CBS_CFS: + break; + default: + return -EINVAL; + } + + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { + case SND_SOC_DAIFMT_I2S: + af |= 0x2; + break; + case SND_SOC_DAIFMT_RIGHT_J: + break; + case SND_SOC_DAIFMT_LEFT_J: + af |= 0x1; + break; + case SND_SOC_DAIFMT_DSP_A: + af |= 0x3; + break; + case SND_SOC_DAIFMT_DSP_B: + af |= 0x13; + break; + default: + return -EINVAL; + } + + switch (fmt & SND_SOC_DAIFMT_INV_MASK) { + case SND_SOC_DAIFMT_NB_NF: + break; + case SND_SOC_DAIFMT_NB_IF: + af |= WM8737_LRP; + break; + default: + return -EINVAL; + } + + snd_soc_update_bits(codec, WM8737_AUDIO_FORMAT, + WM8737_FORMAT_MASK | WM8737_LRP | WM8737_MS, af); + + return 0; +} + +static int wm8737_set_bias_level(struct snd_soc_codec *codec, + enum snd_soc_bias_level level) +{ + struct wm8737_priv *wm8737 = snd_soc_codec_get_drvdata(codec); + int ret; + + switch (level) { + case SND_SOC_BIAS_ON: + break; + + case SND_SOC_BIAS_PREPARE: + /* VMID at 2*75k */ + snd_soc_update_bits(codec, WM8737_MISC_BIAS_CONTROL, + WM8737_VMIDSEL_MASK, 0); + break; + + case SND_SOC_BIAS_STANDBY: + if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { + ret = regulator_bulk_enable(ARRAY_SIZE(wm8737->supplies), + wm8737->supplies); + if (ret != 0) { + dev_err(codec->dev, + "Failed to enable supplies: %d\n", + ret); + return ret; + } + + snd_soc_cache_sync(codec); + + /* Fast VMID ramp at 2*2.5k */ + snd_soc_update_bits(codec, WM8737_MISC_BIAS_CONTROL, + WM8737_VMIDSEL_MASK, 0x4); + + /* Bring VMID up */ + snd_soc_update_bits(codec, WM8737_POWER_MANAGEMENT, + WM8737_VMID_MASK | + WM8737_VREF_MASK, + WM8737_VMID_MASK | + WM8737_VREF_MASK); + + msleep(500); + } + + /* VMID at 2*300k */ + snd_soc_update_bits(codec, WM8737_MISC_BIAS_CONTROL, + WM8737_VMIDSEL_MASK, 2); + + break; + + case SND_SOC_BIAS_OFF: + snd_soc_update_bits(codec, WM8737_POWER_MANAGEMENT, + WM8737_VMID_MASK | WM8737_VREF_MASK, 0); + + regulator_bulk_disable(ARRAY_SIZE(wm8737->supplies), + wm8737->supplies); + break; + } + + codec->dapm.bias_level = level; + return 0; +} + +#define WM8737_RATES SNDRV_PCM_RATE_8000_96000 + +#define WM8737_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ + SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE) + +static struct snd_soc_dai_ops wm8737_dai_ops = { + .hw_params = wm8737_hw_params, + .set_sysclk = wm8737_set_dai_sysclk, + .set_fmt = wm8737_set_dai_fmt, +}; + +static struct snd_soc_dai_driver wm8737_dai = { + .name = "wm8737", + .capture = { + .stream_name = "Capture", + .channels_min = 2, /* Mono modes not yet supported */ + .channels_max = 2, + .rates = WM8737_RATES, + .formats = WM8737_FORMATS, + }, + .ops = &wm8737_dai_ops, +}; + +#ifdef CONFIG_PM +static int wm8737_suspend(struct snd_soc_codec *codec, pm_message_t state) +{ + wm8737_set_bias_level(codec, SND_SOC_BIAS_OFF); + return 0; +} + +static int wm8737_resume(struct snd_soc_codec *codec) +{ + wm8737_set_bias_level(codec, SND_SOC_BIAS_STANDBY); + return 0; +} +#else +#define wm8737_suspend NULL +#define wm8737_resume NULL +#endif + +static int wm8737_probe(struct snd_soc_codec *codec) +{ + struct wm8737_priv *wm8737 = snd_soc_codec_get_drvdata(codec); + int ret, i; + + codec->hw_write = (hw_write_t)i2c_master_send; + ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8737->control_type); + if (ret != 0) { + dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); + return ret; + } + + for (i = 0; i < ARRAY_SIZE(wm8737->supplies); i++) + wm8737->supplies[i].supply = wm8737_supply_names[i]; + + ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8737->supplies), + wm8737->supplies); + if (ret != 0) { + dev_err(codec->dev, "Failed to request supplies: %d\n", ret); + return ret; + } + + ret = regulator_bulk_enable(ARRAY_SIZE(wm8737->supplies), + wm8737->supplies); + if (ret != 0) { + dev_err(codec->dev, "Failed to enable supplies: %d\n", ret); + goto err_get; + } + + ret = wm8737_reset(codec); + if (ret < 0) { + dev_err(codec->dev, "Failed to issue reset\n"); + goto err_enable; + } + + snd_soc_update_bits(codec, WM8737_LEFT_PGA_VOLUME, WM8737_LVU, + WM8737_LVU); + snd_soc_update_bits(codec, WM8737_RIGHT_PGA_VOLUME, WM8737_RVU, + WM8737_RVU); + + wm8737_set_bias_level(codec, SND_SOC_BIAS_STANDBY); + + /* Bias level configuration will have done an extra enable */ + regulator_bulk_disable(ARRAY_SIZE(wm8737->supplies), wm8737->supplies); + + snd_soc_add_controls(codec, wm8737_snd_controls, + ARRAY_SIZE(wm8737_snd_controls)); + wm8737_add_widgets(codec); + + return 0; + +err_enable: + regulator_bulk_disable(ARRAY_SIZE(wm8737->supplies), wm8737->supplies); +err_get: + regulator_bulk_free(ARRAY_SIZE(wm8737->supplies), wm8737->supplies); + + return ret; +} + +static int wm8737_remove(struct snd_soc_codec *codec) +{ + struct wm8737_priv *wm8737 = snd_soc_codec_get_drvdata(codec); + + wm8737_set_bias_level(codec, SND_SOC_BIAS_OFF); + regulator_bulk_free(ARRAY_SIZE(wm8737->supplies), wm8737->supplies); + return 0; +} + +static struct snd_soc_codec_driver soc_codec_dev_wm8737 = { + .probe = wm8737_probe, + .remove = wm8737_remove, + .suspend = wm8737_suspend, + .resume = wm8737_resume, + .set_bias_level = wm8737_set_bias_level, + + .reg_cache_size = WM8737_REGISTER_COUNT - 1, /* Skip reset */ + .reg_word_size = sizeof(u16), + .reg_cache_default = wm8737_reg, +}; + +#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) +static __devinit int wm8737_i2c_probe(struct i2c_client *i2c, + const struct i2c_device_id *id) +{ + struct wm8737_priv *wm8737; + int ret; + + wm8737 = kzalloc(sizeof(struct wm8737_priv), GFP_KERNEL); + if (wm8737 == NULL) + return -ENOMEM; + + i2c_set_clientdata(i2c, wm8737); + wm8737->control_type = SND_SOC_I2C; + + ret = snd_soc_register_codec(&i2c->dev, + &soc_codec_dev_wm8737, &wm8737_dai, 1); + if (ret < 0) + kfree(wm8737); + return ret; + +} + +static __devexit int wm8737_i2c_remove(struct i2c_client *client) +{ + snd_soc_unregister_codec(&client->dev); + kfree(i2c_get_clientdata(client)); + return 0; +} + +static const struct i2c_device_id wm8737_i2c_id[] = { + { "wm8737", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, wm8737_i2c_id); + +static struct i2c_driver wm8737_i2c_driver = { + .driver = { + .name = "wm8737", + .owner = THIS_MODULE, + }, + .probe = wm8737_i2c_probe, + .remove = __devexit_p(wm8737_i2c_remove), + .id_table = wm8737_i2c_id, +}; +#endif + +#if defined(CONFIG_SPI_MASTER) +static int __devinit wm8737_spi_probe(struct spi_device *spi) +{ + struct wm8737_priv *wm8737; + int ret; + + wm8737 = kzalloc(sizeof(struct wm8737_priv), GFP_KERNEL); + if (wm8737 == NULL) + return -ENOMEM; + + wm8737->control_type = SND_SOC_SPI; + spi_set_drvdata(spi, wm8737); + + ret = snd_soc_register_codec(&spi->dev, + &soc_codec_dev_wm8737, &wm8737_dai, 1); + if (ret < 0) + kfree(wm8737); + return ret; +} + +static int __devexit wm8737_spi_remove(struct spi_device *spi) +{ + snd_soc_unregister_codec(&spi->dev); + kfree(spi_get_drvdata(spi)); + return 0; +} + +static struct spi_driver wm8737_spi_driver = { + .driver = { + .name = "wm8737", + .owner = THIS_MODULE, + }, + .probe = wm8737_spi_probe, + .remove = __devexit_p(wm8737_spi_remove), +}; +#endif /* CONFIG_SPI_MASTER */ + +static int __init wm8737_modinit(void) +{ + int ret; +#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) + ret = i2c_add_driver(&wm8737_i2c_driver); + if (ret != 0) { + printk(KERN_ERR "Failed to register WM8737 I2C driver: %d\n", + ret); + } +#endif +#if defined(CONFIG_SPI_MASTER) + ret = spi_register_driver(&wm8737_spi_driver); + if (ret != 0) { + printk(KERN_ERR "Failed to register WM8737 SPI driver: %d\n", + ret); + } +#endif + return 0; +} +module_init(wm8737_modinit); + +static void __exit wm8737_exit(void) +{ +#if defined(CONFIG_SPI_MASTER) + spi_unregister_driver(&wm8737_spi_driver); +#endif +#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) + i2c_del_driver(&wm8737_i2c_driver); +#endif +} +module_exit(wm8737_exit); + +MODULE_DESCRIPTION("ASoC WM8737 driver"); +MODULE_AUTHOR("Mark Brown "); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/codecs/wm8737.h b/sound/soc/codecs/wm8737.h new file mode 100644 index 000000000000..23d14c8ff6e7 --- /dev/null +++ b/sound/soc/codecs/wm8737.h @@ -0,0 +1,322 @@ +#ifndef _WM8737_H +#define _WM8737_H + +/* + * wm8737.c -- WM8523 ALSA SoC Audio driver + * + * Copyright 2010 Wolfson Microelectronics plc + * + * Author: Mark Brown + * + * 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. + */ + +/* + * Register values. + */ +#define WM8737_LEFT_PGA_VOLUME 0x00 +#define WM8737_RIGHT_PGA_VOLUME 0x01 +#define WM8737_AUDIO_PATH_L 0x02 +#define WM8737_AUDIO_PATH_R 0x03 +#define WM8737_3D_ENHANCE 0x04 +#define WM8737_ADC_CONTROL 0x05 +#define WM8737_POWER_MANAGEMENT 0x06 +#define WM8737_AUDIO_FORMAT 0x07 +#define WM8737_CLOCKING 0x08 +#define WM8737_MIC_PREAMP_CONTROL 0x09 +#define WM8737_MISC_BIAS_CONTROL 0x0A +#define WM8737_NOISE_GATE 0x0B +#define WM8737_ALC1 0x0C +#define WM8737_ALC2 0x0D +#define WM8737_ALC3 0x0E +#define WM8737_RESET 0x0F + +#define WM8737_REGISTER_COUNT 16 +#define WM8737_MAX_REGISTER 0x0F + +/* + * Field Definitions. + */ + +/* + * R0 (0x00) - Left PGA volume + */ +#define WM8737_LVU 0x0100 /* LVU */ +#define WM8737_LVU_MASK 0x0100 /* LVU */ +#define WM8737_LVU_SHIFT 8 /* LVU */ +#define WM8737_LVU_WIDTH 1 /* LVU */ +#define WM8737_LINVOL_MASK 0x00FF /* LINVOL - [7:0] */ +#define WM8737_LINVOL_SHIFT 0 /* LINVOL - [7:0] */ +#define WM8737_LINVOL_WIDTH 8 /* LINVOL - [7:0] */ + +/* + * R1 (0x01) - Right PGA volume + */ +#define WM8737_RVU 0x0100 /* RVU */ +#define WM8737_RVU_MASK 0x0100 /* RVU */ +#define WM8737_RVU_SHIFT 8 /* RVU */ +#define WM8737_RVU_WIDTH 1 /* RVU */ +#define WM8737_RINVOL_MASK 0x00FF /* RINVOL - [7:0] */ +#define WM8737_RINVOL_SHIFT 0 /* RINVOL - [7:0] */ +#define WM8737_RINVOL_WIDTH 8 /* RINVOL - [7:0] */ + +/* + * R2 (0x02) - AUDIO path L + */ +#define WM8737_LINSEL_MASK 0x0180 /* LINSEL - [8:7] */ +#define WM8737_LINSEL_SHIFT 7 /* LINSEL - [8:7] */ +#define WM8737_LINSEL_WIDTH 2 /* LINSEL - [8:7] */ +#define WM8737_LMICBOOST_MASK 0x0060 /* LMICBOOST - [6:5] */ +#define WM8737_LMICBOOST_SHIFT 5 /* LMICBOOST - [6:5] */ +#define WM8737_LMICBOOST_WIDTH 2 /* LMICBOOST - [6:5] */ +#define WM8737_LMBE 0x0010 /* LMBE */ +#define WM8737_LMBE_MASK 0x0010 /* LMBE */ +#define WM8737_LMBE_SHIFT 4 /* LMBE */ +#define WM8737_LMBE_WIDTH 1 /* LMBE */ +#define WM8737_LMZC 0x0008 /* LMZC */ +#define WM8737_LMZC_MASK 0x0008 /* LMZC */ +#define WM8737_LMZC_SHIFT 3 /* LMZC */ +#define WM8737_LMZC_WIDTH 1 /* LMZC */ +#define WM8737_LPZC 0x0004 /* LPZC */ +#define WM8737_LPZC_MASK 0x0004 /* LPZC */ +#define WM8737_LPZC_SHIFT 2 /* LPZC */ +#define WM8737_LPZC_WIDTH 1 /* LPZC */ +#define WM8737_LZCTO_MASK 0x0003 /* LZCTO - [1:0] */ +#define WM8737_LZCTO_SHIFT 0 /* LZCTO - [1:0] */ +#define WM8737_LZCTO_WIDTH 2 /* LZCTO - [1:0] */ + +/* + * R3 (0x03) - AUDIO path R + */ +#define WM8737_RINSEL_MASK 0x0180 /* RINSEL - [8:7] */ +#define WM8737_RINSEL_SHIFT 7 /* RINSEL - [8:7] */ +#define WM8737_RINSEL_WIDTH 2 /* RINSEL - [8:7] */ +#define WM8737_RMICBOOST_MASK 0x0060 /* RMICBOOST - [6:5] */ +#define WM8737_RMICBOOST_SHIFT 5 /* RMICBOOST - [6:5] */ +#define WM8737_RMICBOOST_WIDTH 2 /* RMICBOOST - [6:5] */ +#define WM8737_RMBE 0x0010 /* RMBE */ +#define WM8737_RMBE_MASK 0x0010 /* RMBE */ +#define WM8737_RMBE_SHIFT 4 /* RMBE */ +#define WM8737_RMBE_WIDTH 1 /* RMBE */ +#define WM8737_RMZC 0x0008 /* RMZC */ +#define WM8737_RMZC_MASK 0x0008 /* RMZC */ +#define WM8737_RMZC_SHIFT 3 /* RMZC */ +#define WM8737_RMZC_WIDTH 1 /* RMZC */ +#define WM8737_RPZC 0x0004 /* RPZC */ +#define WM8737_RPZC_MASK 0x0004 /* RPZC */ +#define WM8737_RPZC_SHIFT 2 /* RPZC */ +#define WM8737_RPZC_WIDTH 1 /* RPZC */ +#define WM8737_RZCTO_MASK 0x0003 /* RZCTO - [1:0] */ +#define WM8737_RZCTO_SHIFT 0 /* RZCTO - [1:0] */ +#define WM8737_RZCTO_WIDTH 2 /* RZCTO - [1:0] */ + +/* + * R4 (0x04) - 3D Enhance + */ +#define WM8737_DIV2 0x0080 /* DIV2 */ +#define WM8737_DIV2_MASK 0x0080 /* DIV2 */ +#define WM8737_DIV2_SHIFT 7 /* DIV2 */ +#define WM8737_DIV2_WIDTH 1 /* DIV2 */ +#define WM8737_3DLC 0x0040 /* 3DLC */ +#define WM8737_3DLC_MASK 0x0040 /* 3DLC */ +#define WM8737_3DLC_SHIFT 6 /* 3DLC */ +#define WM8737_3DLC_WIDTH 1 /* 3DLC */ +#define WM8737_3DUC 0x0020 /* 3DUC */ +#define WM8737_3DUC_MASK 0x0020 /* 3DUC */ +#define WM8737_3DUC_SHIFT 5 /* 3DUC */ +#define WM8737_3DUC_WIDTH 1 /* 3DUC */ +#define WM8737_3DDEPTH_MASK 0x001E /* 3DDEPTH - [4:1] */ +#define WM8737_3DDEPTH_SHIFT 1 /* 3DDEPTH - [4:1] */ +#define WM8737_3DDEPTH_WIDTH 4 /* 3DDEPTH - [4:1] */ +#define WM8737_3DE 0x0001 /* 3DE */ +#define WM8737_3DE_MASK 0x0001 /* 3DE */ +#define WM8737_3DE_SHIFT 0 /* 3DE */ +#define WM8737_3DE_WIDTH 1 /* 3DE */ + +/* + * R5 (0x05) - ADC Control + */ +#define WM8737_MONOMIX_MASK 0x0180 /* MONOMIX - [8:7] */ +#define WM8737_MONOMIX_SHIFT 7 /* MONOMIX - [8:7] */ +#define WM8737_MONOMIX_WIDTH 2 /* MONOMIX - [8:7] */ +#define WM8737_POLARITY_MASK 0x0060 /* POLARITY - [6:5] */ +#define WM8737_POLARITY_SHIFT 5 /* POLARITY - [6:5] */ +#define WM8737_POLARITY_WIDTH 2 /* POLARITY - [6:5] */ +#define WM8737_HPOR 0x0010 /* HPOR */ +#define WM8737_HPOR_MASK 0x0010 /* HPOR */ +#define WM8737_HPOR_SHIFT 4 /* HPOR */ +#define WM8737_HPOR_WIDTH 1 /* HPOR */ +#define WM8737_LP 0x0004 /* LP */ +#define WM8737_LP_MASK 0x0004 /* LP */ +#define WM8737_LP_SHIFT 2 /* LP */ +#define WM8737_LP_WIDTH 1 /* LP */ +#define WM8737_MONOUT 0x0002 /* MONOUT */ +#define WM8737_MONOUT_MASK 0x0002 /* MONOUT */ +#define WM8737_MONOUT_SHIFT 1 /* MONOUT */ +#define WM8737_MONOUT_WIDTH 1 /* MONOUT */ +#define WM8737_ADCHPD 0x0001 /* ADCHPD */ +#define WM8737_ADCHPD_MASK 0x0001 /* ADCHPD */ +#define WM8737_ADCHPD_SHIFT 0 /* ADCHPD */ +#define WM8737_ADCHPD_WIDTH 1 /* ADCHPD */ + +/* + * R6 (0x06) - Power Management + */ +#define WM8737_VMID 0x0100 /* VMID */ +#define WM8737_VMID_MASK 0x0100 /* VMID */ +#define WM8737_VMID_SHIFT 8 /* VMID */ +#define WM8737_VMID_WIDTH 1 /* VMID */ +#define WM8737_VREF 0x0080 /* VREF */ +#define WM8737_VREF_MASK 0x0080 /* VREF */ +#define WM8737_VREF_SHIFT 7 /* VREF */ +#define WM8737_VREF_WIDTH 1 /* VREF */ +#define WM8737_AI 0x0040 /* AI */ +#define WM8737_AI_MASK 0x0040 /* AI */ +#define WM8737_AI_SHIFT 6 /* AI */ +#define WM8737_AI_WIDTH 1 /* AI */ +#define WM8737_PGL 0x0020 /* PGL */ +#define WM8737_PGL_MASK 0x0020 /* PGL */ +#define WM8737_PGL_SHIFT 5 /* PGL */ +#define WM8737_PGL_WIDTH 1 /* PGL */ +#define WM8737_PGR 0x0010 /* PGR */ +#define WM8737_PGR_MASK 0x0010 /* PGR */ +#define WM8737_PGR_SHIFT 4 /* PGR */ +#define WM8737_PGR_WIDTH 1 /* PGR */ +#define WM8737_ADL 0x0008 /* ADL */ +#define WM8737_ADL_MASK 0x0008 /* ADL */ +#define WM8737_ADL_SHIFT 3 /* ADL */ +#define WM8737_ADL_WIDTH 1 /* ADL */ +#define WM8737_ADR 0x0004 /* ADR */ +#define WM8737_ADR_MASK 0x0004 /* ADR */ +#define WM8737_ADR_SHIFT 2 /* ADR */ +#define WM8737_ADR_WIDTH 1 /* ADR */ +#define WM8737_MICBIAS_MASK 0x0003 /* MICBIAS - [1:0] */ +#define WM8737_MICBIAS_SHIFT 0 /* MICBIAS - [1:0] */ +#define WM8737_MICBIAS_WIDTH 2 /* MICBIAS - [1:0] */ + +/* + * R7 (0x07) - Audio Format + */ +#define WM8737_SDODIS 0x0080 /* SDODIS */ +#define WM8737_SDODIS_MASK 0x0080 /* SDODIS */ +#define WM8737_SDODIS_SHIFT 7 /* SDODIS */ +#define WM8737_SDODIS_WIDTH 1 /* SDODIS */ +#define WM8737_MS 0x0040 /* MS */ +#define WM8737_MS_MASK 0x0040 /* MS */ +#define WM8737_MS_SHIFT 6 /* MS */ +#define WM8737_MS_WIDTH 1 /* MS */ +#define WM8737_LRP 0x0010 /* LRP */ +#define WM8737_LRP_MASK 0x0010 /* LRP */ +#define WM8737_LRP_SHIFT 4 /* LRP */ +#define WM8737_LRP_WIDTH 1 /* LRP */ +#define WM8737_WL_MASK 0x000C /* WL - [3:2] */ +#define WM8737_WL_SHIFT 2 /* WL - [3:2] */ +#define WM8737_WL_WIDTH 2 /* WL - [3:2] */ +#define WM8737_FORMAT_MASK 0x0003 /* FORMAT - [1:0] */ +#define WM8737_FORMAT_SHIFT 0 /* FORMAT - [1:0] */ +#define WM8737_FORMAT_WIDTH 2 /* FORMAT - [1:0] */ + +/* + * R8 (0x08) - Clocking + */ +#define WM8737_AUTODETECT 0x0080 /* AUTODETECT */ +#define WM8737_AUTODETECT_MASK 0x0080 /* AUTODETECT */ +#define WM8737_AUTODETECT_SHIFT 7 /* AUTODETECT */ +#define WM8737_AUTODETECT_WIDTH 1 /* AUTODETECT */ +#define WM8737_CLKDIV2 0x0040 /* CLKDIV2 */ +#define WM8737_CLKDIV2_MASK 0x0040 /* CLKDIV2 */ +#define WM8737_CLKDIV2_SHIFT 6 /* CLKDIV2 */ +#define WM8737_CLKDIV2_WIDTH 1 /* CLKDIV2 */ +#define WM8737_SR_MASK 0x003E /* SR - [5:1] */ +#define WM8737_SR_SHIFT 1 /* SR - [5:1] */ +#define WM8737_SR_WIDTH 5 /* SR - [5:1] */ +#define WM8737_USB_MODE 0x0001 /* USB MODE */ +#define WM8737_USB_MODE_MASK 0x0001 /* USB MODE */ +#define WM8737_USB_MODE_SHIFT 0 /* USB MODE */ +#define WM8737_USB_MODE_WIDTH 1 /* USB MODE */ + +/* + * R9 (0x09) - MIC Preamp Control + */ +#define WM8737_RBYPEN 0x0008 /* RBYPEN */ +#define WM8737_RBYPEN_MASK 0x0008 /* RBYPEN */ +#define WM8737_RBYPEN_SHIFT 3 /* RBYPEN */ +#define WM8737_RBYPEN_WIDTH 1 /* RBYPEN */ +#define WM8737_LBYPEN 0x0004 /* LBYPEN */ +#define WM8737_LBYPEN_MASK 0x0004 /* LBYPEN */ +#define WM8737_LBYPEN_SHIFT 2 /* LBYPEN */ +#define WM8737_LBYPEN_WIDTH 1 /* LBYPEN */ +#define WM8737_MBCTRL_MASK 0x0003 /* MBCTRL - [1:0] */ +#define WM8737_MBCTRL_SHIFT 0 /* MBCTRL - [1:0] */ +#define WM8737_MBCTRL_WIDTH 2 /* MBCTRL - [1:0] */ + +/* + * R10 (0x0A) - Misc Bias Control + */ +#define WM8737_VMIDSEL_MASK 0x000C /* VMIDSEL - [3:2] */ +#define WM8737_VMIDSEL_SHIFT 2 /* VMIDSEL - [3:2] */ +#define WM8737_VMIDSEL_WIDTH 2 /* VMIDSEL - [3:2] */ +#define WM8737_LINPUT1_DC_BIAS_ENABLE 0x0002 /* LINPUT1 DC BIAS ENABLE */ +#define WM8737_LINPUT1_DC_BIAS_ENABLE_MASK 0x0002 /* LINPUT1 DC BIAS ENABLE */ +#define WM8737_LINPUT1_DC_BIAS_ENABLE_SHIFT 1 /* LINPUT1 DC BIAS ENABLE */ +#define WM8737_LINPUT1_DC_BIAS_ENABLE_WIDTH 1 /* LINPUT1 DC BIAS ENABLE */ +#define WM8737_RINPUT1_DC_BIAS_ENABLE 0x0001 /* RINPUT1 DC BIAS ENABLE */ +#define WM8737_RINPUT1_DC_BIAS_ENABLE_MASK 0x0001 /* RINPUT1 DC BIAS ENABLE */ +#define WM8737_RINPUT1_DC_BIAS_ENABLE_SHIFT 0 /* RINPUT1 DC BIAS ENABLE */ +#define WM8737_RINPUT1_DC_BIAS_ENABLE_WIDTH 1 /* RINPUT1 DC BIAS ENABLE */ + +/* + * R11 (0x0B) - Noise Gate + */ +#define WM8737_NGTH_MASK 0x001C /* NGTH - [4:2] */ +#define WM8737_NGTH_SHIFT 2 /* NGTH - [4:2] */ +#define WM8737_NGTH_WIDTH 3 /* NGTH - [4:2] */ +#define WM8737_NGAT 0x0001 /* NGAT */ +#define WM8737_NGAT_MASK 0x0001 /* NGAT */ +#define WM8737_NGAT_SHIFT 0 /* NGAT */ +#define WM8737_NGAT_WIDTH 1 /* NGAT */ + +/* + * R12 (0x0C) - ALC1 + */ +#define WM8737_ALCSEL_MASK 0x0180 /* ALCSEL - [8:7] */ +#define WM8737_ALCSEL_SHIFT 7 /* ALCSEL - [8:7] */ +#define WM8737_ALCSEL_WIDTH 2 /* ALCSEL - [8:7] */ +#define WM8737_MAX_GAIN_MASK 0x0070 /* MAX GAIN - [6:4] */ +#define WM8737_MAX_GAIN_SHIFT 4 /* MAX GAIN - [6:4] */ +#define WM8737_MAX_GAIN_WIDTH 3 /* MAX GAIN - [6:4] */ +#define WM8737_ALCL_MASK 0x000F /* ALCL - [3:0] */ +#define WM8737_ALCL_SHIFT 0 /* ALCL - [3:0] */ +#define WM8737_ALCL_WIDTH 4 /* ALCL - [3:0] */ + +/* + * R13 (0x0D) - ALC2 + */ +#define WM8737_ALCZCE 0x0010 /* ALCZCE */ +#define WM8737_ALCZCE_MASK 0x0010 /* ALCZCE */ +#define WM8737_ALCZCE_SHIFT 4 /* ALCZCE */ +#define WM8737_ALCZCE_WIDTH 1 /* ALCZCE */ +#define WM8737_HLD_MASK 0x000F /* HLD - [3:0] */ +#define WM8737_HLD_SHIFT 0 /* HLD - [3:0] */ +#define WM8737_HLD_WIDTH 4 /* HLD - [3:0] */ + +/* + * R14 (0x0E) - ALC3 + */ +#define WM8737_DCY_MASK 0x00F0 /* DCY - [7:4] */ +#define WM8737_DCY_SHIFT 4 /* DCY - [7:4] */ +#define WM8737_DCY_WIDTH 4 /* DCY - [7:4] */ +#define WM8737_ATK_MASK 0x000F /* ATK - [3:0] */ +#define WM8737_ATK_SHIFT 0 /* ATK - [3:0] */ +#define WM8737_ATK_WIDTH 4 /* ATK - [3:0] */ + +/* + * R15 (0x0F) - Reset + */ +#define WM8737_RESET_MASK 0x01FF /* RESET - [8:0] */ +#define WM8737_RESET_SHIFT 0 /* RESET - [8:0] */ +#define WM8737_RESET_WIDTH 9 /* RESET - [8:0] */ + +#endif -- cgit v1.2.3 From a7a09aebe8c0dd2b76c7b97018a9c614ddb483a5 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 12 Nov 2010 13:49:09 +0000 Subject: drm/i915: Rework execbuffer pinning Avoid evicting buffers that will be used later in the batch in order to make room for the initial buffers by pinning all bound buffers in a single pass before binding (and evicting for) fresh buffer. Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_gem.c | 81 +++++++++++++++++++++++++++++------------ 1 file changed, 58 insertions(+), 23 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 465e07abf5d0..061426e1bbf4 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -3531,44 +3531,75 @@ i915_gem_execbuffer_reserve(struct drm_device *dev, struct drm_i915_private *dev_priv = dev->dev_private; int ret, i, retry; - /* attempt to pin all of the buffers into the GTT */ + /* Attempt to pin all of the buffers into the GTT. + * This is done in 3 phases: + * + * 1a. Unbind all objects that do not match the GTT constraints for + * the execbuffer (fenceable, mappable, alignment etc). + * 1b. Increment pin count for already bound objects. + * 2. Bind new objects. + * 3. Decrement pin count. + * + * This avoid unnecessary unbinding of later objects in order to makr + * room for the earlier objects *unless* we need to defragment. + */ retry = 0; do { ret = 0; + + /* Unbind any ill-fitting objects or pin. */ for (i = 0; i < count; i++) { - struct drm_i915_gem_exec_object2 *entry = &exec_list[i]; struct drm_i915_gem_object *obj = object_list[i]; - bool need_fence = + struct drm_i915_gem_exec_object2 *entry = &exec_list[i]; + bool need_fence, need_mappable; + + if (!obj->gtt_space) + continue; + + need_fence = entry->flags & EXEC_OBJECT_NEEDS_FENCE && obj->tiling_mode != I915_TILING_NONE; - - /* g33/pnv can't fence buffers in the unmappable part */ - bool need_mappable = + need_mappable = entry->relocation_count ? true : need_fence; - /* Check fence reg constraints and rebind if necessary */ - if (need_mappable && !obj->map_and_fenceable) { + if ((entry->alignment && obj->gtt_offset & (entry->alignment - 1)) || + (need_mappable && !obj->map_and_fenceable)) ret = i915_gem_object_unbind(obj); + else + ret = i915_gem_object_pin(obj, + entry->alignment, + need_mappable); + if (ret) { + count = i; + goto err; + } + } + + /* Bind fresh objects */ + for (i = 0; i < count; i++) { + struct drm_i915_gem_exec_object2 *entry = &exec_list[i]; + struct drm_i915_gem_object *obj = object_list[i]; + bool need_fence; + + need_fence = + entry->flags & EXEC_OBJECT_NEEDS_FENCE && + obj->tiling_mode != I915_TILING_NONE; + + if (!obj->gtt_space) { + bool need_mappable = + entry->relocation_count ? true : need_fence; + + ret = i915_gem_object_pin(obj, + entry->alignment, + need_mappable); if (ret) break; } - ret = i915_gem_object_pin(obj, - entry->alignment, - need_mappable); - if (ret) - break; - - /* - * Pre-965 chips need a fence register set up in order - * to properly handle blits to/from tiled surfaces. - */ if (need_fence) { ret = i915_gem_object_get_fence_reg(obj, true); - if (ret) { - i915_gem_object_unpin(obj); + if (ret) break; - } dev_priv->fence_regs[obj->fence_reg].gpu = true; } @@ -3576,8 +3607,12 @@ i915_gem_execbuffer_reserve(struct drm_device *dev, entry->offset = obj->gtt_offset; } - while (i--) - i915_gem_object_unpin(object_list[i]); +err: /* Decrement pin count for bound objects */ + for (i = 0; i < count; i++) { + struct drm_i915_gem_object *obj = object_list[i]; + if (obj->gtt_space) + i915_gem_object_unpin(obj); + } if (ret != -ENOSPC || retry > 1) return ret; -- cgit v1.2.3 From caea7476d48e5f401f2d18b1738827748fb56c12 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 12 Nov 2010 13:53:37 +0000 Subject: drm/i915: More accurately track last fence usage by the GPU Based on a patch by Daniel Vetter. Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_debugfs.c | 3 +- drivers/gpu/drm/i915/i915_drv.h | 17 ++++-- drivers/gpu/drm/i915/i915_gem.c | 110 +++++++++++++++++++++--------------- 3 files changed, 78 insertions(+), 52 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index addb9392e1c4..5faae476954c 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -110,7 +110,7 @@ static const char *get_tiling_flag(struct drm_i915_gem_object *obj) static void describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj) { - seq_printf(m, "%p: %s%s %8zd %08x %08x %d%s%s", + seq_printf(m, "%p: %s%s %8zd %04x %04x %d %d%s%s", &obj->base, get_pin_flag(obj), get_tiling_flag(obj), @@ -118,6 +118,7 @@ describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj) obj->base.read_domains, obj->base.write_domain, obj->last_rendering_seqno, + obj->last_fenced_seqno, obj->dirty ? " dirty" : "", obj->madv == I915_MADV_DONTNEED ? " purgeable" : ""); if (obj->base.name) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 42d3e901619d..ee7df1d2b8c8 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -124,9 +124,8 @@ struct drm_i915_master_private { #define I915_FENCE_REG_NONE -1 struct drm_i915_fence_reg { - struct drm_i915_gem_object *obj; struct list_head lru_list; - bool gpu; + struct drm_i915_gem_object *obj; }; struct sdvo_device_mapping { @@ -787,6 +786,12 @@ struct drm_i915_gem_object { unsigned int fault_mappable : 1; unsigned int pin_mappable : 1; + /* + * Is the GPU currently using a fence to access this buffer, + */ + unsigned int pending_fenced_gpu_access:1; + unsigned int fenced_gpu_access:1; + struct page **pages; /** @@ -802,11 +807,13 @@ struct drm_i915_gem_object { */ uint32_t gtt_offset; - /* Which ring is refering to is this object */ - struct intel_ring_buffer *ring; - /** Breadcrumb of last rendering to the buffer. */ uint32_t last_rendering_seqno; + struct intel_ring_buffer *ring; + + /** Breadcrumb of last fenced GPU access to the buffer. */ + uint32_t last_fenced_seqno; + struct intel_ring_buffer *last_fenced_ring; /** Current tiling stride for the object, if it's tiled. */ uint32_t stride; diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 061426e1bbf4..2cfdee8811c4 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1688,7 +1688,27 @@ i915_gem_object_move_to_active(struct drm_i915_gem_object *obj, /* Move from whatever list we were on to the tail of execution. */ list_move_tail(&obj->mm_list, &dev_priv->mm.active_list); list_move_tail(&obj->ring_list, &ring->active_list); + obj->last_rendering_seqno = seqno; + if (obj->fenced_gpu_access) { + struct drm_i915_fence_reg *reg; + + BUG_ON(obj->fence_reg == I915_FENCE_REG_NONE); + + obj->last_fenced_seqno = seqno; + obj->last_fenced_ring = ring; + + reg = &dev_priv->fence_regs[obj->fence_reg]; + list_move_tail(®->lru_list, &dev_priv->mm.fence_list); + } +} + +static void +i915_gem_object_move_off_active(struct drm_i915_gem_object *obj) +{ + list_del_init(&obj->ring_list); + obj->last_rendering_seqno = 0; + obj->last_fenced_seqno = 0; } static void @@ -1699,8 +1719,33 @@ i915_gem_object_move_to_flushing(struct drm_i915_gem_object *obj) BUG_ON(!obj->active); list_move_tail(&obj->mm_list, &dev_priv->mm.flushing_list); - list_del_init(&obj->ring_list); - obj->last_rendering_seqno = 0; + + i915_gem_object_move_off_active(obj); +} + +static void +i915_gem_object_move_to_inactive(struct drm_i915_gem_object *obj) +{ + struct drm_device *dev = obj->base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; + + if (obj->pin_count != 0) + list_move_tail(&obj->mm_list, &dev_priv->mm.pinned_list); + else + list_move_tail(&obj->mm_list, &dev_priv->mm.inactive_list); + + BUG_ON(!list_empty(&obj->gpu_write_list)); + BUG_ON(!obj->active); + obj->ring = NULL; + + i915_gem_object_move_off_active(obj); + obj->fenced_gpu_access = false; + obj->last_fenced_ring = NULL; + + obj->active = 0; + drm_gem_object_unreference(&obj->base); + + WARN_ON(i915_verify_lists(dev)); } /* Immediately discard the backing storage */ @@ -1729,35 +1774,11 @@ i915_gem_object_is_purgeable(struct drm_i915_gem_object *obj) return obj->madv == I915_MADV_DONTNEED; } -static void -i915_gem_object_move_to_inactive(struct drm_i915_gem_object *obj) -{ - struct drm_device *dev = obj->base.dev; - drm_i915_private_t *dev_priv = dev->dev_private; - - if (obj->pin_count != 0) - list_move_tail(&obj->mm_list, &dev_priv->mm.pinned_list); - else - list_move_tail(&obj->mm_list, &dev_priv->mm.inactive_list); - list_del_init(&obj->ring_list); - - BUG_ON(!list_empty(&obj->gpu_write_list)); - - obj->last_rendering_seqno = 0; - obj->ring = NULL; - if (obj->active) { - obj->active = 0; - drm_gem_object_unreference(&obj->base); - } - WARN_ON(i915_verify_lists(dev)); -} - static void i915_gem_process_flushing_list(struct drm_device *dev, uint32_t flush_domains, struct intel_ring_buffer *ring) { - drm_i915_private_t *dev_priv = dev->dev_private; struct drm_i915_gem_object *obj, *next; list_for_each_entry_safe(obj, next, @@ -1770,14 +1791,6 @@ i915_gem_process_flushing_list(struct drm_device *dev, list_del_init(&obj->gpu_write_list); i915_gem_object_move_to_active(obj, ring); - /* update the fence lru list */ - if (obj->fence_reg != I915_FENCE_REG_NONE) { - struct drm_i915_fence_reg *reg = - &dev_priv->fence_regs[obj->fence_reg]; - list_move_tail(®->lru_list, - &dev_priv->mm.fence_list); - } - trace_i915_gem_object_change_domain(obj, obj->base.read_domains, old_write_domain); @@ -2615,8 +2628,7 @@ i915_gem_object_put_fence_reg(struct drm_i915_gem_object *obj, bool interruptible) { struct drm_device *dev = obj->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; - struct drm_i915_fence_reg *reg; + int ret; if (obj->fence_reg == I915_FENCE_REG_NONE) return 0; @@ -2631,19 +2643,23 @@ i915_gem_object_put_fence_reg(struct drm_i915_gem_object *obj, * therefore we must wait for any outstanding access to complete * before clearing the fence. */ - reg = &dev_priv->fence_regs[obj->fence_reg]; - if (reg->gpu) { - int ret; - + if (obj->fenced_gpu_access) { ret = i915_gem_object_flush_gpu_write_domain(obj, NULL); if (ret) return ret; - ret = i915_gem_object_wait_rendering(obj, interruptible); + obj->fenced_gpu_access = false; + } + + if (obj->last_fenced_seqno) { + ret = i915_do_wait_request(dev, + obj->last_fenced_seqno, + interruptible, + obj->last_fenced_ring); if (ret) return ret; - reg->gpu = false; + obj->last_fenced_seqno = false; } i915_gem_object_flush_gtt_write_domain(obj); @@ -3166,8 +3182,9 @@ i915_gem_object_set_to_gpu_domain(struct drm_i915_gem_object *obj, * write domain */ if (obj->base.write_domain && - (obj->base.write_domain != obj->base.pending_read_domains || - obj->ring != ring)) { + (((obj->base.write_domain != obj->base.pending_read_domains || + obj->ring != ring)) || + (obj->fenced_gpu_access && !obj->pending_fenced_gpu_access))) { flush_domains |= obj->base.write_domain; invalidate_domains |= obj->base.pending_read_domains & ~obj->base.write_domain; @@ -3528,7 +3545,6 @@ i915_gem_execbuffer_reserve(struct drm_device *dev, struct drm_i915_gem_exec_object2 *exec_list, int count) { - struct drm_i915_private *dev_priv = dev->dev_private; int ret, i, retry; /* Attempt to pin all of the buffers into the GTT. @@ -3601,7 +3617,7 @@ i915_gem_execbuffer_reserve(struct drm_device *dev, if (ret) break; - dev_priv->fence_regs[obj->fence_reg].gpu = true; + obj->pending_fenced_gpu_access = true; } entry->offset = obj->gtt_offset; @@ -3981,6 +3997,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, goto err; } obj->in_execbuffer = true; + obj->pending_fenced_gpu_access = false; } /* Move the objects en-masse into the GTT, evicting if necessary. */ @@ -4085,6 +4102,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, obj->base.read_domains = obj->base.pending_read_domains; obj->base.write_domain = obj->base.pending_write_domain; + obj->fenced_gpu_access = obj->pending_fenced_gpu_access; i915_gem_object_move_to_active(obj, ring); if (obj->base.write_domain) { -- cgit v1.2.3 From 8ce28bfcf25527b228b8dff1d38480e3643a94d1 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Thu, 25 Nov 2010 16:50:56 +0800 Subject: ASoC: neo1973_gta02_wm8753: fix wrong parameter for snd_soc_register_dai and snd_soc_unregister_dai Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- sound/soc/samsung/neo1973_gta02_wm8753.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/samsung/neo1973_gta02_wm8753.c b/sound/soc/samsung/neo1973_gta02_wm8753.c index 920e8d1f8841..8c65b6334f51 100644 --- a/sound/soc/samsung/neo1973_gta02_wm8753.c +++ b/sound/soc/samsung/neo1973_gta02_wm8753.c @@ -438,7 +438,7 @@ static int __init neo1973_gta02_init(void) return -ENOMEM; /* register bluetooth DAI here */ - ret = snd_soc_register_dai(&neo1973_gta02_snd_device->dev, -1, &bt_dai); + ret = snd_soc_register_dai(&neo1973_gta02_snd_device->dev, &bt_dai); if (ret) { platform_device_put(neo1973_gta02_snd_device); return ret; @@ -491,7 +491,7 @@ module_init(neo1973_gta02_init); static void __exit neo1973_gta02_exit(void) { - snd_soc_unregister_dai(&neo1973_gta02_snd_device->dev, -1); + snd_soc_unregister_dai(&neo1973_gta02_snd_device->dev); platform_device_unregister(neo1973_gta02_snd_device); gpio_free(GTA02_GPIO_HP_IN); gpio_free(GTA02_GPIO_AMP_SHUT); -- cgit v1.2.3 From 74bd21e9b301445b57bdcccdd7b5063ad3fbad0f Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Thu, 25 Nov 2010 13:43:49 +0800 Subject: ASoC: Fix compile error for smartq_wm8987.c Fix below compile error: CC sound/soc/samsung/smartq_wm8987.o sound/soc/samsung/smartq_wm8987.c: In function 'smartq_hifi_hw_params': sound/soc/samsung/smartq_wm8987.c:42: error: 'struct snd_soc_pcm_runtime' has no member named 'dai' sound/soc/samsung/smartq_wm8987.c:43: error: 'struct snd_soc_pcm_runtime' has no member named 'dai' sound/soc/samsung/smartq_wm8987.c: In function 'smartq_wm8987_init': sound/soc/samsung/smartq_wm8987.c:192: warning: passing argument 1 of 'snd_soc_jack_new' from incompatible pointer type sound/soc/samsung/smartq_wm8987.c: At top level: sound/soc/samsung/smartq_wm8987.c:216: warning: initialization from incompatible pointer type make[3]: *** [sound/soc/samsung/smartq_wm8987.o] Error 1 make[2]: *** [sound/soc/samsung] Error 2 make[1]: *** [sound/soc] Error 2 make: *** [sound] Error 2 Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- sound/soc/samsung/smartq_wm8987.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/sound/soc/samsung/smartq_wm8987.c b/sound/soc/samsung/smartq_wm8987.c index d6a340b8c3f7..0a46fa8730d1 100644 --- a/sound/soc/samsung/smartq_wm8987.c +++ b/sound/soc/samsung/smartq_wm8987.c @@ -39,8 +39,8 @@ static int smartq_hifi_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) { struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_dai *codec_dai = rtd->dai->codec_dai; - struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; + struct snd_soc_dai *codec_dai = rtd->codec_dai; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; unsigned int clk = 0; int ret; @@ -153,8 +153,9 @@ static const struct snd_soc_dapm_route audio_map[] = { {"LINPUT2", NULL, "Mic Bias"}, }; -static int smartq_wm8987_init(struct snd_soc_codec *codec) +static int smartq_wm8987_init(struct snd_soc_pcm_runtime *rtd) { + struct snd_soc_codec *codec = rtd->codec; struct snd_soc_dapm_context *dapm = &codec->dapm; int err = 0; @@ -188,7 +189,7 @@ static int smartq_wm8987_init(struct snd_soc_codec *codec) return err; /* Headphone jack detection */ - err = snd_soc_jack_new(&snd_soc_smartq, "Headphone Jack", + err = snd_soc_jack_new(codec, "Headphone Jack", SND_JACK_HEADPHONE, &smartq_jack); if (err) return err; -- cgit v1.2.3 From b26bb71f610f9b346203bff407e4278d98f9fe80 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Thu, 25 Nov 2010 15:11:45 +0800 Subject: ASoC: smdk_wm9713: fix resource leak in smdk_init error path Fix the error path to properly free allocated resources. Signed-off-by: Axel Lin Acked-by: Jassi Brar Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/samsung/smdk_wm9713.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/sound/soc/samsung/smdk_wm9713.c b/sound/soc/samsung/smdk_wm9713.c index 7ce243086e7d..238cb3a38c5d 100644 --- a/sound/soc/samsung/smdk_wm9713.c +++ b/sound/soc/samsung/smdk_wm9713.c @@ -70,24 +70,27 @@ static int __init smdk_init(void) ret = platform_device_add(smdk_snd_wm9713_device); if (ret) - goto err; + goto err1; smdk_snd_ac97_device = platform_device_alloc("soc-audio", -1); if (!smdk_snd_ac97_device) { ret = -ENOMEM; - goto err; + goto err2; } platform_set_drvdata(smdk_snd_ac97_device, &smdk); ret = platform_device_add(smdk_snd_ac97_device); - if (ret) { - platform_device_put(smdk_snd_ac97_device); - goto err; - } + if (ret) + goto err3; return 0; -err: + +err3: + platform_device_put(smdk_snd_ac97_device); +err2: + platform_device_del(smdk_snd_wm9713_device); +err1: platform_device_put(smdk_snd_wm9713_device); return ret; } -- cgit v1.2.3 From 38533698dc14e739eefb22cf66c048e3c9264313 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 24 Nov 2010 17:18:45 +0000 Subject: ASoC: Make SMDK WM8580 driver unloadable Supply a module exit function so that the driver can be unloaded. Signed-off-by: Mark Brown Acked-by: Jassi Brar Acked-by: Liam Girdwood --- sound/soc/samsung/smdk_wm8580.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/sound/soc/samsung/smdk_wm8580.c b/sound/soc/samsung/smdk_wm8580.c index 0ae3d57d79e6..e2d56b9bac5a 100644 --- a/sound/soc/samsung/smdk_wm8580.c +++ b/sound/soc/samsung/smdk_wm8580.c @@ -280,6 +280,12 @@ static int __init smdk_audio_init(void) } module_init(smdk_audio_init); +static void __exit smdk_audio_exit(void) +{ + platform_device_unregister(smdk_snd_device); +} +module_exit(smdk_audio_exit); + MODULE_AUTHOR("Jaswinder Singh, jassi.brar@samsung.com"); MODULE_DESCRIPTION("ALSA SoC SMDK WM8580"); MODULE_LICENSE("GPL"); -- cgit v1.2.3 From 7a93941975a95dd3be319128552fea71867724d7 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 24 Nov 2010 17:20:27 +0000 Subject: ASoC: Update MAINTAINERS for Samsung driver move Signed-off-by: Mark Brown Acked-by: Jassi Brar Acked-by: Liam Girdwood --- MAINTAINERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index 8e6548dbd5db..0c6e84a49ec7 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -5115,7 +5115,7 @@ SAMSUNG AUDIO (ASoC) DRIVERS M: Jassi Brar L: alsa-devel@alsa-project.org (moderated for non-subscribers) S: Supported -F: sound/soc/s3c24xx +F: sound/soc/samsung TLG2300 VIDEO4LINUX-2 DRIVER M: Huang Shijie -- cgit v1.2.3 From fcd02e261bb3b1ae14830d33da5401c6c4ee9bcc Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 24 Nov 2010 16:27:08 +0000 Subject: ASoC: Add WM8737 ALC support Signed-off-by: Mark Brown Acked-by: Liam Girdwood --- sound/soc/codecs/wm8737.c | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/sound/soc/codecs/wm8737.c b/sound/soc/codecs/wm8737.c index a325fe60d26c..2301338cb2c9 100644 --- a/sound/soc/codecs/wm8737.c +++ b/sound/soc/codecs/wm8737.c @@ -78,6 +78,8 @@ static const unsigned int micboost_tlv[] = { static const DECLARE_TLV_DB_SCALE(pga_tlv, -9750, 50, 1); static const DECLARE_TLV_DB_SCALE(adc_tlv, -600, 600, 0); static const DECLARE_TLV_DB_SCALE(ng_tlv, -7800, 600, 0); +static const DECLARE_TLV_DB_SCALE(alc_max_tlv, -1200, 600, 0); +static const DECLARE_TLV_DB_SCALE(alc_target_tlv, -1800, 100, 0); static const char *micbias_enum_text[] = { "25%", @@ -103,6 +105,38 @@ static const char *high_cutoff_text[] = { static const struct soc_enum high_3d = SOC_ENUM_SINGLE(WM8737_3D_ENHANCE, 5, 2, high_cutoff_text); +static const char *alc_fn_text[] = { + "Disabled", "Right", "Left", "Stereo" +}; + +static const struct soc_enum alc_fn = + SOC_ENUM_SINGLE(WM8737_ALC1, 7, 4, alc_fn_text); + +static const char *alc_hold_text[] = { + "0", "2.67ms", "5.33ms", "10.66ms", "21.32ms", "42.64ms", "85.28ms", + "170.56ms", "341.12ms", "682.24ms", "1.364s", "2.728s", "5.458s", + "10.916s", "21.832s", "43.691s" +}; + +static const struct soc_enum alc_hold = + SOC_ENUM_SINGLE(WM8737_ALC2, 0, 16, alc_hold_text); + +static const char *alc_atk_text[] = { + "8.4ms", "16.8ms", "33.6ms", "67.2ms", "134.4ms", "268.8ms", "537.6ms", + "1.075s", "2.15s", "4.3s", "8.6s" +}; + +static const struct soc_enum alc_atk = + SOC_ENUM_SINGLE(WM8737_ALC3, 0, 11, alc_atk_text); + +static const char *alc_dcy_text[] = { + "33.6ms", "67.2ms", "134.4ms", "268.8ms", "537.6ms", "1.075s", "2.15s", + "4.3s", "8.6s", "17.2s", "34.41s" +}; + +static const struct soc_enum alc_dcy = + SOC_ENUM_SINGLE(WM8737_ALC3, 4, 11, alc_dcy_text); + static const struct snd_kcontrol_new wm8737_snd_controls[] = { SOC_DOUBLE_R_TLV("Mic Boost Volume", WM8737_AUDIO_PATH_L, WM8737_AUDIO_PATH_R, 6, 3, 0, micboost_tlv), @@ -132,6 +166,14 @@ SOC_SINGLE_TLV("3D ADC Volume", WM8737_3D_ENHANCE, 7, 1, 1, adc_tlv), SOC_SINGLE("Noise Gate Switch", WM8737_NOISE_GATE, 0, 1, 0), SOC_SINGLE_TLV("Noise Gate Threshold Volume", WM8737_NOISE_GATE, 2, 7, 0, ng_tlv), + +SOC_ENUM("ALC", alc_fn), +SOC_SINGLE_TLV("ALC Max Gain Volume", WM8737_ALC1, 4, 7, 0, alc_max_tlv), +SOC_SINGLE_TLV("ALC Target Volume", WM8737_ALC1, 0, 15, 0, alc_target_tlv), +SOC_ENUM("ALC Hold Time", alc_hold), +SOC_SINGLE("ALC ZC Switch", WM8737_ALC2, 4, 1, 0), +SOC_ENUM("ALC Attack Time", alc_atk), +SOC_ENUM("ALC Decay Time", alc_dcy), }; static const char *linsel_text[] = { -- cgit v1.2.3 From 77c667d1365e19c2848d37bf408e2f0b086b63d9 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 24 Nov 2010 15:48:01 +0000 Subject: ARM: Samsung: Make sure ASoC DMA device is prototyped Ensure that the prototype agrees with the definition and stop sparse complaining when building the file. Signed-off-by: Mark Brown Acked-by: Kukjin Kim Acked-by: Jassi Brar Acked-by: Liam Girdwood --- arch/arm/plat-samsung/dev-asocdma.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/plat-samsung/dev-asocdma.c b/arch/arm/plat-samsung/dev-asocdma.c index b7b1fcaab814..a068c4f42d56 100644 --- a/arch/arm/plat-samsung/dev-asocdma.c +++ b/arch/arm/plat-samsung/dev-asocdma.c @@ -10,6 +10,7 @@ #include #include +#include static u64 audio_dmamask = DMA_BIT_MASK(32); -- cgit v1.2.3 From db6857c6e700111e2787b8e08ef1a7ceae363e03 Mon Sep 17 00:00:00 2001 From: Simon Horman Date: Thu, 25 Nov 2010 10:30:12 +0900 Subject: kdump: update kexec-tools URL and Vivek's email Signed-off-by: Simon Horman Signed-off-by: Jiri Kosina --- Documentation/kdump/kdump.txt | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/Documentation/kdump/kdump.txt b/Documentation/kdump/kdump.txt index cab61d842259..7a9e0b4b2903 100644 --- a/Documentation/kdump/kdump.txt +++ b/Documentation/kdump/kdump.txt @@ -65,18 +65,21 @@ Install kexec-tools 2) Download the kexec-tools user-space package from the following URL: -http://www.kernel.org/pub/linux/kernel/people/horms/kexec-tools/kexec-tools.tar.gz +http://kernel.org/pub/linux/utils/kernel/kexec/kexec-tools.tar.gz This is a symlink to the latest version. The latest kexec-tools git tree is available at: -git://git.kernel.org/pub/scm/linux/kernel/git/horms/kexec-tools.git -or -http://www.kernel.org/git/?p=linux/kernel/git/horms/kexec-tools.git +git://git.kernel.org/pub/scm/utils/kernel/kexec/kexec-tools.git +and +http://www.kernel.org/pub/scm/utils/kernel/kexec/kexec-tools.git + +There is also a gitweb interface available at +http://www.kernel.org/git/?p=utils/kernel/kexec/kexec-tools.git More information about kexec-tools can be found at -http://www.kernel.org/pub/linux/kernel/people/horms/kexec-tools/README.html +http://www.kernel.org/pub/linux/utils/kernel/kexec/README.html 3) Unpack the tarball with the tar command, as follows: @@ -439,6 +442,6 @@ To Do Contact ======= -Vivek Goyal (vgoyal@in.ibm.com) +Vivek Goyal (vgoyal@redhat.com) Maneesh Soni (maneesh@in.ibm.com) -- cgit v1.2.3 From 10f26fa64200095af0e5d80a980e47877865e4b7 Mon Sep 17 00:00:00 2001 From: Asbjoern Sloth Toennesen Date: Fri, 5 Nov 2010 13:30:08 +0000 Subject: kbuild, deb-pkg: select userland architecture based on UTS_MACHINE Instead of creating the debian package for the compiling userland, create it for a userland matching the kernel thats being compiled. This patch supports all Lenny release architectures, and Linux-based architecture candidates for Squeeze. If it can't find a proper Debian userspace it displays a warning, and fallback to let deb-gencontrol use the host's userspace arch. Eg. with this patch the following make command: make ARCH=i386 deb-pkg will output an i386 Debian package instead of an amd64 one, when run on an amd64 machine. Signed-off-by: Asbjoern Sloth Toennesen Acked-by: maximilian attems Signed-off-by: Michal Marek --- scripts/package/builddeb | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/scripts/package/builddeb b/scripts/package/builddeb index 4dfec9aaaace..5d6be3f5e7f7 100644 --- a/scripts/package/builddeb +++ b/scripts/package/builddeb @@ -25,8 +25,41 @@ create_package() { chown -R root:root "$pdir" chmod -R go-w "$pdir" + # Attempt to find the correct Debian architecture + local forcearch="" debarch="" + case "$UTS_MACHINE" in + i386|ia64|alpha) + debarch="$UTS_MACHINE" ;; + x86_64) + debarch=amd64 ;; + sparc*) + debarch=sparc ;; + s390*) + debarch=s390 ;; + ppc*) + debarch=powerpc ;; + parisc*) + debarch=hppa ;; + mips*) + debarch=mips$(grep -q CPU_LITTLE_ENDIAN=y .config && echo el) ;; + arm*) + debarch=arm$(grep -q CONFIG_AEABI=y .config && echo el) ;; + *) + echo "" >&2 + echo "** ** ** WARNING ** ** **" >&2 + echo "" >&2 + echo "Your architecture doesn't have it's equivalent" >&2 + echo "Debian userspace architecture defined!" >&2 + echo "Falling back to using your current userspace instead!" >&2 + echo "Please add support for $UTS_MACHINE to ${0} ..." >&2 + echo "" >&2 + esac + if [ -n "$debarch" ] ; then + forcearch="-DArchitecture=$debarch" + fi + # Create the package - dpkg-gencontrol -isp -p$pname -P"$pdir" + dpkg-gencontrol -isp $forcearch -p$pname -P"$pdir" dpkg --build "$pdir" .. } -- cgit v1.2.3 From 6e5b86924a633f5b6eefb051404339a5a7bb005e Mon Sep 17 00:00:00 2001 From: Américo Wang Date: Fri, 5 Nov 2010 14:16:10 +0800 Subject: gitignore: add scripts/recordmcount This file is generated, should be ignored by git. Signed-off-by: WANG Cong Signed-off-by: Michal Marek --- scripts/.gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/.gitignore b/scripts/.gitignore index c5d5db54c009..e2741d23bab8 100644 --- a/scripts/.gitignore +++ b/scripts/.gitignore @@ -7,3 +7,4 @@ pnmtologo bin2c unifdef ihex2fw +recordmcount -- cgit v1.2.3 From 45f53cc90e8f0e46ab024d0bc1de49ebee0dc583 Mon Sep 17 00:00:00 2001 From: Andi Kleen Date: Fri, 5 Nov 2010 12:06:05 +0100 Subject: Kconfig: fix single letter command in scripts/config The one letter commands in scripts/config didn't work and always printed usage. Fix this here. Cc: erick@openchill.org Reported-by: erick@openchill.org Signed-off-by: Andi Kleen Signed-off-by: Michal Marek --- scripts/config | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/config b/scripts/config index 608d7fdb13e8..dfd4732f7099 100755 --- a/scripts/config +++ b/scripts/config @@ -86,7 +86,7 @@ while [ "$1" != "" ] ; do B=$ARG shift 2 ;; - --*) + -*) checkarg "$1" shift ;; -- cgit v1.2.3 From b9e4b1e0cd401e915e3ba97afc152946f78f9f0b Mon Sep 17 00:00:00 2001 From: Dennis Kügler Date: Tue, 23 Nov 2010 21:40:09 +0100 Subject: HID: Add support for Perixx PERIBOARD-707 (Plus) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch adds support for the media keys of the Perixx PERIBOARD-707 (Plus) keyboard / remote control. Signed-off-by: Dennis Kügler Signed-off-by: Jiri Kosina --- drivers/hid/hid-core.c | 1 + drivers/hid/hid-ids.h | 1 + drivers/hid/hid-topseed.c | 1 + drivers/hid/usbhid/hid-quirks.c | 2 +- 4 files changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 53ac909e2fff..dc56bd61edb7 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -1298,6 +1298,7 @@ static const struct hid_device_id hid_blacklist[] = { { HID_USB_DEVICE(USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION) }, { HID_USB_DEVICE(USB_VENDOR_ID_CHERRY, USB_DEVICE_ID_CHERRY_CYMOTION_SOLAR) }, { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_TACTICAL_PAD) }, + { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_WIRELESS) }, { HID_USB_DEVICE(USB_VENDOR_ID_CREATIVELABS, USB_DEVICE_ID_PRODIKEYS_PCMIDI) }, { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_1) }, { HID_USB_DEVICE(USB_VENDOR_ID_CYPRESS, USB_DEVICE_ID_CYPRESS_BARCODE_2) }, diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index 104b9f9a4c0b..d91bb12f9c54 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h @@ -162,6 +162,7 @@ #define USB_VENDOR_ID_CHICONY 0x04f2 #define USB_DEVICE_ID_CHICONY_TACTICAL_PAD 0x0418 #define USB_DEVICE_ID_CHICONY_MULTI_TOUCH 0xb19d +#define USB_DEVICE_ID_CHICONY_WIRELESS 0x0618 #define USB_VENDOR_ID_CIDC 0x1677 diff --git a/drivers/hid/hid-topseed.c b/drivers/hid/hid-topseed.c index 956ed9ac19d4..613ff7b1d746 100644 --- a/drivers/hid/hid-topseed.c +++ b/drivers/hid/hid-topseed.c @@ -66,6 +66,7 @@ static const struct hid_device_id ts_devices[] = { { HID_USB_DEVICE(USB_VENDOR_ID_BTC, USB_DEVICE_ID_BTC_EMPREX_REMOTE) }, { HID_USB_DEVICE(USB_VENDOR_ID_BTC, USB_DEVICE_ID_BTC_EMPREX_REMOTE_2) }, { HID_USB_DEVICE(USB_VENDOR_ID_TOPSEED2, USB_DEVICE_ID_TOPSEED2_RF_COMBO) }, + { HID_USB_DEVICE(USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_WIRELESS) }, { } }; MODULE_DEVICE_TABLE(hid, ts_devices); diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c index 2c185477eeb3..76b9a149c7df 100644 --- a/drivers/hid/usbhid/hid-quirks.c +++ b/drivers/hid/usbhid/hid-quirks.c @@ -85,7 +85,7 @@ static const struct hid_blacklist { { USB_VENDOR_ID_PI_ENGINEERING, USB_DEVICE_ID_PI_ENGINEERING_VEC_USB_FOOTPEDAL, HID_QUIRK_HIDINPUT_FORCE }, { USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_MULTI_TOUCH, HID_QUIRK_MULTI_INPUT }, - + { USB_VENDOR_ID_CHICONY, USB_DEVICE_ID_CHICONY_WIRELESS, HID_QUIRK_MULTI_INPUT }, { 0, 0 } }; -- cgit v1.2.3 From c6642782b988e907bb50767eab50042f4947e163 Mon Sep 17 00:00:00 2001 From: Daniel Vetter Date: Fri, 12 Nov 2010 13:46:18 +0000 Subject: drm/i915: Add a mechanism for pipelining fence register updates Not employed just yet... Signed-off-by: Daniel Vetter Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_gem.c | 133 +++++++++++++++++++++++++++------------- drivers/gpu/drm/i915/i915_reg.h | 8 ++- 2 files changed, 98 insertions(+), 43 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 2cfdee8811c4..1e9cf2bf9ba4 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -2322,7 +2322,8 @@ i915_gpu_idle(struct drm_device *dev) return 0; } -static void sandybridge_write_fence_reg(struct drm_i915_gem_object *obj) +static int sandybridge_write_fence_reg(struct drm_i915_gem_object *obj, + struct intel_ring_buffer *pipelined) { struct drm_device *dev = obj->base.dev; drm_i915_private_t *dev_priv = dev->dev_private; @@ -2331,7 +2332,7 @@ static void sandybridge_write_fence_reg(struct drm_i915_gem_object *obj) uint64_t val; val = (uint64_t)((obj->gtt_offset + size - 4096) & - 0xfffff000) << 32; + 0xfffff000) << 32; val |= obj->gtt_offset & 0xfffff000; val |= (uint64_t)((obj->stride / 128) - 1) << SANDYBRIDGE_FENCE_PITCH_SHIFT; @@ -2340,10 +2341,26 @@ static void sandybridge_write_fence_reg(struct drm_i915_gem_object *obj) val |= 1 << I965_FENCE_TILING_Y_SHIFT; val |= I965_FENCE_REG_VALID; - I915_WRITE64(FENCE_REG_SANDYBRIDGE_0 + (regnum * 8), val); + if (pipelined) { + int ret = intel_ring_begin(pipelined, 6); + if (ret) + return ret; + + intel_ring_emit(pipelined, MI_NOOP); + intel_ring_emit(pipelined, MI_LOAD_REGISTER_IMM(2)); + intel_ring_emit(pipelined, FENCE_REG_SANDYBRIDGE_0 + regnum*8); + intel_ring_emit(pipelined, (u32)val); + intel_ring_emit(pipelined, FENCE_REG_SANDYBRIDGE_0 + regnum*8 + 4); + intel_ring_emit(pipelined, (u32)(val >> 32)); + intel_ring_advance(pipelined); + } else + I915_WRITE64(FENCE_REG_SANDYBRIDGE_0 + regnum * 8, val); + + return 0; } -static void i965_write_fence_reg(struct drm_i915_gem_object *obj) +static int i965_write_fence_reg(struct drm_i915_gem_object *obj, + struct intel_ring_buffer *pipelined) { struct drm_device *dev = obj->base.dev; drm_i915_private_t *dev_priv = dev->dev_private; @@ -2359,27 +2376,41 @@ static void i965_write_fence_reg(struct drm_i915_gem_object *obj) val |= 1 << I965_FENCE_TILING_Y_SHIFT; val |= I965_FENCE_REG_VALID; - I915_WRITE64(FENCE_REG_965_0 + (regnum * 8), val); + if (pipelined) { + int ret = intel_ring_begin(pipelined, 6); + if (ret) + return ret; + + intel_ring_emit(pipelined, MI_NOOP); + intel_ring_emit(pipelined, MI_LOAD_REGISTER_IMM(2)); + intel_ring_emit(pipelined, FENCE_REG_965_0 + regnum*8); + intel_ring_emit(pipelined, (u32)val); + intel_ring_emit(pipelined, FENCE_REG_965_0 + regnum*8 + 4); + intel_ring_emit(pipelined, (u32)(val >> 32)); + intel_ring_advance(pipelined); + } else + I915_WRITE64(FENCE_REG_965_0 + regnum * 8, val); + + return 0; } -static void i915_write_fence_reg(struct drm_i915_gem_object *obj) +static int i915_write_fence_reg(struct drm_i915_gem_object *obj, + struct intel_ring_buffer *pipelined) { struct drm_device *dev = obj->base.dev; drm_i915_private_t *dev_priv = dev->dev_private; u32 size = obj->gtt_space->size; - uint32_t fence_reg, val, pitch_val; + u32 fence_reg, val, pitch_val; int tile_width; - if ((obj->gtt_offset & ~I915_FENCE_START_MASK) || - (obj->gtt_offset & (size - 1))) { - WARN(1, "%s: object 0x%08x [fenceable? %d] not 1M or size (0x%08x) aligned [gtt_space offset=%lx, size=%lx]\n", - __func__, obj->gtt_offset, obj->map_and_fenceable, size, - obj->gtt_space->start, obj->gtt_space->size); - return; - } + if (WARN((obj->gtt_offset & ~I915_FENCE_START_MASK) || + (size & -size) != size || + (obj->gtt_offset & (size - 1)), + "object 0x%08x [fenceable? %d] not 1M or pot-size (0x%08x) aligned\n", + obj->gtt_offset, obj->map_and_fenceable, size)) + return -EINVAL; - if (obj->tiling_mode == I915_TILING_Y && - HAS_128_BYTE_Y_TILING(dev)) + if (obj->tiling_mode == I915_TILING_Y && HAS_128_BYTE_Y_TILING(dev)) tile_width = 128; else tile_width = 512; @@ -2388,12 +2419,6 @@ static void i915_write_fence_reg(struct drm_i915_gem_object *obj) pitch_val = obj->stride / tile_width; pitch_val = ffs(pitch_val) - 1; - if (obj->tiling_mode == I915_TILING_Y && - HAS_128_BYTE_Y_TILING(dev)) - WARN_ON(pitch_val > I830_FENCE_MAX_PITCH_VAL); - else - WARN_ON(pitch_val > I915_FENCE_MAX_PITCH_VAL); - val = obj->gtt_offset; if (obj->tiling_mode == I915_TILING_Y) val |= 1 << I830_FENCE_TILING_Y_SHIFT; @@ -2406,10 +2431,25 @@ static void i915_write_fence_reg(struct drm_i915_gem_object *obj) fence_reg = FENCE_REG_830_0 + fence_reg * 4; else fence_reg = FENCE_REG_945_8 + (fence_reg - 8) * 4; - I915_WRITE(fence_reg, val); + + if (pipelined) { + int ret = intel_ring_begin(pipelined, 4); + if (ret) + return ret; + + intel_ring_emit(pipelined, MI_NOOP); + intel_ring_emit(pipelined, MI_LOAD_REGISTER_IMM(1)); + intel_ring_emit(pipelined, fence_reg); + intel_ring_emit(pipelined, val); + intel_ring_advance(pipelined); + } else + I915_WRITE(fence_reg, val); + + return 0; } -static void i830_write_fence_reg(struct drm_i915_gem_object *obj) +static int i830_write_fence_reg(struct drm_i915_gem_object *obj, + struct intel_ring_buffer *pipelined) { struct drm_device *dev = obj->base.dev; drm_i915_private_t *dev_priv = dev->dev_private; @@ -2417,29 +2457,38 @@ static void i830_write_fence_reg(struct drm_i915_gem_object *obj) int regnum = obj->fence_reg; uint32_t val; uint32_t pitch_val; - uint32_t fence_size_bits; - if ((obj->gtt_offset & ~I830_FENCE_START_MASK) || - (obj->gtt_offset & (obj->base.size - 1))) { - WARN(1, "%s: object 0x%08x not 512K or size aligned\n", - __func__, obj->gtt_offset); - return; - } + if (WARN((obj->gtt_offset & ~I830_FENCE_START_MASK) || + (size & -size) != size || + (obj->gtt_offset & (size - 1)), + "object 0x%08x not 512K or pot-size 0x%08x aligned\n", + obj->gtt_offset, size)) + return -EINVAL; pitch_val = obj->stride / 128; pitch_val = ffs(pitch_val) - 1; - WARN_ON(pitch_val > I830_FENCE_MAX_PITCH_VAL); val = obj->gtt_offset; if (obj->tiling_mode == I915_TILING_Y) val |= 1 << I830_FENCE_TILING_Y_SHIFT; - fence_size_bits = I830_FENCE_SIZE_BITS(size); - WARN_ON(fence_size_bits & ~0x00000f00); - val |= fence_size_bits; + val |= I830_FENCE_SIZE_BITS(size); val |= pitch_val << I830_FENCE_PITCH_SHIFT; val |= I830_FENCE_REG_VALID; - I915_WRITE(FENCE_REG_830_0 + (regnum * 4), val); + if (pipelined) { + int ret = intel_ring_begin(pipelined, 4); + if (ret) + return ret; + + intel_ring_emit(pipelined, MI_NOOP); + intel_ring_emit(pipelined, MI_LOAD_REGISTER_IMM(1)); + intel_ring_emit(pipelined, FENCE_REG_830_0 + regnum*4); + intel_ring_emit(pipelined, val); + intel_ring_advance(pipelined); + } else + I915_WRITE(FENCE_REG_830_0 + regnum * 4, val); + + return 0; } static int i915_find_fence_reg(struct drm_device *dev, @@ -2512,6 +2561,7 @@ i915_gem_object_get_fence_reg(struct drm_i915_gem_object *obj, struct drm_device *dev = obj->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_fence_reg *reg = NULL; + struct intel_ring_buffer *pipelined = NULL; int ret; /* Just update our place in the LRU if our fence is getting used. */ @@ -2553,25 +2603,24 @@ i915_gem_object_get_fence_reg(struct drm_i915_gem_object *obj, switch (INTEL_INFO(dev)->gen) { case 6: - sandybridge_write_fence_reg(obj); + ret = sandybridge_write_fence_reg(obj, pipelined); break; case 5: case 4: - i965_write_fence_reg(obj); + ret = i965_write_fence_reg(obj, pipelined); break; case 3: - i915_write_fence_reg(obj); + ret = i915_write_fence_reg(obj, pipelined); break; case 2: - i830_write_fence_reg(obj); + ret = i830_write_fence_reg(obj, pipelined); break; } trace_i915_gem_object_get_fence(obj, obj->fence_reg, obj->tiling_mode); - - return 0; + return ret; } /** diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index c668b2fb7e3d..ce97471d9c40 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -164,7 +164,13 @@ #define MI_MEM_VIRTUAL (1 << 22) /* 965+ only */ #define MI_STORE_DWORD_INDEX MI_INSTR(0x21, 1) #define MI_STORE_DWORD_INDEX_SHIFT 2 -#define MI_LOAD_REGISTER_IMM MI_INSTR(0x22, 1) +/* Official intel docs are somewhat sloppy concerning MI_LOAD_REGISTER_IMM: + * - Always issue a MI_NOOP _before_ the MI_LOAD_REGISTER_IMM - otherwise hw + * simply ignores the register load under certain conditions. + * - One can actually load arbitrary many arbitrary registers: Simply issue x + * address/value pairs. Don't overdue it, though, x <= 2^4 must hold! + */ +#define MI_LOAD_REGISTER_IMM(x) MI_INSTR(0x22, 2*x-1) #define MI_FLUSH_DW MI_INSTR(0x26, 2) /* for GEN6 */ #define MI_BATCH_BUFFER MI_INSTR(0x30, 1) #define MI_BATCH_NON_SECURE (1) -- cgit v1.2.3 From 312817a39f17dbb4de000165b5b724e3728cd91c Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 22 Nov 2010 11:50:11 +0000 Subject: drm/i915: Only save and restore fences for UMS With KMS, we can simply relinquish the fence when we idle the GPU and reassign it upon first use. Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_gem.c | 25 ++++++----- drivers/gpu/drm/i915/i915_suspend.c | 89 +++++++++++++++++++------------------ 2 files changed, 61 insertions(+), 53 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 1e9cf2bf9ba4..939c9e34ce96 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1905,11 +1905,22 @@ static void i915_gem_reset_ring_lists(struct drm_i915_private *dev_priv, } } +static void i915_gem_reset_fences(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + int i; + + for (i = 0; i < 16; i++) { + struct drm_i915_fence_reg *reg = &dev_priv->fence_regs[i]; + if (reg->obj) + i915_gem_clear_fence_reg(reg->obj); + } +} + void i915_gem_reset(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_gem_object *obj; - int i; i915_gem_reset_ring_lists(dev_priv, &dev_priv->render_ring); i915_gem_reset_ring_lists(dev_priv, &dev_priv->bsd_ring); @@ -1940,15 +1951,7 @@ void i915_gem_reset(struct drm_device *dev) } /* The fence registers are invalidated so clear them out */ - for (i = 0; i < 16; i++) { - struct drm_i915_fence_reg *reg; - - reg = &dev_priv->fence_regs[i]; - if (!reg->obj) - continue; - - i915_gem_clear_fence_reg(reg->obj); - } + i915_gem_reset_fences(dev); } /** @@ -4706,6 +4709,8 @@ i915_gem_idle(struct drm_device *dev) } } + i915_gem_reset_fences(dev); + /* Hack! Don't let anybody do execbuf while we don't control the chip. * We need to replace this with a semaphore, or something. * And not confound mm.suspended! diff --git a/drivers/gpu/drm/i915/i915_suspend.c b/drivers/gpu/drm/i915/i915_suspend.c index 42729d25da58..011325e51e3a 100644 --- a/drivers/gpu/drm/i915/i915_suspend.c +++ b/drivers/gpu/drm/i915/i915_suspend.c @@ -235,6 +235,7 @@ static void i915_restore_vga(struct drm_device *dev) static void i915_save_modeset_reg(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; + int i; if (drm_core_check_feature(dev, DRIVER_MODESET)) return; @@ -367,6 +368,28 @@ static void i915_save_modeset_reg(struct drm_device *dev) } i915_save_palette(dev, PIPE_B); dev_priv->savePIPEBSTAT = I915_READ(PIPEBSTAT); + + /* Fences */ + switch (INTEL_INFO(dev)->gen) { + case 6: + for (i = 0; i < 16; i++) + dev_priv->saveFENCE[i] = I915_READ64(FENCE_REG_SANDYBRIDGE_0 + (i * 8)); + break; + case 5: + case 4: + for (i = 0; i < 16; i++) + dev_priv->saveFENCE[i] = I915_READ64(FENCE_REG_965_0 + (i * 8)); + break; + case 3: + if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev)) + for (i = 0; i < 8; i++) + dev_priv->saveFENCE[i+8] = I915_READ(FENCE_REG_945_8 + (i * 4)); + case 2: + for (i = 0; i < 8; i++) + dev_priv->saveFENCE[i] = I915_READ(FENCE_REG_830_0 + (i * 4)); + break; + } + return; } @@ -375,10 +398,33 @@ static void i915_restore_modeset_reg(struct drm_device *dev) struct drm_i915_private *dev_priv = dev->dev_private; int dpll_a_reg, fpa0_reg, fpa1_reg; int dpll_b_reg, fpb0_reg, fpb1_reg; + int i; if (drm_core_check_feature(dev, DRIVER_MODESET)) return; + /* Fences */ + switch (INTEL_INFO(dev)->gen) { + case 6: + for (i = 0; i < 16; i++) + I915_WRITE64(FENCE_REG_SANDYBRIDGE_0 + (i * 8), dev_priv->saveFENCE[i]); + break; + case 5: + case 4: + for (i = 0; i < 16; i++) + I915_WRITE64(FENCE_REG_965_0 + (i * 8), dev_priv->saveFENCE[i]); + break; + case 3: + case 2: + if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev)) + for (i = 0; i < 8; i++) + I915_WRITE(FENCE_REG_945_8 + (i * 4), dev_priv->saveFENCE[i+8]); + for (i = 0; i < 8; i++) + I915_WRITE(FENCE_REG_830_0 + (i * 4), dev_priv->saveFENCE[i]); + break; + } + + if (HAS_PCH_SPLIT(dev)) { dpll_a_reg = PCH_DPLL_A; dpll_b_reg = PCH_DPLL_B; @@ -788,28 +834,6 @@ int i915_save_state(struct drm_device *dev) for (i = 0; i < 3; i++) dev_priv->saveSWF2[i] = I915_READ(SWF30 + (i << 2)); - /* Fences */ - switch (INTEL_INFO(dev)->gen) { - case 6: - for (i = 0; i < 16; i++) - dev_priv->saveFENCE[i] = I915_READ64(FENCE_REG_SANDYBRIDGE_0 + (i * 8)); - break; - case 5: - case 4: - for (i = 0; i < 16; i++) - dev_priv->saveFENCE[i] = I915_READ64(FENCE_REG_965_0 + (i * 8)); - break; - case 3: - if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev)) - for (i = 0; i < 8; i++) - dev_priv->saveFENCE[i+8] = I915_READ(FENCE_REG_945_8 + (i * 4)); - case 2: - for (i = 0; i < 8; i++) - dev_priv->saveFENCE[i] = I915_READ(FENCE_REG_830_0 + (i * 4)); - break; - - } - return 0; } @@ -823,27 +847,6 @@ int i915_restore_state(struct drm_device *dev) /* Hardware status page */ I915_WRITE(HWS_PGA, dev_priv->saveHWS); - /* Fences */ - switch (INTEL_INFO(dev)->gen) { - case 6: - for (i = 0; i < 16; i++) - I915_WRITE64(FENCE_REG_SANDYBRIDGE_0 + (i * 8), dev_priv->saveFENCE[i]); - break; - case 5: - case 4: - for (i = 0; i < 16; i++) - I915_WRITE64(FENCE_REG_965_0 + (i * 8), dev_priv->saveFENCE[i]); - break; - case 3: - case 2: - if (IS_I945G(dev) || IS_I945GM(dev) || IS_G33(dev)) - for (i = 0; i < 8; i++) - I915_WRITE(FENCE_REG_945_8 + (i * 4), dev_priv->saveFENCE[i+8]); - for (i = 0; i < 8; i++) - I915_WRITE(FENCE_REG_830_0 + (i * 4), dev_priv->saveFENCE[i]); - break; - } - i915_restore_display(dev); /* Interrupt state */ -- cgit v1.2.3 From ab5793ad3ae11a5cbe2194b449e5fdd80b19f14f Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 22 Nov 2010 13:24:13 +0000 Subject: drm/i915: Tweak on-error bbaddr parsing for clarity Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_irq.c | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index de95c7bb6dba..9aa1e1dc5fd5 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -525,26 +525,23 @@ i915_ringbuffer_last_batch(struct drm_device *dev, /* Locate the current position in the ringbuffer and walk back * to find the most recently dispatched batch buffer. */ - bbaddr = 0; head = I915_READ_HEAD(ring) & HEAD_ADDR; - val = (u32 *)(ring->virtual_start + head); + val = (u32 *)(ring->virtual_start + head); while (--val >= (u32 *)ring->virtual_start) { bbaddr = i915_get_bbaddr(dev, val); if (bbaddr) - break; + return bbaddr; } - if (bbaddr == 0) { - val = (u32 *)(ring->virtual_start + ring->size); - while (--val >= (u32 *)ring->virtual_start) { - bbaddr = i915_get_bbaddr(dev, val); - if (bbaddr) - break; - } + val = (u32 *)(ring->virtual_start + ring->size); + while (--val >= (u32 *)ring->virtual_start) { + bbaddr = i915_get_bbaddr(dev, val); + if (bbaddr) + return bbaddr; } - return bbaddr; + return 0; } static u32 capture_bo_list(struct drm_i915_error_buffer *err, -- cgit v1.2.3 From 2021746e1d5ad1e3b51e24480c566acbb833c7c1 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 23 Nov 2010 15:26:33 +0000 Subject: drm/i915: Mark a few functions as __must_check ... to benefit from the compiler checking that we remember to handle and propagate errors. Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_drv.h | 77 ++++++++++++++++++++++------------------- drivers/gpu/drm/i915/i915_gem.c | 37 +++++++++----------- 2 files changed, 58 insertions(+), 56 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index ee7df1d2b8c8..b6ca10ade426 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1093,11 +1093,11 @@ int i915_gem_init_object(struct drm_gem_object *obj); struct drm_i915_gem_object *i915_gem_alloc_object(struct drm_device *dev, size_t size); void i915_gem_free_object(struct drm_gem_object *obj); -int i915_gem_object_pin(struct drm_i915_gem_object *obj, - uint32_t alignment, - bool map_and_fenceable); +int __must_check i915_gem_object_pin(struct drm_i915_gem_object *obj, + uint32_t alignment, + bool map_and_fenceable); void i915_gem_object_unpin(struct drm_i915_gem_object *obj); -int i915_gem_object_unbind(struct drm_i915_gem_object *obj); +int __must_check i915_gem_object_unbind(struct drm_i915_gem_object *obj); void i915_gem_release_mmap(struct drm_i915_gem_object *obj); void i915_gem_lastclose(struct drm_device *dev); @@ -1110,37 +1110,42 @@ i915_seqno_passed(uint32_t seq1, uint32_t seq2) return (int32_t)(seq1 - seq2) >= 0; } -int i915_gem_object_get_fence_reg(struct drm_i915_gem_object *obj, - bool interruptible); -int i915_gem_object_put_fence_reg(struct drm_i915_gem_object *obj, - bool interruptible); +int __must_check i915_gem_object_get_fence_reg(struct drm_i915_gem_object *obj, + bool interruptible); +int __must_check i915_gem_object_put_fence_reg(struct drm_i915_gem_object *obj, + bool interruptible); + void i915_gem_retire_requests(struct drm_device *dev); void i915_gem_reset(struct drm_device *dev); void i915_gem_clflush_object(struct drm_i915_gem_object *obj); -int i915_gem_object_set_domain(struct drm_i915_gem_object *obj, - uint32_t read_domains, - uint32_t write_domain); -int i915_gem_object_flush_gpu(struct drm_i915_gem_object *obj, - bool interruptible); -int i915_gem_init_ringbuffer(struct drm_device *dev); +int __must_check i915_gem_object_set_domain(struct drm_i915_gem_object *obj, + uint32_t read_domains, + uint32_t write_domain); +int __must_check i915_gem_object_flush_gpu(struct drm_i915_gem_object *obj, + bool interruptible); +int __must_check i915_gem_init_ringbuffer(struct drm_device *dev); void i915_gem_cleanup_ringbuffer(struct drm_device *dev); -int i915_gem_do_init(struct drm_device *dev, unsigned long start, - unsigned long mappable_end, unsigned long end); -int i915_gpu_idle(struct drm_device *dev); -int i915_gem_idle(struct drm_device *dev); -int i915_add_request(struct drm_device *dev, - struct drm_file *file_priv, - struct drm_i915_gem_request *request, - struct intel_ring_buffer *ring); -int i915_do_wait_request(struct drm_device *dev, - uint32_t seqno, - bool interruptible, - struct intel_ring_buffer *ring); +void i915_gem_do_init(struct drm_device *dev, + unsigned long start, + unsigned long mappable_end, + unsigned long end); +int __must_check i915_gpu_idle(struct drm_device *dev); +int __must_check i915_gem_idle(struct drm_device *dev); +int __must_check i915_add_request(struct drm_device *dev, + struct drm_file *file_priv, + struct drm_i915_gem_request *request, + struct intel_ring_buffer *ring); +int __must_check i915_do_wait_request(struct drm_device *dev, + uint32_t seqno, + bool interruptible, + struct intel_ring_buffer *ring); int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf); -int i915_gem_object_set_to_gtt_domain(struct drm_i915_gem_object *obj, - int write); -int i915_gem_object_set_to_display_plane(struct drm_i915_gem_object *obj, - struct intel_ring_buffer *pipelined); +int __must_check +i915_gem_object_set_to_gtt_domain(struct drm_i915_gem_object *obj, + bool write); +int __must_check +i915_gem_object_set_to_display_plane(struct drm_i915_gem_object *obj, + struct intel_ring_buffer *pipelined); int i915_gem_attach_phys_object(struct drm_device *dev, struct drm_i915_gem_object *obj, int id, @@ -1152,14 +1157,16 @@ void i915_gem_release(struct drm_device *dev, struct drm_file *file); /* i915_gem_gtt.c */ void i915_gem_restore_gtt_mappings(struct drm_device *dev); -int i915_gem_gtt_bind_object(struct drm_i915_gem_object *obj); +int __must_check i915_gem_gtt_bind_object(struct drm_i915_gem_object *obj); void i915_gem_gtt_unbind_object(struct drm_i915_gem_object *obj); /* i915_gem_evict.c */ -int i915_gem_evict_something(struct drm_device *dev, int min_size, - unsigned alignment, bool mappable); -int i915_gem_evict_everything(struct drm_device *dev, bool purgeable_only); -int i915_gem_evict_inactive(struct drm_device *dev, bool purgeable_only); +int __must_check i915_gem_evict_something(struct drm_device *dev, int min_size, + unsigned alignment, bool mappable); +int __must_check i915_gem_evict_everything(struct drm_device *dev, + bool purgeable_only); +int __must_check i915_gem_evict_inactive(struct drm_device *dev, + bool purgeable_only); /* i915_gem_tiling.c */ void i915_gem_detect_bit_6_swizzle(struct drm_device *dev); diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 939c9e34ce96..f6167c55a649 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -215,27 +215,19 @@ i915_gem_object_is_inactive(struct drm_i915_gem_object *obj) return obj->gtt_space && !obj->active && obj->pin_count == 0; } -int i915_gem_do_init(struct drm_device *dev, - unsigned long start, - unsigned long mappable_end, - unsigned long end) +void i915_gem_do_init(struct drm_device *dev, + unsigned long start, + unsigned long mappable_end, + unsigned long end) { drm_i915_private_t *dev_priv = dev->dev_private; - if (start >= end || - (start & (PAGE_SIZE - 1)) != 0 || - (end & (PAGE_SIZE - 1)) != 0) { - return -EINVAL; - } - drm_mm_init(&dev_priv->mm.gtt_space, start, end - start); dev_priv->mm.gtt_total = end - start; dev_priv->mm.mappable_gtt_total = min(end, mappable_end) - start; dev_priv->mm.gtt_mappable_end = mappable_end; - - return 0; } int @@ -243,13 +235,16 @@ i915_gem_init_ioctl(struct drm_device *dev, void *data, struct drm_file *file) { struct drm_i915_gem_init *args = data; - int ret; + + if (args->gtt_start >= args->gtt_end || + (args->gtt_end | args->gtt_start) & (PAGE_SIZE - 1)) + return -EINVAL; mutex_lock(&dev->struct_mutex); - ret = i915_gem_do_init(dev, args->gtt_start, args->gtt_end, args->gtt_end); + i915_gem_do_init(dev, args->gtt_start, args->gtt_end, args->gtt_end); mutex_unlock(&dev->struct_mutex); - return ret; + return 0; } int @@ -2949,7 +2944,7 @@ i915_gem_object_flush_cpu_write_domain(struct drm_i915_gem_object *obj) * flushes to occur. */ int -i915_gem_object_set_to_gtt_domain(struct drm_i915_gem_object *obj, int write) +i915_gem_object_set_to_gtt_domain(struct drm_i915_gem_object *obj, bool write) { uint32_t old_write_domain, old_read_domains; int ret; @@ -5177,8 +5172,8 @@ rescan: &dev_priv->mm.inactive_list, mm_list) { if (i915_gem_object_is_purgeable(obj)) { - i915_gem_object_unbind(obj); - if (--nr_to_scan == 0) + if (i915_gem_object_unbind(obj) == 0 && + --nr_to_scan == 0) break; } } @@ -5188,10 +5183,10 @@ rescan: list_for_each_entry_safe(obj, next, &dev_priv->mm.inactive_list, mm_list) { - if (nr_to_scan) { - i915_gem_object_unbind(obj); + if (nr_to_scan && + i915_gem_object_unbind(obj) == 0) nr_to_scan--; - } else + else cnt++; } -- cgit v1.2.3 From 6299f992c0491232f008028a1f40bc9d86c4c76c Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 24 Nov 2010 12:23:44 +0000 Subject: drm/i915: Defer accounting until read from debugfs Simply remove our accounting of objects inside the aperture, keeping only track of what is in the aperture and its current usage. This removes the over-complication of BUGs that were attempting to keep the accounting correct and also removes the overhead of the accounting on the hot-paths. Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_debugfs.c | 84 +++++++++++++++++++---- drivers/gpu/drm/i915/i915_drv.h | 11 +--- drivers/gpu/drm/i915/i915_gem.c | 128 +++++++----------------------------- 3 files changed, 95 insertions(+), 128 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 5faae476954c..3c9d4b876865 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -128,8 +128,15 @@ describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj) if (obj->gtt_space != NULL) seq_printf(m, " (gtt offset: %08x, size: %08x)", obj->gtt_offset, (unsigned int)obj->gtt_space->size); - if (obj->pin_mappable || obj->fault_mappable) - seq_printf(m, " (mappable)"); + if (obj->pin_mappable || obj->fault_mappable) { + char s[3], *t = s; + if (obj->pin_mappable) + *t++ = 'p'; + if (obj->fault_mappable) + *t++ = 'f'; + *t = '\0'; + seq_printf(m, " (%s mappable)", s); + } if (obj->ring != NULL) seq_printf(m, " (%s)", obj->ring->name); } @@ -191,28 +198,79 @@ static int i915_gem_object_list_info(struct seq_file *m, void *data) return 0; } +#define count_objects(list, member) do { \ + list_for_each_entry(obj, list, member) { \ + size += obj->gtt_space->size; \ + ++count; \ + if (obj->map_and_fenceable) { \ + mappable_size += obj->gtt_space->size; \ + ++mappable_count; \ + } \ + } \ +} while(0) + static int i915_gem_object_info(struct seq_file *m, void* data) { struct drm_info_node *node = (struct drm_info_node *) m->private; struct drm_device *dev = node->minor->dev; struct drm_i915_private *dev_priv = dev->dev_private; + u32 count, mappable_count; + size_t size, mappable_size; + struct drm_i915_gem_object *obj; int ret; ret = mutex_lock_interruptible(&dev->struct_mutex); if (ret) return ret; - seq_printf(m, "%u objects\n", dev_priv->mm.object_count); - seq_printf(m, "%zu object bytes\n", dev_priv->mm.object_memory); - seq_printf(m, "%u pinned\n", dev_priv->mm.pin_count); - seq_printf(m, "%zu pin bytes\n", dev_priv->mm.pin_memory); - seq_printf(m, "%u mappable objects in gtt\n", dev_priv->mm.gtt_mappable_count); - seq_printf(m, "%zu mappable gtt bytes\n", dev_priv->mm.gtt_mappable_memory); - seq_printf(m, "%zu mappable gtt used bytes\n", dev_priv->mm.mappable_gtt_used); - seq_printf(m, "%zu mappable gtt total\n", dev_priv->mm.mappable_gtt_total); - seq_printf(m, "%u objects in gtt\n", dev_priv->mm.gtt_count); - seq_printf(m, "%zu gtt bytes\n", dev_priv->mm.gtt_memory); - seq_printf(m, "%zu gtt total\n", dev_priv->mm.gtt_total); + seq_printf(m, "%u objects, %zu bytes\n", + dev_priv->mm.object_count, + dev_priv->mm.object_memory); + + size = count = mappable_size = mappable_count = 0; + count_objects(&dev_priv->mm.gtt_list, gtt_list); + seq_printf(m, "%u [%u] objects, %zu [%zu] bytes in gtt\n", + count, mappable_count, size, mappable_size); + + size = count = mappable_size = mappable_count = 0; + count_objects(&dev_priv->mm.active_list, mm_list); + count_objects(&dev_priv->mm.flushing_list, mm_list); + seq_printf(m, " %u [%u] active objects, %zu [%zu] bytes\n", + count, mappable_count, size, mappable_size); + + size = count = mappable_size = mappable_count = 0; + count_objects(&dev_priv->mm.pinned_list, mm_list); + seq_printf(m, " %u [%u] pinned objects, %zu [%zu] bytes\n", + count, mappable_count, size, mappable_size); + + size = count = mappable_size = mappable_count = 0; + count_objects(&dev_priv->mm.inactive_list, mm_list); + seq_printf(m, " %u [%u] inactive objects, %zu [%zu] bytes\n", + count, mappable_count, size, mappable_size); + + size = count = mappable_size = mappable_count = 0; + count_objects(&dev_priv->mm.deferred_free_list, mm_list); + seq_printf(m, " %u [%u] freed objects, %zu [%zu] bytes\n", + count, mappable_count, size, mappable_size); + + size = count = mappable_size = mappable_count = 0; + list_for_each_entry(obj, &dev_priv->mm.gtt_list, gtt_list) { + if (obj->fault_mappable) { + size += obj->gtt_space->size; + ++count; + } + if (obj->pin_mappable) { + mappable_size += obj->gtt_space->size; + ++mappable_count; + } + } + seq_printf(m, "%u pinned mappable objects, %zu bytes\n", + mappable_count, mappable_size); + seq_printf(m, "%u fault mappable objects, %zu bytes\n", + count, size); + + seq_printf(m, "%zu [%zu] gtt total\n", + dev_priv->mm.gtt_total, dev_priv->mm.mappable_gtt_total); mutex_unlock(&dev->struct_mutex); diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index b6ca10ade426..4ad34f9c55a2 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -642,17 +642,10 @@ typedef struct drm_i915_private { struct drm_i915_gem_phys_object *phys_objs[I915_MAX_PHYS_OBJECT]; /* accounting, useful for userland debugging */ - size_t object_memory; - size_t pin_memory; - size_t gtt_memory; - size_t gtt_mappable_memory; - size_t mappable_gtt_used; - size_t mappable_gtt_total; size_t gtt_total; + size_t mappable_gtt_total; + size_t object_memory; u32 object_count; - u32 pin_count; - u32 gtt_mappable_count; - u32 gtt_count; } mm; struct sdvo_device_mapping sdvo_mappings[2]; /* indicate whether the LVDS_BORDER should be enabled or not */ diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index f6167c55a649..7507a86c3feb 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -83,80 +83,6 @@ static void i915_gem_info_remove_obj(struct drm_i915_private *dev_priv, dev_priv->mm.object_memory -= size; } -static void i915_gem_info_add_gtt(struct drm_i915_private *dev_priv, - struct drm_i915_gem_object *obj) -{ - dev_priv->mm.gtt_count++; - dev_priv->mm.gtt_memory += obj->gtt_space->size; - if (obj->gtt_offset < dev_priv->mm.gtt_mappable_end) { - dev_priv->mm.mappable_gtt_used += - min_t(size_t, obj->gtt_space->size, - dev_priv->mm.gtt_mappable_end - obj->gtt_offset); - } - list_add_tail(&obj->gtt_list, &dev_priv->mm.gtt_list); -} - -static void i915_gem_info_remove_gtt(struct drm_i915_private *dev_priv, - struct drm_i915_gem_object *obj) -{ - dev_priv->mm.gtt_count--; - dev_priv->mm.gtt_memory -= obj->gtt_space->size; - if (obj->gtt_offset < dev_priv->mm.gtt_mappable_end) { - dev_priv->mm.mappable_gtt_used -= - min_t(size_t, obj->gtt_space->size, - dev_priv->mm.gtt_mappable_end - obj->gtt_offset); - } - list_del_init(&obj->gtt_list); -} - -/** - * Update the mappable working set counters. Call _only_ when there is a change - * in one of (pin|fault)_mappable and update *_mappable _before_ calling. - * @mappable: new state the changed mappable flag (either pin_ or fault_). - */ -static void -i915_gem_info_update_mappable(struct drm_i915_private *dev_priv, - struct drm_i915_gem_object *obj, - bool mappable) -{ - if (mappable) { - if (obj->pin_mappable && obj->fault_mappable) - /* Combined state was already mappable. */ - return; - dev_priv->mm.gtt_mappable_count++; - dev_priv->mm.gtt_mappable_memory += obj->gtt_space->size; - } else { - if (obj->pin_mappable || obj->fault_mappable) - /* Combined state still mappable. */ - return; - dev_priv->mm.gtt_mappable_count--; - dev_priv->mm.gtt_mappable_memory -= obj->gtt_space->size; - } -} - -static void i915_gem_info_add_pin(struct drm_i915_private *dev_priv, - struct drm_i915_gem_object *obj, - bool mappable) -{ - dev_priv->mm.pin_count++; - dev_priv->mm.pin_memory += obj->gtt_space->size; - if (mappable) { - obj->pin_mappable = true; - i915_gem_info_update_mappable(dev_priv, obj, true); - } -} - -static void i915_gem_info_remove_pin(struct drm_i915_private *dev_priv, - struct drm_i915_gem_object *obj) -{ - dev_priv->mm.pin_count--; - dev_priv->mm.pin_memory -= obj->gtt_space->size; - if (obj->pin_mappable) { - obj->pin_mappable = false; - i915_gem_info_update_mappable(dev_priv, obj, false); - } -} - int i915_gem_check_is_wedged(struct drm_device *dev) { @@ -253,19 +179,24 @@ i915_gem_get_aperture_ioctl(struct drm_device *dev, void *data, { struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_gem_get_aperture *args = data; + struct drm_i915_gem_object *obj; + size_t pinned; if (!(dev->driver->driver_features & DRIVER_GEM)) return -ENODEV; + pinned = 0; mutex_lock(&dev->struct_mutex); - args->aper_size = dev_priv->mm.gtt_total; - args->aper_available_size = args->aper_size - dev_priv->mm.pin_memory; + list_for_each_entry(obj, &dev_priv->mm.pinned_list, mm_list) + pinned += obj->gtt_space->size; mutex_unlock(&dev->struct_mutex); + args->aper_size = dev_priv->mm.gtt_total; + args->aper_available_size = args->aper_size -pinned; + return 0; } - /** * Creates a new mm object and returns a handle to it. */ @@ -1267,14 +1198,12 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) /* Now bind it into the GTT if needed */ mutex_lock(&dev->struct_mutex); - BUG_ON(obj->pin_count && !obj->pin_mappable); if (!obj->map_and_fenceable) { ret = i915_gem_object_unbind(obj); if (ret) goto unlock; } - if (!obj->gtt_space) { ret = i915_gem_object_bind_to_gtt(obj, 0, true); if (ret) @@ -1285,11 +1214,6 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) if (ret) goto unlock; - if (!obj->fault_mappable) { - obj->fault_mappable = true; - i915_gem_info_update_mappable(dev_priv, obj, true); - } - /* Need a new fence register? */ if (obj->tiling_mode != I915_TILING_NONE) { ret = i915_gem_object_get_fence_reg(obj, true); @@ -1300,6 +1224,8 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) if (i915_gem_object_is_inactive(obj)) list_move_tail(&obj->mm_list, &dev_priv->mm.inactive_list); + obj->fault_mappable = true; + pfn = ((dev->agp->base + obj->gtt_offset) >> PAGE_SHIFT) + page_offset; @@ -1406,18 +1332,14 @@ out_free_list: void i915_gem_release_mmap(struct drm_i915_gem_object *obj) { - struct drm_device *dev = obj->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + if (!obj->fault_mappable) + return; - if (unlikely(obj->base.map_list.map && dev->dev_mapping)) - unmap_mapping_range(dev->dev_mapping, - (loff_t)obj->base.map_list.hash.key<base.size, 1); + unmap_mapping_range(obj->base.dev->dev_mapping, + (loff_t)obj->base.map_list.hash.key<base.size, 1); - if (obj->fault_mappable) { - obj->fault_mappable = false; - i915_gem_info_update_mappable(dev_priv, obj, false); - } + obj->fault_mappable = false; } static void @@ -2221,8 +2143,6 @@ i915_gem_object_wait_rendering(struct drm_i915_gem_object *obj, int i915_gem_object_unbind(struct drm_i915_gem_object *obj) { - struct drm_device *dev = obj->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; int ret = 0; if (obj->gtt_space == NULL) @@ -2259,10 +2179,9 @@ i915_gem_object_unbind(struct drm_i915_gem_object *obj) i915_gem_clear_fence_reg(obj); i915_gem_gtt_unbind_object(obj); - i915_gem_object_put_pages_gtt(obj); - i915_gem_info_remove_gtt(dev_priv, obj); + list_del_init(&obj->gtt_list); list_del_init(&obj->mm_list); /* Avoid an unnecessary call to unbind on rebind. */ obj->map_and_fenceable = true; @@ -2833,11 +2752,8 @@ i915_gem_object_bind_to_gtt(struct drm_i915_gem_object *obj, goto search_free; } - obj->gtt_offset = obj->gtt_space->start; - - /* keep track of bounds object by adding it to the inactive list */ + list_add_tail(&obj->gtt_list, &dev_priv->mm.gtt_list); list_add_tail(&obj->mm_list, &dev_priv->mm.inactive_list); - i915_gem_info_add_gtt(dev_priv, obj); /* Assert that the object is not currently in any GPU domain. As it * wasn't in the GTT, there shouldn't be any way it could have been in @@ -2846,7 +2762,7 @@ i915_gem_object_bind_to_gtt(struct drm_i915_gem_object *obj, BUG_ON(obj->base.read_domains & I915_GEM_GPU_DOMAINS); BUG_ON(obj->base.write_domain & I915_GEM_GPU_DOMAINS); - trace_i915_gem_object_bind(obj, obj->gtt_offset, map_and_fenceable); + obj->gtt_offset = obj->gtt_space->start; fenceable = obj->gtt_space->size == fence_size && @@ -2857,6 +2773,7 @@ i915_gem_object_bind_to_gtt(struct drm_i915_gem_object *obj, obj->map_and_fenceable = mappable && fenceable; + trace_i915_gem_object_bind(obj, obj->gtt_offset, map_and_fenceable); return 0; } @@ -4372,12 +4289,11 @@ i915_gem_object_pin(struct drm_i915_gem_object *obj, } if (obj->pin_count++ == 0) { - i915_gem_info_add_pin(dev_priv, obj, map_and_fenceable); if (!obj->active) list_move_tail(&obj->mm_list, &dev_priv->mm.pinned_list); } - BUG_ON(!obj->pin_mappable && map_and_fenceable); + obj->pin_mappable |= map_and_fenceable; WARN_ON(i915_verify_lists(dev)); return 0; @@ -4397,7 +4313,7 @@ i915_gem_object_unpin(struct drm_i915_gem_object *obj) if (!obj->active) list_move_tail(&obj->mm_list, &dev_priv->mm.inactive_list); - i915_gem_info_remove_pin(dev_priv, obj); + obj->pin_mappable = false; } WARN_ON(i915_verify_lists(dev)); } -- cgit v1.2.3 From 01660dfc37933c92dbb7c5718aea61f88025d71f Mon Sep 17 00:00:00 2001 From: Arnaud Lacombe Date: Mon, 8 Nov 2010 18:31:53 -0500 Subject: scripts/genksyms: fix header usage FreeBSD does not like when __STDC__ is defined, use the standard instead. Signed-off-by: Arnaud Lacombe Signed-off-by: Michal Marek --- scripts/genksyms/parse.c_shipped | 2 +- scripts/genksyms/parse.y | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/genksyms/parse.c_shipped b/scripts/genksyms/parse.c_shipped index eaee44e66a43..809b949e495b 100644 --- a/scripts/genksyms/parse.c_shipped +++ b/scripts/genksyms/parse.c_shipped @@ -160,7 +160,7 @@ #include -#include +#include #include "genksyms.h" static int is_typedef; diff --git a/scripts/genksyms/parse.y b/scripts/genksyms/parse.y index 10d7dc724b6d..09a265cd7193 100644 --- a/scripts/genksyms/parse.y +++ b/scripts/genksyms/parse.y @@ -24,7 +24,7 @@ %{ #include -#include +#include #include "genksyms.h" static int is_typedef; -- cgit v1.2.3 From 54cf91dc4e51fd5070a9a2346377493cc38a1ca9 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 25 Nov 2010 18:00:26 +0000 Subject: drm/i915: Split i915_gem_execbuffer into its own file. A number of dragons have been seen lurking within the execbuffer code. The first step is then to isolate them from the rest and begin to scrutinise them in depth. Suggested by Daniel Vetter. Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/Makefile | 3 +- drivers/gpu/drm/i915/i915_drv.h | 18 + drivers/gpu/drm/i915/i915_gem.c | 1164 +--------------------------- drivers/gpu/drm/i915/i915_gem_execbuffer.c | 1155 +++++++++++++++++++++++++++ 4 files changed, 1188 insertions(+), 1152 deletions(-) create mode 100644 drivers/gpu/drm/i915/i915_gem_execbuffer.c diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index b3cdb4fe46e0..0ae6a7c5020f 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile @@ -8,8 +8,9 @@ i915-y := i915_drv.o i915_dma.o i915_irq.o i915_mem.o \ i915_suspend.o \ i915_gem.o \ i915_gem_debug.o \ - i915_gem_gtt.o \ i915_gem_evict.o \ + i915_gem_execbuffer.o \ + i915_gem_gtt.o \ i915_gem_tiling.o \ i915_trace_points.o \ intel_display.o \ diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 4ad34f9c55a2..6c10b645dde9 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1083,6 +1083,10 @@ int i915_gem_get_aperture_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv); void i915_gem_load(struct drm_device *dev); int i915_gem_init_object(struct drm_gem_object *obj); +void i915_gem_flush_ring(struct drm_device *dev, + struct intel_ring_buffer *ring, + uint32_t invalidate_domains, + uint32_t flush_domains); struct drm_i915_gem_object *i915_gem_alloc_object(struct drm_device *dev, size_t size); void i915_gem_free_object(struct drm_gem_object *obj); @@ -1094,6 +1098,12 @@ int __must_check i915_gem_object_unbind(struct drm_i915_gem_object *obj); void i915_gem_release_mmap(struct drm_i915_gem_object *obj); void i915_gem_lastclose(struct drm_device *dev); +int __must_check i915_mutex_lock_interruptible(struct drm_device *dev); +int __must_check i915_gem_object_wait_rendering(struct drm_i915_gem_object *obj, + bool interruptible); +void i915_gem_object_move_to_active(struct drm_i915_gem_object *obj, + struct intel_ring_buffer *ring); + /** * Returns true if seq1 is later than seq2. */ @@ -1103,6 +1113,14 @@ i915_seqno_passed(uint32_t seq1, uint32_t seq2) return (int32_t)(seq1 - seq2) >= 0; } +static inline u32 +i915_gem_next_request_seqno(struct drm_device *dev, + struct intel_ring_buffer *ring) +{ + drm_i915_private_t *dev_priv = dev->dev_private; + return ring->outstanding_lazy_request = dev_priv->next_seqno; +} + int __must_check i915_gem_object_get_fence_reg(struct drm_i915_gem_object *obj, bool interruptible); int __must_check i915_gem_object_put_fence_reg(struct drm_i915_gem_object *obj, diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 7507a86c3feb..b30c6c167048 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -35,12 +35,6 @@ #include #include -struct change_domains { - uint32_t invalidate_domains; - uint32_t flush_domains; - uint32_t flush_rings; -}; - static int i915_gem_object_flush_gpu_write_domain(struct drm_i915_gem_object *obj, struct intel_ring_buffer *pipelined); static void i915_gem_object_flush_gtt_write_domain(struct drm_i915_gem_object *obj); @@ -51,8 +45,6 @@ static int i915_gem_object_set_cpu_read_domain_range(struct drm_i915_gem_object uint64_t offset, uint64_t size); static void i915_gem_object_set_to_full_cpu_read_domain(struct drm_i915_gem_object *obj); -static int i915_gem_object_wait_rendering(struct drm_i915_gem_object *obj, - bool interruptible); static int i915_gem_object_bind_to_gtt(struct drm_i915_gem_object *obj, unsigned alignment, bool map_and_fenceable); @@ -113,7 +105,7 @@ i915_gem_check_is_wedged(struct drm_device *dev) return -EIO; } -static int i915_mutex_lock_interruptible(struct drm_device *dev) +int i915_mutex_lock_interruptible(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; int ret; @@ -1577,15 +1569,7 @@ i915_gem_object_put_pages_gtt(struct drm_i915_gem_object *obj) obj->pages = NULL; } -static uint32_t -i915_gem_next_request_seqno(struct drm_device *dev, - struct intel_ring_buffer *ring) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - return ring->outstanding_lazy_request = dev_priv->next_seqno; -} - -static void +void i915_gem_object_move_to_active(struct drm_i915_gem_object *obj, struct intel_ring_buffer *ring) { @@ -1762,24 +1746,6 @@ i915_add_request(struct drm_device *dev, return 0; } -/** - * Command execution barrier - * - * Ensures that all commands in the ring are finished - * before signalling the CPU - */ -static void -i915_retire_commands(struct drm_device *dev, struct intel_ring_buffer *ring) -{ - uint32_t flush_domains = 0; - - /* The sampler always gets flushed on i965 (sigh) */ - if (INTEL_INFO(dev)->gen >= 4) - flush_domains |= I915_GEM_DOMAIN_SAMPLER; - - ring->flush(ring, I915_GEM_DOMAIN_COMMAND, flush_domains); -} - static inline void i915_gem_request_remove_from_client(struct drm_i915_gem_request *request) { @@ -2072,45 +2038,11 @@ i915_wait_request(struct drm_device *dev, uint32_t seqno, return i915_do_wait_request(dev, seqno, 1, ring); } -static void -i915_gem_flush_ring(struct drm_device *dev, - struct intel_ring_buffer *ring, - uint32_t invalidate_domains, - uint32_t flush_domains) -{ - ring->flush(ring, invalidate_domains, flush_domains); - i915_gem_process_flushing_list(dev, flush_domains, ring); -} - -static void -i915_gem_flush(struct drm_device *dev, - uint32_t invalidate_domains, - uint32_t flush_domains, - uint32_t flush_rings) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - - if (flush_domains & I915_GEM_DOMAIN_CPU) - intel_gtt_chipset_flush(); - - if ((flush_domains | invalidate_domains) & I915_GEM_GPU_DOMAINS) { - if (flush_rings & RING_RENDER) - i915_gem_flush_ring(dev, &dev_priv->render_ring, - invalidate_domains, flush_domains); - if (flush_rings & RING_BSD) - i915_gem_flush_ring(dev, &dev_priv->bsd_ring, - invalidate_domains, flush_domains); - if (flush_rings & RING_BLT) - i915_gem_flush_ring(dev, &dev_priv->blt_ring, - invalidate_domains, flush_domains); - } -} - /** * Ensures that all rendering to the object has completed and the object is * safe to unbind from the GTT or access from the CPU. */ -static int +int i915_gem_object_wait_rendering(struct drm_i915_gem_object *obj, bool interruptible) { @@ -2198,6 +2130,16 @@ i915_gem_object_unbind(struct drm_i915_gem_object *obj) return ret; } +void +i915_gem_flush_ring(struct drm_device *dev, + struct intel_ring_buffer *ring, + uint32_t invalidate_domains, + uint32_t flush_domains) +{ + ring->flush(ring, invalidate_domains, flush_domains); + i915_gem_process_flushing_list(dev, flush_domains, ring); +} + static int i915_ring_idle(struct drm_device *dev, struct intel_ring_buffer *ring) { @@ -3014,174 +2956,6 @@ i915_gem_object_set_to_cpu_domain(struct drm_i915_gem_object *obj, bool write) return 0; } -/* - * Set the next domain for the specified object. This - * may not actually perform the necessary flushing/invaliding though, - * as that may want to be batched with other set_domain operations - * - * This is (we hope) the only really tricky part of gem. The goal - * is fairly simple -- track which caches hold bits of the object - * and make sure they remain coherent. A few concrete examples may - * help to explain how it works. For shorthand, we use the notation - * (read_domains, write_domain), e.g. (CPU, CPU) to indicate the - * a pair of read and write domain masks. - * - * Case 1: the batch buffer - * - * 1. Allocated - * 2. Written by CPU - * 3. Mapped to GTT - * 4. Read by GPU - * 5. Unmapped from GTT - * 6. Freed - * - * Let's take these a step at a time - * - * 1. Allocated - * Pages allocated from the kernel may still have - * cache contents, so we set them to (CPU, CPU) always. - * 2. Written by CPU (using pwrite) - * The pwrite function calls set_domain (CPU, CPU) and - * this function does nothing (as nothing changes) - * 3. Mapped by GTT - * This function asserts that the object is not - * currently in any GPU-based read or write domains - * 4. Read by GPU - * i915_gem_execbuffer calls set_domain (COMMAND, 0). - * As write_domain is zero, this function adds in the - * current read domains (CPU+COMMAND, 0). - * flush_domains is set to CPU. - * invalidate_domains is set to COMMAND - * clflush is run to get data out of the CPU caches - * then i915_dev_set_domain calls i915_gem_flush to - * emit an MI_FLUSH and drm_agp_chipset_flush - * 5. Unmapped from GTT - * i915_gem_object_unbind calls set_domain (CPU, CPU) - * flush_domains and invalidate_domains end up both zero - * so no flushing/invalidating happens - * 6. Freed - * yay, done - * - * Case 2: The shared render buffer - * - * 1. Allocated - * 2. Mapped to GTT - * 3. Read/written by GPU - * 4. set_domain to (CPU,CPU) - * 5. Read/written by CPU - * 6. Read/written by GPU - * - * 1. Allocated - * Same as last example, (CPU, CPU) - * 2. Mapped to GTT - * Nothing changes (assertions find that it is not in the GPU) - * 3. Read/written by GPU - * execbuffer calls set_domain (RENDER, RENDER) - * flush_domains gets CPU - * invalidate_domains gets GPU - * clflush (obj) - * MI_FLUSH and drm_agp_chipset_flush - * 4. set_domain (CPU, CPU) - * flush_domains gets GPU - * invalidate_domains gets CPU - * wait_rendering (obj) to make sure all drawing is complete. - * This will include an MI_FLUSH to get the data from GPU - * to memory - * clflush (obj) to invalidate the CPU cache - * Another MI_FLUSH in i915_gem_flush (eliminate this somehow?) - * 5. Read/written by CPU - * cache lines are loaded and dirtied - * 6. Read written by GPU - * Same as last GPU access - * - * Case 3: The constant buffer - * - * 1. Allocated - * 2. Written by CPU - * 3. Read by GPU - * 4. Updated (written) by CPU again - * 5. Read by GPU - * - * 1. Allocated - * (CPU, CPU) - * 2. Written by CPU - * (CPU, CPU) - * 3. Read by GPU - * (CPU+RENDER, 0) - * flush_domains = CPU - * invalidate_domains = RENDER - * clflush (obj) - * MI_FLUSH - * drm_agp_chipset_flush - * 4. Updated (written) by CPU again - * (CPU, CPU) - * flush_domains = 0 (no previous write domain) - * invalidate_domains = 0 (no new read domains) - * 5. Read by GPU - * (CPU+RENDER, 0) - * flush_domains = CPU - * invalidate_domains = RENDER - * clflush (obj) - * MI_FLUSH - * drm_agp_chipset_flush - */ -static void -i915_gem_object_set_to_gpu_domain(struct drm_i915_gem_object *obj, - struct intel_ring_buffer *ring, - struct change_domains *cd) -{ - uint32_t invalidate_domains = 0, flush_domains = 0; - - /* - * If the object isn't moving to a new write domain, - * let the object stay in multiple read domains - */ - if (obj->base.pending_write_domain == 0) - obj->base.pending_read_domains |= obj->base.read_domains; - - /* - * Flush the current write domain if - * the new read domains don't match. Invalidate - * any read domains which differ from the old - * write domain - */ - if (obj->base.write_domain && - (((obj->base.write_domain != obj->base.pending_read_domains || - obj->ring != ring)) || - (obj->fenced_gpu_access && !obj->pending_fenced_gpu_access))) { - flush_domains |= obj->base.write_domain; - invalidate_domains |= - obj->base.pending_read_domains & ~obj->base.write_domain; - } - /* - * Invalidate any read caches which may have - * stale data. That is, any new read domains. - */ - invalidate_domains |= obj->base.pending_read_domains & ~obj->base.read_domains; - if ((flush_domains | invalidate_domains) & I915_GEM_DOMAIN_CPU) - i915_gem_clflush_object(obj); - - /* blow away mappings if mapped through GTT */ - if ((flush_domains | invalidate_domains) & I915_GEM_DOMAIN_GTT) - i915_gem_release_mmap(obj); - - /* The actual obj->write_domain will be updated with - * pending_write_domain after we emit the accumulated flush for all - * of our domain changes in execbuffers (which clears objects' - * write_domains). So if we have a current write domain that we - * aren't changing, set pending_write_domain to that. - */ - if (flush_domains == 0 && obj->base.pending_write_domain == 0) - obj->base.pending_write_domain = obj->base.write_domain; - - cd->invalidate_domains |= invalidate_domains; - cd->flush_domains |= flush_domains; - if (flush_domains & I915_GEM_GPU_DOMAINS) - cd->flush_rings |= obj->ring->id; - if (invalidate_domains & I915_GEM_GPU_DOMAINS) - cd->flush_rings |= ring->id; -} - /** * Moves the object from a partially CPU read to a full one. * @@ -3284,451 +3058,6 @@ i915_gem_object_set_cpu_read_domain_range(struct drm_i915_gem_object *obj, return 0; } -static int -i915_gem_execbuffer_relocate_entry(struct drm_i915_gem_object *obj, - struct drm_file *file_priv, - struct drm_i915_gem_exec_object2 *entry, - struct drm_i915_gem_relocation_entry *reloc) -{ - struct drm_device *dev = obj->base.dev; - struct drm_gem_object *target_obj; - uint32_t target_offset; - int ret = -EINVAL; - - target_obj = drm_gem_object_lookup(dev, file_priv, - reloc->target_handle); - if (target_obj == NULL) - return -ENOENT; - - target_offset = to_intel_bo(target_obj)->gtt_offset; - -#if WATCH_RELOC - DRM_INFO("%s: obj %p offset %08x target %d " - "read %08x write %08x gtt %08x " - "presumed %08x delta %08x\n", - __func__, - obj, - (int) reloc->offset, - (int) reloc->target_handle, - (int) reloc->read_domains, - (int) reloc->write_domain, - (int) target_offset, - (int) reloc->presumed_offset, - reloc->delta); -#endif - - /* The target buffer should have appeared before us in the - * exec_object list, so it should have a GTT space bound by now. - */ - if (target_offset == 0) { - DRM_ERROR("No GTT space found for object %d\n", - reloc->target_handle); - goto err; - } - - /* Validate that the target is in a valid r/w GPU domain */ - if (reloc->write_domain & (reloc->write_domain - 1)) { - DRM_ERROR("reloc with multiple write domains: " - "obj %p target %d offset %d " - "read %08x write %08x", - obj, reloc->target_handle, - (int) reloc->offset, - reloc->read_domains, - reloc->write_domain); - goto err; - } - if (reloc->write_domain & I915_GEM_DOMAIN_CPU || - reloc->read_domains & I915_GEM_DOMAIN_CPU) { - DRM_ERROR("reloc with read/write CPU domains: " - "obj %p target %d offset %d " - "read %08x write %08x", - obj, reloc->target_handle, - (int) reloc->offset, - reloc->read_domains, - reloc->write_domain); - goto err; - } - if (reloc->write_domain && target_obj->pending_write_domain && - reloc->write_domain != target_obj->pending_write_domain) { - DRM_ERROR("Write domain conflict: " - "obj %p target %d offset %d " - "new %08x old %08x\n", - obj, reloc->target_handle, - (int) reloc->offset, - reloc->write_domain, - target_obj->pending_write_domain); - goto err; - } - - target_obj->pending_read_domains |= reloc->read_domains; - target_obj->pending_write_domain |= reloc->write_domain; - - /* If the relocation already has the right value in it, no - * more work needs to be done. - */ - if (target_offset == reloc->presumed_offset) - goto out; - - /* Check that the relocation address is valid... */ - if (reloc->offset > obj->base.size - 4) { - DRM_ERROR("Relocation beyond object bounds: " - "obj %p target %d offset %d size %d.\n", - obj, reloc->target_handle, - (int) reloc->offset, - (int) obj->base.size); - goto err; - } - if (reloc->offset & 3) { - DRM_ERROR("Relocation not 4-byte aligned: " - "obj %p target %d offset %d.\n", - obj, reloc->target_handle, - (int) reloc->offset); - goto err; - } - - /* and points to somewhere within the target object. */ - if (reloc->delta >= target_obj->size) { - DRM_ERROR("Relocation beyond target object bounds: " - "obj %p target %d delta %d size %d.\n", - obj, reloc->target_handle, - (int) reloc->delta, - (int) target_obj->size); - goto err; - } - - reloc->delta += target_offset; - if (obj->base.write_domain == I915_GEM_DOMAIN_CPU) { - uint32_t page_offset = reloc->offset & ~PAGE_MASK; - char *vaddr; - - vaddr = kmap_atomic(obj->pages[reloc->offset >> PAGE_SHIFT]); - *(uint32_t *)(vaddr + page_offset) = reloc->delta; - kunmap_atomic(vaddr); - } else { - struct drm_i915_private *dev_priv = dev->dev_private; - uint32_t __iomem *reloc_entry; - void __iomem *reloc_page; - - ret = i915_gem_object_set_to_gtt_domain(obj, 1); - if (ret) - goto err; - - /* Map the page containing the relocation we're going to perform. */ - reloc->offset += obj->gtt_offset; - reloc_page = io_mapping_map_atomic_wc(dev_priv->mm.gtt_mapping, - reloc->offset & PAGE_MASK); - reloc_entry = (uint32_t __iomem *) - (reloc_page + (reloc->offset & ~PAGE_MASK)); - iowrite32(reloc->delta, reloc_entry); - io_mapping_unmap_atomic(reloc_page); - } - - /* and update the user's relocation entry */ - reloc->presumed_offset = target_offset; - -out: - ret = 0; -err: - drm_gem_object_unreference(target_obj); - return ret; -} - -static int -i915_gem_execbuffer_relocate_object(struct drm_i915_gem_object *obj, - struct drm_file *file_priv, - struct drm_i915_gem_exec_object2 *entry) -{ - struct drm_i915_gem_relocation_entry __user *user_relocs; - int i, ret; - - user_relocs = (void __user *)(uintptr_t)entry->relocs_ptr; - for (i = 0; i < entry->relocation_count; i++) { - struct drm_i915_gem_relocation_entry reloc; - - if (__copy_from_user_inatomic(&reloc, - user_relocs+i, - sizeof(reloc))) - return -EFAULT; - - ret = i915_gem_execbuffer_relocate_entry(obj, file_priv, entry, &reloc); - if (ret) - return ret; - - if (__copy_to_user_inatomic(&user_relocs[i].presumed_offset, - &reloc.presumed_offset, - sizeof(reloc.presumed_offset))) - return -EFAULT; - } - - return 0; -} - -static int -i915_gem_execbuffer_relocate_object_slow(struct drm_i915_gem_object *obj, - struct drm_file *file_priv, - struct drm_i915_gem_exec_object2 *entry, - struct drm_i915_gem_relocation_entry *relocs) -{ - int i, ret; - - for (i = 0; i < entry->relocation_count; i++) { - ret = i915_gem_execbuffer_relocate_entry(obj, file_priv, entry, &relocs[i]); - if (ret) - return ret; - } - - return 0; -} - -static int -i915_gem_execbuffer_relocate(struct drm_device *dev, - struct drm_file *file, - struct drm_i915_gem_object **object_list, - struct drm_i915_gem_exec_object2 *exec_list, - int count) -{ - int i, ret; - - for (i = 0; i < count; i++) { - struct drm_i915_gem_object *obj = object_list[i]; - obj->base.pending_read_domains = 0; - obj->base.pending_write_domain = 0; - ret = i915_gem_execbuffer_relocate_object(obj, file, - &exec_list[i]); - if (ret) - return ret; - } - - return 0; -} - -static int -i915_gem_execbuffer_reserve(struct drm_device *dev, - struct drm_file *file, - struct drm_i915_gem_object **object_list, - struct drm_i915_gem_exec_object2 *exec_list, - int count) -{ - int ret, i, retry; - - /* Attempt to pin all of the buffers into the GTT. - * This is done in 3 phases: - * - * 1a. Unbind all objects that do not match the GTT constraints for - * the execbuffer (fenceable, mappable, alignment etc). - * 1b. Increment pin count for already bound objects. - * 2. Bind new objects. - * 3. Decrement pin count. - * - * This avoid unnecessary unbinding of later objects in order to makr - * room for the earlier objects *unless* we need to defragment. - */ - retry = 0; - do { - ret = 0; - - /* Unbind any ill-fitting objects or pin. */ - for (i = 0; i < count; i++) { - struct drm_i915_gem_object *obj = object_list[i]; - struct drm_i915_gem_exec_object2 *entry = &exec_list[i]; - bool need_fence, need_mappable; - - if (!obj->gtt_space) - continue; - - need_fence = - entry->flags & EXEC_OBJECT_NEEDS_FENCE && - obj->tiling_mode != I915_TILING_NONE; - need_mappable = - entry->relocation_count ? true : need_fence; - - if ((entry->alignment && obj->gtt_offset & (entry->alignment - 1)) || - (need_mappable && !obj->map_and_fenceable)) - ret = i915_gem_object_unbind(obj); - else - ret = i915_gem_object_pin(obj, - entry->alignment, - need_mappable); - if (ret) { - count = i; - goto err; - } - } - - /* Bind fresh objects */ - for (i = 0; i < count; i++) { - struct drm_i915_gem_exec_object2 *entry = &exec_list[i]; - struct drm_i915_gem_object *obj = object_list[i]; - bool need_fence; - - need_fence = - entry->flags & EXEC_OBJECT_NEEDS_FENCE && - obj->tiling_mode != I915_TILING_NONE; - - if (!obj->gtt_space) { - bool need_mappable = - entry->relocation_count ? true : need_fence; - - ret = i915_gem_object_pin(obj, - entry->alignment, - need_mappable); - if (ret) - break; - } - - if (need_fence) { - ret = i915_gem_object_get_fence_reg(obj, true); - if (ret) - break; - - obj->pending_fenced_gpu_access = true; - } - - entry->offset = obj->gtt_offset; - } - -err: /* Decrement pin count for bound objects */ - for (i = 0; i < count; i++) { - struct drm_i915_gem_object *obj = object_list[i]; - if (obj->gtt_space) - i915_gem_object_unpin(obj); - } - - if (ret != -ENOSPC || retry > 1) - return ret; - - /* First attempt, just clear anything that is purgeable. - * Second attempt, clear the entire GTT. - */ - ret = i915_gem_evict_everything(dev, retry == 0); - if (ret) - return ret; - - retry++; - } while (1); -} - -static int -i915_gem_execbuffer_relocate_slow(struct drm_device *dev, - struct drm_file *file, - struct drm_i915_gem_object **object_list, - struct drm_i915_gem_exec_object2 *exec_list, - int count) -{ - struct drm_i915_gem_relocation_entry *reloc; - int i, total, ret; - - for (i = 0; i < count; i++) - object_list[i]->in_execbuffer = false; - - mutex_unlock(&dev->struct_mutex); - - total = 0; - for (i = 0; i < count; i++) - total += exec_list[i].relocation_count; - - reloc = drm_malloc_ab(total, sizeof(*reloc)); - if (reloc == NULL) { - mutex_lock(&dev->struct_mutex); - return -ENOMEM; - } - - total = 0; - for (i = 0; i < count; i++) { - struct drm_i915_gem_relocation_entry __user *user_relocs; - - user_relocs = (void __user *)(uintptr_t)exec_list[i].relocs_ptr; - - if (copy_from_user(reloc+total, user_relocs, - exec_list[i].relocation_count * - sizeof(*reloc))) { - ret = -EFAULT; - mutex_lock(&dev->struct_mutex); - goto err; - } - - total += exec_list[i].relocation_count; - } - - ret = i915_mutex_lock_interruptible(dev); - if (ret) { - mutex_lock(&dev->struct_mutex); - goto err; - } - - ret = i915_gem_execbuffer_reserve(dev, file, - object_list, exec_list, - count); - if (ret) - goto err; - - total = 0; - for (i = 0; i < count; i++) { - struct drm_i915_gem_object *obj = object_list[i]; - obj->base.pending_read_domains = 0; - obj->base.pending_write_domain = 0; - ret = i915_gem_execbuffer_relocate_object_slow(obj, file, - &exec_list[i], - reloc + total); - if (ret) - goto err; - - total += exec_list[i].relocation_count; - } - - /* Leave the user relocations as are, this is the painfully slow path, - * and we want to avoid the complication of dropping the lock whilst - * having buffers reserved in the aperture and so causing spurious - * ENOSPC for random operations. - */ - -err: - drm_free_large(reloc); - return ret; -} - -static int -i915_gem_execbuffer_move_to_gpu(struct drm_device *dev, - struct drm_file *file, - struct intel_ring_buffer *ring, - struct drm_i915_gem_object **objects, - int count) -{ - struct change_domains cd; - int ret, i; - - cd.invalidate_domains = 0; - cd.flush_domains = 0; - cd.flush_rings = 0; - for (i = 0; i < count; i++) - i915_gem_object_set_to_gpu_domain(objects[i], ring, &cd); - - if (cd.invalidate_domains | cd.flush_domains) { -#if WATCH_EXEC - DRM_INFO("%s: invalidate_domains %08x flush_domains %08x\n", - __func__, - cd.invalidate_domains, - cd.flush_domains); -#endif - i915_gem_flush(dev, - cd.invalidate_domains, - cd.flush_domains, - cd.flush_rings); - } - - for (i = 0; i < count; i++) { - struct drm_i915_gem_object *obj = objects[i]; - /* XXX replace with semaphores */ - if (obj->ring && ring != obj->ring) { - ret = i915_gem_object_wait_rendering(obj, true); - if (ret) - return ret; - } - } - - return 0; -} - /* Throttle our rendering by waiting until the ring has completed our requests * emitted over 20 msec ago. * @@ -3786,473 +3115,6 @@ i915_gem_ring_throttle(struct drm_device *dev, struct drm_file *file) return ret; } -static int -i915_gem_check_execbuffer(struct drm_i915_gem_execbuffer2 *exec, - uint64_t exec_offset) -{ - uint32_t exec_start, exec_len; - - exec_start = (uint32_t) exec_offset + exec->batch_start_offset; - exec_len = (uint32_t) exec->batch_len; - - if ((exec_start | exec_len) & 0x7) - return -EINVAL; - - if (!exec_start) - return -EINVAL; - - return 0; -} - -static int -validate_exec_list(struct drm_i915_gem_exec_object2 *exec, - int count) -{ - int i; - - for (i = 0; i < count; i++) { - char __user *ptr = (char __user *)(uintptr_t)exec[i].relocs_ptr; - int length; /* limited by fault_in_pages_readable() */ - - /* First check for malicious input causing overflow */ - if (exec[i].relocation_count > - INT_MAX / sizeof(struct drm_i915_gem_relocation_entry)) - return -EINVAL; - - length = exec[i].relocation_count * - sizeof(struct drm_i915_gem_relocation_entry); - if (!access_ok(VERIFY_READ, ptr, length)) - return -EFAULT; - - /* we may also need to update the presumed offsets */ - if (!access_ok(VERIFY_WRITE, ptr, length)) - return -EFAULT; - - if (fault_in_pages_readable(ptr, length)) - return -EFAULT; - } - - return 0; -} - -static int -i915_gem_do_execbuffer(struct drm_device *dev, void *data, - struct drm_file *file, - struct drm_i915_gem_execbuffer2 *args, - struct drm_i915_gem_exec_object2 *exec_list) -{ - drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_i915_gem_object **object_list = NULL; - struct drm_i915_gem_object *batch_obj; - struct drm_clip_rect *cliprects = NULL; - struct drm_i915_gem_request *request = NULL; - int ret, i, flips; - uint64_t exec_offset; - - struct intel_ring_buffer *ring = NULL; - - ret = i915_gem_check_is_wedged(dev); - if (ret) - return ret; - - ret = validate_exec_list(exec_list, args->buffer_count); - if (ret) - return ret; - -#if WATCH_EXEC - DRM_INFO("buffers_ptr %d buffer_count %d len %08x\n", - (int) args->buffers_ptr, args->buffer_count, args->batch_len); -#endif - switch (args->flags & I915_EXEC_RING_MASK) { - case I915_EXEC_DEFAULT: - case I915_EXEC_RENDER: - ring = &dev_priv->render_ring; - break; - case I915_EXEC_BSD: - if (!HAS_BSD(dev)) { - DRM_ERROR("execbuf with invalid ring (BSD)\n"); - return -EINVAL; - } - ring = &dev_priv->bsd_ring; - break; - case I915_EXEC_BLT: - if (!HAS_BLT(dev)) { - DRM_ERROR("execbuf with invalid ring (BLT)\n"); - return -EINVAL; - } - ring = &dev_priv->blt_ring; - break; - default: - DRM_ERROR("execbuf with unknown ring: %d\n", - (int)(args->flags & I915_EXEC_RING_MASK)); - return -EINVAL; - } - - if (args->buffer_count < 1) { - DRM_ERROR("execbuf with %d buffers\n", args->buffer_count); - return -EINVAL; - } - object_list = drm_malloc_ab(sizeof(*object_list), args->buffer_count); - if (object_list == NULL) { - DRM_ERROR("Failed to allocate object list for %d buffers\n", - args->buffer_count); - ret = -ENOMEM; - goto pre_mutex_err; - } - - if (args->num_cliprects != 0) { - cliprects = kcalloc(args->num_cliprects, sizeof(*cliprects), - GFP_KERNEL); - if (cliprects == NULL) { - ret = -ENOMEM; - goto pre_mutex_err; - } - - ret = copy_from_user(cliprects, - (struct drm_clip_rect __user *) - (uintptr_t) args->cliprects_ptr, - sizeof(*cliprects) * args->num_cliprects); - if (ret != 0) { - DRM_ERROR("copy %d cliprects failed: %d\n", - args->num_cliprects, ret); - ret = -EFAULT; - goto pre_mutex_err; - } - } - - request = kzalloc(sizeof(*request), GFP_KERNEL); - if (request == NULL) { - ret = -ENOMEM; - goto pre_mutex_err; - } - - ret = i915_mutex_lock_interruptible(dev); - if (ret) - goto pre_mutex_err; - - if (dev_priv->mm.suspended) { - mutex_unlock(&dev->struct_mutex); - ret = -EBUSY; - goto pre_mutex_err; - } - - /* Look up object handles */ - for (i = 0; i < args->buffer_count; i++) { - struct drm_i915_gem_object *obj; - - obj = to_intel_bo (drm_gem_object_lookup(dev, file, - exec_list[i].handle)); - if (obj == NULL) { - DRM_ERROR("Invalid object handle %d at index %d\n", - exec_list[i].handle, i); - /* prevent error path from reading uninitialized data */ - args->buffer_count = i; - ret = -ENOENT; - goto err; - } - object_list[i] = obj; - - if (obj->in_execbuffer) { - DRM_ERROR("Object %p appears more than once in object list\n", - obj); - /* prevent error path from reading uninitialized data */ - args->buffer_count = i + 1; - ret = -EINVAL; - goto err; - } - obj->in_execbuffer = true; - obj->pending_fenced_gpu_access = false; - } - - /* Move the objects en-masse into the GTT, evicting if necessary. */ - ret = i915_gem_execbuffer_reserve(dev, file, - object_list, exec_list, - args->buffer_count); - if (ret) - goto err; - - /* The objects are in their final locations, apply the relocations. */ - ret = i915_gem_execbuffer_relocate(dev, file, - object_list, exec_list, - args->buffer_count); - if (ret) { - if (ret == -EFAULT) { - ret = i915_gem_execbuffer_relocate_slow(dev, file, - object_list, - exec_list, - args->buffer_count); - BUG_ON(!mutex_is_locked(&dev->struct_mutex)); - } - if (ret) - goto err; - } - - /* Set the pending read domains for the batch buffer to COMMAND */ - batch_obj = object_list[args->buffer_count-1]; - if (batch_obj->base.pending_write_domain) { - DRM_ERROR("Attempting to use self-modifying batch buffer\n"); - ret = -EINVAL; - goto err; - } - batch_obj->base.pending_read_domains |= I915_GEM_DOMAIN_COMMAND; - - /* Sanity check the batch buffer */ - exec_offset = batch_obj->gtt_offset; - ret = i915_gem_check_execbuffer(args, exec_offset); - if (ret != 0) { - DRM_ERROR("execbuf with invalid offset/length\n"); - goto err; - } - - ret = i915_gem_execbuffer_move_to_gpu(dev, file, ring, - object_list, args->buffer_count); - if (ret) - goto err; - -#if WATCH_COHERENCY - for (i = 0; i < args->buffer_count; i++) { - i915_gem_object_check_coherency(object_list[i], - exec_list[i].handle); - } -#endif - -#if WATCH_EXEC - i915_gem_dump_object(batch_obj, - args->batch_len, - __func__, - ~0); -#endif - - /* Check for any pending flips. As we only maintain a flip queue depth - * of 1, we can simply insert a WAIT for the next display flip prior - * to executing the batch and avoid stalling the CPU. - */ - flips = 0; - for (i = 0; i < args->buffer_count; i++) { - if (object_list[i]->base.write_domain) - flips |= atomic_read(&object_list[i]->pending_flip); - } - if (flips) { - int plane, flip_mask; - - for (plane = 0; flips >> plane; plane++) { - if (((flips >> plane) & 1) == 0) - continue; - - if (plane) - flip_mask = MI_WAIT_FOR_PLANE_B_FLIP; - else - flip_mask = MI_WAIT_FOR_PLANE_A_FLIP; - - ret = intel_ring_begin(ring, 2); - if (ret) - goto err; - - intel_ring_emit(ring, MI_WAIT_FOR_EVENT | flip_mask); - intel_ring_emit(ring, MI_NOOP); - intel_ring_advance(ring); - } - } - - /* Exec the batchbuffer */ - ret = ring->dispatch_execbuffer(ring, args, cliprects, exec_offset); - if (ret) { - DRM_ERROR("dispatch failed %d\n", ret); - goto err; - } - - for (i = 0; i < args->buffer_count; i++) { - struct drm_i915_gem_object *obj = object_list[i]; - - obj->base.read_domains = obj->base.pending_read_domains; - obj->base.write_domain = obj->base.pending_write_domain; - obj->fenced_gpu_access = obj->pending_fenced_gpu_access; - - i915_gem_object_move_to_active(obj, ring); - if (obj->base.write_domain) { - obj->dirty = 1; - list_move_tail(&obj->gpu_write_list, - &ring->gpu_write_list); - intel_mark_busy(dev, obj); - } - - trace_i915_gem_object_change_domain(obj, - obj->base.read_domains, - obj->base.write_domain); - } - - /* - * Ensure that the commands in the batch buffer are - * finished before the interrupt fires - */ - i915_retire_commands(dev, ring); - - if (i915_add_request(dev, file, request, ring)) - i915_gem_next_request_seqno(dev, ring); - else - request = NULL; - -err: - for (i = 0; i < args->buffer_count; i++) { - object_list[i]->in_execbuffer = false; - drm_gem_object_unreference(&object_list[i]->base); - } - - mutex_unlock(&dev->struct_mutex); - -pre_mutex_err: - drm_free_large(object_list); - kfree(cliprects); - kfree(request); - - return ret; -} - -/* - * Legacy execbuffer just creates an exec2 list from the original exec object - * list array and passes it to the real function. - */ -int -i915_gem_execbuffer(struct drm_device *dev, void *data, - struct drm_file *file) -{ - struct drm_i915_gem_execbuffer *args = data; - struct drm_i915_gem_execbuffer2 exec2; - struct drm_i915_gem_exec_object *exec_list = NULL; - struct drm_i915_gem_exec_object2 *exec2_list = NULL; - int ret, i; - -#if WATCH_EXEC - DRM_INFO("buffers_ptr %d buffer_count %d len %08x\n", - (int) args->buffers_ptr, args->buffer_count, args->batch_len); -#endif - - if (args->buffer_count < 1) { - DRM_ERROR("execbuf with %d buffers\n", args->buffer_count); - return -EINVAL; - } - - /* Copy in the exec list from userland */ - exec_list = drm_malloc_ab(sizeof(*exec_list), args->buffer_count); - exec2_list = drm_malloc_ab(sizeof(*exec2_list), args->buffer_count); - if (exec_list == NULL || exec2_list == NULL) { - DRM_ERROR("Failed to allocate exec list for %d buffers\n", - args->buffer_count); - drm_free_large(exec_list); - drm_free_large(exec2_list); - return -ENOMEM; - } - ret = copy_from_user(exec_list, - (struct drm_i915_relocation_entry __user *) - (uintptr_t) args->buffers_ptr, - sizeof(*exec_list) * args->buffer_count); - if (ret != 0) { - DRM_ERROR("copy %d exec entries failed %d\n", - args->buffer_count, ret); - drm_free_large(exec_list); - drm_free_large(exec2_list); - return -EFAULT; - } - - for (i = 0; i < args->buffer_count; i++) { - exec2_list[i].handle = exec_list[i].handle; - exec2_list[i].relocation_count = exec_list[i].relocation_count; - exec2_list[i].relocs_ptr = exec_list[i].relocs_ptr; - exec2_list[i].alignment = exec_list[i].alignment; - exec2_list[i].offset = exec_list[i].offset; - if (INTEL_INFO(dev)->gen < 4) - exec2_list[i].flags = EXEC_OBJECT_NEEDS_FENCE; - else - exec2_list[i].flags = 0; - } - - exec2.buffers_ptr = args->buffers_ptr; - exec2.buffer_count = args->buffer_count; - exec2.batch_start_offset = args->batch_start_offset; - exec2.batch_len = args->batch_len; - exec2.DR1 = args->DR1; - exec2.DR4 = args->DR4; - exec2.num_cliprects = args->num_cliprects; - exec2.cliprects_ptr = args->cliprects_ptr; - exec2.flags = I915_EXEC_RENDER; - - ret = i915_gem_do_execbuffer(dev, data, file, &exec2, exec2_list); - if (!ret) { - /* Copy the new buffer offsets back to the user's exec list. */ - for (i = 0; i < args->buffer_count; i++) - exec_list[i].offset = exec2_list[i].offset; - /* ... and back out to userspace */ - ret = copy_to_user((struct drm_i915_relocation_entry __user *) - (uintptr_t) args->buffers_ptr, - exec_list, - sizeof(*exec_list) * args->buffer_count); - if (ret) { - ret = -EFAULT; - DRM_ERROR("failed to copy %d exec entries " - "back to user (%d)\n", - args->buffer_count, ret); - } - } - - drm_free_large(exec_list); - drm_free_large(exec2_list); - return ret; -} - -int -i915_gem_execbuffer2(struct drm_device *dev, void *data, - struct drm_file *file) -{ - struct drm_i915_gem_execbuffer2 *args = data; - struct drm_i915_gem_exec_object2 *exec2_list = NULL; - int ret; - -#if WATCH_EXEC - DRM_INFO("buffers_ptr %d buffer_count %d len %08x\n", - (int) args->buffers_ptr, args->buffer_count, args->batch_len); -#endif - - if (args->buffer_count < 1) { - DRM_ERROR("execbuf2 with %d buffers\n", args->buffer_count); - return -EINVAL; - } - - exec2_list = drm_malloc_ab(sizeof(*exec2_list), args->buffer_count); - if (exec2_list == NULL) { - DRM_ERROR("Failed to allocate exec list for %d buffers\n", - args->buffer_count); - return -ENOMEM; - } - ret = copy_from_user(exec2_list, - (struct drm_i915_relocation_entry __user *) - (uintptr_t) args->buffers_ptr, - sizeof(*exec2_list) * args->buffer_count); - if (ret != 0) { - DRM_ERROR("copy %d exec entries failed %d\n", - args->buffer_count, ret); - drm_free_large(exec2_list); - return -EFAULT; - } - - ret = i915_gem_do_execbuffer(dev, data, file, args, exec2_list); - if (!ret) { - /* Copy the new buffer offsets back to the user's exec list. */ - ret = copy_to_user((struct drm_i915_relocation_entry __user *) - (uintptr_t) args->buffers_ptr, - exec2_list, - sizeof(*exec2_list) * args->buffer_count); - if (ret) { - ret = -EFAULT; - DRM_ERROR("failed to copy %d exec entries " - "back to user (%d)\n", - args->buffer_count, ret); - } - } - - drm_free_large(exec2_list); - return ret; -} - int i915_gem_object_pin(struct drm_i915_gem_object *obj, uint32_t alignment, diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c new file mode 100644 index 000000000000..bdc613b91af8 --- /dev/null +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c @@ -0,0 +1,1155 @@ +/* + * Copyright © 2008,2010 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + * + * Authors: + * Eric Anholt + * Chris Wilson + * + */ + +#include "drmP.h" +#include "drm.h" +#include "i915_drm.h" +#include "i915_drv.h" +#include "i915_trace.h" +#include "intel_drv.h" + +struct change_domains { + uint32_t invalidate_domains; + uint32_t flush_domains; + uint32_t flush_rings; +}; + +/* + * Set the next domain for the specified object. This + * may not actually perform the necessary flushing/invaliding though, + * as that may want to be batched with other set_domain operations + * + * This is (we hope) the only really tricky part of gem. The goal + * is fairly simple -- track which caches hold bits of the object + * and make sure they remain coherent. A few concrete examples may + * help to explain how it works. For shorthand, we use the notation + * (read_domains, write_domain), e.g. (CPU, CPU) to indicate the + * a pair of read and write domain masks. + * + * Case 1: the batch buffer + * + * 1. Allocated + * 2. Written by CPU + * 3. Mapped to GTT + * 4. Read by GPU + * 5. Unmapped from GTT + * 6. Freed + * + * Let's take these a step at a time + * + * 1. Allocated + * Pages allocated from the kernel may still have + * cache contents, so we set them to (CPU, CPU) always. + * 2. Written by CPU (using pwrite) + * The pwrite function calls set_domain (CPU, CPU) and + * this function does nothing (as nothing changes) + * 3. Mapped by GTT + * This function asserts that the object is not + * currently in any GPU-based read or write domains + * 4. Read by GPU + * i915_gem_execbuffer calls set_domain (COMMAND, 0). + * As write_domain is zero, this function adds in the + * current read domains (CPU+COMMAND, 0). + * flush_domains is set to CPU. + * invalidate_domains is set to COMMAND + * clflush is run to get data out of the CPU caches + * then i915_dev_set_domain calls i915_gem_flush to + * emit an MI_FLUSH and drm_agp_chipset_flush + * 5. Unmapped from GTT + * i915_gem_object_unbind calls set_domain (CPU, CPU) + * flush_domains and invalidate_domains end up both zero + * so no flushing/invalidating happens + * 6. Freed + * yay, done + * + * Case 2: The shared render buffer + * + * 1. Allocated + * 2. Mapped to GTT + * 3. Read/written by GPU + * 4. set_domain to (CPU,CPU) + * 5. Read/written by CPU + * 6. Read/written by GPU + * + * 1. Allocated + * Same as last example, (CPU, CPU) + * 2. Mapped to GTT + * Nothing changes (assertions find that it is not in the GPU) + * 3. Read/written by GPU + * execbuffer calls set_domain (RENDER, RENDER) + * flush_domains gets CPU + * invalidate_domains gets GPU + * clflush (obj) + * MI_FLUSH and drm_agp_chipset_flush + * 4. set_domain (CPU, CPU) + * flush_domains gets GPU + * invalidate_domains gets CPU + * wait_rendering (obj) to make sure all drawing is complete. + * This will include an MI_FLUSH to get the data from GPU + * to memory + * clflush (obj) to invalidate the CPU cache + * Another MI_FLUSH in i915_gem_flush (eliminate this somehow?) + * 5. Read/written by CPU + * cache lines are loaded and dirtied + * 6. Read written by GPU + * Same as last GPU access + * + * Case 3: The constant buffer + * + * 1. Allocated + * 2. Written by CPU + * 3. Read by GPU + * 4. Updated (written) by CPU again + * 5. Read by GPU + * + * 1. Allocated + * (CPU, CPU) + * 2. Written by CPU + * (CPU, CPU) + * 3. Read by GPU + * (CPU+RENDER, 0) + * flush_domains = CPU + * invalidate_domains = RENDER + * clflush (obj) + * MI_FLUSH + * drm_agp_chipset_flush + * 4. Updated (written) by CPU again + * (CPU, CPU) + * flush_domains = 0 (no previous write domain) + * invalidate_domains = 0 (no new read domains) + * 5. Read by GPU + * (CPU+RENDER, 0) + * flush_domains = CPU + * invalidate_domains = RENDER + * clflush (obj) + * MI_FLUSH + * drm_agp_chipset_flush + */ +static void +i915_gem_object_set_to_gpu_domain(struct drm_i915_gem_object *obj, + struct intel_ring_buffer *ring, + struct change_domains *cd) +{ + uint32_t invalidate_domains = 0, flush_domains = 0; + + /* + * If the object isn't moving to a new write domain, + * let the object stay in multiple read domains + */ + if (obj->base.pending_write_domain == 0) + obj->base.pending_read_domains |= obj->base.read_domains; + + /* + * Flush the current write domain if + * the new read domains don't match. Invalidate + * any read domains which differ from the old + * write domain + */ + if (obj->base.write_domain && + (((obj->base.write_domain != obj->base.pending_read_domains || + obj->ring != ring)) || + (obj->fenced_gpu_access && !obj->pending_fenced_gpu_access))) { + flush_domains |= obj->base.write_domain; + invalidate_domains |= + obj->base.pending_read_domains & ~obj->base.write_domain; + } + /* + * Invalidate any read caches which may have + * stale data. That is, any new read domains. + */ + invalidate_domains |= obj->base.pending_read_domains & ~obj->base.read_domains; + if ((flush_domains | invalidate_domains) & I915_GEM_DOMAIN_CPU) + i915_gem_clflush_object(obj); + + /* blow away mappings if mapped through GTT */ + if ((flush_domains | invalidate_domains) & I915_GEM_DOMAIN_GTT) + i915_gem_release_mmap(obj); + + /* The actual obj->write_domain will be updated with + * pending_write_domain after we emit the accumulated flush for all + * of our domain changes in execbuffers (which clears objects' + * write_domains). So if we have a current write domain that we + * aren't changing, set pending_write_domain to that. + */ + if (flush_domains == 0 && obj->base.pending_write_domain == 0) + obj->base.pending_write_domain = obj->base.write_domain; + + cd->invalidate_domains |= invalidate_domains; + cd->flush_domains |= flush_domains; + if (flush_domains & I915_GEM_GPU_DOMAINS) + cd->flush_rings |= obj->ring->id; + if (invalidate_domains & I915_GEM_GPU_DOMAINS) + cd->flush_rings |= ring->id; +} + +static int +i915_gem_execbuffer_relocate_entry(struct drm_i915_gem_object *obj, + struct drm_file *file_priv, + struct drm_i915_gem_exec_object2 *entry, + struct drm_i915_gem_relocation_entry *reloc) +{ + struct drm_device *dev = obj->base.dev; + struct drm_gem_object *target_obj; + uint32_t target_offset; + int ret = -EINVAL; + + target_obj = drm_gem_object_lookup(dev, file_priv, + reloc->target_handle); + if (target_obj == NULL) + return -ENOENT; + + target_offset = to_intel_bo(target_obj)->gtt_offset; + +#if WATCH_RELOC + DRM_INFO("%s: obj %p offset %08x target %d " + "read %08x write %08x gtt %08x " + "presumed %08x delta %08x\n", + __func__, + obj, + (int) reloc->offset, + (int) reloc->target_handle, + (int) reloc->read_domains, + (int) reloc->write_domain, + (int) target_offset, + (int) reloc->presumed_offset, + reloc->delta); +#endif + + /* The target buffer should have appeared before us in the + * exec_object list, so it should have a GTT space bound by now. + */ + if (target_offset == 0) { + DRM_ERROR("No GTT space found for object %d\n", + reloc->target_handle); + goto err; + } + + /* Validate that the target is in a valid r/w GPU domain */ + if (reloc->write_domain & (reloc->write_domain - 1)) { + DRM_ERROR("reloc with multiple write domains: " + "obj %p target %d offset %d " + "read %08x write %08x", + obj, reloc->target_handle, + (int) reloc->offset, + reloc->read_domains, + reloc->write_domain); + goto err; + } + if (reloc->write_domain & I915_GEM_DOMAIN_CPU || + reloc->read_domains & I915_GEM_DOMAIN_CPU) { + DRM_ERROR("reloc with read/write CPU domains: " + "obj %p target %d offset %d " + "read %08x write %08x", + obj, reloc->target_handle, + (int) reloc->offset, + reloc->read_domains, + reloc->write_domain); + goto err; + } + if (reloc->write_domain && target_obj->pending_write_domain && + reloc->write_domain != target_obj->pending_write_domain) { + DRM_ERROR("Write domain conflict: " + "obj %p target %d offset %d " + "new %08x old %08x\n", + obj, reloc->target_handle, + (int) reloc->offset, + reloc->write_domain, + target_obj->pending_write_domain); + goto err; + } + + target_obj->pending_read_domains |= reloc->read_domains; + target_obj->pending_write_domain |= reloc->write_domain; + + /* If the relocation already has the right value in it, no + * more work needs to be done. + */ + if (target_offset == reloc->presumed_offset) + goto out; + + /* Check that the relocation address is valid... */ + if (reloc->offset > obj->base.size - 4) { + DRM_ERROR("Relocation beyond object bounds: " + "obj %p target %d offset %d size %d.\n", + obj, reloc->target_handle, + (int) reloc->offset, + (int) obj->base.size); + goto err; + } + if (reloc->offset & 3) { + DRM_ERROR("Relocation not 4-byte aligned: " + "obj %p target %d offset %d.\n", + obj, reloc->target_handle, + (int) reloc->offset); + goto err; + } + + /* and points to somewhere within the target object. */ + if (reloc->delta >= target_obj->size) { + DRM_ERROR("Relocation beyond target object bounds: " + "obj %p target %d delta %d size %d.\n", + obj, reloc->target_handle, + (int) reloc->delta, + (int) target_obj->size); + goto err; + } + + reloc->delta += target_offset; + if (obj->base.write_domain == I915_GEM_DOMAIN_CPU) { + uint32_t page_offset = reloc->offset & ~PAGE_MASK; + char *vaddr; + + vaddr = kmap_atomic(obj->pages[reloc->offset >> PAGE_SHIFT]); + *(uint32_t *)(vaddr + page_offset) = reloc->delta; + kunmap_atomic(vaddr); + } else { + struct drm_i915_private *dev_priv = dev->dev_private; + uint32_t __iomem *reloc_entry; + void __iomem *reloc_page; + + ret = i915_gem_object_set_to_gtt_domain(obj, 1); + if (ret) + goto err; + + /* Map the page containing the relocation we're going to perform. */ + reloc->offset += obj->gtt_offset; + reloc_page = io_mapping_map_atomic_wc(dev_priv->mm.gtt_mapping, + reloc->offset & PAGE_MASK); + reloc_entry = (uint32_t __iomem *) + (reloc_page + (reloc->offset & ~PAGE_MASK)); + iowrite32(reloc->delta, reloc_entry); + io_mapping_unmap_atomic(reloc_page); + } + + /* and update the user's relocation entry */ + reloc->presumed_offset = target_offset; + +out: + ret = 0; +err: + drm_gem_object_unreference(target_obj); + return ret; +} + +static int +i915_gem_execbuffer_relocate_object(struct drm_i915_gem_object *obj, + struct drm_file *file_priv, + struct drm_i915_gem_exec_object2 *entry) +{ + struct drm_i915_gem_relocation_entry __user *user_relocs; + int i, ret; + + user_relocs = (void __user *)(uintptr_t)entry->relocs_ptr; + for (i = 0; i < entry->relocation_count; i++) { + struct drm_i915_gem_relocation_entry reloc; + + if (__copy_from_user_inatomic(&reloc, + user_relocs+i, + sizeof(reloc))) + return -EFAULT; + + ret = i915_gem_execbuffer_relocate_entry(obj, file_priv, entry, &reloc); + if (ret) + return ret; + + if (__copy_to_user_inatomic(&user_relocs[i].presumed_offset, + &reloc.presumed_offset, + sizeof(reloc.presumed_offset))) + return -EFAULT; + } + + return 0; +} + +static int +i915_gem_execbuffer_relocate_object_slow(struct drm_i915_gem_object *obj, + struct drm_file *file_priv, + struct drm_i915_gem_exec_object2 *entry, + struct drm_i915_gem_relocation_entry *relocs) +{ + int i, ret; + + for (i = 0; i < entry->relocation_count; i++) { + ret = i915_gem_execbuffer_relocate_entry(obj, file_priv, entry, &relocs[i]); + if (ret) + return ret; + } + + return 0; +} + +static int +i915_gem_execbuffer_relocate(struct drm_device *dev, + struct drm_file *file, + struct drm_i915_gem_object **object_list, + struct drm_i915_gem_exec_object2 *exec_list, + int count) +{ + int i, ret; + + for (i = 0; i < count; i++) { + struct drm_i915_gem_object *obj = object_list[i]; + obj->base.pending_read_domains = 0; + obj->base.pending_write_domain = 0; + ret = i915_gem_execbuffer_relocate_object(obj, file, + &exec_list[i]); + if (ret) + return ret; + } + + return 0; +} + +static int +i915_gem_execbuffer_reserve(struct drm_device *dev, + struct drm_file *file, + struct drm_i915_gem_object **object_list, + struct drm_i915_gem_exec_object2 *exec_list, + int count) +{ + int ret, i, retry; + + /* Attempt to pin all of the buffers into the GTT. + * This is done in 3 phases: + * + * 1a. Unbind all objects that do not match the GTT constraints for + * the execbuffer (fenceable, mappable, alignment etc). + * 1b. Increment pin count for already bound objects. + * 2. Bind new objects. + * 3. Decrement pin count. + * + * This avoid unnecessary unbinding of later objects in order to makr + * room for the earlier objects *unless* we need to defragment. + */ + retry = 0; + do { + ret = 0; + + /* Unbind any ill-fitting objects or pin. */ + for (i = 0; i < count; i++) { + struct drm_i915_gem_object *obj = object_list[i]; + struct drm_i915_gem_exec_object2 *entry = &exec_list[i]; + bool need_fence, need_mappable; + + if (!obj->gtt_space) + continue; + + need_fence = + entry->flags & EXEC_OBJECT_NEEDS_FENCE && + obj->tiling_mode != I915_TILING_NONE; + need_mappable = + entry->relocation_count ? true : need_fence; + + if ((entry->alignment && obj->gtt_offset & (entry->alignment - 1)) || + (need_mappable && !obj->map_and_fenceable)) + ret = i915_gem_object_unbind(obj); + else + ret = i915_gem_object_pin(obj, + entry->alignment, + need_mappable); + if (ret) { + count = i; + goto err; + } + } + + /* Bind fresh objects */ + for (i = 0; i < count; i++) { + struct drm_i915_gem_exec_object2 *entry = &exec_list[i]; + struct drm_i915_gem_object *obj = object_list[i]; + bool need_fence; + + need_fence = + entry->flags & EXEC_OBJECT_NEEDS_FENCE && + obj->tiling_mode != I915_TILING_NONE; + + if (!obj->gtt_space) { + bool need_mappable = + entry->relocation_count ? true : need_fence; + + ret = i915_gem_object_pin(obj, + entry->alignment, + need_mappable); + if (ret) + break; + } + + if (need_fence) { + ret = i915_gem_object_get_fence_reg(obj, true); + if (ret) + break; + + obj->pending_fenced_gpu_access = true; + } + + entry->offset = obj->gtt_offset; + } + +err: /* Decrement pin count for bound objects */ + for (i = 0; i < count; i++) { + struct drm_i915_gem_object *obj = object_list[i]; + if (obj->gtt_space) + i915_gem_object_unpin(obj); + } + + if (ret != -ENOSPC || retry > 1) + return ret; + + /* First attempt, just clear anything that is purgeable. + * Second attempt, clear the entire GTT. + */ + ret = i915_gem_evict_everything(dev, retry == 0); + if (ret) + return ret; + + retry++; + } while (1); +} + +static int +i915_gem_execbuffer_relocate_slow(struct drm_device *dev, + struct drm_file *file, + struct drm_i915_gem_object **object_list, + struct drm_i915_gem_exec_object2 *exec_list, + int count) +{ + struct drm_i915_gem_relocation_entry *reloc; + int i, total, ret; + + for (i = 0; i < count; i++) + object_list[i]->in_execbuffer = false; + + mutex_unlock(&dev->struct_mutex); + + total = 0; + for (i = 0; i < count; i++) + total += exec_list[i].relocation_count; + + reloc = drm_malloc_ab(total, sizeof(*reloc)); + if (reloc == NULL) { + mutex_lock(&dev->struct_mutex); + return -ENOMEM; + } + + total = 0; + for (i = 0; i < count; i++) { + struct drm_i915_gem_relocation_entry __user *user_relocs; + + user_relocs = (void __user *)(uintptr_t)exec_list[i].relocs_ptr; + + if (copy_from_user(reloc+total, user_relocs, + exec_list[i].relocation_count * + sizeof(*reloc))) { + ret = -EFAULT; + mutex_lock(&dev->struct_mutex); + goto err; + } + + total += exec_list[i].relocation_count; + } + + ret = i915_mutex_lock_interruptible(dev); + if (ret) { + mutex_lock(&dev->struct_mutex); + goto err; + } + + ret = i915_gem_execbuffer_reserve(dev, file, + object_list, exec_list, + count); + if (ret) + goto err; + + total = 0; + for (i = 0; i < count; i++) { + struct drm_i915_gem_object *obj = object_list[i]; + obj->base.pending_read_domains = 0; + obj->base.pending_write_domain = 0; + ret = i915_gem_execbuffer_relocate_object_slow(obj, file, + &exec_list[i], + reloc + total); + if (ret) + goto err; + + total += exec_list[i].relocation_count; + } + + /* Leave the user relocations as are, this is the painfully slow path, + * and we want to avoid the complication of dropping the lock whilst + * having buffers reserved in the aperture and so causing spurious + * ENOSPC for random operations. + */ + +err: + drm_free_large(reloc); + return ret; +} + +static void +i915_gem_execbuffer_flush(struct drm_device *dev, + uint32_t invalidate_domains, + uint32_t flush_domains, + uint32_t flush_rings) +{ + drm_i915_private_t *dev_priv = dev->dev_private; + + if (flush_domains & I915_GEM_DOMAIN_CPU) + intel_gtt_chipset_flush(); + + if ((flush_domains | invalidate_domains) & I915_GEM_GPU_DOMAINS) { + if (flush_rings & RING_RENDER) + i915_gem_flush_ring(dev, &dev_priv->render_ring, + invalidate_domains, flush_domains); + if (flush_rings & RING_BSD) + i915_gem_flush_ring(dev, &dev_priv->bsd_ring, + invalidate_domains, flush_domains); + if (flush_rings & RING_BLT) + i915_gem_flush_ring(dev, &dev_priv->blt_ring, + invalidate_domains, flush_domains); + } +} + + +static int +i915_gem_execbuffer_move_to_gpu(struct drm_device *dev, + struct drm_file *file, + struct intel_ring_buffer *ring, + struct drm_i915_gem_object **objects, + int count) +{ + struct change_domains cd; + int ret, i; + + cd.invalidate_domains = 0; + cd.flush_domains = 0; + cd.flush_rings = 0; + for (i = 0; i < count; i++) + i915_gem_object_set_to_gpu_domain(objects[i], ring, &cd); + + if (cd.invalidate_domains | cd.flush_domains) { +#if WATCH_EXEC + DRM_INFO("%s: invalidate_domains %08x flush_domains %08x\n", + __func__, + cd.invalidate_domains, + cd.flush_domains); +#endif + i915_gem_execbuffer_flush(dev, + cd.invalidate_domains, + cd.flush_domains, + cd.flush_rings); + } + + for (i = 0; i < count; i++) { + struct drm_i915_gem_object *obj = objects[i]; + /* XXX replace with semaphores */ + if (obj->ring && ring != obj->ring) { + ret = i915_gem_object_wait_rendering(obj, true); + if (ret) + return ret; + } + } + + return 0; +} + +static int +i915_gem_check_execbuffer(struct drm_i915_gem_execbuffer2 *exec, + uint64_t exec_offset) +{ + uint32_t exec_start, exec_len; + + exec_start = (uint32_t) exec_offset + exec->batch_start_offset; + exec_len = (uint32_t) exec->batch_len; + + if ((exec_start | exec_len) & 0x7) + return -EINVAL; + + if (!exec_start) + return -EINVAL; + + return 0; +} + +static int +validate_exec_list(struct drm_i915_gem_exec_object2 *exec, + int count) +{ + int i; + + for (i = 0; i < count; i++) { + char __user *ptr = (char __user *)(uintptr_t)exec[i].relocs_ptr; + int length; /* limited by fault_in_pages_readable() */ + + /* First check for malicious input causing overflow */ + if (exec[i].relocation_count > + INT_MAX / sizeof(struct drm_i915_gem_relocation_entry)) + return -EINVAL; + + length = exec[i].relocation_count * + sizeof(struct drm_i915_gem_relocation_entry); + if (!access_ok(VERIFY_READ, ptr, length)) + return -EFAULT; + + /* we may also need to update the presumed offsets */ + if (!access_ok(VERIFY_WRITE, ptr, length)) + return -EFAULT; + + if (fault_in_pages_readable(ptr, length)) + return -EFAULT; + } + + return 0; +} + +static void +i915_gem_execbuffer_retire_commands(struct drm_device *dev, + struct intel_ring_buffer *ring) +{ + uint32_t flush_domains = 0; + + /* The sampler always gets flushed on i965 (sigh) */ + if (INTEL_INFO(dev)->gen >= 4) + flush_domains |= I915_GEM_DOMAIN_SAMPLER; + + ring->flush(ring, I915_GEM_DOMAIN_COMMAND, flush_domains); +} + + +static int +i915_gem_do_execbuffer(struct drm_device *dev, void *data, + struct drm_file *file, + struct drm_i915_gem_execbuffer2 *args, + struct drm_i915_gem_exec_object2 *exec_list) +{ + drm_i915_private_t *dev_priv = dev->dev_private; + struct drm_i915_gem_object **object_list = NULL; + struct drm_i915_gem_object *batch_obj; + struct drm_clip_rect *cliprects = NULL; + struct drm_i915_gem_request *request = NULL; + struct intel_ring_buffer *ring; + int ret, i, flips; + uint64_t exec_offset; + + ret = validate_exec_list(exec_list, args->buffer_count); + if (ret) + return ret; + +#if WATCH_EXEC + DRM_INFO("buffers_ptr %d buffer_count %d len %08x\n", + (int) args->buffers_ptr, args->buffer_count, args->batch_len); +#endif + switch (args->flags & I915_EXEC_RING_MASK) { + case I915_EXEC_DEFAULT: + case I915_EXEC_RENDER: + ring = &dev_priv->render_ring; + break; + case I915_EXEC_BSD: + if (!HAS_BSD(dev)) { + DRM_ERROR("execbuf with invalid ring (BSD)\n"); + return -EINVAL; + } + ring = &dev_priv->bsd_ring; + break; + case I915_EXEC_BLT: + if (!HAS_BLT(dev)) { + DRM_ERROR("execbuf with invalid ring (BLT)\n"); + return -EINVAL; + } + ring = &dev_priv->blt_ring; + break; + default: + DRM_ERROR("execbuf with unknown ring: %d\n", + (int)(args->flags & I915_EXEC_RING_MASK)); + return -EINVAL; + } + + if (args->buffer_count < 1) { + DRM_ERROR("execbuf with %d buffers\n", args->buffer_count); + return -EINVAL; + } + object_list = drm_malloc_ab(sizeof(*object_list), args->buffer_count); + if (object_list == NULL) { + DRM_ERROR("Failed to allocate object list for %d buffers\n", + args->buffer_count); + ret = -ENOMEM; + goto pre_mutex_err; + } + + if (args->num_cliprects != 0) { + cliprects = kcalloc(args->num_cliprects, sizeof(*cliprects), + GFP_KERNEL); + if (cliprects == NULL) { + ret = -ENOMEM; + goto pre_mutex_err; + } + + ret = copy_from_user(cliprects, + (struct drm_clip_rect __user *) + (uintptr_t) args->cliprects_ptr, + sizeof(*cliprects) * args->num_cliprects); + if (ret != 0) { + DRM_ERROR("copy %d cliprects failed: %d\n", + args->num_cliprects, ret); + ret = -EFAULT; + goto pre_mutex_err; + } + } + + request = kzalloc(sizeof(*request), GFP_KERNEL); + if (request == NULL) { + ret = -ENOMEM; + goto pre_mutex_err; + } + + ret = i915_mutex_lock_interruptible(dev); + if (ret) + goto pre_mutex_err; + + if (dev_priv->mm.suspended) { + mutex_unlock(&dev->struct_mutex); + ret = -EBUSY; + goto pre_mutex_err; + } + + /* Look up object handles */ + for (i = 0; i < args->buffer_count; i++) { + struct drm_i915_gem_object *obj; + + obj = to_intel_bo (drm_gem_object_lookup(dev, file, + exec_list[i].handle)); + if (obj == NULL) { + DRM_ERROR("Invalid object handle %d at index %d\n", + exec_list[i].handle, i); + /* prevent error path from reading uninitialized data */ + args->buffer_count = i; + ret = -ENOENT; + goto err; + } + object_list[i] = obj; + + if (obj->in_execbuffer) { + DRM_ERROR("Object %p appears more than once in object list\n", + obj); + /* prevent error path from reading uninitialized data */ + args->buffer_count = i + 1; + ret = -EINVAL; + goto err; + } + obj->in_execbuffer = true; + obj->pending_fenced_gpu_access = false; + } + + /* Move the objects en-masse into the GTT, evicting if necessary. */ + ret = i915_gem_execbuffer_reserve(dev, file, + object_list, exec_list, + args->buffer_count); + if (ret) + goto err; + + /* The objects are in their final locations, apply the relocations. */ + ret = i915_gem_execbuffer_relocate(dev, file, + object_list, exec_list, + args->buffer_count); + if (ret) { + if (ret == -EFAULT) { + ret = i915_gem_execbuffer_relocate_slow(dev, file, + object_list, + exec_list, + args->buffer_count); + BUG_ON(!mutex_is_locked(&dev->struct_mutex)); + } + if (ret) + goto err; + } + + /* Set the pending read domains for the batch buffer to COMMAND */ + batch_obj = object_list[args->buffer_count-1]; + if (batch_obj->base.pending_write_domain) { + DRM_ERROR("Attempting to use self-modifying batch buffer\n"); + ret = -EINVAL; + goto err; + } + batch_obj->base.pending_read_domains |= I915_GEM_DOMAIN_COMMAND; + + /* Sanity check the batch buffer */ + exec_offset = batch_obj->gtt_offset; + ret = i915_gem_check_execbuffer(args, exec_offset); + if (ret != 0) { + DRM_ERROR("execbuf with invalid offset/length\n"); + goto err; + } + + ret = i915_gem_execbuffer_move_to_gpu(dev, file, ring, + object_list, args->buffer_count); + if (ret) + goto err; + +#if WATCH_COHERENCY + for (i = 0; i < args->buffer_count; i++) { + i915_gem_object_check_coherency(object_list[i], + exec_list[i].handle); + } +#endif + +#if WATCH_EXEC + i915_gem_dump_object(batch_obj, + args->batch_len, + __func__, + ~0); +#endif + + /* Check for any pending flips. As we only maintain a flip queue depth + * of 1, we can simply insert a WAIT for the next display flip prior + * to executing the batch and avoid stalling the CPU. + */ + flips = 0; + for (i = 0; i < args->buffer_count; i++) { + if (object_list[i]->base.write_domain) + flips |= atomic_read(&object_list[i]->pending_flip); + } + if (flips) { + int plane, flip_mask; + + for (plane = 0; flips >> plane; plane++) { + if (((flips >> plane) & 1) == 0) + continue; + + if (plane) + flip_mask = MI_WAIT_FOR_PLANE_B_FLIP; + else + flip_mask = MI_WAIT_FOR_PLANE_A_FLIP; + + ret = intel_ring_begin(ring, 2); + if (ret) + goto err; + + intel_ring_emit(ring, MI_WAIT_FOR_EVENT | flip_mask); + intel_ring_emit(ring, MI_NOOP); + intel_ring_advance(ring); + } + } + + /* Exec the batchbuffer */ + ret = ring->dispatch_execbuffer(ring, args, cliprects, exec_offset); + if (ret) { + DRM_ERROR("dispatch failed %d\n", ret); + goto err; + } + + for (i = 0; i < args->buffer_count; i++) { + struct drm_i915_gem_object *obj = object_list[i]; + + obj->base.read_domains = obj->base.pending_read_domains; + obj->base.write_domain = obj->base.pending_write_domain; + obj->fenced_gpu_access = obj->pending_fenced_gpu_access; + + i915_gem_object_move_to_active(obj, ring); + if (obj->base.write_domain) { + obj->dirty = 1; + list_move_tail(&obj->gpu_write_list, + &ring->gpu_write_list); + intel_mark_busy(dev, obj); + } + + trace_i915_gem_object_change_domain(obj, + obj->base.read_domains, + obj->base.write_domain); + } + + /* + * Ensure that the commands in the batch buffer are + * finished before the interrupt fires + */ + i915_gem_execbuffer_retire_commands(dev, ring); + + if (i915_add_request(dev, file, request, ring)) + i915_gem_next_request_seqno(dev, ring); + else + request = NULL; + +err: + for (i = 0; i < args->buffer_count; i++) { + object_list[i]->in_execbuffer = false; + drm_gem_object_unreference(&object_list[i]->base); + } + + mutex_unlock(&dev->struct_mutex); + +pre_mutex_err: + drm_free_large(object_list); + kfree(cliprects); + kfree(request); + + return ret; +} + +/* + * Legacy execbuffer just creates an exec2 list from the original exec object + * list array and passes it to the real function. + */ +int +i915_gem_execbuffer(struct drm_device *dev, void *data, + struct drm_file *file) +{ + struct drm_i915_gem_execbuffer *args = data; + struct drm_i915_gem_execbuffer2 exec2; + struct drm_i915_gem_exec_object *exec_list = NULL; + struct drm_i915_gem_exec_object2 *exec2_list = NULL; + int ret, i; + +#if WATCH_EXEC + DRM_INFO("buffers_ptr %d buffer_count %d len %08x\n", + (int) args->buffers_ptr, args->buffer_count, args->batch_len); +#endif + + if (args->buffer_count < 1) { + DRM_ERROR("execbuf with %d buffers\n", args->buffer_count); + return -EINVAL; + } + + /* Copy in the exec list from userland */ + exec_list = drm_malloc_ab(sizeof(*exec_list), args->buffer_count); + exec2_list = drm_malloc_ab(sizeof(*exec2_list), args->buffer_count); + if (exec_list == NULL || exec2_list == NULL) { + DRM_ERROR("Failed to allocate exec list for %d buffers\n", + args->buffer_count); + drm_free_large(exec_list); + drm_free_large(exec2_list); + return -ENOMEM; + } + ret = copy_from_user(exec_list, + (struct drm_i915_relocation_entry __user *) + (uintptr_t) args->buffers_ptr, + sizeof(*exec_list) * args->buffer_count); + if (ret != 0) { + DRM_ERROR("copy %d exec entries failed %d\n", + args->buffer_count, ret); + drm_free_large(exec_list); + drm_free_large(exec2_list); + return -EFAULT; + } + + for (i = 0; i < args->buffer_count; i++) { + exec2_list[i].handle = exec_list[i].handle; + exec2_list[i].relocation_count = exec_list[i].relocation_count; + exec2_list[i].relocs_ptr = exec_list[i].relocs_ptr; + exec2_list[i].alignment = exec_list[i].alignment; + exec2_list[i].offset = exec_list[i].offset; + if (INTEL_INFO(dev)->gen < 4) + exec2_list[i].flags = EXEC_OBJECT_NEEDS_FENCE; + else + exec2_list[i].flags = 0; + } + + exec2.buffers_ptr = args->buffers_ptr; + exec2.buffer_count = args->buffer_count; + exec2.batch_start_offset = args->batch_start_offset; + exec2.batch_len = args->batch_len; + exec2.DR1 = args->DR1; + exec2.DR4 = args->DR4; + exec2.num_cliprects = args->num_cliprects; + exec2.cliprects_ptr = args->cliprects_ptr; + exec2.flags = I915_EXEC_RENDER; + + ret = i915_gem_do_execbuffer(dev, data, file, &exec2, exec2_list); + if (!ret) { + /* Copy the new buffer offsets back to the user's exec list. */ + for (i = 0; i < args->buffer_count; i++) + exec_list[i].offset = exec2_list[i].offset; + /* ... and back out to userspace */ + ret = copy_to_user((struct drm_i915_relocation_entry __user *) + (uintptr_t) args->buffers_ptr, + exec_list, + sizeof(*exec_list) * args->buffer_count); + if (ret) { + ret = -EFAULT; + DRM_ERROR("failed to copy %d exec entries " + "back to user (%d)\n", + args->buffer_count, ret); + } + } + + drm_free_large(exec_list); + drm_free_large(exec2_list); + return ret; +} + +int +i915_gem_execbuffer2(struct drm_device *dev, void *data, + struct drm_file *file) +{ + struct drm_i915_gem_execbuffer2 *args = data; + struct drm_i915_gem_exec_object2 *exec2_list = NULL; + int ret; + +#if WATCH_EXEC + DRM_INFO("buffers_ptr %d buffer_count %d len %08x\n", + (int) args->buffers_ptr, args->buffer_count, args->batch_len); +#endif + + if (args->buffer_count < 1) { + DRM_ERROR("execbuf2 with %d buffers\n", args->buffer_count); + return -EINVAL; + } + + exec2_list = drm_malloc_ab(sizeof(*exec2_list), args->buffer_count); + if (exec2_list == NULL) { + DRM_ERROR("Failed to allocate exec list for %d buffers\n", + args->buffer_count); + return -ENOMEM; + } + ret = copy_from_user(exec2_list, + (struct drm_i915_relocation_entry __user *) + (uintptr_t) args->buffers_ptr, + sizeof(*exec2_list) * args->buffer_count); + if (ret != 0) { + DRM_ERROR("copy %d exec entries failed %d\n", + args->buffer_count, ret); + drm_free_large(exec2_list); + return -EFAULT; + } + + ret = i915_gem_do_execbuffer(dev, data, file, args, exec2_list); + if (!ret) { + /* Copy the new buffer offsets back to the user's exec list. */ + ret = copy_to_user((struct drm_i915_relocation_entry __user *) + (uintptr_t) args->buffers_ptr, + exec2_list, + sizeof(*exec2_list) * args->buffer_count); + if (ret) { + ret = -EFAULT; + DRM_ERROR("failed to copy %d exec entries " + "back to user (%d)\n", + args->buffer_count, ret); + } + } + + drm_free_large(exec2_list); + return ret; +} + -- cgit v1.2.3 From 432e58edc9de1d9c3d6a7b444b3c455b8f209a7d Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 25 Nov 2010 19:32:06 +0000 Subject: drm/i915: Avoid allocation for execbuffer object list Besides the minimal improvement in reducing the execbuffer overhead, the real benefit is clarifying a few routines. Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_drv.h | 10 +- drivers/gpu/drm/i915/i915_gem.c | 1 + drivers/gpu/drm/i915/i915_gem_evict.c | 14 +- drivers/gpu/drm/i915/i915_gem_execbuffer.c | 403 ++++++++++++++--------------- 4 files changed, 199 insertions(+), 229 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 6c10b645dde9..e7c4108c94cd 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -712,8 +712,8 @@ struct drm_i915_gem_object { struct list_head mm_list; /** This object's place on GPU write list */ struct list_head gpu_write_list; - /** This object's place on eviction list */ - struct list_head evict_list; + /** This object's place in the batchbuffer or on the eviction list */ + struct list_head exec_list; /** * This is set if the object is on the active or flushing lists @@ -737,12 +737,6 @@ struct drm_i915_gem_object { */ signed int fence_reg : 5; - /** - * Used for checking the object doesn't appear more than once - * in an execbuffer object list. - */ - unsigned int in_execbuffer : 1; - /** * Advice: are the backing pages purgeable? */ diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index b30c6c167048..d9d81f94a4b8 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -3399,6 +3399,7 @@ struct drm_i915_gem_object *i915_gem_alloc_object(struct drm_device *dev, INIT_LIST_HEAD(&obj->mm_list); INIT_LIST_HEAD(&obj->gtt_list); INIT_LIST_HEAD(&obj->ring_list); + INIT_LIST_HEAD(&obj->exec_list); INIT_LIST_HEAD(&obj->gpu_write_list); obj->madv = I915_MADV_WILLNEED; /* Avoid an unnecessary call to unbind on the first bind. */ diff --git a/drivers/gpu/drm/i915/i915_gem_evict.c b/drivers/gpu/drm/i915/i915_gem_evict.c index 03e15d37b550..78b8cf90c922 100644 --- a/drivers/gpu/drm/i915/i915_gem_evict.c +++ b/drivers/gpu/drm/i915/i915_gem_evict.c @@ -34,7 +34,7 @@ static bool mark_free(struct drm_i915_gem_object *obj, struct list_head *unwind) { - list_add(&obj->evict_list, unwind); + list_add(&obj->exec_list, unwind); drm_gem_object_reference(&obj->base); return drm_mm_scan_add_block(obj->gtt_space); } @@ -127,7 +127,7 @@ i915_gem_evict_something(struct drm_device *dev, int min_size, } /* Nothing found, clean up and bail out! */ - list_for_each_entry(obj, &unwind_list, evict_list) { + list_for_each_entry(obj, &unwind_list, exec_list) { ret = drm_mm_scan_remove_block(obj->gtt_space); BUG_ON(ret); drm_gem_object_unreference(&obj->base); @@ -146,12 +146,12 @@ found: while (!list_empty(&unwind_list)) { obj = list_first_entry(&unwind_list, struct drm_i915_gem_object, - evict_list); + exec_list); if (drm_mm_scan_remove_block(obj->gtt_space)) { - list_move(&obj->evict_list, &eviction_list); + list_move(&obj->exec_list, &eviction_list); continue; } - list_del(&obj->evict_list); + list_del_init(&obj->exec_list); drm_gem_object_unreference(&obj->base); } @@ -159,10 +159,10 @@ found: while (!list_empty(&eviction_list)) { obj = list_first_entry(&eviction_list, struct drm_i915_gem_object, - evict_list); + exec_list); if (ret == 0) ret = i915_gem_object_unbind(obj); - list_del(&obj->evict_list); + list_del_init(&obj->exec_list); drm_gem_object_unreference(&obj->base); } diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index bdc613b91af8..d54070111f9d 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c @@ -406,18 +406,16 @@ i915_gem_execbuffer_relocate_object_slow(struct drm_i915_gem_object *obj, static int i915_gem_execbuffer_relocate(struct drm_device *dev, struct drm_file *file, - struct drm_i915_gem_object **object_list, - struct drm_i915_gem_exec_object2 *exec_list, - int count) + struct list_head *objects, + struct drm_i915_gem_exec_object2 *exec) { - int i, ret; + struct drm_i915_gem_object *obj; + int ret; - for (i = 0; i < count; i++) { - struct drm_i915_gem_object *obj = object_list[i]; + list_for_each_entry(obj, objects, exec_list) { obj->base.pending_read_domains = 0; obj->base.pending_write_domain = 0; - ret = i915_gem_execbuffer_relocate_object(obj, file, - &exec_list[i]); + ret = i915_gem_execbuffer_relocate_object(obj, file, exec++); if (ret) return ret; } @@ -428,11 +426,12 @@ i915_gem_execbuffer_relocate(struct drm_device *dev, static int i915_gem_execbuffer_reserve(struct drm_device *dev, struct drm_file *file, - struct drm_i915_gem_object **object_list, - struct drm_i915_gem_exec_object2 *exec_list, - int count) + struct list_head *objects, + struct drm_i915_gem_exec_object2 *exec) { - int ret, i, retry; + struct drm_i915_gem_object *obj; + struct drm_i915_gem_exec_object2 *entry; + int ret, retry; /* Attempt to pin all of the buffers into the GTT. * This is done in 3 phases: @@ -451,13 +450,14 @@ i915_gem_execbuffer_reserve(struct drm_device *dev, ret = 0; /* Unbind any ill-fitting objects or pin. */ - for (i = 0; i < count; i++) { - struct drm_i915_gem_object *obj = object_list[i]; - struct drm_i915_gem_exec_object2 *entry = &exec_list[i]; + entry = exec; + list_for_each_entry(obj, objects, exec_list) { bool need_fence, need_mappable; - if (!obj->gtt_space) + if (!obj->gtt_space) { + entry++; continue; + } need_fence = entry->flags & EXEC_OBJECT_NEEDS_FENCE && @@ -472,16 +472,15 @@ i915_gem_execbuffer_reserve(struct drm_device *dev, ret = i915_gem_object_pin(obj, entry->alignment, need_mappable); - if (ret) { - count = i; + if (ret) goto err; - } + + entry++; } /* Bind fresh objects */ - for (i = 0; i < count; i++) { - struct drm_i915_gem_exec_object2 *entry = &exec_list[i]; - struct drm_i915_gem_object *obj = object_list[i]; + entry = exec; + list_for_each_entry(obj, objects, exec_list) { bool need_fence; need_fence = @@ -504,15 +503,15 @@ i915_gem_execbuffer_reserve(struct drm_device *dev, if (ret) break; - obj->pending_fenced_gpu_access = true; } + obj->pending_fenced_gpu_access = need_fence; entry->offset = obj->gtt_offset; + entry++; } -err: /* Decrement pin count for bound objects */ - for (i = 0; i < count; i++) { - struct drm_i915_gem_object *obj = object_list[i]; + /* Decrement pin count for bound objects */ + list_for_each_entry(obj, objects, exec_list) { if (obj->gtt_space) i915_gem_object_unpin(obj); } @@ -529,26 +528,36 @@ err: /* Decrement pin count for bound objects */ retry++; } while (1); + +err: + while (objects != &obj->exec_list) { + if (obj->gtt_space) + i915_gem_object_unpin(obj); + + obj = list_entry(obj->exec_list.prev, + struct drm_i915_gem_object, + exec_list); + } + + return ret; } static int i915_gem_execbuffer_relocate_slow(struct drm_device *dev, struct drm_file *file, - struct drm_i915_gem_object **object_list, - struct drm_i915_gem_exec_object2 *exec_list, + struct list_head *objects, + struct drm_i915_gem_exec_object2 *exec, int count) { struct drm_i915_gem_relocation_entry *reloc; + struct drm_i915_gem_object *obj; int i, total, ret; - for (i = 0; i < count; i++) - object_list[i]->in_execbuffer = false; - mutex_unlock(&dev->struct_mutex); total = 0; for (i = 0; i < count; i++) - total += exec_list[i].relocation_count; + total += exec[i].relocation_count; reloc = drm_malloc_ab(total, sizeof(*reloc)); if (reloc == NULL) { @@ -560,17 +569,16 @@ i915_gem_execbuffer_relocate_slow(struct drm_device *dev, for (i = 0; i < count; i++) { struct drm_i915_gem_relocation_entry __user *user_relocs; - user_relocs = (void __user *)(uintptr_t)exec_list[i].relocs_ptr; + user_relocs = (void __user *)(uintptr_t)exec[i].relocs_ptr; if (copy_from_user(reloc+total, user_relocs, - exec_list[i].relocation_count * - sizeof(*reloc))) { + exec[i].relocation_count * sizeof(*reloc))) { ret = -EFAULT; mutex_lock(&dev->struct_mutex); goto err; } - total += exec_list[i].relocation_count; + total += exec[i].relocation_count; } ret = i915_mutex_lock_interruptible(dev); @@ -579,24 +587,22 @@ i915_gem_execbuffer_relocate_slow(struct drm_device *dev, goto err; } - ret = i915_gem_execbuffer_reserve(dev, file, - object_list, exec_list, - count); + ret = i915_gem_execbuffer_reserve(dev, file, objects, exec); if (ret) goto err; total = 0; - for (i = 0; i < count; i++) { - struct drm_i915_gem_object *obj = object_list[i]; + list_for_each_entry(obj, objects, exec_list) { obj->base.pending_read_domains = 0; obj->base.pending_write_domain = 0; ret = i915_gem_execbuffer_relocate_object_slow(obj, file, - &exec_list[i], + exec, reloc + total); if (ret) goto err; - total += exec_list[i].relocation_count; + total += exec->relocation_count; + exec++; } /* Leave the user relocations as are, this is the painfully slow path, @@ -636,20 +642,18 @@ i915_gem_execbuffer_flush(struct drm_device *dev, static int -i915_gem_execbuffer_move_to_gpu(struct drm_device *dev, - struct drm_file *file, - struct intel_ring_buffer *ring, - struct drm_i915_gem_object **objects, - int count) +i915_gem_execbuffer_move_to_gpu(struct intel_ring_buffer *ring, + struct list_head *objects) { + struct drm_i915_gem_object *obj; struct change_domains cd; - int ret, i; + int ret; cd.invalidate_domains = 0; cd.flush_domains = 0; cd.flush_rings = 0; - for (i = 0; i < count; i++) - i915_gem_object_set_to_gpu_domain(objects[i], ring, &cd); + list_for_each_entry(obj, objects, exec_list) + i915_gem_object_set_to_gpu_domain(obj, ring, &cd); if (cd.invalidate_domains | cd.flush_domains) { #if WATCH_EXEC @@ -658,14 +662,13 @@ i915_gem_execbuffer_move_to_gpu(struct drm_device *dev, cd.invalidate_domains, cd.flush_domains); #endif - i915_gem_execbuffer_flush(dev, + i915_gem_execbuffer_flush(ring->dev, cd.invalidate_domains, cd.flush_domains, cd.flush_rings); } - for (i = 0; i < count; i++) { - struct drm_i915_gem_object *obj = objects[i]; + list_for_each_entry(obj, objects, exec_list) { /* XXX replace with semaphores */ if (obj->ring && ring != obj->ring) { ret = i915_gem_object_wait_rendering(obj, true); @@ -677,22 +680,10 @@ i915_gem_execbuffer_move_to_gpu(struct drm_device *dev, return 0; } -static int -i915_gem_check_execbuffer(struct drm_i915_gem_execbuffer2 *exec, - uint64_t exec_offset) +static bool +i915_gem_check_execbuffer(struct drm_i915_gem_execbuffer2 *exec) { - uint32_t exec_start, exec_len; - - exec_start = (uint32_t) exec_offset + exec->batch_start_offset; - exec_len = (uint32_t) exec->batch_len; - - if ((exec_start | exec_len) & 0x7) - return -EINVAL; - - if (!exec_start) - return -EINVAL; - - return 0; + return ((exec->batch_start_offset | exec->batch_len) & 0x7) == 0; } static int @@ -726,36 +717,119 @@ validate_exec_list(struct drm_i915_gem_exec_object2 *exec, return 0; } +static int +i915_gem_execbuffer_wait_for_flips(struct intel_ring_buffer *ring, + struct list_head *objects) +{ + struct drm_i915_gem_object *obj; + int flips; + + /* Check for any pending flips. As we only maintain a flip queue depth + * of 1, we can simply insert a WAIT for the next display flip prior + * to executing the batch and avoid stalling the CPU. + */ + flips = 0; + list_for_each_entry(obj, objects, exec_list) { + if (obj->base.write_domain) + flips |= atomic_read(&obj->pending_flip); + } + if (flips) { + int plane, flip_mask, ret; + + for (plane = 0; flips >> plane; plane++) { + if (((flips >> plane) & 1) == 0) + continue; + + if (plane) + flip_mask = MI_WAIT_FOR_PLANE_B_FLIP; + else + flip_mask = MI_WAIT_FOR_PLANE_A_FLIP; + + ret = intel_ring_begin(ring, 2); + if (ret) + return ret; + + intel_ring_emit(ring, MI_WAIT_FOR_EVENT | flip_mask); + intel_ring_emit(ring, MI_NOOP); + intel_ring_advance(ring); + } + } + + return 0; +} + +static void +i915_gem_execbuffer_move_to_active(struct list_head *objects, + struct intel_ring_buffer *ring) +{ + struct drm_i915_gem_object *obj; + + list_for_each_entry(obj, objects, exec_list) { + obj->base.read_domains = obj->base.pending_read_domains; + obj->base.write_domain = obj->base.pending_write_domain; + obj->fenced_gpu_access = obj->pending_fenced_gpu_access; + + i915_gem_object_move_to_active(obj, ring); + if (obj->base.write_domain) { + obj->dirty = 1; + list_move_tail(&obj->gpu_write_list, + &ring->gpu_write_list); + intel_mark_busy(ring->dev, obj); + } + + trace_i915_gem_object_change_domain(obj, + obj->base.read_domains, + obj->base.write_domain); + } +} + static void i915_gem_execbuffer_retire_commands(struct drm_device *dev, + struct drm_file *file, struct intel_ring_buffer *ring) { - uint32_t flush_domains = 0; + struct drm_i915_gem_request *request; + u32 flush_domains; - /* The sampler always gets flushed on i965 (sigh) */ + /* + * Ensure that the commands in the batch buffer are + * finished before the interrupt fires. + * + * The sampler always gets flushed on i965 (sigh). + */ + flush_domains = 0; if (INTEL_INFO(dev)->gen >= 4) flush_domains |= I915_GEM_DOMAIN_SAMPLER; ring->flush(ring, I915_GEM_DOMAIN_COMMAND, flush_domains); -} + /* Add a breadcrumb for the completion of the batch buffer */ + request = kzalloc(sizeof(*request), GFP_KERNEL); + if (request == NULL || i915_add_request(dev, file, request, ring)) { + i915_gem_next_request_seqno(dev, ring); + kfree(request); + } +} static int i915_gem_do_execbuffer(struct drm_device *dev, void *data, struct drm_file *file, struct drm_i915_gem_execbuffer2 *args, - struct drm_i915_gem_exec_object2 *exec_list) + struct drm_i915_gem_exec_object2 *exec) { drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_i915_gem_object **object_list = NULL; + struct list_head objects; struct drm_i915_gem_object *batch_obj; struct drm_clip_rect *cliprects = NULL; - struct drm_i915_gem_request *request = NULL; struct intel_ring_buffer *ring; - int ret, i, flips; - uint64_t exec_offset; + int ret, i; - ret = validate_exec_list(exec_list, args->buffer_count); + if (!i915_gem_check_execbuffer(args)) { + DRM_ERROR("execbuf with invalid offset/length\n"); + return -EINVAL; + } + + ret = validate_exec_list(exec, args->buffer_count); if (ret) return ret; @@ -792,40 +866,24 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, DRM_ERROR("execbuf with %d buffers\n", args->buffer_count); return -EINVAL; } - object_list = drm_malloc_ab(sizeof(*object_list), args->buffer_count); - if (object_list == NULL) { - DRM_ERROR("Failed to allocate object list for %d buffers\n", - args->buffer_count); - ret = -ENOMEM; - goto pre_mutex_err; - } if (args->num_cliprects != 0) { - cliprects = kcalloc(args->num_cliprects, sizeof(*cliprects), + cliprects = kmalloc(args->num_cliprects * sizeof(*cliprects), GFP_KERNEL); if (cliprects == NULL) { ret = -ENOMEM; goto pre_mutex_err; } - ret = copy_from_user(cliprects, - (struct drm_clip_rect __user *) - (uintptr_t) args->cliprects_ptr, - sizeof(*cliprects) * args->num_cliprects); - if (ret != 0) { - DRM_ERROR("copy %d cliprects failed: %d\n", - args->num_cliprects, ret); + if (copy_from_user(cliprects, + (struct drm_clip_rect __user *)(uintptr_t) + args->cliprects_ptr, + sizeof(*cliprects)*args->num_cliprects)) { ret = -EFAULT; goto pre_mutex_err; } } - request = kzalloc(sizeof(*request), GFP_KERNEL); - if (request == NULL) { - ret = -ENOMEM; - goto pre_mutex_err; - } - ret = i915_mutex_lock_interruptible(dev); if (ret) goto pre_mutex_err; @@ -837,49 +895,41 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, } /* Look up object handles */ + INIT_LIST_HEAD(&objects); for (i = 0; i < args->buffer_count; i++) { struct drm_i915_gem_object *obj; - obj = to_intel_bo (drm_gem_object_lookup(dev, file, - exec_list[i].handle)); + obj = to_intel_bo(drm_gem_object_lookup(dev, file, + exec[i].handle)); if (obj == NULL) { DRM_ERROR("Invalid object handle %d at index %d\n", - exec_list[i].handle, i); + exec[i].handle, i); /* prevent error path from reading uninitialized data */ - args->buffer_count = i; ret = -ENOENT; goto err; } - object_list[i] = obj; - if (obj->in_execbuffer) { - DRM_ERROR("Object %p appears more than once in object list\n", - obj); - /* prevent error path from reading uninitialized data */ - args->buffer_count = i + 1; + if (!list_empty(&obj->exec_list)) { + DRM_ERROR("Object %p [handle %d, index %d] appears more than once in object list\n", + obj, exec[i].handle, i); ret = -EINVAL; goto err; } - obj->in_execbuffer = true; - obj->pending_fenced_gpu_access = false; + + list_add_tail(&obj->exec_list, &objects); } /* Move the objects en-masse into the GTT, evicting if necessary. */ - ret = i915_gem_execbuffer_reserve(dev, file, - object_list, exec_list, - args->buffer_count); + ret = i915_gem_execbuffer_reserve(dev, file, &objects, exec); if (ret) goto err; /* The objects are in their final locations, apply the relocations. */ - ret = i915_gem_execbuffer_relocate(dev, file, - object_list, exec_list, - args->buffer_count); + ret = i915_gem_execbuffer_relocate(dev, file, &objects, exec); if (ret) { if (ret == -EFAULT) { ret = i915_gem_execbuffer_relocate_slow(dev, file, - object_list, - exec_list, + &objects, exec, args->buffer_count); BUG_ON(!mutex_is_locked(&dev->struct_mutex)); } @@ -888,7 +938,9 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, } /* Set the pending read domains for the batch buffer to COMMAND */ - batch_obj = object_list[args->buffer_count-1]; + batch_obj = list_entry(objects.prev, + struct drm_i915_gem_object, + exec_list); if (batch_obj->base.pending_write_domain) { DRM_ERROR("Attempting to use self-modifying batch buffer\n"); ret = -EINVAL; @@ -896,115 +948,38 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, } batch_obj->base.pending_read_domains |= I915_GEM_DOMAIN_COMMAND; - /* Sanity check the batch buffer */ - exec_offset = batch_obj->gtt_offset; - ret = i915_gem_check_execbuffer(args, exec_offset); - if (ret != 0) { - DRM_ERROR("execbuf with invalid offset/length\n"); + ret = i915_gem_execbuffer_move_to_gpu(ring, &objects); + if (ret) goto err; - } - ret = i915_gem_execbuffer_move_to_gpu(dev, file, ring, - object_list, args->buffer_count); + ret = i915_gem_execbuffer_wait_for_flips(ring, &objects); if (ret) goto err; -#if WATCH_COHERENCY - for (i = 0; i < args->buffer_count; i++) { - i915_gem_object_check_coherency(object_list[i], - exec_list[i].handle); - } -#endif - -#if WATCH_EXEC - i915_gem_dump_object(batch_obj, - args->batch_len, - __func__, - ~0); -#endif - - /* Check for any pending flips. As we only maintain a flip queue depth - * of 1, we can simply insert a WAIT for the next display flip prior - * to executing the batch and avoid stalling the CPU. - */ - flips = 0; - for (i = 0; i < args->buffer_count; i++) { - if (object_list[i]->base.write_domain) - flips |= atomic_read(&object_list[i]->pending_flip); - } - if (flips) { - int plane, flip_mask; - - for (plane = 0; flips >> plane; plane++) { - if (((flips >> plane) & 1) == 0) - continue; - - if (plane) - flip_mask = MI_WAIT_FOR_PLANE_B_FLIP; - else - flip_mask = MI_WAIT_FOR_PLANE_A_FLIP; - - ret = intel_ring_begin(ring, 2); - if (ret) - goto err; - - intel_ring_emit(ring, MI_WAIT_FOR_EVENT | flip_mask); - intel_ring_emit(ring, MI_NOOP); - intel_ring_advance(ring); - } - } - - /* Exec the batchbuffer */ - ret = ring->dispatch_execbuffer(ring, args, cliprects, exec_offset); - if (ret) { - DRM_ERROR("dispatch failed %d\n", ret); + ret = ring->dispatch_execbuffer(ring, + args, cliprects, + batch_obj->gtt_offset); + if (ret) goto err; - } - for (i = 0; i < args->buffer_count; i++) { - struct drm_i915_gem_object *obj = object_list[i]; - - obj->base.read_domains = obj->base.pending_read_domains; - obj->base.write_domain = obj->base.pending_write_domain; - obj->fenced_gpu_access = obj->pending_fenced_gpu_access; - - i915_gem_object_move_to_active(obj, ring); - if (obj->base.write_domain) { - obj->dirty = 1; - list_move_tail(&obj->gpu_write_list, - &ring->gpu_write_list); - intel_mark_busy(dev, obj); - } - - trace_i915_gem_object_change_domain(obj, - obj->base.read_domains, - obj->base.write_domain); - } - - /* - * Ensure that the commands in the batch buffer are - * finished before the interrupt fires - */ - i915_gem_execbuffer_retire_commands(dev, ring); - - if (i915_add_request(dev, file, request, ring)) - i915_gem_next_request_seqno(dev, ring); - else - request = NULL; + i915_gem_execbuffer_move_to_active(&objects, ring); + i915_gem_execbuffer_retire_commands(dev, file, ring); err: - for (i = 0; i < args->buffer_count; i++) { - object_list[i]->in_execbuffer = false; - drm_gem_object_unreference(&object_list[i]->base); + while (!list_empty(&objects)) { + struct drm_i915_gem_object *obj; + + obj = list_first_entry(&objects, + struct drm_i915_gem_object, + exec_list); + list_del_init(&obj->exec_list); + drm_gem_object_unreference(&obj->base); } mutex_unlock(&dev->struct_mutex); pre_mutex_err: - drm_free_large(object_list); kfree(cliprects); - kfree(request); - return ret; } -- cgit v1.2.3 From acb325062afc09c196f7d3888b81312e6ebcdc35 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Tue, 23 Nov 2010 00:41:00 -0500 Subject: drm/radeon/kms: improve pflip precision on r1xx-r4xx The update pending bit has a separate enable bit. Cc: Mario Kleiner Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/r100.c | 8 +++++--- drivers/gpu/drm/radeon/radeon_reg.h | 2 ++ 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index 2316f73db6c0..300b4a64d8fe 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c @@ -76,6 +76,8 @@ void r100_pre_page_flip(struct radeon_device *rdev, int crtc) /* make sure flip is at vb rather than hb */ tmp = RREG32(RADEON_CRTC_OFFSET_CNTL + radeon_crtc->crtc_offset); tmp &= ~RADEON_CRTC_OFFSET_FLIP_CNTL; + /* make sure pending bit is asserted */ + tmp |= RADEON_CRTC_GUI_TRIG_OFFSET_LEFT_EN; WREG32(RADEON_CRTC_OFFSET_CNTL + radeon_crtc->crtc_offset, tmp); /* set pageflip to happen as late as possible in the vblank interval. @@ -104,9 +106,9 @@ u32 r100_page_flip(struct radeon_device *rdev, int crtc_id, u64 crtc_base) /* update the scanout addresses */ WREG32(RADEON_CRTC_OFFSET + radeon_crtc->crtc_offset, tmp); - /* Note: We don't wait for update_pending to assert, as this never - * happens for some reason on R1xx - R4xx. Adds a bit of imprecision. - */ + /* Wait for update_pending to go high. */ + while (!(RREG32(RADEON_CRTC_OFFSET + radeon_crtc->crtc_offset) & RADEON_CRTC_OFFSET__GUI_TRIG_OFFSET)); + DRM_DEBUG("Update pending now high. Unlocking vupdate_lock.\n"); /* Unlock the lock, so double-buffering can take place inside vblank */ tmp &= ~RADEON_CRTC_OFFSET__OFFSET_LOCK; diff --git a/drivers/gpu/drm/radeon/radeon_reg.h b/drivers/gpu/drm/radeon/radeon_reg.h index 26c43e234350..0a310b7f71c3 100644 --- a/drivers/gpu/drm/radeon/radeon_reg.h +++ b/drivers/gpu/drm/radeon/radeon_reg.h @@ -510,6 +510,8 @@ # define RADEON_CRTC_TILE_EN (1 << 15) # define RADEON_CRTC_OFFSET_FLIP_CNTL (1 << 16) # define RADEON_CRTC_STEREO_OFFSET_EN (1 << 17) +# define RADEON_CRTC_GUI_TRIG_OFFSET_LEFT_EN (1 << 28) +# define RADEON_CRTC_GUI_TRIG_OFFSET_RIGHT_EN (1 << 29) #define R300_CRTC_TILE_X0_Y0 0x0350 #define R300_CRTC2_TILE_X0_Y0 0x0358 -- cgit v1.2.3 From 8ff590903d5fc7f5a0a988c38267a3d08e6393a2 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Tue, 19 Oct 2010 21:31:55 +0800 Subject: crypto: algif_skcipher - User-space interface for skcipher operations This patch adds the af_alg plugin for symmetric key ciphers, corresponding to the ablkcipher kernel operation type. Keys can optionally be set through the setsockopt interface. Once a sendmsg call occurs without MSG_MORE no further writes may be made to the socket until all previous data has been read. IVs and and whether encryption/decryption is performed can be set through the setsockopt interface or as a control message to sendmsg. The interface is completely synchronous, all operations are carried out in recvmsg(2) and will complete prior to the system call returning. The splice(2) interface support reading the user-space data directly without copying (except that the Crypto API itself may copy the data if alignment is off). The recvmsg(2) interface supports directly writing to user-space without additional copying, i.e., the kernel crypto interface will receive the user-space address as its output SG list. Thakns to Miloslav Trmac for reviewing this and contributing fixes and improvements. Signed-off-by: Herbert Xu Acked-by: David S. Miller --- crypto/Kconfig | 8 + crypto/Makefile | 1 + crypto/algif_skcipher.c | 640 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 649 insertions(+) create mode 100644 crypto/algif_skcipher.c diff --git a/crypto/Kconfig b/crypto/Kconfig index 6db27d7ff8b3..69437e21217f 100644 --- a/crypto/Kconfig +++ b/crypto/Kconfig @@ -852,6 +852,14 @@ config CRYPTO_USER_API_HASH This option enables the user-spaces interface for hash algorithms. +config CRYPTO_USER_API_SKCIPHER + tristate "User-space interface for symmetric key cipher algorithms" + select CRYPTO_BLKCIPHER + select CRYPTO_USER_API + help + This option enables the user-spaces interface for symmetric + key cipher algorithms. + source "drivers/crypto/Kconfig" endif # if CRYPTO diff --git a/crypto/Makefile b/crypto/Makefile index 14ab4052a9c8..efc0f18dbb37 100644 --- a/crypto/Makefile +++ b/crypto/Makefile @@ -87,6 +87,7 @@ obj-$(CONFIG_CRYPTO_TEST) += tcrypt.o obj-$(CONFIG_CRYPTO_GHASH) += ghash-generic.o obj-$(CONFIG_CRYPTO_USER_API) += af_alg.o obj-$(CONFIG_CRYPTO_USER_API_HASH) += algif_hash.o +obj-$(CONFIG_CRYPTO_USER_API_SKCIPHER) += algif_skcipher.o # # generic algorithms and the async_tx api diff --git a/crypto/algif_skcipher.c b/crypto/algif_skcipher.c new file mode 100644 index 000000000000..211c956952ca --- /dev/null +++ b/crypto/algif_skcipher.c @@ -0,0 +1,640 @@ +/* + * algif_skcipher: User-space interface for skcipher algorithms + * + * This file provides the user-space API for symmetric key ciphers. + * + * Copyright (c) 2010 Herbert Xu + * + * 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. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct skcipher_sg_list { + struct list_head list; + + int cur; + + struct scatterlist sg[0]; +}; + +struct skcipher_ctx { + struct list_head tsgl; + struct af_alg_sgl rsgl; + + void *iv; + + struct af_alg_completion completion; + + unsigned used; + + unsigned int len; + bool more; + bool merge; + bool enc; + + struct ablkcipher_request req; +}; + +#define MAX_SGL_ENTS ((PAGE_SIZE - sizeof(struct skcipher_sg_list)) / \ + sizeof(struct scatterlist) - 1) + +static inline bool skcipher_writable(struct sock *sk) +{ + struct alg_sock *ask = alg_sk(sk); + struct skcipher_ctx *ctx = ask->private; + + return ctx->used + PAGE_SIZE <= max_t(int, sk->sk_sndbuf, PAGE_SIZE); +} + +static int skcipher_alloc_sgl(struct sock *sk) +{ + struct alg_sock *ask = alg_sk(sk); + struct skcipher_ctx *ctx = ask->private; + struct skcipher_sg_list *sgl; + struct scatterlist *sg = NULL; + + sgl = list_entry(ctx->tsgl.prev, struct skcipher_sg_list, list); + if (!list_empty(&ctx->tsgl)) + sg = sgl->sg; + + if (!sg || sgl->cur >= MAX_SGL_ENTS) { + sgl = sock_kmalloc(sk, sizeof(*sgl) + + sizeof(sgl->sg[0]) * (MAX_SGL_ENTS + 1), + GFP_KERNEL); + if (!sgl) + return -ENOMEM; + + sg_init_table(sgl->sg, MAX_SGL_ENTS + 1); + sgl->cur = 0; + + if (sg) + scatterwalk_sg_chain(sg, MAX_SGL_ENTS + 1, sgl->sg); + + list_add_tail(&sgl->list, &ctx->tsgl); + } + + return 0; +} + +static void skcipher_pull_sgl(struct sock *sk, int used) +{ + struct alg_sock *ask = alg_sk(sk); + struct skcipher_ctx *ctx = ask->private; + struct skcipher_sg_list *sgl; + struct scatterlist *sg; + int i; + + while (!list_empty(&ctx->tsgl)) { + sgl = list_first_entry(&ctx->tsgl, struct skcipher_sg_list, + list); + sg = sgl->sg; + + for (i = 0; i < sgl->cur; i++) { + int plen = min_t(int, used, sg[i].length); + + if (!sg_page(sg + i)) + continue; + + sg[i].length -= plen; + sg[i].offset += plen; + + used -= plen; + ctx->used -= plen; + + if (sg[i].length) + return; + + put_page(sg_page(sg + i)); + sg_assign_page(sg + i, NULL); + } + + list_del(&sgl->list); + sock_kfree_s(sk, sgl, + sizeof(*sgl) + sizeof(sgl->sg[0]) * + (MAX_SGL_ENTS + 1)); + } + + if (!ctx->used) + ctx->merge = 0; +} + +static void skcipher_free_sgl(struct sock *sk) +{ + struct alg_sock *ask = alg_sk(sk); + struct skcipher_ctx *ctx = ask->private; + + skcipher_pull_sgl(sk, ctx->used); +} + +static int skcipher_wait_for_wmem(struct sock *sk, unsigned flags) +{ + long timeout; + DEFINE_WAIT(wait); + int err = -ERESTARTSYS; + + if (flags & MSG_DONTWAIT) + return -EAGAIN; + + set_bit(SOCK_ASYNC_NOSPACE, &sk->sk_socket->flags); + + for (;;) { + if (signal_pending(current)) + break; + prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); + timeout = MAX_SCHEDULE_TIMEOUT; + if (sk_wait_event(sk, &timeout, skcipher_writable(sk))) { + err = 0; + break; + } + } + finish_wait(sk_sleep(sk), &wait); + + return err; +} + +static void skcipher_wmem_wakeup(struct sock *sk) +{ + struct socket_wq *wq; + + if (!skcipher_writable(sk)) + return; + + rcu_read_lock(); + wq = rcu_dereference(sk->sk_wq); + if (wq_has_sleeper(wq)) + wake_up_interruptible_sync_poll(&wq->wait, POLLIN | + POLLRDNORM | + POLLRDBAND); + sk_wake_async(sk, SOCK_WAKE_WAITD, POLL_IN); + rcu_read_unlock(); +} + +static int skcipher_wait_for_data(struct sock *sk, unsigned flags) +{ + struct alg_sock *ask = alg_sk(sk); + struct skcipher_ctx *ctx = ask->private; + long timeout; + DEFINE_WAIT(wait); + int err = -ERESTARTSYS; + + if (flags & MSG_DONTWAIT) { + return -EAGAIN; + } + + set_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags); + + for (;;) { + if (signal_pending(current)) + break; + prepare_to_wait(sk_sleep(sk), &wait, TASK_INTERRUPTIBLE); + timeout = MAX_SCHEDULE_TIMEOUT; + if (sk_wait_event(sk, &timeout, ctx->used)) { + err = 0; + break; + } + } + finish_wait(sk_sleep(sk), &wait); + + clear_bit(SOCK_ASYNC_WAITDATA, &sk->sk_socket->flags); + + return err; +} + +static void skcipher_data_wakeup(struct sock *sk) +{ + struct alg_sock *ask = alg_sk(sk); + struct skcipher_ctx *ctx = ask->private; + struct socket_wq *wq; + + if (!ctx->used) + return; + + rcu_read_lock(); + wq = rcu_dereference(sk->sk_wq); + if (wq_has_sleeper(wq)) + wake_up_interruptible_sync_poll(&wq->wait, POLLOUT | + POLLRDNORM | + POLLRDBAND); + sk_wake_async(sk, SOCK_WAKE_SPACE, POLL_OUT); + rcu_read_unlock(); +} + +static int skcipher_sendmsg(struct kiocb *unused, struct socket *sock, + struct msghdr *msg, size_t size) +{ + struct sock *sk = sock->sk; + struct alg_sock *ask = alg_sk(sk); + struct skcipher_ctx *ctx = ask->private; + struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(&ctx->req); + unsigned ivsize = crypto_ablkcipher_ivsize(tfm); + struct skcipher_sg_list *sgl; + struct af_alg_control con = {}; + long copied = 0; + bool enc = 0; + int limit; + int err; + int i; + + if (msg->msg_controllen) { + err = af_alg_cmsg_send(msg, &con); + if (err) + return err; + + switch (con.op) { + case ALG_OP_ENCRYPT: + enc = 1; + break; + case ALG_OP_DECRYPT: + enc = 0; + break; + default: + return -EINVAL; + } + + if (con.iv && con.iv->ivlen != ivsize) + return -EINVAL; + } + + err = -EINVAL; + + lock_sock(sk); + if (!ctx->more && ctx->used) + goto unlock; + + if (!ctx->used) { + ctx->enc = enc; + if (con.iv) + memcpy(ctx->iv, con.iv->iv, ivsize); + } + + limit = max_t(int, sk->sk_sndbuf, PAGE_SIZE); + limit -= ctx->used; + + while (size) { + struct scatterlist *sg; + unsigned long len = size; + int plen; + + if (ctx->merge) { + sgl = list_entry(ctx->tsgl.prev, + struct skcipher_sg_list, list); + sg = sgl->sg + sgl->cur - 1; + len = min_t(unsigned long, len, + PAGE_SIZE - sg->offset - sg->length); + + err = memcpy_fromiovec(page_address(sg_page(sg)) + + sg->offset + sg->length, + msg->msg_iov, len); + if (err) + goto unlock; + + sg->length += len; + ctx->merge = (sg->offset + sg->length) & + (PAGE_SIZE - 1); + + ctx->used += len; + copied += len; + size -= len; + limit -= len; + continue; + } + + if (limit < PAGE_SIZE) { + err = skcipher_wait_for_wmem(sk, msg->msg_flags); + if (err) + goto unlock; + + limit = max_t(int, sk->sk_sndbuf, PAGE_SIZE); + limit -= ctx->used; + } + + len = min_t(unsigned long, len, limit); + + err = skcipher_alloc_sgl(sk); + if (err) + goto unlock; + + sgl = list_entry(ctx->tsgl.prev, struct skcipher_sg_list, list); + sg = sgl->sg; + do { + i = sgl->cur; + plen = min_t(int, len, PAGE_SIZE); + + sg_assign_page(sg + i, alloc_page(GFP_KERNEL)); + err = -ENOMEM; + if (!sg_page(sg + i)) + goto unlock; + + err = memcpy_fromiovec(page_address(sg_page(sg + i)), + msg->msg_iov, plen); + if (err) { + __free_page(sg_page(sg + i)); + sg_assign_page(sg + i, NULL); + goto unlock; + } + + sg[i].length = plen; + len -= plen; + ctx->used += plen; + copied += plen; + size -= plen; + limit -= plen; + sgl->cur++; + } while (len && sgl->cur < MAX_SGL_ENTS); + + ctx->merge = plen & (PAGE_SIZE - 1); + } + + err = 0; + + ctx->more = msg->msg_flags & MSG_MORE; + if (!ctx->more && !list_empty(&ctx->tsgl)) + sgl = list_entry(ctx->tsgl.prev, struct skcipher_sg_list, list); + +unlock: + skcipher_data_wakeup(sk); + release_sock(sk); + + return copied ?: err; +} + +static ssize_t skcipher_sendpage(struct socket *sock, struct page *page, + int offset, size_t size, int flags) +{ + struct sock *sk = sock->sk; + struct alg_sock *ask = alg_sk(sk); + struct skcipher_ctx *ctx = ask->private; + struct skcipher_sg_list *sgl; + int err = -EINVAL; + int limit; + + lock_sock(sk); + if (!ctx->more && ctx->used) + goto unlock; + + if (!size) + goto done; + + limit = max_t(int, sk->sk_sndbuf, PAGE_SIZE); + limit -= ctx->used; + + if (limit < PAGE_SIZE) { + err = skcipher_wait_for_wmem(sk, flags); + if (err) + goto unlock; + + limit = max_t(int, sk->sk_sndbuf, PAGE_SIZE); + limit -= ctx->used; + } + + err = skcipher_alloc_sgl(sk); + if (err) + goto unlock; + + ctx->merge = 0; + sgl = list_entry(ctx->tsgl.prev, struct skcipher_sg_list, list); + + get_page(page); + sg_set_page(sgl->sg + sgl->cur, page, size, offset); + sgl->cur++; + ctx->used += size; + +done: + ctx->more = flags & MSG_MORE; + if (!ctx->more && !list_empty(&ctx->tsgl)) + sgl = list_entry(ctx->tsgl.prev, struct skcipher_sg_list, list); + +unlock: + skcipher_data_wakeup(sk); + release_sock(sk); + + return err ?: size; +} + +static int skcipher_recvmsg(struct kiocb *unused, struct socket *sock, + struct msghdr *msg, size_t ignored, int flags) +{ + struct sock *sk = sock->sk; + struct alg_sock *ask = alg_sk(sk); + struct skcipher_ctx *ctx = ask->private; + unsigned bs = crypto_ablkcipher_blocksize(crypto_ablkcipher_reqtfm( + &ctx->req)); + struct skcipher_sg_list *sgl; + struct scatterlist *sg; + unsigned long iovlen; + struct iovec *iov; + int err = -EAGAIN; + int used; + long copied = 0; + + lock_sock(sk); + for (iov = msg->msg_iov, iovlen = msg->msg_iovlen; iovlen > 0; + iovlen--, iov++) { + unsigned long seglen = iov->iov_len; + char __user *from = iov->iov_base; + + while (seglen) { + sgl = list_first_entry(&ctx->tsgl, + struct skcipher_sg_list, list); + sg = sgl->sg; + + while (!sg->length) + sg++; + + used = ctx->used; + if (!used) { + err = skcipher_wait_for_data(sk, flags); + if (err) + goto unlock; + } + + used = min_t(unsigned long, used, seglen); + + if (ctx->more || used < ctx->used) + used -= used % bs; + + err = -EINVAL; + if (!used) + goto unlock; + + used = af_alg_make_sg(&ctx->rsgl, from, used, 1); + if (used < 0) + goto unlock; + + ablkcipher_request_set_crypt(&ctx->req, sg, + ctx->rsgl.sg, used, + ctx->iv); + + err = af_alg_wait_for_completion( + ctx->enc ? + crypto_ablkcipher_encrypt(&ctx->req) : + crypto_ablkcipher_decrypt(&ctx->req), + &ctx->completion); + + af_alg_free_sg(&ctx->rsgl); + + if (err) + goto unlock; + + copied += used; + from += used; + seglen -= used; + skcipher_pull_sgl(sk, used); + } + } + + err = 0; + +unlock: + skcipher_wmem_wakeup(sk); + release_sock(sk); + + return copied ?: err; +} + + +static unsigned int skcipher_poll(struct file *file, struct socket *sock, + poll_table *wait) +{ + struct sock *sk = sock->sk; + struct alg_sock *ask = alg_sk(sk); + struct skcipher_ctx *ctx = ask->private; + unsigned int mask; + + sock_poll_wait(file, sk_sleep(sk), wait); + mask = 0; + + if (ctx->used) + mask |= POLLIN | POLLRDNORM; + + if (skcipher_writable(sk)) + mask |= POLLOUT | POLLWRNORM | POLLWRBAND; + + return mask; +} + +static struct proto_ops algif_skcipher_ops = { + .family = PF_ALG, + + .connect = sock_no_connect, + .socketpair = sock_no_socketpair, + .getname = sock_no_getname, + .ioctl = sock_no_ioctl, + .listen = sock_no_listen, + .shutdown = sock_no_shutdown, + .getsockopt = sock_no_getsockopt, + .mmap = sock_no_mmap, + .bind = sock_no_bind, + .accept = sock_no_accept, + .setsockopt = sock_no_setsockopt, + + .release = af_alg_release, + .sendmsg = skcipher_sendmsg, + .sendpage = skcipher_sendpage, + .recvmsg = skcipher_recvmsg, + .poll = skcipher_poll, +}; + +static void *skcipher_bind(const char *name, u32 type, u32 mask) +{ + return crypto_alloc_ablkcipher(name, type, mask); +} + +static void skcipher_release(void *private) +{ + crypto_free_ablkcipher(private); +} + +static int skcipher_setkey(void *private, const u8 *key, unsigned int keylen) +{ + return crypto_ablkcipher_setkey(private, key, keylen); +} + +static void skcipher_sock_destruct(struct sock *sk) +{ + struct alg_sock *ask = alg_sk(sk); + struct skcipher_ctx *ctx = ask->private; + struct crypto_ablkcipher *tfm = crypto_ablkcipher_reqtfm(&ctx->req); + + skcipher_free_sgl(sk); + sock_kfree_s(sk, ctx->iv, crypto_ablkcipher_ivsize(tfm)); + sock_kfree_s(sk, ctx, ctx->len); + af_alg_release_parent(sk); +} + +static int skcipher_accept_parent(void *private, struct sock *sk) +{ + struct skcipher_ctx *ctx; + struct alg_sock *ask = alg_sk(sk); + unsigned int len = sizeof(*ctx) + crypto_ablkcipher_reqsize(private); + + ctx = sock_kmalloc(sk, len, GFP_KERNEL); + if (!ctx) + return -ENOMEM; + + ctx->iv = sock_kmalloc(sk, crypto_ablkcipher_ivsize(private), + GFP_KERNEL); + if (!ctx->iv) { + sock_kfree_s(sk, ctx, len); + return -ENOMEM; + } + + memset(ctx->iv, 0, crypto_ablkcipher_ivsize(private)); + + INIT_LIST_HEAD(&ctx->tsgl); + ctx->len = len; + ctx->used = 0; + ctx->more = 0; + ctx->merge = 0; + ctx->enc = 0; + af_alg_init_completion(&ctx->completion); + + ask->private = ctx; + + ablkcipher_request_set_tfm(&ctx->req, private); + ablkcipher_request_set_callback(&ctx->req, CRYPTO_TFM_REQ_MAY_BACKLOG, + af_alg_complete, &ctx->completion); + + sk->sk_destruct = skcipher_sock_destruct; + + return 0; +} + +static const struct af_alg_type algif_type_skcipher = { + .bind = skcipher_bind, + .release = skcipher_release, + .setkey = skcipher_setkey, + .accept = skcipher_accept_parent, + .ops = &algif_skcipher_ops, + .name = "skcipher", + .owner = THIS_MODULE +}; + +static int __init algif_skcipher_init(void) +{ + return af_alg_register_type(&algif_type_skcipher); +} + +static void __exit algif_skcipher_exit(void) +{ + int err = af_alg_unregister_type(&algif_type_skcipher); + BUG_ON(err); +} + +module_init(algif_skcipher_init); +module_exit(algif_skcipher_exit); +MODULE_LICENSE("GPL"); -- cgit v1.2.3 From 73d8c34f3d78ccf90a431c221df10377affce650 Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Mon, 15 Nov 2010 16:03:04 -0500 Subject: SCSI: improve two error messages This trivial patch (as1338) makes two uninformative error messages in scsi_sysfs_add_sdev() more explicit. Signed-off-by: Alan Stern Signed-off-by: Jiri Kosina --- drivers/scsi/scsi_sysfs.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c index 20ad59dff730..9c52ce4f7129 100644 --- a/drivers/scsi/scsi_sysfs.c +++ b/drivers/scsi/scsi_sysfs.c @@ -864,13 +864,15 @@ int scsi_sysfs_add_sdev(struct scsi_device *sdev) error = device_add(&sdev->sdev_gendev); if (error) { - printk(KERN_INFO "error 1\n"); + sdev_printk(KERN_INFO, sdev, + "failed to add device: %d\n", error); return error; } device_enable_async_suspend(&sdev->sdev_dev); error = device_add(&sdev->sdev_dev); if (error) { - printk(KERN_INFO "error 2\n"); + sdev_printk(KERN_INFO, sdev, + "failed to add class device: %d\n", error); device_del(&sdev->sdev_gendev); return error; } -- cgit v1.2.3 From ccf1fa403e44c4107ef4d73f73cafe81b5148d40 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 26 Nov 2010 11:50:03 +0000 Subject: ASoC: Remove redundant hw_write initialisation in WM8737 Signed-off-by: Mark Brown Acked-by: Liam Girdwood --- sound/soc/codecs/wm8737.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sound/soc/codecs/wm8737.c b/sound/soc/codecs/wm8737.c index 2301338cb2c9..30c67d06a904 100644 --- a/sound/soc/codecs/wm8737.c +++ b/sound/soc/codecs/wm8737.c @@ -560,7 +560,6 @@ static int wm8737_probe(struct snd_soc_codec *codec) struct wm8737_priv *wm8737 = snd_soc_codec_get_drvdata(codec); int ret, i; - codec->hw_write = (hw_write_t)i2c_master_send; ret = snd_soc_codec_set_cache_io(codec, 7, 9, wm8737->control_type); if (ret != 0) { dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret); -- cgit v1.2.3 From 559e0df6b3ffbc218a11bb9dada5320a217cb7a6 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 31 Aug 2010 19:25:12 +0100 Subject: mfd: Add initial WM8958 support The WM8958 is a derivative of the WM8994 which is register compatible with the addition of some extra features, mostly in the CODEC side. The major change visible at the MFD level is that rather than a single DBVDD supply we now have three separate DBVDDs so we must request and enable a different set of supplies. Signed-off-by: Mark Brown Acked-by: Samuel Ortiz Acked-by: Liam Girdwood --- drivers/mfd/wm8994-core.c | 93 ++++++++++++++++++++++++++++++++--------- include/linux/mfd/wm8994/core.h | 8 ++++ 2 files changed, 82 insertions(+), 19 deletions(-) diff --git a/drivers/mfd/wm8994-core.c b/drivers/mfd/wm8994-core.c index b3b2aaf89dbe..8d221ba5e38d 100644 --- a/drivers/mfd/wm8994-core.c +++ b/drivers/mfd/wm8994-core.c @@ -218,6 +218,18 @@ static const char *wm8994_main_supplies[] = { "SPKVDD2", }; +static const char *wm8958_main_supplies[] = { + "DBVDD1", + "DBVDD2", + "DBVDD3", + "DCVDD", + "AVDD1", + "AVDD2", + "CPVDD", + "SPKVDD1", + "SPKVDD2", +}; + #ifdef CONFIG_PM static int wm8994_device_suspend(struct device *dev) { @@ -239,7 +251,7 @@ static int wm8994_device_suspend(struct device *dev) if (ret < 0) dev_err(dev, "Failed to save LDO registers: %d\n", ret); - ret = regulator_bulk_disable(ARRAY_SIZE(wm8994_main_supplies), + ret = regulator_bulk_disable(wm8994->num_supplies, wm8994->supplies); if (ret != 0) { dev_err(dev, "Failed to disable supplies: %d\n", ret); @@ -254,7 +266,7 @@ static int wm8994_device_resume(struct device *dev) struct wm8994 *wm8994 = dev_get_drvdata(dev); int ret; - ret = regulator_bulk_enable(ARRAY_SIZE(wm8994_main_supplies), + ret = regulator_bulk_enable(wm8994->num_supplies, wm8994->supplies); if (ret != 0) { dev_err(dev, "Failed to enable supplies: %d\n", ret); @@ -305,9 +317,10 @@ static int wm8994_ldo_in_use(struct wm8994_pdata *pdata, int ldo) /* * Instantiate the generic non-control parts of the device. */ -static int wm8994_device_init(struct wm8994 *wm8994, unsigned long id, int irq) +static int wm8994_device_init(struct wm8994 *wm8994, int irq) { struct wm8994_pdata *pdata = wm8994->dev->platform_data; + const char *devname; int ret, i; mutex_init(&wm8994->io_lock); @@ -323,25 +336,48 @@ static int wm8994_device_init(struct wm8994 *wm8994, unsigned long id, int irq) goto err; } + switch (wm8994->type) { + case WM8994: + wm8994->num_supplies = ARRAY_SIZE(wm8994_main_supplies); + break; + case WM8958: + wm8994->num_supplies = ARRAY_SIZE(wm8958_main_supplies); + break; + default: + BUG(); + return -EINVAL; + } + wm8994->supplies = kzalloc(sizeof(struct regulator_bulk_data) * - ARRAY_SIZE(wm8994_main_supplies), + wm8994->num_supplies, GFP_KERNEL); if (!wm8994->supplies) { ret = -ENOMEM; goto err; } - for (i = 0; i < ARRAY_SIZE(wm8994_main_supplies); i++) - wm8994->supplies[i].supply = wm8994_main_supplies[i]; - - ret = regulator_bulk_get(wm8994->dev, ARRAY_SIZE(wm8994_main_supplies), + switch (wm8994->type) { + case WM8994: + for (i = 0; i < ARRAY_SIZE(wm8994_main_supplies); i++) + wm8994->supplies[i].supply = wm8994_main_supplies[i]; + break; + case WM8958: + for (i = 0; i < ARRAY_SIZE(wm8958_main_supplies); i++) + wm8994->supplies[i].supply = wm8958_main_supplies[i]; + break; + default: + BUG(); + return -EINVAL; + } + + ret = regulator_bulk_get(wm8994->dev, wm8994->num_supplies, wm8994->supplies); if (ret != 0) { dev_err(wm8994->dev, "Failed to get supplies: %d\n", ret); goto err_supplies; } - ret = regulator_bulk_enable(ARRAY_SIZE(wm8994_main_supplies), + ret = regulator_bulk_enable(wm8994->num_supplies, wm8994->supplies); if (ret != 0) { dev_err(wm8994->dev, "Failed to enable supplies: %d\n", ret); @@ -353,7 +389,22 @@ static int wm8994_device_init(struct wm8994 *wm8994, unsigned long id, int irq) dev_err(wm8994->dev, "Failed to read ID register\n"); goto err_enable; } - if (ret != 0x8994) { + switch (ret) { + case 0x8994: + devname = "WM8994"; + if (wm8994->type != WM8994) + dev_warn(wm8994->dev, "Device registered as type %d\n", + wm8994->type); + wm8994->type = WM8994; + break; + case 0x8958: + devname = "WM8958"; + if (wm8994->type != WM8958) + dev_warn(wm8994->dev, "Device registered as type %d\n", + wm8994->type); + wm8994->type = WM8958; + break; + default: dev_err(wm8994->dev, "Device is not a WM8994, ID is %x\n", ret); ret = -EINVAL; @@ -370,14 +421,16 @@ static int wm8994_device_init(struct wm8994 *wm8994, unsigned long id, int irq) switch (ret) { case 0: case 1: - dev_warn(wm8994->dev, "revision %c not fully supported\n", - 'A' + ret); + if (wm8994->type == WM8994) + dev_warn(wm8994->dev, + "revision %c not fully supported\n", + 'A' + ret); break; default: - dev_info(wm8994->dev, "revision %c\n", 'A' + ret); break; } + dev_info(wm8994->dev, "%s revision %c\n", devname, 'A' + ret); if (pdata) { wm8994->irq_base = pdata->irq_base; @@ -423,10 +476,10 @@ static int wm8994_device_init(struct wm8994 *wm8994, unsigned long id, int irq) err_irq: wm8994_irq_exit(wm8994); err_enable: - regulator_bulk_disable(ARRAY_SIZE(wm8994_main_supplies), + regulator_bulk_disable(wm8994->num_supplies, wm8994->supplies); err_get: - regulator_bulk_free(ARRAY_SIZE(wm8994_main_supplies), wm8994->supplies); + regulator_bulk_free(wm8994->num_supplies, wm8994->supplies); err_supplies: kfree(wm8994->supplies); err: @@ -439,9 +492,9 @@ static void wm8994_device_exit(struct wm8994 *wm8994) { mfd_remove_devices(wm8994->dev); wm8994_irq_exit(wm8994); - regulator_bulk_disable(ARRAY_SIZE(wm8994_main_supplies), + regulator_bulk_disable(wm8994->num_supplies, wm8994->supplies); - regulator_bulk_free(ARRAY_SIZE(wm8994_main_supplies), wm8994->supplies); + regulator_bulk_free(wm8994->num_supplies, wm8994->supplies); kfree(wm8994->supplies); kfree(wm8994); } @@ -506,8 +559,9 @@ static int wm8994_i2c_probe(struct i2c_client *i2c, wm8994->read_dev = wm8994_i2c_read_device; wm8994->write_dev = wm8994_i2c_write_device; wm8994->irq = i2c->irq; + wm8994->type = id->driver_data; - return wm8994_device_init(wm8994, id->driver_data, i2c->irq); + return wm8994_device_init(wm8994, i2c->irq); } static int wm8994_i2c_remove(struct i2c_client *i2c) @@ -535,7 +589,8 @@ static int wm8994_i2c_resume(struct i2c_client *i2c) #endif static const struct i2c_device_id wm8994_i2c_id[] = { - { "wm8994", 0 }, + { "wm8994", WM8994 }, + { "wm8958", WM8958 }, { } }; MODULE_DEVICE_TABLE(i2c, wm8994_i2c_id); diff --git a/include/linux/mfd/wm8994/core.h b/include/linux/mfd/wm8994/core.h index de79baee4925..3fd36845ca45 100644 --- a/include/linux/mfd/wm8994/core.h +++ b/include/linux/mfd/wm8994/core.h @@ -17,6 +17,11 @@ #include +enum wm8994_type { + WM8994 = 0, + WM8958 = 1, +}; + struct regulator_dev; struct regulator_bulk_data; @@ -48,6 +53,8 @@ struct wm8994 { struct mutex io_lock; struct mutex irq_lock; + enum wm8994_type type; + struct device *dev; int (*read_dev)(struct wm8994 *wm8994, unsigned short reg, int bytes, void *dest); @@ -68,6 +75,7 @@ struct wm8994 { u16 gpio_regs[WM8994_NUM_GPIO_REGS]; struct regulator_dev *dbvdd; + int num_supplies; struct regulator_bulk_data *supplies; }; -- cgit v1.2.3 From 4b666729010cbf315c9099b956b193df8edc6753 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 1 Sep 2010 10:47:16 +0100 Subject: gpiolib: Add WM8958 support to the WM8994 driver Several of the GPIOs on the WM8994 are fixed function on the WM8958 so error out if the user tries to request them with gpiolib. Signed-off-by: Mark Brown Acked-by: Liam Girdwood --- drivers/gpio/wm8994-gpio.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/drivers/gpio/wm8994-gpio.c b/drivers/gpio/wm8994-gpio.c index 618398e4ed8e..c822baacd8fc 100644 --- a/drivers/gpio/wm8994-gpio.c +++ b/drivers/gpio/wm8994-gpio.c @@ -35,6 +35,29 @@ static inline struct wm8994_gpio *to_wm8994_gpio(struct gpio_chip *chip) return container_of(chip, struct wm8994_gpio, gpio_chip); } +static int wm8994_gpio_request(struct gpio_chip *chip, unsigned offset) +{ + struct wm8994_gpio *wm8994_gpio = to_wm8994_gpio(chip); + struct wm8994 *wm8994 = wm8994_gpio->wm8994; + + switch (wm8994->type) { + case WM8958: + switch (offset) { + case 1: + case 2: + case 3: + case 4: + case 6: + return -EINVAL; + } + break; + default: + break; + } + + return 0; +} + static int wm8994_gpio_direction_in(struct gpio_chip *chip, unsigned offset) { struct wm8994_gpio *wm8994_gpio = to_wm8994_gpio(chip); @@ -136,6 +159,7 @@ static void wm8994_gpio_dbg_show(struct seq_file *s, struct gpio_chip *chip) static struct gpio_chip template_chip = { .label = "wm8994", .owner = THIS_MODULE, + .request = wm8994_gpio_request, .direction_input = wm8994_gpio_direction_in, .get = wm8994_gpio_get, .direction_output = wm8994_gpio_direction_out, -- cgit v1.2.3 From c8484594aeafe889269bd01232049b184140de3f Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Sat, 27 Nov 2010 16:30:39 +0800 Subject: crypto: Use vzalloc Signed-off-by: Joe Perches Signed-off-by: Herbert Xu --- crypto/deflate.c | 3 +-- crypto/zlib.c | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/crypto/deflate.c b/crypto/deflate.c index 463dc859aa05..cbc7a33a9600 100644 --- a/crypto/deflate.c +++ b/crypto/deflate.c @@ -48,12 +48,11 @@ static int deflate_comp_init(struct deflate_ctx *ctx) int ret = 0; struct z_stream_s *stream = &ctx->comp_stream; - stream->workspace = vmalloc(zlib_deflate_workspacesize()); + stream->workspace = vzalloc(zlib_deflate_workspacesize()); if (!stream->workspace) { ret = -ENOMEM; goto out; } - memset(stream->workspace, 0, zlib_deflate_workspacesize()); ret = zlib_deflateInit2(stream, DEFLATE_DEF_LEVEL, Z_DEFLATED, -DEFLATE_DEF_WINBITS, DEFLATE_DEF_MEMLEVEL, Z_DEFAULT_STRATEGY); diff --git a/crypto/zlib.c b/crypto/zlib.c index c3015733c990..739b8fca4cea 100644 --- a/crypto/zlib.c +++ b/crypto/zlib.c @@ -95,11 +95,10 @@ static int zlib_compress_setup(struct crypto_pcomp *tfm, void *params, zlib_comp_exit(ctx); workspacesize = zlib_deflate_workspacesize(); - stream->workspace = vmalloc(workspacesize); + stream->workspace = vzalloc(workspacesize); if (!stream->workspace) return -ENOMEM; - memset(stream->workspace, 0, workspacesize); ret = zlib_deflateInit2(stream, tb[ZLIB_COMP_LEVEL] ? nla_get_u32(tb[ZLIB_COMP_LEVEL]) -- cgit v1.2.3 From 21ea28abcf825729f9698afd7357dfbf7040d4f8 Mon Sep 17 00:00:00 2001 From: Tracey Dent Date: Sat, 27 Nov 2010 16:32:57 +0800 Subject: crypto: Makefile clean up Changed Makefile to use -y instead of -objs. Signed-off-by: Tracey Dent Signed-off-by: Herbert Xu --- crypto/Makefile | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/crypto/Makefile b/crypto/Makefile index efc0f18dbb37..e9a399ca69db 100644 --- a/crypto/Makefile +++ b/crypto/Makefile @@ -3,32 +3,32 @@ # obj-$(CONFIG_CRYPTO) += crypto.o -crypto-objs := api.o cipher.o compress.o +crypto-y := api.o cipher.o compress.o obj-$(CONFIG_CRYPTO_WORKQUEUE) += crypto_wq.o obj-$(CONFIG_CRYPTO_FIPS) += fips.o crypto_algapi-$(CONFIG_PROC_FS) += proc.o -crypto_algapi-objs := algapi.o scatterwalk.o $(crypto_algapi-y) +crypto_algapi-y := algapi.o scatterwalk.o $(crypto_algapi-y) obj-$(CONFIG_CRYPTO_ALGAPI2) += crypto_algapi.o obj-$(CONFIG_CRYPTO_AEAD2) += aead.o -crypto_blkcipher-objs := ablkcipher.o -crypto_blkcipher-objs += blkcipher.o +crypto_blkcipher-y := ablkcipher.o +crypto_blkcipher-y += blkcipher.o obj-$(CONFIG_CRYPTO_BLKCIPHER2) += crypto_blkcipher.o obj-$(CONFIG_CRYPTO_BLKCIPHER2) += chainiv.o obj-$(CONFIG_CRYPTO_BLKCIPHER2) += eseqiv.o obj-$(CONFIG_CRYPTO_SEQIV) += seqiv.o -crypto_hash-objs += ahash.o -crypto_hash-objs += shash.o +crypto_hash-y += ahash.o +crypto_hash-y += shash.o obj-$(CONFIG_CRYPTO_HASH2) += crypto_hash.o obj-$(CONFIG_CRYPTO_PCOMP2) += pcompress.o -cryptomgr-objs := algboss.o testmgr.o +cryptomgr-y := algboss.o testmgr.o obj-$(CONFIG_CRYPTO_MANAGER2) += cryptomgr.o obj-$(CONFIG_CRYPTO_HMAC) += hmac.o -- cgit v1.2.3 From 0d258efb6a58fe047197c3b9cff8746bb176d58a Mon Sep 17 00:00:00 2001 From: Mathias Krause Date: Sat, 27 Nov 2010 16:34:46 +0800 Subject: crypto: aesni-intel - Ported implementation to x86-32 The AES-NI instructions are also available in legacy mode so the 32-bit architecture may profit from those, too. To illustrate the performance gain here's a short summary of a dm-crypt speed test on a Core i7 M620 running at 2.67GHz comparing both assembler implementations: x86: i568 aes-ni delta ECB, 256 bit: 93.8 MB/s 123.3 MB/s +31.4% CBC, 256 bit: 84.8 MB/s 262.3 MB/s +209.3% LRW, 256 bit: 108.6 MB/s 222.1 MB/s +104.5% XTS, 256 bit: 105.0 MB/s 205.5 MB/s +95.7% Additionally, due to some minor optimizations, the 64-bit version also got a minor performance gain as seen below: x86-64: old impl. new impl. delta ECB, 256 bit: 121.1 MB/s 123.0 MB/s +1.5% CBC, 256 bit: 285.3 MB/s 290.8 MB/s +1.9% LRW, 256 bit: 263.7 MB/s 265.3 MB/s +0.6% XTS, 256 bit: 251.1 MB/s 255.3 MB/s +1.7% Signed-off-by: Mathias Krause Reviewed-by: Huang Ying Signed-off-by: Herbert Xu --- arch/x86/crypto/aesni-intel_asm.S | 197 +++++++++++++++++++++++++++++++------ arch/x86/crypto/aesni-intel_glue.c | 22 ++++- crypto/Kconfig | 12 ++- 3 files changed, 191 insertions(+), 40 deletions(-) diff --git a/arch/x86/crypto/aesni-intel_asm.S b/arch/x86/crypto/aesni-intel_asm.S index aafced54df64..f592e03dc375 100644 --- a/arch/x86/crypto/aesni-intel_asm.S +++ b/arch/x86/crypto/aesni-intel_asm.S @@ -20,6 +20,9 @@ * Wajdi Feghali (wajdi.k.feghali@intel.com) * Copyright (c) 2010, Intel Corporation. * + * Ported x86_64 version to x86: + * Author: Mathias Krause + * * 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 @@ -95,12 +98,16 @@ enc: .octa 0x2 #define IN IN1 #define KEY %xmm2 #define IV %xmm3 + #define BSWAP_MASK %xmm10 #define CTR %xmm11 #define INC %xmm12 +#ifdef __x86_64__ +#define AREG %rax #define KEYP %rdi #define OUTP %rsi +#define UKEYP OUTP #define INP %rdx #define LEN %rcx #define IVP %r8 @@ -109,6 +116,18 @@ enc: .octa 0x2 #define TKEYP T1 #define T2 %r11 #define TCTR_LOW T2 +#else +#define AREG %eax +#define KEYP %edi +#define OUTP AREG +#define UKEYP OUTP +#define INP %edx +#define LEN %esi +#define IVP %ebp +#define KLEN %ebx +#define T1 %ecx +#define TKEYP T1 +#endif /* GHASH_MUL MACRO to implement: Data*HashKey mod (128,127,126,121,0) @@ -1247,10 +1266,11 @@ _key_expansion_256a: shufps $0b10001100, %xmm0, %xmm4 pxor %xmm4, %xmm0 pxor %xmm1, %xmm0 - movaps %xmm0, (%rcx) - add $0x10, %rcx + movaps %xmm0, (TKEYP) + add $0x10, TKEYP ret +.align 4 _key_expansion_192a: pshufd $0b01010101, %xmm1, %xmm1 shufps $0b00010000, %xmm0, %xmm4 @@ -1268,12 +1288,13 @@ _key_expansion_192a: movaps %xmm0, %xmm1 shufps $0b01000100, %xmm0, %xmm6 - movaps %xmm6, (%rcx) + movaps %xmm6, (TKEYP) shufps $0b01001110, %xmm2, %xmm1 - movaps %xmm1, 16(%rcx) - add $0x20, %rcx + movaps %xmm1, 0x10(TKEYP) + add $0x20, TKEYP ret +.align 4 _key_expansion_192b: pshufd $0b01010101, %xmm1, %xmm1 shufps $0b00010000, %xmm0, %xmm4 @@ -1288,10 +1309,11 @@ _key_expansion_192b: pxor %xmm3, %xmm2 pxor %xmm5, %xmm2 - movaps %xmm0, (%rcx) - add $0x10, %rcx + movaps %xmm0, (TKEYP) + add $0x10, TKEYP ret +.align 4 _key_expansion_256b: pshufd $0b10101010, %xmm1, %xmm1 shufps $0b00010000, %xmm2, %xmm4 @@ -1299,8 +1321,8 @@ _key_expansion_256b: shufps $0b10001100, %xmm2, %xmm4 pxor %xmm4, %xmm2 pxor %xmm1, %xmm2 - movaps %xmm2, (%rcx) - add $0x10, %rcx + movaps %xmm2, (TKEYP) + add $0x10, TKEYP ret /* @@ -1308,17 +1330,23 @@ _key_expansion_256b: * unsigned int key_len) */ ENTRY(aesni_set_key) - movups (%rsi), %xmm0 # user key (first 16 bytes) - movaps %xmm0, (%rdi) - lea 0x10(%rdi), %rcx # key addr - movl %edx, 480(%rdi) +#ifndef __x86_64__ + pushl KEYP + movl 8(%esp), KEYP # ctx + movl 12(%esp), UKEYP # in_key + movl 16(%esp), %edx # key_len +#endif + movups (UKEYP), %xmm0 # user key (first 16 bytes) + movaps %xmm0, (KEYP) + lea 0x10(KEYP), TKEYP # key addr + movl %edx, 480(KEYP) pxor %xmm4, %xmm4 # xmm4 is assumed 0 in _key_expansion_x cmp $24, %dl jb .Lenc_key128 je .Lenc_key192 - movups 0x10(%rsi), %xmm2 # other user key - movaps %xmm2, (%rcx) - add $0x10, %rcx + movups 0x10(UKEYP), %xmm2 # other user key + movaps %xmm2, (TKEYP) + add $0x10, TKEYP AESKEYGENASSIST 0x1 %xmm2 %xmm1 # round 1 call _key_expansion_256a AESKEYGENASSIST 0x1 %xmm0 %xmm1 @@ -1347,7 +1375,7 @@ ENTRY(aesni_set_key) call _key_expansion_256a jmp .Ldec_key .Lenc_key192: - movq 0x10(%rsi), %xmm2 # other user key + movq 0x10(UKEYP), %xmm2 # other user key AESKEYGENASSIST 0x1 %xmm2 %xmm1 # round 1 call _key_expansion_192a AESKEYGENASSIST 0x2 %xmm2 %xmm1 # round 2 @@ -1387,33 +1415,47 @@ ENTRY(aesni_set_key) AESKEYGENASSIST 0x36 %xmm0 %xmm1 # round 10 call _key_expansion_128 .Ldec_key: - sub $0x10, %rcx - movaps (%rdi), %xmm0 - movaps (%rcx), %xmm1 - movaps %xmm0, 240(%rcx) - movaps %xmm1, 240(%rdi) - add $0x10, %rdi - lea 240-16(%rcx), %rsi + sub $0x10, TKEYP + movaps (KEYP), %xmm0 + movaps (TKEYP), %xmm1 + movaps %xmm0, 240(TKEYP) + movaps %xmm1, 240(KEYP) + add $0x10, KEYP + lea 240-16(TKEYP), UKEYP .align 4 .Ldec_key_loop: - movaps (%rdi), %xmm0 + movaps (KEYP), %xmm0 AESIMC %xmm0 %xmm1 - movaps %xmm1, (%rsi) - add $0x10, %rdi - sub $0x10, %rsi - cmp %rcx, %rdi + movaps %xmm1, (UKEYP) + add $0x10, KEYP + sub $0x10, UKEYP + cmp TKEYP, KEYP jb .Ldec_key_loop - xor %rax, %rax + xor AREG, AREG +#ifndef __x86_64__ + popl KEYP +#endif ret /* * void aesni_enc(struct crypto_aes_ctx *ctx, u8 *dst, const u8 *src) */ ENTRY(aesni_enc) +#ifndef __x86_64__ + pushl KEYP + pushl KLEN + movl 12(%esp), KEYP + movl 16(%esp), OUTP + movl 20(%esp), INP +#endif movl 480(KEYP), KLEN # key length movups (INP), STATE # input call _aesni_enc1 movups STATE, (OUTP) # output +#ifndef __x86_64__ + popl KLEN + popl KEYP +#endif ret /* @@ -1428,6 +1470,7 @@ ENTRY(aesni_enc) * KEY * TKEYP (T1) */ +.align 4 _aesni_enc1: movaps (KEYP), KEY # key mov KEYP, TKEYP @@ -1490,6 +1533,7 @@ _aesni_enc1: * KEY * TKEYP (T1) */ +.align 4 _aesni_enc4: movaps (KEYP), KEY # key mov KEYP, TKEYP @@ -1583,11 +1627,22 @@ _aesni_enc4: * void aesni_dec (struct crypto_aes_ctx *ctx, u8 *dst, const u8 *src) */ ENTRY(aesni_dec) +#ifndef __x86_64__ + pushl KEYP + pushl KLEN + movl 12(%esp), KEYP + movl 16(%esp), OUTP + movl 20(%esp), INP +#endif mov 480(KEYP), KLEN # key length add $240, KEYP movups (INP), STATE # input call _aesni_dec1 movups STATE, (OUTP) #output +#ifndef __x86_64__ + popl KLEN + popl KEYP +#endif ret /* @@ -1602,6 +1657,7 @@ ENTRY(aesni_dec) * KEY * TKEYP (T1) */ +.align 4 _aesni_dec1: movaps (KEYP), KEY # key mov KEYP, TKEYP @@ -1664,6 +1720,7 @@ _aesni_dec1: * KEY * TKEYP (T1) */ +.align 4 _aesni_dec4: movaps (KEYP), KEY # key mov KEYP, TKEYP @@ -1758,6 +1815,15 @@ _aesni_dec4: * size_t len) */ ENTRY(aesni_ecb_enc) +#ifndef __x86_64__ + pushl LEN + pushl KEYP + pushl KLEN + movl 16(%esp), KEYP + movl 20(%esp), OUTP + movl 24(%esp), INP + movl 28(%esp), LEN +#endif test LEN, LEN # check length jz .Lecb_enc_ret mov 480(KEYP), KLEN @@ -1794,6 +1860,11 @@ ENTRY(aesni_ecb_enc) cmp $16, LEN jge .Lecb_enc_loop1 .Lecb_enc_ret: +#ifndef __x86_64__ + popl KLEN + popl KEYP + popl LEN +#endif ret /* @@ -1801,6 +1872,15 @@ ENTRY(aesni_ecb_enc) * size_t len); */ ENTRY(aesni_ecb_dec) +#ifndef __x86_64__ + pushl LEN + pushl KEYP + pushl KLEN + movl 16(%esp), KEYP + movl 20(%esp), OUTP + movl 24(%esp), INP + movl 28(%esp), LEN +#endif test LEN, LEN jz .Lecb_dec_ret mov 480(KEYP), KLEN @@ -1838,6 +1918,11 @@ ENTRY(aesni_ecb_dec) cmp $16, LEN jge .Lecb_dec_loop1 .Lecb_dec_ret: +#ifndef __x86_64__ + popl KLEN + popl KEYP + popl LEN +#endif ret /* @@ -1845,6 +1930,17 @@ ENTRY(aesni_ecb_dec) * size_t len, u8 *iv) */ ENTRY(aesni_cbc_enc) +#ifndef __x86_64__ + pushl IVP + pushl LEN + pushl KEYP + pushl KLEN + movl 20(%esp), KEYP + movl 24(%esp), OUTP + movl 28(%esp), INP + movl 32(%esp), LEN + movl 36(%esp), IVP +#endif cmp $16, LEN jb .Lcbc_enc_ret mov 480(KEYP), KLEN @@ -1862,6 +1958,12 @@ ENTRY(aesni_cbc_enc) jge .Lcbc_enc_loop movups STATE, (IVP) .Lcbc_enc_ret: +#ifndef __x86_64__ + popl KLEN + popl KEYP + popl LEN + popl IVP +#endif ret /* @@ -1869,6 +1971,17 @@ ENTRY(aesni_cbc_enc) * size_t len, u8 *iv) */ ENTRY(aesni_cbc_dec) +#ifndef __x86_64__ + pushl IVP + pushl LEN + pushl KEYP + pushl KLEN + movl 20(%esp), KEYP + movl 24(%esp), OUTP + movl 28(%esp), INP + movl 32(%esp), LEN + movl 36(%esp), IVP +#endif cmp $16, LEN jb .Lcbc_dec_just_ret mov 480(KEYP), KLEN @@ -1882,16 +1995,30 @@ ENTRY(aesni_cbc_dec) movaps IN1, STATE1 movups 0x10(INP), IN2 movaps IN2, STATE2 +#ifdef __x86_64__ movups 0x20(INP), IN3 movaps IN3, STATE3 movups 0x30(INP), IN4 movaps IN4, STATE4 +#else + movups 0x20(INP), IN1 + movaps IN1, STATE3 + movups 0x30(INP), IN2 + movaps IN2, STATE4 +#endif call _aesni_dec4 pxor IV, STATE1 +#ifdef __x86_64__ pxor IN1, STATE2 pxor IN2, STATE3 pxor IN3, STATE4 movaps IN4, IV +#else + pxor (INP), STATE2 + pxor 0x10(INP), STATE3 + pxor IN1, STATE4 + movaps IN2, IV +#endif movups STATE1, (OUTP) movups STATE2, 0x10(OUTP) movups STATE3, 0x20(OUTP) @@ -1919,8 +2046,15 @@ ENTRY(aesni_cbc_dec) .Lcbc_dec_ret: movups IV, (IVP) .Lcbc_dec_just_ret: +#ifndef __x86_64__ + popl KLEN + popl KEYP + popl LEN + popl IVP +#endif ret +#ifdef __x86_64__ .align 16 .Lbswap_mask: .byte 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 @@ -1936,6 +2070,7 @@ ENTRY(aesni_cbc_dec) * INC: == 1, in little endian * BSWAP_MASK == endian swapping mask */ +.align 4 _aesni_inc_init: movaps .Lbswap_mask, BSWAP_MASK movaps IV, CTR @@ -1960,6 +2095,7 @@ _aesni_inc_init: * CTR: == output IV, in little endian * TCTR_LOW: == lower qword of CTR */ +.align 4 _aesni_inc: paddq INC, CTR add $1, TCTR_LOW @@ -2031,3 +2167,4 @@ ENTRY(aesni_ctr_enc) movups IV, (IVP) .Lctr_enc_just_ret: ret +#endif diff --git a/arch/x86/crypto/aesni-intel_glue.c b/arch/x86/crypto/aesni-intel_glue.c index 02d349d64423..8a3b80075216 100644 --- a/arch/x86/crypto/aesni-intel_glue.c +++ b/arch/x86/crypto/aesni-intel_glue.c @@ -94,8 +94,10 @@ asmlinkage void aesni_cbc_enc(struct crypto_aes_ctx *ctx, u8 *out, const u8 *in, unsigned int len, u8 *iv); asmlinkage void aesni_cbc_dec(struct crypto_aes_ctx *ctx, u8 *out, const u8 *in, unsigned int len, u8 *iv); +#ifdef CONFIG_X86_64 asmlinkage void aesni_ctr_enc(struct crypto_aes_ctx *ctx, u8 *out, const u8 *in, unsigned int len, u8 *iv); +#endif /* asmlinkage void aesni_gcm_enc() * void *ctx, AES Key schedule. Starts on a 16 byte boundary. @@ -410,6 +412,7 @@ static struct crypto_alg blk_cbc_alg = { }, }; +#ifdef CONFIG_X86_64 static void ctr_crypt_final(struct crypto_aes_ctx *ctx, struct blkcipher_walk *walk) { @@ -475,6 +478,7 @@ static struct crypto_alg blk_ctr_alg = { }, }, }; +#endif static int ablk_set_key(struct crypto_ablkcipher *tfm, const u8 *key, unsigned int key_len) @@ -622,6 +626,7 @@ static struct crypto_alg ablk_cbc_alg = { }, }; +#ifdef CONFIG_X86_64 static int ablk_ctr_init(struct crypto_tfm *tfm) { struct cryptd_ablkcipher *cryptd_tfm; @@ -698,6 +703,7 @@ static struct crypto_alg ablk_rfc3686_ctr_alg = { }, }; #endif +#endif #ifdef HAS_LRW static int ablk_lrw_init(struct crypto_tfm *tfm) @@ -1249,18 +1255,20 @@ static int __init aesni_init(void) goto blk_ecb_err; if ((err = crypto_register_alg(&blk_cbc_alg))) goto blk_cbc_err; - if ((err = crypto_register_alg(&blk_ctr_alg))) - goto blk_ctr_err; if ((err = crypto_register_alg(&ablk_ecb_alg))) goto ablk_ecb_err; if ((err = crypto_register_alg(&ablk_cbc_alg))) goto ablk_cbc_err; +#ifdef CONFIG_X86_64 + if ((err = crypto_register_alg(&blk_ctr_alg))) + goto blk_ctr_err; if ((err = crypto_register_alg(&ablk_ctr_alg))) goto ablk_ctr_err; #ifdef HAS_CTR if ((err = crypto_register_alg(&ablk_rfc3686_ctr_alg))) goto ablk_rfc3686_ctr_err; #endif +#endif #ifdef HAS_LRW if ((err = crypto_register_alg(&ablk_lrw_alg))) goto ablk_lrw_err; @@ -1296,18 +1304,20 @@ ablk_pcbc_err: crypto_unregister_alg(&ablk_lrw_alg); ablk_lrw_err: #endif +#ifdef CONFIG_X86_64 #ifdef HAS_CTR crypto_unregister_alg(&ablk_rfc3686_ctr_alg); ablk_rfc3686_ctr_err: #endif crypto_unregister_alg(&ablk_ctr_alg); ablk_ctr_err: + crypto_unregister_alg(&blk_ctr_alg); +blk_ctr_err: +#endif crypto_unregister_alg(&ablk_cbc_alg); ablk_cbc_err: crypto_unregister_alg(&ablk_ecb_alg); ablk_ecb_err: - crypto_unregister_alg(&blk_ctr_alg); -blk_ctr_err: crypto_unregister_alg(&blk_cbc_alg); blk_cbc_err: crypto_unregister_alg(&blk_ecb_alg); @@ -1332,13 +1342,15 @@ static void __exit aesni_exit(void) #ifdef HAS_LRW crypto_unregister_alg(&ablk_lrw_alg); #endif +#ifdef CONFIG_X86_64 #ifdef HAS_CTR crypto_unregister_alg(&ablk_rfc3686_ctr_alg); #endif crypto_unregister_alg(&ablk_ctr_alg); + crypto_unregister_alg(&blk_ctr_alg); +#endif crypto_unregister_alg(&ablk_cbc_alg); crypto_unregister_alg(&ablk_ecb_alg); - crypto_unregister_alg(&blk_ctr_alg); crypto_unregister_alg(&blk_cbc_alg); crypto_unregister_alg(&blk_ecb_alg); crypto_unregister_alg(&__aesni_alg); diff --git a/crypto/Kconfig b/crypto/Kconfig index 69437e21217f..467491df3e3a 100644 --- a/crypto/Kconfig +++ b/crypto/Kconfig @@ -539,8 +539,9 @@ config CRYPTO_AES_X86_64 config CRYPTO_AES_NI_INTEL tristate "AES cipher algorithms (AES-NI)" - depends on (X86 || UML_X86) && 64BIT - select CRYPTO_AES_X86_64 + depends on (X86 || UML_X86) + select CRYPTO_AES_X86_64 if 64BIT + select CRYPTO_AES_586 if !64BIT select CRYPTO_CRYPTD select CRYPTO_ALGAPI select CRYPTO_FPU @@ -563,9 +564,10 @@ config CRYPTO_AES_NI_INTEL See for more information. - In addition to AES cipher algorithm support, the - acceleration for some popular block cipher mode is supported - too, including ECB, CBC, CTR, LRW, PCBC, XTS. + In addition to AES cipher algorithm support, the acceleration + for some popular block cipher mode is supported too, including + ECB, CBC, LRW, PCBC, XTS. The 64 bit version has additional + acceleration for CTR. config CRYPTO_ANUBIS tristate "Anubis cipher algorithm" -- cgit v1.2.3 From 0c3cf4cc9abd854dcc6488719348a75b8f328c54 Mon Sep 17 00:00:00 2001 From: Dmitry Kasatkin Date: Fri, 19 Nov 2010 16:04:22 +0200 Subject: crypto: omap-sham - uses digest buffer in request context Currently driver storred digest results in req->results provided by the client. But some clients do not set it until final() call. It leads to crash. Changed to use internal buffer to store temporary digest results. Signed-off-by: Dmitry Kasatkin Signed-off-by: Herbert Xu --- drivers/crypto/omap-sham.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/drivers/crypto/omap-sham.c b/drivers/crypto/omap-sham.c index a081c7c7d03f..222237014007 100644 --- a/drivers/crypto/omap-sham.c +++ b/drivers/crypto/omap-sham.c @@ -97,6 +97,7 @@ struct omap_sham_reqctx { unsigned long flags; unsigned long op; + u8 digest[SHA1_DIGEST_SIZE]; size_t digcnt; u8 *buffer; size_t bufcnt; @@ -194,7 +195,7 @@ static inline int omap_sham_wait(struct omap_sham_dev *dd, u32 offset, u32 bit) static void omap_sham_copy_hash(struct ahash_request *req, int out) { struct omap_sham_reqctx *ctx = ahash_request_ctx(req); - u32 *hash = (u32 *)req->result; + u32 *hash = (u32 *)ctx->digest; int i; if (likely(ctx->flags & FLAGS_SHA1)) { @@ -453,8 +454,11 @@ static void omap_sham_cleanup(struct ahash_request *req) ctx->flags |= FLAGS_CLEAN; spin_unlock_irqrestore(&dd->lock, flags); - if (ctx->digcnt) + if (ctx->digcnt) { clk_disable(dd->iclk); + memcpy(req->result, ctx->digest, (ctx->flags & FLAGS_SHA1) ? + SHA1_DIGEST_SIZE : MD5_DIGEST_SIZE); + } if (ctx->dma_addr) dma_unmap_single(dd->dev, ctx->dma_addr, ctx->buflen, @@ -576,6 +580,7 @@ static int omap_sham_final_req(struct omap_sham_dev *dd) static int omap_sham_finish_req_hmac(struct ahash_request *req) { + struct omap_sham_reqctx *ctx = ahash_request_ctx(req); struct omap_sham_ctx *tctx = crypto_tfm_ctx(req->base.tfm); struct omap_sham_hmac_ctx *bctx = tctx->base; int bs = crypto_shash_blocksize(bctx->shash); @@ -590,7 +595,7 @@ static int omap_sham_finish_req_hmac(struct ahash_request *req) return crypto_shash_init(&desc.shash) ?: crypto_shash_update(&desc.shash, bctx->opad, bs) ?: - crypto_shash_finup(&desc.shash, req->result, ds, req->result); + crypto_shash_finup(&desc.shash, ctx->digest, ds, ctx->digest); } static void omap_sham_finish_req(struct ahash_request *req, int err) -- cgit v1.2.3 From c8eb54041acc4dedeaf0d9da34b91b8658386751 Mon Sep 17 00:00:00 2001 From: Dmitry Kasatkin Date: Fri, 19 Nov 2010 16:04:23 +0200 Subject: crypto: omap-sham - DMA initialization fixes for off mode DMA parameters for constant data were initialized during driver probe(). It seems that those settings sometimes are lost when devices goes to off mode. This patch makes DMA initialization just before use. It solves off mode problems. Fixes: NB#202786 - Aegis & SHA1 block off mode changes Signed-off-by: Dmitry Kasatkin Signed-off-by: Herbert Xu --- drivers/crypto/omap-sham.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/drivers/crypto/omap-sham.c b/drivers/crypto/omap-sham.c index 222237014007..9dfbc4ab7711 100644 --- a/drivers/crypto/omap-sham.c +++ b/drivers/crypto/omap-sham.c @@ -318,6 +318,16 @@ static int omap_sham_xmit_dma(struct omap_sham_dev *dd, dma_addr_t dma_addr, omap_set_dma_src_params(dd->dma_lch, 0, OMAP_DMA_AMODE_POST_INC, dma_addr, 0, 0); + omap_set_dma_dest_params(dd->dma_lch, 0, + OMAP_DMA_AMODE_CONSTANT, + dd->phys_base + SHA_REG_DIN(0), 0, 16); + + omap_set_dma_dest_burst_mode(dd->dma_lch, + OMAP_DMA_DATA_BURST_16); + + omap_set_dma_src_burst_mode(dd->dma_lch, + OMAP_DMA_DATA_BURST_4); + err = omap_sham_write_ctrl(dd, length, final, 1); if (err) return err; @@ -1071,15 +1081,6 @@ static int omap_sham_dma_init(struct omap_sham_dev *dd) dev_err(dd->dev, "Unable to request DMA channel\n"); return err; } - omap_set_dma_dest_params(dd->dma_lch, 0, - OMAP_DMA_AMODE_CONSTANT, - dd->phys_base + SHA_REG_DIN(0), 0, 16); - - omap_set_dma_dest_burst_mode(dd->dma_lch, - OMAP_DMA_DATA_BURST_16); - - omap_set_dma_src_burst_mode(dd->dma_lch, - OMAP_DMA_DATA_BURST_4); return 0; } -- cgit v1.2.3 From 3e133c8bf6a6723377d94bc97aa52596e49a4090 Mon Sep 17 00:00:00 2001 From: Dmitry Kasatkin Date: Fri, 19 Nov 2010 16:04:24 +0200 Subject: crypto: omap-sham - error handling improved Introduces DMA error handling. DMA error is returned as a result code of the hash request. Clients needs to handle error codes and may repeat hash calculation attempt. Also in the case of DMA error, SHAM module is set to be re-initialized again. It significantly improves stability against possible HW failures. Signed-off-by: Dmitry Kasatkin Signed-off-by: Herbert Xu --- drivers/crypto/omap-sham.c | 67 ++++++++++++++++++++++++++++++---------------- 1 file changed, 44 insertions(+), 23 deletions(-) diff --git a/drivers/crypto/omap-sham.c b/drivers/crypto/omap-sham.c index 9dfbc4ab7711..db206284835a 100644 --- a/drivers/crypto/omap-sham.c +++ b/drivers/crypto/omap-sham.c @@ -83,6 +83,7 @@ #define FLAGS_INIT 0x0100 #define FLAGS_CPU 0x0200 #define FLAGS_HMAC 0x0400 +#define FLAGS_ERROR 0x0800 /* 3rd byte */ #define FLAGS_BUSY 16 @@ -137,6 +138,7 @@ struct omap_sham_dev { int irq; struct clk *iclk; spinlock_t lock; + int err; int dma; int dma_lch; struct tasklet_struct done_task; @@ -234,10 +236,12 @@ static int omap_sham_write_ctrl(struct omap_sham_dev *dd, size_t length, SHA_REG_MASK_SOFTRESET, SHA_REG_MASK_SOFTRESET); if (omap_sham_wait(dd, SHA_REG_SYSSTATUS, - SHA_REG_SYSSTATUS_RESETDONE)) + SHA_REG_SYSSTATUS_RESETDONE)) { + clk_disable(dd->iclk); return -ETIMEDOUT; - + } dd->flags |= FLAGS_INIT; + dd->err = 0; } } else { omap_sham_write(dd, SHA_REG_DIGCNT, ctx->digcnt); @@ -279,11 +283,12 @@ static int omap_sham_xmit_cpu(struct omap_sham_dev *dd, const u8 *buf, if (err) return err; + /* should be non-zero before next lines to disable clocks later */ + ctx->digcnt += length; + if (omap_sham_wait(dd, SHA_REG_CTRL, SHA_REG_CTRL_INPUT_READY)) return -ETIMEDOUT; - ctx->digcnt += length; - if (final) ctx->flags |= FLAGS_FINAL; /* catch last interrupt */ @@ -303,7 +308,6 @@ static int omap_sham_xmit_dma(struct omap_sham_dev *dd, dma_addr_t dma_addr, dev_dbg(dd->dev, "xmit_dma: digcnt: %d, length: %d, final: %d\n", ctx->digcnt, length, final); - /* flush cache entries related to our page */ if (dma_addr == ctx->dma_addr) dma_sync_single_for_device(dd->dev, dma_addr, length, @@ -411,6 +415,7 @@ static int omap_sham_update_dma_fast(struct omap_sham_dev *dd) { struct omap_sham_reqctx *ctx = ahash_request_ctx(dd->req); unsigned int length; + int err; ctx->flags |= FLAGS_FAST; @@ -424,7 +429,11 @@ static int omap_sham_update_dma_fast(struct omap_sham_dev *dd) ctx->total -= length; - return omap_sham_xmit_dma(dd, sg_dma_address(ctx->sg), length, 1); + err = omap_sham_xmit_dma(dd, sg_dma_address(ctx->sg), length, 1); + if (err != -EINPROGRESS) + dma_unmap_sg(dd->dev, ctx->sg, 1, DMA_TO_DEVICE); + + return err; } static int omap_sham_update_cpu(struct omap_sham_dev *dd) @@ -580,9 +589,6 @@ static int omap_sham_final_req(struct omap_sham_dev *dd) ctx->bufcnt = 0; - if (err != -EINPROGRESS) - omap_sham_cleanup(req); - dev_dbg(dd->dev, "final_req: err: %d\n", err); return err; @@ -616,9 +622,11 @@ static void omap_sham_finish_req(struct ahash_request *req, int err) omap_sham_copy_hash(ctx->dd->req, 1); if (ctx->flags & FLAGS_HMAC) err = omap_sham_finish_req_hmac(req); + } else { + ctx->flags |= FLAGS_ERROR; } - if (ctx->flags & FLAGS_FINAL) + if ((ctx->flags & FLAGS_FINAL) || err) omap_sham_cleanup(req); clear_bit(FLAGS_BUSY, &ctx->dd->flags); @@ -776,12 +784,14 @@ static int omap_sham_final(struct ahash_request *req) ctx->flags |= FLAGS_FINUP; - /* OMAP HW accel works only with buffers >= 9 */ - /* HMAC is always >= 9 because of ipad */ - if ((ctx->digcnt + ctx->bufcnt) < 9) - err = omap_sham_final_shash(req); - else if (ctx->bufcnt) - return omap_sham_enqueue(req, OP_FINAL); + if (!(ctx->flags & FLAGS_ERROR)) { + /* OMAP HW accel works only with buffers >= 9 */ + /* HMAC is always >= 9 because of ipad */ + if ((ctx->digcnt + ctx->bufcnt) < 9) + err = omap_sham_final_shash(req); + else if (ctx->bufcnt) + return omap_sham_enqueue(req, OP_FINAL); + } omap_sham_cleanup(req); @@ -851,6 +861,8 @@ static int omap_sham_cra_init_alg(struct crypto_tfm *tfm, const char *alg_base) struct omap_sham_ctx *tctx = crypto_tfm_ctx(tfm); const char *alg_name = crypto_tfm_alg_name(tfm); + pr_info("enter\n"); + /* Allocate a fallback and abort if it failed. */ tctx->fallback = crypto_alloc_shash(alg_name, 0, CRYPTO_ALG_NEED_FALLBACK); @@ -1008,7 +1020,7 @@ static void omap_sham_done_task(unsigned long data) struct omap_sham_dev *dd = (struct omap_sham_dev *)data; struct ahash_request *req = dd->req; struct omap_sham_reqctx *ctx = ahash_request_ctx(req); - int ready = 1; + int ready = 0, err = 0; if (ctx->flags & FLAGS_OUTPUT_READY) { ctx->flags &= ~FLAGS_OUTPUT_READY; @@ -1018,13 +1030,16 @@ static void omap_sham_done_task(unsigned long data) if (dd->flags & FLAGS_DMA_ACTIVE) { dd->flags &= ~FLAGS_DMA_ACTIVE; omap_sham_update_dma_stop(dd); - omap_sham_update_dma_slow(dd); + if (!dd->err) + err = omap_sham_update_dma_slow(dd); } - if (ready && !(dd->flags & FLAGS_DMA_ACTIVE)) { - dev_dbg(dd->dev, "update done\n"); + err = dd->err ? : err; + + if (err != -EINPROGRESS && (ready || err)) { + dev_dbg(dd->dev, "update done: err: %d\n", err); /* finish curent request */ - omap_sham_finish_req(req, 0); + omap_sham_finish_req(req, err); /* start new request */ omap_sham_handle_queue(dd); } @@ -1056,6 +1071,7 @@ static irqreturn_t omap_sham_irq(int irq, void *dev_id) omap_sham_read(dd, SHA_REG_CTRL); ctx->flags |= FLAGS_OUTPUT_READY; + dd->err = 0; tasklet_schedule(&dd->done_task); return IRQ_HANDLED; @@ -1065,8 +1081,13 @@ static void omap_sham_dma_callback(int lch, u16 ch_status, void *data) { struct omap_sham_dev *dd = data; - if (likely(lch == dd->dma_lch)) - tasklet_schedule(&dd->done_task); + if (ch_status != OMAP_DMA_BLOCK_IRQ) { + pr_err("omap-sham DMA error status: 0x%hx\n", ch_status); + dd->err = -EIO; + dd->flags &= ~FLAGS_INIT; /* request to re-initialize */ + } + + tasklet_schedule(&dd->done_task); } static int omap_sham_dma_init(struct omap_sham_dev *dd) -- cgit v1.2.3 From a5d87237bb15eed8449e5a30c0bbe626e0e7f43d Mon Sep 17 00:00:00 2001 From: Dmitry Kasatkin Date: Fri, 19 Nov 2010 16:04:25 +0200 Subject: crypto: omap-sham - removed redundunt locking Locking for queuing and dequeuing is combined. test_and_set_bit() is also replaced with checking under dd->lock. Signed-off-by: Dmitry Kasatkin Signed-off-by: Herbert Xu --- drivers/crypto/omap-sham.c | 47 +++++++++++++++++++++------------------------- 1 file changed, 21 insertions(+), 26 deletions(-) diff --git a/drivers/crypto/omap-sham.c b/drivers/crypto/omap-sham.c index db206284835a..6340c5ef4712 100644 --- a/drivers/crypto/omap-sham.c +++ b/drivers/crypto/omap-sham.c @@ -84,9 +84,7 @@ #define FLAGS_CPU 0x0200 #define FLAGS_HMAC 0x0400 #define FLAGS_ERROR 0x0800 - -/* 3rd byte */ -#define FLAGS_BUSY 16 +#define FLAGS_BUSY 0x1000 #define OP_UPDATE 1 #define OP_FINAL 2 @@ -629,32 +627,37 @@ static void omap_sham_finish_req(struct ahash_request *req, int err) if ((ctx->flags & FLAGS_FINAL) || err) omap_sham_cleanup(req); - clear_bit(FLAGS_BUSY, &ctx->dd->flags); + ctx->dd->flags &= ~FLAGS_BUSY; if (req->base.complete) req->base.complete(&req->base, err); } -static int omap_sham_handle_queue(struct omap_sham_dev *dd) +static int omap_sham_handle_queue(struct omap_sham_dev *dd, + struct ahash_request *req) { struct crypto_async_request *async_req, *backlog; struct omap_sham_reqctx *ctx; - struct ahash_request *req, *prev_req; + struct ahash_request *prev_req; unsigned long flags; - int err = 0; - - if (test_and_set_bit(FLAGS_BUSY, &dd->flags)) - return 0; + int err = 0, ret = 0; spin_lock_irqsave(&dd->lock, flags); - backlog = crypto_get_backlog(&dd->queue); + if (req) + ret = ahash_enqueue_request(&dd->queue, req); + if (dd->flags & FLAGS_BUSY) { + spin_unlock_irqrestore(&dd->lock, flags); + return ret; + } async_req = crypto_dequeue_request(&dd->queue); - if (!async_req) - clear_bit(FLAGS_BUSY, &dd->flags); + if (async_req) { + dd->flags |= FLAGS_BUSY; + backlog = crypto_get_backlog(&dd->queue); + } spin_unlock_irqrestore(&dd->lock, flags); if (!async_req) - return 0; + return ret; if (backlog) backlog->complete(backlog, -EINPROGRESS); @@ -690,7 +693,7 @@ static int omap_sham_handle_queue(struct omap_sham_dev *dd) dev_dbg(dd->dev, "exit, err: %d\n", err); - return err; + return ret; } static int omap_sham_enqueue(struct ahash_request *req, unsigned int op) @@ -698,18 +701,10 @@ static int omap_sham_enqueue(struct ahash_request *req, unsigned int op) struct omap_sham_reqctx *ctx = ahash_request_ctx(req); struct omap_sham_ctx *tctx = crypto_tfm_ctx(req->base.tfm); struct omap_sham_dev *dd = tctx->dd; - unsigned long flags; - int err; ctx->op = op; - spin_lock_irqsave(&dd->lock, flags); - err = ahash_enqueue_request(&dd->queue, req); - spin_unlock_irqrestore(&dd->lock, flags); - - omap_sham_handle_queue(dd); - - return err; + return omap_sham_handle_queue(dd, req); } static int omap_sham_update(struct ahash_request *req) @@ -1041,7 +1036,7 @@ static void omap_sham_done_task(unsigned long data) /* finish curent request */ omap_sham_finish_req(req, err); /* start new request */ - omap_sham_handle_queue(dd); + omap_sham_handle_queue(dd, NULL); } } @@ -1049,7 +1044,7 @@ static void omap_sham_queue_task(unsigned long data) { struct omap_sham_dev *dd = (struct omap_sham_dev *)data; - omap_sham_handle_queue(dd); + omap_sham_handle_queue(dd, NULL); } static irqreturn_t omap_sham_irq(int irq, void *dev_id) -- cgit v1.2.3 From 798eed5d9204b01862985ba0643ce5cf84114072 Mon Sep 17 00:00:00 2001 From: Dmitry Kasatkin Date: Fri, 19 Nov 2010 16:04:26 +0200 Subject: crypto: omap-sham - crypto_ahash_final() now not need to be called. According to the Herbert Xu, client may not always call crypto_ahash_final(). In the case of error in hash calculation resources will be automatically cleaned up. But if no hash calculation error happens and client will not call crypto_ahash_final() at all, then internal buffer will not be freed, and clocks will not be disabled. This patch provides support for atomic crypto_ahash_update() call. Clocks are now enabled and disabled per update request. Data buffer is now allocated as a part of request context. Client is obligated to free it with crypto_free_ahash(). Signed-off-by: Dmitry Kasatkin Signed-off-by: Herbert Xu --- drivers/crypto/omap-sham.c | 168 ++++++++++++++++++++++----------------------- 1 file changed, 82 insertions(+), 86 deletions(-) diff --git a/drivers/crypto/omap-sham.c b/drivers/crypto/omap-sham.c index 6340c5ef4712..85d627774538 100644 --- a/drivers/crypto/omap-sham.c +++ b/drivers/crypto/omap-sham.c @@ -89,6 +89,11 @@ #define OP_UPDATE 1 #define OP_FINAL 2 +#define OMAP_ALIGN_MASK (sizeof(u32)-1) +#define OMAP_ALIGNED __attribute__((aligned(sizeof(u32)))) + +#define BUFLEN PAGE_SIZE + struct omap_sham_dev; struct omap_sham_reqctx { @@ -96,9 +101,8 @@ struct omap_sham_reqctx { unsigned long flags; unsigned long op; - u8 digest[SHA1_DIGEST_SIZE]; + u8 digest[SHA1_DIGEST_SIZE] OMAP_ALIGNED; size_t digcnt; - u8 *buffer; size_t bufcnt; size_t buflen; dma_addr_t dma_addr; @@ -107,6 +111,8 @@ struct omap_sham_reqctx { struct scatterlist *sg; unsigned int offset; /* offset in current sg */ unsigned int total; /* total request */ + + u8 buffer[0] OMAP_ALIGNED; }; struct omap_sham_hmac_ctx { @@ -219,31 +225,33 @@ static void omap_sham_copy_hash(struct ahash_request *req, int out) } } -static int omap_sham_write_ctrl(struct omap_sham_dev *dd, size_t length, - int final, int dma) +static int omap_sham_hw_init(struct omap_sham_dev *dd) { - struct omap_sham_reqctx *ctx = ahash_request_ctx(dd->req); - u32 val = length << 5, mask; + clk_enable(dd->iclk); - if (unlikely(!ctx->digcnt)) { + if (!(dd->flags & FLAGS_INIT)) { + omap_sham_write_mask(dd, SHA_REG_MASK, + SHA_REG_MASK_SOFTRESET, SHA_REG_MASK_SOFTRESET); - clk_enable(dd->iclk); + if (omap_sham_wait(dd, SHA_REG_SYSSTATUS, + SHA_REG_SYSSTATUS_RESETDONE)) + return -ETIMEDOUT; - if (!(dd->flags & FLAGS_INIT)) { - omap_sham_write_mask(dd, SHA_REG_MASK, - SHA_REG_MASK_SOFTRESET, SHA_REG_MASK_SOFTRESET); + dd->flags |= FLAGS_INIT; + dd->err = 0; + } - if (omap_sham_wait(dd, SHA_REG_SYSSTATUS, - SHA_REG_SYSSTATUS_RESETDONE)) { - clk_disable(dd->iclk); - return -ETIMEDOUT; - } - dd->flags |= FLAGS_INIT; - dd->err = 0; - } - } else { + return 0; +} + +static void omap_sham_write_ctrl(struct omap_sham_dev *dd, size_t length, + int final, int dma) +{ + struct omap_sham_reqctx *ctx = ahash_request_ctx(dd->req); + u32 val = length << 5, mask; + + if (likely(ctx->digcnt)) omap_sham_write(dd, SHA_REG_DIGCNT, ctx->digcnt); - } omap_sham_write_mask(dd, SHA_REG_MASK, SHA_REG_MASK_IT_EN | (dma ? SHA_REG_MASK_DMA_EN : 0), @@ -263,23 +271,19 @@ static int omap_sham_write_ctrl(struct omap_sham_dev *dd, size_t length, SHA_REG_CTRL_ALGO | SHA_REG_CTRL_LENGTH; omap_sham_write_mask(dd, SHA_REG_CTRL, val, mask); - - return 0; } static int omap_sham_xmit_cpu(struct omap_sham_dev *dd, const u8 *buf, size_t length, int final) { struct omap_sham_reqctx *ctx = ahash_request_ctx(dd->req); - int err, count, len32; + int count, len32; const u32 *buffer = (const u32 *)buf; dev_dbg(dd->dev, "xmit_cpu: digcnt: %d, length: %d, final: %d\n", ctx->digcnt, length, final); - err = omap_sham_write_ctrl(dd, length, final, 0); - if (err) - return err; + omap_sham_write_ctrl(dd, length, final, 0); /* should be non-zero before next lines to disable clocks later */ ctx->digcnt += length; @@ -302,14 +306,10 @@ static int omap_sham_xmit_dma(struct omap_sham_dev *dd, dma_addr_t dma_addr, size_t length, int final) { struct omap_sham_reqctx *ctx = ahash_request_ctx(dd->req); - int err, len32; + int len32; dev_dbg(dd->dev, "xmit_dma: digcnt: %d, length: %d, final: %d\n", ctx->digcnt, length, final); - /* flush cache entries related to our page */ - if (dma_addr == ctx->dma_addr) - dma_sync_single_for_device(dd->dev, dma_addr, length, - DMA_TO_DEVICE); len32 = DIV_ROUND_UP(length, sizeof(u32)); @@ -320,19 +320,7 @@ static int omap_sham_xmit_dma(struct omap_sham_dev *dd, dma_addr_t dma_addr, omap_set_dma_src_params(dd->dma_lch, 0, OMAP_DMA_AMODE_POST_INC, dma_addr, 0, 0); - omap_set_dma_dest_params(dd->dma_lch, 0, - OMAP_DMA_AMODE_CONSTANT, - dd->phys_base + SHA_REG_DIN(0), 0, 16); - - omap_set_dma_dest_burst_mode(dd->dma_lch, - OMAP_DMA_DATA_BURST_16); - - omap_set_dma_src_burst_mode(dd->dma_lch, - OMAP_DMA_DATA_BURST_4); - - err = omap_sham_write_ctrl(dd, length, final, 1); - if (err) - return err; + omap_sham_write_ctrl(dd, length, final, 1); ctx->digcnt += length; @@ -384,6 +372,21 @@ static size_t omap_sham_append_sg(struct omap_sham_reqctx *ctx) return 0; } +static int omap_sham_xmit_dma_map(struct omap_sham_dev *dd, + struct omap_sham_reqctx *ctx, + size_t length, int final) +{ + ctx->dma_addr = dma_map_single(dd->dev, ctx->buffer, ctx->buflen, + DMA_TO_DEVICE); + if (dma_mapping_error(dd->dev, ctx->dma_addr)) { + dev_err(dd->dev, "dma %u bytes error\n", ctx->buflen); + return -EINVAL; + } + + /* next call does not fail... so no unmap in the case of error */ + return omap_sham_xmit_dma(dd, ctx->dma_addr, length, final); +} + static int omap_sham_update_dma_slow(struct omap_sham_dev *dd) { struct omap_sham_reqctx *ctx = ahash_request_ctx(dd->req); @@ -403,7 +406,7 @@ static int omap_sham_update_dma_slow(struct omap_sham_dev *dd) if (final || (ctx->bufcnt == ctx->buflen && ctx->total)) { count = ctx->bufcnt; ctx->bufcnt = 0; - return omap_sham_xmit_dma(dd, ctx->dma_addr, count, final); + return omap_sham_xmit_dma_map(dd, ctx, count, final); } return 0; @@ -413,7 +416,6 @@ static int omap_sham_update_dma_fast(struct omap_sham_dev *dd) { struct omap_sham_reqctx *ctx = ahash_request_ctx(dd->req); unsigned int length; - int err; ctx->flags |= FLAGS_FAST; @@ -427,11 +429,8 @@ static int omap_sham_update_dma_fast(struct omap_sham_dev *dd) ctx->total -= length; - err = omap_sham_xmit_dma(dd, sg_dma_address(ctx->sg), length, 1); - if (err != -EINPROGRESS) - dma_unmap_sg(dd->dev, ctx->sg, 1, DMA_TO_DEVICE); - - return err; + /* next call does not fail... so no unmap in the case of error */ + return omap_sham_xmit_dma(dd, sg_dma_address(ctx->sg), length, 1); } static int omap_sham_update_cpu(struct omap_sham_dev *dd) @@ -453,6 +452,9 @@ static int omap_sham_update_dma_stop(struct omap_sham_dev *dd) omap_stop_dma(dd->dma_lch); if (ctx->flags & FLAGS_FAST) dma_unmap_sg(dd->dev, ctx->sg, 1, DMA_TO_DEVICE); + else + dma_unmap_single(dd->dev, ctx->dma_addr, ctx->buflen, + DMA_TO_DEVICE); return 0; } @@ -471,18 +473,9 @@ static void omap_sham_cleanup(struct ahash_request *req) ctx->flags |= FLAGS_CLEAN; spin_unlock_irqrestore(&dd->lock, flags); - if (ctx->digcnt) { - clk_disable(dd->iclk); + if (ctx->digcnt) memcpy(req->result, ctx->digest, (ctx->flags & FLAGS_SHA1) ? SHA1_DIGEST_SIZE : MD5_DIGEST_SIZE); - } - - if (ctx->dma_addr) - dma_unmap_single(dd->dev, ctx->dma_addr, ctx->buflen, - DMA_TO_DEVICE); - - if (ctx->buffer) - free_page((unsigned long)ctx->buffer); dev_dbg(dd->dev, "digcnt: %d, bufcnt: %d\n", ctx->digcnt, ctx->bufcnt); } @@ -520,21 +513,7 @@ static int omap_sham_init(struct ahash_request *req) ctx->bufcnt = 0; ctx->digcnt = 0; - - ctx->buflen = PAGE_SIZE; - ctx->buffer = (void *)__get_free_page( - (req->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP) ? - GFP_KERNEL : GFP_ATOMIC); - if (!ctx->buffer) - return -ENOMEM; - - ctx->dma_addr = dma_map_single(dd->dev, ctx->buffer, ctx->buflen, - DMA_TO_DEVICE); - if (dma_mapping_error(dd->dev, ctx->dma_addr)) { - dev_err(dd->dev, "dma %u bytes error\n", ctx->buflen); - free_page((unsigned long)ctx->buffer); - return -EINVAL; - } + ctx->buflen = BUFLEN; if (tctx->flags & FLAGS_HMAC) { struct omap_sham_hmac_ctx *bctx = tctx->base; @@ -581,7 +560,7 @@ static int omap_sham_final_req(struct omap_sham_dev *dd) use_dma = 0; if (use_dma) - err = omap_sham_xmit_dma(dd, ctx->dma_addr, ctx->bufcnt, 1); + err = omap_sham_xmit_dma_map(dd, ctx, ctx->bufcnt, 1); else err = omap_sham_xmit_cpu(dd, ctx->buffer, ctx->bufcnt, 1); @@ -615,6 +594,7 @@ static int omap_sham_finish_req_hmac(struct ahash_request *req) static void omap_sham_finish_req(struct ahash_request *req, int err) { struct omap_sham_reqctx *ctx = ahash_request_ctx(req); + struct omap_sham_dev *dd = ctx->dd; if (!err) { omap_sham_copy_hash(ctx->dd->req, 1); @@ -627,7 +607,8 @@ static void omap_sham_finish_req(struct ahash_request *req, int err) if ((ctx->flags & FLAGS_FINAL) || err) omap_sham_cleanup(req); - ctx->dd->flags &= ~FLAGS_BUSY; + clk_disable(dd->iclk); + dd->flags &= ~FLAGS_BUSY; if (req->base.complete) req->base.complete(&req->base, err); @@ -636,7 +617,7 @@ static void omap_sham_finish_req(struct ahash_request *req, int err) static int omap_sham_handle_queue(struct omap_sham_dev *dd, struct ahash_request *req) { - struct crypto_async_request *async_req, *backlog; + struct crypto_async_request *async_req, *backlog = 0; struct omap_sham_reqctx *ctx; struct ahash_request *prev_req; unsigned long flags; @@ -672,7 +653,22 @@ static int omap_sham_handle_queue(struct omap_sham_dev *dd, dev_dbg(dd->dev, "handling new req, op: %lu, nbytes: %d\n", ctx->op, req->nbytes); - if (req != prev_req && ctx->digcnt) + + err = omap_sham_hw_init(dd); + if (err) + goto err1; + + omap_set_dma_dest_params(dd->dma_lch, 0, + OMAP_DMA_AMODE_CONSTANT, + dd->phys_base + SHA_REG_DIN(0), 0, 16); + + omap_set_dma_dest_burst_mode(dd->dma_lch, + OMAP_DMA_DATA_BURST_16); + + omap_set_dma_src_burst_mode(dd->dma_lch, + OMAP_DMA_DATA_BURST_4); + + if (ctx->digcnt) /* request has changed - restore hash */ omap_sham_copy_hash(req, 0); @@ -684,7 +680,7 @@ static int omap_sham_handle_queue(struct omap_sham_dev *dd, } else if (ctx->op == OP_FINAL) { err = omap_sham_final_req(dd); } - +err1: if (err != -EINPROGRESS) { /* done_task will not finish it, so do it here */ omap_sham_finish_req(req, err); @@ -868,7 +864,7 @@ static int omap_sham_cra_init_alg(struct crypto_tfm *tfm, const char *alg_base) } crypto_ahash_set_reqsize(__crypto_ahash_cast(tfm), - sizeof(struct omap_sham_reqctx)); + sizeof(struct omap_sham_reqctx) + BUFLEN); if (alg_base) { struct omap_sham_hmac_ctx *bctx = tctx->base; @@ -954,7 +950,7 @@ static struct ahash_alg algs[] = { CRYPTO_ALG_NEED_FALLBACK, .cra_blocksize = SHA1_BLOCK_SIZE, .cra_ctxsize = sizeof(struct omap_sham_ctx), - .cra_alignmask = 0, + .cra_alignmask = OMAP_ALIGN_MASK, .cra_module = THIS_MODULE, .cra_init = omap_sham_cra_init, .cra_exit = omap_sham_cra_exit, @@ -978,7 +974,7 @@ static struct ahash_alg algs[] = { .cra_blocksize = SHA1_BLOCK_SIZE, .cra_ctxsize = sizeof(struct omap_sham_ctx) + sizeof(struct omap_sham_hmac_ctx), - .cra_alignmask = 0, + .cra_alignmask = OMAP_ALIGN_MASK, .cra_module = THIS_MODULE, .cra_init = omap_sham_cra_sha1_init, .cra_exit = omap_sham_cra_exit, @@ -1002,7 +998,7 @@ static struct ahash_alg algs[] = { .cra_blocksize = SHA1_BLOCK_SIZE, .cra_ctxsize = sizeof(struct omap_sham_ctx) + sizeof(struct omap_sham_hmac_ctx), - .cra_alignmask = 0, + .cra_alignmask = OMAP_ALIGN_MASK, .cra_module = THIS_MODULE, .cra_init = omap_sham_cra_md5_init, .cra_exit = omap_sham_cra_exit, -- cgit v1.2.3 From 3c8d758ab528317ecd6d91f8651170ffd2331899 Mon Sep 17 00:00:00 2001 From: Dmitry Kasatkin Date: Fri, 19 Nov 2010 16:04:27 +0200 Subject: crypto: omap-sham - hash-in-progress is stored in hw format Hash-in-progress is now stored in hw format. Only on final call, hash is converted to correct format. Speedup copy procedure and will allow to use OMAP burst mode. Signed-off-by: Dmitry Kasatkin Signed-off-by: Herbert Xu --- drivers/crypto/omap-sham.c | 38 ++++++++++++++++++++++++-------------- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/drivers/crypto/omap-sham.c b/drivers/crypto/omap-sham.c index 85d627774538..c8d30eb4794a 100644 --- a/drivers/crypto/omap-sham.c +++ b/drivers/crypto/omap-sham.c @@ -204,24 +204,35 @@ static void omap_sham_copy_hash(struct ahash_request *req, int out) u32 *hash = (u32 *)ctx->digest; int i; + /* MD5 is almost unused. So copy sha1 size to reduce code */ + for (i = 0; i < SHA1_DIGEST_SIZE / sizeof(u32); i++) { + if (out) + hash[i] = omap_sham_read(ctx->dd, + SHA_REG_DIGEST(i)); + else + omap_sham_write(ctx->dd, + SHA_REG_DIGEST(i), hash[i]); + } +} + +static void omap_sham_copy_ready_hash(struct ahash_request *req) +{ + struct omap_sham_reqctx *ctx = ahash_request_ctx(req); + u32 *in = (u32 *)ctx->digest; + u32 *hash = (u32 *)req->result; + int i; + + if (!hash) + return; + if (likely(ctx->flags & FLAGS_SHA1)) { /* SHA1 results are in big endian */ for (i = 0; i < SHA1_DIGEST_SIZE / sizeof(u32); i++) - if (out) - hash[i] = be32_to_cpu(omap_sham_read(ctx->dd, - SHA_REG_DIGEST(i))); - else - omap_sham_write(ctx->dd, SHA_REG_DIGEST(i), - cpu_to_be32(hash[i])); + hash[i] = be32_to_cpu(in[i]); } else { /* MD5 results are in little endian */ for (i = 0; i < MD5_DIGEST_SIZE / sizeof(u32); i++) - if (out) - hash[i] = le32_to_cpu(omap_sham_read(ctx->dd, - SHA_REG_DIGEST(i))); - else - omap_sham_write(ctx->dd, SHA_REG_DIGEST(i), - cpu_to_le32(hash[i])); + hash[i] = le32_to_cpu(in[i]); } } @@ -474,8 +485,7 @@ static void omap_sham_cleanup(struct ahash_request *req) spin_unlock_irqrestore(&dd->lock, flags); if (ctx->digcnt) - memcpy(req->result, ctx->digest, (ctx->flags & FLAGS_SHA1) ? - SHA1_DIGEST_SIZE : MD5_DIGEST_SIZE); + omap_sham_copy_ready_hash(req); dev_dbg(dd->dev, "digcnt: %d, bufcnt: %d\n", ctx->digcnt, ctx->bufcnt); } -- cgit v1.2.3 From a55b290b0e41e02d1969589c5d77d966ac2b7ec8 Mon Sep 17 00:00:00 2001 From: Dmitry Kasatkin Date: Fri, 19 Nov 2010 16:04:28 +0200 Subject: crypto: omap-sham - FLAGS_FIRST is redundant and removed bufcnt is 0 if it was no update requests before, which is exact meaning of FLAGS_FIRST. Signed-off-by: Dmitry Kasatkin Signed-off-by: Herbert Xu --- drivers/crypto/omap-sham.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/drivers/crypto/omap-sham.c b/drivers/crypto/omap-sham.c index c8d30eb4794a..d88d7ebfffa7 100644 --- a/drivers/crypto/omap-sham.c +++ b/drivers/crypto/omap-sham.c @@ -72,7 +72,6 @@ #define DEFAULT_TIMEOUT_INTERVAL HZ -#define FLAGS_FIRST 0x0001 #define FLAGS_FINUP 0x0002 #define FLAGS_FINAL 0x0004 #define FLAGS_FAST 0x0008 @@ -513,8 +512,6 @@ static int omap_sham_init(struct ahash_request *req) ctx->flags = 0; - ctx->flags |= FLAGS_FIRST; - dev_dbg(dd->dev, "init: digest size: %d\n", crypto_ahash_digestsize(tfm)); @@ -739,12 +736,9 @@ static int omap_sham_update(struct ahash_request *req) /* may be can use faster functions */ int aligned = IS_ALIGNED((u32)ctx->sg->offset, sizeof(u32)); - - if (aligned && (ctx->flags & FLAGS_FIRST)) + if (aligned) /* digest: first and final */ ctx->flags |= FLAGS_FAST; - - ctx->flags &= ~FLAGS_FIRST; } } else if (ctx->bufcnt + ctx->total <= ctx->buflen) { /* if not finaup -> not fast */ -- cgit v1.2.3 From 887c883eea9867535059f3c8414c8cfc952ccff1 Mon Sep 17 00:00:00 2001 From: Dmitry Kasatkin Date: Fri, 19 Nov 2010 16:04:29 +0200 Subject: crypto: omap-sham - zero-copy scatterlist handling If scatterlist have more than one entry, current driver uses aligned buffer to copy data to to accelerator to tackle possible issues with DMA and SHA buffer alignment. This commit adds more intelligence to verify SG alignment and possibility to use DMA directly on the data without using copy buffer. Signed-off-by: Dmitry Kasatkin Signed-off-by: Herbert Xu --- drivers/crypto/omap-sham.c | 87 ++++++++++++++++++++++++++++++++-------------- 1 file changed, 61 insertions(+), 26 deletions(-) diff --git a/drivers/crypto/omap-sham.c b/drivers/crypto/omap-sham.c index d88d7ebfffa7..eb988e7a2fd9 100644 --- a/drivers/crypto/omap-sham.c +++ b/drivers/crypto/omap-sham.c @@ -74,7 +74,7 @@ #define FLAGS_FINUP 0x0002 #define FLAGS_FINAL 0x0004 -#define FLAGS_FAST 0x0008 +#define FLAGS_SG 0x0008 #define FLAGS_SHA1 0x0010 #define FLAGS_DMA_ACTIVE 0x0020 #define FLAGS_OUTPUT_READY 0x0040 @@ -393,6 +393,8 @@ static int omap_sham_xmit_dma_map(struct omap_sham_dev *dd, return -EINVAL; } + ctx->flags &= ~FLAGS_SG; + /* next call does not fail... so no unmap in the case of error */ return omap_sham_xmit_dma(dd, ctx->dma_addr, length, final); } @@ -403,9 +405,6 @@ static int omap_sham_update_dma_slow(struct omap_sham_dev *dd) unsigned int final; size_t count; - if (!ctx->total) - return 0; - omap_sham_append_sg(ctx); final = (ctx->flags & FLAGS_FINUP) && !ctx->total; @@ -422,25 +421,62 @@ static int omap_sham_update_dma_slow(struct omap_sham_dev *dd) return 0; } -static int omap_sham_update_dma_fast(struct omap_sham_dev *dd) +/* Start address alignment */ +#define SG_AA(sg) (IS_ALIGNED(sg->offset, sizeof(u32))) +/* SHA1 block size alignment */ +#define SG_SA(sg) (IS_ALIGNED(sg->length, SHA1_MD5_BLOCK_SIZE)) + +static int omap_sham_update_dma_start(struct omap_sham_dev *dd) { struct omap_sham_reqctx *ctx = ahash_request_ctx(dd->req); - unsigned int length; + unsigned int length, final, tail; + struct scatterlist *sg; + + if (!ctx->total) + return 0; + + if (ctx->bufcnt || ctx->offset) + return omap_sham_update_dma_slow(dd); + + dev_dbg(dd->dev, "fast: digcnt: %d, bufcnt: %u, total: %u\n", + ctx->digcnt, ctx->bufcnt, ctx->total); + + sg = ctx->sg; - ctx->flags |= FLAGS_FAST; + if (!SG_AA(sg)) + return omap_sham_update_dma_slow(dd); - length = min(ctx->total, sg_dma_len(ctx->sg)); - ctx->total = length; + if (!sg_is_last(sg) && !SG_SA(sg)) + /* size is not SHA1_BLOCK_SIZE aligned */ + return omap_sham_update_dma_slow(dd); + + length = min(ctx->total, sg->length); + + if (sg_is_last(sg)) { + if (!(ctx->flags & FLAGS_FINUP)) { + /* not last sg must be SHA1_MD5_BLOCK_SIZE aligned */ + tail = length & (SHA1_MD5_BLOCK_SIZE - 1); + /* without finup() we need one block to close hash */ + if (!tail) + tail = SHA1_MD5_BLOCK_SIZE; + length -= tail; + } + } if (!dma_map_sg(dd->dev, ctx->sg, 1, DMA_TO_DEVICE)) { dev_err(dd->dev, "dma_map_sg error\n"); return -EINVAL; } + ctx->flags |= FLAGS_SG; + ctx->total -= length; + ctx->offset = length; /* offset where to start slow */ + + final = (ctx->flags & FLAGS_FINUP) && !ctx->total; /* next call does not fail... so no unmap in the case of error */ - return omap_sham_xmit_dma(dd, sg_dma_address(ctx->sg), length, 1); + return omap_sham_xmit_dma(dd, sg_dma_address(ctx->sg), length, final); } static int omap_sham_update_cpu(struct omap_sham_dev *dd) @@ -460,11 +496,17 @@ static int omap_sham_update_dma_stop(struct omap_sham_dev *dd) struct omap_sham_reqctx *ctx = ahash_request_ctx(dd->req); omap_stop_dma(dd->dma_lch); - if (ctx->flags & FLAGS_FAST) + if (ctx->flags & FLAGS_SG) { dma_unmap_sg(dd->dev, ctx->sg, 1, DMA_TO_DEVICE); - else + if (ctx->sg->length == ctx->offset) { + ctx->sg = sg_next(ctx->sg); + if (ctx->sg) + ctx->offset = 0; + } + } else { dma_unmap_single(dd->dev, ctx->dma_addr, ctx->buflen, DMA_TO_DEVICE); + } return 0; } @@ -545,10 +587,8 @@ static int omap_sham_update_req(struct omap_sham_dev *dd) if (ctx->flags & FLAGS_CPU) err = omap_sham_update_cpu(dd); - else if (ctx->flags & FLAGS_FAST) - err = omap_sham_update_dma_fast(dd); else - err = omap_sham_update_dma_slow(dd); + err = omap_sham_update_dma_start(dd); /* wait for dma completion before can take more data */ dev_dbg(dd->dev, "update: err: %d, digcnt: %d\n", err, ctx->digcnt); @@ -730,18 +770,13 @@ static int omap_sham_update(struct ahash_request *req) */ omap_sham_append_sg(ctx); return 0; - } else if (ctx->bufcnt + ctx->total <= 64) { + } else if (ctx->bufcnt + ctx->total <= SHA1_MD5_BLOCK_SIZE) { + /* + * faster to use CPU for short transfers + */ ctx->flags |= FLAGS_CPU; - } else if (!ctx->bufcnt && sg_is_last(ctx->sg)) { - /* may be can use faster functions */ - int aligned = IS_ALIGNED((u32)ctx->sg->offset, - sizeof(u32)); - if (aligned) - /* digest: first and final */ - ctx->flags |= FLAGS_FAST; } - } else if (ctx->bufcnt + ctx->total <= ctx->buflen) { - /* if not finaup -> not fast */ + } else if (ctx->bufcnt + ctx->total < ctx->buflen) { omap_sham_append_sg(ctx); return 0; } @@ -1026,7 +1061,7 @@ static void omap_sham_done_task(unsigned long data) dd->flags &= ~FLAGS_DMA_ACTIVE; omap_sham_update_dma_stop(dd); if (!dd->err) - err = omap_sham_update_dma_slow(dd); + err = omap_sham_update_dma_start(dd); } err = dd->err ? : err; -- cgit v1.2.3 From 11cef5f07ba0e925af432fc3229fb87585ccccf0 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 26 Nov 2010 17:23:44 +0000 Subject: ASoC: Use DC servo startup mode when not doing DCS correction Devices which do not have a DCS correction applied can use the explicit DC servo startup mode for optimal startup performance. This most immediately affects the WM8958. Signed-off-by: Mark Brown Acked-by: Liam Girdwood --- sound/soc/codecs/wm_hubs.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/sound/soc/codecs/wm_hubs.c b/sound/soc/codecs/wm_hubs.c index e7a19d6ada50..b24ba9fa7ef7 100644 --- a/sound/soc/codecs/wm_hubs.c +++ b/sound/soc/codecs/wm_hubs.c @@ -105,12 +105,20 @@ static void calibrate_dc_servo(struct snd_soc_codec *codec) return; } - /* Set for 32 series updates */ - snd_soc_update_bits(codec, WM8993_DC_SERVO_1, - WM8993_DCS_SERIES_NO_01_MASK, - 32 << WM8993_DCS_SERIES_NO_01_SHIFT); - wait_for_dc_servo(codec, - WM8993_DCS_TRIG_SERIES_0 | WM8993_DCS_TRIG_SERIES_1); + /* Devices not using a DCS code correction have startup mode */ + if (hubs->dcs_codes) { + /* Set for 32 series updates */ + snd_soc_update_bits(codec, WM8993_DC_SERVO_1, + WM8993_DCS_SERIES_NO_01_MASK, + 32 << WM8993_DCS_SERIES_NO_01_SHIFT); + wait_for_dc_servo(codec, + WM8993_DCS_TRIG_SERIES_0 | + WM8993_DCS_TRIG_SERIES_1); + } else { + wait_for_dc_servo(codec, + WM8993_DCS_TRIG_STARTUP_0 | + WM8993_DCS_TRIG_STARTUP_1); + } /* Different chips in the family support different readback * methods. -- cgit v1.2.3 From 3a42315740fa80bb4579eb25fedec9d09ff154e7 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 26 Nov 2010 15:21:06 +0000 Subject: ASoC: Initial WM8958 audio configuration The WM8958 is a WM8994 derivative. This patch merely ensures that some revision specific configuration for WM8994 is not enabled on WM8994, additional patches will add support for the new features introduced on the WM8958. Signed-off-by: Mark Brown Acked-by: Liam Girdwood --- sound/soc/codecs/wm8994.c | 110 ++++++++++++++++++++++++++++++++-------------- 1 file changed, 76 insertions(+), 34 deletions(-) diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index 283399468b0c..8232d5e73194 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c @@ -1535,6 +1535,7 @@ static int wm8994_set_dai_sysclk(struct snd_soc_dai *dai, static int wm8994_set_bias_level(struct snd_soc_codec *codec, enum snd_soc_bias_level level) { + struct wm8994 *control = codec->control_data; struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); switch (level) { @@ -1551,7 +1552,7 @@ static int wm8994_set_bias_level(struct snd_soc_codec *codec, if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { /* Tweak DC servo and DSP configuration for * improved performance. */ - if (wm8994->revision < 4) { + if (control->type == WM8994 && wm8994->revision < 4) { /* Tweak DC servo and DSP configuration for * improved performance. */ snd_soc_write(codec, 0x102, 0x3); @@ -2264,8 +2265,12 @@ int wm8994_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack, { struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); struct wm8994_micdet *micdet; + struct wm8994 *control = codec->control_data; int reg; + if (control->type != WM8994) + return -EINVAL; + switch (micbias) { case 1: micdet = &wm8994->micdet[0]; @@ -2334,11 +2339,13 @@ static irqreturn_t wm8994_mic_irq(int irq, void *data) static int wm8994_codec_probe(struct snd_soc_codec *codec) { + struct wm8994 *control; struct wm8994_priv *wm8994; struct snd_soc_dapm_context *dapm = &codec->dapm; int ret, i; codec->control_data = dev_get_drvdata(codec->dev->parent); + control = codec->control_data; wm8994 = kzalloc(sizeof(struct wm8994_priv), GFP_KERNEL); if (wm8994 == NULL) @@ -2369,41 +2376,67 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) /* Set revision-specific configuration */ wm8994->revision = snd_soc_read(codec, WM8994_CHIP_REVISION); - switch (wm8994->revision) { - case 2: - case 3: - wm8994->hubs.dcs_codes = -5; - wm8994->hubs.hp_startup_mode = 1; + switch (control->type) { + case WM8994: + switch (wm8994->revision) { + case 2: + case 3: + wm8994->hubs.dcs_codes = -5; + wm8994->hubs.hp_startup_mode = 1; + wm8994->hubs.dcs_readback_mode = 1; + break; + default: + wm8994->hubs.dcs_readback_mode = 1; + break; + } + + case WM8958: wm8994->hubs.dcs_readback_mode = 1; break; + default: - wm8994->hubs.dcs_readback_mode = 1; break; } - ret = wm8994_request_irq(codec->control_data, WM8994_IRQ_MIC1_DET, - wm8994_mic_irq, "Mic 1 detect", wm8994); - if (ret != 0) - dev_warn(codec->dev, - "Failed to request Mic1 detect IRQ: %d\n", ret); - - ret = wm8994_request_irq(codec->control_data, WM8994_IRQ_MIC1_SHRT, - wm8994_mic_irq, "Mic 1 short", wm8994); - if (ret != 0) - dev_warn(codec->dev, - "Failed to request Mic1 short IRQ: %d\n", ret); - - ret = wm8994_request_irq(codec->control_data, WM8994_IRQ_MIC2_DET, - wm8994_mic_irq, "Mic 2 detect", wm8994); - if (ret != 0) - dev_warn(codec->dev, - "Failed to request Mic2 detect IRQ: %d\n", ret); - - ret = wm8994_request_irq(codec->control_data, WM8994_IRQ_MIC2_SHRT, - wm8994_mic_irq, "Mic 2 short", wm8994); - if (ret != 0) - dev_warn(codec->dev, - "Failed to request Mic2 short IRQ: %d\n", ret); + switch (control->type) { + case WM8994: + ret = wm8994_request_irq(codec->control_data, + WM8994_IRQ_MIC1_DET, + wm8994_mic_irq, "Mic 1 detect", + wm8994); + if (ret != 0) + dev_warn(codec->dev, + "Failed to request Mic1 detect IRQ: %d\n", + ret); + + ret = wm8994_request_irq(codec->control_data, + WM8994_IRQ_MIC1_SHRT, + wm8994_mic_irq, "Mic 1 short", + wm8994); + if (ret != 0) + dev_warn(codec->dev, + "Failed to request Mic1 short IRQ: %d\n", + ret); + + ret = wm8994_request_irq(codec->control_data, + WM8994_IRQ_MIC2_DET, + wm8994_mic_irq, "Mic 2 detect", + wm8994); + if (ret != 0) + dev_warn(codec->dev, + "Failed to request Mic2 detect IRQ: %d\n", + ret); + + ret = wm8994_request_irq(codec->control_data, + WM8994_IRQ_MIC2_SHRT, + wm8994_mic_irq, "Mic 2 short", + wm8994); + if (ret != 0) + dev_warn(codec->dev, + "Failed to request Mic2 short IRQ: %d\n", + ret); + break; + } /* Remember if AIFnLRCLK is configured as a GPIO. This should be * configured on init - if a system wants to do this dynamically @@ -2496,13 +2529,22 @@ err: static int wm8994_codec_remove(struct snd_soc_codec *codec) { struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); + struct wm8994 *control = codec->control_data; wm8994_set_bias_level(codec, SND_SOC_BIAS_OFF); - wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC2_SHRT, wm8994); - wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC2_DET, wm8994); - wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC1_SHRT, wm8994); - wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC1_DET, wm8994); + switch (control->type) { + case WM8994: + wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC2_SHRT, + wm8994); + wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC2_DET, + wm8994); + wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC1_SHRT, + wm8994); + wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC1_DET, + wm8994); + break; + } kfree(wm8994->retune_mobile_texts); kfree(wm8994->drc_texts); kfree(wm8994); -- cgit v1.2.3 From c4431df050ff124cae7716e301cead1e8f33c575 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 26 Nov 2010 15:21:07 +0000 Subject: ASoC: Implement support for enhanced AIF3 on WM8958 Additional audio routing options are available on the WM8958 audio interface 3. Add support for these. Signed-off-by: Mark Brown Acked-by: Liam Girdwood --- include/linux/mfd/wm8994/registers.h | 67 ++++++++++++++ sound/soc/codecs/wm8994.c | 166 +++++++++++++++++++++++++++++++++-- 2 files changed, 224 insertions(+), 9 deletions(-) diff --git a/include/linux/mfd/wm8994/registers.h b/include/linux/mfd/wm8994/registers.h index 967f62f54159..3eb70a4e7681 100644 --- a/include/linux/mfd/wm8994/registers.h +++ b/include/linux/mfd/wm8994/registers.h @@ -109,6 +109,10 @@ #define WM8994_AIF2DAC_LRCLK 0x315 #define WM8994_AIF2DAC_DATA 0x316 #define WM8994_AIF2ADC_DATA 0x317 +#define WM8958_AIF3_CONTROL_1 0x320 +#define WM8958_AIF3_CONTROL_2 0x321 +#define WM8958_AIF3DAC_DATA 0x322 +#define WM8958_AIF3ADC_DATA 0x323 #define WM8994_AIF1_ADC1_LEFT_VOLUME 0x400 #define WM8994_AIF1_ADC1_RIGHT_VOLUME 0x401 #define WM8994_AIF1_DAC1_LEFT_VOLUME 0x402 @@ -992,6 +996,12 @@ /* * R6 (0x06) - Power Management (6) */ +#define WM8958_AIF3ADC_SRC_MASK 0x0600 /* AIF3ADC_SRC - [10:9] */ +#define WM8958_AIF3ADC_SRC_SHIFT 9 /* AIF3ADC_SRC - [10:9] */ +#define WM8958_AIF3ADC_SRC_WIDTH 2 /* AIF3ADC_SRC - [10:9] */ +#define WM8958_AIF2DAC_SRC_MASK 0x0180 /* AIF2DAC_SRC - [8:7] */ +#define WM8958_AIF2DAC_SRC_SHIFT 7 /* AIF2DAC_SRC - [8:7] */ +#define WM8958_AIF2DAC_SRC_WIDTH 2 /* AIF2DAC_SRC - [8:7] */ #define WM8994_AIF3_TRI 0x0020 /* AIF3_TRI */ #define WM8994_AIF3_TRI_MASK 0x0020 /* AIF3_TRI */ #define WM8994_AIF3_TRI_SHIFT 5 /* AIF3_TRI */ @@ -2552,6 +2562,63 @@ #define WM8994_AIF2ADCR_DAT_INV_SHIFT 0 /* AIF2ADCR_DAT_INV */ #define WM8994_AIF2ADCR_DAT_INV_WIDTH 1 /* AIF2ADCR_DAT_INV */ +/* + * R800 (0x320) - AIF3 Control (1) + */ +#define WM8958_AIF3_LRCLK_INV 0x0080 /* AIF3_LRCLK_INV */ +#define WM8958_AIF3_LRCLK_INV_MASK 0x0080 /* AIF3_LRCLK_INV */ +#define WM8958_AIF3_LRCLK_INV_SHIFT 7 /* AIF3_LRCLK_INV */ +#define WM8958_AIF3_LRCLK_INV_WIDTH 1 /* AIF3_LRCLK_INV */ +#define WM8958_AIF3_WL_MASK 0x0060 /* AIF3_WL - [6:5] */ +#define WM8958_AIF3_WL_SHIFT 5 /* AIF3_WL - [6:5] */ +#define WM8958_AIF3_WL_WIDTH 2 /* AIF3_WL - [6:5] */ +#define WM8958_AIF3_FMT_MASK 0x0018 /* AIF3_FMT - [4:3] */ +#define WM8958_AIF3_FMT_SHIFT 3 /* AIF3_FMT - [4:3] */ +#define WM8958_AIF3_FMT_WIDTH 2 /* AIF3_FMT - [4:3] */ + +/* + * R801 (0x321) - AIF3 Control (2) + */ +#define WM8958_AIF3DAC_BOOST_MASK 0x0C00 /* AIF3DAC_BOOST - [11:10] */ +#define WM8958_AIF3DAC_BOOST_SHIFT 10 /* AIF3DAC_BOOST - [11:10] */ +#define WM8958_AIF3DAC_BOOST_WIDTH 2 /* AIF3DAC_BOOST - [11:10] */ +#define WM8958_AIF3DAC_COMP 0x0010 /* AIF3DAC_COMP */ +#define WM8958_AIF3DAC_COMP_MASK 0x0010 /* AIF3DAC_COMP */ +#define WM8958_AIF3DAC_COMP_SHIFT 4 /* AIF3DAC_COMP */ +#define WM8958_AIF3DAC_COMP_WIDTH 1 /* AIF3DAC_COMP */ +#define WM8958_AIF3DAC_COMPMODE 0x0008 /* AIF3DAC_COMPMODE */ +#define WM8958_AIF3DAC_COMPMODE_MASK 0x0008 /* AIF3DAC_COMPMODE */ +#define WM8958_AIF3DAC_COMPMODE_SHIFT 3 /* AIF3DAC_COMPMODE */ +#define WM8958_AIF3DAC_COMPMODE_WIDTH 1 /* AIF3DAC_COMPMODE */ +#define WM8958_AIF3ADC_COMP 0x0004 /* AIF3ADC_COMP */ +#define WM8958_AIF3ADC_COMP_MASK 0x0004 /* AIF3ADC_COMP */ +#define WM8958_AIF3ADC_COMP_SHIFT 2 /* AIF3ADC_COMP */ +#define WM8958_AIF3ADC_COMP_WIDTH 1 /* AIF3ADC_COMP */ +#define WM8958_AIF3ADC_COMPMODE 0x0002 /* AIF3ADC_COMPMODE */ +#define WM8958_AIF3ADC_COMPMODE_MASK 0x0002 /* AIF3ADC_COMPMODE */ +#define WM8958_AIF3ADC_COMPMODE_SHIFT 1 /* AIF3ADC_COMPMODE */ +#define WM8958_AIF3ADC_COMPMODE_WIDTH 1 /* AIF3ADC_COMPMODE */ +#define WM8958_AIF3_LOOPBACK 0x0001 /* AIF3_LOOPBACK */ +#define WM8958_AIF3_LOOPBACK_MASK 0x0001 /* AIF3_LOOPBACK */ +#define WM8958_AIF3_LOOPBACK_SHIFT 0 /* AIF3_LOOPBACK */ +#define WM8958_AIF3_LOOPBACK_WIDTH 1 /* AIF3_LOOPBACK */ + +/* + * R802 (0x322) - AIF3DAC Data + */ +#define WM8958_AIF3DAC_DAT_INV 0x0001 /* AIF3DAC_DAT_INV */ +#define WM8958_AIF3DAC_DAT_INV_MASK 0x0001 /* AIF3DAC_DAT_INV */ +#define WM8958_AIF3DAC_DAT_INV_SHIFT 0 /* AIF3DAC_DAT_INV */ +#define WM8958_AIF3DAC_DAT_INV_WIDTH 1 /* AIF3DAC_DAT_INV */ + +/* + * R803 (0x323) - AIF3ADC Data + */ +#define WM8958_AIF3ADC_DAT_INV 0x0001 /* AIF3ADC_DAT_INV */ +#define WM8958_AIF3ADC_DAT_INV_MASK 0x0001 /* AIF3ADC_DAT_INV */ +#define WM8958_AIF3ADC_DAT_INV_SHIFT 0 /* AIF3ADC_DAT_INV */ +#define WM8958_AIF3ADC_DAT_INV_WIDTH 1 /* AIF3ADC_DAT_INV */ + /* * R1024 (0x400) - AIF1 ADC1 Left Volume */ diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index 8232d5e73194..fb0609315cd6 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c @@ -647,6 +647,10 @@ SOC_SINGLE_TLV("AIF2 EQ5 Volume", WM8994_AIF2_EQ_GAINS_2, 6, 31, 0, eq_tlv), }; +static const struct snd_kcontrol_new wm8958_snd_controls[] = { +SOC_SINGLE_TLV("AIF3 Boost Volume", WM8958_AIF3_CONTROL_2, 10, 3, 0, aif_tlv), +}; + static int clk_sys_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { @@ -953,14 +957,47 @@ static const struct snd_kcontrol_new aif2adc_mux = SOC_DAPM_ENUM("AIF2ADC Mux", aif2adc_enum); static const char *aif3adc_text[] = { - "AIF1ADCDAT", "AIF2ADCDAT", "AIF2DACDAT", + "AIF1ADCDAT", "AIF2ADCDAT", "AIF2DACDAT", "Mono PCM", }; -static const struct soc_enum aif3adc_enum = +static const struct soc_enum wm8994_aif3adc_enum = SOC_ENUM_SINGLE(WM8994_POWER_MANAGEMENT_6, 3, 3, aif3adc_text); -static const struct snd_kcontrol_new aif3adc_mux = - SOC_DAPM_ENUM("AIF3ADC Mux", aif3adc_enum); +static const struct snd_kcontrol_new wm8994_aif3adc_mux = + SOC_DAPM_ENUM("AIF3ADC Mux", wm8994_aif3adc_enum); + +static const struct soc_enum wm8958_aif3adc_enum = + SOC_ENUM_SINGLE(WM8994_POWER_MANAGEMENT_6, 3, 4, aif3adc_text); + +static const struct snd_kcontrol_new wm8958_aif3adc_mux = + SOC_DAPM_ENUM("AIF3ADC Mux", wm8958_aif3adc_enum); + +static const char *mono_pcm_out_text[] = { + "None", "AIF2ADCL", "AIF2ADCR", +}; + +static const struct soc_enum mono_pcm_out_enum = + SOC_ENUM_SINGLE(WM8994_POWER_MANAGEMENT_6, 9, 3, mono_pcm_out_text); + +static const struct snd_kcontrol_new mono_pcm_out_mux = + SOC_DAPM_ENUM("Mono PCM Out Mux", mono_pcm_out_enum); + +static const char *aif2dac_src_text[] = { + "AIF2", "AIF3", +}; + +/* Note that these two control shouldn't be simultaneously switched to AIF3 */ +static const struct soc_enum aif2dacl_src_enum = + SOC_ENUM_SINGLE(WM8994_POWER_MANAGEMENT_6, 7, 2, aif2dac_src_text); + +static const struct snd_kcontrol_new aif2dacl_src_mux = + SOC_DAPM_ENUM("AIF2DACL Mux", aif2dacl_src_enum); + +static const struct soc_enum aif2dacr_src_enum = + SOC_ENUM_SINGLE(WM8994_POWER_MANAGEMENT_6, 8, 2, aif2dac_src_text); + +static const struct snd_kcontrol_new aif2dacr_src_mux = + SOC_DAPM_ENUM("AIF2DACR Mux", aif2dacr_src_enum); static const struct snd_soc_dapm_widget wm8994_dapm_widgets[] = { SND_SOC_DAPM_INPUT("DMIC1DAT"), @@ -1034,7 +1071,6 @@ SND_SOC_DAPM_AIF_OUT("AIF2ADCDAT", "AIF2 Capture", 0, SND_SOC_NOPM, 0, 0), SND_SOC_DAPM_MUX("AIF1DAC Mux", SND_SOC_NOPM, 0, 0, &aif1dac_mux), SND_SOC_DAPM_MUX("AIF2DAC Mux", SND_SOC_NOPM, 0, 0, &aif2dac_mux), SND_SOC_DAPM_MUX("AIF2ADC Mux", SND_SOC_NOPM, 0, 0, &aif2adc_mux), -SND_SOC_DAPM_MUX("AIF3ADC Mux", SND_SOC_NOPM, 0, 0, &aif3adc_mux), SND_SOC_DAPM_AIF_IN("AIF3DACDAT", "AIF3 Playback", 0, SND_SOC_NOPM, 0, 0), SND_SOC_DAPM_AIF_IN("AIF3ADCDAT", "AIF3 Capture", 0, SND_SOC_NOPM, 0, 0), @@ -1072,8 +1108,18 @@ SND_SOC_DAPM_MIXER("SPKR", WM8994_POWER_MANAGEMENT_3, 9, 0, SND_SOC_DAPM_POST("Debug log", post_ev), }; -static const struct snd_soc_dapm_route intercon[] = { +static const struct snd_soc_dapm_widget wm8994_specific_dapm_widgets[] = { +SND_SOC_DAPM_MUX("AIF3ADC Mux", SND_SOC_NOPM, 0, 0, &wm8994_aif3adc_mux), +}; +static const struct snd_soc_dapm_widget wm8958_dapm_widgets[] = { +SND_SOC_DAPM_MUX("Mono PCM Out Mux", SND_SOC_NOPM, 0, 0, &mono_pcm_out_mux), +SND_SOC_DAPM_MUX("AIF2DACL Mux", SND_SOC_NOPM, 0, 0, &aif2dacl_src_mux), +SND_SOC_DAPM_MUX("AIF2DACR Mux", SND_SOC_NOPM, 0, 0, &aif2dacr_src_mux), +SND_SOC_DAPM_MUX("AIF3ADC Mux", SND_SOC_NOPM, 0, 0, &wm8958_aif3adc_mux), +}; + +static const struct snd_soc_dapm_route intercon[] = { { "CLK_SYS", NULL, "AIF1CLK", check_clk_sys }, { "CLK_SYS", NULL, "AIF2CLK", check_clk_sys }, @@ -1181,9 +1227,6 @@ static const struct snd_soc_dapm_route intercon[] = { { "AIF1DAC2L", NULL, "AIF1DAC Mux" }, { "AIF1DAC2R", NULL, "AIF1DAC Mux" }, - { "AIF2DACL", NULL, "AIF2DAC Mux" }, - { "AIF2DACR", NULL, "AIF2DAC Mux" }, - { "AIF1DAC Mux", "AIF1DACDAT", "AIF1DACDAT" }, { "AIF1DAC Mux", "AIF3DACDAT", "AIF3DACDAT" }, { "AIF2DAC Mux", "AIF2DACDAT", "AIF2DACDAT" }, @@ -1256,6 +1299,26 @@ static const struct snd_soc_dapm_route intercon[] = { { "Right Headphone Mux", "DAC", "DAC1R" }, }; +static const struct snd_soc_dapm_route wm8994_intercon[] = { + { "AIF2DACL", NULL, "AIF2DAC Mux" }, + { "AIF2DACR", NULL, "AIF2DAC Mux" }, +}; + +static const struct snd_soc_dapm_route wm8958_intercon[] = { + { "AIF2DACL", NULL, "AIF2DACL Mux" }, + { "AIF2DACR", NULL, "AIF2DACR Mux" }, + + { "AIF2DACL Mux", "AIF2", "AIF2DAC Mux" }, + { "AIF2DACL Mux", "AIF3", "AIF3DACDAT" }, + { "AIF2DACR Mux", "AIF2", "AIF2DAC Mux" }, + { "AIF2DACR Mux", "AIF3", "AIF3DACDAT" }, + + { "Mono PCM Out Mux", "AIF2ADCL", "AIF2ADCL" }, + { "Mono PCM Out Mux", "AIF2ADCR", "AIF2ADCR" }, + + { "AIF3ADC Mux", "Mono PCM", "Mono PCM Out Mux" }, +}; + /* The size in bits of the FLL divide multiplied by 10 * to allow rounding later */ #define FIXED_FLL_SIZE ((1 << 16) * 10) @@ -1635,6 +1698,7 @@ static int wm8994_set_bias_level(struct snd_soc_codec *codec, static int wm8994_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) { struct snd_soc_codec *codec = dai->codec; + struct wm8994 *control = codec->control_data; int ms_reg; int aif1_reg; int ms = 0; @@ -1719,6 +1783,13 @@ static int wm8994_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) return -EINVAL; } + /* The AIF2 format configuration needs to be mirrored to AIF3 + * on WM8958 if it's in use so just do it all the time. */ + if (control->type == WM8958 && dai->id == 2) + snd_soc_update_bits(codec, WM8958_AIF3_CONTROL_1, + WM8994_AIF1_LRCLK_INV | + WM8958_AIF3_FMT_MASK, aif1); + snd_soc_update_bits(codec, aif1_reg, WM8994_AIF1_BCLK_INV | WM8994_AIF1_LRCLK_INV | WM8994_AIF1_FMT_MASK, @@ -1759,6 +1830,7 @@ static int wm8994_hw_params(struct snd_pcm_substream *substream, struct snd_soc_dai *dai) { struct snd_soc_codec *codec = dai->codec; + struct wm8994 *control = codec->control_data; struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); int aif1_reg; int bclk_reg; @@ -1797,6 +1869,14 @@ static int wm8994_hw_params(struct snd_pcm_substream *substream, dev_dbg(codec->dev, "AIF2 using split LRCLK\n"); } break; + case 3: + switch (control->type) { + case WM8958: + aif1_reg = WM8958_AIF3_CONTROL_1; + break; + default: + return 0; + } default: return -EINVAL; } @@ -1900,6 +1980,47 @@ static int wm8994_hw_params(struct snd_pcm_substream *substream, return 0; } +static int wm8994_aif3_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 wm8994 *control = codec->control_data; + int aif1_reg; + int aif1 = 0; + + switch (dai->id) { + case 3: + switch (control->type) { + case WM8958: + aif1_reg = WM8958_AIF3_CONTROL_1; + break; + default: + return 0; + } + default: + return 0; + } + + switch (params_format(params)) { + case SNDRV_PCM_FORMAT_S16_LE: + break; + case SNDRV_PCM_FORMAT_S20_3LE: + aif1 |= 0x20; + break; + case SNDRV_PCM_FORMAT_S24_LE: + aif1 |= 0x40; + break; + case SNDRV_PCM_FORMAT_S32_LE: + aif1 |= 0x60; + break; + default: + return -EINVAL; + } + + return snd_soc_update_bits(codec, aif1_reg, WM8994_AIF1_WL_MASK, aif1); +} + static int wm8994_aif_mute(struct snd_soc_dai *codec_dai, int mute) { struct snd_soc_codec *codec = codec_dai->codec; @@ -1981,6 +2102,7 @@ static struct snd_soc_dai_ops wm8994_aif2_dai_ops = { }; static struct snd_soc_dai_ops wm8994_aif3_dai_ops = { + .hw_params = wm8994_aif3_hw_params, .set_tristate = wm8994_set_tristate, }; @@ -2511,9 +2633,35 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) ARRAY_SIZE(wm8994_snd_controls)); snd_soc_dapm_new_controls(dapm, wm8994_dapm_widgets, ARRAY_SIZE(wm8994_dapm_widgets)); + + switch (control->type) { + case WM8994: + snd_soc_dapm_new_controls(dapm, wm8994_specific_dapm_widgets, + ARRAY_SIZE(wm8994_specific_dapm_widgets)); + break; + case WM8958: + snd_soc_add_controls(codec, wm8958_snd_controls, + ARRAY_SIZE(wm8958_snd_controls)); + snd_soc_dapm_new_controls(dapm, wm8958_dapm_widgets, + ARRAY_SIZE(wm8958_dapm_widgets)); + break; + } + + wm_hubs_add_analogue_routes(codec, 0, 0); snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon)); + switch (control->type) { + case WM8994: + snd_soc_dapm_add_routes(dapm, wm8994_intercon, + ARRAY_SIZE(wm8994_intercon)); + break; + case WM8958: + snd_soc_dapm_add_routes(dapm, wm8958_intercon, + ARRAY_SIZE(wm8958_intercon)); + break; + } + return 0; err_irq: -- cgit v1.2.3 From d6addcc9d88aeac4a0cc63a06d36baef04f5dc3b Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 26 Nov 2010 15:21:08 +0000 Subject: ASoC: Add WM8958 Multi-band compressor support The WM8958 features a multi-band compressor which can be enabled on any of the AIF inputs. The MBC allows different gains to be applied to differnt audio bands, providing an improvement in perceived loudness of the signal by avoiding overdriving the output transducers. This patch enables support for the MBC. Signed-off-by: Mark Brown Acked-by: Liam Girdwood --- include/linux/mfd/wm8994/registers.h | 115 ++++++++++++++++++++ sound/soc/codecs/wm8994.c | 198 ++++++++++++++++++++++++++++++++--- 2 files changed, 301 insertions(+), 12 deletions(-) diff --git a/include/linux/mfd/wm8994/registers.h b/include/linux/mfd/wm8994/registers.h index 3eb70a4e7681..423b2b5c94ea 100644 --- a/include/linux/mfd/wm8994/registers.h +++ b/include/linux/mfd/wm8994/registers.h @@ -246,6 +246,15 @@ #define WM8994_INTERRUPT_STATUS_2_MASK 0x739 #define WM8994_INTERRUPT_CONTROL 0x740 #define WM8994_IRQ_DEBOUNCE 0x748 +#define WM8958_DSP2_PROGRAM 0x900 +#define WM8958_DSP2_CONFIG 0x901 +#define WM8958_DSP2_MAGICNUM 0xA00 +#define WM8958_DSP2_RELEASEYEAR 0xA01 +#define WM8958_DSP2_RELEASEMONTHDAY 0xA02 +#define WM8958_DSP2_RELEASETIME 0xA03 +#define WM8958_DSP2_VERMAJMIN 0xA04 +#define WM8958_DSP2_VERBUILD 0xA05 +#define WM8958_DSP2_EXECCONTROL 0xA0D #define WM8994_WRITE_SEQUENCER_0 0x3000 #define WM8994_WRITE_SEQUENCER_1 0x3001 #define WM8994_WRITE_SEQUENCER_2 0x3002 @@ -2079,6 +2088,14 @@ /* * R520 (0x208) - Clocking (1) */ +#define WM8958_DSP2CLK_ENA 0x4000 /* DSP2CLK_ENA */ +#define WM8958_DSP2CLK_ENA_MASK 0x4000 /* DSP2CLK_ENA */ +#define WM8958_DSP2CLK_ENA_SHIFT 14 /* DSP2CLK_ENA */ +#define WM8958_DSP2CLK_ENA_WIDTH 1 /* DSP2CLK_ENA */ +#define WM8958_DSP2CLK_SRC 0x1000 /* DSP2CLK_SRC */ +#define WM8958_DSP2CLK_SRC_MASK 0x1000 /* DSP2CLK_SRC */ +#define WM8958_DSP2CLK_SRC_SHIFT 12 /* DSP2CLK_SRC */ +#define WM8958_DSP2CLK_SRC_WIDTH 1 /* DSP2CLK_SRC */ #define WM8994_TOCLK_ENA 0x0010 /* TOCLK_ENA */ #define WM8994_TOCLK_ENA_MASK 0x0010 /* TOCLK_ENA */ #define WM8994_TOCLK_ENA_SHIFT 4 /* TOCLK_ENA */ @@ -4356,4 +4373,102 @@ #define WM8994_TEMP_SHUT_DB_SHIFT 0 /* TEMP_SHUT_DB */ #define WM8994_TEMP_SHUT_DB_WIDTH 1 /* TEMP_SHUT_DB */ +/* + * R2304 (0x900) - DSP2_Program + */ +#define WM8958_DSP2_ENA 0x0001 /* DSP2_ENA */ +#define WM8958_DSP2_ENA_MASK 0x0001 /* DSP2_ENA */ +#define WM8958_DSP2_ENA_SHIFT 0 /* DSP2_ENA */ +#define WM8958_DSP2_ENA_WIDTH 1 /* DSP2_ENA */ + +/* + * R2305 (0x901) - DSP2_Config + */ +#define WM8958_MBC_SEL_MASK 0x0030 /* MBC_SEL - [5:4] */ +#define WM8958_MBC_SEL_SHIFT 4 /* MBC_SEL - [5:4] */ +#define WM8958_MBC_SEL_WIDTH 2 /* MBC_SEL - [5:4] */ +#define WM8958_MBC_ENA 0x0001 /* MBC_ENA */ +#define WM8958_MBC_ENA_MASK 0x0001 /* MBC_ENA */ +#define WM8958_MBC_ENA_SHIFT 0 /* MBC_ENA */ +#define WM8958_MBC_ENA_WIDTH 1 /* MBC_ENA */ + +/* + * R2560 (0xA00) - DSP2_MagicNum + */ +#define WM8958_DSP2_MAGIC_NUM_MASK 0xFFFF /* DSP2_MAGIC_NUM - [15:0] */ +#define WM8958_DSP2_MAGIC_NUM_SHIFT 0 /* DSP2_MAGIC_NUM - [15:0] */ +#define WM8958_DSP2_MAGIC_NUM_WIDTH 16 /* DSP2_MAGIC_NUM - [15:0] */ + +/* + * R2561 (0xA01) - DSP2_ReleaseYear + */ +#define WM8958_DSP2_RELEASE_YEAR_MASK 0xFFFF /* DSP2_RELEASE_YEAR - [15:0] */ +#define WM8958_DSP2_RELEASE_YEAR_SHIFT 0 /* DSP2_RELEASE_YEAR - [15:0] */ +#define WM8958_DSP2_RELEASE_YEAR_WIDTH 16 /* DSP2_RELEASE_YEAR - [15:0] */ + +/* + * R2562 (0xA02) - DSP2_ReleaseMonthDay + */ +#define WM8958_DSP2_RELEASE_MONTH_MASK 0xFF00 /* DSP2_RELEASE_MONTH - [15:8] */ +#define WM8958_DSP2_RELEASE_MONTH_SHIFT 8 /* DSP2_RELEASE_MONTH - [15:8] */ +#define WM8958_DSP2_RELEASE_MONTH_WIDTH 8 /* DSP2_RELEASE_MONTH - [15:8] */ +#define WM8958_DSP2_RELEASE_DAY_MASK 0x00FF /* DSP2_RELEASE_DAY - [7:0] */ +#define WM8958_DSP2_RELEASE_DAY_SHIFT 0 /* DSP2_RELEASE_DAY - [7:0] */ +#define WM8958_DSP2_RELEASE_DAY_WIDTH 8 /* DSP2_RELEASE_DAY - [7:0] */ + +/* + * R2563 (0xA03) - DSP2_ReleaseTime + */ +#define WM8958_DSP2_RELEASE_HOURS_MASK 0xFF00 /* DSP2_RELEASE_HOURS - [15:8] */ +#define WM8958_DSP2_RELEASE_HOURS_SHIFT 8 /* DSP2_RELEASE_HOURS - [15:8] */ +#define WM8958_DSP2_RELEASE_HOURS_WIDTH 8 /* DSP2_RELEASE_HOURS - [15:8] */ +#define WM8958_DSP2_RELEASE_MINS_MASK 0x00FF /* DSP2_RELEASE_MINS - [7:0] */ +#define WM8958_DSP2_RELEASE_MINS_SHIFT 0 /* DSP2_RELEASE_MINS - [7:0] */ +#define WM8958_DSP2_RELEASE_MINS_WIDTH 8 /* DSP2_RELEASE_MINS - [7:0] */ + +/* + * R2564 (0xA04) - DSP2_VerMajMin + */ +#define WM8958_DSP2_MAJOR_VER_MASK 0xFF00 /* DSP2_MAJOR_VER - [15:8] */ +#define WM8958_DSP2_MAJOR_VER_SHIFT 8 /* DSP2_MAJOR_VER - [15:8] */ +#define WM8958_DSP2_MAJOR_VER_WIDTH 8 /* DSP2_MAJOR_VER - [15:8] */ +#define WM8958_DSP2_MINOR_VER_MASK 0x00FF /* DSP2_MINOR_VER - [7:0] */ +#define WM8958_DSP2_MINOR_VER_SHIFT 0 /* DSP2_MINOR_VER - [7:0] */ +#define WM8958_DSP2_MINOR_VER_WIDTH 8 /* DSP2_MINOR_VER - [7:0] */ + +/* + * R2565 (0xA05) - DSP2_VerBuild + */ +#define WM8958_DSP2_BUILD_VER_MASK 0xFFFF /* DSP2_BUILD_VER - [15:0] */ +#define WM8958_DSP2_BUILD_VER_SHIFT 0 /* DSP2_BUILD_VER - [15:0] */ +#define WM8958_DSP2_BUILD_VER_WIDTH 16 /* DSP2_BUILD_VER - [15:0] */ + +/* + * R2573 (0xA0D) - DSP2_ExecControl + */ +#define WM8958_DSP2_STOPC 0x0020 /* DSP2_STOPC */ +#define WM8958_DSP2_STOPC_MASK 0x0020 /* DSP2_STOPC */ +#define WM8958_DSP2_STOPC_SHIFT 5 /* DSP2_STOPC */ +#define WM8958_DSP2_STOPC_WIDTH 1 /* DSP2_STOPC */ +#define WM8958_DSP2_STOPS 0x0010 /* DSP2_STOPS */ +#define WM8958_DSP2_STOPS_MASK 0x0010 /* DSP2_STOPS */ +#define WM8958_DSP2_STOPS_SHIFT 4 /* DSP2_STOPS */ +#define WM8958_DSP2_STOPS_WIDTH 1 /* DSP2_STOPS */ +#define WM8958_DSP2_STOPI 0x0008 /* DSP2_STOPI */ +#define WM8958_DSP2_STOPI_MASK 0x0008 /* DSP2_STOPI */ +#define WM8958_DSP2_STOPI_SHIFT 3 /* DSP2_STOPI */ +#define WM8958_DSP2_STOPI_WIDTH 1 /* DSP2_STOPI */ +#define WM8958_DSP2_STOP 0x0004 /* DSP2_STOP */ +#define WM8958_DSP2_STOP_MASK 0x0004 /* DSP2_STOP */ +#define WM8958_DSP2_STOP_SHIFT 2 /* DSP2_STOP */ +#define WM8958_DSP2_STOP_WIDTH 1 /* DSP2_STOP */ +#define WM8958_DSP2_RUNR 0x0002 /* DSP2_RUNR */ +#define WM8958_DSP2_RUNR_MASK 0x0002 /* DSP2_RUNR */ +#define WM8958_DSP2_RUNR_SHIFT 1 /* DSP2_RUNR */ +#define WM8958_DSP2_RUNR_WIDTH 1 /* DSP2_RUNR */ +#define WM8958_DSP2_RUN 0x0001 /* DSP2_RUN */ +#define WM8958_DSP2_RUN_MASK 0x0001 /* DSP2_RUN */ +#define WM8958_DSP2_RUN_SHIFT 0 /* DSP2_RUN */ +#define WM8958_DSP2_RUN_WIDTH 1 /* DSP2_RUN */ + #endif diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index fb0609315cd6..b30b2dd3f1f4 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c @@ -80,6 +80,8 @@ struct wm8994_priv { int dac_rates[2]; int lrclk_shared[2]; + int mbc_ena[3]; + /* Platform dependant DRC configuration */ const char **drc_texts; int drc_cfg[WM8994_NUM_DRC]; @@ -137,6 +139,7 @@ static int wm8994_volatile(unsigned int reg) case WM8994_RATE_STATUS: case WM8994_LDO_1: case WM8994_LDO_2: + case WM8958_DSP2_EXECCONTROL: return 1; default: return 0; @@ -520,6 +523,168 @@ static const struct soc_enum aif2dacl_src = static const struct soc_enum aif2dacr_src = SOC_ENUM_SINGLE(WM8994_AIF2_CONTROL_2, 14, 2, aif_chan_src_text); +static void wm8958_mbc_apply(struct snd_soc_codec *codec, int mbc, int start) +{ + struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); + int pwr_reg = snd_soc_read(codec, WM8994_POWER_MANAGEMENT_5); + int ena, reg, aif; + + switch (mbc) { + case 0: + pwr_reg &= (WM8994_AIF1DAC1L_ENA | WM8994_AIF1DAC1R_ENA); + aif = 0; + break; + case 1: + pwr_reg &= (WM8994_AIF1DAC2L_ENA | WM8994_AIF1DAC2R_ENA); + aif = 0; + break; + case 2: + pwr_reg &= (WM8994_AIF2DACL_ENA | WM8994_AIF2DACR_ENA); + aif = 1; + break; + default: + BUG(); + return; + } + + /* We can only enable the MBC if the AIF is enabled and we + * want it to be enabled. */ + ena = pwr_reg && wm8994->mbc_ena[mbc]; + + reg = snd_soc_read(codec, WM8958_DSP2_PROGRAM); + + dev_dbg(codec->dev, "MBC %d startup: %d, power: %x, DSP: %x\n", + mbc, start, pwr_reg, reg); + + if (start && ena) { + /* If the DSP is already running then noop */ + if (reg & WM8958_DSP2_ENA) + return; + + /* Switch the clock over to the appropriate AIF */ + snd_soc_update_bits(codec, WM8994_CLOCKING_1, + WM8958_DSP2CLK_SRC | WM8958_DSP2CLK_ENA, + aif << WM8958_DSP2CLK_SRC_SHIFT | + WM8958_DSP2CLK_ENA); + + snd_soc_update_bits(codec, WM8958_DSP2_PROGRAM, + WM8958_DSP2_ENA, WM8958_DSP2_ENA); + + /* TODO: Apply any user specified MBC settings */ + + /* Run the DSP */ + snd_soc_write(codec, WM8958_DSP2_EXECCONTROL, + WM8958_DSP2_RUNR); + + /* And we're off! */ + snd_soc_update_bits(codec, WM8958_DSP2_CONFIG, + WM8958_MBC_ENA | WM8958_MBC_SEL_MASK, + mbc << WM8958_MBC_SEL_SHIFT | + WM8958_MBC_ENA); + } else { + /* If the DSP is already stopped then noop */ + if (!(reg & WM8958_DSP2_ENA)) + return; + + snd_soc_update_bits(codec, WM8958_DSP2_CONFIG, + WM8958_MBC_ENA, 0); + snd_soc_update_bits(codec, WM8958_DSP2_PROGRAM, + WM8958_DSP2_ENA, 0); + snd_soc_update_bits(codec, WM8994_CLOCKING_1, + WM8958_DSP2CLK_ENA, 0); + } +} + +static int wm8958_aif_ev(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = w->codec; + int mbc; + + switch (w->shift) { + case 13: + case 12: + mbc = 2; + break; + case 11: + case 10: + mbc = 1; + break; + case 9: + case 8: + mbc = 0; + break; + default: + BUG(); + return -EINVAL; + } + + switch (event) { + case SND_SOC_DAPM_POST_PMU: + wm8958_mbc_apply(codec, mbc, 1); + break; + case SND_SOC_DAPM_POST_PMD: + wm8958_mbc_apply(codec, mbc, 0); + break; + } + + return 0; +} + +static int wm8958_mbc_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; + uinfo->count = 1; + uinfo->value.integer.min = 0; + uinfo->value.integer.max = 1; + return 0; +} + +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 wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); + + ucontrol->value.integer.value[0] = wm8994->mbc_ena[mbc]; + + return 0; +} + +static int wm8958_mbc_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + int mbc = kcontrol->private_value; + int i; + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); + + if (ucontrol->value.integer.value[0] > 1) + return -EINVAL; + + for (i = 0; i < ARRAY_SIZE(wm8994->mbc_ena); i++) { + if (mbc != i && wm8994->mbc_ena[i]) { + dev_dbg(codec->dev, "MBC %d active already\n", mbc); + return -EBUSY; + } + } + + wm8994->mbc_ena[mbc] = ucontrol->value.integer.value[0]; + + wm8958_mbc_apply(codec, mbc, wm8994->mbc_ena[mbc]); + + return 0; +} + +#define WM8958_MBC_SWITCH(xname, xval) {\ + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \ + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE,\ + .info = wm8958_mbc_info, \ + .get = wm8958_mbc_get, .put = wm8958_mbc_put, \ + .private_value = xval } + static const struct snd_kcontrol_new wm8994_snd_controls[] = { SOC_DOUBLE_R_TLV("AIF1ADC1 Volume", WM8994_AIF1_ADC1_LEFT_VOLUME, WM8994_AIF1_ADC1_RIGHT_VOLUME, @@ -649,6 +814,9 @@ SOC_SINGLE_TLV("AIF2 EQ5 Volume", WM8994_AIF2_EQ_GAINS_2, 6, 31, 0, static const struct snd_kcontrol_new wm8958_snd_controls[] = { SOC_SINGLE_TLV("AIF3 Boost Volume", WM8958_AIF3_CONTROL_2, 10, 3, 0, aif_tlv), +WM8958_MBC_SWITCH("AIF1DAC1 MBC Switch", 0), +WM8958_MBC_SWITCH("AIF1DAC2 MBC Switch", 1), +WM8958_MBC_SWITCH("AIF2DAC MBC Switch", 2), }; static int clk_sys_event(struct snd_soc_dapm_widget *w, @@ -1018,19 +1186,23 @@ SND_SOC_DAPM_AIF_OUT("AIF1ADC1L", "AIF1 Capture", 0, WM8994_POWER_MANAGEMENT_4, 9, 0), SND_SOC_DAPM_AIF_OUT("AIF1ADC1R", "AIF1 Capture", 0, WM8994_POWER_MANAGEMENT_4, 8, 0), -SND_SOC_DAPM_AIF_IN("AIF1DAC1L", NULL, 0, - WM8994_POWER_MANAGEMENT_5, 9, 0), -SND_SOC_DAPM_AIF_IN("AIF1DAC1R", NULL, 0, - WM8994_POWER_MANAGEMENT_5, 8, 0), +SND_SOC_DAPM_AIF_IN_E("AIF1DAC1L", NULL, 0, + WM8994_POWER_MANAGEMENT_5, 9, 0, wm8958_aif_ev, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), +SND_SOC_DAPM_AIF_IN_E("AIF1DAC1R", NULL, 0, + WM8994_POWER_MANAGEMENT_5, 8, 0, wm8958_aif_ev, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), SND_SOC_DAPM_AIF_OUT("AIF1ADC2L", "AIF1 Capture", 0, WM8994_POWER_MANAGEMENT_4, 11, 0), SND_SOC_DAPM_AIF_OUT("AIF1ADC2R", "AIF1 Capture", 0, WM8994_POWER_MANAGEMENT_4, 10, 0), -SND_SOC_DAPM_AIF_IN("AIF1DAC2L", NULL, 0, - WM8994_POWER_MANAGEMENT_5, 11, 0), -SND_SOC_DAPM_AIF_IN("AIF1DAC2R", NULL, 0, - WM8994_POWER_MANAGEMENT_5, 10, 0), +SND_SOC_DAPM_AIF_IN_E("AIF1DAC2L", NULL, 0, + WM8994_POWER_MANAGEMENT_5, 11, 0, wm8958_aif_ev, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), +SND_SOC_DAPM_AIF_IN_E("AIF1DAC2R", NULL, 0, + WM8994_POWER_MANAGEMENT_5, 10, 0, wm8958_aif_ev, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), SND_SOC_DAPM_MIXER("AIF1ADC1L Mixer", SND_SOC_NOPM, 0, 0, aif1adc1l_mix, ARRAY_SIZE(aif1adc1l_mix)), @@ -1059,10 +1231,12 @@ SND_SOC_DAPM_AIF_OUT("AIF2ADCL", NULL, 0, WM8994_POWER_MANAGEMENT_4, 13, 0), SND_SOC_DAPM_AIF_OUT("AIF2ADCR", NULL, 0, WM8994_POWER_MANAGEMENT_4, 12, 0), -SND_SOC_DAPM_AIF_IN("AIF2DACL", NULL, 0, - WM8994_POWER_MANAGEMENT_5, 13, 0), -SND_SOC_DAPM_AIF_IN("AIF2DACR", NULL, 0, - WM8994_POWER_MANAGEMENT_5, 12, 0), +SND_SOC_DAPM_AIF_IN_E("AIF2DACL", NULL, 0, + WM8994_POWER_MANAGEMENT_5, 13, 0, wm8958_aif_ev, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), +SND_SOC_DAPM_AIF_IN_E("AIF2DACR", NULL, 0, + WM8994_POWER_MANAGEMENT_5, 12, 0, wm8958_aif_ev, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), SND_SOC_DAPM_AIF_IN("AIF1DACDAT", "AIF1 Playback", 0, SND_SOC_NOPM, 0, 0), SND_SOC_DAPM_AIF_IN("AIF2DACDAT", "AIF2 Playback", 0, SND_SOC_NOPM, 0, 0), -- cgit v1.2.3 From 821edd2fb5b289b84d715fb744106019fa2e1920 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 26 Nov 2010 15:21:09 +0000 Subject: ASoC: Add WM8958 microphone detection support The WM8958 contains an advanced accessory detection feature which allows detection of up to seven different impedence levels on the microphone bias output, including detection of video outputs. Since some of the more involved accessory interfaces may involve noticable interactions with external components a simple detection scheme is provided by default with the option to provide custom handling of accessory detect. Signed-off-by: Mark Brown Acked-by: Liam Girdwood --- include/linux/mfd/wm8994/registers.h | 43 ++++++++++ sound/soc/codecs/wm8994.c | 150 +++++++++++++++++++++++++++++++++++ sound/soc/codecs/wm8994.h | 4 + 3 files changed, 197 insertions(+) diff --git a/include/linux/mfd/wm8994/registers.h b/include/linux/mfd/wm8994/registers.h index 423b2b5c94ea..a610c8746436 100644 --- a/include/linux/mfd/wm8994/registers.h +++ b/include/linux/mfd/wm8994/registers.h @@ -70,6 +70,9 @@ #define WM8994_DC_SERVO_4 0x57 #define WM8994_DC_SERVO_READBACK 0x58 #define WM8994_ANALOGUE_HP_1 0x60 +#define WM8958_MIC_DETECT_1 0xD0 +#define WM8958_MIC_DETECT_2 0xD1 +#define WM8958_MIC_DETECT_3 0xD2 #define WM8994_CHIP_REVISION 0x100 #define WM8994_CONTROL_INTERFACE 0x101 #define WM8994_WRITE_SEQUENCER_CTRL_1 0x110 @@ -1970,6 +1973,46 @@ #define WM8994_HPOUT1R_DLY_SHIFT 1 /* HPOUT1R_DLY */ #define WM8994_HPOUT1R_DLY_WIDTH 1 /* HPOUT1R_DLY */ +/* + * R208 (0xD0) - Mic Detect 1 + */ +#define WM8958_MICD_BIAS_STARTTIME_MASK 0xF000 /* MICD_BIAS_STARTTIME - [15:12] */ +#define WM8958_MICD_BIAS_STARTTIME_SHIFT 12 /* MICD_BIAS_STARTTIME - [15:12] */ +#define WM8958_MICD_BIAS_STARTTIME_WIDTH 4 /* MICD_BIAS_STARTTIME - [15:12] */ +#define WM8958_MICD_RATE_MASK 0x0F00 /* MICD_RATE - [11:8] */ +#define WM8958_MICD_RATE_SHIFT 8 /* MICD_RATE - [11:8] */ +#define WM8958_MICD_RATE_WIDTH 4 /* MICD_RATE - [11:8] */ +#define WM8958_MICD_DBTIME 0x0002 /* MICD_DBTIME */ +#define WM8958_MICD_DBTIME_MASK 0x0002 /* MICD_DBTIME */ +#define WM8958_MICD_DBTIME_SHIFT 1 /* MICD_DBTIME */ +#define WM8958_MICD_DBTIME_WIDTH 1 /* MICD_DBTIME */ +#define WM8958_MICD_ENA 0x0001 /* MICD_ENA */ +#define WM8958_MICD_ENA_MASK 0x0001 /* MICD_ENA */ +#define WM8958_MICD_ENA_SHIFT 0 /* MICD_ENA */ +#define WM8958_MICD_ENA_WIDTH 1 /* MICD_ENA */ + +/* + * R209 (0xD1) - Mic Detect 2 + */ +#define WM8958_MICD_LVL_SEL_MASK 0x00FF /* MICD_LVL_SEL - [7:0] */ +#define WM8958_MICD_LVL_SEL_SHIFT 0 /* MICD_LVL_SEL - [7:0] */ +#define WM8958_MICD_LVL_SEL_WIDTH 8 /* MICD_LVL_SEL - [7:0] */ + +/* + * R210 (0xD2) - Mic Detect 3 + */ +#define WM8958_MICD_LVL_MASK 0x07FC /* MICD_LVL - [10:2] */ +#define WM8958_MICD_LVL_SHIFT 2 /* MICD_LVL - [10:2] */ +#define WM8958_MICD_LVL_WIDTH 9 /* MICD_LVL - [10:2] */ +#define WM8958_MICD_VALID 0x0002 /* MICD_VALID */ +#define WM8958_MICD_VALID_MASK 0x0002 /* MICD_VALID */ +#define WM8958_MICD_VALID_SHIFT 1 /* MICD_VALID */ +#define WM8958_MICD_VALID_WIDTH 1 /* MICD_VALID */ +#define WM8958_MICD_STS 0x0001 /* MICD_STS */ +#define WM8958_MICD_STS_MASK 0x0001 /* MICD_STS */ +#define WM8958_MICD_STS_SHIFT 0 /* MICD_STS */ +#define WM8958_MICD_STS_WIDTH 1 /* MICD_STS */ + /* * R256 (0x100) - Chip Revision */ diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index b30b2dd3f1f4..948677b581b1 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -95,6 +96,11 @@ struct wm8994_priv { struct wm8994_micdet micdet[2]; + wm8958_micdet_cb jack_cb; + void *jack_cb_data; + bool jack_is_mic; + bool jack_is_video; + int revision; struct wm8994_pdata *pdata; }; @@ -140,6 +146,7 @@ static int wm8994_volatile(unsigned int reg) case WM8994_LDO_1: case WM8994_LDO_2: case WM8958_DSP2_EXECCONTROL: + case WM8958_MIC_DETECT_3: return 1; default: return 0; @@ -2633,6 +2640,133 @@ static irqreturn_t wm8994_mic_irq(int irq, void *data) return IRQ_HANDLED; } +/* Default microphone detection handler for WM8958 - the user can + * override this if they wish. + */ +static void wm8958_default_micdet(u16 status, void *data) +{ + struct snd_soc_codec *codec = data; + struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); + int report = 0; + + /* If nothing present then clear our statuses */ + if (!(status & WM8958_MICD_STS)) { + wm8994->jack_is_video = false; + wm8994->jack_is_mic = false; + goto done; + } + + /* Assume anything over 475 ohms is a microphone and remember + * that we've seen one (since buttons override it) */ + if (status & 0x600) + wm8994->jack_is_mic = true; + if (wm8994->jack_is_mic) + report |= SND_JACK_MICROPHONE; + + /* Video has an impedence of approximately 75 ohms; assume + * this isn't used as a button and remember it since buttons + * override it. */ + if (status & 0x40) + wm8994->jack_is_video = true; + if (wm8994->jack_is_video) + report |= SND_JACK_VIDEOOUT; + + /* Everything else is buttons; just assign slots */ + if (status & 0x4) + report |= SND_JACK_BTN_0; + if (status & 0x8) + report |= SND_JACK_BTN_1; + if (status & 0x10) + report |= SND_JACK_BTN_2; + if (status & 0x20) + report |= SND_JACK_BTN_3; + if (status & 0x80) + report |= SND_JACK_BTN_4; + if (status & 0x100) + report |= SND_JACK_BTN_5; + +done: + snd_soc_jack_report(wm8994->micdet[0].jack, + SND_JACK_BTN_0 | SND_JACK_BTN_1 | SND_JACK_BTN_2 | + SND_JACK_BTN_3 | SND_JACK_BTN_4 | SND_JACK_BTN_5 | + SND_JACK_MICROPHONE | SND_JACK_VIDEOOUT, + report); +} + +/** + * wm8958_mic_detect - Enable microphone detection via the WM8958 IRQ + * + * @codec: WM8958 codec + * @jack: jack to report detection events on + * + * Enable microphone detection functionality for the WM8958. By + * default simple detection which supports the detection of up to 6 + * buttons plus video and microphone functionality is supported. + * + * The WM8958 has an advanced jack detection facility which is able to + * support complex accessory detection, especially when used in + * conjunction with external circuitry. In order to provide maximum + * flexiblity a callback is provided which allows a completely custom + * detection algorithm. + */ +int wm8958_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack, + wm8958_micdet_cb cb, void *cb_data) +{ + struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); + struct wm8994 *control = codec->control_data; + + if (control->type != WM8958) + return -EINVAL; + + if (jack) { + if (!cb) { + dev_dbg(codec->dev, "Using default micdet callback\n"); + cb = wm8958_default_micdet; + cb_data = codec; + } + + wm8994->micdet[0].jack = jack; + wm8994->jack_cb = cb; + wm8994->jack_cb_data = cb_data; + + snd_soc_update_bits(codec, WM8958_MIC_DETECT_1, + WM8958_MICD_ENA, WM8958_MICD_ENA); + } else { + snd_soc_update_bits(codec, WM8958_MIC_DETECT_1, + WM8958_MICD_ENA, 0); + } + + return 0; +} +EXPORT_SYMBOL_GPL(wm8958_mic_detect); + +static irqreturn_t wm8958_mic_irq(int irq, void *data) +{ + struct wm8994_priv *wm8994 = data; + struct snd_soc_codec *codec = wm8994->codec; + int reg; + + reg = snd_soc_read(codec, WM8958_MIC_DETECT_3); + if (reg < 0) { + dev_err(codec->dev, "Failed to read mic detect status: %d\n", + reg); + return IRQ_NONE; + } + + if (!(reg & WM8958_MICD_VALID)) { + dev_dbg(codec->dev, "Mic detect data not valid\n"); + goto out; + } + + if (wm8994->jack_cb) + wm8994->jack_cb(reg, wm8994->jack_cb_data); + else + dev_warn(codec->dev, "Accessory detection with no callback\n"); + +out: + return IRQ_HANDLED; +} + static int wm8994_codec_probe(struct snd_soc_codec *codec) { struct wm8994 *control; @@ -2732,6 +2866,17 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) "Failed to request Mic2 short IRQ: %d\n", ret); break; + + case WM8958: + ret = wm8994_request_irq(codec->control_data, + WM8994_IRQ_MIC1_DET, + wm8958_mic_irq, "Mic detect", + wm8994); + if (ret != 0) + dev_warn(codec->dev, + "Failed to request Mic detect IRQ: %d\n", + ret); + break; } /* Remember if AIFnLRCLK is configured as a GPIO. This should be @@ -2866,6 +3011,11 @@ static int wm8994_codec_remove(struct snd_soc_codec *codec) wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC1_DET, wm8994); break; + + case WM8958: + wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC1_DET, + wm8994); + break; } kfree(wm8994->retune_mobile_texts); kfree(wm8994->drc_texts); diff --git a/sound/soc/codecs/wm8994.h b/sound/soc/codecs/wm8994.h index b8b3166e1f03..455cae6b4356 100644 --- a/sound/soc/codecs/wm8994.h +++ b/sound/soc/codecs/wm8994.h @@ -28,8 +28,12 @@ #define WM8994_FLL_SRC_LRCLK 3 #define WM8994_FLL_SRC_BCLK 4 +typedef void (*wm8958_micdet_cb)(u16 status, void *data); + int wm8994_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack, int micbias, int det, int shrt); +int wm8958_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack, + wm8958_micdet_cb cb, void *cb_data); #define WM8994_CACHE_SIZE 1570 -- cgit v1.2.3 From ca9aef50727dec76ab12513ba833a1cf5e9d7e83 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 26 Nov 2010 17:23:41 +0000 Subject: ASoC: Convert WM8994 to use soc-cache.c cache functions In the process we convert the driver to read registers one at a time when initialising the cache. This has the effect of working around limitations in the sizes of I2C transactions which can be done by some CPUs. Due to the sparseness of the register map the overhead from this should be minimual unless I2C transactions are very expensive to start. Signed-off-by: Mark Brown Acked-by: Liam Girdwood --- sound/soc/codecs/wm8994-tables.c | 1572 ++++++++++++++++++++++++++++++++++++++ sound/soc/codecs/wm8994.c | 95 ++- sound/soc/codecs/wm8994.h | 1 + 3 files changed, 1620 insertions(+), 48 deletions(-) diff --git a/sound/soc/codecs/wm8994-tables.c b/sound/soc/codecs/wm8994-tables.c index 7b935387aeef..68e9b024dd48 100644 --- a/sound/soc/codecs/wm8994-tables.c +++ b/sound/soc/codecs/wm8994-tables.c @@ -1573,3 +1573,1575 @@ const struct wm8994_access_mask wm8994_access_masks[WM8994_CACHE_SIZE] = { { 0x03C3, 0x03C3 }, /* R1569 - Sidetone */ }; +const __devinitdata u16 wm8994_reg_defaults[WM8994_CACHE_SIZE] = { + 0x8994, /* R0 - Software Reset */ + 0x0000, /* R1 - Power Management (1) */ + 0x6000, /* R2 - Power Management (2) */ + 0x0000, /* R3 - Power Management (3) */ + 0x0000, /* R4 - Power Management (4) */ + 0x0000, /* R5 - Power Management (5) */ + 0x0000, /* R6 - Power Management (6) */ + 0x0000, /* R7 */ + 0x0000, /* R8 */ + 0x0000, /* R9 */ + 0x0000, /* R10 */ + 0x0000, /* R11 */ + 0x0000, /* R12 */ + 0x0000, /* R13 */ + 0x0000, /* R14 */ + 0x0000, /* R15 */ + 0x0000, /* R16 */ + 0x0000, /* R17 */ + 0x0000, /* R18 */ + 0x0000, /* R19 */ + 0x0000, /* R20 */ + 0x0000, /* R21 - Input Mixer (1) */ + 0x0000, /* R22 */ + 0x0000, /* R23 */ + 0x008B, /* R24 - Left Line Input 1&2 Volume */ + 0x008B, /* R25 - Left Line Input 3&4 Volume */ + 0x008B, /* R26 - Right Line Input 1&2 Volume */ + 0x008B, /* R27 - Right Line Input 3&4 Volume */ + 0x006D, /* R28 - Left Output Volume */ + 0x006D, /* R29 - Right Output Volume */ + 0x0066, /* R30 - Line Outputs Volume */ + 0x0020, /* R31 - HPOUT2 Volume */ + 0x0079, /* R32 - Left OPGA Volume */ + 0x0079, /* R33 - Right OPGA Volume */ + 0x0003, /* R34 - SPKMIXL Attenuation */ + 0x0003, /* R35 - SPKMIXR Attenuation */ + 0x0011, /* R36 - SPKOUT Mixers */ + 0x0140, /* R37 - ClassD */ + 0x0079, /* R38 - Speaker Volume Left */ + 0x0079, /* R39 - Speaker Volume Right */ + 0x0000, /* R40 - Input Mixer (2) */ + 0x0000, /* R41 - Input Mixer (3) */ + 0x0000, /* R42 - Input Mixer (4) */ + 0x0000, /* R43 - Input Mixer (5) */ + 0x0000, /* R44 - Input Mixer (6) */ + 0x0000, /* R45 - Output Mixer (1) */ + 0x0000, /* R46 - Output Mixer (2) */ + 0x0000, /* R47 - Output Mixer (3) */ + 0x0000, /* R48 - Output Mixer (4) */ + 0x0000, /* R49 - Output Mixer (5) */ + 0x0000, /* R50 - Output Mixer (6) */ + 0x0000, /* R51 - HPOUT2 Mixer */ + 0x0000, /* R52 - Line Mixer (1) */ + 0x0000, /* R53 - Line Mixer (2) */ + 0x0000, /* R54 - Speaker Mixer */ + 0x0000, /* R55 - Additional Control */ + 0x0000, /* R56 - AntiPOP (1) */ + 0x0000, /* R57 - AntiPOP (2) */ + 0x0000, /* R58 - MICBIAS */ + 0x000D, /* R59 - LDO 1 */ + 0x0003, /* R60 - LDO 2 */ + 0x0000, /* R61 */ + 0x0000, /* R62 */ + 0x0000, /* R63 */ + 0x0000, /* R64 */ + 0x0000, /* R65 */ + 0x0000, /* R66 */ + 0x0000, /* R67 */ + 0x0000, /* R68 */ + 0x0000, /* R69 */ + 0x0000, /* R70 */ + 0x0000, /* R71 */ + 0x0000, /* R72 */ + 0x0000, /* R73 */ + 0x0000, /* R74 */ + 0x0000, /* R75 */ + 0x1F25, /* R76 - Charge Pump (1) */ + 0x0000, /* R77 */ + 0x0000, /* R78 */ + 0x0000, /* R79 */ + 0x0000, /* R80 */ + 0x0004, /* R81 - Class W (1) */ + 0x0000, /* R82 */ + 0x0000, /* R83 */ + 0x0000, /* R84 - DC Servo (1) */ + 0x054A, /* R85 - DC Servo (2) */ + 0x0000, /* R86 */ + 0x0000, /* R87 - DC Servo (4) */ + 0x0000, /* R88 - DC Servo Readback */ + 0x0000, /* R89 */ + 0x0000, /* R90 */ + 0x0000, /* R91 */ + 0x0000, /* R92 */ + 0x0000, /* R93 */ + 0x0000, /* R94 */ + 0x0000, /* R95 */ + 0x0000, /* R96 - Analogue HP (1) */ + 0x0000, /* R97 */ + 0x0000, /* R98 */ + 0x0000, /* R99 */ + 0x0000, /* R100 */ + 0x0000, /* R101 */ + 0x0000, /* R102 */ + 0x0000, /* R103 */ + 0x0000, /* R104 */ + 0x0000, /* R105 */ + 0x0000, /* R106 */ + 0x0000, /* R107 */ + 0x0000, /* R108 */ + 0x0000, /* R109 */ + 0x0000, /* R110 */ + 0x0000, /* R111 */ + 0x0000, /* R112 */ + 0x0000, /* R113 */ + 0x0000, /* R114 */ + 0x0000, /* R115 */ + 0x0000, /* R116 */ + 0x0000, /* R117 */ + 0x0000, /* R118 */ + 0x0000, /* R119 */ + 0x0000, /* R120 */ + 0x0000, /* R121 */ + 0x0000, /* R122 */ + 0x0000, /* R123 */ + 0x0000, /* R124 */ + 0x0000, /* R125 */ + 0x0000, /* R126 */ + 0x0000, /* R127 */ + 0x0000, /* R128 */ + 0x0000, /* R129 */ + 0x0000, /* R130 */ + 0x0000, /* R131 */ + 0x0000, /* R132 */ + 0x0000, /* R133 */ + 0x0000, /* R134 */ + 0x0000, /* R135 */ + 0x0000, /* R136 */ + 0x0000, /* R137 */ + 0x0000, /* R138 */ + 0x0000, /* R139 */ + 0x0000, /* R140 */ + 0x0000, /* R141 */ + 0x0000, /* R142 */ + 0x0000, /* R143 */ + 0x0000, /* R144 */ + 0x0000, /* R145 */ + 0x0000, /* R146 */ + 0x0000, /* R147 */ + 0x0000, /* R148 */ + 0x0000, /* R149 */ + 0x0000, /* R150 */ + 0x0000, /* R151 */ + 0x0000, /* R152 */ + 0x0000, /* R153 */ + 0x0000, /* R154 */ + 0x0000, /* R155 */ + 0x0000, /* R156 */ + 0x0000, /* R157 */ + 0x0000, /* R158 */ + 0x0000, /* R159 */ + 0x0000, /* R160 */ + 0x0000, /* R161 */ + 0x0000, /* R162 */ + 0x0000, /* R163 */ + 0x0000, /* R164 */ + 0x0000, /* R165 */ + 0x0000, /* R166 */ + 0x0000, /* R167 */ + 0x0000, /* R168 */ + 0x0000, /* R169 */ + 0x0000, /* R170 */ + 0x0000, /* R171 */ + 0x0000, /* R172 */ + 0x0000, /* R173 */ + 0x0000, /* R174 */ + 0x0000, /* R175 */ + 0x0000, /* R176 */ + 0x0000, /* R177 */ + 0x0000, /* R178 */ + 0x0000, /* R179 */ + 0x0000, /* R180 */ + 0x0000, /* R181 */ + 0x0000, /* R182 */ + 0x0000, /* R183 */ + 0x0000, /* R184 */ + 0x0000, /* R185 */ + 0x0000, /* R186 */ + 0x0000, /* R187 */ + 0x0000, /* R188 */ + 0x0000, /* R189 */ + 0x0000, /* R190 */ + 0x0000, /* R191 */ + 0x0000, /* R192 */ + 0x0000, /* R193 */ + 0x0000, /* R194 */ + 0x0000, /* R195 */ + 0x0000, /* R196 */ + 0x0000, /* R197 */ + 0x0000, /* R198 */ + 0x0000, /* R199 */ + 0x0000, /* R200 */ + 0x0000, /* R201 */ + 0x0000, /* R202 */ + 0x0000, /* R203 */ + 0x0000, /* R204 */ + 0x0000, /* R205 */ + 0x0000, /* R206 */ + 0x0000, /* R207 */ + 0x0000, /* R208 */ + 0x0000, /* R209 */ + 0x0000, /* R210 */ + 0x0000, /* R211 */ + 0x0000, /* R212 */ + 0x0000, /* R213 */ + 0x0000, /* R214 */ + 0x0000, /* R215 */ + 0x0000, /* R216 */ + 0x0000, /* R217 */ + 0x0000, /* R218 */ + 0x0000, /* R219 */ + 0x0000, /* R220 */ + 0x0000, /* R221 */ + 0x0000, /* R222 */ + 0x0000, /* R223 */ + 0x0000, /* R224 */ + 0x0000, /* R225 */ + 0x0000, /* R226 */ + 0x0000, /* R227 */ + 0x0000, /* R228 */ + 0x0000, /* R229 */ + 0x0000, /* R230 */ + 0x0000, /* R231 */ + 0x0000, /* R232 */ + 0x0000, /* R233 */ + 0x0000, /* R234 */ + 0x0000, /* R235 */ + 0x0000, /* R236 */ + 0x0000, /* R237 */ + 0x0000, /* R238 */ + 0x0000, /* R239 */ + 0x0000, /* R240 */ + 0x0000, /* R241 */ + 0x0000, /* R242 */ + 0x0000, /* R243 */ + 0x0000, /* R244 */ + 0x0000, /* R245 */ + 0x0000, /* R246 */ + 0x0000, /* R247 */ + 0x0000, /* R248 */ + 0x0000, /* R249 */ + 0x0000, /* R250 */ + 0x0000, /* R251 */ + 0x0000, /* R252 */ + 0x0000, /* R253 */ + 0x0000, /* R254 */ + 0x0000, /* R255 */ + 0x0003, /* R256 - Chip Revision */ + 0x8004, /* R257 - Control Interface */ + 0x0000, /* R258 */ + 0x0000, /* R259 */ + 0x0000, /* R260 */ + 0x0000, /* R261 */ + 0x0000, /* R262 */ + 0x0000, /* R263 */ + 0x0000, /* R264 */ + 0x0000, /* R265 */ + 0x0000, /* R266 */ + 0x0000, /* R267 */ + 0x0000, /* R268 */ + 0x0000, /* R269 */ + 0x0000, /* R270 */ + 0x0000, /* R271 */ + 0x0000, /* R272 - Write Sequencer Ctrl (1) */ + 0x0000, /* R273 - Write Sequencer Ctrl (2) */ + 0x0000, /* R274 */ + 0x0000, /* R275 */ + 0x0000, /* R276 */ + 0x0000, /* R277 */ + 0x0000, /* R278 */ + 0x0000, /* R279 */ + 0x0000, /* R280 */ + 0x0000, /* R281 */ + 0x0000, /* R282 */ + 0x0000, /* R283 */ + 0x0000, /* R284 */ + 0x0000, /* R285 */ + 0x0000, /* R286 */ + 0x0000, /* R287 */ + 0x0000, /* R288 */ + 0x0000, /* R289 */ + 0x0000, /* R290 */ + 0x0000, /* R291 */ + 0x0000, /* R292 */ + 0x0000, /* R293 */ + 0x0000, /* R294 */ + 0x0000, /* R295 */ + 0x0000, /* R296 */ + 0x0000, /* R297 */ + 0x0000, /* R298 */ + 0x0000, /* R299 */ + 0x0000, /* R300 */ + 0x0000, /* R301 */ + 0x0000, /* R302 */ + 0x0000, /* R303 */ + 0x0000, /* R304 */ + 0x0000, /* R305 */ + 0x0000, /* R306 */ + 0x0000, /* R307 */ + 0x0000, /* R308 */ + 0x0000, /* R309 */ + 0x0000, /* R310 */ + 0x0000, /* R311 */ + 0x0000, /* R312 */ + 0x0000, /* R313 */ + 0x0000, /* R314 */ + 0x0000, /* R315 */ + 0x0000, /* R316 */ + 0x0000, /* R317 */ + 0x0000, /* R318 */ + 0x0000, /* R319 */ + 0x0000, /* R320 */ + 0x0000, /* R321 */ + 0x0000, /* R322 */ + 0x0000, /* R323 */ + 0x0000, /* R324 */ + 0x0000, /* R325 */ + 0x0000, /* R326 */ + 0x0000, /* R327 */ + 0x0000, /* R328 */ + 0x0000, /* R329 */ + 0x0000, /* R330 */ + 0x0000, /* R331 */ + 0x0000, /* R332 */ + 0x0000, /* R333 */ + 0x0000, /* R334 */ + 0x0000, /* R335 */ + 0x0000, /* R336 */ + 0x0000, /* R337 */ + 0x0000, /* R338 */ + 0x0000, /* R339 */ + 0x0000, /* R340 */ + 0x0000, /* R341 */ + 0x0000, /* R342 */ + 0x0000, /* R343 */ + 0x0000, /* R344 */ + 0x0000, /* R345 */ + 0x0000, /* R346 */ + 0x0000, /* R347 */ + 0x0000, /* R348 */ + 0x0000, /* R349 */ + 0x0000, /* R350 */ + 0x0000, /* R351 */ + 0x0000, /* R352 */ + 0x0000, /* R353 */ + 0x0000, /* R354 */ + 0x0000, /* R355 */ + 0x0000, /* R356 */ + 0x0000, /* R357 */ + 0x0000, /* R358 */ + 0x0000, /* R359 */ + 0x0000, /* R360 */ + 0x0000, /* R361 */ + 0x0000, /* R362 */ + 0x0000, /* R363 */ + 0x0000, /* R364 */ + 0x0000, /* R365 */ + 0x0000, /* R366 */ + 0x0000, /* R367 */ + 0x0000, /* R368 */ + 0x0000, /* R369 */ + 0x0000, /* R370 */ + 0x0000, /* R371 */ + 0x0000, /* R372 */ + 0x0000, /* R373 */ + 0x0000, /* R374 */ + 0x0000, /* R375 */ + 0x0000, /* R376 */ + 0x0000, /* R377 */ + 0x0000, /* R378 */ + 0x0000, /* R379 */ + 0x0000, /* R380 */ + 0x0000, /* R381 */ + 0x0000, /* R382 */ + 0x0000, /* R383 */ + 0x0000, /* R384 */ + 0x0000, /* R385 */ + 0x0000, /* R386 */ + 0x0000, /* R387 */ + 0x0000, /* R388 */ + 0x0000, /* R389 */ + 0x0000, /* R390 */ + 0x0000, /* R391 */ + 0x0000, /* R392 */ + 0x0000, /* R393 */ + 0x0000, /* R394 */ + 0x0000, /* R395 */ + 0x0000, /* R396 */ + 0x0000, /* R397 */ + 0x0000, /* R398 */ + 0x0000, /* R399 */ + 0x0000, /* R400 */ + 0x0000, /* R401 */ + 0x0000, /* R402 */ + 0x0000, /* R403 */ + 0x0000, /* R404 */ + 0x0000, /* R405 */ + 0x0000, /* R406 */ + 0x0000, /* R407 */ + 0x0000, /* R408 */ + 0x0000, /* R409 */ + 0x0000, /* R410 */ + 0x0000, /* R411 */ + 0x0000, /* R412 */ + 0x0000, /* R413 */ + 0x0000, /* R414 */ + 0x0000, /* R415 */ + 0x0000, /* R416 */ + 0x0000, /* R417 */ + 0x0000, /* R418 */ + 0x0000, /* R419 */ + 0x0000, /* R420 */ + 0x0000, /* R421 */ + 0x0000, /* R422 */ + 0x0000, /* R423 */ + 0x0000, /* R424 */ + 0x0000, /* R425 */ + 0x0000, /* R426 */ + 0x0000, /* R427 */ + 0x0000, /* R428 */ + 0x0000, /* R429 */ + 0x0000, /* R430 */ + 0x0000, /* R431 */ + 0x0000, /* R432 */ + 0x0000, /* R433 */ + 0x0000, /* R434 */ + 0x0000, /* R435 */ + 0x0000, /* R436 */ + 0x0000, /* R437 */ + 0x0000, /* R438 */ + 0x0000, /* R439 */ + 0x0000, /* R440 */ + 0x0000, /* R441 */ + 0x0000, /* R442 */ + 0x0000, /* R443 */ + 0x0000, /* R444 */ + 0x0000, /* R445 */ + 0x0000, /* R446 */ + 0x0000, /* R447 */ + 0x0000, /* R448 */ + 0x0000, /* R449 */ + 0x0000, /* R450 */ + 0x0000, /* R451 */ + 0x0000, /* R452 */ + 0x0000, /* R453 */ + 0x0000, /* R454 */ + 0x0000, /* R455 */ + 0x0000, /* R456 */ + 0x0000, /* R457 */ + 0x0000, /* R458 */ + 0x0000, /* R459 */ + 0x0000, /* R460 */ + 0x0000, /* R461 */ + 0x0000, /* R462 */ + 0x0000, /* R463 */ + 0x0000, /* R464 */ + 0x0000, /* R465 */ + 0x0000, /* R466 */ + 0x0000, /* R467 */ + 0x0000, /* R468 */ + 0x0000, /* R469 */ + 0x0000, /* R470 */ + 0x0000, /* R471 */ + 0x0000, /* R472 */ + 0x0000, /* R473 */ + 0x0000, /* R474 */ + 0x0000, /* R475 */ + 0x0000, /* R476 */ + 0x0000, /* R477 */ + 0x0000, /* R478 */ + 0x0000, /* R479 */ + 0x0000, /* R480 */ + 0x0000, /* R481 */ + 0x0000, /* R482 */ + 0x0000, /* R483 */ + 0x0000, /* R484 */ + 0x0000, /* R485 */ + 0x0000, /* R486 */ + 0x0000, /* R487 */ + 0x0000, /* R488 */ + 0x0000, /* R489 */ + 0x0000, /* R490 */ + 0x0000, /* R491 */ + 0x0000, /* R492 */ + 0x0000, /* R493 */ + 0x0000, /* R494 */ + 0x0000, /* R495 */ + 0x0000, /* R496 */ + 0x0000, /* R497 */ + 0x0000, /* R498 */ + 0x0000, /* R499 */ + 0x0000, /* R500 */ + 0x0000, /* R501 */ + 0x0000, /* R502 */ + 0x0000, /* R503 */ + 0x0000, /* R504 */ + 0x0000, /* R505 */ + 0x0000, /* R506 */ + 0x0000, /* R507 */ + 0x0000, /* R508 */ + 0x0000, /* R509 */ + 0x0000, /* R510 */ + 0x0000, /* R511 */ + 0x0000, /* R512 - AIF1 Clocking (1) */ + 0x0000, /* R513 - AIF1 Clocking (2) */ + 0x0000, /* R514 */ + 0x0000, /* R515 */ + 0x0000, /* R516 - AIF2 Clocking (1) */ + 0x0000, /* R517 - AIF2 Clocking (2) */ + 0x0000, /* R518 */ + 0x0000, /* R519 */ + 0x0000, /* R520 - Clocking (1) */ + 0x0000, /* R521 - Clocking (2) */ + 0x0000, /* R522 */ + 0x0000, /* R523 */ + 0x0000, /* R524 */ + 0x0000, /* R525 */ + 0x0000, /* R526 */ + 0x0000, /* R527 */ + 0x0083, /* R528 - AIF1 Rate */ + 0x0083, /* R529 - AIF2 Rate */ + 0x0000, /* R530 - Rate Status */ + 0x0000, /* R531 */ + 0x0000, /* R532 */ + 0x0000, /* R533 */ + 0x0000, /* R534 */ + 0x0000, /* R535 */ + 0x0000, /* R536 */ + 0x0000, /* R537 */ + 0x0000, /* R538 */ + 0x0000, /* R539 */ + 0x0000, /* R540 */ + 0x0000, /* R541 */ + 0x0000, /* R542 */ + 0x0000, /* R543 */ + 0x0000, /* R544 - FLL1 Control (1) */ + 0x0000, /* R545 - FLL1 Control (2) */ + 0x0000, /* R546 - FLL1 Control (3) */ + 0x0000, /* R547 - FLL1 Control (4) */ + 0x0C80, /* R548 - FLL1 Control (5) */ + 0x0000, /* R549 */ + 0x0000, /* R550 */ + 0x0000, /* R551 */ + 0x0000, /* R552 */ + 0x0000, /* R553 */ + 0x0000, /* R554 */ + 0x0000, /* R555 */ + 0x0000, /* R556 */ + 0x0000, /* R557 */ + 0x0000, /* R558 */ + 0x0000, /* R559 */ + 0x0000, /* R560 */ + 0x0000, /* R561 */ + 0x0000, /* R562 */ + 0x0000, /* R563 */ + 0x0000, /* R564 */ + 0x0000, /* R565 */ + 0x0000, /* R566 */ + 0x0000, /* R567 */ + 0x0000, /* R568 */ + 0x0000, /* R569 */ + 0x0000, /* R570 */ + 0x0000, /* R571 */ + 0x0000, /* R572 */ + 0x0000, /* R573 */ + 0x0000, /* R574 */ + 0x0000, /* R575 */ + 0x0000, /* R576 - FLL2 Control (1) */ + 0x0000, /* R577 - FLL2 Control (2) */ + 0x0000, /* R578 - FLL2 Control (3) */ + 0x0000, /* R579 - FLL2 Control (4) */ + 0x0C80, /* R580 - FLL2 Control (5) */ + 0x0000, /* R581 */ + 0x0000, /* R582 */ + 0x0000, /* R583 */ + 0x0000, /* R584 */ + 0x0000, /* R585 */ + 0x0000, /* R586 */ + 0x0000, /* R587 */ + 0x0000, /* R588 */ + 0x0000, /* R589 */ + 0x0000, /* R590 */ + 0x0000, /* R591 */ + 0x0000, /* R592 */ + 0x0000, /* R593 */ + 0x0000, /* R594 */ + 0x0000, /* R595 */ + 0x0000, /* R596 */ + 0x0000, /* R597 */ + 0x0000, /* R598 */ + 0x0000, /* R599 */ + 0x0000, /* R600 */ + 0x0000, /* R601 */ + 0x0000, /* R602 */ + 0x0000, /* R603 */ + 0x0000, /* R604 */ + 0x0000, /* R605 */ + 0x0000, /* R606 */ + 0x0000, /* R607 */ + 0x0000, /* R608 */ + 0x0000, /* R609 */ + 0x0000, /* R610 */ + 0x0000, /* R611 */ + 0x0000, /* R612 */ + 0x0000, /* R613 */ + 0x0000, /* R614 */ + 0x0000, /* R615 */ + 0x0000, /* R616 */ + 0x0000, /* R617 */ + 0x0000, /* R618 */ + 0x0000, /* R619 */ + 0x0000, /* R620 */ + 0x0000, /* R621 */ + 0x0000, /* R622 */ + 0x0000, /* R623 */ + 0x0000, /* R624 */ + 0x0000, /* R625 */ + 0x0000, /* R626 */ + 0x0000, /* R627 */ + 0x0000, /* R628 */ + 0x0000, /* R629 */ + 0x0000, /* R630 */ + 0x0000, /* R631 */ + 0x0000, /* R632 */ + 0x0000, /* R633 */ + 0x0000, /* R634 */ + 0x0000, /* R635 */ + 0x0000, /* R636 */ + 0x0000, /* R637 */ + 0x0000, /* R638 */ + 0x0000, /* R639 */ + 0x0000, /* R640 */ + 0x0000, /* R641 */ + 0x0000, /* R642 */ + 0x0000, /* R643 */ + 0x0000, /* R644 */ + 0x0000, /* R645 */ + 0x0000, /* R646 */ + 0x0000, /* R647 */ + 0x0000, /* R648 */ + 0x0000, /* R649 */ + 0x0000, /* R650 */ + 0x0000, /* R651 */ + 0x0000, /* R652 */ + 0x0000, /* R653 */ + 0x0000, /* R654 */ + 0x0000, /* R655 */ + 0x0000, /* R656 */ + 0x0000, /* R657 */ + 0x0000, /* R658 */ + 0x0000, /* R659 */ + 0x0000, /* R660 */ + 0x0000, /* R661 */ + 0x0000, /* R662 */ + 0x0000, /* R663 */ + 0x0000, /* R664 */ + 0x0000, /* R665 */ + 0x0000, /* R666 */ + 0x0000, /* R667 */ + 0x0000, /* R668 */ + 0x0000, /* R669 */ + 0x0000, /* R670 */ + 0x0000, /* R671 */ + 0x0000, /* R672 */ + 0x0000, /* R673 */ + 0x0000, /* R674 */ + 0x0000, /* R675 */ + 0x0000, /* R676 */ + 0x0000, /* R677 */ + 0x0000, /* R678 */ + 0x0000, /* R679 */ + 0x0000, /* R680 */ + 0x0000, /* R681 */ + 0x0000, /* R682 */ + 0x0000, /* R683 */ + 0x0000, /* R684 */ + 0x0000, /* R685 */ + 0x0000, /* R686 */ + 0x0000, /* R687 */ + 0x0000, /* R688 */ + 0x0000, /* R689 */ + 0x0000, /* R690 */ + 0x0000, /* R691 */ + 0x0000, /* R692 */ + 0x0000, /* R693 */ + 0x0000, /* R694 */ + 0x0000, /* R695 */ + 0x0000, /* R696 */ + 0x0000, /* R697 */ + 0x0000, /* R698 */ + 0x0000, /* R699 */ + 0x0000, /* R700 */ + 0x0000, /* R701 */ + 0x0000, /* R702 */ + 0x0000, /* R703 */ + 0x0000, /* R704 */ + 0x0000, /* R705 */ + 0x0000, /* R706 */ + 0x0000, /* R707 */ + 0x0000, /* R708 */ + 0x0000, /* R709 */ + 0x0000, /* R710 */ + 0x0000, /* R711 */ + 0x0000, /* R712 */ + 0x0000, /* R713 */ + 0x0000, /* R714 */ + 0x0000, /* R715 */ + 0x0000, /* R716 */ + 0x0000, /* R717 */ + 0x0000, /* R718 */ + 0x0000, /* R719 */ + 0x0000, /* R720 */ + 0x0000, /* R721 */ + 0x0000, /* R722 */ + 0x0000, /* R723 */ + 0x0000, /* R724 */ + 0x0000, /* R725 */ + 0x0000, /* R726 */ + 0x0000, /* R727 */ + 0x0000, /* R728 */ + 0x0000, /* R729 */ + 0x0000, /* R730 */ + 0x0000, /* R731 */ + 0x0000, /* R732 */ + 0x0000, /* R733 */ + 0x0000, /* R734 */ + 0x0000, /* R735 */ + 0x0000, /* R736 */ + 0x0000, /* R737 */ + 0x0000, /* R738 */ + 0x0000, /* R739 */ + 0x0000, /* R740 */ + 0x0000, /* R741 */ + 0x0000, /* R742 */ + 0x0000, /* R743 */ + 0x0000, /* R744 */ + 0x0000, /* R745 */ + 0x0000, /* R746 */ + 0x0000, /* R747 */ + 0x0000, /* R748 */ + 0x0000, /* R749 */ + 0x0000, /* R750 */ + 0x0000, /* R751 */ + 0x0000, /* R752 */ + 0x0000, /* R753 */ + 0x0000, /* R754 */ + 0x0000, /* R755 */ + 0x0000, /* R756 */ + 0x0000, /* R757 */ + 0x0000, /* R758 */ + 0x0000, /* R759 */ + 0x0000, /* R760 */ + 0x0000, /* R761 */ + 0x0000, /* R762 */ + 0x0000, /* R763 */ + 0x0000, /* R764 */ + 0x0000, /* R765 */ + 0x0000, /* R766 */ + 0x0000, /* R767 */ + 0x4050, /* R768 - AIF1 Control (1) */ + 0x4000, /* R769 - AIF1 Control (2) */ + 0x0000, /* R770 - AIF1 Master/Slave */ + 0x0040, /* R771 - AIF1 BCLK */ + 0x0040, /* R772 - AIF1ADC LRCLK */ + 0x0040, /* R773 - AIF1DAC LRCLK */ + 0x0004, /* R774 - AIF1DAC Data */ + 0x0100, /* R775 - AIF1ADC Data */ + 0x0000, /* R776 */ + 0x0000, /* R777 */ + 0x0000, /* R778 */ + 0x0000, /* R779 */ + 0x0000, /* R780 */ + 0x0000, /* R781 */ + 0x0000, /* R782 */ + 0x0000, /* R783 */ + 0x4050, /* R784 - AIF2 Control (1) */ + 0x4000, /* R785 - AIF2 Control (2) */ + 0x0000, /* R786 - AIF2 Master/Slave */ + 0x0040, /* R787 - AIF2 BCLK */ + 0x0040, /* R788 - AIF2ADC LRCLK */ + 0x0040, /* R789 - AIF2DAC LRCLK */ + 0x0000, /* R790 - AIF2DAC Data */ + 0x0000, /* R791 - AIF2ADC Data */ + 0x0000, /* R792 */ + 0x0000, /* R793 */ + 0x0000, /* R794 */ + 0x0000, /* R795 */ + 0x0000, /* R796 */ + 0x0000, /* R797 */ + 0x0000, /* R798 */ + 0x0000, /* R799 */ + 0x0000, /* R800 */ + 0x0000, /* R801 */ + 0x0000, /* R802 */ + 0x0000, /* R803 */ + 0x0000, /* R804 */ + 0x0000, /* R805 */ + 0x0000, /* R806 */ + 0x0000, /* R807 */ + 0x0000, /* R808 */ + 0x0000, /* R809 */ + 0x0000, /* R810 */ + 0x0000, /* R811 */ + 0x0000, /* R812 */ + 0x0000, /* R813 */ + 0x0000, /* R814 */ + 0x0000, /* R815 */ + 0x0000, /* R816 */ + 0x0000, /* R817 */ + 0x0000, /* R818 */ + 0x0000, /* R819 */ + 0x0000, /* R820 */ + 0x0000, /* R821 */ + 0x0000, /* R822 */ + 0x0000, /* R823 */ + 0x0000, /* R824 */ + 0x0000, /* R825 */ + 0x0000, /* R826 */ + 0x0000, /* R827 */ + 0x0000, /* R828 */ + 0x0000, /* R829 */ + 0x0000, /* R830 */ + 0x0000, /* R831 */ + 0x0000, /* R832 */ + 0x0000, /* R833 */ + 0x0000, /* R834 */ + 0x0000, /* R835 */ + 0x0000, /* R836 */ + 0x0000, /* R837 */ + 0x0000, /* R838 */ + 0x0000, /* R839 */ + 0x0000, /* R840 */ + 0x0000, /* R841 */ + 0x0000, /* R842 */ + 0x0000, /* R843 */ + 0x0000, /* R844 */ + 0x0000, /* R845 */ + 0x0000, /* R846 */ + 0x0000, /* R847 */ + 0x0000, /* R848 */ + 0x0000, /* R849 */ + 0x0000, /* R850 */ + 0x0000, /* R851 */ + 0x0000, /* R852 */ + 0x0000, /* R853 */ + 0x0000, /* R854 */ + 0x0000, /* R855 */ + 0x0000, /* R856 */ + 0x0000, /* R857 */ + 0x0000, /* R858 */ + 0x0000, /* R859 */ + 0x0000, /* R860 */ + 0x0000, /* R861 */ + 0x0000, /* R862 */ + 0x0000, /* R863 */ + 0x0000, /* R864 */ + 0x0000, /* R865 */ + 0x0000, /* R866 */ + 0x0000, /* R867 */ + 0x0000, /* R868 */ + 0x0000, /* R869 */ + 0x0000, /* R870 */ + 0x0000, /* R871 */ + 0x0000, /* R872 */ + 0x0000, /* R873 */ + 0x0000, /* R874 */ + 0x0000, /* R875 */ + 0x0000, /* R876 */ + 0x0000, /* R877 */ + 0x0000, /* R878 */ + 0x0000, /* R879 */ + 0x0000, /* R880 */ + 0x0000, /* R881 */ + 0x0000, /* R882 */ + 0x0000, /* R883 */ + 0x0000, /* R884 */ + 0x0000, /* R885 */ + 0x0000, /* R886 */ + 0x0000, /* R887 */ + 0x0000, /* R888 */ + 0x0000, /* R889 */ + 0x0000, /* R890 */ + 0x0000, /* R891 */ + 0x0000, /* R892 */ + 0x0000, /* R893 */ + 0x0000, /* R894 */ + 0x0000, /* R895 */ + 0x0000, /* R896 */ + 0x0000, /* R897 */ + 0x0000, /* R898 */ + 0x0000, /* R899 */ + 0x0000, /* R900 */ + 0x0000, /* R901 */ + 0x0000, /* R902 */ + 0x0000, /* R903 */ + 0x0000, /* R904 */ + 0x0000, /* R905 */ + 0x0000, /* R906 */ + 0x0000, /* R907 */ + 0x0000, /* R908 */ + 0x0000, /* R909 */ + 0x0000, /* R910 */ + 0x0000, /* R911 */ + 0x0000, /* R912 */ + 0x0000, /* R913 */ + 0x0000, /* R914 */ + 0x0000, /* R915 */ + 0x0000, /* R916 */ + 0x0000, /* R917 */ + 0x0000, /* R918 */ + 0x0000, /* R919 */ + 0x0000, /* R920 */ + 0x0000, /* R921 */ + 0x0000, /* R922 */ + 0x0000, /* R923 */ + 0x0000, /* R924 */ + 0x0000, /* R925 */ + 0x0000, /* R926 */ + 0x0000, /* R927 */ + 0x0000, /* R928 */ + 0x0000, /* R929 */ + 0x0000, /* R930 */ + 0x0000, /* R931 */ + 0x0000, /* R932 */ + 0x0000, /* R933 */ + 0x0000, /* R934 */ + 0x0000, /* R935 */ + 0x0000, /* R936 */ + 0x0000, /* R937 */ + 0x0000, /* R938 */ + 0x0000, /* R939 */ + 0x0000, /* R940 */ + 0x0000, /* R941 */ + 0x0000, /* R942 */ + 0x0000, /* R943 */ + 0x0000, /* R944 */ + 0x0000, /* R945 */ + 0x0000, /* R946 */ + 0x0000, /* R947 */ + 0x0000, /* R948 */ + 0x0000, /* R949 */ + 0x0000, /* R950 */ + 0x0000, /* R951 */ + 0x0000, /* R952 */ + 0x0000, /* R953 */ + 0x0000, /* R954 */ + 0x0000, /* R955 */ + 0x0000, /* R956 */ + 0x0000, /* R957 */ + 0x0000, /* R958 */ + 0x0000, /* R959 */ + 0x0000, /* R960 */ + 0x0000, /* R961 */ + 0x0000, /* R962 */ + 0x0000, /* R963 */ + 0x0000, /* R964 */ + 0x0000, /* R965 */ + 0x0000, /* R966 */ + 0x0000, /* R967 */ + 0x0000, /* R968 */ + 0x0000, /* R969 */ + 0x0000, /* R970 */ + 0x0000, /* R971 */ + 0x0000, /* R972 */ + 0x0000, /* R973 */ + 0x0000, /* R974 */ + 0x0000, /* R975 */ + 0x0000, /* R976 */ + 0x0000, /* R977 */ + 0x0000, /* R978 */ + 0x0000, /* R979 */ + 0x0000, /* R980 */ + 0x0000, /* R981 */ + 0x0000, /* R982 */ + 0x0000, /* R983 */ + 0x0000, /* R984 */ + 0x0000, /* R985 */ + 0x0000, /* R986 */ + 0x0000, /* R987 */ + 0x0000, /* R988 */ + 0x0000, /* R989 */ + 0x0000, /* R990 */ + 0x0000, /* R991 */ + 0x0000, /* R992 */ + 0x0000, /* R993 */ + 0x0000, /* R994 */ + 0x0000, /* R995 */ + 0x0000, /* R996 */ + 0x0000, /* R997 */ + 0x0000, /* R998 */ + 0x0000, /* R999 */ + 0x0000, /* R1000 */ + 0x0000, /* R1001 */ + 0x0000, /* R1002 */ + 0x0000, /* R1003 */ + 0x0000, /* R1004 */ + 0x0000, /* R1005 */ + 0x0000, /* R1006 */ + 0x0000, /* R1007 */ + 0x0000, /* R1008 */ + 0x0000, /* R1009 */ + 0x0000, /* R1010 */ + 0x0000, /* R1011 */ + 0x0000, /* R1012 */ + 0x0000, /* R1013 */ + 0x0000, /* R1014 */ + 0x0000, /* R1015 */ + 0x0000, /* R1016 */ + 0x0000, /* R1017 */ + 0x0000, /* R1018 */ + 0x0000, /* R1019 */ + 0x0000, /* R1020 */ + 0x0000, /* R1021 */ + 0x0000, /* R1022 */ + 0x0000, /* R1023 */ + 0x00C0, /* R1024 - AIF1 ADC1 Left Volume */ + 0x00C0, /* R1025 - AIF1 ADC1 Right Volume */ + 0x00C0, /* R1026 - AIF1 DAC1 Left Volume */ + 0x00C0, /* R1027 - AIF1 DAC1 Right Volume */ + 0x00C0, /* R1028 - AIF1 ADC2 Left Volume */ + 0x00C0, /* R1029 - AIF1 ADC2 Right Volume */ + 0x00C0, /* R1030 - AIF1 DAC2 Left Volume */ + 0x00C0, /* R1031 - AIF1 DAC2 Right Volume */ + 0x0000, /* R1032 */ + 0x0000, /* R1033 */ + 0x0000, /* R1034 */ + 0x0000, /* R1035 */ + 0x0000, /* R1036 */ + 0x0000, /* R1037 */ + 0x0000, /* R1038 */ + 0x0000, /* R1039 */ + 0x0000, /* R1040 - AIF1 ADC1 Filters */ + 0x0000, /* R1041 - AIF1 ADC2 Filters */ + 0x0000, /* R1042 */ + 0x0000, /* R1043 */ + 0x0000, /* R1044 */ + 0x0000, /* R1045 */ + 0x0000, /* R1046 */ + 0x0000, /* R1047 */ + 0x0000, /* R1048 */ + 0x0000, /* R1049 */ + 0x0000, /* R1050 */ + 0x0000, /* R1051 */ + 0x0000, /* R1052 */ + 0x0000, /* R1053 */ + 0x0000, /* R1054 */ + 0x0000, /* R1055 */ + 0x0200, /* R1056 - AIF1 DAC1 Filters (1) */ + 0x0010, /* R1057 - AIF1 DAC1 Filters (2) */ + 0x0200, /* R1058 - AIF1 DAC2 Filters (1) */ + 0x0010, /* R1059 - AIF1 DAC2 Filters (2) */ + 0x0000, /* R1060 */ + 0x0000, /* R1061 */ + 0x0000, /* R1062 */ + 0x0000, /* R1063 */ + 0x0000, /* R1064 */ + 0x0000, /* R1065 */ + 0x0000, /* R1066 */ + 0x0000, /* R1067 */ + 0x0000, /* R1068 */ + 0x0000, /* R1069 */ + 0x0000, /* R1070 */ + 0x0000, /* R1071 */ + 0x0000, /* R1072 */ + 0x0000, /* R1073 */ + 0x0000, /* R1074 */ + 0x0000, /* R1075 */ + 0x0000, /* R1076 */ + 0x0000, /* R1077 */ + 0x0000, /* R1078 */ + 0x0000, /* R1079 */ + 0x0000, /* R1080 */ + 0x0000, /* R1081 */ + 0x0000, /* R1082 */ + 0x0000, /* R1083 */ + 0x0000, /* R1084 */ + 0x0000, /* R1085 */ + 0x0000, /* R1086 */ + 0x0000, /* R1087 */ + 0x0098, /* R1088 - AIF1 DRC1 (1) */ + 0x0845, /* R1089 - AIF1 DRC1 (2) */ + 0x0000, /* R1090 - AIF1 DRC1 (3) */ + 0x0000, /* R1091 - AIF1 DRC1 (4) */ + 0x0000, /* R1092 - AIF1 DRC1 (5) */ + 0x0000, /* R1093 */ + 0x0000, /* R1094 */ + 0x0000, /* R1095 */ + 0x0000, /* R1096 */ + 0x0000, /* R1097 */ + 0x0000, /* R1098 */ + 0x0000, /* R1099 */ + 0x0000, /* R1100 */ + 0x0000, /* R1101 */ + 0x0000, /* R1102 */ + 0x0000, /* R1103 */ + 0x0098, /* R1104 - AIF1 DRC2 (1) */ + 0x0845, /* R1105 - AIF1 DRC2 (2) */ + 0x0000, /* R1106 - AIF1 DRC2 (3) */ + 0x0000, /* R1107 - AIF1 DRC2 (4) */ + 0x0000, /* R1108 - AIF1 DRC2 (5) */ + 0x0000, /* R1109 */ + 0x0000, /* R1110 */ + 0x0000, /* R1111 */ + 0x0000, /* R1112 */ + 0x0000, /* R1113 */ + 0x0000, /* R1114 */ + 0x0000, /* R1115 */ + 0x0000, /* R1116 */ + 0x0000, /* R1117 */ + 0x0000, /* R1118 */ + 0x0000, /* R1119 */ + 0x0000, /* R1120 */ + 0x0000, /* R1121 */ + 0x0000, /* R1122 */ + 0x0000, /* R1123 */ + 0x0000, /* R1124 */ + 0x0000, /* R1125 */ + 0x0000, /* R1126 */ + 0x0000, /* R1127 */ + 0x0000, /* R1128 */ + 0x0000, /* R1129 */ + 0x0000, /* R1130 */ + 0x0000, /* R1131 */ + 0x0000, /* R1132 */ + 0x0000, /* R1133 */ + 0x0000, /* R1134 */ + 0x0000, /* R1135 */ + 0x0000, /* R1136 */ + 0x0000, /* R1137 */ + 0x0000, /* R1138 */ + 0x0000, /* R1139 */ + 0x0000, /* R1140 */ + 0x0000, /* R1141 */ + 0x0000, /* R1142 */ + 0x0000, /* R1143 */ + 0x0000, /* R1144 */ + 0x0000, /* R1145 */ + 0x0000, /* R1146 */ + 0x0000, /* R1147 */ + 0x0000, /* R1148 */ + 0x0000, /* R1149 */ + 0x0000, /* R1150 */ + 0x0000, /* R1151 */ + 0x6318, /* R1152 - AIF1 DAC1 EQ Gains (1) */ + 0x6300, /* R1153 - AIF1 DAC1 EQ Gains (2) */ + 0x0FCA, /* R1154 - AIF1 DAC1 EQ Band 1 A */ + 0x0400, /* R1155 - AIF1 DAC1 EQ Band 1 B */ + 0x00D8, /* R1156 - AIF1 DAC1 EQ Band 1 PG */ + 0x1EB5, /* R1157 - AIF1 DAC1 EQ Band 2 A */ + 0xF145, /* R1158 - AIF1 DAC1 EQ Band 2 B */ + 0x0B75, /* R1159 - AIF1 DAC1 EQ Band 2 C */ + 0x01C5, /* R1160 - AIF1 DAC1 EQ Band 2 PG */ + 0x1C58, /* R1161 - AIF1 DAC1 EQ Band 3 A */ + 0xF373, /* R1162 - AIF1 DAC1 EQ Band 3 B */ + 0x0A54, /* R1163 - AIF1 DAC1 EQ Band 3 C */ + 0x0558, /* R1164 - AIF1 DAC1 EQ Band 3 PG */ + 0x168E, /* R1165 - AIF1 DAC1 EQ Band 4 A */ + 0xF829, /* R1166 - AIF1 DAC1 EQ Band 4 B */ + 0x07AD, /* R1167 - AIF1 DAC1 EQ Band 4 C */ + 0x1103, /* R1168 - AIF1 DAC1 EQ Band 4 PG */ + 0x0564, /* R1169 - AIF1 DAC1 EQ Band 5 A */ + 0x0559, /* R1170 - AIF1 DAC1 EQ Band 5 B */ + 0x4000, /* R1171 - AIF1 DAC1 EQ Band 5 PG */ + 0x0000, /* R1172 */ + 0x0000, /* R1173 */ + 0x0000, /* R1174 */ + 0x0000, /* R1175 */ + 0x0000, /* R1176 */ + 0x0000, /* R1177 */ + 0x0000, /* R1178 */ + 0x0000, /* R1179 */ + 0x0000, /* R1180 */ + 0x0000, /* R1181 */ + 0x0000, /* R1182 */ + 0x0000, /* R1183 */ + 0x6318, /* R1184 - AIF1 DAC2 EQ Gains (1) */ + 0x6300, /* R1185 - AIF1 DAC2 EQ Gains (2) */ + 0x0FCA, /* R1186 - AIF1 DAC2 EQ Band 1 A */ + 0x0400, /* R1187 - AIF1 DAC2 EQ Band 1 B */ + 0x00D8, /* R1188 - AIF1 DAC2 EQ Band 1 PG */ + 0x1EB5, /* R1189 - AIF1 DAC2 EQ Band 2 A */ + 0xF145, /* R1190 - AIF1 DAC2 EQ Band 2 B */ + 0x0B75, /* R1191 - AIF1 DAC2 EQ Band 2 C */ + 0x01C5, /* R1192 - AIF1 DAC2 EQ Band 2 PG */ + 0x1C58, /* R1193 - AIF1 DAC2 EQ Band 3 A */ + 0xF373, /* R1194 - AIF1 DAC2 EQ Band 3 B */ + 0x0A54, /* R1195 - AIF1 DAC2 EQ Band 3 C */ + 0x0558, /* R1196 - AIF1 DAC2 EQ Band 3 PG */ + 0x168E, /* R1197 - AIF1 DAC2 EQ Band 4 A */ + 0xF829, /* R1198 - AIF1 DAC2 EQ Band 4 B */ + 0x07AD, /* R1199 - AIF1 DAC2 EQ Band 4 C */ + 0x1103, /* R1200 - AIF1 DAC2 EQ Band 4 PG */ + 0x0564, /* R1201 - AIF1 DAC2 EQ Band 5 A */ + 0x0559, /* R1202 - AIF1 DAC2 EQ Band 5 B */ + 0x4000, /* R1203 - AIF1 DAC2 EQ Band 5 PG */ + 0x0000, /* R1204 */ + 0x0000, /* R1205 */ + 0x0000, /* R1206 */ + 0x0000, /* R1207 */ + 0x0000, /* R1208 */ + 0x0000, /* R1209 */ + 0x0000, /* R1210 */ + 0x0000, /* R1211 */ + 0x0000, /* R1212 */ + 0x0000, /* R1213 */ + 0x0000, /* R1214 */ + 0x0000, /* R1215 */ + 0x0000, /* R1216 */ + 0x0000, /* R1217 */ + 0x0000, /* R1218 */ + 0x0000, /* R1219 */ + 0x0000, /* R1220 */ + 0x0000, /* R1221 */ + 0x0000, /* R1222 */ + 0x0000, /* R1223 */ + 0x0000, /* R1224 */ + 0x0000, /* R1225 */ + 0x0000, /* R1226 */ + 0x0000, /* R1227 */ + 0x0000, /* R1228 */ + 0x0000, /* R1229 */ + 0x0000, /* R1230 */ + 0x0000, /* R1231 */ + 0x0000, /* R1232 */ + 0x0000, /* R1233 */ + 0x0000, /* R1234 */ + 0x0000, /* R1235 */ + 0x0000, /* R1236 */ + 0x0000, /* R1237 */ + 0x0000, /* R1238 */ + 0x0000, /* R1239 */ + 0x0000, /* R1240 */ + 0x0000, /* R1241 */ + 0x0000, /* R1242 */ + 0x0000, /* R1243 */ + 0x0000, /* R1244 */ + 0x0000, /* R1245 */ + 0x0000, /* R1246 */ + 0x0000, /* R1247 */ + 0x0000, /* R1248 */ + 0x0000, /* R1249 */ + 0x0000, /* R1250 */ + 0x0000, /* R1251 */ + 0x0000, /* R1252 */ + 0x0000, /* R1253 */ + 0x0000, /* R1254 */ + 0x0000, /* R1255 */ + 0x0000, /* R1256 */ + 0x0000, /* R1257 */ + 0x0000, /* R1258 */ + 0x0000, /* R1259 */ + 0x0000, /* R1260 */ + 0x0000, /* R1261 */ + 0x0000, /* R1262 */ + 0x0000, /* R1263 */ + 0x0000, /* R1264 */ + 0x0000, /* R1265 */ + 0x0000, /* R1266 */ + 0x0000, /* R1267 */ + 0x0000, /* R1268 */ + 0x0000, /* R1269 */ + 0x0000, /* R1270 */ + 0x0000, /* R1271 */ + 0x0000, /* R1272 */ + 0x0000, /* R1273 */ + 0x0000, /* R1274 */ + 0x0000, /* R1275 */ + 0x0000, /* R1276 */ + 0x0000, /* R1277 */ + 0x0000, /* R1278 */ + 0x0000, /* R1279 */ + 0x00C0, /* R1280 - AIF2 ADC Left Volume */ + 0x00C0, /* R1281 - AIF2 ADC Right Volume */ + 0x00C0, /* R1282 - AIF2 DAC Left Volume */ + 0x00C0, /* R1283 - AIF2 DAC Right Volume */ + 0x0000, /* R1284 */ + 0x0000, /* R1285 */ + 0x0000, /* R1286 */ + 0x0000, /* R1287 */ + 0x0000, /* R1288 */ + 0x0000, /* R1289 */ + 0x0000, /* R1290 */ + 0x0000, /* R1291 */ + 0x0000, /* R1292 */ + 0x0000, /* R1293 */ + 0x0000, /* R1294 */ + 0x0000, /* R1295 */ + 0x0000, /* R1296 - AIF2 ADC Filters */ + 0x0000, /* R1297 */ + 0x0000, /* R1298 */ + 0x0000, /* R1299 */ + 0x0000, /* R1300 */ + 0x0000, /* R1301 */ + 0x0000, /* R1302 */ + 0x0000, /* R1303 */ + 0x0000, /* R1304 */ + 0x0000, /* R1305 */ + 0x0000, /* R1306 */ + 0x0000, /* R1307 */ + 0x0000, /* R1308 */ + 0x0000, /* R1309 */ + 0x0000, /* R1310 */ + 0x0000, /* R1311 */ + 0x0200, /* R1312 - AIF2 DAC Filters (1) */ + 0x0010, /* R1313 - AIF2 DAC Filters (2) */ + 0x0000, /* R1314 */ + 0x0000, /* R1315 */ + 0x0000, /* R1316 */ + 0x0000, /* R1317 */ + 0x0000, /* R1318 */ + 0x0000, /* R1319 */ + 0x0000, /* R1320 */ + 0x0000, /* R1321 */ + 0x0000, /* R1322 */ + 0x0000, /* R1323 */ + 0x0000, /* R1324 */ + 0x0000, /* R1325 */ + 0x0000, /* R1326 */ + 0x0000, /* R1327 */ + 0x0000, /* R1328 */ + 0x0000, /* R1329 */ + 0x0000, /* R1330 */ + 0x0000, /* R1331 */ + 0x0000, /* R1332 */ + 0x0000, /* R1333 */ + 0x0000, /* R1334 */ + 0x0000, /* R1335 */ + 0x0000, /* R1336 */ + 0x0000, /* R1337 */ + 0x0000, /* R1338 */ + 0x0000, /* R1339 */ + 0x0000, /* R1340 */ + 0x0000, /* R1341 */ + 0x0000, /* R1342 */ + 0x0000, /* R1343 */ + 0x0098, /* R1344 - AIF2 DRC (1) */ + 0x0845, /* R1345 - AIF2 DRC (2) */ + 0x0000, /* R1346 - AIF2 DRC (3) */ + 0x0000, /* R1347 - AIF2 DRC (4) */ + 0x0000, /* R1348 - AIF2 DRC (5) */ + 0x0000, /* R1349 */ + 0x0000, /* R1350 */ + 0x0000, /* R1351 */ + 0x0000, /* R1352 */ + 0x0000, /* R1353 */ + 0x0000, /* R1354 */ + 0x0000, /* R1355 */ + 0x0000, /* R1356 */ + 0x0000, /* R1357 */ + 0x0000, /* R1358 */ + 0x0000, /* R1359 */ + 0x0000, /* R1360 */ + 0x0000, /* R1361 */ + 0x0000, /* R1362 */ + 0x0000, /* R1363 */ + 0x0000, /* R1364 */ + 0x0000, /* R1365 */ + 0x0000, /* R1366 */ + 0x0000, /* R1367 */ + 0x0000, /* R1368 */ + 0x0000, /* R1369 */ + 0x0000, /* R1370 */ + 0x0000, /* R1371 */ + 0x0000, /* R1372 */ + 0x0000, /* R1373 */ + 0x0000, /* R1374 */ + 0x0000, /* R1375 */ + 0x0000, /* R1376 */ + 0x0000, /* R1377 */ + 0x0000, /* R1378 */ + 0x0000, /* R1379 */ + 0x0000, /* R1380 */ + 0x0000, /* R1381 */ + 0x0000, /* R1382 */ + 0x0000, /* R1383 */ + 0x0000, /* R1384 */ + 0x0000, /* R1385 */ + 0x0000, /* R1386 */ + 0x0000, /* R1387 */ + 0x0000, /* R1388 */ + 0x0000, /* R1389 */ + 0x0000, /* R1390 */ + 0x0000, /* R1391 */ + 0x0000, /* R1392 */ + 0x0000, /* R1393 */ + 0x0000, /* R1394 */ + 0x0000, /* R1395 */ + 0x0000, /* R1396 */ + 0x0000, /* R1397 */ + 0x0000, /* R1398 */ + 0x0000, /* R1399 */ + 0x0000, /* R1400 */ + 0x0000, /* R1401 */ + 0x0000, /* R1402 */ + 0x0000, /* R1403 */ + 0x0000, /* R1404 */ + 0x0000, /* R1405 */ + 0x0000, /* R1406 */ + 0x0000, /* R1407 */ + 0x6318, /* R1408 - AIF2 EQ Gains (1) */ + 0x6300, /* R1409 - AIF2 EQ Gains (2) */ + 0x0FCA, /* R1410 - AIF2 EQ Band 1 A */ + 0x0400, /* R1411 - AIF2 EQ Band 1 B */ + 0x00D8, /* R1412 - AIF2 EQ Band 1 PG */ + 0x1EB5, /* R1413 - AIF2 EQ Band 2 A */ + 0xF145, /* R1414 - AIF2 EQ Band 2 B */ + 0x0B75, /* R1415 - AIF2 EQ Band 2 C */ + 0x01C5, /* R1416 - AIF2 EQ Band 2 PG */ + 0x1C58, /* R1417 - AIF2 EQ Band 3 A */ + 0xF373, /* R1418 - AIF2 EQ Band 3 B */ + 0x0A54, /* R1419 - AIF2 EQ Band 3 C */ + 0x0558, /* R1420 - AIF2 EQ Band 3 PG */ + 0x168E, /* R1421 - AIF2 EQ Band 4 A */ + 0xF829, /* R1422 - AIF2 EQ Band 4 B */ + 0x07AD, /* R1423 - AIF2 EQ Band 4 C */ + 0x1103, /* R1424 - AIF2 EQ Band 4 PG */ + 0x0564, /* R1425 - AIF2 EQ Band 5 A */ + 0x0559, /* R1426 - AIF2 EQ Band 5 B */ + 0x4000, /* R1427 - AIF2 EQ Band 5 PG */ + 0x0000, /* R1428 */ + 0x0000, /* R1429 */ + 0x0000, /* R1430 */ + 0x0000, /* R1431 */ + 0x0000, /* R1432 */ + 0x0000, /* R1433 */ + 0x0000, /* R1434 */ + 0x0000, /* R1435 */ + 0x0000, /* R1436 */ + 0x0000, /* R1437 */ + 0x0000, /* R1438 */ + 0x0000, /* R1439 */ + 0x0000, /* R1440 */ + 0x0000, /* R1441 */ + 0x0000, /* R1442 */ + 0x0000, /* R1443 */ + 0x0000, /* R1444 */ + 0x0000, /* R1445 */ + 0x0000, /* R1446 */ + 0x0000, /* R1447 */ + 0x0000, /* R1448 */ + 0x0000, /* R1449 */ + 0x0000, /* R1450 */ + 0x0000, /* R1451 */ + 0x0000, /* R1452 */ + 0x0000, /* R1453 */ + 0x0000, /* R1454 */ + 0x0000, /* R1455 */ + 0x0000, /* R1456 */ + 0x0000, /* R1457 */ + 0x0000, /* R1458 */ + 0x0000, /* R1459 */ + 0x0000, /* R1460 */ + 0x0000, /* R1461 */ + 0x0000, /* R1462 */ + 0x0000, /* R1463 */ + 0x0000, /* R1464 */ + 0x0000, /* R1465 */ + 0x0000, /* R1466 */ + 0x0000, /* R1467 */ + 0x0000, /* R1468 */ + 0x0000, /* R1469 */ + 0x0000, /* R1470 */ + 0x0000, /* R1471 */ + 0x0000, /* R1472 */ + 0x0000, /* R1473 */ + 0x0000, /* R1474 */ + 0x0000, /* R1475 */ + 0x0000, /* R1476 */ + 0x0000, /* R1477 */ + 0x0000, /* R1478 */ + 0x0000, /* R1479 */ + 0x0000, /* R1480 */ + 0x0000, /* R1481 */ + 0x0000, /* R1482 */ + 0x0000, /* R1483 */ + 0x0000, /* R1484 */ + 0x0000, /* R1485 */ + 0x0000, /* R1486 */ + 0x0000, /* R1487 */ + 0x0000, /* R1488 */ + 0x0000, /* R1489 */ + 0x0000, /* R1490 */ + 0x0000, /* R1491 */ + 0x0000, /* R1492 */ + 0x0000, /* R1493 */ + 0x0000, /* R1494 */ + 0x0000, /* R1495 */ + 0x0000, /* R1496 */ + 0x0000, /* R1497 */ + 0x0000, /* R1498 */ + 0x0000, /* R1499 */ + 0x0000, /* R1500 */ + 0x0000, /* R1501 */ + 0x0000, /* R1502 */ + 0x0000, /* R1503 */ + 0x0000, /* R1504 */ + 0x0000, /* R1505 */ + 0x0000, /* R1506 */ + 0x0000, /* R1507 */ + 0x0000, /* R1508 */ + 0x0000, /* R1509 */ + 0x0000, /* R1510 */ + 0x0000, /* R1511 */ + 0x0000, /* R1512 */ + 0x0000, /* R1513 */ + 0x0000, /* R1514 */ + 0x0000, /* R1515 */ + 0x0000, /* R1516 */ + 0x0000, /* R1517 */ + 0x0000, /* R1518 */ + 0x0000, /* R1519 */ + 0x0000, /* R1520 */ + 0x0000, /* R1521 */ + 0x0000, /* R1522 */ + 0x0000, /* R1523 */ + 0x0000, /* R1524 */ + 0x0000, /* R1525 */ + 0x0000, /* R1526 */ + 0x0000, /* R1527 */ + 0x0000, /* R1528 */ + 0x0000, /* R1529 */ + 0x0000, /* R1530 */ + 0x0000, /* R1531 */ + 0x0000, /* R1532 */ + 0x0000, /* R1533 */ + 0x0000, /* R1534 */ + 0x0000, /* R1535 */ + 0x0000, /* R1536 - DAC1 Mixer Volumes */ + 0x0000, /* R1537 - DAC1 Left Mixer Routing */ + 0x0000, /* R1538 - DAC1 Right Mixer Routing */ + 0x0000, /* R1539 - DAC2 Mixer Volumes */ + 0x0000, /* R1540 - DAC2 Left Mixer Routing */ + 0x0000, /* R1541 - DAC2 Right Mixer Routing */ + 0x0000, /* R1542 - AIF1 ADC1 Left Mixer Routing */ + 0x0000, /* R1543 - AIF1 ADC1 Right Mixer Routing */ + 0x0000, /* R1544 - AIF1 ADC2 Left Mixer Routing */ + 0x0000, /* R1545 - AIF1 ADC2 Right mixer Routing */ + 0x0000, /* R1546 */ + 0x0000, /* R1547 */ + 0x0000, /* R1548 */ + 0x0000, /* R1549 */ + 0x0000, /* R1550 */ + 0x0000, /* R1551 */ + 0x02C0, /* R1552 - DAC1 Left Volume */ + 0x02C0, /* R1553 - DAC1 Right Volume */ + 0x02C0, /* R1554 - DAC2 Left Volume */ + 0x02C0, /* R1555 - DAC2 Right Volume */ + 0x0000, /* R1556 - DAC Softmute */ + 0x0000, /* R1557 */ + 0x0000, /* R1558 */ + 0x0000, /* R1559 */ + 0x0000, /* R1560 */ + 0x0000, /* R1561 */ + 0x0000, /* R1562 */ + 0x0000, /* R1563 */ + 0x0000, /* R1564 */ + 0x0000, /* R1565 */ + 0x0000, /* R1566 */ + 0x0000, /* R1567 */ + 0x0002, /* R1568 - Oversampling */ + 0x0000, /* R1569 - Sidetone */ +}; diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index 948677b581b1..d9c6dd5823b4 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c @@ -57,8 +57,6 @@ static int wm8994_retune_mobile_base[] = { WM8994_AIF2_EQ_GAINS_1, }; -#define WM8994_REG_CACHE_SIZE 0x621 - struct wm8994_micdet { struct snd_soc_jack *jack; int det; @@ -71,7 +69,6 @@ struct wm8994_priv { enum snd_soc_control_type control_type; void *control_data; struct snd_soc_codec *codec; - u16 reg_cache[WM8994_REG_CACHE_SIZE + 1]; int sysclk[2]; int sysclk_rate[2]; int mclk[2]; @@ -134,7 +131,7 @@ static int wm8994_readable(unsigned int reg) static int wm8994_volatile(unsigned int reg) { - if (reg >= WM8994_REG_CACHE_SIZE) + if (reg >= WM8994_CACHE_SIZE) return 1; switch (reg) { @@ -156,12 +153,16 @@ static int wm8994_volatile(unsigned int reg) static int wm8994_write(struct snd_soc_codec *codec, unsigned int reg, unsigned int value) { - struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); + int ret; BUG_ON(reg > WM8994_MAX_REGISTER); - if (!wm8994_volatile(reg)) - wm8994->reg_cache[reg] = value; + if (!wm8994_volatile(reg)) { + ret = snd_soc_cache_write(codec, reg, value); + if (ret != 0) + dev_err(codec->dev, "Cache write to %x failed: %d\n", + reg, ret); + } return wm8994_reg_write(codec->control_data, reg, value); } @@ -169,14 +170,22 @@ static int wm8994_write(struct snd_soc_codec *codec, unsigned int reg, static unsigned int wm8994_read(struct snd_soc_codec *codec, unsigned int reg) { - u16 *reg_cache = codec->reg_cache; + unsigned int val; + int ret; BUG_ON(reg > WM8994_MAX_REGISTER); - if (wm8994_volatile(reg)) - return wm8994_reg_read(codec->control_data, reg); - else - return reg_cache[reg]; + if (!wm8994_volatile(reg) && wm8994_readable(reg) && + reg < codec->driver->reg_cache_size) { + ret = snd_soc_cache_read(codec, reg, &val); + if (ret >= 0) + return val; + else + dev_err(codec->dev, "Cache read from %x failed: %d\n", + reg, ret); + } + + return wm8994_reg_read(codec->control_data, reg); } static int configure_aif_clock(struct snd_soc_codec *codec, int aif) @@ -2370,26 +2379,12 @@ static int wm8994_suspend(struct snd_soc_codec *codec, pm_message_t state) static int wm8994_resume(struct snd_soc_codec *codec) { struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); - u16 *reg_cache = codec->reg_cache; int i, ret; /* Restore the registers */ - for (i = 1; i < ARRAY_SIZE(wm8994->reg_cache); i++) { - switch (i) { - case WM8994_LDO_1: - case WM8994_LDO_2: - case WM8994_SOFTWARE_RESET: - /* Handled by other MFD drivers */ - continue; - default: - break; - } - - if (!wm8994_access_masks[i].writable) - continue; - - wm8994_reg_write(codec->control_data, i, reg_cache[i]); - } + ret = snd_soc_cache_sync(codec); + if (ret != 0) + dev_err(codec->dev, "Failed to sync cache: %d\n", ret); wm8994_set_bias_level(codec, SND_SOC_BIAS_STANDBY); @@ -2782,27 +2777,27 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) return -ENOMEM; snd_soc_codec_set_drvdata(codec, wm8994); - codec->reg_cache = &wm8994->reg_cache; - wm8994->pdata = dev_get_platdata(codec->dev->parent); wm8994->codec = codec; - /* Fill the cache with physical values we inherited; don't reset */ - ret = wm8994_bulk_read(codec->control_data, 0, - ARRAY_SIZE(wm8994->reg_cache) - 1, - codec->reg_cache); - if (ret < 0) { - dev_err(codec->dev, "Failed to fill register cache: %d\n", - ret); - goto err; - } + /* Read our current status back from the chip - we don't want to + * reset as this may interfere with the GPIO or LDO operation. */ + for (i = 0; i < WM8994_CACHE_SIZE; i++) { + if (!wm8994_readable(i) || wm8994_volatile(i)) + continue; - /* Clear the cached values for unreadable/volatile registers to - * avoid potential confusion. - */ - for (i = 0; i < ARRAY_SIZE(wm8994->reg_cache); i++) - if (wm8994_volatile(i) || !wm8994_readable(i)) - wm8994->reg_cache[i] = 0; + ret = wm8994_reg_read(codec->control_data, i); + if (ret <= 0) + continue; + + ret = snd_soc_cache_write(codec, i, ret); + if (ret != 0) { + dev_err(codec->dev, + "Failed to initialise cache for 0x%x: %d\n", + i, ret); + goto err; + } + } /* Set revision-specific configuration */ wm8994->revision = snd_soc_read(codec, WM8994_CHIP_REVISION); @@ -3029,11 +3024,15 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8994 = { .remove = wm8994_codec_remove, .suspend = wm8994_suspend, .resume = wm8994_resume, - .read = wm8994_read, - .write = wm8994_write, + .read = wm8994_read, + .write = wm8994_write, .readable_register = wm8994_readable, .volatile_register = wm8994_volatile, .set_bias_level = wm8994_set_bias_level, + + .reg_cache_size = WM8994_CACHE_SIZE, + .reg_cache_default = wm8994_reg_defaults, + .reg_word_size = 2, }; static int __devinit wm8994_probe(struct platform_device *pdev) diff --git a/sound/soc/codecs/wm8994.h b/sound/soc/codecs/wm8994.h index 455cae6b4356..0c355bfc88f1 100644 --- a/sound/soc/codecs/wm8994.h +++ b/sound/soc/codecs/wm8994.h @@ -43,5 +43,6 @@ struct wm8994_access_mask { }; extern const struct wm8994_access_mask wm8994_access_masks[WM8994_CACHE_SIZE]; +extern const __devinitdata u16 wm8994_reg_defaults[WM8994_CACHE_SIZE]; #endif -- cgit v1.2.3 From 2e19b0c8c21cb06eb5b902588c30ae0529ce8ec3 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 26 Nov 2010 17:23:42 +0000 Subject: ASoC: Enable rbtree compression for WM8994/58 register cache The WM8994 and WM8958 register map is relatively sparse so benefits from compression. The rbtree compression gives better results than LZO for both memory and CPU consumption on a map as sparse as this. Signed-off-by: Mark Brown Acked-by: Liam Girdwood --- sound/soc/codecs/wm8994.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index d9c6dd5823b4..5f203c545e00 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c @@ -3033,6 +3033,7 @@ static struct snd_soc_codec_driver soc_codec_dev_wm8994 = { .reg_cache_size = WM8994_CACHE_SIZE, .reg_cache_default = wm8994_reg_defaults, .reg_word_size = 2, + .compress_type = SND_SOC_RBTREE_COMPRESSION, }; static int __devinit wm8994_probe(struct platform_device *pdev) -- cgit v1.2.3 From 39fb51a123c125e36e9bcb67686b3e2945784250 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 26 Nov 2010 17:23:43 +0000 Subject: ASoC: Implement runtime PM for WM8994/58 This allows us to communicate our power management state back to the parent device, allowing it to do a full power down when the device is idle. Signed-off-by: Mark Brown Acked-by: Liam Girdwood --- sound/soc/codecs/wm8994.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index 5f203c545e00..bfd4cf4fde5f 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -1803,6 +1804,8 @@ static int wm8994_set_bias_level(struct snd_soc_codec *codec, case SND_SOC_BIAS_STANDBY: if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { + pm_runtime_get_sync(codec->dev); + /* Tweak DC servo and DSP configuration for * improved performance. */ if (control->type == WM8994 && wm8994->revision < 4) { @@ -1878,6 +1881,8 @@ static int wm8994_set_bias_level(struct snd_soc_codec *codec, WM8994_STARTUP_BIAS_ENA | WM8994_VMID_BUF_ENA | WM8994_VMID_RAMP_MASK, 0); + + pm_runtime_put(codec->dev); } break; } @@ -2780,6 +2785,9 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) wm8994->pdata = dev_get_platdata(codec->dev->parent); wm8994->codec = codec; + pm_runtime_enable(codec->dev); + pm_runtime_resume(codec->dev); + /* Read our current status back from the chip - we don't want to * reset as this may interfere with the GPIO or LDO operation. */ for (i = 0; i < WM8994_CACHE_SIZE; i++) { @@ -2995,6 +3003,8 @@ static int wm8994_codec_remove(struct snd_soc_codec *codec) wm8994_set_bias_level(codec, SND_SOC_BIAS_OFF); + pm_runtime_disable(codec->dev); + switch (control->type) { case WM8994: wm8994_free_irq(codec->control_data, WM8994_IRQ_MIC2_SHRT, -- cgit v1.2.3 From c762be637503b833012457087133c1292fd6056d Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Sun, 28 Nov 2010 16:28:01 +0800 Subject: crypto: algif_skcipher - Pass on error from af_alg_make_sg The error returned from af_alg_make_sg is currently lost and we always pass on -EINVAL. This patch pases on the underlying error. Signed-off-by: Herbert Xu --- crypto/algif_skcipher.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/crypto/algif_skcipher.c b/crypto/algif_skcipher.c index 211c956952ca..9b2f440e88a6 100644 --- a/crypto/algif_skcipher.c +++ b/crypto/algif_skcipher.c @@ -472,7 +472,8 @@ static int skcipher_recvmsg(struct kiocb *unused, struct socket *sock, goto unlock; used = af_alg_make_sg(&ctx->rsgl, from, used, 1); - if (used < 0) + err = used; + if (err < 0) goto unlock; ablkcipher_request_set_crypt(&ctx->req, sg, -- cgit v1.2.3 From 602606a472963a67b234e6b5c99293de4aa9d06b Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sun, 28 Nov 2010 15:31:02 +0000 Subject: drm/i915/execbuffer: On error, starting unwinding from the previous object As the error occurred on the current object, it means that its state was not changed and so it should be excluded from the unwind. Reported-by: Daniel Vetter Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_gem_execbuffer.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index d54070111f9d..66c898c8716d 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c @@ -530,6 +530,9 @@ i915_gem_execbuffer_reserve(struct drm_device *dev, } while (1); err: + obj = list_entry(obj->exec_list.prev, + struct drm_i915_gem_object, + exec_list); while (objects != &obj->exec_list) { if (obj->gtt_space) i915_gem_object_unpin(obj); -- cgit v1.2.3 From ce06b9d6d33fd2ed799b6e825d68fe95077da354 Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Sun, 28 Nov 2010 16:37:14 +0100 Subject: HID: hid-core - rename hid_blacklist to hid_have_special_driver To avoid confusion with hid_blacklist describing various quirks in usbhid code, let's rename this one. Signed-off-by: Dmitry Torokhov Signed-off-by: Jiri Kosina --- drivers/hid/hid-core.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index dc56bd61edb7..396f8c7e0076 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -1230,7 +1230,7 @@ void hid_disconnect(struct hid_device *hdev) EXPORT_SYMBOL_GPL(hid_disconnect); /* a list of devices for which there is a specialized driver on HID bus */ -static const struct hid_device_id hid_blacklist[] = { +static const struct hid_device_id hid_have_special_driver[] = { { HID_USB_DEVICE(USB_VENDOR_ID_3M, USB_DEVICE_ID_3M1968) }, { HID_USB_DEVICE(USB_VENDOR_ID_3M, USB_DEVICE_ID_3M2256) }, { HID_USB_DEVICE(USB_VENDOR_ID_A4TECH, USB_DEVICE_ID_A4TECH_WCP32PU) }, @@ -1503,9 +1503,9 @@ static int hid_bus_match(struct device *dev, struct device_driver *drv) if (!hid_match_device(hdev, hdrv)) return 0; - /* generic wants all non-blacklisted */ + /* generic wants all that don't have specialized driver */ if (!strncmp(hdrv->name, "generic-", 8)) - return !hid_match_id(hdev, hid_blacklist); + return !hid_match_id(hdev, hid_have_special_driver); return 1; } -- cgit v1.2.3 From 7d2cb39c332146b0906651a8567f8b81af4b1584 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sat, 27 Nov 2010 17:38:29 +0000 Subject: drm/i915: Release fenced GTT mapping on suspend ... so that upon first use after resume we will reacquire the fence reg. Reported-by: Keith Packard Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_gem.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index a090acdf3bd5..eae52de75a4c 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1794,8 +1794,15 @@ static void i915_gem_reset_fences(struct drm_device *dev) for (i = 0; i < 16; i++) { struct drm_i915_fence_reg *reg = &dev_priv->fence_regs[i]; - if (reg->obj) - i915_gem_clear_fence_reg(reg->obj); + struct drm_i915_gem_object *obj = reg->obj; + + if (!obj) + continue; + + if (obj->tiling_mode) + i915_gem_release_mmap(obj); + + i915_gem_clear_fence_reg(obj); } } -- cgit v1.2.3 From 85beb5869a4f6abb52a7cf8e01de6fa57e9ee47d Mon Sep 17 00:00:00 2001 From: Steven Rostedt Date: Wed, 24 Nov 2010 16:23:34 -0500 Subject: tracing/slab: Move kmalloc tracepoint out of inline code The tracepoint for kmalloc is in the slab inlined code which causes every instance of kmalloc to have the tracepoint. This patch moves the tracepoint out of the inline code to the slab C file, which removes a large number of inlined trace points. objdump -dr vmlinux.slab| grep 'jmpq.* Signed-off-by: Pekka Enberg --- include/linux/slab_def.h | 33 +++++++++++++-------------------- mm/slab.c | 38 +++++++++++++++++++++++--------------- 2 files changed, 36 insertions(+), 35 deletions(-) diff --git a/include/linux/slab_def.h b/include/linux/slab_def.h index 791a502f6906..83203ae9390b 100644 --- a/include/linux/slab_def.h +++ b/include/linux/slab_def.h @@ -138,11 +138,12 @@ void *kmem_cache_alloc(struct kmem_cache *, gfp_t); void *__kmalloc(size_t size, gfp_t flags); #ifdef CONFIG_TRACING -extern void *kmem_cache_alloc_notrace(struct kmem_cache *cachep, gfp_t flags); +extern void *kmem_cache_alloc_trace(size_t size, + struct kmem_cache *cachep, gfp_t flags); extern size_t slab_buffer_size(struct kmem_cache *cachep); #else static __always_inline void * -kmem_cache_alloc_notrace(struct kmem_cache *cachep, gfp_t flags) +kmem_cache_alloc_trace(size_t size, struct kmem_cache *cachep, gfp_t flags) { return kmem_cache_alloc(cachep, flags); } @@ -179,10 +180,7 @@ found: #endif cachep = malloc_sizes[i].cs_cachep; - ret = kmem_cache_alloc_notrace(cachep, flags); - - trace_kmalloc(_THIS_IP_, ret, - size, slab_buffer_size(cachep), flags); + ret = kmem_cache_alloc_trace(size, cachep, flags); return ret; } @@ -194,14 +192,16 @@ extern void *__kmalloc_node(size_t size, gfp_t flags, int node); extern void *kmem_cache_alloc_node(struct kmem_cache *, gfp_t flags, int node); #ifdef CONFIG_TRACING -extern void *kmem_cache_alloc_node_notrace(struct kmem_cache *cachep, - gfp_t flags, - int nodeid); +extern void *kmem_cache_alloc_node_trace(size_t size, + struct kmem_cache *cachep, + gfp_t flags, + int nodeid); #else static __always_inline void * -kmem_cache_alloc_node_notrace(struct kmem_cache *cachep, - gfp_t flags, - int nodeid) +kmem_cache_alloc_node_trace(size_t size, + struct kmem_cache *cachep, + gfp_t flags, + int nodeid) { return kmem_cache_alloc_node(cachep, flags, nodeid); } @@ -210,7 +210,6 @@ kmem_cache_alloc_node_notrace(struct kmem_cache *cachep, static __always_inline void *kmalloc_node(size_t size, gfp_t flags, int node) { struct kmem_cache *cachep; - void *ret; if (__builtin_constant_p(size)) { int i = 0; @@ -234,13 +233,7 @@ found: #endif cachep = malloc_sizes[i].cs_cachep; - ret = kmem_cache_alloc_node_notrace(cachep, flags, node); - - trace_kmalloc_node(_THIS_IP_, ret, - size, slab_buffer_size(cachep), - flags, node); - - return ret; + return kmem_cache_alloc_node_trace(size, cachep, flags, node); } return __kmalloc_node(size, flags, node); } diff --git a/mm/slab.c b/mm/slab.c index b1e40dafbab3..dfcc8885d7d5 100644 --- a/mm/slab.c +++ b/mm/slab.c @@ -3653,11 +3653,18 @@ void *kmem_cache_alloc(struct kmem_cache *cachep, gfp_t flags) EXPORT_SYMBOL(kmem_cache_alloc); #ifdef CONFIG_TRACING -void *kmem_cache_alloc_notrace(struct kmem_cache *cachep, gfp_t flags) +void * +kmem_cache_alloc_trace(size_t size, struct kmem_cache *cachep, gfp_t flags) { - return __cache_alloc(cachep, flags, __builtin_return_address(0)); + void *ret; + + ret = __cache_alloc(cachep, flags, __builtin_return_address(0)); + + trace_kmalloc(_RET_IP_, ret, + size, slab_buffer_size(cachep), flags); + return ret; } -EXPORT_SYMBOL(kmem_cache_alloc_notrace); +EXPORT_SYMBOL(kmem_cache_alloc_trace); #endif /** @@ -3705,31 +3712,32 @@ void *kmem_cache_alloc_node(struct kmem_cache *cachep, gfp_t flags, int nodeid) EXPORT_SYMBOL(kmem_cache_alloc_node); #ifdef CONFIG_TRACING -void *kmem_cache_alloc_node_notrace(struct kmem_cache *cachep, - gfp_t flags, - int nodeid) +void *kmem_cache_alloc_node_trace(size_t size, + struct kmem_cache *cachep, + gfp_t flags, + int nodeid) { - return __cache_alloc_node(cachep, flags, nodeid, + void *ret; + + ret = __cache_alloc_node(cachep, flags, nodeid, __builtin_return_address(0)); + trace_kmalloc_node(_RET_IP_, ret, + size, slab_buffer_size(cachep), + flags, nodeid); + return ret; } -EXPORT_SYMBOL(kmem_cache_alloc_node_notrace); +EXPORT_SYMBOL(kmem_cache_alloc_node_trace); #endif static __always_inline void * __do_kmalloc_node(size_t size, gfp_t flags, int node, void *caller) { struct kmem_cache *cachep; - void *ret; cachep = kmem_find_general_cachep(size, flags); if (unlikely(ZERO_OR_NULL_PTR(cachep))) return cachep; - ret = kmem_cache_alloc_node_notrace(cachep, flags, node); - - trace_kmalloc_node((unsigned long) caller, ret, - size, cachep->buffer_size, flags, node); - - return ret; + return kmem_cache_alloc_node_trace(size, cachep, flags, node); } #if defined(CONFIG_DEBUG_SLAB) || defined(CONFIG_TRACING) -- cgit v1.2.3 From fa9f90be745d3b600a9d97a063be404c5e5d9071 Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Sun, 28 Nov 2010 21:39:34 +0100 Subject: Kill off a bunch of warning: ‘inline’ is not at beginning of declaration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These warnings are spewed during a build of a 'allnoconfig' kernel (especially the ones from u64_stats_sync.h show up a lot) when building with -Wextra (which I often do).. They are a) annoying b) easy to get rid of. This patch kills them off. include/linux/u64_stats_sync.h:70:1: warning: ‘inline’ is not at beginning of declaration include/linux/u64_stats_sync.h:77:1: warning: ‘inline’ is not at beginning of declaration include/linux/u64_stats_sync.h:84:1: warning: ‘inline’ is not at beginning of declaration include/linux/u64_stats_sync.h:96:1: warning: ‘inline’ is not at beginning of declaration include/linux/u64_stats_sync.h:115:1: warning: ‘inline’ is not at beginning of declaration include/linux/u64_stats_sync.h:127:1: warning: ‘inline’ is not at beginning of declaration kernel/time.c:241:1: warning: ‘inline’ is not at beginning of declaration kernel/time.c:257:1: warning: ‘inline’ is not at beginning of declaration kernel/perf_event.c:4513:1: warning: ‘inline’ is not at beginning of declaration mm/page_alloc.c:4012:1: warning: ‘inline’ is not at beginning of declaration Signed-off-by: Jesper Juhl Signed-off-by: Jiri Kosina --- include/linux/u64_stats_sync.h | 12 ++++++------ kernel/perf_event.c | 2 +- kernel/time.c | 4 ++-- mm/page_alloc.c | 2 +- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/include/linux/u64_stats_sync.h b/include/linux/u64_stats_sync.h index fa261a0da280..8da8c4e87da3 100644 --- a/include/linux/u64_stats_sync.h +++ b/include/linux/u64_stats_sync.h @@ -67,21 +67,21 @@ struct u64_stats_sync { #endif }; -static void inline u64_stats_update_begin(struct u64_stats_sync *syncp) +static inline void u64_stats_update_begin(struct u64_stats_sync *syncp) { #if BITS_PER_LONG==32 && defined(CONFIG_SMP) write_seqcount_begin(&syncp->seq); #endif } -static void inline u64_stats_update_end(struct u64_stats_sync *syncp) +static inline void u64_stats_update_end(struct u64_stats_sync *syncp) { #if BITS_PER_LONG==32 && defined(CONFIG_SMP) write_seqcount_end(&syncp->seq); #endif } -static unsigned int inline u64_stats_fetch_begin(const struct u64_stats_sync *syncp) +static inline unsigned int u64_stats_fetch_begin(const struct u64_stats_sync *syncp) { #if BITS_PER_LONG==32 && defined(CONFIG_SMP) return read_seqcount_begin(&syncp->seq); @@ -93,7 +93,7 @@ static unsigned int inline u64_stats_fetch_begin(const struct u64_stats_sync *sy #endif } -static bool inline u64_stats_fetch_retry(const struct u64_stats_sync *syncp, +static inline bool u64_stats_fetch_retry(const struct u64_stats_sync *syncp, unsigned int start) { #if BITS_PER_LONG==32 && defined(CONFIG_SMP) @@ -112,7 +112,7 @@ static bool inline u64_stats_fetch_retry(const struct u64_stats_sync *syncp, * - UP 32bit must disable BH. * - 64bit have no problem atomically reading u64 values, irq safe. */ -static unsigned int inline u64_stats_fetch_begin_bh(const struct u64_stats_sync *syncp) +static inline unsigned int u64_stats_fetch_begin_bh(const struct u64_stats_sync *syncp) { #if BITS_PER_LONG==32 && defined(CONFIG_SMP) return read_seqcount_begin(&syncp->seq); @@ -124,7 +124,7 @@ static unsigned int inline u64_stats_fetch_begin_bh(const struct u64_stats_sync #endif } -static bool inline u64_stats_fetch_retry_bh(const struct u64_stats_sync *syncp, +static inline bool u64_stats_fetch_retry_bh(const struct u64_stats_sync *syncp, unsigned int start) { #if BITS_PER_LONG==32 && defined(CONFIG_SMP) diff --git a/kernel/perf_event.c b/kernel/perf_event.c index 517d827f4982..06682e7b12e2 100644 --- a/kernel/perf_event.c +++ b/kernel/perf_event.c @@ -4454,7 +4454,7 @@ int perf_swevent_get_recursion_context(void) } EXPORT_SYMBOL_GPL(perf_swevent_get_recursion_context); -void inline perf_swevent_put_recursion_context(int rctx) +inline void perf_swevent_put_recursion_context(int rctx) { struct swevent_htable *swhash = &__get_cpu_var(swevent_htable); diff --git a/kernel/time.c b/kernel/time.c index ba9b338d1835..32174359576f 100644 --- a/kernel/time.c +++ b/kernel/time.c @@ -238,7 +238,7 @@ EXPORT_SYMBOL(current_fs_time); * Avoid unnecessary multiplications/divisions in the * two most common HZ cases: */ -unsigned int inline jiffies_to_msecs(const unsigned long j) +inline unsigned int jiffies_to_msecs(const unsigned long j) { #if HZ <= MSEC_PER_SEC && !(MSEC_PER_SEC % HZ) return (MSEC_PER_SEC / HZ) * j; @@ -254,7 +254,7 @@ unsigned int inline jiffies_to_msecs(const unsigned long j) } EXPORT_SYMBOL(jiffies_to_msecs); -unsigned int inline jiffies_to_usecs(const unsigned long j) +inline unsigned int jiffies_to_usecs(const unsigned long j) { #if HZ <= USEC_PER_SEC && !(USEC_PER_SEC % HZ) return (USEC_PER_SEC / HZ) * j; diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 07a654486f75..f823ee192e94 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -4013,7 +4013,7 @@ static void __init setup_usemap(struct pglist_data *pgdat, zone->pageblock_flags = alloc_bootmem_node(pgdat, usemapsize); } #else -static void inline setup_usemap(struct pglist_data *pgdat, +static inline void setup_usemap(struct pglist_data *pgdat, struct zone *zone, unsigned long zonesize) {} #endif /* CONFIG_SPARSEMEM */ -- cgit v1.2.3 From 559ad0ff1368baea14dbc3207d55b02bd69bda4b Mon Sep 17 00:00:00 2001 From: Mathias Krause Date: Mon, 29 Nov 2010 08:35:39 +0800 Subject: crypto: aesni-intel - Fixed build error on x86-32 Exclude AES-GCM code for x86-32 due to heavy usage of 64-bit registers not available on x86-32. While at it, fixed unregister order in aesni_exit(). Signed-off-by: Mathias Krause Signed-off-by: Herbert Xu --- arch/x86/crypto/aesni-intel_asm.S | 5 ++++- arch/x86/crypto/aesni-intel_glue.c | 26 +++++++++++++------------- 2 files changed, 17 insertions(+), 14 deletions(-) diff --git a/arch/x86/crypto/aesni-intel_asm.S b/arch/x86/crypto/aesni-intel_asm.S index f592e03dc375..d528fde219d2 100644 --- a/arch/x86/crypto/aesni-intel_asm.S +++ b/arch/x86/crypto/aesni-intel_asm.S @@ -32,6 +32,7 @@ #include #include +#ifdef __x86_64__ .data POLY: .octa 0xC2000000000000000000000000000001 TWOONE: .octa 0x00000001000000000000000000000001 @@ -84,6 +85,7 @@ enc: .octa 0x2 #define arg8 STACK_OFFSET+16(%r14) #define arg9 STACK_OFFSET+24(%r14) #define arg10 STACK_OFFSET+32(%r14) +#endif #define STATE1 %xmm0 @@ -130,6 +132,7 @@ enc: .octa 0x2 #endif +#ifdef __x86_64__ /* GHASH_MUL MACRO to implement: Data*HashKey mod (128,127,126,121,0) * * @@ -1255,7 +1258,7 @@ _return_T_done_encrypt: pop %r13 pop %r12 ret - +#endif _key_expansion_128: diff --git a/arch/x86/crypto/aesni-intel_glue.c b/arch/x86/crypto/aesni-intel_glue.c index 8a3b80075216..e1e60c7d5813 100644 --- a/arch/x86/crypto/aesni-intel_glue.c +++ b/arch/x86/crypto/aesni-intel_glue.c @@ -97,7 +97,6 @@ asmlinkage void aesni_cbc_dec(struct crypto_aes_ctx *ctx, u8 *out, #ifdef CONFIG_X86_64 asmlinkage void aesni_ctr_enc(struct crypto_aes_ctx *ctx, u8 *out, const u8 *in, unsigned int len, u8 *iv); -#endif /* asmlinkage void aesni_gcm_enc() * void *ctx, AES Key schedule. Starts on a 16 byte boundary. @@ -149,6 +148,7 @@ aesni_rfc4106_gcm_ctx *aesni_rfc4106_gcm_ctx_get(struct crypto_aead *tfm) PTR_ALIGN((u8 *) crypto_tfm_ctx(crypto_aead_tfm(tfm)), AESNI_ALIGN); } +#endif static inline struct crypto_aes_ctx *aes_ctx(void *raw_ctx) { @@ -822,6 +822,7 @@ static struct crypto_alg ablk_xts_alg = { }; #endif +#ifdef CONFIG_X86_64 static int rfc4106_init(struct crypto_tfm *tfm) { struct cryptd_aead *cryptd_tfm; @@ -1237,6 +1238,7 @@ static struct crypto_alg __rfc4106_alg = { }, }, }; +#endif static int __init aesni_init(void) { @@ -1264,6 +1266,10 @@ static int __init aesni_init(void) goto blk_ctr_err; if ((err = crypto_register_alg(&ablk_ctr_alg))) goto ablk_ctr_err; + if ((err = crypto_register_alg(&__rfc4106_alg))) + goto __aead_gcm_err; + if ((err = crypto_register_alg(&rfc4106_alg))) + goto aead_gcm_err; #ifdef HAS_CTR if ((err = crypto_register_alg(&ablk_rfc3686_ctr_alg))) goto ablk_rfc3686_ctr_err; @@ -1281,19 +1287,9 @@ static int __init aesni_init(void) if ((err = crypto_register_alg(&ablk_xts_alg))) goto ablk_xts_err; #endif - err = crypto_register_alg(&__rfc4106_alg); - if (err) - goto __aead_gcm_err; - err = crypto_register_alg(&rfc4106_alg); - if (err) - goto aead_gcm_err; return err; -aead_gcm_err: - crypto_unregister_alg(&__rfc4106_alg); -__aead_gcm_err: #ifdef HAS_XTS - crypto_unregister_alg(&ablk_xts_alg); ablk_xts_err: #endif #ifdef HAS_PCBC @@ -1309,6 +1305,10 @@ ablk_lrw_err: crypto_unregister_alg(&ablk_rfc3686_ctr_alg); ablk_rfc3686_ctr_err: #endif + crypto_unregister_alg(&rfc4106_alg); +aead_gcm_err: + crypto_unregister_alg(&__rfc4106_alg); +__aead_gcm_err: crypto_unregister_alg(&ablk_ctr_alg); ablk_ctr_err: crypto_unregister_alg(&blk_ctr_alg); @@ -1331,8 +1331,6 @@ aes_err: static void __exit aesni_exit(void) { - crypto_unregister_alg(&__rfc4106_alg); - crypto_unregister_alg(&rfc4106_alg); #ifdef HAS_XTS crypto_unregister_alg(&ablk_xts_alg); #endif @@ -1346,6 +1344,8 @@ static void __exit aesni_exit(void) #ifdef HAS_CTR crypto_unregister_alg(&ablk_rfc3686_ctr_alg); #endif + crypto_unregister_alg(&rfc4106_alg); + crypto_unregister_alg(&__rfc4106_alg); crypto_unregister_alg(&ablk_ctr_alg); crypto_unregister_alg(&blk_ctr_alg); #endif -- cgit v1.2.3 From 64ff31287693c1f325cb9cb049569c1611438ef1 Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Thu, 12 Aug 2010 16:28:09 +0000 Subject: powerpc: Add support for popcnt instructions POWER5 added popcntb, and POWER7 added popcntw and popcntd. As a first step this patch does all the work out of line, but it would be nice to implement them as inlines with an out of line fallback. The performance issue with hweight was noticed when disabling SMT on a large (192 thread) POWER7 box. The patch improves that testcase by about 8%. Signed-off-by: Anton Blanchard Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/include/asm/bitops.h | 9 +++ arch/powerpc/include/asm/cputable.h | 9 ++- arch/powerpc/kernel/ppc_ksyms.c | 7 +++ arch/powerpc/lib/Makefile | 2 +- arch/powerpc/lib/hweight_64.S | 110 ++++++++++++++++++++++++++++++++++++ 5 files changed, 133 insertions(+), 4 deletions(-) create mode 100644 arch/powerpc/lib/hweight_64.S diff --git a/arch/powerpc/include/asm/bitops.h b/arch/powerpc/include/asm/bitops.h index 30964ae2d096..8a7e9314c68a 100644 --- a/arch/powerpc/include/asm/bitops.h +++ b/arch/powerpc/include/asm/bitops.h @@ -267,7 +267,16 @@ static __inline__ int fls64(__u64 x) #include #endif /* __powerpc64__ */ +#ifdef CONFIG_PPC64 +unsigned int __arch_hweight8(unsigned int w); +unsigned int __arch_hweight16(unsigned int w); +unsigned int __arch_hweight32(unsigned int w); +unsigned long __arch_hweight64(__u64 w); +#include +#else #include +#endif + #include /* Little-endian versions */ diff --git a/arch/powerpc/include/asm/cputable.h b/arch/powerpc/include/asm/cputable.h index f3a1fdd9cf08..f0a211d96923 100644 --- a/arch/powerpc/include/asm/cputable.h +++ b/arch/powerpc/include/asm/cputable.h @@ -199,6 +199,8 @@ extern const char *powerpc_base_platform; #define CPU_FTR_UNALIGNED_LD_STD LONG_ASM_CONST(0x0080000000000000) #define CPU_FTR_ASYM_SMT LONG_ASM_CONST(0x0100000000000000) #define CPU_FTR_STCX_CHECKS_ADDRESS LONG_ASM_CONST(0x0200000000000000) +#define CPU_FTR_POPCNTB LONG_ASM_CONST(0x0400000000000000) +#define CPU_FTR_POPCNTD LONG_ASM_CONST(0x0800000000000000) #ifndef __ASSEMBLY__ @@ -403,21 +405,22 @@ extern const char *powerpc_base_platform; CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \ CPU_FTR_MMCRA | CPU_FTR_SMT | \ CPU_FTR_COHERENT_ICACHE | CPU_FTR_LOCKLESS_TLBIE | \ - CPU_FTR_PURR | CPU_FTR_STCX_CHECKS_ADDRESS) + CPU_FTR_PURR | CPU_FTR_STCX_CHECKS_ADDRESS | \ + CPU_FTR_POPCNTB) #define CPU_FTRS_POWER6 (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \ CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \ CPU_FTR_MMCRA | CPU_FTR_SMT | \ CPU_FTR_COHERENT_ICACHE | CPU_FTR_LOCKLESS_TLBIE | \ CPU_FTR_PURR | CPU_FTR_SPURR | CPU_FTR_REAL_LE | \ CPU_FTR_DSCR | CPU_FTR_UNALIGNED_LD_STD | \ - CPU_FTR_STCX_CHECKS_ADDRESS) + CPU_FTR_STCX_CHECKS_ADDRESS | CPU_FTR_POPCNTB) #define CPU_FTRS_POWER7 (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \ CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \ CPU_FTR_MMCRA | CPU_FTR_SMT | \ CPU_FTR_COHERENT_ICACHE | CPU_FTR_LOCKLESS_TLBIE | \ CPU_FTR_PURR | CPU_FTR_SPURR | CPU_FTR_REAL_LE | \ CPU_FTR_DSCR | CPU_FTR_SAO | CPU_FTR_ASYM_SMT | \ - CPU_FTR_STCX_CHECKS_ADDRESS) + CPU_FTR_STCX_CHECKS_ADDRESS | CPU_FTR_POPCNTB | CPU_FTR_POPCNTD) #define CPU_FTRS_CELL (CPU_FTR_USE_TB | CPU_FTR_LWSYNC | \ CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \ CPU_FTR_ALTIVEC_COMP | CPU_FTR_MMCRA | CPU_FTR_SMT | \ diff --git a/arch/powerpc/kernel/ppc_ksyms.c b/arch/powerpc/kernel/ppc_ksyms.c index ab3e392ac63c..ef3ef566235e 100644 --- a/arch/powerpc/kernel/ppc_ksyms.c +++ b/arch/powerpc/kernel/ppc_ksyms.c @@ -186,3 +186,10 @@ EXPORT_SYMBOL(__mtdcr); EXPORT_SYMBOL(__mfdcr); #endif EXPORT_SYMBOL(empty_zero_page); + +#ifdef CONFIG_PPC64 +EXPORT_SYMBOL(__arch_hweight8); +EXPORT_SYMBOL(__arch_hweight16); +EXPORT_SYMBOL(__arch_hweight32); +EXPORT_SYMBOL(__arch_hweight64); +#endif diff --git a/arch/powerpc/lib/Makefile b/arch/powerpc/lib/Makefile index 889f2bc106dd..166a6a0ad544 100644 --- a/arch/powerpc/lib/Makefile +++ b/arch/powerpc/lib/Makefile @@ -16,7 +16,7 @@ obj-$(CONFIG_HAS_IOMEM) += devres.o obj-$(CONFIG_PPC64) += copypage_64.o copyuser_64.o \ memcpy_64.o usercopy_64.o mem_64.o string.o \ - checksum_wrappers_64.o + checksum_wrappers_64.o hweight_64.o obj-$(CONFIG_XMON) += sstep.o ldstfp.o obj-$(CONFIG_KPROBES) += sstep.o ldstfp.o obj-$(CONFIG_HAVE_HW_BREAKPOINT) += sstep.o ldstfp.o diff --git a/arch/powerpc/lib/hweight_64.S b/arch/powerpc/lib/hweight_64.S new file mode 100644 index 000000000000..ee2320bb5ddf --- /dev/null +++ b/arch/powerpc/lib/hweight_64.S @@ -0,0 +1,110 @@ +/* + * 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. + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * Copyright (C) IBM Corporation, 2010 + * + * Author: Anton Blanchard + */ +#include +#include + +/* Note: This code relies on -mminimal-toc */ + +_GLOBAL(__arch_hweight8) +BEGIN_FTR_SECTION + b .__sw_hweight8 + nop + nop +FTR_SECTION_ELSE + popcntb r3,r3 + clrldi r3,r3,64-8 + blr +ALT_FTR_SECTION_END_IFCLR(CPU_FTR_POPCNTB) + +_GLOBAL(__arch_hweight16) +BEGIN_FTR_SECTION + b .__sw_hweight16 + nop + nop + nop + nop +FTR_SECTION_ELSE + BEGIN_FTR_SECTION_NESTED(50) + popcntb r3,r3 + srdi r4,r3,8 + add r3,r4,r3 + clrldi r3,r3,64-8 + blr + FTR_SECTION_ELSE_NESTED(50) + clrlwi r3,r3,16 + popcntw r3,r3 + clrldi r3,r3,64-8 + blr + ALT_FTR_SECTION_END_NESTED_IFCLR(CPU_FTR_POPCNTD, 50) +ALT_FTR_SECTION_END_IFCLR(CPU_FTR_POPCNTB) + +_GLOBAL(__arch_hweight32) +BEGIN_FTR_SECTION + b .__sw_hweight32 + nop + nop + nop + nop + nop + nop +FTR_SECTION_ELSE + BEGIN_FTR_SECTION_NESTED(51) + popcntb r3,r3 + srdi r4,r3,16 + add r3,r4,r3 + srdi r4,r3,8 + add r3,r4,r3 + clrldi r3,r3,64-8 + blr + FTR_SECTION_ELSE_NESTED(51) + popcntw r3,r3 + clrldi r3,r3,64-8 + blr + ALT_FTR_SECTION_END_NESTED_IFCLR(CPU_FTR_POPCNTD, 51) +ALT_FTR_SECTION_END_IFCLR(CPU_FTR_POPCNTB) + +_GLOBAL(__arch_hweight64) +BEGIN_FTR_SECTION + b .__sw_hweight64 + nop + nop + nop + nop + nop + nop + nop + nop +FTR_SECTION_ELSE + BEGIN_FTR_SECTION_NESTED(52) + popcntb r3,r3 + srdi r4,r3,32 + add r3,r4,r3 + srdi r4,r3,16 + add r3,r4,r3 + srdi r4,r3,8 + add r3,r4,r3 + clrldi r3,r3,64-8 + blr + FTR_SECTION_ELSE_NESTED(52) + popcntd r3,r3 + clrldi r3,r3,64-8 + blr + ALT_FTR_SECTION_END_NESTED_IFCLR(CPU_FTR_POPCNTD, 52) +ALT_FTR_SECTION_END_IFCLR(CPU_FTR_POPCNTB) -- cgit v1.2.3 From d72e063bb32c06c6c1cec14f6857b7c37ba62d7a Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Tue, 24 Aug 2010 14:23:44 +0000 Subject: powerpc/kdump: Override crash_free_reserved_phys_range to avoid freeing RTAS The crashkernel region will almost always overlap RTAS. If we free the crashkernel region via "echo 0 > /sys/kernel/kexec_crash_size" then we will free RTAS and the machine will crash in confusing and exciting ways. Override crash_free_reserved_phys_range and check for overlap with RTAS. Signed-off-by: Anton Blanchard Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/crash_dump.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/arch/powerpc/kernel/crash_dump.c b/arch/powerpc/kernel/crash_dump.c index 8e05c16344e4..0a2af50243cb 100644 --- a/arch/powerpc/kernel/crash_dump.c +++ b/arch/powerpc/kernel/crash_dump.c @@ -19,6 +19,7 @@ #include #include #include +#include #ifdef DEBUG #include @@ -141,3 +142,35 @@ ssize_t copy_oldmem_page(unsigned long pfn, char *buf, return csize; } + +#ifdef CONFIG_PPC_RTAS +/* + * The crashkernel region will almost always overlap the RTAS region, so + * we have to be careful when shrinking the crashkernel region. + */ +void crash_free_reserved_phys_range(unsigned long begin, unsigned long end) +{ + unsigned long addr; + const u32 *basep, *sizep; + unsigned int rtas_start = 0, rtas_end = 0; + + basep = of_get_property(rtas.dev, "linux,rtas-base", NULL); + sizep = of_get_property(rtas.dev, "rtas-size", NULL); + + if (basep && sizep) { + rtas_start = *basep; + rtas_end = *basep + *sizep; + } + + for (addr = begin; addr < end; addr += PAGE_SIZE) { + /* Does this page overlap with the RTAS region? */ + if (addr <= rtas_end && ((addr + PAGE_SIZE) > rtas_start)) + continue; + + ClearPageReserved(pfn_to_page(addr >> PAGE_SHIFT)); + init_page_count(pfn_to_page(addr >> PAGE_SHIFT)); + free_page((unsigned long)__va(addr)); + totalram_pages++; + } +} +#endif -- cgit v1.2.3 From 56e640de12c4d9902493cd819c63cacf66515686 Mon Sep 17 00:00:00 2001 From: Christian Dietrich Date: Mon, 6 Sep 2010 04:36:12 +0000 Subject: powerpc: Removing undead ifdef __KERNEL__ The __KERNEL__ ifdef isn't necessary at this point, because it is checked in an outer ifdef level already and has no effect here. Signed-off-by: Christian Dietrich Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/include/asm/processor.h | 2 -- arch/powerpc/include/asm/vdso_datapage.h | 2 -- 2 files changed, 4 deletions(-) diff --git a/arch/powerpc/include/asm/processor.h b/arch/powerpc/include/asm/processor.h index 4c14187ba02d..de1967a1ff57 100644 --- a/arch/powerpc/include/asm/processor.h +++ b/arch/powerpc/include/asm/processor.h @@ -122,7 +122,6 @@ extern struct task_struct *last_task_used_spe; TASK_UNMAPPED_BASE_USER32 : TASK_UNMAPPED_BASE_USER64 ) #endif -#ifdef __KERNEL__ #ifdef __powerpc64__ #define STACK_TOP_USER64 TASK_SIZE_USER64 @@ -139,7 +138,6 @@ extern struct task_struct *last_task_used_spe; #define STACK_TOP_MAX STACK_TOP #endif /* __powerpc64__ */ -#endif /* __KERNEL__ */ typedef struct { unsigned long seg; diff --git a/arch/powerpc/include/asm/vdso_datapage.h b/arch/powerpc/include/asm/vdso_datapage.h index 08679c5319b8..25e39220e89c 100644 --- a/arch/powerpc/include/asm/vdso_datapage.h +++ b/arch/powerpc/include/asm/vdso_datapage.h @@ -116,9 +116,7 @@ struct vdso_data { #endif /* CONFIG_PPC64 */ -#ifdef __KERNEL__ extern struct vdso_data *vdso_data; -#endif #endif /* __ASSEMBLY__ */ -- cgit v1.2.3 From 5a71c61b7724ad0acedff254e07dc1a7dd05ee76 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 13 Sep 2010 09:47:42 +0000 Subject: drivers/char/hvc_vio: Use static const char arrays Signed-off-by: Joe Perches Reviewed-by: Stephen Rothwell Signed-off-by: Benjamin Herrenschmidt --- drivers/char/hvc_vio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/char/hvc_vio.c b/drivers/char/hvc_vio.c index 27370e99c66f..5e2f52b33327 100644 --- a/drivers/char/hvc_vio.c +++ b/drivers/char/hvc_vio.c @@ -39,7 +39,7 @@ #include "hvc_console.h" -char hvc_driver_name[] = "hvc_console"; +static const char hvc_driver_name[] = "hvc_console"; static struct vio_device_id hvc_driver_table[] __devinitdata = { {"serial", "hvterm1"}, -- cgit v1.2.3 From 475fc7c011ace79258c07d981d348a15614e0573 Mon Sep 17 00:00:00 2001 From: Lennert Buytenhek Date: Tue, 21 Sep 2010 23:22:40 +0000 Subject: powerpc: Fix two typos in Documentation/powerpc/booting-without-of.txt Signed-off-by: Lennert Buytenhek Signed-off-by: Benjamin Herrenschmidt --- Documentation/powerpc/booting-without-of.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Documentation/powerpc/booting-without-of.txt b/Documentation/powerpc/booting-without-of.txt index 302db5da49b3..3272ed59dec7 100644 --- a/Documentation/powerpc/booting-without-of.txt +++ b/Documentation/powerpc/booting-without-of.txt @@ -131,7 +131,7 @@ order to avoid the degeneration that had become the ppc32 kernel entry point and the way a new platform should be added to the kernel. The legacy iSeries platform breaks those rules as it predates this scheme, but no new board support will be accepted in the main tree that -doesn't follows them properly. In addition, since the advent of the +doesn't follow them properly. In addition, since the advent of the arch/powerpc merged architecture for ppc32 and ppc64, new 32-bit platforms and 32-bit platforms which move into arch/powerpc will be required to use these rules as well. @@ -1025,7 +1025,7 @@ dtc source code can be found at WARNING: This version is still in early development stage; the resulting device-tree "blobs" have not yet been validated with the -kernel. The current generated bloc lacks a useful reserve map (it will +kernel. The current generated block lacks a useful reserve map (it will be fixed to generate an empty one, it's up to the bootloader to fill it up) among others. The error handling needs work, bugs are lurking, etc... -- cgit v1.2.3 From 4e89a2d8e2d5ab33d73b76f16c10fdf515faabef Mon Sep 17 00:00:00 2001 From: Will Schmidt Date: Tue, 28 Sep 2010 15:33:12 +0000 Subject: powerpc/pseries: Add kernel parameter to disable batched hcalls This introduces a pair of kernel parameters that can be used to disable the MULTITCE and BULK_REMOVE h-calls. By default, those hcalls are enabled, active, and good for throughput and performance. The ability to disable them will be useful for some of the PREEMPT_RT related investigation and work occurring on Power. Signed-off-by: Will Schmidt cc: Olof Johansson cc: Anton Blanchard cc: Benjamin Herrenschmidt Signed-off-by: Benjamin Herrenschmidt --- Documentation/kernel-parameters.txt | 8 ++++++++ arch/powerpc/platforms/pseries/iommu.c | 14 ++++++++++++++ arch/powerpc/platforms/pseries/lpar.c | 12 ++++++++++++ 3 files changed, 34 insertions(+) diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index cdd2a6e8a3b7..69bb6a9c871a 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -403,6 +403,10 @@ and is between 256 and 4096 characters. It is defined in the file bttv.pll= See Documentation/video4linux/bttv/Insmod-options bttv.tuner= and Documentation/video4linux/bttv/CARDLIST + bulk_remove=off [PPC] This parameter disables the use of the pSeries + firmware feature for flushing multiple hpte entries + at a time. + c101= [NET] Moxa C101 synchronous serial card cachesize= [BUGS=X86-32] Override level 2 CPU cache size detection. @@ -1490,6 +1494,10 @@ and is between 256 and 4096 characters. It is defined in the file mtdparts= [MTD] See drivers/mtd/cmdlinepart.c. + multitce=off [PPC] This parameter disables the use of the pSeries + firmware feature for updating multiple TCE entries + at a time. + onenand.bdry= [HW,MTD] Flex-OneNAND Boundary Configuration Format: [die0_boundary][,die0_lock][,die1_boundary][,die1_lock] diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c index a77bcaed80af..fa2906a103dd 100644 --- a/arch/powerpc/platforms/pseries/iommu.c +++ b/arch/powerpc/platforms/pseries/iommu.c @@ -622,3 +622,17 @@ void iommu_init_early_pSeries(void) set_pci_dma_ops(&dma_iommu_ops); } +static int __init disable_multitce(char *str) +{ + if (strcmp(str, "off") == 0 && + firmware_has_feature(FW_FEATURE_LPAR) && + firmware_has_feature(FW_FEATURE_MULTITCE)) { + printk(KERN_INFO "Disabling MULTITCE firmware feature\n"); + ppc_md.tce_build = tce_build_pSeriesLP; + ppc_md.tce_free = tce_free_pSeriesLP; + powerpc_firmware_features &= ~FW_FEATURE_MULTITCE; + } + return 1; +} + +__setup("multitce=", disable_multitce); diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c index f129040d974c..5d3ea9f60dd7 100644 --- a/arch/powerpc/platforms/pseries/lpar.c +++ b/arch/powerpc/platforms/pseries/lpar.c @@ -627,6 +627,18 @@ static void pSeries_lpar_flush_hash_range(unsigned long number, int local) spin_unlock_irqrestore(&pSeries_lpar_tlbie_lock, flags); } +static int __init disable_bulk_remove(char *str) +{ + if (strcmp(str, "off") == 0 && + firmware_has_feature(FW_FEATURE_BULK_REMOVE)) { + printk(KERN_INFO "Disabling BULK_REMOVE firmware feature"); + powerpc_firmware_features &= ~FW_FEATURE_BULK_REMOVE; + } + return 1; +} + +__setup("bulk_remove=", disable_bulk_remove); + void __init hpte_init_lpar(void) { ppc_md.hpte_invalidate = pSeries_lpar_hpte_invalidate; -- cgit v1.2.3 From 787d44caa5bca249d8781d21b626c417f1e3cfc4 Mon Sep 17 00:00:00 2001 From: FUJITA Tomonori Date: Fri, 1 Oct 2010 11:12:54 +0000 Subject: powerpc: enable ARCH_DMA_ADDR_T_64BIT with ARCH_PHYS_ADDR_T_64BIT Signed-off-by: FUJITA Tomonori Cc: Benjamin Herrenschmidt Signed-off-by: Andrew Morton Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/Kconfig | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index e625e9e034ae..06d742c3fbcf 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -20,6 +20,9 @@ config WORD_SIZE config ARCH_PHYS_ADDR_T_64BIT def_bool PPC64 || PHYS_64BIT +config ARCH_DMA_ADDR_T_64BIT + def_bool ARCH_PHYS_ADDR_T_64BIT + config MMU bool default y -- cgit v1.2.3 From 99d86705253dcf728dbbec4d694a6764b6edb70c Mon Sep 17 00:00:00 2001 From: Vaidyanathan Srinivasan Date: Wed, 6 Oct 2010 08:36:59 +0000 Subject: powerpc: Cleanup APIs for cpu/thread/core mappings These APIs take logical cpu number as input Change cpu_first_thread_in_core() to cpu_first_thread_sibling() Change cpu_last_thread_in_core() to cpu_last_thread_sibling() These APIs convert core number (index) to logical cpu/thread numbers Add cpu_first_thread_of_core(int core) Changed cpu_thread_to_core() to cpu_core_index_of_thread(int cpu) The goal is to make 'threads_per_core' accessible to the pseries_energy module. Instead of making an API to read threads_per_core, this is a higher level wrapper function to convert from logical cpu number to core number. The current APIs cpu_first_thread_in_core() and cpu_last_thread_in_core() returns logical CPU number while cpu_thread_to_core() returns core number or index which is not a logical CPU number. The new APIs are now clearly named to distinguish 'core number' versus first and last 'logical cpu number' in that core. The new APIs cpu_{first,last}_thread_sibling() work on logical cpu numbers. While cpu_first_thread_of_core() and cpu_core_index_of_thread() work on core index. Example usage: (4 threads per core system) cpu_first_thread_sibling(5) = 4 cpu_last_thread_sibling(5) = 7 cpu_core_index_of_thread(5) = 1 cpu_first_thread_of_core(1) = 4 cpu_core_index_of_thread() is used in cpu_to_drc_index() in the module and cpu_first_thread_of_core() is used in drc_index_to_cpu() in the module. Make API changes to few callers. Export symbols for use in modules. Signed-off-by: Vaidyanathan Srinivasan Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/include/asm/cputhreads.h | 15 +++++++++------ arch/powerpc/kernel/smp.c | 19 ++++++++++++++++--- arch/powerpc/mm/mmu_context_nohash.c | 12 ++++++------ 3 files changed, 31 insertions(+), 15 deletions(-) diff --git a/arch/powerpc/include/asm/cputhreads.h b/arch/powerpc/include/asm/cputhreads.h index a8e18447c62b..f71bb4c118b4 100644 --- a/arch/powerpc/include/asm/cputhreads.h +++ b/arch/powerpc/include/asm/cputhreads.h @@ -61,22 +61,25 @@ static inline cpumask_t cpu_online_cores_map(void) return cpu_thread_mask_to_cores(cpu_online_map); } -static inline int cpu_thread_to_core(int cpu) -{ - return cpu >> threads_shift; -} +#ifdef CONFIG_SMP +int cpu_core_index_of_thread(int cpu); +int cpu_first_thread_of_core(int core); +#else +static inline int cpu_core_index_of_thread(int cpu) { return cpu; } +static inline int cpu_first_thread_of_core(int core) { return core; } +#endif static inline int cpu_thread_in_core(int cpu) { return cpu & (threads_per_core - 1); } -static inline int cpu_first_thread_in_core(int cpu) +static inline int cpu_first_thread_sibling(int cpu) { return cpu & ~(threads_per_core - 1); } -static inline int cpu_last_thread_in_core(int cpu) +static inline int cpu_last_thread_sibling(int cpu) { return cpu | (threads_per_core - 1); } diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c index 68034bbf2e4f..981360509172 100644 --- a/arch/powerpc/kernel/smp.c +++ b/arch/powerpc/kernel/smp.c @@ -466,7 +466,20 @@ out: return id; } -/* Must be called when no change can occur to cpu_present_mask, +/* Helper routines for cpu to core mapping */ +int cpu_core_index_of_thread(int cpu) +{ + return cpu >> threads_shift; +} +EXPORT_SYMBOL_GPL(cpu_core_index_of_thread); + +int cpu_first_thread_of_core(int core) +{ + return core << threads_shift; +} +EXPORT_SYMBOL_GPL(cpu_first_thread_of_core); + +/* Must be called when no change can occur to cpu_present_map, * i.e. during cpu online or offline. */ static struct device_node *cpu_to_l2cache(int cpu) @@ -514,7 +527,7 @@ int __devinit start_secondary(void *unused) notify_cpu_starting(cpu); set_cpu_online(cpu, true); /* Update sibling maps */ - base = cpu_first_thread_in_core(cpu); + base = cpu_first_thread_sibling(cpu); for (i = 0; i < threads_per_core; i++) { if (cpu_is_offline(base + i)) continue; @@ -600,7 +613,7 @@ int __cpu_disable(void) return err; /* Update sibling maps */ - base = cpu_first_thread_in_core(cpu); + base = cpu_first_thread_sibling(cpu); for (i = 0; i < threads_per_core; i++) { cpumask_clear_cpu(cpu, cpu_sibling_mask(base + i)); cpumask_clear_cpu(base + i, cpu_sibling_mask(cpu)); diff --git a/arch/powerpc/mm/mmu_context_nohash.c b/arch/powerpc/mm/mmu_context_nohash.c index 5ce99848d91e..c0aab52da3a5 100644 --- a/arch/powerpc/mm/mmu_context_nohash.c +++ b/arch/powerpc/mm/mmu_context_nohash.c @@ -111,8 +111,8 @@ static unsigned int steal_context_smp(unsigned int id) * a core map instead but this will do for now. */ for_each_cpu(cpu, mm_cpumask(mm)) { - for (i = cpu_first_thread_in_core(cpu); - i <= cpu_last_thread_in_core(cpu); i++) + for (i = cpu_first_thread_sibling(cpu); + i <= cpu_last_thread_sibling(cpu); i++) __set_bit(id, stale_map[i]); cpu = i - 1; } @@ -264,14 +264,14 @@ void switch_mmu_context(struct mm_struct *prev, struct mm_struct *next) */ if (test_bit(id, stale_map[cpu])) { pr_hardcont(" | stale flush %d [%d..%d]", - id, cpu_first_thread_in_core(cpu), - cpu_last_thread_in_core(cpu)); + id, cpu_first_thread_sibling(cpu), + cpu_last_thread_sibling(cpu)); local_flush_tlb_mm(next); /* XXX This clear should ultimately be part of local_flush_tlb_mm */ - for (i = cpu_first_thread_in_core(cpu); - i <= cpu_last_thread_in_core(cpu); i++) { + for (i = cpu_first_thread_sibling(cpu); + i <= cpu_last_thread_sibling(cpu); i++) { __clear_bit(id, stale_map[i]); } } -- cgit v1.2.3 From 5742bd859524793b857110a13db349d95070d2dc Mon Sep 17 00:00:00 2001 From: Vaidyanathan Srinivasan Date: Wed, 6 Oct 2010 08:37:09 +0000 Subject: powerpc: Add support for new hcall H_BEST_ENERGY Create sysfs interface to export data from H_BEST_ENERGY hcall that can be used by administrative tools on supported pseries platforms for energy management optimizations. sys/device/system/cpu/pseries_(de)activate_hint_list and sys/device/system/cpu/cpuN/pseries_(de)activate_hint will provide hints for activation and deactivation of cpus respectively. These hints are abstract number given by the hypervisor based on the extended knowledge the hypervisor has regarding the system topology and resource mappings. The activate and the deactivate sysfs entry is for the two distinct operations that we could do for energy savings. When we have more capacity than required, we could deactivate few core to save energy. The choice of the core to deactivate will be based on /sys/devices/system/cpu/deactivate_hint_list. The comma separated list of cpus (cores) will be the preferred choice. If we have to activate some of the deactivated cores, then /sys/devices/system/cpu/activate_hint_list will be used. The per-cpu file /sys/device/system/cpu/cpuN/pseries_(de)activate_hint further provide more fine grain information by exporting the value of the hint itself. Added new driver module arch/powerpc/platforms/pseries/pseries_energy.c under new config option CONFIG_PSERIES_ENERGY Signed-off-by: Vaidyanathan Srinivasan Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/include/asm/hvcall.h | 3 +- arch/powerpc/platforms/pseries/Kconfig | 10 + arch/powerpc/platforms/pseries/Makefile | 1 + arch/powerpc/platforms/pseries/pseries_energy.c | 326 ++++++++++++++++++++++++ 4 files changed, 339 insertions(+), 1 deletion(-) create mode 100644 arch/powerpc/platforms/pseries/pseries_energy.c diff --git a/arch/powerpc/include/asm/hvcall.h b/arch/powerpc/include/asm/hvcall.h index de03ca58db5d..bf86b03d5af2 100644 --- a/arch/powerpc/include/asm/hvcall.h +++ b/arch/powerpc/include/asm/hvcall.h @@ -232,7 +232,8 @@ #define H_GET_EM_PARMS 0x2B8 #define H_SET_MPP 0x2D0 #define H_GET_MPP 0x2D4 -#define MAX_HCALL_OPCODE H_GET_MPP +#define H_BEST_ENERGY 0x2F4 +#define MAX_HCALL_OPCODE H_BEST_ENERGY #ifndef __ASSEMBLY__ diff --git a/arch/powerpc/platforms/pseries/Kconfig b/arch/powerpc/platforms/pseries/Kconfig index 3139814f6439..5d1b743dbe7e 100644 --- a/arch/powerpc/platforms/pseries/Kconfig +++ b/arch/powerpc/platforms/pseries/Kconfig @@ -33,6 +33,16 @@ config PSERIES_MSI depends on PCI_MSI && EEH default y +config PSERIES_ENERGY + tristate "pSeries energy management capabilities driver" + depends on PPC_PSERIES + default y + help + Provides interface to platform energy management capabilities + on supported PSERIES platforms. + Provides: /sys/devices/system/cpu/pseries_(de)activation_hint_list + and /sys/devices/system/cpu/cpuN/pseries_(de)activation_hint + config SCANLOG tristate "Scanlog dump interface" depends on RTAS_PROC && PPC_PSERIES diff --git a/arch/powerpc/platforms/pseries/Makefile b/arch/powerpc/platforms/pseries/Makefile index 59eb8bdaa79d..fc5237810ece 100644 --- a/arch/powerpc/platforms/pseries/Makefile +++ b/arch/powerpc/platforms/pseries/Makefile @@ -11,6 +11,7 @@ obj-$(CONFIG_EEH) += eeh.o eeh_cache.o eeh_driver.o eeh_event.o eeh_sysfs.o obj-$(CONFIG_KEXEC) += kexec.o obj-$(CONFIG_PCI) += pci.o pci_dlpar.o obj-$(CONFIG_PSERIES_MSI) += msi.o +obj-$(CONFIG_PSERIES_ENERGY) += pseries_energy.o obj-$(CONFIG_HOTPLUG_CPU) += hotplug-cpu.o obj-$(CONFIG_MEMORY_HOTPLUG) += hotplug-memory.o diff --git a/arch/powerpc/platforms/pseries/pseries_energy.c b/arch/powerpc/platforms/pseries/pseries_energy.c new file mode 100644 index 000000000000..c8b3c69fe891 --- /dev/null +++ b/arch/powerpc/platforms/pseries/pseries_energy.c @@ -0,0 +1,326 @@ +/* + * POWER platform energy management driver + * Copyright (C) 2010 IBM Corporation + * + * 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 pseries platform device driver provides access to + * platform energy management capabilities. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#define MODULE_VERS "1.0" +#define MODULE_NAME "pseries_energy" + +/* Driver flags */ + +static int sysfs_entries; + +/* Helper routines */ + +/* + * Routine to detect firmware support for hcall + * return 1 if H_BEST_ENERGY is supported + * else return 0 + */ + +static int check_for_h_best_energy(void) +{ + struct device_node *rtas = NULL; + const char *hypertas, *s; + int length; + int rc = 0; + + rtas = of_find_node_by_path("/rtas"); + if (!rtas) + return 0; + + hypertas = of_get_property(rtas, "ibm,hypertas-functions", &length); + if (!hypertas) { + of_node_put(rtas); + return 0; + } + + /* hypertas will have list of strings with hcall names */ + for (s = hypertas; s < hypertas + length; s += strlen(s) + 1) { + if (!strncmp("hcall-best-energy-1", s, 19)) { + rc = 1; /* Found the string */ + break; + } + } + of_node_put(rtas); + return rc; +} + +/* Helper Routines to convert between drc_index to cpu numbers */ + +static u32 cpu_to_drc_index(int cpu) +{ + struct device_node *dn = NULL; + const int *indexes; + int i; + int rc = 1; + u32 ret = 0; + + dn = of_find_node_by_path("/cpus"); + if (dn == NULL) + goto err; + indexes = of_get_property(dn, "ibm,drc-indexes", NULL); + if (indexes == NULL) + goto err_of_node_put; + /* Convert logical cpu number to core number */ + i = cpu_core_index_of_thread(cpu); + /* + * The first element indexes[0] is the number of drc_indexes + * returned in the list. Hence i+1 will get the drc_index + * corresponding to core number i. + */ + WARN_ON(i > indexes[0]); + ret = indexes[i + 1]; + rc = 0; + +err_of_node_put: + of_node_put(dn); +err: + if (rc) + printk(KERN_WARNING "cpu_to_drc_index(%d) failed", cpu); + return ret; +} + +static int drc_index_to_cpu(u32 drc_index) +{ + struct device_node *dn = NULL; + const int *indexes; + int i, cpu = 0; + int rc = 1; + + dn = of_find_node_by_path("/cpus"); + if (dn == NULL) + goto err; + indexes = of_get_property(dn, "ibm,drc-indexes", NULL); + if (indexes == NULL) + goto err_of_node_put; + /* + * First element in the array is the number of drc_indexes + * returned. Search through the list to find the matching + * drc_index and get the core number + */ + for (i = 0; i < indexes[0]; i++) { + if (indexes[i + 1] == drc_index) + break; + } + /* Convert core number to logical cpu number */ + cpu = cpu_first_thread_of_core(i); + rc = 0; + +err_of_node_put: + of_node_put(dn); +err: + if (rc) + printk(KERN_WARNING "drc_index_to_cpu(%d) failed", drc_index); + return cpu; +} + +/* + * pseries hypervisor call H_BEST_ENERGY provides hints to OS on + * preferred logical cpus to activate or deactivate for optimized + * energy consumption. + */ + +#define FLAGS_MODE1 0x004E200000080E01 +#define FLAGS_MODE2 0x004E200000080401 +#define FLAGS_ACTIVATE 0x100 + +static ssize_t get_best_energy_list(char *page, int activate) +{ + int rc, cnt, i, cpu; + unsigned long retbuf[PLPAR_HCALL9_BUFSIZE]; + unsigned long flags = 0; + u32 *buf_page; + char *s = page; + + buf_page = (u32 *) get_zeroed_page(GFP_KERNEL); + if (!buf_page) + return -ENOMEM; + + flags = FLAGS_MODE1; + if (activate) + flags |= FLAGS_ACTIVATE; + + rc = plpar_hcall9(H_BEST_ENERGY, retbuf, flags, 0, __pa(buf_page), + 0, 0, 0, 0, 0, 0); + if (rc != H_SUCCESS) { + free_page((unsigned long) buf_page); + return -EINVAL; + } + + cnt = retbuf[0]; + for (i = 0; i < cnt; i++) { + cpu = drc_index_to_cpu(buf_page[2*i+1]); + if ((cpu_online(cpu) && !activate) || + (!cpu_online(cpu) && activate)) + s += sprintf(s, "%d,", cpu); + } + if (s > page) { /* Something to show */ + s--; /* Suppress last comma */ + s += sprintf(s, "\n"); + } + + free_page((unsigned long) buf_page); + return s-page; +} + +static ssize_t get_best_energy_data(struct sys_device *dev, + char *page, int activate) +{ + int rc; + unsigned long retbuf[PLPAR_HCALL9_BUFSIZE]; + unsigned long flags = 0; + + flags = FLAGS_MODE2; + if (activate) + flags |= FLAGS_ACTIVATE; + + rc = plpar_hcall9(H_BEST_ENERGY, retbuf, flags, + cpu_to_drc_index(dev->id), + 0, 0, 0, 0, 0, 0, 0); + + if (rc != H_SUCCESS) + return -EINVAL; + + return sprintf(page, "%lu\n", retbuf[1] >> 32); +} + +/* Wrapper functions */ + +static ssize_t cpu_activate_hint_list_show(struct sysdev_class *class, + struct sysdev_class_attribute *attr, char *page) +{ + return get_best_energy_list(page, 1); +} + +static ssize_t cpu_deactivate_hint_list_show(struct sysdev_class *class, + struct sysdev_class_attribute *attr, char *page) +{ + return get_best_energy_list(page, 0); +} + +static ssize_t percpu_activate_hint_show(struct sys_device *dev, + struct sysdev_attribute *attr, char *page) +{ + return get_best_energy_data(dev, page, 1); +} + +static ssize_t percpu_deactivate_hint_show(struct sys_device *dev, + struct sysdev_attribute *attr, char *page) +{ + return get_best_energy_data(dev, page, 0); +} + +/* + * Create sysfs interface: + * /sys/devices/system/cpu/pseries_activate_hint_list + * /sys/devices/system/cpu/pseries_deactivate_hint_list + * Comma separated list of cpus to activate or deactivate + * /sys/devices/system/cpu/cpuN/pseries_activate_hint + * /sys/devices/system/cpu/cpuN/pseries_deactivate_hint + * Per-cpu value of the hint + */ + +struct sysdev_class_attribute attr_cpu_activate_hint_list = + _SYSDEV_CLASS_ATTR(pseries_activate_hint_list, 0444, + cpu_activate_hint_list_show, NULL); + +struct sysdev_class_attribute attr_cpu_deactivate_hint_list = + _SYSDEV_CLASS_ATTR(pseries_deactivate_hint_list, 0444, + cpu_deactivate_hint_list_show, NULL); + +struct sysdev_attribute attr_percpu_activate_hint = + _SYSDEV_ATTR(pseries_activate_hint, 0444, + percpu_activate_hint_show, NULL); + +struct sysdev_attribute attr_percpu_deactivate_hint = + _SYSDEV_ATTR(pseries_deactivate_hint, 0444, + percpu_deactivate_hint_show, NULL); + +static int __init pseries_energy_init(void) +{ + int cpu, err; + struct sys_device *cpu_sys_dev; + + if (!check_for_h_best_energy()) { + printk(KERN_INFO "Hypercall H_BEST_ENERGY not supported\n"); + return 0; + } + /* Create the sysfs files */ + err = sysfs_create_file(&cpu_sysdev_class.kset.kobj, + &attr_cpu_activate_hint_list.attr); + if (!err) + err = sysfs_create_file(&cpu_sysdev_class.kset.kobj, + &attr_cpu_deactivate_hint_list.attr); + + if (err) + return err; + for_each_possible_cpu(cpu) { + cpu_sys_dev = get_cpu_sysdev(cpu); + err = sysfs_create_file(&cpu_sys_dev->kobj, + &attr_percpu_activate_hint.attr); + if (err) + break; + err = sysfs_create_file(&cpu_sys_dev->kobj, + &attr_percpu_deactivate_hint.attr); + if (err) + break; + } + + if (err) + return err; + + sysfs_entries = 1; /* Removed entries on cleanup */ + return 0; + +} + +static void __exit pseries_energy_cleanup(void) +{ + int cpu; + struct sys_device *cpu_sys_dev; + + if (!sysfs_entries) + return; + + /* Remove the sysfs files */ + sysfs_remove_file(&cpu_sysdev_class.kset.kobj, + &attr_cpu_activate_hint_list.attr); + + sysfs_remove_file(&cpu_sysdev_class.kset.kobj, + &attr_cpu_deactivate_hint_list.attr); + + for_each_possible_cpu(cpu) { + cpu_sys_dev = get_cpu_sysdev(cpu); + sysfs_remove_file(&cpu_sys_dev->kobj, + &attr_percpu_activate_hint.attr); + sysfs_remove_file(&cpu_sys_dev->kobj, + &attr_percpu_deactivate_hint.attr); + } +} + +module_init(pseries_energy_init); +module_exit(pseries_energy_cleanup); +MODULE_DESCRIPTION("Driver for pSeries platform energy management"); +MODULE_AUTHOR("Vaidyanathan Srinivasan"); +MODULE_LICENSE("GPL"); -- cgit v1.2.3 From 8cb7c71bda16e2d67a332642661e0b4219641a23 Mon Sep 17 00:00:00 2001 From: Srikanth Krishnakar Date: Thu, 14 Oct 2010 04:03:35 +0000 Subject: rtc-cmos.c : Fix warning on PowerPC The following warning is seen while compilation of PowerPC kernel: CC drivers/rtc/rtc-cmos.o drivers/rtc/rtc-cmos.c:697:2: warning: #warning Assuming 128 bytes of RTC+NVRAM address space, not 64 bytes. Fix it by adding defined(__powerpc__). Signed-off-by: Srikanth Krishnakar Signed-off-by: Benjamin Herrenschmidt --- drivers/rtc/rtc-cmos.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c index 5856167a0c90..7e6ce626b7f1 100644 --- a/drivers/rtc/rtc-cmos.c +++ b/drivers/rtc/rtc-cmos.c @@ -687,7 +687,8 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq) #if defined(CONFIG_ATARI) address_space = 64; #elif defined(__i386__) || defined(__x86_64__) || defined(__arm__) \ - || defined(__sparc__) || defined(__mips__) + || defined(__sparc__) || defined(__mips__) \ + || defined(__powerpc__) address_space = 128; #else #warning Assuming 128 bytes of RTC+NVRAM address space, not 64 bytes. -- cgit v1.2.3 From 72b962d3bba19657abaa6cc8806661ecbde5ee92 Mon Sep 17 00:00:00 2001 From: Tracey Dent Date: Fri, 15 Oct 2010 17:30:48 +0000 Subject: powerpc/ps3: Replace the use of -objs with -y Changed -objs to -y in Makefile. Signed-off-by: Tracey Dent Signed-off-by: Benjamin Herrenschmidt --- drivers/ps3/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/ps3/Makefile b/drivers/ps3/Makefile index ccea15c11c19..50cb1e1b4a12 100644 --- a/drivers/ps3/Makefile +++ b/drivers/ps3/Makefile @@ -1,6 +1,6 @@ obj-$(CONFIG_PS3_VUART) += ps3-vuart.o obj-$(CONFIG_PS3_PS3AV) += ps3av_mod.o -ps3av_mod-objs += ps3av.o ps3av_cmd.o +ps3av_mod-y := ps3av.o ps3av_cmd.o obj-$(CONFIG_PPC_PS3) += sys-manager-core.o obj-$(CONFIG_PS3_SYS_MANAGER) += ps3-sys-manager.o obj-$(CONFIG_PS3_STORAGE) += ps3stor_lib.o -- cgit v1.2.3 From 6d283d782f9fbafee5c672bfdaff4c10f6fdc788 Mon Sep 17 00:00:00 2001 From: Nishanth Aravamudan Date: Mon, 18 Oct 2010 07:26:59 +0000 Subject: powerpc/vio: Use dma ops helpers Use the set_dma_ops helper. Instead of modifying vio_dma_mapping_ops, just create a trivial wrapper for dma_supported. Signed-off-by: Milton Miller Signed-off-by: Nishanth Aravamudan Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/vio.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/arch/powerpc/kernel/vio.c b/arch/powerpc/kernel/vio.c index 441d2a722f06..b2654058f2e4 100644 --- a/arch/powerpc/kernel/vio.c +++ b/arch/powerpc/kernel/vio.c @@ -600,6 +600,11 @@ static void vio_dma_iommu_unmap_sg(struct device *dev, vio_cmo_dealloc(viodev, alloc_size); } +static int vio_dma_iommu_dma_supported(struct device *dev, u64 mask) +{ + return dma_iommu_ops.dma_supported(dev, mask); +} + struct dma_map_ops vio_dma_mapping_ops = { .alloc_coherent = vio_dma_iommu_alloc_coherent, .free_coherent = vio_dma_iommu_free_coherent, @@ -607,6 +612,7 @@ struct dma_map_ops vio_dma_mapping_ops = { .unmap_sg = vio_dma_iommu_unmap_sg, .map_page = vio_dma_iommu_map_page, .unmap_page = vio_dma_iommu_unmap_page, + .dma_supported = vio_dma_iommu_dma_supported, }; @@ -858,8 +864,7 @@ static void vio_cmo_bus_remove(struct vio_dev *viodev) static void vio_cmo_set_dma_ops(struct vio_dev *viodev) { - vio_dma_mapping_ops.dma_supported = dma_iommu_ops.dma_supported; - viodev->dev.archdata.dma_ops = &vio_dma_mapping_ops; + set_dma_ops(&viodev->dev, &vio_dma_mapping_ops); } /** @@ -1244,7 +1249,7 @@ struct vio_dev *vio_register_device_node(struct device_node *of_node) if (firmware_has_feature(FW_FEATURE_CMO)) vio_cmo_set_dma_ops(viodev); else - viodev->dev.archdata.dma_ops = &dma_iommu_ops; + set_dma_ops(&viodev->dev, &dma_iommu_ops); set_iommu_table_base(&viodev->dev, vio_build_iommu_table(viodev)); set_dev_node(&viodev->dev, of_node_to_nid(of_node)); -- cgit v1.2.3 From 2f9c9be2ff31670c942572cf96eb6c696362b584 Mon Sep 17 00:00:00 2001 From: Nishanth Aravamudan Date: Mon, 18 Oct 2010 07:27:00 +0000 Subject: powerpc/pasemi: Clean up pasemi iommu table initializations No need for empty helpers with iommu off, the ppc_md hooks are optional. The direct_dma_ops are the default pci_dma_ops, so no need to set in the them iommu off case. No need to set the device tree device_node pci node iommu pointer, its only used for dlpar remove. Signed-off-by: Milton Miller Signed-off-by: Nishanth Aravamudan Acked-by: Olof Johansson Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/platforms/pasemi/iommu.c | 19 +------------------ 1 file changed, 1 insertion(+), 18 deletions(-) diff --git a/arch/powerpc/platforms/pasemi/iommu.c b/arch/powerpc/platforms/pasemi/iommu.c index 1f9fb2c57761..14943ef01918 100644 --- a/arch/powerpc/platforms/pasemi/iommu.c +++ b/arch/powerpc/platforms/pasemi/iommu.c @@ -156,20 +156,12 @@ static void iommu_table_iobmap_setup(void) static void pci_dma_bus_setup_pasemi(struct pci_bus *bus) { - struct device_node *dn; - pr_debug("pci_dma_bus_setup, bus %p, bus->self %p\n", bus, bus->self); if (!iommu_table_iobmap_inited) { iommu_table_iobmap_inited = 1; iommu_table_iobmap_setup(); } - - dn = pci_bus_to_OF_node(bus); - - if (dn) - PCI_DN(dn)->iommu_table = &iommu_table_iobmap; - } @@ -192,9 +184,6 @@ static void pci_dma_dev_setup_pasemi(struct pci_dev *dev) set_iommu_table_base(&dev->dev, &iommu_table_iobmap); } -static void pci_dma_bus_setup_null(struct pci_bus *b) { } -static void pci_dma_dev_setup_null(struct pci_dev *d) { } - int __init iob_init(struct device_node *dn) { unsigned long tmp; @@ -251,14 +240,8 @@ void __init iommu_init_early_pasemi(void) iommu_off = of_chosen && of_get_property(of_chosen, "linux,iommu-off", NULL); #endif - if (iommu_off) { - /* Direct I/O, IOMMU off */ - ppc_md.pci_dma_dev_setup = pci_dma_dev_setup_null; - ppc_md.pci_dma_bus_setup = pci_dma_bus_setup_null; - set_pci_dma_ops(&dma_direct_ops); - + if (iommu_off) return; - } iob_init(NULL); -- cgit v1.2.3 From 741d204cee6d62bbe0f74ab57ef31702b7d90f62 Mon Sep 17 00:00:00 2001 From: Nishanth Aravamudan Date: Mon, 18 Oct 2010 07:27:01 +0000 Subject: powerpc/cell: Beat dma ops cleanup direct_dma_ops is the default pci dma ops. No need to call a function to get the pci dma ops, we know they are the dma_direct_ops. Signed-off-by: Milton Miller Signed-off-by: Nishanth Aravamudan Acked-by: Arnd Bergmann Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/platforms/cell/beat_iommu.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/arch/powerpc/platforms/cell/beat_iommu.c b/arch/powerpc/platforms/cell/beat_iommu.c index beec405eb6f8..3ce685568935 100644 --- a/arch/powerpc/platforms/cell/beat_iommu.c +++ b/arch/powerpc/platforms/cell/beat_iommu.c @@ -76,7 +76,7 @@ static void __init celleb_init_direct_mapping(void) static void celleb_dma_dev_setup(struct device *dev) { - dev->archdata.dma_ops = get_pci_dma_ops(); + set_dma_ops(dev, &dma_direct_ops); set_dma_offset(dev, celleb_dma_direct_offset); } @@ -106,7 +106,6 @@ static struct notifier_block celleb_of_bus_notifier = { static int __init celleb_init_iommu(void) { celleb_init_direct_mapping(); - set_pci_dma_ops(&dma_direct_ops); ppc_md.pci_dma_dev_setup = celleb_pci_dma_dev_setup; bus_register_notifier(&platform_bus_type, &celleb_of_bus_notifier); -- cgit v1.2.3 From 34c4d012554ed8c99b3fb25baea9bab3507e9f76 Mon Sep 17 00:00:00 2001 From: Nishanth Aravamudan Date: Mon, 18 Oct 2010 07:27:02 +0000 Subject: powerpc/dart: iommu table cleanup No need to set the device tree device_node pci node iommu pointer, its only used for dlpar remove. Signed-off-by: Milton Miller Signed-off-by: Nishanth Aravamudan Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/sysdev/dart_iommu.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/arch/powerpc/sysdev/dart_iommu.c b/arch/powerpc/sysdev/dart_iommu.c index 17cf15ec38be..8e9e06a7ca59 100644 --- a/arch/powerpc/sysdev/dart_iommu.c +++ b/arch/powerpc/sysdev/dart_iommu.c @@ -312,17 +312,10 @@ static void pci_dma_dev_setup_dart(struct pci_dev *dev) static void pci_dma_bus_setup_dart(struct pci_bus *bus) { - struct device_node *dn; - if (!iommu_table_dart_inited) { iommu_table_dart_inited = 1; iommu_table_dart_setup(); } - - dn = pci_bus_to_OF_node(bus); - - if (dn) - PCI_DN(dn)->iommu_table = &iommu_table_dart; } static bool dart_device_on_pcie(struct device *dev) @@ -373,7 +366,7 @@ void __init iommu_init_early_dart(void) if (dn == NULL) { dn = of_find_compatible_node(NULL, "dart", "u4-dart"); if (dn == NULL) - goto bail; + return; /* use default direct_dma_ops */ dart_is_u4 = 1; } -- cgit v1.2.3 From a8daac8a517dacfea951424f67c1f07e1f76b2ad Mon Sep 17 00:00:00 2001 From: Nishanth Aravamudan Date: Mon, 18 Oct 2010 07:27:03 +0000 Subject: powerpc/pseries: iommu cleanup No need to initialize per-cpu pointer to NULL, it is the default. Direct dma ops and no setup are the defaults, no need to set for iommu-off. Signed-off-by: Milton Miller Signed-off-by: Nishanth Aravamudan Reviewed-by: Grant Likely Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/platforms/pseries/iommu.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c index fa2906a103dd..9fecb313a4c9 100644 --- a/arch/powerpc/platforms/pseries/iommu.c +++ b/arch/powerpc/platforms/pseries/iommu.c @@ -140,7 +140,7 @@ static int tce_build_pSeriesLP(struct iommu_table *tbl, long tcenum, return ret; } -static DEFINE_PER_CPU(u64 *, tce_page) = NULL; +static DEFINE_PER_CPU(u64 *, tce_page); static int tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum, long npages, unsigned long uaddr, @@ -589,13 +589,8 @@ static struct notifier_block iommu_reconfig_nb = { /* These are called very early. */ void iommu_init_early_pSeries(void) { - if (of_chosen && of_get_property(of_chosen, "linux,iommu-off", NULL)) { - /* Direct I/O, IOMMU off */ - ppc_md.pci_dma_dev_setup = NULL; - ppc_md.pci_dma_bus_setup = NULL; - set_pci_dma_ops(&dma_direct_ops); + if (of_chosen && of_get_property(of_chosen, "linux,iommu-off", NULL)) return; - } if (firmware_has_feature(FW_FEATURE_LPAR)) { if (firmware_has_feature(FW_FEATURE_MULTITCE)) { -- cgit v1.2.3 From f6aedd8606ae673f8e1f4d972fc86c451fbc8ba7 Mon Sep 17 00:00:00 2001 From: Nishanth Aravamudan Date: Tue, 26 Oct 2010 17:35:11 +0000 Subject: powerpc/macio: Ensure all dma routines get copied over Also add a comment to dev_archdata, indicating that changes there need to be verified against the driver code. Signed-off-by: Milton Miller Signed-off-by: Nishanth Aravamudan Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/include/asm/device.h | 6 ++++++ drivers/macintosh/macio_asic.c | 7 +++---- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/arch/powerpc/include/asm/device.h b/arch/powerpc/include/asm/device.h index a3954e4fcbe2..16d25c0974be 100644 --- a/arch/powerpc/include/asm/device.h +++ b/arch/powerpc/include/asm/device.h @@ -9,6 +9,12 @@ struct dma_map_ops; struct device_node; +/* + * Arch extensions to struct device. + * + * When adding fields, consider macio_add_one_device in + * drivers/macintosh/macio_asic.c + */ struct dev_archdata { /* DMA operations on that device */ struct dma_map_ops *dma_ops; diff --git a/drivers/macintosh/macio_asic.c b/drivers/macintosh/macio_asic.c index b6e7ddc09d76..4daf9e5a7736 100644 --- a/drivers/macintosh/macio_asic.c +++ b/drivers/macintosh/macio_asic.c @@ -387,11 +387,10 @@ static struct macio_dev * macio_add_one_device(struct macio_chip *chip, /* Set the DMA ops to the ones from the PCI device, this could be * fishy if we didn't know that on PowerMac it's always direct ops * or iommu ops that will work fine + * + * To get all the fields, copy all archdata */ - dev->ofdev.dev.archdata.dma_ops = - chip->lbus.pdev->dev.archdata.dma_ops; - dev->ofdev.dev.archdata.dma_data = - chip->lbus.pdev->dev.archdata.dma_data; + dev->ofdev.dev.archdata = chip->lbus.pdev->dev.archdata; #endif /* CONFIG_PCI */ #ifdef DEBUG -- cgit v1.2.3 From cd34206e949b66d3c5fa3e4d2905aa4af29d1b85 Mon Sep 17 00:00:00 2001 From: Nishanth Aravamudan Date: Tue, 26 Oct 2010 17:35:12 +0000 Subject: powerpc: Add memory_hotplug_max() Add a function to get the maximum address that can be hotplug added. This is needed to calculate the size of the tce table needed to cover all memory in 1:1 mode. Signed-off-by: Milton Miller Signed-off-by: Nishanth Aravamudan Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/include/asm/mmzone.h | 5 +++++ arch/powerpc/mm/numa.c | 26 ++++++++++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/arch/powerpc/include/asm/mmzone.h b/arch/powerpc/include/asm/mmzone.h index aac87cbceb57..fd3fd58bad84 100644 --- a/arch/powerpc/include/asm/mmzone.h +++ b/arch/powerpc/include/asm/mmzone.h @@ -33,6 +33,9 @@ extern int numa_cpu_lookup_table[]; extern cpumask_var_t node_to_cpumask_map[]; #ifdef CONFIG_MEMORY_HOTPLUG extern unsigned long max_pfn; +u64 memory_hotplug_max(void); +#else +#define memory_hotplug_max() memblock_end_of_DRAM() #endif /* @@ -42,6 +45,8 @@ extern unsigned long max_pfn; #define node_start_pfn(nid) (NODE_DATA(nid)->node_start_pfn) #define node_end_pfn(nid) (NODE_DATA(nid)->node_end_pfn) +#else +#define memory_hotplug_max() memblock_end_of_DRAM() #endif /* CONFIG_NEED_MULTIPLE_NODES */ #endif /* __KERNEL__ */ diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c index 74505b245374..8c0944c465f6 100644 --- a/arch/powerpc/mm/numa.c +++ b/arch/powerpc/mm/numa.c @@ -1247,4 +1247,30 @@ int hot_add_scn_to_nid(unsigned long scn_addr) return nid; } +static u64 hot_add_drconf_memory_max(void) +{ + struct device_node *memory = NULL; + unsigned int drconf_cell_cnt = 0; + u64 lmb_size = 0; + const u32 *dm = 0; + + memory = of_find_node_by_path("/ibm,dynamic-reconfiguration-memory"); + if (memory) { + drconf_cell_cnt = of_get_drconf_memory(memory, &dm); + lmb_size = of_get_lmb_size(memory); + of_node_put(memory); + } + return lmb_size * drconf_cell_cnt; +} + +/* + * memory_hotplug_max - return max address of memory that may be added + * + * This is currently only used on systems that support drconfig memory + * hotplug. + */ +u64 memory_hotplug_max(void) +{ + return max(hot_add_drconf_memory_max(), memblock_end_of_DRAM()); +} #endif /* CONFIG_MEMORY_HOTPLUG */ -- cgit v1.2.3 From 467d93a7ee64a5c8f675589d658ce3b8b502d288 Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Sat, 30 Oct 2010 08:10:41 +0000 Subject: powerpc/cell: Use vzalloc rather than vmalloc and memset in spu_alloc_lscsa_std Hi, We can get rid of a memset in arch/powerpc/platforms/cell/spufs/lscsa_alloc.c::spu_alloc_lscsa_std() by using vzalloc() rather than vmalloc()+memset(). Completely untested patch below since I have no hardware nor tools to compile this. Signed-off-by: Jesper Juhl Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/platforms/cell/spufs/lscsa_alloc.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/arch/powerpc/platforms/cell/spufs/lscsa_alloc.c b/arch/powerpc/platforms/cell/spufs/lscsa_alloc.c index a101abf17504..3b894f585280 100644 --- a/arch/powerpc/platforms/cell/spufs/lscsa_alloc.c +++ b/arch/powerpc/platforms/cell/spufs/lscsa_alloc.c @@ -36,10 +36,9 @@ static int spu_alloc_lscsa_std(struct spu_state *csa) struct spu_lscsa *lscsa; unsigned char *p; - lscsa = vmalloc(sizeof(struct spu_lscsa)); + lscsa = vzalloc(sizeof(struct spu_lscsa)); if (!lscsa) return -ENOMEM; - memset(lscsa, 0, sizeof(struct spu_lscsa)); csa->lscsa = lscsa; /* Set LS pages reserved to allow for user-space mapping. */ -- cgit v1.2.3 From f7dec88781dd3ad62ebd4acc515c8938c15353ac Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Thu, 4 Nov 2010 13:29:40 +0000 Subject: powerpc/iseries: Remove unused mf_getSrcHistory function and caller. On Tue, 2 Nov 2010, Michael Ellerman wrote: > On Mon, 2010-11-01 at 22:20 +0100, Jesper Juhl wrote: > > Hi Stephen, > > > > On Tue, 2 Nov 2010, Stephen Rothwell wrote: > > > > > On Mon, 1 Nov 2010 21:06:23 +0100 (CET) Jesper Juhl wrote: > > > > > > > > Remove unused function 'mf_getSrcHistory' (that will never be used ever > > > > according to Stephen Rothwell). > > > > > > > > Signed-off-by: Jesper Juhl > > > > > > Acked-by: Stephen Rothwell > > > > > > > Ok, so if you are the (unofficial) iSeries maintainer and you don't merge > > the patch somewhere that'll eventually go up-stream, but just ACK it > > (thank you for that btw), then where do I send it to get it merged? > > Here. ie. linuxppc-dev. > > But, while you're removing it you should remove the #if 0'ed callsite as > well, see mf_src_proc_show() in that file. :) > Done. See patch below. Remove unused function 'mf_getSrcHistory' (that will never be used ever according to Stephen Rothwell) and also remove most of (under 'if 0') code from mf_src_proc_show() where the function was called. Signed-off-by: Jesper Juhl Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/platforms/iseries/mf.c | 62 ------------------------------------- 1 file changed, 62 deletions(-) diff --git a/arch/powerpc/platforms/iseries/mf.c b/arch/powerpc/platforms/iseries/mf.c index 42d0a886de05..b5e026bdca21 100644 --- a/arch/powerpc/platforms/iseries/mf.c +++ b/arch/powerpc/platforms/iseries/mf.c @@ -1045,71 +1045,9 @@ static const struct file_operations mf_side_proc_fops = { .write = mf_side_proc_write, }; -#if 0 -static void mf_getSrcHistory(char *buffer, int size) -{ - struct IplTypeReturnStuff return_stuff; - struct pending_event *ev = new_pending_event(); - int rc = 0; - char *pages[4]; - - pages[0] = kmalloc(4096, GFP_ATOMIC); - pages[1] = kmalloc(4096, GFP_ATOMIC); - pages[2] = kmalloc(4096, GFP_ATOMIC); - pages[3] = kmalloc(4096, GFP_ATOMIC); - if ((ev == NULL) || (pages[0] == NULL) || (pages[1] == NULL) - || (pages[2] == NULL) || (pages[3] == NULL)) - return -ENOMEM; - - return_stuff.xType = 0; - return_stuff.xRc = 0; - return_stuff.xDone = 0; - ev->event.hp_lp_event.xSubtype = 6; - ev->event.hp_lp_event.x.xSubtypeData = - subtype_data('M', 'F', 'V', 'I'); - ev->event.data.vsp_cmd.xEvent = &return_stuff; - ev->event.data.vsp_cmd.cmd = 4; - ev->event.data.vsp_cmd.lp_index = HvLpConfig_getLpIndex(); - ev->event.data.vsp_cmd.result_code = 0xFF; - ev->event.data.vsp_cmd.reserved = 0; - ev->event.data.vsp_cmd.sub_data.page[0] = iseries_hv_addr(pages[0]); - ev->event.data.vsp_cmd.sub_data.page[1] = iseries_hv_addr(pages[1]); - ev->event.data.vsp_cmd.sub_data.page[2] = iseries_hv_addr(pages[2]); - ev->event.data.vsp_cmd.sub_data.page[3] = iseries_hv_addr(pages[3]); - mb(); - if (signal_event(ev) != 0) - return; - - while (return_stuff.xDone != 1) - udelay(10); - if (return_stuff.xRc == 0) - memcpy(buffer, pages[0], size); - kfree(pages[0]); - kfree(pages[1]); - kfree(pages[2]); - kfree(pages[3]); -} -#endif - static int mf_src_proc_show(struct seq_file *m, void *v) { -#if 0 - int len; - - mf_getSrcHistory(page, count); - len = count; - len -= off; - if (len < count) { - *eof = 1; - if (len <= 0) - return 0; - } else - len = count; - *start = page + off; - return len; -#else return 0; -#endif } static int mf_src_proc_open(struct inode *inode, struct file *file) -- cgit v1.2.3 From 698193d85aa8aba003bacd09e40bbd78474fb00f Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Mon, 8 Nov 2010 17:31:36 +0000 Subject: powerpc: Consolidate obj-y assignments No need to have three of them. Signed-off-by: Michael Ellerman Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/Makefile | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index 36c30f31ec93..3bb2a3e6a337 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile @@ -29,8 +29,10 @@ endif obj-y := cputable.o ptrace.o syscalls.o \ irq.o align.o signal_32.o pmc.o vdso.o \ init_task.o process.o systbl.o idle.o \ - signal.o sysfs.o cacheinfo.o -obj-y += vdso32/ + signal.o sysfs.o cacheinfo.o time.o \ + prom.o traps.o setup-common.o \ + udbg.o misc.o io.o dma.o \ + misc_$(CONFIG_WORD_SIZE).o vdso32/ obj-$(CONFIG_PPC64) += setup_64.o sys_ppc32.o \ signal_64.o ptrace32.o \ paca.o nvram_64.o firmware.o @@ -80,9 +82,6 @@ extra-$(CONFIG_FSL_BOOKE) := head_fsl_booke.o extra-$(CONFIG_8xx) := head_8xx.o extra-y += vmlinux.lds -obj-y += time.o prom.o traps.o setup-common.o \ - udbg.o misc.o io.o dma.o \ - misc_$(CONFIG_WORD_SIZE).o obj-$(CONFIG_PPC32) += entry_32.o setup_32.o obj-$(CONFIG_PPC64) += dma-iommu.o iommu.o obj-$(CONFIG_KGDB) += kgdb.o -- cgit v1.2.3 From 36f567b42932a81866bf723779703ecc84cf714b Mon Sep 17 00:00:00 2001 From: Jesse Larrew Date: Tue, 9 Nov 2010 13:24:48 +0000 Subject: powerpc: Add VPHN firmware feature This simple patch adds the firmware feature for VPHN to the firmware features bitmask. Signed-off-by: Jesse Larrew Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/include/asm/firmware.h | 3 ++- arch/powerpc/include/asm/hvcall.h | 1 + arch/powerpc/platforms/pseries/firmware.c | 1 + 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/arch/powerpc/include/asm/firmware.h b/arch/powerpc/include/asm/firmware.h index 20778a405d7a..4ef662e4a31d 100644 --- a/arch/powerpc/include/asm/firmware.h +++ b/arch/powerpc/include/asm/firmware.h @@ -46,6 +46,7 @@ #define FW_FEATURE_PS3_LV1 ASM_CONST(0x0000000000800000) #define FW_FEATURE_BEAT ASM_CONST(0x0000000001000000) #define FW_FEATURE_CMO ASM_CONST(0x0000000002000000) +#define FW_FEATURE_VPHN ASM_CONST(0x0000000004000000) #ifndef __ASSEMBLY__ @@ -59,7 +60,7 @@ enum { FW_FEATURE_VIO | FW_FEATURE_RDMA | FW_FEATURE_LLAN | FW_FEATURE_BULK_REMOVE | FW_FEATURE_XDABR | FW_FEATURE_MULTITCE | FW_FEATURE_SPLPAR | FW_FEATURE_LPAR | - FW_FEATURE_CMO, + FW_FEATURE_CMO | FW_FEATURE_VPHN, FW_FEATURE_PSERIES_ALWAYS = 0, FW_FEATURE_ISERIES_POSSIBLE = FW_FEATURE_ISERIES | FW_FEATURE_LPAR, FW_FEATURE_ISERIES_ALWAYS = FW_FEATURE_ISERIES | FW_FEATURE_LPAR, diff --git a/arch/powerpc/include/asm/hvcall.h b/arch/powerpc/include/asm/hvcall.h index bf86b03d5af2..ec089acfa56b 100644 --- a/arch/powerpc/include/asm/hvcall.h +++ b/arch/powerpc/include/asm/hvcall.h @@ -232,6 +232,7 @@ #define H_GET_EM_PARMS 0x2B8 #define H_SET_MPP 0x2D0 #define H_GET_MPP 0x2D4 +#define H_HOME_NODE_ASSOCIATIVITY 0x2EC #define H_BEST_ENERGY 0x2F4 #define MAX_HCALL_OPCODE H_BEST_ENERGY diff --git a/arch/powerpc/platforms/pseries/firmware.c b/arch/powerpc/platforms/pseries/firmware.c index 0a14d8cd314f..0b0eff0cce35 100644 --- a/arch/powerpc/platforms/pseries/firmware.c +++ b/arch/powerpc/platforms/pseries/firmware.c @@ -55,6 +55,7 @@ firmware_features_table[FIRMWARE_MAX_FEATURES] = { {FW_FEATURE_XDABR, "hcall-xdabr"}, {FW_FEATURE_MULTITCE, "hcall-multi-tce"}, {FW_FEATURE_SPLPAR, "hcall-splpar"}, + {FW_FEATURE_VPHN, "hcall-vphn"}, }; /* Build up the firmware features bitmask using the contents of -- cgit v1.2.3 From 93fe56e99fb946fcd4244741bfc7af6638f1cac7 Mon Sep 17 00:00:00 2001 From: Michael Neuling Date: Wed, 17 Nov 2010 18:52:42 +0000 Subject: powerpc: Remove unneeded cpu_setup/restore from POWER7 cputable entry These are not needed so just remove them Signed-off-by: Michael Neuling Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/cputable.c | 2 -- arch/powerpc/kernel/misc.S | 5 ----- 2 files changed, 7 deletions(-) diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c index 96a908f1cd87..75062cb40e7b 100644 --- a/arch/powerpc/kernel/cputable.c +++ b/arch/powerpc/kernel/cputable.c @@ -457,8 +457,6 @@ static struct cpu_spec __initdata cpu_specs[] = { .dcache_bsize = 128, .num_pmcs = 6, .pmc_type = PPC_PMC_IBM, - .cpu_setup = __setup_cpu_power7, - .cpu_restore = __restore_cpu_power7, .oprofile_cpu_type = "ppc64/power7", .oprofile_type = PPC_OPROFILE_POWER4, .oprofile_mmcra_sihv = POWER6_MMCRA_SIHV, diff --git a/arch/powerpc/kernel/misc.S b/arch/powerpc/kernel/misc.S index 2d29752cbe16..b69463ec2010 100644 --- a/arch/powerpc/kernel/misc.S +++ b/arch/powerpc/kernel/misc.S @@ -122,8 +122,3 @@ _GLOBAL(longjmp) mtlr r0 mr r3,r4 blr - -_GLOBAL(__setup_cpu_power7) -_GLOBAL(__restore_cpu_power7) - /* place holder */ - blr -- cgit v1.2.3 From 1d32bb1827da3ebb413f6cb492990a42ab030559 Mon Sep 17 00:00:00 2001 From: Michael Neuling Date: Wed, 17 Nov 2010 18:52:43 +0000 Subject: powerpc: Remove POWER6 oprofile workarounds for POWER7 These are not needed on POWER7 so remove them. Signed-off-by: Michael Neuling Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/cputable.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c index 75062cb40e7b..65813ee98b7d 100644 --- a/arch/powerpc/kernel/cputable.c +++ b/arch/powerpc/kernel/cputable.c @@ -459,10 +459,6 @@ static struct cpu_spec __initdata cpu_specs[] = { .pmc_type = PPC_PMC_IBM, .oprofile_cpu_type = "ppc64/power7", .oprofile_type = PPC_OPROFILE_POWER4, - .oprofile_mmcra_sihv = POWER6_MMCRA_SIHV, - .oprofile_mmcra_sipr = POWER6_MMCRA_SIPR, - .oprofile_mmcra_clear = POWER6_MMCRA_THRM | - POWER6_MMCRA_OTHER, .platform = "power7", }, { /* Cell Broadband Engine */ -- cgit v1.2.3 From 6f08cb3be6345bc354e48131f7466766db4d355a Mon Sep 17 00:00:00 2001 From: Michael Neuling Date: Wed, 17 Nov 2010 18:52:44 +0000 Subject: powerpc: Add POWER7+ cputable entry This adds the POWER7+ cputable entry for the PVR 0x004a0000. Rest is the same as vanilla POWER7. Signed-off-by: Michael Neuling Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/cputable.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c index 65813ee98b7d..be5ab18b03b5 100644 --- a/arch/powerpc/kernel/cputable.c +++ b/arch/powerpc/kernel/cputable.c @@ -461,6 +461,22 @@ static struct cpu_spec __initdata cpu_specs[] = { .oprofile_type = PPC_OPROFILE_POWER4, .platform = "power7", }, + { /* Power7+ */ + .pvr_mask = 0xffff0000, + .pvr_value = 0x004A0000, + .cpu_name = "POWER7+ (raw)", + .cpu_features = CPU_FTRS_POWER7, + .cpu_user_features = COMMON_USER_POWER7, + .mmu_features = MMU_FTR_HPTE_TABLE | + MMU_FTR_TLBIE_206, + .icache_bsize = 128, + .dcache_bsize = 128, + .num_pmcs = 6, + .pmc_type = PPC_PMC_IBM, + .oprofile_cpu_type = "ppc64/power7", + .oprofile_type = PPC_OPROFILE_POWER4, + .platform = "power7+", + }, { /* Cell Broadband Engine */ .pvr_mask = 0xffff0000, .pvr_value = 0x00700000, -- cgit v1.2.3 From 0b97fee0ef9b0a0445520f90980410f905c6f9da Mon Sep 17 00:00:00 2001 From: Michael Neuling Date: Wed, 17 Nov 2010 18:52:45 +0000 Subject: powerpc/mm: Avoid avoidable void* pointer Change pgdir from a void to real type. Having this as a void is stupid and has already caused 1 bug. Signed-off-by: Michael Neuling Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/mm/hash_utils_64.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c index 5e9584405c45..a5991facddce 100644 --- a/arch/powerpc/mm/hash_utils_64.c +++ b/arch/powerpc/mm/hash_utils_64.c @@ -1070,7 +1070,7 @@ void hash_preload(struct mm_struct *mm, unsigned long ea, unsigned long access, unsigned long trap) { unsigned long vsid; - void *pgdir; + pgd_t *pgdir; pte_t *ptep; unsigned long flags; int rc, ssize, local = 0; -- cgit v1.2.3 From 46f5221049bb46b0188aad6b6dfab5dbc778be22 Mon Sep 17 00:00:00 2001 From: Stephen Rothwell Date: Thu, 18 Nov 2010 15:06:17 +0000 Subject: powerpc: Remove second definition of STACK_FRAME_OVERHEAD Since STACK_FRAME_OVERHEAD is defined in asm/ptrace.h and that is ASSEMBER safe, we can just include that instead of going via asm-offsets.h. Signed-off-by: Stephen Rothwell Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/asm-offsets.c | 1 - arch/powerpc/kernel/entry_32.S | 1 + arch/powerpc/kernel/exceptions-64s.S | 1 + arch/powerpc/kernel/fpu.S | 1 + arch/powerpc/kernel/head_40x.S | 1 + arch/powerpc/kernel/head_44x.S | 1 + arch/powerpc/kernel/head_64.S | 1 + arch/powerpc/kernel/head_8xx.S | 1 + arch/powerpc/kernel/head_fsl_booke.S | 1 + arch/powerpc/kernel/misc_32.S | 1 + arch/powerpc/kernel/misc_64.S | 1 + arch/powerpc/kernel/ppc_save_regs.S | 1 + arch/powerpc/kernel/vector.S | 1 + arch/powerpc/platforms/pseries/hvCall.S | 1 + 14 files changed, 13 insertions(+), 1 deletion(-) diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c index bd0df2e6aa8f..23e6a93145ab 100644 --- a/arch/powerpc/kernel/asm-offsets.c +++ b/arch/powerpc/kernel/asm-offsets.c @@ -209,7 +209,6 @@ int main(void) DEFINE(RTASENTRY, offsetof(struct rtas_t, entry)); /* Interrupt register frame */ - DEFINE(STACK_FRAME_OVERHEAD, STACK_FRAME_OVERHEAD); DEFINE(INT_FRAME_SIZE, STACK_INT_FRAME_SIZE); DEFINE(SWITCH_FRAME_SIZE, STACK_FRAME_OVERHEAD + sizeof(struct pt_regs)); #ifdef CONFIG_PPC64 diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S index ed4aeb96398b..c22dc1ec1c94 100644 --- a/arch/powerpc/kernel/entry_32.S +++ b/arch/powerpc/kernel/entry_32.S @@ -31,6 +31,7 @@ #include #include #include +#include #undef SHOW_SYSCALLS #undef SHOW_SYSCALLS_TASK diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S index 9f8b01d6466f..8a817995b4cd 100644 --- a/arch/powerpc/kernel/exceptions-64s.S +++ b/arch/powerpc/kernel/exceptions-64s.S @@ -13,6 +13,7 @@ */ #include +#include /* * We layout physical memory as follows: diff --git a/arch/powerpc/kernel/fpu.S b/arch/powerpc/kernel/fpu.S index e86c040ae585..de369558bf0a 100644 --- a/arch/powerpc/kernel/fpu.S +++ b/arch/powerpc/kernel/fpu.S @@ -23,6 +23,7 @@ #include #include #include +#include #ifdef CONFIG_VSX #define REST_32FPVSRS(n,c,base) \ diff --git a/arch/powerpc/kernel/head_40x.S b/arch/powerpc/kernel/head_40x.S index 8278e8bad5a0..9dd21a8c4d52 100644 --- a/arch/powerpc/kernel/head_40x.S +++ b/arch/powerpc/kernel/head_40x.S @@ -40,6 +40,7 @@ #include #include #include +#include /* As with the other PowerPC ports, it is expected that when code * execution begins here, the following registers contain valid, yet diff --git a/arch/powerpc/kernel/head_44x.S b/arch/powerpc/kernel/head_44x.S index 562305b40a8e..cbb3436b592d 100644 --- a/arch/powerpc/kernel/head_44x.S +++ b/arch/powerpc/kernel/head_44x.S @@ -37,6 +37,7 @@ #include #include #include +#include #include #include "head_booke.h" diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S index f0dd577e4a5b..ce41b97eb512 100644 --- a/arch/powerpc/kernel/head_64.S +++ b/arch/powerpc/kernel/head_64.S @@ -38,6 +38,7 @@ #include #include #include +#include /* The physical memory is layed out such that the secondary processor * spin code sits at 0x0000...0x00ff. On server, the vectors follow diff --git a/arch/powerpc/kernel/head_8xx.S b/arch/powerpc/kernel/head_8xx.S index 1f1a04b5c2a4..1cbf64e6b416 100644 --- a/arch/powerpc/kernel/head_8xx.S +++ b/arch/powerpc/kernel/head_8xx.S @@ -29,6 +29,7 @@ #include #include #include +#include /* Macro to make the code more readable. */ #ifdef CONFIG_8xx_CPU6 diff --git a/arch/powerpc/kernel/head_fsl_booke.S b/arch/powerpc/kernel/head_fsl_booke.S index 529b817f473b..3e02710d9562 100644 --- a/arch/powerpc/kernel/head_fsl_booke.S +++ b/arch/powerpc/kernel/head_fsl_booke.S @@ -41,6 +41,7 @@ #include #include #include +#include #include "head_booke.h" /* As with the other PowerPC ports, it is expected that when code diff --git a/arch/powerpc/kernel/misc_32.S b/arch/powerpc/kernel/misc_32.S index a7a570dcdd57..094bd9821ad4 100644 --- a/arch/powerpc/kernel/misc_32.S +++ b/arch/powerpc/kernel/misc_32.S @@ -30,6 +30,7 @@ #include #include #include +#include .text diff --git a/arch/powerpc/kernel/misc_64.S b/arch/powerpc/kernel/misc_64.S index e5144906a56d..206a321a71d3 100644 --- a/arch/powerpc/kernel/misc_64.S +++ b/arch/powerpc/kernel/misc_64.S @@ -25,6 +25,7 @@ #include #include #include +#include .text diff --git a/arch/powerpc/kernel/ppc_save_regs.S b/arch/powerpc/kernel/ppc_save_regs.S index 5113bd2285e1..e83ba3f078e4 100644 --- a/arch/powerpc/kernel/ppc_save_regs.S +++ b/arch/powerpc/kernel/ppc_save_regs.S @@ -11,6 +11,7 @@ #include #include #include +#include /* * Grab the register values as they are now. diff --git a/arch/powerpc/kernel/vector.S b/arch/powerpc/kernel/vector.S index fe460482fa68..9de6f396cf85 100644 --- a/arch/powerpc/kernel/vector.S +++ b/arch/powerpc/kernel/vector.S @@ -5,6 +5,7 @@ #include #include #include +#include /* * load_up_altivec(unused, unused, tsk) diff --git a/arch/powerpc/platforms/pseries/hvCall.S b/arch/powerpc/platforms/pseries/hvCall.S index 48d20573e4de..fd05fdee576a 100644 --- a/arch/powerpc/platforms/pseries/hvCall.S +++ b/arch/powerpc/platforms/pseries/hvCall.S @@ -11,6 +11,7 @@ #include #include #include +#include #define STK_PARM(i) (48 + ((i)-3)*8) -- cgit v1.2.3 From dc427170750f7be9ddedf16ca049b5cb827bd880 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 29 Nov 2010 07:42:59 +0100 Subject: ALSA: hda - Remove dead md2 quirk code Signed-off-by: Takashi Iwai --- Documentation/sound/alsa/HD-Audio-Models.txt | 1 - sound/pci/hda/patch_realtek.c | 42 ++-------------------------- 2 files changed, 2 insertions(+), 41 deletions(-) diff --git a/Documentation/sound/alsa/HD-Audio-Models.txt b/Documentation/sound/alsa/HD-Audio-Models.txt index 37c6aad5e590..16ae4300c747 100644 --- a/Documentation/sound/alsa/HD-Audio-Models.txt +++ b/Documentation/sound/alsa/HD-Audio-Models.txt @@ -149,7 +149,6 @@ ALC882/883/885/888/889 acer-aspire-7730g Acer Aspire 7730G acer-aspire-8930g Acer Aspire 8930G medion Medion Laptops - medion-md2 Medion MD2 targa-dig Targa/MSI targa-2ch-dig Targa/MSI with 2-channel targa-8ch-dig Targa/MSI with 8-channel (MSI GX620) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index f0af8cfab410..65a9edeee9ea 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -231,7 +231,6 @@ enum { ALC888_ACER_ASPIRE_8930G, ALC888_ACER_ASPIRE_7730G, ALC883_MEDION, - ALC883_MEDION_MD2, ALC883_MEDION_WIM2160, ALC883_LAPTOP_EAPD, ALC883_LENOVO_101E_2ch, @@ -8989,19 +8988,6 @@ static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = { { } /* end */ }; -static struct snd_kcontrol_new alc883_medion_md2_mixer[] = { - HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), - HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), - HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), - { } /* end */ -}; - static struct snd_kcontrol_new alc883_medion_wim2160_mixer[] = { HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), @@ -9443,18 +9429,8 @@ static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec, alc888_lenovo_ms7195_rca_automute(codec); } -static struct hda_verb alc883_medion_md2_verbs[] = { - {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, - - {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, - - {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, - { } /* end */ -}; - /* toggle speaker-output according to the hp-jack state */ -static void alc883_medion_md2_setup(struct hda_codec *codec) +static void alc883_lenovo_nb0763_setup(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; @@ -9739,7 +9715,6 @@ static const char *alc882_models[ALC882_MODEL_LAST] = { [ALC888_ACER_ASPIRE_8930G] = "acer-aspire-8930g", [ALC888_ACER_ASPIRE_7730G] = "acer-aspire-7730g", [ALC883_MEDION] = "medion", - [ALC883_MEDION_MD2] = "medion-md2", [ALC883_MEDION_WIM2160] = "medion-wim2160", [ALC883_LAPTOP_EAPD] = "laptop-eapd", [ALC883_LENOVO_101E_2ch] = "lenovo-101e", @@ -10387,19 +10362,6 @@ static struct alc_config_preset alc882_presets[] = { .channel_mode = alc883_sixstack_modes, .input_mux = &alc883_capture_source, }, - [ALC883_MEDION_MD2] = { - .mixers = { alc883_medion_md2_mixer}, - .init_verbs = { alc883_init_verbs, alc883_medion_md2_verbs}, - .num_dacs = ARRAY_SIZE(alc883_dac_nids), - .dac_nids = alc883_dac_nids, - .dig_out_nid = ALC883_DIGOUT_NID, - .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), - .channel_mode = alc883_3ST_2ch_modes, - .input_mux = &alc883_capture_source, - .unsol_event = alc_automute_amp_unsol_event, - .setup = alc883_medion_md2_setup, - .init_hook = alc_automute_amp, - }, [ALC883_MEDION_WIM2160] = { .mixers = { alc883_medion_wim2160_mixer }, .init_verbs = { alc883_init_verbs, alc883_medion_wim2160_verbs }, @@ -10476,7 +10438,7 @@ static struct alc_config_preset alc882_presets[] = { .need_dac_fix = 1, .input_mux = &alc883_lenovo_nb0763_capture_source, .unsol_event = alc_automute_amp_unsol_event, - .setup = alc883_medion_md2_setup, + .setup = alc883_lenovo_nb0763_setup, .init_hook = alc_automute_amp, }, [ALC888_LENOVO_MS7195_DIG] = { -- cgit v1.2.3 From 853dc30274878d14b7abef8313c801f5559b4c47 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Fri, 26 Nov 2010 14:51:56 +0800 Subject: ASoC: Fix resource leak in goni_wm8994.c Properly free allocated resources in goni_init() error path. Add missing snd_soc_unregister_dai() in goni_exit(). Signed-off-by: Axel Lin Acked-by: Jassi Brar Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/samsung/goni_wm8994.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/sound/soc/samsung/goni_wm8994.c b/sound/soc/samsung/goni_wm8994.c index dcfac546cb81..cc8528c0a49a 100644 --- a/sound/soc/samsung/goni_wm8994.c +++ b/sound/soc/samsung/goni_wm8994.c @@ -283,20 +283,25 @@ static int __init goni_init(void) /* register voice DAI here */ ret = snd_soc_register_dai(&goni_snd_device->dev, &voice_dai); - if (ret) + if (ret) { + platform_device_put(goni_snd_device); return ret; + } platform_set_drvdata(goni_snd_device, &goni); ret = platform_device_add(goni_snd_device); - if (ret) + if (ret) { + snd_soc_unregister_dai(&goni_snd_device->dev); platform_device_put(goni_snd_device); + } return ret; } static void __exit goni_exit(void) { + snd_soc_unregister_dai(&goni_snd_device->dev); platform_device_unregister(goni_snd_device); } -- cgit v1.2.3 From b6a11f497369fff39e8eb91c83b531d41a73986d Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Fri, 26 Nov 2010 14:52:47 +0800 Subject: ASoC: Fix resource leak in neo1973_gta02_init() error path Properly free allocated resources in neo1973_gta02_init() error path. Signed-off-by: Axel Lin Acked-by: Jassi Brar Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/samsung/neo1973_gta02_wm8753.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/sound/soc/samsung/neo1973_gta02_wm8753.c b/sound/soc/samsung/neo1973_gta02_wm8753.c index 8c65b6334f51..3eec610c10f9 100644 --- a/sound/soc/samsung/neo1973_gta02_wm8753.c +++ b/sound/soc/samsung/neo1973_gta02_wm8753.c @@ -439,24 +439,20 @@ static int __init neo1973_gta02_init(void) /* register bluetooth DAI here */ ret = snd_soc_register_dai(&neo1973_gta02_snd_device->dev, &bt_dai); - if (ret) { - platform_device_put(neo1973_gta02_snd_device); - return ret; - } + if (ret) + goto err_put_device; platform_set_drvdata(neo1973_gta02_snd_device, &neo1973_gta02); ret = platform_device_add(neo1973_gta02_snd_device); - if (ret) { - platform_device_put(neo1973_gta02_snd_device); - return ret; - } + if (ret) + goto err_unregister_dai; /* Initialise GPIOs used by amp */ ret = gpio_request(GTA02_GPIO_HP_IN, "GTA02_HP_IN"); if (ret) { pr_err("gta02_wm8753: Failed to register GPIO %d\n", GTA02_GPIO_HP_IN); - goto err_unregister_device; + goto err_del_device; } ret = gpio_direction_output(GTA02_GPIO_HP_IN, 1); @@ -483,8 +479,12 @@ err_free_gpio_amp_shut: gpio_free(GTA02_GPIO_AMP_SHUT); err_free_gpio_hp_in: gpio_free(GTA02_GPIO_HP_IN); -err_unregister_device: - platform_device_unregister(neo1973_gta02_snd_device); +err_del_device: + platform_device_del(neo1973_gta02_snd_device); +err_unregister_dai: + snd_soc_unregister_dai(&neo1973_gta02_snd_device->dev); +err_put_device: + platform_device_put(neo1973_gta02_snd_device); return ret; } module_init(neo1973_gta02_init); -- cgit v1.2.3 From 3790f205465f5c47a3629129af875c94f61f1fd3 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Fri, 26 Nov 2010 14:53:38 +0800 Subject: ASoC: Add missing gpio_free(S3C64XX_GPK(12)) in smartq_exit() Signed-off-by: Axel Lin Acked-by: Jassi Brar Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/samsung/smartq_wm8987.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/soc/samsung/smartq_wm8987.c b/sound/soc/samsung/smartq_wm8987.c index 0a46fa8730d1..61e2b5219d42 100644 --- a/sound/soc/samsung/smartq_wm8987.c +++ b/sound/soc/samsung/smartq_wm8987.c @@ -274,6 +274,7 @@ err_unregister_device: static void __exit smartq_exit(void) { + gpio_free(S3C64XX_GPK(12)); snd_soc_jack_free_gpios(&smartq_jack, ARRAY_SIZE(smartq_jack_gpios), smartq_jack_gpios); -- cgit v1.2.3 From d482337eaba627348ffb8b7c0752d65e16667cd9 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Fri, 26 Nov 2010 14:54:42 +0800 Subject: ASoC: Fix resource leak in smdk_spdif.c Properly free allocated resources in smdk_init() error path. Add missing platform_device_unregister() in smdk_exit(). Signed-off-by: Axel Lin Acked-by: Jassi Brar Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/samsung/smdk_spdif.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/sound/soc/samsung/smdk_spdif.c b/sound/soc/samsung/smdk_spdif.c index cd29da089c8f..ca779ad1613c 100644 --- a/sound/soc/samsung/smdk_spdif.c +++ b/sound/soc/samsung/smdk_spdif.c @@ -183,7 +183,7 @@ static int __init smdk_init(void) ret = platform_device_add(smdk_snd_spdif_dit_device); if (ret) - goto err2; + goto err1; smdk_snd_spdif_device = platform_device_alloc("soc-audio", -1); if (!smdk_snd_spdif_device) { @@ -195,17 +195,21 @@ static int __init smdk_init(void) ret = platform_device_add(smdk_snd_spdif_device); if (ret) - goto err1; + goto err3; /* Set audio clock heirachy manually */ ret = set_audio_clock_heirachy(smdk_snd_spdif_device); if (ret) - goto err1; + goto err4; return 0; -err1: +err4: + platform_device_del(smdk_snd_spdif_device); +err3: platform_device_put(smdk_snd_spdif_device); err2: + platform_device_del(smdk_snd_spdif_dit_device); +err1: platform_device_put(smdk_snd_spdif_dit_device); return ret; } @@ -213,6 +217,7 @@ err2: static void __exit smdk_exit(void) { platform_device_unregister(smdk_snd_spdif_device); + platform_device_unregister(smdk_snd_spdif_dit_device); } module_init(smdk_init); -- cgit v1.2.3 From 7a33d4ce8231f789548ce6e25f75894a6c8508a5 Mon Sep 17 00:00:00 2001 From: Dimitris Papastamos Date: Mon, 29 Nov 2010 10:24:54 +0000 Subject: ASoC: soc-cache: Add error checking in the *_cache_sync functions Ensure that we report any errors encountered during reads/writes in the cache syncing functions. Remove redundant newline in the source code. Signed-off-by: Dimitris Papastamos Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/soc-cache.c | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/sound/soc/soc-cache.c b/sound/soc/soc-cache.c index 6c0589e3fefb..e5b18889a493 100644 --- a/sound/soc/soc-cache.c +++ b/sound/soc/soc-cache.c @@ -792,7 +792,6 @@ static struct snd_soc_rbtree_node *snd_soc_rbtree_lookup( return NULL; } - static int snd_soc_rbtree_insert(struct rb_root *root, struct snd_soc_rbtree_node *rbnode) { @@ -826,14 +825,19 @@ static int snd_soc_rbtree_cache_sync(struct snd_soc_codec *codec) struct rb_node *node; struct snd_soc_rbtree_node *rbnode; unsigned int val; + int ret; rbtree_ctx = codec->reg_cache; for (node = rb_first(&rbtree_ctx->root); node; node = rb_next(node)) { rbnode = rb_entry(node, struct snd_soc_rbtree_node, node); if (rbnode->value == rbnode->defval) continue; - snd_soc_cache_read(codec, rbnode->reg, &val); - snd_soc_write(codec, rbnode->reg, val); + ret = snd_soc_cache_read(codec, rbnode->reg, &val); + if (ret) + return ret; + ret = snd_soc_write(codec, rbnode->reg, val); + if (ret) + return ret; dev_dbg(codec->dev, "Synced register %#x, value = %#x\n", rbnode->reg, val); } @@ -1110,11 +1114,16 @@ static int snd_soc_lzo_cache_sync(struct snd_soc_codec *codec) struct snd_soc_lzo_ctx **lzo_blocks; unsigned int val; int i; + int ret; lzo_blocks = codec->reg_cache; for_each_set_bit(i, lzo_blocks[0]->sync_bmp, lzo_blocks[0]->sync_bmp_nbits) { - snd_soc_cache_read(codec, i, &val); - snd_soc_write(codec, i, val); + ret = snd_soc_cache_read(codec, i, &val); + if (ret) + return ret; + ret = snd_soc_write(codec, i, val); + if (ret) + return ret; dev_dbg(codec->dev, "Synced register %#x, value = %#x\n", i, val); } @@ -1390,12 +1399,15 @@ err_tofree: static int snd_soc_flat_cache_sync(struct snd_soc_codec *codec) { int i; + int ret; struct snd_soc_codec_driver *codec_drv; unsigned int val; codec_drv = codec->driver; for (i = 0; i < codec_drv->reg_cache_size; ++i) { - snd_soc_cache_read(codec, i, &val); + ret = snd_soc_cache_read(codec, i, &val); + if (ret) + return ret; if (codec_drv->reg_cache_default) { switch (codec_drv->reg_word_size) { case 1: { @@ -1418,7 +1430,9 @@ static int snd_soc_flat_cache_sync(struct snd_soc_codec *codec) BUG(); } } - snd_soc_write(codec, i, val); + ret = snd_soc_write(codec, i, val); + if (ret) + return ret; dev_dbg(codec->dev, "Synced register %#x, value = %#x\n", i, val); } -- cgit v1.2.3 From df0701bb8660107e811bddba6e4933385f697a21 Mon Sep 17 00:00:00 2001 From: Dimitris Papastamos Date: Mon, 29 Nov 2010 10:54:28 +0000 Subject: ASoC: soc-cache: Ensure consistent cache naming Signed-off-by: Dimitris Papastamos Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- include/sound/soc.h | 2 +- sound/soc/soc-cache.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/sound/soc.h b/include/sound/soc.h index 3eb92ef6c83f..9e593cf1440b 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -256,7 +256,7 @@ enum snd_soc_control_type { }; enum snd_soc_compress_type { - SND_SOC_NO_COMPRESSION, + SND_SOC_FLAT_COMPRESSION, SND_SOC_LZO_COMPRESSION, SND_SOC_RBTREE_COMPRESSION }; diff --git a/sound/soc/soc-cache.c b/sound/soc/soc-cache.c index e5b18889a493..9b1ba33e6fe9 100644 --- a/sound/soc/soc-cache.c +++ b/sound/soc/soc-cache.c @@ -1520,7 +1520,7 @@ static int snd_soc_flat_cache_init(struct snd_soc_codec *codec) /* an array of all supported compression types */ static const struct snd_soc_cache_ops cache_types[] = { { - .id = SND_SOC_NO_COMPRESSION, + .id = SND_SOC_FLAT_COMPRESSION, .init = snd_soc_flat_cache_init, .exit = snd_soc_flat_cache_exit, .read = snd_soc_flat_cache_read, -- cgit v1.2.3 From 7451708f39db19a8303bb7fb95f00aca9f673cb5 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Mon, 29 Nov 2010 22:56:03 +0800 Subject: crypto: af_alg - Add dependency on NET Add missing dependency on NET since we require sockets for our interface. Should really be a select but kconfig doesn't like that: net/Kconfig:6:error: found recursive dependency: NET -> NETWORK_FILESYSTEMS -> AFS_FS -> AF_RXRPC -> CRYPTO -> CRYPTO_USER_API_HASH -> CRYPTO_USER_API -> NET Reported-by: Zimny Lech Signed-off-by: Herbert Xu --- crypto/Kconfig | 2 ++ 1 file changed, 2 insertions(+) diff --git a/crypto/Kconfig b/crypto/Kconfig index 467491df3e3a..96b0e5542121 100644 --- a/crypto/Kconfig +++ b/crypto/Kconfig @@ -848,6 +848,7 @@ config CRYPTO_USER_API config CRYPTO_USER_API_HASH tristate "User-space interface for hash algorithms" + depends on NET select CRYPTO_HASH select CRYPTO_USER_API help @@ -856,6 +857,7 @@ config CRYPTO_USER_API_HASH config CRYPTO_USER_API_SKCIPHER tristate "User-space interface for symmetric key cipher algorithms" + depends on NET select CRYPTO_BLKCIPHER select CRYPTO_USER_API help -- cgit v1.2.3 From d164f6d4f9108126f69ba2963cf6fb7ef4ba9232 Mon Sep 17 00:00:00 2001 From: Victor Gallardo Date: Fri, 8 Oct 2010 10:25:27 +0000 Subject: powerpc/4xx: Add suspend and idle support Add suspend/resume support for 4xx compatible CPUs. See /sys/power/state for available power states configured in. Add two different idle states (idle-wait and idle-doze) controlled via sysfs. Default is idle-wait. cat /sys/devices/system/cpu/cpu0/idle [wait] doze To save additional power, use idle-doze. echo doze > /sys/devices/system/cpu/cpu0/idle cat /sys/devices/system/cpu/cpu0/idle wait [doze] Signed-off-by: Victor Gallardo Signed-off-by: Josh Boyer --- Documentation/powerpc/dts-bindings/4xx/cpm.txt | 52 ++++ arch/powerpc/Kconfig | 13 +- arch/powerpc/platforms/44x/Makefile | 5 +- arch/powerpc/sysdev/Makefile | 1 + arch/powerpc/sysdev/ppc4xx_cpm.c | 346 +++++++++++++++++++++++++ 5 files changed, 413 insertions(+), 4 deletions(-) create mode 100644 Documentation/powerpc/dts-bindings/4xx/cpm.txt create mode 100644 arch/powerpc/sysdev/ppc4xx_cpm.c diff --git a/Documentation/powerpc/dts-bindings/4xx/cpm.txt b/Documentation/powerpc/dts-bindings/4xx/cpm.txt new file mode 100644 index 000000000000..ee459806d35e --- /dev/null +++ b/Documentation/powerpc/dts-bindings/4xx/cpm.txt @@ -0,0 +1,52 @@ +PPC4xx Clock Power Management (CPM) node + +Required properties: + - compatible : compatible list, currently only "ibm,cpm" + - dcr-access-method : "native" + - dcr-reg : < DCR register range > + +Optional properties: + - er-offset : All 4xx SoCs with a CPM controller have + one of two different order for the CPM + registers. Some have the CPM registers + in the following order (ER,FR,SR). The + others have them in the following order + (SR,ER,FR). For the second case set + er-offset = <1>. + - unused-units : specifier consist of one cell. For each + bit in the cell, the corresponding bit + in CPM will be set to turn off unused + devices. + - idle-doze : specifier consist of one cell. For each + bit in the cell, the corresponding bit + in CPM will be set to turn off unused + devices. This is usually just CPM[CPU]. + - standby : specifier consist of one cell. For each + bit in the cell, the corresponding bit + in CPM will be set on standby and + restored on resume. + - suspend : specifier consist of one cell. For each + bit in the cell, the corresponding bit + in CPM will be set on suspend (mem) and + restored on resume. Note, for standby + and suspend the corresponding bits can + be different or the same. Usually for + standby only class 2 and 3 units are set. + However, the interface does not care. + If they are the same, the additional + power saving will be seeing if support + is available to put the DDR in self + refresh mode and any additional power + saving techniques for the specific SoC. + +Example: + CPM0: cpm { + compatible = "ibm,cpm"; + dcr-access-method = "native"; + dcr-reg = <0x160 0x003>; + er-offset = <0>; + unused-units = <0x00000100>; + idle-doze = <0x02000000>; + standby = <0xfeff0000>; + suspend = <0xfeff791d>; +}; diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 06d742c3fbcf..e16b4988f825 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -212,7 +212,7 @@ config ARCH_HIBERNATION_POSSIBLE config ARCH_SUSPEND_POSSIBLE def_bool y depends on ADB_PMU || PPC_EFIKA || PPC_LITE5200 || PPC_83xx || \ - PPC_85xx || PPC_86xx || PPC_PSERIES + PPC_85xx || PPC_86xx || PPC_PSERIES || 44x || 40x config PPC_DCR_NATIVE bool @@ -598,13 +598,11 @@ config EXTRA_TARGETS If unsure, leave blank -if !44x || BROKEN config ARCH_WANTS_FREEZER_CONTROL def_bool y depends on ADB_PMU source kernel/power/Kconfig -endif config SECCOMP bool "Enable seccomp to safely compute untrusted bytecode" @@ -685,6 +683,15 @@ config FSL_PMC Freescale MPC85xx/MPC86xx power management controller support (suspend/resume). For MPC83xx see platforms/83xx/suspend.c +config PPC4xx_CPM + bool + default y + depends on SUSPEND && (44x || 40x) + help + PPC4xx Clock Power Management (CPM) support (suspend/resume). + It also enables support for two different idle states (idle-wait + and idle-doze). + config 4xx_SOC bool diff --git a/arch/powerpc/platforms/44x/Makefile b/arch/powerpc/platforms/44x/Makefile index 82ff326e0795..c04d16df8488 100644 --- a/arch/powerpc/platforms/44x/Makefile +++ b/arch/powerpc/platforms/44x/Makefile @@ -1,4 +1,7 @@ -obj-$(CONFIG_44x) := misc_44x.o idle.o +obj-$(CONFIG_44x) += misc_44x.o +ifneq ($(CONFIG_PPC4xx_CPM),y) +obj-$(CONFIG_44x) += idle.o +endif obj-$(CONFIG_PPC44x_SIMPLE) += ppc44x_simple.o obj-$(CONFIG_EBONY) += ebony.o obj-$(CONFIG_SAM440EP) += sam440ep.o diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile index 0bef9dacb64e..9c2973479142 100644 --- a/arch/powerpc/sysdev/Makefile +++ b/arch/powerpc/sysdev/Makefile @@ -41,6 +41,7 @@ obj-$(CONFIG_OF_RTC) += of_rtc.o ifeq ($(CONFIG_PCI),y) obj-$(CONFIG_4xx) += ppc4xx_pci.o endif +obj-$(CONFIG_PPC4xx_CPM) += ppc4xx_cpm.o obj-$(CONFIG_PPC4xx_GPIO) += ppc4xx_gpio.o obj-$(CONFIG_CPM) += cpm_common.o diff --git a/arch/powerpc/sysdev/ppc4xx_cpm.c b/arch/powerpc/sysdev/ppc4xx_cpm.c new file mode 100644 index 000000000000..73b86cc5ea74 --- /dev/null +++ b/arch/powerpc/sysdev/ppc4xx_cpm.c @@ -0,0 +1,346 @@ +/* + * PowerPC 4xx Clock and Power Management + * + * Copyright (C) 2010, Applied Micro Circuits Corporation + * Victor Gallardo (vgallardo@apm.com) + * + * Based on arch/powerpc/platforms/44x/idle.c: + * Jerone Young + * Copyright 2008 IBM Corp. + * + * Based on arch/powerpc/sysdev/fsl_pmc.c: + * Anton Vorontsov + * Copyright 2009 MontaVista Software, Inc. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * 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. + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define CPM_ER 0 +#define CPM_FR 1 +#define CPM_SR 2 + +#define CPM_IDLE_WAIT 0 +#define CPM_IDLE_DOZE 1 + +struct cpm { + dcr_host_t dcr_host; + unsigned int dcr_offset[3]; + unsigned int powersave_off; + unsigned int unused; + unsigned int idle_doze; + unsigned int standby; + unsigned int suspend; +}; + +static struct cpm cpm; + +struct cpm_idle_mode { + unsigned int enabled; + const char *name; +}; + +static struct cpm_idle_mode idle_mode[] = { + [CPM_IDLE_WAIT] = { 1, "wait" }, /* default */ + [CPM_IDLE_DOZE] = { 0, "doze" }, +}; + +static unsigned int cpm_set(unsigned int cpm_reg, unsigned int mask) +{ + unsigned int value; + + /* CPM controller supports 3 different types of sleep interface + * known as class 1, 2 and 3. For class 1 units, they are + * unconditionally put to sleep when the corresponding CPM bit is + * set. For class 2 and 3 units this is not case; if they can be + * put to to sleep, they will. Here we do not verify, we just + * set them and expect them to eventually go off when they can. + */ + value = dcr_read(cpm.dcr_host, cpm.dcr_offset[cpm_reg]); + dcr_write(cpm.dcr_host, cpm.dcr_offset[cpm_reg], value | mask); + + /* return old state, to restore later if needed */ + return value; +} + +static void cpm_idle_wait(void) +{ + unsigned long msr_save; + + /* save off initial state */ + msr_save = mfmsr(); + /* sync required when CPM0_ER[CPU] is set */ + mb(); + /* set wait state MSR */ + mtmsr(msr_save|MSR_WE|MSR_EE|MSR_CE|MSR_DE); + isync(); + /* return to initial state */ + mtmsr(msr_save); + isync(); +} + +static void cpm_idle_sleep(unsigned int mask) +{ + unsigned int er_save; + + /* update CPM_ER state */ + er_save = cpm_set(CPM_ER, mask); + + /* go to wait state so that CPM0_ER[CPU] can take effect */ + cpm_idle_wait(); + + /* restore CPM_ER state */ + dcr_write(cpm.dcr_host, cpm.dcr_offset[CPM_ER], er_save); +} + +static void cpm_idle_doze(void) +{ + cpm_idle_sleep(cpm.idle_doze); +} + +static void cpm_idle_config(int mode) +{ + int i; + + if (idle_mode[mode].enabled) + return; + + for (i = 0; i < ARRAY_SIZE(idle_mode); i++) + idle_mode[i].enabled = 0; + + idle_mode[mode].enabled = 1; +} + +static ssize_t cpm_idle_show(struct kobject *kobj, + struct kobj_attribute *attr, char *buf) +{ + char *s = buf; + int i; + + for (i = 0; i < ARRAY_SIZE(idle_mode); i++) { + if (idle_mode[i].enabled) + s += sprintf(s, "[%s] ", idle_mode[i].name); + else + s += sprintf(s, "%s ", idle_mode[i].name); + } + + *(s-1) = '\n'; /* convert the last space to a newline */ + + return s - buf; +} + +static ssize_t cpm_idle_store(struct kobject *kobj, + struct kobj_attribute *attr, + const char *buf, size_t n) +{ + int i; + char *p; + int len; + + p = memchr(buf, '\n', n); + len = p ? p - buf : n; + + for (i = 0; i < ARRAY_SIZE(idle_mode); i++) { + if (strncmp(buf, idle_mode[i].name, len) == 0) { + cpm_idle_config(i); + return n; + } + } + + return -EINVAL; +} + +static struct kobj_attribute cpm_idle_attr = + __ATTR(idle, 0644, cpm_idle_show, cpm_idle_store); + +static void cpm_idle_config_sysfs(void) +{ + struct sys_device *sys_dev; + unsigned long ret; + + sys_dev = get_cpu_sysdev(0); + + ret = sysfs_create_file(&sys_dev->kobj, + &cpm_idle_attr.attr); + if (ret) + printk(KERN_WARNING + "cpm: failed to create idle sysfs entry\n"); +} + +static void cpm_idle(void) +{ + if (idle_mode[CPM_IDLE_DOZE].enabled) + cpm_idle_doze(); + else + cpm_idle_wait(); +} + +static int cpm_suspend_valid(suspend_state_t state) +{ + switch (state) { + case PM_SUSPEND_STANDBY: + return !!cpm.standby; + case PM_SUSPEND_MEM: + return !!cpm.suspend; + default: + return 0; + } +} + +static void cpm_suspend_standby(unsigned int mask) +{ + unsigned long tcr_save; + + /* disable decrement interrupt */ + tcr_save = mfspr(SPRN_TCR); + mtspr(SPRN_TCR, tcr_save & ~TCR_DIE); + + /* go to sleep state */ + cpm_idle_sleep(mask); + + /* restore decrement interrupt */ + mtspr(SPRN_TCR, tcr_save); +} + +static int cpm_suspend_enter(suspend_state_t state) +{ + switch (state) { + case PM_SUSPEND_STANDBY: + cpm_suspend_standby(cpm.standby); + break; + case PM_SUSPEND_MEM: + cpm_suspend_standby(cpm.suspend); + break; + } + + return 0; +} + +static struct platform_suspend_ops cpm_suspend_ops = { + .valid = cpm_suspend_valid, + .enter = cpm_suspend_enter, +}; + +static int cpm_get_uint_property(struct device_node *np, + const char *name) +{ + int len; + const unsigned int *prop = of_get_property(np, name, &len); + + if (prop == NULL || len < sizeof(u32)) + return 0; + + return *prop; +} + +static int __init cpm_init(void) +{ + struct device_node *np; + int dcr_base, dcr_len; + int ret = 0; + + if (!cpm.powersave_off) { + cpm_idle_config(CPM_IDLE_WAIT); + ppc_md.power_save = &cpm_idle; + } + + np = of_find_compatible_node(NULL, NULL, "ibm,cpm"); + if (!np) { + ret = -EINVAL; + goto out; + } + + dcr_base = dcr_resource_start(np, 0); + dcr_len = dcr_resource_len(np, 0); + + if (dcr_base == 0 || dcr_len == 0) { + printk(KERN_ERR "cpm: could not parse dcr property for %s\n", + np->full_name); + ret = -EINVAL; + goto out; + } + + cpm.dcr_host = dcr_map(np, dcr_base, dcr_len); + + if (!DCR_MAP_OK(cpm.dcr_host)) { + printk(KERN_ERR "cpm: failed to map dcr property for %s\n", + np->full_name); + ret = -EINVAL; + goto out; + } + + /* All 4xx SoCs with a CPM controller have one of two + * different order for the CPM registers. Some have the + * CPM registers in the following order (ER,FR,SR). The + * others have them in the following order (SR,ER,FR). + */ + + if (cpm_get_uint_property(np, "er-offset") == 0) { + cpm.dcr_offset[CPM_ER] = 0; + cpm.dcr_offset[CPM_FR] = 1; + cpm.dcr_offset[CPM_SR] = 2; + } else { + cpm.dcr_offset[CPM_ER] = 1; + cpm.dcr_offset[CPM_FR] = 2; + cpm.dcr_offset[CPM_SR] = 0; + } + + /* Now let's see what IPs to turn off for the following modes */ + + cpm.unused = cpm_get_uint_property(np, "unused-units"); + cpm.idle_doze = cpm_get_uint_property(np, "idle-doze"); + cpm.standby = cpm_get_uint_property(np, "standby"); + cpm.suspend = cpm_get_uint_property(np, "suspend"); + + /* If some IPs are unused let's turn them off now */ + + if (cpm.unused) { + cpm_set(CPM_ER, cpm.unused); + cpm_set(CPM_FR, cpm.unused); + } + + /* Now let's export interfaces */ + + if (!cpm.powersave_off && cpm.idle_doze) + cpm_idle_config_sysfs(); + + if (cpm.standby || cpm.suspend) + suspend_set_ops(&cpm_suspend_ops); +out: + if (np) + of_node_put(np); + return ret; +} + +late_initcall(cpm_init); + +static int __init cpm_powersave_off(char *arg) +{ + cpm.powersave_off = 1; + return 0; +} +__setup("powersave=off", cpm_powersave_off); -- cgit v1.2.3 From 05ed60874e7fc958707183b71ea47260c1dab358 Mon Sep 17 00:00:00 2001 From: Victor Gallardo Date: Fri, 8 Oct 2010 10:26:13 +0000 Subject: powerpc/4xx: Add Kilauea suspend and idle support - Add Clock Power Management (CPM) node to dts tree - Add idle-doze entry in CPM node - Add standby entry in CPM node - Add PM and SUSPEND support by default in defconfig - Add NO_HZ and CONFIG_HIGH_RES_TIMERS support by default in defconfig Signed-off-by: Victor Gallardo Signed-off-by: Josh Boyer --- arch/powerpc/boot/dts/kilauea.dts | 9 +++++++++ arch/powerpc/configs/40x/kilauea_defconfig | 5 +++++ 2 files changed, 14 insertions(+) diff --git a/arch/powerpc/boot/dts/kilauea.dts b/arch/powerpc/boot/dts/kilauea.dts index 083e68eeaca4..89edb16649c3 100644 --- a/arch/powerpc/boot/dts/kilauea.dts +++ b/arch/powerpc/boot/dts/kilauea.dts @@ -82,6 +82,15 @@ interrupt-parent = <&UIC0>; }; + CPM0: cpm { + compatible = "ibm,cpm"; + dcr-access-method = "native"; + dcr-reg = <0x0b0 0x003>; + unused-units = <0x00000000>; + idle-doze = <0x02000000>; + standby = <0xe3e74800>; + }; + plb { compatible = "ibm,plb-405ex", "ibm,plb4"; #address-cells = <1>; diff --git a/arch/powerpc/configs/40x/kilauea_defconfig b/arch/powerpc/configs/40x/kilauea_defconfig index 4e19ee7ce4ee..34b8c1a1e752 100644 --- a/arch/powerpc/configs/40x/kilauea_defconfig +++ b/arch/powerpc/configs/40x/kilauea_defconfig @@ -12,6 +12,8 @@ CONFIG_MODULES=y CONFIG_MODULE_UNLOAD=y # CONFIG_BLK_DEV_BSG is not set CONFIG_KILAUEA=y +CONFIG_NO_HZ=y +CONFIG_HIGH_RES_TIMERS=y # CONFIG_WALNUT is not set CONFIG_SPARSE_IRQ=y CONFIG_PCI=y @@ -42,6 +44,9 @@ CONFIG_MTD_PHYSMAP_OF=y CONFIG_MTD_NAND=y CONFIG_MTD_NAND_NDFC=y CONFIG_PROC_DEVICETREE=y +CONFIG_PM=y +CONFIG_SUSPEND=y +CONFIG_PPC4xx_CPM=y CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_SIZE=35000 # CONFIG_MISC_DEVICES is not set -- cgit v1.2.3 From ee2ffd8bbb2170f9b52fc8ff4aebe9702e0de651 Mon Sep 17 00:00:00 2001 From: Victor Gallardo Date: Fri, 8 Oct 2010 10:25:44 +0000 Subject: powerpc/4xx: Add Canyonlands suspend and idle support - Add Clock Power Management (CPM) node to dts tree - Add idle-doze entry in CPM node - Add standby entry in CPM node - Add PM and SUSPEND support by default in defconfig - Remove UART2 and UART3 as they are unused, this will allow CPM to put unused-units (UART2 and UART3) to sleep. Signed-off-by: Victor Gallardo Signed-off-by: Josh Boyer --- arch/powerpc/boot/dts/canyonlands.dts | 31 ++++++++------------------ arch/powerpc/configs/44x/canyonlands_defconfig | 3 +++ 2 files changed, 12 insertions(+), 22 deletions(-) diff --git a/arch/powerpc/boot/dts/canyonlands.dts b/arch/powerpc/boot/dts/canyonlands.dts index a30370396250..5b27a4b74b79 100644 --- a/arch/powerpc/boot/dts/canyonlands.dts +++ b/arch/powerpc/boot/dts/canyonlands.dts @@ -105,6 +105,15 @@ dcr-reg = <0x00c 0x002>; }; + CPM0: cpm { + compatible = "ibm,cpm"; + dcr-access-method = "native"; + dcr-reg = <0x160 0x003>; + unused-units = <0x00000100>; + idle-doze = <0x02000000>; + standby = <0xfeff791d>; + }; + L2C0: l2c { compatible = "ibm,l2-cache-460ex", "ibm,l2-cache"; dcr-reg = <0x020 0x008 /* Internal SRAM DCR's */ @@ -270,28 +279,6 @@ interrupts = <0x1 0x4>; }; - UART2: serial@ef600500 { - device_type = "serial"; - compatible = "ns16550"; - reg = <0xef600500 0x00000008>; - virtual-reg = <0xef600500>; - clock-frequency = <0>; /* Filled in by U-Boot */ - current-speed = <0>; /* Filled in by U-Boot */ - interrupt-parent = <&UIC1>; - interrupts = <28 0x4>; - }; - - UART3: serial@ef600600 { - device_type = "serial"; - compatible = "ns16550"; - reg = <0xef600600 0x00000008>; - virtual-reg = <0xef600600>; - clock-frequency = <0>; /* Filled in by U-Boot */ - current-speed = <0>; /* Filled in by U-Boot */ - interrupt-parent = <&UIC1>; - interrupts = <29 0x4>; - }; - IIC0: i2c@ef600700 { compatible = "ibm,iic-460ex", "ibm,iic"; reg = <0xef600700 0x00000014>; diff --git a/arch/powerpc/configs/44x/canyonlands_defconfig b/arch/powerpc/configs/44x/canyonlands_defconfig index 45c64d818b2a..17e4dd98eed7 100644 --- a/arch/powerpc/configs/44x/canyonlands_defconfig +++ b/arch/powerpc/configs/44x/canyonlands_defconfig @@ -42,6 +42,9 @@ CONFIG_MTD_PHYSMAP_OF=y CONFIG_MTD_NAND=y CONFIG_MTD_NAND_NDFC=y CONFIG_PROC_DEVICETREE=y +CONFIG_PM=y +CONFIG_SUSPEND=y +CONFIG_PPC4xx_CPM=y CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_SIZE=35000 # CONFIG_MISC_DEVICES is not set -- cgit v1.2.3 From 95bd48578bbe66fa5d16029c59dfbe95749a5f0b Mon Sep 17 00:00:00 2001 From: Huang Weiyi Date: Sat, 20 Nov 2010 20:06:18 +0800 Subject: staging: brcm80211: remove duplicated #include Remove duplicated #include('s) in drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c Signed-off-by: Huang Weiyi Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c index b907376d054d..0d7aa4adbb77 100644 --- a/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c +++ b/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c @@ -29,10 +29,6 @@ #include #include -#include -#include -#include - #include #include #include -- cgit v1.2.3 From b5a49481754a5cbfdc47bd701208f77c5c9010c6 Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Mon, 22 Nov 2010 11:15:23 +0100 Subject: staging: iio: dac: Enable driver support for AD5444 and AD5446 DA converters Enable support for AD5444 and AD5446: 12-/14-Bit High Bandwidth Multiplying DACs with Serial Interface. staging: iio: dac: Add support for AD5541A, AD5512A digital to analog convertors staging: iio: dac: Fix according to review feedback Review feedback by Jonathan Cameron: Remove spurious new line. Document struct members. Remove redundant variable initialization. Signed-off-by: Michael Hennerich Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/dac/Kconfig | 10 ++ drivers/staging/iio/dac/Makefile | 1 + drivers/staging/iio/dac/ad5446.c | 249 +++++++++++++++++++++++++++++++++++++++ drivers/staging/iio/dac/ad5446.h | 46 ++++++++ 4 files changed, 306 insertions(+) create mode 100644 drivers/staging/iio/dac/ad5446.c create mode 100644 drivers/staging/iio/dac/ad5446.h diff --git a/drivers/staging/iio/dac/Kconfig b/drivers/staging/iio/dac/Kconfig index 583df785fd25..9c497ccd3dce 100644 --- a/drivers/staging/iio/dac/Kconfig +++ b/drivers/staging/iio/dac/Kconfig @@ -9,3 +9,13 @@ config AD5624R_SPI help Say yes here to build support for Analog Devices AD5624R, AD5644R and AD5664R convertors (DAC). This driver uses the common SPI interface. + +config AD5446 + tristate "Analog Devices AD5444, AD5446 and AD5541A, AD5512A DAC SPI driver" + depends on SPI + help + Say yes here to build support for Analog Devices AD5444, AD5446 + and AD5541A, AD5512A DACs. + + To compile this driver as a module, choose M here: the + module will be called ad5446. diff --git a/drivers/staging/iio/dac/Makefile b/drivers/staging/iio/dac/Makefile index 7ddf05d5f1b4..7cf331b4e001 100644 --- a/drivers/staging/iio/dac/Makefile +++ b/drivers/staging/iio/dac/Makefile @@ -3,3 +3,4 @@ # obj-$(CONFIG_AD5624R_SPI) += ad5624r_spi.o +obj-$(CONFIG_AD5446) += ad5446.o diff --git a/drivers/staging/iio/dac/ad5446.c b/drivers/staging/iio/dac/ad5446.c new file mode 100644 index 000000000000..ac3165b0aeff --- /dev/null +++ b/drivers/staging/iio/dac/ad5446.c @@ -0,0 +1,249 @@ +/* + * AD5446 SPI DAC driver + * + * Copyright 2010 Analog Devices Inc. + * + * Licensed under the GPL-2 or later. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../iio.h" +#include "../sysfs.h" +#include "dac.h" + +#include "ad5446.h" + +static ssize_t ad5446_write(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad5446_state *st = dev_info->dev_data; + int ret; + long val; + + ret = strict_strtol(buf, 10, &val); + if (ret) + goto error_ret; + + if (val > RES_MASK(st->chip_info->bits)) { + ret = -EINVAL; + goto error_ret; + } + + mutex_lock(&dev_info->mlock); + switch (spi_get_device_id(st->spi)->driver_data) { + case ID_AD5444: + case ID_AD5446: + st->data = cpu_to_be16(AD5446_LOAD | + (val << st->chip_info->left_shift)); + break; + case ID_AD5542A: + case ID_AD5512A: + st->data = cpu_to_be16(val << st->chip_info->left_shift); + break; + } + + ret = spi_sync(st->spi, &st->msg); + mutex_unlock(&dev_info->mlock); + +error_ret: + return ret ? ret : len; +} + +static IIO_DEV_ATTR_OUT_RAW(0, ad5446_write, 0); + +static ssize_t ad5446_show_scale(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad5446_state *st = iio_dev_get_devdata(dev_info); + /* Corresponds to Vref / 2^(bits) */ + unsigned int scale_uv = (st->vref_mv * 1000) >> st->chip_info->bits; + + return sprintf(buf, "%d.%d\n", scale_uv / 1000, scale_uv % 1000); +} +static IIO_DEVICE_ATTR(out_scale, S_IRUGO, ad5446_show_scale, NULL, 0); + +static ssize_t ad5446_show_name(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad5446_state *st = iio_dev_get_devdata(dev_info); + + return sprintf(buf, "%s\n", spi_get_device_id(st->spi)->name); +} +static IIO_DEVICE_ATTR(name, S_IRUGO, ad5446_show_name, NULL, 0); + +static struct attribute *ad5446_attributes[] = { + &iio_dev_attr_out0_raw.dev_attr.attr, + &iio_dev_attr_out_scale.dev_attr.attr, + &iio_dev_attr_name.dev_attr.attr, + NULL, +}; + +static const struct attribute_group ad5446_attribute_group = { + .attrs = ad5446_attributes, +}; + +static const struct ad5446_chip_info ad5446_chip_info_tbl[] = { + [ID_AD5444] = { + .bits = 12, + .storagebits = 16, + .left_shift = 2, + .sign = 'u', /* IIO_SCAN_EL_TYPE_UNSIGNED */ + }, + [ID_AD5446] = { + .bits = 14, + .storagebits = 16, + .left_shift = 0, + .sign = 'u', /* IIO_SCAN_EL_TYPE_UNSIGNED */ + }, + [ID_AD5542A] = { + .bits = 16, + .storagebits = 16, + .left_shift = 0, + .sign = 'u', /* IIO_SCAN_EL_TYPE_UNSIGNED */ + }, + [ID_AD5512A] = { + .bits = 12, + .storagebits = 16, + .left_shift = 4, + .sign = 'u', /* IIO_SCAN_EL_TYPE_UNSIGNED */ + }, +}; + +static int __devinit ad5446_probe(struct spi_device *spi) +{ + struct ad5446_state *st; + int ret, voltage_uv = 0; + + st = kzalloc(sizeof(*st), GFP_KERNEL); + if (st == NULL) { + ret = -ENOMEM; + goto error_ret; + } + + st->reg = regulator_get(&spi->dev, "vcc"); + if (!IS_ERR(st->reg)) { + ret = regulator_enable(st->reg); + if (ret) + goto error_put_reg; + + voltage_uv = regulator_get_voltage(st->reg); + } + + st->chip_info = + &ad5446_chip_info_tbl[spi_get_device_id(spi)->driver_data]; + + spi_set_drvdata(spi, st); + + st->spi = spi; + + st->indio_dev = iio_allocate_device(); + if (st->indio_dev == NULL) { + ret = -ENOMEM; + goto error_disable_reg; + } + + /* Estabilish that the iio_dev is a child of the spi device */ + st->indio_dev->dev.parent = &spi->dev; + st->indio_dev->attrs = &ad5446_attribute_group; + st->indio_dev->dev_data = (void *)(st); + st->indio_dev->driver_module = THIS_MODULE; + st->indio_dev->modes = INDIO_DIRECT_MODE; + + /* Setup default message */ + + st->xfer.tx_buf = &st->data, + st->xfer.len = 2, + + spi_message_init(&st->msg); + spi_message_add_tail(&st->xfer, &st->msg); + + if (voltage_uv) + st->vref_mv = voltage_uv / 1000; + else + dev_warn(&spi->dev, "reference voltage unspecified\n"); + + ret = iio_device_register(st->indio_dev); + if (ret) + goto error_free_device; + + return 0; + +error_free_device: + iio_free_device(st->indio_dev); +error_disable_reg: + if (!IS_ERR(st->reg)) + regulator_disable(st->reg); +error_put_reg: + if (!IS_ERR(st->reg)) + regulator_put(st->reg); + kfree(st); +error_ret: + return ret; +} + +static int ad5446_remove(struct spi_device *spi) +{ + struct ad5446_state *st = spi_get_drvdata(spi); + struct iio_dev *indio_dev = st->indio_dev; + + iio_device_unregister(indio_dev); + if (!IS_ERR(st->reg)) { + regulator_disable(st->reg); + regulator_put(st->reg); + } + kfree(st); + return 0; +} + +static const struct spi_device_id ad5446_id[] = { + {"ad5444", ID_AD5444}, + {"ad5446", ID_AD5446}, + {"ad5542a", ID_AD5542A}, + {"ad5512a", ID_AD5512A}, + {} +}; + +static struct spi_driver ad5446_driver = { + .driver = { + .name = "ad5446", + .bus = &spi_bus_type, + .owner = THIS_MODULE, + }, + .probe = ad5446_probe, + .remove = __devexit_p(ad5446_remove), + .id_table = ad5446_id, +}; + +static int __init ad5446_init(void) +{ + return spi_register_driver(&ad5446_driver); +} +module_init(ad5446_init); + +static void __exit ad5446_exit(void) +{ + spi_unregister_driver(&ad5446_driver); +} +module_exit(ad5446_exit); + +MODULE_AUTHOR("Michael Hennerich "); +MODULE_DESCRIPTION("Analog Devices AD5444/AD5446 DAC"); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("spi:ad5446"); diff --git a/drivers/staging/iio/dac/ad5446.h b/drivers/staging/iio/dac/ad5446.h new file mode 100644 index 000000000000..24a9cda6b997 --- /dev/null +++ b/drivers/staging/iio/dac/ad5446.h @@ -0,0 +1,46 @@ +/* + * AD5446 SPI DAC driver + * + * Copyright 2010 Analog Devices Inc. + * + * Licensed under the GPL-2 or later. + */ +#ifndef IIO_ADC_AD5446_H_ +#define IIO_ADC_AD5446_H_ + +/* DAC Control Bits */ + +#define AD5446_LOAD (0x0 << 14) /* Load and update */ +#define AD5446_SDO_DIS (0x1 << 14) /* Disable SDO */ +#define AD5446_NOP (0x2 << 14) /* No operation */ +#define AD5446_CLK_RISING (0x3 << 14) /* Clock data on rising edge */ + +#define RES_MASK(bits) ((1 << (bits)) - 1) + +struct ad5446_chip_info { + u8 bits; /* number of DAC bits */ + u8 storagebits; /* number of bits written to the DAC */ + u8 left_shift; /* number of bits the datum must be shifted */ + char sign; /* [s]igned or [u]nsigned */ +}; + +struct ad5446_state { + struct iio_dev *indio_dev; + struct spi_device *spi; + const struct ad5446_chip_info *chip_info; + struct regulator *reg; + struct work_struct poll_work; + unsigned short vref_mv; + struct spi_transfer xfer; + struct spi_message msg; + unsigned short data; +}; + +enum ad5446_supported_device_ids { + ID_AD5444, + ID_AD5446, + ID_AD5542A, + ID_AD5512A, +}; + +#endif /* IIO_ADC_AD5446_H_ */ -- cgit v1.2.3 From 2b4756aa36909a94596752db341a0a2c8bb8c6ea Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Mon, 22 Nov 2010 14:35:32 +0100 Subject: staging: iio: adc: Enable driver support for ad7887 AD converter Enable support for AD7887: SPI Micropower, 2-Channel, 125 kSPS, 12-Bit ADC staging: iio: adc: Fix according to review feedback Review feedback by Jonathan Cameron: Combine statements. Document struct members. Remove redundant variable initialization. Simplify multichannel scan from ring logic. Fix coding style. [v2] staging: iio: adc: ad7887: Fix typos Signed-off-by: Michael Hennerich Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/adc/Kconfig | 14 ++ drivers/staging/iio/adc/Makefile | 4 + drivers/staging/iio/adc/ad7887.h | 105 ++++++++++++ drivers/staging/iio/adc/ad7887_core.c | 305 ++++++++++++++++++++++++++++++++++ drivers/staging/iio/adc/ad7887_ring.c | 266 +++++++++++++++++++++++++++++ 5 files changed, 694 insertions(+) create mode 100644 drivers/staging/iio/adc/ad7887.h create mode 100644 drivers/staging/iio/adc/ad7887_core.c create mode 100644 drivers/staging/iio/adc/ad7887_ring.c diff --git a/drivers/staging/iio/adc/Kconfig b/drivers/staging/iio/adc/Kconfig index 9ca6565d2bae..86869cd233ae 100644 --- a/drivers/staging/iio/adc/Kconfig +++ b/drivers/staging/iio/adc/Kconfig @@ -97,6 +97,20 @@ config AD7476 To compile this driver as a module, choose M here: the module will be called ad7476. +config AD7887 + tristate "Analog Devices AD7887 ADC driver" + depends on SPI + select IIO_RING_BUFFER + select IIO_SW_RING + select IIO_TRIGGER + help + Say yes here to build support for Analog Devices + AD7887 SPI analog to digital convertor (ADC). + If unsure, say N (but it's safe to say "Y"). + + To compile this driver as a module, choose M here: the + module will be called ad7887. + config AD7745 tristate "Analog Devices AD7745, AD7746 AD7747 capacitive sensor driver" depends on I2C diff --git a/drivers/staging/iio/adc/Makefile b/drivers/staging/iio/adc/Makefile index a7dce6bd5f3a..6f231a2cb777 100644 --- a/drivers/staging/iio/adc/Makefile +++ b/drivers/staging/iio/adc/Makefile @@ -15,6 +15,10 @@ ad7476-y := ad7476_core.o ad7476-$(CONFIG_IIO_RING_BUFFER) += ad7476_ring.o obj-$(CONFIG_AD7476) += ad7476.o +ad7887-y := ad7887_core.o +ad7887-$(CONFIG_IIO_RING_BUFFER) += ad7887_ring.o +obj-$(CONFIG_AD7887) += ad7887.o + obj-$(CONFIG_AD7150) += ad7150.o obj-$(CONFIG_AD7152) += ad7152.o obj-$(CONFIG_AD7291) += ad7291.o diff --git a/drivers/staging/iio/adc/ad7887.h b/drivers/staging/iio/adc/ad7887.h new file mode 100644 index 000000000000..8c2a218c9496 --- /dev/null +++ b/drivers/staging/iio/adc/ad7887.h @@ -0,0 +1,105 @@ +/* + * AD7887 SPI ADC driver + * + * Copyright 2010 Analog Devices Inc. + * + * Licensed under the GPL-2 or later. + */ +#ifndef IIO_ADC_AD7887_H_ +#define IIO_ADC_AD7887_H_ + +#define AD7887_REF_DIS (1 << 5) /* on-chip reference disable */ +#define AD7887_DUAL (1 << 4) /* dual-channel mode */ +#define AD7887_CH_AIN1 (1 << 3) /* convert on channel 1, DUAL=1 */ +#define AD7887_CH_AIN0 (0 << 3) /* convert on channel 0, DUAL=0,1 */ +#define AD7887_PM_MODE1 (0) /* CS based shutdown */ +#define AD7887_PM_MODE2 (1) /* full on */ +#define AD7887_PM_MODE3 (2) /* auto shutdown after conversion */ +#define AD7887_PM_MODE4 (3) /* standby mode */ + +enum ad7887_channels { + AD7887_CH0, + AD7887_CH0_CH1, + AD7887_CH1, +}; + +#define RES_MASK(bits) ((1 << (bits)) - 1) /* TODO: move this into a common header */ + +/* + * TODO: struct ad7887_platform_data needs to go into include/linux/iio + */ + +struct ad7887_platform_data { + /* External Vref voltage applied */ + u16 vref_mv; + /* + * AD7887: + * In single channel mode en_dual = flase, AIN1/Vref pins assumes its + * Vref function. In dual channel mode en_dual = true, AIN1 becomes the + * second input channel, and Vref is internally connected to Vdd. + */ + bool en_dual; + /* + * AD7887: + * use_onchip_ref = true, the Vref is internally connected to the 2.500V + * Voltage reference. If use_onchip_ref = false, the reference voltage + * is supplied by AIN1/Vref + */ + bool use_onchip_ref; +}; + +struct ad7887_chip_info { + u8 bits; /* number of ADC bits */ + u8 storagebits; /* number of bits read from the ADC */ + u8 left_shift; /* number of bits the sample must be shifted */ + char sign; /* [s]igned or [u]nsigned */ + u16 int_vref_mv; /* internal reference voltage */ +}; + +struct ad7887_state { + struct iio_dev *indio_dev; + struct spi_device *spi; + const struct ad7887_chip_info *chip_info; + struct regulator *reg; + struct work_struct poll_work; + atomic_t protect_ring; + u16 int_vref_mv; + bool en_dual; + struct spi_transfer xfer[4]; + struct spi_message msg[3]; + struct spi_message *ring_msg; + unsigned char tx_cmd_buf[8]; + + /* + * DMA (thus cache coherency maintenance) requires the + * transfer buffers to live in their own cache lines. + */ + + unsigned char data[4] ____cacheline_aligned; +}; + +enum ad7887_supported_device_ids { + ID_AD7887 +}; + +#ifdef CONFIG_IIO_RING_BUFFER +int ad7887_scan_from_ring(struct ad7887_state *st, long mask); +int ad7887_register_ring_funcs_and_init(struct iio_dev *indio_dev); +void ad7887_ring_cleanup(struct iio_dev *indio_dev); +#else /* CONFIG_IIO_RING_BUFFER */ +static inline int ad7887_scan_from_ring(struct ad7887_state *st, long mask) +{ + return 0; +} + +static inline int +ad7887_register_ring_funcs_and_init(struct iio_dev *indio_dev) +{ + return 0; +} + +static inline void ad7887_ring_cleanup(struct iio_dev *indio_dev) +{ +} +#endif /* CONFIG_IIO_RING_BUFFER */ +#endif /* IIO_ADC_AD7887_H_ */ diff --git a/drivers/staging/iio/adc/ad7887_core.c b/drivers/staging/iio/adc/ad7887_core.c new file mode 100644 index 000000000000..685908995d49 --- /dev/null +++ b/drivers/staging/iio/adc/ad7887_core.c @@ -0,0 +1,305 @@ +/* + * AD7887 SPI ADC driver + * + * Copyright 2010 Analog Devices Inc. + * + * Licensed under the GPL-2 or later. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../iio.h" +#include "../sysfs.h" +#include "../ring_generic.h" +#include "adc.h" + +#include "ad7887.h" + +static int ad7887_scan_direct(struct ad7887_state *st, unsigned ch) +{ + int ret = spi_sync(st->spi, &st->msg[ch]); + if (ret) + return ret; + + return (st->data[(ch * 2)] << 8) | st->data[(ch * 2) + 1]; +} + +static ssize_t ad7887_scan(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad7887_state *st = dev_info->dev_data; + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + int ret; + + mutex_lock(&dev_info->mlock); + if (iio_ring_enabled(dev_info)) + ret = ad7887_scan_from_ring(st, 1 << this_attr->address); + else + ret = ad7887_scan_direct(st, this_attr->address); + mutex_unlock(&dev_info->mlock); + + if (ret < 0) + return ret; + + return sprintf(buf, "%d\n", (ret >> st->chip_info->left_shift) & + RES_MASK(st->chip_info->bits)); +} +static IIO_DEV_ATTR_IN_RAW(0, ad7887_scan, 0); +static IIO_DEV_ATTR_IN_RAW(1, ad7887_scan, 1); + +static ssize_t ad7887_show_scale(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + /* Driver currently only support internal vref */ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad7887_state *st = iio_dev_get_devdata(dev_info); + /* Corresponds to Vref / 2^(bits) */ + unsigned int scale_uv = (st->int_vref_mv * 1000) >> st->chip_info->bits; + + return sprintf(buf, "%d.%d\n", scale_uv / 1000, scale_uv % 1000); +} +static IIO_DEVICE_ATTR(in_scale, S_IRUGO, ad7887_show_scale, NULL, 0); + +static ssize_t ad7887_show_name(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad7887_state *st = iio_dev_get_devdata(dev_info); + + return sprintf(buf, "%s\n", spi_get_device_id(st->spi)->name); +} +static IIO_DEVICE_ATTR(name, S_IRUGO, ad7887_show_name, NULL, 0); + +static struct attribute *ad7887_attributes[] = { + &iio_dev_attr_in0_raw.dev_attr.attr, + &iio_dev_attr_in1_raw.dev_attr.attr, + &iio_dev_attr_in_scale.dev_attr.attr, + &iio_dev_attr_name.dev_attr.attr, + NULL, +}; + +static mode_t ad7887_attr_is_visible(struct kobject *kobj, + struct attribute *attr, int n) +{ + struct device *dev = container_of(kobj, struct device, kobj); + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad7887_state *st = iio_dev_get_devdata(dev_info); + + mode_t mode = attr->mode; + + if ((attr == &iio_dev_attr_in1_raw.dev_attr.attr) && !st->en_dual) + mode = 0; + + return mode; +} + +static const struct attribute_group ad7887_attribute_group = { + .attrs = ad7887_attributes, + .is_visible = ad7887_attr_is_visible, +}; + +static const struct ad7887_chip_info ad7887_chip_info_tbl[] = { + /* + * More devices added in future + */ + [ID_AD7887] = { + .bits = 12, + .storagebits = 16, + .left_shift = 0, + .sign = IIO_SCAN_EL_TYPE_UNSIGNED, + .int_vref_mv = 2500, + }, +}; + +static int __devinit ad7887_probe(struct spi_device *spi) +{ + struct ad7887_platform_data *pdata = spi->dev.platform_data; + struct ad7887_state *st; + int ret, voltage_uv = 0; + + st = kzalloc(sizeof(*st), GFP_KERNEL); + if (st == NULL) { + ret = -ENOMEM; + goto error_ret; + } + + st->reg = regulator_get(&spi->dev, "vcc"); + if (!IS_ERR(st->reg)) { + ret = regulator_enable(st->reg); + if (ret) + goto error_put_reg; + + voltage_uv = regulator_get_voltage(st->reg); + } + + st->chip_info = + &ad7887_chip_info_tbl[spi_get_device_id(spi)->driver_data]; + + spi_set_drvdata(spi, st); + + atomic_set(&st->protect_ring, 0); + st->spi = spi; + + st->indio_dev = iio_allocate_device(); + if (st->indio_dev == NULL) { + ret = -ENOMEM; + goto error_disable_reg; + } + + /* Estabilish that the iio_dev is a child of the spi device */ + st->indio_dev->dev.parent = &spi->dev; + st->indio_dev->attrs = &ad7887_attribute_group; + st->indio_dev->dev_data = (void *)(st); + st->indio_dev->driver_module = THIS_MODULE; + st->indio_dev->modes = INDIO_DIRECT_MODE; + + /* Setup default message */ + + st->tx_cmd_buf[0] = AD7887_CH_AIN0 | AD7887_PM_MODE4 | + ((pdata && pdata->use_onchip_ref) ? + 0 : AD7887_REF_DIS); + + st->xfer[0].rx_buf = &st->data[0]; + st->xfer[0].tx_buf = &st->tx_cmd_buf[0]; + st->xfer[0].len = 2; + + spi_message_init(&st->msg[AD7887_CH0]); + spi_message_add_tail(&st->xfer[0], &st->msg[AD7887_CH0]); + + if (pdata && pdata->en_dual) { + st->tx_cmd_buf[0] |= AD7887_DUAL | AD7887_REF_DIS; + + st->tx_cmd_buf[2] = AD7887_CH_AIN1 | AD7887_DUAL | + AD7887_REF_DIS | AD7887_PM_MODE4; + st->tx_cmd_buf[4] = AD7887_CH_AIN0 | AD7887_DUAL | + AD7887_REF_DIS | AD7887_PM_MODE4; + st->tx_cmd_buf[6] = AD7887_CH_AIN1 | AD7887_DUAL | + AD7887_REF_DIS | AD7887_PM_MODE4; + + st->xfer[1].rx_buf = &st->data[0]; + st->xfer[1].tx_buf = &st->tx_cmd_buf[2]; + st->xfer[1].len = 2; + + st->xfer[2].rx_buf = &st->data[2]; + st->xfer[2].tx_buf = &st->tx_cmd_buf[4]; + st->xfer[2].len = 2; + + spi_message_init(&st->msg[AD7887_CH0_CH1]); + spi_message_add_tail(&st->xfer[1], &st->msg[AD7887_CH0_CH1]); + spi_message_add_tail(&st->xfer[2], &st->msg[AD7887_CH0_CH1]); + + st->xfer[3].rx_buf = &st->data[0]; + st->xfer[3].tx_buf = &st->tx_cmd_buf[6]; + st->xfer[3].len = 2; + + spi_message_init(&st->msg[AD7887_CH1]); + spi_message_add_tail(&st->xfer[3], &st->msg[AD7887_CH1]); + + st->en_dual = true; + + if (pdata && pdata->vref_mv) + st->int_vref_mv = pdata->vref_mv; + else if (voltage_uv) + st->int_vref_mv = voltage_uv / 1000; + else + dev_warn(&spi->dev, "reference voltage unspecified\n"); + + } else { + if (pdata && pdata->vref_mv) + st->int_vref_mv = pdata->vref_mv; + else if (pdata && pdata->use_onchip_ref) + st->int_vref_mv = st->chip_info->int_vref_mv; + else + dev_warn(&spi->dev, "reference voltage unspecified\n"); + } + + + ret = ad7887_register_ring_funcs_and_init(st->indio_dev); + if (ret) + goto error_free_device; + + ret = iio_device_register(st->indio_dev); + if (ret) + goto error_free_device; + + ret = iio_ring_buffer_register(st->indio_dev->ring, 0); + if (ret) + goto error_cleanup_ring; + return 0; + +error_cleanup_ring: + ad7887_ring_cleanup(st->indio_dev); + iio_device_unregister(st->indio_dev); +error_free_device: + iio_free_device(st->indio_dev); +error_disable_reg: + if (!IS_ERR(st->reg)) + regulator_disable(st->reg); +error_put_reg: + if (!IS_ERR(st->reg)) + regulator_put(st->reg); + kfree(st); +error_ret: + return ret; +} + +static int ad7887_remove(struct spi_device *spi) +{ + struct ad7887_state *st = spi_get_drvdata(spi); + struct iio_dev *indio_dev = st->indio_dev; + iio_ring_buffer_unregister(indio_dev->ring); + ad7887_ring_cleanup(indio_dev); + iio_device_unregister(indio_dev); + if (!IS_ERR(st->reg)) { + regulator_disable(st->reg); + regulator_put(st->reg); + } + kfree(st); + return 0; +} + +static const struct spi_device_id ad7887_id[] = { + {"ad7887", ID_AD7887}, + {} +}; + +static struct spi_driver ad7887_driver = { + .driver = { + .name = "ad7887", + .bus = &spi_bus_type, + .owner = THIS_MODULE, + }, + .probe = ad7887_probe, + .remove = __devexit_p(ad7887_remove), + .id_table = ad7887_id, +}; + +static int __init ad7887_init(void) +{ + return spi_register_driver(&ad7887_driver); +} +module_init(ad7887_init); + +static void __exit ad7887_exit(void) +{ + spi_unregister_driver(&ad7887_driver); +} +module_exit(ad7887_exit); + +MODULE_AUTHOR("Michael Hennerich "); +MODULE_DESCRIPTION("Analog Devices AD7887 ADC"); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("spi:ad7887"); diff --git a/drivers/staging/iio/adc/ad7887_ring.c b/drivers/staging/iio/adc/ad7887_ring.c new file mode 100644 index 000000000000..6b9cb1f95a1e --- /dev/null +++ b/drivers/staging/iio/adc/ad7887_ring.c @@ -0,0 +1,266 @@ +/* + * Copyright 2010 Analog Devices Inc. + * Copyright (C) 2008 Jonathan Cameron + * + * Licensed under the GPL-2 or later. + * + * ad7887_ring.c + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../iio.h" +#include "../ring_generic.h" +#include "../ring_sw.h" +#include "../trigger.h" +#include "../sysfs.h" + +#include "ad7887.h" + +static IIO_SCAN_EL_C(in0, 0, 0, NULL); +static IIO_SCAN_EL_C(in1, 1, 0, NULL); + +static ssize_t ad7887_show_type(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_ring_buffer *ring = dev_get_drvdata(dev); + struct iio_dev *indio_dev = ring->indio_dev; + struct ad7887_state *st = indio_dev->dev_data; + + return sprintf(buf, "%c%d/%d>>%d\n", st->chip_info->sign, + st->chip_info->bits, st->chip_info->storagebits, + st->chip_info->left_shift); +} +static IIO_DEVICE_ATTR(in_type, S_IRUGO, ad7887_show_type, NULL, 0); + +static struct attribute *ad7887_scan_el_attrs[] = { + &iio_scan_el_in0.dev_attr.attr, + &iio_const_attr_in0_index.dev_attr.attr, + &iio_scan_el_in1.dev_attr.attr, + &iio_const_attr_in1_index.dev_attr.attr, + &iio_dev_attr_in_type.dev_attr.attr, + NULL, +}; + +static mode_t ad7887_scan_el_attr_is_visible(struct kobject *kobj, + struct attribute *attr, int n) +{ + struct device *dev = container_of(kobj, struct device, kobj); + struct iio_ring_buffer *ring = dev_get_drvdata(dev); + struct iio_dev *indio_dev = ring->indio_dev; + struct ad7887_state *st = indio_dev->dev_data; + + mode_t mode = attr->mode; + + if ((attr == &iio_scan_el_in1.dev_attr.attr) || + (attr == &iio_const_attr_in1_index.dev_attr.attr)) + if (!st->en_dual) + mode = 0; + + return mode; +} + +static struct attribute_group ad7887_scan_el_group = { + .name = "scan_elements", + .attrs = ad7887_scan_el_attrs, + .is_visible = ad7887_scan_el_attr_is_visible, +}; + +int ad7887_scan_from_ring(struct ad7887_state *st, long mask) +{ + struct iio_ring_buffer *ring = st->indio_dev->ring; + int count = 0, ret; + u16 *ring_data; + + if (!(ring->scan_mask & mask)) { + ret = -EBUSY; + goto error_ret; + } + + ring_data = kmalloc(ring->access.get_bytes_per_datum(ring), GFP_KERNEL); + if (ring_data == NULL) { + ret = -ENOMEM; + goto error_ret; + } + ret = ring->access.read_last(ring, (u8 *) ring_data); + if (ret) + goto error_free_ring_data; + + /* for single channel scan the result is stored with zero offset */ + if ((ring->scan_mask == ((1 << 1) | (1 << 0))) && (mask == (1 << 1))) + count = 1; + + ret = be16_to_cpu(ring_data[count]); + +error_free_ring_data: + kfree(ring_data); +error_ret: + return ret; +} + +/** + * ad7887_ring_preenable() setup the parameters of the ring before enabling + * + * The complex nature of the setting of the nuber of bytes per datum is due + * to this driver currently ensuring that the timestamp is stored at an 8 + * byte boundary. + **/ +static int ad7887_ring_preenable(struct iio_dev *indio_dev) +{ + struct ad7887_state *st = indio_dev->dev_data; + struct iio_ring_buffer *ring = indio_dev->ring; + size_t d_size; + + if (indio_dev->ring->access.set_bytes_per_datum) { + d_size = st->chip_info->storagebits / 8 + sizeof(s64); + if (d_size % 8) + d_size += 8 - (d_size % 8); + indio_dev->ring->access.set_bytes_per_datum(indio_dev->ring, + d_size); + } + + switch (ring->scan_mask) { + case (1 << 0): + st->ring_msg = &st->msg[AD7887_CH0]; + break; + case (1 << 1): + st->ring_msg = &st->msg[AD7887_CH1]; + /* Dummy read: push CH1 setting down to hardware */ + spi_sync(st->spi, st->ring_msg); + break; + case ((1 << 1) | (1 << 0)): + st->ring_msg = &st->msg[AD7887_CH0_CH1]; + break; + } + + return 0; +} + +static int ad7887_ring_postdisable(struct iio_dev *indio_dev) +{ + struct ad7887_state *st = indio_dev->dev_data; + + /* dummy read: restore default CH0 settin */ + return spi_sync(st->spi, &st->msg[AD7887_CH0]); +} + +/** + * ad7887_poll_func_th() th of trigger launched polling to ring buffer + * + * As sampling only occurs on spi comms occuring, leave timestamping until + * then. Some triggers will generate their own time stamp. Currently + * there is no way of notifying them when no one cares. + **/ +static void ad7887_poll_func_th(struct iio_dev *indio_dev, s64 time) +{ + struct ad7887_state *st = indio_dev->dev_data; + + schedule_work(&st->poll_work); + return; +} +/** + * ad7887_poll_bh_to_ring() bh of trigger launched polling to ring buffer + * @work_s: the work struct through which this was scheduled + * + * Currently there is no option in this driver to disable the saving of + * timestamps within the ring. + * I think the one copy of this at a time was to avoid problems if the + * trigger was set far too high and the reads then locked up the computer. + **/ +static void ad7887_poll_bh_to_ring(struct work_struct *work_s) +{ + struct ad7887_state *st = container_of(work_s, struct ad7887_state, + poll_work); + struct iio_dev *indio_dev = st->indio_dev; + struct iio_sw_ring_buffer *sw_ring = iio_to_sw_ring(indio_dev->ring); + struct iio_ring_buffer *ring = indio_dev->ring; + s64 time_ns; + __u8 *buf; + int b_sent; + size_t d_size; + + unsigned int bytes = ring->scan_count * st->chip_info->storagebits / 8; + + /* Ensure the timestamp is 8 byte aligned */ + d_size = bytes + sizeof(s64); + if (d_size % sizeof(s64)) + d_size += sizeof(s64) - (d_size % sizeof(s64)); + + /* Ensure only one copy of this function running at a time */ + if (atomic_inc_return(&st->protect_ring) > 1) + return; + + buf = kzalloc(d_size, GFP_KERNEL); + if (buf == NULL) + return; + + b_sent = spi_sync(st->spi, st->ring_msg); + if (b_sent) + goto done; + + time_ns = iio_get_time_ns(); + + memcpy(buf, st->data, bytes); + memcpy(buf + d_size - sizeof(s64), &time_ns, sizeof(time_ns)); + + indio_dev->ring->access.store_to(&sw_ring->buf, buf, time_ns); +done: + kfree(buf); + atomic_dec(&st->protect_ring); +} + +int ad7887_register_ring_funcs_and_init(struct iio_dev *indio_dev) +{ + struct ad7887_state *st = indio_dev->dev_data; + int ret; + + indio_dev->ring = iio_sw_rb_allocate(indio_dev); + if (!indio_dev->ring) { + ret = -ENOMEM; + goto error_ret; + } + /* Effectively select the ring buffer implementation */ + iio_ring_sw_register_funcs(&indio_dev->ring->access); + ret = iio_alloc_pollfunc(indio_dev, NULL, &ad7887_poll_func_th); + if (ret) + goto error_deallocate_sw_rb; + + /* Ring buffer functions - here trigger setup related */ + + indio_dev->ring->preenable = &ad7887_ring_preenable; + indio_dev->ring->postenable = &iio_triggered_ring_postenable; + indio_dev->ring->predisable = &iio_triggered_ring_predisable; + indio_dev->ring->postdisable = &ad7887_ring_postdisable; + indio_dev->ring->scan_el_attrs = &ad7887_scan_el_group; + + INIT_WORK(&st->poll_work, &ad7887_poll_bh_to_ring); + + /* Flag that polled ring buffering is possible */ + indio_dev->modes |= INDIO_RING_TRIGGERED; + return 0; +error_deallocate_sw_rb: + iio_sw_rb_free(indio_dev->ring); +error_ret: + return ret; +} + +void ad7887_ring_cleanup(struct iio_dev *indio_dev) +{ + /* ensure that the trigger has been detached */ + if (indio_dev->trig) { + iio_put_trigger(indio_dev->trig); + iio_trigger_dettach_poll_func(indio_dev->trig, + indio_dev->pollfunc); + } + kfree(indio_dev->pollfunc); + iio_sw_rb_free(indio_dev->ring); +} -- cgit v1.2.3 From a9672951a5c4e57e048895d868a2172962ef7ffd Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Mon, 22 Nov 2010 23:09:47 +0000 Subject: staging: iio: adis16260 add id table support Signed-off-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/gyro/adis16260_core.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/staging/iio/gyro/adis16260_core.c b/drivers/staging/iio/gyro/adis16260_core.c index 8190c0fe0bea..6f549030e3bb 100644 --- a/drivers/staging/iio/gyro/adis16260_core.c +++ b/drivers/staging/iio/gyro/adis16260_core.c @@ -635,6 +635,12 @@ err_ret: return ret; } +static const struct spi_device_id adis16260_id[] = { + {"adis16260", 0}, + {"adis16265", 0}, + {} +}; + static struct spi_driver adis16260_driver = { .driver = { .name = "adis16260", @@ -642,6 +648,7 @@ static struct spi_driver adis16260_driver = { }, .probe = adis16260_probe, .remove = __devexit_p(adis16260_remove), + .id_table = adis16260_id, }; static __init int adis16260_init(void) -- cgit v1.2.3 From fe34604844c151668579cb6ad52f75a5c651bed9 Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Mon, 22 Nov 2010 23:09:48 +0000 Subject: staging: iio: adis16260 add suppport for adis16255 and adis16250. Unusual element is addition of 'negate' and 'axis' platform data to ensure we support all the functionality of the adis16255 driver currently in staging. Signed-off-by: Jonathan Cameron Acked-by: Matthias Brugger Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/gyro/adis16260.h | 3 + drivers/staging/iio/gyro/adis16260_core.c | 133 +++++++++++++++------ drivers/staging/iio/gyro/adis16260_platform_data.h | 19 +++ drivers/staging/iio/gyro/gyro.h | 9 ++ 4 files changed, 125 insertions(+), 39 deletions(-) create mode 100644 drivers/staging/iio/gyro/adis16260_platform_data.h diff --git a/drivers/staging/iio/gyro/adis16260.h b/drivers/staging/iio/gyro/adis16260.h index 812440af57d6..c1fd4364287f 100644 --- a/drivers/staging/iio/gyro/adis16260.h +++ b/drivers/staging/iio/gyro/adis16260.h @@ -1,5 +1,6 @@ #ifndef SPI_ADIS16260_H_ #define SPI_ADIS16260_H_ +#include "adis16260_platform_data.h" #define ADIS16260_STARTUP_DELAY 220 /* ms */ @@ -92,6 +93,7 @@ * @tx: transmit buffer * @rx: recieve buffer * @buf_lock: mutex to protect tx and rx + * @negate: negate the scale parameter **/ struct adis16260_state { struct spi_device *us; @@ -102,6 +104,7 @@ struct adis16260_state { u8 *tx; u8 *rx; struct mutex buf_lock; + unsigned negate:1; }; int adis16260_set_irq(struct device *dev, bool enable); diff --git a/drivers/staging/iio/gyro/adis16260_core.c b/drivers/staging/iio/gyro/adis16260_core.c index 6f549030e3bb..045e27da980a 100644 --- a/drivers/staging/iio/gyro/adis16260_core.c +++ b/drivers/staging/iio/gyro/adis16260_core.c @@ -134,8 +134,6 @@ static int adis16260_spi_read_reg_16(struct device *dev, mutex_lock(&st->buf_lock); st->tx[0] = ADIS16260_READ_REG(lower_reg_address); st->tx[1] = 0; - st->tx[2] = 0; - st->tx[3] = 0; spi_message_init(&msg); spi_message_add_tail(&xfers[0], &msg); @@ -293,6 +291,22 @@ static ssize_t adis16260_write_frequency(struct device *dev, return ret ? ret : len; } +static ssize_t adis16260_read_gyro_scale(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *indio_dev = dev_get_drvdata(dev); + struct adis16260_state *st = iio_dev_get_devdata(indio_dev); + ssize_t ret = 0; + + if (st->negate) + ret = sprintf(buf, "-"); + /* Take the iio_dev status lock */ + ret += sprintf(buf + ret, "%s\n", "0.00127862821"); + + return ret; +} + static int adis16260_reset(struct device *dev) { int ret; @@ -447,18 +461,6 @@ static IIO_DEV_ATTR_IN_NAMED_RAW(0, supply, ADIS16260_SUPPLY_OUT); static IIO_CONST_ATTR_IN_NAMED_SCALE(0, supply, "0.0018315"); -static IIO_DEV_ATTR_GYRO(adis16260_read_14bit_signed, - ADIS16260_GYRO_OUT); -static IIO_CONST_ATTR_GYRO_SCALE("0.00127862821"); -static IIO_DEV_ATTR_GYRO_CALIBSCALE(S_IWUSR | S_IRUGO, - adis16260_read_14bit_signed, - adis16260_write_16bit, - ADIS16260_GYRO_SCALE); -static IIO_DEV_ATTR_GYRO_CALIBBIAS(S_IWUSR | S_IRUGO, - adis16260_read_12bit_signed, - adis16260_write_16bit, - ADIS16260_GYRO_OFF); - static IIO_DEV_ATTR_TEMP_RAW(adis16260_read_12bit_unsigned); static IIO_CONST_ATTR_TEMP_OFFSET("25"); static IIO_CONST_ATTR_TEMP_SCALE("0.1453"); @@ -470,8 +472,6 @@ static IIO_CONST_ATTR(in1_scale, "0.0006105"); static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO, adis16260_read_frequency, adis16260_write_frequency); -static IIO_DEV_ATTR_ANGL(adis16260_read_14bit_signed, - ADIS16260_ANGL_OUT); static IIO_DEVICE_ATTR(reset, S_IWUSR, NULL, adis16260_write_reset, 0); @@ -487,38 +487,70 @@ static struct attribute_group adis16260_event_attribute_group = { .attrs = adis16260_event_attributes, }; -static struct attribute *adis16260_attributes[] = { - &iio_dev_attr_in0_supply_raw.dev_attr.attr, - &iio_const_attr_in0_supply_scale.dev_attr.attr, - &iio_dev_attr_gyro_raw.dev_attr.attr, - &iio_const_attr_gyro_scale.dev_attr.attr, - &iio_dev_attr_gyro_calibscale.dev_attr.attr, - &iio_dev_attr_gyro_calibbias.dev_attr.attr, - &iio_dev_attr_angl_raw.dev_attr.attr, - &iio_dev_attr_temp_raw.dev_attr.attr, - &iio_const_attr_temp_offset.dev_attr.attr, - &iio_const_attr_temp_scale.dev_attr.attr, - &iio_dev_attr_in1_raw.dev_attr.attr, - &iio_const_attr_in1_scale.dev_attr.attr, - &iio_dev_attr_sampling_frequency.dev_attr.attr, - &iio_const_attr_sampling_frequency_available.dev_attr.attr, - &iio_dev_attr_reset.dev_attr.attr, - &iio_const_attr_name.dev_attr.attr, - NULL -}; +#define ADIS16260_GYRO_ATTR_SET(axis) \ + IIO_DEV_ATTR_GYRO##axis(adis16260_read_14bit_signed, \ + ADIS16260_GYRO_OUT); \ + static IIO_DEV_ATTR_GYRO##axis##_SCALE(S_IRUGO, \ + adis16260_read_gyro_scale, \ + NULL, \ + 0); \ + static IIO_DEV_ATTR_GYRO##axis##_CALIBSCALE(S_IRUGO | S_IWUSR, \ + adis16260_read_12bit_unsigned, \ + adis16260_write_16bit, \ + ADIS16260_GYRO_SCALE); \ + static IIO_DEV_ATTR_GYRO##axis##_CALIBBIAS(S_IWUSR | S_IRUGO, \ + adis16260_read_12bit_signed, \ + adis16260_write_16bit, \ + ADIS16260_GYRO_OFF); \ + static IIO_DEV_ATTR_ANGL##axis(adis16260_read_14bit_signed, \ + ADIS16260_ANGL_OUT); + +static ADIS16260_GYRO_ATTR_SET(); +static ADIS16260_GYRO_ATTR_SET(_X); +static ADIS16260_GYRO_ATTR_SET(_Y); +static ADIS16260_GYRO_ATTR_SET(_Z); + +#define ADIS16260_ATTR_GROUP(axis) \ + struct attribute *adis16260_attributes##axis[] = { \ + &iio_dev_attr_in0_supply_raw.dev_attr.attr, \ + &iio_const_attr_in0_supply_scale.dev_attr.attr, \ + &iio_dev_attr_gyro##axis##_raw.dev_attr.attr, \ + &iio_dev_attr_gyro##axis##_scale.dev_attr.attr, \ + &iio_dev_attr_gyro##axis##_calibscale.dev_attr.attr, \ + &iio_dev_attr_gyro##axis##_calibbias.dev_attr.attr, \ + &iio_dev_attr_angl##axis##_raw.dev_attr.attr, \ + &iio_dev_attr_temp_raw.dev_attr.attr, \ + &iio_const_attr_temp_offset.dev_attr.attr, \ + &iio_const_attr_temp_scale.dev_attr.attr, \ + &iio_dev_attr_in1_raw.dev_attr.attr, \ + &iio_const_attr_in1_scale.dev_attr.attr, \ + &iio_dev_attr_sampling_frequency.dev_attr.attr, \ + &iio_const_attr_sampling_frequency_available.dev_attr.attr, \ + &iio_dev_attr_reset.dev_attr.attr, \ + &iio_const_attr_name.dev_attr.attr, \ + NULL \ + }; \ + static const struct attribute_group adis16260_attribute_group##axis \ + = { \ + .attrs = adis16260_attributes##axis, \ + }; -static const struct attribute_group adis16260_attribute_group = { - .attrs = adis16260_attributes, -}; +static ADIS16260_ATTR_GROUP(); +static ADIS16260_ATTR_GROUP(_x); +static ADIS16260_ATTR_GROUP(_y); +static ADIS16260_ATTR_GROUP(_z); static int __devinit adis16260_probe(struct spi_device *spi) { int ret, regdone = 0; + struct adis16260_platform_data *pd = spi->dev.platform_data; struct adis16260_state *st = kzalloc(sizeof *st, GFP_KERNEL); if (!st) { ret = -ENOMEM; goto error_ret; } + if (pd) + st->negate = pd->negate; /* this is only used for removal purposes */ spi_set_drvdata(spi, st); @@ -545,7 +577,24 @@ static int __devinit adis16260_probe(struct spi_device *spi) st->indio_dev->dev.parent = &spi->dev; st->indio_dev->num_interrupt_lines = 1; st->indio_dev->event_attrs = &adis16260_event_attribute_group; - st->indio_dev->attrs = &adis16260_attribute_group; + if (pd && pd->direction) + switch (pd->direction) { + case 'x': + st->indio_dev->attrs = &adis16260_attribute_group_x; + break; + case 'y': + st->indio_dev->attrs = &adis16260_attribute_group_y; + break; + case 'z': + st->indio_dev->attrs = &adis16260_attribute_group_z; + break; + default: + st->indio_dev->attrs = &adis16260_attribute_group; + break; + } + else + st->indio_dev->attrs = &adis16260_attribute_group; + st->indio_dev->dev_data = (void *)(st); st->indio_dev->driver_module = THIS_MODULE; st->indio_dev->modes = INDIO_DIRECT_MODE; @@ -635,9 +684,15 @@ err_ret: return ret; } +/* + * These parts do not need to be differentiated until someone adds + * support for the on chip filtering. + */ static const struct spi_device_id adis16260_id[] = { {"adis16260", 0}, {"adis16265", 0}, + {"adis16250", 0}, + {"adis16255", 0}, {} }; diff --git a/drivers/staging/iio/gyro/adis16260_platform_data.h b/drivers/staging/iio/gyro/adis16260_platform_data.h new file mode 100644 index 000000000000..12802e97be92 --- /dev/null +++ b/drivers/staging/iio/gyro/adis16260_platform_data.h @@ -0,0 +1,19 @@ +/* + * ADIS16260 Programmable Digital Gyroscope Sensor Driver Platform Data + * + * Based on adis16255.h Matthia Brugger + * + * Copyright (C) 2010 Fraunhofer Institute for Integrated Circuits + * + * Licensed under the GPL-2 or later. + */ + +/** + * struct adis16260_platform_data - instance specific data + * @direction: x y or z + * @negate: flag to indicate value should be inverted. + **/ +struct adis16260_platform_data { + char direction; + unsigned negate:1; +}; diff --git a/drivers/staging/iio/gyro/gyro.h b/drivers/staging/iio/gyro/gyro.h index 98b837b775a2..b4ea5bf161ff 100644 --- a/drivers/staging/iio/gyro/gyro.h +++ b/drivers/staging/iio/gyro/gyro.h @@ -71,3 +71,12 @@ #define IIO_DEV_ATTR_ANGL(_show, _addr) \ IIO_DEVICE_ATTR(angl_raw, S_IRUGO, _show, NULL, _addr) + +#define IIO_DEV_ATTR_ANGL_X(_show, _addr) \ + IIO_DEVICE_ATTR(angl_x_raw, S_IRUGO, _show, NULL, _addr) + +#define IIO_DEV_ATTR_ANGL_Y(_show, _addr) \ + IIO_DEVICE_ATTR(angl_y_raw, S_IRUGO, _show, NULL, _addr) + +#define IIO_DEV_ATTR_ANGL_Z(_show, _addr) \ + IIO_DEVICE_ATTR(angl_z_raw, S_IRUGO, _show, NULL, _addr) -- cgit v1.2.3 From f386caa3cd74231cd86c813fe4453e3d6e39876c Mon Sep 17 00:00:00 2001 From: Jonathan Cameron Date: Mon, 22 Nov 2010 23:31:16 +0000 Subject: staging: iio: documentation rewrite and cleanup of sysfs documetation Change to capital syntax for documetation e.g. 'inX-inY_raw' Use multiple 'What:' entries rather than wild cards or options so as to make the documentation clearer and easier to search. Some trivial spelling fixes. Signed-off-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/Documentation/sysfs-bus-iio | 627 ++++++++++++++++-------- 1 file changed, 428 insertions(+), 199 deletions(-) diff --git a/drivers/staging/iio/Documentation/sysfs-bus-iio b/drivers/staging/iio/Documentation/sysfs-bus-iio index fdb017a1c1a2..2dde97de75f8 100644 --- a/drivers/staging/iio/Documentation/sysfs-bus-iio +++ b/drivers/staging/iio/Documentation/sysfs-bus-iio @@ -1,11 +1,12 @@ -What: /sys/bus/iio/devices/device[n] +What: /sys/bus/iio/devices/deviceX KernelVersion: 2.6.35 Contact: linux-iio@vger.kernel.org Description: Hardware chip or device accessed by on communication port. - Corresponds to a grouping of sensor channels. + Corresponds to a grouping of sensor channels. X is the IIO + index of the device. -What: /sys/bus/iio/devices/trigger[n] +What: /sys/bus/iio/devices/triggerX KernelVersion: 2.6.35 Contact: linux-iio@vger.kernel.org Description: @@ -13,25 +14,26 @@ Description: May be provided by a device driver that also has an IIO device based on hardware generated events (e.g. data ready) or provided by a separate driver for other hardware (e.g. - periodic timer, gpio or high resolution timer). + periodic timer, GPIO or high resolution timer). Contains trigger type specific elements. These do not generalize well and hence are not documented in this file. + X is the IIO index of the trigger. -What: /sys/bus/iio/devices/device[n]:buffer +What: /sys/bus/iio/devices/deviceX:buffer KernelVersion: 2.6.35 Contact: linux-iio@vger.kernel.org Description: - Link to /sys/class/iio/device[n]/device[n]:buffer. n indicates + Link to /sys/class/iio/deviceX/deviceX:buffer. X indicates the device with which this buffer buffer is associated. -What: /sys/.../device[n]/name +What: /sys/bus/iio/devices/deviceX/name KernelVersion: 2.6.35 Contact: linux-iio@vger.kernel.org Description: - Description of the physical chip / device. Typically a part - number. + Description of the physical chip / device for device X. + Typically a part number. -What: /sys/.../device[n]/sampling_frequency +What: /sys/bus/iio/devices/deviceX/sampling_frequency KernelVersion: 2.6.35 Contact: linux-iio@vger.kernel.org Description: @@ -44,158 +46,233 @@ Description: relevant directories. If it effects all of the above then it is to be found in the base device directory as here. -What: /sys/.../device[n]/sampling_frequency_available +What: /sys/bus/iio/devices/deviceX/sampling_frequency_available KernelVersion: 2.6.35 Contact: linux-iio@vger.kernel.org Description: When the internal sampling clock can only take a small - discrete set of values, this file lists those availale. + discrete set of values, this file lists those available. -What: /sys/.../device[n]/in[m][_name]_raw +What: /sys/bus/iio/devices/deviceX/inY_raw +What: /sys/bus/iio/devices/deviceX/inY_supply_raw KernelVersion: 2.6.35 Contact: linux-iio@vger.kernel.org Description: Raw (unscaled no bias removal etc) voltage measurement from - channel m. name is used in special cases where this does - not correspond to externally available input (e.g. supply - voltage monitoring in which case the file is in_supply_raw). - If the device supports events on this channel then m must be - specified (even on named channels) so as to allow the source - of event codes to be identified. - -What: /sys/.../device[n]/in[m][_name]_offset + channel Y. In special cases where the channel does not + correspond to externally available input one of the named + versions may be used. The number must always be specified and + unique to allow association with event codes. + +What: /sys/bus/iio/devices/deviceX/inY-inZ_raw KernelVersion: 2.6.35 Contact: linux-iio@vger.kernel.org Description: - If known for a device, offset to be added to in[m]_raw prior - to scaling by in[_name][m]_scale in order to obtain voltage in - millivolts. Not present if the offset is always 0 or unknown. - If m is not present, then voltage offset applies to all in - channels. May be writable if a variable offset is controlled - by the device. Note that this is different to calibbias which - is for devices that apply offsets to compensate for variation - between different instances of the part, typically adjusted by - using some hardware supported calibration procedure. + Raw (unscaled) differential voltage measurement equivalent to + channel Y - channel Z where these channel numbers apply to the + physically equivalent inputs when non differential readings are + separately available. In differential only parts, then all that + is required is a consistent labeling. -What: /sys/.../device[n]/in[m][_name]_offset_available +What: /sys/bus/iio/devices/deviceX/temp_raw +What: /sys/bus/iio/devices/deviceX/temp_x_raw +What: /sys/bus/iio/devices/deviceX/temp_y_raw +What: /sys/bus/iio/devices/deviceX/temp_z_raw KernelVersion: 2.6.35 Contact: linux-iio@vger.kernel.org Description: - If a small number of discrete offset values are available, this - will be a space separated list. If these are independant (but - options the same) for individual offsets then m should not be - present. + Raw (unscaled no bias removal etc) temperature measurement. + It an axis is specified it generally means that the temperature + sensor is associated with one part of a compound device (e.g. + a gyroscope axis). -What: /sys/.../device[n]/in[m][_name]_offset_[min|max] +What: /sys/bus/iio/devices/deviceX/accel_x_raw +What: /sys/bus/iio/devices/deviceX/accel_y_raw +What: /sys/bus/iio/devices/deviceX/accel_z_raw KernelVersion: 2.6.35 Contact: linux-iio@vger.kernel.org Description: - If a more or less continuous range of voltage offsets are - supported then these specify the minimum and maximum. If shared - by all in channels then m is not present. + Acceleration in direction x, y or z (may be arbitrarily assigned + but should match other such assignments on device) + channel m (not present if only one accelerometer channel at + this orientation). Has all of the equivalent parameters as per + inY. Units after application of scale and offset are m/s^2. -What: /sys/.../device[n]/in[m][_name]_calibbias +What: /sys/bus/iio/devices/deviceX/gyro_x_raw +What: /sys/bus/iio/devices/deviceX/gyro_y_raw +What: /sys/bus/iio/devices/deviceX/gyro_z_raw KernelVersion: 2.6.35 Contact: linux-iio@vger.kernel.org Description: - Hardware applied calibration offset. (assumed to fix production - inaccuracies) + Angular velocity about axis x, y or z (may be arbitrarily + assigned) Data converted by application of offset then scale to + radians per second. Has all the equivalent parameters as + per inY. -What /sys/.../device[n]/in[m][_name]_calibscale +What: /sys/bus/iio/devices/deviceX/incli_x_raw +What: /sys/bus/iio/devices/deviceX/incli_y_raw +What: /sys/bus/iio/devices/deviceX/incli_z_raw KernelVersion: 2.6.35 Contact: linux-iio@vger.kernel.org Description: - Hardware applied calibration scale factor. (assumed to fix - production inaccuracies) + Inclination raw reading about axis x, y or z (may be + arbitrarily assigned). Data converted by application of offset + and scale to Degrees. -What: /sys/.../device[n]/in[m][_name]_scale +What: /sys/bus/iio/devices/deviceX/magn_x_raw +What: /sys/bus/iio/devices/deviceX/magn_y_raw +What: /sys/bus/iio/devices/deviceX/magn_z_raw KernelVersion: 2.6.35 Contact: linux-iio@vger.kernel.org Description: - If known for a device, scale to be applied to volt[m]_raw post - addition of in[_name][m]_offset in order to obtain the measured - voltage in millivolts. If shared across all in channels then - m is not present. + Magnetic field along axis x, y or z (may be arbitrarily + assigned) channel m (not present if only one magnetometer + at this orientation). Data converted by application of + offset then scale to Gauss. Has all the equivalent modifiers + as per inY. -What: /sys/.../device[n]/in[m]-in[o]_raw -KernelVersion: 2.6.35 +What: /sys/bus/iio/devices/deviceX/accel_x_peak_raw +What: /sys/bus/iio/devices/deviceX/accel_y_peak_raw +What: /sys/bus/iio/devices/deviceX/accel_z_peak_raw +KernelVersion: 2.6.36 Contact: linux-iio@vger.kernel.org Description: - Raw (unscaled) differential voltage measurement equivalent to - channel m - channel o where these channel numbers apply to the - physically equivalent inputs when non differential readings are - separately available. In differential only parts, then all that - is required is a consistent labelling. + Some devices provide a store of the highest value seen since + some reset condition. These attributes allow access to this + and are otherwise the direct equivalent of the + Y[_name]_raw attributes. -What: /sys/.../device[n]/accel[_x|_y|_z][m]_raw -KernelVersion: 2.6.35 +What: /sys/bus/iio/devices/deviceX/accel_xyz_squared_peak_raw +KernelVersion: 2.6.36 Contact: linux-iio@vger.kernel.org Description: - Acceleration in direction x, y or z (may be arbitrarily assigned - but should match other such assignments on device) - channel m (not present if only one accelerometer channel at - this orientation). Has all of the equivalent parameters as per - in[m]. Units after application of scale and offset are m/s^2. + A computed peak value based on the sum squared magnitude of + the underlying value in the specified directions. -What: /sys/.../device[n]/gyro[_x|_y|_z][m]_raw +What: /sys/bus/iio/devices/deviceX/accel_offset +What: /sys/bus/iio/devices/deviceX/temp_offset KernelVersion: 2.6.35 Contact: linux-iio@vger.kernel.org Description: - Angular velocity about axis x, y or z (may be arbitrarily - assigned) channel m (not present if only one gyroscope at - this orientation). - Data converted by application of offset then scale to - radians per second. Has all the equivalent parameters as - per in[m]. - -What: /sys/.../device[n]/incli[_x|_y|_z][m]_raw + If known for a device, offset to be added to [Y]_raw prior + to scaling by [Y]_scale in order to obtain value in the + units as specified in [y]_raw documentation. + Not present if the offset is always 0 or unknown. If Y is not + present, then the offset applies to all in channels of . + May be writable if a variable offset can be applied on the + device. Note that this is different to calibbias which + is for devices (or drivers) that apply offsets to compensate + for variation between different instances of the part, typically + adjusted by using some hardware supported calibration procedure. + +What: /sys/bus/iio/devices/deviceX/inY_scale +What: /sys/bus/iio/devices/deviceX/inY_supply_scale +What: /sys/bus/iio/devices/deviceX/in_scale +What: /sys/bus/iio/devices/deviceX/accel_scale +What: /sys/bus/iio/devices/deviceX/accel_peak_scale +What: /sys/bus/iio/devices/deviceX/gyro_scale +What: /sys/bus/iio/devices/deviceX/magn_scale +What: /sys/bus/iio/devices/deviceX/magn_x_scale +What: /sys/bus/iio/devices/deviceX/magn_y_scale +What: /sys/bus/iio/devices/deviceX/magn_z_scale KernelVersion: 2.6.35 Contact: linux-iio@vger.kernel.org Description: - Inclination raw reading about axis x, y or z (may be arbitarily - assigned) channel m (not present if only one inclinometer at - this orientation). Data converted by application of offset - and scale to Degrees. - -What: /sys/.../device[n]/magn[_x|_y|_z][m]_raw + If known for a device, scale to be applied to Y[_name]_raw + post addition of [Y][_name]_offset in order to obtain the + measured value in units as specified in + [Y][_name]_raw documentation.. If shared across all in + channels then Y is not present and the value is called + [Y][_name]_scale. The peak modifier means this value + is applied to Y[_name]_peak_raw values. + +What: /sys/bus/iio/devices/deviceX/accel_x_calibbias +What: /sys/bus/iio/devices/deviceX/accel_y_calibbias +What: /sys/bus/iio/devices/deviceX/accel_z_calibbias +What: /sys/bus/iio/devices/deviceX/gyro_x_calibbias +What: /sys/bus/iio/devices/deviceX/gyro_y_calibbias +What: /sys/bus/iio/devices/deviceX/gyro_z_calibbias KernelVersion: 2.6.35 Contact: linux-iio@vger.kernel.org Description: - Magnetic field along axis x, y or z (may be arbitrarily - assigned) channel m (not present if only one magnetometer - at this orientation). Data converted by application of - offset then scale to Gauss. Has all the equivalent modifiers - as per in[m]. - -What: /sys/.../device[n]/device[n]:event[m] + Hardware applied calibration offset. (assumed to fix production + inaccuracies). If shared across all channels, _calibbias + is used. + +What /sys/bus/iio/devices/deviceX/inY_calibscale +What /sys/bus/iio/devices/deviceX/inY_supply_calibscale +What /sys/bus/iio/devices/deviceX/in_calibscale +What /sys/bus/iio/devices/deviceX/accel_x_calibscale +What /sys/bus/iio/devices/deviceX/accel_y_calibscale +What /sys/bus/iio/devices/deviceX/accel_z_calibscale +What /sys/bus/iio/devices/deviceX/gyro_x_calibscale +What /sys/bus/iio/devices/deviceX/gyro_y_calibscale +What /sys/bus/iio/devices/deviceX/gyro_z_calibscale KernelVersion: 2.6.35 Contact: linux-iio@vger.kernel.org Description: - Configuration of which hardware generated events are passed up to - userspace. Some of these are a bit complex to generalize so this - section is a work in progress. + Hardware applied calibration scale factor. (assumed to fix + production inaccuracies). If shared across all channels, + _calibscale is used. -What: /sys/.../device[n]:event[m]/dev -KernelVersion: 2.6.35 +What: /sys/bus/iio/devices/deviceX/accel_scale_available +KernelVersion: 2.635 Contact: linux-iio@vger.kernel.org Description: - major:minor character device numbers for the event line. + If a discrete set of scale values are available, they + are listed in this attribute. -Taking accel_x0 as an example +What: /sys/bus/iio/devices/deviceX/deviceX:eventY +KernelVersion: 2.6.35 +Contact: linux-iio@vger.kernel.org +Description: + Configuration of which hardware generated events are passed up + to user-space. -What: /sys/.../device[n]:event[m]/accel_x0_thresh[_rising|_falling]_en +What: /sys/bus/iio/devices/deviceX:event/dev +What: /sys/bus/iio/devices/deviceX:eventY/dev +KernelVersion: 2.6.35 +Contact: linux-iio@vger.kernel.org +Description: + major:minor character device numbers for the event line Y of + device X. + +What: /sys/.../deviceX:eventY/accel_x_thresh_rising_en +What: /sys/.../deviceX:eventY/accel_x_thresh_falling_en +What: /sys/.../deviceX:eventY/accel_y_thresh_rising_en +What: /sys/.../deviceX:eventY/accel_y_thresh_falling_en +What: /sys/.../deviceX:eventY/accel_z_thresh_rising_en +What: /sys/.../deviceX:eventY/accel_z_thresh_falling_en +What: /sys/.../deviceX:eventY/gyro_x_thresh_rising_en +What: /sys/.../deviceX:eventY/gyro_x_thresh_falling_en +What: /sys/.../deviceX:eventY/gyro_y_thresh_rising_en +What: /sys/.../deviceX:eventY/gyro_y_thresh_falling_en +What: /sys/.../deviceX:eventY/gyro_z_thresh_rising_en +What: /sys/.../deviceX:eventY/gyro_z_thresh_falling_en +What: /sys/.../deviceX:eventY/magn_x_thresh_rising_en +What: /sys/.../deviceX:eventY/magn_x_thresh_falling_en +What: /sys/.../deviceX:eventY/magn_y_thresh_rising_en +What: /sys/.../deviceX:eventY/magn_y_thresh_falling_en +What: /sys/.../deviceX:eventY/magn_z_thresh_rising_en +What: /sys/.../deviceX:eventY/magn_z_thresh_falling_en +What: /sys/.../deviceX:eventY/inZ_supply_thresh_rising_en +What: /sys/.../deviceX:eventY/inZ_supply_thresh_falling_en +What: /sys/.../deviceX:eventY/inZ_thresh_rising_en +What: /sys/.../deviceX:eventY/inZ_thresh_falling_en +What: /sys/.../deviceX:eventY/temp_thresh_rising_en +What: /sys/.../deviceX:eventY/temp_thresh_falling_en KernelVersion: 2.6.37 Contact: linux-iio@vger.kernel.org Description: - Event generated when accel_x0 passes a threshold in the specfied + Event generated when channel passes a threshold in the specified (_rising|_falling) direction. If the direction is not specified, then either the device will report an event which ever direction a single threshold value is called in (e.g. - accel_x0__thresh_value) or - accel_x0__thresh_rising_value and - accel_x0__thresh_falling_value may take different - values, but the device can only enable both thresholds or - neither. + [Z][_name]__thresh_value) or + [Z][_name]__thresh_rising_value and + [Z][_name]__thresh_falling_value may take + different values, but the device can only enable both thresholds + or neither. Note the driver will assume the last p events requested are to be enabled where p is however many it supports (which may vary depending on the exact set requested. So if you want to be @@ -205,186 +282,338 @@ Description: a given event type is enabled a future point (and not those for whatever event was previously enabled). -What: /sys/.../accel_x0__thresh[_rising|_falling]_value +What: /sys/.../deviceX:eventY/accel_x_roc_rising_en +What: /sys/.../deviceX:eventY/accel_x_roc_falling_en +What: /sys/.../deviceX:eventY/accel_y_roc_rising_en +What: /sys/.../deviceX:eventY/accel_y_roc_falling_en +What: /sys/.../deviceX:eventY/accel_z_roc_rising_en +What: /sys/.../deviceX:eventY/accel_z_roc_falling_en +What: /sys/.../deviceX:eventY/gyro_x_roc_rising_en +What: /sys/.../deviceX:eventY/gyro_x_roc_falling_en +What: /sys/.../deviceX:eventY/gyro_y_roc_rising_en +What: /sys/.../deviceX:eventY/gyro_y_roc_falling_en +What: /sys/.../deviceX:eventY/gyro_z_roc_rising_en +What: /sys/.../deviceX:eventY/gyro_z_roc_falling_en +What: /sys/.../deviceX:eventY/magn_x_roc_rising_en +What: /sys/.../deviceX:eventY/magn_x_roc_falling_en +What: /sys/.../deviceX:eventY/magn_y_roc_rising_en +What: /sys/.../deviceX:eventY/magn_y_roc_falling_en +What: /sys/.../deviceX:eventY/magn_z_roc_rising_en +What: /sys/.../deviceX:eventY/magn_z_roc_falling_en +What: /sys/.../deviceX:eventY/inZ_supply_roc_rising_en +What: /sys/.../deviceX:eventY/inZ_supply_roc_falling_en +What: /sys/.../deviceX:eventY/inZ_roc_rising_en +What: /sys/.../deviceX:eventY/inZ_roc_falling_en +What: /sys/.../deviceX:eventY/temp_roc_rising_en +What: /sys/.../deviceX:eventY/temp_roc_falling_en +KernelVersion: 2.6.37 +Contact: linux-iio@vger.kernel.org +Description: + Event generated when channel passes a threshold on the rate of + change (1st differential) in the specified (_rising|_falling) + direction. If the direction is not specified, then either the + device will report an event which ever direction a single + threshold value is called in (e.g. + [Z][_name]__roc_value) or + [Z][_name]__roc_rising_value and + [Z][_name]__roc_falling_value may take + different values, but the device can only enable both rate of + change thresholds or neither. + Note the driver will assume the last p events requested are + to be enabled where p is however many it supports (which may + vary depending on the exact set requested. So if you want to be + sure you have set what you think you have, check the contents of + these attributes after everything is configured. Drivers may + have to buffer any parameters so that they are consistent when + a given event type is enabled a future point (and not those for + whatever event was previously enabled). + +What: /sys/.../deviceX:eventY/accel_x_raw_thresh_rising_value +What: /sys/.../deviceX:eventY/accel_x_raw_thresh_falling_value +What: /sys/.../deviceX:eventY/accel_y_raw_thresh_rising_value +What: /sys/.../deviceX:eventY/accel_y_raw_thresh_falling_value +What: /sys/.../deviceX:eventY/accel_z_raw_thresh_rising_value +What: /sys/.../deviceX:eventY/accel_z_raw_thresh_falling_value +What: /sys/.../deviceX:eventY/gyro_x_raw_thresh_rising_value +What: /sys/.../deviceX:eventY/gyro_x_raw_thresh_falling_value +What: /sys/.../deviceX:eventY/gyro_y_raw_thresh_rising_value +What: /sys/.../deviceX:eventY/gyro_y_raw_thresh_falling_value +What: /sys/.../deviceX:eventY/gyro_z_raw_thresh_rising_value +What: /sys/.../deviceX:eventY/gyro_z_raw_thresh_falling_value +What: /sys/.../deviceX:eventY/magn_x_raw_thresh_rising_value +What: /sys/.../deviceX:eventY/magn_x_raw_thresh_falling_value +What: /sys/.../deviceX:eventY/magn_y_raw_thresh_rising_value +What: /sys/.../deviceX:eventY/magn_y_raw_thresh_falling_value +What: /sys/.../deviceX:eventY/magn_z_raw_thresh_rising_value +What: /sys/.../deviceX:eventY/magn_z_raw_thresh_falling_value +What: /sys/.../deviceX:eventY/inZ_supply_raw_thresh_rising_value +What: /sys/.../deviceX:eventY/inZ_supply_raw_thresh_falling_value +What: /sys/.../deviceX:eventY/inZ_raw_thresh_falling_value +What: /sys/.../deviceX:eventY/inZ_raw_thresh_falling_value +What: /sys/.../deviceX:eventY/temp_raw_thresh_falling_value +What: /sys/.../deviceX:eventY/temp_raw_thresh_falling_value KernelVersion: 2.6.37 Contact: linux-iio@vger.kernel.org Description: Specifies the value of threshold that the device is comparing against for the events enabled by - accel_x0__thresh[_rising|falling]_en. - If seperate exist for the two directions, but direction is - not specified for this attribute, then a single threshold value - applies to both directions. + Z[_name]_thresh[_rising|falling]_en. + If separate attributes exist for the two directions, but + direction is not specified for this attribute, then a single + threshold value applies to both directions. The raw or input element of the name indicates whether the value is in raw device units or in processed units (as _raw and _input do on sysfs direct channel read attributes). -What: /sys/.../accel_x0_thresh[_rising|_falling]_meanperiod +What: /sys/.../deviceX:eventY/accel_x_raw_roc_rising_value +What: /sys/.../deviceX:eventY/accel_x_raw_roc_falling_value +What: /sys/.../deviceX:eventY/accel_y_raw_roc_rising_value +What: /sys/.../deviceX:eventY/accel_y_raw_roc_falling_value +What: /sys/.../deviceX:eventY/accel_z_raw_roc_rising_value +What: /sys/.../deviceX:eventY/accel_z_raw_roc_falling_value +What: /sys/.../deviceX:eventY/gyro_x_raw_roc_rising_value +What: /sys/.../deviceX:eventY/gyro_x_raw_roc_falling_value +What: /sys/.../deviceX:eventY/gyro_y_raw_roc_rising_value +What: /sys/.../deviceX:eventY/gyro_y_raw_roc_falling_value +What: /sys/.../deviceX:eventY/gyro_z_raw_roc_rising_value +What: /sys/.../deviceX:eventY/gyro_z_raw_roc_falling_value +What: /sys/.../deviceX:eventY/magn_x_raw_roc_rising_value +What: /sys/.../deviceX:eventY/magn_x_raw_roc_falling_value +What: /sys/.../deviceX:eventY/magn_y_raw_roc_rising_value +What: /sys/.../deviceX:eventY/magn_y_raw_roc_falling_value +What: /sys/.../deviceX:eventY/magn_z_raw_roc_rising_value +What: /sys/.../deviceX:eventY/magn_z_raw_roc_falling_value +What: /sys/.../deviceX:eventY/inZ_supply_raw_roc_rising_value +What: /sys/.../deviceX:eventY/inZ_supply_raw_roc_falling_value +What: /sys/.../deviceX:eventY/inZ_raw_roc_falling_value +What: /sys/.../deviceX:eventY/inZ_raw_roc_falling_value +What: /sys/.../deviceX:eventY/temp_raw_roc_falling_value +What: /sys/.../deviceX:eventY/temp_raw_roc_falling_value KernelVersion: 2.6.37 Contact: linux-iio@vger.kernel.org Description: - Period of time (in seconds) over which the raw channel value - is averaged before being compared with the threshold set in - accel_x0_thresh[_rising|_falling]_meanperiod. If direction is - not specified then this mean period applies to both directions. + Specifies the value of rate of change threshold that the + device is comparing against for the events enabled by + [Z][_name]_roc[_rising|falling]_en. + If separate attributes exist for the two directions, + but direction is not specified for this attribute, + then a single threshold value applies to both directions. + The raw or input element of the name indicates whether the + value is in raw device units or in processed units (as _raw + and _input do on sysfs direct channel read attributes). -What: /sys/.../accel_x0_thresh[_rising|_falling]_period +What: /sys/.../deviceX:eventY/accel_x_thresh_rising_period +What: /sys/.../deviceX:eventY/accel_x_thresh_falling_period +hat: /sys/.../deviceX:eventY/accel_x_roc_rising_period +What: /sys/.../deviceX:eventY/accel_x_roc_falling_period +What: /sys/.../deviceX:eventY/accel_y_thresh_rising_period +What: /sys/.../deviceX:eventY/accel_y_thresh_falling_period +What: /sys/.../deviceX:eventY/accel_y_roc_rising_period +What: /sys/.../deviceX:eventY/accel_y_roc_falling_period +What: /sys/.../deviceX:eventY/accel_z_thresh_rising_period +What: /sys/.../deviceX:eventY/accel_z_thresh_falling_period +What: /sys/.../deviceX:eventY/accel_z_roc_rising_period +What: /sys/.../deviceX:eventY/accel_z_roc_falling_period +What: /sys/.../deviceX:eventY/gyro_x_thresh_rising_period +What: /sys/.../deviceX:eventY/gyro_x_thresh_falling_period +What: /sys/.../deviceX:eventY/gyro_x_roc_rising_period +What: /sys/.../deviceX:eventY/gyro_x_roc_falling_period +What: /sys/.../deviceX:eventY/gyro_y_thresh_rising_period +What: /sys/.../deviceX:eventY/gyro_y_thresh_falling_period +What: /sys/.../deviceX:eventY/gyro_y_roc_rising_period +What: /sys/.../deviceX:eventY/gyro_y_roc_falling_period +What: /sys/.../deviceX:eventY/gyro_z_thresh_rising_period +What: /sys/.../deviceX:eventY/gyro_z_thresh_falling_period +What: /sys/.../deviceX:eventY/gyro_z_roc_rising_period +What: /sys/.../deviceX:eventY/gyro_z_roc_falling_period +What: /sys/.../deviceX:eventY/magn_x_thresh_rising_period +What: /sys/.../deviceX:eventY/magn_x_thresh_falling_period +What: /sys/.../deviceX:eventY/magn_x_roc_rising_period +What: /sys/.../deviceX:eventY/magn_x_roc_falling_period +What: /sys/.../deviceX:eventY/magn_y_thresh_rising_period +What: /sys/.../deviceX:eventY/magn_y_thresh_falling_period +What: /sys/.../deviceX:eventY/magn_y_roc_rising_period +What: /sys/.../deviceX:eventY/magn_y_roc_falling_period +What: /sys/.../deviceX:eventY/magn_z_thresh_rising_period +What: /sys/.../deviceX:eventY/magn_z_thresh_falling_period +What: /sys/.../deviceX:eventY/magn_z_roc_rising_period +What: /sys/.../deviceX:eventY/magn_z_roc_falling_period +What: /sys/.../deviceX:eventY/inZ_supply_thresh_rising_period +What: /sys/.../deviceX:eventY/inZ_supply_thresh_falling_period +What: /sys/.../deviceX:eventY/inz_supply_roc_rising_period +What: /sys/.../deviceX:eventY/inZ_supply_roc_falling_period +What: /sys/.../deviceX:eventY/inZ_thresh_rising_period +What: /sys/.../deviceX:eventY/inZ_thresh_falling_period +What: /sys/.../deviceX:eventY/inZ_roc_rising_period +What: /sys/.../deviceX:eventY/inZ_roc_falling_period +What: /sys/.../deviceX:eventY/temp_thresh_rising_period +What: /sys/.../deviceX:eventY/temp_thresh_falling_period +What: /sys/.../deviceX:eventY/temp_roc_rising_period +What: /sys/.../deviceX:eventY/temp_roc_falling_period +What: /sys/.../deviceX:eventY/accel_x&y&z_mag_falling_period KernelVersion: 2.6.37 Contact: linux-iio@vger.kernel.org Description: - Period of time (in seconds) for which the threshold must be - passed before an event is generated. If direction is not + Period of time (in seconds) for which the condition must be + met before an event is generated. If direction is not specified then this period applies to both directions. -What: /sys/.../device[n]:event[m]/accel_x0_mag[_rising|_falling]_en +What: /sys/.../deviceX:eventY/accel_mag_en +What: /sys/.../deviceX:eventY/accel_mag_rising_en +What: /sys/.../deviceX:eventY/accel_mag_falling_en +What: /sys/.../deviceX:eventY/accel_x_mag_en +What: /sys/.../deviceX:eventY/accel_x_mag_rising_en +What: /sys/.../deviceX:eventY/accel_x_mag_falling_en +What: /sys/.../deviceX:eventY/accel_y_mag_en +What: /sys/.../deviceX:eventY/accel_y_mag_rising_en +What: /sys/.../deviceX:eventY/accel_y_mag_falling_en +What: /sys/.../deviceX:eventY/accel_z_mag_en +What: /sys/.../deviceX:eventY/accel_z_mag_rising_en +What: /sys/.../deviceX:eventY/accel_z_mag_falling_en +What: /sys/.../deviceX:eventY/accel_x&y&z_mag_rising_en +What: /sys/.../deviceX:eventY/accel_x&y&z_mag_falling_en KernelVersion: 2.6.37 Contact: linux-iio@vger.kernel.org Description: - Similar to accel_x0_thresh[_rising|_falling]_en, but here the + Similar to accel_x_thresh[_rising|_falling]_en, but here the magnitude of the channel is compared to the threshold, not its signed value. -What: /sys/.../accel_x0__mag[_rising|_falling]_value -KernelVersion: 2.6.37 -Contact: linux-iio@vger.kernel.org -Description: - The value to which the magnitude of the channel is compared. - -What: /sys/.../accel_x0_mag[_rising|_falling]_meanperiod -KernelVersion: 2.6.37 -Contact: linux-iio@vger.kernel.org -Description: - Period of time (in seconds) over which the value of the channel - is averaged before being compared to the threshold - -What: /sys/.../accel_x0_mag[_rising|_falling]_period -KernelVersion: 2.6.37 -Contact: linux-iio@vger.kernel.org -Description: - Period of time (in seconds) for which the condition must be true - before an event occurs. - -What: /sys/.../device[n]:event[m]/accel_x0_roc[_rising|_falling]_en +What: /sys/.../accel_raw_mag_value +What: /sys/.../accel_x_raw_mag_rising_value +What: /sys/.../accel_y_raw_mag_rising_value +What: /sys/.../accel_z_raw_mag_rising_value KernelVersion: 2.6.37 Contact: linux-iio@vger.kernel.org Description: - Similar to accel_x0_thresh[_rising|_falling]_en, but here the - first differential is compared with the threshold. + The value to which the magnitude of the channel is compared. If + number or direction is not specified, applies to all channels of + this type. -What: /sys/.../accel_x0__roc[_rising|_falling]_value -KernelVersion: 2.6.37 -Contact: linux-iio@vger.kernel.org -Description: - The value to which the first differential of the channel is - compared. - -What: /sys/.../accel_x0_roc[_rising|_falling]_meanperiod -KernelVersion: 2.6.37 -Contact: linux-iio@vger.kernel.org -Description: - Period of time (in seconds) over which the value of the channel - is averaged before being compared to the threshold - -What: /sys/.../accel_x0_roc[_rising|_falling]_period -KernelVersion: 2.6.37 -Contact: linux-iio@vger.kernel.org -Description: - Period of time (in seconds) for which the condition must be true - before an event occurs. - -What: /sys/.../device[n]/device[n]:buffer:event/dev +What: /sys/bus/iio/devices/deviceX:buffer:event/dev KernelVersion: 2.6.35 Contact: linux-iio@vger.kernel.org Description: - Buffer for device n event character device major:minor numbers. + Buffer for device X event character device major:minor numbers. -What: /sys/.../device[n]/device[n]:buffer:access/dev +What: /sys/bus/iio/devices/deviceX:buffer:access/dev KernelVersion: 2.6.35 Contact: linux-iio@vger.kernel.org Description: - Buffer for device n access character device o major:minor numbers. + Buffer for device X access character device major:minor numbers. -What: /sys/.../device[n]:buffer/trigger +What: /sys/bus/iio/devices/deviceX:buffer/trigger KernelVersion: 2.6.35 Contact: linux-iio@vger.kernel.org Description: The name of the trigger source being used, as per string given - in /sys/class/iio/trigger[n]/name. + in /sys/class/iio/triggerY/name. -What: /sys/.../device[n]:buffer/length +What: /sys/bus/iio/devices/deviceX:buffer/length KernelVersion: 2.6.35 Contact: linux-iio@vger.kernel.org Description: Number of scans contained by the buffer. -What: /sys/.../device[n]:buffer/bytes_per_datum +What: /sys/bus/iio/devices/deviceX:buffer/bytes_per_datum KernelVersion: 2.6.37 Contact: linux-iio@vger.kernel.org Description: Bytes per scan. Due to alignment fun, the scan may be larger than implied directly by the scan_element parameters. -What: /sys/.../device[n]:buffer/enable +What: /sys/bus/iio/devices/deviceX:buffer/enable KernelVersion: 2.6.35 Contact: linux-iio@vger.kernel.org Description: Actually start the buffer capture up. Will start trigger if first device and appropriate. -What: /sys/.../device[n]:buffer/alignment -KernelVersion: 2.6.35 -Contact: linux-iio@vger.kernel.org -Description: - Minimum data alignment. Scan elements larger than this are - aligned to the nearest power of 2 times this. (may not be - true in weird hardware buffers that pack data well) - -What: /sys/.../device[n]/buffer/scan_elements +What: /sys/bus/iio/devices/deviceX:buffer/scan_elements KernelVersion: 2.6.37 Contact: linux-iio@vger.kernel.org Description: Directory containing interfaces for elements that will be captured for a single triggered sample set in the buffer. -What: /sys/.../device[n]/buffer/scan_elements/accel_x0_en +What: /sys/bus/iio/devices/deviceX:buffer/scan_elements/accel_x_en +What: /sys/bus/iio/devices/deviceX:buffer/scan_elements/accel_y_en +What: /sys/bus/iio/devices/deviceX:buffer/scan_elements/accel_z_en +What: /sys/bus/iio/devices/deviceX:buffer/scan_elements/gyro_x_en +What: /sys/bus/iio/devices/deviceX:buffer/scan_elements/gyro_y_en +What: /sys/bus/iio/devices/deviceX:buffer/scan_elements/gyro_z_en +What: /sys/bus/iio/devices/deviceX:buffer/scan_elements/magn_x_en +What: /sys/bus/iio/devices/deviceX:buffer/scan_elements/magn_y_en +What: /sys/bus/iio/devices/deviceX:buffer/scan_elements/magn_z_en +What: /sys/bus/iio/devices/deviceX:buffer/scan_elements/timestamp_en +What: /sys/bus/iio/devices/deviceX:buffer/scan_elements/inY_supply_en +What: /sys/bus/iio/devices/deviceX:buffer/scan_elements/inY_en +What: /sys/bus/iio/devices/deviceX:buffer/scan_elements/inY-inZ_en +What: /sys/bus/iio/devices/deviceX:buffer/scan_elements/incli_x_en +What: /sys/bus/iio/devices/deviceX:buffer/scan_elements/incli_y_en KernelVersion: 2.6.37 Contact: linux-iio@vger.kernel.org Description: Scan element control for triggered data capture. -What: /sys/.../device[n]/buffer/scan_elements/accel[_x0]_type +What: /sys/bus/iio/devices/deviceX:buffer/scan_elements/accel_type +What: /sys/bus/iio/devices/deviceX:buffer/scan_elements/gyro_type +What: /sys/bus/iio/devices/deviceX:buffer/scan_elements/magn_type +What: /sys/bus/iio/devices/deviceX:buffer/scan_elements/incli_type +What: /sys/bus/iio/devices/deviceX:buffer/scan_elements/inY_type +What: /sys/bus/iio/devices/deviceX:buffer/scan_elements/in-in_type +What: /sys/.../deviceX:buffer/scan_elements/inY_supply_type +What: /sys/.../deviceX:buffer/scan_elements/timestamp_type KernelVersion: 2.6.37 Contact: linux-iio@vger.kernel.org Description: Description of the scan element data storage within the buffer - and hence the form in which it is read from userspace. - Form is [s|u]bits/storagebits. s or u specifies if signed - (2's complement) or unsigned. bits is the number of bits of - data and storagebits is the space (after padding) that it - occupies in the buffer. Note that some devices will have - additional information in the unused bits so to get a clean - value, the bits value must be used to mask the buffer output - value appropriately. The storagebits value also specifies the - data alignment. So s48/64 will be a signed 48 bit integer - stored in a 64 bit location aligned to a a64 bit boundary. + and hence the form in which it is read from user-space. + Form is [s|u]bits/storagebits[>>shift]. s or u specifies if + signed (2's complement) or unsigned. bits is the number of bits + of data and storagebits is the space (after padding) that it + occupies in the buffer. shift if specified, is the shift that + needs to be applied prior to masking out unused bits. Some + devices put their data in the middle of the transferred elements + with additional information on both sides. Note that some + devices will have additional information in the unused bits + so to get a clean value, the bits value must be used to mask + the buffer output value appropriately. The storagebits value + also specifies the data alignment. So s48/64>>2 will be a + signed 48 bit integer stored in a 64 bit location aligned to + a a64 bit boundary. To obtain the clean value, shift right 2 + and apply a mask to zero the top 16 bits of the result. For other storage combinations this attribute will be extended appropriately. -What: /sys/.../device[n]/buffer/scan_elements/accel[_x0]_index +What: /sys/.../deviceX:buffer/scan_elements/accel_type_available +KernelVersion: 2.6.37 +Contact: linux-iio@vger.kernel.org +Description: + If the type parameter can take one of a small set of values, + this attribute lists them. + +What: /sys/bus/iio/devices/deviceX:buffer/scan_elements/inY_index +What: /sys/.../deviceX:buffer/scan_elements/inY_supply_index +What: /sys/bus/iio/devices/deviceX:buffer/scan_elements/accel_x_index +What: /sys/bus/iio/devices/deviceX:buffer/scan_elements/accel_y_index +What: /sys/bus/iio/devices/deviceX:buffer/scan_elements/accel_z_index +What: /sys/bus/iio/devices/deviceX:buffer/scan_elements/gyro_x_index +What: /sys/bus/iio/devices/deviceX:buffer/scan_elements/gyro_y_index +What: /sys/bus/iio/devices/deviceX:buffer/scan_elements/gyro_z_index +What: /sys/bus/iio/devices/deviceX:buffer/scan_elements/magn_x_index +What: /sys/bus/iio/devices/deviceX:buffer/scan_elements/magn_y_index +What: /sys/bus/iio/devices/deviceX:buffer/scan_elements/magn_z_index +What: /sys/bus/iio/devices/deviceX:buffer/scan_elements/incli_x_index +What: /sys/bus/iio/devices/deviceX:buffer/scan_elements/incli_y_index +What: /sys/.../deviceX:buffer/scan_elements/timestamp_index KernelVersion: 2.6.37 Contact: linux-iio@vger.kernel.org Description: A single positive integer specifying the position of this - scan element in the buffer. Note these are not dependant on - what is enabled and may not be contiguous. Thus for userspace + scan element in the buffer. Note these are not dependent on + what is enabled and may not be contiguous. Thus for user-space to establish the full layout these must be used in conjunction with all _en attributes to establish which channels are present, and the relevant _type attributes to establish the data storage format. - -What: /sys/.../device[n]/buffer/scan_elements/accel[_x0]_shift -KernelVersion: 2.6.37 -Contact: linux-iio@vger.kernel.org -Description: - A bit shift (to right) that must be applied prior to - extracting the bits specified by accel[_x0]_precision. -- cgit v1.2.3 From d846263da4c6032b7a9440d335794ef8d3e76dfb Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Tue, 23 Nov 2010 11:14:16 +0100 Subject: staging: iio: dac: ad5446: Enable driver support for AD5620/AD5640/AD5660 DA converters Initial support for single channel, 12-/14-/16-Bit nanoDAC with On-Chip Reference staging: iio: dac: ad5446: Fix according to review feedback Review feedback by Jonathan Cameron: Use kernel doc style to document headers. Turn data into a union Add some comments for clarity Signed-off-by: Michael Hennerich Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/dac/Kconfig | 6 +- drivers/staging/iio/dac/ad5446.c | 120 +++++++++++++++++++++++++++++++++------ drivers/staging/iio/dac/ad5446.h | 72 +++++++++++++++++++---- 3 files changed, 167 insertions(+), 31 deletions(-) diff --git a/drivers/staging/iio/dac/Kconfig b/drivers/staging/iio/dac/Kconfig index 9c497ccd3dce..9191bd23cc08 100644 --- a/drivers/staging/iio/dac/Kconfig +++ b/drivers/staging/iio/dac/Kconfig @@ -11,11 +11,11 @@ config AD5624R_SPI AD5664R convertors (DAC). This driver uses the common SPI interface. config AD5446 - tristate "Analog Devices AD5444, AD5446 and AD5541A, AD5512A DAC SPI driver" + tristate "Analog Devices AD5444/6, AD5620/40/60 and AD5541A/12A DAC SPI driver" depends on SPI help - Say yes here to build support for Analog Devices AD5444, AD5446 - and AD5541A, AD5512A DACs. + Say yes here to build support for Analog Devices AD5444, AD5446, + AD5620, AD5640, AD5660 and AD5541A, AD5512A DACs. To compile this driver as a module, choose M here: the module will be called ad5446. diff --git a/drivers/staging/iio/dac/ad5446.c b/drivers/staging/iio/dac/ad5446.c index ac3165b0aeff..4d65d274b1ee 100644 --- a/drivers/staging/iio/dac/ad5446.c +++ b/drivers/staging/iio/dac/ad5446.c @@ -23,6 +23,31 @@ #include "ad5446.h" +static void ad5446_store_sample(struct ad5446_state *st, unsigned val) +{ + st->data.d16 = cpu_to_be16(AD5446_LOAD | + (val << st->chip_info->left_shift)); +} + +static void ad5542_store_sample(struct ad5446_state *st, unsigned val) +{ + st->data.d16 = cpu_to_be16(val << st->chip_info->left_shift); +} + +static void ad5620_store_sample(struct ad5446_state *st, unsigned val) +{ + st->data.d16 = cpu_to_be16(AD5620_LOAD | + (val << st->chip_info->left_shift)); +} + +static void ad5660_store_sample(struct ad5446_state *st, unsigned val) +{ + val |= AD5660_LOAD; + st->data.d24[0] = (val >> 16) & 0xFF; + st->data.d24[1] = (val >> 8) & 0xFF; + st->data.d24[2] = val & 0xFF; +} + static ssize_t ad5446_write(struct device *dev, struct device_attribute *attr, const char *buf, @@ -43,18 +68,7 @@ static ssize_t ad5446_write(struct device *dev, } mutex_lock(&dev_info->mlock); - switch (spi_get_device_id(st->spi)->driver_data) { - case ID_AD5444: - case ID_AD5446: - st->data = cpu_to_be16(AD5446_LOAD | - (val << st->chip_info->left_shift)); - break; - case ID_AD5542A: - case ID_AD5512A: - st->data = cpu_to_be16(val << st->chip_info->left_shift); - break; - } - + st->chip_info->store_sample(st, val); ret = spi_sync(st->spi, &st->msg); mutex_unlock(&dev_info->mlock); @@ -105,24 +119,76 @@ static const struct ad5446_chip_info ad5446_chip_info_tbl[] = { .storagebits = 16, .left_shift = 2, .sign = 'u', /* IIO_SCAN_EL_TYPE_UNSIGNED */ + .store_sample = ad5446_store_sample, }, [ID_AD5446] = { .bits = 14, .storagebits = 16, .left_shift = 0, .sign = 'u', /* IIO_SCAN_EL_TYPE_UNSIGNED */ + .store_sample = ad5446_store_sample, }, [ID_AD5542A] = { .bits = 16, .storagebits = 16, .left_shift = 0, .sign = 'u', /* IIO_SCAN_EL_TYPE_UNSIGNED */ + .store_sample = ad5542_store_sample, }, [ID_AD5512A] = { .bits = 12, .storagebits = 16, .left_shift = 4, .sign = 'u', /* IIO_SCAN_EL_TYPE_UNSIGNED */ + .store_sample = ad5542_store_sample, + }, + [ID_AD5620_2500] = { + .bits = 12, + .storagebits = 16, + .left_shift = 2, + .sign = 'u', /* IIO_SCAN_EL_TYPE_UNSIGNED */ + .int_vref_mv = 2500, + .store_sample = ad5620_store_sample, + }, + [ID_AD5620_1250] = { + .bits = 12, + .storagebits = 16, + .left_shift = 2, + .sign = 'u', /* IIO_SCAN_EL_TYPE_UNSIGNED */ + .int_vref_mv = 1250, + .store_sample = ad5620_store_sample, + }, + [ID_AD5640_2500] = { + .bits = 14, + .storagebits = 16, + .left_shift = 0, + .sign = 'u', /* IIO_SCAN_EL_TYPE_UNSIGNED */ + .int_vref_mv = 2500, + .store_sample = ad5620_store_sample, + }, + [ID_AD5640_1250] = { + .bits = 14, + .storagebits = 16, + .left_shift = 0, + .sign = 'u', /* IIO_SCAN_EL_TYPE_UNSIGNED */ + .int_vref_mv = 1250, + .store_sample = ad5620_store_sample, + }, + [ID_AD5660_2500] = { + .bits = 16, + .storagebits = 24, + .left_shift = 0, + .sign = 'u', /* IIO_SCAN_EL_TYPE_UNSIGNED */ + .int_vref_mv = 2500, + .store_sample = ad5660_store_sample, + }, + [ID_AD5660_1250] = { + .bits = 16, + .storagebits = 24, + .left_shift = 0, + .sign = 'u', /* IIO_SCAN_EL_TYPE_UNSIGNED */ + .int_vref_mv = 1250, + .store_sample = ad5660_store_sample, }, }; @@ -168,16 +234,28 @@ static int __devinit ad5446_probe(struct spi_device *spi) /* Setup default message */ - st->xfer.tx_buf = &st->data, - st->xfer.len = 2, + st->xfer.tx_buf = &st->data; + st->xfer.len = st->chip_info->storagebits / 8; spi_message_init(&st->msg); spi_message_add_tail(&st->xfer, &st->msg); - if (voltage_uv) - st->vref_mv = voltage_uv / 1000; - else - dev_warn(&spi->dev, "reference voltage unspecified\n"); + switch (spi_get_device_id(spi)->driver_data) { + case ID_AD5620_2500: + case ID_AD5620_1250: + case ID_AD5640_2500: + case ID_AD5640_1250: + case ID_AD5660_2500: + case ID_AD5660_1250: + st->vref_mv = st->chip_info->int_vref_mv; + break; + default: + if (voltage_uv) + st->vref_mv = voltage_uv / 1000; + else + dev_warn(&spi->dev, + "reference voltage unspecified\n"); + } ret = iio_device_register(st->indio_dev); if (ret) @@ -217,6 +295,12 @@ static const struct spi_device_id ad5446_id[] = { {"ad5446", ID_AD5446}, {"ad5542a", ID_AD5542A}, {"ad5512a", ID_AD5512A}, + {"ad5620-2500", ID_AD5620_2500}, /* AD5620/40/60: */ + {"ad5620-1250", ID_AD5620_1250}, /* part numbers may look differently */ + {"ad5640-2500", ID_AD5640_2500}, + {"ad5640-1250", ID_AD5640_1250}, + {"ad5660-2500", ID_AD5660_2500}, + {"ad5660-1250", ID_AD5660_1250}, {} }; diff --git a/drivers/staging/iio/dac/ad5446.h b/drivers/staging/iio/dac/ad5446.h index 24a9cda6b997..ca795a9d1866 100644 --- a/drivers/staging/iio/dac/ad5446.h +++ b/drivers/staging/iio/dac/ad5446.h @@ -5,8 +5,8 @@ * * Licensed under the GPL-2 or later. */ -#ifndef IIO_ADC_AD5446_H_ -#define IIO_ADC_AD5446_H_ +#ifndef IIO_DAC_AD5446_H_ +#define IIO_DAC_AD5446_H_ /* DAC Control Bits */ @@ -15,14 +15,30 @@ #define AD5446_NOP (0x2 << 14) /* No operation */ #define AD5446_CLK_RISING (0x3 << 14) /* Clock data on rising edge */ +#define AD5620_LOAD (0x0 << 14) /* Load and update Norm Operation*/ +#define AD5620_PWRDWN_1k (0x1 << 14) /* Power-down: 1kOhm to GND */ +#define AD5620_PWRDWN_100k (0x2 << 14) /* Power-down: 100kOhm to GND */ +#define AD5620_PWRDWN_TRISTATE (0x3 << 14) /* Power-down: Three-state */ + +#define AD5660_LOAD (0x0 << 16) /* Load and update Norm Operation*/ +#define AD5660_PWRDWN_1k (0x1 << 16) /* Power-down: 1kOhm to GND */ +#define AD5660_PWRDWN_100k (0x2 << 16) /* Power-down: 100kOhm to GND */ +#define AD5660_PWRDWN_TRISTATE (0x3 << 16) /* Power-down: Three-state */ + #define RES_MASK(bits) ((1 << (bits)) - 1) -struct ad5446_chip_info { - u8 bits; /* number of DAC bits */ - u8 storagebits; /* number of bits written to the DAC */ - u8 left_shift; /* number of bits the datum must be shifted */ - char sign; /* [s]igned or [u]nsigned */ -}; +/** + * struct ad5446_state - driver instance specific data + * @indio_dev: the industrial I/O device + * @spi: spi_device + * @chip_info: chip model specific constants, available modes etc + * @reg: supply regulator + * @poll_work: bottom half of polling interrupt handler + * @vref_mv: actual reference voltage used + * @xfer: default spi transfer + * @msg: default spi message + * @data: spi transmit buffer + */ struct ad5446_state { struct iio_dev *indio_dev; @@ -33,14 +49,50 @@ struct ad5446_state { unsigned short vref_mv; struct spi_transfer xfer; struct spi_message msg; - unsigned short data; + union { + unsigned short d16; + unsigned char d24[3]; + } data; +}; + +/** + * struct ad5446_chip_info - chip specifc information + * @bits: accuracy of the DAC in bits + * @storagebits: number of bits written to the DAC + * @left_shift: number of bits the datum must be shifted + * @sign: data representation [s]igned or [u]nsigned + * @int_vref_mv: AD5620/40/60: the internal reference voltage + * @store_sample: chip specifc helper function to store the datum + */ + +struct ad5446_chip_info { + u8 bits; + u8 storagebits; + u8 left_shift; + char sign; + u16 int_vref_mv; + void (*store_sample) (struct ad5446_state *st, unsigned val); }; +/** + * ad5446_supported_device_ids: + * The AD5620/40/60 parts are available in different fixed internal reference + * voltage options. The actual part numbers may look differently + * (and a bit cryptic), however this style is used to make clear which + * parts are supported here. + */ + enum ad5446_supported_device_ids { ID_AD5444, ID_AD5446, ID_AD5542A, ID_AD5512A, + ID_AD5620_2500, + ID_AD5620_1250, + ID_AD5640_2500, + ID_AD5640_1250, + ID_AD5660_2500, + ID_AD5660_1250, }; -#endif /* IIO_ADC_AD5446_H_ */ +#endif /* IIO_DAC_AD5446_H_ */ -- cgit v1.2.3 From 4f76548299196e0fd880469a39552ccde797474b Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Tue, 23 Nov 2010 11:40:13 +0100 Subject: staging: iio: dac: ad5446: Remove unused sign member from chip specific information structure Remove unused sign member from chip specific information structure Fix typos Signed-off-by: Michael Hennerich Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/dac/ad5446.c | 10 ---------- drivers/staging/iio/dac/ad5446.h | 6 ++---- 2 files changed, 2 insertions(+), 14 deletions(-) diff --git a/drivers/staging/iio/dac/ad5446.c b/drivers/staging/iio/dac/ad5446.c index 4d65d274b1ee..e3387cd31145 100644 --- a/drivers/staging/iio/dac/ad5446.c +++ b/drivers/staging/iio/dac/ad5446.c @@ -118,35 +118,30 @@ static const struct ad5446_chip_info ad5446_chip_info_tbl[] = { .bits = 12, .storagebits = 16, .left_shift = 2, - .sign = 'u', /* IIO_SCAN_EL_TYPE_UNSIGNED */ .store_sample = ad5446_store_sample, }, [ID_AD5446] = { .bits = 14, .storagebits = 16, .left_shift = 0, - .sign = 'u', /* IIO_SCAN_EL_TYPE_UNSIGNED */ .store_sample = ad5446_store_sample, }, [ID_AD5542A] = { .bits = 16, .storagebits = 16, .left_shift = 0, - .sign = 'u', /* IIO_SCAN_EL_TYPE_UNSIGNED */ .store_sample = ad5542_store_sample, }, [ID_AD5512A] = { .bits = 12, .storagebits = 16, .left_shift = 4, - .sign = 'u', /* IIO_SCAN_EL_TYPE_UNSIGNED */ .store_sample = ad5542_store_sample, }, [ID_AD5620_2500] = { .bits = 12, .storagebits = 16, .left_shift = 2, - .sign = 'u', /* IIO_SCAN_EL_TYPE_UNSIGNED */ .int_vref_mv = 2500, .store_sample = ad5620_store_sample, }, @@ -154,7 +149,6 @@ static const struct ad5446_chip_info ad5446_chip_info_tbl[] = { .bits = 12, .storagebits = 16, .left_shift = 2, - .sign = 'u', /* IIO_SCAN_EL_TYPE_UNSIGNED */ .int_vref_mv = 1250, .store_sample = ad5620_store_sample, }, @@ -162,7 +156,6 @@ static const struct ad5446_chip_info ad5446_chip_info_tbl[] = { .bits = 14, .storagebits = 16, .left_shift = 0, - .sign = 'u', /* IIO_SCAN_EL_TYPE_UNSIGNED */ .int_vref_mv = 2500, .store_sample = ad5620_store_sample, }, @@ -170,7 +163,6 @@ static const struct ad5446_chip_info ad5446_chip_info_tbl[] = { .bits = 14, .storagebits = 16, .left_shift = 0, - .sign = 'u', /* IIO_SCAN_EL_TYPE_UNSIGNED */ .int_vref_mv = 1250, .store_sample = ad5620_store_sample, }, @@ -178,7 +170,6 @@ static const struct ad5446_chip_info ad5446_chip_info_tbl[] = { .bits = 16, .storagebits = 24, .left_shift = 0, - .sign = 'u', /* IIO_SCAN_EL_TYPE_UNSIGNED */ .int_vref_mv = 2500, .store_sample = ad5660_store_sample, }, @@ -186,7 +177,6 @@ static const struct ad5446_chip_info ad5446_chip_info_tbl[] = { .bits = 16, .storagebits = 24, .left_shift = 0, - .sign = 'u', /* IIO_SCAN_EL_TYPE_UNSIGNED */ .int_vref_mv = 1250, .store_sample = ad5660_store_sample, }, diff --git a/drivers/staging/iio/dac/ad5446.h b/drivers/staging/iio/dac/ad5446.h index ca795a9d1866..902542e22c4a 100644 --- a/drivers/staging/iio/dac/ad5446.h +++ b/drivers/staging/iio/dac/ad5446.h @@ -56,20 +56,18 @@ struct ad5446_state { }; /** - * struct ad5446_chip_info - chip specifc information + * struct ad5446_chip_info - chip specific information * @bits: accuracy of the DAC in bits * @storagebits: number of bits written to the DAC * @left_shift: number of bits the datum must be shifted - * @sign: data representation [s]igned or [u]nsigned * @int_vref_mv: AD5620/40/60: the internal reference voltage - * @store_sample: chip specifc helper function to store the datum + * @store_sample: chip specific helper function to store the datum */ struct ad5446_chip_info { u8 bits; u8 storagebits; u8 left_shift; - char sign; u16 int_vref_mv; void (*store_sample) (struct ad5446_state *st, unsigned val); }; -- cgit v1.2.3 From 4f26559156eae1b616ef2d0d168bd25f493e02f4 Mon Sep 17 00:00:00 2001 From: Sven Eckelmann Date: Mon, 22 Nov 2010 00:55:39 +0100 Subject: Staging: batman-adv: Replace Andrew Lunn as Staging maintainer Andrew Lunn didn't submit patches to staging since a while and may not be the right person for new patches. Signed-off-by: Sven Eckelmann Signed-off-by: Greg Kroah-Hartman --- drivers/staging/batman-adv/TODO | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/batman-adv/TODO b/drivers/staging/batman-adv/TODO index 11c384f8b063..7967ffaa833e 100644 --- a/drivers/staging/batman-adv/TODO +++ b/drivers/staging/batman-adv/TODO @@ -9,6 +9,6 @@ Please send all patches to: Marek Lindner Simon Wunderlich - Andrew Lunn + Sven Eckelmann b.a.t.m.a.n@lists.open-mesh.org Greg Kroah-Hartman -- cgit v1.2.3 From 2f1646788f4d3cd2ce5cb24d13096afbd8782665 Mon Sep 17 00:00:00 2001 From: Marek Lindner Date: Mon, 22 Nov 2010 00:55:40 +0100 Subject: Staging: batman-adv: ensure that eth_type_trans gets linear memory eth_type_trans tries to pull data with the length of the ethernet header from the skb. We only ensured that enough data for the first ethernet header and the batman header is available in non-paged memory of the skb and not for the ethernet after the batman header. eth_type_trans would fail sometimes with drivers which don't ensure that all there data is perfectly linearised. Reported-by: Rafal Lesniak Signed-off-by: Marek Lindner Signed-off-by: Sven Eckelmann Signed-off-by: Greg Kroah-Hartman --- drivers/staging/batman-adv/soft-interface.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/drivers/staging/batman-adv/soft-interface.c b/drivers/staging/batman-adv/soft-interface.c index 3904db9ce7b1..0e996181daf7 100644 --- a/drivers/staging/batman-adv/soft-interface.c +++ b/drivers/staging/batman-adv/soft-interface.c @@ -194,14 +194,15 @@ void interface_rx(struct net_device *soft_iface, struct bat_priv *priv = netdev_priv(soft_iface); /* check if enough space is available for pulling, and pull */ - if (!pskb_may_pull(skb, hdr_size)) { - kfree_skb(skb); - return; - } + if (!pskb_may_pull(skb, hdr_size)) + goto dropped; + skb_pull_rcsum(skb, hdr_size); /* skb_set_mac_header(skb, -sizeof(struct ethhdr));*/ /* skb->dev & skb->pkt_type are set here */ + if (unlikely(!pskb_may_pull(skb, ETH_HLEN))) + goto dropped; skb->protocol = eth_type_trans(skb, soft_iface); /* should not be neccesary anymore as we use skb_pull_rcsum() @@ -216,6 +217,11 @@ void interface_rx(struct net_device *soft_iface, soft_iface->last_rx = jiffies; netif_rx(skb); + return; + +dropped: + kfree_skb(skb); + return; } #ifdef HAVE_NET_DEVICE_OPS -- cgit v1.2.3 From 43fc987224a45dc53ccc302df5889230d9587921 Mon Sep 17 00:00:00 2001 From: Sven Eckelmann Date: Mon, 22 Nov 2010 00:55:41 +0100 Subject: Staging: batman-adv: Add new sysfs files to README Signed-off-by: Sven Eckelmann Signed-off-by: Greg Kroah-Hartman --- drivers/staging/batman-adv/README | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/batman-adv/README b/drivers/staging/batman-adv/README index 7c878bb07f3a..77f0cdd5b0dd 100644 --- a/drivers/staging/batman-adv/README +++ b/drivers/staging/batman-adv/README @@ -1,4 +1,4 @@ -[state: 04-09-2010] +[state: 21-11-2010] BATMAN-ADV ---------- @@ -67,7 +67,8 @@ All mesh wide settings can be found in batman's own interface folder: # ls /sys/class/net/bat0/mesh/ -# aggregated_ogms bonding orig_interval vis_mode +# aggregated_ogms bonding fragmentation orig_interval +# vis_mode There is a special folder for debugging informations: @@ -237,4 +238,3 @@ You can also contact the Authors: Marek Lindner Simon Wunderlich - -- cgit v1.2.3 From bd27509f49ab841bc10fd604ccd9e7f9914b7120 Mon Sep 17 00:00:00 2001 From: Sven Eckelmann Date: Mon, 22 Nov 2010 00:55:42 +0100 Subject: Staging: batman-adv: Don't remove interface with spinlock held We call a lot of the netdevice code when holding if_list_lock which will spin the whole time. This is not necessary because we only want to protect the access to the list to be serialized. An extra queue can be used which hold all interfaces which should be removed and then use that queue without any locks for netdevice cleanup. Reported-by: Rafal Lesniak Signed-off-by: Sven Eckelmann Signed-off-by: Greg Kroah-Hartman --- drivers/staging/batman-adv/hard-interface.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/drivers/staging/batman-adv/hard-interface.c b/drivers/staging/batman-adv/hard-interface.c index b68a7e5173be..d85de82f941a 100644 --- a/drivers/staging/batman-adv/hard-interface.c +++ b/drivers/staging/batman-adv/hard-interface.c @@ -463,9 +463,6 @@ static void hardif_remove_interface(struct batman_if *batman_if) return; batman_if->if_status = IF_TO_BE_REMOVED; - - /* caller must take if_list_lock */ - list_del_rcu(&batman_if->list); synchronize_rcu(); sysfs_del_hardif(&batman_if->hardif_obj); hardif_put(batman_if); @@ -474,13 +471,21 @@ static void hardif_remove_interface(struct batman_if *batman_if) void hardif_remove_interfaces(void) { struct batman_if *batman_if, *batman_if_tmp; + struct list_head if_queue; + + INIT_LIST_HEAD(&if_queue); - rtnl_lock(); spin_lock(&if_list_lock); list_for_each_entry_safe(batman_if, batman_if_tmp, &if_list, list) { - hardif_remove_interface(batman_if); + list_del_rcu(&batman_if->list); + list_add_tail(&batman_if->list, &if_queue); } spin_unlock(&if_list_lock); + + rtnl_lock(); + list_for_each_entry_safe(batman_if, batman_if_tmp, &if_queue, list) { + hardif_remove_interface(batman_if); + } rtnl_unlock(); } @@ -507,8 +512,10 @@ static int hard_if_event(struct notifier_block *this, break; case NETDEV_UNREGISTER: spin_lock(&if_list_lock); - hardif_remove_interface(batman_if); + list_del_rcu(&batman_if->list); spin_unlock(&if_list_lock); + + hardif_remove_interface(batman_if); break; case NETDEV_CHANGEMTU: if (batman_if->soft_iface) -- cgit v1.2.3 From b4abfcd4c79ec12340b4c68e3a211badd3c90e20 Mon Sep 17 00:00:00 2001 From: Marek Lindner Date: Mon, 22 Nov 2010 00:55:43 +0100 Subject: Staging: batman-adv: convert batman_if custom refcounting to kref functions Signed-off-by: Marek Lindner Signed-off-by: Sven Eckelmann Signed-off-by: Greg Kroah-Hartman --- drivers/staging/batman-adv/bat_sysfs.c | 12 ++++++------ drivers/staging/batman-adv/hard-interface.c | 30 ++++++++++++++--------------- drivers/staging/batman-adv/hard-interface.h | 14 +++++--------- drivers/staging/batman-adv/types.h | 2 +- 4 files changed, 26 insertions(+), 32 deletions(-) diff --git a/drivers/staging/batman-adv/bat_sysfs.c b/drivers/staging/batman-adv/bat_sysfs.c index bc17fb816300..536f65120edd 100644 --- a/drivers/staging/batman-adv/bat_sysfs.c +++ b/drivers/staging/batman-adv/bat_sysfs.c @@ -413,7 +413,7 @@ static ssize_t show_mesh_iface(struct kobject *kobj, struct attribute *attr, length = sprintf(buff, "%s\n", batman_if->if_status == IF_NOT_IN_USE ? "none" : batman_if->soft_iface->name); - hardif_put(batman_if); + kref_put(&batman_if->refcount, hardif_free_ref); return length; } @@ -436,7 +436,7 @@ static ssize_t store_mesh_iface(struct kobject *kobj, struct attribute *attr, if (strlen(buff) >= IFNAMSIZ) { pr_err("Invalid parameter for 'mesh_iface' setting received: " "interface name too long '%s'\n", buff); - hardif_put(batman_if); + kref_put(&batman_if->refcount, hardif_free_ref); return -EINVAL; } @@ -447,7 +447,7 @@ static ssize_t store_mesh_iface(struct kobject *kobj, struct attribute *attr, if ((batman_if->if_status == status_tmp) || ((batman_if->soft_iface) && (strncmp(batman_if->soft_iface->name, buff, IFNAMSIZ) == 0))) { - hardif_put(batman_if); + kref_put(&batman_if->refcount, hardif_free_ref); return count; } @@ -455,7 +455,7 @@ static ssize_t store_mesh_iface(struct kobject *kobj, struct attribute *attr, rtnl_lock(); hardif_disable_interface(batman_if); rtnl_unlock(); - hardif_put(batman_if); + kref_put(&batman_if->refcount, hardif_free_ref); return count; } @@ -467,7 +467,7 @@ static ssize_t store_mesh_iface(struct kobject *kobj, struct attribute *attr, } ret = hardif_enable_interface(batman_if, buff); - hardif_put(batman_if); + kref_put(&batman_if->refcount, hardif_free_ref); return ret; } @@ -502,7 +502,7 @@ static ssize_t show_iface_status(struct kobject *kobj, struct attribute *attr, break; } - hardif_put(batman_if); + kref_put(&batman_if->refcount, hardif_free_ref); return length; } diff --git a/drivers/staging/batman-adv/hard-interface.c b/drivers/staging/batman-adv/hard-interface.c index d85de82f941a..6d5b74862f23 100644 --- a/drivers/staging/batman-adv/hard-interface.c +++ b/drivers/staging/batman-adv/hard-interface.c @@ -50,7 +50,7 @@ struct batman_if *get_batman_if_by_netdev(struct net_device *net_dev) out: if (batman_if) - hardif_hold(batman_if); + kref_get(&batman_if->refcount); rcu_read_unlock(); return batman_if; @@ -100,7 +100,7 @@ static struct batman_if *get_active_batman_if(struct net_device *soft_iface) out: if (batman_if) - hardif_hold(batman_if); + kref_get(&batman_if->refcount); rcu_read_unlock(); return batman_if; @@ -125,13 +125,13 @@ static void set_primary_if(struct bat_priv *bat_priv, struct batman_if *old_if; if (batman_if) - hardif_hold(batman_if); + kref_get(&batman_if->refcount); old_if = bat_priv->primary_if; bat_priv->primary_if = batman_if; if (old_if) - hardif_put(old_if); + kref_put(&old_if->refcount, hardif_free_ref); if (!bat_priv->primary_if) return; @@ -315,7 +315,7 @@ int hardif_enable_interface(struct batman_if *batman_if, char *iface_name) batman_if->batman_adv_ptype.type = __constant_htons(ETH_P_BATMAN); batman_if->batman_adv_ptype.func = batman_skb_recv; batman_if->batman_adv_ptype.dev = batman_if->net_dev; - hardif_hold(batman_if); + kref_get(&batman_if->refcount); dev_add_pack(&batman_if->batman_adv_ptype); atomic_set(&batman_if->seqno, 1); @@ -374,7 +374,7 @@ void hardif_disable_interface(struct batman_if *batman_if) bat_info(batman_if->soft_iface, "Removing interface: %s\n", batman_if->net_dev->name); dev_remove_pack(&batman_if->batman_adv_ptype); - hardif_put(batman_if); + kref_put(&batman_if->refcount, hardif_free_ref); bat_priv->num_ifaces--; orig_hash_del_if(batman_if, bat_priv->num_ifaces); @@ -386,7 +386,7 @@ void hardif_disable_interface(struct batman_if *batman_if) set_primary_if(bat_priv, new_if); if (new_if) - hardif_put(new_if); + kref_put(&new_if->refcount, hardif_free_ref); } kfree(batman_if->packet_buff); @@ -432,8 +432,7 @@ static struct batman_if *hardif_add_interface(struct net_device *net_dev) batman_if->soft_iface = NULL; batman_if->if_status = IF_NOT_IN_USE; INIT_LIST_HEAD(&batman_if->list); - atomic_set(&batman_if->refcnt, 0); - hardif_hold(batman_if); + kref_init(&batman_if->refcount); check_known_mac_addr(batman_if->net_dev); @@ -442,7 +441,7 @@ static struct batman_if *hardif_add_interface(struct net_device *net_dev) spin_unlock(&if_list_lock); /* extra reference for return */ - hardif_hold(batman_if); + kref_get(&batman_if->refcount); return batman_if; free_if: @@ -465,7 +464,7 @@ static void hardif_remove_interface(struct batman_if *batman_if) batman_if->if_status = IF_TO_BE_REMOVED; synchronize_rcu(); sysfs_del_hardif(&batman_if->hardif_obj); - hardif_put(batman_if); + kref_put(&batman_if->refcount, hardif_free_ref); } void hardif_remove_interfaces(void) @@ -522,10 +521,8 @@ static int hard_if_event(struct notifier_block *this, update_min_mtu(batman_if->soft_iface); break; case NETDEV_CHANGEADDR: - if (batman_if->if_status == IF_NOT_IN_USE) { - hardif_put(batman_if); - goto out; - } + if (batman_if->if_status == IF_NOT_IN_USE) + goto hardif_put; check_known_mac_addr(batman_if->net_dev); update_mac_addresses(batman_if); @@ -537,8 +534,9 @@ static int hard_if_event(struct notifier_block *this, default: break; }; - hardif_put(batman_if); +hardif_put: + kref_put(&batman_if->refcount, hardif_free_ref); out: return NOTIFY_DONE; } diff --git a/drivers/staging/batman-adv/hard-interface.h b/drivers/staging/batman-adv/hard-interface.h index d5508899065b..1d1cd9ff7126 100644 --- a/drivers/staging/batman-adv/hard-interface.h +++ b/drivers/staging/batman-adv/hard-interface.h @@ -42,17 +42,13 @@ int batman_skb_recv(struct sk_buff *skb, int hardif_min_mtu(struct net_device *soft_iface); void update_min_mtu(struct net_device *soft_iface); -static inline void hardif_hold(struct batman_if *batman_if) +static inline void hardif_free_ref(struct kref *refcount) { - atomic_inc(&batman_if->refcnt); -} + struct batman_if *batman_if; -static inline void hardif_put(struct batman_if *batman_if) -{ - if (atomic_dec_and_test(&batman_if->refcnt)) { - dev_put(batman_if->net_dev); - kfree(batman_if); - } + batman_if = container_of(refcount, struct batman_if, refcount); + dev_put(batman_if->net_dev); + kfree(batman_if); } #endif /* _NET_BATMAN_ADV_HARD_INTERFACE_H_ */ diff --git a/drivers/staging/batman-adv/types.h b/drivers/staging/batman-adv/types.h index f3f7366231e7..d89ec70a67a8 100644 --- a/drivers/staging/batman-adv/types.h +++ b/drivers/staging/batman-adv/types.h @@ -43,7 +43,7 @@ struct batman_if { unsigned char *packet_buff; int packet_len; struct kobject *hardif_obj; - atomic_t refcnt; + struct kref refcount; struct packet_type batman_adv_ptype; struct net_device *soft_iface; }; -- cgit v1.2.3 From 3f427604d669031343af8e6ecd8d1cc7a6408ab2 Mon Sep 17 00:00:00 2001 From: Marek Lindner Date: Mon, 22 Nov 2010 00:55:44 +0100 Subject: Staging: batman-adv: use rcu callbacks when freeing batman_if Signed-off-by: Marek Lindner Signed-off-by: Sven Eckelmann Signed-off-by: Greg Kroah-Hartman --- drivers/staging/batman-adv/hard-interface.c | 12 ++++++++++-- drivers/staging/batman-adv/hard-interface.h | 1 - drivers/staging/batman-adv/types.h | 1 + 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/drivers/staging/batman-adv/hard-interface.c b/drivers/staging/batman-adv/hard-interface.c index 6d5b74862f23..c2ff29432a5e 100644 --- a/drivers/staging/batman-adv/hard-interface.c +++ b/drivers/staging/batman-adv/hard-interface.c @@ -36,6 +36,15 @@ /* protect update critical side of if_list - but not the content */ static DEFINE_SPINLOCK(if_list_lock); +static void hardif_free_rcu(struct rcu_head *rcu) +{ + struct batman_if *batman_if; + + batman_if = container_of(rcu, struct batman_if, rcu); + dev_put(batman_if->net_dev); + kref_put(&batman_if->refcount, hardif_free_ref); +} + struct batman_if *get_batman_if_by_netdev(struct net_device *net_dev) { struct batman_if *batman_if; @@ -462,9 +471,8 @@ static void hardif_remove_interface(struct batman_if *batman_if) return; batman_if->if_status = IF_TO_BE_REMOVED; - synchronize_rcu(); sysfs_del_hardif(&batman_if->hardif_obj); - kref_put(&batman_if->refcount, hardif_free_ref); + call_rcu(&batman_if->rcu, hardif_free_rcu); } void hardif_remove_interfaces(void) diff --git a/drivers/staging/batman-adv/hard-interface.h b/drivers/staging/batman-adv/hard-interface.h index 1d1cd9ff7126..30ec3b8db459 100644 --- a/drivers/staging/batman-adv/hard-interface.h +++ b/drivers/staging/batman-adv/hard-interface.h @@ -47,7 +47,6 @@ static inline void hardif_free_ref(struct kref *refcount) struct batman_if *batman_if; batman_if = container_of(refcount, struct batman_if, refcount); - dev_put(batman_if->net_dev); kfree(batman_if); } diff --git a/drivers/staging/batman-adv/types.h b/drivers/staging/batman-adv/types.h index d89ec70a67a8..8f6ba1c56927 100644 --- a/drivers/staging/batman-adv/types.h +++ b/drivers/staging/batman-adv/types.h @@ -46,6 +46,7 @@ struct batman_if { struct kref refcount; struct packet_type batman_adv_ptype; struct net_device *soft_iface; + struct rcu_head rcu; }; /** -- cgit v1.2.3 From 49b588e79f7c85aec05008a945fdf17d281e83f9 Mon Sep 17 00:00:00 2001 From: Andreas Langer Date: Mon, 22 Nov 2010 00:55:45 +0100 Subject: Staging: batman-adv: restructure fragmentation to handle batman unicast packets The unicast_frag_send_skb() function expected 'raw' packets (without any batman-adv header) to fragment them. This needs to be changed, so that this function is able to fragment packets that already traveled inside the mesh but need to be fragmented now. Signed-off-by: Andreas Langer Signed-off-by: Sven Eckelmann Signed-off-by: Greg Kroah-Hartman --- drivers/staging/batman-adv/unicast.c | 66 ++++++++++++++++++++---------------- 1 file changed, 36 insertions(+), 30 deletions(-) diff --git a/drivers/staging/batman-adv/unicast.c b/drivers/staging/batman-adv/unicast.c index 0459413ff67f..58bf2b6201bf 100644 --- a/drivers/staging/batman-adv/unicast.c +++ b/drivers/staging/batman-adv/unicast.c @@ -152,55 +152,58 @@ void frag_list_free(struct list_head *head) return; } -static int unicast_send_frag_skb(struct sk_buff *skb, struct bat_priv *bat_priv, - struct batman_if *batman_if, uint8_t dstaddr[], - struct orig_node *orig_node) +static int frag_send_skb(struct sk_buff *skb, struct bat_priv *bat_priv, + struct batman_if *batman_if, uint8_t dstaddr[]) { - struct unicast_frag_packet *ucast_frag1, *ucast_frag2; - int hdr_len = sizeof(struct unicast_frag_packet); + struct unicast_packet tmp_uc, *unicast_packet; struct sk_buff *frag_skb; + struct unicast_frag_packet *frag1, *frag2; + int uc_hdr_len = sizeof(struct unicast_packet); + int ucf_hdr_len = sizeof(struct unicast_frag_packet); int data_len = skb->len; if (!bat_priv->primary_if) goto dropped; - frag_skb = dev_alloc_skb(data_len - (data_len / 2) + hdr_len); + unicast_packet = (struct unicast_packet *) skb->data; + + memcpy(&tmp_uc, unicast_packet, uc_hdr_len); + frag_skb = dev_alloc_skb(data_len - (data_len / 2) + ucf_hdr_len); skb_split(skb, frag_skb, data_len / 2); - if (my_skb_head_push(frag_skb, hdr_len) < 0 || - my_skb_head_push(skb, hdr_len) < 0) + if (my_skb_head_push(skb, ucf_hdr_len - uc_hdr_len) < 0 || + my_skb_head_push(frag_skb, ucf_hdr_len) < 0) goto drop_frag; - ucast_frag1 = (struct unicast_frag_packet *)skb->data; - ucast_frag2 = (struct unicast_frag_packet *)frag_skb->data; + frag1 = (struct unicast_frag_packet *)skb->data; + frag2 = (struct unicast_frag_packet *)frag_skb->data; - ucast_frag1->version = COMPAT_VERSION; - ucast_frag1->packet_type = BAT_UNICAST_FRAG; - ucast_frag1->ttl = TTL; - memcpy(ucast_frag1->orig, - bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN); - memcpy(ucast_frag1->dest, orig_node->orig, ETH_ALEN); + memcpy(frag1, &tmp_uc, sizeof(struct unicast_packet)); - memcpy(ucast_frag2, ucast_frag1, sizeof(struct unicast_frag_packet)); + frag1->ttl--; + frag1->version = COMPAT_VERSION; + frag1->packet_type = BAT_UNICAST_FRAG; - ucast_frag1->flags |= UNI_FRAG_HEAD; - ucast_frag2->flags &= ~UNI_FRAG_HEAD; + memcpy(frag1->orig, bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN); + memcpy(frag2, frag1, sizeof(struct unicast_frag_packet)); - ucast_frag1->seqno = htons((uint16_t)atomic_inc_return( - &batman_if->frag_seqno)); + frag1->flags |= UNI_FRAG_HEAD; + frag2->flags &= ~UNI_FRAG_HEAD; - ucast_frag2->seqno = htons((uint16_t)atomic_inc_return( - &batman_if->frag_seqno)); + frag1->seqno = htons((uint16_t)atomic_inc_return( + &batman_if->frag_seqno)); + frag2->seqno = htons((uint16_t)atomic_inc_return( + &batman_if->frag_seqno)); send_skb_packet(skb, batman_if, dstaddr); send_skb_packet(frag_skb, batman_if, dstaddr); - return 0; + return NET_RX_SUCCESS; drop_frag: kfree_skb(frag_skb); dropped: kfree_skb(skb); - return 1; + return NET_RX_DROP; } int unicast_send_skb(struct sk_buff *skb, struct bat_priv *bat_priv) @@ -240,11 +243,6 @@ int unicast_send_skb(struct sk_buff *skb, struct bat_priv *bat_priv) if (batman_if->if_status != IF_ACTIVE) goto dropped; - if (atomic_read(&bat_priv->frag_enabled) && - data_len + sizeof(struct unicast_packet) > batman_if->net_dev->mtu) - return unicast_send_frag_skb(skb, bat_priv, batman_if, - dstaddr, orig_node); - if (my_skb_head_push(skb, sizeof(struct unicast_packet)) < 0) goto dropped; @@ -258,6 +256,14 @@ int unicast_send_skb(struct sk_buff *skb, struct bat_priv *bat_priv) /* copy the destination for faster routing */ memcpy(unicast_packet->dest, orig_node->orig, ETH_ALEN); + if (atomic_read(&bat_priv->frag_enabled) && + data_len + sizeof(struct unicast_packet) > + batman_if->net_dev->mtu) { + /* send frag skb decreases ttl */ + unicast_packet->ttl++; + return frag_send_skb(skb, bat_priv, batman_if, + dstaddr); + } send_skb_packet(skb, batman_if, dstaddr); return 0; -- cgit v1.2.3 From 8bbde32cf5bd9dbe2f53d562f563b465c0829b23 Mon Sep 17 00:00:00 2001 From: Andreas Langer Date: Mon, 22 Nov 2010 00:55:46 +0100 Subject: Staging: batman-adv: add frag_ prefix to all fragmentation related functions Signed-off-by: Andreas Langer Signed-off-by: Sven Eckelmann Signed-off-by: Greg Kroah-Hartman --- drivers/staging/batman-adv/routing.c | 8 ++++---- drivers/staging/batman-adv/unicast.c | 8 ++++---- drivers/staging/batman-adv/unicast.h | 8 ++++---- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/staging/batman-adv/routing.c b/drivers/staging/batman-adv/routing.c index 657b69e6b957..295e92e49429 100644 --- a/drivers/staging/batman-adv/routing.c +++ b/drivers/staging/batman-adv/routing.c @@ -1231,24 +1231,24 @@ int recv_ucast_frag_packet(struct sk_buff *skb, struct batman_if *recv_if) orig_node->last_frag_packet = jiffies; if (list_empty(&orig_node->frag_list) && - create_frag_buffer(&orig_node->frag_list)) { + frag_create_buffer(&orig_node->frag_list)) { spin_unlock_irqrestore(&bat_priv->orig_hash_lock, flags); return NET_RX_DROP; } tmp_frag_entry = - search_frag_packet(&orig_node->frag_list, + frag_search_packet(&orig_node->frag_list, unicast_packet); if (!tmp_frag_entry) { - create_frag_entry(&orig_node->frag_list, skb); + frag_create_entry(&orig_node->frag_list, skb); spin_unlock_irqrestore(&bat_priv->orig_hash_lock, flags); return NET_RX_SUCCESS; } - skb = merge_frag_packet(&orig_node->frag_list, + skb = frag_merge_packet(&orig_node->frag_list, tmp_frag_entry, skb); spin_unlock_irqrestore(&bat_priv->orig_hash_lock, flags); if (!skb) diff --git a/drivers/staging/batman-adv/unicast.c b/drivers/staging/batman-adv/unicast.c index 58bf2b6201bf..fef8521235f1 100644 --- a/drivers/staging/batman-adv/unicast.c +++ b/drivers/staging/batman-adv/unicast.c @@ -29,7 +29,7 @@ #include "hard-interface.h" -struct sk_buff *merge_frag_packet(struct list_head *head, +struct sk_buff *frag_merge_packet(struct list_head *head, struct frag_packet_list_entry *tfp, struct sk_buff *skb) { @@ -62,7 +62,7 @@ struct sk_buff *merge_frag_packet(struct list_head *head, return skb; } -void create_frag_entry(struct list_head *head, struct sk_buff *skb) +void frag_create_entry(struct list_head *head, struct sk_buff *skb) { struct frag_packet_list_entry *tfp; struct unicast_frag_packet *up = @@ -78,7 +78,7 @@ void create_frag_entry(struct list_head *head, struct sk_buff *skb) return; } -int create_frag_buffer(struct list_head *head) +int frag_create_buffer(struct list_head *head) { int i; struct frag_packet_list_entry *tfp; @@ -99,7 +99,7 @@ int create_frag_buffer(struct list_head *head) return 0; } -struct frag_packet_list_entry *search_frag_packet(struct list_head *head, +struct frag_packet_list_entry *frag_search_packet(struct list_head *head, struct unicast_frag_packet *up) { struct frag_packet_list_entry *tfp; diff --git a/drivers/staging/batman-adv/unicast.h b/drivers/staging/batman-adv/unicast.h index 797369771900..b50d61b83600 100644 --- a/drivers/staging/batman-adv/unicast.h +++ b/drivers/staging/batman-adv/unicast.h @@ -25,13 +25,13 @@ #define FRAG_TIMEOUT 10000 /* purge frag list entrys after time in ms */ #define FRAG_BUFFER_SIZE 6 /* number of list elements in buffer */ -struct sk_buff *merge_frag_packet(struct list_head *head, +struct sk_buff *frag_merge_packet(struct list_head *head, struct frag_packet_list_entry *tfp, struct sk_buff *skb); -void create_frag_entry(struct list_head *head, struct sk_buff *skb); -int create_frag_buffer(struct list_head *head); -struct frag_packet_list_entry *search_frag_packet(struct list_head *head, +void frag_create_entry(struct list_head *head, struct sk_buff *skb); +int frag_create_buffer(struct list_head *head); +struct frag_packet_list_entry *frag_search_packet(struct list_head *head, struct unicast_frag_packet *up); void frag_list_free(struct list_head *head); int unicast_send_skb(struct sk_buff *skb, struct bat_priv *bat_priv); -- cgit v1.2.3 From f3cc7595d242a22a9ffba91979d2cd4e4e815424 Mon Sep 17 00:00:00 2001 From: Andreas Langer Date: Mon, 22 Nov 2010 00:55:47 +0100 Subject: Staging: batman-adv: move skb reassembly of fragmented packets into dedicated function Signed-off-by: Andreas Langer Signed-off-by: Sven Eckelmann Signed-off-by: Greg Kroah-Hartman --- drivers/staging/batman-adv/routing.c | 43 ++++------------------- drivers/staging/batman-adv/unicast.c | 66 ++++++++++++++++++++++++++++++++---- drivers/staging/batman-adv/unicast.h | 10 ++---- 3 files changed, 69 insertions(+), 50 deletions(-) diff --git a/drivers/staging/batman-adv/routing.c b/drivers/staging/batman-adv/routing.c index 295e92e49429..d36c3f932d8c 100644 --- a/drivers/staging/batman-adv/routing.c +++ b/drivers/staging/batman-adv/routing.c @@ -1204,10 +1204,9 @@ int recv_ucast_frag_packet(struct sk_buff *skb, struct batman_if *recv_if) { struct bat_priv *bat_priv = netdev_priv(recv_if->soft_iface); struct unicast_frag_packet *unicast_packet; - struct orig_node *orig_node; - struct frag_packet_list_entry *tmp_frag_entry; int hdr_size = sizeof(struct unicast_frag_packet); - unsigned long flags; + struct sk_buff *new_skb = NULL; + int ret; if (check_unicast_packet(skb, hdr_size) < 0) return NET_RX_DROP; @@ -1217,44 +1216,16 @@ int recv_ucast_frag_packet(struct sk_buff *skb, struct batman_if *recv_if) /* packet for me */ if (is_my_mac(unicast_packet->dest)) { - spin_lock_irqsave(&bat_priv->orig_hash_lock, flags); - orig_node = ((struct orig_node *) - hash_find(bat_priv->orig_hash, unicast_packet->orig)); - - if (!orig_node) { - pr_debug("couldn't find orig node for fragmentation\n"); - spin_unlock_irqrestore(&bat_priv->orig_hash_lock, - flags); - return NET_RX_DROP; - } - - orig_node->last_frag_packet = jiffies; + ret = frag_reassemble_skb(skb, bat_priv, &new_skb); - if (list_empty(&orig_node->frag_list) && - frag_create_buffer(&orig_node->frag_list)) { - spin_unlock_irqrestore(&bat_priv->orig_hash_lock, - flags); + if (ret == NET_RX_DROP) return NET_RX_DROP; - } - - tmp_frag_entry = - frag_search_packet(&orig_node->frag_list, - unicast_packet); - if (!tmp_frag_entry) { - frag_create_entry(&orig_node->frag_list, skb); - spin_unlock_irqrestore(&bat_priv->orig_hash_lock, - flags); + /* packet was buffered for late merge */ + if (!new_skb) return NET_RX_SUCCESS; - } - skb = frag_merge_packet(&orig_node->frag_list, - tmp_frag_entry, skb); - spin_unlock_irqrestore(&bat_priv->orig_hash_lock, flags); - if (!skb) - return NET_RX_DROP; - - interface_rx(recv_if->soft_iface, skb, hdr_size); + interface_rx(recv_if->soft_iface, new_skb, hdr_size); return NET_RX_SUCCESS; } diff --git a/drivers/staging/batman-adv/unicast.c b/drivers/staging/batman-adv/unicast.c index fef8521235f1..57fe2de627a1 100644 --- a/drivers/staging/batman-adv/unicast.c +++ b/drivers/staging/batman-adv/unicast.c @@ -29,9 +29,9 @@ #include "hard-interface.h" -struct sk_buff *frag_merge_packet(struct list_head *head, - struct frag_packet_list_entry *tfp, - struct sk_buff *skb) +static struct sk_buff *frag_merge_packet(struct list_head *head, + struct frag_packet_list_entry *tfp, + struct sk_buff *skb) { struct unicast_frag_packet *up = (struct unicast_frag_packet *)skb->data; @@ -62,7 +62,7 @@ struct sk_buff *frag_merge_packet(struct list_head *head, return skb; } -void frag_create_entry(struct list_head *head, struct sk_buff *skb) +static void frag_create_entry(struct list_head *head, struct sk_buff *skb) { struct frag_packet_list_entry *tfp; struct unicast_frag_packet *up = @@ -78,7 +78,7 @@ void frag_create_entry(struct list_head *head, struct sk_buff *skb) return; } -int frag_create_buffer(struct list_head *head) +static int frag_create_buffer(struct list_head *head) { int i; struct frag_packet_list_entry *tfp; @@ -99,7 +99,7 @@ int frag_create_buffer(struct list_head *head) return 0; } -struct frag_packet_list_entry *frag_search_packet(struct list_head *head, +static struct frag_packet_list_entry *frag_search_packet(struct list_head *head, struct unicast_frag_packet *up) { struct frag_packet_list_entry *tfp; @@ -152,6 +152,60 @@ void frag_list_free(struct list_head *head) return; } +/* frag_reassemble_skb(): + * returns NET_RX_DROP if the operation failed - skb is left intact + * returns NET_RX_SUCCESS if the fragment was buffered (skb_new will be NULL) + * or the skb could be reassembled (skb_new will point to the new packet and + * skb was freed) + */ +int frag_reassemble_skb(struct sk_buff *skb, struct bat_priv *bat_priv, + struct sk_buff **new_skb) +{ + unsigned long flags; + struct orig_node *orig_node; + struct frag_packet_list_entry *tmp_frag_entry; + int ret = NET_RX_DROP; + struct unicast_frag_packet *unicast_packet = + (struct unicast_frag_packet *)skb->data; + + *new_skb = NULL; + spin_lock_irqsave(&bat_priv->orig_hash_lock, flags); + orig_node = ((struct orig_node *) + hash_find(bat_priv->orig_hash, unicast_packet->orig)); + + if (!orig_node) { + pr_debug("couldn't find originator in orig_hash\n"); + goto out; + } + + orig_node->last_frag_packet = jiffies; + + if (list_empty(&orig_node->frag_list) && + frag_create_buffer(&orig_node->frag_list)) { + pr_debug("couldn't create frag buffer\n"); + goto out; + } + + tmp_frag_entry = frag_search_packet(&orig_node->frag_list, + unicast_packet); + + if (!tmp_frag_entry) { + frag_create_entry(&orig_node->frag_list, skb); + ret = NET_RX_SUCCESS; + goto out; + } + + *new_skb = frag_merge_packet(&orig_node->frag_list, tmp_frag_entry, + skb); + /* if not, merge failed */ + if (*new_skb) + ret = NET_RX_SUCCESS; +out: + spin_unlock_irqrestore(&bat_priv->orig_hash_lock, flags); + + return ret; +} + static int frag_send_skb(struct sk_buff *skb, struct bat_priv *bat_priv, struct batman_if *batman_if, uint8_t dstaddr[]) { diff --git a/drivers/staging/batman-adv/unicast.h b/drivers/staging/batman-adv/unicast.h index b50d61b83600..5908b01fb1c5 100644 --- a/drivers/staging/batman-adv/unicast.h +++ b/drivers/staging/batman-adv/unicast.h @@ -25,14 +25,8 @@ #define FRAG_TIMEOUT 10000 /* purge frag list entrys after time in ms */ #define FRAG_BUFFER_SIZE 6 /* number of list elements in buffer */ -struct sk_buff *frag_merge_packet(struct list_head *head, - struct frag_packet_list_entry *tfp, - struct sk_buff *skb); - -void frag_create_entry(struct list_head *head, struct sk_buff *skb); -int frag_create_buffer(struct list_head *head); -struct frag_packet_list_entry *frag_search_packet(struct list_head *head, - struct unicast_frag_packet *up); +int frag_reassemble_skb(struct sk_buff *skb, struct bat_priv *bat_priv, + struct sk_buff **new_skb); void frag_list_free(struct list_head *head); int unicast_send_skb(struct sk_buff *skb, struct bat_priv *bat_priv); -- cgit v1.2.3 From b8cd75445e842b11a0a8ff1e763303a575c21c77 Mon Sep 17 00:00:00 2001 From: Andreas Langer Date: Mon, 22 Nov 2010 00:55:48 +0100 Subject: Staging: batman-adv: remove redundant is_my_mac() check in route_unicast_packet Callers should check the if the received packet is for us before it calls route_unicast_packet. Signed-off-by: Andreas Langer Signed-off-by: Sven Eckelmann Signed-off-by: Greg Kroah-Hartman --- drivers/staging/batman-adv/routing.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/drivers/staging/batman-adv/routing.c b/drivers/staging/batman-adv/routing.c index d36c3f932d8c..9b61d6bc37d6 100644 --- a/drivers/staging/batman-adv/routing.c +++ b/drivers/staging/batman-adv/routing.c @@ -1131,12 +1131,6 @@ static int route_unicast_packet(struct sk_buff *skb, unicast_packet = (struct unicast_packet *)skb->data; - /* packet for me */ - if (is_my_mac(unicast_packet->dest)) { - interface_rx(recv_if->soft_iface, skb, hdr_size); - return NET_RX_SUCCESS; - } - /* TTL exceeded */ if (unicast_packet->ttl < 2) { pr_debug("Warning - can't forward unicast packet from %pM to " @@ -1170,7 +1164,6 @@ static int route_unicast_packet(struct sk_buff *skb, return NET_RX_DROP; unicast_packet = (struct unicast_packet *)skb->data; - ethhdr = (struct ethhdr *)skb_mac_header(skb); /* decrement ttl */ unicast_packet->ttl--; -- cgit v1.2.3 From 9061109ab18352c73b5dda426043dbb6d5e2dae7 Mon Sep 17 00:00:00 2001 From: Andreas Langer Date: Mon, 22 Nov 2010 00:55:49 +0100 Subject: Staging: batman-adv: fragment forwarded packets If a packet is too big to be forwarded over an interface it will be fragmented on-the-fly (if fragmentation is enabled). Signed-off-by: Andreas Langer Signed-off-by: Sven Eckelmann Signed-off-by: Greg Kroah-Hartman --- drivers/staging/batman-adv/routing.c | 6 ++++++ drivers/staging/batman-adv/unicast.c | 4 ++-- drivers/staging/batman-adv/unicast.h | 2 ++ 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/drivers/staging/batman-adv/routing.c b/drivers/staging/batman-adv/routing.c index 9b61d6bc37d6..1e101113b6ff 100644 --- a/drivers/staging/batman-adv/routing.c +++ b/drivers/staging/batman-adv/routing.c @@ -1165,6 +1165,12 @@ static int route_unicast_packet(struct sk_buff *skb, unicast_packet = (struct unicast_packet *)skb->data; + if (unicast_packet->packet_type == BAT_UNICAST && + atomic_read(&bat_priv->frag_enabled) && + skb->len > batman_if->net_dev->mtu) + return frag_send_skb(skb, bat_priv, batman_if, + dstaddr); + /* decrement ttl */ unicast_packet->ttl--; diff --git a/drivers/staging/batman-adv/unicast.c b/drivers/staging/batman-adv/unicast.c index 57fe2de627a1..12afae618ce2 100644 --- a/drivers/staging/batman-adv/unicast.c +++ b/drivers/staging/batman-adv/unicast.c @@ -206,8 +206,8 @@ out: return ret; } -static int frag_send_skb(struct sk_buff *skb, struct bat_priv *bat_priv, - struct batman_if *batman_if, uint8_t dstaddr[]) +int frag_send_skb(struct sk_buff *skb, struct bat_priv *bat_priv, + struct batman_if *batman_if, uint8_t dstaddr[]) { struct unicast_packet tmp_uc, *unicast_packet; struct sk_buff *frag_skb; diff --git a/drivers/staging/batman-adv/unicast.h b/drivers/staging/batman-adv/unicast.h index 5908b01fb1c5..e32b7867a9a4 100644 --- a/drivers/staging/batman-adv/unicast.h +++ b/drivers/staging/batman-adv/unicast.h @@ -29,5 +29,7 @@ int frag_reassemble_skb(struct sk_buff *skb, struct bat_priv *bat_priv, struct sk_buff **new_skb); void frag_list_free(struct list_head *head); int unicast_send_skb(struct sk_buff *skb, struct bat_priv *bat_priv); +int frag_send_skb(struct sk_buff *skb, struct bat_priv *bat_priv, + struct batman_if *batman_if, uint8_t dstaddr[]); #endif /* _NET_BATMAN_ADV_UNICAST_H_ */ -- cgit v1.2.3 From 225f7b0b950d141819a8d9694141571b349e563d Mon Sep 17 00:00:00 2001 From: Andreas Langer Date: Mon, 22 Nov 2010 00:55:50 +0100 Subject: Staging: batman-adv: reassemble fragmented skb if mtu allows it Signed-off-by: Andreas Langer Signed-off-by: Sven Eckelmann Signed-off-by: Greg Kroah-Hartman --- drivers/staging/batman-adv/routing.c | 21 ++++++++++++++++++++- drivers/staging/batman-adv/unicast.c | 8 ++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/drivers/staging/batman-adv/routing.c b/drivers/staging/batman-adv/routing.c index 1e101113b6ff..750cec708244 100644 --- a/drivers/staging/batman-adv/routing.c +++ b/drivers/staging/batman-adv/routing.c @@ -1128,6 +1128,8 @@ static int route_unicast_packet(struct sk_buff *skb, unsigned long flags; struct unicast_packet *unicast_packet; struct ethhdr *ethhdr = (struct ethhdr *)skb_mac_header(skb); + int ret; + struct sk_buff *new_skb; unicast_packet = (struct unicast_packet *)skb->data; @@ -1171,6 +1173,22 @@ static int route_unicast_packet(struct sk_buff *skb, return frag_send_skb(skb, bat_priv, batman_if, dstaddr); + if (unicast_packet->packet_type == BAT_UNICAST_FRAG && + 2 * skb->len - hdr_size <= batman_if->net_dev->mtu) { + + ret = frag_reassemble_skb(skb, bat_priv, &new_skb); + + if (ret == NET_RX_DROP) + return NET_RX_DROP; + + /* packet was buffered for late merge */ + if (!new_skb) + return NET_RX_SUCCESS; + + skb = new_skb; + unicast_packet = (struct unicast_packet *) skb->data; + } + /* decrement ttl */ unicast_packet->ttl--; @@ -1224,7 +1242,8 @@ int recv_ucast_frag_packet(struct sk_buff *skb, struct batman_if *recv_if) if (!new_skb) return NET_RX_SUCCESS; - interface_rx(recv_if->soft_iface, new_skb, hdr_size); + interface_rx(recv_if->soft_iface, new_skb, + sizeof(struct unicast_packet)); return NET_RX_SUCCESS; } diff --git a/drivers/staging/batman-adv/unicast.c b/drivers/staging/batman-adv/unicast.c index 12afae618ce2..e58e634c2806 100644 --- a/drivers/staging/batman-adv/unicast.c +++ b/drivers/staging/batman-adv/unicast.c @@ -36,6 +36,9 @@ static struct sk_buff *frag_merge_packet(struct list_head *head, struct unicast_frag_packet *up = (struct unicast_frag_packet *)skb->data; struct sk_buff *tmp_skb; + struct unicast_packet *unicast_packet; + int hdr_len = sizeof(struct unicast_packet), + uni_diff = sizeof(struct unicast_frag_packet) - hdr_len; /* set skb to the first part and tmp_skb to the second part */ if (up->flags & UNI_FRAG_HEAD) { @@ -59,6 +62,11 @@ static struct sk_buff *frag_merge_packet(struct list_head *head, memcpy(skb_put(skb, tmp_skb->len), tmp_skb->data, tmp_skb->len); kfree_skb(tmp_skb); + + memmove(skb->data + uni_diff, skb->data, hdr_len); + unicast_packet = (struct unicast_packet *) skb_pull(skb, uni_diff); + unicast_packet->packet_type = BAT_UNICAST; + return skb; } -- cgit v1.2.3 From 420193573f1191b22e08f85ead41c090d283dd05 Mon Sep 17 00:00:00 2001 From: Marek Lindner Date: Mon, 22 Nov 2010 00:55:51 +0100 Subject: Staging: batman-adv: softif bridge loop avoidance By connecting multiple batman-adv mesh nodes to the same ethernet segment a loop can be created when the soft-interface is bridged into that ethernet segment. A simple visualization of the loop involving the most common case - a LAN as ethernet segment: node1 <-- LAN --> node2 | | wifi <-- mesh --> wifi Packets from the LAN (e.g. ARP broadcasts) will circle forever from node1 or node2 over the mesh back into the LAN. This patch adds the functionality to detect other batman-adv nodes connected to the LAN and select a 'gateway' to talk to the non-batman-adv devices on this LAN. All traffic from and to the mesh will be handled by this gateway to avoid the loop. OGMs received via the soft-interface are interpreted as 'port announcements' to locate potential batman-adv nodes. The patch can also deal with vlans on top of batX and offers a list of LAN neighbors via debugfs. Signed-off-by: Marek Lindner [sven.eckelmann@gmx.de: Rework on top of current version] Signed-off-by: Sven Eckelmann Signed-off-by: Greg Kroah-Hartman --- drivers/staging/batman-adv/bat_debugfs.c | 9 + drivers/staging/batman-adv/main.c | 4 + drivers/staging/batman-adv/main.h | 2 + drivers/staging/batman-adv/originator.c | 2 + drivers/staging/batman-adv/routing.c | 12 +- drivers/staging/batman-adv/routing.h | 2 + drivers/staging/batman-adv/soft-interface.c | 296 +++++++++++++++++++++++++++- drivers/staging/batman-adv/soft-interface.h | 5 +- drivers/staging/batman-adv/types.h | 12 ++ 9 files changed, 331 insertions(+), 13 deletions(-) diff --git a/drivers/staging/batman-adv/bat_debugfs.c b/drivers/staging/batman-adv/bat_debugfs.c index 57f84a9f8234..22f3eb98470f 100644 --- a/drivers/staging/batman-adv/bat_debugfs.c +++ b/drivers/staging/batman-adv/bat_debugfs.c @@ -27,6 +27,7 @@ #include "translation-table.h" #include "originator.h" #include "hard-interface.h" +#include "soft-interface.h" #include "vis.h" #include "icmp_socket.h" @@ -227,6 +228,12 @@ static int originators_open(struct inode *inode, struct file *file) return single_open(file, orig_seq_print_text, net_dev); } +static int softif_neigh_open(struct inode *inode, struct file *file) +{ + struct net_device *net_dev = (struct net_device *)inode->i_private; + return single_open(file, softif_neigh_seq_print_text, net_dev); +} + static int transtable_global_open(struct inode *inode, struct file *file) { struct net_device *net_dev = (struct net_device *)inode->i_private; @@ -263,12 +270,14 @@ struct bat_debuginfo bat_debuginfo_##_name = { \ }; static BAT_DEBUGINFO(originators, S_IRUGO, originators_open); +static BAT_DEBUGINFO(softif_neigh, S_IRUGO, softif_neigh_open); static BAT_DEBUGINFO(transtable_global, S_IRUGO, transtable_global_open); static BAT_DEBUGINFO(transtable_local, S_IRUGO, transtable_local_open); static BAT_DEBUGINFO(vis_data, S_IRUGO, vis_data_open); static struct bat_debuginfo *mesh_debuginfos[] = { &bat_debuginfo_originators, + &bat_debuginfo_softif_neigh, &bat_debuginfo_transtable_global, &bat_debuginfo_transtable_local, &bat_debuginfo_vis_data, diff --git a/drivers/staging/batman-adv/main.c b/drivers/staging/batman-adv/main.c index 0587940d2723..f7d6733e3d9a 100644 --- a/drivers/staging/batman-adv/main.c +++ b/drivers/staging/batman-adv/main.c @@ -86,9 +86,11 @@ int mesh_init(struct net_device *soft_iface) spin_lock_init(&bat_priv->hna_ghash_lock); spin_lock_init(&bat_priv->vis_hash_lock); spin_lock_init(&bat_priv->vis_list_lock); + spin_lock_init(&bat_priv->softif_neigh_lock); INIT_HLIST_HEAD(&bat_priv->forw_bat_list); INIT_HLIST_HEAD(&bat_priv->forw_bcast_list); + INIT_HLIST_HEAD(&bat_priv->softif_neigh_list); if (originator_init(bat_priv) < 1) goto err; @@ -132,6 +134,8 @@ void mesh_free(struct net_device *soft_iface) hna_local_free(bat_priv); hna_global_free(bat_priv); + softif_neigh_purge(bat_priv); + atomic_set(&bat_priv->mesh_state, MESH_INACTIVE); } diff --git a/drivers/staging/batman-adv/main.h b/drivers/staging/batman-adv/main.h index 5e3f51681f5e..ec35ef8920bd 100644 --- a/drivers/staging/batman-adv/main.h +++ b/drivers/staging/batman-adv/main.h @@ -71,6 +71,8 @@ * forw_packet->direct_link_flags */ #define MAX_AGGREGATION_MS 100 +#define SOFTIF_NEIGH_TIMEOUT 180000 /* 3 minutes */ + #define RESET_PROTECTION_MS 30000 #define EXPECTED_SEQNO_RANGE 65536 /* don't reset again within 30 seconds */ diff --git a/drivers/staging/batman-adv/originator.c b/drivers/staging/batman-adv/originator.c index 55270080a44b..fc7fb31b5eda 100644 --- a/drivers/staging/batman-adv/originator.c +++ b/drivers/staging/batman-adv/originator.c @@ -28,6 +28,7 @@ #include "routing.h" #include "hard-interface.h" #include "unicast.h" +#include "soft-interface.h" static void purge_orig(struct work_struct *work); @@ -286,6 +287,7 @@ static void _purge_orig(struct bat_priv *bat_priv) spin_unlock_irqrestore(&bat_priv->orig_hash_lock, flags); + softif_neigh_purge(bat_priv); } static void purge_orig(struct work_struct *work) diff --git a/drivers/staging/batman-adv/routing.c b/drivers/staging/batman-adv/routing.c index 750cec708244..3946c7c1b8e7 100644 --- a/drivers/staging/batman-adv/routing.c +++ b/drivers/staging/batman-adv/routing.c @@ -1117,8 +1117,8 @@ static int check_unicast_packet(struct sk_buff *skb, int hdr_size) return 0; } -static int route_unicast_packet(struct sk_buff *skb, - struct batman_if *recv_if, int hdr_size) +int route_unicast_packet(struct sk_buff *skb, struct batman_if *recv_if, + int hdr_size) { struct bat_priv *bat_priv = netdev_priv(recv_if->soft_iface); struct orig_node *orig_node; @@ -1186,7 +1186,7 @@ static int route_unicast_packet(struct sk_buff *skb, return NET_RX_SUCCESS; skb = new_skb; - unicast_packet = (struct unicast_packet *) skb->data; + unicast_packet = (struct unicast_packet *)skb->data; } /* decrement ttl */ @@ -1210,7 +1210,7 @@ int recv_unicast_packet(struct sk_buff *skb, struct batman_if *recv_if) /* packet for me */ if (is_my_mac(unicast_packet->dest)) { - interface_rx(recv_if->soft_iface, skb, hdr_size); + interface_rx(recv_if->soft_iface, skb, recv_if, hdr_size); return NET_RX_SUCCESS; } @@ -1242,7 +1242,7 @@ int recv_ucast_frag_packet(struct sk_buff *skb, struct batman_if *recv_if) if (!new_skb) return NET_RX_SUCCESS; - interface_rx(recv_if->soft_iface, new_skb, + interface_rx(recv_if->soft_iface, new_skb, recv_if, sizeof(struct unicast_packet)); return NET_RX_SUCCESS; } @@ -1324,7 +1324,7 @@ int recv_bcast_packet(struct sk_buff *skb, struct batman_if *recv_if) add_bcast_packet_to_list(bat_priv, skb); /* broadcast for me */ - interface_rx(recv_if->soft_iface, skb, hdr_size); + interface_rx(recv_if->soft_iface, skb, recv_if, hdr_size); return NET_RX_SUCCESS; } diff --git a/drivers/staging/batman-adv/routing.h b/drivers/staging/batman-adv/routing.h index 92674c8d9c03..f108f230bfdb 100644 --- a/drivers/staging/batman-adv/routing.h +++ b/drivers/staging/batman-adv/routing.h @@ -32,6 +32,8 @@ void receive_bat_packet(struct ethhdr *ethhdr, void update_routes(struct bat_priv *bat_priv, struct orig_node *orig_node, struct neigh_node *neigh_node, unsigned char *hna_buff, int hna_buff_len); +int route_unicast_packet(struct sk_buff *skb, struct batman_if *recv_if, + int hdr_size); int recv_icmp_packet(struct sk_buff *skb, struct batman_if *recv_if); int recv_unicast_packet(struct sk_buff *skb, struct batman_if *recv_if); int recv_ucast_frag_packet(struct sk_buff *skb, struct batman_if *recv_if); diff --git a/drivers/staging/batman-adv/soft-interface.c b/drivers/staging/batman-adv/soft-interface.c index 0e996181daf7..c3313d0616cc 100644 --- a/drivers/staging/batman-adv/soft-interface.c +++ b/drivers/staging/batman-adv/soft-interface.c @@ -33,7 +33,9 @@ #include #include #include +#include #include "unicast.h" +#include "routing.h" static int bat_get_settings(struct net_device *dev, struct ethtool_cmd *cmd); @@ -75,6 +77,220 @@ int my_skb_head_push(struct sk_buff *skb, unsigned int len) return 0; } +static void softif_neigh_free_ref(struct kref *refcount) +{ + struct softif_neigh *softif_neigh; + + softif_neigh = container_of(refcount, struct softif_neigh, refcount); + kfree(softif_neigh); +} + +static void softif_neigh_free_rcu(struct rcu_head *rcu) +{ + struct softif_neigh *softif_neigh; + + softif_neigh = container_of(rcu, struct softif_neigh, rcu); + kref_put(&softif_neigh->refcount, softif_neigh_free_ref); +} + +void softif_neigh_purge(struct bat_priv *bat_priv) +{ + struct softif_neigh *softif_neigh, *softif_neigh_tmp; + struct hlist_node *node, *node_tmp; + unsigned long flags; + + spin_lock_irqsave(&bat_priv->softif_neigh_lock, flags); + + hlist_for_each_entry_safe(softif_neigh, node, node_tmp, + &bat_priv->softif_neigh_list, list) { + + if ((!time_after(jiffies, softif_neigh->last_seen + + msecs_to_jiffies(SOFTIF_NEIGH_TIMEOUT))) && + (atomic_read(&bat_priv->mesh_state) == MESH_ACTIVE)) + continue; + + hlist_del_rcu(&softif_neigh->list); + + if (bat_priv->softif_neigh == softif_neigh) { + bat_dbg(DBG_ROUTES, bat_priv, + "Current mesh exit point '%pM' vanished " + "(vid: %d).\n", + softif_neigh->addr, softif_neigh->vid); + softif_neigh_tmp = bat_priv->softif_neigh; + bat_priv->softif_neigh = NULL; + kref_put(&softif_neigh_tmp->refcount, + softif_neigh_free_ref); + } + + call_rcu(&softif_neigh->rcu, softif_neigh_free_rcu); + } + + spin_unlock_irqrestore(&bat_priv->softif_neigh_lock, flags); +} + +static struct softif_neigh *softif_neigh_get(struct bat_priv *bat_priv, + uint8_t *addr, short vid) +{ + struct softif_neigh *softif_neigh; + struct hlist_node *node; + unsigned long flags; + + rcu_read_lock(); + hlist_for_each_entry_rcu(softif_neigh, node, + &bat_priv->softif_neigh_list, list) { + if (memcmp(softif_neigh->addr, addr, ETH_ALEN) != 0) + continue; + + if (softif_neigh->vid != vid) + continue; + + softif_neigh->last_seen = jiffies; + goto found; + } + + softif_neigh = kzalloc(sizeof(struct softif_neigh), GFP_ATOMIC); + if (!softif_neigh) + goto out; + + memcpy(softif_neigh->addr, addr, ETH_ALEN); + softif_neigh->vid = vid; + softif_neigh->last_seen = jiffies; + kref_init(&softif_neigh->refcount); + + INIT_HLIST_NODE(&softif_neigh->list); + spin_lock_irqsave(&bat_priv->softif_neigh_lock, flags); + hlist_add_head_rcu(&softif_neigh->list, &bat_priv->softif_neigh_list); + spin_unlock_irqrestore(&bat_priv->softif_neigh_lock, flags); + +found: + kref_get(&softif_neigh->refcount); +out: + rcu_read_unlock(); + return softif_neigh; +} + +int softif_neigh_seq_print_text(struct seq_file *seq, void *offset) +{ + struct net_device *net_dev = (struct net_device *)seq->private; + struct bat_priv *bat_priv = netdev_priv(net_dev); + struct softif_neigh *softif_neigh; + struct hlist_node *node; + size_t buf_size, pos; + char *buff; + + if (!bat_priv->primary_if) { + return seq_printf(seq, "BATMAN mesh %s disabled - " + "please specify interfaces to enable it\n", + net_dev->name); + } + + seq_printf(seq, "Softif neighbor list (%s)\n", net_dev->name); + + buf_size = 1; + /* Estimate length for: " xx:xx:xx:xx:xx:xx\n" */ + rcu_read_lock(); + hlist_for_each_entry_rcu(softif_neigh, node, + &bat_priv->softif_neigh_list, list) + buf_size += 30; + rcu_read_unlock(); + + buff = kmalloc(buf_size, GFP_ATOMIC); + if (!buff) + return -ENOMEM; + + buff[0] = '\0'; + pos = 0; + + rcu_read_lock(); + hlist_for_each_entry_rcu(softif_neigh, node, + &bat_priv->softif_neigh_list, list) { + pos += snprintf(buff + pos, 31, "%s %pM (vid: %d)\n", + bat_priv->softif_neigh == softif_neigh + ? "=>" : " ", softif_neigh->addr, + softif_neigh->vid); + } + rcu_read_unlock(); + + seq_printf(seq, "%s", buff); + kfree(buff); + return 0; +} + +static void softif_batman_recv(struct sk_buff *skb, struct net_device *dev, + short vid) +{ + struct bat_priv *bat_priv = netdev_priv(dev); + struct ethhdr *ethhdr = (struct ethhdr *)skb->data; + struct batman_packet *batman_packet; + struct softif_neigh *softif_neigh, *softif_neigh_tmp; + + if (ntohs(ethhdr->h_proto) == ETH_P_8021Q) + batman_packet = (struct batman_packet *) + (skb->data + ETH_HLEN + VLAN_HLEN); + else + batman_packet = (struct batman_packet *)(skb->data + ETH_HLEN); + + if (batman_packet->version != COMPAT_VERSION) + goto err; + + if (batman_packet->packet_type != BAT_PACKET) + goto err; + + if (!(batman_packet->flags & PRIMARIES_FIRST_HOP)) + goto err; + + if (is_my_mac(batman_packet->orig)) + goto err; + + softif_neigh = softif_neigh_get(bat_priv, batman_packet->orig, vid); + + if (!softif_neigh) + goto err; + + if (bat_priv->softif_neigh == softif_neigh) + goto out; + + /* we got a neighbor but its mac is 'bigger' than ours */ + if (memcmp(bat_priv->primary_if->net_dev->dev_addr, + softif_neigh->addr, ETH_ALEN) < 0) + goto out; + + /* switch to new 'smallest neighbor' */ + if ((bat_priv->softif_neigh) && + (memcmp(softif_neigh->addr, bat_priv->softif_neigh->addr, + ETH_ALEN) < 0)) { + bat_dbg(DBG_ROUTES, bat_priv, + "Changing mesh exit point from %pM (vid: %d) " + "to %pM (vid: %d).\n", + bat_priv->softif_neigh->addr, + bat_priv->softif_neigh->vid, + softif_neigh->addr, softif_neigh->vid); + softif_neigh_tmp = bat_priv->softif_neigh; + bat_priv->softif_neigh = softif_neigh; + kref_put(&softif_neigh_tmp->refcount, softif_neigh_free_ref); + /* we need to hold the additional reference */ + goto err; + } + + /* close own batX device and use softif_neigh as exit node */ + if ((!bat_priv->softif_neigh) && + (memcmp(softif_neigh->addr, + bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN) < 0)) { + bat_dbg(DBG_ROUTES, bat_priv, + "Setting mesh exit point to %pM (vid: %d).\n", + softif_neigh->addr, softif_neigh->vid); + bat_priv->softif_neigh = softif_neigh; + /* we need to hold the additional reference */ + goto err; + } + +out: + kref_put(&softif_neigh->refcount, softif_neigh_free_ref); +err: + kfree_skb(skb); + return; +} + static int interface_open(struct net_device *dev) { netif_start_queue(dev); @@ -109,7 +325,6 @@ static int interface_set_mac_addr(struct net_device *dev, void *p) } memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN); - return 0; } @@ -129,13 +344,36 @@ int interface_tx(struct sk_buff *skb, struct net_device *soft_iface) struct ethhdr *ethhdr = (struct ethhdr *)skb->data; struct bat_priv *bat_priv = netdev_priv(soft_iface); struct bcast_packet *bcast_packet; + struct vlan_ethhdr *vhdr; int data_len = skb->len, ret; + short vid = -1; if (atomic_read(&bat_priv->mesh_state) != MESH_ACTIVE) goto dropped; soft_iface->trans_start = jiffies; + switch (ntohs(ethhdr->h_proto)) { + case ETH_P_8021Q: + vhdr = (struct vlan_ethhdr *)skb->data; + vid = ntohs(vhdr->h_vlan_TCI) & VLAN_VID_MASK; + + if (ntohs(vhdr->h_vlan_encapsulated_proto) != ETH_P_BATMAN) + break; + + /* fall through */ + case ETH_P_BATMAN: + softif_batman_recv(skb, soft_iface, vid); + goto end; + } + + /** + * if we have a another chosen mesh exit node in range + * it will transport the packets to the mesh + */ + if ((bat_priv->softif_neigh) && (bat_priv->softif_neigh->vid == vid)) + goto dropped; + /* TODO: check this for locks */ hna_local_add(soft_iface, ethhdr->h_source); @@ -189,16 +427,60 @@ end: } void interface_rx(struct net_device *soft_iface, - struct sk_buff *skb, int hdr_size) + struct sk_buff *skb, struct batman_if *recv_if, + int hdr_size) { - struct bat_priv *priv = netdev_priv(soft_iface); + struct bat_priv *bat_priv = netdev_priv(soft_iface); + struct unicast_packet *unicast_packet; + struct ethhdr *ethhdr; + struct vlan_ethhdr *vhdr; + short vid = -1; + int ret; /* check if enough space is available for pulling, and pull */ if (!pskb_may_pull(skb, hdr_size)) goto dropped; skb_pull_rcsum(skb, hdr_size); -/* skb_set_mac_header(skb, -sizeof(struct ethhdr));*/ + skb_reset_mac_header(skb); + + ethhdr = (struct ethhdr *)skb_mac_header(skb); + + switch (ntohs(ethhdr->h_proto)) { + case ETH_P_8021Q: + vhdr = (struct vlan_ethhdr *)skb->data; + vid = ntohs(vhdr->h_vlan_TCI) & VLAN_VID_MASK; + + if (ntohs(vhdr->h_vlan_encapsulated_proto) != ETH_P_BATMAN) + break; + + /* fall through */ + case ETH_P_BATMAN: + goto dropped; + } + + /** + * if we have a another chosen mesh exit node in range + * it will transport the packets to the non-mesh network + */ + if ((bat_priv->softif_neigh) && (bat_priv->softif_neigh->vid == vid)) { + skb_push(skb, hdr_size); + unicast_packet = (struct unicast_packet *)skb->data; + + if ((unicast_packet->packet_type != BAT_UNICAST) && + (unicast_packet->packet_type != BAT_UNICAST_FRAG)) + goto dropped; + + skb_reset_mac_header(skb); + + memcpy(unicast_packet->dest, + bat_priv->softif_neigh->addr, ETH_ALEN); + ret = route_unicast_packet(skb, recv_if, hdr_size); + if (ret == NET_RX_DROP) + goto dropped; + + goto out; + } /* skb->dev & skb->pkt_type are set here */ if (unlikely(!pskb_may_pull(skb, ETH_HLEN))) @@ -211,8 +493,8 @@ void interface_rx(struct net_device *soft_iface, /* skb->ip_summed = CHECKSUM_UNNECESSARY;*/ - priv->stats.rx_packets++; - priv->stats.rx_bytes += skb->len + sizeof(struct ethhdr); + bat_priv->stats.rx_packets++; + bat_priv->stats.rx_bytes += skb->len + sizeof(struct ethhdr); soft_iface->last_rx = jiffies; @@ -221,6 +503,7 @@ void interface_rx(struct net_device *soft_iface, dropped: kfree_skb(skb); +out: return; } @@ -310,6 +593,7 @@ struct net_device *softif_create(char *name) bat_priv->primary_if = NULL; bat_priv->num_ifaces = 0; + bat_priv->softif_neigh = NULL; ret = sysfs_add_meshif(soft_iface); if (ret < 0) diff --git a/drivers/staging/batman-adv/soft-interface.h b/drivers/staging/batman-adv/soft-interface.h index 843a7ec082fe..02b77334d10d 100644 --- a/drivers/staging/batman-adv/soft-interface.h +++ b/drivers/staging/batman-adv/soft-interface.h @@ -23,9 +23,12 @@ #define _NET_BATMAN_ADV_SOFT_INTERFACE_H_ int my_skb_head_push(struct sk_buff *skb, unsigned int len); +int softif_neigh_seq_print_text(struct seq_file *seq, void *offset); +void softif_neigh_purge(struct bat_priv *bat_priv); int interface_tx(struct sk_buff *skb, struct net_device *soft_iface); void interface_rx(struct net_device *soft_iface, - struct sk_buff *skb, int hdr_size); + struct sk_buff *skb, struct batman_if *recv_if, + int hdr_size); struct net_device *softif_create(char *name); void softif_destroy(struct net_device *soft_iface); diff --git a/drivers/staging/batman-adv/types.h b/drivers/staging/batman-adv/types.h index 8f6ba1c56927..835d51f9a95d 100644 --- a/drivers/staging/batman-adv/types.h +++ b/drivers/staging/batman-adv/types.h @@ -123,6 +123,8 @@ struct bat_priv { atomic_t bcast_queue_left; atomic_t batman_queue_left; char num_ifaces; + struct hlist_head softif_neigh_list; + struct softif_neigh *softif_neigh; struct debug_log *debug_log; struct batman_if *primary_if; struct kobject *mesh_obj; @@ -141,6 +143,7 @@ struct bat_priv { spinlock_t hna_ghash_lock; /* protects hna_global_hash */ spinlock_t vis_hash_lock; /* protects vis_hash */ spinlock_t vis_list_lock; /* protects vis_info::recv_list */ + spinlock_t softif_neigh_lock; /* protects soft-interface neigh list */ int16_t num_local_hna; atomic_t hna_local_changed; struct delayed_work hna_work; @@ -239,4 +242,13 @@ struct recvlist_node { uint8_t mac[ETH_ALEN]; }; +struct softif_neigh { + struct hlist_node list; + uint8_t addr[ETH_ALEN]; + unsigned long last_seen; + short vid; + struct kref refcount; + struct rcu_head rcu; +}; + #endif /* _NET_BATMAN_ADV_TYPES_H_ */ -- cgit v1.2.3 From 641ee3f8f4375bde4e216aacd26d286a34efed61 Mon Sep 17 00:00:00 2001 From: Linus Lüssing Date: Mon, 22 Nov 2010 00:55:52 +0100 Subject: Staging: batman-adv: Unify sysfs file names with their bat_priv atomics MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Both sysfs entries and variable names shall be as descriptive as possible while not exceeding a certain length. This patch renames bat_priv atomics to be equally descriptive with their according sysfs entries. Unifying sysfs and bat_priv atomic names also makes it easier to find each others pendant. The reduced ("type"-)information which was previously indicated with a _enabled for booleans got substituted by a comment in bat_priv. This patch has also been done in regards for the future BAT_ATTR_* macros (they only need one name argument instead of a file and variable name). Signed-off-by: Linus Lüssing Signed-off-by: Marek Lindner Signed-off-by: Sven Eckelmann Signed-off-by: Greg Kroah-Hartman --- drivers/staging/batman-adv/aggregation.c | 6 +++--- drivers/staging/batman-adv/bat_sysfs.c | 24 ++++++++++++------------ drivers/staging/batman-adv/hard-interface.c | 6 +++--- drivers/staging/batman-adv/routing.c | 4 ++-- drivers/staging/batman-adv/soft-interface.c | 6 +++--- drivers/staging/batman-adv/translation-table.c | 2 +- drivers/staging/batman-adv/types.h | 12 ++++++------ drivers/staging/batman-adv/unicast.c | 2 +- 8 files changed, 31 insertions(+), 31 deletions(-) diff --git a/drivers/staging/batman-adv/aggregation.c b/drivers/staging/batman-adv/aggregation.c index 08624d44e231..3dfed2f4bb5d 100644 --- a/drivers/staging/batman-adv/aggregation.c +++ b/drivers/staging/batman-adv/aggregation.c @@ -123,7 +123,7 @@ static void new_aggregated_packet(unsigned char *packet_buff, int packet_len, return; } - if ((atomic_read(&bat_priv->aggregation_enabled)) && + if ((atomic_read(&bat_priv->aggregated_ogms)) && (packet_len < MAX_AGGREGATION_BYTES)) forw_packet_aggr->skb = dev_alloc_skb(MAX_AGGREGATION_BYTES + sizeof(struct ethhdr)); @@ -206,7 +206,7 @@ void add_bat_packet_to_list(struct bat_priv *bat_priv, /* find position for the packet in the forward queue */ spin_lock_irqsave(&bat_priv->forw_bat_list_lock, flags); /* own packets are not to be aggregated */ - if ((atomic_read(&bat_priv->aggregation_enabled)) && (!own_packet)) { + if ((atomic_read(&bat_priv->aggregated_ogms)) && (!own_packet)) { hlist_for_each_entry(forw_packet_pos, tmp_node, &bat_priv->forw_bat_list, list) { if (can_aggregate_with(batman_packet, @@ -233,7 +233,7 @@ void add_bat_packet_to_list(struct bat_priv *bat_priv, * later on */ if ((!own_packet) && - (atomic_read(&bat_priv->aggregation_enabled))) + (atomic_read(&bat_priv->aggregated_ogms))) send_time += msecs_to_jiffies(MAX_AGGREGATION_MS); new_aggregated_packet(packet_buff, packet_len, diff --git a/drivers/staging/batman-adv/bat_sysfs.c b/drivers/staging/batman-adv/bat_sysfs.c index 536f65120edd..a67c54c48ff4 100644 --- a/drivers/staging/batman-adv/bat_sysfs.c +++ b/drivers/staging/batman-adv/bat_sysfs.c @@ -41,7 +41,7 @@ static ssize_t show_aggr_ogms(struct kobject *kobj, struct attribute *attr, { struct device *dev = to_dev(kobj->parent); struct bat_priv *bat_priv = netdev_priv(to_net_dev(dev)); - int aggr_status = atomic_read(&bat_priv->aggregation_enabled); + int aggr_status = atomic_read(&bat_priv->aggregated_ogms); return sprintf(buff, "%s\n", aggr_status == 0 ? "disabled" : "enabled"); @@ -73,15 +73,15 @@ static ssize_t store_aggr_ogms(struct kobject *kobj, struct attribute *attr, return -EINVAL; } - if (atomic_read(&bat_priv->aggregation_enabled) == aggr_tmp) + if (atomic_read(&bat_priv->aggregated_ogms) == aggr_tmp) return count; bat_info(net_dev, "Changing aggregation from: %s to: %s\n", - atomic_read(&bat_priv->aggregation_enabled) == 1 ? + atomic_read(&bat_priv->aggregated_ogms) == 1 ? "enabled" : "disabled", aggr_tmp == 1 ? "enabled" : "disabled"); - atomic_set(&bat_priv->aggregation_enabled, (unsigned)aggr_tmp); + atomic_set(&bat_priv->aggregated_ogms, (unsigned)aggr_tmp); return count; } @@ -90,7 +90,7 @@ static ssize_t show_bond(struct kobject *kobj, struct attribute *attr, { struct device *dev = to_dev(kobj->parent); struct bat_priv *bat_priv = netdev_priv(to_net_dev(dev)); - int bond_status = atomic_read(&bat_priv->bonding_enabled); + int bond_status = atomic_read(&bat_priv->bonding); return sprintf(buff, "%s\n", bond_status == 0 ? "disabled" : "enabled"); @@ -122,15 +122,15 @@ static ssize_t store_bond(struct kobject *kobj, struct attribute *attr, return -EINVAL; } - if (atomic_read(&bat_priv->bonding_enabled) == bonding_enabled_tmp) + if (atomic_read(&bat_priv->bonding) == bonding_enabled_tmp) return count; bat_info(net_dev, "Changing bonding from: %s to: %s\n", - atomic_read(&bat_priv->bonding_enabled) == 1 ? + atomic_read(&bat_priv->bonding) == 1 ? "enabled" : "disabled", bonding_enabled_tmp == 1 ? "enabled" : "disabled"); - atomic_set(&bat_priv->bonding_enabled, (unsigned)bonding_enabled_tmp); + atomic_set(&bat_priv->bonding, (unsigned)bonding_enabled_tmp); return count; } @@ -139,7 +139,7 @@ static ssize_t show_frag(struct kobject *kobj, struct attribute *attr, { struct device *dev = to_dev(kobj->parent); struct bat_priv *bat_priv = netdev_priv(to_net_dev(dev)); - int frag_status = atomic_read(&bat_priv->frag_enabled); + int frag_status = atomic_read(&bat_priv->fragmentation); return sprintf(buff, "%s\n", frag_status == 0 ? "disabled" : "enabled"); @@ -171,15 +171,15 @@ static ssize_t store_frag(struct kobject *kobj, struct attribute *attr, return -EINVAL; } - if (atomic_read(&bat_priv->frag_enabled) == frag_enabled_tmp) + if (atomic_read(&bat_priv->fragmentation) == frag_enabled_tmp) return count; bat_info(net_dev, "Changing fragmentation from: %s to: %s\n", - atomic_read(&bat_priv->frag_enabled) == 1 ? + atomic_read(&bat_priv->fragmentation) == 1 ? "enabled" : "disabled", frag_enabled_tmp == 1 ? "enabled" : "disabled"); - atomic_set(&bat_priv->frag_enabled, (unsigned)frag_enabled_tmp); + atomic_set(&bat_priv->fragmentation, (unsigned)frag_enabled_tmp); update_min_mtu(net_dev); return count; } diff --git a/drivers/staging/batman-adv/hard-interface.c b/drivers/staging/batman-adv/hard-interface.c index c2ff29432a5e..ff0ac9825001 100644 --- a/drivers/staging/batman-adv/hard-interface.c +++ b/drivers/staging/batman-adv/hard-interface.c @@ -208,7 +208,7 @@ int hardif_min_mtu(struct net_device *soft_iface) * (have MTU > 1500 + BAT_HEADER_LEN) */ int min_mtu = ETH_DATA_LEN; - if (atomic_read(&bat_priv->frag_enabled)) + if (atomic_read(&bat_priv->fragmentation)) goto out; rcu_read_lock(); @@ -332,7 +332,7 @@ int hardif_enable_interface(struct batman_if *batman_if, char *iface_name) bat_info(batman_if->soft_iface, "Adding interface: %s\n", batman_if->net_dev->name); - if (atomic_read(&bat_priv->frag_enabled) && batman_if->net_dev->mtu < + if (atomic_read(&bat_priv->fragmentation) && batman_if->net_dev->mtu < ETH_DATA_LEN + BAT_HEADER_LEN) bat_info(batman_if->soft_iface, "The MTU of interface %s is too small (%i) to handle " @@ -343,7 +343,7 @@ int hardif_enable_interface(struct batman_if *batman_if, char *iface_name) batman_if->net_dev->name, batman_if->net_dev->mtu, ETH_DATA_LEN + BAT_HEADER_LEN); - if (!atomic_read(&bat_priv->frag_enabled) && batman_if->net_dev->mtu < + if (!atomic_read(&bat_priv->fragmentation) && batman_if->net_dev->mtu < ETH_DATA_LEN + BAT_HEADER_LEN) bat_info(batman_if->soft_iface, "The MTU of interface %s is too small (%i) to handle " diff --git a/drivers/staging/batman-adv/routing.c b/drivers/staging/batman-adv/routing.c index 3946c7c1b8e7..1b3548634904 100644 --- a/drivers/staging/batman-adv/routing.c +++ b/drivers/staging/batman-adv/routing.c @@ -1019,7 +1019,7 @@ struct neigh_node *find_router(struct bat_priv *bat_priv, /* without bonding, the first node should * always choose the default router. */ - bonding_enabled = atomic_read(&bat_priv->bonding_enabled); + bonding_enabled = atomic_read(&bat_priv->bonding); if ((!recv_if) && (!bonding_enabled)) return orig_node->router; @@ -1168,7 +1168,7 @@ int route_unicast_packet(struct sk_buff *skb, struct batman_if *recv_if, unicast_packet = (struct unicast_packet *)skb->data; if (unicast_packet->packet_type == BAT_UNICAST && - atomic_read(&bat_priv->frag_enabled) && + atomic_read(&bat_priv->fragmentation) && skb->len > batman_if->net_dev->mtu) return frag_send_skb(skb, bat_priv, batman_if, dstaddr); diff --git a/drivers/staging/batman-adv/soft-interface.c b/drivers/staging/batman-adv/soft-interface.c index c3313d0616cc..c903a76ad0e2 100644 --- a/drivers/staging/batman-adv/soft-interface.c +++ b/drivers/staging/batman-adv/soft-interface.c @@ -578,12 +578,12 @@ struct net_device *softif_create(char *name) bat_priv = netdev_priv(soft_iface); - atomic_set(&bat_priv->aggregation_enabled, 1); - atomic_set(&bat_priv->bonding_enabled, 0); + atomic_set(&bat_priv->aggregated_ogms, 1); + atomic_set(&bat_priv->bonding, 0); atomic_set(&bat_priv->vis_mode, VIS_TYPE_CLIENT_UPDATE); atomic_set(&bat_priv->orig_interval, 1000); atomic_set(&bat_priv->log_level, 0); - atomic_set(&bat_priv->frag_enabled, 1); + atomic_set(&bat_priv->fragmentation, 1); atomic_set(&bat_priv->bcast_queue_left, BCAST_QUEUE_LEN); atomic_set(&bat_priv->batman_queue_left, BATMAN_QUEUE_LEN); diff --git a/drivers/staging/batman-adv/translation-table.c b/drivers/staging/batman-adv/translation-table.c index 681ccbda3eac..3bc752111638 100644 --- a/drivers/staging/batman-adv/translation-table.c +++ b/drivers/staging/batman-adv/translation-table.c @@ -79,7 +79,7 @@ void hna_local_add(struct net_device *soft_iface, uint8_t *addr) required_bytes += BAT_PACKET_LEN; if ((required_bytes > ETH_DATA_LEN) || - (atomic_read(&bat_priv->aggregation_enabled) && + (atomic_read(&bat_priv->aggregated_ogms) && required_bytes > MAX_AGGREGATION_BYTES) || (bat_priv->num_local_hna + 1 > 255)) { bat_dbg(DBG_ROUTES, bat_priv, diff --git a/drivers/staging/batman-adv/types.h b/drivers/staging/batman-adv/types.h index 835d51f9a95d..4463da391498 100644 --- a/drivers/staging/batman-adv/types.h +++ b/drivers/staging/batman-adv/types.h @@ -113,12 +113,12 @@ struct neigh_node { struct bat_priv { atomic_t mesh_state; struct net_device_stats stats; - atomic_t aggregation_enabled; - atomic_t bonding_enabled; - atomic_t frag_enabled; - atomic_t vis_mode; - atomic_t orig_interval; - atomic_t log_level; + atomic_t aggregated_ogms; /* boolean */ + atomic_t bonding; /* boolean */ + atomic_t fragmentation; /* boolean */ + atomic_t vis_mode; /* VIS_TYPE_* */ + atomic_t orig_interval; /* uint */ + atomic_t log_level; /* uint */ atomic_t bcast_seqno; atomic_t bcast_queue_left; atomic_t batman_queue_left; diff --git a/drivers/staging/batman-adv/unicast.c b/drivers/staging/batman-adv/unicast.c index e58e634c2806..5ae959327b48 100644 --- a/drivers/staging/batman-adv/unicast.c +++ b/drivers/staging/batman-adv/unicast.c @@ -318,7 +318,7 @@ int unicast_send_skb(struct sk_buff *skb, struct bat_priv *bat_priv) /* copy the destination for faster routing */ memcpy(unicast_packet->dest, orig_node->orig, ETH_ALEN); - if (atomic_read(&bat_priv->frag_enabled) && + if (atomic_read(&bat_priv->fragmentation) && data_len + sizeof(struct unicast_packet) > batman_if->net_dev->mtu) { /* send frag skb decreases ttl */ -- cgit v1.2.3 From add9e1722755072f40d79104db04e350b25624d9 Mon Sep 17 00:00:00 2001 From: Linus Lüssing Date: Mon, 22 Nov 2010 00:55:53 +0100 Subject: Staging: batman-adv: Wrapper functions for sysfs storing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sysfs configuration options that just took a boolean value (enable(d)/disable(d)/0/1) and integer setting basically all had the same structure. To avoid even more copy and pasting in the future and to make introducing new configuration parameters for batman-adv simpler, more generic wrapper functions are being introduced with this commit. They can deal with boolean and unsigned integer parameters, storing them in the specified atomic_t variables. Signed-off-by: Linus Lüssing Signed-off-by: Sven Eckelmann Signed-off-by: Greg Kroah-Hartman --- drivers/staging/batman-adv/bat_sysfs.c | 333 +++++++++++++-------------------- 1 file changed, 130 insertions(+), 203 deletions(-) diff --git a/drivers/staging/batman-adv/bat_sysfs.c b/drivers/staging/batman-adv/bat_sysfs.c index a67c54c48ff4..19be53174bc6 100644 --- a/drivers/staging/batman-adv/bat_sysfs.c +++ b/drivers/staging/batman-adv/bat_sysfs.c @@ -28,6 +28,7 @@ #define to_dev(obj) container_of(obj, struct device, kobj) +/* Use this, if you have customized show and store functions */ #define BAT_ATTR(_name, _mode, _show, _store) \ struct bat_attribute bat_attr_##_name = { \ .attr = {.name = __stringify(_name), \ @@ -36,152 +37,168 @@ struct bat_attribute bat_attr_##_name = { \ .store = _store, \ }; -static ssize_t show_aggr_ogms(struct kobject *kobj, struct attribute *attr, - char *buff) -{ - struct device *dev = to_dev(kobj->parent); - struct bat_priv *bat_priv = netdev_priv(to_net_dev(dev)); - int aggr_status = atomic_read(&bat_priv->aggregated_ogms); +#define BAT_ATTR_STORE_BOOL(_name, _post_func) \ +ssize_t store_##_name(struct kobject *kobj, struct attribute *attr, \ + char *buff, size_t count) \ +{ \ + struct device *dev = to_dev(kobj->parent); \ + struct net_device *net_dev = to_net_dev(dev); \ + struct bat_priv *bat_priv = netdev_priv(net_dev); \ + return __store_bool_attr(buff, count, _post_func, attr, \ + &bat_priv->_name, net_dev); \ +} - return sprintf(buff, "%s\n", - aggr_status == 0 ? "disabled" : "enabled"); +#define BAT_ATTR_SHOW_BOOL(_name) \ +ssize_t show_##_name(struct kobject *kobj, struct attribute *attr, \ + char *buff) \ +{ \ + struct device *dev = to_dev(kobj->parent); \ + struct net_device *net_dev = to_net_dev(dev); \ + struct bat_priv *bat_priv = netdev_priv(net_dev); \ + return sprintf(buff, "%s\n", \ + atomic_read(&bat_priv->_name) == 0 ? \ + "disabled" : "enabled"); \ +} \ + +/* Use this, if you are going to turn a [name] in bat_priv on or off */ +#define BAT_ATTR_BOOL(_name, _mode, _post_func) \ + static BAT_ATTR_STORE_BOOL(_name, _post_func) \ + static BAT_ATTR_SHOW_BOOL(_name) \ + static BAT_ATTR(_name, _mode, show_##_name, store_##_name) + + +#define BAT_ATTR_STORE_UINT(_name, _min, _max, _post_func) \ +ssize_t store_##_name(struct kobject *kobj, struct attribute *attr, \ + char *buff, size_t count) \ +{ \ + struct device *dev = to_dev(kobj->parent); \ + struct net_device *net_dev = to_net_dev(dev); \ + struct bat_priv *bat_priv = netdev_priv(net_dev); \ + return __store_uint_attr(buff, count, _min, _max, _post_func, \ + attr, &bat_priv->_name, net_dev); \ } -static ssize_t store_aggr_ogms(struct kobject *kobj, struct attribute *attr, - char *buff, size_t count) +#define BAT_ATTR_SHOW_UINT(_name) \ +ssize_t show_##_name(struct kobject *kobj, struct attribute *attr, \ + char *buff) \ +{ \ + struct device *dev = to_dev(kobj->parent); \ + struct net_device *net_dev = to_net_dev(dev); \ + struct bat_priv *bat_priv = netdev_priv(net_dev); \ + return sprintf(buff, "%i\n", atomic_read(&bat_priv->_name)); \ +} \ + +/* Use this, if you are going to set [name] in bat_priv to unsigned integer + * values only */ +#define BAT_ATTR_UINT(_name, _mode, _min, _max, _post_func) \ + static BAT_ATTR_STORE_UINT(_name, _min, _max, _post_func) \ + static BAT_ATTR_SHOW_UINT(_name) \ + static BAT_ATTR(_name, _mode, show_##_name, store_##_name) + + +static int store_bool_attr(char *buff, size_t count, + struct net_device *net_dev, + char *attr_name, atomic_t *attr) { - struct device *dev = to_dev(kobj->parent); - struct net_device *net_dev = to_net_dev(dev); - struct bat_priv *bat_priv = netdev_priv(net_dev); - int aggr_tmp = -1; + int enabled = -1; - if (((count == 2) && (buff[0] == '1')) || - (strncmp(buff, "enable", 6) == 0)) - aggr_tmp = 1; + if (buff[count - 1] == '\n') + buff[count - 1] = '\0'; - if (((count == 2) && (buff[0] == '0')) || - (strncmp(buff, "disable", 7) == 0)) - aggr_tmp = 0; + if ((strncmp(buff, "1", 2) == 0) || + (strncmp(buff, "enable", 7) == 0) || + (strncmp(buff, "enabled", 8) == 0)) + enabled = 1; - if (aggr_tmp < 0) { - if (buff[count - 1] == '\n') - buff[count - 1] = '\0'; + if ((strncmp(buff, "0", 2) == 0) || + (strncmp(buff, "disable", 8) == 0) || + (strncmp(buff, "disabled", 9) == 0)) + enabled = 0; + if (enabled < 0) { bat_info(net_dev, - "Invalid parameter for 'aggregate OGM' setting" - "received: %s\n", buff); + "%s: Invalid parameter received: %s\n", + attr_name, buff); return -EINVAL; } - if (atomic_read(&bat_priv->aggregated_ogms) == aggr_tmp) + if (atomic_read(attr) == enabled) return count; - bat_info(net_dev, "Changing aggregation from: %s to: %s\n", - atomic_read(&bat_priv->aggregated_ogms) == 1 ? - "enabled" : "disabled", aggr_tmp == 1 ? "enabled" : - "disabled"); + bat_info(net_dev, "%s: Changing from: %s to: %s\n", attr_name, + atomic_read(attr) == 1 ? "enabled" : "disabled", + enabled == 1 ? "enabled" : "disabled"); - atomic_set(&bat_priv->aggregated_ogms, (unsigned)aggr_tmp); + atomic_set(attr, (unsigned)enabled); return count; } -static ssize_t show_bond(struct kobject *kobj, struct attribute *attr, - char *buff) +static inline ssize_t __store_bool_attr(char *buff, size_t count, + void (*post_func)(struct net_device *), + struct attribute *attr, + atomic_t *attr_store, struct net_device *net_dev) { - struct device *dev = to_dev(kobj->parent); - struct bat_priv *bat_priv = netdev_priv(to_net_dev(dev)); - int bond_status = atomic_read(&bat_priv->bonding); + int ret; - return sprintf(buff, "%s\n", - bond_status == 0 ? "disabled" : "enabled"); + ret = store_bool_attr(buff, count, net_dev, (char *)attr->name, + attr_store); + if (post_func && ret) + post_func(net_dev); + + return ret; } -static ssize_t store_bond(struct kobject *kobj, struct attribute *attr, - char *buff, size_t count) +static int store_uint_attr(char *buff, size_t count, + struct net_device *net_dev, char *attr_name, + unsigned int min, unsigned int max, atomic_t *attr) { - struct device *dev = to_dev(kobj->parent); - struct net_device *net_dev = to_net_dev(dev); - struct bat_priv *bat_priv = netdev_priv(net_dev); - int bonding_enabled_tmp = -1; - - if (((count == 2) && (buff[0] == '1')) || - (strncmp(buff, "enable", 6) == 0)) - bonding_enabled_tmp = 1; + unsigned long uint_val; + int ret; - if (((count == 2) && (buff[0] == '0')) || - (strncmp(buff, "disable", 7) == 0)) - bonding_enabled_tmp = 0; + ret = strict_strtoul(buff, 10, &uint_val); + if (ret) { + bat_info(net_dev, + "%s: Invalid parameter received: %s\n", + attr_name, buff); + return -EINVAL; + } - if (bonding_enabled_tmp < 0) { - if (buff[count - 1] == '\n') - buff[count - 1] = '\0'; + if (uint_val < min) { + bat_info(net_dev, "%s: Value is too small: %lu min: %u\n", + attr_name, uint_val, min); + return -EINVAL; + } - bat_err(net_dev, - "Invalid parameter for 'bonding' setting received: " - "%s\n", buff); + if (uint_val > max) { + bat_info(net_dev, "%s: Value is too big: %lu max: %u\n", + attr_name, uint_val, max); return -EINVAL; } - if (atomic_read(&bat_priv->bonding) == bonding_enabled_tmp) + if (atomic_read(attr) == uint_val) return count; - bat_info(net_dev, "Changing bonding from: %s to: %s\n", - atomic_read(&bat_priv->bonding) == 1 ? - "enabled" : "disabled", - bonding_enabled_tmp == 1 ? "enabled" : "disabled"); + bat_info(net_dev, "%s: Changing from: %i to: %lu\n", + attr_name, atomic_read(attr), uint_val); - atomic_set(&bat_priv->bonding, (unsigned)bonding_enabled_tmp); + atomic_set(attr, uint_val); return count; } -static ssize_t show_frag(struct kobject *kobj, struct attribute *attr, - char *buff) -{ - struct device *dev = to_dev(kobj->parent); - struct bat_priv *bat_priv = netdev_priv(to_net_dev(dev)); - int frag_status = atomic_read(&bat_priv->fragmentation); - - return sprintf(buff, "%s\n", - frag_status == 0 ? "disabled" : "enabled"); -} - -static ssize_t store_frag(struct kobject *kobj, struct attribute *attr, - char *buff, size_t count) +static inline ssize_t __store_uint_attr(char *buff, size_t count, + int min, int max, + void (*post_func)(struct net_device *), + struct attribute *attr, + atomic_t *attr_store, struct net_device *net_dev) { - struct device *dev = to_dev(kobj->parent); - struct net_device *net_dev = to_net_dev(dev); - struct bat_priv *bat_priv = netdev_priv(net_dev); - int frag_enabled_tmp = -1; - - if (((count == 2) && (buff[0] == '1')) || - (strncmp(buff, "enable", 6) == 0)) - frag_enabled_tmp = 1; - - if (((count == 2) && (buff[0] == '0')) || - (strncmp(buff, "disable", 7) == 0)) - frag_enabled_tmp = 0; - - if (frag_enabled_tmp < 0) { - if (buff[count - 1] == '\n') - buff[count - 1] = '\0'; - - bat_err(net_dev, - "Invalid parameter for 'fragmentation' setting on mesh" - "received: %s\n", buff); - return -EINVAL; - } - - if (atomic_read(&bat_priv->fragmentation) == frag_enabled_tmp) - return count; + int ret; - bat_info(net_dev, "Changing fragmentation from: %s to: %s\n", - atomic_read(&bat_priv->fragmentation) == 1 ? - "enabled" : "disabled", - frag_enabled_tmp == 1 ? "enabled" : "disabled"); + ret = store_uint_attr(buff, count, net_dev, (char *)attr->name, + min, max, attr_store); + if (post_func && ret) + post_func(net_dev); - atomic_set(&bat_priv->fragmentation, (unsigned)frag_enabled_tmp); - update_min_mtu(net_dev); - return count; + return ret; } static ssize_t show_vis_mode(struct kobject *kobj, struct attribute *attr, @@ -238,103 +255,13 @@ static ssize_t store_vis_mode(struct kobject *kobj, struct attribute *attr, return count; } -static ssize_t show_orig_interval(struct kobject *kobj, struct attribute *attr, - char *buff) -{ - struct device *dev = to_dev(kobj->parent); - struct bat_priv *bat_priv = netdev_priv(to_net_dev(dev)); - - return sprintf(buff, "%i\n", - atomic_read(&bat_priv->orig_interval)); -} - -static ssize_t store_orig_interval(struct kobject *kobj, struct attribute *attr, - char *buff, size_t count) -{ - struct device *dev = to_dev(kobj->parent); - struct net_device *net_dev = to_net_dev(dev); - struct bat_priv *bat_priv = netdev_priv(net_dev); - unsigned long orig_interval_tmp; - int ret; - - ret = strict_strtoul(buff, 10, &orig_interval_tmp); - if (ret) { - bat_info(net_dev, "Invalid parameter for 'orig_interval' " - "setting received: %s\n", buff); - return -EINVAL; - } - - if (orig_interval_tmp < JITTER * 2) { - bat_info(net_dev, "New originator interval too small: %li " - "(min: %i)\n", orig_interval_tmp, JITTER * 2); - return -EINVAL; - } - - if (atomic_read(&bat_priv->orig_interval) == orig_interval_tmp) - return count; - - bat_info(net_dev, "Changing originator interval from: %i to: %li\n", - atomic_read(&bat_priv->orig_interval), - orig_interval_tmp); - - atomic_set(&bat_priv->orig_interval, orig_interval_tmp); - return count; -} - -#ifdef CONFIG_BATMAN_ADV_DEBUG -static ssize_t show_log_level(struct kobject *kobj, struct attribute *attr, - char *buff) -{ - struct device *dev = to_dev(kobj->parent); - struct bat_priv *bat_priv = netdev_priv(to_net_dev(dev)); - int log_level = atomic_read(&bat_priv->log_level); - - return sprintf(buff, "%d\n", log_level); -} - -static ssize_t store_log_level(struct kobject *kobj, struct attribute *attr, - char *buff, size_t count) -{ - struct device *dev = to_dev(kobj->parent); - struct net_device *net_dev = to_net_dev(dev); - struct bat_priv *bat_priv = netdev_priv(net_dev); - unsigned long log_level_tmp; - int ret; - - ret = strict_strtoul(buff, 10, &log_level_tmp); - if (ret) { - bat_info(net_dev, "Invalid parameter for 'log_level' " - "setting received: %s\n", buff); - return -EINVAL; - } - - if (log_level_tmp > 3) { - bat_info(net_dev, "New log level too big: %li " - "(max: %i)\n", log_level_tmp, 3); - return -EINVAL; - } - - if (atomic_read(&bat_priv->log_level) == log_level_tmp) - return count; - - bat_info(net_dev, "Changing log level from: %i to: %li\n", - atomic_read(&bat_priv->log_level), - log_level_tmp); - - atomic_set(&bat_priv->log_level, (unsigned)log_level_tmp); - return count; -} -#endif - -static BAT_ATTR(aggregated_ogms, S_IRUGO | S_IWUSR, - show_aggr_ogms, store_aggr_ogms); -static BAT_ATTR(bonding, S_IRUGO | S_IWUSR, show_bond, store_bond); -static BAT_ATTR(fragmentation, S_IRUGO | S_IWUSR, show_frag, store_frag); +BAT_ATTR_BOOL(aggregated_ogms, S_IRUGO | S_IWUSR, NULL); +BAT_ATTR_BOOL(bonding, S_IRUGO | S_IWUSR, NULL); +BAT_ATTR_BOOL(fragmentation, S_IRUGO | S_IWUSR, update_min_mtu); static BAT_ATTR(vis_mode, S_IRUGO | S_IWUSR, show_vis_mode, store_vis_mode); -static BAT_ATTR(orig_interval, S_IRUGO | S_IWUSR, - show_orig_interval, store_orig_interval); +BAT_ATTR_UINT(orig_interval, S_IRUGO | S_IWUSR, 2 * JITTER, INT_MAX, NULL); #ifdef CONFIG_BATMAN_ADV_DEBUG -static BAT_ATTR(log_level, S_IRUGO | S_IWUSR, show_log_level, store_log_level); +BAT_ATTR_UINT(log_level, S_IRUGO | S_IWUSR, 0, 3, NULL); #endif static struct bat_attribute *mesh_attrs[] = { -- cgit v1.2.3 From 1623948f879069b33d07986aa95e3b9969322ff4 Mon Sep 17 00:00:00 2001 From: Linus Lüssing Date: Mon, 22 Nov 2010 00:55:54 +0100 Subject: Staging: batman-adv: Ommit storing struct device in sysfs functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We actually do not need an extra struct device variable, therefore replacing them with defines that directly get the bat_priv or net_device. This further reduces the code size in bat_sysfs.c and especially shortens some macros. Signed-off-by: Linus Lüssing Signed-off-by: Sven Eckelmann Signed-off-by: Greg Kroah-Hartman --- drivers/staging/batman-adv/bat_sysfs.c | 33 ++++++++++++--------------------- 1 file changed, 12 insertions(+), 21 deletions(-) diff --git a/drivers/staging/batman-adv/bat_sysfs.c b/drivers/staging/batman-adv/bat_sysfs.c index 19be53174bc6..9bec60de42ba 100644 --- a/drivers/staging/batman-adv/bat_sysfs.c +++ b/drivers/staging/batman-adv/bat_sysfs.c @@ -26,7 +26,9 @@ #include "hard-interface.h" #include "vis.h" -#define to_dev(obj) container_of(obj, struct device, kobj) +#define to_dev(obj) container_of(obj, struct device, kobj) +#define kobj_to_netdev(obj) to_net_dev(to_dev(obj->parent)) +#define kobj_to_batpriv(obj) netdev_priv(kobj_to_netdev(obj)) /* Use this, if you have customized show and store functions */ #define BAT_ATTR(_name, _mode, _show, _store) \ @@ -41,8 +43,7 @@ struct bat_attribute bat_attr_##_name = { \ ssize_t store_##_name(struct kobject *kobj, struct attribute *attr, \ char *buff, size_t count) \ { \ - struct device *dev = to_dev(kobj->parent); \ - struct net_device *net_dev = to_net_dev(dev); \ + struct net_device *net_dev = kobj_to_netdev(kobj); \ struct bat_priv *bat_priv = netdev_priv(net_dev); \ return __store_bool_attr(buff, count, _post_func, attr, \ &bat_priv->_name, net_dev); \ @@ -52,9 +53,7 @@ ssize_t store_##_name(struct kobject *kobj, struct attribute *attr, \ ssize_t show_##_name(struct kobject *kobj, struct attribute *attr, \ char *buff) \ { \ - struct device *dev = to_dev(kobj->parent); \ - struct net_device *net_dev = to_net_dev(dev); \ - struct bat_priv *bat_priv = netdev_priv(net_dev); \ + struct bat_priv *bat_priv = kobj_to_batpriv(kobj); \ return sprintf(buff, "%s\n", \ atomic_read(&bat_priv->_name) == 0 ? \ "disabled" : "enabled"); \ @@ -71,8 +70,7 @@ ssize_t show_##_name(struct kobject *kobj, struct attribute *attr, \ ssize_t store_##_name(struct kobject *kobj, struct attribute *attr, \ char *buff, size_t count) \ { \ - struct device *dev = to_dev(kobj->parent); \ - struct net_device *net_dev = to_net_dev(dev); \ + struct net_device *net_dev = kobj_to_netdev(kobj); \ struct bat_priv *bat_priv = netdev_priv(net_dev); \ return __store_uint_attr(buff, count, _min, _max, _post_func, \ attr, &bat_priv->_name, net_dev); \ @@ -82,9 +80,7 @@ ssize_t store_##_name(struct kobject *kobj, struct attribute *attr, \ ssize_t show_##_name(struct kobject *kobj, struct attribute *attr, \ char *buff) \ { \ - struct device *dev = to_dev(kobj->parent); \ - struct net_device *net_dev = to_net_dev(dev); \ - struct bat_priv *bat_priv = netdev_priv(net_dev); \ + struct bat_priv *bat_priv = kobj_to_batpriv(kobj); \ return sprintf(buff, "%i\n", atomic_read(&bat_priv->_name)); \ } \ @@ -204,8 +200,7 @@ static inline ssize_t __store_uint_attr(char *buff, size_t count, static ssize_t show_vis_mode(struct kobject *kobj, struct attribute *attr, char *buff) { - struct device *dev = to_dev(kobj->parent); - struct bat_priv *bat_priv = netdev_priv(to_net_dev(dev)); + struct bat_priv *bat_priv = kobj_to_batpriv(kobj); int vis_mode = atomic_read(&bat_priv->vis_mode); return sprintf(buff, "%s\n", @@ -216,8 +211,7 @@ static ssize_t show_vis_mode(struct kobject *kobj, struct attribute *attr, static ssize_t store_vis_mode(struct kobject *kobj, struct attribute *attr, char *buff, size_t count) { - struct device *dev = to_dev(kobj->parent); - struct net_device *net_dev = to_net_dev(dev); + struct net_device *net_dev = kobj_to_netdev(kobj); struct bat_priv *bat_priv = netdev_priv(net_dev); unsigned long val; int ret, vis_mode_tmp = -1; @@ -329,8 +323,7 @@ void sysfs_del_meshif(struct net_device *dev) static ssize_t show_mesh_iface(struct kobject *kobj, struct attribute *attr, char *buff) { - struct device *dev = to_dev(kobj->parent); - struct net_device *net_dev = to_net_dev(dev); + struct net_device *net_dev = kobj_to_netdev(kobj); struct batman_if *batman_if = get_batman_if_by_netdev(net_dev); ssize_t length; @@ -348,8 +341,7 @@ static ssize_t show_mesh_iface(struct kobject *kobj, struct attribute *attr, static ssize_t store_mesh_iface(struct kobject *kobj, struct attribute *attr, char *buff, size_t count) { - struct device *dev = to_dev(kobj->parent); - struct net_device *net_dev = to_net_dev(dev); + struct net_device *net_dev = kobj_to_netdev(kobj); struct batman_if *batman_if = get_batman_if_by_netdev(net_dev); int status_tmp = -1; int ret; @@ -402,8 +394,7 @@ static ssize_t store_mesh_iface(struct kobject *kobj, struct attribute *attr, static ssize_t show_iface_status(struct kobject *kobj, struct attribute *attr, char *buff) { - struct device *dev = to_dev(kobj->parent); - struct net_device *net_dev = to_net_dev(dev); + struct net_device *net_dev = kobj_to_netdev(kobj); struct batman_if *batman_if = get_batman_if_by_netdev(net_dev); ssize_t length; -- cgit v1.2.3 From 1341a00ad356dfb21978ce4e5e979024558042d2 Mon Sep 17 00:00:00 2001 From: Linus Lüssing Date: Mon, 22 Nov 2010 00:55:55 +0100 Subject: Staging: batman-adv: Make hop_penalty configurable via sysfs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When having a mixed topology of both very mobile and rather static nodes, you are usually best advised to set the originator interval on all nodes to a level best suited for the most mobile node. However, if most of the nodes are rather static, this can create a lot of undesired overhead as a trade-off then. If setting the interval too low on the static nodes, a mobile node might be chosen as a router for too long, not switching away from it fast enough because of its mobility and the low frequency of ogms of static nodes. Exposing the hop_penalty is especially useful for the stated scenario: A static node can keep the default originator interval, a mobile node can select a quicker one resulting in faster route updates towards this mobile node. Additionally, such a mobile node could select a higher hop penalty (or even set it to 255 to disable acting as a router for other nodes) to make it less desirable, letting other nodes avoid selecting this mobile node as a router. Signed-off-by: Linus Lüssing Signed-off-by: Sven Eckelmann Signed-off-by: Greg Kroah-Hartman --- drivers/staging/batman-adv/bat_sysfs.c | 2 ++ drivers/staging/batman-adv/main.h | 2 -- drivers/staging/batman-adv/send.c | 7 ++++--- drivers/staging/batman-adv/soft-interface.c | 1 + drivers/staging/batman-adv/sysfs-class-net-mesh | 7 +++++++ drivers/staging/batman-adv/types.h | 1 + 6 files changed, 15 insertions(+), 5 deletions(-) diff --git a/drivers/staging/batman-adv/bat_sysfs.c b/drivers/staging/batman-adv/bat_sysfs.c index 9bec60de42ba..5ff6e5e6a1e2 100644 --- a/drivers/staging/batman-adv/bat_sysfs.c +++ b/drivers/staging/batman-adv/bat_sysfs.c @@ -254,6 +254,7 @@ BAT_ATTR_BOOL(bonding, S_IRUGO | S_IWUSR, NULL); BAT_ATTR_BOOL(fragmentation, S_IRUGO | S_IWUSR, update_min_mtu); static BAT_ATTR(vis_mode, S_IRUGO | S_IWUSR, show_vis_mode, store_vis_mode); BAT_ATTR_UINT(orig_interval, S_IRUGO | S_IWUSR, 2 * JITTER, INT_MAX, NULL); +BAT_ATTR_UINT(hop_penalty, S_IRUGO | S_IWUSR, 0, TQ_MAX_VALUE, NULL); #ifdef CONFIG_BATMAN_ADV_DEBUG BAT_ATTR_UINT(log_level, S_IRUGO | S_IWUSR, 0, 3, NULL); #endif @@ -264,6 +265,7 @@ static struct bat_attribute *mesh_attrs[] = { &bat_attr_fragmentation, &bat_attr_vis_mode, &bat_attr_orig_interval, + &bat_attr_hop_penalty, #ifdef CONFIG_BATMAN_ADV_DEBUG &bat_attr_log_level, #endif diff --git a/drivers/staging/batman-adv/main.h b/drivers/staging/batman-adv/main.h index ec35ef8920bd..d8d50f35610a 100644 --- a/drivers/staging/batman-adv/main.h +++ b/drivers/staging/batman-adv/main.h @@ -52,8 +52,6 @@ #define TQ_LOCAL_BIDRECT_RECV_MINIMUM 1 #define TQ_TOTAL_BIDRECT_LIMIT 1 -#define TQ_HOP_PENALTY 10 - #define NUM_WORDS (TQ_LOCAL_WINDOW_SIZE / WORD_BIT_SIZE) #define PACKBUFF_SIZE 2000 diff --git a/drivers/staging/batman-adv/send.c b/drivers/staging/batman-adv/send.c index 7adf76ddd0ba..1489b6c760f6 100644 --- a/drivers/staging/batman-adv/send.c +++ b/drivers/staging/batman-adv/send.c @@ -33,9 +33,10 @@ static void send_outstanding_bcast_packet(struct work_struct *work); /* apply hop penalty for a normal link */ -static uint8_t hop_penalty(const uint8_t tq) +static uint8_t hop_penalty(const uint8_t tq, struct bat_priv *bat_priv) { - return (tq * (TQ_MAX_VALUE - TQ_HOP_PENALTY)) / (TQ_MAX_VALUE); + int hop_penalty = atomic_read(&bat_priv->hop_penalty); + return (tq * (TQ_MAX_VALUE - hop_penalty)) / (TQ_MAX_VALUE); } /* when do we schedule our own packet to be sent */ @@ -330,7 +331,7 @@ void schedule_forward_packet(struct orig_node *orig_node, } /* apply hop penalty */ - batman_packet->tq = hop_penalty(batman_packet->tq); + batman_packet->tq = hop_penalty(batman_packet->tq, bat_priv); bat_dbg(DBG_BATMAN, bat_priv, "Forwarding packet: tq_orig: %i, tq_avg: %i, " diff --git a/drivers/staging/batman-adv/soft-interface.c b/drivers/staging/batman-adv/soft-interface.c index c903a76ad0e2..1cf9aa21a408 100644 --- a/drivers/staging/batman-adv/soft-interface.c +++ b/drivers/staging/batman-adv/soft-interface.c @@ -582,6 +582,7 @@ struct net_device *softif_create(char *name) atomic_set(&bat_priv->bonding, 0); atomic_set(&bat_priv->vis_mode, VIS_TYPE_CLIENT_UPDATE); atomic_set(&bat_priv->orig_interval, 1000); + atomic_set(&bat_priv->hop_penalty, 10); atomic_set(&bat_priv->log_level, 0); atomic_set(&bat_priv->fragmentation, 1); atomic_set(&bat_priv->bcast_queue_left, BCAST_QUEUE_LEN); diff --git a/drivers/staging/batman-adv/sysfs-class-net-mesh b/drivers/staging/batman-adv/sysfs-class-net-mesh index b4cdb6038bf1..bd20e14261c0 100644 --- a/drivers/staging/batman-adv/sysfs-class-net-mesh +++ b/drivers/staging/batman-adv/sysfs-class-net-mesh @@ -29,6 +29,13 @@ Description: Defines the interval in milliseconds in which batman sends its protocol messages. +What: /sys/class/net//mesh/hop_penalty +Date: Oct 2010 +Contact: Linus Lüssing +Description: + Defines the penalty which will be applied to an + originator message's tq-field on every hop. + What: /sys/class/net//mesh/vis_mode Date: May 2010 Contact: Marek Lindner diff --git a/drivers/staging/batman-adv/types.h b/drivers/staging/batman-adv/types.h index 4463da391498..e41f95fbf61f 100644 --- a/drivers/staging/batman-adv/types.h +++ b/drivers/staging/batman-adv/types.h @@ -118,6 +118,7 @@ struct bat_priv { atomic_t fragmentation; /* boolean */ atomic_t vis_mode; /* VIS_TYPE_* */ atomic_t orig_interval; /* uint */ + atomic_t hop_penalty; /* uint */ atomic_t log_level; /* uint */ atomic_t bcast_seqno; atomic_t bcast_queue_left; -- cgit v1.2.3 From 51f3d8a27c1a1ac6aced25ea93fc5c0520e9256c Mon Sep 17 00:00:00 2001 From: Sven Eckelmann Date: Mon, 22 Nov 2010 00:55:56 +0100 Subject: Staging: batman-adv: Remove hashdata_compare_cb from hash Function pointers cannot be inlined by a compiler and thus always has the overhead of an call. hashdata_compare_cb's are one of the most often called function pointers and its overhead must kept relative low. As first step, every function which uses this function pointer takes it as parameter instead of storing it inside the hash abstraction structure. This not generate any performance gain right now. The called functions must also be able to be inlined by the calling functions to enable inlining of the function pointer. Reported-by: David S. Miller Signed-off-by: Sven Eckelmann Signed-off-by: Greg Kroah-Hartman --- drivers/staging/batman-adv/TODO | 2 +- drivers/staging/batman-adv/hash.c | 25 +++++++++-------- drivers/staging/batman-adv/hash.h | 23 +++++++-------- drivers/staging/batman-adv/icmp_socket.c | 2 ++ drivers/staging/batman-adv/main.c | 7 ----- drivers/staging/batman-adv/main.h | 1 - drivers/staging/batman-adv/originator.c | 9 +++--- drivers/staging/batman-adv/originator.h | 7 +++++ drivers/staging/batman-adv/routing.c | 15 ++++++---- drivers/staging/batman-adv/send.c | 1 + drivers/staging/batman-adv/translation-table.c | 39 ++++++++++++++++---------- drivers/staging/batman-adv/unicast.c | 5 +++- drivers/staging/batman-adv/vis.c | 15 ++++++---- 13 files changed, 89 insertions(+), 62 deletions(-) diff --git a/drivers/staging/batman-adv/TODO b/drivers/staging/batman-adv/TODO index 7967ffaa833e..a9c77d671a5a 100644 --- a/drivers/staging/batman-adv/TODO +++ b/drivers/staging/batman-adv/TODO @@ -1,6 +1,6 @@ * remove own list functionality from hash * use hlist_head, hlist_node in hash - * don't use callbacks for compare+choose in hash + * don't use callbacks for choose in hash * think about more efficient ways instead of abstraction of hash * Request a new review * Process the comments from the review diff --git a/drivers/staging/batman-adv/hash.c b/drivers/staging/batman-adv/hash.c index 8ef26eb4949d..a4abe140a953 100644 --- a/drivers/staging/batman-adv/hash.c +++ b/drivers/staging/batman-adv/hash.c @@ -137,8 +137,7 @@ struct hash_it_t *hash_iterate(struct hashtable_t *hash, } /* allocates and clears the hash */ -struct hashtable_t *hash_new(int size, hashdata_compare_cb compare, - hashdata_choose_cb choose) +struct hashtable_t *hash_new(int size, hashdata_choose_cb choose) { struct hashtable_t *hash; @@ -157,14 +156,13 @@ struct hashtable_t *hash_new(int size, hashdata_compare_cb compare, hash_init(hash); - hash->compare = compare; hash->choose = choose; return hash; } /* adds data to the hashtable. returns 0 on success, -1 on error */ -int hash_add(struct hashtable_t *hash, void *data) +int hash_add(struct hashtable_t *hash, hashdata_compare_cb compare, void *data) { int index; struct element_t *bucket, *prev_bucket = NULL; @@ -176,7 +174,7 @@ int hash_add(struct hashtable_t *hash, void *data) bucket = hash->table[index]; while (bucket != NULL) { - if (hash->compare(bucket->data, data)) + if (compare(bucket->data, data)) return -1; prev_bucket = bucket; @@ -204,7 +202,8 @@ int hash_add(struct hashtable_t *hash, void *data) /* finds data, based on the key in keydata. returns the found data on success, * or NULL on error */ -void *hash_find(struct hashtable_t *hash, void *keydata) +void *hash_find(struct hashtable_t *hash, hashdata_compare_cb compare, + void *keydata) { int index; struct element_t *bucket; @@ -216,7 +215,7 @@ void *hash_find(struct hashtable_t *hash, void *keydata) bucket = hash->table[index]; while (bucket != NULL) { - if (hash->compare(bucket->data, keydata)) + if (compare(bucket->data, keydata)) return bucket->data; bucket = bucket->next; @@ -250,7 +249,8 @@ void *hash_remove_bucket(struct hashtable_t *hash, struct hash_it_t *hash_it_t) * can remove the used structure yourself, or NULL on error . data could be the * structure you use with just the key filled, we just need the key for * comparing. */ -void *hash_remove(struct hashtable_t *hash, void *data) +void *hash_remove(struct hashtable_t *hash, hashdata_compare_cb compare, + void *data) { struct hash_it_t hash_it_t; @@ -259,7 +259,7 @@ void *hash_remove(struct hashtable_t *hash, void *data) hash_it_t.prev_bucket = NULL; while (hash_it_t.bucket != NULL) { - if (hash->compare(hash_it_t.bucket->data, data)) { + if (compare(hash_it_t.bucket->data, data)) { hash_it_t.first_bucket = (hash_it_t.bucket == hash->table[hash_it_t.index] ? @@ -276,14 +276,15 @@ void *hash_remove(struct hashtable_t *hash, void *data) /* resize the hash, returns the pointer to the new hash or NULL on * error. removes the old hash on success. */ -struct hashtable_t *hash_resize(struct hashtable_t *hash, int size) +struct hashtable_t *hash_resize(struct hashtable_t *hash, + hashdata_compare_cb compare, int size) { struct hashtable_t *new_hash; struct element_t *bucket; int i; /* initialize a new hash with the new size */ - new_hash = hash_new(size, hash->compare, hash->choose); + new_hash = hash_new(size, hash->choose); if (new_hash == NULL) return NULL; @@ -293,7 +294,7 @@ struct hashtable_t *hash_resize(struct hashtable_t *hash, int size) bucket = hash->table[i]; while (bucket != NULL) { - hash_add(new_hash, bucket->data); + hash_add(new_hash, compare, bucket->data); bucket = bucket->next; } } diff --git a/drivers/staging/batman-adv/hash.h b/drivers/staging/batman-adv/hash.h index 2c8e1762389f..742277ea980b 100644 --- a/drivers/staging/batman-adv/hash.h +++ b/drivers/staging/batman-adv/hash.h @@ -27,7 +27,10 @@ .prev_bucket = NULL, \ .first_bucket = NULL } - +/* callback to a compare function. should + * compare 2 element datas for their keys, + * return 0 if same and not 0 if not + * same */ typedef int (*hashdata_compare_cb)(void *, void *); typedef int (*hashdata_choose_cb)(void *, int); typedef void (*hashdata_free_cb)(void *, void *); @@ -48,18 +51,13 @@ struct hashtable_t { struct element_t **table; /* the hashtable itself, with the buckets */ int elements; /* number of elements registered */ int size; /* size of hashtable */ - hashdata_compare_cb compare;/* callback to a compare function. should - * compare 2 element datas for their keys, - * return 0 if same and not 0 if not - * same */ hashdata_choose_cb choose; /* the hashfunction, should return an index * based on the key in the data of the first * argument and the size the second */ }; /* allocates and clears the hash */ -struct hashtable_t *hash_new(int size, hashdata_compare_cb compare, - hashdata_choose_cb choose); +struct hashtable_t *hash_new(int size, hashdata_choose_cb choose); /* remove bucket (this might be used in hash_iterate() if you already found the * bucket you want to delete and don't need the overhead to find it again with @@ -76,21 +74,24 @@ void hash_delete(struct hashtable_t *hash, hashdata_free_cb free_cb, void *arg); void hash_destroy(struct hashtable_t *hash); /* adds data to the hashtable. returns 0 on success, -1 on error */ -int hash_add(struct hashtable_t *hash, void *data); +int hash_add(struct hashtable_t *hash, hashdata_compare_cb compare, void *data); /* removes data from hash, if found. returns pointer do data on success, so you * can remove the used structure yourself, or NULL on error . data could be the * structure you use with just the key filled, we just need the key for * comparing. */ -void *hash_remove(struct hashtable_t *hash, void *data); +void *hash_remove(struct hashtable_t *hash, hashdata_compare_cb compare, + void *data); /* finds data, based on the key in keydata. returns the found data on success, * or NULL on error */ -void *hash_find(struct hashtable_t *hash, void *keydata); +void *hash_find(struct hashtable_t *hash, hashdata_compare_cb compare, + void *keydata); /* resize the hash, returns the pointer to the new hash or NULL on * error. removes the old hash on success */ -struct hashtable_t *hash_resize(struct hashtable_t *hash, int size); +struct hashtable_t *hash_resize(struct hashtable_t *hash, + hashdata_compare_cb compare, int size); /* iterate though the hash. first element is selected with iter_in NULL. use * the returned iterator to access the elements until hash_it_t returns NULL. */ diff --git a/drivers/staging/batman-adv/icmp_socket.c b/drivers/staging/batman-adv/icmp_socket.c index 48856ca73b6a..a7b98ce295f9 100644 --- a/drivers/staging/batman-adv/icmp_socket.c +++ b/drivers/staging/batman-adv/icmp_socket.c @@ -26,6 +26,7 @@ #include "send.h" #include "types.h" #include "hash.h" +#include "originator.h" #include "hard-interface.h" @@ -225,6 +226,7 @@ static ssize_t bat_socket_write(struct file *file, const char __user *buff, spin_lock_irqsave(&bat_priv->orig_hash_lock, flags); orig_node = ((struct orig_node *)hash_find(bat_priv->orig_hash, + compare_orig, icmp_packet->dst)); if (!orig_node) diff --git a/drivers/staging/batman-adv/main.c b/drivers/staging/batman-adv/main.c index f7d6733e3d9a..2ed77dd88509 100644 --- a/drivers/staging/batman-adv/main.c +++ b/drivers/staging/batman-adv/main.c @@ -149,13 +149,6 @@ void dec_module_count(void) module_put(THIS_MODULE); } -/* returns 1 if they are the same originator */ - -int compare_orig(void *data1, void *data2) -{ - return (memcmp(data1, data2, ETH_ALEN) == 0 ? 1 : 0); -} - /* hashfunction to choose an entry in a hash table of given size */ /* hash algorithm from http://en.wikipedia.org/wiki/Hash_table */ int choose_orig(void *data, int32_t size) diff --git a/drivers/staging/batman-adv/main.h b/drivers/staging/batman-adv/main.h index d8d50f35610a..97a74b047c57 100644 --- a/drivers/staging/batman-adv/main.h +++ b/drivers/staging/batman-adv/main.h @@ -135,7 +135,6 @@ int mesh_init(struct net_device *soft_iface); void mesh_free(struct net_device *soft_iface); void inc_module_count(void); void dec_module_count(void); -int compare_orig(void *data1, void *data2); int choose_orig(void *data, int32_t size); int is_my_mac(uint8_t *addr); int is_bcast(uint8_t *addr); diff --git a/drivers/staging/batman-adv/originator.c b/drivers/staging/batman-adv/originator.c index fc7fb31b5eda..7735b7fcf157 100644 --- a/drivers/staging/batman-adv/originator.c +++ b/drivers/staging/batman-adv/originator.c @@ -45,7 +45,7 @@ int originator_init(struct bat_priv *bat_priv) return 1; spin_lock_irqsave(&bat_priv->orig_hash_lock, flags); - bat_priv->orig_hash = hash_new(128, compare_orig, choose_orig); + bat_priv->orig_hash = hash_new(128, choose_orig); if (!bat_priv->orig_hash) goto err; @@ -129,7 +129,8 @@ struct orig_node *get_orig_node(struct bat_priv *bat_priv, uint8_t *addr) struct hashtable_t *swaphash; int size; - orig_node = ((struct orig_node *)hash_find(bat_priv->orig_hash, addr)); + orig_node = ((struct orig_node *)hash_find(bat_priv->orig_hash, + compare_orig, addr)); if (orig_node) return orig_node; @@ -166,11 +167,11 @@ struct orig_node *get_orig_node(struct bat_priv *bat_priv, uint8_t *addr) if (!orig_node->bcast_own_sum) goto free_bcast_own; - if (hash_add(bat_priv->orig_hash, orig_node) < 0) + if (hash_add(bat_priv->orig_hash, compare_orig, orig_node) < 0) goto free_bcast_own_sum; if (bat_priv->orig_hash->elements * 4 > bat_priv->orig_hash->size) { - swaphash = hash_resize(bat_priv->orig_hash, + swaphash = hash_resize(bat_priv->orig_hash, compare_orig, bat_priv->orig_hash->size * 2); if (!swaphash) diff --git a/drivers/staging/batman-adv/originator.h b/drivers/staging/batman-adv/originator.h index a97c4004776a..ed903dcaa35c 100644 --- a/drivers/staging/batman-adv/originator.h +++ b/drivers/staging/batman-adv/originator.h @@ -33,4 +33,11 @@ int orig_seq_print_text(struct seq_file *seq, void *offset); int orig_hash_add_if(struct batman_if *batman_if, int max_if_num); int orig_hash_del_if(struct batman_if *batman_if, int max_if_num); + +/* returns 1 if they are the same originator */ +static inline int compare_orig(void *data1, void *data2) +{ + return (memcmp(data1, data2, ETH_ALEN) == 0 ? 1 : 0); +} + #endif /* _NET_BATMAN_ADV_ORIGINATOR_H_ */ diff --git a/drivers/staging/batman-adv/routing.c b/drivers/staging/batman-adv/routing.c index 1b3548634904..bb0bd7871959 100644 --- a/drivers/staging/batman-adv/routing.c +++ b/drivers/staging/batman-adv/routing.c @@ -811,6 +811,7 @@ static int recv_my_icmp_packet(struct bat_priv *bat_priv, /* get routing information */ spin_lock_irqsave(&bat_priv->orig_hash_lock, flags); orig_node = ((struct orig_node *)hash_find(bat_priv->orig_hash, + compare_orig, icmp_packet->orig)); ret = NET_RX_DROP; @@ -873,7 +874,8 @@ static int recv_icmp_ttl_exceeded(struct bat_priv *bat_priv, /* get routing information */ spin_lock_irqsave(&bat_priv->orig_hash_lock, flags); orig_node = ((struct orig_node *) - hash_find(bat_priv->orig_hash, icmp_packet->orig)); + hash_find(bat_priv->orig_hash, compare_orig, + icmp_packet->orig)); ret = NET_RX_DROP; if ((orig_node != NULL) && @@ -967,7 +969,8 @@ int recv_icmp_packet(struct sk_buff *skb, struct batman_if *recv_if) /* get routing information */ spin_lock_irqsave(&bat_priv->orig_hash_lock, flags); orig_node = ((struct orig_node *) - hash_find(bat_priv->orig_hash, icmp_packet->dst)); + hash_find(bat_priv->orig_hash, compare_orig, + icmp_packet->dst)); if ((orig_node != NULL) && (orig_node->router != NULL)) { @@ -1038,7 +1041,7 @@ struct neigh_node *find_router(struct bat_priv *bat_priv, router_orig->orig, ETH_ALEN) == 0) { primary_orig_node = router_orig; } else { - primary_orig_node = hash_find(bat_priv->orig_hash, + primary_orig_node = hash_find(bat_priv->orig_hash, compare_orig, router_orig->primary_addr); if (!primary_orig_node) @@ -1144,7 +1147,8 @@ int route_unicast_packet(struct sk_buff *skb, struct batman_if *recv_if, /* get routing information */ spin_lock_irqsave(&bat_priv->orig_hash_lock, flags); orig_node = ((struct orig_node *) - hash_find(bat_priv->orig_hash, unicast_packet->dest)); + hash_find(bat_priv->orig_hash, compare_orig, + unicast_packet->dest)); router = find_router(bat_priv, orig_node, recv_if); @@ -1290,7 +1294,8 @@ int recv_bcast_packet(struct sk_buff *skb, struct batman_if *recv_if) spin_lock_irqsave(&bat_priv->orig_hash_lock, flags); orig_node = ((struct orig_node *) - hash_find(bat_priv->orig_hash, bcast_packet->orig)); + hash_find(bat_priv->orig_hash, compare_orig, + bcast_packet->orig)); if (orig_node == NULL) { spin_unlock_irqrestore(&bat_priv->orig_hash_lock, flags); diff --git a/drivers/staging/batman-adv/send.c b/drivers/staging/batman-adv/send.c index 1489b6c760f6..1840ef0e3755 100644 --- a/drivers/staging/batman-adv/send.c +++ b/drivers/staging/batman-adv/send.c @@ -28,6 +28,7 @@ #include "types.h" #include "vis.h" #include "aggregation.h" +#include "originator.h" static void send_outstanding_bcast_packet(struct work_struct *work); diff --git a/drivers/staging/batman-adv/translation-table.c b/drivers/staging/batman-adv/translation-table.c index 3bc752111638..33cd5daa414c 100644 --- a/drivers/staging/batman-adv/translation-table.c +++ b/drivers/staging/batman-adv/translation-table.c @@ -24,6 +24,7 @@ #include "soft-interface.h" #include "types.h" #include "hash.h" +#include "originator.h" static void hna_local_purge(struct work_struct *work); static void _hna_global_del_orig(struct bat_priv *bat_priv, @@ -41,7 +42,7 @@ int hna_local_init(struct bat_priv *bat_priv) if (bat_priv->hna_local_hash) return 1; - bat_priv->hna_local_hash = hash_new(128, compare_orig, choose_orig); + bat_priv->hna_local_hash = hash_new(128, choose_orig); if (!bat_priv->hna_local_hash) return 0; @@ -64,7 +65,7 @@ void hna_local_add(struct net_device *soft_iface, uint8_t *addr) spin_lock_irqsave(&bat_priv->hna_lhash_lock, flags); hna_local_entry = ((struct hna_local_entry *)hash_find(bat_priv->hna_local_hash, - addr)); + compare_orig, addr)); spin_unlock_irqrestore(&bat_priv->hna_lhash_lock, flags); if (hna_local_entry) { @@ -107,13 +108,13 @@ void hna_local_add(struct net_device *soft_iface, uint8_t *addr) spin_lock_irqsave(&bat_priv->hna_lhash_lock, flags); - hash_add(bat_priv->hna_local_hash, hna_local_entry); + hash_add(bat_priv->hna_local_hash, compare_orig, hna_local_entry); bat_priv->num_local_hna++; atomic_set(&bat_priv->hna_local_changed, 1); if (bat_priv->hna_local_hash->elements * 4 > bat_priv->hna_local_hash->size) { - swaphash = hash_resize(bat_priv->hna_local_hash, + swaphash = hash_resize(bat_priv->hna_local_hash, compare_orig, bat_priv->hna_local_hash->size * 2); if (!swaphash) @@ -128,7 +129,8 @@ void hna_local_add(struct net_device *soft_iface, uint8_t *addr) spin_lock_irqsave(&bat_priv->hna_ghash_lock, flags); hna_global_entry = ((struct hna_global_entry *) - hash_find(bat_priv->hna_global_hash, addr)); + hash_find(bat_priv->hna_global_hash, + compare_orig, addr)); if (hna_global_entry) _hna_global_del_orig(bat_priv, hna_global_entry, @@ -232,7 +234,8 @@ static void hna_local_del(struct bat_priv *bat_priv, bat_dbg(DBG_ROUTES, bat_priv, "Deleting local hna entry (%pM): %s\n", hna_local_entry->addr, message); - hash_remove(bat_priv->hna_local_hash, hna_local_entry->addr); + hash_remove(bat_priv->hna_local_hash, compare_orig, + hna_local_entry->addr); _hna_local_del(hna_local_entry, bat_priv); } @@ -245,7 +248,7 @@ void hna_local_remove(struct bat_priv *bat_priv, spin_lock_irqsave(&bat_priv->hna_lhash_lock, flags); hna_local_entry = (struct hna_local_entry *) - hash_find(bat_priv->hna_local_hash, addr); + hash_find(bat_priv->hna_local_hash, compare_orig, addr); if (hna_local_entry) hna_local_del(bat_priv, hna_local_entry, message); @@ -295,7 +298,7 @@ int hna_global_init(struct bat_priv *bat_priv) if (bat_priv->hna_global_hash) return 1; - bat_priv->hna_global_hash = hash_new(128, compare_orig, choose_orig); + bat_priv->hna_global_hash = hash_new(128, choose_orig); if (!bat_priv->hna_global_hash) return 0; @@ -319,7 +322,8 @@ void hna_global_add_orig(struct bat_priv *bat_priv, hna_ptr = hna_buff + (hna_buff_count * ETH_ALEN); hna_global_entry = (struct hna_global_entry *) - hash_find(bat_priv->hna_global_hash, hna_ptr); + hash_find(bat_priv->hna_global_hash, compare_orig, + hna_ptr); if (!hna_global_entry) { spin_unlock_irqrestore(&bat_priv->hna_ghash_lock, @@ -340,7 +344,8 @@ void hna_global_add_orig(struct bat_priv *bat_priv, hna_global_entry->addr, orig_node->orig); spin_lock_irqsave(&bat_priv->hna_ghash_lock, flags); - hash_add(bat_priv->hna_global_hash, hna_global_entry); + hash_add(bat_priv->hna_global_hash, compare_orig, + hna_global_entry); } @@ -352,7 +357,8 @@ void hna_global_add_orig(struct bat_priv *bat_priv, hna_ptr = hna_buff + (hna_buff_count * ETH_ALEN); hna_local_entry = (struct hna_local_entry *) - hash_find(bat_priv->hna_local_hash, hna_ptr); + hash_find(bat_priv->hna_local_hash, compare_orig, + hna_ptr); if (hna_local_entry) hna_local_del(bat_priv, hna_local_entry, @@ -379,7 +385,7 @@ void hna_global_add_orig(struct bat_priv *bat_priv, if (bat_priv->hna_global_hash->elements * 4 > bat_priv->hna_global_hash->size) { - swaphash = hash_resize(bat_priv->hna_global_hash, + swaphash = hash_resize(bat_priv->hna_global_hash, compare_orig, bat_priv->hna_global_hash->size * 2); if (!swaphash) @@ -450,7 +456,8 @@ static void _hna_global_del_orig(struct bat_priv *bat_priv, hna_global_entry->addr, hna_global_entry->orig_node->orig, message); - hash_remove(bat_priv->hna_global_hash, hna_global_entry->addr); + hash_remove(bat_priv->hna_global_hash, compare_orig, + hna_global_entry->addr); kfree(hna_global_entry); } @@ -470,7 +477,8 @@ void hna_global_del_orig(struct bat_priv *bat_priv, while ((hna_buff_count + 1) * ETH_ALEN <= orig_node->hna_buff_len) { hna_ptr = orig_node->hna_buff + (hna_buff_count * ETH_ALEN); hna_global_entry = (struct hna_global_entry *) - hash_find(bat_priv->hna_global_hash, hna_ptr); + hash_find(bat_priv->hna_global_hash, compare_orig, + hna_ptr); if ((hna_global_entry) && (hna_global_entry->orig_node == orig_node)) @@ -508,7 +516,8 @@ struct orig_node *transtable_search(struct bat_priv *bat_priv, uint8_t *addr) spin_lock_irqsave(&bat_priv->hna_ghash_lock, flags); hna_global_entry = (struct hna_global_entry *) - hash_find(bat_priv->hna_global_hash, addr); + hash_find(bat_priv->hna_global_hash, + compare_orig, addr); spin_unlock_irqrestore(&bat_priv->hna_ghash_lock, flags); if (!hna_global_entry) diff --git a/drivers/staging/batman-adv/unicast.c b/drivers/staging/batman-adv/unicast.c index 5ae959327b48..1f4d911d9e5a 100644 --- a/drivers/staging/batman-adv/unicast.c +++ b/drivers/staging/batman-adv/unicast.c @@ -23,6 +23,7 @@ #include "unicast.h" #include "send.h" #include "soft-interface.h" +#include "originator.h" #include "hash.h" #include "translation-table.h" #include "routing.h" @@ -179,7 +180,8 @@ int frag_reassemble_skb(struct sk_buff *skb, struct bat_priv *bat_priv, *new_skb = NULL; spin_lock_irqsave(&bat_priv->orig_hash_lock, flags); orig_node = ((struct orig_node *) - hash_find(bat_priv->orig_hash, unicast_packet->orig)); + hash_find(bat_priv->orig_hash, compare_orig, + unicast_packet->orig)); if (!orig_node) { pr_debug("couldn't find originator in orig_hash\n"); @@ -283,6 +285,7 @@ int unicast_send_skb(struct sk_buff *skb, struct bat_priv *bat_priv) /* get routing information */ orig_node = ((struct orig_node *)hash_find(bat_priv->orig_hash, + compare_orig, ethhdr->h_dest)); /* check for hna host */ diff --git a/drivers/staging/batman-adv/vis.c b/drivers/staging/batman-adv/vis.c index 4473cc8ed6b0..ff0abe9f5607 100644 --- a/drivers/staging/batman-adv/vis.c +++ b/drivers/staging/batman-adv/vis.c @@ -26,6 +26,7 @@ #include "soft-interface.h" #include "hard-interface.h" #include "hash.h" +#include "originator.h" #define MAX_VIS_PACKET_SIZE 1000 @@ -363,7 +364,7 @@ static struct vis_info *add_packet(struct bat_priv *bat_priv, sizeof(struct vis_packet)); memcpy(search_packet->vis_orig, vis_packet->vis_orig, ETH_ALEN); - old_info = hash_find(bat_priv->vis_hash, &search_elem); + old_info = hash_find(bat_priv->vis_hash, vis_info_cmp, &search_elem); kfree_skb(search_elem.skb_packet); if (old_info != NULL) { @@ -380,7 +381,7 @@ static struct vis_info *add_packet(struct bat_priv *bat_priv, } } /* remove old entry */ - hash_remove(bat_priv->vis_hash, old_info); + hash_remove(bat_priv->vis_hash, vis_info_cmp, old_info); send_list_del(old_info); kref_put(&old_info->refcount, free_info); } @@ -421,7 +422,7 @@ static struct vis_info *add_packet(struct bat_priv *bat_priv, recv_list_add(bat_priv, &info->recv_list, packet->sender_orig); /* try to add it */ - if (hash_add(bat_priv->vis_hash, info) < 0) { + if (hash_add(bat_priv->vis_hash, vis_info_cmp, info) < 0) { /* did not work (for some reason) */ kref_put(&old_info->refcount, free_info); info = NULL; @@ -710,6 +711,7 @@ static void unicast_vis_packet(struct bat_priv *bat_priv, spin_lock_irqsave(&bat_priv->orig_hash_lock, flags); packet = (struct vis_packet *)info->skb_packet->data; orig_node = ((struct orig_node *)hash_find(bat_priv->orig_hash, + compare_orig, packet->target_orig)); if ((!orig_node) || (!orig_node->router)) @@ -794,13 +796,14 @@ int vis_init(struct bat_priv *bat_priv) { struct vis_packet *packet; unsigned long flags; + int hash_added; if (bat_priv->vis_hash) return 1; spin_lock_irqsave(&bat_priv->vis_hash_lock, flags); - bat_priv->vis_hash = hash_new(256, vis_info_cmp, vis_info_choose); + bat_priv->vis_hash = hash_new(256, vis_info_choose); if (!bat_priv->vis_hash) { pr_err("Can't initialize vis_hash\n"); goto err; @@ -839,7 +842,9 @@ int vis_init(struct bat_priv *bat_priv) INIT_LIST_HEAD(&bat_priv->vis_send_list); - if (hash_add(bat_priv->vis_hash, bat_priv->my_vis_info) < 0) { + hash_added = hash_add(bat_priv->vis_hash, vis_info_cmp, + bat_priv->my_vis_info); + if (hash_added < 0) { pr_err("Can't add own vis packet into hash\n"); /* not in hash, need to remove it manually. */ kref_put(&bat_priv->my_vis_info->refcount, free_info); -- cgit v1.2.3 From 6d5e654240dc14ded3d74aa5df6857572ba9f5e3 Mon Sep 17 00:00:00 2001 From: Sven Eckelmann Date: Mon, 22 Nov 2010 00:55:57 +0100 Subject: Staging: batman-adv: Remove hashdata_choose_cb from hash Function pointers cannot be inlined by a compiler and thus always has the overhead of an call. hashdata_choose_cb's are one of the most often called function pointers and its overhead must kept relative low. As first step, every function which uses this function pointer takes it as parameter instead of storing it inside the hash abstraction structure. This not generate any performance gain right now. The called functions must also be able to be inlined by the calling functions to enable inlining of the function pointer. Reported-by: David S. Miller Signed-off-by: Sven Eckelmann Signed-off-by: Greg Kroah-Hartman --- drivers/staging/batman-adv/TODO | 1 - drivers/staging/batman-adv/hash.c | 24 ++++++++++---------- drivers/staging/batman-adv/hash.h | 19 +++++++++------- drivers/staging/batman-adv/icmp_socket.c | 2 +- drivers/staging/batman-adv/main.c | 21 ----------------- drivers/staging/batman-adv/main.h | 1 - drivers/staging/batman-adv/originator.c | 11 ++++++--- drivers/staging/batman-adv/originator.h | 21 +++++++++++++++++ drivers/staging/batman-adv/routing.c | 13 ++++++----- drivers/staging/batman-adv/translation-table.c | 31 +++++++++++++++----------- drivers/staging/batman-adv/unicast.c | 3 ++- drivers/staging/batman-adv/vis.c | 17 +++++++++----- 12 files changed, 91 insertions(+), 73 deletions(-) diff --git a/drivers/staging/batman-adv/TODO b/drivers/staging/batman-adv/TODO index a9c77d671a5a..2c02aa107de8 100644 --- a/drivers/staging/batman-adv/TODO +++ b/drivers/staging/batman-adv/TODO @@ -1,6 +1,5 @@ * remove own list functionality from hash * use hlist_head, hlist_node in hash - * don't use callbacks for choose in hash * think about more efficient ways instead of abstraction of hash * Request a new review * Process the comments from the review diff --git a/drivers/staging/batman-adv/hash.c b/drivers/staging/batman-adv/hash.c index a4abe140a953..6361a3175520 100644 --- a/drivers/staging/batman-adv/hash.c +++ b/drivers/staging/batman-adv/hash.c @@ -137,7 +137,7 @@ struct hash_it_t *hash_iterate(struct hashtable_t *hash, } /* allocates and clears the hash */ -struct hashtable_t *hash_new(int size, hashdata_choose_cb choose) +struct hashtable_t *hash_new(int size) { struct hashtable_t *hash; @@ -156,13 +156,12 @@ struct hashtable_t *hash_new(int size, hashdata_choose_cb choose) hash_init(hash); - hash->choose = choose; - return hash; } /* adds data to the hashtable. returns 0 on success, -1 on error */ -int hash_add(struct hashtable_t *hash, hashdata_compare_cb compare, void *data) +int hash_add(struct hashtable_t *hash, hashdata_compare_cb compare, + hashdata_choose_cb choose, void *data) { int index; struct element_t *bucket, *prev_bucket = NULL; @@ -170,7 +169,7 @@ int hash_add(struct hashtable_t *hash, hashdata_compare_cb compare, void *data) if (!hash) return -1; - index = hash->choose(data, hash->size); + index = choose(data, hash->size); bucket = hash->table[index]; while (bucket != NULL) { @@ -203,7 +202,7 @@ int hash_add(struct hashtable_t *hash, hashdata_compare_cb compare, void *data) /* finds data, based on the key in keydata. returns the found data on success, * or NULL on error */ void *hash_find(struct hashtable_t *hash, hashdata_compare_cb compare, - void *keydata) + hashdata_choose_cb choose, void *keydata) { int index; struct element_t *bucket; @@ -211,7 +210,7 @@ void *hash_find(struct hashtable_t *hash, hashdata_compare_cb compare, if (!hash) return NULL; - index = hash->choose(keydata , hash->size); + index = choose(keydata , hash->size); bucket = hash->table[index]; while (bucket != NULL) { @@ -250,11 +249,11 @@ void *hash_remove_bucket(struct hashtable_t *hash, struct hash_it_t *hash_it_t) * structure you use with just the key filled, we just need the key for * comparing. */ void *hash_remove(struct hashtable_t *hash, hashdata_compare_cb compare, - void *data) + hashdata_choose_cb choose, void *data) { struct hash_it_t hash_it_t; - hash_it_t.index = hash->choose(data, hash->size); + hash_it_t.index = choose(data, hash->size); hash_it_t.bucket = hash->table[hash_it_t.index]; hash_it_t.prev_bucket = NULL; @@ -277,14 +276,15 @@ void *hash_remove(struct hashtable_t *hash, hashdata_compare_cb compare, /* resize the hash, returns the pointer to the new hash or NULL on * error. removes the old hash on success. */ struct hashtable_t *hash_resize(struct hashtable_t *hash, - hashdata_compare_cb compare, int size) + hashdata_compare_cb compare, + hashdata_choose_cb choose, int size) { struct hashtable_t *new_hash; struct element_t *bucket; int i; /* initialize a new hash with the new size */ - new_hash = hash_new(size, hash->choose); + new_hash = hash_new(size); if (new_hash == NULL) return NULL; @@ -294,7 +294,7 @@ struct hashtable_t *hash_resize(struct hashtable_t *hash, bucket = hash->table[i]; while (bucket != NULL) { - hash_add(new_hash, compare, bucket->data); + hash_add(new_hash, compare, choose, bucket->data); bucket = bucket->next; } } diff --git a/drivers/staging/batman-adv/hash.h b/drivers/staging/batman-adv/hash.h index 742277ea980b..85ee12b0779a 100644 --- a/drivers/staging/batman-adv/hash.h +++ b/drivers/staging/batman-adv/hash.h @@ -32,6 +32,10 @@ * return 0 if same and not 0 if not * same */ typedef int (*hashdata_compare_cb)(void *, void *); + +/* the hashfunction, should return an index + * based on the key in the data of the first + * argument and the size the second */ typedef int (*hashdata_choose_cb)(void *, int); typedef void (*hashdata_free_cb)(void *, void *); @@ -51,13 +55,10 @@ struct hashtable_t { struct element_t **table; /* the hashtable itself, with the buckets */ int elements; /* number of elements registered */ int size; /* size of hashtable */ - hashdata_choose_cb choose; /* the hashfunction, should return an index - * based on the key in the data of the first - * argument and the size the second */ }; /* allocates and clears the hash */ -struct hashtable_t *hash_new(int size, hashdata_choose_cb choose); +struct hashtable_t *hash_new(int size); /* remove bucket (this might be used in hash_iterate() if you already found the * bucket you want to delete and don't need the overhead to find it again with @@ -74,24 +75,26 @@ void hash_delete(struct hashtable_t *hash, hashdata_free_cb free_cb, void *arg); void hash_destroy(struct hashtable_t *hash); /* adds data to the hashtable. returns 0 on success, -1 on error */ -int hash_add(struct hashtable_t *hash, hashdata_compare_cb compare, void *data); +int hash_add(struct hashtable_t *hash, hashdata_compare_cb compare, + hashdata_choose_cb choose, void *data); /* removes data from hash, if found. returns pointer do data on success, so you * can remove the used structure yourself, or NULL on error . data could be the * structure you use with just the key filled, we just need the key for * comparing. */ void *hash_remove(struct hashtable_t *hash, hashdata_compare_cb compare, - void *data); + hashdata_choose_cb choose, void *data); /* finds data, based on the key in keydata. returns the found data on success, * or NULL on error */ void *hash_find(struct hashtable_t *hash, hashdata_compare_cb compare, - void *keydata); + hashdata_choose_cb choose, void *keydata); /* resize the hash, returns the pointer to the new hash or NULL on * error. removes the old hash on success */ struct hashtable_t *hash_resize(struct hashtable_t *hash, - hashdata_compare_cb compare, int size); + hashdata_compare_cb compare, + hashdata_choose_cb choose, int size); /* iterate though the hash. first element is selected with iter_in NULL. use * the returned iterator to access the elements until hash_it_t returns NULL. */ diff --git a/drivers/staging/batman-adv/icmp_socket.c b/drivers/staging/batman-adv/icmp_socket.c index a7b98ce295f9..a8c98aa9630c 100644 --- a/drivers/staging/batman-adv/icmp_socket.c +++ b/drivers/staging/batman-adv/icmp_socket.c @@ -226,7 +226,7 @@ static ssize_t bat_socket_write(struct file *file, const char __user *buff, spin_lock_irqsave(&bat_priv->orig_hash_lock, flags); orig_node = ((struct orig_node *)hash_find(bat_priv->orig_hash, - compare_orig, + compare_orig, choose_orig, icmp_packet->dst)); if (!orig_node) diff --git a/drivers/staging/batman-adv/main.c b/drivers/staging/batman-adv/main.c index 2ed77dd88509..61d1aa66e956 100644 --- a/drivers/staging/batman-adv/main.c +++ b/drivers/staging/batman-adv/main.c @@ -149,27 +149,6 @@ void dec_module_count(void) module_put(THIS_MODULE); } -/* hashfunction to choose an entry in a hash table of given size */ -/* hash algorithm from http://en.wikipedia.org/wiki/Hash_table */ -int choose_orig(void *data, int32_t size) -{ - unsigned char *key = data; - uint32_t hash = 0; - size_t i; - - for (i = 0; i < 6; i++) { - hash += key[i]; - hash += (hash << 10); - hash ^= (hash >> 6); - } - - hash += (hash << 3); - hash ^= (hash >> 11); - hash += (hash << 15); - - return hash % size; -} - int is_my_mac(uint8_t *addr) { struct batman_if *batman_if; diff --git a/drivers/staging/batman-adv/main.h b/drivers/staging/batman-adv/main.h index 97a74b047c57..3ee1eb0a7253 100644 --- a/drivers/staging/batman-adv/main.h +++ b/drivers/staging/batman-adv/main.h @@ -135,7 +135,6 @@ int mesh_init(struct net_device *soft_iface); void mesh_free(struct net_device *soft_iface); void inc_module_count(void); void dec_module_count(void); -int choose_orig(void *data, int32_t size); int is_my_mac(uint8_t *addr); int is_bcast(uint8_t *addr); int is_mcast(uint8_t *addr); diff --git a/drivers/staging/batman-adv/originator.c b/drivers/staging/batman-adv/originator.c index 7735b7fcf157..7c1fae7a2fac 100644 --- a/drivers/staging/batman-adv/originator.c +++ b/drivers/staging/batman-adv/originator.c @@ -45,7 +45,7 @@ int originator_init(struct bat_priv *bat_priv) return 1; spin_lock_irqsave(&bat_priv->orig_hash_lock, flags); - bat_priv->orig_hash = hash_new(128, choose_orig); + bat_priv->orig_hash = hash_new(128); if (!bat_priv->orig_hash) goto err; @@ -128,9 +128,11 @@ struct orig_node *get_orig_node(struct bat_priv *bat_priv, uint8_t *addr) struct orig_node *orig_node; struct hashtable_t *swaphash; int size; + int hash_added; orig_node = ((struct orig_node *)hash_find(bat_priv->orig_hash, - compare_orig, addr)); + compare_orig, choose_orig, + addr)); if (orig_node) return orig_node; @@ -167,11 +169,14 @@ struct orig_node *get_orig_node(struct bat_priv *bat_priv, uint8_t *addr) if (!orig_node->bcast_own_sum) goto free_bcast_own; - if (hash_add(bat_priv->orig_hash, compare_orig, orig_node) < 0) + hash_added = hash_add(bat_priv->orig_hash, compare_orig, choose_orig, + orig_node); + if (hash_added < 0) goto free_bcast_own_sum; if (bat_priv->orig_hash->elements * 4 > bat_priv->orig_hash->size) { swaphash = hash_resize(bat_priv->orig_hash, compare_orig, + choose_orig, bat_priv->orig_hash->size * 2); if (!swaphash) diff --git a/drivers/staging/batman-adv/originator.h b/drivers/staging/batman-adv/originator.h index ed903dcaa35c..d474ceb2a4eb 100644 --- a/drivers/staging/batman-adv/originator.h +++ b/drivers/staging/batman-adv/originator.h @@ -40,4 +40,25 @@ static inline int compare_orig(void *data1, void *data2) return (memcmp(data1, data2, ETH_ALEN) == 0 ? 1 : 0); } +/* hashfunction to choose an entry in a hash table of given size */ +/* hash algorithm from http://en.wikipedia.org/wiki/Hash_table */ +static inline int choose_orig(void *data, int32_t size) +{ + unsigned char *key = data; + uint32_t hash = 0; + size_t i; + + for (i = 0; i < 6; i++) { + hash += key[i]; + hash += (hash << 10); + hash ^= (hash >> 6); + } + + hash += (hash << 3); + hash ^= (hash >> 11); + hash += (hash << 15); + + return hash % size; +} + #endif /* _NET_BATMAN_ADV_ORIGINATOR_H_ */ diff --git a/drivers/staging/batman-adv/routing.c b/drivers/staging/batman-adv/routing.c index bb0bd7871959..9cbb19594e34 100644 --- a/drivers/staging/batman-adv/routing.c +++ b/drivers/staging/batman-adv/routing.c @@ -811,7 +811,7 @@ static int recv_my_icmp_packet(struct bat_priv *bat_priv, /* get routing information */ spin_lock_irqsave(&bat_priv->orig_hash_lock, flags); orig_node = ((struct orig_node *)hash_find(bat_priv->orig_hash, - compare_orig, + compare_orig, choose_orig, icmp_packet->orig)); ret = NET_RX_DROP; @@ -874,7 +874,7 @@ static int recv_icmp_ttl_exceeded(struct bat_priv *bat_priv, /* get routing information */ spin_lock_irqsave(&bat_priv->orig_hash_lock, flags); orig_node = ((struct orig_node *) - hash_find(bat_priv->orig_hash, compare_orig, + hash_find(bat_priv->orig_hash, compare_orig, choose_orig, icmp_packet->orig)); ret = NET_RX_DROP; @@ -969,7 +969,7 @@ int recv_icmp_packet(struct sk_buff *skb, struct batman_if *recv_if) /* get routing information */ spin_lock_irqsave(&bat_priv->orig_hash_lock, flags); orig_node = ((struct orig_node *) - hash_find(bat_priv->orig_hash, compare_orig, + hash_find(bat_priv->orig_hash, compare_orig, choose_orig, icmp_packet->dst)); if ((orig_node != NULL) && @@ -1042,7 +1042,8 @@ struct neigh_node *find_router(struct bat_priv *bat_priv, primary_orig_node = router_orig; } else { primary_orig_node = hash_find(bat_priv->orig_hash, compare_orig, - router_orig->primary_addr); + choose_orig, + router_orig->primary_addr); if (!primary_orig_node) return orig_node->router; @@ -1147,7 +1148,7 @@ int route_unicast_packet(struct sk_buff *skb, struct batman_if *recv_if, /* get routing information */ spin_lock_irqsave(&bat_priv->orig_hash_lock, flags); orig_node = ((struct orig_node *) - hash_find(bat_priv->orig_hash, compare_orig, + hash_find(bat_priv->orig_hash, compare_orig, choose_orig, unicast_packet->dest)); router = find_router(bat_priv, orig_node, recv_if); @@ -1294,7 +1295,7 @@ int recv_bcast_packet(struct sk_buff *skb, struct batman_if *recv_if) spin_lock_irqsave(&bat_priv->orig_hash_lock, flags); orig_node = ((struct orig_node *) - hash_find(bat_priv->orig_hash, compare_orig, + hash_find(bat_priv->orig_hash, compare_orig, choose_orig, bcast_packet->orig)); if (orig_node == NULL) { diff --git a/drivers/staging/batman-adv/translation-table.c b/drivers/staging/batman-adv/translation-table.c index 33cd5daa414c..96d59b100df8 100644 --- a/drivers/staging/batman-adv/translation-table.c +++ b/drivers/staging/batman-adv/translation-table.c @@ -42,7 +42,7 @@ int hna_local_init(struct bat_priv *bat_priv) if (bat_priv->hna_local_hash) return 1; - bat_priv->hna_local_hash = hash_new(128, choose_orig); + bat_priv->hna_local_hash = hash_new(128); if (!bat_priv->hna_local_hash) return 0; @@ -65,7 +65,8 @@ void hna_local_add(struct net_device *soft_iface, uint8_t *addr) spin_lock_irqsave(&bat_priv->hna_lhash_lock, flags); hna_local_entry = ((struct hna_local_entry *)hash_find(bat_priv->hna_local_hash, - compare_orig, addr)); + compare_orig, choose_orig, + addr)); spin_unlock_irqrestore(&bat_priv->hna_lhash_lock, flags); if (hna_local_entry) { @@ -108,13 +109,15 @@ void hna_local_add(struct net_device *soft_iface, uint8_t *addr) spin_lock_irqsave(&bat_priv->hna_lhash_lock, flags); - hash_add(bat_priv->hna_local_hash, compare_orig, hna_local_entry); + hash_add(bat_priv->hna_local_hash, compare_orig, choose_orig, + hna_local_entry); bat_priv->num_local_hna++; atomic_set(&bat_priv->hna_local_changed, 1); if (bat_priv->hna_local_hash->elements * 4 > bat_priv->hna_local_hash->size) { swaphash = hash_resize(bat_priv->hna_local_hash, compare_orig, + choose_orig, bat_priv->hna_local_hash->size * 2); if (!swaphash) @@ -130,7 +133,7 @@ void hna_local_add(struct net_device *soft_iface, uint8_t *addr) hna_global_entry = ((struct hna_global_entry *) hash_find(bat_priv->hna_global_hash, - compare_orig, addr)); + compare_orig, choose_orig, addr)); if (hna_global_entry) _hna_global_del_orig(bat_priv, hna_global_entry, @@ -234,7 +237,7 @@ static void hna_local_del(struct bat_priv *bat_priv, bat_dbg(DBG_ROUTES, bat_priv, "Deleting local hna entry (%pM): %s\n", hna_local_entry->addr, message); - hash_remove(bat_priv->hna_local_hash, compare_orig, + hash_remove(bat_priv->hna_local_hash, compare_orig, choose_orig, hna_local_entry->addr); _hna_local_del(hna_local_entry, bat_priv); } @@ -248,7 +251,8 @@ void hna_local_remove(struct bat_priv *bat_priv, spin_lock_irqsave(&bat_priv->hna_lhash_lock, flags); hna_local_entry = (struct hna_local_entry *) - hash_find(bat_priv->hna_local_hash, compare_orig, addr); + hash_find(bat_priv->hna_local_hash, compare_orig, choose_orig, + addr); if (hna_local_entry) hna_local_del(bat_priv, hna_local_entry, message); @@ -298,7 +302,7 @@ int hna_global_init(struct bat_priv *bat_priv) if (bat_priv->hna_global_hash) return 1; - bat_priv->hna_global_hash = hash_new(128, choose_orig); + bat_priv->hna_global_hash = hash_new(128); if (!bat_priv->hna_global_hash) return 0; @@ -323,7 +327,7 @@ void hna_global_add_orig(struct bat_priv *bat_priv, hna_ptr = hna_buff + (hna_buff_count * ETH_ALEN); hna_global_entry = (struct hna_global_entry *) hash_find(bat_priv->hna_global_hash, compare_orig, - hna_ptr); + choose_orig, hna_ptr); if (!hna_global_entry) { spin_unlock_irqrestore(&bat_priv->hna_ghash_lock, @@ -345,7 +349,7 @@ void hna_global_add_orig(struct bat_priv *bat_priv, spin_lock_irqsave(&bat_priv->hna_ghash_lock, flags); hash_add(bat_priv->hna_global_hash, compare_orig, - hna_global_entry); + choose_orig, hna_global_entry); } @@ -358,7 +362,7 @@ void hna_global_add_orig(struct bat_priv *bat_priv, hna_ptr = hna_buff + (hna_buff_count * ETH_ALEN); hna_local_entry = (struct hna_local_entry *) hash_find(bat_priv->hna_local_hash, compare_orig, - hna_ptr); + choose_orig, hna_ptr); if (hna_local_entry) hna_local_del(bat_priv, hna_local_entry, @@ -386,6 +390,7 @@ void hna_global_add_orig(struct bat_priv *bat_priv, if (bat_priv->hna_global_hash->elements * 4 > bat_priv->hna_global_hash->size) { swaphash = hash_resize(bat_priv->hna_global_hash, compare_orig, + choose_orig, bat_priv->hna_global_hash->size * 2); if (!swaphash) @@ -456,7 +461,7 @@ static void _hna_global_del_orig(struct bat_priv *bat_priv, hna_global_entry->addr, hna_global_entry->orig_node->orig, message); - hash_remove(bat_priv->hna_global_hash, compare_orig, + hash_remove(bat_priv->hna_global_hash, compare_orig, choose_orig, hna_global_entry->addr); kfree(hna_global_entry); } @@ -478,7 +483,7 @@ void hna_global_del_orig(struct bat_priv *bat_priv, hna_ptr = orig_node->hna_buff + (hna_buff_count * ETH_ALEN); hna_global_entry = (struct hna_global_entry *) hash_find(bat_priv->hna_global_hash, compare_orig, - hna_ptr); + choose_orig, hna_ptr); if ((hna_global_entry) && (hna_global_entry->orig_node == orig_node)) @@ -517,7 +522,7 @@ struct orig_node *transtable_search(struct bat_priv *bat_priv, uint8_t *addr) spin_lock_irqsave(&bat_priv->hna_ghash_lock, flags); hna_global_entry = (struct hna_global_entry *) hash_find(bat_priv->hna_global_hash, - compare_orig, addr); + compare_orig, choose_orig, addr); spin_unlock_irqrestore(&bat_priv->hna_ghash_lock, flags); if (!hna_global_entry) diff --git a/drivers/staging/batman-adv/unicast.c b/drivers/staging/batman-adv/unicast.c index 1f4d911d9e5a..132875047835 100644 --- a/drivers/staging/batman-adv/unicast.c +++ b/drivers/staging/batman-adv/unicast.c @@ -180,7 +180,7 @@ int frag_reassemble_skb(struct sk_buff *skb, struct bat_priv *bat_priv, *new_skb = NULL; spin_lock_irqsave(&bat_priv->orig_hash_lock, flags); orig_node = ((struct orig_node *) - hash_find(bat_priv->orig_hash, compare_orig, + hash_find(bat_priv->orig_hash, compare_orig, choose_orig, unicast_packet->orig)); if (!orig_node) { @@ -286,6 +286,7 @@ int unicast_send_skb(struct sk_buff *skb, struct bat_priv *bat_priv) /* get routing information */ orig_node = ((struct orig_node *)hash_find(bat_priv->orig_hash, compare_orig, + choose_orig, ethhdr->h_dest)); /* check for hna host */ diff --git a/drivers/staging/batman-adv/vis.c b/drivers/staging/batman-adv/vis.c index ff0abe9f5607..dccd296c6ff3 100644 --- a/drivers/staging/batman-adv/vis.c +++ b/drivers/staging/batman-adv/vis.c @@ -350,6 +350,7 @@ static struct vis_info *add_packet(struct bat_priv *bat_priv, struct vis_packet *search_packet, *old_packet; struct vis_info search_elem; struct vis_packet *packet; + int hash_added; *is_new = 0; /* sanity check */ @@ -364,7 +365,8 @@ static struct vis_info *add_packet(struct bat_priv *bat_priv, sizeof(struct vis_packet)); memcpy(search_packet->vis_orig, vis_packet->vis_orig, ETH_ALEN); - old_info = hash_find(bat_priv->vis_hash, vis_info_cmp, &search_elem); + old_info = hash_find(bat_priv->vis_hash, vis_info_cmp, vis_info_choose, + &search_elem); kfree_skb(search_elem.skb_packet); if (old_info != NULL) { @@ -381,7 +383,8 @@ static struct vis_info *add_packet(struct bat_priv *bat_priv, } } /* remove old entry */ - hash_remove(bat_priv->vis_hash, vis_info_cmp, old_info); + hash_remove(bat_priv->vis_hash, vis_info_cmp, vis_info_choose, + old_info); send_list_del(old_info); kref_put(&old_info->refcount, free_info); } @@ -422,7 +425,9 @@ static struct vis_info *add_packet(struct bat_priv *bat_priv, recv_list_add(bat_priv, &info->recv_list, packet->sender_orig); /* try to add it */ - if (hash_add(bat_priv->vis_hash, vis_info_cmp, info) < 0) { + hash_added = hash_add(bat_priv->vis_hash, vis_info_cmp, vis_info_choose, + info); + if (hash_added < 0) { /* did not work (for some reason) */ kref_put(&old_info->refcount, free_info); info = NULL; @@ -711,7 +716,7 @@ static void unicast_vis_packet(struct bat_priv *bat_priv, spin_lock_irqsave(&bat_priv->orig_hash_lock, flags); packet = (struct vis_packet *)info->skb_packet->data; orig_node = ((struct orig_node *)hash_find(bat_priv->orig_hash, - compare_orig, + compare_orig, choose_orig, packet->target_orig)); if ((!orig_node) || (!orig_node->router)) @@ -803,7 +808,7 @@ int vis_init(struct bat_priv *bat_priv) spin_lock_irqsave(&bat_priv->vis_hash_lock, flags); - bat_priv->vis_hash = hash_new(256, vis_info_choose); + bat_priv->vis_hash = hash_new(256); if (!bat_priv->vis_hash) { pr_err("Can't initialize vis_hash\n"); goto err; @@ -842,7 +847,7 @@ int vis_init(struct bat_priv *bat_priv) INIT_LIST_HEAD(&bat_priv->vis_send_list); - hash_added = hash_add(bat_priv->vis_hash, vis_info_cmp, + hash_added = hash_add(bat_priv->vis_hash, vis_info_cmp, vis_info_choose, bat_priv->my_vis_info); if (hash_added < 0) { pr_err("Can't add own vis packet into hash\n"); -- cgit v1.2.3 From 60eb502436910fb8118639e2ce4d7a4f732b6754 Mon Sep 17 00:00:00 2001 From: Sven Eckelmann Date: Mon, 22 Nov 2010 00:55:58 +0100 Subject: Staging: batman-adv: Move hash callback related function to header To enable inlining of the function pointers hashdata_choose_cb, hashdata_choose_cb and hashdata_free_cb, also the hash functions which uses them must be inlined by the called function. This should increase the performance, but also increases the size of the generated machine code slightly. Reported-by: David S. Miller Signed-off-by: Sven Eckelmann Signed-off-by: Greg Kroah-Hartman --- drivers/staging/batman-adv/hash.c | 150 ------------------------------------- drivers/staging/batman-adv/hash.h | 152 +++++++++++++++++++++++++++++++++++--- 2 files changed, 140 insertions(+), 162 deletions(-) diff --git a/drivers/staging/batman-adv/hash.c b/drivers/staging/batman-adv/hash.c index 6361a3175520..7d0498754afd 100644 --- a/drivers/staging/batman-adv/hash.c +++ b/drivers/staging/batman-adv/hash.c @@ -33,30 +33,6 @@ static void hash_init(struct hashtable_t *hash) hash->table[i] = NULL; } -/* remove the hash structure. if hashdata_free_cb != NULL, this function will be - * called to remove the elements inside of the hash. if you don't remove the - * elements, memory might be leaked. */ -void hash_delete(struct hashtable_t *hash, hashdata_free_cb free_cb, void *arg) -{ - struct element_t *bucket, *last_bucket; - int i; - - for (i = 0; i < hash->size; i++) { - bucket = hash->table[i]; - - while (bucket != NULL) { - if (free_cb != NULL) - free_cb(bucket->data, arg); - - last_bucket = bucket; - bucket = bucket->next; - kfree(last_bucket); - } - } - - hash_destroy(hash); -} - /* free only the hashtable and the hash itself. */ void hash_destroy(struct hashtable_t *hash) { @@ -159,70 +135,6 @@ struct hashtable_t *hash_new(int size) return hash; } -/* adds data to the hashtable. returns 0 on success, -1 on error */ -int hash_add(struct hashtable_t *hash, hashdata_compare_cb compare, - hashdata_choose_cb choose, void *data) -{ - int index; - struct element_t *bucket, *prev_bucket = NULL; - - if (!hash) - return -1; - - index = choose(data, hash->size); - bucket = hash->table[index]; - - while (bucket != NULL) { - if (compare(bucket->data, data)) - return -1; - - prev_bucket = bucket; - bucket = bucket->next; - } - - /* found the tail of the list, add new element */ - bucket = kmalloc(sizeof(struct element_t), GFP_ATOMIC); - - if (bucket == NULL) - return -1; - - bucket->data = data; - bucket->next = NULL; - - /* and link it */ - if (prev_bucket == NULL) - hash->table[index] = bucket; - else - prev_bucket->next = bucket; - - hash->elements++; - return 0; -} - -/* finds data, based on the key in keydata. returns the found data on success, - * or NULL on error */ -void *hash_find(struct hashtable_t *hash, hashdata_compare_cb compare, - hashdata_choose_cb choose, void *keydata) -{ - int index; - struct element_t *bucket; - - if (!hash) - return NULL; - - index = choose(keydata , hash->size); - bucket = hash->table[index]; - - while (bucket != NULL) { - if (compare(bucket->data, keydata)) - return bucket->data; - - bucket = bucket->next; - } - - return NULL; -} - /* remove bucket (this might be used in hash_iterate() if you already found the * bucket you want to delete and don't need the overhead to find it again with * hash_remove(). But usually, you don't want to use this function, as it @@ -243,65 +155,3 @@ void *hash_remove_bucket(struct hashtable_t *hash, struct hash_it_t *hash_it_t) return data_save; } - -/* removes data from hash, if found. returns pointer do data on success, so you - * can remove the used structure yourself, or NULL on error . data could be the - * structure you use with just the key filled, we just need the key for - * comparing. */ -void *hash_remove(struct hashtable_t *hash, hashdata_compare_cb compare, - hashdata_choose_cb choose, void *data) -{ - struct hash_it_t hash_it_t; - - hash_it_t.index = choose(data, hash->size); - hash_it_t.bucket = hash->table[hash_it_t.index]; - hash_it_t.prev_bucket = NULL; - - while (hash_it_t.bucket != NULL) { - if (compare(hash_it_t.bucket->data, data)) { - hash_it_t.first_bucket = - (hash_it_t.bucket == - hash->table[hash_it_t.index] ? - &hash->table[hash_it_t.index] : NULL); - return hash_remove_bucket(hash, &hash_it_t); - } - - hash_it_t.prev_bucket = hash_it_t.bucket; - hash_it_t.bucket = hash_it_t.bucket->next; - } - - return NULL; -} - -/* resize the hash, returns the pointer to the new hash or NULL on - * error. removes the old hash on success. */ -struct hashtable_t *hash_resize(struct hashtable_t *hash, - hashdata_compare_cb compare, - hashdata_choose_cb choose, int size) -{ - struct hashtable_t *new_hash; - struct element_t *bucket; - int i; - - /* initialize a new hash with the new size */ - new_hash = hash_new(size); - - if (new_hash == NULL) - return NULL; - - /* copy the elements */ - for (i = 0; i < hash->size; i++) { - bucket = hash->table[i]; - - while (bucket != NULL) { - hash_add(new_hash, compare, choose, bucket->data); - bucket = bucket->next; - } - } - - /* remove hash and eventual overflow buckets but not the content - * itself. */ - hash_delete(hash, NULL, NULL); - - return new_hash; -} diff --git a/drivers/staging/batman-adv/hash.h b/drivers/staging/batman-adv/hash.h index 85ee12b0779a..efc4c28f7c15 100644 --- a/drivers/staging/batman-adv/hash.h +++ b/drivers/staging/batman-adv/hash.h @@ -66,35 +66,163 @@ struct hashtable_t *hash_new(int size); * fiddles with hash-internals. */ void *hash_remove_bucket(struct hashtable_t *hash, struct hash_it_t *hash_it_t); +/* free only the hashtable and the hash itself. */ +void hash_destroy(struct hashtable_t *hash); + /* remove the hash structure. if hashdata_free_cb != NULL, this function will be * called to remove the elements inside of the hash. if you don't remove the * elements, memory might be leaked. */ -void hash_delete(struct hashtable_t *hash, hashdata_free_cb free_cb, void *arg); +static inline void hash_delete(struct hashtable_t *hash, + hashdata_free_cb free_cb, void *arg) +{ + struct element_t *bucket, *last_bucket; + int i; -/* free only the hashtable and the hash itself. */ -void hash_destroy(struct hashtable_t *hash); + for (i = 0; i < hash->size; i++) { + bucket = hash->table[i]; + + while (bucket != NULL) { + if (free_cb != NULL) + free_cb(bucket->data, arg); + + last_bucket = bucket; + bucket = bucket->next; + kfree(last_bucket); + } + } + + hash_destroy(hash); +} /* adds data to the hashtable. returns 0 on success, -1 on error */ -int hash_add(struct hashtable_t *hash, hashdata_compare_cb compare, - hashdata_choose_cb choose, void *data); +static inline int hash_add(struct hashtable_t *hash, + hashdata_compare_cb compare, + hashdata_choose_cb choose, void *data) +{ + int index; + struct element_t *bucket, *prev_bucket = NULL; + + if (!hash) + return -1; + + index = choose(data, hash->size); + bucket = hash->table[index]; + + while (bucket != NULL) { + if (compare(bucket->data, data)) + return -1; + + prev_bucket = bucket; + bucket = bucket->next; + } + + /* found the tail of the list, add new element */ + bucket = kmalloc(sizeof(struct element_t), GFP_ATOMIC); + + if (bucket == NULL) + return -1; + + bucket->data = data; + bucket->next = NULL; + + /* and link it */ + if (prev_bucket == NULL) + hash->table[index] = bucket; + else + prev_bucket->next = bucket; + + hash->elements++; + return 0; +} /* removes data from hash, if found. returns pointer do data on success, so you * can remove the used structure yourself, or NULL on error . data could be the * structure you use with just the key filled, we just need the key for * comparing. */ -void *hash_remove(struct hashtable_t *hash, hashdata_compare_cb compare, - hashdata_choose_cb choose, void *data); +static inline void *hash_remove(struct hashtable_t *hash, + hashdata_compare_cb compare, + hashdata_choose_cb choose, void *data) +{ + struct hash_it_t hash_it_t; + + hash_it_t.index = choose(data, hash->size); + hash_it_t.bucket = hash->table[hash_it_t.index]; + hash_it_t.prev_bucket = NULL; + + while (hash_it_t.bucket != NULL) { + if (compare(hash_it_t.bucket->data, data)) { + hash_it_t.first_bucket = + (hash_it_t.bucket == + hash->table[hash_it_t.index] ? + &hash->table[hash_it_t.index] : NULL); + return hash_remove_bucket(hash, &hash_it_t); + } + + hash_it_t.prev_bucket = hash_it_t.bucket; + hash_it_t.bucket = hash_it_t.bucket->next; + } + + return NULL; +} /* finds data, based on the key in keydata. returns the found data on success, * or NULL on error */ -void *hash_find(struct hashtable_t *hash, hashdata_compare_cb compare, - hashdata_choose_cb choose, void *keydata); +static inline void *hash_find(struct hashtable_t *hash, + hashdata_compare_cb compare, + hashdata_choose_cb choose, void *keydata) +{ + int index; + struct element_t *bucket; + + if (!hash) + return NULL; + + index = choose(keydata , hash->size); + bucket = hash->table[index]; + + while (bucket != NULL) { + if (compare(bucket->data, keydata)) + return bucket->data; + + bucket = bucket->next; + } + + return NULL; +} /* resize the hash, returns the pointer to the new hash or NULL on * error. removes the old hash on success */ -struct hashtable_t *hash_resize(struct hashtable_t *hash, - hashdata_compare_cb compare, - hashdata_choose_cb choose, int size); +static inline struct hashtable_t *hash_resize(struct hashtable_t *hash, + hashdata_compare_cb compare, + hashdata_choose_cb choose, + int size) +{ + struct hashtable_t *new_hash; + struct element_t *bucket; + int i; + + /* initialize a new hash with the new size */ + new_hash = hash_new(size); + + if (new_hash == NULL) + return NULL; + + /* copy the elements */ + for (i = 0; i < hash->size; i++) { + bucket = hash->table[i]; + + while (bucket != NULL) { + hash_add(new_hash, compare, choose, bucket->data); + bucket = bucket->next; + } + } + + /* remove hash and eventual overflow buckets but not the content + * itself. */ + hash_delete(hash, NULL, NULL); + + return new_hash; +} /* iterate though the hash. first element is selected with iter_in NULL. use * the returned iterator to access the elements until hash_it_t returns NULL. */ -- cgit v1.2.3 From a3238c3b379146a2d480dfee4c7f76c4692d7466 Mon Sep 17 00:00:00 2001 From: Sven Eckelmann Date: Mon, 22 Nov 2010 00:55:59 +0100 Subject: Staging: batman-adv: Make hash_iterate inlineable hash_iterate is next to the function pointers the most called function related to hashes which benefits from inlining as it is uses in loops. Reported-by: David S. Miller Signed-off-by: Sven Eckelmann Signed-off-by: Greg Kroah-Hartman --- drivers/staging/batman-adv/TODO | 1 - drivers/staging/batman-adv/hash.c | 72 ------------------------------------- drivers/staging/batman-adv/hash.h | 74 ++++++++++++++++++++++++++++++++++++--- 3 files changed, 70 insertions(+), 77 deletions(-) diff --git a/drivers/staging/batman-adv/TODO b/drivers/staging/batman-adv/TODO index 2c02aa107de8..91b5e9cd48d5 100644 --- a/drivers/staging/batman-adv/TODO +++ b/drivers/staging/batman-adv/TODO @@ -1,6 +1,5 @@ * remove own list functionality from hash * use hlist_head, hlist_node in hash - * think about more efficient ways instead of abstraction of hash * Request a new review * Process the comments from the review * Move into mainline proper diff --git a/drivers/staging/batman-adv/hash.c b/drivers/staging/batman-adv/hash.c index 7d0498754afd..bfe943cac1ab 100644 --- a/drivers/staging/batman-adv/hash.c +++ b/drivers/staging/batman-adv/hash.c @@ -40,78 +40,6 @@ void hash_destroy(struct hashtable_t *hash) kfree(hash); } -/* iterate though the hash. First element is selected if an iterator - * initialized with HASHIT() is supplied as iter. Use the returned - * (or supplied) iterator to access the elements until hash_iterate returns - * NULL. */ - -struct hash_it_t *hash_iterate(struct hashtable_t *hash, - struct hash_it_t *iter) -{ - if (!hash) - return NULL; - if (!iter) - return NULL; - - /* sanity checks first (if our bucket got deleted in the last - * iteration): */ - if (iter->bucket != NULL) { - if (iter->first_bucket != NULL) { - /* we're on the first element and it got removed after - * the last iteration. */ - if ((*iter->first_bucket) != iter->bucket) { - /* there are still other elements in the list */ - if ((*iter->first_bucket) != NULL) { - iter->prev_bucket = NULL; - iter->bucket = (*iter->first_bucket); - iter->first_bucket = - &hash->table[iter->index]; - return iter; - } else { - iter->bucket = NULL; - } - } - } else if (iter->prev_bucket != NULL) { - /* - * we're not on the first element, and the bucket got - * removed after the last iteration. the last bucket's - * next pointer is not pointing to our actual bucket - * anymore. select the next. - */ - if (iter->prev_bucket->next != iter->bucket) - iter->bucket = iter->prev_bucket; - } - } - - /* now as we are sane, select the next one if there is some */ - if (iter->bucket != NULL) { - if (iter->bucket->next != NULL) { - iter->prev_bucket = iter->bucket; - iter->bucket = iter->bucket->next; - iter->first_bucket = NULL; - return iter; - } - } - - /* if not returned yet, we've reached the last one on the index and have - * to search forward */ - iter->index++; - /* go through the entries of the hash table */ - while (iter->index < hash->size) { - if ((hash->table[iter->index]) != NULL) { - iter->prev_bucket = NULL; - iter->bucket = hash->table[iter->index]; - iter->first_bucket = &hash->table[iter->index]; - return iter; - } else { - iter->index++; - } - } - - /* nothing to iterate over anymore */ - return NULL; -} - /* allocates and clears the hash */ struct hashtable_t *hash_new(int size) { diff --git a/drivers/staging/batman-adv/hash.h b/drivers/staging/batman-adv/hash.h index efc4c28f7c15..a8e4dd1ec6a0 100644 --- a/drivers/staging/batman-adv/hash.h +++ b/drivers/staging/batman-adv/hash.h @@ -224,9 +224,75 @@ static inline struct hashtable_t *hash_resize(struct hashtable_t *hash, return new_hash; } -/* iterate though the hash. first element is selected with iter_in NULL. use - * the returned iterator to access the elements until hash_it_t returns NULL. */ -struct hash_it_t *hash_iterate(struct hashtable_t *hash, - struct hash_it_t *iter_in); +/* iterate though the hash. First element is selected if an iterator + * initialized with HASHIT() is supplied as iter. Use the returned + * (or supplied) iterator to access the elements until hash_iterate returns + * NULL. */ +static inline struct hash_it_t *hash_iterate(struct hashtable_t *hash, + struct hash_it_t *iter) +{ + if (!hash) + return NULL; + if (!iter) + return NULL; + + /* sanity checks first (if our bucket got deleted in the last + * iteration): */ + if (iter->bucket != NULL) { + if (iter->first_bucket != NULL) { + /* we're on the first element and it got removed after + * the last iteration. */ + if ((*iter->first_bucket) != iter->bucket) { + /* there are still other elements in the list */ + if ((*iter->first_bucket) != NULL) { + iter->prev_bucket = NULL; + iter->bucket = (*iter->first_bucket); + iter->first_bucket = + &hash->table[iter->index]; + return iter; + } else { + iter->bucket = NULL; + } + } + } else if (iter->prev_bucket != NULL) { + /* + * we're not on the first element, and the bucket got + * removed after the last iteration. the last bucket's + * next pointer is not pointing to our actual bucket + * anymore. select the next. + */ + if (iter->prev_bucket->next != iter->bucket) + iter->bucket = iter->prev_bucket; + } + } + + /* now as we are sane, select the next one if there is some */ + if (iter->bucket != NULL) { + if (iter->bucket->next != NULL) { + iter->prev_bucket = iter->bucket; + iter->bucket = iter->bucket->next; + iter->first_bucket = NULL; + return iter; + } + } + + /* if not returned yet, we've reached the last one on the index and have + * to search forward */ + iter->index++; + /* go through the entries of the hash table */ + while (iter->index < hash->size) { + if ((hash->table[iter->index]) != NULL) { + iter->prev_bucket = NULL; + iter->bucket = hash->table[iter->index]; + iter->first_bucket = &hash->table[iter->index]; + return iter; + } else { + iter->index++; + } + } + + /* nothing to iterate over anymore */ + return NULL; +} #endif /* _NET_BATMAN_ADV_HASH_H_ */ -- cgit v1.2.3 From bd204952cf161404eae0aa6478fb1b4c586ac678 Mon Sep 17 00:00:00 2001 From: Sven Eckelmann Date: Mon, 22 Nov 2010 00:56:00 +0100 Subject: Staging: batman-adv: Rewrite hash using hlist_* The hash implementation is a complete implementation of a hash using buckets as hash entries and overflow buckets attached to them. The kernel already provides datastructures hlist_head and hlist_node which can be used to implement an hash using lists as hash buckets. So it is better to implement heavily used functionality on top of those instead of providing a full hash implementation. The rewrite changes the behavior of some functions slightly: * hash_add add elements to the front instead of the tail * hash_iterate doesn't provide pointer to access bucket->data directly, but it can be accessed using hlist_entry Reported-by: David S. Miller Signed-off-by: Sven Eckelmann Signed-off-by: Greg Kroah-Hartman --- drivers/staging/batman-adv/TODO | 2 - drivers/staging/batman-adv/hash.c | 14 +- drivers/staging/batman-adv/hash.h | 175 ++++++++++--------------- drivers/staging/batman-adv/originator.c | 20 ++- drivers/staging/batman-adv/routing.c | 4 +- drivers/staging/batman-adv/translation-table.c | 22 ++-- drivers/staging/batman-adv/vis.c | 29 +++- 7 files changed, 126 insertions(+), 140 deletions(-) diff --git a/drivers/staging/batman-adv/TODO b/drivers/staging/batman-adv/TODO index 91b5e9cd48d5..ba69ba3ab62d 100644 --- a/drivers/staging/batman-adv/TODO +++ b/drivers/staging/batman-adv/TODO @@ -1,5 +1,3 @@ - * remove own list functionality from hash - * use hlist_head, hlist_node in hash * Request a new review * Process the comments from the review * Move into mainline proper diff --git a/drivers/staging/batman-adv/hash.c b/drivers/staging/batman-adv/hash.c index bfe943cac1ab..8605e2fd0427 100644 --- a/drivers/staging/batman-adv/hash.c +++ b/drivers/staging/batman-adv/hash.c @@ -30,7 +30,7 @@ static void hash_init(struct hashtable_t *hash) hash->elements = 0; for (i = 0 ; i < hash->size; i++) - hash->table[i] = NULL; + INIT_HLIST_HEAD(&hash->table[i]); } /* free only the hashtable and the hash itself. */ @@ -70,15 +70,13 @@ struct hashtable_t *hash_new(int size) void *hash_remove_bucket(struct hashtable_t *hash, struct hash_it_t *hash_it_t) { void *data_save; + struct element_t *bucket; - data_save = hash_it_t->bucket->data; + bucket = hlist_entry(hash_it_t->walk, struct element_t, hlist); + data_save = bucket->data; - if (hash_it_t->prev_bucket != NULL) - hash_it_t->prev_bucket->next = hash_it_t->bucket->next; - else if (hash_it_t->first_bucket != NULL) - (*hash_it_t->first_bucket) = hash_it_t->bucket->next; - - kfree(hash_it_t->bucket); + hlist_del(hash_it_t->walk); + kfree(bucket); hash->elements--; return data_save; diff --git a/drivers/staging/batman-adv/hash.h b/drivers/staging/batman-adv/hash.h index a8e4dd1ec6a0..0b61c6e3e7cf 100644 --- a/drivers/staging/batman-adv/hash.h +++ b/drivers/staging/batman-adv/hash.h @@ -22,10 +22,11 @@ #ifndef _NET_BATMAN_ADV_HASH_H_ #define _NET_BATMAN_ADV_HASH_H_ +#include + #define HASHIT(name) struct hash_it_t name = { \ - .index = -1, .bucket = NULL, \ - .prev_bucket = NULL, \ - .first_bucket = NULL } + .index = 0, .walk = NULL, \ + .safe = NULL} /* callback to a compare function. should * compare 2 element datas for their keys, @@ -41,18 +42,17 @@ typedef void (*hashdata_free_cb)(void *, void *); struct element_t { void *data; /* pointer to the data */ - struct element_t *next; /* overflow bucket pointer */ + struct hlist_node hlist; /* bucket list pointer */ }; struct hash_it_t { - int index; - struct element_t *bucket; - struct element_t *prev_bucket; - struct element_t **first_bucket; + size_t index; + struct hlist_node *walk; + struct hlist_node *safe; }; struct hashtable_t { - struct element_t **table; /* the hashtable itself, with the buckets */ + struct hlist_head *table; /* the hashtable itself, with the buckets */ int elements; /* number of elements registered */ int size; /* size of hashtable */ }; @@ -75,19 +75,21 @@ void hash_destroy(struct hashtable_t *hash); static inline void hash_delete(struct hashtable_t *hash, hashdata_free_cb free_cb, void *arg) { - struct element_t *bucket, *last_bucket; + struct hlist_head *head; + struct hlist_node *walk, *safe; + struct element_t *bucket; int i; for (i = 0; i < hash->size; i++) { - bucket = hash->table[i]; + head = &hash->table[i]; - while (bucket != NULL) { + hlist_for_each_safe(walk, safe, head) { + bucket = hlist_entry(walk, struct element_t, hlist); if (free_cb != NULL) free_cb(bucket->data, arg); - last_bucket = bucket; - bucket = bucket->next; - kfree(last_bucket); + hlist_del(walk); + kfree(bucket); } } @@ -100,36 +102,30 @@ static inline int hash_add(struct hashtable_t *hash, hashdata_choose_cb choose, void *data) { int index; - struct element_t *bucket, *prev_bucket = NULL; + struct hlist_head *head; + struct hlist_node *walk, *safe; + struct element_t *bucket; if (!hash) return -1; index = choose(data, hash->size); - bucket = hash->table[index]; + head = &hash->table[index]; - while (bucket != NULL) { + hlist_for_each_safe(walk, safe, head) { + bucket = hlist_entry(walk, struct element_t, hlist); if (compare(bucket->data, data)) return -1; - - prev_bucket = bucket; - bucket = bucket->next; } - /* found the tail of the list, add new element */ + /* no duplicate found in list, add new element */ bucket = kmalloc(sizeof(struct element_t), GFP_ATOMIC); if (bucket == NULL) return -1; bucket->data = data; - bucket->next = NULL; - - /* and link it */ - if (prev_bucket == NULL) - hash->table[index] = bucket; - else - prev_bucket->next = bucket; + hlist_add_head(&bucket->hlist, head); hash->elements++; return 0; @@ -144,22 +140,16 @@ static inline void *hash_remove(struct hashtable_t *hash, hashdata_choose_cb choose, void *data) { struct hash_it_t hash_it_t; + struct element_t *bucket; + struct hlist_head *head; hash_it_t.index = choose(data, hash->size); - hash_it_t.bucket = hash->table[hash_it_t.index]; - hash_it_t.prev_bucket = NULL; - - while (hash_it_t.bucket != NULL) { - if (compare(hash_it_t.bucket->data, data)) { - hash_it_t.first_bucket = - (hash_it_t.bucket == - hash->table[hash_it_t.index] ? - &hash->table[hash_it_t.index] : NULL); - return hash_remove_bucket(hash, &hash_it_t); - } + head = &hash->table[hash_it_t.index]; - hash_it_t.prev_bucket = hash_it_t.bucket; - hash_it_t.bucket = hash_it_t.bucket->next; + hlist_for_each(hash_it_t.walk, head) { + bucket = hlist_entry(hash_it_t.walk, struct element_t, hlist); + if (compare(bucket->data, data)) + return hash_remove_bucket(hash, &hash_it_t); } return NULL; @@ -172,19 +162,20 @@ static inline void *hash_find(struct hashtable_t *hash, hashdata_choose_cb choose, void *keydata) { int index; + struct hlist_head *head; + struct hlist_node *walk; struct element_t *bucket; if (!hash) return NULL; index = choose(keydata , hash->size); - bucket = hash->table[index]; + head = &hash->table[index]; - while (bucket != NULL) { + hlist_for_each(walk, head) { + bucket = hlist_entry(walk, struct element_t, hlist); if (compare(bucket->data, keydata)) return bucket->data; - - bucket = bucket->next; } return NULL; @@ -193,13 +184,14 @@ static inline void *hash_find(struct hashtable_t *hash, /* resize the hash, returns the pointer to the new hash or NULL on * error. removes the old hash on success */ static inline struct hashtable_t *hash_resize(struct hashtable_t *hash, - hashdata_compare_cb compare, hashdata_choose_cb choose, int size) { struct hashtable_t *new_hash; + struct hlist_head *head, *new_head; + struct hlist_node *walk, *safe; struct element_t *bucket; - int i; + int i, new_index; /* initialize a new hash with the new size */ new_hash = hash_new(size); @@ -209,17 +201,20 @@ static inline struct hashtable_t *hash_resize(struct hashtable_t *hash, /* copy the elements */ for (i = 0; i < hash->size; i++) { - bucket = hash->table[i]; + head = &hash->table[i]; + + hlist_for_each_safe(walk, safe, head) { + bucket = hlist_entry(walk, struct element_t, hlist); - while (bucket != NULL) { - hash_add(new_hash, compare, choose, bucket->data); - bucket = bucket->next; + new_index = choose(bucket->data, size); + new_head = &new_hash->table[new_index]; + + hlist_del(walk); + hlist_add_head(walk, new_head); } } - /* remove hash and eventual overflow buckets but not the content - * itself. */ - hash_delete(hash, NULL, NULL); + hash_destroy(hash); return new_hash; } @@ -236,63 +231,29 @@ static inline struct hash_it_t *hash_iterate(struct hashtable_t *hash, if (!iter) return NULL; - /* sanity checks first (if our bucket got deleted in the last - * iteration): */ - if (iter->bucket != NULL) { - if (iter->first_bucket != NULL) { - /* we're on the first element and it got removed after - * the last iteration. */ - if ((*iter->first_bucket) != iter->bucket) { - /* there are still other elements in the list */ - if ((*iter->first_bucket) != NULL) { - iter->prev_bucket = NULL; - iter->bucket = (*iter->first_bucket); - iter->first_bucket = - &hash->table[iter->index]; - return iter; - } else { - iter->bucket = NULL; - } - } - } else if (iter->prev_bucket != NULL) { - /* - * we're not on the first element, and the bucket got - * removed after the last iteration. the last bucket's - * next pointer is not pointing to our actual bucket - * anymore. select the next. - */ - if (iter->prev_bucket->next != iter->bucket) - iter->bucket = iter->prev_bucket; - } - } + iter->walk = iter->safe; - /* now as we are sane, select the next one if there is some */ - if (iter->bucket != NULL) { - if (iter->bucket->next != NULL) { - iter->prev_bucket = iter->bucket; - iter->bucket = iter->bucket->next; - iter->first_bucket = NULL; - return iter; - } - } + /* we search for the next head with list entries */ + if (!iter->walk) { + while (iter->index < hash->size) { + if (hlist_empty(&hash->table[iter->index])) + iter->index++; + else { + iter->walk = hash->table[iter->index].first; - /* if not returned yet, we've reached the last one on the index and have - * to search forward */ - iter->index++; - /* go through the entries of the hash table */ - while (iter->index < hash->size) { - if ((hash->table[iter->index]) != NULL) { - iter->prev_bucket = NULL; - iter->bucket = hash->table[iter->index]; - iter->first_bucket = &hash->table[iter->index]; - return iter; - } else { - iter->index++; + /* search next time */ + ++iter->index; + break; + } } } - /* nothing to iterate over anymore */ - return NULL; + /* return iter when we found bucket otherwise null */ + if (!iter->walk) + return NULL; + + iter->safe = iter->walk->next; + return iter; } #endif /* _NET_BATMAN_ADV_HASH_H_ */ diff --git a/drivers/staging/batman-adv/originator.c b/drivers/staging/batman-adv/originator.c index 7c1fae7a2fac..a4b7d377d941 100644 --- a/drivers/staging/batman-adv/originator.c +++ b/drivers/staging/batman-adv/originator.c @@ -175,8 +175,7 @@ struct orig_node *get_orig_node(struct bat_priv *bat_priv, uint8_t *addr) goto free_bcast_own_sum; if (bat_priv->orig_hash->elements * 4 > bat_priv->orig_hash->size) { - swaphash = hash_resize(bat_priv->orig_hash, compare_orig, - choose_orig, + swaphash = hash_resize(bat_priv->orig_hash, choose_orig, bat_priv->orig_hash->size * 2); if (!swaphash) @@ -272,6 +271,7 @@ static bool purge_orig_node(struct bat_priv *bat_priv, static void _purge_orig(struct bat_priv *bat_priv) { HASHIT(hashit); + struct element_t *bucket; struct orig_node *orig_node; unsigned long flags; @@ -279,7 +279,8 @@ static void _purge_orig(struct bat_priv *bat_priv) /* for all origins... */ while (hash_iterate(bat_priv->orig_hash, &hashit)) { - orig_node = hashit.bucket->data; + bucket = hlist_entry(hashit.walk, struct element_t, hlist); + orig_node = bucket->data; if (purge_orig_node(bat_priv, orig_node)) { hash_remove_bucket(bat_priv->orig_hash, &hashit); @@ -315,6 +316,7 @@ void purge_orig_ref(struct bat_priv *bat_priv) int orig_seq_print_text(struct seq_file *seq, void *offset) { HASHIT(hashit); + struct element_t *bucket; struct net_device *net_dev = (struct net_device *)seq->private; struct bat_priv *bat_priv = netdev_priv(net_dev); struct orig_node *orig_node; @@ -347,8 +349,8 @@ int orig_seq_print_text(struct seq_file *seq, void *offset) spin_lock_irqsave(&bat_priv->orig_hash_lock, flags); while (hash_iterate(bat_priv->orig_hash, &hashit)) { - - orig_node = hashit.bucket->data; + bucket = hlist_entry(hashit.walk, struct element_t, hlist); + orig_node = bucket->data; if (!orig_node->router) continue; @@ -419,13 +421,15 @@ int orig_hash_add_if(struct batman_if *batman_if, int max_if_num) struct orig_node *orig_node; unsigned long flags; HASHIT(hashit); + struct element_t *bucket; /* resize all orig nodes because orig_node->bcast_own(_sum) depend on * if_num */ spin_lock_irqsave(&bat_priv->orig_hash_lock, flags); while (hash_iterate(bat_priv->orig_hash, &hashit)) { - orig_node = hashit.bucket->data; + bucket = hlist_entry(hashit.walk, struct element_t, hlist); + orig_node = bucket->data; if (orig_node_add_if(orig_node, max_if_num) == -1) goto err; @@ -498,6 +502,7 @@ int orig_hash_del_if(struct batman_if *batman_if, int max_if_num) struct orig_node *orig_node; unsigned long flags; HASHIT(hashit); + struct element_t *bucket; int ret; /* resize all orig nodes because orig_node->bcast_own(_sum) depend on @@ -505,7 +510,8 @@ int orig_hash_del_if(struct batman_if *batman_if, int max_if_num) spin_lock_irqsave(&bat_priv->orig_hash_lock, flags); while (hash_iterate(bat_priv->orig_hash, &hashit)) { - orig_node = hashit.bucket->data; + bucket = hlist_entry(hashit.walk, struct element_t, hlist); + orig_node = bucket->data; ret = orig_node_del_if(orig_node, max_if_num, batman_if->if_num); diff --git a/drivers/staging/batman-adv/routing.c b/drivers/staging/batman-adv/routing.c index 9cbb19594e34..77e5d1411c99 100644 --- a/drivers/staging/batman-adv/routing.c +++ b/drivers/staging/batman-adv/routing.c @@ -38,6 +38,7 @@ void slide_own_bcast_window(struct batman_if *batman_if) { struct bat_priv *bat_priv = netdev_priv(batman_if->soft_iface); HASHIT(hashit); + struct element_t *bucket; struct orig_node *orig_node; TYPE_OF_WORD *word; unsigned long flags; @@ -45,7 +46,8 @@ void slide_own_bcast_window(struct batman_if *batman_if) spin_lock_irqsave(&bat_priv->orig_hash_lock, flags); while (hash_iterate(bat_priv->orig_hash, &hashit)) { - orig_node = hashit.bucket->data; + bucket = hlist_entry(hashit.walk, struct element_t, hlist); + orig_node = bucket->data; word = &(orig_node->bcast_own[batman_if->if_num * NUM_WORDS]); bit_get_packet(bat_priv, word, 1, 0); diff --git a/drivers/staging/batman-adv/translation-table.c b/drivers/staging/batman-adv/translation-table.c index 96d59b100df8..6639bfb66ab8 100644 --- a/drivers/staging/batman-adv/translation-table.c +++ b/drivers/staging/batman-adv/translation-table.c @@ -116,8 +116,7 @@ void hna_local_add(struct net_device *soft_iface, uint8_t *addr) if (bat_priv->hna_local_hash->elements * 4 > bat_priv->hna_local_hash->size) { - swaphash = hash_resize(bat_priv->hna_local_hash, compare_orig, - choose_orig, + swaphash = hash_resize(bat_priv->hna_local_hash, choose_orig, bat_priv->hna_local_hash->size * 2); if (!swaphash) @@ -146,6 +145,7 @@ int hna_local_fill_buffer(struct bat_priv *bat_priv, unsigned char *buff, int buff_len) { struct hna_local_entry *hna_local_entry; + struct element_t *bucket; HASHIT(hashit); int i = 0; unsigned long flags; @@ -157,7 +157,8 @@ int hna_local_fill_buffer(struct bat_priv *bat_priv, if (buff_len < (i + 1) * ETH_ALEN) break; - hna_local_entry = hashit.bucket->data; + bucket = hlist_entry(hashit.walk, struct element_t, hlist); + hna_local_entry = bucket->data; memcpy(buff + (i * ETH_ALEN), hna_local_entry->addr, ETH_ALEN); i++; @@ -178,6 +179,7 @@ int hna_local_seq_print_text(struct seq_file *seq, void *offset) struct hna_local_entry *hna_local_entry; HASHIT(hashit); HASHIT(hashit_count); + struct element_t *bucket; unsigned long flags; size_t buf_size, pos; char *buff; @@ -208,7 +210,8 @@ int hna_local_seq_print_text(struct seq_file *seq, void *offset) pos = 0; while (hash_iterate(bat_priv->hna_local_hash, &hashit)) { - hna_local_entry = hashit.bucket->data; + bucket = hlist_entry(hashit.walk, struct element_t, hlist); + hna_local_entry = bucket->data; pos += snprintf(buff + pos, 22, " * %pM\n", hna_local_entry->addr); @@ -267,13 +270,15 @@ static void hna_local_purge(struct work_struct *work) container_of(delayed_work, struct bat_priv, hna_work); struct hna_local_entry *hna_local_entry; HASHIT(hashit); + struct element_t *bucket; unsigned long flags; unsigned long timeout; spin_lock_irqsave(&bat_priv->hna_lhash_lock, flags); while (hash_iterate(bat_priv->hna_local_hash, &hashit)) { - hna_local_entry = hashit.bucket->data; + bucket = hlist_entry(hashit.walk, struct element_t, hlist); + hna_local_entry = bucket->data; timeout = hna_local_entry->last_seen + LOCAL_HNA_TIMEOUT * HZ; @@ -389,8 +394,7 @@ void hna_global_add_orig(struct bat_priv *bat_priv, if (bat_priv->hna_global_hash->elements * 4 > bat_priv->hna_global_hash->size) { - swaphash = hash_resize(bat_priv->hna_global_hash, compare_orig, - choose_orig, + swaphash = hash_resize(bat_priv->hna_global_hash, choose_orig, bat_priv->hna_global_hash->size * 2); if (!swaphash) @@ -409,6 +413,7 @@ int hna_global_seq_print_text(struct seq_file *seq, void *offset) struct hna_global_entry *hna_global_entry; HASHIT(hashit); HASHIT(hashit_count); + struct element_t *bucket; unsigned long flags; size_t buf_size, pos; char *buff; @@ -438,7 +443,8 @@ int hna_global_seq_print_text(struct seq_file *seq, void *offset) pos = 0; while (hash_iterate(bat_priv->hna_global_hash, &hashit)) { - hna_global_entry = hashit.bucket->data; + bucket = hlist_entry(hashit.walk, struct element_t, hlist); + hna_global_entry = bucket->data; pos += snprintf(buff + pos, 44, " * %pM via %pM\n", hna_global_entry->addr, diff --git a/drivers/staging/batman-adv/vis.c b/drivers/staging/batman-adv/vis.c index dccd296c6ff3..e2031c9aab9d 100644 --- a/drivers/staging/batman-adv/vis.c +++ b/drivers/staging/batman-adv/vis.c @@ -177,6 +177,7 @@ int vis_seq_print_text(struct seq_file *seq, void *offset) { HASHIT(hashit); HASHIT(hashit_count); + struct element_t *bucket; struct vis_info *info; struct vis_packet *packet; struct vis_info_entry *entries; @@ -199,7 +200,9 @@ int vis_seq_print_text(struct seq_file *seq, void *offset) /* Estimate length */ spin_lock_irqsave(&bat_priv->vis_hash_lock, flags); while (hash_iterate(bat_priv->vis_hash, &hashit_count)) { - info = hashit_count.bucket->data; + bucket = hlist_entry(hashit_count.walk, struct element_t, + hlist); + info = bucket->data; packet = (struct vis_packet *)info->skb_packet->data; entries = (struct vis_info_entry *) ((char *)packet + sizeof(struct vis_packet)); @@ -237,7 +240,8 @@ int vis_seq_print_text(struct seq_file *seq, void *offset) buff_pos = 0; while (hash_iterate(bat_priv->vis_hash, &hashit)) { - info = hashit.bucket->data; + bucket = hlist_entry(hashit.walk, struct element_t, hlist); + info = bucket->data; packet = (struct vis_packet *)info->skb_packet->data; entries = (struct vis_info_entry *) ((char *)packet + sizeof(struct vis_packet)); @@ -515,6 +519,7 @@ static int find_best_vis_server(struct bat_priv *bat_priv, struct vis_info *info) { HASHIT(hashit); + struct element_t *bucket; struct orig_node *orig_node; struct vis_packet *packet; int best_tq = -1; @@ -522,7 +527,8 @@ static int find_best_vis_server(struct bat_priv *bat_priv, packet = (struct vis_packet *)info->skb_packet->data; while (hash_iterate(bat_priv->orig_hash, &hashit)) { - orig_node = hashit.bucket->data; + bucket = hlist_entry(hashit.walk, struct element_t, hlist); + orig_node = bucket->data; if ((orig_node) && (orig_node->router) && (orig_node->flags & VIS_SERVER) && (orig_node->router->tq_avg > best_tq)) { @@ -551,6 +557,7 @@ static int generate_vis_packet(struct bat_priv *bat_priv) { HASHIT(hashit_local); HASHIT(hashit_global); + struct element_t *bucket; struct orig_node *orig_node; struct vis_info *info = (struct vis_info *)bat_priv->my_vis_info; struct vis_packet *packet = (struct vis_packet *)info->skb_packet->data; @@ -580,7 +587,9 @@ static int generate_vis_packet(struct bat_priv *bat_priv) } while (hash_iterate(bat_priv->orig_hash, &hashit_global)) { - orig_node = hashit_global.bucket->data; + bucket = hlist_entry(hashit_global.walk, struct element_t, + hlist); + orig_node = bucket->data; if (!orig_node->router) continue; @@ -615,7 +624,9 @@ static int generate_vis_packet(struct bat_priv *bat_priv) spin_lock_irqsave(&bat_priv->hna_lhash_lock, flags); while (hash_iterate(bat_priv->hna_local_hash, &hashit_local)) { - hna_local_entry = hashit_local.bucket->data; + bucket = hlist_entry(hashit_local.walk, struct element_t, + hlist); + hna_local_entry = bucket->data; entry = (struct vis_info_entry *)skb_put(info->skb_packet, sizeof(*entry)); memset(entry->src, 0, ETH_ALEN); @@ -639,10 +650,12 @@ static int generate_vis_packet(struct bat_priv *bat_priv) static void purge_vis_packets(struct bat_priv *bat_priv) { HASHIT(hashit); + struct element_t *bucket; struct vis_info *info; while (hash_iterate(bat_priv->vis_hash, &hashit)) { - info = hashit.bucket->data; + bucket = hlist_entry(hashit.walk, struct element_t, hlist); + info = bucket->data; /* never purge own data. */ if (info == bat_priv->my_vis_info) @@ -661,6 +674,7 @@ static void broadcast_vis_packet(struct bat_priv *bat_priv, struct vis_info *info) { HASHIT(hashit); + struct element_t *bucket; struct orig_node *orig_node; struct vis_packet *packet; struct sk_buff *skb; @@ -674,7 +688,8 @@ static void broadcast_vis_packet(struct bat_priv *bat_priv, /* send to all routers in range. */ while (hash_iterate(bat_priv->orig_hash, &hashit)) { - orig_node = hashit.bucket->data; + bucket = hlist_entry(hashit.walk, struct element_t, hlist); + orig_node = bucket->data; /* if it's a vis server and reachable, send it. */ if ((!orig_node) || (!orig_node->router)) -- cgit v1.2.3 From 7a18deb7b03e4112af5add8498889f9b2b36d59f Mon Sep 17 00:00:00 2001 From: Sven Eckelmann Date: Mon, 22 Nov 2010 00:56:01 +0100 Subject: Staging: batman-adv: Limit spin_locks to spin_lock_bh spin_lock_irqsave disables the IRQs and stores them inside the flags provided by the caller. This is needed to protect a bottom half handler or a user context critical section from being interrupted by an interrupt handler which also tries to acquire the spinlock and locks forever. The linux device drivers will receive the packets inside an interrupt handler and the network infrastructure will process them inside bottom half. Thus batman-adv will only run in user context and bottom half handlers. We can conclude that batman-adv doesn't share its own spinlocks with real interrupt handlers. This makes it possible to exchange the quite complex spin_lock_irqsave with spin_lock_bh which only stops bottom halves from running on the current cpu, but allows interrupt handlers to take over to keep the interrupt latency low. Signed-off-by: Sven Eckelmann Signed-off-by: Greg Kroah-Hartman --- drivers/staging/batman-adv/aggregation.c | 12 ++-- drivers/staging/batman-adv/bat_debugfs.c | 14 ++-- drivers/staging/batman-adv/icmp_socket.c | 24 +++---- drivers/staging/batman-adv/originator.c | 37 +++++------ drivers/staging/batman-adv/routing.c | 49 ++++++-------- drivers/staging/batman-adv/send.c | 32 ++++----- drivers/staging/batman-adv/soft-interface.c | 10 ++- drivers/staging/batman-adv/translation-table.c | 70 +++++++++----------- drivers/staging/batman-adv/unicast.c | 12 ++-- drivers/staging/batman-adv/vis.c | 90 +++++++++++--------------- 10 files changed, 147 insertions(+), 203 deletions(-) diff --git a/drivers/staging/batman-adv/aggregation.c b/drivers/staging/batman-adv/aggregation.c index 3dfed2f4bb5d..0c92e3b35abf 100644 --- a/drivers/staging/batman-adv/aggregation.c +++ b/drivers/staging/batman-adv/aggregation.c @@ -104,7 +104,6 @@ static void new_aggregated_packet(unsigned char *packet_buff, int packet_len, { struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface); struct forw_packet *forw_packet_aggr; - unsigned long flags; unsigned char *skb_buff; /* own packet should always be scheduled */ @@ -156,9 +155,9 @@ static void new_aggregated_packet(unsigned char *packet_buff, int packet_len, forw_packet_aggr->direct_link_flags |= 1; /* add new packet to packet list */ - spin_lock_irqsave(&bat_priv->forw_bat_list_lock, flags); + spin_lock_bh(&bat_priv->forw_bat_list_lock); hlist_add_head(&forw_packet_aggr->list, &bat_priv->forw_bat_list); - spin_unlock_irqrestore(&bat_priv->forw_bat_list_lock, flags); + spin_unlock_bh(&bat_priv->forw_bat_list_lock); /* start timer for this packet */ INIT_DELAYED_WORK(&forw_packet_aggr->delayed_work, @@ -201,10 +200,9 @@ void add_bat_packet_to_list(struct bat_priv *bat_priv, struct batman_packet *batman_packet = (struct batman_packet *)packet_buff; bool direct_link = batman_packet->flags & DIRECTLINK ? 1 : 0; - unsigned long flags; /* find position for the packet in the forward queue */ - spin_lock_irqsave(&bat_priv->forw_bat_list_lock, flags); + spin_lock_bh(&bat_priv->forw_bat_list_lock); /* own packets are not to be aggregated */ if ((atomic_read(&bat_priv->aggregated_ogms)) && (!own_packet)) { hlist_for_each_entry(forw_packet_pos, tmp_node, @@ -225,7 +223,7 @@ void add_bat_packet_to_list(struct bat_priv *bat_priv, * suitable aggregation packet found */ if (forw_packet_aggr == NULL) { /* the following section can run without the lock */ - spin_unlock_irqrestore(&bat_priv->forw_bat_list_lock, flags); + spin_unlock_bh(&bat_priv->forw_bat_list_lock); /** * if we could not aggregate this packet with one of the others @@ -243,7 +241,7 @@ void add_bat_packet_to_list(struct bat_priv *bat_priv, aggregate(forw_packet_aggr, packet_buff, packet_len, direct_link); - spin_unlock_irqrestore(&bat_priv->forw_bat_list_lock, flags); + spin_unlock_bh(&bat_priv->forw_bat_list_lock); } } diff --git a/drivers/staging/batman-adv/bat_debugfs.c b/drivers/staging/batman-adv/bat_debugfs.c index 22f3eb98470f..cbac1a53ad74 100644 --- a/drivers/staging/batman-adv/bat_debugfs.c +++ b/drivers/staging/batman-adv/bat_debugfs.c @@ -54,12 +54,11 @@ static int fdebug_log(struct debug_log *debug_log, char *fmt, ...) va_list args; static char debug_log_buf[256]; char *p; - unsigned long flags; if (!debug_log) return 0; - spin_lock_irqsave(&debug_log->lock, flags); + spin_lock_bh(&debug_log->lock); va_start(args, fmt); printed_len = vscnprintf(debug_log_buf, sizeof(debug_log_buf), fmt, args); @@ -68,7 +67,7 @@ static int fdebug_log(struct debug_log *debug_log, char *fmt, ...) for (p = debug_log_buf; *p != 0; p++) emit_log_char(debug_log, *p); - spin_unlock_irqrestore(&debug_log->lock, flags); + spin_unlock_bh(&debug_log->lock); wake_up(&debug_log->queue_wait); @@ -110,7 +109,6 @@ static ssize_t log_read(struct file *file, char __user *buf, struct debug_log *debug_log = bat_priv->debug_log; int error, i = 0; char c; - unsigned long flags; if ((file->f_flags & O_NONBLOCK) && !(debug_log->log_end - debug_log->log_start)) @@ -131,7 +129,7 @@ static ssize_t log_read(struct file *file, char __user *buf, if (error) return error; - spin_lock_irqsave(&debug_log->lock, flags); + spin_lock_bh(&debug_log->lock); while ((!error) && (i < count) && (debug_log->log_start != debug_log->log_end)) { @@ -139,18 +137,18 @@ static ssize_t log_read(struct file *file, char __user *buf, debug_log->log_start++; - spin_unlock_irqrestore(&debug_log->lock, flags); + spin_unlock_bh(&debug_log->lock); error = __put_user(c, buf); - spin_lock_irqsave(&debug_log->lock, flags); + spin_lock_bh(&debug_log->lock); buf++; i++; } - spin_unlock_irqrestore(&debug_log->lock, flags); + spin_unlock_bh(&debug_log->lock); if (!error) return i; diff --git a/drivers/staging/batman-adv/icmp_socket.c b/drivers/staging/batman-adv/icmp_socket.c index a8c98aa9630c..a933ca609b74 100644 --- a/drivers/staging/batman-adv/icmp_socket.c +++ b/drivers/staging/batman-adv/icmp_socket.c @@ -85,9 +85,8 @@ static int bat_socket_release(struct inode *inode, struct file *file) struct socket_client *socket_client = file->private_data; struct socket_packet *socket_packet; struct list_head *list_pos, *list_pos_tmp; - unsigned long flags; - spin_lock_irqsave(&socket_client->lock, flags); + spin_lock_bh(&socket_client->lock); /* for all packets in the queue ... */ list_for_each_safe(list_pos, list_pos_tmp, &socket_client->queue_list) { @@ -99,7 +98,7 @@ static int bat_socket_release(struct inode *inode, struct file *file) } socket_client_hash[socket_client->index] = NULL; - spin_unlock_irqrestore(&socket_client->lock, flags); + spin_unlock_bh(&socket_client->lock); kfree(socket_client); dec_module_count(); @@ -114,7 +113,6 @@ static ssize_t bat_socket_read(struct file *file, char __user *buf, struct socket_packet *socket_packet; size_t packet_len; int error; - unsigned long flags; if ((file->f_flags & O_NONBLOCK) && (socket_client->queue_len == 0)) return -EAGAIN; @@ -131,14 +129,14 @@ static ssize_t bat_socket_read(struct file *file, char __user *buf, if (error) return error; - spin_lock_irqsave(&socket_client->lock, flags); + spin_lock_bh(&socket_client->lock); socket_packet = list_first_entry(&socket_client->queue_list, struct socket_packet, list); list_del(&socket_packet->list); socket_client->queue_len--; - spin_unlock_irqrestore(&socket_client->lock, flags); + spin_unlock_bh(&socket_client->lock); error = __copy_to_user(buf, &socket_packet->icmp_packet, socket_packet->icmp_len); @@ -164,7 +162,6 @@ static ssize_t bat_socket_write(struct file *file, const char __user *buff, struct batman_if *batman_if; size_t packet_len = sizeof(struct icmp_packet); uint8_t dstaddr[ETH_ALEN]; - unsigned long flags; if (len < sizeof(struct icmp_packet)) { bat_dbg(DBG_BATMAN, bat_priv, @@ -224,7 +221,7 @@ static ssize_t bat_socket_write(struct file *file, const char __user *buff, if (atomic_read(&bat_priv->mesh_state) != MESH_ACTIVE) goto dst_unreach; - spin_lock_irqsave(&bat_priv->orig_hash_lock, flags); + spin_lock_bh(&bat_priv->orig_hash_lock); orig_node = ((struct orig_node *)hash_find(bat_priv->orig_hash, compare_orig, choose_orig, icmp_packet->dst)); @@ -238,7 +235,7 @@ static ssize_t bat_socket_write(struct file *file, const char __user *buff, batman_if = orig_node->router->if_incoming; memcpy(dstaddr, orig_node->router->addr, ETH_ALEN); - spin_unlock_irqrestore(&bat_priv->orig_hash_lock, flags); + spin_unlock_bh(&bat_priv->orig_hash_lock); if (!batman_if) goto dst_unreach; @@ -258,7 +255,7 @@ static ssize_t bat_socket_write(struct file *file, const char __user *buff, goto out; unlock: - spin_unlock_irqrestore(&bat_priv->orig_hash_lock, flags); + spin_unlock_bh(&bat_priv->orig_hash_lock); dst_unreach: icmp_packet->msg_type = DESTINATION_UNREACHABLE; bat_socket_add_packet(socket_client, icmp_packet, packet_len); @@ -313,7 +310,6 @@ static void bat_socket_add_packet(struct socket_client *socket_client, size_t icmp_len) { struct socket_packet *socket_packet; - unsigned long flags; socket_packet = kmalloc(sizeof(struct socket_packet), GFP_ATOMIC); @@ -324,12 +320,12 @@ static void bat_socket_add_packet(struct socket_client *socket_client, memcpy(&socket_packet->icmp_packet, icmp_packet, icmp_len); socket_packet->icmp_len = icmp_len; - spin_lock_irqsave(&socket_client->lock, flags); + spin_lock_bh(&socket_client->lock); /* while waiting for the lock the socket_client could have been * deleted */ if (!socket_client_hash[icmp_packet->uid]) { - spin_unlock_irqrestore(&socket_client->lock, flags); + spin_unlock_bh(&socket_client->lock); kfree(socket_packet); return; } @@ -346,7 +342,7 @@ static void bat_socket_add_packet(struct socket_client *socket_client, socket_client->queue_len--; } - spin_unlock_irqrestore(&socket_client->lock, flags); + spin_unlock_bh(&socket_client->lock); wake_up(&socket_client->queue_wait); } diff --git a/drivers/staging/batman-adv/originator.c b/drivers/staging/batman-adv/originator.c index a4b7d377d941..8bef4681bf82 100644 --- a/drivers/staging/batman-adv/originator.c +++ b/drivers/staging/batman-adv/originator.c @@ -40,22 +40,21 @@ static void start_purge_timer(struct bat_priv *bat_priv) int originator_init(struct bat_priv *bat_priv) { - unsigned long flags; if (bat_priv->orig_hash) return 1; - spin_lock_irqsave(&bat_priv->orig_hash_lock, flags); + spin_lock_bh(&bat_priv->orig_hash_lock); bat_priv->orig_hash = hash_new(128); if (!bat_priv->orig_hash) goto err; - spin_unlock_irqrestore(&bat_priv->orig_hash_lock, flags); + spin_unlock_bh(&bat_priv->orig_hash_lock); start_purge_timer(bat_priv); return 1; err: - spin_unlock_irqrestore(&bat_priv->orig_hash_lock, flags); + spin_unlock_bh(&bat_priv->orig_hash_lock); return 0; } @@ -108,17 +107,15 @@ static void free_orig_node(void *data, void *arg) void originator_free(struct bat_priv *bat_priv) { - unsigned long flags; - if (!bat_priv->orig_hash) return; cancel_delayed_work_sync(&bat_priv->orig_work); - spin_lock_irqsave(&bat_priv->orig_hash_lock, flags); + spin_lock_bh(&bat_priv->orig_hash_lock); hash_delete(bat_priv->orig_hash, free_orig_node, bat_priv); bat_priv->orig_hash = NULL; - spin_unlock_irqrestore(&bat_priv->orig_hash_lock, flags); + spin_unlock_bh(&bat_priv->orig_hash_lock); } /* this function finds or creates an originator entry for the given @@ -273,9 +270,8 @@ static void _purge_orig(struct bat_priv *bat_priv) HASHIT(hashit); struct element_t *bucket; struct orig_node *orig_node; - unsigned long flags; - spin_lock_irqsave(&bat_priv->orig_hash_lock, flags); + spin_lock_bh(&bat_priv->orig_hash_lock); /* for all origins... */ while (hash_iterate(bat_priv->orig_hash, &hashit)) { @@ -292,7 +288,7 @@ static void _purge_orig(struct bat_priv *bat_priv) frag_list_free(&orig_node->frag_list); } - spin_unlock_irqrestore(&bat_priv->orig_hash_lock, flags); + spin_unlock_bh(&bat_priv->orig_hash_lock); softif_neigh_purge(bat_priv); } @@ -324,7 +320,6 @@ int orig_seq_print_text(struct seq_file *seq, void *offset) int batman_count = 0; int last_seen_secs; int last_seen_msecs; - unsigned long flags; if ((!bat_priv->primary_if) || (bat_priv->primary_if->if_status != IF_ACTIVE)) { @@ -346,7 +341,7 @@ int orig_seq_print_text(struct seq_file *seq, void *offset) "Originator", "last-seen", "#", TQ_MAX_VALUE, "Nexthop", "outgoingIF", "Potential nexthops"); - spin_lock_irqsave(&bat_priv->orig_hash_lock, flags); + spin_lock_bh(&bat_priv->orig_hash_lock); while (hash_iterate(bat_priv->orig_hash, &hashit)) { bucket = hlist_entry(hashit.walk, struct element_t, hlist); @@ -377,7 +372,7 @@ int orig_seq_print_text(struct seq_file *seq, void *offset) batman_count++; } - spin_unlock_irqrestore(&bat_priv->orig_hash_lock, flags); + spin_unlock_bh(&bat_priv->orig_hash_lock); if ((batman_count == 0)) seq_printf(seq, "No batman nodes in range ...\n"); @@ -419,13 +414,12 @@ int orig_hash_add_if(struct batman_if *batman_if, int max_if_num) { struct bat_priv *bat_priv = netdev_priv(batman_if->soft_iface); struct orig_node *orig_node; - unsigned long flags; HASHIT(hashit); struct element_t *bucket; /* resize all orig nodes because orig_node->bcast_own(_sum) depend on * if_num */ - spin_lock_irqsave(&bat_priv->orig_hash_lock, flags); + spin_lock_bh(&bat_priv->orig_hash_lock); while (hash_iterate(bat_priv->orig_hash, &hashit)) { bucket = hlist_entry(hashit.walk, struct element_t, hlist); @@ -435,11 +429,11 @@ int orig_hash_add_if(struct batman_if *batman_if, int max_if_num) goto err; } - spin_unlock_irqrestore(&bat_priv->orig_hash_lock, flags); + spin_unlock_bh(&bat_priv->orig_hash_lock); return 0; err: - spin_unlock_irqrestore(&bat_priv->orig_hash_lock, flags); + spin_unlock_bh(&bat_priv->orig_hash_lock); return -ENOMEM; } @@ -500,14 +494,13 @@ int orig_hash_del_if(struct batman_if *batman_if, int max_if_num) struct bat_priv *bat_priv = netdev_priv(batman_if->soft_iface); struct batman_if *batman_if_tmp; struct orig_node *orig_node; - unsigned long flags; HASHIT(hashit); struct element_t *bucket; int ret; /* resize all orig nodes because orig_node->bcast_own(_sum) depend on * if_num */ - spin_lock_irqsave(&bat_priv->orig_hash_lock, flags); + spin_lock_bh(&bat_priv->orig_hash_lock); while (hash_iterate(bat_priv->orig_hash, &hashit)) { bucket = hlist_entry(hashit.walk, struct element_t, hlist); @@ -538,10 +531,10 @@ int orig_hash_del_if(struct batman_if *batman_if, int max_if_num) rcu_read_unlock(); batman_if->if_num = -1; - spin_unlock_irqrestore(&bat_priv->orig_hash_lock, flags); + spin_unlock_bh(&bat_priv->orig_hash_lock); return 0; err: - spin_unlock_irqrestore(&bat_priv->orig_hash_lock, flags); + spin_unlock_bh(&bat_priv->orig_hash_lock); return -ENOMEM; } diff --git a/drivers/staging/batman-adv/routing.c b/drivers/staging/batman-adv/routing.c index 77e5d1411c99..1536963dd69f 100644 --- a/drivers/staging/batman-adv/routing.c +++ b/drivers/staging/batman-adv/routing.c @@ -41,9 +41,8 @@ void slide_own_bcast_window(struct batman_if *batman_if) struct element_t *bucket; struct orig_node *orig_node; TYPE_OF_WORD *word; - unsigned long flags; - spin_lock_irqsave(&bat_priv->orig_hash_lock, flags); + spin_lock_bh(&bat_priv->orig_hash_lock); while (hash_iterate(bat_priv->orig_hash, &hashit)) { bucket = hlist_entry(hashit.walk, struct element_t, hlist); @@ -55,7 +54,7 @@ void slide_own_bcast_window(struct batman_if *batman_if) bit_packet_count(word); } - spin_unlock_irqrestore(&bat_priv->orig_hash_lock, flags); + spin_unlock_bh(&bat_priv->orig_hash_lock); } static void update_HNA(struct bat_priv *bat_priv, struct orig_node *orig_node, @@ -749,7 +748,6 @@ int recv_bat_packet(struct sk_buff *skb, struct batman_if *batman_if) { struct bat_priv *bat_priv = netdev_priv(batman_if->soft_iface); struct ethhdr *ethhdr; - unsigned long flags; /* drop packet if it has not necessary minimum size */ if (unlikely(!pskb_may_pull(skb, sizeof(struct batman_packet)))) @@ -775,12 +773,12 @@ int recv_bat_packet(struct sk_buff *skb, struct batman_if *batman_if) ethhdr = (struct ethhdr *)skb_mac_header(skb); - spin_lock_irqsave(&bat_priv->orig_hash_lock, flags); + spin_lock_bh(&bat_priv->orig_hash_lock); receive_aggr_bat_packet(ethhdr, skb->data, skb_headlen(skb), batman_if); - spin_unlock_irqrestore(&bat_priv->orig_hash_lock, flags); + spin_unlock_bh(&bat_priv->orig_hash_lock); kfree_skb(skb); return NET_RX_SUCCESS; @@ -794,7 +792,6 @@ static int recv_my_icmp_packet(struct bat_priv *bat_priv, struct ethhdr *ethhdr; struct batman_if *batman_if; int ret; - unsigned long flags; uint8_t dstaddr[ETH_ALEN]; icmp_packet = (struct icmp_packet_rr *)skb->data; @@ -811,7 +808,7 @@ static int recv_my_icmp_packet(struct bat_priv *bat_priv, /* answer echo request (ping) */ /* get routing information */ - spin_lock_irqsave(&bat_priv->orig_hash_lock, flags); + spin_lock_bh(&bat_priv->orig_hash_lock); orig_node = ((struct orig_node *)hash_find(bat_priv->orig_hash, compare_orig, choose_orig, icmp_packet->orig)); @@ -824,7 +821,7 @@ static int recv_my_icmp_packet(struct bat_priv *bat_priv, * copy the required data before sending */ batman_if = orig_node->router->if_incoming; memcpy(dstaddr, orig_node->router->addr, ETH_ALEN); - spin_unlock_irqrestore(&bat_priv->orig_hash_lock, flags); + spin_unlock_bh(&bat_priv->orig_hash_lock); /* create a copy of the skb, if needed, to modify it. */ if (skb_cow(skb, sizeof(struct ethhdr)) < 0) @@ -843,7 +840,7 @@ static int recv_my_icmp_packet(struct bat_priv *bat_priv, ret = NET_RX_SUCCESS; } else - spin_unlock_irqrestore(&bat_priv->orig_hash_lock, flags); + spin_unlock_bh(&bat_priv->orig_hash_lock); return ret; } @@ -856,7 +853,6 @@ static int recv_icmp_ttl_exceeded(struct bat_priv *bat_priv, struct ethhdr *ethhdr; struct batman_if *batman_if; int ret; - unsigned long flags; uint8_t dstaddr[ETH_ALEN]; icmp_packet = (struct icmp_packet *)skb->data; @@ -874,7 +870,7 @@ static int recv_icmp_ttl_exceeded(struct bat_priv *bat_priv, return NET_RX_DROP; /* get routing information */ - spin_lock_irqsave(&bat_priv->orig_hash_lock, flags); + spin_lock_bh(&bat_priv->orig_hash_lock); orig_node = ((struct orig_node *) hash_find(bat_priv->orig_hash, compare_orig, choose_orig, icmp_packet->orig)); @@ -887,7 +883,7 @@ static int recv_icmp_ttl_exceeded(struct bat_priv *bat_priv, * copy the required data before sending */ batman_if = orig_node->router->if_incoming; memcpy(dstaddr, orig_node->router->addr, ETH_ALEN); - spin_unlock_irqrestore(&bat_priv->orig_hash_lock, flags); + spin_unlock_bh(&bat_priv->orig_hash_lock); /* create a copy of the skb, if needed, to modify it. */ if (skb_cow(skb, sizeof(struct ethhdr)) < 0) @@ -906,7 +902,7 @@ static int recv_icmp_ttl_exceeded(struct bat_priv *bat_priv, ret = NET_RX_SUCCESS; } else - spin_unlock_irqrestore(&bat_priv->orig_hash_lock, flags); + spin_unlock_bh(&bat_priv->orig_hash_lock); return ret; } @@ -921,7 +917,6 @@ int recv_icmp_packet(struct sk_buff *skb, struct batman_if *recv_if) struct batman_if *batman_if; int hdr_size = sizeof(struct icmp_packet); int ret; - unsigned long flags; uint8_t dstaddr[ETH_ALEN]; /** @@ -969,7 +964,7 @@ int recv_icmp_packet(struct sk_buff *skb, struct batman_if *recv_if) ret = NET_RX_DROP; /* get routing information */ - spin_lock_irqsave(&bat_priv->orig_hash_lock, flags); + spin_lock_bh(&bat_priv->orig_hash_lock); orig_node = ((struct orig_node *) hash_find(bat_priv->orig_hash, compare_orig, choose_orig, icmp_packet->dst)); @@ -981,7 +976,7 @@ int recv_icmp_packet(struct sk_buff *skb, struct batman_if *recv_if) * copy the required data before sending */ batman_if = orig_node->router->if_incoming; memcpy(dstaddr, orig_node->router->addr, ETH_ALEN); - spin_unlock_irqrestore(&bat_priv->orig_hash_lock, flags); + spin_unlock_bh(&bat_priv->orig_hash_lock); /* create a copy of the skb, if needed, to modify it. */ if (skb_cow(skb, sizeof(struct ethhdr)) < 0) @@ -998,7 +993,7 @@ int recv_icmp_packet(struct sk_buff *skb, struct batman_if *recv_if) ret = NET_RX_SUCCESS; } else - spin_unlock_irqrestore(&bat_priv->orig_hash_lock, flags); + spin_unlock_bh(&bat_priv->orig_hash_lock); return ret; } @@ -1131,7 +1126,6 @@ int route_unicast_packet(struct sk_buff *skb, struct batman_if *recv_if, struct neigh_node *router; struct batman_if *batman_if; uint8_t dstaddr[ETH_ALEN]; - unsigned long flags; struct unicast_packet *unicast_packet; struct ethhdr *ethhdr = (struct ethhdr *)skb_mac_header(skb); int ret; @@ -1148,7 +1142,7 @@ int route_unicast_packet(struct sk_buff *skb, struct batman_if *recv_if, } /* get routing information */ - spin_lock_irqsave(&bat_priv->orig_hash_lock, flags); + spin_lock_bh(&bat_priv->orig_hash_lock); orig_node = ((struct orig_node *) hash_find(bat_priv->orig_hash, compare_orig, choose_orig, unicast_packet->dest)); @@ -1156,7 +1150,7 @@ int route_unicast_packet(struct sk_buff *skb, struct batman_if *recv_if, router = find_router(bat_priv, orig_node, recv_if); if (!router) { - spin_unlock_irqrestore(&bat_priv->orig_hash_lock, flags); + spin_unlock_bh(&bat_priv->orig_hash_lock); return NET_RX_DROP; } @@ -1166,7 +1160,7 @@ int route_unicast_packet(struct sk_buff *skb, struct batman_if *recv_if, batman_if = router->if_incoming; memcpy(dstaddr, router->addr, ETH_ALEN); - spin_unlock_irqrestore(&bat_priv->orig_hash_lock, flags); + spin_unlock_bh(&bat_priv->orig_hash_lock); /* create a copy of the skb, if needed, to modify it. */ if (skb_cow(skb, sizeof(struct ethhdr)) < 0) @@ -1266,7 +1260,6 @@ int recv_bcast_packet(struct sk_buff *skb, struct batman_if *recv_if) struct ethhdr *ethhdr; int hdr_size = sizeof(struct bcast_packet); int32_t seq_diff; - unsigned long flags; /* drop packet if it has not necessary minimum size */ if (unlikely(!pskb_may_pull(skb, hdr_size))) @@ -1295,13 +1288,13 @@ int recv_bcast_packet(struct sk_buff *skb, struct batman_if *recv_if) if (bcast_packet->ttl < 2) return NET_RX_DROP; - spin_lock_irqsave(&bat_priv->orig_hash_lock, flags); + spin_lock_bh(&bat_priv->orig_hash_lock); orig_node = ((struct orig_node *) hash_find(bat_priv->orig_hash, compare_orig, choose_orig, bcast_packet->orig)); if (orig_node == NULL) { - spin_unlock_irqrestore(&bat_priv->orig_hash_lock, flags); + spin_unlock_bh(&bat_priv->orig_hash_lock); return NET_RX_DROP; } @@ -1309,7 +1302,7 @@ int recv_bcast_packet(struct sk_buff *skb, struct batman_if *recv_if) if (get_bit_status(orig_node->bcast_bits, orig_node->last_bcast_seqno, ntohl(bcast_packet->seqno))) { - spin_unlock_irqrestore(&bat_priv->orig_hash_lock, flags); + spin_unlock_bh(&bat_priv->orig_hash_lock); return NET_RX_DROP; } @@ -1318,7 +1311,7 @@ int recv_bcast_packet(struct sk_buff *skb, struct batman_if *recv_if) /* check whether the packet is old and the host just restarted. */ if (window_protected(bat_priv, seq_diff, &orig_node->bcast_seqno_reset)) { - spin_unlock_irqrestore(&bat_priv->orig_hash_lock, flags); + spin_unlock_bh(&bat_priv->orig_hash_lock); return NET_RX_DROP; } @@ -1327,7 +1320,7 @@ int recv_bcast_packet(struct sk_buff *skb, struct batman_if *recv_if) if (bit_get_packet(bat_priv, orig_node->bcast_bits, seq_diff, 1)) orig_node->last_bcast_seqno = ntohl(bcast_packet->seqno); - spin_unlock_irqrestore(&bat_priv->orig_hash_lock, flags); + spin_unlock_bh(&bat_priv->orig_hash_lock); /* rebroadcast packet */ add_bcast_packet_to_list(bat_priv, skb); diff --git a/drivers/staging/batman-adv/send.c b/drivers/staging/batman-adv/send.c index 1840ef0e3755..9ed77d7bbca0 100644 --- a/drivers/staging/batman-adv/send.c +++ b/drivers/staging/batman-adv/send.c @@ -367,13 +367,12 @@ static void _add_bcast_packet_to_list(struct bat_priv *bat_priv, struct forw_packet *forw_packet, unsigned long send_time) { - unsigned long flags; INIT_HLIST_NODE(&forw_packet->list); /* add new packet to packet list */ - spin_lock_irqsave(&bat_priv->forw_bcast_list_lock, flags); + spin_lock_bh(&bat_priv->forw_bcast_list_lock); hlist_add_head(&forw_packet->list, &bat_priv->forw_bcast_list); - spin_unlock_irqrestore(&bat_priv->forw_bcast_list_lock, flags); + spin_unlock_bh(&bat_priv->forw_bcast_list_lock); /* start timer for this packet */ INIT_DELAYED_WORK(&forw_packet->delayed_work, @@ -443,14 +442,13 @@ static void send_outstanding_bcast_packet(struct work_struct *work) container_of(work, struct delayed_work, work); struct forw_packet *forw_packet = container_of(delayed_work, struct forw_packet, delayed_work); - unsigned long flags; struct sk_buff *skb1; struct net_device *soft_iface = forw_packet->if_incoming->soft_iface; struct bat_priv *bat_priv = netdev_priv(soft_iface); - spin_lock_irqsave(&bat_priv->forw_bcast_list_lock, flags); + spin_lock_bh(&bat_priv->forw_bcast_list_lock); hlist_del(&forw_packet->list); - spin_unlock_irqrestore(&bat_priv->forw_bcast_list_lock, flags); + spin_unlock_bh(&bat_priv->forw_bcast_list_lock); if (atomic_read(&bat_priv->mesh_state) == MESH_DEACTIVATING) goto out; @@ -488,13 +486,12 @@ void send_outstanding_bat_packet(struct work_struct *work) container_of(work, struct delayed_work, work); struct forw_packet *forw_packet = container_of(delayed_work, struct forw_packet, delayed_work); - unsigned long flags; struct bat_priv *bat_priv; bat_priv = netdev_priv(forw_packet->if_incoming->soft_iface); - spin_lock_irqsave(&bat_priv->forw_bat_list_lock, flags); + spin_lock_bh(&bat_priv->forw_bat_list_lock); hlist_del(&forw_packet->list); - spin_unlock_irqrestore(&bat_priv->forw_bat_list_lock, flags); + spin_unlock_bh(&bat_priv->forw_bat_list_lock); if (atomic_read(&bat_priv->mesh_state) == MESH_DEACTIVATING) goto out; @@ -522,7 +519,6 @@ void purge_outstanding_packets(struct bat_priv *bat_priv, { struct forw_packet *forw_packet; struct hlist_node *tmp_node, *safe_tmp_node; - unsigned long flags; if (batman_if) bat_dbg(DBG_BATMAN, bat_priv, @@ -533,7 +529,7 @@ void purge_outstanding_packets(struct bat_priv *bat_priv, "purge_outstanding_packets()\n"); /* free bcast list */ - spin_lock_irqsave(&bat_priv->forw_bcast_list_lock, flags); + spin_lock_bh(&bat_priv->forw_bcast_list_lock); hlist_for_each_entry_safe(forw_packet, tmp_node, safe_tmp_node, &bat_priv->forw_bcast_list, list) { @@ -545,19 +541,19 @@ void purge_outstanding_packets(struct bat_priv *bat_priv, (forw_packet->if_incoming != batman_if)) continue; - spin_unlock_irqrestore(&bat_priv->forw_bcast_list_lock, flags); + spin_unlock_bh(&bat_priv->forw_bcast_list_lock); /** * send_outstanding_bcast_packet() will lock the list to * delete the item from the list */ cancel_delayed_work_sync(&forw_packet->delayed_work); - spin_lock_irqsave(&bat_priv->forw_bcast_list_lock, flags); + spin_lock_bh(&bat_priv->forw_bcast_list_lock); } - spin_unlock_irqrestore(&bat_priv->forw_bcast_list_lock, flags); + spin_unlock_bh(&bat_priv->forw_bcast_list_lock); /* free batman packet list */ - spin_lock_irqsave(&bat_priv->forw_bat_list_lock, flags); + spin_lock_bh(&bat_priv->forw_bat_list_lock); hlist_for_each_entry_safe(forw_packet, tmp_node, safe_tmp_node, &bat_priv->forw_bat_list, list) { @@ -569,14 +565,14 @@ void purge_outstanding_packets(struct bat_priv *bat_priv, (forw_packet->if_incoming != batman_if)) continue; - spin_unlock_irqrestore(&bat_priv->forw_bat_list_lock, flags); + spin_unlock_bh(&bat_priv->forw_bat_list_lock); /** * send_outstanding_bat_packet() will lock the list to * delete the item from the list */ cancel_delayed_work_sync(&forw_packet->delayed_work); - spin_lock_irqsave(&bat_priv->forw_bat_list_lock, flags); + spin_lock_bh(&bat_priv->forw_bat_list_lock); } - spin_unlock_irqrestore(&bat_priv->forw_bat_list_lock, flags); + spin_unlock_bh(&bat_priv->forw_bat_list_lock); } diff --git a/drivers/staging/batman-adv/soft-interface.c b/drivers/staging/batman-adv/soft-interface.c index 1cf9aa21a408..28ffe34919d3 100644 --- a/drivers/staging/batman-adv/soft-interface.c +++ b/drivers/staging/batman-adv/soft-interface.c @@ -97,9 +97,8 @@ void softif_neigh_purge(struct bat_priv *bat_priv) { struct softif_neigh *softif_neigh, *softif_neigh_tmp; struct hlist_node *node, *node_tmp; - unsigned long flags; - spin_lock_irqsave(&bat_priv->softif_neigh_lock, flags); + spin_lock_bh(&bat_priv->softif_neigh_lock); hlist_for_each_entry_safe(softif_neigh, node, node_tmp, &bat_priv->softif_neigh_list, list) { @@ -125,7 +124,7 @@ void softif_neigh_purge(struct bat_priv *bat_priv) call_rcu(&softif_neigh->rcu, softif_neigh_free_rcu); } - spin_unlock_irqrestore(&bat_priv->softif_neigh_lock, flags); + spin_unlock_bh(&bat_priv->softif_neigh_lock); } static struct softif_neigh *softif_neigh_get(struct bat_priv *bat_priv, @@ -133,7 +132,6 @@ static struct softif_neigh *softif_neigh_get(struct bat_priv *bat_priv, { struct softif_neigh *softif_neigh; struct hlist_node *node; - unsigned long flags; rcu_read_lock(); hlist_for_each_entry_rcu(softif_neigh, node, @@ -158,9 +156,9 @@ static struct softif_neigh *softif_neigh_get(struct bat_priv *bat_priv, kref_init(&softif_neigh->refcount); INIT_HLIST_NODE(&softif_neigh->list); - spin_lock_irqsave(&bat_priv->softif_neigh_lock, flags); + spin_lock_bh(&bat_priv->softif_neigh_lock); hlist_add_head_rcu(&softif_neigh->list, &bat_priv->softif_neigh_list); - spin_unlock_irqrestore(&bat_priv->softif_neigh_lock, flags); + spin_unlock_bh(&bat_priv->softif_neigh_lock); found: kref_get(&softif_neigh->refcount); diff --git a/drivers/staging/batman-adv/translation-table.c b/drivers/staging/batman-adv/translation-table.c index 6639bfb66ab8..4b0a1079347b 100644 --- a/drivers/staging/batman-adv/translation-table.c +++ b/drivers/staging/batman-adv/translation-table.c @@ -59,15 +59,14 @@ void hna_local_add(struct net_device *soft_iface, uint8_t *addr) struct hna_local_entry *hna_local_entry; struct hna_global_entry *hna_global_entry; struct hashtable_t *swaphash; - unsigned long flags; int required_bytes; - spin_lock_irqsave(&bat_priv->hna_lhash_lock, flags); + spin_lock_bh(&bat_priv->hna_lhash_lock); hna_local_entry = ((struct hna_local_entry *)hash_find(bat_priv->hna_local_hash, compare_orig, choose_orig, addr)); - spin_unlock_irqrestore(&bat_priv->hna_lhash_lock, flags); + spin_unlock_bh(&bat_priv->hna_lhash_lock); if (hna_local_entry) { hna_local_entry->last_seen = jiffies; @@ -107,7 +106,7 @@ void hna_local_add(struct net_device *soft_iface, uint8_t *addr) else hna_local_entry->never_purge = 0; - spin_lock_irqsave(&bat_priv->hna_lhash_lock, flags); + spin_lock_bh(&bat_priv->hna_lhash_lock); hash_add(bat_priv->hna_local_hash, compare_orig, choose_orig, hna_local_entry); @@ -125,10 +124,10 @@ void hna_local_add(struct net_device *soft_iface, uint8_t *addr) bat_priv->hna_local_hash = swaphash; } - spin_unlock_irqrestore(&bat_priv->hna_lhash_lock, flags); + spin_unlock_bh(&bat_priv->hna_lhash_lock); /* remove address from global hash if present */ - spin_lock_irqsave(&bat_priv->hna_ghash_lock, flags); + spin_lock_bh(&bat_priv->hna_ghash_lock); hna_global_entry = ((struct hna_global_entry *) hash_find(bat_priv->hna_global_hash, @@ -138,7 +137,7 @@ void hna_local_add(struct net_device *soft_iface, uint8_t *addr) _hna_global_del_orig(bat_priv, hna_global_entry, "local hna received"); - spin_unlock_irqrestore(&bat_priv->hna_ghash_lock, flags); + spin_unlock_bh(&bat_priv->hna_ghash_lock); } int hna_local_fill_buffer(struct bat_priv *bat_priv, @@ -148,9 +147,8 @@ int hna_local_fill_buffer(struct bat_priv *bat_priv, struct element_t *bucket; HASHIT(hashit); int i = 0; - unsigned long flags; - spin_lock_irqsave(&bat_priv->hna_lhash_lock, flags); + spin_lock_bh(&bat_priv->hna_lhash_lock); while (hash_iterate(bat_priv->hna_local_hash, &hashit)) { @@ -168,7 +166,7 @@ int hna_local_fill_buffer(struct bat_priv *bat_priv, if (i == bat_priv->num_local_hna) atomic_set(&bat_priv->hna_local_changed, 0); - spin_unlock_irqrestore(&bat_priv->hna_lhash_lock, flags); + spin_unlock_bh(&bat_priv->hna_lhash_lock); return i; } @@ -180,7 +178,6 @@ int hna_local_seq_print_text(struct seq_file *seq, void *offset) HASHIT(hashit); HASHIT(hashit_count); struct element_t *bucket; - unsigned long flags; size_t buf_size, pos; char *buff; @@ -194,7 +191,7 @@ int hna_local_seq_print_text(struct seq_file *seq, void *offset) "announced via HNA:\n", net_dev->name); - spin_lock_irqsave(&bat_priv->hna_lhash_lock, flags); + spin_lock_bh(&bat_priv->hna_lhash_lock); buf_size = 1; /* Estimate length for: " * xx:xx:xx:xx:xx:xx\n" */ @@ -203,7 +200,7 @@ int hna_local_seq_print_text(struct seq_file *seq, void *offset) buff = kmalloc(buf_size, GFP_ATOMIC); if (!buff) { - spin_unlock_irqrestore(&bat_priv->hna_lhash_lock, flags); + spin_unlock_bh(&bat_priv->hna_lhash_lock); return -ENOMEM; } buff[0] = '\0'; @@ -217,7 +214,7 @@ int hna_local_seq_print_text(struct seq_file *seq, void *offset) hna_local_entry->addr); } - spin_unlock_irqrestore(&bat_priv->hna_lhash_lock, flags); + spin_unlock_bh(&bat_priv->hna_lhash_lock); seq_printf(seq, "%s", buff); kfree(buff); @@ -249,9 +246,8 @@ void hna_local_remove(struct bat_priv *bat_priv, uint8_t *addr, char *message) { struct hna_local_entry *hna_local_entry; - unsigned long flags; - spin_lock_irqsave(&bat_priv->hna_lhash_lock, flags); + spin_lock_bh(&bat_priv->hna_lhash_lock); hna_local_entry = (struct hna_local_entry *) hash_find(bat_priv->hna_local_hash, compare_orig, choose_orig, @@ -259,7 +255,7 @@ void hna_local_remove(struct bat_priv *bat_priv, if (hna_local_entry) hna_local_del(bat_priv, hna_local_entry, message); - spin_unlock_irqrestore(&bat_priv->hna_lhash_lock, flags); + spin_unlock_bh(&bat_priv->hna_lhash_lock); } static void hna_local_purge(struct work_struct *work) @@ -271,10 +267,9 @@ static void hna_local_purge(struct work_struct *work) struct hna_local_entry *hna_local_entry; HASHIT(hashit); struct element_t *bucket; - unsigned long flags; unsigned long timeout; - spin_lock_irqsave(&bat_priv->hna_lhash_lock, flags); + spin_lock_bh(&bat_priv->hna_lhash_lock); while (hash_iterate(bat_priv->hna_local_hash, &hashit)) { bucket = hlist_entry(hashit.walk, struct element_t, hlist); @@ -288,7 +283,7 @@ static void hna_local_purge(struct work_struct *work) "address timed out"); } - spin_unlock_irqrestore(&bat_priv->hna_lhash_lock, flags); + spin_unlock_bh(&bat_priv->hna_lhash_lock); hna_local_start_timer(bat_priv); } @@ -323,11 +318,10 @@ void hna_global_add_orig(struct bat_priv *bat_priv, struct hna_local_entry *hna_local_entry; struct hashtable_t *swaphash; int hna_buff_count = 0; - unsigned long flags; unsigned char *hna_ptr; while ((hna_buff_count + 1) * ETH_ALEN <= hna_buff_len) { - spin_lock_irqsave(&bat_priv->hna_ghash_lock, flags); + spin_lock_bh(&bat_priv->hna_ghash_lock); hna_ptr = hna_buff + (hna_buff_count * ETH_ALEN); hna_global_entry = (struct hna_global_entry *) @@ -335,8 +329,7 @@ void hna_global_add_orig(struct bat_priv *bat_priv, choose_orig, hna_ptr); if (!hna_global_entry) { - spin_unlock_irqrestore(&bat_priv->hna_ghash_lock, - flags); + spin_unlock_bh(&bat_priv->hna_ghash_lock); hna_global_entry = kmalloc(sizeof(struct hna_global_entry), @@ -352,17 +345,17 @@ void hna_global_add_orig(struct bat_priv *bat_priv, "%pM (via %pM)\n", hna_global_entry->addr, orig_node->orig); - spin_lock_irqsave(&bat_priv->hna_ghash_lock, flags); + spin_lock_bh(&bat_priv->hna_ghash_lock); hash_add(bat_priv->hna_global_hash, compare_orig, choose_orig, hna_global_entry); } hna_global_entry->orig_node = orig_node; - spin_unlock_irqrestore(&bat_priv->hna_ghash_lock, flags); + spin_unlock_bh(&bat_priv->hna_ghash_lock); /* remove address from local hash if present */ - spin_lock_irqsave(&bat_priv->hna_lhash_lock, flags); + spin_lock_bh(&bat_priv->hna_lhash_lock); hna_ptr = hna_buff + (hna_buff_count * ETH_ALEN); hna_local_entry = (struct hna_local_entry *) @@ -373,7 +366,7 @@ void hna_global_add_orig(struct bat_priv *bat_priv, hna_local_del(bat_priv, hna_local_entry, "global hna received"); - spin_unlock_irqrestore(&bat_priv->hna_lhash_lock, flags); + spin_unlock_bh(&bat_priv->hna_lhash_lock); hna_buff_count++; } @@ -390,7 +383,7 @@ void hna_global_add_orig(struct bat_priv *bat_priv, } } - spin_lock_irqsave(&bat_priv->hna_ghash_lock, flags); + spin_lock_bh(&bat_priv->hna_ghash_lock); if (bat_priv->hna_global_hash->elements * 4 > bat_priv->hna_global_hash->size) { @@ -403,7 +396,7 @@ void hna_global_add_orig(struct bat_priv *bat_priv, bat_priv->hna_global_hash = swaphash; } - spin_unlock_irqrestore(&bat_priv->hna_ghash_lock, flags); + spin_unlock_bh(&bat_priv->hna_ghash_lock); } int hna_global_seq_print_text(struct seq_file *seq, void *offset) @@ -414,7 +407,6 @@ int hna_global_seq_print_text(struct seq_file *seq, void *offset) HASHIT(hashit); HASHIT(hashit_count); struct element_t *bucket; - unsigned long flags; size_t buf_size, pos; char *buff; @@ -427,7 +419,7 @@ int hna_global_seq_print_text(struct seq_file *seq, void *offset) seq_printf(seq, "Globally announced HNAs received via the mesh %s\n", net_dev->name); - spin_lock_irqsave(&bat_priv->hna_ghash_lock, flags); + spin_lock_bh(&bat_priv->hna_ghash_lock); buf_size = 1; /* Estimate length for: " * xx:xx:xx:xx:xx:xx via xx:xx:xx:xx:xx:xx\n"*/ @@ -436,7 +428,7 @@ int hna_global_seq_print_text(struct seq_file *seq, void *offset) buff = kmalloc(buf_size, GFP_ATOMIC); if (!buff) { - spin_unlock_irqrestore(&bat_priv->hna_ghash_lock, flags); + spin_unlock_bh(&bat_priv->hna_ghash_lock); return -ENOMEM; } buff[0] = '\0'; @@ -451,7 +443,7 @@ int hna_global_seq_print_text(struct seq_file *seq, void *offset) hna_global_entry->orig_node->orig); } - spin_unlock_irqrestore(&bat_priv->hna_ghash_lock, flags); + spin_unlock_bh(&bat_priv->hna_ghash_lock); seq_printf(seq, "%s", buff); kfree(buff); @@ -477,13 +469,12 @@ void hna_global_del_orig(struct bat_priv *bat_priv, { struct hna_global_entry *hna_global_entry; int hna_buff_count = 0; - unsigned long flags; unsigned char *hna_ptr; if (orig_node->hna_buff_len == 0) return; - spin_lock_irqsave(&bat_priv->hna_ghash_lock, flags); + spin_lock_bh(&bat_priv->hna_ghash_lock); while ((hna_buff_count + 1) * ETH_ALEN <= orig_node->hna_buff_len) { hna_ptr = orig_node->hna_buff + (hna_buff_count * ETH_ALEN); @@ -499,7 +490,7 @@ void hna_global_del_orig(struct bat_priv *bat_priv, hna_buff_count++; } - spin_unlock_irqrestore(&bat_priv->hna_ghash_lock, flags); + spin_unlock_bh(&bat_priv->hna_ghash_lock); orig_node->hna_buff_len = 0; kfree(orig_node->hna_buff); @@ -523,13 +514,12 @@ void hna_global_free(struct bat_priv *bat_priv) struct orig_node *transtable_search(struct bat_priv *bat_priv, uint8_t *addr) { struct hna_global_entry *hna_global_entry; - unsigned long flags; - spin_lock_irqsave(&bat_priv->hna_ghash_lock, flags); + spin_lock_bh(&bat_priv->hna_ghash_lock); hna_global_entry = (struct hna_global_entry *) hash_find(bat_priv->hna_global_hash, compare_orig, choose_orig, addr); - spin_unlock_irqrestore(&bat_priv->hna_ghash_lock, flags); + spin_unlock_bh(&bat_priv->hna_ghash_lock); if (!hna_global_entry) return NULL; diff --git a/drivers/staging/batman-adv/unicast.c b/drivers/staging/batman-adv/unicast.c index 132875047835..3b62d998a2f1 100644 --- a/drivers/staging/batman-adv/unicast.c +++ b/drivers/staging/batman-adv/unicast.c @@ -170,7 +170,6 @@ void frag_list_free(struct list_head *head) int frag_reassemble_skb(struct sk_buff *skb, struct bat_priv *bat_priv, struct sk_buff **new_skb) { - unsigned long flags; struct orig_node *orig_node; struct frag_packet_list_entry *tmp_frag_entry; int ret = NET_RX_DROP; @@ -178,7 +177,7 @@ int frag_reassemble_skb(struct sk_buff *skb, struct bat_priv *bat_priv, (struct unicast_frag_packet *)skb->data; *new_skb = NULL; - spin_lock_irqsave(&bat_priv->orig_hash_lock, flags); + spin_lock_bh(&bat_priv->orig_hash_lock); orig_node = ((struct orig_node *) hash_find(bat_priv->orig_hash, compare_orig, choose_orig, unicast_packet->orig)); @@ -211,7 +210,7 @@ int frag_reassemble_skb(struct sk_buff *skb, struct bat_priv *bat_priv, if (*new_skb) ret = NET_RX_SUCCESS; out: - spin_unlock_irqrestore(&bat_priv->orig_hash_lock, flags); + spin_unlock_bh(&bat_priv->orig_hash_lock); return ret; } @@ -279,9 +278,8 @@ int unicast_send_skb(struct sk_buff *skb, struct bat_priv *bat_priv) struct neigh_node *router; int data_len = skb->len; uint8_t dstaddr[6]; - unsigned long flags; - spin_lock_irqsave(&bat_priv->orig_hash_lock, flags); + spin_lock_bh(&bat_priv->orig_hash_lock); /* get routing information */ orig_node = ((struct orig_node *)hash_find(bat_priv->orig_hash, @@ -304,7 +302,7 @@ int unicast_send_skb(struct sk_buff *skb, struct bat_priv *bat_priv) batman_if = router->if_incoming; memcpy(dstaddr, router->addr, ETH_ALEN); - spin_unlock_irqrestore(&bat_priv->orig_hash_lock, flags); + spin_unlock_bh(&bat_priv->orig_hash_lock); if (batman_if->if_status != IF_ACTIVE) goto dropped; @@ -334,7 +332,7 @@ int unicast_send_skb(struct sk_buff *skb, struct bat_priv *bat_priv) return 0; unlock: - spin_unlock_irqrestore(&bat_priv->orig_hash_lock, flags); + spin_unlock_bh(&bat_priv->orig_hash_lock); dropped: kfree_skb(skb); return 1; diff --git a/drivers/staging/batman-adv/vis.c b/drivers/staging/batman-adv/vis.c index e2031c9aab9d..65676dcd40ed 100644 --- a/drivers/staging/batman-adv/vis.c +++ b/drivers/staging/batman-adv/vis.c @@ -54,16 +54,15 @@ static void free_info(struct kref *ref) struct vis_info *info = container_of(ref, struct vis_info, refcount); struct bat_priv *bat_priv = info->bat_priv; struct recvlist_node *entry, *tmp; - unsigned long flags; list_del_init(&info->send_list); - spin_lock_irqsave(&bat_priv->vis_list_lock, flags); + spin_lock_bh(&bat_priv->vis_list_lock); list_for_each_entry_safe(entry, tmp, &info->recv_list, list) { list_del(&entry->list); kfree(entry); } - spin_unlock_irqrestore(&bat_priv->vis_list_lock, flags); + spin_unlock_bh(&bat_priv->vis_list_lock); kfree_skb(info->skb_packet); } @@ -187,7 +186,6 @@ int vis_seq_print_text(struct seq_file *seq, void *offset) struct if_list_entry *entry; struct hlist_node *pos, *n; int i; - unsigned long flags; int vis_server = atomic_read(&bat_priv->vis_mode); size_t buff_pos, buf_size; char *buff; @@ -198,7 +196,7 @@ int vis_seq_print_text(struct seq_file *seq, void *offset) buf_size = 1; /* Estimate length */ - spin_lock_irqsave(&bat_priv->vis_hash_lock, flags); + spin_lock_bh(&bat_priv->vis_hash_lock); while (hash_iterate(bat_priv->vis_hash, &hashit_count)) { bucket = hlist_entry(hashit_count.walk, struct element_t, hlist); @@ -233,7 +231,7 @@ int vis_seq_print_text(struct seq_file *seq, void *offset) buff = kmalloc(buf_size, GFP_ATOMIC); if (!buff) { - spin_unlock_irqrestore(&bat_priv->vis_hash_lock, flags); + spin_unlock_bh(&bat_priv->vis_hash_lock); return -ENOMEM; } buff[0] = '\0'; @@ -278,7 +276,7 @@ int vis_seq_print_text(struct seq_file *seq, void *offset) } } - spin_unlock_irqrestore(&bat_priv->vis_hash_lock, flags); + spin_unlock_bh(&bat_priv->vis_hash_lock); seq_printf(seq, "%s", buff); kfree(buff); @@ -311,16 +309,15 @@ static void recv_list_add(struct bat_priv *bat_priv, struct list_head *recv_list, char *mac) { struct recvlist_node *entry; - unsigned long flags; entry = kmalloc(sizeof(struct recvlist_node), GFP_ATOMIC); if (!entry) return; memcpy(entry->mac, mac, ETH_ALEN); - spin_lock_irqsave(&bat_priv->vis_list_lock, flags); + spin_lock_bh(&bat_priv->vis_list_lock); list_add_tail(&entry->list, recv_list); - spin_unlock_irqrestore(&bat_priv->vis_list_lock, flags); + spin_unlock_bh(&bat_priv->vis_list_lock); } /* returns 1 if this mac is in the recv_list */ @@ -328,17 +325,15 @@ static int recv_list_is_in(struct bat_priv *bat_priv, struct list_head *recv_list, char *mac) { struct recvlist_node *entry; - unsigned long flags; - spin_lock_irqsave(&bat_priv->vis_list_lock, flags); + spin_lock_bh(&bat_priv->vis_list_lock); list_for_each_entry(entry, recv_list, list) { if (memcmp(entry->mac, mac, ETH_ALEN) == 0) { - spin_unlock_irqrestore(&bat_priv->vis_list_lock, - flags); + spin_unlock_bh(&bat_priv->vis_list_lock); return 1; } } - spin_unlock_irqrestore(&bat_priv->vis_list_lock, flags); + spin_unlock_bh(&bat_priv->vis_list_lock); return 0; } @@ -447,12 +442,11 @@ void receive_server_sync_packet(struct bat_priv *bat_priv, { struct vis_info *info; int is_new, make_broadcast; - unsigned long flags; int vis_server = atomic_read(&bat_priv->vis_mode); make_broadcast = (vis_server == VIS_TYPE_SERVER_SYNC); - spin_lock_irqsave(&bat_priv->vis_hash_lock, flags); + spin_lock_bh(&bat_priv->vis_hash_lock); info = add_packet(bat_priv, vis_packet, vis_info_len, &is_new, make_broadcast); if (!info) @@ -463,7 +457,7 @@ void receive_server_sync_packet(struct bat_priv *bat_priv, if (vis_server == VIS_TYPE_SERVER_SYNC && is_new) send_list_add(bat_priv, info); end: - spin_unlock_irqrestore(&bat_priv->vis_hash_lock, flags); + spin_unlock_bh(&bat_priv->vis_hash_lock); } /* handle an incoming client update packet and schedule forward if needed. */ @@ -474,7 +468,6 @@ void receive_client_update_packet(struct bat_priv *bat_priv, struct vis_info *info; struct vis_packet *packet; int is_new; - unsigned long flags; int vis_server = atomic_read(&bat_priv->vis_mode); int are_target = 0; @@ -487,7 +480,7 @@ void receive_client_update_packet(struct bat_priv *bat_priv, is_my_mac(vis_packet->target_orig)) are_target = 1; - spin_lock_irqsave(&bat_priv->vis_hash_lock, flags); + spin_lock_bh(&bat_priv->vis_hash_lock); info = add_packet(bat_priv, vis_packet, vis_info_len, &is_new, are_target); @@ -508,7 +501,7 @@ void receive_client_update_packet(struct bat_priv *bat_priv, } end: - spin_unlock_irqrestore(&bat_priv->vis_hash_lock, flags); + spin_unlock_bh(&bat_priv->vis_hash_lock); } /* Walk the originators and find the VIS server with the best tq. Set the packet @@ -564,12 +557,11 @@ static int generate_vis_packet(struct bat_priv *bat_priv) struct vis_info_entry *entry; struct hna_local_entry *hna_local_entry; int best_tq = -1; - unsigned long flags; info->first_seen = jiffies; packet->vis_type = atomic_read(&bat_priv->vis_mode); - spin_lock_irqsave(&bat_priv->orig_hash_lock, flags); + spin_lock_bh(&bat_priv->orig_hash_lock); memcpy(packet->target_orig, broadcast_addr, ETH_ALEN); packet->ttl = TTL; packet->seqno = htonl(ntohl(packet->seqno) + 1); @@ -580,8 +572,7 @@ static int generate_vis_packet(struct bat_priv *bat_priv) best_tq = find_best_vis_server(bat_priv, info); if (best_tq < 0) { - spin_unlock_irqrestore(&bat_priv->orig_hash_lock, - flags); + spin_unlock_bh(&bat_priv->orig_hash_lock); return -1; } } @@ -614,15 +605,14 @@ static int generate_vis_packet(struct bat_priv *bat_priv) packet->entries++; if (vis_packet_full(info)) { - spin_unlock_irqrestore( - &bat_priv->orig_hash_lock, flags); + spin_unlock_bh(&bat_priv->orig_hash_lock); return 0; } } - spin_unlock_irqrestore(&bat_priv->orig_hash_lock, flags); + spin_unlock_bh(&bat_priv->orig_hash_lock); - spin_lock_irqsave(&bat_priv->hna_lhash_lock, flags); + spin_lock_bh(&bat_priv->hna_lhash_lock); while (hash_iterate(bat_priv->hna_local_hash, &hashit_local)) { bucket = hlist_entry(hashit_local.walk, struct element_t, hlist); @@ -635,13 +625,12 @@ static int generate_vis_packet(struct bat_priv *bat_priv) packet->entries++; if (vis_packet_full(info)) { - spin_unlock_irqrestore(&bat_priv->hna_lhash_lock, - flags); + spin_unlock_bh(&bat_priv->hna_lhash_lock); return 0; } } - spin_unlock_irqrestore(&bat_priv->hna_lhash_lock, flags); + spin_unlock_bh(&bat_priv->hna_lhash_lock); return 0; } @@ -678,12 +667,11 @@ static void broadcast_vis_packet(struct bat_priv *bat_priv, struct orig_node *orig_node; struct vis_packet *packet; struct sk_buff *skb; - unsigned long flags; struct batman_if *batman_if; uint8_t dstaddr[ETH_ALEN]; - spin_lock_irqsave(&bat_priv->orig_hash_lock, flags); + spin_lock_bh(&bat_priv->orig_hash_lock); packet = (struct vis_packet *)info->skb_packet->data; /* send to all routers in range. */ @@ -705,17 +693,17 @@ static void broadcast_vis_packet(struct bat_priv *bat_priv, memcpy(packet->target_orig, orig_node->orig, ETH_ALEN); batman_if = orig_node->router->if_incoming; memcpy(dstaddr, orig_node->router->addr, ETH_ALEN); - spin_unlock_irqrestore(&bat_priv->orig_hash_lock, flags); + spin_unlock_bh(&bat_priv->orig_hash_lock); skb = skb_clone(info->skb_packet, GFP_ATOMIC); if (skb) send_skb_packet(skb, batman_if, dstaddr); - spin_lock_irqsave(&bat_priv->orig_hash_lock, flags); + spin_lock_bh(&bat_priv->orig_hash_lock); } - spin_unlock_irqrestore(&bat_priv->orig_hash_lock, flags); + spin_unlock_bh(&bat_priv->orig_hash_lock); } static void unicast_vis_packet(struct bat_priv *bat_priv, @@ -724,11 +712,10 @@ static void unicast_vis_packet(struct bat_priv *bat_priv, struct orig_node *orig_node; struct sk_buff *skb; struct vis_packet *packet; - unsigned long flags; struct batman_if *batman_if; uint8_t dstaddr[ETH_ALEN]; - spin_lock_irqsave(&bat_priv->orig_hash_lock, flags); + spin_lock_bh(&bat_priv->orig_hash_lock); packet = (struct vis_packet *)info->skb_packet->data; orig_node = ((struct orig_node *)hash_find(bat_priv->orig_hash, compare_orig, choose_orig, @@ -741,7 +728,7 @@ static void unicast_vis_packet(struct bat_priv *bat_priv, * copy the required data before sending */ batman_if = orig_node->router->if_incoming; memcpy(dstaddr, orig_node->router->addr, ETH_ALEN); - spin_unlock_irqrestore(&bat_priv->orig_hash_lock, flags); + spin_unlock_bh(&bat_priv->orig_hash_lock); skb = skb_clone(info->skb_packet, GFP_ATOMIC); if (skb) @@ -750,7 +737,7 @@ static void unicast_vis_packet(struct bat_priv *bat_priv, return; out: - spin_unlock_irqrestore(&bat_priv->orig_hash_lock, flags); + spin_unlock_bh(&bat_priv->orig_hash_lock); } /* only send one vis packet. called from send_vis_packets() */ @@ -783,9 +770,8 @@ static void send_vis_packets(struct work_struct *work) struct bat_priv *bat_priv = container_of(delayed_work, struct bat_priv, vis_work); struct vis_info *info, *temp; - unsigned long flags; - spin_lock_irqsave(&bat_priv->vis_hash_lock, flags); + spin_lock_bh(&bat_priv->vis_hash_lock); purge_vis_packets(bat_priv); if (generate_vis_packet(bat_priv) == 0) { @@ -797,16 +783,16 @@ static void send_vis_packets(struct work_struct *work) send_list) { kref_get(&info->refcount); - spin_unlock_irqrestore(&bat_priv->vis_hash_lock, flags); + spin_unlock_bh(&bat_priv->vis_hash_lock); if (bat_priv->primary_if) send_vis_packet(bat_priv, info); - spin_lock_irqsave(&bat_priv->vis_hash_lock, flags); + spin_lock_bh(&bat_priv->vis_hash_lock); send_list_del(info); kref_put(&info->refcount, free_info); } - spin_unlock_irqrestore(&bat_priv->vis_hash_lock, flags); + spin_unlock_bh(&bat_priv->vis_hash_lock); start_vis_timer(bat_priv); } @@ -815,13 +801,12 @@ static void send_vis_packets(struct work_struct *work) int vis_init(struct bat_priv *bat_priv) { struct vis_packet *packet; - unsigned long flags; int hash_added; if (bat_priv->vis_hash) return 1; - spin_lock_irqsave(&bat_priv->vis_hash_lock, flags); + spin_lock_bh(&bat_priv->vis_hash_lock); bat_priv->vis_hash = hash_new(256); if (!bat_priv->vis_hash) { @@ -871,7 +856,7 @@ int vis_init(struct bat_priv *bat_priv) goto err; } - spin_unlock_irqrestore(&bat_priv->vis_hash_lock, flags); + spin_unlock_bh(&bat_priv->vis_hash_lock); start_vis_timer(bat_priv); return 1; @@ -879,7 +864,7 @@ free_info: kfree(bat_priv->my_vis_info); bat_priv->my_vis_info = NULL; err: - spin_unlock_irqrestore(&bat_priv->vis_hash_lock, flags); + spin_unlock_bh(&bat_priv->vis_hash_lock); vis_quit(bat_priv); return 0; } @@ -896,18 +881,17 @@ static void free_info_ref(void *data, void *arg) /* shutdown vis-server */ void vis_quit(struct bat_priv *bat_priv) { - unsigned long flags; if (!bat_priv->vis_hash) return; cancel_delayed_work_sync(&bat_priv->vis_work); - spin_lock_irqsave(&bat_priv->vis_hash_lock, flags); + spin_lock_bh(&bat_priv->vis_hash_lock); /* properly remove, kill timers ... */ hash_delete(bat_priv->vis_hash, free_info_ref, NULL); bat_priv->vis_hash = NULL; bat_priv->my_vis_info = NULL; - spin_unlock_irqrestore(&bat_priv->vis_hash_lock, flags); + spin_unlock_bh(&bat_priv->vis_hash_lock); } /* schedule packets for (re)transmission */ -- cgit v1.2.3 From dfaf9dd3459cac02411cebf418e8469aa0d8ca5d Mon Sep 17 00:00:00 2001 From: Marek Lindner Date: Mon, 22 Nov 2010 00:56:02 +0100 Subject: Staging: batman-adv: adding gateway functionality Via the /sys filesystem you can change the gateway mode of a node using gw_mode. Adjustments to it can be done using gw_bandwidth for server mode and gw_sel_class for client mode. Signed-off-by: Marek Lindner [sven.eckelmann@gmx.de: Rework on top of current version] Signed-off-by: Sven Eckelmann Signed-off-by: Greg Kroah-Hartman --- drivers/staging/batman-adv/Makefile | 19 +- drivers/staging/batman-adv/bat_debugfs.c | 10 + drivers/staging/batman-adv/bat_sysfs.c | 115 +++++++ drivers/staging/batman-adv/gateway_client.c | 387 ++++++++++++++++++++++++ drivers/staging/batman-adv/gateway_client.h | 35 +++ drivers/staging/batman-adv/gateway_common.c | 177 +++++++++++ drivers/staging/batman-adv/gateway_common.h | 38 +++ drivers/staging/batman-adv/main.c | 4 + drivers/staging/batman-adv/originator.c | 6 + drivers/staging/batman-adv/packet.h | 4 +- drivers/staging/batman-adv/routing.c | 16 +- drivers/staging/batman-adv/send.c | 8 + drivers/staging/batman-adv/soft-interface.c | 4 + drivers/staging/batman-adv/sysfs-class-net-mesh | 21 ++ drivers/staging/batman-adv/types.h | 18 +- 15 files changed, 858 insertions(+), 4 deletions(-) create mode 100644 drivers/staging/batman-adv/gateway_client.c create mode 100644 drivers/staging/batman-adv/gateway_client.h create mode 100644 drivers/staging/batman-adv/gateway_common.c create mode 100644 drivers/staging/batman-adv/gateway_common.h diff --git a/drivers/staging/batman-adv/Makefile b/drivers/staging/batman-adv/Makefile index 78924283ea74..d936aeccd194 100644 --- a/drivers/staging/batman-adv/Makefile +++ b/drivers/staging/batman-adv/Makefile @@ -19,4 +19,21 @@ # obj-$(CONFIG_BATMAN_ADV) += batman-adv.o -batman-adv-y := main.o bat_debugfs.o bat_sysfs.o send.o routing.o soft-interface.o icmp_socket.o translation-table.o bitarray.o hash.o ring_buffer.o vis.o hard-interface.o aggregation.o originator.o unicast.o +batman-adv-y += aggregation.o +batman-adv-y += bat_debugfs.o +batman-adv-y += bat_sysfs.o +batman-adv-y += bitarray.o +batman-adv-y += gateway_client.o +batman-adv-y += gateway_common.o +batman-adv-y += hard-interface.o +batman-adv-y += hash.o +batman-adv-y += icmp_socket.o +batman-adv-y += main.o +batman-adv-y += originator.o +batman-adv-y += ring_buffer.o +batman-adv-y += routing.o +batman-adv-y += send.o +batman-adv-y += soft-interface.o +batman-adv-y += translation-table.o +batman-adv-y += unicast.o +batman-adv-y += vis.o diff --git a/drivers/staging/batman-adv/bat_debugfs.c b/drivers/staging/batman-adv/bat_debugfs.c index cbac1a53ad74..0ae81d07f102 100644 --- a/drivers/staging/batman-adv/bat_debugfs.c +++ b/drivers/staging/batman-adv/bat_debugfs.c @@ -27,6 +27,8 @@ #include "translation-table.h" #include "originator.h" #include "hard-interface.h" +#include "gateway_common.h" +#include "gateway_client.h" #include "soft-interface.h" #include "vis.h" #include "icmp_socket.h" @@ -226,6 +228,12 @@ static int originators_open(struct inode *inode, struct file *file) return single_open(file, orig_seq_print_text, net_dev); } +static int gateways_open(struct inode *inode, struct file *file) +{ + struct net_device *net_dev = (struct net_device *)inode->i_private; + return single_open(file, gw_client_seq_print_text, net_dev); +} + static int softif_neigh_open(struct inode *inode, struct file *file) { struct net_device *net_dev = (struct net_device *)inode->i_private; @@ -268,6 +276,7 @@ struct bat_debuginfo bat_debuginfo_##_name = { \ }; static BAT_DEBUGINFO(originators, S_IRUGO, originators_open); +static BAT_DEBUGINFO(gateways, S_IRUGO, gateways_open); static BAT_DEBUGINFO(softif_neigh, S_IRUGO, softif_neigh_open); static BAT_DEBUGINFO(transtable_global, S_IRUGO, transtable_global_open); static BAT_DEBUGINFO(transtable_local, S_IRUGO, transtable_local_open); @@ -275,6 +284,7 @@ static BAT_DEBUGINFO(vis_data, S_IRUGO, vis_data_open); static struct bat_debuginfo *mesh_debuginfos[] = { &bat_debuginfo_originators, + &bat_debuginfo_gateways, &bat_debuginfo_softif_neigh, &bat_debuginfo_transtable_global, &bat_debuginfo_transtable_local, diff --git a/drivers/staging/batman-adv/bat_sysfs.c b/drivers/staging/batman-adv/bat_sysfs.c index 5ff6e5e6a1e2..cd7bb51825f1 100644 --- a/drivers/staging/batman-adv/bat_sysfs.c +++ b/drivers/staging/batman-adv/bat_sysfs.c @@ -24,6 +24,8 @@ #include "translation-table.h" #include "originator.h" #include "hard-interface.h" +#include "gateway_common.h" +#include "gateway_client.h" #include "vis.h" #define to_dev(obj) container_of(obj, struct device, kobj) @@ -249,12 +251,122 @@ static ssize_t store_vis_mode(struct kobject *kobj, struct attribute *attr, return count; } +static void post_gw_deselect(struct net_device *net_dev) +{ + struct bat_priv *bat_priv = netdev_priv(net_dev); + gw_deselect(bat_priv); +} + +static ssize_t show_gw_mode(struct kobject *kobj, struct attribute *attr, + char *buff) +{ + struct bat_priv *bat_priv = kobj_to_batpriv(kobj); + int bytes_written; + + switch (atomic_read(&bat_priv->gw_mode)) { + case GW_MODE_CLIENT: + bytes_written = sprintf(buff, "%s\n", GW_MODE_CLIENT_NAME); + break; + case GW_MODE_SERVER: + bytes_written = sprintf(buff, "%s\n", GW_MODE_SERVER_NAME); + break; + default: + bytes_written = sprintf(buff, "%s\n", GW_MODE_OFF_NAME); + break; + } + + return bytes_written; +} + +static ssize_t store_gw_mode(struct kobject *kobj, struct attribute *attr, + char *buff, size_t count) +{ + struct net_device *net_dev = kobj_to_netdev(kobj); + struct bat_priv *bat_priv = netdev_priv(net_dev); + char *curr_gw_mode_str; + int gw_mode_tmp = -1; + + if (buff[count - 1] == '\n') + buff[count - 1] = '\0'; + + if (strncmp(buff, GW_MODE_OFF_NAME, strlen(GW_MODE_OFF_NAME)) == 0) + gw_mode_tmp = GW_MODE_OFF; + + if (strncmp(buff, GW_MODE_CLIENT_NAME, + strlen(GW_MODE_CLIENT_NAME)) == 0) + gw_mode_tmp = GW_MODE_CLIENT; + + if (strncmp(buff, GW_MODE_SERVER_NAME, + strlen(GW_MODE_SERVER_NAME)) == 0) + gw_mode_tmp = GW_MODE_SERVER; + + if (gw_mode_tmp < 0) { + bat_info(net_dev, + "Invalid parameter for 'gw mode' setting received: " + "%s\n", buff); + return -EINVAL; + } + + if (atomic_read(&bat_priv->gw_mode) == gw_mode_tmp) + return count; + + switch (atomic_read(&bat_priv->gw_mode)) { + case GW_MODE_CLIENT: + curr_gw_mode_str = GW_MODE_CLIENT_NAME; + break; + case GW_MODE_SERVER: + curr_gw_mode_str = GW_MODE_SERVER_NAME; + break; + default: + curr_gw_mode_str = GW_MODE_OFF_NAME; + break; + } + + bat_info(net_dev, "Changing gw mode from: %s to: %s\n", + curr_gw_mode_str, buff); + + gw_deselect(bat_priv); + atomic_set(&bat_priv->gw_mode, (unsigned)gw_mode_tmp); + return count; +} + +static ssize_t show_gw_bwidth(struct kobject *kobj, struct attribute *attr, + char *buff) +{ + struct bat_priv *bat_priv = kobj_to_batpriv(kobj); + int down, up; + int gw_bandwidth = atomic_read(&bat_priv->gw_bandwidth); + + gw_bandwidth_to_kbit(gw_bandwidth, &down, &up); + return sprintf(buff, "%i%s/%i%s\n", + (down > 2048 ? down / 1024 : down), + (down > 2048 ? "MBit" : "KBit"), + (up > 2048 ? up / 1024 : up), + (up > 2048 ? "MBit" : "KBit")); +} + +static ssize_t store_gw_bwidth(struct kobject *kobj, struct attribute *attr, + char *buff, size_t count) +{ + struct net_device *net_dev = kobj_to_netdev(kobj); + + if (buff[count - 1] == '\n') + buff[count - 1] = '\0'; + + return gw_bandwidth_set(net_dev, buff, count); +} + BAT_ATTR_BOOL(aggregated_ogms, S_IRUGO | S_IWUSR, NULL); BAT_ATTR_BOOL(bonding, S_IRUGO | S_IWUSR, NULL); BAT_ATTR_BOOL(fragmentation, S_IRUGO | S_IWUSR, update_min_mtu); static BAT_ATTR(vis_mode, S_IRUGO | S_IWUSR, show_vis_mode, store_vis_mode); +static BAT_ATTR(gw_mode, S_IRUGO | S_IWUSR, show_gw_mode, store_gw_mode); BAT_ATTR_UINT(orig_interval, S_IRUGO | S_IWUSR, 2 * JITTER, INT_MAX, NULL); BAT_ATTR_UINT(hop_penalty, S_IRUGO | S_IWUSR, 0, TQ_MAX_VALUE, NULL); +BAT_ATTR_UINT(gw_sel_class, S_IRUGO | S_IWUSR, 1, TQ_MAX_VALUE, + post_gw_deselect); +static BAT_ATTR(gw_bandwidth, S_IRUGO | S_IWUSR, show_gw_bwidth, + store_gw_bwidth); #ifdef CONFIG_BATMAN_ADV_DEBUG BAT_ATTR_UINT(log_level, S_IRUGO | S_IWUSR, 0, 3, NULL); #endif @@ -264,8 +376,11 @@ static struct bat_attribute *mesh_attrs[] = { &bat_attr_bonding, &bat_attr_fragmentation, &bat_attr_vis_mode, + &bat_attr_gw_mode, &bat_attr_orig_interval, &bat_attr_hop_penalty, + &bat_attr_gw_sel_class, + &bat_attr_gw_bandwidth, #ifdef CONFIG_BATMAN_ADV_DEBUG &bat_attr_log_level, #endif diff --git a/drivers/staging/batman-adv/gateway_client.c b/drivers/staging/batman-adv/gateway_client.c new file mode 100644 index 000000000000..1846a6219631 --- /dev/null +++ b/drivers/staging/batman-adv/gateway_client.c @@ -0,0 +1,387 @@ +/* + * Copyright (C) 2009-2010 B.A.T.M.A.N. contributors: + * + * Marek Lindner + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA + * + */ + +#include "main.h" +#include "gateway_client.h" +#include "gateway_common.h" +#include "hard-interface.h" + +static void gw_node_free_ref(struct kref *refcount) +{ + struct gw_node *gw_node; + + gw_node = container_of(refcount, struct gw_node, refcount); + kfree(gw_node); +} + +static void gw_node_free_rcu(struct rcu_head *rcu) +{ + struct gw_node *gw_node; + + gw_node = container_of(rcu, struct gw_node, rcu); + kref_put(&gw_node->refcount, gw_node_free_ref); +} + +void gw_deselect(struct bat_priv *bat_priv) +{ + struct gw_node *gw_node = bat_priv->curr_gw; + + bat_priv->curr_gw = NULL; + + if (gw_node) + kref_put(&gw_node->refcount, gw_node_free_ref); +} + +static struct gw_node *gw_select(struct bat_priv *bat_priv, + struct gw_node *new_gw_node) +{ + struct gw_node *curr_gw_node = bat_priv->curr_gw; + + if (new_gw_node) + kref_get(&new_gw_node->refcount); + + bat_priv->curr_gw = new_gw_node; + return curr_gw_node; +} + +void gw_election(struct bat_priv *bat_priv) +{ + struct hlist_node *node; + struct gw_node *gw_node, *curr_gw_tmp = NULL, *old_gw_node = NULL; + uint8_t max_tq = 0; + uint32_t max_gw_factor = 0, tmp_gw_factor = 0; + int down, up; + + /** + * The batman daemon checks here if we already passed a full originator + * cycle in order to make sure we don't choose the first gateway we + * hear about. This check is based on the daemon's uptime which we + * don't have. + **/ + if (atomic_read(&bat_priv->gw_mode) != GW_MODE_CLIENT) + return; + + if (bat_priv->curr_gw) + return; + + rcu_read_lock(); + if (hlist_empty(&bat_priv->gw_list)) { + rcu_read_unlock(); + + if (bat_priv->curr_gw) { + bat_dbg(DBG_BATMAN, bat_priv, + "Removing selected gateway - " + "no gateway in range\n"); + gw_deselect(bat_priv); + } + + return; + } + + hlist_for_each_entry_rcu(gw_node, node, &bat_priv->gw_list, list) { + if (!gw_node->orig_node->router) + continue; + + if (gw_node->deleted) + continue; + + switch (atomic_read(&bat_priv->gw_sel_class)) { + case 1: /* fast connection */ + gw_bandwidth_to_kbit(gw_node->orig_node->gw_flags, + &down, &up); + + tmp_gw_factor = (gw_node->orig_node->router->tq_avg * + gw_node->orig_node->router->tq_avg * + down * 100 * 100) / + (TQ_LOCAL_WINDOW_SIZE * + TQ_LOCAL_WINDOW_SIZE * 64); + + if ((tmp_gw_factor > max_gw_factor) || + ((tmp_gw_factor == max_gw_factor) && + (gw_node->orig_node->router->tq_avg > max_tq))) + curr_gw_tmp = gw_node; + break; + + default: /** + * 2: stable connection (use best statistic) + * 3: fast-switch (use best statistic but change as + * soon as a better gateway appears) + * XX: late-switch (use best statistic but change as + * soon as a better gateway appears which has + * $routing_class more tq points) + **/ + if (gw_node->orig_node->router->tq_avg > max_tq) + curr_gw_tmp = gw_node; + break; + } + + if (gw_node->orig_node->router->tq_avg > max_tq) + max_tq = gw_node->orig_node->router->tq_avg; + + if (tmp_gw_factor > max_gw_factor) + max_gw_factor = tmp_gw_factor; + } + + if (bat_priv->curr_gw != curr_gw_tmp) { + if ((bat_priv->curr_gw) && (!curr_gw_tmp)) + bat_dbg(DBG_BATMAN, bat_priv, + "Removing selected gateway - " + "no gateway in range\n"); + else if ((!bat_priv->curr_gw) && (curr_gw_tmp)) + bat_dbg(DBG_BATMAN, bat_priv, + "Adding route to gateway %pM " + "(gw_flags: %i, tq: %i)\n", + curr_gw_tmp->orig_node->orig, + curr_gw_tmp->orig_node->gw_flags, + curr_gw_tmp->orig_node->router->tq_avg); + else + bat_dbg(DBG_BATMAN, bat_priv, + "Changing route to gateway %pM " + "(gw_flags: %i, tq: %i)\n", + curr_gw_tmp->orig_node->orig, + curr_gw_tmp->orig_node->gw_flags, + curr_gw_tmp->orig_node->router->tq_avg); + + old_gw_node = gw_select(bat_priv, curr_gw_tmp); + } + + rcu_read_unlock(); + + /* the kfree() has to be outside of the rcu lock */ + if (old_gw_node) + kref_put(&old_gw_node->refcount, gw_node_free_ref); +} + +void gw_check_election(struct bat_priv *bat_priv, struct orig_node *orig_node) +{ + struct gw_node *curr_gateway_tmp = bat_priv->curr_gw; + uint8_t gw_tq_avg, orig_tq_avg; + + if (!curr_gateway_tmp) + return; + + if (!curr_gateway_tmp->orig_node) + goto deselect; + + if (!curr_gateway_tmp->orig_node->router) + goto deselect; + + /* this node already is the gateway */ + if (curr_gateway_tmp->orig_node == orig_node) + return; + + if (!orig_node->router) + return; + + gw_tq_avg = curr_gateway_tmp->orig_node->router->tq_avg; + orig_tq_avg = orig_node->router->tq_avg; + + /* the TQ value has to be better */ + if (orig_tq_avg < gw_tq_avg) + return; + + /** + * if the routing class is greater than 3 the value tells us how much + * greater the TQ value of the new gateway must be + **/ + if ((atomic_read(&bat_priv->gw_sel_class) > 3) && + (orig_tq_avg - gw_tq_avg < atomic_read(&bat_priv->gw_sel_class))) + return; + + bat_dbg(DBG_BATMAN, bat_priv, + "Restarting gateway selection: better gateway found (tq curr: " + "%i, tq new: %i)\n", + gw_tq_avg, orig_tq_avg); + +deselect: + gw_deselect(bat_priv); +} + +static void gw_node_add(struct bat_priv *bat_priv, + struct orig_node *orig_node, uint8_t new_gwflags) +{ + struct gw_node *gw_node; + int down, up; + + gw_node = kmalloc(sizeof(struct gw_node), GFP_ATOMIC); + if (!gw_node) + return; + + memset(gw_node, 0, sizeof(struct gw_node)); + INIT_HLIST_NODE(&gw_node->list); + gw_node->orig_node = orig_node; + kref_init(&gw_node->refcount); + + spin_lock_bh(&bat_priv->gw_list_lock); + hlist_add_head_rcu(&gw_node->list, &bat_priv->gw_list); + spin_unlock_bh(&bat_priv->gw_list_lock); + + gw_bandwidth_to_kbit(new_gwflags, &down, &up); + bat_dbg(DBG_BATMAN, bat_priv, + "Found new gateway %pM -> gw_class: %i - %i%s/%i%s\n", + orig_node->orig, new_gwflags, + (down > 2048 ? down / 1024 : down), + (down > 2048 ? "MBit" : "KBit"), + (up > 2048 ? up / 1024 : up), + (up > 2048 ? "MBit" : "KBit")); +} + +void gw_node_update(struct bat_priv *bat_priv, + struct orig_node *orig_node, uint8_t new_gwflags) +{ + struct hlist_node *node; + struct gw_node *gw_node; + + rcu_read_lock(); + hlist_for_each_entry_rcu(gw_node, node, &bat_priv->gw_list, list) { + if (gw_node->orig_node != orig_node) + continue; + + bat_dbg(DBG_BATMAN, bat_priv, + "Gateway class of originator %pM changed from " + "%i to %i\n", + orig_node->orig, gw_node->orig_node->gw_flags, + new_gwflags); + + gw_node->deleted = 0; + + if (new_gwflags == 0) { + gw_node->deleted = jiffies; + bat_dbg(DBG_BATMAN, bat_priv, + "Gateway %pM removed from gateway list\n", + orig_node->orig); + + if (gw_node == bat_priv->curr_gw) { + rcu_read_unlock(); + gw_deselect(bat_priv); + return; + } + } + + rcu_read_unlock(); + return; + } + rcu_read_unlock(); + + if (new_gwflags == 0) + return; + + gw_node_add(bat_priv, orig_node, new_gwflags); +} + +void gw_node_delete(struct bat_priv *bat_priv, struct orig_node *orig_node) +{ + return gw_node_update(bat_priv, orig_node, 0); +} + +void gw_node_purge(struct bat_priv *bat_priv) +{ + struct gw_node *gw_node; + struct hlist_node *node, *node_tmp; + unsigned long timeout = 2 * PURGE_TIMEOUT * HZ; + + spin_lock_bh(&bat_priv->gw_list_lock); + + hlist_for_each_entry_safe(gw_node, node, node_tmp, + &bat_priv->gw_list, list) { + if (((!gw_node->deleted) || + (time_before(jiffies, gw_node->deleted + timeout))) && + atomic_read(&bat_priv->mesh_state) == MESH_ACTIVE) + continue; + + if (bat_priv->curr_gw == gw_node) + gw_deselect(bat_priv); + + hlist_del_rcu(&gw_node->list); + call_rcu(&gw_node->rcu, gw_node_free_rcu); + } + + + spin_unlock_bh(&bat_priv->gw_list_lock); +} + +static int _write_buffer_text(struct bat_priv *bat_priv, + struct seq_file *seq, struct gw_node *gw_node) +{ + int down, up; + + gw_bandwidth_to_kbit(gw_node->orig_node->gw_flags, &down, &up); + + return seq_printf(seq, "%s %pM (%3i) %pM [%10s]: %3i - %i%s/%i%s\n", + (bat_priv->curr_gw == gw_node ? "=>" : " "), + gw_node->orig_node->orig, + gw_node->orig_node->router->tq_avg, + gw_node->orig_node->router->addr, + gw_node->orig_node->router->if_incoming->net_dev->name, + gw_node->orig_node->gw_flags, + (down > 2048 ? down / 1024 : down), + (down > 2048 ? "MBit" : "KBit"), + (up > 2048 ? up / 1024 : up), + (up > 2048 ? "MBit" : "KBit")); +} + +int gw_client_seq_print_text(struct seq_file *seq, void *offset) +{ + struct net_device *net_dev = (struct net_device *)seq->private; + struct bat_priv *bat_priv = netdev_priv(net_dev); + struct gw_node *gw_node; + struct hlist_node *node; + int gw_count = 0; + + if (!bat_priv->primary_if) { + + return seq_printf(seq, "BATMAN mesh %s disabled - please " + "specify interfaces to enable it\n", + net_dev->name); + } + + if (bat_priv->primary_if->if_status != IF_ACTIVE) { + + return seq_printf(seq, "BATMAN mesh %s disabled - " + "primary interface not active\n", + net_dev->name); + } + + seq_printf(seq, " %-12s (%s/%i) %17s [%10s]: gw_class ... " + "[B.A.T.M.A.N. adv %s%s, MainIF/MAC: %s/%pM (%s)]\n", + "Gateway", "#", TQ_MAX_VALUE, "Nexthop", + "outgoingIF", SOURCE_VERSION, REVISION_VERSION_STR, + bat_priv->primary_if->net_dev->name, + bat_priv->primary_if->net_dev->dev_addr, net_dev->name); + + rcu_read_lock(); + hlist_for_each_entry_rcu(gw_node, node, &bat_priv->gw_list, list) { + if (gw_node->deleted) + continue; + + if (!gw_node->orig_node->router) + continue; + + _write_buffer_text(bat_priv, seq, gw_node); + gw_count++; + } + rcu_read_unlock(); + + if (gw_count == 0) + seq_printf(seq, "No gateways in range ...\n"); + + return 0; +} diff --git a/drivers/staging/batman-adv/gateway_client.h b/drivers/staging/batman-adv/gateway_client.h new file mode 100644 index 000000000000..7383b903faea --- /dev/null +++ b/drivers/staging/batman-adv/gateway_client.h @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2009-2010 B.A.T.M.A.N. contributors: + * + * Marek Lindner + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA + * + */ + +#ifndef _NET_BATMAN_ADV_GATEWAY_CLIENT_H_ +#define _NET_BATMAN_ADV_GATEWAY_CLIENT_H_ + +void gw_deselect(struct bat_priv *bat_priv); +void gw_election(struct bat_priv *bat_priv); +void *gw_get_selected(struct bat_priv *bat_priv); +void gw_check_election(struct bat_priv *bat_priv, struct orig_node *orig_node); +void gw_node_update(struct bat_priv *bat_priv, + struct orig_node *orig_node, uint8_t new_gwflags); +void gw_node_delete(struct bat_priv *bat_priv, struct orig_node *orig_node); +void gw_node_purge(struct bat_priv *bat_priv); +int gw_client_seq_print_text(struct seq_file *seq, void *offset); + +#endif /* _NET_BATMAN_ADV_GATEWAY_CLIENT_H_ */ diff --git a/drivers/staging/batman-adv/gateway_common.c b/drivers/staging/batman-adv/gateway_common.c new file mode 100644 index 000000000000..b962982f017e --- /dev/null +++ b/drivers/staging/batman-adv/gateway_common.c @@ -0,0 +1,177 @@ +/* + * Copyright (C) 2009-2010 B.A.T.M.A.N. contributors: + * + * Marek Lindner + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA + * + */ + +#include "main.h" +#include "gateway_common.h" +#include "gateway_client.h" + +/* calculates the gateway class from kbit */ +static void kbit_to_gw_bandwidth(int down, int up, long *gw_srv_class) +{ + int mdown = 0, tdown, tup, difference; + uint8_t sbit, part; + + *gw_srv_class = 0; + difference = 0x0FFFFFFF; + + /* test all downspeeds */ + for (sbit = 0; sbit < 2; sbit++) { + for (part = 0; part < 16; part++) { + tdown = 32 * (sbit + 2) * (1 << part); + + if (abs(tdown - down) < difference) { + *gw_srv_class = (sbit << 7) + (part << 3); + difference = abs(tdown - down); + mdown = tdown; + } + } + } + + /* test all upspeeds */ + difference = 0x0FFFFFFF; + + for (part = 0; part < 8; part++) { + tup = ((part + 1) * (mdown)) / 8; + + if (abs(tup - up) < difference) { + *gw_srv_class = (*gw_srv_class & 0xF8) | part; + difference = abs(tup - up); + } + } +} + +/* returns the up and downspeeds in kbit, calculated from the class */ +void gw_bandwidth_to_kbit(uint8_t gw_srv_class, int *down, int *up) +{ + char sbit = (gw_srv_class & 0x80) >> 7; + char dpart = (gw_srv_class & 0x78) >> 3; + char upart = (gw_srv_class & 0x07); + + if (!gw_srv_class) { + *down = 0; + *up = 0; + return; + } + + *down = 32 * (sbit + 2) * (1 << dpart); + *up = ((upart + 1) * (*down)) / 8; +} + +static bool parse_gw_bandwidth(struct net_device *net_dev, char *buff, + long *up, long *down) +{ + int ret, multi = 1; + char *slash_ptr, *tmp_ptr; + + slash_ptr = strchr(buff, '/'); + if (slash_ptr) + *slash_ptr = 0; + + if (strlen(buff) > 4) { + tmp_ptr = buff + strlen(buff) - 4; + + if (strnicmp(tmp_ptr, "mbit", 4) == 0) + multi = 1024; + + if ((strnicmp(tmp_ptr, "kbit", 4) == 0) || + (multi > 1)) + *tmp_ptr = '\0'; + } + + ret = strict_strtoul(buff, 10, down); + if (ret) { + bat_err(net_dev, + "Download speed of gateway mode invalid: %s\n", + buff); + return false; + } + + *down *= multi; + + /* we also got some upload info */ + if (slash_ptr) { + multi = 1; + + if (strlen(slash_ptr + 1) > 4) { + tmp_ptr = slash_ptr + 1 - 4 + strlen(slash_ptr + 1); + + if (strnicmp(tmp_ptr, "mbit", 4) == 0) + multi = 1024; + + if ((strnicmp(tmp_ptr, "kbit", 4) == 0) || + (multi > 1)) + *tmp_ptr = '\0'; + } + + ret = strict_strtoul(slash_ptr + 1, 10, up); + if (ret) { + bat_err(net_dev, + "Upload speed of gateway mode invalid: " + "%s\n", slash_ptr + 1); + return false; + } + + *up *= multi; + } + + return true; +} + +ssize_t gw_bandwidth_set(struct net_device *net_dev, char *buff, size_t count) +{ + struct bat_priv *bat_priv = netdev_priv(net_dev); + long gw_bandwidth_tmp = 0, up = 0, down = 0; + bool ret; + + ret = parse_gw_bandwidth(net_dev, buff, &up, &down); + if (!ret) + goto end; + + if ((!down) || (down < 256)) + down = 2000; + + if (!up) + up = down / 5; + + kbit_to_gw_bandwidth(down, up, &gw_bandwidth_tmp); + + /** + * the gw bandwidth we guessed above might not match the given + * speeds, hence we need to calculate it back to show the number + * that is going to be propagated + **/ + gw_bandwidth_to_kbit((uint8_t)gw_bandwidth_tmp, + (int *)&down, (int *)&up); + + gw_deselect(bat_priv); + bat_info(net_dev, "Changing gateway bandwidth from: '%i' to: '%ld' " + "(propagating: %ld%s/%ld%s)\n", + atomic_read(&bat_priv->gw_bandwidth), gw_bandwidth_tmp, + (down > 2048 ? down / 1024 : down), + (down > 2048 ? "MBit" : "KBit"), + (up > 2048 ? up / 1024 : up), + (up > 2048 ? "MBit" : "KBit")); + + atomic_set(&bat_priv->gw_bandwidth, gw_bandwidth_tmp); + +end: + return count; +} diff --git a/drivers/staging/batman-adv/gateway_common.h b/drivers/staging/batman-adv/gateway_common.h new file mode 100644 index 000000000000..5e728d0b7959 --- /dev/null +++ b/drivers/staging/batman-adv/gateway_common.h @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2009-2010 B.A.T.M.A.N. contributors: + * + * Marek Lindner + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA + * + */ + +#ifndef _NET_BATMAN_ADV_GATEWAY_COMMON_H_ +#define _NET_BATMAN_ADV_GATEWAY_COMMON_H_ + +enum gw_modes { + GW_MODE_OFF, + GW_MODE_CLIENT, + GW_MODE_SERVER, +}; + +#define GW_MODE_OFF_NAME "off" +#define GW_MODE_CLIENT_NAME "client" +#define GW_MODE_SERVER_NAME "server" + +void gw_bandwidth_to_kbit(uint8_t gw_class, int *down, int *up); +ssize_t gw_bandwidth_set(struct net_device *net_dev, char *buff, size_t count); + +#endif /* _NET_BATMAN_ADV_GATEWAY_COMMON_H_ */ diff --git a/drivers/staging/batman-adv/main.c b/drivers/staging/batman-adv/main.c index 61d1aa66e956..c91e635d3d96 100644 --- a/drivers/staging/batman-adv/main.c +++ b/drivers/staging/batman-adv/main.c @@ -29,6 +29,7 @@ #include "icmp_socket.h" #include "translation-table.h" #include "hard-interface.h" +#include "gateway_client.h" #include "types.h" #include "vis.h" #include "hash.h" @@ -84,12 +85,14 @@ int mesh_init(struct net_device *soft_iface) spin_lock_init(&bat_priv->forw_bcast_list_lock); spin_lock_init(&bat_priv->hna_lhash_lock); spin_lock_init(&bat_priv->hna_ghash_lock); + spin_lock_init(&bat_priv->gw_list_lock); spin_lock_init(&bat_priv->vis_hash_lock); spin_lock_init(&bat_priv->vis_list_lock); spin_lock_init(&bat_priv->softif_neigh_lock); INIT_HLIST_HEAD(&bat_priv->forw_bat_list); INIT_HLIST_HEAD(&bat_priv->forw_bcast_list); + INIT_HLIST_HEAD(&bat_priv->gw_list); INIT_HLIST_HEAD(&bat_priv->softif_neigh_list); if (originator_init(bat_priv) < 1) @@ -129,6 +132,7 @@ void mesh_free(struct net_device *soft_iface) vis_quit(bat_priv); + gw_node_purge(bat_priv); originator_free(bat_priv); hna_local_free(bat_priv); diff --git a/drivers/staging/batman-adv/originator.c b/drivers/staging/batman-adv/originator.c index 8bef4681bf82..89ec02100a3b 100644 --- a/drivers/staging/batman-adv/originator.c +++ b/drivers/staging/batman-adv/originator.c @@ -26,6 +26,7 @@ #include "hash.h" #include "translation-table.h" #include "routing.h" +#include "gateway_client.h" #include "hard-interface.h" #include "unicast.h" #include "soft-interface.h" @@ -279,6 +280,8 @@ static void _purge_orig(struct bat_priv *bat_priv) orig_node = bucket->data; if (purge_orig_node(bat_priv, orig_node)) { + if (orig_node->gw_flags) + gw_node_delete(bat_priv, orig_node); hash_remove_bucket(bat_priv->orig_hash, &hashit); free_orig_node(orig_node, bat_priv); } @@ -290,6 +293,9 @@ static void _purge_orig(struct bat_priv *bat_priv) spin_unlock_bh(&bat_priv->orig_hash_lock); + gw_node_purge(bat_priv); + gw_election(bat_priv); + softif_neigh_purge(bat_priv); } diff --git a/drivers/staging/batman-adv/packet.h b/drivers/staging/batman-adv/packet.h index 2693383889a4..b49fdf70a6d5 100644 --- a/drivers/staging/batman-adv/packet.h +++ b/drivers/staging/batman-adv/packet.h @@ -32,7 +32,7 @@ #define BAT_UNICAST_FRAG 0x06 /* this file is included by batctl which needs these defines */ -#define COMPAT_VERSION 13 +#define COMPAT_VERSION 12 #define DIRECTLINK 0x40 #define VIS_SERVER 0x20 #define PRIMARIES_FIRST_HOP 0x10 @@ -61,6 +61,8 @@ struct batman_packet { uint8_t prev_sender[6]; uint8_t ttl; uint8_t num_hna; + uint8_t gw_flags; /* flags related to gateway class */ + uint8_t align; } __attribute__((packed)); #define BAT_PACKET_LEN sizeof(struct batman_packet) diff --git a/drivers/staging/batman-adv/routing.c b/drivers/staging/batman-adv/routing.c index 1536963dd69f..9f31167a9058 100644 --- a/drivers/staging/batman-adv/routing.c +++ b/drivers/staging/batman-adv/routing.c @@ -32,6 +32,8 @@ #include "ring_buffer.h" #include "vis.h" #include "aggregation.h" +#include "gateway_common.h" +#include "gateway_client.h" #include "unicast.h" void slide_own_bcast_window(struct batman_if *batman_if) @@ -316,11 +318,23 @@ static void update_orig(struct bat_priv *bat_priv, update_routes(bat_priv, orig_node, neigh_node, hna_buff, tmp_hna_buff_len); - return; + goto update_gw; update_hna: update_routes(bat_priv, orig_node, orig_node->router, hna_buff, tmp_hna_buff_len); + +update_gw: + if (orig_node->gw_flags != batman_packet->gw_flags) + gw_node_update(bat_priv, orig_node, batman_packet->gw_flags); + + orig_node->gw_flags = batman_packet->gw_flags; + + /* restart gateway selection if fast or late switching was enabled */ + if ((orig_node->gw_flags) && + (atomic_read(&bat_priv->gw_mode) == GW_MODE_CLIENT) && + (atomic_read(&bat_priv->gw_sel_class) > 2)) + gw_check_election(bat_priv, orig_node); } /* checks whether the host restarted and is in the protection time. diff --git a/drivers/staging/batman-adv/send.c b/drivers/staging/batman-adv/send.c index 9ed77d7bbca0..36945dc5a44b 100644 --- a/drivers/staging/batman-adv/send.c +++ b/drivers/staging/batman-adv/send.c @@ -28,6 +28,7 @@ #include "types.h" #include "vis.h" #include "aggregation.h" +#include "gateway_common.h" #include "originator.h" @@ -284,6 +285,13 @@ void schedule_own_packet(struct batman_if *batman_if) else batman_packet->flags &= ~VIS_SERVER; + if ((batman_if == bat_priv->primary_if) && + (atomic_read(&bat_priv->gw_mode) == GW_MODE_SERVER)) + batman_packet->gw_flags = + (uint8_t)atomic_read(&bat_priv->gw_bandwidth); + else + batman_packet->gw_flags = 0; + atomic_inc(&batman_if->seqno); slide_own_bcast_window(batman_if); diff --git a/drivers/staging/batman-adv/soft-interface.c b/drivers/staging/batman-adv/soft-interface.c index 28ffe34919d3..64eaf2a56fb0 100644 --- a/drivers/staging/batman-adv/soft-interface.c +++ b/drivers/staging/batman-adv/soft-interface.c @@ -28,6 +28,7 @@ #include "translation-table.h" #include "types.h" #include "hash.h" +#include "gateway_common.h" #include "send.h" #include "bat_sysfs.h" #include @@ -579,6 +580,9 @@ struct net_device *softif_create(char *name) atomic_set(&bat_priv->aggregated_ogms, 1); atomic_set(&bat_priv->bonding, 0); atomic_set(&bat_priv->vis_mode, VIS_TYPE_CLIENT_UPDATE); + atomic_set(&bat_priv->gw_mode, GW_MODE_OFF); + atomic_set(&bat_priv->gw_sel_class, 20); + atomic_set(&bat_priv->gw_bandwidth, 41); atomic_set(&bat_priv->orig_interval, 1000); atomic_set(&bat_priv->hop_penalty, 10); atomic_set(&bat_priv->log_level, 0); diff --git a/drivers/staging/batman-adv/sysfs-class-net-mesh b/drivers/staging/batman-adv/sysfs-class-net-mesh index bd20e14261c0..748fe1701d25 100644 --- a/drivers/staging/batman-adv/sysfs-class-net-mesh +++ b/drivers/staging/batman-adv/sysfs-class-net-mesh @@ -22,6 +22,27 @@ Description: mesh will be fragmented or silently discarded if the packet size exceeds the outgoing interface MTU. +What: /sys/class/net//mesh/gw_bandwidth +Date: October 2010 +Contact: Marek Lindner +Description: + Defines the bandwidth which is propagated by this + node if gw_mode was set to 'server'. + +What: /sys/class/net//mesh/gw_mode +Date: October 2010 +Contact: Marek Lindner +Description: + Defines the state of the gateway features. Can be + either 'off', 'client' or 'server'. + +What: /sys/class/net//mesh/gw_sel_class +Date: October 2010 +Contact: Marek Lindner +Description: + Defines the selection criteria this node will use + to choose a gateway if gw_mode was set to 'client'. + What: /sys/class/net//mesh/orig_interval Date: May 2010 Contact: Marek Lindner diff --git a/drivers/staging/batman-adv/types.h b/drivers/staging/batman-adv/types.h index e41f95fbf61f..1d0084995c7c 100644 --- a/drivers/staging/batman-adv/types.h +++ b/drivers/staging/batman-adv/types.h @@ -55,6 +55,7 @@ struct batman_if { * @last_valid: when last packet from this node was received * @bcast_seqno_reset: time when the broadcast seqno window was reset * @batman_seqno_reset: time when the batman seqno window was reset + * @gw_flags: flags related to gateway class * @flags: for now only VIS_SERVER flag * @last_real_seqno: last and best known squence number * @last_ttl: ttl of last received packet @@ -74,7 +75,8 @@ struct orig_node { unsigned long last_valid; unsigned long bcast_seqno_reset; unsigned long batman_seqno_reset; - uint8_t flags; + uint8_t gw_flags; + uint8_t flags; unsigned char *hna_buff; int16_t hna_buff_len; uint32_t last_real_seqno; @@ -90,6 +92,14 @@ struct orig_node { } bond; }; +struct gw_node { + struct hlist_node list; + struct orig_node *orig_node; + unsigned long deleted; + struct kref refcount; + struct rcu_head rcu; +}; + /** * neigh_node * @last_valid: when last packet via this neighbor was received @@ -117,6 +127,9 @@ struct bat_priv { atomic_t bonding; /* boolean */ atomic_t fragmentation; /* boolean */ atomic_t vis_mode; /* VIS_TYPE_* */ + atomic_t gw_mode; /* GW_MODE_* */ + atomic_t gw_sel_class; /* uint */ + atomic_t gw_bandwidth; /* gw bandwidth */ atomic_t orig_interval; /* uint */ atomic_t hop_penalty; /* uint */ atomic_t log_level; /* uint */ @@ -132,6 +145,7 @@ struct bat_priv { struct dentry *debug_dir; struct hlist_head forw_bat_list; struct hlist_head forw_bcast_list; + struct hlist_head gw_list; struct list_head vis_send_list; struct hashtable_t *orig_hash; struct hashtable_t *hna_local_hash; @@ -142,6 +156,7 @@ struct bat_priv { spinlock_t forw_bcast_list_lock; /* protects */ spinlock_t hna_lhash_lock; /* protects hna_local_hash */ spinlock_t hna_ghash_lock; /* protects hna_global_hash */ + spinlock_t gw_list_lock; /* protects gw_list */ spinlock_t vis_hash_lock; /* protects vis_hash */ spinlock_t vis_list_lock; /* protects vis_info::recv_list */ spinlock_t softif_neigh_lock; /* protects soft-interface neigh list */ @@ -150,6 +165,7 @@ struct bat_priv { struct delayed_work hna_work; struct delayed_work orig_work; struct delayed_work vis_work; + struct gw_node *curr_gw; struct vis_info *my_vis_info; }; -- cgit v1.2.3 From 6c3a42db6ca46204b35f0cdb8abfa9e4771641ef Mon Sep 17 00:00:00 2001 From: Marek Lindner Date: Mon, 22 Nov 2010 00:56:03 +0100 Subject: Staging: batman-adv: send DHCP requests directly to the chosen gw If the gateway client mode is active batman-adv will send the broadcasted DHCP requests via unicast to the currently selected best gateway. Therefore attached clients can profit from batman's knowledge about the network topology. Signed-off-by: Marek Lindner [sven.eckelmann@gmx.de: Rework on top of current version] Signed-off-by: Sven Eckelmann Signed-off-by: Greg Kroah-Hartman --- drivers/staging/batman-adv/gateway_client.c | 60 +++++++++++++++++++++++++++++ drivers/staging/batman-adv/gateway_client.h | 1 + drivers/staging/batman-adv/soft-interface.c | 14 ++++++- drivers/staging/batman-adv/unicast.c | 12 ++++-- 4 files changed, 82 insertions(+), 5 deletions(-) diff --git a/drivers/staging/batman-adv/gateway_client.c b/drivers/staging/batman-adv/gateway_client.c index 1846a6219631..3d4e1096a9dc 100644 --- a/drivers/staging/batman-adv/gateway_client.c +++ b/drivers/staging/batman-adv/gateway_client.c @@ -23,6 +23,9 @@ #include "gateway_client.h" #include "gateway_common.h" #include "hard-interface.h" +#include +#include +#include static void gw_node_free_ref(struct kref *refcount) { @@ -40,6 +43,16 @@ static void gw_node_free_rcu(struct rcu_head *rcu) kref_put(&gw_node->refcount, gw_node_free_ref); } +void *gw_get_selected(struct bat_priv *bat_priv) +{ + struct gw_node *curr_gateway_tmp = bat_priv->curr_gw; + + if (!curr_gateway_tmp) + return NULL; + + return curr_gateway_tmp->orig_node; +} + void gw_deselect(struct bat_priv *bat_priv) { struct gw_node *gw_node = bat_priv->curr_gw; @@ -385,3 +398,50 @@ int gw_client_seq_print_text(struct seq_file *seq, void *offset) return 0; } + +int gw_is_target(struct bat_priv *bat_priv, struct sk_buff *skb) +{ + struct ethhdr *ethhdr; + struct iphdr *iphdr; + struct udphdr *udphdr; + unsigned int header_len = 0; + + if (atomic_read(&bat_priv->gw_mode) == GW_MODE_OFF) + return 0; + + /* check for ethernet header */ + if (!pskb_may_pull(skb, header_len + ETH_HLEN)) + return 0; + ethhdr = (struct ethhdr *)skb->data; + header_len += ETH_HLEN; + + /* check for ip header */ + if (ntohs(ethhdr->h_proto) != ETH_P_IP) + return 0; + + if (!pskb_may_pull(skb, header_len + sizeof(struct iphdr))) + return 0; + iphdr = (struct iphdr *)(skb->data + header_len); + header_len += iphdr->ihl * 4; + + /* check for udp header */ + if (iphdr->protocol != IPPROTO_UDP) + return 0; + + if (!pskb_may_pull(skb, header_len + sizeof(struct udphdr))) + return 0; + udphdr = (struct udphdr *)(skb->data + header_len); + header_len += sizeof(struct udphdr); + + /* check for bootp port */ + if (ntohs(udphdr->dest) != 67) + return 0; + + if (atomic_read(&bat_priv->gw_mode) == GW_MODE_SERVER) + return -1; + + if (!bat_priv->curr_gw) + return 0; + + return 1; +} diff --git a/drivers/staging/batman-adv/gateway_client.h b/drivers/staging/batman-adv/gateway_client.h index 7383b903faea..4585e6549844 100644 --- a/drivers/staging/batman-adv/gateway_client.h +++ b/drivers/staging/batman-adv/gateway_client.h @@ -31,5 +31,6 @@ void gw_node_update(struct bat_priv *bat_priv, void gw_node_delete(struct bat_priv *bat_priv, struct orig_node *orig_node); void gw_node_purge(struct bat_priv *bat_priv); int gw_client_seq_print_text(struct seq_file *seq, void *offset); +int gw_is_target(struct bat_priv *bat_priv, struct sk_buff *skb); #endif /* _NET_BATMAN_ADV_GATEWAY_CLIENT_H_ */ diff --git a/drivers/staging/batman-adv/soft-interface.c b/drivers/staging/batman-adv/soft-interface.c index 64eaf2a56fb0..9b968df185d1 100644 --- a/drivers/staging/batman-adv/soft-interface.c +++ b/drivers/staging/batman-adv/soft-interface.c @@ -29,6 +29,7 @@ #include "types.h" #include "hash.h" #include "gateway_common.h" +#include "gateway_client.h" #include "send.h" #include "bat_sysfs.h" #include @@ -346,6 +347,7 @@ int interface_tx(struct sk_buff *skb, struct net_device *soft_iface) struct vlan_ethhdr *vhdr; int data_len = skb->len, ret; short vid = -1; + bool do_bcast = false; if (atomic_read(&bat_priv->mesh_state) != MESH_ACTIVE) goto dropped; @@ -376,8 +378,18 @@ int interface_tx(struct sk_buff *skb, struct net_device *soft_iface) /* TODO: check this for locks */ hna_local_add(soft_iface, ethhdr->h_source); - /* ethernet packet should be broadcasted */ if (is_bcast(ethhdr->h_dest) || is_mcast(ethhdr->h_dest)) { + ret = gw_is_target(bat_priv, skb); + + if (ret < 0) + goto dropped; + + if (ret == 0) + do_bcast = true; + } + + /* ethernet packet should be broadcasted */ + if (do_bcast) { if (!bat_priv->primary_if) goto dropped; diff --git a/drivers/staging/batman-adv/unicast.c b/drivers/staging/batman-adv/unicast.c index 3b62d998a2f1..7b9385b658c8 100644 --- a/drivers/staging/batman-adv/unicast.c +++ b/drivers/staging/batman-adv/unicast.c @@ -23,6 +23,7 @@ #include "unicast.h" #include "send.h" #include "soft-interface.h" +#include "gateway_client.h" #include "originator.h" #include "hash.h" #include "translation-table.h" @@ -282,10 +283,13 @@ int unicast_send_skb(struct sk_buff *skb, struct bat_priv *bat_priv) spin_lock_bh(&bat_priv->orig_hash_lock); /* get routing information */ - orig_node = ((struct orig_node *)hash_find(bat_priv->orig_hash, - compare_orig, - choose_orig, - ethhdr->h_dest)); + if (is_bcast(ethhdr->h_dest) || is_mcast(ethhdr->h_dest)) + orig_node = (struct orig_node *)gw_get_selected(bat_priv); + else + orig_node = ((struct orig_node *)hash_find(bat_priv->orig_hash, + compare_orig, + choose_orig, + ethhdr->h_dest)); /* check for hna host */ if (!orig_node) -- cgit v1.2.3 From c9c556b63b19c8b52de5c5ea6f47ab16fc540e47 Mon Sep 17 00:00:00 2001 From: Marek Lindner Date: Mon, 22 Nov 2010 00:56:04 +0100 Subject: Staging: batman-adv: best gw DHCP filter 802.1Q support The DHCP filter inspects packets to determine whether or not to send them via ethernet unicast. This patch adds 802.1Q (vlan) support for this check. Signed-off-by: Marek Lindner [sven.eckelmann@gmx.de: Rework on top of current version] Signed-off-by: Sven Eckelmann Signed-off-by: Greg Kroah-Hartman --- drivers/staging/batman-adv/gateway_client.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/staging/batman-adv/gateway_client.c b/drivers/staging/batman-adv/gateway_client.c index 3d4e1096a9dc..fde1d8a952fd 100644 --- a/drivers/staging/batman-adv/gateway_client.c +++ b/drivers/staging/batman-adv/gateway_client.c @@ -415,6 +415,14 @@ int gw_is_target(struct bat_priv *bat_priv, struct sk_buff *skb) ethhdr = (struct ethhdr *)skb->data; header_len += ETH_HLEN; + /* check for initial vlan header */ + if (ntohs(ethhdr->h_proto) == ETH_P_8021Q) { + if (!pskb_may_pull(skb, header_len + VLAN_HLEN)) + return 0; + ethhdr = (struct ethhdr *)(skb->data + VLAN_HLEN); + header_len += VLAN_HLEN; + } + /* check for ip header */ if (ntohs(ethhdr->h_proto) != ETH_P_IP) return 0; -- cgit v1.2.3 From 003db3b2ad61c2964d624b0786cf8202e9a92c8e Mon Sep 17 00:00:00 2001 From: Marek Lindner Date: Mon, 22 Nov 2010 00:56:05 +0100 Subject: Staging: batman-adv: add gateway IPv6 support by filtering DHCPv6 messages MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some additional checks will be needed in case of extension headers like the fragmentation or hop-by-hop (for jumbo frames for example) headers or ipsec stuff. But this patch should do for most people for now, the rest can be added with a later one. Signed-off-by: Marek Lindner Acked-by: Linus Lüssing Signed-off-by: Sven Eckelmann Signed-off-by: Greg Kroah-Hartman --- drivers/staging/batman-adv/gateway_client.c | 40 ++++++++++++++++++++++------- 1 file changed, 31 insertions(+), 9 deletions(-) diff --git a/drivers/staging/batman-adv/gateway_client.c b/drivers/staging/batman-adv/gateway_client.c index fde1d8a952fd..0065ffb8d96d 100644 --- a/drivers/staging/batman-adv/gateway_client.c +++ b/drivers/staging/batman-adv/gateway_client.c @@ -24,6 +24,7 @@ #include "gateway_common.h" #include "hard-interface.h" #include +#include #include #include @@ -403,6 +404,7 @@ int gw_is_target(struct bat_priv *bat_priv, struct sk_buff *skb) { struct ethhdr *ethhdr; struct iphdr *iphdr; + struct ipv6hdr *ipv6hdr; struct udphdr *udphdr; unsigned int header_len = 0; @@ -424,17 +426,32 @@ int gw_is_target(struct bat_priv *bat_priv, struct sk_buff *skb) } /* check for ip header */ - if (ntohs(ethhdr->h_proto) != ETH_P_IP) - return 0; + switch (ntohs(ethhdr->h_proto)) { + case ETH_P_IP: + if (!pskb_may_pull(skb, header_len + sizeof(struct iphdr))) + return 0; + iphdr = (struct iphdr *)(skb->data + header_len); + header_len += iphdr->ihl * 4; - if (!pskb_may_pull(skb, header_len + sizeof(struct iphdr))) - return 0; - iphdr = (struct iphdr *)(skb->data + header_len); - header_len += iphdr->ihl * 4; + /* check for udp header */ + if (iphdr->protocol != IPPROTO_UDP) + return 0; + + break; + case ETH_P_IPV6: + if (!pskb_may_pull(skb, header_len + sizeof(struct ipv6hdr))) + return 0; + ipv6hdr = (struct ipv6hdr *)(skb->data + header_len); + header_len += sizeof(struct ipv6hdr); - /* check for udp header */ - if (iphdr->protocol != IPPROTO_UDP) + /* check for udp header */ + if (ipv6hdr->nexthdr != IPPROTO_UDP) + return 0; + + break; + default: return 0; + } if (!pskb_may_pull(skb, header_len + sizeof(struct udphdr))) return 0; @@ -442,7 +459,12 @@ int gw_is_target(struct bat_priv *bat_priv, struct sk_buff *skb) header_len += sizeof(struct udphdr); /* check for bootp port */ - if (ntohs(udphdr->dest) != 67) + if ((ntohs(ethhdr->h_proto) == ETH_P_IP) && + (ntohs(udphdr->dest) != 67)) + return 0; + + if ((ntohs(ethhdr->h_proto) == ETH_P_IPV6) && + (ntohs(udphdr->dest) != 547)) return 0; if (atomic_read(&bat_priv->gw_mode) == GW_MODE_SERVER) -- cgit v1.2.3 From 8cab2fbe6dacfdd3b122c450d2fffde6ac06a8b6 Mon Sep 17 00:00:00 2001 From: Sven Eckelmann Date: Mon, 22 Nov 2010 00:56:06 +0100 Subject: Staging: batman-adv: Use kernel version min macro The kernel headers already provide different versions of a min/max macro which should be used by all modules according to Documentation/CodingStyle. Signed-off-by: Sven Eckelmann Signed-off-by: Greg Kroah-Hartman --- drivers/staging/batman-adv/hard-interface.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/drivers/staging/batman-adv/hard-interface.c b/drivers/staging/batman-adv/hard-interface.c index ff0ac9825001..4f95777ce080 100644 --- a/drivers/staging/batman-adv/hard-interface.c +++ b/drivers/staging/batman-adv/hard-interface.c @@ -31,8 +31,6 @@ #include -#define MIN(x, y) ((x) < (y) ? (x) : (y)) - /* protect update critical side of if_list - but not the content */ static DEFINE_SPINLOCK(if_list_lock); @@ -220,8 +218,8 @@ int hardif_min_mtu(struct net_device *soft_iface) if (batman_if->soft_iface != soft_iface) continue; - min_mtu = MIN(batman_if->net_dev->mtu - BAT_HEADER_LEN, - min_mtu); + min_mtu = min_t(int, batman_if->net_dev->mtu - BAT_HEADER_LEN, + min_mtu); } rcu_read_unlock(); out: -- cgit v1.2.3 From 951c44e0dbfaa580d5b4fb13427ab93ee252636a Mon Sep 17 00:00:00 2001 From: Sven Eckelmann Date: Mon, 22 Nov 2010 00:56:07 +0100 Subject: Staging: batman-adv: Use kernel functions to identify broadcasts linux/etherdevice.h already provides functions to classify different ethernet addresses. These inlineable functions should be used instead of custom functions. The check for multicast together with multicast can also be replaced with a single test for multicast because for every ethernet address x following is always true: is_broadcast_ether_addr(x) => is_multicast_ether_addr(x) or when looking more at the implementation: (FF:FF:FF:FF:FF:FF == x) => [(01:00:00:00:00:00 & x) != 00:00:00:00:00:00] Reported-by: Tobias Klauser Signed-off-by: Sven Eckelmann Signed-off-by: Greg Kroah-Hartman --- drivers/staging/batman-adv/main.c | 10 ---------- drivers/staging/batman-adv/main.h | 3 +-- drivers/staging/batman-adv/routing.c | 16 ++++++++-------- drivers/staging/batman-adv/soft-interface.c | 2 +- drivers/staging/batman-adv/unicast.c | 2 +- drivers/staging/batman-adv/vis.c | 4 ++-- 6 files changed, 13 insertions(+), 24 deletions(-) diff --git a/drivers/staging/batman-adv/main.c b/drivers/staging/batman-adv/main.c index c91e635d3d96..b827f6a158cb 100644 --- a/drivers/staging/batman-adv/main.c +++ b/drivers/staging/batman-adv/main.c @@ -172,16 +172,6 @@ int is_my_mac(uint8_t *addr) } -int is_bcast(uint8_t *addr) -{ - return (addr[0] == (uint8_t)0xff) && (addr[1] == (uint8_t)0xff); -} - -int is_mcast(uint8_t *addr) -{ - return *addr & 0x01; -} - module_init(batman_init); module_exit(batman_exit); diff --git a/drivers/staging/batman-adv/main.h b/drivers/staging/batman-adv/main.h index 3ee1eb0a7253..6b60c33a8b77 100644 --- a/drivers/staging/batman-adv/main.h +++ b/drivers/staging/batman-adv/main.h @@ -109,6 +109,7 @@ #include /* mutex */ #include /* needed by all modules */ #include /* netdevice */ +#include /* ethernet address classifaction */ #include /* ethernet header */ #include /* poll_table */ #include /* kernel threads */ @@ -136,8 +137,6 @@ void mesh_free(struct net_device *soft_iface); void inc_module_count(void); void dec_module_count(void); int is_my_mac(uint8_t *addr); -int is_bcast(uint8_t *addr); -int is_mcast(uint8_t *addr); #ifdef CONFIG_BATMAN_ADV_DEBUG int debug_log(struct bat_priv *bat_priv, char *fmt, ...); diff --git a/drivers/staging/batman-adv/routing.c b/drivers/staging/batman-adv/routing.c index 9f31167a9058..d8b0c5a6d5df 100644 --- a/drivers/staging/batman-adv/routing.c +++ b/drivers/staging/batman-adv/routing.c @@ -770,11 +770,11 @@ int recv_bat_packet(struct sk_buff *skb, struct batman_if *batman_if) ethhdr = (struct ethhdr *)skb_mac_header(skb); /* packet with broadcast indication but unicast recipient */ - if (!is_bcast(ethhdr->h_dest)) + if (!is_broadcast_ether_addr(ethhdr->h_dest)) return NET_RX_DROP; /* packet with broadcast sender address */ - if (is_bcast(ethhdr->h_source)) + if (is_broadcast_ether_addr(ethhdr->h_source)) return NET_RX_DROP; /* create a copy of the skb, if needed, to modify it. */ @@ -946,11 +946,11 @@ int recv_icmp_packet(struct sk_buff *skb, struct batman_if *recv_if) ethhdr = (struct ethhdr *)skb_mac_header(skb); /* packet with unicast indication but broadcast recipient */ - if (is_bcast(ethhdr->h_dest)) + if (is_broadcast_ether_addr(ethhdr->h_dest)) return NET_RX_DROP; /* packet with broadcast sender address */ - if (is_bcast(ethhdr->h_source)) + if (is_broadcast_ether_addr(ethhdr->h_source)) return NET_RX_DROP; /* not for me */ @@ -1118,11 +1118,11 @@ static int check_unicast_packet(struct sk_buff *skb, int hdr_size) ethhdr = (struct ethhdr *)skb_mac_header(skb); /* packet with unicast indication but broadcast recipient */ - if (is_bcast(ethhdr->h_dest)) + if (is_broadcast_ether_addr(ethhdr->h_dest)) return -1; /* packet with broadcast sender address */ - if (is_bcast(ethhdr->h_source)) + if (is_broadcast_ether_addr(ethhdr->h_source)) return -1; /* not for me */ @@ -1282,11 +1282,11 @@ int recv_bcast_packet(struct sk_buff *skb, struct batman_if *recv_if) ethhdr = (struct ethhdr *)skb_mac_header(skb); /* packet with broadcast indication but unicast recipient */ - if (!is_bcast(ethhdr->h_dest)) + if (!is_broadcast_ether_addr(ethhdr->h_dest)) return NET_RX_DROP; /* packet with broadcast sender address */ - if (is_bcast(ethhdr->h_source)) + if (is_broadcast_ether_addr(ethhdr->h_source)) return NET_RX_DROP; /* ignore broadcasts sent by myself */ diff --git a/drivers/staging/batman-adv/soft-interface.c b/drivers/staging/batman-adv/soft-interface.c index 9b968df185d1..e89ede192ed0 100644 --- a/drivers/staging/batman-adv/soft-interface.c +++ b/drivers/staging/batman-adv/soft-interface.c @@ -378,7 +378,7 @@ int interface_tx(struct sk_buff *skb, struct net_device *soft_iface) /* TODO: check this for locks */ hna_local_add(soft_iface, ethhdr->h_source); - if (is_bcast(ethhdr->h_dest) || is_mcast(ethhdr->h_dest)) { + if (is_multicast_ether_addr(ethhdr->h_dest)) { ret = gw_is_target(bat_priv, skb); if (ret < 0) diff --git a/drivers/staging/batman-adv/unicast.c b/drivers/staging/batman-adv/unicast.c index 7b9385b658c8..dc2e28bed844 100644 --- a/drivers/staging/batman-adv/unicast.c +++ b/drivers/staging/batman-adv/unicast.c @@ -283,7 +283,7 @@ int unicast_send_skb(struct sk_buff *skb, struct bat_priv *bat_priv) spin_lock_bh(&bat_priv->orig_hash_lock); /* get routing information */ - if (is_bcast(ethhdr->h_dest) || is_mcast(ethhdr->h_dest)) + if (is_multicast_ether_addr(ethhdr->h_dest)) orig_node = (struct orig_node *)gw_get_selected(bat_priv); else orig_node = ((struct orig_node *)hash_find(bat_priv->orig_hash, diff --git a/drivers/staging/batman-adv/vis.c b/drivers/staging/batman-adv/vis.c index 65676dcd40ed..957a08624ff8 100644 --- a/drivers/staging/batman-adv/vis.c +++ b/drivers/staging/batman-adv/vis.c @@ -472,7 +472,7 @@ void receive_client_update_packet(struct bat_priv *bat_priv, int are_target = 0; /* clients shall not broadcast. */ - if (is_bcast(vis_packet->target_orig)) + if (is_broadcast_ether_addr(vis_packet->target_orig)) return; /* Are we the target for this VIS packet? */ @@ -755,7 +755,7 @@ static void send_vis_packet(struct bat_priv *bat_priv, struct vis_info *info) ETH_ALEN); packet->ttl--; - if (is_bcast(packet->target_orig)) + if (is_broadcast_ether_addr(packet->target_orig)) broadcast_vis_packet(bat_priv, info); else unicast_vis_packet(bat_priv, info); -- cgit v1.2.3 From 964c6975e8a4314c451d420f1cb54880ab535433 Mon Sep 17 00:00:00 2001 From: Vinod Koul Date: Mon, 22 Nov 2010 10:33:28 +0000 Subject: Staging: sst: Add runtime PM support This adds runtime PM support for audio driver. This also fixes LPA audio mode for moorestown platform Signed-off-by: Vinod Koul Signed-off-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/staging/intel_sst/intel_sst.c | 43 ++++++++++++++++++++-- .../staging/intel_sst/intel_sst_app_interface.c | 13 ++++++- drivers/staging/intel_sst/intel_sst_common.h | 1 + .../staging/intel_sst/intel_sst_drv_interface.c | 16 ++++++-- drivers/staging/intel_sst/intel_sst_dsp.c | 3 +- drivers/staging/intel_sst/intel_sst_ipc.c | 1 + 6 files changed, 69 insertions(+), 8 deletions(-) diff --git a/drivers/staging/intel_sst/intel_sst.c b/drivers/staging/intel_sst/intel_sst.c index 0ba6742d9236..bd92549893a6 100644 --- a/drivers/staging/intel_sst/intel_sst.c +++ b/drivers/staging/intel_sst/intel_sst.c @@ -36,6 +36,7 @@ #include #include #include +#include #include #include "intel_sst.h" #include "intel_sst_ioctl.h" @@ -320,6 +321,9 @@ static int __devinit intel_sst_probe(struct pci_dev *pci, } } sst_drv_ctx->lpe_stalled = 0; + pm_runtime_set_active(&pci->dev); + pm_runtime_enable(&pci->dev); + pm_runtime_allow(&pci->dev); pr_debug("...successfully done!!!\n"); return ret; @@ -408,8 +412,10 @@ int intel_sst_suspend(struct pci_dev *pci, pm_message_t state) pr_debug("intel_sst_suspend called\n"); - if (sst_drv_ctx->pb_streams != 0 || sst_drv_ctx->cp_streams != 0) - return -EPERM; + if (sst_drv_ctx->stream_cnt) { + pr_err("active streams,not able to suspend\n"); + return -EBUSY; + } /*Assert RESET on LPE Processor*/ csr.full = sst_shim_read(sst_drv_ctx->shim, SST_CSR); csr.full = csr.full | 0x2; @@ -439,7 +445,7 @@ int intel_sst_resume(struct pci_dev *pci) pr_debug("intel_sst_resume called\n"); if (sst_drv_ctx->sst_state != SST_SUSPENDED) { pr_err("SST is not in suspended state\n"); - return -EPERM; + return 0; } sst_drv_ctx = pci_get_drvdata(pci); pci_set_power_state(pci, PCI_D0); @@ -454,6 +460,34 @@ int intel_sst_resume(struct pci_dev *pci) return 0; } +static int intel_sst_runtime_suspend(struct device *dev) +{ + struct pci_dev *pci_dev = to_pci_dev(dev); + pr_debug("runtime_suspend called\n"); + return intel_sst_suspend(pci_dev, PMSG_SUSPEND); +} + +static int intel_sst_runtime_resume(struct device *dev) +{ + struct pci_dev *pci_dev = to_pci_dev(dev); + pr_debug("runtime_resume called\n"); + return intel_sst_resume(pci_dev); +} + +static int intel_sst_runtime_idle(struct device *dev) +{ + pr_debug("runtime_idle called\n"); + if (sst_drv_ctx->stream_cnt == 0 && sst_drv_ctx->am_cnt == 0) + pm_schedule_suspend(dev, SST_SUSPEND_DELAY); + return -EBUSY; +} + +static const struct dev_pm_ops intel_sst_pm = { + .runtime_suspend = intel_sst_runtime_suspend, + .runtime_resume = intel_sst_runtime_resume, + .runtime_idle = intel_sst_runtime_idle, +}; + /* PCI Routines */ static struct pci_device_id intel_sst_ids[] = { { PCI_VDEVICE(INTEL, SST_MRST_PCI_ID), 3}, @@ -470,6 +504,9 @@ static struct pci_driver driver = { #ifdef CONFIG_PM .suspend = intel_sst_suspend, .resume = intel_sst_resume, + .driver = { + .pm = &intel_sst_pm, + }, #endif }; diff --git a/drivers/staging/intel_sst/intel_sst_app_interface.c b/drivers/staging/intel_sst/intel_sst_app_interface.c index c1ca39ef3646..4b316ccab411 100644 --- a/drivers/staging/intel_sst/intel_sst_app_interface.c +++ b/drivers/staging/intel_sst/intel_sst_app_interface.c @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #ifdef CONFIG_MRST_RAR_HANDLER @@ -103,8 +104,10 @@ int intel_sst_open(struct inode *i_node, struct file *file_ptr) unsigned int retval; mutex_lock(&sst_drv_ctx->stream_lock); + pm_runtime_get_sync(&sst_drv_ctx->pci->dev); retval = intel_sst_check_device(); if (retval) { + pm_runtime_put(&sst_drv_ctx->pci->dev); mutex_unlock(&sst_drv_ctx->stream_lock); return retval; } @@ -113,6 +116,7 @@ int intel_sst_open(struct inode *i_node, struct file *file_ptr) struct ioctl_pvt_data *data = kzalloc(sizeof(struct ioctl_pvt_data), GFP_KERNEL); if (!data) { + pm_runtime_put(&sst_drv_ctx->pci->dev); mutex_unlock(&sst_drv_ctx->stream_lock); return -ENOMEM; } @@ -125,6 +129,7 @@ int intel_sst_open(struct inode *i_node, struct file *file_ptr) pr_debug("pvt_id handle = %d!\n", data->pvt_id); } else { retval = -EUSERS; + pm_runtime_put(&sst_drv_ctx->pci->dev); mutex_unlock(&sst_drv_ctx->stream_lock); } return retval; @@ -147,8 +152,10 @@ int intel_sst_open_cntrl(struct inode *i_node, struct file *file_ptr) /* audio manager open */ mutex_lock(&sst_drv_ctx->stream_lock); + pm_runtime_get_sync(&sst_drv_ctx->pci->dev); retval = intel_sst_check_device(); if (retval) { + pm_runtime_put(&sst_drv_ctx->pci->dev); mutex_unlock(&sst_drv_ctx->stream_lock); return retval; } @@ -157,8 +164,10 @@ int intel_sst_open_cntrl(struct inode *i_node, struct file *file_ptr) sst_drv_ctx->am_cnt++; pr_debug("AM handle opened...\n"); file_ptr->private_data = NULL; - } else + } else { retval = -EACCES; + pm_runtime_put(&sst_drv_ctx->pci->dev); + } mutex_unlock(&sst_drv_ctx->stream_lock); return retval; @@ -181,6 +190,7 @@ int intel_sst_release(struct inode *i_node, struct file *file_ptr) mutex_lock(&sst_drv_ctx->stream_lock); sst_drv_ctx->encoded_cnt--; sst_drv_ctx->stream_cnt--; + pm_runtime_put(&sst_drv_ctx->pci->dev); mutex_unlock(&sst_drv_ctx->stream_lock); free_stream_context(data->str_id); kfree(data); @@ -192,6 +202,7 @@ int intel_sst_release_cntrl(struct inode *i_node, struct file *file_ptr) /* audio manager close */ mutex_lock(&sst_drv_ctx->stream_lock); sst_drv_ctx->am_cnt--; + pm_runtime_put(&sst_drv_ctx->pci->dev); mutex_unlock(&sst_drv_ctx->stream_lock); pr_debug("AM handle closed\n"); return 0; diff --git a/drivers/staging/intel_sst/intel_sst_common.h b/drivers/staging/intel_sst/intel_sst_common.h index dcc1ebbe1ac6..a82882423d2d 100644 --- a/drivers/staging/intel_sst/intel_sst_common.h +++ b/drivers/staging/intel_sst/intel_sst_common.h @@ -37,6 +37,7 @@ #define SST_FW_FILENAME_MFLD "fw_sst_082f.bin" #define SST_MRST_PCI_ID 0x080A #define SST_MFLD_PCI_ID 0x082F +#define SST_SUSPEND_DELAY 2000 enum sst_states { SST_FW_LOADED = 1, diff --git a/drivers/staging/intel_sst/intel_sst_drv_interface.c b/drivers/staging/intel_sst/intel_sst_drv_interface.c index 9ecbff60cacf..f91c914ba209 100644 --- a/drivers/staging/intel_sst/intel_sst_drv_interface.c +++ b/drivers/staging/intel_sst/intel_sst_drv_interface.c @@ -32,6 +32,7 @@ #include #include #include +#include #include "intel_sst.h" #include "intel_sst_ioctl.h" #include "intel_sst_fw_ipc.h" @@ -310,12 +311,15 @@ int sst_open_pcm_stream(struct snd_sst_params *str_param) struct stream_info *str_info; int retval; + pm_runtime_get_sync(&sst_drv_ctx->pci->dev); + if (sst_drv_ctx->sst_state == SST_SUSPENDED) { - /*LPE is suspended, resume it before proceding*/ + /* LPE is suspended, resume it before proceding*/ pr_debug("Resuming from Suspended state\n"); retval = intel_sst_resume(sst_drv_ctx->pci); if (retval) { pr_err("Resume Failed = %#x, abort\n", retval); + pm_runtime_put(&sst_drv_ctx->pci->dev); return retval; } } @@ -325,20 +329,25 @@ int sst_open_pcm_stream(struct snd_sst_params *str_param) retval = sst_download_fw(); if (retval) { pr_err("FW download fail %x, abort\n", retval); + pm_runtime_put(&sst_drv_ctx->pci->dev); return retval; } send_intial_rx_timeslot(); } - if (!str_param) + if (!str_param) { + pm_runtime_put(&sst_drv_ctx->pci->dev); return -EINVAL; + } retval = sst_get_stream(str_param); if (retval > 0) { sst_drv_ctx->stream_cnt++; str_info = &sst_drv_ctx->streams[retval]; str_info->src = MAD_DRV; - } + } else + pm_runtime_put(&sst_drv_ctx->pci->dev); + return retval; } @@ -364,6 +373,7 @@ int sst_close_pcm_stream(unsigned int str_id) stream->period_elapsed = NULL; sst_drv_ctx->stream_cnt--; pr_debug("sst: will call runtime put now\n"); + pm_runtime_put(&sst_drv_ctx->pci->dev); return 0; } diff --git a/drivers/staging/intel_sst/intel_sst_dsp.c b/drivers/staging/intel_sst/intel_sst_dsp.c index d1b0537cf4b8..6e5c9152da9f 100644 --- a/drivers/staging/intel_sst/intel_sst_dsp.c +++ b/drivers/staging/intel_sst/intel_sst_dsp.c @@ -51,7 +51,8 @@ static int intel_sst_reset_dsp_mrst(void) union config_status_reg csr; pr_debug("Resetting the DSP in mrst\n"); - csr.full = 0x3a2; + csr.full = sst_shim_read(sst_drv_ctx->shim, SST_CSR); + csr.full |= 0x382; sst_shim_write(sst_drv_ctx->shim, SST_CSR, csr.full); csr.full = sst_shim_read(sst_drv_ctx->shim, SST_CSR); csr.part.strb_cntr_rst = 0; diff --git a/drivers/staging/intel_sst/intel_sst_ipc.c b/drivers/staging/intel_sst/intel_sst_ipc.c index 993c5333e906..5aa92ba9018c 100644 --- a/drivers/staging/intel_sst/intel_sst_ipc.c +++ b/drivers/staging/intel_sst/intel_sst_ipc.c @@ -182,6 +182,7 @@ int process_fw_init(struct sst_ipc_msg_wq *msg) sst_send_sound_card_type(); mutex_lock(&sst_drv_ctx->sst_lock); sst_drv_ctx->sst_state = SST_FW_RUNNING; + sst_drv_ctx->lpe_stalled = 0; mutex_unlock(&sst_drv_ctx->sst_lock); pr_debug("FW Version %x.%x\n", init->fw_version.major, init->fw_version.minor); -- cgit v1.2.3 From 79a35ad57300f78c7250eeeca57b602e06ff402a Mon Sep 17 00:00:00 2001 From: Vinod Koul Date: Mon, 22 Nov 2010 10:33:40 +0000 Subject: Staging: sst: Construct fw string name runtime The firmware name for each platform is appended by PCI id of device. This patch makes use of pci id to construct the string rather than hardcode the string. Signed-off-by: Vinod Koul Signed-off-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/staging/intel_sst/intel_sst_common.h | 3 +-- drivers/staging/intel_sst/intel_sst_drv_interface.c | 11 ++++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/staging/intel_sst/intel_sst_common.h b/drivers/staging/intel_sst/intel_sst_common.h index a82882423d2d..e0c6339ca0ae 100644 --- a/drivers/staging/intel_sst/intel_sst_common.h +++ b/drivers/staging/intel_sst/intel_sst_common.h @@ -33,10 +33,9 @@ /* driver names */ #define SST_DRV_NAME "intel_sst_driver" -#define SST_FW_FILENAME_MRST "fw_sst_080a.bin" -#define SST_FW_FILENAME_MFLD "fw_sst_082f.bin" #define SST_MRST_PCI_ID 0x080A #define SST_MFLD_PCI_ID 0x082F +#define PCI_ID_LENGTH 4 #define SST_SUSPEND_DELAY 2000 enum sst_states { diff --git a/drivers/staging/intel_sst/intel_sst_drv_interface.c b/drivers/staging/intel_sst/intel_sst_drv_interface.c index f91c914ba209..ea8e251b5099 100644 --- a/drivers/staging/intel_sst/intel_sst_drv_interface.c +++ b/drivers/staging/intel_sst/intel_sst_drv_interface.c @@ -48,13 +48,14 @@ int sst_download_fw(void) { int retval; const struct firmware *fw_sst; - const char *name; + char name[20]; + if (sst_drv_ctx->sst_state != SST_UN_INIT) return -EPERM; - if (sst_drv_ctx->pci_id == SST_MRST_PCI_ID) - name = SST_FW_FILENAME_MRST; - else - name = SST_FW_FILENAME_MFLD; + + snprintf(name, sizeof(name), "%s%04x%s", "fw_sst_", + sst_drv_ctx->pci_id, ".bin"); + pr_debug("Downloading %s FW now...\n", name); retval = request_firmware(&fw_sst, name, &sst_drv_ctx->pci->dev); if (retval) { -- cgit v1.2.3 From 62877913ba55b3f2e5ac34dbc1a2975868ea8d25 Mon Sep 17 00:00:00 2001 From: Vinod Koul Date: Mon, 22 Nov 2010 10:33:51 +0000 Subject: Staging: sst: add ioctls for post processing algorithm interface This patch adds two new ioctls to intel_sst_ctrl device. This i/f can be used by application to send algorithm parameters Signed-off-by: Vinod Koul [This will need further discussion in the context of the final ALSA interface but is fine for staging, ie anyone who relies on it should expect changes Also fixed a missing kmalloc fail check] Signed-off-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/staging/intel_sst/intel_sst.c | 27 ++-- .../staging/intel_sst/intel_sst_app_interface.c | 143 +++++++++++++++++++++ drivers/staging/intel_sst/intel_sst_common.h | 2 +- drivers/staging/intel_sst/intel_sst_fw_ipc.h | 2 + drivers/staging/intel_sst/intel_sst_ioctl.h | 15 +-- drivers/staging/intel_sst/intel_sst_ipc.c | 49 +++++++ 6 files changed, 215 insertions(+), 23 deletions(-) diff --git a/drivers/staging/intel_sst/intel_sst.c b/drivers/staging/intel_sst/intel_sst.c index bd92549893a6..ce4a9f79ccd2 100644 --- a/drivers/staging/intel_sst/intel_sst.c +++ b/drivers/staging/intel_sst/intel_sst.c @@ -306,19 +306,19 @@ static int __devinit intel_sst_probe(struct pci_dev *pci, goto do_unmap_dram; pr_debug("Registered IRQ 0x%x\n", pci->irq); + /*Register LPE Control as misc driver*/ + ret = misc_register(&lpe_ctrl); + if (ret) { + pr_err("couldn't register control device\n"); + goto do_free_irq; + } + if (sst_drv_ctx->pci_id == SST_MRST_PCI_ID) { ret = misc_register(&lpe_dev); if (ret) { - pr_err("couldn't register LPE device\n"); - goto do_free_irq; - } - - /*Register LPE Control as misc driver*/ - ret = misc_register(&lpe_ctrl); - if (ret) { - pr_err("couldn't register misc driver\n"); - goto do_free_irq; - } + pr_err("couldn't register misc driver\n"); + goto do_free_misc; + } } sst_drv_ctx->lpe_stalled = 0; pm_runtime_set_active(&pci->dev); @@ -327,6 +327,8 @@ static int __devinit intel_sst_probe(struct pci_dev *pci, pr_debug("...successfully done!!!\n"); return ret; +do_free_misc: + misc_deregister(&lpe_ctrl); do_free_irq: free_irq(pci->irq, sst_drv_ctx); do_unmap_dram: @@ -371,10 +373,9 @@ static void __devexit intel_sst_remove(struct pci_dev *pci) mutex_lock(&sst_drv_ctx->sst_lock); sst_drv_ctx->sst_state = SST_UN_INIT; mutex_unlock(&sst_drv_ctx->sst_lock); - if (sst_drv_ctx->pci_id == SST_MRST_PCI_ID) { + misc_deregister(&lpe_ctrl); + if (sst_drv_ctx->pci_id == SST_MRST_PCI_ID) misc_deregister(&lpe_dev); - misc_deregister(&lpe_ctrl); - } free_irq(pci->irq, sst_drv_ctx); iounmap(sst_drv_ctx->dram); iounmap(sst_drv_ctx->iram); diff --git a/drivers/staging/intel_sst/intel_sst_app_interface.c b/drivers/staging/intel_sst/intel_sst_app_interface.c index 4b316ccab411..ce2c755a1766 100644 --- a/drivers/staging/intel_sst/intel_sst_app_interface.c +++ b/drivers/staging/intel_sst/intel_sst_app_interface.c @@ -827,6 +827,141 @@ static void sst_print_stream_params(struct snd_sst_get_stream_params *get_prm) return; } +/** + * sst_create_algo_ipc - create ipc msg for algorithm parameters + * + * @algo_params: Algorithm parameters + * @msg: post msg pointer + * + * This function is called to create ipc msg + */ +int sst_create_algo_ipc(struct snd_ppp_params *algo_params, + struct ipc_post **msg) +{ + if (sst_create_large_msg(msg)) + return -ENOMEM; + sst_fill_header(&(*msg)->header, + IPC_IA_ALG_PARAMS, 1, algo_params->str_id); + (*msg)->header.part.data = sizeof(u32) + + sizeof(*algo_params) + algo_params->size; + memcpy((*msg)->mailbox_data, &(*msg)->header, sizeof(u32)); + memcpy((*msg)->mailbox_data + sizeof(u32), + algo_params, sizeof(*algo_params)); + return 0; +} + +/** + * sst_send_algo_ipc - send ipc msg for algorithm parameters + * + * @msg: post msg pointer + * + * This function is called to send ipc msg + */ +int sst_send_algo_ipc(struct ipc_post **msg) +{ + sst_drv_ctx->ppp_params_blk.condition = false; + sst_drv_ctx->ppp_params_blk.ret_code = 0; + sst_drv_ctx->ppp_params_blk.on = true; + sst_drv_ctx->ppp_params_blk.data = NULL; + spin_lock(&sst_drv_ctx->list_spin_lock); + list_add_tail(&(*msg)->node, &sst_drv_ctx->ipc_dispatch_list); + spin_unlock(&sst_drv_ctx->list_spin_lock); + sst_post_message(&sst_drv_ctx->ipc_post_msg_wq); + return sst_wait_interruptible_timeout(sst_drv_ctx, + &sst_drv_ctx->ppp_params_blk, SST_BLOCK_TIMEOUT); +} + +/** + * intel_sst_ioctl_dsp - recieves the device ioctl's + * + * @cmd:Ioctl cmd + * @arg:data + * + * This function is called when a user space component + * sends a DSP Ioctl to SST driver + */ +long intel_sst_ioctl_dsp(unsigned int cmd, unsigned long arg) +{ + int retval = 0; + struct snd_ppp_params algo_params; + struct snd_ppp_params *algo_params_copied; + struct ipc_post *msg; + + switch (_IOC_NR(cmd)) { + case _IOC_NR(SNDRV_SST_SET_ALGO): + if (copy_from_user(&algo_params, (void __user *)arg, + sizeof(algo_params))) + return -EFAULT; + if (algo_params.size > SST_MAILBOX_SIZE) + return -EMSGSIZE; + + pr_debug("Algo ID %d Str id %d Enable %d Size %d\n", + algo_params.algo_id, algo_params.str_id, + algo_params.enable, algo_params.size); + retval = sst_create_algo_ipc(&algo_params, &msg); + if (retval) + break; + algo_params.reserved = 0; + if (copy_from_user(msg->mailbox_data + sizeof(algo_params), + algo_params.params, algo_params.size)) + return -EFAULT; + + retval = sst_send_algo_ipc(&msg); + if (retval) { + pr_debug("Error in sst_set_algo = %d\n", retval); + retval = -EIO; + } + break; + + case _IOC_NR(SNDRV_SST_GET_ALGO): + if (copy_from_user(&algo_params, (void __user *)arg, + sizeof(algo_params))) + return -EFAULT; + pr_debug("Algo ID %d Str id %d Enable %d Size %d\n", + algo_params.algo_id, algo_params.str_id, + algo_params.enable, algo_params.size); + retval = sst_create_algo_ipc(&algo_params, &msg); + if (retval) + break; + algo_params.reserved = 1; + retval = sst_send_algo_ipc(&msg); + if (retval) { + pr_debug("Error in sst_get_algo = %d\n", retval); + retval = -EIO; + break; + } + algo_params_copied = (struct snd_ppp_params *) + sst_drv_ctx->ppp_params_blk.data; + if (algo_params_copied->size > algo_params.size) { + pr_debug("mem insufficient to copy\n"); + retval = -EMSGSIZE; + goto free_mem; + } else { + char __user *tmp; + + if (copy_to_user(algo_params.params, + algo_params_copied->params, + algo_params_copied->size)) { + retval = -EFAULT; + goto free_mem; + } + tmp = (char __user *)arg + offsetof( + struct snd_ppp_params, size); + if (copy_to_user(tmp, &algo_params_copied->size, + sizeof(__u32))) { + retval = -EFAULT; + goto free_mem; + } + + } +free_mem: + kfree(algo_params_copied->params); + kfree(algo_params_copied); + break; + } + return retval; +} + /** * intel_sst_ioctl - receives the device ioctl's * @file_ptr:pointer to file @@ -1270,6 +1405,14 @@ free_iobufs: kfree(fw_info); break; } + case _IOC_NR(SNDRV_SST_GET_ALGO): + case _IOC_NR(SNDRV_SST_SET_ALGO): + if (minor != AM_MODULE) { + retval = -EBADRQC; + break; + } + retval = intel_sst_ioctl_dsp(cmd, arg); + break; default: retval = -EINVAL; } diff --git a/drivers/staging/intel_sst/intel_sst_common.h b/drivers/staging/intel_sst/intel_sst_common.h index e0c6339ca0ae..0a60e865b696 100644 --- a/drivers/staging/intel_sst/intel_sst_common.h +++ b/drivers/staging/intel_sst/intel_sst_common.h @@ -392,7 +392,7 @@ struct intel_sst_drv { struct stream_info streams[MAX_NUM_STREAMS]; struct stream_alloc_block alloc_block[MAX_ACTIVE_STREAM]; - struct sst_block tgt_dev_blk, fw_info_blk, + struct sst_block tgt_dev_blk, fw_info_blk, ppp_params_blk, vol_info_blk, mute_info_blk, hs_info_blk; struct mutex list_lock;/* mutex for IPC list locking */ spinlock_t list_spin_lock; /* mutex for IPC list locking */ diff --git a/drivers/staging/intel_sst/intel_sst_fw_ipc.h b/drivers/staging/intel_sst/intel_sst_fw_ipc.h index 75c187672450..8df313d10d2a 100644 --- a/drivers/staging/intel_sst/intel_sst_fw_ipc.h +++ b/drivers/staging/intel_sst/intel_sst_fw_ipc.h @@ -68,6 +68,8 @@ #define IPC_IA_CAPT_VOICE 0x17 #define IPC_IA_DECODE_FRAMES 0x18 +#define IPC_IA_ALG_PARAMS 0x1A + /* I2L Stream config/control msgs */ #define IPC_IA_ALLOC_STREAM 0x20 /* Allocate a stream ID */ #define IPC_IA_FREE_STREAM 0x21 /* Free the stream ID */ diff --git a/drivers/staging/intel_sst/intel_sst_ioctl.h b/drivers/staging/intel_sst/intel_sst_ioctl.h index 03b931619a3e..bebc395a3c1f 100644 --- a/drivers/staging/intel_sst/intel_sst_ioctl.h +++ b/drivers/staging/intel_sst/intel_sst_ioctl.h @@ -190,21 +190,15 @@ struct snd_prp_params { __u32 reserved; /* No pre-processing defined yet */ }; -struct snd_params_block { - __u32 type; /*Type of the parameter*/ - __u32 size; /*size of the parameters in the block*/ - __u8 params[0]; /*Parameters of the algorithm*/ -}; - /* Pre and post processing params structure */ struct snd_ppp_params { - enum sst_algo_types algo_id;/* Post/Pre processing algorithm ID */ + __u8 algo_id;/* Post/Pre processing algorithm ID */ __u8 str_id; /*Only 5 bits used 0 - 31 are valid*/ __u8 enable; /* 0= disable, 1= enable*/ __u8 reserved; __u32 size; /*Size of parameters for all blocks*/ - struct snd_params_block params[0]; -}; + void *params; +} __attribute__ ((packed)); struct snd_sst_postproc_info { __u32 src_min; /* Supported SRC Min sampling freq */ @@ -431,5 +425,8 @@ struct snd_sst_dbufs { #define SNDRV_SST_FW_INFO _IOR('L', 0x20, struct snd_sst_fw_info *) #define SNDRV_SST_SET_TARGET_DEVICE _IOW('L', 0x21, \ struct snd_sst_target_device *) +/*DSP Ioctls on /dev/intel_sst_ctrl only*/ +#define SNDRV_SST_SET_ALGO _IOW('L', 0x30, struct snd_ppp_params *) +#define SNDRV_SST_GET_ALGO _IOWR('L', 0x31, struct snd_ppp_params *) #endif /* __INTEL_SST_IOCTL_H__ */ diff --git a/drivers/staging/intel_sst/intel_sst_ipc.c b/drivers/staging/intel_sst/intel_sst_ipc.c index 5aa92ba9018c..0742dde2685d 100644 --- a/drivers/staging/intel_sst/intel_sst_ipc.c +++ b/drivers/staging/intel_sst/intel_sst_ipc.c @@ -336,6 +336,55 @@ void sst_process_reply(struct work_struct *work) wake_up(&sst_drv_ctx->wait_queue); } break; + case IPC_IA_ALG_PARAMS: { + pr_debug("sst:IPC_ALG_PARAMS response %x\n", msg->header.full); + pr_debug("sst: data value %x\n", msg->header.part.data); + pr_debug("sst: large value %x\n", msg->header.part.large); + + if (!msg->header.part.large) { + if (!msg->header.part.data) { + pr_debug("sst: alg set success\n"); + sst_drv_ctx->ppp_params_blk.ret_code = 0; + } else { + pr_debug("sst: alg set failed\n"); + sst_drv_ctx->ppp_params_blk.ret_code = + -msg->header.part.data; + } + + } else if (msg->header.part.data) { + struct snd_ppp_params *mailbox_params, *get_params; + char *params; + + pr_debug("sst: alg get success\n"); + mailbox_params = (struct snd_ppp_params *)msg->mailbox; + get_params = kzalloc(sizeof(*get_params), GFP_KERNEL); + if (get_params == NULL) { + pr_err("sst: out of memory for ALG PARAMS"); + break; + } + memcpy_fromio(get_params, mailbox_params, + sizeof(*get_params)); + get_params->params = kzalloc(mailbox_params->size, + GFP_KERNEL); + if (get_params->params == NULL) { + kfree(get_params); + pr_err("sst: out of memory for ALG PARAMS block"); + break; + } + params = msg->mailbox; + params = params + sizeof(*mailbox_params) - sizeof(u32); + memcpy_fromio(get_params->params, params, + get_params->size); + sst_drv_ctx->ppp_params_blk.ret_code = 0; + sst_drv_ctx->ppp_params_blk.data = get_params; + } + + if (sst_drv_ctx->ppp_params_blk.on == true) { + sst_drv_ctx->ppp_params_blk.condition = true; + wake_up(&sst_drv_ctx->wait_queue); + } + break; + } case IPC_IA_GET_FW_INFO: { struct snd_sst_fw_info *fw_info = (struct snd_sst_fw_info *)msg->mailbox; -- cgit v1.2.3 From de92e3a3b25dd0cda00a07b30c325785b5c2d939 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Wed, 24 Nov 2010 19:33:26 +0000 Subject: Staging: sep: minimal fix for wrong include Signed-off-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/staging/sep/sep_driver_config.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/sep/sep_driver_config.h b/drivers/staging/sep/sep_driver_config.h index 686a353c8c98..68688cbc2a92 100644 --- a/drivers/staging/sep/sep_driver_config.h +++ b/drivers/staging/sep/sep_driver_config.h @@ -421,7 +421,7 @@ struct RAR_buffer { #else /* using real RAR_REGISTER */ -#include "../rar_register/rar_register.h" +#include #endif /* CONFIG_RAR_REGISTER */ -- cgit v1.2.3 From 62a8c3a32e4143812ed8e0f3783ef1ea40dc87e4 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Wed, 24 Nov 2010 19:33:43 +0000 Subject: Staging: sep: handle the rar definition stuff in the header SEP isn't the only driver that may need to handle both cases easily Signed-off-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/staging/sep/sep_driver.c | 1 + drivers/staging/sep/sep_driver_config.h | 61 --------------------------------- include/linux/rar_register.h | 16 +++++++++ 3 files changed, 17 insertions(+), 61 deletions(-) diff --git a/drivers/staging/sep/sep_driver.c b/drivers/staging/sep/sep_driver.c index ef36239c7b24..8a1ff861b135 100644 --- a/drivers/staging/sep/sep_driver.c +++ b/drivers/staging/sep/sep_driver.c @@ -53,6 +53,7 @@ #include #include #include +#include #include #include diff --git a/drivers/staging/sep/sep_driver_config.h b/drivers/staging/sep/sep_driver_config.h index 68688cbc2a92..cfda86f2aaff 100644 --- a/drivers/staging/sep/sep_driver_config.h +++ b/drivers/staging/sep/sep_driver_config.h @@ -235,15 +235,6 @@ held by the proccess (struct file) */ /* This stub header is for non Moorestown driver only */ -/* - * Constants that specify different kinds of RAR regions that could be - * set up. - */ -static __u32 const RAR_TYPE_VIDEO; /* 0 */ -static __u32 const RAR_TYPE_AUDIO = 1; -static __u32 const RAR_TYPE_IMAGE = 2; -static __u32 const RAR_TYPE_DATA = 3; - /* * @struct RAR_stat * @@ -373,56 +364,4 @@ struct RAR_buffer { #endif /* MEMRAR */ -/* rar_register */ -#ifndef CONFIG_RAR_REGISTER -/* This stub header is for non Moorestown driver only */ - -/* The register_rar function is to used by other device drivers - * to ensure that this driver is ready. As we cannot be sure of - * the compile/execute order of dirvers in ther kernel, it is - * best to give this driver a callback function to call when - * it is ready to give out addresses. The callback function - * would have those steps that continue the initialization of - * a driver that do require a valid RAR address. One of those - * steps would be to call get_rar_address() - * This function return 0 on success an -1 on failure. - */ -#define register_rar(a, b, c) (-ENODEV) - -/* The get_rar_address function is used by other device drivers - * to obtain RAR address information on a RAR. It takes two - * parameter: - * - * int rar_index - * The rar_index is an index to the rar for which you wish to retrieve - * the address information. - * Values can be 0,1, or 2. - * - * struct RAR_address_struct is a pointer to a place to which the function - * can return the address structure for the RAR. - * - * The function returns a 0 upon success or a -1 if there is no RAR - * facility on this system. - */ -#define rar_get_address(a, b, c) (-ENODEV) - -/* The lock_rar function is ued by other device drivers to lock an RAR. - * once an RAR is locked, it stays locked until the next system reboot. - * The function takes one parameter: - * - * int rar_index - * The rar_index is an index to the rar that you want to lock. - * Values can be 0,1, or 2. - * - * The function returns a 0 upon success or a -1 if there is no RAR - * facility on this system. - */ -#define rar_lock(a) (-1) - -#else /* using real RAR_REGISTER */ - -#include - -#endif /* CONFIG_RAR_REGISTER */ - #endif /* SEP DRIVER CONFIG */ diff --git a/include/linux/rar_register.h b/include/linux/rar_register.h index ffa805780f85..5c6118189363 100644 --- a/include/linux/rar_register.h +++ b/include/linux/rar_register.h @@ -34,11 +34,27 @@ struct rar_device; +#if defined(CONFIG_RAR_REGISTER) int register_rar(int num, int (*callback)(unsigned long data), unsigned long data); void unregister_rar(int num); int rar_get_address(int rar_index, dma_addr_t *start, dma_addr_t *end); int rar_lock(int rar_index); +#else +extern void unregister_rar(int num) { } +extern int rar_lock(int rar_index) { return -EIO; } + +extern inline int register_rar(int num, + int (*callback)(unsigned long data), unsigned long data) +{ + return -ENODEV; +} + +extern int rar_get_address(int rar_index, dma_addr_t *start, dma_addr_t *end) +{ + return -ENODEV; +} +#endif /* RAR_REGISTER */ #endif /* __KERNEL__ */ #endif /* _RAR_REGISTER_H */ -- cgit v1.2.3 From 266aa856f2c3aeddadd2fcf186d119af10539c3e Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Wed, 24 Nov 2010 19:33:55 +0000 Subject: Staging: sep: handle the memrar stuff in the headers Signed-off-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/staging/memrar/memrar.h | 19 +++++ drivers/staging/sep/sep_driver.c | 2 + drivers/staging/sep/sep_driver_config.h | 133 -------------------------------- 3 files changed, 21 insertions(+), 133 deletions(-) diff --git a/drivers/staging/memrar/memrar.h b/drivers/staging/memrar/memrar.h index 0b735b827c09..0feb73b94c91 100644 --- a/drivers/staging/memrar/memrar.h +++ b/drivers/staging/memrar/memrar.h @@ -95,6 +95,7 @@ struct RAR_buffer { dma_addr_t bus_address; }; +#if defined(CONFIG_MRST_RAR_HANDLER) /** * rar_reserve() - reserve RAR buffers * @buffers: array of RAR_buffers where type and size of buffers to @@ -149,7 +150,25 @@ extern size_t rar_release(struct RAR_buffer *buffers, extern size_t rar_handle_to_bus(struct RAR_buffer *buffers, size_t count); +#else +extern inline size_t rar_reserve(struct RAR_buffer *buffers, size_t count) +{ + return 0; +} + +extern inline size_t rar_release(struct RAR_buffer *buffers, size_t count) +{ + return 0; +} + +extern inline size_t rar_handle_to_bus(struct RAR_buffer *buffers, + size_t count) +{ + return 0; +} + +#endif /* MRST_RAR_HANDLER */ #endif /* __KERNEL__ */ #endif /* _MEMRAR_H */ diff --git a/drivers/staging/sep/sep_driver.c b/drivers/staging/sep/sep_driver.c index 8a1ff861b135..b2cf553da341 100644 --- a/drivers/staging/sep/sep_driver.c +++ b/drivers/staging/sep/sep_driver.c @@ -59,6 +59,8 @@ #include #include +#include "../memrar/memrar.h" + #include "sep_driver_hw_defs.h" #include "sep_driver_config.h" #include "sep_driver_api.h" diff --git a/drivers/staging/sep/sep_driver_config.h b/drivers/staging/sep/sep_driver_config.h index cfda86f2aaff..b96045f178cd 100644 --- a/drivers/staging/sep/sep_driver_config.h +++ b/drivers/staging/sep/sep_driver_config.h @@ -230,138 +230,5 @@ held by the proccess (struct file) */ /* the token that defines the data pool pointers address */ #define SEP_EXT_CACHE_ADDR_VAL_TOKEN 0xBABABABA -/* rar handler */ -#ifndef CONFIG_MRST_RAR_HANDLER - -/* This stub header is for non Moorestown driver only */ - -/* - * @struct RAR_stat - * - * @brief This structure is used for @c RAR_HANDLER_STAT ioctl and for - * @c RAR_get_stat() user space wrapper function. - */ -struct RAR_stat { - /* Type of RAR memory (e.g., audio vs. video) */ - __u32 type; - - /* - * Total size of RAR memory region. - */ - __u32 capacity; - - /* Size of the largest reservable block. */ - __u32 largest_block_size; -}; - - -/* - * @struct RAR_block_info - * - * @brief The argument for the @c RAR_HANDLER_RESERVE @c ioctl. - * - */ -struct RAR_block_info { - /* Type of RAR memory (e.g., audio vs. video) */ - __u32 type; - - /* Requested size of a block to be reserved in RAR. */ - __u32 size; - - /* Handle that can be used to refer to reserved block. */ - __u32 handle; -}; - -/* - * @struct RAR_buffer - * - * Structure that contains all information related to a given block of - * memory in RAR. It is generally only used when retrieving bus - * addresses. - * - * @note This structure is used only by RAR-enabled drivers, and is - * not intended to be exposed to the user space. - */ -struct RAR_buffer { - /* Structure containing base RAR buffer information */ - struct RAR_block_info info; - - /* Buffer bus address */ - __u32 bus_address; -}; - - -#define RAR_IOCTL_BASE 0xE0 - -/* Reserve RAR block. */ -#define RAR_HANDLER_RESERVE _IOWR(RAR_IOCTL_BASE, 0x00, struct RAR_block_info) - -/* Release previously reserved RAR block. */ -#define RAR_HANDLER_RELEASE _IOW(RAR_IOCTL_BASE, 0x01, __u32) - -/* Get RAR stats. */ -#define RAR_HANDLER_STAT _IOWR(RAR_IOCTL_BASE, 0x02, struct RAR_stat) - - -/* -------------------------------------------------------------- */ -/* Kernel Side RAR Handler Interface */ -/* -------------------------------------------------------------- */ - -/* - * @function rar_reserve - * - * @brief Reserve RAR buffers. - * - * This function will reserve buffers in the restricted access regions - * of given types. - * - * @return Number of successfully reserved buffers. - * Successful buffer reservations will have the corresponding - * @c bus_address field set to a non-zero value in the - * given @a buffers vector. - */ -#define rar_reserve(a, b) ((size_t)NULL) - -/* - * @function rar_release - * - * @brief Release RAR buffers retrieved through call to - * @c rar_reserve() or @c rar_handle_to_bus(). - * - * This function will release RAR buffers that were retrieved through - * a call to @c rar_reserve() or @c rar_handle_to_bus() by - * decrementing the reference count. The RAR buffer will be reclaimed - * when the reference count drops to zero. - * - * @return Number of successfully released buffers. - * Successful releases will have their handle field set to - * zero in the given @a buffers vector. - */ -#define rar_release(a, b) ((size_t)NULL) - -/* - * @function rar_handle_to_bus - * - * @brief Convert a vector of RAR handles to bus addresses. - * - * This function will retrieve the RAR buffer bus addresses, type and - * size corresponding to the RAR handles provided in the @a buffers - * vector. - * - * @return Number of successfully converted buffers. - * The bus address will be set to @c 0 for unrecognized - * handles. - * - * @note The reference count for each corresponding buffer in RAR will - * be incremented. Call @c rar_release() when done with the - * buffers. - */ -#define rar_handle_to_bus(a, b) ((size_t)NULL) - -#else /* using rear memrar */ - -#include "../memrar/memrar.h" - -#endif /* MEMRAR */ #endif /* SEP DRIVER CONFIG */ -- cgit v1.2.3 From 8d80e4e2da31be71b8c1a5def986e10831d2aada Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Wed, 24 Nov 2010 19:34:08 +0000 Subject: Staging: sep: netlink - what netlink Kill unused stuff Signed-off-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/staging/sep/sep_driver.c | 24 +----------------------- 1 file changed, 1 insertion(+), 23 deletions(-) diff --git a/drivers/staging/sep/sep_driver.c b/drivers/staging/sep/sep_driver.c index b2cf553da341..38b2db49c403 100644 --- a/drivers/staging/sep/sep_driver.c +++ b/drivers/staging/sep/sep_driver.c @@ -55,10 +55,6 @@ #include #include -#include -#include -#include - #include "../memrar/memrar.h" #include "sep_driver_hw_defs.h" @@ -943,23 +939,11 @@ static unsigned long sep_set_time(struct sep_device *sep) */ static int sep_init_caller_id(struct sep_device *sep) { - /* return value */ - int ret_val; - - /* counter */ int counter; - struct cb_id caller_id; - dev_dbg(&sep->pdev->dev, "sep_init_caller_id start\n"); - ret_val = 0; - - /* init cb_id struct */ - caller_id.idx = CN_IDX_PROC; - caller_id.val = CN_VAL_PROC; - /** * init caller id table * note that locking is not needed here as this function is @@ -975,16 +959,10 @@ static int sep_init_caller_id(struct sep_device *sep) dev_dbg(&sep->pdev->dev, "caller id table init finished\n"); - /* register to netlink connector */ - - if (ret_val) - dev_warn(&sep->pdev->dev, - "cn_add_callback failed %x\n", ret_val); - dev_dbg(&sep->pdev->dev, "sep_init_caller_id end\n"); - return ret_val; + return 0; } /** -- cgit v1.2.3 From 4c8e2a1f3d5e6b63ebfd26f324a2b24194af37fa Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Wed, 24 Nov 2010 19:34:25 +0000 Subject: Staging: sep: clean up caller_id function This is called on a kmalloc/memset object. Remove everything that isn't a set to zero Oh look 8) Signed-off-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/staging/sep/sep_driver.c | 42 ---------------------------------------- 1 file changed, 42 deletions(-) diff --git a/drivers/staging/sep/sep_driver.c b/drivers/staging/sep/sep_driver.c index 38b2db49c403..c98cb9b481bd 100644 --- a/drivers/staging/sep/sep_driver.c +++ b/drivers/staging/sep/sep_driver.c @@ -933,38 +933,6 @@ static unsigned long sep_set_time(struct sep_device *sep) return time.tv_sec; } -/** - * sep_init_caller_id - initializes the caller id functionality - * @sep: pointer to struct sep_device - */ -static int sep_init_caller_id(struct sep_device *sep) -{ - int counter; - - dev_dbg(&sep->pdev->dev, - "sep_init_caller_id start\n"); - - /** - * init caller id table - * note that locking is not needed here as this function is - * called prior to registering the device file - */ - for (counter = 0; counter < SEP_CALLER_ID_TABLE_NUM_ENTRIES; counter++) - sep->caller_id_table[counter].pid = 0; - - - /* init access flag */ - sep->singleton_access_flag = 0; - - dev_dbg(&sep->pdev->dev, - "caller id table init finished\n"); - - dev_dbg(&sep->pdev->dev, - "sep_init_caller_id end\n"); - - return 0; -} - /** * sep_set_caller_id_handler - inserts the data into the caller id table * note that this function does fall under the ioctl lock @@ -4056,16 +4024,6 @@ static int __init sep_init(void) mutex_init(&sep->sep_mutex); mutex_init(&sep->ioctl_mutex); - if (sep->mrst == 0) { - ret_val = sep_init_caller_id(sep); - if (ret_val) { - dev_warn(&sep->pdev->dev, - "cant init caller id\n"); - goto end_function_unregister_pci; - } - - } - /* new chip requires share area reconfigure */ if (sep->pdev->revision == 4) { /* only for new chip */ ret_val = sep_reconfig_shared_area(sep); -- cgit v1.2.3 From d1bb83213d5b7b3a4e3db59179917a433f82762c Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Wed, 24 Nov 2010 19:34:52 +0000 Subject: Staging: sep: Fix the kernel-doc in SEP The long blurb goes at the end Signed-off-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/staging/sep/sep_driver.c | 322 +++++++++++++++++++++++---------------- 1 file changed, 188 insertions(+), 134 deletions(-) diff --git a/drivers/staging/sep/sep_driver.c b/drivers/staging/sep/sep_driver.c index c98cb9b481bd..4a0bb4350424 100644 --- a/drivers/staging/sep/sep_driver.c +++ b/drivers/staging/sep/sep_driver.c @@ -78,9 +78,10 @@ static struct sep_device *sep_dev; /** * sep_load_firmware - copy firmware cache/resident + * @sep: pointer to struct sep_device we are loading + * * This functions copies the cache and resident from their source * location into destination shared memory. - * @sep: pointer to struct sep_device */ static int sep_load_firmware(struct sep_device *sep) @@ -228,10 +229,11 @@ static void sep_unmap_and_free_shared_area(struct sep_device *sep) /** * sep_shared_bus_to_virt - convert bus/virt addresses - * Returns virtual address inside the shared area according - * to the bus address. * @sep: pointer to struct sep_device * @bus_address: address to convert + * + * Returns virtual address inside the shared area according + * to the bus address. */ static void *sep_shared_bus_to_virt(struct sep_device *sep, @@ -244,6 +246,8 @@ static void *sep_shared_bus_to_virt(struct sep_device *sep, * open function for the singleton driver * @inode_ptr struct inode * * @file_ptr struct file * + * + * Called when the user opens the singleton device interface */ static int sep_singleton_open(struct inode *inode_ptr, struct file *file_ptr) @@ -252,8 +256,8 @@ static int sep_singleton_open(struct inode *inode_ptr, struct file *file_ptr) struct sep_device *sep; - /** - * get the sep device structure and use it for the + /* + * Get the sep device structure and use it for the * private_data field in filp for other methods */ sep = sep_dev; @@ -282,8 +286,7 @@ end_function: * @filp: file handle to sep device * * Open method for the SEP device. Called when userspace opens - * the SEP device node. Must also release the memory data pool - * allocations. + * the SEP device node. * * Returns zero on success otherwise an error code. */ @@ -292,8 +295,8 @@ static int sep_open(struct inode *inode, struct file *filp) { struct sep_device *sep; - /** - * get the sep device structure and use it for the + /* + * Get the sep device structure and use it for the * private_data field in filp for other methods */ sep = sep_dev; @@ -301,7 +304,7 @@ static int sep_open(struct inode *inode, struct file *filp) dev_dbg(&sep->pdev->dev, "Open for pid %d\n", current->pid); - /* anyone can open; locking takes place at transaction level */ + /* Anyone can open; locking takes place at transaction level */ return 0; } @@ -333,8 +336,7 @@ static int sep_singleton_release(struct inode *inode, struct file *filp) * @filp: file handle to sep device * * Open method for the SEP request daemon. Called when - * request daemon in userspace opens - * the SEP device node. + * request daemon in userspace opens the SEP device node. * * Returns zero on success otherwise an error code. */ @@ -385,9 +387,11 @@ static int sep_request_daemon_release(struct inode *inode, struct file *filp) } /** + * sep_req_daemon_send_reply_command_handler - poke the SEP + * @sep: struct sep_device * + * * This function raises interrupt to SEPm that signals that is has a * new command from HOST - * @sep: struct sep_device * */ static int sep_req_daemon_send_reply_command_handler(struct sep_device *sep) { @@ -427,9 +431,10 @@ static int sep_req_daemon_send_reply_command_handler(struct sep_device *sep) /** - * sep_free_dma_table_data_handler - handles the request - * for freeing dma table for synhronic actions + * sep_free_dma_table_data_handler - free DMA table * @sep: pointere to struct sep_device + * + * Handles the request to free dma table for synchronic actions */ static int sep_free_dma_table_data_handler(struct sep_device *sep) @@ -531,10 +536,12 @@ static int sep_free_dma_table_data_handler(struct sep_device *sep) /** - * sep_request_daemon_mmap - maps the - * shared area to user space + * sep_request_daemon_mmap - maps the shared area to user space * @filp: pointer to struct file * @vma: pointer to vm_area_struct + * + * Called by the kernel when the daemon attempts an mmap() syscall + * using our handle. */ static int sep_request_daemon_mmap(struct file *filp, struct vm_area_struct *vma) @@ -577,10 +584,12 @@ end_function: } /** - * sep_request_daemon_poll - + * sep_request_daemon_poll - poll implementation * @sep: struct sep_device * for current sep device * @filp: struct file * for open file * @wait: poll_table * for poll + * + * Called when our device is part of a poll() or select() syscall */ static unsigned int sep_request_daemon_poll(struct file *filp, poll_table *wait) @@ -689,6 +698,8 @@ static int sep_release(struct inode *inode, struct file *filp) * sep_mmap - maps the shared area to user space * @filp: pointer to struct file * @vma: pointer to vm_area_struct + * + * Called on an mmap of our space via the normal sep device */ static int sep_mmap(struct file *filp, struct vm_area_struct *vma) { @@ -776,9 +787,12 @@ end_function: } /** - * sep_poll - + * sep_poll - poll handler * @filp: pointer to struct file * @wait: pointer to poll_table + * + * Called by the OS when the kernel is asked to do a poll on + * a SEP file handle. */ static unsigned int sep_poll(struct file *filp, poll_table *wait) { @@ -792,7 +806,7 @@ static unsigned int sep_poll(struct file *filp, poll_table *wait) dev_dbg(&sep->pdev->dev, "poll: start\n"); - /* am I the process that own the transaction? */ + /* Am I the process that owns the transaction? */ mutex_lock(&sep->sep_mutex); if (current->pid != sep->pid_doing_transaction) { dev_warn(&sep->pdev->dev, "poll; wrong pid\n"); @@ -934,10 +948,12 @@ static unsigned long sep_set_time(struct sep_device *sep) } /** - * sep_set_caller_id_handler - inserts the data into the caller id table - * note that this function does fall under the ioctl lock + * sep_set_caller_id_handler - insert caller id entry * @sep: sep device * @arg: pointer to struct caller_id_struct + * + * Inserts the data into the caller id table. Note that this function + * falls under the ioctl lock */ static int sep_set_caller_id_handler(struct sep_device *sep, u32 arg) { @@ -1003,9 +1019,11 @@ end_function: } /** - * sep_set_current_caller_id - set the caller id (if exists) to the sep - * note that this function does fall under the ioctl lock + * sep_set_current_caller_id - set the caller id * @sep: pointer to struct_sep + * + * Set the caller ID (if it exists) to the sep. Note that this + * function falls under the ioctl lock */ static int sep_set_current_caller_id(struct sep_device *sep) { @@ -1040,10 +1058,12 @@ static int sep_set_current_caller_id(struct sep_device *sep) /** * sep_send_command_handler - kick off a command - * note that this function does fall under the ioctl lock + * @sep: sep being signalled + * * This function raises interrupt to SEP that signals that is has a new * command from the host - * @sep: sep being signalled + * + * Note that this function does fall under the ioctl lock */ static int sep_send_command_handler(struct sep_device *sep) @@ -1085,14 +1105,15 @@ end_function: } /** - * sep_allocate_data_pool_memory_handler - + * sep_allocate_data_pool_memory_handler -allocate pool memory + * @sep: pointer to struct_sep + * @arg: pointer to struct alloc_struct + * * This function handles the allocate data pool memory request * This function returns calculates the bus address of the * allocated memory, and the offset of this area from the mapped address. * Therefore, the FVOs in user space can calculate the exact virtual * address of this allocated memory - * @sep: pointer to struct_sep - * @arg: pointer to struct alloc_struct */ static int sep_allocate_data_pool_memory_handler(struct sep_device *sep, unsigned long arg) @@ -1100,7 +1121,7 @@ static int sep_allocate_data_pool_memory_handler(struct sep_device *sep, int error = 0; struct alloc_struct command_args; - /* holds the allocated buffer address in the system memory pool */ + /* Holds the allocated buffer address in the system memory pool */ u32 *token_addr; dev_dbg(&sep->pdev->dev, @@ -1112,7 +1133,7 @@ static int sep_allocate_data_pool_memory_handler(struct sep_device *sep, goto end_function; } - /* allocate memory */ + /* Allocate memory */ if ((sep->data_pool_bytes_allocated + command_args.num_bytes) > SEP_DRIVER_DATA_POOL_SHARED_AREA_SIZE_IN_BYTES) { error = -ENOMEM; @@ -1123,14 +1144,14 @@ static int sep_allocate_data_pool_memory_handler(struct sep_device *sep, "bytes_allocated: %x\n", (int)sep->data_pool_bytes_allocated); dev_dbg(&sep->pdev->dev, "offset: %x\n", SEP_DRIVER_DATA_POOL_AREA_OFFSET_IN_BYTES); - /* set the virtual and bus address */ + /* Set the virtual and bus address */ command_args.offset = SEP_DRIVER_DATA_POOL_AREA_OFFSET_IN_BYTES + sep->data_pool_bytes_allocated; dev_dbg(&sep->pdev->dev, "command_args.offset: %x\n", command_args.offset); - /* place in the shared area that is known by the sep */ + /* Place in the shared area that is known by the sep */ token_addr = (u32 *)(sep->shared_addr + SEP_DRIVER_DATA_POOL_ALLOCATION_OFFSET_IN_BYTES + (sep->num_of_data_allocations)*2*sizeof(u32)); @@ -1148,7 +1169,7 @@ static int sep_allocate_data_pool_memory_handler(struct sep_device *sep, dev_dbg(&sep->pdev->dev, "data pool token [0] %x\n", token_addr[0]); dev_dbg(&sep->pdev->dev, "data pool token [1] %x\n", token_addr[1]); - /* write the memory back to the user space */ + /* Write the memory back to the user space */ error = copy_to_user((void *)arg, (void *)&command_args, sizeof(struct alloc_struct)); if (error) { @@ -1175,17 +1196,18 @@ end_function: } /** - * sep_lock_kernel_pages - - * This function locks all the physical pages of the kernel virtual buffer - * and construct a basic lli array, where each entry holds the physical - * page address and the size that application data holds in this page - * This function is used only during kernel crypto mod calls from within - * the kernel (when ioctl is not used) + * sep_lock_kernel_pages - map kernel pages for DMA * @sep: pointer to struct sep_device * @kernel_virt_addr: address of data buffer in kernel * @data_size: size of data * @lli_array_ptr: lli array * @in_out_flag: input into device or output from device + * + * This function locks all the physical pages of the kernel virtual buffer + * and construct a basic lli array, where each entry holds the physical + * page address and the size that application data holds in this page + * This function is used only during kernel crypto mod calls from within + * the kernel (when ioctl is not used) */ static int sep_lock_kernel_pages(struct sep_device *sep, u32 kernel_virt_addr, @@ -1273,16 +1295,17 @@ end_function: } /** - * sep_lock_user_pages - - * This function locks all the physical pages of the application - * virtual buffer and construct a basic lli array, where each entry - * holds the physical page address and the size that application - * data holds in this physical pages + * sep_lock_user_pages - lock and map user pages for DMA * @sep: pointer to struct sep_device * @app_virt_addr: user memory data buffer * @data_size: size of data buffer * @lli_array_ptr: lli array * @in_out_flag: input or output to device + * + * This function locks all the physical pages of the application + * virtual buffer and construct a basic lli array, where each entry + * holds the physical page address and the size that application + * data holds in this physical pages */ static int sep_lock_user_pages(struct sep_device *sep, u32 app_virt_addr, @@ -1505,17 +1528,16 @@ end_function: } /** - * u32 sep_calculate_lli_table_max_size - - * this function calculates the size of data - * that can be inserted into the lli - * table from this array the condition is that - * either the table is full - * (all etnries are entered), or there are no more - * entries in the lli array + * u32 sep_calculate_lli_table_max_size - size the LLI table * @sep: pointer to struct sep_device * @lli_in_array_ptr * @num_array_entries * @last_table_flag + * + * This function calculates the size of data that can be inserted into + * the lli table from this array, such that either the table is full + * (all entries are entered), or there are no more entries in the + * lli array */ static u32 sep_calculate_lli_table_max_size(struct sep_device *sep, struct sep_lli_entry *lli_in_array_ptr, @@ -1590,15 +1612,16 @@ end_function: } /** - * sep_build_lli_table - - * this functions builds ont lli table from the lli_array according to - * the given size of data + * sep_build_lli_table - build an lli array for the given table * @sep: pointer to struct sep_device * @lli_array_ptr: pointer to lli array * @lli_table_ptr: pointer to lli table * @num_processed_entries_ptr: pointer to number of entries * @num_table_entries_ptr: pointer to number of tables * @table_data_size: total data size + * + * Builds ant lli table from the lli_array according to + * the given size of data */ static void sep_build_lli_table(struct sep_device *sep, struct sep_lli_entry *lli_array_ptr, @@ -1707,13 +1730,14 @@ static void sep_build_lli_table(struct sep_device *sep, } /** - * sep_shared_area_virt_to_bus - + * sep_shared_area_virt_to_bus - map shared area to bus address + * @sep: pointer to struct sep_device + * @virt_address: virtual address to convert + * * This functions returns the physical address inside shared area according * to the virtual address. It can be either on the externa RAM device * (ioremapped), or on the system RAM * This implementation is for the external RAM - * @sep: pointer to struct sep_device - * @virt_address: virtual address to convert */ static dma_addr_t sep_shared_area_virt_to_bus(struct sep_device *sep, void *virt_address) @@ -1731,13 +1755,14 @@ static dma_addr_t sep_shared_area_virt_to_bus(struct sep_device *sep, } /** - * sep_shared_area_bus_to_virt - + * sep_shared_area_bus_to_virt - map shared area bus address to kernel + * @sep: pointer to struct sep_device + * @bus_address: bus address to convert + * * This functions returns the virtual address inside shared area * according to the physical address. It can be either on the * externa RAM device (ioremapped), or on the system RAM * This implementation is for the external RAM - * @sep: pointer to struct sep_device - * @bus_address: bus address to convert */ static void *sep_shared_area_bus_to_virt(struct sep_device *sep, @@ -1754,13 +1779,13 @@ static void *sep_shared_area_bus_to_virt(struct sep_device *sep, } /** - * sep_debug_print_lli_tables - - * this function goes over the list of the print created tables and - * prints all the data + * sep_debug_print_lli_tables - dump LLI table * @sep: pointer to struct sep_device * @lli_table_ptr: pointer to sep_lli_entry * @num_table_entries: number of entries * @table_data_size: total data size + * + * Walk the the list of the print created tables and print all the data */ static void sep_debug_print_lli_tables(struct sep_device *sep, struct sep_lli_entry *lli_table_ptr, @@ -1831,12 +1856,14 @@ static void sep_debug_print_lli_tables(struct sep_device *sep, /** - * sep_prepare_empty_lli_table - - * This function creates empty lli tables when there is no data + * sep_prepare_empty_lli_table - create a blank LLI table * @sep: pointer to struct sep_device * @lli_table_addr_ptr: pointer to lli table * @num_entries_ptr: pointer to number of entries * @table_data_size_ptr: point to table data size + * + * This function creates empty lli tables when there is no data + */ static void sep_prepare_empty_lli_table(struct sep_device *sep, dma_addr_t *lli_table_addr_ptr, @@ -1881,11 +1908,7 @@ static void sep_prepare_empty_lli_table(struct sep_device *sep, } /** - * sep_prepare_input_dma_table - - * This function prepares only input DMA table for synhronic symmetric - * operations (HASH) - * Note that all bus addresses that are passed to the sep - * are in 32 bit format; the SEP is a 32 bit device + * sep_prepare_input_dma_table - prepare input DMA mappings * @sep: pointer to struct sep_device * @data_size: * @block_size: @@ -1893,6 +1916,11 @@ static void sep_prepare_empty_lli_table(struct sep_device *sep, * @num_entries_ptr: * @table_data_size_ptr: * @is_kva: set for kernel data (kernel cryptio call) + * + * This function prepares only input DMA table for synhronic symmetric + * operations (HASH) + * Note that all bus addresses that are passed to the sep + * are in 32 bit format; the SEP is a 32 bit device */ static int sep_prepare_input_dma_table(struct sep_device *sep, unsigned long app_virt_addr, @@ -2099,12 +2127,7 @@ end_function: } /** - * sep_construct_dma_tables_from_lli - - * This function creates the input and output dma tables for - * symmetric operations (AES/DES) according to the block - * size from LLI arays - * Note that all bus addresses that are passed to the sep - * are in 32 bit format; the SEP is a 32 bit device + * sep_construct_dma_tables_from_lli - prepare AES/DES mappings * @sep: pointer to struct_sep * @lli_in_array: * @sep_in_lli_entries: @@ -2116,6 +2139,12 @@ end_function: * @in_num_entries_ptr * @out_num_entries_ptr * @table_data_size_ptr + * + * This function creates the input and output dma tables for + * symmetric operations (AES/DES) according to the block + * size from LLI arays + * Note that all bus addresses that are passed to the sep + * are in 32 bit format; the SEP is a 32 bit device */ static int sep_construct_dma_tables_from_lli( struct sep_device *sep, @@ -2358,12 +2387,7 @@ static int sep_construct_dma_tables_from_lli( } /** - * sep_prepare_input_output_dma_table - - * This function builds input and output DMA tables for synhronic - * symmetric operations (AES, DES, HASH). It also checks that each table - * is of the modular block size - * Note that all bus addresses that are passed to the sep - * are in 32 bit format; the SEP is a 32 bit device + * sep_prepare_input_output_dma_table - prepare DMA I/O table * @app_virt_in_addr: * @app_virt_out_addr: * @data_size: @@ -2374,6 +2398,12 @@ static int sep_construct_dma_tables_from_lli( * @out_num_entries_ptr: * @table_data_size_ptr: * @is_kva: set for kernel data; used only for kernel crypto module + * + * This function builds input and output DMA tables for synhronic + * symmetric operations (AES, DES, HASH). It also checks that each table + * is of the modular block size + * Note that all bus addresses that are passed to the sep + * are in 32 bit format; the SEP is a 32 bit device */ static int sep_prepare_input_output_dma_table(struct sep_device *sep, unsigned long app_virt_in_addr, @@ -2522,12 +2552,7 @@ end_function: } /** - * sep_prepare_input_output_dma_table_in_dcb - - * This function prepares the linked dma tables and puts the - * address for the linked list of tables inta a dcb (data control - * block) the address of which is known by the sep hardware - * Note that all bus addresses that are passed to the sep - * are in 32 bit format; the SEP is a 32 bit device + * sep_prepare_input_output_dma_table_in_dcb - prepare control blocks * @app_in_address: unsigned long; for data buffer in (user space) * @app_out_address: unsigned long; for data buffer out (user space) * @data_in_size: u32; for size of data @@ -2535,6 +2560,12 @@ end_function: * @tail_block_size: u32; for size of tail block * @isapplet: bool; to indicate external app * @is_kva: bool; kernel buffer; only used for kernel crypto module + * + * This function prepares the linked dma tables and puts the + * address for the linked list of tables inta a dcb (data control + * block) the address of which is known by the sep hardware + * Note that all bus addresses that are passed to the sep + * are in 32 bit format; the SEP is a 32 bit device */ static int sep_prepare_input_output_dma_table_in_dcb(struct sep_device *sep, u32 app_in_address, @@ -2737,14 +2768,14 @@ end_function: /** - * sep_create_sync_dma_tables_handler - - * this function handles tha request for creation of the DMA table - * for the synchronic symmetric operations (AES,DES) - * Note that all bus addresses that are passed to the sep - * are in 32 bit format; the SEP is a 32 bit device + * sep_create_sync_dma_tables_handler - create sync dma tables * @sep: pointer to struct sep_device * @arg: pointer to struct bld_syn_tab_struct -*/ + * + * Handle the request for creation of the DMA tables for the synchronic + * symmetric operations (AES,DES). Note that all bus addresses that are + * passed to the SEP are in 32 bit format; the SEP is a 32 bit device + */ static int sep_create_sync_dma_tables_handler(struct sep_device *sep, unsigned long arg) { @@ -2799,11 +2830,12 @@ end_function: } /** - * sep_free_dma_tables_and_dcb - - * This function frees the dma tables and dcb block + * sep_free_dma_tables_and_dcb - free DMA tables and DCBs * @sep: pointer to struct sep_device * @isapplet: indicates external application (used for kernel access) * @is_kva: indicates kernel addresses (only used for kernel crypto) + * + * This function frees the dma tables and dcb block */ static int sep_free_dma_tables_and_dcb(struct sep_device *sep, bool isapplet, bool is_kva) @@ -2858,11 +2890,12 @@ static int sep_free_dma_tables_and_dcb(struct sep_device *sep, bool isapplet, } /** - * sep_get_static_pool_addr_handler - - * this function sets the bus and virtual addresses of the static pool - * and returns the virtual address + * sep_get_static_pool_addr_handler - get static pool address * @sep: pointer to struct sep_device * @arg: parameters from user space application + * + * This function sets the bus and virtual addresses of the static pool + * and returns the virtual address */ static int sep_get_static_pool_addr_handler(struct sep_device *sep, unsigned long arg) @@ -2901,8 +2934,7 @@ static int sep_get_static_pool_addr_handler(struct sep_device *sep, } /** - * sep_start_handler - - * This function starts the sep device + * sep_start_handler - start device * @sep: pointer to struct sep_device */ static int sep_start_handler(struct sep_device *sep) @@ -2926,11 +2958,12 @@ static int sep_start_handler(struct sep_device *sep) } /** - * ep_check_sum_calc - - * This function performs a checsum for messages that are sent + * ep_check_sum_calc - checksum messages + * @data: buffer to checksum + * @length: buffer size + * + * This function performs a checksum for messages that are sent * to the sep - * @data: - * @length: */ static u32 sep_check_sum_calc(u8 *data, u32 length) { @@ -2956,17 +2989,18 @@ static u32 sep_check_sum_calc(u8 *data, u32 length) /** * sep_init_handler - - * this function handles the request for SEP initialization + * @sep: pointer to struct sep_device + * @arg: parameters from user space application + * + * Handles the request for SEP initialization * Note that this will go away for Medfield once the SCU * SEP initialization is complete * Also note that the message to the sep has components * from user space as well as components written by the driver - * This is becuase the portions of the message that partain to + * This is becuase the portions of the message that pertain to * physical addresses must be set by the driver after the message * leaves custody of the user space application for security * reasons. - * @sep: pointer to struct sep_device - * @arg: parameters from user space application */ static int sep_init_handler(struct sep_device *sep, unsigned long arg) { @@ -3127,9 +3161,10 @@ end_function: } /** - * sep_end_transaction_handler - - * This API handles the end transaction request + * sep_end_transaction_handler - end transaction * @sep: pointer to struct sep_device + * + * This API handles the end transaction request */ static int sep_end_transaction_handler(struct sep_device *sep) { @@ -3163,11 +3198,12 @@ static int sep_end_transaction_handler(struct sep_device *sep) } /** - * sep_prepare_dcb_handler - - * This function will retrieve the RAR buffer physical addresses, type - * & size corresponding to the RAR handles provided in the buffers vector. + * sep_prepare_dcb_handler - prepare a control block * @sep: pointer to struct sep_device * @arg: pointer to user parameters + * + * This function will retrieve the RAR buffer physical addresses, type + * & size corresponding to the RAR handles provided in the buffers vector. */ static int sep_prepare_dcb_handler(struct sep_device *sep, unsigned long arg) @@ -3211,10 +3247,11 @@ end_function: } /** - * sep_free_dcb_handler - - * this function frees the DCB resources - * and updates the needed user-space buffers + * sep_free_dcb_handler - free control block resources * @sep: pointer to struct sep_device + * + * This function frees the DCB resources and updates the needed + * user-space buffers. */ static int sep_free_dcb_handler(struct sep_device *sep) { @@ -3230,11 +3267,12 @@ static int sep_free_dcb_handler(struct sep_device *sep) } /** - * sep_rar_prepare_output_msg_handler - - * This function will retrieve the RAR buffer physical addresses, type - * & size corresponding to the RAR handles provided in the buffers vector. + * sep_rar_prepare_output_msg_handler - prepare an output message * @sep: pointer to struct sep_device * @arg: pointer to user parameters + * + * This function will retrieve the RAR buffer physical addresses, type + * & size corresponding to the RAR handles provided in the buffers vector. */ static int sep_rar_prepare_output_msg_handler(struct sep_device *sep, @@ -3300,10 +3338,11 @@ end_function: } /** - * sep_realloc_ext_cache_handler - - * This function tells the sep where the extapp is located + * sep_realloc_ext_cache_handler - report location of extcache * @sep: pointer to struct sep_device * @arg: pointer to user parameters + * + * This function tells the sep where the extapp is located */ static int sep_realloc_ext_cache_handler(struct sep_device *sep, unsigned long arg) @@ -3332,6 +3371,8 @@ static int sep_realloc_ext_cache_handler(struct sep_device *sep, * @filp: pointer to struct file * @cmd: command * @arg: pointer to argument structure + * + * Implement the ioctl methods availble on the SEP device. */ static long sep_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { @@ -3462,6 +3503,8 @@ end_function: * @filp: pointer to struct file * @cmd: command * @arg: pointer to argument structure + * + * Implement the additional ioctls for the singleton device */ static long sep_singleton_ioctl(struct file *filp, u32 cmd, unsigned long arg) { @@ -3522,6 +3565,7 @@ end_function: * @filp: pointer to struct file * @cmd: command * @arg: pointer to argument structure + * * Called by the request daemon to perform ioctls on the daemon device */ @@ -3643,10 +3687,11 @@ static irqreturn_t sep_inthandler(int irq, void *dev_id) } /** - * sep_callback - + * sep_callback - RAR callback + * @sep_context_pointer: pointer to struct sep_device + * * Function that is called by rar_register when it is ready with * a region (only for Moorestown) - * @sep_context_pointer: pointer to struct sep_device */ static int sep_callback(unsigned long sep_context_pointer) { @@ -3696,10 +3741,12 @@ end_function: } /** - * sep_probe - - * Function that is activated on the successful probe of the SEP device + * sep_probe - probe a matching PCI device * @pdev: pci_device * @end: pci_device_id + * + * Attempt to set up and configure a SEP device that has been + * discovered by the PCI layer. */ static int __devinit sep_probe(struct pci_dev *pdev, const struct pci_device_id *ent) @@ -3904,10 +3951,11 @@ static const struct file_operations sep_file_operations = { }; /** - * sep_reconfig_shared_area - - * reconfig the shared area between HOST and SEP - needed in case - * the DX_CC_Init function was called before OS loading + * sep_reconfig_shared_area - reconfigure shared area * @sep: pointer to struct sep_device + * + * Reconfig the shared area between HOST and SEP - needed in case + * the DX_CC_Init function was called before OS loading. */ static int sep_reconfig_shared_area(struct sep_device *sep) { @@ -3948,9 +3996,10 @@ static int sep_reconfig_shared_area(struct sep_device *sep) } /** - * sep_register_driver_to_fs - - * This function registers the driver to the file system + * sep_register_driver_to_fs - register misc devices * @sep: pointer to struct sep_device + * + * This function registers the driver to the file system */ static int sep_register_driver_to_fs(struct sep_device *sep) { @@ -4000,7 +4049,9 @@ static int sep_register_driver_to_fs(struct sep_device *sep) } /** - * sep_init - init function; this is the first thing called on boot + * sep_init - init function + * + * Module load time. Register the PCI device driver. */ static int __init sep_init(void) { @@ -4051,7 +4102,10 @@ end_function: /** - * sep_exit - called to unload driver (never called on static compile) + * sep_exit - called to unload driver + * + * Drop the misc devices then remove and unmap the various resources + * that are not released by the driver remove method. */ static void __exit sep_exit(void) { -- cgit v1.2.3 From da14e55130785db243a98523b57ddf56d6c6320a Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Wed, 24 Nov 2010 19:38:02 +0000 Subject: Staging: sep: clean up some of the obvious sillies Various assignments are done but not used dev_dbg formatting is a bit weird and wraps when not needed Take out some of the blank lines and reformat a bit to reduce view size Remove some comments that are obvious Fix else formatting Remove some user triggerable dev_warns Fix copy_from_user error return cases (-EFAULT not bytes copied) Signed-off-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/staging/sep/sep_driver.c | 941 +++++++++++---------------------------- 1 file changed, 249 insertions(+), 692 deletions(-) diff --git a/drivers/staging/sep/sep_driver.c b/drivers/staging/sep/sep_driver.c index 4a0bb4350424..f576285fbb8f 100644 --- a/drivers/staging/sep/sep_driver.c +++ b/drivers/staging/sep/sep_driver.c @@ -83,15 +83,13 @@ static struct sep_device *sep_dev; * This functions copies the cache and resident from their source * location into destination shared memory. */ - static int sep_load_firmware(struct sep_device *sep) { const struct firmware *fw; char *cache_name = "cache.image.bin"; char *res_name = "resident.image.bin"; char *extapp_name = "extapp.image.bin"; - - int error = 0; + int error ; unsigned int work1, work2, work3; /* set addresses and load resident */ @@ -110,7 +108,7 @@ static int sep_load_firmware(struct sep_device *sep) dev_dbg(&sep->pdev->dev, "resident virtual is %p\n", sep->resident_addr); - dev_dbg(&sep->pdev->dev, "residnet bus is %lx\n", + dev_dbg(&sep->pdev->dev, "resident bus is %lx\n", (unsigned long)sep->resident_bus); dev_dbg(&sep->pdev->dev, "resident size is %08x\n", sep->resident_size); @@ -134,7 +132,7 @@ static int sep_load_firmware(struct sep_device *sep) error = request_firmware(&fw, cache_name, &sep->pdev->dev); if (error) { - dev_warn(&sep->pdev->dev, "cant request cache fw\n"); + dev_warn(&sep->pdev->dev, "Unable to request cache firmware\n"); return error; } @@ -155,7 +153,7 @@ static int sep_load_firmware(struct sep_device *sep) error = request_firmware(&fw, extapp_name, &sep->pdev->dev); if (error) { - dev_warn(&sep->pdev->dev, "cant request extapp fw\n"); + dev_warn(&sep->pdev->dev, "Unable to request extapp firmware\n"); return error; } @@ -181,15 +179,13 @@ MODULE_FIRMWARE("sep/extapp.image.bin"); * sep_dump_message - dump the message that is pending * @sep: sep device */ - static void sep_dump_message(struct sep_device *sep) { int count; u32 *p = sep->shared_addr; for (count = 0; count < 12 * 4; count += 4) - dev_dbg(&sep->pdev->dev, - "Word %d of the message is %x\n", - count, *p++); + dev_dbg(&sep->pdev->dev, "Word %d of the message is %x\n", + count, *p++); } /** @@ -197,7 +193,6 @@ static void sep_dump_message(struct sep_device *sep) * @sep: security processor * @size: size of shared area */ - static int sep_map_and_alloc_shared_area(struct sep_device *sep) { sep->shared_addr = dma_alloc_coherent(&sep->pdev->dev, @@ -211,8 +206,8 @@ static int sep_map_and_alloc_shared_area(struct sep_device *sep) } dev_dbg(&sep->pdev->dev, "sep: shared_addr %x bytes @%p (bus %llx)\n", - sep->shared_size, sep->shared_addr, - (unsigned long long)sep->shared_bus); + sep->shared_size, sep->shared_addr, + (unsigned long long)sep->shared_bus); return 0; } @@ -235,7 +230,6 @@ static void sep_unmap_and_free_shared_area(struct sep_device *sep) * Returns virtual address inside the shared area according * to the bus address. */ - static void *sep_shared_bus_to_virt(struct sep_device *sep, dma_addr_t bus_address) { @@ -249,11 +243,9 @@ static void *sep_shared_bus_to_virt(struct sep_device *sep, * * Called when the user opens the singleton device interface */ - static int sep_singleton_open(struct inode *inode_ptr, struct file *file_ptr) { int error = 0; - struct sep_device *sep; /* @@ -290,7 +282,6 @@ end_function: * * Returns zero on success otherwise an error code. */ - static int sep_open(struct inode *inode, struct file *filp) { struct sep_device *sep; @@ -317,16 +308,13 @@ static int sep_open(struct inode *inode, struct file *filp) * multiple simultaenous opens that means this method is called when the * final reference to the open handle is dropped. */ - static int sep_singleton_release(struct inode *inode, struct file *filp) { struct sep_device *sep = filp->private_data; dev_dbg(&sep->pdev->dev, "Singleton release for pid %d\n", - current->pid); - + current->pid); clear_bit(0, &sep->singleton_access_flag); - return 0; } @@ -340,14 +328,11 @@ static int sep_singleton_release(struct inode *inode, struct file *filp) * * Returns zero on success otherwise an error code. */ - static int sep_request_daemon_open(struct inode *inode, struct file *filp) { - struct sep_device *sep; - + struct sep_device *sep = sep_dev; int error = 0; - sep = sep_dev; filp->private_data = sep; dev_dbg(&sep->pdev->dev, "Request daemon open for pid %d\n", @@ -355,13 +340,8 @@ static int sep_request_daemon_open(struct inode *inode, struct file *filp) /* There is supposed to be only one request daemon */ dev_dbg(&sep->pdev->dev, "calling test and set for req_dmon open 0\n"); - if (test_and_set_bit(0, &sep->request_daemon_open)) { + if (test_and_set_bit(0, &sep->request_daemon_open)) error = -EBUSY; - goto end_function; - } - -end_function: - return error; } @@ -372,7 +352,6 @@ end_function: * * Called on the final close of a SEP daemon. */ - static int sep_request_daemon_release(struct inode *inode, struct file *filp) { struct sep_device *sep = filp->private_data; @@ -382,7 +361,6 @@ static int sep_request_daemon_release(struct inode *inode, struct file *filp) /* clear the request_daemon_open flag */ clear_bit(0, &sep->request_daemon_open); - return 0; } @@ -395,15 +373,11 @@ static int sep_request_daemon_release(struct inode *inode, struct file *filp) */ static int sep_req_daemon_send_reply_command_handler(struct sep_device *sep) { - int error = 0; - unsigned long lck_flags; dev_dbg(&sep->pdev->dev, "sep_req_daemon_send_reply_command_handler start\n"); - error = 0; - sep_dump_message(sep); /* counters are lockable region */ @@ -426,7 +400,7 @@ static int sep_req_daemon_send_reply_command_handler(struct sep_device *sep) dev_dbg(&sep->pdev->dev, "sep_req_daemon_send_reply_command_handler end\n"); - return error; + return 0; } @@ -436,80 +410,56 @@ static int sep_req_daemon_send_reply_command_handler(struct sep_device *sep) * * Handles the request to free dma table for synchronic actions */ - static int sep_free_dma_table_data_handler(struct sep_device *sep) { - /* counter */ - int count = 0; - - /* dcb counter */ - int dcb_counter = 0; - + int count; + int dcb_counter; /* pointer to the current dma_resource struct */ struct sep_dma_resource *dma; - dev_dbg(&sep->pdev->dev, - "sep_free_dma_table_data_handler start\n"); - - - for (dcb_counter = 0; dcb_counter < sep->nr_dcb_creat; - dcb_counter++) { + dev_dbg(&sep->pdev->dev, "sep_free_dma_table_data_handler start\n"); + for (dcb_counter = 0; dcb_counter < sep->nr_dcb_creat; dcb_counter++) { dma = &sep->dma_res_arr[dcb_counter]; /* unmap and free input map array */ if (dma->in_map_array) { - - for (count = 0; count < dma->in_num_pages; - count++) { - + for (count = 0; count < dma->in_num_pages; count++) { dma_unmap_page(&sep->pdev->dev, dma->in_map_array[count].dma_addr, dma->in_map_array[count].size, DMA_TO_DEVICE); } - kfree(dma->in_map_array); } /* unmap output map array, DON'T free it yet */ if (dma->out_map_array) { - for (count = 0; count < dma->out_num_pages; - count++) { - + for (count = 0; count < dma->out_num_pages; count++) { dma_unmap_page(&sep->pdev->dev, dma->out_map_array[count].dma_addr, dma->out_map_array[count].size, DMA_FROM_DEVICE); } - kfree(dma->out_map_array); } /* free page cache for output */ if (dma->in_page_array) { - for (count = 0; count < dma->in_num_pages; - count++) { - + for (count = 0; count < dma->in_num_pages; count++) { flush_dcache_page(dma->in_page_array[count]); page_cache_release(dma->in_page_array[count]); } - kfree(dma->in_page_array); - } if (dma->out_page_array) { - for (count = 0; count < dma->out_num_pages; - count++) { - + for (count = 0; count < dma->out_num_pages; count++) { if (!PageReserved(dma->out_page_array[count])) SetPageDirty(dma->out_page_array[count]); - flush_dcache_page(dma->out_page_array[count]); page_cache_release(dma->out_page_array[count]); } - kfree(dma->out_page_array); } @@ -522,19 +472,15 @@ static int sep_free_dma_table_data_handler(struct sep_device *sep) dma->out_map_array = 0; dma->in_map_num_entries = 0; dma->out_map_num_entries = 0; - } sep->nr_dcb_creat = 0; sep->num_lli_tables_created = 0; - dev_dbg(&sep->pdev->dev, - "sep_free_dma_table_data_handler end\n"); - + dev_dbg(&sep->pdev->dev, "sep_free_dma_table_data_handler end\n"); return 0; } - /** * sep_request_daemon_mmap - maps the shared area to user space * @filp: pointer to struct file @@ -546,11 +492,8 @@ static int sep_free_dma_table_data_handler(struct sep_device *sep) static int sep_request_daemon_mmap(struct file *filp, struct vm_area_struct *vma) { - /* device */ struct sep_device *sep = filp->private_data; - dma_addr_t bus_address; - int error = 0; dev_dbg(&sep->pdev->dev, "daemon mmap start\n"); @@ -563,23 +506,19 @@ static int sep_request_daemon_mmap(struct file *filp, /* get physical address */ bus_address = sep->shared_bus; - dev_dbg(&sep->pdev->dev, - "bus_address is %08lx\n", - (unsigned long)bus_address); + dev_dbg(&sep->pdev->dev, "bus_address is %08lx\n", + (unsigned long)bus_address); if (remap_pfn_range(vma, vma->vm_start, bus_address >> PAGE_SHIFT, vma->vm_end - vma->vm_start, vma->vm_page_prot)) { - dev_warn(&sep->pdev->dev, - "remap_page_range failed\n"); + dev_warn(&sep->pdev->dev, "remap_page_range failed\n"); error = -EAGAIN; goto end_function; } end_function: - dev_dbg(&sep->pdev->dev, "daemon mmap end\n"); - return error; } @@ -595,69 +534,46 @@ static unsigned int sep_request_daemon_poll(struct file *filp, poll_table *wait) { u32 mask = 0; - /* GPR2 register */ u32 retval2; - unsigned long lck_flags; - struct sep_device *sep = filp->private_data; - dev_dbg(&sep->pdev->dev, - "daemon poll: start\n"); - - dev_dbg(&sep->pdev->dev, "daemon poll: calling poll wait sep_event\n"); + dev_dbg(&sep->pdev->dev, "daemon poll: start\n"); poll_wait(filp, &sep->event_request_daemon, wait); - dev_dbg(&sep->pdev->dev, "daemon poll: exit poll wait sep_event\n"); - - dev_dbg(&sep->pdev->dev, - "daemon poll: send_ct is %lx reply ct is %lx\n", - sep->send_ct, sep->reply_ct); + dev_dbg(&sep->pdev->dev, "daemon poll: send_ct is %lx reply ct is %lx\n", + sep->send_ct, sep->reply_ct); spin_lock_irqsave(&sep->snd_rply_lck, lck_flags); /* check if the data is ready */ if (sep->send_ct == sep->reply_ct) { - spin_unlock_irqrestore(&sep->snd_rply_lck, lck_flags); retval2 = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR2_REG_ADDR); - dev_dbg(&sep->pdev->dev, "daemon poll: data check (GPR2) is %x\n", retval2); /* check if PRINT request */ if ((retval2 >> 30) & 0x1) { - - dev_dbg(&sep->pdev->dev, - "daemon poll: PRINTF request in\n"); + dev_dbg(&sep->pdev->dev, "daemon poll: PRINTF request in\n"); mask |= POLLIN; goto end_function; } - /* check if NVS request */ if (retval2 >> 31) { - - dev_dbg(&sep->pdev->dev, - "daemon poll: NVS request in\n"); + dev_dbg(&sep->pdev->dev, "daemon poll: NVS request in\n"); mask |= POLLPRI | POLLWRNORM; } - } - - else { - + } else { spin_unlock_irqrestore(&sep->snd_rply_lck, lck_flags); - dev_dbg(&sep->pdev->dev, "daemon poll: no reply received; returning 0\n"); mask = 0; } - end_function: - - dev_dbg(&sep->pdev->dev, - "daemon poll: exit\n"); + dev_dbg(&sep->pdev->dev, "daemon poll: exit\n"); return mask; } @@ -668,7 +584,6 @@ end_function: * * Called on the final close of a SEP device. */ - static int sep_release(struct inode *inode, struct file *filp) { struct sep_device *sep = filp->private_data; @@ -709,9 +624,6 @@ static int sep_mmap(struct file *filp, struct vm_area_struct *vma) dev_dbg(&sep->pdev->dev, "mmap start\n"); - - dev_dbg(&sep->pdev->dev, "calling wait on event_mmap, tsetbit" - " SEP_MMAP_LOCK_BIT in_use_flags 0\n"); /* Set the transaction busy (own the device) */ wait_event_interruptible(sep->event, test_and_set_bit(SEP_MMAP_LOCK_BIT, @@ -748,8 +660,7 @@ static int sep_mmap(struct file *filp, struct vm_area_struct *vma) goto end_function_with_error; } - dev_dbg(&sep->pdev->dev, - "shared_addr is %p\n", sep->shared_addr); + dev_dbg(&sep->pdev->dev, "shared_addr is %p\n", sep->shared_addr); /* get bus address */ bus_addr = sep->shared_bus; @@ -759,17 +670,14 @@ static int sep_mmap(struct file *filp, struct vm_area_struct *vma) if (remap_pfn_range(vma, vma->vm_start, bus_addr >> PAGE_SHIFT, vma->vm_end - vma->vm_start, vma->vm_page_prot)) { - dev_warn(&sep->pdev->dev, - "remap_page_range failed\n"); + dev_warn(&sep->pdev->dev, "remap_page_range failed\n"); error = -EAGAIN; goto end_function_with_error; } - dev_dbg(&sep->pdev->dev, "mmap end\n"); goto end_function; end_function_with_error: - /* clear the bit */ clear_bit(SEP_MMAP_LOCK_BIT, &sep->in_use_flags); mutex_lock(&sep->sep_mutex); @@ -782,7 +690,6 @@ end_function_with_error: wake_up(&sep->event); end_function: - return error; } @@ -799,7 +706,6 @@ static unsigned int sep_poll(struct file *filp, poll_table *wait) u32 mask = 0; u32 retval = 0; u32 retval2 = 0; - unsigned long lck_flags; struct sep_device *sep = filp->private_data; @@ -814,7 +720,6 @@ static unsigned int sep_poll(struct file *filp, poll_table *wait) mutex_unlock(&sep->sep_mutex); goto end_function; } - mutex_unlock(&sep->sep_mutex); /* check if send command or send_reply were activated previously */ @@ -829,18 +734,13 @@ static unsigned int sep_poll(struct file *filp, poll_table *wait) poll_wait(filp, &sep->event, wait); - dev_dbg(&sep->pdev->dev, "poll: exit wait sep_event\n"); - dev_dbg(&sep->pdev->dev, "poll: send_ct is %lx reply ct is %lx\n", sep->send_ct, sep->reply_ct); /* check if error occured during poll */ retval2 = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR3_REG_ADDR); - if (retval2 != 0x0) { - - dev_warn(&sep->pdev->dev, "poll; poll error %x\n", - retval2); + dev_warn(&sep->pdev->dev, "poll; poll error %x\n", retval2); mask |= POLLERR; goto end_function; } @@ -848,7 +748,6 @@ static unsigned int sep_poll(struct file *filp, poll_table *wait) spin_lock_irqsave(&sep->snd_rply_lck, lck_flags); if (sep->send_ct == sep->reply_ct) { - spin_unlock_irqrestore(&sep->snd_rply_lck, lck_flags); retval = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR2_REG_ADDR); dev_dbg(&sep->pdev->dev, "poll: data ready check (GPR2) %x\n", @@ -856,46 +755,33 @@ static unsigned int sep_poll(struct file *filp, poll_table *wait) /* check if printf request */ if ((retval >> 30) & 0x1) { - dev_dbg(&sep->pdev->dev, "poll: sep printf request\n"); wake_up(&sep->event_request_daemon); goto end_function; - } /* check if the this is sep reply or request */ if (retval >> 31) { - dev_dbg(&sep->pdev->dev, "poll: sep request\n"); wake_up(&sep->event_request_daemon); - } else { - dev_dbg(&sep->pdev->dev, "poll: normal return\n"); - /* in case it is again by send_reply_comand */ - clear_bit(SEP_SEND_MSG_LOCK_BIT, &sep->in_use_flags); - sep_dump_message(sep); - dev_dbg(&sep->pdev->dev, "poll; sep reply POLLIN | POLLRDNORM\n"); mask |= POLLIN | POLLRDNORM; } - } else { - spin_unlock_irqrestore(&sep->snd_rply_lck, lck_flags); - dev_dbg(&sep->pdev->dev, "poll; no reply received; returning mask of 0\n"); mask = 0; } end_function: - dev_dbg(&sep->pdev->dev, "poll: end\n"); return mask; } @@ -907,7 +793,6 @@ end_function: * Return the address of the two dwords in memory used for time * setting. */ - static u32 *sep_time_address(struct sep_device *sep) { return sep->shared_addr + SEP_DRIVER_SYSTEM_TIME_MEMORY_OFFSET_IN_BYTES; @@ -926,8 +811,7 @@ static unsigned long sep_set_time(struct sep_device *sep) u32 *time_addr; /* address of time as seen by the kernel */ - dev_dbg(&sep->pdev->dev, - "sep:sep_set_time start\n"); + dev_dbg(&sep->pdev->dev, "sep:sep_set_time start\n"); do_gettimeofday(&time); @@ -937,12 +821,9 @@ static unsigned long sep_set_time(struct sep_device *sep) time_addr[0] = SEP_TIME_VAL_TOKEN; time_addr[1] = time.tv_sec; - dev_dbg(&sep->pdev->dev, - "time.tv_sec is %lu\n", time.tv_sec); - dev_dbg(&sep->pdev->dev, - "time_addr is %p\n", time_addr); - dev_dbg(&sep->pdev->dev, - "sep->shared_addr is %p\n", sep->shared_addr); + dev_dbg(&sep->pdev->dev, "time.tv_sec is %lu\n", time.tv_sec); + dev_dbg(&sep->pdev->dev, "time_addr is %p\n", time_addr); + dev_dbg(&sep->pdev->dev, "sep->shared_addr is %p\n", sep->shared_addr); return time.tv_sec; } @@ -958,14 +839,11 @@ static unsigned long sep_set_time(struct sep_device *sep) static int sep_set_caller_id_handler(struct sep_device *sep, u32 arg) { void __user *hash; - int error; + int error = 0; int i; struct caller_id_struct command_args; - dev_dbg(&sep->pdev->dev, - "sep_set_caller_id_handler start\n"); - - error = 0; + dev_dbg(&sep->pdev->dev, "sep_set_caller_id_handler start\n"); for (i = 0; i < SEP_CALLER_ID_TABLE_NUM_ENTRIES; i++) { if (sep->caller_id_table[i].pid == 0) @@ -973,12 +851,9 @@ static int sep_set_caller_id_handler(struct sep_device *sep, u32 arg) } if (i == SEP_CALLER_ID_TABLE_NUM_ENTRIES) { - dev_warn(&sep->pdev->dev, - "no more caller id entries left\n"); - dev_warn(&sep->pdev->dev, - "maximum number is %d\n", - SEP_CALLER_ID_TABLE_NUM_ENTRIES); - + dev_warn(&sep->pdev->dev, "no more caller id entries left\n"); + dev_warn(&sep->pdev->dev, "maximum number is %d\n", + SEP_CALLER_ID_TABLE_NUM_ENTRIES); error = -EUSERS; goto end_function; } @@ -1002,7 +877,7 @@ static int sep_set_caller_id_handler(struct sep_device *sep, u32 arg) command_args.callerIdSizeInBytes); if (command_args.callerIdSizeInBytes > - SEP_CALLER_ID_HASH_SIZE_IN_BYTES) { + SEP_CALLER_ID_HASH_SIZE_IN_BYTES) { error = -EMSGSIZE; goto end_function; } @@ -1013,8 +888,7 @@ static int sep_set_caller_id_handler(struct sep_device *sep, u32 arg) hash, command_args.callerIdSizeInBytes)) error = -EFAULT; end_function: - dev_dbg(&sep->pdev->dev, - "sep_set_caller_id_handler end\n"); + dev_dbg(&sep->pdev->dev, "sep_set_caller_id_handler end\n"); return error; } @@ -1030,29 +904,23 @@ static int sep_set_current_caller_id(struct sep_device *sep) int i; dev_dbg(&sep->pdev->dev, "sep_set_current_caller_id start\n"); - dev_dbg(&sep->pdev->dev, "current process is %d\n", current->pid); /* zero the previous value */ - memset((void *)(sep->shared_addr + - (SEP_CALLER_ID_OFFSET_BYTES)), - 0, - SEP_CALLER_ID_HASH_SIZE_IN_BYTES); + memset(sep->shared_addr + SEP_CALLER_ID_OFFSET_BYTES, + 0, SEP_CALLER_ID_HASH_SIZE_IN_BYTES); for (i = 0; i < SEP_CALLER_ID_TABLE_NUM_ENTRIES; i++) { if (sep->caller_id_table[i].pid == current->pid) { dev_dbg(&sep->pdev->dev, "Caller Id found\n"); - memcpy((void *)(sep->shared_addr + - (SEP_CALLER_ID_OFFSET_BYTES)), + memcpy(sep->shared_addr + SEP_CALLER_ID_OFFSET_BYTES, (void *)(sep->caller_id_table[i].callerIdHash), SEP_CALLER_ID_HASH_SIZE_IN_BYTES); break; } } - dev_dbg(&sep->pdev->dev, "sep_set_current_caller_id end\n"); - return 0; } @@ -1065,7 +933,6 @@ static int sep_set_current_caller_id(struct sep_device *sep) * * Note that this function does fall under the ioctl lock */ - static int sep_send_command_handler(struct sep_device *sep) { unsigned long lck_flags; @@ -1073,13 +940,10 @@ static int sep_send_command_handler(struct sep_device *sep) dev_dbg(&sep->pdev->dev, "sep_send_command_handler start\n"); - dev_dbg(&sep->pdev->dev, "calling test and set for " - " in_use_flags SEP_SEND_MSG_LOCK_BIT 0\n"); if (test_and_set_bit(SEP_SEND_MSG_LOCK_BIT, &sep->in_use_flags)) { error = -EPROTO; goto end_function; } - sep_set_time(sep); /* only Medfield has caller id */ @@ -1093,8 +957,9 @@ static int sep_send_command_handler(struct sep_device *sep) sep->send_ct++; spin_unlock_irqrestore(&sep->snd_rply_lck, lck_flags); - dev_dbg(&sep->pdev->dev, "sep_send_command_handler" - "send_ct %lx reply_ct %lx\n", sep->send_ct, sep->reply_ct); + dev_dbg(&sep->pdev->dev, + "sep_send_command_handler send_ct %lx reply_ct %lx\n", + sep->send_ct, sep->reply_ct); /* send interrupt to SEP */ sep_write_reg(sep, HW_HOST_HOST_SEP_GPR0_REG_ADDR, 0x2); @@ -1156,8 +1021,7 @@ static int sep_allocate_data_pool_memory_handler(struct sep_device *sep, SEP_DRIVER_DATA_POOL_ALLOCATION_OFFSET_IN_BYTES + (sep->num_of_data_allocations)*2*sizeof(u32)); - dev_dbg(&sep->pdev->dev, - "allocation offset: %x\n", + dev_dbg(&sep->pdev->dev, "allocation offset: %x\n", SEP_DRIVER_DATA_POOL_ALLOCATION_OFFSET_IN_BYTES); dev_dbg(&sep->pdev->dev, "data pool token addr is %p\n", token_addr); @@ -1173,7 +1037,7 @@ static int sep_allocate_data_pool_memory_handler(struct sep_device *sep, error = copy_to_user((void *)arg, (void *)&command_args, sizeof(struct alloc_struct)); if (error) { - + error = -EFAULT; dev_warn(&sep->pdev->dev, "allocate data pool copy to user error\n"); goto end_function; @@ -1189,9 +1053,7 @@ static int sep_allocate_data_pool_memory_handler(struct sep_device *sep, (int)sep->data_pool_bytes_allocated); end_function: - - dev_dbg(&sep->pdev->dev, - "sep_allocate_data_pool_memory_handler end\n"); + dev_dbg(&sep->pdev->dev, "sep_allocate_data_pool_memory_handler end\n"); return error; } @@ -1216,12 +1078,9 @@ static int sep_lock_kernel_pages(struct sep_device *sep, int in_out_flag) { - /* error */ int error = 0; - /* array of lli */ struct sep_lli_entry *lli_array; - /* map array */ struct sep_dma_map *map_array; @@ -1235,11 +1094,9 @@ static int sep_lock_kernel_pages(struct sep_device *sep, lli_array = kmalloc(sizeof(struct sep_lli_entry), GFP_ATOMIC); if (!lli_array) { - error = -ENOMEM; goto end_function; } - map_array = kmalloc(sizeof(struct sep_dma_map), GFP_ATOMIC); if (!map_array) { error = -ENOMEM; @@ -1260,8 +1117,7 @@ static int sep_lock_kernel_pages(struct sep_device *sep, lli_array[0].block_size = map_array[0].size; dev_dbg(&sep->pdev->dev, - "lli_array[0].bus_address is %08lx," - " lli_array[0].block_size is %x\n", + "lli_array[0].bus_address is %08lx, lli_array[0].block_size is %x\n", (unsigned long)lli_array[0].bus_address, lli_array[0].block_size); @@ -1279,18 +1135,13 @@ static int sep_lock_kernel_pages(struct sep_device *sep, sep->dma_res_arr[sep->nr_dcb_creat].out_map_array = map_array; sep->dma_res_arr[sep->nr_dcb_creat].out_map_num_entries = 1; } - goto end_function; end_function_with_error: - kfree(lli_array); end_function: - - dev_dbg(&sep->pdev->dev, - "sep_lock_kernel_pages end\n"); - + dev_dbg(&sep->pdev->dev, "sep_lock_kernel_pages end\n"); return error; } @@ -1314,59 +1165,39 @@ static int sep_lock_user_pages(struct sep_device *sep, int in_out_flag) { - /* error */ - int error; - + int error = 0; + u32 count; + int result; /* the the page of the end address of the user space buffer */ u32 end_page; - /* the page of the start address of the user space buffer */ u32 start_page; - /* the range in pages */ u32 num_pages; - - /* array of pointers ot page */ + /* array of pointers to page */ struct page **page_array; - /* array of lli */ struct sep_lli_entry *lli_array; - /* map array */ struct sep_dma_map *map_array; - /* direction of the DMA mapping for locked pages */ enum dma_data_direction dir; - /* count */ - u32 count; - - /* result */ - int result; - dev_dbg(&sep->pdev->dev, "sep_lock_user_pages start\n"); - error = 0; - /* set start and end pages and num pages */ end_page = (app_virt_addr + data_size - 1) >> PAGE_SHIFT; start_page = app_virt_addr >> PAGE_SHIFT; num_pages = end_page - start_page + 1; - dev_dbg(&sep->pdev->dev, - "app_virt_addr is %x\n", app_virt_addr); - dev_dbg(&sep->pdev->dev, - "data_size is %x\n", data_size); - dev_dbg(&sep->pdev->dev, - "start_page is %x\n", start_page); - dev_dbg(&sep->pdev->dev, - "end_page is %x\n", end_page); - dev_dbg(&sep->pdev->dev, - "num_pages is %x\n", num_pages); + dev_dbg(&sep->pdev->dev, "app_virt_addr is %x\n", app_virt_addr); + dev_dbg(&sep->pdev->dev, "data_size is %x\n", data_size); + dev_dbg(&sep->pdev->dev, "start_page is %x\n", start_page); + dev_dbg(&sep->pdev->dev, "end_page is %x\n", end_page); + dev_dbg(&sep->pdev->dev, "num_pages is %x\n", num_pages); - dev_dbg(&sep->pdev->dev, - "starting page_array malloc\n"); + dev_dbg(&sep->pdev->dev, "starting page_array malloc\n"); /* allocate array of pages structure pointers */ page_array = kmalloc(sizeof(struct page *) * num_pages, GFP_ATOMIC); @@ -1374,11 +1205,9 @@ static int sep_lock_user_pages(struct sep_device *sep, error = -ENOMEM; goto end_function; } - map_array = kmalloc(sizeof(struct sep_dma_map) * num_pages, GFP_ATOMIC); if (!map_array) { - dev_warn(&sep->pdev->dev, - "kmalloc for map_array failed\n"); + dev_warn(&sep->pdev->dev, "kmalloc for map_array failed\n"); error = -ENOMEM; goto end_function_with_error1; } @@ -1387,15 +1216,12 @@ static int sep_lock_user_pages(struct sep_device *sep, GFP_ATOMIC); if (!lli_array) { - - dev_warn(&sep->pdev->dev, - "kmalloc for lli_array failed\n"); + dev_warn(&sep->pdev->dev, "kmalloc for lli_array failed\n"); error = -ENOMEM; goto end_function_with_error2; } - dev_dbg(&sep->pdev->dev, - "starting get_user_pages\n"); + dev_dbg(&sep->pdev->dev, "starting get_user_pages\n"); /* convert the application virtual address into a set of physical */ down_read(¤t->mm->mmap_sem); @@ -1408,15 +1234,13 @@ static int sep_lock_user_pages(struct sep_device *sep, /* check the number of pages locked - if not all then exit with error */ if (result != num_pages) { - dev_warn(&sep->pdev->dev, "not all pages locked by get_user_pages\n"); error = -ENOMEM; goto end_function_with_error3; } - dev_dbg(&sep->pdev->dev, - "get_user_pages succeeded\n"); + dev_dbg(&sep->pdev->dev, "get_user_pages succeeded\n"); /* set direction */ if (in_out_flag == SEP_DRIVER_IN_FLAG) @@ -1441,9 +1265,7 @@ static int sep_lock_user_pages(struct sep_device *sep, lli_array[count].bus_address = (u32)map_array[count].dma_addr; lli_array[count].block_size = PAGE_SIZE; - dev_warn(&sep->pdev->dev, - "lli_array[%x].bus_address is %08lx, \ - lli_array[%x].block_size is %x\n", + dev_warn(&sep->pdev->dev, "lli_array[%x].bus_address is %08lx, lli_array[%x].block_size is %x\n", count, (unsigned long)lli_array[count].bus_address, count, lli_array[count].block_size); } @@ -1460,20 +1282,17 @@ static int sep_lock_user_pages(struct sep_device *sep, PAGE_SIZE - (app_virt_addr & (~PAGE_MASK)); dev_dbg(&sep->pdev->dev, - "lli_array[0].bus_address is %08lx, \ - lli_array[0].block_size is %x\n", + "lli_array[0].bus_address is %08lx, lli_array[0].block_size is %x\n", (unsigned long)lli_array[count].bus_address, lli_array[count].block_size); /* check the size of the last page */ if (num_pages > 1) { - lli_array[num_pages - 1].block_size = (app_virt_addr + data_size) & (~PAGE_MASK); dev_warn(&sep->pdev->dev, - "lli_array[%x].bus_address is %08lx, \ - lli_array[%x].block_size is %x\n", + "lli_array[%x].bus_address is %08lx, lli_array[%x].block_size is %x\n", num_pages - 1, (unsigned long)lli_array[count].bus_address, num_pages - 1, @@ -1483,47 +1302,35 @@ static int sep_lock_user_pages(struct sep_device *sep, /* set output params acording to the in_out flag */ if (in_out_flag == SEP_DRIVER_IN_FLAG) { *lli_array_ptr = lli_array; - sep->dma_res_arr[sep->nr_dcb_creat].in_num_pages = - num_pages; - sep->dma_res_arr[sep->nr_dcb_creat].in_page_array = - page_array; - sep->dma_res_arr[sep->nr_dcb_creat].in_map_array = - map_array; + sep->dma_res_arr[sep->nr_dcb_creat].in_num_pages = num_pages; + sep->dma_res_arr[sep->nr_dcb_creat].in_page_array = page_array; + sep->dma_res_arr[sep->nr_dcb_creat].in_map_array = map_array; sep->dma_res_arr[sep->nr_dcb_creat].in_map_num_entries = - num_pages; + num_pages; } else { *lli_array_ptr = lli_array; - sep->dma_res_arr[sep->nr_dcb_creat].out_num_pages = - num_pages; + sep->dma_res_arr[sep->nr_dcb_creat].out_num_pages = num_pages; sep->dma_res_arr[sep->nr_dcb_creat].out_page_array = - page_array; - sep->dma_res_arr[sep->nr_dcb_creat].out_map_array = - map_array; + page_array; + sep->dma_res_arr[sep->nr_dcb_creat].out_map_array = map_array; sep->dma_res_arr[sep->nr_dcb_creat].out_map_num_entries = - num_pages; + num_pages; } - goto end_function; end_function_with_error3: - /* free lli array */ kfree(lli_array); end_function_with_error2: - kfree(map_array); end_function_with_error1: - /* free page array */ kfree(page_array); end_function: - - dev_dbg(&sep->pdev->dev, - "sep_lock_user_pages end\n"); - + dev_dbg(&sep->pdev->dev, "sep_lock_user_pages end\n"); return error; } @@ -1544,16 +1351,12 @@ static u32 sep_calculate_lli_table_max_size(struct sep_device *sep, u32 num_array_entries, u32 *last_table_flag) { + u32 counter; /* table data size */ - u32 table_data_size; - + u32 table_data_size = 0; /* data size for the next table */ u32 next_table_data_size; - /* counter */ - u32 counter; - - table_data_size = 0; *last_table_flag = 0; /* @@ -1562,7 +1365,7 @@ static u32 sep_calculate_lli_table_max_size(struct sep_device *sep, */ for (counter = 0; (counter < (SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP - 1)) && - (counter < num_array_entries); counter++) + (counter < num_array_entries); counter++) table_data_size += lli_in_array_ptr[counter].block_size; /* @@ -1571,7 +1374,6 @@ static u32 sep_calculate_lli_table_max_size(struct sep_device *sep, * and no need to check the block alignment */ if (counter == num_array_entries) { - /* set the last table flag */ *last_table_flag = 1; goto end_function; @@ -1584,11 +1386,8 @@ static u32 sep_calculate_lli_table_max_size(struct sep_device *sep, */ next_table_data_size = 0; for (; counter < num_array_entries; counter++) { - next_table_data_size += lli_in_array_ptr[counter].block_size; - if (next_table_data_size >= SEP_DRIVER_MIN_DATA_SIZE_PER_TABLE) - break; } @@ -1603,11 +1402,9 @@ static u32 sep_calculate_lli_table_max_size(struct sep_device *sep, table_data_size -= (SEP_DRIVER_MIN_DATA_SIZE_PER_TABLE - next_table_data_size); - dev_dbg(&sep->pdev->dev, - "table data size is %x\n", table_data_size); - + dev_dbg(&sep->pdev->dev, "table data size is %x\n", + table_data_size); end_function: - return table_data_size; } @@ -1632,20 +1429,17 @@ static void sep_build_lli_table(struct sep_device *sep, { /* current table data size */ u32 curr_table_data_size; - /* counter of lli array entry */ u32 array_counter; - dev_dbg(&sep->pdev->dev, - "sep_build_lli_table start\n"); + dev_dbg(&sep->pdev->dev, "sep_build_lli_table start\n"); /* init currrent table data size and lli array entry counter */ curr_table_data_size = 0; array_counter = 0; *num_table_entries_ptr = 1; - dev_dbg(&sep->pdev->dev, - "table_data_size is %x\n", table_data_size); + dev_dbg(&sep->pdev->dev, "table_data_size is %x\n", table_data_size); /* fill the table till table size reaches the needed amount */ while (curr_table_data_size < table_data_size) { @@ -1660,18 +1454,15 @@ static void sep_build_lli_table(struct sep_device *sep, curr_table_data_size += lli_array_ptr[array_counter].block_size; - dev_dbg(&sep->pdev->dev, - "lli_table_ptr is %p\n", lli_table_ptr); - dev_dbg(&sep->pdev->dev, - "lli_table_ptr->bus_address is %08lx\n", - (unsigned long)lli_table_ptr->bus_address); - dev_dbg(&sep->pdev->dev, - "lli_table_ptr->block_size is %x\n", + dev_dbg(&sep->pdev->dev, "lli_table_ptr is %p\n", + lli_table_ptr); + dev_dbg(&sep->pdev->dev, "lli_table_ptr->bus_address is %08lx\n", + (unsigned long)lli_table_ptr->bus_address); + dev_dbg(&sep->pdev->dev, "lli_table_ptr->block_size is %x\n", lli_table_ptr->block_size); /* check for overflow of the table data */ if (curr_table_data_size > table_data_size) { - dev_dbg(&sep->pdev->dev, "curr_table_data_size too large\n"); @@ -1686,15 +1477,13 @@ static void sep_build_lli_table(struct sep_device *sep, /* update the block size left in the lli array */ lli_array_ptr[array_counter].block_size = (curr_table_data_size - table_data_size); - } else - /* advance to the next entry in the lli_array */ array_counter++; dev_dbg(&sep->pdev->dev, "lli_table_ptr->bus_address is %08lx\n", - (unsigned long)lli_table_ptr->bus_address); + (unsigned long)lli_table_ptr->bus_address); dev_dbg(&sep->pdev->dev, "lli_table_ptr->block_size is %x\n", lli_table_ptr->block_size); @@ -1707,26 +1496,19 @@ static void sep_build_lli_table(struct sep_device *sep, lli_table_ptr->bus_address = 0xffffffff; lli_table_ptr->block_size = 0; - dev_dbg(&sep->pdev->dev, - "lli_table_ptr is %p\n", lli_table_ptr); - dev_dbg(&sep->pdev->dev, - "lli_table_ptr->bus_address is %08lx\n", - (unsigned long)lli_table_ptr->bus_address); - dev_dbg(&sep->pdev->dev, - "lli_table_ptr->block_size is %x\n", - lli_table_ptr->block_size); + dev_dbg(&sep->pdev->dev, "lli_table_ptr is %p\n", lli_table_ptr); + dev_dbg(&sep->pdev->dev, "lli_table_ptr->bus_address is %08lx\n", + (unsigned long)lli_table_ptr->bus_address); + dev_dbg(&sep->pdev->dev, "lli_table_ptr->block_size is %x\n", + lli_table_ptr->block_size); /* set the output parameter */ *num_processed_entries_ptr += array_counter; - dev_dbg(&sep->pdev->dev, - "num_processed_entries_ptr is %x\n", + dev_dbg(&sep->pdev->dev, "num_processed_entries_ptr is %x\n", *num_processed_entries_ptr); - dev_dbg(&sep->pdev->dev, - "sep_build_lli_table end\n"); - - return; + dev_dbg(&sep->pdev->dev, "sep_build_lli_table end\n"); } /** @@ -1742,16 +1524,12 @@ static void sep_build_lli_table(struct sep_device *sep, static dma_addr_t sep_shared_area_virt_to_bus(struct sep_device *sep, void *virt_address) { - dev_dbg(&sep->pdev->dev, - "sh virt to phys v %08lx\n", - (unsigned long)virt_address); - dev_dbg(&sep->pdev->dev, - "sh virt to phys p %08lx\n", - (unsigned long)(sep->shared_bus - + (virt_address - sep->shared_addr))); + dev_dbg(&sep->pdev->dev, "sh virt to phys v %p\n", virt_address); + dev_dbg(&sep->pdev->dev, "sh virt to phys p %08lx\n", + (unsigned long) + sep->shared_bus + (virt_address - sep->shared_addr)); - return sep->shared_bus - + (size_t)(virt_address - sep->shared_addr); + return sep->shared_bus + (size_t)(virt_address - sep->shared_addr); } /** @@ -1764,18 +1542,14 @@ static dma_addr_t sep_shared_area_virt_to_bus(struct sep_device *sep, * externa RAM device (ioremapped), or on the system RAM * This implementation is for the external RAM */ - static void *sep_shared_area_bus_to_virt(struct sep_device *sep, dma_addr_t bus_address) { - dev_dbg(&sep->pdev->dev, - "shared bus to virt b=%x v=%x\n", - (u32)bus_address, - (u32)(sep->shared_addr + + dev_dbg(&sep->pdev->dev, "shared bus to virt b=%x v=%x\n", + (u32)bus_address, (u32)(sep->shared_addr + (size_t)(bus_address - sep->shared_bus))); - return sep->shared_addr - + (size_t)(bus_address - sep->shared_bus); + return sep->shared_addr + (size_t)(bus_address - sep->shared_bus); } /** @@ -1792,20 +1566,17 @@ static void sep_debug_print_lli_tables(struct sep_device *sep, unsigned long num_table_entries, unsigned long table_data_size) { - unsigned long table_count = 0; + unsigned long table_count = 1; unsigned long entries_count = 0; - dev_dbg(&sep->pdev->dev, - "sep_debug_print_lli_tables start\n"); + dev_dbg(&sep->pdev->dev, "sep_debug_print_lli_tables start\n"); - table_count = 1; while ((unsigned long) lli_table_ptr != 0xffffffff) { dev_dbg(&sep->pdev->dev, "lli table %08lx, table_data_size is %lu\n", table_count, table_data_size); - dev_dbg(&sep->pdev->dev, - "num_table_entries is %lu\n", - num_table_entries); + dev_dbg(&sep->pdev->dev, "num_table_entries is %lu\n", + num_table_entries); /* print entries of the table (without info entry) */ for (entries_count = 0; entries_count < num_table_entries; @@ -1820,7 +1591,6 @@ static void sep_debug_print_lli_tables(struct sep_device *sep, (unsigned long)lli_table_ptr->bus_address, lli_table_ptr->block_size); } - /* point to the info entry */ lli_table_ptr--; @@ -1850,8 +1620,7 @@ static void sep_debug_print_lli_tables(struct sep_device *sep, table_count++; } - dev_dbg(&sep->pdev->dev, - "sep_debug_print_lli_tables end\n"); + dev_dbg(&sep->pdev->dev, "sep_debug_print_lli_tables end\n"); } @@ -1863,7 +1632,6 @@ static void sep_debug_print_lli_tables(struct sep_device *sep, * @table_data_size_ptr: point to table data size * * This function creates empty lli tables when there is no data - */ static void sep_prepare_empty_lli_table(struct sep_device *sep, dma_addr_t *lli_table_addr_ptr, @@ -1878,9 +1646,8 @@ static void sep_prepare_empty_lli_table(struct sep_device *sep, lli_table_ptr = (struct sep_lli_entry *)(sep->shared_addr + SYNCHRONIC_DMA_TABLES_AREA_OFFSET_BYTES + - sep->num_lli_tables_created * - sizeof(struct sep_lli_entry) * - SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP); + sep->num_lli_tables_created * sizeof(struct sep_lli_entry) * + SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP); lli_table_ptr->bus_address = 0; lli_table_ptr->block_size = 0; @@ -1931,43 +1698,29 @@ static int sep_prepare_input_dma_table(struct sep_device *sep, u32 *table_data_size_ptr, bool is_kva) { + int error = 0; /* pointer to the info entry of the table - the last entry */ struct sep_lli_entry *info_entry_ptr; - - /* array of pointers ot page */ + /* array of pointers to page */ struct sep_lli_entry *lli_array_ptr; - /* points to the first entry to be processed in the lli_in_array */ u32 current_entry = 0; - /* num entries in the virtual buffer */ u32 sep_lli_entries = 0; - /* lli table pointer */ struct sep_lli_entry *in_lli_table_ptr; - /* the total data in one table */ u32 table_data_size = 0; - /* flag for last table */ u32 last_table_flag = 0; - /* number of entries in lli table */ u32 num_entries_in_table = 0; - /* next table address */ u32 lli_table_alloc_addr = 0; - /* error */ - int error = 0; - - dev_dbg(&sep->pdev->dev, - "sep_prepare_input_dma_table start\n"); - - dev_dbg(&sep->pdev->dev, - "data_size is %x\n", data_size); - dev_dbg(&sep->pdev->dev, - "block_size is %x\n", block_size); + dev_dbg(&sep->pdev->dev, "sep_prepare_input_dma_table start\n"); + dev_dbg(&sep->pdev->dev, "data_size is %x\n", data_size); + dev_dbg(&sep->pdev->dev, "block_size is %x\n", block_size); /* initialize the pages pointers */ sep->dma_res_arr[sep->nr_dcb_creat].in_page_array = 0; @@ -1976,29 +1729,22 @@ static int sep_prepare_input_dma_table(struct sep_device *sep, /* set the kernel address for first table to be allocated */ lli_table_alloc_addr = (u32)(sep->shared_addr + SYNCHRONIC_DMA_TABLES_AREA_OFFSET_BYTES + - sep->num_lli_tables_created * - sizeof(struct sep_lli_entry) * + sep->num_lli_tables_created * sizeof(struct sep_lli_entry) * SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP); if (data_size == 0) { - /* special case - create meptu table - 2 entries, zero data */ sep_prepare_empty_lli_table(sep, lli_table_ptr, - num_entries_ptr, - table_data_size_ptr); - + num_entries_ptr, table_data_size_ptr); goto update_dcb_counter; } /* check if the pages are in Kernel Virtual Address layout */ if (is_kva == true) - /* lock the pages in the kernel */ error = sep_lock_kernel_pages(sep, app_virt_addr, data_size, &lli_array_ptr, SEP_DRIVER_IN_FLAG); - else - /* * lock the pages of the user buffer * and translate them to pages @@ -2009,15 +1755,13 @@ static int sep_prepare_input_dma_table(struct sep_device *sep, if (error) goto end_function; - dev_dbg(&sep->pdev->dev, - "output sep_in_num_pages is %x\n", + dev_dbg(&sep->pdev->dev, "output sep_in_num_pages is %x\n", sep->dma_res_arr[sep->nr_dcb_creat].in_num_pages); current_entry = 0; info_entry_ptr = 0; - sep_lli_entries = - sep->dma_res_arr[sep->nr_dcb_creat].in_num_pages; + sep_lli_entries = sep->dma_res_arr[sep->nr_dcb_creat].in_num_pages; /* loop till all the entries in in array are not processed */ while (current_entry < sep_lli_entries) { @@ -2048,17 +1792,16 @@ static int sep_prepare_input_dma_table(struct sep_device *sep, (sep_lli_entries - current_entry), &last_table_flag); - /** + /* * if this is not the last table - * then allign it to the block size */ if (!last_table_flag) table_data_size = - (table_data_size / block_size) * block_size; + (table_data_size / block_size) * block_size; - dev_dbg(&sep->pdev->dev, - "output table_data_size is %x\n", - table_data_size); + dev_dbg(&sep->pdev->dev, "output table_data_size is %x\n", + table_data_size); /* construct input lli table */ sep_build_lli_table(sep, &lli_array_ptr[current_entry], @@ -2077,52 +1820,38 @@ static int sep_prepare_input_dma_table(struct sep_device *sep, "output lli_table_in_ptr is %08lx\n", (unsigned long)*lli_table_ptr); - } - - else { - + } else { /* update the info entry of the previous in table */ info_entry_ptr->bus_address = sep_shared_area_virt_to_bus(sep, - in_lli_table_ptr); - info_entry_ptr->block_size = + in_lli_table_ptr); + info_entry_ptr->block_size = ((num_entries_in_table) << 24) | (table_data_size); } - /* save the pointer to the info entry of the current tables */ info_entry_ptr = in_lli_table_ptr + num_entries_in_table - 1; - } - /* print input tables */ sep_debug_print_lli_tables(sep, (struct sep_lli_entry *) sep_shared_area_bus_to_virt(sep, *lli_table_ptr), - *num_entries_ptr, - *table_data_size_ptr); - + *num_entries_ptr, *table_data_size_ptr); /* the array of the pages */ kfree(lli_array_ptr); update_dcb_counter: - /* update dcb counter */ sep->nr_dcb_creat++; - goto end_function; end_function_error: - /* free all the allocated resources */ kfree(sep->dma_res_arr[sep->nr_dcb_creat].in_map_array); kfree(lli_array_ptr); kfree(sep->dma_res_arr[sep->nr_dcb_creat].in_page_array); end_function: - - dev_dbg(&sep->pdev->dev, - "sep_prepare_input_dma_table end\n"); - + dev_dbg(&sep->pdev->dev, "sep_prepare_input_dma_table end\n"); return error; } @@ -2161,45 +1890,32 @@ static int sep_construct_dma_tables_from_lli( { /* points to the area where next lli table can be allocated */ u32 lli_table_alloc_addr = 0; - /* input lli table */ struct sep_lli_entry *in_lli_table_ptr = 0; - /* output lli table */ struct sep_lli_entry *out_lli_table_ptr = 0; - /* pointer to the info entry of the table - the last entry */ struct sep_lli_entry *info_in_entry_ptr = 0; - /* pointer to the info entry of the table - the last entry */ struct sep_lli_entry *info_out_entry_ptr = 0; - /* points to the first entry to be processed in the lli_in_array */ u32 current_in_entry = 0; - /* points to the first entry to be processed in the lli_out_array */ u32 current_out_entry = 0; - /* max size of the input table */ u32 in_table_data_size = 0; - /* max size of the output table */ u32 out_table_data_size = 0; - /* flag te signifies if this is the last tables build */ u32 last_table_flag = 0; - /* the data size that should be in table */ u32 table_data_size = 0; - /* number of etnries in the input table */ u32 num_entries_in_table = 0; - /* number of etnries in the output table */ u32 num_entries_out_table = 0; - dev_dbg(&sep->pdev->dev, - "sep_construct_dma_tables_from_lli start\n"); + dev_dbg(&sep->pdev->dev, "sep_construct_dma_tables_from_lli start\n"); /* initiate to point after the message area */ lli_table_alloc_addr = (u32)(sep->shared_addr + @@ -2210,7 +1926,6 @@ static int sep_construct_dma_tables_from_lli( /* loop till all the entries in in array are not processed */ while (current_in_entry < sep_in_lli_entries) { - /* set the new input and output tables */ in_lli_table_ptr = (struct sep_lli_entry *)lli_table_alloc_addr; @@ -2229,8 +1944,7 @@ static int sep_construct_dma_tables_from_lli( SYNCHRONIC_DMA_TABLES_AREA_OFFSET_BYTES + SYNCHRONIC_DMA_TABLES_AREA_SIZE_BYTES)) { - dev_warn(&sep->pdev->dev, - "dma table limit overrun\n"); + dev_warn(&sep->pdev->dev, "dma table limit overrun\n"); return -ENOMEM; } @@ -2281,8 +1995,8 @@ static int sep_construct_dma_tables_from_lli( block_size; } - dev_dbg(&sep->pdev->dev, - "table_data_size is %x\n", table_data_size); + dev_dbg(&sep->pdev->dev, "table_data_size is %x\n", + table_data_size); /* construct input lli table */ sep_build_lli_table(sep, &lli_in_array[current_in_entry], @@ -2380,9 +2094,7 @@ static int sep_construct_dma_tables_from_lli( *out_num_entries_ptr, *table_data_size_ptr); - dev_dbg(&sep->pdev->dev, - "sep_construct_dma_tables_from_lli end\n"); - + dev_dbg(&sep->pdev->dev, "sep_construct_dma_tables_from_lli end\n"); return 0; } @@ -2418,20 +2130,15 @@ static int sep_prepare_input_output_dma_table(struct sep_device *sep, bool is_kva) { + int error = 0; /* array of pointers of page */ struct sep_lli_entry *lli_in_array; - /* array of pointers of page */ struct sep_lli_entry *lli_out_array; - /* error */ - int error = 0; - - dev_dbg(&sep->pdev->dev, - "sep_prepare_input_output_dma_table start\n"); + dev_dbg(&sep->pdev->dev, "sep_prepare_input_output_dma_table start\n"); if (data_size == 0) { - /* prepare empty table for input and output */ sep_prepare_empty_lli_table(sep, lli_table_in_ptr, in_num_entries_ptr, table_data_size_ptr); @@ -2471,8 +2178,8 @@ static int sep_prepare_input_output_dma_table(struct sep_device *sep, error = sep_lock_user_pages(sep, app_virt_in_addr, data_size, &lli_in_array, SEP_DRIVER_IN_FLAG); if (error) { - dev_warn(&sep->pdev->dev, "sep_lock_user_pages for " - "input virtual buffer failed\n"); + dev_warn(&sep->pdev->dev, + "sep_lock_user_pages for input virtual buffer failed\n"); goto end_function; } @@ -2480,20 +2187,17 @@ static int sep_prepare_input_output_dma_table(struct sep_device *sep, data_size, &lli_out_array, SEP_DRIVER_OUT_FLAG); if (error) { - dev_warn(&sep->pdev->dev, "sep_lock_user_pages for " - "output virtual buffer failed\n"); + dev_warn(&sep->pdev->dev, + "sep_lock_user_pages for output virtual buffer failed\n"); goto end_function_free_lli_in; } } - dev_dbg(&sep->pdev->dev, - "sep_in_num_pages is %x\n", + dev_dbg(&sep->pdev->dev, "sep_in_num_pages is %x\n", sep->dma_res_arr[sep->nr_dcb_creat].in_num_pages); - dev_dbg(&sep->pdev->dev, - "sep_out_num_pages is %x\n", + dev_dbg(&sep->pdev->dev, "sep_out_num_pages is %x\n", sep->dma_res_arr[sep->nr_dcb_creat].out_num_pages); - dev_dbg(&sep->pdev->dev, - "SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP is %x\n", + dev_dbg(&sep->pdev->dev, "SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP is %x\n", SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP); /* call the fucntion that creates table from the lli arrays */ @@ -2514,38 +2218,32 @@ static int sep_prepare_input_output_dma_table(struct sep_device *sep, kfree(lli_in_array); update_dcb_counter: - /* update dcb counter */ sep->nr_dcb_creat++; - /* fall through - free the lli entry arrays */ - dev_dbg(&sep->pdev->dev, - "in_num_entries_ptr is %08x\n", *in_num_entries_ptr); - dev_dbg(&sep->pdev->dev, - "out_num_entries_ptr is %08x\n", *out_num_entries_ptr); - dev_dbg(&sep->pdev->dev, - "table_data_size_ptr is %08x\n", *table_data_size_ptr); + dev_dbg(&sep->pdev->dev, "in_num_entries_ptr is %08x\n", + *in_num_entries_ptr); + dev_dbg(&sep->pdev->dev, "out_num_entries_ptr is %08x\n", + *out_num_entries_ptr); + dev_dbg(&sep->pdev->dev, "table_data_size_ptr is %08x\n", + *table_data_size_ptr); goto end_function; end_function_with_error: - kfree(sep->dma_res_arr[sep->nr_dcb_creat].out_map_array); kfree(sep->dma_res_arr[sep->nr_dcb_creat].out_page_array); kfree(lli_out_array); end_function_free_lli_in: - kfree(sep->dma_res_arr[sep->nr_dcb_creat].in_map_array); kfree(sep->dma_res_arr[sep->nr_dcb_creat].in_page_array); kfree(lli_in_array); end_function: - dev_dbg(&sep->pdev->dev, - "sep_prepare_input_output_dma_table" - " end result = %d\n", error); + "sep_prepare_input_output_dma_table end result = %d\n", error); return error; @@ -2576,35 +2274,26 @@ static int sep_prepare_input_output_dma_table_in_dcb(struct sep_device *sep, bool isapplet, bool is_kva) { - /* error */ int error = 0; - /* size of tail */ u32 tail_size = 0; - /* address of the created dcb table */ struct sep_dcblock *dcb_table_ptr = 0; - /* the physical address of the first input DMA table */ dma_addr_t in_first_mlli_address = 0; - /* number of entries in the first input DMA table */ u32 in_first_num_entries = 0; - /* the physical address of the first output DMA table */ dma_addr_t out_first_mlli_address = 0; - /* number of entries in the first output DMA table */ u32 out_first_num_entries = 0; - /* data in the first input/output table */ u32 first_data_size = 0; - dev_dbg(&sep->pdev->dev, - "prepare_input_output_dma_table_in_dcb start\n"); + dev_dbg(&sep->pdev->dev, "prepare_input_output_dma_table_in_dcb start\n"); if (sep->nr_dcb_creat == SEP_MAX_NUM_SYNC_DMA_OPS) { - /*No more DCBS to allocate*/ + /* No more DCBS to allocate */ dev_warn(&sep->pdev->dev, "no more dcb's available\n"); error = -ENOSPC; goto end_function; @@ -2627,17 +2316,12 @@ static int sep_prepare_input_output_dma_table_in_dcb(struct sep_device *sep, if (isapplet == true) { tail_size = data_in_size % block_size; - if (tail_size) { - if (data_in_size < tail_block_size) { - dev_warn(&sep->pdev->dev, - "data in size smaller than tail" - " block size\n"); + dev_warn(&sep->pdev->dev, "data in size smaller than tail block size\n"); error = -ENOSPC; goto end_function; } - if (tail_block_size) /* * case the tail size should be @@ -2645,7 +2329,7 @@ static int sep_prepare_input_output_dma_table_in_dcb(struct sep_device *sep, */ tail_size = tail_block_size + ((data_in_size - - tail_block_size) % block_size); + tail_block_size) % block_size); } /* check if there is enough data for dma operation */ @@ -2653,9 +2337,7 @@ static int sep_prepare_input_output_dma_table_in_dcb(struct sep_device *sep, if (is_kva == true) { memcpy(dcb_table_ptr->tail_data, (void *)app_in_address, data_in_size); - } - - else { + } else { if (copy_from_user(dcb_table_ptr->tail_data, (void __user *)app_in_address, data_in_size)) { @@ -2669,7 +2351,7 @@ static int sep_prepare_input_output_dma_table_in_dcb(struct sep_device *sep, /* set the output user-space address for mem2mem op */ if (app_out_address) dcb_table_ptr->out_vr_tail_pt = - (u32)app_out_address; + (u32)app_out_address; /* * Update both data length parameters in order to avoid @@ -2679,15 +2361,12 @@ static int sep_prepare_input_output_dma_table_in_dcb(struct sep_device *sep, tail_size = 0x0; data_in_size = 0x0; } - if (tail_size) { if (is_kva == true) { memcpy(dcb_table_ptr->tail_data, (void *)(app_in_address + data_in_size - tail_size), tail_size); - } - - else { + } else { /* we have tail data - copy it to dcb */ if (copy_from_user(dcb_table_ptr->tail_data, (void *)(app_in_address + @@ -2696,17 +2375,16 @@ static int sep_prepare_input_output_dma_table_in_dcb(struct sep_device *sep, goto end_function; } } - if (app_out_address) /* - * Caclulate the output address + * Calculate the output address * according to tail data size */ dcb_table_ptr->out_vr_tail_pt = app_out_address + data_in_size - tail_size; - /*save the real tail data size*/ + /* Save the real tail data size */ dcb_table_ptr->tail_data_size = tail_size; /* * Update the data size without the tail @@ -2715,7 +2393,6 @@ static int sep_prepare_input_output_dma_table_in_dcb(struct sep_device *sep, data_in_size = (data_in_size - tail_size); } } - /* check if we need to build only input table or input/output */ if (app_out_address) { /* prepare input/output tables */ @@ -2730,9 +2407,7 @@ static int sep_prepare_input_output_dma_table_in_dcb(struct sep_device *sep, &out_first_num_entries, &first_data_size, is_kva); - } - - else { + } else { /* prepare input tables */ error = sep_prepare_input_dma_table(sep, app_in_address, @@ -2745,8 +2420,7 @@ static int sep_prepare_input_output_dma_table_in_dcb(struct sep_device *sep, } if (error) { - dev_warn(&sep->pdev->dev, "prepare dma table call failed" - " from prepare dcb call\n"); + dev_warn(&sep->pdev->dev, "prepare dma table call failed from prepare dcb call\n"); goto end_function; } @@ -2759,7 +2433,6 @@ static int sep_prepare_input_output_dma_table_in_dcb(struct sep_device *sep, dcb_table_ptr->output_mlli_data_size = first_data_size; end_function: - dev_dbg(&sep->pdev->dev, "sep_prepare_input_output_dma_table_in_dcb end\n"); return error; @@ -2788,28 +2461,22 @@ static int sep_create_sync_dma_tables_handler(struct sep_device *sep, "sep_create_sync_dma_tables_handler start\n"); if (copy_from_user(&command_args, (void __user *)arg, - sizeof(struct bld_syn_tab_struct))) { + sizeof(struct bld_syn_tab_struct))) { error = -EFAULT; - dev_warn(&sep->pdev->dev, "create dma tables;" - " copy_from_user fails\n"); goto end_function; } - dev_dbg(&sep->pdev->dev, - "app_in_address is %08llx\n", command_args.app_in_address); - dev_dbg(&sep->pdev->dev, - "app_out_address is %08llx\n", command_args.app_out_address); - dev_dbg(&sep->pdev->dev, - "data_size is %u\n", command_args.data_in_size); - dev_dbg(&sep->pdev->dev, - "block_size is %u\n", command_args.block_size); + dev_dbg(&sep->pdev->dev, "app_in_address is %08llx\n", + command_args.app_in_address); + dev_dbg(&sep->pdev->dev, "app_out_address is %08llx\n", + command_args.app_out_address); + dev_dbg(&sep->pdev->dev, "data_size is %u\n", + command_args.data_in_size); + dev_dbg(&sep->pdev->dev, "block_size is %u\n", + command_args.block_size); /* validate user parameters */ if (!command_args.app_in_address) { - - dev_warn(&sep->pdev->dev, - "params validation error\n"); - error = -EINVAL; goto end_function; } @@ -2824,7 +2491,6 @@ static int sep_create_sync_dma_tables_handler(struct sep_device *sep, false); end_function: - dev_dbg(&sep->pdev->dev, "sep_create_sync_dma_tables_handler end\n"); return error; } @@ -2840,17 +2506,14 @@ end_function: static int sep_free_dma_tables_and_dcb(struct sep_device *sep, bool isapplet, bool is_kva) { - int i = 0; int error = 0; int error_temp = 0; - struct sep_dcblock *dcb_table_ptr; dev_dbg(&sep->pdev->dev, "sep_free_dma_tables_and_dcb start\n"); if (isapplet == true) { - /* set pointer to first dcb table */ dcb_table_ptr = (struct sep_dcblock *) (sep->shared_addr + @@ -2858,30 +2521,25 @@ static int sep_free_dma_tables_and_dcb(struct sep_device *sep, bool isapplet, /* go over each dcb and see if tail pointer must be updated */ for (i = 0; i < sep->nr_dcb_creat; i++, dcb_table_ptr++) { - if (dcb_table_ptr->out_vr_tail_pt) { - if (is_kva == true) { memcpy((void *)dcb_table_ptr->out_vr_tail_pt, dcb_table_ptr->tail_data, dcb_table_ptr->tail_data_size); - } - - else { + } else { error_temp = copy_to_user( (void *)dcb_table_ptr->out_vr_tail_pt, dcb_table_ptr->tail_data, dcb_table_ptr->tail_data_size); } - if (error_temp) { /* release the dma resource */ - error = error_temp; + error = -EFAULT; + break; } } } } - /* free the output pages, if any */ sep_free_dma_table_data_handler(sep); @@ -2901,9 +2559,7 @@ static int sep_get_static_pool_addr_handler(struct sep_device *sep, unsigned long arg) { struct stat_pool_addr_struct command_args; - u32 *static_pool_addr = 0; - unsigned long addr_hold; dev_dbg(&sep->pdev->dev, "sep_get_static_pool_addr_handler start\n"); @@ -3013,22 +2669,18 @@ static int sep_init_handler(struct sep_device *sep, unsigned long arg) struct init_struct command_args; dev_dbg(&sep->pdev->dev, "sep_init_handler start\n"); - error = 0; /* make sure that we have not initialized already */ reg_val = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR3_REG_ADDR); if (reg_val != 0x2) { error = SEP_ALREADY_INITIALIZED_ERR; - dev_warn(&sep->pdev->dev, - "init; device already initialized\n"); + dev_warn(&sep->pdev->dev, "init; device already initialized\n"); goto end_function; } /* only root can initialize */ if (!capable(CAP_SYS_ADMIN)) { - dev_warn(&sep->pdev->dev, - "init; only root can init\n"); error = -EACCES; goto end_function; } @@ -3038,17 +2690,13 @@ static int sep_init_handler(struct sep_device *sep, unsigned long arg) sizeof(struct init_struct)); if (error) { - dev_warn(&sep->pdev->dev, - "init; copy_from_user failed %x\n", error); + error = -EFAULT; goto end_function; } /* validate parameters */ if (!command_args.message_addr || !command_args.sep_sram_addr || command_args.message_size_in_words > 14) { - - dev_warn(&sep->pdev->dev, - "init; parameter error\n"); error = -EINVAL; goto end_function; } @@ -3060,9 +2708,7 @@ static int sep_init_handler(struct sep_device *sep, unsigned long arg) command_args.message_size_in_words*sizeof(u32)); if (error) { - - dev_warn(&sep->pdev->dev, - "init; copy sep init message failed %x\n", error); + error = -EFAULT; goto end_function; } @@ -3070,7 +2716,6 @@ static int sep_init_handler(struct sep_device *sep, unsigned long arg) error = sep_load_firmware(sep); if (error) { - dev_warn(&sep->pdev->dev, "init; copy sep init message failed %x\n", error); goto end_function; @@ -3102,10 +2747,8 @@ static int sep_init_handler(struct sep_device *sep, unsigned long arg) /* debug print of message */ for (counter = 0; counter < command_args.message_size_in_words; - counter++) - - dev_dbg(&sep->pdev->dev, - "init; sep message word %d is %x\n", + counter++) + dev_dbg(&sep->pdev->dev, "init; sep message word %d is %x\n", counter, message_buff[counter]); /* tell the sep the sram address */ @@ -3113,11 +2756,9 @@ static int sep_init_handler(struct sep_device *sep, unsigned long arg) /* push the message to the sep */ for (counter = 0; counter < command_args.message_size_in_words; - counter++) { - + counter++) { sep_write_reg(sep, HW_SRAM_DATA_REG_ADDR, - message_buff[counter]); - + message_buff[counter]); sep_wait_sram_write(sep); } @@ -3132,7 +2773,6 @@ static int sep_init_handler(struct sep_device *sep, unsigned long arg) while (!(reg_val & 0xFFFFFFFD)); if (reg_val == 0x1) { - dev_warn(&sep->pdev->dev, "init; device int failed\n"); error = sep_read_reg(sep, 0x8060); dev_warn(&sep->pdev->dev, "init; sw monitor is %x\n", error); @@ -3140,9 +2780,7 @@ static int sep_init_handler(struct sep_device *sep, unsigned long arg) dev_warn(&sep->pdev->dev, "init; error is %x\n", error); goto end_function; } - - dev_dbg(&sep->pdev->dev, "init; end CC INIT, reg_val is %x\n", - reg_val); + dev_dbg(&sep->pdev->dev, "init; end CC INIT, reg_val is %x\n", reg_val); /* signal sep to zero the GPR3 */ sep_write_reg(sep, HW_HOST_HOST_SEP_GPR0_REG_ADDR, 0x10); @@ -3154,7 +2792,6 @@ static int sep_init_handler(struct sep_device *sep, unsigned long arg) reg_val = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR3_REG_ADDR); while (reg_val != 0); - end_function: dev_dbg(&sep->pdev->dev, "init is done\n"); return error; @@ -3205,34 +2842,32 @@ static int sep_end_transaction_handler(struct sep_device *sep) * This function will retrieve the RAR buffer physical addresses, type * & size corresponding to the RAR handles provided in the buffers vector. */ - static int sep_prepare_dcb_handler(struct sep_device *sep, unsigned long arg) { /* error */ - int error = 0; - + int error; /* command arguments */ struct build_dcb_struct command_args; dev_dbg(&sep->pdev->dev, "sep_prepare_dcb_handler start\n"); - /* get the command arguments */ + /* Get the command arguments */ if (copy_from_user(&command_args, (void __user *)arg, - sizeof(struct build_dcb_struct))) { + sizeof(struct build_dcb_struct))) { error = -EFAULT; goto end_function; } - dev_dbg(&sep->pdev->dev, - "app_in_address is %08llx\n", command_args.app_in_address); - dev_dbg(&sep->pdev->dev, - "app_out_address is %08llx\n", command_args.app_out_address); - dev_dbg(&sep->pdev->dev, - "data_size is %x\n", command_args.data_in_size); - dev_dbg(&sep->pdev->dev, - "block_size is %x\n", command_args.block_size); - dev_dbg(&sep->pdev->dev, - "tail block_size is %x\n", command_args.tail_block_size); + dev_dbg(&sep->pdev->dev, "app_in_address is %08llx\n", + command_args.app_in_address); + dev_dbg(&sep->pdev->dev, "app_out_address is %08llx\n", + command_args.app_out_address); + dev_dbg(&sep->pdev->dev, "data_size is %x\n", + command_args.data_in_size); + dev_dbg(&sep->pdev->dev, "block_size is %x\n", + command_args.block_size); + dev_dbg(&sep->pdev->dev, "tail block_size is %x\n", + command_args.tail_block_size); error = sep_prepare_input_output_dma_table_in_dcb(sep, command_args.app_in_address, command_args.app_out_address, @@ -3240,7 +2875,6 @@ static int sep_prepare_dcb_handler(struct sep_device *sep, unsigned long arg) command_args.tail_block_size, true, false); end_function: - dev_dbg(&sep->pdev->dev, "sep_prepare_dcb_handler end\n"); return error; @@ -3274,52 +2908,40 @@ static int sep_free_dcb_handler(struct sep_device *sep) * This function will retrieve the RAR buffer physical addresses, type * & size corresponding to the RAR handles provided in the buffers vector. */ - static int sep_rar_prepare_output_msg_handler(struct sep_device *sep, unsigned long arg) { - /* error return code */ int error = 0; - /* command args */ struct rar_hndl_to_bus_struct command_args; struct RAR_buffer rar_buf; - /* bus address */ dma_addr_t rar_bus = 0; - /* holds the RAR address in the system memory offset */ u32 *rar_addr; - dev_dbg(&sep->pdev->dev, - "sep_rar_prepare_output_msg_handler start\n"); + dev_dbg(&sep->pdev->dev, "sep_rar_prepare_output_msg_handler start\n"); /* copy the data */ - if (copy_from_user(&command_args, - (void __user *)arg, - sizeof(command_args))) { + if (copy_from_user(&command_args, (void __user *)arg, + sizeof(command_args))) { error = -EFAULT; goto end_function; } /* call to translation function only if user handle is not NULL */ if (command_args.rar_handle) { - memset(&rar_buf, 0, sizeof(rar_buf)); rar_buf.info.handle = (u32)command_args.rar_handle; if (rar_handle_to_bus(&rar_buf, 1) != 1) { - dev_dbg(&sep->pdev->dev, - "rar_handle_to_bus failure\n"); + dev_dbg(&sep->pdev->dev, "rar_handle_to_bus failure\n"); error = -EFAULT; goto end_function; } - rar_bus = rar_buf.bus_address; } - - dev_dbg(&sep->pdev->dev, "rar msg; rar_addr_bus = %x\n", - (u32)rar_bus); + dev_dbg(&sep->pdev->dev, "rar msg; rar_addr_bus = %x\n", (u32)rar_bus); /* set value in the SYSTEM MEMORY offset */ rar_addr = (u32 *)(sep->shared_addr + @@ -3330,10 +2952,7 @@ static int sep_rar_prepare_output_msg_handler(struct sep_device *sep, rar_addr[1] = rar_bus; end_function: - - dev_dbg(&sep->pdev->dev, - "sep_rar_prepare_output_msg_handler start\n"); - + dev_dbg(&sep->pdev->dev, "sep_rar_prepare_output_msg_handler start\n"); return error; } @@ -3355,13 +2974,12 @@ static int sep_realloc_ext_cache_handler(struct sep_device *sep, SEP_DRIVER_SYSTEM_EXT_CACHE_ADDR_OFFSET_IN_BYTES); /* copy the physical address to the System Area for the sep */ - system_addr[0] = SEP_EXT_CACHE_ADDR_VAL_TOKEN; - dev_dbg(&sep->pdev->dev, - "ext cache init; system addr 0 is %x\n", system_addr[0]); + dev_dbg(&sep->pdev->dev, "ext cache init; system addr 0 is %x\n", + system_addr[0]); system_addr[1] = sep->extapp_bus; - dev_dbg(&sep->pdev->dev, - "ext cache init; system addr 1 is %x\n", system_addr[1]); + dev_dbg(&sep->pdev->dev, "ext cache init; system addr 1 is %x\n", + system_addr[1]); return 0; } @@ -3410,8 +3028,7 @@ static long sep_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) /* make sure we own this device */ mutex_lock(&sep->sep_mutex); if ((current->pid != sep->pid_doing_transaction) && - (sep->pid_doing_transaction != 0)) { - + (sep->pid_doing_transaction != 0)) { dev_dbg(&sep->pdev->dev, "ioctl pid is not owner\n"); mutex_unlock(&sep->sep_mutex); error = -EACCES; @@ -3485,15 +3102,13 @@ static long sep_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) error = sep_free_dcb_handler(sep); break; default: - dev_warn(&sep->pdev->dev, "invalid ioctl %x\n", cmd); + dev_dbg(&sep->pdev->dev, "invalid ioctl %x\n", cmd); error = -ENOTTY; break; } - mutex_unlock(&sep->ioctl_mutex); end_function: - dev_dbg(&sep->pdev->dev, "ioctl end\n"); return error; } @@ -3508,18 +3123,12 @@ end_function: */ static long sep_singleton_ioctl(struct file *filp, u32 cmd, unsigned long arg) { - /* error */ - long error; + long error = 0; struct sep_device *sep = filp->private_data; - error = 0; - - dev_dbg(&sep->pdev->dev, - "singleton_ioctl start\n"); - - dev_dbg(&sep->pdev->dev, - "cmd is %x\n", cmd); + dev_dbg(&sep->pdev->dev, "singleton_ioctl start\n"); + dev_dbg(&sep->pdev->dev, "cmd is %x\n", cmd); /* check that the command is for sep device */ if (_IOC_TYPE(cmd) != SEP_IOC_MAGIC_NUMBER) { @@ -3530,8 +3139,7 @@ static long sep_singleton_ioctl(struct file *filp, u32 cmd, unsigned long arg) /* make sure we own this device */ mutex_lock(&sep->sep_mutex); if ((current->pid != sep->pid_doing_transaction) && - (sep->pid_doing_transaction != 0)) { - + (sep->pid_doing_transaction != 0)) { dev_dbg(&sep->pdev->dev, "singleton ioctl pid is not owner\n"); mutex_unlock(&sep->sep_mutex); error = -EACCES; @@ -3541,21 +3149,17 @@ static long sep_singleton_ioctl(struct file *filp, u32 cmd, unsigned long arg) mutex_unlock(&sep->sep_mutex); switch (cmd) { - case SEP_IOCTLSETCALLERID: mutex_lock(&sep->ioctl_mutex); error = sep_set_caller_id_handler(sep, arg); mutex_unlock(&sep->ioctl_mutex); break; - default: error = sep_ioctl(filp, cmd, arg); break; - } end_function: - dev_dbg(&sep->pdev->dev, "singleton ioctl end\n"); return error; } @@ -3568,20 +3172,15 @@ end_function: * * Called by the request daemon to perform ioctls on the daemon device */ - static long sep_request_daemon_ioctl(struct file *filp, u32 cmd, unsigned long arg) { long error; - struct sep_device *sep = filp->private_data; - dev_dbg(&sep->pdev->dev, - "daemon ioctl: start\n"); - - dev_dbg(&sep->pdev->dev, - "daemon ioctl: cmd is %x\n", cmd); + dev_dbg(&sep->pdev->dev, "daemon ioctl: start\n"); + dev_dbg(&sep->pdev->dev, "daemon ioctl: cmd is %x\n", cmd); /* check that the command is for sep device */ if (_IOC_TYPE(cmd) != SEP_IOC_MAGIC_NUMBER) { @@ -3594,13 +3193,10 @@ static long sep_request_daemon_ioctl(struct file *filp, u32 cmd, switch (cmd) { case SEP_IOCSENDSEPRPLYCOMMAND: - /* send reply command to SEP */ error = sep_req_daemon_send_reply_command_handler(sep); break; - case SEP_IOCENDTRANSACTION: - /* * end req daemon transaction, do nothing * will be removed upon update in middleware @@ -3608,19 +3204,14 @@ static long sep_request_daemon_ioctl(struct file *filp, u32 cmd, */ error = 0; break; - default: - dev_dbg(&sep->pdev->dev, - "daemon ioctl: no such IOCTL\n"); + dev_dbg(&sep->pdev->dev, "daemon ioctl: no such IOCTL\n"); error = -ENOTTY; } - mutex_unlock(&sep->ioctl_mutex); end_function: - - dev_dbg(&sep->pdev->dev, - "daemon ioctl: end\n"); + dev_dbg(&sep->pdev->dev, "daemon ioctl: end\n"); return error; } @@ -3630,7 +3221,6 @@ end_function: * @irq: interrupt * @dev_id: device id */ - static irqreturn_t sep_inthandler(int irq, void *dev_id) { irqreturn_t int_error = IRQ_HANDLED; @@ -3640,18 +3230,16 @@ static irqreturn_t sep_inthandler(int irq, void *dev_id) /* read the IRR register to check if this is SEP interrupt */ reg_val = sep_read_reg(sep, HW_HOST_IRR_REG_ADDR); - dev_dbg(&sep->pdev->dev, - "SEP Interrupt - reg is %08x\n", reg_val); + dev_dbg(&sep->pdev->dev, "SEP Interrupt - reg is %08x\n", reg_val); if (reg_val & (0x1 << 13)) { - /* lock and update the counter of reply messages */ spin_lock_irqsave(&sep->snd_rply_lck, lck_flags); sep->reply_ct++; spin_unlock_irqrestore(&sep->snd_rply_lck, lck_flags); dev_dbg(&sep->pdev->dev, "sep int: send_ct %lx reply_ct %lx\n", - sep->send_ct, sep->reply_ct); + sep->send_ct, sep->reply_ct); /* is this printf or daemon request? */ reg_val2 = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR2_REG_ADDR); @@ -3659,27 +3247,19 @@ static irqreturn_t sep_inthandler(int irq, void *dev_id) "SEP Interrupt - reg2 is %08x\n", reg_val2); if ((reg_val2 >> 30) & 0x1) { - dev_dbg(&sep->pdev->dev, "int: printf request\n"); wake_up(&sep->event_request_daemon); - } - - else if (reg_val2 >> 31) { - + } else if (reg_val2 >> 31) { dev_dbg(&sep->pdev->dev, "int: daemon request\n"); wake_up(&sep->event_request_daemon); } else { - dev_dbg(&sep->pdev->dev, "int: sep reply\n"); wake_up(&sep->event); } - } else { - dev_dbg(&sep->pdev->dev, "int: not sep interrupt\n"); int_error = IRQ_NONE; } - if (int_error == IRQ_HANDLED) sep_write_reg(sep, HW_HOST_ICR_REG_ADDR, reg_val); @@ -3695,16 +3275,14 @@ static irqreturn_t sep_inthandler(int irq, void *dev_id) */ static int sep_callback(unsigned long sep_context_pointer) { - int error = 0; - struct sep_device *sep = - (struct sep_device *)sep_context_pointer; - - dma_addr_t rar_end_address = 0; + int error; + struct sep_device *sep = (struct sep_device *)sep_context_pointer; + dma_addr_t rar_end_address; dev_dbg(&sep->pdev->dev, "callback start\n"); error = rar_get_address(RAR_TYPE_IMAGE, &sep->rar_bus, - &rar_end_address); + &rar_end_address); if (error) { dev_warn(&sep->pdev->dev, "mrst cant get rar region\n"); @@ -3714,9 +3292,9 @@ static int sep_callback(unsigned long sep_context_pointer) sep->rar_size = (size_t)(rar_end_address - sep->rar_bus + 1); if (!request_mem_region(sep->rar_bus, sep->rar_size, - "sep_sec_driver")) { + "sep_sec_driver")) { dev_warn(&sep->pdev->dev, - "request mem region for mrst failed\n"); + "request mem region for mrst failed\n"); error = -1; goto end_function; } @@ -3724,18 +3302,15 @@ static int sep_callback(unsigned long sep_context_pointer) sep->rar_addr = ioremap_nocache(sep->rar_bus, sep->rar_size); if (!sep->rar_addr) { dev_warn(&sep->pdev->dev, - "ioremap nocache for mrst rar failed\n"); - error = -1; + "ioremap nocache for mrst rar failed\n"); + error = -ENOMEM; goto end_function; } - - dev_dbg(&sep->pdev->dev, "rar start is %p, phy is %llx," - " size is %x\n", - sep->rar_addr, (unsigned long long)sep->rar_bus, - sep->rar_size); + dev_dbg(&sep->pdev->dev, "rar start is %p, phy is %llx, size is %x\n", + sep->rar_addr, (unsigned long long)sep->rar_bus, + sep->rar_size); end_function: - dev_dbg(&sep->pdev->dev, "callback end\n"); return error; } @@ -3769,7 +3344,6 @@ static int __devinit sep_probe(struct pci_dev *pdev, /* allocate the sep_device structure for this device */ sep_dev = kmalloc(sizeof(struct sep_device), GFP_ATOMIC); - if (sep_dev == NULL) { dev_warn(&pdev->dev, "can't kmalloc the sep_device structure\n"); @@ -3865,8 +3439,7 @@ static int __devinit sep_probe(struct pci_dev *pdev, sep->rar_size); } - dev_dbg(&sep->pdev->dev, - "about to write IMR and ICR REG_ADDR\n"); + dev_dbg(&sep->pdev->dev, "about to write IMR and ICR REG_ADDR\n"); /* clear ICR register */ sep_write_reg(sep, HW_HOST_ICR_REG_ADDR, 0xFFFFFFFF); @@ -3874,18 +3447,14 @@ static int __devinit sep_probe(struct pci_dev *pdev, /* set the IMR register - open only GPR 2 */ sep_write_reg(sep, HW_HOST_IMR_REG_ADDR, (~(0x1 << 13))); - dev_dbg(&sep->pdev->dev, - "about to call request_irq\n"); + dev_dbg(&sep->pdev->dev, "about to call request_irq\n"); /* get the interrupt line */ error = request_irq(pdev->irq, sep_inthandler, IRQF_SHARED, "sep_driver", sep); - if (error) - goto end_function_free_res; - - goto end_function; + if (!error) + goto end_function; -end_function_free_res: if (sep->rar_addr) dma_free_coherent(&sep->pdev->dev, sep->rar_size, sep->rar_addr, sep->rar_bus); @@ -3959,37 +3528,29 @@ static const struct file_operations sep_file_operations = { */ static int sep_reconfig_shared_area(struct sep_device *sep) { - int ret_val = 0; + int ret_val; dev_dbg(&sep->pdev->dev, "reconfig shared area start\n"); /* send the new SHARED MESSAGE AREA to the SEP */ dev_dbg(&sep->pdev->dev, "sending %08llx to sep\n", - (unsigned long long)sep->shared_bus); + (unsigned long long)sep->shared_bus); - sep_write_reg(sep, HW_HOST_HOST_SEP_GPR1_REG_ADDR, - sep->shared_bus); + sep_write_reg(sep, HW_HOST_HOST_SEP_GPR1_REG_ADDR, sep->shared_bus); /* poll for SEP response */ ret_val = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR1_REG_ADDR); - while (ret_val != 0xffffffff && - ret_val != sep->shared_bus) { - - ret_val = sep_read_reg(sep, - HW_HOST_SEP_HOST_GPR1_REG_ADDR); - } + while (ret_val != 0xffffffff && ret_val != sep->shared_bus) + ret_val = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR1_REG_ADDR); /* check the return value (register) */ if (ret_val != sep->shared_bus) { dev_warn(&sep->pdev->dev, "could not reconfig shared area\n"); dev_warn(&sep->pdev->dev, "result was %x\n", ret_val); ret_val = -ENOMEM; - } - - else { + } else ret_val = 0; - } dev_dbg(&sep->pdev->dev, "reconfig shared area end\n"); return ret_val; @@ -4003,7 +3564,7 @@ static int sep_reconfig_shared_area(struct sep_device *sep) */ static int sep_register_driver_to_fs(struct sep_device *sep) { - int ret_val = 0; + int ret_val; sep->miscdev_sep.minor = MISC_DYNAMIC_MINOR; sep->miscdev_sep.name = SEP_DEV_NAME; @@ -4035,8 +3596,7 @@ static int sep_register_driver_to_fs(struct sep_device *sep) if (!sep->mrst) { ret_val = misc_register(&sep->miscdev_daemon); if (ret_val) { - dev_warn(&sep->pdev->dev, - "misc reg fails for dmn %x\n", + dev_warn(&sep->pdev->dev, "misc reg fails for dmn %x\n", ret_val); misc_deregister(&sep->miscdev_sep); misc_deregister(&sep->miscdev_singleton); @@ -4044,7 +3604,6 @@ static int sep_register_driver_to_fs(struct sep_device *sep) return ret_val; } } - return ret_val; } @@ -4062,8 +3621,8 @@ static int __init sep_init(void) ret_val = pci_register_driver(&sep_pci_driver); if (ret_val) { - pr_debug("sep_driver:sep_driver_to_device failed," - " ret_val is %d\n", ret_val); + pr_debug("sep_driver:sep_driver_to_device failed, ret_val is %d\n", + ret_val); goto end_function; } @@ -4085,11 +3644,9 @@ static int __init sep_init(void) /* register driver to fs */ ret_val = sep_register_driver_to_fs(sep); if (ret_val) { - dev_warn(&sep->pdev->dev, - "error registering device to file\n"); + dev_warn(&sep->pdev->dev, "error registering device to file\n"); goto end_function_unregister_pci; } - goto end_function; end_function_unregister_pci: -- cgit v1.2.3 From 7c9eb69123a634c8551e8887bda03c2e549da233 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Wed, 24 Nov 2010 19:38:21 +0000 Subject: Staging: sep: Use kzalloc when needed Signed-off-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/staging/sep/sep_driver.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/drivers/staging/sep/sep_driver.c b/drivers/staging/sep/sep_driver.c index f576285fbb8f..ff9df36d5461 100644 --- a/drivers/staging/sep/sep_driver.c +++ b/drivers/staging/sep/sep_driver.c @@ -3343,16 +3343,13 @@ static int __devinit sep_probe(struct pci_dev *pdev, } /* allocate the sep_device structure for this device */ - sep_dev = kmalloc(sizeof(struct sep_device), GFP_ATOMIC); + sep_dev = kzalloc(sizeof(struct sep_device), GFP_ATOMIC); if (sep_dev == NULL) { dev_warn(&pdev->dev, "can't kmalloc the sep_device structure\n"); return -ENOMEM; } - /* zero out sep structure */ - memset((void *)sep_dev, 0, sizeof(struct sep_device)); - /* * we're going to use another variable for actually * working with the device; this way, if we have @@ -3365,8 +3362,6 @@ static int __devinit sep_probe(struct pci_dev *pdev, if (pdev->device == MRST_PCI_DEVICE_ID) sep->mrst = 1; - else - sep->mrst = 0; dev_dbg(&sep->pdev->dev, "PCI obtained, device being prepared\n"); dev_dbg(&sep->pdev->dev, "revision is %d\n", sep->pdev->revision); @@ -3423,7 +3418,6 @@ static int __devinit sep_probe(struct pci_dev *pdev, goto end_function_deallocate_sep_shared_area; } } else { - sep->rar_size = FAKE_RAR_SIZE; sep->rar_addr = dma_alloc_coherent(NULL, sep->rar_size, &sep->rar_bus, GFP_KERNEL); -- cgit v1.2.3 From 6eb44c531763ff50325822bac749e92938782795 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Wed, 24 Nov 2010 19:38:39 +0000 Subject: Staging: sep: Make SEP consistent SEP is initials so make it consistent in the driver, ditto DMA and DCB Consistent capitalisation of comment leads Signed-off-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/staging/sep/sep_driver.c | 631 +++++++++++++++++++-------------------- 1 file changed, 313 insertions(+), 318 deletions(-) diff --git a/drivers/staging/sep/sep_driver.c b/drivers/staging/sep/sep_driver.c index ff9df36d5461..9c165587a247 100644 --- a/drivers/staging/sep/sep_driver.c +++ b/drivers/staging/sep/sep_driver.c @@ -92,7 +92,7 @@ static int sep_load_firmware(struct sep_device *sep) int error ; unsigned int work1, work2, work3; - /* set addresses and load resident */ + /* Set addresses and load resident */ sep->resident_bus = sep->rar_bus; sep->resident_addr = sep->rar_addr; @@ -113,7 +113,7 @@ static int sep_load_firmware(struct sep_device *sep) dev_dbg(&sep->pdev->dev, "resident size is %08x\n", sep->resident_size); - /* set addresses for dcache (no loading needed) */ + /* Set addresses for dcache (no loading needed) */ work1 = (unsigned int)sep->resident_bus; work2 = (unsigned int)sep->resident_size; work3 = (work1 + work2 + (1024 * 4)) & 0xfffff000; @@ -126,7 +126,7 @@ static int sep_load_firmware(struct sep_device *sep) sep->dcache_size = 1024 * 128; - /* set addresses and load cache */ + /* Set addresses and load cache */ sep->cache_bus = sep->dcache_bus + sep->dcache_size; sep->cache_addr = sep->dcache_addr + sep->dcache_size; @@ -147,7 +147,7 @@ static int sep_load_firmware(struct sep_device *sep) dev_dbg(&sep->pdev->dev, "cache size is %08x\n", sep->cache_size); - /* set addresses and load extapp */ + /* Set addresses and load extapp */ sep->extapp_bus = sep->cache_bus + (1024 * 370); sep->extapp_addr = sep->cache_addr + (1024 * 370); @@ -177,7 +177,7 @@ MODULE_FIRMWARE("sep/extapp.image.bin"); /** * sep_dump_message - dump the message that is pending - * @sep: sep device + * @sep: SEP device */ static void sep_dump_message(struct sep_device *sep) { @@ -205,7 +205,7 @@ static int sep_map_and_alloc_shared_area(struct sep_device *sep) return -ENOMEM; } dev_dbg(&sep->pdev->dev, - "sep: shared_addr %x bytes @%p (bus %llx)\n", + "shared_addr %x bytes @%p (bus %llx)\n", sep->shared_size, sep->shared_addr, (unsigned long long)sep->shared_bus); return 0; @@ -249,7 +249,7 @@ static int sep_singleton_open(struct inode *inode_ptr, struct file *file_ptr) struct sep_device *sep; /* - * Get the sep device structure and use it for the + * Get the SEP device structure and use it for the * private_data field in filp for other methods */ sep = sep_dev; @@ -274,8 +274,8 @@ end_function: /** * sep_open - device open method - * @inode: inode of sep device - * @filp: file handle to sep device + * @inode: inode of SEP device + * @filp: file handle to SEP device * * Open method for the SEP device. Called when userspace opens * the SEP device node. @@ -287,7 +287,7 @@ static int sep_open(struct inode *inode, struct file *filp) struct sep_device *sep; /* - * Get the sep device structure and use it for the + * Get the SEP device structure and use it for the * private_data field in filp for other methods */ sep = sep_dev; @@ -320,8 +320,8 @@ static int sep_singleton_release(struct inode *inode, struct file *filp) /** * sep_request_daemonopen - request daemon open method - * @inode: inode of sep device - * @filp: file handle to sep device + * @inode: inode of SEP device + * @filp: file handle to SEP device * * Open method for the SEP request daemon. Called when * request daemon in userspace opens the SEP device node. @@ -359,7 +359,7 @@ static int sep_request_daemon_release(struct inode *inode, struct file *filp) dev_dbg(&sep->pdev->dev, "Reques daemon release for pid %d\n", current->pid); - /* clear the request_daemon_open flag */ + /* Clear the request_daemon_open flag */ clear_bit(0, &sep->request_daemon_open); return 0; } @@ -380,12 +380,12 @@ static int sep_req_daemon_send_reply_command_handler(struct sep_device *sep) sep_dump_message(sep); - /* counters are lockable region */ + /* Counters are lockable region */ spin_lock_irqsave(&sep->snd_rply_lck, lck_flags); sep->send_ct++; sep->reply_ct++; - /* send the interrupt to SEP */ + /* Send the interrupt to SEP */ sep_write_reg(sep, HW_HOST_HOST_SEP_GPR2_REG_ADDR, sep->send_ct); @@ -408,13 +408,13 @@ static int sep_req_daemon_send_reply_command_handler(struct sep_device *sep) * sep_free_dma_table_data_handler - free DMA table * @sep: pointere to struct sep_device * - * Handles the request to free dma table for synchronic actions + * Handles the request to free DMA table for synchronic actions */ static int sep_free_dma_table_data_handler(struct sep_device *sep) { int count; int dcb_counter; - /* pointer to the current dma_resource struct */ + /* Pointer to the current dma_resource struct */ struct sep_dma_resource *dma; dev_dbg(&sep->pdev->dev, "sep_free_dma_table_data_handler start\n"); @@ -422,7 +422,7 @@ static int sep_free_dma_table_data_handler(struct sep_device *sep) for (dcb_counter = 0; dcb_counter < sep->nr_dcb_creat; dcb_counter++) { dma = &sep->dma_res_arr[dcb_counter]; - /* unmap and free input map array */ + /* Unmap and free input map array */ if (dma->in_map_array) { for (count = 0; count < dma->in_num_pages; count++) { dma_unmap_page(&sep->pdev->dev, @@ -433,7 +433,7 @@ static int sep_free_dma_table_data_handler(struct sep_device *sep) kfree(dma->in_map_array); } - /* unmap output map array, DON'T free it yet */ + /* Unmap output map array, DON'T free it yet */ if (dma->out_map_array) { for (count = 0; count < dma->out_num_pages; count++) { dma_unmap_page(&sep->pdev->dev, @@ -444,7 +444,7 @@ static int sep_free_dma_table_data_handler(struct sep_device *sep) kfree(dma->out_map_array); } - /* free page cache for output */ + /* Free page cache for output */ if (dma->in_page_array) { for (count = 0; count < dma->in_num_pages; count++) { flush_dcache_page(dma->in_page_array[count]); @@ -463,7 +463,7 @@ static int sep_free_dma_table_data_handler(struct sep_device *sep) kfree(dma->out_page_array); } - /* reset all the values */ + /* Reset all the values */ dma->in_page_array = 0; dma->out_page_array = 0; dma->in_num_pages = 0; @@ -503,7 +503,7 @@ static int sep_request_daemon_mmap(struct file *filp, goto end_function; } - /* get physical address */ + /* Get physical address */ bus_address = sep->shared_bus; dev_dbg(&sep->pdev->dev, "bus_address is %08lx\n", @@ -524,7 +524,7 @@ end_function: /** * sep_request_daemon_poll - poll implementation - * @sep: struct sep_device * for current sep device + * @sep: struct sep_device * for current SEP device * @filp: struct file * for open file * @wait: poll_table * for poll * @@ -547,7 +547,7 @@ static unsigned int sep_request_daemon_poll(struct file *filp, sep->send_ct, sep->reply_ct); spin_lock_irqsave(&sep->snd_rply_lck, lck_flags); - /* check if the data is ready */ + /* Check if the data is ready */ if (sep->send_ct == sep->reply_ct) { spin_unlock_irqrestore(&sep->snd_rply_lck, lck_flags); @@ -555,13 +555,13 @@ static unsigned int sep_request_daemon_poll(struct file *filp, dev_dbg(&sep->pdev->dev, "daemon poll: data check (GPR2) is %x\n", retval2); - /* check if PRINT request */ + /* Check if PRINT request */ if ((retval2 >> 30) & 0x1) { dev_dbg(&sep->pdev->dev, "daemon poll: PRINTF request in\n"); mask |= POLLIN; goto end_function; } - /* check if NVS request */ + /* Check if NVS request */ if (retval2 >> 31) { dev_dbg(&sep->pdev->dev, "daemon poll: NVS request in\n"); mask |= POLLPRI | POLLWRNORM; @@ -591,7 +591,7 @@ static int sep_release(struct inode *inode, struct file *filp) dev_dbg(&sep->pdev->dev, "Release for pid %d\n", current->pid); mutex_lock(&sep->sep_mutex); - /* is this the process that has a transaction open? + /* Is this the process that has a transaction open? * If so, lets reset pid_doing_transaction to 0 and * clear the in use flags, and then wake up sep_event * so that other processes can do transactions @@ -614,7 +614,7 @@ static int sep_release(struct inode *inode, struct file *filp) * @filp: pointer to struct file * @vma: pointer to vm_area_struct * - * Called on an mmap of our space via the normal sep device + * Called on an mmap of our space via the normal SEP device */ static int sep_mmap(struct file *filp, struct vm_area_struct *vma) { @@ -636,8 +636,8 @@ static int sep_mmap(struct file *filp, struct vm_area_struct *vma) /* * The pid_doing_transaction indicates that this process * now owns the facilities to performa a transaction with - * the sep. While this process is performing a transaction, - * no other process who has the sep device open can perform + * the SEP. While this process is performing a transaction, + * no other process who has the SEP device open can perform * any transactions. This method allows more than one process * to have the device open at any given time, which provides * finer granularity for device utilization by multiple @@ -647,12 +647,12 @@ static int sep_mmap(struct file *filp, struct vm_area_struct *vma) sep->pid_doing_transaction = current->pid; mutex_unlock(&sep->sep_mutex); - /* zero the pools and the number of data pool alocation pointers */ + /* Zero the pools and the number of data pool alocation pointers */ sep->data_pool_bytes_allocated = 0; sep->num_of_data_allocations = 0; /* - * check that the size of the mapped range is as the size of the message + * Check that the size of the mapped range is as the size of the message * shared area */ if ((vma->vm_end - vma->vm_start) > SEP_DRIVER_MMMAP_AREA_SIZE) { @@ -662,7 +662,7 @@ static int sep_mmap(struct file *filp, struct vm_area_struct *vma) dev_dbg(&sep->pdev->dev, "shared_addr is %p\n", sep->shared_addr); - /* get bus address */ + /* Get bus address */ bus_addr = sep->shared_bus; dev_dbg(&sep->pdev->dev, @@ -678,13 +678,13 @@ static int sep_mmap(struct file *filp, struct vm_area_struct *vma) goto end_function; end_function_with_error: - /* clear the bit */ + /* Clear the bit */ clear_bit(SEP_MMAP_LOCK_BIT, &sep->in_use_flags); mutex_lock(&sep->sep_mutex); sep->pid_doing_transaction = 0; mutex_unlock(&sep->sep_mutex); - /* raise event for stuck contextes */ + /* Raise event for stuck contextes */ dev_warn(&sep->pdev->dev, "mmap error - waking up event\n"); wake_up(&sep->event); @@ -722,14 +722,14 @@ static unsigned int sep_poll(struct file *filp, poll_table *wait) } mutex_unlock(&sep->sep_mutex); - /* check if send command or send_reply were activated previously */ + /* Check if send command or send_reply were activated previously */ if (!test_bit(SEP_SEND_MSG_LOCK_BIT, &sep->in_use_flags)) { dev_warn(&sep->pdev->dev, "poll; lock bit set\n"); mask = POLLERR; goto end_function; } - /* add the event to the polling wait table */ + /* Add the event to the polling wait table */ dev_dbg(&sep->pdev->dev, "poll: calling wait sep_event\n"); poll_wait(filp, &sep->event, wait); @@ -737,7 +737,7 @@ static unsigned int sep_poll(struct file *filp, poll_table *wait) dev_dbg(&sep->pdev->dev, "poll: send_ct is %lx reply ct is %lx\n", sep->send_ct, sep->reply_ct); - /* check if error occured during poll */ + /* Check if error occured during poll */ retval2 = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR3_REG_ADDR); if (retval2 != 0x0) { dev_warn(&sep->pdev->dev, "poll; poll error %x\n", retval2); @@ -753,25 +753,24 @@ static unsigned int sep_poll(struct file *filp, poll_table *wait) dev_dbg(&sep->pdev->dev, "poll: data ready check (GPR2) %x\n", retval); - /* check if printf request */ + /* Check if printf request */ if ((retval >> 30) & 0x1) { - dev_dbg(&sep->pdev->dev, "poll: sep printf request\n"); + dev_dbg(&sep->pdev->dev, "poll: SEP printf request\n"); wake_up(&sep->event_request_daemon); goto end_function; } - /* check if the this is sep reply or request */ + /* Check if the this is SEP reply or request */ if (retval >> 31) { - dev_dbg(&sep->pdev->dev, "poll: sep request\n"); + dev_dbg(&sep->pdev->dev, "poll: SEP request\n"); wake_up(&sep->event_request_daemon); } else { dev_dbg(&sep->pdev->dev, "poll: normal return\n"); - /* in case it is again by send_reply_comand */ + /* In case it is again by send_reply_comand */ clear_bit(SEP_SEND_MSG_LOCK_BIT, &sep->in_use_flags); sep_dump_message(sep); dev_dbg(&sep->pdev->dev, - "poll; sep reply POLLIN | POLLRDNORM\n"); - + "poll; SEP reply POLLIN | POLLRDNORM\n"); mask |= POLLIN | POLLRDNORM; } } else { @@ -803,19 +802,19 @@ static u32 *sep_time_address(struct sep_device *sep) * @sep: the SEP we are setting the time for * * Calculates time and sets it at the predefined address. - * Called with the sep mutex held. + * Called with the SEP mutex held. */ static unsigned long sep_set_time(struct sep_device *sep) { struct timeval time; - u32 *time_addr; /* address of time as seen by the kernel */ + u32 *time_addr; /* Address of time as seen by the kernel */ - dev_dbg(&sep->pdev->dev, "sep:sep_set_time start\n"); + dev_dbg(&sep->pdev->dev, "sep_set_time start\n"); do_gettimeofday(&time); - /* set value in the SYSTEM MEMORY offset */ + /* Set value in the SYSTEM MEMORY offset */ time_addr = sep_time_address(sep); time_addr[0] = SEP_TIME_VAL_TOKEN; @@ -830,7 +829,7 @@ static unsigned long sep_set_time(struct sep_device *sep) /** * sep_set_caller_id_handler - insert caller id entry - * @sep: sep device + * @sep: SEP device * @arg: pointer to struct caller_id_struct * * Inserts the data into the caller id table. Note that this function @@ -858,7 +857,7 @@ static int sep_set_caller_id_handler(struct sep_device *sep, u32 arg) goto end_function; } - /* copy the data */ + /* Copy the data */ if (copy_from_user(&command_args, (void __user *)arg, sizeof(command_args))) { error = -EFAULT; @@ -894,9 +893,9 @@ end_function: /** * sep_set_current_caller_id - set the caller id - * @sep: pointer to struct_sep + * @sep: pointer to struct_sep_device * - * Set the caller ID (if it exists) to the sep. Note that this + * Set the caller ID (if it exists) to the SEP. Note that this * function falls under the ioctl lock */ static int sep_set_current_caller_id(struct sep_device *sep) @@ -906,7 +905,7 @@ static int sep_set_current_caller_id(struct sep_device *sep) dev_dbg(&sep->pdev->dev, "sep_set_current_caller_id start\n"); dev_dbg(&sep->pdev->dev, "current process is %d\n", current->pid); - /* zero the previous value */ + /* Zero the previous value */ memset(sep->shared_addr + SEP_CALLER_ID_OFFSET_BYTES, 0, SEP_CALLER_ID_HASH_SIZE_IN_BYTES); @@ -926,7 +925,7 @@ static int sep_set_current_caller_id(struct sep_device *sep) /** * sep_send_command_handler - kick off a command - * @sep: sep being signalled + * @sep: SEP being signalled * * This function raises interrupt to SEP that signals that is has a new * command from the host @@ -946,13 +945,13 @@ static int sep_send_command_handler(struct sep_device *sep) } sep_set_time(sep); - /* only Medfield has caller id */ + /* Only Medfield has caller id */ if (sep->mrst == 0) sep_set_current_caller_id(sep); sep_dump_message(sep); - /* update counter */ + /* Update counter */ spin_lock_irqsave(&sep->snd_rply_lck, lck_flags); sep->send_ct++; spin_unlock_irqrestore(&sep->snd_rply_lck, lck_flags); @@ -961,7 +960,7 @@ static int sep_send_command_handler(struct sep_device *sep) "sep_send_command_handler send_ct %lx reply_ct %lx\n", sep->send_ct, sep->reply_ct); - /* send interrupt to SEP */ + /* Send interrupt to SEP */ sep_write_reg(sep, HW_HOST_HOST_SEP_GPR0_REG_ADDR, 0x2); end_function: @@ -971,7 +970,7 @@ end_function: /** * sep_allocate_data_pool_memory_handler -allocate pool memory - * @sep: pointer to struct_sep + * @sep: pointer to struct sep_device * @arg: pointer to struct alloc_struct * * This function handles the allocate data pool memory request @@ -1016,7 +1015,7 @@ static int sep_allocate_data_pool_memory_handler(struct sep_device *sep, dev_dbg(&sep->pdev->dev, "command_args.offset: %x\n", command_args.offset); - /* Place in the shared area that is known by the sep */ + /* Place in the shared area that is known by the SEP */ token_addr = (u32 *)(sep->shared_addr + SEP_DRIVER_DATA_POOL_ALLOCATION_OFFSET_IN_BYTES + (sep->num_of_data_allocations)*2*sizeof(u32)); @@ -1043,7 +1042,7 @@ static int sep_allocate_data_pool_memory_handler(struct sep_device *sep, goto end_function; } - /* update the allocation */ + /* Update the allocation */ sep->data_pool_bytes_allocated += command_args.num_bytes; sep->num_of_data_allocations += 1; @@ -1079,9 +1078,9 @@ static int sep_lock_kernel_pages(struct sep_device *sep, { int error = 0; - /* array of lli */ + /* Array of lli */ struct sep_lli_entry *lli_array; - /* map array */ + /* Map array */ struct sep_dma_map *map_array; dev_dbg(&sep->pdev->dev, @@ -1110,7 +1109,7 @@ static int sep_lock_kernel_pages(struct sep_device *sep, /* - * set the start address of the first page - app data may start not at + * Set the start address of the first page - app data may start not at * the beginning of the page */ lli_array[0].bus_address = (u32)map_array[0].dma_addr; @@ -1121,7 +1120,7 @@ static int sep_lock_kernel_pages(struct sep_device *sep, (unsigned long)lli_array[0].bus_address, lli_array[0].block_size); - /* set the output parameters */ + /* Set the output parameters */ if (in_out_flag == SEP_DRIVER_IN_FLAG) { *lli_array_ptr = lli_array; sep->dma_res_arr[sep->nr_dcb_creat].in_num_pages = 1; @@ -1168,25 +1167,25 @@ static int sep_lock_user_pages(struct sep_device *sep, int error = 0; u32 count; int result; - /* the the page of the end address of the user space buffer */ + /* The the page of the end address of the user space buffer */ u32 end_page; - /* the page of the start address of the user space buffer */ + /* The page of the start address of the user space buffer */ u32 start_page; - /* the range in pages */ + /* The range in pages */ u32 num_pages; - /* array of pointers to page */ + /* Array of pointers to page */ struct page **page_array; - /* array of lli */ + /* Array of lli */ struct sep_lli_entry *lli_array; - /* map array */ + /* Map array */ struct sep_dma_map *map_array; - /* direction of the DMA mapping for locked pages */ + /* Direction of the DMA mapping for locked pages */ enum dma_data_direction dir; dev_dbg(&sep->pdev->dev, "sep_lock_user_pages start\n"); - /* set start and end pages and num pages */ + /* Set start and end pages and num pages */ end_page = (app_virt_addr + data_size - 1) >> PAGE_SHIFT; start_page = app_virt_addr >> PAGE_SHIFT; num_pages = end_page - start_page + 1; @@ -1199,7 +1198,7 @@ static int sep_lock_user_pages(struct sep_device *sep, dev_dbg(&sep->pdev->dev, "starting page_array malloc\n"); - /* allocate array of pages structure pointers */ + /* Allocate array of pages structure pointers */ page_array = kmalloc(sizeof(struct page *) * num_pages, GFP_ATOMIC); if (!page_array) { error = -ENOMEM; @@ -1223,7 +1222,7 @@ static int sep_lock_user_pages(struct sep_device *sep, dev_dbg(&sep->pdev->dev, "starting get_user_pages\n"); - /* convert the application virtual address into a set of physical */ + /* Convert the application virtual address into a set of physical */ down_read(¤t->mm->mmap_sem); result = get_user_pages(current, current->mm, app_virt_addr, num_pages, @@ -1232,7 +1231,7 @@ static int sep_lock_user_pages(struct sep_device *sep, up_read(¤t->mm->mmap_sem); - /* check the number of pages locked - if not all then exit with error */ + /* Check the number of pages locked - if not all then exit with error */ if (result != num_pages) { dev_warn(&sep->pdev->dev, "not all pages locked by get_user_pages\n"); @@ -1242,26 +1241,25 @@ static int sep_lock_user_pages(struct sep_device *sep, dev_dbg(&sep->pdev->dev, "get_user_pages succeeded\n"); - /* set direction */ + /* Set direction */ if (in_out_flag == SEP_DRIVER_IN_FLAG) dir = DMA_TO_DEVICE; else dir = DMA_FROM_DEVICE; /* - * fill the array using page array data and - * map the pages - this action - * will also flush the cache as needed + * Fill the array using page array data and + * map the pages - this action will also flush the cache as needed */ for (count = 0; count < num_pages; count++) { - /* fill the map array */ + /* Fill the map array */ map_array[count].dma_addr = dma_map_page(&sep->pdev->dev, page_array[count], 0, PAGE_SIZE, /*dir*/DMA_BIDIRECTIONAL); map_array[count].size = PAGE_SIZE; - /* fill the lli array entry */ + /* Fill the lli array entry */ lli_array[count].bus_address = (u32)map_array[count].dma_addr; lli_array[count].block_size = PAGE_SIZE; @@ -1270,11 +1268,11 @@ static int sep_lock_user_pages(struct sep_device *sep, count, lli_array[count].block_size); } - /* check the offset for the first page */ + /* Check the offset for the first page */ lli_array[0].bus_address = lli_array[0].bus_address + (app_virt_addr & (~PAGE_MASK)); - /* check that not all the data is in the first page only */ + /* Check that not all the data is in the first page only */ if ((PAGE_SIZE - (app_virt_addr & (~PAGE_MASK))) >= data_size) lli_array[0].block_size = data_size; else @@ -1286,7 +1284,7 @@ static int sep_lock_user_pages(struct sep_device *sep, (unsigned long)lli_array[count].bus_address, lli_array[count].block_size); - /* check the size of the last page */ + /* Check the size of the last page */ if (num_pages > 1) { lli_array[num_pages - 1].block_size = (app_virt_addr + data_size) & (~PAGE_MASK); @@ -1299,7 +1297,7 @@ static int sep_lock_user_pages(struct sep_device *sep, lli_array[count].block_size); } - /* set output params acording to the in_out flag */ + /* Set output params acording to the in_out flag */ if (in_out_flag == SEP_DRIVER_IN_FLAG) { *lli_array_ptr = lli_array; sep->dma_res_arr[sep->nr_dcb_creat].in_num_pages = num_pages; @@ -1319,14 +1317,14 @@ static int sep_lock_user_pages(struct sep_device *sep, goto end_function; end_function_with_error3: - /* free lli array */ + /* Free lli array */ kfree(lli_array); end_function_with_error2: kfree(map_array); end_function_with_error1: - /* free page array */ + /* Free page array */ kfree(page_array); end_function: @@ -1352,15 +1350,15 @@ static u32 sep_calculate_lli_table_max_size(struct sep_device *sep, u32 *last_table_flag) { u32 counter; - /* table data size */ + /* Table data size */ u32 table_data_size = 0; - /* data size for the next table */ + /* Data size for the next table */ u32 next_table_data_size; *last_table_flag = 0; /* - * calculate the data in the out lli table till we fill the whole + * Calculate the data in the out lli table till we fill the whole * table or till the data has ended */ for (counter = 0; @@ -1369,20 +1367,19 @@ static u32 sep_calculate_lli_table_max_size(struct sep_device *sep, table_data_size += lli_in_array_ptr[counter].block_size; /* - * check if we reached the last entry, + * Check if we reached the last entry, * meaning this ia the last table to build, * and no need to check the block alignment */ if (counter == num_array_entries) { - /* set the last table flag */ + /* Set the last table flag */ *last_table_flag = 1; goto end_function; } /* - * calculate the data size of the next table. - * Stop if no entries left or - * if data size is more the DMA restriction + * Calculate the data size of the next table. + * Stop if no entries left or if data size is more the DMA restriction */ next_table_data_size = 0; for (; counter < num_array_entries; counter++) { @@ -1392,7 +1389,7 @@ static u32 sep_calculate_lli_table_max_size(struct sep_device *sep, } /* - * check if the next table data size is less then DMA rstriction. + * Check if the next table data size is less then DMA rstriction. * if it is - recalculate the current table size, so that the next * table data size will be adaquete for DMA */ @@ -1427,23 +1424,23 @@ static void sep_build_lli_table(struct sep_device *sep, u32 *num_table_entries_ptr, u32 table_data_size) { - /* current table data size */ + /* Current table data size */ u32 curr_table_data_size; - /* counter of lli array entry */ + /* Counter of lli array entry */ u32 array_counter; dev_dbg(&sep->pdev->dev, "sep_build_lli_table start\n"); - /* init currrent table data size and lli array entry counter */ + /* Init currrent table data size and lli array entry counter */ curr_table_data_size = 0; array_counter = 0; *num_table_entries_ptr = 1; dev_dbg(&sep->pdev->dev, "table_data_size is %x\n", table_data_size); - /* fill the table till table size reaches the needed amount */ + /* Fill the table till table size reaches the needed amount */ while (curr_table_data_size < table_data_size) { - /* update the number of entries in table */ + /* Update the number of entries in table */ (*num_table_entries_ptr)++; lli_table_ptr->bus_address = @@ -1461,24 +1458,24 @@ static void sep_build_lli_table(struct sep_device *sep, dev_dbg(&sep->pdev->dev, "lli_table_ptr->block_size is %x\n", lli_table_ptr->block_size); - /* check for overflow of the table data */ + /* Check for overflow of the table data */ if (curr_table_data_size > table_data_size) { dev_dbg(&sep->pdev->dev, "curr_table_data_size too large\n"); - /* update the size of block in the table */ + /* Update the size of block in the table */ lli_table_ptr->block_size -= cpu_to_le32((curr_table_data_size - table_data_size)); - /* update the physical address in the lli array */ + /* Update the physical address in the lli array */ lli_array_ptr[array_counter].bus_address += cpu_to_le32(lli_table_ptr->block_size); - /* update the block size left in the lli array */ + /* Update the block size left in the lli array */ lli_array_ptr[array_counter].block_size = (curr_table_data_size - table_data_size); } else - /* advance to the next entry in the lli_array */ + /* Advance to the next entry in the lli_array */ array_counter++; dev_dbg(&sep->pdev->dev, @@ -1488,11 +1485,11 @@ static void sep_build_lli_table(struct sep_device *sep, "lli_table_ptr->block_size is %x\n", lli_table_ptr->block_size); - /* move to the next entry in table */ + /* Move to the next entry in table */ lli_table_ptr++; } - /* set the info entry to default */ + /* Set the info entry to default */ lli_table_ptr->bus_address = 0xffffffff; lli_table_ptr->block_size = 0; @@ -1502,7 +1499,7 @@ static void sep_build_lli_table(struct sep_device *sep, dev_dbg(&sep->pdev->dev, "lli_table_ptr->block_size is %x\n", lli_table_ptr->block_size); - /* set the output parameter */ + /* Set the output parameter */ *num_processed_entries_ptr += array_counter; dev_dbg(&sep->pdev->dev, "num_processed_entries_ptr is %x\n", @@ -1578,7 +1575,7 @@ static void sep_debug_print_lli_tables(struct sep_device *sep, dev_dbg(&sep->pdev->dev, "num_table_entries is %lu\n", num_table_entries); - /* print entries of the table (without info entry) */ + /* Print entries of the table (without info entry) */ for (entries_count = 0; entries_count < num_table_entries; entries_count++, lli_table_ptr++) { @@ -1591,7 +1588,7 @@ static void sep_debug_print_lli_tables(struct sep_device *sep, (unsigned long)lli_table_ptr->bus_address, lli_table_ptr->block_size); } - /* point to the info entry */ + /* Point to the info entry */ lli_table_ptr--; dev_dbg(&sep->pdev->dev, @@ -1642,7 +1639,7 @@ static void sep_prepare_empty_lli_table(struct sep_device *sep, dev_dbg(&sep->pdev->dev, "sep_prepare_empty_lli_table start\n"); - /* find the area for new table */ + /* Find the area for new table */ lli_table_ptr = (struct sep_lli_entry *)(sep->shared_addr + SYNCHRONIC_DMA_TABLES_AREA_OFFSET_BYTES + @@ -1656,18 +1653,18 @@ static void sep_prepare_empty_lli_table(struct sep_device *sep, lli_table_ptr->bus_address = 0xFFFFFFFF; lli_table_ptr->block_size = 0; - /* set the output parameter value */ + /* Set the output parameter value */ *lli_table_addr_ptr = sep->shared_bus + SYNCHRONIC_DMA_TABLES_AREA_OFFSET_BYTES + sep->num_lli_tables_created * sizeof(struct sep_lli_entry) * SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP; - /* set the num of entries and table data size for empty table */ + /* Set the num of entries and table data size for empty table */ *num_entries_ptr = 2; *table_data_size_ptr = 0; - /* update the number of created tables */ + /* Update the number of created tables */ sep->num_lli_tables_created++; dev_dbg(&sep->pdev->dev, "sep_prepare_empty_lli_table start\n"); @@ -1686,7 +1683,7 @@ static void sep_prepare_empty_lli_table(struct sep_device *sep, * * This function prepares only input DMA table for synhronic symmetric * operations (HASH) - * Note that all bus addresses that are passed to the sep + * Note that all bus addresses that are passed to the SEP * are in 32 bit format; the SEP is a 32 bit device */ static int sep_prepare_input_dma_table(struct sep_device *sep, @@ -1699,54 +1696,54 @@ static int sep_prepare_input_dma_table(struct sep_device *sep, bool is_kva) { int error = 0; - /* pointer to the info entry of the table - the last entry */ + /* Pointer to the info entry of the table - the last entry */ struct sep_lli_entry *info_entry_ptr; - /* array of pointers to page */ + /* Array of pointers to page */ struct sep_lli_entry *lli_array_ptr; - /* points to the first entry to be processed in the lli_in_array */ + /* Points to the first entry to be processed in the lli_in_array */ u32 current_entry = 0; - /* num entries in the virtual buffer */ + /* Num entries in the virtual buffer */ u32 sep_lli_entries = 0; - /* lli table pointer */ + /* Lli table pointer */ struct sep_lli_entry *in_lli_table_ptr; - /* the total data in one table */ + /* The total data in one table */ u32 table_data_size = 0; - /* flag for last table */ + /* Flag for last table */ u32 last_table_flag = 0; - /* number of entries in lli table */ + /* Number of entries in lli table */ u32 num_entries_in_table = 0; - /* next table address */ + /* Next table address */ u32 lli_table_alloc_addr = 0; dev_dbg(&sep->pdev->dev, "sep_prepare_input_dma_table start\n"); dev_dbg(&sep->pdev->dev, "data_size is %x\n", data_size); dev_dbg(&sep->pdev->dev, "block_size is %x\n", block_size); - /* initialize the pages pointers */ + /* Initialize the pages pointers */ sep->dma_res_arr[sep->nr_dcb_creat].in_page_array = 0; sep->dma_res_arr[sep->nr_dcb_creat].in_num_pages = 0; - /* set the kernel address for first table to be allocated */ + /* Set the kernel address for first table to be allocated */ lli_table_alloc_addr = (u32)(sep->shared_addr + SYNCHRONIC_DMA_TABLES_AREA_OFFSET_BYTES + sep->num_lli_tables_created * sizeof(struct sep_lli_entry) * SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP); if (data_size == 0) { - /* special case - create meptu table - 2 entries, zero data */ + /* Special case - create meptu table - 2 entries, zero data */ sep_prepare_empty_lli_table(sep, lli_table_ptr, num_entries_ptr, table_data_size_ptr); goto update_dcb_counter; } - /* check if the pages are in Kernel Virtual Address layout */ + /* Check if the pages are in Kernel Virtual Address layout */ if (is_kva == true) - /* lock the pages in the kernel */ + /* Lock the pages in the kernel */ error = sep_lock_kernel_pages(sep, app_virt_addr, data_size, &lli_array_ptr, SEP_DRIVER_IN_FLAG); else /* - * lock the pages of the user buffer + * Lock the pages of the user buffer * and translate them to pages */ error = sep_lock_user_pages(sep, app_virt_addr, @@ -1763,10 +1760,10 @@ static int sep_prepare_input_dma_table(struct sep_device *sep, sep_lli_entries = sep->dma_res_arr[sep->nr_dcb_creat].in_num_pages; - /* loop till all the entries in in array are not processed */ + /* Loop till all the entries in in array are not processed */ while (current_entry < sep_lli_entries) { - /* set the new input and output tables */ + /* Set the new input and output tables */ in_lli_table_ptr = (struct sep_lli_entry *)lli_table_alloc_addr; @@ -1783,17 +1780,17 @@ static int sep_prepare_input_dma_table(struct sep_device *sep, } - /* update the number of created tables */ + /* Update the number of created tables */ sep->num_lli_tables_created++; - /* calculate the maximum size of data for input table */ + /* Calculate the maximum size of data for input table */ table_data_size = sep_calculate_lli_table_max_size(sep, &lli_array_ptr[current_entry], (sep_lli_entries - current_entry), &last_table_flag); /* - * if this is not the last table - + * If this is not the last table - * then allign it to the block size */ if (!last_table_flag) @@ -1803,14 +1800,14 @@ static int sep_prepare_input_dma_table(struct sep_device *sep, dev_dbg(&sep->pdev->dev, "output table_data_size is %x\n", table_data_size); - /* construct input lli table */ + /* Construct input lli table */ sep_build_lli_table(sep, &lli_array_ptr[current_entry], in_lli_table_ptr, ¤t_entry, &num_entries_in_table, table_data_size); if (info_entry_ptr == 0) { - /* set the output parameters to physical addresses */ + /* Set the output parameters to physical addresses */ *lli_table_ptr = sep_shared_area_virt_to_bus(sep, in_lli_table_ptr); *num_entries_ptr = num_entries_in_table; @@ -1821,7 +1818,7 @@ static int sep_prepare_input_dma_table(struct sep_device *sep, (unsigned long)*lli_table_ptr); } else { - /* update the info entry of the previous in table */ + /* Update the info entry of the previous in table */ info_entry_ptr->bus_address = sep_shared_area_virt_to_bus(sep, in_lli_table_ptr); @@ -1829,23 +1826,23 @@ static int sep_prepare_input_dma_table(struct sep_device *sep, ((num_entries_in_table) << 24) | (table_data_size); } - /* save the pointer to the info entry of the current tables */ + /* Save the pointer to the info entry of the current tables */ info_entry_ptr = in_lli_table_ptr + num_entries_in_table - 1; } - /* print input tables */ + /* Print input tables */ sep_debug_print_lli_tables(sep, (struct sep_lli_entry *) sep_shared_area_bus_to_virt(sep, *lli_table_ptr), *num_entries_ptr, *table_data_size_ptr); - /* the array of the pages */ + /* The array of the pages */ kfree(lli_array_ptr); update_dcb_counter: - /* update dcb counter */ + /* Update DCB counter */ sep->nr_dcb_creat++; goto end_function; end_function_error: - /* free all the allocated resources */ + /* Free all the allocated resources */ kfree(sep->dma_res_arr[sep->nr_dcb_creat].in_map_array); kfree(lli_array_ptr); kfree(sep->dma_res_arr[sep->nr_dcb_creat].in_page_array); @@ -1857,7 +1854,7 @@ end_function: } /** * sep_construct_dma_tables_from_lli - prepare AES/DES mappings - * @sep: pointer to struct_sep + * @sep: pointer to struct sep_device * @lli_in_array: * @sep_in_lli_entries: * @lli_out_array: @@ -1869,10 +1866,10 @@ end_function: * @out_num_entries_ptr * @table_data_size_ptr * - * This function creates the input and output dma tables for + * This function creates the input and output DMA tables for * symmetric operations (AES/DES) according to the block * size from LLI arays - * Note that all bus addresses that are passed to the sep + * Note that all bus addresses that are passed to the SEP * are in 32 bit format; the SEP is a 32 bit device */ static int sep_construct_dma_tables_from_lli( @@ -1888,56 +1885,56 @@ static int sep_construct_dma_tables_from_lli( u32 *out_num_entries_ptr, u32 *table_data_size_ptr) { - /* points to the area where next lli table can be allocated */ + /* Points to the area where next lli table can be allocated */ u32 lli_table_alloc_addr = 0; - /* input lli table */ + /* Input lli table */ struct sep_lli_entry *in_lli_table_ptr = 0; - /* output lli table */ + /* Output lli table */ struct sep_lli_entry *out_lli_table_ptr = 0; - /* pointer to the info entry of the table - the last entry */ + /* Pointer to the info entry of the table - the last entry */ struct sep_lli_entry *info_in_entry_ptr = 0; - /* pointer to the info entry of the table - the last entry */ + /* Pointer to the info entry of the table - the last entry */ struct sep_lli_entry *info_out_entry_ptr = 0; - /* points to the first entry to be processed in the lli_in_array */ + /* Points to the first entry to be processed in the lli_in_array */ u32 current_in_entry = 0; - /* points to the first entry to be processed in the lli_out_array */ + /* Points to the first entry to be processed in the lli_out_array */ u32 current_out_entry = 0; - /* max size of the input table */ + /* Max size of the input table */ u32 in_table_data_size = 0; - /* max size of the output table */ + /* Max size of the output table */ u32 out_table_data_size = 0; - /* flag te signifies if this is the last tables build */ + /* Flag te signifies if this is the last tables build */ u32 last_table_flag = 0; - /* the data size that should be in table */ + /* The data size that should be in table */ u32 table_data_size = 0; - /* number of etnries in the input table */ + /* Number of etnries in the input table */ u32 num_entries_in_table = 0; - /* number of etnries in the output table */ + /* Number of etnries in the output table */ u32 num_entries_out_table = 0; dev_dbg(&sep->pdev->dev, "sep_construct_dma_tables_from_lli start\n"); - /* initiate to point after the message area */ + /* Initiate to point after the message area */ lli_table_alloc_addr = (u32)(sep->shared_addr + SYNCHRONIC_DMA_TABLES_AREA_OFFSET_BYTES + (sep->num_lli_tables_created * (sizeof(struct sep_lli_entry) * SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP))); - /* loop till all the entries in in array are not processed */ + /* Loop till all the entries in in array are not processed */ while (current_in_entry < sep_in_lli_entries) { - /* set the new input and output tables */ + /* Set the new input and output tables */ in_lli_table_ptr = (struct sep_lli_entry *)lli_table_alloc_addr; lli_table_alloc_addr += sizeof(struct sep_lli_entry) * SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP; - /* set the first output tables */ + /* Set the first output tables */ out_lli_table_ptr = (struct sep_lli_entry *)lli_table_alloc_addr; - /* check if the DMA table area limit was overrun */ + /* Check if the DMA table area limit was overrun */ if ((lli_table_alloc_addr + sizeof(struct sep_lli_entry) * SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP) > ((u32)sep->shared_addr + @@ -1948,20 +1945,20 @@ static int sep_construct_dma_tables_from_lli( return -ENOMEM; } - /* update the number of the lli tables created */ + /* Update the number of the lli tables created */ sep->num_lli_tables_created += 2; lli_table_alloc_addr += sizeof(struct sep_lli_entry) * SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP; - /* calculate the maximum size of data for input table */ + /* Calculate the maximum size of data for input table */ in_table_data_size = sep_calculate_lli_table_max_size(sep, &lli_in_array[current_in_entry], (sep_in_lli_entries - current_in_entry), &last_table_flag); - /* calculate the maximum size of data for output table */ + /* Calculate the maximum size of data for output table */ out_table_data_size = sep_calculate_lli_table_max_size(sep, &lli_out_array[current_out_entry], @@ -1980,7 +1977,7 @@ static int sep_construct_dma_tables_from_lli( if (!last_table_flag) { /* - * if this is not the last table, + * If this is not the last table, * then must check where the data is smallest * and then align it to the block size */ @@ -1988,7 +1985,7 @@ static int sep_construct_dma_tables_from_lli( table_data_size = out_table_data_size; /* - * now calculate the table size so that + * Now calculate the table size so that * it will be module block size */ table_data_size = (table_data_size / block_size) * @@ -1998,23 +1995,23 @@ static int sep_construct_dma_tables_from_lli( dev_dbg(&sep->pdev->dev, "table_data_size is %x\n", table_data_size); - /* construct input lli table */ + /* Construct input lli table */ sep_build_lli_table(sep, &lli_in_array[current_in_entry], in_lli_table_ptr, ¤t_in_entry, &num_entries_in_table, table_data_size); - /* construct output lli table */ + /* Construct output lli table */ sep_build_lli_table(sep, &lli_out_array[current_out_entry], out_lli_table_ptr, ¤t_out_entry, &num_entries_out_table, table_data_size); - /* if info entry is null - this is the first table built */ + /* If info entry is null - this is the first table built */ if (info_in_entry_ptr == 0) { - /* set the output parameters to physical addresses */ + /* Set the output parameters to physical addresses */ *lli_table_in_ptr = sep_shared_area_virt_to_bus(sep, in_lli_table_ptr); @@ -2034,7 +2031,7 @@ static int sep_construct_dma_tables_from_lli( "output lli_table_out_ptr is %08lx\n", (unsigned long)*lli_table_out_ptr); } else { - /* update the info entry of the previous in table */ + /* Update the info entry of the previous in table */ info_in_entry_ptr->bus_address = sep_shared_area_virt_to_bus(sep, in_lli_table_ptr); @@ -2043,7 +2040,7 @@ static int sep_construct_dma_tables_from_lli( ((num_entries_in_table) << 24) | (table_data_size); - /* update the info entry of the previous in table */ + /* Update the info entry of the previous in table */ info_out_entry_ptr->bus_address = sep_shared_area_virt_to_bus(sep, out_lli_table_ptr); @@ -2063,7 +2060,7 @@ static int sep_construct_dma_tables_from_lli( info_out_entry_ptr->block_size); } - /* save the pointer to the info entry of the current tables */ + /* Save the pointer to the info entry of the current tables */ info_in_entry_ptr = in_lli_table_ptr + num_entries_in_table - 1; info_out_entry_ptr = out_lli_table_ptr + @@ -2080,14 +2077,14 @@ static int sep_construct_dma_tables_from_lli( (unsigned long)info_out_entry_ptr); } - /* print input tables */ + /* Print input tables */ sep_debug_print_lli_tables(sep, (struct sep_lli_entry *) sep_shared_area_bus_to_virt(sep, *lli_table_in_ptr), *in_num_entries_ptr, *table_data_size_ptr); - /* print output tables */ + /* Print output tables */ sep_debug_print_lli_tables(sep, (struct sep_lli_entry *) sep_shared_area_bus_to_virt(sep, *lli_table_out_ptr), @@ -2114,7 +2111,7 @@ static int sep_construct_dma_tables_from_lli( * This function builds input and output DMA tables for synhronic * symmetric operations (AES, DES, HASH). It also checks that each table * is of the modular block size - * Note that all bus addresses that are passed to the sep + * Note that all bus addresses that are passed to the SEP * are in 32 bit format; the SEP is a 32 bit device */ static int sep_prepare_input_output_dma_table(struct sep_device *sep, @@ -2131,15 +2128,15 @@ static int sep_prepare_input_output_dma_table(struct sep_device *sep, { int error = 0; - /* array of pointers of page */ + /* Array of pointers of page */ struct sep_lli_entry *lli_in_array; - /* array of pointers of page */ + /* Array of pointers of page */ struct sep_lli_entry *lli_out_array; dev_dbg(&sep->pdev->dev, "sep_prepare_input_output_dma_table start\n"); if (data_size == 0) { - /* prepare empty table for input and output */ + /* Prepare empty table for input and output */ sep_prepare_empty_lli_table(sep, lli_table_in_ptr, in_num_entries_ptr, table_data_size_ptr); @@ -2149,11 +2146,11 @@ static int sep_prepare_input_output_dma_table(struct sep_device *sep, goto update_dcb_counter; } - /* initialize the pages pointers */ + /* Initialize the pages pointers */ sep->dma_res_arr[sep->nr_dcb_creat].in_page_array = 0; sep->dma_res_arr[sep->nr_dcb_creat].out_page_array = 0; - /* lock the pages of the buffer and translate them to pages */ + /* Lock the pages of the buffer and translate them to pages */ if (is_kva == true) { error = sep_lock_kernel_pages(sep, app_virt_in_addr, data_size, &lli_in_array, SEP_DRIVER_IN_FLAG); @@ -2200,7 +2197,7 @@ static int sep_prepare_input_output_dma_table(struct sep_device *sep, dev_dbg(&sep->pdev->dev, "SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP is %x\n", SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP); - /* call the fucntion that creates table from the lli arrays */ + /* Call the fucntion that creates table from the lli arrays */ error = sep_construct_dma_tables_from_lli(sep, lli_in_array, sep->dma_res_arr[sep->nr_dcb_creat].in_num_pages, lli_out_array, @@ -2218,9 +2215,9 @@ static int sep_prepare_input_output_dma_table(struct sep_device *sep, kfree(lli_in_array); update_dcb_counter: - /* update dcb counter */ + /* Update DCB counter */ sep->nr_dcb_creat++; - /* fall through - free the lli entry arrays */ + /* Fall through - free the lli entry arrays */ dev_dbg(&sep->pdev->dev, "in_num_entries_ptr is %08x\n", *in_num_entries_ptr); dev_dbg(&sep->pdev->dev, "out_num_entries_ptr is %08x\n", @@ -2259,10 +2256,10 @@ end_function: * @isapplet: bool; to indicate external app * @is_kva: bool; kernel buffer; only used for kernel crypto module * - * This function prepares the linked dma tables and puts the - * address for the linked list of tables inta a dcb (data control - * block) the address of which is known by the sep hardware - * Note that all bus addresses that are passed to the sep + * This function prepares the linked DMA tables and puts the + * address for the linked list of tables inta a DCB (data control + * block) the address of which is known by the SEP hardware + * Note that all bus addresses that are passed to the SEP * are in 32 bit format; the SEP is a 32 bit device */ static int sep_prepare_input_output_dma_table_in_dcb(struct sep_device *sep, @@ -2275,36 +2272,36 @@ static int sep_prepare_input_output_dma_table_in_dcb(struct sep_device *sep, bool is_kva) { int error = 0; - /* size of tail */ + /* Size of tail */ u32 tail_size = 0; - /* address of the created dcb table */ + /* Address of the created DCB table */ struct sep_dcblock *dcb_table_ptr = 0; - /* the physical address of the first input DMA table */ + /* The physical address of the first input DMA table */ dma_addr_t in_first_mlli_address = 0; - /* number of entries in the first input DMA table */ + /* Number of entries in the first input DMA table */ u32 in_first_num_entries = 0; - /* the physical address of the first output DMA table */ + /* The physical address of the first output DMA table */ dma_addr_t out_first_mlli_address = 0; - /* number of entries in the first output DMA table */ + /* Number of entries in the first output DMA table */ u32 out_first_num_entries = 0; - /* data in the first input/output table */ + /* Data in the first input/output table */ u32 first_data_size = 0; dev_dbg(&sep->pdev->dev, "prepare_input_output_dma_table_in_dcb start\n"); if (sep->nr_dcb_creat == SEP_MAX_NUM_SYNC_DMA_OPS) { - /* No more DCBS to allocate */ - dev_warn(&sep->pdev->dev, "no more dcb's available\n"); + /* No more DCBs to allocate */ + dev_warn(&sep->pdev->dev, "no more DCBs available\n"); error = -ENOSPC; goto end_function; } - /* allocate new DCB */ + /* Allocate new DCB */ dcb_table_ptr = (struct sep_dcblock *)(sep->shared_addr + SEP_DRIVER_SYSTEM_DCB_MEMORY_OFFSET_IN_BYTES + (sep->nr_dcb_creat * sizeof(struct sep_dcblock))); - /* set the default values in the dcb */ + /* Set the default values in the DCB */ dcb_table_ptr->input_mlli_address = 0; dcb_table_ptr->input_mlli_num_entries = 0; dcb_table_ptr->input_mlli_data_size = 0; @@ -2324,7 +2321,7 @@ static int sep_prepare_input_output_dma_table_in_dcb(struct sep_device *sep, } if (tail_block_size) /* - * case the tail size should be + * Case the tail size should be * bigger than the real block size */ tail_size = tail_block_size + @@ -2332,7 +2329,7 @@ static int sep_prepare_input_output_dma_table_in_dcb(struct sep_device *sep, tail_block_size) % block_size); } - /* check if there is enough data for dma operation */ + /* Check if there is enough data for DMA operation */ if (data_in_size < SEP_DRIVER_MIN_DATA_SIZE_PER_TABLE) { if (is_kva == true) { memcpy(dcb_table_ptr->tail_data, @@ -2348,7 +2345,7 @@ static int sep_prepare_input_output_dma_table_in_dcb(struct sep_device *sep, dcb_table_ptr->tail_data_size = data_in_size; - /* set the output user-space address for mem2mem op */ + /* Set the output user-space address for mem2mem op */ if (app_out_address) dcb_table_ptr->out_vr_tail_pt = (u32)app_out_address; @@ -2367,7 +2364,7 @@ static int sep_prepare_input_output_dma_table_in_dcb(struct sep_device *sep, (void *)(app_in_address + data_in_size - tail_size), tail_size); } else { - /* we have tail data - copy it to dcb */ + /* We have tail data - copy it to DCB */ if (copy_from_user(dcb_table_ptr->tail_data, (void *)(app_in_address + data_in_size - tail_size), tail_size)) { @@ -2393,9 +2390,9 @@ static int sep_prepare_input_output_dma_table_in_dcb(struct sep_device *sep, data_in_size = (data_in_size - tail_size); } } - /* check if we need to build only input table or input/output */ + /* Check if we need to build only input table or input/output */ if (app_out_address) { - /* prepare input/output tables */ + /* Prepare input/output tables */ error = sep_prepare_input_output_dma_table(sep, app_in_address, app_out_address, @@ -2408,7 +2405,7 @@ static int sep_prepare_input_output_dma_table_in_dcb(struct sep_device *sep, &first_data_size, is_kva); } else { - /* prepare input tables */ + /* Prepare input tables */ error = sep_prepare_input_dma_table(sep, app_in_address, data_in_size, @@ -2420,11 +2417,11 @@ static int sep_prepare_input_output_dma_table_in_dcb(struct sep_device *sep, } if (error) { - dev_warn(&sep->pdev->dev, "prepare dma table call failed from prepare dcb call\n"); + dev_warn(&sep->pdev->dev, "prepare DMA table call failed from prepare DCB call\n"); goto end_function; } - /* set the dcb values */ + /* Set the DCB values */ dcb_table_ptr->input_mlli_address = in_first_mlli_address; dcb_table_ptr->input_mlli_num_entries = in_first_num_entries; dcb_table_ptr->input_mlli_data_size = first_data_size; @@ -2441,7 +2438,7 @@ end_function: /** - * sep_create_sync_dma_tables_handler - create sync dma tables + * sep_create_sync_dma_tables_handler - create sync DMA tables * @sep: pointer to struct sep_device * @arg: pointer to struct bld_syn_tab_struct * @@ -2454,7 +2451,7 @@ static int sep_create_sync_dma_tables_handler(struct sep_device *sep, { int error = 0; - /* command arguments */ + /* Command arguments */ struct bld_syn_tab_struct command_args; dev_dbg(&sep->pdev->dev, @@ -2475,7 +2472,7 @@ static int sep_create_sync_dma_tables_handler(struct sep_device *sep, dev_dbg(&sep->pdev->dev, "block_size is %u\n", command_args.block_size); - /* validate user parameters */ + /* Validate user parameters */ if (!command_args.app_in_address) { error = -EINVAL; goto end_function; @@ -2501,7 +2498,7 @@ end_function: * @isapplet: indicates external application (used for kernel access) * @is_kva: indicates kernel addresses (only used for kernel crypto) * - * This function frees the dma tables and dcb block + * This function frees the DMA tables and DCB */ static int sep_free_dma_tables_and_dcb(struct sep_device *sep, bool isapplet, bool is_kva) @@ -2514,12 +2511,12 @@ static int sep_free_dma_tables_and_dcb(struct sep_device *sep, bool isapplet, dev_dbg(&sep->pdev->dev, "sep_free_dma_tables_and_dcb start\n"); if (isapplet == true) { - /* set pointer to first dcb table */ + /* Set pointer to first DCB table */ dcb_table_ptr = (struct sep_dcblock *) (sep->shared_addr + SEP_DRIVER_SYSTEM_DCB_MEMORY_OFFSET_IN_BYTES); - /* go over each dcb and see if tail pointer must be updated */ + /* Go over each DCB and see if tail pointer must be updated */ for (i = 0; i < sep->nr_dcb_creat; i++, dcb_table_ptr++) { if (dcb_table_ptr->out_vr_tail_pt) { if (is_kva == true) { @@ -2533,14 +2530,14 @@ static int sep_free_dma_tables_and_dcb(struct sep_device *sep, bool isapplet, dcb_table_ptr->tail_data_size); } if (error_temp) { - /* release the dma resource */ + /* Release the DMA resource */ error = -EFAULT; break; } } } } - /* free the output pages, if any */ + /* Free the output pages, if any */ sep_free_dma_table_data_handler(sep); dev_dbg(&sep->pdev->dev, "sep_free_dma_tables_and_dcb end\n"); @@ -2579,7 +2576,7 @@ static int sep_get_static_pool_addr_handler(struct sep_device *sep, (u32)static_pool_addr[1], (u32)command_args.static_virt_address); - /* send the parameters to user application */ + /* Send the parameters to user application */ if (copy_to_user((void __user *) arg, &command_args, sizeof(struct stat_pool_addr_struct))) return -EFAULT; @@ -2600,14 +2597,14 @@ static int sep_start_handler(struct sep_device *sep) dev_dbg(&sep->pdev->dev, "sep_start_handler start\n"); - /* wait in polling for message from SEP */ + /* Wait in polling for message from SEP */ do reg_val = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR3_REG_ADDR); while (!reg_val); - /* check the value */ + /* Check the value */ if (reg_val == 0x1) - /* fatal error - read error status from GPRO */ + /* Fatal error - read error status from GPRO */ error = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR0_REG_ADDR); dev_dbg(&sep->pdev->dev, "sep_start_handler end\n"); return error; @@ -2619,7 +2616,7 @@ static int sep_start_handler(struct sep_device *sep) * @length: buffer size * * This function performs a checksum for messages that are sent - * to the sep + * to the SEP. */ static u32 sep_check_sum_calc(u8 *data, u32 length) { @@ -2651,7 +2648,7 @@ static u32 sep_check_sum_calc(u8 *data, u32 length) * Handles the request for SEP initialization * Note that this will go away for Medfield once the SCU * SEP initialization is complete - * Also note that the message to the sep has components + * Also note that the message to the SEP has components * from user space as well as components written by the driver * This is becuase the portions of the message that pertain to * physical addresses must be set by the driver after the message @@ -2670,7 +2667,7 @@ static int sep_init_handler(struct sep_device *sep, unsigned long arg) dev_dbg(&sep->pdev->dev, "sep_init_handler start\n"); - /* make sure that we have not initialized already */ + /* Make sure that we have not initialized already */ reg_val = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR3_REG_ADDR); if (reg_val != 0x2) { @@ -2679,13 +2676,13 @@ static int sep_init_handler(struct sep_device *sep, unsigned long arg) goto end_function; } - /* only root can initialize */ + /* Only root can initialize */ if (!capable(CAP_SYS_ADMIN)) { error = -EACCES; goto end_function; } - /* copy in the parameters */ + /* Copy in the parameters */ error = copy_from_user(&command_args, (void __user *)arg, sizeof(struct init_struct)); @@ -2694,14 +2691,14 @@ static int sep_init_handler(struct sep_device *sep, unsigned long arg) goto end_function; } - /* validate parameters */ + /* Validate parameters */ if (!command_args.message_addr || !command_args.sep_sram_addr || command_args.message_size_in_words > 14) { error = -EINVAL; goto end_function; } - /* copy in the sep init message */ + /* Copy in the SEP init message */ addr_hold = (unsigned long)command_args.message_addr; error = copy_from_user(message_buff, (void __user *)addr_hold, @@ -2712,16 +2709,16 @@ static int sep_init_handler(struct sep_device *sep, unsigned long arg) goto end_function; } - /* load resident, cache, and extapp firmware */ + /* Load resident, cache, and extapp firmware */ error = sep_load_firmware(sep); if (error) { dev_warn(&sep->pdev->dev, - "init; copy sep init message failed %x\n", error); + "init; copy SEP init message failed %x\n", error); goto end_function; } - /* compute the base address */ + /* Compute the base address */ new_base_addr = sep->shared_bus; if (sep->resident_bus < new_base_addr) @@ -2733,7 +2730,7 @@ static int sep_init_handler(struct sep_device *sep, unsigned long arg) if (sep->dcache_bus < new_base_addr) new_base_addr = sep->dcache_bus; - /* put physical addresses in sep message */ + /* Put physical addresses in SEP message */ message_buff[3] = (u32)new_base_addr; message_buff[4] = (u32)sep->shared_bus; message_buff[6] = (u32)sep->resident_bus; @@ -2745,16 +2742,16 @@ static int sep_init_handler(struct sep_device *sep, unsigned long arg) sep_check_sum_calc((u8 *)message_buff, command_args.message_size_in_words*sizeof(u32)); - /* debug print of message */ + /* Debug print of message */ for (counter = 0; counter < command_args.message_size_in_words; counter++) - dev_dbg(&sep->pdev->dev, "init; sep message word %d is %x\n", + dev_dbg(&sep->pdev->dev, "init; SEP message word %d is %x\n", counter, message_buff[counter]); - /* tell the sep the sram address */ + /* Tell the SEP the sram address */ sep_write_reg(sep, HW_SRAM_ADDR_REG_ADDR, command_args.sep_sram_addr); - /* push the message to the sep */ + /* Push the message to the SEP */ for (counter = 0; counter < command_args.message_size_in_words; counter++) { sep_write_reg(sep, HW_SRAM_DATA_REG_ADDR, @@ -2762,10 +2759,10 @@ static int sep_init_handler(struct sep_device *sep, unsigned long arg) sep_wait_sram_write(sep); } - /* signal sep that message is ready and to init */ + /* Signal SEP that message is ready and to init */ sep_write_reg(sep, HW_HOST_HOST_SEP_GPR0_REG_ADDR, 0x1); - /* wait for acknowledge */ + /* Wait for acknowledge */ dev_dbg(&sep->pdev->dev, "init; waiting for msg response\n"); do @@ -2782,10 +2779,10 @@ static int sep_init_handler(struct sep_device *sep, unsigned long arg) } dev_dbg(&sep->pdev->dev, "init; end CC INIT, reg_val is %x\n", reg_val); - /* signal sep to zero the GPR3 */ + /* Signal SEP to zero the GPR3 */ sep_write_reg(sep, HW_HOST_HOST_SEP_GPR0_REG_ADDR, 0x10); - /* wait for response */ + /* Wait for response */ dev_dbg(&sep->pdev->dev, "init; waiting for zero set response\n"); do @@ -2807,25 +2804,25 @@ static int sep_end_transaction_handler(struct sep_device *sep) { dev_dbg(&sep->pdev->dev, "sep_end_transaction_handler start\n"); - /* clear the data pool pointers Token */ + /* Clear the data pool pointers Token */ memset((void *)(sep->shared_addr + SEP_DRIVER_DATA_POOL_ALLOCATION_OFFSET_IN_BYTES), 0, sep->num_of_data_allocations*2*sizeof(u32)); - /* check that all the dma resources were freed */ + /* Check that all the DMA resources were freed */ sep_free_dma_table_data_handler(sep); clear_bit(SEP_MMAP_LOCK_BIT, &sep->in_use_flags); /* - * we are now through with the transaction. Let's + * We are now through with the transaction. Let's * allow other processes who have the device open * to perform transactions */ mutex_lock(&sep->sep_mutex); sep->pid_doing_transaction = 0; mutex_unlock(&sep->sep_mutex); - /* raise event for stuck contextes */ + /* Raise event for stuck contextes */ wake_up(&sep->event); dev_dbg(&sep->pdev->dev, "waking up event\n"); @@ -2844,9 +2841,8 @@ static int sep_end_transaction_handler(struct sep_device *sep) */ static int sep_prepare_dcb_handler(struct sep_device *sep, unsigned long arg) { - /* error */ int error; - /* command arguments */ + /* Command arguments */ struct build_dcb_struct command_args; dev_dbg(&sep->pdev->dev, "sep_prepare_dcb_handler start\n"); @@ -2912,24 +2908,24 @@ static int sep_rar_prepare_output_msg_handler(struct sep_device *sep, unsigned long arg) { int error = 0; - /* command args */ + /* Command args */ struct rar_hndl_to_bus_struct command_args; struct RAR_buffer rar_buf; - /* bus address */ + /* Bus address */ dma_addr_t rar_bus = 0; - /* holds the RAR address in the system memory offset */ + /* Holds the RAR address in the system memory offset */ u32 *rar_addr; dev_dbg(&sep->pdev->dev, "sep_rar_prepare_output_msg_handler start\n"); - /* copy the data */ + /* Copy the data */ if (copy_from_user(&command_args, (void __user *)arg, sizeof(command_args))) { error = -EFAULT; goto end_function; } - /* call to translation function only if user handle is not NULL */ + /* Call to translation function only if user handle is not NULL */ if (command_args.rar_handle) { memset(&rar_buf, 0, sizeof(rar_buf)); rar_buf.info.handle = (u32)command_args.rar_handle; @@ -2943,11 +2939,11 @@ static int sep_rar_prepare_output_msg_handler(struct sep_device *sep, } dev_dbg(&sep->pdev->dev, "rar msg; rar_addr_bus = %x\n", (u32)rar_bus); - /* set value in the SYSTEM MEMORY offset */ + /* Set value in the SYSTEM MEMORY offset */ rar_addr = (u32 *)(sep->shared_addr + SEP_DRIVER_SYSTEM_RAR_MEMORY_OFFSET_IN_BYTES); - /* copy the physical address to the System Area for the sep */ + /* Copy the physical address to the System Area for the SEP */ rar_addr[0] = SEP_RAR_VAL_TOKEN; rar_addr[1] = rar_bus; @@ -2961,19 +2957,19 @@ end_function: * @sep: pointer to struct sep_device * @arg: pointer to user parameters * - * This function tells the sep where the extapp is located + * This function tells the SEP where the extapp is located */ static int sep_realloc_ext_cache_handler(struct sep_device *sep, unsigned long arg) { - /* holds the new ext cache address in the system memory offset */ + /* Holds the new ext cache address in the system memory offset */ u32 *system_addr; - /* set value in the SYSTEM MEMORY offset */ + /* Set value in the SYSTEM MEMORY offset */ system_addr = (u32 *)(sep->shared_addr + SEP_DRIVER_SYSTEM_EXT_CACHE_ADDR_OFFSET_IN_BYTES); - /* copy the physical address to the System Area for the sep */ + /* Copy the physical address to the System Area for the SEP */ system_addr[0] = SEP_EXT_CACHE_ADDR_VAL_TOKEN; dev_dbg(&sep->pdev->dev, "ext cache init; system addr 0 is %x\n", system_addr[0]); @@ -3025,7 +3021,7 @@ static long sep_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) dev_dbg(&sep->pdev->dev, "SEP_IOCFREEDCB is %x\n", SEP_IOCFREEDCB); - /* make sure we own this device */ + /* Make sure we own this device */ mutex_lock(&sep->sep_mutex); if ((current->pid != sep->pid_doing_transaction) && (sep->pid_doing_transaction != 0)) { @@ -3037,48 +3033,48 @@ static long sep_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) mutex_unlock(&sep->sep_mutex); - /* check that the command is for sep device */ + /* Check that the command is for SEP device */ if (_IOC_TYPE(cmd) != SEP_IOC_MAGIC_NUMBER) { error = -ENOTTY; goto end_function; } - /* lock to prevent the daemon to interfere with operation */ + /* Lock to prevent the daemon to interfere with operation */ mutex_lock(&sep->ioctl_mutex); switch (cmd) { case SEP_IOCSENDSEPCOMMAND: - /* send command to SEP */ + /* Send command to SEP */ error = sep_send_command_handler(sep); break; case SEP_IOCALLOCDATAPOLL: - /* allocate data pool */ + /* Allocate data pool */ error = sep_allocate_data_pool_memory_handler(sep, arg); break; case SEP_IOCCREATESYMDMATABLE: - /* create dma table for synhronic operation */ + /* Create DMA table for synhronic operation */ error = sep_create_sync_dma_tables_handler(sep, arg); break; case SEP_IOCFREEDMATABLEDATA: - /* free the pages */ + /* Free the pages */ error = sep_free_dma_table_data_handler(sep); break; case SEP_IOCSEPSTART: - /* start command to sep */ - if (sep->pdev->revision == 0) /* only for old chip */ + /* Start command to SEP */ + if (sep->pdev->revision == 0) /* Only for old chip */ error = sep_start_handler(sep); else - error = -EPERM; /* not permitted on new chip */ + error = -EPERM; /* Not permitted on new chip */ break; case SEP_IOCSEPINIT: - /* init command to sep */ - if (sep->pdev->revision == 0) /* only for old chip */ + /* Init command to SEP */ + if (sep->pdev->revision == 0) /* Only for old chip */ error = sep_init_handler(sep, arg); else - error = -EPERM; /* not permitted on new chip */ + error = -EPERM; /* Not permitted on new chip */ break; case SEP_IOCGETSTATICPOOLADDR: - /* get the physical and virtual addresses of the static pool */ + /* Get the physical and virtual addresses of the static pool */ error = sep_get_static_pool_addr_handler(sep, arg); break; case SEP_IOCENDTRANSACTION: @@ -3087,10 +3083,10 @@ static long sep_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) case SEP_IOCREALLOCEXTCACHE: if (sep->mrst) error = -ENODEV; - if (sep->pdev->revision == 0) /* only for old chip */ + if (sep->pdev->revision == 0) /* Only for old chip */ error = sep_realloc_ext_cache_handler(sep, arg); else - error = -EPERM; /* not permitted on new chip */ + error = -EPERM; /* Not permitted on new chip */ break; case SEP_IOCRARPREPAREMESSAGE: error = sep_rar_prepare_output_msg_handler(sep, arg); @@ -3123,20 +3119,19 @@ end_function: */ static long sep_singleton_ioctl(struct file *filp, u32 cmd, unsigned long arg) { - /* error */ long error = 0; struct sep_device *sep = filp->private_data; dev_dbg(&sep->pdev->dev, "singleton_ioctl start\n"); dev_dbg(&sep->pdev->dev, "cmd is %x\n", cmd); - /* check that the command is for sep device */ + /* Check that the command is for the SEP device */ if (_IOC_TYPE(cmd) != SEP_IOC_MAGIC_NUMBER) { error = -ENOTTY; goto end_function; } - /* make sure we own this device */ + /* Make sure we own this device */ mutex_lock(&sep->sep_mutex); if ((current->pid != sep->pid_doing_transaction) && (sep->pid_doing_transaction != 0)) { @@ -3182,23 +3177,23 @@ static long sep_request_daemon_ioctl(struct file *filp, u32 cmd, dev_dbg(&sep->pdev->dev, "daemon ioctl: start\n"); dev_dbg(&sep->pdev->dev, "daemon ioctl: cmd is %x\n", cmd); - /* check that the command is for sep device */ + /* Check that the command is for SEP device */ if (_IOC_TYPE(cmd) != SEP_IOC_MAGIC_NUMBER) { error = -ENOTTY; goto end_function; } - /* only one process can access ioctl at any given time */ + /* Only one process can access ioctl at any given time */ mutex_lock(&sep->ioctl_mutex); switch (cmd) { case SEP_IOCSENDSEPRPLYCOMMAND: - /* send reply command to SEP */ + /* Send reply command to SEP */ error = sep_req_daemon_send_reply_command_handler(sep); break; case SEP_IOCENDTRANSACTION: /* - * end req daemon transaction, do nothing + * End req daemon transaction, do nothing * will be removed upon update in middleware * API library */ @@ -3217,7 +3212,7 @@ end_function: } /** - * sep_inthandler - Interrupt Handler + * sep_inthandler - interrupt handler * @irq: interrupt * @dev_id: device id */ @@ -3228,12 +3223,12 @@ static irqreturn_t sep_inthandler(int irq, void *dev_id) u32 reg_val, reg_val2 = 0; struct sep_device *sep = dev_id; - /* read the IRR register to check if this is SEP interrupt */ + /* Read the IRR register to check if this is SEP interrupt */ reg_val = sep_read_reg(sep, HW_HOST_IRR_REG_ADDR); dev_dbg(&sep->pdev->dev, "SEP Interrupt - reg is %08x\n", reg_val); if (reg_val & (0x1 << 13)) { - /* lock and update the counter of reply messages */ + /* Lock and update the counter of reply messages */ spin_lock_irqsave(&sep->snd_rply_lck, lck_flags); sep->reply_ct++; spin_unlock_irqrestore(&sep->snd_rply_lck, lck_flags); @@ -3241,7 +3236,7 @@ static irqreturn_t sep_inthandler(int irq, void *dev_id) dev_dbg(&sep->pdev->dev, "sep int: send_ct %lx reply_ct %lx\n", sep->send_ct, sep->reply_ct); - /* is this printf or daemon request? */ + /* Is this printf or daemon request? */ reg_val2 = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR2_REG_ADDR); dev_dbg(&sep->pdev->dev, "SEP Interrupt - reg2 is %08x\n", reg_val2); @@ -3253,11 +3248,11 @@ static irqreturn_t sep_inthandler(int irq, void *dev_id) dev_dbg(&sep->pdev->dev, "int: daemon request\n"); wake_up(&sep->event_request_daemon); } else { - dev_dbg(&sep->pdev->dev, "int: sep reply\n"); + dev_dbg(&sep->pdev->dev, "int: SEP reply\n"); wake_up(&sep->event); } } else { - dev_dbg(&sep->pdev->dev, "int: not sep interrupt\n"); + dev_dbg(&sep->pdev->dev, "int: not SEP interrupt\n"); int_error = IRQ_NONE; } if (int_error == IRQ_HANDLED) @@ -3329,20 +3324,20 @@ static int __devinit sep_probe(struct pci_dev *pdev, int error = 0; struct sep_device *sep; - pr_debug("Sep pci probe starting\n"); + pr_debug("SEP pci probe starting\n"); if (sep_dev != NULL) { dev_warn(&pdev->dev, "only one SEP supported.\n"); return -EBUSY; } - /* enable the device */ + /* Enable the device */ error = pci_enable_device(pdev); if (error) { dev_warn(&pdev->dev, "error enabling pci device\n"); goto end_function; } - /* allocate the sep_device structure for this device */ + /* Allocate the sep_device structure for this device */ sep_dev = kzalloc(sizeof(struct sep_device), GFP_ATOMIC); if (sep_dev == NULL) { dev_warn(&pdev->dev, @@ -3351,7 +3346,7 @@ static int __devinit sep_probe(struct pci_dev *pdev, } /* - * we're going to use another variable for actually + * We're going to use another variable for actually * working with the device; this way, if we have * multiple devices in the future, it would be easier * to make appropriate changes @@ -3366,7 +3361,7 @@ static int __devinit sep_probe(struct pci_dev *pdev, dev_dbg(&sep->pdev->dev, "PCI obtained, device being prepared\n"); dev_dbg(&sep->pdev->dev, "revision is %d\n", sep->pdev->revision); - /* set up our register area */ + /* Set up our register area */ sep->reg_physical_addr = pci_resource_start(sep->pdev, 0); if (!sep->reg_physical_addr) { dev_warn(&sep->pdev->dev, "Error getting register start\n"); @@ -3395,7 +3390,7 @@ static int __devinit sep_probe(struct pci_dev *pdev, (unsigned long long)sep->reg_physical_end, sep->reg_addr); - /* allocate the shared area */ + /* Allocate the shared area */ sep->shared_size = SEP_DRIVER_MESSAGE_SHARED_AREA_SIZE_IN_BYTES + SYNCHRONIC_DMA_TABLES_AREA_SIZE_BYTES + SEP_DRIVER_DATA_POOL_SHARED_AREA_SIZE_IN_BYTES + @@ -3404,11 +3399,11 @@ static int __devinit sep_probe(struct pci_dev *pdev, if (sep_map_and_alloc_shared_area(sep)) { error = -ENOMEM; - /* allocation failed */ + /* Allocation failed */ goto end_function_error; } - /* the next section depends on type of unit */ + /* The next section depends on type of unit */ if (sep->mrst) { error = register_rar(RAR_TYPE_IMAGE, &sep_callback, (unsigned long)sep); @@ -3435,14 +3430,14 @@ static int __devinit sep_probe(struct pci_dev *pdev, dev_dbg(&sep->pdev->dev, "about to write IMR and ICR REG_ADDR\n"); - /* clear ICR register */ + /* Clear ICR register */ sep_write_reg(sep, HW_HOST_ICR_REG_ADDR, 0xFFFFFFFF); - /* set the IMR register - open only GPR 2 */ + /* Set the IMR register - open only GPR 2 */ sep_write_reg(sep, HW_HOST_IMR_REG_ADDR, (~(0x1 << 13))); dev_dbg(&sep->pdev->dev, "about to call request_irq\n"); - /* get the interrupt line */ + /* Get the interrupt line */ error = request_irq(pdev->irq, sep_inthandler, IRQF_SHARED, "sep_driver", sep); @@ -3455,7 +3450,7 @@ static int __devinit sep_probe(struct pci_dev *pdev, goto end_function; end_function_deallocate_sep_shared_area: - /* de-allocate shared area */ + /* De-allocate shared area */ sep_unmap_and_free_shared_area(sep); end_function_error: @@ -3475,7 +3470,7 @@ static DEFINE_PCI_DEVICE_TABLE(sep_pci_id_tbl) = { MODULE_DEVICE_TABLE(pci, sep_pci_id_tbl); -/* field for registering driver to PCI device */ +/* Field for registering driver to PCI device */ static struct pci_driver sep_pci_driver = { .name = "sep_sec_driver", .id_table = sep_pci_id_tbl, @@ -3483,7 +3478,7 @@ static struct pci_driver sep_pci_driver = { /* FIXME: remove handler */ }; -/* file operation for singleton sep operations */ +/* File operation for singleton SEP operations */ static const struct file_operations singleton_file_operations = { .owner = THIS_MODULE, .unlocked_ioctl = sep_singleton_ioctl, @@ -3493,7 +3488,7 @@ static const struct file_operations singleton_file_operations = { .mmap = sep_mmap, }; -/* file operation for daemon operations */ +/* File operation for daemon operations */ static const struct file_operations daemon_file_operations = { .owner = THIS_MODULE, .unlocked_ioctl = sep_request_daemon_ioctl, @@ -3503,7 +3498,7 @@ static const struct file_operations daemon_file_operations = { .mmap = sep_request_daemon_mmap, }; -/* the files operations structure of the driver */ +/* The files operations structure of the driver */ static const struct file_operations sep_file_operations = { .owner = THIS_MODULE, .unlocked_ioctl = sep_ioctl, @@ -3526,19 +3521,19 @@ static int sep_reconfig_shared_area(struct sep_device *sep) dev_dbg(&sep->pdev->dev, "reconfig shared area start\n"); - /* send the new SHARED MESSAGE AREA to the SEP */ + /* Send the new SHARED MESSAGE AREA to the SEP */ dev_dbg(&sep->pdev->dev, "sending %08llx to sep\n", (unsigned long long)sep->shared_bus); sep_write_reg(sep, HW_HOST_HOST_SEP_GPR1_REG_ADDR, sep->shared_bus); - /* poll for SEP response */ + /* Poll for SEP response */ ret_val = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR1_REG_ADDR); while (ret_val != 0xffffffff && ret_val != sep->shared_bus) ret_val = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR1_REG_ADDR); - /* check the return value (register) */ + /* Check the return value (register) */ if (ret_val != sep->shared_bus) { dev_warn(&sep->pdev->dev, "could not reconfig shared area\n"); dev_warn(&sep->pdev->dev, "result was %x\n", ret_val); @@ -3574,7 +3569,7 @@ static int sep_register_driver_to_fs(struct sep_device *sep) ret_val = misc_register(&sep->miscdev_sep); if (ret_val) { - dev_warn(&sep->pdev->dev, "misc reg fails for sep %x\n", + dev_warn(&sep->pdev->dev, "misc reg fails for SEP %x\n", ret_val); return ret_val; } @@ -3611,7 +3606,7 @@ static int __init sep_init(void) int ret_val = 0; struct sep_device *sep = NULL; - pr_debug("Sep driver: Init start\n"); + pr_debug("SEP driver: Init start\n"); ret_val = pci_register_driver(&sep_pci_driver); if (ret_val) { @@ -3628,14 +3623,14 @@ static int __init sep_init(void) mutex_init(&sep->sep_mutex); mutex_init(&sep->ioctl_mutex); - /* new chip requires share area reconfigure */ - if (sep->pdev->revision == 4) { /* only for new chip */ + /* The new chip requires ashared area reconfigure */ + if (sep->pdev->revision == 4) { /* Only for new chip */ ret_val = sep_reconfig_shared_area(sep); if (ret_val) goto end_function_unregister_pci; } - /* register driver to fs */ + /* Register driver to fs */ ret_val = sep_register_driver_to_fs(sep); if (ret_val) { dev_warn(&sep->pdev->dev, "error registering device to file\n"); @@ -3665,18 +3660,18 @@ static void __exit sep_exit(void) sep = sep_dev; pr_debug("Exit start\n"); - /* unregister from fs */ + /* Unregister from fs */ misc_deregister(&sep->miscdev_sep); misc_deregister(&sep->miscdev_singleton); misc_deregister(&sep->miscdev_daemon); - /* free the irq */ + /* Free the irq */ free_irq(sep->pdev->irq, sep); - /* unregister the driver */ + /* Unregister the driver */ pci_unregister_driver(&sep_pci_driver); - /* free shared area */ + /* Free the shared area */ if (sep_dev) { sep_unmap_and_free_shared_area(sep_dev); dev_dbg(&sep->pdev->dev, -- cgit v1.2.3 From 2bb3af58d0f712c728cf1230539044d94c9a3be0 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Wed, 24 Nov 2010 19:38:54 +0000 Subject: Staging: sep: cant is an angular inclination So use can't instead. Signed-off-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/staging/sep/sep_driver.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/sep/sep_driver.c b/drivers/staging/sep/sep_driver.c index 9c165587a247..ebe7a90aec0e 100644 --- a/drivers/staging/sep/sep_driver.c +++ b/drivers/staging/sep/sep_driver.c @@ -98,7 +98,7 @@ static int sep_load_firmware(struct sep_device *sep) error = request_firmware(&fw, res_name, &sep->pdev->dev); if (error) { - dev_warn(&sep->pdev->dev, "cant request resident fw\n"); + dev_warn(&sep->pdev->dev, "can't request resident fw\n"); return error; } @@ -3280,7 +3280,7 @@ static int sep_callback(unsigned long sep_context_pointer) &rar_end_address); if (error) { - dev_warn(&sep->pdev->dev, "mrst cant get rar region\n"); + dev_warn(&sep->pdev->dev, "mrst can't get rar region\n"); goto end_function; } @@ -3417,7 +3417,7 @@ static int __devinit sep_probe(struct pci_dev *pdev, sep->rar_addr = dma_alloc_coherent(NULL, sep->rar_size, &sep->rar_bus, GFP_KERNEL); if (sep->rar_addr == NULL) { - dev_warn(&sep->pdev->dev, "cant allocate mfld rar\n"); + dev_warn(&sep->pdev->dev, "can't allocate mfld rar\n"); error = -ENOMEM; goto end_function_deallocate_sep_shared_area; } -- cgit v1.2.3 From 6f89be93ce6e718a51215336845c70ada06627ba Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Wed, 24 Nov 2010 19:39:07 +0000 Subject: Staging: sep: clean up a couple of spots missed in pass one Another copy_user case and some formatting of dbg Signed-off-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/staging/sep/sep_driver.c | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/drivers/staging/sep/sep_driver.c b/drivers/staging/sep/sep_driver.c index ebe7a90aec0e..5e27b5a4d043 100644 --- a/drivers/staging/sep/sep_driver.c +++ b/drivers/staging/sep/sep_driver.c @@ -1037,8 +1037,6 @@ static int sep_allocate_data_pool_memory_handler(struct sep_device *sep, sizeof(struct alloc_struct)); if (error) { error = -EFAULT; - dev_warn(&sep->pdev->dev, - "allocate data pool copy to user error\n"); goto end_function; } @@ -1083,13 +1081,10 @@ static int sep_lock_kernel_pages(struct sep_device *sep, /* Map array */ struct sep_dma_map *map_array; - dev_dbg(&sep->pdev->dev, - "sep_lock_kernel_pages start\n"); - - dev_dbg(&sep->pdev->dev, - "kernel_virt_addr is %08x\n", kernel_virt_addr); - dev_dbg(&sep->pdev->dev, - "data_size is %x\n", data_size); + dev_dbg(&sep->pdev->dev, "sep_lock_kernel_pages start\n"); + dev_dbg(&sep->pdev->dev, "kernel_virt_addr is %08x\n", + kernel_virt_addr); + dev_dbg(&sep->pdev->dev, "data_size is %x\n", data_size); lli_array = kmalloc(sizeof(struct sep_lli_entry), GFP_ATOMIC); if (!lli_array) { @@ -1182,8 +1177,7 @@ static int sep_lock_user_pages(struct sep_device *sep, /* Direction of the DMA mapping for locked pages */ enum dma_data_direction dir; - dev_dbg(&sep->pdev->dev, - "sep_lock_user_pages start\n"); + dev_dbg(&sep->pdev->dev, "sep_lock_user_pages start\n"); /* Set start and end pages and num pages */ end_page = (app_virt_addr + data_size - 1) >> PAGE_SHIFT; -- cgit v1.2.3 From da3f825bc71b420e129b6344be0e3e863ebf8a42 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Wed, 24 Nov 2010 19:39:20 +0000 Subject: Staging: sep: Fix crash if a device is not found The existing code works mostly by luck. The PCI probe is done by the register and completes before the register returns thus allowing the other init code to run in time. Without a SEP or if unlucky this doesn't occur and you get an OOPS which for some reason causes grumpiness. As the season of good b^Hcheer is supposed to be approaching we should probably fix it. Signed-off-by: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/staging/sep/sep_driver.c | 363 ++++++++++++++++++--------------------- 1 file changed, 167 insertions(+), 196 deletions(-) diff --git a/drivers/staging/sep/sep_driver.c b/drivers/staging/sep/sep_driver.c index 5e27b5a4d043..76331112a264 100644 --- a/drivers/staging/sep/sep_driver.c +++ b/drivers/staging/sep/sep_driver.c @@ -256,8 +256,7 @@ static int sep_singleton_open(struct inode *inode_ptr, struct file *file_ptr) file_ptr->private_data = sep; - dev_dbg(&sep->pdev->dev, "Singleton open for pid %d\n", - current->pid); + dev_dbg(&sep->pdev->dev, "Singleton open for pid %d\n", current->pid); dev_dbg(&sep->pdev->dev, "calling test and set for singleton 0\n"); if (test_and_set_bit(0, &sep->singleton_access_flag)) { @@ -265,10 +264,8 @@ static int sep_singleton_open(struct inode *inode_ptr, struct file *file_ptr) goto end_function; } - dev_dbg(&sep->pdev->dev, - "sep_singleton_open end\n"); + dev_dbg(&sep->pdev->dev, "sep_singleton_open end\n"); end_function: - return error; } @@ -386,9 +383,7 @@ static int sep_req_daemon_send_reply_command_handler(struct sep_device *sep) sep->reply_ct++; /* Send the interrupt to SEP */ - sep_write_reg(sep, HW_HOST_HOST_SEP_GPR2_REG_ADDR, - sep->send_ct); - + sep_write_reg(sep, HW_HOST_HOST_SEP_GPR2_REG_ADDR, sep->send_ct); sep->send_ct++; spin_unlock_irqrestore(&sep->snd_rply_lck, lck_flags); @@ -3304,6 +3299,125 @@ end_function: return error; } +/** + * sep_reconfig_shared_area - reconfigure shared area + * @sep: pointer to struct sep_device + * + * Reconfig the shared area between HOST and SEP - needed in case + * the DX_CC_Init function was called before OS loading. + */ +static int sep_reconfig_shared_area(struct sep_device *sep) +{ + int ret_val; + + dev_dbg(&sep->pdev->dev, "reconfig shared area start\n"); + + /* Send the new SHARED MESSAGE AREA to the SEP */ + dev_dbg(&sep->pdev->dev, "sending %08llx to sep\n", + (unsigned long long)sep->shared_bus); + + sep_write_reg(sep, HW_HOST_HOST_SEP_GPR1_REG_ADDR, sep->shared_bus); + + /* Poll for SEP response */ + ret_val = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR1_REG_ADDR); + + while (ret_val != 0xffffffff && ret_val != sep->shared_bus) + ret_val = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR1_REG_ADDR); + + /* Check the return value (register) */ + if (ret_val != sep->shared_bus) { + dev_warn(&sep->pdev->dev, "could not reconfig shared area\n"); + dev_warn(&sep->pdev->dev, "result was %x\n", ret_val); + ret_val = -ENOMEM; + } else + ret_val = 0; + + dev_dbg(&sep->pdev->dev, "reconfig shared area end\n"); + return ret_val; +} + +/* File operation for singleton SEP operations */ +static const struct file_operations singleton_file_operations = { + .owner = THIS_MODULE, + .unlocked_ioctl = sep_singleton_ioctl, + .poll = sep_poll, + .open = sep_singleton_open, + .release = sep_singleton_release, + .mmap = sep_mmap, +}; + +/* File operation for daemon operations */ +static const struct file_operations daemon_file_operations = { + .owner = THIS_MODULE, + .unlocked_ioctl = sep_request_daemon_ioctl, + .poll = sep_request_daemon_poll, + .open = sep_request_daemon_open, + .release = sep_request_daemon_release, + .mmap = sep_request_daemon_mmap, +}; + +/* The files operations structure of the driver */ +static const struct file_operations sep_file_operations = { + .owner = THIS_MODULE, + .unlocked_ioctl = sep_ioctl, + .poll = sep_poll, + .open = sep_open, + .release = sep_release, + .mmap = sep_mmap, +}; + +/** + * sep_register_driver_with_fs - register misc devices + * @sep: pointer to struct sep_device + * + * This function registers the driver with the file system + */ +static int sep_register_driver_with_fs(struct sep_device *sep) +{ + int ret_val; + + sep->miscdev_sep.minor = MISC_DYNAMIC_MINOR; + sep->miscdev_sep.name = SEP_DEV_NAME; + sep->miscdev_sep.fops = &sep_file_operations; + + sep->miscdev_singleton.minor = MISC_DYNAMIC_MINOR; + sep->miscdev_singleton.name = SEP_DEV_SINGLETON; + sep->miscdev_singleton.fops = &singleton_file_operations; + + sep->miscdev_daemon.minor = MISC_DYNAMIC_MINOR; + sep->miscdev_daemon.name = SEP_DEV_DAEMON; + sep->miscdev_daemon.fops = &daemon_file_operations; + + ret_val = misc_register(&sep->miscdev_sep); + if (ret_val) { + dev_warn(&sep->pdev->dev, "misc reg fails for SEP %x\n", + ret_val); + return ret_val; + } + + ret_val = misc_register(&sep->miscdev_singleton); + if (ret_val) { + dev_warn(&sep->pdev->dev, "misc reg fails for sing %x\n", + ret_val); + misc_deregister(&sep->miscdev_sep); + return ret_val; + } + + if (!sep->mrst) { + ret_val = misc_register(&sep->miscdev_daemon); + if (ret_val) { + dev_warn(&sep->pdev->dev, "misc reg fails for dmn %x\n", + ret_val); + misc_deregister(&sep->miscdev_sep); + misc_deregister(&sep->miscdev_singleton); + + return ret_val; + } + } + return ret_val; +} + + /** * sep_probe - probe a matching PCI device * @pdev: pci_device @@ -3349,6 +3463,12 @@ static int __devinit sep_probe(struct pci_dev *pdev, sep->pdev = pdev; + init_waitqueue_head(&sep->event); + init_waitqueue_head(&sep->event_request_daemon); + spin_lock_init(&sep->snd_rply_lck); + mutex_init(&sep->sep_mutex); + mutex_init(&sep->ioctl_mutex); + if (pdev->device == MRST_PCI_DEVICE_ID) sep->mrst = 1; @@ -3435,9 +3555,26 @@ static int __devinit sep_probe(struct pci_dev *pdev, error = request_irq(pdev->irq, sep_inthandler, IRQF_SHARED, "sep_driver", sep); - if (!error) - goto end_function; + if (error) + goto end_function_dealloc_rar; + /* The new chip requires ashared area reconfigure */ + if (sep->pdev->revision == 4) { /* Only for new chip */ + error = sep_reconfig_shared_area(sep); + if (error) + goto end_function_free_irq; + } + /* Finally magic up the device nodes */ + /* Register driver with the fs */ + error = sep_register_driver_with_fs(sep); + if (error == 0) + /* Success */ + return 0; + +end_function_free_irq: + free_irq(pdev->irq, sep); + +end_function_dealloc_rar: if (sep->rar_addr) dma_free_coherent(&sep->pdev->dev, sep->rar_size, sep->rar_addr, sep->rar_bus); @@ -3456,6 +3593,23 @@ end_function: return error; } +static void sep_remove(struct pci_dev *pdev) +{ + struct sep_device *sep = sep_dev; + + /* Unregister from fs */ + misc_deregister(&sep->miscdev_sep); + misc_deregister(&sep->miscdev_singleton); + misc_deregister(&sep->miscdev_daemon); + + /* Free the irq */ + free_irq(sep->pdev->irq, sep); + + /* Free the shared area */ + sep_unmap_and_free_shared_area(sep_dev); + iounmap((void *) sep_dev->reg_addr); +} + static DEFINE_PCI_DEVICE_TABLE(sep_pci_id_tbl) = { {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MRST_PCI_DEVICE_ID)}, {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MFLD_PCI_DEVICE_ID)}, @@ -3468,127 +3622,10 @@ MODULE_DEVICE_TABLE(pci, sep_pci_id_tbl); static struct pci_driver sep_pci_driver = { .name = "sep_sec_driver", .id_table = sep_pci_id_tbl, - .probe = sep_probe - /* FIXME: remove handler */ + .probe = sep_probe, + .remove = sep_remove }; -/* File operation for singleton SEP operations */ -static const struct file_operations singleton_file_operations = { - .owner = THIS_MODULE, - .unlocked_ioctl = sep_singleton_ioctl, - .poll = sep_poll, - .open = sep_singleton_open, - .release = sep_singleton_release, - .mmap = sep_mmap, -}; - -/* File operation for daemon operations */ -static const struct file_operations daemon_file_operations = { - .owner = THIS_MODULE, - .unlocked_ioctl = sep_request_daemon_ioctl, - .poll = sep_request_daemon_poll, - .open = sep_request_daemon_open, - .release = sep_request_daemon_release, - .mmap = sep_request_daemon_mmap, -}; - -/* The files operations structure of the driver */ -static const struct file_operations sep_file_operations = { - .owner = THIS_MODULE, - .unlocked_ioctl = sep_ioctl, - .poll = sep_poll, - .open = sep_open, - .release = sep_release, - .mmap = sep_mmap, -}; - -/** - * sep_reconfig_shared_area - reconfigure shared area - * @sep: pointer to struct sep_device - * - * Reconfig the shared area between HOST and SEP - needed in case - * the DX_CC_Init function was called before OS loading. - */ -static int sep_reconfig_shared_area(struct sep_device *sep) -{ - int ret_val; - - dev_dbg(&sep->pdev->dev, "reconfig shared area start\n"); - - /* Send the new SHARED MESSAGE AREA to the SEP */ - dev_dbg(&sep->pdev->dev, "sending %08llx to sep\n", - (unsigned long long)sep->shared_bus); - - sep_write_reg(sep, HW_HOST_HOST_SEP_GPR1_REG_ADDR, sep->shared_bus); - - /* Poll for SEP response */ - ret_val = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR1_REG_ADDR); - - while (ret_val != 0xffffffff && ret_val != sep->shared_bus) - ret_val = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR1_REG_ADDR); - - /* Check the return value (register) */ - if (ret_val != sep->shared_bus) { - dev_warn(&sep->pdev->dev, "could not reconfig shared area\n"); - dev_warn(&sep->pdev->dev, "result was %x\n", ret_val); - ret_val = -ENOMEM; - } else - ret_val = 0; - - dev_dbg(&sep->pdev->dev, "reconfig shared area end\n"); - return ret_val; -} - -/** - * sep_register_driver_to_fs - register misc devices - * @sep: pointer to struct sep_device - * - * This function registers the driver to the file system - */ -static int sep_register_driver_to_fs(struct sep_device *sep) -{ - int ret_val; - - sep->miscdev_sep.minor = MISC_DYNAMIC_MINOR; - sep->miscdev_sep.name = SEP_DEV_NAME; - sep->miscdev_sep.fops = &sep_file_operations; - - sep->miscdev_singleton.minor = MISC_DYNAMIC_MINOR; - sep->miscdev_singleton.name = SEP_DEV_SINGLETON; - sep->miscdev_singleton.fops = &singleton_file_operations; - - sep->miscdev_daemon.minor = MISC_DYNAMIC_MINOR; - sep->miscdev_daemon.name = SEP_DEV_DAEMON; - sep->miscdev_daemon.fops = &daemon_file_operations; - - ret_val = misc_register(&sep->miscdev_sep); - if (ret_val) { - dev_warn(&sep->pdev->dev, "misc reg fails for SEP %x\n", - ret_val); - return ret_val; - } - - ret_val = misc_register(&sep->miscdev_singleton); - if (ret_val) { - dev_warn(&sep->pdev->dev, "misc reg fails for sing %x\n", - ret_val); - misc_deregister(&sep->miscdev_sep); - return ret_val; - } - - if (!sep->mrst) { - ret_val = misc_register(&sep->miscdev_daemon); - if (ret_val) { - dev_warn(&sep->pdev->dev, "misc reg fails for dmn %x\n", - ret_val); - misc_deregister(&sep->miscdev_sep); - misc_deregister(&sep->miscdev_singleton); - - return ret_val; - } - } - return ret_val; -} /** * sep_init - init function @@ -3597,47 +3634,7 @@ static int sep_register_driver_to_fs(struct sep_device *sep) */ static int __init sep_init(void) { - int ret_val = 0; - struct sep_device *sep = NULL; - - pr_debug("SEP driver: Init start\n"); - - ret_val = pci_register_driver(&sep_pci_driver); - if (ret_val) { - pr_debug("sep_driver:sep_driver_to_device failed, ret_val is %d\n", - ret_val); - goto end_function; - } - - sep = sep_dev; - - init_waitqueue_head(&sep->event); - init_waitqueue_head(&sep->event_request_daemon); - spin_lock_init(&sep->snd_rply_lck); - mutex_init(&sep->sep_mutex); - mutex_init(&sep->ioctl_mutex); - - /* The new chip requires ashared area reconfigure */ - if (sep->pdev->revision == 4) { /* Only for new chip */ - ret_val = sep_reconfig_shared_area(sep); - if (ret_val) - goto end_function_unregister_pci; - } - - /* Register driver to fs */ - ret_val = sep_register_driver_to_fs(sep); - if (ret_val) { - dev_warn(&sep->pdev->dev, "error registering device to file\n"); - goto end_function_unregister_pci; - } - goto end_function; - -end_function_unregister_pci: - pci_unregister_driver(&sep_pci_driver); - -end_function: - dev_dbg(&sep->pdev->dev, "Init end\n"); - return ret_val; + return pci_register_driver(&sep_pci_driver); } @@ -3649,33 +3646,7 @@ end_function: */ static void __exit sep_exit(void) { - struct sep_device *sep; - - sep = sep_dev; - pr_debug("Exit start\n"); - - /* Unregister from fs */ - misc_deregister(&sep->miscdev_sep); - misc_deregister(&sep->miscdev_singleton); - misc_deregister(&sep->miscdev_daemon); - - /* Free the irq */ - free_irq(sep->pdev->irq, sep); - - /* Unregister the driver */ pci_unregister_driver(&sep_pci_driver); - - /* Free the shared area */ - if (sep_dev) { - sep_unmap_and_free_shared_area(sep_dev); - dev_dbg(&sep->pdev->dev, - "free pages SEP SHARED AREA\n"); - iounmap((void *) sep_dev->reg_addr); - dev_dbg(&sep->pdev->dev, - "iounmap\n"); - } - pr_debug("release_mem_region\n"); - pr_debug("Exit end\n"); } -- cgit v1.2.3 From 3b93ff030204ca36fb1e9917743bbf22a423e527 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 29 Nov 2010 11:18:08 -0800 Subject: Staging: sep: do not select the driver by default The Kconfig file should not have 'y' as the default, especially as the driver will crash a machine if it is loaded and the hardware is not present. Cc: Mark Allyn Cc: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/staging/sep/Kconfig | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/staging/sep/Kconfig b/drivers/staging/sep/Kconfig index 34f3ef5f9df8..92bf16667d04 100644 --- a/drivers/staging/sep/Kconfig +++ b/drivers/staging/sep/Kconfig @@ -1,7 +1,6 @@ config DX_SEP tristate "Discretix SEP driver" depends on PCI - default y help Discretix SEP driver; used for the security processor subsystem on bard the Intel Mobile Internet Device. -- cgit v1.2.3 From 857cf1d1e623467622eff3a6b0edc720dcafdd52 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 29 Nov 2010 11:18:08 -0800 Subject: Staging: sep: do not select the driver by default The Kconfig file should not have 'y' as the default, especially as the driver will crash a machine if it is loaded and the hardware is not present. Reported-by: Stephen Rothwell Cc: Mark Allyn Cc: Alan Cox Signed-off-by: Greg Kroah-Hartman --- drivers/staging/sep/Kconfig | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/staging/sep/Kconfig b/drivers/staging/sep/Kconfig index 34f3ef5f9df8..92bf16667d04 100644 --- a/drivers/staging/sep/Kconfig +++ b/drivers/staging/sep/Kconfig @@ -1,7 +1,6 @@ config DX_SEP tristate "Discretix SEP driver" depends on PCI - default y help Discretix SEP driver; used for the security processor subsystem on bard the Intel Mobile Internet Device. -- cgit v1.2.3 From 57d8cd23c2a0d261bdc959201dd4a33a2080bdfb Mon Sep 17 00:00:00 2001 From: Brett Rudley Date: Mon, 22 Nov 2010 16:58:52 -0800 Subject: staging: brcm80211: OSL shrink: Remove OSL_PCI_READ/WRITE_CONFIG Replace OSL layer PCI READ/WRITE macros with native calls. Signed-off-by: Brett Rudley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/include/linux_osl.h | 9 ---- drivers/staging/brcm80211/include/siutils.h | 2 +- drivers/staging/brcm80211/util/aiutils.c | 6 +-- drivers/staging/brcm80211/util/linux_osl.c | 13 ----- drivers/staging/brcm80211/util/siutils.c | 70 ++++++++++++++------------- 5 files changed, 40 insertions(+), 60 deletions(-) diff --git a/drivers/staging/brcm80211/include/linux_osl.h b/drivers/staging/brcm80211/include/linux_osl.h index d314dfb2b62f..010182fa1a92 100644 --- a/drivers/staging/brcm80211/include/linux_osl.h +++ b/drivers/staging/brcm80211/include/linux_osl.h @@ -40,15 +40,6 @@ extern void osl_assert(char *exp, char *file, int line); #endif /* __GNUC__ */ #endif /* defined(BCMDBG_ASSERT) */ -/* PCI configuration space access macros */ -#define OSL_PCI_READ_CONFIG(osh, offset, size) \ - osl_pci_read_config((osh), (offset), (size)) -#define OSL_PCI_WRITE_CONFIG(osh, offset, size, val) \ - osl_pci_write_config((osh), (offset), (size), (val)) -extern u32 osl_pci_read_config(struct osl_info *osh, uint offset, uint size); -extern void osl_pci_write_config(struct osl_info *osh, uint offset, uint size, - uint val); - /* PCI device bus # and slot # */ #define OSL_PCI_BUS(osh) osl_pci_bus(osh) #define OSL_PCI_SLOT(osh) osl_pci_slot(osh) diff --git a/drivers/staging/brcm80211/include/siutils.h b/drivers/staging/brcm80211/include/siutils.h index 6a074ab9f34b..0f042799c376 100644 --- a/drivers/staging/brcm80211/include/siutils.h +++ b/drivers/staging/brcm80211/include/siutils.h @@ -217,7 +217,7 @@ typedef struct gpioh_item { /* misc si info needed by some of the routines */ typedef struct si_info { struct si_pub pub; /* back plane public state (must be first field) */ - void *osh; /* osl os handle */ + struct osl_info *osh; /* osl os handle */ void *sdh; /* bcmsdh handle */ uint dev_coreid; /* the core provides driver functions */ void *intr_arg; /* interrupt callback function arg */ diff --git a/drivers/staging/brcm80211/util/aiutils.c b/drivers/staging/brcm80211/util/aiutils.c index 1d4e3729ad61..dbb3e369b740 100644 --- a/drivers/staging/brcm80211/util/aiutils.c +++ b/drivers/staging/brcm80211/util/aiutils.c @@ -129,7 +129,7 @@ void ai_scan(si_t *sih, void *regs, uint devid) sii->curwrap = (void *)((unsigned long)regs + SI_CORE_SIZE); /* Now point the window at the erom */ - OSL_PCI_WRITE_CONFIG(sii->osh, PCI_BAR0_WIN, 4, erombase); + pci_write_config_dword(sii->osh->pdev, PCI_BAR0_WIN, erombase); eromptr = regs; break; @@ -351,10 +351,10 @@ void *ai_setcoreidx(si_t *sih, uint coreidx) case PCI_BUS: /* point bar0 window */ - OSL_PCI_WRITE_CONFIG(sii->osh, PCI_BAR0_WIN, 4, addr); + pci_write_config_dword(sii->osh->pdev, PCI_BAR0_WIN, addr); regs = sii->curmap; /* point bar0 2nd 4KB window */ - OSL_PCI_WRITE_CONFIG(sii->osh, PCI_BAR0_WIN2, 4, wrap); + pci_write_config_dword(sii->osh->pdev, PCI_BAR0_WIN2, wrap); break; #ifdef BCMSDIO diff --git a/drivers/staging/brcm80211/util/linux_osl.c b/drivers/staging/brcm80211/util/linux_osl.c index a07eada14d08..a0f9dcb0b786 100644 --- a/drivers/staging/brcm80211/util/linux_osl.c +++ b/drivers/staging/brcm80211/util/linux_osl.c @@ -128,19 +128,6 @@ void BCMFASTPATH osl_pktfree(struct osl_info *osh, void *p, bool send) } } -u32 osl_pci_read_config(struct osl_info *osh, uint offset, uint size) -{ - uint val; - pci_read_config_dword(osh->pdev, offset, &val); - return val; -} - -void osl_pci_write_config(struct osl_info *osh, uint offset, uint size, - uint val) -{ - pci_write_config_dword(osh->pdev, offset, val); -} - /* return bus # for the pci device pointed by osh->pdev */ uint osl_pci_bus(struct osl_info *osh) { diff --git a/drivers/staging/brcm80211/util/siutils.c b/drivers/staging/brcm80211/util/siutils.c index 4d2df4977727..e13053626d29 100644 --- a/drivers/staging/brcm80211/util/siutils.c +++ b/drivers/staging/brcm80211/util/siutils.c @@ -315,7 +315,7 @@ static __used void si_nvram_process(si_info_t *sii, char *pvars) switch (BUSTYPE(sii->pub.bustype)) { case PCI_BUS: /* do a pci config read to get subsystem id and subvendor id */ - w = OSL_PCI_READ_CONFIG(sii->osh, PCI_CFG_SVID, sizeof(u32)); + pci_read_config_dword(sii->osh->pdev, PCI_CFG_SVID, &w); /* Let nvram variables override subsystem Vend/ID */ sii->pub.boardvendor = (u16)si_getdevpathintvar(&sii->pub, "boardvendor"); @@ -526,20 +526,23 @@ static si_info_t *si_doattach(si_info_t *sii, uint devid, struct osl_info *osh, sii->osh = osh; /* check to see if we are a si core mimic'ing a pci core */ - if ((bustype == PCI_BUS) && - (OSL_PCI_READ_CONFIG(sii->osh, PCI_SPROM_CONTROL, sizeof(u32)) == - 0xffffffff)) { - SI_ERROR(("%s: incoming bus is PCI but it's a lie, switching to SI " "devid:0x%x\n", __func__, devid)); - bustype = SI_BUS; + if (bustype == PCI_BUS) { + pci_read_config_dword(sii->osh->pdev, PCI_SPROM_CONTROL, &w); + if (w == 0xffffffff) { + SI_ERROR(("%s: incoming bus is PCI but it's a lie, " + " switching to SI devid:0x%x\n", + __func__, devid)); + bustype = SI_BUS; + } } /* find Chipcommon address */ if (bustype == PCI_BUS) { - savewin = - OSL_PCI_READ_CONFIG(sii->osh, PCI_BAR0_WIN, sizeof(u32)); + pci_read_config_dword(sii->osh->pdev, PCI_BAR0_WIN, &savewin); if (!GOODCOREADDR(savewin, SI_ENUM_BASE)) savewin = SI_ENUM_BASE; - OSL_PCI_WRITE_CONFIG(sii->osh, PCI_BAR0_WIN, 4, SI_ENUM_BASE); + pci_write_config_dword(sii->osh->pdev, PCI_BAR0_WIN, + SI_ENUM_BASE); cc = (chipcregs_t *) regs; } else { cc = (chipcregs_t *) REG_MAP(SI_ENUM_BASE, SI_CORE_SIZE); @@ -1089,16 +1092,18 @@ void si_watchdog(si_t *sih, uint ticks) static uint si_slowclk_src(si_info_t *sii) { chipcregs_t *cc; + u32 val; ASSERT(SI_FAST(sii) || si_coreid(&sii->pub) == CC_CORE_ID); if (sii->pub.ccrev < 6) { - if ((BUSTYPE(sii->pub.bustype) == PCI_BUS) && - (OSL_PCI_READ_CONFIG(sii->osh, PCI_GPIO_OUT, sizeof(u32)) - & PCI_CFG_GPIO_SCS)) - return SCC_SS_PCI; - else - return SCC_SS_XTAL; + if (BUSTYPE(sii->pub.bustype) == PCI_BUS) { + pci_read_config_dword(sii->osh->pdev, PCI_GPIO_OUT, + &val); + if (val & PCI_CFG_GPIO_SCS) + return SCC_SS_PCI; + } + return SCC_SS_XTAL; } else if (sii->pub.ccrev < 10) { cc = (chipcregs_t *) si_setcoreidx(&sii->pub, sii->curidx); return R_REG(sii->osh, &cc->slow_clk_ctl) & SCC_SS_MASK; @@ -1280,12 +1285,9 @@ int si_clkctl_xtal(si_t *sih, uint what, bool on) if (PCIE(sii)) return -1; - in = OSL_PCI_READ_CONFIG(sii->osh, PCI_GPIO_IN, sizeof(u32)); - out = - OSL_PCI_READ_CONFIG(sii->osh, PCI_GPIO_OUT, sizeof(u32)); - outen = - OSL_PCI_READ_CONFIG(sii->osh, PCI_GPIO_OUTEN, - sizeof(u32)); + pci_read_config_dword(sii->osh->pdev, PCI_GPIO_IN, &in); + pci_read_config_dword(sii->osh->pdev, PCI_GPIO_OUT, &out); + pci_read_config_dword(sii->osh->pdev, PCI_GPIO_OUTEN, &outen); /* * Avoid glitching the clock if GPRS is already using it. @@ -1306,18 +1308,18 @@ int si_clkctl_xtal(si_t *sih, uint what, bool on) out |= PCI_CFG_GPIO_XTAL; if (what & PLL) out |= PCI_CFG_GPIO_PLL; - OSL_PCI_WRITE_CONFIG(sii->osh, PCI_GPIO_OUT, - sizeof(u32), out); - OSL_PCI_WRITE_CONFIG(sii->osh, PCI_GPIO_OUTEN, - sizeof(u32), outen); + pci_write_config_dword(sii->osh->pdev, + PCI_GPIO_OUT, out); + pci_write_config_dword(sii->osh->pdev, + PCI_GPIO_OUTEN, outen); udelay(XTAL_ON_DELAY); } /* turn pll on */ if (what & PLL) { out &= ~PCI_CFG_GPIO_PLL; - OSL_PCI_WRITE_CONFIG(sii->osh, PCI_GPIO_OUT, - sizeof(u32), out); + pci_write_config_dword(sii->osh->pdev, + PCI_GPIO_OUT, out); mdelay(2); } } else { @@ -1325,10 +1327,10 @@ int si_clkctl_xtal(si_t *sih, uint what, bool on) out &= ~PCI_CFG_GPIO_XTAL; if (what & PLL) out |= PCI_CFG_GPIO_PLL; - OSL_PCI_WRITE_CONFIG(sii->osh, PCI_GPIO_OUT, - sizeof(u32), out); - OSL_PCI_WRITE_CONFIG(sii->osh, PCI_GPIO_OUTEN, - sizeof(u32), outen); + pci_write_config_dword(sii->osh->pdev, + PCI_GPIO_OUT, out); + pci_write_config_dword(sii->osh->pdev, + PCI_GPIO_OUTEN, outen); } default: @@ -1696,9 +1698,9 @@ void si_pci_setup(si_t *sih, uint coremask) */ if (PCIE(sii) || (PCI(sii) && ((sii->pub.buscorerev) >= 6))) { /* pci config write to set this core bit in PCIIntMask */ - w = OSL_PCI_READ_CONFIG(sii->osh, PCI_INT_MASK, sizeof(u32)); + pci_read_config_dword(sii->osh->pdev, PCI_INT_MASK, &w); w |= (coremask << PCI_SBIM_SHIFT); - OSL_PCI_WRITE_CONFIG(sii->osh, PCI_INT_MASK, sizeof(u32), w); + pci_write_config_dword(sii->osh->pdev, PCI_INT_MASK, w); } else { /* set sbintvec bit for our flag number */ si_setint(sih, siflag); @@ -1936,7 +1938,7 @@ bool si_deviceremoved(si_t *sih) switch (BUSTYPE(sih->bustype)) { case PCI_BUS: ASSERT(sii->osh != NULL); - w = OSL_PCI_READ_CONFIG(sii->osh, PCI_CFG_VID, sizeof(u32)); + pci_read_config_dword(sii->osh->pdev, PCI_CFG_VID, &w); if ((w & 0xFFFF) != VENDOR_BROADCOM) return true; break; -- cgit v1.2.3 From 7c8bc0147f54ecb43f48d9e898ad7f85cb934db7 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Tue, 23 Nov 2010 08:04:29 +0100 Subject: staging: brcm80211: add include file for using semaphore related definitions Source wl_iw.c uses semaphore definitions and as such should include . Signed-off-by: Arend van Spriel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmfmac/wl_iw.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/staging/brcm80211/brcmfmac/wl_iw.c b/drivers/staging/brcm80211/brcmfmac/wl_iw.c index d583b9d65d35..e714d6a9452b 100644 --- a/drivers/staging/brcm80211/brcmfmac/wl_iw.c +++ b/drivers/staging/brcm80211/brcmfmac/wl_iw.c @@ -15,6 +15,7 @@ */ #include +#include #include #include #include -- cgit v1.2.3 From b6eb5c0f71af22f7b44353a01241fff9a02997af Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Tue, 23 Nov 2010 14:06:22 +0100 Subject: staging: brcm80211: remove unneccessary packets funtion prototype The prototype for function pktsegcnt in bmcutils.h is not defined nor used anywhere in the driver so it can be removed. Reviewed-by: Brett Rudley Signed-off-by: Arend van Spriel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/include/bcmutils.h | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/staging/brcm80211/include/bcmutils.h b/drivers/staging/brcm80211/include/bcmutils.h index 4c1c111bac9b..632bceb480cb 100644 --- a/drivers/staging/brcm80211/include/bcmutils.h +++ b/drivers/staging/brcm80211/include/bcmutils.h @@ -149,10 +149,9 @@ /* externs */ /* packet */ - extern uint pktfrombuf(struct osl_info *osh, void *p, uint offset, - int len, unsigned char *buf); - extern uint pktsegcnt(struct osl_info *osh, void *p); - extern uint pkttotlen(struct osl_info *osh, void *p); + extern uint pktfrombuf(struct osl_info *osh, struct sk_buff *p, + uint offset, int len, unsigned char *buf); + extern uint pkttotlen(struct osl_info *osh, struct sk_buff *p); /* ethernet address */ extern int bcm_ether_atoe(char *p, struct ether_addr *ea); -- cgit v1.2.3 From c26b1378a71de617fb5ba7da8b6fdc882caed0e8 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Tue, 23 Nov 2010 14:06:23 +0100 Subject: staging: brcm80211: change packet buffer type to native struct sk_buff The packet queues now store struct sk_buff pointer and subsequently all driver code handling packets now use struct sk_buff as package storage type. Next step will be getting rid of packet macros. Reviewed-by: Brett Rudley Signed-off-by: Arend van Spriel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmfmac/bcmsdh.c | 2 +- drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c | 8 ++--- drivers/staging/brcm80211/brcmfmac/dhd.h | 10 +++--- drivers/staging/brcm80211/brcmfmac/dhd_bus.h | 2 +- drivers/staging/brcm80211/brcmfmac/dhd_cdc.c | 6 ++-- drivers/staging/brcm80211/brcmfmac/dhd_common.c | 5 +-- drivers/staging/brcm80211/brcmfmac/dhd_linux.c | 10 +++--- drivers/staging/brcm80211/brcmfmac/dhd_proto.h | 7 ++-- drivers/staging/brcm80211/brcmfmac/dhd_sdio.c | 39 ++++++++++++----------- drivers/staging/brcm80211/include/bcmsdbus.h | 2 +- drivers/staging/brcm80211/include/bcmsdh.h | 2 +- drivers/staging/brcm80211/include/bcmutils.h | 28 +++++++++------- drivers/staging/brcm80211/include/hnddma.h | 2 +- drivers/staging/brcm80211/sys/wl_mac80211.c | 7 ---- drivers/staging/brcm80211/sys/wlc_ampdu.c | 25 +++++++-------- drivers/staging/brcm80211/sys/wlc_ampdu.h | 8 ++--- drivers/staging/brcm80211/sys/wlc_bmac.c | 8 ++--- drivers/staging/brcm80211/sys/wlc_mac80211.c | 39 ++++++++++++----------- drivers/staging/brcm80211/sys/wlc_mac80211.h | 16 +++++----- drivers/staging/brcm80211/sys/wlc_pub.h | 7 ++++ drivers/staging/brcm80211/util/bcmutils.c | 33 ++++++++++--------- drivers/staging/brcm80211/util/hnddma.c | 17 +++++----- 22 files changed, 151 insertions(+), 132 deletions(-) diff --git a/drivers/staging/brcm80211/brcmfmac/bcmsdh.c b/drivers/staging/brcm80211/brcmfmac/bcmsdh.c index 6171ebf56ff1..acf43a365081 100644 --- a/drivers/staging/brcm80211/brcmfmac/bcmsdh.c +++ b/drivers/staging/brcm80211/brcmfmac/bcmsdh.c @@ -453,7 +453,7 @@ bool bcmsdh_regfail(void *sdh) int bcmsdh_recv_buf(void *sdh, u32 addr, uint fn, uint flags, - u8 *buf, uint nbytes, void *pkt, + u8 *buf, uint nbytes, struct sk_buff *pkt, bcmsdh_cmplt_fn_t complete, void *handle) { bcmsdh_info_t *bcmsdh = (bcmsdh_info_t *) sdh; diff --git a/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c b/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c index babda77d9326..3d3a428fa279 100644 --- a/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c +++ b/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c @@ -928,13 +928,13 @@ sdioh_request_word(sdioh_info_t *sd, uint cmd_type, uint rw, uint func, static SDIOH_API_RC sdioh_request_packet(sdioh_info_t *sd, uint fix_inc, uint write, uint func, - uint addr, void *pkt) + uint addr, struct sk_buff *pkt) { bool fifo = (fix_inc == SDIOH_DATA_FIX); u32 SGCount = 0; int err_ret = 0; - void *pnext; + struct sk_buff *pnext; sd_trace(("%s: Enter\n", __func__)); @@ -1026,10 +1026,10 @@ sdioh_request_packet(sdioh_info_t *sd, uint fix_inc, uint write, uint func, extern SDIOH_API_RC sdioh_request_buffer(sdioh_info_t *sd, uint pio_dma, uint fix_inc, uint write, uint func, uint addr, uint reg_width, uint buflen_u, - u8 *buffer, void *pkt) + u8 *buffer, struct sk_buff *pkt) { SDIOH_API_RC Status; - void *mypkt = NULL; + struct sk_buff *mypkt = NULL; sd_trace(("%s: Enter\n", __func__)); diff --git a/drivers/staging/brcm80211/brcmfmac/dhd.h b/drivers/staging/brcm80211/brcmfmac/dhd.h index 7785772ed917..69c6a0272812 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd.h +++ b/drivers/staging/brcm80211/brcmfmac/dhd.h @@ -295,10 +295,12 @@ extern void dhd_detach(dhd_pub_t *dhdp); /* Indication from bus module to change flow-control state */ extern void dhd_txflowcontrol(dhd_pub_t *dhdp, int ifidx, bool on); -extern bool dhd_prec_enq(dhd_pub_t *dhdp, struct pktq *q, void *pkt, int prec); +extern bool dhd_prec_enq(dhd_pub_t *dhdp, struct pktq *q, + struct sk_buff *pkt, int prec); /* Receive frame for delivery to OS. Callee disposes of rxp. */ -extern void dhd_rx_frame(dhd_pub_t *dhdp, int ifidx, void *rxp, int numpkt); +extern void dhd_rx_frame(dhd_pub_t *dhdp, int ifidx, + struct sk_buff *rxp, int numpkt); /* Return pointer to interface name */ extern char *dhd_ifname(dhd_pub_t *dhdp, int idx); @@ -307,7 +309,7 @@ extern char *dhd_ifname(dhd_pub_t *dhdp, int idx); extern void dhd_sched_dpc(dhd_pub_t *dhdp); /* Notify tx completion */ -extern void dhd_txcomplete(dhd_pub_t *dhdp, void *txp, bool success); +extern void dhd_txcomplete(dhd_pub_t *dhdp, struct sk_buff *txp, bool success); /* Query ioctl */ extern int dhdcdc_query_ioctl(dhd_pub_t *dhd, int ifidx, uint cmd, void *buf, @@ -378,7 +380,7 @@ extern void dhd_vif_sendup(struct dhd_info *dhd, int ifidx, unsigned char * cp, int len); /* Send packet to dongle via data channel */ -extern int dhd_sendpkt(dhd_pub_t *dhdp, int ifidx, void *pkt); +extern int dhd_sendpkt(dhd_pub_t *dhdp, int ifidx, struct sk_buff *pkt); /* Send event to host */ extern void dhd_sendup_event(dhd_pub_t *dhdp, wl_event_msg_t *event, diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_bus.h b/drivers/staging/brcm80211/brcmfmac/dhd_bus.h index 6629a229b4a1..cd0d5400bf07 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_bus.h +++ b/drivers/staging/brcm80211/brcmfmac/dhd_bus.h @@ -36,7 +36,7 @@ extern void dhd_bus_stop(struct dhd_bus *bus, bool enforce_mutex); extern int dhd_bus_init(dhd_pub_t *dhdp, bool enforce_mutex); /* Send a data frame to the dongle. Callee disposes of txp. */ -extern int dhd_bus_txdata(struct dhd_bus *bus, void *txp); +extern int dhd_bus_txdata(struct dhd_bus *bus, struct sk_buff *txp); /* Send/receive a control message to/from the dongle. * Expects caller to enforce a single outstanding transaction. diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_cdc.c b/drivers/staging/brcm80211/brcmfmac/dhd_cdc.c index 8e4e10794dce..c23d30b13147 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_cdc.c +++ b/drivers/staging/brcm80211/brcmfmac/dhd_cdc.c @@ -310,7 +310,7 @@ void dhd_prot_dump(dhd_pub_t *dhdp, struct bcmstrbuf *strbuf) bcm_bprintf(strbuf, "Protocol CDC: reqid %d\n", dhdp->prot->reqid); } -void dhd_prot_hdrpush(dhd_pub_t *dhd, int ifidx, void *pktbuf) +void dhd_prot_hdrpush(dhd_pub_t *dhd, int ifidx, struct sk_buff *pktbuf) { #ifdef BDC struct bdc_header *h; @@ -336,7 +336,7 @@ void dhd_prot_hdrpush(dhd_pub_t *dhd, int ifidx, void *pktbuf) BDC_SET_IF_IDX(h, ifidx); } -bool dhd_proto_fcinfo(dhd_pub_t *dhd, void *pktbuf, u8 * fcbits) +bool dhd_proto_fcinfo(dhd_pub_t *dhd, struct sk_buff *pktbuf, u8 * fcbits) { #ifdef BDC struct bdc_header *h; @@ -356,7 +356,7 @@ bool dhd_proto_fcinfo(dhd_pub_t *dhd, void *pktbuf, u8 * fcbits) return false; } -int dhd_prot_hdrpull(dhd_pub_t *dhd, int *ifidx, void *pktbuf) +int dhd_prot_hdrpull(dhd_pub_t *dhd, int *ifidx, struct sk_buff *pktbuf) { #ifdef BDC struct bdc_header *h; diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_common.c b/drivers/staging/brcm80211/brcmfmac/dhd_common.c index f7ffea69233c..e212abb8a357 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_common.c +++ b/drivers/staging/brcm80211/brcmfmac/dhd_common.c @@ -327,9 +327,10 @@ void dhd_store_conn_status(u32 event, u32 status, u32 reason) } } -bool dhd_prec_enq(dhd_pub_t *dhdp, struct pktq *q, void *pkt, int prec) +bool dhd_prec_enq(dhd_pub_t *dhdp, struct pktq *q, struct sk_buff *pkt, + int prec) { - void *p; + struct sk_buff *p; int eprec = -1; /* precedence to evict from */ bool discard_oldest; diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_linux.c b/drivers/staging/brcm80211/brcmfmac/dhd_linux.c index 27d4e02d3aab..ec887fb32faa 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_linux.c +++ b/drivers/staging/brcm80211/brcmfmac/dhd_linux.c @@ -1018,7 +1018,7 @@ static void dhd_set_multicast_list(struct net_device *dev) up(&dhd->sysioc_sem); } -int dhd_sendpkt(dhd_pub_t *dhdp, int ifidx, void *pktbuf) +int dhd_sendpkt(dhd_pub_t *dhdp, int ifidx, struct sk_buff *pktbuf) { int ret; dhd_info_t *dhd = (dhd_info_t *) (dhdp->info); @@ -1132,13 +1132,15 @@ void dhd_txflowcontrol(dhd_pub_t *dhdp, int ifidx, bool state) netif_wake_queue(net); } -void dhd_rx_frame(dhd_pub_t *dhdp, int ifidx, void *pktbuf, int numpkt) +void dhd_rx_frame(dhd_pub_t *dhdp, int ifidx, struct sk_buff *pktbuf, + int numpkt) { dhd_info_t *dhd = (dhd_info_t *) dhdp->info; struct sk_buff *skb; unsigned char *eth; uint len; - void *data, *pnext, *save_pktbuf; + void *data; + struct sk_buff *pnext, *save_pktbuf; int i; dhd_if_t *ifp; wl_event_msg_t event; @@ -1222,7 +1224,7 @@ void dhd_event(struct dhd_info *dhd, char *evpkt, int evlen, int ifidx) return; } -void dhd_txcomplete(dhd_pub_t *dhdp, void *txp, bool success) +void dhd_txcomplete(dhd_pub_t *dhdp, struct sk_buff *txp, bool success) { uint ifidx; dhd_info_t *dhd = (dhd_info_t *) (dhdp->info); diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_proto.h b/drivers/staging/brcm80211/brcmfmac/dhd_proto.h index cc42fa4a9140..a5309e27b65b 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_proto.h +++ b/drivers/staging/brcm80211/brcmfmac/dhd_proto.h @@ -46,15 +46,16 @@ extern int dhd_prot_init(dhd_pub_t *dhdp); /* Stop protocol: sync w/dongle state. */ extern void dhd_prot_stop(dhd_pub_t *dhdp); -extern bool dhd_proto_fcinfo(dhd_pub_t *dhd, void *pktbuf, u8 *fcbits); +extern bool dhd_proto_fcinfo(dhd_pub_t *dhd, struct sk_buff *pktbuf, + u8 *fcbits); /* Add any protocol-specific data header. * Caller must reserve prot_hdrlen prepend space. */ -extern void dhd_prot_hdrpush(dhd_pub_t *, int ifidx, void *txp); +extern void dhd_prot_hdrpush(dhd_pub_t *, int ifidx, struct sk_buff *txp); /* Remove any protocol-specific data header. */ -extern int dhd_prot_hdrpull(dhd_pub_t *, int *ifidx, void *rxp); +extern int dhd_prot_hdrpull(dhd_pub_t *, int *ifidx, struct sk_buff *rxp); /* Use protocol to issue ioctl to dongle */ extern int dhd_prot_ioctl(dhd_pub_t *dhd, int ifidx, wl_ioctl_t *ioc, diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c b/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c index d94b11a3271b..12bb7c602f1f 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c +++ b/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c @@ -203,8 +203,8 @@ typedef struct dhd_bus { u8 rx_seq; /* Receive sequence number (expected) */ bool rxskip; /* Skip receive (awaiting NAK ACK) */ - void *glomd; /* Packet containing glomming descriptor */ - void *glom; /* Packet chain for glommed superframe */ + struct sk_buff *glomd; /* Packet containing glomming descriptor */ + struct sk_buff *glom; /* Packet chain for glommed superframe */ uint glomerr; /* Glom packet read errors */ u8 *rxbuf; /* Buffer for receiving control packets */ @@ -446,11 +446,13 @@ static uint process_nvram_vars(char *varbuf, uint len); static void dhd_dongle_setmemsize(struct dhd_bus *bus, int mem_size); static int dhd_bcmsdh_recv_buf(dhd_bus_t *bus, u32 addr, uint fn, - uint flags, u8 *buf, uint nbytes, void *pkt, - bcmsdh_cmplt_fn_t complete, void *handle); + uint flags, u8 *buf, uint nbytes, + struct sk_buff *pkt, bcmsdh_cmplt_fn_t complete, + void *handle); static int dhd_bcmsdh_send_buf(dhd_bus_t *bus, u32 addr, uint fn, - uint flags, u8 *buf, uint nbytes, void *pkt, - bcmsdh_cmplt_fn_t complete, void *handle); + uint flags, u8 *buf, uint nbytes, + struct sk_buff *pkt, bcmsdh_cmplt_fn_t complete, + void *handle); static bool dhdsdio_download_firmware(struct dhd_bus *bus, struct osl_info *osh, void *sdh); @@ -902,7 +904,8 @@ void dhd_enable_oob_intr(struct dhd_bus *bus, bool enable) /* Writes a HW/SW header into the packet and sends it. */ /* Assumes: (a) header space already there, (b) caller holds lock */ -static int dhdsdio_txpkt(dhd_bus_t *bus, void *pkt, uint chan, bool free_pkt) +static int dhdsdio_txpkt(dhd_bus_t *bus, struct sk_buff *pkt, uint chan, + bool free_pkt) { int ret; struct osl_info *osh; @@ -911,7 +914,7 @@ static int dhdsdio_txpkt(dhd_bus_t *bus, void *pkt, uint chan, bool free_pkt) u32 swheader; uint retries = 0; bcmsdh_info_t *sdh; - void *new; + struct sk_buff *new; int i; DHD_TRACE(("%s: Enter\n", __func__)); @@ -1063,7 +1066,7 @@ done: return ret; } -int dhd_bus_txdata(struct dhd_bus *bus, void *pkt) +int dhd_bus_txdata(struct dhd_bus *bus, struct sk_buff *pkt) { int ret = BCME_ERROR; struct osl_info *osh; @@ -1164,7 +1167,7 @@ int dhd_bus_txdata(struct dhd_bus *bus, void *pkt) static uint dhdsdio_sendfromq(dhd_bus_t *bus, uint maxframes) { - void *pkt; + struct sk_buff *pkt; u32 intstatus = 0; uint retries = 0; int ret = 0, prec_out; @@ -3180,7 +3183,7 @@ static u8 dhdsdio_rxglom(dhd_bus_t *bus, u8 rxseq) u8 *dptr, num = 0; u16 sublen, check; - void *pfirst, *plast, *pnext, *save_pfirst; + struct sk_buff *pfirst, *plast, *pnext, *save_pfirst; struct osl_info *osh = bus->dhd->osh; int errcode; @@ -3590,7 +3593,7 @@ static uint dhdsdio_readframes(dhd_bus_t *bus, uint maxframes, bool *finished) u8 fcbits; /* Extracted fcbits from software header */ u8 delta; - void *pkt; /* Packet for event or data frames */ + struct sk_buff *pkt; /* Packet for event or data frames */ u16 pad; /* Number of pad bytes to read */ u16 rdlen; /* Total number of bytes to read */ u8 rxseq; /* Next sequence number to expect */ @@ -4628,7 +4631,7 @@ static void dhdsdio_pktgen_init(dhd_bus_t *bus) static void dhdsdio_pktgen(dhd_bus_t *bus) { - void *pkt; + struct sk_buff *pkt; u8 *data; uint pktcount; uint fillbyte; @@ -4735,7 +4738,7 @@ static void dhdsdio_pktgen(dhd_bus_t *bus) static void dhdsdio_sdtest_set(dhd_bus_t *bus, bool start) { - void *pkt; + struct sk_buff *pkt; u8 *data; struct osl_info *osh = bus->dhd->osh; @@ -4760,7 +4763,7 @@ static void dhdsdio_sdtest_set(dhd_bus_t *bus, bool start) bus->pktgen_fail++; } -static void dhdsdio_testrcv(dhd_bus_t *bus, void *pkt, uint seq) +static void dhdsdio_testrcv(dhd_bus_t *bus, struct sk_buff *pkt, uint seq) { struct osl_info *osh = bus->dhd->osh; u8 *data; @@ -4962,7 +4965,7 @@ extern int dhd_bus_console_in(dhd_pub_t *dhdp, unsigned char *msg, uint msglen) dhd_bus_t *bus = dhdp->bus; u32 addr, val; int rv; - void *pkt; + struct sk_buff *pkt; /* Address could be zero if CONSOLE := 0 in dongle Makefile */ if (bus->console_addr == 0) @@ -5989,7 +5992,7 @@ err: static int dhd_bcmsdh_recv_buf(dhd_bus_t *bus, u32 addr, uint fn, uint flags, - u8 *buf, uint nbytes, void *pkt, + u8 *buf, uint nbytes, struct sk_buff *pkt, bcmsdh_cmplt_fn_t complete, void *handle) { int status; @@ -6003,7 +6006,7 @@ dhd_bcmsdh_recv_buf(dhd_bus_t *bus, u32 addr, uint fn, uint flags, static int dhd_bcmsdh_send_buf(dhd_bus_t *bus, u32 addr, uint fn, uint flags, - u8 *buf, uint nbytes, void *pkt, + u8 *buf, uint nbytes, struct sk_buff *pkt, bcmsdh_cmplt_fn_t complete, void *handle) { return bcmsdh_send_buf diff --git a/drivers/staging/brcm80211/include/bcmsdbus.h b/drivers/staging/brcm80211/include/bcmsdbus.h index 4f040e41ae50..89059dd8088b 100644 --- a/drivers/staging/brcm80211/include/bcmsdbus.h +++ b/drivers/staging/brcm80211/include/bcmsdbus.h @@ -79,7 +79,7 @@ extern SDIOH_API_RC sdioh_request_buffer(sdioh_info_t *si, uint pio_dma, uint fix_inc, uint rw, uint fnc_num, u32 addr, uint regwidth, u32 buflen, u8 *buffer, - void *pkt); + struct sk_buff *pkt); /* get cis data */ extern SDIOH_API_RC sdioh_cis_read(sdioh_info_t *si, uint fuc, u8 *cis, diff --git a/drivers/staging/brcm80211/include/bcmsdh.h b/drivers/staging/brcm80211/include/bcmsdh.h index 69aa061bb524..0e1f79919c9c 100644 --- a/drivers/staging/brcm80211/include/bcmsdh.h +++ b/drivers/staging/brcm80211/include/bcmsdh.h @@ -122,7 +122,7 @@ extern int bcmsdh_send_buf(void *sdh, u32 addr, uint fn, uint flags, u8 *buf, uint nbytes, void *pkt, bcmsdh_cmplt_fn_t complete, void *handle); extern int bcmsdh_recv_buf(void *sdh, u32 addr, uint fn, uint flags, - u8 *buf, uint nbytes, void *pkt, + u8 *buf, uint nbytes, struct sk_buff *pkt, bcmsdh_cmplt_fn_t complete, void *handle); /* Flags bits */ diff --git a/drivers/staging/brcm80211/include/bcmutils.h b/drivers/staging/brcm80211/include/bcmutils.h index 632bceb480cb..e673dfd21622 100644 --- a/drivers/staging/brcm80211/include/bcmutils.h +++ b/drivers/staging/brcm80211/include/bcmutils.h @@ -55,10 +55,10 @@ #endif typedef struct pktq_prec { - void *head; /* first packet to dequeue */ - void *tail; /* last packet to dequeue */ - u16 len; /* number of queued packets */ - u16 max; /* maximum number of queued packets */ + struct sk_buff *head; /* first packet to dequeue */ + struct sk_buff *tail; /* last packet to dequeue */ + u16 len; /* number of queued packets */ + u16 max; /* maximum number of queued packets */ } pktq_prec_t; /* multi-priority pkt queue */ @@ -104,10 +104,13 @@ #define pktq_ppeek(pq, prec) ((pq)->q[prec].head) #define pktq_ppeek_tail(pq, prec) ((pq)->q[prec].tail) - extern void *pktq_penq(struct pktq *pq, int prec, void *p); - extern void *pktq_penq_head(struct pktq *pq, int prec, void *p); - extern void *pktq_pdeq(struct pktq *pq, int prec); - extern void *pktq_pdeq_tail(struct pktq *pq, int prec); +extern struct sk_buff *pktq_penq(struct pktq *pq, int prec, + struct sk_buff *p); +extern struct sk_buff *pktq_penq_head(struct pktq *pq, int prec, + struct sk_buff *p); +extern struct sk_buff *pktq_pdeq(struct pktq *pq, int prec); +extern struct sk_buff *pktq_pdeq_tail(struct pktq *pq, int prec); + /* Empty the queue at particular precedence level */ #ifdef BRCM_FULLMAC extern void pktq_pflush(struct osl_info *osh, struct pktq *pq, int prec, @@ -119,8 +122,8 @@ /* operations on a set of precedences in packet queue */ - extern int pktq_mlen(struct pktq *pq, uint prec_bmp); - extern void *pktq_mdeq(struct pktq *pq, uint prec_bmp, int *prec_out); +extern int pktq_mlen(struct pktq *pq, uint prec_bmp); +extern struct sk_buff *pktq_mdeq(struct pktq *pq, uint prec_bmp, int *prec_out); /* operations on packet queue as a whole */ @@ -139,7 +142,7 @@ extern void pktq_init(struct pktq *pq, int num_prec, int max_len); /* prec_out may be NULL if caller is not interested in return value */ - extern void *pktq_peek_tail(struct pktq *pq, int *prec_out); + extern struct sk_buff *pktq_peek_tail(struct pktq *pq, int *prec_out); #ifdef BRCM_FULLMAC extern void pktq_flush(struct osl_info *osh, struct pktq *pq, bool dir); #else @@ -164,7 +167,8 @@ extern char *getvar(char *vars, const char *name); extern int getintvar(char *vars, const char *name); #ifdef BCMDBG - extern void prpkt(const char *msg, struct osl_info *osh, void *p0); + extern void prpkt(const char *msg, struct osl_info *osh, + struct sk_buff *p0); #endif /* BCMDBG */ #define bcm_perf_enable() #define bcmstats(fmt) diff --git a/drivers/staging/brcm80211/include/hnddma.h b/drivers/staging/brcm80211/include/hnddma.h index 854a3996baa8..05dd9ba19858 100644 --- a/drivers/staging/brcm80211/include/hnddma.h +++ b/drivers/staging/brcm80211/include/hnddma.h @@ -41,7 +41,7 @@ typedef void (*di_txsuspend_t) (hnddma_t *dmah); typedef void (*di_txresume_t) (hnddma_t *dmah); typedef bool(*di_txsuspended_t) (hnddma_t *dmah); typedef bool(*di_txsuspendedidle_t) (hnddma_t *dmah); -typedef int (*di_txfast_t) (hnddma_t *dmah, void *p, bool commit); +typedef int (*di_txfast_t) (hnddma_t *dmah, struct sk_buff *p, bool commit); typedef int (*di_txunframed_t) (hnddma_t *dmah, void *p, uint len, bool commit); typedef void *(*di_getpos_t) (hnddma_t *di, bool direction); diff --git a/drivers/staging/brcm80211/sys/wl_mac80211.c b/drivers/staging/brcm80211/sys/wl_mac80211.c index 6c162b9f864a..76f611d3c3ad 100644 --- a/drivers/staging/brcm80211/sys/wl_mac80211.c +++ b/drivers/staging/brcm80211/sys/wl_mac80211.c @@ -48,13 +48,6 @@ #include -extern void wlc_wme_setparams(wlc_info_t *wlc, u16 aci, void *arg, - bool suspend); -bool wlc_sendpkt_mac80211(wlc_info_t *wlc, void *sdu, struct ieee80211_hw *hw); -void wlc_mac_bcn_promisc_change(wlc_info_t *wlc, bool promisc); -void wlc_set_addrmatch(wlc_info_t *wlc, int match_reg_offset, - const struct ether_addr *addr); - static void wl_timer(unsigned long data); static void _wl_timer(wl_timer_t *t); diff --git a/drivers/staging/brcm80211/sys/wlc_ampdu.c b/drivers/staging/brcm80211/sys/wlc_ampdu.c index 1fa56cefeed9..f2acda77d47b 100644 --- a/drivers/staging/brcm80211/sys/wlc_ampdu.c +++ b/drivers/staging/brcm80211/sys/wlc_ampdu.c @@ -146,11 +146,10 @@ static void scb_ampdu_update_config_all(ampdu_info_t *ampdu); #define wlc_ampdu_txflowcontrol(a, b, c) do {} while (0) static void wlc_ampdu_dotxstatus_complete(ampdu_info_t *ampdu, struct scb *scb, - void *p, tx_status_t *txs, - u32 frmtxstatus, - u32 frmtxstatus2); + struct sk_buff *p, tx_status_t *txs, + u32 frmtxstatus, u32 frmtxstatus2); -static inline u16 pkt_txh_seqnum(wlc_info_t *wlc, void *p) +static inline u16 pkt_txh_seqnum(wlc_info_t *wlc, struct sk_buff *p) { d11txh_t *txh; struct dot11_header *h; @@ -471,7 +470,8 @@ static void wlc_ffpld_calc_mcs2ampdu_table(ampdu_info_t *ampdu, int f) } static void BCMFASTPATH -wlc_ampdu_agg(ampdu_info_t *ampdu, struct scb *scb, void *p, uint prec) +wlc_ampdu_agg(ampdu_info_t *ampdu, struct scb *scb, struct sk_buff *p, + uint prec) { scb_ampdu_t *scb_ampdu; scb_ampdu_tid_ini_t *ini; @@ -488,11 +488,12 @@ wlc_ampdu_agg(ampdu_info_t *ampdu, struct scb *scb, void *p, uint prec) } int BCMFASTPATH -wlc_sendampdu(ampdu_info_t *ampdu, wlc_txq_info_t *qi, void **pdu, int prec) +wlc_sendampdu(ampdu_info_t *ampdu, wlc_txq_info_t *qi, struct sk_buff **pdu, + int prec) { wlc_info_t *wlc; struct osl_info *osh; - void *p, *pkt[AMPDU_MAX_MPDU]; + struct sk_buff *p, *pkt[AMPDU_MAX_MPDU]; u8 tid, ndelim; int err = 0; u8 preamble_type = WLC_GF_PREAMBLE; @@ -884,7 +885,7 @@ wlc_sendampdu(ampdu_info_t *ampdu, wlc_txq_info_t *qi, void **pdu, int prec) } void BCMFASTPATH -wlc_ampdu_dotxstatus(ampdu_info_t *ampdu, struct scb *scb, void *p, +wlc_ampdu_dotxstatus(ampdu_info_t *ampdu, struct scb *scb, struct sk_buff *p, tx_status_t *txs) { scb_ampdu_t *scb_ampdu; @@ -948,14 +949,12 @@ rate_status(wlc_info_t *wlc, struct ieee80211_tx_info *tx_info, } } -extern void wlc_txq_enq(wlc_info_t *wlc, struct scb *scb, void *sdu, - uint prec); - #define SHORTNAME "AMPDU status" static void BCMFASTPATH -wlc_ampdu_dotxstatus_complete(ampdu_info_t *ampdu, struct scb *scb, void *p, - tx_status_t *txs, u32 s1, u32 s2) +wlc_ampdu_dotxstatus_complete(ampdu_info_t *ampdu, struct scb *scb, + struct sk_buff *p, tx_status_t *txs, + u32 s1, u32 s2) { scb_ampdu_t *scb_ampdu; wlc_info_t *wlc = ampdu->wlc; diff --git a/drivers/staging/brcm80211/sys/wlc_ampdu.h b/drivers/staging/brcm80211/sys/wlc_ampdu.h index 939cae0d7b4f..c86411beac11 100644 --- a/drivers/staging/brcm80211/sys/wlc_ampdu.h +++ b/drivers/staging/brcm80211/sys/wlc_ampdu.h @@ -21,10 +21,10 @@ extern ampdu_info_t *wlc_ampdu_attach(wlc_info_t *wlc); extern void wlc_ampdu_detach(ampdu_info_t *ampdu); extern bool wlc_ampdu_cap(ampdu_info_t *ampdu); extern int wlc_ampdu_set(ampdu_info_t *ampdu, bool on); -extern int wlc_sendampdu(ampdu_info_t *ampdu, wlc_txq_info_t *qi, void **aggp, - int prec); -extern void wlc_ampdu_dotxstatus(ampdu_info_t *ampdu, struct scb *scb, void *p, - tx_status_t *txs); +extern int wlc_sendampdu(ampdu_info_t *ampdu, wlc_txq_info_t *qi, + struct sk_buff **aggp, int prec); +extern void wlc_ampdu_dotxstatus(ampdu_info_t *ampdu, struct scb *scb, + struct sk_buff *p, tx_status_t *txs); extern void wlc_ampdu_reset(ampdu_info_t *ampdu); extern void wlc_ampdu_macaddr_upd(wlc_info_t *wlc); extern void wlc_ampdu_shm_upd(ampdu_info_t *ampdu); diff --git a/drivers/staging/brcm80211/sys/wlc_bmac.c b/drivers/staging/brcm80211/sys/wlc_bmac.c index 4b2708620049..2a2ad494746d 100644 --- a/drivers/staging/brcm80211/sys/wlc_bmac.c +++ b/drivers/staging/brcm80211/sys/wlc_bmac.c @@ -270,9 +270,9 @@ static u32 WLBANDINITFN(wlc_setband_inact) (wlc_info_t *wlc, uint bandunit) static bool BCMFASTPATH wlc_bmac_recv(wlc_hw_info_t *wlc_hw, uint fifo, bool bound) { - void *p; - void *head = NULL; - void *tail = NULL; + struct sk_buff *p; + struct sk_buff *head = NULL; + struct sk_buff *tail = NULL; uint n = 0; uint bound_limit = bound ? wlc_hw->wlc->pub->tunables->rxbnd : -1; u32 tsf_h, tsf_l; @@ -3316,7 +3316,7 @@ bool BCMFASTPATH wlc_isr(wlc_info_t *wlc, bool *wantdpc) /* process tx completion events for corerev < 5 */ static bool wlc_bmac_txstatus_corerev4(wlc_hw_info_t *wlc_hw) { - void *status_p; + struct sk_buff *status_p; tx_status_t *txs; struct osl_info *osh; bool fatal = false; diff --git a/drivers/staging/brcm80211/sys/wlc_mac80211.c b/drivers/staging/brcm80211/sys/wlc_mac80211.c index 37a87d8f23c8..d99fcb524d54 100644 --- a/drivers/staging/brcm80211/sys/wlc_mac80211.c +++ b/drivers/staging/brcm80211/sys/wlc_mac80211.c @@ -221,16 +221,15 @@ static const u8 acbitmap2maxprio[] = { #define WLC_REPLAY_CNTRS_VALUE WPA_CAP_16_REPLAY_CNTRS /* local prototypes */ -extern void wlc_txq_enq(void *ctx, struct scb *scb, void *sdu, uint prec); static u16 BCMFASTPATH wlc_d11hdrs_mac80211(wlc_info_t *wlc, - struct ieee80211_hw *hw, void *p, + struct ieee80211_hw *hw, + struct sk_buff *p, struct scb *scb, uint frag, uint nfrags, uint queue, uint next_frag_len, wsec_key_t *key, ratespec_t rspec_override); -bool wlc_sendpkt_mac80211(wlc_info_t *wlc, void *sdu, struct ieee80211_hw *hw); -void wlc_wme_setparams(wlc_info_t *wlc, u16 aci, void *arg, bool suspend); + static void wlc_bss_default_init(wlc_info_t *wlc); static void wlc_ucode_mac_upd(wlc_info_t *wlc); static ratespec_t mac80211_wlc_set_nrate(wlc_info_t *wlc, wlcband_t *cur_band, @@ -258,7 +257,7 @@ static void wlc_compute_mimo_plcp(ratespec_t rate, uint length, u8 *plcp); static u16 wlc_compute_frame_dur(wlc_info_t *wlc, ratespec_t rate, u8 preamble_type, uint next_frag_len); static void wlc_recvctl(wlc_info_t *wlc, struct osl_info *osh, d11rxhdr_t *rxh, - void *p); + struct sk_buff *p); static uint wlc_calc_frame_len(wlc_info_t *wlc, ratespec_t rate, u8 preamble_type, uint dur); static uint wlc_calc_ack_time(wlc_info_t *wlc, ratespec_t rate, @@ -5000,10 +4999,10 @@ wlc_prec_enq(wlc_info_t *wlc, struct pktq *q, void *pkt, int prec) } bool BCMFASTPATH -wlc_prec_enq_head(wlc_info_t *wlc, struct pktq *q, void *pkt, int prec, - bool head) +wlc_prec_enq_head(wlc_info_t *wlc, struct pktq *q, struct sk_buff *pkt, + int prec, bool head) { - void *p; + struct sk_buff *p; int eprec = -1; /* precedence to evict from */ /* Determine precedence from which to evict packet, if any */ @@ -5064,7 +5063,8 @@ wlc_prec_enq_head(wlc_info_t *wlc, struct pktq *q, void *pkt, int prec, return true; } -void BCMFASTPATH wlc_txq_enq(void *ctx, struct scb *scb, void *sdu, uint prec) +void BCMFASTPATH wlc_txq_enq(void *ctx, struct scb *scb, struct sk_buff *sdu, + uint prec) { wlc_info_t *wlc = (wlc_info_t *) ctx; wlc_txq_info_t *qi = wlc->active_queue; /* Check me */ @@ -5104,7 +5104,8 @@ void BCMFASTPATH wlc_txq_enq(void *ctx, struct scb *scb, void *sdu, uint prec) } bool BCMFASTPATH -wlc_sendpkt_mac80211(wlc_info_t *wlc, void *sdu, struct ieee80211_hw *hw) +wlc_sendpkt_mac80211(wlc_info_t *wlc, struct sk_buff *sdu, + struct ieee80211_hw *hw) { u8 prio; uint fifo; @@ -5141,7 +5142,7 @@ wlc_sendpkt_mac80211(wlc_info_t *wlc, void *sdu, struct ieee80211_hw *hw) void BCMFASTPATH wlc_send_q(wlc_info_t *wlc, wlc_txq_info_t *qi) { - void *pkt[DOT11_MAXNUMFRAGS]; + struct sk_buff *pkt[DOT11_MAXNUMFRAGS]; int prec; u16 prec_map; int err = 0, i, count; @@ -5228,7 +5229,8 @@ bcmc_fid_generate(wlc_info_t *wlc, wlc_bsscfg_t *bsscfg, d11txh_t *txh) } void BCMFASTPATH -wlc_txfifo(wlc_info_t *wlc, uint fifo, void *p, bool commit, s8 txpktpend) +wlc_txfifo(wlc_info_t *wlc, uint fifo, struct sk_buff *p, bool commit, + s8 txpktpend) { u16 frameid = INVALIDFID; d11txh_t *txh; @@ -5641,7 +5643,7 @@ wlc_rspec_to_rts_rspec(wlc_info_t *wlc, ratespec_t rspec, bool use_rspec, */ static u16 BCMFASTPATH wlc_d11hdrs_mac80211(wlc_info_t *wlc, struct ieee80211_hw *hw, - void *p, struct scb *scb, uint frag, + struct sk_buff *p, struct scb *scb, uint frag, uint nfrags, uint queue, uint next_frag_len, wsec_key_t *key, ratespec_t rspec_override) { @@ -6507,7 +6509,7 @@ static void wlc_war16165(wlc_info_t *wlc, bool tx) bool BCMFASTPATH wlc_dotxstatus(wlc_info_t *wlc, tx_status_t *txs, u32 frm_tx2) { - void *p; + struct sk_buff *p; uint queue; d11txh_t *txh; struct scb *scb = NULL; @@ -6790,7 +6792,7 @@ void wlc_bcn_li_upd(wlc_info_t *wlc) } static void -prep_mac80211_status(wlc_info_t *wlc, d11rxhdr_t *rxh, void *p, +prep_mac80211_status(wlc_info_t *wlc, d11rxhdr_t *rxh, struct sk_buff *p, struct ieee80211_rx_status *rx_status) { u32 tsf_l, tsf_h; @@ -6900,7 +6902,8 @@ prep_mac80211_status(wlc_info_t *wlc, d11rxhdr_t *rxh, void *p, } static void -wlc_recvctl(wlc_info_t *wlc, struct osl_info *osh, d11rxhdr_t *rxh, void *p) +wlc_recvctl(wlc_info_t *wlc, struct osl_info *osh, d11rxhdr_t *rxh, + struct sk_buff *p) { int len_mpdu; struct ieee80211_rx_status rx_status; @@ -6963,7 +6966,7 @@ void wlc_bss_list_free(wlc_info_t *wlc, wlc_bss_list_t *bss_list) * Param 'bound' indicates max. # frames to process before break out. */ /* WLC_HIGH_API */ -void BCMFASTPATH wlc_recv(wlc_info_t *wlc, void *p) +void BCMFASTPATH wlc_recv(wlc_info_t *wlc, struct sk_buff *p) { d11rxhdr_t *rxh; struct dot11_header *h; @@ -7789,7 +7792,7 @@ wlc_bss_update_probe_resp(wlc_info_t *wlc, wlc_bsscfg_t *cfg, bool suspend) } /* prepares pdu for transmission. returns BCM error codes */ -int wlc_prep_pdu(wlc_info_t *wlc, void *pdu, uint *fifop) +int wlc_prep_pdu(wlc_info_t *wlc, struct sk_buff *pdu, uint *fifop) { struct osl_info *osh; uint fifo; diff --git a/drivers/staging/brcm80211/sys/wlc_mac80211.h b/drivers/staging/brcm80211/sys/wlc_mac80211.h index 006880049f37..72a9236d8d86 100644 --- a/drivers/staging/brcm80211/sys/wlc_mac80211.h +++ b/drivers/staging/brcm80211/sys/wlc_mac80211.h @@ -818,11 +818,13 @@ struct antsel_info { extern void wlc_high_dpc(wlc_info_t *wlc, u32 macintstatus); extern void wlc_fatal_error(wlc_info_t *wlc); extern void wlc_bmac_rpc_watchdog(wlc_info_t *wlc); -extern void wlc_recv(wlc_info_t *wlc, void *p); +extern void wlc_recv(wlc_info_t *wlc, struct sk_buff *p); extern bool wlc_dotxstatus(wlc_info_t *wlc, tx_status_t *txs, u32 frm_tx2); -extern void wlc_txfifo(wlc_info_t *wlc, uint fifo, void *p, bool commit, - s8 txpktpend); +extern void wlc_txfifo(wlc_info_t *wlc, uint fifo, struct sk_buff *p, + bool commit, s8 txpktpend); extern void wlc_txfifo_complete(wlc_info_t *wlc, uint fifo, s8 txpktpend); +extern void wlc_txq_enq(void *ctx, struct scb *scb, struct sk_buff *sdu, + uint prec); extern void wlc_info_init(wlc_info_t *wlc, int unit); extern void wlc_print_txstatus(tx_status_t *txs); extern int wlc_xmtfifo_sz_get(wlc_info_t *wlc, uint fifo, uint *blocks); @@ -879,7 +881,7 @@ extern void wlc_txflowcontrol_override(wlc_info_t *wlc, wlc_txq_info_t *qi, extern bool wlc_txflowcontrol_prio_isset(wlc_info_t *wlc, wlc_txq_info_t *qi, int prio); extern void wlc_send_q(wlc_info_t *wlc, wlc_txq_info_t *qi); -extern int wlc_prep_pdu(wlc_info_t *wlc, void *pdu, uint *fifo); +extern int wlc_prep_pdu(wlc_info_t *wlc, struct sk_buff *pdu, uint *fifo); extern u16 wlc_calc_lsig_len(wlc_info_t *wlc, ratespec_t ratespec, uint mac_len); @@ -923,8 +925,8 @@ extern bool wlc_ismpc(wlc_info_t *wlc); extern bool wlc_is_non_delay_mpc(wlc_info_t *wlc); extern void wlc_radio_mpc_upd(wlc_info_t *wlc); extern bool wlc_prec_enq(wlc_info_t *wlc, struct pktq *q, void *pkt, int prec); -extern bool wlc_prec_enq_head(wlc_info_t *wlc, struct pktq *q, void *pkt, - int prec, bool head); +extern bool wlc_prec_enq_head(wlc_info_t *wlc, struct pktq *q, + struct sk_buff *pkt, int prec, bool head); extern u16 wlc_phytxctl1_calc(wlc_info_t *wlc, ratespec_t rspec); extern void wlc_compute_plcp(wlc_info_t *wlc, ratespec_t rate, uint length, u8 *plcp); @@ -953,8 +955,6 @@ extern void wlc_mimops_action_ht_send(wlc_info_t *wlc, wlc_bsscfg_t *bsscfg, extern void wlc_switch_shortslot(wlc_info_t *wlc, bool shortslot); extern void wlc_set_bssid(wlc_bsscfg_t *cfg); extern void wlc_edcf_setparams(wlc_bsscfg_t *cfg, bool suspend); -extern void wlc_wme_setparams(wlc_info_t *wlc, u16 aci, void *arg, - bool suspend); extern void wlc_set_ratetable(wlc_info_t *wlc); extern int wlc_set_mac(wlc_bsscfg_t *cfg); diff --git a/drivers/staging/brcm80211/sys/wlc_pub.h b/drivers/staging/brcm80211/sys/wlc_pub.h index 4b1ab1d1c2ce..b3ad4c0233ab 100644 --- a/drivers/staging/brcm80211/sys/wlc_pub.h +++ b/drivers/staging/brcm80211/sys/wlc_pub.h @@ -512,6 +512,8 @@ extern bool wlc_isr(struct wlc_info *wlc, bool *wantdpc); extern bool wlc_dpc(struct wlc_info *wlc, bool bounded); extern bool wlc_send80211_raw(struct wlc_info *wlc, wlc_if_t *wlcif, void *p, uint ac); +extern bool wlc_sendpkt_mac80211(wlc_info_t *wlc, struct sk_buff *sdu, + struct ieee80211_hw *hw); extern int wlc_iovar_op(struct wlc_info *wlc, const char *name, void *params, int p_len, void *arg, int len, bool set, struct wlc_if *wlcif); @@ -520,6 +522,11 @@ extern int wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, /* helper functions */ extern void wlc_statsupd(struct wlc_info *wlc); extern int wlc_get_header_len(void); +extern void wlc_mac_bcn_promisc_change(wlc_info_t *wlc, bool promisc); +extern void wlc_set_addrmatch(wlc_info_t *wlc, int match_reg_offset, + const struct ether_addr *addr); +extern void wlc_wme_setparams(wlc_info_t *wlc, u16 aci, void *arg, + bool suspend); extern wlc_pub_t *wlc_pub(void *wlc); diff --git a/drivers/staging/brcm80211/util/bcmutils.c b/drivers/staging/brcm80211/util/bcmutils.c index 83f96cdfe771..701ea0170933 100644 --- a/drivers/staging/brcm80211/util/bcmutils.c +++ b/drivers/staging/brcm80211/util/bcmutils.c @@ -33,7 +33,7 @@ #include /* copy a buffer into a pkt buffer chain */ -uint pktfrombuf(struct osl_info *osh, void *p, uint offset, int len, +uint pktfrombuf(struct osl_info *osh, struct sk_buff *p, uint offset, int len, unsigned char *buf) { uint n, ret = 0; @@ -61,7 +61,7 @@ uint pktfrombuf(struct osl_info *osh, void *p, uint offset, int len, return ret; } /* return total length of buffer chain */ -uint BCMFASTPATH pkttotlen(struct osl_info *osh, void *p) +uint BCMFASTPATH pkttotlen(struct osl_info *osh, struct sk_buff *p) { uint total; @@ -75,7 +75,8 @@ uint BCMFASTPATH pkttotlen(struct osl_info *osh, void *p) * osl multiple-precedence packet queue * hi_prec is always >= the number of the highest non-empty precedence */ -void *BCMFASTPATH pktq_penq(struct pktq *pq, int prec, void *p) +struct sk_buff *BCMFASTPATH pktq_penq(struct pktq *pq, int prec, + struct sk_buff *p) { struct pktq_prec *q; @@ -103,7 +104,8 @@ void *BCMFASTPATH pktq_penq(struct pktq *pq, int prec, void *p) return p; } -void *BCMFASTPATH pktq_penq_head(struct pktq *pq, int prec, void *p) +struct sk_buff *BCMFASTPATH pktq_penq_head(struct pktq *pq, int prec, + struct sk_buff *p) { struct pktq_prec *q; @@ -130,10 +132,10 @@ void *BCMFASTPATH pktq_penq_head(struct pktq *pq, int prec, void *p) return p; } -void *BCMFASTPATH pktq_pdeq(struct pktq *pq, int prec) +struct sk_buff *BCMFASTPATH pktq_pdeq(struct pktq *pq, int prec) { struct pktq_prec *q; - void *p; + struct sk_buff *p; ASSERT(prec >= 0 && prec < pq->num_prec); @@ -156,10 +158,10 @@ void *BCMFASTPATH pktq_pdeq(struct pktq *pq, int prec) return p; } -void *BCMFASTPATH pktq_pdeq_tail(struct pktq *pq, int prec) +struct sk_buff *BCMFASTPATH pktq_pdeq_tail(struct pktq *pq, int prec) { struct pktq_prec *q; - void *p, *prev; + struct sk_buff *p, *prev; ASSERT(prec >= 0 && prec < pq->num_prec); @@ -189,7 +191,7 @@ void *BCMFASTPATH pktq_pdeq_tail(struct pktq *pq, int prec) void pktq_pflush(struct osl_info *osh, struct pktq *pq, int prec, bool dir) { struct pktq_prec *q; - void *p; + struct sk_buff *p; q = &pq->q[prec]; p = q->head; @@ -218,7 +220,7 @@ pktq_pflush(struct osl_info *osh, struct pktq *pq, int prec, bool dir, ifpkt_cb_t fn, int arg) { struct pktq_prec *q; - void *p, *prev = NULL; + struct sk_buff *p, *prev = NULL; q = &pq->q[prec]; p = q->head; @@ -275,7 +277,7 @@ void pktq_init(struct pktq *pq, int num_prec, int max_len) pq->q[prec].max = pq->max; } -void *pktq_peek_tail(struct pktq *pq, int *prec_out) +struct sk_buff *pktq_peek_tail(struct pktq *pq, int *prec_out) { int prec; @@ -306,10 +308,11 @@ int pktq_mlen(struct pktq *pq, uint prec_bmp) return len; } /* Priority dequeue from a specific set of precedences */ -void *BCMFASTPATH pktq_mdeq(struct pktq *pq, uint prec_bmp, int *prec_out) +struct sk_buff *BCMFASTPATH pktq_mdeq(struct pktq *pq, uint prec_bmp, + int *prec_out) { struct pktq_prec *q; - void *p; + struct sk_buff *p; int prec; if (pq->len == 0) @@ -407,9 +410,9 @@ int getintvar(char *vars, const char *name) #if defined(BCMDBG) /* pretty hex print a pkt buffer chain */ -void prpkt(const char *msg, struct osl_info *osh, void *p0) +void prpkt(const char *msg, struct osl_info *osh, struct sk_buff *p0) { - void *p; + struct sk_buff *p; if (msg && (msg[0] != '\0')) printf("%s:\n", msg); diff --git a/drivers/staging/brcm80211/util/hnddma.c b/drivers/staging/brcm80211/util/hnddma.c index f1e9cfcca991..33d2c9a5a97c 100644 --- a/drivers/staging/brcm80211/util/hnddma.c +++ b/drivers/staging/brcm80211/util/hnddma.c @@ -232,7 +232,7 @@ static bool dma32_alloc(dma_info_t *di, uint direction); static bool dma32_txreset(dma_info_t *di); static bool dma32_rxreset(dma_info_t *di); static bool dma32_txsuspendedidle(dma_info_t *di); -static int dma32_txfast(dma_info_t *di, void *p0, bool commit); +static int dma32_txfast(dma_info_t *di, struct sk_buff *p0, bool commit); static void *dma32_getnexttxp(dma_info_t *di, txd_range_t range); static void *dma32_getnextrxp(dma_info_t *di, bool forceall); static void dma32_txrotate(dma_info_t *di); @@ -254,7 +254,7 @@ static bool dma64_alloc(dma_info_t *di, uint direction); static bool dma64_txreset(dma_info_t *di); static bool dma64_rxreset(dma_info_t *di); static bool dma64_txsuspendedidle(dma_info_t *di); -static int dma64_txfast(dma_info_t *di, void *p0, bool commit); +static int dma64_txfast(dma_info_t *di, struct sk_buff *p0, bool commit); static int dma64_txunframed(dma_info_t *di, void *p0, uint len, bool commit); static void *dma64_getpos(dma_info_t *di, bool direction); static void *dma64_getnexttxp(dma_info_t *di, txd_range_t range); @@ -979,7 +979,7 @@ _dma_rx_param_get(dma_info_t *di, u16 *rxoffset, u16 *rxbufsize) */ static void *BCMFASTPATH _dma_rx(dma_info_t *di) { - void *p, *head, *tail; + struct sk_buff *p, *head, *tail; uint len; uint pkt_len; int resid = 0; @@ -1054,7 +1054,7 @@ static void *BCMFASTPATH _dma_rx(dma_info_t *di) */ static bool BCMFASTPATH _dma_rxfill(dma_info_t *di) { - void *p; + struct sk_buff *p; u16 rxin, rxout; u32 flags = 0; uint n; @@ -1652,9 +1652,9 @@ static bool dma32_txsuspendedidle(dma_info_t *di) * WARNING: call must check the return value for error. * the error(toss frames) could be fatal and cause many subsequent hard to debug problems */ -static int dma32_txfast(dma_info_t *di, void *p0, bool commit) +static int dma32_txfast(dma_info_t *di, struct sk_buff *p0, bool commit) { - void *p, *next; + struct sk_buff *p, *next; unsigned char *data; uint len; u16 txout; @@ -2301,9 +2301,10 @@ static int dma64_txunframed(dma_info_t *di, void *buf, uint len, bool commit) * WARNING: call must check the return value for error. * the error(toss frames) could be fatal and cause many subsequent hard to debug problems */ -static int BCMFASTPATH dma64_txfast(dma_info_t *di, void *p0, bool commit) +static int BCMFASTPATH dma64_txfast(dma_info_t *di, struct sk_buff *p0, + bool commit) { - void *p, *next; + struct sk_buff *p, *next; unsigned char *data; uint len; u16 txout; -- cgit v1.2.3 From 54991ad6d05186bd0324dbdc9c64c5b7952e74c4 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Tue, 23 Nov 2010 14:06:24 +0100 Subject: staging: brcm80211: removed packet macros for accessing sk_buff fields With the packet storage type changed from void pointer to struct sk_buff pointer there is no need for macros for accessing these fields through casting. These can now be accessed directly. Reviewed-by: Brett Rudley Signed-off-by: Arend van Spriel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c | 32 ++--- drivers/staging/brcm80211/brcmfmac/dhd_cdc.c | 18 +-- drivers/staging/brcm80211/brcmfmac/dhd_linux.c | 10 +- drivers/staging/brcm80211/brcmfmac/dhd_sdio.c | 136 +++++++++++----------- drivers/staging/brcm80211/include/linux_osl.h | 18 +-- drivers/staging/brcm80211/sys/wlc_ampdu.c | 22 ++-- drivers/staging/brcm80211/sys/wlc_bmac.c | 10 +- drivers/staging/brcm80211/sys/wlc_mac80211.c | 50 ++++---- drivers/staging/brcm80211/sys/wlc_pub.h | 2 +- drivers/staging/brcm80211/util/bcmutils.c | 54 ++++----- drivers/staging/brcm80211/util/hnddma.c | 24 ++-- 11 files changed, 183 insertions(+), 193 deletions(-) diff --git a/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c b/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c index 3d3a428fa279..aadfe69a8a0c 100644 --- a/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c +++ b/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c @@ -944,8 +944,8 @@ sdioh_request_packet(sdioh_info_t *sd, uint fix_inc, uint write, uint func, /* Claim host controller */ sdio_claim_host(gInstance->func[func]); - for (pnext = pkt; pnext; pnext = PKTNEXT(pnext)) { - uint pkt_len = PKTLEN(pnext); + for (pnext = pkt; pnext; pnext = pnext->next) { + uint pkt_len = pnext->len; pkt_len += 3; pkt_len &= 0xFFFFFFFC; @@ -962,23 +962,23 @@ sdioh_request_packet(sdioh_info_t *sd, uint fix_inc, uint write, uint func, * is supposed to give * us something we can work with. */ - ASSERT(((u32) (PKTDATA(pkt)) & DMA_ALIGN_MASK) == 0); + ASSERT(((u32) (pkt->data) & DMA_ALIGN_MASK) == 0); if ((write) && (!fifo)) { err_ret = sdio_memcpy_toio(gInstance->func[func], addr, - ((u8 *) PKTDATA(pnext)), + ((u8 *) (pnext->data)), pkt_len); } else if (write) { err_ret = sdio_memcpy_toio(gInstance->func[func], addr, - ((u8 *) PKTDATA(pnext)), + ((u8 *) (pnext->data)), pkt_len); } else if (fifo) { err_ret = sdio_readsb(gInstance->func[func], - ((u8 *) PKTDATA(pnext)), + ((u8 *) (pnext->data)), addr, pkt_len); } else { err_ret = sdio_memcpy_fromio(gInstance->func[func], - ((u8 *) PKTDATA(pnext)), + ((u8 *) (pnext->data)), addr, pkt_len); } @@ -1048,41 +1048,41 @@ sdioh_request_buffer(sdioh_info_t *sd, uint pio_dma, uint fix_inc, uint write, /* For a write, copy the buffer data into the packet. */ if (write) - bcopy(buffer, PKTDATA(mypkt), buflen_u); + bcopy(buffer, mypkt->data, buflen_u); Status = sdioh_request_packet(sd, fix_inc, write, func, addr, mypkt); /* For a read, copy the packet data back to the buffer. */ if (!write) - bcopy(PKTDATA(mypkt), buffer, buflen_u); + bcopy(mypkt->data, buffer, buflen_u); PKTFREE(sd->osh, mypkt, write ? true : false); - } else if (((u32) (PKTDATA(pkt)) & DMA_ALIGN_MASK) != 0) { + } else if (((u32) (pkt->data) & DMA_ALIGN_MASK) != 0) { /* Case 2: We have a packet, but it is unaligned. */ /* In this case, we cannot have a chain. */ - ASSERT(PKTNEXT(pkt) == NULL); + ASSERT(pkt->next == NULL); sd_data(("%s: Creating aligned %s Packet, len=%d\n", - __func__, write ? "TX" : "RX", PKTLEN(pkt))); - mypkt = PKTGET(sd->osh, PKTLEN(pkt), write ? true : false); + __func__, write ? "TX" : "RX", pkt->len)); + mypkt = PKTGET(sd->osh, pkt->len, write ? true : false); if (!mypkt) { sd_err(("%s: PKTGET failed: len %d\n", - __func__, PKTLEN(pkt))); + __func__, pkt->len)); return SDIOH_API_RC_FAIL; } /* For a write, copy the buffer data into the packet. */ if (write) - bcopy(PKTDATA(pkt), PKTDATA(mypkt), PKTLEN(pkt)); + bcopy(pkt->data, mypkt->data, pkt->len); Status = sdioh_request_packet(sd, fix_inc, write, func, addr, mypkt); /* For a read, copy the packet data back to the buffer. */ if (!write) - bcopy(PKTDATA(mypkt), PKTDATA(pkt), PKTLEN(mypkt)); + bcopy(mypkt->data, pkt->data, mypkt->len); PKTFREE(sd->osh, mypkt, write ? true : false); } else { /* case 3: We have a packet and diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_cdc.c b/drivers/staging/brcm80211/brcmfmac/dhd_cdc.c index c23d30b13147..2fa77cb53040 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_cdc.c +++ b/drivers/staging/brcm80211/brcmfmac/dhd_cdc.c @@ -323,13 +323,13 @@ void dhd_prot_hdrpush(dhd_pub_t *dhd, int ifidx, struct sk_buff *pktbuf) skb_push(pktbuf, BDC_HEADER_LEN); - h = (struct bdc_header *)PKTDATA(pktbuf); + h = (struct bdc_header *)(pktbuf->data); h->flags = (BDC_PROTO_VER << BDC_FLAG_VER_SHIFT); if (PKTSUMNEEDED(pktbuf)) h->flags |= BDC_FLAG_SUM_NEEDED; - h->priority = (PKTPRIO(pktbuf) & BDC_PRIORITY_MASK); + h->priority = (pktbuf->priority & BDC_PRIORITY_MASK); h->flags2 = 0; h->rssi = 0; #endif /* BDC */ @@ -341,13 +341,13 @@ bool dhd_proto_fcinfo(dhd_pub_t *dhd, struct sk_buff *pktbuf, u8 * fcbits) #ifdef BDC struct bdc_header *h; - if (PKTLEN(pktbuf) < BDC_HEADER_LEN) { + if (pktbuf->len < BDC_HEADER_LEN) { DHD_ERROR(("%s: rx data too short (%d < %d)\n", - __func__, PKTLEN(pktbuf), BDC_HEADER_LEN)); + __func__, pktbuf->len, BDC_HEADER_LEN)); return BCME_ERROR; } - h = (struct bdc_header *)PKTDATA(pktbuf); + h = (struct bdc_header *)(pktbuf->data); *fcbits = h->priority >> BDC_PRIORITY_FC_SHIFT; if ((h->flags2 & BDC_FLAG2_FC_FLAG) == BDC_FLAG2_FC_FLAG) @@ -367,13 +367,13 @@ int dhd_prot_hdrpull(dhd_pub_t *dhd, int *ifidx, struct sk_buff *pktbuf) #ifdef BDC /* Pop BDC header used to convey priority for buses that don't */ - if (PKTLEN(pktbuf) < BDC_HEADER_LEN) { + if (pktbuf->len < BDC_HEADER_LEN) { DHD_ERROR(("%s: rx data too short (%d < %d)\n", __func__, - PKTLEN(pktbuf), BDC_HEADER_LEN)); + pktbuf->len, BDC_HEADER_LEN)); return BCME_ERROR; } - h = (struct bdc_header *)PKTDATA(pktbuf); + h = (struct bdc_header *)(pktbuf->data); *ifidx = BDC_GET_IF_IDX(h); if (*ifidx >= DHD_MAX_IFS) { @@ -396,7 +396,7 @@ int dhd_prot_hdrpull(dhd_pub_t *dhd, int *ifidx, struct sk_buff *pktbuf) PKTSETSUMGOOD(pktbuf, true); } - PKTSETPRIO(pktbuf, (h->priority & BDC_PRIORITY_MASK)); + pktbuf->priority = h->priority & BDC_PRIORITY_MASK; skb_pull(pktbuf, BDC_HEADER_LEN); #endif /* BDC */ diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_linux.c b/drivers/staging/brcm80211/brcmfmac/dhd_linux.c index ec887fb32faa..2a502f9ab66d 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_linux.c +++ b/drivers/staging/brcm80211/brcmfmac/dhd_linux.c @@ -1028,8 +1028,8 @@ int dhd_sendpkt(dhd_pub_t *dhdp, int ifidx, struct sk_buff *pktbuf) return -ENODEV; /* Update multicast statistic */ - if (PKTLEN(pktbuf) >= ETHER_ADDR_LEN) { - u8 *pktdata = (u8 *) PKTDATA(pktbuf); + if (pktbuf->len >= ETHER_ADDR_LEN) { + u8 *pktdata = (u8 *) (pktbuf->data); struct ether_header *eh = (struct ether_header *)pktdata; if (ETHER_ISMULTI(eh->ether_dhost)) @@ -1151,8 +1151,8 @@ void dhd_rx_frame(dhd_pub_t *dhdp, int ifidx, struct sk_buff *pktbuf, for (i = 0; pktbuf && i < numpkt; i++, pktbuf = pnext) { - pnext = PKTNEXT(pktbuf); - PKTSETNEXT(pktbuf, NULL); + pnext = pktbuf->next; + pktbuf->next = NULL; skb = PKTTONATIVE(dhdp->osh, pktbuf); @@ -1233,7 +1233,7 @@ void dhd_txcomplete(dhd_pub_t *dhdp, struct sk_buff *txp, bool success) dhd_prot_hdrpull(dhdp, &ifidx, txp); - eh = (struct ether_header *)PKTDATA(txp); + eh = (struct ether_header *)(txp->data); type = ntoh16(eh->ether_type); if (type == ETHER_TYPE_802_1X) diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c b/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c index 12bb7c602f1f..1d06fb299801 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c +++ b/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c @@ -357,16 +357,16 @@ extern void bcmsdh_enable_hw_oob_intr(void *sdh, bool enable); #if defined(OOB_INTR_ONLY) && defined(SDIO_ISR_THREAD) #error OOB_INTR_ONLY is NOT working with SDIO_ISR_THREAD #endif /* defined(OOB_INTR_ONLY) && defined(SDIO_ISR_THREAD) */ -#define PKTALIGN(osh, p, len, align) \ +#define PKTALIGN(_osh, _p, _len, _align) \ do { \ uint datalign; \ - datalign = (unsigned long)PKTDATA((p)); \ - datalign = roundup(datalign, (align)) - datalign; \ - ASSERT(datalign < (align)); \ - ASSERT(PKTLEN((p)) >= ((len) + datalign)); \ + datalign = (unsigned long)((_p)->data); \ + datalign = roundup(datalign, (_align)) - datalign; \ + ASSERT(datalign < (_align)); \ + ASSERT((_p)->len >= ((_len) + datalign)); \ if (datalign) \ - skb_pull((p), datalign); \ - __skb_trim((p), (len)); \ + skb_pull((_p), datalign); \ + __skb_trim((_p), (_len)); \ } while (0) /* Limit on rounding up frames */ @@ -927,7 +927,7 @@ static int dhdsdio_txpkt(dhd_bus_t *bus, struct sk_buff *pkt, uint chan, goto done; } - frame = (u8 *) PKTDATA(pkt); + frame = (u8 *) (pkt->data); /* Add alignment padding, allocate new packet if needed */ pad = ((unsigned long)frame % DHD_SDALIGN); @@ -936,37 +936,37 @@ static int dhdsdio_txpkt(dhd_bus_t *bus, struct sk_buff *pkt, uint chan, DHD_INFO(("%s: insufficient headroom %d for %d pad\n", __func__, (int)PKTHEADROOM(pkt), pad)); bus->dhd->tx_realloc++; - new = PKTGET(osh, (PKTLEN(pkt) + DHD_SDALIGN), true); + new = PKTGET(osh, (pkt->len + DHD_SDALIGN), true); if (!new) { DHD_ERROR(("%s: couldn't allocate new %d-byte " "packet\n", - __func__, PKTLEN(pkt) + DHD_SDALIGN)); + __func__, pkt->len + DHD_SDALIGN)); ret = BCME_NOMEM; goto done; } - PKTALIGN(osh, new, PKTLEN(pkt), DHD_SDALIGN); - bcopy(PKTDATA(pkt), PKTDATA(new), PKTLEN(pkt)); + PKTALIGN(osh, new, pkt->len, DHD_SDALIGN); + bcopy(pkt->data, new->data, pkt->len); if (free_pkt) PKTFREE(osh, pkt, true); /* free the pkt if canned one is not used */ free_pkt = true; pkt = new; - frame = (u8 *) PKTDATA(pkt); + frame = (u8 *) (pkt->data); ASSERT(((unsigned long)frame % DHD_SDALIGN) == 0); pad = 0; } else { skb_push(pkt, pad); - frame = (u8 *) PKTDATA(pkt); + frame = (u8 *) (pkt->data); - ASSERT((pad + SDPCM_HDRLEN) <= (int)PKTLEN(pkt)); + ASSERT((pad + SDPCM_HDRLEN) <= (int)(pkt->len)); bzero(frame, pad + SDPCM_HDRLEN); } } ASSERT(pad < DHD_SDALIGN); /* Hardware tag: 2 byte len followed by 2 byte ~len check (all LE) */ - len = (u16) PKTLEN(pkt); + len = (u16) (pkt->len); *(u16 *) frame = htol16(len); *(((u16 *) frame) + 1) = htol16(~len); @@ -979,7 +979,7 @@ static int dhdsdio_txpkt(dhd_bus_t *bus, struct sk_buff *pkt, uint chan, htol32_ua_store(0, frame + SDPCM_FRAMETAG_LEN + sizeof(swheader)); #ifdef DHD_DEBUG - tx_packets[PKTPRIO(pkt)]++; + tx_packets[pkt->priority]++; if (DHD_BYTES_ON() && (((DHD_CTL_ON() && (chan == SDPCM_CONTROL_CHANNEL)) || (DHD_DATA_ON() && (chan != SDPCM_CONTROL_CHANNEL))))) { @@ -1075,14 +1075,14 @@ int dhd_bus_txdata(struct dhd_bus *bus, struct sk_buff *pkt) DHD_TRACE(("%s: Enter\n", __func__)); osh = bus->dhd->osh; - datalen = PKTLEN(pkt); + datalen = pkt->len; #ifdef SDTEST /* Push the test header if doing loopback */ if (bus->ext_loop) { u8 *data; skb_push(pkt, SDPCM_TEST_HDRLEN); - data = PKTDATA(pkt); + data = pkt->data; *data++ = SDPCM_TEST_ECHOREQ; *data++ = (u8) bus->loopid++; *data++ = (datalen >> 0); @@ -1093,9 +1093,9 @@ int dhd_bus_txdata(struct dhd_bus *bus, struct sk_buff *pkt) /* Add space for the header */ skb_push(pkt, SDPCM_HDRLEN); - ASSERT(IS_ALIGNED((unsigned long)PKTDATA(pkt), 2)); + ASSERT(IS_ALIGNED((unsigned long)(pkt->data), 2)); - prec = PRIO2PREC((PKTPRIO(pkt) & PRIOMASK)); + prec = PRIO2PREC((pkt->priority & PRIOMASK)); /* Check for existing queue, current flow-control, pending event, or pending clock */ @@ -1191,7 +1191,7 @@ static uint dhdsdio_sendfromq(dhd_bus_t *bus, uint maxframes) break; } dhd_os_sdunlock_txq(bus->dhd); - datalen = PKTLEN(pkt) - SDPCM_HDRLEN; + datalen = pkt->len - SDPCM_HDRLEN; #ifndef SDTEST ret = dhdsdio_txpkt(bus, pkt, SDPCM_DATA_CHANNEL, true); @@ -3204,8 +3204,8 @@ static u8 dhdsdio_rxglom(dhd_bus_t *bus, u8 rxseq) dhd_os_sdlock_rxq(bus->dhd); pfirst = plast = pnext = NULL; - dlen = (u16) PKTLEN(bus->glomd); - dptr = PKTDATA(bus->glomd); + dlen = (u16) (bus->glomd->len); + dptr = bus->glomd->data; if (!dlen || (dlen & 1)) { DHD_ERROR(("%s: bad glomd len(%d), ignore descriptor\n", __func__, dlen)); @@ -3246,13 +3246,13 @@ static u8 dhdsdio_rxglom(dhd_bus_t *bus, u8 rxseq) __func__, num, sublen)); break; } - ASSERT(!PKTLINK(pnext)); + ASSERT(!(pnext->prev)); if (!pfirst) { ASSERT(!plast); pfirst = plast = pnext; } else { ASSERT(plast); - PKTSETNEXT(plast, pnext); + plast->next = pnext; plast = pnext; } @@ -3295,10 +3295,10 @@ static u8 dhdsdio_rxglom(dhd_bus_t *bus, u8 rxseq) if (DHD_GLOM_ON()) { DHD_GLOM(("%s: try superframe read, packet chain:\n", __func__)); - for (pnext = bus->glom; pnext; pnext = PKTNEXT(pnext)) { + for (pnext = bus->glom; pnext; pnext = pnext->next) { DHD_GLOM((" %p: %p len 0x%04x (%d)\n", - pnext, (u8 *) PKTDATA(pnext), - PKTLEN(pnext), PKTLEN(pnext))); + pnext, (u8 *) (pnext->data), + pnext->len, pnext->len)); } } @@ -3314,7 +3314,7 @@ static u8 dhdsdio_rxglom(dhd_bus_t *bus, u8 rxseq) bcmsdh_cur_sbwad (bus->sdh), SDIO_FUNC_2, F2SYNC, - (u8 *) PKTDATA(pfirst), + (u8 *) pfirst->data, dlen, pfirst, NULL, NULL); } else if (bus->dataptr) { errcode = dhd_bcmsdh_recv_buf(bus, @@ -3360,13 +3360,13 @@ static u8 dhdsdio_rxglom(dhd_bus_t *bus, u8 rxseq) } #ifdef DHD_DEBUG if (DHD_GLOM_ON()) { - prhex("SUPERFRAME", PKTDATA(pfirst), - min_t(int, PKTLEN(pfirst), 48)); + prhex("SUPERFRAME", pfirst->data, + min_t(int, pfirst->len, 48)); } #endif /* Validate the superframe header */ - dptr = (u8 *) PKTDATA(pfirst); + dptr = (u8 *) (pfirst->data); sublen = ltoh16_ua(dptr); check = ltoh16_ua(dptr + sizeof(u16)); @@ -3404,11 +3404,11 @@ static u8 dhdsdio_rxglom(dhd_bus_t *bus, u8 rxseq) __func__)); errcode = -1; } else if ((doff < SDPCM_HDRLEN) || - (doff > (PKTLEN(pfirst) - SDPCM_HDRLEN))) { + (doff > (pfirst->len - SDPCM_HDRLEN))) { DHD_ERROR(("%s (superframe): Bad data offset %d: HW %d " "pkt %d min %d\n", __func__, doff, sublen, - PKTLEN(pfirst), SDPCM_HDRLEN)); + pfirst->len, SDPCM_HDRLEN)); errcode = -1; } @@ -3434,9 +3434,9 @@ static u8 dhdsdio_rxglom(dhd_bus_t *bus, u8 rxseq) /* Validate all the subframe headers */ for (num = 0, pnext = pfirst; pnext && !errcode; - num++, pnext = PKTNEXT(pnext)) { - dptr = (u8 *) PKTDATA(pnext); - dlen = (u16) PKTLEN(pnext); + num++, pnext = pnext->next) { + dptr = (u8 *) (pnext->data); + dlen = (u16) (pnext->len); sublen = ltoh16_ua(dptr); check = ltoh16_ua(dptr + sizeof(u16)); chan = SDPCM_PACKET_CHANNEL(&dptr[SDPCM_FRAMETAG_LEN]); @@ -3496,10 +3496,10 @@ static u8 dhdsdio_rxglom(dhd_bus_t *bus, u8 rxseq) dhd_os_sdlock_rxq(bus->dhd); for (num = 0; pfirst; rxseq++, pfirst = pnext) { - pnext = PKTNEXT(pfirst); - PKTSETNEXT(pfirst, NULL); + pnext = pfirst->next; + pfirst->next = NULL; - dptr = (u8 *) PKTDATA(pfirst); + dptr = (u8 *) (pfirst->data); sublen = ltoh16_ua(dptr); chan = SDPCM_PACKET_CHANNEL(&dptr[SDPCM_FRAMETAG_LEN]); seq = SDPCM_PACKET_SEQUENCE(&dptr[SDPCM_FRAMETAG_LEN]); @@ -3507,8 +3507,8 @@ static u8 dhdsdio_rxglom(dhd_bus_t *bus, u8 rxseq) DHD_GLOM(("%s: Get subframe %d, %p(%p/%d), sublen %d " "chan %d seq %d\n", - __func__, num, pfirst, PKTDATA(pfirst), - PKTLEN(pfirst), sublen, chan, seq)); + __func__, num, pfirst, pfirst->data, + pfirst->len, sublen, chan, seq)); ASSERT((chan == SDPCM_DATA_CHANNEL) || (chan == SDPCM_EVENT_CHANNEL)); @@ -3527,10 +3527,10 @@ static u8 dhdsdio_rxglom(dhd_bus_t *bus, u8 rxseq) __skb_trim(pfirst, sublen); skb_pull(pfirst, doff); - if (PKTLEN(pfirst) == 0) { + if (pfirst->len == 0) { PKTFREE(bus->dhd->osh, pfirst, false); if (plast) { - PKTSETNEXT(plast, pnext); + plast->next = pnext; } else { ASSERT(save_pfirst == pfirst); save_pfirst = pnext; @@ -3543,7 +3543,7 @@ static u8 dhdsdio_rxglom(dhd_bus_t *bus, u8 rxseq) bus->dhd->rx_errors++; PKTFREE(osh, pfirst, false); if (plast) { - PKTSETNEXT(plast, pnext); + plast->next = pnext; } else { ASSERT(save_pfirst == pfirst); save_pfirst = pnext; @@ -3553,7 +3553,7 @@ static u8 dhdsdio_rxglom(dhd_bus_t *bus, u8 rxseq) /* this packet will go up, link back into chain and count it */ - PKTSETNEXT(pfirst, pnext); + pfirst->next = pnext; plast = pfirst; num++; @@ -3561,11 +3561,11 @@ static u8 dhdsdio_rxglom(dhd_bus_t *bus, u8 rxseq) if (DHD_GLOM_ON()) { DHD_GLOM(("%s subframe %d to stack, %p(%p/%d) " "nxt/lnk %p/%p\n", - __func__, num, pfirst, PKTDATA(pfirst), - PKTLEN(pfirst), PKTNEXT(pfirst), - PKTLINK(pfirst))); - prhex("", (u8 *) PKTDATA(pfirst), - min_t(int, PKTLEN(pfirst), 32)); + __func__, num, pfirst, pfirst->data, + pfirst->len, pfirst->next, + pfirst->prev)); + prhex("", (u8 *) pfirst->data, + min_t(int, pfirst->len, 32)); } #endif /* DHD_DEBUG */ } @@ -3737,9 +3737,9 @@ static uint dhdsdio_readframes(dhd_bus_t *bus, uint maxframes, bool *finished) if (bus->bus == SPI_BUS) bus->usebufpool = true; - ASSERT(!PKTLINK(pkt)); + ASSERT(!(pkt->prev)); PKTALIGN(osh, pkt, rdlen, DHD_SDALIGN); - rxbuf = (u8 *) PKTDATA(pkt); + rxbuf = (u8 *) (pkt->data); /* Read the entire frame */ sdret = dhd_bcmsdh_recv_buf(bus, @@ -4103,17 +4103,17 @@ static uint dhdsdio_readframes(dhd_bus_t *bus, uint maxframes, bool *finished) } dhd_os_sdunlock_rxq(bus->dhd); - ASSERT(!PKTLINK(pkt)); + ASSERT(!(pkt->prev)); /* Leave room for what we already read, and align remainder */ - ASSERT(firstread < (PKTLEN(pkt))); + ASSERT(firstread < pkt->len); skb_pull(pkt, firstread); PKTALIGN(osh, pkt, rdlen, DHD_SDALIGN); /* Read the remaining frame data */ sdret = dhd_bcmsdh_recv_buf(bus, bcmsdh_cur_sbwad(sdh), SDIO_FUNC_2, - F2SYNC, ((u8 *) PKTDATA(pkt)), rdlen, + F2SYNC, ((u8 *) (pkt->data)), rdlen, pkt, NULL, NULL); bus->f2rxdata++; ASSERT(sdret != BCME_PENDING); @@ -4136,11 +4136,11 @@ static uint dhdsdio_readframes(dhd_bus_t *bus, uint maxframes, bool *finished) /* Copy the already-read portion */ skb_push(pkt, firstread); - bcopy(bus->rxhdr, PKTDATA(pkt), firstread); + bcopy(bus->rxhdr, pkt->data, firstread); #ifdef DHD_DEBUG if (DHD_BYTES_ON() && DHD_DATA_ON()) - prhex("Rx Data", PKTDATA(pkt), len); + prhex("Rx Data", pkt->data, len); #endif deliver: @@ -4151,7 +4151,7 @@ deliver: __func__, len)); #ifdef DHD_DEBUG if (DHD_GLOM_ON()) { - prhex("Glom Data", PKTDATA(pkt), len); + prhex("Glom Data", pkt->data, len); } #endif __skb_trim(pkt, len); @@ -4178,7 +4178,7 @@ deliver: } #endif /* SDTEST */ - if (PKTLEN(pkt) == 0) { + if (pkt->len == 0) { dhd_os_sdlock_rxq(bus->dhd); PKTFREE(bus->dhd->osh, pkt, false); dhd_os_sdunlock_rxq(bus->dhd); @@ -4672,7 +4672,7 @@ static void dhdsdio_pktgen(dhd_bus_t *bus) } PKTALIGN(osh, pkt, (len + SDPCM_HDRLEN + SDPCM_TEST_HDRLEN), DHD_SDALIGN); - data = (u8 *) PKTDATA(pkt) + SDPCM_HDRLEN; + data = (u8 *) (pkt->data) + SDPCM_HDRLEN; /* Write test header cmd and extra based on mode */ switch (bus->pktgen_mode) { @@ -4711,9 +4711,9 @@ static void dhdsdio_pktgen(dhd_bus_t *bus) #ifdef DHD_DEBUG if (DHD_BYTES_ON() && DHD_DATA_ON()) { - data = (u8 *) PKTDATA(pkt) + SDPCM_HDRLEN; + data = (u8 *) (pkt->data) + SDPCM_HDRLEN; prhex("dhdsdio_pktgen: Tx Data", data, - PKTLEN(pkt) - SDPCM_HDRLEN); + pkt->len - SDPCM_HDRLEN); } #endif @@ -4750,7 +4750,7 @@ static void dhdsdio_sdtest_set(dhd_bus_t *bus, bool start) return; } PKTALIGN(osh, pkt, (SDPCM_HDRLEN + SDPCM_TEST_HDRLEN), DHD_SDALIGN); - data = (u8 *) PKTDATA(pkt) + SDPCM_HDRLEN; + data = (u8 *) (pkt->data) + SDPCM_HDRLEN; /* Fill in the test header */ *data++ = SDPCM_TEST_SEND; @@ -4775,7 +4775,7 @@ static void dhdsdio_testrcv(dhd_bus_t *bus, struct sk_buff *pkt, uint seq) u16 offset; /* Check for min length */ - pktlen = PKTLEN(pkt); + pktlen = pkt->len; if (pktlen < SDPCM_TEST_HDRLEN) { DHD_ERROR(("dhdsdio_restrcv: toss runt frame, pktlen %d\n", pktlen)); @@ -4784,7 +4784,7 @@ static void dhdsdio_testrcv(dhd_bus_t *bus, struct sk_buff *pkt, uint seq) } /* Extract header fields */ - data = PKTDATA(pkt); + data = pkt->data; cmd = *data++; extra = *data++; len = *data++; @@ -4807,7 +4807,7 @@ static void dhdsdio_testrcv(dhd_bus_t *bus, struct sk_buff *pkt, uint seq) case SDPCM_TEST_ECHOREQ: /* Rx->Tx turnaround ok (even on NDIS w/current implementation) */ - *(u8 *) (PKTDATA(pkt)) = SDPCM_TEST_ECHORSP; + *(u8 *) (pkt->data) = SDPCM_TEST_ECHORSP; if (dhdsdio_txpkt(bus, pkt, SDPCM_TEST_CHANNEL, true) == 0) { bus->pktgen_sent++; } else { diff --git a/drivers/staging/brcm80211/include/linux_osl.h b/drivers/staging/brcm80211/include/linux_osl.h index 010182fa1a92..4e446606b5c1 100644 --- a/drivers/staging/brcm80211/include/linux_osl.h +++ b/drivers/staging/brcm80211/include/linux_osl.h @@ -246,15 +246,10 @@ extern void osl_dma_unmap(struct osl_info *osh, uint pa, uint size, #define BZERO_SM(r, len) memset((r), '\0', (len)) /* packet primitives */ -#define PKTGET(osh, len, send) osl_pktget((osh), (len)) -#define PKTFREE(osh, skb, send) osl_pktfree((osh), (skb), (send)) -#define PKTDATA(skb) (((struct sk_buff *)(skb))->data) -#define PKTLEN(skb) (((struct sk_buff *)(skb))->len) -#define PKTHEADROOM(skb) (PKTDATA(skb)-(((struct sk_buff *)(skb))->head)) -#define PKTTAILROOM(skb) ((((struct sk_buff *)(skb))->end)-(((struct sk_buff *)(skb))->tail)) -#define PKTNEXT(skb) (((struct sk_buff *)(skb))->next) -#define PKTSETNEXT(skb, x) \ - (((struct sk_buff *)(skb))->next = (struct sk_buff *)(x)) +#define PKTGET(osh, len, send) osl_pktget((osh), (len)) +#define PKTFREE(osh, skb, send) osl_pktfree((osh), (skb), (send)) +#define PKTHEADROOM(skb) ((skb)->data - (skb)->head) +#define PKTTAILROOM(skb) ((skb)->end - (skb)->tail) #define PKTALLOCED(osh) (((struct osl_pubinfo *)(osh))->pktalloced) extern void *osl_pktget(struct osl_info *osh, uint len); extern void osl_pktfree(struct osl_info *osh, void *skb, bool send); @@ -293,14 +288,9 @@ osl_pkt_tonative(struct osl_pubinfo *osh, void *pkt) #define PKTSKIPCT(osh, skb) #endif /* BRCM_FULLMAC */ -#define PKTLINK(skb) (((struct sk_buff *)(skb))->prev) -#define PKTSETLINK(skb, x) (((struct sk_buff *)(skb))->prev = (struct sk_buff*)(x)) -#define PKTPRIO(skb) (((struct sk_buff *)(skb))->priority) -#define PKTSETPRIO(skb, x) (((struct sk_buff *)(skb))->priority = (x)) #define PKTSUMNEEDED(skb) (((struct sk_buff *)(skb))->ip_summed == CHECKSUM_PARTIAL) #define PKTSETSUMGOOD(skb, x) (((struct sk_buff *)(skb))->ip_summed = \ ((x) ? CHECKSUM_UNNECESSARY : CHECKSUM_NONE)) /* PKTSETSUMNEEDED and PKTSUMGOOD are not possible because skb->ip_summed is overloaded */ -#define PKTSHARED(skb) (((struct sk_buff *)(skb))->cloned) #endif /* _linux_osl_h_ */ diff --git a/drivers/staging/brcm80211/sys/wlc_ampdu.c b/drivers/staging/brcm80211/sys/wlc_ampdu.c index f2acda77d47b..c5ab4a459471 100644 --- a/drivers/staging/brcm80211/sys/wlc_ampdu.c +++ b/drivers/staging/brcm80211/sys/wlc_ampdu.c @@ -153,7 +153,7 @@ static inline u16 pkt_txh_seqnum(wlc_info_t *wlc, struct sk_buff *p) { d11txh_t *txh; struct dot11_header *h; - txh = (d11txh_t *) PKTDATA(p); + txh = (d11txh_t *) p->data; h = (struct dot11_header *)((u8 *) (txh + 1) + D11_PHY_HDR_LEN); return ltoh16(h->seq) >> SEQNUM_SHIFT; } @@ -475,7 +475,7 @@ wlc_ampdu_agg(ampdu_info_t *ampdu, struct scb *scb, struct sk_buff *p, { scb_ampdu_t *scb_ampdu; scb_ampdu_tid_ini_t *ini; - u8 tid = (u8) PKTPRIO(p); + u8 tid = (u8) (p->priority); scb_ampdu = SCB_AMPDU_CUBBY(ampdu, scb); @@ -529,7 +529,7 @@ wlc_sendampdu(ampdu_info_t *ampdu, wlc_txq_info_t *qi, struct sk_buff **pdu, ASSERT(p); - tid = (u8) PKTPRIO(p); + tid = (u8) (p->priority); ASSERT(tid < AMPDU_MAX_SCB_TID); f = ampdu->fifo_tb + prio2fifo[tid]; @@ -589,7 +589,7 @@ wlc_sendampdu(ampdu_info_t *ampdu, wlc_txq_info_t *qi, struct sk_buff **pdu, /* pkt is good to be aggregated */ ASSERT(tx_info->flags & IEEE80211_TX_CTL_AMPDU); - txh = (d11txh_t *) PKTDATA(p); + txh = (d11txh_t *) p->data; plcp = (u8 *) (txh + 1); h = (struct dot11_header *)(plcp + D11_PHY_HDR_LEN); seq = ltoh16(h->seq) >> SEQNUM_SHIFT; @@ -744,7 +744,7 @@ wlc_sendampdu(ampdu_info_t *ampdu, wlc_txq_info_t *qi, struct sk_buff **pdu, if (p) { if ((tx_info->flags & IEEE80211_TX_CTL_AMPDU) && - ((u8) PKTPRIO(p) == tid)) { + ((u8) (p->priority) == tid)) { plen = pkttotlen(osh, p) + AMPDU_MAX_MPDU_OVERHEAD; @@ -778,7 +778,7 @@ wlc_sendampdu(ampdu_info_t *ampdu, wlc_txq_info_t *qi, struct sk_buff **pdu, WLCNTADD(ampdu->cnt->txmpdu, count); /* patch up the last txh */ - txh = (d11txh_t *) PKTDATA(pkt[count - 1]); + txh = (d11txh_t *) pkt[count - 1]->data; mcl = ltoh16(txh->MacTxControlLow); mcl &= ~TXC_AMPDU_MASK; mcl |= (TXC_AMPDU_LAST << TXC_AMPDU_SHIFT); @@ -796,7 +796,7 @@ wlc_sendampdu(ampdu_info_t *ampdu, wlc_txq_info_t *qi, struct sk_buff **pdu, ampdu_len -= roundup(len, 4) - len; /* patch up the first txh & plcp */ - txh = (d11txh_t *) PKTDATA(pkt[0]); + txh = (d11txh_t *) pkt[0]->data; plcp = (u8 *) (txh + 1); WLC_SET_MIMO_PLCP_LEN(plcp, ampdu_len); @@ -901,7 +901,7 @@ wlc_ampdu_dotxstatus(ampdu_info_t *ampdu, struct scb *scb, struct sk_buff *p, ASSERT(txs->status & TX_STATUS_AMPDU); scb_ampdu = SCB_AMPDU_CUBBY(ampdu, scb); ASSERT(scb_ampdu); - ini = SCB_AMPDU_INI(scb_ampdu, PKTPRIO(p)); + ini = SCB_AMPDU_INI(scb_ampdu, p->priority); ASSERT(ini->scb == scb); /* BMAC_NOTE: For the split driver, second level txstatus comes later @@ -985,7 +985,7 @@ wlc_ampdu_dotxstatus_complete(ampdu_info_t *ampdu, struct scb *scb, scb_ampdu = SCB_AMPDU_CUBBY(ampdu, scb); ASSERT(scb_ampdu); - tid = (u8) PKTPRIO(p); + tid = (u8) (p->priority); ini = SCB_AMPDU_INI(scb_ampdu, tid); retry_limit = ampdu->retry_limit_tid[tid]; @@ -1065,7 +1065,7 @@ wlc_ampdu_dotxstatus_complete(ampdu_info_t *ampdu, struct scb *scb, #ifdef BCMDBG if (WL_ERROR_ON()) { prpkt("txpkt (AMPDU)", wlc->osh, p); - wlc_print_txdesc((d11txh_t *) PKTDATA(p)); + wlc_print_txdesc((d11txh_t *) p->data); wlc_print_txstatus(txs); } #endif /* BCMDBG */ @@ -1076,7 +1076,7 @@ wlc_ampdu_dotxstatus_complete(ampdu_info_t *ampdu, struct scb *scb, while (p) { tx_info = IEEE80211_SKB_CB(p); ASSERT(tx_info->flags & IEEE80211_TX_CTL_AMPDU); - txh = (d11txh_t *) PKTDATA(p); + txh = (d11txh_t *) p->data; mcl = ltoh16(txh->MacTxControlLow); plcp = (u8 *) (txh + 1); h = (struct dot11_header *)(plcp + D11_PHY_HDR_LEN); diff --git a/drivers/staging/brcm80211/sys/wlc_bmac.c b/drivers/staging/brcm80211/sys/wlc_bmac.c index 2a2ad494746d..264389f788f1 100644 --- a/drivers/staging/brcm80211/sys/wlc_bmac.c +++ b/drivers/staging/brcm80211/sys/wlc_bmac.c @@ -285,7 +285,7 @@ wlc_bmac_recv(wlc_hw_info_t *wlc_hw, uint fifo, bool bound) if (!tail) head = tail = p; else { - PKTSETLINK(tail, p); + tail->prev = p; tail = p; } @@ -302,11 +302,11 @@ wlc_bmac_recv(wlc_hw_info_t *wlc_hw, uint fifo, bool bound) /* process each frame */ while ((p = head) != NULL) { - head = PKTLINK(head); - PKTSETLINK(p, NULL); + head = head->prev; + p->prev = NULL; /* record the tsf_l in wlc_rxd11hdr */ - wlc_rxhdr = (wlc_d11rxhdr_t *) PKTDATA(p); + wlc_rxhdr = (wlc_d11rxhdr_t *) p->data; wlc_rxhdr->tsf_l = htol32(tsf_l); /* compute the RSSI from d11rxhdr and record it in wlc_rxd11hr */ @@ -3327,7 +3327,7 @@ static bool wlc_bmac_txstatus_corerev4(wlc_hw_info_t *wlc_hw) while (!fatal && (status_p = dma_rx(wlc_hw->di[RX_TXSTATUS_FIFO]))) { - txs = (tx_status_t *) PKTDATA(status_p); + txs = (tx_status_t *) status_p->data; /* MAC uses little endian only */ ltoh16_buf((void *)txs, sizeof(tx_status_t)); diff --git a/drivers/staging/brcm80211/sys/wlc_mac80211.c b/drivers/staging/brcm80211/sys/wlc_mac80211.c index d99fcb524d54..52e4d95a5cb1 100644 --- a/drivers/staging/brcm80211/sys/wlc_mac80211.c +++ b/drivers/staging/brcm80211/sys/wlc_mac80211.c @@ -5042,9 +5042,9 @@ wlc_prec_enq_head(wlc_info_t *wlc, struct pktq *q, struct sk_buff *pkt, /* Increment wme stats */ if (WME_ENAB(wlc->pub)) { WLCNTINCR(wlc->pub->_wme_cnt-> - tx_failed[WME_PRIO2AC(PKTPRIO(p))].packets); + tx_failed[WME_PRIO2AC(p->priority)].packets); WLCNTADD(wlc->pub->_wme_cnt-> - tx_failed[WME_PRIO2AC(PKTPRIO(p))].bytes, + tx_failed[WME_PRIO2AC(p->priority)].bytes, pkttotlen(wlc->osh, p)); } @@ -5071,7 +5071,7 @@ void BCMFASTPATH wlc_txq_enq(void *ctx, struct scb *scb, struct sk_buff *sdu, struct pktq *q = &qi->q; int prio; - prio = PKTPRIO(sdu); + prio = sdu->priority; ASSERT(pktq_max(q) >= wlc->pub->tunables->datahiwat); @@ -5111,7 +5111,7 @@ wlc_sendpkt_mac80211(wlc_info_t *wlc, struct sk_buff *sdu, uint fifo; void *pkt; struct scb *scb = &global_scb; - struct dot11_header *d11_header = (struct dot11_header *)PKTDATA(sdu); + struct dot11_header *d11_header = (struct dot11_header *)(sdu->data); u16 type, fc; ASSERT(sdu); @@ -5120,13 +5120,13 @@ wlc_sendpkt_mac80211(wlc_info_t *wlc, struct sk_buff *sdu, type = FC_TYPE(fc); /* 802.11 standard requires management traffic to go at highest priority */ - prio = (type == FC_TYPE_DATA ? PKTPRIO(sdu) : MAXPRIO); + prio = (type == FC_TYPE_DATA ? sdu->priority : MAXPRIO); fifo = prio2fifo[prio]; ASSERT((uint) PKTHEADROOM(sdu) >= TXOFF); - ASSERT(!PKTSHARED(sdu)); - ASSERT(!PKTNEXT(sdu)); - ASSERT(!PKTLINK(sdu)); + ASSERT(!(sdu->cloned)); + ASSERT(!(sdu->next)); + ASSERT(!(sdu->prev)); ASSERT(fifo < NFIFO); pkt = sdu; @@ -5236,7 +5236,7 @@ wlc_txfifo(wlc_info_t *wlc, uint fifo, struct sk_buff *p, bool commit, d11txh_t *txh; ASSERT(fifo < NFIFO); - txh = (d11txh_t *) PKTDATA(p); + txh = (d11txh_t *) (p->data); /* When a BC/MC frame is being committed to the BCMC fifo via DMA (NOT PIO), update * ucode or BSS info as appropriate. @@ -5690,7 +5690,7 @@ wlc_d11hdrs_mac80211(wlc_info_t *wlc, struct ieee80211_hw *hw, osh = wlc->osh; /* locate 802.11 MAC header */ - h = (struct dot11_header *)PKTDATA(p); + h = (struct dot11_header *)(p->data); fc = ltoh16(h->fc); type = FC_TYPE(fc); @@ -5731,12 +5731,12 @@ wlc_d11hdrs_mac80211(wlc_info_t *wlc, struct ieee80211_hw *hw, } else { /* Increment the counter for first fragment */ if (tx_info->flags & IEEE80211_TX_CTL_FIRST_FRAGMENT) { - SCB_SEQNUM(scb, PKTPRIO(p))++; + SCB_SEQNUM(scb, p->priority)++; } /* extract fragment number from frame first */ seq = ltoh16(seq) & FRAGNUM_MASK; - seq |= (SCB_SEQNUM(scb, PKTPRIO(p)) << SEQNUM_SHIFT); + seq |= (SCB_SEQNUM(scb, p->priority) << SEQNUM_SHIFT); h->seq = htol16(seq); frameid = ((seq << TXFID_SEQ_SHIFT) & TXFID_SEQ_MASK) | @@ -6559,7 +6559,7 @@ wlc_dotxstatus(wlc_info_t *wlc, tx_status_t *txs, u32 frm_tx2) if (p == NULL) goto fatal; - txh = (d11txh_t *) PKTDATA(p); + txh = (d11txh_t *) (p->data); mcl = ltoh16(txh->MacTxControlLow); if (txs->phyerr) { @@ -6649,8 +6649,8 @@ wlc_dotxstatus(wlc_info_t *wlc, tx_status_t *txs, u32 frm_tx2) wlc_txfifo_complete(wlc, queue, 1); if (lastframe) { - PKTSETNEXT(p, NULL); - PKTSETLINK(p, NULL); + p->next = NULL; + p->prev = NULL; wlc->txretried = 0; /* remove PLCP & Broadcom tx descriptor header */ skb_pull(p, D11_PHY_HDR_LEN); @@ -6825,7 +6825,7 @@ prep_mac80211_status(wlc_info_t *wlc, d11rxhdr_t *rxh, struct sk_buff *p, /* qual */ rx_status->antenna = (rxh->PhyRxStatus_0 & PRXS0_RXANT_UPSUBBAND) ? 1 : 0; /* ant */ - plcp = PKTDATA(p); + plcp = p->data; rspec = wlc_compute_rspec(rxh, plcp); if (IS_MCS(rspec)) { @@ -6920,12 +6920,12 @@ wlc_recvctl(wlc_info_t *wlc, struct osl_info *osh, d11rxhdr_t *rxh, prep_mac80211_status(wlc, rxh, p, &rx_status); /* mac header+body length, exclude CRC and plcp header */ - len_mpdu = PKTLEN(p) - D11_PHY_HDR_LEN - DOT11_FCS_LEN; + len_mpdu = p->len - D11_PHY_HDR_LEN - DOT11_FCS_LEN; skb_pull(p, D11_PHY_HDR_LEN); __skb_trim(p, len_mpdu); - ASSERT(!PKTNEXT(p)); - ASSERT(!PKTLINK(p)); + ASSERT(!(p->next)); + ASSERT(!(p->prev)); ASSERT(IS_ALIGNED((unsigned long)skb->data, 2)); @@ -6980,7 +6980,7 @@ void BCMFASTPATH wlc_recv(wlc_info_t *wlc, struct sk_buff *p) osh = wlc->osh; /* frame starts with rxhdr */ - rxh = (d11rxhdr_t *) PKTDATA(p); + rxh = (d11rxhdr_t *) (p->data); /* strip off rxhdr */ skb_pull(p, wlc->hwrxoff); @@ -6990,17 +6990,17 @@ void BCMFASTPATH wlc_recv(wlc_info_t *wlc, struct sk_buff *p) /* MAC inserts 2 pad bytes for a4 headers or QoS or A-MSDU subframes */ if (rxh->RxStatus1 & RXS_PBPRES) { - if (PKTLEN(p) < 2) { + if (p->len < 2) { WLCNTINCR(wlc->pub->_cnt->rxrunt); WL_ERROR(("wl%d: wlc_recv: rcvd runt of len %d\n", - wlc->pub->unit, PKTLEN(p))); + wlc->pub->unit, p->len)); goto toss; } skb_pull(p, 2); } - h = (struct dot11_header *)(PKTDATA(p) + D11_PHY_HDR_LEN); - len = PKTLEN(p); + h = (struct dot11_header *)(p->data + D11_PHY_HDR_LEN); + len = p->len; if (rxh->RxStatus1 & RXS_FCSERR) { if (wlc->pub->mac80211_state & MAC80211_PROMISC_BCNS) { @@ -7804,7 +7804,7 @@ int wlc_prep_pdu(wlc_info_t *wlc, struct sk_buff *pdu, uint *fifop) osh = wlc->osh; ASSERT(pdu); - txh = (d11txh_t *) PKTDATA(pdu); + txh = (d11txh_t *) (pdu->data); ASSERT(txh); h = (struct dot11_header *)((u8 *) (txh + 1) + D11_PHY_HDR_LEN); ASSERT(h); diff --git a/drivers/staging/brcm80211/sys/wlc_pub.h b/drivers/staging/brcm80211/sys/wlc_pub.h index b3ad4c0233ab..ea796cb40b7a 100644 --- a/drivers/staging/brcm80211/sys/wlc_pub.h +++ b/drivers/staging/brcm80211/sys/wlc_pub.h @@ -440,7 +440,7 @@ struct wlc_if; #define WLC_PREC_COUNT 16 /* Max precedence level implemented */ -/* pri is PKTPRIO encoded in the packet. This maps the Packet priority to +/* pri is priority encoded in the packet. This maps the Packet priority to * enqueue precedence as defined in wlc_prec_map */ extern const u8 wlc_prio2prec_map[]; diff --git a/drivers/staging/brcm80211/util/bcmutils.c b/drivers/staging/brcm80211/util/bcmutils.c index 701ea0170933..49c1f74dda83 100644 --- a/drivers/staging/brcm80211/util/bcmutils.c +++ b/drivers/staging/brcm80211/util/bcmutils.c @@ -39,19 +39,19 @@ uint pktfrombuf(struct osl_info *osh, struct sk_buff *p, uint offset, int len, uint n, ret = 0; /* skip 'offset' bytes */ - for (; p && offset; p = PKTNEXT(p)) { - if (offset < (uint) PKTLEN(p)) + for (; p && offset; p = p->next) { + if (offset < (uint) (p->len)) break; - offset -= PKTLEN(p); + offset -= p->len; } if (!p) return 0; /* copy the data */ - for (; p && len; p = PKTNEXT(p)) { - n = min((uint) PKTLEN(p) - offset, (uint) len); - bcopy(buf, PKTDATA(p) + offset, n); + for (; p && len; p = p->next) { + n = min((uint) (p->len) - offset, (uint) len); + bcopy(buf, p->data + offset, n); buf += n; len -= n; ret += n; @@ -66,8 +66,8 @@ uint BCMFASTPATH pkttotlen(struct osl_info *osh, struct sk_buff *p) uint total; total = 0; - for (; p; p = PKTNEXT(p)) - total += PKTLEN(p); + for (; p; p = p->next) + total += p->len; return total; } @@ -81,7 +81,7 @@ struct sk_buff *BCMFASTPATH pktq_penq(struct pktq *pq, int prec, struct pktq_prec *q; ASSERT(prec >= 0 && prec < pq->num_prec); - ASSERT(PKTLINK(p) == NULL); /* queueing chains not allowed */ + ASSERT(p->prev == NULL); /* queueing chains not allowed */ ASSERT(!pktq_full(pq)); ASSERT(!pktq_pfull(pq, prec)); @@ -89,7 +89,7 @@ struct sk_buff *BCMFASTPATH pktq_penq(struct pktq *pq, int prec, q = &pq->q[prec]; if (q->head) - PKTSETLINK(q->tail, p); + q->tail->prev = p; else q->head = p; @@ -110,7 +110,7 @@ struct sk_buff *BCMFASTPATH pktq_penq_head(struct pktq *pq, int prec, struct pktq_prec *q; ASSERT(prec >= 0 && prec < pq->num_prec); - ASSERT(PKTLINK(p) == NULL); /* queueing chains not allowed */ + ASSERT(p->prev == NULL); /* queueing chains not allowed */ ASSERT(!pktq_full(pq)); ASSERT(!pktq_pfull(pq, prec)); @@ -120,7 +120,7 @@ struct sk_buff *BCMFASTPATH pktq_penq_head(struct pktq *pq, int prec, if (q->head == NULL) q->tail = p; - PKTSETLINK(p, q->head); + p->prev = q->head; q->head = p; q->len++; @@ -145,7 +145,7 @@ struct sk_buff *BCMFASTPATH pktq_pdeq(struct pktq *pq, int prec) if (p == NULL) return NULL; - q->head = PKTLINK(p); + q->head = p->prev; if (q->head == NULL) q->tail = NULL; @@ -153,7 +153,7 @@ struct sk_buff *BCMFASTPATH pktq_pdeq(struct pktq *pq, int prec) pq->len--; - PKTSETLINK(p, NULL); + p->prev = NULL; return p; } @@ -171,11 +171,11 @@ struct sk_buff *BCMFASTPATH pktq_pdeq_tail(struct pktq *pq, int prec) if (p == NULL) return NULL; - for (prev = NULL; p != q->tail; p = PKTLINK(p)) + for (prev = NULL; p != q->tail; p = p->prev) prev = p; if (prev) - PKTSETLINK(prev, NULL); + prev->prev = NULL; else q->head = NULL; @@ -196,8 +196,8 @@ void pktq_pflush(struct osl_info *osh, struct pktq *pq, int prec, bool dir) q = &pq->q[prec]; p = q->head; while (p) { - q->head = PKTLINK(p); - PKTSETLINK(p, NULL); + q->head = p->prev; + p->prev = NULL; PKTFREE(osh, p, dir); q->len--; pq->len--; @@ -228,17 +228,17 @@ pktq_pflush(struct osl_info *osh, struct pktq *pq, int prec, bool dir, if (fn == NULL || (*fn) (p, arg)) { bool head = (p == q->head); if (head) - q->head = PKTLINK(p); + q->head = p->prev; else - PKTSETLINK(prev, PKTLINK(p)); - PKTSETLINK(p, NULL); + prev->prev = p->prev; + p->prev = NULL; PKTFREE(osh, p, dir); q->len--; pq->len--; - p = (head ? q->head : PKTLINK(prev)); + p = (head ? q->head : prev->prev); } else { prev = p; - p = PKTLINK(p); + p = p->prev; } } @@ -331,7 +331,7 @@ struct sk_buff *BCMFASTPATH pktq_mdeq(struct pktq *pq, uint prec_bmp, if (p == NULL) return NULL; - q->head = PKTLINK(p); + q->head = p->prev; if (q->head == NULL) q->tail = NULL; @@ -342,7 +342,7 @@ struct sk_buff *BCMFASTPATH pktq_mdeq(struct pktq *pq, uint prec_bmp, pq->len--; - PKTSETLINK(p, NULL); + p->prev = NULL; return p; } @@ -417,8 +417,8 @@ void prpkt(const char *msg, struct osl_info *osh, struct sk_buff *p0) if (msg && (msg[0] != '\0')) printf("%s:\n", msg); - for (p = p0; p; p = PKTNEXT(p)) - prhex(NULL, PKTDATA(p), PKTLEN(p)); + for (p = p0; p; p = p->next) + prhex(NULL, p->data, p->len); } #endif /* defined(BCMDBG) */ diff --git a/drivers/staging/brcm80211/util/hnddma.c b/drivers/staging/brcm80211/util/hnddma.c index 33d2c9a5a97c..c9dddcdb1099 100644 --- a/drivers/staging/brcm80211/util/hnddma.c +++ b/drivers/staging/brcm80211/util/hnddma.c @@ -989,15 +989,15 @@ static void *BCMFASTPATH _dma_rx(dma_info_t *di) if (head == NULL) return NULL; - len = ltoh16(*(u16 *) (PKTDATA(head))); + len = ltoh16(*(u16 *) (head->data)); DMA_TRACE(("%s: dma_rx len %d\n", di->name, len)); #if defined(__mips__) if (!len) { - while (!(len = *(u16 *) OSL_UNCACHED(PKTDATA(head)))) + while (!(len = *(u16 *) OSL_UNCACHED(head->data))) udelay(1); - *(u16 *) PKTDATA(head) = htol16((u16) len); + *(u16 *) (head->data) = htol16((u16) len); } #endif /* defined(__mips__) */ @@ -1010,7 +1010,7 @@ static void *BCMFASTPATH _dma_rx(dma_info_t *di) if (resid > 0) { tail = head; while ((resid > 0) && (p = _dma_getnextrxp(di, false))) { - PKTSETNEXT(tail, p); + tail->next = p; pkt_len = min(resid, (int)di->rxbufsize); __skb_trim(p, pkt_len); @@ -1115,12 +1115,12 @@ static bool BCMFASTPATH _dma_rxfill(dma_info_t *di) /* Do a cached write instead of uncached write since DMA_MAP * will flush the cache. */ - *(u32 *) (PKTDATA(p)) = 0; + *(u32 *) (p->data) = 0; if (DMASGLIST_ENAB) bzero(&di->rxp_dmah[rxout], sizeof(hnddma_seg_map_t)); - pa = DMA_MAP(di->osh, PKTDATA(p), + pa = DMA_MAP(di->osh, p->data, di->rxbufsize, DMA_RX, p, &di->rxp_dmah[rxout]); ASSERT(IS_ALIGNED(PHYSADDRLO(pa), 4)); @@ -1673,12 +1673,12 @@ static int dma32_txfast(dma_info_t *di, struct sk_buff *p0, bool commit) uint nsegs, j; hnddma_seg_map_t *map; - data = PKTDATA(p); - len = PKTLEN(p); + data = p->data; + len = p->len; #ifdef BCM_DMAPAD len += PKTDMAPAD(di->osh, p); #endif - next = PKTNEXT(p); + next = p->next; /* return nonzero if out of tx descriptors */ if (NEXTTXD(txout) == di->txin) @@ -2323,12 +2323,12 @@ static int BCMFASTPATH dma64_txfast(dma_info_t *di, struct sk_buff *p0, uint nsegs, j; hnddma_seg_map_t *map; - data = PKTDATA(p); - len = PKTLEN(p); + data = p->data; + len = p->len; #ifdef BCM_DMAPAD len += PKTDMAPAD(di->osh, p); #endif /* BCM_DMAPAD */ - next = PKTNEXT(p); + next = p->next; /* return nonzero if out of tx descriptors */ if (NEXTTXD(txout) == di->txin) -- cgit v1.2.3 From 3be727c8f076cafaf26a1ceda4cad85f5166c8a3 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Tue, 23 Nov 2010 22:20:30 +0100 Subject: staging: brcm80211: remove some more packet related macros macros PKTHEADROOM and PKTTAILROOM have been replaced by native skbuff functions and macros PKTALLOCED and PKTUNALLOC have been removed. Reviewed-by: Roland Vossen Reviewed-by: Brett Rudley Signed-off-by: Arend van Spriel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmfmac/dhd_sdio.c | 8 ++++---- drivers/staging/brcm80211/include/linux_osl.h | 7 ++----- drivers/staging/brcm80211/sys/wlc_mac80211.c | 8 ++++---- 3 files changed, 10 insertions(+), 13 deletions(-) diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c b/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c index 1d06fb299801..9e96c7e6e3c5 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c +++ b/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c @@ -932,9 +932,9 @@ static int dhdsdio_txpkt(dhd_bus_t *bus, struct sk_buff *pkt, uint chan, /* Add alignment padding, allocate new packet if needed */ pad = ((unsigned long)frame % DHD_SDALIGN); if (pad) { - if (PKTHEADROOM(pkt) < pad) { + if (skb_headroom(pkt) < pad) { DHD_INFO(("%s: insufficient headroom %d for %d pad\n", - __func__, (int)PKTHEADROOM(pkt), pad)); + __func__, skb_headroom(pkt), pad)); bus->dhd->tx_realloc++; new = PKTGET(osh, (pkt->len + DHD_SDALIGN), true); if (!new) { @@ -994,7 +994,7 @@ static int dhdsdio_txpkt(dhd_bus_t *bus, struct sk_buff *pkt, uint chan, u16 pad = bus->blocksize - (len % bus->blocksize); if ((pad <= bus->roundup) && (pad < bus->blocksize)) #ifdef NOTUSED - if (pad <= PKTTAILROOM(pkt)) + if (pad <= skb_tailroom(pkt)) #endif /* NOTUSED */ len += pad; } else if (len % DHD_SDALIGN) { @@ -1004,7 +1004,7 @@ static int dhdsdio_txpkt(dhd_bus_t *bus, struct sk_buff *pkt, uint chan, /* Some controllers have trouble with odd bytes -- round to even */ if (forcealign && (len & (ALIGNMENT - 1))) { #ifdef NOTUSED - if (PKTTAILROOM(pkt)) + if (skb_tailroom(pkt)) #endif len = roundup(len, ALIGNMENT); #ifdef NOTUSED diff --git a/drivers/staging/brcm80211/include/linux_osl.h b/drivers/staging/brcm80211/include/linux_osl.h index 4e446606b5c1..b973f3fea7e2 100644 --- a/drivers/staging/brcm80211/include/linux_osl.h +++ b/drivers/staging/brcm80211/include/linux_osl.h @@ -17,6 +17,7 @@ #ifndef _linux_osl_h_ #define _linux_osl_h_ +#include extern struct osl_info *osl_attach(void *pdev, uint bustype); extern void osl_detach(struct osl_info *osh); @@ -248,9 +249,7 @@ extern void osl_dma_unmap(struct osl_info *osh, uint pa, uint size, /* packet primitives */ #define PKTGET(osh, len, send) osl_pktget((osh), (len)) #define PKTFREE(osh, skb, send) osl_pktfree((osh), (skb), (send)) -#define PKTHEADROOM(skb) ((skb)->data - (skb)->head) -#define PKTTAILROOM(skb) ((skb)->end - (skb)->tail) -#define PKTALLOCED(osh) (((struct osl_pubinfo *)(osh))->pktalloced) + extern void *osl_pktget(struct osl_info *osh, uint len); extern void osl_pktfree(struct osl_info *osh, void *skb, bool send); @@ -281,8 +280,6 @@ osl_pkt_tonative(struct osl_pubinfo *osh, void *pkt) #define PKTTONATIVE(osh, pkt) \ osl_pkt_tonative((struct osl_pubinfo *)(osh), (pkt)) #else /* !BRCM_FULLMAC */ -#define PKTUNALLOC(osh) (((struct osl_pubinfo *)(osh))->pktalloced--) - #define PKTSETSKIPCT(osh, skb) #define PKTCLRSKIPCT(osh, skb) #define PKTSKIPCT(osh, skb) diff --git a/drivers/staging/brcm80211/sys/wlc_mac80211.c b/drivers/staging/brcm80211/sys/wlc_mac80211.c index 52e4d95a5cb1..e61aa5a62c45 100644 --- a/drivers/staging/brcm80211/sys/wlc_mac80211.c +++ b/drivers/staging/brcm80211/sys/wlc_mac80211.c @@ -2732,9 +2732,9 @@ uint wlc_down(wlc_info_t *wlc) /* Verify all packets are flushed from the driver */ - if (PKTALLOCED(wlc->osh) != 0) { + if (wlc->osh->pub.pktalloced != 0) { WL_ERROR(("%d packets not freed at wlc_down!!!!!!\n", - PKTALLOCED(wlc->osh))); + wlc->osh->pub.pktalloced)); } #ifdef BCMDBG /* Since all the packets should have been freed, @@ -5123,7 +5123,7 @@ wlc_sendpkt_mac80211(wlc_info_t *wlc, struct sk_buff *sdu, prio = (type == FC_TYPE_DATA ? sdu->priority : MAXPRIO); fifo = prio2fifo[prio]; - ASSERT((uint) PKTHEADROOM(sdu) >= TXOFF); + ASSERT((uint) skb_headroom(sdu) >= TXOFF); ASSERT(!(sdu->cloned)); ASSERT(!(sdu->next)); ASSERT(!(sdu->prev)); @@ -6933,7 +6933,7 @@ wlc_recvctl(wlc_info_t *wlc, struct osl_info *osh, d11rxhdr_t *rxh, ieee80211_rx_irqsafe(wlc->pub->ieee_hw, p); WLCNTINCR(wlc->pub->_cnt->ieee_rx); - PKTUNALLOC(osh); + osh->pub.pktalloced--; return; } -- cgit v1.2.3 From c95e66e1fae810110410b59f411110ca671ffb28 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Tue, 23 Nov 2010 22:20:31 +0100 Subject: staging: brcm80211: remove unused dhd_ops_virt variable definition The variable dhd_ops_virt was used before although its use was rather limited as can be found in previous commit: | commit 4fd68ae1a558043a2cc4ea2faf7235e71c3241aa | Author: Julia Lawall | Date: Tue Oct 26 12:25:33 2010 +0200 | | drivers/staging/brcm80211/brcmfmac/dhd_linux.c: delete double assignment | Reviewed-by: Roland Vossen Reviewed-by: Brett Rudley Signed-off-by: Arend van Spriel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmfmac/dhd_linux.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_linux.c b/drivers/staging/brcm80211/brcmfmac/dhd_linux.c index 2a502f9ab66d..7f66d7a84b6e 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_linux.c +++ b/drivers/staging/brcm80211/brcmfmac/dhd_linux.c @@ -2251,14 +2251,6 @@ static struct net_device_ops dhd_ops_pri = { .ndo_set_multicast_list = dhd_set_multicast_list }; -static struct net_device_ops dhd_ops_virt = { - .ndo_get_stats = dhd_get_stats, - .ndo_do_ioctl = dhd_ioctl_entry, - .ndo_start_xmit = dhd_start_xmit, - .ndo_set_mac_address = dhd_set_mac_address, - .ndo_set_multicast_list = dhd_set_multicast_list -}; - int dhd_net_attach(dhd_pub_t *dhdp, int ifidx) { dhd_info_t *dhd = (dhd_info_t *) dhdp->info; -- cgit v1.2.3 From fa7a1db200ecb7a5912722a563646935700765a8 Mon Sep 17 00:00:00 2001 From: Brett Rudley Date: Tue, 23 Nov 2010 15:30:02 -0800 Subject: staging: brcm80211: Remove BUSTYPE macro BUSTYPE isn't used in this configuration. Signed-off-by: Brett Rudley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/include/bcmdefs.h | 1 - drivers/staging/brcm80211/include/nicpci.h | 2 +- drivers/staging/brcm80211/include/siutils.h | 4 +- drivers/staging/brcm80211/phy/wlc_phy_cmn.c | 4 +- drivers/staging/brcm80211/phy/wlc_phy_int.h | 2 +- drivers/staging/brcm80211/sys/wl_mac80211.c | 4 +- drivers/staging/brcm80211/sys/wlc_bmac.c | 20 +++++----- drivers/staging/brcm80211/sys/wlc_mac80211.c | 2 +- drivers/staging/brcm80211/util/aiutils.c | 8 ++-- drivers/staging/brcm80211/util/bcmsrom.c | 12 +++--- drivers/staging/brcm80211/util/hnddma.c | 8 ++-- drivers/staging/brcm80211/util/nicpci.c | 3 +- drivers/staging/brcm80211/util/sbutils.c | 8 ++-- drivers/staging/brcm80211/util/siutils.c | 57 ++++++++++++---------------- 14 files changed, 63 insertions(+), 72 deletions(-) diff --git a/drivers/staging/brcm80211/include/bcmdefs.h b/drivers/staging/brcm80211/include/bcmdefs.h index ae6a65a64714..ba1f5e93179b 100644 --- a/drivers/staging/brcm80211/include/bcmdefs.h +++ b/drivers/staging/brcm80211/include/bcmdefs.h @@ -51,7 +51,6 @@ #define SPI_BUS 6 /* gSPI target */ #define RPC_BUS 7 /* RPC target */ -#define BUSTYPE(bus) (bus) #define CHIPTYPE(bus) (bus) #define CHIPID(chip) (chip) #define CHIPREV(rev) (rev) diff --git a/drivers/staging/brcm80211/include/nicpci.h b/drivers/staging/brcm80211/include/nicpci.h index 7ea7daf7c2b6..928818daedd7 100644 --- a/drivers/staging/brcm80211/include/nicpci.h +++ b/drivers/staging/brcm80211/include/nicpci.h @@ -74,6 +74,6 @@ extern bool pcicore_pmecap_fast(struct osl_info *osh); extern void pcicore_pmeen(void *pch); extern void pcicore_pmeclr(void *pch); extern bool pcicore_pmestat(void *pch); -#endif /* defined(BCMSDIO) || (defined(BCMBUSTYPE) && (BCMBUSTYPE == SI_BUS)) */ +#endif /* defined(BCMSDIO)||(defined(BCMBUSTYPE) && (BCMBUSTYPE==SI_BUS)) */ #endif /* _NICPCI_H */ diff --git a/drivers/staging/brcm80211/include/siutils.h b/drivers/staging/brcm80211/include/siutils.h index 0f042799c376..d6115cdd94f6 100644 --- a/drivers/staging/brcm80211/include/siutils.h +++ b/drivers/staging/brcm80211/include/siutils.h @@ -295,9 +295,9 @@ typedef struct si_info { #define ILP_DIV_5MHZ 0 /* ILP = 5 MHz */ #define ILP_DIV_1MHZ 4 /* ILP = 1 MHz */ -#define PCI(si) ((BUSTYPE((si)->pub.bustype) == PCI_BUS) && \ +#define PCI(si) (((si)->pub.bustype == PCI_BUS) && \ ((si)->pub.buscoretype == PCI_CORE_ID)) -#define PCIE(si) ((BUSTYPE((si)->pub.bustype) == PCI_BUS) && \ +#define PCIE(si) (((si)->pub.bustype == PCI_BUS) && \ ((si)->pub.buscoretype == PCIE_CORE_ID)) #define PCI_FORCEHT(si) \ (PCIE(si) && (si->pub.chip == BCM4716_CHIP_ID)) diff --git a/drivers/staging/brcm80211/phy/wlc_phy_cmn.c b/drivers/staging/brcm80211/phy/wlc_phy_cmn.c index e20c1f09f8bb..87d33dd8e01b 100644 --- a/drivers/staging/brcm80211/phy/wlc_phy_cmn.c +++ b/drivers/staging/brcm80211/phy/wlc_phy_cmn.c @@ -300,7 +300,7 @@ void write_radio_reg(phy_info_t *pi, u16 addr, u16 val) W_REG(osh, &pi->regs->phy4wdatalo, val); } - if (BUSTYPE(pi->sh->bustype) == PCI_BUS) { + if (pi->sh->bustype == PCI_BUS) { if (++pi->phy_wreg >= pi->phy_wreg_limit) { (void)R_REG(osh, &pi->regs->maccontrol); pi->phy_wreg = 0; @@ -445,7 +445,7 @@ void write_phy_reg(phy_info_t *pi, u16 addr, u16 val) #else W_REG(osh, (volatile u32 *)(®s->phyregaddr), addr | (val << 16)); - if (BUSTYPE(pi->sh->bustype) == PCI_BUS) { + if (pi->sh->bustype == PCI_BUS) { if (++pi->phy_wreg >= pi->phy_wreg_limit) { pi->phy_wreg = 0; (void)R_REG(osh, ®s->phyversion); diff --git a/drivers/staging/brcm80211/phy/wlc_phy_int.h b/drivers/staging/brcm80211/phy/wlc_phy_int.h index fb92c3bccb16..72eee9120c2f 100644 --- a/drivers/staging/brcm80211/phy/wlc_phy_int.h +++ b/drivers/staging/brcm80211/phy/wlc_phy_int.h @@ -1158,7 +1158,7 @@ extern void wlc_phy_table_write_nphy(phy_info_t *pi, u32, u32, u32, (pi->ipa5g_on && CHSPEC_IS5G(pi->radio_chanspec))) #define WLC_PHY_WAR_PR51571(pi) \ - if ((BUSTYPE((pi)->sh->bustype) == PCI_BUS) && NREV_LT((pi)->pubpi.phy_rev, 3)) \ + if (((pi)->sh->bustype == PCI_BUS) && NREV_LT((pi)->pubpi.phy_rev, 3)) \ (void)R_REG((pi)->sh->osh, &(pi)->regs->maccontrol) extern void wlc_phy_cal_perical_nphy_run(phy_info_t *pi, u8 caltype); diff --git a/drivers/staging/brcm80211/sys/wl_mac80211.c b/drivers/staging/brcm80211/sys/wl_mac80211.c index 76f611d3c3ad..7d18d4f269e9 100644 --- a/drivers/staging/brcm80211/sys/wl_mac80211.c +++ b/drivers/staging/brcm80211/sys/wl_mac80211.c @@ -1305,8 +1305,8 @@ void wl_free(wl_info_t *wl) * unregister_netdev() calls get_stats() which may read chip registers * so we cannot unmap the chip registers until after calling unregister_netdev() . */ - if (wl->regsva && BUSTYPE(wl->bcm_bustype) != SDIO_BUS && - BUSTYPE(wl->bcm_bustype) != JTAG_BUS) { + if (wl->regsva && wl->bcm_bustype != SDIO_BUS && + wl->bcm_bustype != JTAG_BUS) { iounmap((void *)wl->regsva); } wl->regsva = NULL; diff --git a/drivers/staging/brcm80211/sys/wlc_bmac.c b/drivers/staging/brcm80211/sys/wlc_bmac.c index 264389f788f1..d427980aebed 100644 --- a/drivers/staging/brcm80211/sys/wlc_bmac.c +++ b/drivers/staging/brcm80211/sys/wlc_bmac.c @@ -832,7 +832,7 @@ int wlc_bmac_attach(wlc_info_t *wlc, u16 vendor, u16 device, uint unit, || (wlc_hw->boardflags & BFL_NOPLLDOWN)) wlc_bmac_pllreq(wlc_hw, true, WLC_PLLREQ_SHARED); - if ((BUSTYPE(wlc_hw->sih->bustype) == PCI_BUS) + if ((wlc_hw->sih->bustype == PCI_BUS) && (si_pci_war16165(wlc_hw->sih))) wlc->war16165 = true; @@ -992,7 +992,7 @@ int wlc_bmac_attach(wlc_info_t *wlc, u16 vendor, u16 device, uint unit, wlc_coredisable(wlc_hw); /* Match driver "down" state */ - if (BUSTYPE(wlc_hw->sih->bustype) == PCI_BUS) + if (wlc_hw->sih->bustype == PCI_BUS) si_pci_down(wlc_hw->sih); /* register sb interrupt callback functions */ @@ -1081,7 +1081,7 @@ int wlc_bmac_detach(wlc_info_t *wlc) */ si_deregister_intr_callback(wlc_hw->sih); - if (BUSTYPE(wlc_hw->sih->bustype) == PCI_BUS) + if (wlc_hw->sih->bustype == PCI_BUS) si_pci_sleep(wlc_hw->sih); } @@ -1207,7 +1207,7 @@ int wlc_bmac_up_prep(wlc_hw_info_t *wlc_hw) */ coremask = (1 << wlc_hw->wlc->core->coreidx); - if (BUSTYPE(wlc_hw->sih->bustype) == PCI_BUS) + if (wlc_hw->sih->bustype == PCI_BUS) si_pci_setup(wlc_hw->sih, coremask); ASSERT(si_coreid(wlc_hw->sih) == D11_CORE_ID); @@ -1218,13 +1218,13 @@ int wlc_bmac_up_prep(wlc_hw_info_t *wlc_hw) */ if (wlc_bmac_radio_read_hwdisabled(wlc_hw)) { /* put SB PCI in down state again */ - if (BUSTYPE(wlc_hw->sih->bustype) == PCI_BUS) + if (wlc_hw->sih->bustype == PCI_BUS) si_pci_down(wlc_hw->sih); wlc_bmac_xtal(wlc_hw, OFF); return BCME_RADIOOFF; } - if (BUSTYPE(wlc_hw->sih->bustype) == PCI_BUS) + if (wlc_hw->sih->bustype == PCI_BUS) si_pci_up(wlc_hw->sih); /* reset the d11 core */ @@ -1310,7 +1310,7 @@ int wlc_bmac_down_finish(wlc_hw_info_t *wlc_hw) /* turn off primary xtal and pll */ if (!wlc_hw->noreset) { - if (BUSTYPE(wlc_hw->sih->bustype) == PCI_BUS) + if (wlc_hw->sih->bustype == PCI_BUS) si_pci_down(wlc_hw->sih); wlc_bmac_xtal(wlc_hw, OFF); } @@ -2263,7 +2263,7 @@ void wlc_bmac_hw_up(wlc_hw_info_t *wlc_hw) si_clkctl_init(wlc_hw->sih); wlc_clkctl_clk(wlc_hw, CLK_FAST); - if (BUSTYPE(wlc_hw->sih->bustype) == PCI_BUS) { + if (wlc_hw->sih->bustype == PCI_BUS) { si_pci_fixcfg(wlc_hw->sih); /* AI chip doesn't restore bar0win2 on hibernation/resume, need sw fixup */ @@ -4123,8 +4123,8 @@ void wlc_gpio_fast_deinit(wlc_hw_info_t *wlc_hw) /* Only chips with internal bus or PCIE cores or certain PCI cores * are able to switch cores w/o disabling interrupts */ - if (!((BUSTYPE(wlc_hw->sih->bustype) == SI_BUS) || - ((BUSTYPE(wlc_hw->sih->bustype) == PCI_BUS) && + if (!((wlc_hw->sih->bustype == SI_BUS) || + ((wlc_hw->sih->bustype == PCI_BUS) && ((wlc_hw->sih->buscoretype == PCIE_CORE_ID) || (wlc_hw->sih->buscorerev >= 13))))) return; diff --git a/drivers/staging/brcm80211/sys/wlc_mac80211.c b/drivers/staging/brcm80211/sys/wlc_mac80211.c index e61aa5a62c45..29b6139ae4f0 100644 --- a/drivers/staging/brcm80211/sys/wlc_mac80211.c +++ b/drivers/staging/brcm80211/sys/wlc_mac80211.c @@ -92,7 +92,7 @@ /* To inform the ucode of the last mcast frame posted so that it can clear moredata bit */ #define BCMCFID(wlc, fid) wlc_bmac_write_shm((wlc)->hw, M_BCMC_FID, (fid)) -#define WLC_WAR16165(wlc) (BUSTYPE(wlc->pub->sih->bustype) == PCI_BUS && \ +#define WLC_WAR16165(wlc) (wlc->pub->sih->bustype == PCI_BUS && \ (!AP_ENAB(wlc->pub)) && (wlc->war16165)) /* debug/trace */ diff --git a/drivers/staging/brcm80211/util/aiutils.c b/drivers/staging/brcm80211/util/aiutils.c index dbb3e369b740..cf900773fa7d 100644 --- a/drivers/staging/brcm80211/util/aiutils.c +++ b/drivers/staging/brcm80211/util/aiutils.c @@ -119,7 +119,7 @@ void ai_scan(si_t *sih, void *regs, uint devid) erombase = R_REG(sii->osh, &cc->eromptr); - switch (BUSTYPE(sih->bustype)) { + switch (sih->bustype) { case SI_BUS: eromptr = (u32 *) REG_MAP(erombase, SI_CORE_SIZE); break; @@ -334,7 +334,7 @@ void *ai_setcoreidx(si_t *sih, uint coreidx) ASSERT((sii->intrsenabled_fn == NULL) || !(*(sii)->intrsenabled_fn) ((sii)->intr_arg)); - switch (BUSTYPE(sih->bustype)) { + switch (sih->bustype) { case SI_BUS: /* map new one */ if (!sii->regs[coreidx]) { @@ -508,7 +508,7 @@ uint ai_corereg(si_t *sih, uint coreidx, uint regoff, uint mask, uint val) if (coreidx >= SI_MAXCORES) return 0; - if (BUSTYPE(sih->bustype) == SI_BUS) { + if (sih->bustype == SI_BUS) { /* If internal bus, we can always get at everything */ fast = true; /* map if does not exist */ @@ -518,7 +518,7 @@ uint ai_corereg(si_t *sih, uint coreidx, uint regoff, uint mask, uint val) ASSERT(GOODREGS(sii->regs[coreidx])); } r = (u32 *) ((unsigned char *) sii->regs[coreidx] + regoff); - } else if (BUSTYPE(sih->bustype) == PCI_BUS) { + } else if (sih->bustype == PCI_BUS) { /* If pci/pcie, we can get at pci/pcie regs and on newer cores to chipc */ if ((sii->coreid[coreidx] == CC_CORE_ID) && SI_FAST(sii)) { diff --git a/drivers/staging/brcm80211/util/bcmsrom.c b/drivers/staging/brcm80211/util/bcmsrom.c index 7240e3c11c5c..af4658e4d67e 100644 --- a/drivers/staging/brcm80211/util/bcmsrom.c +++ b/drivers/staging/brcm80211/util/bcmsrom.c @@ -164,14 +164,14 @@ int srom_var_init(si_t *sih, uint bustype, void *curmap, struct osl_info *osh, len = 0; - ASSERT(bustype == BUSTYPE(bustype)); + ASSERT(bustype == bustype); if (vars == NULL || count == NULL) return 0; *vars = NULL; *count = 0; - switch (BUSTYPE(bustype)) { + switch (bustype) { case SI_BUS: case JTAG_BUS: return initvars_srom_si(sih, osh, curmap, vars, count); @@ -204,7 +204,7 @@ srom_read(si_t *sih, uint bustype, void *curmap, struct osl_info *osh, uint i; #endif /* BCMSDIO */ - ASSERT(bustype == BUSTYPE(bustype)); + ASSERT(bustype == bustype); /* check input - 16-bit access only */ if (byteoff & 1 || nbytes & 1 || (byteoff + nbytes) > SROM_MAX) @@ -213,7 +213,7 @@ srom_read(si_t *sih, uint bustype, void *curmap, struct osl_info *osh, off = byteoff / 2; nw = nbytes / 2; - if (BUSTYPE(bustype) == PCI_BUS) { + if (bustype == PCI_BUS) { if (!curmap) return 1; @@ -235,7 +235,7 @@ srom_read(si_t *sih, uint bustype, void *curmap, struct osl_info *osh, } #endif #ifdef BCMSDIO - } else if (BUSTYPE(bustype) == SDIO_BUS) { + } else if (bustype == SDIO_BUS) { off = byteoff / 2; nw = nbytes / 2; for (i = 0; i < nw; i++) { @@ -244,7 +244,7 @@ srom_read(si_t *sih, uint bustype, void *curmap, struct osl_info *osh, return 1; } #endif /* BCMSDIO */ - } else if (BUSTYPE(bustype) == SI_BUS) { + } else if (bustype == SI_BUS) { return 1; } else { return 1; diff --git a/drivers/staging/brcm80211/util/hnddma.c b/drivers/staging/brcm80211/util/hnddma.c index c9dddcdb1099..3c85aa584d8f 100644 --- a/drivers/staging/brcm80211/util/hnddma.c +++ b/drivers/staging/brcm80211/util/hnddma.c @@ -2666,8 +2666,8 @@ uint dma_addrwidth(si_t *sih, void *dmaregs) /* backplane are 64-bit capable */ if (si_backplane64(sih)) /* If bus is System Backplane or PCIE then we can access 64-bits */ - if ((BUSTYPE(sih->bustype) == SI_BUS) || - ((BUSTYPE(sih->bustype) == PCI_BUS) && + if ((sih->bustype == SI_BUS) || + ((sih->bustype == PCI_BUS) && (sih->buscoretype == PCIE_CORE_ID))) return DMADDRWIDTH_64; @@ -2681,8 +2681,8 @@ uint dma_addrwidth(si_t *sih, void *dmaregs) dma32regs = (dma32regs_t *) dmaregs; /* For System Backplane, PCIE bus or addrext feature, 32-bits ok */ - if ((BUSTYPE(sih->bustype) == SI_BUS) || - ((BUSTYPE(sih->bustype) == PCI_BUS) + if ((sih->bustype == SI_BUS) || + ((sih->bustype == PCI_BUS) && sih->buscoretype == PCIE_CORE_ID) || (_dma32_addrext(osh, dma32regs))) return DMADDRWIDTH_32; diff --git a/drivers/staging/brcm80211/util/nicpci.c b/drivers/staging/brcm80211/util/nicpci.c index 2127cc903223..1adac0783369 100644 --- a/drivers/staging/brcm80211/util/nicpci.c +++ b/drivers/staging/brcm80211/util/nicpci.c @@ -47,7 +47,8 @@ typedef struct { /* debug/trace */ #define PCI_ERROR(args) -#define PCIE_PUB(sih) ((BUSTYPE((sih)->bustype) == PCI_BUS) && ((sih)->buscoretype == PCIE_CORE_ID)) +#define PCIE_PUB(sih) \ + (((sih)->bustype == PCI_BUS) && ((sih)->buscoretype == PCIE_CORE_ID)) /* routines to access mdio slave device registers */ static bool pcie_mdiosetblock(pcicore_info_t *pi, uint blk); diff --git a/drivers/staging/brcm80211/util/sbutils.c b/drivers/staging/brcm80211/util/sbutils.c index 82767e266e97..7b93ac22d4fc 100644 --- a/drivers/staging/brcm80211/util/sbutils.c +++ b/drivers/staging/brcm80211/util/sbutils.c @@ -90,7 +90,7 @@ static u32 _sb_coresba(si_info_t *sii) { u32 sbaddr = 0; - switch (BUSTYPE(sii->pub.bustype)) { + switch (sii->pub.bustype) { case SPI_BUS: case SDIO_BUS: sbaddr = (u32)(unsigned long)sii->curmap; @@ -347,7 +347,7 @@ static void *_sb_setcoreidx(si_info_t *sii, uint coreidx) u32 sbaddr = sii->coresba[coreidx]; void *regs; - switch (BUSTYPE(sii->pub.bustype)) { + switch (sii->pub.bustype) { #ifdef BCMSDIO case SPI_BUS: case SDIO_BUS: @@ -412,8 +412,8 @@ bool sb_taclear(si_t *sih, bool details) sii = SI_INFO(sih); - if ((BUSTYPE(sii->pub.bustype) == SDIO_BUS) || - (BUSTYPE(sii->pub.bustype) == SPI_BUS)) { + if ((sii->pub.bustype == SDIO_BUS) || + (sii->pub.bustype == SPI_BUS)) { INTR_OFF(sii, intr_val); origidx = si_coreidx(sih); diff --git a/drivers/staging/brcm80211/util/siutils.c b/drivers/staging/brcm80211/util/siutils.c index e13053626d29..050c2d248978 100644 --- a/drivers/staging/brcm80211/util/siutils.c +++ b/drivers/staging/brcm80211/util/siutils.c @@ -117,12 +117,12 @@ static bool si_buscore_prep(si_info_t *sii, uint bustype, uint devid, #ifndef BRCM_FULLMAC /* kludge to enable the clock on the 4306 which lacks a slowclock */ - if (BUSTYPE(bustype) == PCI_BUS && !si_ispcie(sii)) + if (bustype == PCI_BUS && !si_ispcie(sii)) si_clkctl_xtal(&sii->pub, XTAL | PLL, ON); #endif #if defined(BCMSDIO) - if (BUSTYPE(bustype) == SDIO_BUS) { + if (bustype == SDIO_BUS) { int err; u8 clkset; @@ -224,7 +224,7 @@ static bool si_buscore_setup(si_info_t *sii, chipcregs_t *cc, uint bustype, SI_VMSG(("CORE[%d]: id 0x%x rev %d base 0x%x regs 0x%p\n", i, cid, crev, sii->coresba[i], sii->regs[i])); - if (BUSTYPE(bustype) == PCI_BUS) { + if (bustype == PCI_BUS) { if (cid == PCI_CORE_ID) { pciidx = i; pcirev = crev; @@ -236,8 +236,8 @@ static bool si_buscore_setup(si_info_t *sii, chipcregs_t *cc, uint bustype, } } #ifdef BCMSDIO - else if (((BUSTYPE(bustype) == SDIO_BUS) || - (BUSTYPE(bustype) == SPI_BUS)) && + else if (((bustype == SDIO_BUS) || + (bustype == SPI_BUS)) && ((cid == PCMCIA_CORE_ID) || (cid == SDIOD_CORE_ID))) { sii->pub.buscorerev = crev; sii->pub.buscoretype = cid; @@ -259,7 +259,7 @@ static bool si_buscore_setup(si_info_t *sii, chipcregs_t *cc, uint bustype, * or downloaded code was * already running. */ - if ((BUSTYPE(bustype) == SDIO_BUS) || (BUSTYPE(bustype) == SPI_BUS)) { + if ((bustype == SDIO_BUS) || (bustype == SPI_BUS)) { if (si_setcore(&sii->pub, ARM7S_CORE_ID, 0) || si_setcore(&sii->pub, ARMCM3_CORE_ID, 0)) si_core_disable(&sii->pub, 0); @@ -285,7 +285,7 @@ static bool si_buscore_setup(si_info_t *sii, chipcregs_t *cc, uint bustype, sii->pub.buscoretype, sii->pub.buscorerev)); /* fixup necessary chip/core configurations */ - if (BUSTYPE(sii->pub.bustype) == PCI_BUS) { + if (sii->pub.bustype == PCI_BUS) { if (SI_FAST(sii)) { if (!sii->pch) { sii->pch = (void *)pcicore_init( @@ -312,7 +312,7 @@ static __used void si_nvram_process(si_info_t *sii, char *pvars) uint w = 0; /* get boardtype and boardrev */ - switch (BUSTYPE(sii->pub.bustype)) { + switch (sii->pub.bustype) { case PCI_BUS: /* do a pci config read to get subsystem id and subvendor id */ pci_read_config_dword(sii->osh->pdev, PCI_CFG_SVID, &w); @@ -394,11 +394,6 @@ static si_info_t *si_doattach(si_info_t *sii, uint devid, struct osl_info *osh, cc = (chipcregs_t *) sii->curmap; sih->bustype = bustype; - if (bustype != BUSTYPE(bustype)) { - SI_ERROR(("si_doattach: bus type %d does not match configured bus type %d\n", bustype, BUSTYPE(bustype))); - return NULL; - } - /* bus/core/clk setup for register access */ if (!si_buscore_prep(sii, bustype, devid, sdh)) { SI_ERROR(("si_doattach: si_core_clk_prep failed %d\n", @@ -448,7 +443,7 @@ static si_info_t *si_doattach(si_info_t *sii, uint devid, struct osl_info *osh, /* Init nvram from sprom/otp if they exist */ if (srom_var_init - (&sii->pub, BUSTYPE(bustype), regs, sii->osh, vars, varsz)) { + (&sii->pub, bustype, regs, sii->osh, vars, varsz)) { SI_ERROR(("si_doattach: srom_var_init failed: bad srom\n")); goto exit; } @@ -549,10 +544,6 @@ static si_info_t *si_doattach(si_info_t *sii, uint devid, struct osl_info *osh, } sih->bustype = bustype; - if (bustype != BUSTYPE(bustype)) { - SI_ERROR(("si_doattach: bus type %d does not match configured bus type %d\n", bustype, BUSTYPE(bustype))); - return NULL; - } /* bus/core/clk setup for register access */ if (!si_buscore_prep(sii, bustype, devid, sdh)) { @@ -620,7 +611,7 @@ static si_info_t *si_doattach(si_info_t *sii, uint devid, struct osl_info *osh, /* Init nvram from sprom/otp if they exist */ if (srom_var_init - (&sii->pub, BUSTYPE(bustype), regs, sii->osh, vars, varsz)) { + (&sii->pub, bustype, regs, sii->osh, vars, varsz)) { SI_ERROR(("si_doattach: srom_var_init failed: bad srom\n")); goto exit; } @@ -691,7 +682,7 @@ static si_info_t *si_doattach(si_info_t *sii, uint devid, struct osl_info *osh, return sii; exit: - if (BUSTYPE(sih->bustype) == PCI_BUS) { + if (sih->bustype == PCI_BUS) { if (sii->pch) pcicore_deinit(sii->pch); sii->pch = NULL; @@ -715,7 +706,7 @@ void si_detach(si_t *sih) if (sii == NULL) return; - if (BUSTYPE(sih->bustype) == SI_BUS) + if (sih->bustype == SI_BUS) for (idx = 0; idx < SI_MAXCORES; idx++) if (sii->regs[idx]) { REG_UNMAP(sii->regs[idx]); @@ -725,7 +716,7 @@ void si_detach(si_t *sih) #ifndef BRCM_FULLMAC nvram_exit((void *)si_local); /* free up nvram buffers */ - if (BUSTYPE(sih->bustype) == PCI_BUS) { + if (sih->bustype == PCI_BUS) { if (sii->pch) pcicore_deinit(sii->pch); sii->pch = NULL; @@ -1097,7 +1088,7 @@ static uint si_slowclk_src(si_info_t *sii) ASSERT(SI_FAST(sii) || si_coreid(&sii->pub) == CC_CORE_ID); if (sii->pub.ccrev < 6) { - if (BUSTYPE(sii->pub.bustype) == PCI_BUS) { + if (sii->pub.bustype == PCI_BUS) { pci_read_config_dword(sii->osh->pdev, PCI_GPIO_OUT, &val); if (val & PCI_CFG_GPIO_SCS) @@ -1273,7 +1264,7 @@ int si_clkctl_xtal(si_t *sih, uint what, bool on) sii = SI_INFO(sih); - switch (BUSTYPE(sih->bustype)) { + switch (sih->bustype) { #ifdef BCMSDIO case SDIO_BUS: @@ -1384,7 +1375,7 @@ static bool _si_clkctl_cc(si_info_t *sii, uint mode) INTR_OFF(sii, intr_val); origidx = sii->curidx; - if ((BUSTYPE(sii->pub.bustype) == SI_BUS) && + if ((sii->pub.bustype == SI_BUS) && si_setcore(&sii->pub, MIPS33_CORE_ID, 0) && (si_corerev(&sii->pub) <= 7) && (sii->pub.ccrev >= 10)) goto done; @@ -1466,7 +1457,7 @@ int si_devpath(si_t *sih, char *path, int size) if (!path || size <= 0) return -1; - switch (BUSTYPE(sih->bustype)) { + switch (sih->bustype) { case SI_BUS: case JTAG_BUS: slen = snprintf(path, (size_t) size, "sb/%u/", si_coreidx(sih)); @@ -1556,7 +1547,7 @@ static __used bool si_ispcie(si_info_t *sii) { u8 cap_ptr; - if (BUSTYPE(sii->pub.bustype) != PCI_BUS) + if (sii->pub.bustype != PCI_BUS) return false; cap_ptr = @@ -1623,7 +1614,7 @@ void si_pci_up(si_t *sih) sii = SI_INFO(sih); /* if not pci bus, we're done */ - if (BUSTYPE(sih->bustype) != PCI_BUS) + if (sih->bustype != PCI_BUS) return; if (PCI_FORCEHT(sii)) @@ -1652,7 +1643,7 @@ void si_pci_down(si_t *sih) sii = SI_INFO(sih); /* if not pci bus, we're done */ - if (BUSTYPE(sih->bustype) != PCI_BUS) + if (sih->bustype != PCI_BUS) return; /* release FORCEHT since chip is going to "down" state */ @@ -1675,7 +1666,7 @@ void si_pci_setup(si_t *sih, uint coremask) sii = SI_INFO(sih); - if (BUSTYPE(sii->pub.bustype) != PCI_BUS) + if (sii->pub.bustype != PCI_BUS) return; ASSERT(PCI(sii) || PCIE(sii)); @@ -1737,7 +1728,7 @@ int si_pci_fixcfg(si_t *sih) si_info_t *sii = SI_INFO(sih); - ASSERT(BUSTYPE(sii->pub.bustype) == PCI_BUS); + ASSERT(sii->pub.bustype == PCI_BUS); /* Fixup PI in SROM shadow area to enable the correct PCI core access */ /* save the current index */ @@ -1783,7 +1774,7 @@ u32 si_gpiocontrol(si_t *sih, u32 mask, u32 val, u8 priority) * ignore reservation if it's high priority (e.g., test apps) */ if ((priority != GPIO_HI_PRIORITY) && - (BUSTYPE(sih->bustype) == SI_BUS) && (val || mask)) { + (sih->bustype == SI_BUS) && (val || mask)) { mask = priority ? (si_gpioreservation & mask) : ((si_gpioreservation | mask) & ~(si_gpioreservation)); val &= mask; @@ -1935,7 +1926,7 @@ bool si_deviceremoved(si_t *sih) sii = SI_INFO(sih); - switch (BUSTYPE(sih->bustype)) { + switch (sih->bustype) { case PCI_BUS: ASSERT(sii->osh != NULL); pci_read_config_dword(sii->osh->pdev, PCI_CFG_VID, &w); -- cgit v1.2.3 From 8956110dbbb75773d851854e6e11cd8428fce71a Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Wed, 24 Nov 2010 11:46:09 -0800 Subject: staging: fix intel_sst/intelmid sound build SND_INTELMID selects 3 SND_* kconfig symbols, but that is useless if the SOUND & SND symbols in their hierarchy are not enabled, so make this symbol depend on SOUND & SND. ERROR: "snd_pcm_period_elapsed" [drivers/staging/intel_sst/snd-intelmid.ko] undefined! ERROR: "snd_card_create" [drivers/staging/intel_sst/snd-intelmid.ko] undefined! ERROR: "snd_pcm_hw_constraint_integer" [drivers/staging/intel_sst/snd-intelmid.ko] undefined! ERROR: "snd_device_new" [drivers/staging/intel_sst/snd-intelmid.ko] undefined! ERROR: "snd_pcm_set_ops" [drivers/staging/intel_sst/snd-intelmid.ko] undefined! ERROR: "snd_jack_new" [drivers/staging/intel_sst/snd-intelmid.ko] undefined! ERROR: "snd_pcm_lib_free_pages" [drivers/staging/intel_sst/snd-intelmid.ko] undefined! ERROR: "snd_pcm_lib_ioctl" [drivers/staging/intel_sst/snd-intelmid.ko] undefined! ERROR: "snd_pcm_lib_malloc_pages" [drivers/staging/intel_sst/snd-intelmid.ko] undefined! ERROR: "snd_ctl_new1" [drivers/staging/intel_sst/snd-intelmid.ko] undefined! ERROR: "snd_pcm_lib_preallocate_pages_for_all" [drivers/staging/intel_sst/snd-intelmid.ko] undefined! ERROR: "snd_card_free" [drivers/staging/intel_sst/snd-intelmid.ko] undefined! ERROR: "snd_card_register" [drivers/staging/intel_sst/snd-intelmid.ko] undefined! ERROR: "snd_jack_report" [drivers/staging/intel_sst/snd-intelmid.ko] undefined! ERROR: "snd_pcm_new" [drivers/staging/intel_sst/snd-intelmid.ko] undefined! ERROR: "snd_ctl_add" [drivers/staging/intel_sst/snd-intelmid.ko] undefined! Signed-off-by: Randy Dunlap Signed-off-by: Greg Kroah-Hartman --- drivers/staging/intel_sst/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/staging/intel_sst/Kconfig b/drivers/staging/intel_sst/Kconfig index b46bd9d1b324..82391077b384 100644 --- a/drivers/staging/intel_sst/Kconfig +++ b/drivers/staging/intel_sst/Kconfig @@ -8,6 +8,7 @@ config SND_INTEL_SST config SND_INTELMID tristate "Intel MID sound card driver" + depends on SOUND && SND select SND_PCM select SND_SEQUENCER select SND_JACK -- cgit v1.2.3 From 280740a9016db986758db811bbc998acc79e5551 Mon Sep 17 00:00:00 2001 From: Vasiliy Kulikov Date: Fri, 26 Nov 2010 20:06:53 +0300 Subject: staging: msm: tvenc: fix error handling Driver init() function should return error code. Also fix tvenc_clk leak. Signed-off-by: Vasiliy Kulikov Signed-off-by: Greg Kroah-Hartman --- drivers/staging/msm/tvenc.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/staging/msm/tvenc.c b/drivers/staging/msm/tvenc.c index f41c5ac22f25..4fbb77b253d3 100644 --- a/drivers/staging/msm/tvenc.c +++ b/drivers/staging/msm/tvenc.c @@ -279,12 +279,13 @@ static int __init tvenc_driver_init(void) if (IS_ERR(tvenc_clk)) { printk(KERN_ERR "error: can't get tvenc_clk!\n"); - return IS_ERR(tvenc_clk); + return PTR_ERR(tvenc_clk); } if (IS_ERR(tvdac_clk)) { printk(KERN_ERR "error: can't get tvdac_clk!\n"); - return IS_ERR(tvdac_clk); + clk_put(tvenc_clk); + return PTR_ERR(tvdac_clk); } // pm_qos_add_requirement(PM_QOS_SYSTEM_BUS_FREQ , "tvenc", -- cgit v1.2.3 From e93192acff4eaf7024c2450d91f3de69258f1f12 Mon Sep 17 00:00:00 2001 From: Al Cho Date: Fri, 26 Nov 2010 19:06:39 +0800 Subject: staging: keucr: fix keucr init coding style fix keucr init.c init.h coding style. only fix coding style check by checkpatch.pl. Signed-off-by: Al Cho Signed-off-by: Greg Kroah-Hartman --- drivers/staging/keucr/init.c | 415 ++++++++++++++++++++++--------------------- drivers/staging/keucr/init.h | 3 + 2 files changed, 217 insertions(+), 201 deletions(-) diff --git a/drivers/staging/keucr/init.c b/drivers/staging/keucr/init.c index 978bf87ff13d..e6c56deec94c 100644 --- a/drivers/staging/keucr/init.c +++ b/drivers/staging/keucr/init.c @@ -11,43 +11,37 @@ #include "transport.h" #include "init.h" -BYTE IsSSFDCCompliance; -BYTE IsXDCompliance; -extern DWORD MediaChange; -extern int Check_D_MediaFmt(struct us_data *); +BYTE IsSSFDCCompliance; +BYTE IsXDCompliance; -//----- ENE_InitMedia() ---------------------------------------- +/* + * ENE_InitMedia(): + */ int ENE_InitMedia(struct us_data *us) { int result; BYTE MiscReg03 = 0; - printk("--- Init Media ---\n"); + printk(KERN_INFO "--- Init Media ---\n"); result = ENE_Read_BYTE(us, REG_CARD_STATUS, &MiscReg03); - if (result != USB_STOR_XFER_GOOD) - { - printk("Read register fail !!\n"); + if (result != USB_STOR_XFER_GOOD) { + printk(KERN_ERR "Read register fail !!\n"); return USB_STOR_TRANSPORT_ERROR; } - printk("MiscReg03 = %x\n", MiscReg03); + printk(KERN_INFO "MiscReg03 = %x\n", MiscReg03); - if (MiscReg03 & 0x01) - { - if (!us->SD_Status.Ready) - { + if (MiscReg03 & 0x01) { + if (!us->SD_Status.Ready) { result = ENE_SDInit(us); if (result != USB_STOR_XFER_GOOD) return USB_STOR_TRANSPORT_ERROR; } } - if (MiscReg03 & 0x02) - { - if (!us->SM_Status.Ready && !us->MS_Status.Ready) - { + if (MiscReg03 & 0x02) { + if (!us->SM_Status.Ready && !us->MS_Status.Ready) { result = ENE_SMInit(us); - if (result != USB_STOR_XFER_GOOD) - { + if (result != USB_STOR_XFER_GOOD) { result = ENE_MSInit(us); if (result != USB_STOR_XFER_GOOD) return USB_STOR_TRANSPORT_ERROR; @@ -58,7 +52,9 @@ int ENE_InitMedia(struct us_data *us) return result; } -//----- ENE_Read_BYTE() ---------------------------------------- +/* + * ENE_Read_BYTE() : + */ int ENE_Read_BYTE(struct us_data *us, WORD index, void *buf) { struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf; @@ -76,19 +72,20 @@ int ENE_Read_BYTE(struct us_data *us, WORD index, void *buf) return result; } -//----- ENE_SDInit() --------------------- +/* + * ENE_SDInit(): + */ int ENE_SDInit(struct us_data *us) { struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf; int result; BYTE buf[0x200]; - printk("transport --- ENE_SDInit\n"); - // SD Init Part-1 + printk(KERN_INFO "transport --- ENE_SDInit\n"); + /* SD Init Part-1 */ result = ENE_LoadBinCode(us, SD_INIT1_PATTERN); - if (result != USB_STOR_XFER_GOOD) - { - printk("Load SD Init Code Part-1 Fail !!\n"); + if (result != USB_STOR_XFER_GOOD) { + printk(KERN_ERR "Load SD Init Code Part-1 Fail !!\n"); return USB_STOR_TRANSPORT_ERROR; } @@ -98,17 +95,15 @@ int ENE_SDInit(struct us_data *us) bcb->CDB[0] = 0xF2; result = ENE_SendScsiCmd(us, FDIR_READ, NULL, 0); - if (result != USB_STOR_XFER_GOOD) - { - printk("Exection SD Init Code Fail !!\n"); + if (result != USB_STOR_XFER_GOOD) { + printk(KERN_ERR "Exection SD Init Code Fail !!\n"); return USB_STOR_TRANSPORT_ERROR; } - // SD Init Part-2 + /* SD Init Part-2 */ result = ENE_LoadBinCode(us, SD_INIT2_PATTERN); - if (result != USB_STOR_XFER_GOOD) - { - printk("Load SD Init Code Part-2 Fail !!\n"); + if (result != USB_STOR_XFER_GOOD) { + printk(KERN_ERR "Load SD Init Code Part-2 Fail !!\n"); return USB_STOR_TRANSPORT_ERROR; } @@ -119,45 +114,41 @@ int ENE_SDInit(struct us_data *us) bcb->CDB[0] = 0xF1; result = ENE_SendScsiCmd(us, FDIR_READ, &buf, 0); - if (result != USB_STOR_XFER_GOOD) - { - printk("Exection SD Init Code Fail !!\n"); + if (result != USB_STOR_XFER_GOOD) { + printk(KERN_ERR "Exection SD Init Code Fail !!\n"); return USB_STOR_TRANSPORT_ERROR; } us->SD_Status = *(PSD_STATUS)&buf[0]; - if (us->SD_Status.Insert && us->SD_Status.Ready) - { + if (us->SD_Status.Insert && us->SD_Status.Ready) { ENE_ReadSDReg(us, (PBYTE)&buf); - printk("Insert = %x\n", us->SD_Status.Insert); - printk("Ready = %x\n", us->SD_Status.Ready); - printk("IsMMC = %x\n", us->SD_Status.IsMMC); - printk("HiCapacity = %x\n", us->SD_Status.HiCapacity); - printk("HiSpeed = %x\n", us->SD_Status.HiSpeed); - printk("WtP = %x\n", us->SD_Status.WtP); - } - else - { - printk("SD Card Not Ready --- %x\n", buf[0]); + printk(KERN_INFO "Insert = %x\n", us->SD_Status.Insert); + printk(KERN_INFO "Ready = %x\n", us->SD_Status.Ready); + printk(KERN_INFO "IsMMC = %x\n", us->SD_Status.IsMMC); + printk(KERN_INFO "HiCapacity = %x\n", us->SD_Status.HiCapacity); + printk(KERN_INFO "HiSpeed = %x\n", us->SD_Status.HiSpeed); + printk(KERN_INFO "WtP = %x\n", us->SD_Status.WtP); + } else { + printk(KERN_ERR "SD Card Not Ready --- %x\n", buf[0]); return USB_STOR_TRANSPORT_ERROR; } return USB_STOR_TRANSPORT_GOOD; } -//----- ENE_MSInit() ---------------------------------------- +/* + * ENE_MSInit(): + */ int ENE_MSInit(struct us_data *us) { struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf; int result; BYTE buf[0x200]; WORD MSP_BlockSize, MSP_UserAreaBlocks; - - printk("transport --- ENE_MSInit\n"); + printk(KERN_INFO "transport --- ENE_MSInit\n"); result = ENE_LoadBinCode(us, MS_INIT_PATTERN); - if (result != USB_STOR_XFER_GOOD) - { - printk("Load MS Init Code Fail !!\n"); + if (result != USB_STOR_XFER_GOOD) { + printk(KERN_ERR "Load MS Init Code Fail !!\n"); return USB_STOR_TRANSPORT_ERROR; } @@ -169,53 +160,49 @@ int ENE_MSInit(struct us_data *us) bcb->CDB[1] = 0x01; result = ENE_SendScsiCmd(us, FDIR_READ, &buf, 0); - if (result != USB_STOR_XFER_GOOD) - { - printk("Exection MS Init Code Fail !!\n"); + if (result != USB_STOR_XFER_GOOD) { + printk(KERN_ERR "Exection MS Init Code Fail !!\n"); return USB_STOR_TRANSPORT_ERROR; } us->MS_Status = *(PMS_STATUS)&buf[0]; - if (us->MS_Status.Insert && us->MS_Status.Ready) - { - printk("Insert = %x\n", us->MS_Status.Insert); - printk("Ready = %x\n", us->MS_Status.Ready); - printk("IsMSPro = %x\n", us->MS_Status.IsMSPro); - printk("IsMSPHG = %x\n", us->MS_Status.IsMSPHG); - printk("WtP = %x\n", us->MS_Status.WtP); - if (us->MS_Status.IsMSPro) - { - MSP_BlockSize = (buf[6] <<8) | buf[7]; - MSP_UserAreaBlocks = (buf[10]<<8) | buf[11]; + if (us->MS_Status.Insert && us->MS_Status.Ready) { + printk(KERN_INFO "Insert = %x\n", us->MS_Status.Insert); + printk(KERN_INFO "Ready = %x\n", us->MS_Status.Ready); + printk(KERN_INFO "IsMSPro = %x\n", us->MS_Status.IsMSPro); + printk(KERN_INFO "IsMSPHG = %x\n", us->MS_Status.IsMSPHG); + printk(KERN_INFO "WtP = %x\n", us->MS_Status.WtP); + if (us->MS_Status.IsMSPro) { + MSP_BlockSize = (buf[6] << 8) | buf[7]; + MSP_UserAreaBlocks = (buf[10] << 8) | buf[11]; us->MSP_TotalBlock = MSP_BlockSize * MSP_UserAreaBlocks; - } - else + } else { MS_CardInit(us); - printk("MS Init Code OK !!\n"); - } - else - { - printk("MS Card Not Ready --- %x\n", buf[0]); + } + printk(KERN_INFO "MS Init Code OK !!\n"); + } else { + printk(KERN_INFO "MS Card Not Ready --- %x\n", buf[0]); return USB_STOR_TRANSPORT_ERROR; } return USB_STOR_TRANSPORT_GOOD; } -//----- ENE_SMInit() ---------------------------------------- +/* + *ENE_SMInit() + */ int ENE_SMInit(struct us_data *us) { struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf; int result; BYTE buf[0x200]; - printk("transport --- ENE_SMInit\n"); + printk(KERN_INFO "transport --- ENE_SMInit\n"); result = ENE_LoadBinCode(us, SM_INIT_PATTERN); - if (result != USB_STOR_XFER_GOOD) - { - printk("Load SM Init Code Fail !!\n"); + if (result != USB_STOR_XFER_GOOD) { + printk(KERN_INFO "Load SM Init Code Fail !!\n"); return USB_STOR_TRANSPORT_ERROR; } @@ -227,9 +214,9 @@ int ENE_SMInit(struct us_data *us) bcb->CDB[1] = 0x01; result = ENE_SendScsiCmd(us, FDIR_READ, &buf, 0); - if (result != USB_STOR_XFER_GOOD) - { - printk("Exection SM Init Code Fail !! result = %x\n", result); + if (result != USB_STOR_XFER_GOOD) { + printk(KERN_ERR + "Exection SM Init Code Fail !! result = %x\n", result); return USB_STOR_TRANSPORT_ERROR; } @@ -238,32 +225,31 @@ int ENE_SMInit(struct us_data *us) us->SM_DeviceID = buf[1]; us->SM_CardID = buf[2]; - if (us->SM_Status.Insert && us->SM_Status.Ready) - { - printk("Insert = %x\n", us->SM_Status.Insert); - printk("Ready = %x\n", us->SM_Status.Ready); - printk("WtP = %x\n", us->SM_Status.WtP); - printk("DeviceID = %x\n", us->SM_DeviceID); - printk("CardID = %x\n", us->SM_CardID); + if (us->SM_Status.Insert && us->SM_Status.Ready) { + printk(KERN_INFO "Insert = %x\n", us->SM_Status.Insert); + printk(KERN_INFO "Ready = %x\n", us->SM_Status.Ready); + printk(KERN_INFO "WtP = %x\n", us->SM_Status.WtP); + printk(KERN_INFO "DeviceID = %x\n", us->SM_DeviceID); + printk(KERN_INFO "CardID = %x\n", us->SM_CardID); MediaChange = 1; Check_D_MediaFmt(us); - } - else - { - printk("SM Card Not Ready --- %x\n", buf[0]); + } else { + printk(KERN_ERR "SM Card Not Ready --- %x\n", buf[0]); return USB_STOR_TRANSPORT_ERROR; } return USB_STOR_TRANSPORT_GOOD; } -//----- ENE_ReadSDReg() ---------------------------------------------- +/* + * ENE_ReadSDReg() + */ int ENE_ReadSDReg(struct us_data *us, u8 *RdBuf) { WORD tmpreg; DWORD reg4b; - - //printk("transport --- ENE_ReadSDReg\n"); + + /* printk(KERN_INFO "transport --- ENE_ReadSDReg\n"); */ reg4b = *(PDWORD)&RdBuf[0x18]; us->SD_READ_BL_LEN = (BYTE)((reg4b >> 8) & 0x0f); @@ -277,74 +263,75 @@ int ENE_ReadSDReg(struct us_data *us, u8 *RdBuf) if (us->SD_Status.HiCapacity && us->SD_Status.IsMMC) us->HC_C_SIZE = *(PDWORD)(&RdBuf[0x100]); - if (us->SD_READ_BL_LEN > SD_BLOCK_LEN) - { - us->SD_Block_Mult = 1 << (us->SD_READ_BL_LEN - SD_BLOCK_LEN); us->SD_READ_BL_LEN = SD_BLOCK_LEN; - } - else - { us->SD_Block_Mult = 1; + if (us->SD_READ_BL_LEN > SD_BLOCK_LEN) { + us->SD_Block_Mult = + 1 << (us->SD_READ_BL_LEN - SD_BLOCK_LEN); + us->SD_READ_BL_LEN = SD_BLOCK_LEN; + } else { + us->SD_Block_Mult = 1; } return USB_STOR_TRANSPORT_GOOD; } -//----- ENE_LoadBinCode() --------------------- +/* + * ENE_LoadBinCode() + */ int ENE_LoadBinCode(struct us_data *us, BYTE flag) { struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf; int result; - //void *buf; + /* void *buf; */ PBYTE buf; - //printk("transport --- ENE_LoadBinCode\n"); + /* printk(KERN_INFO "transport --- ENE_LoadBinCode\n"); */ if (us->BIN_FLAG == flag) return USB_STOR_TRANSPORT_GOOD; buf = kmalloc(0x800, GFP_KERNEL); if (buf == NULL) return USB_STOR_TRANSPORT_ERROR; - switch ( flag ) - { - // For SD - case SD_INIT1_PATTERN: - printk("SD_INIT1_PATTERN\n"); - memcpy(buf, SD_Init1, 0x800); + switch (flag) { + /* For SD */ + case SD_INIT1_PATTERN: + printk(KERN_INFO "SD_INIT1_PATTERN\n"); + memcpy(buf, SD_Init1, 0x800); break; - case SD_INIT2_PATTERN: - printk("SD_INIT2_PATTERN\n"); - memcpy(buf, SD_Init2, 0x800); + case SD_INIT2_PATTERN: + printk(KERN_INFO "SD_INIT2_PATTERN\n"); + memcpy(buf, SD_Init2, 0x800); break; - case SD_RW_PATTERN: - printk("SD_RW_PATTERN\n"); - memcpy(buf, SD_Rdwr, 0x800); + case SD_RW_PATTERN: + printk(KERN_INFO "SD_RW_PATTERN\n"); + memcpy(buf, SD_Rdwr, 0x800); break; - // For MS - case MS_INIT_PATTERN: - printk("MS_INIT_PATTERN\n"); - memcpy(buf, MS_Init, 0x800); + /* For MS */ + case MS_INIT_PATTERN: + printk(KERN_INFO "MS_INIT_PATTERN\n"); + memcpy(buf, MS_Init, 0x800); break; - case MSP_RW_PATTERN: - printk("MSP_RW_PATTERN\n"); - memcpy(buf, MSP_Rdwr, 0x800); + case MSP_RW_PATTERN: + printk(KERN_INFO "MSP_RW_PATTERN\n"); + memcpy(buf, MSP_Rdwr, 0x800); break; - case MS_RW_PATTERN: - printk("MS_RW_PATTERN\n"); - memcpy(buf, MS_Rdwr, 0x800); + case MS_RW_PATTERN: + printk(KERN_INFO "MS_RW_PATTERN\n"); + memcpy(buf, MS_Rdwr, 0x800); break; - // For SS - case SM_INIT_PATTERN: - printk("SM_INIT_PATTERN\n"); - memcpy(buf, SM_Init, 0x800); + /* For SS */ + case SM_INIT_PATTERN: + printk(KERN_INFO "SM_INIT_PATTERN\n"); + memcpy(buf, SM_Init, 0x800); break; - case SM_RW_PATTERN: - printk("SM_RW_PATTERN\n"); - memcpy(buf, SM_Rdwr, 0x800); + case SM_RW_PATTERN: + printk(KERN_INFO "SM_RW_PATTERN\n"); + memcpy(buf, SM_Rdwr, 0x800); break; } memset(bcb, 0, sizeof(struct bulk_cb_wrap)); bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); bcb->DataTransferLength = 0x800; - bcb->Flags =0x00; + bcb->Flags = 0x00; bcb->CDB[0] = 0xEF; result = ENE_SendScsiCmd(us, FDIR_WRITE, buf, 0); @@ -354,54 +341,58 @@ int ENE_LoadBinCode(struct us_data *us, BYTE flag) return result; } -//----- ENE_SendScsiCmd() --------------------- +/* + * ENE_SendScsiCmd(): + */ int ENE_SendScsiCmd(struct us_data *us, BYTE fDir, void *buf, int use_sg) { struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf; struct bulk_cs_wrap *bcs = (struct bulk_cs_wrap *) us->iobuf; int result; - unsigned int transfer_length=bcb->DataTransferLength, cswlen=0, partial=0; + unsigned int transfer_length = bcb->DataTransferLength, + cswlen = 0, partial = 0; unsigned int residue; - //printk("transport --- ENE_SendScsiCmd\n"); - // send cmd to out endpoint - result = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe, bcb, US_BULK_CB_WRAP_LEN, NULL); - if (result != USB_STOR_XFER_GOOD) - { - printk("send cmd to out endpoint fail ---\n"); + /* printk(KERN_INFO "transport --- ENE_SendScsiCmd\n"); */ + /* send cmd to out endpoint */ + result = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe, + bcb, US_BULK_CB_WRAP_LEN, NULL); + if (result != USB_STOR_XFER_GOOD) { + printk(KERN_ERR "send cmd to out endpoint fail ---\n"); return USB_STOR_TRANSPORT_ERROR; } - if (buf) - { - unsigned int pipe = fDir == FDIR_READ ? us->recv_bulk_pipe : us->send_bulk_pipe; - // Bulk + if (buf) { + unsigned int pipe = fDir == + FDIR_READ ? us->recv_bulk_pipe : us->send_bulk_pipe; + /* Bulk */ if (use_sg) result = usb_stor_bulk_srb(us, pipe, us->srb); else - result = usb_stor_bulk_transfer_sg(us, pipe, buf, transfer_length, 0, &partial); - if (result != USB_STOR_XFER_GOOD) - { - printk("data transfer fail ---\n"); + result = usb_stor_bulk_transfer_sg(us, pipe, buf, + transfer_length, 0, &partial); + if (result != USB_STOR_XFER_GOOD) { + printk(KERN_ERR "data transfer fail ---\n"); return USB_STOR_TRANSPORT_ERROR; } } - // Get CSW for device status - result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, bcs, US_BULK_CS_WRAP_LEN, &cswlen); + /* Get CSW for device status */ + result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, bcs, + US_BULK_CS_WRAP_LEN, &cswlen); - if (result == USB_STOR_XFER_SHORT && cswlen == 0) - { - printk("Received 0-length CSW; retrying...\n"); - result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, bcs, US_BULK_CS_WRAP_LEN, &cswlen); + if (result == USB_STOR_XFER_SHORT && cswlen == 0) { + printk(KERN_WARNING "Received 0-length CSW; retrying...\n"); + result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, + bcs, US_BULK_CS_WRAP_LEN, &cswlen); } - if (result == USB_STOR_XFER_STALLED) - { + if (result == USB_STOR_XFER_STALLED) { /* get the status again */ - printk("Attempting to get CSW (2nd try)...\n"); - result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, bcs, US_BULK_CS_WRAP_LEN, NULL); + printk(KERN_WARNING "Attempting to get CSW (2nd try)...\n"); + result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, + bcs, US_BULK_CS_WRAP_LEN, NULL); } if (result != USB_STOR_XFER_GOOD) @@ -410,12 +401,14 @@ int ENE_SendScsiCmd(struct us_data *us, BYTE fDir, void *buf, int use_sg) /* check bulk status */ residue = le32_to_cpu(bcs->Residue); - /* try to compute the actual residue, based on how much data - * was really transferred and what the device tells us */ - if (residue && !(us->fflags & US_FL_IGNORE_RESIDUE)) - { + /* + * try to compute the actual residue, based on how much data + * was really transferred and what the device tells us + */ + if (residue && !(us->fflags & US_FL_IGNORE_RESIDUE)) { residue = min(residue, transfer_length); - scsi_set_resid(us->srb, max(scsi_get_resid(us->srb), (int) residue)); + scsi_set_resid(us->srb, max(scsi_get_resid(us->srb), + (int) residue)); } if (bcs->Status != US_BULK_STAT_OK) @@ -424,35 +417,40 @@ int ENE_SendScsiCmd(struct us_data *us, BYTE fDir, void *buf, int use_sg) return USB_STOR_TRANSPORT_GOOD; } -//----- ENE_Read_Data() --------------------- +/* + * ENE_Read_Data() + */ int ENE_Read_Data(struct us_data *us, void *buf, unsigned int length) { struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf; struct bulk_cs_wrap *bcs = (struct bulk_cs_wrap *) us->iobuf; int result; - //printk("transport --- ENE_Read_Data\n"); - // set up the command wrapper + /* printk(KERN_INFO "transport --- ENE_Read_Data\n"); */ + /* set up the command wrapper */ memset(bcb, 0, sizeof(struct bulk_cb_wrap)); bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); bcb->DataTransferLength = length; - bcb->Flags =0x80; + bcb->Flags = 0x80; bcb->CDB[0] = 0xED; bcb->CDB[2] = 0xFF; bcb->CDB[3] = 0x81; - // send cmd to out endpoint - result = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe, bcb, US_BULK_CB_WRAP_LEN, NULL); + /* send cmd to out endpoint */ + result = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe, bcb, + US_BULK_CB_WRAP_LEN, NULL); if (result != USB_STOR_XFER_GOOD) return USB_STOR_TRANSPORT_ERROR; - // R/W data - result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, buf, length, NULL); + /* R/W data */ + result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, + buf, length, NULL); if (result != USB_STOR_XFER_GOOD) return USB_STOR_TRANSPORT_ERROR; - // Get CSW for device status - result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, bcs, US_BULK_CS_WRAP_LEN, NULL); + /* Get CSW for device status */ + result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, bcs, + US_BULK_CS_WRAP_LEN, NULL); if (result != USB_STOR_XFER_GOOD) return USB_STOR_TRANSPORT_ERROR; if (bcs->Status != US_BULK_STAT_OK) @@ -461,35 +459,40 @@ int ENE_Read_Data(struct us_data *us, void *buf, unsigned int length) return USB_STOR_TRANSPORT_GOOD; } -//----- ENE_Write_Data() --------------------- +/* + * ENE_Write_Data(): + */ int ENE_Write_Data(struct us_data *us, void *buf, unsigned int length) { struct bulk_cb_wrap *bcb = (struct bulk_cb_wrap *) us->iobuf; struct bulk_cs_wrap *bcs = (struct bulk_cs_wrap *) us->iobuf; int result; - //printk("transport --- ENE_Write_Data\n"); - // set up the command wrapper + /* printk("transport --- ENE_Write_Data\n"); */ + /* set up the command wrapper */ memset(bcb, 0, sizeof(struct bulk_cb_wrap)); bcb->Signature = cpu_to_le32(US_BULK_CB_SIGN); bcb->DataTransferLength = length; - bcb->Flags =0x00; + bcb->Flags = 0x00; bcb->CDB[0] = 0xEE; bcb->CDB[2] = 0xFF; bcb->CDB[3] = 0x81; - // send cmd to out endpoint - result = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe, bcb, US_BULK_CB_WRAP_LEN, NULL); + /* send cmd to out endpoint */ + result = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe, bcb, + US_BULK_CB_WRAP_LEN, NULL); if (result != USB_STOR_XFER_GOOD) return USB_STOR_TRANSPORT_ERROR; - // R/W data - result = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe, buf, length, NULL); + /* R/W data */ + result = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe, + buf, length, NULL); if (result != USB_STOR_XFER_GOOD) return USB_STOR_TRANSPORT_ERROR; - // Get CSW for device status - result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, bcs, US_BULK_CS_WRAP_LEN, NULL); + /* Get CSW for device status */ + result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, bcs, + US_BULK_CS_WRAP_LEN, NULL); if (result != USB_STOR_XFER_GOOD) return USB_STOR_TRANSPORT_ERROR; if (bcs->Status != US_BULK_STAT_OK) @@ -498,42 +501,52 @@ int ENE_Write_Data(struct us_data *us, void *buf, unsigned int length) return USB_STOR_TRANSPORT_GOOD; } -//----- usb_stor_print_cmd() --------------------- +/* + * usb_stor_print_cmd(): + */ void usb_stor_print_cmd(struct scsi_cmnd *srb) { PBYTE Cdb = srb->cmnd; DWORD cmd = Cdb[0]; - DWORD bn = ((Cdb[2]<<24) & 0xff000000) | ((Cdb[3]<<16) & 0x00ff0000) | - ((Cdb[4]<< 8) & 0x0000ff00) | ((Cdb[5]<< 0) & 0x000000ff); - WORD blen = ((Cdb[7]<< 8) & 0xff00) | ((Cdb[8]<< 0) & 0x00ff); + DWORD bn = ((Cdb[2] << 24) & 0xff000000) | + ((Cdb[3] << 16) & 0x00ff0000) | + ((Cdb[4] << 8) & 0x0000ff00) | + ((Cdb[5] << 0) & 0x000000ff); + WORD blen = ((Cdb[7] << 8) & 0xff00) | ((Cdb[8] << 0) & 0x00ff); switch (cmd) { case TEST_UNIT_READY: - //printk("scsi cmd %X --- SCSIOP_TEST_UNIT_READY\n", cmd); + /* printk(KERN_INFO + "scsi cmd %X --- SCSIOP_TEST_UNIT_READY\n", cmd); */ break; case INQUIRY: - printk("scsi cmd %X --- SCSIOP_INQUIRY\n", cmd); + printk(KERN_INFO "scsi cmd %X --- SCSIOP_INQUIRY\n", cmd); break; case MODE_SENSE: - printk("scsi cmd %X --- SCSIOP_MODE_SENSE\n", cmd); + printk(KERN_INFO "scsi cmd %X --- SCSIOP_MODE_SENSE\n", cmd); break; case START_STOP: - printk("scsi cmd %X --- SCSIOP_START_STOP\n", cmd); + printk(KERN_INFO "scsi cmd %X --- SCSIOP_START_STOP\n", cmd); break; case READ_CAPACITY: - printk("scsi cmd %X --- SCSIOP_READ_CAPACITY\n", cmd); + printk(KERN_INFO "scsi cmd %X --- SCSIOP_READ_CAPACITY\n", cmd); break; case READ_10: - //printk("scsi cmd %X --- SCSIOP_READ, bn = %X, blen = %X\n", cmd, bn, blen); + /* printk(KERN_INFO + "scsi cmd %X --- SCSIOP_READ,bn = %X, blen = %X\n" + ,cmd, bn, blen); */ break; case WRITE_10: - //printk("scsi cmd %X --- SCSIOP_WRITE, bn = %X, blen = %X\n", cmd, bn, blen); + /* printk(KERN_INFO + "scsi cmd %X --- SCSIOP_WRITE, + bn = %X, blen = %X\n" , cmd, bn, blen); */ break; case ALLOW_MEDIUM_REMOVAL: - printk("scsi cmd %X --- SCSIOP_ALLOW_MEDIUM_REMOVAL\n", cmd); + printk(KERN_INFO + "scsi cmd %X --- SCSIOP_ALLOW_MEDIUM_REMOVAL\n", cmd); break; default: - printk("scsi cmd %X --- Other cmd\n", cmd); + printk(KERN_INFO "scsi cmd %X --- Other cmd\n", cmd); break; } bn = 0; diff --git a/drivers/staging/keucr/init.h b/drivers/staging/keucr/init.h index cd199fc1e6d5..5223132a6c24 100644 --- a/drivers/staging/keucr/init.h +++ b/drivers/staging/keucr/init.h @@ -1,5 +1,8 @@ #include "common.h" +extern DWORD MediaChange; +extern int Check_D_MediaFmt(struct us_data *); + BYTE SD_Init1[] = { 0x90, 0xFF, 0x09, 0xE0, 0x30, 0xE1, 0x06, 0x90, 0xFF, 0x23, 0x74, 0x80, 0xF0, 0x90, 0xFF, 0x09, -- cgit v1.2.3 From 6efe04ee4109a9d3fc0d419667f54861628b0d45 Mon Sep 17 00:00:00 2001 From: Al Cho Date: Fri, 26 Nov 2010 19:07:27 +0800 Subject: staging: keucr: fix keucr init other coding style fix keucr init.c other coding style but not from checkpatch.pl. replace ternary conditional "?:" with if/else. Signed-off-by: Al Cho Signed-off-by: Greg Kroah-Hartman --- drivers/staging/keucr/init.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/staging/keucr/init.c b/drivers/staging/keucr/init.c index e6c56deec94c..515e448852a0 100644 --- a/drivers/staging/keucr/init.c +++ b/drivers/staging/keucr/init.c @@ -364,8 +364,13 @@ int ENE_SendScsiCmd(struct us_data *us, BYTE fDir, void *buf, int use_sg) } if (buf) { - unsigned int pipe = fDir == - FDIR_READ ? us->recv_bulk_pipe : us->send_bulk_pipe; + unsigned int pipe = fDir; + + if (fDir == FDIR_READ) + pipe = us->recv_bulk_pipe; + else + pipe = us->send_bulk_pipe; + /* Bulk */ if (use_sg) result = usb_stor_bulk_srb(us, pipe, us->srb); -- cgit v1.2.3 From e999fb057436c2167d5ee3f5c82753e953981525 Mon Sep 17 00:00:00 2001 From: Marek Belisko Date: Tue, 23 Nov 2010 13:29:28 +0100 Subject: staging: ft1000: Remove functions which create devices in kernel space. Remove exec_mknod() and rm_mknod() helpers which was used for device nodes creating/removing in kernel space. Signed-off-by: Marek Belisko Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ft1000/ft1000-usb/ft1000_chdev.c | 93 ------------------------ 1 file changed, 93 deletions(-) diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_chdev.c b/drivers/staging/ft1000/ft1000-usb/ft1000_chdev.c index 76cee9e30624..1aec926c993c 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_chdev.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_chdev.c @@ -78,88 +78,6 @@ static struct file_operations ft1000fops = .llseek = no_llseek, }; - - - -//--------------------------------------------------------------------------- -// Function: exec_mknod -// -// Parameters: -// -// Returns: -// -// Description: -// -// Notes: -// -//--------------------------------------------------------------------------- -static int exec_mknod (void *pdata) -{ - struct ft1000_info *info; - char mjnum[4]; - char minornum[4]; - char temp[32]; - int retcode; -// int i; //aelias [-] reason : unused variable - char *envp[] = { "HOME=/", "PATH=/usr/bin:/bin", NULL }; - char *argv[]={"-m 666",temp,"c",mjnum,minornum,NULL}; - - info = pdata; - DEBUG("ft1000_chdev:exec_mknod is called with major number = %d\n", info->DeviceMajor); - sprintf(temp, "%s%s", "/dev/", info->DeviceName) ; - sprintf(mjnum, "%d", info->DeviceMajor); - sprintf(minornum, "%d", info->CardNumber); - - //char *argv[]={"mknod","-m 666",temp,"c",mjnum,minornum,NULL}; -// char *argv[]={"-m 666",temp,"c",mjnum,minornum,NULL}; - - //for (i=0; i<7;i++) - // DEBUG("argv[%d]=%s\n", i, argv[i]); - - - retcode = call_usermodehelper ("/bin/mknod", argv, envp, 1); - if (retcode) { - DEBUG("ft1000_chdev:exec_mknod failed to make the node: retcode = %d\n", retcode); - } - - - - return retcode; - -} - -//--------------------------------------------------------------------------- -// Function: rm_mknod -// -// Description: This module removes the FT1000 device file -// -//--------------------------------------------------------------------------- -static int rm_mknod (void *pdata) -{ - - struct ft1000_info *info; - //char *argv[4]={"rm", "-f", "/dev/FT1000", NULL}; - int retcode; - char temp[32]; - char *argv[]={"rm", "-f", temp, NULL}; - - info = (struct ft1000_info *)pdata; - DEBUG("ft1000_chdev:rm_mknod is called for device %s\n", info->DeviceName); - sprintf(temp, "%s%s", "/dev/", info->DeviceName) ; - -// char *argv[]={"rm", "-f", temp, NULL}; - - retcode = call_usermodehelper ("/bin/rm", argv, NULL, 1); - if (retcode) { - DEBUG("ft1000_chdev:rm_mknod failed to remove the node: retcode = %d\n", retcode); - } - else - DEBUG("ft1000_chdev:rm_mknod done!\n"); - - - return retcode; - -} //--------------------------------------------------------------------------- // Function: ft1000_get_buffer // @@ -238,15 +156,10 @@ int ft1000_CreateDevice(struct ft1000_device *dev) struct ft1000_info *info = netdev_priv(dev->net); int result; int i; - pid_t pid; // make a new device name sprintf(info->DeviceName, "%s%d", "FT100", info->CardNumber); - // Delete any existing FT1000 node - pid = kernel_thread (rm_mknod,(void *)info, 0); - msleep(1000); - DEBUG("ft1000_CreateDevice: number of instance = %d\n", ft1000_flarion_cnt); DEBUG("DeviceCreated = %x\n", info->DeviceCreated); @@ -282,9 +195,6 @@ int ft1000_CreateDevice(struct ft1000_device *dev) DEBUG("ft1000_PcdCreateDevice: device major = %d\n", info->DeviceMajor); } - // Create a thread to call user mode app to mknod - pid = kernel_thread (exec_mknod, (void *)info, 0); - // initialize application information // if (ft1000_flarion_cnt == 0) { @@ -350,7 +260,6 @@ void ft1000_DestroyDevice(struct net_device *dev) { struct ft1000_info *info = netdev_priv(dev); int result = 0; - pid_t pid; int i; struct dpram_blk *pdpram_blk; struct dpram_blk *ptr; @@ -366,8 +275,6 @@ void ft1000_DestroyDevice(struct net_device *dev) DEBUG("ft1000_DestroyDevice: unregistered device \"%s\", result = %d\n", info->DeviceName, result); - pid = kernel_thread (rm_mknod, (void *)info, 0); - // Make sure we free any memory reserve for slow Queue for (i=0; iapp_info[i].app_sqlist) == 0) { -- cgit v1.2.3 From 4960b8fe1b0602195e2170bb94d50edc47d36d73 Mon Sep 17 00:00:00 2001 From: Marek Belisko Date: Wed, 24 Nov 2010 10:42:39 +0100 Subject: staging: ft1000: Fix goto error logic. Fix goto error logic which could lead to kernel panics because kthread_stop() is called in not correct error conditions. Seen it sometimes when dsp_reload() fails then I got kernel panic. Signed-off-by: Marek Belisko Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ft1000/ft1000-usb/ft1000_usb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_usb.c b/drivers/staging/ft1000/ft1000-usb/ft1000_usb.c index f88ff86df177..d71ac30629f5 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_usb.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_usb.c @@ -204,9 +204,9 @@ static int ft1000_probe(struct usb_interface *interface, return 0; -err_load: - kthread_stop(pft1000info->pPollThread); err_thread: + kthread_stop(pft1000info->pPollThread); +err_load: kfree(pFileStart); err_fw: kfree(ft1000dev); -- cgit v1.2.3 From e030d58e8860f1c87b17631dbdd70747cbe1fb5b Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Mon, 15 Nov 2010 15:46:07 -0500 Subject: sysfs: remove useless test from sysfs_merge_group Dan Carpenter pointed out that the new sysfs_merge_group() and sysfs_unmerge_group() routines requires their grp argument to be non-NULL, because they dereference grp to obtain the list of attributes. Hence it's pointless for the routines to include a test and special-case handling for when grp is NULL. This patch (as1433) removes the unneeded tests. Signed-off-by: Alan Stern CC: Dan Carpenter Signed-off-by: Greg Kroah-Hartman --- fs/sysfs/group.c | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/fs/sysfs/group.c b/fs/sysfs/group.c index 442f34ff1af8..c8769dc222d8 100644 --- a/fs/sysfs/group.c +++ b/fs/sysfs/group.c @@ -165,10 +165,7 @@ int sysfs_merge_group(struct kobject *kobj, struct attribute *const *attr; int i; - if (grp) - dir_sd = sysfs_get_dirent(kobj->sd, NULL, grp->name); - else - dir_sd = sysfs_get(kobj->sd); + dir_sd = sysfs_get_dirent(kobj->sd, NULL, grp->name); if (!dir_sd) return -ENOENT; @@ -195,10 +192,7 @@ void sysfs_unmerge_group(struct kobject *kobj, struct sysfs_dirent *dir_sd; struct attribute *const *attr; - if (grp) - dir_sd = sysfs_get_dirent(kobj->sd, NULL, grp->name); - else - dir_sd = sysfs_get(kobj->sd); + dir_sd = sysfs_get_dirent(kobj->sd, NULL, grp->name); if (dir_sd) { for (attr = grp->attrs; *attr; ++attr) sysfs_hash_and_remove(dir_sd, NULL, (*attr)->name); -- cgit v1.2.3 From c6c0ac664c86ff6408fadbed4913938c8a732e26 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Thu, 25 Nov 2010 09:44:07 +1100 Subject: driver core: Document that device_rename() is only for networking Document that device_rename() is not to be used by anything other than the network core. Signed-off-by: Michael Ellerman Signed-off-by: Greg Kroah-Hartman --- drivers/base/core.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/base/core.c b/drivers/base/core.c index 46ff6c251932..610d967632cd 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c @@ -1513,6 +1513,8 @@ EXPORT_SYMBOL_GPL(device_destroy); * exclusion between two different calls of device_rename * on the same device to ensure that new_name is valid and * won't conflict with other devices. + * + * "Never use this function, bad things will happen" - gregkh */ int device_rename(struct device *dev, const char *new_name) { -- cgit v1.2.3 From 74d51d029818eca9d1aec22dd2895e269c0044b1 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Thu, 29 Jul 2010 14:45:24 +1000 Subject: powerpc/nvram: Move things out of asm/nvram.h This moves a bunch of definitions out of asm/nvram.h to the files that use them or just outright remove completely unused stuff. We leave the partition signatures definitions, they will be useful Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/include/asm/nvram.h | 42 ++-------------------------------- arch/powerpc/kernel/nvram_64.c | 21 ++++++++++++++++- arch/powerpc/platforms/chrp/time.c | 4 ++++ arch/powerpc/platforms/pseries/nvram.c | 2 ++ 4 files changed, 28 insertions(+), 41 deletions(-) diff --git a/arch/powerpc/include/asm/nvram.h b/arch/powerpc/include/asm/nvram.h index 850b72f27445..459dc09ecbd8 100644 --- a/arch/powerpc/include/asm/nvram.h +++ b/arch/powerpc/include/asm/nvram.h @@ -10,31 +10,7 @@ #ifndef _ASM_POWERPC_NVRAM_H #define _ASM_POWERPC_NVRAM_H -#include - -#define NVRW_CNT 0x20 -#define NVRAM_HEADER_LEN 16 /* sizeof(struct nvram_header) */ -#define NVRAM_BLOCK_LEN 16 -#define NVRAM_MAX_REQ (2080/NVRAM_BLOCK_LEN) -#define NVRAM_MIN_REQ (1056/NVRAM_BLOCK_LEN) - -#define NVRAM_AS0 0x74 -#define NVRAM_AS1 0x75 -#define NVRAM_DATA 0x77 - - -/* RTC Offsets */ - -#define MOTO_RTC_SECONDS 0x1FF9 -#define MOTO_RTC_MINUTES 0x1FFA -#define MOTO_RTC_HOURS 0x1FFB -#define MOTO_RTC_DAY_OF_WEEK 0x1FFC -#define MOTO_RTC_DAY_OF_MONTH 0x1FFD -#define MOTO_RTC_MONTH 0x1FFE -#define MOTO_RTC_YEAR 0x1FFF -#define MOTO_RTC_CONTROLA 0x1FF8 -#define MOTO_RTC_CONTROLB 0x1FF9 - +/* Signatures for nvram partitions */ #define NVRAM_SIG_SP 0x02 /* support processor */ #define NVRAM_SIG_OF 0x50 /* open firmware config */ #define NVRAM_SIG_FW 0x51 /* general firmware */ @@ -49,25 +25,11 @@ #define NVRAM_SIG_OS 0xa0 /* OS defined */ #define NVRAM_SIG_PANIC 0xa1 /* Apple OSX "panic" */ -/* If change this size, then change the size of NVNAME_LEN */ -struct nvram_header { - unsigned char signature; - unsigned char checksum; - unsigned short length; - char name[12]; -}; - #ifdef __KERNEL__ +#include #include -struct nvram_partition { - struct list_head partition; - struct nvram_header header; - unsigned int index; -}; - - extern int nvram_write_error_log(char * buff, int length, unsigned int err_type, unsigned int err_seq); extern int nvram_read_error_log(char * buff, int length, diff --git a/arch/powerpc/kernel/nvram_64.c b/arch/powerpc/kernel/nvram_64.c index 9cf197f01e94..a8154f1813df 100644 --- a/arch/powerpc/kernel/nvram_64.c +++ b/arch/powerpc/kernel/nvram_64.c @@ -34,6 +34,25 @@ #undef DEBUG_NVRAM +#define NVRAM_HEADER_LEN 16 /* sizeof(struct nvram_header) */ +#define NVRAM_BLOCK_LEN 16 +#define NVRAM_MAX_REQ (2080/NVRAM_BLOCK_LEN) +#define NVRAM_MIN_REQ (1056/NVRAM_BLOCK_LEN) + +/* If change this size, then change the size of NVNAME_LEN */ +struct nvram_header { + unsigned char signature; + unsigned char checksum; + unsigned short length; + char name[12]; +}; + +struct nvram_partition { + struct list_head partition; + struct nvram_header header; + unsigned int index; +}; + static struct nvram_partition * nvram_part; static long nvram_error_log_index = -1; static long nvram_error_log_size = 0; @@ -432,7 +451,7 @@ static int __init nvram_setup_partition(void) } /* try creating a partition with the free space we have */ - rc = nvram_create_os_partition(); + rc = nvram_create_partition("ppc64,linux", ); if (!rc) { return 0; } diff --git a/arch/powerpc/platforms/chrp/time.c b/arch/powerpc/platforms/chrp/time.c index 054dfe5b8e77..f803f4b8ab6f 100644 --- a/arch/powerpc/platforms/chrp/time.c +++ b/arch/powerpc/platforms/chrp/time.c @@ -29,6 +29,10 @@ extern spinlock_t rtc_lock; +#define NVRAM_AS0 0x74 +#define NVRAM_AS1 0x75 +#define NVRAM_DATA 0x77 + static int nvram_as1 = NVRAM_AS1; static int nvram_as0 = NVRAM_AS0; static int nvram_data = NVRAM_DATA; diff --git a/arch/powerpc/platforms/pseries/nvram.c b/arch/powerpc/platforms/pseries/nvram.c index bc3c7f2abd79..f4e4c06284b4 100644 --- a/arch/powerpc/platforms/pseries/nvram.c +++ b/arch/powerpc/platforms/pseries/nvram.c @@ -27,6 +27,8 @@ static int nvram_fetch, nvram_store; static char nvram_buf[NVRW_CNT]; /* assume this is in the first 4GB */ static DEFINE_SPINLOCK(nvram_lock); +/* Max bytes to read/write in one go */ +#define NVRW_CNT 0x20 static ssize_t pSeries_nvram_read(char *buf, size_t count, loff_t *index) { -- cgit v1.2.3 From 4e7c77a385efac81d6677a4a761b1b66cd2cb59e Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Thu, 29 Jul 2010 15:28:20 +1000 Subject: powerpc/nvram: More flexible nvram_create_partition() Replace nvram_create_os_partition() with a variant that takes the partition name, signature and size as arguments. Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/nvram_64.c | 46 +++++++++++++++++++++------------- arch/powerpc/platforms/pseries/nvram.c | 6 ++--- 2 files changed, 31 insertions(+), 21 deletions(-) diff --git a/arch/powerpc/kernel/nvram_64.c b/arch/powerpc/kernel/nvram_64.c index a8154f1813df..9e133355f742 100644 --- a/arch/powerpc/kernel/nvram_64.c +++ b/arch/powerpc/kernel/nvram_64.c @@ -307,13 +307,15 @@ static int __init nvram_remove_os_partition(void) return 0; } -/* nvram_create_os_partition - * - * Create a OS linux partition to buffer error logs. - * Will create a partition starting at the first free - * space found if space has enough room. +/** + * nvram_create_partition - Create a partition in nvram + * @name: name of the partition to create + * @sig: signature of the partition to create + * @req_size: size to allocate preferrably + * @min_size: minimum acceptable size (0 means req_size) */ -static int __init nvram_create_os_partition(void) +static int __init nvram_create_partition(const char *name, int sig, + int req_size, int min_size) { struct nvram_partition *part; struct nvram_partition *new_part; @@ -322,20 +324,27 @@ static int __init nvram_create_os_partition(void) loff_t tmp_index; long size = 0; int rc; - + + /* If no minimum size specified, make it the same as the + * requested size + */ + if (min_size == 0) + min_size = req_size; + /* Find a free partition that will give us the maximum needed size If can't find one that will give us the minimum size needed */ list_for_each_entry(part, &nvram_part->partition, partition) { if (part->header.signature != NVRAM_SIG_FREE) continue; - if (part->header.length >= NVRAM_MAX_REQ) { - size = NVRAM_MAX_REQ; + if (part->header.length >= req_size) { + size = req_size; free_part = part; break; } - if (!size && part->header.length >= NVRAM_MIN_REQ) { - size = NVRAM_MIN_REQ; + if (part->header.length > size && + part->header.length >= min_size) { + size = part->header.length; free_part = part; } } @@ -350,9 +359,9 @@ static int __init nvram_create_os_partition(void) } new_part->index = free_part->index; - new_part->header.signature = NVRAM_SIG_OS; + new_part->header.signature = sig; new_part->header.length = size; - strcpy(new_part->header.name, "ppc64,linux"); + strncpy(new_part->header.name, name, 12); new_part->header.checksum = nvram_checksum(&new_part->header); rc = nvram_write_header(new_part); @@ -451,10 +460,10 @@ static int __init nvram_setup_partition(void) } /* try creating a partition with the free space we have */ - rc = nvram_create_partition("ppc64,linux", ); - if (!rc) { + rc = nvram_create_partition("ppc64,linux", NVRAM_SIG_OS, + NVRAM_MAX_REQ, NVRAM_MIN_REQ); + if (!rc) return 0; - } /* need to free up some space */ rc = nvram_remove_os_partition(); @@ -463,9 +472,10 @@ static int __init nvram_setup_partition(void) } /* create a partition in this new space */ - rc = nvram_create_os_partition(); + rc = nvram_create_partition("ppc64,linux", NVRAM_SIG_OS, + NVRAM_MAX_REQ, NVRAM_MIN_REQ); if (rc) { - printk(KERN_ERR "nvram_create_os_partition: Could not find a " + printk(KERN_ERR "nvram_create_partition: Could not find a " "NVRAM partition large enough\n"); return rc; } diff --git a/arch/powerpc/platforms/pseries/nvram.c b/arch/powerpc/platforms/pseries/nvram.c index f4e4c06284b4..2a1ef5c25344 100644 --- a/arch/powerpc/platforms/pseries/nvram.c +++ b/arch/powerpc/platforms/pseries/nvram.c @@ -22,14 +22,14 @@ #include #include +/* Max bytes to read/write in one go */ +#define NVRW_CNT 0x20 + static unsigned int nvram_size; static int nvram_fetch, nvram_store; static char nvram_buf[NVRW_CNT]; /* assume this is in the first 4GB */ static DEFINE_SPINLOCK(nvram_lock); -/* Max bytes to read/write in one go */ -#define NVRW_CNT 0x20 - static ssize_t pSeries_nvram_read(char *buf, size_t count, loff_t *index) { unsigned int i; -- cgit v1.2.3 From 36673307aee535f951f4eede81049c6962bc4ba9 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Thu, 29 Jul 2010 18:18:44 +1000 Subject: powerpc/nvram: nvram_create_partitions() now uses bytes This converts nvram_create_partition() to use a size in bytes rather than blocks. It does the appropriate alignment internally The size passed is also the data size (ie. doesn't include the header anymore). Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/nvram_64.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/arch/powerpc/kernel/nvram_64.c b/arch/powerpc/kernel/nvram_64.c index 9e133355f742..a5a5587121a7 100644 --- a/arch/powerpc/kernel/nvram_64.c +++ b/arch/powerpc/kernel/nvram_64.c @@ -34,10 +34,10 @@ #undef DEBUG_NVRAM -#define NVRAM_HEADER_LEN 16 /* sizeof(struct nvram_header) */ -#define NVRAM_BLOCK_LEN 16 -#define NVRAM_MAX_REQ (2080/NVRAM_BLOCK_LEN) -#define NVRAM_MIN_REQ (1056/NVRAM_BLOCK_LEN) +#define NVRAM_HEADER_LEN sizeof(struct nvram_header) +#define NVRAM_BLOCK_LEN NVRAM_HEADER_LEN +#define NVRAM_MAX_REQ 2079 +#define NVRAM_MIN_REQ 1055 /* If change this size, then change the size of NVNAME_LEN */ struct nvram_header { @@ -311,7 +311,7 @@ static int __init nvram_remove_os_partition(void) * nvram_create_partition - Create a partition in nvram * @name: name of the partition to create * @sig: signature of the partition to create - * @req_size: size to allocate preferrably + * @req_size: size of data to allocate in bytes * @min_size: minimum acceptable size (0 means req_size) */ static int __init nvram_create_partition(const char *name, int sig, @@ -325,12 +325,20 @@ static int __init nvram_create_partition(const char *name, int sig, long size = 0; int rc; + /* Convert sizes from bytes to blocks */ + req_size = _ALIGN_UP(req_size, NVRAM_BLOCK_LEN) / NVRAM_BLOCK_LEN; + min_size = _ALIGN_UP(min_size, NVRAM_BLOCK_LEN) / NVRAM_BLOCK_LEN; + /* If no minimum size specified, make it the same as the * requested size */ if (min_size == 0) min_size = req_size; + /* Now add one block to each for the header */ + req_size += 1; + min_size += 1; + /* Find a free partition that will give us the maximum needed size If can't find one that will give us the minimum size needed */ list_for_each_entry(part, &nvram_part->partition, partition) { @@ -450,7 +458,7 @@ static int __init nvram_setup_partition(void) if (strcmp(part->header.name, "ppc64,linux")) continue; - if (part->header.length >= NVRAM_MIN_REQ) { + if ((part->header.length - 1) * NVRAM_BLOCK_LEN >= NVRAM_MIN_REQ) { /* found our partition */ nvram_error_log_index = part->index + NVRAM_HEADER_LEN; nvram_error_log_size = ((part->header.length - 1) * -- cgit v1.2.3 From 578914cffc283b907777796420148d582072cbae Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Thu, 29 Jul 2010 17:21:17 +1000 Subject: powerpc/nvram: Ensure that the partition header/block size is right Use BUILD_BUG_ON to ensure the structure representing a partition header have the right size. Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/nvram_64.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/powerpc/kernel/nvram_64.c b/arch/powerpc/kernel/nvram_64.c index a5a5587121a7..f7538820c03d 100644 --- a/arch/powerpc/kernel/nvram_64.c +++ b/arch/powerpc/kernel/nvram_64.c @@ -565,6 +565,8 @@ static int __init nvram_init(void) int error; int rc; + BUILD_BUG_ON(NVRAM_BLOCK_LEN != 16); + if (ppc_md.nvram_size == NULL || ppc_md.nvram_size() <= 0) return -ENODEV; -- cgit v1.2.3 From cef0d5ad62ec6e0c8456b8f58e898aa3219311a5 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Thu, 29 Jul 2010 17:22:34 +1000 Subject: powerpc/nvram: Completely clear a new partition When creating a partition, we clear it entirely rather than just the first two words since the previous code was rather specific to the pseries log partition format. Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/nvram_64.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/arch/powerpc/kernel/nvram_64.c b/arch/powerpc/kernel/nvram_64.c index f7538820c03d..02737e687559 100644 --- a/arch/powerpc/kernel/nvram_64.c +++ b/arch/powerpc/kernel/nvram_64.c @@ -320,7 +320,7 @@ static int __init nvram_create_partition(const char *name, int sig, struct nvram_partition *part; struct nvram_partition *new_part; struct nvram_partition *free_part = NULL; - int seq_init[2] = { 0, 0 }; + static char nv_init_vals[16]; loff_t tmp_index; long size = 0; int rc; @@ -379,14 +379,15 @@ static int __init nvram_create_partition(const char *name, int sig, return rc; } - /* make sure and initialize to zero the sequence number and the error - type logged */ - tmp_index = new_part->index + NVRAM_HEADER_LEN; - rc = ppc_md.nvram_write((char *)&seq_init, sizeof(seq_init), &tmp_index); - if (rc <= 0) { - printk(KERN_ERR "nvram_create_os_partition: nvram_write " - "failed (%d)\n", rc); - return rc; + /* Clear the partition */ + for (tmp_index = new_part->index + NVRAM_HEADER_LEN; + tmp_index < ((size - 1) * NVRAM_BLOCK_LEN); + tmp_index += NVRAM_BLOCK_LEN) { + rc = ppc_md.nvram_write(nv_init_vals, NVRAM_BLOCK_LEN, &tmp_index); + if (rc <= 0) { + pr_err("nvram_create_partition: nvram_write failed (%d)\n", rc); + return rc; + } } nvram_error_log_index = new_part->index + NVRAM_HEADER_LEN; -- cgit v1.2.3 From e49e2e87235518c21b1f5228809209831e6169e7 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Thu, 29 Jul 2010 17:38:55 +1000 Subject: powerpc/nvram: Shuffle code around in nvram_create_partition() This error log stuff is really pseries specific. As a first step we move the initialization of these variables to the caller of nvram_create_partition(), which is also slightly reorganized so we setup the free partition before we clear the new partition, so the chance of an error during clear leaving us with invalid headers is lessened. Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/nvram_64.c | 108 +++++++++++++++++++++++------------------ 1 file changed, 62 insertions(+), 46 deletions(-) diff --git a/arch/powerpc/kernel/nvram_64.c b/arch/powerpc/kernel/nvram_64.c index 02737e687559..eabee7c61183 100644 --- a/arch/powerpc/kernel/nvram_64.c +++ b/arch/powerpc/kernel/nvram_64.c @@ -313,9 +313,15 @@ static int __init nvram_remove_os_partition(void) * @sig: signature of the partition to create * @req_size: size of data to allocate in bytes * @min_size: minimum acceptable size (0 means req_size) + * + * Returns a negative error code or a positive nvram index + * of the beginning of the data area of the newly created + * partition. If you provided a min_size smaller than req_size + * you need to query for the actual size yourself after the + * call using nvram_partition_get_size(). */ -static int __init nvram_create_partition(const char *name, int sig, - int req_size, int min_size) +static loff_t __init nvram_create_partition(const char *name, int sig, + int req_size, int min_size) { struct nvram_partition *part; struct nvram_partition *new_part; @@ -334,6 +340,8 @@ static int __init nvram_create_partition(const char *name, int sig, */ if (min_size == 0) min_size = req_size; + if (min_size > req_size) + return -EINVAL; /* Now add one block to each for the header */ req_size += 1; @@ -362,7 +370,7 @@ static int __init nvram_create_partition(const char *name, int sig, /* Create our OS partition */ new_part = kmalloc(sizeof(*new_part), GFP_KERNEL); if (!new_part) { - printk(KERN_ERR "nvram_create_os_partition: kmalloc failed\n"); + pr_err("nvram_create_os_partition: kmalloc failed\n"); return -ENOMEM; } @@ -374,12 +382,29 @@ static int __init nvram_create_partition(const char *name, int sig, rc = nvram_write_header(new_part); if (rc <= 0) { - printk(KERN_ERR "nvram_create_os_partition: nvram_write_header " - "failed (%d)\n", rc); + pr_err("nvram_create_os_partition: nvram_write_header " + "failed (%d)\n", rc); return rc; } + list_add_tail(&new_part->partition, &free_part->partition); + + /* Adjust or remove the partition we stole the space from */ + if (free_part->header.length > size) { + free_part->index += size * NVRAM_BLOCK_LEN; + free_part->header.length -= size; + free_part->header.checksum = nvram_checksum(&free_part->header); + rc = nvram_write_header(free_part); + if (rc <= 0) { + pr_err("nvram_create_os_partition: nvram_write_header " + "failed (%d)\n", rc); + return rc; + } + } else { + list_del(&free_part->partition); + kfree(free_part); + } - /* Clear the partition */ + /* Clear the new partition */ for (tmp_index = new_part->index + NVRAM_HEADER_LEN; tmp_index < ((size - 1) * NVRAM_BLOCK_LEN); tmp_index += NVRAM_BLOCK_LEN) { @@ -390,31 +415,24 @@ static int __init nvram_create_partition(const char *name, int sig, } } - nvram_error_log_index = new_part->index + NVRAM_HEADER_LEN; - nvram_error_log_size = ((part->header.length - 1) * - NVRAM_BLOCK_LEN) - sizeof(struct err_log_info); - - list_add_tail(&new_part->partition, &free_part->partition); - - if (free_part->header.length <= size) { - list_del(&free_part->partition); - kfree(free_part); - return 0; - } + return new_part->index + NVRAM_HEADER_LEN; +} - /* Adjust the partition we stole the space from */ - free_part->index += size * NVRAM_BLOCK_LEN; - free_part->header.length -= size; - free_part->header.checksum = nvram_checksum(&free_part->header); +/** + * nvram_get_partition_size - Get the data size of an nvram partition + * @data_index: This is the offset of the start of the data of + * the partition. The same value that is returned by + * nvram_create_partition(). + */ +static int nvram_get_partition_size(loff_t data_index) +{ + struct nvram_partition *part; - rc = nvram_write_header(free_part); - if (rc <= 0) { - printk(KERN_ERR "nvram_create_os_partition: nvram_write_header " - "failed (%d)\n", rc); - return rc; + list_for_each_entry(part, &nvram_part->partition, partition) { + if (part->index + NVRAM_HEADER_LEN == data_index) + return (part->header.length - 1) * NVRAM_BLOCK_LEN; } - - return 0; + return -1; } @@ -469,30 +487,28 @@ static int __init nvram_setup_partition(void) } /* try creating a partition with the free space we have */ - rc = nvram_create_partition("ppc64,linux", NVRAM_SIG_OS, + rc = nvram_create_partition("ppc64,linux", NVRAM_SIG_OS, NVRAM_MAX_REQ, NVRAM_MIN_REQ); - if (!rc) - return 0; - - /* need to free up some space */ - rc = nvram_remove_os_partition(); - if (rc) { - return rc; - } - - /* create a partition in this new space */ - rc = nvram_create_partition("ppc64,linux", NVRAM_SIG_OS, - NVRAM_MAX_REQ, NVRAM_MIN_REQ); - if (rc) { - printk(KERN_ERR "nvram_create_partition: Could not find a " - "NVRAM partition large enough\n"); - return rc; + if (rc < 0) { + /* need to free up some space */ + rc = nvram_remove_os_partition(); + if (rc) + return rc; + /* create a partition in this new space */ + rc = nvram_create_partition("ppc64,linux", NVRAM_SIG_OS, + NVRAM_MAX_REQ, NVRAM_MIN_REQ); + if (rc < 0) { + pr_err("nvram_create_partition: Could not find" + " enough space in NVRAM for partition\n"); + return rc; + } } + nvram_error_log_index = rc; + nvram_error_log_size = nvram_get_partition_size(rc) - sizeof(struct err_log_info); return 0; } - static int __init nvram_scan_partitions(void) { loff_t cur_index = 0; -- cgit v1.2.3 From fa2b4e54d41f3c9f1bee6a7d63ecd4f0ab161e89 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Thu, 29 Jul 2010 18:19:59 +1000 Subject: powerpc/nvram: Improve partition removal Existing code is nasty, has bugs etc... rewrite the function more simply, and make it take the signature and optional name of the partitions to remove as arguments, thus making it a more generic utility. We also try to remove a log partition that we find and is too small rather than creating a duplicate. Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/nvram_64.c | 91 ++++++++++++++++++++---------------------- 1 file changed, 43 insertions(+), 48 deletions(-) diff --git a/arch/powerpc/kernel/nvram_64.c b/arch/powerpc/kernel/nvram_64.c index eabee7c61183..6dd2700852f0 100644 --- a/arch/powerpc/kernel/nvram_64.c +++ b/arch/powerpc/kernel/nvram_64.c @@ -247,61 +247,54 @@ static unsigned char __init nvram_checksum(struct nvram_header *p) return c_sum; } -static int __init nvram_remove_os_partition(void) +/** + * nvram_remove_partition - Remove one or more partitions in nvram + * @name: name of the partition to remove, or NULL for a + * signature only match + * @sig: signature of the partition(s) to remove + */ + +static int __init nvram_remove_partition(const char *name, int sig) { - struct list_head *i; - struct list_head *j; - struct nvram_partition * part; - struct nvram_partition * cur_part; + struct nvram_partition *part, *prev, *tmp; int rc; - list_for_each(i, &nvram_part->partition) { - part = list_entry(i, struct nvram_partition, partition); - if (part->header.signature != NVRAM_SIG_OS) + list_for_each_entry(part, &nvram_part->partition, partition) { + if (part->header.signature != sig) continue; - - /* Make os partition a free partition */ + if (name && strncmp(name, part->header.name, 12)) + continue; + + /* Make partition a free partition */ part->header.signature = NVRAM_SIG_FREE; sprintf(part->header.name, "wwwwwwwwwwww"); part->header.checksum = nvram_checksum(&part->header); - - /* Merge contiguous free partitions backwards */ - list_for_each_prev(j, &part->partition) { - cur_part = list_entry(j, struct nvram_partition, partition); - if (cur_part == nvram_part || cur_part->header.signature != NVRAM_SIG_FREE) { - break; - } - - part->header.length += cur_part->header.length; - part->header.checksum = nvram_checksum(&part->header); - part->index = cur_part->index; - - list_del(&cur_part->partition); - kfree(cur_part); - j = &part->partition; /* fixup our loop */ - } - - /* Merge contiguous free partitions forwards */ - list_for_each(j, &part->partition) { - cur_part = list_entry(j, struct nvram_partition, partition); - if (cur_part == nvram_part || cur_part->header.signature != NVRAM_SIG_FREE) { - break; - } - - part->header.length += cur_part->header.length; - part->header.checksum = nvram_checksum(&part->header); - - list_del(&cur_part->partition); - kfree(cur_part); - j = &part->partition; /* fixup our loop */ - } - rc = nvram_write_header(part); if (rc <= 0) { - printk(KERN_ERR "nvram_remove_os_partition: nvram_write failed (%d)\n", rc); + printk(KERN_ERR "nvram_remove_partition: nvram_write failed (%d)\n", rc); return rc; } + } + /* Merge contiguous ones */ + prev = NULL; + list_for_each_entry_safe(part, tmp, &nvram_part->partition, partition) { + if (part->header.signature != NVRAM_SIG_FREE) { + prev = NULL; + continue; + } + if (prev) { + prev->header.length += part->header.length; + prev->header.checksum = nvram_checksum(&part->header); + rc = nvram_write_header(part); + if (rc <= 0) { + printk(KERN_ERR "nvram_remove_partition: nvram_write failed (%d)\n", rc); + return rc; + } + list_del(&part->partition); + kfree(part); + } else + prev = part; } return 0; @@ -484,17 +477,19 @@ static int __init nvram_setup_partition(void) NVRAM_BLOCK_LEN) - sizeof(struct err_log_info); return 0; } + + /* Found one but it's too small, remove it */ + nvram_remove_partition("ppc64,linux", NVRAM_SIG_OS); } /* try creating a partition with the free space we have */ rc = nvram_create_partition("ppc64,linux", NVRAM_SIG_OS, NVRAM_MAX_REQ, NVRAM_MIN_REQ); if (rc < 0) { - /* need to free up some space */ - rc = nvram_remove_os_partition(); - if (rc) - return rc; - /* create a partition in this new space */ + /* need to free up some space, remove any "OS" partition */ + nvram_remove_partition(NULL, NVRAM_SIG_OS); + + /* Try again */ rc = nvram_create_partition("ppc64,linux", NVRAM_SIG_OS, NVRAM_MAX_REQ, NVRAM_MIN_REQ); if (rc < 0) { -- cgit v1.2.3 From cf5cbf9f8085eb45316d6e3c888a77cc50696701 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Mon, 2 Aug 2010 10:01:58 +1000 Subject: powerpc/nvram: Add nvram_find_partition() Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/nvram_64.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/arch/powerpc/kernel/nvram_64.c b/arch/powerpc/kernel/nvram_64.c index 6dd2700852f0..01e6844be8d7 100644 --- a/arch/powerpc/kernel/nvram_64.c +++ b/arch/powerpc/kernel/nvram_64.c @@ -429,6 +429,28 @@ static int nvram_get_partition_size(loff_t data_index) } +/** + * nvram_find_partition - Find an nvram partition by signature and name + * @name: Name of the partition or NULL for any name + * @sig: Signature to test against + * @out_size: if non-NULL, returns the size of the data part of the partition + */ +loff_t nvram_find_partition(const char *name, int sig, int *out_size) +{ + struct nvram_partition *p; + + list_for_each_entry(p, &nvram_part->partition, partition) { + if (p->header.signature == sig && + (!name || !strncmp(p->header.name, name, 12))) { + if (out_size) + *out_size = (p->header.length - 1) * + NVRAM_BLOCK_LEN; + return p->index + NVRAM_HEADER_LEN; + } + } + return 0; +} + /* nvram_setup_partition * * This will setup the partition we need for buffering the -- cgit v1.2.3 From d9626947f20b3dc0992e4ac28b477f7601f8f16e Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Mon, 2 Aug 2010 10:13:56 +1000 Subject: powerpc/nvram: Change nvram_setup_partition() to use new helper This changes the function to use nvram_find_partition() instead of doing the lookup "by hand". It also makes some of the logic clearer and prints out more useful diagnostic information. Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/nvram_64.c | 71 +++++++++++++++++++----------------------- 1 file changed, 32 insertions(+), 39 deletions(-) diff --git a/arch/powerpc/kernel/nvram_64.c b/arch/powerpc/kernel/nvram_64.c index 01e6844be8d7..76f546b9944d 100644 --- a/arch/powerpc/kernel/nvram_64.c +++ b/arch/powerpc/kernel/nvram_64.c @@ -469,9 +469,8 @@ loff_t nvram_find_partition(const char *name, int sig, int *out_size) */ static int __init nvram_setup_partition(void) { - struct list_head * p; - struct nvram_partition * part; - int rc; + loff_t p; + int size; /* For now, we don't do any of this on pmac, until I * have figured out if it's worth killing some unused stuffs @@ -481,48 +480,42 @@ static int __init nvram_setup_partition(void) if (machine_is(powermac)) return -ENOSPC; - /* see if we have an OS partition that meets our needs. - will try getting the max we need. If not we'll delete - partitions and try again. */ - list_for_each(p, &nvram_part->partition) { - part = list_entry(p, struct nvram_partition, partition); - if (part->header.signature != NVRAM_SIG_OS) - continue; - - if (strcmp(part->header.name, "ppc64,linux")) - continue; - - if ((part->header.length - 1) * NVRAM_BLOCK_LEN >= NVRAM_MIN_REQ) { - /* found our partition */ - nvram_error_log_index = part->index + NVRAM_HEADER_LEN; - nvram_error_log_size = ((part->header.length - 1) * - NVRAM_BLOCK_LEN) - sizeof(struct err_log_info); - return 0; - } + p = nvram_find_partition("ppc64,linux", NVRAM_SIG_OS, &size); - /* Found one but it's too small, remove it */ + /* Found one but too small, remove it */ + if (p && size < NVRAM_MIN_REQ) { + pr_info("nvram: Found too small ppc64,linux partition" + ",removing it..."); nvram_remove_partition("ppc64,linux", NVRAM_SIG_OS); + p = 0; } - - /* try creating a partition with the free space we have */ - rc = nvram_create_partition("ppc64,linux", NVRAM_SIG_OS, - NVRAM_MAX_REQ, NVRAM_MIN_REQ); - if (rc < 0) { - /* need to free up some space, remove any "OS" partition */ - nvram_remove_partition(NULL, NVRAM_SIG_OS); - - /* Try again */ - rc = nvram_create_partition("ppc64,linux", NVRAM_SIG_OS, - NVRAM_MAX_REQ, NVRAM_MIN_REQ); - if (rc < 0) { - pr_err("nvram_create_partition: Could not find" - " enough space in NVRAM for partition\n"); - return rc; + + /* Create one if we didn't find */ + if (!p) { + p = nvram_create_partition("ppc64,linux", NVRAM_SIG_OS, + NVRAM_MAX_REQ, NVRAM_MIN_REQ); + /* No room for it, try to get rid of any OS partition + * and try again + */ + if (p == -ENOSPC) { + pr_info("nvram: No room to create ppc64,linux" + " partition, deleting all OS partitions..."); + nvram_remove_partition(NULL, NVRAM_SIG_OS); + p = nvram_create_partition("ppc64,linux", NVRAM_SIG_OS, + NVRAM_MAX_REQ, NVRAM_MIN_REQ); } } + + if (p <= 0) { + pr_err("nvram: Failed to find or create ppc64,linux" + " partition, err %d\n", (int)p); + return 0; + } + + nvram_error_log_index = p; + nvram_error_log_size = nvram_get_partition_size(p) - + sizeof(struct err_log_info); - nvram_error_log_index = rc; - nvram_error_log_size = nvram_get_partition_size(rc) - sizeof(struct err_log_info); return 0; } -- cgit v1.2.3 From edc79a2f3ee1c74d915f6a0ce3cb22bf468f5ad5 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Mon, 2 Aug 2010 11:18:09 +1000 Subject: powerpc/nvram: Move the log partition stuff to pseries The nvram log partition stuff currently in nvram_64.c is really pseries specific. It isn't actually used on anything else (despite the fact that we ran the code to setup the partition on anything except powermac) and the log format is specific to pseries RTAS implementation. So move it where it belongs Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/include/asm/nvram.h | 10 +- arch/powerpc/kernel/nvram_64.c | 254 +++------------------------------ arch/powerpc/platforms/pseries/nvram.c | 200 ++++++++++++++++++++++++++ 3 files changed, 227 insertions(+), 237 deletions(-) diff --git a/arch/powerpc/include/asm/nvram.h b/arch/powerpc/include/asm/nvram.h index 459dc09ecbd8..92efe67d1c57 100644 --- a/arch/powerpc/include/asm/nvram.h +++ b/arch/powerpc/include/asm/nvram.h @@ -30,13 +30,14 @@ #include #include +#ifdef CONFIG_PPC_PSERIES extern int nvram_write_error_log(char * buff, int length, unsigned int err_type, unsigned int err_seq); extern int nvram_read_error_log(char * buff, int length, unsigned int * err_type, unsigned int *err_seq); extern int nvram_clear_error_log(void); - extern int pSeries_nvram_init(void); +#endif /* CONFIG_PPC_PSERIES */ #ifdef CONFIG_MMIO_NVRAM extern int mmio_nvram_init(void); @@ -47,6 +48,13 @@ static inline int mmio_nvram_init(void) } #endif +extern int __init nvram_scan_partitions(void); +extern loff_t nvram_create_partition(const char *name, int sig, + int req_size, int min_size); +extern int nvram_remove_partition(const char *name, int sig); +extern int nvram_get_partition_size(loff_t data_index); +extern loff_t nvram_find_partition(const char *name, int sig, int *out_size); + #endif /* __KERNEL__ */ /* PowerMac specific nvram stuffs */ diff --git a/arch/powerpc/kernel/nvram_64.c b/arch/powerpc/kernel/nvram_64.c index 76f546b9944d..125d86cf0afc 100644 --- a/arch/powerpc/kernel/nvram_64.c +++ b/arch/powerpc/kernel/nvram_64.c @@ -36,8 +36,6 @@ #define NVRAM_HEADER_LEN sizeof(struct nvram_header) #define NVRAM_BLOCK_LEN NVRAM_HEADER_LEN -#define NVRAM_MAX_REQ 2079 -#define NVRAM_MIN_REQ 1055 /* If change this size, then change the size of NVNAME_LEN */ struct nvram_header { @@ -54,13 +52,6 @@ struct nvram_partition { }; static struct nvram_partition * nvram_part; -static long nvram_error_log_index = -1; -static long nvram_error_log_size = 0; - -struct err_log_info { - int error_type; - unsigned int seq_num; -}; static loff_t dev_nvram_llseek(struct file *file, loff_t offset, int origin) { @@ -254,7 +245,7 @@ static unsigned char __init nvram_checksum(struct nvram_header *p) * @sig: signature of the partition(s) to remove */ -static int __init nvram_remove_partition(const char *name, int sig) +int __init nvram_remove_partition(const char *name, int sig) { struct nvram_partition *part, *prev, *tmp; int rc; @@ -313,8 +304,8 @@ static int __init nvram_remove_partition(const char *name, int sig) * you need to query for the actual size yourself after the * call using nvram_partition_get_size(). */ -static loff_t __init nvram_create_partition(const char *name, int sig, - int req_size, int min_size) +loff_t __init nvram_create_partition(const char *name, int sig, + int req_size, int min_size) { struct nvram_partition *part; struct nvram_partition *new_part; @@ -417,7 +408,7 @@ static loff_t __init nvram_create_partition(const char *name, int sig, * the partition. The same value that is returned by * nvram_create_partition(). */ -static int nvram_get_partition_size(loff_t data_index) +int nvram_get_partition_size(loff_t data_index) { struct nvram_partition *part; @@ -451,75 +442,7 @@ loff_t nvram_find_partition(const char *name, int sig, int *out_size) return 0; } -/* nvram_setup_partition - * - * This will setup the partition we need for buffering the - * error logs and cleanup partitions if needed. - * - * The general strategy is the following: - * 1.) If there is ppc64,linux partition large enough then use it. - * 2.) If there is not a ppc64,linux partition large enough, search - * for a free partition that is large enough. - * 3.) If there is not a free partition large enough remove - * _all_ OS partitions and consolidate the space. - * 4.) Will first try getting a chunk that will satisfy the maximum - * error log size (NVRAM_MAX_REQ). - * 5.) If the max chunk cannot be allocated then try finding a chunk - * that will satisfy the minum needed (NVRAM_MIN_REQ). - */ -static int __init nvram_setup_partition(void) -{ - loff_t p; - int size; - - /* For now, we don't do any of this on pmac, until I - * have figured out if it's worth killing some unused stuffs - * in our nvram, as Apple defined partitions use pretty much - * all of the space - */ - if (machine_is(powermac)) - return -ENOSPC; - - p = nvram_find_partition("ppc64,linux", NVRAM_SIG_OS, &size); - - /* Found one but too small, remove it */ - if (p && size < NVRAM_MIN_REQ) { - pr_info("nvram: Found too small ppc64,linux partition" - ",removing it..."); - nvram_remove_partition("ppc64,linux", NVRAM_SIG_OS); - p = 0; - } - - /* Create one if we didn't find */ - if (!p) { - p = nvram_create_partition("ppc64,linux", NVRAM_SIG_OS, - NVRAM_MAX_REQ, NVRAM_MIN_REQ); - /* No room for it, try to get rid of any OS partition - * and try again - */ - if (p == -ENOSPC) { - pr_info("nvram: No room to create ppc64,linux" - " partition, deleting all OS partitions..."); - nvram_remove_partition(NULL, NVRAM_SIG_OS); - p = nvram_create_partition("ppc64,linux", NVRAM_SIG_OS, - NVRAM_MAX_REQ, NVRAM_MIN_REQ); - } - } - - if (p <= 0) { - pr_err("nvram: Failed to find or create ppc64,linux" - " partition, err %d\n", (int)p); - return 0; - } - - nvram_error_log_index = p; - nvram_error_log_size = nvram_get_partition_size(p) - - sizeof(struct err_log_info); - - return 0; -} - -static int __init nvram_scan_partitions(void) +int __init nvram_scan_partitions(void) { loff_t cur_index = 0; struct nvram_header phead; @@ -529,7 +452,15 @@ static int __init nvram_scan_partitions(void) int total_size; int err; - if (ppc_md.nvram_size == NULL) + /* Initialize our anchor for the nvram partition list */ + nvram_part = kmalloc(sizeof(struct nvram_partition), GFP_KERNEL); + if (!nvram_part) { + printk(KERN_ERR "nvram_init: Failed kmalloc\n"); + return -ENOMEM; + } + INIT_LIST_HEAD(&nvram_part->partition); + + if (ppc_md.nvram_size == NULL || ppc_md.nvram_size() <= 0) return -ENODEV; total_size = ppc_md.nvram_size(); @@ -582,6 +513,10 @@ static int __init nvram_scan_partitions(void) } err = 0; +#ifdef DEBUG_NVRAM + nvram_print_partitions("NVRAM Partitions"); +#endif + out: kfree(header); return err; @@ -589,7 +524,6 @@ static int __init nvram_scan_partitions(void) static int __init nvram_init(void) { - int error; int rc; BUILD_BUG_ON(NVRAM_BLOCK_LEN != 16); @@ -603,29 +537,6 @@ static int __init nvram_init(void) return rc; } - /* initialize our anchor for the nvram partition list */ - nvram_part = kmalloc(sizeof(struct nvram_partition), GFP_KERNEL); - if (!nvram_part) { - printk(KERN_ERR "nvram_init: Failed kmalloc\n"); - return -ENOMEM; - } - INIT_LIST_HEAD(&nvram_part->partition); - - /* Get all the NVRAM partitions */ - error = nvram_scan_partitions(); - if (error) { - printk(KERN_ERR "nvram_init: Failed nvram_scan_partitions\n"); - return error; - } - - if(nvram_setup_partition()) - printk(KERN_WARNING "nvram_init: Could not find nvram partition" - " for nvram buffered error logging.\n"); - -#ifdef DEBUG_NVRAM - nvram_print_partitions("NVRAM Partitions"); -#endif - return rc; } @@ -634,135 +545,6 @@ void __exit nvram_cleanup(void) misc_deregister( &nvram_dev ); } - -#ifdef CONFIG_PPC_PSERIES - -/* nvram_write_error_log - * - * We need to buffer the error logs into nvram to ensure that we have - * the failure information to decode. If we have a severe error there - * is no way to guarantee that the OS or the machine is in a state to - * get back to user land and write the error to disk. For example if - * the SCSI device driver causes a Machine Check by writing to a bad - * IO address, there is no way of guaranteeing that the device driver - * is in any state that is would also be able to write the error data - * captured to disk, thus we buffer it in NVRAM for analysis on the - * next boot. - * - * In NVRAM the partition containing the error log buffer will looks like: - * Header (in bytes): - * +-----------+----------+--------+------------+------------------+ - * | signature | checksum | length | name | data | - * |0 |1 |2 3|4 15|16 length-1| - * +-----------+----------+--------+------------+------------------+ - * - * The 'data' section would look like (in bytes): - * +--------------+------------+-----------------------------------+ - * | event_logged | sequence # | error log | - * |0 3|4 7|8 nvram_error_log_size-1| - * +--------------+------------+-----------------------------------+ - * - * event_logged: 0 if event has not been logged to syslog, 1 if it has - * sequence #: The unique sequence # for each event. (until it wraps) - * error log: The error log from event_scan - */ -int nvram_write_error_log(char * buff, int length, - unsigned int err_type, unsigned int error_log_cnt) -{ - int rc; - loff_t tmp_index; - struct err_log_info info; - - if (nvram_error_log_index == -1) { - return -ESPIPE; - } - - if (length > nvram_error_log_size) { - length = nvram_error_log_size; - } - - info.error_type = err_type; - info.seq_num = error_log_cnt; - - tmp_index = nvram_error_log_index; - - rc = ppc_md.nvram_write((char *)&info, sizeof(struct err_log_info), &tmp_index); - if (rc <= 0) { - printk(KERN_ERR "nvram_write_error_log: Failed nvram_write (%d)\n", rc); - return rc; - } - - rc = ppc_md.nvram_write(buff, length, &tmp_index); - if (rc <= 0) { - printk(KERN_ERR "nvram_write_error_log: Failed nvram_write (%d)\n", rc); - return rc; - } - - return 0; -} - -/* nvram_read_error_log - * - * Reads nvram for error log for at most 'length' - */ -int nvram_read_error_log(char * buff, int length, - unsigned int * err_type, unsigned int * error_log_cnt) -{ - int rc; - loff_t tmp_index; - struct err_log_info info; - - if (nvram_error_log_index == -1) - return -1; - - if (length > nvram_error_log_size) - length = nvram_error_log_size; - - tmp_index = nvram_error_log_index; - - rc = ppc_md.nvram_read((char *)&info, sizeof(struct err_log_info), &tmp_index); - if (rc <= 0) { - printk(KERN_ERR "nvram_read_error_log: Failed nvram_read (%d)\n", rc); - return rc; - } - - rc = ppc_md.nvram_read(buff, length, &tmp_index); - if (rc <= 0) { - printk(KERN_ERR "nvram_read_error_log: Failed nvram_read (%d)\n", rc); - return rc; - } - - *error_log_cnt = info.seq_num; - *err_type = info.error_type; - - return 0; -} - -/* This doesn't actually zero anything, but it sets the event_logged - * word to tell that this event is safely in syslog. - */ -int nvram_clear_error_log(void) -{ - loff_t tmp_index; - int clear_word = ERR_FLAG_ALREADY_LOGGED; - int rc; - - if (nvram_error_log_index == -1) - return -1; - - tmp_index = nvram_error_log_index; - - rc = ppc_md.nvram_write((char *)&clear_word, sizeof(int), &tmp_index); - if (rc <= 0) { - printk(KERN_ERR "nvram_clear_error_log: Failed nvram_write (%d)\n", rc); - return rc; - } - - return 0; -} - -#endif /* CONFIG_PPC_PSERIES */ - module_init(nvram_init); module_exit(nvram_cleanup); MODULE_LICENSE("GPL"); diff --git a/arch/powerpc/platforms/pseries/nvram.c b/arch/powerpc/platforms/pseries/nvram.c index 2a1ef5c25344..55a7141131f1 100644 --- a/arch/powerpc/platforms/pseries/nvram.c +++ b/arch/powerpc/platforms/pseries/nvram.c @@ -30,6 +30,16 @@ static int nvram_fetch, nvram_store; static char nvram_buf[NVRW_CNT]; /* assume this is in the first 4GB */ static DEFINE_SPINLOCK(nvram_lock); +static long nvram_error_log_index = -1; +static long nvram_error_log_size = 0; + +struct err_log_info { + int error_type; + unsigned int seq_num; +}; +#define NVRAM_MAX_REQ 2079 +#define NVRAM_MIN_REQ 1055 + static ssize_t pSeries_nvram_read(char *buf, size_t count, loff_t *index) { unsigned int i; @@ -121,6 +131,196 @@ static ssize_t pSeries_nvram_get_size(void) return nvram_size ? nvram_size : -ENODEV; } + +/* nvram_write_error_log + * + * We need to buffer the error logs into nvram to ensure that we have + * the failure information to decode. If we have a severe error there + * is no way to guarantee that the OS or the machine is in a state to + * get back to user land and write the error to disk. For example if + * the SCSI device driver causes a Machine Check by writing to a bad + * IO address, there is no way of guaranteeing that the device driver + * is in any state that is would also be able to write the error data + * captured to disk, thus we buffer it in NVRAM for analysis on the + * next boot. + * + * In NVRAM the partition containing the error log buffer will looks like: + * Header (in bytes): + * +-----------+----------+--------+------------+------------------+ + * | signature | checksum | length | name | data | + * |0 |1 |2 3|4 15|16 length-1| + * +-----------+----------+--------+------------+------------------+ + * + * The 'data' section would look like (in bytes): + * +--------------+------------+-----------------------------------+ + * | event_logged | sequence # | error log | + * |0 3|4 7|8 nvram_error_log_size-1| + * +--------------+------------+-----------------------------------+ + * + * event_logged: 0 if event has not been logged to syslog, 1 if it has + * sequence #: The unique sequence # for each event. (until it wraps) + * error log: The error log from event_scan + */ +int nvram_write_error_log(char * buff, int length, + unsigned int err_type, unsigned int error_log_cnt) +{ + int rc; + loff_t tmp_index; + struct err_log_info info; + + if (nvram_error_log_index == -1) { + return -ESPIPE; + } + + if (length > nvram_error_log_size) { + length = nvram_error_log_size; + } + + info.error_type = err_type; + info.seq_num = error_log_cnt; + + tmp_index = nvram_error_log_index; + + rc = ppc_md.nvram_write((char *)&info, sizeof(struct err_log_info), &tmp_index); + if (rc <= 0) { + printk(KERN_ERR "nvram_write_error_log: Failed nvram_write (%d)\n", rc); + return rc; + } + + rc = ppc_md.nvram_write(buff, length, &tmp_index); + if (rc <= 0) { + printk(KERN_ERR "nvram_write_error_log: Failed nvram_write (%d)\n", rc); + return rc; + } + + return 0; +} + +/* nvram_read_error_log + * + * Reads nvram for error log for at most 'length' + */ +int nvram_read_error_log(char * buff, int length, + unsigned int * err_type, unsigned int * error_log_cnt) +{ + int rc; + loff_t tmp_index; + struct err_log_info info; + + if (nvram_error_log_index == -1) + return -1; + + if (length > nvram_error_log_size) + length = nvram_error_log_size; + + tmp_index = nvram_error_log_index; + + rc = ppc_md.nvram_read((char *)&info, sizeof(struct err_log_info), &tmp_index); + if (rc <= 0) { + printk(KERN_ERR "nvram_read_error_log: Failed nvram_read (%d)\n", rc); + return rc; + } + + rc = ppc_md.nvram_read(buff, length, &tmp_index); + if (rc <= 0) { + printk(KERN_ERR "nvram_read_error_log: Failed nvram_read (%d)\n", rc); + return rc; + } + + *error_log_cnt = info.seq_num; + *err_type = info.error_type; + + return 0; +} + +/* This doesn't actually zero anything, but it sets the event_logged + * word to tell that this event is safely in syslog. + */ +int nvram_clear_error_log(void) +{ + loff_t tmp_index; + int clear_word = ERR_FLAG_ALREADY_LOGGED; + int rc; + + if (nvram_error_log_index == -1) + return -1; + + tmp_index = nvram_error_log_index; + + rc = ppc_md.nvram_write((char *)&clear_word, sizeof(int), &tmp_index); + if (rc <= 0) { + printk(KERN_ERR "nvram_clear_error_log: Failed nvram_write (%d)\n", rc); + return rc; + } + + return 0; +} + +/* pseries_nvram_init_log_partition + * + * This will setup the partition we need for buffering the + * error logs and cleanup partitions if needed. + * + * The general strategy is the following: + * 1.) If there is ppc64,linux partition large enough then use it. + * 2.) If there is not a ppc64,linux partition large enough, search + * for a free partition that is large enough. + * 3.) If there is not a free partition large enough remove + * _all_ OS partitions and consolidate the space. + * 4.) Will first try getting a chunk that will satisfy the maximum + * error log size (NVRAM_MAX_REQ). + * 5.) If the max chunk cannot be allocated then try finding a chunk + * that will satisfy the minum needed (NVRAM_MIN_REQ). + */ +static int __init pseries_nvram_init_log_partition(void) +{ + loff_t p; + int size; + + /* Scan nvram for partitions */ + nvram_scan_partitions(); + + /* Lookg for ours */ + p = nvram_find_partition("ppc64,linux", NVRAM_SIG_OS, &size); + + /* Found one but too small, remove it */ + if (p && size < NVRAM_MIN_REQ) { + pr_info("nvram: Found too small ppc64,linux partition" + ",removing it..."); + nvram_remove_partition("ppc64,linux", NVRAM_SIG_OS); + p = 0; + } + + /* Create one if we didn't find */ + if (!p) { + p = nvram_create_partition("ppc64,linux", NVRAM_SIG_OS, + NVRAM_MAX_REQ, NVRAM_MIN_REQ); + /* No room for it, try to get rid of any OS partition + * and try again + */ + if (p == -ENOSPC) { + pr_info("nvram: No room to create ppc64,linux" + " partition, deleting all OS partitions..."); + nvram_remove_partition(NULL, NVRAM_SIG_OS); + p = nvram_create_partition("ppc64,linux", NVRAM_SIG_OS, + NVRAM_MAX_REQ, NVRAM_MIN_REQ); + } + } + + if (p <= 0) { + pr_err("nvram: Failed to find or create ppc64,linux" + " partition, err %d\n", (int)p); + return 0; + } + + nvram_error_log_index = p; + nvram_error_log_size = nvram_get_partition_size(p) - + sizeof(struct err_log_info); + + return 0; +} +machine_arch_initcall(pseries, pseries_nvram_init_log_partition); + int __init pSeries_nvram_init(void) { struct device_node *nvram; -- cgit v1.2.3 From 9a866b870880065364c894823257e6982103d4e4 Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Mon, 2 Aug 2010 10:51:25 +1000 Subject: powerpc/nvram: Rename ppc64,linux partition to ibm,rtas-log I'm not aware of any userspace tool accessing it by its name anyways, it's read back by the kernel itself on the next boot to get back older log entries Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/platforms/pseries/nvram.c | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/arch/powerpc/platforms/pseries/nvram.c b/arch/powerpc/platforms/pseries/nvram.c index 55a7141131f1..7e828ba29bc3 100644 --- a/arch/powerpc/platforms/pseries/nvram.c +++ b/arch/powerpc/platforms/pseries/nvram.c @@ -40,6 +40,8 @@ struct err_log_info { #define NVRAM_MAX_REQ 2079 #define NVRAM_MIN_REQ 1055 +#define NVRAM_LOG_PART_NAME "ibm,rtas-log" + static ssize_t pSeries_nvram_read(char *buf, size_t count, loff_t *index) { unsigned int i; @@ -262,8 +264,8 @@ int nvram_clear_error_log(void) * error logs and cleanup partitions if needed. * * The general strategy is the following: - * 1.) If there is ppc64,linux partition large enough then use it. - * 2.) If there is not a ppc64,linux partition large enough, search + * 1.) If there is log partition large enough then use it. + * 2.) If there is none large enough, search * for a free partition that is large enough. * 3.) If there is not a free partition large enough remove * _all_ OS partitions and consolidate the space. @@ -281,34 +283,35 @@ static int __init pseries_nvram_init_log_partition(void) nvram_scan_partitions(); /* Lookg for ours */ - p = nvram_find_partition("ppc64,linux", NVRAM_SIG_OS, &size); + p = nvram_find_partition(NVRAM_LOG_PART_NAME, NVRAM_SIG_OS, &size); /* Found one but too small, remove it */ if (p && size < NVRAM_MIN_REQ) { - pr_info("nvram: Found too small ppc64,linux partition" + pr_info("nvram: Found too small "NVRAM_LOG_PART_NAME" partition" ",removing it..."); - nvram_remove_partition("ppc64,linux", NVRAM_SIG_OS); + nvram_remove_partition(NVRAM_LOG_PART_NAME, NVRAM_SIG_OS); p = 0; } /* Create one if we didn't find */ if (!p) { - p = nvram_create_partition("ppc64,linux", NVRAM_SIG_OS, + p = nvram_create_partition(NVRAM_LOG_PART_NAME, NVRAM_SIG_OS, NVRAM_MAX_REQ, NVRAM_MIN_REQ); /* No room for it, try to get rid of any OS partition * and try again */ if (p == -ENOSPC) { - pr_info("nvram: No room to create ppc64,linux" + pr_info("nvram: No room to create "NVRAM_LOG_PART_NAME " partition, deleting all OS partitions..."); nvram_remove_partition(NULL, NVRAM_SIG_OS); - p = nvram_create_partition("ppc64,linux", NVRAM_SIG_OS, - NVRAM_MAX_REQ, NVRAM_MIN_REQ); + p = nvram_create_partition(NVRAM_LOG_PART_NAME, + NVRAM_SIG_OS, NVRAM_MAX_REQ, + NVRAM_MIN_REQ); } } if (p <= 0) { - pr_err("nvram: Failed to find or create ppc64,linux" + pr_err("nvram: Failed to find or create "NVRAM_LOG_PART_NAME " partition, err %d\n", (int)p); return 0; } -- cgit v1.2.3 From 690d1a9bd14bd861328ca66473a223f60cf1ad31 Mon Sep 17 00:00:00 2001 From: Jim Keniston Date: Thu, 11 Nov 2010 18:54:22 +0000 Subject: powerpc/nvram: Fix NVRAM partition list setup Simplify creation and use of the NVRAM partition list. Signed-off-by: Jim Keniston Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/nvram_64.c | 26 ++++++++------------------ 1 file changed, 8 insertions(+), 18 deletions(-) diff --git a/arch/powerpc/kernel/nvram_64.c b/arch/powerpc/kernel/nvram_64.c index 125d86cf0afc..b8a50fa5875b 100644 --- a/arch/powerpc/kernel/nvram_64.c +++ b/arch/powerpc/kernel/nvram_64.c @@ -51,7 +51,7 @@ struct nvram_partition { unsigned int index; }; -static struct nvram_partition * nvram_part; +static LIST_HEAD(nvram_partitions); static loff_t dev_nvram_llseek(struct file *file, loff_t offset, int origin) { @@ -196,13 +196,11 @@ static struct miscdevice nvram_dev = { #ifdef DEBUG_NVRAM static void __init nvram_print_partitions(char * label) { - struct list_head * p; struct nvram_partition * tmp_part; printk(KERN_WARNING "--------%s---------\n", label); printk(KERN_WARNING "indx\t\tsig\tchks\tlen\tname\n"); - list_for_each(p, &nvram_part->partition) { - tmp_part = list_entry(p, struct nvram_partition, partition); + list_for_each_entry(tmp_part, &nvram_partitions, partition) { printk(KERN_WARNING "%4d \t%02x\t%02x\t%d\t%s\n", tmp_part->index, tmp_part->header.signature, tmp_part->header.checksum, tmp_part->header.length, @@ -250,7 +248,7 @@ int __init nvram_remove_partition(const char *name, int sig) struct nvram_partition *part, *prev, *tmp; int rc; - list_for_each_entry(part, &nvram_part->partition, partition) { + list_for_each_entry(part, &nvram_partitions, partition) { if (part->header.signature != sig) continue; if (name && strncmp(name, part->header.name, 12)) @@ -269,7 +267,7 @@ int __init nvram_remove_partition(const char *name, int sig) /* Merge contiguous ones */ prev = NULL; - list_for_each_entry_safe(part, tmp, &nvram_part->partition, partition) { + list_for_each_entry_safe(part, tmp, &nvram_partitions, partition) { if (part->header.signature != NVRAM_SIG_FREE) { prev = NULL; continue; @@ -333,7 +331,7 @@ loff_t __init nvram_create_partition(const char *name, int sig, /* Find a free partition that will give us the maximum needed size If can't find one that will give us the minimum size needed */ - list_for_each_entry(part, &nvram_part->partition, partition) { + list_for_each_entry(part, &nvram_partitions, partition) { if (part->header.signature != NVRAM_SIG_FREE) continue; @@ -412,7 +410,7 @@ int nvram_get_partition_size(loff_t data_index) { struct nvram_partition *part; - list_for_each_entry(part, &nvram_part->partition, partition) { + list_for_each_entry(part, &nvram_partitions, partition) { if (part->index + NVRAM_HEADER_LEN == data_index) return (part->header.length - 1) * NVRAM_BLOCK_LEN; } @@ -430,7 +428,7 @@ loff_t nvram_find_partition(const char *name, int sig, int *out_size) { struct nvram_partition *p; - list_for_each_entry(p, &nvram_part->partition, partition) { + list_for_each_entry(p, &nvram_partitions, partition) { if (p->header.signature == sig && (!name || !strncmp(p->header.name, name, 12))) { if (out_size) @@ -452,14 +450,6 @@ int __init nvram_scan_partitions(void) int total_size; int err; - /* Initialize our anchor for the nvram partition list */ - nvram_part = kmalloc(sizeof(struct nvram_partition), GFP_KERNEL); - if (!nvram_part) { - printk(KERN_ERR "nvram_init: Failed kmalloc\n"); - return -ENOMEM; - } - INIT_LIST_HEAD(&nvram_part->partition); - if (ppc_md.nvram_size == NULL || ppc_md.nvram_size() <= 0) return -ENODEV; total_size = ppc_md.nvram_size(); @@ -507,7 +497,7 @@ int __init nvram_scan_partitions(void) memcpy(&tmp_part->header, &phead, NVRAM_HEADER_LEN); tmp_part->index = cur_index; - list_add_tail(&tmp_part->partition, &nvram_part->partition); + list_add_tail(&tmp_part->partition, &nvram_partitions); cur_index += phead.length * NVRAM_BLOCK_LEN; } -- cgit v1.2.3 From 6024ede9ba84aa1b891c2d6bc98eda07801235e5 Mon Sep 17 00:00:00 2001 From: Jim Keniston Date: Thu, 11 Nov 2010 18:54:27 +0000 Subject: powerpc/nvram: Handle partition names >= 12 chars The name field in the nvram_header can be < 12 chars, null-terminated, or 12 chars without the null. Handle this safely. Signed-off-by: Jim Keniston Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/nvram_64.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/kernel/nvram_64.c b/arch/powerpc/kernel/nvram_64.c index b8a50fa5875b..bb12b3248f13 100644 --- a/arch/powerpc/kernel/nvram_64.c +++ b/arch/powerpc/kernel/nvram_64.c @@ -42,6 +42,7 @@ struct nvram_header { unsigned char signature; unsigned char checksum; unsigned short length; + /* Terminating null required only for names < 12 chars. */ char name[12]; }; @@ -201,7 +202,7 @@ static void __init nvram_print_partitions(char * label) printk(KERN_WARNING "--------%s---------\n", label); printk(KERN_WARNING "indx\t\tsig\tchks\tlen\tname\n"); list_for_each_entry(tmp_part, &nvram_partitions, partition) { - printk(KERN_WARNING "%4d \t%02x\t%02x\t%d\t%s\n", + printk(KERN_WARNING "%4d \t%02x\t%02x\t%d\t%12s\n", tmp_part->index, tmp_part->header.signature, tmp_part->header.checksum, tmp_part->header.length, tmp_part->header.name); @@ -256,7 +257,7 @@ int __init nvram_remove_partition(const char *name, int sig) /* Make partition a free partition */ part->header.signature = NVRAM_SIG_FREE; - sprintf(part->header.name, "wwwwwwwwwwww"); + strncpy(part->header.name, "wwwwwwwwwwww", 12); part->header.checksum = nvram_checksum(&part->header); rc = nvram_write_header(part); if (rc <= 0) { -- cgit v1.2.3 From 576ecb8e2b725726471cc62b12c01e28d33127ba Mon Sep 17 00:00:00 2001 From: Samuel Kvasnica Date: Fri, 19 Nov 2010 13:38:49 +0000 Subject: xfs: fix exporting with left over 64-bit inodes We now support mounting and using filesystems with 64-bit inodes even when not mounted with the inode64 option (which now only controls if we allocate new inodes in that space or not). Make sure we always use large NFS file handles when exporting a filesystem that may contain 64-bit inodes. Note that this only affects newly generated file handles, any outstanding 32-bit file handle is still accepted. [hch: the comment and commit log are mine, the rest is from a patch snipplet from Samuel] Signed-off-by: Christoph Hellwig Signed-off-by: Alex Elder --- fs/xfs/linux-2.6/xfs_export.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/fs/xfs/linux-2.6/xfs_export.c b/fs/xfs/linux-2.6/xfs_export.c index 3764d74790ec..fc0114da7fdd 100644 --- a/fs/xfs/linux-2.6/xfs_export.c +++ b/fs/xfs/linux-2.6/xfs_export.c @@ -70,8 +70,16 @@ xfs_fs_encode_fh( else fileid_type = FILEID_INO32_GEN_PARENT; - /* filesystem may contain 64bit inode numbers */ - if (!(XFS_M(inode->i_sb)->m_flags & XFS_MOUNT_SMALL_INUMS)) + /* + * If the the filesystem may contain 64bit inode numbers, we need + * to use larger file handles that can represent them. + * + * While we only allocate inodes that do not fit into 32 bits any + * large enough filesystem may contain them, thus the slightly + * confusing looking conditional below. + */ + if (!(XFS_M(inode->i_sb)->m_flags & XFS_MOUNT_SMALL_INUMS) || + (XFS_M(inode->i_sb)->m_flags & XFS_MOUNT_32BITINODES)) fileid_type |= XFS_FILEID_TYPE_64FLAG; /* -- cgit v1.2.3 From e2714bf8d5c8e131a6df6b0ea2269433e9a03a9b Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Wed, 1 Dec 2010 22:06:21 +0000 Subject: xfs: remove leftovers of old buffer log items in recovery code XFS used to support different types of buffer log items long time ago. Remove the switch statements checking the log item type in various buffer recovery helpers that were left over from those days and the rather useless xlog_recover_do_buffer_pass2 wrapper. Signed-off-by: Christoph Hellwig Signed-off-by: Alex Elder --- fs/xfs/xfs_log_recover.c | 155 ++++++++++++----------------------------------- 1 file changed, 40 insertions(+), 115 deletions(-) diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index 966d3f97458c..e51d93db1b0b 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c @@ -1614,22 +1614,13 @@ xlog_recover_do_buffer_pass1( xfs_buf_cancel_t *nextp; xfs_buf_cancel_t *prevp; xfs_buf_cancel_t **bucket; - xfs_daddr_t blkno = 0; - uint len = 0; - ushort flags = 0; - - switch (buf_f->blf_type) { - case XFS_LI_BUF: - blkno = buf_f->blf_blkno; - len = buf_f->blf_len; - flags = buf_f->blf_flags; - break; - } + xfs_daddr_t blkno = buf_f->blf_blkno; + uint len = buf_f->blf_len; /* * If this isn't a cancel buffer item, then just return. */ - if (!(flags & XFS_BLF_CANCEL)) { + if (!(buf_f->blf_flags & XFS_BLF_CANCEL)) { trace_xfs_log_recover_buf_not_cancel(log, buf_f); return; } @@ -1767,77 +1758,38 @@ xlog_check_buffer_cancelled( return 0; } -STATIC int -xlog_recover_do_buffer_pass2( - xlog_t *log, - xfs_buf_log_format_t *buf_f) -{ - xfs_daddr_t blkno = 0; - ushort flags = 0; - uint len = 0; - - switch (buf_f->blf_type) { - case XFS_LI_BUF: - blkno = buf_f->blf_blkno; - flags = buf_f->blf_flags; - len = buf_f->blf_len; - break; - } - - return xlog_check_buffer_cancelled(log, blkno, len, flags); -} - /* - * Perform recovery for a buffer full of inodes. In these buffers, - * the only data which should be recovered is that which corresponds - * to the di_next_unlinked pointers in the on disk inode structures. - * The rest of the data for the inodes is always logged through the - * inodes themselves rather than the inode buffer and is recovered - * in xlog_recover_do_inode_trans(). + * Perform recovery for a buffer full of inodes. In these buffers, the only + * data which should be recovered is that which corresponds to the + * di_next_unlinked pointers in the on disk inode structures. The rest of the + * data for the inodes is always logged through the inodes themselves rather + * than the inode buffer and is recovered in xlog_recover_inode_pass2(). * - * The only time when buffers full of inodes are fully recovered is - * when the buffer is full of newly allocated inodes. In this case - * the buffer will not be marked as an inode buffer and so will be - * sent to xlog_recover_do_reg_buffer() below during recovery. + * The only time when buffers full of inodes are fully recovered is when the + * buffer is full of newly allocated inodes. In this case the buffer will + * not be marked as an inode buffer and so will be sent to + * xlog_recover_do_reg_buffer() below during recovery. */ STATIC int xlog_recover_do_inode_buffer( - xfs_mount_t *mp, + struct xfs_mount *mp, xlog_recover_item_t *item, - xfs_buf_t *bp, + struct xfs_buf *bp, xfs_buf_log_format_t *buf_f) { int i; - int item_index; - int bit; - int nbits; - int reg_buf_offset; - int reg_buf_bytes; + int item_index = 0; + int bit = 0; + int nbits = 0; + int reg_buf_offset = 0; + int reg_buf_bytes = 0; int next_unlinked_offset; int inodes_per_buf; xfs_agino_t *logged_nextp; xfs_agino_t *buffer_nextp; - unsigned int *data_map = NULL; - unsigned int map_size = 0; trace_xfs_log_recover_buf_inode_buf(mp->m_log, buf_f); - switch (buf_f->blf_type) { - case XFS_LI_BUF: - data_map = buf_f->blf_data_map; - map_size = buf_f->blf_map_size; - break; - } - /* - * Set the variables corresponding to the current region to - * 0 so that we'll initialize them on the first pass through - * the loop. - */ - reg_buf_offset = 0; - reg_buf_bytes = 0; - bit = 0; - nbits = 0; - item_index = 0; inodes_per_buf = XFS_BUF_COUNT(bp) >> mp->m_sb.sb_inodelog; for (i = 0; i < inodes_per_buf; i++) { next_unlinked_offset = (i * mp->m_sb.sb_inodesize) + @@ -1852,18 +1804,18 @@ xlog_recover_do_inode_buffer( * the current di_next_unlinked field. */ bit += nbits; - bit = xfs_next_bit(data_map, map_size, bit); + bit = xfs_next_bit(buf_f->blf_data_map, + buf_f->blf_map_size, bit); /* * If there are no more logged regions in the * buffer, then we're done. */ - if (bit == -1) { + if (bit == -1) return 0; - } - nbits = xfs_contig_bits(data_map, map_size, - bit); + nbits = xfs_contig_bits(buf_f->blf_data_map, + buf_f->blf_map_size, bit); ASSERT(nbits > 0); reg_buf_offset = bit << XFS_BLF_SHIFT; reg_buf_bytes = nbits << XFS_BLF_SHIFT; @@ -1875,9 +1827,8 @@ xlog_recover_do_inode_buffer( * di_next_unlinked field, then move on to the next * di_next_unlinked field. */ - if (next_unlinked_offset < reg_buf_offset) { + if (next_unlinked_offset < reg_buf_offset) continue; - } ASSERT(item->ri_buf[item_index].i_addr != NULL); ASSERT((item->ri_buf[item_index].i_len % XFS_BLF_CHUNK) == 0); @@ -1913,36 +1864,29 @@ xlog_recover_do_inode_buffer( * given buffer. The bitmap in the buf log format structure indicates * where to place the logged data. */ -/*ARGSUSED*/ STATIC void xlog_recover_do_reg_buffer( struct xfs_mount *mp, xlog_recover_item_t *item, - xfs_buf_t *bp, + struct xfs_buf *bp, xfs_buf_log_format_t *buf_f) { int i; int bit; int nbits; - unsigned int *data_map = NULL; - unsigned int map_size = 0; int error; trace_xfs_log_recover_buf_reg_buf(mp->m_log, buf_f); - switch (buf_f->blf_type) { - case XFS_LI_BUF: - data_map = buf_f->blf_data_map; - map_size = buf_f->blf_map_size; - break; - } bit = 0; i = 1; /* 0 is the buf format structure */ while (1) { - bit = xfs_next_bit(data_map, map_size, bit); + bit = xfs_next_bit(buf_f->blf_data_map, + buf_f->blf_map_size, bit); if (bit == -1) break; - nbits = xfs_contig_bits(data_map, map_size, bit); + nbits = xfs_contig_bits(buf_f->blf_data_map, + buf_f->blf_map_size, bit); ASSERT(nbits > 0); ASSERT(item->ri_buf[i].i_addr != NULL); ASSERT(item->ri_buf[i].i_len % XFS_BLF_CHUNK == 0); @@ -2182,13 +2126,9 @@ xlog_recover_do_buffer_trans( int pass) { xfs_buf_log_format_t *buf_f = item->ri_buf[0].i_addr; - xfs_mount_t *mp; + xfs_mount_t *mp = log->l_mp; xfs_buf_t *bp; int error; - int cancel; - xfs_daddr_t blkno; - int len; - ushort flags; uint buf_flags; if (pass == XLOG_RECOVER_PASS1) { @@ -2206,47 +2146,32 @@ xlog_recover_do_buffer_trans( * we call here will tell us whether or not to * continue with the replay of this buffer. */ - cancel = xlog_recover_do_buffer_pass2(log, buf_f); - if (cancel) { + if (xlog_check_buffer_cancelled(log, buf_f->blf_blkno, + buf_f->blf_len, buf_f->blf_flags)) { trace_xfs_log_recover_buf_cancel(log, buf_f); return 0; } } trace_xfs_log_recover_buf_recover(log, buf_f); - switch (buf_f->blf_type) { - case XFS_LI_BUF: - blkno = buf_f->blf_blkno; - len = buf_f->blf_len; - flags = buf_f->blf_flags; - break; - default: - xfs_fs_cmn_err(CE_ALERT, log->l_mp, - "xfs_log_recover: unknown buffer type 0x%x, logdev %s", - buf_f->blf_type, log->l_mp->m_logname ? - log->l_mp->m_logname : "internal"); - XFS_ERROR_REPORT("xlog_recover_do_buffer_trans", - XFS_ERRLEVEL_LOW, log->l_mp); - return XFS_ERROR(EFSCORRUPTED); - } - mp = log->l_mp; buf_flags = XBF_LOCK; - if (!(flags & XFS_BLF_INODE_BUF)) + if (!(buf_f->blf_flags & XFS_BLF_INODE_BUF)) buf_flags |= XBF_MAPPED; - bp = xfs_buf_read(mp->m_ddev_targp, blkno, len, buf_flags); + bp = xfs_buf_read(mp->m_ddev_targp, buf_f->blf_blkno, buf_f->blf_len, + buf_flags); if (XFS_BUF_ISERROR(bp)) { - xfs_ioerror_alert("xlog_recover_do..(read#1)", log->l_mp, - bp, blkno); + xfs_ioerror_alert("xlog_recover_do..(read#1)", mp, + bp, buf_f->blf_blkno); error = XFS_BUF_GETERROR(bp); xfs_buf_relse(bp); return error; } error = 0; - if (flags & XFS_BLF_INODE_BUF) { + if (buf_f->blf_flags & XFS_BLF_INODE_BUF) { error = xlog_recover_do_inode_buffer(mp, item, bp, buf_f); - } else if (flags & + } else if (buf_f->blf_flags & (XFS_BLF_UDQUOT_BUF|XFS_BLF_PDQUOT_BUF|XFS_BLF_GDQUOT_BUF)) { xlog_recover_do_dquot_buffer(mp, log, item, bp, buf_f); } else { -- cgit v1.2.3 From d5689eaa0ac5588cf459ee32f86d5700dd7d6403 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Wed, 1 Dec 2010 22:06:22 +0000 Subject: xfs: use struct list_head for the buf cancel table Signed-off-by: Christoph Hellwig Signed-off-by: Alex Elder --- fs/xfs/xfs_buf_item.h | 11 ---- fs/xfs/xfs_log_priv.h | 6 +- fs/xfs/xfs_log_recover.c | 159 ++++++++++++++++++----------------------------- 3 files changed, 65 insertions(+), 111 deletions(-) diff --git a/fs/xfs/xfs_buf_item.h b/fs/xfs/xfs_buf_item.h index 0e2ed43f16c7..b6ecd2061e7c 100644 --- a/fs/xfs/xfs_buf_item.h +++ b/fs/xfs/xfs_buf_item.h @@ -105,17 +105,6 @@ typedef struct xfs_buf_log_item { xfs_buf_log_format_t bli_format; /* in-log header */ } xfs_buf_log_item_t; -/* - * This structure is used during recovery to record the buf log - * items which have been canceled and should not be replayed. - */ -typedef struct xfs_buf_cancel { - xfs_daddr_t bc_blkno; - uint bc_len; - int bc_refcount; - struct xfs_buf_cancel *bc_next; -} xfs_buf_cancel_t; - void xfs_buf_item_init(struct xfs_buf *, struct xfs_mount *); void xfs_buf_item_relse(struct xfs_buf *); void xfs_buf_item_log(xfs_buf_log_item_t *, uint, uint); diff --git a/fs/xfs/xfs_log_priv.h b/fs/xfs/xfs_log_priv.h index edcdfe01617f..c1ce505313e9 100644 --- a/fs/xfs/xfs_log_priv.h +++ b/fs/xfs/xfs_log_priv.h @@ -21,7 +21,6 @@ struct xfs_buf; struct log; struct xlog_ticket; -struct xfs_buf_cancel; struct xfs_mount; /* @@ -491,7 +490,7 @@ typedef struct log { struct xfs_buftarg *l_targ; /* buftarg of log */ uint l_flags; uint l_quotaoffs_flag; /* XFS_DQ_*, for QUOTAOFFs */ - struct xfs_buf_cancel **l_buf_cancel_table; + struct list_head *l_buf_cancel_table; int l_iclog_hsize; /* size of iclog header */ int l_iclog_heads; /* # of iclog header sectors */ uint l_sectBBsize; /* sector size in BBs (2^n) */ @@ -534,6 +533,9 @@ typedef struct log { } xlog_t; +#define XLOG_BUF_CANCEL_BUCKET(log, blkno) \ + ((log)->l_buf_cancel_table + ((__uint64_t)blkno % XLOG_BC_TABLE_SIZE)) + #define XLOG_FORCED_SHUTDOWN(log) ((log)->l_flags & XLOG_IO_ERROR) /* common routines */ diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index e51d93db1b0b..960afd41315e 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c @@ -52,6 +52,17 @@ STATIC void xlog_recover_check_summary(xlog_t *); #define xlog_recover_check_summary(log) #endif +/* + * This structure is used during recovery to record the buf log items which + * have been canceled and should not be replayed. + */ +struct xfs_buf_cancel { + xfs_daddr_t bc_blkno; + uint bc_len; + int bc_refcount; + struct list_head bc_list; +}; + /* * Sector aligned buffer routines for buffer create/read/write/access */ @@ -1607,15 +1618,11 @@ xlog_recover_reorder_trans( */ STATIC void xlog_recover_do_buffer_pass1( - xlog_t *log, + struct log *log, xfs_buf_log_format_t *buf_f) { - xfs_buf_cancel_t *bcp; - xfs_buf_cancel_t *nextp; - xfs_buf_cancel_t *prevp; - xfs_buf_cancel_t **bucket; - xfs_daddr_t blkno = buf_f->blf_blkno; - uint len = buf_f->blf_len; + struct list_head *bucket; + struct xfs_buf_cancel *bcp; /* * If this isn't a cancel buffer item, then just return. @@ -1626,51 +1633,25 @@ xlog_recover_do_buffer_pass1( } /* - * Insert an xfs_buf_cancel record into the hash table of - * them. If there is already an identical record, bump - * its reference count. - */ - bucket = &log->l_buf_cancel_table[(__uint64_t)blkno % - XLOG_BC_TABLE_SIZE]; - /* - * If the hash bucket is empty then just insert a new record into - * the bucket. - */ - if (*bucket == NULL) { - bcp = (xfs_buf_cancel_t *)kmem_alloc(sizeof(xfs_buf_cancel_t), - KM_SLEEP); - bcp->bc_blkno = blkno; - bcp->bc_len = len; - bcp->bc_refcount = 1; - bcp->bc_next = NULL; - *bucket = bcp; - return; - } - - /* - * The hash bucket is not empty, so search for duplicates of our - * record. If we find one them just bump its refcount. If not - * then add us at the end of the list. + * Insert an xfs_buf_cancel record into the hash table of them. + * If there is already an identical record, bump its reference count. */ - prevp = NULL; - nextp = *bucket; - while (nextp != NULL) { - if (nextp->bc_blkno == blkno && nextp->bc_len == len) { - nextp->bc_refcount++; + bucket = XLOG_BUF_CANCEL_BUCKET(log, buf_f->blf_blkno); + list_for_each_entry(bcp, bucket, bc_list) { + if (bcp->bc_blkno == buf_f->blf_blkno && + bcp->bc_len == buf_f->blf_len) { + bcp->bc_refcount++; trace_xfs_log_recover_buf_cancel_ref_inc(log, buf_f); return; } - prevp = nextp; - nextp = nextp->bc_next; - } - ASSERT(prevp != NULL); - bcp = (xfs_buf_cancel_t *)kmem_alloc(sizeof(xfs_buf_cancel_t), - KM_SLEEP); - bcp->bc_blkno = blkno; - bcp->bc_len = len; + } + + bcp = kmem_alloc(sizeof(struct xfs_buf_cancel), KM_SLEEP); + bcp->bc_blkno = buf_f->blf_blkno; + bcp->bc_len = buf_f->blf_len; bcp->bc_refcount = 1; - bcp->bc_next = NULL; - prevp->bc_next = bcp; + list_add_tail(&bcp->bc_list, bucket); + trace_xfs_log_recover_buf_cancel_add(log, buf_f); } @@ -1689,14 +1670,13 @@ xlog_recover_do_buffer_pass1( */ STATIC int xlog_check_buffer_cancelled( - xlog_t *log, + struct log *log, xfs_daddr_t blkno, uint len, ushort flags) { - xfs_buf_cancel_t *bcp; - xfs_buf_cancel_t *prevp; - xfs_buf_cancel_t **bucket; + struct list_head *bucket; + struct xfs_buf_cancel *bcp; if (log->l_buf_cancel_table == NULL) { /* @@ -1707,55 +1687,36 @@ xlog_check_buffer_cancelled( return 0; } - bucket = &log->l_buf_cancel_table[(__uint64_t)blkno % - XLOG_BC_TABLE_SIZE]; - bcp = *bucket; - if (bcp == NULL) { - /* - * There is no corresponding entry in the table built - * in pass one, so this buffer has not been cancelled. - */ - ASSERT(!(flags & XFS_BLF_CANCEL)); - return 0; - } - /* - * Search for an entry in the buffer cancel table that - * matches our buffer. + * Search for an entry in the cancel table that matches our buffer. */ - prevp = NULL; - while (bcp != NULL) { - if (bcp->bc_blkno == blkno && bcp->bc_len == len) { - /* - * We've go a match, so return 1 so that the - * recovery of this buffer is cancelled. - * If this buffer is actually a buffer cancel - * log item, then decrement the refcount on the - * one in the table and remove it if this is the - * last reference. - */ - if (flags & XFS_BLF_CANCEL) { - bcp->bc_refcount--; - if (bcp->bc_refcount == 0) { - if (prevp == NULL) { - *bucket = bcp->bc_next; - } else { - prevp->bc_next = bcp->bc_next; - } - kmem_free(bcp); - } - } - return 1; - } - prevp = bcp; - bcp = bcp->bc_next; + bucket = XLOG_BUF_CANCEL_BUCKET(log, blkno); + list_for_each_entry(bcp, bucket, bc_list) { + if (bcp->bc_blkno == blkno && bcp->bc_len == len) + goto found; } + /* - * We didn't find a corresponding entry in the table, so - * return 0 so that the buffer is NOT cancelled. + * We didn't find a corresponding entry in the table, so return 0 so + * that the buffer is NOT cancelled. */ ASSERT(!(flags & XFS_BLF_CANCEL)); return 0; + +found: + /* + * We've go a match, so return 1 so that the recovery of this buffer + * is cancelled. If this buffer is actually a buffer cancel log + * item, then decrement the refcount on the one in the table and + * remove it if this is the last reference. + */ + if (flags & XFS_BLF_CANCEL) { + if (--bcp->bc_refcount == 0) { + list_del(&bcp->bc_list); + kmem_free(bcp); + } + } + return 1; } /* @@ -3649,7 +3610,7 @@ xlog_do_log_recovery( xfs_daddr_t head_blk, xfs_daddr_t tail_blk) { - int error; + int error, i; ASSERT(head_blk != tail_blk); @@ -3657,10 +3618,12 @@ xlog_do_log_recovery( * First do a pass to find all of the cancelled buf log items. * Store them in the buf_cancel_table for use in the second pass. */ - log->l_buf_cancel_table = - (xfs_buf_cancel_t **)kmem_zalloc(XLOG_BC_TABLE_SIZE * - sizeof(xfs_buf_cancel_t*), + log->l_buf_cancel_table = kmem_zalloc(XLOG_BC_TABLE_SIZE * + sizeof(struct list_head), KM_SLEEP); + for (i = 0; i < XLOG_BC_TABLE_SIZE; i++) + INIT_LIST_HEAD(&log->l_buf_cancel_table[i]); + error = xlog_do_recovery_pass(log, head_blk, tail_blk, XLOG_RECOVER_PASS1); if (error != 0) { @@ -3679,7 +3642,7 @@ xlog_do_log_recovery( int i; for (i = 0; i < XLOG_BC_TABLE_SIZE; i++) - ASSERT(log->l_buf_cancel_table[i] == NULL); + ASSERT(list_empty(&log->l_buf_cancel_table[i])); } #endif /* DEBUG */ -- cgit v1.2.3 From d0450948641b2090b5d467ba638bbebd40b20b21 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Wed, 1 Dec 2010 22:06:23 +0000 Subject: xfs: refactor xlog_recover_commit_trans Merge the call to xlog_recover_reorder_trans and the loop over the recovery items from xlog_recover_do_trans into xlog_recover_commit_trans, and keep the switch statement over the log item types as a separate helper. Signed-off-by: Christoph Hellwig Signed-off-by: Alex Elder --- fs/xfs/xfs_log_recover.c | 117 +++++++++++++++++++++-------------------------- 1 file changed, 53 insertions(+), 64 deletions(-) diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index 960afd41315e..26e18052a648 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c @@ -2673,64 +2673,6 @@ xlog_recover_do_efd_trans( spin_unlock(&ailp->xa_lock); } -/* - * Perform the transaction - * - * If the transaction modifies a buffer or inode, do it now. Otherwise, - * EFIs and EFDs get queued up by adding entries into the AIL for them. - */ -STATIC int -xlog_recover_do_trans( - xlog_t *log, - xlog_recover_t *trans, - int pass) -{ - int error = 0; - xlog_recover_item_t *item; - - error = xlog_recover_reorder_trans(log, trans, pass); - if (error) - return error; - - list_for_each_entry(item, &trans->r_itemq, ri_list) { - trace_xfs_log_recover_item_recover(log, trans, item, pass); - switch (ITEM_TYPE(item)) { - case XFS_LI_BUF: - error = xlog_recover_do_buffer_trans(log, item, pass); - break; - case XFS_LI_INODE: - error = xlog_recover_do_inode_trans(log, item, pass); - break; - case XFS_LI_EFI: - error = xlog_recover_do_efi_trans(log, item, - trans->r_lsn, pass); - break; - case XFS_LI_EFD: - xlog_recover_do_efd_trans(log, item, pass); - error = 0; - break; - case XFS_LI_DQUOT: - error = xlog_recover_do_dquot_trans(log, item, pass); - break; - case XFS_LI_QUOTAOFF: - error = xlog_recover_do_quotaoff_trans(log, item, - pass); - break; - default: - xlog_warn( - "XFS: invalid item type (%d) xlog_recover_do_trans", ITEM_TYPE(item)); - ASSERT(0); - error = XFS_ERROR(EIO); - break; - } - - if (error) - return error; - } - - return 0; -} - /* * Free up any resources allocated by the transaction * @@ -2738,7 +2680,7 @@ xlog_recover_do_trans( */ STATIC void xlog_recover_free_trans( - xlog_recover_t *trans) + struct xlog_recover *trans) { xlog_recover_item_t *item, *n; int i; @@ -2756,18 +2698,65 @@ xlog_recover_free_trans( kmem_free(trans); } +STATIC int +xlog_recover_commit_item( + struct log *log, + struct xlog_recover *trans, + xlog_recover_item_t *item, + int pass) +{ + trace_xfs_log_recover_item_recover(log, trans, item, pass); + + switch (ITEM_TYPE(item)) { + case XFS_LI_BUF: + return xlog_recover_do_buffer_trans(log, item, pass); + case XFS_LI_INODE: + return xlog_recover_do_inode_trans(log, item, pass); + case XFS_LI_EFI: + return xlog_recover_do_efi_trans(log, item, trans->r_lsn, pass); + case XFS_LI_EFD: + xlog_recover_do_efd_trans(log, item, pass); + return 0; + case XFS_LI_DQUOT: + return xlog_recover_do_dquot_trans(log, item, pass); + case XFS_LI_QUOTAOFF: + return xlog_recover_do_quotaoff_trans(log, item, pass); + default: + xlog_warn( + "XFS: invalid item type (%d) xlog_recover_do_trans", ITEM_TYPE(item)); + ASSERT(0); + return XFS_ERROR(EIO); + } +} + +/* + * Perform the transaction. + * + * If the transaction modifies a buffer or inode, do it now. Otherwise, + * EFIs and EFDs get queued up by adding entries into the AIL for them. + */ STATIC int xlog_recover_commit_trans( - xlog_t *log, - xlog_recover_t *trans, + struct log *log, + struct xlog_recover *trans, int pass) { - int error; + int error = 0; + xlog_recover_item_t *item; hlist_del(&trans->r_list); - if ((error = xlog_recover_do_trans(log, trans, pass))) + + error = xlog_recover_reorder_trans(log, trans, pass); + if (error) return error; - xlog_recover_free_trans(trans); /* no error */ + + list_for_each_entry(item, &trans->r_itemq, ri_list) { + error = xlog_recover_commit_item(log, trans, item, pass); + if (error) + return error; + } + + xlog_recover_free_trans(trans); return 0; } -- cgit v1.2.3 From c9f71f5fc4390ea3a8087c00d53a799e7e0f0f8e Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Wed, 1 Dec 2010 22:06:24 +0000 Subject: xfs: untangle phase1 vs phase2 recovery helpers Dispatch to a different helper for phase1 vs phase2 in xlog_recover_commit_trans instead of doing it in all the low-level functions. Signed-off-by: Christoph Hellwig Signed-off-by: Alex Elder --- fs/xfs/xfs_log_recover.c | 194 +++++++++++++++++++++++------------------------ 1 file changed, 93 insertions(+), 101 deletions(-) diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index 26e18052a648..4ab4f6ff48aa 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c @@ -1616,11 +1616,12 @@ xlog_recover_reorder_trans( * record in the table to tell us how many times we expect to see this * record during the second pass. */ -STATIC void -xlog_recover_do_buffer_pass1( +STATIC int +xlog_recover_buffer_pass1( struct log *log, - xfs_buf_log_format_t *buf_f) + xlog_recover_item_t *item) { + xfs_buf_log_format_t *buf_f = item->ri_buf[0].i_addr; struct list_head *bucket; struct xfs_buf_cancel *bcp; @@ -1629,7 +1630,7 @@ xlog_recover_do_buffer_pass1( */ if (!(buf_f->blf_flags & XFS_BLF_CANCEL)) { trace_xfs_log_recover_buf_not_cancel(log, buf_f); - return; + return 0; } /* @@ -1642,7 +1643,7 @@ xlog_recover_do_buffer_pass1( bcp->bc_len == buf_f->blf_len) { bcp->bc_refcount++; trace_xfs_log_recover_buf_cancel_ref_inc(log, buf_f); - return; + return 0; } } @@ -1653,6 +1654,7 @@ xlog_recover_do_buffer_pass1( list_add_tail(&bcp->bc_list, bucket); trace_xfs_log_recover_buf_cancel_add(log, buf_f); + return 0; } /* @@ -2081,10 +2083,9 @@ xlog_recover_do_dquot_buffer( * for more details on the implementation of the table of cancel records. */ STATIC int -xlog_recover_do_buffer_trans( +xlog_recover_buffer_pass2( xlog_t *log, - xlog_recover_item_t *item, - int pass) + xlog_recover_item_t *item) { xfs_buf_log_format_t *buf_f = item->ri_buf[0].i_addr; xfs_mount_t *mp = log->l_mp; @@ -2092,27 +2093,16 @@ xlog_recover_do_buffer_trans( int error; uint buf_flags; - if (pass == XLOG_RECOVER_PASS1) { - /* - * In this pass we're only looking for buf items - * with the XFS_BLF_CANCEL bit set. - */ - xlog_recover_do_buffer_pass1(log, buf_f); + /* + * In this pass we only want to recover all the buffers which have + * not been cancelled and are not cancellation buffers themselves. + */ + if (xlog_check_buffer_cancelled(log, buf_f->blf_blkno, + buf_f->blf_len, buf_f->blf_flags)) { + trace_xfs_log_recover_buf_cancel(log, buf_f); return 0; - } else { - /* - * In this pass we want to recover all the buffers - * which have not been cancelled and are not - * cancellation buffers themselves. The routine - * we call here will tell us whether or not to - * continue with the replay of this buffer. - */ - if (xlog_check_buffer_cancelled(log, buf_f->blf_blkno, - buf_f->blf_len, buf_f->blf_flags)) { - trace_xfs_log_recover_buf_cancel(log, buf_f); - return 0; - } } + trace_xfs_log_recover_buf_recover(log, buf_f); buf_flags = XBF_LOCK; @@ -2172,16 +2162,14 @@ xlog_recover_do_buffer_trans( } STATIC int -xlog_recover_do_inode_trans( +xlog_recover_inode_pass2( xlog_t *log, - xlog_recover_item_t *item, - int pass) + xlog_recover_item_t *item) { xfs_inode_log_format_t *in_f; - xfs_mount_t *mp; + xfs_mount_t *mp = log->l_mp; xfs_buf_t *bp; xfs_dinode_t *dip; - xfs_ino_t ino; int len; xfs_caddr_t src; xfs_caddr_t dest; @@ -2191,10 +2179,6 @@ xlog_recover_do_inode_trans( xfs_icdinode_t *dicp; int need_free = 0; - if (pass == XLOG_RECOVER_PASS1) { - return 0; - } - if (item->ri_buf[0].i_len == sizeof(xfs_inode_log_format_t)) { in_f = item->ri_buf[0].i_addr; } else { @@ -2204,8 +2188,6 @@ xlog_recover_do_inode_trans( if (error) goto error; } - ino = in_f->ilf_ino; - mp = log->l_mp; /* * Inode buffers can be freed, look out for it, @@ -2240,8 +2222,8 @@ xlog_recover_do_inode_trans( xfs_buf_relse(bp); xfs_fs_cmn_err(CE_ALERT, mp, "xfs_inode_recover: Bad inode magic number, dino ptr = 0x%p, dino bp = 0x%p, ino = %Ld", - dip, bp, ino); - XFS_ERROR_REPORT("xlog_recover_do_inode_trans(1)", + dip, bp, in_f->ilf_ino); + XFS_ERROR_REPORT("xlog_recover_inode_pass2(1)", XFS_ERRLEVEL_LOW, mp); error = EFSCORRUPTED; goto error; @@ -2251,8 +2233,8 @@ xlog_recover_do_inode_trans( xfs_buf_relse(bp); xfs_fs_cmn_err(CE_ALERT, mp, "xfs_inode_recover: Bad inode log record, rec ptr 0x%p, ino %Ld", - item, ino); - XFS_ERROR_REPORT("xlog_recover_do_inode_trans(2)", + item, in_f->ilf_ino); + XFS_ERROR_REPORT("xlog_recover_inode_pass2(2)", XFS_ERRLEVEL_LOW, mp); error = EFSCORRUPTED; goto error; @@ -2280,12 +2262,12 @@ xlog_recover_do_inode_trans( if (unlikely((dicp->di_mode & S_IFMT) == S_IFREG)) { if ((dicp->di_format != XFS_DINODE_FMT_EXTENTS) && (dicp->di_format != XFS_DINODE_FMT_BTREE)) { - XFS_CORRUPTION_ERROR("xlog_recover_do_inode_trans(3)", + XFS_CORRUPTION_ERROR("xlog_recover_inode_pass2(3)", XFS_ERRLEVEL_LOW, mp, dicp); xfs_buf_relse(bp); xfs_fs_cmn_err(CE_ALERT, mp, "xfs_inode_recover: Bad regular inode log record, rec ptr 0x%p, ino ptr = 0x%p, ino bp = 0x%p, ino %Ld", - item, dip, bp, ino); + item, dip, bp, in_f->ilf_ino); error = EFSCORRUPTED; goto error; } @@ -2293,40 +2275,40 @@ xlog_recover_do_inode_trans( if ((dicp->di_format != XFS_DINODE_FMT_EXTENTS) && (dicp->di_format != XFS_DINODE_FMT_BTREE) && (dicp->di_format != XFS_DINODE_FMT_LOCAL)) { - XFS_CORRUPTION_ERROR("xlog_recover_do_inode_trans(4)", + XFS_CORRUPTION_ERROR("xlog_recover_inode_pass2(4)", XFS_ERRLEVEL_LOW, mp, dicp); xfs_buf_relse(bp); xfs_fs_cmn_err(CE_ALERT, mp, "xfs_inode_recover: Bad dir inode log record, rec ptr 0x%p, ino ptr = 0x%p, ino bp = 0x%p, ino %Ld", - item, dip, bp, ino); + item, dip, bp, in_f->ilf_ino); error = EFSCORRUPTED; goto error; } } if (unlikely(dicp->di_nextents + dicp->di_anextents > dicp->di_nblocks)){ - XFS_CORRUPTION_ERROR("xlog_recover_do_inode_trans(5)", + XFS_CORRUPTION_ERROR("xlog_recover_inode_pass2(5)", XFS_ERRLEVEL_LOW, mp, dicp); xfs_buf_relse(bp); xfs_fs_cmn_err(CE_ALERT, mp, "xfs_inode_recover: Bad inode log record, rec ptr 0x%p, dino ptr 0x%p, dino bp 0x%p, ino %Ld, total extents = %d, nblocks = %Ld", - item, dip, bp, ino, + item, dip, bp, in_f->ilf_ino, dicp->di_nextents + dicp->di_anextents, dicp->di_nblocks); error = EFSCORRUPTED; goto error; } if (unlikely(dicp->di_forkoff > mp->m_sb.sb_inodesize)) { - XFS_CORRUPTION_ERROR("xlog_recover_do_inode_trans(6)", + XFS_CORRUPTION_ERROR("xlog_recover_inode_pass2(6)", XFS_ERRLEVEL_LOW, mp, dicp); xfs_buf_relse(bp); xfs_fs_cmn_err(CE_ALERT, mp, "xfs_inode_recover: Bad inode log rec ptr 0x%p, dino ptr 0x%p, dino bp 0x%p, ino %Ld, forkoff 0x%x", - item, dip, bp, ino, dicp->di_forkoff); + item, dip, bp, in_f->ilf_ino, dicp->di_forkoff); error = EFSCORRUPTED; goto error; } if (unlikely(item->ri_buf[1].i_len > sizeof(struct xfs_icdinode))) { - XFS_CORRUPTION_ERROR("xlog_recover_do_inode_trans(7)", + XFS_CORRUPTION_ERROR("xlog_recover_inode_pass2(7)", XFS_ERRLEVEL_LOW, mp, dicp); xfs_buf_relse(bp); xfs_fs_cmn_err(CE_ALERT, mp, @@ -2418,7 +2400,7 @@ xlog_recover_do_inode_trans( break; default: - xlog_warn("XFS: xlog_recover_do_inode_trans: Invalid flag"); + xlog_warn("XFS: xlog_recover_inode_pass2: Invalid flag"); ASSERT(0); xfs_buf_relse(bp); error = EIO; @@ -2442,18 +2424,11 @@ error: * of that type. */ STATIC int -xlog_recover_do_quotaoff_trans( +xlog_recover_quotaoff_pass1( xlog_t *log, - xlog_recover_item_t *item, - int pass) + xlog_recover_item_t *item) { - xfs_qoff_logformat_t *qoff_f; - - if (pass == XLOG_RECOVER_PASS2) { - return (0); - } - - qoff_f = item->ri_buf[0].i_addr; + xfs_qoff_logformat_t *qoff_f = item->ri_buf[0].i_addr; ASSERT(qoff_f); /* @@ -2474,22 +2449,17 @@ xlog_recover_do_quotaoff_trans( * Recover a dquot record */ STATIC int -xlog_recover_do_dquot_trans( +xlog_recover_dquot_pass2( xlog_t *log, - xlog_recover_item_t *item, - int pass) + xlog_recover_item_t *item) { - xfs_mount_t *mp; + xfs_mount_t *mp = log->l_mp; xfs_buf_t *bp; struct xfs_disk_dquot *ddq, *recddq; int error; xfs_dq_logformat_t *dq_f; uint type; - if (pass == XLOG_RECOVER_PASS1) { - return 0; - } - mp = log->l_mp; /* * Filesystems are required to send in quota flags at mount time. @@ -2533,7 +2503,7 @@ xlog_recover_do_dquot_trans( if ((error = xfs_qm_dqcheck(recddq, dq_f->qlf_id, 0, XFS_QMOPT_DOWARN, - "xlog_recover_do_dquot_trans (log copy)"))) { + "xlog_recover_dquot_pass2 (log copy)"))) { return XFS_ERROR(EIO); } ASSERT(dq_f->qlf_len == 1); @@ -2556,7 +2526,7 @@ xlog_recover_do_dquot_trans( * minimal initialization then. */ if (xfs_qm_dqcheck(ddq, dq_f->qlf_id, 0, XFS_QMOPT_DOWARN, - "xlog_recover_do_dquot_trans")) { + "xlog_recover_dquot_pass2")) { xfs_buf_relse(bp); return XFS_ERROR(EIO); } @@ -2579,24 +2549,18 @@ xlog_recover_do_dquot_trans( * LSN. */ STATIC int -xlog_recover_do_efi_trans( +xlog_recover_efi_pass2( xlog_t *log, xlog_recover_item_t *item, - xfs_lsn_t lsn, - int pass) + xfs_lsn_t lsn) { int error; - xfs_mount_t *mp; + xfs_mount_t *mp = log->l_mp; xfs_efi_log_item_t *efip; xfs_efi_log_format_t *efi_formatp; - if (pass == XLOG_RECOVER_PASS1) { - return 0; - } - efi_formatp = item->ri_buf[0].i_addr; - mp = log->l_mp; efip = xfs_efi_init(mp, efi_formatp->efi_nextents); if ((error = xfs_efi_copy_format(&(item->ri_buf[0]), &(efip->efi_format)))) { @@ -2623,11 +2587,10 @@ xlog_recover_do_efi_trans( * efd format structure. If we find it, we remove the efi from the * AIL and free it. */ -STATIC void -xlog_recover_do_efd_trans( +STATIC int +xlog_recover_efd_pass2( xlog_t *log, - xlog_recover_item_t *item, - int pass) + xlog_recover_item_t *item) { xfs_efd_log_format_t *efd_formatp; xfs_efi_log_item_t *efip = NULL; @@ -2636,10 +2599,6 @@ xlog_recover_do_efd_trans( struct xfs_ail_cursor cur; struct xfs_ail *ailp = log->l_ailp; - if (pass == XLOG_RECOVER_PASS1) { - return; - } - efd_formatp = item->ri_buf[0].i_addr; ASSERT((item->ri_buf[0].i_len == (sizeof(xfs_efd_log_format_32_t) + ((efd_formatp->efd_nextents - 1) * sizeof(xfs_extent_32_t)))) || @@ -2671,6 +2630,8 @@ xlog_recover_do_efd_trans( } xfs_trans_ail_cursor_done(ailp, &cur); spin_unlock(&ailp->xa_lock); + + return 0; } /* @@ -2699,31 +2660,59 @@ xlog_recover_free_trans( } STATIC int -xlog_recover_commit_item( +xlog_recover_commit_pass1( struct log *log, struct xlog_recover *trans, - xlog_recover_item_t *item, - int pass) + xlog_recover_item_t *item) { - trace_xfs_log_recover_item_recover(log, trans, item, pass); + trace_xfs_log_recover_item_recover(log, trans, item, XLOG_RECOVER_PASS1); switch (ITEM_TYPE(item)) { case XFS_LI_BUF: - return xlog_recover_do_buffer_trans(log, item, pass); + return xlog_recover_buffer_pass1(log, item); + case XFS_LI_QUOTAOFF: + return xlog_recover_quotaoff_pass1(log, item); case XFS_LI_INODE: - return xlog_recover_do_inode_trans(log, item, pass); case XFS_LI_EFI: - return xlog_recover_do_efi_trans(log, item, trans->r_lsn, pass); case XFS_LI_EFD: - xlog_recover_do_efd_trans(log, item, pass); + case XFS_LI_DQUOT: + /* nothing to do in pass 1 */ return 0; + default: + xlog_warn( + "XFS: invalid item type (%d) xlog_recover_commit_pass1", + ITEM_TYPE(item)); + ASSERT(0); + return XFS_ERROR(EIO); + } +} + +STATIC int +xlog_recover_commit_pass2( + struct log *log, + struct xlog_recover *trans, + xlog_recover_item_t *item) +{ + trace_xfs_log_recover_item_recover(log, trans, item, XLOG_RECOVER_PASS2); + + switch (ITEM_TYPE(item)) { + case XFS_LI_BUF: + return xlog_recover_buffer_pass2(log, item); + case XFS_LI_INODE: + return xlog_recover_inode_pass2(log, item); + case XFS_LI_EFI: + return xlog_recover_efi_pass2(log, item, trans->r_lsn); + case XFS_LI_EFD: + return xlog_recover_efd_pass2(log, item); case XFS_LI_DQUOT: - return xlog_recover_do_dquot_trans(log, item, pass); + return xlog_recover_dquot_pass2(log, item); case XFS_LI_QUOTAOFF: - return xlog_recover_do_quotaoff_trans(log, item, pass); + /* nothing to do in pass2 */ + return 0; default: xlog_warn( - "XFS: invalid item type (%d) xlog_recover_do_trans", ITEM_TYPE(item)); + "XFS: invalid item type (%d) xlog_recover_commit_pass2", + ITEM_TYPE(item)); ASSERT(0); return XFS_ERROR(EIO); } @@ -2751,7 +2740,10 @@ xlog_recover_commit_trans( return error; list_for_each_entry(item, &trans->r_itemq, ri_list) { - error = xlog_recover_commit_item(log, trans, item, pass); + if (pass == XLOG_RECOVER_PASS1) + error = xlog_recover_commit_pass1(log, trans, item); + else + error = xlog_recover_commit_pass2(log, trans, item); if (error) return error; } -- cgit v1.2.3 From 85da94c6b4666582c38579ccdcd90a5d9b5697ef Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Fri, 10 Dec 2010 08:42:16 +0000 Subject: xfs: improve mapping type check in xfs_vm_writepage Currently we only refuse a "read-only" mapping for writing out unwritten and delayed buffers, and refuse any other for overwrites. Improve the checks to require delalloc mappings for delayed buffers, and unwritten extent mappings for unwritten extents. Signed-off-by: Christoph Hellwig Reviewed-by: Dave Chinner Signed-off-by: Alex Elder --- fs/xfs/linux-2.6/xfs_aops.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/fs/xfs/linux-2.6/xfs_aops.c b/fs/xfs/linux-2.6/xfs_aops.c index 691f61223ed6..23a7668e07da 100644 --- a/fs/xfs/linux-2.6/xfs_aops.c +++ b/fs/xfs/linux-2.6/xfs_aops.c @@ -1082,17 +1082,17 @@ xfs_vm_writepage( if (buffer_unwritten(bh) || buffer_delay(bh)) { int new_ioend = 0; - /* - * Make sure we don't use a read-only iomap - */ - if (flags == BMAPI_READ) - imap_valid = 0; - if (buffer_unwritten(bh)) { - type = IO_UNWRITTEN; + if (type != IO_UNWRITTEN) { + type = IO_UNWRITTEN; + imap_valid = 0; + } flags = BMAPI_WRITE | BMAPI_IGNSTATE; } else if (buffer_delay(bh)) { - type = IO_DELAY; + if (type != IO_DELAY) { + type = IO_DELAY; + imap_valid = 0; + } flags = BMAPI_ALLOCATE; if (wbc->sync_mode == WB_SYNC_NONE) @@ -1128,8 +1128,11 @@ xfs_vm_writepage( * That means it must already have extents allocated * underneath it. Map the extent by reading it. */ - if (!imap_valid || flags != BMAPI_READ) { + if (flags != BMAPI_READ) { flags = BMAPI_READ; + imap_valid = 0; + } + if (!imap_valid) { size = xfs_probe_cluster(inode, page, bh, head); err = xfs_map_blocks(inode, offset, size, &imap, flags); -- cgit v1.2.3 From 221cb2517e8fc9a1d67c7a8a9c19fc5a916b583f Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Fri, 10 Dec 2010 08:42:17 +0000 Subject: xfs: remove some dead bio handling code We'll never have BIO_EOPNOTSUPP set after calling submit_bio as this can only happen for discards, and used to happen for barriers, none of which is every submitted by xfs_submit_ioend_bio. Also remove the loop around bio_alloc as it will never fail due to it's mempool backing. Signed-off-by: Christoph Hellwig Reviewed-by: Dave Chinner Signed-off-by: Alex Elder --- fs/xfs/linux-2.6/xfs_aops.c | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/fs/xfs/linux-2.6/xfs_aops.c b/fs/xfs/linux-2.6/xfs_aops.c index 23a7668e07da..ca67ae92c238 100644 --- a/fs/xfs/linux-2.6/xfs_aops.c +++ b/fs/xfs/linux-2.6/xfs_aops.c @@ -380,26 +380,18 @@ xfs_submit_ioend_bio( submit_bio(wbc->sync_mode == WB_SYNC_ALL ? WRITE_SYNC_PLUG : WRITE, bio); - ASSERT(!bio_flagged(bio, BIO_EOPNOTSUPP)); - bio_put(bio); } STATIC struct bio * xfs_alloc_ioend_bio( struct buffer_head *bh) { - struct bio *bio; int nvecs = bio_get_nr_vecs(bh->b_bdev); - - do { - bio = bio_alloc(GFP_NOIO, nvecs); - nvecs >>= 1; - } while (!bio); + struct bio *bio = bio_alloc(GFP_NOIO, nvecs); ASSERT(bio->bi_private == NULL); bio->bi_sector = bh->b_blocknr * (bh->b_size >> 9); bio->bi_bdev = bh->b_bdev; - bio_get(bio); return bio; } @@ -470,9 +462,8 @@ xfs_submit_ioend( /* Pass 1 - start writeback */ do { next = ioend->io_list; - for (bh = ioend->io_buffer_head; bh; bh = bh->b_private) { + for (bh = ioend->io_buffer_head; bh; bh = bh->b_private) xfs_start_buffer_writeback(bh); - } } while ((ioend = next) != NULL); /* Pass 2 - submit I/O */ -- cgit v1.2.3 From 6ac7248ec5f20cb44a063d7c7191b8e0068b5a28 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Fri, 10 Dec 2010 08:42:18 +0000 Subject: xfs: a few small tweaks for overwrites in xfs_vm_writepage Don't trylock the buffer. We are the only one ever locking it for a regular file address space, and trylock was only copied from the generic code which did it due to the old buffer based writeout in jbd. Also make sure to only write out the buffer if the iomap actually is valid, because we wouldn't have a proper mapping otherwise. In practice we will never get an invalid mapping here as the page lock guarantees truncate doesn't race with us, but better be safe than sorry. Also make sure we allocate a new ioend when crossing boundaries between mappings, just like we do for delalloc and unwritten extents. Again this currently doesn't matter as the I/O end handler only cares for the boundaries for unwritten extents, but this makes the code fully correct and the same as for delalloc/unwritten extents. Signed-off-by: Christoph Hellwig Reviewed-by: Dave Chinner Signed-off-by: Alex Elder --- fs/xfs/linux-2.6/xfs_aops.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/fs/xfs/linux-2.6/xfs_aops.c b/fs/xfs/linux-2.6/xfs_aops.c index ca67ae92c238..1ace78bfbea7 100644 --- a/fs/xfs/linux-2.6/xfs_aops.c +++ b/fs/xfs/linux-2.6/xfs_aops.c @@ -1051,6 +1051,8 @@ xfs_vm_writepage( type = IO_NEW; do { + int new_ioend = 0; + if (offset >= end_offset) break; if (!buffer_uptodate(bh)) @@ -1071,8 +1073,6 @@ xfs_vm_writepage( imap_valid = xfs_imap_valid(inode, &imap, offset); if (buffer_unwritten(bh) || buffer_delay(bh)) { - int new_ioend = 0; - if (buffer_unwritten(bh)) { if (type != IO_UNWRITTEN) { type = IO_UNWRITTEN; @@ -1124,6 +1124,7 @@ xfs_vm_writepage( imap_valid = 0; } if (!imap_valid) { + new_ioend = 1; size = xfs_probe_cluster(inode, page, bh, head); err = xfs_map_blocks(inode, offset, size, &imap, flags); @@ -1142,14 +1143,12 @@ xfs_vm_writepage( * that we are writing into for the first time. */ type = IO_NEW; - if (trylock_buffer(bh)) { - if (imap_valid) - all_bh = 1; + if (imap_valid) { + all_bh = 1; + lock_buffer(bh); xfs_add_to_ioend(inode, bh, offset, type, - &ioend, !imap_valid); + &ioend, new_ioend); count++; - } else { - imap_valid = 0; } } else if (PageUptodate(page)) { ASSERT(buffer_mapped(bh)); -- cgit v1.2.3 From 405f80429436d38ab4e6b4c0d99861a1f00648fd Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Fri, 10 Dec 2010 08:42:19 +0000 Subject: xfs: cleanup the xfs_iomap_write_* helpers Remove passing the BMAPI_* flags to these helpers, in xfs_iomap_write_direct the check BMAPI_DIRECT was always true, and in the xfs_iomap_write_delay path is was never checked at all. Remove the nmap return value as we never make use of it. Signed-off-by: Christoph Hellwig Reviewed-by: Dave Chinner Signed-off-by: Alex Elder --- fs/xfs/xfs_iomap.c | 45 +++++++++++++++------------------------------ 1 file changed, 15 insertions(+), 30 deletions(-) diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c index 20576146369f..991291068378 100644 --- a/fs/xfs/xfs_iomap.c +++ b/fs/xfs/xfs_iomap.c @@ -51,11 +51,11 @@ #define XFS_WRITE_IMAPS XFS_BMAP_MAX_NMAP STATIC int xfs_iomap_write_direct(struct xfs_inode *, xfs_off_t, size_t, - int, struct xfs_bmbt_irec *, int *); -STATIC int xfs_iomap_write_delay(struct xfs_inode *, xfs_off_t, size_t, int, - struct xfs_bmbt_irec *, int *); + struct xfs_bmbt_irec *, int); +STATIC int xfs_iomap_write_delay(struct xfs_inode *, xfs_off_t, size_t, + struct xfs_bmbt_irec *); STATIC int xfs_iomap_write_allocate(struct xfs_inode *, xfs_off_t, size_t, - struct xfs_bmbt_irec *, int *); + struct xfs_bmbt_irec *); int xfs_iomap( @@ -134,12 +134,12 @@ xfs_iomap( } if (flags & BMAPI_DIRECT) { - error = xfs_iomap_write_direct(ip, offset, count, flags, - imap, nimaps); + error = xfs_iomap_write_direct(ip, offset, count, imap, + *nimaps); } else { - error = xfs_iomap_write_delay(ip, offset, count, flags, - imap, nimaps); + error = xfs_iomap_write_delay(ip, offset, count, imap); } + if (!error) { trace_xfs_iomap_alloc(ip, offset, count, flags, imap); } @@ -155,13 +155,10 @@ xfs_iomap( break; } - error = xfs_iomap_write_allocate(ip, offset, count, - imap, nimaps); + error = xfs_iomap_write_allocate(ip, offset, count, imap); break; } - ASSERT(*nimaps <= 1); - out: if (lockmode) xfs_iunlock(ip, lockmode); @@ -241,9 +238,8 @@ xfs_iomap_write_direct( xfs_inode_t *ip, xfs_off_t offset, size_t count, - int flags, xfs_bmbt_irec_t *imap, - int *nmaps) + int nmaps) { xfs_mount_t *mp = ip->i_mount; xfs_fileoff_t offset_fsb; @@ -279,7 +275,7 @@ xfs_iomap_write_direct( if (error) goto error_out; } else { - if (*nmaps && (imap->br_startblock == HOLESTARTBLOCK)) + if (nmaps && (imap->br_startblock == HOLESTARTBLOCK)) last_fsb = MIN(last_fsb, (xfs_fileoff_t) imap->br_blockcount + imap->br_startoff); @@ -331,7 +327,7 @@ xfs_iomap_write_direct( xfs_trans_ijoin(tp, ip); bmapi_flag = XFS_BMAPI_WRITE; - if ((flags & BMAPI_DIRECT) && (offset < ip->i_size || extsz)) + if (offset < ip->i_size || extsz) bmapi_flag |= XFS_BMAPI_PREALLOC; /* @@ -370,7 +366,6 @@ xfs_iomap_write_direct( goto error_out; } - *nmaps = 1; return 0; error0: /* Cancel bmap, unlock inode, unreserve quota blocks, cancel trans */ @@ -379,7 +374,6 @@ error0: /* Cancel bmap, unlock inode, unreserve quota blocks, cancel trans */ error1: /* Just cancel transaction */ xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES | XFS_TRANS_ABORT); - *nmaps = 0; /* nothing set-up here */ error_out: return XFS_ERROR(error); @@ -396,7 +390,6 @@ xfs_iomap_eof_want_preallocate( xfs_inode_t *ip, xfs_off_t offset, size_t count, - int ioflag, xfs_bmbt_irec_t *imap, int nimaps, int *prealloc) @@ -440,9 +433,7 @@ xfs_iomap_write_delay( xfs_inode_t *ip, xfs_off_t offset, size_t count, - int ioflag, - xfs_bmbt_irec_t *ret_imap, - int *nmaps) + xfs_bmbt_irec_t *ret_imap) { xfs_mount_t *mp = ip->i_mount; xfs_fileoff_t offset_fsb; @@ -470,7 +461,7 @@ xfs_iomap_write_delay( offset_fsb = XFS_B_TO_FSBT(mp, offset); error = xfs_iomap_eof_want_preallocate(mp, ip, offset, count, - ioflag, imap, XFS_WRITE_IMAPS, &prealloc); + imap, XFS_WRITE_IMAPS, &prealloc); if (error) return error; @@ -523,8 +514,6 @@ retry: return xfs_cmn_err_fsblock_zero(ip, &imap[0]); *ret_imap = imap[0]; - *nmaps = 1; - return 0; } @@ -543,8 +532,7 @@ xfs_iomap_write_allocate( xfs_inode_t *ip, xfs_off_t offset, size_t count, - xfs_bmbt_irec_t *imap, - int *retmap) + xfs_bmbt_irec_t *imap) { xfs_mount_t *mp = ip->i_mount; xfs_fileoff_t offset_fsb, last_block; @@ -557,8 +545,6 @@ xfs_iomap_write_allocate( int error = 0; int nres; - *retmap = 0; - /* * Make sure that the dquots are there. */ @@ -680,7 +666,6 @@ xfs_iomap_write_allocate( if ((offset_fsb >= imap->br_startoff) && (offset_fsb < (imap->br_startoff + imap->br_blockcount))) { - *retmap = 1; XFS_STATS_INC(xs_xstrat_quick); return 0; } -- cgit v1.2.3 From a206c817c864583c44e2f418db8e6c7a000fbc38 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Fri, 10 Dec 2010 08:42:20 +0000 Subject: xfs: kill xfs_iomap Opencode the xfs_iomap code in it's two callers. The overlap of passed flags already was minimal and will be further reduced in the next patch. As a side effect the BMAPI_* flags for xfs_bmapi and the IO_* flags for I/O end processing are merged into a single set of flags, which should be a bit more descriptive of the operation we perform. Also improve the tracing by giving each caller it's own type set of tracepoints. Signed-off-by: Christoph Hellwig Reviewed-by: Dave Chinner Signed-off-by: Alex Elder --- fs/xfs/linux-2.6/xfs_aops.c | 211 +++++++++++++++++++++++++++++++------------ fs/xfs/linux-2.6/xfs_aops.h | 16 ++++ fs/xfs/linux-2.6/xfs_trace.h | 28 +++--- fs/xfs/xfs_iomap.c | 122 +------------------------ fs/xfs/xfs_iomap.h | 27 ++---- 5 files changed, 191 insertions(+), 213 deletions(-) diff --git a/fs/xfs/linux-2.6/xfs_aops.c b/fs/xfs/linux-2.6/xfs_aops.c index 1ace78bfbea7..365040f61d89 100644 --- a/fs/xfs/linux-2.6/xfs_aops.c +++ b/fs/xfs/linux-2.6/xfs_aops.c @@ -38,15 +38,6 @@ #include #include -/* - * Types of I/O for bmap clustering and I/O completion tracking. - */ -enum { - IO_READ, /* mapping for a read */ - IO_DELAY, /* mapping covers delalloc region */ - IO_UNWRITTEN, /* mapping covers allocated but uninitialized data */ - IO_NEW /* just allocated */ -}; /* * Prime number of hash buckets since address is used as the key. @@ -182,9 +173,6 @@ xfs_setfilesize( xfs_inode_t *ip = XFS_I(ioend->io_inode); xfs_fsize_t isize; - ASSERT((ip->i_d.di_mode & S_IFMT) == S_IFREG); - ASSERT(ioend->io_type != IO_READ); - if (unlikely(ioend->io_error)) return 0; @@ -244,10 +232,8 @@ xfs_end_io( * We might have to update the on-disk file size after extending * writes. */ - if (ioend->io_type != IO_READ) { - error = xfs_setfilesize(ioend); - ASSERT(!error || error == EAGAIN); - } + error = xfs_setfilesize(ioend); + ASSERT(!error || error == EAGAIN); /* * If we didn't complete processing of the ioend, requeue it to the @@ -320,12 +306,88 @@ xfs_map_blocks( loff_t offset, ssize_t count, struct xfs_bmbt_irec *imap, - int flags) + int type, + int nonblocking) { - int nmaps = 1; - int new = 0; + struct xfs_inode *ip = XFS_I(inode); + struct xfs_mount *mp = ip->i_mount; + xfs_fileoff_t offset_fsb, end_fsb; + int error = 0; + int lockmode = 0; + int bmapi_flags = XFS_BMAPI_ENTIRE; + int nimaps = 1; + + if (XFS_FORCED_SHUTDOWN(mp)) + return -XFS_ERROR(EIO); + + switch (type) { + case IO_OVERWRITE: + lockmode = xfs_ilock_map_shared(ip); + break; + case IO_UNWRITTEN: + lockmode = XFS_ILOCK_EXCL; + bmapi_flags |= XFS_BMAPI_IGSTATE; + xfs_ilock(ip, lockmode); + break; + case IO_DELALLOC: + lockmode = XFS_ILOCK_SHARED; + + if (!xfs_ilock_nowait(ip, lockmode)) { + if (nonblocking) + return -XFS_ERROR(EAGAIN); + xfs_ilock(ip, lockmode); + } + break; + } + + ASSERT(offset <= mp->m_maxioffset); + if (offset + count > mp->m_maxioffset) + count = mp->m_maxioffset - offset; + end_fsb = XFS_B_TO_FSB(mp, (xfs_ufsize_t)offset + count); + offset_fsb = XFS_B_TO_FSBT(mp, offset); + + error = xfs_bmapi(NULL, ip, offset_fsb, end_fsb - offset_fsb, + bmapi_flags, NULL, 0, imap, &nimaps, NULL); + if (error) + goto out; + + switch (type) { + case IO_UNWRITTEN: + /* If we found an extent, return it */ + if (nimaps && + (imap->br_startblock != HOLESTARTBLOCK) && + (imap->br_startblock != DELAYSTARTBLOCK)) { + trace_xfs_map_blocks_found(ip, offset, count, type, imap); + break; + } + + error = xfs_iomap_write_delay(ip, offset, count, imap); + if (!error) + trace_xfs_map_blocks_alloc(ip, offset, count, type, imap); + break; + case IO_DELALLOC: + /* If we found an extent, return it */ + xfs_iunlock(ip, lockmode); + lockmode = 0; + + if (nimaps && !isnullstartblock(imap->br_startblock)) { + trace_xfs_map_blocks_found(ip, offset, count, type, imap); + break; + } + + error = xfs_iomap_write_allocate(ip, offset, count, imap); + if (!error) + trace_xfs_map_blocks_alloc(ip, offset, count, type, imap); + break; + default: + if (nimaps) + trace_xfs_map_blocks_found(ip, offset, count, type, imap); + } - return -xfs_iomap(XFS_I(inode), offset, count, flags, imap, &nmaps, &new); +out: + if (lockmode) + xfs_iunlock(ip, lockmode); + return -XFS_ERROR(error); } STATIC int @@ -722,9 +784,9 @@ xfs_is_delayed_page( if (buffer_unwritten(bh)) acceptable = (type == IO_UNWRITTEN); else if (buffer_delay(bh)) - acceptable = (type == IO_DELAY); + acceptable = (type == IO_DELALLOC); else if (buffer_dirty(bh) && buffer_mapped(bh)) - acceptable = (type == IO_NEW); + acceptable = (type == IO_OVERWRITE); else break; } while ((bh = bh->b_this_page) != head); @@ -809,7 +871,7 @@ xfs_convert_page( if (buffer_unwritten(bh)) type = IO_UNWRITTEN; else - type = IO_DELAY; + type = IO_DELALLOC; if (!xfs_imap_valid(inode, imap, offset)) { done = 1; @@ -826,7 +888,7 @@ xfs_convert_page( page_dirty--; count++; } else { - type = IO_NEW; + type = IO_OVERWRITE; if (buffer_mapped(bh) && all_bh) { lock_buffer(bh); xfs_add_to_ioend(inode, bh, offset, @@ -926,7 +988,7 @@ xfs_aops_discard_page( struct buffer_head *bh, *head; loff_t offset = page_offset(page); - if (!xfs_is_delayed_page(page, IO_DELAY)) + if (!xfs_is_delayed_page(page, IO_DELALLOC)) goto out_invalidate; if (XFS_FORCED_SHUTDOWN(ip->i_mount)) @@ -994,9 +1056,10 @@ xfs_vm_writepage( __uint64_t end_offset; pgoff_t end_index, last_index; ssize_t size, len; - int flags, err, imap_valid = 0, uptodate = 1; + int err, imap_valid = 0, uptodate = 1; int count = 0; int all_bh = 0; + int nonblocking = 0; trace_xfs_writepage(inode, page, 0); @@ -1047,8 +1110,10 @@ xfs_vm_writepage( bh = head = page_buffers(page); offset = page_offset(page); - flags = BMAPI_READ; - type = IO_NEW; + type = IO_OVERWRITE; + + if (wbc->sync_mode == WB_SYNC_NONE && wbc->nonblocking) + nonblocking = 1; do { int new_ioend = 0; @@ -1078,16 +1143,11 @@ xfs_vm_writepage( type = IO_UNWRITTEN; imap_valid = 0; } - flags = BMAPI_WRITE | BMAPI_IGNSTATE; } else if (buffer_delay(bh)) { - if (type != IO_DELAY) { - type = IO_DELAY; + if (type != IO_DELALLOC) { + type = IO_DELALLOC; imap_valid = 0; } - flags = BMAPI_ALLOCATE; - - if (wbc->sync_mode == WB_SYNC_NONE) - flags |= BMAPI_TRYLOCK; } if (!imap_valid) { @@ -1100,8 +1160,8 @@ xfs_vm_writepage( * for unwritten extent conversion. */ new_ioend = 1; - err = xfs_map_blocks(inode, offset, len, - &imap, flags); + err = xfs_map_blocks(inode, offset, len, &imap, + type, nonblocking); if (err) goto error; imap_valid = xfs_imap_valid(inode, &imap, @@ -1119,30 +1179,21 @@ xfs_vm_writepage( * That means it must already have extents allocated * underneath it. Map the extent by reading it. */ - if (flags != BMAPI_READ) { - flags = BMAPI_READ; + if (type != IO_OVERWRITE) { + type = IO_OVERWRITE; imap_valid = 0; } if (!imap_valid) { new_ioend = 1; size = xfs_probe_cluster(inode, page, bh, head); err = xfs_map_blocks(inode, offset, size, - &imap, flags); + &imap, type, nonblocking); if (err) goto error; imap_valid = xfs_imap_valid(inode, &imap, offset); } - /* - * We set the type to IO_NEW in case we are doing a - * small write at EOF that is extending the file but - * without needing an allocation. We need to update the - * file size on I/O completion in this case so it is - * the same case as having just allocated a new extent - * that we are writing into for the first time. - */ - type = IO_NEW; if (imap_valid) { all_bh = 1; lock_buffer(bh); @@ -1250,13 +1301,19 @@ __xfs_get_blocks( int create, int direct) { - int flags = create ? BMAPI_WRITE : BMAPI_READ; + struct xfs_inode *ip = XFS_I(inode); + struct xfs_mount *mp = ip->i_mount; + xfs_fileoff_t offset_fsb, end_fsb; + int error = 0; + int lockmode = 0; struct xfs_bmbt_irec imap; + int nimaps = 1; xfs_off_t offset; ssize_t size; - int nimap = 1; int new = 0; - int error; + + if (XFS_FORCED_SHUTDOWN(mp)) + return -XFS_ERROR(EIO); offset = (xfs_off_t)iblock << inode->i_blkbits; ASSERT(bh_result->b_size >= (1 << inode->i_blkbits)); @@ -1265,15 +1322,45 @@ __xfs_get_blocks( if (!create && direct && offset >= i_size_read(inode)) return 0; - if (direct && create) - flags |= BMAPI_DIRECT; + if (create) { + lockmode = XFS_ILOCK_EXCL; + xfs_ilock(ip, lockmode); + } else { + lockmode = xfs_ilock_map_shared(ip); + } + + ASSERT(offset <= mp->m_maxioffset); + if (offset + size > mp->m_maxioffset) + size = mp->m_maxioffset - offset; + end_fsb = XFS_B_TO_FSB(mp, (xfs_ufsize_t)offset + size); + offset_fsb = XFS_B_TO_FSBT(mp, offset); - error = xfs_iomap(XFS_I(inode), offset, size, flags, &imap, &nimap, - &new); + error = xfs_bmapi(NULL, ip, offset_fsb, end_fsb - offset_fsb, + XFS_BMAPI_ENTIRE, NULL, 0, &imap, &nimaps, NULL); if (error) - return -error; - if (nimap == 0) - return 0; + goto out_unlock; + + if (create && + (!nimaps || + (imap.br_startblock == HOLESTARTBLOCK || + imap.br_startblock == DELAYSTARTBLOCK))) { + if (direct) { + error = xfs_iomap_write_direct(ip, offset, size, + &imap, nimaps); + } else { + error = xfs_iomap_write_delay(ip, offset, size, &imap); + } + if (error) + goto out_unlock; + + trace_xfs_get_blocks_alloc(ip, offset, size, 0, &imap); + } else if (nimaps) { + trace_xfs_get_blocks_found(ip, offset, size, 0, &imap); + } else { + trace_xfs_get_blocks_notfound(ip, offset, size); + goto out_unlock; + } + xfs_iunlock(ip, lockmode); if (imap.br_startblock != HOLESTARTBLOCK && imap.br_startblock != DELAYSTARTBLOCK) { @@ -1340,6 +1427,10 @@ __xfs_get_blocks( } return 0; + +out_unlock: + xfs_iunlock(ip, lockmode); + return -error; } int @@ -1427,7 +1518,7 @@ xfs_vm_direct_IO( ssize_t ret; if (rw & WRITE) { - iocb->private = xfs_alloc_ioend(inode, IO_NEW); + iocb->private = xfs_alloc_ioend(inode, IO_DIRECT); ret = __blockdev_direct_IO(rw, iocb, inode, bdev, iov, offset, nr_segs, diff --git a/fs/xfs/linux-2.6/xfs_aops.h b/fs/xfs/linux-2.6/xfs_aops.h index c5057fb6237a..71f721e1a71f 100644 --- a/fs/xfs/linux-2.6/xfs_aops.h +++ b/fs/xfs/linux-2.6/xfs_aops.h @@ -22,6 +22,22 @@ extern struct workqueue_struct *xfsdatad_workqueue; extern struct workqueue_struct *xfsconvertd_workqueue; extern mempool_t *xfs_ioend_pool; +/* + * Types of I/O for bmap clustering and I/O completion tracking. + */ +enum { + IO_DIRECT = 0, /* special case for direct I/O ioends */ + IO_DELALLOC, /* mapping covers delalloc region */ + IO_UNWRITTEN, /* mapping covers allocated but uninitialized data */ + IO_OVERWRITE, /* mapping covers already allocated extent */ +}; + +#define XFS_IO_TYPES \ + { 0, "" }, \ + { IO_DELALLOC, "delalloc" }, \ + { IO_UNWRITTEN, "unwritten" }, \ + { IO_OVERWRITE, "overwrite" } + /* * xfs_ioend struct manages large extent writes for XFS. * It can manage several multi-page bio's at once. diff --git a/fs/xfs/linux-2.6/xfs_trace.h b/fs/xfs/linux-2.6/xfs_trace.h index acef2e98c594..f56431c916a0 100644 --- a/fs/xfs/linux-2.6/xfs_trace.h +++ b/fs/xfs/linux-2.6/xfs_trace.h @@ -935,10 +935,10 @@ DEFINE_PAGE_EVENT(xfs_writepage); DEFINE_PAGE_EVENT(xfs_releasepage); DEFINE_PAGE_EVENT(xfs_invalidatepage); -DECLARE_EVENT_CLASS(xfs_iomap_class, +DECLARE_EVENT_CLASS(xfs_imap_class, TP_PROTO(struct xfs_inode *ip, xfs_off_t offset, ssize_t count, - int flags, struct xfs_bmbt_irec *irec), - TP_ARGS(ip, offset, count, flags, irec), + int type, struct xfs_bmbt_irec *irec), + TP_ARGS(ip, offset, count, type, irec), TP_STRUCT__entry( __field(dev_t, dev) __field(xfs_ino_t, ino) @@ -946,7 +946,7 @@ DECLARE_EVENT_CLASS(xfs_iomap_class, __field(loff_t, new_size) __field(loff_t, offset) __field(size_t, count) - __field(int, flags) + __field(int, type) __field(xfs_fileoff_t, startoff) __field(xfs_fsblock_t, startblock) __field(xfs_filblks_t, blockcount) @@ -958,13 +958,13 @@ DECLARE_EVENT_CLASS(xfs_iomap_class, __entry->new_size = ip->i_new_size; __entry->offset = offset; __entry->count = count; - __entry->flags = flags; + __entry->type = type; __entry->startoff = irec ? irec->br_startoff : 0; __entry->startblock = irec ? irec->br_startblock : 0; __entry->blockcount = irec ? irec->br_blockcount : 0; ), TP_printk("dev %d:%d ino 0x%llx size 0x%llx new_size 0x%llx " - "offset 0x%llx count %zd flags %s " + "offset 0x%llx count %zd type %s " "startoff 0x%llx startblock %lld blockcount 0x%llx", MAJOR(__entry->dev), MINOR(__entry->dev), __entry->ino, @@ -972,20 +972,21 @@ DECLARE_EVENT_CLASS(xfs_iomap_class, __entry->new_size, __entry->offset, __entry->count, - __print_flags(__entry->flags, "|", BMAPI_FLAGS), + __print_symbolic(__entry->type, XFS_IO_TYPES), __entry->startoff, (__int64_t)__entry->startblock, __entry->blockcount) ) #define DEFINE_IOMAP_EVENT(name) \ -DEFINE_EVENT(xfs_iomap_class, name, \ +DEFINE_EVENT(xfs_imap_class, name, \ TP_PROTO(struct xfs_inode *ip, xfs_off_t offset, ssize_t count, \ - int flags, struct xfs_bmbt_irec *irec), \ - TP_ARGS(ip, offset, count, flags, irec)) -DEFINE_IOMAP_EVENT(xfs_iomap_enter); -DEFINE_IOMAP_EVENT(xfs_iomap_found); -DEFINE_IOMAP_EVENT(xfs_iomap_alloc); + int type, struct xfs_bmbt_irec *irec), \ + TP_ARGS(ip, offset, count, type, irec)) +DEFINE_IOMAP_EVENT(xfs_map_blocks_found); +DEFINE_IOMAP_EVENT(xfs_map_blocks_alloc); +DEFINE_IOMAP_EVENT(xfs_get_blocks_found); +DEFINE_IOMAP_EVENT(xfs_get_blocks_alloc); DECLARE_EVENT_CLASS(xfs_simple_io_class, TP_PROTO(struct xfs_inode *ip, xfs_off_t offset, ssize_t count), @@ -1022,6 +1023,7 @@ DEFINE_EVENT(xfs_simple_io_class, name, \ TP_ARGS(ip, offset, count)) DEFINE_SIMPLE_IO_EVENT(xfs_delalloc_enospc); DEFINE_SIMPLE_IO_EVENT(xfs_unwritten_convert); +DEFINE_SIMPLE_IO_EVENT(xfs_get_blocks_notfound); TRACE_EVENT(xfs_itruncate_start, diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c index 991291068378..22b62a179e89 100644 --- a/fs/xfs/xfs_iomap.c +++ b/fs/xfs/xfs_iomap.c @@ -47,124 +47,8 @@ #define XFS_WRITEIO_ALIGN(mp,off) (((off) >> mp->m_writeio_log) \ << mp->m_writeio_log) -#define XFS_STRAT_WRITE_IMAPS 2 #define XFS_WRITE_IMAPS XFS_BMAP_MAX_NMAP -STATIC int xfs_iomap_write_direct(struct xfs_inode *, xfs_off_t, size_t, - struct xfs_bmbt_irec *, int); -STATIC int xfs_iomap_write_delay(struct xfs_inode *, xfs_off_t, size_t, - struct xfs_bmbt_irec *); -STATIC int xfs_iomap_write_allocate(struct xfs_inode *, xfs_off_t, size_t, - struct xfs_bmbt_irec *); - -int -xfs_iomap( - struct xfs_inode *ip, - xfs_off_t offset, - ssize_t count, - int flags, - struct xfs_bmbt_irec *imap, - int *nimaps, - int *new) -{ - struct xfs_mount *mp = ip->i_mount; - xfs_fileoff_t offset_fsb, end_fsb; - int error = 0; - int lockmode = 0; - int bmapi_flags = 0; - - ASSERT((ip->i_d.di_mode & S_IFMT) == S_IFREG); - - *new = 0; - - if (XFS_FORCED_SHUTDOWN(mp)) - return XFS_ERROR(EIO); - - trace_xfs_iomap_enter(ip, offset, count, flags, NULL); - - switch (flags & (BMAPI_READ | BMAPI_WRITE | BMAPI_ALLOCATE)) { - case BMAPI_READ: - lockmode = xfs_ilock_map_shared(ip); - bmapi_flags = XFS_BMAPI_ENTIRE; - break; - case BMAPI_WRITE: - lockmode = XFS_ILOCK_EXCL; - if (flags & BMAPI_IGNSTATE) - bmapi_flags |= XFS_BMAPI_IGSTATE|XFS_BMAPI_ENTIRE; - xfs_ilock(ip, lockmode); - break; - case BMAPI_ALLOCATE: - lockmode = XFS_ILOCK_SHARED; - bmapi_flags = XFS_BMAPI_ENTIRE; - - /* Attempt non-blocking lock */ - if (flags & BMAPI_TRYLOCK) { - if (!xfs_ilock_nowait(ip, lockmode)) - return XFS_ERROR(EAGAIN); - } else { - xfs_ilock(ip, lockmode); - } - break; - default: - BUG(); - } - - ASSERT(offset <= mp->m_maxioffset); - if ((xfs_fsize_t)offset + count > mp->m_maxioffset) - count = mp->m_maxioffset - offset; - end_fsb = XFS_B_TO_FSB(mp, (xfs_ufsize_t)offset + count); - offset_fsb = XFS_B_TO_FSBT(mp, offset); - - error = xfs_bmapi(NULL, ip, offset_fsb, - (xfs_filblks_t)(end_fsb - offset_fsb), - bmapi_flags, NULL, 0, imap, - nimaps, NULL); - - if (error) - goto out; - - switch (flags & (BMAPI_WRITE|BMAPI_ALLOCATE)) { - case BMAPI_WRITE: - /* If we found an extent, return it */ - if (*nimaps && - (imap->br_startblock != HOLESTARTBLOCK) && - (imap->br_startblock != DELAYSTARTBLOCK)) { - trace_xfs_iomap_found(ip, offset, count, flags, imap); - break; - } - - if (flags & BMAPI_DIRECT) { - error = xfs_iomap_write_direct(ip, offset, count, imap, - *nimaps); - } else { - error = xfs_iomap_write_delay(ip, offset, count, imap); - } - - if (!error) { - trace_xfs_iomap_alloc(ip, offset, count, flags, imap); - } - *new = 1; - break; - case BMAPI_ALLOCATE: - /* If we found an extent, return it */ - xfs_iunlock(ip, lockmode); - lockmode = 0; - - if (*nimaps && !isnullstartblock(imap->br_startblock)) { - trace_xfs_iomap_found(ip, offset, count, flags, imap); - break; - } - - error = xfs_iomap_write_allocate(ip, offset, count, imap); - break; - } - -out: - if (lockmode) - xfs_iunlock(ip, lockmode); - return XFS_ERROR(error); -} - STATIC int xfs_iomap_eof_align_last_fsb( xfs_mount_t *mp, @@ -233,7 +117,7 @@ xfs_cmn_err_fsblock_zero( return EFSCORRUPTED; } -STATIC int +int xfs_iomap_write_direct( xfs_inode_t *ip, xfs_off_t offset, @@ -428,7 +312,7 @@ xfs_iomap_eof_want_preallocate( return 0; } -STATIC int +int xfs_iomap_write_delay( xfs_inode_t *ip, xfs_off_t offset, @@ -527,7 +411,7 @@ retry: * We no longer bother to look at the incoming map - all we have to * guarantee is that whatever we allocate fills the required range. */ -STATIC int +int xfs_iomap_write_allocate( xfs_inode_t *ip, xfs_off_t offset, diff --git a/fs/xfs/xfs_iomap.h b/fs/xfs/xfs_iomap.h index 7748a430f50d..80615760959a 100644 --- a/fs/xfs/xfs_iomap.h +++ b/fs/xfs/xfs_iomap.h @@ -18,30 +18,15 @@ #ifndef __XFS_IOMAP_H__ #define __XFS_IOMAP_H__ -/* base extent manipulation calls */ -#define BMAPI_READ (1 << 0) /* read extents */ -#define BMAPI_WRITE (1 << 1) /* create extents */ -#define BMAPI_ALLOCATE (1 << 2) /* delayed allocate to real extents */ - -/* modifiers */ -#define BMAPI_IGNSTATE (1 << 4) /* ignore unwritten state on read */ -#define BMAPI_DIRECT (1 << 5) /* direct instead of buffered write */ -#define BMAPI_MMA (1 << 6) /* allocate for mmap write */ -#define BMAPI_TRYLOCK (1 << 7) /* non-blocking request */ - -#define BMAPI_FLAGS \ - { BMAPI_READ, "READ" }, \ - { BMAPI_WRITE, "WRITE" }, \ - { BMAPI_ALLOCATE, "ALLOCATE" }, \ - { BMAPI_IGNSTATE, "IGNSTATE" }, \ - { BMAPI_DIRECT, "DIRECT" }, \ - { BMAPI_TRYLOCK, "TRYLOCK" } - struct xfs_inode; struct xfs_bmbt_irec; -extern int xfs_iomap(struct xfs_inode *, xfs_off_t, ssize_t, int, - struct xfs_bmbt_irec *, int *, int *); +extern int xfs_iomap_write_direct(struct xfs_inode *, xfs_off_t, size_t, + struct xfs_bmbt_irec *, int); +extern int xfs_iomap_write_delay(struct xfs_inode *, xfs_off_t, size_t, + struct xfs_bmbt_irec *); +extern int xfs_iomap_write_allocate(struct xfs_inode *, xfs_off_t, size_t, + struct xfs_bmbt_irec *); extern int xfs_iomap_write_unwritten(struct xfs_inode *, xfs_off_t, size_t); #endif /* __XFS_IOMAP_H__*/ -- cgit v1.2.3 From 8ff2957d581582890693affc09920108a67cb05d Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Fri, 10 Dec 2010 08:42:21 +0000 Subject: xfs: simplify xfs_map_blocks No need to lock the extent map exclusive when performing an overwrite, we know the extent map must already have been loaded by get_blocks. Apply the non-blocking inode semantics to all mapping types instead of just delayed allocations. Remove the handling of not yet allocated blocks for the IO_UNWRITTEN case - if an extent is marked as unwritten allocated in the buffer it must already have an extent on disk. Add asserts to verify all the assumptions above in debug builds. Signed-off-by: Christoph Hellwig Reviewed-by: Dave Chinner Signed-off-by: Alex Elder --- fs/xfs/linux-2.6/xfs_aops.c | 77 +++++++++++++++------------------------------ 1 file changed, 25 insertions(+), 52 deletions(-) diff --git a/fs/xfs/linux-2.6/xfs_aops.c b/fs/xfs/linux-2.6/xfs_aops.c index 365040f61d89..1252a8443429 100644 --- a/fs/xfs/linux-2.6/xfs_aops.c +++ b/fs/xfs/linux-2.6/xfs_aops.c @@ -313,81 +313,54 @@ xfs_map_blocks( struct xfs_mount *mp = ip->i_mount; xfs_fileoff_t offset_fsb, end_fsb; int error = 0; - int lockmode = 0; int bmapi_flags = XFS_BMAPI_ENTIRE; int nimaps = 1; if (XFS_FORCED_SHUTDOWN(mp)) return -XFS_ERROR(EIO); - switch (type) { - case IO_OVERWRITE: - lockmode = xfs_ilock_map_shared(ip); - break; - case IO_UNWRITTEN: - lockmode = XFS_ILOCK_EXCL; + if (type == IO_UNWRITTEN) bmapi_flags |= XFS_BMAPI_IGSTATE; - xfs_ilock(ip, lockmode); - break; - case IO_DELALLOC: - lockmode = XFS_ILOCK_SHARED; - - if (!xfs_ilock_nowait(ip, lockmode)) { - if (nonblocking) - return -XFS_ERROR(EAGAIN); - xfs_ilock(ip, lockmode); - } - break; + + if (!xfs_ilock_nowait(ip, XFS_ILOCK_SHARED)) { + if (nonblocking) + return -XFS_ERROR(EAGAIN); + xfs_ilock(ip, XFS_ILOCK_SHARED); } + ASSERT(ip->i_d.di_format != XFS_DINODE_FMT_BTREE || + (ip->i_df.if_flags & XFS_IFEXTENTS)); ASSERT(offset <= mp->m_maxioffset); + if (offset + count > mp->m_maxioffset) count = mp->m_maxioffset - offset; end_fsb = XFS_B_TO_FSB(mp, (xfs_ufsize_t)offset + count); offset_fsb = XFS_B_TO_FSBT(mp, offset); - error = xfs_bmapi(NULL, ip, offset_fsb, end_fsb - offset_fsb, bmapi_flags, NULL, 0, imap, &nimaps, NULL); - if (error) - goto out; - - switch (type) { - case IO_UNWRITTEN: - /* If we found an extent, return it */ - if (nimaps && - (imap->br_startblock != HOLESTARTBLOCK) && - (imap->br_startblock != DELAYSTARTBLOCK)) { - trace_xfs_map_blocks_found(ip, offset, count, type, imap); - break; - } + xfs_iunlock(ip, XFS_ILOCK_SHARED); - error = xfs_iomap_write_delay(ip, offset, count, imap); - if (!error) - trace_xfs_map_blocks_alloc(ip, offset, count, type, imap); - break; - case IO_DELALLOC: - /* If we found an extent, return it */ - xfs_iunlock(ip, lockmode); - lockmode = 0; - - if (nimaps && !isnullstartblock(imap->br_startblock)) { - trace_xfs_map_blocks_found(ip, offset, count, type, imap); - break; - } + if (error) + return -XFS_ERROR(error); + if (type == IO_DELALLOC && + (!nimaps || isnullstartblock(imap->br_startblock))) { error = xfs_iomap_write_allocate(ip, offset, count, imap); if (!error) trace_xfs_map_blocks_alloc(ip, offset, count, type, imap); - break; - default: - if (nimaps) - trace_xfs_map_blocks_found(ip, offset, count, type, imap); + return -XFS_ERROR(error); } -out: - if (lockmode) - xfs_iunlock(ip, lockmode); - return -XFS_ERROR(error); +#ifdef DEBUG + if (type == IO_UNWRITTEN) { + ASSERT(nimaps); + ASSERT(imap->br_startblock != HOLESTARTBLOCK); + ASSERT(imap->br_startblock != DELAYSTARTBLOCK); + } +#endif + if (nimaps) + trace_xfs_map_blocks_found(ip, offset, count, type, imap); + return 0; } STATIC int -- cgit v1.2.3 From ed1e7b7e484dfb64168755613d499f32a97409bd Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Fri, 10 Dec 2010 08:42:22 +0000 Subject: xfs: remove xfs_probe_cluster xfs_map_blocks always calls xfs_bmapi with the XFS_BMAPI_ENTIRE entire flag, which tells it to not cap the extent at the passed in size, but just treat the size as an minimum to map. This means xfs_probe_cluster is entirely useless as we'll always get the whole extent back anyway. Signed-off-by: Christoph Hellwig Reviewed-by: Dave Chinner Signed-off-by: Alex Elder --- fs/xfs/linux-2.6/xfs_aops.c | 111 ++------------------------------------------ 1 file changed, 4 insertions(+), 107 deletions(-) diff --git a/fs/xfs/linux-2.6/xfs_aops.c b/fs/xfs/linux-2.6/xfs_aops.c index 1252a8443429..c3bc7690f043 100644 --- a/fs/xfs/linux-2.6/xfs_aops.c +++ b/fs/xfs/linux-2.6/xfs_aops.c @@ -304,13 +304,13 @@ STATIC int xfs_map_blocks( struct inode *inode, loff_t offset, - ssize_t count, struct xfs_bmbt_irec *imap, int type, int nonblocking) { struct xfs_inode *ip = XFS_I(inode); struct xfs_mount *mp = ip->i_mount; + ssize_t count = 1 << inode->i_blkbits; xfs_fileoff_t offset_fsb, end_fsb; int error = 0; int bmapi_flags = XFS_BMAPI_ENTIRE; @@ -634,108 +634,6 @@ xfs_map_at_offset( clear_buffer_unwritten(bh); } -/* - * Look for a page at index that is suitable for clustering. - */ -STATIC unsigned int -xfs_probe_page( - struct page *page, - unsigned int pg_offset) -{ - struct buffer_head *bh, *head; - int ret = 0; - - if (PageWriteback(page)) - return 0; - if (!PageDirty(page)) - return 0; - if (!page->mapping) - return 0; - if (!page_has_buffers(page)) - return 0; - - bh = head = page_buffers(page); - do { - if (!buffer_uptodate(bh)) - break; - if (!buffer_mapped(bh)) - break; - ret += bh->b_size; - if (ret >= pg_offset) - break; - } while ((bh = bh->b_this_page) != head); - - return ret; -} - -STATIC size_t -xfs_probe_cluster( - struct inode *inode, - struct page *startpage, - struct buffer_head *bh, - struct buffer_head *head) -{ - struct pagevec pvec; - pgoff_t tindex, tlast, tloff; - size_t total = 0; - int done = 0, i; - - /* First sum forwards in this page */ - do { - if (!buffer_uptodate(bh) || !buffer_mapped(bh)) - return total; - total += bh->b_size; - } while ((bh = bh->b_this_page) != head); - - /* if we reached the end of the page, sum forwards in following pages */ - tlast = i_size_read(inode) >> PAGE_CACHE_SHIFT; - tindex = startpage->index + 1; - - /* Prune this back to avoid pathological behavior */ - tloff = min(tlast, startpage->index + 64); - - pagevec_init(&pvec, 0); - while (!done && tindex <= tloff) { - unsigned len = min_t(pgoff_t, PAGEVEC_SIZE, tlast - tindex + 1); - - if (!pagevec_lookup(&pvec, inode->i_mapping, tindex, len)) - break; - - for (i = 0; i < pagevec_count(&pvec); i++) { - struct page *page = pvec.pages[i]; - size_t pg_offset, pg_len = 0; - - if (tindex == tlast) { - pg_offset = - i_size_read(inode) & (PAGE_CACHE_SIZE - 1); - if (!pg_offset) { - done = 1; - break; - } - } else - pg_offset = PAGE_CACHE_SIZE; - - if (page->index == tindex && trylock_page(page)) { - pg_len = xfs_probe_page(page, pg_offset); - unlock_page(page); - } - - if (!pg_len) { - done = 1; - break; - } - - total += pg_len; - tindex++; - } - - pagevec_release(&pvec); - cond_resched(); - } - - return total; -} - /* * Test if a given page is suitable for writing as part of an unwritten * or delayed allocate extent. @@ -1028,7 +926,7 @@ xfs_vm_writepage( unsigned int type; __uint64_t end_offset; pgoff_t end_index, last_index; - ssize_t size, len; + ssize_t len; int err, imap_valid = 0, uptodate = 1; int count = 0; int all_bh = 0; @@ -1133,7 +1031,7 @@ xfs_vm_writepage( * for unwritten extent conversion. */ new_ioend = 1; - err = xfs_map_blocks(inode, offset, len, &imap, + err = xfs_map_blocks(inode, offset, &imap, type, nonblocking); if (err) goto error; @@ -1158,8 +1056,7 @@ xfs_vm_writepage( } if (!imap_valid) { new_ioend = 1; - size = xfs_probe_cluster(inode, page, bh, head); - err = xfs_map_blocks(inode, offset, size, + err = xfs_map_blocks(inode, offset, &imap, type, nonblocking); if (err) goto error; -- cgit v1.2.3 From 2fa24f92530edaf86c3b5f662464e0d2e3b3e517 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Fri, 10 Dec 2010 08:42:23 +0000 Subject: xfs: remove the all_bh flag from xfs_convert_page The all_bh flag is always set when entering the page clustering machinery with a regular written extent, which means the check for it is superflous. Signed-off-by: Christoph Hellwig Reviewed-by: Dave Chinner Signed-off-by: Alex Elder --- fs/xfs/linux-2.6/xfs_aops.c | 33 +++++++++++++-------------------- 1 file changed, 13 insertions(+), 20 deletions(-) diff --git a/fs/xfs/linux-2.6/xfs_aops.c b/fs/xfs/linux-2.6/xfs_aops.c index c3bc7690f043..86f57f61939b 100644 --- a/fs/xfs/linux-2.6/xfs_aops.c +++ b/fs/xfs/linux-2.6/xfs_aops.c @@ -682,8 +682,7 @@ xfs_convert_page( loff_t tindex, struct xfs_bmbt_irec *imap, xfs_ioend_t **ioendp, - struct writeback_control *wbc, - int all_bh) + struct writeback_control *wbc) { struct buffer_head *bh, *head; xfs_off_t end_offset; @@ -738,11 +737,14 @@ xfs_convert_page( continue; } - if (buffer_unwritten(bh) || buffer_delay(bh)) { + if (buffer_unwritten(bh) || buffer_delay(bh) || + buffer_mapped(bh)) { if (buffer_unwritten(bh)) type = IO_UNWRITTEN; - else + else if (buffer_delay(bh)) type = IO_DELALLOC; + else + type = IO_OVERWRITE; if (!xfs_imap_valid(inode, imap, offset)) { done = 1; @@ -752,23 +754,17 @@ xfs_convert_page( ASSERT(imap->br_startblock != HOLESTARTBLOCK); ASSERT(imap->br_startblock != DELAYSTARTBLOCK); - xfs_map_at_offset(inode, bh, imap, offset); + if (type == IO_OVERWRITE) + lock_buffer(bh); + else + xfs_map_at_offset(inode, bh, imap, offset); xfs_add_to_ioend(inode, bh, offset, type, ioendp, done); page_dirty--; count++; } else { - type = IO_OVERWRITE; - if (buffer_mapped(bh) && all_bh) { - lock_buffer(bh); - xfs_add_to_ioend(inode, bh, offset, - type, ioendp, done); - count++; - page_dirty--; - } else { - done = 1; - } + done = 1; } } while (offset += len, (bh = bh->b_this_page) != head); @@ -800,7 +796,6 @@ xfs_cluster_write( struct xfs_bmbt_irec *imap, xfs_ioend_t **ioendp, struct writeback_control *wbc, - int all_bh, pgoff_t tlast) { struct pagevec pvec; @@ -815,7 +810,7 @@ xfs_cluster_write( for (i = 0; i < pagevec_count(&pvec); i++) { done = xfs_convert_page(inode, pvec.pages[i], tindex++, - imap, ioendp, wbc, all_bh); + imap, ioendp, wbc); if (done) break; } @@ -929,7 +924,6 @@ xfs_vm_writepage( ssize_t len; int err, imap_valid = 0, uptodate = 1; int count = 0; - int all_bh = 0; int nonblocking = 0; trace_xfs_writepage(inode, page, 0); @@ -1065,7 +1059,6 @@ xfs_vm_writepage( } if (imap_valid) { - all_bh = 1; lock_buffer(bh); xfs_add_to_ioend(inode, bh, offset, type, &ioend, new_ioend); @@ -1102,7 +1095,7 @@ xfs_vm_writepage( end_index = last_index; xfs_cluster_write(inode, page->index + 1, &imap, &ioend, - wbc, all_bh, end_index); + wbc, end_index); } if (iohead) -- cgit v1.2.3 From aeea1b1f81800e362a3aca86d769d02e137a8fa7 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Fri, 10 Dec 2010 08:42:24 +0000 Subject: xfs: refactor xfs_vm_writepage After the last patches the code for overwrites is the same as for delayed and unwritten extents except that it doesn't need to call xfs_map_at_offset. Take care of that fact to simplify xfs_vm_writepage. The buffer loop now first checks the type of buffer and checks/sets the ioend type, or continues to the next buffer if it's not interesting to us. Only after that we validate the iomap and perform the block mapping if needed, all in common code for the cases where we have to do work. Signed-off-by: Christoph Hellwig Reviewed-by: Dave Chinner Signed-off-by: Alex Elder --- fs/xfs/linux-2.6/xfs_aops.c | 97 ++++++++++++++++++--------------------------- 1 file changed, 39 insertions(+), 58 deletions(-) diff --git a/fs/xfs/linux-2.6/xfs_aops.c b/fs/xfs/linux-2.6/xfs_aops.c index 86f57f61939b..4d982dc8b862 100644 --- a/fs/xfs/linux-2.6/xfs_aops.c +++ b/fs/xfs/linux-2.6/xfs_aops.c @@ -999,74 +999,55 @@ xfs_vm_writepage( continue; } - if (imap_valid) - imap_valid = xfs_imap_valid(inode, &imap, offset); - - if (buffer_unwritten(bh) || buffer_delay(bh)) { - if (buffer_unwritten(bh)) { - if (type != IO_UNWRITTEN) { - type = IO_UNWRITTEN; - imap_valid = 0; - } - } else if (buffer_delay(bh)) { - if (type != IO_DELALLOC) { - type = IO_DELALLOC; - imap_valid = 0; - } - } - - if (!imap_valid) { - /* - * If we didn't have a valid mapping then we - * need to ensure that we put the new mapping - * in a new ioend structure. This needs to be - * done to ensure that the ioends correctly - * reflect the block mappings at io completion - * for unwritten extent conversion. - */ - new_ioend = 1; - err = xfs_map_blocks(inode, offset, &imap, - type, nonblocking); - if (err) - goto error; - imap_valid = xfs_imap_valid(inode, &imap, - offset); + if (buffer_unwritten(bh)) { + if (type != IO_UNWRITTEN) { + type = IO_UNWRITTEN; + imap_valid = 0; } - if (imap_valid) { - xfs_map_at_offset(inode, bh, &imap, offset); - xfs_add_to_ioend(inode, bh, offset, type, - &ioend, new_ioend); - count++; + } else if (buffer_delay(bh)) { + if (type != IO_DELALLOC) { + type = IO_DELALLOC; + imap_valid = 0; } } else if (buffer_uptodate(bh)) { - /* - * we got here because the buffer is already mapped. - * That means it must already have extents allocated - * underneath it. Map the extent by reading it. - */ if (type != IO_OVERWRITE) { type = IO_OVERWRITE; imap_valid = 0; } - if (!imap_valid) { - new_ioend = 1; - err = xfs_map_blocks(inode, offset, - &imap, type, nonblocking); - if (err) - goto error; - imap_valid = xfs_imap_valid(inode, &imap, - offset); + } else { + if (PageUptodate(page)) { + ASSERT(buffer_mapped(bh)); + imap_valid = 0; } + continue; + } - if (imap_valid) { + if (imap_valid) + imap_valid = xfs_imap_valid(inode, &imap, offset); + if (!imap_valid) { + /* + * If we didn't have a valid mapping then we need to + * put the new mapping into a separate ioend structure. + * This ensures non-contiguous extents always have + * separate ioends, which is particularly important + * for unwritten extent conversion at I/O completion + * time. + */ + new_ioend = 1; + err = xfs_map_blocks(inode, offset, &imap, type, + nonblocking); + if (err) + goto error; + imap_valid = xfs_imap_valid(inode, &imap, offset); + } + if (imap_valid) { + if (type == IO_OVERWRITE) lock_buffer(bh); - xfs_add_to_ioend(inode, bh, offset, type, - &ioend, new_ioend); - count++; - } - } else if (PageUptodate(page)) { - ASSERT(buffer_mapped(bh)); - imap_valid = 0; + else + xfs_map_at_offset(inode, bh, &imap, offset); + xfs_add_to_ioend(inode, bh, offset, type, &ioend, + new_ioend); + count++; } if (!iohead) -- cgit v1.2.3 From ecff71e677c6d469f525dcf31ada709d5858307c Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Fri, 10 Dec 2010 08:42:25 +0000 Subject: xfs: simplify xfs_map_at_offset Move the buffer locking into the callers as they need to do it wether they call xfs_map_at_offset or not. Remove the b_bdev assignment, which is already done by get_blocks. Remove the duplicate extent type asserts in xfs_convert_page just before calling xfs_map_at_offset. Signed-off-by: Christoph Hellwig Reviewed-by: Dave Chinner Signed-off-by: Alex Elder --- fs/xfs/linux-2.6/xfs_aops.c | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/fs/xfs/linux-2.6/xfs_aops.c b/fs/xfs/linux-2.6/xfs_aops.c index 4d982dc8b862..ec7bbb5645b6 100644 --- a/fs/xfs/linux-2.6/xfs_aops.c +++ b/fs/xfs/linux-2.6/xfs_aops.c @@ -626,9 +626,7 @@ xfs_map_at_offset( ASSERT(imap->br_startblock != HOLESTARTBLOCK); ASSERT(imap->br_startblock != DELAYSTARTBLOCK); - lock_buffer(bh); xfs_map_buffer(inode, bh, imap, offset); - bh->b_bdev = xfs_find_bdev_for_inode(inode); set_buffer_mapped(bh); clear_buffer_delay(bh); clear_buffer_unwritten(bh); @@ -751,12 +749,8 @@ xfs_convert_page( continue; } - ASSERT(imap->br_startblock != HOLESTARTBLOCK); - ASSERT(imap->br_startblock != DELAYSTARTBLOCK); - - if (type == IO_OVERWRITE) - lock_buffer(bh); - else + lock_buffer(bh); + if (type != IO_OVERWRITE) xfs_map_at_offset(inode, bh, imap, offset); xfs_add_to_ioend(inode, bh, offset, type, ioendp, done); @@ -1041,9 +1035,8 @@ xfs_vm_writepage( imap_valid = xfs_imap_valid(inode, &imap, offset); } if (imap_valid) { - if (type == IO_OVERWRITE) - lock_buffer(bh); - else + lock_buffer(bh); + if (type != IO_OVERWRITE) xfs_map_at_offset(inode, bh, &imap, offset); xfs_add_to_ioend(inode, bh, offset, type, &ioend, new_ioend); -- cgit v1.2.3 From 9f9baab38dacd11fe6095a1e59f3783a305f7020 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Fri, 10 Dec 2010 15:03:57 +0000 Subject: xfs: clean up xfs_alloc_ag_vextent_exact Use a goto label to consolidate all block not found cases, and add a tracepoint for them. Also clean up a few whitespace issues. Based on an earlier patch from Dave Chinner. Signed-off-by: Christoph Hellwig Signed-off-by: Alex Elder --- fs/xfs/linux-2.6/xfs_trace.h | 1 + fs/xfs/xfs_alloc.c | 58 ++++++++++++++++++++++++-------------------- 2 files changed, 33 insertions(+), 26 deletions(-) diff --git a/fs/xfs/linux-2.6/xfs_trace.h b/fs/xfs/linux-2.6/xfs_trace.h index f56431c916a0..83e8760159ef 100644 --- a/fs/xfs/linux-2.6/xfs_trace.h +++ b/fs/xfs/linux-2.6/xfs_trace.h @@ -1422,6 +1422,7 @@ DEFINE_EVENT(xfs_alloc_class, name, \ TP_PROTO(struct xfs_alloc_arg *args), \ TP_ARGS(args)) DEFINE_ALLOC_EVENT(xfs_alloc_exact_done); +DEFINE_ALLOC_EVENT(xfs_alloc_exact_notfound); DEFINE_ALLOC_EVENT(xfs_alloc_exact_error); DEFINE_ALLOC_EVENT(xfs_alloc_near_nominleft); DEFINE_ALLOC_EVENT(xfs_alloc_near_first); diff --git a/fs/xfs/xfs_alloc.c b/fs/xfs/xfs_alloc.c index 112abc439ca5..d9133f10d2b1 100644 --- a/fs/xfs/xfs_alloc.c +++ b/fs/xfs/xfs_alloc.c @@ -577,61 +577,58 @@ xfs_alloc_ag_vextent_exact( xfs_extlen_t rlen; /* length of returned extent */ ASSERT(args->alignment == 1); + /* * Allocate/initialize a cursor for the by-number freespace btree. */ bno_cur = xfs_allocbt_init_cursor(args->mp, args->tp, args->agbp, - args->agno, XFS_BTNUM_BNO); + args->agno, XFS_BTNUM_BNO); + /* * Lookup bno and minlen in the btree (minlen is irrelevant, really). * Look for the closest free block <= bno, it must contain bno * if any free block does. */ - if ((error = xfs_alloc_lookup_le(bno_cur, args->agbno, args->minlen, &i))) + error = xfs_alloc_lookup_le(bno_cur, args->agbno, args->minlen, &i); + if (error) goto error0; - if (!i) { - /* - * Didn't find it, return null. - */ - xfs_btree_del_cursor(bno_cur, XFS_BTREE_NOERROR); - args->agbno = NULLAGBLOCK; - return 0; - } + if (!i) + goto not_found; + /* * Grab the freespace record. */ - if ((error = xfs_alloc_get_rec(bno_cur, &fbno, &flen, &i))) + error = xfs_alloc_get_rec(bno_cur, &fbno, &flen, &i); + if (error) goto error0; XFS_WANT_CORRUPTED_GOTO(i == 1, error0); ASSERT(fbno <= args->agbno); minend = args->agbno + args->minlen; maxend = args->agbno + args->maxlen; fend = fbno + flen; + /* * Give up if the freespace isn't long enough for the minimum request. */ - if (fend < minend) { - xfs_btree_del_cursor(bno_cur, XFS_BTREE_NOERROR); - args->agbno = NULLAGBLOCK; - return 0; - } + if (fend < minend) + goto not_found; + /* * End of extent will be smaller of the freespace end and the * maximal requested end. - */ - end = XFS_AGBLOCK_MIN(fend, maxend); - /* + * * Fix the length according to mod and prod if given. */ + end = XFS_AGBLOCK_MIN(fend, maxend); args->len = end - args->agbno; xfs_alloc_fix_len(args); - if (!xfs_alloc_fix_minleft(args)) { - xfs_btree_del_cursor(bno_cur, XFS_BTREE_NOERROR); - return 0; - } + if (!xfs_alloc_fix_minleft(args)) + goto not_found; + rlen = args->len; ASSERT(args->agbno + rlen <= fend); end = args->agbno + rlen; + /* * We are allocating agbno for rlen [agbno .. end] * Allocate/initialize a cursor for the by-size btree. @@ -640,16 +637,25 @@ xfs_alloc_ag_vextent_exact( args->agno, XFS_BTNUM_CNT); ASSERT(args->agbno + args->len <= be32_to_cpu(XFS_BUF_TO_AGF(args->agbp)->agf_length)); - if ((error = xfs_alloc_fixup_trees(cnt_cur, bno_cur, fbno, flen, - args->agbno, args->len, XFSA_FIXUP_BNO_OK))) { + error = xfs_alloc_fixup_trees(cnt_cur, bno_cur, fbno, flen, args->agbno, + args->len, XFSA_FIXUP_BNO_OK); + if (error) { xfs_btree_del_cursor(cnt_cur, XFS_BTREE_ERROR); goto error0; } + xfs_btree_del_cursor(bno_cur, XFS_BTREE_NOERROR); xfs_btree_del_cursor(cnt_cur, XFS_BTREE_NOERROR); - trace_xfs_alloc_exact_done(args); args->wasfromfl = 0; + trace_xfs_alloc_exact_done(args); + return 0; + +not_found: + /* Didn't find it, return null. */ + xfs_btree_del_cursor(bno_cur, XFS_BTREE_NOERROR); + args->agbno = NULLAGBLOCK; + trace_xfs_alloc_exact_notfound(args); return 0; error0: -- cgit v1.2.3 From 489a150f6454e2cd93d9e0ee6d7c5a361844f62a Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Fri, 10 Dec 2010 15:04:11 +0000 Subject: xfs: factor duplicate code in xfs_alloc_ag_vextent_near into a helper Add a new xfs_alloc_find_best_extent that does a forward/backward search in the allocation btree. That code previously was existed two times in xfs_alloc_ag_vextent_near, once for each search direction. Based on an earlier patch from Dave Chinner. Signed-off-by: Christoph Hellwig Signed-off-by: Alex Elder --- fs/xfs/xfs_alloc.c | 293 +++++++++++++++++++++-------------------------------- 1 file changed, 113 insertions(+), 180 deletions(-) diff --git a/fs/xfs/xfs_alloc.c b/fs/xfs/xfs_alloc.c index d9133f10d2b1..fa8723f5870a 100644 --- a/fs/xfs/xfs_alloc.c +++ b/fs/xfs/xfs_alloc.c @@ -664,6 +664,95 @@ error0: return error; } +/* + * Search the btree in a given direction via the search cursor and compare + * the records found against the good extent we've already found. + */ +STATIC int +xfs_alloc_find_best_extent( + struct xfs_alloc_arg *args, /* allocation argument structure */ + struct xfs_btree_cur **gcur, /* good cursor */ + struct xfs_btree_cur **scur, /* searching cursor */ + xfs_agblock_t gdiff, /* difference for search comparison */ + xfs_agblock_t *sbno, /* extent found by search */ + xfs_extlen_t *slen, + xfs_extlen_t *slena, /* aligned length */ + int dir) /* 0 = search right, 1 = search left */ +{ + xfs_agblock_t bno; + xfs_agblock_t new; + xfs_agblock_t sdiff; + int error; + int i; + + /* The good extent is perfect, no need to search. */ + if (!gdiff) + goto out_use_good; + + /* + * Look until we find a better one, run out of space or run off the end. + */ + do { + error = xfs_alloc_get_rec(*scur, sbno, slen, &i); + if (error) + goto error0; + XFS_WANT_CORRUPTED_GOTO(i == 1, error0); + xfs_alloc_compute_aligned(*sbno, *slen, args->alignment, + args->minlen, &bno, slena); + + /* + * The good extent is closer than this one. + */ + if (!dir) { + if (bno >= args->agbno + gdiff) + goto out_use_good; + } else { + if (bno <= args->agbno - gdiff) + goto out_use_good; + } + + /* + * Same distance, compare length and pick the best. + */ + if (*slena >= args->minlen) { + args->len = XFS_EXTLEN_MIN(*slena, args->maxlen); + xfs_alloc_fix_len(args); + + sdiff = xfs_alloc_compute_diff(args->agbno, args->len, + args->alignment, *sbno, + *slen, &new); + + /* + * Choose closer size and invalidate other cursor. + */ + if (sdiff < gdiff) + goto out_use_search; + goto out_use_good; + } + + if (!dir) + error = xfs_btree_increment(*scur, 0, &i); + else + error = xfs_btree_decrement(*scur, 0, &i); + if (error) + goto error0; + } while (i); + +out_use_good: + xfs_btree_del_cursor(*scur, XFS_BTREE_NOERROR); + *scur = NULL; + return 0; + +out_use_search: + xfs_btree_del_cursor(*gcur, XFS_BTREE_NOERROR); + *gcur = NULL; + return 0; + +error0: + /* caller invalidates cursors */ + return error; +} + /* * Allocate a variable extent near bno in the allocation group agno. * Extent's length (returned in len) will be between minlen and maxlen, @@ -931,203 +1020,45 @@ xfs_alloc_ag_vextent_near( } } } while (bno_cur_lt || bno_cur_gt); + /* * Got both cursors still active, need to find better entry. */ if (bno_cur_lt && bno_cur_gt) { - /* - * Left side is long enough, look for a right side entry. - */ if (ltlena >= args->minlen) { /* - * Fix up the length. + * Left side is good, look for a right side entry. */ args->len = XFS_EXTLEN_MIN(ltlena, args->maxlen); xfs_alloc_fix_len(args); - rlen = args->len; - ltdiff = xfs_alloc_compute_diff(args->agbno, rlen, + ltdiff = xfs_alloc_compute_diff(args->agbno, args->len, args->alignment, ltbno, ltlen, <new); + + error = xfs_alloc_find_best_extent(args, + &bno_cur_lt, &bno_cur_gt, + ltdiff, >bno, >len, >lena, + 0 /* search right */); + } else { + ASSERT(gtlena >= args->minlen); + /* - * Not perfect. - */ - if (ltdiff) { - /* - * Look until we find a better one, run out of - * space, or run off the end. - */ - while (bno_cur_lt && bno_cur_gt) { - if ((error = xfs_alloc_get_rec( - bno_cur_gt, >bno, - >len, &i))) - goto error0; - XFS_WANT_CORRUPTED_GOTO(i == 1, error0); - xfs_alloc_compute_aligned(gtbno, gtlen, - args->alignment, args->minlen, - >bnoa, >lena); - /* - * The left one is clearly better. - */ - if (gtbnoa >= args->agbno + ltdiff) { - xfs_btree_del_cursor( - bno_cur_gt, - XFS_BTREE_NOERROR); - bno_cur_gt = NULL; - break; - } - /* - * If we reach a big enough entry, - * compare the two and pick the best. - */ - if (gtlena >= args->minlen) { - args->len = - XFS_EXTLEN_MIN(gtlena, - args->maxlen); - xfs_alloc_fix_len(args); - rlen = args->len; - gtdiff = xfs_alloc_compute_diff( - args->agbno, rlen, - args->alignment, - gtbno, gtlen, >new); - /* - * Right side is better. - */ - if (gtdiff < ltdiff) { - xfs_btree_del_cursor( - bno_cur_lt, - XFS_BTREE_NOERROR); - bno_cur_lt = NULL; - } - /* - * Left side is better. - */ - else { - xfs_btree_del_cursor( - bno_cur_gt, - XFS_BTREE_NOERROR); - bno_cur_gt = NULL; - } - break; - } - /* - * Fell off the right end. - */ - if ((error = xfs_btree_increment( - bno_cur_gt, 0, &i))) - goto error0; - if (!i) { - xfs_btree_del_cursor( - bno_cur_gt, - XFS_BTREE_NOERROR); - bno_cur_gt = NULL; - break; - } - } - } - /* - * The left side is perfect, trash the right side. - */ - else { - xfs_btree_del_cursor(bno_cur_gt, - XFS_BTREE_NOERROR); - bno_cur_gt = NULL; - } - } - /* - * It's the right side that was found first, look left. - */ - else { - /* - * Fix up the length. + * Right side is good, look for a left side entry. */ args->len = XFS_EXTLEN_MIN(gtlena, args->maxlen); xfs_alloc_fix_len(args); - rlen = args->len; - gtdiff = xfs_alloc_compute_diff(args->agbno, rlen, + gtdiff = xfs_alloc_compute_diff(args->agbno, args->len, args->alignment, gtbno, gtlen, >new); - /* - * Right side entry isn't perfect. - */ - if (gtdiff) { - /* - * Look until we find a better one, run out of - * space, or run off the end. - */ - while (bno_cur_lt && bno_cur_gt) { - if ((error = xfs_alloc_get_rec( - bno_cur_lt, <bno, - <len, &i))) - goto error0; - XFS_WANT_CORRUPTED_GOTO(i == 1, error0); - xfs_alloc_compute_aligned(ltbno, ltlen, - args->alignment, args->minlen, - <bnoa, <lena); - /* - * The right one is clearly better. - */ - if (ltbnoa <= args->agbno - gtdiff) { - xfs_btree_del_cursor( - bno_cur_lt, - XFS_BTREE_NOERROR); - bno_cur_lt = NULL; - break; - } - /* - * If we reach a big enough entry, - * compare the two and pick the best. - */ - if (ltlena >= args->minlen) { - args->len = XFS_EXTLEN_MIN( - ltlena, args->maxlen); - xfs_alloc_fix_len(args); - rlen = args->len; - ltdiff = xfs_alloc_compute_diff( - args->agbno, rlen, - args->alignment, - ltbno, ltlen, <new); - /* - * Left side is better. - */ - if (ltdiff < gtdiff) { - xfs_btree_del_cursor( - bno_cur_gt, - XFS_BTREE_NOERROR); - bno_cur_gt = NULL; - } - /* - * Right side is better. - */ - else { - xfs_btree_del_cursor( - bno_cur_lt, - XFS_BTREE_NOERROR); - bno_cur_lt = NULL; - } - break; - } - /* - * Fell off the left end. - */ - if ((error = xfs_btree_decrement( - bno_cur_lt, 0, &i))) - goto error0; - if (!i) { - xfs_btree_del_cursor(bno_cur_lt, - XFS_BTREE_NOERROR); - bno_cur_lt = NULL; - break; - } - } - } - /* - * The right side is perfect, trash the left side. - */ - else { - xfs_btree_del_cursor(bno_cur_lt, - XFS_BTREE_NOERROR); - bno_cur_lt = NULL; - } + + error = xfs_alloc_find_best_extent(args, + &bno_cur_gt, &bno_cur_lt, + gtdiff, <bno, <len, <lena, + 1 /* search left */); } + + if (error) + goto error0; } + /* * If we couldn't get anything, give up. */ @@ -1136,6 +1067,7 @@ xfs_alloc_ag_vextent_near( args->agbno = NULLAGBLOCK; return 0; } + /* * At this point we have selected a freespace entry, either to the * left or to the right. If it's on the right, copy all the @@ -1152,6 +1084,7 @@ xfs_alloc_ag_vextent_near( j = 1; } else j = 0; + /* * Fix up the length and compute the useful address. */ -- cgit v1.2.3 From dcfcf20512cb517ac18b9433b676183fa1257911 Mon Sep 17 00:00:00 2001 From: Dave Chinner Date: Thu, 23 Dec 2010 11:57:13 +1100 Subject: xfs: provide a inode iolock lockdep class The XFS iolock needs to be re-initialised to a new lock class before it enters reclaim to prevent lockdep false positives. Unfortunately, this is not sufficient protection as inodes in the XFS_IRECLAIMABLE state can be recycled and not re-initialised before being reused. We need to re-initialise the lock state when transfering out of XFS_IRECLAIMABLE state to XFS_INEW, but we need to keep the same class as if the inode was just allocated. Hence we need a specific lockdep class variable for the iolock so that both initialisations use the same class. While there, add a specific class for inodes in the reclaim state so that it is easy to tell from lockdep reports what state the inode was in that generated the report. Signed-off-by: Dave Chinner Reviewed-by: Christoph Hellwig --- fs/xfs/linux-2.6/xfs_super.c | 2 ++ fs/xfs/xfs_iget.c | 19 +++++++++++++++++++ fs/xfs/xfs_inode.h | 2 ++ 3 files changed, 23 insertions(+) diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c index 064f964d4f3c..c45b3233d486 100644 --- a/fs/xfs/linux-2.6/xfs_super.c +++ b/fs/xfs/linux-2.6/xfs_super.c @@ -1118,6 +1118,8 @@ xfs_fs_evict_inode( */ ASSERT(!rwsem_is_locked(&ip->i_iolock.mr_lock)); mrlock_init(&ip->i_iolock, MRLOCK_BARRIER, "xfsio", ip->i_ino); + lockdep_set_class_and_name(&ip->i_iolock.mr_lock, + &xfs_iolock_reclaimable, "xfs_iolock_reclaimable"); xfs_inactive(ip); } diff --git a/fs/xfs/xfs_iget.c b/fs/xfs/xfs_iget.c index 0cdd26932d8e..cdb1c2505fc6 100644 --- a/fs/xfs/xfs_iget.c +++ b/fs/xfs/xfs_iget.c @@ -42,6 +42,17 @@ #include "xfs_trace.h" +/* + * Define xfs inode iolock lockdep classes. We need to ensure that all active + * inodes are considered the same for lockdep purposes, including inodes that + * are recycled through the XFS_IRECLAIMABLE state. This is the the only way to + * guarantee the locks are considered the same when there are multiple lock + * initialisation siteÑ•. Also, define a reclaimable inode class so it is + * obvious in lockdep reports which class the report is against. + */ +static struct lock_class_key xfs_iolock_active; +struct lock_class_key xfs_iolock_reclaimable; + /* * Allocate and initialise an xfs_inode. */ @@ -71,6 +82,8 @@ xfs_inode_alloc( ASSERT(completion_done(&ip->i_flush)); mrlock_init(&ip->i_iolock, MRLOCK_BARRIER, "xfsio", ip->i_ino); + lockdep_set_class_and_name(&ip->i_iolock.mr_lock, + &xfs_iolock_active, "xfs_iolock_active"); /* initialise the xfs inode */ ip->i_ino = ino; @@ -218,6 +231,12 @@ xfs_iget_cache_hit( ip->i_flags |= XFS_INEW; __xfs_inode_clear_reclaim_tag(mp, pag, ip); inode->i_state = I_NEW; + + ASSERT(!rwsem_is_locked(&ip->i_iolock.mr_lock)); + mrlock_init(&ip->i_iolock, MRLOCK_BARRIER, "xfsio", ip->i_ino); + lockdep_set_class_and_name(&ip->i_iolock.mr_lock, + &xfs_iolock_active, "xfs_iolock_active"); + spin_unlock(&ip->i_flags_lock); write_unlock(&pag->pag_ici_lock); } else { diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h index fb2ca2e4cdc9..1c6514d73dc8 100644 --- a/fs/xfs/xfs_inode.h +++ b/fs/xfs/xfs_inode.h @@ -438,6 +438,8 @@ static inline void xfs_ifunlock(xfs_inode_t *ip) #define XFS_IOLOCK_DEP(flags) (((flags) & XFS_IOLOCK_DEP_MASK) >> XFS_IOLOCK_SHIFT) #define XFS_ILOCK_DEP(flags) (((flags) & XFS_ILOCK_DEP_MASK) >> XFS_ILOCK_SHIFT) +extern struct lock_class_key xfs_iolock_reclaimable; + /* * Flags for xfs_itruncate_start(). */ -- cgit v1.2.3 From 622d81494fa32343a4b97b607619656c7a4a6d1a Mon Sep 17 00:00:00 2001 From: Dave Chinner Date: Thu, 23 Dec 2010 11:57:37 +1100 Subject: xfs: use KM_NOFS for allocations during attribute list operations When listing attributes, we are doiing memory allocations under the inode ilock using only KM_SLEEP. This allows memory allocation to recurse back into the filesystem and do writeback, which may the ilock we already hold on the current inode. THis will deadlock. Hence use KM_NOFS for such allocations outside of transaction context to ensure that reclaim recursion does not occur. Reported-by: Nick Piggin Signed-off-by: Dave Chinner Reviewed-by: Christoph Hellwig --- fs/xfs/xfs_attr_leaf.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/xfs/xfs_attr_leaf.c b/fs/xfs/xfs_attr_leaf.c index a6cff8edcdb6..71e90dc2aeb1 100644 --- a/fs/xfs/xfs_attr_leaf.c +++ b/fs/xfs/xfs_attr_leaf.c @@ -637,7 +637,7 @@ xfs_attr_shortform_list(xfs_attr_list_context_t *context) * It didn't all fit, so we have to sort everything on hashval. */ sbsize = sf->hdr.count * sizeof(*sbuf); - sbp = sbuf = kmem_alloc(sbsize, KM_SLEEP); + sbp = sbuf = kmem_alloc(sbsize, KM_SLEEP | KM_NOFS); /* * Scan the attribute list for the rest of the entries, storing @@ -2386,7 +2386,7 @@ xfs_attr_leaf_list_int(xfs_dabuf_t *bp, xfs_attr_list_context_t *context) args.dp = context->dp; args.whichfork = XFS_ATTR_FORK; args.valuelen = valuelen; - args.value = kmem_alloc(valuelen, KM_SLEEP); + args.value = kmem_alloc(valuelen, KM_SLEEP | KM_NOFS); args.rmtblkno = be32_to_cpu(name_rmt->valueblk); args.rmtblkcnt = XFS_B_TO_FSB(args.dp->i_mount, valuelen); retval = xfs_attr_rmtval_get(&args); -- cgit v1.2.3 From 055388a3188f56676c21e92962fc366ac8b5cb72 Mon Sep 17 00:00:00 2001 From: Dave Chinner Date: Tue, 4 Jan 2011 11:35:03 +1100 Subject: xfs: dynamic speculative EOF preallocation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Currently the size of the speculative preallocation during delayed allocation is fixed by either the allocsize mount option of a default size. We are seeing a lot of cases where we need to recommend using the allocsize mount option to prevent fragmentation when buffered writes land in the same AG. Rather than using a fixed preallocation size by default (up to 64k), make it dynamic by basing it on the current inode size. That way the EOF preallocation will increase as the file size increases. Hence for streaming writes we are much more likely to get large preallocations exactly when we need it to reduce fragementation. For default settings, the size of the initial extents is determined by the number of parallel writers and the amount of memory in the machine. For 4GB RAM and 4 concurrent 32GB file writes: EXT: FILE-OFFSET BLOCK-RANGE AG AG-OFFSET TOTAL 0: [0..1048575]: 1048672..2097247 0 (1048672..2097247) 1048576 1: [1048576..2097151]: 5242976..6291551 0 (5242976..6291551) 1048576 2: [2097152..4194303]: 12583008..14680159 0 (12583008..14680159) 2097152 3: [4194304..8388607]: 25165920..29360223 0 (25165920..29360223) 4194304 4: [8388608..16777215]: 58720352..67108959 0 (58720352..67108959) 8388608 5: [16777216..33554423]: 117440584..134217791 0 (117440584..134217791) 16777208 6: [33554424..50331511]: 184549056..201326143 0 (184549056..201326143) 16777088 7: [50331512..67108599]: 251657408..268434495 0 (251657408..268434495) 16777088 and for 16 concurrent 16GB file writes: EXT: FILE-OFFSET BLOCK-RANGE AG AG-OFFSET TOTAL 0: [0..262143]: 2490472..2752615 0 (2490472..2752615) 262144 1: [262144..524287]: 6291560..6553703 0 (6291560..6553703) 262144 2: [524288..1048575]: 13631592..14155879 0 (13631592..14155879) 524288 3: [1048576..2097151]: 30408808..31457383 0 (30408808..31457383) 1048576 4: [2097152..4194303]: 52428904..54526055 0 (52428904..54526055) 2097152 5: [4194304..8388607]: 104857704..109052007 0 (104857704..109052007) 4194304 6: [8388608..16777215]: 209715304..218103911 0 (209715304..218103911) 8388608 7: [16777216..33554423]: 452984848..469762055 0 (452984848..469762055) 16777208 Because it is hard to take back specualtive preallocation, cases where there are large slow growing log files on a nearly full filesystem may cause premature ENOSPC. Hence as the filesystem nears full, the maximum dynamic prealloc size Ñ–s reduced according to this table (based on 4k block size): freespace max prealloc size >5% full extent (8GB) 4-5% 2GB (8GB >> 2) 3-4% 1GB (8GB >> 3) 2-3% 512MB (8GB >> 4) 1-2% 256MB (8GB >> 5) <1% 128MB (8GB >> 6) This should reduce the amount of space held in speculative preallocation for such cases. The allocsize mount option turns off the dynamic behaviour and fixes the prealloc size to whatever the mount option specifies. i.e. the behaviour is unchanged. Signed-off-by: Dave Chinner --- fs/xfs/xfs_fsops.c | 1 + fs/xfs/xfs_iomap.c | 84 +++++++++++++++++++++++++++++++++++++++++++++++------- fs/xfs/xfs_mount.c | 21 ++++++++++++++ fs/xfs/xfs_mount.h | 14 +++++++++ 4 files changed, 110 insertions(+), 10 deletions(-) diff --git a/fs/xfs/xfs_fsops.c b/fs/xfs/xfs_fsops.c index a7c116e814af..f56d30e8040c 100644 --- a/fs/xfs/xfs_fsops.c +++ b/fs/xfs/xfs_fsops.c @@ -374,6 +374,7 @@ xfs_growfs_data_private( mp->m_maxicount = icount << mp->m_sb.sb_inopblog; } else mp->m_maxicount = 0; + xfs_set_low_space_thresholds(mp); /* update secondary superblocks. */ for (agno = 1; agno < nagcount; agno++) { diff --git a/fs/xfs/xfs_iomap.c b/fs/xfs/xfs_iomap.c index 22b62a179e89..55582bd66659 100644 --- a/fs/xfs/xfs_iomap.c +++ b/fs/xfs/xfs_iomap.c @@ -267,6 +267,9 @@ error_out: * If the caller is doing a write at the end of the file, then extend the * allocation out to the file system's write iosize. We clean up any extra * space left over when the file is closed in xfs_inactive(). + * + * If we find we already have delalloc preallocation beyond EOF, don't do more + * preallocation as it it not needed. */ STATIC int xfs_iomap_eof_want_preallocate( @@ -282,6 +285,7 @@ xfs_iomap_eof_want_preallocate( xfs_filblks_t count_fsb; xfs_fsblock_t firstblock; int n, error, imaps; + int found_delalloc = 0; *prealloc = 0; if ((offset + count) <= ip->i_size) @@ -306,12 +310,60 @@ xfs_iomap_eof_want_preallocate( return 0; start_fsb += imap[n].br_blockcount; count_fsb -= imap[n].br_blockcount; + + if (imap[n].br_startblock == DELAYSTARTBLOCK) + found_delalloc = 1; } } - *prealloc = 1; + if (!found_delalloc) + *prealloc = 1; return 0; } +/* + * If we don't have a user specified preallocation size, dynamically increase + * the preallocation size as the size of the file grows. Cap the maximum size + * at a single extent or less if the filesystem is near full. The closer the + * filesystem is to full, the smaller the maximum prealocation. + */ +STATIC xfs_fsblock_t +xfs_iomap_prealloc_size( + struct xfs_mount *mp, + struct xfs_inode *ip) +{ + xfs_fsblock_t alloc_blocks = 0; + + if (!(mp->m_flags & XFS_MOUNT_DFLT_IOSIZE)) { + int shift = 0; + int64_t freesp; + + alloc_blocks = XFS_B_TO_FSB(mp, ip->i_size); + alloc_blocks = XFS_FILEOFF_MIN(MAXEXTLEN, + rounddown_pow_of_two(alloc_blocks)); + + xfs_icsb_sync_counters(mp, XFS_ICSB_LAZY_COUNT); + freesp = mp->m_sb.sb_fdblocks; + if (freesp < mp->m_low_space[XFS_LOWSP_5_PCNT]) { + shift = 2; + if (freesp < mp->m_low_space[XFS_LOWSP_4_PCNT]) + shift++; + if (freesp < mp->m_low_space[XFS_LOWSP_3_PCNT]) + shift++; + if (freesp < mp->m_low_space[XFS_LOWSP_2_PCNT]) + shift++; + if (freesp < mp->m_low_space[XFS_LOWSP_1_PCNT]) + shift++; + } + if (shift) + alloc_blocks >>= shift; + } + + if (alloc_blocks < mp->m_writeio_blocks) + alloc_blocks = mp->m_writeio_blocks; + + return alloc_blocks; +} + int xfs_iomap_write_delay( xfs_inode_t *ip, @@ -344,6 +396,7 @@ xfs_iomap_write_delay( extsz = xfs_get_extsz_hint(ip); offset_fsb = XFS_B_TO_FSBT(mp, offset); + error = xfs_iomap_eof_want_preallocate(mp, ip, offset, count, imap, XFS_WRITE_IMAPS, &prealloc); if (error) @@ -351,9 +404,11 @@ xfs_iomap_write_delay( retry: if (prealloc) { + xfs_fsblock_t alloc_blocks = xfs_iomap_prealloc_size(mp, ip); + aligned_offset = XFS_WRITEIO_ALIGN(mp, (offset + count - 1)); ioalign = XFS_B_TO_FSBT(mp, aligned_offset); - last_fsb = ioalign + mp->m_writeio_blocks; + last_fsb = ioalign + alloc_blocks; } else { last_fsb = XFS_B_TO_FSB(mp, ((xfs_ufsize_t)(offset + count))); } @@ -371,22 +426,31 @@ retry: XFS_BMAPI_DELAY | XFS_BMAPI_WRITE | XFS_BMAPI_ENTIRE, &firstblock, 1, imap, &nimaps, NULL); - if (error && (error != ENOSPC)) + switch (error) { + case 0: + case ENOSPC: + case EDQUOT: + break; + default: return XFS_ERROR(error); + } /* - * If bmapi returned us nothing, and if we didn't get back EDQUOT, - * then we must have run out of space - flush all other inodes with - * delalloc blocks and retry without EOF preallocation. + * If bmapi returned us nothing, we got either ENOSPC or EDQUOT. For + * ENOSPC, * flush all other inodes with delalloc blocks to free up + * some of the excess reserved metadata space. For both cases, retry + * without EOF preallocation. */ if (nimaps == 0) { trace_xfs_delalloc_enospc(ip, offset, count); if (flushed) - return XFS_ERROR(ENOSPC); + return XFS_ERROR(error ? error : ENOSPC); - xfs_iunlock(ip, XFS_ILOCK_EXCL); - xfs_flush_inodes(ip); - xfs_ilock(ip, XFS_ILOCK_EXCL); + if (error == ENOSPC) { + xfs_iunlock(ip, XFS_ILOCK_EXCL); + xfs_flush_inodes(ip); + xfs_ilock(ip, XFS_ILOCK_EXCL); + } flushed = 1; error = 0; diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c index 19e9dfa1c254..40579fdf0d0a 100644 --- a/fs/xfs/xfs_mount.c +++ b/fs/xfs/xfs_mount.c @@ -974,6 +974,24 @@ xfs_set_rw_sizes(xfs_mount_t *mp) mp->m_writeio_blocks = 1 << (mp->m_writeio_log - sbp->sb_blocklog); } +/* + * precalculate the low space thresholds for dynamic speculative preallocation. + */ +void +xfs_set_low_space_thresholds( + struct xfs_mount *mp) +{ + int i; + + for (i = 0; i < XFS_LOWSP_MAX; i++) { + __uint64_t space = mp->m_sb.sb_dblocks; + + do_div(space, 100); + mp->m_low_space[i] = space * (i + 1); + } +} + + /* * Set whether we're using inode alignment. */ @@ -1196,6 +1214,9 @@ xfs_mountfs( */ xfs_set_rw_sizes(mp); + /* set the low space thresholds for dynamic preallocation */ + xfs_set_low_space_thresholds(mp); + /* * Set the inode cluster size. * This may still be overridden by the file system diff --git a/fs/xfs/xfs_mount.h b/fs/xfs/xfs_mount.h index 5861b4980740..a62e8971539d 100644 --- a/fs/xfs/xfs_mount.h +++ b/fs/xfs/xfs_mount.h @@ -103,6 +103,16 @@ extern int xfs_icsb_modify_counters(struct xfs_mount *, xfs_sb_field_t, xfs_mod_incore_sb(mp, field, delta, rsvd) #endif +/* dynamic preallocation free space thresholds, 5% down to 1% */ +enum { + XFS_LOWSP_1_PCNT = 0, + XFS_LOWSP_2_PCNT, + XFS_LOWSP_3_PCNT, + XFS_LOWSP_4_PCNT, + XFS_LOWSP_5_PCNT, + XFS_LOWSP_MAX, +}; + typedef struct xfs_mount { struct super_block *m_super; xfs_tid_t m_tid; /* next unused tid for fs */ @@ -202,6 +212,8 @@ typedef struct xfs_mount { __int64_t m_update_flags; /* sb flags we need to update on the next remount,rw */ struct shrinker m_inode_shrink; /* inode reclaim shrinker */ + int64_t m_low_space[XFS_LOWSP_MAX]; + /* low free space thresholds */ } xfs_mount_t; /* @@ -379,6 +391,8 @@ extern int xfs_sb_validate_fsb_count(struct xfs_sb *, __uint64_t); extern int xfs_dev_is_read_only(struct xfs_mount *, char *); +extern void xfs_set_low_space_thresholds(struct xfs_mount *); + #endif /* __KERNEL__ */ extern void xfs_mod_sb(struct xfs_trans *, __int64_t); -- cgit v1.2.3 From 6e857567dbbfe14dd6cc3f7414671b047b1ff5c7 Mon Sep 17 00:00:00 2001 From: Dave Chinner Date: Thu, 23 Dec 2010 12:02:31 +1100 Subject: xfs: don't truncate prealloc from frequently accessed inodes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A long standing problem for streaming writeÑ• through the NFS server has been that the NFS server opens and closes file descriptors on an inode for every write. The result of this behaviour is that the ->release() function is called on every close and that results in XFS truncating speculative preallocation beyond the EOF. This has an adverse effect on file layout when multiple files are being written at the same time - they interleave their extents and can result in severe fragmentation. To avoid this problem, keep track of ->release calls made on a dirty inode. For most cases, an inode is only going to be opened once for writing and then closed again during it's lifetime in cache. Hence if there are multiple ->release calls when the inode is dirty, there is a good chance that the inode is being accessed by the NFS server. Hence set a flag the first time ->release is called while there are delalloc blocks still outstanding on the inode. If this flag is set when ->release is next called, then do no truncate away the speculative preallocation - leave it there so that subsequent writes do not need to reallocate the delalloc space. This will prevent interleaving of extents of different inodes written concurrently to the same AG. If we get this wrong, it is not a big deal as we truncate speculative allocation beyond EOF anyway in xfs_inactive() when the inode is thrown out of the cache. Signed-off-by: Dave Chinner Reviewed-by: Christoph Hellwig --- fs/xfs/xfs_inode.h | 13 ++++++----- fs/xfs/xfs_vnodeops.c | 61 +++++++++++++++++++++++++++++++++------------------ 2 files changed, 47 insertions(+), 27 deletions(-) diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h index 1c6514d73dc8..5c95fa8ec11d 100644 --- a/fs/xfs/xfs_inode.h +++ b/fs/xfs/xfs_inode.h @@ -376,12 +376,13 @@ static inline void xfs_ifunlock(xfs_inode_t *ip) /* * In-core inode flags. */ -#define XFS_IRECLAIM 0x0001 /* we have started reclaiming this inode */ -#define XFS_ISTALE 0x0002 /* inode has been staled */ -#define XFS_IRECLAIMABLE 0x0004 /* inode can be reclaimed */ -#define XFS_INEW 0x0008 /* inode has just been allocated */ -#define XFS_IFILESTREAM 0x0010 /* inode is in a filestream directory */ -#define XFS_ITRUNCATED 0x0020 /* truncated down so flush-on-close */ +#define XFS_IRECLAIM 0x0001 /* started reclaiming this inode */ +#define XFS_ISTALE 0x0002 /* inode has been staled */ +#define XFS_IRECLAIMABLE 0x0004 /* inode can be reclaimed */ +#define XFS_INEW 0x0008 /* inode has just been allocated */ +#define XFS_IFILESTREAM 0x0010 /* inode is in a filestream directory */ +#define XFS_ITRUNCATED 0x0020 /* truncated down so flush-on-close */ +#define XFS_IDIRTY_RELEASE 0x0040 /* dirty release already seen */ /* * Flags for inode locking. diff --git a/fs/xfs/xfs_vnodeops.c b/fs/xfs/xfs_vnodeops.c index 8e4a63c4151a..d8e6f8cd6f0c 100644 --- a/fs/xfs/xfs_vnodeops.c +++ b/fs/xfs/xfs_vnodeops.c @@ -964,29 +964,48 @@ xfs_release( xfs_flush_pages(ip, 0, -1, XBF_ASYNC, FI_NONE); } - if (ip->i_d.di_nlink != 0) { - if ((((ip->i_d.di_mode & S_IFMT) == S_IFREG) && - ((ip->i_size > 0) || (VN_CACHED(VFS_I(ip)) > 0 || - ip->i_delayed_blks > 0)) && - (ip->i_df.if_flags & XFS_IFEXTENTS)) && - (!(ip->i_d.di_flags & - (XFS_DIFLAG_PREALLOC | XFS_DIFLAG_APPEND)))) { + if (ip->i_d.di_nlink == 0) + return 0; - /* - * If we can't get the iolock just skip truncating - * the blocks past EOF because we could deadlock - * with the mmap_sem otherwise. We'll get another - * chance to drop them once the last reference to - * the inode is dropped, so we'll never leak blocks - * permanently. - */ - error = xfs_free_eofblocks(mp, ip, - XFS_FREE_EOF_TRYLOCK); - if (error) - return error; - } - } + if ((((ip->i_d.di_mode & S_IFMT) == S_IFREG) && + ((ip->i_size > 0) || (VN_CACHED(VFS_I(ip)) > 0 || + ip->i_delayed_blks > 0)) && + (ip->i_df.if_flags & XFS_IFEXTENTS)) && + (!(ip->i_d.di_flags & (XFS_DIFLAG_PREALLOC | XFS_DIFLAG_APPEND)))) { + /* + * If we can't get the iolock just skip truncating the blocks + * past EOF because we could deadlock with the mmap_sem + * otherwise. We'll get another chance to drop them once the + * last reference to the inode is dropped, so we'll never leak + * blocks permanently. + * + * Further, check if the inode is being opened, written and + * closed frequently and we have delayed allocation blocks + * oustanding (e.g. streaming writes from the NFS server), + * truncating the blocks past EOF will cause fragmentation to + * occur. + * + * In this case don't do the truncation, either, but we have to + * be careful how we detect this case. Blocks beyond EOF show + * up as i_delayed_blks even when the inode is clean, so we + * need to truncate them away first before checking for a dirty + * release. Hence on the first dirty close we will still remove + * the speculative allocation, but after that we will leave it + * in place. + */ + if (xfs_iflags_test(ip, XFS_IDIRTY_RELEASE)) + return 0; + + error = xfs_free_eofblocks(mp, ip, + XFS_FREE_EOF_TRYLOCK); + if (error) + return error; + + /* delalloc blocks after truncation means it really is dirty */ + if (ip->i_delayed_blks) + xfs_iflags_set(ip, XFS_IDIRTY_RELEASE); + } return 0; } -- cgit v1.2.3 From d95b7aaf9ab6738bef1ebcc52ab66563085e44ac Mon Sep 17 00:00:00 2001 From: Dave Chinner Date: Thu, 16 Dec 2010 16:41:39 +1100 Subject: xfs: rcu free inodes Introduce RCU freeing of XFS inodes so that we can convert lookup traversals to use rcu_read_lock() protection. This patch only introduces the RCU freeing to minimise the potential conflicts with mainline if this is merged into mainline via a VFS patchset. It abuses the i_dentry list for the RCU callback structure because the VFS patches make this a union so it is safe to use like this and simplifies and merge issues. This patch uses basic RCU freeing rather than SLAB_DESTROY_BY_RCU. The later lookup patches need the same "found free inode" protection regardless of the RCU freeing method used, so once again the RCU freeing method can be dealt with apprpriately at merge time without affecting any other code. Signed-off-by: Dave Chinner Reviewed-by: Paul E. McKenney --- fs/xfs/xfs_iget.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/fs/xfs/xfs_iget.c b/fs/xfs/xfs_iget.c index cdb1c2505fc6..9fae47556604 100644 --- a/fs/xfs/xfs_iget.c +++ b/fs/xfs/xfs_iget.c @@ -104,6 +104,18 @@ xfs_inode_alloc( return ip; } +void +__xfs_inode_free( + struct rcu_head *head) +{ + struct inode *inode = container_of((void *)head, + struct inode, i_dentry); + struct xfs_inode *ip = XFS_I(inode); + + INIT_LIST_HEAD(&inode->i_dentry); + kmem_zone_free(xfs_inode_zone, ip); +} + void xfs_inode_free( struct xfs_inode *ip) @@ -147,7 +159,7 @@ xfs_inode_free( ASSERT(!spin_is_locked(&ip->i_flags_lock)); ASSERT(completion_done(&ip->i_flush)); - kmem_zone_free(xfs_inode_zone, ip); + call_rcu((struct rcu_head *)&VFS_I(ip)->i_dentry, __xfs_inode_free); } /* -- cgit v1.2.3 From 1a3e8f3da09c7082d25b512a0ffe569391e4c09a Mon Sep 17 00:00:00 2001 From: Dave Chinner Date: Fri, 17 Dec 2010 17:29:43 +1100 Subject: xfs: convert inode cache lookups to use RCU locking MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With delayed logging greatly increasing the sustained parallelism of inode operations, the inode cache locking is showing significant read vs write contention when inode reclaim runs at the same time as lookups. There is also a lot more write lock acquistions than there are read locks (4:1 ratio) so the read locking is not really buying us much in the way of parallelism. To avoid the read vs write contention, change the cache to use RCU locking on the read side. To avoid needing to RCU free every single inode, use the built in slab RCU freeing mechanism. This requires us to be able to detect lookups of freed inodes, so enÑ•ure that ever freed inode has an inode number of zero and the XFS_IRECLAIM flag set. We already check the XFS_IRECLAIM flag in cache hit lookup path, but also add a check for a zero inode number as well. We canthen convert all the read locking lockups to use RCU read side locking and hence remove all read side locking. Signed-off-by: Dave Chinner Reviewed-by: Alex Elder --- fs/xfs/linux-2.6/xfs_sync.c | 84 +++++++++++++++++++++++++++++++++++---------- fs/xfs/xfs_iget.c | 47 ++++++++++++++++++------- fs/xfs/xfs_inode.c | 52 +++++++++++++++++++++------- 3 files changed, 141 insertions(+), 42 deletions(-) diff --git a/fs/xfs/linux-2.6/xfs_sync.c b/fs/xfs/linux-2.6/xfs_sync.c index afb0d7cfad1c..fd38682da851 100644 --- a/fs/xfs/linux-2.6/xfs_sync.c +++ b/fs/xfs/linux-2.6/xfs_sync.c @@ -53,14 +53,30 @@ xfs_inode_ag_walk_grab( { struct inode *inode = VFS_I(ip); + ASSERT(rcu_read_lock_held()); + + /* + * check for stale RCU freed inode + * + * If the inode has been reallocated, it doesn't matter if it's not in + * the AG we are walking - we are walking for writeback, so if it + * passes all the "valid inode" checks and is dirty, then we'll write + * it back anyway. If it has been reallocated and still being + * initialised, the XFS_INEW check below will catch it. + */ + spin_lock(&ip->i_flags_lock); + if (!ip->i_ino) + goto out_unlock_noent; + + /* avoid new or reclaimable inodes. Leave for reclaim code to flush */ + if (__xfs_iflags_test(ip, XFS_INEW | XFS_IRECLAIMABLE | XFS_IRECLAIM)) + goto out_unlock_noent; + spin_unlock(&ip->i_flags_lock); + /* nothing to sync during shutdown */ if (XFS_FORCED_SHUTDOWN(ip->i_mount)) return EFSCORRUPTED; - /* avoid new or reclaimable inodes. Leave for reclaim code to flush */ - if (xfs_iflags_test(ip, XFS_INEW | XFS_IRECLAIMABLE | XFS_IRECLAIM)) - return ENOENT; - /* If we can't grab the inode, it must on it's way to reclaim. */ if (!igrab(inode)) return ENOENT; @@ -72,6 +88,10 @@ xfs_inode_ag_walk_grab( /* inode is valid */ return 0; + +out_unlock_noent: + spin_unlock(&ip->i_flags_lock); + return ENOENT; } STATIC int @@ -98,12 +118,12 @@ restart: int error = 0; int i; - read_lock(&pag->pag_ici_lock); + rcu_read_lock(); nr_found = radix_tree_gang_lookup(&pag->pag_ici_root, (void **)batch, first_index, XFS_LOOKUP_BATCH); if (!nr_found) { - read_unlock(&pag->pag_ici_lock); + rcu_read_unlock(); break; } @@ -118,18 +138,26 @@ restart: batch[i] = NULL; /* - * Update the index for the next lookup. Catch overflows - * into the next AG range which can occur if we have inodes - * in the last block of the AG and we are currently - * pointing to the last inode. + * Update the index for the next lookup. Catch + * overflows into the next AG range which can occur if + * we have inodes in the last block of the AG and we + * are currently pointing to the last inode. + * + * Because we may see inodes that are from the wrong AG + * due to RCU freeing and reallocation, only update the + * index if it lies in this AG. It was a race that lead + * us to see this inode, so another lookup from the + * same index will not find it again. */ + if (XFS_INO_TO_AGNO(mp, ip->i_ino) != pag->pag_agno) + continue; first_index = XFS_INO_TO_AGINO(mp, ip->i_ino + 1); if (first_index < XFS_INO_TO_AGINO(mp, ip->i_ino)) done = 1; } /* unlock now we've grabbed the inodes. */ - read_unlock(&pag->pag_ici_lock); + rcu_read_unlock(); for (i = 0; i < nr_found; i++) { if (!batch[i]) @@ -639,9 +667,14 @@ xfs_reclaim_inode_grab( struct xfs_inode *ip, int flags) { + ASSERT(rcu_read_lock_held()); + + /* quick check for stale RCU freed inode */ + if (!ip->i_ino) + return 1; /* - * do some unlocked checks first to avoid unnecceary lock traffic. + * do some unlocked checks first to avoid unnecessary lock traffic. * The first is a flush lock check, the second is a already in reclaim * check. Only do these checks if we are not going to block on locks. */ @@ -654,11 +687,16 @@ xfs_reclaim_inode_grab( * The radix tree lock here protects a thread in xfs_iget from racing * with us starting reclaim on the inode. Once we have the * XFS_IRECLAIM flag set it will not touch us. + * + * Due to RCU lookup, we may find inodes that have been freed and only + * have XFS_IRECLAIM set. Indeed, we may see reallocated inodes that + * aren't candidates for reclaim at all, so we must check the + * XFS_IRECLAIMABLE is set first before proceeding to reclaim. */ spin_lock(&ip->i_flags_lock); - ASSERT_ALWAYS(__xfs_iflags_test(ip, XFS_IRECLAIMABLE)); - if (__xfs_iflags_test(ip, XFS_IRECLAIM)) { - /* ignore as it is already under reclaim */ + if (!__xfs_iflags_test(ip, XFS_IRECLAIMABLE) || + __xfs_iflags_test(ip, XFS_IRECLAIM)) { + /* not a reclaim candidate. */ spin_unlock(&ip->i_flags_lock); return 1; } @@ -864,14 +902,14 @@ restart: struct xfs_inode *batch[XFS_LOOKUP_BATCH]; int i; - write_lock(&pag->pag_ici_lock); + rcu_read_lock(); nr_found = radix_tree_gang_lookup_tag( &pag->pag_ici_root, (void **)batch, first_index, XFS_LOOKUP_BATCH, XFS_ICI_RECLAIM_TAG); if (!nr_found) { - write_unlock(&pag->pag_ici_lock); + rcu_read_unlock(); break; } @@ -891,14 +929,24 @@ restart: * occur if we have inodes in the last block of * the AG and we are currently pointing to the * last inode. + * + * Because we may see inodes that are from the + * wrong AG due to RCU freeing and + * reallocation, only update the index if it + * lies in this AG. It was a race that lead us + * to see this inode, so another lookup from + * the same index will not find it again. */ + if (XFS_INO_TO_AGNO(mp, ip->i_ino) != + pag->pag_agno) + continue; first_index = XFS_INO_TO_AGINO(mp, ip->i_ino + 1); if (first_index < XFS_INO_TO_AGINO(mp, ip->i_ino)) done = 1; } /* unlock now we've grabbed the inodes. */ - write_unlock(&pag->pag_ici_lock); + rcu_read_unlock(); for (i = 0; i < nr_found; i++) { if (!batch[i]) diff --git a/fs/xfs/xfs_iget.c b/fs/xfs/xfs_iget.c index 9fae47556604..04ed09b907b8 100644 --- a/fs/xfs/xfs_iget.c +++ b/fs/xfs/xfs_iget.c @@ -80,6 +80,7 @@ xfs_inode_alloc( ASSERT(atomic_read(&ip->i_pincount) == 0); ASSERT(!spin_is_locked(&ip->i_flags_lock)); ASSERT(completion_done(&ip->i_flush)); + ASSERT(ip->i_ino == 0); mrlock_init(&ip->i_iolock, MRLOCK_BARRIER, "xfsio", ip->i_ino); lockdep_set_class_and_name(&ip->i_iolock.mr_lock, @@ -98,9 +99,6 @@ xfs_inode_alloc( ip->i_size = 0; ip->i_new_size = 0; - /* prevent anyone from using this yet */ - VFS_I(ip)->i_state = I_NEW; - return ip; } @@ -159,6 +157,16 @@ xfs_inode_free( ASSERT(!spin_is_locked(&ip->i_flags_lock)); ASSERT(completion_done(&ip->i_flush)); + /* + * Because we use RCU freeing we need to ensure the inode always + * appears to be reclaimed with an invalid inode number when in the + * free state. The ip->i_flags_lock provides the barrier against lookup + * races. + */ + spin_lock(&ip->i_flags_lock); + ip->i_flags = XFS_IRECLAIM; + ip->i_ino = 0; + spin_unlock(&ip->i_flags_lock); call_rcu((struct rcu_head *)&VFS_I(ip)->i_dentry, __xfs_inode_free); } @@ -169,14 +177,29 @@ static int xfs_iget_cache_hit( struct xfs_perag *pag, struct xfs_inode *ip, + xfs_ino_t ino, int flags, - int lock_flags) __releases(pag->pag_ici_lock) + int lock_flags) __releases(RCU) { struct inode *inode = VFS_I(ip); struct xfs_mount *mp = ip->i_mount; int error; + /* + * check for re-use of an inode within an RCU grace period due to the + * radix tree nodes not being updated yet. We monitor for this by + * setting the inode number to zero before freeing the inode structure. + * If the inode has been reallocated and set up, then the inode number + * will not match, so check for that, too. + */ spin_lock(&ip->i_flags_lock); + if (ip->i_ino != ino) { + trace_xfs_iget_skip(ip); + XFS_STATS_INC(xs_ig_frecycle); + error = EAGAIN; + goto out_error; + } + /* * If we are racing with another cache hit that is currently @@ -219,7 +242,7 @@ xfs_iget_cache_hit( ip->i_flags |= XFS_IRECLAIM; spin_unlock(&ip->i_flags_lock); - read_unlock(&pag->pag_ici_lock); + rcu_read_unlock(); error = -inode_init_always(mp->m_super, inode); if (error) { @@ -227,7 +250,7 @@ xfs_iget_cache_hit( * Re-initializing the inode failed, and we are in deep * trouble. Try to re-add it to the reclaim list. */ - read_lock(&pag->pag_ici_lock); + rcu_read_lock(); spin_lock(&ip->i_flags_lock); ip->i_flags &= ~XFS_INEW; @@ -261,7 +284,7 @@ xfs_iget_cache_hit( /* We've got a live one. */ spin_unlock(&ip->i_flags_lock); - read_unlock(&pag->pag_ici_lock); + rcu_read_unlock(); trace_xfs_iget_hit(ip); } @@ -275,7 +298,7 @@ xfs_iget_cache_hit( out_error: spin_unlock(&ip->i_flags_lock); - read_unlock(&pag->pag_ici_lock); + rcu_read_unlock(); return error; } @@ -397,7 +420,7 @@ xfs_iget( xfs_agino_t agino; /* reject inode numbers outside existing AGs */ - if (XFS_INO_TO_AGNO(mp, ino) >= mp->m_sb.sb_agcount) + if (!ino || XFS_INO_TO_AGNO(mp, ino) >= mp->m_sb.sb_agcount) return EINVAL; /* get the perag structure and ensure that it's inode capable */ @@ -406,15 +429,15 @@ xfs_iget( again: error = 0; - read_lock(&pag->pag_ici_lock); + rcu_read_lock(); ip = radix_tree_lookup(&pag->pag_ici_root, agino); if (ip) { - error = xfs_iget_cache_hit(pag, ip, flags, lock_flags); + error = xfs_iget_cache_hit(pag, ip, ino, flags, lock_flags); if (error) goto out_error_or_again; } else { - read_unlock(&pag->pag_ici_lock); + rcu_read_unlock(); XFS_STATS_INC(xs_ig_missed); error = xfs_iget_cache_miss(mp, pag, tp, ino, &ip, diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index 108c7a085f94..43ffd9079106 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -2000,16 +2000,32 @@ xfs_ifree_cluster( */ for (i = 0; i < ninodes; i++) { retry: - read_lock(&pag->pag_ici_lock); + rcu_read_lock(); ip = radix_tree_lookup(&pag->pag_ici_root, XFS_INO_TO_AGINO(mp, (inum + i))); - /* Inode not in memory or stale, nothing to do */ - if (!ip || xfs_iflags_test(ip, XFS_ISTALE)) { - read_unlock(&pag->pag_ici_lock); + /* Inode not in memory, nothing to do */ + if (!ip) { + rcu_read_unlock(); continue; } + /* + * because this is an RCU protected lookup, we could + * find a recently freed or even reallocated inode + * during the lookup. We need to check under the + * i_flags_lock for a valid inode here. Skip it if it + * is not valid, the wrong inode or stale. + */ + spin_lock(&ip->i_flags_lock); + if (ip->i_ino != inum + i || + __xfs_iflags_test(ip, XFS_ISTALE)) { + spin_unlock(&ip->i_flags_lock); + rcu_read_unlock(); + continue; + } + spin_unlock(&ip->i_flags_lock); + /* * Don't try to lock/unlock the current inode, but we * _cannot_ skip the other inodes that we did not find @@ -2019,11 +2035,11 @@ retry: */ if (ip != free_ip && !xfs_ilock_nowait(ip, XFS_ILOCK_EXCL)) { - read_unlock(&pag->pag_ici_lock); + rcu_read_unlock(); delay(1); goto retry; } - read_unlock(&pag->pag_ici_lock); + rcu_read_unlock(); xfs_iflock(ip); xfs_iflags_set(ip, XFS_ISTALE); @@ -2629,7 +2645,7 @@ xfs_iflush_cluster( mask = ~(((XFS_INODE_CLUSTER_SIZE(mp) >> mp->m_sb.sb_inodelog)) - 1); first_index = XFS_INO_TO_AGINO(mp, ip->i_ino) & mask; - read_lock(&pag->pag_ici_lock); + rcu_read_lock(); /* really need a gang lookup range call here */ nr_found = radix_tree_gang_lookup(&pag->pag_ici_root, (void**)ilist, first_index, inodes_per_cluster); @@ -2640,9 +2656,21 @@ xfs_iflush_cluster( iq = ilist[i]; if (iq == ip) continue; - /* if the inode lies outside this cluster, we're done. */ - if ((XFS_INO_TO_AGINO(mp, iq->i_ino) & mask) != first_index) - break; + + /* + * because this is an RCU protected lookup, we could find a + * recently freed or even reallocated inode during the lookup. + * We need to check under the i_flags_lock for a valid inode + * here. Skip it if it is not valid or the wrong inode. + */ + spin_lock(&ip->i_flags_lock); + if (!ip->i_ino || + (XFS_INO_TO_AGINO(mp, iq->i_ino) & mask) != first_index) { + spin_unlock(&ip->i_flags_lock); + continue; + } + spin_unlock(&ip->i_flags_lock); + /* * Do an un-protected check to see if the inode is dirty and * is a candidate for flushing. These checks will be repeated @@ -2692,7 +2720,7 @@ xfs_iflush_cluster( } out_free: - read_unlock(&pag->pag_ici_lock); + rcu_read_unlock(); kmem_free(ilist); out_put: xfs_perag_put(pag); @@ -2704,7 +2732,7 @@ cluster_corrupt_out: * Corruption detected in the clustering loop. Invalidate the * inode buffer and shut down the filesystem. */ - read_unlock(&pag->pag_ici_lock); + rcu_read_unlock(); /* * Clean up the buffer. If it was B_DELWRI, just release it -- * brelse can handle it with no problems. If not, shut down the -- cgit v1.2.3 From 1a427ab0c1b205d1bda8da0b77ea9d295ac23c57 Mon Sep 17 00:00:00 2001 From: Dave Chinner Date: Thu, 16 Dec 2010 17:08:41 +1100 Subject: xfs: convert pag_ici_lock to a spin lock now that we are using RCU protection for the inode cache lookups, the lock is only needed on the modification side. Hence it is not necessary for the lock to be a rwlock as there are no read side holders anymore. Convert it to a spin lock to reflect it's exclusive nature. Signed-off-by: Dave Chinner Reviewed-by: Alex Elder Reviewed-by: Christoph Hellwig --- fs/xfs/linux-2.6/xfs_sync.c | 8 ++++---- fs/xfs/xfs_ag.h | 2 +- fs/xfs/xfs_iget.c | 10 +++++----- fs/xfs/xfs_mount.c | 2 +- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/fs/xfs/linux-2.6/xfs_sync.c b/fs/xfs/linux-2.6/xfs_sync.c index fd38682da851..a02480de9759 100644 --- a/fs/xfs/linux-2.6/xfs_sync.c +++ b/fs/xfs/linux-2.6/xfs_sync.c @@ -620,12 +620,12 @@ xfs_inode_set_reclaim_tag( struct xfs_perag *pag; pag = xfs_perag_get(mp, XFS_INO_TO_AGNO(mp, ip->i_ino)); - write_lock(&pag->pag_ici_lock); + spin_lock(&pag->pag_ici_lock); spin_lock(&ip->i_flags_lock); __xfs_inode_set_reclaim_tag(pag, ip); __xfs_iflags_set(ip, XFS_IRECLAIMABLE); spin_unlock(&ip->i_flags_lock); - write_unlock(&pag->pag_ici_lock); + spin_unlock(&pag->pag_ici_lock); xfs_perag_put(pag); } @@ -833,12 +833,12 @@ reclaim: * added to the tree assert that it's been there before to catch * problems with the inode life time early on. */ - write_lock(&pag->pag_ici_lock); + spin_lock(&pag->pag_ici_lock); if (!radix_tree_delete(&pag->pag_ici_root, XFS_INO_TO_AGINO(ip->i_mount, ip->i_ino))) ASSERT(0); __xfs_inode_clear_reclaim(pag, ip); - write_unlock(&pag->pag_ici_lock); + spin_unlock(&pag->pag_ici_lock); /* * Here we do an (almost) spurious inode lock in order to coordinate diff --git a/fs/xfs/xfs_ag.h b/fs/xfs/xfs_ag.h index 63c7a1a6c022..58632cc17f2d 100644 --- a/fs/xfs/xfs_ag.h +++ b/fs/xfs/xfs_ag.h @@ -227,7 +227,7 @@ typedef struct xfs_perag { atomic_t pagf_fstrms; /* # of filestreams active in this AG */ - rwlock_t pag_ici_lock; /* incore inode lock */ + spinlock_t pag_ici_lock; /* incore inode cache lock */ struct radix_tree_root pag_ici_root; /* incore inode cache root */ int pag_ici_reclaimable; /* reclaimable inodes */ struct mutex pag_ici_reclaim_lock; /* serialisation point */ diff --git a/fs/xfs/xfs_iget.c b/fs/xfs/xfs_iget.c index 04ed09b907b8..3ecad00e8409 100644 --- a/fs/xfs/xfs_iget.c +++ b/fs/xfs/xfs_iget.c @@ -260,7 +260,7 @@ xfs_iget_cache_hit( goto out_error; } - write_lock(&pag->pag_ici_lock); + spin_lock(&pag->pag_ici_lock); spin_lock(&ip->i_flags_lock); ip->i_flags &= ~(XFS_IRECLAIMABLE | XFS_IRECLAIM); ip->i_flags |= XFS_INEW; @@ -273,7 +273,7 @@ xfs_iget_cache_hit( &xfs_iolock_active, "xfs_iolock_active"); spin_unlock(&ip->i_flags_lock); - write_unlock(&pag->pag_ici_lock); + spin_unlock(&pag->pag_ici_lock); } else { /* If the VFS inode is being torn down, pause and try again. */ if (!igrab(inode)) { @@ -351,7 +351,7 @@ xfs_iget_cache_miss( BUG(); } - write_lock(&pag->pag_ici_lock); + spin_lock(&pag->pag_ici_lock); /* insert the new inode */ error = radix_tree_insert(&pag->pag_ici_root, agino, ip); @@ -366,14 +366,14 @@ xfs_iget_cache_miss( ip->i_udquot = ip->i_gdquot = NULL; xfs_iflags_set(ip, XFS_INEW); - write_unlock(&pag->pag_ici_lock); + spin_unlock(&pag->pag_ici_lock); radix_tree_preload_end(); *ipp = ip; return 0; out_preload_end: - write_unlock(&pag->pag_ici_lock); + spin_unlock(&pag->pag_ici_lock); radix_tree_preload_end(); if (lock_flags) xfs_iunlock(ip, lock_flags); diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c index 40579fdf0d0a..d447aef84bc3 100644 --- a/fs/xfs/xfs_mount.c +++ b/fs/xfs/xfs_mount.c @@ -472,7 +472,7 @@ xfs_initialize_perag( goto out_unwind; pag->pag_agno = index; pag->pag_mount = mp; - rwlock_init(&pag->pag_ici_lock); + spin_lock_init(&pag->pag_ici_lock); mutex_init(&pag->pag_ici_reclaim_lock); INIT_RADIX_TREE(&pag->pag_ici_root, GFP_ATOMIC); spin_lock_init(&pag->pag_buf_lock); -- cgit v1.2.3 From ff57ab21995a8636cfc72efeebb09cc6034d756f Mon Sep 17 00:00:00 2001 From: Dave Chinner Date: Tue, 30 Nov 2010 17:27:57 +1100 Subject: xfs: convert xfsbud shrinker to a per-buftarg shrinker. Before we introduce per-buftarg LRU lists, split the shrinker implementation into per-buftarg shrinker callbacks. At the moment we wake all the xfsbufds to run the delayed write queues to free the dirty buffers and make their pages available for reclaim. However, with an LRU, we want to be able to free clean, unused buffers as well, so we need to separate the xfsbufd from the shrinker callbacks. Signed-off-by: Dave Chinner Reviewed-by: Christoph Hellwig Reviewed-by: Alex Elder --- fs/xfs/linux-2.6/xfs_buf.c | 89 +++++++++++++--------------------------------- fs/xfs/linux-2.6/xfs_buf.h | 4 ++- 2 files changed, 27 insertions(+), 66 deletions(-) diff --git a/fs/xfs/linux-2.6/xfs_buf.c b/fs/xfs/linux-2.6/xfs_buf.c index 4c5deb6e9e31..0a00d7a2fc23 100644 --- a/fs/xfs/linux-2.6/xfs_buf.c +++ b/fs/xfs/linux-2.6/xfs_buf.c @@ -44,12 +44,7 @@ static kmem_zone_t *xfs_buf_zone; STATIC int xfsbufd(void *); -STATIC int xfsbufd_wakeup(struct shrinker *, int, gfp_t); STATIC void xfs_buf_delwri_queue(xfs_buf_t *, int); -static struct shrinker xfs_buf_shake = { - .shrink = xfsbufd_wakeup, - .seeks = DEFAULT_SEEKS, -}; static struct workqueue_struct *xfslogd_workqueue; struct workqueue_struct *xfsdatad_workqueue; @@ -337,7 +332,6 @@ _xfs_buf_lookup_pages( __func__, gfp_mask); XFS_STATS_INC(xb_page_retries); - xfsbufd_wakeup(NULL, 0, gfp_mask); congestion_wait(BLK_RW_ASYNC, HZ/50); goto retry; } @@ -1461,28 +1455,23 @@ xfs_wait_buftarg( } } -/* - * buftarg list for delwrite queue processing - */ -static LIST_HEAD(xfs_buftarg_list); -static DEFINE_SPINLOCK(xfs_buftarg_lock); - -STATIC void -xfs_register_buftarg( - xfs_buftarg_t *btp) -{ - spin_lock(&xfs_buftarg_lock); - list_add(&btp->bt_list, &xfs_buftarg_list); - spin_unlock(&xfs_buftarg_lock); -} - -STATIC void -xfs_unregister_buftarg( - xfs_buftarg_t *btp) +int +xfs_buftarg_shrink( + struct shrinker *shrink, + int nr_to_scan, + gfp_t mask) { - spin_lock(&xfs_buftarg_lock); - list_del(&btp->bt_list); - spin_unlock(&xfs_buftarg_lock); + struct xfs_buftarg *btp = container_of(shrink, + struct xfs_buftarg, bt_shrinker); + if (nr_to_scan) { + if (test_bit(XBT_FORCE_SLEEP, &btp->bt_flags)) + return -1; + if (list_empty(&btp->bt_delwrite_queue)) + return -1; + set_bit(XBT_FORCE_FLUSH, &btp->bt_flags); + wake_up_process(btp->bt_task); + } + return list_empty(&btp->bt_delwrite_queue) ? -1 : 1; } void @@ -1490,17 +1479,14 @@ xfs_free_buftarg( struct xfs_mount *mp, struct xfs_buftarg *btp) { + unregister_shrinker(&btp->bt_shrinker); + xfs_flush_buftarg(btp, 1); if (mp->m_flags & XFS_MOUNT_BARRIER) xfs_blkdev_issue_flush(btp); iput(btp->bt_mapping->host); - /* Unregister the buftarg first so that we don't get a - * wakeup finding a non-existent task - */ - xfs_unregister_buftarg(btp); kthread_stop(btp->bt_task); - kmem_free(btp); } @@ -1597,20 +1583,13 @@ xfs_alloc_delwrite_queue( xfs_buftarg_t *btp, const char *fsname) { - int error = 0; - - INIT_LIST_HEAD(&btp->bt_list); INIT_LIST_HEAD(&btp->bt_delwrite_queue); spin_lock_init(&btp->bt_delwrite_lock); btp->bt_flags = 0; btp->bt_task = kthread_run(xfsbufd, btp, "xfsbufd/%s", fsname); - if (IS_ERR(btp->bt_task)) { - error = PTR_ERR(btp->bt_task); - goto out_error; - } - xfs_register_buftarg(btp); -out_error: - return error; + if (IS_ERR(btp->bt_task)) + return PTR_ERR(btp->bt_task); + return 0; } xfs_buftarg_t * @@ -1633,6 +1612,9 @@ xfs_alloc_buftarg( goto error; if (xfs_alloc_delwrite_queue(btp, fsname)) goto error; + btp->bt_shrinker.shrink = xfs_buftarg_shrink; + btp->bt_shrinker.seeks = DEFAULT_SEEKS; + register_shrinker(&btp->bt_shrinker); return btp; error: @@ -1737,27 +1719,6 @@ xfs_buf_runall_queues( flush_workqueue(queue); } -STATIC int -xfsbufd_wakeup( - struct shrinker *shrink, - int priority, - gfp_t mask) -{ - xfs_buftarg_t *btp; - - spin_lock(&xfs_buftarg_lock); - list_for_each_entry(btp, &xfs_buftarg_list, bt_list) { - if (test_bit(XBT_FORCE_SLEEP, &btp->bt_flags)) - continue; - if (list_empty(&btp->bt_delwrite_queue)) - continue; - set_bit(XBT_FORCE_FLUSH, &btp->bt_flags); - wake_up_process(btp->bt_task); - } - spin_unlock(&xfs_buftarg_lock); - return 0; -} - /* * Move as many buffers as specified to the supplied list * idicating if we skipped any buffers to prevent deadlocks. @@ -1952,7 +1913,6 @@ xfs_buf_init(void) if (!xfsconvertd_workqueue) goto out_destroy_xfsdatad_workqueue; - register_shrinker(&xfs_buf_shake); return 0; out_destroy_xfsdatad_workqueue: @@ -1968,7 +1928,6 @@ xfs_buf_init(void) void xfs_buf_terminate(void) { - unregister_shrinker(&xfs_buf_shake); destroy_workqueue(xfsconvertd_workqueue); destroy_workqueue(xfsdatad_workqueue); destroy_workqueue(xfslogd_workqueue); diff --git a/fs/xfs/linux-2.6/xfs_buf.h b/fs/xfs/linux-2.6/xfs_buf.h index 383a3f37cf98..9344103e77d6 100644 --- a/fs/xfs/linux-2.6/xfs_buf.h +++ b/fs/xfs/linux-2.6/xfs_buf.h @@ -128,10 +128,12 @@ typedef struct xfs_buftarg { /* per device delwri queue */ struct task_struct *bt_task; - struct list_head bt_list; struct list_head bt_delwrite_queue; spinlock_t bt_delwrite_lock; unsigned long bt_flags; + + /* LRU control structures */ + struct shrinker bt_shrinker; } xfs_buftarg_t; /* -- cgit v1.2.3 From 0f6bb83cb12e4617e696ffa566f3fc6c092686e2 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Tue, 30 Nov 2010 16:49:02 +0800 Subject: crypto: algif_skcipher - Fixed overflow when sndbuf is page aligned When sk_sndbuf is not a multiple of PAGE_SIZE, the limit tests in sendmsg fail as the limit variable becomes negative and we're using an unsigned comparison. The same thing can happen if sk_sndbuf is lowered after a sendmsg call. This patch fixes this by always taking the signed maximum of limit and 0 before we perform the comparison. It also rounds the value of sk_sndbuf down to a multiple of PAGE_SIZE so that we don't end up allocating a page only to use a small number of bytes in it because we're bound by sk_sndbuf. Signed-off-by: Herbert Xu --- crypto/algif_skcipher.c | 32 +++++++++++--------------------- 1 file changed, 11 insertions(+), 21 deletions(-) diff --git a/crypto/algif_skcipher.c b/crypto/algif_skcipher.c index 9b2f440e88a6..1f33480e3260 100644 --- a/crypto/algif_skcipher.c +++ b/crypto/algif_skcipher.c @@ -52,12 +52,18 @@ struct skcipher_ctx { #define MAX_SGL_ENTS ((PAGE_SIZE - sizeof(struct skcipher_sg_list)) / \ sizeof(struct scatterlist) - 1) -static inline bool skcipher_writable(struct sock *sk) +static inline int skcipher_sndbuf(struct sock *sk) { struct alg_sock *ask = alg_sk(sk); struct skcipher_ctx *ctx = ask->private; - return ctx->used + PAGE_SIZE <= max_t(int, sk->sk_sndbuf, PAGE_SIZE); + return max_t(int, max_t(int, sk->sk_sndbuf & PAGE_MASK, PAGE_SIZE) - + ctx->used, 0); +} + +static inline bool skcipher_writable(struct sock *sk) +{ + return PAGE_SIZE <= skcipher_sndbuf(sk); } static int skcipher_alloc_sgl(struct sock *sk) @@ -245,7 +251,6 @@ static int skcipher_sendmsg(struct kiocb *unused, struct socket *sock, struct af_alg_control con = {}; long copied = 0; bool enc = 0; - int limit; int err; int i; @@ -281,9 +286,6 @@ static int skcipher_sendmsg(struct kiocb *unused, struct socket *sock, memcpy(ctx->iv, con.iv->iv, ivsize); } - limit = max_t(int, sk->sk_sndbuf, PAGE_SIZE); - limit -= ctx->used; - while (size) { struct scatterlist *sg; unsigned long len = size; @@ -309,20 +311,16 @@ static int skcipher_sendmsg(struct kiocb *unused, struct socket *sock, ctx->used += len; copied += len; size -= len; - limit -= len; continue; } - if (limit < PAGE_SIZE) { + if (!skcipher_writable(sk)) { err = skcipher_wait_for_wmem(sk, msg->msg_flags); if (err) goto unlock; - - limit = max_t(int, sk->sk_sndbuf, PAGE_SIZE); - limit -= ctx->used; } - len = min_t(unsigned long, len, limit); + len = min_t(unsigned long, len, skcipher_sndbuf(sk)); err = skcipher_alloc_sgl(sk); if (err) @@ -352,7 +350,6 @@ static int skcipher_sendmsg(struct kiocb *unused, struct socket *sock, ctx->used += plen; copied += plen; size -= plen; - limit -= plen; sgl->cur++; } while (len && sgl->cur < MAX_SGL_ENTS); @@ -380,7 +377,6 @@ static ssize_t skcipher_sendpage(struct socket *sock, struct page *page, struct skcipher_ctx *ctx = ask->private; struct skcipher_sg_list *sgl; int err = -EINVAL; - int limit; lock_sock(sk); if (!ctx->more && ctx->used) @@ -389,16 +385,10 @@ static ssize_t skcipher_sendpage(struct socket *sock, struct page *page, if (!size) goto done; - limit = max_t(int, sk->sk_sndbuf, PAGE_SIZE); - limit -= ctx->used; - - if (limit < PAGE_SIZE) { + if (!skcipher_writable(sk)) { err = skcipher_wait_for_wmem(sk, flags); if (err) goto unlock; - - limit = max_t(int, sk->sk_sndbuf, PAGE_SIZE); - limit -= ctx->used; } err = skcipher_alloc_sgl(sk); -- cgit v1.2.3 From bc97e57eb21f8db55bf0e1f182d384e75b2e3c99 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Tue, 30 Nov 2010 17:04:31 +0800 Subject: crypto: algif_skcipher - Handle unaligned receive buffer As it is if user-space passes through a receive buffer that's not aligned to to the cipher block size, we'll end up encrypting or decrypting a partial block which causes a spurious EINVAL to be returned. This patch fixes this by moving the partial block test after the af_alg_make_sg call. Signed-off-by: Herbert Xu --- crypto/algif_skcipher.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/crypto/algif_skcipher.c b/crypto/algif_skcipher.c index 1f33480e3260..6a6dfc062d2a 100644 --- a/crypto/algif_skcipher.c +++ b/crypto/algif_skcipher.c @@ -454,17 +454,17 @@ static int skcipher_recvmsg(struct kiocb *unused, struct socket *sock, used = min_t(unsigned long, used, seglen); + used = af_alg_make_sg(&ctx->rsgl, from, used, 1); + err = used; + if (err < 0) + goto unlock; + if (ctx->more || used < ctx->used) used -= used % bs; err = -EINVAL; if (!used) - goto unlock; - - used = af_alg_make_sg(&ctx->rsgl, from, used, 1); - err = used; - if (err < 0) - goto unlock; + goto free; ablkcipher_request_set_crypt(&ctx->req, sg, ctx->rsgl.sg, used, @@ -476,6 +476,7 @@ static int skcipher_recvmsg(struct kiocb *unused, struct socket *sock, crypto_ablkcipher_decrypt(&ctx->req), &ctx->completion); +free: af_alg_free_sg(&ctx->rsgl); if (err) -- cgit v1.2.3 From c8d6bf9a7b282255cd155b676ff91b08266b8529 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Tue, 30 Nov 2010 11:32:04 +0900 Subject: ASoC: sh: fsi-ak4642: Add FSI port and ak464x selection Current FSI-Ak4642 device had niche settings which were FSI2-A-AK4643 and FSI-A-AK4642. This patch add platform_device_id which can control FSI/FSI2, PortA/PortB, AK4642/AK4643 from platform data. Signed-off-by: Kuninori Morimoto Acked-by: Paul Mundt Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- arch/arm/mach-shmobile/board-ap4evb.c | 5 ++ arch/sh/boards/mach-se/7724/setup.c | 5 ++ sound/soc/sh/fsi-ak4642.c | 133 +++++++++++++++++++++++++++++++--- 3 files changed, 131 insertions(+), 12 deletions(-) diff --git a/arch/arm/mach-shmobile/board-ap4evb.c b/arch/arm/mach-shmobile/board-ap4evb.c index d3260542b943..82c3204af899 100644 --- a/arch/arm/mach-shmobile/board-ap4evb.c +++ b/arch/arm/mach-shmobile/board-ap4evb.c @@ -640,6 +640,10 @@ static struct platform_device fsi_device = { }, }; +static struct platform_device fsi_ak4643_device = { + .name = "sh_fsi2_a_ak4643", +}; + static struct sh_mobile_lcdc_info sh_mobile_lcdc1_info = { .clock_source = LCDC_CLK_EXTERNAL, .ch[0] = { @@ -838,6 +842,7 @@ static struct platform_device *ap4evb_devices[] __initdata = { &sdhi1_device, &usb1_host_device, &fsi_device, + &fsi_ak4643_device, &sh_mmcif_device, &lcdc1_device, &lcdc_device, diff --git a/arch/sh/boards/mach-se/7724/setup.c b/arch/sh/boards/mach-se/7724/setup.c index c31d228fdfc6..dff89d0fa20f 100644 --- a/arch/sh/boards/mach-se/7724/setup.c +++ b/arch/sh/boards/mach-se/7724/setup.c @@ -343,6 +343,10 @@ static struct platform_device fsi_device = { }, }; +static struct platform_device fsi_ak4642_device = { + .name = "sh_fsi_a_ak4642", +}; + /* KEYSC in SoC (Needs SW33-2 set to ON) */ static struct sh_keysc_info keysc_info = { .mode = SH_KEYSC_MODE_1, @@ -615,6 +619,7 @@ static struct platform_device *ms7724se_devices[] __initdata = { &sh7724_usb0_host_device, &sh7724_usb1_gadget_device, &fsi_device, + &fsi_ak4642_device, &sdhi0_cn7_device, &sdhi1_cn8_device, &irda_device, diff --git a/sound/soc/sh/fsi-ak4642.c b/sound/soc/sh/fsi-ak4642.c index d96602de71de..4ef279c504db 100644 --- a/sound/soc/sh/fsi-ak4642.c +++ b/sound/soc/sh/fsi-ak4642.c @@ -12,6 +12,13 @@ #include #include +struct fsi_ak4642_data { + const char *name; + const char *cpu_dai; + const char *codec; + const char *platform; +}; + static int fsi_ak4642_dai_init(struct snd_soc_pcm_runtime *rtd) { struct snd_soc_dai *dai = rtd->codec_dai; @@ -27,17 +34,12 @@ static int fsi_ak4642_dai_init(struct snd_soc_pcm_runtime *rtd) } static struct snd_soc_dai_link fsi_dai_link = { - .name = "AK4642", - .stream_name = "AK4642", - .cpu_dai_name = "fsia-dai", /* fsi A */ + /* .name */ + /* .stream_name */ + /* .cpu_dai_name */ .codec_dai_name = "ak4642-hifi", -#ifdef CONFIG_MACH_AP4EVB - .platform_name = "sh_fsi2", - .codec_name = "ak4642-codec.0-0013", -#else - .platform_name = "sh_fsi.0", - .codec_name = "ak4642-codec.0-0012", -#endif + /* .platform_name */ + /* .codec_name */ .init = fsi_ak4642_dai_init, .ops = NULL, }; @@ -50,14 +52,30 @@ static struct snd_soc_card fsi_soc_card = { static struct platform_device *fsi_snd_device; -static int __init fsi_ak4642_init(void) +static int fsi_ak4642_probe(struct platform_device *pdev) { int ret = -ENOMEM; + const struct platform_device_id *id_entry; + struct fsi_ak4642_data *pdata; + + id_entry = pdev->id_entry; + if (!id_entry) { + dev_err(&pdev->dev, "unknown fsi ak4642\n"); + return -ENODEV; + } + + pdata = (struct fsi_ak4642_data *)id_entry->driver_data; fsi_snd_device = platform_device_alloc("soc-audio", FSI_PORT_A); if (!fsi_snd_device) goto out; + fsi_dai_link.name = pdata->name; + fsi_dai_link.stream_name = pdata->name; + fsi_dai_link.cpu_dai_name = pdata->cpu_dai; + fsi_dai_link.platform_name = pdata->platform; + fsi_dai_link.codec_name = pdata->codec; + platform_set_drvdata(fsi_snd_device, &fsi_soc_card); ret = platform_device_add(fsi_snd_device); @@ -68,9 +86,100 @@ out: return ret; } -static void __exit fsi_ak4642_exit(void) +static int fsi_ak4642_remove(struct platform_device *pdev) { platform_device_unregister(fsi_snd_device); + return 0; +} + +static struct fsi_ak4642_data fsi_a_ak4642 = { + .name = "AK4642", + .cpu_dai = "fsia-dai", + .codec = "ak4642-codec.0-0012", + .platform = "sh_fsi.0", +}; + +static struct fsi_ak4642_data fsi_b_ak4642 = { + .name = "AK4642", + .cpu_dai = "fsib-dai", + .codec = "ak4642-codec.0-0012", + .platform = "sh_fsi.0", +}; + +static struct fsi_ak4642_data fsi_a_ak4643 = { + .name = "AK4643", + .cpu_dai = "fsia-dai", + .codec = "ak4642-codec.0-0013", + .platform = "sh_fsi.0", +}; + +static struct fsi_ak4642_data fsi_b_ak4643 = { + .name = "AK4643", + .cpu_dai = "fsib-dai", + .codec = "ak4642-codec.0-0013", + .platform = "sh_fsi.0", +}; + +static struct fsi_ak4642_data fsi2_a_ak4642 = { + .name = "AK4642", + .cpu_dai = "fsia-dai", + .codec = "ak4642-codec.0-0012", + .platform = "sh_fsi2", +}; + +static struct fsi_ak4642_data fsi2_b_ak4642 = { + .name = "AK4642", + .cpu_dai = "fsib-dai", + .codec = "ak4642-codec.0-0012", + .platform = "sh_fsi2", +}; + +static struct fsi_ak4642_data fsi2_a_ak4643 = { + .name = "AK4643", + .cpu_dai = "fsia-dai", + .codec = "ak4642-codec.0-0013", + .platform = "sh_fsi2", +}; + +static struct fsi_ak4642_data fsi2_b_ak4643 = { + .name = "AK4643", + .cpu_dai = "fsib-dai", + .codec = "ak4642-codec.0-0013", + .platform = "sh_fsi2", +}; + +static struct platform_device_id fsi_id_table[] = { + /* FSI */ + { "sh_fsi_a_ak4642", (kernel_ulong_t)&fsi_a_ak4642 }, + { "sh_fsi_b_ak4642", (kernel_ulong_t)&fsi_b_ak4642 }, + { "sh_fsi_a_ak4643", (kernel_ulong_t)&fsi_a_ak4643 }, + { "sh_fsi_b_ak4643", (kernel_ulong_t)&fsi_b_ak4643 }, + + /* FSI 2 */ + { "sh_fsi2_a_ak4642", (kernel_ulong_t)&fsi2_a_ak4642 }, + { "sh_fsi2_b_ak4642", (kernel_ulong_t)&fsi2_b_ak4642 }, + { "sh_fsi2_a_ak4643", (kernel_ulong_t)&fsi2_a_ak4643 }, + { "sh_fsi2_b_ak4643", (kernel_ulong_t)&fsi2_b_ak4643 }, + {}, +}; + +static struct platform_driver fsi_ak4642 = { + .driver = { + .name = "fsi-ak4642-audio", + }, + .probe = fsi_ak4642_probe, + .remove = fsi_ak4642_remove, + .id_table = fsi_id_table, +}; + +static int __init fsi_ak4642_init(void) +{ + return platform_driver_register(&fsi_ak4642); +} + +static void __exit fsi_ak4642_exit(void) +{ + platform_driver_unregister(&fsi_ak4642); } module_init(fsi_ak4642_init); -- cgit v1.2.3 From 551102762ebe8bc0aa867d28960d9be97bbe17c1 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Tue, 30 Nov 2010 15:34:11 +0800 Subject: ASoC: Simplify pm860x_probe error handling Simplify pm860x_probe error handling and return actual error code we got. Signed-off-by: Axel Lin Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/codecs/88pm860x-codec.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/sound/soc/codecs/88pm860x-codec.c b/sound/soc/codecs/88pm860x-codec.c index 7e4d88007d4f..08e15dee9182 100644 --- a/sound/soc/codecs/88pm860x-codec.c +++ b/sound/soc/codecs/88pm860x-codec.c @@ -1358,7 +1358,7 @@ static int pm860x_probe(struct snd_soc_codec *codec) pm860x->name[i], pm860x); if (ret < 0) { dev_err(codec->dev, "Failed to request IRQ!\n"); - goto out_irq; + goto out; } } @@ -1369,7 +1369,7 @@ static int pm860x_probe(struct snd_soc_codec *codec) if (ret < 0) { dev_err(codec->dev, "Failed to fill register cache: %d\n", ret); - goto out_codec; + goto out; } snd_soc_add_controls(codec, pm860x_snd_controls, @@ -1379,12 +1379,10 @@ static int pm860x_probe(struct snd_soc_codec *codec) snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); return 0; -out_codec: - i = 3; -out_irq: - for (; i >= 0; i--) +out: + while (--i >= 0) free_irq(pm860x->irq[i], pm860x); - return -EINVAL; + return ret; } static int pm860x_remove(struct snd_soc_codec *codec) -- cgit v1.2.3 From 09c74a9d0b0bedff16d0881db8cc0054a5e34f47 Mon Sep 17 00:00:00 2001 From: Dimitris Papastamos Date: Mon, 29 Nov 2010 11:43:33 +0000 Subject: ASoC: soc-cache: Fix memory overflow in LZO initialization The bitmap_zero() nbits argument was improperly set to reg_size but the underlying buffer was bmp_size long. This caused the memset to zero past the end of the allocated buffer and into the kernel heap causing strange kernel crashes sometimes by overwriting critical kernel structures. Signed-off-by: Dimitris Papastamos Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/soc-cache.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/soc-cache.c b/sound/soc/soc-cache.c index 9b1ba33e6fe9..514398463f7d 100644 --- a/sound/soc/soc-cache.c +++ b/sound/soc/soc-cache.c @@ -1348,7 +1348,7 @@ static int snd_soc_lzo_cache_init(struct snd_soc_codec *codec) ret = -ENOMEM; goto err; } - bitmap_zero(sync_bmp, reg_size); + bitmap_zero(sync_bmp, bmp_size); /* allocate the lzo blocks and initialize them */ for (i = 0; i < blkcount; ++i) { -- cgit v1.2.3 From 70eac33e7ac370dc137cabff7a4ba3094ca25a8c Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 30 Nov 2010 14:07:47 +0000 Subject: drm/i915: Move instruction state invalidation from execbuffer to flush Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/intel_ringbuffer.c | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index b12578558268..7fc55a80be20 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -109,6 +109,10 @@ render_ring_flush(struct intel_ring_buffer *ring, if (invalidate_domains & I915_GEM_DOMAIN_INSTRUCTION) cmd |= MI_EXE_FLUSH; + if (invalidate_domains & I915_GEM_DOMAIN_COMMAND && + (IS_G4X(dev) || IS_GEN5(dev))) + cmd |= MI_INVALIDATE_ISP; + #if WATCH_EXEC DRM_INFO("%s: queue flush %08x to ring\n", __func__, cmd); #endif @@ -583,17 +587,6 @@ render_ring_dispatch_execbuffer(struct intel_ring_buffer *ring, intel_ring_advance(ring); } - if (IS_G4X(dev) || IS_GEN5(dev)) { - if (intel_ring_begin(ring, 2) == 0) { - intel_ring_emit(ring, MI_FLUSH | - MI_NO_WRITE_FLUSH | - MI_INVALIDATE_ISP ); - intel_ring_emit(ring, MI_NOOP); - intel_ring_advance(ring); - } - } - /* XXX breadcrumb */ - return 0; } -- cgit v1.2.3 From c4e7a4146798ce22c229dd21ed31f59f07c4119e Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 30 Nov 2010 14:10:25 +0000 Subject: drm/i915/ringbuffer: Handle cliprects in the caller This makes the various rings more consistent by removing the anomalous handing of the rendering ring execbuffer dispatch. Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_dma.c | 22 ++++---- drivers/gpu/drm/i915/i915_drv.h | 4 +- drivers/gpu/drm/i915/i915_gem_execbuffer.c | 30 +++++++++-- drivers/gpu/drm/i915/intel_ringbuffer.c | 86 ++++++++++-------------------- drivers/gpu/drm/i915/intel_ringbuffer.h | 4 +- 5 files changed, 67 insertions(+), 79 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 7960fd63ecb1..9a22da9b2083 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -352,16 +352,16 @@ static int i915_emit_cmds(struct drm_device * dev, int *buffer, int dwords) int i915_emit_box(struct drm_device *dev, - struct drm_clip_rect *boxes, - int i, int DR1, int DR4) + struct drm_clip_rect *box, + int DR1, int DR4) { struct drm_i915_private *dev_priv = dev->dev_private; - struct drm_clip_rect box = boxes[i]; int ret; - if (box.y2 <= box.y1 || box.x2 <= box.x1 || box.y2 <= 0 || box.x2 <= 0) { + if (box->y2 <= box->y1 || box->x2 <= box->x1 || + box->y2 <= 0 || box->x2 <= 0) { DRM_ERROR("Bad box %d,%d..%d,%d\n", - box.x1, box.y1, box.x2, box.y2); + box->x1, box->y1, box->x2, box->y2); return -EINVAL; } @@ -371,8 +371,8 @@ i915_emit_box(struct drm_device *dev, return ret; OUT_RING(GFX_OP_DRAWRECT_INFO_I965); - OUT_RING((box.x1 & 0xffff) | (box.y1 << 16)); - OUT_RING(((box.x2 - 1) & 0xffff) | ((box.y2 - 1) << 16)); + OUT_RING((box->x1 & 0xffff) | (box->y1 << 16)); + OUT_RING(((box->x2 - 1) & 0xffff) | ((box->y2 - 1) << 16)); OUT_RING(DR4); } else { ret = BEGIN_LP_RING(6); @@ -381,8 +381,8 @@ i915_emit_box(struct drm_device *dev, OUT_RING(GFX_OP_DRAWRECT_INFO); OUT_RING(DR1); - OUT_RING((box.x1 & 0xffff) | (box.y1 << 16)); - OUT_RING(((box.x2 - 1) & 0xffff) | ((box.y2 - 1) << 16)); + OUT_RING((box->x1 & 0xffff) | (box->y1 << 16)); + OUT_RING(((box->x2 - 1) & 0xffff) | ((box->y2 - 1) << 16)); OUT_RING(DR4); OUT_RING(0); } @@ -434,7 +434,7 @@ static int i915_dispatch_cmdbuffer(struct drm_device * dev, for (i = 0; i < count; i++) { if (i < nbox) { - ret = i915_emit_box(dev, cliprects, i, + ret = i915_emit_box(dev, &cliprects[i], cmd->DR1, cmd->DR4); if (ret) return ret; @@ -467,7 +467,7 @@ static int i915_dispatch_batchbuffer(struct drm_device * dev, count = nbox ? nbox : 1; for (i = 0; i < count; i++) { if (i < nbox) { - ret = i915_emit_box(dev, cliprects, i, + ret = i915_emit_box(dev, &cliprects[i], batch->DR1, batch->DR4); if (ret) return ret; diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index e7c4108c94cd..590d8f2d0958 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -966,8 +966,8 @@ extern int i915_driver_device_is_agp(struct drm_device * dev); extern long i915_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg); extern int i915_emit_box(struct drm_device *dev, - struct drm_clip_rect *boxes, - int i, int DR1, int DR4); + struct drm_clip_rect *box, + int DR1, int DR4); extern int i915_reset(struct drm_device *dev, u8 flags); extern unsigned long i915_chipset_val(struct drm_i915_private *dev_priv); extern unsigned long i915_mch_val(struct drm_i915_private *dev_priv); diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index 66c898c8716d..f57536a70a3a 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c @@ -825,6 +825,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, struct drm_i915_gem_object *batch_obj; struct drm_clip_rect *cliprects = NULL; struct intel_ring_buffer *ring; + u32 exec_start, exec_len; int ret, i; if (!i915_gem_check_execbuffer(args)) { @@ -871,6 +872,11 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, } if (args->num_cliprects != 0) { + if (ring != &dev_priv->render_ring) { + DRM_ERROR("clip rectangles are only valid with the render ring\n"); + return -EINVAL; + } + cliprects = kmalloc(args->num_cliprects * sizeof(*cliprects), GFP_KERNEL); if (cliprects == NULL) { @@ -959,11 +965,25 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, if (ret) goto err; - ret = ring->dispatch_execbuffer(ring, - args, cliprects, - batch_obj->gtt_offset); - if (ret) - goto err; + exec_start = batch_obj->gtt_offset + args->batch_start_offset; + exec_len = args->batch_len; + if (cliprects) { + for (i = 0; i < args->num_cliprects; i++) { + ret = i915_emit_box(dev, &cliprects[i], + args->DR1, args->DR4); + if (ret) + goto err; + + ret = ring->dispatch_execbuffer(ring, + exec_start, exec_len); + if (ret) + goto err; + } + } else { + ret = ring->dispatch_execbuffer(ring, exec_start, exec_len); + if (ret) + goto err; + } i915_gem_execbuffer_move_to_active(&objects, ring); i915_gem_execbuffer_retire_commands(dev, file, ring); diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 7fc55a80be20..21871b0766e2 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -508,25 +508,18 @@ ring_status_page_get_seqno(struct intel_ring_buffer *ring) } static int -ring_dispatch_execbuffer(struct intel_ring_buffer *ring, - struct drm_i915_gem_execbuffer2 *exec, - struct drm_clip_rect *cliprects, - uint64_t exec_offset) +ring_dispatch_execbuffer(struct intel_ring_buffer *ring, u32 offset, u32 length) { - uint32_t exec_start; int ret; - exec_start = (uint32_t) exec_offset + exec->batch_start_offset; - ret = intel_ring_begin(ring, 2); if (ret) return ret; intel_ring_emit(ring, - MI_BATCH_BUFFER_START | - (2 << 6) | + MI_BATCH_BUFFER_START | (2 << 6) | MI_BATCH_NON_SECURE_I965); - intel_ring_emit(ring, exec_start); + intel_ring_emit(ring, offset); intel_ring_advance(ring); return 0; @@ -534,58 +527,40 @@ ring_dispatch_execbuffer(struct intel_ring_buffer *ring, static int render_ring_dispatch_execbuffer(struct intel_ring_buffer *ring, - struct drm_i915_gem_execbuffer2 *exec, - struct drm_clip_rect *cliprects, - uint64_t exec_offset) + u32 offset, u32 len) { struct drm_device *dev = ring->dev; drm_i915_private_t *dev_priv = dev->dev_private; - int nbox = exec->num_cliprects; - uint32_t exec_start, exec_len; - int i, count, ret; - - exec_start = (uint32_t) exec_offset + exec->batch_start_offset; - exec_len = (uint32_t) exec->batch_len; + int ret; trace_i915_gem_request_submit(dev, dev_priv->next_seqno + 1); - count = nbox ? nbox : 1; - for (i = 0; i < count; i++) { - if (i < nbox) { - ret = i915_emit_box(dev, cliprects, i, - exec->DR1, exec->DR4); - if (ret) - return ret; - } + if (IS_I830(dev) || IS_845G(dev)) { + ret = intel_ring_begin(ring, 4); + if (ret) + return ret; - if (IS_I830(dev) || IS_845G(dev)) { - ret = intel_ring_begin(ring, 4); - if (ret) - return ret; + intel_ring_emit(ring, MI_BATCH_BUFFER); + intel_ring_emit(ring, offset | MI_BATCH_NON_SECURE); + intel_ring_emit(ring, offset + len - 8); + intel_ring_emit(ring, 0); + } else { + ret = intel_ring_begin(ring, 2); + if (ret) + return ret; - intel_ring_emit(ring, MI_BATCH_BUFFER); - intel_ring_emit(ring, exec_start | MI_BATCH_NON_SECURE); - intel_ring_emit(ring, exec_start + exec_len - 4); - intel_ring_emit(ring, 0); + if (INTEL_INFO(dev)->gen >= 4) { + intel_ring_emit(ring, + MI_BATCH_BUFFER_START | (2 << 6) | + MI_BATCH_NON_SECURE_I965); + intel_ring_emit(ring, offset); } else { - ret = intel_ring_begin(ring, 2); - if (ret) - return ret; - - if (INTEL_INFO(dev)->gen >= 4) { - intel_ring_emit(ring, - MI_BATCH_BUFFER_START | (2 << 6) - | MI_BATCH_NON_SECURE_I965); - intel_ring_emit(ring, exec_start); - } else { - intel_ring_emit(ring, MI_BATCH_BUFFER_START - | (2 << 6)); - intel_ring_emit(ring, exec_start | - MI_BATCH_NON_SECURE); - } + intel_ring_emit(ring, + MI_BATCH_BUFFER_START | (2 << 6)); + intel_ring_emit(ring, offset | MI_BATCH_NON_SECURE); } - intel_ring_advance(ring); } + intel_ring_advance(ring); return 0; } @@ -904,22 +879,17 @@ static void gen6_ring_flush(struct intel_ring_buffer *ring, static int gen6_ring_dispatch_execbuffer(struct intel_ring_buffer *ring, - struct drm_i915_gem_execbuffer2 *exec, - struct drm_clip_rect *cliprects, - uint64_t exec_offset) + u32 offset, u32 len) { - uint32_t exec_start; int ret; - exec_start = (uint32_t) exec_offset + exec->batch_start_offset; - ret = intel_ring_begin(ring, 2); if (ret) return ret; intel_ring_emit(ring, MI_BATCH_BUFFER_START | MI_BATCH_NON_SECURE_I965); /* bit0-7 is the length on GEN6+ */ - intel_ring_emit(ring, exec_start); + intel_ring_emit(ring, offset); intel_ring_advance(ring); return 0; diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index 1747e329ee94..8e3526777926 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -57,9 +57,7 @@ struct intel_ring_buffer { u32 *seqno); u32 (*get_seqno)(struct intel_ring_buffer *ring); int (*dispatch_execbuffer)(struct intel_ring_buffer *ring, - struct drm_i915_gem_execbuffer2 *exec, - struct drm_clip_rect *cliprects, - uint64_t exec_offset); + u32 offset, u32 length); void (*cleanup)(struct intel_ring_buffer *ring); /** -- cgit v1.2.3 From 2eea392d0a28a0a07d36a9da544eb40f81bf4cb6 Mon Sep 17 00:00:00 2001 From: Jarkko Nikula Date: Thu, 25 Nov 2010 17:47:38 +0200 Subject: ASoC: Add support for optional auxiliary dailess codecs This makes possible to register auxiliary dailess codecs in a machine driver. Term dailess is used here for amplifiers and codecs without DAI or DAI being unused. Dailess auxiliary codecs are kept in struct snd_soc_aux_dev and those codecs are probed after initializing the DAI links. There are no major differences between DAI link codecs and dailess codecs in ASoC core point of view. DAPM handles them equally and sysfs and debugfs directories for dailess codecs are similar except the pmdown_time node is not created. Only suspend and resume functions are modified to traverse all probed codecs instead of DAI link codecs. Example below shows a dailess codec registration. struct snd_soc_aux_dev foo_aux_dev[] = { { .name = "Amp", .codec_name = "codec.2", .init = foo_init2, }, }; static struct snd_soc_card card = { ... .aux_dev = foo_aux_dev, .num_aux_devs = ARRAY_SIZE(foo_aux_dev), }; Signed-off-by: Jarkko Nikula Signed-off-by: Mark Brown --- include/sound/soc.h | 17 ++++++ sound/soc/soc-core.c | 155 +++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 166 insertions(+), 6 deletions(-) diff --git a/include/sound/soc.h b/include/sound/soc.h index 9e593cf1440b..4a9195c5ef2d 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -583,6 +583,14 @@ struct snd_soc_prefix_map { const char *name_prefix; }; +struct snd_soc_aux_dev { + const char *name; /* Codec name */ + const char *codec_name; /* for multi-codec */ + + /* codec/machine specific init - e.g. add machine controls */ + int (*init)(struct snd_soc_dapm_context *dapm); +}; + /* SoC card */ struct snd_soc_card { const char *name; @@ -624,6 +632,15 @@ struct snd_soc_card { struct snd_soc_prefix_map *prefix_map; int num_prefixes; + /* + * optional auxiliary devices such as amplifiers or codecs with DAI + * link unused + */ + struct snd_soc_aux_dev *aux_dev; + int num_aux_devs; + struct snd_soc_pcm_runtime *rtd_aux; + int num_aux_rtd; + struct work_struct deferred_resume_work; /* lists of probed devices belonging to this card */ diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index c8d8dde7f4dd..a7670d5ac13d 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -986,6 +986,7 @@ static int soc_suspend(struct device *dev) { struct platform_device *pdev = to_platform_device(dev); struct snd_soc_card *card = platform_get_drvdata(pdev); + struct snd_soc_codec *codec; int i; /* If the initialization of this soc device failed, there is no codec @@ -1064,8 +1065,7 @@ static int soc_suspend(struct device *dev) } /* suspend all CODECs */ - for (i = 0; i < card->num_rtd; i++) { - struct snd_soc_codec *codec = card->rtd[i].codec; + list_for_each_entry(codec, &card->codec_dev_list, card_list) { /* If there are paths active then the CODEC will be held with * bias _ON and should not be suspended. */ if (!codec->suspended && codec->driver->suspend) { @@ -1106,6 +1106,7 @@ static void soc_resume_deferred(struct work_struct *work) struct snd_soc_card *card = container_of(work, struct snd_soc_card, deferred_resume_work); struct platform_device *pdev = to_platform_device(card->dev); + struct snd_soc_codec *codec; int i; /* our power state is still SNDRV_CTL_POWER_D3hot from suspend time, @@ -1131,8 +1132,7 @@ static void soc_resume_deferred(struct work_struct *work) cpu_dai->driver->resume(cpu_dai); } - for (i = 0; i < card->num_rtd; i++) { - struct snd_soc_codec *codec = card->rtd[i].codec; + list_for_each_entry(codec, &card->codec_dev_list, card_list) { /* If the CODEC was idle over suspend then it will have been * left with bias OFF or STANDBY and suspended so we must now * resume. Otherwise the suspend was suppressed. @@ -1603,6 +1603,130 @@ static void soc_unregister_ac97_dai_link(struct snd_soc_codec *codec) } #endif +static int soc_probe_aux_dev(struct snd_soc_card *card, int num) +{ + struct snd_soc_aux_dev *aux_dev = &card->aux_dev[num]; + struct snd_soc_pcm_runtime *rtd = &card->rtd_aux[num]; + struct snd_soc_codec *codec; + const char *temp; + int ret = 0; + + /* find CODEC from registered CODECs*/ + list_for_each_entry(codec, &codec_list, list) { + if (!strcmp(codec->name, aux_dev->codec_name)) { + if (codec->probed) { + dev_err(codec->dev, + "asoc: codec already probed"); + ret = -EBUSY; + goto out; + } + break; + } + } + + if (!try_module_get(codec->dev->driver->owner)) + return -ENODEV; + + codec->card = card; + codec->dapm.card = card; + + soc_set_name_prefix(card, codec); + if (codec->driver->probe) { + ret = codec->driver->probe(codec); + if (ret < 0) { + dev_err(codec->dev, "asoc: failed to probe CODEC"); + return ret; + } + } + + soc_init_codec_debugfs(codec); + + /* mark codec as probed and add to card codec list */ + codec->probed = 1; + list_add(&codec->card_list, &card->codec_dev_list); + list_add(&codec->dapm.list, &card->dapm_list); + + /* now that all clients have probed, initialise the DAI link */ + if (aux_dev->init) { + /* machine controls, routes and widgets are not prefixed */ + temp = codec->name_prefix; + codec->name_prefix = NULL; + ret = aux_dev->init(&codec->dapm); + if (ret < 0) { + dev_err(codec->dev, + "asoc: failed to init %s\n", aux_dev->name); + return ret; + } + codec->name_prefix = temp; + } + + /* Make sure all DAPM widgets are instantiated */ + snd_soc_dapm_new_widgets(&codec->dapm); + snd_soc_dapm_sync(&codec->dapm); + + /* register the rtd device */ + rtd->codec = codec; + rtd->card = card; + rtd->dev.parent = card->dev; + rtd->dev.release = rtd_release; + rtd->dev.init_name = aux_dev->name; + ret = device_register(&rtd->dev); + if (ret < 0) { + dev_err(codec->dev, + "asoc: failed to register aux runtime device %d\n", + ret); + return ret; + } + rtd->dev_registered = 1; + + /* add DAPM sysfs entries for this codec */ + ret = snd_soc_dapm_sys_add(&rtd->dev); + if (ret < 0) + dev_err(codec->dev, + "asoc: failed to add codec dapm sysfs entries\n"); + + /* add codec sysfs entries */ + ret = device_create_file(&rtd->dev, &dev_attr_codec_reg); + if (ret < 0) + dev_err(codec->dev, "asoc: failed to add codec sysfs files\n"); + +out: + return ret; +} + +static void soc_remove_aux_dev(struct snd_soc_card *card, int num) +{ + struct snd_soc_pcm_runtime *rtd = &card->rtd_aux[num]; + struct snd_soc_codec *codec = rtd->codec; + int err; + + /* unregister the rtd device */ + if (rtd->dev_registered) { + device_unregister(&rtd->dev); + rtd->dev_registered = 0; + } + + /* remove the CODEC */ + if (codec && codec->probed) { + if (codec->driver->remove) { + err = codec->driver->remove(codec); + if (err < 0) + dev_err(codec->dev, + "asoc: failed to remove %s\n", + codec->name); + } + + /* Make sure all DAPM widgets are freed */ + snd_soc_dapm_free(&codec->dapm); + + soc_cleanup_codec_debugfs(codec); + device_remove_file(&rtd->dev, &dev_attr_codec_reg); + codec->probed = 0; + list_del(&codec->card_list); + module_put(codec->dev->driver->owner); + } +} + static void snd_soc_instantiate_card(struct snd_soc_card *card) { struct platform_device *pdev = to_platform_device(card->dev); @@ -1657,6 +1781,15 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card) } } + for (i = 0; i < card->num_aux_devs; i++) { + ret = soc_probe_aux_dev(card, i); + if (ret < 0) { + pr_err("asoc: failed to add auxiliary devices %s: %d\n", + card->name, ret); + goto probe_aux_dev_err; + } + } + snprintf(card->snd_card->shortname, sizeof(card->snd_card->shortname), "%s", card->name); snprintf(card->snd_card->longname, sizeof(card->snd_card->longname), @@ -1683,6 +1816,10 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card) mutex_unlock(&card->mutex); return; +probe_aux_dev_err: + for (i = 0; i < card->num_aux_devs; i++) + soc_remove_aux_dev(card, i); + probe_dai_err: for (i = 0; i < card->num_links; i++) soc_remove_dai_link(card, i); @@ -1744,6 +1881,10 @@ static int soc_remove(struct platform_device *pdev) run_delayed_work(&rtd->delayed_work); } + /* remove auxiliary devices */ + for (i = 0; i < card->num_aux_devs; i++) + soc_remove_aux_dev(card, i); + /* remove and free each DAI */ for (i = 0; i < card->num_rtd; i++) soc_remove_dai_link(card, i); @@ -2946,10 +3087,12 @@ static int snd_soc_register_card(struct snd_soc_card *card) if (!card->name || !card->dev) return -EINVAL; - card->rtd = kzalloc(sizeof(struct snd_soc_pcm_runtime) * card->num_links, - GFP_KERNEL); + card->rtd = kzalloc(sizeof(struct snd_soc_pcm_runtime) * + (card->num_links + card->num_aux_devs), + GFP_KERNEL); if (card->rtd == NULL) return -ENOMEM; + card->rtd_aux = &card->rtd[card->num_links]; for (i = 0; i < card->num_links; i++) card->rtd[i].dai_link = &card->dai_link[i]; -- cgit v1.2.3 From 18f454047b3d009e347dc3aeacb1aec91a4c493f Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Tue, 30 Nov 2010 14:31:45 +0200 Subject: ASoC: tlv320dac33: Do not enable the codec in init_chip No need to enable the codec at this time. The codec will be enabled later by other events Signed-off-by: Peter Ujfalusi Acked-by: Mark Brown Signed-off-by: Liam Girdwood --- sound/soc/codecs/tlv320dac33.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/sound/soc/codecs/tlv320dac33.c b/sound/soc/codecs/tlv320dac33.c index ccb267f4e968..080ec9183f67 100644 --- a/sound/soc/codecs/tlv320dac33.c +++ b/sound/soc/codecs/tlv320dac33.c @@ -315,8 +315,6 @@ static void dac33_init_chip(struct snd_soc_codec *codec) clock source = internal osc (?) */ dac33_write(codec, DAC33_ANA_VOL_SOFT_STEP_CTRL, DAC33_VOLCLKEN); - dac33_write(codec, DAC33_PWR_CTRL, DAC33_PDNALLB); - /* Restore only selected registers (gains mostly) */ dac33_write(codec, DAC33_LDAC_DIG_VOL_CTRL, dac33_read_reg_cache(codec, DAC33_LDAC_DIG_VOL_CTRL)); -- cgit v1.2.3 From 3e202345abc2cea09a3601df527629102f37e563 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Tue, 30 Nov 2010 14:31:46 +0200 Subject: ASoC: tlv320dac33: Avoid multiple soft power up During playback start the codec has been already powered at BIAS_ON event time, so there's no need to enable the codec again. Signed-off-by: Peter Ujfalusi Acked-by: Mark Brown Signed-off-by: Liam Girdwood --- sound/soc/codecs/tlv320dac33.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sound/soc/codecs/tlv320dac33.c b/sound/soc/codecs/tlv320dac33.c index 080ec9183f67..a0ba5d1be1b3 100644 --- a/sound/soc/codecs/tlv320dac33.c +++ b/sound/soc/codecs/tlv320dac33.c @@ -642,7 +642,8 @@ static int dac33_set_bias_level(struct snd_soc_codec *codec, switch (level) { case SND_SOC_BIAS_ON: - dac33_soft_power(codec, 1); + if (!dac33->substream) + dac33_soft_power(codec, 1); break; case SND_SOC_BIAS_PREPARE: break; -- cgit v1.2.3 From d5876ce1242b78987e6243ba3cb23bb61d44d4a9 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Tue, 30 Nov 2010 16:00:00 +0200 Subject: ASoC: tpa6130a2: Simplify power state management Use simpler way to avoid setting the same power state for the amplifier. Simplifies the check introduced by patch: ASoC: tpa6130a2: Fix unbalanced regulator disables Signed-off-by: Peter Ujfalusi Cc: Jarkko Nikula Signed-off-by: Liam Girdwood --- sound/soc/codecs/tpa6130a2.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/sound/soc/codecs/tpa6130a2.c b/sound/soc/codecs/tpa6130a2.c index 9d61a1d6fce0..199edf07f47e 100644 --- a/sound/soc/codecs/tpa6130a2.c +++ b/sound/soc/codecs/tpa6130a2.c @@ -41,7 +41,7 @@ struct tpa6130a2_data { unsigned char regs[TPA6130A2_CACHEREGNUM]; struct regulator *supply; int power_gpio; - unsigned char power_state; + u8 power_state:1; enum tpa_model id; }; @@ -116,7 +116,7 @@ static int tpa6130a2_initialize(void) return ret; } -static int tpa6130a2_power(int power) +static int tpa6130a2_power(u8 power) { struct tpa6130a2_data *data; u8 val; @@ -126,8 +126,10 @@ static int tpa6130a2_power(int power) data = i2c_get_clientdata(tpa6130a2_client); mutex_lock(&data->mutex); - if (power && !data->power_state) { + if (power == data->power_state) + goto exit; + if (power) { ret = regulator_enable(data->supply); if (ret != 0) { dev_err(&tpa6130a2_client->dev, @@ -154,7 +156,7 @@ static int tpa6130a2_power(int power) val = tpa6130a2_read(TPA6130A2_REG_CONTROL); val &= ~TPA6130A2_SWS; tpa6130a2_i2c_write(TPA6130A2_REG_CONTROL, val); - } else if (!power && data->power_state) { + } else { /* set SWS */ val = tpa6130a2_read(TPA6130A2_REG_CONTROL); val |= TPA6130A2_SWS; -- cgit v1.2.3 From d534bacd918fcf0909039b95db7c090702e739d5 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Tue, 30 Nov 2010 16:00:01 +0200 Subject: ASoC: tpa6130a2: Defer SW enable from power enable Do not enable the amplifier right after the power has been restored to the amplifier. The DAPM_SUPPLY widget turns on the amp early in the DAPM power walk, and the unmuting of channel happens quite late. Keeping the amp in SW reset state ensures better muting. In this way the pop noise coming from other components (codec) can be filtered out. Signed-off-by: Peter Ujfalusi Acked-by: Mark Brown Signed-off-by: Liam Girdwood --- sound/soc/codecs/tpa6130a2.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/sound/soc/codecs/tpa6130a2.c b/sound/soc/codecs/tpa6130a2.c index 199edf07f47e..42887ae1568b 100644 --- a/sound/soc/codecs/tpa6130a2.c +++ b/sound/soc/codecs/tpa6130a2.c @@ -151,11 +151,6 @@ static int tpa6130a2_power(u8 power) data->power_state = 0; goto exit; } - - /* Clear SWS */ - val = tpa6130a2_read(TPA6130A2_REG_CONTROL); - val &= ~TPA6130A2_SWS; - tpa6130a2_i2c_write(TPA6130A2_REG_CONTROL, val); } else { /* set SWS */ val = tpa6130a2_read(TPA6130A2_REG_CONTROL); @@ -301,6 +296,7 @@ static void tpa6130a2_channel_enable(u8 channel, int enable) /* Enable amplifier */ val = tpa6130a2_read(TPA6130A2_REG_CONTROL); val |= channel; + val &= ~TPA6130A2_SWS; tpa6130a2_i2c_write(TPA6130A2_REG_CONTROL, val); /* Unmute channel */ -- cgit v1.2.3 From 8cc14e13d15ec558c880ce6eaaddf99c08f85ab6 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Tue, 30 Nov 2010 16:00:02 +0200 Subject: ASoC: tpa6130a2: Use one event handler for PGA_E Reduce the amount of duplicated code by using single event handler for PGA_E to enable the needed channel. Use the w->shift to pass the channel information to the handler function. Signed-off-by: Peter Ujfalusi Acked-by: Mark Brown Signed-off-by: Liam Girdwood --- sound/soc/codecs/tpa6130a2.c | 24 +++++------------------- 1 file changed, 5 insertions(+), 19 deletions(-) diff --git a/sound/soc/codecs/tpa6130a2.c b/sound/soc/codecs/tpa6130a2.c index 42887ae1568b..4c77a82d9780 100644 --- a/sound/soc/codecs/tpa6130a2.c +++ b/sound/soc/codecs/tpa6130a2.c @@ -317,29 +317,15 @@ static void tpa6130a2_channel_enable(u8 channel, int enable) } } -static int tpa6130a2_left_event(struct snd_soc_dapm_widget *w, +static int tpa6130a2_pga_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { switch (event) { case SND_SOC_DAPM_POST_PMU: - tpa6130a2_channel_enable(TPA6130A2_HP_EN_L, 1); + tpa6130a2_channel_enable(w->shift, 1); break; case SND_SOC_DAPM_POST_PMD: - tpa6130a2_channel_enable(TPA6130A2_HP_EN_L, 0); - break; - } - return 0; -} - -static int tpa6130a2_right_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - switch (event) { - case SND_SOC_DAPM_POST_PMU: - tpa6130a2_channel_enable(TPA6130A2_HP_EN_R, 1); - break; - case SND_SOC_DAPM_POST_PMD: - tpa6130a2_channel_enable(TPA6130A2_HP_EN_R, 0); + tpa6130a2_channel_enable(w->shift, 0); break; } return 0; @@ -363,10 +349,10 @@ static int tpa6130a2_supply_event(struct snd_soc_dapm_widget *w, static const struct snd_soc_dapm_widget tpa6130a2_dapm_widgets[] = { SND_SOC_DAPM_PGA_E("TPA6130A2 Left", SND_SOC_NOPM, - 0, 0, NULL, 0, tpa6130a2_left_event, + TPA6130A2_HP_EN_L, 0, NULL, 0, tpa6130a2_pga_event, SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD), SND_SOC_DAPM_PGA_E("TPA6130A2 Right", SND_SOC_NOPM, - 0, 0, NULL, 0, tpa6130a2_right_event, + TPA6130A2_HP_EN_R, 0, NULL, 0, tpa6130a2_pga_event, SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD), SND_SOC_DAPM_SUPPLY("TPA6130A2 Enable", SND_SOC_NOPM, 0, 0, tpa6130a2_supply_event, -- cgit v1.2.3 From 1bb5ec6a6a0e094c84cc4fa2ba4a6d7cf8e9e8c6 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Tue, 30 Nov 2010 16:00:03 +0200 Subject: ASoC: tpa6130a2: Add stereo DAPM path New DAPM widgets, and paths to enable both channels at the same time (for stereo output). With this path the switch time difference can be avoided between left and right channels. The original DAPM paths can be still used, if only one of TPA's output has been connected to a speaker, but for most of the cases, switching to the stereo path is better. Signed-off-by: Peter Ujfalusi Acked-by: Mark Brown Signed-off-by: Liam Girdwood --- sound/soc/codecs/tpa6130a2.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/sound/soc/codecs/tpa6130a2.c b/sound/soc/codecs/tpa6130a2.c index 4c77a82d9780..c97badfac540 100644 --- a/sound/soc/codecs/tpa6130a2.c +++ b/sound/soc/codecs/tpa6130a2.c @@ -354,20 +354,27 @@ static const struct snd_soc_dapm_widget tpa6130a2_dapm_widgets[] = { SND_SOC_DAPM_PGA_E("TPA6130A2 Right", SND_SOC_NOPM, TPA6130A2_HP_EN_R, 0, NULL, 0, tpa6130a2_pga_event, SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD), + SND_SOC_DAPM_PGA_E("TPA6130A2 Stereo", SND_SOC_NOPM, + TPA6130A2_HP_EN_L | TPA6130A2_HP_EN_R, 0, NULL, 0, + tpa6130a2_pga_event, + SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD), SND_SOC_DAPM_SUPPLY("TPA6130A2 Enable", SND_SOC_NOPM, 0, 0, tpa6130a2_supply_event, SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD), /* Outputs */ SND_SOC_DAPM_OUTPUT("TPA6130A2 Headphone Left"), SND_SOC_DAPM_OUTPUT("TPA6130A2 Headphone Right"), + SND_SOC_DAPM_OUTPUT("TPA6130A2 Headphone Stereo"), }; static const struct snd_soc_dapm_route audio_map[] = { {"TPA6130A2 Headphone Left", NULL, "TPA6130A2 Left"}, {"TPA6130A2 Headphone Right", NULL, "TPA6130A2 Right"}, + {"TPA6130A2 Headphone Stereo", NULL, "TPA6130A2 Stereo"}, {"TPA6130A2 Headphone Left", NULL, "TPA6130A2 Enable"}, {"TPA6130A2 Headphone Right", NULL, "TPA6130A2 Enable"}, + {"TPA6130A2 Headphone Stereo", NULL, "TPA6130A2 Enable"}, }; int tpa6130a2_add_controls(struct snd_soc_codec *codec) -- cgit v1.2.3 From b54ce60eb7f61f8e314b8b241b0469eda3bb1d42 Mon Sep 17 00:00:00 2001 From: Gui Jianfeng Date: Tue, 30 Nov 2010 20:52:46 +0100 Subject: cfq-iosched: Get rid of st->active When a cfq group is running, it won't be dequeued from service tree, so there's no need to store the active one in st->active. Just gid rid of it. Signed-off-by: Gui Jianfeng Acked-by: Vivek Goyal Signed-off-by: Jens Axboe --- block/cfq-iosched.c | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c index 73a58628f54a..e18d316ae652 100644 --- a/block/cfq-iosched.c +++ b/block/cfq-iosched.c @@ -87,7 +87,6 @@ struct cfq_rb_root { unsigned count; unsigned total_weight; u64 min_vdisktime; - struct rb_node *active; }; #define CFQ_RB_ROOT (struct cfq_rb_root) { .rb = RB_ROOT, .left = NULL, \ .count = 0, .min_vdisktime = 0, } @@ -563,11 +562,6 @@ static void update_min_vdisktime(struct cfq_rb_root *st) u64 vdisktime = st->min_vdisktime; struct cfq_group *cfqg; - if (st->active) { - cfqg = rb_entry_cfqg(st->active); - vdisktime = cfqg->vdisktime; - } - if (st->left) { cfqg = rb_entry_cfqg(st->left); vdisktime = min_vdisktime(vdisktime, cfqg->vdisktime); @@ -894,9 +888,6 @@ cfq_group_service_tree_del(struct cfq_data *cfqd, struct cfq_group *cfqg) { struct cfq_rb_root *st = &cfqd->grp_service_tree; - if (st->active == &cfqg->rb_node) - st->active = NULL; - BUG_ON(cfqg->nr_cfqq < 1); cfqg->nr_cfqq--; @@ -1095,7 +1086,7 @@ static void cfq_put_cfqg(struct cfq_group *cfqg) if (!atomic_dec_and_test(&cfqg->ref)) return; for_each_cfqg_st(cfqg, i, j, st) - BUG_ON(!RB_EMPTY_ROOT(&st->rb) || st->active != NULL); + BUG_ON(!RB_EMPTY_ROOT(&st->rb)); kfree(cfqg); } @@ -1687,9 +1678,6 @@ __cfq_slice_expired(struct cfq_data *cfqd, struct cfq_queue *cfqq, if (cfqq == cfqd->active_queue) cfqd->active_queue = NULL; - if (&cfqq->cfqg->rb_node == cfqd->grp_service_tree.active) - cfqd->grp_service_tree.active = NULL; - if (cfqd->active_cic) { put_io_context(cfqd->active_cic->ioc); cfqd->active_cic = NULL; @@ -2199,7 +2187,6 @@ static struct cfq_group *cfq_get_next_cfqg(struct cfq_data *cfqd) if (RB_EMPTY_ROOT(&st->rb)) return NULL; cfqg = cfq_rb_first_group(st); - st->active = &cfqg->rb_node; update_min_vdisktime(st); return cfqg; } -- cgit v1.2.3 From 760701bfe14faee8ea0608a9cab2046071d98a39 Mon Sep 17 00:00:00 2001 From: Gui Jianfeng Date: Tue, 30 Nov 2010 20:52:47 +0100 Subject: cfq-iosched: Get rid of on_st flag It's able to check whether a CFQ group on a service tree by checking "cfqg->rb_node". There's no need to maintain an extra flag here. Signed-off-by: Gui Jianfeng Acked-by: Vivek Goyal Signed-off-by: Jens Axboe --- block/cfq-iosched.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c index e18d316ae652..5d0349d602fe 100644 --- a/block/cfq-iosched.c +++ b/block/cfq-iosched.c @@ -179,7 +179,6 @@ struct cfq_group { /* group service_tree key */ u64 vdisktime; unsigned int weight; - bool on_st; /* number of cfqq currently on this group */ int nr_cfqq; @@ -863,7 +862,7 @@ cfq_group_service_tree_add(struct cfq_data *cfqd, struct cfq_group *cfqg) struct rb_node *n; cfqg->nr_cfqq++; - if (cfqg->on_st) + if (!RB_EMPTY_NODE(&cfqg->rb_node)) return; /* @@ -879,7 +878,6 @@ cfq_group_service_tree_add(struct cfq_data *cfqd, struct cfq_group *cfqg) cfqg->vdisktime = st->min_vdisktime; __cfq_group_service_tree_add(st, cfqg); - cfqg->on_st = true; st->total_weight += cfqg->weight; } @@ -896,7 +894,6 @@ cfq_group_service_tree_del(struct cfq_data *cfqd, struct cfq_group *cfqg) return; cfq_log_cfqg(cfqd, cfqg, "del_from_rr group"); - cfqg->on_st = false; st->total_weight -= cfqg->weight; if (!RB_EMPTY_NODE(&cfqg->rb_node)) cfq_rb_erase(&cfqg->rb_node, st); -- cgit v1.2.3 From 5b275ce27077d6463ca28c9671dce7c2c1f622e2 Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Thu, 11 Nov 2010 15:27:29 +0000 Subject: thermal: make ops constant And while touching that function definition do something about the disaster of formatting there. Signed-off-by: Alan Cox Acked-by: Zhang Rui Signed-off-by: Len Brown --- drivers/thermal/thermal_sys.c | 17 +++++------------ include/linux/thermal.h | 15 +++++---------- 2 files changed, 10 insertions(+), 22 deletions(-) diff --git a/drivers/thermal/thermal_sys.c b/drivers/thermal/thermal_sys.c index 13c72c629329..bde3477c1c6b 100644 --- a/drivers/thermal/thermal_sys.c +++ b/drivers/thermal/thermal_sys.c @@ -823,11 +823,8 @@ static struct class thermal_class = { * @devdata: device private data. * @ops: standard thermal cooling devices callbacks. */ -struct thermal_cooling_device *thermal_cooling_device_register(char *type, - void *devdata, - struct - thermal_cooling_device_ops - *ops) +struct thermal_cooling_device *thermal_cooling_device_register( + char *type, void *devdata, const struct thermal_cooling_device_ops *ops) { struct thermal_cooling_device *cdev; struct thermal_zone_device *pos; @@ -1048,13 +1045,9 @@ EXPORT_SYMBOL(thermal_zone_device_update); * section 11.1.5.1 of the ACPI specification 3.0. */ struct thermal_zone_device *thermal_zone_device_register(char *type, - int trips, - void *devdata, struct - thermal_zone_device_ops - *ops, int tc1, int - tc2, - int passive_delay, - int polling_delay) + int trips, void *devdata, + const struct thermal_zone_device_ops *ops, + int tc1, int tc2, int passive_delay, int polling_delay) { struct thermal_zone_device *tz; struct thermal_cooling_device *pos; diff --git a/include/linux/thermal.h b/include/linux/thermal.h index 1de8b9eb841b..06626904daa0 100644 --- a/include/linux/thermal.h +++ b/include/linux/thermal.h @@ -77,7 +77,7 @@ struct thermal_cooling_device { char type[THERMAL_NAME_LENGTH]; struct device device; void *devdata; - struct thermal_cooling_device_ops *ops; + const struct thermal_cooling_device_ops *ops; struct list_head node; }; @@ -114,7 +114,7 @@ struct thermal_zone_device { int last_temperature; bool passive; unsigned int forced_passive; - struct thermal_zone_device_ops *ops; + const struct thermal_zone_device_ops *ops; struct list_head cooling_devices; struct idr idr; struct mutex lock; /* protect cooling devices list */ @@ -129,11 +129,8 @@ struct thermal_zone_device { }; struct thermal_zone_device *thermal_zone_device_register(char *, int, void *, - struct - thermal_zone_device_ops - *, int tc1, int tc2, - int passive_freq, - int polling_freq); + const struct thermal_zone_device_ops *, int tc1, int tc2, + int passive_freq, int polling_freq); void thermal_zone_device_unregister(struct thermal_zone_device *); int thermal_zone_bind_cooling_device(struct thermal_zone_device *, int, @@ -142,9 +139,7 @@ int thermal_zone_unbind_cooling_device(struct thermal_zone_device *, int, struct thermal_cooling_device *); void thermal_zone_device_update(struct thermal_zone_device *); struct thermal_cooling_device *thermal_cooling_device_register(char *, void *, - struct - thermal_cooling_device_ops - *); + const struct thermal_cooling_device_ops *); void thermal_cooling_device_unregister(struct thermal_cooling_device *); #endif /* __THERMAL_H__ */ -- cgit v1.2.3 From 257e48f1474a1f5bfa6fcafb12f77a8479063293 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 29 Nov 2010 16:19:24 +0000 Subject: drm/i915/lvds: Disable panel-fitter on gen4 for 1:1 scale factors Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/intel_lvds.c | 27 +++++++++++++++------------ 1 file changed, 15 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index 4324a326f98e..5b88e145ee79 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c @@ -269,14 +269,13 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder, u32 scaled_width = adjusted_mode->hdisplay * mode->vdisplay; u32 scaled_height = mode->hdisplay * adjusted_mode->vdisplay; - pfit_control |= PFIT_ENABLE; /* 965+ is easy, it does everything in hw */ if (scaled_width > scaled_height) - pfit_control |= PFIT_SCALING_PILLAR; + pfit_control |= PFIT_ENABLE | PFIT_SCALING_PILLAR; else if (scaled_width < scaled_height) - pfit_control |= PFIT_SCALING_LETTER; - else - pfit_control |= PFIT_SCALING_AUTO; + pfit_control |= PFIT_ENABLE | PFIT_SCALING_LETTER; + else if (adjusted_mode->hdisplay != mode->hdisplay) + pfit_control |= PFIT_ENABLE | PFIT_SCALING_AUTO; } else { u32 scaled_width = adjusted_mode->hdisplay * mode->vdisplay; u32 scaled_height = mode->hdisplay * adjusted_mode->vdisplay; @@ -323,13 +322,17 @@ static bool intel_lvds_mode_fixup(struct drm_encoder *encoder, * Full scaling, even if it changes the aspect ratio. * Fortunately this is all done for us in hw. */ - pfit_control |= PFIT_ENABLE; - if (INTEL_INFO(dev)->gen >= 4) - pfit_control |= PFIT_SCALING_AUTO; - else - pfit_control |= (VERT_AUTO_SCALE | HORIZ_AUTO_SCALE | - VERT_INTERP_BILINEAR | - HORIZ_INTERP_BILINEAR); + if (mode->vdisplay != adjusted_mode->vdisplay || + mode->hdisplay != adjusted_mode->hdisplay) { + pfit_control |= PFIT_ENABLE; + if (INTEL_INFO(dev)->gen >= 4) + pfit_control |= PFIT_SCALING_AUTO; + else + pfit_control |= (VERT_AUTO_SCALE | + VERT_INTERP_BILINEAR | + HORIZ_AUTO_SCALE | + HORIZ_INTERP_BILINEAR); + } break; default: -- cgit v1.2.3 From 28b26e15533e60970a014582d812d471ad63bcd0 Mon Sep 17 00:00:00 2001 From: Florian Faber Date: Wed, 1 Dec 2010 12:14:47 +0100 Subject: ALSA: hdsp - Add support for RPM io box Add support for the RME HDSP RPM IO box. Changes have been made in the identification of the IO box and the neccessary controls have been added. Signed-off-by: Florian Faber Signed-off-by: Takashi Iwai --- include/sound/hdsp.h | 1 + sound/pci/rme9652/hdsp.c | 538 ++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 482 insertions(+), 57 deletions(-) diff --git a/include/sound/hdsp.h b/include/sound/hdsp.h index d98a78dff2db..0909a3843479 100644 --- a/include/sound/hdsp.h +++ b/include/sound/hdsp.h @@ -28,6 +28,7 @@ enum HDSP_IO_Type { Multiface, H9652, H9632, + RPM, Undefined, }; diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c index 0b720cf7783e..2d8332416c83 100644 --- a/sound/pci/rme9652/hdsp.c +++ b/sound/pci/rme9652/hdsp.c @@ -60,6 +60,7 @@ MODULE_SUPPORTED_DEVICE("{{RME Hammerfall-DSP}," "{RME HDSP-9652}," "{RME HDSP-9632}}"); #ifdef HDSP_FW_LOADER +MODULE_FIRMWARE("rpm_firmware.bin"); MODULE_FIRMWARE("multiface_firmware.bin"); MODULE_FIRMWARE("multiface_firmware_rev11.bin"); MODULE_FIRMWARE("digiface_firmware.bin"); @@ -81,6 +82,7 @@ MODULE_FIRMWARE("digiface_firmware_rev11.bin"); #define H9632_SS_CHANNELS 12 #define H9632_DS_CHANNELS 8 #define H9632_QS_CHANNELS 4 +#define RPM_CHANNELS 6 /* Write registers. These are defined as byte-offsets from the iobase value. */ @@ -191,6 +193,25 @@ MODULE_FIRMWARE("digiface_firmware_rev11.bin"); #define HDSP_PhoneGain1 (1<<30) #define HDSP_QuadSpeed (1<<31) +/* RPM uses some of the registers for special purposes */ +#define HDSP_RPM_Inp12 0x04A00 +#define HDSP_RPM_Inp12_Phon_6dB 0x00800 /* Dolby */ +#define HDSP_RPM_Inp12_Phon_0dB 0x00000 /* .. */ +#define HDSP_RPM_Inp12_Phon_n6dB 0x04000 /* inp_0 */ +#define HDSP_RPM_Inp12_Line_0dB 0x04200 /* Dolby+PRO */ +#define HDSP_RPM_Inp12_Line_n6dB 0x00200 /* PRO */ + +#define HDSP_RPM_Inp34 0x32000 +#define HDSP_RPM_Inp34_Phon_6dB 0x20000 /* SyncRef1 */ +#define HDSP_RPM_Inp34_Phon_0dB 0x00000 /* .. */ +#define HDSP_RPM_Inp34_Phon_n6dB 0x02000 /* SyncRef2 */ +#define HDSP_RPM_Inp34_Line_0dB 0x30000 /* SyncRef1+SyncRef0 */ +#define HDSP_RPM_Inp34_Line_n6dB 0x10000 /* SyncRef0 */ + +#define HDSP_RPM_Bypass 0x01000 + +#define HDSP_RPM_Disconnect 0x00001 + #define HDSP_ADGainMask (HDSP_ADGain0|HDSP_ADGain1) #define HDSP_ADGainMinus10dBV HDSP_ADGainMask #define HDSP_ADGainPlus4dBu (HDSP_ADGain0) @@ -450,7 +471,7 @@ struct hdsp { u32 creg_spdif; u32 creg_spdif_stream; int clock_source_locked; - char *card_name; /* digiface/multiface */ + char *card_name; /* digiface/multiface/rpm */ enum HDSP_IO_Type io_type; /* ditto, but for code use */ unsigned short firmware_rev; unsigned short state; /* stores state bits */ @@ -612,6 +633,7 @@ static int hdsp_playback_to_output_key (struct hdsp *hdsp, int in, int out) switch (hdsp->io_type) { case Multiface: case Digiface: + case RPM: default: if (hdsp->firmware_rev == 0xa) return (64 * out) + (32 + (in)); @@ -629,6 +651,7 @@ static int hdsp_input_to_output_key (struct hdsp *hdsp, int in, int out) switch (hdsp->io_type) { case Multiface: case Digiface: + case RPM: default: if (hdsp->firmware_rev == 0xa) return (64 * out) + in; @@ -655,7 +678,7 @@ static int hdsp_check_for_iobox (struct hdsp *hdsp) { if (hdsp->io_type == H9652 || hdsp->io_type == H9632) return 0; if (hdsp_read (hdsp, HDSP_statusRegister) & HDSP_ConfigError) { - snd_printk ("Hammerfall-DSP: no Digiface or Multiface connected!\n"); + snd_printk("Hammerfall-DSP: no IO box connected!\n"); hdsp->state &= ~HDSP_FirmwareLoaded; return -EIO; } @@ -680,7 +703,7 @@ static int hdsp_wait_for_iobox(struct hdsp *hdsp, unsigned int loops, } } - snd_printk("Hammerfall-DSP: no Digiface or Multiface connected!\n"); + snd_printk("Hammerfall-DSP: no IO box connected!\n"); hdsp->state &= ~HDSP_FirmwareLoaded; return -EIO; } @@ -752,17 +775,21 @@ static int hdsp_get_iobox_version (struct hdsp *hdsp) hdsp_write (hdsp, HDSP_control2Reg, HDSP_S_LOAD); hdsp_write (hdsp, HDSP_fifoData, 0); - if (hdsp_fifo_wait (hdsp, 0, HDSP_SHORT_WAIT)) { - hdsp->io_type = Multiface; - hdsp_write (hdsp, HDSP_control2Reg, HDSP_VERSION_BIT); - hdsp_write (hdsp, HDSP_control2Reg, HDSP_S_LOAD); - hdsp_fifo_wait (hdsp, 0, HDSP_SHORT_WAIT); + if (hdsp_fifo_wait(hdsp, 0, HDSP_SHORT_WAIT)) { + hdsp_write(hdsp, HDSP_control2Reg, HDSP_VERSION_BIT); + hdsp_write(hdsp, HDSP_control2Reg, HDSP_S_LOAD); + if (hdsp_fifo_wait(hdsp, 0, HDSP_SHORT_WAIT)) + hdsp->io_type = RPM; + else + hdsp->io_type = Multiface; } else { hdsp->io_type = Digiface; } } else { /* firmware was already loaded, get iobox type */ - if (hdsp_read(hdsp, HDSP_status2Register) & HDSP_version1) + if (hdsp_read(hdsp, HDSP_status2Register) & HDSP_version2) + hdsp->io_type = RPM; + else if (hdsp_read(hdsp, HDSP_status2Register) & HDSP_version1) hdsp->io_type = Multiface; else hdsp->io_type = Digiface; @@ -1184,6 +1211,7 @@ static int hdsp_set_rate(struct hdsp *hdsp, int rate, int called_internally) hdsp->channel_map = channel_map_ds; } else { switch (hdsp->io_type) { + case RPM: case Multiface: hdsp->channel_map = channel_map_mf_ss; break; @@ -3231,6 +3259,318 @@ HDSP_PRECISE_POINTER("Precise Pointer", 0), HDSP_USE_MIDI_TASKLET("Use Midi Tasklet", 0), }; + +static int hdsp_rpm_input12(struct hdsp *hdsp) +{ + switch (hdsp->control_register & HDSP_RPM_Inp12) { + case HDSP_RPM_Inp12_Phon_6dB: + return 0; + case HDSP_RPM_Inp12_Phon_n6dB: + return 2; + case HDSP_RPM_Inp12_Line_0dB: + return 3; + case HDSP_RPM_Inp12_Line_n6dB: + return 4; + } + return 1; +} + + +static int snd_hdsp_get_rpm_input12(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +{ + struct hdsp *hdsp = snd_kcontrol_chip(kcontrol); + + ucontrol->value.enumerated.item[0] = hdsp_rpm_input12(hdsp); + return 0; +} + + +static int hdsp_set_rpm_input12(struct hdsp *hdsp, int mode) +{ + hdsp->control_register &= ~HDSP_RPM_Inp12; + switch (mode) { + case 0: + hdsp->control_register |= HDSP_RPM_Inp12_Phon_6dB; + break; + case 1: + break; + case 2: + hdsp->control_register |= HDSP_RPM_Inp12_Phon_n6dB; + break; + case 3: + hdsp->control_register |= HDSP_RPM_Inp12_Line_0dB; + break; + case 4: + hdsp->control_register |= HDSP_RPM_Inp12_Line_n6dB; + break; + default: + return -1; + } + + hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register); + return 0; +} + + +static int snd_hdsp_put_rpm_input12(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +{ + struct hdsp *hdsp = snd_kcontrol_chip(kcontrol); + int change; + int val; + + if (!snd_hdsp_use_is_exclusive(hdsp)) + return -EBUSY; + val = ucontrol->value.enumerated.item[0]; + if (val < 0) + val = 0; + if (val > 4) + val = 4; + spin_lock_irq(&hdsp->lock); + if (val != hdsp_rpm_input12(hdsp)) + change = (hdsp_set_rpm_input12(hdsp, val) == 0) ? 1 : 0; + else + change = 0; + spin_unlock_irq(&hdsp->lock); + return change; +} + + +static int snd_hdsp_info_rpm_input(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) +{ + static char *texts[] = {"Phono +6dB", "Phono 0dB", "Phono -6dB", "Line 0dB", "Line -6dB"}; + + uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; + uinfo->count = 1; + uinfo->value.enumerated.items = 5; + if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) + uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; + strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); + return 0; +} + + +static int hdsp_rpm_input34(struct hdsp *hdsp) +{ + switch (hdsp->control_register & HDSP_RPM_Inp34) { + case HDSP_RPM_Inp34_Phon_6dB: + return 0; + case HDSP_RPM_Inp34_Phon_n6dB: + return 2; + case HDSP_RPM_Inp34_Line_0dB: + return 3; + case HDSP_RPM_Inp34_Line_n6dB: + return 4; + } + return 1; +} + + +static int snd_hdsp_get_rpm_input34(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +{ + struct hdsp *hdsp = snd_kcontrol_chip(kcontrol); + + ucontrol->value.enumerated.item[0] = hdsp_rpm_input34(hdsp); + return 0; +} + + +static int hdsp_set_rpm_input34(struct hdsp *hdsp, int mode) +{ + hdsp->control_register &= ~HDSP_RPM_Inp34; + switch (mode) { + case 0: + hdsp->control_register |= HDSP_RPM_Inp34_Phon_6dB; + break; + case 1: + break; + case 2: + hdsp->control_register |= HDSP_RPM_Inp34_Phon_n6dB; + break; + case 3: + hdsp->control_register |= HDSP_RPM_Inp34_Line_0dB; + break; + case 4: + hdsp->control_register |= HDSP_RPM_Inp34_Line_n6dB; + break; + default: + return -1; + } + + hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register); + return 0; +} + + +static int snd_hdsp_put_rpm_input34(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +{ + struct hdsp *hdsp = snd_kcontrol_chip(kcontrol); + int change; + int val; + + if (!snd_hdsp_use_is_exclusive(hdsp)) + return -EBUSY; + val = ucontrol->value.enumerated.item[0]; + if (val < 0) + val = 0; + if (val > 4) + val = 4; + spin_lock_irq(&hdsp->lock); + if (val != hdsp_rpm_input34(hdsp)) + change = (hdsp_set_rpm_input34(hdsp, val) == 0) ? 1 : 0; + else + change = 0; + spin_unlock_irq(&hdsp->lock); + return change; +} + + +/* RPM Bypass switch */ +static int hdsp_rpm_bypass(struct hdsp *hdsp) +{ + return (hdsp->control_register & HDSP_RPM_Bypass) ? 1 : 0; +} + + +static int snd_hdsp_get_rpm_bypass(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +{ + struct hdsp *hdsp = snd_kcontrol_chip(kcontrol); + + ucontrol->value.integer.value[0] = hdsp_rpm_bypass(hdsp); + return 0; +} + + +static int hdsp_set_rpm_bypass(struct hdsp *hdsp, int on) +{ + if (on) + hdsp->control_register |= HDSP_RPM_Bypass; + else + hdsp->control_register &= ~HDSP_RPM_Bypass; + hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register); + return 0; +} + + +static int snd_hdsp_put_rpm_bypass(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +{ + struct hdsp *hdsp = snd_kcontrol_chip(kcontrol); + int change; + unsigned int val; + + if (!snd_hdsp_use_is_exclusive(hdsp)) + return -EBUSY; + val = ucontrol->value.integer.value[0] & 1; + spin_lock_irq(&hdsp->lock); + change = (int)val != hdsp_rpm_bypass(hdsp); + hdsp_set_rpm_bypass(hdsp, val); + spin_unlock_irq(&hdsp->lock); + return change; +} + + +static int snd_hdsp_info_rpm_bypass(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) +{ + static char *texts[] = {"On", "Off"}; + + uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; + uinfo->count = 1; + uinfo->value.enumerated.items = 2; + if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) + uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; + strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); + return 0; +} + + +/* RPM Disconnect switch */ +static int hdsp_rpm_disconnect(struct hdsp *hdsp) +{ + return (hdsp->control_register & HDSP_RPM_Disconnect) ? 1 : 0; +} + + +static int snd_hdsp_get_rpm_disconnect(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +{ + struct hdsp *hdsp = snd_kcontrol_chip(kcontrol); + + ucontrol->value.integer.value[0] = hdsp_rpm_disconnect(hdsp); + return 0; +} + + +static int hdsp_set_rpm_disconnect(struct hdsp *hdsp, int on) +{ + if (on) + hdsp->control_register |= HDSP_RPM_Disconnect; + else + hdsp->control_register &= ~HDSP_RPM_Disconnect; + hdsp_write(hdsp, HDSP_controlRegister, hdsp->control_register); + return 0; +} + + +static int snd_hdsp_put_rpm_disconnect(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +{ + struct hdsp *hdsp = snd_kcontrol_chip(kcontrol); + int change; + unsigned int val; + + if (!snd_hdsp_use_is_exclusive(hdsp)) + return -EBUSY; + val = ucontrol->value.integer.value[0] & 1; + spin_lock_irq(&hdsp->lock); + change = (int)val != hdsp_rpm_disconnect(hdsp); + hdsp_set_rpm_disconnect(hdsp, val); + spin_unlock_irq(&hdsp->lock); + return change; +} + +static int snd_hdsp_info_rpm_disconnect(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) +{ + static char *texts[] = {"On", "Off"}; + + uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; + uinfo->count = 1; + uinfo->value.enumerated.items = 2; + if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) + uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; + strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); + return 0; +} + +static struct snd_kcontrol_new snd_hdsp_rpm_controls[] = { + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "RPM Bypass", + .get = snd_hdsp_get_rpm_bypass, + .put = snd_hdsp_put_rpm_bypass, + .info = snd_hdsp_info_rpm_bypass + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "RPM Disconnect", + .get = snd_hdsp_get_rpm_disconnect, + .put = snd_hdsp_put_rpm_disconnect, + .info = snd_hdsp_info_rpm_disconnect + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Input 1/2", + .get = snd_hdsp_get_rpm_input12, + .put = snd_hdsp_put_rpm_input12, + .info = snd_hdsp_info_rpm_input + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Input 3/4", + .get = snd_hdsp_get_rpm_input34, + .put = snd_hdsp_put_rpm_input34, + .info = snd_hdsp_info_rpm_input + }, + HDSP_SYSTEM_SAMPLE_RATE("System Sample Rate", 0), + HDSP_MIXER("Mixer", 0) +}; + static struct snd_kcontrol_new snd_hdsp_96xx_aeb = HDSP_AEB("Analog Extension Board", 0); static struct snd_kcontrol_new snd_hdsp_adat_sync_check = HDSP_ADAT_SYNC_CHECK; @@ -3240,6 +3580,16 @@ static int snd_hdsp_create_controls(struct snd_card *card, struct hdsp *hdsp) int err; struct snd_kcontrol *kctl; + if (hdsp->io_type == RPM) { + /* RPM Bypass, Disconnect and Input switches */ + for (idx = 0; idx < ARRAY_SIZE(snd_hdsp_rpm_controls); idx++) { + err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_hdsp_rpm_controls[idx], hdsp)); + if (err < 0) + return err; + } + return 0; + } + for (idx = 0; idx < ARRAY_SIZE(snd_hdsp_controls); idx++) { if ((err = snd_ctl_add(card, kctl = snd_ctl_new1(&snd_hdsp_controls[idx], hdsp))) < 0) return err; @@ -3459,48 +3809,102 @@ snd_hdsp_proc_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer) snd_iprintf(buffer, "\n"); - switch (hdsp_spdif_in(hdsp)) { - case HDSP_SPDIFIN_OPTICAL: - snd_iprintf(buffer, "IEC958 input: Optical\n"); - break; - case HDSP_SPDIFIN_COAXIAL: - snd_iprintf(buffer, "IEC958 input: Coaxial\n"); - break; - case HDSP_SPDIFIN_INTERNAL: - snd_iprintf(buffer, "IEC958 input: Internal\n"); - break; - case HDSP_SPDIFIN_AES: - snd_iprintf(buffer, "IEC958 input: AES\n"); - break; - default: - snd_iprintf(buffer, "IEC958 input: ???\n"); - break; + if (hdsp->io_type != RPM) { + switch (hdsp_spdif_in(hdsp)) { + case HDSP_SPDIFIN_OPTICAL: + snd_iprintf(buffer, "IEC958 input: Optical\n"); + break; + case HDSP_SPDIFIN_COAXIAL: + snd_iprintf(buffer, "IEC958 input: Coaxial\n"); + break; + case HDSP_SPDIFIN_INTERNAL: + snd_iprintf(buffer, "IEC958 input: Internal\n"); + break; + case HDSP_SPDIFIN_AES: + snd_iprintf(buffer, "IEC958 input: AES\n"); + break; + default: + snd_iprintf(buffer, "IEC958 input: ???\n"); + break; + } } - if (hdsp->control_register & HDSP_SPDIFOpticalOut) - snd_iprintf(buffer, "IEC958 output: Coaxial & ADAT1\n"); - else - snd_iprintf(buffer, "IEC958 output: Coaxial only\n"); + if (RPM == hdsp->io_type) { + if (hdsp->control_register & HDSP_RPM_Bypass) + snd_iprintf(buffer, "RPM Bypass: disabled\n"); + else + snd_iprintf(buffer, "RPM Bypass: enabled\n"); + if (hdsp->control_register & HDSP_RPM_Disconnect) + snd_iprintf(buffer, "RPM disconnected\n"); + else + snd_iprintf(buffer, "RPM connected\n"); - if (hdsp->control_register & HDSP_SPDIFProfessional) - snd_iprintf(buffer, "IEC958 quality: Professional\n"); - else - snd_iprintf(buffer, "IEC958 quality: Consumer\n"); + switch (hdsp->control_register & HDSP_RPM_Inp12) { + case HDSP_RPM_Inp12_Phon_6dB: + snd_iprintf(buffer, "Input 1/2: Phono, 6dB\n"); + break; + case HDSP_RPM_Inp12_Phon_0dB: + snd_iprintf(buffer, "Input 1/2: Phono, 0dB\n"); + break; + case HDSP_RPM_Inp12_Phon_n6dB: + snd_iprintf(buffer, "Input 1/2: Phono, -6dB\n"); + break; + case HDSP_RPM_Inp12_Line_0dB: + snd_iprintf(buffer, "Input 1/2: Line, 0dB\n"); + break; + case HDSP_RPM_Inp12_Line_n6dB: + snd_iprintf(buffer, "Input 1/2: Line, -6dB\n"); + break; + default: + snd_iprintf(buffer, "Input 1/2: ???\n"); + } - if (hdsp->control_register & HDSP_SPDIFEmphasis) - snd_iprintf(buffer, "IEC958 emphasis: on\n"); - else - snd_iprintf(buffer, "IEC958 emphasis: off\n"); + switch (hdsp->control_register & HDSP_RPM_Inp34) { + case HDSP_RPM_Inp34_Phon_6dB: + snd_iprintf(buffer, "Input 3/4: Phono, 6dB\n"); + break; + case HDSP_RPM_Inp34_Phon_0dB: + snd_iprintf(buffer, "Input 3/4: Phono, 0dB\n"); + break; + case HDSP_RPM_Inp34_Phon_n6dB: + snd_iprintf(buffer, "Input 3/4: Phono, -6dB\n"); + break; + case HDSP_RPM_Inp34_Line_0dB: + snd_iprintf(buffer, "Input 3/4: Line, 0dB\n"); + break; + case HDSP_RPM_Inp34_Line_n6dB: + snd_iprintf(buffer, "Input 3/4: Line, -6dB\n"); + break; + default: + snd_iprintf(buffer, "Input 3/4: ???\n"); + } - if (hdsp->control_register & HDSP_SPDIFNonAudio) - snd_iprintf(buffer, "IEC958 NonAudio: on\n"); - else - snd_iprintf(buffer, "IEC958 NonAudio: off\n"); - if ((x = hdsp_spdif_sample_rate (hdsp)) != 0) - snd_iprintf (buffer, "IEC958 sample rate: %d\n", x); - else - snd_iprintf (buffer, "IEC958 sample rate: Error flag set\n"); + } else { + if (hdsp->control_register & HDSP_SPDIFOpticalOut) + snd_iprintf(buffer, "IEC958 output: Coaxial & ADAT1\n"); + else + snd_iprintf(buffer, "IEC958 output: Coaxial only\n"); + + if (hdsp->control_register & HDSP_SPDIFProfessional) + snd_iprintf(buffer, "IEC958 quality: Professional\n"); + else + snd_iprintf(buffer, "IEC958 quality: Consumer\n"); + + if (hdsp->control_register & HDSP_SPDIFEmphasis) + snd_iprintf(buffer, "IEC958 emphasis: on\n"); + else + snd_iprintf(buffer, "IEC958 emphasis: off\n"); + if (hdsp->control_register & HDSP_SPDIFNonAudio) + snd_iprintf(buffer, "IEC958 NonAudio: on\n"); + else + snd_iprintf(buffer, "IEC958 NonAudio: off\n"); + x = hdsp_spdif_sample_rate(hdsp); + if (x != 0) + snd_iprintf(buffer, "IEC958 sample rate: %d\n", x); + else + snd_iprintf(buffer, "IEC958 sample rate: Error flag set\n"); + } snd_iprintf(buffer, "\n"); /* Sync Check */ @@ -3765,7 +4169,7 @@ static irqreturn_t snd_hdsp_interrupt(int irq, void *dev_id) snd_hdsp_midi_input_read (&hdsp->midi[0]); } } - if (hdsp->io_type != Multiface && hdsp->io_type != H9632 && midi1 && midi1status) { + if (hdsp->io_type != Multiface && hdsp->io_type != RPM && hdsp->io_type != H9632 && midi1 && midi1status) { if (hdsp->use_midi_tasklet) { /* we disable interrupts for this input until processing is done */ hdsp->control_register &= ~HDSP_Midi1InterruptEnable; @@ -4093,7 +4497,7 @@ static struct snd_pcm_hardware snd_hdsp_playback_subinfo = SNDRV_PCM_RATE_96000), .rate_min = 32000, .rate_max = 96000, - .channels_min = 14, + .channels_min = 6, .channels_max = HDSP_MAX_CHANNELS, .buffer_bytes_max = HDSP_CHANNEL_BUFFER_BYTES * HDSP_MAX_CHANNELS, .period_bytes_min = (64 * 4) * 10, @@ -4122,7 +4526,7 @@ static struct snd_pcm_hardware snd_hdsp_capture_subinfo = SNDRV_PCM_RATE_96000), .rate_min = 32000, .rate_max = 96000, - .channels_min = 14, + .channels_min = 5, .channels_max = HDSP_MAX_CHANNELS, .buffer_bytes_max = HDSP_CHANNEL_BUFFER_BYTES * HDSP_MAX_CHANNELS, .period_bytes_min = (64 * 4) * 10, @@ -4357,10 +4761,12 @@ static int snd_hdsp_playback_open(struct snd_pcm_substream *substream) snd_hdsp_hw_rule_rate_out_channels, hdsp, SNDRV_PCM_HW_PARAM_CHANNELS, -1); - hdsp->creg_spdif_stream = hdsp->creg_spdif; - hdsp->spdif_ctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE; - snd_ctl_notify(hdsp->card, SNDRV_CTL_EVENT_MASK_VALUE | - SNDRV_CTL_EVENT_MASK_INFO, &hdsp->spdif_ctl->id); + if (RPM != hdsp->io_type) { + hdsp->creg_spdif_stream = hdsp->creg_spdif; + hdsp->spdif_ctl->vd[0].access &= ~SNDRV_CTL_ELEM_ACCESS_INACTIVE; + snd_ctl_notify(hdsp->card, SNDRV_CTL_EVENT_MASK_VALUE | + SNDRV_CTL_EVENT_MASK_INFO, &hdsp->spdif_ctl->id); + } return 0; } @@ -4375,9 +4781,11 @@ static int snd_hdsp_playback_release(struct snd_pcm_substream *substream) spin_unlock_irq(&hdsp->lock); - hdsp->spdif_ctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE; - snd_ctl_notify(hdsp->card, SNDRV_CTL_EVENT_MASK_VALUE | - SNDRV_CTL_EVENT_MASK_INFO, &hdsp->spdif_ctl->id); + if (RPM != hdsp->io_type) { + hdsp->spdif_ctl->vd[0].access |= SNDRV_CTL_ELEM_ACCESS_INACTIVE; + snd_ctl_notify(hdsp->card, SNDRV_CTL_EVENT_MASK_VALUE | + SNDRV_CTL_EVENT_MASK_INFO, &hdsp->spdif_ctl->id); + } return 0; } @@ -4616,7 +5024,7 @@ static int snd_hdsp_hwdep_ioctl(struct snd_hwdep *hw, struct file *file, unsigne if (hdsp->io_type != H9632) info.adatsync_sync_check = (unsigned char)hdsp_adatsync_sync_check(hdsp); info.spdif_sync_check = (unsigned char)hdsp_spdif_sync_check(hdsp); - for (i = 0; i < ((hdsp->io_type != Multiface && hdsp->io_type != H9632) ? 3 : 1); ++i) + for (i = 0; i < ((hdsp->io_type != Multiface && hdsp->io_type != RPM && hdsp->io_type != H9632) ? 3 : 1); ++i) info.adat_sync_check[i] = (unsigned char)hdsp_adat_sync_check(hdsp, i); info.spdif_in = (unsigned char)hdsp_spdif_in(hdsp); info.spdif_out = (unsigned char)hdsp_spdif_out(hdsp); @@ -4636,6 +5044,9 @@ static int snd_hdsp_hwdep_ioctl(struct snd_hwdep *hw, struct file *file, unsigne info.phone_gain = (unsigned char)hdsp_phone_gain(hdsp); info.xlr_breakout_cable = (unsigned char)hdsp_xlr_breakout_cable(hdsp); + } else if (hdsp->io_type == RPM) { + info.da_gain = (unsigned char) hdsp_rpm_input12(hdsp); + info.ad_gain = (unsigned char) hdsp_rpm_input34(hdsp); } if (hdsp->io_type == H9632 || hdsp->io_type == H9652) info.analog_extension_board = (unsigned char)hdsp_aeb(hdsp); @@ -4844,6 +5255,14 @@ static void snd_hdsp_initialize_channels(struct hdsp *hdsp) hdsp->ds_in_channels = hdsp->ds_out_channels = MULTIFACE_DS_CHANNELS; break; + case RPM: + hdsp->card_name = "RME Hammerfall DSP + RPM"; + hdsp->ss_in_channels = RPM_CHANNELS-1; + hdsp->ss_out_channels = RPM_CHANNELS; + hdsp->ds_in_channels = RPM_CHANNELS-1; + hdsp->ds_out_channels = RPM_CHANNELS; + break; + default: /* should never get here */ break; @@ -4930,6 +5349,9 @@ static int hdsp_request_fw_loader(struct hdsp *hdsp) /* caution: max length of firmware filename is 30! */ switch (hdsp->io_type) { + case RPM: + fwfile = "rpm_firmware.bin"; + break; case Multiface: if (hdsp->firmware_rev == 0xa) fwfile = "multiface_firmware.bin"; @@ -5100,7 +5522,9 @@ static int __devinit snd_hdsp_create(struct snd_card *card, return 0; } else { snd_printk(KERN_INFO "Hammerfall-DSP: Firmware already present, initializing card.\n"); - if (hdsp_read(hdsp, HDSP_status2Register) & HDSP_version1) + if (hdsp_read(hdsp, HDSP_status2Register) & HDSP_version2) + hdsp->io_type = RPM; + else if (hdsp_read(hdsp, HDSP_status2Register) & HDSP_version1) hdsp->io_type = Multiface; else hdsp->io_type = Digiface; -- cgit v1.2.3 From 06c6f4d34a23f7c9c783f1a875bb492b15fa23ac Mon Sep 17 00:00:00 2001 From: Jarkko Nikula Date: Wed, 1 Dec 2010 09:10:47 +0200 Subject: ASoC: Fix build failure in soc-core.c Commit 2eea392 "ASoC: Add support for optional auxiliary dailess codecs" causes a build failure in soc-core.c: soc_probe_aux_dev since code tries to access non-existing struct snd_soc_dapm_context and struct snd_soc_card members. Root cause for this was a double accident. Author sent the RFC patch from top of another patch set and the RFC got committed. Fix the build failure by removing the code line that depends on that another patch set. Signed-off-by: Jarkko Nikula Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/soc-core.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index a7670d5ac13d..eb950f73076a 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -1644,7 +1644,6 @@ static int soc_probe_aux_dev(struct snd_soc_card *card, int num) /* mark codec as probed and add to card codec list */ codec->probed = 1; list_add(&codec->card_list, &card->codec_dev_list); - list_add(&codec->dapm.list, &card->dapm_list); /* now that all clients have probed, initialise the DAI link */ if (aux_dev->init) { -- cgit v1.2.3 From b2822a8c22d13bc8c441e1c0492baa40ae974b51 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 30 Nov 2010 16:59:29 +0000 Subject: ASoC: Correct event flags for WM8958 AIF DACs We need a post notification as we need to shut down the MBC after the data stops flowing rather than before. Signed-off-by: Mark Brown Acked-by: Liam Girdwood --- sound/soc/codecs/wm8994.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index bfd4cf4fde5f..51f5cf16b425 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c @@ -1205,10 +1205,10 @@ SND_SOC_DAPM_AIF_OUT("AIF1ADC1R", "AIF1 Capture", 0, WM8994_POWER_MANAGEMENT_4, 8, 0), SND_SOC_DAPM_AIF_IN_E("AIF1DAC1L", NULL, 0, WM8994_POWER_MANAGEMENT_5, 9, 0, wm8958_aif_ev, - SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), SND_SOC_DAPM_AIF_IN_E("AIF1DAC1R", NULL, 0, WM8994_POWER_MANAGEMENT_5, 8, 0, wm8958_aif_ev, - SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), SND_SOC_DAPM_AIF_OUT("AIF1ADC2L", "AIF1 Capture", 0, WM8994_POWER_MANAGEMENT_4, 11, 0), @@ -1216,10 +1216,10 @@ SND_SOC_DAPM_AIF_OUT("AIF1ADC2R", "AIF1 Capture", 0, WM8994_POWER_MANAGEMENT_4, 10, 0), SND_SOC_DAPM_AIF_IN_E("AIF1DAC2L", NULL, 0, WM8994_POWER_MANAGEMENT_5, 11, 0, wm8958_aif_ev, - SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), SND_SOC_DAPM_AIF_IN_E("AIF1DAC2R", NULL, 0, WM8994_POWER_MANAGEMENT_5, 10, 0, wm8958_aif_ev, - SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), SND_SOC_DAPM_MIXER("AIF1ADC1L Mixer", SND_SOC_NOPM, 0, 0, aif1adc1l_mix, ARRAY_SIZE(aif1adc1l_mix)), -- cgit v1.2.3 From 131d81061eba5ffd436b5d132530ac5205b16892 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 30 Nov 2010 17:03:39 +0000 Subject: ASoC: Allow user-specified WM8958 multiband compressor configurations The paramters of the WM8958 multiband compressor can be tuned by the user for their system using a graphical configuration tool on the host. Allow the user to specify a set of such paramters in platform data and select between them at runtime. Signed-off-by: Mark Brown Acked-by: Liam Girdwood --- include/linux/mfd/wm8994/pdata.h | 17 ++++++++ include/linux/mfd/wm8994/registers.h | 68 +++++++++++++++++++++++++++++ sound/soc/codecs/wm8994.c | 84 +++++++++++++++++++++++++++++++++++- 3 files changed, 167 insertions(+), 2 deletions(-) diff --git a/include/linux/mfd/wm8994/pdata.h b/include/linux/mfd/wm8994/pdata.h index 5c51f367c061..882b51aefbc0 100644 --- a/include/linux/mfd/wm8994/pdata.h +++ b/include/linux/mfd/wm8994/pdata.h @@ -30,6 +30,8 @@ struct wm8994_ldo_pdata { #define WM8994_DRC_REGS 5 #define WM8994_EQ_REGS 19 +#define WM8958_MBC_CUTOFF_REGS 20 +#define WM8958_MBC_COEFF_REGS 48 /** * DRC configurations are specified with a label and a set of register @@ -59,6 +61,18 @@ struct wm8994_retune_mobile_cfg { u16 regs[WM8994_EQ_REGS]; }; +/** + * Multiband compressor configurations are specified with a label and + * two sets of values to write. Configurations are expected to be + * generated using the multiband compressor configuration panel in + * WISCE - see http://www.wolfsonmicro.com/wisce/ + */ +struct wm8958_mbc_cfg { + const char *name; + u16 cutoff_regs[WM8958_MBC_CUTOFF_REGS]; + u16 coeff_regs[WM8958_MBC_COEFF_REGS]; +}; + struct wm8994_pdata { int gpio_base; @@ -78,6 +92,9 @@ struct wm8994_pdata { int num_retune_mobile_cfgs; struct wm8994_retune_mobile_cfg *retune_mobile_cfgs; + int num_mbc_cfgs; + struct wm8958_mbc_cfg *mbc_cfgs; + /* LINEOUT can be differential or single ended */ unsigned int lineout1_diff:1; unsigned int lineout2_diff:1; diff --git a/include/linux/mfd/wm8994/registers.h b/include/linux/mfd/wm8994/registers.h index a610c8746436..ccf3a774fe36 100644 --- a/include/linux/mfd/wm8994/registers.h +++ b/include/linux/mfd/wm8994/registers.h @@ -258,6 +258,74 @@ #define WM8958_DSP2_VERMAJMIN 0xA04 #define WM8958_DSP2_VERBUILD 0xA05 #define WM8958_DSP2_EXECCONTROL 0xA0D +#define WM8958_MBC_BAND_2_LOWER_CUTOFF_C1_1 0x2200 +#define WM8958_MBC_BAND_2_LOWER_CUTOFF_C1_2 0x2201 +#define WM8958_MBC_BAND_2_LOWER_CUTOFF_C2_1 0x2202 +#define WM8958_MBC_BAND_2_LOWER_CUTOFF_C2_2 0x2203 +#define WM8958_MBC_BAND_2_LOWER_CUTOFF_C3_1 0x2204 +#define WM8958_MBC_BAND_2_LOWER_CUTOFF_C3_2 0x2205 +#define WM8958_MBC_BAND_2_UPPER_CUTOFF_C2_1 0x2206 +#define WM8958_MBC_BAND_2_UPPER_CUTOFF_C2_2 0x2207 +#define WM8958_MBC_BAND_2_UPPER_CUTOFF_C3_1 0x2208 +#define WM8958_MBC_BAND_2_UPPER_CUTOFF_C3_2 0x2209 +#define WM8958_MBC_BAND_2_UPPER_CUTOFF_C1_1 0x220A +#define WM8958_MBC_BAND_2_UPPER_CUTOFF_C1_2 0x220B +#define WM8958_MBC_BAND_1_UPPER_CUTOFF_C1_1 0x220C +#define WM8958_MBC_BAND_1_UPPER_CUTOFF_C1_2 0x220D +#define WM8958_MBC_BAND_1_UPPER_CUTOFF_C2_1 0x220E +#define WM8958_MBC_BAND_1_UPPER_CUTOFF_C2_2 0x220F +#define WM8958_MBC_BAND_1_UPPER_CUTOFF_C3_1 0x2210 +#define WM8958_MBC_BAND_1_UPPER_CUTOFF_C3_2 0x2211 +#define WM8958_MBC_BAND_1_LOWER_CUTOFF_1 0x2212 +#define WM8958_MBC_BAND_1_LOWER_CUTOFF_2 0x2213 +#define WM8958_MBC_BAND_1_K_1 0x2400 +#define WM8958_MBC_BAND_1_K_2 0x2401 +#define WM8958_MBC_BAND_1_N1_1 0x2402 +#define WM8958_MBC_BAND_1_N1_2 0x2403 +#define WM8958_MBC_BAND_1_N2_1 0x2404 +#define WM8958_MBC_BAND_1_N2_2 0x2405 +#define WM8958_MBC_BAND_1_N3_1 0x2406 +#define WM8958_MBC_BAND_1_N3_2 0x2407 +#define WM8958_MBC_BAND_1_N4_1 0x2408 +#define WM8958_MBC_BAND_1_N4_2 0x2409 +#define WM8958_MBC_BAND_1_N5_1 0x240A +#define WM8958_MBC_BAND_1_N5_2 0x240B +#define WM8958_MBC_BAND_1_X1_1 0x240C +#define WM8958_MBC_BAND_1_X1_2 0x240D +#define WM8958_MBC_BAND_1_X2_1 0x240E +#define WM8958_MBC_BAND_1_X2_2 0x240F +#define WM8958_MBC_BAND_1_X3_1 0x2410 +#define WM8958_MBC_BAND_1_X3_2 0x2411 +#define WM8958_MBC_BAND_1_ATTACK_1 0x2412 +#define WM8958_MBC_BAND_1_ATTACK_2 0x2413 +#define WM8958_MBC_BAND_1_DECAY_1 0x2414 +#define WM8958_MBC_BAND_1_DECAY_2 0x2415 +#define WM8958_MBC_BAND_2_K_1 0x2416 +#define WM8958_MBC_BAND_2_K_2 0x2417 +#define WM8958_MBC_BAND_2_N1_1 0x2418 +#define WM8958_MBC_BAND_2_N1_2 0x2419 +#define WM8958_MBC_BAND_2_N2_1 0x241A +#define WM8958_MBC_BAND_2_N2_2 0x241B +#define WM8958_MBC_BAND_2_N3_1 0x241C +#define WM8958_MBC_BAND_2_N3_2 0x241D +#define WM8958_MBC_BAND_2_N4_1 0x241E +#define WM8958_MBC_BAND_2_N4_2 0x241F +#define WM8958_MBC_BAND_2_N5_1 0x2420 +#define WM8958_MBC_BAND_2_N5_2 0x2421 +#define WM8958_MBC_BAND_2_X1_1 0x2422 +#define WM8958_MBC_BAND_2_X1_2 0x2423 +#define WM8958_MBC_BAND_2_X2_1 0x2424 +#define WM8958_MBC_BAND_2_X2_2 0x2425 +#define WM8958_MBC_BAND_2_X3_1 0x2426 +#define WM8958_MBC_BAND_2_X3_2 0x2427 +#define WM8958_MBC_BAND_2_ATTACK_1 0x2428 +#define WM8958_MBC_BAND_2_ATTACK_2 0x2429 +#define WM8958_MBC_BAND_2_DECAY_1 0x242A +#define WM8958_MBC_BAND_2_DECAY_2 0x242B +#define WM8958_MBC_B2_PG2_1 0x242C +#define WM8958_MBC_B2_PG2_2 0x242D +#define WM8958_MBC_B1_PG2_1 0x242E +#define WM8958_MBC_B1_PG2_2 0x242F #define WM8994_WRITE_SEQUENCER_0 0x3000 #define WM8994_WRITE_SEQUENCER_1 0x3001 #define WM8994_WRITE_SEQUENCER_2 0x3002 diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index 51f5cf16b425..59d361145b15 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c @@ -92,6 +92,11 @@ struct wm8994_priv { int retune_mobile_cfg[WM8994_NUM_EQ]; struct soc_enum retune_mobile_enum; + /* Platform dependant MBC configuration */ + int mbc_cfg; + const char **mbc_texts; + struct soc_enum mbc_enum; + struct wm8994_micdet micdet[2]; wm8958_micdet_cb jack_cb; @@ -543,8 +548,9 @@ static const struct soc_enum aif2dacr_src = static void wm8958_mbc_apply(struct snd_soc_codec *codec, int mbc, int start) { struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); + struct wm8994_pdata *pdata = wm8994->pdata; int pwr_reg = snd_soc_read(codec, WM8994_POWER_MANAGEMENT_5); - int ena, reg, aif; + int ena, reg, aif, i; switch (mbc) { case 0: @@ -587,7 +593,20 @@ static void wm8958_mbc_apply(struct snd_soc_codec *codec, int mbc, int start) snd_soc_update_bits(codec, WM8958_DSP2_PROGRAM, WM8958_DSP2_ENA, WM8958_DSP2_ENA); - /* TODO: Apply any user specified MBC settings */ + /* If we've got user supplied MBC settings use them */ + if (pdata && pdata->num_mbc_cfgs) { + struct wm8958_mbc_cfg *cfg + = &pdata->mbc_cfgs[wm8994->mbc_cfg]; + + for (i = 0; i < ARRAY_SIZE(cfg->coeff_regs); i++) + snd_soc_write(codec, i + WM8958_MBC_BAND_1_K_1, + cfg->coeff_regs[i]); + + for (i = 0; i < ARRAY_SIZE(cfg->cutoff_regs); i++) + snd_soc_write(codec, + i + WM8958_MBC_BAND_2_LOWER_CUTOFF_C1_1, + cfg->cutoff_regs[i]); + } /* Run the DSP */ snd_soc_write(codec, WM8958_DSP2_EXECCONTROL, @@ -648,6 +667,39 @@ static int wm8958_aif_ev(struct snd_soc_dapm_widget *w, return 0; } +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 wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); + struct wm8994_pdata *pdata = wm8994->pdata; + int value = ucontrol->value.integer.value[0]; + int reg; + + /* Don't allow on the fly reconfiguration */ + reg = snd_soc_read(codec, WM8994_CLOCKING_1); + if (reg < 0 || reg & WM8958_DSP2CLK_ENA) + return -EBUSY; + + if (value >= pdata->num_mbc_cfgs) + return -EINVAL; + + wm8994->mbc_cfg = value; + + return 0; +} + +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 wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); + + ucontrol->value.enumerated.item[0] = wm8994->mbc_cfg; + + return 0; +} + static int wm8958_mbc_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { @@ -2539,6 +2591,34 @@ static void wm8994_handle_pdata(struct wm8994_priv *wm8994) dev_dbg(codec->dev, "%d ReTune Mobile configurations\n", pdata->num_retune_mobile_cfgs); + if (pdata->num_mbc_cfgs) { + struct snd_kcontrol_new control[] = { + SOC_ENUM_EXT("MBC Mode", wm8994->mbc_enum, + wm8958_get_mbc_enum, wm8958_put_mbc_enum), + }; + + /* We need an array of texts for the enum API */ + wm8994->mbc_texts = kmalloc(sizeof(char *) + * pdata->num_mbc_cfgs, GFP_KERNEL); + if (!wm8994->mbc_texts) { + dev_err(wm8994->codec->dev, + "Failed to allocate %d MBC config texts\n", + pdata->num_mbc_cfgs); + return; + } + + for (i = 0; i < pdata->num_mbc_cfgs; i++) + wm8994->mbc_texts[i] = pdata->mbc_cfgs[i].name; + + wm8994->mbc_enum.max = pdata->num_mbc_cfgs; + wm8994->mbc_enum.texts = wm8994->mbc_texts; + + ret = snd_soc_add_controls(wm8994->codec, control, 1); + if (ret != 0) + dev_err(wm8994->codec->dev, + "Failed to add MBC mode controls: %d\n", ret); + } + if (pdata->num_retune_mobile_cfgs) wm8994_handle_retune_mobile_pdata(wm8994); else -- cgit v1.2.3 From 437f6a2b25becc0a2c2cfe02ce78d65a4957e5d8 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 1 Dec 2010 15:50:42 +0900 Subject: ASoC: sh: fsi-ak4642: tidyup unnecessary variables Signed-off-by: Kuninori Morimoto Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/sh/fsi-ak4642.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/sound/soc/sh/fsi-ak4642.c b/sound/soc/sh/fsi-ak4642.c index 4ef279c504db..839ba6cc2120 100644 --- a/sound/soc/sh/fsi-ak4642.c +++ b/sound/soc/sh/fsi-ak4642.c @@ -34,14 +34,8 @@ static int fsi_ak4642_dai_init(struct snd_soc_pcm_runtime *rtd) } static struct snd_soc_dai_link fsi_dai_link = { - /* .name */ - /* .stream_name */ - /* .cpu_dai_name */ .codec_dai_name = "ak4642-hifi", - /* .platform_name */ - /* .codec_name */ .init = fsi_ak4642_dai_init, - .ops = NULL, }; static struct snd_soc_card fsi_soc_card = { -- cgit v1.2.3 From 806bfedfb124b85d2e2b8ecdb8a451b23abed386 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 1 Dec 2010 15:50:52 +0900 Subject: ASoC: sh: fsi-ak4642: midify card name Signed-off-by: Kuninori Morimoto Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/sh/fsi-ak4642.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/sound/soc/sh/fsi-ak4642.c b/sound/soc/sh/fsi-ak4642.c index 839ba6cc2120..a14820ac9665 100644 --- a/sound/soc/sh/fsi-ak4642.c +++ b/sound/soc/sh/fsi-ak4642.c @@ -14,6 +14,7 @@ struct fsi_ak4642_data { const char *name; + const char *card; const char *cpu_dai; const char *codec; const char *platform; @@ -39,7 +40,6 @@ static struct snd_soc_dai_link fsi_dai_link = { }; static struct snd_soc_card fsi_soc_card = { - .name = "FSI (AK4642)", .dai_link = &fsi_dai_link, .num_links = 1, }; @@ -69,6 +69,7 @@ static int fsi_ak4642_probe(struct platform_device *pdev) fsi_dai_link.cpu_dai_name = pdata->cpu_dai; fsi_dai_link.platform_name = pdata->platform; fsi_dai_link.codec_name = pdata->codec; + fsi_soc_card.name = pdata->card; platform_set_drvdata(fsi_snd_device, &fsi_soc_card); ret = platform_device_add(fsi_snd_device); @@ -88,6 +89,7 @@ static int fsi_ak4642_remove(struct platform_device *pdev) static struct fsi_ak4642_data fsi_a_ak4642 = { .name = "AK4642", + .card = "FSIA (AK4642)", .cpu_dai = "fsia-dai", .codec = "ak4642-codec.0-0012", .platform = "sh_fsi.0", @@ -95,6 +97,7 @@ static struct fsi_ak4642_data fsi_a_ak4642 = { static struct fsi_ak4642_data fsi_b_ak4642 = { .name = "AK4642", + .card = "FSIB (AK4642)", .cpu_dai = "fsib-dai", .codec = "ak4642-codec.0-0012", .platform = "sh_fsi.0", @@ -102,6 +105,7 @@ static struct fsi_ak4642_data fsi_b_ak4642 = { static struct fsi_ak4642_data fsi_a_ak4643 = { .name = "AK4643", + .card = "FSIA (AK4643)", .cpu_dai = "fsia-dai", .codec = "ak4642-codec.0-0013", .platform = "sh_fsi.0", @@ -109,6 +113,7 @@ static struct fsi_ak4642_data fsi_a_ak4643 = { static struct fsi_ak4642_data fsi_b_ak4643 = { .name = "AK4643", + .card = "FSIB (AK4643)", .cpu_dai = "fsib-dai", .codec = "ak4642-codec.0-0013", .platform = "sh_fsi.0", @@ -116,6 +121,7 @@ static struct fsi_ak4642_data fsi_b_ak4643 = { static struct fsi_ak4642_data fsi2_a_ak4642 = { .name = "AK4642", + .card = "FSI2A (AK4642)", .cpu_dai = "fsia-dai", .codec = "ak4642-codec.0-0012", .platform = "sh_fsi2", @@ -123,6 +129,7 @@ static struct fsi_ak4642_data fsi2_a_ak4642 = { static struct fsi_ak4642_data fsi2_b_ak4642 = { .name = "AK4642", + .card = "FSI2B (AK4642)", .cpu_dai = "fsib-dai", .codec = "ak4642-codec.0-0012", .platform = "sh_fsi2", @@ -130,6 +137,7 @@ static struct fsi_ak4642_data fsi2_b_ak4642 = { static struct fsi_ak4642_data fsi2_a_ak4643 = { .name = "AK4643", + .card = "FSI2A (AK4643)", .cpu_dai = "fsia-dai", .codec = "ak4642-codec.0-0013", .platform = "sh_fsi2", @@ -137,6 +145,7 @@ static struct fsi_ak4642_data fsi2_a_ak4643 = { static struct fsi_ak4642_data fsi2_b_ak4643 = { .name = "AK4643", + .card = "FSI2B (AK4643)", .cpu_dai = "fsib-dai", .codec = "ak4642-codec.0-0013", .platform = "sh_fsi2", -- cgit v1.2.3 From cca67a3668392857641e9440ca6dc16a48b12e37 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Wed, 1 Dec 2010 17:22:34 +0800 Subject: ASoC: ak4535: Improve readability for setting mute The mute/unmute is controled by SMUTE (Soft Mute Control bit): 0: Normal Operation (Default) 1: DAC outputs soft-muted I think this change improves readability. Signed-off-by: Axel Lin Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/codecs/ak4535.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/sound/soc/codecs/ak4535.c b/sound/soc/codecs/ak4535.c index 73675458076d..8b38739c88f8 100644 --- a/sound/soc/codecs/ak4535.c +++ b/sound/soc/codecs/ak4535.c @@ -366,9 +366,9 @@ static int ak4535_set_dai_fmt(struct snd_soc_dai *codec_dai, static int ak4535_mute(struct snd_soc_dai *dai, int mute) { struct snd_soc_codec *codec = dai->codec; - u16 mute_reg = ak4535_read_reg_cache(codec, AK4535_DAC) & 0xffdf; + u16 mute_reg = ak4535_read_reg_cache(codec, AK4535_DAC); if (!mute) - ak4535_write(codec, AK4535_DAC, mute_reg); + ak4535_write(codec, AK4535_DAC, mute_reg & ~0x20); else ak4535_write(codec, AK4535_DAC, mute_reg | 0x20); return 0; @@ -381,11 +381,11 @@ static int ak4535_set_bias_level(struct snd_soc_codec *codec, switch (level) { case SND_SOC_BIAS_ON: - mute_reg = ak4535_read_reg_cache(codec, AK4535_DAC) & 0xffdf; - ak4535_write(codec, AK4535_DAC, mute_reg); + mute_reg = ak4535_read_reg_cache(codec, AK4535_DAC); + ak4535_write(codec, AK4535_DAC, mute_reg & ~0x20); break; case SND_SOC_BIAS_PREPARE: - mute_reg = ak4535_read_reg_cache(codec, AK4535_DAC) & 0xffdf; + mute_reg = ak4535_read_reg_cache(codec, AK4535_DAC); ak4535_write(codec, AK4535_DAC, mute_reg | 0x20); break; case SND_SOC_BIAS_STANDBY: -- cgit v1.2.3 From ac5435b9800f313bdcd6a43444ceb1d89f241a5e Mon Sep 17 00:00:00 2001 From: Pekka Enberg Date: Sun, 28 Nov 2010 22:59:56 +0200 Subject: Staging: w35und: Remove unused defines from sysdef.h This patch removes all the defines in sysdef.h that are not used at all. Cc: Pavel Machek Signed-off-by: Pekka Enberg Signed-off-by: Greg Kroah-Hartman --- drivers/staging/winbond/sysdef.h | 6 ------ 1 file changed, 6 deletions(-) diff --git a/drivers/staging/winbond/sysdef.h b/drivers/staging/winbond/sysdef.h index 9195adf98e14..7198708108bb 100644 --- a/drivers/staging/winbond/sysdef.h +++ b/drivers/staging/winbond/sysdef.h @@ -2,17 +2,11 @@ #ifndef SYS_DEF_H #define SYS_DEF_H -#define WB_LINUX -#define WB_LINUX_WPA_PSK #define _USE_FALLBACK_RATE_ #define _WPA2_ -#ifndef _WPA_PSK_DEBUG -#undef _WPA_PSK_DEBUG -#endif - /* debug print options, mark what debug you don't need */ #ifdef FULL_DEBUG -- cgit v1.2.3 From 1140bd9f30f4d6dac6b53365a70819ecd4cc8c54 Mon Sep 17 00:00:00 2001 From: Pekka Enberg Date: Sun, 28 Nov 2010 22:59:57 +0200 Subject: Staging: w35und: Kill _USE_FALLBACK_RATE_ macro The _USE_FALLBACK_RATE_ macro parametrizes DEFAULT_RATE_RETRY_LIMIT. It's only used in Mxx_initial() in reg.c where _USE_FALLBACK_RATE_ is always defined because the reg.c file includes sysdef.h at the top. It's therefore safe to remove the _USE_FALLBACK_RATE_ macro. Cc: Pavel Machek Signed-off-by: Pekka Enberg Signed-off-by: Greg Kroah-Hartman --- drivers/staging/winbond/sysdef.h | 2 -- drivers/staging/winbond/wb35reg_s.h | 4 ---- 2 files changed, 6 deletions(-) diff --git a/drivers/staging/winbond/sysdef.h b/drivers/staging/winbond/sysdef.h index 7198708108bb..f8d8606a4efa 100644 --- a/drivers/staging/winbond/sysdef.h +++ b/drivers/staging/winbond/sysdef.h @@ -3,8 +3,6 @@ #ifndef SYS_DEF_H #define SYS_DEF_H -#define _USE_FALLBACK_RATE_ - #define _WPA2_ /* debug print options, mark what debug you don't need */ diff --git a/drivers/staging/winbond/wb35reg_s.h b/drivers/staging/winbond/wb35reg_s.h index 9d5993bfc1f4..9b782ededf43 100644 --- a/drivers/staging/winbond/wb35reg_s.h +++ b/drivers/staging/winbond/wb35reg_s.h @@ -51,11 +51,7 @@ struct hw_data; #define DEFAULT_CWMAX 1023 /* (M2C) CWmax. Its value is in the range 0-1023. */ #define DEFAULT_AID 1 /* (M34) AID. Its value is in the range 1-2007. */ -#ifdef _USE_FALLBACK_RATE_ #define DEFAULT_RATE_RETRY_LIMIT 2 /* (M38) as named */ -#else -#define DEFAULT_RATE_RETRY_LIMIT 7 /* (M38) as named */ -#endif #define DEFAULT_LONG_RETRY_LIMIT 7 /* (M38) LongRetryLimit. Its value is in the range 0-15. */ #define DEFAULT_SHORT_RETRY_LIMIT 7 /* (M38) ShortRetryLimit. Its value is in the range 0-15. */ -- cgit v1.2.3 From c84fa49f61798b6248cef56876f1643db3b7b2f3 Mon Sep 17 00:00:00 2001 From: Pekka Enberg Date: Sun, 28 Nov 2010 22:59:58 +0200 Subject: Staging: w35und: Kill WPA2 definitions The _WPA2_ macro is always defined but the data structures that are wrapped by it are never used. Kill them. Cc: Pavel Machek Signed-off-by: Pekka Enberg Signed-off-by: Greg Kroah-Hartman --- drivers/staging/winbond/mac_structures.h | 46 -------------------------------- drivers/staging/winbond/sysdef.h | 2 -- 2 files changed, 48 deletions(-) diff --git a/drivers/staging/winbond/mac_structures.h b/drivers/staging/winbond/mac_structures.h index ed3df2964065..91c550e94d87 100644 --- a/drivers/staging/winbond/mac_structures.h +++ b/drivers/staging/winbond/mac_structures.h @@ -111,9 +111,6 @@ /* -- WPA -- */ #define ELEMENT_ID_RSN_WPA 221 -#ifdef _WPA2_ -#define ELEMENT_ID_RSN_WPA2 48 -#endif /* endif WPA2 */ #define WLAN_MAX_PAIRWISE_CIPHER_SUITE_COUNT ((u16) 6) #define WLAN_MAX_AUTH_KEY_MGT_SUITE_LIST_COUNT ((u16) 2) @@ -367,21 +364,11 @@ struct Extended_Supported_Rates_Element { /* WPA(802.11i draft 3.0) */ #define VERSION_WPA 1 -#ifdef _WPA2_ -#define VERSION_WPA2 1 -#endif /* end def _WPA2_ */ /* WPA2.0 OUI=00:50:F2, the MSB is reserved for suite type */ #define OUI_WPA 0x00F25000 -#ifdef _WPA2_ -/* for wpa2 change to 0x00ACOF04 by Ws 26/04/04 */ -#define OUI_WPA2 0x00AC0F00 -#endif /* end def _WPA2_ */ #define OUI_WPA_ADDITIONAL 0x01 #define WLAN_MIN_RSN_WPA_LENGTH 6 /* added by ws 09/10/04 */ -#ifdef _WPA2_ -#define WLAN_MIN_RSN_WPA2_LENGTH 2 /* Fix to 2 09/14/05 */ -#endif /* end def _WPA2_ */ #define oui_wpa (u32)(OUI_WPA|OUI_WPA_ADDITIONAL) @@ -390,12 +377,6 @@ struct Extended_Supported_Rates_Element { /* 20061108 For WPS. It's little endian. Big endian is 0x0050F204 */ #define WPA_WPS_OUI cpu_to_le32(0x04F25000) -/* -----WPA2----- */ -#ifdef _WPA2_ -#define WPA2_OUI_BIG ((u32)0x01AC0F00) -#define WPA2_OUI_LITTLE ((u32)0x01AC0F01) -#endif /* end def _WPA2_ */ - /* Authentication suite */ #define OUI_AUTH_WPA_NONE 0x00 /* for WPA_NONE */ #define OUI_AUTH_8021X 0x01 @@ -460,33 +441,6 @@ struct RSN_Capability_Element { } __attribute__ ((packed)) ; } __attribute__ ((packed)) ; -#ifdef _WPA2_ -struct pmkid { - u8 pValue[16]; -}; - -struct WPA2_RSN_Information_Element { - u8 Element_ID; - u8 Length; - u16 Version; - struct suite_selector GroupKeySuite; - u16 PairwiseKeySuiteCount; - struct suite_selector PairwiseKeySuite[1]; - -} __attribute__ ((packed)); - -struct WPA2_RSN_Auth_Sub_Information_Element { - u16 AuthKeyMngtSuiteCount; - struct suite_selector AuthKeyMngtSuite[1]; -} __attribute__ ((packed)); - - -struct PMKID_Information_Element { - u16 PMKID_Count; - struct pmkid pmkid[16]; -} __attribute__ ((packed)); - -#endif /* enddef _WPA2_ */ /*============================================================ // MAC Frame structure (different type) and subfield structure //============================================================*/ diff --git a/drivers/staging/winbond/sysdef.h b/drivers/staging/winbond/sysdef.h index f8d8606a4efa..8d4ebe15d930 100644 --- a/drivers/staging/winbond/sysdef.h +++ b/drivers/staging/winbond/sysdef.h @@ -3,8 +3,6 @@ #ifndef SYS_DEF_H #define SYS_DEF_H -#define _WPA2_ - /* debug print options, mark what debug you don't need */ #ifdef FULL_DEBUG -- cgit v1.2.3 From a4170e3dddc5eb88d23dd5f6e7c9cdefc244001e Mon Sep 17 00:00:00 2001 From: Pekka Enberg Date: Sun, 28 Nov 2010 22:59:59 +0200 Subject: Staging: w35und: Kill unused code in mac_structures.h This patch kills tons of unused macros and struct definitions from mac_structures.h. Cc: Pavel Machek Signed-off-by: Pekka Enberg Signed-off-by: Greg Kroah-Hartman --- drivers/staging/winbond/mac_structures.h | 499 ------------------------------- 1 file changed, 499 deletions(-) diff --git a/drivers/staging/winbond/mac_structures.h b/drivers/staging/winbond/mac_structures.h index 91c550e94d87..76c63c74d50c 100644 --- a/drivers/staging/winbond/mac_structures.h +++ b/drivers/staging/winbond/mac_structures.h @@ -21,23 +21,11 @@ #ifndef _MAC_Structures_H_ #define _MAC_Structures_H_ -#include - -/*========================================================= -// Some miscellaneous definitions -//-----*/ -#define MAX_CHANNELS 30 #define MAC_ADDR_LENGTH 6 -#define MAX_WEP_KEY_SIZE 16 /* 128 bits */ -#define MAX_802_11_FRAGMENT_NUMBER 10 /* By spec */ /* ======================================================== // 802.11 Frame define //----- */ -#define MASK_PROTOCOL_VERSION_TYPE 0x0F -#define MASK_FRAGMENT_NUMBER 0x000F -#define SEQUENCE_NUMBER_SHIFT 4 -#define DIFFER_11_TO_3 18 #define DOT_11_MAC_HEADER_SIZE 24 #define DOT_11_SNAP_SIZE 6 #define DOT_11_DURATION_OFFSET 2 @@ -47,15 +35,9 @@ #define DOT_11_TYPE_OFFSET 30 #define DOT_11_DATA_OFFSET 24 #define DOT_11_DA_OFFSET 4 -#define DOT_3_TYPE_ARP 0x80F3 -#define DOT_3_TYPE_IPX 0x8137 -#define DOT_3_TYPE_OFFSET 12 - -#define ETHERNET_HEADER_SIZE 14 #define MAX_ETHERNET_PACKET_SIZE 1514 - /* ----- management : Type of Bits (2, 3) and Subtype of Bits (4, 5, 6, 7) */ #define MAC_SUBTYPE_MNGMNT_ASSOC_REQUEST 0x00 #define MAC_SUBTYPE_MNGMNT_ASSOC_RESPONSE 0x10 @@ -69,126 +51,6 @@ #define MAC_SUBTYPE_MNGMNT_AUTHENTICATION 0xB0 #define MAC_SUBTYPE_MNGMNT_DEAUTHENTICATION 0xC0 -/* ----- control : Type of Bits (2, 3) and Subtype of Bits (4, 5, 6, 7) */ -#define MAC_SUBTYPE_CONTROL_PSPOLL 0xA4 -#define MAC_SUBTYPE_CONTROL_RTS 0xB4 -#define MAC_SUBTYPE_CONTROL_CTS 0xC4 -#define MAC_SUBTYPE_CONTROL_ACK 0xD4 -#define MAC_SUBTYPE_CONTROL_CFEND 0xE4 -#define MAC_SUBTYPE_CONTROL_CFEND_CFACK 0xF4 - -/* ----- data : Type of Bits (2, 3) and Subtype of Bits (4, 5, 6, 7) */ -#define MAC_SUBTYPE_DATA 0x08 -#define MAC_SUBTYPE_DATA_CFACK 0x18 -#define MAC_SUBTYPE_DATA_CFPOLL 0x28 -#define MAC_SUBTYPE_DATA_CFACK_CFPOLL 0x38 -#define MAC_SUBTYPE_DATA_NULL 0x48 -#define MAC_SUBTYPE_DATA_CFACK_NULL 0x58 -#define MAC_SUBTYPE_DATA_CFPOLL_NULL 0x68 -#define MAC_SUBTYPE_DATA_CFACK_CFPOLL_NULL 0x78 - -/* ----- Frame Type of Bits (2, 3) */ -#define MAC_TYPE_MANAGEMENT 0x00 -#define MAC_TYPE_CONTROL 0x04 -#define MAC_TYPE_DATA 0x08 - -/* ----- definitions for Management Frame Element ID (1 BYTE) */ -#define ELEMENT_ID_SSID 0 -#define ELEMENT_ID_SUPPORTED_RATES 1 -#define ELEMENT_ID_FH_PARAMETER_SET 2 -#define ELEMENT_ID_DS_PARAMETER_SET 3 -#define ELEMENT_ID_CF_PARAMETER_SET 4 -#define ELEMENT_ID_TIM 5 -#define ELEMENT_ID_IBSS_PARAMETER_SET 6 -/* 7~15 reserverd */ -#define ELEMENT_ID_CHALLENGE_TEXT 16 -/* 17~31 reserved for challenge text extension */ -/* 32~255 reserved */ -/*-- 11G -- */ -#define ELEMENT_ID_ERP_INFORMATION 42 -#define ELEMENT_ID_EXTENDED_SUPPORTED_RATES 50 - -/* -- WPA -- */ - -#define ELEMENT_ID_RSN_WPA 221 - -#define WLAN_MAX_PAIRWISE_CIPHER_SUITE_COUNT ((u16) 6) -#define WLAN_MAX_AUTH_KEY_MGT_SUITE_LIST_COUNT ((u16) 2) - -/* =================================================================== -* Reason Code (Table 18): indicate the reason of DisAssoc, DeAuthen -* length of ReasonCode is 2 Octs. -* =================================================================== */ -#define REASON_REASERED 0 -#define REASON_UNSPECIDIED 1 -#define REASON_PREAUTH_INVALID 2 -#define DEAUTH_REASON_LEFT_BSS 3 -#define DISASS_REASON_AP_INACTIVE 4 -#define DISASS_REASON_AP_BUSY 5 -#define REASON_CLASS2_FRAME_FROM_NONAUTH_STA 6 -#define REASON_CLASS3_FRAME_FROM_NONASSO_STA 7 -#define DISASS_REASON_LEFT_BSS 8 -#define REASON_NOT_AUTH_YET 9 -/* 802.11i define */ -#define REASON_INVALID_IE 13 -#define REASON_MIC_ERROR 14 -#define REASON_4WAY_HANDSHAKE_TIMEOUT 15 -#define REASON_GROUPKEY_UPDATE_TIMEOUT 16 -#define REASON_IE_DIFF_4WAY_ASSOC 17 -#define REASON_INVALID_MULTICAST_CIPHER 18 -#define REASON_INVALID_UNICAST_CIPHER 19 -#define REASON_INVALID_AKMP 20 -#define REASON_UNSUPPORTED_RSNIE_VERSION 21 -#define REASON_INVALID_RSNIE_CAPABILITY 22 -#define REASON_802_1X_AUTH_FAIL 23 -#define REASON_CIPHER_REJECT_PER_SEC_POLICY 14 - -/* -//=========================================================== -// enum_MMPDUResultCode -- -// Status code (2 Octs) in the MMPDU's frame body. Table.19 -// -//=========================================================== -enum enum_MMPDUResultCode -{ -// SUCCESS = 0, // Redefined - UNSPECIFIED_FAILURE = 1, - - // 2 - 9 Reserved - - NOT_SUPPROT_CAPABILITIES = 10, - - //REASSOCIATION_DENIED - // - REASSOC_DENIED_UNABLE_CFM_ASSOC_EXIST = 11, - - //ASSOCIATION_DENIED_NOT_IN_STANDARD - // - ASSOC_DENIED_REASON_NOT_IN_STANDARD = 12, - PEER_NOT_SUPPORT_AUTH_ALGORITHM = 13, - AUTH_SEQNUM_OUT_OF_EXPECT = 14, - AUTH_REJECT_REASON_CHALLENGE_FAIL = 15, - AUTH_REJECT_REASON_WAIT_TIMEOUT = 16, - ASSOC_DENIED_REASON_AP_BUSY = 17, - ASSOC_DENIED_REASON_NOT_SUPPORT_BASIC_RATE = 18 -} WB_MMPDURESULTCODE, *PWB_MMPDURESULTCODE; -*/ - -#define RATE_BITMAP_1M 1 -#define RATE_BITMAP_2M 2 -#define RATE_BITMAP_5dot5M 5 -#define RATE_BITMAP_6M 6 -#define RATE_BITMAP_9M 9 -#define RATE_BITMAP_11M 11 -#define RATE_BITMAP_12M 12 -#define RATE_BITMAP_18M 18 -#define RATE_BITMAP_22M 22 -#define RATE_BITMAP_24M 24 -#define RATE_BITMAP_33M 17 -#define RATE_BITMAP_36M 19 -#define RATE_BITMAP_48M 25 -#define RATE_BITMAP_54M 28 - #define RATE_AUTO 0 #define RATE_1M 2 #define RATE_2M 4 @@ -206,365 +68,4 @@ enum enum_MMPDUResultCode #define RATE_54M 108 #define RATE_MAX 255 -/* CAPABILITY */ -#define CAPABILITY_ESS_BIT 0x0001 -#define CAPABILITY_IBSS_BIT 0x0002 -#define CAPABILITY_CF_POLL_BIT 0x0004 -#define CAPABILITY_CF_POLL_REQ_BIT 0x0008 -#define CAPABILITY_PRIVACY_BIT 0x0010 -#define CAPABILITY_SHORT_PREAMBLE_BIT 0x0020 -#define CAPABILITY_PBCC_BIT 0x0040 -#define CAPABILITY_CHAN_AGILITY_BIT 0x0080 -#define CAPABILITY_SHORT_SLOT_TIME_BIT 0x0400 -#define CAPABILITY_DSSS_OFDM_BIT 0x2000 - - -struct Capability_Information_Element { - union { - u16 __attribute__ ((packed)) wValue; - #ifdef _BIG_ENDIAN_ /* 20060926 add by anson's endian */ - struct _Capability { - /* -- 11G -- */ - u8 Reserved3:2; - u8 DSSS_OFDM:1; - u8 Reserved2:2; - u8 Short_Slot_Time:1; - u8 Reserved1:2; - u8 Channel_Agility:1; - u8 PBCC:1; - u8 ShortPreamble:1; - u8 CF_Privacy:1; - u8 CF_Poll_Request:1; - u8 CF_Pollable:1; - u8 IBSS:1; - u8 ESS:1; - } __attribute__ ((packed)) Capability; - #else - struct _Capability { - u8 ESS:1; - u8 IBSS:1; - u8 CF_Pollable:1; - u8 CF_Poll_Request:1; - u8 CF_Privacy:1; - u8 ShortPreamble:1; - u8 PBCC:1; - u8 Channel_Agility:1; - u8 Reserved1:2; - /* -- 11G -- */ - u8 Short_Slot_Time:1; - u8 Reserved2:2; - u8 DSSS_OFDM:1; - u8 Reserved3:2; - } __attribute__ ((packed)) Capability; - #endif - } __attribute__ ((packed)) ; -} __attribute__ ((packed)); - -struct FH_Parameter_Set_Element { - u8 Element_ID; - u8 Length; - u8 Dwell_Time[2]; - u8 Hop_Set; - u8 Hop_Pattern; - u8 Hop_Index; -}; - -struct DS_Parameter_Set_Element { - u8 Element_ID; - u8 Length; - u8 Current_Channel; -}; - -struct Supported_Rates_Element { - u8 Element_ID; - u8 Length; - u8 SupportedRates[8]; -} __attribute__ ((packed)); - -struct SSID_Element { - u8 Element_ID; - u8 Length; - u8 SSID[32]; -} __attribute__ ((packed)) ; - -struct CF_Parameter_Set_Element { - u8 Element_ID; - u8 Length; - u8 CFP_Count; - u8 CFP_Period; - u8 CFP_MaxDuration[2]; /* in Time Units */ - u8 CFP_DurRemaining[2]; /* in time units */ -}; - -struct TIM_Element { - u8 Element_ID; - u8 Length; - u8 DTIM_Count; - u8 DTIM_Period; - u8 Bitmap_Control; - u8 Partial_Virtual_Bitmap[251]; -}; - -struct IBSS_Parameter_Set_Element { - u8 Element_ID; - u8 Length; - u8 ATIM_Window[2]; -}; - -struct Challenge_Text_Element { - u8 Element_ID; - u8 Length; - u8 Challenge_Text[253]; -}; - -struct PHY_Parameter_Set_Element { -/* int aSlotTime; */ -/* int aSifsTime; */ - s32 aCCATime; - s32 aRxTxTurnaroundTime; - s32 aTxPLCPDelay; - s32 RxPLCPDelay; - s32 aRxTxSwitchTime; - s32 aTxRampOntime; - s32 aTxRampOffTime; - s32 aTxRFDelay; - s32 aRxRFDelay; - s32 aAirPropagationTime; - s32 aMACProcessingDelay; - s32 aPreambleLength; - s32 aPLCPHeaderLength; - s32 aMPDUDurationFactor; - s32 aMPDUMaxLength; -/* int aCWmin; */ -/* int aCWmax; */ -}; - -/* -- 11G -- */ -struct ERP_Information_Element { - u8 Element_ID; - u8 Length; - #ifdef _BIG_ENDIAN_ /* 20060926 add by anson's endian */ - u8 Reserved:5; /* 20060926 add by anson */ - u8 Barker_Preamble_Mode:1; - u8 Use_Protection:1; - u8 NonERP_Present:1; - #else - u8 NonERP_Present:1; - u8 Use_Protection:1; - u8 Barker_Preamble_Mode:1; - u8 Reserved:5; - #endif -}; - -struct Extended_Supported_Rates_Element { - u8 Element_ID; - u8 Length; - u8 ExtendedSupportedRates[255]; -} __attribute__ ((packed)); - -/* WPA(802.11i draft 3.0) */ -#define VERSION_WPA 1 -/* WPA2.0 OUI=00:50:F2, the MSB is reserved for suite type */ -#define OUI_WPA 0x00F25000 - -#define OUI_WPA_ADDITIONAL 0x01 -#define WLAN_MIN_RSN_WPA_LENGTH 6 /* added by ws 09/10/04 */ - -#define oui_wpa (u32)(OUI_WPA|OUI_WPA_ADDITIONAL) - -#define WPA_OUI_BIG ((u32) 0x01F25000)/* added by ws 09/23/04 */ -#define WPA_OUI_LITTLE ((u32) 0x01F25001)/* added by ws 09/23/04 */ -/* 20061108 For WPS. It's little endian. Big endian is 0x0050F204 */ -#define WPA_WPS_OUI cpu_to_le32(0x04F25000) - -/* Authentication suite */ -#define OUI_AUTH_WPA_NONE 0x00 /* for WPA_NONE */ -#define OUI_AUTH_8021X 0x01 -#define OUI_AUTH_PSK 0x02 -/* Cipher suite */ -#define OUI_CIPHER_GROUP_KEY 0x00 /* added by ws 05/21/04 */ -#define OUI_CIPHER_WEP_40 0x01 -#define OUI_CIPHER_TKIP 0x02 -#define OUI_CIPHER_CCMP 0x04 -#define OUI_CIPHER_WEP_104 0x05 - -struct suite_selector{ - union{ - u8 Value[4]; - struct _SUIT_ { - u8 OUI[3]; - u8 Type; - } SuitSelector; - }; -}; - -/* -- WPA -- */ -struct RSN_Information_Element{ - u8 Element_ID; - u8 Length; - /* WPA version 2.0 additional field, and should be 00:50:F2:01 */ - struct suite_selector OuiWPAAdditional; - u16 Version; - struct suite_selector GroupKeySuite; - u16 PairwiseKeySuiteCount; - struct suite_selector PairwiseKeySuite[1]; -} __attribute__ ((packed)); -struct RSN_Auth_Sub_Information_Element { - u16 AuthKeyMngtSuiteCount; - struct suite_selector AuthKeyMngtSuite[1]; -} __attribute__ ((packed)); - -/* -- WPA2 -- */ -struct RSN_Capability_Element { - union { - u16 __attribute__ ((packed)) wValue; - #ifdef _BIG_ENDIAN_ /* 20060927 add by anson's endian */ - struct _RSN_Capability { - u16 __attribute__ ((packed)) Reserved2:8; /* 20051201 */ - u16 __attribute__ ((packed)) Reserved1:2; - u16 __attribute__ ((packed)) GTK_Replay_Counter:2; - u16 __attribute__ ((packed)) PTK_Replay_Counter:2; - u16 __attribute__ ((packed)) No_Pairwise:1; - u16 __attribute__ ((packed)) Pre_Auth:1; - } __attribute__ ((packed)) RSN_Capability; - #else - struct _RSN_Capability { - u16 __attribute__ ((packed)) Pre_Auth:1; - u16 __attribute__ ((packed)) No_Pairwise:1; - u16 __attribute__ ((packed)) PTK_Replay_Counter:2; - u16 __attribute__ ((packed)) GTK_Replay_Counter:2; - u16 __attribute__ ((packed)) Reserved1:2; - u16 __attribute__ ((packed)) Reserved2:8; /* 20051201 */ - } __attribute__ ((packed)) RSN_Capability; - #endif - - } __attribute__ ((packed)) ; -} __attribute__ ((packed)) ; - -/*============================================================ -// MAC Frame structure (different type) and subfield structure -//============================================================*/ -struct MAC_frame_control { -/* a combination of the [Protocol Version, Control Type, Control Subtype]*/ - u8 mac_frame_info; -/* 20060927 add by anson's endian */ - #ifdef _BIG_ENDIAN_ - u8 order:1; - u8 WEP:1; - u8 more_data:1; - u8 pwr_mgt:1; - u8 retry:1; - u8 more_frag:1; - u8 from_ds:1; - u8 to_ds:1; - #else - u8 to_ds:1; - u8 from_ds:1; - u8 more_frag:1; - u8 retry:1; - u8 pwr_mgt:1; - u8 more_data:1; - u8 WEP:1; - u8 order:1; - #endif -} __attribute__ ((packed)); - -struct Management_Frame { -/* 2B, ToDS,FromDS,MoreFrag,MoreData,Order=0 */ - struct MAC_frame_control frame_control; - u16 duration; - u8 DA[MAC_ADDR_LENGTH]; /* Addr1 */ - u8 SA[MAC_ADDR_LENGTH]; /* Addr2 */ - u8 BSSID[MAC_ADDR_LENGTH]; /* Addr3 */ - u16 Sequence_Control; - /* Management Frame Body <= 325 bytes */ - /* FCS 4 bytes */ -} __attribute__ ((packed)); - -/* SW-MAC don't Tx/Rx Control-Frame, HW-MAC do it. */ -struct Control_Frame { -/* ToDS,FromDS,MoreFrag,Retry,MoreData,WEP,Order=0 */ - struct MAC_frame_control frame_control; - u16 duration; - u8 RA[MAC_ADDR_LENGTH]; - u8 TA[MAC_ADDR_LENGTH]; - u16 FCS; -} __attribute__ ((packed)); - -struct Data_Frame { - struct MAC_frame_control frame_control; - u16 duration; - u8 Addr1[MAC_ADDR_LENGTH]; - u8 Addr2[MAC_ADDR_LENGTH]; - u8 Addr3[MAC_ADDR_LENGTH]; - u16 Sequence_Control; - u8 Addr4[MAC_ADDR_LENGTH]; /* only exist when ToDS=FromDS=1 */ - /* Data Frame Body <= 2312 */ - /* FCS */ -} __attribute__ ((packed)); - -struct Disassociation_Frame_Body { - u16 reasonCode; -} __attribute__ ((packed)); - -struct Association_Request_Frame_Body { - u16 capability_information; - u16 listenInterval; - u8 Current_AP_Address[MAC_ADDR_LENGTH];/* for reassociation only */ - /* SSID (2+32 bytes) */ - /* Supported_Rates (2+8 bytes) */ -} __attribute__ ((packed)); - -struct Association_Response_Frame_Body { - u16 capability_information; - u16 statusCode; - u16 Association_ID; - struct Supported_Rates_Element supportedRates; -} __attribute__ ((packed)); - -/*struct Reassociation_Request_Frame_Body -{ - u16 capability_information; - u16 listenInterval; - u8 Current_AP_Address[MAC_ADDR_LENGTH]; - // SSID (2+32 bytes) - // Supported_Rates (2+8 bytes) -};*/ -/* eliminated by WS 07/22/04 comboined with associateion request frame. */ - -struct Reassociation_Response_Frame_Body { - u16 capability_information; - u16 statusCode; - u16 Association_ID; - struct Supported_Rates_Element supportedRates; -} __attribute__ ((packed)); - -struct Deauthentication_Frame_Body { - u16 reasonCode; -} __attribute__ ((packed)); - - -struct Probe_Response_Frame_Body { - u16 Timestamp; - u16 Beacon_Interval; - u16 Capability_Information; - /* SSID - // Supported_Rates - // PHY parameter Set (DS Parameters) - // CF parameter Set - // IBSS parameter Set */ -} __attribute__ ((packed)); - -struct Authentication_Frame_Body { - u16 algorithmNumber; - u16 sequenceNumber; - u16 statusCode; - /* NB: don't include ChallengeText in this structure - // struct Challenge_Text_Element sChallengeTextElement; - // wkchen added */ -} __attribute__ ((packed)); - - #endif /* _MAC_Structure_H_ */ - - -- cgit v1.2.3 From 2855bb79d75ad1419b1f54008f861a39517acfd5 Mon Sep 17 00:00:00 2001 From: Pekka Enberg Date: Sun, 28 Nov 2010 23:00:00 +0200 Subject: Staging: w35und: Use pr_debug() for debugging Use pr_debug() for debugging printk's and kill the FULL_DEBUG macro. It would be even better to use dev_dbg() but unfortunately looking up struct device in the current code structure makes things very ugly. Please note that I dropped the DataDmp() calls from RFSynthesizer_SwitchingChannel() because that function doesn't exist. Cc: Pavel Machek Signed-off-by: Pekka Enberg Signed-off-by: Greg Kroah-Hartman --- drivers/staging/winbond/mds.c | 16 ++++------------ drivers/staging/winbond/reg.c | 27 +++++---------------------- drivers/staging/winbond/sysdef.h | 12 ------------ drivers/staging/winbond/wb35reg.c | 20 +++++--------------- drivers/staging/winbond/wb35rx.c | 21 +++++---------------- drivers/staging/winbond/wb35tx.c | 16 ++++------------ drivers/staging/winbond/wbusb.c | 13 +++---------- 7 files changed, 26 insertions(+), 99 deletions(-) diff --git a/drivers/staging/winbond/mds.c b/drivers/staging/winbond/mds.c index 90f2cc019d3b..8ae3d84e34bb 100644 --- a/drivers/staging/winbond/mds.c +++ b/drivers/staging/winbond/mds.c @@ -346,9 +346,7 @@ static void Mds_HeaderCopy(struct wbsoft_priv *adapter, struct wb35_descriptor * ctmp1 = ctmpf = CURRENT_TX_RATE_FOR_MNG; pDes->TxRate = ctmp1; - #ifdef _PE_TX_DUMP_ - printk("Tx rate =%x\n", ctmp1); - #endif + pr_debug("Tx rate =%x\n", ctmp1); pT01->T01_modulation_type = (ctmp1%3) ? 0 : 1; @@ -426,9 +424,7 @@ Mds_Tx(struct wbsoft_priv *adapter) do { FillIndex = pMds->TxFillIndex; if (pMds->TxOwner[FillIndex]) { /* Is owned by software 0:Yes 1:No */ -#ifdef _PE_TX_DUMP_ - printk("[Mds_Tx] Tx Owner is H/W.\n"); -#endif + pr_debug("[Mds_Tx] Tx Owner is H/W.\n"); break; } @@ -472,9 +468,7 @@ Mds_Tx(struct wbsoft_priv *adapter) /* For speed up Key setting */ if (pTxDes->EapFix) { -#ifdef _PE_TX_DUMP_ - printk("35: EPA 4th frame detected. Size = %d\n", PacketSize); -#endif + pr_debug("35: EPA 4th frame detected. Size = %d\n", PacketSize); pHwData->IsKeyPreSet = 1; } @@ -563,9 +557,7 @@ Mds_SendComplete(struct wbsoft_priv *adapter, struct T02_descriptor *pT02) pHwData->tx_retry_count[RetryCount] += RetryCount; else pHwData->tx_retry_count[7] += RetryCount; - #ifdef _PE_STATE_DUMP_ - printk("dto_tx_retry_count =%d\n", pHwData->dto_tx_retry_count); - #endif + pr_debug("dto_tx_retry_count =%d\n", pHwData->dto_tx_retry_count); MTO_SetTxCount(adapter, TxRate, RetryCount); } pHwData->dto_tx_frag_count += (RetryCount+1); diff --git a/drivers/staging/winbond/reg.c b/drivers/staging/winbond/reg.c index 439d213fe951..dcd7560ce2cc 100644 --- a/drivers/staging/winbond/reg.c +++ b/drivers/staging/winbond/reg.c @@ -1012,9 +1012,7 @@ void RFSynthesizer_initial(struct hw_data *pHwData) case RF_AIROHA_7230: /* Start to fill RF parameters, PLL_ON should be pulled low. */ Wb35Reg_WriteSync(pHwData, 0x03dc, 0x00000000); - #ifdef _PE_STATE_DUMP_ - printk("* PLL_ON low\n"); - #endif + pr_debug("* PLL_ON low\n"); number = ARRAY_SIZE(al7230_rf_data_24); Set_ChanIndep_RfData_al7230_24(pHwData, pltmp, number); break; @@ -1100,9 +1098,7 @@ void RFSynthesizer_initial(struct hw_data *pHwData) case RF_AIROHA_7230: /* RF parameters have filled completely, PLL_ON should be pulled high */ Wb35Reg_WriteSync(pHwData, 0x03dc, 0x00000080); - #ifdef _PE_STATE_DUMP_ - printk("* PLL_ON high\n"); - #endif + pr_debug("* PLL_ON high\n"); /* 2.4GHz */ ltmp = (1 << 31) | (0 << 30) | (24 << 24) | 0x9ABA8F; @@ -1117,9 +1113,7 @@ void RFSynthesizer_initial(struct hw_data *pHwData) /* 5GHz */ Wb35Reg_WriteSync(pHwData, 0x03dc, 0x00000000); - #ifdef _PE_STATE_DUMP_ - printk("* PLL_ON low\n"); - #endif + pr_debug("* PLL_ON low\n"); number = ARRAY_SIZE(al7230_rf_data_50); Set_ChanIndep_RfData_al7230_50(pHwData, pltmp, number); @@ -1129,9 +1123,7 @@ void RFSynthesizer_initial(struct hw_data *pHwData) msleep(5); Wb35Reg_WriteSync(pHwData, 0x03dc, 0x00000080); - #ifdef _PE_STATE_DUMP_ - printk("* PLL_ON high\n"); - #endif + pr_debug("* PLL_ON high\n"); ltmp = (1 << 31) | (0 << 30) | (24 << 24) | 0x9ABA8F; Wb35Reg_WriteSync(pHwData, 0x0864, ltmp); @@ -1797,9 +1789,7 @@ void RFSynthesizer_SwitchingChannel(struct hw_data *pHwData, struct chan_info C /* Write to register. number must less and equal than 16 */ Wb35Reg_BurstWrite(pHwData, 0x0864, pltmp, number, NO_INCREMENT); - #ifdef _PE_STATE_DUMP_ - printk("Band changed\n"); - #endif + pr_debug("Band changed\n"); } if (Channel.band <= BAND_TYPE_OFDM_24) { /* channel 1 ~ 14 */ @@ -2338,13 +2328,6 @@ void EEPROMTxVgaAdjust(struct hw_data *pHwData) pHwData->TxVgaFor50[32].TxVgaValue = pTxVga[17] - stmp * 2 / 4; pHwData->TxVgaFor50[31].TxVgaValue = pTxVga[17] - stmp * 3 / 4; } - - #ifdef _PE_STATE_DUMP_ - printk(" TxVgaFor24 :\n"); - DataDmp((u8 *)pHwData->TxVgaFor24, 14 , 0); - printk(" TxVgaFor50 :\n"); - DataDmp((u8 *)pHwData->TxVgaFor50, 70 , 0); - #endif } void BBProcessor_RateChanging(struct hw_data *pHwData, u8 rate) diff --git a/drivers/staging/winbond/sysdef.h b/drivers/staging/winbond/sysdef.h index 8d4ebe15d930..04e6e8ff7349 100644 --- a/drivers/staging/winbond/sysdef.h +++ b/drivers/staging/winbond/sysdef.h @@ -3,16 +3,4 @@ #ifndef SYS_DEF_H #define SYS_DEF_H -/* debug print options, mark what debug you don't need */ - -#ifdef FULL_DEBUG -#define _PE_STATE_DUMP_ -#define _PE_TX_DUMP_ -#define _PE_RX_DUMP_ -#define _PE_OID_DUMP_ -#define _PE_DTO_DUMP_ -#define _PE_REG_DUMP_ -#define _PE_USB_INI_DUMP_ -#endif - #endif diff --git a/drivers/staging/winbond/wb35reg.c b/drivers/staging/winbond/wb35reg.c index 770722385eeb..f33f4f80b462 100644 --- a/drivers/staging/winbond/wb35reg.c +++ b/drivers/staging/winbond/wb35reg.c @@ -150,9 +150,7 @@ unsigned char Wb35Reg_WriteSync(struct hw_data *pHwData, u16 RegisterNo, u32 Reg Wb35Reg_EP0VM_start(pHwData); if (ret < 0) { -#ifdef _PE_REG_DUMP_ - printk("EP0 Write register usb message sending error\n"); -#endif + pr_debug("EP0 Write register usb message sending error\n"); pHwData->SurpriseRemove = 1; return false; } @@ -320,9 +318,7 @@ unsigned char Wb35Reg_ReadSync(struct hw_data *pHwData, u16 RegisterNo, u32 *pRe Wb35Reg_EP0VM_start(pHwData); if (ret < 0) { -#ifdef _PE_REG_DUMP_ - printk("EP0 Read register usb message sending error\n"); -#endif + pr_debug("EP0 Read register usb message sending error\n"); pHwData->SurpriseRemove = 1; return false; } @@ -442,9 +438,7 @@ void Wb35Reg_EP0VM(struct hw_data *pHwData) ret = usb_submit_urb(urb, GFP_ATOMIC); if (ret < 0) { -#ifdef _PE_REG_DUMP_ - printk("EP0 Irp sending error\n"); -#endif + pr_debug("EP0 Irp sending error\n"); goto cleanup; } return; @@ -479,9 +473,7 @@ void Wb35Reg_EP0VM_complete(struct urb *urb) spin_unlock_irq(®->EP0VM_spin_lock); if (reg->EP0VM_status) { -#ifdef _PE_REG_DUMP_ - printk("EP0 IoCompleteRoutine return error\n"); -#endif + pr_debug("EP0 IoCompleteRoutine return error\n"); reg->EP0vm_state = VM_STOP; pHwData->SurpriseRemove = 1; } else { @@ -526,9 +518,7 @@ void Wb35Reg_destroy(struct hw_data *pHwData) usb_free_urb(urb); kfree(reg_queue); } else { -#ifdef _PE_REG_DUMP_ - printk("EP0 queue release error\n"); -#endif + pr_debug("EP0 queue release error\n"); } spin_lock_irq(®->EP0VM_spin_lock); diff --git a/drivers/staging/winbond/wb35rx.c b/drivers/staging/winbond/wb35rx.c index 5af271f2de9c..02557289ffb6 100644 --- a/drivers/staging/winbond/wb35rx.c +++ b/drivers/staging/winbond/wb35rx.c @@ -109,10 +109,7 @@ static u16 Wb35Rx_indicate(struct ieee80211_hw *hw) /* Basic check for Rx length. Is length valid? */ if (PacketSize > MAX_PACKET_SIZE) { -#ifdef _PE_RX_DUMP_ - printk("Serious ERROR : Rx data size too long, size =%d\n", PacketSize); -#endif - + pr_debug("Serious ERROR : Rx data size too long, size =%d\n", PacketSize); pWb35Rx->EP3vm_state = VM_STOP; pWb35Rx->Ep3ErrorCount2++; break; @@ -186,9 +183,7 @@ static void Wb35Rx_Complete(struct urb *urb) /* The URB is completed, check the result */ if (pWb35Rx->EP3VM_status != 0) { -#ifdef _PE_USB_STATE_DUMP_ - printk("EP3 IoCompleteRoutine return error\n"); -#endif + pr_debug("EP3 IoCompleteRoutine return error\n"); pWb35Rx->EP3vm_state = VM_STOP; goto error; } @@ -249,9 +244,7 @@ static void Wb35Rx(struct ieee80211_hw *hw) RxBufferId = pWb35Rx->RxBufferId; if (!pWb35Rx->RxOwner[RxBufferId]) { /* It's impossible to run here. */ -#ifdef _PE_RX_DUMP_ - printk("Rx driver fifo unavailable\n"); -#endif + pr_debug("Rx driver fifo unavailable\n"); goto error; } @@ -337,9 +330,7 @@ void Wb35Rx_stop(struct hw_data *pHwData) /* Canceling the Irp if already sends it out. */ if (pWb35Rx->EP3vm_state == VM_RUNNING) { usb_unlink_urb(pWb35Rx->RxUrb); /* Only use unlink, let Wb35Rx_destroy to free them */ -#ifdef _PE_RX_DUMP_ - printk("EP3 Rx stop\n"); -#endif + pr_debug("EP3 Rx stop\n"); } } @@ -355,8 +346,6 @@ void Wb35Rx_destroy(struct hw_data *pHwData) if (pWb35Rx->RxUrb) usb_free_urb(pWb35Rx->RxUrb); -#ifdef _PE_RX_DUMP_ - printk("Wb35Rx_destroy OK\n"); -#endif + pr_debug("Wb35Rx_destroy OK\n"); } diff --git a/drivers/staging/winbond/wb35tx.c b/drivers/staging/winbond/wb35tx.c index fd52554e46f8..8f0d5273d907 100644 --- a/drivers/staging/winbond/wb35tx.c +++ b/drivers/staging/winbond/wb35tx.c @@ -153,16 +153,12 @@ void Wb35Tx_stop(struct hw_data * pHwData) // Trying to canceling the Trp of EP2 if (pWb35Tx->EP2vm_state == VM_RUNNING) usb_unlink_urb( pWb35Tx->Tx2Urb ); // Only use unlink, let Wb35Tx_destrot to free them - #ifdef _PE_TX_DUMP_ - printk("EP2 Tx stop\n"); - #endif + pr_debug("EP2 Tx stop\n"); // Trying to canceling the Irp of EP4 if (pWb35Tx->EP4vm_state == VM_RUNNING) usb_unlink_urb( pWb35Tx->Tx4Urb ); // Only use unlink, let Wb35Tx_destrot to free them - #ifdef _PE_TX_DUMP_ - printk("EP4 Tx stop\n"); - #endif + pr_debug("EP4 Tx stop\n"); } //====================================================== @@ -182,9 +178,7 @@ void Wb35Tx_destroy(struct hw_data * pHwData) if (pWb35Tx->Tx2Urb) usb_free_urb( pWb35Tx->Tx2Urb ); - #ifdef _PE_TX_DUMP_ - printk("Wb35Tx_destroy OK\n"); - #endif + pr_debug("Wb35Tx_destroy OK\n"); } void Wb35Tx_CurrentTime(struct wbsoft_priv *adapter, u32 TimeCount) @@ -279,9 +273,7 @@ static void Wb35Tx_EP2VM(struct wbsoft_priv *adapter) retv = usb_submit_urb(pUrb, GFP_ATOMIC); if (retv < 0) { - #ifdef _PE_TX_DUMP_ - printk("EP2 Tx Irp sending error\n"); - #endif + pr_debug("EP2 Tx Irp sending error\n"); goto error; } diff --git a/drivers/staging/winbond/wbusb.c b/drivers/staging/winbond/wbusb.c index dcb6d5b63d76..5f54b0fd706a 100644 --- a/drivers/staging/winbond/wbusb.c +++ b/drivers/staging/winbond/wbusb.c @@ -184,10 +184,7 @@ static void hal_set_current_channel_ex(struct hw_data *pHwData, struct chan_info RFSynthesizer_SwitchingChannel(pHwData, channel); /* Switch channel */ pHwData->Channel = channel.ChanNo; pHwData->band = channel.band; -#ifdef _PE_STATE_DUMP_ - printk("Set channel is %d, band =%d\n", pHwData->Channel, - pHwData->band); -#endif + pr_debug("Set channel is %d, band =%d\n", pHwData->Channel, pHwData->band); reg->M28_MacControl &= ~0xff; /* Clean channel information field */ reg->M28_MacControl |= channel.ChanNo; Wb35Reg_WriteWithCallbackValue(pHwData, 0x0828, reg->M28_MacControl, @@ -728,9 +725,7 @@ static int wb35_hw_init(struct ieee80211_hw *hw) } priv->sLocalPara.bAntennaNo = hal_get_antenna_number(pHwData); -#ifdef _PE_STATE_DUMP_ - printk("Driver init, antenna no = %d\n", psLOCAL->bAntennaNo); -#endif + pr_debug("Driver init, antenna no = %d\n", priv->sLocalPara.bAntennaNo); hal_get_hw_radio_off(pHwData); /* Waiting for HAL setting OK */ @@ -856,9 +851,7 @@ static void wb35_hw_halt(struct wbsoft_priv *adapter) { /* Turn off Rx and Tx hardware ability */ hal_stop(&adapter->sHwData); -#ifdef _PE_USB_INI_DUMP_ - printk("[w35und] Hal_stop O.K.\n"); -#endif + pr_debug("[w35und] Hal_stop O.K.\n"); /* Waiting Irp completed */ msleep(100); -- cgit v1.2.3 From ddee7e28e7d5e4ba2b8537c6a59b035745c250bb Mon Sep 17 00:00:00 2001 From: Pekka Enberg Date: Sun, 28 Nov 2010 23:00:01 +0200 Subject: Staging: w35und: Remove empty sysdef.h header The sysdef.h header is empty now so kill it. Cc: Pavel Machek Signed-off-by: Pekka Enberg Signed-off-by: Greg Kroah-Hartman --- drivers/staging/winbond/mds.c | 1 - drivers/staging/winbond/mlmetxrx.c | 2 -- drivers/staging/winbond/mto.c | 1 - drivers/staging/winbond/phy_calibration.c | 1 - drivers/staging/winbond/reg.c | 1 - drivers/staging/winbond/sysdef.h | 6 ------ drivers/staging/winbond/wb35reg.c | 1 - drivers/staging/winbond/wb35rx.c | 1 - drivers/staging/winbond/wb35tx.c | 1 - 9 files changed, 15 deletions(-) delete mode 100644 drivers/staging/winbond/sysdef.h diff --git a/drivers/staging/winbond/mds.c b/drivers/staging/winbond/mds.c index 8ae3d84e34bb..b4e0514b7f34 100644 --- a/drivers/staging/winbond/mds.c +++ b/drivers/staging/winbond/mds.c @@ -1,7 +1,6 @@ #include "mds_f.h" #include "mlmetxrx_f.h" #include "mto.h" -#include "sysdef.h" #include "wbhal.h" #include "wblinux_f.h" #include "wb35tx_f.h" diff --git a/drivers/staging/winbond/mlmetxrx.c b/drivers/staging/winbond/mlmetxrx.c index 7425a23f12e8..87f339f1af43 100644 --- a/drivers/staging/winbond/mlmetxrx.c +++ b/drivers/staging/winbond/mlmetxrx.c @@ -15,8 +15,6 @@ Copyright (c) 1996-2002 Winbond Electronics Corp. All Rights Reserved. ============================================================================ */ -#include "sysdef.h" - #include "mds_f.h" void MLME_GetNextPacket(struct wbsoft_priv *adapter, struct wb35_descriptor *desc) diff --git a/drivers/staging/winbond/mto.c b/drivers/staging/winbond/mto.c index 1faebceceff7..c03e5010ca34 100644 --- a/drivers/staging/winbond/mto.c +++ b/drivers/staging/winbond/mto.c @@ -17,7 +17,6 @@ * ============================================================================ */ -#include "sysdef.h" #include "sme_api.h" #include "wbhal.h" #include "wb35reg_f.h" diff --git a/drivers/staging/winbond/phy_calibration.c b/drivers/staging/winbond/phy_calibration.c index 0658b09c7853..09844db64fe9 100644 --- a/drivers/staging/winbond/phy_calibration.c +++ b/drivers/staging/winbond/phy_calibration.c @@ -10,7 +10,6 @@ */ /****************** INCLUDE FILES SECTION ***********************************/ -#include "sysdef.h" #include "phy_calibration.h" #include "wbhal.h" #include "wb35reg_f.h" diff --git a/drivers/staging/winbond/reg.c b/drivers/staging/winbond/reg.c index dcd7560ce2cc..4d2c6a12a951 100644 --- a/drivers/staging/winbond/reg.c +++ b/drivers/staging/winbond/reg.c @@ -1,4 +1,3 @@ -#include "sysdef.h" #include "wbhal.h" #include "wb35reg_f.h" #include "core.h" diff --git a/drivers/staging/winbond/sysdef.h b/drivers/staging/winbond/sysdef.h deleted file mode 100644 index 04e6e8ff7349..000000000000 --- a/drivers/staging/winbond/sysdef.h +++ /dev/null @@ -1,6 +0,0 @@ -/* Winbond WLAN System Configuration defines */ - -#ifndef SYS_DEF_H -#define SYS_DEF_H - -#endif diff --git a/drivers/staging/winbond/wb35reg.c b/drivers/staging/winbond/wb35reg.c index f33f4f80b462..a15de1eab796 100644 --- a/drivers/staging/winbond/wb35reg.c +++ b/drivers/staging/winbond/wb35reg.c @@ -1,4 +1,3 @@ -#include "sysdef.h" #include "wb35reg_f.h" #include diff --git a/drivers/staging/winbond/wb35rx.c b/drivers/staging/winbond/wb35rx.c index 02557289ffb6..190758ebad5c 100644 --- a/drivers/staging/winbond/wb35rx.c +++ b/drivers/staging/winbond/wb35rx.c @@ -14,7 +14,6 @@ #include #include "core.h" -#include "sysdef.h" #include "wb35rx_f.h" static void packet_came(struct ieee80211_hw *hw, char *pRxBufferAddress, int PacketSize) diff --git a/drivers/staging/winbond/wb35tx.c b/drivers/staging/winbond/wb35tx.c index 8f0d5273d907..5e9e21a6dbff 100644 --- a/drivers/staging/winbond/wb35tx.c +++ b/drivers/staging/winbond/wb35tx.c @@ -13,7 +13,6 @@ #include "wb35tx_f.h" #include "mds_f.h" -#include "sysdef.h" unsigned char Wb35Tx_get_tx_buffer(struct hw_data * pHwData, u8 **pBuffer) -- cgit v1.2.3 From 9255650cbf997762bd667896b0b86661cd81c9b4 Mon Sep 17 00:00:00 2001 From: Pekka Enberg Date: Sun, 28 Nov 2010 23:00:02 +0200 Subject: Staging: w35und: Kill Vendor2 ifdef from hal_init_hardware The Vendor2 macro is never defined so remove the ifdef'd block from hal_init_hardware(). Cc: Pavel Machek Signed-off-by: Pekka Enberg Signed-off-by: Greg Kroah-Hartman --- drivers/staging/winbond/wbusb.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/drivers/staging/winbond/wbusb.c b/drivers/staging/winbond/wbusb.c index 5f54b0fd706a..9fc078f8c77a 100644 --- a/drivers/staging/winbond/wbusb.c +++ b/drivers/staging/winbond/wbusb.c @@ -642,13 +642,6 @@ static int hal_init_hardware(struct ieee80211_hw *hw) SoftwareSet = hal_software_set(pHwData); -#ifdef Vendor2 - /* Try to make sure the EEPROM contain */ - SoftwareSet >>= 8; - if (SoftwareSet != 0x82) - return false; -#endif - Wb35Rx_start(hw); Wb35Tx_EP2VM_start(priv); -- cgit v1.2.3 From 9618386a4e58e0459932846d9b07fa81225840d3 Mon Sep 17 00:00:00 2001 From: Pekka Enberg Date: Sun, 28 Nov 2010 23:00:03 +0200 Subject: Staging: w35und: Kill write-only ->TxToggle This patch removes ->TxToggle from struct wb35_mds because it's a write only struct member. Cc: Pavel Machek Signed-off-by: Pekka Enberg Signed-off-by: Greg Kroah-Hartman --- drivers/staging/winbond/mds.c | 5 ----- drivers/staging/winbond/mds_s.h | 4 ---- 2 files changed, 9 deletions(-) diff --git a/drivers/staging/winbond/mds.c b/drivers/staging/winbond/mds.c index b4e0514b7f34..0daabdc8d91c 100644 --- a/drivers/staging/winbond/mds.c +++ b/drivers/staging/winbond/mds.c @@ -481,11 +481,6 @@ Mds_Tx(struct wbsoft_priv *adapter) XmitBufSize += CurrentSize; XmitBufAddress += CurrentSize; -#ifdef _IBSS_BEACON_SEQ_STICK_ - if ((XmitBufAddress[DOT_11_DA_OFFSET+8] & 0xfc) != MAC_SUBTYPE_MNGMNT_PROBE_REQUEST) /* +8 for USB hdr */ -#endif - pMds->TxToggle = true; - /* Get packet to transmit completed, 1:TESTSTA 2:MLME 3: Ndis data */ MLME_SendComplete(adapter, 0, true); diff --git a/drivers/staging/winbond/mds_s.h b/drivers/staging/winbond/mds_s.h index e2de4bd23b4d..eeedf0186365 100644 --- a/drivers/staging/winbond/mds_s.h +++ b/drivers/staging/winbond/mds_s.h @@ -107,10 +107,6 @@ struct wb35_mds { u8 TxRate[((MAX_USB_TX_DESCRIPTOR + 1) & ~0x01)][2]; /* [0] current tx rate, [1] fall back rate */ u8 TxInfo[((MAX_USB_TX_DESCRIPTOR + 1) & ~0x01)]; /*Store information for callback function */ - /* for scanning mechanism */ - u8 TxToggle; /* It is TRUE if there are tx activities in some time interval */ - u8 Reserved_[3]; - /* ---- for Tx Parameter */ u16 TxFragmentThreshold; /* For frame body only */ u16 TxRTSThreshold; -- cgit v1.2.3 From 37b0544a4a455609cbf25fa56441a6f1221dec85 Mon Sep 17 00:00:00 2001 From: Pekka Enberg Date: Sun, 28 Nov 2010 23:00:04 +0200 Subject: Staging: w35und: Kill _IBSS_BEACON_SEQ_STICK_ This patch kills the _IBSS_BEACON_SEQ_STICK_ ifdefs because the macro is never defined. Cc: Pavel Machek Signed-off-by: Pekka Enberg Signed-off-by: Greg Kroah-Hartman --- drivers/staging/winbond/mlmetxrx_f.h | 4 ---- drivers/staging/winbond/reg.c | 4 ---- 2 files changed, 8 deletions(-) diff --git a/drivers/staging/winbond/mlmetxrx_f.h b/drivers/staging/winbond/mlmetxrx_f.h index 012507fc49e3..6db423bc6677 100644 --- a/drivers/staging/winbond/mlmetxrx_f.h +++ b/drivers/staging/winbond/mlmetxrx_f.h @@ -16,8 +16,4 @@ void MLME_SendComplete(struct wbsoft_priv *adapter, u8 PacketID, unsigned char SendOK); -#ifdef _IBSS_BEACON_SEQ_STICK_ -s8 SendBCNullData(struct wbsoft_priv *adapter, u16 wIdx); -#endif - #endif diff --git a/drivers/staging/winbond/reg.c b/drivers/staging/winbond/reg.c index 4d2c6a12a951..1b38d6d225c9 100644 --- a/drivers/staging/winbond/reg.c +++ b/drivers/staging/winbond/reg.c @@ -2064,11 +2064,7 @@ void Mxx_initial(struct hw_data *pHwData) */ /* M00 bit set */ - #ifdef _IBSS_BEACON_SEQ_STICK_ - reg->M00_MacControl = 0; /* Solve beacon sequence number stop by software */ - #else reg->M00_MacControl = 0x80000000; /* Solve beacon sequence number stop by hardware */ - #endif /* M24 disable enter power save, BB RxOn and enable NAV attack */ reg->M24_MacControl = 0x08040042; -- cgit v1.2.3 From 01b5ceeca5aa45735a987420c83228a9778a791f Mon Sep 17 00:00:00 2001 From: Pekka Enberg Date: Sun, 28 Nov 2010 23:00:05 +0200 Subject: Staging: w35und: Merge mlmetxrx.c to mds.c This patch merges mlmetxrx.c to mds.c because it's small and the functions are only used in mto.c. Cc: Pavel Machek Signed-off-by: Pekka Enberg Signed-off-by: Greg Kroah-Hartman --- drivers/staging/winbond/Makefile | 1 - drivers/staging/winbond/mds.c | 39 ++++++++++++++++++++++- drivers/staging/winbond/mlmetxrx.c | 60 ------------------------------------ drivers/staging/winbond/mlmetxrx_f.h | 19 ------------ drivers/staging/winbond/wbusb.c | 1 - 5 files changed, 38 insertions(+), 82 deletions(-) delete mode 100644 drivers/staging/winbond/mlmetxrx.c delete mode 100644 drivers/staging/winbond/mlmetxrx_f.h diff --git a/drivers/staging/winbond/Makefile b/drivers/staging/winbond/Makefile index 79fa2271a0c1..081d48db04cb 100644 --- a/drivers/staging/winbond/Makefile +++ b/drivers/staging/winbond/Makefile @@ -1,6 +1,5 @@ w35und-y := \ mds.o \ - mlmetxrx.o \ mto.o \ phy_calibration.o \ reg.o \ diff --git a/drivers/staging/winbond/mds.c b/drivers/staging/winbond/mds.c index 0daabdc8d91c..00e9756da9c1 100644 --- a/drivers/staging/winbond/mds.c +++ b/drivers/staging/winbond/mds.c @@ -1,5 +1,4 @@ #include "mds_f.h" -#include "mlmetxrx_f.h" #include "mto.h" #include "wbhal.h" #include "wblinux_f.h" @@ -397,6 +396,44 @@ static void Mds_HeaderCopy(struct wbsoft_priv *adapter, struct wb35_descriptor * } +static void MLME_GetNextPacket(struct wbsoft_priv *adapter, struct wb35_descriptor *desc) +{ + desc->InternalUsed = desc->buffer_start_index + desc->buffer_number; + desc->InternalUsed %= MAX_DESCRIPTOR_BUFFER_INDEX; + desc->buffer_address[desc->InternalUsed] = adapter->sMlmeFrame.pMMPDU; + desc->buffer_size[desc->InternalUsed] = adapter->sMlmeFrame.len; + desc->buffer_total_size += adapter->sMlmeFrame.len; + desc->buffer_number++; + desc->Type = adapter->sMlmeFrame.DataType; +} + +static void MLMEfreeMMPDUBuffer(struct wbsoft_priv *adapter, s8 *pData) +{ + int i; + + /* Reclaim the data buffer */ + for (i = 0; i < MAX_NUM_TX_MMPDU; i++) { + if (pData == (s8 *)&(adapter->sMlmeFrame.TxMMPDU[i])) + break; + } + if (adapter->sMlmeFrame.TxMMPDUInUse[i]) + adapter->sMlmeFrame.TxMMPDUInUse[i] = false; + else { + /* Something wrong + PD43 Add debug code here??? */ + } +} + +static void MLME_SendComplete(struct wbsoft_priv *adapter, u8 PacketID, unsigned char SendOK) +{ + /* Reclaim the data buffer */ + adapter->sMlmeFrame.len = 0; + MLMEfreeMMPDUBuffer(adapter, adapter->sMlmeFrame.pMMPDU); + + /* Return resource */ + adapter->sMlmeFrame.IsInUsed = PACKET_FREE_TO_USE; +} + void Mds_Tx(struct wbsoft_priv *adapter) { diff --git a/drivers/staging/winbond/mlmetxrx.c b/drivers/staging/winbond/mlmetxrx.c deleted file mode 100644 index 87f339f1af43..000000000000 --- a/drivers/staging/winbond/mlmetxrx.c +++ /dev/null @@ -1,60 +0,0 @@ -/* ============================================================================ - Module Name: - MLMETxRx.C - - Description: - The interface between MDS (MAC Data Service) and MLME. - - Revision History: - -------------------------------------------------------------------------- - 200209 UN20 Jennifer Xu - Initial Release - 20021108 PD43 Austin Liu - 20030117 PD43 Austin Liu - Deleted MLMEReturnPacket and MLMEProcThread() - - Copyright (c) 1996-2002 Winbond Electronics Corp. All Rights Reserved. -============================================================================ */ -#include "mds_f.h" - -void MLME_GetNextPacket(struct wbsoft_priv *adapter, struct wb35_descriptor *desc) -{ - desc->InternalUsed = desc->buffer_start_index + desc->buffer_number; - desc->InternalUsed %= MAX_DESCRIPTOR_BUFFER_INDEX; - desc->buffer_address[desc->InternalUsed] = adapter->sMlmeFrame.pMMPDU; - desc->buffer_size[desc->InternalUsed] = adapter->sMlmeFrame.len; - desc->buffer_total_size += adapter->sMlmeFrame.len; - desc->buffer_number++; - desc->Type = adapter->sMlmeFrame.DataType; -} - -static void MLMEfreeMMPDUBuffer(struct wbsoft_priv *adapter, s8 *pData) -{ - int i; - - /* Reclaim the data buffer */ - for (i = 0; i < MAX_NUM_TX_MMPDU; i++) { - if (pData == (s8 *)&(adapter->sMlmeFrame.TxMMPDU[i])) - break; - } - if (adapter->sMlmeFrame.TxMMPDUInUse[i]) - adapter->sMlmeFrame.TxMMPDUInUse[i] = false; - else { - /* Something wrong - PD43 Add debug code here??? */ - } -} - -void -MLME_SendComplete(struct wbsoft_priv *adapter, u8 PacketID, unsigned char SendOK) -{ - /* Reclaim the data buffer */ - adapter->sMlmeFrame.len = 0; - MLMEfreeMMPDUBuffer(adapter, adapter->sMlmeFrame.pMMPDU); - - /* Return resource */ - adapter->sMlmeFrame.IsInUsed = PACKET_FREE_TO_USE; -} - - - diff --git a/drivers/staging/winbond/mlmetxrx_f.h b/drivers/staging/winbond/mlmetxrx_f.h deleted file mode 100644 index 6db423bc6677..000000000000 --- a/drivers/staging/winbond/mlmetxrx_f.h +++ /dev/null @@ -1,19 +0,0 @@ -/* ================================================================ -// MLMETxRx.H -- -// -// Functions defined in MLMETxRx.c. -// -// Copyright (c) 2002 Winbond Electrics Corp. All Rights Reserved. -//================================================================ */ -#ifndef _MLMETXRX_H -#define _MLMETXRX_H - -#include "core.h" - -void MLME_GetNextPacket(struct wbsoft_priv *adapter, struct wb35_descriptor *pDes); - -void -MLME_SendComplete(struct wbsoft_priv *adapter, u8 PacketID, - unsigned char SendOK); - -#endif diff --git a/drivers/staging/winbond/wbusb.c b/drivers/staging/winbond/wbusb.c index 9fc078f8c77a..c5a3107bd4a7 100644 --- a/drivers/staging/winbond/wbusb.c +++ b/drivers/staging/winbond/wbusb.c @@ -14,7 +14,6 @@ #include "core.h" #include "mds_f.h" -#include "mlmetxrx_f.h" #include "mto.h" #include "wbhal.h" #include "wb35reg_f.h" -- cgit v1.2.3 From 4398954e5f91e340f5a2db53d219b6562e3e1bf0 Mon Sep 17 00:00:00 2001 From: Pekka Enberg Date: Sun, 28 Nov 2010 23:00:06 +0200 Subject: Staging: w35und: Kill wblinux_f.h header The wblinux_f.h header file doesn't contain anything that's actually used. Kill it. Cc: Pavel Machek Signed-off-by: Pekka Enberg Signed-off-by: Greg Kroah-Hartman --- drivers/staging/winbond/mds.c | 1 - drivers/staging/winbond/wblinux_f.h | 17 ----------------- drivers/staging/winbond/wbusb.c | 1 - 3 files changed, 19 deletions(-) delete mode 100644 drivers/staging/winbond/wblinux_f.h diff --git a/drivers/staging/winbond/mds.c b/drivers/staging/winbond/mds.c index 00e9756da9c1..9cfea94bcea5 100644 --- a/drivers/staging/winbond/mds.c +++ b/drivers/staging/winbond/mds.c @@ -1,7 +1,6 @@ #include "mds_f.h" #include "mto.h" #include "wbhal.h" -#include "wblinux_f.h" #include "wb35tx_f.h" unsigned char diff --git a/drivers/staging/winbond/wblinux_f.h b/drivers/staging/winbond/wblinux_f.h deleted file mode 100644 index 0a9d214f7187..000000000000 --- a/drivers/staging/winbond/wblinux_f.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef __WBLINUX_F_H -#define __WBLINUX_F_H - -#include "core.h" -#include "mds_s.h" - -/* - * ==================================================================== - * Copyright (c) 1996-2004 Winbond Electronic Corporation - * - * wblinux_f.h - * ==================================================================== - */ -int wb35_start_xmit(struct sk_buff *skb, struct net_device *netdev); -void wb35_set_multicast(struct net_device *netdev); -struct net_device_stats *wb35_netdev_stats(struct net_device *netdev); -#endif diff --git a/drivers/staging/winbond/wbusb.c b/drivers/staging/winbond/wbusb.c index c5a3107bd4a7..4f959c203857 100644 --- a/drivers/staging/winbond/wbusb.c +++ b/drivers/staging/winbond/wbusb.c @@ -19,7 +19,6 @@ #include "wb35reg_f.h" #include "wb35tx_f.h" #include "wb35rx_f.h" -#include "wblinux_f.h" MODULE_DESCRIPTION("IS89C35 802.11bg WLAN USB Driver"); MODULE_LICENSE("GPL"); -- cgit v1.2.3 From 9be98819d31c4e105ad028ee092d27a46a9e298a Mon Sep 17 00:00:00 2001 From: Pekka Enberg Date: Sun, 28 Nov 2010 23:00:07 +0200 Subject: Staging: w35und: Remove unused fields from struct wb_usb This patch removes two unused fields from struct wb_usb: - DetectCount which is always zero - IsUsb20 which is a write-only struct member Cc: Pavel Machek Signed-off-by: Pekka Enberg Signed-off-by: Greg Kroah-Hartman --- drivers/staging/winbond/wb35reg_s.h | 1 - drivers/staging/winbond/wbusb.c | 8 ++------ drivers/staging/winbond/wbusb_s.h | 2 -- 3 files changed, 2 insertions(+), 9 deletions(-) diff --git a/drivers/staging/winbond/wb35reg_s.h b/drivers/staging/winbond/wb35reg_s.h index 9b782ededf43..eb274ffdd1ba 100644 --- a/drivers/staging/winbond/wb35reg_s.h +++ b/drivers/staging/winbond/wb35reg_s.h @@ -234,7 +234,6 @@ u32 hal_get_bss_pk_cnt(struct hw_data *hw_data); /* return 100ms count */ #define hal_get_time_count(_P) (_P->time_count / 10) -#define hal_detect_error(_P) (_P->WbUsb.DetectCount) #define hal_ibss_disconnect(_A) (hal_stop_sync_bss(_A)) diff --git a/drivers/staging/winbond/wbusb.c b/drivers/staging/winbond/wbusb.c index 4f959c203857..3f5baa7eac26 100644 --- a/drivers/staging/winbond/wbusb.c +++ b/drivers/staging/winbond/wbusb.c @@ -337,10 +337,8 @@ static void hal_stop(struct hw_data *pHwData) static unsigned char hal_idle(struct hw_data *pHwData) { struct wb35_reg *reg = &pHwData->reg; - struct wb_usb *pWbUsb = &pHwData->WbUsb; - if (!pHwData->SurpriseRemove - && (pWbUsb->DetectCount || reg->EP0vm_state != VM_STOP)) + if (!pHwData->SurpriseRemove && reg->EP0vm_state != VM_STOP) return false; return true; @@ -786,10 +784,8 @@ static int wb35_probe(struct usb_interface *intf, interface = intf->cur_altsetting; endpoint = &interface->endpoint[0].desc; - if (endpoint[2].wMaxPacketSize == 512) { + if (endpoint[2].wMaxPacketSize == 512) printk("[w35und] Working on USB 2.0\n"); - pWbUsb->IsUsb20 = 1; - } err = wb35_hw_init(dev); if (err) diff --git a/drivers/staging/winbond/wbusb_s.h b/drivers/staging/winbond/wbusb_s.h index 8961ae594c4e..f62639176a4f 100644 --- a/drivers/staging/winbond/wbusb_s.h +++ b/drivers/staging/winbond/wbusb_s.h @@ -11,8 +11,6 @@ #include struct wb_usb { - u32 IsUsb20; struct usb_device *udev; - u32 DetectCount; }; #endif -- cgit v1.2.3 From 2894c6cd0ea84c30fc028ba92f8e61fbe7971e65 Mon Sep 17 00:00:00 2001 From: Pekka Enberg Date: Sun, 28 Nov 2010 23:00:08 +0200 Subject: Staging: w35und: Kill struct wb_usb This patch kills struct wb_usb which now only contains a pointer to struct usb_device. Cc: Pavel Machek Signed-off-by: Pekka Enberg Signed-off-by: Greg Kroah-Hartman --- drivers/staging/winbond/wb35reg.c | 12 ++++++------ drivers/staging/winbond/wb35rx.c | 4 ++-- drivers/staging/winbond/wb35tx.c | 6 +++--- drivers/staging/winbond/wbhal.h | 3 +-- drivers/staging/winbond/wbusb.c | 4 +--- drivers/staging/winbond/wbusb_s.h | 16 ---------------- 6 files changed, 13 insertions(+), 32 deletions(-) delete mode 100644 drivers/staging/winbond/wbusb_s.h diff --git a/drivers/staging/winbond/wb35reg.c b/drivers/staging/winbond/wb35reg.c index a15de1eab796..42ae61014522 100644 --- a/drivers/staging/winbond/wb35reg.c +++ b/drivers/staging/winbond/wb35reg.c @@ -139,8 +139,8 @@ unsigned char Wb35Reg_WriteSync(struct hw_data *pHwData, u16 RegisterNo, u32 Reg /* Sync IoCallDriver */ reg->EP0vm_state = VM_RUNNING; - ret = usb_control_msg(pHwData->WbUsb.udev, - usb_sndctrlpipe(pHwData->WbUsb.udev, 0), + ret = usb_control_msg(pHwData->udev, + usb_sndctrlpipe(pHwData->udev, 0), 0x03, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT, 0x0, RegisterNo, &RegisterValue, 4, HZ * 100); reg->EP0vm_state = VM_STOP; @@ -302,8 +302,8 @@ unsigned char Wb35Reg_ReadSync(struct hw_data *pHwData, u16 RegisterNo, u32 *pRe msleep(10); reg->EP0vm_state = VM_RUNNING; - ret = usb_control_msg(pHwData->WbUsb.udev, - usb_rcvctrlpipe(pHwData->WbUsb.udev, 0), + ret = usb_control_msg(pHwData->udev, + usb_rcvctrlpipe(pHwData->udev, 0), 0x01, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, 0x0, RegisterNo, pltmp, 4, HZ * 100); @@ -427,8 +427,8 @@ void Wb35Reg_EP0VM(struct hw_data *pHwData) if (reg_queue->DIRECT == 1) /* output */ pBuffer = ®_queue->VALUE; - usb_fill_control_urb(urb, pHwData->WbUsb.udev, - REG_DIRECTION(pHwData->WbUsb.udev, reg_queue), + usb_fill_control_urb(urb, pHwData->udev, + REG_DIRECTION(pHwData->udev, reg_queue), (u8 *)dr, pBuffer, cpu_to_le16(dr->wLength), Wb35Reg_EP0VM_complete, (void *)pHwData); diff --git a/drivers/staging/winbond/wb35rx.c b/drivers/staging/winbond/wb35rx.c index 190758ebad5c..f118eeba396a 100644 --- a/drivers/staging/winbond/wb35rx.c +++ b/drivers/staging/winbond/wb35rx.c @@ -260,8 +260,8 @@ static void Wb35Rx(struct ieee80211_hw *hw) } pRxBufferAddress = pWb35Rx->pDRx; - usb_fill_bulk_urb(urb, pHwData->WbUsb.udev, - usb_rcvbulkpipe(pHwData->WbUsb.udev, 3), + usb_fill_bulk_urb(urb, pHwData->udev, + usb_rcvbulkpipe(pHwData->udev, 3), pRxBufferAddress, MAX_USB_RX_BUFFER, Wb35Rx_Complete, hw); diff --git a/drivers/staging/winbond/wb35tx.c b/drivers/staging/winbond/wb35tx.c index 5e9e21a6dbff..44fc3fe79b79 100644 --- a/drivers/staging/winbond/wb35tx.c +++ b/drivers/staging/winbond/wb35tx.c @@ -88,8 +88,8 @@ static void Wb35Tx(struct wbsoft_priv *adapter) // // Issuing URB // - usb_fill_bulk_urb(pUrb, pHwData->WbUsb.udev, - usb_sndbulkpipe(pHwData->WbUsb.udev, 4), + usb_fill_bulk_urb(pUrb, pHwData->udev, + usb_sndbulkpipe(pHwData->udev, 4), pTxBufferAddress, pMds->TxBufferSize[ SendIndex ], Wb35Tx_complete, adapter); @@ -265,7 +265,7 @@ static void Wb35Tx_EP2VM(struct wbsoft_priv *adapter) // // Issuing URB // - usb_fill_int_urb( pUrb, pHwData->WbUsb.udev, usb_rcvintpipe(pHwData->WbUsb.udev,2), + usb_fill_int_urb( pUrb, pHwData->udev, usb_rcvintpipe(pHwData->udev,2), pltmp, MAX_INTERRUPT_LENGTH, Wb35Tx_EP2VM_complete, adapter, 32); pWb35Tx->EP2vm_state = VM_RUNNING; diff --git a/drivers/staging/winbond/wbhal.h b/drivers/staging/winbond/wbhal.h index dcf3b213b4f1..39e84a0d9729 100644 --- a/drivers/staging/winbond/wbhal.h +++ b/drivers/staging/winbond/wbhal.h @@ -356,7 +356,6 @@ struct txvga_for_50 { * ============================================== */ -#include "wbusb_s.h" #include "wb35reg_s.h" #include "wb35tx_s.h" #include "wb35rx_s.h" @@ -437,7 +436,7 @@ struct hw_data { * Variable for each module * ================================================== */ - struct wb_usb WbUsb; /* Need WbUsb.h */ + struct usb_device *udev; struct wb35_reg reg; /* Need Wb35Reg.h */ struct wb35_tx Wb35Tx; /* Need Wb35Tx.h */ struct wb35_rx Wb35Rx; /* Need Wb35Rx.h */ diff --git a/drivers/staging/winbond/wbusb.c b/drivers/staging/winbond/wbusb.c index 3f5baa7eac26..2163d60c2eaf 100644 --- a/drivers/staging/winbond/wbusb.c +++ b/drivers/staging/winbond/wbusb.c @@ -747,7 +747,6 @@ static int wb35_probe(struct usb_interface *intf, struct usb_host_interface *interface; struct ieee80211_hw *dev; struct wbsoft_priv *priv; - struct wb_usb *pWbUsb; int nr, err; u32 ltmp; @@ -778,8 +777,7 @@ static int wb35_probe(struct usb_interface *intf, priv = dev->priv; - pWbUsb = &priv->sHwData.WbUsb; - pWbUsb->udev = udev; + priv->sHwData.udev = udev; interface = intf->cur_altsetting; endpoint = &interface->endpoint[0].desc; diff --git a/drivers/staging/winbond/wbusb_s.h b/drivers/staging/winbond/wbusb_s.h deleted file mode 100644 index f62639176a4f..000000000000 --- a/drivers/staging/winbond/wbusb_s.h +++ /dev/null @@ -1,16 +0,0 @@ -/* ========================================================= - * Copyright (c) 1996-2004 Winbond Electronic Corporation - * - * Module Name: - * wbusb_s.h - * ========================================================= - */ -#ifndef __WINBOND_WBUSB_S_H -#define __WINBOND_WBUSB_S_H - -#include - -struct wb_usb { - struct usb_device *udev; -}; -#endif -- cgit v1.2.3 From 0e7a3e7a746b5dc6ccf9896e882441c4fdbfd09a Mon Sep 17 00:00:00 2001 From: David Chosrova Date: Mon, 29 Nov 2010 21:50:48 +0100 Subject: Staging: rtl8192u: remove dead code to disable dot11d This patch removes all the ENABLE_DOT11D ifdefs. It is always defined for driver. DOT11D has to do with regulatory domains. What prompted this patch was a warning message in Sparse. drivers/staging/rtl8192u/r8192U_core.c:247:1: warning: "eqMacAddr" redefined in file included from drivers/staging/rtl8192u/:81:81: drivers/staging/rtl8192u/dot11d.h:35:1: warning: this is the location of the previous definition Now there are no ifdefs around dot11d.h it made no sense to have this second definition, so I removed that macro as well. ( Thanks Dan ;-) ). Acked-by. Dan Carpenter Signed-off-by: David Chosrova Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192u/Makefile | 1 - drivers/staging/rtl8192u/dot11d.h | 2 - drivers/staging/rtl8192u/ieee80211/Makefile | 2 - drivers/staging/rtl8192u/ieee80211/dot11d.c | 2 - drivers/staging/rtl8192u/ieee80211/dot11d.h | 3 -- drivers/staging/rtl8192u/ieee80211/ieee80211.h | 8 ---- drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c | 12 ------ .../staging/rtl8192u/ieee80211/ieee80211_softmac.c | 44 ---------------------- .../rtl8192u/ieee80211/ieee80211_softmac_wx.c | 4 -- drivers/staging/rtl8192u/r8192U_core.c | 21 ----------- drivers/staging/rtl8192u/r8192U_wx.c | 6 --- drivers/staging/rtl8192u/r819xU_phy.c | 4 -- 12 files changed, 109 deletions(-) diff --git a/drivers/staging/rtl8192u/Makefile b/drivers/staging/rtl8192u/Makefile index 206d924a707c..eefc657ce99e 100644 --- a/drivers/staging/rtl8192u/Makefile +++ b/drivers/staging/rtl8192u/Makefile @@ -9,7 +9,6 @@ ccflags-y += -DTHOMAS_BEACON -DTHOMAS_TASKLET -DTHOMAS_SKB -DTHOMAS_TURBO #ccflags-y += -DUSB_TX_DRIVER_AGGREGATION_ENABLE #ccflags-y += -DUSB_RX_AGGREGATION_SUPPORT ccflags-y += -DUSE_ONE_PIPE -ccflags-y += -DENABLE_DOT11D ccflags-y += -Idrivers/staging/rtl8192u/ieee80211 r8192u_usb-y := r8192U_core.o r8180_93cx6.o r8192U_wx.o \ diff --git a/drivers/staging/rtl8192u/dot11d.h b/drivers/staging/rtl8192u/dot11d.h index d99cc030ec7a..92e7a00f3ee1 100644 --- a/drivers/staging/rtl8192u/dot11d.h +++ b/drivers/staging/rtl8192u/dot11d.h @@ -1,7 +1,6 @@ #ifndef __INC_DOT11D_H #define __INC_DOT11D_H -#ifdef ENABLE_DOT11D #include "ieee80211/ieee80211.h" @@ -98,5 +97,4 @@ int ToLegalChannel( struct ieee80211_device *dev, u8 channel ); -#endif /* ENABLE_DOT11D */ #endif /* #ifndef __INC_DOT11D_H */ diff --git a/drivers/staging/rtl8192u/ieee80211/Makefile b/drivers/staging/rtl8192u/ieee80211/Makefile index 45704f85ef0b..0775c5599d69 100644 --- a/drivers/staging/rtl8192u/ieee80211/Makefile +++ b/drivers/staging/rtl8192u/ieee80211/Makefile @@ -20,7 +20,6 @@ ifeq ($(NIC_SELECT),RTL8192U) endif #ccflags-y := -DJOHN_NOCPY #flags to enable or disble 80211D feature -ccflags-y += -DENABLE_DOT11D ieee80211-rsl-objs := ieee80211_rx.o \ ieee80211_softmac.o \ ieee80211_tx.o \ @@ -75,7 +74,6 @@ CFLAGS += -I$(KSRC)/include -I. CFLAGS += -DMODVERSIONS -DEXPORT_SYMTAB -include $(KSRC)/include/linux/modversions.h #Kernel 2.4.20 #CFLAGS += -D__NO_VERSION__ -DEXPORT_SYMTAB -#CFLAGS += -DENABLE_DOT11D SMP := $(shell $(CC) $(MODCFLAGS) -E -dM $(CONFIG_FILE) | \ grep CONFIG_SMP | awk '{print $$3}') ifneq ($(SMP),1) diff --git a/drivers/staging/rtl8192u/ieee80211/dot11d.c b/drivers/staging/rtl8192u/ieee80211/dot11d.c index b91cbfcfa71f..ce63fc341c6e 100644 --- a/drivers/staging/rtl8192u/ieee80211/dot11d.c +++ b/drivers/staging/rtl8192u/ieee80211/dot11d.c @@ -1,4 +1,3 @@ -#ifdef ENABLE_DOT11D //----------------------------------------------------------------------------- // File: // Dot11d.c @@ -220,4 +219,3 @@ EXPORT_SYMBOL(DOT11D_ScanComplete); EXPORT_SYMBOL(IsLegalChannel); EXPORT_SYMBOL(ToLegalChannel); -#endif diff --git a/drivers/staging/rtl8192u/ieee80211/dot11d.h b/drivers/staging/rtl8192u/ieee80211/dot11d.h index 15b7a4ba37b6..54f2b4c434ff 100644 --- a/drivers/staging/rtl8192u/ieee80211/dot11d.h +++ b/drivers/staging/rtl8192u/ieee80211/dot11d.h @@ -1,10 +1,8 @@ #ifndef __INC_DOT11D_H #define __INC_DOT11D_H -#ifdef ENABLE_DOT11D #include "ieee80211.h" -//#define ENABLE_DOT11D //#define DOT11D_MAX_CHNL_NUM 83 @@ -98,5 +96,4 @@ int ToLegalChannel( struct ieee80211_device * dev, u8 channel ); -#endif //ENABLE_DOT11D #endif // #ifndef __INC_DOT11D_H diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211.h b/drivers/staging/rtl8192u/ieee80211/ieee80211.h index e1216b704959..c0b844d75c0d 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211.h +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211.h @@ -1572,10 +1572,8 @@ struct ieee80211_network { #ifdef THOMAS_TURBO u8 Turbo_Enable;//enable turbo mode, added by thomas #endif -#ifdef ENABLE_DOT11D u16 CountryIeLen; u8 CountryIeBuf[MAX_IE_LEN]; -#endif // HT Related, by amy, 2008.04.29 BSS_HT bssht; // Add to handle broadcom AP management frame CCK rate. @@ -1769,7 +1767,6 @@ typedef u32 RT_RF_CHANGE_SOURCE; #define RF_CHANGE_BY_IPS BIT28 #define RF_CHANGE_BY_INIT 0 // Do not change the RFOff reason. Defined by Bruce, 2008-01-17. -#ifdef ENABLE_DOT11D typedef enum { COUNTRY_CODE_FCC = 0, @@ -1784,7 +1781,6 @@ typedef enum COUNTRY_CODE_MIC, COUNTRY_CODE_GLOBAL_DOMAIN }country_code_type_t; -#endif #define RT_MAX_LD_SLOT_NUM 10 typedef struct _RT_LINK_DETECT_T{ @@ -1970,12 +1966,8 @@ struct ieee80211_device { /* map of allowed channels. 0 is dummy */ // FIXME: remeber to default to a basic channel plan depending of the PHY type -#ifdef ENABLE_DOT11D void* pDot11dInfo; bool bGlobalDomain; -#else - int channel_map[MAX_CHANNEL_NUMBER+1]; -#endif int rate; /* current rate */ int basic_rate; //FIXME: pleace callback, see if redundant with softmac_features diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c index c8ca9d8ed5d2..1ea8da3655ec 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_rx.c @@ -44,9 +44,7 @@ #include #include "ieee80211.h" -#ifdef ENABLE_DOT11D #include "dot11d.h" -#endif static inline void ieee80211_monitor_rx(struct ieee80211_device *ieee, struct sk_buff *skb, struct ieee80211_rx_stats *rx_stats) @@ -1599,7 +1597,6 @@ static const char *get_info_element_string(u16 id) } #endif -#ifdef ENABLE_DOT11D static inline void ieee80211_extract_country_ie( struct ieee80211_device *ieee, struct ieee80211_info_element *info_element, @@ -1632,7 +1629,6 @@ static inline void ieee80211_extract_country_ie( } } -#endif int ieee80211_parse_info_param(struct ieee80211_device *ieee, struct ieee80211_info_element *info_element, @@ -2086,14 +2082,12 @@ int ieee80211_parse_info_param(struct ieee80211_device *ieee, "QoS Error need to parse QOS_PARAMETER IE\n"); break; -#ifdef ENABLE_DOT11D case MFIE_TYPE_COUNTRY: IEEE80211_DEBUG_SCAN("MFIE_TYPE_COUNTRY: %d bytes\n", info_element->len); //printk("=====>Receive <%s> Country IE\n",network->ssid); ieee80211_extract_country_ie(ieee, info_element, network, network->bssid);//addr2 is same as addr3 when from an AP break; -#endif /* TODO */ default: IEEE80211_DEBUG_MGMT @@ -2229,10 +2223,8 @@ static inline int ieee80211_network_init( #ifdef THOMAS_TURBO network->Turbo_Enable = 0; #endif -#ifdef ENABLE_DOT11D network->CountryIeLen = 0; memset(network->CountryIeBuf, 0, MAX_IE_LEN); -#endif //Initialize HT parameters //ieee80211_ht_initialize(&network->bssht); HTInitializeBssDesc(&network->bssht); @@ -2399,10 +2391,8 @@ static inline void update_network(struct ieee80211_network *dst, dst->Turbo_Enable = src->Turbo_Enable; #endif -#ifdef ENABLE_DOT11D dst->CountryIeLen = src->CountryIeLen; memcpy(dst->CountryIeBuf, src->CountryIeBuf, src->CountryIeLen); -#endif //added by amy for LEAP dst->bWithAironetIE = src->bWithAironetIE; @@ -2470,7 +2460,6 @@ static inline void ieee80211_process_probe_response( return; } -#ifdef ENABLE_DOT11D // For Asus EeePc request, // (1) if wireless adapter receive get any 802.11d country code in AP beacon, // wireless adapter should follow the country code. @@ -2527,7 +2516,6 @@ static inline void ieee80211_process_probe_response( } } } -#endif /* The network parsed correctly -- so now we scan our known networks * to see if we can find it in our list. diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c index bc8c42533693..12858880f95f 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c @@ -21,9 +21,7 @@ #include #include #include -#ifdef ENABLE_DOT11D #include "dot11d.h" -#endif u8 rsn_authen_cipher_suite[16][4] = { {0x00,0x0F,0xAC,0x00}, //Use group key, //Reserved @@ -430,10 +428,8 @@ void ieee80211_send_probe_requests(struct ieee80211_device *ieee) void ieee80211_softmac_scan_syncro(struct ieee80211_device *ieee) { short ch = 0; -#ifdef ENABLE_DOT11D u8 channel_map[MAX_CHANNEL_NUMBER+1]; memcpy(channel_map, GET_DOT11D_INFO(ieee)->channel_map, MAX_CHANNEL_NUMBER+1); -#endif down(&ieee->scan_sem); while(1) @@ -443,11 +439,7 @@ void ieee80211_softmac_scan_syncro(struct ieee80211_device *ieee) ch++; if (ch > MAX_CHANNEL_NUMBER) goto out; /* scan completed */ -#ifdef ENABLE_DOT11D }while(!channel_map[ch]); -#else - }while(!ieee->channel_map[ch]); -#endif /* this function can be called in two situations * 1- We have switched to ad-hoc mode and we are @@ -471,9 +463,7 @@ void ieee80211_softmac_scan_syncro(struct ieee80211_device *ieee) if (ieee->state == IEEE80211_LINKED) goto out; ieee->set_chan(ieee->dev, ch); -#ifdef ENABLE_DOT11D if(channel_map[ch] == 1) -#endif ieee80211_send_probe_requests(ieee); /* this prevent excessive time wait when we @@ -496,10 +486,8 @@ out: } else{ ieee->sync_scan_hurryup = 0; -#ifdef ENABLE_DOT11D if(IS_DOT11D_ENABLE(ieee)) DOT11D_ScanComplete(ieee); -#endif up(&ieee->scan_sem); } } @@ -510,10 +498,8 @@ void ieee80211_softmac_scan_wq(struct work_struct *work) struct delayed_work *dwork = container_of(work, struct delayed_work, work); struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, softmac_scan_wq); static short watchdog = 0; -#ifdef ENABLE_DOT11D u8 channel_map[MAX_CHANNEL_NUMBER+1]; memcpy(channel_map, GET_DOT11D_INFO(ieee)->channel_map, MAX_CHANNEL_NUMBER+1); -#endif if(!ieee->ieee_up) return; down(&ieee->scan_sem); @@ -523,25 +509,15 @@ void ieee80211_softmac_scan_wq(struct work_struct *work) if (watchdog++ > MAX_CHANNEL_NUMBER) { //if current channel is not in channel map, set to default channel. - #ifdef ENABLE_DOT11D if (!channel_map[ieee->current_network.channel]); - #else - if (!ieee->channel_map[ieee->current_network.channel]); - #endif ieee->current_network.channel = 6; goto out; /* no good chans */ } -#ifdef ENABLE_DOT11D }while(!channel_map[ieee->current_network.channel]); -#else - }while(!ieee->channel_map[ieee->current_network.channel]); -#endif if (ieee->scanning == 0 ) goto out; ieee->set_chan(ieee->dev, ieee->current_network.channel); -#ifdef ENABLE_DOT11D if(channel_map[ieee->current_network.channel] == 1) -#endif ieee80211_send_probe_requests(ieee); @@ -550,10 +526,8 @@ void ieee80211_softmac_scan_wq(struct work_struct *work) up(&ieee->scan_sem); return; out: -#ifdef ENABLE_DOT11D if(IS_DOT11D_ENABLE(ieee)) DOT11D_ScanComplete(ieee); -#endif ieee->actscanning = false; watchdog = 0; ieee->scanning = 0; @@ -635,7 +609,6 @@ void ieee80211_stop_scan(struct ieee80211_device *ieee) /* called with ieee->lock held */ void ieee80211_start_scan(struct ieee80211_device *ieee) { -#ifdef ENABLE_DOT11D if(IS_DOT11D_ENABLE(ieee) ) { if(IS_COUNTRY_IE_VALID(ieee)) @@ -643,7 +616,6 @@ void ieee80211_start_scan(struct ieee80211_device *ieee) RESET_CIE_WATCHDOG(ieee); } } -#endif if (ieee->softmac_features & IEEE_SOFTMAC_SCAN){ if (ieee->scanning == 0){ ieee->scanning = 1; @@ -657,7 +629,6 @@ void ieee80211_start_scan(struct ieee80211_device *ieee) /* called with wx_sem held */ void ieee80211_start_scan_syncro(struct ieee80211_device *ieee) { -#ifdef ENABLE_DOT11D if(IS_DOT11D_ENABLE(ieee) ) { if(IS_COUNTRY_IE_VALID(ieee)) @@ -665,7 +636,6 @@ void ieee80211_start_scan_syncro(struct ieee80211_device *ieee) RESET_CIE_WATCHDOG(ieee); } } -#endif ieee->sync_scan_hurryup = 0; if (ieee->softmac_features & IEEE_SOFTMAC_SCAN) ieee80211_softmac_scan_syncro(ieee); @@ -2390,11 +2360,9 @@ void ieee80211_start_ibss_wq(struct work_struct *work) ieee80211_softmac_check_all_nets(ieee); -#ifdef ENABLE_DOT11D //if creating an ad-hoc, set its channel to 10 temporarily--this is the requirement for ASUS, not 11D, so disable 11d. // if((IS_DOT11D_ENABLE(ieee)) && (ieee->state == IEEE80211_NOLINK)) if (ieee->state == IEEE80211_NOLINK) ieee->current_network.channel = 6; -#endif /* if not then the state is not linked. Maybe the user swithced to * ad-hoc mode just after being in monitor mode, or just after * being very few time in managed mode (so the card have had no @@ -2483,7 +2451,6 @@ inline void ieee80211_start_ibss(struct ieee80211_device *ieee) void ieee80211_start_bss(struct ieee80211_device *ieee) { unsigned long flags; -#ifdef ENABLE_DOT11D // // Ref: 802.11d 11.1.3.3 // STA shall not start a BSS unless properly formed Beacon frame including a Country IE. @@ -2495,7 +2462,6 @@ void ieee80211_start_bss(struct ieee80211_device *ieee) return; } } -#endif /* check if we have already found the net we * are interested in (if any). * if not (we are disassociated and we are not @@ -2530,10 +2496,8 @@ void ieee80211_disassociate(struct ieee80211_device *ieee) if (ieee->data_hard_stop) ieee->data_hard_stop(ieee->dev); -#ifdef ENABLE_DOT11D if(IS_DOT11D_ENABLE(ieee)) Dot11d_Reset(ieee); -#endif ieee->state = IEEE80211_NOLINK; ieee->is_set_key = false; ieee->link_change(ieee->dev); @@ -2669,11 +2633,7 @@ void ieee80211_start_protocol(struct ieee80211_device *ieee) ch++; if (ch > MAX_CHANNEL_NUMBER) return; /* no channel found */ -#ifdef ENABLE_DOT11D }while(!GET_DOT11D_INFO(ieee)->channel_map[ch]); -#else - }while(!ieee->channel_map[ch]); -#endif ieee->current_network.channel = ch; } @@ -2721,11 +2681,9 @@ void ieee80211_softmac_init(struct ieee80211_device *ieee) for(i = 0; i < 5; i++) { ieee->seq_ctrl[i] = 0; } -#ifdef ENABLE_DOT11D ieee->pDot11dInfo = kzalloc(sizeof(RT_DOT11D_INFO), GFP_ATOMIC); if (!ieee->pDot11dInfo) IEEE80211_DEBUG(IEEE80211_DL_ERR, "can't alloc memory for DOT11D\n"); -#endif //added for AP roaming ieee->LinkDetectInfo.SlotNum = 2; ieee->LinkDetectInfo.NumRecvBcnInPeriod=0; @@ -2796,13 +2754,11 @@ void ieee80211_softmac_init(struct ieee80211_device *ieee) void ieee80211_softmac_free(struct ieee80211_device *ieee) { down(&ieee->wx_sem); -#ifdef ENABLE_DOT11D if(NULL != ieee->pDot11dInfo) { kfree(ieee->pDot11dInfo); ieee->pDot11dInfo = NULL; } -#endif del_timer_sync(&ieee->associate_timer); cancel_delayed_work(&ieee->associate_retry_wq); diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac_wx.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac_wx.c index f335c258ba84..cb5a3c32974e 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac_wx.c +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac_wx.c @@ -15,9 +15,7 @@ #include "ieee80211.h" -#ifdef ENABLE_DOT11D #include "dot11d.h" -#endif /* FIXME: add A freqs */ const long ieee80211_wlan_frequencies[] = { @@ -63,12 +61,10 @@ int ieee80211_wx_set_freq(struct ieee80211_device *ieee, struct iw_request_info }else { /* Set the channel */ -#ifdef ENABLE_DOT11D if (!(GET_DOT11D_INFO(ieee)->channel_map)[fwrq->m]) { ret = -EINVAL; goto out; } -#endif ieee->current_network.channel = fwrq->m; ieee->set_chan(ieee->dev, ieee->current_network.channel); diff --git a/drivers/staging/rtl8192u/r8192U_core.c b/drivers/staging/rtl8192u/r8192U_core.c index cbfe1341d856..9cd41b698161 100644 --- a/drivers/staging/rtl8192u/r8192U_core.c +++ b/drivers/staging/rtl8192u/r8192U_core.c @@ -77,9 +77,7 @@ double __extendsfdf2(float a) {return a;} #include "r8192_pm.h" #endif -#ifdef ENABLE_DOT11D #include "dot11d.h" -#endif //set here to open your trace code. //WB u32 rt_global_debug_component = \ // COMP_INIT | @@ -166,7 +164,6 @@ static struct usb_driver rtl8192_usb_driver = { #endif }; -#ifdef ENABLE_DOT11D typedef struct _CHANNEL_LIST { @@ -242,9 +239,7 @@ static void rtl819x_set_channel_map(u8 channel_plan, struct r8192_priv* priv) } return; } -#endif -#define eqMacAddr(a,b) ( ((a)[0]==(b)[0] && (a)[1]==(b)[1] && (a)[2]==(b)[2] && (a)[3]==(b)[3] && (a)[4]==(b)[4] && (a)[5]==(b)[5]) ? 1:0 ) #define rx_hal_is_cck_rate(_pdrvinfo)\ (_pdrvinfo->RxRate == DESC90_RATE1M ||\ @@ -3155,7 +3150,6 @@ static void rtl8192_read_eeprom_info(struct net_device* dev) short rtl8192_get_channel_map(struct net_device * dev) { struct r8192_priv *priv = ieee80211_priv(dev); -#ifdef ENABLE_DOT11D if(priv->ChannelPlan > COUNTRY_CODE_GLOBAL_DOMAIN){ printk("rtl8180_init:Error channel plan! Set to default.\n"); priv->ChannelPlan= 0; @@ -3163,21 +3157,6 @@ short rtl8192_get_channel_map(struct net_device * dev) RT_TRACE(COMP_INIT, "Channel plan is %d\n",priv->ChannelPlan); rtl819x_set_channel_map(priv->ChannelPlan, priv); -#else - int ch,i; - //Set Default Channel Plan - if(!channels){ - DMESG("No channels, aborting"); - return -1; - } - ch=channels; - priv->ChannelPlan= 0;//hikaru - // set channels 1..14 allowed in given locale - for (i=1; i<=14; i++) { - (priv->ieee80211->channel_map)[i] = (u8)(ch & 0x01); - ch >>= 1; - } -#endif return 0; } diff --git a/drivers/staging/rtl8192u/r8192U_wx.c b/drivers/staging/rtl8192u/r8192U_wx.c index 25d5c870b0fb..f6408f98ede6 100644 --- a/drivers/staging/rtl8192u/r8192U_wx.c +++ b/drivers/staging/rtl8192u/r8192U_wx.c @@ -21,9 +21,7 @@ #include "r8192U.h" #include "r8192U_hw.h" -#ifdef ENABLE_DOT11D #include "dot11d.h" -#endif #define RATE_COUNT 12 u32 rtl8180_rates[] = {1000000,2000000,5500000,11000000, @@ -458,11 +456,7 @@ static int rtl8180_wx_get_range(struct net_device *dev, for (i = 0, val = 0; i < 14; i++) { // Include only legal frequencies for some countries -#ifdef ENABLE_DOT11D if ((GET_DOT11D_INFO(priv->ieee80211)->channel_map)[i+1]) { -#else - if ((priv->ieee80211->channel_map)[i+1]) { -#endif range->freq[val].i = i + 1; range->freq[val].m = ieee80211_wlan_frequencies[i] * 100000; range->freq[val].e = 1; diff --git a/drivers/staging/rtl8192u/r819xU_phy.c b/drivers/staging/rtl8192u/r819xU_phy.c index 8e10992366fe..41684e8fcf4c 100644 --- a/drivers/staging/rtl8192u/r819xU_phy.c +++ b/drivers/staging/rtl8192u/r819xU_phy.c @@ -6,9 +6,7 @@ #include "r8192U_dm.h" #include "r819xU_firmware_img.h" -#ifdef ENABLE_DOT11D #include "dot11d.h" -#endif static u32 RF_CHANNEL_TABLE_ZEBRA[] = { 0, 0x085c, //2412 1 @@ -1257,13 +1255,11 @@ u8 rtl8192_phy_SwChnlStepByStep(struct net_device *dev, u8 channel, u8* stage, u RT_TRACE(COMP_CH, "====>%s()====stage:%d, step:%d, channel:%d\n", __FUNCTION__, *stage, *step, channel); // RT_ASSERT(IsLegalChannel(Adapter, channel), ("illegal channel: %d\n", channel)); -#ifdef ENABLE_DOT11D if (!IsLegalChannel(priv->ieee80211, channel)) { RT_TRACE(COMP_ERR, "=============>set to illegal channel:%d\n", channel); return true; //return true to tell upper caller function this channel setting is finished! Or it will in while loop. } -#endif //FIXME:need to check whether channel is legal or not here.WB -- cgit v1.2.3 From 8c66be9203d891ea37346a78925f0e6534b98bd3 Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Wed, 1 Dec 2010 17:34:39 +0100 Subject: staging: iio: dds: ad9832: Fix kconfig description The AD9832 driver doesn't support the AD9833 and AD9834 Signed-off-by: Michael Hennerich Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/dds/Kconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/iio/dds/Kconfig b/drivers/staging/iio/dds/Kconfig index d045ed69ad38..7969be29b0eb 100644 --- a/drivers/staging/iio/dds/Kconfig +++ b/drivers/staging/iio/dds/Kconfig @@ -11,11 +11,11 @@ config AD5930 ad5930/ad5932, provides direct access via sysfs. config AD9832 - tristate "Analog Devices ad9832/3/4/5 driver" + tristate "Analog Devices ad9832/5 driver" depends on SPI help Say yes here to build support for Analog Devices DDS chip - ad9832/3/4/5, provides direct access via sysfs. + ad9832 and ad9835, provides direct access via sysfs. config AD9850 tristate "Analog Devices ad9850/1 driver" -- cgit v1.2.3 From b834517572d19d34c9cd9adb878aec3138db9224 Mon Sep 17 00:00:00 2001 From: David Chosrova Date: Wed, 1 Dec 2010 13:42:16 +0100 Subject: Staging: rtl8192u: check return code kmalloc. This patch checks the return code of kmalloc when trying to allocate memory for priv->rx_urb in rtl8192_usb_initendpoints(), return -ENOMEM when failed. Signed-off-by: David Chosrova Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192u/r8192U_core.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/staging/rtl8192u/r8192U_core.c b/drivers/staging/rtl8192u/r8192U_core.c index 9cd41b698161..ae4f2b9d9e8f 100644 --- a/drivers/staging/rtl8192u/r8192U_core.c +++ b/drivers/staging/rtl8192u/r8192U_core.c @@ -2198,6 +2198,8 @@ short rtl8192_usb_initendpoints(struct net_device *dev) priv->rx_urb = kmalloc(sizeof(struct urb *) * (MAX_RX_URB+1), GFP_KERNEL); + if (priv->rx_urb == NULL) + return -ENOMEM; #ifndef JACKSON_NEW_RX for(i=0;i<(MAX_RX_URB+1);i++){ -- cgit v1.2.3 From 954c7a6c960bcedf28e8b5dcdcd6fe68d8c6c110 Mon Sep 17 00:00:00 2001 From: Brett Rudley Date: Tue, 30 Nov 2010 15:22:13 -0800 Subject: staging: brcm80211: Remove OSL_DMADDRWIDTH Signed-off-by: Brett Rudley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/include/linux_osl.h | 3 --- drivers/staging/brcm80211/sys/wlc_bmac.c | 1 - 2 files changed, 4 deletions(-) diff --git a/drivers/staging/brcm80211/include/linux_osl.h b/drivers/staging/brcm80211/include/linux_osl.h index b973f3fea7e2..18bc1f0d2d84 100644 --- a/drivers/staging/brcm80211/include/linux_osl.h +++ b/drivers/staging/brcm80211/include/linux_osl.h @@ -85,9 +85,6 @@ extern uint osl_dma_map(struct osl_info *osh, void *va, uint size, extern void osl_dma_unmap(struct osl_info *osh, uint pa, uint size, int direction); -/* API for DMA addressing capability */ -#define OSL_DMADDRWIDTH(osh, addrwidth) do {} while (0) - /* register access macros */ #if defined(BCMSDIO) #ifdef BRCM_FULLMAC diff --git a/drivers/staging/brcm80211/sys/wlc_bmac.c b/drivers/staging/brcm80211/sys/wlc_bmac.c index d427980aebed..2245a8b25a24 100644 --- a/drivers/staging/brcm80211/sys/wlc_bmac.c +++ b/drivers/staging/brcm80211/sys/wlc_bmac.c @@ -588,7 +588,6 @@ static bool wlc_bmac_attach_dmapio(wlc_info_t *wlc, uint j, bool wme) */ addrwidth = dma_addrwidth(wlc_hw->sih, DMAREG(wlc_hw, DMA_TX, 0)); - OSL_DMADDRWIDTH(osh, addrwidth); if (!wl_alloc_dma_resources(wlc_hw->wlc->wl, addrwidth)) { WL_ERROR(("wl%d: wlc_attach: alloc_dma_resources failed\n", unit)); -- cgit v1.2.3 From f5343314f62ba392ec069210ae342bc32c4ce367 Mon Sep 17 00:00:00 2001 From: Brett Rudley Date: Tue, 30 Nov 2010 15:22:14 -0800 Subject: staging: brcm80211: Remove unused PKTFREESETCB Signed-off-by: Brett Rudley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/include/linux_osl.h | 6 ------ drivers/staging/brcm80211/include/osl.h | 6 ------ drivers/staging/brcm80211/util/linux_osl.c | 3 --- 3 files changed, 15 deletions(-) diff --git a/drivers/staging/brcm80211/include/linux_osl.h b/drivers/staging/brcm80211/include/linux_osl.h index 18bc1f0d2d84..0e2e53e623cf 100644 --- a/drivers/staging/brcm80211/include/linux_osl.h +++ b/drivers/staging/brcm80211/include/linux_osl.h @@ -47,12 +47,6 @@ extern void osl_assert(char *exp, char *file, int line); extern uint osl_pci_bus(struct osl_info *osh); extern uint osl_pci_slot(struct osl_info *osh); -#define PKTFREESETCB(osh, _tx_fn, _tx_ctx) \ - do { \ - ((struct osl_pubinfo *)osh)->tx_fn = _tx_fn; \ - ((struct osl_pubinfo *)osh)->tx_ctx = _tx_ctx; \ - } while (0) - #define BUS_SWAP32(v) (v) extern void *osl_dma_alloc_consistent(struct osl_info *osh, uint size, diff --git a/drivers/staging/brcm80211/include/osl.h b/drivers/staging/brcm80211/include/osl.h index 4d0ce9705500..186bb77b7623 100644 --- a/drivers/staging/brcm80211/include/osl.h +++ b/drivers/staging/brcm80211/include/osl.h @@ -17,15 +17,9 @@ #ifndef _osl_h_ #define _osl_h_ -/* Drivers use PKTFREESETCB to register a callback function - when a packet is freed by OSL */ -typedef void (*pktfree_cb_fn_t) (void *ctx, void *pkt, unsigned int status); - struct osl_pubinfo { uint pktalloced; /* Number of allocated packet buffers */ bool mmbus; /* Bus supports memory-mapped registers */ - pktfree_cb_fn_t tx_fn; /* Callback function for PKTFREE */ - void *tx_ctx; /* Context to the callback function */ }; /* osl handle type forward declaration */ diff --git a/drivers/staging/brcm80211/util/linux_osl.c b/drivers/staging/brcm80211/util/linux_osl.c index a0f9dcb0b786..260995e0e90e 100644 --- a/drivers/staging/brcm80211/util/linux_osl.c +++ b/drivers/staging/brcm80211/util/linux_osl.c @@ -103,9 +103,6 @@ void BCMFASTPATH osl_pktfree(struct osl_info *osh, void *p, bool send) skb = (struct sk_buff *)p; ASSERT(skb); - if (send && osh->pub.tx_fn) - osh->pub.tx_fn(osh->pub.tx_ctx, p, 0); - /* perversion: we use skb->next to chain multi-skb packets */ while (skb) { nskb = skb->next; -- cgit v1.2.3 From c53d201371bf45cdb5b843ade52edd8903bb72f6 Mon Sep 17 00:00:00 2001 From: Brett Rudley Date: Tue, 30 Nov 2010 15:22:15 -0800 Subject: staging: brcm80211: Remove bogus gcc version checking Signed-off-by: Brett Rudley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/include/linux_osl.h | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/drivers/staging/brcm80211/include/linux_osl.h b/drivers/staging/brcm80211/include/linux_osl.h index 0e2e53e623cf..94f5d12d53d9 100644 --- a/drivers/staging/brcm80211/include/linux_osl.h +++ b/drivers/staging/brcm80211/include/linux_osl.h @@ -29,17 +29,8 @@ extern u32 g_assert_type; do { if (!(exp)) osl_assert(#exp, __FILE__, __LINE__); } while (0) extern void osl_assert(char *exp, char *file, int line); #else -#ifdef __GNUC__ -#define GCC_VERSION \ - (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) -#if GCC_VERSION > 30100 #define ASSERT(exp) do {} while (0) -#else - /* ASSERT could cause segmentation fault on GCC3.1, use empty instead */ -#define ASSERT(exp) -#endif /* GCC_VERSION > 30100 */ -#endif /* __GNUC__ */ -#endif /* defined(BCMDBG_ASSERT) */ +#endif /* defined(BCMDBG_ASSERT) */ /* PCI device bus # and slot # */ #define OSL_PCI_BUS(osh) osl_pci_bus(osh) -- cgit v1.2.3 From c10407ac459577f6b58f3db0777b6d0d53a3be9f Mon Sep 17 00:00:00 2001 From: Brett Rudley Date: Tue, 30 Nov 2010 17:35:09 -0800 Subject: staging: brcm80211: remove OSL_SYSUPTIME_SUPPORT Signed-off-by: Brett Rudley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/include/osl.h | 7 ------- 1 file changed, 7 deletions(-) diff --git a/drivers/staging/brcm80211/include/osl.h b/drivers/staging/brcm80211/include/osl.h index 186bb77b7623..662b5197b374 100644 --- a/drivers/staging/brcm80211/include/osl.h +++ b/drivers/staging/brcm80211/include/osl.h @@ -56,11 +56,4 @@ typedef void (*osl_wreg_fn_t) (void *ctx, void *reg, unsigned int val, #define OR_REG(osh, r, v) W_REG(osh, (r), R_REG(osh, r) | (v)) #endif /* !OR_REG */ -#if !defined(OSL_SYSUPTIME) -#define OSL_SYSUPTIME() (0) -#define OSL_SYSUPTIME_SUPPORT false -#else -#define OSL_SYSUPTIME_SUPPORT true -#endif /* OSL_SYSUPTIME */ - #endif /* _osl_h_ */ -- cgit v1.2.3 From 9249ede9d4d9dbf41ab6545a7a43fd5f6e5aa620 Mon Sep 17 00:00:00 2001 From: Brett Rudley Date: Tue, 30 Nov 2010 20:09:49 -0800 Subject: staging: brcm80211: bzero => memset s/bzero/memset/g Signed-off-by: Brett Rudley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c | 2 +- .../brcm80211/brcmfmac/bcmsdh_sdmmc_linux.c | 2 +- drivers/staging/brcm80211/brcmfmac/dhd_sdio.c | 8 ++-- drivers/staging/brcm80211/brcmfmac/wl_iw.c | 24 +++++------ drivers/staging/brcm80211/include/linux_osl.h | 3 -- drivers/staging/brcm80211/phy/wlc_phy_cmn.c | 16 ++++---- drivers/staging/brcm80211/phy/wlc_phy_lcn.c | 6 +-- drivers/staging/brcm80211/sys/wl_mac80211.c | 8 ++-- drivers/staging/brcm80211/sys/wlc_ampdu.c | 6 +-- drivers/staging/brcm80211/sys/wlc_bmac.c | 2 +- drivers/staging/brcm80211/sys/wlc_channel.c | 10 ++--- drivers/staging/brcm80211/sys/wlc_mac80211.c | 48 +++++++++++----------- drivers/staging/brcm80211/sys/wlc_rate.c | 2 +- drivers/staging/brcm80211/util/bcmotp.c | 2 +- drivers/staging/brcm80211/util/bcmsrom.c | 2 +- drivers/staging/brcm80211/util/bcmutils.c | 2 +- drivers/staging/brcm80211/util/hnddma.c | 13 +++--- drivers/staging/brcm80211/util/linux_osl.c | 2 +- drivers/staging/brcm80211/util/siutils.c | 4 +- 19 files changed, 82 insertions(+), 80 deletions(-) diff --git a/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c b/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c index aadfe69a8a0c..2e02d5e58415 100644 --- a/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c +++ b/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c @@ -751,7 +751,7 @@ sdioh_cis_read(sdioh_info_t *sd, uint func, u8 *cisd, u32 length) sd_trace(("%s: Func = %d\n", __func__, func)); if (!sd->func_cis_ptr[func]) { - bzero(cis, length); + memset(cis, 0, length); sd_err(("%s: no func_cis_ptr[%d]\n", __func__, func)); return SDIOH_API_RC_FAIL; } diff --git a/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc_linux.c b/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc_linux.c index 14f73fd28760..ceaa47490680 100644 --- a/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc_linux.c +++ b/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc_linux.c @@ -213,7 +213,7 @@ int sdio_function_init(void) if (!gInstance) return -ENOMEM; - bzero(&sdmmc_dev, sizeof(sdmmc_dev)); + memset(&sdmmc_dev, 0, sizeof(sdmmc_dev)); error = sdio_register_driver(&bcmsdh_sdmmc_driver); return error; diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c b/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c index 9e96c7e6e3c5..6b41d1f1b764 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c +++ b/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c @@ -960,7 +960,7 @@ static int dhdsdio_txpkt(dhd_bus_t *bus, struct sk_buff *pkt, uint chan, frame = (u8 *) (pkt->data); ASSERT((pad + SDPCM_HDRLEN) <= (int)(pkt->len)); - bzero(frame, pad + SDPCM_HDRLEN); + memset(frame, 0, pad + SDPCM_HDRLEN); } } ASSERT(pad < DHD_SDALIGN); @@ -1252,7 +1252,7 @@ int dhd_bus_txctl(struct dhd_bus *bus, unsigned char *msg, uint msglen) frame -= doff; len += doff; msglen += doff; - bzero(frame, doff + SDPCM_HDRLEN); + memset(frame, 0, doff + SDPCM_HDRLEN); } ASSERT(doff < DHD_SDALIGN); } @@ -2536,7 +2536,7 @@ static int dhdsdio_write_vars(dhd_bus_t *bus) if (!vbuffer) return BCME_NOMEM; - bzero(vbuffer, varsize); + memset(vbuffer, 0, varsize); bcopy(bus->vars, vbuffer, bus->varsz); /* Write the vars list */ @@ -5285,7 +5285,7 @@ dhdsdio_probe_attach(struct dhd_bus *bus, struct osl_info *osh, void *sdh, "failed\n", fn)); break; } - bzero(cis[fn], SBSDIO_CIS_SIZE_LIMIT); + memset(cis[fn], 0, SBSDIO_CIS_SIZE_LIMIT); err = bcmsdh_cis_read(sdh, fn, cis[fn], SBSDIO_CIS_SIZE_LIMIT); diff --git a/drivers/staging/brcm80211/brcmfmac/wl_iw.c b/drivers/staging/brcm80211/brcmfmac/wl_iw.c index e714d6a9452b..8bf24c7ce684 100644 --- a/drivers/staging/brcm80211/brcmfmac/wl_iw.c +++ b/drivers/staging/brcm80211/brcmfmac/wl_iw.c @@ -347,10 +347,10 @@ wl_iw_config_commit(struct net_device *dev, if (!ssid.SSID_len) return 0; - bzero(&bssid, sizeof(struct sockaddr)); + memset(&bssid, 0, sizeof(struct sockaddr)); error = dev_wlc_ioctl(dev, WLC_REASSOC, &bssid, ETHER_ADDR_LEN); if (error) { - WL_ERROR(("%s: WLC_REASSOC to %s failed \n", __func__, + WL_ERROR(("%s: WLC_REASSOC to %s failed\n", __func__, ssid.SSID)); return error; } @@ -775,7 +775,7 @@ wl_iw_set_wap(struct net_device *dev, if (ETHER_ISBCAST(awrq->sa_data) || ETHER_ISNULLADDR(awrq->sa_data)) { scb_val_t scbval; - bzero(&scbval, sizeof(scb_val_t)); + memset(&scbval, 0, sizeof(scb_val_t)); (void)dev_wlc_ioctl(dev, WLC_DISASSOC, &scbval, sizeof(scb_val_t)); return 0; @@ -2412,7 +2412,7 @@ wl_iw_get_encode(struct net_device *dev, WL_TRACE(("%s: SIOCGIWENCODE\n", dev->name)); - bzero(&key, sizeof(wl_wsec_key_t)); + memset(&key, 0, sizeof(wl_wsec_key_t)); if ((dwrq->flags & IW_ENCODE_INDEX) == 0) { for (key.index = 0; key.index < DOT11_MAX_DEFAULT_KEYS; @@ -2647,7 +2647,7 @@ wl_iw_set_pmksa(struct net_device *dev, if (iwpmksa->cmd == IW_PMKSA_FLUSH) { WL_WSEC(("wl_iw_set_pmksa - IW_PMKSA_FLUSH\n")); - bzero((char *)&pmkid_list, sizeof(pmkid_list)); + memset((char *)&pmkid_list, 0, sizeof(pmkid_list)); } else if (iwpmksa->cmd == IW_PMKSA_REMOVE) { @@ -2676,7 +2676,7 @@ wl_iw_set_pmksa(struct net_device *dev, if ((pmkid_list.pmkids.npmkid > 0) && (i < pmkid_list.pmkids.npmkid)) { - bzero(&pmkid_list.pmkids.pmkid[i], sizeof(pmkid_t)); + memset(&pmkid_list.pmkids.pmkid[i], 0, sizeof(pmkid_t)); for (; i < (pmkid_list.pmkids.npmkid - 1); i++) { bcopy(&pmkid_list.pmkids.pmkid[i + 1].BSSID, &pmkid_list.pmkids.pmkid[i].BSSID, @@ -3409,16 +3409,16 @@ void wl_iw_event(struct net_device *dev, wl_event_msg_t *e, void *data) case WLC_E_DEAUTH_IND: case WLC_E_DISASSOC_IND: cmd = SIOCGIWAP; - bzero(wrqu.addr.sa_data, ETHER_ADDR_LEN); + memset(wrqu.addr.sa_data, 0, ETHER_ADDR_LEN); wrqu.addr.sa_family = ARPHRD_ETHER; - bzero(&extra, ETHER_ADDR_LEN); + memset(&extra, 0, ETHER_ADDR_LEN); break; case WLC_E_LINK: case WLC_E_NDIS_LINK: cmd = SIOCGIWAP; if (!(flags & WLC_EVENT_MSG_LINK)) { - bzero(wrqu.addr.sa_data, ETHER_ADDR_LEN); - bzero(&extra, ETHER_ADDR_LEN); + memset(wrqu.addr.sa_data, 0, ETHER_ADDR_LEN); + memset(&extra, 0, ETHER_ADDR_LEN); WAKE_LOCK_TIMEOUT(iw->pub, WAKE_LOCK_LINK_DOWN_TMOUT, 20 * HZ); } else { @@ -3488,7 +3488,7 @@ void wl_iw_event(struct net_device *dev, wl_event_msg_t *e, void *data) wrqu.data.length = sizeof(struct iw_pmkid_cand); pmkidcand = pmkcandlist->pmkid_cand; while (count) { - bzero(iwpmkidcand, + memset(iwpmkidcand, 0, sizeof(struct iw_pmkid_cand)); if (pmkidcand->preauth) iwpmkidcand->flags |= @@ -3586,7 +3586,7 @@ wl_iw_get_wireless_stats(struct net_device *dev, struct iw_statistics *wstats) phy_noise = dtoh32(phy_noise); WL_TRACE(("wl_iw_get_wireless_stats phy noise=%d\n", phy_noise)); - bzero(&scb_val, sizeof(scb_val_t)); + memset(&scb_val, 0, sizeof(scb_val_t)); res = dev_wlc_ioctl(dev, WLC_GET_RSSI, &scb_val, sizeof(scb_val_t)); if (res) goto done; diff --git a/drivers/staging/brcm80211/include/linux_osl.h b/drivers/staging/brcm80211/include/linux_osl.h index 94f5d12d53d9..ec1c51119637 100644 --- a/drivers/staging/brcm80211/include/linux_osl.h +++ b/drivers/staging/brcm80211/include/linux_osl.h @@ -102,7 +102,6 @@ extern void osl_dma_unmap(struct osl_info *osh, uint pa, uint size, /* bcopy's: Linux kernel doesn't provide these (anymore) */ #define bcopy(src, dst, len) memcpy((dst), (src), (len)) #define bcmp(b1, b2, len) memcmp((b1), (b2), (len)) -#define bzero(b, len) memset((b), '\0', (len)) /* register access macros */ #if defined(OSLREGOPS) @@ -201,10 +200,8 @@ extern void osl_dma_unmap(struct osl_info *osh, uint pa, uint size, #define AND_REG(osh, r, v) W_REG(osh, (r), R_REG(osh, r) & (v)) #define OR_REG(osh, r, v) W_REG(osh, (r), R_REG(osh, r) | (v)) -/* bcopy, bcmp, and bzero functions */ #define bcopy(src, dst, len) memcpy((dst), (src), (len)) #define bcmp(b1, b2, len) memcmp((b1), (b2), (len)) -#define bzero(b, len) memset((b), '\0', (len)) /* uncached/cached virtual address */ #ifdef __mips__ diff --git a/drivers/staging/brcm80211/phy/wlc_phy_cmn.c b/drivers/staging/brcm80211/phy/wlc_phy_cmn.c index 87d33dd8e01b..6ea4df64d18e 100644 --- a/drivers/staging/brcm80211/phy/wlc_phy_cmn.c +++ b/drivers/staging/brcm80211/phy/wlc_phy_cmn.c @@ -1538,7 +1538,7 @@ wlc_phy_chanspec_band_validch(wlc_phy_t *ppi, uint band, chanvec_t *channels) ASSERT((band == WLC_BAND_2G) || (band == WLC_BAND_5G)); - bzero(channels, sizeof(chanvec_t)); + memset(channels, 0, sizeof(chanvec_t)); for (i = 0; i < ARRAY_SIZE(chan_info_all); i++) { channel = chan_info_all[i].chan; @@ -1900,7 +1900,7 @@ void wlc_phy_txpower_recalc_target(phy_info_t *pi) tx_pwr_min = min(tx_pwr_min, tx_pwr_target[rate]); } - bzero(pi->tx_power_offset, sizeof(pi->tx_power_offset)); + memset(pi->tx_power_offset, 0, sizeof(pi->tx_power_offset)); pi->tx_power_max = tx_pwr_max; pi->tx_power_min = tx_pwr_min; pi->tx_power_max_rate_ind = tx_pwr_max_rate_ind; @@ -2511,7 +2511,7 @@ wlc_phy_noise_calc_phy(phy_info_t *pi, u32 *cmplx_pwr, s8 *pwr_ant) s8 cmplx_pwr_dbm[PHY_CORE_MAX]; u8 i; - bzero((u8 *) cmplx_pwr_dbm, sizeof(cmplx_pwr_dbm)); + memset((u8 *) cmplx_pwr_dbm, 0, sizeof(cmplx_pwr_dbm)); ASSERT(pi->pubpi.phy_corenum <= PHY_CORE_MAX); wlc_phy_compute_dB(cmplx_pwr, cmplx_pwr_dbm, pi->pubpi.phy_corenum); @@ -2625,9 +2625,9 @@ wlc_phy_noise_sample_request(wlc_phy_t *pih, u8 reason, u8 ch) u8 wait_crs = 0; u8 i; - bzero((u8 *) est, sizeof(est)); - bzero((u8 *) cmplx_pwr, sizeof(cmplx_pwr)); - bzero((u8 *) noise_dbm_ant, sizeof(noise_dbm_ant)); + memset((u8 *) est, 0, sizeof(est)); + memset((u8 *) cmplx_pwr, 0, sizeof(cmplx_pwr)); + memset((u8 *) noise_dbm_ant, 0, sizeof(noise_dbm_ant)); log_num_samps = PHY_NOISE_SAMPLE_LOG_NUM_NPHY; num_samps = 1 << log_num_samps; @@ -2708,8 +2708,8 @@ static s8 wlc_phy_noise_read_shmem(phy_info_t *pi) u8 idx, core; ASSERT(pi->pubpi.phy_corenum <= PHY_CORE_MAX); - bzero((u8 *) cmplx_pwr, sizeof(cmplx_pwr)); - bzero((u8 *) noise_dbm_ant, sizeof(noise_dbm_ant)); + memset((u8 *) cmplx_pwr, 0, sizeof(cmplx_pwr)); + memset((u8 *) noise_dbm_ant, 0, sizeof(noise_dbm_ant)); for (idx = 0, core = 0; core < pi->pubpi.phy_corenum; idx += 2, core++) { lo = wlapi_bmac_read_shm(pi->sh->physhim, M_PWRIND_MAP(idx)); diff --git a/drivers/staging/brcm80211/phy/wlc_phy_lcn.c b/drivers/staging/brcm80211/phy/wlc_phy_lcn.c index 1fde9d5701b0..9492ca5421f8 100644 --- a/drivers/staging/brcm80211/phy/wlc_phy_lcn.c +++ b/drivers/staging/brcm80211/phy/wlc_phy_lcn.c @@ -1331,7 +1331,7 @@ static void wlc_lcnphy_clear_tx_power_offsets(phy_info_t *pi) u32 data_buf[64]; phytbl_info_t tab; - bzero(data_buf, sizeof(data_buf)); + memset(data_buf, 0, sizeof(data_buf)); tab.tbl_id = LCNPHY_TBL_ID_TXPWRCTL; tab.tbl_width = 32; @@ -1955,7 +1955,7 @@ wlc_lcnphy_tx_iqlo_cal(phy_info_t *pi, band_idx = (CHSPEC_IS5G(pi->radio_chanspec) ? 1 : 0); cal_gains = *target_gains; - bzero(ncorr_override, sizeof(ncorr_override)); + memset(ncorr_override, 0, sizeof(ncorr_override)); for (j = 0; j < iqcal_gainparams_numgains_lcnphy[band_idx]; j++) { if (hash == tbl_iqcal_gainparams_lcnphy[band_idx][j][0]) { cal_gains.gm_gain = @@ -2533,7 +2533,7 @@ static void wlc_lcnphy_clear_papd_comptable(phy_info_t *pi) tab.tbl_width = 32; tab.tbl_offset = 0; - bzero(temp_offset, sizeof(temp_offset)); + memset(temp_offset, 0, sizeof(temp_offset)); for (j = 1; j < 128; j += 2) temp_offset[j] = 0x80000; diff --git a/drivers/staging/brcm80211/sys/wl_mac80211.c b/drivers/staging/brcm80211/sys/wl_mac80211.c index 7d18d4f269e9..959ea528245a 100644 --- a/drivers/staging/brcm80211/sys/wl_mac80211.c +++ b/drivers/staging/brcm80211/sys/wl_mac80211.c @@ -530,7 +530,7 @@ wl_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif, /* Init the scb */ scb = (struct scb *)sta->drv_priv; - bzero(scb, sizeof(struct scb)); + memset(scb, 0, sizeof(struct scb)); for (i = 0; i < NUMPRIO; i++) scb->seqctl[i] = 0xFFFF; scb->seqctl_nonqos = 0xFFFF; @@ -1073,7 +1073,7 @@ wl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) pci_set_drvdata(pdev, hw); - bzero(hw->priv, sizeof(*wl)); + memset(hw->priv, 0, sizeof(*wl)); wl = wl_attach(pdev->vendor, pdev->device, pci_resource_start(pdev, 0), PCI_BUS, pdev, pdev->irq); @@ -1555,7 +1555,7 @@ wl_timer_t *wl_init_timer(wl_info_t *wl, void (*fn) (void *arg), void *arg, return 0; } - bzero(t, sizeof(wl_timer_t)); + memset(t, 0, sizeof(wl_timer_t)); init_timer(&t->timer); t->timer.data = (unsigned long) t; @@ -1747,7 +1747,7 @@ static int wl_request_fw(wl_info_t *wl, struct pci_dev *pdev) char fw_name[100]; int i; - bzero((void *)&wl->fw, sizeof(struct wl_firmware)); + memset((void *)&wl->fw, 0, sizeof(struct wl_firmware)); for (i = 0; i < WL_MAX_FW; i++) { if (wl_firmwares[i] == NULL) break; diff --git a/drivers/staging/brcm80211/sys/wlc_ampdu.c b/drivers/staging/brcm80211/sys/wlc_ampdu.c index c5ab4a459471..86563b5860a2 100644 --- a/drivers/staging/brcm80211/sys/wlc_ampdu.c +++ b/drivers/staging/brcm80211/sys/wlc_ampdu.c @@ -976,7 +976,7 @@ wlc_ampdu_dotxstatus_complete(ampdu_info_t *ampdu, struct scb *scb, #ifdef BCMDBG u8 hole[AMPDU_MAX_MPDU]; - bzero(hole, sizeof(hole)); + memset(hole, 0, sizeof(hole)); #endif ASSERT(tx_info->flags & IEEE80211_TX_CTL_AMPDU); @@ -993,7 +993,7 @@ wlc_ampdu_dotxstatus_complete(ampdu_info_t *ampdu, struct scb *scb, ASSERT(ini->scb == scb); - bzero(bitmap, sizeof(bitmap)); + memset(bitmap, 0, sizeof(bitmap)); queue = txs->frameid & TXFID_QUEUE_MASK; ASSERT(queue < AC_COUNT); @@ -1318,7 +1318,7 @@ void wlc_ampdu_macaddr_upd(wlc_info_t *wlc) char template[T_RAM_ACCESS_SZ * 2]; /* driver needs to write the ta in the template; ta is at offset 16 */ - bzero(template, sizeof(template)); + memset(template, 0, sizeof(template)); bcopy((char *)wlc->pub->cur_etheraddr.octet, template, ETHER_ADDR_LEN); wlc_write_template_ram(wlc, (T_BA_TPL_BASE + 16), (T_RAM_ACCESS_SZ * 2), template); diff --git a/drivers/staging/brcm80211/sys/wlc_bmac.c b/drivers/staging/brcm80211/sys/wlc_bmac.c index 2245a8b25a24..6711c69edf38 100644 --- a/drivers/staging/brcm80211/sys/wlc_bmac.c +++ b/drivers/staging/brcm80211/sys/wlc_bmac.c @@ -1457,7 +1457,7 @@ wlc_mhfdef(wlc_info_t *wlc, u16 *mhfs, u16 mhf2_init) { wlc_hw_info_t *wlc_hw = wlc->hw; - bzero(mhfs, sizeof(u16) * MHFMAX); + memset(mhfs, 0, MHFMAX * sizeof(u16)); mhfs[MHF2] |= mhf2_init; diff --git a/drivers/staging/brcm80211/sys/wlc_channel.c b/drivers/staging/brcm80211/sys/wlc_channel.c index 2fcdbc72c837..bb82a8c008a4 100644 --- a/drivers/staging/brcm80211/sys/wlc_channel.c +++ b/drivers/staging/brcm80211/sys/wlc_channel.c @@ -382,7 +382,7 @@ void wlc_locale_get_channels(const locale_info_t *locale, chanvec_t *channels) { u8 i; - bzero(channels, sizeof(chanvec_t)); + memset(channels, 0, sizeof(chanvec_t)); for (i = 0; i < ARRAY_SIZE(g_table_locale_base); i++) { if (locale->valid_channels & (1 << i)) { @@ -634,7 +634,7 @@ wlc_cm_info_t *wlc_channel_mgr_attach(wlc_info_t *wlc) } /* internal country information which must match regulatory constraints in firmware */ - bzero(country_abbrev, WLC_CNTRY_BUF_SZ); + memset(country_abbrev, 0, WLC_CNTRY_BUF_SZ); strncpy(country_abbrev, "X2", sizeof(country_abbrev) - 1); country = wlc_country_lookup(wlc, country_abbrev); @@ -763,7 +763,7 @@ wlc_set_country_common(wlc_cm_info_t *wlc_cm, /* save current country state */ wlc_cm->country = country; - bzero(&prev_country_abbrev, WLC_CNTRY_BUF_SZ); + memset(&prev_country_abbrev, 0, WLC_CNTRY_BUF_SZ); strncpy(prev_country_abbrev, wlc_cm->country_abbrev, WLC_CNTRY_BUF_SZ - 1); @@ -1008,7 +1008,7 @@ void wlc_quiet_channels_reset(wlc_cm_info_t *wlc_cm) wlcband_t *band; const chanvec_t *chanvec; - bzero(&wlc_cm->quiet_channels, sizeof(chanvec_t)); + memset(&wlc_cm->quiet_channels, 0, sizeof(chanvec_t)); band = wlc->band; for (i = 0; i < NBANDS(wlc); @@ -1319,7 +1319,7 @@ wlc_channel_reg_limits(wlc_cm_info_t *wlc_cm, chanspec_t chanspec, int maxpwr_idx; uint j; - bzero(txpwr, sizeof(txpwr_limits_t)); + memset(txpwr, 0, sizeof(txpwr_limits_t)); if (!wlc_valid_chanspec_db(wlc_cm, chanspec)) { country = wlc_country_lookup(wlc, wlc->autocountry_default); diff --git a/drivers/staging/brcm80211/sys/wlc_mac80211.c b/drivers/staging/brcm80211/sys/wlc_mac80211.c index 29b6139ae4f0..7017db68c983 100644 --- a/drivers/staging/brcm80211/sys/wlc_mac80211.c +++ b/drivers/staging/brcm80211/sys/wlc_mac80211.c @@ -372,7 +372,8 @@ void wlc_reset(wlc_info_t *wlc) wlc_statsupd(wlc); /* reset our snapshot of macstat counters */ - bzero((char *)wlc->core->macstat_snapshot, sizeof(macstat_t)); + memset((char *)wlc->core->macstat_snapshot, 0, + sizeof(macstat_t)); } wlc_bmac_reset(wlc->hw); @@ -866,7 +867,7 @@ static int wlc_get_current_txpwr(wlc_info_t *wlc, void *pwr, uint len) else if (len < sizeof(tx_power_t)) return BCME_BUFTOOSHORT; - bzero(&power, sizeof(tx_power_t)); + memset(&power, 0, sizeof(tx_power_t)); power.chanspec = WLC_BAND_PI_RADIO_CHANSPEC; if (wlc->pub->associated) @@ -988,7 +989,7 @@ static int wlc_get_current_txpwr(wlc_info_t *wlc, void *pwr, uint len) } else { int band_idx = CHSPEC_IS2G(power.chanspec) ? 0 : 1; - bzero(old_power, sizeof(tx_power_legacy_t)); + memset(old_power, 0, sizeof(tx_power_legacy_t)); old_power->txpwr_local_max = power.local_max; old_power->txpwr_local_constraint = power.local_constraint; @@ -1359,7 +1360,7 @@ void wlc_wme_setparams(wlc_info_t *wlc, u16 aci, void *arg, bool suspend) wlc->wme_admctl = 0; do { - bzero((char *)&acp_shm, sizeof(shm_acparams_t)); + memset((char *)&acp_shm, 0, sizeof(shm_acparams_t)); /* find out which ac this set of params applies to */ ASSERT(aci < AC_COUNT); /* set the admission control policy for this AC */ @@ -1440,7 +1441,7 @@ void wlc_edcf_setparams(wlc_bsscfg_t *cfg, bool suspend) wlc->wme_admctl = 0; for (i = 0; i < AC_COUNT; i++, edcf_acp++) { - bzero((char *)&acp_shm, sizeof(shm_acparams_t)); + memset((char *)&acp_shm, 0, sizeof(shm_acparams_t)); /* find out which ac this set of params applies to */ aci = (edcf_acp->ACI & EDCF_ACI_MASK) >> EDCF_ACI_SHIFT; ASSERT(aci < AC_COUNT); @@ -2633,7 +2634,7 @@ int wlc_up(wlc_info_t *wlc) static void wlc_tx_prec_map_init(wlc_info_t *wlc) { wlc->tx_prec_map = WLC_PREC_BMP_ALL; - bzero(wlc->fifo2prec_map, sizeof(u16) * NFIFO); + memset(wlc->fifo2prec_map, 0, NFIFO * sizeof(u16)); /* For non-WME, both fifos have overlapping MAXPRIO. So just disable all precedences * if either is full. @@ -2790,10 +2791,10 @@ int wlc_set_gmode(wlc_info_t *wlc, u8 gmode, bool config) wlc_protection_upd(wlc, WLC_PROT_G_USER, gmode); /* Clear supported rates filter */ - bzero(&wlc->sup_rates_override, sizeof(wlc_rateset_t)); + memset(&wlc->sup_rates_override, 0, sizeof(wlc_rateset_t)); /* Clear rateset override */ - bzero(&rs, sizeof(wlc_rateset_t)); + memset(&rs, 0, sizeof(wlc_rateset_t)); switch (gmode) { case GMODE_LEGACY_B: @@ -3589,7 +3590,7 @@ _wlc_ioctl(wlc_info_t *wlc, int cmd, void *arg, int len, struct wlc_if *wlcif) break; } - bzero((char *)&key, sizeof(key)); + memset((char *)&key, 0, sizeof(key)); if (src_key) { key.index = src_key->id; key.len = src_key->len; @@ -3686,7 +3687,7 @@ _wlc_ioctl(wlc_info_t *wlc, int cmd, void *arg, int len, struct wlc_if *wlcif) wlc_rateset_t rs; wl_rateset_t *ret_rs = (wl_rateset_t *) arg; - bzero(&rs, sizeof(wlc_rateset_t)); + memset(&rs, 0, sizeof(wlc_rateset_t)); wlc_default_rateset(wlc, (wlc_rateset_t *) &rs); if (len < (int)(rs.count + sizeof(rs.count))) { @@ -3714,7 +3715,7 @@ _wlc_ioctl(wlc_info_t *wlc, int cmd, void *arg, int len, struct wlc_if *wlcif) break; } - bzero(&rs, sizeof(wlc_rateset_t)); + memset(&rs, 0, sizeof(wlc_rateset_t)); /* Copy only legacy rateset section */ rs.count = in_rs->count; @@ -4048,7 +4049,7 @@ _wlc_ioctl(wlc_info_t *wlc, int cmd, void *arg, int len, struct wlc_if *wlcif) /* check for an empty rateset to clear the override */ if (rs.count == 0) { - bzero(&wlc->sup_rates_override, + memset(&wlc->sup_rates_override, 0, sizeof(wlc_rateset_t)); break; } @@ -4349,7 +4350,7 @@ int wlc_module_unregister(wlc_pub_t *pub, const char *name, void *hdl) for (i = 0; i < WLC_MAXMODULES; i++) { if (!strcmp(wlc->modulecb[i].name, name) && (wlc->modulecb[i].hdl == hdl)) { - bzero(&wlc->modulecb[i], sizeof(modulecb_t)); + memset(&wlc->modulecb[i], 0, sizeof(modulecb_t)); return 0; } } @@ -5355,7 +5356,7 @@ wlc_compute_ofdm_plcp(ratespec_t rspec, u32 length, u8 *plcp) rate_signal = rate_info[rate] & RATE_MASK; ASSERT(rate_signal != 0); - bzero(plcp, D11_PHY_HDR_LEN); + memset(plcp, 0, D11_PHY_HDR_LEN); D11A_PHY_HDR_SRATE((ofdm_phy_hdr_t *) plcp, rate_signal); tmp = (length & 0xfff) << 5; @@ -5718,7 +5719,7 @@ wlc_d11hdrs_mac80211(wlc_info_t *wlc, struct ieee80211_hw *hw, /* add Broadcom tx descriptor header */ txh = (d11txh_t *) skb_push(p, D11_TXH_LEN); - bzero((char *)txh, D11_TXH_LEN); + memset((char *)txh, 0, D11_TXH_LEN); /* setup frameid */ if (tx_info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) { @@ -6134,9 +6135,10 @@ wlc_d11hdrs_mac80211(wlc_info_t *wlc, struct ieee80211_hw *hw, D11A_PHY_HDR_GRATE((ofdm_phy_hdr_t *) rts_plcp) : rts_plcp[0]) << 8; } else { - bzero((char *)txh->RTSPhyHeader, D11_PHY_HDR_LEN); - bzero((char *)&txh->rts_frame, sizeof(struct dot11_rts_frame)); - bzero((char *)txh->RTSPLCPFallback, + memset((char *)txh->RTSPhyHeader, 0, D11_PHY_HDR_LEN); + memset((char *)&txh->rts_frame, 0, + sizeof(struct dot11_rts_frame)); + memset((char *)txh->RTSPLCPFallback, 0, sizeof(txh->RTSPLCPFallback)); txh->RTSDurFallback = 0; } @@ -7274,7 +7276,7 @@ void wlc_rate_lookup_init(wlc_info_t *wlc, wlc_rateset_t *rateset) uint i; /* incoming rates are in 500kbps units as in 802.11 Supported Rates */ - bzero(br, WLC_MAXRATE + 1); + memset(br, 0, WLC_MAXRATE + 1); /* For each basic rate in the rates list, make an entry in the * best basic lookup. @@ -7608,7 +7610,7 @@ wlc_bcn_prb_template(wlc_info_t *wlc, uint type, ratespec_t bcn_rspec, *len = hdr_len + body_len; /* return actual size */ /* format PHY and MAC headers */ - bzero((char *)buf, hdr_len); + memset((char *)buf, 0, hdr_len); plcp = (cck_phy_hdr_t *) buf; @@ -7729,7 +7731,7 @@ void wlc_shm_ssid_upd(wlc_info_t *wlc, wlc_bsscfg_t *cfg) u8 ssidbuf[DOT11_MAX_SSID_LEN]; /* padding the ssid with zero and copy it into shm */ - bzero(ssidbuf, DOT11_MAX_SSID_LEN); + memset(ssidbuf, 0, DOT11_MAX_SSID_LEN); bcopy(ssidptr, ssidbuf, cfg->SSID_len); wlc_copyto_shm(wlc, base, ssidbuf, DOT11_MAX_SSID_LEN); @@ -7845,7 +7847,7 @@ void wlc_reprate_init(wlc_info_t *wlc) void wlc_bsscfg_reprate_init(wlc_bsscfg_t *bsscfg) { bsscfg->txrspecidx = 0; - bzero((char *)bsscfg->txrspec, sizeof(bsscfg->txrspec)); + memset((char *)bsscfg->txrspec, 0, sizeof(bsscfg->txrspec)); } /* Retrieve a consolidated set of revision information, @@ -7900,7 +7902,7 @@ static void wlc_bss_default_init(wlc_info_t *wlc) wlc_bss_info_t *bi = wlc->default_bss; /* init default and target BSS with some sane initial values */ - bzero((char *)(bi), sizeof(wlc_bss_info_t)); + memset((char *)(bi), 0, sizeof(wlc_bss_info_t)); bi->beacon_period = ISSIM_ENAB(wlc->pub->sih) ? BEACON_INTERVAL_DEF_QT : BEACON_INTERVAL_DEFAULT; bi->dtim_period = ISSIM_ENAB(wlc->pub->sih) ? DTIM_INTERVAL_DEF_QT : diff --git a/drivers/staging/brcm80211/sys/wlc_rate.c b/drivers/staging/brcm80211/sys/wlc_rate.c index e1199b236f5f..ab7d0bed3c0a 100644 --- a/drivers/staging/brcm80211/sys/wlc_rate.c +++ b/drivers/staging/brcm80211/sys/wlc_rate.c @@ -299,7 +299,7 @@ wlc_rate_hwrs_filter_sort_validate(wlc_rateset_t *rs, uint count; uint i; - bzero(rateset, sizeof(rateset)); + memset(rateset, 0, sizeof(rateset)); count = rs->count; for (i = 0; i < count; i++) { diff --git a/drivers/staging/brcm80211/util/bcmotp.c b/drivers/staging/brcm80211/util/bcmotp.c index 499cf0366200..ac25989c8dab 100644 --- a/drivers/staging/brcm80211/util/bcmotp.c +++ b/drivers/staging/brcm80211/util/bcmotp.c @@ -901,7 +901,7 @@ void *otp_init(si_t *sih) void *ret = NULL; oi = &otpinfo; - bzero(oi, sizeof(otpinfo_t)); + memset(oi, 0, sizeof(otpinfo_t)); oi->ccrev = sih->ccrev; diff --git a/drivers/staging/brcm80211/util/bcmsrom.c b/drivers/staging/brcm80211/util/bcmsrom.c index af4658e4d67e..77098465d541 100644 --- a/drivers/staging/brcm80211/util/bcmsrom.c +++ b/drivers/staging/brcm80211/util/bcmsrom.c @@ -405,7 +405,7 @@ int srom_parsecis(struct osl_info *osh, u8 *pcis[], uint ciscnt, char **vars, return -2; varbuf_init(&b, base, MAXSZ_NVRAM_VARS); - bzero(base, MAXSZ_NVRAM_VARS); + memset(base, 0, MAXSZ_NVRAM_VARS); eabuf[0] = '\0'; for (cisnum = 0; cisnum < ciscnt; cisnum++) { cis = *pcis++; diff --git a/drivers/staging/brcm80211/util/bcmutils.c b/drivers/staging/brcm80211/util/bcmutils.c index 49c1f74dda83..64d1440a5041 100644 --- a/drivers/staging/brcm80211/util/bcmutils.c +++ b/drivers/staging/brcm80211/util/bcmutils.c @@ -266,7 +266,7 @@ void pktq_init(struct pktq *pq, int num_prec, int max_len) ASSERT(num_prec > 0 && num_prec <= PKTQ_MAX_PREC); /* pq is variable size; only zero out what's requested */ - bzero(pq, + memset(pq, 0, offsetof(struct pktq, q) + (sizeof(struct pktq_prec) * num_prec)); pq->num_prec = (u16) num_prec; diff --git a/drivers/staging/brcm80211/util/hnddma.c b/drivers/staging/brcm80211/util/hnddma.c index 3c85aa584d8f..996998d805e0 100644 --- a/drivers/staging/brcm80211/util/hnddma.c +++ b/drivers/staging/brcm80211/util/hnddma.c @@ -1118,7 +1118,8 @@ static bool BCMFASTPATH _dma_rxfill(dma_info_t *di) *(u32 *) (p->data) = 0; if (DMASGLIST_ENAB) - bzero(&di->rxp_dmah[rxout], sizeof(hnddma_seg_map_t)); + memset(&di->rxp_dmah[rxout], 0, + sizeof(hnddma_seg_map_t)); pa = DMA_MAP(di->osh, p->data, di->rxbufsize, DMA_RX, p, &di->rxp_dmah[rxout]); @@ -1688,7 +1689,8 @@ static int dma32_txfast(dma_info_t *di, struct sk_buff *p0, bool commit) continue; if (DMASGLIST_ENAB) - bzero(&di->txp_dmah[txout], sizeof(hnddma_seg_map_t)); + memset(&di->txp_dmah[txout], 0, + sizeof(hnddma_seg_map_t)); /* get physical address of buffer start */ pa = DMA_MAP(di->osh, data, len, DMA_TX, p, @@ -1960,7 +1962,7 @@ static void dma32_txrotate(dma_info_t *di) if (DMASGLIST_ENAB) { bcopy(&di->txp_dmah[old], &di->txp_dmah[new], sizeof(hnddma_seg_map_t)); - bzero(&di->txp_dmah[old], sizeof(hnddma_seg_map_t)); + memset(&di->txp_dmah[old], 0, sizeof(hnddma_seg_map_t)); } di->txp[old] = NULL; @@ -2339,7 +2341,8 @@ static int BCMFASTPATH dma64_txfast(dma_info_t *di, struct sk_buff *p0, /* get physical address of buffer start */ if (DMASGLIST_ENAB) - bzero(&di->txp_dmah[txout], sizeof(hnddma_seg_map_t)); + memset(&di->txp_dmah[txout], 0, + sizeof(hnddma_seg_map_t)); pa = DMA_MAP(di->osh, data, len, DMA_TX, p, &di->txp_dmah[txout]); @@ -2637,7 +2640,7 @@ static void dma64_txrotate(dma_info_t *di) if (DMASGLIST_ENAB) { bcopy(&di->txp_dmah[old], &di->txp_dmah[new], sizeof(hnddma_seg_map_t)); - bzero(&di->txp_dmah[old], sizeof(hnddma_seg_map_t)); + memset(&di->txp_dmah[old], 0, sizeof(hnddma_seg_map_t)); } di->txp[old] = NULL; diff --git a/drivers/staging/brcm80211/util/linux_osl.c b/drivers/staging/brcm80211/util/linux_osl.c index 260995e0e90e..6a06d61568b9 100644 --- a/drivers/staging/brcm80211/util/linux_osl.c +++ b/drivers/staging/brcm80211/util/linux_osl.c @@ -43,7 +43,7 @@ struct osl_info *osl_attach(void *pdev, uint bustype) osh = kmalloc(sizeof(struct osl_info), GFP_ATOMIC); ASSERT(osh); - bzero(osh, sizeof(struct osl_info)); + memset(osh, 0, sizeof(struct osl_info)); osh->magic = OS_HANDLE_MAGIC; osh->pdev = pdev; diff --git a/drivers/staging/brcm80211/util/siutils.c b/drivers/staging/brcm80211/util/siutils.c index 050c2d248978..1a9ff1a895c2 100644 --- a/drivers/staging/brcm80211/util/siutils.c +++ b/drivers/staging/brcm80211/util/siutils.c @@ -380,7 +380,7 @@ static si_info_t *si_doattach(si_info_t *sii, uint devid, struct osl_info *osh, ASSERT(GOODREGS(regs)); - bzero((unsigned char *) sii, sizeof(si_info_t)); + memset((unsigned char *) sii, 0, sizeof(si_info_t)); savewin = 0; @@ -510,7 +510,7 @@ static si_info_t *si_doattach(si_info_t *sii, uint devid, struct osl_info *osh, ASSERT(GOODREGS(regs)); - bzero((unsigned char *) sii, sizeof(si_info_t)); + memset((unsigned char *) sii, 0, sizeof(si_info_t)); savewin = 0; -- cgit v1.2.3 From a043b26646444eba28e5010965dbf61bc3ba5277 Mon Sep 17 00:00:00 2001 From: Brett Rudley Date: Tue, 30 Nov 2010 20:32:51 -0800 Subject: staging: brcm80211: bcmp => memcmp s/bcmp/memcmp/ Signed-off-by: Brett Rudley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmfmac/dhd_common.c | 2 +- drivers/staging/brcm80211/brcmfmac/wl_iw.c | 8 ++++---- drivers/staging/brcm80211/include/linux_osl.h | 2 -- drivers/staging/brcm80211/phy/wlc_phy_cmn.c | 2 +- drivers/staging/brcm80211/sys/wlc_mac80211.h | 2 +- drivers/staging/brcm80211/util/bcmsrom.c | 2 +- drivers/staging/brcm80211/util/bcmutils.c | 2 +- drivers/staging/brcm80211/util/nvram/nvram_ro.c | 2 +- 8 files changed, 10 insertions(+), 12 deletions(-) diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_common.c b/drivers/staging/brcm80211/brcmfmac/dhd_common.c index e212abb8a357..ce5f9134055c 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_common.c +++ b/drivers/staging/brcm80211/brcmfmac/dhd_common.c @@ -834,7 +834,7 @@ wl_host_event(struct dhd_info *dhd, int *ifidx, void *pktdata, u16 flags; int evlen; - if (bcmp(BRCM_OUI, &pvt_data->bcm_hdr.oui[0], DOT11_OUI_LEN)) { + if (memcmp(BRCM_OUI, &pvt_data->bcm_hdr.oui[0], DOT11_OUI_LEN)) { DHD_ERROR(("%s: mismatched OUI, bailing\n", __func__)); return BCME_ERROR; } diff --git a/drivers/staging/brcm80211/brcmfmac/wl_iw.c b/drivers/staging/brcm80211/brcmfmac/wl_iw.c index 8bf24c7ce684..e524cd102c41 100644 --- a/drivers/staging/brcm80211/brcmfmac/wl_iw.c +++ b/drivers/staging/brcm80211/brcmfmac/wl_iw.c @@ -1407,7 +1407,7 @@ static bool ie_is_wpa_ie(u8 **wpaie, u8 **tlvs, int *tlvs_len) u8 *ie = *wpaie; if ((ie[1] >= 6) && - !bcmp((const void *)&ie[2], (const void *)(WPA_OUI "\x01"), 4)) { + !memcmp((const void *)&ie[2], (const void *)(WPA_OUI "\x01"), 4)) { return true; } @@ -1423,7 +1423,7 @@ static bool ie_is_wps_ie(u8 **wpsie, u8 **tlvs, int *tlvs_len) u8 *ie = *wpsie; if ((ie[1] >= 4) && - !bcmp((const void *)&ie[2], (const void *)(WPA_OUI "\x04"), 4)) { + !memcmp((const void *)&ie[2], (const void *)(WPA_OUI "\x04"), 4)) { return true; } @@ -2669,7 +2669,7 @@ wl_iw_set_pmksa(struct net_device *dev, } for (i = 0; i < pmkid_list.pmkids.npmkid; i++) - if (!bcmp + if (!memcmp (&iwpmksa->bssid.sa_data[0], &pmkid_list.pmkids.pmkid[i].BSSID, ETHER_ADDR_LEN)) break; @@ -2692,7 +2692,7 @@ wl_iw_set_pmksa(struct net_device *dev, else if (iwpmksa->cmd == IW_PMKSA_ADD) { for (i = 0; i < pmkid_list.pmkids.npmkid; i++) - if (!bcmp + if (!memcmp (&iwpmksa->bssid.sa_data[0], &pmkid_list.pmkids.pmkid[i].BSSID, ETHER_ADDR_LEN)) break; diff --git a/drivers/staging/brcm80211/include/linux_osl.h b/drivers/staging/brcm80211/include/linux_osl.h index ec1c51119637..c2edea4649cb 100644 --- a/drivers/staging/brcm80211/include/linux_osl.h +++ b/drivers/staging/brcm80211/include/linux_osl.h @@ -101,7 +101,6 @@ extern void osl_dma_unmap(struct osl_info *osh, uint pa, uint size, #endif /* bcopy's: Linux kernel doesn't provide these (anymore) */ #define bcopy(src, dst, len) memcpy((dst), (src), (len)) -#define bcmp(b1, b2, len) memcmp((b1), (b2), (len)) /* register access macros */ #if defined(OSLREGOPS) @@ -201,7 +200,6 @@ extern void osl_dma_unmap(struct osl_info *osh, uint pa, uint size, #define OR_REG(osh, r, v) W_REG(osh, (r), R_REG(osh, r) | (v)) #define bcopy(src, dst, len) memcpy((dst), (src), (len)) -#define bcmp(b1, b2, len) memcmp((b1), (b2), (len)) /* uncached/cached virtual address */ #ifdef __mips__ diff --git a/drivers/staging/brcm80211/phy/wlc_phy_cmn.c b/drivers/staging/brcm80211/phy/wlc_phy_cmn.c index 6ea4df64d18e..574d4f3a2084 100644 --- a/drivers/staging/brcm80211/phy/wlc_phy_cmn.c +++ b/drivers/staging/brcm80211/phy/wlc_phy_cmn.c @@ -167,7 +167,7 @@ char *phy_getvar(phy_info_t *pi, const char *name) return NULL; for (s = vars; s && *s;) { - if ((bcmp(s, name, len) == 0) && (s[len] == '=')) + if ((memcmp(s, name, len) == 0) && (s[len] == '=')) return &s[len + 1]; while (*s++) diff --git a/drivers/staging/brcm80211/sys/wlc_mac80211.h b/drivers/staging/brcm80211/sys/wlc_mac80211.h index 72a9236d8d86..2a6cf2ab19dd 100644 --- a/drivers/staging/brcm80211/sys/wlc_mac80211.h +++ b/drivers/staging/brcm80211/sys/wlc_mac80211.h @@ -813,7 +813,7 @@ struct antsel_info { dma_getnexttxp((wlc)->hw->di[(_queue)], HNDDMA_RANGE_TRANSMITTED) #define WLC_IS_MATCH_SSID(wlc, ssid1, ssid2, len1, len2) \ - ((len1 == len2) && !bcmp(ssid1, ssid2, len1)) + ((len1 == len2) && !memcmp(ssid1, ssid2, len1)) extern void wlc_high_dpc(wlc_info_t *wlc, u32 macintstatus); extern void wlc_fatal_error(wlc_info_t *wlc); diff --git a/drivers/staging/brcm80211/util/bcmsrom.c b/drivers/staging/brcm80211/util/bcmsrom.c index 77098465d541..3a0beb93c0b6 100644 --- a/drivers/staging/brcm80211/util/bcmsrom.c +++ b/drivers/staging/brcm80211/util/bcmsrom.c @@ -131,7 +131,7 @@ static int varbuf_append(varbuf_t *b, const char *fmt, ...) if (s != NULL) { len = (size_t) (s - b->buf); for (s = b->base; s < b->buf;) { - if ((bcmp(s, b->buf, len) == 0) && s[len] == '=') { + if ((memcmp(s, b->buf, len) == 0) && s[len] == '=') { len = strlen(s) + 1; memmove(s, (s + len), ((b->buf + r + 1) - (s + len))); diff --git a/drivers/staging/brcm80211/util/bcmutils.c b/drivers/staging/brcm80211/util/bcmutils.c index 64d1440a5041..9c4d46764aca 100644 --- a/drivers/staging/brcm80211/util/bcmutils.c +++ b/drivers/staging/brcm80211/util/bcmutils.c @@ -379,7 +379,7 @@ char *getvar(char *vars, const char *name) /* first look in vars[] */ for (s = vars; s && *s;) { - if ((bcmp(s, name, len) == 0) && (s[len] == '=')) + if ((memcmp(s, name, len) == 0) && (s[len] == '=')) return &s[len + 1]; while (*s++) diff --git a/drivers/staging/brcm80211/util/nvram/nvram_ro.c b/drivers/staging/brcm80211/util/nvram/nvram_ro.c index 2521c5b19192..e4d41ee78e2a 100644 --- a/drivers/staging/brcm80211/util/nvram/nvram_ro.c +++ b/drivers/staging/brcm80211/util/nvram/nvram_ro.c @@ -133,7 +133,7 @@ static char *findvar(char *vars, char *lim, const char *name) len = strlen(name); for (s = vars; (s < lim) && *s;) { - if ((bcmp(s, name, len) == 0) && (s[len] == '=')) + if ((memcmp(s, name, len) == 0) && (s[len] == '=')) return &s[len + 1]; while (*s++) -- cgit v1.2.3 From 01d11441fd7ede922e10008986ecdb0a84256bc5 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Wed, 1 Dec 2010 11:16:35 -0800 Subject: staging: brcm80211 needs lots of delay.h Fix lots of errors like: drivers/staging/brcm80211/phy/wlc_phy_n.c:17613: error: implicit declaration of function 'mdelay' drivers/staging/brcm80211/util/nicpci.c:246: error: implicit declaration of function 'udelay' Signed-off-by: Randy Dunlap Cc: Brett Rudley Cc: Henry Ptasinski Cc: Dowan Kim Cc: Roland Vossen Cc: Arend van Spriel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/phy/wlc_phy_cmn.c | 1 + drivers/staging/brcm80211/phy/wlc_phy_lcn.c | 1 + drivers/staging/brcm80211/phy/wlc_phy_n.c | 1 + drivers/staging/brcm80211/util/aiutils.c | 1 + drivers/staging/brcm80211/util/bcmotp.c | 1 + drivers/staging/brcm80211/util/hndpmu.c | 1 + drivers/staging/brcm80211/util/nicpci.c | 1 + drivers/staging/brcm80211/util/siutils.c | 1 + 8 files changed, 8 insertions(+) diff --git a/drivers/staging/brcm80211/phy/wlc_phy_cmn.c b/drivers/staging/brcm80211/phy/wlc_phy_cmn.c index 574d4f3a2084..b223433482f1 100644 --- a/drivers/staging/brcm80211/phy/wlc_phy_cmn.c +++ b/drivers/staging/brcm80211/phy/wlc_phy_cmn.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/staging/brcm80211/phy/wlc_phy_lcn.c b/drivers/staging/brcm80211/phy/wlc_phy_lcn.c index 9492ca5421f8..3ac2b49d9a9d 100644 --- a/drivers/staging/brcm80211/phy/wlc_phy_lcn.c +++ b/drivers/staging/brcm80211/phy/wlc_phy_lcn.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/staging/brcm80211/phy/wlc_phy_n.c b/drivers/staging/brcm80211/phy/wlc_phy_n.c index 3e1ab579c086..c328de56e59a 100644 --- a/drivers/staging/brcm80211/phy/wlc_phy_n.c +++ b/drivers/staging/brcm80211/phy/wlc_phy_n.c @@ -18,6 +18,7 @@ #include #include #include +#include #include #include #include diff --git a/drivers/staging/brcm80211/util/aiutils.c b/drivers/staging/brcm80211/util/aiutils.c index cf900773fa7d..09e09c9770a9 100644 --- a/drivers/staging/brcm80211/util/aiutils.c +++ b/drivers/staging/brcm80211/util/aiutils.c @@ -14,6 +14,7 @@ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include #include #include #include diff --git a/drivers/staging/brcm80211/util/bcmotp.c b/drivers/staging/brcm80211/util/bcmotp.c index ac25989c8dab..3c625c84619e 100644 --- a/drivers/staging/brcm80211/util/bcmotp.c +++ b/drivers/staging/brcm80211/util/bcmotp.c @@ -14,6 +14,7 @@ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include #include #include #include diff --git a/drivers/staging/brcm80211/util/hndpmu.c b/drivers/staging/brcm80211/util/hndpmu.c index 5b6fa72b99e8..45f4fdaed0ac 100644 --- a/drivers/staging/brcm80211/util/hndpmu.c +++ b/drivers/staging/brcm80211/util/hndpmu.c @@ -13,6 +13,7 @@ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include #include #include #include diff --git a/drivers/staging/brcm80211/util/nicpci.c b/drivers/staging/brcm80211/util/nicpci.c index 1adac0783369..56e658c429a8 100644 --- a/drivers/staging/brcm80211/util/nicpci.c +++ b/drivers/staging/brcm80211/util/nicpci.c @@ -14,6 +14,7 @@ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include #include #include #include diff --git a/drivers/staging/brcm80211/util/siutils.c b/drivers/staging/brcm80211/util/siutils.c index 1a9ff1a895c2..33a42f672af8 100644 --- a/drivers/staging/brcm80211/util/siutils.c +++ b/drivers/staging/brcm80211/util/siutils.c @@ -14,6 +14,7 @@ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#include #include #include #include -- cgit v1.2.3 From 2cb22a7a5624603b9db3571fc65489f5389b512c Mon Sep 17 00:00:00 2001 From: Roland Vossen Date: Wed, 1 Dec 2010 21:37:34 +0100 Subject: staging: brcm80211: replaced typedef struct wl_info_t by struct wl_info. Part of the code cleanup effort. CodingStyle doc advises to restrict the usage of typedefs. Also moved several function declarations from .c to .h file because this typedef replace operation induced checkpatch.pl warnings. Signed-off-by: Roland Vossen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmfmac/wl_iw.c | 3 +- drivers/staging/brcm80211/include/bcmdefs.h | 3 + drivers/staging/brcm80211/sys/wl_mac80211.c | 109 ++++++++++++------------ drivers/staging/brcm80211/sys/wl_mac80211.h | 10 +-- drivers/staging/brcm80211/sys/wl_ucode.h | 8 ++ drivers/staging/brcm80211/sys/wl_ucode_loader.c | 9 +- 6 files changed, 69 insertions(+), 73 deletions(-) diff --git a/drivers/staging/brcm80211/brcmfmac/wl_iw.c b/drivers/staging/brcm80211/brcmfmac/wl_iw.c index e524cd102c41..d8600bfc304e 100644 --- a/drivers/staging/brcm80211/brcmfmac/wl_iw.c +++ b/drivers/staging/brcm80211/brcmfmac/wl_iw.c @@ -32,14 +32,13 @@ #include #include -typedef void wlc_info_t; -typedef void wl_info_t; typedef const struct si_pub si_t; #include #include #include #include + #define WL_ERROR(x) printf x #define WL_TRACE(x) #define WL_ASSOC(x) diff --git a/drivers/staging/brcm80211/include/bcmdefs.h b/drivers/staging/brcm80211/include/bcmdefs.h index ba1f5e93179b..4ce4486a19a1 100644 --- a/drivers/staging/brcm80211/include/bcmdefs.h +++ b/drivers/staging/brcm80211/include/bcmdefs.h @@ -144,4 +144,7 @@ typedef struct { /* Max. nvram variable table size */ #define MAXSZ_NVRAM_VARS 4096 +/* handle forward declaration */ +struct wl_info; + #endif /* _bcmdefs_h_ */ diff --git a/drivers/staging/brcm80211/sys/wl_mac80211.c b/drivers/staging/brcm80211/sys/wl_mac80211.c index 959ea528245a..364b34986621 100644 --- a/drivers/staging/brcm80211/sys/wl_mac80211.c +++ b/drivers/staging/brcm80211/sys/wl_mac80211.c @@ -99,13 +99,13 @@ struct ieee80211_tkip_data { }; #define WL_DEV_IF(dev) ((wl_if_t *)netdev_priv(dev)) -#define WL_INFO(dev) ((wl_info_t *)(WL_DEV_IF(dev)->wl)) /* points to wl */ -static int wl_request_fw(wl_info_t *wl, struct pci_dev *pdev); -static void wl_release_fw(wl_info_t *wl); +#define WL_INFO(dev) ((struct wl_info *)(WL_DEV_IF(dev)->wl)) +static int wl_request_fw(struct wl_info *wl, struct pci_dev *pdev); +static void wl_release_fw(struct wl_info *wl); /* local prototypes */ -static int wl_start(struct sk_buff *skb, wl_info_t *wl); -static int wl_start_int(wl_info_t *wl, struct ieee80211_hw *hw, +static int wl_start(struct sk_buff *skb, struct wl_info *wl); +static int wl_start_int(struct wl_info *wl, struct ieee80211_hw *hw, struct sk_buff *skb); static void wl_dpc(unsigned long data); @@ -176,7 +176,7 @@ static int wl_ampdu_action(struct ieee80211_hw *hw, struct ieee80211_vif *vif, static int wl_ops_tx(struct ieee80211_hw *hw, struct sk_buff *skb) { int status; - wl_info_t *wl = hw->priv; + struct wl_info *wl = hw->priv; WL_LOCK(wl); if (!wl->pub->up) { WL_ERROR(("ops->tx called while down\n")); @@ -191,7 +191,7 @@ static int wl_ops_tx(struct ieee80211_hw *hw, struct sk_buff *skb) static int wl_ops_start(struct ieee80211_hw *hw) { - wl_info_t *wl = hw->priv; + struct wl_info *wl = hw->priv; /* struct ieee80211_channel *curchan = hw->conf.channel; */ WL_NONE(("%s : Initial channel: %d\n", __func__, curchan->hw_value)); @@ -204,7 +204,7 @@ static int wl_ops_start(struct ieee80211_hw *hw) static void wl_ops_stop(struct ieee80211_hw *hw) { - wl_info_t *wl = hw->priv; + struct wl_info *wl = hw->priv; ASSERT(wl); WL_LOCK(wl); wl_down(wl); @@ -217,7 +217,7 @@ static void wl_ops_stop(struct ieee80211_hw *hw) static int wl_ops_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) { - wl_info_t *wl; + struct wl_info *wl; int err; /* Just STA for now */ @@ -251,7 +251,7 @@ static int ieee_set_channel(struct ieee80211_hw *hw, struct ieee80211_channel *chan, enum nl80211_channel_type type) { - wl_info_t *wl = HW_TO_WL(hw); + struct wl_info *wl = HW_TO_WL(hw); int err = 0; switch (type) { @@ -276,7 +276,7 @@ ieee_set_channel(struct ieee80211_hw *hw, struct ieee80211_channel *chan, static int wl_ops_config(struct ieee80211_hw *hw, u32 changed) { struct ieee80211_conf *conf = &hw->conf; - wl_info_t *wl = HW_TO_WL(hw); + struct wl_info *wl = HW_TO_WL(hw); int err = 0; int new_int; @@ -343,7 +343,7 @@ wl_ops_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_bss_conf *info, u32 changed) { - wl_info_t *wl = HW_TO_WL(hw); + struct wl_info *wl = HW_TO_WL(hw); int val; @@ -413,7 +413,7 @@ wl_ops_configure_filter(struct ieee80211_hw *hw, unsigned int changed_flags, unsigned int *total_flags, u64 multicast) { - wl_info_t *wl = hw->priv; + struct wl_info *wl = hw->priv; changed_flags &= MAC_FILTERS; *total_flags &= MAC_FILTERS; @@ -500,7 +500,7 @@ static int wl_ops_conf_tx(struct ieee80211_hw *hw, u16 queue, const struct ieee80211_tx_queue_params *params) { - wl_info_t *wl = hw->priv; + struct wl_info *wl = hw->priv; WL_NONE(("%s: Enter (WME config)\n", __func__)); WL_NONE(("queue %d, txop %d, cwmin %d, cwmax %d, aifs %d\n", queue, @@ -526,7 +526,7 @@ wl_sta_add(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct scb *scb; int i; - wl_info_t *wl = hw->priv; + struct wl_info *wl = hw->priv; /* Init the scb */ scb = (struct scb *)sta->drv_priv; @@ -571,7 +571,7 @@ wl_ampdu_action(struct ieee80211_hw *hw, #if defined(BCMDBG) struct scb *scb = (struct scb *)sta->drv_priv; #endif - wl_info_t *wl = hw->priv; + struct wl_info *wl = hw->priv; ASSERT(scb->magic == SCB_MAGIC); switch (action) { @@ -630,7 +630,7 @@ static const struct ieee80211_ops wl_ops = { .ampdu_action = wl_ampdu_action, }; -static int wl_set_hint(wl_info_t *wl, char *abbrev) +static int wl_set_hint(struct wl_info *wl, char *abbrev) { WL_ERROR(("%s: Sending country code %c%c to MAC80211\n", __func__, abbrev[0], abbrev[1])); @@ -648,10 +648,10 @@ static int wl_set_hint(wl_info_t *wl, char *abbrev) * a warning that this function is defined but not used if we declare * it as static. */ -static wl_info_t *wl_attach(u16 vendor, u16 device, unsigned long regs, +static struct wl_info *wl_attach(u16 vendor, u16 device, unsigned long regs, uint bustype, void *btparam, uint irq) { - wl_info_t *wl; + struct wl_info *wl; struct osl_info *osh; int unit, err; @@ -954,7 +954,7 @@ static struct ieee80211_supported_band wl_band_5GHz_nphy = { static int ieee_hw_rate_init(struct ieee80211_hw *hw) { - wl_info_t *wl = HW_TO_WL(hw); + struct wl_info *wl = HW_TO_WL(hw); int has_5g; char phy_list[4]; @@ -1033,7 +1033,7 @@ int __devinit wl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { int rc; - wl_info_t *wl; + struct wl_info *wl; struct ieee80211_hw *hw; u32 val; @@ -1062,7 +1062,7 @@ wl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) if ((val & 0x0000ff00) != 0) pci_write_config_dword(pdev, 0x40, val & 0xffff00ff); - hw = ieee80211_alloc_hw(sizeof(wl_info_t), &wl_ops); + hw = ieee80211_alloc_hw(sizeof(struct wl_info), &wl_ops); if (!hw) { WL_ERROR(("%s: ieee80211_alloc_hw failed\n", __func__)); rc = -ENOMEM; @@ -1092,7 +1092,7 @@ wl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) #ifdef LINUXSTA_PS static int wl_suspend(struct pci_dev *pdev, pm_message_t state) { - wl_info_t *wl; + struct wl_info *wl; struct ieee80211_hw *hw; WL_TRACE(("wl: wl_suspend\n")); @@ -1115,7 +1115,7 @@ static int wl_suspend(struct pci_dev *pdev, pm_message_t state) static int wl_resume(struct pci_dev *pdev) { - wl_info_t *wl; + struct wl_info *wl; struct ieee80211_hw *hw; int err = 0; u32 val; @@ -1154,7 +1154,7 @@ static int wl_resume(struct pci_dev *pdev) static void wl_remove(struct pci_dev *pdev) { - wl_info_t *wl; + struct wl_info *wl; struct ieee80211_hw *hw; hw = pci_get_drvdata(pdev); @@ -1257,7 +1257,7 @@ module_exit(wl_module_exit); * by the wl parameter. * */ -void wl_free(wl_info_t *wl) +void wl_free(struct wl_info *wl) { wl_timer_t *t, *next; struct osl_info *osh; @@ -1316,7 +1316,7 @@ void wl_free(wl_info_t *wl) } /* transmit a packet */ -static int BCMFASTPATH wl_start(struct sk_buff *skb, wl_info_t *wl) +static int BCMFASTPATH wl_start(struct sk_buff *skb, struct wl_info *wl) { if (!wl) return -ENETDOWN; @@ -1325,19 +1325,19 @@ static int BCMFASTPATH wl_start(struct sk_buff *skb, wl_info_t *wl) } static int BCMFASTPATH -wl_start_int(wl_info_t *wl, struct ieee80211_hw *hw, struct sk_buff *skb) +wl_start_int(struct wl_info *wl, struct ieee80211_hw *hw, struct sk_buff *skb) { wlc_sendpkt_mac80211(wl->wlc, skb, hw); return NETDEV_TX_OK; } -void wl_txflowcontrol(wl_info_t *wl, struct wl_if *wlif, bool state, int prio) +void wl_txflowcontrol(struct wl_info *wl, struct wl_if *wlif, bool state, + int prio) { WL_ERROR(("Shouldn't be here %s\n", __func__)); } - -void wl_init(wl_info_t *wl) +void wl_init(struct wl_info *wl) { WL_TRACE(("wl%d: wl_init\n", wl->pub->unit)); @@ -1346,7 +1346,7 @@ void wl_init(wl_info_t *wl) wlc_init(wl->wlc); } -uint wl_reset(wl_info_t *wl) +uint wl_reset(struct wl_info *wl) { WL_TRACE(("wl%d: wl_reset\n", wl->pub->unit)); @@ -1362,7 +1362,7 @@ uint wl_reset(wl_info_t *wl) * These are interrupt on/off entry points. Disable interrupts * during interrupt state transition. */ -void BCMFASTPATH wl_intrson(wl_info_t *wl) +void BCMFASTPATH wl_intrson(struct wl_info *wl) { unsigned long flags; @@ -1371,12 +1371,12 @@ void BCMFASTPATH wl_intrson(wl_info_t *wl) INT_UNLOCK(wl, flags); } -bool wl_alloc_dma_resources(wl_info_t *wl, uint addrwidth) +bool wl_alloc_dma_resources(struct wl_info *wl, uint addrwidth) { return true; } -u32 BCMFASTPATH wl_intrsoff(wl_info_t *wl) +u32 BCMFASTPATH wl_intrsoff(struct wl_info *wl) { unsigned long flags; u32 status; @@ -1387,7 +1387,7 @@ u32 BCMFASTPATH wl_intrsoff(wl_info_t *wl) return status; } -void wl_intrsrestore(wl_info_t *wl, u32 macintmask) +void wl_intrsrestore(struct wl_info *wl, u32 macintmask) { unsigned long flags; @@ -1396,7 +1396,7 @@ void wl_intrsrestore(wl_info_t *wl, u32 macintmask) INT_UNLOCK(wl, flags); } -int wl_up(wl_info_t *wl) +int wl_up(struct wl_info *wl) { int error = 0; @@ -1408,7 +1408,7 @@ int wl_up(wl_info_t *wl) return error; } -void wl_down(wl_info_t *wl) +void wl_down(struct wl_info *wl) { uint callbacks, ret_val = 0; @@ -1429,11 +1429,11 @@ void wl_down(wl_info_t *wl) irqreturn_t BCMFASTPATH wl_isr(int irq, void *dev_id) { - wl_info_t *wl; + struct wl_info *wl; bool ours, wantdpc; unsigned long flags; - wl = (wl_info_t *) dev_id; + wl = (struct wl_info *) dev_id; WL_ISRLOCK(wl, flags); @@ -1457,9 +1457,9 @@ irqreturn_t BCMFASTPATH wl_isr(int irq, void *dev_id) static void BCMFASTPATH wl_dpc(unsigned long data) { - wl_info_t *wl; + struct wl_info *wl; - wl = (wl_info_t *) data; + wl = (struct wl_info *) data; WL_LOCK(wl); @@ -1492,17 +1492,17 @@ static void BCMFASTPATH wl_dpc(unsigned long data) WL_UNLOCK(wl); } -static void wl_link_up(wl_info_t *wl, char *ifname) +static void wl_link_up(struct wl_info *wl, char *ifname) { WL_ERROR(("wl%d: link up (%s)\n", wl->pub->unit, ifname)); } -static void wl_link_down(wl_info_t *wl, char *ifname) +static void wl_link_down(struct wl_info *wl, char *ifname) { WL_ERROR(("wl%d: link down (%s)\n", wl->pub->unit, ifname)); } -void wl_event(wl_info_t *wl, char *ifname, wlc_event_t *e) +void wl_event(struct wl_info *wl, char *ifname, wlc_event_t *e) { switch (e->event.event_type) { @@ -1544,7 +1544,7 @@ static void _wl_timer(wl_timer_t *t) WL_UNLOCK(t->wl); } -wl_timer_t *wl_init_timer(wl_info_t *wl, void (*fn) (void *arg), void *arg, +wl_timer_t *wl_init_timer(struct wl_info *wl, void (*fn) (void *arg), void *arg, const char *name) { wl_timer_t *t; @@ -1578,7 +1578,7 @@ wl_timer_t *wl_init_timer(wl_info_t *wl, void (*fn) (void *arg), void *arg, /* BMAC_NOTE: Add timer adds only the kernel timer since it's going to be more accurate * as well as it's easier to make it periodic */ -void wl_add_timer(wl_info_t *wl, wl_timer_t *t, uint ms, int periodic) +void wl_add_timer(struct wl_info *wl, wl_timer_t *t, uint ms, int periodic) { #ifdef BCMDBG if (t->set) { @@ -1598,7 +1598,7 @@ void wl_add_timer(wl_info_t *wl, wl_timer_t *t, uint ms, int periodic) } /* return true if timer successfully deleted, false if still pending */ -bool wl_del_timer(wl_info_t *wl, wl_timer_t *t) +bool wl_del_timer(struct wl_info *wl, wl_timer_t *t) { if (t->set) { t->set = false; @@ -1611,7 +1611,7 @@ bool wl_del_timer(wl_info_t *wl, wl_timer_t *t) return true; } -void wl_free_timer(wl_info_t *wl, wl_timer_t *t) +void wl_free_timer(struct wl_info *wl, wl_timer_t *t) { wl_timer_t *tmp; @@ -1647,7 +1647,7 @@ void wl_free_timer(wl_info_t *wl, wl_timer_t *t) static int wl_linux_watchdog(void *ctx) { - wl_info_t *wl = (wl_info_t *) ctx; + struct wl_info *wl = (struct wl_info *) ctx; struct net_device_stats *stats = NULL; uint id; /* refresh stats */ @@ -1687,13 +1687,12 @@ struct wl_fw_hdr { u32 idx; }; - char *wl_firmwares[WL_MAX_FW] = { "brcm/bcm43xx", NULL }; -int wl_ucode_init_buf(wl_info_t *wl, void **pbuf, u32 idx) +int wl_ucode_init_buf(struct wl_info *wl, void **pbuf, u32 idx) { int i, entry; const u8 *pdata; @@ -1719,7 +1718,7 @@ int wl_ucode_init_buf(wl_info_t *wl, void **pbuf, u32 idx) return -1; } -int wl_ucode_init_uint(wl_info_t *wl, u32 *data, u32 idx) +int wl_ucode_init_uint(struct wl_info *wl, u32 *data, u32 idx) { int i, entry; const u8 *pdata; @@ -1740,7 +1739,7 @@ int wl_ucode_init_uint(wl_info_t *wl, u32 *data, u32 idx) return -1; } -static int wl_request_fw(wl_info_t *wl, struct pci_dev *pdev) +static int wl_request_fw(struct wl_info *wl, struct pci_dev *pdev) { int status; struct device *device = &pdev->dev; @@ -1786,7 +1785,7 @@ void wl_ucode_free_buf(void *p) kfree(p); } -static void wl_release_fw(wl_info_t *wl) +static void wl_release_fw(struct wl_info *wl) { int i; for (i = 0; i < WL_MAX_FW; i++) { diff --git a/drivers/staging/brcm80211/sys/wl_mac80211.h b/drivers/staging/brcm80211/sys/wl_mac80211.h index 239ef3a0ed9b..87a8128d1b3c 100644 --- a/drivers/staging/brcm80211/sys/wl_mac80211.h +++ b/drivers/staging/brcm80211/sys/wl_mac80211.h @@ -97,9 +97,6 @@ struct wl_info { #define INT_LOCK(wl, flags) spin_lock_irqsave(&(wl)->isr_lock, flags) #define INT_UNLOCK(wl, flags) spin_unlock_irqrestore(&(wl)->isr_lock, flags) -/* handle forward declaration */ -typedef struct wl_info wl_info_t; - #ifndef PCI_D0 #define PCI_D0 0 #endif @@ -114,12 +111,7 @@ extern irqreturn_t wl_isr(int irq, void *dev_id); extern int __devinit wl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent); -extern void wl_free(wl_info_t *wl); +extern void wl_free(struct wl_info *wl); extern int wl_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd); -extern int wl_ucode_data_init(wl_info_t *wl); -extern void wl_ucode_data_free(void); -extern void wl_ucode_free_buf(void *); -extern int wl_ucode_init_buf(wl_info_t *wl, void **pbuf, u32 idx); -extern int wl_ucode_init_uint(wl_info_t *wl, u32 *data, u32 idx); #endif /* _wl_mac80211_h_ */ diff --git a/drivers/staging/brcm80211/sys/wl_ucode.h b/drivers/staging/brcm80211/sys/wl_ucode.h index a1ba37209f96..b797ab661195 100644 --- a/drivers/staging/brcm80211/sys/wl_ucode.h +++ b/drivers/staging/brcm80211/sys/wl_ucode.h @@ -35,3 +35,11 @@ extern u32 *bcm43xx_24_lcn; extern u32 bcm43xx_24_lcnsz; extern u32 *bcm43xx_bommajor; extern u32 *bcm43xx_bomminor; + +extern int wl_ucode_data_init(struct wl_info *wl); +extern void wl_ucode_data_free(void); + +extern int wl_ucode_init_buf(struct wl_info *wl, void **pbuf, unsigned int idx); +extern int wl_ucode_init_uint(struct wl_info *wl, unsigned *data, + unsigned int idx); +extern void wl_ucode_free_buf(void *); diff --git a/drivers/staging/brcm80211/sys/wl_ucode_loader.c b/drivers/staging/brcm80211/sys/wl_ucode_loader.c index 0b41a9cb1ec9..acd24726b0f0 100644 --- a/drivers/staging/brcm80211/sys/wl_ucode_loader.c +++ b/drivers/staging/brcm80211/sys/wl_ucode_loader.c @@ -14,17 +14,12 @@ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -typedef struct wl_info wl_info_t; #include #include #include #include -extern int wl_ucode_init_buf(wl_info_t *wl, void **pbuf, unsigned int idx); -extern int wl_ucode_init_uint(wl_info_t *wl, unsigned *data, unsigned int idx); -extern int wl_ucode_data_init(wl_info_t *wl); -extern void wl_ucode_data_free(void); -extern void wl_ucode_free_buf(void *); + d11init_t *d11lcn0bsinitvals24; d11init_t *d11lcn0initvals24; @@ -42,7 +37,7 @@ u32 bcm43xx_24_lcnsz; u32 *bcm43xx_bommajor; u32 *bcm43xx_bomminor; -int wl_ucode_data_init(wl_info_t *wl) +int wl_ucode_data_init(struct wl_info *wl) { wl_ucode_init_buf(wl, (void **)&d11lcn0bsinitvals24, D11LCN0BSINITVALS24); -- cgit v1.2.3 From 430cbeb86fdcbbdabea7d4aa65307de8de425350 Mon Sep 17 00:00:00 2001 From: Dave Chinner Date: Thu, 2 Dec 2010 16:30:55 +1100 Subject: xfs: add a lru to the XFS buffer cache Introduce a per-buftarg LRU for memory reclaim to operate on. This is the last piece we need to put in place so that we can fully control the buffer lifecycle. This allows XFS to be responsibile for maintaining the working set of buffers under memory pressure instead of relying on the VM reclaim not to take pages we need out from underneath us. The implementation introduces a b_lru_ref counter into the buffer. This is currently set to 1 whenever the buffer is referenced and so is used to determine if the buffer should be added to the LRU or not when freed. Effectively it allows lazy LRU initialisation of the buffer so we do not need to touch the LRU list and locks in xfs_buf_find(). Instead, when the buffer is being released and we drop the last reference to it, we check the b_lru_ref count and if it is none zero we re-add the buffer reference and add the inode to the LRU. The b_lru_ref counter is decremented by the shrinker, and whenever the shrinker comes across a buffer with a zero b_lru_ref counter, if released the LRU reference on the buffer. In the absence of a lookup race, this will result in the buffer being freed. This counting mechanism is used instead of a reference flag so that it is simple to re-introduce buffer-type specific reclaim reference counts to prioritise reclaim more effectively. We still have all those hooks in the XFS code, so this will provide the infrastructure to re-implement that functionality. Signed-off-by: Dave Chinner Reviewed-by: Christoph Hellwig --- fs/xfs/linux-2.6/xfs_buf.c | 164 +++++++++++++++++++++++++++++++++++++++------ fs/xfs/linux-2.6/xfs_buf.h | 8 ++- 2 files changed, 150 insertions(+), 22 deletions(-) diff --git a/fs/xfs/linux-2.6/xfs_buf.c b/fs/xfs/linux-2.6/xfs_buf.c index 0a00d7a2fc23..92f1f2acc6ab 100644 --- a/fs/xfs/linux-2.6/xfs_buf.c +++ b/fs/xfs/linux-2.6/xfs_buf.c @@ -163,8 +163,79 @@ test_page_region( } /* - * Internal xfs_buf_t object manipulation + * xfs_buf_lru_add - add a buffer to the LRU. + * + * The LRU takes a new reference to the buffer so that it will only be freed + * once the shrinker takes the buffer off the LRU. */ +STATIC void +xfs_buf_lru_add( + struct xfs_buf *bp) +{ + struct xfs_buftarg *btp = bp->b_target; + + spin_lock(&btp->bt_lru_lock); + if (list_empty(&bp->b_lru)) { + atomic_inc(&bp->b_hold); + list_add_tail(&bp->b_lru, &btp->bt_lru); + btp->bt_lru_nr++; + } + spin_unlock(&btp->bt_lru_lock); +} + +/* + * xfs_buf_lru_del - remove a buffer from the LRU + * + * The unlocked check is safe here because it only occurs when there are not + * b_lru_ref counts left on the inode under the pag->pag_buf_lock. it is there + * to optimise the shrinker removing the buffer from the LRU and calling + * xfs_buf_free(). i.e. it removes an unneccessary round trip on the + * bt_lru_lock. + */ +STATIC void +xfs_buf_lru_del( + struct xfs_buf *bp) +{ + struct xfs_buftarg *btp = bp->b_target; + + if (list_empty(&bp->b_lru)) + return; + + spin_lock(&btp->bt_lru_lock); + if (!list_empty(&bp->b_lru)) { + list_del_init(&bp->b_lru); + btp->bt_lru_nr--; + } + spin_unlock(&btp->bt_lru_lock); +} + +/* + * When we mark a buffer stale, we remove the buffer from the LRU and clear the + * b_lru_ref count so that the buffer is freed immediately when the buffer + * reference count falls to zero. If the buffer is already on the LRU, we need + * to remove the reference that LRU holds on the buffer. + * + * This prevents build-up of stale buffers on the LRU. + */ +void +xfs_buf_stale( + struct xfs_buf *bp) +{ + bp->b_flags |= XBF_STALE; + atomic_set(&(bp)->b_lru_ref, 0); + if (!list_empty(&bp->b_lru)) { + struct xfs_buftarg *btp = bp->b_target; + + spin_lock(&btp->bt_lru_lock); + if (!list_empty(&bp->b_lru)) { + list_del_init(&bp->b_lru); + btp->bt_lru_nr--; + atomic_dec(&bp->b_hold); + } + spin_unlock(&btp->bt_lru_lock); + } + ASSERT(atomic_read(&bp->b_hold) >= 1); +} STATIC void _xfs_buf_initialize( @@ -181,7 +252,9 @@ _xfs_buf_initialize( memset(bp, 0, sizeof(xfs_buf_t)); atomic_set(&bp->b_hold, 1); + atomic_set(&bp->b_lru_ref, 1); init_completion(&bp->b_iowait); + INIT_LIST_HEAD(&bp->b_lru); INIT_LIST_HEAD(&bp->b_list); RB_CLEAR_NODE(&bp->b_rbnode); sema_init(&bp->b_sema, 0); /* held, no waiters */ @@ -257,6 +330,8 @@ xfs_buf_free( { trace_xfs_buf_free(bp, _RET_IP_); + ASSERT(list_empty(&bp->b_lru)); + if (bp->b_flags & (_XBF_PAGE_CACHE|_XBF_PAGES)) { uint i; @@ -822,6 +897,7 @@ xfs_buf_rele( if (!pag) { ASSERT(!bp->b_relse); + ASSERT(list_empty(&bp->b_lru)); ASSERT(RB_EMPTY_NODE(&bp->b_rbnode)); if (atomic_dec_and_test(&bp->b_hold)) xfs_buf_free(bp); @@ -829,13 +905,19 @@ xfs_buf_rele( } ASSERT(!RB_EMPTY_NODE(&bp->b_rbnode)); + ASSERT(atomic_read(&bp->b_hold) > 0); if (atomic_dec_and_lock(&bp->b_hold, &pag->pag_buf_lock)) { if (bp->b_relse) { atomic_inc(&bp->b_hold); spin_unlock(&pag->pag_buf_lock); bp->b_relse(bp); + } else if (!(bp->b_flags & XBF_STALE) && + atomic_read(&bp->b_lru_ref)) { + xfs_buf_lru_add(bp); + spin_unlock(&pag->pag_buf_lock); } else { + xfs_buf_lru_del(bp); ASSERT(!(bp->b_flags & (XBF_DELWRI|_XBF_DELWRI_Q))); rb_erase(&bp->b_rbnode, &pag->pag_buf_tree); spin_unlock(&pag->pag_buf_lock); @@ -1432,27 +1514,35 @@ xfs_buf_iomove( */ /* - * Wait for any bufs with callbacks that have been submitted but - * have not yet returned... walk the hash list for the target. + * Wait for any bufs with callbacks that have been submitted but have not yet + * returned. These buffers will have an elevated hold count, so wait on those + * while freeing all the buffers only held by the LRU. */ void xfs_wait_buftarg( struct xfs_buftarg *btp) { - struct xfs_perag *pag; - uint i; + struct xfs_buf *bp; - for (i = 0; i < btp->bt_mount->m_sb.sb_agcount; i++) { - pag = xfs_perag_get(btp->bt_mount, i); - spin_lock(&pag->pag_buf_lock); - while (rb_first(&pag->pag_buf_tree)) { - spin_unlock(&pag->pag_buf_lock); +restart: + spin_lock(&btp->bt_lru_lock); + while (!list_empty(&btp->bt_lru)) { + bp = list_first_entry(&btp->bt_lru, struct xfs_buf, b_lru); + if (atomic_read(&bp->b_hold) > 1) { + spin_unlock(&btp->bt_lru_lock); delay(100); - spin_lock(&pag->pag_buf_lock); + goto restart; } - spin_unlock(&pag->pag_buf_lock); - xfs_perag_put(pag); + /* + * clear the LRU reference count so the bufer doesn't get + * ignored in xfs_buf_rele(). + */ + atomic_set(&bp->b_lru_ref, 0); + spin_unlock(&btp->bt_lru_lock); + xfs_buf_rele(bp); + spin_lock(&btp->bt_lru_lock); } + spin_unlock(&btp->bt_lru_lock); } int @@ -1463,15 +1553,45 @@ xfs_buftarg_shrink( { struct xfs_buftarg *btp = container_of(shrink, struct xfs_buftarg, bt_shrinker); - if (nr_to_scan) { - if (test_bit(XBT_FORCE_SLEEP, &btp->bt_flags)) - return -1; - if (list_empty(&btp->bt_delwrite_queue)) - return -1; - set_bit(XBT_FORCE_FLUSH, &btp->bt_flags); - wake_up_process(btp->bt_task); + struct xfs_buf *bp; + LIST_HEAD(dispose); + + if (!nr_to_scan) + return btp->bt_lru_nr; + + spin_lock(&btp->bt_lru_lock); + while (!list_empty(&btp->bt_lru)) { + if (nr_to_scan-- <= 0) + break; + + bp = list_first_entry(&btp->bt_lru, struct xfs_buf, b_lru); + + /* + * Decrement the b_lru_ref count unless the value is already + * zero. If the value is already zero, we need to reclaim the + * buffer, otherwise it gets another trip through the LRU. + */ + if (!atomic_add_unless(&bp->b_lru_ref, -1, 0)) { + list_move_tail(&bp->b_lru, &btp->bt_lru); + continue; + } + + /* + * remove the buffer from the LRU now to avoid needing another + * lock round trip inside xfs_buf_rele(). + */ + list_move(&bp->b_lru, &dispose); + btp->bt_lru_nr--; } - return list_empty(&btp->bt_delwrite_queue) ? -1 : 1; + spin_unlock(&btp->bt_lru_lock); + + while (!list_empty(&dispose)) { + bp = list_first_entry(&dispose, struct xfs_buf, b_lru); + list_del_init(&bp->b_lru); + xfs_buf_rele(bp); + } + + return btp->bt_lru_nr; } void @@ -1606,6 +1726,8 @@ xfs_alloc_buftarg( btp->bt_mount = mp; btp->bt_dev = bdev->bd_dev; btp->bt_bdev = bdev; + INIT_LIST_HEAD(&btp->bt_lru); + spin_lock_init(&btp->bt_lru_lock); if (xfs_setsize_buftarg_early(btp, bdev)) goto error; if (xfs_mapping_buftarg(btp, bdev)) diff --git a/fs/xfs/linux-2.6/xfs_buf.h b/fs/xfs/linux-2.6/xfs_buf.h index 9344103e77d6..4601eabd0da0 100644 --- a/fs/xfs/linux-2.6/xfs_buf.h +++ b/fs/xfs/linux-2.6/xfs_buf.h @@ -134,6 +134,9 @@ typedef struct xfs_buftarg { /* LRU control structures */ struct shrinker bt_shrinker; + struct list_head bt_lru; + spinlock_t bt_lru_lock; + unsigned int bt_lru_nr; } xfs_buftarg_t; /* @@ -166,9 +169,11 @@ typedef struct xfs_buf { xfs_off_t b_file_offset; /* offset in file */ size_t b_buffer_length;/* size of buffer in bytes */ atomic_t b_hold; /* reference count */ + atomic_t b_lru_ref; /* lru reclaim ref count */ xfs_buf_flags_t b_flags; /* status flags */ struct semaphore b_sema; /* semaphore for lockables */ + struct list_head b_lru; /* lru list */ wait_queue_head_t b_waiters; /* unpin waiters */ struct list_head b_list; struct xfs_perag *b_pag; /* contains rbtree root */ @@ -266,7 +271,8 @@ extern void xfs_buf_terminate(void); #define XFS_BUF_ZEROFLAGS(bp) ((bp)->b_flags &= \ ~(XBF_READ|XBF_WRITE|XBF_ASYNC|XBF_DELWRI|XBF_ORDERED)) -#define XFS_BUF_STALE(bp) ((bp)->b_flags |= XBF_STALE) +void xfs_buf_stale(struct xfs_buf *bp); +#define XFS_BUF_STALE(bp) xfs_buf_stale(bp); #define XFS_BUF_UNSTALE(bp) ((bp)->b_flags &= ~XBF_STALE) #define XFS_BUF_ISSTALE(bp) ((bp)->b_flags & XBF_STALE) #define XFS_BUF_SUPER_STALE(bp) do { \ -- cgit v1.2.3 From 821eb21d97a8b686649c08b7284d0b9f34d0e138 Mon Sep 17 00:00:00 2001 From: Dave Chinner Date: Thu, 2 Dec 2010 16:31:13 +1100 Subject: xfs: connect up buffer reclaim priority hooks Now that the buffer reclaim infrastructure can handle different reclaim priorities for different types of buffers, reconnect the hooks in the XFS code that has been sitting dormant since it was ported to Linux. This should finally give use reclaim prioritisation that is on a par with the functionality that Irix provided XFS 15 years ago. Signed-off-by: Dave Chinner Reviewed-by: Christoph Hellwig --- fs/xfs/linux-2.6/xfs_buf.h | 10 ++++++++-- fs/xfs/xfs_btree.c | 9 ++++----- fs/xfs/xfs_inode.c | 2 +- fs/xfs/xfs_trans.h | 2 +- 4 files changed, 14 insertions(+), 9 deletions(-) diff --git a/fs/xfs/linux-2.6/xfs_buf.h b/fs/xfs/linux-2.6/xfs_buf.h index 4601eabd0da0..a76c2428faff 100644 --- a/fs/xfs/linux-2.6/xfs_buf.h +++ b/fs/xfs/linux-2.6/xfs_buf.h @@ -336,9 +336,15 @@ void xfs_buf_stale(struct xfs_buf *bp); #define XFS_BUF_SIZE(bp) ((bp)->b_buffer_length) #define XFS_BUF_SET_SIZE(bp, cnt) ((bp)->b_buffer_length = (cnt)) -#define XFS_BUF_SET_VTYPE_REF(bp, type, ref) do { } while (0) +static inline void +xfs_buf_set_ref( + struct xfs_buf *bp, + int lru_ref) +{ + atomic_set(&bp->b_lru_ref, lru_ref); +} +#define XFS_BUF_SET_VTYPE_REF(bp, type, ref) xfs_buf_set_ref(bp, ref) #define XFS_BUF_SET_VTYPE(bp, type) do { } while (0) -#define XFS_BUF_SET_REF(bp, ref) do { } while (0) #define XFS_BUF_ISPINNED(bp) atomic_read(&((bp)->b_pin_count)) diff --git a/fs/xfs/xfs_btree.c b/fs/xfs/xfs_btree.c index 04f9cca8da7e..2f9e97c128a0 100644 --- a/fs/xfs/xfs_btree.c +++ b/fs/xfs/xfs_btree.c @@ -634,9 +634,8 @@ xfs_btree_read_bufl( return error; } ASSERT(!bp || !XFS_BUF_GETERROR(bp)); - if (bp != NULL) { + if (bp) XFS_BUF_SET_VTYPE_REF(bp, B_FS_MAP, refval); - } *bpp = bp; return 0; } @@ -944,13 +943,13 @@ xfs_btree_set_refs( switch (cur->bc_btnum) { case XFS_BTNUM_BNO: case XFS_BTNUM_CNT: - XFS_BUF_SET_VTYPE_REF(*bpp, B_FS_MAP, XFS_ALLOC_BTREE_REF); + XFS_BUF_SET_VTYPE_REF(bp, B_FS_MAP, XFS_ALLOC_BTREE_REF); break; case XFS_BTNUM_INO: - XFS_BUF_SET_VTYPE_REF(*bpp, B_FS_INOMAP, XFS_INO_BTREE_REF); + XFS_BUF_SET_VTYPE_REF(bp, B_FS_INOMAP, XFS_INO_BTREE_REF); break; case XFS_BTNUM_BMAP: - XFS_BUF_SET_VTYPE_REF(*bpp, B_FS_MAP, XFS_BMAP_BTREE_REF); + XFS_BUF_SET_VTYPE_REF(bp, B_FS_MAP, XFS_BMAP_BTREE_REF); break; default: ASSERT(0); diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index 43ffd9079106..be7cf625421f 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -887,7 +887,7 @@ xfs_iread( * around for a while. This helps to keep recently accessed * meta-data in-core longer. */ - XFS_BUF_SET_REF(bp, XFS_INO_REF); + xfs_buf_set_ref(bp, XFS_INO_REF); /* * Use xfs_trans_brelse() to release the buffer containing the diff --git a/fs/xfs/xfs_trans.h b/fs/xfs/xfs_trans.h index 246286b77a86..c2042b736b81 100644 --- a/fs/xfs/xfs_trans.h +++ b/fs/xfs/xfs_trans.h @@ -294,8 +294,8 @@ struct xfs_log_item_desc { #define XFS_ALLOC_BTREE_REF 2 #define XFS_BMAP_BTREE_REF 2 #define XFS_DIR_BTREE_REF 2 +#define XFS_INO_REF 2 #define XFS_ATTR_BTREE_REF 1 -#define XFS_INO_REF 1 #define XFS_DQUOT_REF 1 #ifdef __KERNEL__ -- cgit v1.2.3 From 079f2f7485648c1397a35575fae45908a0db5ba6 Mon Sep 17 00:00:00 2001 From: Steffen Klassert Date: Mon, 22 Nov 2010 11:25:50 +0100 Subject: crypto: scatterwalk - Add scatterwalk_crypto_chain helper A lot of crypto algorithms implement their own chaining function. So add a generic one that can be used from all the algorithms that need scatterlist chaining. Signed-off-by: Steffen Klassert Signed-off-by: Herbert Xu --- include/crypto/scatterwalk.h | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/include/crypto/scatterwalk.h b/include/crypto/scatterwalk.h index 833d208c25d6..4fd95a323beb 100644 --- a/include/crypto/scatterwalk.h +++ b/include/crypto/scatterwalk.h @@ -68,6 +68,21 @@ static inline struct scatterlist *scatterwalk_sg_next(struct scatterlist *sg) return (++sg)->length ? sg : (void *)sg_page(sg); } +static inline void scatterwalk_crypto_chain(struct scatterlist *head, + struct scatterlist *sg, + int chain, int num) +{ + if (chain) { + head->length += sg->length; + sg = scatterwalk_sg_next(sg); + } + + if (sg) + scatterwalk_sg_chain(head, num, sg); + else + sg_mark_end(head); +} + static inline unsigned long scatterwalk_samebuf(struct scatter_walk *walk_in, struct scatter_walk *walk_out) { -- cgit v1.2.3 From c920fa6051c1e7eb3733eaefd01e5bcdddb3d4c8 Mon Sep 17 00:00:00 2001 From: Steffen Klassert Date: Mon, 22 Nov 2010 11:26:54 +0100 Subject: crypto: Use scatterwalk_crypto_chain Use scatterwalk_crypto_chain in favor of locally defined chaining functions. Signed-off-by: Steffen Klassert Signed-off-by: Herbert Xu --- crypto/authenc.c | 22 ++++------------------ crypto/eseqiv.c | 18 ++---------------- crypto/gcm.c | 19 ++----------------- 3 files changed, 8 insertions(+), 51 deletions(-) diff --git a/crypto/authenc.c b/crypto/authenc.c index a5a22cfcd07b..5ef7ba6b6a76 100644 --- a/crypto/authenc.c +++ b/crypto/authenc.c @@ -107,20 +107,6 @@ badkey: goto out; } -static void authenc_chain(struct scatterlist *head, struct scatterlist *sg, - int chain) -{ - if (chain) { - head->length += sg->length; - sg = scatterwalk_sg_next(sg); - } - - if (sg) - scatterwalk_sg_chain(head, 2, sg); - else - sg_mark_end(head); -} - static void authenc_geniv_ahash_update_done(struct crypto_async_request *areq, int err) { @@ -345,7 +331,7 @@ static int crypto_authenc_genicv(struct aead_request *req, u8 *iv, if (ivsize) { sg_init_table(cipher, 2); sg_set_buf(cipher, iv, ivsize); - authenc_chain(cipher, dst, vdst == iv + ivsize); + scatterwalk_crypto_chain(cipher, dst, vdst == iv + ivsize, 2); dst = cipher; cryptlen += ivsize; } @@ -354,7 +340,7 @@ static int crypto_authenc_genicv(struct aead_request *req, u8 *iv, authenc_ahash_fn = crypto_authenc_ahash; sg_init_table(asg, 2); sg_set_page(asg, sg_page(assoc), assoc->length, assoc->offset); - authenc_chain(asg, dst, 0); + scatterwalk_crypto_chain(asg, dst, 0, 2); dst = asg; cryptlen += req->assoclen; } @@ -499,7 +485,7 @@ static int crypto_authenc_iverify(struct aead_request *req, u8 *iv, if (ivsize) { sg_init_table(cipher, 2); sg_set_buf(cipher, iv, ivsize); - authenc_chain(cipher, src, vsrc == iv + ivsize); + scatterwalk_crypto_chain(cipher, src, vsrc == iv + ivsize, 2); src = cipher; cryptlen += ivsize; } @@ -508,7 +494,7 @@ static int crypto_authenc_iverify(struct aead_request *req, u8 *iv, authenc_ahash_fn = crypto_authenc_ahash; sg_init_table(asg, 2); sg_set_page(asg, sg_page(assoc), assoc->length, assoc->offset); - authenc_chain(asg, src, 0); + scatterwalk_crypto_chain(asg, src, 0, 2); src = asg; cryptlen += req->assoclen; } diff --git a/crypto/eseqiv.c b/crypto/eseqiv.c index 3ca3b669d5d5..42ce9f570aec 100644 --- a/crypto/eseqiv.c +++ b/crypto/eseqiv.c @@ -62,20 +62,6 @@ out: skcipher_givcrypt_complete(req, err); } -static void eseqiv_chain(struct scatterlist *head, struct scatterlist *sg, - int chain) -{ - if (chain) { - head->length += sg->length; - sg = scatterwalk_sg_next(sg); - } - - if (sg) - scatterwalk_sg_chain(head, 2, sg); - else - sg_mark_end(head); -} - static int eseqiv_givencrypt(struct skcipher_givcrypt_request *req) { struct crypto_ablkcipher *geniv = skcipher_givcrypt_reqtfm(req); @@ -124,13 +110,13 @@ static int eseqiv_givencrypt(struct skcipher_givcrypt_request *req) sg_init_table(reqctx->src, 2); sg_set_buf(reqctx->src, giv, ivsize); - eseqiv_chain(reqctx->src, osrc, vsrc == giv + ivsize); + scatterwalk_crypto_chain(reqctx->src, osrc, vsrc == giv + ivsize, 2); dst = reqctx->src; if (osrc != odst) { sg_init_table(reqctx->dst, 2); sg_set_buf(reqctx->dst, giv, ivsize); - eseqiv_chain(reqctx->dst, odst, vdst == giv + ivsize); + scatterwalk_crypto_chain(reqctx->dst, odst, vdst == giv + ivsize, 2); dst = reqctx->dst; } diff --git a/crypto/gcm.c b/crypto/gcm.c index 2f5fbba6576c..1a252639ef91 100644 --- a/crypto/gcm.c +++ b/crypto/gcm.c @@ -1102,21 +1102,6 @@ static int crypto_rfc4543_setauthsize(struct crypto_aead *parent, return crypto_aead_setauthsize(ctx->child, authsize); } -/* this is the same as crypto_authenc_chain */ -static void crypto_rfc4543_chain(struct scatterlist *head, - struct scatterlist *sg, int chain) -{ - if (chain) { - head->length += sg->length; - sg = scatterwalk_sg_next(sg); - } - - if (sg) - scatterwalk_sg_chain(head, 2, sg); - else - sg_mark_end(head); -} - static struct aead_request *crypto_rfc4543_crypt(struct aead_request *req, int enc) { @@ -1154,13 +1139,13 @@ static struct aead_request *crypto_rfc4543_crypt(struct aead_request *req, sg_init_table(payload, 2); sg_set_buf(payload, req->iv, 8); - crypto_rfc4543_chain(payload, dst, vdst == req->iv + 8); + scatterwalk_crypto_chain(payload, dst, vdst == req->iv + 8, 2); assoclen += 8 + req->cryptlen - (enc ? 0 : authsize); sg_init_table(assoc, 2); sg_set_page(assoc, sg_page(req->assoc), req->assoc->length, req->assoc->offset); - crypto_rfc4543_chain(assoc, payload, 0); + scatterwalk_crypto_chain(assoc, payload, 0, 2); aead_request_set_tfm(subreq, ctx->child); aead_request_set_callback(subreq, req->base.flags, req->base.complete, -- cgit v1.2.3 From 3bd2e2216bc82a83fc5048f8e61d2d22dd5d9cda Mon Sep 17 00:00:00 2001 From: Dmitry Kasatkin Date: Tue, 30 Nov 2010 10:13:27 +0200 Subject: crypto: omap-aes - DMA initialization fixes for OMAP off mode DMA parameters for constant data were initialized during driver probe(). It seems that those settings sometimes are lost when devices goes to off mode. This patch makes DMA initialization just before use. It solves off mode problems. Signed-off-by: Dmitry Kasatkin Signed-off-by: Herbert Xu --- drivers/crypto/omap-aes.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/crypto/omap-aes.c b/drivers/crypto/omap-aes.c index 799ca517c121..41c91f3c7f14 100644 --- a/drivers/crypto/omap-aes.c +++ b/drivers/crypto/omap-aes.c @@ -339,18 +339,6 @@ static int omap_aes_dma_init(struct omap_aes_dev *dd) goto err_dma_out; } - omap_set_dma_dest_params(dd->dma_lch_in, 0, OMAP_DMA_AMODE_CONSTANT, - dd->phys_base + AES_REG_DATA, 0, 4); - - omap_set_dma_dest_burst_mode(dd->dma_lch_in, OMAP_DMA_DATA_BURST_4); - omap_set_dma_src_burst_mode(dd->dma_lch_in, OMAP_DMA_DATA_BURST_4); - - omap_set_dma_src_params(dd->dma_lch_out, 0, OMAP_DMA_AMODE_CONSTANT, - dd->phys_base + AES_REG_DATA, 0, 4); - - omap_set_dma_src_burst_mode(dd->dma_lch_out, OMAP_DMA_DATA_BURST_4); - omap_set_dma_dest_burst_mode(dd->dma_lch_out, OMAP_DMA_DATA_BURST_4); - return 0; err_dma_out: @@ -443,6 +431,12 @@ static int omap_aes_crypt_dma(struct crypto_tfm *tfm, dma_addr_t dma_addr_in, len32 = DIV_ROUND_UP(length, sizeof(u32)); /* IN */ + omap_set_dma_dest_params(dd->dma_lch_in, 0, OMAP_DMA_AMODE_CONSTANT, + dd->phys_base + AES_REG_DATA, 0, 4); + + omap_set_dma_dest_burst_mode(dd->dma_lch_in, OMAP_DMA_DATA_BURST_4); + omap_set_dma_src_burst_mode(dd->dma_lch_in, OMAP_DMA_DATA_BURST_4); + omap_set_dma_transfer_params(dd->dma_lch_in, OMAP_DMA_DATA_TYPE_S32, len32, 1, OMAP_DMA_SYNC_PACKET, dd->dma_in, OMAP_DMA_DST_SYNC); @@ -451,6 +445,12 @@ static int omap_aes_crypt_dma(struct crypto_tfm *tfm, dma_addr_t dma_addr_in, dma_addr_in, 0, 0); /* OUT */ + omap_set_dma_src_params(dd->dma_lch_out, 0, OMAP_DMA_AMODE_CONSTANT, + dd->phys_base + AES_REG_DATA, 0, 4); + + omap_set_dma_src_burst_mode(dd->dma_lch_out, OMAP_DMA_DATA_BURST_4); + omap_set_dma_dest_burst_mode(dd->dma_lch_out, OMAP_DMA_DATA_BURST_4); + omap_set_dma_transfer_params(dd->dma_lch_out, OMAP_DMA_DATA_TYPE_S32, len32, 1, OMAP_DMA_SYNC_PACKET, dd->dma_out, OMAP_DMA_SRC_SYNC); -- cgit v1.2.3 From eeb2b202c5b886b76c3bfa76f47e450fa69389fb Mon Sep 17 00:00:00 2001 From: Dmitry Kasatkin Date: Tue, 30 Nov 2010 10:13:28 +0200 Subject: crypto: omap-aes - redundant locking is removed Submitting request involved double locking for enqueuing and dequeuing. Now it is done under the same lock. FLAGS_BUSY is now handled under the same lock. Signed-off-by: Dmitry Kasatkin Signed-off-by: Herbert Xu --- drivers/crypto/omap-aes.c | 70 ++++++++++++++++++++++------------------------- 1 file changed, 32 insertions(+), 38 deletions(-) diff --git a/drivers/crypto/omap-aes.c b/drivers/crypto/omap-aes.c index 41c91f3c7f14..2d8f72eaf896 100644 --- a/drivers/crypto/omap-aes.c +++ b/drivers/crypto/omap-aes.c @@ -78,7 +78,7 @@ #define FLAGS_NEW_IV BIT(5) #define FLAGS_INIT BIT(6) #define FLAGS_FAST BIT(7) -#define FLAGS_BUSY 8 +#define FLAGS_BUSY BIT(8) struct omap_aes_ctx { struct omap_aes_dev *dd; @@ -179,9 +179,8 @@ static int omap_aes_wait(struct omap_aes_dev *dd, u32 offset, u32 bit) static int omap_aes_hw_init(struct omap_aes_dev *dd) { - int err = 0; - clk_enable(dd->iclk); + if (!(dd->flags & FLAGS_INIT)) { /* is it necessary to reset before every operation? */ omap_aes_write_mask(dd, AES_REG_MASK, AES_REG_MASK_SOFTRESET, @@ -193,18 +192,15 @@ static int omap_aes_hw_init(struct omap_aes_dev *dd) __asm__ __volatile__("nop"); __asm__ __volatile__("nop"); - err = omap_aes_wait(dd, AES_REG_SYSSTATUS, - AES_REG_SYSSTATUS_RESETDONE); - if (!err) - dd->flags |= FLAGS_INIT; + if (omap_aes_wait(dd, AES_REG_SYSSTATUS, + AES_REG_SYSSTATUS_RESETDONE)) { + clk_disable(dd->iclk); + return -ETIMEDOUT; + } + dd->flags |= FLAGS_INIT; } - return err; -} - -static void omap_aes_hw_cleanup(struct omap_aes_dev *dd) -{ - clk_disable(dd->iclk); + return 0; } static void omap_aes_write_ctrl(struct omap_aes_dev *dd) @@ -538,6 +534,8 @@ static void omap_aes_finish_req(struct omap_aes_dev *dd, int err) pr_debug("err: %d\n", err); + dd->flags &= ~FLAGS_BUSY; + ctx = crypto_ablkcipher_ctx(crypto_ablkcipher_reqtfm(dd->req)); if (!dd->total) @@ -553,7 +551,7 @@ static int omap_aes_crypt_dma_stop(struct omap_aes_dev *dd) omap_aes_write_mask(dd, AES_REG_MASK, 0, AES_REG_MASK_START); - omap_aes_hw_cleanup(dd); + clk_disable(dd->iclk); omap_stop_dma(dd->dma_lch_in); omap_stop_dma(dd->dma_lch_out); @@ -580,22 +578,26 @@ static int omap_aes_crypt_dma_stop(struct omap_aes_dev *dd) return err; } -static int omap_aes_handle_req(struct omap_aes_dev *dd) +static int omap_aes_handle_req(struct omap_aes_dev *dd, + struct ablkcipher_request *req) { struct crypto_async_request *async_req, *backlog; struct omap_aes_ctx *ctx; struct omap_aes_reqctx *rctx; - struct ablkcipher_request *req; unsigned long flags; - - if (dd->total) - goto start; + int err = 0; spin_lock_irqsave(&dd->lock, flags); + if (req) + err = ablkcipher_enqueue_request(&dd->queue, req); + if (dd->flags & FLAGS_BUSY) { + spin_unlock_irqrestore(&dd->lock, flags); + return err; + } backlog = crypto_get_backlog(&dd->queue); async_req = crypto_dequeue_request(&dd->queue); - if (!async_req) - clear_bit(FLAGS_BUSY, &dd->flags); + if (async_req) + dd->flags |= FLAGS_BUSY; spin_unlock_irqrestore(&dd->lock, flags); if (!async_req) @@ -637,20 +639,23 @@ static int omap_aes_handle_req(struct omap_aes_dev *dd) if (!IS_ALIGNED(req->nbytes, AES_BLOCK_SIZE)) pr_err("request size is not exact amount of AES blocks\n"); -start: - return omap_aes_crypt_dma_start(dd); + omap_aes_crypt_dma_start(dd); + + return err; } static void omap_aes_task(unsigned long data) { struct omap_aes_dev *dd = (struct omap_aes_dev *)data; - int err; pr_debug("enter\n"); - err = omap_aes_crypt_dma_stop(dd); + omap_aes_crypt_dma_stop(dd); - err = omap_aes_handle_req(dd); + if (dd->total) + omap_aes_crypt_dma_start(dd); + else + omap_aes_handle_req(dd, NULL); pr_debug("exit\n"); } @@ -661,8 +666,6 @@ static int omap_aes_crypt(struct ablkcipher_request *req, unsigned long mode) crypto_ablkcipher_reqtfm(req)); struct omap_aes_reqctx *rctx = ablkcipher_request_ctx(req); struct omap_aes_dev *dd; - unsigned long flags; - int err; pr_debug("nbytes: %d, enc: %d, cbc: %d\n", req->nbytes, !!(mode & FLAGS_ENCRYPT), @@ -674,16 +677,7 @@ static int omap_aes_crypt(struct ablkcipher_request *req, unsigned long mode) rctx->mode = mode; - spin_lock_irqsave(&dd->lock, flags); - err = ablkcipher_enqueue_request(&dd->queue, req); - spin_unlock_irqrestore(&dd->lock, flags); - - if (!test_and_set_bit(FLAGS_BUSY, &dd->flags)) - omap_aes_handle_req(dd); - - pr_debug("exit\n"); - - return err; + return omap_aes_handle_req(dd, req); } /* ********************** ALG API ************************************ */ -- cgit v1.2.3 From 21fe9767f3bd56fd9a271dc43b93cd4608d47f4a Mon Sep 17 00:00:00 2001 From: Dmitry Kasatkin Date: Tue, 30 Nov 2010 10:13:29 +0200 Subject: crypto: omap-aes - error handling implementation improved Previous version had not error handling. Request could remain uncompleted. Also in the case of DMA error, FLAGS_INIT is unset and accelerator will be initialized again. Buffer size allignment is checked. Signed-off-by: Dmitry Kasatkin Signed-off-by: Herbert Xu --- drivers/crypto/omap-aes.c | 134 ++++++++++++++++++++++++++++++++-------------- 1 file changed, 93 insertions(+), 41 deletions(-) diff --git a/drivers/crypto/omap-aes.c b/drivers/crypto/omap-aes.c index 2d8f72eaf896..704cc701ab42 100644 --- a/drivers/crypto/omap-aes.c +++ b/drivers/crypto/omap-aes.c @@ -103,14 +103,16 @@ struct omap_aes_dev { struct omap_aes_ctx *ctx; struct device *dev; unsigned long flags; + int err; u32 *iv; u32 ctrl; - spinlock_t lock; - struct crypto_queue queue; + spinlock_t lock; + struct crypto_queue queue; - struct tasklet_struct task; + struct tasklet_struct done_task; + struct tasklet_struct queue_task; struct ablkcipher_request *req; size_t total; @@ -198,24 +200,30 @@ static int omap_aes_hw_init(struct omap_aes_dev *dd) return -ETIMEDOUT; } dd->flags |= FLAGS_INIT; + dd->err = 0; } return 0; } -static void omap_aes_write_ctrl(struct omap_aes_dev *dd) +static int omap_aes_write_ctrl(struct omap_aes_dev *dd) { unsigned int key32; - int i; + int i, err, init = dd->flags & FLAGS_INIT; u32 val, mask; + err = omap_aes_hw_init(dd); + if (err) + return err; + val = FLD_VAL(((dd->ctx->keylen >> 3) - 1), 4, 3); if (dd->flags & FLAGS_CBC) val |= AES_REG_CTRL_CBC; if (dd->flags & FLAGS_ENCRYPT) val |= AES_REG_CTRL_DIRECTION; - if (dd->ctrl == val && !(dd->flags & FLAGS_NEW_IV) && + /* check if hw state & mode have not changed */ + if (init && dd->ctrl == val && !(dd->flags & FLAGS_NEW_IV) && !(dd->ctx->flags & FLAGS_NEW_KEY)) goto out; @@ -257,6 +265,8 @@ out: /* start DMA or disable idle mode */ omap_aes_write_mask(dd, AES_REG_MASK, AES_REG_MASK_START, AES_REG_MASK_START); + + return 0; } static struct omap_aes_dev *omap_aes_find_dev(struct omap_aes_ctx *ctx) @@ -284,8 +294,16 @@ static void omap_aes_dma_callback(int lch, u16 ch_status, void *data) { struct omap_aes_dev *dd = data; - if (lch == dd->dma_lch_out) - tasklet_schedule(&dd->task); + if (ch_status != OMAP_DMA_BLOCK_IRQ) { + pr_err("omap-aes DMA error status: 0x%hx\n", ch_status); + dd->err = -EIO; + dd->flags &= ~FLAGS_INIT; /* request to re-initialize */ + } else if (lch == dd->dma_lch_in) { + return; + } + + /* dma_lch_out - completed */ + tasklet_schedule(&dd->done_task); } static int omap_aes_dma_init(struct omap_aes_dev *dd) @@ -390,6 +408,11 @@ static int sg_copy(struct scatterlist **sg, size_t *offset, void *buf, if (!count) return off; + /* + * buflen and total are AES_BLOCK_SIZE size aligned, + * so count should be also aligned + */ + sg_copy_buf(buf + off, *sg, *offset, count, out); off += count; @@ -415,6 +438,7 @@ static int omap_aes_crypt_dma(struct crypto_tfm *tfm, dma_addr_t dma_addr_in, struct omap_aes_ctx *ctx = crypto_tfm_ctx(tfm); struct omap_aes_dev *dd = ctx->dd; int len32; + int err; pr_debug("len: %d\n", length); @@ -454,11 +478,13 @@ static int omap_aes_crypt_dma(struct crypto_tfm *tfm, dma_addr_t dma_addr_in, omap_set_dma_dest_params(dd->dma_lch_out, 0, OMAP_DMA_AMODE_POST_INC, dma_addr_out, 0, 0); + err = omap_aes_write_ctrl(dd); + if (err) + return err; + omap_start_dma(dd->dma_lch_in); omap_start_dma(dd->dma_lch_out); - omap_aes_write_ctrl(dd); - return 0; } @@ -484,8 +510,10 @@ static int omap_aes_crypt_dma_start(struct omap_aes_dev *dd) count = min(dd->total, sg_dma_len(dd->in_sg)); count = min(count, sg_dma_len(dd->out_sg)); - if (count != dd->total) + if (count != dd->total) { + pr_err("request length != buffer length\n"); return -EINVAL; + } pr_debug("fast\n"); @@ -521,25 +549,28 @@ static int omap_aes_crypt_dma_start(struct omap_aes_dev *dd) dd->total -= count; - err = omap_aes_hw_init(dd); - err = omap_aes_crypt_dma(tfm, addr_in, addr_out, count); + if (err) { + dma_unmap_sg(dd->dev, dd->in_sg, 1, DMA_TO_DEVICE); + dma_unmap_sg(dd->dev, dd->out_sg, 1, DMA_TO_DEVICE); + } return err; } static void omap_aes_finish_req(struct omap_aes_dev *dd, int err) { + struct ablkcipher_request *req = dd->req; struct omap_aes_ctx *ctx; pr_debug("err: %d\n", err); dd->flags &= ~FLAGS_BUSY; - ctx = crypto_ablkcipher_ctx(crypto_ablkcipher_reqtfm(dd->req)); + ctx = crypto_ablkcipher_ctx(crypto_ablkcipher_reqtfm(req)); - if (!dd->total) - dd->req->base.complete(&dd->req->base, err); + if (req->base.complete) + req->base.complete(&req->base, err); } static int omap_aes_crypt_dma_stop(struct omap_aes_dev *dd) @@ -551,11 +582,11 @@ static int omap_aes_crypt_dma_stop(struct omap_aes_dev *dd) omap_aes_write_mask(dd, AES_REG_MASK, 0, AES_REG_MASK_START); - clk_disable(dd->iclk); - omap_stop_dma(dd->dma_lch_in); omap_stop_dma(dd->dma_lch_out); + clk_disable(dd->iclk); + if (dd->flags & FLAGS_FAST) { dma_unmap_sg(dd->dev, dd->out_sg, 1, DMA_FROM_DEVICE); dma_unmap_sg(dd->dev, dd->in_sg, 1, DMA_TO_DEVICE); @@ -572,27 +603,24 @@ static int omap_aes_crypt_dma_stop(struct omap_aes_dev *dd) } } - if (err || !dd->total) - omap_aes_finish_req(dd, err); - return err; } -static int omap_aes_handle_req(struct omap_aes_dev *dd, +static int omap_aes_handle_queue(struct omap_aes_dev *dd, struct ablkcipher_request *req) { struct crypto_async_request *async_req, *backlog; struct omap_aes_ctx *ctx; struct omap_aes_reqctx *rctx; unsigned long flags; - int err = 0; + int err, ret = 0; spin_lock_irqsave(&dd->lock, flags); if (req) - err = ablkcipher_enqueue_request(&dd->queue, req); + ret = ablkcipher_enqueue_request(&dd->queue, req); if (dd->flags & FLAGS_BUSY) { spin_unlock_irqrestore(&dd->lock, flags); - return err; + return ret; } backlog = crypto_get_backlog(&dd->queue); async_req = crypto_dequeue_request(&dd->queue); @@ -601,7 +629,7 @@ static int omap_aes_handle_req(struct omap_aes_dev *dd, spin_unlock_irqrestore(&dd->lock, flags); if (!async_req) - return 0; + return ret; if (backlog) backlog->complete(backlog, -EINPROGRESS); @@ -636,30 +664,46 @@ static int omap_aes_handle_req(struct omap_aes_dev *dd, ctx->flags |= FLAGS_NEW_KEY; } - if (!IS_ALIGNED(req->nbytes, AES_BLOCK_SIZE)) - pr_err("request size is not exact amount of AES blocks\n"); - - omap_aes_crypt_dma_start(dd); + err = omap_aes_crypt_dma_start(dd); + if (err) { + /* aes_task will not finish it, so do it here */ + omap_aes_finish_req(dd, err); + tasklet_schedule(&dd->queue_task); + } - return err; + return ret; /* return ret, which is enqueue return value */ } -static void omap_aes_task(unsigned long data) +static void omap_aes_done_task(unsigned long data) { struct omap_aes_dev *dd = (struct omap_aes_dev *)data; + int err; pr_debug("enter\n"); - omap_aes_crypt_dma_stop(dd); + err = omap_aes_crypt_dma_stop(dd); - if (dd->total) - omap_aes_crypt_dma_start(dd); - else - omap_aes_handle_req(dd, NULL); + err = dd->err ? : err; + + if (dd->total && !err) { + err = omap_aes_crypt_dma_start(dd); + if (!err) + return; /* DMA started. Not fininishing. */ + } + + omap_aes_finish_req(dd, err); + omap_aes_handle_queue(dd, NULL); pr_debug("exit\n"); } +static void omap_aes_queue_task(unsigned long data) +{ + struct omap_aes_dev *dd = (struct omap_aes_dev *)data; + + omap_aes_handle_queue(dd, NULL); +} + static int omap_aes_crypt(struct ablkcipher_request *req, unsigned long mode) { struct omap_aes_ctx *ctx = crypto_ablkcipher_ctx( @@ -671,13 +715,18 @@ static int omap_aes_crypt(struct ablkcipher_request *req, unsigned long mode) !!(mode & FLAGS_ENCRYPT), !!(mode & FLAGS_CBC)); + if (!IS_ALIGNED(req->nbytes, AES_BLOCK_SIZE)) { + pr_err("request size is not exact amount of AES blocks\n"); + return -EINVAL; + } + dd = omap_aes_find_dev(ctx); if (!dd) return -ENODEV; rctx->mode = mode; - return omap_aes_handle_req(dd, req); + return omap_aes_handle_queue(dd, req); } /* ********************** ALG API ************************************ */ @@ -843,7 +892,8 @@ static int omap_aes_probe(struct platform_device *pdev) (reg & AES_REG_REV_MAJOR) >> 4, reg & AES_REG_REV_MINOR); clk_disable(dd->iclk); - tasklet_init(&dd->task, omap_aes_task, (unsigned long)dd); + tasklet_init(&dd->done_task, omap_aes_done_task, (unsigned long)dd); + tasklet_init(&dd->queue_task, omap_aes_queue_task, (unsigned long)dd); err = omap_aes_dma_init(dd); if (err) @@ -870,7 +920,8 @@ err_algs: crypto_unregister_alg(&algs[j]); omap_aes_dma_cleanup(dd); err_dma: - tasklet_kill(&dd->task); + tasklet_kill(&dd->done_task); + tasklet_kill(&dd->queue_task); iounmap(dd->io_base); err_io: clk_put(dd->iclk); @@ -897,7 +948,8 @@ static int omap_aes_remove(struct platform_device *pdev) for (i = 0; i < ARRAY_SIZE(algs); i++) crypto_unregister_alg(&algs[i]); - tasklet_kill(&dd->task); + tasklet_kill(&dd->done_task); + tasklet_kill(&dd->queue_task); omap_aes_dma_cleanup(dd); iounmap(dd->io_base); clk_put(dd->iclk); -- cgit v1.2.3 From 67a730ce449561f6df838f0b38a2b72cbf4e3c4c Mon Sep 17 00:00:00 2001 From: Dmitry Kasatkin Date: Tue, 30 Nov 2010 10:13:30 +0200 Subject: crypto: omap-aes - unnecessary code removed Key and IV should always be set before AES operation. So no need to check if it has changed or not. Signed-off-by: Dmitry Kasatkin Signed-off-by: Herbert Xu --- drivers/crypto/omap-aes.c | 70 ++++++++++++----------------------------------- 1 file changed, 17 insertions(+), 53 deletions(-) diff --git a/drivers/crypto/omap-aes.c b/drivers/crypto/omap-aes.c index 704cc701ab42..0b21dcef0289 100644 --- a/drivers/crypto/omap-aes.c +++ b/drivers/crypto/omap-aes.c @@ -74,11 +74,9 @@ #define FLAGS_CBC BIT(1) #define FLAGS_GIV BIT(2) -#define FLAGS_NEW_KEY BIT(4) -#define FLAGS_NEW_IV BIT(5) -#define FLAGS_INIT BIT(6) -#define FLAGS_FAST BIT(7) -#define FLAGS_BUSY BIT(8) +#define FLAGS_INIT BIT(4) +#define FLAGS_FAST BIT(5) +#define FLAGS_BUSY BIT(6) struct omap_aes_ctx { struct omap_aes_dev *dd; @@ -105,9 +103,6 @@ struct omap_aes_dev { unsigned long flags; int err; - u32 *iv; - u32 ctrl; - spinlock_t lock; struct crypto_queue queue; @@ -209,28 +204,13 @@ static int omap_aes_hw_init(struct omap_aes_dev *dd) static int omap_aes_write_ctrl(struct omap_aes_dev *dd) { unsigned int key32; - int i, err, init = dd->flags & FLAGS_INIT; + int i, err; u32 val, mask; err = omap_aes_hw_init(dd); if (err) return err; - val = FLD_VAL(((dd->ctx->keylen >> 3) - 1), 4, 3); - if (dd->flags & FLAGS_CBC) - val |= AES_REG_CTRL_CBC; - if (dd->flags & FLAGS_ENCRYPT) - val |= AES_REG_CTRL_DIRECTION; - - /* check if hw state & mode have not changed */ - if (init && dd->ctrl == val && !(dd->flags & FLAGS_NEW_IV) && - !(dd->ctx->flags & FLAGS_NEW_KEY)) - goto out; - - /* only need to write control registers for new settings */ - - dd->ctrl = val; - val = 0; if (dd->dma_lch_out >= 0) val |= AES_REG_MASK_DMA_OUT_EN; @@ -241,27 +221,28 @@ static int omap_aes_write_ctrl(struct omap_aes_dev *dd) omap_aes_write_mask(dd, AES_REG_MASK, val, mask); - pr_debug("Set key\n"); key32 = dd->ctx->keylen / sizeof(u32); - /* set a key */ + + /* it seems a key should always be set even if it has not changed */ for (i = 0; i < key32; i++) { omap_aes_write(dd, AES_REG_KEY(i), __le32_to_cpu(dd->ctx->key[i])); } - dd->ctx->flags &= ~FLAGS_NEW_KEY; - if (dd->flags & FLAGS_NEW_IV) { - pr_debug("Set IV\n"); - omap_aes_write_n(dd, AES_REG_IV(0), dd->iv, 4); - dd->flags &= ~FLAGS_NEW_IV; - } + if ((dd->flags & FLAGS_CBC) && dd->req->info) + omap_aes_write_n(dd, AES_REG_IV(0), dd->req->info, 4); + + val = FLD_VAL(((dd->ctx->keylen >> 3) - 1), 4, 3); + if (dd->flags & FLAGS_CBC) + val |= AES_REG_CTRL_CBC; + if (dd->flags & FLAGS_ENCRYPT) + val |= AES_REG_CTRL_DIRECTION; mask = AES_REG_CTRL_CBC | AES_REG_CTRL_DIRECTION | AES_REG_CTRL_KEY_SIZE; - omap_aes_write_mask(dd, AES_REG_CTRL, dd->ctrl, mask); + omap_aes_write_mask(dd, AES_REG_CTRL, val, mask); -out: /* start DMA or disable idle mode */ omap_aes_write_mask(dd, AES_REG_MASK, AES_REG_MASK_START, AES_REG_MASK_START); @@ -561,16 +542,12 @@ static int omap_aes_crypt_dma_start(struct omap_aes_dev *dd) static void omap_aes_finish_req(struct omap_aes_dev *dd, int err) { struct ablkcipher_request *req = dd->req; - struct omap_aes_ctx *ctx; pr_debug("err: %d\n", err); dd->flags &= ~FLAGS_BUSY; - ctx = crypto_ablkcipher_ctx(crypto_ablkcipher_reqtfm(req)); - - if (req->base.complete) - req->base.complete(&req->base, err); + req->base.complete(&req->base, err); } static int omap_aes_crypt_dma_stop(struct omap_aes_dev *dd) @@ -636,8 +613,6 @@ static int omap_aes_handle_queue(struct omap_aes_dev *dd, req = ablkcipher_request_cast(async_req); - pr_debug("get new req\n"); - /* assign new request to device */ dd->req = req; dd->total = req->nbytes; @@ -651,18 +626,8 @@ static int omap_aes_handle_queue(struct omap_aes_dev *dd, rctx->mode &= FLAGS_MODE_MASK; dd->flags = (dd->flags & ~FLAGS_MODE_MASK) | rctx->mode; - dd->iv = req->info; - if ((dd->flags & FLAGS_CBC) && dd->iv) - dd->flags |= FLAGS_NEW_IV; - else - dd->flags &= ~FLAGS_NEW_IV; - + dd->ctx = ctx; ctx->dd = dd; - if (dd->ctx != ctx) { - /* assign new context to device */ - dd->ctx = ctx; - ctx->flags |= FLAGS_NEW_KEY; - } err = omap_aes_crypt_dma_start(dd); if (err) { @@ -744,7 +709,6 @@ static int omap_aes_setkey(struct crypto_ablkcipher *tfm, const u8 *key, memcpy(ctx->key, key, keylen); ctx->keylen = keylen; - ctx->flags |= FLAGS_NEW_KEY; return 0; } -- cgit v1.2.3 From 83ea7e0fe1471508ab8e8d7b317e743fe7a05a5f Mon Sep 17 00:00:00 2001 From: Dmitry Kasatkin Date: Tue, 30 Nov 2010 10:13:31 +0200 Subject: crypto: omap-aes - initialize aes module once per request AES module was initialized for every DMA transaction. That is redundant. Now it is initialized once per request. Signed-off-by: Dmitry Kasatkin Signed-off-by: Herbert Xu --- drivers/crypto/omap-aes.c | 54 ++++++++++++++++++++++++----------------------- 1 file changed, 28 insertions(+), 26 deletions(-) diff --git a/drivers/crypto/omap-aes.c b/drivers/crypto/omap-aes.c index 0b21dcef0289..b69da4f07c89 100644 --- a/drivers/crypto/omap-aes.c +++ b/drivers/crypto/omap-aes.c @@ -176,6 +176,11 @@ static int omap_aes_wait(struct omap_aes_dev *dd, u32 offset, u32 bit) static int omap_aes_hw_init(struct omap_aes_dev *dd) { + /* + * clocks are enabled when request starts and disabled when finished. + * It may be long delays between requests. + * Device might go to off mode to save power. + */ clk_enable(dd->iclk); if (!(dd->flags & FLAGS_INIT)) { @@ -190,10 +195,9 @@ static int omap_aes_hw_init(struct omap_aes_dev *dd) __asm__ __volatile__("nop"); if (omap_aes_wait(dd, AES_REG_SYSSTATUS, - AES_REG_SYSSTATUS_RESETDONE)) { - clk_disable(dd->iclk); + AES_REG_SYSSTATUS_RESETDONE)) return -ETIMEDOUT; - } + dd->flags |= FLAGS_INIT; dd->err = 0; } @@ -243,9 +247,19 @@ static int omap_aes_write_ctrl(struct omap_aes_dev *dd) omap_aes_write_mask(dd, AES_REG_CTRL, val, mask); - /* start DMA or disable idle mode */ - omap_aes_write_mask(dd, AES_REG_MASK, AES_REG_MASK_START, - AES_REG_MASK_START); + /* IN */ + omap_set_dma_dest_params(dd->dma_lch_in, 0, OMAP_DMA_AMODE_CONSTANT, + dd->phys_base + AES_REG_DATA, 0, 4); + + omap_set_dma_dest_burst_mode(dd->dma_lch_in, OMAP_DMA_DATA_BURST_4); + omap_set_dma_src_burst_mode(dd->dma_lch_in, OMAP_DMA_DATA_BURST_4); + + /* OUT */ + omap_set_dma_src_params(dd->dma_lch_out, 0, OMAP_DMA_AMODE_CONSTANT, + dd->phys_base + AES_REG_DATA, 0, 4); + + omap_set_dma_src_burst_mode(dd->dma_lch_out, OMAP_DMA_DATA_BURST_4); + omap_set_dma_dest_burst_mode(dd->dma_lch_out, OMAP_DMA_DATA_BURST_4); return 0; } @@ -419,7 +433,6 @@ static int omap_aes_crypt_dma(struct crypto_tfm *tfm, dma_addr_t dma_addr_in, struct omap_aes_ctx *ctx = crypto_tfm_ctx(tfm); struct omap_aes_dev *dd = ctx->dd; int len32; - int err; pr_debug("len: %d\n", length); @@ -432,12 +445,6 @@ static int omap_aes_crypt_dma(struct crypto_tfm *tfm, dma_addr_t dma_addr_in, len32 = DIV_ROUND_UP(length, sizeof(u32)); /* IN */ - omap_set_dma_dest_params(dd->dma_lch_in, 0, OMAP_DMA_AMODE_CONSTANT, - dd->phys_base + AES_REG_DATA, 0, 4); - - omap_set_dma_dest_burst_mode(dd->dma_lch_in, OMAP_DMA_DATA_BURST_4); - omap_set_dma_src_burst_mode(dd->dma_lch_in, OMAP_DMA_DATA_BURST_4); - omap_set_dma_transfer_params(dd->dma_lch_in, OMAP_DMA_DATA_TYPE_S32, len32, 1, OMAP_DMA_SYNC_PACKET, dd->dma_in, OMAP_DMA_DST_SYNC); @@ -446,12 +453,6 @@ static int omap_aes_crypt_dma(struct crypto_tfm *tfm, dma_addr_t dma_addr_in, dma_addr_in, 0, 0); /* OUT */ - omap_set_dma_src_params(dd->dma_lch_out, 0, OMAP_DMA_AMODE_CONSTANT, - dd->phys_base + AES_REG_DATA, 0, 4); - - omap_set_dma_src_burst_mode(dd->dma_lch_out, OMAP_DMA_DATA_BURST_4); - omap_set_dma_dest_burst_mode(dd->dma_lch_out, OMAP_DMA_DATA_BURST_4); - omap_set_dma_transfer_params(dd->dma_lch_out, OMAP_DMA_DATA_TYPE_S32, len32, 1, OMAP_DMA_SYNC_PACKET, dd->dma_out, OMAP_DMA_SRC_SYNC); @@ -459,13 +460,13 @@ static int omap_aes_crypt_dma(struct crypto_tfm *tfm, dma_addr_t dma_addr_in, omap_set_dma_dest_params(dd->dma_lch_out, 0, OMAP_DMA_AMODE_POST_INC, dma_addr_out, 0, 0); - err = omap_aes_write_ctrl(dd); - if (err) - return err; - omap_start_dma(dd->dma_lch_in); omap_start_dma(dd->dma_lch_out); + /* start DMA or disable idle mode */ + omap_aes_write_mask(dd, AES_REG_MASK, AES_REG_MASK_START, + AES_REG_MASK_START); + return 0; } @@ -545,6 +546,7 @@ static void omap_aes_finish_req(struct omap_aes_dev *dd, int err) pr_debug("err: %d\n", err); + clk_disable(dd->iclk); dd->flags &= ~FLAGS_BUSY; req->base.complete(&req->base, err); @@ -562,8 +564,6 @@ static int omap_aes_crypt_dma_stop(struct omap_aes_dev *dd) omap_stop_dma(dd->dma_lch_in); omap_stop_dma(dd->dma_lch_out); - clk_disable(dd->iclk); - if (dd->flags & FLAGS_FAST) { dma_unmap_sg(dd->dev, dd->out_sg, 1, DMA_FROM_DEVICE); dma_unmap_sg(dd->dev, dd->in_sg, 1, DMA_TO_DEVICE); @@ -629,7 +629,9 @@ static int omap_aes_handle_queue(struct omap_aes_dev *dd, dd->ctx = ctx; ctx->dd = dd; - err = omap_aes_crypt_dma_start(dd); + err = omap_aes_write_ctrl(dd); + if (!err) + err = omap_aes_crypt_dma_start(dd); if (err) { /* aes_task will not finish it, so do it here */ omap_aes_finish_req(dd, err); -- cgit v1.2.3 From efce41b65f66251d60484781df305e8a85c9507b Mon Sep 17 00:00:00 2001 From: Dmitry Kasatkin Date: Tue, 30 Nov 2010 10:13:32 +0200 Subject: crypto: omap-aes - checkpatch --file warning fixes Signed-off-by: Dmitry Kasatkin Signed-off-by: Herbert Xu --- drivers/crypto/omap-aes.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/crypto/omap-aes.c b/drivers/crypto/omap-aes.c index b69da4f07c89..add2a1a72ba4 100644 --- a/drivers/crypto/omap-aes.c +++ b/drivers/crypto/omap-aes.c @@ -96,7 +96,7 @@ struct omap_aes_reqctx { struct omap_aes_dev { struct list_head list; unsigned long phys_base; - void __iomem *io_base; + void __iomem *io_base; struct clk *iclk; struct omap_aes_ctx *ctx; struct device *dev; @@ -759,7 +759,7 @@ static struct crypto_alg algs[] = { .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, .cra_blocksize = AES_BLOCK_SIZE, .cra_ctxsize = sizeof(struct omap_aes_ctx), - .cra_alignmask = 0, + .cra_alignmask = 0, .cra_type = &crypto_ablkcipher_type, .cra_module = THIS_MODULE, .cra_init = omap_aes_cra_init, @@ -779,7 +779,7 @@ static struct crypto_alg algs[] = { .cra_flags = CRYPTO_ALG_TYPE_ABLKCIPHER | CRYPTO_ALG_ASYNC, .cra_blocksize = AES_BLOCK_SIZE, .cra_ctxsize = sizeof(struct omap_aes_ctx), - .cra_alignmask = 0, + .cra_alignmask = 0, .cra_type = &crypto_ablkcipher_type, .cra_module = THIS_MODULE, .cra_init = omap_aes_cra_init, -- cgit v1.2.3 From 87ca9c8a7ea9c8c7ce1561edaad1aa8570f1a01e Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 2 Dec 2010 09:42:56 +0000 Subject: drm/i915: Prevent stalling for a GTT read back from a read-only GPU target Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_drv.h | 6 ++++++ drivers/gpu/drm/i915/i915_gem.c | 9 ++++++--- drivers/gpu/drm/i915/i915_gem_execbuffer.c | 1 + 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 590d8f2d0958..7b37c198cb19 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -728,6 +728,12 @@ struct drm_i915_gem_object { */ unsigned int dirty : 1; + /** + * This is set if the object has been written to since the last + * GPU flush. + */ + unsigned int pending_gpu_write : 1; + /** * Fence register bits (if any) for this object. Will be set * as needed when mapped into the GTT. diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index eae52de75a4c..c3e6d7bda6e1 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1643,6 +1643,7 @@ i915_gem_object_move_to_inactive(struct drm_i915_gem_object *obj) obj->last_fenced_ring = NULL; obj->active = 0; + obj->pending_gpu_write = false; drm_gem_object_unreference(&obj->base); WARN_ON(i915_verify_lists(dev)); @@ -2810,9 +2811,11 @@ i915_gem_object_set_to_gtt_domain(struct drm_i915_gem_object *obj, bool write) return -EINVAL; i915_gem_object_flush_gpu_write_domain(obj); - ret = i915_gem_object_wait_rendering(obj, true); - if (ret) - return ret; + if (obj->pending_gpu_write || write) { + ret = i915_gem_object_wait_rendering(obj, true); + if (ret) + return ret; + } i915_gem_object_flush_cpu_write_domain(obj); diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index f57536a70a3a..af01a58a643b 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c @@ -775,6 +775,7 @@ i915_gem_execbuffer_move_to_active(struct list_head *objects, i915_gem_object_move_to_active(obj, ring); if (obj->base.write_domain) { obj->dirty = 1; + obj->pending_gpu_write = true; list_move_tail(&obj->gpu_write_list, &ring->gpu_write_list); intel_mark_busy(ring->dev, obj); -- cgit v1.2.3 From d9e86c0ee60f323e890484628f351bf50fa9a15d Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 10 Nov 2010 16:40:20 +0000 Subject: drm/i915: Pipelined fencing [infrastructure] With this change, every batchbuffer can use all available fences (save pinned and scanout, of course) without ever stalling the gpu! In theory. Currently the actual pipelined update of the register is disabled due to some stability issues. However, just the deferred update is a significant win. Based on a series of patches by Daniel Vetter. The premise is that before every access to a buffer through the GTT we have to declare whether we need a register or not. If the access is by the GPU, a pipelined update to the register is made via the ringbuffer, and we track the last seqno of the batches that access it. If by the CPU we wait for the last GPU access and update the register (either to clear or to set it for the current buffer). One advantage of being able to pipeline changes is that we can defer the actual updating of the fence register until we first need to access the object through the GTT, i.e. we can eliminate the stall on set_tiling. This is important as the userspace bo cache does not track the tiling status of active buffers which generate frequent stalls on gen3 when enabling tiling for an already bound buffer. Signed-off-by: Chris Wilson Reviewed-by: Daniel Vetter --- drivers/gpu/drm/i915/i915_drv.h | 10 +- drivers/gpu/drm/i915/i915_gem.c | 360 ++++++++++++++++++----------- drivers/gpu/drm/i915/i915_gem_execbuffer.c | 20 +- drivers/gpu/drm/i915/i915_gem_tiling.c | 23 +- drivers/gpu/drm/i915/intel_display.c | 17 +- drivers/gpu/drm/i915/intel_overlay.c | 10 + 6 files changed, 274 insertions(+), 166 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 7b37c198cb19..af9ff40b135b 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -126,6 +126,7 @@ struct drm_i915_master_private { struct drm_i915_fence_reg { struct list_head lru_list; struct drm_i915_gem_object *obj; + uint32_t setup_seqno; }; struct sdvo_device_mapping { @@ -752,6 +753,7 @@ struct drm_i915_gem_object { * Current tiling mode for the object. */ unsigned int tiling_mode : 2; + unsigned int tiling_changed : 1; /** How many users have pinned this object in GTT space. The following * users can each hold at most one reference: pwrite/pread, pin_ioctl @@ -1121,10 +1123,10 @@ i915_gem_next_request_seqno(struct drm_device *dev, return ring->outstanding_lazy_request = dev_priv->next_seqno; } -int __must_check i915_gem_object_get_fence_reg(struct drm_i915_gem_object *obj, - bool interruptible); -int __must_check i915_gem_object_put_fence_reg(struct drm_i915_gem_object *obj, - bool interruptible); +int __must_check i915_gem_object_get_fence(struct drm_i915_gem_object *obj, + struct intel_ring_buffer *pipelined, + bool interruptible); +int __must_check i915_gem_object_put_fence(struct drm_i915_gem_object *obj); void i915_gem_retire_requests(struct drm_device *dev); void i915_gem_reset(struct drm_device *dev); diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index c3e6d7bda6e1..23d2417a3585 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -47,7 +47,8 @@ static void i915_gem_object_set_to_full_cpu_read_domain(struct drm_i915_gem_obje static int i915_gem_object_bind_to_gtt(struct drm_i915_gem_object *obj, unsigned alignment, bool map_and_fenceable); -static void i915_gem_clear_fence_reg(struct drm_i915_gem_object *obj); +static void i915_gem_clear_fence_reg(struct drm_device *dev, + struct drm_i915_fence_reg *reg); static int i915_gem_phys_pwrite(struct drm_device *dev, struct drm_i915_gem_object *obj, struct drm_i915_gem_pwrite *args, @@ -684,7 +685,11 @@ i915_gem_gtt_pwrite_slow(struct drm_device *dev, goto out_unpin_pages; } - ret = i915_gem_object_set_to_gtt_domain(obj, 1); + ret = i915_gem_object_set_to_gtt_domain(obj, true); + if (ret) + goto out_unpin_pages; + + ret = i915_gem_object_put_fence(obj); if (ret) goto out_unpin_pages; @@ -966,14 +971,17 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data, */ if (obj->phys_obj) ret = i915_gem_phys_pwrite(dev, obj, args, file); - else if (obj->tiling_mode == I915_TILING_NONE && - obj->gtt_space && + else if (obj->gtt_space && obj->base.write_domain != I915_GEM_DOMAIN_CPU) { ret = i915_gem_object_pin(obj, 0, true); if (ret) goto out; - ret = i915_gem_object_set_to_gtt_domain(obj, 1); + ret = i915_gem_object_set_to_gtt_domain(obj, true); + if (ret) + goto out_unpin; + + ret = i915_gem_object_put_fence(obj); if (ret) goto out_unpin; @@ -1205,12 +1213,12 @@ int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf) if (ret) goto unlock; - /* Need a new fence register? */ - if (obj->tiling_mode != I915_TILING_NONE) { - ret = i915_gem_object_get_fence_reg(obj, true); - if (ret) - goto unlock; - } + if (obj->tiling_mode == I915_TILING_NONE) + ret = i915_gem_object_put_fence(obj); + else + ret = i915_gem_object_get_fence(obj, NULL, true); + if (ret) + goto unlock; if (i915_gem_object_is_inactive(obj)) list_move_tail(&obj->mm_list, &dev_priv->mm.inactive_list); @@ -1608,7 +1616,6 @@ i915_gem_object_move_off_active(struct drm_i915_gem_object *obj) { list_del_init(&obj->ring_list); obj->last_rendering_seqno = 0; - obj->last_fenced_seqno = 0; } static void @@ -1640,7 +1647,6 @@ i915_gem_object_move_to_inactive(struct drm_i915_gem_object *obj) i915_gem_object_move_off_active(obj); obj->fenced_gpu_access = false; - obj->last_fenced_ring = NULL; obj->active = 0; obj->pending_gpu_write = false; @@ -1803,7 +1809,11 @@ static void i915_gem_reset_fences(struct drm_device *dev) if (obj->tiling_mode) i915_gem_release_mmap(obj); - i915_gem_clear_fence_reg(obj); + reg->obj->fence_reg = I915_FENCE_REG_NONE; + reg->obj->fenced_gpu_access = false; + reg->obj->last_fenced_seqno = 0; + reg->obj->last_fenced_ring = NULL; + i915_gem_clear_fence_reg(dev, reg); } } @@ -2114,8 +2124,9 @@ i915_gem_object_unbind(struct drm_i915_gem_object *obj) } /* release the fence reg _after_ flushing */ - if (obj->fence_reg != I915_FENCE_REG_NONE) - i915_gem_clear_fence_reg(obj); + ret = i915_gem_object_put_fence(obj); + if (ret == -ERESTARTSYS) + return ret; i915_gem_gtt_unbind_object(obj); i915_gem_object_put_pages_gtt(obj); @@ -2357,59 +2368,118 @@ static int i830_write_fence_reg(struct drm_i915_gem_object *obj, return 0; } -static int i915_find_fence_reg(struct drm_device *dev, - bool interruptible) +static bool ring_passed_seqno(struct intel_ring_buffer *ring, u32 seqno) +{ + return i915_seqno_passed(ring->get_seqno(ring), seqno); +} + +static int +i915_gem_object_flush_fence(struct drm_i915_gem_object *obj, + struct intel_ring_buffer *pipelined, + bool interruptible) +{ + int ret; + + if (obj->fenced_gpu_access) { + if (obj->base.write_domain & I915_GEM_GPU_DOMAINS) + i915_gem_flush_ring(obj->base.dev, + obj->last_fenced_ring, + 0, obj->base.write_domain); + + obj->fenced_gpu_access = false; + } + + if (obj->last_fenced_seqno && pipelined != obj->last_fenced_ring) { + if (!ring_passed_seqno(obj->last_fenced_ring, + obj->last_fenced_seqno)) { + ret = i915_do_wait_request(obj->base.dev, + obj->last_fenced_seqno, + interruptible, + obj->last_fenced_ring); + if (ret) + return ret; + } + + obj->last_fenced_seqno = 0; + obj->last_fenced_ring = NULL; + } + + return 0; +} + +int +i915_gem_object_put_fence(struct drm_i915_gem_object *obj) +{ + int ret; + + if (obj->tiling_mode) + i915_gem_release_mmap(obj); + + ret = i915_gem_object_flush_fence(obj, NULL, true); + if (ret) + return ret; + + if (obj->fence_reg != I915_FENCE_REG_NONE) { + struct drm_i915_private *dev_priv = obj->base.dev->dev_private; + i915_gem_clear_fence_reg(obj->base.dev, + &dev_priv->fence_regs[obj->fence_reg]); + + obj->fence_reg = I915_FENCE_REG_NONE; + } + + return 0; +} + +static struct drm_i915_fence_reg * +i915_find_fence_reg(struct drm_device *dev, + struct intel_ring_buffer *pipelined) { struct drm_i915_private *dev_priv = dev->dev_private; - struct drm_i915_fence_reg *reg; - struct drm_i915_gem_object *obj = NULL; - int i, avail, ret; + struct drm_i915_fence_reg *reg, *first, *avail; + int i; /* First try to find a free reg */ - avail = 0; + avail = NULL; for (i = dev_priv->fence_reg_start; i < dev_priv->num_fence_regs; i++) { reg = &dev_priv->fence_regs[i]; if (!reg->obj) - return i; + return reg; if (!reg->obj->pin_count) - avail++; + avail = reg; } - if (avail == 0) - return -ENOSPC; + if (avail == NULL) + return NULL; /* None available, try to steal one or wait for a user to finish */ - avail = I915_FENCE_REG_NONE; - list_for_each_entry(reg, &dev_priv->mm.fence_list, - lru_list) { - obj = reg->obj; - if (obj->pin_count) + avail = first = NULL; + list_for_each_entry(reg, &dev_priv->mm.fence_list, lru_list) { + if (reg->obj->pin_count) continue; - /* found one! */ - avail = obj->fence_reg; - break; - } + if (first == NULL) + first = reg; - BUG_ON(avail == I915_FENCE_REG_NONE); + if (!pipelined || + !reg->obj->last_fenced_ring || + reg->obj->last_fenced_ring == pipelined) { + avail = reg; + break; + } + } - /* We only have a reference on obj from the active list. put_fence_reg - * might drop that one, causing a use-after-free in it. So hold a - * private reference to obj like the other callers of put_fence_reg - * (set_tiling ioctl) do. */ - drm_gem_object_reference(&obj->base); - ret = i915_gem_object_put_fence_reg(obj, interruptible); - drm_gem_object_unreference(&obj->base); - if (ret != 0) - return ret; + if (avail == NULL) + avail = first; return avail; } /** - * i915_gem_object_get_fence_reg - set up a fence reg for an object + * i915_gem_object_get_fence - set up a fence reg for an object * @obj: object to map through a fence reg + * @pipelined: ring on which to queue the change, or NULL for CPU access + * @interruptible: must we wait uninterruptibly for the register to retire? * * When mapping objects through the GTT, userspace wants to be able to write * to them without having to worry about swizzling if the object is tiled. @@ -2421,52 +2491,119 @@ static int i915_find_fence_reg(struct drm_device *dev, * and tiling format. */ int -i915_gem_object_get_fence_reg(struct drm_i915_gem_object *obj, - bool interruptible) +i915_gem_object_get_fence(struct drm_i915_gem_object *obj, + struct intel_ring_buffer *pipelined, + bool interruptible) { struct drm_device *dev = obj->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct drm_i915_fence_reg *reg = NULL; - struct intel_ring_buffer *pipelined = NULL; + struct drm_i915_fence_reg *reg; int ret; - /* Just update our place in the LRU if our fence is getting used. */ + /* Just update our place in the LRU if our fence is getting reused. */ if (obj->fence_reg != I915_FENCE_REG_NONE) { reg = &dev_priv->fence_regs[obj->fence_reg]; list_move_tail(®->lru_list, &dev_priv->mm.fence_list); + + if (!obj->fenced_gpu_access && !obj->last_fenced_seqno) + pipelined = NULL; + + if (!pipelined) { + if (reg->setup_seqno) { + if (!ring_passed_seqno(obj->last_fenced_ring, + reg->setup_seqno)) { + ret = i915_do_wait_request(obj->base.dev, + reg->setup_seqno, + interruptible, + obj->last_fenced_ring); + if (ret) + return ret; + } + + reg->setup_seqno = 0; + } + } else if (obj->last_fenced_ring && + obj->last_fenced_ring != pipelined) { + ret = i915_gem_object_flush_fence(obj, + pipelined, + interruptible); + if (ret) + return ret; + } else if (obj->tiling_changed) { + if (obj->fenced_gpu_access) { + if (obj->base.write_domain & I915_GEM_GPU_DOMAINS) + i915_gem_flush_ring(obj->base.dev, obj->ring, + 0, obj->base.write_domain); + + obj->fenced_gpu_access = false; + } + } + + if (!obj->fenced_gpu_access && !obj->last_fenced_seqno) + pipelined = NULL; + BUG_ON(!pipelined && reg->setup_seqno); + + if (obj->tiling_changed) { + if (pipelined) { + reg->setup_seqno = + i915_gem_next_request_seqno(dev, pipelined); + obj->last_fenced_seqno = reg->setup_seqno; + obj->last_fenced_ring = pipelined; + } + goto update; + } + return 0; } - switch (obj->tiling_mode) { - case I915_TILING_NONE: - WARN(1, "allocating a fence for non-tiled object?\n"); - break; - case I915_TILING_X: - if (!obj->stride) - return -EINVAL; - WARN((obj->stride & (512 - 1)), - "object 0x%08x is X tiled but has non-512B pitch\n", - obj->gtt_offset); - break; - case I915_TILING_Y: - if (!obj->stride) - return -EINVAL; - WARN((obj->stride & (128 - 1)), - "object 0x%08x is Y tiled but has non-128B pitch\n", - obj->gtt_offset); - break; - } + reg = i915_find_fence_reg(dev, pipelined); + if (reg == NULL) + return -ENOSPC; - ret = i915_find_fence_reg(dev, interruptible); - if (ret < 0) + ret = i915_gem_object_flush_fence(obj, pipelined, interruptible); + if (ret) return ret; - obj->fence_reg = ret; - reg = &dev_priv->fence_regs[obj->fence_reg]; - list_add_tail(®->lru_list, &dev_priv->mm.fence_list); + if (reg->obj) { + struct drm_i915_gem_object *old = reg->obj; + + drm_gem_object_reference(&old->base); + + if (old->tiling_mode) + i915_gem_release_mmap(old); + + /* XXX The pipelined change over appears to be incoherent. */ + ret = i915_gem_object_flush_fence(old, + NULL, //pipelined, + interruptible); + if (ret) { + drm_gem_object_unreference(&old->base); + return ret; + } + + if (old->last_fenced_seqno == 0 && obj->last_fenced_seqno == 0) + pipelined = NULL; + + old->fence_reg = I915_FENCE_REG_NONE; + old->last_fenced_ring = pipelined; + old->last_fenced_seqno = + pipelined ? i915_gem_next_request_seqno(dev, pipelined) : 0; + + drm_gem_object_unreference(&old->base); + } else if (obj->last_fenced_seqno == 0) + pipelined = NULL; reg->obj = obj; + list_move_tail(®->lru_list, &dev_priv->mm.fence_list); + obj->fence_reg = reg - dev_priv->fence_regs; + obj->last_fenced_ring = pipelined; + reg->setup_seqno = + pipelined ? i915_gem_next_request_seqno(dev, pipelined) : 0; + obj->last_fenced_seqno = reg->setup_seqno; + +update: + obj->tiling_changed = false; switch (INTEL_INFO(dev)->gen) { case 6: ret = sandybridge_write_fence_reg(obj, pipelined); @@ -2497,87 +2634,34 @@ i915_gem_object_get_fence_reg(struct drm_i915_gem_object *obj, * data structures in dev_priv and obj. */ static void -i915_gem_clear_fence_reg(struct drm_i915_gem_object *obj) +i915_gem_clear_fence_reg(struct drm_device *dev, + struct drm_i915_fence_reg *reg) { - struct drm_device *dev = obj->base.dev; drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_i915_fence_reg *reg = &dev_priv->fence_regs[obj->fence_reg]; - uint32_t fence_reg; + uint32_t fence_reg = reg - dev_priv->fence_regs; switch (INTEL_INFO(dev)->gen) { case 6: - I915_WRITE64(FENCE_REG_SANDYBRIDGE_0 + - (obj->fence_reg * 8), 0); + I915_WRITE64(FENCE_REG_SANDYBRIDGE_0 + fence_reg*8, 0); break; case 5: case 4: - I915_WRITE64(FENCE_REG_965_0 + (obj->fence_reg * 8), 0); + I915_WRITE64(FENCE_REG_965_0 + fence_reg*8, 0); break; case 3: - if (obj->fence_reg >= 8) - fence_reg = FENCE_REG_945_8 + (obj->fence_reg - 8) * 4; + if (fence_reg >= 8) + fence_reg = FENCE_REG_945_8 + (fence_reg - 8) * 4; else case 2: - fence_reg = FENCE_REG_830_0 + obj->fence_reg * 4; + fence_reg = FENCE_REG_830_0 + fence_reg * 4; I915_WRITE(fence_reg, 0); break; } - reg->obj = NULL; - obj->fence_reg = I915_FENCE_REG_NONE; list_del_init(®->lru_list); -} - -/** - * i915_gem_object_put_fence_reg - waits on outstanding fenced access - * to the buffer to finish, and then resets the fence register. - * @obj: tiled object holding a fence register. - * @bool: whether the wait upon the fence is interruptible - * - * Zeroes out the fence register itself and clears out the associated - * data structures in dev_priv and obj. - */ -int -i915_gem_object_put_fence_reg(struct drm_i915_gem_object *obj, - bool interruptible) -{ - struct drm_device *dev = obj->base.dev; - int ret; - - if (obj->fence_reg == I915_FENCE_REG_NONE) - return 0; - - /* If we've changed tiling, GTT-mappings of the object - * need to re-fault to ensure that the correct fence register - * setup is in place. - */ - i915_gem_release_mmap(obj); - - /* On the i915, GPU access to tiled buffers is via a fence, - * therefore we must wait for any outstanding access to complete - * before clearing the fence. - */ - if (obj->fenced_gpu_access) { - i915_gem_object_flush_gpu_write_domain(obj); - obj->fenced_gpu_access = false; - } - - if (obj->last_fenced_seqno) { - ret = i915_do_wait_request(dev, - obj->last_fenced_seqno, - interruptible, - obj->last_fenced_ring); - if (ret) - return ret; - - obj->last_fenced_seqno = false; - } - - i915_gem_object_flush_gtt_write_domain(obj); - i915_gem_clear_fence_reg(obj); - - return 0; + reg->obj = NULL; + reg->setup_seqno = 0; } /** diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index af01a58a643b..9bdc495e17bb 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c @@ -424,7 +424,7 @@ i915_gem_execbuffer_relocate(struct drm_device *dev, } static int -i915_gem_execbuffer_reserve(struct drm_device *dev, +i915_gem_execbuffer_reserve(struct intel_ring_buffer *ring, struct drm_file *file, struct list_head *objects, struct drm_i915_gem_exec_object2 *exec) @@ -499,10 +499,15 @@ i915_gem_execbuffer_reserve(struct drm_device *dev, } if (need_fence) { - ret = i915_gem_object_get_fence_reg(obj, true); + ret = i915_gem_object_get_fence(obj, ring, 1); + if (ret) + break; + } else if (entry->flags & EXEC_OBJECT_NEEDS_FENCE && + obj->tiling_mode == I915_TILING_NONE) { + /* XXX pipelined! */ + ret = i915_gem_object_put_fence(obj); if (ret) break; - } obj->pending_fenced_gpu_access = need_fence; @@ -522,7 +527,7 @@ i915_gem_execbuffer_reserve(struct drm_device *dev, /* First attempt, just clear anything that is purgeable. * Second attempt, clear the entire GTT. */ - ret = i915_gem_evict_everything(dev, retry == 0); + ret = i915_gem_evict_everything(ring->dev, retry == 0); if (ret) return ret; @@ -548,6 +553,7 @@ err: static int i915_gem_execbuffer_relocate_slow(struct drm_device *dev, struct drm_file *file, + struct intel_ring_buffer *ring, struct list_head *objects, struct drm_i915_gem_exec_object2 *exec, int count) @@ -590,7 +596,7 @@ i915_gem_execbuffer_relocate_slow(struct drm_device *dev, goto err; } - ret = i915_gem_execbuffer_reserve(dev, file, objects, exec); + ret = i915_gem_execbuffer_reserve(ring, file, objects, exec); if (ret) goto err; @@ -930,7 +936,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, } /* Move the objects en-masse into the GTT, evicting if necessary. */ - ret = i915_gem_execbuffer_reserve(dev, file, &objects, exec); + ret = i915_gem_execbuffer_reserve(ring, file, &objects, exec); if (ret) goto err; @@ -938,7 +944,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, ret = i915_gem_execbuffer_relocate(dev, file, &objects, exec); if (ret) { if (ret == -EFAULT) { - ret = i915_gem_execbuffer_relocate_slow(dev, file, + ret = i915_gem_execbuffer_relocate_slow(dev, file, ring, &objects, exec, args->buffer_count); BUG_ON(!mutex_is_locked(&dev->struct_mutex)); diff --git a/drivers/gpu/drm/i915/i915_gem_tiling.c b/drivers/gpu/drm/i915/i915_gem_tiling.c index 1c5fdb30f272..22a32b9932c5 100644 --- a/drivers/gpu/drm/i915/i915_gem_tiling.c +++ b/drivers/gpu/drm/i915/i915_gem_tiling.c @@ -244,9 +244,6 @@ i915_gem_object_fence_ok(struct drm_i915_gem_object *obj, int tiling_mode) if (INTEL_INFO(obj->base.dev)->gen >= 4) return true; - if (!obj->gtt_space) - return true; - if (INTEL_INFO(obj->base.dev)->gen == 3) { if (obj->gtt_offset & ~I915_FENCE_START_MASK) return false; @@ -345,27 +342,21 @@ i915_gem_set_tiling(struct drm_device *dev, void *data, * tiling mode. Otherwise we can just leave it alone, but * need to ensure that any fence register is cleared. */ - if (!i915_gem_object_fence_ok(obj, args->tiling_mode)) - ret = i915_gem_object_unbind(obj); - else if (obj->fence_reg != I915_FENCE_REG_NONE) - ret = i915_gem_object_put_fence_reg(obj, true); - else - i915_gem_release_mmap(obj); + i915_gem_release_mmap(obj); - if (ret != 0) { - args->tiling_mode = obj->tiling_mode; - args->stride = obj->stride; - goto err; - } + obj->map_and_fenceable = + obj->gtt_space == NULL || + (obj->gtt_offset + obj->base.size <= dev_priv->mm.gtt_mappable_end && + i915_gem_object_fence_ok(obj, args->tiling_mode)); + obj->tiling_changed = true; obj->tiling_mode = args->tiling_mode; obj->stride = args->stride; } -err: drm_gem_object_unreference(&obj->base); mutex_unlock(&dev->struct_mutex); - return ret; + return 0; } /** diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index c2c94a26f92e..e141dd2e46e5 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -1474,7 +1474,7 @@ intel_pin_and_fence_fb_obj(struct drm_device *dev, * a fence as the cost is not that onerous. */ if (obj->tiling_mode != I915_TILING_NONE) { - ret = i915_gem_object_get_fence_reg(obj, false); + ret = i915_gem_object_get_fence(obj, pipelined, false); if (ret) goto err_unpin; } @@ -4370,6 +4370,12 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc, /* we only need to pin inside GTT if cursor is non-phy */ mutex_lock(&dev->struct_mutex); if (!dev_priv->info->cursor_needs_physical) { + if (obj->tiling_mode) { + DRM_ERROR("cursor cannot be tiled\n"); + ret = -EINVAL; + goto fail_locked; + } + ret = i915_gem_object_pin(obj, PAGE_SIZE, true); if (ret) { DRM_ERROR("failed to pin cursor bo\n"); @@ -4382,6 +4388,12 @@ static int intel_crtc_cursor_set(struct drm_crtc *crtc, goto fail_unpin; } + ret = i915_gem_object_put_fence(obj); + if (ret) { + DRM_ERROR("failed to move cursor bo into the GTT\n"); + goto fail_unpin; + } + addr = obj->gtt_offset; } else { int align = IS_I830(dev) ? 16 * 1024 : 256; @@ -4966,6 +4978,7 @@ static void intel_unpin_work_fn(struct work_struct *__work) i915_gem_object_unpin(work->old_fb_obj); drm_gem_object_unreference(&work->pending_flip_obj->base); drm_gem_object_unreference(&work->old_fb_obj->base); + mutex_unlock(&work->dev->struct_mutex); kfree(work); } @@ -5009,10 +5022,12 @@ static void do_intel_finish_page_flip(struct drm_device *dev, spin_unlock_irqrestore(&dev->event_lock, flags); obj = work->old_fb_obj; + atomic_clear_mask(1 << intel_crtc->plane, &obj->pending_flip.counter); if (atomic_read(&obj->pending_flip) == 0) wake_up(&dev_priv->pending_flip_queue); + schedule_work(&work->work); trace_i915_flip_complete(intel_crtc->plane, work->pending_flip_obj); diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c index af715cc03ee0..d0c1add393a3 100644 --- a/drivers/gpu/drm/i915/intel_overlay.c +++ b/drivers/gpu/drm/i915/intel_overlay.c @@ -787,6 +787,10 @@ static int intel_overlay_do_put_image(struct intel_overlay *overlay, if (ret != 0) goto out_unpin; + ret = i915_gem_object_put_fence(new_bo); + if (ret) + goto out_unpin; + if (!overlay->active) { regs = intel_overlay_map_regs(overlay); if (!regs) { @@ -1161,6 +1165,12 @@ int intel_overlay_put_image(struct drm_device *dev, void *data, mutex_lock(&dev->mode_config.mutex); mutex_lock(&dev->struct_mutex); + if (new_bo->tiling_mode) { + DRM_ERROR("buffer used for overlay image can not be tiled\n"); + ret = -EINVAL; + goto out_unlock; + } + ret = intel_overlay_recover_from_interrupt(overlay, true); if (ret != 0) goto out_unlock; -- cgit v1.2.3 From c6748e09eed072be077fe583976516b76daf42ec Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 12 Nov 2010 16:02:21 +0000 Subject: drm/i915: Remove inactive LRU tracking from set_domain_ioctl As the userspace mappings are torn down on every GPU write, we prefer to track when the buffer is activated (via a fresh i915_gem_fault). This makes the LRU conceptually simpler. With coherent mappings, the remaining use-case for set_domain_ioctl is GPU synchronisation. Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_gem.c | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 23d2417a3585..9e036010e3fc 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1018,7 +1018,6 @@ int i915_gem_set_domain_ioctl(struct drm_device *dev, void *data, struct drm_file *file) { - struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_gem_set_domain *args = data; struct drm_i915_gem_object *obj; uint32_t read_domains = args->read_domains; @@ -1051,21 +1050,9 @@ i915_gem_set_domain_ioctl(struct drm_device *dev, void *data, goto unlock; } - intel_mark_busy(dev, obj); - if (read_domains & I915_GEM_DOMAIN_GTT) { ret = i915_gem_object_set_to_gtt_domain(obj, write_domain != 0); - /* Update the LRU on the fence for the CPU access that's - * about to occur. - */ - if (obj->fence_reg != I915_FENCE_REG_NONE) { - struct drm_i915_fence_reg *reg = - &dev_priv->fence_regs[obj->fence_reg]; - list_move_tail(®->lru_list, - &dev_priv->mm.fence_list); - } - /* Silently promote "you're not bound, there was nothing to do" * to success, since the client was just asking us to * make sure everything was done. @@ -1076,10 +1063,6 @@ i915_gem_set_domain_ioctl(struct drm_device *dev, void *data, ret = i915_gem_object_set_to_cpu_domain(obj, write_domain != 0); } - /* Maintain LRU order of "inactive" objects */ - if (ret == 0 && i915_gem_object_is_inactive(obj)) - list_move_tail(&obj->mm_list, &dev_priv->mm.inactive_list); - drm_gem_object_unreference(&obj->base); unlock: mutex_unlock(&dev->struct_mutex); -- cgit v1.2.3 From 60de2ba51eaba9eefcc355cb20c8582b1481e755 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 12 Nov 2010 15:53:11 +0000 Subject: drm/i915: Kill the get_fence tracepoint As the tracepoint is now decoupled from when the actual register is assigned and was never complemented by detailing when the object lost its fence, it has outlived its limited usefulness. Profiling the actual stalls is a far more profitable venture anyway. Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_gem.c | 3 --- drivers/gpu/drm/i915/i915_trace.h | 22 ---------------------- 2 files changed, 25 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 9e036010e3fc..d99212fe54ed 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -2603,9 +2603,6 @@ update: break; } - trace_i915_gem_object_get_fence(obj, - obj->fence_reg, - obj->tiling_mode); return ret; } diff --git a/drivers/gpu/drm/i915/i915_trace.h b/drivers/gpu/drm/i915/i915_trace.h index 1df7262ae077..7f0fc3ed61aa 100644 --- a/drivers/gpu/drm/i915/i915_trace.h +++ b/drivers/gpu/drm/i915/i915_trace.h @@ -80,28 +80,6 @@ TRACE_EVENT(i915_gem_object_change_domain, __entry->read_domains, __entry->write_domain) ); -TRACE_EVENT(i915_gem_object_get_fence, - - TP_PROTO(struct drm_i915_gem_object *obj, int fence, int tiling_mode), - - TP_ARGS(obj, fence, tiling_mode), - - TP_STRUCT__entry( - __field(struct drm_i915_gem_object *, obj) - __field(int, fence) - __field(int, tiling_mode) - ), - - TP_fast_assign( - __entry->obj = obj; - __entry->fence = fence; - __entry->tiling_mode = tiling_mode; - ), - - TP_printk("obj=%p, fence=%d, tiling=%d", - __entry->obj, __entry->fence, __entry->tiling_mode) -); - DECLARE_EVENT_CLASS(i915_gem_object, TP_PROTO(struct drm_i915_gem_object *obj), -- cgit v1.2.3 From a44a11e9a049b491445bfbd93969d23c49047714 Mon Sep 17 00:00:00 2001 From: Arnaud Lacombe Date: Thu, 4 Nov 2010 00:16:08 -0400 Subject: kconfig: the day kconfig warns about "select"-abuse has come CC: catalin.marinas@arm.com Signed-off-by: Arnaud Lacombe Signed-off-by: Michal Marek --- Documentation/kbuild/kconfig-language.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/Documentation/kbuild/kconfig-language.txt b/Documentation/kbuild/kconfig-language.txt index 2fe93ca7c77c..5b9b1be6fde2 100644 --- a/Documentation/kbuild/kconfig-language.txt +++ b/Documentation/kbuild/kconfig-language.txt @@ -112,7 +112,6 @@ applicable everywhere (see syntax). (no prompts anywhere) and for symbols with no dependencies. That will limit the usefulness but on the other hand avoid the illegal configurations all over. - kconfig should one day warn about such things. - numerical ranges: "range" ["if" ] This allows to limit the range of possible input values for int -- cgit v1.2.3 From 0a18a9386c056028799938960f91be338c4ff349 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Thu, 4 Nov 2010 10:24:16 +0100 Subject: tags: put function prototypes back! MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Commit 7db86dc (ctags: usability fix) removed function prototypes from tags file claiming "It makes no real sense to include function prototypes". But it is useful for quickly determining which header file developer needs to include to fix compilation. Now if someone wants to remove forward declarations (which I agree are baggage), write a postprocessing script. Signed-off-by: Alexey Dobriyan Signed-off-by: Uwe Kleine-König Signed-off-by: Michal Marek --- scripts/tags.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/tags.sh b/scripts/tags.sh index 8509bb512935..e091db312ddb 100755 --- a/scripts/tags.sh +++ b/scripts/tags.sh @@ -123,7 +123,7 @@ exuberant() -I ____cacheline_internodealigned_in_smp \ -I EXPORT_SYMBOL,EXPORT_SYMBOL_GPL \ -I DEFINE_TRACE,EXPORT_TRACEPOINT_SYMBOL,EXPORT_TRACEPOINT_SYMBOL_GPL \ - --extra=+f --c-kinds=-px \ + --extra=+f --c-kinds=+px \ --regex-asm='/^ENTRY\(([^)]*)\).*/\1/' \ --regex-c='/^SYSCALL_DEFINE[[:digit:]]?\(([^,)]*).*/sys_\1/' -- cgit v1.2.3 From 39646871a47fd8808c08de0ce7d7ca8393af2805 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Thu, 2 Dec 2010 09:29:56 +0200 Subject: ASoC: tpa6130a2: Replace DAPM code with direct interface The use of DAPM widgets, and extra routing can cause ordering problems in the system. Machine drivers should use the exported direct interface with SND_SOC_DAPM_HP's event callback to manage the state of the amplifier. Signed-off-by: Peter Ujfalusi Acked-by: Mark Brown Signed-off-by: Liam Girdwood --- sound/soc/codecs/tpa6130a2.c | 69 +++++++------------------------------------- sound/soc/codecs/tpa6130a2.h | 1 + 2 files changed, 12 insertions(+), 58 deletions(-) diff --git a/sound/soc/codecs/tpa6130a2.c b/sound/soc/codecs/tpa6130a2.c index c97badfac540..0a99f313e218 100644 --- a/sound/soc/codecs/tpa6130a2.c +++ b/sound/soc/codecs/tpa6130a2.c @@ -317,65 +317,24 @@ static void tpa6130a2_channel_enable(u8 channel, int enable) } } -static int tpa6130a2_pga_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) -{ - switch (event) { - case SND_SOC_DAPM_POST_PMU: - tpa6130a2_channel_enable(w->shift, 1); - break; - case SND_SOC_DAPM_POST_PMD: - tpa6130a2_channel_enable(w->shift, 0); - break; - } - return 0; -} - -static int tpa6130a2_supply_event(struct snd_soc_dapm_widget *w, - struct snd_kcontrol *kcontrol, int event) +int tpa6130a2_stereo_enable(struct snd_soc_codec *codec, int enable) { int ret = 0; - - switch (event) { - case SND_SOC_DAPM_POST_PMU: + if (enable) { ret = tpa6130a2_power(1); - break; - case SND_SOC_DAPM_POST_PMD: + if (ret < 0) + return ret; + tpa6130a2_channel_enable(TPA6130A2_HP_EN_R | TPA6130A2_HP_EN_L, + 1); + } else { + tpa6130a2_channel_enable(TPA6130A2_HP_EN_R | TPA6130A2_HP_EN_L, + 0); ret = tpa6130a2_power(0); - break; } + return ret; } - -static const struct snd_soc_dapm_widget tpa6130a2_dapm_widgets[] = { - SND_SOC_DAPM_PGA_E("TPA6130A2 Left", SND_SOC_NOPM, - TPA6130A2_HP_EN_L, 0, NULL, 0, tpa6130a2_pga_event, - SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_PGA_E("TPA6130A2 Right", SND_SOC_NOPM, - TPA6130A2_HP_EN_R, 0, NULL, 0, tpa6130a2_pga_event, - SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_PGA_E("TPA6130A2 Stereo", SND_SOC_NOPM, - TPA6130A2_HP_EN_L | TPA6130A2_HP_EN_R, 0, NULL, 0, - tpa6130a2_pga_event, - SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_SUPPLY("TPA6130A2 Enable", SND_SOC_NOPM, - 0, 0, tpa6130a2_supply_event, - SND_SOC_DAPM_POST_PMU|SND_SOC_DAPM_POST_PMD), - /* Outputs */ - SND_SOC_DAPM_OUTPUT("TPA6130A2 Headphone Left"), - SND_SOC_DAPM_OUTPUT("TPA6130A2 Headphone Right"), - SND_SOC_DAPM_OUTPUT("TPA6130A2 Headphone Stereo"), -}; - -static const struct snd_soc_dapm_route audio_map[] = { - {"TPA6130A2 Headphone Left", NULL, "TPA6130A2 Left"}, - {"TPA6130A2 Headphone Right", NULL, "TPA6130A2 Right"}, - {"TPA6130A2 Headphone Stereo", NULL, "TPA6130A2 Stereo"}, - - {"TPA6130A2 Headphone Left", NULL, "TPA6130A2 Enable"}, - {"TPA6130A2 Headphone Right", NULL, "TPA6130A2 Enable"}, - {"TPA6130A2 Headphone Stereo", NULL, "TPA6130A2 Enable"}, -}; +EXPORT_SYMBOL_GPL(tpa6130a2_stereo_enable); int tpa6130a2_add_controls(struct snd_soc_codec *codec) { @@ -387,18 +346,12 @@ int tpa6130a2_add_controls(struct snd_soc_codec *codec) data = i2c_get_clientdata(tpa6130a2_client); - snd_soc_dapm_new_controls(dapm, tpa6130a2_dapm_widgets, - ARRAY_SIZE(tpa6130a2_dapm_widgets)); - - snd_soc_dapm_add_routes(dapm, audio_map, ARRAY_SIZE(audio_map)); - if (data->id == TPA6140A2) return snd_soc_add_controls(codec, tpa6140a2_controls, ARRAY_SIZE(tpa6140a2_controls)); else return snd_soc_add_controls(codec, tpa6130a2_controls, ARRAY_SIZE(tpa6130a2_controls)); - } EXPORT_SYMBOL_GPL(tpa6130a2_add_controls); diff --git a/sound/soc/codecs/tpa6130a2.h b/sound/soc/codecs/tpa6130a2.h index 57e867fd86d1..5df49c8756b2 100644 --- a/sound/soc/codecs/tpa6130a2.h +++ b/sound/soc/codecs/tpa6130a2.h @@ -57,5 +57,6 @@ #define TPA6130A2_VERSION_MASK (0x0f) extern int tpa6130a2_add_controls(struct snd_soc_codec *codec); +extern int tpa6130a2_stereo_enable(struct snd_soc_codec *codec, int enable); #endif /* __TPA6130A2_H__ */ -- cgit v1.2.3 From fbe609e41b48f2e7da7c053ca835ba1277d3bed2 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Wed, 1 Dec 2010 14:38:24 +0800 Subject: ASoC: Remove unused aic3x_i2c_init and aic3x_i2c_exit functions Signed-off-by: Axel Lin Acked-by: Mark Brown Acked-by: Jarkko Nikula Signed-off-by: Liam Girdwood --- sound/soc/codecs/tlv320aic3x.c | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c index fc5abdf0bcb0..8cd4cf5c44dc 100644 --- a/sound/soc/codecs/tlv320aic3x.c +++ b/sound/soc/codecs/tlv320aic3x.c @@ -1545,21 +1545,6 @@ static struct i2c_driver aic3x_i2c_driver = { .remove = aic3x_i2c_remove, .id_table = aic3x_i2c_id, }; - -static inline void aic3x_i2c_init(void) -{ - int ret; - - ret = i2c_add_driver(&aic3x_i2c_driver); - if (ret) - printk(KERN_ERR "%s: error regsitering i2c driver, %d\n", - __func__, ret); -} - -static inline void aic3x_i2c_exit(void) -{ - i2c_del_driver(&aic3x_i2c_driver); -} #endif static int __init aic3x_modinit(void) -- cgit v1.2.3 From d921184e82e828e9c0bc3958f838decaaa9191a8 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 30 Nov 2010 21:03:09 +0000 Subject: ASoC: Provide WM8731 microphone boost TLV information Signed-off-by: Mark Brown Acked-by: Liam Girdwood --- sound/soc/codecs/wm8731.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sound/soc/codecs/wm8731.c b/sound/soc/codecs/wm8731.c index 94e0cf3a66a1..c90e0252972f 100644 --- a/sound/soc/codecs/wm8731.c +++ b/sound/soc/codecs/wm8731.c @@ -74,6 +74,7 @@ static const struct soc_enum wm8731_enum[] = { static const DECLARE_TLV_DB_SCALE(in_tlv, -3450, 150, 0); static const DECLARE_TLV_DB_SCALE(sidetone_tlv, -1500, 300, 0); static const DECLARE_TLV_DB_SCALE(out_tlv, -12100, 100, 1); +static const DECLARE_TLV_DB_SCALE(mic_tlv, 0, 2000, 0); static const struct snd_kcontrol_new wm8731_snd_controls[] = { @@ -86,7 +87,7 @@ SOC_DOUBLE_R_TLV("Capture Volume", WM8731_LINVOL, WM8731_RINVOL, 0, 31, 0, in_tlv), SOC_DOUBLE_R("Line Capture Switch", WM8731_LINVOL, WM8731_RINVOL, 7, 1, 1), -SOC_SINGLE("Mic Boost (+20dB)", WM8731_APANA, 0, 1, 0), +SOC_SINGLE_TLV("Mic Boost Volume", WM8731_APANA, 0, 1, 0, mic_tlv), SOC_SINGLE("Mic Capture Switch", WM8731_APANA, 1, 1, 1), SOC_SINGLE_TLV("Sidetone Playback Volume", WM8731_APANA, 6, 3, 1, -- cgit v1.2.3 From 59f7297014b7e96779493f132eed04a3d44565df Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 30 Nov 2010 21:03:44 +0000 Subject: ASoC: Split WM8731 enumeration array into individual enums This is much more maintainable than the array. Signed-off-by: Mark Brown Acked-by: Liam Girdwood --- sound/soc/codecs/wm8731.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/sound/soc/codecs/wm8731.c b/sound/soc/codecs/wm8731.c index c90e0252972f..8003761a8e02 100644 --- a/sound/soc/codecs/wm8731.c +++ b/sound/soc/codecs/wm8731.c @@ -64,12 +64,15 @@ static const u16 wm8731_reg[WM8731_CACHEREGNUM] = { #define wm8731_reset(c) snd_soc_write(c, WM8731_RESET, 0) static const char *wm8731_input_select[] = {"Line In", "Mic"}; + static const char *wm8731_deemph[] = {"None", "32Khz", "44.1Khz", "48Khz"}; -static const struct soc_enum wm8731_enum[] = { - SOC_ENUM_SINGLE(WM8731_APANA, 2, 2, wm8731_input_select), - SOC_ENUM_SINGLE(WM8731_APDIGI, 1, 4, wm8731_deemph), -}; +static const struct soc_enum wm8731_insel_enum = + SOC_ENUM_SINGLE(WM8731_APANA, 2, 2, wm8731_input_select); + +static const struct soc_enum wm8731_deemph_enum = + SOC_ENUM_SINGLE(WM8731_APDIGI, 1, 4, wm8731_deemph); + static const DECLARE_TLV_DB_SCALE(in_tlv, -3450, 150, 0); static const DECLARE_TLV_DB_SCALE(sidetone_tlv, -1500, 300, 0); @@ -96,7 +99,7 @@ SOC_SINGLE_TLV("Sidetone Playback Volume", WM8731_APANA, 6, 3, 1, SOC_SINGLE("ADC High Pass Filter Switch", WM8731_APDIGI, 0, 1, 1), SOC_SINGLE("Store DC Offset Switch", WM8731_APDIGI, 4, 1, 0), -SOC_ENUM("Playback De-emphasis", wm8731_enum[1]), +SOC_ENUM("Playback De-emphasis", wm8731_deemph_enum), }; /* Output Mixer */ @@ -108,7 +111,7 @@ SOC_DAPM_SINGLE("HiFi Playback Switch", WM8731_APANA, 4, 1, 0), /* Input mux */ static const struct snd_kcontrol_new wm8731_input_mux_controls = -SOC_DAPM_ENUM("Input Select", wm8731_enum[0]); +SOC_DAPM_ENUM("Input Select", wm8731_insel_enum); static const struct snd_soc_dapm_widget wm8731_dapm_widgets[] = { SND_SOC_DAPM_SUPPLY("OSC", WM8731_PWR, 5, 1, NULL, 0), -- cgit v1.2.3 From dd31b310b9104327fb6bf7d2fe3b0f0f6fde4dd7 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 2 Dec 2010 11:44:00 +0000 Subject: ASoC: Automatically manage WM8731 deemphasis The deemphasis filter should be selected based on sample rate for optimal performance. Signed-off-by: Mark Brown Acked-by: Liam Girdwood --- sound/soc/codecs/wm8731.c | 76 +++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 71 insertions(+), 5 deletions(-) diff --git a/sound/soc/codecs/wm8731.c b/sound/soc/codecs/wm8731.c index 8003761a8e02..71122dc36826 100644 --- a/sound/soc/codecs/wm8731.c +++ b/sound/soc/codecs/wm8731.c @@ -46,6 +46,8 @@ struct wm8731_priv { u16 reg_cache[WM8731_CACHEREGNUM]; unsigned int sysclk; int sysclk_type; + int playback_fs; + bool deemph; }; @@ -65,14 +67,73 @@ static const u16 wm8731_reg[WM8731_CACHEREGNUM] = { static const char *wm8731_input_select[] = {"Line In", "Mic"}; -static const char *wm8731_deemph[] = {"None", "32Khz", "44.1Khz", "48Khz"}; - static const struct soc_enum wm8731_insel_enum = SOC_ENUM_SINGLE(WM8731_APANA, 2, 2, wm8731_input_select); -static const struct soc_enum wm8731_deemph_enum = - SOC_ENUM_SINGLE(WM8731_APDIGI, 1, 4, wm8731_deemph); +static int wm8731_deemph[] = { 0, 32000, 44100, 48000 }; + +static int wm8731_set_deemph(struct snd_soc_codec *codec) +{ + struct wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec); + int val, i, best; + + /* If we're using deemphasis select the nearest available sample + * rate. + */ + if (wm8731->deemph) { + best = 1; + for (i = 2; i < ARRAY_SIZE(wm8731_deemph); i++) { + if (abs(wm8731_deemph[i] - wm8731->playback_fs) < + abs(wm8731_deemph[best] - wm8731->playback_fs)) + best = i; + } + + val = best << 1; + } else { + best = 0; + val = 0; + } + + dev_dbg(codec->dev, "Set deemphasis %d (%dHz)\n", + best, wm8731_deemph[best]); + return snd_soc_update_bits(codec, WM8731_APDIGI, 0x6, val); +} + +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 wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec); + + ucontrol->value.enumerated.item[0] = wm8731->deemph; + + return 0; +} + +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 wm8731_priv *wm8731 = snd_soc_codec_get_drvdata(codec); + int deemph = ucontrol->value.enumerated.item[0]; + int ret = 0; + + if (deemph > 1) + return -EINVAL; + + mutex_lock(&codec->mutex); + if (wm8731->deemph != deemph) { + wm8731->deemph = deemph; + + wm8731_set_deemph(codec); + + ret = 1; + } + mutex_unlock(&codec->mutex); + + return ret; +} static const DECLARE_TLV_DB_SCALE(in_tlv, -3450, 150, 0); static const DECLARE_TLV_DB_SCALE(sidetone_tlv, -1500, 300, 0); @@ -99,7 +160,8 @@ SOC_SINGLE_TLV("Sidetone Playback Volume", WM8731_APANA, 6, 3, 1, SOC_SINGLE("ADC High Pass Filter Switch", WM8731_APDIGI, 0, 1, 1), SOC_SINGLE("Store DC Offset Switch", WM8731_APDIGI, 4, 1, 0), -SOC_ENUM("Playback De-emphasis", wm8731_deemph_enum), +SOC_SINGLE_BOOL_EXT("Playback Deemphasis Switch", 0, + wm8731_get_deemph, wm8731_put_deemph), }; /* Output Mixer */ @@ -243,6 +305,8 @@ static int wm8731_hw_params(struct snd_pcm_substream *substream, u16 srate = (coeff_div[i].sr << 2) | (coeff_div[i].bosr << 1) | coeff_div[i].usb; + wm8731->playback_fs = params_rate(params); + snd_soc_write(codec, WM8731_SRATE, srate); /* bit size */ @@ -257,6 +321,8 @@ static int wm8731_hw_params(struct snd_pcm_substream *substream, break; } + wm8731_set_deemph(codec); + snd_soc_write(codec, WM8731_IFACE, iface); return 0; } -- cgit v1.2.3 From 8bc3c2c207dc82d47ffc6ef7b788e04ea637d3f1 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 30 Nov 2010 14:56:18 +0000 Subject: ASoC: Tune performance of WM8958 revision A Update some of the default configuration for the device to improve the performance. Signed-off-by: Mark Brown Acked-by: Liam Girdwood --- include/linux/mfd/wm8994/registers.h | 9 +++++++++ sound/soc/codecs/wm8994.c | 36 +++++++++++++++++++++++++++--------- 2 files changed, 36 insertions(+), 9 deletions(-) diff --git a/include/linux/mfd/wm8994/registers.h b/include/linux/mfd/wm8994/registers.h index ccf3a774fe36..be072faec6f0 100644 --- a/include/linux/mfd/wm8994/registers.h +++ b/include/linux/mfd/wm8994/registers.h @@ -64,6 +64,7 @@ #define WM8994_LDO_1 0x3B #define WM8994_LDO_2 0x3C #define WM8994_CHARGE_PUMP_1 0x4C +#define WM8958_CHARGE_PUMP_2 0x4D #define WM8994_CLASS_W_1 0x51 #define WM8994_DC_SERVO_1 0x54 #define WM8994_DC_SERVO_2 0x55 @@ -1925,6 +1926,14 @@ #define WM8994_CP_ENA_SHIFT 15 /* CP_ENA */ #define WM8994_CP_ENA_WIDTH 1 /* CP_ENA */ +/* + * R77 (0x4D) - Charge Pump (2) + */ +#define WM8958_CP_DISCH 0x8000 /* CP_DISCH */ +#define WM8958_CP_DISCH_MASK 0x8000 /* CP_DISCH */ +#define WM8958_CP_DISCH_SHIFT 15 /* CP_DISCH */ +#define WM8958_CP_DISCH_WIDTH 1 /* CP_DISCH */ + /* * R81 (0x51) - Class W (1) */ diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index 59d361145b15..af3a98ae0579 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c @@ -1858,15 +1858,33 @@ static int wm8994_set_bias_level(struct snd_soc_codec *codec, if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { pm_runtime_get_sync(codec->dev); - /* Tweak DC servo and DSP configuration for - * improved performance. */ - if (control->type == WM8994 && wm8994->revision < 4) { - /* Tweak DC servo and DSP configuration for - * improved performance. */ - snd_soc_write(codec, 0x102, 0x3); - snd_soc_write(codec, 0x56, 0x3); - snd_soc_write(codec, 0x817, 0); - snd_soc_write(codec, 0x102, 0); + switch (control->type) { + case WM8994: + if (wm8994->revision < 4) { + /* Tweak DC servo and DSP + * configuration for improved + * performance. */ + snd_soc_write(codec, 0x102, 0x3); + snd_soc_write(codec, 0x56, 0x3); + snd_soc_write(codec, 0x817, 0); + snd_soc_write(codec, 0x102, 0); + } + break; + + case WM8958: + if (wm8994->revision == 0) { + /* Optimise performance for rev A */ + snd_soc_write(codec, 0x102, 0x3); + snd_soc_write(codec, 0xcb, 0x81); + snd_soc_write(codec, 0x817, 0); + snd_soc_write(codec, 0x102, 0); + + snd_soc_update_bits(codec, + WM8958_CHARGE_PUMP_2, + WM8958_CP_DISCH, + WM8958_CP_DISCH); + } + break; } /* Discharge LINEOUT1 & 2 */ -- cgit v1.2.3 From 43f901fbc8ba94bfa8d58155ba9378d7a13af636 Mon Sep 17 00:00:00 2001 From: Thomas Chou Date: Wed, 6 Oct 2010 15:13:53 +0800 Subject: gen_init_cpio: remove leading `/' from file names When we extracted the generated cpio archive using "cpio -id" command, it complained, cpio: Removing leading `/' from member names var/run cpio: Removing leading `/' from member names var/lib cpio: Removing leading `/' from member names var/lib/misc It is worse with the latest "cpio" or "pax", which tries to overwrite the host file system with the leading '/'. So the leading '/' of file names should be removed. This is consistent with the initramfs come with major distributions such as Fedora or Debian, etc. Signed-off-by: Thomas Chou Acked-by: Mike Frysinger Signed-off-by: Michal Marek --- usr/gen_init_cpio.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/usr/gen_init_cpio.c b/usr/gen_init_cpio.c index b2b3c2d1cf8b..59df70d9d1dc 100644 --- a/usr/gen_init_cpio.c +++ b/usr/gen_init_cpio.c @@ -104,6 +104,8 @@ static int cpio_mkslink(const char *name, const char *target, char s[256]; time_t mtime = time(NULL); + if (name[0] == '/') + name++; sprintf(s,"%s%08X%08X%08lX%08lX%08X%08lX" "%08X%08X%08X%08X%08X%08X%08X", "070701", /* magic */ @@ -152,6 +154,8 @@ static int cpio_mkgeneric(const char *name, unsigned int mode, char s[256]; time_t mtime = time(NULL); + if (name[0] == '/') + name++; sprintf(s,"%s%08X%08X%08lX%08lX%08X%08lX" "%08X%08X%08X%08X%08X%08X%08X", "070701", /* magic */ @@ -245,6 +249,8 @@ static int cpio_mknod(const char *name, unsigned int mode, else mode |= S_IFCHR; + if (name[0] == '/') + name++; sprintf(s,"%s%08X%08X%08lX%08lX%08X%08lX" "%08X%08X%08X%08X%08X%08X%08X", "070701", /* magic */ @@ -332,6 +338,8 @@ static int cpio_mkfile(const char *name, const char *location, /* data goes on last link */ if (i == nlinks) size = buf.st_size; + if (name[0] == '/') + name++; namesize = strlen(name) + 1; sprintf(s,"%s%08X%08X%08lX%08lX%08X%08lX" "%08lX%08X%08X%08X%08X%08X%08X", -- cgit v1.2.3 From 89733aa9cca016a542dc621d147a32d6b0fcdad5 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 2 Dec 2010 08:22:41 -0800 Subject: Staging: hv: remove OnChildDeviceCreate vmbus_driver callback It's only ever set to one function, so just call that function instead. Cc: Haiyang Zhang Cc: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/channel_mgmt.c | 2 +- drivers/staging/hv/vmbus.c | 13 ------------- drivers/staging/hv/vmbus_api.h | 3 --- drivers/staging/hv/vmbus_drv.c | 10 +++------- drivers/staging/hv/vmbus_private.h | 2 +- 5 files changed, 5 insertions(+), 25 deletions(-) diff --git a/drivers/staging/hv/channel_mgmt.c b/drivers/staging/hv/channel_mgmt.c index ae830f2e4e3a..3105fd1afe7d 100644 --- a/drivers/staging/hv/channel_mgmt.c +++ b/drivers/staging/hv/channel_mgmt.c @@ -355,7 +355,7 @@ static void vmbus_process_offer(void *context) * We need to set the DeviceObject field before calling * VmbusChildDeviceAdd() */ - newchannel->device_obj = VmbusChildDeviceCreate( + newchannel->device_obj = vmbus_child_device_create( &newchannel->offermsg.offer.InterfaceType, &newchannel->offermsg.offer.InterfaceInstance, newchannel); diff --git a/drivers/staging/hv/vmbus.c b/drivers/staging/hv/vmbus.c index e6462c6774d1..163c743ea476 100644 --- a/drivers/staging/hv/vmbus.c +++ b/drivers/staging/hv/vmbus.c @@ -60,19 +60,6 @@ static void VmbusGetChannelOffers(void) vmbus_request_offers(); } -/* - * VmbusCreateChildDevice - Creates the child device on the bus that represents the channel offer - */ -struct hv_device *VmbusChildDeviceCreate(struct hv_guid *DeviceType, - struct hv_guid *DeviceInstance, - struct vmbus_channel *channel) -{ - struct vmbus_driver *vmbusDriver = (struct vmbus_driver *)gDriver; - - return vmbusDriver->OnChildDeviceCreate(DeviceType, DeviceInstance, - channel); -} - /* * VmbusChildDeviceAdd - Registers the child device with the vmbus */ diff --git a/drivers/staging/hv/vmbus_api.h b/drivers/staging/hv/vmbus_api.h index 2af42e550076..e26365c0e798 100644 --- a/drivers/staging/hv/vmbus_api.h +++ b/drivers/staging/hv/vmbus_api.h @@ -122,9 +122,6 @@ struct vmbus_driver { struct hv_driver Base; /* Set by the caller */ - struct hv_device * (*OnChildDeviceCreate)(struct hv_guid *DeviceType, - struct hv_guid *DeviceInstance, - struct vmbus_channel *channel); void (*OnChildDeviceDestroy)(struct hv_device *device); int (*OnChildDeviceAdd)(struct hv_device *RootDevice, struct hv_device *ChildDevice); diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c index 096587592e23..224e8440b818 100644 --- a/drivers/staging/hv/vmbus_drv.c +++ b/drivers/staging/hv/vmbus_drv.c @@ -69,9 +69,6 @@ static irqreturn_t vmbus_isr(int irq, void *dev_id); static void vmbus_device_release(struct device *device); static void vmbus_bus_release(struct device *device); -static struct hv_device *vmbus_child_device_create(struct hv_guid *type, - struct hv_guid *instance, - struct vmbus_channel *channel); static void vmbus_child_device_destroy(struct hv_device *device_obj); static int vmbus_child_device_register(struct hv_device *root_device_obj, struct hv_device *child_device_obj); @@ -301,7 +298,6 @@ static int vmbus_bus_init(int (*drv_init)(struct hv_driver *drv)) * Set this up to allow lower layer to callback to add/remove child * devices on the bus */ - vmbus_drv_obj->OnChildDeviceCreate = vmbus_child_device_create; vmbus_drv_obj->OnChildDeviceDestroy = vmbus_child_device_destroy; vmbus_drv_obj->OnChildDeviceAdd = vmbus_child_device_register; vmbus_drv_obj->OnChildDeviceRemove = vmbus_child_device_unregister; @@ -492,9 +488,9 @@ EXPORT_SYMBOL(vmbus_child_driver_unregister); * vmbus_child_device_create - Creates and registers a new child device * on the vmbus. */ -static struct hv_device *vmbus_child_device_create(struct hv_guid *type, - struct hv_guid *instance, - struct vmbus_channel *channel) +struct hv_device *vmbus_child_device_create(struct hv_guid *type, + struct hv_guid *instance, + struct vmbus_channel *channel) { struct vm_device *child_device_ctx; struct hv_device *child_device_obj; diff --git a/drivers/staging/hv/vmbus_private.h b/drivers/staging/hv/vmbus_private.h index 09eaec964b30..d07d832edc01 100644 --- a/drivers/staging/hv/vmbus_private.h +++ b/drivers/staging/hv/vmbus_private.h @@ -102,7 +102,7 @@ extern struct VMBUS_CONNECTION gVmbusConnection; /* General vmbus interface */ -struct hv_device *VmbusChildDeviceCreate(struct hv_guid *deviceType, +struct hv_device *vmbus_child_device_create(struct hv_guid *deviceType, struct hv_guid *deviceInstance, struct vmbus_channel *channel); -- cgit v1.2.3 From 9205307cd88f09e51f2c4aeba79266317a299853 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 2 Dec 2010 08:25:17 -0800 Subject: Staging: hv: remove OnChildDeviceDestroy vmbus_driver callback No one ever calls it so get rid of it, it's pointless. Cc: Haiyang Zhang Cc: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/vmbus_api.h | 1 - drivers/staging/hv/vmbus_drv.c | 10 ---------- 2 files changed, 11 deletions(-) diff --git a/drivers/staging/hv/vmbus_api.h b/drivers/staging/hv/vmbus_api.h index e26365c0e798..189b672a21ee 100644 --- a/drivers/staging/hv/vmbus_api.h +++ b/drivers/staging/hv/vmbus_api.h @@ -122,7 +122,6 @@ struct vmbus_driver { struct hv_driver Base; /* Set by the caller */ - void (*OnChildDeviceDestroy)(struct hv_device *device); int (*OnChildDeviceAdd)(struct hv_device *RootDevice, struct hv_device *ChildDevice); void (*OnChildDeviceRemove)(struct hv_device *device); diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c index 224e8440b818..656e9541e5ec 100644 --- a/drivers/staging/hv/vmbus_drv.c +++ b/drivers/staging/hv/vmbus_drv.c @@ -69,7 +69,6 @@ static irqreturn_t vmbus_isr(int irq, void *dev_id); static void vmbus_device_release(struct device *device); static void vmbus_bus_release(struct device *device); -static void vmbus_child_device_destroy(struct hv_device *device_obj); static int vmbus_child_device_register(struct hv_device *root_device_obj, struct hv_device *child_device_obj); static void vmbus_child_device_unregister(struct hv_device *child_device_obj); @@ -298,7 +297,6 @@ static int vmbus_bus_init(int (*drv_init)(struct hv_driver *drv)) * Set this up to allow lower layer to callback to add/remove child * devices on the bus */ - vmbus_drv_obj->OnChildDeviceDestroy = vmbus_child_device_destroy; vmbus_drv_obj->OnChildDeviceAdd = vmbus_child_device_register; vmbus_drv_obj->OnChildDeviceRemove = vmbus_child_device_unregister; @@ -599,13 +597,6 @@ static void vmbus_child_device_unregister(struct hv_device *device_obj) &device_ctx->device); } -/* - * vmbus_child_device_destroy - Destroy the specified child device on the vmbus. - */ -static void vmbus_child_device_destroy(struct hv_device *device_obj) -{ -} - /* * vmbus_uevent - add uevent for our device * @@ -848,7 +839,6 @@ static void vmbus_device_release(struct device *device) { struct vm_device *device_ctx = device_to_vm_device(device); - /* vmbus_child_device_destroy(&device_ctx->device_obj); */ kfree(device_ctx); /* !!DO NOT REFERENCE device_ctx anymore at this point!! */ -- cgit v1.2.3 From 9d8bd71ad4f295f80450b5089d239c3135802699 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 2 Dec 2010 08:34:45 -0800 Subject: Staging: hv: remove OnChildDeviceRemove vmbus_driver callback It's only ever set to one function, so just call that function instead. Cc: Haiyang Zhang Cc: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/channel_mgmt.c | 4 ++-- drivers/staging/hv/vmbus.c | 10 ---------- drivers/staging/hv/vmbus_api.h | 1 - drivers/staging/hv/vmbus_drv.c | 4 +--- drivers/staging/hv/vmbus_private.h | 2 +- 5 files changed, 4 insertions(+), 17 deletions(-) diff --git a/drivers/staging/hv/channel_mgmt.c b/drivers/staging/hv/channel_mgmt.c index 3105fd1afe7d..0f4d6093f674 100644 --- a/drivers/staging/hv/channel_mgmt.c +++ b/drivers/staging/hv/channel_mgmt.c @@ -413,7 +413,7 @@ static void vmbus_process_rescind_offer(void *context) { struct vmbus_channel *channel = context; - VmbusChildDeviceRemove(channel->device_obj); + vmbus_child_device_unregister(channel->device_obj); } /* @@ -847,7 +847,7 @@ void vmbus_release_unattached_channels(void) "Releasing unattached device object %p", channel->device_obj); - VmbusChildDeviceRemove(channel->device_obj); + vmbus_child_device_unregister(channel->device_obj); free_channel(channel); } else { if (!start) diff --git a/drivers/staging/hv/vmbus.c b/drivers/staging/hv/vmbus.c index 163c743ea476..d7db7d0f5ee6 100644 --- a/drivers/staging/hv/vmbus.c +++ b/drivers/staging/hv/vmbus.c @@ -70,16 +70,6 @@ int VmbusChildDeviceAdd(struct hv_device *ChildDevice) return vmbusDriver->OnChildDeviceAdd(gDevice, ChildDevice); } -/* - * VmbusChildDeviceRemove Unregisters the child device from the vmbus - */ -void VmbusChildDeviceRemove(struct hv_device *ChildDevice) -{ - struct vmbus_driver *vmbusDriver = (struct vmbus_driver *)gDriver; - - vmbusDriver->OnChildDeviceRemove(ChildDevice); -} - /* * VmbusOnDeviceAdd - Callback when the root bus device is added */ diff --git a/drivers/staging/hv/vmbus_api.h b/drivers/staging/hv/vmbus_api.h index 189b672a21ee..59742800b06e 100644 --- a/drivers/staging/hv/vmbus_api.h +++ b/drivers/staging/hv/vmbus_api.h @@ -124,7 +124,6 @@ struct vmbus_driver { /* Set by the caller */ int (*OnChildDeviceAdd)(struct hv_device *RootDevice, struct hv_device *ChildDevice); - void (*OnChildDeviceRemove)(struct hv_device *device); /* Set by the callee */ int (*OnIsr)(struct hv_driver *driver); diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c index 656e9541e5ec..7323f334f83e 100644 --- a/drivers/staging/hv/vmbus_drv.c +++ b/drivers/staging/hv/vmbus_drv.c @@ -71,7 +71,6 @@ static void vmbus_bus_release(struct device *device); static int vmbus_child_device_register(struct hv_device *root_device_obj, struct hv_device *child_device_obj); -static void vmbus_child_device_unregister(struct hv_device *child_device_obj); static ssize_t vmbus_show_device_attr(struct device *dev, struct device_attribute *dev_attr, char *buf); @@ -298,7 +297,6 @@ static int vmbus_bus_init(int (*drv_init)(struct hv_driver *drv)) * devices on the bus */ vmbus_drv_obj->OnChildDeviceAdd = vmbus_child_device_register; - vmbus_drv_obj->OnChildDeviceRemove = vmbus_child_device_unregister; /* Call to bus driver to initialize */ ret = drv_init(&vmbus_drv_obj->Base); @@ -580,7 +578,7 @@ static int vmbus_child_device_register(struct hv_device *root_device_obj, * vmbus_child_device_unregister - Remove the specified child device * from the vmbus. */ -static void vmbus_child_device_unregister(struct hv_device *device_obj) +void vmbus_child_device_unregister(struct hv_device *device_obj) { struct vm_device *device_ctx = to_vm_device(device_obj); diff --git a/drivers/staging/hv/vmbus_private.h b/drivers/staging/hv/vmbus_private.h index d07d832edc01..a5965f8ca107 100644 --- a/drivers/staging/hv/vmbus_private.h +++ b/drivers/staging/hv/vmbus_private.h @@ -108,7 +108,7 @@ struct hv_device *vmbus_child_device_create(struct hv_guid *deviceType, int VmbusChildDeviceAdd(struct hv_device *Device); -void VmbusChildDeviceRemove(struct hv_device *Device); +void vmbus_child_device_unregister(struct hv_device *device_obj); /* static void */ /* VmbusChildDeviceDestroy( */ -- cgit v1.2.3 From 097e310329fb69c928aa44b517a547e4a17658fd Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 2 Dec 2010 08:41:05 -0800 Subject: Staging: hv: remove OnIsr vmbus_driver callback It's only ever set to one function, so just call that function instead. Cc: Haiyang Zhang Cc: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/vmbus.c | 5 ++--- drivers/staging/hv/vmbus_api.h | 2 +- drivers/staging/hv/vmbus_drv.c | 4 +--- 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/drivers/staging/hv/vmbus.c b/drivers/staging/hv/vmbus.c index d7db7d0f5ee6..09b04517ee09 100644 --- a/drivers/staging/hv/vmbus.c +++ b/drivers/staging/hv/vmbus.c @@ -175,9 +175,9 @@ static void VmbusOnEventDPC(struct hv_driver *drv) } /* - * VmbusOnISR - ISR routine + * vmbus_on_isr - ISR routine */ -static int VmbusOnISR(struct hv_driver *drv) +int vmbus_on_isr(struct hv_driver *drv) { int ret = 0; int cpu = smp_processor_id(); @@ -235,7 +235,6 @@ int VmbusInitialize(struct hv_driver *drv) driver->Base.OnDeviceAdd = VmbusOnDeviceAdd; driver->Base.OnDeviceRemove = VmbusOnDeviceRemove; driver->Base.OnCleanup = VmbusOnCleanup; - driver->OnIsr = VmbusOnISR; driver->OnMsgDpc = VmbusOnMsgDPC; driver->OnEventDpc = VmbusOnEventDPC; driver->GetChannelOffers = VmbusGetChannelOffers; diff --git a/drivers/staging/hv/vmbus_api.h b/drivers/staging/hv/vmbus_api.h index 59742800b06e..d0c30a725c7a 100644 --- a/drivers/staging/hv/vmbus_api.h +++ b/drivers/staging/hv/vmbus_api.h @@ -126,12 +126,12 @@ struct vmbus_driver { struct hv_device *ChildDevice); /* Set by the callee */ - int (*OnIsr)(struct hv_driver *driver); void (*OnMsgDpc)(struct hv_driver *driver); void (*OnEventDpc)(struct hv_driver *driver); void (*GetChannelOffers)(void); }; int VmbusInitialize(struct hv_driver *drv); +int vmbus_on_isr(struct hv_driver *drv); #endif /* _VMBUS_API_H_ */ diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c index 7323f334f83e..4551a469832d 100644 --- a/drivers/staging/hv/vmbus_drv.c +++ b/drivers/staging/hv/vmbus_drv.c @@ -873,10 +873,8 @@ static irqreturn_t vmbus_isr(int irq, void *dev_id) struct vmbus_driver *vmbus_driver_obj = &g_vmbus_drv.drv_obj; int ret; - /* ASSERT(vmbus_driver_obj->OnIsr != NULL); */ - /* Call to bus driver to handle interrupt */ - ret = vmbus_driver_obj->OnIsr(&vmbus_driver_obj->Base); + ret = vmbus_on_isr(&vmbus_driver_obj->Base); /* Schedules a dpc if necessary */ if (ret > 0) { -- cgit v1.2.3 From 4a1494fc101b05f895ef52b9d01769d382c5a6e2 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 2 Dec 2010 08:44:48 -0800 Subject: Staging: hv: remove OnMsgDpc vmbus_driver callback It's only ever set to one function, so just call that function instead. Cc: Haiyang Zhang Cc: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/vmbus.c | 5 ++--- drivers/staging/hv/vmbus_api.h | 2 +- drivers/staging/hv/vmbus_drv.c | 6 ++---- 3 files changed, 5 insertions(+), 8 deletions(-) diff --git a/drivers/staging/hv/vmbus.c b/drivers/staging/hv/vmbus.c index 09b04517ee09..df986be8bb84 100644 --- a/drivers/staging/hv/vmbus.c +++ b/drivers/staging/hv/vmbus.c @@ -119,9 +119,9 @@ static void VmbusOnCleanup(struct hv_driver *drv) } /* - * VmbusOnMsgDPC - DPC routine to handle messages from the hypervisior + * vmbus_on_msg_dpc - DPC routine to handle messages from the hypervisior */ -static void VmbusOnMsgDPC(struct hv_driver *drv) +void vmbus_on_msg_dpc(struct hv_driver *drv) { int cpu = smp_processor_id(); void *page_addr = hv_context.synic_message_page[cpu]; @@ -235,7 +235,6 @@ int VmbusInitialize(struct hv_driver *drv) driver->Base.OnDeviceAdd = VmbusOnDeviceAdd; driver->Base.OnDeviceRemove = VmbusOnDeviceRemove; driver->Base.OnCleanup = VmbusOnCleanup; - driver->OnMsgDpc = VmbusOnMsgDPC; driver->OnEventDpc = VmbusOnEventDPC; driver->GetChannelOffers = VmbusGetChannelOffers; diff --git a/drivers/staging/hv/vmbus_api.h b/drivers/staging/hv/vmbus_api.h index d0c30a725c7a..332a92d2cfd3 100644 --- a/drivers/staging/hv/vmbus_api.h +++ b/drivers/staging/hv/vmbus_api.h @@ -126,12 +126,12 @@ struct vmbus_driver { struct hv_device *ChildDevice); /* Set by the callee */ - void (*OnMsgDpc)(struct hv_driver *driver); void (*OnEventDpc)(struct hv_driver *driver); void (*GetChannelOffers)(void); }; int VmbusInitialize(struct hv_driver *drv); int vmbus_on_isr(struct hv_driver *drv); +void vmbus_on_msg_dpc(struct hv_driver *drv); #endif /* _VMBUS_API_H_ */ diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c index 4551a469832d..d57f54db2a5a 100644 --- a/drivers/staging/hv/vmbus_drv.c +++ b/drivers/staging/hv/vmbus_drv.c @@ -849,14 +849,12 @@ static void vmbus_msg_dpc(unsigned long data) { struct vmbus_driver *vmbus_drv_obj = (struct vmbus_driver *)data; - /* ASSERT(vmbus_drv_obj->OnMsgDpc != NULL); */ - /* Call to bus driver to handle interrupt */ - vmbus_drv_obj->OnMsgDpc(&vmbus_drv_obj->Base); + vmbus_on_msg_dpc(&vmbus_drv_obj->Base); } /* - * vmbus_msg_dpc - Tasklet routine to handle hypervisor events + * vmbus_event_dpc - Tasklet routine to handle hypervisor events */ static void vmbus_event_dpc(unsigned long data) { -- cgit v1.2.3 From c722bd3e2cb92be7afec346894faa29605436c1a Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 2 Dec 2010 08:47:11 -0800 Subject: Staging: hv: remove OnEventDpc vmbus_driver callback It's only ever set to one function, so just call that function instead. Cc: Haiyang Zhang Cc: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/vmbus.c | 5 ++--- drivers/staging/hv/vmbus_api.h | 2 +- drivers/staging/hv/vmbus_drv.c | 4 +--- 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/drivers/staging/hv/vmbus.c b/drivers/staging/hv/vmbus.c index df986be8bb84..3aeedf6026e3 100644 --- a/drivers/staging/hv/vmbus.c +++ b/drivers/staging/hv/vmbus.c @@ -166,9 +166,9 @@ void vmbus_on_msg_dpc(struct hv_driver *drv) } /* - * VmbusOnEventDPC - DPC routine to handle events from the hypervisior + * vmbus_on_event_dpc - DPC routine to handle events from the hypervisior */ -static void VmbusOnEventDPC(struct hv_driver *drv) +void vmbus_on_event_dpc(struct hv_driver *drv) { /* TODO: Process any events */ VmbusOnEvents(); @@ -235,7 +235,6 @@ int VmbusInitialize(struct hv_driver *drv) driver->Base.OnDeviceAdd = VmbusOnDeviceAdd; driver->Base.OnDeviceRemove = VmbusOnDeviceRemove; driver->Base.OnCleanup = VmbusOnCleanup; - driver->OnEventDpc = VmbusOnEventDPC; driver->GetChannelOffers = VmbusGetChannelOffers; /* Hypervisor initialization...setup hypercall page..etc */ diff --git a/drivers/staging/hv/vmbus_api.h b/drivers/staging/hv/vmbus_api.h index 332a92d2cfd3..31549c9579ba 100644 --- a/drivers/staging/hv/vmbus_api.h +++ b/drivers/staging/hv/vmbus_api.h @@ -126,12 +126,12 @@ struct vmbus_driver { struct hv_device *ChildDevice); /* Set by the callee */ - void (*OnEventDpc)(struct hv_driver *driver); void (*GetChannelOffers)(void); }; int VmbusInitialize(struct hv_driver *drv); int vmbus_on_isr(struct hv_driver *drv); void vmbus_on_msg_dpc(struct hv_driver *drv); +void vmbus_on_event_dpc(struct hv_driver *drv); #endif /* _VMBUS_API_H_ */ diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c index d57f54db2a5a..d075d9624279 100644 --- a/drivers/staging/hv/vmbus_drv.c +++ b/drivers/staging/hv/vmbus_drv.c @@ -860,10 +860,8 @@ static void vmbus_event_dpc(unsigned long data) { struct vmbus_driver *vmbus_drv_obj = (struct vmbus_driver *)data; - /* ASSERT(vmbus_drv_obj->OnEventDpc != NULL); */ - /* Call to bus driver to handle interrupt */ - vmbus_drv_obj->OnEventDpc(&vmbus_drv_obj->Base); + vmbus_on_event_dpc(&vmbus_drv_obj->Base); } static irqreturn_t vmbus_isr(int irq, void *dev_id) -- cgit v1.2.3 From 2d6e882bada0ca7828347647c5b1091bf5f18fee Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 2 Dec 2010 08:50:58 -0800 Subject: Staging: hv: remove GetChannelOffers vmbus_driver callback It's only ever set to one function, so just call that function instead. Actually, that wrapper function only ever called vmbus_request_offers() so just call that function instead, no need for a do-nothing intermediate step here. Cc: Haiyang Zhang Cc: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/vmbus.c | 9 --------- drivers/staging/hv/vmbus_api.h | 3 --- drivers/staging/hv/vmbus_drv.c | 7 ++----- 3 files changed, 2 insertions(+), 17 deletions(-) diff --git a/drivers/staging/hv/vmbus.c b/drivers/staging/hv/vmbus.c index 3aeedf6026e3..ae9e298f5c85 100644 --- a/drivers/staging/hv/vmbus.c +++ b/drivers/staging/hv/vmbus.c @@ -52,14 +52,6 @@ static const struct hv_guid gVmbusDeviceId = { static struct hv_driver *gDriver; /* vmbus driver object */ static struct hv_device *gDevice; /* vmbus root device */ -/* - * VmbusGetChannelOffers - Retrieve the channel offers from the parent partition - */ -static void VmbusGetChannelOffers(void) -{ - vmbus_request_offers(); -} - /* * VmbusChildDeviceAdd - Registers the child device with the vmbus */ @@ -235,7 +227,6 @@ int VmbusInitialize(struct hv_driver *drv) driver->Base.OnDeviceAdd = VmbusOnDeviceAdd; driver->Base.OnDeviceRemove = VmbusOnDeviceRemove; driver->Base.OnCleanup = VmbusOnCleanup; - driver->GetChannelOffers = VmbusGetChannelOffers; /* Hypervisor initialization...setup hypercall page..etc */ ret = hv_init(); diff --git a/drivers/staging/hv/vmbus_api.h b/drivers/staging/hv/vmbus_api.h index 31549c9579ba..c85d7d43146e 100644 --- a/drivers/staging/hv/vmbus_api.h +++ b/drivers/staging/hv/vmbus_api.h @@ -124,9 +124,6 @@ struct vmbus_driver { /* Set by the caller */ int (*OnChildDeviceAdd)(struct hv_device *RootDevice, struct hv_device *ChildDevice); - - /* Set by the callee */ - void (*GetChannelOffers)(void); }; int VmbusInitialize(struct hv_driver *drv); diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c index d075d9624279..6de53c40e023 100644 --- a/drivers/staging/hv/vmbus_drv.c +++ b/drivers/staging/hv/vmbus_drv.c @@ -387,9 +387,7 @@ static int vmbus_bus_init(int (*drv_init)(struct hv_driver *drv)) goto cleanup; } - - vmbus_drv_obj->GetChannelOffers(); - + vmbus_request_offers(); wait_for_completion(&hv_channel_ready); cleanup: @@ -441,7 +439,6 @@ static void vmbus_bus_exit(void) */ int vmbus_child_driver_register(struct driver_context *driver_ctx) { - struct vmbus_driver *vmbus_drv_obj = &g_vmbus_drv.drv_obj; int ret; DPRINT_INFO(VMBUS_DRV, "child driver (%p) registering - name %s", @@ -452,7 +449,7 @@ int vmbus_child_driver_register(struct driver_context *driver_ctx) ret = driver_register(&driver_ctx->driver); - vmbus_drv_obj->GetChannelOffers(); + vmbus_request_offers(); return ret; } -- cgit v1.2.3 From 98293a279cc0ff085ead7c032c6b8cb7b6ad7e88 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 2 Dec 2010 09:16:04 -0800 Subject: Staging: hv: remove OnChildDeviceAdd vmbus_driver callback It's only ever set to one function, so just call that function instead. Cc: Haiyang Zhang Cc: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/vmbus.c | 4 +--- drivers/staging/hv/vmbus_api.h | 4 ---- drivers/staging/hv/vmbus_drv.c | 12 ++---------- drivers/staging/hv/vmbus_private.h | 3 ++- 4 files changed, 5 insertions(+), 18 deletions(-) diff --git a/drivers/staging/hv/vmbus.c b/drivers/staging/hv/vmbus.c index ae9e298f5c85..7a7454ce8cad 100644 --- a/drivers/staging/hv/vmbus.c +++ b/drivers/staging/hv/vmbus.c @@ -57,9 +57,7 @@ static struct hv_device *gDevice; /* vmbus root device */ */ int VmbusChildDeviceAdd(struct hv_device *ChildDevice) { - struct vmbus_driver *vmbusDriver = (struct vmbus_driver *)gDriver; - - return vmbusDriver->OnChildDeviceAdd(gDevice, ChildDevice); + return vmbus_child_device_register(gDevice, ChildDevice); } /* diff --git a/drivers/staging/hv/vmbus_api.h b/drivers/staging/hv/vmbus_api.h index c85d7d43146e..6f3d59c7589d 100644 --- a/drivers/staging/hv/vmbus_api.h +++ b/drivers/staging/hv/vmbus_api.h @@ -120,10 +120,6 @@ struct vmbus_driver { /* !! Must be the 1st field !! */ /* FIXME if ^, then someone is doing somthing stupid */ struct hv_driver Base; - - /* Set by the caller */ - int (*OnChildDeviceAdd)(struct hv_device *RootDevice, - struct hv_device *ChildDevice); }; int VmbusInitialize(struct hv_driver *drv); diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c index 6de53c40e023..4fa23c92128b 100644 --- a/drivers/staging/hv/vmbus_drv.c +++ b/drivers/staging/hv/vmbus_drv.c @@ -69,8 +69,6 @@ static irqreturn_t vmbus_isr(int irq, void *dev_id); static void vmbus_device_release(struct device *device); static void vmbus_bus_release(struct device *device); -static int vmbus_child_device_register(struct hv_device *root_device_obj, - struct hv_device *child_device_obj); static ssize_t vmbus_show_device_attr(struct device *dev, struct device_attribute *dev_attr, char *buf); @@ -292,12 +290,6 @@ static int vmbus_bus_init(int (*drv_init)(struct hv_driver *drv)) int ret; unsigned int vector; - /* - * Set this up to allow lower layer to callback to add/remove child - * devices on the bus - */ - vmbus_drv_obj->OnChildDeviceAdd = vmbus_child_device_register; - /* Call to bus driver to initialize */ ret = drv_init(&vmbus_drv_obj->Base); if (ret != 0) { @@ -530,8 +522,8 @@ struct hv_device *vmbus_child_device_create(struct hv_guid *type, /* * vmbus_child_device_register - Register the child device on the specified bus */ -static int vmbus_child_device_register(struct hv_device *root_device_obj, - struct hv_device *child_device_obj) +int vmbus_child_device_register(struct hv_device *root_device_obj, + struct hv_device *child_device_obj) { int ret = 0; struct vm_device *root_device_ctx = diff --git a/drivers/staging/hv/vmbus_private.h b/drivers/staging/hv/vmbus_private.h index a5965f8ca107..07f6d22eeabb 100644 --- a/drivers/staging/hv/vmbus_private.h +++ b/drivers/staging/hv/vmbus_private.h @@ -107,7 +107,8 @@ struct hv_device *vmbus_child_device_create(struct hv_guid *deviceType, struct vmbus_channel *channel); int VmbusChildDeviceAdd(struct hv_device *Device); - +int vmbus_child_device_register(struct hv_device *root_device_obj, + struct hv_device *child_device_obj); void vmbus_child_device_unregister(struct hv_device *device_obj); /* static void */ -- cgit v1.2.3 From a69a6691d71cc24979ce29394478218307a77a84 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 2 Dec 2010 09:42:18 -0800 Subject: Staging: hv: remove struct vmbus_driver It's only a wrapper for the struct hv_driver structure, so just use that instead, as there are no other fields left in it at the moment. Cc: Haiyang Zhang Cc: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/vmbus.c | 15 +++++++-------- drivers/staging/hv/vmbus_api.h | 7 ------- drivers/staging/hv/vmbus_drv.c | 42 +++++++++++++++++++++--------------------- 3 files changed, 28 insertions(+), 36 deletions(-) diff --git a/drivers/staging/hv/vmbus.c b/drivers/staging/hv/vmbus.c index 7a7454ce8cad..650a97598f17 100644 --- a/drivers/staging/hv/vmbus.c +++ b/drivers/staging/hv/vmbus.c @@ -202,9 +202,8 @@ int vmbus_on_isr(struct hv_driver *drv) /* * VmbusInitialize - Main entry point */ -int VmbusInitialize(struct hv_driver *drv) +int VmbusInitialize(struct hv_driver *driver) { - struct vmbus_driver *driver = (struct vmbus_driver *)drv; int ret; DPRINT_INFO(VMBUS, "+++++++ HV Driver version = %s +++++++", @@ -218,20 +217,20 @@ int VmbusInitialize(struct hv_driver *drv) sizeof(struct vmbus_channel_packet_page_buffer), sizeof(struct vmbus_channel_packet_multipage_buffer)); - drv->name = gDriverName; - memcpy(&drv->deviceType, &gVmbusDeviceType, sizeof(struct hv_guid)); + driver->name = gDriverName; + memcpy(&driver->deviceType, &gVmbusDeviceType, sizeof(struct hv_guid)); /* Setup dispatch table */ - driver->Base.OnDeviceAdd = VmbusOnDeviceAdd; - driver->Base.OnDeviceRemove = VmbusOnDeviceRemove; - driver->Base.OnCleanup = VmbusOnCleanup; + driver->OnDeviceAdd = VmbusOnDeviceAdd; + driver->OnDeviceRemove = VmbusOnDeviceRemove; + driver->OnCleanup = VmbusOnCleanup; /* Hypervisor initialization...setup hypercall page..etc */ ret = hv_init(); if (ret != 0) DPRINT_ERR(VMBUS, "Unable to initialize the hypervisor - 0x%x", ret); - gDriver = drv; + gDriver = driver; return ret; } diff --git a/drivers/staging/hv/vmbus_api.h b/drivers/staging/hv/vmbus_api.h index 6f3d59c7589d..45c9b9a55528 100644 --- a/drivers/staging/hv/vmbus_api.h +++ b/drivers/staging/hv/vmbus_api.h @@ -115,13 +115,6 @@ struct hv_device { void *Extension; }; -/* Vmbus driver object */ -struct vmbus_driver { - /* !! Must be the 1st field !! */ - /* FIXME if ^, then someone is doing somthing stupid */ - struct hv_driver Base; -}; - int VmbusInitialize(struct hv_driver *drv); int vmbus_on_isr(struct hv_driver *drv); void vmbus_on_msg_dpc(struct hv_driver *drv); diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c index 4fa23c92128b..2d3cf0f35328 100644 --- a/drivers/staging/hv/vmbus_drv.c +++ b/drivers/staging/hv/vmbus_drv.c @@ -46,7 +46,7 @@ struct vmbus_driver_context { /* The driver field is not used in here. Instead, the bus field is */ /* used to represent the driver */ struct driver_context drv_ctx; - struct vmbus_driver drv_obj; + struct hv_driver drv_obj; struct bus_type bus; struct tasklet_struct msg_dpc; @@ -285,32 +285,32 @@ static ssize_t vmbus_show_device_attr(struct device *dev, static int vmbus_bus_init(int (*drv_init)(struct hv_driver *drv)) { struct vmbus_driver_context *vmbus_drv_ctx = &g_vmbus_drv; - struct vmbus_driver *vmbus_drv_obj = &g_vmbus_drv.drv_obj; + struct hv_driver *driver = &g_vmbus_drv.drv_obj; struct vm_device *dev_ctx = &g_vmbus_drv.device_ctx; int ret; unsigned int vector; /* Call to bus driver to initialize */ - ret = drv_init(&vmbus_drv_obj->Base); + ret = drv_init(driver); if (ret != 0) { DPRINT_ERR(VMBUS_DRV, "Unable to initialize vmbus (%d)", ret); goto cleanup; } /* Sanity checks */ - if (!vmbus_drv_obj->Base.OnDeviceAdd) { + if (!driver->OnDeviceAdd) { DPRINT_ERR(VMBUS_DRV, "OnDeviceAdd() routine not set"); ret = -1; goto cleanup; } - vmbus_drv_ctx->bus.name = vmbus_drv_obj->Base.name; + vmbus_drv_ctx->bus.name = driver->name; /* Initialize the bus context */ tasklet_init(&vmbus_drv_ctx->msg_dpc, vmbus_msg_dpc, - (unsigned long)vmbus_drv_obj); + (unsigned long)driver); tasklet_init(&vmbus_drv_ctx->event_dpc, vmbus_event_dpc, - (unsigned long)vmbus_drv_obj); + (unsigned long)driver); /* Now, register the bus driver with LDM */ ret = bus_register(&vmbus_drv_ctx->bus); @@ -321,7 +321,7 @@ static int vmbus_bus_init(int (*drv_init)(struct hv_driver *drv)) /* Get the interrupt resource */ ret = request_irq(vmbus_irq, vmbus_isr, IRQF_SAMPLE_RANDOM, - vmbus_drv_obj->Base.name, NULL); + driver->name, NULL); if (ret != 0) { DPRINT_ERR(VMBUS_DRV, "ERROR - Unable to request IRQ %d", @@ -339,7 +339,7 @@ static int vmbus_bus_init(int (*drv_init)(struct hv_driver *drv)) /* Call to bus driver to add the root device */ memset(dev_ctx, 0, sizeof(struct vm_device)); - ret = vmbus_drv_obj->Base.OnDeviceAdd(&dev_ctx->device_obj, &vector); + ret = driver->OnDeviceAdd(&dev_ctx->device_obj, &vector); if (ret != 0) { DPRINT_ERR(VMBUS_DRV, "ERROR - Unable to add vmbus root device"); @@ -393,17 +393,17 @@ cleanup: */ static void vmbus_bus_exit(void) { - struct vmbus_driver *vmbus_drv_obj = &g_vmbus_drv.drv_obj; + struct hv_driver *driver = &g_vmbus_drv.drv_obj; struct vmbus_driver_context *vmbus_drv_ctx = &g_vmbus_drv; struct vm_device *dev_ctx = &g_vmbus_drv.device_ctx; /* Remove the root device */ - if (vmbus_drv_obj->Base.OnDeviceRemove) - vmbus_drv_obj->Base.OnDeviceRemove(&dev_ctx->device_obj); + if (driver->OnDeviceRemove) + driver->OnDeviceRemove(&dev_ctx->device_obj); - if (vmbus_drv_obj->Base.OnCleanup) - vmbus_drv_obj->Base.OnCleanup(&vmbus_drv_obj->Base); + if (driver->OnCleanup) + driver->OnCleanup(driver); /* Unregister the root bus device */ device_unregister(&dev_ctx->device); @@ -678,7 +678,7 @@ static int vmbus_match(struct device *device, struct device_driver *driver) struct vmbus_driver_context *vmbus_drv_ctx = (struct vmbus_driver_context *)driver_ctx; - device_ctx->device_obj.Driver = &vmbus_drv_ctx->drv_obj.Base; + device_ctx->device_obj.Driver = &vmbus_drv_ctx->drv_obj; DPRINT_INFO(VMBUS_DRV, "device object (%p) set to driver object (%p)", &device_ctx->device_obj, @@ -836,10 +836,10 @@ static void vmbus_device_release(struct device *device) */ static void vmbus_msg_dpc(unsigned long data) { - struct vmbus_driver *vmbus_drv_obj = (struct vmbus_driver *)data; + struct hv_driver *driver = (struct hv_driver *)data; /* Call to bus driver to handle interrupt */ - vmbus_on_msg_dpc(&vmbus_drv_obj->Base); + vmbus_on_msg_dpc(driver); } /* @@ -847,19 +847,19 @@ static void vmbus_msg_dpc(unsigned long data) */ static void vmbus_event_dpc(unsigned long data) { - struct vmbus_driver *vmbus_drv_obj = (struct vmbus_driver *)data; + struct hv_driver *driver = (struct hv_driver *)data; /* Call to bus driver to handle interrupt */ - vmbus_on_event_dpc(&vmbus_drv_obj->Base); + vmbus_on_event_dpc(driver); } static irqreturn_t vmbus_isr(int irq, void *dev_id) { - struct vmbus_driver *vmbus_driver_obj = &g_vmbus_drv.drv_obj; + struct hv_driver *driver = &g_vmbus_drv.drv_obj; int ret; /* Call to bus driver to handle interrupt */ - ret = vmbus_on_isr(&vmbus_driver_obj->Base); + ret = vmbus_on_isr(driver); /* Schedules a dpc if necessary */ if (ret > 0) { -- cgit v1.2.3 From 1953ecfc293911311f04d8c19f04d2249a30707b Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 2 Dec 2010 11:28:28 -0800 Subject: Staging: hv: rename the vmbus to "hyperv" This changes the name of the bus in sysfs from "vmbus" to "hyperv" which is the name it should show (vmbus is way to generic). Cc: Haiyang Zhang Cc: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/vmbus.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/hv/vmbus.c b/drivers/staging/hv/vmbus.c index 650a97598f17..df342f285c04 100644 --- a/drivers/staging/hv/vmbus.c +++ b/drivers/staging/hv/vmbus.c @@ -27,7 +27,7 @@ #include "version_info.h" #include "vmbus_private.h" -static const char *gDriverName = "vmbus"; +static const char *gDriverName = "hyperv"; /* * Windows vmbus does not defined this. -- cgit v1.2.3 From 36199a992aba4f3ea1bc0430f04655e99010a65d Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 2 Dec 2010 11:59:22 -0800 Subject: Staging: hv: remove vmbus.c Merge the functions into vmbus_drv.c as there's no need to have them separate anymore. It will also make unwinding some of the function and pointer mess easier, as well as making functions static in the future. Cc: Haiyang Zhang Cc: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/Makefile | 2 +- drivers/staging/hv/vmbus.c | 236 ----------------------------------------- drivers/staging/hv/vmbus_drv.c | 209 ++++++++++++++++++++++++++++++++++++ 3 files changed, 210 insertions(+), 237 deletions(-) delete mode 100644 drivers/staging/hv/vmbus.c diff --git a/drivers/staging/hv/Makefile b/drivers/staging/hv/Makefile index b46349bb43bf..acd39bd75b1c 100644 --- a/drivers/staging/hv/Makefile +++ b/drivers/staging/hv/Makefile @@ -5,7 +5,7 @@ obj-$(CONFIG_HYPERV_NET) += hv_netvsc.o obj-$(CONFIG_HYPERV_UTILS) += hv_utils.o hv_vmbus-y := vmbus_drv.o osd.o \ - vmbus.o hv.o connection.o channel.o \ + hv.o connection.o channel.o \ channel_mgmt.o ring_buffer.o hv_storvsc-y := storvsc_drv.o storvsc.o hv_blkvsc-y := blkvsc_drv.o blkvsc.o diff --git a/drivers/staging/hv/vmbus.c b/drivers/staging/hv/vmbus.c deleted file mode 100644 index df342f285c04..000000000000 --- a/drivers/staging/hv/vmbus.c +++ /dev/null @@ -1,236 +0,0 @@ -/* - * Copyright (c) 2009, Microsoft Corporation. - * - * This program is free software; you can redistribute it and/or modify it - * under the terms and conditions of the GNU General Public License, - * version 2, as published by the Free Software Foundation. - * - * This program is distributed in the hope 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. - * - * You should have received a copy of the GNU General Public License along with - * this program; if not, write to the Free Software Foundation, Inc., 59 Temple - * Place - Suite 330, Boston, MA 02111-1307 USA. - * - * Authors: - * Haiyang Zhang - * Hank Janssen - * - */ -#include -#include -#include -#include "osd.h" -#include "logging.h" -#include "version_info.h" -#include "vmbus_private.h" - -static const char *gDriverName = "hyperv"; - -/* - * Windows vmbus does not defined this. - * We defined this to be consistent with other devices - */ -/* {c5295816-f63a-4d5f-8d1a-4daf999ca185} */ -static const struct hv_guid gVmbusDeviceType = { - .data = { - 0x16, 0x58, 0x29, 0xc5, 0x3a, 0xf6, 0x5f, 0x4d, - 0x8d, 0x1a, 0x4d, 0xaf, 0x99, 0x9c, 0xa1, 0x85 - } -}; - -/* {ac3760fc-9adf-40aa-9427-a70ed6de95c5} */ -static const struct hv_guid gVmbusDeviceId = { - .data = { - 0xfc, 0x60, 0x37, 0xac, 0xdf, 0x9a, 0xaa, 0x40, - 0x94, 0x27, 0xa7, 0x0e, 0xd6, 0xde, 0x95, 0xc5 - } -}; - -static struct hv_driver *gDriver; /* vmbus driver object */ -static struct hv_device *gDevice; /* vmbus root device */ - -/* - * VmbusChildDeviceAdd - Registers the child device with the vmbus - */ -int VmbusChildDeviceAdd(struct hv_device *ChildDevice) -{ - return vmbus_child_device_register(gDevice, ChildDevice); -} - -/* - * VmbusOnDeviceAdd - Callback when the root bus device is added - */ -static int VmbusOnDeviceAdd(struct hv_device *dev, void *AdditionalInfo) -{ - u32 *irqvector = AdditionalInfo; - int ret; - - gDevice = dev; - - memcpy(&gDevice->deviceType, &gVmbusDeviceType, sizeof(struct hv_guid)); - memcpy(&gDevice->deviceInstance, &gVmbusDeviceId, - sizeof(struct hv_guid)); - - /* strcpy(dev->name, "vmbus"); */ - /* SynIC setup... */ - on_each_cpu(hv_synic_init, (void *)irqvector, 1); - - /* Connect to VMBus in the root partition */ - ret = VmbusConnect(); - - /* VmbusSendEvent(device->localPortId+1); */ - return ret; -} - -/* - * VmbusOnDeviceRemove - Callback when the root bus device is removed - */ -static int VmbusOnDeviceRemove(struct hv_device *dev) -{ - int ret = 0; - - vmbus_release_unattached_channels(); - VmbusDisconnect(); - on_each_cpu(hv_synic_cleanup, NULL, 1); - return ret; -} - -/* - * VmbusOnCleanup - Perform any cleanup when the driver is removed - */ -static void VmbusOnCleanup(struct hv_driver *drv) -{ - /* struct vmbus_driver *driver = (struct vmbus_driver *)drv; */ - - hv_cleanup(); -} - -/* - * vmbus_on_msg_dpc - DPC routine to handle messages from the hypervisior - */ -void vmbus_on_msg_dpc(struct hv_driver *drv) -{ - int cpu = smp_processor_id(); - void *page_addr = hv_context.synic_message_page[cpu]; - struct hv_message *msg = (struct hv_message *)page_addr + - VMBUS_MESSAGE_SINT; - struct hv_message *copied; - - while (1) { - if (msg->header.message_type == HVMSG_NONE) { - /* no msg */ - break; - } else { - copied = kmemdup(msg, sizeof(*copied), GFP_ATOMIC); - if (copied == NULL) - continue; - - osd_schedule_callback(gVmbusConnection.WorkQueue, - vmbus_onmessage, - (void *)copied); - } - - msg->header.message_type = HVMSG_NONE; - - /* - * Make sure the write to MessageType (ie set to - * HVMSG_NONE) happens before we read the - * MessagePending and EOMing. Otherwise, the EOMing - * will not deliver any more messages since there is - * no empty slot - */ - mb(); - - if (msg->header.message_flags.msg_pending) { - /* - * This will cause message queue rescan to - * possibly deliver another msg from the - * hypervisor - */ - wrmsrl(HV_X64_MSR_EOM, 0); - } - } -} - -/* - * vmbus_on_event_dpc - DPC routine to handle events from the hypervisior - */ -void vmbus_on_event_dpc(struct hv_driver *drv) -{ - /* TODO: Process any events */ - VmbusOnEvents(); -} - -/* - * vmbus_on_isr - ISR routine - */ -int vmbus_on_isr(struct hv_driver *drv) -{ - int ret = 0; - int cpu = smp_processor_id(); - void *page_addr; - struct hv_message *msg; - union hv_synic_event_flags *event; - - page_addr = hv_context.synic_message_page[cpu]; - msg = (struct hv_message *)page_addr + VMBUS_MESSAGE_SINT; - - /* Check if there are actual msgs to be process */ - if (msg->header.message_type != HVMSG_NONE) { - DPRINT_DBG(VMBUS, "received msg type %d size %d", - msg->header.message_type, - msg->header.payload_size); - ret |= 0x1; - } - - /* TODO: Check if there are events to be process */ - page_addr = hv_context.synic_event_page[cpu]; - event = (union hv_synic_event_flags *)page_addr + VMBUS_MESSAGE_SINT; - - /* Since we are a child, we only need to check bit 0 */ - if (test_and_clear_bit(0, (unsigned long *) &event->flags32[0])) { - DPRINT_DBG(VMBUS, "received event %d", event->flags32[0]); - ret |= 0x2; - } - - return ret; -} - -/* - * VmbusInitialize - Main entry point - */ -int VmbusInitialize(struct hv_driver *driver) -{ - int ret; - - DPRINT_INFO(VMBUS, "+++++++ HV Driver version = %s +++++++", - HV_DRV_VERSION); - DPRINT_INFO(VMBUS, "+++++++ Vmbus supported version = %d +++++++", - VMBUS_REVISION_NUMBER); - DPRINT_INFO(VMBUS, "+++++++ Vmbus using SINT %d +++++++", - VMBUS_MESSAGE_SINT); - DPRINT_DBG(VMBUS, "sizeof(vmbus_channel_packet_page_buffer)=%zd, " - "sizeof(VMBUS_CHANNEL_PACKET_MULITPAGE_BUFFER)=%zd", - sizeof(struct vmbus_channel_packet_page_buffer), - sizeof(struct vmbus_channel_packet_multipage_buffer)); - - driver->name = gDriverName; - memcpy(&driver->deviceType, &gVmbusDeviceType, sizeof(struct hv_guid)); - - /* Setup dispatch table */ - driver->OnDeviceAdd = VmbusOnDeviceAdd; - driver->OnDeviceRemove = VmbusOnDeviceRemove; - driver->OnCleanup = VmbusOnCleanup; - - /* Hypervisor initialization...setup hypercall page..etc */ - ret = hv_init(); - if (ret != 0) - DPRINT_ERR(VMBUS, "Unable to initialize the hypervisor - 0x%x", - ret); - gDriver = driver; - - return ret; -} diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c index 2d3cf0f35328..9c2325dff1c0 100644 --- a/drivers/staging/hv/vmbus_drv.c +++ b/drivers/staging/hv/vmbus_drv.c @@ -33,6 +33,7 @@ #include "logging.h" #include "vmbus.h" #include "channel.h" +#include "vmbus_private.h" /* FIXME! We need to do this dynamically for PIC and APIC system */ @@ -122,6 +123,214 @@ static struct vmbus_driver_context g_vmbus_drv = { .bus.dev_attrs = vmbus_device_attrs, }; +static const char *gDriverName = "hyperv"; + +/* + * Windows vmbus does not defined this. + * We defined this to be consistent with other devices + */ +/* {c5295816-f63a-4d5f-8d1a-4daf999ca185} */ +static const struct hv_guid gVmbusDeviceType = { + .data = { + 0x16, 0x58, 0x29, 0xc5, 0x3a, 0xf6, 0x5f, 0x4d, + 0x8d, 0x1a, 0x4d, 0xaf, 0x99, 0x9c, 0xa1, 0x85 + } +}; + +/* {ac3760fc-9adf-40aa-9427-a70ed6de95c5} */ +static const struct hv_guid gVmbusDeviceId = { + .data = { + 0xfc, 0x60, 0x37, 0xac, 0xdf, 0x9a, 0xaa, 0x40, + 0x94, 0x27, 0xa7, 0x0e, 0xd6, 0xde, 0x95, 0xc5 + } +}; + +static struct hv_driver *gDriver; /* vmbus driver object */ +static struct hv_device *gDevice; /* vmbus root device */ + +/* + * VmbusChildDeviceAdd - Registers the child device with the vmbus + */ +int VmbusChildDeviceAdd(struct hv_device *ChildDevice) +{ + return vmbus_child_device_register(gDevice, ChildDevice); +} + +/* + * VmbusOnDeviceAdd - Callback when the root bus device is added + */ +static int VmbusOnDeviceAdd(struct hv_device *dev, void *AdditionalInfo) +{ + u32 *irqvector = AdditionalInfo; + int ret; + + gDevice = dev; + + memcpy(&gDevice->deviceType, &gVmbusDeviceType, sizeof(struct hv_guid)); + memcpy(&gDevice->deviceInstance, &gVmbusDeviceId, + sizeof(struct hv_guid)); + + /* strcpy(dev->name, "vmbus"); */ + /* SynIC setup... */ + on_each_cpu(hv_synic_init, (void *)irqvector, 1); + + /* Connect to VMBus in the root partition */ + ret = VmbusConnect(); + + /* VmbusSendEvent(device->localPortId+1); */ + return ret; +} + +/* + * VmbusOnDeviceRemove - Callback when the root bus device is removed + */ +static int VmbusOnDeviceRemove(struct hv_device *dev) +{ + int ret = 0; + + vmbus_release_unattached_channels(); + VmbusDisconnect(); + on_each_cpu(hv_synic_cleanup, NULL, 1); + return ret; +} + +/* + * VmbusOnCleanup - Perform any cleanup when the driver is removed + */ +static void VmbusOnCleanup(struct hv_driver *drv) +{ + /* struct vmbus_driver *driver = (struct vmbus_driver *)drv; */ + + hv_cleanup(); +} + +/* + * vmbus_on_msg_dpc - DPC routine to handle messages from the hypervisior + */ +void vmbus_on_msg_dpc(struct hv_driver *drv) +{ + int cpu = smp_processor_id(); + void *page_addr = hv_context.synic_message_page[cpu]; + struct hv_message *msg = (struct hv_message *)page_addr + + VMBUS_MESSAGE_SINT; + struct hv_message *copied; + + while (1) { + if (msg->header.message_type == HVMSG_NONE) { + /* no msg */ + break; + } else { + copied = kmemdup(msg, sizeof(*copied), GFP_ATOMIC); + if (copied == NULL) + continue; + + osd_schedule_callback(gVmbusConnection.WorkQueue, + vmbus_onmessage, + (void *)copied); + } + + msg->header.message_type = HVMSG_NONE; + + /* + * Make sure the write to MessageType (ie set to + * HVMSG_NONE) happens before we read the + * MessagePending and EOMing. Otherwise, the EOMing + * will not deliver any more messages since there is + * no empty slot + */ + mb(); + + if (msg->header.message_flags.msg_pending) { + /* + * This will cause message queue rescan to + * possibly deliver another msg from the + * hypervisor + */ + wrmsrl(HV_X64_MSR_EOM, 0); + } + } +} + +/* + * vmbus_on_event_dpc - DPC routine to handle events from the hypervisior + */ +void vmbus_on_event_dpc(struct hv_driver *drv) +{ + /* TODO: Process any events */ + VmbusOnEvents(); +} + +/* + * vmbus_on_isr - ISR routine + */ +int vmbus_on_isr(struct hv_driver *drv) +{ + int ret = 0; + int cpu = smp_processor_id(); + void *page_addr; + struct hv_message *msg; + union hv_synic_event_flags *event; + + page_addr = hv_context.synic_message_page[cpu]; + msg = (struct hv_message *)page_addr + VMBUS_MESSAGE_SINT; + + /* Check if there are actual msgs to be process */ + if (msg->header.message_type != HVMSG_NONE) { + DPRINT_DBG(VMBUS, "received msg type %d size %d", + msg->header.message_type, + msg->header.payload_size); + ret |= 0x1; + } + + /* TODO: Check if there are events to be process */ + page_addr = hv_context.synic_event_page[cpu]; + event = (union hv_synic_event_flags *)page_addr + VMBUS_MESSAGE_SINT; + + /* Since we are a child, we only need to check bit 0 */ + if (test_and_clear_bit(0, (unsigned long *) &event->flags32[0])) { + DPRINT_DBG(VMBUS, "received event %d", event->flags32[0]); + ret |= 0x2; + } + + return ret; +} + +/* + * VmbusInitialize - Main entry point + */ +int VmbusInitialize(struct hv_driver *driver) +{ + int ret; + + DPRINT_INFO(VMBUS, "+++++++ HV Driver version = %s +++++++", + HV_DRV_VERSION); + DPRINT_INFO(VMBUS, "+++++++ Vmbus supported version = %d +++++++", + VMBUS_REVISION_NUMBER); + DPRINT_INFO(VMBUS, "+++++++ Vmbus using SINT %d +++++++", + VMBUS_MESSAGE_SINT); + DPRINT_DBG(VMBUS, "sizeof(vmbus_channel_packet_page_buffer)=%zd, " + "sizeof(VMBUS_CHANNEL_PACKET_MULITPAGE_BUFFER)=%zd", + sizeof(struct vmbus_channel_packet_page_buffer), + sizeof(struct vmbus_channel_packet_multipage_buffer)); + + driver->name = gDriverName; + memcpy(&driver->deviceType, &gVmbusDeviceType, sizeof(struct hv_guid)); + + /* Setup dispatch table */ + driver->OnDeviceAdd = VmbusOnDeviceAdd; + driver->OnDeviceRemove = VmbusOnDeviceRemove; + driver->OnCleanup = VmbusOnCleanup; + + /* Hypervisor initialization...setup hypercall page..etc */ + ret = hv_init(); + if (ret != 0) + DPRINT_ERR(VMBUS, "Unable to initialize the hypervisor - 0x%x", + ret); + gDriver = driver; + + return ret; +} + static void get_channel_info(struct hv_device *device, struct hv_device_info *info) { -- cgit v1.2.3 From 6c884555f23d0c73f7e71ce977ee4dd882532c0f Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 2 Dec 2010 12:04:00 -0800 Subject: Staging: hv: call VmbusInitialize directly from vmbus_bus_init() No need to pass a function pointer to a function in the same file. Cc: Haiyang Zhang Cc: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/vmbus_api.h | 1 - drivers/staging/hv/vmbus_drv.c | 8 ++++---- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/staging/hv/vmbus_api.h b/drivers/staging/hv/vmbus_api.h index 45c9b9a55528..bb71cd22bce9 100644 --- a/drivers/staging/hv/vmbus_api.h +++ b/drivers/staging/hv/vmbus_api.h @@ -115,7 +115,6 @@ struct hv_device { void *Extension; }; -int VmbusInitialize(struct hv_driver *drv); int vmbus_on_isr(struct hv_driver *drv); void vmbus_on_msg_dpc(struct hv_driver *drv); void vmbus_on_event_dpc(struct hv_driver *drv); diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c index 9c2325dff1c0..01b9a3dc00d6 100644 --- a/drivers/staging/hv/vmbus_drv.c +++ b/drivers/staging/hv/vmbus_drv.c @@ -298,7 +298,7 @@ int vmbus_on_isr(struct hv_driver *drv) /* * VmbusInitialize - Main entry point */ -int VmbusInitialize(struct hv_driver *driver) +static int VmbusInitialize(struct hv_driver *driver) { int ret; @@ -491,7 +491,7 @@ static ssize_t vmbus_show_device_attr(struct device *dev, * - setup the vmbus root device * - retrieve the channel offers */ -static int vmbus_bus_init(int (*drv_init)(struct hv_driver *drv)) +static int vmbus_bus_init(void) { struct vmbus_driver_context *vmbus_drv_ctx = &g_vmbus_drv; struct hv_driver *driver = &g_vmbus_drv.drv_obj; @@ -500,7 +500,7 @@ static int vmbus_bus_init(int (*drv_init)(struct hv_driver *drv)) unsigned int vector; /* Call to bus driver to initialize */ - ret = drv_init(driver); + ret = VmbusInitialize(driver); if (ret != 0) { DPRINT_ERR(VMBUS_DRV, "Unable to initialize vmbus (%d)", ret); goto cleanup; @@ -1107,7 +1107,7 @@ static int __init vmbus_init(void) if (!dmi_check_system(microsoft_hv_dmi_table)) return -ENODEV; - return vmbus_bus_init(VmbusInitialize); + return vmbus_bus_init(); } static void __exit vmbus_exit(void) -- cgit v1.2.3 From 0bdb250c69251499f53a4ac6f9dae117da490696 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 2 Dec 2010 12:04:59 -0800 Subject: Staging: hv: remove gDriver variable It's only set and never used anymore, so remove it. Gotta love static variables with a "global" hungarian notatation on the name... Cc: Haiyang Zhang Cc: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/vmbus_drv.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c index 01b9a3dc00d6..b18fa53f3a24 100644 --- a/drivers/staging/hv/vmbus_drv.c +++ b/drivers/staging/hv/vmbus_drv.c @@ -145,7 +145,6 @@ static const struct hv_guid gVmbusDeviceId = { } }; -static struct hv_driver *gDriver; /* vmbus driver object */ static struct hv_device *gDevice; /* vmbus root device */ /* @@ -326,8 +325,6 @@ static int VmbusInitialize(struct hv_driver *driver) if (ret != 0) DPRINT_ERR(VMBUS, "Unable to initialize the hypervisor - 0x%x", ret); - gDriver = driver; - return ret; } -- cgit v1.2.3 From 6d26e38fa2085ab3ba37a52e34caf46f8e049544 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 2 Dec 2010 12:08:08 -0800 Subject: Staging: hv: merge VmbusInitialize into vmbus_bus_init No need to have two functions for this. Cc: Haiyang Zhang Cc: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/vmbus_drv.c | 60 ++++++++++++++++-------------------------- 1 file changed, 23 insertions(+), 37 deletions(-) diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c index b18fa53f3a24..3f5810a7a699 100644 --- a/drivers/staging/hv/vmbus_drv.c +++ b/drivers/staging/hv/vmbus_drv.c @@ -294,40 +294,6 @@ int vmbus_on_isr(struct hv_driver *drv) return ret; } -/* - * VmbusInitialize - Main entry point - */ -static int VmbusInitialize(struct hv_driver *driver) -{ - int ret; - - DPRINT_INFO(VMBUS, "+++++++ HV Driver version = %s +++++++", - HV_DRV_VERSION); - DPRINT_INFO(VMBUS, "+++++++ Vmbus supported version = %d +++++++", - VMBUS_REVISION_NUMBER); - DPRINT_INFO(VMBUS, "+++++++ Vmbus using SINT %d +++++++", - VMBUS_MESSAGE_SINT); - DPRINT_DBG(VMBUS, "sizeof(vmbus_channel_packet_page_buffer)=%zd, " - "sizeof(VMBUS_CHANNEL_PACKET_MULITPAGE_BUFFER)=%zd", - sizeof(struct vmbus_channel_packet_page_buffer), - sizeof(struct vmbus_channel_packet_multipage_buffer)); - - driver->name = gDriverName; - memcpy(&driver->deviceType, &gVmbusDeviceType, sizeof(struct hv_guid)); - - /* Setup dispatch table */ - driver->OnDeviceAdd = VmbusOnDeviceAdd; - driver->OnDeviceRemove = VmbusOnDeviceRemove; - driver->OnCleanup = VmbusOnCleanup; - - /* Hypervisor initialization...setup hypercall page..etc */ - ret = hv_init(); - if (ret != 0) - DPRINT_ERR(VMBUS, "Unable to initialize the hypervisor - 0x%x", - ret); - return ret; -} - static void get_channel_info(struct hv_device *device, struct hv_device_info *info) { @@ -496,10 +462,30 @@ static int vmbus_bus_init(void) int ret; unsigned int vector; - /* Call to bus driver to initialize */ - ret = VmbusInitialize(driver); + DPRINT_INFO(VMBUS, "+++++++ HV Driver version = %s +++++++", + HV_DRV_VERSION); + DPRINT_INFO(VMBUS, "+++++++ Vmbus supported version = %d +++++++", + VMBUS_REVISION_NUMBER); + DPRINT_INFO(VMBUS, "+++++++ Vmbus using SINT %d +++++++", + VMBUS_MESSAGE_SINT); + DPRINT_DBG(VMBUS, "sizeof(vmbus_channel_packet_page_buffer)=%zd, " + "sizeof(VMBUS_CHANNEL_PACKET_MULITPAGE_BUFFER)=%zd", + sizeof(struct vmbus_channel_packet_page_buffer), + sizeof(struct vmbus_channel_packet_multipage_buffer)); + + driver->name = gDriverName; + memcpy(&driver->deviceType, &gVmbusDeviceType, sizeof(struct hv_guid)); + + /* Setup dispatch table */ + driver->OnDeviceAdd = VmbusOnDeviceAdd; + driver->OnDeviceRemove = VmbusOnDeviceRemove; + driver->OnCleanup = VmbusOnCleanup; + + /* Hypervisor initialization...setup hypercall page..etc */ + ret = hv_init(); if (ret != 0) { - DPRINT_ERR(VMBUS_DRV, "Unable to initialize vmbus (%d)", ret); + DPRINT_ERR(VMBUS, "Unable to initialize the hypervisor - 0x%x", + ret); goto cleanup; } -- cgit v1.2.3 From cef6dbfa8ef6b8c474e020a24758aa848a2632fa Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 2 Dec 2010 12:11:25 -0800 Subject: Staging: hv: make some vmbus_drv functions static Now that vmbus_drv.c is merged with vmbus.c, some of the newly global functions can now be marked static. Cc: Haiyang Zhang Cc: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/vmbus_api.h | 4 ---- drivers/staging/hv/vmbus_drv.c | 6 +++--- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/drivers/staging/hv/vmbus_api.h b/drivers/staging/hv/vmbus_api.h index bb71cd22bce9..2da3f52610b3 100644 --- a/drivers/staging/hv/vmbus_api.h +++ b/drivers/staging/hv/vmbus_api.h @@ -115,8 +115,4 @@ struct hv_device { void *Extension; }; -int vmbus_on_isr(struct hv_driver *drv); -void vmbus_on_msg_dpc(struct hv_driver *drv); -void vmbus_on_event_dpc(struct hv_driver *drv); - #endif /* _VMBUS_API_H_ */ diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c index 3f5810a7a699..f623b57c59d0 100644 --- a/drivers/staging/hv/vmbus_drv.c +++ b/drivers/staging/hv/vmbus_drv.c @@ -206,7 +206,7 @@ static void VmbusOnCleanup(struct hv_driver *drv) /* * vmbus_on_msg_dpc - DPC routine to handle messages from the hypervisior */ -void vmbus_on_msg_dpc(struct hv_driver *drv) +static void vmbus_on_msg_dpc(struct hv_driver *drv) { int cpu = smp_processor_id(); void *page_addr = hv_context.synic_message_page[cpu]; @@ -253,7 +253,7 @@ void vmbus_on_msg_dpc(struct hv_driver *drv) /* * vmbus_on_event_dpc - DPC routine to handle events from the hypervisior */ -void vmbus_on_event_dpc(struct hv_driver *drv) +static void vmbus_on_event_dpc(struct hv_driver *drv) { /* TODO: Process any events */ VmbusOnEvents(); @@ -262,7 +262,7 @@ void vmbus_on_event_dpc(struct hv_driver *drv) /* * vmbus_on_isr - ISR routine */ -int vmbus_on_isr(struct hv_driver *drv) +static int vmbus_on_isr(struct hv_driver *drv) { int ret = 0; int cpu = smp_processor_id(); -- cgit v1.2.3 From bafbb8df076de1e3b63914473a403fba96b88f3c Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 2 Dec 2010 12:12:46 -0800 Subject: Staging: hv: remove vmbus_on_event_dpc() Just call VmbusOnEvents() as that's all the function did, so we can remove it. Cc: Haiyang Zhang Cc: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/vmbus_drv.c | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c index f623b57c59d0..d794b603bf17 100644 --- a/drivers/staging/hv/vmbus_drv.c +++ b/drivers/staging/hv/vmbus_drv.c @@ -250,15 +250,6 @@ static void vmbus_on_msg_dpc(struct hv_driver *drv) } } -/* - * vmbus_on_event_dpc - DPC routine to handle events from the hypervisior - */ -static void vmbus_on_event_dpc(struct hv_driver *drv) -{ - /* TODO: Process any events */ - VmbusOnEvents(); -} - /* * vmbus_on_isr - ISR routine */ @@ -1039,10 +1030,8 @@ static void vmbus_msg_dpc(unsigned long data) */ static void vmbus_event_dpc(unsigned long data) { - struct hv_driver *driver = (struct hv_driver *)data; - /* Call to bus driver to handle interrupt */ - vmbus_on_event_dpc(driver); + VmbusOnEvents(); } static irqreturn_t vmbus_isr(int irq, void *dev_id) -- cgit v1.2.3 From df880a42dc4086ba7ff16f6ccb255e78fc0dc374 Mon Sep 17 00:00:00 2001 From: Brett Rudley Date: Wed, 1 Dec 2010 15:36:38 -0800 Subject: staging: brcm80211: Remove unused code from osl.h Signed-off-by: Brett Rudley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/include/osl.h | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/drivers/staging/brcm80211/include/osl.h b/drivers/staging/brcm80211/include/osl.h index 662b5197b374..c2fa2975c955 100644 --- a/drivers/staging/brcm80211/include/osl.h +++ b/drivers/staging/brcm80211/include/osl.h @@ -38,22 +38,10 @@ typedef struct osl_dmainfo osldma_t; typedef unsigned int (*osl_rreg_fn_t) (void *ctx, void *reg, unsigned int size); typedef void (*osl_wreg_fn_t) (void *ctx, void *reg, unsigned int val, unsigned int size); -#endif +#endif /* BCMSDIO */ #include -/* -------------------------------------------------------------------------- -** Register manipulation macros. -*/ - #define SET_REG(osh, r, mask, val) W_REG((osh), (r), ((R_REG((osh), r) & ~(mask)) | (val))) -#ifndef AND_REG -#define AND_REG(osh, r, v) W_REG(osh, (r), R_REG(osh, r) & (v)) -#endif /* !AND_REG */ - -#ifndef OR_REG -#define OR_REG(osh, r, v) W_REG(osh, (r), R_REG(osh, r) | (v)) -#endif /* !OR_REG */ - -#endif /* _osl_h_ */ +#endif /* _osl_h_ */ -- cgit v1.2.3 From c523ea78ec9a33586fa7a73859de7c462097cdfc Mon Sep 17 00:00:00 2001 From: Brett Rudley Date: Wed, 1 Dec 2010 15:36:39 -0800 Subject: staging: brcm80211: absorb linux_osl.h into osl.h Move code from linux_osl.h into osl.h and delete linux_osl.h, which created a bunch of checkpatch errors... I fixed most but volatile warnings will have to be dealt with later. Signed-off-by: Brett Rudley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/include/linux_osl.h | 270 -------------------------- drivers/staging/brcm80211/include/osl.h | 261 ++++++++++++++++++++++++- 2 files changed, 259 insertions(+), 272 deletions(-) delete mode 100644 drivers/staging/brcm80211/include/linux_osl.h diff --git a/drivers/staging/brcm80211/include/linux_osl.h b/drivers/staging/brcm80211/include/linux_osl.h deleted file mode 100644 index c2edea4649cb..000000000000 --- a/drivers/staging/brcm80211/include/linux_osl.h +++ /dev/null @@ -1,270 +0,0 @@ -/* - * Copyright (c) 2010 Broadcom Corporation - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef _linux_osl_h_ -#define _linux_osl_h_ - -#include - -extern struct osl_info *osl_attach(void *pdev, uint bustype); -extern void osl_detach(struct osl_info *osh); - -extern u32 g_assert_type; - -#if defined(BCMDBG_ASSERT) -#define ASSERT(exp) \ - do { if (!(exp)) osl_assert(#exp, __FILE__, __LINE__); } while (0) -extern void osl_assert(char *exp, char *file, int line); -#else -#define ASSERT(exp) do {} while (0) -#endif /* defined(BCMDBG_ASSERT) */ - -/* PCI device bus # and slot # */ -#define OSL_PCI_BUS(osh) osl_pci_bus(osh) -#define OSL_PCI_SLOT(osh) osl_pci_slot(osh) -extern uint osl_pci_bus(struct osl_info *osh); -extern uint osl_pci_slot(struct osl_info *osh); - -#define BUS_SWAP32(v) (v) - -extern void *osl_dma_alloc_consistent(struct osl_info *osh, uint size, - u16 align, uint *tot, unsigned long *pap); - -#ifdef BRCM_FULLMAC -#define DMA_ALLOC_CONSISTENT(osh, size, pap, dmah, alignbits) \ - osl_dma_alloc_consistent((osh), (size), (0), (tot), (pap)) -#else -#define DMA_ALLOC_CONSISTENT(osh, size, align, tot, pap, dmah) \ - osl_dma_alloc_consistent((osh), (size), (align), (tot), (pap)) -#endif /* BRCM_FULLMAC */ - -#define DMA_FREE_CONSISTENT(osh, va, size, pa, dmah) \ - osl_dma_free_consistent((osh), (void *)(va), (size), (pa)) -extern void osl_dma_free_consistent(struct osl_info *osh, void *va, - uint size, unsigned long pa); - -/* map/unmap direction */ -#define DMA_TX 1 /* TX direction for DMA */ -#define DMA_RX 2 /* RX direction for DMA */ - -/* map/unmap shared (dma-able) memory */ -#define DMA_MAP(osh, va, size, direction, p, dmah) \ - osl_dma_map((osh), (va), (size), (direction)) -#define DMA_UNMAP(osh, pa, size, direction, p, dmah) \ - osl_dma_unmap((osh), (pa), (size), (direction)) -extern uint osl_dma_map(struct osl_info *osh, void *va, uint size, - int direction); -extern void osl_dma_unmap(struct osl_info *osh, uint pa, uint size, - int direction); - -/* register access macros */ -#if defined(BCMSDIO) -#ifdef BRCM_FULLMAC -#include -#endif -#define OSL_WRITE_REG(osh, r, v) (bcmsdh_reg_write(NULL, (unsigned long)(r), sizeof(*(r)), (v))) -#define OSL_READ_REG(osh, r) (bcmsdh_reg_read(NULL, (unsigned long)(r), sizeof(*(r)))) -#endif - -#if defined(BCMSDIO) -#define SELECT_BUS_WRITE(osh, mmap_op, bus_op) \ - if (((struct osl_pubinfo *)(osh))->mmbus) \ - mmap_op else bus_op -#define SELECT_BUS_READ(osh, mmap_op, bus_op) \ - (((struct osl_pubinfo *)(osh))->mmbus) ? mmap_op : bus_op -#else -#define SELECT_BUS_WRITE(osh, mmap_op, bus_op) mmap_op -#define SELECT_BUS_READ(osh, mmap_op, bus_op) mmap_op -#endif - -/* the largest reasonable packet buffer driver uses for ethernet MTU in bytes */ -#define PKTBUFSZ 2048 /* largest reasonable packet buffer, driver uses for ethernet MTU */ - -#define OSL_SYSUPTIME() ((u32)jiffies * (1000 / HZ)) -#define printf(fmt, args...) printk(fmt , ## args) -#ifdef BRCM_FULLMAC -#include /* for vsn/printf's */ -#include /* for mem*, str* */ -#endif -/* bcopy's: Linux kernel doesn't provide these (anymore) */ -#define bcopy(src, dst, len) memcpy((dst), (src), (len)) - -/* register access macros */ -#if defined(OSLREGOPS) -#else -#ifndef IL_BIGENDIAN -#ifndef __mips__ -#define R_REG(osh, r) (\ - SELECT_BUS_READ(osh, sizeof(*(r)) == sizeof(u8) ? readb((volatile u8*)(r)) : \ - sizeof(*(r)) == sizeof(u16) ? readw((volatile u16*)(r)) : \ - readl((volatile u32*)(r)), OSL_READ_REG(osh, r)) \ -) -#else /* __mips__ */ -#define R_REG(osh, r) (\ - SELECT_BUS_READ(osh, \ - ({ \ - __typeof(*(r)) __osl_v; \ - __asm__ __volatile__("sync"); \ - switch (sizeof(*(r))) { \ - case sizeof(u8): \ - __osl_v = readb((volatile u8*)(r)); \ - break; \ - case sizeof(u16): \ - __osl_v = readw((volatile u16*)(r)); \ - break; \ - case sizeof(u32): \ - __osl_v = \ - readl((volatile u32*)(r)); \ - break; \ - } \ - __asm__ __volatile__("sync"); \ - __osl_v; \ - }), \ - ({ \ - __typeof(*(r)) __osl_v; \ - __asm__ __volatile__("sync"); \ - __osl_v = OSL_READ_REG(osh, r); \ - __asm__ __volatile__("sync"); \ - __osl_v; \ - })) \ -) -#endif /* __mips__ */ - -#define W_REG(osh, r, v) do { \ - SELECT_BUS_WRITE(osh, \ - switch (sizeof(*(r))) { \ - case sizeof(u8): \ - writeb((u8)(v), (volatile u8*)(r)); break; \ - case sizeof(u16): \ - writew((u16)(v), (volatile u16*)(r)); break; \ - case sizeof(u32): \ - writel((u32)(v), (volatile u32*)(r)); break; \ - }, \ - (OSL_WRITE_REG(osh, r, v))); \ - } while (0) -#else /* IL_BIGENDIAN */ -#define R_REG(osh, r) (\ - SELECT_BUS_READ(osh, \ - ({ \ - __typeof(*(r)) __osl_v; \ - switch (sizeof(*(r))) { \ - case sizeof(u8): \ - __osl_v = \ - readb((volatile u8*)((r)^3)); \ - break; \ - case sizeof(u16): \ - __osl_v = \ - readw((volatile u16*)((r)^2)); \ - break; \ - case sizeof(u32): \ - __osl_v = readl((volatile u32*)(r)); \ - break; \ - } \ - __osl_v; \ - }), \ - OSL_READ_REG(osh, r)) \ -) -#define W_REG(osh, r, v) do { \ - SELECT_BUS_WRITE(osh, \ - switch (sizeof(*(r))) { \ - case sizeof(u8): \ - writeb((u8)(v), \ - (volatile u8*)((r)^3)); break; \ - case sizeof(u16): \ - writew((u16)(v), \ - (volatile u16*)((r)^2)); break; \ - case sizeof(u32): \ - writel((u32)(v), \ - (volatile u32*)(r)); break; \ - }, \ - (OSL_WRITE_REG(osh, r, v))); \ - } while (0) -#endif /* IL_BIGENDIAN */ - -#endif /* OSLREGOPS */ - -#define AND_REG(osh, r, v) W_REG(osh, (r), R_REG(osh, r) & (v)) -#define OR_REG(osh, r, v) W_REG(osh, (r), R_REG(osh, r) | (v)) - -#define bcopy(src, dst, len) memcpy((dst), (src), (len)) - -/* uncached/cached virtual address */ -#ifdef __mips__ -#include -#define OSL_UNCACHED(va) ((void *)KSEG1ADDR((va))) -#define OSL_CACHED(va) ((void *)KSEG0ADDR((va))) -#else -#define OSL_UNCACHED(va) ((void *)va) -#define OSL_CACHED(va) ((void *)va) -#endif /* mips */ - -/* map/unmap physical to virtual I/O */ -#if !defined(CONFIG_MMC_MSM7X00A) -#define REG_MAP(pa, size) ioremap_nocache((unsigned long)(pa), (unsigned long)(size)) -#else -#define REG_MAP(pa, size) (void *)(0) -#endif /* !defined(CONFIG_MMC_MSM7X00A */ -#define REG_UNMAP(va) iounmap((va)) - -#define R_SM(r) (*(r)) -#define W_SM(r, v) (*(r) = (v)) -#define BZERO_SM(r, len) memset((r), '\0', (len)) - -/* packet primitives */ -#define PKTGET(osh, len, send) osl_pktget((osh), (len)) -#define PKTFREE(osh, skb, send) osl_pktfree((osh), (skb), (send)) - -extern void *osl_pktget(struct osl_info *osh, uint len); -extern void osl_pktfree(struct osl_info *osh, void *skb, bool send); - -#ifdef BRCM_FULLMAC -static inline void * -osl_pkt_frmnative(struct osl_pubinfo *osh, struct sk_buff *skb) -{ - struct sk_buff *nskb; - - for (nskb = skb; nskb; nskb = nskb->next) - osh->pktalloced++; - - return (void *)skb; -} -#define PKTFRMNATIVE(osh, skb) \ - osl_pkt_frmnative(((struct osl_pubinfo *)osh), (struct sk_buff*)(skb)) - -static inline struct sk_buff * -osl_pkt_tonative(struct osl_pubinfo *osh, void *pkt) -{ - struct sk_buff *nskb; - - for (nskb = (struct sk_buff *)pkt; nskb; nskb = nskb->next) - osh->pktalloced--; - - return (struct sk_buff *)pkt; -} -#define PKTTONATIVE(osh, pkt) \ - osl_pkt_tonative((struct osl_pubinfo *)(osh), (pkt)) -#else /* !BRCM_FULLMAC */ -#define PKTSETSKIPCT(osh, skb) -#define PKTCLRSKIPCT(osh, skb) -#define PKTSKIPCT(osh, skb) -#endif /* BRCM_FULLMAC */ - -#define PKTSUMNEEDED(skb) (((struct sk_buff *)(skb))->ip_summed == CHECKSUM_PARTIAL) -#define PKTSETSUMGOOD(skb, x) (((struct sk_buff *)(skb))->ip_summed = \ - ((x) ? CHECKSUM_UNNECESSARY : CHECKSUM_NONE)) -/* PKTSETSUMNEEDED and PKTSUMGOOD are not possible because skb->ip_summed is overloaded */ - -#endif /* _linux_osl_h_ */ diff --git a/drivers/staging/brcm80211/include/osl.h b/drivers/staging/brcm80211/include/osl.h index c2fa2975c955..2368c80db60a 100644 --- a/drivers/staging/brcm80211/include/osl.h +++ b/drivers/staging/brcm80211/include/osl.h @@ -40,8 +40,265 @@ typedef void (*osl_wreg_fn_t) (void *ctx, void *reg, unsigned int val, unsigned int size); #endif /* BCMSDIO */ -#include +#include -#define SET_REG(osh, r, mask, val) W_REG((osh), (r), ((R_REG((osh), r) & ~(mask)) | (val))) +extern struct osl_info *osl_attach(void *pdev, uint bustype); +extern void osl_detach(struct osl_info *osh); + +extern u32 g_assert_type; + +#if defined(BCMDBG_ASSERT) +#define ASSERT(exp) \ + do { if (!(exp)) osl_assert(#exp, __FILE__, __LINE__); } while (0) +extern void osl_assert(char *exp, char *file, int line); +#else +#define ASSERT(exp) do {} while (0) +#endif /* defined(BCMDBG_ASSERT) */ + +/* PCI device bus # and slot # */ +#define OSL_PCI_BUS(osh) osl_pci_bus(osh) +#define OSL_PCI_SLOT(osh) osl_pci_slot(osh) +extern uint osl_pci_bus(struct osl_info *osh); +extern uint osl_pci_slot(struct osl_info *osh); + +#define BUS_SWAP32(v) (v) + +extern void *osl_dma_alloc_consistent(struct osl_info *osh, uint size, + u16 align, uint *tot, unsigned long *pap); + +#ifdef BRCM_FULLMAC +#define DMA_ALLOC_CONSISTENT(osh, size, pap, dmah, alignbits) \ + osl_dma_alloc_consistent((osh), (size), (0), (tot), (pap)) +#else +#define DMA_ALLOC_CONSISTENT(osh, size, align, tot, pap, dmah) \ + osl_dma_alloc_consistent((osh), (size), (align), (tot), (pap)) +#endif /* BRCM_FULLMAC */ + +#define DMA_FREE_CONSISTENT(osh, va, size, pa, dmah) \ + osl_dma_free_consistent((osh), (void *)(va), (size), (pa)) +extern void osl_dma_free_consistent(struct osl_info *osh, void *va, + uint size, unsigned long pa); + +/* map/unmap direction */ +#define DMA_TX 1 /* TX direction for DMA */ +#define DMA_RX 2 /* RX direction for DMA */ + +/* map/unmap shared (dma-able) memory */ +#define DMA_MAP(osh, va, size, direction, p, dmah) \ + osl_dma_map((osh), (va), (size), (direction)) +#define DMA_UNMAP(osh, pa, size, direction, p, dmah) \ + osl_dma_unmap((osh), (pa), (size), (direction)) +extern uint osl_dma_map(struct osl_info *osh, void *va, uint size, + int direction); +extern void osl_dma_unmap(struct osl_info *osh, uint pa, uint size, + int direction); + +/* register access macros */ +#if defined(BCMSDIO) +#ifdef BRCM_FULLMAC +#include +#endif +#define OSL_WRITE_REG(osh, r, v) \ + (bcmsdh_reg_write(NULL, (unsigned long)(r), sizeof(*(r)), (v))) +#define OSL_READ_REG(osh, r) \ + (bcmsdh_reg_read(NULL, (unsigned long)(r), sizeof(*(r)))) +#endif + +#if defined(BCMSDIO) +#define SELECT_BUS_WRITE(osh, mmap_op, bus_op) \ + if (((struct osl_pubinfo *)(osh))->mmbus) \ + mmap_op else bus_op +#define SELECT_BUS_READ(osh, mmap_op, bus_op) \ + (((struct osl_pubinfo *)(osh))->mmbus) ? mmap_op : bus_op +#else +#define SELECT_BUS_WRITE(osh, mmap_op, bus_op) mmap_op +#define SELECT_BUS_READ(osh, mmap_op, bus_op) mmap_op +#endif + +/* the largest reasonable packet buffer driver uses for ethernet MTU in bytes */ +#define PKTBUFSZ 2048 + +#define OSL_SYSUPTIME() ((u32)jiffies * (1000 / HZ)) +#define printf(fmt, args...) printk(fmt , ## args) +#ifdef BRCM_FULLMAC +#include /* for vsn/printf's */ +#include /* for mem*, str* */ +#endif +/* bcopy's: Linux kernel doesn't provide these (anymore) */ +#define bcopy(src, dst, len) memcpy((dst), (src), (len)) + +/* register access macros */ +#if defined(OSLREGOPS) +#else +#ifndef IL_BIGENDIAN +#ifndef __mips__ +#define R_REG(osh, r) (\ + SELECT_BUS_READ(osh, sizeof(*(r)) == sizeof(u8) ? \ + readb((volatile u8*)(r)) : \ + sizeof(*(r)) == sizeof(u16) ? readw((volatile u16*)(r)) : \ + readl((volatile u32*)(r)), OSL_READ_REG(osh, r)) \ +) +#else /* __mips__ */ +#define R_REG(osh, r) (\ + SELECT_BUS_READ(osh, \ + ({ \ + __typeof(*(r)) __osl_v; \ + __asm__ __volatile__("sync"); \ + switch (sizeof(*(r))) { \ + case sizeof(u8): \ + __osl_v = readb((volatile u8*)(r)); \ + break; \ + case sizeof(u16): \ + __osl_v = readw((volatile u16*)(r)); \ + break; \ + case sizeof(u32): \ + __osl_v = \ + readl((volatile u32*)(r)); \ + break; \ + } \ + __asm__ __volatile__("sync"); \ + __osl_v; \ + }), \ + ({ \ + __typeof(*(r)) __osl_v; \ + __asm__ __volatile__("sync"); \ + __osl_v = OSL_READ_REG(osh, r); \ + __asm__ __volatile__("sync"); \ + __osl_v; \ + })) \ +) +#endif /* __mips__ */ + +#define W_REG(osh, r, v) do { \ + SELECT_BUS_WRITE(osh, \ + switch (sizeof(*(r))) { \ + case sizeof(u8): \ + writeb((u8)(v), (volatile u8*)(r)); break; \ + case sizeof(u16): \ + writew((u16)(v), (volatile u16*)(r)); break; \ + case sizeof(u32): \ + writel((u32)(v), (volatile u32*)(r)); break; \ + }, \ + (OSL_WRITE_REG(osh, r, v))); \ + } while (0) +#else /* IL_BIGENDIAN */ +#define R_REG(osh, r) (\ + SELECT_BUS_READ(osh, \ + ({ \ + __typeof(*(r)) __osl_v; \ + switch (sizeof(*(r))) { \ + case sizeof(u8): \ + __osl_v = \ + readb((volatile u8*)((r)^3)); \ + break; \ + case sizeof(u16): \ + __osl_v = \ + readw((volatile u16*)((r)^2)); \ + break; \ + case sizeof(u32): \ + __osl_v = readl((volatile u32*)(r)); \ + break; \ + } \ + __osl_v; \ + }), \ + OSL_READ_REG(osh, r)) \ +) +#define W_REG(osh, r, v) do { \ + SELECT_BUS_WRITE(osh, \ + switch (sizeof(*(r))) { \ + case sizeof(u8): \ + writeb((u8)(v), \ + (volatile u8*)((r)^3)); break; \ + case sizeof(u16): \ + writew((u16)(v), \ + (volatile u16*)((r)^2)); break; \ + case sizeof(u32): \ + writel((u32)(v), \ + (volatile u32*)(r)); break; \ + }, \ + (OSL_WRITE_REG(osh, r, v))); \ + } while (0) +#endif /* IL_BIGENDIAN */ + +#endif /* OSLREGOPS */ + +#define AND_REG(osh, r, v) W_REG(osh, (r), R_REG(osh, r) & (v)) +#define OR_REG(osh, r, v) W_REG(osh, (r), R_REG(osh, r) | (v)) + +#define bcopy(src, dst, len) memcpy((dst), (src), (len)) + +/* uncached/cached virtual address */ +#ifdef __mips__ +#include +#define OSL_UNCACHED(va) ((void *)KSEG1ADDR((va))) +#define OSL_CACHED(va) ((void *)KSEG0ADDR((va))) +#else +#define OSL_UNCACHED(va) ((void *)va) +#define OSL_CACHED(va) ((void *)va) +#endif /* mips */ + +/* map/unmap physical to virtual I/O */ +#if !defined(CONFIG_MMC_MSM7X00A) +#define REG_MAP(pa, size) ioremap_nocache((unsigned long)(pa), \ + (unsigned long)(size)) +#else +#define REG_MAP(pa, size) (void *)(0) +#endif /* !defined(CONFIG_MMC_MSM7X00A */ +#define REG_UNMAP(va) iounmap((va)) + +#define R_SM(r) (*(r)) +#define W_SM(r, v) (*(r) = (v)) +#define BZERO_SM(r, len) memset((r), '\0', (len)) + +/* packet primitives */ +#define PKTGET(osh, len, send) osl_pktget((osh), (len)) +#define PKTFREE(osh, skb, send) osl_pktfree((osh), (skb), (send)) + +extern void *osl_pktget(struct osl_info *osh, uint len); +extern void osl_pktfree(struct osl_info *osh, void *skb, bool send); + +#ifdef BRCM_FULLMAC +static inline void * +osl_pkt_frmnative(struct osl_pubinfo *osh, struct sk_buff *skb) +{ + struct sk_buff *nskb; + + for (nskb = skb; nskb; nskb = nskb->next) + osh->pktalloced++; + + return (void *)skb; +} +#define PKTFRMNATIVE(osh, skb) \ + osl_pkt_frmnative(((struct osl_pubinfo *)osh), (struct sk_buff*)(skb)) + +static inline struct sk_buff * +osl_pkt_tonative(struct osl_pubinfo *osh, void *pkt) +{ + struct sk_buff *nskb; + + for (nskb = (struct sk_buff *)pkt; nskb; nskb = nskb->next) + osh->pktalloced--; + + return (struct sk_buff *)pkt; +} +#define PKTTONATIVE(osh, pkt) \ + osl_pkt_tonative((struct osl_pubinfo *)(osh), (pkt)) +#else /* !BRCM_FULLMAC */ +#define PKTSETSKIPCT(osh, skb) +#define PKTCLRSKIPCT(osh, skb) +#define PKTSKIPCT(osh, skb) +#endif /* BRCM_FULLMAC */ + +#define PKTSUMNEEDED(skb) \ + (((struct sk_buff *)(skb))->ip_summed == CHECKSUM_PARTIAL) +#define PKTSETSUMGOOD(skb, x) \ + (((struct sk_buff *)(skb))->ip_summed = \ + ((x) ? CHECKSUM_UNNECESSARY : CHECKSUM_NONE)) +/* PKTSETSUMNEEDED and PKTSUMGOOD are not possible because + skb->ip_summed is overloaded */ + + +#define SET_REG(osh, r, mask, val) \ + W_REG((osh), (r), ((R_REG((osh), r) & ~(mask)) | (val))) #endif /* _osl_h_ */ -- cgit v1.2.3 From 92246bcbd7730eaaec0c29a2adc1cb4b4451ed9e Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Thu, 2 Dec 2010 15:44:50 +0100 Subject: staging: brcm80211: remove redundant CHIPTYPE macro The CHIPTYPE macro simply expands to the macro argument so it is redundant and as such removed. Reviewed-by: Roland Vossen Signed-off-by: Arend van Spriel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/include/bcmdefs.h | 1 - drivers/staging/brcm80211/util/siutils.c | 26 +++++++++++++------------- 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/drivers/staging/brcm80211/include/bcmdefs.h b/drivers/staging/brcm80211/include/bcmdefs.h index 4ce4486a19a1..350bd6d526a4 100644 --- a/drivers/staging/brcm80211/include/bcmdefs.h +++ b/drivers/staging/brcm80211/include/bcmdefs.h @@ -51,7 +51,6 @@ #define SPI_BUS 6 /* gSPI target */ #define RPC_BUS 7 /* RPC target */ -#define CHIPTYPE(bus) (bus) #define CHIPID(chip) (chip) #define CHIPREV(rev) (rev) diff --git a/drivers/staging/brcm80211/util/siutils.c b/drivers/staging/brcm80211/util/siutils.c index 33a42f672af8..da35edd2d7b5 100644 --- a/drivers/staging/brcm80211/util/siutils.c +++ b/drivers/staging/brcm80211/util/siutils.c @@ -568,7 +568,7 @@ static si_info_t *si_doattach(si_info_t *sii, uint devid, struct osl_info *osh, sih->issim = IS_SIM(sih->chippkg); /* scan for cores */ - if (CHIPTYPE(sii->pub.socitype) == SOCI_AI) { + if (sii->pub.socitype == SOCI_AI) { SI_MSG(("Found chip type AI (0x%08x)\n", w)); /* pass chipc address instead of original core base */ ai_scan(&sii->pub, (void *)cc, devid); @@ -765,7 +765,7 @@ void si_deregister_intr_callback(si_t *sih) uint si_flag(si_t *sih) { - if (CHIPTYPE(sih->socitype) == SOCI_AI) + if (sih->socitype == SOCI_AI) return ai_flag(sih); else { ASSERT(0); @@ -775,7 +775,7 @@ uint si_flag(si_t *sih) void si_setint(si_t *sih, int siflag) { - if (CHIPTYPE(sih->socitype) == SOCI_AI) + if (sih->socitype == SOCI_AI) ai_setint(sih, siflag); else ASSERT(0); @@ -807,7 +807,7 @@ bool si_backplane64(si_t *sih) #ifndef BCMSDIO uint si_corerev(si_t *sih) { - if (CHIPTYPE(sih->socitype) == SOCI_AI) + if (sih->socitype == SOCI_AI) return ai_corerev(sih); else { ASSERT(0); @@ -850,7 +850,7 @@ void *si_setcore(si_t *sih, uint coreid, uint coreunit) if (!GOODIDX(idx)) return NULL; - if (CHIPTYPE(sih->socitype) == SOCI_AI) + if (sih->socitype == SOCI_AI) return ai_setcoreidx(sih, idx); else { #ifdef BCMSDIO @@ -865,7 +865,7 @@ void *si_setcore(si_t *sih, uint coreid, uint coreunit) #ifndef BCMSDIO void *si_setcoreidx(si_t *sih, uint coreidx) { - if (CHIPTYPE(sih->socitype) == SOCI_AI) + if (sih->socitype == SOCI_AI) return ai_setcoreidx(sih, coreidx); else { ASSERT(0); @@ -917,7 +917,7 @@ void si_restore_core(si_t *sih, uint coreid, uint intr_val) u32 si_core_cflags(si_t *sih, u32 mask, u32 val) { - if (CHIPTYPE(sih->socitype) == SOCI_AI) + if (sih->socitype == SOCI_AI) return ai_core_cflags(sih, mask, val); else { ASSERT(0); @@ -927,7 +927,7 @@ u32 si_core_cflags(si_t *sih, u32 mask, u32 val) u32 si_core_sflags(si_t *sih, u32 mask, u32 val) { - if (CHIPTYPE(sih->socitype) == SOCI_AI) + if (sih->socitype == SOCI_AI) return ai_core_sflags(sih, mask, val); else { ASSERT(0); @@ -937,7 +937,7 @@ u32 si_core_sflags(si_t *sih, u32 mask, u32 val) bool si_iscoreup(si_t *sih) { - if (CHIPTYPE(sih->socitype) == SOCI_AI) + if (sih->socitype == SOCI_AI) return ai_iscoreup(sih); else { #ifdef BCMSDIO @@ -952,7 +952,7 @@ bool si_iscoreup(si_t *sih) void si_write_wrapperreg(si_t *sih, u32 offset, u32 val) { /* only for 4319, no requirement for SOCI_SB */ - if (CHIPTYPE(sih->socitype) == SOCI_AI) { + if (sih->socitype == SOCI_AI) { ai_write_wrap_reg(sih, offset, val); } } @@ -960,7 +960,7 @@ void si_write_wrapperreg(si_t *sih, u32 offset, u32 val) uint si_corereg(si_t *sih, uint coreidx, uint regoff, uint mask, uint val) { - if (CHIPTYPE(sih->socitype) == SOCI_AI) + if (sih->socitype == SOCI_AI) return ai_corereg(sih, coreidx, regoff, mask, val); else { #ifdef BCMSDIO @@ -975,7 +975,7 @@ uint si_corereg(si_t *sih, uint coreidx, uint regoff, uint mask, uint val) void si_core_disable(si_t *sih, u32 bits) { - if (CHIPTYPE(sih->socitype) == SOCI_AI) + if (sih->socitype == SOCI_AI) ai_core_disable(sih, bits); #ifdef BCMSDIO else @@ -985,7 +985,7 @@ void si_core_disable(si_t *sih, u32 bits) void si_core_reset(si_t *sih, u32 bits, u32 resetbits) { - if (CHIPTYPE(sih->socitype) == SOCI_AI) + if (sih->socitype == SOCI_AI) ai_core_reset(sih, bits, resetbits); #ifdef BCMSDIO else -- cgit v1.2.3 From dfa26436109d06f233a0ad735731cfb2d0c6ab5a Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Thu, 2 Dec 2010 15:44:51 +0100 Subject: staging: brcm80211: remove redundant CHIPID macro The CHIPID macro simply expands to the macro argument so it is redundant and as such removed. Reviewed-by: Roland Vossen Signed-off-by: Arend van Spriel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/include/bcmdefs.h | 1 - drivers/staging/brcm80211/phy/wlc_phy_cmn.c | 18 +++--- drivers/staging/brcm80211/phy/wlc_phy_n.c | 52 ++++++++--------- drivers/staging/brcm80211/sys/wlc_bmac.c | 24 ++++---- drivers/staging/brcm80211/sys/wlc_mac80211.c | 8 +-- drivers/staging/brcm80211/util/aiutils.c | 2 +- drivers/staging/brcm80211/util/bcmotp.c | 6 +- drivers/staging/brcm80211/util/hndpmu.c | 86 ++++++++++++++-------------- drivers/staging/brcm80211/util/sbutils.c | 2 +- drivers/staging/brcm80211/util/siutils.c | 22 +++---- 10 files changed, 110 insertions(+), 111 deletions(-) diff --git a/drivers/staging/brcm80211/include/bcmdefs.h b/drivers/staging/brcm80211/include/bcmdefs.h index 350bd6d526a4..82356129caa5 100644 --- a/drivers/staging/brcm80211/include/bcmdefs.h +++ b/drivers/staging/brcm80211/include/bcmdefs.h @@ -51,7 +51,6 @@ #define SPI_BUS 6 /* gSPI target */ #define RPC_BUS 7 /* RPC target */ -#define CHIPID(chip) (chip) #define CHIPREV(rev) (rev) /* Defines for DMA Address Width - Shared between OSL and HNDDMA */ diff --git a/drivers/staging/brcm80211/phy/wlc_phy_cmn.c b/drivers/staging/brcm80211/phy/wlc_phy_cmn.c index b223433482f1..3bed37cb59b8 100644 --- a/drivers/staging/brcm80211/phy/wlc_phy_cmn.c +++ b/drivers/staging/brcm80211/phy/wlc_phy_cmn.c @@ -1085,8 +1085,8 @@ wlc_phy_table_addr(phy_info_t *pi, uint tbl_id, uint tbl_offset, pi->tbl_data_hi = tblDataHi; pi->tbl_data_lo = tblDataLo; - if ((CHIPID(pi->sh->chip) == BCM43224_CHIP_ID || - CHIPID(pi->sh->chip) == BCM43421_CHIP_ID) && + if ((pi->sh->chip == BCM43224_CHIP_ID || + pi->sh->chip == BCM43421_CHIP_ID) && (pi->sh->chiprev == 1)) { pi->tbl_addr = tblAddr; pi->tbl_save_id = tbl_id; @@ -1098,8 +1098,8 @@ void wlc_phy_table_data_write(phy_info_t *pi, uint width, u32 val) { ASSERT((width == 8) || (width == 16) || (width == 32)); - if ((CHIPID(pi->sh->chip) == BCM43224_CHIP_ID || - CHIPID(pi->sh->chip) == BCM43421_CHIP_ID) && + if ((pi->sh->chip == BCM43224_CHIP_ID || + pi->sh->chip == BCM43421_CHIP_ID) && (pi->sh->chiprev == 1) && (pi->tbl_save_id == NPHY_TBL_ID_ANTSWCTRLLUT)) { read_phy_reg(pi, pi->tbl_data_lo); @@ -1137,8 +1137,8 @@ wlc_phy_write_table(phy_info_t *pi, const phytbl_info_t *ptbl_info, for (idx = 0; idx < ptbl_info->tbl_len; idx++) { - if ((CHIPID(pi->sh->chip) == BCM43224_CHIP_ID || - CHIPID(pi->sh->chip) == BCM43421_CHIP_ID) && + if ((pi->sh->chip == BCM43224_CHIP_ID || + pi->sh->chip == BCM43421_CHIP_ID) && (pi->sh->chiprev == 1) && (tbl_id == NPHY_TBL_ID_ANTSWCTRLLUT)) { read_phy_reg(pi, tblDataLo); @@ -1180,8 +1180,8 @@ wlc_phy_read_table(phy_info_t *pi, const phytbl_info_t *ptbl_info, for (idx = 0; idx < ptbl_info->tbl_len; idx++) { - if ((CHIPID(pi->sh->chip) == BCM43224_CHIP_ID || - CHIPID(pi->sh->chip) == BCM43421_CHIP_ID) && + if ((pi->sh->chip == BCM43224_CHIP_ID || + pi->sh->chip == BCM43421_CHIP_ID) && (pi->sh->chiprev == 1)) { (void)read_phy_reg(pi, tblDataLo); @@ -3330,7 +3330,7 @@ const u8 *wlc_phy_get_ofdm_rate_lookup(void) void wlc_lcnphy_epa_switch(phy_info_t *pi, bool mode) { - if ((CHIPID(pi->sh->chip) == BCM4313_CHIP_ID) && + if ((pi->sh->chip == BCM4313_CHIP_ID) && (pi->sh->boardflags & BFL_FEM)) { if (mode) { u16 txant = 0; diff --git a/drivers/staging/brcm80211/phy/wlc_phy_n.c b/drivers/staging/brcm80211/phy/wlc_phy_n.c index c328de56e59a..c6cce8de1aee 100644 --- a/drivers/staging/brcm80211/phy/wlc_phy_n.c +++ b/drivers/staging/brcm80211/phy/wlc_phy_n.c @@ -14559,7 +14559,7 @@ void WLBANDINITFN(wlc_phy_init_nphy) (phy_info_t *pi) } } - if ((!PHY_IPA(pi)) && (CHIPID(pi->sh->chip) == BCM5357_CHIP_ID)) { + if ((!PHY_IPA(pi)) && (pi->sh->chip == BCM5357_CHIP_ID)) { si_pmu_chipcontrol(pi->sh->sih, 1, CCTRL5357_EXTPA, CCTRL5357_EXTPA); } @@ -17604,7 +17604,7 @@ static void wlc_phy_radio_postinit_2057(phy_info_t *pi) mod_radio_reg(pi, RADIO_2057_XTALPUOVR_PINCTRL, 0x1, 0x1); - if (CHIPID(pi->sh->chip) == !BCM6362_CHIP_ID) { + if (pi->sh->chip == !BCM6362_CHIP_ID) { mod_radio_reg(pi, RADIO_2057_XTALPUOVR_PINCTRL, 0x2, 0x2); } @@ -18012,8 +18012,8 @@ wlc_phy_chanspec_radio2056_setup(phy_info_t *pi, write_radio_reg(pi, RADIO_2056_SYN_PLL_LOOPFILTER2 | RADIO_2056_SYN, 0x1f); - if ((CHIPID(pi->sh->chip) == BCM4716_CHIP_ID) || - (CHIPID(pi->sh->chip) == BCM47162_CHIP_ID)) { + if ((pi->sh->chip == BCM4716_CHIP_ID) || + (pi->sh->chip == BCM47162_CHIP_ID)) { write_radio_reg(pi, RADIO_2056_SYN_PLL_LOOPFILTER4 | @@ -18075,8 +18075,8 @@ wlc_phy_chanspec_radio2056_setup(phy_info_t *pi, WRITE_RADIO_REG2(pi, RADIO_2056, TX, core, PADG_IDAC, 0xcc); - if ((CHIPID(pi->sh->chip) == BCM4716_CHIP_ID) || - (CHIPID(pi->sh->chip) == + if ((pi->sh->chip == BCM4716_CHIP_ID) || + (pi->sh->chip == BCM47162_CHIP_ID)) { bias = 0x40; cascbias = 0x45; @@ -18088,11 +18088,11 @@ wlc_phy_chanspec_radio2056_setup(phy_info_t *pi, bias = 0x25; cascbias = 0x20; - if ((CHIPID(pi->sh->chip) == + if ((pi->sh->chip == BCM43224_CHIP_ID) - || (CHIPID(pi->sh->chip) == + || (pi->sh->chip == BCM43225_CHIP_ID) - || (CHIPID(pi->sh->chip) == + || (pi->sh->chip == BCM43421_CHIP_ID)) { if (pi->sh->chippkg == BCM43224_FAB_SMIC) { @@ -18203,9 +18203,9 @@ wlc_phy_chanspec_radio2056_setup(phy_info_t *pi, cascbias = 0x30; - if ((CHIPID(pi->sh->chip) == BCM43224_CHIP_ID) || - (CHIPID(pi->sh->chip) == BCM43225_CHIP_ID) || - (CHIPID(pi->sh->chip) == BCM43421_CHIP_ID)) { + if ((pi->sh->chip == BCM43224_CHIP_ID) || + (pi->sh->chip == BCM43225_CHIP_ID) || + (pi->sh->chip == BCM43421_CHIP_ID)) { if (pi->sh->chippkg == BCM43224_FAB_SMIC) { cascbias = 0x35; } @@ -18932,7 +18932,7 @@ static void wlc_phy_spurwar_nphy(phy_info_t *pi) case 38: case 102: case 118: - if ((CHIPID(pi->sh->chip) == BCM4716_CHIP_ID) && + if ((pi->sh->chip == BCM4716_CHIP_ID) && (pi->sh->chippkg == BCM4717_PKG_ID)) { nphy_adj_tone_id_buf[0] = 32; nphy_adj_noise_var_buf[0] = 0x21f; @@ -19067,7 +19067,7 @@ wlc_phy_chanspec_nphy_setup(phy_info_t *pi, chanspec_t chanspec, if (pi->nphy_aband_spurwar_en && ((val == 38) || (val == 102) || (val == 118))) { - if ((CHIPID(pi->sh->chip) == + if ((pi->sh->chip == BCM4716_CHIP_ID) && (pi->sh->chippkg == BCM4717_PKG_ID)) { @@ -19082,8 +19082,8 @@ wlc_phy_chanspec_nphy_setup(phy_info_t *pi, chanspec_t chanspec, if (pi->phy_spuravoid == SPURAVOID_FORCEON) spuravoid = 1; - if ((CHIPID(pi->sh->chip) == BCM4716_CHIP_ID) || - (CHIPID(pi->sh->chip) == BCM47162_CHIP_ID)) { + if ((pi->sh->chip == BCM4716_CHIP_ID) || + (pi->sh->chip == BCM47162_CHIP_ID)) { si_pmu_spuravoid(pi->sh->sih, pi->sh->osh, spuravoid); } else { wlapi_bmac_core_phypll_ctl(pi->sh->physhim, false); @@ -19091,9 +19091,9 @@ wlc_phy_chanspec_nphy_setup(phy_info_t *pi, chanspec_t chanspec, wlapi_bmac_core_phypll_ctl(pi->sh->physhim, true); } - if ((CHIPID(pi->sh->chip) == BCM43224_CHIP_ID) || - (CHIPID(pi->sh->chip) == BCM43225_CHIP_ID) || - (CHIPID(pi->sh->chip) == BCM43421_CHIP_ID)) { + if ((pi->sh->chip == BCM43224_CHIP_ID) || + (pi->sh->chip == BCM43225_CHIP_ID) || + (pi->sh->chip == BCM43421_CHIP_ID)) { if (spuravoid == 1) { @@ -19110,8 +19110,8 @@ wlc_phy_chanspec_nphy_setup(phy_info_t *pi, chanspec_t chanspec, } } - if (!((CHIPID(pi->sh->chip) == BCM4716_CHIP_ID) || - (CHIPID(pi->sh->chip) == BCM47162_CHIP_ID))) { + if (!((pi->sh->chip == BCM4716_CHIP_ID) || + (pi->sh->chip == BCM47162_CHIP_ID))) { wlapi_bmac_core_phypll_reset(pi->sh->physhim); } @@ -21067,11 +21067,11 @@ s16 wlc_phy_tempsense_nphy(phy_info_t *pi) wlc_phy_table_write_nphy(pi, NPHY_TBL_ID_AFECTRL, 1, 0x03, 16, &auxADC_rssi_ctrlH_save); - if (CHIPID(pi->sh->chip) == BCM5357_CHIP_ID) { + if (pi->sh->chip == BCM5357_CHIP_ID) { radio_temp[0] = (193 * (radio_temp[1] + radio_temp2[1]) + 88 * (auxADC_Vl) - 27111 + 128) / 256; - } else if (CHIPID(pi->sh->chip) == BCM43236_CHIP_ID) { + } else if (pi->sh->chip == BCM43236_CHIP_ID) { radio_temp[0] = (198 * (radio_temp[1] + radio_temp2[1]) + 91 * (auxADC_Vl) - 27243 + 128) / 256; @@ -26282,7 +26282,7 @@ static u32 *wlc_phy_get_ipa_gaintbl_nphy(phy_info_t *pi) } else if (NREV_IS(pi->pubpi.phy_rev, 6)) { tx_pwrctrl_tbl = nphy_tpc_txgain_ipa_rev6; - if (CHIPID(pi->sh->chip) == BCM47162_CHIP_ID) { + if (pi->sh->chip == BCM47162_CHIP_ID) { tx_pwrctrl_tbl = nphy_tpc_txgain_ipa_rev5; } @@ -26838,7 +26838,7 @@ wlc_phy_a2_nphy(phy_info_t *pi, nphy_ipa_txcalgains_t *txgains, phy_a2 = 63; if (CHSPEC_IS2G(pi->radio_chanspec)) { - if (CHIPID(pi->sh->chip) == BCM6362_CHIP_ID) { + if (pi->sh->chip == BCM6362_CHIP_ID) { phy_a1 = 35; phy_a3 = 35; } else if ((pi->pubpi.radiorev == 4) @@ -26951,7 +26951,7 @@ wlc_phy_a2_nphy(phy_info_t *pi, nphy_ipa_txcalgains_t *txgains, if (NREV_GE(pi->pubpi.phy_rev, 6)) { phy_a5 = 0x00f7 | (phy_a4 << 8); - if (CHIPID(pi->sh->chip) == + if (pi->sh->chip == BCM47162_CHIP_ID) { phy_a5 = 0x10f7 | (phy_a4 << diff --git a/drivers/staging/brcm80211/sys/wlc_bmac.c b/drivers/staging/brcm80211/sys/wlc_bmac.c index 6711c69edf38..b28dfb301ae4 100644 --- a/drivers/staging/brcm80211/sys/wlc_bmac.c +++ b/drivers/staging/brcm80211/sys/wlc_bmac.c @@ -407,8 +407,8 @@ bool BCMFASTPATH wlc_dpc(wlc_info_t *wlc, bool bounded) WL_ERROR(("wl%d: PSM microcode watchdog fired at %d (seconds). Resetting.\n", wlc_hw->unit, wlc_hw->now)); printk_once("%s : PSM Watchdog, chipid 0x%x, chiprev 0x%x\n", - __func__, CHIPID(wlc_hw->sih->chip), - CHIPREV(wlc_hw->sih->chiprev)); + __func__, wlc_hw->sih->chip, + CHIPREV(wlc_hw->sih->chiprev)); WLCNTINCR(wlc->pub->_cnt->psmwds); @@ -842,7 +842,7 @@ int wlc_bmac_attach(wlc_info_t *wlc, u16 vendor, u16 device, uint unit, } else wlc_hw->_nbands = 1; - if ((CHIPID(wlc_hw->sih->chip) == BCM43225_CHIP_ID)) + if ((wlc_hw->sih->chip == BCM43225_CHIP_ID)) wlc_hw->_nbands = 1; /* BMAC_NOTE: remove init of pub values when wlc_attach() unconditionally does the @@ -2224,9 +2224,9 @@ bool wlc_bmac_radio_read_hwdisabled(wlc_hw_info_t *wlc_hw) flags |= SICF_PCLKE; /* AI chip doesn't restore bar0win2 on hibernation/resume, need sw fixup */ - if ((CHIPID(wlc_hw->sih->chip) == BCM43224_CHIP_ID) || - (CHIPID(wlc_hw->sih->chip) == BCM43225_CHIP_ID) || - (CHIPID(wlc_hw->sih->chip) == BCM43421_CHIP_ID)) + if ((wlc_hw->sih->chip == BCM43224_CHIP_ID) || + (wlc_hw->sih->chip == BCM43225_CHIP_ID) || + (wlc_hw->sih->chip == BCM43421_CHIP_ID)) wlc_hw->regs = (d11regs_t *) si_setcore(wlc_hw->sih, D11_CORE_ID, 0); @@ -2266,9 +2266,9 @@ void wlc_bmac_hw_up(wlc_hw_info_t *wlc_hw) si_pci_fixcfg(wlc_hw->sih); /* AI chip doesn't restore bar0win2 on hibernation/resume, need sw fixup */ - if ((CHIPID(wlc_hw->sih->chip) == BCM43224_CHIP_ID) || - (CHIPID(wlc_hw->sih->chip) == BCM43225_CHIP_ID) || - (CHIPID(wlc_hw->sih->chip) == BCM43421_CHIP_ID)) + if ((wlc_hw->sih->chip == BCM43224_CHIP_ID) || + (wlc_hw->sih->chip == BCM43225_CHIP_ID) || + (wlc_hw->sih->chip == BCM43421_CHIP_ID)) wlc_hw->regs = (d11regs_t *) si_setcore(wlc_hw->sih, D11_CORE_ID, 0); @@ -2281,7 +2281,7 @@ void wlc_bmac_hw_up(wlc_hw_info_t *wlc_hw) wlc_hw->wlc->pub->hw_up = true; if ((wlc_hw->boardflags & BFL_FEM) - && (CHIPID(wlc_hw->sih->chip) == BCM4313_CHIP_ID)) { + && (wlc_hw->sih->chip == BCM4313_CHIP_ID)) { if (! (wlc_hw->boardrev >= 0x1250 && (wlc_hw->boardflags & BFL_FEM_BT))) @@ -2689,8 +2689,8 @@ void wlc_bmac_switch_macfreq(wlc_hw_info_t *wlc_hw, u8 spurmode) regs = wlc_hw->regs; osh = wlc_hw->osh; - if ((CHIPID(wlc_hw->sih->chip) == BCM43224_CHIP_ID) || - (CHIPID(wlc_hw->sih->chip) == BCM43225_CHIP_ID)) { + if ((wlc_hw->sih->chip == BCM43224_CHIP_ID) || + (wlc_hw->sih->chip == BCM43225_CHIP_ID)) { if (spurmode == WL_SPURAVOID_ON2) { /* 126Mhz */ W_REG(osh, ®s->tsf_clk_frac_l, 0x2082); W_REG(osh, ®s->tsf_clk_frac_h, 0x8); diff --git a/drivers/staging/brcm80211/sys/wlc_mac80211.c b/drivers/staging/brcm80211/sys/wlc_mac80211.c index 7017db68c983..f64a9e8b8281 100644 --- a/drivers/staging/brcm80211/sys/wlc_mac80211.c +++ b/drivers/staging/brcm80211/sys/wlc_mac80211.c @@ -1991,7 +1991,7 @@ void *wlc_attach(void *wl, u16 vendor, u16 device, uint unit, bool piomode, wlc_radio_mpc_upd(wlc); if (WLANTSEL_ENAB(wlc)) { - if ((CHIPID(wlc->pub->sih->chip)) == BCM43235_CHIP_ID) { + if ((wlc->pub->sih->chip) == BCM43235_CHIP_ID) { if ((getintvar(wlc->pub->vars, "aa2g") == 7) || (getintvar(wlc->pub->vars, "aa5g") == 7)) { wlc_bmac_antsel_set(wlc->hw, 1); @@ -2537,7 +2537,7 @@ int wlc_up(wlc_info_t *wlc) } if ((wlc->pub->boardflags & BFL_FEM) - && (CHIPID(wlc->pub->sih->chip) == BCM4313_CHIP_ID)) { + && (wlc->pub->sih->chip == BCM4313_CHIP_ID)) { if (wlc->pub->boardrev >= 0x1250 && (wlc->pub->boardflags & BFL_FEM_BT)) { wlc_mhf(wlc, MHF5, MHF5_4313_GPIOCTRL, @@ -6427,8 +6427,8 @@ void wlc_high_dpc(wlc_info_t *wlc, u32 macintstatus) WL_ERROR(("wl%d: PSM microcode watchdog fired at %d (seconds). Resetting.\n", wlc->pub->unit, wlc->pub->now)); printk_once("%s : PSM Watchdog, chipid 0x%x, chiprev 0x%x\n", - __func__, CHIPID(wlc->pub->sih->chip), - CHIPREV(wlc->pub->sih->chiprev)); + __func__, wlc->pub->sih->chip, + CHIPREV(wlc->pub->sih->chiprev)); WLCNTINCR(wlc->pub->_cnt->psmwds); diff --git a/drivers/staging/brcm80211/util/aiutils.c b/drivers/staging/brcm80211/util/aiutils.c index 09e09c9770a9..7e3cce24e174 100644 --- a/drivers/staging/brcm80211/util/aiutils.c +++ b/drivers/staging/brcm80211/util/aiutils.c @@ -31,7 +31,7 @@ #include #include -#define BCM47162_DMP() ((CHIPID(sih->chip) == BCM47162_CHIP_ID) && \ +#define BCM47162_DMP() ((sih->chip == BCM47162_CHIP_ID) && \ (CHIPREV(sih->chiprev) == 0) && \ (sii->coreid[sii->curidx] == MIPS74K_CORE_ID)) diff --git a/drivers/staging/brcm80211/util/bcmotp.c b/drivers/staging/brcm80211/util/bcmotp.c index 3c625c84619e..d820e7b9e970 100644 --- a/drivers/staging/brcm80211/util/bcmotp.c +++ b/drivers/staging/brcm80211/util/bcmotp.c @@ -223,7 +223,7 @@ static int ipxotp_max_rgnsz(si_t *sih, int osizew) { int ret = 0; - switch (CHIPID(sih->chip)) { + switch (sih->chip) { case BCM43224_CHIP_ID: case BCM43225_CHIP_ID: ret = osizew * 2 - OTP_SZ_FU_72 - OTP_SZ_CHECKSUM; @@ -273,8 +273,8 @@ static void _ipxotp_init(otpinfo_t *oi, chipcregs_t *cc) /* Read OTP lock bits and subregion programmed indication bits */ oi->status = R_REG(oi->osh, &cc->otpstatus); - if ((CHIPID(oi->sih->chip) == BCM43224_CHIP_ID) - || (CHIPID(oi->sih->chip) == BCM43225_CHIP_ID)) { + if ((oi->sih->chip == BCM43224_CHIP_ID) + || (oi->sih->chip == BCM43225_CHIP_ID)) { u32 p_bits; p_bits = (ipxotp_otpr(oi, cc, oi->otpgu_base + OTPGU_P_OFF) & diff --git a/drivers/staging/brcm80211/util/hndpmu.c b/drivers/staging/brcm80211/util/hndpmu.c index 45f4fdaed0ac..466c8a603022 100644 --- a/drivers/staging/brcm80211/util/hndpmu.c +++ b/drivers/staging/brcm80211/util/hndpmu.c @@ -136,7 +136,7 @@ void si_pmu_set_ldo_voltage(si_t *sih, struct osl_info *osh, u8 ldo, u8 voltage) ASSERT(sih->cccaps & CC_CAP_PMU); - switch (CHIPID(sih->chip)) { + switch (sih->chip) { case BCM4336_CHIP_ID: switch (ldo) { case SET_LDO_VOLTAGE_CLDO_PWM: @@ -204,7 +204,7 @@ u16 si_pmu_fast_pwrup_delay(si_t *sih, struct osl_info *osh) cc = si_setcoreidx(sih, SI_CC_IDX); ASSERT(cc != NULL); - switch (CHIPID(sih->chip)) { + switch (sih->chip) { case BCM43224_CHIP_ID: case BCM43225_CHIP_ID: case BCM43421_CHIP_ID: @@ -604,7 +604,7 @@ static void si_pmu_res_masks(si_t *sih, u32 * pmin, u32 * pmax) rsrcs = (sih->pmucaps & PCAP_RC_MASK) >> PCAP_RC_SHIFT; /* determine min/max rsrc masks */ - switch (CHIPID(sih->chip)) { + switch (sih->chip) { case BCM43224_CHIP_ID: case BCM43225_CHIP_ID: case BCM43421_CHIP_ID: @@ -701,7 +701,7 @@ void si_pmu_res_init(si_t *sih, struct osl_info *osh) cc = si_setcoreidx(sih, SI_CC_IDX); ASSERT(cc != NULL); - switch (CHIPID(sih->chip)) { + switch (sih->chip) { case BCM4329_CHIP_ID: /* Optimize resources up/down timers */ if (ISSIM_ENAB(sih)) { @@ -1100,7 +1100,7 @@ static const pmu1_xtaltab0_t *si_pmu1_xtaltab0(si_t *sih) #ifdef BCMDBG char chn[8]; #endif - switch (CHIPID(sih->chip)) { + switch (sih->chip) { case BCM4329_CHIP_ID: return pmu1_xtaltab0_880_4329; case BCM4319_CHIP_ID: @@ -1128,7 +1128,7 @@ static const pmu1_xtaltab0_t *si_pmu1_xtaldef0(si_t *sih) char chn[8]; #endif - switch (CHIPID(sih->chip)) { + switch (sih->chip) { case BCM4329_CHIP_ID: /* Default to 38400Khz */ return &pmu1_xtaltab0_880_4329[PMU1_XTALTAB0_880_38400K]; @@ -1160,7 +1160,7 @@ static u32 si_pmu1_pllfvco0(si_t *sih) char chn[8]; #endif - switch (CHIPID(sih->chip)) { + switch (sih->chip) { case BCM4329_CHIP_ID: return FVCO_880; case BCM4319_CHIP_ID: @@ -1239,8 +1239,8 @@ static void si_pmu1_pllinit0(si_t *sih, struct osl_info *osh, chipcregs_t *cc, */ if ((((R_REG(osh, &cc->pmucontrol) & PCTL_XTALFREQ_MASK) >> PCTL_XTALFREQ_SHIFT) == xt->xf) && - !((CHIPID(sih->chip) == BCM4319_CHIP_ID) - || (CHIPID(sih->chip) == BCM4330_CHIP_ID))) { + !((sih->chip == BCM4319_CHIP_ID) + || (sih->chip == BCM4330_CHIP_ID))) { PMU_MSG(("PLL already programmed for %d.%d MHz\n", xt->fref / 1000, xt->fref % 1000)); return; @@ -1250,7 +1250,7 @@ static void si_pmu1_pllinit0(si_t *sih, struct osl_info *osh, chipcregs_t *cc, PMU_MSG(("Programming PLL for %d.%d MHz\n", xt->fref / 1000, xt->fref % 1000)); - switch (CHIPID(sih->chip)) { + switch (sih->chip) { case BCM4329_CHIP_ID: /* Change the BBPLL drive strength to 8 for all channels */ buf_strength = 0x888888; @@ -1357,10 +1357,10 @@ static void si_pmu1_pllinit0(si_t *sih, struct osl_info *osh, chipcregs_t *cc, p2div << PMU1_PLL0_PC0_P2DIV_SHIFT) & PMU1_PLL0_PC0_P2DIV_MASK); W_REG(osh, &cc->pllcontrol_data, tmp); - if ((CHIPID(sih->chip) == BCM4330_CHIP_ID)) + if ((sih->chip == BCM4330_CHIP_ID)) si_pmu_set_4330_plldivs(sih); - if ((CHIPID(sih->chip) == BCM4329_CHIP_ID) + if ((sih->chip == BCM4329_CHIP_ID) && (CHIPREV(sih->chiprev) == 0)) { W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1); @@ -1369,9 +1369,9 @@ static void si_pmu1_pllinit0(si_t *sih, struct osl_info *osh, chipcregs_t *cc, tmp = tmp | DOT11MAC_880MHZ_CLK_DIVISOR_VAL; W_REG(osh, &cc->pllcontrol_data, tmp); } - if ((CHIPID(sih->chip) == BCM4319_CHIP_ID) || - (CHIPID(sih->chip) == BCM4336_CHIP_ID) || - (CHIPID(sih->chip) == BCM4330_CHIP_ID)) + if ((sih->chip == BCM4319_CHIP_ID) || + (sih->chip == BCM4336_CHIP_ID) || + (sih->chip == BCM4330_CHIP_ID)) ndiv_mode = PMU1_PLL0_PC2_NDIV_MODE_MFB; else ndiv_mode = PMU1_PLL0_PC2_NDIV_MODE_MASH; @@ -1413,7 +1413,7 @@ static void si_pmu1_pllinit0(si_t *sih, struct osl_info *osh, chipcregs_t *cc, /* to operate the 4319 usb in 24MHz/48MHz; chipcontrol[2][84:83] needs * to be updated. */ - if ((CHIPID(sih->chip) == BCM4319_CHIP_ID) + if ((sih->chip == BCM4319_CHIP_ID) && (xt->fref != XTAL_FREQ_30000MHZ)) { W_REG(osh, &cc->chipcontrol_addr, PMU1_PLL0_CHIPCTL2); tmp = @@ -1442,7 +1442,7 @@ static void si_pmu1_pllinit0(si_t *sih, struct osl_info *osh, chipcregs_t *cc, PCTL_ILP_DIV_MASK) | ((xt->xf << PCTL_XTALFREQ_SHIFT) & PCTL_XTALFREQ_MASK); - if ((CHIPID(sih->chip) == BCM4329_CHIP_ID) + if ((sih->chip == BCM4329_CHIP_ID) && CHIPREV(sih->chiprev) == 0) { /* clear the htstretch before clearing HTReqEn */ AND_REG(osh, &cc->clkstretch, ~CSTRETCH_HT); @@ -1523,7 +1523,7 @@ void si_pmu_pll_init(si_t *sih, struct osl_info *osh, uint xtalfreq) cc = si_setcoreidx(sih, SI_CC_IDX); ASSERT(cc != NULL); - switch (CHIPID(sih->chip)) { + switch (sih->chip) { case BCM4329_CHIP_ID: if (xtalfreq == 0) xtalfreq = 38400; @@ -1577,7 +1577,7 @@ u32 si_pmu_alp_clock(si_t *sih, struct osl_info *osh) cc = si_setcoreidx(sih, SI_CC_IDX); ASSERT(cc != NULL); - switch (CHIPID(sih->chip)) { + switch (sih->chip) { case BCM43224_CHIP_ID: case BCM43225_CHIP_ID: case BCM43421_CHIP_ID: @@ -1637,7 +1637,7 @@ si_pmu5_clock(si_t *sih, struct osl_info *osh, chipcregs_t *cc, uint pll0, return 0; } - if (CHIPID(sih->chip) == BCM5357_CHIP_ID) { + if (sih->chip == BCM5357_CHIP_ID) { /* Detect failure in clock setting */ if ((R_REG(osh, &cc->chipstatus) & 0x40000) != 0) { return 133 * 1000000; @@ -1691,7 +1691,7 @@ u32 si_pmu_si_clock(si_t *sih, struct osl_info *osh) cc = si_setcoreidx(sih, SI_CC_IDX); ASSERT(cc != NULL); - switch (CHIPID(sih->chip)) { + switch (sih->chip) { case BCM43224_CHIP_ID: case BCM43225_CHIP_ID: case BCM43421_CHIP_ID: @@ -1763,14 +1763,14 @@ u32 si_pmu_cpu_clock(si_t *sih, struct osl_info *osh) ASSERT(sih->cccaps & CC_CAP_PMU); if ((sih->pmurev >= 5) && - !((CHIPID(sih->chip) == BCM4329_CHIP_ID) || - (CHIPID(sih->chip) == BCM4319_CHIP_ID) || - (CHIPID(sih->chip) == BCM43236_CHIP_ID) || - (CHIPID(sih->chip) == BCM4336_CHIP_ID) || - (CHIPID(sih->chip) == BCM4330_CHIP_ID))) { + !((sih->chip == BCM4329_CHIP_ID) || + (sih->chip == BCM4319_CHIP_ID) || + (sih->chip == BCM43236_CHIP_ID) || + (sih->chip == BCM4336_CHIP_ID) || + (sih->chip == BCM4330_CHIP_ID))) { uint pll; - switch (CHIPID(sih->chip)) { + switch (sih->chip) { case BCM5356_CHIP_ID: pll = PMU5356_MAINPLL_PLL0; break; @@ -1807,14 +1807,14 @@ u32 si_pmu_mem_clock(si_t *sih, struct osl_info *osh) ASSERT(sih->cccaps & CC_CAP_PMU); if ((sih->pmurev >= 5) && - !((CHIPID(sih->chip) == BCM4329_CHIP_ID) || - (CHIPID(sih->chip) == BCM4319_CHIP_ID) || - (CHIPID(sih->chip) == BCM4330_CHIP_ID) || - (CHIPID(sih->chip) == BCM4336_CHIP_ID) || - (CHIPID(sih->chip) == BCM43236_CHIP_ID))) { + !((sih->chip == BCM4329_CHIP_ID) || + (sih->chip == BCM4319_CHIP_ID) || + (sih->chip == BCM4330_CHIP_ID) || + (sih->chip == BCM4336_CHIP_ID) || + (sih->chip == BCM43236_CHIP_ID))) { uint pll; - switch (CHIPID(sih->chip)) { + switch (sih->chip) { case BCM5356_CHIP_ID: pll = PMU5356_MAINPLL_PLL0; break; @@ -1999,7 +1999,7 @@ void si_pmu_init(si_t *sih, struct osl_info *osh) else if (sih->pmurev >= 2) OR_REG(osh, &cc->pmucontrol, PCTL_NOILP_ON_WAIT); - if ((CHIPID(sih->chip) == BCM4329_CHIP_ID) && (sih->chiprev == 2)) { + if ((sih->chip == BCM4329_CHIP_ID) && (sih->chiprev == 2)) { /* Fix for 4329b0 bad LPOM state. */ W_REG(osh, &cc->regcontrol_addr, 2); OR_REG(osh, &cc->regcontrol_data, 0x100); @@ -2090,7 +2090,7 @@ void si_pmu_otp_power(si_t *sih, struct osl_info *osh, bool on) cc = si_setcoreidx(sih, SI_CC_IDX); ASSERT(cc != NULL); - switch (CHIPID(sih->chip)) { + switch (sih->chip) { case BCM4329_CHIP_ID: rsrcs = PMURES_BIT(RES4329_OTP_PU); break; @@ -2153,7 +2153,7 @@ void si_pmu_rcal(si_t *sih, struct osl_info *osh) cc = si_setcoreidx(sih, SI_CC_IDX); ASSERT(cc != NULL); - switch (CHIPID(sih->chip)) { + switch (sih->chip) { case BCM4329_CHIP_ID:{ u8 rcal_code; u32 val; @@ -2236,7 +2236,7 @@ void si_pmu_spuravoid(si_t *sih, struct osl_info *osh, u8 spuravoid) ASSERT(cc != NULL); /* force the HT off */ - if (CHIPID(sih->chip) == BCM4336_CHIP_ID) { + if (sih->chip == BCM4336_CHIP_ID) { tmp = R_REG(osh, &cc->max_res_mask); tmp &= ~RES4336_HT_AVAIL; W_REG(osh, &cc->max_res_mask, tmp); @@ -2250,7 +2250,7 @@ void si_pmu_spuravoid(si_t *sih, struct osl_info *osh, u8 spuravoid) si_pmu_spuravoid_pllupdate(sih, cc, osh, spuravoid); /* enable HT back on */ - if (CHIPID(sih->chip) == BCM4336_CHIP_ID) { + if (sih->chip == BCM4336_CHIP_ID) { tmp = R_REG(osh, &cc->max_res_mask); tmp |= RES4336_HT_AVAIL; W_REG(osh, &cc->max_res_mask, tmp); @@ -2269,14 +2269,14 @@ si_pmu_spuravoid_pllupdate(si_t *sih, chipcregs_t *cc, struct osl_info *osh, u8 bcm5357_bcm43236_p1div[] = { 0x1, 0x5, 0x5 }; u8 bcm5357_bcm43236_ndiv[] = { 0x30, 0xf6, 0xfc }; - switch (CHIPID(sih->chip)) { + switch (sih->chip) { case BCM5357_CHIP_ID: case BCM43235_CHIP_ID: case BCM43236_CHIP_ID: case BCM43238_CHIP_ID: /* BCM5357 needs to touch PLL1_PLLCTL[02], so offset PLL0_PLLCTL[02] by 6 */ - phypll_offset = (CHIPID(sih->chip) == BCM5357_CHIP_ID) ? 6 : 0; + phypll_offset = (sih->chip == BCM5357_CHIP_ID) ? 6 : 0; /* RMW only the P1 divider */ W_REG(osh, &cc->pllcontrol_addr, @@ -2468,7 +2468,7 @@ bool si_pmu_is_otp_powered(si_t *sih, struct osl_info *osh) cc = si_setcoreidx(sih, SI_CC_IDX); ASSERT(cc != NULL); - switch (CHIPID(sih->chip)) { + switch (sih->chip) { case BCM4329_CHIP_ID: st = (R_REG(osh, &cc->res_state) & PMURES_BIT(RES4329_OTP_PU)) != 0; @@ -2553,7 +2553,7 @@ void si_pmu_swreg_init(si_t *sih, struct osl_info *osh) { ASSERT(sih->cccaps & CC_CAP_PMU); - switch (CHIPID(sih->chip)) { + switch (sih->chip) { case BCM4336_CHIP_ID: /* Reduce CLDO PWM output voltage to 1.2V */ si_pmu_set_ldo_voltage(sih, osh, SET_LDO_VOLTAGE_CLDO_PWM, 0xe); @@ -2579,7 +2579,7 @@ void si_pmu_radio_enable(si_t *sih, bool enable) { ASSERT(sih->cccaps & CC_CAP_PMU); - switch (CHIPID(sih->chip)) { + switch (sih->chip) { case BCM4319_CHIP_ID: if (enable) si_write_wrapperreg(sih, AI_OOBSELOUTB74, diff --git a/drivers/staging/brcm80211/util/sbutils.c b/drivers/staging/brcm80211/util/sbutils.c index 7b93ac22d4fc..63c3ab1866a4 100644 --- a/drivers/staging/brcm80211/util/sbutils.c +++ b/drivers/staging/brcm80211/util/sbutils.c @@ -251,7 +251,7 @@ static uint _sb_scan(si_info_t *sii, u32 sba, void *regs, uint bus, u32 sbba, else { /* Older chips */ SI_ERROR(("sb_chip2numcores: unsupported chip " - "0x%x\n", CHIPID(sii->pub.chip))); + "0x%x\n", sii->pub.chip)); ASSERT(0); numcores = 1; } diff --git a/drivers/staging/brcm80211/util/siutils.c b/drivers/staging/brcm80211/util/siutils.c index da35edd2d7b5..3d694b99f6c1 100644 --- a/drivers/staging/brcm80211/util/siutils.c +++ b/drivers/staging/brcm80211/util/siutils.c @@ -414,7 +414,7 @@ static si_info_t *si_doattach(si_info_t *sii, uint devid, struct osl_info *osh, sih->chiprev = (w & CID_REV_MASK) >> CID_REV_SHIFT; sih->chippkg = (w & CID_PKG_MASK) >> CID_PKG_SHIFT; - if ((CHIPID(sih->chip) == BCM4329_CHIP_ID) && + if ((sih->chip == BCM4329_CHIP_ID) && (sih->chippkg != BCM4329_289PIN_PKG_ID)) sih->chippkg = BCM4329_182PIN_PKG_ID; @@ -591,9 +591,9 @@ static si_info_t *si_doattach(si_info_t *sii, uint devid, struct osl_info *osh, /* assume current core is CC */ if ((sii->pub.ccrev == 0x25) && - ((CHIPID(sih->chip) == BCM43236_CHIP_ID - || CHIPID(sih->chip) == BCM43235_CHIP_ID - || CHIPID(sih->chip) == BCM43238_CHIP_ID) + ((sih->chip == BCM43236_CHIP_ID + || sih->chip == BCM43235_CHIP_ID + || sih->chip == BCM43238_CHIP_ID) && (CHIPREV(sii->pub.chiprev) <= 2))) { if ((cc->chipstatus & CST43236_BP_CLK) != 0) { @@ -650,8 +650,8 @@ static si_info_t *si_doattach(si_info_t *sii, uint devid, struct osl_info *osh, pcicore_attach(sii->pch, pvars, SI_DOATTACH); } - if ((CHIPID(sih->chip) == BCM43224_CHIP_ID) || - (CHIPID(sih->chip) == BCM43421_CHIP_ID)) { + if ((sih->chip == BCM43224_CHIP_ID) || + (sih->chip == BCM43421_CHIP_ID)) { /* enable 12 mA drive strenth for 43224 and set chipControl register bit 15 */ if (CHIPREV(sih->chiprev) == 0) { SI_MSG(("Applying 43224A0 WARs\n")); @@ -669,14 +669,14 @@ static si_info_t *si_doattach(si_info_t *sii, uint devid, struct osl_info *osh, } } - if (CHIPID(sih->chip) == BCM4313_CHIP_ID) { + if (sih->chip == BCM4313_CHIP_ID) { /* enable 12 mA drive strenth for 4313 and set chipControl register bit 1 */ SI_MSG(("Applying 4313 WARs\n")); si_pmu_chipcontrol(sih, 0, CCTRL_4313_12MA_LED_DRIVE, CCTRL_4313_12MA_LED_DRIVE); } - if (CHIPID(sih->chip) == BCM4331_CHIP_ID) { + if (sih->chip == BCM4331_CHIP_ID) { /* Enable Ext PA lines depending on chip package option */ si_chipcontrl_epa4331(sih, true); } @@ -1042,7 +1042,7 @@ void si_watchdog(si_t *sih, uint ticks) if (PMUCTL_ENAB(sih)) { - if ((CHIPID(sih->chip) == BCM4319_CHIP_ID) && + if ((sih->chip == BCM4319_CHIP_ID) && (CHIPREV(sih->chiprev) == 0) && (ticks != 0)) { si_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, clk_ctl_st), ~0, 0x2); @@ -1957,7 +1957,7 @@ bool si_is_sprom_available(si_t *sih) return sromctrl & SRC_PRESENT; } - switch (CHIPID(sih->chip)) { + switch (sih->chip) { case BCM4329_CHIP_ID: return (sih->chipst & CST4329_SPROM_SEL) != 0; case BCM4319_CHIP_ID: @@ -1977,7 +1977,7 @@ bool si_is_sprom_available(si_t *sih) bool si_is_otp_disabled(si_t *sih) { - switch (CHIPID(sih->chip)) { + switch (sih->chip) { case BCM4329_CHIP_ID: return (sih->chipst & CST4329_SPROM_OTP_SEL_MASK) == CST4329_OTP_PWRDN; -- cgit v1.2.3 From ff29ee8f9301c38f28d4d22fe49373d3b996956e Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Thu, 2 Dec 2010 15:44:52 +0100 Subject: staging: brcm80211: remove redundant CHIPREV macro The CHIPREV macro simply expands to the macro argument so it is redundant and as such removed. Reviewed-by: Roland Vossen Signed-off-by: Arend van Spriel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/include/bcmdefs.h | 1 - drivers/staging/brcm80211/sys/wlc_bmac.c | 2 +- drivers/staging/brcm80211/sys/wlc_mac80211.c | 2 +- drivers/staging/brcm80211/util/aiutils.c | 2 +- drivers/staging/brcm80211/util/hndpmu.c | 8 ++++---- drivers/staging/brcm80211/util/siutils.c | 8 ++++---- 6 files changed, 11 insertions(+), 12 deletions(-) diff --git a/drivers/staging/brcm80211/include/bcmdefs.h b/drivers/staging/brcm80211/include/bcmdefs.h index 82356129caa5..74601fc971c9 100644 --- a/drivers/staging/brcm80211/include/bcmdefs.h +++ b/drivers/staging/brcm80211/include/bcmdefs.h @@ -51,7 +51,6 @@ #define SPI_BUS 6 /* gSPI target */ #define RPC_BUS 7 /* RPC target */ -#define CHIPREV(rev) (rev) /* Defines for DMA Address Width - Shared between OSL and HNDDMA */ #define DMADDR_MASK_32 0x0 /* Address mask for 32-bits */ diff --git a/drivers/staging/brcm80211/sys/wlc_bmac.c b/drivers/staging/brcm80211/sys/wlc_bmac.c index b28dfb301ae4..79ee24f3b07f 100644 --- a/drivers/staging/brcm80211/sys/wlc_bmac.c +++ b/drivers/staging/brcm80211/sys/wlc_bmac.c @@ -408,7 +408,7 @@ bool BCMFASTPATH wlc_dpc(wlc_info_t *wlc, bool bounded) printk_once("%s : PSM Watchdog, chipid 0x%x, chiprev 0x%x\n", __func__, wlc_hw->sih->chip, - CHIPREV(wlc_hw->sih->chiprev)); + wlc_hw->sih->chiprev); WLCNTINCR(wlc->pub->_cnt->psmwds); diff --git a/drivers/staging/brcm80211/sys/wlc_mac80211.c b/drivers/staging/brcm80211/sys/wlc_mac80211.c index f64a9e8b8281..9aae3405aa11 100644 --- a/drivers/staging/brcm80211/sys/wlc_mac80211.c +++ b/drivers/staging/brcm80211/sys/wlc_mac80211.c @@ -6428,7 +6428,7 @@ void wlc_high_dpc(wlc_info_t *wlc, u32 macintstatus) printk_once("%s : PSM Watchdog, chipid 0x%x, chiprev 0x%x\n", __func__, wlc->pub->sih->chip, - CHIPREV(wlc->pub->sih->chiprev)); + wlc->pub->sih->chiprev); WLCNTINCR(wlc->pub->_cnt->psmwds); diff --git a/drivers/staging/brcm80211/util/aiutils.c b/drivers/staging/brcm80211/util/aiutils.c index 7e3cce24e174..ddd2f9d64c20 100644 --- a/drivers/staging/brcm80211/util/aiutils.c +++ b/drivers/staging/brcm80211/util/aiutils.c @@ -32,7 +32,7 @@ #include #define BCM47162_DMP() ((sih->chip == BCM47162_CHIP_ID) && \ - (CHIPREV(sih->chiprev) == 0) && \ + (sih->chiprev == 0) && \ (sii->coreid[sii->curidx] == MIPS74K_CORE_ID)) /* EROM parsing */ diff --git a/drivers/staging/brcm80211/util/hndpmu.c b/drivers/staging/brcm80211/util/hndpmu.c index 466c8a603022..6cc59a895868 100644 --- a/drivers/staging/brcm80211/util/hndpmu.c +++ b/drivers/staging/brcm80211/util/hndpmu.c @@ -1361,7 +1361,7 @@ static void si_pmu1_pllinit0(si_t *sih, struct osl_info *osh, chipcregs_t *cc, si_pmu_set_4330_plldivs(sih); if ((sih->chip == BCM4329_CHIP_ID) - && (CHIPREV(sih->chiprev) == 0)) { + && (sih->chiprev == 0)) { W_REG(osh, &cc->pllcontrol_addr, PMU1_PLL0_PLLCTL1); tmp = R_REG(osh, &cc->pllcontrol_data); @@ -1443,7 +1443,7 @@ static void si_pmu1_pllinit0(si_t *sih, struct osl_info *osh, chipcregs_t *cc, ((xt->xf << PCTL_XTALFREQ_SHIFT) & PCTL_XTALFREQ_MASK); if ((sih->chip == BCM4329_CHIP_ID) - && CHIPREV(sih->chiprev) == 0) { + && sih->chiprev == 0) { /* clear the htstretch before clearing HTReqEn */ AND_REG(osh, &cc->clkstretch, ~CSTRETCH_HT); tmp &= ~PCTL_HT_REQ_EN; @@ -1708,7 +1708,7 @@ u32 si_pmu_si_clock(si_t *sih, struct osl_info *osh) PMU5_MAINPLL_SI); break; case BCM4329_CHIP_ID: - if (CHIPREV(sih->chiprev) == 0) + if (sih->chiprev == 0) clock = 38400 * 1000; else clock = si_pmu1_cpuclk0(sih, osh, cc); @@ -2562,7 +2562,7 @@ void si_pmu_swreg_init(si_t *sih, struct osl_info *osh) 0xe); /* Reduce LNLDO1 output voltage to 1.2V */ si_pmu_set_ldo_voltage(sih, osh, SET_LDO_VOLTAGE_LNLDO1, 0xe); - if (CHIPREV(sih->chiprev) == 0) + if (sih->chiprev == 0) si_pmu_regcontrol(sih, 2, 0x400000, 0x400000); break; diff --git a/drivers/staging/brcm80211/util/siutils.c b/drivers/staging/brcm80211/util/siutils.c index 3d694b99f6c1..29d2d68354f6 100644 --- a/drivers/staging/brcm80211/util/siutils.c +++ b/drivers/staging/brcm80211/util/siutils.c @@ -594,7 +594,7 @@ static si_info_t *si_doattach(si_info_t *sii, uint devid, struct osl_info *osh, ((sih->chip == BCM43236_CHIP_ID || sih->chip == BCM43235_CHIP_ID || sih->chip == BCM43238_CHIP_ID) - && (CHIPREV(sii->pub.chiprev) <= 2))) { + && (sii->pub.chiprev <= 2))) { if ((cc->chipstatus & CST43236_BP_CLK) != 0) { uint clkdiv; @@ -653,7 +653,7 @@ static si_info_t *si_doattach(si_info_t *sii, uint devid, struct osl_info *osh, if ((sih->chip == BCM43224_CHIP_ID) || (sih->chip == BCM43421_CHIP_ID)) { /* enable 12 mA drive strenth for 43224 and set chipControl register bit 15 */ - if (CHIPREV(sih->chiprev) == 0) { + if (sih->chiprev == 0) { SI_MSG(("Applying 43224A0 WARs\n")); si_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, chipcontrol), @@ -662,7 +662,7 @@ static si_info_t *si_doattach(si_info_t *sii, uint devid, struct osl_info *osh, si_pmu_chipcontrol(sih, 0, CCTRL_43224A0_12MA_LED_DRIVE, CCTRL_43224A0_12MA_LED_DRIVE); } - if (CHIPREV(sih->chiprev) >= 1) { + if (sih->chiprev >= 1) { SI_MSG(("Applying 43224B0+ WARs\n")); si_pmu_chipcontrol(sih, 0, CCTRL_43224B0_12MA_LED_DRIVE, CCTRL_43224B0_12MA_LED_DRIVE); @@ -1043,7 +1043,7 @@ void si_watchdog(si_t *sih, uint ticks) if (PMUCTL_ENAB(sih)) { if ((sih->chip == BCM4319_CHIP_ID) && - (CHIPREV(sih->chiprev) == 0) && (ticks != 0)) { + (sih->chiprev == 0) && (ticks != 0)) { si_corereg(sih, SI_CC_IDX, offsetof(chipcregs_t, clk_ctl_st), ~0, 0x2); si_setcore(sih, USB20D_CORE_ID, 0); -- cgit v1.2.3 From eb6b420da13fee2edc30b7bde67c0c8993c4c30d Mon Sep 17 00:00:00 2001 From: Peter Huewe Date: Thu, 2 Dec 2010 00:43:32 +0100 Subject: staging/sep: Fix sparse warning 'do-while statement is not a compound statement' This patch fixes the warning generated by sparse: 'do-while statement is not a compound statement' by adding the necessary brackets around the do block Signed-off-by: Peter Huewe Signed-off-by: Greg Kroah-Hartman --- drivers/staging/sep/sep_dev.h | 4 ++-- drivers/staging/sep/sep_driver.c | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/staging/sep/sep_dev.h b/drivers/staging/sep/sep_dev.h index 7b4993b3650d..0ffe68cb7140 100644 --- a/drivers/staging/sep/sep_dev.h +++ b/drivers/staging/sep/sep_dev.h @@ -147,9 +147,9 @@ static inline u32 sep_read_reg(struct sep_device *dev, int reg) static inline void sep_wait_sram_write(struct sep_device *dev) { u32 reg_val; - do + do { reg_val = sep_read_reg(dev, HW_SRAM_DATA_READY_REG_ADDR); - while (!(reg_val & 1)); + } while (!(reg_val & 1)); } diff --git a/drivers/staging/sep/sep_driver.c b/drivers/staging/sep/sep_driver.c index 76331112a264..d7348871b17b 100644 --- a/drivers/staging/sep/sep_driver.c +++ b/drivers/staging/sep/sep_driver.c @@ -2587,9 +2587,9 @@ static int sep_start_handler(struct sep_device *sep) dev_dbg(&sep->pdev->dev, "sep_start_handler start\n"); /* Wait in polling for message from SEP */ - do + do { reg_val = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR3_REG_ADDR); - while (!reg_val); + } while (!reg_val); /* Check the value */ if (reg_val == 0x1) @@ -2754,9 +2754,9 @@ static int sep_init_handler(struct sep_device *sep, unsigned long arg) /* Wait for acknowledge */ dev_dbg(&sep->pdev->dev, "init; waiting for msg response\n"); - do + do { reg_val = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR3_REG_ADDR); - while (!(reg_val & 0xFFFFFFFD)); + } while (!(reg_val & 0xFFFFFFFD)); if (reg_val == 0x1) { dev_warn(&sep->pdev->dev, "init; device int failed\n"); @@ -2774,9 +2774,9 @@ static int sep_init_handler(struct sep_device *sep, unsigned long arg) /* Wait for response */ dev_dbg(&sep->pdev->dev, "init; waiting for zero set response\n"); - do + do { reg_val = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR3_REG_ADDR); - while (reg_val != 0); + } while (reg_val != 0); end_function: dev_dbg(&sep->pdev->dev, "init is done\n"); -- cgit v1.2.3 From dda16b23e32cf2351aa03590f43cc8a2873dc6a9 Mon Sep 17 00:00:00 2001 From: Peter Huewe Date: Thu, 2 Dec 2010 00:43:33 +0100 Subject: staging/sep: Fix sparse warning 'Using plain integer as NULL pointer' This patch fixes the warning generated by sparse: "Using plain integer as NULL pointer" by replacing the offending 0s with NULL. Signed-off-by: Peter Huewe Signed-off-by: Greg Kroah-Hartman --- drivers/staging/sep/sep_driver.c | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/drivers/staging/sep/sep_driver.c b/drivers/staging/sep/sep_driver.c index d7348871b17b..2216beddecee 100644 --- a/drivers/staging/sep/sep_driver.c +++ b/drivers/staging/sep/sep_driver.c @@ -459,12 +459,12 @@ static int sep_free_dma_table_data_handler(struct sep_device *sep) } /* Reset all the values */ - dma->in_page_array = 0; - dma->out_page_array = 0; + dma->in_page_array = NULL; + dma->out_page_array = NULL; dma->in_num_pages = 0; dma->out_num_pages = 0; - dma->in_map_array = 0; - dma->out_map_array = 0; + dma->in_map_array = NULL; + dma->out_map_array = NULL; dma->in_map_num_entries = 0; dma->out_map_num_entries = 0; } @@ -1114,13 +1114,13 @@ static int sep_lock_kernel_pages(struct sep_device *sep, if (in_out_flag == SEP_DRIVER_IN_FLAG) { *lli_array_ptr = lli_array; sep->dma_res_arr[sep->nr_dcb_creat].in_num_pages = 1; - sep->dma_res_arr[sep->nr_dcb_creat].in_page_array = 0; + sep->dma_res_arr[sep->nr_dcb_creat].in_page_array = NULL; sep->dma_res_arr[sep->nr_dcb_creat].in_map_array = map_array; sep->dma_res_arr[sep->nr_dcb_creat].in_map_num_entries = 1; } else { *lli_array_ptr = lli_array; sep->dma_res_arr[sep->nr_dcb_creat].out_num_pages = 1; - sep->dma_res_arr[sep->nr_dcb_creat].out_page_array = 0; + sep->dma_res_arr[sep->nr_dcb_creat].out_page_array = NULL; sep->dma_res_arr[sep->nr_dcb_creat].out_map_array = map_array; sep->dma_res_arr[sep->nr_dcb_creat].out_map_num_entries = 1; } @@ -1216,7 +1216,7 @@ static int sep_lock_user_pages(struct sep_device *sep, result = get_user_pages(current, current->mm, app_virt_addr, num_pages, ((in_out_flag == SEP_DRIVER_IN_FLAG) ? 0 : 1), - 0, page_array, 0); + 0, page_array, NULL); up_read(¤t->mm->mmap_sem); @@ -1709,7 +1709,7 @@ static int sep_prepare_input_dma_table(struct sep_device *sep, dev_dbg(&sep->pdev->dev, "block_size is %x\n", block_size); /* Initialize the pages pointers */ - sep->dma_res_arr[sep->nr_dcb_creat].in_page_array = 0; + sep->dma_res_arr[sep->nr_dcb_creat].in_page_array = NULL; sep->dma_res_arr[sep->nr_dcb_creat].in_num_pages = 0; /* Set the kernel address for first table to be allocated */ @@ -1745,7 +1745,7 @@ static int sep_prepare_input_dma_table(struct sep_device *sep, sep->dma_res_arr[sep->nr_dcb_creat].in_num_pages); current_entry = 0; - info_entry_ptr = 0; + info_entry_ptr = NULL; sep_lli_entries = sep->dma_res_arr[sep->nr_dcb_creat].in_num_pages; @@ -1794,7 +1794,7 @@ static int sep_prepare_input_dma_table(struct sep_device *sep, in_lli_table_ptr, ¤t_entry, &num_entries_in_table, table_data_size); - if (info_entry_ptr == 0) { + if (info_entry_ptr == NULL) { /* Set the output parameters to physical addresses */ *lli_table_ptr = sep_shared_area_virt_to_bus(sep, @@ -1877,13 +1877,13 @@ static int sep_construct_dma_tables_from_lli( /* Points to the area where next lli table can be allocated */ u32 lli_table_alloc_addr = 0; /* Input lli table */ - struct sep_lli_entry *in_lli_table_ptr = 0; + struct sep_lli_entry *in_lli_table_ptr = NULL; /* Output lli table */ - struct sep_lli_entry *out_lli_table_ptr = 0; + struct sep_lli_entry *out_lli_table_ptr = NULL; /* Pointer to the info entry of the table - the last entry */ - struct sep_lli_entry *info_in_entry_ptr = 0; + struct sep_lli_entry *info_in_entry_ptr = NULL; /* Pointer to the info entry of the table - the last entry */ - struct sep_lli_entry *info_out_entry_ptr = 0; + struct sep_lli_entry *info_out_entry_ptr = NULL; /* Points to the first entry to be processed in the lli_in_array */ u32 current_in_entry = 0; /* Points to the first entry to be processed in the lli_out_array */ @@ -1999,7 +1999,7 @@ static int sep_construct_dma_tables_from_lli( table_data_size); /* If info entry is null - this is the first table built */ - if (info_in_entry_ptr == 0) { + if (info_in_entry_ptr == NULL) { /* Set the output parameters to physical addresses */ *lli_table_in_ptr = sep_shared_area_virt_to_bus(sep, in_lli_table_ptr); @@ -2136,8 +2136,8 @@ static int sep_prepare_input_output_dma_table(struct sep_device *sep, } /* Initialize the pages pointers */ - sep->dma_res_arr[sep->nr_dcb_creat].in_page_array = 0; - sep->dma_res_arr[sep->nr_dcb_creat].out_page_array = 0; + sep->dma_res_arr[sep->nr_dcb_creat].in_page_array = NULL; + sep->dma_res_arr[sep->nr_dcb_creat].out_page_array = NULL; /* Lock the pages of the buffer and translate them to pages */ if (is_kva == true) { @@ -2264,7 +2264,7 @@ static int sep_prepare_input_output_dma_table_in_dcb(struct sep_device *sep, /* Size of tail */ u32 tail_size = 0; /* Address of the created DCB table */ - struct sep_dcblock *dcb_table_ptr = 0; + struct sep_dcblock *dcb_table_ptr = NULL; /* The physical address of the first input DMA table */ dma_addr_t in_first_mlli_address = 0; /* Number of entries in the first input DMA table */ @@ -2545,7 +2545,7 @@ static int sep_get_static_pool_addr_handler(struct sep_device *sep, unsigned long arg) { struct stat_pool_addr_struct command_args; - u32 *static_pool_addr = 0; + u32 *static_pool_addr = NULL; unsigned long addr_hold; dev_dbg(&sep->pdev->dev, "sep_get_static_pool_addr_handler start\n"); -- cgit v1.2.3 From d1f521c16a4d7e46bbb9c6968076f80be995e0ed Mon Sep 17 00:00:00 2001 From: Peter Huewe Date: Thu, 2 Dec 2010 00:43:34 +0100 Subject: staging/sep: Fix printk format warning This patch fixes gcc's complaints about the wrong format string for size_t arguments: "format '%x' expects type 'unsigned int', but argument has type 'size_t'" Signed-off-by: Peter Huewe Signed-off-by: Greg Kroah-Hartman --- drivers/staging/sep/sep_driver.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/staging/sep/sep_driver.c b/drivers/staging/sep/sep_driver.c index 2216beddecee..f2c216df362e 100644 --- a/drivers/staging/sep/sep_driver.c +++ b/drivers/staging/sep/sep_driver.c @@ -110,7 +110,7 @@ static int sep_load_firmware(struct sep_device *sep) sep->resident_addr); dev_dbg(&sep->pdev->dev, "resident bus is %lx\n", (unsigned long)sep->resident_bus); - dev_dbg(&sep->pdev->dev, "resident size is %08x\n", + dev_dbg(&sep->pdev->dev, "resident size is %08zx\n", sep->resident_size); /* Set addresses for dcache (no loading needed) */ @@ -144,7 +144,7 @@ static int sep_load_firmware(struct sep_device *sep) sep->cache_addr); dev_dbg(&sep->pdev->dev, "cache bus is %08lx\n", (unsigned long)sep->cache_bus); - dev_dbg(&sep->pdev->dev, "cache size is %08x\n", + dev_dbg(&sep->pdev->dev, "cache size is %08zx\n", sep->cache_size); /* Set addresses and load extapp */ @@ -165,7 +165,7 @@ static int sep_load_firmware(struct sep_device *sep) sep->extapp_addr); dev_dbg(&sep->pdev->dev, "extapp bus is %08llx\n", (unsigned long long)sep->extapp_bus); - dev_dbg(&sep->pdev->dev, "extapp size is %08x\n", + dev_dbg(&sep->pdev->dev, "extapp size is %08zx\n", sep->extapp_size); return error; @@ -205,7 +205,7 @@ static int sep_map_and_alloc_shared_area(struct sep_device *sep) return -ENOMEM; } dev_dbg(&sep->pdev->dev, - "shared_addr %x bytes @%p (bus %llx)\n", + "shared_addr %zx bytes @%p (bus %llx)\n", sep->shared_size, sep->shared_addr, (unsigned long long)sep->shared_bus); return 0; @@ -3290,7 +3290,7 @@ static int sep_callback(unsigned long sep_context_pointer) error = -ENOMEM; goto end_function; } - dev_dbg(&sep->pdev->dev, "rar start is %p, phy is %llx, size is %x\n", + dev_dbg(&sep->pdev->dev, "rar start is %p, phy is %llx, size is %zx\n", sep->rar_addr, (unsigned long long)sep->rar_bus, sep->rar_size); @@ -3537,7 +3537,7 @@ static int __devinit sep_probe(struct pci_dev *pdev, } dev_dbg(&sep->pdev->dev, "rar start is %p, phy is %llx," - " size is %x\n", sep->rar_addr, + " size is %zx\n", sep->rar_addr, (unsigned long long)sep->rar_bus, sep->rar_size); } -- cgit v1.2.3 From d5c21fc6155549e7f92fdeb039227f2b8e597e98 Mon Sep 17 00:00:00 2001 From: Matthias Brugger Date: Thu, 2 Dec 2010 14:13:04 +0100 Subject: staging: adis16255 delete driver This patch deletes the adis16255 driver from staging as a similar implementation exists inside the iio subsystem. Signed-off-by: Matthias Brugger Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/Kconfig | 2 - drivers/staging/Makefile | 1 - drivers/staging/adis16255/Kconfig | 11 - drivers/staging/adis16255/Makefile | 1 - drivers/staging/adis16255/adis16255.c | 468 ---------------------------------- drivers/staging/adis16255/adis16255.h | 12 - 6 files changed, 495 deletions(-) delete mode 100644 drivers/staging/adis16255/Kconfig delete mode 100644 drivers/staging/adis16255/Makefile delete mode 100644 drivers/staging/adis16255/adis16255.c delete mode 100644 drivers/staging/adis16255/adis16255.h diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index 1f61914a3ab8..f2d9fe8cde5f 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -143,8 +143,6 @@ source "drivers/staging/cxt1e1/Kconfig" source "drivers/staging/ti-st/Kconfig" -source "drivers/staging/adis16255/Kconfig" - source "drivers/staging/xgifb/Kconfig" source "drivers/staging/msm/Kconfig" diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index 75c0c1ff1cf5..10c72bb1940d 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -54,7 +54,6 @@ obj-$(CONFIG_VIDEO_DT3155) += dt3155v4l/ obj-$(CONFIG_CRYSTALHD) += crystalhd/ obj-$(CONFIG_CXT1E1) += cxt1e1/ obj-$(CONFIG_TI_ST) += ti-st/ -obj-$(CONFIG_ADIS16255) += adis16255/ obj-$(CONFIG_FB_XGI) += xgifb/ obj-$(CONFIG_MSM_STAGING) += msm/ obj-$(CONFIG_EASYCAP) += easycap/ diff --git a/drivers/staging/adis16255/Kconfig b/drivers/staging/adis16255/Kconfig deleted file mode 100644 index a883c1f4478b..000000000000 --- a/drivers/staging/adis16255/Kconfig +++ /dev/null @@ -1,11 +0,0 @@ -config ADIS16255 - tristate "Analog Devices ADIS16250/16255" - depends on SPI && SYSFS - ---help--- - If you say yes here you get support for the Analog Devices - ADIS16250/16255 Low Power Gyroscope. The driver exposes - orientation and gyroscope value, as well as sample rate - to the sysfs. - - This driver can also be built as a module. If so, the module - will be called adis16255. diff --git a/drivers/staging/adis16255/Makefile b/drivers/staging/adis16255/Makefile deleted file mode 100644 index 8c3908106bfa..000000000000 --- a/drivers/staging/adis16255/Makefile +++ /dev/null @@ -1 +0,0 @@ -obj-$(CONFIG_ADIS16255) += adis16255.o diff --git a/drivers/staging/adis16255/adis16255.c b/drivers/staging/adis16255/adis16255.c deleted file mode 100644 index 8d4d7cbab979..000000000000 --- a/drivers/staging/adis16255/adis16255.c +++ /dev/null @@ -1,468 +0,0 @@ -/* - * Analog Devices ADIS16250/ADIS16255 Low Power Gyroscope - * - * Written by: Matthias Brugger - * - * Copyright (C) 2010 Fraunhofer Institute for Integrated Circuits - * - * 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. - * - * 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. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the - * Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -/* - * The driver just has a bare interface to the sysfs (sample rate in Hz, - * orientation (x, y, z) and gyroscope data in °/sec. - * - * It should be added to iio subsystem when this has left staging. - * - */ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include - -#include -#include - -#include "adis16255.h" - -#define ADIS_STATUS 0x3d -#define ADIS_SMPL_PRD_MSB 0x37 -#define ADIS_SMPL_PRD_LSB 0x36 -#define ADIS_MSC_CTRL_MSB 0x35 -#define ADIS_MSC_CTRL_LSB 0x34 -#define ADIS_GPIO_CTRL 0x33 -#define ADIS_ALM_SMPL1 0x25 -#define ADIS_ALM_MAG1 0x21 -#define ADIS_GYRO_SCALE 0x17 -#define ADIS_GYRO_OUT 0x05 -#define ADIS_SUPPLY_OUT 0x03 -#define ADIS_ENDURANCE 0x01 - -/* - * data structure for every sensor - * - * @dev: Driver model representation of the device. - * @spi: Pointer to the spi device which will manage i/o to spi bus. - * @data: Last read data from device. - * @irq_adis: GPIO Number of IRQ signal - * @irq: irq line manage by kernel - * @negative: indicates if sensor is upside down (negative == 1) - * @direction: indicates axis (x, y, z) the sensor is meassuring - */ -struct spi_adis16255_data { - struct device dev; - struct spi_device *spi; - s16 data; - int irq; - u8 negative; - char direction; -}; - -/*-------------------------------------------------------------------------*/ - -static int spi_adis16255_read_data(struct spi_adis16255_data *spiadis, - u8 adr, - u8 *rbuf) -{ - struct spi_device *spi = spiadis->spi; - struct spi_message msg; - struct spi_transfer xfer1, xfer2; - u8 *buf, *rx; - int ret; - - buf = kzalloc(4, GFP_KERNEL); - if (buf == NULL) - return -ENOMEM; - - rx = kzalloc(4, GFP_KERNEL); - if (rx == NULL) { - ret = -ENOMEM; - goto err_buf; - } - - buf[0] = adr; - - spi_message_init(&msg); - memset(&xfer1, 0, sizeof(xfer1)); - memset(&xfer2, 0, sizeof(xfer2)); - - xfer1.tx_buf = buf; - xfer1.rx_buf = buf + 2; - xfer1.len = 2; - xfer1.delay_usecs = 9; - - xfer2.tx_buf = rx + 2; - xfer2.rx_buf = rx; - xfer2.len = 2; - - spi_message_add_tail(&xfer1, &msg); - spi_message_add_tail(&xfer2, &msg); - - ret = spi_sync(spi, &msg); - if (ret == 0) { - rbuf[0] = rx[0]; - rbuf[1] = rx[1]; - } - - kfree(rx); -err_buf: - kfree(buf); - - return ret; -} - -static int spi_adis16255_write_data(struct spi_adis16255_data *spiadis, - u8 adr1, - u8 adr2, - u8 *wbuf) -{ - struct spi_device *spi = spiadis->spi; - struct spi_message msg; - struct spi_transfer xfer1, xfer2; - u8 *buf, *rx; - int ret; - - buf = kmalloc(4, GFP_KERNEL); - if (buf == NULL) - return -ENOMEM; - - rx = kzalloc(4, GFP_KERNEL); - if (rx == NULL) { - ret = -ENOMEM; - goto err_buf; - } - - spi_message_init(&msg); - memset(&xfer1, 0, sizeof(xfer1)); - memset(&xfer2, 0, sizeof(xfer2)); - - buf[0] = adr1 | 0x80; - buf[1] = *wbuf; - - buf[2] = adr2 | 0x80; - buf[3] = *(wbuf + 1); - - xfer1.tx_buf = buf; - xfer1.rx_buf = rx; - xfer1.len = 2; - xfer1.delay_usecs = 9; - - xfer2.tx_buf = buf+2; - xfer2.rx_buf = rx+2; - xfer2.len = 2; - - spi_message_add_tail(&xfer1, &msg); - spi_message_add_tail(&xfer2, &msg); - - ret = spi_sync(spi, &msg); - if (ret != 0) - dev_warn(&spi->dev, "write data to %#x %#x failed\n", - buf[0], buf[2]); - - kfree(rx); -err_buf: - kfree(buf); - return ret; -} - -/*-------------------------------------------------------------------------*/ - -static irqreturn_t adis_irq_thread(int irq, void *dev_id) -{ - struct spi_adis16255_data *spiadis = dev_id; - int status; - u16 value = 0; - - status = spi_adis16255_read_data(spiadis, ADIS_GYRO_OUT, (u8 *)&value); - if (status != 0) { - dev_warn(&spiadis->spi->dev, "SPI FAILED\n"); - goto exit; - } - - /* perform on new data only... */ - if (value & 0x8000) { - /* delete error and new data bit */ - value = value & 0x3fff; - /* set negative value */ - if (value & 0x2000) - value = value | 0xe000; - - if (likely(spiadis->negative)) - value = -value; - - spiadis->data = (s16) value; - } - -exit: - return IRQ_HANDLED; -} - -/*-------------------------------------------------------------------------*/ - -ssize_t adis16255_show_data(struct device *device, - struct device_attribute *da, - char *buf) -{ - struct spi_adis16255_data *spiadis = dev_get_drvdata(device); - return snprintf(buf, PAGE_SIZE, "%d\n", spiadis->data); -} -DEVICE_ATTR(data, S_IRUGO , adis16255_show_data, NULL); - -ssize_t adis16255_show_direction(struct device *device, - struct device_attribute *da, - char *buf) -{ - struct spi_adis16255_data *spiadis = dev_get_drvdata(device); - return snprintf(buf, PAGE_SIZE, "%c\n", spiadis->direction); -} -DEVICE_ATTR(direction, S_IRUGO , adis16255_show_direction, NULL); - -ssize_t adis16255_show_sample_rate(struct device *device, - struct device_attribute *da, - char *buf) -{ - struct spi_adis16255_data *spiadis = dev_get_drvdata(device); - int status = 0; - u16 value = 0; - int ts = 0; - - status = spi_adis16255_read_data(spiadis, ADIS_SMPL_PRD_MSB, - (u8 *)&value); - if (status != 0) - return -EINVAL; - - if (value & 0x80) { - /* timebase = 60.54 ms */ - ts = 60540 * ((0x7f & value) + 1); - } else { - /* timebase = 1.953 ms */ - ts = 1953 * ((0x7f & value) + 1); - } - - return snprintf(buf, PAGE_SIZE, "%d\n", (1000*1000)/ts); -} -DEVICE_ATTR(sample_rate, S_IRUGO , adis16255_show_sample_rate, NULL); - -static struct attribute *adis16255_attributes[] = { - &dev_attr_data.attr, - &dev_attr_direction.attr, - &dev_attr_sample_rate.attr, - NULL -}; - -static const struct attribute_group adis16255_attr_group = { - .attrs = adis16255_attributes, -}; - -/*-------------------------------------------------------------------------*/ - -static int spi_adis16255_shutdown(struct spi_adis16255_data *spiadis) -{ - u16 value = 0; - /* turn sensor off */ - spi_adis16255_write_data(spiadis, - ADIS_SMPL_PRD_MSB, ADIS_SMPL_PRD_LSB, - (u8 *)&value); - spi_adis16255_write_data(spiadis, - ADIS_MSC_CTRL_MSB, ADIS_MSC_CTRL_LSB, - (u8 *)&value); - return 0; -} - -static int spi_adis16255_bringup(struct spi_adis16255_data *spiadis) -{ - int status = 0; - u16 value = 0; - - status = spi_adis16255_read_data(spiadis, ADIS_GYRO_SCALE, - (u8 *)&value); - if (status != 0) - goto err; - if (value != 0x0800) { - dev_warn(&spiadis->spi->dev, "Scale factor is none default " - "value (%.4x)\n", value); - } - - /* timebase = 1.953 ms, Ns = 0 -> 512 Hz sample rate */ - value = 0x0001; - status = spi_adis16255_write_data(spiadis, - ADIS_SMPL_PRD_MSB, ADIS_SMPL_PRD_LSB, - (u8 *)&value); - if (status != 0) - goto err; - - /* start internal self-test */ - value = 0x0400; - status = spi_adis16255_write_data(spiadis, - ADIS_MSC_CTRL_MSB, ADIS_MSC_CTRL_LSB, - (u8 *)&value); - if (status != 0) - goto err; - - /* wait 35 ms to finish self-test */ - msleep(35); - - value = 0x0000; - status = spi_adis16255_read_data(spiadis, ADIS_STATUS, - (u8 *)&value); - if (status != 0) - goto err; - - if (value & 0x23) { - if (value & 0x20) { - dev_warn(&spiadis->spi->dev, "self-test error\n"); - status = -ENODEV; - goto err; - } else if (value & 0x3) { - dev_warn(&spiadis->spi->dev, "Sensor voltage " - "out of range.\n"); - status = -ENODEV; - goto err; - } - } - - /* set interrupt to active high on DIO0 when data ready */ - value = 0x0006; - status = spi_adis16255_write_data(spiadis, - ADIS_MSC_CTRL_MSB, ADIS_MSC_CTRL_LSB, - (u8 *)&value); - if (status != 0) - goto err; - return status; - -err: - spi_adis16255_shutdown(spiadis); - return status; -} - -/*-------------------------------------------------------------------------*/ - -static int __devinit spi_adis16255_probe(struct spi_device *spi) -{ - - struct adis16255_init_data *init_data = spi->dev.platform_data; - struct spi_adis16255_data *spiadis; - int status = 0; - - spiadis = kzalloc(sizeof(*spiadis), GFP_KERNEL); - if (!spiadis) - return -ENOMEM; - - spiadis->spi = spi; - spiadis->direction = init_data->direction; - - if (init_data->negative) - spiadis->negative = 1; - - status = gpio_request(init_data->irq, "adis16255"); - if (status != 0) - goto err; - - status = gpio_direction_input(init_data->irq); - if (status != 0) - goto gpio_err; - - spiadis->irq = gpio_to_irq(init_data->irq); - - status = request_threaded_irq(spiadis->irq, - NULL, adis_irq_thread, - IRQF_DISABLED, "adis-driver", spiadis); - - if (status != 0) { - dev_err(&spi->dev, "IRQ request failed\n"); - goto gpio_err; - } - - dev_dbg(&spi->dev, "GPIO %d IRQ %d\n", init_data->irq, spiadis->irq); - - dev_set_drvdata(&spi->dev, spiadis); - status = sysfs_create_group(&spi->dev.kobj, &adis16255_attr_group); - if (status != 0) - goto irq_err; - - status = spi_adis16255_bringup(spiadis); - if (status != 0) - goto sysfs_err; - - dev_info(&spi->dev, "spi_adis16255 driver added!\n"); - - return status; - -sysfs_err: - sysfs_remove_group(&spiadis->spi->dev.kobj, &adis16255_attr_group); -irq_err: - free_irq(spiadis->irq, spiadis); -gpio_err: - gpio_free(init_data->irq); -err: - kfree(spiadis); - return status; -} - -static int __devexit spi_adis16255_remove(struct spi_device *spi) -{ - struct spi_adis16255_data *spiadis = dev_get_drvdata(&spi->dev); - - spi_adis16255_shutdown(spiadis); - - free_irq(spiadis->irq, spiadis); - gpio_free(irq_to_gpio(spiadis->irq)); - - sysfs_remove_group(&spiadis->spi->dev.kobj, &adis16255_attr_group); - - kfree(spiadis); - - dev_info(&spi->dev, "spi_adis16255 driver removed!\n"); - return 0; -} - -static struct spi_driver spi_adis16255_drv = { - .driver = { - .name = "spi_adis16255", - .owner = THIS_MODULE, - }, - .probe = spi_adis16255_probe, - .remove = __devexit_p(spi_adis16255_remove), -}; - -/*-------------------------------------------------------------------------*/ - -static int __init spi_adis16255_init(void) -{ - return spi_register_driver(&spi_adis16255_drv); -} -module_init(spi_adis16255_init); - -static void __exit spi_adis16255_exit(void) -{ - spi_unregister_driver(&spi_adis16255_drv); -} -module_exit(spi_adis16255_exit); - -MODULE_AUTHOR("Matthias Brugger"); -MODULE_DESCRIPTION("SPI device driver for ADIS16255 sensor"); -MODULE_LICENSE("GPL"); diff --git a/drivers/staging/adis16255/adis16255.h b/drivers/staging/adis16255/adis16255.h deleted file mode 100644 index 03e07001bab2..000000000000 --- a/drivers/staging/adis16255/adis16255.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef ADIS16255_H -#define ADIS16255_H - -#include - -struct adis16255_init_data { - char direction; - u8 negative; - int irq; -}; - -#endif -- cgit v1.2.3 From 7c74cbd01b2698583fb74ebdfcd7ef4c768e6346 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Thu, 23 Sep 2010 11:03:01 +1000 Subject: drm/nouveau: tidy fifo swmthd handler a little Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_irq.c | 56 +++++++++++++++++++---------------- 1 file changed, 31 insertions(+), 25 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_irq.c b/drivers/gpu/drm/nouveau/nouveau_irq.c index 7bfd9e6c9d67..a4fa9e14d66d 100644 --- a/drivers/gpu/drm/nouveau/nouveau_irq.c +++ b/drivers/gpu/drm/nouveau/nouveau_irq.c @@ -108,36 +108,45 @@ nouveau_call_method(struct nouveau_channel *chan, int class, int mthd, int data) } static bool -nouveau_fifo_swmthd(struct nouveau_channel *chan, uint32_t addr, uint32_t data) +nouveau_fifo_swmthd(struct drm_device *dev, u32 chid, u32 addr, u32 data) { - struct drm_device *dev = chan->dev; + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_channel *chan = NULL; + struct nouveau_gpuobj *obj; const int subc = (addr >> 13) & 0x7; const int mthd = addr & 0x1ffc; + bool handled = false; + u32 engine; - if (mthd == 0x0000) { - struct nouveau_gpuobj *gpuobj; - - gpuobj = nouveau_ramht_find(chan, data); - if (!gpuobj) - return false; + if (likely(chid >= 0 && chid < dev_priv->engine.fifo.channels)) + chan = dev_priv->fifos[chid]; + if (unlikely(!chan)) + return false; - if (gpuobj->engine != NVOBJ_ENGINE_SW) - return false; + switch (mthd) { + case 0x0000: /* bind object to subchannel */ + obj = nouveau_ramht_find(chan, data); + if (unlikely(!obj || obj->engine != NVOBJ_ENGINE_SW)) + break; - chan->sw_subchannel[subc] = gpuobj->class; - nv_wr32(dev, NV04_PFIFO_CACHE1_ENGINE, nv_rd32(dev, - NV04_PFIFO_CACHE1_ENGINE) & ~(0xf << subc * 4)); - return true; - } + chan->sw_subchannel[subc] = obj->class; + engine = 0x0000000f << (subc * 4); - /* hw object */ - if (nv_rd32(dev, NV04_PFIFO_CACHE1_ENGINE) & (1 << (subc*4))) - return false; + nv_mask(dev, NV04_PFIFO_CACHE1_ENGINE, engine, 0x00000000); + handled = true; + break; + default: + engine = nv_rd32(dev, NV04_PFIFO_CACHE1_ENGINE); + if (unlikely(((engine >> (subc * 4)) & 0xf) != 0)) + break; - if (nouveau_call_method(chan, chan->sw_subchannel[subc], mthd, data)) - return false; + if (!nouveau_call_method(chan, chan->sw_subchannel[subc], + mthd, data)) + handled = true; + break; + } - return true; + return handled; } static void @@ -150,14 +159,11 @@ nouveau_fifo_irq_handler(struct drm_device *dev) reassign = nv_rd32(dev, NV03_PFIFO_CACHES) & 1; while ((status = nv_rd32(dev, NV03_PFIFO_INTR_0)) && (cnt++ < 100)) { - struct nouveau_channel *chan = NULL; uint32_t chid, get; nv_wr32(dev, NV03_PFIFO_CACHES, 0); chid = engine->fifo.channel_id(dev); - if (chid >= 0 && chid < engine->fifo.channels) - chan = dev_priv->fifos[chid]; get = nv_rd32(dev, NV03_PFIFO_CACHE1_GET); if (status & NV_PFIFO_INTR_CACHE_ERROR) { @@ -184,7 +190,7 @@ nouveau_fifo_irq_handler(struct drm_device *dev) NV40_PFIFO_CACHE1_DATA(ptr)); } - if (!chan || !nouveau_fifo_swmthd(chan, mthd, data)) { + if (!nouveau_fifo_swmthd(dev, chid, mthd, data)) { NV_INFO(dev, "PFIFO_CACHE_ERROR - Ch %d/%d " "Mthd 0x%04x Data 0x%08x\n", chid, (mthd >> 13) & 7, mthd & 0x1ffc, -- cgit v1.2.3 From ceed5f30bf0f515b52246230e5faacf89983fd8f Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 5 Oct 2010 16:41:29 +1000 Subject: drm/nouveau: disallow fbcon accel if running in interrupt context A future commit will add locking to the DRM's channel, and there's numerous problems that come up if we allow printk from an interrupt context to be accelerated. It seems saner to just disallow it completely. As a nice side-effect, all the "to accel or not to accel" logic gets moved out of the chipset-specific code. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_fbcon.c | 137 +++++++++++++++++++++++--------- drivers/gpu/drm/nouveau/nouveau_fbcon.h | 12 +-- drivers/gpu/drm/nouveau/nv04_fbcon.c | 68 ++++++---------- drivers/gpu/drm/nouveau/nv50_fbcon.c | 69 ++++++---------- 4 files changed, 153 insertions(+), 133 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/drivers/gpu/drm/nouveau/nouveau_fbcon.c index 02a4d1fd4845..22e83adcc930 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fbcon.c +++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c @@ -49,6 +49,90 @@ #include "nouveau_fbcon.h" #include "nouveau_dma.h" +static void +nouveau_fbcon_fillrect(struct fb_info *info, const struct fb_fillrect *rect) +{ + struct nouveau_fbdev *nfbdev = info->par; + struct drm_device *dev = nfbdev->dev; + struct drm_nouveau_private *dev_priv = dev->dev_private; + int ret; + + if (info->state != FBINFO_STATE_RUNNING) + return; + + ret = -ENODEV; + if (!in_interrupt() && !(info->flags & FBINFO_HWACCEL_DISABLED)) { + if (dev_priv->card_type < NV_50) + ret = nv04_fbcon_fillrect(info, rect); + else + if (dev_priv->card_type < NV_C0) + ret = nv50_fbcon_fillrect(info, rect); + } + + if (ret == 0) + return; + + if (ret != -ENODEV) + nouveau_fbcon_gpu_lockup(info); + cfb_fillrect(info, rect); +} + +static void +nouveau_fbcon_copyarea(struct fb_info *info, const struct fb_copyarea *image) +{ + struct nouveau_fbdev *nfbdev = info->par; + struct drm_device *dev = nfbdev->dev; + struct drm_nouveau_private *dev_priv = dev->dev_private; + int ret; + + if (info->state != FBINFO_STATE_RUNNING) + return; + + ret = -ENODEV; + if (!in_interrupt() && !(info->flags & FBINFO_HWACCEL_DISABLED)) { + if (dev_priv->card_type < NV_50) + ret = nv04_fbcon_copyarea(info, image); + else + if (dev_priv->card_type < NV_C0) + ret = nv50_fbcon_copyarea(info, image); + } + + if (ret == 0) + return; + + if (ret != -ENODEV) + nouveau_fbcon_gpu_lockup(info); + cfb_copyarea(info, image); +} + +static void +nouveau_fbcon_imageblit(struct fb_info *info, const struct fb_image *image) +{ + struct nouveau_fbdev *nfbdev = info->par; + struct drm_device *dev = nfbdev->dev; + struct drm_nouveau_private *dev_priv = dev->dev_private; + int ret; + + if (info->state != FBINFO_STATE_RUNNING) + return; + + ret = -ENODEV; + if (!in_interrupt() && !(info->flags & FBINFO_HWACCEL_DISABLED)) { + if (dev_priv->card_type < NV_50) + ret = nv04_fbcon_imageblit(info, image); + else + if (dev_priv->card_type < NV_C0) + ret = nv50_fbcon_imageblit(info, image); + } + + if (ret == 0) + return; + + if (ret != -ENODEV) + nouveau_fbcon_gpu_lockup(info); + cfb_imageblit(info, image); +} + static int nouveau_fbcon_sync(struct fb_info *info) { @@ -97,24 +181,9 @@ static struct fb_ops nouveau_fbcon_ops = { .owner = THIS_MODULE, .fb_check_var = drm_fb_helper_check_var, .fb_set_par = drm_fb_helper_set_par, - .fb_fillrect = cfb_fillrect, - .fb_copyarea = cfb_copyarea, - .fb_imageblit = cfb_imageblit, - .fb_sync = nouveau_fbcon_sync, - .fb_pan_display = drm_fb_helper_pan_display, - .fb_blank = drm_fb_helper_blank, - .fb_setcmap = drm_fb_helper_setcmap, - .fb_debug_enter = drm_fb_helper_debug_enter, - .fb_debug_leave = drm_fb_helper_debug_leave, -}; - -static struct fb_ops nv04_fbcon_ops = { - .owner = THIS_MODULE, - .fb_check_var = drm_fb_helper_check_var, - .fb_set_par = drm_fb_helper_set_par, - .fb_fillrect = nv04_fbcon_fillrect, - .fb_copyarea = nv04_fbcon_copyarea, - .fb_imageblit = nv04_fbcon_imageblit, + .fb_fillrect = nouveau_fbcon_fillrect, + .fb_copyarea = nouveau_fbcon_copyarea, + .fb_imageblit = nouveau_fbcon_imageblit, .fb_sync = nouveau_fbcon_sync, .fb_pan_display = drm_fb_helper_pan_display, .fb_blank = drm_fb_helper_blank, @@ -123,14 +192,13 @@ static struct fb_ops nv04_fbcon_ops = { .fb_debug_leave = drm_fb_helper_debug_leave, }; -static struct fb_ops nv50_fbcon_ops = { +static struct fb_ops nouveau_fbcon_sw_ops = { .owner = THIS_MODULE, .fb_check_var = drm_fb_helper_check_var, .fb_set_par = drm_fb_helper_set_par, - .fb_fillrect = nv50_fbcon_fillrect, - .fb_copyarea = nv50_fbcon_copyarea, - .fb_imageblit = nv50_fbcon_imageblit, - .fb_sync = nouveau_fbcon_sync, + .fb_fillrect = cfb_fillrect, + .fb_copyarea = cfb_copyarea, + .fb_imageblit = cfb_imageblit, .fb_pan_display = drm_fb_helper_pan_display, .fb_blank = drm_fb_helper_blank, .fb_setcmap = drm_fb_helper_setcmap, @@ -257,7 +325,7 @@ nouveau_fbcon_create(struct nouveau_fbdev *nfbdev, FBINFO_HWACCEL_FILLRECT | FBINFO_HWACCEL_IMAGEBLIT; info->flags |= FBINFO_CAN_FORCE_OUTPUT; - info->fbops = &nouveau_fbcon_ops; + info->fbops = &nouveau_fbcon_sw_ops; info->fix.smem_start = dev->mode_config.fb_base + nvbo->bo.offset - dev_priv->vm_vram_base; info->fix.smem_len = size; @@ -286,18 +354,15 @@ nouveau_fbcon_create(struct nouveau_fbdev *nfbdev, info->pixmap.scan_align = 1; if (dev_priv->channel && !nouveau_nofbaccel) { - switch (dev_priv->card_type) { - case NV_C0: - break; - case NV_50: - nv50_fbcon_accel_init(info); - info->fbops = &nv50_fbcon_ops; - break; - default: - nv04_fbcon_accel_init(info); - info->fbops = &nv04_fbcon_ops; - break; - }; + ret = -ENODEV; + if (dev_priv->card_type < NV_50) + ret = nv04_fbcon_accel_init(info); + else + if (dev_priv->card_type < NV_C0) + ret = nv50_fbcon_accel_init(info); + + if (ret == 0) + info->fbops = &nouveau_fbcon_ops; } nouveau_fbcon_zfill(dev, nfbdev); diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.h b/drivers/gpu/drm/nouveau/nouveau_fbcon.h index e7e12684c37e..6b933f2c3a5b 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fbcon.h +++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.h @@ -40,13 +40,13 @@ struct nouveau_fbdev { void nouveau_fbcon_restore(void); -void nv04_fbcon_copyarea(struct fb_info *info, const struct fb_copyarea *region); -void nv04_fbcon_fillrect(struct fb_info *info, const struct fb_fillrect *rect); -void nv04_fbcon_imageblit(struct fb_info *info, const struct fb_image *image); +int nv04_fbcon_copyarea(struct fb_info *info, const struct fb_copyarea *region); +int nv04_fbcon_fillrect(struct fb_info *info, const struct fb_fillrect *rect); +int nv04_fbcon_imageblit(struct fb_info *info, const struct fb_image *image); int nv04_fbcon_accel_init(struct fb_info *info); -void nv50_fbcon_fillrect(struct fb_info *info, const struct fb_fillrect *rect); -void nv50_fbcon_copyarea(struct fb_info *info, const struct fb_copyarea *region); -void nv50_fbcon_imageblit(struct fb_info *info, const struct fb_image *image); +int nv50_fbcon_fillrect(struct fb_info *info, const struct fb_fillrect *rect); +int nv50_fbcon_copyarea(struct fb_info *info, const struct fb_copyarea *region); +int nv50_fbcon_imageblit(struct fb_info *info, const struct fb_image *image); int nv50_fbcon_accel_init(struct fb_info *info); void nouveau_fbcon_gpu_lockup(struct fb_info *info); diff --git a/drivers/gpu/drm/nouveau/nv04_fbcon.c b/drivers/gpu/drm/nouveau/nv04_fbcon.c index 33e4c9388bc1..a32804e7d202 100644 --- a/drivers/gpu/drm/nouveau/nv04_fbcon.c +++ b/drivers/gpu/drm/nouveau/nv04_fbcon.c @@ -28,52 +28,39 @@ #include "nouveau_ramht.h" #include "nouveau_fbcon.h" -void +int nv04_fbcon_copyarea(struct fb_info *info, const struct fb_copyarea *region) { struct nouveau_fbdev *nfbdev = info->par; struct drm_device *dev = nfbdev->dev; struct drm_nouveau_private *dev_priv = dev->dev_private; struct nouveau_channel *chan = dev_priv->channel; + int ret; - if (info->state != FBINFO_STATE_RUNNING) - return; - - if (!(info->flags & FBINFO_HWACCEL_DISABLED) && RING_SPACE(chan, 4)) { - nouveau_fbcon_gpu_lockup(info); - } - - if (info->flags & FBINFO_HWACCEL_DISABLED) { - cfb_copyarea(info, region); - return; - } + ret = RING_SPACE(chan, 4); + if (ret) + return ret; BEGIN_RING(chan, NvSubImageBlit, 0x0300, 3); OUT_RING(chan, (region->sy << 16) | region->sx); OUT_RING(chan, (region->dy << 16) | region->dx); OUT_RING(chan, (region->height << 16) | region->width); FIRE_RING(chan); + return 0; } -void +int nv04_fbcon_fillrect(struct fb_info *info, const struct fb_fillrect *rect) { struct nouveau_fbdev *nfbdev = info->par; struct drm_device *dev = nfbdev->dev; struct drm_nouveau_private *dev_priv = dev->dev_private; struct nouveau_channel *chan = dev_priv->channel; + int ret; - if (info->state != FBINFO_STATE_RUNNING) - return; - - if (!(info->flags & FBINFO_HWACCEL_DISABLED) && RING_SPACE(chan, 7)) { - nouveau_fbcon_gpu_lockup(info); - } - - if (info->flags & FBINFO_HWACCEL_DISABLED) { - cfb_fillrect(info, rect); - return; - } + ret = RING_SPACE(chan, 7); + if (ret) + return ret; BEGIN_RING(chan, NvSubGdiRect, 0x02fc, 1); OUT_RING(chan, (rect->rop != ROP_COPY) ? 1 : 3); @@ -87,9 +74,10 @@ nv04_fbcon_fillrect(struct fb_info *info, const struct fb_fillrect *rect) OUT_RING(chan, (rect->dx << 16) | rect->dy); OUT_RING(chan, (rect->width << 16) | rect->height); FIRE_RING(chan); + return 0; } -void +int nv04_fbcon_imageblit(struct fb_info *info, const struct fb_image *image) { struct nouveau_fbdev *nfbdev = info->par; @@ -101,23 +89,14 @@ nv04_fbcon_imageblit(struct fb_info *info, const struct fb_image *image) uint32_t dsize; uint32_t width; uint32_t *data = (uint32_t *)image->data; + int ret; - if (info->state != FBINFO_STATE_RUNNING) - return; - - if (image->depth != 1) { - cfb_imageblit(info, image); - return; - } - - if (!(info->flags & FBINFO_HWACCEL_DISABLED) && RING_SPACE(chan, 8)) { - nouveau_fbcon_gpu_lockup(info); - } + if (image->depth != 1) + return -ENODEV; - if (info->flags & FBINFO_HWACCEL_DISABLED) { - cfb_imageblit(info, image); - return; - } + ret = RING_SPACE(chan, 8); + if (ret) + return ret; width = ALIGN(image->width, 8); dsize = ALIGN(width * image->height, 32) >> 5; @@ -144,11 +123,9 @@ nv04_fbcon_imageblit(struct fb_info *info, const struct fb_image *image) while (dsize) { int iter_len = dsize > 128 ? 128 : dsize; - if (RING_SPACE(chan, iter_len + 1)) { - nouveau_fbcon_gpu_lockup(info); - cfb_imageblit(info, image); - return; - } + ret = RING_SPACE(chan, iter_len + 1); + if (ret) + return ret; BEGIN_RING(chan, NvSubGdiRect, 0x0c00, iter_len); OUT_RINGp(chan, data, iter_len); @@ -157,6 +134,7 @@ nv04_fbcon_imageblit(struct fb_info *info, const struct fb_image *image) } FIRE_RING(chan); + return 0; } static int diff --git a/drivers/gpu/drm/nouveau/nv50_fbcon.c b/drivers/gpu/drm/nouveau/nv50_fbcon.c index 6dcf048eddbc..6edf9dca35ca 100644 --- a/drivers/gpu/drm/nouveau/nv50_fbcon.c +++ b/drivers/gpu/drm/nouveau/nv50_fbcon.c @@ -4,26 +4,18 @@ #include "nouveau_ramht.h" #include "nouveau_fbcon.h" -void +int nv50_fbcon_fillrect(struct fb_info *info, const struct fb_fillrect *rect) { struct nouveau_fbdev *nfbdev = info->par; struct drm_device *dev = nfbdev->dev; struct drm_nouveau_private *dev_priv = dev->dev_private; struct nouveau_channel *chan = dev_priv->channel; + int ret; - if (info->state != FBINFO_STATE_RUNNING) - return; - - if (!(info->flags & FBINFO_HWACCEL_DISABLED) && - RING_SPACE(chan, rect->rop == ROP_COPY ? 7 : 11)) { - nouveau_fbcon_gpu_lockup(info); - } - - if (info->flags & FBINFO_HWACCEL_DISABLED) { - cfb_fillrect(info, rect); - return; - } + ret = RING_SPACE(chan, rect->rop == ROP_COPY ? 7 : 11); + if (ret) + return ret; if (rect->rop != ROP_COPY) { BEGIN_RING(chan, NvSub2D, 0x02ac, 1); @@ -45,27 +37,21 @@ nv50_fbcon_fillrect(struct fb_info *info, const struct fb_fillrect *rect) OUT_RING(chan, 3); } FIRE_RING(chan); + return 0; } -void +int nv50_fbcon_copyarea(struct fb_info *info, const struct fb_copyarea *region) { struct nouveau_fbdev *nfbdev = info->par; struct drm_device *dev = nfbdev->dev; struct drm_nouveau_private *dev_priv = dev->dev_private; struct nouveau_channel *chan = dev_priv->channel; + int ret; - if (info->state != FBINFO_STATE_RUNNING) - return; - - if (!(info->flags & FBINFO_HWACCEL_DISABLED) && RING_SPACE(chan, 12)) { - nouveau_fbcon_gpu_lockup(info); - } - - if (info->flags & FBINFO_HWACCEL_DISABLED) { - cfb_copyarea(info, region); - return; - } + ret = RING_SPACE(chan, 12); + if (ret) + return ret; BEGIN_RING(chan, NvSub2D, 0x0110, 1); OUT_RING(chan, 0); @@ -80,9 +66,10 @@ nv50_fbcon_copyarea(struct fb_info *info, const struct fb_copyarea *region) OUT_RING(chan, 0); OUT_RING(chan, region->sy); FIRE_RING(chan); + return 0; } -void +int nv50_fbcon_imageblit(struct fb_info *info, const struct fb_image *image) { struct nouveau_fbdev *nfbdev = info->par; @@ -92,23 +79,14 @@ nv50_fbcon_imageblit(struct fb_info *info, const struct fb_image *image) uint32_t width, dwords, *data = (uint32_t *)image->data; uint32_t mask = ~(~0 >> (32 - info->var.bits_per_pixel)); uint32_t *palette = info->pseudo_palette; + int ret; - if (info->state != FBINFO_STATE_RUNNING) - return; - - if (image->depth != 1) { - cfb_imageblit(info, image); - return; - } - - if (!(info->flags & FBINFO_HWACCEL_DISABLED) && RING_SPACE(chan, 11)) { - nouveau_fbcon_gpu_lockup(info); - } + if (image->depth != 1) + return -ENODEV; - if (info->flags & FBINFO_HWACCEL_DISABLED) { - cfb_imageblit(info, image); - return; - } + ret = RING_SPACE(chan, 11); + if (ret) + return ret; width = ALIGN(image->width, 32); dwords = (width * image->height) >> 5; @@ -134,11 +112,9 @@ nv50_fbcon_imageblit(struct fb_info *info, const struct fb_image *image) while (dwords) { int push = dwords > 2047 ? 2047 : dwords; - if (RING_SPACE(chan, push + 1)) { - nouveau_fbcon_gpu_lockup(info); - cfb_imageblit(info, image); - return; - } + ret = RING_SPACE(chan, push + 1); + if (ret) + return ret; dwords -= push; @@ -148,6 +124,7 @@ nv50_fbcon_imageblit(struct fb_info *info, const struct fb_image *image) } FIRE_RING(chan); + return 0; } int -- cgit v1.2.3 From 6a6b73f254123851f7f73ab5e57344a569d6a0ab Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 5 Oct 2010 16:53:48 +1000 Subject: drm/nouveau: add per-channel mutex, use to lock access to drm's channel This fixes a race condition between fbcon acceleration and TTM buffer moves. To reproduce: - start X - switch to vt and "while (true); do dmesg; done" - switch to another vt and "sleep 2 && cat /path/to/debugfs/dri/0/evict_vram" - switch back to vt running dmesg We don't make use of this on any other channel yet, they're currently protected by drm_global_mutex. This will change in the near future. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_bo.c | 15 +++++++++++---- drivers/gpu/drm/nouveau/nouveau_channel.c | 1 + drivers/gpu/drm/nouveau/nouveau_drv.h | 2 ++ drivers/gpu/drm/nouveau/nouveau_fbcon.c | 17 ++++++++++++++--- 4 files changed, 28 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index c41e1c200ef5..d8817b4bb189 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c @@ -683,17 +683,24 @@ nouveau_bo_move_m2mf(struct ttm_buffer_object *bo, int evict, bool intr, int ret; chan = nvbo->channel; - if (!chan || nvbo->no_vm) + if (!chan || nvbo->no_vm) { chan = dev_priv->channel; + mutex_lock(&chan->mutex); + } if (dev_priv->card_type < NV_50) ret = nv04_bo_move_m2mf(chan, bo, &bo->mem, new_mem); else ret = nv50_bo_move_m2mf(chan, bo, &bo->mem, new_mem); - if (ret) - return ret; + if (ret == 0) { + ret = nouveau_bo_move_accel_cleanup(chan, nvbo, evict, + no_wait_reserve, + no_wait_gpu, new_mem); + } - return nouveau_bo_move_accel_cleanup(chan, nvbo, evict, no_wait_reserve, no_wait_gpu, new_mem); + if (chan == dev_priv->channel) + mutex_unlock(&chan->mutex); + return ret; } static int diff --git a/drivers/gpu/drm/nouveau/nouveau_channel.c b/drivers/gpu/drm/nouveau/nouveau_channel.c index 373950e34814..8636478c477a 100644 --- a/drivers/gpu/drm/nouveau/nouveau_channel.c +++ b/drivers/gpu/drm/nouveau/nouveau_channel.c @@ -145,6 +145,7 @@ nouveau_channel_alloc(struct drm_device *dev, struct nouveau_channel **chan_ret, chan->file_priv = file_priv; chan->vram_handle = vram_handle; chan->gart_handle = tt_handle; + mutex_init(&chan->mutex); NV_INFO(dev, "Allocating FIFO number %d\n", channel); diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index 1c7db64c03bf..04bc56cf4f1a 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -166,6 +166,8 @@ struct nouveau_channel { struct drm_device *dev; int id; + struct mutex mutex; + /* owner of this fifo */ struct drm_file *file_priv; /* mapping of the fifo itself */ diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/drivers/gpu/drm/nouveau/nouveau_fbcon.c index 22e83adcc930..bc30dbe11d00 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fbcon.c +++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c @@ -62,11 +62,13 @@ nouveau_fbcon_fillrect(struct fb_info *info, const struct fb_fillrect *rect) ret = -ENODEV; if (!in_interrupt() && !(info->flags & FBINFO_HWACCEL_DISABLED)) { + mutex_lock(&dev_priv->channel->mutex); if (dev_priv->card_type < NV_50) ret = nv04_fbcon_fillrect(info, rect); else if (dev_priv->card_type < NV_C0) ret = nv50_fbcon_fillrect(info, rect); + mutex_unlock(&dev_priv->channel->mutex); } if (ret == 0) @@ -90,11 +92,13 @@ nouveau_fbcon_copyarea(struct fb_info *info, const struct fb_copyarea *image) ret = -ENODEV; if (!in_interrupt() && !(info->flags & FBINFO_HWACCEL_DISABLED)) { + mutex_lock(&dev_priv->channel->mutex); if (dev_priv->card_type < NV_50) ret = nv04_fbcon_copyarea(info, image); else if (dev_priv->card_type < NV_C0) ret = nv50_fbcon_copyarea(info, image); + mutex_unlock(&dev_priv->channel->mutex); } if (ret == 0) @@ -118,11 +122,13 @@ nouveau_fbcon_imageblit(struct fb_info *info, const struct fb_image *image) ret = -ENODEV; if (!in_interrupt() && !(info->flags & FBINFO_HWACCEL_DISABLED)) { + mutex_lock(&dev_priv->channel->mutex); if (dev_priv->card_type < NV_50) ret = nv04_fbcon_imageblit(info, image); else if (dev_priv->card_type < NV_C0) ret = nv50_fbcon_imageblit(info, image); + mutex_unlock(&dev_priv->channel->mutex); } if (ret == 0) @@ -142,12 +148,15 @@ nouveau_fbcon_sync(struct fb_info *info) struct nouveau_channel *chan = dev_priv->channel; int ret, i; - if (!chan || !chan->accel_done || + if (!chan || !chan->accel_done || in_interrupt() || info->state != FBINFO_STATE_RUNNING || info->flags & FBINFO_HWACCEL_DISABLED) return 0; - if (RING_SPACE(chan, 4)) { + mutex_lock(&chan->mutex); + ret = RING_SPACE(chan, 4); + if (ret) { + mutex_unlock(&chan->mutex); nouveau_fbcon_gpu_lockup(info); return 0; } @@ -158,6 +167,7 @@ nouveau_fbcon_sync(struct fb_info *info) OUT_RING(chan, 0); nouveau_bo_wr32(chan->notifier_bo, chan->m2mf_ntfy + 3, 0xffffffff); FIRE_RING(chan); + mutex_unlock(&chan->mutex); ret = -EBUSY; for (i = 0; i < 100000; i++) { @@ -353,6 +363,8 @@ nouveau_fbcon_create(struct nouveau_fbdev *nfbdev, info->pixmap.flags = FB_PIXMAP_SYSTEM; info->pixmap.scan_align = 1; + mutex_unlock(&dev->struct_mutex); + if (dev_priv->channel && !nouveau_nofbaccel) { ret = -ENODEV; if (dev_priv->card_type < NV_50) @@ -373,7 +385,6 @@ nouveau_fbcon_create(struct nouveau_fbdev *nfbdev, nouveau_fb->base.height, nvbo->bo.offset, nvbo); - mutex_unlock(&dev->struct_mutex); vga_switcheroo_client_fb_set(dev->pdev, info); return 0; -- cgit v1.2.3 From cff5c1332486ced8ff4180e957e04983cb72a39e Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 6 Oct 2010 16:16:59 +1000 Subject: drm/nouveau: add more fine-grained locking to channel list + structures Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_channel.c | 186 +++++++++++++++++------------ drivers/gpu/drm/nouveau/nouveau_drv.c | 7 +- drivers/gpu/drm/nouveau/nouveau_drv.h | 23 ++-- drivers/gpu/drm/nouveau/nouveau_fence.c | 10 ++ drivers/gpu/drm/nouveau/nouveau_gem.c | 28 +++-- drivers/gpu/drm/nouveau/nouveau_irq.c | 42 ++++--- drivers/gpu/drm/nouveau/nouveau_notifier.c | 10 +- drivers/gpu/drm/nouveau/nouveau_object.c | 34 ++++-- drivers/gpu/drm/nouveau/nouveau_state.c | 8 +- drivers/gpu/drm/nouveau/nv04_fifo.c | 4 +- drivers/gpu/drm/nouveau/nv04_graph.c | 4 +- drivers/gpu/drm/nouveau/nv10_fifo.c | 2 +- drivers/gpu/drm/nouveau/nv10_graph.c | 4 +- drivers/gpu/drm/nouveau/nv40_fifo.c | 2 +- drivers/gpu/drm/nouveau/nv40_graph.c | 2 +- drivers/gpu/drm/nouveau/nv50_fb.c | 6 +- drivers/gpu/drm/nouveau/nv50_fifo.c | 9 +- drivers/gpu/drm/nouveau/nv50_graph.c | 2 +- drivers/gpu/drm/nouveau/nv50_instmem.c | 14 +-- 19 files changed, 236 insertions(+), 161 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_channel.c b/drivers/gpu/drm/nouveau/nouveau_channel.c index 8636478c477a..47bf2d3d658c 100644 --- a/drivers/gpu/drm/nouveau/nouveau_channel.c +++ b/drivers/gpu/drm/nouveau/nouveau_channel.c @@ -107,54 +107,54 @@ nouveau_channel_user_pushbuf_alloc(struct drm_device *dev) int nouveau_channel_alloc(struct drm_device *dev, struct nouveau_channel **chan_ret, struct drm_file *file_priv, - uint32_t vram_handle, uint32_t tt_handle) + uint32_t vram_handle, uint32_t gart_handle) { struct drm_nouveau_private *dev_priv = dev->dev_private; struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo; struct nouveau_channel *chan; - int channel, user; - int ret; - - /* - * Alright, here is the full story - * Nvidia cards have multiple hw fifo contexts (praise them for that, - * no complicated crash-prone context switches) - * We allocate a new context for each app and let it write to it - * directly (woo, full userspace command submission !) - * When there are no more contexts, you lost - */ - for (channel = 0; channel < pfifo->channels; channel++) { - if (dev_priv->fifos[channel] == NULL) - break; - } - - /* no more fifos. you lost. */ - if (channel == pfifo->channels) - return -EINVAL; + unsigned long flags; + int user, ret; - dev_priv->fifos[channel] = kzalloc(sizeof(struct nouveau_channel), - GFP_KERNEL); - if (!dev_priv->fifos[channel]) + /* allocate and lock channel structure */ + chan = kzalloc(sizeof(*chan), GFP_KERNEL); + if (!chan) return -ENOMEM; - chan = dev_priv->fifos[channel]; - INIT_LIST_HEAD(&chan->nvsw.vbl_wait); - INIT_LIST_HEAD(&chan->fence.pending); chan->dev = dev; - chan->id = channel; chan->file_priv = file_priv; chan->vram_handle = vram_handle; - chan->gart_handle = tt_handle; + chan->gart_handle = gart_handle; + + atomic_set(&chan->refcount, 1); mutex_init(&chan->mutex); + mutex_lock(&chan->mutex); - NV_INFO(dev, "Allocating FIFO number %d\n", channel); + /* allocate hw channel id */ + spin_lock_irqsave(&dev_priv->channels.lock, flags); + for (chan->id = 0; chan->id < pfifo->channels; chan->id++) { + if (!dev_priv->channels.ptr[chan->id]) { + dev_priv->channels.ptr[chan->id] = chan; + break; + } + } + spin_unlock_irqrestore(&dev_priv->channels.lock, flags); + + if (chan->id == pfifo->channels) { + mutex_unlock(&chan->mutex); + kfree(chan); + return -ENODEV; + } + + NV_DEBUG(dev, "initialising channel %d\n", chan->id); + INIT_LIST_HEAD(&chan->nvsw.vbl_wait); + INIT_LIST_HEAD(&chan->fence.pending); /* Allocate DMA push buffer */ chan->pushbuf_bo = nouveau_channel_user_pushbuf_alloc(dev); if (!chan->pushbuf_bo) { ret = -ENOMEM; NV_ERROR(dev, "pushbuf %d\n", ret); - nouveau_channel_free(chan); + nouveau_channel_put(&chan); return ret; } @@ -162,18 +162,18 @@ nouveau_channel_alloc(struct drm_device *dev, struct nouveau_channel **chan_ret, /* Locate channel's user control regs */ if (dev_priv->card_type < NV_40) - user = NV03_USER(channel); + user = NV03_USER(chan->id); else if (dev_priv->card_type < NV_50) - user = NV40_USER(channel); + user = NV40_USER(chan->id); else - user = NV50_USER(channel); + user = NV50_USER(chan->id); chan->user = ioremap(pci_resource_start(dev->pdev, 0) + user, PAGE_SIZE); if (!chan->user) { NV_ERROR(dev, "ioremap of regs failed.\n"); - nouveau_channel_free(chan); + nouveau_channel_put(&chan); return -ENOMEM; } chan->user_put = 0x40; @@ -183,15 +183,15 @@ nouveau_channel_alloc(struct drm_device *dev, struct nouveau_channel **chan_ret, ret = nouveau_notifier_init_channel(chan); if (ret) { NV_ERROR(dev, "ntfy %d\n", ret); - nouveau_channel_free(chan); + nouveau_channel_put(&chan); return ret; } /* Setup channel's default objects */ - ret = nouveau_gpuobj_channel_init(chan, vram_handle, tt_handle); + ret = nouveau_gpuobj_channel_init(chan, vram_handle, gart_handle); if (ret) { NV_ERROR(dev, "gpuobj %d\n", ret); - nouveau_channel_free(chan); + nouveau_channel_put(&chan); return ret; } @@ -199,7 +199,7 @@ nouveau_channel_alloc(struct drm_device *dev, struct nouveau_channel **chan_ret, ret = nouveau_channel_pushbuf_ctxdma_init(chan); if (ret) { NV_ERROR(dev, "pbctxdma %d\n", ret); - nouveau_channel_free(chan); + nouveau_channel_put(&chan); return ret; } @@ -209,14 +209,14 @@ nouveau_channel_alloc(struct drm_device *dev, struct nouveau_channel **chan_ret, /* Create a graphics context for new channel */ ret = pgraph->create_context(chan); if (ret) { - nouveau_channel_free(chan); + nouveau_channel_put(&chan); return ret; } /* Construct inital RAMFC for new channel */ ret = pfifo->create_context(chan); if (ret) { - nouveau_channel_free(chan); + nouveau_channel_put(&chan); return ret; } @@ -226,33 +226,70 @@ nouveau_channel_alloc(struct drm_device *dev, struct nouveau_channel **chan_ret, if (!ret) ret = nouveau_fence_channel_init(chan); if (ret) { - nouveau_channel_free(chan); + nouveau_channel_put(&chan); return ret; } nouveau_debugfs_channel_init(chan); - NV_INFO(dev, "%s: initialised FIFO %d\n", __func__, channel); + NV_DEBUG(dev, "channel %d initialised\n", chan->id); *chan_ret = chan; return 0; } -/* stops a fifo */ +struct nouveau_channel * +nouveau_channel_get(struct drm_device *dev, struct drm_file *file_priv, int id) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_channel *chan = ERR_PTR(-ENODEV); + unsigned long flags; + + spin_lock_irqsave(&dev_priv->channels.lock, flags); + chan = dev_priv->channels.ptr[id]; + + if (unlikely(!chan || atomic_read(&chan->refcount) == 0)) { + spin_unlock_irqrestore(&dev_priv->channels.lock, flags); + return ERR_PTR(-EINVAL); + } + + if (unlikely(file_priv && chan->file_priv != file_priv)) { + spin_unlock_irqrestore(&dev_priv->channels.lock, flags); + return ERR_PTR(-EINVAL); + } + + atomic_inc(&chan->refcount); + spin_unlock_irqrestore(&dev_priv->channels.lock, flags); + + mutex_lock(&chan->mutex); + return chan; +} + void -nouveau_channel_free(struct nouveau_channel *chan) +nouveau_channel_put(struct nouveau_channel **pchan) { + struct nouveau_channel *chan = *pchan; struct drm_device *dev = chan->dev; struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo; + struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; unsigned long flags; int ret; - NV_INFO(dev, "%s: freeing fifo %d\n", __func__, chan->id); + /* unlock the channel */ + mutex_unlock(&chan->mutex); + + /* decrement the refcount, and we're done if there's still refs */ + if (likely(!atomic_dec_and_test(&chan->refcount))) { + *pchan = NULL; + return; + } + /* noone wants the channel anymore */ + NV_DEBUG(dev, "freeing channel %d\n", chan->id); nouveau_debugfs_channel_fini(chan); + *pchan = NULL; - /* Give outstanding push buffers a chance to complete */ + /* give it chance to idle */ nouveau_fence_update(chan); if (chan->fence.sequence != chan->fence.sequence_ack) { struct nouveau_fence *fence = NULL; @@ -267,13 +304,13 @@ nouveau_channel_free(struct nouveau_channel *chan) NV_ERROR(dev, "Failed to idle channel %d.\n", chan->id); } - /* Ensure all outstanding fences are signaled. They should be if the + /* ensure all outstanding fences are signaled. they should be if the * above attempts at idling were OK, but if we failed this'll tell TTM * we're done with the buffers. */ nouveau_fence_channel_fini(chan); - /* This will prevent pfifo from switching channels. */ + /* boot it off the hardware */ pfifo->reassign(dev, false); /* We want to give pgraph a chance to idle and get rid of all potential @@ -302,7 +339,14 @@ nouveau_channel_free(struct nouveau_channel *chan) spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags); - /* Release the channel's resources */ + /* aside from its resources, the channel should now be dead, + * remove it from the channel list + */ + spin_lock_irqsave(&dev_priv->channels.lock, flags); + dev_priv->channels.ptr[chan->id] = NULL; + spin_unlock_irqrestore(&dev_priv->channels.lock, flags); + + /* destroy any resources the channel owned */ nouveau_gpuobj_ref(NULL, &chan->pushbuf); if (chan->pushbuf_bo) { nouveau_bo_unmap(chan->pushbuf_bo); @@ -314,7 +358,6 @@ nouveau_channel_free(struct nouveau_channel *chan) if (chan->user) iounmap(chan->user); - dev_priv->fifos[chan->id] = NULL; kfree(chan); } @@ -324,31 +367,20 @@ nouveau_channel_cleanup(struct drm_device *dev, struct drm_file *file_priv) { struct drm_nouveau_private *dev_priv = dev->dev_private; struct nouveau_engine *engine = &dev_priv->engine; + struct nouveau_channel *chan; int i; NV_DEBUG(dev, "clearing FIFO enables from file_priv\n"); for (i = 0; i < engine->fifo.channels; i++) { - struct nouveau_channel *chan = dev_priv->fifos[i]; + chan = nouveau_channel_get(dev, file_priv, i); + if (IS_ERR(chan)) + continue; - if (chan && chan->file_priv == file_priv) - nouveau_channel_free(chan); + atomic_dec(&chan->refcount); + nouveau_channel_put(&chan); } } -int -nouveau_channel_owner(struct drm_device *dev, struct drm_file *file_priv, - int channel) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_engine *engine = &dev_priv->engine; - - if (channel >= engine->fifo.channels) - return 0; - if (dev_priv->fifos[channel] == NULL) - return 0; - - return (dev_priv->fifos[channel]->file_priv == file_priv); -} /*********************************** * ioctls wrapping the functions @@ -396,24 +428,26 @@ nouveau_ioctl_fifo_alloc(struct drm_device *dev, void *data, /* Named memory object area */ ret = drm_gem_handle_create(file_priv, chan->notifier_bo->gem, &init->notifier_handle); - if (ret) { - nouveau_channel_free(chan); - return ret; - } - return 0; + if (ret == 0) + atomic_inc(&chan->refcount); /* userspace reference */ + nouveau_channel_put(&chan); + return ret; } static int nouveau_ioctl_fifo_free(struct drm_device *dev, void *data, struct drm_file *file_priv) { - struct drm_nouveau_channel_free *cfree = data; + struct drm_nouveau_channel_free *req = data; struct nouveau_channel *chan; - NOUVEAU_GET_USER_CHANNEL_WITH_RETURN(cfree->channel, file_priv, chan); + chan = nouveau_channel_get(dev, file_priv, req->channel); + if (IS_ERR(chan)) + return PTR_ERR(chan); - nouveau_channel_free(chan); + atomic_dec(&chan->refcount); + nouveau_channel_put(&chan); return 0; } diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.c b/drivers/gpu/drm/nouveau/nouveau_drv.c index 90875494a65a..f139aa2cbe5c 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.c +++ b/drivers/gpu/drm/nouveau/nouveau_drv.c @@ -195,9 +195,8 @@ nouveau_pci_suspend(struct pci_dev *pdev, pm_message_t pm_state) for (i = 0; i < pfifo->channels; i++) { struct nouveau_fence *fence = NULL; - chan = dev_priv->fifos[i]; - if (!chan || (dev_priv->card_type >= NV_50 && - chan == dev_priv->fifos[0])) + chan = dev_priv->channels.ptr[i]; + if (!chan || !chan->pushbuf_bo) continue; ret = nouveau_fence_new(chan, &fence, true); @@ -313,7 +312,7 @@ nouveau_pci_resume(struct pci_dev *pdev) int j; for (i = 0; i < dev_priv->engine.fifo.channels; i++) { - chan = dev_priv->fifos[i]; + chan = dev_priv->channels.ptr[i]; if (!chan || !chan->pushbuf_bo) continue; diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index 04bc56cf4f1a..c3f102125083 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -166,6 +166,7 @@ struct nouveau_channel { struct drm_device *dev; int id; + atomic_t refcount; struct mutex mutex; /* owner of this fifo */ @@ -607,8 +608,10 @@ struct drm_nouveau_private { struct nouveau_bo *bo; } fence; - int fifo_alloc_count; - struct nouveau_channel *fifos[NOUVEAU_MAX_CHANNEL_NR]; + struct { + spinlock_t lock; + struct nouveau_channel *ptr[NOUVEAU_MAX_CHANNEL_NR]; + } channels; struct nouveau_engine engine; struct nouveau_channel *channel; @@ -721,16 +724,6 @@ nouveau_bo_ref(struct nouveau_bo *ref, struct nouveau_bo **pnvbo) return 0; } -#define NOUVEAU_GET_USER_CHANNEL_WITH_RETURN(id, cl, ch) do { \ - struct drm_nouveau_private *nv = dev->dev_private; \ - if (!nouveau_channel_owner(dev, (cl), (id))) { \ - NV_ERROR(dev, "pid %d doesn't own channel %d\n", \ - DRM_CURRENTPID, (id)); \ - return -EPERM; \ - } \ - (ch) = nv->fifos[(id)]; \ -} while (0) - /* nouveau_drv.c */ extern int nouveau_agpmode; extern int nouveau_duallink; @@ -805,13 +798,13 @@ extern int nouveau_ioctl_notifier_free(struct drm_device *, void *data, extern struct drm_ioctl_desc nouveau_ioctls[]; extern int nouveau_max_ioctl; extern void nouveau_channel_cleanup(struct drm_device *, struct drm_file *); -extern int nouveau_channel_owner(struct drm_device *, struct drm_file *, - int channel); extern int nouveau_channel_alloc(struct drm_device *dev, struct nouveau_channel **chan, struct drm_file *file_priv, uint32_t fb_ctxdma, uint32_t tt_ctxdma); -extern void nouveau_channel_free(struct nouveau_channel *); +extern struct nouveau_channel * +nouveau_channel_get(struct drm_device *, struct drm_file *, int id); +extern void nouveau_channel_put(struct nouveau_channel **); /* nouveau_object.c */ extern int nouveau_gpuobj_early_init(struct drm_device *); diff --git a/drivers/gpu/drm/nouveau/nouveau_fence.c b/drivers/gpu/drm/nouveau/nouveau_fence.c index ab1bbfbf266e..42694b122eef 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fence.c +++ b/drivers/gpu/drm/nouveau/nouveau_fence.c @@ -393,8 +393,18 @@ nouveau_fence_sync(struct nouveau_fence *fence, return nouveau_fence_wait(fence, NULL, false, false); } + /* try to take wchan's mutex, if we can't take it right away + * we have to fallback to software sync to prevent locking + * order issues + */ + if (!mutex_trylock(&wchan->mutex)) { + free_semaphore(&sema->ref); + return nouveau_fence_wait(fence, NULL, false, false); + } + /* Make wchan wait until it gets signalled */ ret = emit_semaphore(wchan, NV_SW_SEMAPHORE_ACQUIRE, sema); + mutex_unlock(&wchan->mutex); if (ret) goto out; diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c index 1f2301d26c0a..454d5ceb28f1 100644 --- a/drivers/gpu/drm/nouveau/nouveau_gem.c +++ b/drivers/gpu/drm/nouveau/nouveau_gem.c @@ -146,11 +146,6 @@ nouveau_gem_ioctl_new(struct drm_device *dev, void *data, if (unlikely(dev_priv->ttm.bdev.dev_mapping == NULL)) dev_priv->ttm.bdev.dev_mapping = dev_priv->dev->dev_mapping; - if (req->channel_hint) { - NOUVEAU_GET_USER_CHANNEL_WITH_RETURN(req->channel_hint, - file_priv, chan); - } - if (req->info.domain & NOUVEAU_GEM_DOMAIN_VRAM) flags |= TTM_PL_FLAG_VRAM; if (req->info.domain & NOUVEAU_GEM_DOMAIN_GART) @@ -161,10 +156,18 @@ nouveau_gem_ioctl_new(struct drm_device *dev, void *data, if (!nouveau_gem_tile_flags_valid(dev, req->info.tile_flags)) return -EINVAL; + if (req->channel_hint) { + chan = nouveau_channel_get(dev, file_priv, req->channel_hint); + if (IS_ERR(chan)) + return PTR_ERR(chan); + } + ret = nouveau_gem_new(dev, chan, req->info.size, req->align, flags, req->info.tile_mode, req->info.tile_flags, false, (req->info.domain & NOUVEAU_GEM_DOMAIN_MAPPABLE), &nvbo); + if (chan) + nouveau_channel_put(&chan); if (ret) return ret; @@ -341,9 +344,7 @@ retry: return -EINVAL; } - mutex_unlock(&drm_global_mutex); ret = ttm_bo_wait_cpu(&nvbo->bo, false); - mutex_lock(&drm_global_mutex); if (ret) { NV_ERROR(dev, "fail wait_cpu\n"); return ret; @@ -585,7 +586,9 @@ nouveau_gem_ioctl_pushbuf(struct drm_device *dev, void *data, struct nouveau_fence *fence = NULL; int i, j, ret = 0, do_reloc = 0; - NOUVEAU_GET_USER_CHANNEL_WITH_RETURN(req->channel, file_priv, chan); + chan = nouveau_channel_get(dev, file_priv, req->channel); + if (IS_ERR(chan)) + return PTR_ERR(chan); req->vram_available = dev_priv->fb_aper_free; req->gart_available = dev_priv->gart_info.aper_free; @@ -595,28 +598,34 @@ nouveau_gem_ioctl_pushbuf(struct drm_device *dev, void *data, if (unlikely(req->nr_push > NOUVEAU_GEM_MAX_PUSH)) { NV_ERROR(dev, "pushbuf push count exceeds limit: %d max %d\n", req->nr_push, NOUVEAU_GEM_MAX_PUSH); + nouveau_channel_put(&chan); return -EINVAL; } if (unlikely(req->nr_buffers > NOUVEAU_GEM_MAX_BUFFERS)) { NV_ERROR(dev, "pushbuf bo count exceeds limit: %d max %d\n", req->nr_buffers, NOUVEAU_GEM_MAX_BUFFERS); + nouveau_channel_put(&chan); return -EINVAL; } if (unlikely(req->nr_relocs > NOUVEAU_GEM_MAX_RELOCS)) { NV_ERROR(dev, "pushbuf reloc count exceeds limit: %d max %d\n", req->nr_relocs, NOUVEAU_GEM_MAX_RELOCS); + nouveau_channel_put(&chan); return -EINVAL; } push = u_memcpya(req->push, req->nr_push, sizeof(*push)); - if (IS_ERR(push)) + if (IS_ERR(push)) { + nouveau_channel_put(&chan); return PTR_ERR(push); + } bo = u_memcpya(req->buffers, req->nr_buffers, sizeof(*bo)); if (IS_ERR(bo)) { kfree(push); + nouveau_channel_put(&chan); return PTR_ERR(bo); } @@ -750,6 +759,7 @@ out_next: req->suffix1 = 0x00000000; } + nouveau_channel_put(&chan); return ret; } diff --git a/drivers/gpu/drm/nouveau/nouveau_irq.c b/drivers/gpu/drm/nouveau/nouveau_irq.c index a4fa9e14d66d..c5e37bc17192 100644 --- a/drivers/gpu/drm/nouveau/nouveau_irq.c +++ b/drivers/gpu/drm/nouveau/nouveau_irq.c @@ -113,15 +113,17 @@ nouveau_fifo_swmthd(struct drm_device *dev, u32 chid, u32 addr, u32 data) struct drm_nouveau_private *dev_priv = dev->dev_private; struct nouveau_channel *chan = NULL; struct nouveau_gpuobj *obj; + unsigned long flags; const int subc = (addr >> 13) & 0x7; const int mthd = addr & 0x1ffc; bool handled = false; u32 engine; + spin_lock_irqsave(&dev_priv->channels.lock, flags); if (likely(chid >= 0 && chid < dev_priv->engine.fifo.channels)) - chan = dev_priv->fifos[chid]; + chan = dev_priv->channels.ptr[chid]; if (unlikely(!chan)) - return false; + goto out; switch (mthd) { case 0x0000: /* bind object to subchannel */ @@ -146,6 +148,8 @@ nouveau_fifo_swmthd(struct drm_device *dev, u32 chid, u32 addr, u32 data) break; } +out: + spin_unlock_irqrestore(&dev_priv->channels.lock, flags); return handled; } @@ -398,6 +402,8 @@ static int nouveau_graph_chid_from_grctx(struct drm_device *dev) { struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_channel *chan; + unsigned long flags; uint32_t inst; int i; @@ -407,27 +413,29 @@ nouveau_graph_chid_from_grctx(struct drm_device *dev) if (dev_priv->card_type < NV_50) { inst = (nv_rd32(dev, 0x40032c) & 0xfffff) << 4; + spin_lock_irqsave(&dev_priv->channels.lock, flags); for (i = 0; i < dev_priv->engine.fifo.channels; i++) { - struct nouveau_channel *chan = dev_priv->fifos[i]; - + chan = dev_priv->channels.ptr[i]; if (!chan || !chan->ramin_grctx) continue; if (inst == chan->ramin_grctx->pinst) break; } + spin_unlock_irqrestore(&dev_priv->channels.lock, flags); } else { inst = (nv_rd32(dev, 0x40032c) & 0xfffff) << 12; + spin_lock_irqsave(&dev_priv->channels.lock, flags); for (i = 0; i < dev_priv->engine.fifo.channels; i++) { - struct nouveau_channel *chan = dev_priv->fifos[i]; - + chan = dev_priv->channels.ptr[i]; if (!chan || !chan->ramin) continue; if (inst == chan->ramin->vinst) break; } + spin_unlock_irqrestore(&dev_priv->channels.lock, flags); } @@ -449,7 +457,8 @@ nouveau_graph_trapped_channel(struct drm_device *dev, int *channel_ret) else channel = nouveau_graph_chid_from_grctx(dev); - if (channel >= engine->fifo.channels || !dev_priv->fifos[channel]) { + if (channel >= engine->fifo.channels || + !dev_priv->channels.ptr[channel]) { NV_ERROR(dev, "AIII, invalid/inactive channel id %d\n", channel); return -EINVAL; } @@ -532,14 +541,19 @@ nouveau_pgraph_intr_swmthd(struct drm_device *dev, struct nouveau_pgraph_trap *trap) { struct drm_nouveau_private *dev_priv = dev->dev_private; + unsigned long flags; + int ret = -EINVAL; + + spin_lock_irqsave(&dev_priv->channels.lock, flags); + if (trap->channel > 0 && + trap->channel < dev_priv->engine.fifo.channels && + dev_priv->channels.ptr[trap->channel]) { + ret = nouveau_call_method(dev_priv->channels.ptr[trap->channel], + trap->class, trap->mthd, trap->data); + } + spin_unlock_irqrestore(&dev_priv->channels.lock, flags); - if (trap->channel < 0 || - trap->channel >= dev_priv->engine.fifo.channels || - !dev_priv->fifos[trap->channel]) - return -ENODEV; - - return nouveau_call_method(dev_priv->fifos[trap->channel], - trap->class, trap->mthd, trap->data); + return ret; } static inline void diff --git a/drivers/gpu/drm/nouveau/nouveau_notifier.c b/drivers/gpu/drm/nouveau/nouveau_notifier.c index 2cc59f8c658b..2c5a1f66f7f0 100644 --- a/drivers/gpu/drm/nouveau/nouveau_notifier.c +++ b/drivers/gpu/drm/nouveau/nouveau_notifier.c @@ -185,11 +185,11 @@ nouveau_ioctl_notifier_alloc(struct drm_device *dev, void *data, struct nouveau_channel *chan; int ret; - NOUVEAU_GET_USER_CHANNEL_WITH_RETURN(na->channel, file_priv, chan); + chan = nouveau_channel_get(dev, file_priv, na->channel); + if (IS_ERR(chan)) + return PTR_ERR(chan); ret = nouveau_notifier_alloc(chan, na->handle, na->size, &na->offset); - if (ret) - return ret; - - return 0; + nouveau_channel_put(&chan); + return ret; } diff --git a/drivers/gpu/drm/nouveau/nouveau_object.c b/drivers/gpu/drm/nouveau/nouveau_object.c index dd572adca02a..068441c4b563 100644 --- a/drivers/gpu/drm/nouveau/nouveau_object.c +++ b/drivers/gpu/drm/nouveau/nouveau_object.c @@ -876,8 +876,6 @@ int nouveau_ioctl_grobj_alloc(struct drm_device *dev, void *data, struct nouveau_channel *chan; int ret; - NOUVEAU_GET_USER_CHANNEL_WITH_RETURN(init->channel, file_priv, chan); - if (init->handle == ~0) return -EINVAL; @@ -893,8 +891,14 @@ int nouveau_ioctl_grobj_alloc(struct drm_device *dev, void *data, return -EPERM; } - if (nouveau_ramht_find(chan, init->handle)) - return -EEXIST; + chan = nouveau_channel_get(dev, file_priv, init->channel); + if (IS_ERR(chan)) + return PTR_ERR(chan); + + if (nouveau_ramht_find(chan, init->handle)) { + ret = -EEXIST; + goto out; + } if (!grc->software) ret = nouveau_gpuobj_gr_new(chan, grc->id, &gr); @@ -903,7 +907,7 @@ int nouveau_ioctl_grobj_alloc(struct drm_device *dev, void *data, if (ret) { NV_ERROR(dev, "Error creating object: %d (%d/0x%08x)\n", ret, init->channel, init->handle); - return ret; + goto out; } ret = nouveau_ramht_insert(chan, init->handle, gr); @@ -911,10 +915,11 @@ int nouveau_ioctl_grobj_alloc(struct drm_device *dev, void *data, if (ret) { NV_ERROR(dev, "Error referencing object: %d (%d/0x%08x)\n", ret, init->channel, init->handle); - return ret; } - return 0; +out: + nouveau_channel_put(&chan); + return ret; } int nouveau_ioctl_gpuobj_free(struct drm_device *dev, void *data, @@ -923,15 +928,20 @@ int nouveau_ioctl_gpuobj_free(struct drm_device *dev, void *data, struct drm_nouveau_gpuobj_free *objfree = data; struct nouveau_gpuobj *gpuobj; struct nouveau_channel *chan; + int ret = -ENOENT; - NOUVEAU_GET_USER_CHANNEL_WITH_RETURN(objfree->channel, file_priv, chan); + chan = nouveau_channel_get(dev, file_priv, objfree->channel); + if (IS_ERR(chan)) + return PTR_ERR(chan); gpuobj = nouveau_ramht_find(chan, objfree->handle); - if (!gpuobj) - return -ENOENT; + if (gpuobj) { + nouveau_ramht_remove(chan, objfree->handle); + ret = 0; + } - nouveau_ramht_remove(chan, objfree->handle); - return 0; + nouveau_channel_put(&chan); + return ret; } u32 diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c index 049f755567e5..513c1063fb5e 100644 --- a/drivers/gpu/drm/nouveau/nouveau_state.c +++ b/drivers/gpu/drm/nouveau/nouveau_state.c @@ -516,11 +516,11 @@ nouveau_card_init_channel(struct drm_device *dev) if (ret) goto out_err; + mutex_unlock(&dev_priv->channel->mutex); return 0; out_err: - nouveau_channel_free(dev_priv->channel); - dev_priv->channel = NULL; + nouveau_channel_put(&dev_priv->channel); return ret; } @@ -567,6 +567,7 @@ nouveau_card_init(struct drm_device *dev) if (ret) goto out; engine = &dev_priv->engine; + spin_lock_init(&dev_priv->channels.lock); spin_lock_init(&dev_priv->context_switch_lock); /* Make the CRTCs and I2C buses accessible */ @@ -713,8 +714,7 @@ static void nouveau_card_takedown(struct drm_device *dev) if (!engine->graph.accel_blocked) { nouveau_fence_fini(dev); - nouveau_channel_free(dev_priv->channel); - dev_priv->channel = NULL; + nouveau_channel_put(&dev_priv->channel); } if (!nouveau_noaccel) { diff --git a/drivers/gpu/drm/nouveau/nv04_fifo.c b/drivers/gpu/drm/nouveau/nv04_fifo.c index 708293b7ddcd..25c439dcdfd9 100644 --- a/drivers/gpu/drm/nouveau/nv04_fifo.c +++ b/drivers/gpu/drm/nouveau/nv04_fifo.c @@ -208,7 +208,7 @@ nv04_fifo_unload_context(struct drm_device *dev) if (chid < 0 || chid >= dev_priv->engine.fifo.channels) return 0; - chan = dev_priv->fifos[chid]; + chan = dev_priv->channels.ptr[chid]; if (!chan) { NV_ERROR(dev, "Inactive channel on PFIFO: %d\n", chid); return -EINVAL; @@ -289,7 +289,7 @@ nv04_fifo_init(struct drm_device *dev) pfifo->reassign(dev, true); for (i = 0; i < dev_priv->engine.fifo.channels; i++) { - if (dev_priv->fifos[i]) { + if (dev_priv->channels.ptr[i]) { uint32_t mode = nv_rd32(dev, NV04_PFIFO_MODE); nv_wr32(dev, NV04_PFIFO_MODE, mode | (1 << i)); } diff --git a/drivers/gpu/drm/nouveau/nv04_graph.c b/drivers/gpu/drm/nouveau/nv04_graph.c index c8973421b635..98b9525c1ebd 100644 --- a/drivers/gpu/drm/nouveau/nv04_graph.c +++ b/drivers/gpu/drm/nouveau/nv04_graph.c @@ -357,7 +357,7 @@ nv04_graph_channel(struct drm_device *dev) if (chid >= dev_priv->engine.fifo.channels) return NULL; - return dev_priv->fifos[chid]; + return dev_priv->channels.ptr[chid]; } void @@ -376,7 +376,7 @@ nv04_graph_context_switch(struct drm_device *dev) /* Load context for next channel */ chid = dev_priv->engine.fifo.channel_id(dev); - chan = dev_priv->fifos[chid]; + chan = dev_priv->channels.ptr[chid]; if (chan) nv04_graph_load_context(chan); diff --git a/drivers/gpu/drm/nouveau/nv10_fifo.c b/drivers/gpu/drm/nouveau/nv10_fifo.c index f1b03ad58fd5..39328fcce709 100644 --- a/drivers/gpu/drm/nouveau/nv10_fifo.c +++ b/drivers/gpu/drm/nouveau/nv10_fifo.c @@ -241,7 +241,7 @@ nv10_fifo_init(struct drm_device *dev) pfifo->reassign(dev, true); for (i = 0; i < dev_priv->engine.fifo.channels; i++) { - if (dev_priv->fifos[i]) { + if (dev_priv->channels.ptr[i]) { uint32_t mode = nv_rd32(dev, NV04_PFIFO_MODE); nv_wr32(dev, NV04_PFIFO_MODE, mode | (1 << i)); } diff --git a/drivers/gpu/drm/nouveau/nv10_graph.c b/drivers/gpu/drm/nouveau/nv10_graph.c index 8e68c9731159..cd931b57cf05 100644 --- a/drivers/gpu/drm/nouveau/nv10_graph.c +++ b/drivers/gpu/drm/nouveau/nv10_graph.c @@ -802,7 +802,7 @@ nv10_graph_context_switch(struct drm_device *dev) /* Load context for next channel */ chid = (nv_rd32(dev, NV04_PGRAPH_TRAPPED_ADDR) >> 20) & 0x1f; - chan = dev_priv->fifos[chid]; + chan = dev_priv->channels.ptr[chid]; if (chan && chan->pgraph_ctx) nv10_graph_load_context(chan); @@ -833,7 +833,7 @@ nv10_graph_channel(struct drm_device *dev) if (chid >= dev_priv->engine.fifo.channels) return NULL; - return dev_priv->fifos[chid]; + return dev_priv->channels.ptr[chid]; } int nv10_graph_create_context(struct nouveau_channel *chan) diff --git a/drivers/gpu/drm/nouveau/nv40_fifo.c b/drivers/gpu/drm/nouveau/nv40_fifo.c index d337b8b28cdd..3c7be3dc8b88 100644 --- a/drivers/gpu/drm/nouveau/nv40_fifo.c +++ b/drivers/gpu/drm/nouveau/nv40_fifo.c @@ -301,7 +301,7 @@ nv40_fifo_init(struct drm_device *dev) pfifo->reassign(dev, true); for (i = 0; i < dev_priv->engine.fifo.channels; i++) { - if (dev_priv->fifos[i]) { + if (dev_priv->channels.ptr[i]) { uint32_t mode = nv_rd32(dev, NV04_PFIFO_MODE); nv_wr32(dev, NV04_PFIFO_MODE, mode | (1 << i)); } diff --git a/drivers/gpu/drm/nouveau/nv40_graph.c b/drivers/gpu/drm/nouveau/nv40_graph.c index 7ee1b91569b8..e0b41a26447f 100644 --- a/drivers/gpu/drm/nouveau/nv40_graph.c +++ b/drivers/gpu/drm/nouveau/nv40_graph.c @@ -42,7 +42,7 @@ nv40_graph_channel(struct drm_device *dev) inst = (inst & NV40_PGRAPH_CTXCTL_CUR_INSTANCE) << 4; for (i = 0; i < dev_priv->engine.fifo.channels; i++) { - struct nouveau_channel *chan = dev_priv->fifos[i]; + struct nouveau_channel *chan = dev_priv->channels.ptr[i]; if (chan && chan->ramin_grctx && chan->ramin_grctx->pinst == inst) diff --git a/drivers/gpu/drm/nouveau/nv50_fb.c b/drivers/gpu/drm/nouveau/nv50_fb.c index cd1988b15d2c..d745c952986a 100644 --- a/drivers/gpu/drm/nouveau/nv50_fb.c +++ b/drivers/gpu/drm/nouveau/nv50_fb.c @@ -42,6 +42,7 @@ void nv50_fb_vm_trap(struct drm_device *dev, int display, const char *name) { struct drm_nouveau_private *dev_priv = dev->dev_private; + unsigned long flags; u32 trap[6], idx, chinst; int i, ch; @@ -60,8 +61,10 @@ nv50_fb_vm_trap(struct drm_device *dev, int display, const char *name) return; chinst = (trap[2] << 16) | trap[1]; + + spin_lock_irqsave(&dev_priv->channels.lock, flags); for (ch = 0; ch < dev_priv->engine.fifo.channels; ch++) { - struct nouveau_channel *chan = dev_priv->fifos[ch]; + struct nouveau_channel *chan = dev_priv->channels.ptr[ch]; if (!chan || !chan->ramin) continue; @@ -69,6 +72,7 @@ nv50_fb_vm_trap(struct drm_device *dev, int display, const char *name) if (chinst == chan->ramin->vinst >> 12) break; } + spin_unlock_irqrestore(&dev_priv->channels.lock, flags); NV_INFO(dev, "%s - VM: Trapped %s at %02x%04x%04x status %08x " "channel %d (0x%08x)\n", diff --git a/drivers/gpu/drm/nouveau/nv50_fifo.c b/drivers/gpu/drm/nouveau/nv50_fifo.c index 1da65bd60c10..815960fe4f43 100644 --- a/drivers/gpu/drm/nouveau/nv50_fifo.c +++ b/drivers/gpu/drm/nouveau/nv50_fifo.c @@ -44,7 +44,8 @@ nv50_fifo_playlist_update(struct drm_device *dev) /* We never schedule channel 0 or 127 */ for (i = 1, nr = 0; i < 127; i++) { - if (dev_priv->fifos[i] && dev_priv->fifos[i]->ramfc) { + if (dev_priv->channels.ptr[i] && + dev_priv->channels.ptr[i]->ramfc) { nv_wo32(cur, (nr * 4), i); nr++; } @@ -60,7 +61,7 @@ static void nv50_fifo_channel_enable(struct drm_device *dev, int channel) { struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_channel *chan = dev_priv->fifos[channel]; + struct nouveau_channel *chan = dev_priv->channels.ptr[channel]; uint32_t inst; NV_DEBUG(dev, "ch%d\n", channel); @@ -118,7 +119,7 @@ nv50_fifo_init_context_table(struct drm_device *dev) NV_DEBUG(dev, "\n"); for (i = 0; i < NV50_PFIFO_CTX_TABLE__SIZE; i++) { - if (dev_priv->fifos[i]) + if (dev_priv->channels.ptr[i]) nv50_fifo_channel_enable(dev, i); else nv50_fifo_channel_disable(dev, i); @@ -392,7 +393,7 @@ nv50_fifo_unload_context(struct drm_device *dev) if (chid < 1 || chid >= dev_priv->engine.fifo.channels - 1) return 0; - chan = dev_priv->fifos[chid]; + chan = dev_priv->channels.ptr[chid]; if (!chan) { NV_ERROR(dev, "Inactive channel on PFIFO: %d\n", chid); return -EINVAL; diff --git a/drivers/gpu/drm/nouveau/nv50_graph.c b/drivers/gpu/drm/nouveau/nv50_graph.c index 8b669d0af610..24a3f8487579 100644 --- a/drivers/gpu/drm/nouveau/nv50_graph.c +++ b/drivers/gpu/drm/nouveau/nv50_graph.c @@ -190,7 +190,7 @@ nv50_graph_channel(struct drm_device *dev) inst = (inst & NV50_PGRAPH_CTXCTL_CUR_INSTANCE) << 12; for (i = 0; i < dev_priv->engine.fifo.channels; i++) { - struct nouveau_channel *chan = dev_priv->fifos[i]; + struct nouveau_channel *chan = dev_priv->channels.ptr[i]; if (chan && chan->ramin && chan->ramin->vinst == inst) return chan; diff --git a/drivers/gpu/drm/nouveau/nv50_instmem.c b/drivers/gpu/drm/nouveau/nv50_instmem.c index b773229b7647..0651e7629235 100644 --- a/drivers/gpu/drm/nouveau/nv50_instmem.c +++ b/drivers/gpu/drm/nouveau/nv50_instmem.c @@ -131,10 +131,10 @@ nv50_instmem_init(struct drm_device *dev) } /* we need a channel to plug into the hw to control the BARs */ - ret = nv50_channel_new(dev, 128*1024, &dev_priv->fifos[0]); + ret = nv50_channel_new(dev, 128*1024, &dev_priv->channels.ptr[0]); if (ret) return ret; - chan = dev_priv->fifos[127] = dev_priv->fifos[0]; + chan = dev_priv->channels.ptr[127] = dev_priv->channels.ptr[0]; /* allocate page table for PRAMIN BAR */ ret = nouveau_gpuobj_new(dev, chan, (dev_priv->ramin_size >> 12) * 8, @@ -240,7 +240,7 @@ nv50_instmem_takedown(struct drm_device *dev) { struct drm_nouveau_private *dev_priv = dev->dev_private; struct nv50_instmem_priv *priv = dev_priv->engine.instmem.priv; - struct nouveau_channel *chan = dev_priv->fifos[0]; + struct nouveau_channel *chan = dev_priv->channels.ptr[0]; int i; NV_DEBUG(dev, "\n"); @@ -264,8 +264,8 @@ nv50_instmem_takedown(struct drm_device *dev) nouveau_gpuobj_ref(NULL, &chan->vm_vram_pt[i]); dev_priv->vm_vram_pt_nr = 0; - nv50_channel_del(&dev_priv->fifos[0]); - dev_priv->fifos[127] = NULL; + nv50_channel_del(&dev_priv->channels.ptr[0]); + dev_priv->channels.ptr[127] = NULL; } dev_priv->engine.instmem.priv = NULL; @@ -276,7 +276,7 @@ int nv50_instmem_suspend(struct drm_device *dev) { struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_channel *chan = dev_priv->fifos[0]; + struct nouveau_channel *chan = dev_priv->channels.ptr[0]; struct nouveau_gpuobj *ramin = chan->ramin; int i; @@ -294,7 +294,7 @@ nv50_instmem_resume(struct drm_device *dev) { struct drm_nouveau_private *dev_priv = dev->dev_private; struct nv50_instmem_priv *priv = dev_priv->engine.instmem.priv; - struct nouveau_channel *chan = dev_priv->fifos[0]; + struct nouveau_channel *chan = dev_priv->channels.ptr[0]; struct nouveau_gpuobj *ramin = chan->ramin; int i; -- cgit v1.2.3 From b12120a58e06cc6b799494c80215e418c14f9f5f Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 6 Oct 2010 16:20:17 +1000 Subject: drm/nouveau: switch to unlocked ioctls Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_channel.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_channel.c b/drivers/gpu/drm/nouveau/nouveau_channel.c index 47bf2d3d658c..0e2414b0ae50 100644 --- a/drivers/gpu/drm/nouveau/nouveau_channel.c +++ b/drivers/gpu/drm/nouveau/nouveau_channel.c @@ -456,18 +456,18 @@ nouveau_ioctl_fifo_free(struct drm_device *dev, void *data, ***********************************/ struct drm_ioctl_desc nouveau_ioctls[] = { - DRM_IOCTL_DEF_DRV(NOUVEAU_GETPARAM, nouveau_ioctl_getparam, DRM_AUTH), - DRM_IOCTL_DEF_DRV(NOUVEAU_SETPARAM, nouveau_ioctl_setparam, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), - DRM_IOCTL_DEF_DRV(NOUVEAU_CHANNEL_ALLOC, nouveau_ioctl_fifo_alloc, DRM_AUTH), - DRM_IOCTL_DEF_DRV(NOUVEAU_CHANNEL_FREE, nouveau_ioctl_fifo_free, DRM_AUTH), - DRM_IOCTL_DEF_DRV(NOUVEAU_GROBJ_ALLOC, nouveau_ioctl_grobj_alloc, DRM_AUTH), - DRM_IOCTL_DEF_DRV(NOUVEAU_NOTIFIEROBJ_ALLOC, nouveau_ioctl_notifier_alloc, DRM_AUTH), - DRM_IOCTL_DEF_DRV(NOUVEAU_GPUOBJ_FREE, nouveau_ioctl_gpuobj_free, DRM_AUTH), - DRM_IOCTL_DEF_DRV(NOUVEAU_GEM_NEW, nouveau_gem_ioctl_new, DRM_AUTH), - DRM_IOCTL_DEF_DRV(NOUVEAU_GEM_PUSHBUF, nouveau_gem_ioctl_pushbuf, DRM_AUTH), - DRM_IOCTL_DEF_DRV(NOUVEAU_GEM_CPU_PREP, nouveau_gem_ioctl_cpu_prep, DRM_AUTH), - DRM_IOCTL_DEF_DRV(NOUVEAU_GEM_CPU_FINI, nouveau_gem_ioctl_cpu_fini, DRM_AUTH), - DRM_IOCTL_DEF_DRV(NOUVEAU_GEM_INFO, nouveau_gem_ioctl_info, DRM_AUTH), + DRM_IOCTL_DEF_DRV(NOUVEAU_GETPARAM, nouveau_ioctl_getparam, DRM_UNLOCKED|DRM_AUTH), + DRM_IOCTL_DEF_DRV(NOUVEAU_SETPARAM, nouveau_ioctl_setparam, DRM_UNLOCKED|DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), + DRM_IOCTL_DEF_DRV(NOUVEAU_CHANNEL_ALLOC, nouveau_ioctl_fifo_alloc, DRM_UNLOCKED|DRM_AUTH), + DRM_IOCTL_DEF_DRV(NOUVEAU_CHANNEL_FREE, nouveau_ioctl_fifo_free, DRM_UNLOCKED|DRM_AUTH), + DRM_IOCTL_DEF_DRV(NOUVEAU_GROBJ_ALLOC, nouveau_ioctl_grobj_alloc, DRM_UNLOCKED|DRM_AUTH), + DRM_IOCTL_DEF_DRV(NOUVEAU_NOTIFIEROBJ_ALLOC, nouveau_ioctl_notifier_alloc, DRM_UNLOCKED|DRM_AUTH), + DRM_IOCTL_DEF_DRV(NOUVEAU_GPUOBJ_FREE, nouveau_ioctl_gpuobj_free, DRM_UNLOCKED|DRM_AUTH), + DRM_IOCTL_DEF_DRV(NOUVEAU_GEM_NEW, nouveau_gem_ioctl_new, DRM_UNLOCKED|DRM_AUTH), + DRM_IOCTL_DEF_DRV(NOUVEAU_GEM_PUSHBUF, nouveau_gem_ioctl_pushbuf, DRM_UNLOCKED|DRM_AUTH), + DRM_IOCTL_DEF_DRV(NOUVEAU_GEM_CPU_PREP, nouveau_gem_ioctl_cpu_prep, DRM_UNLOCKED|DRM_AUTH), + DRM_IOCTL_DEF_DRV(NOUVEAU_GEM_CPU_FINI, nouveau_gem_ioctl_cpu_fini, DRM_UNLOCKED|DRM_AUTH), + DRM_IOCTL_DEF_DRV(NOUVEAU_GEM_INFO, nouveau_gem_ioctl_info, DRM_UNLOCKED|DRM_AUTH), }; int nouveau_max_ioctl = DRM_ARRAY_SIZE(nouveau_ioctls); -- cgit v1.2.3 From 21e86c1c8a844bf978f8fc431a59c9f5a578812d Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 11 Oct 2010 11:48:45 +1000 Subject: drm/nouveau: remove cpu_writers lock No other driver uses this, and userspace should be responsible for handling locking between them if they share BOs. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_drv.h | 1 - drivers/gpu/drm/nouveau/nouveau_gem.c | 64 +++-------------------------------- include/drm/nouveau_drm.h | 1 - 3 files changed, 4 insertions(+), 62 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index c3f102125083..b78663fc334c 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -96,7 +96,6 @@ struct nouveau_bo { struct nouveau_tile_reg *tile; struct drm_gem_object *gem; - struct drm_file *cpu_filp; int pin_refcnt; }; diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c index 454d5ceb28f1..e14d10e38870 100644 --- a/drivers/gpu/drm/nouveau/nouveau_gem.c +++ b/drivers/gpu/drm/nouveau/nouveau_gem.c @@ -48,9 +48,6 @@ nouveau_gem_object_del(struct drm_gem_object *gem) return; nvbo->gem = NULL; - if (unlikely(nvbo->cpu_filp)) - ttm_bo_synccpu_write_release(bo); - if (unlikely(nvbo->pin_refcnt)) { nvbo->pin_refcnt = 1; nouveau_bo_unpin(nvbo); @@ -334,23 +331,6 @@ retry: validate_fini(op, NULL); return -EINVAL; } - - if (unlikely(atomic_read(&nvbo->bo.cpu_writers) > 0)) { - validate_fini(op, NULL); - - if (nvbo->cpu_filp == file_priv) { - NV_ERROR(dev, "bo %p mapped by process trying " - "to validate it!\n", nvbo); - return -EINVAL; - } - - ret = ttm_bo_wait_cpu(&nvbo->bo, false); - if (ret) { - NV_ERROR(dev, "fail wait_cpu\n"); - return ret; - } - goto retry; - } } return 0; @@ -791,26 +771,9 @@ nouveau_gem_ioctl_cpu_prep(struct drm_device *dev, void *data, return -ENOENT; nvbo = nouveau_gem_object(gem); - if (nvbo->cpu_filp) { - if (nvbo->cpu_filp == file_priv) - goto out; - - ret = ttm_bo_wait_cpu(&nvbo->bo, no_wait); - if (ret) - goto out; - } - - if (req->flags & NOUVEAU_GEM_CPU_PREP_NOBLOCK) { - spin_lock(&nvbo->bo.bdev->fence_lock); - ret = ttm_bo_wait(&nvbo->bo, false, false, no_wait); - spin_unlock(&nvbo->bo.bdev->fence_lock); - } else { - ret = ttm_bo_synccpu_write_grab(&nvbo->bo, no_wait); - if (ret == 0) - nvbo->cpu_filp = file_priv; - } - -out: + spin_lock(&nvbo->bo.bdev->fence_lock); + ret = ttm_bo_wait(&nvbo->bo, true, true, no_wait); + spin_unlock(&nvbo->bo.bdev->fence_lock); drm_gem_object_unreference_unlocked(gem); return ret; } @@ -819,26 +782,7 @@ int nouveau_gem_ioctl_cpu_fini(struct drm_device *dev, void *data, struct drm_file *file_priv) { - struct drm_nouveau_gem_cpu_prep *req = data; - struct drm_gem_object *gem; - struct nouveau_bo *nvbo; - int ret = -EINVAL; - - gem = drm_gem_object_lookup(dev, file_priv, req->handle); - if (!gem) - return -ENOENT; - nvbo = nouveau_gem_object(gem); - - if (nvbo->cpu_filp != file_priv) - goto out; - nvbo->cpu_filp = NULL; - - ttm_bo_synccpu_write_release(&nvbo->bo); - ret = 0; - -out: - drm_gem_object_unreference_unlocked(gem); - return ret; + return 0; } int diff --git a/include/drm/nouveau_drm.h b/include/drm/nouveau_drm.h index bc5590b1a1ac..60a7b3e9c2e9 100644 --- a/include/drm/nouveau_drm.h +++ b/include/drm/nouveau_drm.h @@ -171,7 +171,6 @@ struct drm_nouveau_gem_pushbuf { }; #define NOUVEAU_GEM_CPU_PREP_NOWAIT 0x00000001 -#define NOUVEAU_GEM_CPU_PREP_NOBLOCK 0x00000002 #define NOUVEAU_GEM_CPU_PREP_WRITE 0x00000004 struct drm_nouveau_gem_cpu_prep { uint32_t handle; -- cgit v1.2.3 From 08cd3d4311fb9c5038bc6fb0c83c250cfb218da2 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 12 Oct 2010 08:01:59 +1000 Subject: drm/nouveau: fix thinko in channel locking in semaphore path Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_fence.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_fence.c b/drivers/gpu/drm/nouveau/nouveau_fence.c index 42694b122eef..5f9f66f35067 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fence.c +++ b/drivers/gpu/drm/nouveau/nouveau_fence.c @@ -393,23 +393,23 @@ nouveau_fence_sync(struct nouveau_fence *fence, return nouveau_fence_wait(fence, NULL, false, false); } - /* try to take wchan's mutex, if we can't take it right away + /* try to take chan's mutex, if we can't take it right away * we have to fallback to software sync to prevent locking * order issues */ - if (!mutex_trylock(&wchan->mutex)) { + if (!mutex_trylock(&chan->mutex)) { free_semaphore(&sema->ref); return nouveau_fence_wait(fence, NULL, false, false); } /* Make wchan wait until it gets signalled */ ret = emit_semaphore(wchan, NV_SW_SEMAPHORE_ACQUIRE, sema); - mutex_unlock(&wchan->mutex); if (ret) goto out; /* Signal the semaphore from chan */ ret = emit_semaphore(chan, NV_SW_SEMAPHORE_RELEASE, sema); + mutex_unlock(&chan->mutex); out: kref_put(&sema->ref, free_semaphore); return ret; -- cgit v1.2.3 From 938c40ed69b2c1eceb72247b5e8975b28afc195f Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 12 Oct 2010 09:54:54 +1000 Subject: drm/nouveau: use interruptible waits during pushbuf validation Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_gem.c | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c index e14d10e38870..23b521ea8e04 100644 --- a/drivers/gpu/drm/nouveau/nouveau_gem.c +++ b/drivers/gpu/drm/nouveau/nouveau_gem.c @@ -299,14 +299,15 @@ retry: return -EINVAL; } - ret = ttm_bo_reserve(&nvbo->bo, false, false, true, sequence); + ret = ttm_bo_reserve(&nvbo->bo, true, false, true, sequence); if (ret) { validate_fini(op, NULL); - if (ret == -EAGAIN) - ret = ttm_bo_wait_unreserved(&nvbo->bo, false); + if (unlikely(ret == -EAGAIN)) + ret = ttm_bo_wait_unreserved(&nvbo->bo, true); drm_gem_object_unreference_unlocked(gem); - if (ret) { - NV_ERROR(dev, "fail reserve\n"); + if (unlikely(ret)) { + if (ret != -ERESTARTSYS) + NV_ERROR(dev, "fail reserve\n"); return ret; } goto retry; @@ -365,10 +366,11 @@ validate_list(struct nouveau_channel *chan, struct list_head *list, nvbo->channel = (b->read_domains & (1 << 31)) ? NULL : chan; ret = ttm_bo_validate(&nvbo->bo, &nvbo->placement, - false, false, false); + true, false, false); nvbo->channel = NULL; if (unlikely(ret)) { - NV_ERROR(dev, "fail ttm_validate\n"); + if (ret != -ERESTARTSYS) + NV_ERROR(dev, "fail ttm_validate\n"); return ret; } @@ -420,13 +422,15 @@ nouveau_gem_pushbuf_validate(struct nouveau_channel *chan, ret = validate_init(chan, file_priv, pbbo, nr_buffers, op); if (unlikely(ret)) { - NV_ERROR(dev, "validate_init\n"); + if (ret != -ERESTARTSYS) + NV_ERROR(dev, "validate_init\n"); return ret; } ret = validate_list(chan, &op->vram_list, pbbo, user_buffers); if (unlikely(ret < 0)) { - NV_ERROR(dev, "validate vram_list\n"); + if (ret != -ERESTARTSYS) + NV_ERROR(dev, "validate vram_list\n"); validate_fini(op, NULL); return ret; } @@ -434,7 +438,8 @@ nouveau_gem_pushbuf_validate(struct nouveau_channel *chan, ret = validate_list(chan, &op->gart_list, pbbo, user_buffers); if (unlikely(ret < 0)) { - NV_ERROR(dev, "validate gart_list\n"); + if (ret != -ERESTARTSYS) + NV_ERROR(dev, "validate gart_list\n"); validate_fini(op, NULL); return ret; } @@ -442,7 +447,8 @@ nouveau_gem_pushbuf_validate(struct nouveau_channel *chan, ret = validate_list(chan, &op->both_list, pbbo, user_buffers); if (unlikely(ret < 0)) { - NV_ERROR(dev, "validate both_list\n"); + if (ret != -ERESTARTSYS) + NV_ERROR(dev, "validate both_list\n"); validate_fini(op, NULL); return ret; } @@ -628,7 +634,8 @@ nouveau_gem_ioctl_pushbuf(struct drm_device *dev, void *data, ret = nouveau_gem_pushbuf_validate(chan, file_priv, bo, req->buffers, req->nr_buffers, &op, &do_reloc); if (ret) { - NV_ERROR(dev, "validate: %d\n", ret); + if (ret != -ERESTARTSYS) + NV_ERROR(dev, "validate: %d\n", ret); goto out; } -- cgit v1.2.3 From 18a16a768c3d37f5bfdbb414217b530294d5d442 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 12 Oct 2010 10:11:00 +1000 Subject: drm/nouveau: return error from nouveau_ramht_remove() if not found Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_object.c | 10 ++-------- drivers/gpu/drm/nouveau/nouveau_ramht.c | 5 +++-- drivers/gpu/drm/nouveau/nouveau_ramht.h | 2 +- 3 files changed, 6 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_object.c b/drivers/gpu/drm/nouveau/nouveau_object.c index 068441c4b563..ce9958a30175 100644 --- a/drivers/gpu/drm/nouveau/nouveau_object.c +++ b/drivers/gpu/drm/nouveau/nouveau_object.c @@ -926,20 +926,14 @@ int nouveau_ioctl_gpuobj_free(struct drm_device *dev, void *data, struct drm_file *file_priv) { struct drm_nouveau_gpuobj_free *objfree = data; - struct nouveau_gpuobj *gpuobj; struct nouveau_channel *chan; - int ret = -ENOENT; + int ret; chan = nouveau_channel_get(dev, file_priv, objfree->channel); if (IS_ERR(chan)) return PTR_ERR(chan); - gpuobj = nouveau_ramht_find(chan, objfree->handle); - if (gpuobj) { - nouveau_ramht_remove(chan, objfree->handle); - ret = 0; - } - + ret = nouveau_ramht_remove(chan, objfree->handle); nouveau_channel_put(&chan); return ret; } diff --git a/drivers/gpu/drm/nouveau/nouveau_ramht.c b/drivers/gpu/drm/nouveau/nouveau_ramht.c index 2d8580927ca4..b4c63c058888 100644 --- a/drivers/gpu/drm/nouveau/nouveau_ramht.c +++ b/drivers/gpu/drm/nouveau/nouveau_ramht.c @@ -214,18 +214,19 @@ out: spin_unlock_irqrestore(&chan->ramht->lock, flags); } -void +int nouveau_ramht_remove(struct nouveau_channel *chan, u32 handle) { struct nouveau_ramht_entry *entry; entry = nouveau_ramht_remove_entry(chan, handle); if (!entry) - return; + return -ENOENT; nouveau_ramht_remove_hash(chan, entry->handle); nouveau_gpuobj_ref(NULL, &entry->gpuobj); kfree(entry); + return 0; } struct nouveau_gpuobj * diff --git a/drivers/gpu/drm/nouveau/nouveau_ramht.h b/drivers/gpu/drm/nouveau/nouveau_ramht.h index b79cb5e1a8f1..c82de98fee0e 100644 --- a/drivers/gpu/drm/nouveau/nouveau_ramht.h +++ b/drivers/gpu/drm/nouveau/nouveau_ramht.h @@ -48,7 +48,7 @@ extern void nouveau_ramht_ref(struct nouveau_ramht *, struct nouveau_ramht **, extern int nouveau_ramht_insert(struct nouveau_channel *, u32 handle, struct nouveau_gpuobj *); -extern void nouveau_ramht_remove(struct nouveau_channel *, u32 handle); +extern int nouveau_ramht_remove(struct nouveau_channel *, u32 handle); extern struct nouveau_gpuobj * nouveau_ramht_find(struct nouveau_channel *chan, u32 handle); -- cgit v1.2.3 From 6032649df9f456f379be8d51f64488cacbfa8317 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 12 Oct 2010 12:31:32 +1000 Subject: drm/nouveau: hook up acpi power supply change tracking Not used at all yet, but lets hook it up now anyway. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_drv.h | 1 + drivers/gpu/drm/nouveau/nouveau_pm.c | 30 ++++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index b78663fc334c..699d546623bd 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -439,6 +439,7 @@ struct nouveau_pm_engine { struct nouveau_pm_level *cur; struct device *hwmon; + struct notifier_block acpi_nb; int (*clock_get)(struct drm_device *, u32 id); void *(*clock_pre)(struct drm_device *, struct nouveau_pm_level *, diff --git a/drivers/gpu/drm/nouveau/nouveau_pm.c b/drivers/gpu/drm/nouveau/nouveau_pm.c index 9f7b158f5825..d93814160bcf 100644 --- a/drivers/gpu/drm/nouveau/nouveau_pm.c +++ b/drivers/gpu/drm/nouveau/nouveau_pm.c @@ -27,6 +27,10 @@ #include "nouveau_drv.h" #include "nouveau_pm.h" +#ifdef CONFIG_ACPI +#include +#endif +#include #include #include @@ -446,6 +450,25 @@ nouveau_hwmon_fini(struct drm_device *dev) #endif } +#ifdef CONFIG_ACPI +static int +nouveau_pm_acpi_event(struct notifier_block *nb, unsigned long val, void *data) +{ + struct drm_nouveau_private *dev_priv = + container_of(nb, struct drm_nouveau_private, engine.pm.acpi_nb); + struct drm_device *dev = dev_priv->dev; + struct acpi_bus_event *entry = (struct acpi_bus_event *)data; + + if (strcmp(entry->device_class, "ac_adapter") == 0) { + bool ac = power_supply_is_system_supplied(); + + NV_DEBUG(dev, "power supply changed: %s\n", ac ? "AC" : "DC"); + } + + return NOTIFY_OK; +} +#endif + int nouveau_pm_init(struct drm_device *dev) { @@ -485,6 +508,10 @@ nouveau_pm_init(struct drm_device *dev) nouveau_sysfs_init(dev); nouveau_hwmon_init(dev); +#ifdef CONFIG_ACPI + pm->acpi_nb.notifier_call = nouveau_pm_acpi_event; + register_acpi_notifier(&pm->acpi_nb); +#endif return 0; } @@ -503,6 +530,9 @@ nouveau_pm_fini(struct drm_device *dev) nouveau_perf_fini(dev); nouveau_volt_fini(dev); +#ifdef CONFIG_ACPI + unregister_acpi_notifier(&pm->acpi_nb); +#endif nouveau_hwmon_fini(dev); nouveau_sysfs_fini(dev); } -- cgit v1.2.3 From 9acc8100cb14b91d446a482fdd0cf7e3ccbcf930 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Thu, 14 Oct 2010 14:55:23 +1000 Subject: drm/nouveau: fallback to sw fbcon if we can't get mutex immediately Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_fbcon.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/drivers/gpu/drm/nouveau/nouveau_fbcon.c index bc30dbe11d00..0fce4eb914d5 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fbcon.c +++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c @@ -61,8 +61,8 @@ nouveau_fbcon_fillrect(struct fb_info *info, const struct fb_fillrect *rect) return; ret = -ENODEV; - if (!in_interrupt() && !(info->flags & FBINFO_HWACCEL_DISABLED)) { - mutex_lock(&dev_priv->channel->mutex); + if (!in_interrupt() && !(info->flags & FBINFO_HWACCEL_DISABLED) && + mutex_trylock(&dev_priv->channel->mutex)) { if (dev_priv->card_type < NV_50) ret = nv04_fbcon_fillrect(info, rect); else @@ -91,8 +91,8 @@ nouveau_fbcon_copyarea(struct fb_info *info, const struct fb_copyarea *image) return; ret = -ENODEV; - if (!in_interrupt() && !(info->flags & FBINFO_HWACCEL_DISABLED)) { - mutex_lock(&dev_priv->channel->mutex); + if (!in_interrupt() && !(info->flags & FBINFO_HWACCEL_DISABLED) && + mutex_trylock(&dev_priv->channel->mutex)) { if (dev_priv->card_type < NV_50) ret = nv04_fbcon_copyarea(info, image); else @@ -121,8 +121,8 @@ nouveau_fbcon_imageblit(struct fb_info *info, const struct fb_image *image) return; ret = -ENODEV; - if (!in_interrupt() && !(info->flags & FBINFO_HWACCEL_DISABLED)) { - mutex_lock(&dev_priv->channel->mutex); + if (!in_interrupt() && !(info->flags & FBINFO_HWACCEL_DISABLED) && + mutex_trylock(&dev_priv->channel->mutex)) { if (dev_priv->card_type < NV_50) ret = nv04_fbcon_imageblit(info, image); else @@ -153,7 +153,9 @@ nouveau_fbcon_sync(struct fb_info *info) info->flags & FBINFO_HWACCEL_DISABLED) return 0; - mutex_lock(&chan->mutex); + if (!mutex_trylock(&chan->mutex)) + return 0; + ret = RING_SPACE(chan, 4); if (ret) { mutex_unlock(&chan->mutex); -- cgit v1.2.3 From cbb4b608b603c7fba4c1cf5b298d1aa23d3fdd22 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 18 Oct 2010 12:34:04 +1000 Subject: drm/nv50: remove some unnecessary PDISPLAY init Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nv50_display.c | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c index f624c611ddea..7ac87efb791f 100644 --- a/drivers/gpu/drm/nouveau/nv50_display.c +++ b/drivers/gpu/drm/nouveau/nv50_display.c @@ -218,9 +218,9 @@ nv50_display_init(struct drm_device *dev) struct nouveau_gpio_engine *pgpio = &dev_priv->engine.gpio; struct nouveau_channel *evo = dev_priv->evo; struct drm_connector *connector; - uint32_t val, ram_amount; - uint64_t start; int ret, i; + u64 start; + u32 val; NV_DEBUG_KMS(dev, "\n"); @@ -262,17 +262,6 @@ nv50_display_init(struct drm_device *dev) nv_wr32(dev, NV50_PDISPLAY_DAC_CLK_CTRL1(i), 0x00000001); } - /* This used to be in crtc unblank, but seems out of place there. */ - nv_wr32(dev, NV50_PDISPLAY_UNK_380, 0); - /* RAM is clamped to 256 MiB. */ - ram_amount = dev_priv->vram_size; - NV_DEBUG_KMS(dev, "ram_amount %d\n", ram_amount); - if (ram_amount > 256*1024*1024) - ram_amount = 256*1024*1024; - nv_wr32(dev, NV50_PDISPLAY_RAM_AMOUNT, ram_amount - 1); - nv_wr32(dev, NV50_PDISPLAY_UNK_388, 0x150000); - nv_wr32(dev, NV50_PDISPLAY_UNK_38C, 0); - /* The precise purpose is unknown, i suspect it has something to do * with text mode. */ -- cgit v1.2.3 From aa5ac7358c010dcb5916d1d0c2651ae65a4f7ab7 Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Thu, 14 Oct 2010 20:37:56 +0200 Subject: drm/nouveau: Leave BO eviction synchronization for later. The pushbuf ioctl syncs after validation, no need for this anymore. Signed-off-by: Francisco Jerez Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_bo.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index d8817b4bb189..8442bfbf5d42 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c @@ -485,15 +485,8 @@ nouveau_bo_move_accel_cleanup(struct nouveau_channel *chan, if (ret) return ret; - if (nvbo->channel) { - ret = nouveau_fence_sync(fence, nvbo->channel); - if (ret) - goto out; - } - ret = ttm_bo_move_accel_cleanup(&nvbo->bo, fence, NULL, evict, no_wait_reserve, no_wait_gpu, new_mem); -out: nouveau_fence_unref((void *)&fence); return ret; } -- cgit v1.2.3 From fcccab2e4eb8d579837481054cc2cb28eea0baef Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Thu, 14 Oct 2010 21:55:23 +0200 Subject: drm/nouveau: Use lazy fence waits when doing software interchannel sync. Signed-off-by: Francisco Jerez Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_fence.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_fence.c b/drivers/gpu/drm/nouveau/nouveau_fence.c index 5f9f66f35067..0a22955998e8 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fence.c +++ b/drivers/gpu/drm/nouveau/nouveau_fence.c @@ -390,7 +390,7 @@ nouveau_fence_sync(struct nouveau_fence *fence, if (!sema) { /* Early card or broken userspace, fall back to * software sync. */ - return nouveau_fence_wait(fence, NULL, false, false); + return nouveau_fence_wait(fence, NULL, true, false); } /* try to take chan's mutex, if we can't take it right away @@ -399,7 +399,7 @@ nouveau_fence_sync(struct nouveau_fence *fence, */ if (!mutex_trylock(&chan->mutex)) { free_semaphore(&sema->ref); - return nouveau_fence_wait(fence, NULL, false, false); + return nouveau_fence_wait(fence, NULL, true, false); } /* Make wchan wait until it gets signalled */ -- cgit v1.2.3 From 3945e47543863385b54d94c94b023ee7ca9df972 Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Mon, 18 Oct 2010 03:53:39 +0200 Subject: drm/nouveau: Refactor context destruction to avoid a lock ordering issue. The destroy_context() engine hooks call gpuobj management functions to release the channel resources, these functions use HARDIRQ-unsafe locks whereas destroy_context() is called with the HARDIRQ-safe context_switch_lock held, that's a lock ordering violation. Push the engine-specific channel destruction logic into destroy_context() and let the hardware-specific code lock and unlock when it's actually needed. Change the engine destruction order to avoid a race in the small gap between pgraph and pfifo context uninitialization. Reported-by: Marcin Slusarz Signed-off-by: Francisco Jerez Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_channel.c | 24 ++++++------------------ drivers/gpu/drm/nouveau/nouveau_drv.h | 2 -- drivers/gpu/drm/nouveau/nouveau_state.c | 8 ++++---- drivers/gpu/drm/nouveau/nv04_fifo.c | 21 +++++++++++++++++++-- drivers/gpu/drm/nouveau/nv04_graph.c | 15 +++++++++++++++ drivers/gpu/drm/nouveau/nv10_fifo.c | 11 ----------- drivers/gpu/drm/nouveau/nv10_graph.c | 15 +++++++++++++++ drivers/gpu/drm/nouveau/nv20_graph.c | 14 +++++++++++++- drivers/gpu/drm/nouveau/nv40_fifo.c | 11 ----------- drivers/gpu/drm/nouveau/nv40_graph.c | 16 ++++++++++++++++ drivers/gpu/drm/nouveau/nv50_fifo.c | 17 +++++++++++++++++ drivers/gpu/drm/nouveau/nv50_graph.c | 11 +++++++++++ 12 files changed, 116 insertions(+), 49 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_channel.c b/drivers/gpu/drm/nouveau/nouveau_channel.c index 0e2414b0ae50..9a051fafa7c3 100644 --- a/drivers/gpu/drm/nouveau/nouveau_channel.c +++ b/drivers/gpu/drm/nouveau/nouveau_channel.c @@ -313,32 +313,20 @@ nouveau_channel_put(struct nouveau_channel **pchan) /* boot it off the hardware */ pfifo->reassign(dev, false); - /* We want to give pgraph a chance to idle and get rid of all potential - * errors. We need to do this before the lock, otherwise the irq handler - * is unable to process them. + /* We want to give pgraph a chance to idle and get rid of all + * potential errors. We need to do this without the context + * switch lock held, otherwise the irq handler is unable to + * process them. */ if (pgraph->channel(dev) == chan) nouveau_wait_for_idle(dev); - spin_lock_irqsave(&dev_priv->context_switch_lock, flags); - - pgraph->fifo_access(dev, false); - if (pgraph->channel(dev) == chan) - pgraph->unload_context(dev); - pgraph->destroy_context(chan); - pgraph->fifo_access(dev, true); - - if (pfifo->channel_id(dev) == chan->id) { - pfifo->disable(dev); - pfifo->unload_context(dev); - pfifo->enable(dev); - } + /* destroy the engine specific contexts */ pfifo->destroy_context(chan); + pgraph->destroy_context(chan); pfifo->reassign(dev, true); - spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags); - /* aside from its resources, the channel should now be dead, * remove it from the channel list */ diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index 699d546623bd..198dabebafb2 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -998,14 +998,12 @@ extern int nv04_fifo_unload_context(struct drm_device *); extern int nv10_fifo_init(struct drm_device *); extern int nv10_fifo_channel_id(struct drm_device *); extern int nv10_fifo_create_context(struct nouveau_channel *); -extern void nv10_fifo_destroy_context(struct nouveau_channel *); extern int nv10_fifo_load_context(struct nouveau_channel *); extern int nv10_fifo_unload_context(struct drm_device *); /* nv40_fifo.c */ extern int nv40_fifo_init(struct drm_device *); extern int nv40_fifo_create_context(struct nouveau_channel *); -extern void nv40_fifo_destroy_context(struct nouveau_channel *); extern int nv40_fifo_load_context(struct nouveau_channel *); extern int nv40_fifo_unload_context(struct drm_device *); diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c index 513c1063fb5e..1a4ba6ccafb1 100644 --- a/drivers/gpu/drm/nouveau/nouveau_state.c +++ b/drivers/gpu/drm/nouveau/nouveau_state.c @@ -137,7 +137,7 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->fifo.cache_pull = nv04_fifo_cache_pull; engine->fifo.channel_id = nv10_fifo_channel_id; engine->fifo.create_context = nv10_fifo_create_context; - engine->fifo.destroy_context = nv10_fifo_destroy_context; + engine->fifo.destroy_context = nv04_fifo_destroy_context; engine->fifo.load_context = nv10_fifo_load_context; engine->fifo.unload_context = nv10_fifo_unload_context; engine->display.early_init = nv04_display_early_init; @@ -191,7 +191,7 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->fifo.cache_pull = nv04_fifo_cache_pull; engine->fifo.channel_id = nv10_fifo_channel_id; engine->fifo.create_context = nv10_fifo_create_context; - engine->fifo.destroy_context = nv10_fifo_destroy_context; + engine->fifo.destroy_context = nv04_fifo_destroy_context; engine->fifo.load_context = nv10_fifo_load_context; engine->fifo.unload_context = nv10_fifo_unload_context; engine->display.early_init = nv04_display_early_init; @@ -245,7 +245,7 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->fifo.cache_pull = nv04_fifo_cache_pull; engine->fifo.channel_id = nv10_fifo_channel_id; engine->fifo.create_context = nv10_fifo_create_context; - engine->fifo.destroy_context = nv10_fifo_destroy_context; + engine->fifo.destroy_context = nv04_fifo_destroy_context; engine->fifo.load_context = nv10_fifo_load_context; engine->fifo.unload_context = nv10_fifo_unload_context; engine->display.early_init = nv04_display_early_init; @@ -302,7 +302,7 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->fifo.cache_pull = nv04_fifo_cache_pull; engine->fifo.channel_id = nv10_fifo_channel_id; engine->fifo.create_context = nv40_fifo_create_context; - engine->fifo.destroy_context = nv40_fifo_destroy_context; + engine->fifo.destroy_context = nv04_fifo_destroy_context; engine->fifo.load_context = nv40_fifo_load_context; engine->fifo.unload_context = nv40_fifo_unload_context; engine->display.early_init = nv04_display_early_init; diff --git a/drivers/gpu/drm/nouveau/nv04_fifo.c b/drivers/gpu/drm/nouveau/nv04_fifo.c index 25c439dcdfd9..4c0d3a8fca68 100644 --- a/drivers/gpu/drm/nouveau/nv04_fifo.c +++ b/drivers/gpu/drm/nouveau/nv04_fifo.c @@ -151,10 +151,27 @@ void nv04_fifo_destroy_context(struct nouveau_channel *chan) { struct drm_device *dev = chan->dev; + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo; + unsigned long flags; - nv_wr32(dev, NV04_PFIFO_MODE, - nv_rd32(dev, NV04_PFIFO_MODE) & ~(1 << chan->id)); + spin_lock_irqsave(&dev_priv->context_switch_lock, flags); + pfifo->reassign(dev, false); + + /* Unload the context if it's the currently active one */ + if (pfifo->channel_id(dev) == chan->id) { + pfifo->disable(dev); + pfifo->unload_context(dev); + pfifo->enable(dev); + } + + /* Keep it from being rescheduled */ + nv_mask(dev, NV04_PFIFO_MODE, 1 << chan->id, 0); + + pfifo->reassign(dev, true); + spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags); + /* Free the channel resources */ nouveau_gpuobj_ref(NULL, &chan->ramfc); } diff --git a/drivers/gpu/drm/nouveau/nv04_graph.c b/drivers/gpu/drm/nouveau/nv04_graph.c index 98b9525c1ebd..1e2ad3942330 100644 --- a/drivers/gpu/drm/nouveau/nv04_graph.c +++ b/drivers/gpu/drm/nouveau/nv04_graph.c @@ -412,10 +412,25 @@ int nv04_graph_create_context(struct nouveau_channel *chan) void nv04_graph_destroy_context(struct nouveau_channel *chan) { + struct drm_device *dev = chan->dev; + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; struct graph_state *pgraph_ctx = chan->pgraph_ctx; + unsigned long flags; + + spin_lock_irqsave(&dev_priv->context_switch_lock, flags); + pgraph->fifo_access(dev, false); + + /* Unload the context if it's the currently active one */ + if (pgraph->channel(dev) == chan) + pgraph->unload_context(dev); + /* Free the context resources */ kfree(pgraph_ctx); chan->pgraph_ctx = NULL; + + pgraph->fifo_access(dev, true); + spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags); } int nv04_graph_load_context(struct nouveau_channel *chan) diff --git a/drivers/gpu/drm/nouveau/nv10_fifo.c b/drivers/gpu/drm/nouveau/nv10_fifo.c index 39328fcce709..912556f2e33c 100644 --- a/drivers/gpu/drm/nouveau/nv10_fifo.c +++ b/drivers/gpu/drm/nouveau/nv10_fifo.c @@ -73,17 +73,6 @@ nv10_fifo_create_context(struct nouveau_channel *chan) return 0; } -void -nv10_fifo_destroy_context(struct nouveau_channel *chan) -{ - struct drm_device *dev = chan->dev; - - nv_wr32(dev, NV04_PFIFO_MODE, - nv_rd32(dev, NV04_PFIFO_MODE) & ~(1 << chan->id)); - - nouveau_gpuobj_ref(NULL, &chan->ramfc); -} - static void nv10_fifo_do_load_context(struct drm_device *dev, int chid) { diff --git a/drivers/gpu/drm/nouveau/nv10_graph.c b/drivers/gpu/drm/nouveau/nv10_graph.c index cd931b57cf05..e3a87a64c164 100644 --- a/drivers/gpu/drm/nouveau/nv10_graph.c +++ b/drivers/gpu/drm/nouveau/nv10_graph.c @@ -875,10 +875,25 @@ int nv10_graph_create_context(struct nouveau_channel *chan) void nv10_graph_destroy_context(struct nouveau_channel *chan) { + struct drm_device *dev = chan->dev; + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; struct graph_state *pgraph_ctx = chan->pgraph_ctx; + unsigned long flags; + + spin_lock_irqsave(&dev_priv->context_switch_lock, flags); + pgraph->fifo_access(dev, false); + + /* Unload the context if it's the currently active one */ + if (pgraph->channel(dev) == chan) + pgraph->unload_context(dev); + /* Free the context resources */ kfree(pgraph_ctx); chan->pgraph_ctx = NULL; + + pgraph->fifo_access(dev, true); + spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags); } void diff --git a/drivers/gpu/drm/nouveau/nv20_graph.c b/drivers/gpu/drm/nouveau/nv20_graph.c index 12ab9cd56eca..8a0402012557 100644 --- a/drivers/gpu/drm/nouveau/nv20_graph.c +++ b/drivers/gpu/drm/nouveau/nv20_graph.c @@ -425,9 +425,21 @@ nv20_graph_destroy_context(struct nouveau_channel *chan) struct drm_device *dev = chan->dev; struct drm_nouveau_private *dev_priv = dev->dev_private; struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; + unsigned long flags; - nouveau_gpuobj_ref(NULL, &chan->ramin_grctx); + spin_lock_irqsave(&dev_priv->context_switch_lock, flags); + pgraph->fifo_access(dev, false); + + /* Unload the context if it's the currently active one */ + if (pgraph->channel(dev) == chan) + pgraph->unload_context(dev); + + pgraph->fifo_access(dev, true); + spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags); + + /* Free the context resources */ nv_wo32(pgraph->ctx_table, chan->id * 4, 0); + nouveau_gpuobj_ref(NULL, &chan->ramin_grctx); } int diff --git a/drivers/gpu/drm/nouveau/nv40_fifo.c b/drivers/gpu/drm/nouveau/nv40_fifo.c index 3c7be3dc8b88..311ac9ea5d53 100644 --- a/drivers/gpu/drm/nouveau/nv40_fifo.c +++ b/drivers/gpu/drm/nouveau/nv40_fifo.c @@ -70,17 +70,6 @@ nv40_fifo_create_context(struct nouveau_channel *chan) return 0; } -void -nv40_fifo_destroy_context(struct nouveau_channel *chan) -{ - struct drm_device *dev = chan->dev; - - nv_wr32(dev, NV04_PFIFO_MODE, - nv_rd32(dev, NV04_PFIFO_MODE) & ~(1 << chan->id)); - - nouveau_gpuobj_ref(NULL, &chan->ramfc); -} - static void nv40_fifo_do_load_context(struct drm_device *dev, int chid) { diff --git a/drivers/gpu/drm/nouveau/nv40_graph.c b/drivers/gpu/drm/nouveau/nv40_graph.c index e0b41a26447f..70d97cde49d0 100644 --- a/drivers/gpu/drm/nouveau/nv40_graph.c +++ b/drivers/gpu/drm/nouveau/nv40_graph.c @@ -79,6 +79,22 @@ nv40_graph_create_context(struct nouveau_channel *chan) void nv40_graph_destroy_context(struct nouveau_channel *chan) { + struct drm_device *dev = chan->dev; + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; + unsigned long flags; + + spin_lock_irqsave(&dev_priv->context_switch_lock, flags); + pgraph->fifo_access(dev, false); + + /* Unload the context if it's the currently active one */ + if (pgraph->channel(dev) == chan) + pgraph->unload_context(dev); + + pgraph->fifo_access(dev, true); + spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags); + + /* Free the context resources */ nouveau_gpuobj_ref(NULL, &chan->ramin_grctx); } diff --git a/drivers/gpu/drm/nouveau/nv50_fifo.c b/drivers/gpu/drm/nouveau/nv50_fifo.c index 815960fe4f43..d3295aae0c4e 100644 --- a/drivers/gpu/drm/nouveau/nv50_fifo.c +++ b/drivers/gpu/drm/nouveau/nv50_fifo.c @@ -292,10 +292,23 @@ void nv50_fifo_destroy_context(struct nouveau_channel *chan) { struct drm_device *dev = chan->dev; + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo; struct nouveau_gpuobj *ramfc = NULL; + unsigned long flags; NV_DEBUG(dev, "ch%d\n", chan->id); + spin_lock_irqsave(&dev_priv->context_switch_lock, flags); + pfifo->reassign(dev, false); + + /* Unload the context if it's the currently active one */ + if (pfifo->channel_id(dev) == chan->id) { + pfifo->disable(dev); + pfifo->unload_context(dev); + pfifo->enable(dev); + } + /* This will ensure the channel is seen as disabled. */ nouveau_gpuobj_ref(chan->ramfc, &ramfc); nouveau_gpuobj_ref(NULL, &chan->ramfc); @@ -306,6 +319,10 @@ nv50_fifo_destroy_context(struct nouveau_channel *chan) nv50_fifo_channel_disable(dev, 127); nv50_fifo_playlist_update(dev); + pfifo->reassign(dev, true); + spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags); + + /* Free the channel resources */ nouveau_gpuobj_ref(NULL, &ramfc); nouveau_gpuobj_ref(NULL, &chan->cache); } diff --git a/drivers/gpu/drm/nouveau/nv50_graph.c b/drivers/gpu/drm/nouveau/nv50_graph.c index 24a3f8487579..dcc9175fb794 100644 --- a/drivers/gpu/drm/nouveau/nv50_graph.c +++ b/drivers/gpu/drm/nouveau/nv50_graph.c @@ -242,17 +242,28 @@ nv50_graph_destroy_context(struct nouveau_channel *chan) { struct drm_device *dev = chan->dev; struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; int i, hdr = (dev_priv->chipset == 0x50) ? 0x200 : 0x20; + unsigned long flags; NV_DEBUG(dev, "ch%d\n", chan->id); if (!chan->ramin) return; + spin_lock_irqsave(&dev_priv->context_switch_lock, flags); + pgraph->fifo_access(dev, false); + + if (pgraph->channel(dev) == chan) + pgraph->unload_context(dev); + for (i = hdr; i < hdr + 24; i += 4) nv_wo32(chan->ramin, i, 0); dev_priv->engine.instmem.flush(dev); + pgraph->fifo_access(dev, true); + spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags); + nouveau_gpuobj_ref(NULL, &chan->ramin_grctx); } -- cgit v1.2.3 From f175b745b50c5c5356e8b3b409b7f38aa44de6bb Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Mon, 18 Oct 2010 03:54:33 +0200 Subject: drm/nouveau: Fix race condition in channel refcount handling. nouveau_channel_put() can be executed after the 'refcount == 0' check in nouveau_channel_get() and before the channel reference count is incremented. In that case CPU0 will take the context down while CPU1 thinks it owns the channel and 'refcount == 1'. Signed-off-by: Francisco Jerez Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_channel.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_channel.c b/drivers/gpu/drm/nouveau/nouveau_channel.c index 9a051fafa7c3..c46a6f641964 100644 --- a/drivers/gpu/drm/nouveau/nouveau_channel.c +++ b/drivers/gpu/drm/nouveau/nouveau_channel.c @@ -247,17 +247,16 @@ nouveau_channel_get(struct drm_device *dev, struct drm_file *file_priv, int id) spin_lock_irqsave(&dev_priv->channels.lock, flags); chan = dev_priv->channels.ptr[id]; - if (unlikely(!chan || atomic_read(&chan->refcount) == 0)) { + if (unlikely(!chan || (file_priv && chan->file_priv != file_priv))) { spin_unlock_irqrestore(&dev_priv->channels.lock, flags); return ERR_PTR(-EINVAL); } - if (unlikely(file_priv && chan->file_priv != file_priv)) { + if (unlikely(!atomic_inc_not_zero(&chan->refcount))) { spin_unlock_irqrestore(&dev_priv->channels.lock, flags); return ERR_PTR(-EINVAL); } - atomic_inc(&chan->refcount); spin_unlock_irqrestore(&dev_priv->channels.lock, flags); mutex_lock(&chan->mutex); -- cgit v1.2.3 From feeb0aecfb73b5b7699c0a85ba1650e6f9c50be2 Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Mon, 18 Oct 2010 02:58:04 +0200 Subject: drm/nouveau: Add unlocked variants of nouveau_channel_get/put. Signed-off-by: Francisco Jerez Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_channel.c | 36 ++++++++++++++++++++----------- drivers/gpu/drm/nouveau/nouveau_drv.h | 3 +++ 2 files changed, 26 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_channel.c b/drivers/gpu/drm/nouveau/nouveau_channel.c index c46a6f641964..38929fd3f4e3 100644 --- a/drivers/gpu/drm/nouveau/nouveau_channel.c +++ b/drivers/gpu/drm/nouveau/nouveau_channel.c @@ -237,34 +237,40 @@ nouveau_channel_alloc(struct drm_device *dev, struct nouveau_channel **chan_ret, return 0; } +struct nouveau_channel * +nouveau_channel_get_unlocked(struct nouveau_channel *ref) +{ + if (likely(ref && atomic_inc_not_zero(&ref->refcount))) + return ref; + + return NULL; +} + struct nouveau_channel * nouveau_channel_get(struct drm_device *dev, struct drm_file *file_priv, int id) { struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_channel *chan = ERR_PTR(-ENODEV); + struct nouveau_channel *chan; unsigned long flags; spin_lock_irqsave(&dev_priv->channels.lock, flags); - chan = dev_priv->channels.ptr[id]; + chan = nouveau_channel_get_unlocked(dev_priv->channels.ptr[id]); + spin_unlock_irqrestore(&dev_priv->channels.lock, flags); - if (unlikely(!chan || (file_priv && chan->file_priv != file_priv))) { - spin_unlock_irqrestore(&dev_priv->channels.lock, flags); + if (unlikely(!chan)) return ERR_PTR(-EINVAL); - } - if (unlikely(!atomic_inc_not_zero(&chan->refcount))) { - spin_unlock_irqrestore(&dev_priv->channels.lock, flags); + if (unlikely(file_priv && chan->file_priv != file_priv)) { + nouveau_channel_put_unlocked(&chan); return ERR_PTR(-EINVAL); } - spin_unlock_irqrestore(&dev_priv->channels.lock, flags); - mutex_lock(&chan->mutex); return chan; } void -nouveau_channel_put(struct nouveau_channel **pchan) +nouveau_channel_put_unlocked(struct nouveau_channel **pchan) { struct nouveau_channel *chan = *pchan; struct drm_device *dev = chan->dev; @@ -274,9 +280,6 @@ nouveau_channel_put(struct nouveau_channel **pchan) unsigned long flags; int ret; - /* unlock the channel */ - mutex_unlock(&chan->mutex); - /* decrement the refcount, and we're done if there's still refs */ if (likely(!atomic_dec_and_test(&chan->refcount))) { *pchan = NULL; @@ -348,6 +351,13 @@ nouveau_channel_put(struct nouveau_channel **pchan) kfree(chan); } +void +nouveau_channel_put(struct nouveau_channel **pchan) +{ + mutex_unlock(&(*pchan)->mutex); + nouveau_channel_put_unlocked(pchan); +} + /* cleans up all the fifos from file_priv */ void nouveau_channel_cleanup(struct drm_device *dev, struct drm_file *file_priv) diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index 198dabebafb2..e6708be58bcf 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -803,7 +803,10 @@ extern int nouveau_channel_alloc(struct drm_device *dev, struct drm_file *file_priv, uint32_t fb_ctxdma, uint32_t tt_ctxdma); extern struct nouveau_channel * +nouveau_channel_get_unlocked(struct nouveau_channel *); +extern struct nouveau_channel * nouveau_channel_get(struct drm_device *, struct drm_file *, int id); +extern void nouveau_channel_put_unlocked(struct nouveau_channel **); extern void nouveau_channel_put(struct nouveau_channel **); /* nouveau_object.c */ -- cgit v1.2.3 From 36c952e8b3bad911ef13111058f0a5c4b361027e Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Mon, 18 Oct 2010 03:01:34 +0200 Subject: drm/nouveau: Fix lock unbalance on card take down. Signed-off-by: Francisco Jerez Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_state.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c index 1a4ba6ccafb1..af203cc5d7ad 100644 --- a/drivers/gpu/drm/nouveau/nouveau_state.c +++ b/drivers/gpu/drm/nouveau/nouveau_state.c @@ -714,7 +714,7 @@ static void nouveau_card_takedown(struct drm_device *dev) if (!engine->graph.accel_blocked) { nouveau_fence_fini(dev); - nouveau_channel_put(&dev_priv->channel); + nouveau_channel_put_unlocked(&dev_priv->channel); } if (!nouveau_noaccel) { -- cgit v1.2.3 From f091a3d403065416b7d27221bbeb956481132ffd Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Mon, 18 Oct 2010 03:55:48 +0200 Subject: drm/nouveau: Implement weak channel references. nouveau_channel_ref() takes a "weak" channel reference that doesn't prevent the hardware channel resources from being released, it just keeps the channel data structure alive. Signed-off-by: Francisco Jerez Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_channel.c | 55 ++++++++++++++++++++++--------- drivers/gpu/drm/nouveau/nouveau_drv.h | 8 ++++- 2 files changed, 47 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_channel.c b/drivers/gpu/drm/nouveau/nouveau_channel.c index 38929fd3f4e3..76033c509d35 100644 --- a/drivers/gpu/drm/nouveau/nouveau_channel.c +++ b/drivers/gpu/drm/nouveau/nouveau_channel.c @@ -125,7 +125,8 @@ nouveau_channel_alloc(struct drm_device *dev, struct nouveau_channel **chan_ret, chan->vram_handle = vram_handle; chan->gart_handle = gart_handle; - atomic_set(&chan->refcount, 1); + kref_init(&chan->ref); + atomic_set(&chan->users, 1); mutex_init(&chan->mutex); mutex_lock(&chan->mutex); @@ -133,7 +134,7 @@ nouveau_channel_alloc(struct drm_device *dev, struct nouveau_channel **chan_ret, spin_lock_irqsave(&dev_priv->channels.lock, flags); for (chan->id = 0; chan->id < pfifo->channels; chan->id++) { if (!dev_priv->channels.ptr[chan->id]) { - dev_priv->channels.ptr[chan->id] = chan; + nouveau_channel_ref(chan, &dev_priv->channels.ptr[chan->id]); break; } } @@ -240,10 +241,12 @@ nouveau_channel_alloc(struct drm_device *dev, struct nouveau_channel **chan_ret, struct nouveau_channel * nouveau_channel_get_unlocked(struct nouveau_channel *ref) { - if (likely(ref && atomic_inc_not_zero(&ref->refcount))) - return ref; + struct nouveau_channel *chan = NULL; - return NULL; + if (likely(ref && atomic_inc_not_zero(&ref->users))) + nouveau_channel_ref(ref, &chan); + + return chan; } struct nouveau_channel * @@ -281,15 +284,14 @@ nouveau_channel_put_unlocked(struct nouveau_channel **pchan) int ret; /* decrement the refcount, and we're done if there's still refs */ - if (likely(!atomic_dec_and_test(&chan->refcount))) { - *pchan = NULL; + if (likely(!atomic_dec_and_test(&chan->users))) { + nouveau_channel_ref(NULL, pchan); return; } /* noone wants the channel anymore */ NV_DEBUG(dev, "freeing channel %d\n", chan->id); nouveau_debugfs_channel_fini(chan); - *pchan = NULL; /* give it chance to idle */ nouveau_fence_update(chan); @@ -333,7 +335,7 @@ nouveau_channel_put_unlocked(struct nouveau_channel **pchan) * remove it from the channel list */ spin_lock_irqsave(&dev_priv->channels.lock, flags); - dev_priv->channels.ptr[chan->id] = NULL; + nouveau_channel_ref(NULL, &dev_priv->channels.ptr[chan->id]); spin_unlock_irqrestore(&dev_priv->channels.lock, flags); /* destroy any resources the channel owned */ @@ -345,10 +347,8 @@ nouveau_channel_put_unlocked(struct nouveau_channel **pchan) } nouveau_gpuobj_channel_takedown(chan); nouveau_notifier_takedown_channel(chan); - if (chan->user) - iounmap(chan->user); - kfree(chan); + nouveau_channel_ref(NULL, pchan); } void @@ -358,6 +358,31 @@ nouveau_channel_put(struct nouveau_channel **pchan) nouveau_channel_put_unlocked(pchan); } +static void +nouveau_channel_del(struct kref *ref) +{ + struct nouveau_channel *chan = + container_of(ref, struct nouveau_channel, ref); + + if (chan->user) + iounmap(chan->user); + + kfree(chan); +} + +void +nouveau_channel_ref(struct nouveau_channel *chan, + struct nouveau_channel **pchan) +{ + if (chan) + kref_get(&chan->ref); + + if (*pchan) + kref_put(&(*pchan)->ref, nouveau_channel_del); + + *pchan = chan; +} + /* cleans up all the fifos from file_priv */ void nouveau_channel_cleanup(struct drm_device *dev, struct drm_file *file_priv) @@ -373,7 +398,7 @@ nouveau_channel_cleanup(struct drm_device *dev, struct drm_file *file_priv) if (IS_ERR(chan)) continue; - atomic_dec(&chan->refcount); + atomic_dec(&chan->users); nouveau_channel_put(&chan); } } @@ -427,7 +452,7 @@ nouveau_ioctl_fifo_alloc(struct drm_device *dev, void *data, &init->notifier_handle); if (ret == 0) - atomic_inc(&chan->refcount); /* userspace reference */ + atomic_inc(&chan->users); /* userspace reference */ nouveau_channel_put(&chan); return ret; } @@ -443,7 +468,7 @@ nouveau_ioctl_fifo_free(struct drm_device *dev, void *data, if (IS_ERR(chan)) return PTR_ERR(chan); - atomic_dec(&chan->refcount); + atomic_dec(&chan->users); nouveau_channel_put(&chan); return 0; } diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index e6708be58bcf..d152bc334fd6 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -165,7 +165,11 @@ struct nouveau_channel { struct drm_device *dev; int id; - atomic_t refcount; + /* references to the channel data structure */ + struct kref ref; + /* users of the hardware channel resources, the hardware + * context will be kicked off when it reaches zero. */ + atomic_t users; struct mutex mutex; /* owner of this fifo */ @@ -808,6 +812,8 @@ extern struct nouveau_channel * nouveau_channel_get(struct drm_device *, struct drm_file *, int id); extern void nouveau_channel_put_unlocked(struct nouveau_channel **); extern void nouveau_channel_put(struct nouveau_channel **); +extern void nouveau_channel_ref(struct nouveau_channel *chan, + struct nouveau_channel **pchan); /* nouveau_object.c */ extern int nouveau_gpuobj_early_init(struct drm_device *); -- cgit v1.2.3 From 2a6789ae5e8a6b25a0835834655205166a757a81 Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Mon, 18 Oct 2010 03:56:14 +0200 Subject: drm/nouveau: Make fences take a weak channel reference. Fences didn't increment the channel reference count, and the fenced channel could go away at any time. Fixes a potential race in nouveau_fence_update(). Signed-off-by: Francisco Jerez Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_fence.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_fence.c b/drivers/gpu/drm/nouveau/nouveau_fence.c index 0a22955998e8..e1ae9bab6e41 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fence.c +++ b/drivers/gpu/drm/nouveau/nouveau_fence.c @@ -64,6 +64,7 @@ nouveau_fence_del(struct kref *ref) struct nouveau_fence *fence = container_of(ref, struct nouveau_fence, refcount); + nouveau_channel_ref(NULL, &fence->channel); kfree(fence); } @@ -113,7 +114,7 @@ nouveau_fence_new(struct nouveau_channel *chan, struct nouveau_fence **pfence, if (!fence) return -ENOMEM; kref_init(&fence->refcount); - fence->channel = chan; + nouveau_channel_ref(chan, &fence->channel); if (emit) ret = nouveau_fence_emit(fence); -- cgit v1.2.3 From 2b478addc0bfaaf5031e36ee166c9457ceae628c Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Mon, 18 Oct 2010 03:56:40 +0200 Subject: drm/nouveau: Avoid race in the interchannel sync code. It needs a "strong" channel reference because it actually writes to the channel pushbuf, otherwise the corresponding FIFO context could get kicked off in the middle of nouveau_fence_sync(). Signed-off-by: Francisco Jerez Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_fence.c | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_fence.c b/drivers/gpu/drm/nouveau/nouveau_fence.c index e1ae9bab6e41..29fe03bc4870 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fence.c +++ b/drivers/gpu/drm/nouveau/nouveau_fence.c @@ -128,7 +128,7 @@ nouveau_fence_new(struct nouveau_channel *chan, struct nouveau_fence **pfence, struct nouveau_channel * nouveau_fence_channel(struct nouveau_fence *fence) { - return fence ? fence->channel : NULL; + return fence ? nouveau_channel_get_unlocked(fence->channel) : NULL; } int @@ -381,17 +381,18 @@ nouveau_fence_sync(struct nouveau_fence *fence, struct nouveau_channel *chan = nouveau_fence_channel(fence); struct drm_device *dev = wchan->dev; struct nouveau_semaphore *sema; - int ret; + int ret = 0; - if (likely(!fence || chan == wchan || + if (likely(!chan || chan == wchan || nouveau_fence_signalled(fence, NULL))) - return 0; + goto out; sema = alloc_semaphore(dev); if (!sema) { /* Early card or broken userspace, fall back to * software sync. */ - return nouveau_fence_wait(fence, NULL, true, false); + ret = nouveau_fence_wait(fence, NULL, true, false); + goto out; } /* try to take chan's mutex, if we can't take it right away @@ -399,20 +400,25 @@ nouveau_fence_sync(struct nouveau_fence *fence, * order issues */ if (!mutex_trylock(&chan->mutex)) { - free_semaphore(&sema->ref); - return nouveau_fence_wait(fence, NULL, true, false); + ret = nouveau_fence_wait(fence, NULL, true, false); + goto out_unref; } /* Make wchan wait until it gets signalled */ ret = emit_semaphore(wchan, NV_SW_SEMAPHORE_ACQUIRE, sema); if (ret) - goto out; + goto out_unlock; /* Signal the semaphore from chan */ ret = emit_semaphore(chan, NV_SW_SEMAPHORE_RELEASE, sema); + +out_unlock: mutex_unlock(&chan->mutex); -out: +out_unref: kref_put(&sema->ref, free_semaphore); +out: + if (chan) + nouveau_channel_put_unlocked(&chan); return ret; } -- cgit v1.2.3 From 889fa93dc0ab94b9255e9dd8e2036facfee5485e Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Mon, 18 Oct 2010 03:57:19 +0200 Subject: drm/nouveau: Take fence spinlock in nouveau_fence_channel_fini(). Without it there's a potential race with nouveau_fence_update(). Signed-off-by: Francisco Jerez Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_fence.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/gpu/drm/nouveau/nouveau_fence.c b/drivers/gpu/drm/nouveau/nouveau_fence.c index 29fe03bc4870..f70bec835f5f 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fence.c +++ b/drivers/gpu/drm/nouveau/nouveau_fence.c @@ -490,6 +490,8 @@ nouveau_fence_channel_fini(struct nouveau_channel *chan) { struct nouveau_fence *tmp, *fence; + spin_lock(&chan->fence.lock); + list_for_each_entry_safe(fence, tmp, &chan->fence.pending, entry) { fence->signalled = true; list_del(&fence->entry); @@ -499,6 +501,8 @@ nouveau_fence_channel_fini(struct nouveau_channel *chan) kref_put(&fence->refcount, nouveau_fence_del); } + + spin_unlock(&chan->fence.lock); } int -- cgit v1.2.3 From 0541324abce0225a795222558fdfe35c8dbc5b4f Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Mon, 18 Oct 2010 16:15:15 +0200 Subject: drm/nv40: Ignore sync-to-vblank active when waiting for idle. Signed-off-by: Francisco Jerez Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_reg.h | 1 + drivers/gpu/drm/nouveau/nouveau_state.c | 8 +++++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_reg.h b/drivers/gpu/drm/nouveau/nouveau_reg.h index 1b42541ca9e5..1bbe7037cf99 100644 --- a/drivers/gpu/drm/nouveau/nouveau_reg.h +++ b/drivers/gpu/drm/nouveau/nouveau_reg.h @@ -332,6 +332,7 @@ #define NV04_PGRAPH_BSWIZZLE5 0x004006A0 #define NV03_PGRAPH_STATUS 0x004006B0 #define NV04_PGRAPH_STATUS 0x00400700 +# define NV40_PGRAPH_STATUS_SYNC_STALL 0x00004000 #define NV04_PGRAPH_TRAPPED_ADDR 0x00400704 #define NV04_PGRAPH_TRAPPED_DATA 0x00400708 #define NV04_PGRAPH_SURFACE 0x0040070C diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c index af203cc5d7ad..82b58188398b 100644 --- a/drivers/gpu/drm/nouveau/nouveau_state.c +++ b/drivers/gpu/drm/nouveau/nouveau_state.c @@ -1105,7 +1105,13 @@ bool nouveau_wait_until(struct drm_device *dev, uint64_t timeout, /* Waits for PGRAPH to go completely idle */ bool nouveau_wait_for_idle(struct drm_device *dev) { - if (!nv_wait(dev, NV04_PGRAPH_STATUS, 0xffffffff, 0x00000000)) { + struct drm_nouveau_private *dev_priv = dev->dev_private; + uint32_t mask = ~0; + + if (dev_priv->card_type == NV_40) + mask &= ~NV40_PGRAPH_STATUS_SYNC_STALL; + + if (!nv_wait(dev, NV04_PGRAPH_STATUS, mask, 0)) { NV_ERROR(dev, "PGRAPH idle timed out with status 0x%08x\n", nv_rd32(dev, NV04_PGRAPH_STATUS)); return false; -- cgit v1.2.3 From 9100468d1be26063aa25ecd667ea922c101d203f Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 15 Oct 2010 09:15:26 +1000 Subject: drm/nouveau: pass gpuobj alignment request down into backing allocator Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_drv.h | 8 ++++---- drivers/gpu/drm/nouveau/nouveau_object.c | 2 +- drivers/gpu/drm/nouveau/nv04_instmem.c | 2 +- drivers/gpu/drm/nouveau/nv50_instmem.c | 10 +++++----- drivers/gpu/drm/nouveau/nvc0_instmem.c | 6 +++--- 5 files changed, 14 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index d152bc334fd6..1d474f526986 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -265,7 +265,7 @@ struct nouveau_instmem_engine { void (*resume)(struct drm_device *dev); int (*populate)(struct drm_device *, struct nouveau_gpuobj *, - uint32_t *size); + u32 *size, u32 align); void (*clear)(struct drm_device *, struct nouveau_gpuobj *); int (*bind)(struct drm_device *, struct nouveau_gpuobj *); int (*unbind)(struct drm_device *, struct nouveau_gpuobj *); @@ -1121,7 +1121,7 @@ extern void nv04_instmem_takedown(struct drm_device *); extern int nv04_instmem_suspend(struct drm_device *); extern void nv04_instmem_resume(struct drm_device *); extern int nv04_instmem_populate(struct drm_device *, struct nouveau_gpuobj *, - uint32_t *size); + u32 *size, u32 align); extern void nv04_instmem_clear(struct drm_device *, struct nouveau_gpuobj *); extern int nv04_instmem_bind(struct drm_device *, struct nouveau_gpuobj *); extern int nv04_instmem_unbind(struct drm_device *, struct nouveau_gpuobj *); @@ -1133,7 +1133,7 @@ extern void nv50_instmem_takedown(struct drm_device *); extern int nv50_instmem_suspend(struct drm_device *); extern void nv50_instmem_resume(struct drm_device *); extern int nv50_instmem_populate(struct drm_device *, struct nouveau_gpuobj *, - uint32_t *size); + u32 *size, u32 align); extern void nv50_instmem_clear(struct drm_device *, struct nouveau_gpuobj *); extern int nv50_instmem_bind(struct drm_device *, struct nouveau_gpuobj *); extern int nv50_instmem_unbind(struct drm_device *, struct nouveau_gpuobj *); @@ -1147,7 +1147,7 @@ extern void nvc0_instmem_takedown(struct drm_device *); extern int nvc0_instmem_suspend(struct drm_device *); extern void nvc0_instmem_resume(struct drm_device *); extern int nvc0_instmem_populate(struct drm_device *, struct nouveau_gpuobj *, - uint32_t *size); + u32 *size, u32 align); extern void nvc0_instmem_clear(struct drm_device *, struct nouveau_gpuobj *); extern int nvc0_instmem_bind(struct drm_device *, struct nouveau_gpuobj *); extern int nvc0_instmem_unbind(struct drm_device *, struct nouveau_gpuobj *); diff --git a/drivers/gpu/drm/nouveau/nouveau_object.c b/drivers/gpu/drm/nouveau/nouveau_object.c index ce9958a30175..0b8183edfcd7 100644 --- a/drivers/gpu/drm/nouveau/nouveau_object.c +++ b/drivers/gpu/drm/nouveau/nouveau_object.c @@ -112,7 +112,7 @@ nouveau_gpuobj_new(struct drm_device *dev, struct nouveau_channel *chan, NV_DEBUG(dev, "global heap\n"); /* allocate backing pages, sets vinst */ - ret = engine->instmem.populate(dev, gpuobj, &size); + ret = engine->instmem.populate(dev, gpuobj, &size, align); if (ret) { nouveau_gpuobj_ref(NULL, &gpuobj); return ret; diff --git a/drivers/gpu/drm/nouveau/nv04_instmem.c b/drivers/gpu/drm/nouveau/nv04_instmem.c index 0b5ae297abde..554e55d0ec48 100644 --- a/drivers/gpu/drm/nouveau/nv04_instmem.c +++ b/drivers/gpu/drm/nouveau/nv04_instmem.c @@ -99,7 +99,7 @@ nv04_instmem_takedown(struct drm_device *dev) int nv04_instmem_populate(struct drm_device *dev, struct nouveau_gpuobj *gpuobj, - uint32_t *sz) + u32 *size, u32 align) { return 0; } diff --git a/drivers/gpu/drm/nouveau/nv50_instmem.c b/drivers/gpu/drm/nouveau/nv50_instmem.c index 0651e7629235..2c98eb176d64 100644 --- a/drivers/gpu/drm/nouveau/nv50_instmem.c +++ b/drivers/gpu/drm/nouveau/nv50_instmem.c @@ -322,19 +322,19 @@ nv50_instmem_resume(struct drm_device *dev) int nv50_instmem_populate(struct drm_device *dev, struct nouveau_gpuobj *gpuobj, - uint32_t *sz) + u32 *size, u32 align) { int ret; if (gpuobj->im_backing) return -EINVAL; - *sz = ALIGN(*sz, 4096); - if (*sz == 0) + *size = ALIGN(*size, 4096); + if (*size == 0) return -EINVAL; - ret = nouveau_bo_new(dev, NULL, *sz, 0, TTM_PL_FLAG_VRAM, 0, 0x0000, - true, false, &gpuobj->im_backing); + ret = nouveau_bo_new(dev, NULL, *size, align, TTM_PL_FLAG_VRAM, + 0, 0x0000, true, false, &gpuobj->im_backing); if (ret) { NV_ERROR(dev, "error getting PRAMIN backing pages: %d\n", ret); return ret; diff --git a/drivers/gpu/drm/nouveau/nvc0_instmem.c b/drivers/gpu/drm/nouveau/nvc0_instmem.c index 13a0f78a9088..7b4e71f5c274 100644 --- a/drivers/gpu/drm/nouveau/nvc0_instmem.c +++ b/drivers/gpu/drm/nouveau/nvc0_instmem.c @@ -28,7 +28,7 @@ int nvc0_instmem_populate(struct drm_device *dev, struct nouveau_gpuobj *gpuobj, - uint32_t *size) + u32 *size, u32 align) { int ret; @@ -36,8 +36,8 @@ nvc0_instmem_populate(struct drm_device *dev, struct nouveau_gpuobj *gpuobj, if (*size == 0) return -EINVAL; - ret = nouveau_bo_new(dev, NULL, *size, 0, TTM_PL_FLAG_VRAM, 0, 0x0000, - true, false, &gpuobj->im_backing); + ret = nouveau_bo_new(dev, NULL, *size, align, TTM_PL_FLAG_VRAM, + 0, 0x0000, true, false, &gpuobj->im_backing); if (ret) { NV_ERROR(dev, "error getting PRAMIN backing pages: %d\n", ret); return ret; -- cgit v1.2.3 From 50536946faaf3d9ac0245838eb09e5eb1065b06c Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 19 Oct 2010 19:47:06 +1000 Subject: drm/nouveau: store engine type in gpuobj class structs We will eventually want to address hw engines other than PGRAPH. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_drv.h | 4 +- drivers/gpu/drm/nouveau/nouveau_object.c | 2 +- drivers/gpu/drm/nouveau/nv04_graph.c | 84 ++++++++++++++++---------------- drivers/gpu/drm/nouveau/nv10_graph.c | 40 +++++++-------- drivers/gpu/drm/nouveau/nv20_graph.c | 70 +++++++++++++------------- drivers/gpu/drm/nouveau/nv40_graph.c | 34 ++++++------- drivers/gpu/drm/nouveau/nv50_graph.c | 20 ++++---- 7 files changed, 127 insertions(+), 127 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index 1d474f526986..2fdc26655ca1 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -132,7 +132,7 @@ enum nouveau_flags { #define NVOBJ_ENGINE_SW 0 #define NVOBJ_ENGINE_GR 1 -#define NVOBJ_ENGINE_DISPLAY 2 +#define NVOBJ_ENGINE_DISPLAY 0xcafe0001 #define NVOBJ_ENGINE_INT 0xdeadbeef #define NVOBJ_FLAG_ZERO_ALLOC (1 << 1) @@ -324,7 +324,7 @@ struct nouveau_pgraph_object_method { struct nouveau_pgraph_object_class { int id; - bool software; + u32 engine; struct nouveau_pgraph_object_method *methods; }; diff --git a/drivers/gpu/drm/nouveau/nouveau_object.c b/drivers/gpu/drm/nouveau/nouveau_object.c index 0b8183edfcd7..70ffd7530503 100644 --- a/drivers/gpu/drm/nouveau/nouveau_object.c +++ b/drivers/gpu/drm/nouveau/nouveau_object.c @@ -900,7 +900,7 @@ int nouveau_ioctl_grobj_alloc(struct drm_device *dev, void *data, goto out; } - if (!grc->software) + if (grc->engine != NVOBJ_ENGINE_SW) ret = nouveau_gpuobj_gr_new(chan, grc->id, &gr); else ret = nouveau_gpuobj_sw_new(chan, grc->id, &gr); diff --git a/drivers/gpu/drm/nouveau/nv04_graph.c b/drivers/gpu/drm/nouveau/nv04_graph.c index 1e2ad3942330..5d8ab1b6b04a 100644 --- a/drivers/gpu/drm/nouveau/nv04_graph.c +++ b/drivers/gpu/drm/nouveau/nv04_graph.c @@ -1091,48 +1091,48 @@ static struct nouveau_pgraph_object_method nv04_graph_mthds_surf3d[] = { }; struct nouveau_pgraph_object_class nv04_graph_grclass[] = { - { 0x0038, false, NULL }, /* dvd subpicture */ - { 0x0039, false, NULL }, /* m2mf */ - { 0x004b, false, nv04_graph_mthds_nv03_gdirect }, /* nv03 gdirect */ - { 0x004a, false, nv04_graph_mthds_nv04_gdirect }, /* nv04 gdirect */ - { 0x001f, false, nv04_graph_mthds_nv01_imageblit }, /* nv01 imageblit */ - { 0x005f, false, nv04_graph_mthds_nv04_imageblit_ifc }, /* nv04 imageblit */ - { 0x0060, false, nv04_graph_mthds_nv04_iifc }, /* nv04 iifc */ - { 0x0064, false, NULL }, /* nv05 iifc */ - { 0x0021, false, nv04_graph_mthds_nv01_ifc }, /* nv01 ifc */ - { 0x0061, false, nv04_graph_mthds_nv04_imageblit_ifc }, /* nv04 ifc */ - { 0x0065, false, NULL }, /* nv05 ifc */ - { 0x0036, false, nv04_graph_mthds_nv03_sifc }, /* nv03 sifc */ - { 0x0076, false, nv04_graph_mthds_nv04_sifc }, /* nv04 sifc */ - { 0x0066, false, NULL }, /* nv05 sifc */ - { 0x0037, false, nv04_graph_mthds_nv03_sifm }, /* nv03 sifm */ - { 0x0077, false, nv04_graph_mthds_nv04_sifm }, /* nv04 sifm */ - { 0x0030, false, NULL }, /* null */ - { 0x0042, false, NULL }, /* surf2d */ - { 0x0043, false, NULL }, /* rop */ - { 0x0012, false, NULL }, /* beta1 */ - { 0x0072, false, NULL }, /* beta4 */ - { 0x0019, false, NULL }, /* cliprect */ - { 0x0018, false, NULL }, /* nv01 pattern */ - { 0x0044, false, NULL }, /* nv04 pattern */ - { 0x0052, false, NULL }, /* swzsurf */ - { 0x0053, false, nv04_graph_mthds_surf3d }, /* surf3d */ - { 0x0048, false, nv04_graph_mthds_nv03_tex_tri }, /* nv03 tex_tri */ - { 0x0054, false, NULL }, /* tex_tri */ - { 0x0055, false, NULL }, /* multitex_tri */ - { 0x0017, false, NULL }, /* nv01 chroma */ - { 0x0057, false, NULL }, /* nv04 chroma */ - { 0x0058, false, NULL }, /* surf_dst */ - { 0x0059, false, NULL }, /* surf_src */ - { 0x005a, false, NULL }, /* surf_color */ - { 0x005b, false, NULL }, /* surf_zeta */ - { 0x001c, false, nv04_graph_mthds_nv01_shape }, /* nv01 line */ - { 0x005c, false, nv04_graph_mthds_nv04_shape }, /* nv04 line */ - { 0x001d, false, nv04_graph_mthds_nv01_shape }, /* nv01 tri */ - { 0x005d, false, nv04_graph_mthds_nv04_shape }, /* nv04 tri */ - { 0x001e, false, nv04_graph_mthds_nv01_shape }, /* nv01 rect */ - { 0x005e, false, nv04_graph_mthds_nv04_shape }, /* nv04 rect */ - { 0x506e, true, nv04_graph_mthds_sw }, + { 0x0038, NVOBJ_ENGINE_GR, NULL }, /* dvd subpicture */ + { 0x0039, NVOBJ_ENGINE_GR, NULL }, /* m2mf */ + { 0x004b, NVOBJ_ENGINE_GR, nv04_graph_mthds_nv03_gdirect }, /* nv03 gdirect */ + { 0x004a, NVOBJ_ENGINE_GR, nv04_graph_mthds_nv04_gdirect }, /* nv04 gdirect */ + { 0x001f, NVOBJ_ENGINE_GR, nv04_graph_mthds_nv01_imageblit }, /* nv01 imageblit */ + { 0x005f, NVOBJ_ENGINE_GR, nv04_graph_mthds_nv04_imageblit_ifc }, /* nv04 imageblit */ + { 0x0060, NVOBJ_ENGINE_GR, nv04_graph_mthds_nv04_iifc }, /* nv04 iifc */ + { 0x0064, NVOBJ_ENGINE_GR, NULL }, /* nv05 iifc */ + { 0x0021, NVOBJ_ENGINE_GR, nv04_graph_mthds_nv01_ifc }, /* nv01 ifc */ + { 0x0061, NVOBJ_ENGINE_GR, nv04_graph_mthds_nv04_imageblit_ifc }, /* nv04 ifc */ + { 0x0065, NVOBJ_ENGINE_GR, NULL }, /* nv05 ifc */ + { 0x0036, NVOBJ_ENGINE_GR, nv04_graph_mthds_nv03_sifc }, /* nv03 sifc */ + { 0x0076, NVOBJ_ENGINE_GR, nv04_graph_mthds_nv04_sifc }, /* nv04 sifc */ + { 0x0066, NVOBJ_ENGINE_GR, NULL }, /* nv05 sifc */ + { 0x0037, NVOBJ_ENGINE_GR, nv04_graph_mthds_nv03_sifm }, /* nv03 sifm */ + { 0x0077, NVOBJ_ENGINE_GR, nv04_graph_mthds_nv04_sifm }, /* nv04 sifm */ + { 0x0030, NVOBJ_ENGINE_GR, NULL }, /* null */ + { 0x0042, NVOBJ_ENGINE_GR, NULL }, /* surf2d */ + { 0x0043, NVOBJ_ENGINE_GR, NULL }, /* rop */ + { 0x0012, NVOBJ_ENGINE_GR, NULL }, /* beta1 */ + { 0x0072, NVOBJ_ENGINE_GR, NULL }, /* beta4 */ + { 0x0019, NVOBJ_ENGINE_GR, NULL }, /* cliprect */ + { 0x0018, NVOBJ_ENGINE_GR, NULL }, /* nv01 pattern */ + { 0x0044, NVOBJ_ENGINE_GR, NULL }, /* nv04 pattern */ + { 0x0052, NVOBJ_ENGINE_GR, NULL }, /* swzsurf */ + { 0x0053, NVOBJ_ENGINE_GR, nv04_graph_mthds_surf3d }, /* surf3d */ + { 0x0048, NVOBJ_ENGINE_GR, nv04_graph_mthds_nv03_tex_tri }, /* nv03 tex_tri */ + { 0x0054, NVOBJ_ENGINE_GR, NULL }, /* tex_tri */ + { 0x0055, NVOBJ_ENGINE_GR, NULL }, /* multitex_tri */ + { 0x0017, NVOBJ_ENGINE_GR, NULL }, /* nv01 chroma */ + { 0x0057, NVOBJ_ENGINE_GR, NULL }, /* nv04 chroma */ + { 0x0058, NVOBJ_ENGINE_GR, NULL }, /* surf_dst */ + { 0x0059, NVOBJ_ENGINE_GR, NULL }, /* surf_src */ + { 0x005a, NVOBJ_ENGINE_GR, NULL }, /* surf_color */ + { 0x005b, NVOBJ_ENGINE_GR, NULL }, /* surf_zeta */ + { 0x001c, NVOBJ_ENGINE_GR, nv04_graph_mthds_nv01_shape }, /* nv01 line */ + { 0x005c, NVOBJ_ENGINE_GR, nv04_graph_mthds_nv04_shape }, /* nv04 line */ + { 0x001d, NVOBJ_ENGINE_GR, nv04_graph_mthds_nv01_shape }, /* nv01 tri */ + { 0x005d, NVOBJ_ENGINE_GR, nv04_graph_mthds_nv04_shape }, /* nv04 tri */ + { 0x001e, NVOBJ_ENGINE_GR, nv04_graph_mthds_nv01_shape }, /* nv01 rect */ + { 0x005e, NVOBJ_ENGINE_GR, nv04_graph_mthds_nv04_shape }, /* nv04 rect */ + { 0x506e, NVOBJ_ENGINE_SW, nv04_graph_mthds_sw }, {} }; diff --git a/drivers/gpu/drm/nouveau/nv10_graph.c b/drivers/gpu/drm/nouveau/nv10_graph.c index e3a87a64c164..375d63161d12 100644 --- a/drivers/gpu/drm/nouveau/nv10_graph.c +++ b/drivers/gpu/drm/nouveau/nv10_graph.c @@ -1075,25 +1075,25 @@ static struct nouveau_pgraph_object_method nv17_graph_celsius_mthds[] = { }; struct nouveau_pgraph_object_class nv10_graph_grclass[] = { - { 0x0030, false, NULL }, /* null */ - { 0x0039, false, NULL }, /* m2mf */ - { 0x004a, false, NULL }, /* gdirect */ - { 0x005f, false, NULL }, /* imageblit */ - { 0x009f, false, NULL }, /* imageblit (nv12) */ - { 0x008a, false, NULL }, /* ifc */ - { 0x0089, false, NULL }, /* sifm */ - { 0x0062, false, NULL }, /* surf2d */ - { 0x0043, false, NULL }, /* rop */ - { 0x0012, false, NULL }, /* beta1 */ - { 0x0072, false, NULL }, /* beta4 */ - { 0x0019, false, NULL }, /* cliprect */ - { 0x0044, false, NULL }, /* pattern */ - { 0x0052, false, NULL }, /* swzsurf */ - { 0x0093, false, NULL }, /* surf3d */ - { 0x0094, false, NULL }, /* tex_tri */ - { 0x0095, false, NULL }, /* multitex_tri */ - { 0x0056, false, NULL }, /* celcius (nv10) */ - { 0x0096, false, NULL }, /* celcius (nv11) */ - { 0x0099, false, nv17_graph_celsius_mthds }, /* celcius (nv17) */ + { 0x0030, NVOBJ_ENGINE_GR, NULL }, /* null */ + { 0x0039, NVOBJ_ENGINE_GR, NULL }, /* m2mf */ + { 0x004a, NVOBJ_ENGINE_GR, NULL }, /* gdirect */ + { 0x005f, NVOBJ_ENGINE_GR, NULL }, /* imageblit */ + { 0x009f, NVOBJ_ENGINE_GR, NULL }, /* imageblit (nv12) */ + { 0x008a, NVOBJ_ENGINE_GR, NULL }, /* ifc */ + { 0x0089, NVOBJ_ENGINE_GR, NULL }, /* sifm */ + { 0x0062, NVOBJ_ENGINE_GR, NULL }, /* surf2d */ + { 0x0043, NVOBJ_ENGINE_GR, NULL }, /* rop */ + { 0x0012, NVOBJ_ENGINE_GR, NULL }, /* beta1 */ + { 0x0072, NVOBJ_ENGINE_GR, NULL }, /* beta4 */ + { 0x0019, NVOBJ_ENGINE_GR, NULL }, /* cliprect */ + { 0x0044, NVOBJ_ENGINE_GR, NULL }, /* pattern */ + { 0x0052, NVOBJ_ENGINE_GR, NULL }, /* swzsurf */ + { 0x0093, NVOBJ_ENGINE_GR, NULL }, /* surf3d */ + { 0x0094, NVOBJ_ENGINE_GR, NULL }, /* tex_tri */ + { 0x0095, NVOBJ_ENGINE_GR, NULL }, /* multitex_tri */ + { 0x0056, NVOBJ_ENGINE_GR, NULL }, /* celcius (nv10) */ + { 0x0096, NVOBJ_ENGINE_GR, NULL }, /* celcius (nv11) */ + { 0x0099, NVOBJ_ENGINE_GR, nv17_graph_celsius_mthds }, /* celcius (nv17) */ {} }; diff --git a/drivers/gpu/drm/nouveau/nv20_graph.c b/drivers/gpu/drm/nouveau/nv20_graph.c index 8a0402012557..109418d72f93 100644 --- a/drivers/gpu/drm/nouveau/nv20_graph.c +++ b/drivers/gpu/drm/nouveau/nv20_graph.c @@ -757,45 +757,45 @@ nv30_graph_init(struct drm_device *dev) } struct nouveau_pgraph_object_class nv20_graph_grclass[] = { - { 0x0030, false, NULL }, /* null */ - { 0x0039, false, NULL }, /* m2mf */ - { 0x004a, false, NULL }, /* gdirect */ - { 0x009f, false, NULL }, /* imageblit (nv12) */ - { 0x008a, false, NULL }, /* ifc */ - { 0x0089, false, NULL }, /* sifm */ - { 0x0062, false, NULL }, /* surf2d */ - { 0x0043, false, NULL }, /* rop */ - { 0x0012, false, NULL }, /* beta1 */ - { 0x0072, false, NULL }, /* beta4 */ - { 0x0019, false, NULL }, /* cliprect */ - { 0x0044, false, NULL }, /* pattern */ - { 0x009e, false, NULL }, /* swzsurf */ - { 0x0096, false, NULL }, /* celcius */ - { 0x0097, false, NULL }, /* kelvin (nv20) */ - { 0x0597, false, NULL }, /* kelvin (nv25) */ + { 0x0030, NVOBJ_ENGINE_GR, NULL }, /* null */ + { 0x0039, NVOBJ_ENGINE_GR, NULL }, /* m2mf */ + { 0x004a, NVOBJ_ENGINE_GR, NULL }, /* gdirect */ + { 0x009f, NVOBJ_ENGINE_GR, NULL }, /* imageblit (nv12) */ + { 0x008a, NVOBJ_ENGINE_GR, NULL }, /* ifc */ + { 0x0089, NVOBJ_ENGINE_GR, NULL }, /* sifm */ + { 0x0062, NVOBJ_ENGINE_GR, NULL }, /* surf2d */ + { 0x0043, NVOBJ_ENGINE_GR, NULL }, /* rop */ + { 0x0012, NVOBJ_ENGINE_GR, NULL }, /* beta1 */ + { 0x0072, NVOBJ_ENGINE_GR, NULL }, /* beta4 */ + { 0x0019, NVOBJ_ENGINE_GR, NULL }, /* cliprect */ + { 0x0044, NVOBJ_ENGINE_GR, NULL }, /* pattern */ + { 0x009e, NVOBJ_ENGINE_GR, NULL }, /* swzsurf */ + { 0x0096, NVOBJ_ENGINE_GR, NULL }, /* celcius */ + { 0x0097, NVOBJ_ENGINE_GR, NULL }, /* kelvin (nv20) */ + { 0x0597, NVOBJ_ENGINE_GR, NULL }, /* kelvin (nv25) */ {} }; struct nouveau_pgraph_object_class nv30_graph_grclass[] = { - { 0x0030, false, NULL }, /* null */ - { 0x0039, false, NULL }, /* m2mf */ - { 0x004a, false, NULL }, /* gdirect */ - { 0x009f, false, NULL }, /* imageblit (nv12) */ - { 0x008a, false, NULL }, /* ifc */ - { 0x038a, false, NULL }, /* ifc (nv30) */ - { 0x0089, false, NULL }, /* sifm */ - { 0x0389, false, NULL }, /* sifm (nv30) */ - { 0x0062, false, NULL }, /* surf2d */ - { 0x0362, false, NULL }, /* surf2d (nv30) */ - { 0x0043, false, NULL }, /* rop */ - { 0x0012, false, NULL }, /* beta1 */ - { 0x0072, false, NULL }, /* beta4 */ - { 0x0019, false, NULL }, /* cliprect */ - { 0x0044, false, NULL }, /* pattern */ - { 0x039e, false, NULL }, /* swzsurf */ - { 0x0397, false, NULL }, /* rankine (nv30) */ - { 0x0497, false, NULL }, /* rankine (nv35) */ - { 0x0697, false, NULL }, /* rankine (nv34) */ + { 0x0030, NVOBJ_ENGINE_GR, NULL }, /* null */ + { 0x0039, NVOBJ_ENGINE_GR, NULL }, /* m2mf */ + { 0x004a, NVOBJ_ENGINE_GR, NULL }, /* gdirect */ + { 0x009f, NVOBJ_ENGINE_GR, NULL }, /* imageblit (nv12) */ + { 0x008a, NVOBJ_ENGINE_GR, NULL }, /* ifc */ + { 0x038a, NVOBJ_ENGINE_GR, NULL }, /* ifc (nv30) */ + { 0x0089, NVOBJ_ENGINE_GR, NULL }, /* sifm */ + { 0x0389, NVOBJ_ENGINE_GR, NULL }, /* sifm (nv30) */ + { 0x0062, NVOBJ_ENGINE_GR, NULL }, /* surf2d */ + { 0x0362, NVOBJ_ENGINE_GR, NULL }, /* surf2d (nv30) */ + { 0x0043, NVOBJ_ENGINE_GR, NULL }, /* rop */ + { 0x0012, NVOBJ_ENGINE_GR, NULL }, /* beta1 */ + { 0x0072, NVOBJ_ENGINE_GR, NULL }, /* beta4 */ + { 0x0019, NVOBJ_ENGINE_GR, NULL }, /* cliprect */ + { 0x0044, NVOBJ_ENGINE_GR, NULL }, /* pattern */ + { 0x039e, NVOBJ_ENGINE_GR, NULL }, /* swzsurf */ + { 0x0397, NVOBJ_ENGINE_GR, NULL }, /* rankine (nv30) */ + { 0x0497, NVOBJ_ENGINE_GR, NULL }, /* rankine (nv35) */ + { 0x0697, NVOBJ_ENGINE_GR, NULL }, /* rankine (nv34) */ {} }; diff --git a/drivers/gpu/drm/nouveau/nv40_graph.c b/drivers/gpu/drm/nouveau/nv40_graph.c index 70d97cde49d0..cd47760b2d0a 100644 --- a/drivers/gpu/drm/nouveau/nv40_graph.c +++ b/drivers/gpu/drm/nouveau/nv40_graph.c @@ -409,23 +409,23 @@ void nv40_graph_takedown(struct drm_device *dev) } struct nouveau_pgraph_object_class nv40_graph_grclass[] = { - { 0x0030, false, NULL }, /* null */ - { 0x0039, false, NULL }, /* m2mf */ - { 0x004a, false, NULL }, /* gdirect */ - { 0x009f, false, NULL }, /* imageblit (nv12) */ - { 0x008a, false, NULL }, /* ifc */ - { 0x0089, false, NULL }, /* sifm */ - { 0x3089, false, NULL }, /* sifm (nv40) */ - { 0x0062, false, NULL }, /* surf2d */ - { 0x3062, false, NULL }, /* surf2d (nv40) */ - { 0x0043, false, NULL }, /* rop */ - { 0x0012, false, NULL }, /* beta1 */ - { 0x0072, false, NULL }, /* beta4 */ - { 0x0019, false, NULL }, /* cliprect */ - { 0x0044, false, NULL }, /* pattern */ - { 0x309e, false, NULL }, /* swzsurf */ - { 0x4097, false, NULL }, /* curie (nv40) */ - { 0x4497, false, NULL }, /* curie (nv44) */ + { 0x0030, NVOBJ_ENGINE_GR, NULL }, /* null */ + { 0x0039, NVOBJ_ENGINE_GR, NULL }, /* m2mf */ + { 0x004a, NVOBJ_ENGINE_GR, NULL }, /* gdirect */ + { 0x009f, NVOBJ_ENGINE_GR, NULL }, /* imageblit (nv12) */ + { 0x008a, NVOBJ_ENGINE_GR, NULL }, /* ifc */ + { 0x0089, NVOBJ_ENGINE_GR, NULL }, /* sifm */ + { 0x3089, NVOBJ_ENGINE_GR, NULL }, /* sifm (nv40) */ + { 0x0062, NVOBJ_ENGINE_GR, NULL }, /* surf2d */ + { 0x3062, NVOBJ_ENGINE_GR, NULL }, /* surf2d (nv40) */ + { 0x0043, NVOBJ_ENGINE_GR, NULL }, /* rop */ + { 0x0012, NVOBJ_ENGINE_GR, NULL }, /* beta1 */ + { 0x0072, NVOBJ_ENGINE_GR, NULL }, /* beta4 */ + { 0x0019, NVOBJ_ENGINE_GR, NULL }, /* cliprect */ + { 0x0044, NVOBJ_ENGINE_GR, NULL }, /* pattern */ + { 0x309e, NVOBJ_ENGINE_GR, NULL }, /* swzsurf */ + { 0x4097, NVOBJ_ENGINE_GR, NULL }, /* curie (nv40) */ + { 0x4497, NVOBJ_ENGINE_GR, NULL }, /* curie (nv44) */ {} }; diff --git a/drivers/gpu/drm/nouveau/nv50_graph.c b/drivers/gpu/drm/nouveau/nv50_graph.c index dcc9175fb794..01a598917e3c 100644 --- a/drivers/gpu/drm/nouveau/nv50_graph.c +++ b/drivers/gpu/drm/nouveau/nv50_graph.c @@ -401,16 +401,16 @@ static struct nouveau_pgraph_object_method nv50_graph_nvsw_methods[] = { }; struct nouveau_pgraph_object_class nv50_graph_grclass[] = { - { 0x506e, true, nv50_graph_nvsw_methods }, /* nvsw */ - { 0x0030, false, NULL }, /* null */ - { 0x5039, false, NULL }, /* m2mf */ - { 0x502d, false, NULL }, /* 2d */ - { 0x50c0, false, NULL }, /* compute */ - { 0x85c0, false, NULL }, /* compute (nva3, nva5, nva8) */ - { 0x5097, false, NULL }, /* tesla (nv50) */ - { 0x8297, false, NULL }, /* tesla (nv8x/nv9x) */ - { 0x8397, false, NULL }, /* tesla (nva0, nvaa, nvac) */ - { 0x8597, false, NULL }, /* tesla (nva3, nva5, nva8) */ + { 0x506e, NVOBJ_ENGINE_SW, nv50_graph_nvsw_methods }, /* nvsw */ + { 0x0030, NVOBJ_ENGINE_GR, NULL }, /* null */ + { 0x5039, NVOBJ_ENGINE_GR, NULL }, /* m2mf */ + { 0x502d, NVOBJ_ENGINE_GR, NULL }, /* 2d */ + { 0x50c0, NVOBJ_ENGINE_GR, NULL }, /* compute */ + { 0x85c0, NVOBJ_ENGINE_GR, NULL }, /* compute (nva3, nva5, nva8) */ + { 0x5097, NVOBJ_ENGINE_GR, NULL }, /* tesla (nv50) */ + { 0x8297, NVOBJ_ENGINE_GR, NULL }, /* tesla (nv8x/nv9x) */ + { 0x8397, NVOBJ_ENGINE_GR, NULL }, /* tesla (nva0, nvaa, nvac) */ + { 0x8597, NVOBJ_ENGINE_GR, NULL }, /* tesla (nva3, nva5, nva8) */ {} }; -- cgit v1.2.3 From a6a1a38075661bec189f2bad7912f8861e6ce357 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 19 Oct 2010 19:57:34 +1000 Subject: drm/nouveau: use object class structs more extensively The structs themselves, as well as the non-sw object creation function are probably very misnamed now. That's a problem for later :) Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_drv.h | 2 - drivers/gpu/drm/nouveau/nouveau_fence.c | 2 +- drivers/gpu/drm/nouveau/nouveau_object.c | 97 ++++++++++++++++---------------- drivers/gpu/drm/nouveau/nv10_graph.c | 1 + drivers/gpu/drm/nouveau/nv20_graph.c | 2 + drivers/gpu/drm/nouveau/nv40_graph.c | 1 + 6 files changed, 53 insertions(+), 52 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index 2fdc26655ca1..2099f04c0b0a 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -842,8 +842,6 @@ extern int nouveau_gpuobj_gart_dma_new(struct nouveau_channel *, uint32_t *o_ret); extern int nouveau_gpuobj_gr_new(struct nouveau_channel *, int class, struct nouveau_gpuobj **); -extern int nouveau_gpuobj_sw_new(struct nouveau_channel *, int class, - struct nouveau_gpuobj **); extern int nouveau_ioctl_grobj_alloc(struct drm_device *, void *data, struct drm_file *); extern int nouveau_ioctl_gpuobj_free(struct drm_device *, void *data, diff --git a/drivers/gpu/drm/nouveau/nouveau_fence.c b/drivers/gpu/drm/nouveau/nouveau_fence.c index f70bec835f5f..75ce1b45d8a4 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fence.c +++ b/drivers/gpu/drm/nouveau/nouveau_fence.c @@ -437,7 +437,7 @@ nouveau_fence_channel_init(struct nouveau_channel *chan) int ret; /* Create an NV_SW object for various sync purposes */ - ret = nouveau_gpuobj_sw_new(chan, NV_SW, &obj); + ret = nouveau_gpuobj_gr_new(chan, NV_SW, &obj); if (ret) return ret; diff --git a/drivers/gpu/drm/nouveau/nouveau_object.c b/drivers/gpu/drm/nouveau/nouveau_object.c index 70ffd7530503..9c26da4cdc00 100644 --- a/drivers/gpu/drm/nouveau/nouveau_object.c +++ b/drivers/gpu/drm/nouveau/nouveau_object.c @@ -495,23 +495,67 @@ nouveau_gpuobj_gart_dma_new(struct nouveau_channel *chan, entry[5]: set to 0? */ +static int +nouveau_gpuobj_sw_new(struct nouveau_channel *chan, int class, + struct nouveau_gpuobj **gpuobj_ret) +{ + struct drm_nouveau_private *dev_priv; + struct nouveau_gpuobj *gpuobj; + + if (!chan || !gpuobj_ret || *gpuobj_ret != NULL) + return -EINVAL; + dev_priv = chan->dev->dev_private; + + gpuobj = kzalloc(sizeof(*gpuobj), GFP_KERNEL); + if (!gpuobj) + return -ENOMEM; + gpuobj->dev = chan->dev; + gpuobj->engine = NVOBJ_ENGINE_SW; + gpuobj->class = class; + kref_init(&gpuobj->refcount); + gpuobj->cinst = 0x40; + + spin_lock(&dev_priv->ramin_lock); + list_add_tail(&gpuobj->list, &dev_priv->gpuobj_list); + spin_unlock(&dev_priv->ramin_lock); + *gpuobj_ret = gpuobj; + return 0; +} + int nouveau_gpuobj_gr_new(struct nouveau_channel *chan, int class, struct nouveau_gpuobj **gpuobj) { + struct drm_nouveau_private *dev_priv = chan->dev->dev_private; + struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; + struct nouveau_pgraph_object_class *grc; struct drm_device *dev = chan->dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; int ret; NV_DEBUG(dev, "ch%d class=0x%04x\n", chan->id, class); + grc = pgraph->grclass; + while (grc->id) { + if (grc->id == class) + break; + grc++; + } + + if (!grc->id) { + NV_ERROR(dev, "illegal object class: 0x%x\n", class); + return -EINVAL; + } + + if (grc->engine == NVOBJ_ENGINE_SW) + return nouveau_gpuobj_sw_new(chan, class, gpuobj); + ret = nouveau_gpuobj_new(dev, chan, nouveau_gpuobj_class_instmem_size(dev, class), 16, NVOBJ_FLAG_ZERO_ALLOC | NVOBJ_FLAG_ZERO_FREE, gpuobj); if (ret) { - NV_ERROR(dev, "Error creating gpuobj: %d\n", ret); + NV_ERROR(dev, "error creating gpuobj: %d\n", ret); return ret; } @@ -541,38 +585,11 @@ nouveau_gpuobj_gr_new(struct nouveau_channel *chan, int class, } dev_priv->engine.instmem.flush(dev); - (*gpuobj)->engine = NVOBJ_ENGINE_GR; + (*gpuobj)->engine = grc->engine; (*gpuobj)->class = class; return 0; } -int -nouveau_gpuobj_sw_new(struct nouveau_channel *chan, int class, - struct nouveau_gpuobj **gpuobj_ret) -{ - struct drm_nouveau_private *dev_priv; - struct nouveau_gpuobj *gpuobj; - - if (!chan || !gpuobj_ret || *gpuobj_ret != NULL) - return -EINVAL; - dev_priv = chan->dev->dev_private; - - gpuobj = kzalloc(sizeof(*gpuobj), GFP_KERNEL); - if (!gpuobj) - return -ENOMEM; - gpuobj->dev = chan->dev; - gpuobj->engine = NVOBJ_ENGINE_SW; - gpuobj->class = class; - kref_init(&gpuobj->refcount); - gpuobj->cinst = 0x40; - - spin_lock(&dev_priv->ramin_lock); - list_add_tail(&gpuobj->list, &dev_priv->gpuobj_list); - spin_unlock(&dev_priv->ramin_lock); - *gpuobj_ret = gpuobj; - return 0; -} - static int nouveau_gpuobj_channel_init_pramin(struct nouveau_channel *chan) { @@ -868,10 +885,7 @@ nouveau_gpuobj_resume(struct drm_device *dev) int nouveau_ioctl_grobj_alloc(struct drm_device *dev, void *data, struct drm_file *file_priv) { - struct drm_nouveau_private *dev_priv = dev->dev_private; struct drm_nouveau_grobj_alloc *init = data; - struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; - struct nouveau_pgraph_object_class *grc; struct nouveau_gpuobj *gr = NULL; struct nouveau_channel *chan; int ret; @@ -879,18 +893,6 @@ int nouveau_ioctl_grobj_alloc(struct drm_device *dev, void *data, if (init->handle == ~0) return -EINVAL; - grc = pgraph->grclass; - while (grc->id) { - if (grc->id == init->class) - break; - grc++; - } - - if (!grc->id) { - NV_ERROR(dev, "Illegal object class: 0x%x\n", init->class); - return -EPERM; - } - chan = nouveau_channel_get(dev, file_priv, init->channel); if (IS_ERR(chan)) return PTR_ERR(chan); @@ -900,10 +902,7 @@ int nouveau_ioctl_grobj_alloc(struct drm_device *dev, void *data, goto out; } - if (grc->engine != NVOBJ_ENGINE_SW) - ret = nouveau_gpuobj_gr_new(chan, grc->id, &gr); - else - ret = nouveau_gpuobj_sw_new(chan, grc->id, &gr); + ret = nouveau_gpuobj_gr_new(chan, init->class, &gr); if (ret) { NV_ERROR(dev, "Error creating object: %d (%d/0x%08x)\n", ret, init->channel, init->handle); diff --git a/drivers/gpu/drm/nouveau/nv10_graph.c b/drivers/gpu/drm/nouveau/nv10_graph.c index 375d63161d12..ed31a622889e 100644 --- a/drivers/gpu/drm/nouveau/nv10_graph.c +++ b/drivers/gpu/drm/nouveau/nv10_graph.c @@ -1075,6 +1075,7 @@ static struct nouveau_pgraph_object_method nv17_graph_celsius_mthds[] = { }; struct nouveau_pgraph_object_class nv10_graph_grclass[] = { + { 0x506e, NVOBJ_ENGINE_SW, NULL }, /* nvsw */ { 0x0030, NVOBJ_ENGINE_GR, NULL }, /* null */ { 0x0039, NVOBJ_ENGINE_GR, NULL }, /* m2mf */ { 0x004a, NVOBJ_ENGINE_GR, NULL }, /* gdirect */ diff --git a/drivers/gpu/drm/nouveau/nv20_graph.c b/drivers/gpu/drm/nouveau/nv20_graph.c index 109418d72f93..872f8d059694 100644 --- a/drivers/gpu/drm/nouveau/nv20_graph.c +++ b/drivers/gpu/drm/nouveau/nv20_graph.c @@ -757,6 +757,7 @@ nv30_graph_init(struct drm_device *dev) } struct nouveau_pgraph_object_class nv20_graph_grclass[] = { + { 0x506e, NVOBJ_ENGINE_SW, NULL }, /* nvsw */ { 0x0030, NVOBJ_ENGINE_GR, NULL }, /* null */ { 0x0039, NVOBJ_ENGINE_GR, NULL }, /* m2mf */ { 0x004a, NVOBJ_ENGINE_GR, NULL }, /* gdirect */ @@ -777,6 +778,7 @@ struct nouveau_pgraph_object_class nv20_graph_grclass[] = { }; struct nouveau_pgraph_object_class nv30_graph_grclass[] = { + { 0x506e, NVOBJ_ENGINE_SW, NULL }, /* nvsw */ { 0x0030, NVOBJ_ENGINE_GR, NULL }, /* null */ { 0x0039, NVOBJ_ENGINE_GR, NULL }, /* m2mf */ { 0x004a, NVOBJ_ENGINE_GR, NULL }, /* gdirect */ diff --git a/drivers/gpu/drm/nouveau/nv40_graph.c b/drivers/gpu/drm/nouveau/nv40_graph.c index cd47760b2d0a..70d957895cea 100644 --- a/drivers/gpu/drm/nouveau/nv40_graph.c +++ b/drivers/gpu/drm/nouveau/nv40_graph.c @@ -409,6 +409,7 @@ void nv40_graph_takedown(struct drm_device *dev) } struct nouveau_pgraph_object_class nv40_graph_grclass[] = { + { 0x506e, NVOBJ_ENGINE_SW, NULL }, /* nvsw */ { 0x0030, NVOBJ_ENGINE_GR, NULL }, /* null */ { 0x0039, NVOBJ_ENGINE_GR, NULL }, /* m2mf */ { 0x004a, NVOBJ_ENGINE_GR, NULL }, /* gdirect */ -- cgit v1.2.3 From b8c157d3a9a13871742c8a8d3d4598c3791ed5f5 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 20 Oct 2010 10:39:35 +1000 Subject: drm/nouveau: only expose the object classes that are supported by the chipset We previously added all the available classes for the entire generation, even though the objects wouldn't work on the hardware. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_drv.h | 38 +-- drivers/gpu/drm/nouveau/nouveau_irq.c | 36 +-- drivers/gpu/drm/nouveau/nouveau_object.c | 112 ++++++- drivers/gpu/drm/nouveau/nouveau_state.c | 7 - drivers/gpu/drm/nouveau/nv04_graph.c | 530 ++++++++++++++++++------------- drivers/gpu/drm/nouveau/nv10_graph.c | 92 +++--- drivers/gpu/drm/nouveau/nv20_graph.c | 131 +++++--- drivers/gpu/drm/nouveau/nv40_graph.c | 63 ++-- drivers/gpu/drm/nouveau/nv50_graph.c | 91 ++++-- 9 files changed, 667 insertions(+), 433 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index 2099f04c0b0a..3fb87995446b 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -316,21 +316,9 @@ struct nouveau_fifo_engine { void (*tlb_flush)(struct drm_device *dev); }; -struct nouveau_pgraph_object_method { - int id; - int (*exec)(struct nouveau_channel *chan, int grclass, int mthd, - uint32_t data); -}; - -struct nouveau_pgraph_object_class { - int id; - u32 engine; - struct nouveau_pgraph_object_method *methods; -}; - struct nouveau_pgraph_engine { - struct nouveau_pgraph_object_class *grclass; bool accel_blocked; + bool registered; int grctx_size; /* NV2x/NV3x context table (0x400780) */ @@ -584,6 +572,7 @@ struct drm_nouveau_private { bool ramin_available; struct drm_mm ramin_heap; struct list_head gpuobj_list; + struct list_head classes; struct nouveau_bo *vga_ram; @@ -816,12 +805,29 @@ extern void nouveau_channel_ref(struct nouveau_channel *chan, struct nouveau_channel **pchan); /* nouveau_object.c */ +#define NVOBJ_CLASS(d,c,e) do { \ + int ret = nouveau_gpuobj_class_new((d), (c), NVOBJ_ENGINE_##e); \ + if (ret) \ + return ret; \ +} while(0) + +#define NVOBJ_MTHD(d,c,m,e) do { \ + int ret = nouveau_gpuobj_mthd_new((d), (c), (m), (e)); \ + if (ret) \ + return ret; \ +} while(0) + extern int nouveau_gpuobj_early_init(struct drm_device *); extern int nouveau_gpuobj_init(struct drm_device *); extern void nouveau_gpuobj_takedown(struct drm_device *); extern int nouveau_gpuobj_suspend(struct drm_device *dev); extern void nouveau_gpuobj_suspend_cleanup(struct drm_device *dev); extern void nouveau_gpuobj_resume(struct drm_device *dev); +extern int nouveau_gpuobj_class_new(struct drm_device *, u32 class, u32 eng); +extern int nouveau_gpuobj_mthd_new(struct drm_device *, u32 class, u32 mthd, + int (*exec)(struct nouveau_channel *, + u32 class, u32 mthd, u32 data)); +extern int nouveau_gpuobj_mthd_call(struct nouveau_channel *, u32, u32, u32); extern int nouveau_gpuobj_channel_init(struct nouveau_channel *, uint32_t vram_h, uint32_t tt_h); extern void nouveau_gpuobj_channel_takedown(struct nouveau_channel *); @@ -1038,7 +1044,6 @@ extern int nvc0_fifo_load_context(struct nouveau_channel *); extern int nvc0_fifo_unload_context(struct drm_device *); /* nv04_graph.c */ -extern struct nouveau_pgraph_object_class nv04_graph_grclass[]; extern int nv04_graph_init(struct drm_device *); extern void nv04_graph_takedown(struct drm_device *); extern void nv04_graph_fifo_access(struct drm_device *, bool); @@ -1050,7 +1055,6 @@ extern int nv04_graph_unload_context(struct drm_device *); extern void nv04_graph_context_switch(struct drm_device *); /* nv10_graph.c */ -extern struct nouveau_pgraph_object_class nv10_graph_grclass[]; extern int nv10_graph_init(struct drm_device *); extern void nv10_graph_takedown(struct drm_device *); extern struct nouveau_channel *nv10_graph_channel(struct drm_device *); @@ -1063,8 +1067,6 @@ extern void nv10_graph_set_region_tiling(struct drm_device *, int, uint32_t, uint32_t, uint32_t); /* nv20_graph.c */ -extern struct nouveau_pgraph_object_class nv20_graph_grclass[]; -extern struct nouveau_pgraph_object_class nv30_graph_grclass[]; extern int nv20_graph_create_context(struct nouveau_channel *); extern void nv20_graph_destroy_context(struct nouveau_channel *); extern int nv20_graph_load_context(struct nouveau_channel *); @@ -1076,7 +1078,6 @@ extern void nv20_graph_set_region_tiling(struct drm_device *, int, uint32_t, uint32_t, uint32_t); /* nv40_graph.c */ -extern struct nouveau_pgraph_object_class nv40_graph_grclass[]; extern int nv40_graph_init(struct drm_device *); extern void nv40_graph_takedown(struct drm_device *); extern struct nouveau_channel *nv40_graph_channel(struct drm_device *); @@ -1089,7 +1090,6 @@ extern void nv40_graph_set_region_tiling(struct drm_device *, int, uint32_t, uint32_t, uint32_t); /* nv50_graph.c */ -extern struct nouveau_pgraph_object_class nv50_graph_grclass[]; extern int nv50_graph_init(struct drm_device *); extern void nv50_graph_takedown(struct drm_device *); extern void nv50_graph_fifo_access(struct drm_device *, bool); diff --git a/drivers/gpu/drm/nouveau/nouveau_irq.c b/drivers/gpu/drm/nouveau/nouveau_irq.c index c5e37bc17192..f09151d17297 100644 --- a/drivers/gpu/drm/nouveau/nouveau_irq.c +++ b/drivers/gpu/drm/nouveau/nouveau_irq.c @@ -80,33 +80,6 @@ nouveau_irq_uninstall(struct drm_device *dev) nv_wr32(dev, NV03_PMC_INTR_EN_0, 0); } -static int -nouveau_call_method(struct nouveau_channel *chan, int class, int mthd, int data) -{ - struct drm_nouveau_private *dev_priv = chan->dev->dev_private; - struct nouveau_pgraph_object_method *grm; - struct nouveau_pgraph_object_class *grc; - - grc = dev_priv->engine.graph.grclass; - while (grc->id) { - if (grc->id == class) - break; - grc++; - } - - if (grc->id != class || !grc->methods) - return -ENOENT; - - grm = grc->methods; - while (grm->id) { - if (grm->id == mthd) - return grm->exec(chan, class, mthd, data); - grm++; - } - - return -ENOENT; -} - static bool nouveau_fifo_swmthd(struct drm_device *dev, u32 chid, u32 addr, u32 data) { @@ -142,8 +115,8 @@ nouveau_fifo_swmthd(struct drm_device *dev, u32 chid, u32 addr, u32 data) if (unlikely(((engine >> (subc * 4)) & 0xf) != 0)) break; - if (!nouveau_call_method(chan, chan->sw_subchannel[subc], - mthd, data)) + if (!nouveau_gpuobj_mthd_call(chan, chan->sw_subchannel[subc], + mthd, data)) handled = true; break; } @@ -541,6 +514,7 @@ nouveau_pgraph_intr_swmthd(struct drm_device *dev, struct nouveau_pgraph_trap *trap) { struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_channel *chan; unsigned long flags; int ret = -EINVAL; @@ -548,8 +522,8 @@ nouveau_pgraph_intr_swmthd(struct drm_device *dev, if (trap->channel > 0 && trap->channel < dev_priv->engine.fifo.channels && dev_priv->channels.ptr[trap->channel]) { - ret = nouveau_call_method(dev_priv->channels.ptr[trap->channel], - trap->class, trap->mthd, trap->data); + chan = dev_priv->channels.ptr[trap->channel]; + ret = nouveau_gpuobj_mthd_call(chan, trap->class, trap->mthd, trap->data); } spin_unlock_irqrestore(&dev_priv->channels.lock, flags); diff --git a/drivers/gpu/drm/nouveau/nouveau_object.c b/drivers/gpu/drm/nouveau/nouveau_object.c index 9c26da4cdc00..6226beb3613d 100644 --- a/drivers/gpu/drm/nouveau/nouveau_object.c +++ b/drivers/gpu/drm/nouveau/nouveau_object.c @@ -36,6 +36,83 @@ #include "nouveau_drm.h" #include "nouveau_ramht.h" +struct nouveau_gpuobj_method { + struct list_head head; + u32 mthd; + int (*exec)(struct nouveau_channel *, u32 class, u32 mthd, u32 data); +}; + +struct nouveau_gpuobj_class { + struct list_head head; + struct list_head methods; + u32 id; + u32 engine; +}; + +int +nouveau_gpuobj_class_new(struct drm_device *dev, u32 class, u32 engine) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_gpuobj_class *oc; + + oc = kzalloc(sizeof(*oc), GFP_KERNEL); + if (!oc) + return -ENOMEM; + + INIT_LIST_HEAD(&oc->methods); + oc->id = class; + oc->engine = engine; + list_add(&oc->head, &dev_priv->classes); + return 0; +} + +int +nouveau_gpuobj_mthd_new(struct drm_device *dev, u32 class, u32 mthd, + int (*exec)(struct nouveau_channel *, u32, u32, u32)) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_gpuobj_method *om; + struct nouveau_gpuobj_class *oc; + + list_for_each_entry(oc, &dev_priv->classes, head) { + if (oc->id == class) + goto found; + } + + return -EINVAL; + +found: + om = kzalloc(sizeof(*om), GFP_KERNEL); + if (!om) + return -ENOMEM; + + om->mthd = mthd; + om->exec = exec; + list_add(&om->head, &oc->methods); + return 0; +} + +int +nouveau_gpuobj_mthd_call(struct nouveau_channel *chan, + u32 class, u32 mthd, u32 data) +{ + struct drm_nouveau_private *dev_priv = chan->dev->dev_private; + struct nouveau_gpuobj_method *om; + struct nouveau_gpuobj_class *oc; + + list_for_each_entry(oc, &dev_priv->classes, head) { + if (oc->id != class) + continue; + + list_for_each_entry(om, &oc->methods, head) { + if (om->mthd == mthd) + return om->exec(chan, class, mthd, data); + } + } + + return -ENOENT; +} + /* NVidia uses context objects to drive drawing operations. Context objects can be selected into 8 subchannels in the FIFO, @@ -205,9 +282,20 @@ void nouveau_gpuobj_takedown(struct drm_device *dev) { struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_gpuobj_method *om, *tm; + struct nouveau_gpuobj_class *oc, *tc; NV_DEBUG(dev, "\n"); + list_for_each_entry_safe(oc, tc, &dev_priv->classes, head) { + list_for_each_entry_safe(om, tm, &oc->methods, head) { + list_del(&om->head); + kfree(om); + } + list_del(&oc->head); + kfree(oc); + } + BUG_ON(!list_empty(&dev_priv->gpuobj_list)); } @@ -527,26 +615,22 @@ nouveau_gpuobj_gr_new(struct nouveau_channel *chan, int class, struct nouveau_gpuobj **gpuobj) { struct drm_nouveau_private *dev_priv = chan->dev->dev_private; - struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; - struct nouveau_pgraph_object_class *grc; struct drm_device *dev = chan->dev; + struct nouveau_gpuobj_class *oc; int ret; NV_DEBUG(dev, "ch%d class=0x%04x\n", chan->id, class); - grc = pgraph->grclass; - while (grc->id) { - if (grc->id == class) - break; - grc++; + list_for_each_entry(oc, &dev_priv->classes, head) { + if (oc->id == class) + goto found; } - if (!grc->id) { - NV_ERROR(dev, "illegal object class: 0x%x\n", class); - return -EINVAL; - } + NV_ERROR(dev, "illegal object class: 0x%x\n", class); + return -EINVAL; - if (grc->engine == NVOBJ_ENGINE_SW) +found: + if (oc->engine == NVOBJ_ENGINE_SW) return nouveau_gpuobj_sw_new(chan, class, gpuobj); ret = nouveau_gpuobj_new(dev, chan, @@ -585,8 +669,8 @@ nouveau_gpuobj_gr_new(struct nouveau_channel *chan, int class, } dev_priv->engine.instmem.flush(dev); - (*gpuobj)->engine = grc->engine; - (*gpuobj)->class = class; + (*gpuobj)->engine = oc->engine; + (*gpuobj)->class = oc->id; return 0; } diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c index 82b58188398b..be28754ffd50 100644 --- a/drivers/gpu/drm/nouveau/nouveau_state.c +++ b/drivers/gpu/drm/nouveau/nouveau_state.c @@ -65,7 +65,6 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->timer.takedown = nv04_timer_takedown; engine->fb.init = nv04_fb_init; engine->fb.takedown = nv04_fb_takedown; - engine->graph.grclass = nv04_graph_grclass; engine->graph.init = nv04_graph_init; engine->graph.takedown = nv04_graph_takedown; engine->graph.fifo_access = nv04_graph_fifo_access; @@ -118,7 +117,6 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->fb.init = nv10_fb_init; engine->fb.takedown = nv10_fb_takedown; engine->fb.set_region_tiling = nv10_fb_set_region_tiling; - engine->graph.grclass = nv10_graph_grclass; engine->graph.init = nv10_graph_init; engine->graph.takedown = nv10_graph_takedown; engine->graph.channel = nv10_graph_channel; @@ -172,7 +170,6 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->fb.init = nv10_fb_init; engine->fb.takedown = nv10_fb_takedown; engine->fb.set_region_tiling = nv10_fb_set_region_tiling; - engine->graph.grclass = nv20_graph_grclass; engine->graph.init = nv20_graph_init; engine->graph.takedown = nv20_graph_takedown; engine->graph.channel = nv10_graph_channel; @@ -226,7 +223,6 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->fb.init = nv30_fb_init; engine->fb.takedown = nv30_fb_takedown; engine->fb.set_region_tiling = nv10_fb_set_region_tiling; - engine->graph.grclass = nv30_graph_grclass; engine->graph.init = nv30_graph_init; engine->graph.takedown = nv20_graph_takedown; engine->graph.fifo_access = nv04_graph_fifo_access; @@ -283,7 +279,6 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->fb.init = nv40_fb_init; engine->fb.takedown = nv40_fb_takedown; engine->fb.set_region_tiling = nv40_fb_set_region_tiling; - engine->graph.grclass = nv40_graph_grclass; engine->graph.init = nv40_graph_init; engine->graph.takedown = nv40_graph_takedown; engine->graph.fifo_access = nv04_graph_fifo_access; @@ -345,7 +340,6 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->timer.takedown = nv04_timer_takedown; engine->fb.init = nv50_fb_init; engine->fb.takedown = nv50_fb_takedown; - engine->graph.grclass = nv50_graph_grclass; engine->graph.init = nv50_graph_init; engine->graph.takedown = nv50_graph_takedown; engine->graph.fifo_access = nv50_graph_fifo_access; @@ -424,7 +418,6 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->timer.takedown = nv04_timer_takedown; engine->fb.init = nvc0_fb_init; engine->fb.takedown = nvc0_fb_takedown; - engine->graph.grclass = NULL; //nvc0_graph_grclass; engine->graph.init = nvc0_graph_init; engine->graph.takedown = nvc0_graph_takedown; engine->graph.fifo_access = nvc0_graph_fifo_access; diff --git a/drivers/gpu/drm/nouveau/nv04_graph.c b/drivers/gpu/drm/nouveau/nv04_graph.c index 5d8ab1b6b04a..81aba097ef95 100644 --- a/drivers/gpu/drm/nouveau/nv04_graph.c +++ b/drivers/gpu/drm/nouveau/nv04_graph.c @@ -27,6 +27,8 @@ #include "nouveau_drm.h" #include "nouveau_drv.h" +static int nv04_graph_register(struct drm_device *dev); + static uint32_t nv04_graph_ctx_regs[] = { 0x0040053c, 0x00400544, @@ -483,12 +485,17 @@ int nv04_graph_init(struct drm_device *dev) { struct drm_nouveau_private *dev_priv = dev->dev_private; uint32_t tmp; + int ret; nv_wr32(dev, NV03_PMC_ENABLE, nv_rd32(dev, NV03_PMC_ENABLE) & ~NV_PMC_ENABLE_PGRAPH); nv_wr32(dev, NV03_PMC_ENABLE, nv_rd32(dev, NV03_PMC_ENABLE) | NV_PMC_ENABLE_PGRAPH); + ret = nv04_graph_register(dev); + if (ret) + return ret; + /* Enable PGRAPH interrupts */ nv_wr32(dev, NV03_PGRAPH_INTR, 0xFFFFFFFF); nv_wr32(dev, NV03_PGRAPH_INTR_EN, 0xFFFFFFFF); @@ -539,8 +546,8 @@ nv04_graph_fifo_access(struct drm_device *dev, bool enabled) } static int -nv04_graph_mthd_set_ref(struct nouveau_channel *chan, int grclass, - int mthd, uint32_t data) +nv04_graph_mthd_set_ref(struct nouveau_channel *chan, + u32 class, u32 mthd, u32 data) { atomic_set(&chan->fence.last_sequence_irq, data); return 0; @@ -621,12 +628,12 @@ nv04_graph_mthd_set_ref(struct nouveau_channel *chan, int grclass, */ static void -nv04_graph_set_ctx1(struct nouveau_channel *chan, uint32_t mask, uint32_t value) +nv04_graph_set_ctx1(struct nouveau_channel *chan, u32 mask, u32 value) { struct drm_device *dev = chan->dev; - uint32_t instance = (nv_rd32(dev, NV04_PGRAPH_CTX_SWITCH4) & 0xffff) << 4; + u32 instance = (nv_rd32(dev, NV04_PGRAPH_CTX_SWITCH4) & 0xffff) << 4; int subc = (nv_rd32(dev, NV04_PGRAPH_TRAPPED_ADDR) >> 13) & 0x7; - uint32_t tmp; + u32 tmp; tmp = nv_ri32(dev, instance); tmp &= ~mask; @@ -638,11 +645,11 @@ nv04_graph_set_ctx1(struct nouveau_channel *chan, uint32_t mask, uint32_t value) } static void -nv04_graph_set_ctx_val(struct nouveau_channel *chan, uint32_t mask, uint32_t value) +nv04_graph_set_ctx_val(struct nouveau_channel *chan, u32 mask, u32 value) { struct drm_device *dev = chan->dev; - uint32_t instance = (nv_rd32(dev, NV04_PGRAPH_CTX_SWITCH4) & 0xffff) << 4; - uint32_t tmp, ctx1; + u32 instance = (nv_rd32(dev, NV04_PGRAPH_CTX_SWITCH4) & 0xffff) << 4; + u32 tmp, ctx1; int class, op, valid = 1; ctx1 = nv_ri32(dev, instance); @@ -687,13 +694,13 @@ nv04_graph_set_ctx_val(struct nouveau_channel *chan, uint32_t mask, uint32_t val } static int -nv04_graph_mthd_set_operation(struct nouveau_channel *chan, int grclass, - int mthd, uint32_t data) +nv04_graph_mthd_set_operation(struct nouveau_channel *chan, + u32 class, u32 mthd, u32 data) { if (data > 5) return 1; /* Old versions of the objects only accept first three operations. */ - if (data > 2 && grclass < 0x40) + if (data > 2 && class < 0x40) return 1; nv04_graph_set_ctx1(chan, 0x00038000, data << 15); /* changing operation changes set of objects needed for validation */ @@ -702,8 +709,8 @@ nv04_graph_mthd_set_operation(struct nouveau_channel *chan, int grclass, } static int -nv04_graph_mthd_surf3d_clip_h(struct nouveau_channel *chan, int grclass, - int mthd, uint32_t data) +nv04_graph_mthd_surf3d_clip_h(struct nouveau_channel *chan, + u32 class, u32 mthd, u32 data) { uint32_t min = data & 0xffff, max; uint32_t w = data >> 16; @@ -721,8 +728,8 @@ nv04_graph_mthd_surf3d_clip_h(struct nouveau_channel *chan, int grclass, } static int -nv04_graph_mthd_surf3d_clip_v(struct nouveau_channel *chan, int grclass, - int mthd, uint32_t data) +nv04_graph_mthd_surf3d_clip_v(struct nouveau_channel *chan, + u32 class, u32 mthd, u32 data) { uint32_t min = data & 0xffff, max; uint32_t w = data >> 16; @@ -740,8 +747,8 @@ nv04_graph_mthd_surf3d_clip_v(struct nouveau_channel *chan, int grclass, } static int -nv04_graph_mthd_bind_surf2d(struct nouveau_channel *chan, int grclass, - int mthd, uint32_t data) +nv04_graph_mthd_bind_surf2d(struct nouveau_channel *chan, + u32 class, u32 mthd, u32 data) { switch (nv_ri32(chan->dev, data << 4) & 0xff) { case 0x30: @@ -757,8 +764,8 @@ nv04_graph_mthd_bind_surf2d(struct nouveau_channel *chan, int grclass, } static int -nv04_graph_mthd_bind_surf2d_swzsurf(struct nouveau_channel *chan, int grclass, - int mthd, uint32_t data) +nv04_graph_mthd_bind_surf2d_swzsurf(struct nouveau_channel *chan, + u32 class, u32 mthd, u32 data) { switch (nv_ri32(chan->dev, data << 4) & 0xff) { case 0x30: @@ -778,8 +785,8 @@ nv04_graph_mthd_bind_surf2d_swzsurf(struct nouveau_channel *chan, int grclass, } static int -nv04_graph_mthd_bind_nv01_patt(struct nouveau_channel *chan, int grclass, - int mthd, uint32_t data) +nv04_graph_mthd_bind_nv01_patt(struct nouveau_channel *chan, + u32 class, u32 mthd, u32 data) { switch (nv_ri32(chan->dev, data << 4) & 0xff) { case 0x30: @@ -793,8 +800,8 @@ nv04_graph_mthd_bind_nv01_patt(struct nouveau_channel *chan, int grclass, } static int -nv04_graph_mthd_bind_nv04_patt(struct nouveau_channel *chan, int grclass, - int mthd, uint32_t data) +nv04_graph_mthd_bind_nv04_patt(struct nouveau_channel *chan, + u32 class, u32 mthd, u32 data) { switch (nv_ri32(chan->dev, data << 4) & 0xff) { case 0x30: @@ -808,8 +815,8 @@ nv04_graph_mthd_bind_nv04_patt(struct nouveau_channel *chan, int grclass, } static int -nv04_graph_mthd_bind_rop(struct nouveau_channel *chan, int grclass, - int mthd, uint32_t data) +nv04_graph_mthd_bind_rop(struct nouveau_channel *chan, + u32 class, u32 mthd, u32 data) { switch (nv_ri32(chan->dev, data << 4) & 0xff) { case 0x30: @@ -823,8 +830,8 @@ nv04_graph_mthd_bind_rop(struct nouveau_channel *chan, int grclass, } static int -nv04_graph_mthd_bind_beta1(struct nouveau_channel *chan, int grclass, - int mthd, uint32_t data) +nv04_graph_mthd_bind_beta1(struct nouveau_channel *chan, + u32 class, u32 mthd, u32 data) { switch (nv_ri32(chan->dev, data << 4) & 0xff) { case 0x30: @@ -838,8 +845,8 @@ nv04_graph_mthd_bind_beta1(struct nouveau_channel *chan, int grclass, } static int -nv04_graph_mthd_bind_beta4(struct nouveau_channel *chan, int grclass, - int mthd, uint32_t data) +nv04_graph_mthd_bind_beta4(struct nouveau_channel *chan, + u32 class, u32 mthd, u32 data) { switch (nv_ri32(chan->dev, data << 4) & 0xff) { case 0x30: @@ -853,8 +860,8 @@ nv04_graph_mthd_bind_beta4(struct nouveau_channel *chan, int grclass, } static int -nv04_graph_mthd_bind_surf_dst(struct nouveau_channel *chan, int grclass, - int mthd, uint32_t data) +nv04_graph_mthd_bind_surf_dst(struct nouveau_channel *chan, + u32 class, u32 mthd, u32 data) { switch (nv_ri32(chan->dev, data << 4) & 0xff) { case 0x30: @@ -868,8 +875,8 @@ nv04_graph_mthd_bind_surf_dst(struct nouveau_channel *chan, int grclass, } static int -nv04_graph_mthd_bind_surf_src(struct nouveau_channel *chan, int grclass, - int mthd, uint32_t data) +nv04_graph_mthd_bind_surf_src(struct nouveau_channel *chan, + u32 class, u32 mthd, u32 data) { switch (nv_ri32(chan->dev, data << 4) & 0xff) { case 0x30: @@ -883,8 +890,8 @@ nv04_graph_mthd_bind_surf_src(struct nouveau_channel *chan, int grclass, } static int -nv04_graph_mthd_bind_surf_color(struct nouveau_channel *chan, int grclass, - int mthd, uint32_t data) +nv04_graph_mthd_bind_surf_color(struct nouveau_channel *chan, + u32 class, u32 mthd, u32 data) { switch (nv_ri32(chan->dev, data << 4) & 0xff) { case 0x30: @@ -898,8 +905,8 @@ nv04_graph_mthd_bind_surf_color(struct nouveau_channel *chan, int grclass, } static int -nv04_graph_mthd_bind_surf_zeta(struct nouveau_channel *chan, int grclass, - int mthd, uint32_t data) +nv04_graph_mthd_bind_surf_zeta(struct nouveau_channel *chan, + u32 class, u32 mthd, u32 data) { switch (nv_ri32(chan->dev, data << 4) & 0xff) { case 0x30: @@ -913,8 +920,8 @@ nv04_graph_mthd_bind_surf_zeta(struct nouveau_channel *chan, int grclass, } static int -nv04_graph_mthd_bind_clip(struct nouveau_channel *chan, int grclass, - int mthd, uint32_t data) +nv04_graph_mthd_bind_clip(struct nouveau_channel *chan, + u32 class, u32 mthd, u32 data) { switch (nv_ri32(chan->dev, data << 4) & 0xff) { case 0x30: @@ -928,8 +935,8 @@ nv04_graph_mthd_bind_clip(struct nouveau_channel *chan, int grclass, } static int -nv04_graph_mthd_bind_chroma(struct nouveau_channel *chan, int grclass, - int mthd, uint32_t data) +nv04_graph_mthd_bind_chroma(struct nouveau_channel *chan, + u32 class, u32 mthd, u32 data) { switch (nv_ri32(chan->dev, data << 4) & 0xff) { case 0x30: @@ -945,194 +952,259 @@ nv04_graph_mthd_bind_chroma(struct nouveau_channel *chan, int grclass, return 1; } -static struct nouveau_pgraph_object_method nv04_graph_mthds_sw[] = { - { 0x0150, nv04_graph_mthd_set_ref }, - {} -}; - -static struct nouveau_pgraph_object_method nv04_graph_mthds_nv03_gdirect[] = { - { 0x0184, nv04_graph_mthd_bind_nv01_patt }, - { 0x0188, nv04_graph_mthd_bind_rop }, - { 0x018c, nv04_graph_mthd_bind_beta1 }, - { 0x0190, nv04_graph_mthd_bind_surf_dst }, - { 0x02fc, nv04_graph_mthd_set_operation }, - {}, -}; - -static struct nouveau_pgraph_object_method nv04_graph_mthds_nv04_gdirect[] = { - { 0x0188, nv04_graph_mthd_bind_nv04_patt }, - { 0x018c, nv04_graph_mthd_bind_rop }, - { 0x0190, nv04_graph_mthd_bind_beta1 }, - { 0x0194, nv04_graph_mthd_bind_beta4 }, - { 0x0198, nv04_graph_mthd_bind_surf2d }, - { 0x02fc, nv04_graph_mthd_set_operation }, - {}, -}; - -static struct nouveau_pgraph_object_method nv04_graph_mthds_nv01_imageblit[] = { - { 0x0184, nv04_graph_mthd_bind_chroma }, - { 0x0188, nv04_graph_mthd_bind_clip }, - { 0x018c, nv04_graph_mthd_bind_nv01_patt }, - { 0x0190, nv04_graph_mthd_bind_rop }, - { 0x0194, nv04_graph_mthd_bind_beta1 }, - { 0x0198, nv04_graph_mthd_bind_surf_dst }, - { 0x019c, nv04_graph_mthd_bind_surf_src }, - { 0x02fc, nv04_graph_mthd_set_operation }, - {}, -}; - -static struct nouveau_pgraph_object_method nv04_graph_mthds_nv04_imageblit_ifc[] = { - { 0x0184, nv04_graph_mthd_bind_chroma }, - { 0x0188, nv04_graph_mthd_bind_clip }, - { 0x018c, nv04_graph_mthd_bind_nv04_patt }, - { 0x0190, nv04_graph_mthd_bind_rop }, - { 0x0194, nv04_graph_mthd_bind_beta1 }, - { 0x0198, nv04_graph_mthd_bind_beta4 }, - { 0x019c, nv04_graph_mthd_bind_surf2d }, - { 0x02fc, nv04_graph_mthd_set_operation }, - {}, -}; - -static struct nouveau_pgraph_object_method nv04_graph_mthds_nv04_iifc[] = { - { 0x0188, nv04_graph_mthd_bind_chroma }, - { 0x018c, nv04_graph_mthd_bind_clip }, - { 0x0190, nv04_graph_mthd_bind_nv04_patt }, - { 0x0194, nv04_graph_mthd_bind_rop }, - { 0x0198, nv04_graph_mthd_bind_beta1 }, - { 0x019c, nv04_graph_mthd_bind_beta4 }, - { 0x01a0, nv04_graph_mthd_bind_surf2d_swzsurf }, - { 0x03e4, nv04_graph_mthd_set_operation }, - {}, -}; - -static struct nouveau_pgraph_object_method nv04_graph_mthds_nv01_ifc[] = { - { 0x0184, nv04_graph_mthd_bind_chroma }, - { 0x0188, nv04_graph_mthd_bind_clip }, - { 0x018c, nv04_graph_mthd_bind_nv01_patt }, - { 0x0190, nv04_graph_mthd_bind_rop }, - { 0x0194, nv04_graph_mthd_bind_beta1 }, - { 0x0198, nv04_graph_mthd_bind_surf_dst }, - { 0x02fc, nv04_graph_mthd_set_operation }, - {}, -}; - -static struct nouveau_pgraph_object_method nv04_graph_mthds_nv03_sifc[] = { - { 0x0184, nv04_graph_mthd_bind_chroma }, - { 0x0188, nv04_graph_mthd_bind_nv01_patt }, - { 0x018c, nv04_graph_mthd_bind_rop }, - { 0x0190, nv04_graph_mthd_bind_beta1 }, - { 0x0194, nv04_graph_mthd_bind_surf_dst }, - { 0x02fc, nv04_graph_mthd_set_operation }, - {}, -}; - -static struct nouveau_pgraph_object_method nv04_graph_mthds_nv04_sifc[] = { - { 0x0184, nv04_graph_mthd_bind_chroma }, - { 0x0188, nv04_graph_mthd_bind_nv04_patt }, - { 0x018c, nv04_graph_mthd_bind_rop }, - { 0x0190, nv04_graph_mthd_bind_beta1 }, - { 0x0194, nv04_graph_mthd_bind_beta4 }, - { 0x0198, nv04_graph_mthd_bind_surf2d }, - { 0x02fc, nv04_graph_mthd_set_operation }, - {}, -}; - -static struct nouveau_pgraph_object_method nv04_graph_mthds_nv03_sifm[] = { - { 0x0188, nv04_graph_mthd_bind_nv01_patt }, - { 0x018c, nv04_graph_mthd_bind_rop }, - { 0x0190, nv04_graph_mthd_bind_beta1 }, - { 0x0194, nv04_graph_mthd_bind_surf_dst }, - { 0x0304, nv04_graph_mthd_set_operation }, - {}, -}; - -static struct nouveau_pgraph_object_method nv04_graph_mthds_nv04_sifm[] = { - { 0x0188, nv04_graph_mthd_bind_nv04_patt }, - { 0x018c, nv04_graph_mthd_bind_rop }, - { 0x0190, nv04_graph_mthd_bind_beta1 }, - { 0x0194, nv04_graph_mthd_bind_beta4 }, - { 0x0198, nv04_graph_mthd_bind_surf2d_swzsurf }, - { 0x0304, nv04_graph_mthd_set_operation }, - {}, -}; - -static struct nouveau_pgraph_object_method nv04_graph_mthds_nv01_shape[] = { - { 0x0184, nv04_graph_mthd_bind_clip }, - { 0x0188, nv04_graph_mthd_bind_nv01_patt }, - { 0x018c, nv04_graph_mthd_bind_rop }, - { 0x0190, nv04_graph_mthd_bind_beta1 }, - { 0x0194, nv04_graph_mthd_bind_surf_dst }, - { 0x02fc, nv04_graph_mthd_set_operation }, - {}, -}; - -static struct nouveau_pgraph_object_method nv04_graph_mthds_nv04_shape[] = { - { 0x0184, nv04_graph_mthd_bind_clip }, - { 0x0188, nv04_graph_mthd_bind_nv04_patt }, - { 0x018c, nv04_graph_mthd_bind_rop }, - { 0x0190, nv04_graph_mthd_bind_beta1 }, - { 0x0194, nv04_graph_mthd_bind_beta4 }, - { 0x0198, nv04_graph_mthd_bind_surf2d }, - { 0x02fc, nv04_graph_mthd_set_operation }, - {}, -}; - -static struct nouveau_pgraph_object_method nv04_graph_mthds_nv03_tex_tri[] = { - { 0x0188, nv04_graph_mthd_bind_clip }, - { 0x018c, nv04_graph_mthd_bind_surf_color }, - { 0x0190, nv04_graph_mthd_bind_surf_zeta }, - {}, -}; +static int +nv04_graph_register(struct drm_device *dev) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; -static struct nouveau_pgraph_object_method nv04_graph_mthds_surf3d[] = { - { 0x02f8, nv04_graph_mthd_surf3d_clip_h }, - { 0x02fc, nv04_graph_mthd_surf3d_clip_v }, - {}, -}; + if (dev_priv->engine.graph.registered) + return 0; -struct nouveau_pgraph_object_class nv04_graph_grclass[] = { - { 0x0038, NVOBJ_ENGINE_GR, NULL }, /* dvd subpicture */ - { 0x0039, NVOBJ_ENGINE_GR, NULL }, /* m2mf */ - { 0x004b, NVOBJ_ENGINE_GR, nv04_graph_mthds_nv03_gdirect }, /* nv03 gdirect */ - { 0x004a, NVOBJ_ENGINE_GR, nv04_graph_mthds_nv04_gdirect }, /* nv04 gdirect */ - { 0x001f, NVOBJ_ENGINE_GR, nv04_graph_mthds_nv01_imageblit }, /* nv01 imageblit */ - { 0x005f, NVOBJ_ENGINE_GR, nv04_graph_mthds_nv04_imageblit_ifc }, /* nv04 imageblit */ - { 0x0060, NVOBJ_ENGINE_GR, nv04_graph_mthds_nv04_iifc }, /* nv04 iifc */ - { 0x0064, NVOBJ_ENGINE_GR, NULL }, /* nv05 iifc */ - { 0x0021, NVOBJ_ENGINE_GR, nv04_graph_mthds_nv01_ifc }, /* nv01 ifc */ - { 0x0061, NVOBJ_ENGINE_GR, nv04_graph_mthds_nv04_imageblit_ifc }, /* nv04 ifc */ - { 0x0065, NVOBJ_ENGINE_GR, NULL }, /* nv05 ifc */ - { 0x0036, NVOBJ_ENGINE_GR, nv04_graph_mthds_nv03_sifc }, /* nv03 sifc */ - { 0x0076, NVOBJ_ENGINE_GR, nv04_graph_mthds_nv04_sifc }, /* nv04 sifc */ - { 0x0066, NVOBJ_ENGINE_GR, NULL }, /* nv05 sifc */ - { 0x0037, NVOBJ_ENGINE_GR, nv04_graph_mthds_nv03_sifm }, /* nv03 sifm */ - { 0x0077, NVOBJ_ENGINE_GR, nv04_graph_mthds_nv04_sifm }, /* nv04 sifm */ - { 0x0030, NVOBJ_ENGINE_GR, NULL }, /* null */ - { 0x0042, NVOBJ_ENGINE_GR, NULL }, /* surf2d */ - { 0x0043, NVOBJ_ENGINE_GR, NULL }, /* rop */ - { 0x0012, NVOBJ_ENGINE_GR, NULL }, /* beta1 */ - { 0x0072, NVOBJ_ENGINE_GR, NULL }, /* beta4 */ - { 0x0019, NVOBJ_ENGINE_GR, NULL }, /* cliprect */ - { 0x0018, NVOBJ_ENGINE_GR, NULL }, /* nv01 pattern */ - { 0x0044, NVOBJ_ENGINE_GR, NULL }, /* nv04 pattern */ - { 0x0052, NVOBJ_ENGINE_GR, NULL }, /* swzsurf */ - { 0x0053, NVOBJ_ENGINE_GR, nv04_graph_mthds_surf3d }, /* surf3d */ - { 0x0048, NVOBJ_ENGINE_GR, nv04_graph_mthds_nv03_tex_tri }, /* nv03 tex_tri */ - { 0x0054, NVOBJ_ENGINE_GR, NULL }, /* tex_tri */ - { 0x0055, NVOBJ_ENGINE_GR, NULL }, /* multitex_tri */ - { 0x0017, NVOBJ_ENGINE_GR, NULL }, /* nv01 chroma */ - { 0x0057, NVOBJ_ENGINE_GR, NULL }, /* nv04 chroma */ - { 0x0058, NVOBJ_ENGINE_GR, NULL }, /* surf_dst */ - { 0x0059, NVOBJ_ENGINE_GR, NULL }, /* surf_src */ - { 0x005a, NVOBJ_ENGINE_GR, NULL }, /* surf_color */ - { 0x005b, NVOBJ_ENGINE_GR, NULL }, /* surf_zeta */ - { 0x001c, NVOBJ_ENGINE_GR, nv04_graph_mthds_nv01_shape }, /* nv01 line */ - { 0x005c, NVOBJ_ENGINE_GR, nv04_graph_mthds_nv04_shape }, /* nv04 line */ - { 0x001d, NVOBJ_ENGINE_GR, nv04_graph_mthds_nv01_shape }, /* nv01 tri */ - { 0x005d, NVOBJ_ENGINE_GR, nv04_graph_mthds_nv04_shape }, /* nv04 tri */ - { 0x001e, NVOBJ_ENGINE_GR, nv04_graph_mthds_nv01_shape }, /* nv01 rect */ - { 0x005e, NVOBJ_ENGINE_GR, nv04_graph_mthds_nv04_shape }, /* nv04 rect */ - { 0x506e, NVOBJ_ENGINE_SW, nv04_graph_mthds_sw }, - {} + /* dvd subpicture */ + NVOBJ_CLASS(dev, 0x0038, GR); + + /* m2mf */ + NVOBJ_CLASS(dev, 0x0039, GR); + + /* nv03 gdirect */ + NVOBJ_CLASS(dev, 0x004b, GR); + NVOBJ_MTHD (dev, 0x004b, 0x0184, nv04_graph_mthd_bind_nv01_patt); + NVOBJ_MTHD (dev, 0x004b, 0x0188, nv04_graph_mthd_bind_rop); + NVOBJ_MTHD (dev, 0x004b, 0x018c, nv04_graph_mthd_bind_beta1); + NVOBJ_MTHD (dev, 0x004b, 0x0190, nv04_graph_mthd_bind_surf_dst); + NVOBJ_MTHD (dev, 0x004b, 0x02fc, nv04_graph_mthd_set_operation); + + /* nv04 gdirect */ + NVOBJ_CLASS(dev, 0x004a, GR); + NVOBJ_MTHD (dev, 0x004a, 0x0188, nv04_graph_mthd_bind_nv04_patt); + NVOBJ_MTHD (dev, 0x004a, 0x018c, nv04_graph_mthd_bind_rop); + NVOBJ_MTHD (dev, 0x004a, 0x0190, nv04_graph_mthd_bind_beta1); + NVOBJ_MTHD (dev, 0x004a, 0x0194, nv04_graph_mthd_bind_beta4); + NVOBJ_MTHD (dev, 0x004a, 0x0198, nv04_graph_mthd_bind_surf2d); + NVOBJ_MTHD (dev, 0x004a, 0x02fc, nv04_graph_mthd_set_operation); + + /* nv01 imageblit */ + NVOBJ_CLASS(dev, 0x001f, GR); + NVOBJ_MTHD (dev, 0x001f, 0x0184, nv04_graph_mthd_bind_chroma); + NVOBJ_MTHD (dev, 0x001f, 0x0188, nv04_graph_mthd_bind_clip); + NVOBJ_MTHD (dev, 0x001f, 0x018c, nv04_graph_mthd_bind_nv01_patt); + NVOBJ_MTHD (dev, 0x001f, 0x0190, nv04_graph_mthd_bind_rop); + NVOBJ_MTHD (dev, 0x001f, 0x0194, nv04_graph_mthd_bind_beta1); + NVOBJ_MTHD (dev, 0x001f, 0x0198, nv04_graph_mthd_bind_surf_dst); + NVOBJ_MTHD (dev, 0x001f, 0x019c, nv04_graph_mthd_bind_surf_src); + NVOBJ_MTHD (dev, 0x001f, 0x02fc, nv04_graph_mthd_set_operation); + + /* nv04 imageblit */ + NVOBJ_CLASS(dev, 0x005f, GR); + NVOBJ_MTHD (dev, 0x005f, 0x0184, nv04_graph_mthd_bind_chroma); + NVOBJ_MTHD (dev, 0x005f, 0x0188, nv04_graph_mthd_bind_clip); + NVOBJ_MTHD (dev, 0x005f, 0x018c, nv04_graph_mthd_bind_nv04_patt); + NVOBJ_MTHD (dev, 0x005f, 0x0190, nv04_graph_mthd_bind_rop); + NVOBJ_MTHD (dev, 0x005f, 0x0194, nv04_graph_mthd_bind_beta1); + NVOBJ_MTHD (dev, 0x005f, 0x0198, nv04_graph_mthd_bind_beta4); + NVOBJ_MTHD (dev, 0x005f, 0x019c, nv04_graph_mthd_bind_surf2d); + NVOBJ_MTHD (dev, 0x005f, 0x02fc, nv04_graph_mthd_set_operation); + + /* nv04 iifc */ + NVOBJ_CLASS(dev, 0x0060, GR); + NVOBJ_MTHD (dev, 0x0060, 0x0188, nv04_graph_mthd_bind_chroma); + NVOBJ_MTHD (dev, 0x0060, 0x018c, nv04_graph_mthd_bind_clip); + NVOBJ_MTHD (dev, 0x0060, 0x0190, nv04_graph_mthd_bind_nv04_patt); + NVOBJ_MTHD (dev, 0x0060, 0x0194, nv04_graph_mthd_bind_rop); + NVOBJ_MTHD (dev, 0x0060, 0x0198, nv04_graph_mthd_bind_beta1); + NVOBJ_MTHD (dev, 0x0060, 0x019c, nv04_graph_mthd_bind_beta4); + NVOBJ_MTHD (dev, 0x0060, 0x01a0, nv04_graph_mthd_bind_surf2d_swzsurf); + NVOBJ_MTHD (dev, 0x0060, 0x03e4, nv04_graph_mthd_set_operation); + + /* nv05 iifc */ + NVOBJ_CLASS(dev, 0x0064, GR); + + /* nv01 ifc */ + NVOBJ_CLASS(dev, 0x0021, GR); + NVOBJ_MTHD (dev, 0x0021, 0x0184, nv04_graph_mthd_bind_chroma); + NVOBJ_MTHD (dev, 0x0021, 0x0188, nv04_graph_mthd_bind_clip); + NVOBJ_MTHD (dev, 0x0021, 0x018c, nv04_graph_mthd_bind_nv01_patt); + NVOBJ_MTHD (dev, 0x0021, 0x0190, nv04_graph_mthd_bind_rop); + NVOBJ_MTHD (dev, 0x0021, 0x0194, nv04_graph_mthd_bind_beta1); + NVOBJ_MTHD (dev, 0x0021, 0x0198, nv04_graph_mthd_bind_surf_dst); + NVOBJ_MTHD (dev, 0x0021, 0x02fc, nv04_graph_mthd_set_operation); + + /* nv04 ifc */ + NVOBJ_CLASS(dev, 0x0061, GR); + NVOBJ_MTHD (dev, 0x0061, 0x0184, nv04_graph_mthd_bind_chroma); + NVOBJ_MTHD (dev, 0x0061, 0x0188, nv04_graph_mthd_bind_clip); + NVOBJ_MTHD (dev, 0x0061, 0x018c, nv04_graph_mthd_bind_nv04_patt); + NVOBJ_MTHD (dev, 0x0061, 0x0190, nv04_graph_mthd_bind_rop); + NVOBJ_MTHD (dev, 0x0061, 0x0194, nv04_graph_mthd_bind_beta1); + NVOBJ_MTHD (dev, 0x0061, 0x0198, nv04_graph_mthd_bind_beta4); + NVOBJ_MTHD (dev, 0x0061, 0x019c, nv04_graph_mthd_bind_surf2d); + NVOBJ_MTHD (dev, 0x0061, 0x02fc, nv04_graph_mthd_set_operation); + + /* nv05 ifc */ + NVOBJ_CLASS(dev, 0x0065, GR); + + /* nv03 sifc */ + NVOBJ_CLASS(dev, 0x0036, GR); + NVOBJ_MTHD (dev, 0x0036, 0x0184, nv04_graph_mthd_bind_chroma); + NVOBJ_MTHD (dev, 0x0036, 0x0188, nv04_graph_mthd_bind_nv01_patt); + NVOBJ_MTHD (dev, 0x0036, 0x018c, nv04_graph_mthd_bind_rop); + NVOBJ_MTHD (dev, 0x0036, 0x0190, nv04_graph_mthd_bind_beta1); + NVOBJ_MTHD (dev, 0x0036, 0x0194, nv04_graph_mthd_bind_surf_dst); + NVOBJ_MTHD (dev, 0x0036, 0x02fc, nv04_graph_mthd_set_operation); + + /* nv04 sifc */ + NVOBJ_CLASS(dev, 0x0076, GR); + NVOBJ_MTHD (dev, 0x0076, 0x0184, nv04_graph_mthd_bind_chroma); + NVOBJ_MTHD (dev, 0x0076, 0x0188, nv04_graph_mthd_bind_nv04_patt); + NVOBJ_MTHD (dev, 0x0076, 0x018c, nv04_graph_mthd_bind_rop); + NVOBJ_MTHD (dev, 0x0076, 0x0190, nv04_graph_mthd_bind_beta1); + NVOBJ_MTHD (dev, 0x0076, 0x0194, nv04_graph_mthd_bind_beta4); + NVOBJ_MTHD (dev, 0x0076, 0x0198, nv04_graph_mthd_bind_surf2d); + NVOBJ_MTHD (dev, 0x0076, 0x02fc, nv04_graph_mthd_set_operation); + + /* nv05 sifc */ + NVOBJ_CLASS(dev, 0x0066, GR); + + /* nv03 sifm */ + NVOBJ_CLASS(dev, 0x0037, GR); + NVOBJ_MTHD (dev, 0x0037, 0x0188, nv04_graph_mthd_bind_nv01_patt); + NVOBJ_MTHD (dev, 0x0037, 0x018c, nv04_graph_mthd_bind_rop); + NVOBJ_MTHD (dev, 0x0037, 0x0190, nv04_graph_mthd_bind_beta1); + NVOBJ_MTHD (dev, 0x0037, 0x0194, nv04_graph_mthd_bind_surf_dst); + NVOBJ_MTHD (dev, 0x0037, 0x0304, nv04_graph_mthd_set_operation); + + /* nv04 sifm */ + NVOBJ_CLASS(dev, 0x0077, GR); + NVOBJ_MTHD (dev, 0x0077, 0x0188, nv04_graph_mthd_bind_nv04_patt); + NVOBJ_MTHD (dev, 0x0077, 0x018c, nv04_graph_mthd_bind_rop); + NVOBJ_MTHD (dev, 0x0077, 0x0190, nv04_graph_mthd_bind_beta1); + NVOBJ_MTHD (dev, 0x0077, 0x0194, nv04_graph_mthd_bind_beta4); + NVOBJ_MTHD (dev, 0x0077, 0x0198, nv04_graph_mthd_bind_surf2d_swzsurf); + NVOBJ_MTHD (dev, 0x0077, 0x0304, nv04_graph_mthd_set_operation); + + /* null */ + NVOBJ_CLASS(dev, 0x0030, GR); + + /* surf2d */ + NVOBJ_CLASS(dev, 0x0042, GR); + + /* rop */ + NVOBJ_CLASS(dev, 0x0043, GR); + + /* beta1 */ + NVOBJ_CLASS(dev, 0x0012, GR); + + /* beta4 */ + NVOBJ_CLASS(dev, 0x0072, GR); + + /* cliprect */ + NVOBJ_CLASS(dev, 0x0019, GR); + + /* nv01 pattern */ + NVOBJ_CLASS(dev, 0x0018, GR); + + /* nv04 pattern */ + NVOBJ_CLASS(dev, 0x0044, GR); + + /* swzsurf */ + NVOBJ_CLASS(dev, 0x0052, GR); + + /* surf3d */ + NVOBJ_CLASS(dev, 0x0053, GR); + NVOBJ_MTHD (dev, 0x0053, 0x02f8, nv04_graph_mthd_surf3d_clip_h); + NVOBJ_MTHD (dev, 0x0053, 0x02fc, nv04_graph_mthd_surf3d_clip_v); + + /* nv03 tex_tri */ + NVOBJ_CLASS(dev, 0x0048, GR); + NVOBJ_MTHD (dev, 0x0048, 0x0188, nv04_graph_mthd_bind_clip); + NVOBJ_MTHD (dev, 0x0048, 0x018c, nv04_graph_mthd_bind_surf_color); + NVOBJ_MTHD (dev, 0x0048, 0x0190, nv04_graph_mthd_bind_surf_zeta); + + /* tex_tri */ + NVOBJ_CLASS(dev, 0x0054, GR); + + /* multitex_tri */ + NVOBJ_CLASS(dev, 0x0055, GR); + + /* nv01 chroma */ + NVOBJ_CLASS(dev, 0x0017, GR); + + /* nv04 chroma */ + NVOBJ_CLASS(dev, 0x0057, GR); + + /* surf_dst */ + NVOBJ_CLASS(dev, 0x0058, GR); + + /* surf_src */ + NVOBJ_CLASS(dev, 0x0059, GR); + + /* surf_color */ + NVOBJ_CLASS(dev, 0x005a, GR); + + /* surf_zeta */ + NVOBJ_CLASS(dev, 0x005b, GR); + + /* nv01 line */ + NVOBJ_CLASS(dev, 0x001c, GR); + NVOBJ_MTHD (dev, 0x001c, 0x0184, nv04_graph_mthd_bind_clip); + NVOBJ_MTHD (dev, 0x001c, 0x0188, nv04_graph_mthd_bind_nv01_patt); + NVOBJ_MTHD (dev, 0x001c, 0x018c, nv04_graph_mthd_bind_rop); + NVOBJ_MTHD (dev, 0x001c, 0x0190, nv04_graph_mthd_bind_beta1); + NVOBJ_MTHD (dev, 0x001c, 0x0194, nv04_graph_mthd_bind_surf_dst); + NVOBJ_MTHD (dev, 0x001c, 0x02fc, nv04_graph_mthd_set_operation); + + /* nv04 line */ + NVOBJ_CLASS(dev, 0x005c, GR); + NVOBJ_MTHD (dev, 0x005c, 0x0184, nv04_graph_mthd_bind_clip); + NVOBJ_MTHD (dev, 0x005c, 0x0188, nv04_graph_mthd_bind_nv04_patt); + NVOBJ_MTHD (dev, 0x005c, 0x018c, nv04_graph_mthd_bind_rop); + NVOBJ_MTHD (dev, 0x005c, 0x0190, nv04_graph_mthd_bind_beta1); + NVOBJ_MTHD (dev, 0x005c, 0x0194, nv04_graph_mthd_bind_beta4); + NVOBJ_MTHD (dev, 0x005c, 0x0198, nv04_graph_mthd_bind_surf2d); + NVOBJ_MTHD (dev, 0x005c, 0x02fc, nv04_graph_mthd_set_operation); + + /* nv01 tri */ + NVOBJ_CLASS(dev, 0x001d, GR); + NVOBJ_MTHD (dev, 0x001d, 0x0184, nv04_graph_mthd_bind_clip); + NVOBJ_MTHD (dev, 0x001d, 0x0188, nv04_graph_mthd_bind_nv01_patt); + NVOBJ_MTHD (dev, 0x001d, 0x018c, nv04_graph_mthd_bind_rop); + NVOBJ_MTHD (dev, 0x001d, 0x0190, nv04_graph_mthd_bind_beta1); + NVOBJ_MTHD (dev, 0x001d, 0x0194, nv04_graph_mthd_bind_surf_dst); + NVOBJ_MTHD (dev, 0x001d, 0x02fc, nv04_graph_mthd_set_operation); + + /* nv04 tri */ + NVOBJ_CLASS(dev, 0x005d, GR); + NVOBJ_MTHD (dev, 0x005d, 0x0184, nv04_graph_mthd_bind_clip); + NVOBJ_MTHD (dev, 0x005d, 0x0188, nv04_graph_mthd_bind_nv04_patt); + NVOBJ_MTHD (dev, 0x005d, 0x018c, nv04_graph_mthd_bind_rop); + NVOBJ_MTHD (dev, 0x005d, 0x0190, nv04_graph_mthd_bind_beta1); + NVOBJ_MTHD (dev, 0x005d, 0x0194, nv04_graph_mthd_bind_beta4); + NVOBJ_MTHD (dev, 0x005d, 0x0198, nv04_graph_mthd_bind_surf2d); + NVOBJ_MTHD (dev, 0x005d, 0x02fc, nv04_graph_mthd_set_operation); + + /* nv01 rect */ + NVOBJ_CLASS(dev, 0x001e, GR); + NVOBJ_MTHD (dev, 0x001e, 0x0184, nv04_graph_mthd_bind_clip); + NVOBJ_MTHD (dev, 0x001e, 0x0188, nv04_graph_mthd_bind_nv01_patt); + NVOBJ_MTHD (dev, 0x001e, 0x018c, nv04_graph_mthd_bind_rop); + NVOBJ_MTHD (dev, 0x001e, 0x0190, nv04_graph_mthd_bind_beta1); + NVOBJ_MTHD (dev, 0x001e, 0x0194, nv04_graph_mthd_bind_surf_dst); + NVOBJ_MTHD (dev, 0x001e, 0x02fc, nv04_graph_mthd_set_operation); + + /* nv04 rect */ + NVOBJ_CLASS(dev, 0x005e, GR); + NVOBJ_MTHD (dev, 0x005e, 0x0184, nv04_graph_mthd_bind_clip); + NVOBJ_MTHD (dev, 0x005e, 0x0188, nv04_graph_mthd_bind_nv04_patt); + NVOBJ_MTHD (dev, 0x005e, 0x018c, nv04_graph_mthd_bind_rop); + NVOBJ_MTHD (dev, 0x005e, 0x0190, nv04_graph_mthd_bind_beta1); + NVOBJ_MTHD (dev, 0x005e, 0x0194, nv04_graph_mthd_bind_beta4); + NVOBJ_MTHD (dev, 0x005e, 0x0198, nv04_graph_mthd_bind_surf2d); + NVOBJ_MTHD (dev, 0x005e, 0x02fc, nv04_graph_mthd_set_operation); + + /* nvsw */ + NVOBJ_CLASS(dev, 0x506e, SW); + NVOBJ_MTHD (dev, 0x506e, 0x0150, nv04_graph_mthd_set_ref); + + dev_priv->engine.graph.registered = true; + return 0; }; - diff --git a/drivers/gpu/drm/nouveau/nv10_graph.c b/drivers/gpu/drm/nouveau/nv10_graph.c index ed31a622889e..17c20dbff232 100644 --- a/drivers/gpu/drm/nouveau/nv10_graph.c +++ b/drivers/gpu/drm/nouveau/nv10_graph.c @@ -27,6 +27,8 @@ #include "nouveau_drm.h" #include "nouveau_drv.h" +static int nv10_graph_register(struct drm_device *); + #define NV10_FIFO_NUMBER 32 struct pipe_state { @@ -914,13 +916,17 @@ int nv10_graph_init(struct drm_device *dev) { struct drm_nouveau_private *dev_priv = dev->dev_private; uint32_t tmp; - int i; + int ret, i; nv_wr32(dev, NV03_PMC_ENABLE, nv_rd32(dev, NV03_PMC_ENABLE) & ~NV_PMC_ENABLE_PGRAPH); nv_wr32(dev, NV03_PMC_ENABLE, nv_rd32(dev, NV03_PMC_ENABLE) | NV_PMC_ENABLE_PGRAPH); + ret = nv10_graph_register(dev); + if (ret) + return ret; + nv_wr32(dev, NV03_PGRAPH_INTR , 0xFFFFFFFF); nv_wr32(dev, NV03_PGRAPH_INTR_EN, 0xFFFFFFFF); @@ -966,8 +972,8 @@ void nv10_graph_takedown(struct drm_device *dev) } static int -nv17_graph_mthd_lma_window(struct nouveau_channel *chan, int grclass, - int mthd, uint32_t data) +nv17_graph_mthd_lma_window(struct nouveau_channel *chan, + u32 class, u32 mthd, u32 data) { struct drm_device *dev = chan->dev; struct graph_state *ctx = chan->pgraph_ctx; @@ -1046,8 +1052,8 @@ nv17_graph_mthd_lma_window(struct nouveau_channel *chan, int grclass, } static int -nv17_graph_mthd_lma_enable(struct nouveau_channel *chan, int grclass, - int mthd, uint32_t data) +nv17_graph_mthd_lma_enable(struct nouveau_channel *chan, + u32 class, u32 mthd, u32 data) { struct drm_device *dev = chan->dev; struct drm_nouveau_private *dev_priv = dev->dev_private; @@ -1065,36 +1071,48 @@ nv17_graph_mthd_lma_enable(struct nouveau_channel *chan, int grclass, return 0; } -static struct nouveau_pgraph_object_method nv17_graph_celsius_mthds[] = { - { 0x1638, nv17_graph_mthd_lma_window }, - { 0x163c, nv17_graph_mthd_lma_window }, - { 0x1640, nv17_graph_mthd_lma_window }, - { 0x1644, nv17_graph_mthd_lma_window }, - { 0x1658, nv17_graph_mthd_lma_enable }, - {} -}; +static int +nv10_graph_register(struct drm_device *dev) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; -struct nouveau_pgraph_object_class nv10_graph_grclass[] = { - { 0x506e, NVOBJ_ENGINE_SW, NULL }, /* nvsw */ - { 0x0030, NVOBJ_ENGINE_GR, NULL }, /* null */ - { 0x0039, NVOBJ_ENGINE_GR, NULL }, /* m2mf */ - { 0x004a, NVOBJ_ENGINE_GR, NULL }, /* gdirect */ - { 0x005f, NVOBJ_ENGINE_GR, NULL }, /* imageblit */ - { 0x009f, NVOBJ_ENGINE_GR, NULL }, /* imageblit (nv12) */ - { 0x008a, NVOBJ_ENGINE_GR, NULL }, /* ifc */ - { 0x0089, NVOBJ_ENGINE_GR, NULL }, /* sifm */ - { 0x0062, NVOBJ_ENGINE_GR, NULL }, /* surf2d */ - { 0x0043, NVOBJ_ENGINE_GR, NULL }, /* rop */ - { 0x0012, NVOBJ_ENGINE_GR, NULL }, /* beta1 */ - { 0x0072, NVOBJ_ENGINE_GR, NULL }, /* beta4 */ - { 0x0019, NVOBJ_ENGINE_GR, NULL }, /* cliprect */ - { 0x0044, NVOBJ_ENGINE_GR, NULL }, /* pattern */ - { 0x0052, NVOBJ_ENGINE_GR, NULL }, /* swzsurf */ - { 0x0093, NVOBJ_ENGINE_GR, NULL }, /* surf3d */ - { 0x0094, NVOBJ_ENGINE_GR, NULL }, /* tex_tri */ - { 0x0095, NVOBJ_ENGINE_GR, NULL }, /* multitex_tri */ - { 0x0056, NVOBJ_ENGINE_GR, NULL }, /* celcius (nv10) */ - { 0x0096, NVOBJ_ENGINE_GR, NULL }, /* celcius (nv11) */ - { 0x0099, NVOBJ_ENGINE_GR, nv17_graph_celsius_mthds }, /* celcius (nv17) */ - {} -}; + if (dev_priv->engine.graph.registered) + return 0; + + NVOBJ_CLASS(dev, 0x506e, SW); /* nvsw */ + NVOBJ_CLASS(dev, 0x0030, GR); /* null */ + NVOBJ_CLASS(dev, 0x0039, GR); /* m2mf */ + NVOBJ_CLASS(dev, 0x004a, GR); /* gdirect */ + NVOBJ_CLASS(dev, 0x005f, GR); /* imageblit */ + NVOBJ_CLASS(dev, 0x009f, GR); /* imageblit (nv12) */ + NVOBJ_CLASS(dev, 0x008a, GR); /* ifc */ + NVOBJ_CLASS(dev, 0x0089, GR); /* sifm */ + NVOBJ_CLASS(dev, 0x0062, GR); /* surf2d */ + NVOBJ_CLASS(dev, 0x0043, GR); /* rop */ + NVOBJ_CLASS(dev, 0x0012, GR); /* beta1 */ + NVOBJ_CLASS(dev, 0x0072, GR); /* beta4 */ + NVOBJ_CLASS(dev, 0x0019, GR); /* cliprect */ + NVOBJ_CLASS(dev, 0x0044, GR); /* pattern */ + NVOBJ_CLASS(dev, 0x0052, GR); /* swzsurf */ + NVOBJ_CLASS(dev, 0x0093, GR); /* surf3d */ + NVOBJ_CLASS(dev, 0x0094, GR); /* tex_tri */ + NVOBJ_CLASS(dev, 0x0095, GR); /* multitex_tri */ + + /* celcius */ + if (dev_priv->chipset <= 0x10) { + NVOBJ_CLASS(dev, 0x0056, GR); + } else + if (dev_priv->chipset <= 0x17 || dev_priv->chipset == 0x1a) { + NVOBJ_CLASS(dev, 0x0096, GR); + } else { + NVOBJ_CLASS(dev, 0x0099, GR); + NVOBJ_MTHD (dev, 0x0099, 0x1638, nv17_graph_mthd_lma_window); + NVOBJ_MTHD (dev, 0x0099, 0x163c, nv17_graph_mthd_lma_window); + NVOBJ_MTHD (dev, 0x0099, 0x1640, nv17_graph_mthd_lma_window); + NVOBJ_MTHD (dev, 0x0099, 0x1644, nv17_graph_mthd_lma_window); + NVOBJ_MTHD (dev, 0x0099, 0x1658, nv17_graph_mthd_lma_enable); + } + + dev_priv->engine.graph.registered = true; + return 0; +} diff --git a/drivers/gpu/drm/nouveau/nv20_graph.c b/drivers/gpu/drm/nouveau/nv20_graph.c index 872f8d059694..7720bccb3c98 100644 --- a/drivers/gpu/drm/nouveau/nv20_graph.c +++ b/drivers/gpu/drm/nouveau/nv20_graph.c @@ -32,6 +32,9 @@ #define NV34_GRCTX_SIZE (18140) #define NV35_36_GRCTX_SIZE (22396) +static int nv20_graph_register(struct drm_device *); +static int nv30_graph_register(struct drm_device *); + static void nv20_graph_context_init(struct drm_device *dev, struct nouveau_gpuobj *ctx) { @@ -572,6 +575,12 @@ nv20_graph_init(struct drm_device *dev) nv20_graph_rdi(dev); + ret = nv20_graph_register(dev); + if (ret) { + nouveau_gpuobj_ref(NULL, &pgraph->ctx_table); + return ret; + } + nv_wr32(dev, NV03_PGRAPH_INTR , 0xFFFFFFFF); nv_wr32(dev, NV03_PGRAPH_INTR_EN, 0xFFFFFFFF); @@ -696,6 +705,12 @@ nv30_graph_init(struct drm_device *dev) return ret; } + ret = nv30_graph_register(dev); + if (ret) { + nouveau_gpuobj_ref(NULL, &pgraph->ctx_table); + return ret; + } + nv_wr32(dev, NV20_PGRAPH_CHANNEL_CTX_TABLE, pgraph->ctx_table->pinst >> 4); @@ -756,48 +771,76 @@ nv30_graph_init(struct drm_device *dev) return 0; } -struct nouveau_pgraph_object_class nv20_graph_grclass[] = { - { 0x506e, NVOBJ_ENGINE_SW, NULL }, /* nvsw */ - { 0x0030, NVOBJ_ENGINE_GR, NULL }, /* null */ - { 0x0039, NVOBJ_ENGINE_GR, NULL }, /* m2mf */ - { 0x004a, NVOBJ_ENGINE_GR, NULL }, /* gdirect */ - { 0x009f, NVOBJ_ENGINE_GR, NULL }, /* imageblit (nv12) */ - { 0x008a, NVOBJ_ENGINE_GR, NULL }, /* ifc */ - { 0x0089, NVOBJ_ENGINE_GR, NULL }, /* sifm */ - { 0x0062, NVOBJ_ENGINE_GR, NULL }, /* surf2d */ - { 0x0043, NVOBJ_ENGINE_GR, NULL }, /* rop */ - { 0x0012, NVOBJ_ENGINE_GR, NULL }, /* beta1 */ - { 0x0072, NVOBJ_ENGINE_GR, NULL }, /* beta4 */ - { 0x0019, NVOBJ_ENGINE_GR, NULL }, /* cliprect */ - { 0x0044, NVOBJ_ENGINE_GR, NULL }, /* pattern */ - { 0x009e, NVOBJ_ENGINE_GR, NULL }, /* swzsurf */ - { 0x0096, NVOBJ_ENGINE_GR, NULL }, /* celcius */ - { 0x0097, NVOBJ_ENGINE_GR, NULL }, /* kelvin (nv20) */ - { 0x0597, NVOBJ_ENGINE_GR, NULL }, /* kelvin (nv25) */ - {} -}; - -struct nouveau_pgraph_object_class nv30_graph_grclass[] = { - { 0x506e, NVOBJ_ENGINE_SW, NULL }, /* nvsw */ - { 0x0030, NVOBJ_ENGINE_GR, NULL }, /* null */ - { 0x0039, NVOBJ_ENGINE_GR, NULL }, /* m2mf */ - { 0x004a, NVOBJ_ENGINE_GR, NULL }, /* gdirect */ - { 0x009f, NVOBJ_ENGINE_GR, NULL }, /* imageblit (nv12) */ - { 0x008a, NVOBJ_ENGINE_GR, NULL }, /* ifc */ - { 0x038a, NVOBJ_ENGINE_GR, NULL }, /* ifc (nv30) */ - { 0x0089, NVOBJ_ENGINE_GR, NULL }, /* sifm */ - { 0x0389, NVOBJ_ENGINE_GR, NULL }, /* sifm (nv30) */ - { 0x0062, NVOBJ_ENGINE_GR, NULL }, /* surf2d */ - { 0x0362, NVOBJ_ENGINE_GR, NULL }, /* surf2d (nv30) */ - { 0x0043, NVOBJ_ENGINE_GR, NULL }, /* rop */ - { 0x0012, NVOBJ_ENGINE_GR, NULL }, /* beta1 */ - { 0x0072, NVOBJ_ENGINE_GR, NULL }, /* beta4 */ - { 0x0019, NVOBJ_ENGINE_GR, NULL }, /* cliprect */ - { 0x0044, NVOBJ_ENGINE_GR, NULL }, /* pattern */ - { 0x039e, NVOBJ_ENGINE_GR, NULL }, /* swzsurf */ - { 0x0397, NVOBJ_ENGINE_GR, NULL }, /* rankine (nv30) */ - { 0x0497, NVOBJ_ENGINE_GR, NULL }, /* rankine (nv35) */ - { 0x0697, NVOBJ_ENGINE_GR, NULL }, /* rankine (nv34) */ - {} -}; +static int +nv20_graph_register(struct drm_device *dev) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + + if (dev_priv->engine.graph.registered) + return 0; + NVOBJ_CLASS(dev, 0x506e, SW); /* nvsw */ + NVOBJ_CLASS(dev, 0x0030, GR); /* null */ + NVOBJ_CLASS(dev, 0x0039, GR); /* m2mf */ + NVOBJ_CLASS(dev, 0x004a, GR); /* gdirect */ + NVOBJ_CLASS(dev, 0x009f, GR); /* imageblit (nv12) */ + NVOBJ_CLASS(dev, 0x008a, GR); /* ifc */ + NVOBJ_CLASS(dev, 0x0089, GR); /* sifm */ + NVOBJ_CLASS(dev, 0x0062, GR); /* surf2d */ + NVOBJ_CLASS(dev, 0x0043, GR); /* rop */ + NVOBJ_CLASS(dev, 0x0012, GR); /* beta1 */ + NVOBJ_CLASS(dev, 0x0072, GR); /* beta4 */ + NVOBJ_CLASS(dev, 0x0019, GR); /* cliprect */ + NVOBJ_CLASS(dev, 0x0044, GR); /* pattern */ + NVOBJ_CLASS(dev, 0x009e, GR); /* swzsurf */ + NVOBJ_CLASS(dev, 0x0096, GR); /* celcius */ + + /* kelvin */ + if (dev_priv->chipset < 0x25) + NVOBJ_CLASS(dev, 0x0097, GR); + else + NVOBJ_CLASS(dev, 0x0597, GR); + + dev_priv->engine.graph.registered = true; + return 0; +} + +static int +nv30_graph_register(struct drm_device *dev) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + + if (dev_priv->engine.graph.registered) + return 0; + + NVOBJ_CLASS(dev, 0x506e, SW); /* nvsw */ + NVOBJ_CLASS(dev, 0x0030, GR); /* null */ + NVOBJ_CLASS(dev, 0x0039, GR); /* m2mf */ + NVOBJ_CLASS(dev, 0x004a, GR); /* gdirect */ + NVOBJ_CLASS(dev, 0x009f, GR); /* imageblit (nv12) */ + NVOBJ_CLASS(dev, 0x008a, GR); /* ifc */ + NVOBJ_CLASS(dev, 0x038a, GR); /* ifc (nv30) */ + NVOBJ_CLASS(dev, 0x0089, GR); /* sifm */ + NVOBJ_CLASS(dev, 0x0389, GR); /* sifm (nv30) */ + NVOBJ_CLASS(dev, 0x0062, GR); /* surf2d */ + NVOBJ_CLASS(dev, 0x0362, GR); /* surf2d (nv30) */ + NVOBJ_CLASS(dev, 0x0043, GR); /* rop */ + NVOBJ_CLASS(dev, 0x0012, GR); /* beta1 */ + NVOBJ_CLASS(dev, 0x0072, GR); /* beta4 */ + NVOBJ_CLASS(dev, 0x0019, GR); /* cliprect */ + NVOBJ_CLASS(dev, 0x0044, GR); /* pattern */ + NVOBJ_CLASS(dev, 0x039e, GR); /* swzsurf */ + + /* rankine */ + if (0x00000003 & (1 << (dev_priv->chipset & 0x0f))) + NVOBJ_CLASS(dev, 0x0397, GR); + else + if (0x00000010 & (1 << (dev_priv->chipset & 0x0f))) + NVOBJ_CLASS(dev, 0x0697, GR); + else + if (0x000001e0 & (1 << (dev_priv->chipset & 0x0f))) + NVOBJ_CLASS(dev, 0x0497, GR); + + dev_priv->engine.graph.registered = true; + return 0; +} diff --git a/drivers/gpu/drm/nouveau/nv40_graph.c b/drivers/gpu/drm/nouveau/nv40_graph.c index 70d957895cea..b9361e28687c 100644 --- a/drivers/gpu/drm/nouveau/nv40_graph.c +++ b/drivers/gpu/drm/nouveau/nv40_graph.c @@ -29,6 +29,8 @@ #include "nouveau_drv.h" #include "nouveau_grctx.h" +static int nv40_graph_register(struct drm_device *); + struct nouveau_channel * nv40_graph_channel(struct drm_device *dev) { @@ -248,7 +250,7 @@ nv40_graph_init(struct drm_device *dev) struct nouveau_fb_engine *pfb = &dev_priv->engine.fb; struct nouveau_grctx ctx = {}; uint32_t vramsz, *cp; - int i, j; + int ret, i, j; nv_wr32(dev, NV03_PMC_ENABLE, nv_rd32(dev, NV03_PMC_ENABLE) & ~NV_PMC_ENABLE_PGRAPH); @@ -272,6 +274,10 @@ nv40_graph_init(struct drm_device *dev) kfree(cp); + ret = nv40_graph_register(dev); + if (ret) + return ret; + /* No context present currently */ nv_wr32(dev, NV40_PGRAPH_CTXCTL_CUR, 0x00000000); @@ -408,25 +414,38 @@ void nv40_graph_takedown(struct drm_device *dev) { } -struct nouveau_pgraph_object_class nv40_graph_grclass[] = { - { 0x506e, NVOBJ_ENGINE_SW, NULL }, /* nvsw */ - { 0x0030, NVOBJ_ENGINE_GR, NULL }, /* null */ - { 0x0039, NVOBJ_ENGINE_GR, NULL }, /* m2mf */ - { 0x004a, NVOBJ_ENGINE_GR, NULL }, /* gdirect */ - { 0x009f, NVOBJ_ENGINE_GR, NULL }, /* imageblit (nv12) */ - { 0x008a, NVOBJ_ENGINE_GR, NULL }, /* ifc */ - { 0x0089, NVOBJ_ENGINE_GR, NULL }, /* sifm */ - { 0x3089, NVOBJ_ENGINE_GR, NULL }, /* sifm (nv40) */ - { 0x0062, NVOBJ_ENGINE_GR, NULL }, /* surf2d */ - { 0x3062, NVOBJ_ENGINE_GR, NULL }, /* surf2d (nv40) */ - { 0x0043, NVOBJ_ENGINE_GR, NULL }, /* rop */ - { 0x0012, NVOBJ_ENGINE_GR, NULL }, /* beta1 */ - { 0x0072, NVOBJ_ENGINE_GR, NULL }, /* beta4 */ - { 0x0019, NVOBJ_ENGINE_GR, NULL }, /* cliprect */ - { 0x0044, NVOBJ_ENGINE_GR, NULL }, /* pattern */ - { 0x309e, NVOBJ_ENGINE_GR, NULL }, /* swzsurf */ - { 0x4097, NVOBJ_ENGINE_GR, NULL }, /* curie (nv40) */ - { 0x4497, NVOBJ_ENGINE_GR, NULL }, /* curie (nv44) */ - {} -}; +static int +nv40_graph_register(struct drm_device *dev) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + + if (dev_priv->engine.graph.registered) + return 0; + NVOBJ_CLASS(dev, 0x506e, SW); /* nvsw */ + NVOBJ_CLASS(dev, 0x0030, GR); /* null */ + NVOBJ_CLASS(dev, 0x0039, GR); /* m2mf */ + NVOBJ_CLASS(dev, 0x004a, GR); /* gdirect */ + NVOBJ_CLASS(dev, 0x009f, GR); /* imageblit (nv12) */ + NVOBJ_CLASS(dev, 0x008a, GR); /* ifc */ + NVOBJ_CLASS(dev, 0x0089, GR); /* sifm */ + NVOBJ_CLASS(dev, 0x3089, GR); /* sifm (nv40) */ + NVOBJ_CLASS(dev, 0x0062, GR); /* surf2d */ + NVOBJ_CLASS(dev, 0x3062, GR); /* surf2d (nv40) */ + NVOBJ_CLASS(dev, 0x0043, GR); /* rop */ + NVOBJ_CLASS(dev, 0x0012, GR); /* beta1 */ + NVOBJ_CLASS(dev, 0x0072, GR); /* beta4 */ + NVOBJ_CLASS(dev, 0x0019, GR); /* cliprect */ + NVOBJ_CLASS(dev, 0x0044, GR); /* pattern */ + NVOBJ_CLASS(dev, 0x309e, GR); /* swzsurf */ + + /* curie */ + if (dev_priv->chipset >= 0x60 || + 0x00005450 & (1 << (dev_priv->chipset & 0x0f))) + NVOBJ_CLASS(dev, 0x4497, GR); + else + NVOBJ_CLASS(dev, 0x4097, GR); + + dev_priv->engine.graph.registered = true; + return 0; +} diff --git a/drivers/gpu/drm/nouveau/nv50_graph.c b/drivers/gpu/drm/nouveau/nv50_graph.c index 01a598917e3c..84ca90e91811 100644 --- a/drivers/gpu/drm/nouveau/nv50_graph.c +++ b/drivers/gpu/drm/nouveau/nv50_graph.c @@ -30,6 +30,8 @@ #include "nouveau_ramht.h" #include "nouveau_grctx.h" +static int nv50_graph_register(struct drm_device *); + static void nv50_graph_init_reset(struct drm_device *dev) { @@ -145,12 +147,15 @@ nv50_graph_init(struct drm_device *dev) nv50_graph_init_reset(dev); nv50_graph_init_regs__nv(dev); nv50_graph_init_regs(dev); - nv50_graph_init_intr(dev); ret = nv50_graph_init_ctxctl(dev); if (ret) return ret; + ret = nv50_graph_register(dev); + if (ret) + return ret; + nv50_graph_init_intr(dev); return 0; } @@ -333,8 +338,8 @@ nv50_graph_context_switch(struct drm_device *dev) } static int -nv50_graph_nvsw_dma_vblsem(struct nouveau_channel *chan, int grclass, - int mthd, uint32_t data) +nv50_graph_nvsw_dma_vblsem(struct nouveau_channel *chan, + u32 class, u32 mthd, u32 data) { struct nouveau_gpuobj *gpuobj; @@ -351,8 +356,8 @@ nv50_graph_nvsw_dma_vblsem(struct nouveau_channel *chan, int grclass, } static int -nv50_graph_nvsw_vblsem_offset(struct nouveau_channel *chan, int grclass, - int mthd, uint32_t data) +nv50_graph_nvsw_vblsem_offset(struct nouveau_channel *chan, + u32 class, u32 mthd, u32 data) { if (nouveau_notifier_offset(chan->nvsw.vblsem, &data)) return -ERANGE; @@ -362,16 +367,16 @@ nv50_graph_nvsw_vblsem_offset(struct nouveau_channel *chan, int grclass, } static int -nv50_graph_nvsw_vblsem_release_val(struct nouveau_channel *chan, int grclass, - int mthd, uint32_t data) +nv50_graph_nvsw_vblsem_release_val(struct nouveau_channel *chan, + u32 class, u32 mthd, u32 data) { chan->nvsw.vblsem_rval = data; return 0; } static int -nv50_graph_nvsw_vblsem_release(struct nouveau_channel *chan, int grclass, - int mthd, uint32_t data) +nv50_graph_nvsw_vblsem_release(struct nouveau_channel *chan, + u32 class, u32 mthd, u32 data) { struct drm_device *dev = chan->dev; struct drm_nouveau_private *dev_priv = dev->dev_private; @@ -392,27 +397,53 @@ nv50_graph_nvsw_vblsem_release(struct nouveau_channel *chan, int grclass, return 0; } -static struct nouveau_pgraph_object_method nv50_graph_nvsw_methods[] = { - { 0x018c, nv50_graph_nvsw_dma_vblsem }, - { 0x0400, nv50_graph_nvsw_vblsem_offset }, - { 0x0404, nv50_graph_nvsw_vblsem_release_val }, - { 0x0408, nv50_graph_nvsw_vblsem_release }, - {} -}; - -struct nouveau_pgraph_object_class nv50_graph_grclass[] = { - { 0x506e, NVOBJ_ENGINE_SW, nv50_graph_nvsw_methods }, /* nvsw */ - { 0x0030, NVOBJ_ENGINE_GR, NULL }, /* null */ - { 0x5039, NVOBJ_ENGINE_GR, NULL }, /* m2mf */ - { 0x502d, NVOBJ_ENGINE_GR, NULL }, /* 2d */ - { 0x50c0, NVOBJ_ENGINE_GR, NULL }, /* compute */ - { 0x85c0, NVOBJ_ENGINE_GR, NULL }, /* compute (nva3, nva5, nva8) */ - { 0x5097, NVOBJ_ENGINE_GR, NULL }, /* tesla (nv50) */ - { 0x8297, NVOBJ_ENGINE_GR, NULL }, /* tesla (nv8x/nv9x) */ - { 0x8397, NVOBJ_ENGINE_GR, NULL }, /* tesla (nva0, nvaa, nvac) */ - { 0x8597, NVOBJ_ENGINE_GR, NULL }, /* tesla (nva3, nva5, nva8) */ - {} -}; +static int +nv50_graph_register(struct drm_device *dev) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + + if (dev_priv->engine.graph.registered) + return 0; + + NVOBJ_CLASS(dev, 0x506e, SW); /* nvsw */ + NVOBJ_MTHD (dev, 0x506e, 0x018c, nv50_graph_nvsw_dma_vblsem); + NVOBJ_MTHD (dev, 0x506e, 0x0400, nv50_graph_nvsw_vblsem_offset); + NVOBJ_MTHD (dev, 0x506e, 0x0404, nv50_graph_nvsw_vblsem_release_val); + NVOBJ_MTHD (dev, 0x506e, 0x0408, nv50_graph_nvsw_vblsem_release); + + NVOBJ_CLASS(dev, 0x0030, GR); /* null */ + NVOBJ_CLASS(dev, 0x5039, GR); /* m2mf */ + NVOBJ_CLASS(dev, 0x502d, GR); /* 2d */ + NVOBJ_CLASS(dev, 0x50c0, GR); /* compute */ + NVOBJ_CLASS(dev, 0x85c0, GR); /* compute (nva3, nva5, nva8) */ + + /* tesla */ + if (dev_priv->chipset == 0x50) + NVOBJ_CLASS(dev, 0x5097, GR); /* tesla (nv50) */ + else + if (dev_priv->chipset < 0xa0) + NVOBJ_CLASS(dev, 0x8297, GR); /* tesla (nv8x/nv9x) */ + else { + switch (dev_priv->chipset) { + case 0xa0: + case 0xaa: + case 0xac: + NVOBJ_CLASS(dev, 0x8397, GR); + break; + case 0xa3: + case 0xa5: + case 0xa8: + NVOBJ_CLASS(dev, 0x8597, GR); + break; + case 0xaf: + NVOBJ_CLASS(dev, 0x8697, GR); + break; + } + } + + dev_priv->engine.graph.registered = true; + return 0; +} void nv50_graph_tlb_flush(struct drm_device *dev) -- cgit v1.2.3 From bd2e597de8dbd000a3977871f15cb81e2925d63e Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 19 Oct 2010 20:06:01 +1000 Subject: drm/nv84: add support for the PCRYPT engine Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/Makefile | 1 + drivers/gpu/drm/nouveau/nouveau_channel.c | 12 ++++ drivers/gpu/drm/nouveau/nouveau_drv.c | 1 + drivers/gpu/drm/nouveau/nouveau_drv.h | 24 +++++++ drivers/gpu/drm/nouveau/nouveau_irq.c | 16 +++++ drivers/gpu/drm/nouveau/nouveau_object.c | 3 +- drivers/gpu/drm/nouveau/nouveau_state.c | 62 ++++++++++++++--- drivers/gpu/drm/nouveau/nv84_crypt.c | 110 ++++++++++++++++++++++++++++++ 8 files changed, 218 insertions(+), 11 deletions(-) create mode 100644 drivers/gpu/drm/nouveau/nv84_crypt.c diff --git a/drivers/gpu/drm/nouveau/Makefile b/drivers/gpu/drm/nouveau/Makefile index 23fa82d667d6..a541f5bff75d 100644 --- a/drivers/gpu/drm/nouveau/Makefile +++ b/drivers/gpu/drm/nouveau/Makefile @@ -18,6 +18,7 @@ nouveau-y := nouveau_drv.o nouveau_state.o nouveau_channel.o nouveau_mem.o \ nv04_graph.o nv10_graph.o nv20_graph.o \ nv40_graph.o nv50_graph.o nvc0_graph.o \ nv40_grctx.o nv50_grctx.o \ + nv84_crypt.o \ nv04_instmem.o nv50_instmem.o nvc0_instmem.o \ nv50_crtc.o nv50_dac.o nv50_sor.o \ nv50_cursor.o nv50_display.o nv50_fbcon.o \ diff --git a/drivers/gpu/drm/nouveau/nouveau_channel.c b/drivers/gpu/drm/nouveau/nouveau_channel.c index 76033c509d35..8f2df6beb893 100644 --- a/drivers/gpu/drm/nouveau/nouveau_channel.c +++ b/drivers/gpu/drm/nouveau/nouveau_channel.c @@ -112,6 +112,7 @@ nouveau_channel_alloc(struct drm_device *dev, struct nouveau_channel **chan_ret, struct drm_nouveau_private *dev_priv = dev->dev_private; struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo; + struct nouveau_crypt_engine *pcrypt = &dev_priv->engine.crypt; struct nouveau_channel *chan; unsigned long flags; int user, ret; @@ -214,6 +215,14 @@ nouveau_channel_alloc(struct drm_device *dev, struct nouveau_channel **chan_ret, return ret; } + if (pcrypt->create_context) { + ret = pcrypt->create_context(chan); + if (ret) { + nouveau_channel_put(&chan); + return ret; + } + } + /* Construct inital RAMFC for new channel */ ret = pfifo->create_context(chan); if (ret) { @@ -280,6 +289,7 @@ nouveau_channel_put_unlocked(struct nouveau_channel **pchan) struct drm_nouveau_private *dev_priv = dev->dev_private; struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo; struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; + struct nouveau_crypt_engine *pcrypt = &dev_priv->engine.crypt; unsigned long flags; int ret; @@ -328,6 +338,8 @@ nouveau_channel_put_unlocked(struct nouveau_channel **pchan) /* destroy the engine specific contexts */ pfifo->destroy_context(chan); pgraph->destroy_context(chan); + if (pcrypt->destroy_context) + pcrypt->destroy_context(chan); pfifo->reassign(dev, true); diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.c b/drivers/gpu/drm/nouveau/nouveau_drv.c index f139aa2cbe5c..6dbb8818c530 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.c +++ b/drivers/gpu/drm/nouveau/nouveau_drv.c @@ -299,6 +299,7 @@ nouveau_pci_resume(struct pci_dev *pdev) engine->timer.init(dev); engine->fb.init(dev); engine->graph.init(dev); + engine->crypt.init(dev); engine->fifo.init(dev); NV_INFO(dev, "Restoring GPU objects...\n"); diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index 3fb87995446b..d15bfd427267 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -132,6 +132,11 @@ enum nouveau_flags { #define NVOBJ_ENGINE_SW 0 #define NVOBJ_ENGINE_GR 1 +#define NVOBJ_ENGINE_PPP 2 +#define NVOBJ_ENGINE_COPY 3 +#define NVOBJ_ENGINE_VP 4 +#define NVOBJ_ENGINE_CRYPT 5 +#define NVOBJ_ENGINE_BSP 6 #define NVOBJ_ENGINE_DISPLAY 0xcafe0001 #define NVOBJ_ENGINE_INT 0xdeadbeef @@ -208,6 +213,7 @@ struct nouveau_channel { /* PGRAPH context */ /* XXX may be merge 2 pointers as private data ??? */ struct nouveau_gpuobj *ramin_grctx; + struct nouveau_gpuobj *crypt_ctx; void *pgraph_ctx; /* NV50 VM */ @@ -444,6 +450,16 @@ struct nouveau_pm_engine { int (*temp_get)(struct drm_device *); }; +struct nouveau_crypt_engine { + bool registered; + + int (*init)(struct drm_device *); + void (*takedown)(struct drm_device *); + int (*create_context)(struct nouveau_channel *); + void (*destroy_context)(struct nouveau_channel *); + void (*tlb_flush)(struct drm_device *dev); +}; + struct nouveau_engine { struct nouveau_instmem_engine instmem; struct nouveau_mc_engine mc; @@ -454,6 +470,7 @@ struct nouveau_engine { struct nouveau_display_engine display; struct nouveau_gpio_engine gpio; struct nouveau_pm_engine pm; + struct nouveau_crypt_engine crypt; }; struct nouveau_pll_vals { @@ -1113,6 +1130,13 @@ extern void nvc0_graph_destroy_context(struct nouveau_channel *); extern int nvc0_graph_load_context(struct nouveau_channel *); extern int nvc0_graph_unload_context(struct drm_device *); +/* nv84_crypt.c */ +extern int nv84_crypt_init(struct drm_device *dev); +extern void nv84_crypt_fini(struct drm_device *dev); +extern int nv84_crypt_create_context(struct nouveau_channel *); +extern void nv84_crypt_destroy_context(struct nouveau_channel *); +extern void nv84_crypt_tlb_flush(struct drm_device *dev); + /* nv04_instmem.c */ extern int nv04_instmem_init(struct drm_device *); extern void nv04_instmem_takedown(struct drm_device *); diff --git a/drivers/gpu/drm/nouveau/nouveau_irq.c b/drivers/gpu/drm/nouveau/nouveau_irq.c index f09151d17297..ca9b969f4f9c 100644 --- a/drivers/gpu/drm/nouveau/nouveau_irq.c +++ b/drivers/gpu/drm/nouveau/nouveau_irq.c @@ -1230,6 +1230,22 @@ nouveau_irq_handler(DRM_IRQ_ARGS) status &= ~NV_PMC_INTR_0_PGRAPH_PENDING; } + if (status & 0x00004000) { + u32 stat = nv_rd32(dev, 0x102130); + u32 mthd = nv_rd32(dev, 0x102190); + u32 data = nv_rd32(dev, 0x102194); + u32 inst = nv_rd32(dev, 0x102188) & 0x7fffffff; + + NV_INFO(dev, "PCRYPT_INTR: 0x%08x 0x%08x 0x%08x 0x%08x\n", + stat, mthd, data, inst); + nv_wr32(dev, 0x102130, stat); + nv_wr32(dev, 0x10200c, 0x10); + + nv50_fb_vm_trap(dev, nouveau_ratelimit(), "PCRYPT"); + status &= ~0x00004000; + + } + if (status & NV_PMC_INTR_0_CRTCn_PENDING) { nouveau_crtc_irq_handler(dev, (status>>24)&3); status &= ~NV_PMC_INTR_0_CRTCn_PENDING; diff --git a/drivers/gpu/drm/nouveau/nouveau_object.c b/drivers/gpu/drm/nouveau/nouveau_object.c index 6226beb3613d..ee526534c6f4 100644 --- a/drivers/gpu/drm/nouveau/nouveau_object.c +++ b/drivers/gpu/drm/nouveau/nouveau_object.c @@ -272,6 +272,7 @@ nouveau_gpuobj_init(struct drm_device *dev) NV_DEBUG(dev, "\n"); INIT_LIST_HEAD(&dev_priv->gpuobj_list); + INIT_LIST_HEAD(&dev_priv->classes); spin_lock_init(&dev_priv->ramin_lock); dev_priv->ramin_base = ~0; @@ -686,7 +687,7 @@ nouveau_gpuobj_channel_init_pramin(struct nouveau_channel *chan) NV_DEBUG(dev, "ch%d\n", chan->id); /* Base amount for object storage (4KiB enough?) */ - size = 0x1000; + size = 0x2000; base = 0; /* PGRAPH context */ diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c index be28754ffd50..f13134aa8c4f 100644 --- a/drivers/gpu/drm/nouveau/nouveau_state.c +++ b/drivers/gpu/drm/nouveau/nouveau_state.c @@ -98,6 +98,8 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->pm.clock_get = nv04_pm_clock_get; engine->pm.clock_pre = nv04_pm_clock_pre; engine->pm.clock_set = nv04_pm_clock_set; + engine->crypt.init = nouveau_stub_init; + engine->crypt.takedown = nouveau_stub_takedown; break; case 0x10: engine->instmem.init = nv04_instmem_init; @@ -151,6 +153,8 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->pm.clock_get = nv04_pm_clock_get; engine->pm.clock_pre = nv04_pm_clock_pre; engine->pm.clock_set = nv04_pm_clock_set; + engine->crypt.init = nouveau_stub_init; + engine->crypt.takedown = nouveau_stub_takedown; break; case 0x20: engine->instmem.init = nv04_instmem_init; @@ -204,6 +208,8 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->pm.clock_get = nv04_pm_clock_get; engine->pm.clock_pre = nv04_pm_clock_pre; engine->pm.clock_set = nv04_pm_clock_set; + engine->crypt.init = nouveau_stub_init; + engine->crypt.takedown = nouveau_stub_takedown; break; case 0x30: engine->instmem.init = nv04_instmem_init; @@ -259,6 +265,8 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->pm.clock_set = nv04_pm_clock_set; engine->pm.voltage_get = nouveau_voltage_gpio_get; engine->pm.voltage_set = nouveau_voltage_gpio_set; + engine->crypt.init = nouveau_stub_init; + engine->crypt.takedown = nouveau_stub_takedown; break; case 0x40: case 0x60: @@ -316,6 +324,8 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->pm.voltage_get = nouveau_voltage_gpio_get; engine->pm.voltage_set = nouveau_voltage_gpio_set; engine->pm.temp_get = nv40_temp_get; + engine->crypt.init = nouveau_stub_init; + engine->crypt.takedown = nouveau_stub_takedown; break; case 0x50: case 0x80: /* gotta love NVIDIA's consistency.. */ @@ -380,19 +390,23 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->gpio.set = nv50_gpio_set; engine->gpio.irq_enable = nv50_gpio_irq_enable; switch (dev_priv->chipset) { - case 0xa3: - case 0xa5: - case 0xa8: - case 0xaf: - engine->pm.clock_get = nva3_pm_clock_get; - engine->pm.clock_pre = nva3_pm_clock_pre; - engine->pm.clock_set = nva3_pm_clock_set; - break; - default: + case 0x84: + case 0x86: + case 0x92: + case 0x94: + case 0x96: + case 0x98: + case 0xa0: + case 0x50: engine->pm.clock_get = nv50_pm_clock_get; engine->pm.clock_pre = nv50_pm_clock_pre; engine->pm.clock_set = nv50_pm_clock_set; break; + default: + engine->pm.clock_get = nva3_pm_clock_get; + engine->pm.clock_pre = nva3_pm_clock_pre; + engine->pm.clock_set = nva3_pm_clock_set; + break; } engine->pm.voltage_get = nouveau_voltage_gpio_get; engine->pm.voltage_set = nouveau_voltage_gpio_set; @@ -400,6 +414,23 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->pm.temp_get = nv84_temp_get; else engine->pm.temp_get = nv40_temp_get; + switch (dev_priv->chipset) { + case 0x84: + case 0x86: + case 0x92: + case 0x94: + case 0x96: + case 0xa0: + engine->crypt.init = nv84_crypt_init; + engine->crypt.takedown = nv84_crypt_fini; + engine->crypt.create_context = nv84_crypt_create_context; + engine->crypt.destroy_context = nv84_crypt_destroy_context; + break; + default: + engine->crypt.init = nouveau_stub_init; + engine->crypt.takedown = nouveau_stub_takedown; + break; + } break; case 0xC0: engine->instmem.init = nvc0_instmem_init; @@ -447,6 +478,8 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->gpio.get = nv50_gpio_get; engine->gpio.set = nv50_gpio_set; engine->gpio.irq_enable = nv50_gpio_irq_enable; + engine->crypt.init = nouveau_stub_init; + engine->crypt.takedown = nouveau_stub_takedown; break; default: NV_ERROR(dev, "NV%02x unsupported\n", dev_priv->chipset); @@ -619,10 +652,15 @@ nouveau_card_init(struct drm_device *dev) if (ret) goto out_fb; + /* PCRYPT */ + ret = engine->crypt.init(dev); + if (ret) + goto out_graph; + /* PFIFO */ ret = engine->fifo.init(dev); if (ret) - goto out_graph; + goto out_crypt; } ret = engine->display.create(dev); @@ -669,6 +707,9 @@ out_display: out_fifo: if (!nouveau_noaccel) engine->fifo.takedown(dev); +out_crypt: + if (!nouveau_noaccel) + engine->crypt.takedown(dev); out_graph: if (!nouveau_noaccel) engine->graph.takedown(dev); @@ -712,6 +753,7 @@ static void nouveau_card_takedown(struct drm_device *dev) if (!nouveau_noaccel) { engine->fifo.takedown(dev); + engine->crypt.takedown(dev); engine->graph.takedown(dev); } engine->fb.takedown(dev); diff --git a/drivers/gpu/drm/nouveau/nv84_crypt.c b/drivers/gpu/drm/nouveau/nv84_crypt.c new file mode 100644 index 000000000000..63bd6bb41e38 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nv84_crypt.c @@ -0,0 +1,110 @@ +/* + * Copyright 2010 Red Hat Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: Ben Skeggs + */ + +#include "drmP.h" +#include "nouveau_drv.h" + +int +nv84_crypt_create_context(struct nouveau_channel *chan) +{ + struct drm_device *dev = chan->dev; + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_gpuobj *ramin = chan->ramin; + int ret; + + NV_DEBUG(dev, "ch%d\n", chan->id); + + ret = nouveau_gpuobj_new(dev, chan, 256, 0x1000, + NVOBJ_FLAG_ZERO_ALLOC | NVOBJ_FLAG_ZERO_FREE, + &chan->crypt_ctx); + if (ret) + return ret; + + nv_wo32(ramin, 0xa0, 0x00190000); + nv_wo32(ramin, 0xa4, chan->crypt_ctx->vinst + 0xff); + nv_wo32(ramin, 0xa8, chan->crypt_ctx->vinst); + nv_wo32(ramin, 0xac, 0); + nv_wo32(ramin, 0xb0, 0); + nv_wo32(ramin, 0xb4, 0); + + dev_priv->engine.instmem.flush(dev); + return 0; +} + +void +nv84_crypt_destroy_context(struct nouveau_channel *chan) +{ + struct drm_device *dev = chan->dev; + u32 inst; + + if (!chan->ramin) + return; + + inst = (chan->ramin->vinst >> 12); + inst |= 0x80000000; + + /* mark context as invalid if still on the hardware, not + * doing this causes issues the next time PCRYPT is used, + * unsurprisingly :) + */ + nv_wr32(dev, 0x10200c, 0x00000000); + if (nv_rd32(dev, 0x102188) == inst) + nv_mask(dev, 0x102188, 0x80000000, 0x00000000); + if (nv_rd32(dev, 0x10218c) == inst) + nv_mask(dev, 0x10218c, 0x80000000, 0x00000000); + nv_wr32(dev, 0x10200c, 0x00000010); + + nouveau_gpuobj_ref(NULL, &chan->crypt_ctx); +} + +void +nv84_crypt_tlb_flush(struct drm_device *dev) +{ + nv50_vm_flush(dev, 0x0a); +} + +int +nv84_crypt_init(struct drm_device *dev) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_crypt_engine *pcrypt = &dev_priv->engine.crypt; + + if (!pcrypt->registered) { + NVOBJ_CLASS(dev, 0x74c1, CRYPT); + pcrypt->registered = true; + } + + nv_mask(dev, 0x000200, 0x00004000, 0x00000000); + nv_mask(dev, 0x000200, 0x00004000, 0x00004000); + nv_wr32(dev, 0x102130, 0xffffffff); + nv_wr32(dev, 0x102140, 0xffffffbf); + nv_wr32(dev, 0x10200c, 0x00000010); + return 0; +} + +void +nv84_crypt_fini(struct drm_device *dev) +{ + nv_wr32(dev, 0x102140, 0x00000000); +} -- cgit v1.2.3 From 3052be2cea64371300a0338d3ca5d3575fbd109c Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 20 Oct 2010 11:46:38 +1000 Subject: drm/nv50: remove excessive alignment of graph/crypt contexts Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nv50_graph.c | 2 +- drivers/gpu/drm/nouveau/nv84_crypt.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nv50_graph.c b/drivers/gpu/drm/nouveau/nv50_graph.c index 84ca90e91811..a764af52a3ba 100644 --- a/drivers/gpu/drm/nouveau/nv50_graph.c +++ b/drivers/gpu/drm/nouveau/nv50_graph.c @@ -216,7 +216,7 @@ nv50_graph_create_context(struct nouveau_channel *chan) NV_DEBUG(dev, "ch%d\n", chan->id); - ret = nouveau_gpuobj_new(dev, chan, pgraph->grctx_size, 0x1000, + ret = nouveau_gpuobj_new(dev, chan, pgraph->grctx_size, 0, NVOBJ_FLAG_ZERO_ALLOC | NVOBJ_FLAG_ZERO_FREE, &chan->ramin_grctx); if (ret) diff --git a/drivers/gpu/drm/nouveau/nv84_crypt.c b/drivers/gpu/drm/nouveau/nv84_crypt.c index 63bd6bb41e38..f988b1a9d1d7 100644 --- a/drivers/gpu/drm/nouveau/nv84_crypt.c +++ b/drivers/gpu/drm/nouveau/nv84_crypt.c @@ -35,7 +35,7 @@ nv84_crypt_create_context(struct nouveau_channel *chan) NV_DEBUG(dev, "ch%d\n", chan->id); - ret = nouveau_gpuobj_new(dev, chan, 256, 0x1000, + ret = nouveau_gpuobj_new(dev, chan, 256, 0, NVOBJ_FLAG_ZERO_ALLOC | NVOBJ_FLAG_ZERO_FREE, &chan->crypt_ctx); if (ret) -- cgit v1.2.3 From f4512e6579ddaa9b1f8ab1d5659131243ffc421f Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 20 Oct 2010 11:47:09 +1000 Subject: drm/nv50: create graph and crypt contexts on demand This really needs cleaning up somehow, and probably investigate what's needed to do this on earlier generations. NVIDIA do something similar there too. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_channel.c | 11 ++--------- drivers/gpu/drm/nouveau/nouveau_object.c | 23 +++++++++++++++++++++++ 2 files changed, 25 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_channel.c b/drivers/gpu/drm/nouveau/nouveau_channel.c index 8f2df6beb893..f2d674202369 100644 --- a/drivers/gpu/drm/nouveau/nouveau_channel.c +++ b/drivers/gpu/drm/nouveau/nouveau_channel.c @@ -112,7 +112,6 @@ nouveau_channel_alloc(struct drm_device *dev, struct nouveau_channel **chan_ret, struct drm_nouveau_private *dev_priv = dev->dev_private; struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo; - struct nouveau_crypt_engine *pcrypt = &dev_priv->engine.crypt; struct nouveau_channel *chan; unsigned long flags; int user, ret; @@ -209,14 +208,8 @@ nouveau_channel_alloc(struct drm_device *dev, struct nouveau_channel **chan_ret, pfifo->reassign(dev, false); /* Create a graphics context for new channel */ - ret = pgraph->create_context(chan); - if (ret) { - nouveau_channel_put(&chan); - return ret; - } - - if (pcrypt->create_context) { - ret = pcrypt->create_context(chan); + if (dev_priv->card_type < NV_50) { + ret = pgraph->create_context(chan); if (ret) { nouveau_channel_put(&chan); return ret; diff --git a/drivers/gpu/drm/nouveau/nouveau_object.c b/drivers/gpu/drm/nouveau/nouveau_object.c index ee526534c6f4..54078186fe65 100644 --- a/drivers/gpu/drm/nouveau/nouveau_object.c +++ b/drivers/gpu/drm/nouveau/nouveau_object.c @@ -634,6 +634,29 @@ found: if (oc->engine == NVOBJ_ENGINE_SW) return nouveau_gpuobj_sw_new(chan, class, gpuobj); + switch (oc->engine) { + case NVOBJ_ENGINE_GR: + if (dev_priv->card_type >= NV_50 && !chan->ramin_grctx) { + struct nouveau_pgraph_engine *pgraph = + &dev_priv->engine.graph; + + ret = pgraph->create_context(chan); + if (ret) + return ret; + } + break; + case NVOBJ_ENGINE_CRYPT: + if (!chan->crypt_ctx) { + struct nouveau_crypt_engine *pcrypt = + &dev_priv->engine.crypt; + + ret = pcrypt->create_context(chan); + if (ret) + return ret; + } + break; + } + ret = nouveau_gpuobj_new(dev, chan, nouveau_gpuobj_class_instmem_size(dev, class), 16, -- cgit v1.2.3 From 106ddad5aa8e8e03503cea05f9a64611f849952f Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 19 Oct 2010 11:14:17 +1000 Subject: drm/nv50: clearer separation of the stages of evo init Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_reg.h | 14 ++--- drivers/gpu/drm/nouveau/nv50_display.c | 93 ++++++++++++++++++---------------- 2 files changed, 55 insertions(+), 52 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_reg.h b/drivers/gpu/drm/nouveau/nouveau_reg.h index 1bbe7037cf99..5e28bc63c41e 100644 --- a/drivers/gpu/drm/nouveau/nouveau_reg.h +++ b/drivers/gpu/drm/nouveau/nouveau_reg.h @@ -747,15 +747,11 @@ #define NV50_PDISPLAY_CURSOR_CURSOR_CTRL2_STATUS 0x00030000 #define NV50_PDISPLAY_CURSOR_CURSOR_CTRL2_STATUS_ACTIVE 0x00010000 -#define NV50_PDISPLAY_CTRL_STATE 0x00610300 -#define NV50_PDISPLAY_CTRL_STATE_PENDING 0x80000000 -#define NV50_PDISPLAY_CTRL_STATE_METHOD 0x00001ffc -#define NV50_PDISPLAY_CTRL_STATE_ENABLE 0x00000001 -#define NV50_PDISPLAY_CTRL_VAL 0x00610304 -#define NV50_PDISPLAY_UNK_380 0x00610380 -#define NV50_PDISPLAY_RAM_AMOUNT 0x00610384 -#define NV50_PDISPLAY_UNK_388 0x00610388 -#define NV50_PDISPLAY_UNK_38C 0x0061038c +#define NV50_PDISPLAY_PIO_CTRL 0x00610300 +#define NV50_PDISPLAY_PIO_CTRL_PENDING 0x80000000 +#define NV50_PDISPLAY_PIO_CTRL_MTHD 0x00001ffc +#define NV50_PDISPLAY_PIO_CTRL_ENABLED 0x00000001 +#define NV50_PDISPLAY_PIO_DATA 0x00610304 #define NV50_PDISPLAY_CRTC_P(i, r) ((i) * 0x540 + NV50_PDISPLAY_CRTC_##r) #define NV50_PDISPLAY_CRTC_C(i, r) (4 + (i) * 0x540 + NV50_PDISPLAY_CRTC_##r) diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c index 7ac87efb791f..7c9c7c5bf22a 100644 --- a/drivers/gpu/drm/nouveau/nv50_display.c +++ b/drivers/gpu/drm/nouveau/nv50_display.c @@ -225,6 +225,7 @@ nv50_display_init(struct drm_device *dev) NV_DEBUG_KMS(dev, "\n"); nv_wr32(dev, 0x00610184, nv_rd32(dev, 0x00614004)); + /* * I think the 0x006101XX range is some kind of main control area * that enables things. @@ -240,16 +241,19 @@ nv50_display_init(struct drm_device *dev) val = nv_rd32(dev, 0x0061610c + (i * 0x800)); nv_wr32(dev, 0x0061019c + (i * 0x10), val); } + /* DAC */ for (i = 0; i < 3; i++) { val = nv_rd32(dev, 0x0061a000 + (i * 0x800)); nv_wr32(dev, 0x006101d0 + (i * 0x04), val); } + /* SOR */ for (i = 0; i < nv50_sor_nr(dev); i++) { val = nv_rd32(dev, 0x0061c000 + (i * 0x800)); nv_wr32(dev, 0x006101e0 + (i * 0x04), val); } + /* EXT */ for (i = 0; i < 3; i++) { val = nv_rd32(dev, 0x0061e000 + (i * 0x800)); @@ -276,6 +280,49 @@ nv50_display_init(struct drm_device *dev) } } + for (i = 0; i < 2; i++) { + nv_wr32(dev, NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(i), 0x2000); + if (!nv_wait(dev, NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(i), + NV50_PDISPLAY_CURSOR_CURSOR_CTRL2_STATUS, 0)) { + NV_ERROR(dev, "timeout: CURSOR_CTRL2_STATUS == 0\n"); + NV_ERROR(dev, "CURSOR_CTRL2 = 0x%08x\n", + nv_rd32(dev, NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(i))); + return -EBUSY; + } + + nv_wr32(dev, NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(i), + NV50_PDISPLAY_CURSOR_CURSOR_CTRL2_ON); + if (!nv_wait(dev, NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(i), + NV50_PDISPLAY_CURSOR_CURSOR_CTRL2_STATUS, + NV50_PDISPLAY_CURSOR_CURSOR_CTRL2_STATUS_ACTIVE)) { + NV_ERROR(dev, "timeout: " + "CURSOR_CTRL2_STATUS_ACTIVE(%d)\n", i); + NV_ERROR(dev, "CURSOR_CTRL2(%d) = 0x%08x\n", i, + nv_rd32(dev, NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(i))); + return -EBUSY; + } + } + + nv_wr32(dev, NV50_PDISPLAY_OBJECTS, (evo->ramin->vinst >> 8) | 9); + nv_wr32(dev, NV50_PDISPLAY_PIO_CTRL, 0x00000000); + nv_wr32(dev, 0x610028, 0x00000000); + nv_mask(dev, NV50_PDISPLAY_INTR_0, 0x00000000, 0x00000000); + nv_mask(dev, NV50_PDISPLAY_INTR_1, 0x00000000, 0x00000000); + nv_wr32(dev, NV50_PDISPLAY_INTR_EN, + NV50_PDISPLAY_INTR_EN_CLK_UNK10 | + NV50_PDISPLAY_INTR_EN_CLK_UNK20 | + NV50_PDISPLAY_INTR_EN_CLK_UNK40); + + /* enable hotplug interrupts */ + list_for_each_entry(connector, &dev->mode_config.connector_list, head) { + struct nouveau_connector *conn = nouveau_connector(connector); + + if (conn->dcb->gpio_tag == 0xff) + continue; + + pgpio->irq_enable(dev, conn->dcb->gpio_tag, true); + } + /* taken from nv bug #12637, attempts to un-wedge the hw if it's * stuck in some unspecified state */ @@ -297,7 +344,6 @@ nv50_display_init(struct drm_device *dev) } } - nv_wr32(dev, NV50_PDISPLAY_CTRL_STATE, NV50_PDISPLAY_CTRL_STATE_ENABLE); nv_wr32(dev, NV50_PDISPLAY_CHANNEL_STAT(0), 0x1000b03); if (!nv_wait(dev, NV50_PDISPLAY_CHANNEL_STAT(0), 0x40000000, 0x40000000)) { @@ -307,31 +353,6 @@ nv50_display_init(struct drm_device *dev) return -EBUSY; } - for (i = 0; i < 2; i++) { - nv_wr32(dev, NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(i), 0x2000); - if (!nv_wait(dev, NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(i), - NV50_PDISPLAY_CURSOR_CURSOR_CTRL2_STATUS, 0)) { - NV_ERROR(dev, "timeout: CURSOR_CTRL2_STATUS == 0\n"); - NV_ERROR(dev, "CURSOR_CTRL2 = 0x%08x\n", - nv_rd32(dev, NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(i))); - return -EBUSY; - } - - nv_wr32(dev, NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(i), - NV50_PDISPLAY_CURSOR_CURSOR_CTRL2_ON); - if (!nv_wait(dev, NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(i), - NV50_PDISPLAY_CURSOR_CURSOR_CTRL2_STATUS, - NV50_PDISPLAY_CURSOR_CURSOR_CTRL2_STATUS_ACTIVE)) { - NV_ERROR(dev, "timeout: " - "CURSOR_CTRL2_STATUS_ACTIVE(%d)\n", i); - NV_ERROR(dev, "CURSOR_CTRL2(%d) = 0x%08x\n", i, - nv_rd32(dev, NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(i))); - return -EBUSY; - } - } - - nv_wr32(dev, NV50_PDISPLAY_OBJECTS, (evo->ramin->vinst >> 8) | 9); - /* initialise fifo */ nv_wr32(dev, NV50_PDISPLAY_CHANNEL_DMA_CB(0), ((evo->pushbuf_bo->bo.mem.start << PAGE_SHIFT) >> 8) | @@ -350,7 +371,9 @@ nv50_display_init(struct drm_device *dev) nv_wr32(dev, NV50_PDISPLAY_USER_PUT(0), 0); nv_wr32(dev, NV50_PDISPLAY_CHANNEL_STAT(0), 0x01000003 | NV50_PDISPLAY_CHANNEL_STAT_DMA_ENABLED); - nv_wr32(dev, 0x610300, nv_rd32(dev, 0x610300) & ~1); + + /* enable error reporting on the channel */ + nv_mask(dev, 0x610028, 0x00000000, 0x00010001 << 0); evo->dma.max = (4096/4) - 2; evo->dma.put = 0; @@ -382,21 +405,6 @@ nv50_display_init(struct drm_device *dev) if (!nv_wait(dev, 0x640004, 0xffffffff, evo->dma.put << 2)) NV_ERROR(dev, "evo pushbuf stalled\n"); - /* enable clock change interrupts. */ - nv_wr32(dev, 0x610028, 0x00010001); - nv_wr32(dev, NV50_PDISPLAY_INTR_EN, (NV50_PDISPLAY_INTR_EN_CLK_UNK10 | - NV50_PDISPLAY_INTR_EN_CLK_UNK20 | - NV50_PDISPLAY_INTR_EN_CLK_UNK40)); - - /* enable hotplug interrupts */ - list_for_each_entry(connector, &dev->mode_config.connector_list, head) { - struct nouveau_connector *conn = nouveau_connector(connector); - - if (conn->dcb->gpio_tag == 0xff) - continue; - - pgpio->irq_enable(dev, conn->dcb->gpio_tag, true); - } return 0; } @@ -442,7 +450,6 @@ static int nv50_display_disable(struct drm_device *dev) } nv_wr32(dev, NV50_PDISPLAY_CHANNEL_STAT(0), 0); - nv_wr32(dev, NV50_PDISPLAY_CTRL_STATE, 0); if (!nv_wait(dev, NV50_PDISPLAY_CHANNEL_STAT(0), 0x1e0000, 0)) { NV_ERROR(dev, "timeout: (0x610200 & 0x1e0000) == 0\n"); NV_ERROR(dev, "0x610200 = 0x%08x\n", -- cgit v1.2.3 From b7bc613a4cc08d867b43189c2af0bb83b1fa1dc6 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 19 Oct 2010 13:05:51 +1000 Subject: drm/nv50: move evo handling to nv50_evo.c Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/Makefile | 2 +- drivers/gpu/drm/nouveau/nouveau_reg.h | 22 +-- drivers/gpu/drm/nouveau/nv50_display.c | 238 +------------------------- drivers/gpu/drm/nouveau/nv50_evo.c | 295 +++++++++++++++++++++++++++++++++ drivers/gpu/drm/nouveau/nv50_evo.h | 10 ++ 5 files changed, 322 insertions(+), 245 deletions(-) create mode 100644 drivers/gpu/drm/nouveau/nv50_evo.c diff --git a/drivers/gpu/drm/nouveau/Makefile b/drivers/gpu/drm/nouveau/Makefile index a541f5bff75d..c8c8de0bbc77 100644 --- a/drivers/gpu/drm/nouveau/Makefile +++ b/drivers/gpu/drm/nouveau/Makefile @@ -20,7 +20,7 @@ nouveau-y := nouveau_drv.o nouveau_state.o nouveau_channel.o nouveau_mem.o \ nv40_grctx.o nv50_grctx.o \ nv84_crypt.o \ nv04_instmem.o nv50_instmem.o nvc0_instmem.o \ - nv50_crtc.o nv50_dac.o nv50_sor.o \ + nv50_evo.o nv50_crtc.o nv50_dac.o nv50_sor.o \ nv50_cursor.o nv50_display.o nv50_fbcon.o \ nv04_dac.o nv04_dfp.o nv04_tv.o nv17_tv.o nv17_tv_modes.o \ nv04_crtc.o nv04_display.o nv04_cursor.o nv04_fbcon.o \ diff --git a/drivers/gpu/drm/nouveau/nouveau_reg.h b/drivers/gpu/drm/nouveau/nouveau_reg.h index 5e28bc63c41e..d0ce86c24ebf 100644 --- a/drivers/gpu/drm/nouveau/nouveau_reg.h +++ b/drivers/gpu/drm/nouveau/nouveau_reg.h @@ -729,17 +729,17 @@ #define NV50_PDISPLAY_UNK30_CTRL_PENDING 0x80000000 #define NV50_PDISPLAY_TRAPPED_ADDR 0x00610080 #define NV50_PDISPLAY_TRAPPED_DATA 0x00610084 -#define NV50_PDISPLAY_CHANNEL_STAT(i) ((i) * 0x10 + 0x00610200) -#define NV50_PDISPLAY_CHANNEL_STAT_DMA 0x00000010 -#define NV50_PDISPLAY_CHANNEL_STAT_DMA_DISABLED 0x00000000 -#define NV50_PDISPLAY_CHANNEL_STAT_DMA_ENABLED 0x00000010 -#define NV50_PDISPLAY_CHANNEL_DMA_CB(i) ((i) * 0x10 + 0x00610204) -#define NV50_PDISPLAY_CHANNEL_DMA_CB_LOCATION 0x00000002 -#define NV50_PDISPLAY_CHANNEL_DMA_CB_LOCATION_VRAM 0x00000000 -#define NV50_PDISPLAY_CHANNEL_DMA_CB_LOCATION_SYSTEM 0x00000002 -#define NV50_PDISPLAY_CHANNEL_DMA_CB_VALID 0x00000001 -#define NV50_PDISPLAY_CHANNEL_UNK2(i) ((i) * 0x10 + 0x00610208) -#define NV50_PDISPLAY_CHANNEL_UNK3(i) ((i) * 0x10 + 0x0061020c) +#define NV50_PDISPLAY_EVO_CTRL(i) ((i) * 0x10 + 0x00610200) +#define NV50_PDISPLAY_EVO_CTRL_DMA 0x00000010 +#define NV50_PDISPLAY_EVO_CTRL_DMA_DISABLED 0x00000000 +#define NV50_PDISPLAY_EVO_CTRL_DMA_ENABLED 0x00000010 +#define NV50_PDISPLAY_EVO_DMA_CB(i) ((i) * 0x10 + 0x00610204) +#define NV50_PDISPLAY_EVO_DMA_CB_LOCATION 0x00000002 +#define NV50_PDISPLAY_EVO_DMA_CB_LOCATION_VRAM 0x00000000 +#define NV50_PDISPLAY_EVO_DMA_CB_LOCATION_SYSTEM 0x00000002 +#define NV50_PDISPLAY_EVO_DMA_CB_VALID 0x00000001 +#define NV50_PDISPLAY_EVO_UNK2(i) ((i) * 0x10 + 0x00610208) +#define NV50_PDISPLAY_EVO_HASH_TAG(i) ((i) * 0x10 + 0x0061020c) #define NV50_PDISPLAY_CURSOR 0x00610270 #define NV50_PDISPLAY_CURSOR_CURSOR_CTRL2(i) ((i) * 0x10 + 0x00610270) diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c index 7c9c7c5bf22a..db100a8f231e 100644 --- a/drivers/gpu/drm/nouveau/nv50_display.c +++ b/drivers/gpu/drm/nouveau/nv50_display.c @@ -46,159 +46,6 @@ nv50_sor_nr(struct drm_device *dev) return 4; } -static void -nv50_evo_channel_del(struct nouveau_channel **pchan) -{ - struct nouveau_channel *chan = *pchan; - - if (!chan) - return; - *pchan = NULL; - - nouveau_gpuobj_channel_takedown(chan); - nouveau_bo_unmap(chan->pushbuf_bo); - nouveau_bo_ref(NULL, &chan->pushbuf_bo); - - if (chan->user) - iounmap(chan->user); - - kfree(chan); -} - -static int -nv50_evo_dmaobj_new(struct nouveau_channel *evo, uint32_t class, uint32_t name, - uint32_t tile_flags, uint32_t magic_flags, - uint32_t offset, uint32_t limit) -{ - struct drm_nouveau_private *dev_priv = evo->dev->dev_private; - struct drm_device *dev = evo->dev; - struct nouveau_gpuobj *obj = NULL; - int ret; - - ret = nouveau_gpuobj_new(dev, evo, 6*4, 32, 0, &obj); - if (ret) - return ret; - obj->engine = NVOBJ_ENGINE_DISPLAY; - - nv_wo32(obj, 0, (tile_flags << 22) | (magic_flags << 16) | class); - nv_wo32(obj, 4, limit); - nv_wo32(obj, 8, offset); - nv_wo32(obj, 12, 0x00000000); - nv_wo32(obj, 16, 0x00000000); - if (dev_priv->card_type < NV_C0) - nv_wo32(obj, 20, 0x00010000); - else - nv_wo32(obj, 20, 0x00020000); - dev_priv->engine.instmem.flush(dev); - - ret = nouveau_ramht_insert(evo, name, obj); - nouveau_gpuobj_ref(NULL, &obj); - if (ret) { - return ret; - } - - return 0; -} - -static int -nv50_evo_channel_new(struct drm_device *dev, struct nouveau_channel **pchan) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_gpuobj *ramht = NULL; - struct nouveau_channel *chan; - int ret; - - chan = kzalloc(sizeof(struct nouveau_channel), GFP_KERNEL); - if (!chan) - return -ENOMEM; - *pchan = chan; - - chan->id = -1; - chan->dev = dev; - chan->user_get = 4; - chan->user_put = 0; - - ret = nouveau_gpuobj_new(dev, NULL, 32768, 0x1000, - NVOBJ_FLAG_ZERO_ALLOC, &chan->ramin); - if (ret) { - NV_ERROR(dev, "Error allocating EVO channel memory: %d\n", ret); - nv50_evo_channel_del(pchan); - return ret; - } - - ret = drm_mm_init(&chan->ramin_heap, 0, 32768); - if (ret) { - NV_ERROR(dev, "Error initialising EVO PRAMIN heap: %d\n", ret); - nv50_evo_channel_del(pchan); - return ret; - } - - ret = nouveau_gpuobj_new(dev, chan, 4096, 16, 0, &ramht); - if (ret) { - NV_ERROR(dev, "Unable to allocate EVO RAMHT: %d\n", ret); - nv50_evo_channel_del(pchan); - return ret; - } - - ret = nouveau_ramht_new(dev, ramht, &chan->ramht); - nouveau_gpuobj_ref(NULL, &ramht); - if (ret) { - nv50_evo_channel_del(pchan); - return ret; - } - - if (dev_priv->chipset != 0x50) { - ret = nv50_evo_dmaobj_new(chan, 0x3d, NvEvoFB16, 0x70, 0x19, - 0, 0xffffffff); - if (ret) { - nv50_evo_channel_del(pchan); - return ret; - } - - - ret = nv50_evo_dmaobj_new(chan, 0x3d, NvEvoFB32, 0x7a, 0x19, - 0, 0xffffffff); - if (ret) { - nv50_evo_channel_del(pchan); - return ret; - } - } - - ret = nv50_evo_dmaobj_new(chan, 0x3d, NvEvoVRAM, 0, 0x19, - 0, dev_priv->vram_size); - if (ret) { - nv50_evo_channel_del(pchan); - return ret; - } - - ret = nouveau_bo_new(dev, NULL, 4096, 0, TTM_PL_FLAG_VRAM, 0, 0, - false, true, &chan->pushbuf_bo); - if (ret == 0) - ret = nouveau_bo_pin(chan->pushbuf_bo, TTM_PL_FLAG_VRAM); - if (ret) { - NV_ERROR(dev, "Error creating EVO DMA push buffer: %d\n", ret); - nv50_evo_channel_del(pchan); - return ret; - } - - ret = nouveau_bo_map(chan->pushbuf_bo); - if (ret) { - NV_ERROR(dev, "Error mapping EVO DMA push buffer: %d\n", ret); - nv50_evo_channel_del(pchan); - return ret; - } - - chan->user = ioremap(pci_resource_start(dev->pdev, 0) + - NV50_PDISPLAY_USER(0), PAGE_SIZE); - if (!chan->user) { - NV_ERROR(dev, "Error mapping EVO control regs.\n"); - nv50_evo_channel_del(pchan); - return -ENOMEM; - } - - return 0; -} - int nv50_display_early_init(struct drm_device *dev) { @@ -214,12 +61,10 @@ int nv50_display_init(struct drm_device *dev) { struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_timer_engine *ptimer = &dev_priv->engine.timer; struct nouveau_gpio_engine *pgpio = &dev_priv->engine.gpio; - struct nouveau_channel *evo = dev_priv->evo; struct drm_connector *connector; + struct nouveau_channel *evo; int ret, i; - u64 start; u32 val; NV_DEBUG_KMS(dev, "\n"); @@ -303,7 +148,6 @@ nv50_display_init(struct drm_device *dev) } } - nv_wr32(dev, NV50_PDISPLAY_OBJECTS, (evo->ramin->vinst >> 8) | 9); nv_wr32(dev, NV50_PDISPLAY_PIO_CTRL, 0x00000000); nv_wr32(dev, 0x610028, 0x00000000); nv_mask(dev, NV50_PDISPLAY_INTR_0, 0x00000000, 0x00000000); @@ -323,69 +167,12 @@ nv50_display_init(struct drm_device *dev) pgpio->irq_enable(dev, conn->dcb->gpio_tag, true); } - /* taken from nv bug #12637, attempts to un-wedge the hw if it's - * stuck in some unspecified state - */ - start = ptimer->read(dev); - nv_wr32(dev, NV50_PDISPLAY_CHANNEL_STAT(0), 0x2b00); - while ((val = nv_rd32(dev, NV50_PDISPLAY_CHANNEL_STAT(0))) & 0x1e0000) { - if ((val & 0x9f0000) == 0x20000) - nv_wr32(dev, NV50_PDISPLAY_CHANNEL_STAT(0), - val | 0x800000); - - if ((val & 0x3f0000) == 0x30000) - nv_wr32(dev, NV50_PDISPLAY_CHANNEL_STAT(0), - val | 0x200000); - - if (ptimer->read(dev) - start > 1000000000ULL) { - NV_ERROR(dev, "timeout: (0x610200 & 0x1e0000) != 0\n"); - NV_ERROR(dev, "0x610200 = 0x%08x\n", val); - return -EBUSY; - } - } - - nv_wr32(dev, NV50_PDISPLAY_CHANNEL_STAT(0), 0x1000b03); - if (!nv_wait(dev, NV50_PDISPLAY_CHANNEL_STAT(0), - 0x40000000, 0x40000000)) { - NV_ERROR(dev, "timeout: (0x610200 & 0x40000000) == 0x40000000\n"); - NV_ERROR(dev, "0x610200 = 0x%08x\n", - nv_rd32(dev, NV50_PDISPLAY_CHANNEL_STAT(0))); - return -EBUSY; - } - - /* initialise fifo */ - nv_wr32(dev, NV50_PDISPLAY_CHANNEL_DMA_CB(0), - ((evo->pushbuf_bo->bo.mem.start << PAGE_SHIFT) >> 8) | - NV50_PDISPLAY_CHANNEL_DMA_CB_LOCATION_VRAM | - NV50_PDISPLAY_CHANNEL_DMA_CB_VALID); - nv_wr32(dev, NV50_PDISPLAY_CHANNEL_UNK2(0), 0x00010000); - nv_wr32(dev, NV50_PDISPLAY_CHANNEL_UNK3(0), 0x00000002); - if (!nv_wait(dev, 0x610200, 0x80000000, 0x00000000)) { - NV_ERROR(dev, "timeout: (0x610200 & 0x80000000) == 0\n"); - NV_ERROR(dev, "0x610200 = 0x%08x\n", nv_rd32(dev, 0x610200)); - return -EBUSY; - } - nv_wr32(dev, NV50_PDISPLAY_CHANNEL_STAT(0), - (nv_rd32(dev, NV50_PDISPLAY_CHANNEL_STAT(0)) & ~0x00000003) | - NV50_PDISPLAY_CHANNEL_STAT_DMA_ENABLED); - nv_wr32(dev, NV50_PDISPLAY_USER_PUT(0), 0); - nv_wr32(dev, NV50_PDISPLAY_CHANNEL_STAT(0), 0x01000003 | - NV50_PDISPLAY_CHANNEL_STAT_DMA_ENABLED); - - /* enable error reporting on the channel */ - nv_mask(dev, 0x610028, 0x00000000, 0x00010001 << 0); - - evo->dma.max = (4096/4) - 2; - evo->dma.put = 0; - evo->dma.cur = evo->dma.put; - evo->dma.free = evo->dma.max - evo->dma.cur; - - ret = RING_SPACE(evo, NOUVEAU_DMA_SKIPS); + ret = nv50_evo_init(dev); if (ret) return ret; + evo = dev_priv->evo; - for (i = 0; i < NOUVEAU_DMA_SKIPS; i++) - OUT_RING(evo, 0); + nv_wr32(dev, NV50_PDISPLAY_OBJECTS, (evo->ramin->vinst >> 8) | 9); ret = RING_SPACE(evo, 11); if (ret) @@ -449,12 +236,7 @@ static int nv50_display_disable(struct drm_device *dev) } } - nv_wr32(dev, NV50_PDISPLAY_CHANNEL_STAT(0), 0); - if (!nv_wait(dev, NV50_PDISPLAY_CHANNEL_STAT(0), 0x1e0000, 0)) { - NV_ERROR(dev, "timeout: (0x610200 & 0x1e0000) == 0\n"); - NV_ERROR(dev, "0x610200 = 0x%08x\n", - nv_rd32(dev, NV50_PDISPLAY_CHANNEL_STAT(0))); - } + nv50_evo_fini(dev); for (i = 0; i < 3; i++) { if (!nv_wait(dev, NV50_PDISPLAY_SOR_DPMS_STATE(i), @@ -504,13 +286,6 @@ int nv50_display_create(struct drm_device *dev) dev->mode_config.fb_base = dev_priv->fb_phys; - /* Create EVO channel */ - ret = nv50_evo_channel_new(dev, &dev_priv->evo); - if (ret) { - NV_ERROR(dev, "Error creating EVO channel: %d\n", ret); - return ret; - } - /* Create CRTC objects */ for (i = 0; i < 2; i++) nv50_crtc_create(dev, i); @@ -565,14 +340,11 @@ int nv50_display_create(struct drm_device *dev) void nv50_display_destroy(struct drm_device *dev) { - struct drm_nouveau_private *dev_priv = dev->dev_private; - NV_DEBUG_KMS(dev, "\n"); drm_mode_config_cleanup(dev); nv50_display_disable(dev); - nv50_evo_channel_del(&dev_priv->evo); } static u16 diff --git a/drivers/gpu/drm/nouveau/nv50_evo.c b/drivers/gpu/drm/nouveau/nv50_evo.c new file mode 100644 index 000000000000..211f5fb1dc73 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nv50_evo.c @@ -0,0 +1,295 @@ +/* + * Copyright 2010 Red Hat Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: Ben Skeggs + */ + +#include "drmP.h" + +#include "nouveau_drv.h" +#include "nouveau_dma.h" +#include "nouveau_ramht.h" + +static void +nv50_evo_channel_del(struct nouveau_channel **pchan) +{ + struct nouveau_channel *chan = *pchan; + + if (!chan) + return; + *pchan = NULL; + + nouveau_gpuobj_channel_takedown(chan); + nouveau_bo_unmap(chan->pushbuf_bo); + nouveau_bo_ref(NULL, &chan->pushbuf_bo); + + if (chan->user) + iounmap(chan->user); + + kfree(chan); +} + +int +nv50_evo_dmaobj_new(struct nouveau_channel *evo, u32 class, u32 name, + u32 tile_flags, u32 magic_flags, u32 offset, u32 limit) +{ + struct drm_nouveau_private *dev_priv = evo->dev->dev_private; + struct drm_device *dev = evo->dev; + struct nouveau_gpuobj *obj = NULL; + int ret; + + ret = nouveau_gpuobj_new(dev, evo, 6*4, 32, 0, &obj); + if (ret) + return ret; + obj->engine = NVOBJ_ENGINE_DISPLAY; + + nv_wo32(obj, 0, (tile_flags << 22) | (magic_flags << 16) | class); + nv_wo32(obj, 4, limit); + nv_wo32(obj, 8, offset); + nv_wo32(obj, 12, 0x00000000); + nv_wo32(obj, 16, 0x00000000); + if (dev_priv->card_type < NV_C0) + nv_wo32(obj, 20, 0x00010000); + else + nv_wo32(obj, 20, 0x00020000); + dev_priv->engine.instmem.flush(dev); + + ret = nouveau_ramht_insert(evo, name, obj); + nouveau_gpuobj_ref(NULL, &obj); + if (ret) { + return ret; + } + + return 0; +} + +static int +nv50_evo_channel_new(struct drm_device *dev, struct nouveau_channel **pchan) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_gpuobj *ramht = NULL; + struct nouveau_channel *chan; + int ret; + + chan = kzalloc(sizeof(struct nouveau_channel), GFP_KERNEL); + if (!chan) + return -ENOMEM; + *pchan = chan; + + chan->id = -1; + chan->dev = dev; + chan->user_get = 4; + chan->user_put = 0; + + ret = nouveau_gpuobj_new(dev, NULL, 32768, 0x1000, + NVOBJ_FLAG_ZERO_ALLOC, &chan->ramin); + if (ret) { + NV_ERROR(dev, "Error allocating EVO channel memory: %d\n", ret); + nv50_evo_channel_del(pchan); + return ret; + } + + ret = drm_mm_init(&chan->ramin_heap, 0, 32768); + if (ret) { + NV_ERROR(dev, "Error initialising EVO PRAMIN heap: %d\n", ret); + nv50_evo_channel_del(pchan); + return ret; + } + + ret = nouveau_gpuobj_new(dev, chan, 4096, 16, 0, &ramht); + if (ret) { + NV_ERROR(dev, "Unable to allocate EVO RAMHT: %d\n", ret); + nv50_evo_channel_del(pchan); + return ret; + } + + ret = nouveau_ramht_new(dev, ramht, &chan->ramht); + nouveau_gpuobj_ref(NULL, &ramht); + if (ret) { + nv50_evo_channel_del(pchan); + return ret; + } + + if (dev_priv->chipset != 0x50) { + ret = nv50_evo_dmaobj_new(chan, 0x3d, NvEvoFB16, 0x70, 0x19, + 0, 0xffffffff); + if (ret) { + nv50_evo_channel_del(pchan); + return ret; + } + + + ret = nv50_evo_dmaobj_new(chan, 0x3d, NvEvoFB32, 0x7a, 0x19, + 0, 0xffffffff); + if (ret) { + nv50_evo_channel_del(pchan); + return ret; + } + } + + ret = nv50_evo_dmaobj_new(chan, 0x3d, NvEvoVRAM, 0, 0x19, + 0, dev_priv->vram_size); + if (ret) { + nv50_evo_channel_del(pchan); + return ret; + } + + ret = nouveau_bo_new(dev, NULL, 4096, 0, TTM_PL_FLAG_VRAM, 0, 0, + false, true, &chan->pushbuf_bo); + if (ret == 0) + ret = nouveau_bo_pin(chan->pushbuf_bo, TTM_PL_FLAG_VRAM); + if (ret) { + NV_ERROR(dev, "Error creating EVO DMA push buffer: %d\n", ret); + nv50_evo_channel_del(pchan); + return ret; + } + + ret = nouveau_bo_map(chan->pushbuf_bo); + if (ret) { + NV_ERROR(dev, "Error mapping EVO DMA push buffer: %d\n", ret); + nv50_evo_channel_del(pchan); + return ret; + } + + chan->user = ioremap(pci_resource_start(dev->pdev, 0) + + NV50_PDISPLAY_USER(0), PAGE_SIZE); + if (!chan->user) { + NV_ERROR(dev, "Error mapping EVO control regs.\n"); + nv50_evo_channel_del(pchan); + return -ENOMEM; + } + + return 0; +} + +static int +nv50_evo_channel_init(struct nouveau_channel *evo) +{ + struct drm_nouveau_private *dev_priv = evo->dev->dev_private; + struct nouveau_timer_engine *ptimer = &dev_priv->engine.timer; + struct drm_device *dev = evo->dev; + int ret, i; + u64 start; + u32 tmp; + + /* taken from nv bug #12637, attempts to un-wedge the hw if it's + * stuck in some unspecified state + */ + start = ptimer->read(dev); + nv_wr32(dev, NV50_PDISPLAY_EVO_CTRL(0), 0x2b00); + while ((tmp = nv_rd32(dev, NV50_PDISPLAY_EVO_CTRL(0))) & 0x1e0000) { + if ((tmp & 0x9f0000) == 0x20000) + nv_wr32(dev, NV50_PDISPLAY_EVO_CTRL(0), tmp | 0x800000); + + if ((tmp & 0x3f0000) == 0x30000) + nv_wr32(dev, NV50_PDISPLAY_EVO_CTRL(0), tmp | 0x200000); + + if (ptimer->read(dev) - start > 1000000000ULL) { + NV_ERROR(dev, "timeout: (0x610200 & 0x1e0000) != 0\n"); + NV_ERROR(dev, "0x610200 = 0x%08x\n", tmp); + return -EBUSY; + } + } + + nv_wr32(dev, NV50_PDISPLAY_EVO_CTRL(0), 0x1000b03); + if (!nv_wait(dev, NV50_PDISPLAY_EVO_CTRL(0), + 0x40000000, 0x40000000)) { + NV_ERROR(dev, "timeout: (0x610200 & 0x40000000) == 0x40000000\n"); + NV_ERROR(dev, "0x610200 = 0x%08x\n", + nv_rd32(dev, NV50_PDISPLAY_EVO_CTRL(0))); + return -EBUSY; + } + + /* initialise fifo */ + nv_wr32(dev, NV50_PDISPLAY_EVO_DMA_CB(0), + ((evo->pushbuf_bo->bo.mem.start << PAGE_SHIFT) >> 8) | + NV50_PDISPLAY_EVO_DMA_CB_LOCATION_VRAM | + NV50_PDISPLAY_EVO_DMA_CB_VALID); + nv_wr32(dev, NV50_PDISPLAY_EVO_UNK2(0), 0x00010000); + nv_wr32(dev, NV50_PDISPLAY_EVO_HASH_TAG(0), 0x00000002); + if (!nv_wait(dev, 0x610200, 0x80000000, 0x00000000)) { + NV_ERROR(dev, "timeout: (0x610200 & 0x80000000) == 0\n"); + NV_ERROR(dev, "0x610200 = 0x%08x\n", nv_rd32(dev, 0x610200)); + return -EBUSY; + } + nv_wr32(dev, NV50_PDISPLAY_EVO_CTRL(0), + (nv_rd32(dev, NV50_PDISPLAY_EVO_CTRL(0)) & ~0x00000003) | + NV50_PDISPLAY_EVO_CTRL_DMA_ENABLED); + nv_wr32(dev, NV50_PDISPLAY_USER_PUT(0), 0); + nv_wr32(dev, NV50_PDISPLAY_EVO_CTRL(0), 0x01000003 | + NV50_PDISPLAY_EVO_CTRL_DMA_ENABLED); + + /* enable error reporting on the channel */ + nv_mask(dev, 0x610028, 0x00000000, 0x00010001 << 0); + + evo->dma.max = (4096/4) - 2; + evo->dma.put = 0; + evo->dma.cur = evo->dma.put; + evo->dma.free = evo->dma.max - evo->dma.cur; + + ret = RING_SPACE(evo, NOUVEAU_DMA_SKIPS); + if (ret) + return ret; + + for (i = 0; i < NOUVEAU_DMA_SKIPS; i++) + OUT_RING(evo, 0); + + return 0; +} + +static void +nv50_evo_channel_fini(struct nouveau_channel *evo) +{ + struct drm_device *dev = evo->dev; + + nv_wr32(dev, NV50_PDISPLAY_EVO_CTRL(0), 0); + if (!nv_wait(dev, NV50_PDISPLAY_EVO_CTRL(0), 0x1e0000, 0)) { + NV_ERROR(dev, "timeout: (0x610200 & 0x1e0000) == 0\n"); + NV_ERROR(dev, "0x610200 = 0x%08x\n", + nv_rd32(dev, NV50_PDISPLAY_EVO_CTRL(0))); + } +} + +int +nv50_evo_init(struct drm_device *dev) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + int ret; + + if (!dev_priv->evo) { + ret = nv50_evo_channel_new(dev, &dev_priv->evo); + if (ret) + return ret; + } + + return nv50_evo_channel_init(dev_priv->evo); +} + +void +nv50_evo_fini(struct drm_device *dev) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + + if (dev_priv->evo) { + nv50_evo_channel_fini(dev_priv->evo); + nv50_evo_channel_del(&dev_priv->evo); + } +} diff --git a/drivers/gpu/drm/nouveau/nv50_evo.h b/drivers/gpu/drm/nouveau/nv50_evo.h index aae13343bcec..aa4f0d3cea8e 100644 --- a/drivers/gpu/drm/nouveau/nv50_evo.h +++ b/drivers/gpu/drm/nouveau/nv50_evo.h @@ -24,6 +24,15 @@ * */ +#ifndef __NV50_EVO_H__ +#define __NV50_EVO_H__ + +int nv50_evo_init(struct drm_device *dev); +void nv50_evo_fini(struct drm_device *dev); +int nv50_evo_dmaobj_new(struct nouveau_channel *, u32 class, u32 name, + u32 tile_flags, u32 magic_flags, + u32 offset, u32 limit); + #define NV50_EVO_UPDATE 0x00000080 #define NV50_EVO_UNK84 0x00000084 #define NV50_EVO_UNK84_NOTIFY 0x40000000 @@ -111,3 +120,4 @@ #define NV50_EVO_CRTC_SCALE_RES1 0x000008d8 #define NV50_EVO_CRTC_SCALE_RES2 0x000008dc +#endif -- cgit v1.2.3 From 1e96268aca1bb40f42bdbc9d2293b123b072f1de Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 19 Oct 2010 14:18:06 +1000 Subject: drm/nv50: initial work to allow multiple evo channels This doesn't work yet for unknown reasons. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_drv.h | 1 + drivers/gpu/drm/nouveau/nouveau_ramht.c | 2 +- drivers/gpu/drm/nouveau/nv50_evo.c | 246 +++++++++++++++++++------------- 3 files changed, 147 insertions(+), 102 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index d15bfd427267..bf34f25c7a54 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -689,6 +689,7 @@ struct drm_nouveau_private { struct backlight_device *backlight; struct nouveau_channel *evo; + u32 evo_alloc; struct { struct dcb_entry *dcb; u16 script; diff --git a/drivers/gpu/drm/nouveau/nouveau_ramht.c b/drivers/gpu/drm/nouveau/nouveau_ramht.c index b4c63c058888..d4a2adc927d8 100644 --- a/drivers/gpu/drm/nouveau/nouveau_ramht.c +++ b/drivers/gpu/drm/nouveau/nouveau_ramht.c @@ -114,7 +114,7 @@ nouveau_ramht_insert(struct nouveau_channel *chan, u32 handle, (gpuobj->engine << NV40_RAMHT_CONTEXT_ENGINE_SHIFT); } else { if (gpuobj->engine == NVOBJ_ENGINE_DISPLAY) { - ctx = (gpuobj->cinst << 10) | 2; + ctx = (gpuobj->cinst << 10) | chan->id; } else { ctx = (gpuobj->cinst >> 4) | ((gpuobj->engine << diff --git a/drivers/gpu/drm/nouveau/nv50_evo.c b/drivers/gpu/drm/nouveau/nv50_evo.c index 211f5fb1dc73..dbad233e750f 100644 --- a/drivers/gpu/drm/nouveau/nv50_evo.c +++ b/drivers/gpu/drm/nouveau/nv50_evo.c @@ -29,22 +29,26 @@ #include "nouveau_ramht.h" static void -nv50_evo_channel_del(struct nouveau_channel **pchan) +nv50_evo_channel_del(struct nouveau_channel **pevo) { - struct nouveau_channel *chan = *pchan; + struct drm_nouveau_private *dev_priv; + struct nouveau_channel *evo = *pevo; - if (!chan) + if (!evo) return; - *pchan = NULL; + *pevo = NULL; - nouveau_gpuobj_channel_takedown(chan); - nouveau_bo_unmap(chan->pushbuf_bo); - nouveau_bo_ref(NULL, &chan->pushbuf_bo); + dev_priv = evo->dev->dev_private; + dev_priv->evo_alloc &= ~(1 << evo->id); - if (chan->user) - iounmap(chan->user); + nouveau_gpuobj_channel_takedown(evo); + nouveau_bo_unmap(evo->pushbuf_bo); + nouveau_bo_ref(NULL, &evo->pushbuf_bo); - kfree(chan); + if (evo->user) + iounmap(evo->user); + + kfree(evo); } int @@ -56,7 +60,7 @@ nv50_evo_dmaobj_new(struct nouveau_channel *evo, u32 class, u32 name, struct nouveau_gpuobj *obj = NULL; int ret; - ret = nouveau_gpuobj_new(dev, evo, 6*4, 32, 0, &obj); + ret = nouveau_gpuobj_new(dev, dev_priv->evo, 6*4, 32, 0, &obj); if (ret) return ret; obj->engine = NVOBJ_ENGINE_DISPLAY; @@ -82,101 +86,63 @@ nv50_evo_dmaobj_new(struct nouveau_channel *evo, u32 class, u32 name, } static int -nv50_evo_channel_new(struct drm_device *dev, struct nouveau_channel **pchan) +nv50_evo_channel_new(struct drm_device *dev, struct nouveau_channel **pevo) { struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_gpuobj *ramht = NULL; - struct nouveau_channel *chan; + struct nouveau_channel *evo; int ret; - chan = kzalloc(sizeof(struct nouveau_channel), GFP_KERNEL); - if (!chan) + evo = kzalloc(sizeof(struct nouveau_channel), GFP_KERNEL); + if (!evo) return -ENOMEM; - *pchan = chan; - - chan->id = -1; - chan->dev = dev; - chan->user_get = 4; - chan->user_put = 0; - - ret = nouveau_gpuobj_new(dev, NULL, 32768, 0x1000, - NVOBJ_FLAG_ZERO_ALLOC, &chan->ramin); - if (ret) { - NV_ERROR(dev, "Error allocating EVO channel memory: %d\n", ret); - nv50_evo_channel_del(pchan); - return ret; - } - - ret = drm_mm_init(&chan->ramin_heap, 0, 32768); - if (ret) { - NV_ERROR(dev, "Error initialising EVO PRAMIN heap: %d\n", ret); - nv50_evo_channel_del(pchan); - return ret; - } + *pevo = evo; - ret = nouveau_gpuobj_new(dev, chan, 4096, 16, 0, &ramht); - if (ret) { - NV_ERROR(dev, "Unable to allocate EVO RAMHT: %d\n", ret); - nv50_evo_channel_del(pchan); - return ret; - } + for (evo->id = 0; evo->id < 5; evo->id++) { + if (dev_priv->evo_alloc & (1 << evo->id)) + continue; - ret = nouveau_ramht_new(dev, ramht, &chan->ramht); - nouveau_gpuobj_ref(NULL, &ramht); - if (ret) { - nv50_evo_channel_del(pchan); - return ret; + dev_priv->evo_alloc |= (1 << evo->id); + break; } - if (dev_priv->chipset != 0x50) { - ret = nv50_evo_dmaobj_new(chan, 0x3d, NvEvoFB16, 0x70, 0x19, - 0, 0xffffffff); - if (ret) { - nv50_evo_channel_del(pchan); - return ret; - } - - - ret = nv50_evo_dmaobj_new(chan, 0x3d, NvEvoFB32, 0x7a, 0x19, - 0, 0xffffffff); - if (ret) { - nv50_evo_channel_del(pchan); - return ret; - } + if (evo->id == 5) { + kfree(evo); + return -ENODEV; } - ret = nv50_evo_dmaobj_new(chan, 0x3d, NvEvoVRAM, 0, 0x19, - 0, dev_priv->vram_size); - if (ret) { - nv50_evo_channel_del(pchan); - return ret; - } + evo->dev = dev; + evo->user_get = 4; + evo->user_put = 0; ret = nouveau_bo_new(dev, NULL, 4096, 0, TTM_PL_FLAG_VRAM, 0, 0, - false, true, &chan->pushbuf_bo); + false, true, &evo->pushbuf_bo); if (ret == 0) - ret = nouveau_bo_pin(chan->pushbuf_bo, TTM_PL_FLAG_VRAM); + ret = nouveau_bo_pin(evo->pushbuf_bo, TTM_PL_FLAG_VRAM); if (ret) { NV_ERROR(dev, "Error creating EVO DMA push buffer: %d\n", ret); - nv50_evo_channel_del(pchan); + nv50_evo_channel_del(pevo); return ret; } - ret = nouveau_bo_map(chan->pushbuf_bo); + ret = nouveau_bo_map(evo->pushbuf_bo); if (ret) { NV_ERROR(dev, "Error mapping EVO DMA push buffer: %d\n", ret); - nv50_evo_channel_del(pchan); + nv50_evo_channel_del(pevo); return ret; } - chan->user = ioremap(pci_resource_start(dev->pdev, 0) + - NV50_PDISPLAY_USER(0), PAGE_SIZE); - if (!chan->user) { + evo->user = ioremap(pci_resource_start(dev->pdev, 0) + + NV50_PDISPLAY_USER(evo->id), PAGE_SIZE); + if (!evo->user) { NV_ERROR(dev, "Error mapping EVO control regs.\n"); - nv50_evo_channel_del(pchan); + nv50_evo_channel_del(pevo); return -ENOMEM; } + /* bind primary evo channel's ramht to the channel */ + if (dev_priv->evo && evo != dev_priv->evo) + nouveau_ramht_ref(dev_priv->evo->ramht, &evo->ramht, NULL); + return 0; } @@ -186,7 +152,7 @@ nv50_evo_channel_init(struct nouveau_channel *evo) struct drm_nouveau_private *dev_priv = evo->dev->dev_private; struct nouveau_timer_engine *ptimer = &dev_priv->engine.timer; struct drm_device *dev = evo->dev; - int ret, i; + int id = evo->id, ret, i; u64 start; u32 tmp; @@ -194,13 +160,13 @@ nv50_evo_channel_init(struct nouveau_channel *evo) * stuck in some unspecified state */ start = ptimer->read(dev); - nv_wr32(dev, NV50_PDISPLAY_EVO_CTRL(0), 0x2b00); - while ((tmp = nv_rd32(dev, NV50_PDISPLAY_EVO_CTRL(0))) & 0x1e0000) { + nv_wr32(dev, NV50_PDISPLAY_EVO_CTRL(id), 0x2b00); + while ((tmp = nv_rd32(dev, NV50_PDISPLAY_EVO_CTRL(id))) & 0x1e0000) { if ((tmp & 0x9f0000) == 0x20000) - nv_wr32(dev, NV50_PDISPLAY_EVO_CTRL(0), tmp | 0x800000); + nv_wr32(dev, NV50_PDISPLAY_EVO_CTRL(id), tmp | 0x800000); if ((tmp & 0x3f0000) == 0x30000) - nv_wr32(dev, NV50_PDISPLAY_EVO_CTRL(0), tmp | 0x200000); + nv_wr32(dev, NV50_PDISPLAY_EVO_CTRL(id), tmp | 0x200000); if (ptimer->read(dev) - start > 1000000000ULL) { NV_ERROR(dev, "timeout: (0x610200 & 0x1e0000) != 0\n"); @@ -209,36 +175,37 @@ nv50_evo_channel_init(struct nouveau_channel *evo) } } - nv_wr32(dev, NV50_PDISPLAY_EVO_CTRL(0), 0x1000b03); - if (!nv_wait(dev, NV50_PDISPLAY_EVO_CTRL(0), + nv_wr32(dev, NV50_PDISPLAY_EVO_CTRL(id), 0x1000b03); + if (!nv_wait(dev, NV50_PDISPLAY_EVO_CTRL(id), 0x40000000, 0x40000000)) { NV_ERROR(dev, "timeout: (0x610200 & 0x40000000) == 0x40000000\n"); NV_ERROR(dev, "0x610200 = 0x%08x\n", - nv_rd32(dev, NV50_PDISPLAY_EVO_CTRL(0))); + nv_rd32(dev, NV50_PDISPLAY_EVO_CTRL(id))); return -EBUSY; } /* initialise fifo */ - nv_wr32(dev, NV50_PDISPLAY_EVO_DMA_CB(0), + nv_wr32(dev, NV50_PDISPLAY_EVO_DMA_CB(id), ((evo->pushbuf_bo->bo.mem.start << PAGE_SHIFT) >> 8) | NV50_PDISPLAY_EVO_DMA_CB_LOCATION_VRAM | NV50_PDISPLAY_EVO_DMA_CB_VALID); - nv_wr32(dev, NV50_PDISPLAY_EVO_UNK2(0), 0x00010000); - nv_wr32(dev, NV50_PDISPLAY_EVO_HASH_TAG(0), 0x00000002); - if (!nv_wait(dev, 0x610200, 0x80000000, 0x00000000)) { + nv_wr32(dev, NV50_PDISPLAY_EVO_UNK2(id), 0x00010000); + nv_wr32(dev, NV50_PDISPLAY_EVO_HASH_TAG(id), id); + if (!nv_wait(dev, NV50_PDISPLAY_EVO_CTRL(id), 0x80000000, 0x00000000)) { NV_ERROR(dev, "timeout: (0x610200 & 0x80000000) == 0\n"); - NV_ERROR(dev, "0x610200 = 0x%08x\n", nv_rd32(dev, 0x610200)); + NV_ERROR(dev, "0x610200 = 0x%08x\n", + nv_rd32(dev, NV50_PDISPLAY_EVO_CTRL(id))); return -EBUSY; } - nv_wr32(dev, NV50_PDISPLAY_EVO_CTRL(0), - (nv_rd32(dev, NV50_PDISPLAY_EVO_CTRL(0)) & ~0x00000003) | + nv_wr32(dev, NV50_PDISPLAY_EVO_CTRL(id), + (nv_rd32(dev, NV50_PDISPLAY_EVO_CTRL(id)) & ~0x00000003) | NV50_PDISPLAY_EVO_CTRL_DMA_ENABLED); - nv_wr32(dev, NV50_PDISPLAY_USER_PUT(0), 0); - nv_wr32(dev, NV50_PDISPLAY_EVO_CTRL(0), 0x01000003 | - NV50_PDISPLAY_EVO_CTRL_DMA_ENABLED); + nv_wr32(dev, NV50_PDISPLAY_USER_PUT(id), 0); + nv_wr32(dev, NV50_PDISPLAY_EVO_CTRL(id), 0x01000003 | + NV50_PDISPLAY_EVO_CTRL_DMA_ENABLED); /* enable error reporting on the channel */ - nv_mask(dev, 0x610028, 0x00000000, 0x00010001 << 0); + nv_mask(dev, 0x610028, 0x00000000, 0x00010001 << id); evo->dma.max = (4096/4) - 2; evo->dma.put = 0; @@ -260,12 +227,89 @@ nv50_evo_channel_fini(struct nouveau_channel *evo) { struct drm_device *dev = evo->dev; - nv_wr32(dev, NV50_PDISPLAY_EVO_CTRL(0), 0); - if (!nv_wait(dev, NV50_PDISPLAY_EVO_CTRL(0), 0x1e0000, 0)) { + nv_wr32(dev, NV50_PDISPLAY_EVO_CTRL(evo->id), 0); + if (!nv_wait(dev, NV50_PDISPLAY_EVO_CTRL(evo->id), 0x1e0000, 0)) { NV_ERROR(dev, "timeout: (0x610200 & 0x1e0000) == 0\n"); NV_ERROR(dev, "0x610200 = 0x%08x\n", - nv_rd32(dev, NV50_PDISPLAY_EVO_CTRL(0))); + nv_rd32(dev, NV50_PDISPLAY_EVO_CTRL(evo->id))); + } +} + +static int +nv50_evo_create(struct drm_device *dev) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_gpuobj *ramht = NULL; + struct nouveau_channel *evo; + int ret; + + /* create primary evo channel, the one we use for modesetting + * purporses + */ + ret = nv50_evo_channel_new(dev, &dev_priv->evo); + if (ret) + return ret; + evo = dev_priv->evo; + + /* setup object management on it, any other evo channel will + * use this also as there's no per-channel support on the + * hardware + */ + ret = nouveau_gpuobj_new(dev, NULL, 32768, 0x1000, + NVOBJ_FLAG_ZERO_ALLOC, &evo->ramin); + if (ret) { + NV_ERROR(dev, "Error allocating EVO channel memory: %d\n", ret); + nv50_evo_channel_del(&dev_priv->evo); + return ret; + } + + ret = drm_mm_init(&evo->ramin_heap, 0, 32768); + if (ret) { + NV_ERROR(dev, "Error initialising EVO PRAMIN heap: %d\n", ret); + nv50_evo_channel_del(&dev_priv->evo); + return ret; + } + + ret = nouveau_gpuobj_new(dev, evo, 4096, 16, 0, &ramht); + if (ret) { + NV_ERROR(dev, "Unable to allocate EVO RAMHT: %d\n", ret); + nv50_evo_channel_del(&dev_priv->evo); + return ret; + } + + ret = nouveau_ramht_new(dev, ramht, &evo->ramht); + nouveau_gpuobj_ref(NULL, &ramht); + if (ret) { + nv50_evo_channel_del(&dev_priv->evo); + return ret; + } + + /* create some default objects for the scanout memtypes we support */ + if (dev_priv->chipset != 0x50) { + ret = nv50_evo_dmaobj_new(evo, 0x3d, NvEvoFB16, 0x70, 0x19, + 0, 0xffffffff); + if (ret) { + nv50_evo_channel_del(&dev_priv->evo); + return ret; + } + + + ret = nv50_evo_dmaobj_new(evo, 0x3d, NvEvoFB32, 0x7a, 0x19, + 0, 0xffffffff); + if (ret) { + nv50_evo_channel_del(&dev_priv->evo); + return ret; + } + } + + ret = nv50_evo_dmaobj_new(evo, 0x3d, NvEvoVRAM, 0, 0x19, + 0, dev_priv->vram_size); + if (ret) { + nv50_evo_channel_del(&dev_priv->evo); + return ret; } + + return 0; } int @@ -275,7 +319,7 @@ nv50_evo_init(struct drm_device *dev) int ret; if (!dev_priv->evo) { - ret = nv50_evo_channel_new(dev, &dev_priv->evo); + ret = nv50_evo_create(dev); if (ret) return ret; } -- cgit v1.2.3 From 43ce028ff2b1df68c690f0af14a109288d3e9e86 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 19 Oct 2010 18:01:41 +1000 Subject: drm/nv50: rework evo init to match nvidia more closely Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nv50_evo.c | 73 ++++++++++++++------------------------ 1 file changed, 26 insertions(+), 47 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nv50_evo.c b/drivers/gpu/drm/nouveau/nv50_evo.c index dbad233e750f..d270f17a5310 100644 --- a/drivers/gpu/drm/nouveau/nv50_evo.c +++ b/drivers/gpu/drm/nouveau/nv50_evo.c @@ -149,60 +149,36 @@ nv50_evo_channel_new(struct drm_device *dev, struct nouveau_channel **pevo) static int nv50_evo_channel_init(struct nouveau_channel *evo) { - struct drm_nouveau_private *dev_priv = evo->dev->dev_private; - struct nouveau_timer_engine *ptimer = &dev_priv->engine.timer; struct drm_device *dev = evo->dev; int id = evo->id, ret, i; - u64 start; + u64 pushbuf = evo->pushbuf_bo->bo.mem.start << PAGE_SHIFT; u32 tmp; - /* taken from nv bug #12637, attempts to un-wedge the hw if it's - * stuck in some unspecified state - */ - start = ptimer->read(dev); - nv_wr32(dev, NV50_PDISPLAY_EVO_CTRL(id), 0x2b00); - while ((tmp = nv_rd32(dev, NV50_PDISPLAY_EVO_CTRL(id))) & 0x1e0000) { - if ((tmp & 0x9f0000) == 0x20000) - nv_wr32(dev, NV50_PDISPLAY_EVO_CTRL(id), tmp | 0x800000); - - if ((tmp & 0x3f0000) == 0x30000) - nv_wr32(dev, NV50_PDISPLAY_EVO_CTRL(id), tmp | 0x200000); - - if (ptimer->read(dev) - start > 1000000000ULL) { - NV_ERROR(dev, "timeout: (0x610200 & 0x1e0000) != 0\n"); - NV_ERROR(dev, "0x610200 = 0x%08x\n", tmp); - return -EBUSY; - } - } + tmp = nv_rd32(dev, NV50_PDISPLAY_EVO_CTRL(id)); + if ((tmp & 0x009f0000) == 0x00020000) + nv_wr32(dev, NV50_PDISPLAY_EVO_CTRL(id), tmp | 0x00800000); - nv_wr32(dev, NV50_PDISPLAY_EVO_CTRL(id), 0x1000b03); - if (!nv_wait(dev, NV50_PDISPLAY_EVO_CTRL(id), - 0x40000000, 0x40000000)) { - NV_ERROR(dev, "timeout: (0x610200 & 0x40000000) == 0x40000000\n"); - NV_ERROR(dev, "0x610200 = 0x%08x\n", - nv_rd32(dev, NV50_PDISPLAY_EVO_CTRL(id))); - return -EBUSY; - } + tmp = nv_rd32(dev, NV50_PDISPLAY_EVO_CTRL(id)); + if ((tmp & 0x003f0000) == 0x00030000) + nv_wr32(dev, NV50_PDISPLAY_EVO_CTRL(id), tmp | 0x00600000); /* initialise fifo */ - nv_wr32(dev, NV50_PDISPLAY_EVO_DMA_CB(id), - ((evo->pushbuf_bo->bo.mem.start << PAGE_SHIFT) >> 8) | - NV50_PDISPLAY_EVO_DMA_CB_LOCATION_VRAM | - NV50_PDISPLAY_EVO_DMA_CB_VALID); + nv_wr32(dev, NV50_PDISPLAY_EVO_DMA_CB(id), pushbuf >> 8 | + NV50_PDISPLAY_EVO_DMA_CB_LOCATION_VRAM | + NV50_PDISPLAY_EVO_DMA_CB_VALID); nv_wr32(dev, NV50_PDISPLAY_EVO_UNK2(id), 0x00010000); nv_wr32(dev, NV50_PDISPLAY_EVO_HASH_TAG(id), id); + nv_mask(dev, NV50_PDISPLAY_EVO_CTRL(id), NV50_PDISPLAY_EVO_CTRL_DMA, + NV50_PDISPLAY_EVO_CTRL_DMA_ENABLED); + + nv_wr32(dev, NV50_PDISPLAY_USER_PUT(id), 0x00000000); + nv_wr32(dev, NV50_PDISPLAY_EVO_CTRL(id), 0x01000003 | + NV50_PDISPLAY_EVO_CTRL_DMA_ENABLED); if (!nv_wait(dev, NV50_PDISPLAY_EVO_CTRL(id), 0x80000000, 0x00000000)) { - NV_ERROR(dev, "timeout: (0x610200 & 0x80000000) == 0\n"); - NV_ERROR(dev, "0x610200 = 0x%08x\n", + NV_ERROR(dev, "EvoCh %d init timeout: 0x%08x\n", id, nv_rd32(dev, NV50_PDISPLAY_EVO_CTRL(id))); return -EBUSY; } - nv_wr32(dev, NV50_PDISPLAY_EVO_CTRL(id), - (nv_rd32(dev, NV50_PDISPLAY_EVO_CTRL(id)) & ~0x00000003) | - NV50_PDISPLAY_EVO_CTRL_DMA_ENABLED); - nv_wr32(dev, NV50_PDISPLAY_USER_PUT(id), 0); - nv_wr32(dev, NV50_PDISPLAY_EVO_CTRL(id), 0x01000003 | - NV50_PDISPLAY_EVO_CTRL_DMA_ENABLED); /* enable error reporting on the channel */ nv_mask(dev, 0x610028, 0x00000000, 0x00010001 << id); @@ -226,12 +202,15 @@ static void nv50_evo_channel_fini(struct nouveau_channel *evo) { struct drm_device *dev = evo->dev; - - nv_wr32(dev, NV50_PDISPLAY_EVO_CTRL(evo->id), 0); - if (!nv_wait(dev, NV50_PDISPLAY_EVO_CTRL(evo->id), 0x1e0000, 0)) { - NV_ERROR(dev, "timeout: (0x610200 & 0x1e0000) == 0\n"); - NV_ERROR(dev, "0x610200 = 0x%08x\n", - nv_rd32(dev, NV50_PDISPLAY_EVO_CTRL(evo->id))); + int id = evo->id; + + nv_mask(dev, 0x610028, 0x00010001 << id, 0x00000000); + nv_mask(dev, NV50_PDISPLAY_EVO_CTRL(id), 0x00001010, 0x00001000); + nv_wr32(dev, NV50_PDISPLAY_INTR_0, (1 << id)); + nv_mask(dev, NV50_PDISPLAY_EVO_CTRL(id), 0x00000003, 0x00000000); + if (!nv_wait(dev, NV50_PDISPLAY_EVO_CTRL(id), 0x001e0000, 0x00000000)) { + NV_ERROR(dev, "EvoCh %d takedown timeout: 0x%08x\n", id, + nv_rd32(dev, NV50_PDISPLAY_EVO_CTRL(id))); } } -- cgit v1.2.3 From 97e2000f757c19bb53e032320669f9a0d0b2a989 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 20 Oct 2010 14:23:29 +1000 Subject: drm/nv50: improve evo error handler when more than just channel 0 active Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_reg.h | 21 +++++++++--------- drivers/gpu/drm/nouveau/nv50_display.c | 40 +++++++++++++++++++--------------- drivers/gpu/drm/nouveau/nv50_graph.c | 11 +++++----- 3 files changed, 39 insertions(+), 33 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_reg.h b/drivers/gpu/drm/nouveau/nouveau_reg.h index d0ce86c24ebf..b6384d36d5d0 100644 --- a/drivers/gpu/drm/nouveau/nouveau_reg.h +++ b/drivers/gpu/drm/nouveau/nouveau_reg.h @@ -715,20 +715,21 @@ #define NV50_PDISPLAY_INTR_1_CLK_UNK10 0x00000010 #define NV50_PDISPLAY_INTR_1_CLK_UNK20 0x00000020 #define NV50_PDISPLAY_INTR_1_CLK_UNK40 0x00000040 -#define NV50_PDISPLAY_INTR_EN 0x0061002c -#define NV50_PDISPLAY_INTR_EN_VBLANK_CRTC 0x0000000c -#define NV50_PDISPLAY_INTR_EN_VBLANK_CRTC_(n) (1 << ((n) + 2)) -#define NV50_PDISPLAY_INTR_EN_VBLANK_CRTC_0 0x00000004 -#define NV50_PDISPLAY_INTR_EN_VBLANK_CRTC_1 0x00000008 -#define NV50_PDISPLAY_INTR_EN_CLK_UNK10 0x00000010 -#define NV50_PDISPLAY_INTR_EN_CLK_UNK20 0x00000020 -#define NV50_PDISPLAY_INTR_EN_CLK_UNK40 0x00000040 +#define NV50_PDISPLAY_INTR_EN_0 0x00610028 +#define NV50_PDISPLAY_INTR_EN_1 0x0061002c +#define NV50_PDISPLAY_INTR_EN_1_VBLANK_CRTC 0x0000000c +#define NV50_PDISPLAY_INTR_EN_1_VBLANK_CRTC_(n) (1 << ((n) + 2)) +#define NV50_PDISPLAY_INTR_EN_1_VBLANK_CRTC_0 0x00000004 +#define NV50_PDISPLAY_INTR_EN_1_VBLANK_CRTC_1 0x00000008 +#define NV50_PDISPLAY_INTR_EN_1_CLK_UNK10 0x00000010 +#define NV50_PDISPLAY_INTR_EN_1_CLK_UNK20 0x00000020 +#define NV50_PDISPLAY_INTR_EN_1_CLK_UNK40 0x00000040 #define NV50_PDISPLAY_UNK30_CTRL 0x00610030 #define NV50_PDISPLAY_UNK30_CTRL_UPDATE_VCLK0 0x00000200 #define NV50_PDISPLAY_UNK30_CTRL_UPDATE_VCLK1 0x00000400 #define NV50_PDISPLAY_UNK30_CTRL_PENDING 0x80000000 -#define NV50_PDISPLAY_TRAPPED_ADDR 0x00610080 -#define NV50_PDISPLAY_TRAPPED_DATA 0x00610084 +#define NV50_PDISPLAY_TRAPPED_ADDR(i) ((i) * 0x08 + 0x00610080) +#define NV50_PDISPLAY_TRAPPED_DATA(i) ((i) * 0x08 + 0x00610084) #define NV50_PDISPLAY_EVO_CTRL(i) ((i) * 0x10 + 0x00610200) #define NV50_PDISPLAY_EVO_CTRL_DMA 0x00000010 #define NV50_PDISPLAY_EVO_CTRL_DMA_DISABLED 0x00000000 diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c index db100a8f231e..99871e304d10 100644 --- a/drivers/gpu/drm/nouveau/nv50_display.c +++ b/drivers/gpu/drm/nouveau/nv50_display.c @@ -149,13 +149,13 @@ nv50_display_init(struct drm_device *dev) } nv_wr32(dev, NV50_PDISPLAY_PIO_CTRL, 0x00000000); - nv_wr32(dev, 0x610028, 0x00000000); nv_mask(dev, NV50_PDISPLAY_INTR_0, 0x00000000, 0x00000000); + nv_wr32(dev, NV50_PDISPLAY_INTR_EN_0, 0x00000000); nv_mask(dev, NV50_PDISPLAY_INTR_1, 0x00000000, 0x00000000); - nv_wr32(dev, NV50_PDISPLAY_INTR_EN, - NV50_PDISPLAY_INTR_EN_CLK_UNK10 | - NV50_PDISPLAY_INTR_EN_CLK_UNK20 | - NV50_PDISPLAY_INTR_EN_CLK_UNK40); + nv_wr32(dev, NV50_PDISPLAY_INTR_EN_1, + NV50_PDISPLAY_INTR_EN_1_CLK_UNK10 | + NV50_PDISPLAY_INTR_EN_1_CLK_UNK20 | + NV50_PDISPLAY_INTR_EN_1_CLK_UNK40); /* enable hotplug interrupts */ list_for_each_entry(connector, &dev->mode_config.connector_list, head) { @@ -248,7 +248,7 @@ static int nv50_display_disable(struct drm_device *dev) } /* disable interrupts. */ - nv_wr32(dev, NV50_PDISPLAY_INTR_EN, 0x00000000); + nv_wr32(dev, NV50_PDISPLAY_INTR_EN_1, 0x00000000); /* disable hotplug interrupts */ nv_wr32(dev, 0xe054, 0xffffffff); @@ -451,8 +451,7 @@ nv50_display_vblank_handler(struct drm_device *dev, uint32_t intr) if (intr & NV50_PDISPLAY_INTR_1_VBLANK_CRTC_1) nv50_display_vblank_crtc_handler(dev, 1); - nv_wr32(dev, NV50_PDISPLAY_INTR_EN, nv_rd32(dev, - NV50_PDISPLAY_INTR_EN) & ~intr); + nv_mask(dev, NV50_PDISPLAY_INTR_EN_1, intr, 0x00000000); nv_wr32(dev, NV50_PDISPLAY_INTR_1, intr); } @@ -779,16 +778,23 @@ nv50_display_irq_handler_bh(struct work_struct *work) static void nv50_display_error_handler(struct drm_device *dev) { - uint32_t addr, data; + u32 channels = (nv_rd32(dev, NV50_PDISPLAY_INTR_0) & 0x001f0000) >> 16; + u32 addr, data; + int chid; - nv_wr32(dev, NV50_PDISPLAY_INTR_0, 0x00010000); - addr = nv_rd32(dev, NV50_PDISPLAY_TRAPPED_ADDR); - data = nv_rd32(dev, NV50_PDISPLAY_TRAPPED_DATA); + for (chid = 0; chid < 5; chid++) { + if (!(channels & (1 << chid))) + continue; - NV_ERROR(dev, "EvoCh %d Mthd 0x%04x Data 0x%08x (0x%04x 0x%02x)\n", - 0, addr & 0xffc, data, addr >> 16, (addr >> 12) & 0xf); + nv_wr32(dev, NV50_PDISPLAY_INTR_0, 0x00010000 << chid); + addr = nv_rd32(dev, NV50_PDISPLAY_TRAPPED_ADDR(chid)); + data = nv_rd32(dev, NV50_PDISPLAY_TRAPPED_DATA(chid)); + NV_ERROR(dev, "EvoCh %d Mthd 0x%04x Data 0x%08x " + "(0x%04x 0x%02x)\n", chid, + addr & 0xffc, data, addr >> 16, (addr >> 12) & 0xf); - nv_wr32(dev, NV50_PDISPLAY_TRAPPED_ADDR, 0x90000000); + nv_wr32(dev, NV50_PDISPLAY_TRAPPED_ADDR(chid), 0x90000000); + } } void @@ -891,9 +897,9 @@ nv50_display_irq_handler(struct drm_device *dev) if (!intr0 && !(intr1 & ~delayed)) break; - if (intr0 & 0x00010000) { + if (intr0 & 0x001f0000) { nv50_display_error_handler(dev); - intr0 &= ~0x00010000; + intr0 &= ~0x001f0000; } if (intr1 & NV50_PDISPLAY_INTR_1_VBLANK_CRTC) { diff --git a/drivers/gpu/drm/nouveau/nv50_graph.c b/drivers/gpu/drm/nouveau/nv50_graph.c index a764af52a3ba..d441308a09cf 100644 --- a/drivers/gpu/drm/nouveau/nv50_graph.c +++ b/drivers/gpu/drm/nouveau/nv50_graph.c @@ -384,13 +384,12 @@ nv50_graph_nvsw_vblsem_release(struct nouveau_channel *chan, if (!chan->nvsw.vblsem || chan->nvsw.vblsem_offset == ~0 || data > 1) return -EINVAL; - if (!(nv_rd32(dev, NV50_PDISPLAY_INTR_EN) & - NV50_PDISPLAY_INTR_EN_VBLANK_CRTC_(data))) { + if (!(nv_rd32(dev, NV50_PDISPLAY_INTR_EN_1) & + NV50_PDISPLAY_INTR_EN_1_VBLANK_CRTC_(data))) { nv_wr32(dev, NV50_PDISPLAY_INTR_1, - NV50_PDISPLAY_INTR_1_VBLANK_CRTC_(data)); - nv_wr32(dev, NV50_PDISPLAY_INTR_EN, nv_rd32(dev, - NV50_PDISPLAY_INTR_EN) | - NV50_PDISPLAY_INTR_EN_VBLANK_CRTC_(data)); + NV50_PDISPLAY_INTR_1_VBLANK_CRTC_(data)); + nv_mask(dev, NV50_PDISPLAY_INTR_EN_1, 0, + NV50_PDISPLAY_INTR_EN_1_VBLANK_CRTC_(data)); } list_add(&chan->nvsw.vbl_wait, &dev_priv->vbl_waiting); -- cgit v1.2.3 From 8888cb18ffd1f32c51e61ca8d3d179c3c3946d1e Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 20 Oct 2010 15:35:28 +1000 Subject: drm/nv50: fix evo instmem alignment Not an issue right now, we're forced to 64k size/alignment by the BO allocator anyway. This won't be the case soon. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nv50_evo.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/nouveau/nv50_evo.c b/drivers/gpu/drm/nouveau/nv50_evo.c index d270f17a5310..887b2a97e2a2 100644 --- a/drivers/gpu/drm/nouveau/nv50_evo.c +++ b/drivers/gpu/drm/nouveau/nv50_evo.c @@ -234,7 +234,7 @@ nv50_evo_create(struct drm_device *dev) * use this also as there's no per-channel support on the * hardware */ - ret = nouveau_gpuobj_new(dev, NULL, 32768, 0x1000, + ret = nouveau_gpuobj_new(dev, NULL, 32768, 65536, NVOBJ_FLAG_ZERO_ALLOC, &evo->ramin); if (ret) { NV_ERROR(dev, "Error allocating EVO channel memory: %d\n", ret); -- cgit v1.2.3 From 01d63187d1aad6236dd229d5824c61a60f1ab42c Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Thu, 21 Oct 2010 11:37:21 +1000 Subject: drm/nv10: fix thinko and let nv17 do 3d again :) Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nv10_graph.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/nouveau/nv10_graph.c b/drivers/gpu/drm/nouveau/nv10_graph.c index 17c20dbff232..a571bfd4471b 100644 --- a/drivers/gpu/drm/nouveau/nv10_graph.c +++ b/drivers/gpu/drm/nouveau/nv10_graph.c @@ -1102,7 +1102,7 @@ nv10_graph_register(struct drm_device *dev) if (dev_priv->chipset <= 0x10) { NVOBJ_CLASS(dev, 0x0056, GR); } else - if (dev_priv->chipset <= 0x17 || dev_priv->chipset == 0x1a) { + if (dev_priv->chipset < 0x17 || dev_priv->chipset == 0x1a) { NVOBJ_CLASS(dev, 0x0096, GR); } else { NVOBJ_CLASS(dev, 0x0099, GR); -- cgit v1.2.3 From 35fa2f2ad161024e735fb0cd571cb92e50171afd Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Thu, 21 Oct 2010 14:07:03 +1000 Subject: drm/nouveau: add support for MSI Only supported on NV50+ so far, and disabled by default currently. The module parameter "msi=1" will enable it. There's a kernel bug which will cause this to fail if the module (or the NVIDIA binary driver) has ever been loaded before loading nouveau with MSI enabled. As such, this is only safe to enable if you have nouveau load on boot, and don't wish to ever reload it. The workaround is to "echo 0 > /sys/bus/pci/devices//enable" until the enable count reads 0. Then you should be able to load nouveau with MSI enabled. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_drv.c | 4 ++++ drivers/gpu/drm/nouveau/nouveau_drv.h | 5 +++++ drivers/gpu/drm/nouveau/nouveau_irq.c | 35 +++++++++++++++++++++++++++++++++ drivers/gpu/drm/nouveau/nouveau_state.c | 9 +++------ 4 files changed, 47 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.c b/drivers/gpu/drm/nouveau/nouveau_drv.c index 6dbb8818c530..db926ecf5b6f 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.c +++ b/drivers/gpu/drm/nouveau/nouveau_drv.c @@ -115,6 +115,10 @@ MODULE_PARM_DESC(perflvl_wr, "Allow perflvl changes (warning: dangerous!)\n"); int nouveau_perflvl_wr; module_param_named(perflvl_wr, nouveau_perflvl_wr, int, 0400); +MODULE_PARM_DESC(msi, "Enable MSI (default: off)\n"); +int nouveau_msi; +module_param_named(msi, nouveau_msi, int, 0400); + int nouveau_fbpercrtc; #if 0 module_param_named(fbpercrtc, nouveau_fbpercrtc, int, 0400); diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index bf34f25c7a54..9ab7dc8ede4e 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -593,6 +593,8 @@ struct drm_nouveau_private { struct nouveau_bo *vga_ram; + /* interrupt handling */ + bool msi_enabled; struct workqueue_struct *wq; struct work_struct irq_work; struct work_struct hpd_work; @@ -754,6 +756,7 @@ extern int nouveau_force_post; extern int nouveau_override_conntype; extern char *nouveau_perflvl; extern int nouveau_perflvl_wr; +extern int nouveau_msi; extern int nouveau_pci_suspend(struct pci_dev *pdev, pm_message_t pm_state); extern int nouveau_pci_resume(struct pci_dev *pdev); @@ -872,6 +875,8 @@ extern int nouveau_ioctl_gpuobj_free(struct drm_device *, void *data, struct drm_file *); /* nouveau_irq.c */ +extern int nouveau_irq_init(struct drm_device *); +extern void nouveau_irq_fini(struct drm_device *); extern irqreturn_t nouveau_irq_handler(DRM_IRQ_ARGS); extern void nouveau_irq_preinstall(struct drm_device *); extern int nouveau_irq_postinstall(struct drm_device *); diff --git a/drivers/gpu/drm/nouveau/nouveau_irq.c b/drivers/gpu/drm/nouveau/nouveau_irq.c index ca9b969f4f9c..17e2fa86cde7 100644 --- a/drivers/gpu/drm/nouveau/nouveau_irq.c +++ b/drivers/gpu/drm/nouveau/nouveau_irq.c @@ -68,8 +68,13 @@ nouveau_irq_preinstall(struct drm_device *dev) int nouveau_irq_postinstall(struct drm_device *dev) { + struct drm_nouveau_private *dev_priv = dev->dev_private; + /* Master enable */ nv_wr32(dev, NV03_PMC_INTR_EN_0, NV_PMC_INTR_EN_0_MASTER_ENABLE); + if (dev_priv->msi_enabled) + nv_wr08(dev, 0x00088068, 0xff); + return 0; } @@ -1263,5 +1268,35 @@ nouveau_irq_handler(DRM_IRQ_ARGS) spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags); + if (dev_priv->msi_enabled) + nv_wr08(dev, 0x00088068, 0xff); + return IRQ_HANDLED; } + +int +nouveau_irq_init(struct drm_device *dev) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + int ret; + + if (nouveau_msi != 0 && dev_priv->card_type >= NV_50) { + ret = pci_enable_msi(dev->pdev); + if (ret == 0) { + NV_INFO(dev, "enabled MSI\n"); + dev_priv->msi_enabled = true; + } + } + + return drm_irq_install(dev); +} + +void +nouveau_irq_fini(struct drm_device *dev) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + + drm_irq_uninstall(dev); + if (dev_priv->msi_enabled) + pci_disable_msi(dev->pdev); +} diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c index f13134aa8c4f..410a79f5e0cd 100644 --- a/drivers/gpu/drm/nouveau/nouveau_state.c +++ b/drivers/gpu/drm/nouveau/nouveau_state.c @@ -667,10 +667,7 @@ nouveau_card_init(struct drm_device *dev) if (ret) goto out_fifo; - /* this call irq_preinstall, register irq handler and - * call irq_postinstall - */ - ret = drm_irq_install(dev); + ret = nouveau_irq_init(dev); if (ret) goto out_display; @@ -701,7 +698,7 @@ nouveau_card_init(struct drm_device *dev) out_fence: nouveau_fence_fini(dev); out_irq: - drm_irq_uninstall(dev); + nouveau_irq_fini(dev); out_display: engine->display.destroy(dev); out_fifo: @@ -772,7 +769,7 @@ static void nouveau_card_takedown(struct drm_device *dev) nouveau_gpuobj_takedown(dev); nouveau_mem_vram_fini(dev); - drm_irq_uninstall(dev); + nouveau_irq_fini(dev); nouveau_pm_fini(dev); nouveau_bios_takedown(dev); -- cgit v1.2.3 From 5f80198e43cf96542923269ccb607052e5f144cc Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 22 Oct 2010 08:44:09 +1000 Subject: drm/nv50: regression fix, point NVAA/NVAC at correct PM functions Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_state.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c index 410a79f5e0cd..c5f29f0d18da 100644 --- a/drivers/gpu/drm/nouveau/nouveau_state.c +++ b/drivers/gpu/drm/nouveau/nouveau_state.c @@ -397,6 +397,8 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) case 0x96: case 0x98: case 0xa0: + case 0xaa: + case 0xac: case 0x50: engine->pm.clock_get = nv50_pm_clock_get; engine->pm.clock_pre = nv50_pm_clock_pre; -- cgit v1.2.3 From 382d62e524db528cdf53563ad9a018adc170dfde Mon Sep 17 00:00:00 2001 From: Marcin Slusarz Date: Wed, 20 Oct 2010 21:50:24 +0200 Subject: drm/nouveau: fix annoying nouveau_fence type issue nouveau_fence_* functions are not type safe, which could lead to bugs. Additionally every use of nouveau_fence_unref had to cast struct nouveau_fence to void **. Fix it by renaming old functions and creating static inline functions with new prototypes. We still need old functions, because we pass function pointers to ttm. As we are wrapping functions, drop unused "void *arg" parameter where possible. Signed-off-by: Marcin Slusarz Signed-off-by: Francisco Jerez Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_bo.c | 12 +++++------ drivers/gpu/drm/nouveau/nouveau_channel.c | 4 ++-- drivers/gpu/drm/nouveau/nouveau_drv.c | 4 ++-- drivers/gpu/drm/nouveau/nouveau_drv.h | 33 ++++++++++++++++++++++++++----- drivers/gpu/drm/nouveau/nouveau_fence.c | 22 ++++++++++----------- drivers/gpu/drm/nouveau/nouveau_gem.c | 4 ++-- drivers/gpu/drm/nouveau/nouveau_mem.c | 4 ++-- 7 files changed, 53 insertions(+), 30 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index 8442bfbf5d42..c09928322eb9 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c @@ -487,7 +487,7 @@ nouveau_bo_move_accel_cleanup(struct nouveau_channel *chan, ret = ttm_bo_move_accel_cleanup(&nvbo->bo, fence, NULL, evict, no_wait_reserve, no_wait_gpu, new_mem); - nouveau_fence_unref((void *)&fence); + nouveau_fence_unref(&fence); return ret; } @@ -949,11 +949,11 @@ struct ttm_bo_driver nouveau_bo_driver = { .evict_flags = nouveau_bo_evict_flags, .move = nouveau_bo_move, .verify_access = nouveau_bo_verify_access, - .sync_obj_signaled = nouveau_fence_signalled, - .sync_obj_wait = nouveau_fence_wait, - .sync_obj_flush = nouveau_fence_flush, - .sync_obj_unref = nouveau_fence_unref, - .sync_obj_ref = nouveau_fence_ref, + .sync_obj_signaled = __nouveau_fence_signalled, + .sync_obj_wait = __nouveau_fence_wait, + .sync_obj_flush = __nouveau_fence_flush, + .sync_obj_unref = __nouveau_fence_unref, + .sync_obj_ref = __nouveau_fence_ref, .fault_reserve_notify = &nouveau_ttm_fault_reserve_notify, .io_mem_reserve = &nouveau_ttm_io_mem_reserve, .io_mem_free = &nouveau_ttm_io_mem_free, diff --git a/drivers/gpu/drm/nouveau/nouveau_channel.c b/drivers/gpu/drm/nouveau/nouveau_channel.c index f2d674202369..c9cdbd786dae 100644 --- a/drivers/gpu/drm/nouveau/nouveau_channel.c +++ b/drivers/gpu/drm/nouveau/nouveau_channel.c @@ -303,8 +303,8 @@ nouveau_channel_put_unlocked(struct nouveau_channel **pchan) ret = nouveau_fence_new(chan, &fence, true); if (ret == 0) { - ret = nouveau_fence_wait(fence, NULL, false, false); - nouveau_fence_unref((void *)&fence); + ret = nouveau_fence_wait(fence, false, false); + nouveau_fence_unref(&fence); } if (ret) diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.c b/drivers/gpu/drm/nouveau/nouveau_drv.c index db926ecf5b6f..15f48493d0d8 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.c +++ b/drivers/gpu/drm/nouveau/nouveau_drv.c @@ -205,8 +205,8 @@ nouveau_pci_suspend(struct pci_dev *pdev, pm_message_t pm_state) ret = nouveau_fence_new(chan, &fence, true); if (ret == 0) { - ret = nouveau_fence_wait(fence, NULL, false, false); - nouveau_fence_unref((void *)&fence); + ret = nouveau_fence_wait(fence, false, false); + nouveau_fence_unref(&fence); } if (ret) { diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index 9ab7dc8ede4e..a356d894a2ee 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -1264,12 +1264,35 @@ extern void nouveau_fence_work(struct nouveau_fence *fence, void (*work)(void *priv, bool signalled), void *priv); struct nouveau_channel *nouveau_fence_channel(struct nouveau_fence *); -extern bool nouveau_fence_signalled(void *obj, void *arg); -extern int nouveau_fence_wait(void *obj, void *arg, bool lazy, bool intr); + +extern bool __nouveau_fence_signalled(void *obj, void *arg); +extern int __nouveau_fence_wait(void *obj, void *arg, bool lazy, bool intr); +extern int __nouveau_fence_flush(void *obj, void *arg); +extern void __nouveau_fence_unref(void **obj); +extern void *__nouveau_fence_ref(void *obj); + +static inline bool nouveau_fence_signalled(struct nouveau_fence *obj) +{ + return __nouveau_fence_signalled(obj, NULL); +} +static inline int +nouveau_fence_wait(struct nouveau_fence *obj, bool lazy, bool intr) +{ + return __nouveau_fence_wait(obj, NULL, lazy, intr); +} extern int nouveau_fence_sync(struct nouveau_fence *, struct nouveau_channel *); -extern int nouveau_fence_flush(void *obj, void *arg); -extern void nouveau_fence_unref(void **obj); -extern void *nouveau_fence_ref(void *obj); +static inline int nouveau_fence_flush(struct nouveau_fence *obj) +{ + return __nouveau_fence_flush(obj, NULL); +} +static inline void nouveau_fence_unref(struct nouveau_fence **obj) +{ + __nouveau_fence_unref((void **)obj); +} +static inline struct nouveau_fence *nouveau_fence_ref(struct nouveau_fence *obj) +{ + return __nouveau_fence_ref(obj); +} /* nouveau_gem.c */ extern int nouveau_gem_new(struct drm_device *, struct nouveau_channel *, diff --git a/drivers/gpu/drm/nouveau/nouveau_fence.c b/drivers/gpu/drm/nouveau/nouveau_fence.c index 75ce1b45d8a4..91aa6c54cc96 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fence.c +++ b/drivers/gpu/drm/nouveau/nouveau_fence.c @@ -120,7 +120,7 @@ nouveau_fence_new(struct nouveau_channel *chan, struct nouveau_fence **pfence, ret = nouveau_fence_emit(fence); if (ret) - nouveau_fence_unref((void *)&fence); + nouveau_fence_unref(&fence); *pfence = fence; return ret; } @@ -183,7 +183,7 @@ nouveau_fence_work(struct nouveau_fence *fence, } void -nouveau_fence_unref(void **sync_obj) +__nouveau_fence_unref(void **sync_obj) { struct nouveau_fence *fence = nouveau_fence(*sync_obj); @@ -193,7 +193,7 @@ nouveau_fence_unref(void **sync_obj) } void * -nouveau_fence_ref(void *sync_obj) +__nouveau_fence_ref(void *sync_obj) { struct nouveau_fence *fence = nouveau_fence(sync_obj); @@ -202,7 +202,7 @@ nouveau_fence_ref(void *sync_obj) } bool -nouveau_fence_signalled(void *sync_obj, void *sync_arg) +__nouveau_fence_signalled(void *sync_obj, void *sync_arg) { struct nouveau_fence *fence = nouveau_fence(sync_obj); struct nouveau_channel *chan = fence->channel; @@ -215,13 +215,13 @@ nouveau_fence_signalled(void *sync_obj, void *sync_arg) } int -nouveau_fence_wait(void *sync_obj, void *sync_arg, bool lazy, bool intr) +__nouveau_fence_wait(void *sync_obj, void *sync_arg, bool lazy, bool intr) { unsigned long timeout = jiffies + (3 * DRM_HZ); int ret = 0; while (1) { - if (nouveau_fence_signalled(sync_obj, sync_arg)) + if (__nouveau_fence_signalled(sync_obj, sync_arg)) break; if (time_after_eq(jiffies, timeout)) { @@ -369,7 +369,7 @@ emit_semaphore(struct nouveau_channel *chan, int method, kref_get(&sema->ref); nouveau_fence_work(fence, semaphore_work, sema); - nouveau_fence_unref((void *)&fence); + nouveau_fence_unref(&fence); return 0; } @@ -384,14 +384,14 @@ nouveau_fence_sync(struct nouveau_fence *fence, int ret = 0; if (likely(!chan || chan == wchan || - nouveau_fence_signalled(fence, NULL))) + nouveau_fence_signalled(fence))) goto out; sema = alloc_semaphore(dev); if (!sema) { /* Early card or broken userspace, fall back to * software sync. */ - ret = nouveau_fence_wait(fence, NULL, true, false); + ret = nouveau_fence_wait(fence, true, false); goto out; } @@ -400,7 +400,7 @@ nouveau_fence_sync(struct nouveau_fence *fence, * order issues */ if (!mutex_trylock(&chan->mutex)) { - ret = nouveau_fence_wait(fence, NULL, true, false); + ret = nouveau_fence_wait(fence, true, false); goto out_unref; } @@ -423,7 +423,7 @@ out: } int -nouveau_fence_flush(void *sync_obj, void *sync_arg) +__nouveau_fence_flush(void *sync_obj, void *sync_arg) { return 0; } diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c index 23b521ea8e04..de8535b58710 100644 --- a/drivers/gpu/drm/nouveau/nouveau_gem.c +++ b/drivers/gpu/drm/nouveau/nouveau_gem.c @@ -238,7 +238,7 @@ validate_fini_list(struct list_head *list, struct nouveau_fence *fence) prev_fence = nvbo->bo.sync_obj; nvbo->bo.sync_obj = nouveau_fence_ref(fence); spin_unlock(&nvbo->bo.bdev->fence_lock); - nouveau_fence_unref((void *)&prev_fence); + nouveau_fence_unref(&prev_fence); } if (unlikely(nvbo->validate_mapped)) { @@ -728,7 +728,7 @@ nouveau_gem_ioctl_pushbuf(struct drm_device *dev, void *data, out: validate_fini(&op, fence); - nouveau_fence_unref((void**)&fence); + nouveau_fence_unref(&fence); kfree(bo); kfree(push); diff --git a/drivers/gpu/drm/nouveau/nouveau_mem.c b/drivers/gpu/drm/nouveau/nouveau_mem.c index fe4a30dc4b42..a7c3e08aa7b5 100644 --- a/drivers/gpu/drm/nouveau/nouveau_mem.c +++ b/drivers/gpu/drm/nouveau/nouveau_mem.c @@ -54,7 +54,7 @@ nv10_mem_set_region_tiling(struct drm_device *dev, int i, uint32_t addr, tile->addr = addr; tile->size = size; tile->used = !!pitch; - nouveau_fence_unref((void **)&tile->fence); + nouveau_fence_unref(&tile->fence); pfifo->reassign(dev, false); pfifo->cache_pull(dev, false); @@ -87,7 +87,7 @@ nv10_mem_set_tiling(struct drm_device *dev, uint32_t addr, uint32_t size, continue; if (tile->fence && - !nouveau_fence_signalled(tile->fence, NULL)) + !nouveau_fence_signalled(tile->fence)) /* Pending tile region. */ continue; -- cgit v1.2.3 From 63f7fcfebd2ff1995b649101d6120b60fa0e5b06 Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Fri, 22 Oct 2010 04:31:02 +0200 Subject: drm/nv04: Make CRTC base changes effective in the next hsync. Signed-off-by: Francisco Jerez Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_hw.c | 2 +- drivers/gpu/drm/nouveau/nv04_crtc.c | 5 ++++- drivers/gpu/drm/nouveau/nvreg.h | 3 ++- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_hw.c b/drivers/gpu/drm/nouveau/nouveau_hw.c index b9672a05c411..979275836985 100644 --- a/drivers/gpu/drm/nouveau/nouveau_hw.c +++ b/drivers/gpu/drm/nouveau/nouveau_hw.c @@ -953,7 +953,7 @@ nv_load_state_ext(struct drm_device *dev, int head, NVWriteCRTC(dev, head, NV_PCRTC_850, regp->crtc_850); reg900 = NVReadRAMDAC(dev, head, NV_PRAMDAC_900); - if (regp->crtc_cfg == NV_PCRTC_CONFIG_START_ADDRESS_HSYNC) + if (regp->crtc_cfg == NV10_PCRTC_CONFIG_START_ADDRESS_HSYNC) NVWriteRAMDAC(dev, head, NV_PRAMDAC_900, reg900 | 0x10000); else NVWriteRAMDAC(dev, head, NV_PRAMDAC_900, reg900 & ~0x10000); diff --git a/drivers/gpu/drm/nouveau/nv04_crtc.c b/drivers/gpu/drm/nouveau/nv04_crtc.c index 40e180741629..b61a7ff8b7b7 100644 --- a/drivers/gpu/drm/nouveau/nv04_crtc.c +++ b/drivers/gpu/drm/nouveau/nv04_crtc.c @@ -551,7 +551,10 @@ nv_crtc_mode_set_regs(struct drm_crtc *crtc, struct drm_display_mode * mode) if (dev_priv->card_type >= NV_30) regp->gpio_ext = NVReadCRTC(dev, 0, NV_PCRTC_GPIO_EXT); - regp->crtc_cfg = NV_PCRTC_CONFIG_START_ADDRESS_HSYNC; + if (dev_priv->card_type >= NV_10) + regp->crtc_cfg = NV10_PCRTC_CONFIG_START_ADDRESS_HSYNC; + else + regp->crtc_cfg = NV04_PCRTC_CONFIG_START_ADDRESS_HSYNC; /* Some misc regs */ if (dev_priv->card_type == NV_40) { diff --git a/drivers/gpu/drm/nouveau/nvreg.h b/drivers/gpu/drm/nouveau/nvreg.h index 881f8a585613..fe0f253089ac 100644 --- a/drivers/gpu/drm/nouveau/nvreg.h +++ b/drivers/gpu/drm/nouveau/nvreg.h @@ -153,7 +153,8 @@ #define NV_PCRTC_START 0x00600800 #define NV_PCRTC_CONFIG 0x00600804 # define NV_PCRTC_CONFIG_START_ADDRESS_NON_VGA (1 << 0) -# define NV_PCRTC_CONFIG_START_ADDRESS_HSYNC (2 << 0) +# define NV04_PCRTC_CONFIG_START_ADDRESS_HSYNC (4 << 0) +# define NV10_PCRTC_CONFIG_START_ADDRESS_HSYNC (2 << 0) #define NV_PCRTC_CURSOR_CONFIG 0x00600810 # define NV_PCRTC_CURSOR_CONFIG_ENABLE_ENABLE (1 << 0) # define NV_PCRTC_CURSOR_CONFIG_DOUBLE_SCAN_ENABLE (1 << 4) -- cgit v1.2.3 From 042206c0cd4924879c4292c5ffa2bf1e8023ae5a Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Thu, 21 Oct 2010 18:19:29 +0200 Subject: drm/nouveau: Implement the vblank DRM hooks. Signed-off-by: Francisco Jerez Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_display.c | 27 +++++++++++++++++++++++++++ drivers/gpu/drm/nouveau/nouveau_drv.c | 4 ++++ drivers/gpu/drm/nouveau/nouveau_drv.h | 4 ++++ drivers/gpu/drm/nouveau/nouveau_hw.c | 5 +++-- drivers/gpu/drm/nouveau/nouveau_irq.c | 8 ++++++-- drivers/gpu/drm/nouveau/nouveau_state.c | 12 +++++++----- drivers/gpu/drm/nouveau/nv50_display.c | 16 +++++++--------- drivers/gpu/drm/nouveau/nv50_graph.c | 9 +-------- 8 files changed, 59 insertions(+), 26 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c index 2e11fd65b4dd..f8987bcb7f51 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.c +++ b/drivers/gpu/drm/nouveau/nouveau_display.c @@ -29,6 +29,7 @@ #include "nouveau_drv.h" #include "nouveau_fb.h" #include "nouveau_fbcon.h" +#include "nouveau_hw.h" static void nouveau_user_framebuffer_destroy(struct drm_framebuffer *drm_fb) @@ -104,3 +105,29 @@ const struct drm_mode_config_funcs nouveau_mode_config_funcs = { .output_poll_changed = nouveau_fbcon_output_poll_changed, }; +int +nouveau_vblank_enable(struct drm_device *dev, int crtc) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + + if (dev_priv->card_type >= NV_50) + nv_mask(dev, NV50_PDISPLAY_INTR_EN_1, 0, + NV50_PDISPLAY_INTR_EN_1_VBLANK_CRTC_(crtc)); + else + NVWriteCRTC(dev, crtc, NV_PCRTC_INTR_EN_0, + NV_PCRTC_INTR_0_VBLANK); + + return 0; +} + +void +nouveau_vblank_disable(struct drm_device *dev, int crtc) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + + if (dev_priv->card_type >= NV_50) + nv_mask(dev, NV50_PDISPLAY_INTR_EN_1, + NV50_PDISPLAY_INTR_EN_1_VBLANK_CRTC_(crtc), 0); + else + NVWriteCRTC(dev, crtc, NV_PCRTC_INTR_EN_0, 0); +} diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.c b/drivers/gpu/drm/nouveau/nouveau_drv.c index 15f48493d0d8..52f9307d7396 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.c +++ b/drivers/gpu/drm/nouveau/nouveau_drv.c @@ -397,6 +397,9 @@ static struct drm_driver driver = { .irq_postinstall = nouveau_irq_postinstall, .irq_uninstall = nouveau_irq_uninstall, .irq_handler = nouveau_irq_handler, + .get_vblank_counter = drm_vblank_count, + .enable_vblank = nouveau_vblank_enable, + .disable_vblank = nouveau_vblank_disable, .reclaim_buffers = drm_core_reclaim_buffers, .ioctls = nouveau_ioctls, .fops = { @@ -407,6 +410,7 @@ static struct drm_driver driver = { .mmap = nouveau_ttm_mmap, .poll = drm_poll, .fasync = drm_fasync, + .read = drm_read, #if defined(CONFIG_COMPAT) .compat_ioctl = nouveau_compat_ioctl, #endif diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index a356d894a2ee..7cf034fd5cd0 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -1312,6 +1312,10 @@ extern int nouveau_gem_ioctl_cpu_fini(struct drm_device *, void *, extern int nouveau_gem_ioctl_info(struct drm_device *, void *, struct drm_file *); +/* nouveau_display.c */ +int nouveau_vblank_enable(struct drm_device *dev, int crtc); +void nouveau_vblank_disable(struct drm_device *dev, int crtc); + /* nv10_gpio.c */ int nv10_gpio_get(struct drm_device *dev, enum dcb_gpio_tag tag); int nv10_gpio_set(struct drm_device *dev, enum dcb_gpio_tag tag, int state); diff --git a/drivers/gpu/drm/nouveau/nouveau_hw.c b/drivers/gpu/drm/nouveau/nouveau_hw.c index 979275836985..6ba640e7a7e9 100644 --- a/drivers/gpu/drm/nouveau/nouveau_hw.c +++ b/drivers/gpu/drm/nouveau/nouveau_hw.c @@ -1017,8 +1017,9 @@ nv_load_state_ext(struct drm_device *dev, int head, NVWriteCRTC(dev, head, NV_PCRTC_START, regp->fb_start); - /* Setting 1 on this value gives you interrupts for every vblank period. */ - NVWriteCRTC(dev, head, NV_PCRTC_INTR_EN_0, 0); + /* Enable vblank interrupts. */ + NVWriteCRTC(dev, head, NV_PCRTC_INTR_EN_0, + (dev->vblank_enabled[head] ? 1 : 0)); NVWriteCRTC(dev, head, NV_PCRTC_INTR_0, NV_PCRTC_INTR_0_VBLANK); } diff --git a/drivers/gpu/drm/nouveau/nouveau_irq.c b/drivers/gpu/drm/nouveau/nouveau_irq.c index 17e2fa86cde7..f3ae74ef3318 100644 --- a/drivers/gpu/drm/nouveau/nouveau_irq.c +++ b/drivers/gpu/drm/nouveau/nouveau_irq.c @@ -1200,11 +1200,15 @@ nv50_pgraph_irq_handler(struct drm_device *dev) static void nouveau_crtc_irq_handler(struct drm_device *dev, int crtc) { - if (crtc & 1) + if (crtc & 1) { nv_wr32(dev, NV_CRTC0_INTSTAT, NV_CRTC_INTR_VBLANK); + drm_handle_vblank(dev, 0); + } - if (crtc & 2) + if (crtc & 2) { nv_wr32(dev, NV_CRTC1_INTSTAT, NV_CRTC_INTR_VBLANK); + drm_handle_vblank(dev, 1); + } } irqreturn_t diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c index c5f29f0d18da..d72aa8d19a19 100644 --- a/drivers/gpu/drm/nouveau/nouveau_state.c +++ b/drivers/gpu/drm/nouveau/nouveau_state.c @@ -669,13 +669,13 @@ nouveau_card_init(struct drm_device *dev) if (ret) goto out_fifo; - ret = nouveau_irq_init(dev); + ret = drm_vblank_init(dev, nv_two_heads(dev) ? 2 : 1); if (ret) - goto out_display; + goto out_vblank; - ret = drm_vblank_init(dev, 0); + ret = nouveau_irq_init(dev); if (ret) - goto out_irq; + goto out_vblank; /* what about PVIDEO/PCRTC/PRAMDAC etc? */ @@ -701,7 +701,8 @@ out_fence: nouveau_fence_fini(dev); out_irq: nouveau_irq_fini(dev); -out_display: +out_vblank: + drm_vblank_cleanup(dev); engine->display.destroy(dev); out_fifo: if (!nouveau_noaccel) @@ -772,6 +773,7 @@ static void nouveau_card_takedown(struct drm_device *dev) nouveau_mem_vram_fini(dev); nouveau_irq_fini(dev); + drm_vblank_cleanup(dev); nouveau_pm_fini(dev); nouveau_bios_takedown(dev); diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c index 99871e304d10..17b950abf200 100644 --- a/drivers/gpu/drm/nouveau/nv50_display.c +++ b/drivers/gpu/drm/nouveau/nv50_display.c @@ -428,31 +428,29 @@ static void nv50_display_vblank_crtc_handler(struct drm_device *dev, int crtc) { struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_channel *chan; - struct list_head *entry, *tmp; - - list_for_each_safe(entry, tmp, &dev_priv->vbl_waiting) { - chan = list_entry(entry, struct nouveau_channel, nvsw.vbl_wait); + struct nouveau_channel *chan, *tmp; + list_for_each_entry_safe(chan, tmp, &dev_priv->vbl_waiting, + nvsw.vbl_wait) { nouveau_bo_wr32(chan->notifier_bo, chan->nvsw.vblsem_offset, chan->nvsw.vblsem_rval); list_del(&chan->nvsw.vbl_wait); + drm_vblank_put(dev, crtc); } + + drm_handle_vblank(dev, crtc); } static void nv50_display_vblank_handler(struct drm_device *dev, uint32_t intr) { - intr &= NV50_PDISPLAY_INTR_1_VBLANK_CRTC; - if (intr & NV50_PDISPLAY_INTR_1_VBLANK_CRTC_0) nv50_display_vblank_crtc_handler(dev, 0); if (intr & NV50_PDISPLAY_INTR_1_VBLANK_CRTC_1) nv50_display_vblank_crtc_handler(dev, 1); - nv_mask(dev, NV50_PDISPLAY_INTR_EN_1, intr, 0x00000000); - nv_wr32(dev, NV50_PDISPLAY_INTR_1, intr); + nv_wr32(dev, NV50_PDISPLAY_INTR_1, NV50_PDISPLAY_INTR_1_VBLANK_CRTC); } static void diff --git a/drivers/gpu/drm/nouveau/nv50_graph.c b/drivers/gpu/drm/nouveau/nv50_graph.c index d441308a09cf..ac7f62d524bb 100644 --- a/drivers/gpu/drm/nouveau/nv50_graph.c +++ b/drivers/gpu/drm/nouveau/nv50_graph.c @@ -384,14 +384,7 @@ nv50_graph_nvsw_vblsem_release(struct nouveau_channel *chan, if (!chan->nvsw.vblsem || chan->nvsw.vblsem_offset == ~0 || data > 1) return -EINVAL; - if (!(nv_rd32(dev, NV50_PDISPLAY_INTR_EN_1) & - NV50_PDISPLAY_INTR_EN_1_VBLANK_CRTC_(data))) { - nv_wr32(dev, NV50_PDISPLAY_INTR_1, - NV50_PDISPLAY_INTR_1_VBLANK_CRTC_(data)); - nv_mask(dev, NV50_PDISPLAY_INTR_EN_1, 0, - NV50_PDISPLAY_INTR_EN_1_VBLANK_CRTC_(data)); - } - + drm_vblank_get(dev, data); list_add(&chan->nvsw.vbl_wait, &dev_priv->vbl_waiting); return 0; } -- cgit v1.2.3 From 332b242f47786d1a43bd7a19a0513dd5d493db8e Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Wed, 20 Oct 2010 23:35:40 +0200 Subject: drm/nouveau: Implement the pageflip ioctl. nv0x-nv4x should be mostly fine, nv50 doesn't work yet. Signed-off-by: Francisco Jerez Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_bo.c | 12 ++ drivers/gpu/drm/nouveau/nouveau_channel.c | 1 + drivers/gpu/drm/nouveau/nouveau_display.c | 180 ++++++++++++++++++++++++++++++ drivers/gpu/drm/nouveau/nouveau_drv.h | 16 +++ drivers/gpu/drm/nouveau/nouveau_gem.c | 11 +- drivers/gpu/drm/nouveau/nouveau_state.c | 3 + drivers/gpu/drm/nouveau/nv04_crtc.c | 1 + drivers/gpu/drm/nouveau/nv04_graph.c | 16 +++ drivers/gpu/drm/nouveau/nv10_graph.c | 4 + drivers/gpu/drm/nouveau/nv20_graph.c | 8 ++ drivers/gpu/drm/nouveau/nv40_graph.c | 4 + drivers/gpu/drm/nouveau/nv50_crtc.c | 1 + drivers/gpu/drm/nouveau/nv50_graph.c | 16 +++ include/drm/nouveau_drm.h | 1 + 14 files changed, 265 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index c09928322eb9..cdc8f544d47f 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c @@ -942,6 +942,18 @@ nouveau_ttm_fault_reserve_notify(struct ttm_buffer_object *bo) return ttm_bo_validate(bo, &nvbo->placement, false, true, false); } +void +nouveau_bo_fence(struct nouveau_bo *nvbo, struct nouveau_fence *fence) +{ + spin_lock(&nvbo->bo.bdev->fence_lock); + __nouveau_fence_unref(&nvbo->bo.sync_obj); + + if (likely(fence)) + nvbo->bo.sync_obj = nouveau_fence_ref(fence); + + spin_unlock(&nvbo->bo.bdev->fence_lock); +} + struct ttm_bo_driver nouveau_bo_driver = { .create_ttm_backend_entry = nouveau_bo_create_ttm_backend_entry, .invalidate_caches = nouveau_bo_invalidate_caches, diff --git a/drivers/gpu/drm/nouveau/nouveau_channel.c b/drivers/gpu/drm/nouveau/nouveau_channel.c index c9cdbd786dae..11b2370e16da 100644 --- a/drivers/gpu/drm/nouveau/nouveau_channel.c +++ b/drivers/gpu/drm/nouveau/nouveau_channel.c @@ -148,6 +148,7 @@ nouveau_channel_alloc(struct drm_device *dev, struct nouveau_channel **chan_ret, NV_DEBUG(dev, "initialising channel %d\n", chan->id); INIT_LIST_HEAD(&chan->nvsw.vbl_wait); + INIT_LIST_HEAD(&chan->nvsw.flip); INIT_LIST_HEAD(&chan->fence.pending); /* Allocate DMA push buffer */ diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c index f8987bcb7f51..505c6bfb4d75 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.c +++ b/drivers/gpu/drm/nouveau/nouveau_display.c @@ -30,6 +30,8 @@ #include "nouveau_fb.h" #include "nouveau_fbcon.h" #include "nouveau_hw.h" +#include "nouveau_crtc.h" +#include "nouveau_dma.h" static void nouveau_user_framebuffer_destroy(struct drm_framebuffer *drm_fb) @@ -131,3 +133,181 @@ nouveau_vblank_disable(struct drm_device *dev, int crtc) else NVWriteCRTC(dev, crtc, NV_PCRTC_INTR_EN_0, 0); } + +static int +nouveau_page_flip_reserve(struct nouveau_bo *old_bo, + struct nouveau_bo *new_bo) +{ + int ret; + + ret = nouveau_bo_pin(new_bo, TTM_PL_FLAG_VRAM); + if (ret) + return ret; + + ret = ttm_bo_reserve(&new_bo->bo, false, false, false, 0); + if (ret) + goto fail; + + ret = ttm_bo_reserve(&old_bo->bo, false, false, false, 0); + if (ret) + goto fail_unreserve; + + return 0; + +fail_unreserve: + ttm_bo_unreserve(&new_bo->bo); +fail: + nouveau_bo_unpin(new_bo); + return ret; +} + +static void +nouveau_page_flip_unreserve(struct nouveau_bo *old_bo, + struct nouveau_bo *new_bo, + struct nouveau_fence *fence) +{ + nouveau_bo_fence(new_bo, fence); + ttm_bo_unreserve(&new_bo->bo); + + nouveau_bo_fence(old_bo, fence); + ttm_bo_unreserve(&old_bo->bo); + + nouveau_bo_unpin(old_bo); +} + +static int +nouveau_page_flip_emit(struct nouveau_channel *chan, + struct nouveau_bo *old_bo, + struct nouveau_bo *new_bo, + struct nouveau_page_flip_state *s, + struct nouveau_fence **pfence) +{ + struct drm_device *dev = chan->dev; + unsigned long flags; + int ret; + + /* Queue it to the pending list */ + spin_lock_irqsave(&dev->event_lock, flags); + list_add_tail(&s->head, &chan->nvsw.flip); + spin_unlock_irqrestore(&dev->event_lock, flags); + + /* Synchronize with the old framebuffer */ + ret = nouveau_fence_sync(old_bo->bo.sync_obj, chan); + if (ret) + goto fail; + + /* Emit the pageflip */ + ret = RING_SPACE(chan, 2); + if (ret) + goto fail; + + BEGIN_RING(chan, NvSubSw, NV_SW_PAGE_FLIP, 1); + OUT_RING(chan, 0); + FIRE_RING(chan); + + ret = nouveau_fence_new(chan, pfence, true); + if (ret) + goto fail; + + return 0; +fail: + spin_lock_irqsave(&dev->event_lock, flags); + list_del(&s->head); + spin_unlock_irqrestore(&dev->event_lock, flags); + return ret; +} + +int +nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb, + struct drm_pending_vblank_event *event) +{ + struct drm_device *dev = crtc->dev; + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_bo *old_bo = nouveau_framebuffer(crtc->fb)->nvbo; + struct nouveau_bo *new_bo = nouveau_framebuffer(fb)->nvbo; + struct nouveau_page_flip_state *s; + struct nouveau_channel *chan; + struct nouveau_fence *fence; + int ret; + + if (dev_priv->engine.graph.accel_blocked) + return -ENODEV; + + s = kzalloc(sizeof(*s), GFP_KERNEL); + if (!s) + return -ENOMEM; + + /* Don't let the buffers go away while we flip */ + ret = nouveau_page_flip_reserve(old_bo, new_bo); + if (ret) + goto fail_free; + + /* Initialize a page flip struct */ + *s = (struct nouveau_page_flip_state) + { { }, s->event, nouveau_crtc(crtc)->index, + fb->bits_per_pixel, fb->pitch, crtc->x, crtc->y, + new_bo->bo.offset }; + + /* Choose the channel the flip will be handled in */ + chan = nouveau_fence_channel(new_bo->bo.sync_obj); + if (!chan) + chan = nouveau_channel_get_unlocked(dev_priv->channel); + mutex_lock(&chan->mutex); + + /* Emit a page flip */ + ret = nouveau_page_flip_emit(chan, old_bo, new_bo, s, &fence); + nouveau_channel_put(&chan); + if (ret) + goto fail_unreserve; + + /* Update the crtc struct and cleanup */ + crtc->fb = fb; + + nouveau_page_flip_unreserve(old_bo, new_bo, fence); + nouveau_fence_unref(&fence); + return 0; + +fail_unreserve: + nouveau_page_flip_unreserve(old_bo, new_bo, NULL); +fail_free: + kfree(s); + return ret; +} + +int +nouveau_finish_page_flip(struct nouveau_channel *chan, + struct nouveau_page_flip_state *ps) +{ + struct drm_device *dev = chan->dev; + struct nouveau_page_flip_state *s; + unsigned long flags; + + spin_lock_irqsave(&dev->event_lock, flags); + + if (list_empty(&chan->nvsw.flip)) { + NV_ERROR(dev, "Unexpected pageflip in channel %d.\n", chan->id); + spin_unlock_irqrestore(&dev->event_lock, flags); + return -EINVAL; + } + + s = list_first_entry(&chan->nvsw.flip, + struct nouveau_page_flip_state, head); + if (s->event) { + struct drm_pending_vblank_event *e = s->event; + struct timeval now; + + do_gettimeofday(&now); + e->event.sequence = 0; + e->event.tv_sec = now.tv_sec; + e->event.tv_usec = now.tv_usec; + list_add_tail(&e->base.link, &e->base.file_priv->event_list); + wake_up_interruptible(&e->base.file_priv->event_wait); + } + + list_del(&s->head); + *ps = *s; + kfree(s); + + spin_unlock_irqrestore(&dev->event_lock, flags); + return 0; +} diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index 7cf034fd5cd0..2bb1f1572a55 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -166,6 +166,13 @@ struct nouveau_gpuobj { void *priv; }; +struct nouveau_page_flip_state { + struct list_head head; + struct drm_pending_vblank_event *event; + int crtc, bpp, pitch, x, y; + uint64_t offset; +}; + struct nouveau_channel { struct drm_device *dev; int id; @@ -253,6 +260,7 @@ struct nouveau_channel { uint32_t vblsem_offset; uint32_t vblsem_rval; struct list_head vbl_wait; + struct list_head flip; } nvsw; struct { @@ -1076,6 +1084,8 @@ extern void nv04_graph_destroy_context(struct nouveau_channel *); extern int nv04_graph_load_context(struct nouveau_channel *); extern int nv04_graph_unload_context(struct drm_device *); extern void nv04_graph_context_switch(struct drm_device *); +extern int nv04_graph_mthd_page_flip(struct nouveau_channel *chan, + u32 class, u32 mthd, u32 data); /* nv10_graph.c */ extern int nv10_graph_init(struct drm_device *); @@ -1249,6 +1259,7 @@ extern u16 nouveau_bo_rd16(struct nouveau_bo *nvbo, unsigned index); extern void nouveau_bo_wr16(struct nouveau_bo *nvbo, unsigned index, u16 val); extern u32 nouveau_bo_rd32(struct nouveau_bo *nvbo, unsigned index); extern void nouveau_bo_wr32(struct nouveau_bo *nvbo, unsigned index, u32 val); +extern void nouveau_bo_fence(struct nouveau_bo *, struct nouveau_fence *); /* nouveau_fence.c */ struct nouveau_fence; @@ -1315,6 +1326,10 @@ extern int nouveau_gem_ioctl_info(struct drm_device *, void *, /* nouveau_display.c */ int nouveau_vblank_enable(struct drm_device *dev, int crtc); void nouveau_vblank_disable(struct drm_device *dev, int crtc); +int nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb, + struct drm_pending_vblank_event *event); +int nouveau_finish_page_flip(struct nouveau_channel *, + struct nouveau_page_flip_state *); /* nv10_gpio.c */ int nv10_gpio_get(struct drm_device *dev, enum dcb_gpio_tag tag); @@ -1514,5 +1529,6 @@ nv_match_device(struct drm_device *dev, unsigned device, #define NV_SW_VBLSEM_OFFSET 0x00000400 #define NV_SW_VBLSEM_RELEASE_VALUE 0x00000404 #define NV_SW_VBLSEM_RELEASE 0x00000408 +#define NV_SW_PAGE_FLIP 0x00000500 #endif /* __NOUVEAU_DRV_H__ */ diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c index de8535b58710..9886b644f27d 100644 --- a/drivers/gpu/drm/nouveau/nouveau_gem.c +++ b/drivers/gpu/drm/nouveau/nouveau_gem.c @@ -231,15 +231,8 @@ validate_fini_list(struct list_head *list, struct nouveau_fence *fence) list_for_each_safe(entry, tmp, list) { nvbo = list_entry(entry, struct nouveau_bo, entry); - if (likely(fence)) { - struct nouveau_fence *prev_fence; - - spin_lock(&nvbo->bo.bdev->fence_lock); - prev_fence = nvbo->bo.sync_obj; - nvbo->bo.sync_obj = nouveau_fence_ref(fence); - spin_unlock(&nvbo->bo.bdev->fence_lock); - nouveau_fence_unref(&prev_fence); - } + + nouveau_bo_fence(nvbo, fence); if (unlikely(nvbo->validate_mapped)) { ttm_bo_kunmap(&nvbo->kmap); diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c index d72aa8d19a19..ec9d193b6f61 100644 --- a/drivers/gpu/drm/nouveau/nouveau_state.c +++ b/drivers/gpu/drm/nouveau/nouveau_state.c @@ -1090,6 +1090,9 @@ int nouveau_ioctl_getparam(struct drm_device *dev, void *data, case NOUVEAU_GETPARAM_HAS_BO_USAGE: getparam->value = 1; break; + case NOUVEAU_GETPARAM_HAS_PAGEFLIP: + getparam->value = (dev_priv->card_type < NV_50); + break; case NOUVEAU_GETPARAM_GRAPH_UNITS: /* NV40 and NV50 versions are quite different, but register * address is the same. User is supposed to know the card diff --git a/drivers/gpu/drm/nouveau/nv04_crtc.c b/drivers/gpu/drm/nouveau/nv04_crtc.c index b61a7ff8b7b7..e4aea721971f 100644 --- a/drivers/gpu/drm/nouveau/nv04_crtc.c +++ b/drivers/gpu/drm/nouveau/nv04_crtc.c @@ -989,6 +989,7 @@ static const struct drm_crtc_funcs nv04_crtc_funcs = { .cursor_move = nv04_crtc_cursor_move, .gamma_set = nv_crtc_gamma_set, .set_config = drm_crtc_helper_set_config, + .page_flip = nouveau_crtc_page_flip, .destroy = nv_crtc_destroy, }; diff --git a/drivers/gpu/drm/nouveau/nv04_graph.c b/drivers/gpu/drm/nouveau/nv04_graph.c index 81aba097ef95..239519aefce6 100644 --- a/drivers/gpu/drm/nouveau/nv04_graph.c +++ b/drivers/gpu/drm/nouveau/nv04_graph.c @@ -26,6 +26,7 @@ #include "drm.h" #include "nouveau_drm.h" #include "nouveau_drv.h" +#include "nouveau_hw.h" static int nv04_graph_register(struct drm_device *dev); @@ -553,6 +554,20 @@ nv04_graph_mthd_set_ref(struct nouveau_channel *chan, return 0; } +int +nv04_graph_mthd_page_flip(struct nouveau_channel *chan, + u32 class, u32 mthd, u32 data) +{ + struct drm_device *dev = chan->dev; + struct nouveau_page_flip_state s; + + if (!nouveau_finish_page_flip(chan, &s)) + nv_set_crtc_base(dev, s.crtc, + s.offset + s.y * s.pitch + s.x * s.bpp / 8); + + return 0; +} + /* * Software methods, why they are needed, and how they all work: * @@ -1204,6 +1219,7 @@ nv04_graph_register(struct drm_device *dev) /* nvsw */ NVOBJ_CLASS(dev, 0x506e, SW); NVOBJ_MTHD (dev, 0x506e, 0x0150, nv04_graph_mthd_set_ref); + NVOBJ_MTHD (dev, 0x506e, 0x0500, nv04_graph_mthd_page_flip); dev_priv->engine.graph.registered = true; return 0; diff --git a/drivers/gpu/drm/nouveau/nv10_graph.c b/drivers/gpu/drm/nouveau/nv10_graph.c index a571bfd4471b..3fbb49dfc09c 100644 --- a/drivers/gpu/drm/nouveau/nv10_graph.c +++ b/drivers/gpu/drm/nouveau/nv10_graph.c @@ -1113,6 +1113,10 @@ nv10_graph_register(struct drm_device *dev) NVOBJ_MTHD (dev, 0x0099, 0x1658, nv17_graph_mthd_lma_enable); } + /* nvsw */ + NVOBJ_CLASS(dev, 0x506e, SW); + NVOBJ_MTHD (dev, 0x506e, 0x0500, nv04_graph_mthd_page_flip); + dev_priv->engine.graph.registered = true; return 0; } diff --git a/drivers/gpu/drm/nouveau/nv20_graph.c b/drivers/gpu/drm/nouveau/nv20_graph.c index 7720bccb3c98..51b9dd12949d 100644 --- a/drivers/gpu/drm/nouveau/nv20_graph.c +++ b/drivers/gpu/drm/nouveau/nv20_graph.c @@ -801,6 +801,10 @@ nv20_graph_register(struct drm_device *dev) else NVOBJ_CLASS(dev, 0x0597, GR); + /* nvsw */ + NVOBJ_CLASS(dev, 0x506e, SW); + NVOBJ_MTHD (dev, 0x506e, 0x0500, nv04_graph_mthd_page_flip); + dev_priv->engine.graph.registered = true; return 0; } @@ -841,6 +845,10 @@ nv30_graph_register(struct drm_device *dev) if (0x000001e0 & (1 << (dev_priv->chipset & 0x0f))) NVOBJ_CLASS(dev, 0x0497, GR); + /* nvsw */ + NVOBJ_CLASS(dev, 0x506e, SW); + NVOBJ_MTHD (dev, 0x506e, 0x0500, nv04_graph_mthd_page_flip); + dev_priv->engine.graph.registered = true; return 0; } diff --git a/drivers/gpu/drm/nouveau/nv40_graph.c b/drivers/gpu/drm/nouveau/nv40_graph.c index b9361e28687c..159bdcd757d4 100644 --- a/drivers/gpu/drm/nouveau/nv40_graph.c +++ b/drivers/gpu/drm/nouveau/nv40_graph.c @@ -446,6 +446,10 @@ nv40_graph_register(struct drm_device *dev) else NVOBJ_CLASS(dev, 0x4097, GR); + /* nvsw */ + NVOBJ_CLASS(dev, 0x506e, SW); + NVOBJ_MTHD (dev, 0x506e, 0x0500, nv04_graph_mthd_page_flip); + dev_priv->engine.graph.registered = true; return 0; } diff --git a/drivers/gpu/drm/nouveau/nv50_crtc.c b/drivers/gpu/drm/nouveau/nv50_crtc.c index 56476d0c6de8..1225ea0a841b 100644 --- a/drivers/gpu/drm/nouveau/nv50_crtc.c +++ b/drivers/gpu/drm/nouveau/nv50_crtc.c @@ -437,6 +437,7 @@ static const struct drm_crtc_funcs nv50_crtc_funcs = { .cursor_move = nv50_crtc_cursor_move, .gamma_set = nv50_crtc_gamma_set, .set_config = drm_crtc_helper_set_config, + .page_flip = nouveau_crtc_page_flip, .destroy = nv50_crtc_destroy, }; diff --git a/drivers/gpu/drm/nouveau/nv50_graph.c b/drivers/gpu/drm/nouveau/nv50_graph.c index ac7f62d524bb..6d81f4dab37d 100644 --- a/drivers/gpu/drm/nouveau/nv50_graph.c +++ b/drivers/gpu/drm/nouveau/nv50_graph.c @@ -29,6 +29,8 @@ #include "nouveau_drv.h" #include "nouveau_ramht.h" #include "nouveau_grctx.h" +#include "nouveau_dma.h" +#include "nv50_evo.h" static int nv50_graph_register(struct drm_device *); @@ -389,6 +391,19 @@ nv50_graph_nvsw_vblsem_release(struct nouveau_channel *chan, return 0; } +static int +nv50_graph_nvsw_mthd_page_flip(struct nouveau_channel *chan, + u32 class, u32 mthd, u32 data) +{ + struct nouveau_page_flip_state s; + + if (!nouveau_finish_page_flip(chan, &s)) { + /* XXX - Do something here */ + } + + return 0; +} + static int nv50_graph_register(struct drm_device *dev) { @@ -402,6 +417,7 @@ nv50_graph_register(struct drm_device *dev) NVOBJ_MTHD (dev, 0x506e, 0x0400, nv50_graph_nvsw_vblsem_offset); NVOBJ_MTHD (dev, 0x506e, 0x0404, nv50_graph_nvsw_vblsem_release_val); NVOBJ_MTHD (dev, 0x506e, 0x0408, nv50_graph_nvsw_vblsem_release); + NVOBJ_MTHD (dev, 0x506e, 0x0500, nv50_graph_nvsw_mthd_page_flip); NVOBJ_CLASS(dev, 0x0030, GR); /* null */ NVOBJ_CLASS(dev, 0x5039, GR); /* m2mf */ diff --git a/include/drm/nouveau_drm.h b/include/drm/nouveau_drm.h index 60a7b3e9c2e9..39aa0fd6a529 100644 --- a/include/drm/nouveau_drm.h +++ b/include/drm/nouveau_drm.h @@ -81,6 +81,7 @@ struct drm_nouveau_gpuobj_free { #define NOUVEAU_GETPARAM_GRAPH_UNITS 13 #define NOUVEAU_GETPARAM_PTIMER_TIME 14 #define NOUVEAU_GETPARAM_HAS_BO_USAGE 15 +#define NOUVEAU_GETPARAM_HAS_PAGEFLIP 16 struct drm_nouveau_getparam { uint64_t param; uint64_t value; -- cgit v1.2.3 From 1c180fa5bd5f264e4863bb88861e8cd7d135b917 Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Mon, 25 Oct 2010 03:30:34 +0200 Subject: drm/nouveau: Call drm_vblank_pre/post_modeset() around mode setting. Signed-off-by: Francisco Jerez Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nv04_crtc.c | 2 ++ drivers/gpu/drm/nouveau/nv50_crtc.c | 2 ++ 2 files changed, 4 insertions(+) diff --git a/drivers/gpu/drm/nouveau/nv04_crtc.c b/drivers/gpu/drm/nouveau/nv04_crtc.c index e4aea721971f..297505eb98d5 100644 --- a/drivers/gpu/drm/nouveau/nv04_crtc.c +++ b/drivers/gpu/drm/nouveau/nv04_crtc.c @@ -672,6 +672,7 @@ static void nv_crtc_prepare(struct drm_crtc *crtc) if (nv_two_heads(dev)) NVSetOwner(dev, nv_crtc->index); + drm_vblank_pre_modeset(dev, nv_crtc->index); funcs->dpms(crtc, DRM_MODE_DPMS_OFF); NVBlankScreen(dev, nv_crtc->index, true); @@ -704,6 +705,7 @@ static void nv_crtc_commit(struct drm_crtc *crtc) #endif funcs->dpms(crtc, DRM_MODE_DPMS_ON); + drm_vblank_post_modeset(dev, nv_crtc->index); } static void nv_crtc_destroy(struct drm_crtc *crtc) diff --git a/drivers/gpu/drm/nouveau/nv50_crtc.c b/drivers/gpu/drm/nouveau/nv50_crtc.c index 1225ea0a841b..f3570cc45017 100644 --- a/drivers/gpu/drm/nouveau/nv50_crtc.c +++ b/drivers/gpu/drm/nouveau/nv50_crtc.c @@ -454,6 +454,7 @@ nv50_crtc_prepare(struct drm_crtc *crtc) NV_DEBUG_KMS(dev, "index %d\n", nv_crtc->index); + drm_vblank_pre_modeset(dev, nv_crtc->index); nv50_crtc_blank(nv_crtc, true); } @@ -469,6 +470,7 @@ nv50_crtc_commit(struct drm_crtc *crtc) NV_DEBUG_KMS(dev, "index %d\n", nv_crtc->index); nv50_crtc_blank(nv_crtc, false); + drm_vblank_post_modeset(dev, nv_crtc->index); ret = RING_SPACE(evo, 2); if (ret) { -- cgit v1.2.3 From 1f6d2de2c539df6fe52ad2187191a9dfe10c7233 Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Sun, 24 Oct 2010 14:15:58 +0200 Subject: drm/nv50: Keep track of the head a channel is vsync'ing to. In a multihead setup vblank interrupts may end up enabled in both heads. In that case we want to ignore the vblank interrupts coming from the wrong CRTC to avoid tearing and unbalanced calls to drm_vblank_get/put (fdo bug 31074). Reported-by: Felix Leimbach Signed-off-by: Francisco Jerez Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_drv.h | 1 + drivers/gpu/drm/nouveau/nv50_display.c | 3 +++ drivers/gpu/drm/nouveau/nv50_graph.c | 3 +++ 3 files changed, 7 insertions(+) diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index 2bb1f1572a55..5814db82f778 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -257,6 +257,7 @@ struct nouveau_channel { struct { struct nouveau_gpuobj *vblsem; + uint32_t vblsem_head; uint32_t vblsem_offset; uint32_t vblsem_rval; struct list_head vbl_wait; diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c index 17b950abf200..41b212801870 100644 --- a/drivers/gpu/drm/nouveau/nv50_display.c +++ b/drivers/gpu/drm/nouveau/nv50_display.c @@ -432,6 +432,9 @@ nv50_display_vblank_crtc_handler(struct drm_device *dev, int crtc) list_for_each_entry_safe(chan, tmp, &dev_priv->vbl_waiting, nvsw.vbl_wait) { + if (chan->nvsw.vblsem_head != crtc) + continue; + nouveau_bo_wr32(chan->notifier_bo, chan->nvsw.vblsem_offset, chan->nvsw.vblsem_rval); list_del(&chan->nvsw.vbl_wait); diff --git a/drivers/gpu/drm/nouveau/nv50_graph.c b/drivers/gpu/drm/nouveau/nv50_graph.c index 6d81f4dab37d..e0f52942b2eb 100644 --- a/drivers/gpu/drm/nouveau/nv50_graph.c +++ b/drivers/gpu/drm/nouveau/nv50_graph.c @@ -387,7 +387,10 @@ nv50_graph_nvsw_vblsem_release(struct nouveau_channel *chan, return -EINVAL; drm_vblank_get(dev, data); + + chan->nvsw.vblsem_head = data; list_add(&chan->nvsw.vbl_wait, &dev_priv->vbl_waiting); + return 0; } -- cgit v1.2.3 From e419cf0954901bb3a987f8b76cbc9654ca06121c Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Mon, 25 Oct 2010 23:38:59 +0200 Subject: drm/nouveau: Add a separate class for the kernel channel mutex. nouveau_bo_move_m2mf() needs to lock the kernel channel, and it may be called from the pushbuf IOCTL with an user channel already locked. Use a separate subclass for the kernel channel mutex because this is legitimate mutex nesting. Signed-off-by: Francisco Jerez Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_bo.c | 2 +- drivers/gpu/drm/nouveau/nouveau_drv.h | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index cdc8f544d47f..099f806f39ed 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c @@ -678,7 +678,7 @@ nouveau_bo_move_m2mf(struct ttm_buffer_object *bo, int evict, bool intr, chan = nvbo->channel; if (!chan || nvbo->no_vm) { chan = dev_priv->channel; - mutex_lock(&chan->mutex); + mutex_lock_nested(&chan->mutex, NOUVEAU_KCHANNEL_MUTEX); } if (dev_priv->card_type < NV_50) diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index 5814db82f778..ce0475ead381 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -173,6 +173,11 @@ struct nouveau_page_flip_state { uint64_t offset; }; +enum nouveau_channel_mutex_class { + NOUVEAU_UCHANNEL_MUTEX, + NOUVEAU_KCHANNEL_MUTEX +}; + struct nouveau_channel { struct drm_device *dev; int id; -- cgit v1.2.3 From a5cf68b04b2b8ea716cf6fd8499c1c54d05fdf5e Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Sun, 24 Oct 2010 16:14:41 +0200 Subject: drm/nouveau: Rework tile region handling. The point is to share more code between the PFB/PGRAPH tile region hooks, and give the hardware specific functions a chance to allocate per-region resources. Signed-off-by: Francisco Jerez Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_bo.c | 11 ++-- drivers/gpu/drm/nouveau/nouveau_drv.h | 59 ++++++++++------- drivers/gpu/drm/nouveau/nouveau_mem.c | 111 +++++++++++++++++++------------- drivers/gpu/drm/nouveau/nouveau_state.c | 25 ++++--- drivers/gpu/drm/nouveau/nv10_fb.c | 48 +++++++++----- drivers/gpu/drm/nouveau/nv10_graph.c | 17 ++--- drivers/gpu/drm/nouveau/nv20_graph.c | 25 ++++--- drivers/gpu/drm/nouveau/nv30_fb.c | 23 ++++++- drivers/gpu/drm/nouveau/nv40_fb.c | 22 +++---- drivers/gpu/drm/nouveau/nv40_graph.c | 40 ++++++------ 10 files changed, 221 insertions(+), 160 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index 099f806f39ed..8d5dd980240d 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c @@ -46,9 +46,7 @@ nouveau_bo_del_ttm(struct ttm_buffer_object *bo) if (unlikely(nvbo->gem)) DRM_ERROR("bo %p still attached to GEM object\n", bo); - if (nvbo->tile) - nv10_mem_expire_tiling(dev, nvbo->tile, NULL); - + nv10_mem_put_tile_region(dev, nvbo->tile, NULL); kfree(nvbo); } @@ -792,7 +790,8 @@ nouveau_bo_vm_bind(struct ttm_buffer_object *bo, struct ttm_mem_reg *new_mem, } else if (dev_priv->card_type >= NV_10) { *new_tile = nv10_mem_set_tiling(dev, offset, new_mem->size, - nvbo->tile_mode); + nvbo->tile_mode, + nvbo->tile_flags); } return 0; @@ -808,9 +807,7 @@ nouveau_bo_vm_cleanup(struct ttm_buffer_object *bo, if (dev_priv->card_type >= NV_10 && dev_priv->card_type < NV_50) { - if (*old_tile) - nv10_mem_expire_tiling(dev, *old_tile, bo->sync_obj); - + nv10_mem_put_tile_region(dev, *old_tile, bo->sync_obj); *old_tile = new_tile; } } diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index ce0475ead381..8b524d894f18 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -66,10 +66,11 @@ struct nouveau_grctx; #define NV50_VM_VRAM_NR (NV50_VM_MAX_VRAM / NV50_VM_BLOCK) struct nouveau_tile_reg { - struct nouveau_fence *fence; - uint32_t addr; - uint32_t size; bool used; + uint32_t addr; + uint32_t limit; + uint32_t pitch; + struct nouveau_fence *fence; }; struct nouveau_bo { @@ -309,8 +310,11 @@ struct nouveau_fb_engine { int (*init)(struct drm_device *dev); void (*takedown)(struct drm_device *dev); - void (*set_region_tiling)(struct drm_device *dev, int i, uint32_t addr, - uint32_t size, uint32_t pitch); + void (*init_tile_region)(struct drm_device *dev, int i, + uint32_t addr, uint32_t size, + uint32_t pitch, uint32_t flags); + void (*set_tile_region)(struct drm_device *dev, int i); + void (*free_tile_region)(struct drm_device *dev, int i); }; struct nouveau_fifo_engine { @@ -356,8 +360,7 @@ struct nouveau_pgraph_engine { int (*unload_context)(struct drm_device *); void (*tlb_flush)(struct drm_device *dev); - void (*set_region_tiling)(struct drm_device *dev, int i, uint32_t addr, - uint32_t size, uint32_t pitch); + void (*set_tile_region)(struct drm_device *dev, int i); }; struct nouveau_display_engine { @@ -668,7 +671,10 @@ struct drm_nouveau_private { } gart_info; /* nv10-nv40 tiling regions */ - struct nouveau_tile_reg tile[NOUVEAU_MAX_TILE_NR]; + struct { + struct nouveau_tile_reg reg[NOUVEAU_MAX_TILE_NR]; + spinlock_t lock; + } tile; /* VRAM/fb configuration */ uint64_t vram_size; @@ -798,13 +804,12 @@ extern void nouveau_mem_gart_fini(struct drm_device *); extern int nouveau_mem_init_agp(struct drm_device *); extern int nouveau_mem_reset_agp(struct drm_device *); extern void nouveau_mem_close(struct drm_device *); -extern struct nouveau_tile_reg *nv10_mem_set_tiling(struct drm_device *dev, - uint32_t addr, - uint32_t size, - uint32_t pitch); -extern void nv10_mem_expire_tiling(struct drm_device *dev, - struct nouveau_tile_reg *tile, - struct nouveau_fence *fence); +extern struct nouveau_tile_reg *nv10_mem_set_tiling( + struct drm_device *dev, uint32_t addr, uint32_t size, + uint32_t pitch, uint32_t flags); +extern void nv10_mem_put_tile_region(struct drm_device *dev, + struct nouveau_tile_reg *tile, + struct nouveau_fence *fence); extern int nv50_mem_vm_bind_linear(struct drm_device *, uint64_t virt, uint32_t size, uint32_t flags, uint64_t phys); @@ -1011,18 +1016,25 @@ extern void nv04_fb_takedown(struct drm_device *); /* nv10_fb.c */ extern int nv10_fb_init(struct drm_device *); extern void nv10_fb_takedown(struct drm_device *); -extern void nv10_fb_set_region_tiling(struct drm_device *, int, uint32_t, - uint32_t, uint32_t); +extern void nv10_fb_init_tile_region(struct drm_device *dev, int i, + uint32_t addr, uint32_t size, + uint32_t pitch, uint32_t flags); +extern void nv10_fb_set_tile_region(struct drm_device *dev, int i); +extern void nv10_fb_free_tile_region(struct drm_device *dev, int i); /* nv30_fb.c */ extern int nv30_fb_init(struct drm_device *); extern void nv30_fb_takedown(struct drm_device *); +extern void nv30_fb_init_tile_region(struct drm_device *dev, int i, + uint32_t addr, uint32_t size, + uint32_t pitch, uint32_t flags); +extern void nv30_fb_free_tile_region(struct drm_device *dev, int i); /* nv40_fb.c */ extern int nv40_fb_init(struct drm_device *); extern void nv40_fb_takedown(struct drm_device *); -extern void nv40_fb_set_region_tiling(struct drm_device *, int, uint32_t, - uint32_t, uint32_t); +extern void nv40_fb_set_tile_region(struct drm_device *dev, int i); + /* nv50_fb.c */ extern int nv50_fb_init(struct drm_device *); extern void nv50_fb_takedown(struct drm_device *); @@ -1102,8 +1114,7 @@ extern void nv10_graph_destroy_context(struct nouveau_channel *); extern int nv10_graph_load_context(struct nouveau_channel *); extern int nv10_graph_unload_context(struct drm_device *); extern void nv10_graph_context_switch(struct drm_device *); -extern void nv10_graph_set_region_tiling(struct drm_device *, int, uint32_t, - uint32_t, uint32_t); +extern void nv10_graph_set_tile_region(struct drm_device *dev, int i); /* nv20_graph.c */ extern int nv20_graph_create_context(struct nouveau_channel *); @@ -1113,8 +1124,7 @@ extern int nv20_graph_unload_context(struct drm_device *); extern int nv20_graph_init(struct drm_device *); extern void nv20_graph_takedown(struct drm_device *); extern int nv30_graph_init(struct drm_device *); -extern void nv20_graph_set_region_tiling(struct drm_device *, int, uint32_t, - uint32_t, uint32_t); +extern void nv20_graph_set_tile_region(struct drm_device *dev, int i); /* nv40_graph.c */ extern int nv40_graph_init(struct drm_device *); @@ -1125,8 +1135,7 @@ extern void nv40_graph_destroy_context(struct nouveau_channel *); extern int nv40_graph_load_context(struct nouveau_channel *); extern int nv40_graph_unload_context(struct drm_device *); extern void nv40_grctx_init(struct nouveau_grctx *); -extern void nv40_graph_set_region_tiling(struct drm_device *, int, uint32_t, - uint32_t, uint32_t); +extern void nv40_graph_set_tile_region(struct drm_device *dev, int i); /* nv50_graph.c */ extern int nv50_graph_init(struct drm_device *); diff --git a/drivers/gpu/drm/nouveau/nouveau_mem.c b/drivers/gpu/drm/nouveau/nouveau_mem.c index a7c3e08aa7b5..549f59052881 100644 --- a/drivers/gpu/drm/nouveau/nouveau_mem.c +++ b/drivers/gpu/drm/nouveau/nouveau_mem.c @@ -42,83 +42,104 @@ */ static void -nv10_mem_set_region_tiling(struct drm_device *dev, int i, uint32_t addr, - uint32_t size, uint32_t pitch) +nv10_mem_update_tile_region(struct drm_device *dev, + struct nouveau_tile_reg *tile, uint32_t addr, + uint32_t size, uint32_t pitch, uint32_t flags) { struct drm_nouveau_private *dev_priv = dev->dev_private; struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo; struct nouveau_fb_engine *pfb = &dev_priv->engine.fb; struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; - struct nouveau_tile_reg *tile = &dev_priv->tile[i]; + int i = tile - dev_priv->tile.reg; + unsigned long save; - tile->addr = addr; - tile->size = size; - tile->used = !!pitch; nouveau_fence_unref(&tile->fence); + if (tile->pitch) + pfb->free_tile_region(dev, i); + + if (pitch) + pfb->init_tile_region(dev, i, addr, size, pitch, flags); + + spin_lock_irqsave(&dev_priv->context_switch_lock, save); pfifo->reassign(dev, false); pfifo->cache_pull(dev, false); nouveau_wait_for_idle(dev); - pgraph->set_region_tiling(dev, i, addr, size, pitch); - pfb->set_region_tiling(dev, i, addr, size, pitch); + pfb->set_tile_region(dev, i); + pgraph->set_tile_region(dev, i); pfifo->cache_pull(dev, true); pfifo->reassign(dev, true); + spin_unlock_irqrestore(&dev_priv->context_switch_lock, save); } -struct nouveau_tile_reg * -nv10_mem_set_tiling(struct drm_device *dev, uint32_t addr, uint32_t size, - uint32_t pitch) +static struct nouveau_tile_reg * +nv10_mem_get_tile_region(struct drm_device *dev, int i) { struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_fb_engine *pfb = &dev_priv->engine.fb; - struct nouveau_tile_reg *found = NULL; - unsigned long i, flags; + struct nouveau_tile_reg *tile = &dev_priv->tile.reg[i]; - spin_lock_irqsave(&dev_priv->context_switch_lock, flags); + spin_lock(&dev_priv->tile.lock); - for (i = 0; i < pfb->num_tiles; i++) { - struct nouveau_tile_reg *tile = &dev_priv->tile[i]; - - if (tile->used) - /* Tile region in use. */ - continue; + if (!tile->used && + (!tile->fence || nouveau_fence_signalled(tile->fence))) + tile->used = true; + else + tile = NULL; - if (tile->fence && - !nouveau_fence_signalled(tile->fence)) - /* Pending tile region. */ - continue; + spin_unlock(&dev_priv->tile.lock); + return tile; +} - if (max(tile->addr, addr) < - min(tile->addr + tile->size, addr + size)) - /* Kill an intersecting tile region. */ - nv10_mem_set_region_tiling(dev, i, 0, 0, 0); +void +nv10_mem_put_tile_region(struct drm_device *dev, struct nouveau_tile_reg *tile, + struct nouveau_fence *fence) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; - if (pitch && !found) { - /* Free tile region. */ - nv10_mem_set_region_tiling(dev, i, addr, size, pitch); - found = tile; + if (tile) { + spin_lock(&dev_priv->tile.lock); + if (fence) { + /* Mark it as pending. */ + tile->fence = fence; + nouveau_fence_ref(fence); } - } - - spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags); - return found; + tile->used = false; + spin_unlock(&dev_priv->tile.lock); + } } -void -nv10_mem_expire_tiling(struct drm_device *dev, struct nouveau_tile_reg *tile, - struct nouveau_fence *fence) +struct nouveau_tile_reg * +nv10_mem_set_tiling(struct drm_device *dev, uint32_t addr, uint32_t size, + uint32_t pitch, uint32_t flags) { - if (fence) { - /* Mark it as pending. */ - tile->fence = fence; - nouveau_fence_ref(fence); + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_fb_engine *pfb = &dev_priv->engine.fb; + struct nouveau_tile_reg *tile, *found = NULL; + int i; + + for (i = 0; i < pfb->num_tiles; i++) { + tile = nv10_mem_get_tile_region(dev, i); + + if (pitch && !found) { + found = tile; + continue; + + } else if (tile && tile->pitch) { + /* Kill an unused tile region. */ + nv10_mem_update_tile_region(dev, tile, 0, 0, 0, 0); + } + + nv10_mem_put_tile_region(dev, tile, NULL); } - tile->used = false; + if (found) + nv10_mem_update_tile_region(dev, found, addr, size, + pitch, flags); + return found; } /* diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c index ec9d193b6f61..1a7a50ccb7c8 100644 --- a/drivers/gpu/drm/nouveau/nouveau_state.c +++ b/drivers/gpu/drm/nouveau/nouveau_state.c @@ -118,7 +118,9 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->timer.takedown = nv04_timer_takedown; engine->fb.init = nv10_fb_init; engine->fb.takedown = nv10_fb_takedown; - engine->fb.set_region_tiling = nv10_fb_set_region_tiling; + engine->fb.init_tile_region = nv10_fb_init_tile_region; + engine->fb.set_tile_region = nv10_fb_set_tile_region; + engine->fb.free_tile_region = nv10_fb_free_tile_region; engine->graph.init = nv10_graph_init; engine->graph.takedown = nv10_graph_takedown; engine->graph.channel = nv10_graph_channel; @@ -127,7 +129,7 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->graph.fifo_access = nv04_graph_fifo_access; engine->graph.load_context = nv10_graph_load_context; engine->graph.unload_context = nv10_graph_unload_context; - engine->graph.set_region_tiling = nv10_graph_set_region_tiling; + engine->graph.set_tile_region = nv10_graph_set_tile_region; engine->fifo.channels = 32; engine->fifo.init = nv10_fifo_init; engine->fifo.takedown = nouveau_stub_takedown; @@ -173,7 +175,9 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->timer.takedown = nv04_timer_takedown; engine->fb.init = nv10_fb_init; engine->fb.takedown = nv10_fb_takedown; - engine->fb.set_region_tiling = nv10_fb_set_region_tiling; + engine->fb.init_tile_region = nv10_fb_init_tile_region; + engine->fb.set_tile_region = nv10_fb_set_tile_region; + engine->fb.free_tile_region = nv10_fb_free_tile_region; engine->graph.init = nv20_graph_init; engine->graph.takedown = nv20_graph_takedown; engine->graph.channel = nv10_graph_channel; @@ -182,7 +186,7 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->graph.fifo_access = nv04_graph_fifo_access; engine->graph.load_context = nv20_graph_load_context; engine->graph.unload_context = nv20_graph_unload_context; - engine->graph.set_region_tiling = nv20_graph_set_region_tiling; + engine->graph.set_tile_region = nv20_graph_set_tile_region; engine->fifo.channels = 32; engine->fifo.init = nv10_fifo_init; engine->fifo.takedown = nouveau_stub_takedown; @@ -228,7 +232,9 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->timer.takedown = nv04_timer_takedown; engine->fb.init = nv30_fb_init; engine->fb.takedown = nv30_fb_takedown; - engine->fb.set_region_tiling = nv10_fb_set_region_tiling; + engine->fb.init_tile_region = nv30_fb_init_tile_region; + engine->fb.set_tile_region = nv10_fb_set_tile_region; + engine->fb.free_tile_region = nv30_fb_free_tile_region; engine->graph.init = nv30_graph_init; engine->graph.takedown = nv20_graph_takedown; engine->graph.fifo_access = nv04_graph_fifo_access; @@ -237,7 +243,7 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->graph.destroy_context = nv20_graph_destroy_context; engine->graph.load_context = nv20_graph_load_context; engine->graph.unload_context = nv20_graph_unload_context; - engine->graph.set_region_tiling = nv20_graph_set_region_tiling; + engine->graph.set_tile_region = nv20_graph_set_tile_region; engine->fifo.channels = 32; engine->fifo.init = nv10_fifo_init; engine->fifo.takedown = nouveau_stub_takedown; @@ -286,7 +292,9 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->timer.takedown = nv04_timer_takedown; engine->fb.init = nv40_fb_init; engine->fb.takedown = nv40_fb_takedown; - engine->fb.set_region_tiling = nv40_fb_set_region_tiling; + engine->fb.init_tile_region = nv30_fb_init_tile_region; + engine->fb.set_tile_region = nv40_fb_set_tile_region; + engine->fb.free_tile_region = nv30_fb_free_tile_region; engine->graph.init = nv40_graph_init; engine->graph.takedown = nv40_graph_takedown; engine->graph.fifo_access = nv04_graph_fifo_access; @@ -295,7 +303,7 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->graph.destroy_context = nv40_graph_destroy_context; engine->graph.load_context = nv40_graph_load_context; engine->graph.unload_context = nv40_graph_unload_context; - engine->graph.set_region_tiling = nv40_graph_set_region_tiling; + engine->graph.set_tile_region = nv40_graph_set_tile_region; engine->fifo.channels = 32; engine->fifo.init = nv40_fifo_init; engine->fifo.takedown = nouveau_stub_takedown; @@ -596,6 +604,7 @@ nouveau_card_init(struct drm_device *dev) goto out; engine = &dev_priv->engine; spin_lock_init(&dev_priv->channels.lock); + spin_lock_init(&dev_priv->tile.lock); spin_lock_init(&dev_priv->context_switch_lock); /* Make the CRTCs and I2C buses accessible */ diff --git a/drivers/gpu/drm/nouveau/nv10_fb.c b/drivers/gpu/drm/nouveau/nv10_fb.c index cc5cda44e501..d50acc6a90d1 100644 --- a/drivers/gpu/drm/nouveau/nv10_fb.c +++ b/drivers/gpu/drm/nouveau/nv10_fb.c @@ -4,22 +4,40 @@ #include "nouveau_drm.h" void -nv10_fb_set_region_tiling(struct drm_device *dev, int i, uint32_t addr, - uint32_t size, uint32_t pitch) +nv10_fb_init_tile_region(struct drm_device *dev, int i, uint32_t addr, + uint32_t size, uint32_t pitch, uint32_t flags) { struct drm_nouveau_private *dev_priv = dev->dev_private; - uint32_t limit = max(1u, addr + size) - 1; - - if (pitch) { - if (dev_priv->card_type >= NV_20) - addr |= 1; - else - addr |= 1 << 31; - } - - nv_wr32(dev, NV10_PFB_TLIMIT(i), limit); - nv_wr32(dev, NV10_PFB_TSIZE(i), pitch); - nv_wr32(dev, NV10_PFB_TILE(i), addr); + struct nouveau_tile_reg *tile = &dev_priv->tile.reg[i]; + + tile->addr = addr; + tile->limit = max(1u, addr + size) - 1; + tile->pitch = pitch; + + if (dev_priv->card_type == NV_20) + tile->addr |= 1; + else + tile->addr |= 1 << 31; +} + +void +nv10_fb_free_tile_region(struct drm_device *dev, int i) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_tile_reg *tile = &dev_priv->tile.reg[i]; + + tile->addr = tile->limit = tile->pitch = 0; +} + +void +nv10_fb_set_tile_region(struct drm_device *dev, int i) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_tile_reg *tile = &dev_priv->tile.reg[i]; + + nv_wr32(dev, NV10_PFB_TLIMIT(i), tile->limit); + nv_wr32(dev, NV10_PFB_TSIZE(i), tile->pitch); + nv_wr32(dev, NV10_PFB_TILE(i), tile->addr); } int @@ -33,7 +51,7 @@ nv10_fb_init(struct drm_device *dev) /* Turn all the tiling regions off. */ for (i = 0; i < pfb->num_tiles; i++) - pfb->set_region_tiling(dev, i, 0, 0, 0); + pfb->set_tile_region(dev, i); return 0; } diff --git a/drivers/gpu/drm/nouveau/nv10_graph.c b/drivers/gpu/drm/nouveau/nv10_graph.c index 3fbb49dfc09c..1cd141edca04 100644 --- a/drivers/gpu/drm/nouveau/nv10_graph.c +++ b/drivers/gpu/drm/nouveau/nv10_graph.c @@ -899,17 +899,14 @@ void nv10_graph_destroy_context(struct nouveau_channel *chan) } void -nv10_graph_set_region_tiling(struct drm_device *dev, int i, uint32_t addr, - uint32_t size, uint32_t pitch) +nv10_graph_set_tile_region(struct drm_device *dev, int i) { - uint32_t limit = max(1u, addr + size) - 1; - - if (pitch) - addr |= 1 << 31; + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_tile_reg *tile = &dev_priv->tile.reg[i]; - nv_wr32(dev, NV10_PGRAPH_TLIMIT(i), limit); - nv_wr32(dev, NV10_PGRAPH_TSIZE(i), pitch); - nv_wr32(dev, NV10_PGRAPH_TILE(i), addr); + nv_wr32(dev, NV10_PGRAPH_TLIMIT(i), tile->limit); + nv_wr32(dev, NV10_PGRAPH_TSIZE(i), tile->pitch); + nv_wr32(dev, NV10_PGRAPH_TILE(i), tile->addr); } int nv10_graph_init(struct drm_device *dev) @@ -949,7 +946,7 @@ int nv10_graph_init(struct drm_device *dev) /* Turn all the tiling regions off. */ for (i = 0; i < NV10_PFB_TILE__SIZE; i++) - nv10_graph_set_region_tiling(dev, i, 0, 0, 0); + nv10_graph_set_tile_region(dev, i); nv_wr32(dev, NV10_PGRAPH_CTX_SWITCH(0), 0x00000000); nv_wr32(dev, NV10_PGRAPH_CTX_SWITCH(1), 0x00000000); diff --git a/drivers/gpu/drm/nouveau/nv20_graph.c b/drivers/gpu/drm/nouveau/nv20_graph.c index 51b9dd12949d..a71871b91c69 100644 --- a/drivers/gpu/drm/nouveau/nv20_graph.c +++ b/drivers/gpu/drm/nouveau/nv20_graph.c @@ -511,24 +511,21 @@ nv20_graph_rdi(struct drm_device *dev) } void -nv20_graph_set_region_tiling(struct drm_device *dev, int i, uint32_t addr, - uint32_t size, uint32_t pitch) +nv20_graph_set_tile_region(struct drm_device *dev, int i) { - uint32_t limit = max(1u, addr + size) - 1; - - if (pitch) - addr |= 1; + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_tile_reg *tile = &dev_priv->tile.reg[i]; - nv_wr32(dev, NV20_PGRAPH_TLIMIT(i), limit); - nv_wr32(dev, NV20_PGRAPH_TSIZE(i), pitch); - nv_wr32(dev, NV20_PGRAPH_TILE(i), addr); + nv_wr32(dev, NV20_PGRAPH_TLIMIT(i), tile->limit); + nv_wr32(dev, NV20_PGRAPH_TSIZE(i), tile->pitch); + nv_wr32(dev, NV20_PGRAPH_TILE(i), tile->addr); nv_wr32(dev, NV10_PGRAPH_RDI_INDEX, 0x00EA0030 + 4 * i); - nv_wr32(dev, NV10_PGRAPH_RDI_DATA, limit); + nv_wr32(dev, NV10_PGRAPH_RDI_DATA, tile->limit); nv_wr32(dev, NV10_PGRAPH_RDI_INDEX, 0x00EA0050 + 4 * i); - nv_wr32(dev, NV10_PGRAPH_RDI_DATA, pitch); + nv_wr32(dev, NV10_PGRAPH_RDI_DATA, tile->pitch); nv_wr32(dev, NV10_PGRAPH_RDI_INDEX, 0x00EA0010 + 4 * i); - nv_wr32(dev, NV10_PGRAPH_RDI_DATA, addr); + nv_wr32(dev, NV10_PGRAPH_RDI_DATA, tile->addr); } int @@ -612,7 +609,7 @@ nv20_graph_init(struct drm_device *dev) /* Turn all the tiling regions off. */ for (i = 0; i < NV10_PFB_TILE__SIZE; i++) - nv20_graph_set_region_tiling(dev, i, 0, 0, 0); + nv20_graph_set_tile_region(dev, i); for (i = 0; i < 8; i++) { nv_wr32(dev, 0x400980 + i * 4, nv_rd32(dev, 0x100300 + i * 4)); @@ -751,7 +748,7 @@ nv30_graph_init(struct drm_device *dev) /* Turn all the tiling regions off. */ for (i = 0; i < NV10_PFB_TILE__SIZE; i++) - nv20_graph_set_region_tiling(dev, i, 0, 0, 0); + nv20_graph_set_tile_region(dev, i); nv_wr32(dev, NV10_PGRAPH_CTX_CONTROL, 0x10000100); nv_wr32(dev, NV10_PGRAPH_STATE , 0xFFFFFFFF); diff --git a/drivers/gpu/drm/nouveau/nv30_fb.c b/drivers/gpu/drm/nouveau/nv30_fb.c index 4a3f2f095128..e0135f0e2144 100644 --- a/drivers/gpu/drm/nouveau/nv30_fb.c +++ b/drivers/gpu/drm/nouveau/nv30_fb.c @@ -29,6 +29,27 @@ #include "nouveau_drv.h" #include "nouveau_drm.h" +void +nv30_fb_init_tile_region(struct drm_device *dev, int i, uint32_t addr, + uint32_t size, uint32_t pitch, uint32_t flags) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_tile_reg *tile = &dev_priv->tile.reg[i]; + + tile->addr = addr | 1; + tile->limit = max(1u, addr + size) - 1; + tile->pitch = pitch; +} + +void +nv30_fb_free_tile_region(struct drm_device *dev, int i) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_tile_reg *tile = &dev_priv->tile.reg[i]; + + tile->addr = tile->limit = tile->pitch = 0; +} + static int calc_bias(struct drm_device *dev, int k, int i, int j) { @@ -65,7 +86,7 @@ nv30_fb_init(struct drm_device *dev) /* Turn all the tiling regions off. */ for (i = 0; i < pfb->num_tiles; i++) - pfb->set_region_tiling(dev, i, 0, 0, 0); + pfb->set_tile_region(dev, i); /* Init the memory timing regs at 0x10037c/0x1003ac */ if (dev_priv->chipset == 0x30 || diff --git a/drivers/gpu/drm/nouveau/nv40_fb.c b/drivers/gpu/drm/nouveau/nv40_fb.c index 3cd07d8d5bd7..f3d9c0505f7b 100644 --- a/drivers/gpu/drm/nouveau/nv40_fb.c +++ b/drivers/gpu/drm/nouveau/nv40_fb.c @@ -4,26 +4,22 @@ #include "nouveau_drm.h" void -nv40_fb_set_region_tiling(struct drm_device *dev, int i, uint32_t addr, - uint32_t size, uint32_t pitch) +nv40_fb_set_tile_region(struct drm_device *dev, int i) { struct drm_nouveau_private *dev_priv = dev->dev_private; - uint32_t limit = max(1u, addr + size) - 1; - - if (pitch) - addr |= 1; + struct nouveau_tile_reg *tile = &dev_priv->tile.reg[i]; switch (dev_priv->chipset) { case 0x40: - nv_wr32(dev, NV10_PFB_TLIMIT(i), limit); - nv_wr32(dev, NV10_PFB_TSIZE(i), pitch); - nv_wr32(dev, NV10_PFB_TILE(i), addr); + nv_wr32(dev, NV10_PFB_TLIMIT(i), tile->limit); + nv_wr32(dev, NV10_PFB_TSIZE(i), tile->pitch); + nv_wr32(dev, NV10_PFB_TILE(i), tile->addr); break; default: - nv_wr32(dev, NV40_PFB_TLIMIT(i), limit); - nv_wr32(dev, NV40_PFB_TSIZE(i), pitch); - nv_wr32(dev, NV40_PFB_TILE(i), addr); + nv_wr32(dev, NV40_PFB_TLIMIT(i), tile->limit); + nv_wr32(dev, NV40_PFB_TSIZE(i), tile->pitch); + nv_wr32(dev, NV40_PFB_TILE(i), tile->addr); break; } } @@ -64,7 +60,7 @@ nv40_fb_init(struct drm_device *dev) /* Turn all the tiling regions off. */ for (i = 0; i < pfb->num_tiles; i++) - pfb->set_region_tiling(dev, i, 0, 0, 0); + pfb->set_tile_region(dev, i); return 0; } diff --git a/drivers/gpu/drm/nouveau/nv40_graph.c b/drivers/gpu/drm/nouveau/nv40_graph.c index 159bdcd757d4..7a51608b55ba 100644 --- a/drivers/gpu/drm/nouveau/nv40_graph.c +++ b/drivers/gpu/drm/nouveau/nv40_graph.c @@ -192,43 +192,39 @@ nv40_graph_unload_context(struct drm_device *dev) } void -nv40_graph_set_region_tiling(struct drm_device *dev, int i, uint32_t addr, - uint32_t size, uint32_t pitch) +nv40_graph_set_tile_region(struct drm_device *dev, int i) { struct drm_nouveau_private *dev_priv = dev->dev_private; - uint32_t limit = max(1u, addr + size) - 1; - - if (pitch) - addr |= 1; + struct nouveau_tile_reg *tile = &dev_priv->tile.reg[i]; switch (dev_priv->chipset) { case 0x44: case 0x4a: case 0x4e: - nv_wr32(dev, NV20_PGRAPH_TSIZE(i), pitch); - nv_wr32(dev, NV20_PGRAPH_TLIMIT(i), limit); - nv_wr32(dev, NV20_PGRAPH_TILE(i), addr); + nv_wr32(dev, NV20_PGRAPH_TSIZE(i), tile->pitch); + nv_wr32(dev, NV20_PGRAPH_TLIMIT(i), tile->limit); + nv_wr32(dev, NV20_PGRAPH_TILE(i), tile->addr); break; case 0x46: case 0x47: case 0x49: case 0x4b: - nv_wr32(dev, NV47_PGRAPH_TSIZE(i), pitch); - nv_wr32(dev, NV47_PGRAPH_TLIMIT(i), limit); - nv_wr32(dev, NV47_PGRAPH_TILE(i), addr); - nv_wr32(dev, NV40_PGRAPH_TSIZE1(i), pitch); - nv_wr32(dev, NV40_PGRAPH_TLIMIT1(i), limit); - nv_wr32(dev, NV40_PGRAPH_TILE1(i), addr); + nv_wr32(dev, NV47_PGRAPH_TSIZE(i), tile->pitch); + nv_wr32(dev, NV47_PGRAPH_TLIMIT(i), tile->limit); + nv_wr32(dev, NV47_PGRAPH_TILE(i), tile->addr); + nv_wr32(dev, NV40_PGRAPH_TSIZE1(i), tile->pitch); + nv_wr32(dev, NV40_PGRAPH_TLIMIT1(i), tile->limit); + nv_wr32(dev, NV40_PGRAPH_TILE1(i), tile->addr); break; default: - nv_wr32(dev, NV20_PGRAPH_TSIZE(i), pitch); - nv_wr32(dev, NV20_PGRAPH_TLIMIT(i), limit); - nv_wr32(dev, NV20_PGRAPH_TILE(i), addr); - nv_wr32(dev, NV40_PGRAPH_TSIZE1(i), pitch); - nv_wr32(dev, NV40_PGRAPH_TLIMIT1(i), limit); - nv_wr32(dev, NV40_PGRAPH_TILE1(i), addr); + nv_wr32(dev, NV20_PGRAPH_TSIZE(i), tile->pitch); + nv_wr32(dev, NV20_PGRAPH_TLIMIT(i), tile->limit); + nv_wr32(dev, NV20_PGRAPH_TILE(i), tile->addr); + nv_wr32(dev, NV40_PGRAPH_TSIZE1(i), tile->pitch); + nv_wr32(dev, NV40_PGRAPH_TLIMIT1(i), tile->limit); + nv_wr32(dev, NV40_PGRAPH_TILE1(i), tile->addr); break; } } @@ -369,7 +365,7 @@ nv40_graph_init(struct drm_device *dev) /* Turn all the tiling regions off. */ for (i = 0; i < pfb->num_tiles; i++) - nv40_graph_set_region_tiling(dev, i, 0, 0, 0); + nv40_graph_set_tile_region(dev, i); /* begin RAM config */ vramsz = pci_resource_len(dev->pdev, 0) - 1; -- cgit v1.2.3 From 87a326a38589e1c919af5f86a59cd571ff0aa831 Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Sun, 24 Oct 2010 16:36:12 +0200 Subject: drm/nv20: Add Z compression support. Signed-off-by: Francisco Jerez Tested-by: Xavier Chantry Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_drv.h | 3 ++ drivers/gpu/drm/nouveau/nouveau_reg.h | 6 +++ drivers/gpu/drm/nouveau/nv10_fb.c | 90 +++++++++++++++++++++++++++++++++-- drivers/gpu/drm/nouveau/nv20_graph.c | 21 ++++---- 4 files changed, 106 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index 8b524d894f18..a94430b94a20 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -70,6 +70,8 @@ struct nouveau_tile_reg { uint32_t addr; uint32_t limit; uint32_t pitch; + uint32_t zcomp; + struct drm_mm_node *tag_mem; struct nouveau_fence *fence; }; @@ -306,6 +308,7 @@ struct nouveau_timer_engine { struct nouveau_fb_engine { int num_tiles; + struct drm_mm tag_heap; int (*init)(struct drm_device *dev); void (*takedown)(struct drm_device *dev); diff --git a/drivers/gpu/drm/nouveau/nouveau_reg.h b/drivers/gpu/drm/nouveau/nouveau_reg.h index b6384d36d5d0..df3a87e792f2 100644 --- a/drivers/gpu/drm/nouveau/nouveau_reg.h +++ b/drivers/gpu/drm/nouveau/nouveau_reg.h @@ -45,6 +45,11 @@ # define NV04_PFB_REF_CMD_REFRESH (1 << 0) #define NV04_PFB_PRE 0x001002d4 # define NV04_PFB_PRE_CMD_PRECHARGE (1 << 0) +#define NV20_PFB_ZCOMP(i) (0x00100300 + 4*(i)) +# define NV20_PFB_ZCOMP_MODE_32 (4 << 24) +# define NV20_PFB_ZCOMP_EN (1 << 31) +# define NV25_PFB_ZCOMP_MODE_16 (1 << 20) +# define NV25_PFB_ZCOMP_MODE_32 (2 << 20) #define NV10_PFB_CLOSE_PAGE2 0x0010033c #define NV04_PFB_SCRAMBLE(i) (0x00100400 + 4 * (i)) #define NV40_PFB_TILE(i) (0x00100600 + (i*16)) @@ -379,6 +384,7 @@ #define NV20_PGRAPH_TLIMIT(i) (0x00400904 + (i*16)) #define NV20_PGRAPH_TSIZE(i) (0x00400908 + (i*16)) #define NV20_PGRAPH_TSTATUS(i) (0x0040090C + (i*16)) +#define NV20_PGRAPH_ZCOMP(i) (0x00400980 + 4*(i)) #define NV10_PGRAPH_TILE(i) (0x00400B00 + (i*16)) #define NV10_PGRAPH_TLIMIT(i) (0x00400B04 + (i*16)) #define NV10_PGRAPH_TSIZE(i) (0x00400B08 + (i*16)) diff --git a/drivers/gpu/drm/nouveau/nv10_fb.c b/drivers/gpu/drm/nouveau/nv10_fb.c index d50acc6a90d1..f78181a59b4a 100644 --- a/drivers/gpu/drm/nouveau/nv10_fb.c +++ b/drivers/gpu/drm/nouveau/nv10_fb.c @@ -3,21 +3,81 @@ #include "nouveau_drv.h" #include "nouveau_drm.h" +static struct drm_mm_node * +nv20_fb_alloc_tag(struct drm_device *dev, uint32_t size) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_fb_engine *pfb = &dev_priv->engine.fb; + struct drm_mm_node *mem; + int ret; + + ret = drm_mm_pre_get(&pfb->tag_heap); + if (ret) + return NULL; + + spin_lock(&dev_priv->tile.lock); + mem = drm_mm_search_free(&pfb->tag_heap, size, 0, 0); + if (mem) + mem = drm_mm_get_block_atomic(mem, size, 0); + spin_unlock(&dev_priv->tile.lock); + + return mem; +} + +static void +nv20_fb_free_tag(struct drm_device *dev, struct drm_mm_node *mem) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + + spin_lock(&dev_priv->tile.lock); + drm_mm_put_block(mem); + spin_unlock(&dev_priv->tile.lock); +} + void nv10_fb_init_tile_region(struct drm_device *dev, int i, uint32_t addr, uint32_t size, uint32_t pitch, uint32_t flags) { struct drm_nouveau_private *dev_priv = dev->dev_private; struct nouveau_tile_reg *tile = &dev_priv->tile.reg[i]; + int bpp = (flags & NOUVEAU_GEM_TILE_32BPP ? 32 : 16); tile->addr = addr; tile->limit = max(1u, addr + size) - 1; tile->pitch = pitch; - if (dev_priv->card_type == NV_20) - tile->addr |= 1; - else + if (dev_priv->card_type == NV_20) { + if (flags & NOUVEAU_GEM_TILE_ZETA) { + /* + * Allocate some of the on-die tag memory, + * used to store Z compression meta-data (most + * likely just a bitmap determining if a given + * tile is compressed or not). + */ + tile->tag_mem = nv20_fb_alloc_tag(dev, size / 256); + + if (tile->tag_mem) { + /* Enable Z compression */ + if (dev_priv->chipset >= 0x25) + tile->zcomp = tile->tag_mem->start | + (bpp == 16 ? + NV25_PFB_ZCOMP_MODE_16 : + NV25_PFB_ZCOMP_MODE_32); + else + tile->zcomp = tile->tag_mem->start | + NV20_PFB_ZCOMP_EN | + (bpp == 16 ? 0 : + NV20_PFB_ZCOMP_MODE_32); + } + + tile->addr |= 3; + } else { + tile->addr |= 1; + } + + } else { tile->addr |= 1 << 31; + } } void @@ -26,7 +86,12 @@ nv10_fb_free_tile_region(struct drm_device *dev, int i) struct drm_nouveau_private *dev_priv = dev->dev_private; struct nouveau_tile_reg *tile = &dev_priv->tile.reg[i]; - tile->addr = tile->limit = tile->pitch = 0; + if (tile->tag_mem) { + nv20_fb_free_tag(dev, tile->tag_mem); + tile->tag_mem = NULL; + } + + tile->addr = tile->limit = tile->pitch = tile->zcomp = 0; } void @@ -38,6 +103,9 @@ nv10_fb_set_tile_region(struct drm_device *dev, int i) nv_wr32(dev, NV10_PFB_TLIMIT(i), tile->limit); nv_wr32(dev, NV10_PFB_TSIZE(i), tile->pitch); nv_wr32(dev, NV10_PFB_TILE(i), tile->addr); + + if (dev_priv->card_type == NV_20) + nv_wr32(dev, NV20_PFB_ZCOMP(i), tile->zcomp); } int @@ -49,6 +117,11 @@ nv10_fb_init(struct drm_device *dev) pfb->num_tiles = NV10_PFB_TILE__SIZE; + if (dev_priv->card_type == NV_20) + drm_mm_init(&pfb->tag_heap, 0, + (dev_priv->chipset >= 0x25 ? + 64 * 1024 : 32 * 1024)); + /* Turn all the tiling regions off. */ for (i = 0; i < pfb->num_tiles; i++) pfb->set_tile_region(dev, i); @@ -59,4 +132,13 @@ nv10_fb_init(struct drm_device *dev) void nv10_fb_takedown(struct drm_device *dev) { + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_fb_engine *pfb = &dev_priv->engine.fb; + int i; + + for (i = 0; i < pfb->num_tiles; i++) + pfb->free_tile_region(dev, i); + + if (dev_priv->card_type == NV_20) + drm_mm_takedown(&pfb->tag_heap); } diff --git a/drivers/gpu/drm/nouveau/nv20_graph.c b/drivers/gpu/drm/nouveau/nv20_graph.c index a71871b91c69..bd065c2fcba4 100644 --- a/drivers/gpu/drm/nouveau/nv20_graph.c +++ b/drivers/gpu/drm/nouveau/nv20_graph.c @@ -526,6 +526,12 @@ nv20_graph_set_tile_region(struct drm_device *dev, int i) nv_wr32(dev, NV10_PGRAPH_RDI_DATA, tile->pitch); nv_wr32(dev, NV10_PGRAPH_RDI_INDEX, 0x00EA0010 + 4 * i); nv_wr32(dev, NV10_PGRAPH_RDI_DATA, tile->addr); + + if (dev_priv->card_type == NV_20) { + nv_wr32(dev, NV20_PGRAPH_ZCOMP(i), tile->zcomp); + nv_wr32(dev, NV10_PGRAPH_RDI_INDEX, 0x00ea0090 + 4 * i); + nv_wr32(dev, NV10_PGRAPH_RDI_DATA, tile->zcomp); + } } int @@ -589,16 +595,17 @@ nv20_graph_init(struct drm_device *dev) nv_wr32(dev, 0x40009C , 0x00000040); if (dev_priv->chipset >= 0x25) { - nv_wr32(dev, 0x400890, 0x00080000); + nv_wr32(dev, 0x400890, 0x00a8cfff); nv_wr32(dev, 0x400610, 0x304B1FB6); - nv_wr32(dev, 0x400B80, 0x18B82880); + nv_wr32(dev, 0x400B80, 0x1cbd3883); nv_wr32(dev, 0x400B84, 0x44000000); nv_wr32(dev, 0x400098, 0x40000080); nv_wr32(dev, 0x400B88, 0x000000ff); + } else { - nv_wr32(dev, 0x400880, 0x00080000); /* 0x0008c7df */ + nv_wr32(dev, 0x400880, 0x0008c7df); nv_wr32(dev, 0x400094, 0x00000005); - nv_wr32(dev, 0x400B80, 0x45CAA208); /* 0x45eae20e */ + nv_wr32(dev, 0x400B80, 0x45eae20e); nv_wr32(dev, 0x400B84, 0x24000000); nv_wr32(dev, 0x400098, 0x00000040); nv_wr32(dev, NV10_PGRAPH_RDI_INDEX, 0x00E00038); @@ -611,12 +618,6 @@ nv20_graph_init(struct drm_device *dev) for (i = 0; i < NV10_PFB_TILE__SIZE; i++) nv20_graph_set_tile_region(dev, i); - for (i = 0; i < 8; i++) { - nv_wr32(dev, 0x400980 + i * 4, nv_rd32(dev, 0x100300 + i * 4)); - nv_wr32(dev, NV10_PGRAPH_RDI_INDEX, 0x00EA0090 + i * 4); - nv_wr32(dev, NV10_PGRAPH_RDI_DATA, - nv_rd32(dev, 0x100300 + i * 4)); - } nv_wr32(dev, 0x4009a0, nv_rd32(dev, 0x100324)); nv_wr32(dev, NV10_PGRAPH_RDI_INDEX, 0x00EA000C); nv_wr32(dev, NV10_PGRAPH_RDI_DATA, nv_rd32(dev, 0x100324)); -- cgit v1.2.3 From 23c45e8ed203f933753fb66a6290c4ff853eb7bb Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Thu, 28 Oct 2010 23:10:29 +0200 Subject: drm/nouveau: Fix sleep while atomic in nouveau_bo_fence(). Reported-by: Pekka Paalanen Signed-off-by: Francisco Jerez Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_bo.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index 8d5dd980240d..f4ee43db00aa 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c @@ -942,13 +942,17 @@ nouveau_ttm_fault_reserve_notify(struct ttm_buffer_object *bo) void nouveau_bo_fence(struct nouveau_bo *nvbo, struct nouveau_fence *fence) { - spin_lock(&nvbo->bo.bdev->fence_lock); - __nouveau_fence_unref(&nvbo->bo.sync_obj); + struct nouveau_fence *old_fence; if (likely(fence)) - nvbo->bo.sync_obj = nouveau_fence_ref(fence); + nouveau_fence_ref(fence); + spin_lock(&nvbo->bo.bdev->fence_lock); + old_fence = nvbo->bo.sync_obj; + nvbo->bo.sync_obj = fence; spin_unlock(&nvbo->bo.bdev->fence_lock); + + nouveau_fence_unref(&old_fence); } struct ttm_bo_driver nouveau_bo_driver = { -- cgit v1.2.3 From aa2c2e8039e3692065022a7ff885009b2d88818a Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Thu, 4 Nov 2010 13:40:15 +1000 Subject: drm/nv50: fix compute object class Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nv50_graph.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nv50_graph.c b/drivers/gpu/drm/nouveau/nv50_graph.c index e0f52942b2eb..7a98d41c68a6 100644 --- a/drivers/gpu/drm/nouveau/nv50_graph.c +++ b/drivers/gpu/drm/nouveau/nv50_graph.c @@ -425,8 +425,6 @@ nv50_graph_register(struct drm_device *dev) NVOBJ_CLASS(dev, 0x0030, GR); /* null */ NVOBJ_CLASS(dev, 0x5039, GR); /* m2mf */ NVOBJ_CLASS(dev, 0x502d, GR); /* 2d */ - NVOBJ_CLASS(dev, 0x50c0, GR); /* compute */ - NVOBJ_CLASS(dev, 0x85c0, GR); /* compute (nva3, nva5, nva8) */ /* tesla */ if (dev_priv->chipset == 0x50) @@ -452,6 +450,14 @@ nv50_graph_register(struct drm_device *dev) } } + /* compute */ + if (dev_priv->chipset <= 0xa0 || + dev_priv->chipset == 0xaa || + dev_priv->chipset == 0xac) + NVOBJ_CLASS(dev, 0x50c0, GR); + else + NVOBJ_CLASS(dev, 0x85c0, GR); + dev_priv->engine.graph.registered = true; return 0; } -- cgit v1.2.3 From a169f09b96306cc353ffe0e1bc4bc0e1e9492281 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 5 Nov 2010 09:40:00 +1000 Subject: drm/nv50: 0x50c0 apparently works on NVA3+ too, so lets allow it Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nv50_graph.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nv50_graph.c b/drivers/gpu/drm/nouveau/nv50_graph.c index 7a98d41c68a6..6785269f778a 100644 --- a/drivers/gpu/drm/nouveau/nv50_graph.c +++ b/drivers/gpu/drm/nouveau/nv50_graph.c @@ -451,11 +451,10 @@ nv50_graph_register(struct drm_device *dev) } /* compute */ - if (dev_priv->chipset <= 0xa0 || - dev_priv->chipset == 0xaa || - dev_priv->chipset == 0xac) - NVOBJ_CLASS(dev, 0x50c0, GR); - else + NVOBJ_CLASS(dev, 0x50c0, GR); + if (dev_priv->chipset > 0xa0 && + dev_priv->chipset != 0xaa && + dev_priv->chipset != 0xac) NVOBJ_CLASS(dev, 0x85c0, GR); dev_priv->engine.graph.registered = true; -- cgit v1.2.3 From 8f8a54482b008714ccfad15f4592b3802b80d479 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 3 Nov 2010 09:57:28 +1000 Subject: drm/nouveau: allow irq handlers to be installed by engine-specific code Lets start to clean up this mess! Reviewed-by: Francisco Jerez Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_drv.h | 4 ++++ drivers/gpu/drm/nouveau/nouveau_irq.c | 34 +++++++++++++++++++++++++++++++++- 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index a94430b94a20..52dc97d87ebd 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -614,6 +614,7 @@ struct drm_nouveau_private { struct nouveau_bo *vga_ram; /* interrupt handling */ + void (*irq_handler[32])(struct drm_device *); bool msi_enabled; struct workqueue_struct *wq; struct work_struct irq_work; @@ -900,6 +901,9 @@ extern int nouveau_ioctl_gpuobj_free(struct drm_device *, void *data, extern int nouveau_irq_init(struct drm_device *); extern void nouveau_irq_fini(struct drm_device *); extern irqreturn_t nouveau_irq_handler(DRM_IRQ_ARGS); +extern void nouveau_irq_register(struct drm_device *, int status_bit, + void (*)(struct drm_device *)); +extern void nouveau_irq_unregister(struct drm_device *, int status_bit); extern void nouveau_irq_preinstall(struct drm_device *); extern int nouveau_irq_postinstall(struct drm_device *); extern void nouveau_irq_uninstall(struct drm_device *); diff --git a/drivers/gpu/drm/nouveau/nouveau_irq.c b/drivers/gpu/drm/nouveau/nouveau_irq.c index f3ae74ef3318..819bc3dd89e0 100644 --- a/drivers/gpu/drm/nouveau/nouveau_irq.c +++ b/drivers/gpu/drm/nouveau/nouveau_irq.c @@ -1216,8 +1216,9 @@ nouveau_irq_handler(DRM_IRQ_ARGS) { struct drm_device *dev = (struct drm_device *)arg; struct drm_nouveau_private *dev_priv = dev->dev_private; - uint32_t status; unsigned long flags; + u32 status; + int i; status = nv_rd32(dev, NV03_PMC_INTR_0); if (!status) @@ -1267,6 +1268,14 @@ nouveau_irq_handler(DRM_IRQ_ARGS) NV_PMC_INTR_0_NV50_I2C_PENDING); } + for (i = 0; i < 32 && status; i++) { + if (!(status & (1 << i)) || !dev_priv->irq_handler[i]) + continue; + + dev_priv->irq_handler[i](dev); + status &= ~(1 << i); + } + if (status) NV_ERROR(dev, "Unhandled PMC INTR status bits 0x%08x\n", status); @@ -1304,3 +1313,26 @@ nouveau_irq_fini(struct drm_device *dev) if (dev_priv->msi_enabled) pci_disable_msi(dev->pdev); } + +void +nouveau_irq_register(struct drm_device *dev, int status_bit, + void (*handler)(struct drm_device *)) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + unsigned long flags; + + spin_lock_irqsave(&dev_priv->context_switch_lock, flags); + dev_priv->irq_handler[status_bit] = handler; + spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags); +} + +void +nouveau_irq_unregister(struct drm_device *dev, int status_bit) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + unsigned long flags; + + spin_lock_irqsave(&dev_priv->context_switch_lock, flags); + dev_priv->irq_handler[status_bit] = NULL; + spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags); +} -- cgit v1.2.3 From d7facf9dc50acff69de9688088caa78b3cf69ebb Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 3 Nov 2010 10:06:43 +1000 Subject: drm/nv84: move PCRYPT ISR out of nouveau_irq.c Reviewed-by: Francisco Jerez Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/Makefile | 2 +- drivers/gpu/drm/nouveau/nouveau_irq.c | 25 +---------------------- drivers/gpu/drm/nouveau/nouveau_util.c | 36 ++++++++++++++++++++++++++++++++++ drivers/gpu/drm/nouveau/nouveau_util.h | 33 +++++++++++++++++++++++++++++++ drivers/gpu/drm/nouveau/nv84_crypt.c | 27 +++++++++++++++++++++++++ 5 files changed, 98 insertions(+), 25 deletions(-) create mode 100644 drivers/gpu/drm/nouveau/nouveau_util.c create mode 100644 drivers/gpu/drm/nouveau/nouveau_util.h diff --git a/drivers/gpu/drm/nouveau/Makefile b/drivers/gpu/drm/nouveau/Makefile index c8c8de0bbc77..7ea9a1154ca8 100644 --- a/drivers/gpu/drm/nouveau/Makefile +++ b/drivers/gpu/drm/nouveau/Makefile @@ -5,7 +5,7 @@ ccflags-y := -Iinclude/drm nouveau-y := nouveau_drv.o nouveau_state.o nouveau_channel.o nouveau_mem.o \ nouveau_object.o nouveau_irq.o nouveau_notifier.o \ - nouveau_sgdma.o nouveau_dma.o \ + nouveau_sgdma.o nouveau_dma.o nouveau_util.o \ nouveau_bo.o nouveau_fence.o nouveau_gem.o nouveau_ttm.o \ nouveau_hw.o nouveau_calc.o nouveau_bios.o nouveau_i2c.o \ nouveau_display.o nouveau_connector.o nouveau_fbcon.o \ diff --git a/drivers/gpu/drm/nouveau/nouveau_irq.c b/drivers/gpu/drm/nouveau/nouveau_irq.c index 819bc3dd89e0..bdaf8ae44476 100644 --- a/drivers/gpu/drm/nouveau/nouveau_irq.c +++ b/drivers/gpu/drm/nouveau/nouveau_irq.c @@ -36,19 +36,12 @@ #include "nouveau_drv.h" #include "nouveau_reg.h" #include "nouveau_ramht.h" -#include +#include "nouveau_util.h" /* needed for hotplug irq */ #include "nouveau_connector.h" #include "nv50_display.h" -static DEFINE_RATELIMIT_STATE(nouveau_ratelimit_state, 3 * HZ, 20); - -static int nouveau_ratelimit(void) -{ - return __ratelimit(&nouveau_ratelimit_state); -} - void nouveau_irq_preinstall(struct drm_device *dev) { @@ -1240,22 +1233,6 @@ nouveau_irq_handler(DRM_IRQ_ARGS) status &= ~NV_PMC_INTR_0_PGRAPH_PENDING; } - if (status & 0x00004000) { - u32 stat = nv_rd32(dev, 0x102130); - u32 mthd = nv_rd32(dev, 0x102190); - u32 data = nv_rd32(dev, 0x102194); - u32 inst = nv_rd32(dev, 0x102188) & 0x7fffffff; - - NV_INFO(dev, "PCRYPT_INTR: 0x%08x 0x%08x 0x%08x 0x%08x\n", - stat, mthd, data, inst); - nv_wr32(dev, 0x102130, stat); - nv_wr32(dev, 0x10200c, 0x10); - - nv50_fb_vm_trap(dev, nouveau_ratelimit(), "PCRYPT"); - status &= ~0x00004000; - - } - if (status & NV_PMC_INTR_0_CRTCn_PENDING) { nouveau_crtc_irq_handler(dev, (status>>24)&3); status &= ~NV_PMC_INTR_0_CRTCn_PENDING; diff --git a/drivers/gpu/drm/nouveau/nouveau_util.c b/drivers/gpu/drm/nouveau/nouveau_util.c new file mode 100644 index 000000000000..e8b1eaaa212b --- /dev/null +++ b/drivers/gpu/drm/nouveau/nouveau_util.c @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2010 Nouveau Project + * + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#include + +static DEFINE_RATELIMIT_STATE(nouveau_ratelimit_state, 3 * HZ, 20); + +int +nouveau_ratelimit(void) +{ + return __ratelimit(&nouveau_ratelimit_state); +} diff --git a/drivers/gpu/drm/nouveau/nouveau_util.h b/drivers/gpu/drm/nouveau/nouveau_util.h new file mode 100644 index 000000000000..9a7a7c18c99a --- /dev/null +++ b/drivers/gpu/drm/nouveau/nouveau_util.h @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2010 Nouveau Project + * + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifndef __NOUVEAU_UTIL_H__ +#define __NOUVEAU_UTIL_H__ + +int nouveau_ratelimit(void); + +#endif diff --git a/drivers/gpu/drm/nouveau/nv84_crypt.c b/drivers/gpu/drm/nouveau/nv84_crypt.c index f988b1a9d1d7..1cda0240f55d 100644 --- a/drivers/gpu/drm/nouveau/nv84_crypt.c +++ b/drivers/gpu/drm/nouveau/nv84_crypt.c @@ -24,6 +24,9 @@ #include "drmP.h" #include "nouveau_drv.h" +#include "nouveau_util.h" + +static void nv84_crypt_isr(struct drm_device *); int nv84_crypt_create_context(struct nouveau_channel *chan) @@ -97,8 +100,11 @@ nv84_crypt_init(struct drm_device *dev) nv_mask(dev, 0x000200, 0x00004000, 0x00000000); nv_mask(dev, 0x000200, 0x00004000, 0x00004000); + + nouveau_irq_register(dev, 14, nv84_crypt_isr); nv_wr32(dev, 0x102130, 0xffffffff); nv_wr32(dev, 0x102140, 0xffffffbf); + nv_wr32(dev, 0x10200c, 0x00000010); return 0; } @@ -107,4 +113,25 @@ void nv84_crypt_fini(struct drm_device *dev) { nv_wr32(dev, 0x102140, 0x00000000); + nouveau_irq_unregister(dev, 14); +} + +static void +nv84_crypt_isr(struct drm_device *dev) +{ + u32 stat = nv_rd32(dev, 0x102130); + u32 mthd = nv_rd32(dev, 0x102190); + u32 data = nv_rd32(dev, 0x102194); + u32 inst = nv_rd32(dev, 0x102188) & 0x7fffffff; + int show = nouveau_ratelimit(); + + if (show) { + NV_INFO(dev, "PCRYPT_INTR: 0x%08x 0x%08x 0x%08x 0x%08x\n", + stat, mthd, data, inst); + } + + nv_wr32(dev, 0x102130, stat); + nv_wr32(dev, 0x10200c, 0x10); + + nv50_fb_vm_trap(dev, show, "PCRYPT"); } -- cgit v1.2.3 From 2cbd4c818578ef8f2e486dc77267ead1e503c637 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 3 Nov 2010 10:18:04 +1000 Subject: drm/nv50: move GPIO ISR to nv50_gpio.c Reviewed-by: Francisco Jerez Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_drv.h | 1 + drivers/gpu/drm/nouveau/nouveau_irq.c | 6 ++---- drivers/gpu/drm/nouveau/nouveau_state.c | 2 +- drivers/gpu/drm/nouveau/nv50_display.c | 19 ----------------- drivers/gpu/drm/nouveau/nv50_gpio.c | 36 +++++++++++++++++++++++++++++++++ 5 files changed, 40 insertions(+), 24 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index 52dc97d87ebd..c0fad126eaa4 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -1359,6 +1359,7 @@ int nv10_gpio_set(struct drm_device *dev, enum dcb_gpio_tag tag, int state); /* nv50_gpio.c */ int nv50_gpio_init(struct drm_device *dev); +void nv50_gpio_fini(struct drm_device *dev); int nv50_gpio_get(struct drm_device *dev, enum dcb_gpio_tag tag); int nv50_gpio_set(struct drm_device *dev, enum dcb_gpio_tag tag, int state); void nv50_gpio_irq_enable(struct drm_device *, enum dcb_gpio_tag, bool on); diff --git a/drivers/gpu/drm/nouveau/nouveau_irq.c b/drivers/gpu/drm/nouveau/nouveau_irq.c index bdaf8ae44476..061bae33b6e0 100644 --- a/drivers/gpu/drm/nouveau/nouveau_irq.c +++ b/drivers/gpu/drm/nouveau/nouveau_irq.c @@ -1238,11 +1238,9 @@ nouveau_irq_handler(DRM_IRQ_ARGS) status &= ~NV_PMC_INTR_0_CRTCn_PENDING; } - if (status & (NV_PMC_INTR_0_NV50_DISPLAY_PENDING | - NV_PMC_INTR_0_NV50_I2C_PENDING)) { + if (status & NV_PMC_INTR_0_NV50_DISPLAY_PENDING) { nv50_display_irq_handler(dev); - status &= ~(NV_PMC_INTR_0_NV50_DISPLAY_PENDING | - NV_PMC_INTR_0_NV50_I2C_PENDING); + status &= ~NV_PMC_INTR_0_NV50_DISPLAY_PENDING; } for (i = 0; i < 32 && status; i++) { diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c index 1a7a50ccb7c8..84bff459491e 100644 --- a/drivers/gpu/drm/nouveau/nouveau_state.c +++ b/drivers/gpu/drm/nouveau/nouveau_state.c @@ -393,7 +393,7 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->display.init = nv50_display_init; engine->display.destroy = nv50_display_destroy; engine->gpio.init = nv50_gpio_init; - engine->gpio.takedown = nouveau_stub_takedown; + engine->gpio.takedown = nv50_gpio_fini; engine->gpio.get = nv50_gpio_get; engine->gpio.set = nv50_gpio_set; engine->gpio.irq_enable = nv50_gpio_irq_enable; diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c index 41b212801870..42cb5b5c73c0 100644 --- a/drivers/gpu/drm/nouveau/nv50_display.c +++ b/drivers/gpu/drm/nouveau/nv50_display.c @@ -869,25 +869,6 @@ nv50_display_irq_handler(struct drm_device *dev) struct drm_nouveau_private *dev_priv = dev->dev_private; uint32_t delayed = 0; - if (nv_rd32(dev, NV50_PMC_INTR_0) & NV50_PMC_INTR_0_HOTPLUG) { - uint32_t hpd0_bits, hpd1_bits = 0; - - hpd0_bits = nv_rd32(dev, 0xe054); - nv_wr32(dev, 0xe054, hpd0_bits); - - if (dev_priv->chipset >= 0x90) { - hpd1_bits = nv_rd32(dev, 0xe074); - nv_wr32(dev, 0xe074, hpd1_bits); - } - - spin_lock(&dev_priv->hpd_state.lock); - dev_priv->hpd_state.hpd0_bits |= hpd0_bits; - dev_priv->hpd_state.hpd1_bits |= hpd1_bits; - spin_unlock(&dev_priv->hpd_state.lock); - - queue_work(dev_priv->wq, &dev_priv->hpd_work); - } - while (nv_rd32(dev, NV50_PMC_INTR_0) & NV50_PMC_INTR_0_DISPLAY) { uint32_t intr0 = nv_rd32(dev, NV50_PDISPLAY_INTR_0); uint32_t intr1 = nv_rd32(dev, NV50_PDISPLAY_INTR_1); diff --git a/drivers/gpu/drm/nouveau/nv50_gpio.c b/drivers/gpu/drm/nouveau/nv50_gpio.c index b2fab2bf3d61..302f7ebe5b6f 100644 --- a/drivers/gpu/drm/nouveau/nv50_gpio.c +++ b/drivers/gpu/drm/nouveau/nv50_gpio.c @@ -26,6 +26,8 @@ #include "nouveau_drv.h" #include "nouveau_hw.h" +static void nv50_gpio_isr(struct drm_device *dev); + static int nv50_gpio_location(struct dcb_gpio_entry *gpio, uint32_t *reg, uint32_t *shift) { @@ -107,5 +109,39 @@ nv50_gpio_init(struct drm_device *dev) nv_wr32(dev, 0xe074, 0xffffffff); } + nouveau_irq_register(dev, 21, nv50_gpio_isr); return 0; } + +void +nv50_gpio_fini(struct drm_device *dev) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + + nv_wr32(dev, 0xe050, 0x00000000); + if (dev_priv->chipset >= 0x90) + nv_wr32(dev, 0xe070, 0x00000000); + nouveau_irq_unregister(dev, 21); +} + +static void +nv50_gpio_isr(struct drm_device *dev) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + uint32_t hpd0_bits, hpd1_bits = 0; + + hpd0_bits = nv_rd32(dev, 0xe054); + nv_wr32(dev, 0xe054, hpd0_bits); + + if (dev_priv->chipset >= 0x90) { + hpd1_bits = nv_rd32(dev, 0xe074); + nv_wr32(dev, 0xe074, hpd1_bits); + } + + spin_lock(&dev_priv->hpd_state.lock); + dev_priv->hpd_state.hpd0_bits |= hpd0_bits; + dev_priv->hpd_state.hpd1_bits |= hpd1_bits; + spin_unlock(&dev_priv->hpd_state.lock); + + queue_work(dev_priv->wq, &dev_priv->hpd_work); +} -- cgit v1.2.3 From 19b7fc7bf59f4bf02ee738a79baaccae31220df3 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 3 Nov 2010 10:27:27 +1000 Subject: drm/nv50: use register/unregister functionality for PDISPLAY ISR Reviewed-by: Francisco Jerez Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_irq.c | 16 +--------------- drivers/gpu/drm/nouveau/nv50_display.c | 10 ++++++++-- drivers/gpu/drm/nouveau/nv50_display.h | 1 - drivers/gpu/drm/nouveau/nv50_gpio.c | 4 ++++ 4 files changed, 13 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_irq.c b/drivers/gpu/drm/nouveau/nouveau_irq.c index 061bae33b6e0..2f546884f2ed 100644 --- a/drivers/gpu/drm/nouveau/nouveau_irq.c +++ b/drivers/gpu/drm/nouveau/nouveau_irq.c @@ -38,10 +38,6 @@ #include "nouveau_ramht.h" #include "nouveau_util.h" -/* needed for hotplug irq */ -#include "nouveau_connector.h" -#include "nv50_display.h" - void nouveau_irq_preinstall(struct drm_device *dev) { @@ -50,12 +46,7 @@ nouveau_irq_preinstall(struct drm_device *dev) /* Master disable */ nv_wr32(dev, NV03_PMC_INTR_EN_0, 0); - if (dev_priv->card_type >= NV_50) { - INIT_WORK(&dev_priv->irq_work, nv50_display_irq_handler_bh); - INIT_WORK(&dev_priv->hpd_work, nv50_display_irq_hotplug_bh); - spin_lock_init(&dev_priv->hpd_state.lock); - INIT_LIST_HEAD(&dev_priv->vbl_waiting); - } + INIT_LIST_HEAD(&dev_priv->vbl_waiting); } int @@ -1238,11 +1229,6 @@ nouveau_irq_handler(DRM_IRQ_ARGS) status &= ~NV_PMC_INTR_0_CRTCn_PENDING; } - if (status & NV_PMC_INTR_0_NV50_DISPLAY_PENDING) { - nv50_display_irq_handler(dev); - status &= ~NV_PMC_INTR_0_NV50_DISPLAY_PENDING; - } - for (i = 0; i < 32 && status; i++) { if (!(status & (1 << i)) || !dev_priv->irq_handler[i]) continue; diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c index 42cb5b5c73c0..e5dbd171672c 100644 --- a/drivers/gpu/drm/nouveau/nv50_display.c +++ b/drivers/gpu/drm/nouveau/nv50_display.c @@ -33,6 +33,8 @@ #include "nouveau_ramht.h" #include "drm_crtc_helper.h" +static void nv50_display_isr(struct drm_device *); + static inline int nv50_sor_nr(struct drm_device *dev) { @@ -328,6 +330,9 @@ int nv50_display_create(struct drm_device *dev) } } + INIT_WORK(&dev_priv->irq_work, nv50_display_irq_handler_bh); + nouveau_irq_register(dev, 26, nv50_display_isr); + ret = nv50_display_init(dev); if (ret) { nv50_display_destroy(dev); @@ -345,6 +350,7 @@ nv50_display_destroy(struct drm_device *dev) drm_mode_config_cleanup(dev); nv50_display_disable(dev); + nouveau_irq_unregister(dev, 26); } static u16 @@ -863,8 +869,8 @@ nv50_display_irq_hotplug_bh(struct work_struct *work) drm_helper_hpd_irq_event(dev); } -void -nv50_display_irq_handler(struct drm_device *dev) +static void +nv50_display_isr(struct drm_device *dev) { struct drm_nouveau_private *dev_priv = dev->dev_private; uint32_t delayed = 0; diff --git a/drivers/gpu/drm/nouveau/nv50_display.h b/drivers/gpu/drm/nouveau/nv50_display.h index c551f0b85ee0..a269fccf3555 100644 --- a/drivers/gpu/drm/nouveau/nv50_display.h +++ b/drivers/gpu/drm/nouveau/nv50_display.h @@ -35,7 +35,6 @@ #include "nouveau_crtc.h" #include "nv50_evo.h" -void nv50_display_irq_handler(struct drm_device *dev); void nv50_display_irq_handler_bh(struct work_struct *work); void nv50_display_irq_hotplug_bh(struct work_struct *work); int nv50_display_early_init(struct drm_device *dev); diff --git a/drivers/gpu/drm/nouveau/nv50_gpio.c b/drivers/gpu/drm/nouveau/nv50_gpio.c index 302f7ebe5b6f..87266d1b5def 100644 --- a/drivers/gpu/drm/nouveau/nv50_gpio.c +++ b/drivers/gpu/drm/nouveau/nv50_gpio.c @@ -26,6 +26,8 @@ #include "nouveau_drv.h" #include "nouveau_hw.h" +#include "nv50_display.h" + static void nv50_gpio_isr(struct drm_device *dev); static int @@ -109,6 +111,8 @@ nv50_gpio_init(struct drm_device *dev) nv_wr32(dev, 0xe074, 0xffffffff); } + INIT_WORK(&dev_priv->hpd_work, nv50_display_irq_hotplug_bh); + spin_lock_init(&dev_priv->hpd_state.lock); nouveau_irq_register(dev, 21, nv50_gpio_isr); return 0; } -- cgit v1.2.3 From 8cbe71a6e70b5439ae60bd542231c4b8878a8f1c Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 3 Nov 2010 10:45:48 +1000 Subject: drm/nouveau: move bitfield/enum helpers to nouveau_util.c Reviewed-by: Francisco Jerez Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_irq.c | 86 +++++++--------------------------- drivers/gpu/drm/nouveau/nouveau_util.c | 33 +++++++++++++ drivers/gpu/drm/nouveau/nouveau_util.h | 12 +++++ 3 files changed, 63 insertions(+), 68 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_irq.c b/drivers/gpu/drm/nouveau/nouveau_irq.c index 2f546884f2ed..e8a3c400f741 100644 --- a/drivers/gpu/drm/nouveau/nouveau_irq.c +++ b/drivers/gpu/drm/nouveau/nouveau_irq.c @@ -267,28 +267,25 @@ nouveau_fifo_irq_handler(struct drm_device *dev) nv_wr32(dev, NV03_PMC_INTR_0, NV_PMC_INTR_0_PFIFO_PENDING); } -struct nouveau_bitfield_names { - uint32_t mask; - const char *name; -}; - -static struct nouveau_bitfield_names nstatus_names[] = +static struct nouveau_bitfield nstatus_names[] = { { NV04_PGRAPH_NSTATUS_STATE_IN_USE, "STATE_IN_USE" }, { NV04_PGRAPH_NSTATUS_INVALID_STATE, "INVALID_STATE" }, { NV04_PGRAPH_NSTATUS_BAD_ARGUMENT, "BAD_ARGUMENT" }, - { NV04_PGRAPH_NSTATUS_PROTECTION_FAULT, "PROTECTION_FAULT" } + { NV04_PGRAPH_NSTATUS_PROTECTION_FAULT, "PROTECTION_FAULT" }, + {} }; -static struct nouveau_bitfield_names nstatus_names_nv10[] = +static struct nouveau_bitfield nstatus_names_nv10[] = { { NV10_PGRAPH_NSTATUS_STATE_IN_USE, "STATE_IN_USE" }, { NV10_PGRAPH_NSTATUS_INVALID_STATE, "INVALID_STATE" }, { NV10_PGRAPH_NSTATUS_BAD_ARGUMENT, "BAD_ARGUMENT" }, - { NV10_PGRAPH_NSTATUS_PROTECTION_FAULT, "PROTECTION_FAULT" } + { NV10_PGRAPH_NSTATUS_PROTECTION_FAULT, "PROTECTION_FAULT" }, + {} }; -static struct nouveau_bitfield_names nsource_names[] = +static struct nouveau_bitfield nsource_names[] = { { NV03_PGRAPH_NSOURCE_NOTIFICATION, "NOTIFICATION" }, { NV03_PGRAPH_NSOURCE_DATA_ERROR, "DATA_ERROR" }, @@ -309,57 +306,9 @@ static struct nouveau_bitfield_names nsource_names[] = { NV03_PGRAPH_NSOURCE_DMA_VTX_PROTECTION, "DMA_VTX_PROTECTION" }, { NV03_PGRAPH_NSOURCE_DMA_WIDTH_A, "DMA_WIDTH_A" }, { NV03_PGRAPH_NSOURCE_DMA_WIDTH_B, "DMA_WIDTH_B" }, + {} }; -static void -nouveau_print_bitfield_names_(uint32_t value, - const struct nouveau_bitfield_names *namelist, - const int namelist_len) -{ - /* - * Caller must have already printed the KERN_* log level for us. - * Also the caller is responsible for adding the newline. - */ - int i; - for (i = 0; i < namelist_len; ++i) { - uint32_t mask = namelist[i].mask; - if (value & mask) { - printk(" %s", namelist[i].name); - value &= ~mask; - } - } - if (value) - printk(" (unknown bits 0x%08x)", value); -} -#define nouveau_print_bitfield_names(val, namelist) \ - nouveau_print_bitfield_names_((val), (namelist), ARRAY_SIZE(namelist)) - -struct nouveau_enum_names { - uint32_t value; - const char *name; -}; - -static void -nouveau_print_enum_names_(uint32_t value, - const struct nouveau_enum_names *namelist, - const int namelist_len) -{ - /* - * Caller must have already printed the KERN_* log level for us. - * Also the caller is responsible for adding the newline. - */ - int i; - for (i = 0; i < namelist_len; ++i) { - if (value == namelist[i].value) { - printk("%s", namelist[i].name); - return; - } - } - printk("unknown value 0x%08x", value); -} -#define nouveau_print_enum_names(val, namelist) \ - nouveau_print_enum_names_((val), (namelist), ARRAY_SIZE(namelist)) - static int nouveau_graph_chid_from_grctx(struct drm_device *dev) { @@ -482,12 +431,12 @@ nouveau_graph_dump_trap_info(struct drm_device *dev, const char *id, if (dev_priv->card_type < NV_50) { NV_INFO(dev, "%s - nSource:", id); - nouveau_print_bitfield_names(nsource, nsource_names); + nouveau_bitfield_print(nsource_names, nsource); printk(", nStatus:"); if (dev_priv->card_type < NV_10) - nouveau_print_bitfield_names(nstatus, nstatus_names); + nouveau_bitfield_print(nstatus_names, nstatus); else - nouveau_print_bitfield_names(nstatus, nstatus_names_nv10); + nouveau_bitfield_print(nstatus_names_nv10, nstatus); printk("\n"); } @@ -631,13 +580,14 @@ nouveau_pgraph_irq_handler(struct drm_device *dev) nv_wr32(dev, NV03_PMC_INTR_0, NV_PMC_INTR_0_PGRAPH_PENDING); } -static struct nouveau_enum_names nv50_mp_exec_error_names[] = +static struct nouveau_enum nv50_mp_exec_error_names[] = { { 3, "STACK_UNDERFLOW" }, { 4, "QUADON_ACTIVE" }, { 8, "TIMEOUT" }, { 0x10, "INVALID_OPCODE" }, { 0x40, "BREAKPOINT" }, + {} }; static void @@ -666,8 +616,7 @@ nv50_pgraph_mp_trap(struct drm_device *dev, int tpid, int display) ophigh= nv_rd32(dev, addr + 0x74); NV_INFO(dev, "PGRAPH_TRAP_MP_EXEC - " "TP %d MP %d: ", tpid, i); - nouveau_print_enum_names(status, - nv50_mp_exec_error_names); + nouveau_enum_print(nv50_mp_exec_error_names, status); printk(" at %06x warp %d, opcode %08x %08x\n", pc&0xffffff, pc >> 24, oplow, ophigh); @@ -1020,7 +969,7 @@ nv50_pgraph_trap_handler(struct drm_device *dev) } /* There must be a *lot* of these. Will take some time to gather them up. */ -static struct nouveau_enum_names nv50_data_error_names[] = +static struct nouveau_enum nv50_data_error_names[] = { { 4, "INVALID_VALUE" }, { 5, "INVALID_ENUM" }, @@ -1028,6 +977,7 @@ static struct nouveau_enum_names nv50_data_error_names[] = { 0xc, "INVALID_BITFIELD" }, { 0x28, "MP_NO_REG_SPACE" }, { 0x2b, "MP_BLOCK_SIZE_MISMATCH" }, + {} }; static void @@ -1126,8 +1076,8 @@ nv50_pgraph_irq_handler(struct drm_device *dev) nouveau_graph_dump_trap_info(dev, "PGRAPH_DATA_ERROR", &trap); NV_INFO (dev, "PGRAPH_DATA_ERROR - "); - nouveau_print_enum_names(nv_rd32(dev, 0x400110), - nv50_data_error_names); + nouveau_enum_print(nv50_data_error_names, + nv_rd32(dev, 0x400110)); printk("\n"); } status &= ~0x00100000; diff --git a/drivers/gpu/drm/nouveau/nouveau_util.c b/drivers/gpu/drm/nouveau/nouveau_util.c index e8b1eaaa212b..fbe0fb13bc1e 100644 --- a/drivers/gpu/drm/nouveau/nouveau_util.c +++ b/drivers/gpu/drm/nouveau/nouveau_util.c @@ -27,8 +27,41 @@ #include +#include "nouveau_util.h" + static DEFINE_RATELIMIT_STATE(nouveau_ratelimit_state, 3 * HZ, 20); +void +nouveau_bitfield_print(const struct nouveau_bitfield *bf, u32 value) +{ + while (bf->name) { + if (value & bf->mask) { + printk(" %s", bf->name); + value &= ~bf->mask; + } + + bf++; + } + + if (value) + printk(" (unknown bits 0x%08x)", value); +} + +void +nouveau_enum_print(const struct nouveau_enum *en, u32 value) +{ + while (en->name) { + if (value == en->value) { + printk("%s", en->name); + return; + } + + en++; + } + + printk("(unknown enum 0x%08x)", value); +} + int nouveau_ratelimit(void) { diff --git a/drivers/gpu/drm/nouveau/nouveau_util.h b/drivers/gpu/drm/nouveau/nouveau_util.h index 9a7a7c18c99a..d9ceaea26f4b 100644 --- a/drivers/gpu/drm/nouveau/nouveau_util.h +++ b/drivers/gpu/drm/nouveau/nouveau_util.h @@ -28,6 +28,18 @@ #ifndef __NOUVEAU_UTIL_H__ #define __NOUVEAU_UTIL_H__ +struct nouveau_bitfield { + u32 mask; + const char *name; +}; + +struct nouveau_enum { + u32 value; + const char *name; +}; + +void nouveau_bitfield_print(const struct nouveau_bitfield *, u32 value); +void nouveau_enum_print(const struct nouveau_enum *, u32 value); int nouveau_ratelimit(void); #endif -- cgit v1.2.3 From 25b85783da8c71e577c676173e9d60a1b7e6113a Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 3 Nov 2010 11:36:09 +1000 Subject: drm/nv04-nv40: register vblank isr Reviewed-by: Francisco Jerez Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_irq.c | 19 ------------------- drivers/gpu/drm/nouveau/nv04_display.c | 18 ++++++++++++++++++ 2 files changed, 18 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_irq.c b/drivers/gpu/drm/nouveau/nouveau_irq.c index e8a3c400f741..6c30669ac0b6 100644 --- a/drivers/gpu/drm/nouveau/nouveau_irq.c +++ b/drivers/gpu/drm/nouveau/nouveau_irq.c @@ -1131,20 +1131,6 @@ nv50_pgraph_irq_handler(struct drm_device *dev) nv_wr32(dev, 0x400824, nv_rd32(dev, 0x400824) & ~(1 << 31)); } -static void -nouveau_crtc_irq_handler(struct drm_device *dev, int crtc) -{ - if (crtc & 1) { - nv_wr32(dev, NV_CRTC0_INTSTAT, NV_CRTC_INTR_VBLANK); - drm_handle_vblank(dev, 0); - } - - if (crtc & 2) { - nv_wr32(dev, NV_CRTC1_INTSTAT, NV_CRTC_INTR_VBLANK); - drm_handle_vblank(dev, 1); - } -} - irqreturn_t nouveau_irq_handler(DRM_IRQ_ARGS) { @@ -1174,11 +1160,6 @@ nouveau_irq_handler(DRM_IRQ_ARGS) status &= ~NV_PMC_INTR_0_PGRAPH_PENDING; } - if (status & NV_PMC_INTR_0_CRTCn_PENDING) { - nouveau_crtc_irq_handler(dev, (status>>24)&3); - status &= ~NV_PMC_INTR_0_CRTCn_PENDING; - } - for (i = 0; i < 32 && status; i++) { if (!(status & (1 << i)) || !dev_priv->irq_handler[i]) continue; diff --git a/drivers/gpu/drm/nouveau/nv04_display.c b/drivers/gpu/drm/nouveau/nv04_display.c index 9e28cf772e3c..0978a5b326dc 100644 --- a/drivers/gpu/drm/nouveau/nv04_display.c +++ b/drivers/gpu/drm/nouveau/nv04_display.c @@ -32,6 +32,9 @@ #include "nouveau_encoder.h" #include "nouveau_connector.h" +static void nv04_vblank_crtc0_isr(struct drm_device *); +static void nv04_vblank_crtc1_isr(struct drm_device *); + static void nv04_display_store_initial_head_owner(struct drm_device *dev) { @@ -197,6 +200,8 @@ nv04_display_create(struct drm_device *dev) func->save(encoder); } + nouveau_irq_register(dev, 24, nv04_vblank_crtc0_isr); + nouveau_irq_register(dev, 25, nv04_vblank_crtc1_isr); return 0; } @@ -258,3 +263,16 @@ nv04_display_init(struct drm_device *dev) return 0; } +static void +nv04_vblank_crtc0_isr(struct drm_device *dev) +{ + nv_wr32(dev, NV_CRTC0_INTSTAT, NV_CRTC_INTR_VBLANK); + drm_handle_vblank(dev, 0); +} + +static void +nv04_vblank_crtc1_isr(struct drm_device *dev) +{ + nv_wr32(dev, NV_CRTC1_INTSTAT, NV_CRTC_INTR_VBLANK); + drm_handle_vblank(dev, 1); +} -- cgit v1.2.3 From 5178d40dff23b5eef7f0a3be2411fa6a347e750d Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 3 Nov 2010 10:56:05 +1000 Subject: drm/nouveau: move PFIFO ISR into nv04_fifo.c Reviewed-by: Francisco Jerez Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_drv.h | 2 + drivers/gpu/drm/nouveau/nouveau_irq.c | 203 ------------------------------- drivers/gpu/drm/nouveau/nouveau_state.c | 10 +- drivers/gpu/drm/nouveau/nv04_fifo.c | 206 ++++++++++++++++++++++++++++++++ drivers/gpu/drm/nouveau/nv10_fifo.c | 1 + drivers/gpu/drm/nouveau/nv40_fifo.c | 1 + drivers/gpu/drm/nouveau/nv50_fifo.c | 4 + 7 files changed, 219 insertions(+), 208 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index c0fad126eaa4..e174479ab675 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -1053,6 +1053,7 @@ extern void nvc0_fb_takedown(struct drm_device *); /* nv04_fifo.c */ extern int nv04_fifo_init(struct drm_device *); +extern void nv04_fifo_fini(struct drm_device *); extern void nv04_fifo_disable(struct drm_device *); extern void nv04_fifo_enable(struct drm_device *); extern bool nv04_fifo_reassign(struct drm_device *, bool); @@ -1062,6 +1063,7 @@ extern int nv04_fifo_create_context(struct nouveau_channel *); extern void nv04_fifo_destroy_context(struct nouveau_channel *); extern int nv04_fifo_load_context(struct nouveau_channel *); extern int nv04_fifo_unload_context(struct drm_device *); +extern void nv04_fifo_isr(struct drm_device *); /* nv10_fifo.c */ extern int nv10_fifo_init(struct drm_device *); diff --git a/drivers/gpu/drm/nouveau/nouveau_irq.c b/drivers/gpu/drm/nouveau/nouveau_irq.c index 6c30669ac0b6..16f42f774a9e 100644 --- a/drivers/gpu/drm/nouveau/nouveau_irq.c +++ b/drivers/gpu/drm/nouveau/nouveau_irq.c @@ -69,204 +69,6 @@ nouveau_irq_uninstall(struct drm_device *dev) nv_wr32(dev, NV03_PMC_INTR_EN_0, 0); } -static bool -nouveau_fifo_swmthd(struct drm_device *dev, u32 chid, u32 addr, u32 data) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_channel *chan = NULL; - struct nouveau_gpuobj *obj; - unsigned long flags; - const int subc = (addr >> 13) & 0x7; - const int mthd = addr & 0x1ffc; - bool handled = false; - u32 engine; - - spin_lock_irqsave(&dev_priv->channels.lock, flags); - if (likely(chid >= 0 && chid < dev_priv->engine.fifo.channels)) - chan = dev_priv->channels.ptr[chid]; - if (unlikely(!chan)) - goto out; - - switch (mthd) { - case 0x0000: /* bind object to subchannel */ - obj = nouveau_ramht_find(chan, data); - if (unlikely(!obj || obj->engine != NVOBJ_ENGINE_SW)) - break; - - chan->sw_subchannel[subc] = obj->class; - engine = 0x0000000f << (subc * 4); - - nv_mask(dev, NV04_PFIFO_CACHE1_ENGINE, engine, 0x00000000); - handled = true; - break; - default: - engine = nv_rd32(dev, NV04_PFIFO_CACHE1_ENGINE); - if (unlikely(((engine >> (subc * 4)) & 0xf) != 0)) - break; - - if (!nouveau_gpuobj_mthd_call(chan, chan->sw_subchannel[subc], - mthd, data)) - handled = true; - break; - } - -out: - spin_unlock_irqrestore(&dev_priv->channels.lock, flags); - return handled; -} - -static void -nouveau_fifo_irq_handler(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_engine *engine = &dev_priv->engine; - uint32_t status, reassign; - int cnt = 0; - - reassign = nv_rd32(dev, NV03_PFIFO_CACHES) & 1; - while ((status = nv_rd32(dev, NV03_PFIFO_INTR_0)) && (cnt++ < 100)) { - uint32_t chid, get; - - nv_wr32(dev, NV03_PFIFO_CACHES, 0); - - chid = engine->fifo.channel_id(dev); - get = nv_rd32(dev, NV03_PFIFO_CACHE1_GET); - - if (status & NV_PFIFO_INTR_CACHE_ERROR) { - uint32_t mthd, data; - int ptr; - - /* NV_PFIFO_CACHE1_GET actually goes to 0xffc before - * wrapping on my G80 chips, but CACHE1 isn't big - * enough for this much data.. Tests show that it - * wraps around to the start at GET=0x800.. No clue - * as to why.. - */ - ptr = (get & 0x7ff) >> 2; - - if (dev_priv->card_type < NV_40) { - mthd = nv_rd32(dev, - NV04_PFIFO_CACHE1_METHOD(ptr)); - data = nv_rd32(dev, - NV04_PFIFO_CACHE1_DATA(ptr)); - } else { - mthd = nv_rd32(dev, - NV40_PFIFO_CACHE1_METHOD(ptr)); - data = nv_rd32(dev, - NV40_PFIFO_CACHE1_DATA(ptr)); - } - - if (!nouveau_fifo_swmthd(dev, chid, mthd, data)) { - NV_INFO(dev, "PFIFO_CACHE_ERROR - Ch %d/%d " - "Mthd 0x%04x Data 0x%08x\n", - chid, (mthd >> 13) & 7, mthd & 0x1ffc, - data); - } - - nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_PUSH, 0); - nv_wr32(dev, NV03_PFIFO_INTR_0, - NV_PFIFO_INTR_CACHE_ERROR); - - nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH0, - nv_rd32(dev, NV03_PFIFO_CACHE1_PUSH0) & ~1); - nv_wr32(dev, NV03_PFIFO_CACHE1_GET, get + 4); - nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH0, - nv_rd32(dev, NV03_PFIFO_CACHE1_PUSH0) | 1); - nv_wr32(dev, NV04_PFIFO_CACHE1_HASH, 0); - - nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_PUSH, - nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_PUSH) | 1); - nv_wr32(dev, NV04_PFIFO_CACHE1_PULL0, 1); - - status &= ~NV_PFIFO_INTR_CACHE_ERROR; - } - - if (status & NV_PFIFO_INTR_DMA_PUSHER) { - u32 dma_get = nv_rd32(dev, 0x003244); - u32 dma_put = nv_rd32(dev, 0x003240); - u32 push = nv_rd32(dev, 0x003220); - u32 state = nv_rd32(dev, 0x003228); - - if (dev_priv->card_type == NV_50) { - u32 ho_get = nv_rd32(dev, 0x003328); - u32 ho_put = nv_rd32(dev, 0x003320); - u32 ib_get = nv_rd32(dev, 0x003334); - u32 ib_put = nv_rd32(dev, 0x003330); - - if (nouveau_ratelimit()) - NV_INFO(dev, "PFIFO_DMA_PUSHER - Ch %d Get 0x%02x%08x " - "Put 0x%02x%08x IbGet 0x%08x IbPut 0x%08x " - "State 0x%08x Push 0x%08x\n", - chid, ho_get, dma_get, ho_put, - dma_put, ib_get, ib_put, state, - push); - - /* METHOD_COUNT, in DMA_STATE on earlier chipsets */ - nv_wr32(dev, 0x003364, 0x00000000); - if (dma_get != dma_put || ho_get != ho_put) { - nv_wr32(dev, 0x003244, dma_put); - nv_wr32(dev, 0x003328, ho_put); - } else - if (ib_get != ib_put) { - nv_wr32(dev, 0x003334, ib_put); - } - } else { - NV_INFO(dev, "PFIFO_DMA_PUSHER - Ch %d Get 0x%08x " - "Put 0x%08x State 0x%08x Push 0x%08x\n", - chid, dma_get, dma_put, state, push); - - if (dma_get != dma_put) - nv_wr32(dev, 0x003244, dma_put); - } - - nv_wr32(dev, 0x003228, 0x00000000); - nv_wr32(dev, 0x003220, 0x00000001); - nv_wr32(dev, 0x002100, NV_PFIFO_INTR_DMA_PUSHER); - status &= ~NV_PFIFO_INTR_DMA_PUSHER; - } - - if (status & NV_PFIFO_INTR_SEMAPHORE) { - uint32_t sem; - - status &= ~NV_PFIFO_INTR_SEMAPHORE; - nv_wr32(dev, NV03_PFIFO_INTR_0, - NV_PFIFO_INTR_SEMAPHORE); - - sem = nv_rd32(dev, NV10_PFIFO_CACHE1_SEMAPHORE); - nv_wr32(dev, NV10_PFIFO_CACHE1_SEMAPHORE, sem | 0x1); - - nv_wr32(dev, NV03_PFIFO_CACHE1_GET, get + 4); - nv_wr32(dev, NV04_PFIFO_CACHE1_PULL0, 1); - } - - if (dev_priv->card_type == NV_50) { - if (status & 0x00000010) { - nv50_fb_vm_trap(dev, 1, "PFIFO_BAR_FAULT"); - status &= ~0x00000010; - nv_wr32(dev, 0x002100, 0x00000010); - } - } - - if (status) { - if (nouveau_ratelimit()) - NV_INFO(dev, "PFIFO_INTR 0x%08x - Ch %d\n", - status, chid); - nv_wr32(dev, NV03_PFIFO_INTR_0, status); - status = 0; - } - - nv_wr32(dev, NV03_PFIFO_CACHES, reassign); - } - - if (status) { - NV_INFO(dev, "PFIFO still angry after %d spins, halt\n", cnt); - nv_wr32(dev, 0x2140, 0); - nv_wr32(dev, 0x140, 0); - } - - nv_wr32(dev, NV03_PMC_INTR_0, NV_PMC_INTR_0_PFIFO_PENDING); -} - static struct nouveau_bitfield nstatus_names[] = { { NV04_PGRAPH_NSTATUS_STATE_IN_USE, "STATE_IN_USE" }, @@ -1146,11 +948,6 @@ nouveau_irq_handler(DRM_IRQ_ARGS) spin_lock_irqsave(&dev_priv->context_switch_lock, flags); - if (status & NV_PMC_INTR_0_PFIFO_PENDING) { - nouveau_fifo_irq_handler(dev); - status &= ~NV_PMC_INTR_0_PFIFO_PENDING; - } - if (status & NV_PMC_INTR_0_PGRAPH_PENDING) { if (dev_priv->card_type >= NV_50) nv50_pgraph_irq_handler(dev); diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c index 84bff459491e..262545b58d96 100644 --- a/drivers/gpu/drm/nouveau/nouveau_state.c +++ b/drivers/gpu/drm/nouveau/nouveau_state.c @@ -75,7 +75,7 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->graph.unload_context = nv04_graph_unload_context; engine->fifo.channels = 16; engine->fifo.init = nv04_fifo_init; - engine->fifo.takedown = nouveau_stub_takedown; + engine->fifo.takedown = nv04_fifo_fini; engine->fifo.disable = nv04_fifo_disable; engine->fifo.enable = nv04_fifo_enable; engine->fifo.reassign = nv04_fifo_reassign; @@ -132,7 +132,7 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->graph.set_tile_region = nv10_graph_set_tile_region; engine->fifo.channels = 32; engine->fifo.init = nv10_fifo_init; - engine->fifo.takedown = nouveau_stub_takedown; + engine->fifo.takedown = nv04_fifo_fini; engine->fifo.disable = nv04_fifo_disable; engine->fifo.enable = nv04_fifo_enable; engine->fifo.reassign = nv04_fifo_reassign; @@ -189,7 +189,7 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->graph.set_tile_region = nv20_graph_set_tile_region; engine->fifo.channels = 32; engine->fifo.init = nv10_fifo_init; - engine->fifo.takedown = nouveau_stub_takedown; + engine->fifo.takedown = nv04_fifo_fini; engine->fifo.disable = nv04_fifo_disable; engine->fifo.enable = nv04_fifo_enable; engine->fifo.reassign = nv04_fifo_reassign; @@ -246,7 +246,7 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->graph.set_tile_region = nv20_graph_set_tile_region; engine->fifo.channels = 32; engine->fifo.init = nv10_fifo_init; - engine->fifo.takedown = nouveau_stub_takedown; + engine->fifo.takedown = nv04_fifo_fini; engine->fifo.disable = nv04_fifo_disable; engine->fifo.enable = nv04_fifo_enable; engine->fifo.reassign = nv04_fifo_reassign; @@ -306,7 +306,7 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->graph.set_tile_region = nv40_graph_set_tile_region; engine->fifo.channels = 32; engine->fifo.init = nv40_fifo_init; - engine->fifo.takedown = nouveau_stub_takedown; + engine->fifo.takedown = nv04_fifo_fini; engine->fifo.disable = nv04_fifo_disable; engine->fifo.enable = nv04_fifo_enable; engine->fifo.reassign = nv04_fifo_reassign; diff --git a/drivers/gpu/drm/nouveau/nv04_fifo.c b/drivers/gpu/drm/nouveau/nv04_fifo.c index 4c0d3a8fca68..a32ba8ccaae6 100644 --- a/drivers/gpu/drm/nouveau/nv04_fifo.c +++ b/drivers/gpu/drm/nouveau/nv04_fifo.c @@ -28,6 +28,7 @@ #include "drm.h" #include "nouveau_drv.h" #include "nouveau_ramht.h" +#include "nouveau_util.h" #define NV04_RAMFC(c) (dev_priv->ramfc->pinst + ((c) * NV04_RAMFC__SIZE)) #define NV04_RAMFC__SIZE 32 @@ -284,6 +285,7 @@ nv04_fifo_init_ramxx(struct drm_device *dev) static void nv04_fifo_init_intr(struct drm_device *dev) { + nouveau_irq_register(dev, 8, nv04_fifo_isr); nv_wr32(dev, 0x002100, 0xffffffff); nv_wr32(dev, 0x002140, 0xffffffff); } @@ -315,3 +317,207 @@ nv04_fifo_init(struct drm_device *dev) return 0; } +void +nv04_fifo_fini(struct drm_device *dev) +{ + nv_wr32(dev, 0x2140, 0x00000000); + nouveau_irq_unregister(dev, 8); +} + +static bool +nouveau_fifo_swmthd(struct drm_device *dev, u32 chid, u32 addr, u32 data) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_channel *chan = NULL; + struct nouveau_gpuobj *obj; + unsigned long flags; + const int subc = (addr >> 13) & 0x7; + const int mthd = addr & 0x1ffc; + bool handled = false; + u32 engine; + + spin_lock_irqsave(&dev_priv->channels.lock, flags); + if (likely(chid >= 0 && chid < dev_priv->engine.fifo.channels)) + chan = dev_priv->channels.ptr[chid]; + if (unlikely(!chan)) + goto out; + + switch (mthd) { + case 0x0000: /* bind object to subchannel */ + obj = nouveau_ramht_find(chan, data); + if (unlikely(!obj || obj->engine != NVOBJ_ENGINE_SW)) + break; + + chan->sw_subchannel[subc] = obj->class; + engine = 0x0000000f << (subc * 4); + + nv_mask(dev, NV04_PFIFO_CACHE1_ENGINE, engine, 0x00000000); + handled = true; + break; + default: + engine = nv_rd32(dev, NV04_PFIFO_CACHE1_ENGINE); + if (unlikely(((engine >> (subc * 4)) & 0xf) != 0)) + break; + + if (!nouveau_gpuobj_mthd_call(chan, chan->sw_subchannel[subc], + mthd, data)) + handled = true; + break; + } + +out: + spin_unlock_irqrestore(&dev_priv->channels.lock, flags); + return handled; +} + +void +nv04_fifo_isr(struct drm_device *dev) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_engine *engine = &dev_priv->engine; + uint32_t status, reassign; + int cnt = 0; + + reassign = nv_rd32(dev, NV03_PFIFO_CACHES) & 1; + while ((status = nv_rd32(dev, NV03_PFIFO_INTR_0)) && (cnt++ < 100)) { + uint32_t chid, get; + + nv_wr32(dev, NV03_PFIFO_CACHES, 0); + + chid = engine->fifo.channel_id(dev); + get = nv_rd32(dev, NV03_PFIFO_CACHE1_GET); + + if (status & NV_PFIFO_INTR_CACHE_ERROR) { + uint32_t mthd, data; + int ptr; + + /* NV_PFIFO_CACHE1_GET actually goes to 0xffc before + * wrapping on my G80 chips, but CACHE1 isn't big + * enough for this much data.. Tests show that it + * wraps around to the start at GET=0x800.. No clue + * as to why.. + */ + ptr = (get & 0x7ff) >> 2; + + if (dev_priv->card_type < NV_40) { + mthd = nv_rd32(dev, + NV04_PFIFO_CACHE1_METHOD(ptr)); + data = nv_rd32(dev, + NV04_PFIFO_CACHE1_DATA(ptr)); + } else { + mthd = nv_rd32(dev, + NV40_PFIFO_CACHE1_METHOD(ptr)); + data = nv_rd32(dev, + NV40_PFIFO_CACHE1_DATA(ptr)); + } + + if (!nouveau_fifo_swmthd(dev, chid, mthd, data)) { + NV_INFO(dev, "PFIFO_CACHE_ERROR - Ch %d/%d " + "Mthd 0x%04x Data 0x%08x\n", + chid, (mthd >> 13) & 7, mthd & 0x1ffc, + data); + } + + nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_PUSH, 0); + nv_wr32(dev, NV03_PFIFO_INTR_0, + NV_PFIFO_INTR_CACHE_ERROR); + + nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH0, + nv_rd32(dev, NV03_PFIFO_CACHE1_PUSH0) & ~1); + nv_wr32(dev, NV03_PFIFO_CACHE1_GET, get + 4); + nv_wr32(dev, NV03_PFIFO_CACHE1_PUSH0, + nv_rd32(dev, NV03_PFIFO_CACHE1_PUSH0) | 1); + nv_wr32(dev, NV04_PFIFO_CACHE1_HASH, 0); + + nv_wr32(dev, NV04_PFIFO_CACHE1_DMA_PUSH, + nv_rd32(dev, NV04_PFIFO_CACHE1_DMA_PUSH) | 1); + nv_wr32(dev, NV04_PFIFO_CACHE1_PULL0, 1); + + status &= ~NV_PFIFO_INTR_CACHE_ERROR; + } + + if (status & NV_PFIFO_INTR_DMA_PUSHER) { + u32 dma_get = nv_rd32(dev, 0x003244); + u32 dma_put = nv_rd32(dev, 0x003240); + u32 push = nv_rd32(dev, 0x003220); + u32 state = nv_rd32(dev, 0x003228); + + if (dev_priv->card_type == NV_50) { + u32 ho_get = nv_rd32(dev, 0x003328); + u32 ho_put = nv_rd32(dev, 0x003320); + u32 ib_get = nv_rd32(dev, 0x003334); + u32 ib_put = nv_rd32(dev, 0x003330); + + if (nouveau_ratelimit()) + NV_INFO(dev, "PFIFO_DMA_PUSHER - Ch %d Get 0x%02x%08x " + "Put 0x%02x%08x IbGet 0x%08x IbPut 0x%08x " + "State 0x%08x Push 0x%08x\n", + chid, ho_get, dma_get, ho_put, + dma_put, ib_get, ib_put, state, + push); + + /* METHOD_COUNT, in DMA_STATE on earlier chipsets */ + nv_wr32(dev, 0x003364, 0x00000000); + if (dma_get != dma_put || ho_get != ho_put) { + nv_wr32(dev, 0x003244, dma_put); + nv_wr32(dev, 0x003328, ho_put); + } else + if (ib_get != ib_put) { + nv_wr32(dev, 0x003334, ib_put); + } + } else { + NV_INFO(dev, "PFIFO_DMA_PUSHER - Ch %d Get 0x%08x " + "Put 0x%08x State 0x%08x Push 0x%08x\n", + chid, dma_get, dma_put, state, push); + + if (dma_get != dma_put) + nv_wr32(dev, 0x003244, dma_put); + } + + nv_wr32(dev, 0x003228, 0x00000000); + nv_wr32(dev, 0x003220, 0x00000001); + nv_wr32(dev, 0x002100, NV_PFIFO_INTR_DMA_PUSHER); + status &= ~NV_PFIFO_INTR_DMA_PUSHER; + } + + if (status & NV_PFIFO_INTR_SEMAPHORE) { + uint32_t sem; + + status &= ~NV_PFIFO_INTR_SEMAPHORE; + nv_wr32(dev, NV03_PFIFO_INTR_0, + NV_PFIFO_INTR_SEMAPHORE); + + sem = nv_rd32(dev, NV10_PFIFO_CACHE1_SEMAPHORE); + nv_wr32(dev, NV10_PFIFO_CACHE1_SEMAPHORE, sem | 0x1); + + nv_wr32(dev, NV03_PFIFO_CACHE1_GET, get + 4); + nv_wr32(dev, NV04_PFIFO_CACHE1_PULL0, 1); + } + + if (dev_priv->card_type == NV_50) { + if (status & 0x00000010) { + nv50_fb_vm_trap(dev, 1, "PFIFO_BAR_FAULT"); + status &= ~0x00000010; + nv_wr32(dev, 0x002100, 0x00000010); + } + } + + if (status) { + if (nouveau_ratelimit()) + NV_INFO(dev, "PFIFO_INTR 0x%08x - Ch %d\n", + status, chid); + nv_wr32(dev, NV03_PFIFO_INTR_0, status); + status = 0; + } + + nv_wr32(dev, NV03_PFIFO_CACHES, reassign); + } + + if (status) { + NV_INFO(dev, "PFIFO still angry after %d spins, halt\n", cnt); + nv_wr32(dev, 0x2140, 0); + nv_wr32(dev, 0x140, 0); + } + + nv_wr32(dev, NV03_PMC_INTR_0, NV_PMC_INTR_0_PFIFO_PENDING); +} diff --git a/drivers/gpu/drm/nouveau/nv10_fifo.c b/drivers/gpu/drm/nouveau/nv10_fifo.c index 912556f2e33c..acb9216e6d0a 100644 --- a/drivers/gpu/drm/nouveau/nv10_fifo.c +++ b/drivers/gpu/drm/nouveau/nv10_fifo.c @@ -208,6 +208,7 @@ nv10_fifo_init_ramxx(struct drm_device *dev) static void nv10_fifo_init_intr(struct drm_device *dev) { + nouveau_irq_register(dev, 8, nv04_fifo_isr); nv_wr32(dev, 0x002100, 0xffffffff); nv_wr32(dev, 0x002140, 0xffffffff); } diff --git a/drivers/gpu/drm/nouveau/nv40_fifo.c b/drivers/gpu/drm/nouveau/nv40_fifo.c index 311ac9ea5d53..f6b3580c685a 100644 --- a/drivers/gpu/drm/nouveau/nv40_fifo.c +++ b/drivers/gpu/drm/nouveau/nv40_fifo.c @@ -268,6 +268,7 @@ nv40_fifo_init_ramxx(struct drm_device *dev) static void nv40_fifo_init_intr(struct drm_device *dev) { + nouveau_irq_register(dev, 8, nv04_fifo_isr); nv_wr32(dev, 0x002100, 0xffffffff); nv_wr32(dev, 0x002140, 0xffffffff); } diff --git a/drivers/gpu/drm/nouveau/nv50_fifo.c b/drivers/gpu/drm/nouveau/nv50_fifo.c index d3295aae0c4e..ed18952ae7f4 100644 --- a/drivers/gpu/drm/nouveau/nv50_fifo.c +++ b/drivers/gpu/drm/nouveau/nv50_fifo.c @@ -106,6 +106,7 @@ nv50_fifo_init_intr(struct drm_device *dev) { NV_DEBUG(dev, "\n"); + nouveau_irq_register(dev, 8, nv04_fifo_isr); nv_wr32(dev, NV03_PFIFO_INTR_0, 0xFFFFFFFF); nv_wr32(dev, NV03_PFIFO_INTR_EN_0, 0xFFFFFFFF); } @@ -207,6 +208,9 @@ nv50_fifo_takedown(struct drm_device *dev) if (!pfifo->playlist[0]) return; + nv_wr32(dev, 0x2140, 0x00000000); + nouveau_irq_unregister(dev, 8); + nouveau_gpuobj_ref(NULL, &pfifo->playlist[0]); nouveau_gpuobj_ref(NULL, &pfifo->playlist[1]); } -- cgit v1.2.3 From 274fec93cdd627408a799519fa602f2eecb14d2f Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 3 Nov 2010 13:16:18 +1000 Subject: drm/nouveau: tidy+move PGRAPH ISRs to their respective *_graph.c files Reviewed-by: Francisco Jerez Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_drv.h | 8 +- drivers/gpu/drm/nouveau/nouveau_irq.c | 894 +------------------------------ drivers/gpu/drm/nouveau/nouveau_object.c | 18 + drivers/gpu/drm/nouveau/nv04_graph.c | 95 +++- drivers/gpu/drm/nouveau/nv10_graph.c | 72 ++- drivers/gpu/drm/nouveau/nv20_graph.c | 47 ++ drivers/gpu/drm/nouveau/nv40_graph.c | 69 +++ drivers/gpu/drm/nouveau/nv50_graph.c | 500 ++++++++++++++++- 8 files changed, 809 insertions(+), 894 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index e174479ab675..b19ef7fbb9dd 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -54,6 +54,7 @@ struct nouveau_fpriv { #include "nouveau_drm.h" #include "nouveau_reg.h" #include "nouveau_bios.h" +#include "nouveau_util.h" struct nouveau_grctx; #define MAX_NUM_DCB_ENTRIES 16 @@ -872,6 +873,7 @@ extern int nouveau_gpuobj_mthd_new(struct drm_device *, u32 class, u32 mthd, int (*exec)(struct nouveau_channel *, u32 class, u32 mthd, u32 data)); extern int nouveau_gpuobj_mthd_call(struct nouveau_channel *, u32, u32, u32); +extern int nouveau_gpuobj_mthd_call2(struct drm_device *, int, u32, u32, u32); extern int nouveau_gpuobj_channel_init(struct nouveau_channel *, uint32_t vram_h, uint32_t tt_h); extern void nouveau_gpuobj_channel_takedown(struct nouveau_channel *); @@ -1110,9 +1112,9 @@ extern int nv04_graph_create_context(struct nouveau_channel *); extern void nv04_graph_destroy_context(struct nouveau_channel *); extern int nv04_graph_load_context(struct nouveau_channel *); extern int nv04_graph_unload_context(struct drm_device *); -extern void nv04_graph_context_switch(struct drm_device *); extern int nv04_graph_mthd_page_flip(struct nouveau_channel *chan, u32 class, u32 mthd, u32 data); +extern struct nouveau_bitfield nv04_graph_nsource[]; /* nv10_graph.c */ extern int nv10_graph_init(struct drm_device *); @@ -1122,8 +1124,9 @@ extern int nv10_graph_create_context(struct nouveau_channel *); extern void nv10_graph_destroy_context(struct nouveau_channel *); extern int nv10_graph_load_context(struct nouveau_channel *); extern int nv10_graph_unload_context(struct drm_device *); -extern void nv10_graph_context_switch(struct drm_device *); extern void nv10_graph_set_tile_region(struct drm_device *dev, int i); +extern struct nouveau_bitfield nv10_graph_intr[]; +extern struct nouveau_bitfield nv10_graph_nstatus[]; /* nv20_graph.c */ extern int nv20_graph_create_context(struct nouveau_channel *); @@ -1155,7 +1158,6 @@ extern int nv50_graph_create_context(struct nouveau_channel *); extern void nv50_graph_destroy_context(struct nouveau_channel *); extern int nv50_graph_load_context(struct nouveau_channel *); extern int nv50_graph_unload_context(struct drm_device *); -extern void nv50_graph_context_switch(struct drm_device *); extern int nv50_grctx_init(struct nouveau_grctx *); extern void nv50_graph_tlb_flush(struct drm_device *dev); extern void nv86_graph_tlb_flush(struct drm_device *dev); diff --git a/drivers/gpu/drm/nouveau/nouveau_irq.c b/drivers/gpu/drm/nouveau/nouveau_irq.c index 16f42f774a9e..2ba7265bc967 100644 --- a/drivers/gpu/drm/nouveau/nouveau_irq.c +++ b/drivers/gpu/drm/nouveau/nouveau_irq.c @@ -69,910 +69,34 @@ nouveau_irq_uninstall(struct drm_device *dev) nv_wr32(dev, NV03_PMC_INTR_EN_0, 0); } -static struct nouveau_bitfield nstatus_names[] = -{ - { NV04_PGRAPH_NSTATUS_STATE_IN_USE, "STATE_IN_USE" }, - { NV04_PGRAPH_NSTATUS_INVALID_STATE, "INVALID_STATE" }, - { NV04_PGRAPH_NSTATUS_BAD_ARGUMENT, "BAD_ARGUMENT" }, - { NV04_PGRAPH_NSTATUS_PROTECTION_FAULT, "PROTECTION_FAULT" }, - {} -}; - -static struct nouveau_bitfield nstatus_names_nv10[] = -{ - { NV10_PGRAPH_NSTATUS_STATE_IN_USE, "STATE_IN_USE" }, - { NV10_PGRAPH_NSTATUS_INVALID_STATE, "INVALID_STATE" }, - { NV10_PGRAPH_NSTATUS_BAD_ARGUMENT, "BAD_ARGUMENT" }, - { NV10_PGRAPH_NSTATUS_PROTECTION_FAULT, "PROTECTION_FAULT" }, - {} -}; - -static struct nouveau_bitfield nsource_names[] = -{ - { NV03_PGRAPH_NSOURCE_NOTIFICATION, "NOTIFICATION" }, - { NV03_PGRAPH_NSOURCE_DATA_ERROR, "DATA_ERROR" }, - { NV03_PGRAPH_NSOURCE_PROTECTION_ERROR, "PROTECTION_ERROR" }, - { NV03_PGRAPH_NSOURCE_RANGE_EXCEPTION, "RANGE_EXCEPTION" }, - { NV03_PGRAPH_NSOURCE_LIMIT_COLOR, "LIMIT_COLOR" }, - { NV03_PGRAPH_NSOURCE_LIMIT_ZETA, "LIMIT_ZETA" }, - { NV03_PGRAPH_NSOURCE_ILLEGAL_MTHD, "ILLEGAL_MTHD" }, - { NV03_PGRAPH_NSOURCE_DMA_R_PROTECTION, "DMA_R_PROTECTION" }, - { NV03_PGRAPH_NSOURCE_DMA_W_PROTECTION, "DMA_W_PROTECTION" }, - { NV03_PGRAPH_NSOURCE_FORMAT_EXCEPTION, "FORMAT_EXCEPTION" }, - { NV03_PGRAPH_NSOURCE_PATCH_EXCEPTION, "PATCH_EXCEPTION" }, - { NV03_PGRAPH_NSOURCE_STATE_INVALID, "STATE_INVALID" }, - { NV03_PGRAPH_NSOURCE_DOUBLE_NOTIFY, "DOUBLE_NOTIFY" }, - { NV03_PGRAPH_NSOURCE_NOTIFY_IN_USE, "NOTIFY_IN_USE" }, - { NV03_PGRAPH_NSOURCE_METHOD_CNT, "METHOD_CNT" }, - { NV03_PGRAPH_NSOURCE_BFR_NOTIFICATION, "BFR_NOTIFICATION" }, - { NV03_PGRAPH_NSOURCE_DMA_VTX_PROTECTION, "DMA_VTX_PROTECTION" }, - { NV03_PGRAPH_NSOURCE_DMA_WIDTH_A, "DMA_WIDTH_A" }, - { NV03_PGRAPH_NSOURCE_DMA_WIDTH_B, "DMA_WIDTH_B" }, - {} -}; - -static int -nouveau_graph_chid_from_grctx(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_channel *chan; - unsigned long flags; - uint32_t inst; - int i; - - if (dev_priv->card_type < NV_40) - return dev_priv->engine.fifo.channels; - else - if (dev_priv->card_type < NV_50) { - inst = (nv_rd32(dev, 0x40032c) & 0xfffff) << 4; - - spin_lock_irqsave(&dev_priv->channels.lock, flags); - for (i = 0; i < dev_priv->engine.fifo.channels; i++) { - chan = dev_priv->channels.ptr[i]; - if (!chan || !chan->ramin_grctx) - continue; - - if (inst == chan->ramin_grctx->pinst) - break; - } - spin_unlock_irqrestore(&dev_priv->channels.lock, flags); - } else { - inst = (nv_rd32(dev, 0x40032c) & 0xfffff) << 12; - - spin_lock_irqsave(&dev_priv->channels.lock, flags); - for (i = 0; i < dev_priv->engine.fifo.channels; i++) { - chan = dev_priv->channels.ptr[i]; - if (!chan || !chan->ramin) - continue; - - if (inst == chan->ramin->vinst) - break; - } - spin_unlock_irqrestore(&dev_priv->channels.lock, flags); - } - - - return i; -} - -static int -nouveau_graph_trapped_channel(struct drm_device *dev, int *channel_ret) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_engine *engine = &dev_priv->engine; - int channel; - - if (dev_priv->card_type < NV_10) - channel = (nv_rd32(dev, NV04_PGRAPH_TRAPPED_ADDR) >> 24) & 0xf; - else - if (dev_priv->card_type < NV_40) - channel = (nv_rd32(dev, NV04_PGRAPH_TRAPPED_ADDR) >> 20) & 0x1f; - else - channel = nouveau_graph_chid_from_grctx(dev); - - if (channel >= engine->fifo.channels || - !dev_priv->channels.ptr[channel]) { - NV_ERROR(dev, "AIII, invalid/inactive channel id %d\n", channel); - return -EINVAL; - } - - *channel_ret = channel; - return 0; -} - -struct nouveau_pgraph_trap { - int channel; - int class; - int subc, mthd, size; - uint32_t data, data2; - uint32_t nsource, nstatus; -}; - -static void -nouveau_graph_trap_info(struct drm_device *dev, - struct nouveau_pgraph_trap *trap) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - uint32_t address; - - trap->nsource = trap->nstatus = 0; - if (dev_priv->card_type < NV_50) { - trap->nsource = nv_rd32(dev, NV03_PGRAPH_NSOURCE); - trap->nstatus = nv_rd32(dev, NV03_PGRAPH_NSTATUS); - } - - if (nouveau_graph_trapped_channel(dev, &trap->channel)) - trap->channel = -1; - address = nv_rd32(dev, NV04_PGRAPH_TRAPPED_ADDR); - - trap->mthd = address & 0x1FFC; - trap->data = nv_rd32(dev, NV04_PGRAPH_TRAPPED_DATA); - if (dev_priv->card_type < NV_10) { - trap->subc = (address >> 13) & 0x7; - } else { - trap->subc = (address >> 16) & 0x7; - trap->data2 = nv_rd32(dev, NV10_PGRAPH_TRAPPED_DATA_HIGH); - } - - if (dev_priv->card_type < NV_10) - trap->class = nv_rd32(dev, 0x400180 + trap->subc*4) & 0xFF; - else if (dev_priv->card_type < NV_40) - trap->class = nv_rd32(dev, 0x400160 + trap->subc*4) & 0xFFF; - else if (dev_priv->card_type < NV_50) - trap->class = nv_rd32(dev, 0x400160 + trap->subc*4) & 0xFFFF; - else - trap->class = nv_rd32(dev, 0x400814); -} - -static void -nouveau_graph_dump_trap_info(struct drm_device *dev, const char *id, - struct nouveau_pgraph_trap *trap) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - uint32_t nsource = trap->nsource, nstatus = trap->nstatus; - - if (dev_priv->card_type < NV_50) { - NV_INFO(dev, "%s - nSource:", id); - nouveau_bitfield_print(nsource_names, nsource); - printk(", nStatus:"); - if (dev_priv->card_type < NV_10) - nouveau_bitfield_print(nstatus_names, nstatus); - else - nouveau_bitfield_print(nstatus_names_nv10, nstatus); - printk("\n"); - } - - NV_INFO(dev, "%s - Ch %d/%d Class 0x%04x Mthd 0x%04x " - "Data 0x%08x:0x%08x\n", - id, trap->channel, trap->subc, - trap->class, trap->mthd, - trap->data2, trap->data); -} - -static int -nouveau_pgraph_intr_swmthd(struct drm_device *dev, - struct nouveau_pgraph_trap *trap) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_channel *chan; - unsigned long flags; - int ret = -EINVAL; - - spin_lock_irqsave(&dev_priv->channels.lock, flags); - if (trap->channel > 0 && - trap->channel < dev_priv->engine.fifo.channels && - dev_priv->channels.ptr[trap->channel]) { - chan = dev_priv->channels.ptr[trap->channel]; - ret = nouveau_gpuobj_mthd_call(chan, trap->class, trap->mthd, trap->data); - } - spin_unlock_irqrestore(&dev_priv->channels.lock, flags); - - return ret; -} - -static inline void -nouveau_pgraph_intr_notify(struct drm_device *dev, uint32_t nsource) -{ - struct nouveau_pgraph_trap trap; - int unhandled = 0; - - nouveau_graph_trap_info(dev, &trap); - - if (nsource & NV03_PGRAPH_NSOURCE_ILLEGAL_MTHD) { - if (nouveau_pgraph_intr_swmthd(dev, &trap)) - unhandled = 1; - } else { - unhandled = 1; - } - - if (unhandled) - nouveau_graph_dump_trap_info(dev, "PGRAPH_NOTIFY", &trap); -} - - -static inline void -nouveau_pgraph_intr_error(struct drm_device *dev, uint32_t nsource) -{ - struct nouveau_pgraph_trap trap; - int unhandled = 0; - - nouveau_graph_trap_info(dev, &trap); - trap.nsource = nsource; - - if (nsource & NV03_PGRAPH_NSOURCE_ILLEGAL_MTHD) { - if (nouveau_pgraph_intr_swmthd(dev, &trap)) - unhandled = 1; - } else if (nsource & NV03_PGRAPH_NSOURCE_DMA_VTX_PROTECTION) { - uint32_t v = nv_rd32(dev, 0x402000); - nv_wr32(dev, 0x402000, v); - - /* dump the error anyway for now: it's useful for - Gallium development */ - unhandled = 1; - } else { - unhandled = 1; - } - - if (unhandled && nouveau_ratelimit()) - nouveau_graph_dump_trap_info(dev, "PGRAPH_ERROR", &trap); -} - -static inline void -nouveau_pgraph_intr_context_switch(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_engine *engine = &dev_priv->engine; - uint32_t chid; - - chid = engine->fifo.channel_id(dev); - NV_DEBUG(dev, "PGRAPH context switch interrupt channel %x\n", chid); - - switch (dev_priv->card_type) { - case NV_04: - nv04_graph_context_switch(dev); - break; - case NV_10: - nv10_graph_context_switch(dev); - break; - default: - NV_ERROR(dev, "Context switch not implemented\n"); - break; - } -} - -static void -nouveau_pgraph_irq_handler(struct drm_device *dev) -{ - uint32_t status; - - while ((status = nv_rd32(dev, NV03_PGRAPH_INTR))) { - uint32_t nsource = nv_rd32(dev, NV03_PGRAPH_NSOURCE); - - if (status & NV_PGRAPH_INTR_NOTIFY) { - nouveau_pgraph_intr_notify(dev, nsource); - - status &= ~NV_PGRAPH_INTR_NOTIFY; - nv_wr32(dev, NV03_PGRAPH_INTR, NV_PGRAPH_INTR_NOTIFY); - } - - if (status & NV_PGRAPH_INTR_ERROR) { - nouveau_pgraph_intr_error(dev, nsource); - - status &= ~NV_PGRAPH_INTR_ERROR; - nv_wr32(dev, NV03_PGRAPH_INTR, NV_PGRAPH_INTR_ERROR); - } - - if (status & NV_PGRAPH_INTR_CONTEXT_SWITCH) { - status &= ~NV_PGRAPH_INTR_CONTEXT_SWITCH; - nv_wr32(dev, NV03_PGRAPH_INTR, - NV_PGRAPH_INTR_CONTEXT_SWITCH); - - nouveau_pgraph_intr_context_switch(dev); - } - - if (status) { - NV_INFO(dev, "Unhandled PGRAPH_INTR - 0x%08x\n", status); - nv_wr32(dev, NV03_PGRAPH_INTR, status); - } - - if ((nv_rd32(dev, NV04_PGRAPH_FIFO) & (1 << 0)) == 0) - nv_wr32(dev, NV04_PGRAPH_FIFO, 1); - } - - nv_wr32(dev, NV03_PMC_INTR_0, NV_PMC_INTR_0_PGRAPH_PENDING); -} - -static struct nouveau_enum nv50_mp_exec_error_names[] = -{ - { 3, "STACK_UNDERFLOW" }, - { 4, "QUADON_ACTIVE" }, - { 8, "TIMEOUT" }, - { 0x10, "INVALID_OPCODE" }, - { 0x40, "BREAKPOINT" }, - {} -}; - -static void -nv50_pgraph_mp_trap(struct drm_device *dev, int tpid, int display) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - uint32_t units = nv_rd32(dev, 0x1540); - uint32_t addr, mp10, status, pc, oplow, ophigh; - int i; - int mps = 0; - for (i = 0; i < 4; i++) { - if (!(units & 1 << (i+24))) - continue; - if (dev_priv->chipset < 0xa0) - addr = 0x408200 + (tpid << 12) + (i << 7); - else - addr = 0x408100 + (tpid << 11) + (i << 7); - mp10 = nv_rd32(dev, addr + 0x10); - status = nv_rd32(dev, addr + 0x14); - if (!status) - continue; - if (display) { - nv_rd32(dev, addr + 0x20); - pc = nv_rd32(dev, addr + 0x24); - oplow = nv_rd32(dev, addr + 0x70); - ophigh= nv_rd32(dev, addr + 0x74); - NV_INFO(dev, "PGRAPH_TRAP_MP_EXEC - " - "TP %d MP %d: ", tpid, i); - nouveau_enum_print(nv50_mp_exec_error_names, status); - printk(" at %06x warp %d, opcode %08x %08x\n", - pc&0xffffff, pc >> 24, - oplow, ophigh); - } - nv_wr32(dev, addr + 0x10, mp10); - nv_wr32(dev, addr + 0x14, 0); - mps++; - } - if (!mps && display) - NV_INFO(dev, "PGRAPH_TRAP_MP_EXEC - TP %d: " - "No MPs claiming errors?\n", tpid); -} - -static void -nv50_pgraph_tp_trap(struct drm_device *dev, int type, uint32_t ustatus_old, - uint32_t ustatus_new, int display, const char *name) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - int tps = 0; - uint32_t units = nv_rd32(dev, 0x1540); - int i, r; - uint32_t ustatus_addr, ustatus; - for (i = 0; i < 16; i++) { - if (!(units & (1 << i))) - continue; - if (dev_priv->chipset < 0xa0) - ustatus_addr = ustatus_old + (i << 12); - else - ustatus_addr = ustatus_new + (i << 11); - ustatus = nv_rd32(dev, ustatus_addr) & 0x7fffffff; - if (!ustatus) - continue; - tps++; - switch (type) { - case 6: /* texture error... unknown for now */ - nv50_fb_vm_trap(dev, display, name); - if (display) { - NV_ERROR(dev, "magic set %d:\n", i); - for (r = ustatus_addr + 4; r <= ustatus_addr + 0x10; r += 4) - NV_ERROR(dev, "\t0x%08x: 0x%08x\n", r, - nv_rd32(dev, r)); - } - break; - case 7: /* MP error */ - if (ustatus & 0x00010000) { - nv50_pgraph_mp_trap(dev, i, display); - ustatus &= ~0x00010000; - } - break; - case 8: /* TPDMA error */ - { - uint32_t e0c = nv_rd32(dev, ustatus_addr + 4); - uint32_t e10 = nv_rd32(dev, ustatus_addr + 8); - uint32_t e14 = nv_rd32(dev, ustatus_addr + 0xc); - uint32_t e18 = nv_rd32(dev, ustatus_addr + 0x10); - uint32_t e1c = nv_rd32(dev, ustatus_addr + 0x14); - uint32_t e20 = nv_rd32(dev, ustatus_addr + 0x18); - uint32_t e24 = nv_rd32(dev, ustatus_addr + 0x1c); - nv50_fb_vm_trap(dev, display, name); - /* 2d engine destination */ - if (ustatus & 0x00000010) { - if (display) { - NV_INFO(dev, "PGRAPH_TRAP_TPDMA_2D - TP %d - Unknown fault at address %02x%08x\n", - i, e14, e10); - NV_INFO(dev, "PGRAPH_TRAP_TPDMA_2D - TP %d - e0c: %08x, e18: %08x, e1c: %08x, e20: %08x, e24: %08x\n", - i, e0c, e18, e1c, e20, e24); - } - ustatus &= ~0x00000010; - } - /* Render target */ - if (ustatus & 0x00000040) { - if (display) { - NV_INFO(dev, "PGRAPH_TRAP_TPDMA_RT - TP %d - Unknown fault at address %02x%08x\n", - i, e14, e10); - NV_INFO(dev, "PGRAPH_TRAP_TPDMA_RT - TP %d - e0c: %08x, e18: %08x, e1c: %08x, e20: %08x, e24: %08x\n", - i, e0c, e18, e1c, e20, e24); - } - ustatus &= ~0x00000040; - } - /* CUDA memory: l[], g[] or stack. */ - if (ustatus & 0x00000080) { - if (display) { - if (e18 & 0x80000000) { - /* g[] read fault? */ - NV_INFO(dev, "PGRAPH_TRAP_TPDMA - TP %d - Global read fault at address %02x%08x\n", - i, e14, e10 | ((e18 >> 24) & 0x1f)); - e18 &= ~0x1f000000; - } else if (e18 & 0xc) { - /* g[] write fault? */ - NV_INFO(dev, "PGRAPH_TRAP_TPDMA - TP %d - Global write fault at address %02x%08x\n", - i, e14, e10 | ((e18 >> 7) & 0x1f)); - e18 &= ~0x00000f80; - } else { - NV_INFO(dev, "PGRAPH_TRAP_TPDMA - TP %d - Unknown CUDA fault at address %02x%08x\n", - i, e14, e10); - } - NV_INFO(dev, "PGRAPH_TRAP_TPDMA - TP %d - e0c: %08x, e18: %08x, e1c: %08x, e20: %08x, e24: %08x\n", - i, e0c, e18, e1c, e20, e24); - } - ustatus &= ~0x00000080; - } - } - break; - } - if (ustatus) { - if (display) - NV_INFO(dev, "%s - TP%d: Unhandled ustatus 0x%08x\n", name, i, ustatus); - } - nv_wr32(dev, ustatus_addr, 0xc0000000); - } - - if (!tps && display) - NV_INFO(dev, "%s - No TPs claiming errors?\n", name); -} - -static void -nv50_pgraph_trap_handler(struct drm_device *dev) -{ - struct nouveau_pgraph_trap trap; - uint32_t status = nv_rd32(dev, 0x400108); - uint32_t ustatus; - int display = nouveau_ratelimit(); - - - if (!status && display) { - nouveau_graph_trap_info(dev, &trap); - nouveau_graph_dump_trap_info(dev, "PGRAPH_TRAP", &trap); - NV_INFO(dev, "PGRAPH_TRAP - no units reporting traps?\n"); - } - - /* DISPATCH: Relays commands to other units and handles NOTIFY, - * COND, QUERY. If you get a trap from it, the command is still stuck - * in DISPATCH and you need to do something about it. */ - if (status & 0x001) { - ustatus = nv_rd32(dev, 0x400804) & 0x7fffffff; - if (!ustatus && display) { - NV_INFO(dev, "PGRAPH_TRAP_DISPATCH - no ustatus?\n"); - } - - /* Known to be triggered by screwed up NOTIFY and COND... */ - if (ustatus & 0x00000001) { - nv50_fb_vm_trap(dev, display, "PGRAPH_TRAP_DISPATCH_FAULT"); - nv_wr32(dev, 0x400500, 0); - if (nv_rd32(dev, 0x400808) & 0x80000000) { - if (display) { - if (nouveau_graph_trapped_channel(dev, &trap.channel)) - trap.channel = -1; - trap.class = nv_rd32(dev, 0x400814); - trap.mthd = nv_rd32(dev, 0x400808) & 0x1ffc; - trap.subc = (nv_rd32(dev, 0x400808) >> 16) & 0x7; - trap.data = nv_rd32(dev, 0x40080c); - trap.data2 = nv_rd32(dev, 0x400810); - nouveau_graph_dump_trap_info(dev, - "PGRAPH_TRAP_DISPATCH_FAULT", &trap); - NV_INFO(dev, "PGRAPH_TRAP_DISPATCH_FAULT - 400808: %08x\n", nv_rd32(dev, 0x400808)); - NV_INFO(dev, "PGRAPH_TRAP_DISPATCH_FAULT - 400848: %08x\n", nv_rd32(dev, 0x400848)); - } - nv_wr32(dev, 0x400808, 0); - } else if (display) { - NV_INFO(dev, "PGRAPH_TRAP_DISPATCH_FAULT - No stuck command?\n"); - } - nv_wr32(dev, 0x4008e8, nv_rd32(dev, 0x4008e8) & 3); - nv_wr32(dev, 0x400848, 0); - ustatus &= ~0x00000001; - } - if (ustatus & 0x00000002) { - nv50_fb_vm_trap(dev, display, "PGRAPH_TRAP_DISPATCH_QUERY"); - nv_wr32(dev, 0x400500, 0); - if (nv_rd32(dev, 0x40084c) & 0x80000000) { - if (display) { - if (nouveau_graph_trapped_channel(dev, &trap.channel)) - trap.channel = -1; - trap.class = nv_rd32(dev, 0x400814); - trap.mthd = nv_rd32(dev, 0x40084c) & 0x1ffc; - trap.subc = (nv_rd32(dev, 0x40084c) >> 16) & 0x7; - trap.data = nv_rd32(dev, 0x40085c); - trap.data2 = 0; - nouveau_graph_dump_trap_info(dev, - "PGRAPH_TRAP_DISPATCH_QUERY", &trap); - NV_INFO(dev, "PGRAPH_TRAP_DISPATCH_QUERY - 40084c: %08x\n", nv_rd32(dev, 0x40084c)); - } - nv_wr32(dev, 0x40084c, 0); - } else if (display) { - NV_INFO(dev, "PGRAPH_TRAP_DISPATCH_QUERY - No stuck command?\n"); - } - ustatus &= ~0x00000002; - } - if (ustatus && display) - NV_INFO(dev, "PGRAPH_TRAP_DISPATCH - Unhandled ustatus 0x%08x\n", ustatus); - nv_wr32(dev, 0x400804, 0xc0000000); - nv_wr32(dev, 0x400108, 0x001); - status &= ~0x001; - } - - /* TRAPs other than dispatch use the "normal" trap regs. */ - if (status && display) { - nouveau_graph_trap_info(dev, &trap); - nouveau_graph_dump_trap_info(dev, - "PGRAPH_TRAP", &trap); - } - - /* M2MF: Memory to memory copy engine. */ - if (status & 0x002) { - ustatus = nv_rd32(dev, 0x406800) & 0x7fffffff; - if (!ustatus && display) { - NV_INFO(dev, "PGRAPH_TRAP_M2MF - no ustatus?\n"); - } - if (ustatus & 0x00000001) { - nv50_fb_vm_trap(dev, display, "PGRAPH_TRAP_M2MF_NOTIFY"); - ustatus &= ~0x00000001; - } - if (ustatus & 0x00000002) { - nv50_fb_vm_trap(dev, display, "PGRAPH_TRAP_M2MF_IN"); - ustatus &= ~0x00000002; - } - if (ustatus & 0x00000004) { - nv50_fb_vm_trap(dev, display, "PGRAPH_TRAP_M2MF_OUT"); - ustatus &= ~0x00000004; - } - NV_INFO (dev, "PGRAPH_TRAP_M2MF - %08x %08x %08x %08x\n", - nv_rd32(dev, 0x406804), - nv_rd32(dev, 0x406808), - nv_rd32(dev, 0x40680c), - nv_rd32(dev, 0x406810)); - if (ustatus && display) - NV_INFO(dev, "PGRAPH_TRAP_M2MF - Unhandled ustatus 0x%08x\n", ustatus); - /* No sane way found yet -- just reset the bugger. */ - nv_wr32(dev, 0x400040, 2); - nv_wr32(dev, 0x400040, 0); - nv_wr32(dev, 0x406800, 0xc0000000); - nv_wr32(dev, 0x400108, 0x002); - status &= ~0x002; - } - - /* VFETCH: Fetches data from vertex buffers. */ - if (status & 0x004) { - ustatus = nv_rd32(dev, 0x400c04) & 0x7fffffff; - if (!ustatus && display) { - NV_INFO(dev, "PGRAPH_TRAP_VFETCH - no ustatus?\n"); - } - if (ustatus & 0x00000001) { - nv50_fb_vm_trap(dev, display, "PGRAPH_TRAP_VFETCH_FAULT"); - NV_INFO (dev, "PGRAPH_TRAP_VFETCH_FAULT - %08x %08x %08x %08x\n", - nv_rd32(dev, 0x400c00), - nv_rd32(dev, 0x400c08), - nv_rd32(dev, 0x400c0c), - nv_rd32(dev, 0x400c10)); - ustatus &= ~0x00000001; - } - if (ustatus && display) - NV_INFO(dev, "PGRAPH_TRAP_VFETCH - Unhandled ustatus 0x%08x\n", ustatus); - nv_wr32(dev, 0x400c04, 0xc0000000); - nv_wr32(dev, 0x400108, 0x004); - status &= ~0x004; - } - - /* STRMOUT: DirectX streamout / OpenGL transform feedback. */ - if (status & 0x008) { - ustatus = nv_rd32(dev, 0x401800) & 0x7fffffff; - if (!ustatus && display) { - NV_INFO(dev, "PGRAPH_TRAP_STRMOUT - no ustatus?\n"); - } - if (ustatus & 0x00000001) { - nv50_fb_vm_trap(dev, display, "PGRAPH_TRAP_STRMOUT_FAULT"); - NV_INFO (dev, "PGRAPH_TRAP_STRMOUT_FAULT - %08x %08x %08x %08x\n", - nv_rd32(dev, 0x401804), - nv_rd32(dev, 0x401808), - nv_rd32(dev, 0x40180c), - nv_rd32(dev, 0x401810)); - ustatus &= ~0x00000001; - } - if (ustatus && display) - NV_INFO(dev, "PGRAPH_TRAP_STRMOUT - Unhandled ustatus 0x%08x\n", ustatus); - /* No sane way found yet -- just reset the bugger. */ - nv_wr32(dev, 0x400040, 0x80); - nv_wr32(dev, 0x400040, 0); - nv_wr32(dev, 0x401800, 0xc0000000); - nv_wr32(dev, 0x400108, 0x008); - status &= ~0x008; - } - - /* CCACHE: Handles code and c[] caches and fills them. */ - if (status & 0x010) { - ustatus = nv_rd32(dev, 0x405018) & 0x7fffffff; - if (!ustatus && display) { - NV_INFO(dev, "PGRAPH_TRAP_CCACHE - no ustatus?\n"); - } - if (ustatus & 0x00000001) { - nv50_fb_vm_trap(dev, display, "PGRAPH_TRAP_CCACHE_FAULT"); - NV_INFO (dev, "PGRAPH_TRAP_CCACHE_FAULT - %08x %08x %08x %08x %08x %08x %08x\n", - nv_rd32(dev, 0x405800), - nv_rd32(dev, 0x405804), - nv_rd32(dev, 0x405808), - nv_rd32(dev, 0x40580c), - nv_rd32(dev, 0x405810), - nv_rd32(dev, 0x405814), - nv_rd32(dev, 0x40581c)); - ustatus &= ~0x00000001; - } - if (ustatus && display) - NV_INFO(dev, "PGRAPH_TRAP_CCACHE - Unhandled ustatus 0x%08x\n", ustatus); - nv_wr32(dev, 0x405018, 0xc0000000); - nv_wr32(dev, 0x400108, 0x010); - status &= ~0x010; - } - - /* Unknown, not seen yet... 0x402000 is the only trap status reg - * remaining, so try to handle it anyway. Perhaps related to that - * unknown DMA slot on tesla? */ - if (status & 0x20) { - nv50_fb_vm_trap(dev, display, "PGRAPH_TRAP_UNKC04"); - ustatus = nv_rd32(dev, 0x402000) & 0x7fffffff; - if (display) - NV_INFO(dev, "PGRAPH_TRAP_UNKC04 - Unhandled ustatus 0x%08x\n", ustatus); - nv_wr32(dev, 0x402000, 0xc0000000); - /* no status modifiction on purpose */ - } - - /* TEXTURE: CUDA texturing units */ - if (status & 0x040) { - nv50_pgraph_tp_trap (dev, 6, 0x408900, 0x408600, display, - "PGRAPH_TRAP_TEXTURE"); - nv_wr32(dev, 0x400108, 0x040); - status &= ~0x040; - } - - /* MP: CUDA execution engines. */ - if (status & 0x080) { - nv50_pgraph_tp_trap (dev, 7, 0x408314, 0x40831c, display, - "PGRAPH_TRAP_MP"); - nv_wr32(dev, 0x400108, 0x080); - status &= ~0x080; - } - - /* TPDMA: Handles TP-initiated uncached memory accesses: - * l[], g[], stack, 2d surfaces, render targets. */ - if (status & 0x100) { - nv50_pgraph_tp_trap (dev, 8, 0x408e08, 0x408708, display, - "PGRAPH_TRAP_TPDMA"); - nv_wr32(dev, 0x400108, 0x100); - status &= ~0x100; - } - - if (status) { - if (display) - NV_INFO(dev, "PGRAPH_TRAP - Unknown trap 0x%08x\n", - status); - nv_wr32(dev, 0x400108, status); - } -} - -/* There must be a *lot* of these. Will take some time to gather them up. */ -static struct nouveau_enum nv50_data_error_names[] = -{ - { 4, "INVALID_VALUE" }, - { 5, "INVALID_ENUM" }, - { 8, "INVALID_OBJECT" }, - { 0xc, "INVALID_BITFIELD" }, - { 0x28, "MP_NO_REG_SPACE" }, - { 0x2b, "MP_BLOCK_SIZE_MISMATCH" }, - {} -}; - -static void -nv50_pgraph_irq_handler(struct drm_device *dev) -{ - struct nouveau_pgraph_trap trap; - int unhandled = 0; - uint32_t status; - - while ((status = nv_rd32(dev, NV03_PGRAPH_INTR))) { - /* NOTIFY: You've set a NOTIFY an a command and it's done. */ - if (status & 0x00000001) { - nouveau_graph_trap_info(dev, &trap); - if (nouveau_ratelimit()) - nouveau_graph_dump_trap_info(dev, - "PGRAPH_NOTIFY", &trap); - status &= ~0x00000001; - nv_wr32(dev, NV03_PGRAPH_INTR, 0x00000001); - } - - /* COMPUTE_QUERY: Purpose and exact cause unknown, happens - * when you write 0x200 to 0x50c0 method 0x31c. */ - if (status & 0x00000002) { - nouveau_graph_trap_info(dev, &trap); - if (nouveau_ratelimit()) - nouveau_graph_dump_trap_info(dev, - "PGRAPH_COMPUTE_QUERY", &trap); - status &= ~0x00000002; - nv_wr32(dev, NV03_PGRAPH_INTR, 0x00000002); - } - - /* Unknown, never seen: 0x4 */ - - /* ILLEGAL_MTHD: You used a wrong method for this class. */ - if (status & 0x00000010) { - nouveau_graph_trap_info(dev, &trap); - if (nouveau_pgraph_intr_swmthd(dev, &trap)) - unhandled = 1; - if (unhandled && nouveau_ratelimit()) - nouveau_graph_dump_trap_info(dev, - "PGRAPH_ILLEGAL_MTHD", &trap); - status &= ~0x00000010; - nv_wr32(dev, NV03_PGRAPH_INTR, 0x00000010); - } - - /* ILLEGAL_CLASS: You used a wrong class. */ - if (status & 0x00000020) { - nouveau_graph_trap_info(dev, &trap); - if (nouveau_ratelimit()) - nouveau_graph_dump_trap_info(dev, - "PGRAPH_ILLEGAL_CLASS", &trap); - status &= ~0x00000020; - nv_wr32(dev, NV03_PGRAPH_INTR, 0x00000020); - } - - /* DOUBLE_NOTIFY: You tried to set a NOTIFY on another NOTIFY. */ - if (status & 0x00000040) { - nouveau_graph_trap_info(dev, &trap); - if (nouveau_ratelimit()) - nouveau_graph_dump_trap_info(dev, - "PGRAPH_DOUBLE_NOTIFY", &trap); - status &= ~0x00000040; - nv_wr32(dev, NV03_PGRAPH_INTR, 0x00000040); - } - - /* CONTEXT_SWITCH: PGRAPH needs us to load a new context */ - if (status & 0x00001000) { - nv_wr32(dev, 0x400500, 0x00000000); - nv_wr32(dev, NV03_PGRAPH_INTR, - NV_PGRAPH_INTR_CONTEXT_SWITCH); - nv_wr32(dev, NV40_PGRAPH_INTR_EN, nv_rd32(dev, - NV40_PGRAPH_INTR_EN) & - ~NV_PGRAPH_INTR_CONTEXT_SWITCH); - nv_wr32(dev, 0x400500, 0x00010001); - - nv50_graph_context_switch(dev); - - status &= ~NV_PGRAPH_INTR_CONTEXT_SWITCH; - } - - /* BUFFER_NOTIFY: Your m2mf transfer finished */ - if (status & 0x00010000) { - nouveau_graph_trap_info(dev, &trap); - if (nouveau_ratelimit()) - nouveau_graph_dump_trap_info(dev, - "PGRAPH_BUFFER_NOTIFY", &trap); - status &= ~0x00010000; - nv_wr32(dev, NV03_PGRAPH_INTR, 0x00010000); - } - - /* DATA_ERROR: Invalid value for this method, or invalid - * state in current PGRAPH context for this operation */ - if (status & 0x00100000) { - nouveau_graph_trap_info(dev, &trap); - if (nouveau_ratelimit()) { - nouveau_graph_dump_trap_info(dev, - "PGRAPH_DATA_ERROR", &trap); - NV_INFO (dev, "PGRAPH_DATA_ERROR - "); - nouveau_enum_print(nv50_data_error_names, - nv_rd32(dev, 0x400110)); - printk("\n"); - } - status &= ~0x00100000; - nv_wr32(dev, NV03_PGRAPH_INTR, 0x00100000); - } - - /* TRAP: Something bad happened in the middle of command - * execution. Has a billion types, subtypes, and even - * subsubtypes. */ - if (status & 0x00200000) { - nv50_pgraph_trap_handler(dev); - status &= ~0x00200000; - nv_wr32(dev, NV03_PGRAPH_INTR, 0x00200000); - } - - /* Unknown, never seen: 0x00400000 */ - - /* SINGLE_STEP: Happens on every method if you turned on - * single stepping in 40008c */ - if (status & 0x01000000) { - nouveau_graph_trap_info(dev, &trap); - if (nouveau_ratelimit()) - nouveau_graph_dump_trap_info(dev, - "PGRAPH_SINGLE_STEP", &trap); - status &= ~0x01000000; - nv_wr32(dev, NV03_PGRAPH_INTR, 0x01000000); - } - - /* 0x02000000 happens when you pause a ctxprog... - * but the only way this can happen that I know is by - * poking the relevant MMIO register, and we don't - * do that. */ - - if (status) { - NV_INFO(dev, "Unhandled PGRAPH_INTR - 0x%08x\n", - status); - nv_wr32(dev, NV03_PGRAPH_INTR, status); - } - - { - const int isb = (1 << 16) | (1 << 0); - - if ((nv_rd32(dev, 0x400500) & isb) != isb) - nv_wr32(dev, 0x400500, - nv_rd32(dev, 0x400500) | isb); - } - } - - nv_wr32(dev, NV03_PMC_INTR_0, NV_PMC_INTR_0_PGRAPH_PENDING); - if (nv_rd32(dev, 0x400824) & (1 << 31)) - nv_wr32(dev, 0x400824, nv_rd32(dev, 0x400824) & ~(1 << 31)); -} - irqreturn_t nouveau_irq_handler(DRM_IRQ_ARGS) { struct drm_device *dev = (struct drm_device *)arg; struct drm_nouveau_private *dev_priv = dev->dev_private; unsigned long flags; - u32 status; + u32 stat; int i; - status = nv_rd32(dev, NV03_PMC_INTR_0); - if (!status) + stat = nv_rd32(dev, NV03_PMC_INTR_0); + if (!stat) return IRQ_NONE; spin_lock_irqsave(&dev_priv->context_switch_lock, flags); - - if (status & NV_PMC_INTR_0_PGRAPH_PENDING) { - if (dev_priv->card_type >= NV_50) - nv50_pgraph_irq_handler(dev); - else - nouveau_pgraph_irq_handler(dev); - - status &= ~NV_PMC_INTR_0_PGRAPH_PENDING; - } - - for (i = 0; i < 32 && status; i++) { - if (!(status & (1 << i)) || !dev_priv->irq_handler[i]) + for (i = 0; i < 32 && stat; i++) { + if (!(stat & (1 << i)) || !dev_priv->irq_handler[i]) continue; dev_priv->irq_handler[i](dev); - status &= ~(1 << i); + stat &= ~(1 << i); } - if (status) - NV_ERROR(dev, "Unhandled PMC INTR status bits 0x%08x\n", status); - - spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags); - if (dev_priv->msi_enabled) nv_wr08(dev, 0x00088068, 0xff); + spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags); + if (stat && nouveau_ratelimit()) + NV_ERROR(dev, "PMC - unhandled INTR 0x%08x\n", stat); return IRQ_HANDLED; } diff --git a/drivers/gpu/drm/nouveau/nouveau_object.c b/drivers/gpu/drm/nouveau/nouveau_object.c index 54078186fe65..94429553433c 100644 --- a/drivers/gpu/drm/nouveau/nouveau_object.c +++ b/drivers/gpu/drm/nouveau/nouveau_object.c @@ -113,6 +113,24 @@ nouveau_gpuobj_mthd_call(struct nouveau_channel *chan, return -ENOENT; } +int +nouveau_gpuobj_mthd_call2(struct drm_device *dev, int chid, + u32 class, u32 mthd, u32 data) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_channel *chan = NULL; + unsigned long flags; + int ret = -EINVAL; + + spin_lock_irqsave(&dev_priv->channels.lock, flags); + if (chid > 0 && chid < dev_priv->engine.fifo.channels) + chan = dev_priv->channels.ptr[chid]; + if (chan) + ret = nouveau_gpuobj_mthd_call(chan, class, mthd, data); + spin_unlock_irqrestore(&dev_priv->channels.lock, flags); + return ret; +} + /* NVidia uses context objects to drive drawing operations. Context objects can be selected into 8 subchannels in the FIFO, diff --git a/drivers/gpu/drm/nouveau/nv04_graph.c b/drivers/gpu/drm/nouveau/nv04_graph.c index 239519aefce6..0bc616d35eb6 100644 --- a/drivers/gpu/drm/nouveau/nv04_graph.c +++ b/drivers/gpu/drm/nouveau/nv04_graph.c @@ -27,8 +27,10 @@ #include "nouveau_drm.h" #include "nouveau_drv.h" #include "nouveau_hw.h" +#include "nouveau_util.h" -static int nv04_graph_register(struct drm_device *dev); +static int nv04_graph_register(struct drm_device *dev); +static void nv04_graph_isr(struct drm_device *dev); static uint32_t nv04_graph_ctx_regs[] = { 0x0040053c, @@ -363,7 +365,7 @@ nv04_graph_channel(struct drm_device *dev) return dev_priv->channels.ptr[chid]; } -void +static void nv04_graph_context_switch(struct drm_device *dev) { struct drm_nouveau_private *dev_priv = dev->dev_private; @@ -498,6 +500,7 @@ int nv04_graph_init(struct drm_device *dev) return ret; /* Enable PGRAPH interrupts */ + nouveau_irq_register(dev, 12, nv04_graph_isr); nv_wr32(dev, NV03_PGRAPH_INTR, 0xFFFFFFFF); nv_wr32(dev, NV03_PGRAPH_INTR_EN, 0xFFFFFFFF); @@ -533,6 +536,8 @@ int nv04_graph_init(struct drm_device *dev) void nv04_graph_takedown(struct drm_device *dev) { + nv_wr32(dev, NV03_PGRAPH_INTR_EN, 0x00000000); + nouveau_irq_unregister(dev, 12); } void @@ -1224,3 +1229,89 @@ nv04_graph_register(struct drm_device *dev) dev_priv->engine.graph.registered = true; return 0; }; + +static struct nouveau_bitfield nv04_graph_intr[] = { + { NV_PGRAPH_INTR_NOTIFY, "NOTIFY" }, + {} +}; + +static struct nouveau_bitfield nv04_graph_nstatus[] = +{ + { NV04_PGRAPH_NSTATUS_STATE_IN_USE, "STATE_IN_USE" }, + { NV04_PGRAPH_NSTATUS_INVALID_STATE, "INVALID_STATE" }, + { NV04_PGRAPH_NSTATUS_BAD_ARGUMENT, "BAD_ARGUMENT" }, + { NV04_PGRAPH_NSTATUS_PROTECTION_FAULT, "PROTECTION_FAULT" }, + {} +}; + +struct nouveau_bitfield nv04_graph_nsource[] = +{ + { NV03_PGRAPH_NSOURCE_NOTIFICATION, "NOTIFICATION" }, + { NV03_PGRAPH_NSOURCE_DATA_ERROR, "DATA_ERROR" }, + { NV03_PGRAPH_NSOURCE_PROTECTION_ERROR, "PROTECTION_ERROR" }, + { NV03_PGRAPH_NSOURCE_RANGE_EXCEPTION, "RANGE_EXCEPTION" }, + { NV03_PGRAPH_NSOURCE_LIMIT_COLOR, "LIMIT_COLOR" }, + { NV03_PGRAPH_NSOURCE_LIMIT_ZETA, "LIMIT_ZETA" }, + { NV03_PGRAPH_NSOURCE_ILLEGAL_MTHD, "ILLEGAL_MTHD" }, + { NV03_PGRAPH_NSOURCE_DMA_R_PROTECTION, "DMA_R_PROTECTION" }, + { NV03_PGRAPH_NSOURCE_DMA_W_PROTECTION, "DMA_W_PROTECTION" }, + { NV03_PGRAPH_NSOURCE_FORMAT_EXCEPTION, "FORMAT_EXCEPTION" }, + { NV03_PGRAPH_NSOURCE_PATCH_EXCEPTION, "PATCH_EXCEPTION" }, + { NV03_PGRAPH_NSOURCE_STATE_INVALID, "STATE_INVALID" }, + { NV03_PGRAPH_NSOURCE_DOUBLE_NOTIFY, "DOUBLE_NOTIFY" }, + { NV03_PGRAPH_NSOURCE_NOTIFY_IN_USE, "NOTIFY_IN_USE" }, + { NV03_PGRAPH_NSOURCE_METHOD_CNT, "METHOD_CNT" }, + { NV03_PGRAPH_NSOURCE_BFR_NOTIFICATION, "BFR_NOTIFICATION" }, + { NV03_PGRAPH_NSOURCE_DMA_VTX_PROTECTION, "DMA_VTX_PROTECTION" }, + { NV03_PGRAPH_NSOURCE_DMA_WIDTH_A, "DMA_WIDTH_A" }, + { NV03_PGRAPH_NSOURCE_DMA_WIDTH_B, "DMA_WIDTH_B" }, + {} +}; + +static void +nv04_graph_isr(struct drm_device *dev) +{ + u32 stat; + + while ((stat = nv_rd32(dev, NV03_PGRAPH_INTR))) { + u32 nsource = nv_rd32(dev, NV03_PGRAPH_NSOURCE); + u32 nstatus = nv_rd32(dev, NV03_PGRAPH_NSTATUS); + u32 addr = nv_rd32(dev, NV04_PGRAPH_TRAPPED_ADDR); + u32 chid = (addr & 0x0f000000) >> 24; + u32 subc = (addr & 0x0000e000) >> 13; + u32 mthd = (addr & 0x00001ffc); + u32 data = nv_rd32(dev, NV04_PGRAPH_TRAPPED_DATA); + u32 class = nv_rd32(dev, 0x400180 + subc * 4) & 0xff; + u32 show = stat; + + if (stat & NV_PGRAPH_INTR_NOTIFY) { + if (nsource & NV03_PGRAPH_NSOURCE_ILLEGAL_MTHD) { + if (!nouveau_gpuobj_mthd_call2(dev, chid, class, mthd, data)) + show &= ~NV_PGRAPH_INTR_NOTIFY; + } + } + + if (stat & NV_PGRAPH_INTR_CONTEXT_SWITCH) { + nv_wr32(dev, NV03_PGRAPH_INTR, NV_PGRAPH_INTR_CONTEXT_SWITCH); + stat &= ~NV_PGRAPH_INTR_CONTEXT_SWITCH; + show &= ~NV_PGRAPH_INTR_CONTEXT_SWITCH; + nv04_graph_context_switch(dev); + } + + nv_wr32(dev, NV03_PGRAPH_INTR, stat); + nv_wr32(dev, NV04_PGRAPH_FIFO, 0x00000001); + + if (show && nouveau_ratelimit()) { + NV_INFO(dev, "PGRAPH -"); + nouveau_bitfield_print(nv04_graph_intr, show); + printk(" nsource:"); + nouveau_bitfield_print(nv04_graph_nsource, nsource); + printk(" nstatus:"); + nouveau_bitfield_print(nv04_graph_nstatus, nstatus); + printk("\n"); + NV_INFO(dev, "PGRAPH - ch %d/%d class 0x%04x " + "mthd 0x%04x data 0x%08x\n", + chid, subc, class, mthd, data); + } + } +} diff --git a/drivers/gpu/drm/nouveau/nv10_graph.c b/drivers/gpu/drm/nouveau/nv10_graph.c index 1cd141edca04..536b39e4a9e2 100644 --- a/drivers/gpu/drm/nouveau/nv10_graph.c +++ b/drivers/gpu/drm/nouveau/nv10_graph.c @@ -26,8 +26,10 @@ #include "drm.h" #include "nouveau_drm.h" #include "nouveau_drv.h" +#include "nouveau_util.h" -static int nv10_graph_register(struct drm_device *); +static int nv10_graph_register(struct drm_device *); +static void nv10_graph_isr(struct drm_device *); #define NV10_FIFO_NUMBER 32 @@ -788,7 +790,7 @@ nv10_graph_unload_context(struct drm_device *dev) return 0; } -void +static void nv10_graph_context_switch(struct drm_device *dev) { struct drm_nouveau_private *dev_priv = dev->dev_private; @@ -924,6 +926,7 @@ int nv10_graph_init(struct drm_device *dev) if (ret) return ret; + nouveau_irq_register(dev, 12, nv10_graph_isr); nv_wr32(dev, NV03_PGRAPH_INTR , 0xFFFFFFFF); nv_wr32(dev, NV03_PGRAPH_INTR_EN, 0xFFFFFFFF); @@ -966,6 +969,8 @@ int nv10_graph_init(struct drm_device *dev) void nv10_graph_takedown(struct drm_device *dev) { + nv_wr32(dev, NV03_PGRAPH_INTR_EN, 0x00000000); + nouveau_irq_unregister(dev, 12); } static int @@ -1117,3 +1122,66 @@ nv10_graph_register(struct drm_device *dev) dev_priv->engine.graph.registered = true; return 0; } + +struct nouveau_bitfield nv10_graph_intr[] = { + { NV_PGRAPH_INTR_NOTIFY, "NOTIFY" }, + { NV_PGRAPH_INTR_ERROR, "ERROR" }, + {} +}; + +struct nouveau_bitfield nv10_graph_nstatus[] = +{ + { NV10_PGRAPH_NSTATUS_STATE_IN_USE, "STATE_IN_USE" }, + { NV10_PGRAPH_NSTATUS_INVALID_STATE, "INVALID_STATE" }, + { NV10_PGRAPH_NSTATUS_BAD_ARGUMENT, "BAD_ARGUMENT" }, + { NV10_PGRAPH_NSTATUS_PROTECTION_FAULT, "PROTECTION_FAULT" }, + {} +}; + +static void +nv10_graph_isr(struct drm_device *dev) +{ + u32 stat; + + while ((stat = nv_rd32(dev, NV03_PGRAPH_INTR))) { + u32 nsource = nv_rd32(dev, NV03_PGRAPH_NSOURCE); + u32 nstatus = nv_rd32(dev, NV03_PGRAPH_NSTATUS); + u32 addr = nv_rd32(dev, NV04_PGRAPH_TRAPPED_ADDR); + u32 chid = (addr & 0x01f00000) >> 20; + u32 subc = (addr & 0x00070000) >> 16; + u32 mthd = (addr & 0x00001ffc); + u32 data = nv_rd32(dev, NV04_PGRAPH_TRAPPED_DATA); + u32 class = nv_rd32(dev, 0x400160 + subc * 4) & 0xfff; + u32 show = stat; + + if (stat & NV_PGRAPH_INTR_ERROR) { + if (nsource & NV03_PGRAPH_NSOURCE_ILLEGAL_MTHD) { + if (!nouveau_gpuobj_mthd_call2(dev, chid, class, mthd, data)) + show &= ~NV_PGRAPH_INTR_ERROR; + } + } + + if (stat & NV_PGRAPH_INTR_CONTEXT_SWITCH) { + nv_wr32(dev, NV03_PGRAPH_INTR, NV_PGRAPH_INTR_CONTEXT_SWITCH); + stat &= ~NV_PGRAPH_INTR_CONTEXT_SWITCH; + show &= ~NV_PGRAPH_INTR_CONTEXT_SWITCH; + nv10_graph_context_switch(dev); + } + + nv_wr32(dev, NV03_PGRAPH_INTR, stat); + nv_wr32(dev, NV04_PGRAPH_FIFO, 0x00000001); + + if (show && nouveau_ratelimit()) { + NV_INFO(dev, "PGRAPH -"); + nouveau_bitfield_print(nv10_graph_intr, show); + printk(" nsource:"); + nouveau_bitfield_print(nv04_graph_nsource, nsource); + printk(" nstatus:"); + nouveau_bitfield_print(nv10_graph_nstatus, nstatus); + printk("\n"); + NV_INFO(dev, "PGRAPH - ch %d/%d class 0x%04x " + "mthd 0x%04x data 0x%08x\n", + chid, subc, class, mthd, data); + } + } +} diff --git a/drivers/gpu/drm/nouveau/nv20_graph.c b/drivers/gpu/drm/nouveau/nv20_graph.c index bd065c2fcba4..8464b76798d5 100644 --- a/drivers/gpu/drm/nouveau/nv20_graph.c +++ b/drivers/gpu/drm/nouveau/nv20_graph.c @@ -34,6 +34,7 @@ static int nv20_graph_register(struct drm_device *); static int nv30_graph_register(struct drm_device *); +static void nv20_graph_isr(struct drm_device *); static void nv20_graph_context_init(struct drm_device *dev, struct nouveau_gpuobj *ctx) @@ -584,6 +585,7 @@ nv20_graph_init(struct drm_device *dev) return ret; } + nouveau_irq_register(dev, 12, nv20_graph_isr); nv_wr32(dev, NV03_PGRAPH_INTR , 0xFFFFFFFF); nv_wr32(dev, NV03_PGRAPH_INTR_EN, 0xFFFFFFFF); @@ -661,6 +663,9 @@ nv20_graph_takedown(struct drm_device *dev) struct drm_nouveau_private *dev_priv = dev->dev_private; struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; + nv_wr32(dev, NV03_PGRAPH_INTR_EN, 0x00000000); + nouveau_irq_unregister(dev, 12); + nouveau_gpuobj_ref(NULL, &pgraph->ctx_table); } @@ -712,6 +717,7 @@ nv30_graph_init(struct drm_device *dev) nv_wr32(dev, NV20_PGRAPH_CHANNEL_CTX_TABLE, pgraph->ctx_table->pinst >> 4); + nouveau_irq_register(dev, 12, nv20_graph_isr); nv_wr32(dev, NV03_PGRAPH_INTR , 0xFFFFFFFF); nv_wr32(dev, NV03_PGRAPH_INTR_EN, 0xFFFFFFFF); @@ -850,3 +856,44 @@ nv30_graph_register(struct drm_device *dev) dev_priv->engine.graph.registered = true; return 0; } + +static void +nv20_graph_isr(struct drm_device *dev) +{ + u32 stat; + + while ((stat = nv_rd32(dev, NV03_PGRAPH_INTR))) { + u32 nsource = nv_rd32(dev, NV03_PGRAPH_NSOURCE); + u32 nstatus = nv_rd32(dev, NV03_PGRAPH_NSTATUS); + u32 addr = nv_rd32(dev, NV04_PGRAPH_TRAPPED_ADDR); + u32 chid = (addr & 0x01f00000) >> 20; + u32 subc = (addr & 0x00070000) >> 16; + u32 mthd = (addr & 0x00001ffc); + u32 data = nv_rd32(dev, NV04_PGRAPH_TRAPPED_DATA); + u32 class = nv_rd32(dev, 0x400160 + subc * 4) & 0xfff; + u32 show = stat; + + if (stat & NV_PGRAPH_INTR_ERROR) { + if (nsource & NV03_PGRAPH_NSOURCE_ILLEGAL_MTHD) { + if (!nouveau_gpuobj_mthd_call2(dev, chid, class, mthd, data)) + show &= ~NV_PGRAPH_INTR_ERROR; + } + } + + nv_wr32(dev, NV03_PGRAPH_INTR, stat); + nv_wr32(dev, NV04_PGRAPH_FIFO, 0x00000001); + + if (show && nouveau_ratelimit()) { + NV_INFO(dev, "PGRAPH -"); + nouveau_bitfield_print(nv10_graph_intr, show); + printk(" nsource:"); + nouveau_bitfield_print(nv04_graph_nsource, nsource); + printk(" nstatus:"); + nouveau_bitfield_print(nv10_graph_nstatus, nstatus); + printk("\n"); + NV_INFO(dev, "PGRAPH - ch %d/%d class 0x%04x " + "mthd 0x%04x data 0x%08x\n", + chid, subc, class, mthd, data); + } + } +} diff --git a/drivers/gpu/drm/nouveau/nv40_graph.c b/drivers/gpu/drm/nouveau/nv40_graph.c index 7a51608b55ba..0618846a97ce 100644 --- a/drivers/gpu/drm/nouveau/nv40_graph.c +++ b/drivers/gpu/drm/nouveau/nv40_graph.c @@ -30,6 +30,7 @@ #include "nouveau_grctx.h" static int nv40_graph_register(struct drm_device *); +static void nv40_graph_isr(struct drm_device *); struct nouveau_channel * nv40_graph_channel(struct drm_device *dev) @@ -277,6 +278,7 @@ nv40_graph_init(struct drm_device *dev) /* No context present currently */ nv_wr32(dev, NV40_PGRAPH_CTXCTL_CUR, 0x00000000); + nouveau_irq_register(dev, 12, nv40_graph_isr); nv_wr32(dev, NV03_PGRAPH_INTR , 0xFFFFFFFF); nv_wr32(dev, NV40_PGRAPH_INTR_EN, 0xFFFFFFFF); @@ -408,6 +410,7 @@ nv40_graph_init(struct drm_device *dev) void nv40_graph_takedown(struct drm_device *dev) { + nouveau_irq_unregister(dev, 12); } static int @@ -449,3 +452,69 @@ nv40_graph_register(struct drm_device *dev) dev_priv->engine.graph.registered = true; return 0; } + +static int +nv40_graph_isr_chid(struct drm_device *dev, u32 inst) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_channel *chan; + unsigned long flags; + int i; + + spin_lock_irqsave(&dev_priv->channels.lock, flags); + for (i = 0; i < dev_priv->engine.fifo.channels; i++) { + chan = dev_priv->channels.ptr[i]; + if (!chan || !chan->ramin_grctx) + continue; + + if (inst == chan->ramin_grctx->pinst) + break; + } + spin_unlock_irqrestore(&dev_priv->channels.lock, flags); + return i; +} + +static void +nv40_graph_isr(struct drm_device *dev) +{ + u32 stat; + + while ((stat = nv_rd32(dev, NV03_PGRAPH_INTR))) { + u32 nsource = nv_rd32(dev, NV03_PGRAPH_NSOURCE); + u32 nstatus = nv_rd32(dev, NV03_PGRAPH_NSTATUS); + u32 inst = (nv_rd32(dev, 0x40032c) & 0x000fffff) << 4; + u32 chid = nv40_graph_isr_chid(dev, inst); + u32 addr = nv_rd32(dev, NV04_PGRAPH_TRAPPED_ADDR); + u32 subc = (addr & 0x00070000) >> 16; + u32 mthd = (addr & 0x00001ffc); + u32 data = nv_rd32(dev, NV04_PGRAPH_TRAPPED_DATA); + u32 class = nv_rd32(dev, 0x400160 + subc * 4) & 0xffff; + u32 show = stat; + + if (stat & NV_PGRAPH_INTR_ERROR) { + if (nsource & NV03_PGRAPH_NSOURCE_ILLEGAL_MTHD) { + if (!nouveau_gpuobj_mthd_call2(dev, chid, class, mthd, data)) + show &= ~NV_PGRAPH_INTR_ERROR; + } else + if (nsource & NV03_PGRAPH_NSOURCE_DMA_VTX_PROTECTION) { + nv_mask(dev, 0x402000, 0, 0); + } + } + + nv_wr32(dev, NV03_PGRAPH_INTR, stat); + nv_wr32(dev, NV04_PGRAPH_FIFO, 0x00000001); + + if (show && nouveau_ratelimit()) { + NV_INFO(dev, "PGRAPH -"); + nouveau_bitfield_print(nv10_graph_intr, show); + printk(" nsource:"); + nouveau_bitfield_print(nv04_graph_nsource, nsource); + printk(" nstatus:"); + nouveau_bitfield_print(nv10_graph_nstatus, nstatus); + printk("\n"); + NV_INFO(dev, "PGRAPH - ch %d (0x%08x) subc %d " + "class 0x%04x mthd 0x%04x data 0x%08x\n", + chid, inst, subc, class, mthd, data); + } + } +} diff --git a/drivers/gpu/drm/nouveau/nv50_graph.c b/drivers/gpu/drm/nouveau/nv50_graph.c index 6785269f778a..b3900788c66d 100644 --- a/drivers/gpu/drm/nouveau/nv50_graph.c +++ b/drivers/gpu/drm/nouveau/nv50_graph.c @@ -32,7 +32,8 @@ #include "nouveau_dma.h" #include "nv50_evo.h" -static int nv50_graph_register(struct drm_device *); +static int nv50_graph_register(struct drm_device *); +static void nv50_graph_isr(struct drm_device *); static void nv50_graph_init_reset(struct drm_device *dev) @@ -50,6 +51,7 @@ nv50_graph_init_intr(struct drm_device *dev) { NV_DEBUG(dev, "\n"); + nouveau_irq_register(dev, 12, nv50_graph_isr); nv_wr32(dev, NV03_PGRAPH_INTR, 0xffffffff); nv_wr32(dev, 0x400138, 0xffffffff); nv_wr32(dev, NV40_PGRAPH_INTR_EN, 0xffffffff); @@ -165,6 +167,8 @@ void nv50_graph_takedown(struct drm_device *dev) { NV_DEBUG(dev, "\n"); + nv_wr32(dev, 0x40013c, 0x00000000); + nouveau_irq_unregister(dev, 12); } void @@ -324,7 +328,7 @@ nv50_graph_unload_context(struct drm_device *dev) return 0; } -void +static void nv50_graph_context_switch(struct drm_device *dev) { uint32_t inst; @@ -512,3 +516,495 @@ nv86_graph_tlb_flush(struct drm_device *dev) nv_mask(dev, 0x400500, 0x00000001, 0x00000001); spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags); } + +static struct nouveau_enum nv50_mp_exec_error_names[] = +{ + { 3, "STACK_UNDERFLOW" }, + { 4, "QUADON_ACTIVE" }, + { 8, "TIMEOUT" }, + { 0x10, "INVALID_OPCODE" }, + { 0x40, "BREAKPOINT" }, + {} +}; + +static struct nouveau_bitfield nv50_graph_trap_m2mf[] = { + { 0x00000001, "NOTIFY" }, + { 0x00000002, "IN" }, + { 0x00000004, "OUT" }, + {} +}; + +static struct nouveau_bitfield nv50_graph_trap_vfetch[] = { + { 0x00000001, "FAULT" }, + {} +}; + +static struct nouveau_bitfield nv50_graph_trap_strmout[] = { + { 0x00000001, "FAULT" }, + {} +}; + +static struct nouveau_bitfield nv50_graph_trap_ccache[] = { + { 0x00000001, "FAULT" }, + {} +}; + +/* There must be a *lot* of these. Will take some time to gather them up. */ +static struct nouveau_enum nv50_data_error_names[] = { + { 4, "INVALID_VALUE" }, + { 5, "INVALID_ENUM" }, + { 8, "INVALID_OBJECT" }, + { 0xc, "INVALID_BITFIELD" }, + { 0x28, "MP_NO_REG_SPACE" }, + { 0x2b, "MP_BLOCK_SIZE_MISMATCH" }, + {} +}; + +static struct nouveau_bitfield nv50_graph_intr[] = { + { 0x00000001, "NOTIFY" }, + { 0x00000002, "COMPUTE_QUERY" }, + { 0x00000010, "ILLEGAL_MTHD" }, + { 0x00000020, "ILLEGAL_CLASS" }, + { 0x00000040, "DOUBLE_NOTIFY" }, + { 0x00001000, "CONTEXT_SWITCH" }, + { 0x00010000, "BUFFER_NOTIFY" }, + { 0x00100000, "DATA_ERROR" }, + { 0x00200000, "TRAP" }, + { 0x01000000, "SINGLE_STEP" }, + {} +}; + +static void +nv50_pgraph_mp_trap(struct drm_device *dev, int tpid, int display) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + uint32_t units = nv_rd32(dev, 0x1540); + uint32_t addr, mp10, status, pc, oplow, ophigh; + int i; + int mps = 0; + for (i = 0; i < 4; i++) { + if (!(units & 1 << (i+24))) + continue; + if (dev_priv->chipset < 0xa0) + addr = 0x408200 + (tpid << 12) + (i << 7); + else + addr = 0x408100 + (tpid << 11) + (i << 7); + mp10 = nv_rd32(dev, addr + 0x10); + status = nv_rd32(dev, addr + 0x14); + if (!status) + continue; + if (display) { + nv_rd32(dev, addr + 0x20); + pc = nv_rd32(dev, addr + 0x24); + oplow = nv_rd32(dev, addr + 0x70); + ophigh= nv_rd32(dev, addr + 0x74); + NV_INFO(dev, "PGRAPH_TRAP_MP_EXEC - " + "TP %d MP %d: ", tpid, i); + nouveau_enum_print(nv50_mp_exec_error_names, status); + printk(" at %06x warp %d, opcode %08x %08x\n", + pc&0xffffff, pc >> 24, + oplow, ophigh); + } + nv_wr32(dev, addr + 0x10, mp10); + nv_wr32(dev, addr + 0x14, 0); + mps++; + } + if (!mps && display) + NV_INFO(dev, "PGRAPH_TRAP_MP_EXEC - TP %d: " + "No MPs claiming errors?\n", tpid); +} + +static void +nv50_pgraph_tp_trap(struct drm_device *dev, int type, uint32_t ustatus_old, + uint32_t ustatus_new, int display, const char *name) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + int tps = 0; + uint32_t units = nv_rd32(dev, 0x1540); + int i, r; + uint32_t ustatus_addr, ustatus; + for (i = 0; i < 16; i++) { + if (!(units & (1 << i))) + continue; + if (dev_priv->chipset < 0xa0) + ustatus_addr = ustatus_old + (i << 12); + else + ustatus_addr = ustatus_new + (i << 11); + ustatus = nv_rd32(dev, ustatus_addr) & 0x7fffffff; + if (!ustatus) + continue; + tps++; + switch (type) { + case 6: /* texture error... unknown for now */ + nv50_fb_vm_trap(dev, display, name); + if (display) { + NV_ERROR(dev, "magic set %d:\n", i); + for (r = ustatus_addr + 4; r <= ustatus_addr + 0x10; r += 4) + NV_ERROR(dev, "\t0x%08x: 0x%08x\n", r, + nv_rd32(dev, r)); + } + break; + case 7: /* MP error */ + if (ustatus & 0x00010000) { + nv50_pgraph_mp_trap(dev, i, display); + ustatus &= ~0x00010000; + } + break; + case 8: /* TPDMA error */ + { + uint32_t e0c = nv_rd32(dev, ustatus_addr + 4); + uint32_t e10 = nv_rd32(dev, ustatus_addr + 8); + uint32_t e14 = nv_rd32(dev, ustatus_addr + 0xc); + uint32_t e18 = nv_rd32(dev, ustatus_addr + 0x10); + uint32_t e1c = nv_rd32(dev, ustatus_addr + 0x14); + uint32_t e20 = nv_rd32(dev, ustatus_addr + 0x18); + uint32_t e24 = nv_rd32(dev, ustatus_addr + 0x1c); + nv50_fb_vm_trap(dev, display, name); + /* 2d engine destination */ + if (ustatus & 0x00000010) { + if (display) { + NV_INFO(dev, "PGRAPH_TRAP_TPDMA_2D - TP %d - Unknown fault at address %02x%08x\n", + i, e14, e10); + NV_INFO(dev, "PGRAPH_TRAP_TPDMA_2D - TP %d - e0c: %08x, e18: %08x, e1c: %08x, e20: %08x, e24: %08x\n", + i, e0c, e18, e1c, e20, e24); + } + ustatus &= ~0x00000010; + } + /* Render target */ + if (ustatus & 0x00000040) { + if (display) { + NV_INFO(dev, "PGRAPH_TRAP_TPDMA_RT - TP %d - Unknown fault at address %02x%08x\n", + i, e14, e10); + NV_INFO(dev, "PGRAPH_TRAP_TPDMA_RT - TP %d - e0c: %08x, e18: %08x, e1c: %08x, e20: %08x, e24: %08x\n", + i, e0c, e18, e1c, e20, e24); + } + ustatus &= ~0x00000040; + } + /* CUDA memory: l[], g[] or stack. */ + if (ustatus & 0x00000080) { + if (display) { + if (e18 & 0x80000000) { + /* g[] read fault? */ + NV_INFO(dev, "PGRAPH_TRAP_TPDMA - TP %d - Global read fault at address %02x%08x\n", + i, e14, e10 | ((e18 >> 24) & 0x1f)); + e18 &= ~0x1f000000; + } else if (e18 & 0xc) { + /* g[] write fault? */ + NV_INFO(dev, "PGRAPH_TRAP_TPDMA - TP %d - Global write fault at address %02x%08x\n", + i, e14, e10 | ((e18 >> 7) & 0x1f)); + e18 &= ~0x00000f80; + } else { + NV_INFO(dev, "PGRAPH_TRAP_TPDMA - TP %d - Unknown CUDA fault at address %02x%08x\n", + i, e14, e10); + } + NV_INFO(dev, "PGRAPH_TRAP_TPDMA - TP %d - e0c: %08x, e18: %08x, e1c: %08x, e20: %08x, e24: %08x\n", + i, e0c, e18, e1c, e20, e24); + } + ustatus &= ~0x00000080; + } + } + break; + } + if (ustatus) { + if (display) + NV_INFO(dev, "%s - TP%d: Unhandled ustatus 0x%08x\n", name, i, ustatus); + } + nv_wr32(dev, ustatus_addr, 0xc0000000); + } + + if (!tps && display) + NV_INFO(dev, "%s - No TPs claiming errors?\n", name); +} + +static int +nv50_pgraph_trap_handler(struct drm_device *dev, u32 display, u64 inst, u32 chid) +{ + u32 status = nv_rd32(dev, 0x400108); + u32 ustatus; + + if (!status && display) { + NV_INFO(dev, "PGRAPH - TRAP: no units reporting traps?\n"); + return 1; + } + + /* DISPATCH: Relays commands to other units and handles NOTIFY, + * COND, QUERY. If you get a trap from it, the command is still stuck + * in DISPATCH and you need to do something about it. */ + if (status & 0x001) { + ustatus = nv_rd32(dev, 0x400804) & 0x7fffffff; + if (!ustatus && display) { + NV_INFO(dev, "PGRAPH_TRAP_DISPATCH - no ustatus?\n"); + } + + nv_wr32(dev, 0x400500, 0x00000000); + + /* Known to be triggered by screwed up NOTIFY and COND... */ + if (ustatus & 0x00000001) { + u32 addr = nv_rd32(dev, 0x400808); + u32 subc = (addr & 0x00070000) >> 16; + u32 mthd = (addr & 0x00001ffc); + u32 datal = nv_rd32(dev, 0x40080c); + u32 datah = nv_rd32(dev, 0x400810); + u32 class = nv_rd32(dev, 0x400814); + u32 r848 = nv_rd32(dev, 0x400848); + + NV_INFO(dev, "PGRAPH - TRAP DISPATCH_FAULT\n"); + if (display && (addr & 0x80000000)) { + NV_INFO(dev, "PGRAPH - ch %d (0x%010llx) " + "subc %d class 0x%04x mthd 0x%04x " + "data 0x%08x%08x " + "400808 0x%08x 400848 0x%08x\n", + chid, inst, subc, class, mthd, datah, + datal, addr, r848); + } else + if (display) { + NV_INFO(dev, "PGRAPH - no stuck command?\n"); + } + + nv_wr32(dev, 0x400808, 0); + nv_wr32(dev, 0x4008e8, nv_rd32(dev, 0x4008e8) & 3); + nv_wr32(dev, 0x400848, 0); + ustatus &= ~0x00000001; + } + + if (ustatus & 0x00000002) { + u32 addr = nv_rd32(dev, 0x40084c); + u32 subc = (addr & 0x00070000) >> 16; + u32 mthd = (addr & 0x00001ffc); + u32 data = nv_rd32(dev, 0x40085c); + u32 class = nv_rd32(dev, 0x400814); + + NV_INFO(dev, "PGRAPH - TRAP DISPATCH_QUERY\n"); + if (display && (addr & 0x80000000)) { + NV_INFO(dev, "PGRAPH - ch %d (0x%010llx) " + "subc %d class 0x%04x mthd 0x%04x " + "data 0x%08x 40084c 0x%08x\n", + chid, inst, subc, class, mthd, + data, addr); + } else + if (display) { + NV_INFO(dev, "PGRAPH - no stuck command?\n"); + } + + nv_wr32(dev, 0x40084c, 0); + ustatus &= ~0x00000002; + } + + if (ustatus && display) { + NV_INFO(dev, "PGRAPH - TRAP_DISPATCH (unknown " + "0x%08x)\n", ustatus); + } + + nv_wr32(dev, 0x400804, 0xc0000000); + nv_wr32(dev, 0x400108, 0x001); + status &= ~0x001; + if (!status) + return 0; + } + + /* M2MF: Memory to memory copy engine. */ + if (status & 0x002) { + u32 ustatus = nv_rd32(dev, 0x406800) & 0x7fffffff; + if (display) { + NV_INFO(dev, "PGRAPH - TRAP_M2MF"); + nouveau_bitfield_print(nv50_graph_trap_m2mf, ustatus); + printk("\n"); + NV_INFO(dev, "PGRAPH - TRAP_M2MF %08x %08x %08x %08x\n", + nv_rd32(dev, 0x406804), nv_rd32(dev, 0x406808), + nv_rd32(dev, 0x40680c), nv_rd32(dev, 0x406810)); + + } + + /* No sane way found yet -- just reset the bugger. */ + nv_wr32(dev, 0x400040, 2); + nv_wr32(dev, 0x400040, 0); + nv_wr32(dev, 0x406800, 0xc0000000); + nv_wr32(dev, 0x400108, 0x002); + status &= ~0x002; + } + + /* VFETCH: Fetches data from vertex buffers. */ + if (status & 0x004) { + u32 ustatus = nv_rd32(dev, 0x400c04) & 0x7fffffff; + if (display) { + NV_INFO(dev, "PGRAPH - TRAP_VFETCH"); + nouveau_bitfield_print(nv50_graph_trap_vfetch, ustatus); + printk("\n"); + NV_INFO(dev, "PGRAPH - TRAP_VFETCH %08x %08x %08x %08x\n", + nv_rd32(dev, 0x400c00), nv_rd32(dev, 0x400c08), + nv_rd32(dev, 0x400c0c), nv_rd32(dev, 0x400c10)); + } + + nv_wr32(dev, 0x400c04, 0xc0000000); + nv_wr32(dev, 0x400108, 0x004); + status &= ~0x004; + } + + /* STRMOUT: DirectX streamout / OpenGL transform feedback. */ + if (status & 0x008) { + ustatus = nv_rd32(dev, 0x401800) & 0x7fffffff; + if (display) { + NV_INFO(dev, "PGRAPH - TRAP_STRMOUT"); + nouveau_bitfield_print(nv50_graph_trap_strmout, ustatus); + printk("\n"); + NV_INFO(dev, "PGRAPH - TRAP_STRMOUT %08x %08x %08x %08x\n", + nv_rd32(dev, 0x401804), nv_rd32(dev, 0x401808), + nv_rd32(dev, 0x40180c), nv_rd32(dev, 0x401810)); + + } + + /* No sane way found yet -- just reset the bugger. */ + nv_wr32(dev, 0x400040, 0x80); + nv_wr32(dev, 0x400040, 0); + nv_wr32(dev, 0x401800, 0xc0000000); + nv_wr32(dev, 0x400108, 0x008); + status &= ~0x008; + } + + /* CCACHE: Handles code and c[] caches and fills them. */ + if (status & 0x010) { + ustatus = nv_rd32(dev, 0x405018) & 0x7fffffff; + if (display) { + NV_INFO(dev, "PGRAPH - TRAP_CCACHE"); + nouveau_bitfield_print(nv50_graph_trap_ccache, ustatus); + printk("\n"); + NV_INFO(dev, "PGRAPH - TRAP_CCACHE %08x %08x %08x %08x" + " %08x %08x %08x\n", + nv_rd32(dev, 0x405800), nv_rd32(dev, 0x405804), + nv_rd32(dev, 0x405808), nv_rd32(dev, 0x40580c), + nv_rd32(dev, 0x405810), nv_rd32(dev, 0x405814), + nv_rd32(dev, 0x40581c)); + + } + + nv_wr32(dev, 0x405018, 0xc0000000); + nv_wr32(dev, 0x400108, 0x010); + status &= ~0x010; + } + + /* Unknown, not seen yet... 0x402000 is the only trap status reg + * remaining, so try to handle it anyway. Perhaps related to that + * unknown DMA slot on tesla? */ + if (status & 0x20) { + ustatus = nv_rd32(dev, 0x402000) & 0x7fffffff; + if (display) + NV_INFO(dev, "PGRAPH - TRAP_UNKC04 0x%08x\n", ustatus); + nv_wr32(dev, 0x402000, 0xc0000000); + /* no status modifiction on purpose */ + } + + /* TEXTURE: CUDA texturing units */ + if (status & 0x040) { + nv50_pgraph_tp_trap(dev, 6, 0x408900, 0x408600, display, + "PGRAPH - TRAP_TEXTURE"); + nv_wr32(dev, 0x400108, 0x040); + status &= ~0x040; + } + + /* MP: CUDA execution engines. */ + if (status & 0x080) { + nv50_pgraph_tp_trap(dev, 7, 0x408314, 0x40831c, display, + "PGRAPH - TRAP_MP"); + nv_wr32(dev, 0x400108, 0x080); + status &= ~0x080; + } + + /* TPDMA: Handles TP-initiated uncached memory accesses: + * l[], g[], stack, 2d surfaces, render targets. */ + if (status & 0x100) { + nv50_pgraph_tp_trap(dev, 8, 0x408e08, 0x408708, display, + "PGRAPH - TRAP_TPDMA"); + nv_wr32(dev, 0x400108, 0x100); + status &= ~0x100; + } + + if (status) { + if (display) + NV_INFO(dev, "PGRAPH - TRAP: unknown 0x%08x\n", status); + nv_wr32(dev, 0x400108, status); + } + + return 1; +} + +static int +nv50_graph_isr_chid(struct drm_device *dev, u64 inst) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_channel *chan; + unsigned long flags; + int i; + + spin_lock_irqsave(&dev_priv->channels.lock, flags); + for (i = 0; i < dev_priv->engine.fifo.channels; i++) { + chan = dev_priv->channels.ptr[i]; + if (!chan || !chan->ramin) + continue; + + if (inst == chan->ramin->vinst) + break; + } + spin_unlock_irqrestore(&dev_priv->channels.lock, flags); + return i; +} + +static void +nv50_graph_isr(struct drm_device *dev) +{ + u32 stat; + + while ((stat = nv_rd32(dev, 0x400100))) { + u64 inst = (u64)(nv_rd32(dev, 0x40032c) & 0x0fffffff) << 12; + u32 chid = nv50_graph_isr_chid(dev, inst); + u32 addr = nv_rd32(dev, NV04_PGRAPH_TRAPPED_ADDR); + u32 subc = (addr & 0x00070000) >> 16; + u32 mthd = (addr & 0x00001ffc); + u32 data = nv_rd32(dev, NV04_PGRAPH_TRAPPED_DATA); + u32 class = nv_rd32(dev, 0x400814); + u32 show = stat; + + if (stat & 0x00000010) { + if (!nouveau_gpuobj_mthd_call2(dev, chid, class, + mthd, data)) + show &= ~0x00000010; + } + + if (stat & 0x00001000) { + nv_wr32(dev, 0x400500, 0x00000000); + nv_wr32(dev, 0x400100, 0x00001000); + nv_mask(dev, 0x40013c, 0x00001000, 0x00000000); + nv50_graph_context_switch(dev); + stat &= ~0x00001000; + show &= ~0x00001000; + } + + show = (show && nouveau_ratelimit()) ? show : 0; + + if (show & 0x00100000) { + u32 ecode = nv_rd32(dev, 0x400110); + NV_INFO(dev, "PGRAPH - DATA_ERROR "); + nouveau_enum_print(nv50_data_error_names, ecode); + printk("\n"); + } + + if (stat & 0x00200000) { + if (!nv50_pgraph_trap_handler(dev, show, inst, chid)) + show &= ~0x00200000; + } + + nv_wr32(dev, 0x400100, stat); + nv_wr32(dev, 0x400500, 0x00010001); + + if (show) { + NV_INFO(dev, "PGRAPH -"); + nouveau_bitfield_print(nv50_graph_intr, show); + printk("\n"); + NV_INFO(dev, "PGRAPH - ch %d (0x%010llx) subc %d " + "class 0x%04x mthd 0x%04x data 0x%08x\n", + chid, inst, subc, class, mthd, data); + } + } + + if (nv_rd32(dev, 0x400824) & (1 << 31)) + nv_wr32(dev, 0x400824, nv_rd32(dev, 0x400824) & ~(1 << 31)); +} -- cgit v1.2.3 From e4cbadcaaa4678020e37ca93502942ffdf9aef80 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Thu, 11 Nov 2010 13:59:05 +1000 Subject: drm/nv04-nv40: unregister irq handler on destroy Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nv04_display.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/gpu/drm/nouveau/nv04_display.c b/drivers/gpu/drm/nouveau/nv04_display.c index 0978a5b326dc..1715e1464b7d 100644 --- a/drivers/gpu/drm/nouveau/nv04_display.c +++ b/drivers/gpu/drm/nouveau/nv04_display.c @@ -213,6 +213,9 @@ nv04_display_destroy(struct drm_device *dev) NV_DEBUG_KMS(dev, "\n"); + nouveau_irq_unregister(dev, 24); + nouveau_irq_unregister(dev, 25); + /* Turn every CRTC off. */ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { struct drm_mode_set modeset = { -- cgit v1.2.3 From fce2bad0ee2666d6a10bfeb634b1021469cc3d79 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Thu, 11 Nov 2010 16:14:56 +1000 Subject: drm/nv50: rework PGPIO IRQ handling and hotplug detection Allows callers to install their own handlers for when a GPIO line changes state (such as for hotplug detect). This also fixes a bug where we weren't acknowledging the GPIO IRQ until after the bottom half had run, causing a severe IRQ storm in some cases. Reviewed-by: Francisco Jerez Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_connector.c | 54 +++++++- drivers/gpu/drm/nouveau/nouveau_dp.c | 6 +- drivers/gpu/drm/nouveau/nouveau_drv.h | 21 ++-- drivers/gpu/drm/nouveau/nouveau_state.c | 4 + drivers/gpu/drm/nouveau/nv50_display.c | 66 ---------- drivers/gpu/drm/nouveau/nv50_display.h | 1 - drivers/gpu/drm/nouveau/nv50_gpio.c | 186 +++++++++++++++++++++++++--- 7 files changed, 234 insertions(+), 104 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c index 52c356e9a3d1..a21e00076839 100644 --- a/drivers/gpu/drm/nouveau/nouveau_connector.c +++ b/drivers/gpu/drm/nouveau/nouveau_connector.c @@ -37,6 +37,8 @@ #include "nouveau_connector.h" #include "nouveau_hw.h" +static void nouveau_connector_hotplug(void *, int); + static struct nouveau_encoder * find_encoder_by_type(struct drm_connector *connector, int type) { @@ -94,22 +96,30 @@ nouveau_connector_bpp(struct drm_connector *connector) } static void -nouveau_connector_destroy(struct drm_connector *drm_connector) +nouveau_connector_destroy(struct drm_connector *connector) { - struct nouveau_connector *nv_connector = - nouveau_connector(drm_connector); + struct nouveau_connector *nv_connector = nouveau_connector(connector); + struct drm_nouveau_private *dev_priv; + struct nouveau_gpio_engine *pgpio; struct drm_device *dev; if (!nv_connector) return; dev = nv_connector->base.dev; + dev_priv = dev->dev_private; NV_DEBUG_KMS(dev, "\n"); + pgpio = &dev_priv->engine.gpio; + if (pgpio->irq_unregister) { + pgpio->irq_unregister(dev, nv_connector->dcb->gpio_tag, + nouveau_connector_hotplug, connector); + } + kfree(nv_connector->edid); - drm_sysfs_connector_remove(drm_connector); - drm_connector_cleanup(drm_connector); - kfree(drm_connector); + drm_sysfs_connector_remove(connector); + drm_connector_cleanup(connector); + kfree(connector); } static struct nouveau_i2c_chan * @@ -760,6 +770,7 @@ nouveau_connector_create(struct drm_device *dev, int index) { const struct drm_connector_funcs *funcs = &nouveau_connector_funcs; struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_gpio_engine *pgpio = &dev_priv->engine.gpio; struct nouveau_connector *nv_connector = NULL; struct dcb_connector_table_entry *dcb = NULL; struct drm_connector *connector; @@ -876,6 +887,11 @@ nouveau_connector_create(struct drm_device *dev, int index) break; } + if (pgpio->irq_register) { + pgpio->irq_register(dev, nv_connector->dcb->gpio_tag, + nouveau_connector_hotplug, connector); + } + drm_sysfs_connector_add(connector); dcb->drm = connector; return dcb->drm; @@ -886,3 +902,29 @@ fail: return ERR_PTR(ret); } + +static void +nouveau_connector_hotplug(void *data, int plugged) +{ + struct drm_connector *connector = data; + struct drm_device *dev = connector->dev; + + NV_INFO(dev, "%splugged %s\n", plugged ? "" : "un", + drm_get_connector_name(connector)); + + if (connector->encoder && connector->encoder->crtc && + connector->encoder->crtc->enabled) { + struct nouveau_encoder *nv_encoder = nouveau_encoder(connector->encoder); + struct drm_encoder_helper_funcs *helper = + connector->encoder->helper_private; + + if (nv_encoder->dcb->type == OUTPUT_DP) { + if (plugged) + helper->dpms(connector->encoder, DRM_MODE_DPMS_ON); + else + helper->dpms(connector->encoder, DRM_MODE_DPMS_OFF); + } + } + + drm_helper_hpd_irq_event(dev); +} diff --git a/drivers/gpu/drm/nouveau/nouveau_dp.c b/drivers/gpu/drm/nouveau/nouveau_dp.c index 4562f309ae3d..38d599554bce 100644 --- a/drivers/gpu/drm/nouveau/nouveau_dp.c +++ b/drivers/gpu/drm/nouveau/nouveau_dp.c @@ -279,7 +279,7 @@ nouveau_dp_link_train(struct drm_encoder *encoder) struct bit_displayport_encoder_table *dpe; int dpe_headerlen; uint8_t config[4], status[3]; - bool cr_done, cr_max_vs, eq_done; + bool cr_done, cr_max_vs, eq_done, hpd_state; int ret = 0, i, tries, voltage; NV_DEBUG_KMS(dev, "link training!!\n"); @@ -297,7 +297,7 @@ nouveau_dp_link_train(struct drm_encoder *encoder) /* disable hotplug detect, this flips around on some panels during * link training. */ - pgpio->irq_enable(dev, nv_connector->dcb->gpio_tag, false); + hpd_state = pgpio->irq_enable(dev, nv_connector->dcb->gpio_tag, false); if (dpe->script0) { NV_DEBUG_KMS(dev, "SOR-%d: running DP script 0\n", nv_encoder->or); @@ -439,7 +439,7 @@ stop: } /* re-enable hotplug detect */ - pgpio->irq_enable(dev, nv_connector->dcb->gpio_tag, true); + pgpio->irq_enable(dev, nv_connector->dcb->gpio_tag, hpd_state); return eq_done; } diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index b19ef7fbb9dd..912c9f785222 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -376,13 +376,19 @@ struct nouveau_display_engine { }; struct nouveau_gpio_engine { + void *priv; + int (*init)(struct drm_device *); void (*takedown)(struct drm_device *); int (*get)(struct drm_device *, enum dcb_gpio_tag); int (*set)(struct drm_device *, enum dcb_gpio_tag, int state); - void (*irq_enable)(struct drm_device *, enum dcb_gpio_tag, bool on); + int (*irq_register)(struct drm_device *, enum dcb_gpio_tag, + void (*)(void *, int), void *); + void (*irq_unregister)(struct drm_device *, enum dcb_gpio_tag, + void (*)(void *, int), void *); + bool (*irq_enable)(struct drm_device *, enum dcb_gpio_tag, bool on); }; struct nouveau_pm_voltage_level { @@ -619,13 +625,6 @@ struct drm_nouveau_private { bool msi_enabled; struct workqueue_struct *wq; struct work_struct irq_work; - struct work_struct hpd_work; - - struct { - spinlock_t lock; - uint32_t hpd0_bits; - uint32_t hpd1_bits; - } hpd_state; struct list_head vbl_waiting; @@ -1366,7 +1365,11 @@ int nv50_gpio_init(struct drm_device *dev); void nv50_gpio_fini(struct drm_device *dev); int nv50_gpio_get(struct drm_device *dev, enum dcb_gpio_tag tag); int nv50_gpio_set(struct drm_device *dev, enum dcb_gpio_tag tag, int state); -void nv50_gpio_irq_enable(struct drm_device *, enum dcb_gpio_tag, bool on); +int nv50_gpio_irq_register(struct drm_device *, enum dcb_gpio_tag, + void (*)(void *, int), void *); +void nv50_gpio_irq_unregister(struct drm_device *, enum dcb_gpio_tag, + void (*)(void *, int), void *); +bool nv50_gpio_irq_enable(struct drm_device *, enum dcb_gpio_tag, bool on); /* nv50_calc. */ int nv50_calc_pll(struct drm_device *, struct pll_lims *, int clk, diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c index 262545b58d96..b26b34c419cb 100644 --- a/drivers/gpu/drm/nouveau/nouveau_state.c +++ b/drivers/gpu/drm/nouveau/nouveau_state.c @@ -396,6 +396,8 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->gpio.takedown = nv50_gpio_fini; engine->gpio.get = nv50_gpio_get; engine->gpio.set = nv50_gpio_set; + engine->gpio.irq_register = nv50_gpio_irq_register; + engine->gpio.irq_unregister = nv50_gpio_irq_unregister; engine->gpio.irq_enable = nv50_gpio_irq_enable; switch (dev_priv->chipset) { case 0x84: @@ -487,6 +489,8 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->gpio.takedown = nouveau_stub_takedown; engine->gpio.get = nv50_gpio_get; engine->gpio.set = nv50_gpio_set; + engine->gpio.irq_register = nv50_gpio_irq_register; + engine->gpio.irq_unregister = nv50_gpio_irq_unregister; engine->gpio.irq_enable = nv50_gpio_irq_enable; engine->crypt.init = nouveau_stub_init; engine->crypt.takedown = nouveau_stub_takedown; diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c index e5dbd171672c..7cc94ed9ed95 100644 --- a/drivers/gpu/drm/nouveau/nv50_display.c +++ b/drivers/gpu/drm/nouveau/nv50_display.c @@ -804,71 +804,6 @@ nv50_display_error_handler(struct drm_device *dev) } } -void -nv50_display_irq_hotplug_bh(struct work_struct *work) -{ - struct drm_nouveau_private *dev_priv = - container_of(work, struct drm_nouveau_private, hpd_work); - struct drm_device *dev = dev_priv->dev; - struct drm_connector *connector; - const uint32_t gpio_reg[4] = { 0xe104, 0xe108, 0xe280, 0xe284 }; - uint32_t unplug_mask, plug_mask, change_mask; - uint32_t hpd0, hpd1; - - spin_lock_irq(&dev_priv->hpd_state.lock); - hpd0 = dev_priv->hpd_state.hpd0_bits; - dev_priv->hpd_state.hpd0_bits = 0; - hpd1 = dev_priv->hpd_state.hpd1_bits; - dev_priv->hpd_state.hpd1_bits = 0; - spin_unlock_irq(&dev_priv->hpd_state.lock); - - hpd0 &= nv_rd32(dev, 0xe050); - if (dev_priv->chipset >= 0x90) - hpd1 &= nv_rd32(dev, 0xe070); - - plug_mask = (hpd0 & 0x0000ffff) | (hpd1 << 16); - unplug_mask = (hpd0 >> 16) | (hpd1 & 0xffff0000); - change_mask = plug_mask | unplug_mask; - - list_for_each_entry(connector, &dev->mode_config.connector_list, head) { - struct drm_encoder_helper_funcs *helper; - struct nouveau_connector *nv_connector = - nouveau_connector(connector); - struct nouveau_encoder *nv_encoder; - struct dcb_gpio_entry *gpio; - uint32_t reg; - bool plugged; - - if (!nv_connector->dcb) - continue; - - gpio = nouveau_bios_gpio_entry(dev, nv_connector->dcb->gpio_tag); - if (!gpio || !(change_mask & (1 << gpio->line))) - continue; - - reg = nv_rd32(dev, gpio_reg[gpio->line >> 3]); - plugged = !!(reg & (4 << ((gpio->line & 7) << 2))); - NV_INFO(dev, "%splugged %s\n", plugged ? "" : "un", - drm_get_connector_name(connector)) ; - - if (!connector->encoder || !connector->encoder->crtc || - !connector->encoder->crtc->enabled) - continue; - nv_encoder = nouveau_encoder(connector->encoder); - helper = connector->encoder->helper_private; - - if (nv_encoder->dcb->type != OUTPUT_DP) - continue; - - if (plugged) - helper->dpms(connector->encoder, DRM_MODE_DPMS_ON); - else - helper->dpms(connector->encoder, DRM_MODE_DPMS_OFF); - } - - drm_helper_hpd_irq_event(dev); -} - static void nv50_display_isr(struct drm_device *dev) { @@ -918,4 +853,3 @@ nv50_display_isr(struct drm_device *dev) } } } - diff --git a/drivers/gpu/drm/nouveau/nv50_display.h b/drivers/gpu/drm/nouveau/nv50_display.h index a269fccf3555..f0e30b78ef6b 100644 --- a/drivers/gpu/drm/nouveau/nv50_display.h +++ b/drivers/gpu/drm/nouveau/nv50_display.h @@ -36,7 +36,6 @@ #include "nv50_evo.h" void nv50_display_irq_handler_bh(struct work_struct *work); -void nv50_display_irq_hotplug_bh(struct work_struct *work); int nv50_display_early_init(struct drm_device *dev); void nv50_display_late_takedown(struct drm_device *dev); int nv50_display_create(struct drm_device *dev); diff --git a/drivers/gpu/drm/nouveau/nv50_gpio.c b/drivers/gpu/drm/nouveau/nv50_gpio.c index 87266d1b5def..6b149c0cc06d 100644 --- a/drivers/gpu/drm/nouveau/nv50_gpio.c +++ b/drivers/gpu/drm/nouveau/nv50_gpio.c @@ -29,6 +29,24 @@ #include "nv50_display.h" static void nv50_gpio_isr(struct drm_device *dev); +static void nv50_gpio_isr_bh(struct work_struct *work); + +struct nv50_gpio_priv { + struct list_head handlers; + spinlock_t lock; +}; + +struct nv50_gpio_handler { + struct drm_device *dev; + struct list_head head; + struct work_struct work; + bool inhibit; + + struct dcb_gpio_entry *gpio; + + void (*handler)(void *data, int state); + void *data; +}; static int nv50_gpio_location(struct dcb_gpio_entry *gpio, uint32_t *reg, uint32_t *shift) @@ -79,29 +97,123 @@ nv50_gpio_set(struct drm_device *dev, enum dcb_gpio_tag tag, int state) return 0; } +int +nv50_gpio_irq_register(struct drm_device *dev, enum dcb_gpio_tag tag, + void (*handler)(void *, int), void *data) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_gpio_engine *pgpio = &dev_priv->engine.gpio; + struct nv50_gpio_priv *priv = pgpio->priv; + struct nv50_gpio_handler *gpioh; + struct dcb_gpio_entry *gpio; + unsigned long flags; + + gpio = nouveau_bios_gpio_entry(dev, tag); + if (!gpio) + return -ENOENT; + + gpioh = kzalloc(sizeof(*gpioh), GFP_KERNEL); + if (!gpioh) + return -ENOMEM; + + INIT_WORK(&gpioh->work, nv50_gpio_isr_bh); + gpioh->dev = dev; + gpioh->gpio = gpio; + gpioh->handler = handler; + gpioh->data = data; + + spin_lock_irqsave(&priv->lock, flags); + list_add(&gpioh->head, &priv->handlers); + spin_unlock_irqrestore(&priv->lock, flags); + return 0; +} + void -nv50_gpio_irq_enable(struct drm_device *dev, enum dcb_gpio_tag tag, bool on) +nv50_gpio_irq_unregister(struct drm_device *dev, enum dcb_gpio_tag tag, + void (*handler)(void *, int), void *data) { + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_gpio_engine *pgpio = &dev_priv->engine.gpio; + struct nv50_gpio_priv *priv = pgpio->priv; + struct nv50_gpio_handler *gpioh, *tmp; struct dcb_gpio_entry *gpio; - u32 reg, mask; + unsigned long flags; gpio = nouveau_bios_gpio_entry(dev, tag); - if (!gpio) { - NV_ERROR(dev, "gpio tag 0x%02x not found\n", tag); + if (!gpio) return; + + spin_lock_irqsave(&priv->lock, flags); + list_for_each_entry_safe(gpioh, tmp, &priv->handlers, head) { + if (gpioh->gpio != gpio || + gpioh->handler != handler || + gpioh->data != data) + continue; + list_del(&gpioh->head); + kfree(gpioh); } + spin_unlock_irqrestore(&priv->lock, flags); +} + +bool +nv50_gpio_irq_enable(struct drm_device *dev, enum dcb_gpio_tag tag, bool on) +{ + struct dcb_gpio_entry *gpio; + u32 reg, mask; + + gpio = nouveau_bios_gpio_entry(dev, tag); + if (!gpio) + return false; reg = gpio->line < 16 ? 0xe050 : 0xe070; mask = 0x00010001 << (gpio->line & 0xf); nv_wr32(dev, reg + 4, mask); - nv_mask(dev, reg + 0, mask, on ? mask : 0); + reg = nv_mask(dev, reg + 0, mask, on ? mask : 0); + return (reg & mask) == mask; +} + +static int +nv50_gpio_create(struct drm_device *dev) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_gpio_engine *pgpio = &dev_priv->engine.gpio; + struct nv50_gpio_priv *priv; + + priv = kzalloc(sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + INIT_LIST_HEAD(&priv->handlers); + spin_lock_init(&priv->lock); + pgpio->priv = priv; + return 0; +} + +static void +nv50_gpio_destroy(struct drm_device *dev) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_gpio_engine *pgpio = &dev_priv->engine.gpio; + + kfree(pgpio->priv); + pgpio->priv = NULL; } int nv50_gpio_init(struct drm_device *dev) { struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_gpio_engine *pgpio = &dev_priv->engine.gpio; + struct nv50_gpio_priv *priv; + int ret; + + if (!pgpio->priv) { + ret = nv50_gpio_create(dev); + if (ret) + return ret; + } + priv = pgpio->priv; /* disable, and ack any pending gpio interrupts */ nv_wr32(dev, 0xe050, 0x00000000); @@ -111,8 +223,6 @@ nv50_gpio_init(struct drm_device *dev) nv_wr32(dev, 0xe074, 0xffffffff); } - INIT_WORK(&dev_priv->hpd_work, nv50_display_irq_hotplug_bh); - spin_lock_init(&dev_priv->hpd_state.lock); nouveau_irq_register(dev, 21, nv50_gpio_isr); return 0; } @@ -126,26 +236,64 @@ nv50_gpio_fini(struct drm_device *dev) if (dev_priv->chipset >= 0x90) nv_wr32(dev, 0xe070, 0x00000000); nouveau_irq_unregister(dev, 21); + + nv50_gpio_destroy(dev); +} + +static void +nv50_gpio_isr_bh(struct work_struct *work) +{ + struct nv50_gpio_handler *gpioh = + container_of(work, struct nv50_gpio_handler, work); + struct drm_nouveau_private *dev_priv = gpioh->dev->dev_private; + struct nouveau_gpio_engine *pgpio = &dev_priv->engine.gpio; + struct nv50_gpio_priv *priv = pgpio->priv; + unsigned long flags; + int state; + + state = pgpio->get(gpioh->dev, gpioh->gpio->tag); + if (state < 0) + return; + + gpioh->handler(gpioh->data, state); + + spin_lock_irqsave(&priv->lock, flags); + gpioh->inhibit = false; + spin_unlock_irqrestore(&priv->lock, flags); } static void nv50_gpio_isr(struct drm_device *dev) { struct drm_nouveau_private *dev_priv = dev->dev_private; - uint32_t hpd0_bits, hpd1_bits = 0; + struct nouveau_gpio_engine *pgpio = &dev_priv->engine.gpio; + struct nv50_gpio_priv *priv = pgpio->priv; + struct nv50_gpio_handler *gpioh; + u32 intr0, intr1 = 0; + u32 hi, lo, ch; - hpd0_bits = nv_rd32(dev, 0xe054); - nv_wr32(dev, 0xe054, hpd0_bits); + intr0 = nv_rd32(dev, 0xe054) & nv_rd32(dev, 0xe050); + if (dev_priv->chipset >= 0x90) + intr1 = nv_rd32(dev, 0xe074) & nv_rd32(dev, 0xe070); - if (dev_priv->chipset >= 0x90) { - hpd1_bits = nv_rd32(dev, 0xe074); - nv_wr32(dev, 0xe074, hpd1_bits); - } + hi = (intr0 & 0x0000ffff) | (intr1 << 16); + lo = (intr0 >> 16) | (intr1 & 0xffff0000); + ch = hi | lo; - spin_lock(&dev_priv->hpd_state.lock); - dev_priv->hpd_state.hpd0_bits |= hpd0_bits; - dev_priv->hpd_state.hpd1_bits |= hpd1_bits; - spin_unlock(&dev_priv->hpd_state.lock); + nv_wr32(dev, 0xe054, intr0); + if (dev_priv->chipset >= 0x90) + nv_wr32(dev, 0xe074, intr1); + + spin_lock(&priv->lock); + list_for_each_entry(gpioh, &priv->handlers, head) { + if (!(ch & (1 << gpioh->gpio->line))) + continue; - queue_work(dev_priv->wq, &dev_priv->hpd_work); + if (gpioh->inhibit) + continue; + gpioh->inhibit = true; + + queue_work(dev_priv->wq, &gpioh->work); + } + spin_unlock(&priv->lock); } -- cgit v1.2.3 From dc1e5c0dbff27c2b5147eaea16c578d2337870c3 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 25 Oct 2010 15:23:59 +1000 Subject: drm/nouveau: simplify gpuobj suspend/resume Reviewed-by: Francisco Jerez Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_drv.c | 14 ++++---- drivers/gpu/drm/nouveau/nouveau_drv.h | 3 +- drivers/gpu/drm/nouveau/nouveau_object.c | 56 ++++++-------------------------- drivers/gpu/drm/nouveau/nv50_instmem.c | 21 ++---------- 4 files changed, 21 insertions(+), 73 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.c b/drivers/gpu/drm/nouveau/nouveau_drv.c index 52f9307d7396..7ff5b4369f03 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.c +++ b/drivers/gpu/drm/nouveau/nouveau_drv.c @@ -222,17 +222,17 @@ nouveau_pci_suspend(struct pci_dev *pdev, pm_message_t pm_state) pfifo->unload_context(dev); pgraph->unload_context(dev); - NV_INFO(dev, "Suspending GPU objects...\n"); - ret = nouveau_gpuobj_suspend(dev); + ret = pinstmem->suspend(dev); if (ret) { NV_ERROR(dev, "... failed: %d\n", ret); goto out_abort; } - ret = pinstmem->suspend(dev); + NV_INFO(dev, "Suspending GPU objects...\n"); + ret = nouveau_gpuobj_suspend(dev); if (ret) { NV_ERROR(dev, "... failed: %d\n", ret); - nouveau_gpuobj_suspend_cleanup(dev); + pinstmem->resume(dev); goto out_abort; } @@ -297,6 +297,9 @@ nouveau_pci_resume(struct pci_dev *pdev) } } + NV_INFO(dev, "Restoring GPU objects...\n"); + nouveau_gpuobj_resume(dev); + NV_INFO(dev, "Reinitialising engines...\n"); engine->instmem.resume(dev); engine->mc.init(dev); @@ -306,9 +309,6 @@ nouveau_pci_resume(struct pci_dev *pdev) engine->crypt.init(dev); engine->fifo.init(dev); - NV_INFO(dev, "Restoring GPU objects...\n"); - nouveau_gpuobj_resume(dev); - nouveau_irq_postinstall(dev); /* Re-write SKIPS, they'll have been lost over the suspend */ diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index 912c9f785222..18a611e1ab80 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -153,7 +153,7 @@ struct nouveau_gpuobj { struct drm_mm_node *im_pramin; struct nouveau_bo *im_backing; - uint32_t *im_backing_suspend; + u32 *suspend; int im_bound; uint32_t flags; @@ -865,7 +865,6 @@ extern int nouveau_gpuobj_early_init(struct drm_device *); extern int nouveau_gpuobj_init(struct drm_device *); extern void nouveau_gpuobj_takedown(struct drm_device *); extern int nouveau_gpuobj_suspend(struct drm_device *dev); -extern void nouveau_gpuobj_suspend_cleanup(struct drm_device *dev); extern void nouveau_gpuobj_resume(struct drm_device *dev); extern int nouveau_gpuobj_class_new(struct drm_device *, u32 class, u32 eng); extern int nouveau_gpuobj_mthd_new(struct drm_device *, u32 class, u32 mthd, diff --git a/drivers/gpu/drm/nouveau/nouveau_object.c b/drivers/gpu/drm/nouveau/nouveau_object.c index 94429553433c..8c5e35cc04df 100644 --- a/drivers/gpu/drm/nouveau/nouveau_object.c +++ b/drivers/gpu/drm/nouveau/nouveau_object.c @@ -934,54 +934,23 @@ nouveau_gpuobj_suspend(struct drm_device *dev) struct nouveau_gpuobj *gpuobj; int i; - if (dev_priv->card_type < NV_50) { - dev_priv->susres.ramin_copy = vmalloc(dev_priv->ramin_rsvd_vram); - if (!dev_priv->susres.ramin_copy) - return -ENOMEM; - - for (i = 0; i < dev_priv->ramin_rsvd_vram; i += 4) - dev_priv->susres.ramin_copy[i/4] = nv_ri32(dev, i); - return 0; - } - list_for_each_entry(gpuobj, &dev_priv->gpuobj_list, list) { - if (!gpuobj->im_backing) + if (gpuobj->cinst != 0xdeadbeef) continue; - gpuobj->im_backing_suspend = vmalloc(gpuobj->size); - if (!gpuobj->im_backing_suspend) { + gpuobj->suspend = vmalloc(gpuobj->size); + if (!gpuobj->suspend) { nouveau_gpuobj_resume(dev); return -ENOMEM; } for (i = 0; i < gpuobj->size; i += 4) - gpuobj->im_backing_suspend[i/4] = nv_ro32(gpuobj, i); + gpuobj->suspend[i/4] = nv_ro32(gpuobj, i); } return 0; } -void -nouveau_gpuobj_suspend_cleanup(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_gpuobj *gpuobj; - - if (dev_priv->card_type < NV_50) { - vfree(dev_priv->susres.ramin_copy); - dev_priv->susres.ramin_copy = NULL; - return; - } - - list_for_each_entry(gpuobj, &dev_priv->gpuobj_list, list) { - if (!gpuobj->im_backing_suspend) - continue; - - vfree(gpuobj->im_backing_suspend); - gpuobj->im_backing_suspend = NULL; - } -} - void nouveau_gpuobj_resume(struct drm_device *dev) { @@ -989,23 +958,18 @@ nouveau_gpuobj_resume(struct drm_device *dev) struct nouveau_gpuobj *gpuobj; int i; - if (dev_priv->card_type < NV_50) { - for (i = 0; i < dev_priv->ramin_rsvd_vram; i += 4) - nv_wi32(dev, i, dev_priv->susres.ramin_copy[i/4]); - nouveau_gpuobj_suspend_cleanup(dev); - return; - } - list_for_each_entry(gpuobj, &dev_priv->gpuobj_list, list) { - if (!gpuobj->im_backing_suspend) + if (!gpuobj->suspend) continue; for (i = 0; i < gpuobj->size; i += 4) - nv_wo32(gpuobj, i, gpuobj->im_backing_suspend[i/4]); - dev_priv->engine.instmem.flush(dev); + nv_wo32(gpuobj, i, gpuobj->suspend[i/4]); + + vfree(gpuobj->suspend); + gpuobj->suspend = NULL; } - nouveau_gpuobj_suspend_cleanup(dev); + dev_priv->engine.instmem.flush(dev); } int nouveau_ioctl_grobj_alloc(struct drm_device *dev, void *data, diff --git a/drivers/gpu/drm/nouveau/nv50_instmem.c b/drivers/gpu/drm/nouveau/nv50_instmem.c index 2c98eb176d64..1640c12d8b3a 100644 --- a/drivers/gpu/drm/nouveau/nv50_instmem.c +++ b/drivers/gpu/drm/nouveau/nv50_instmem.c @@ -276,16 +276,8 @@ int nv50_instmem_suspend(struct drm_device *dev) { struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_channel *chan = dev_priv->channels.ptr[0]; - struct nouveau_gpuobj *ramin = chan->ramin; - int i; - ramin->im_backing_suspend = vmalloc(ramin->size); - if (!ramin->im_backing_suspend) - return -ENOMEM; - - for (i = 0; i < ramin->size; i += 4) - ramin->im_backing_suspend[i/4] = nv_ri32(dev, i); + dev_priv->ramin_available = false; return 0; } @@ -295,17 +287,8 @@ nv50_instmem_resume(struct drm_device *dev) struct drm_nouveau_private *dev_priv = dev->dev_private; struct nv50_instmem_priv *priv = dev_priv->engine.instmem.priv; struct nouveau_channel *chan = dev_priv->channels.ptr[0]; - struct nouveau_gpuobj *ramin = chan->ramin; int i; - dev_priv->ramin_available = false; - dev_priv->ramin_base = ~0; - for (i = 0; i < ramin->size; i += 4) - nv_wo32(ramin, i, ramin->im_backing_suspend[i/4]); - dev_priv->ramin_available = true; - vfree(ramin->im_backing_suspend); - ramin->im_backing_suspend = NULL; - /* Poke the relevant regs, and pray it works :) */ nv_wr32(dev, NV50_PUNK_BAR_CFG_BASE, (chan->ramin->vinst >> 12)); nv_wr32(dev, NV50_PUNK_UNK1710, 0); @@ -318,6 +301,8 @@ nv50_instmem_resume(struct drm_device *dev) for (i = 0; i < 8; i++) nv_wr32(dev, 0x1900 + (i*4), 0); + + dev_priv->ramin_available = true; } int -- cgit v1.2.3 From e41115d0ad5c40a7ea4d85b1c77b4c02185a5581 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 1 Nov 2010 11:45:02 +1000 Subject: drm/nouveau: rework gpu-specific instmem interfaces Reviewed-by: Francisco Jerez Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_drv.h | 44 +++++------ drivers/gpu/drm/nouveau/nouveau_object.c | 112 +++++++++----------------- drivers/gpu/drm/nouveau/nouveau_state.c | 56 ++++++------- drivers/gpu/drm/nouveau/nv04_instmem.c | 50 ++++++++---- drivers/gpu/drm/nouveau/nv50_instmem.c | 130 +++++++++++++++++-------------- drivers/gpu/drm/nouveau/nvc0_instmem.c | 121 +++++++++++++++++----------- 6 files changed, 270 insertions(+), 243 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index 18a611e1ab80..822cd40b3eb4 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -146,15 +146,16 @@ enum nouveau_flags { #define NVOBJ_FLAG_ZERO_ALLOC (1 << 1) #define NVOBJ_FLAG_ZERO_FREE (1 << 2) + +#define NVOBJ_CINST_GLOBAL 0xdeadbeef + struct nouveau_gpuobj { struct drm_device *dev; struct kref refcount; struct list_head list; - struct drm_mm_node *im_pramin; - struct nouveau_bo *im_backing; + void *node; u32 *suspend; - int im_bound; uint32_t flags; @@ -288,11 +289,11 @@ struct nouveau_instmem_engine { int (*suspend)(struct drm_device *dev); void (*resume)(struct drm_device *dev); - int (*populate)(struct drm_device *, struct nouveau_gpuobj *, - u32 *size, u32 align); - void (*clear)(struct drm_device *, struct nouveau_gpuobj *); - int (*bind)(struct drm_device *, struct nouveau_gpuobj *); - int (*unbind)(struct drm_device *, struct nouveau_gpuobj *); + int (*get)(struct nouveau_gpuobj *, u32 size, u32 align); + void (*put)(struct nouveau_gpuobj *); + int (*map)(struct nouveau_gpuobj *); + void (*unmap)(struct nouveau_gpuobj *); + void (*flush)(struct drm_device *); }; @@ -1182,11 +1183,10 @@ extern int nv04_instmem_init(struct drm_device *); extern void nv04_instmem_takedown(struct drm_device *); extern int nv04_instmem_suspend(struct drm_device *); extern void nv04_instmem_resume(struct drm_device *); -extern int nv04_instmem_populate(struct drm_device *, struct nouveau_gpuobj *, - u32 *size, u32 align); -extern void nv04_instmem_clear(struct drm_device *, struct nouveau_gpuobj *); -extern int nv04_instmem_bind(struct drm_device *, struct nouveau_gpuobj *); -extern int nv04_instmem_unbind(struct drm_device *, struct nouveau_gpuobj *); +extern int nv04_instmem_get(struct nouveau_gpuobj *, u32 size, u32 align); +extern void nv04_instmem_put(struct nouveau_gpuobj *); +extern int nv04_instmem_map(struct nouveau_gpuobj *); +extern void nv04_instmem_unmap(struct nouveau_gpuobj *); extern void nv04_instmem_flush(struct drm_device *); /* nv50_instmem.c */ @@ -1194,11 +1194,10 @@ extern int nv50_instmem_init(struct drm_device *); extern void nv50_instmem_takedown(struct drm_device *); extern int nv50_instmem_suspend(struct drm_device *); extern void nv50_instmem_resume(struct drm_device *); -extern int nv50_instmem_populate(struct drm_device *, struct nouveau_gpuobj *, - u32 *size, u32 align); -extern void nv50_instmem_clear(struct drm_device *, struct nouveau_gpuobj *); -extern int nv50_instmem_bind(struct drm_device *, struct nouveau_gpuobj *); -extern int nv50_instmem_unbind(struct drm_device *, struct nouveau_gpuobj *); +extern int nv50_instmem_get(struct nouveau_gpuobj *, u32 size, u32 align); +extern void nv50_instmem_put(struct nouveau_gpuobj *); +extern int nv50_instmem_map(struct nouveau_gpuobj *); +extern void nv50_instmem_unmap(struct nouveau_gpuobj *); extern void nv50_instmem_flush(struct drm_device *); extern void nv84_instmem_flush(struct drm_device *); extern void nv50_vm_flush(struct drm_device *, int engine); @@ -1208,11 +1207,10 @@ extern int nvc0_instmem_init(struct drm_device *); extern void nvc0_instmem_takedown(struct drm_device *); extern int nvc0_instmem_suspend(struct drm_device *); extern void nvc0_instmem_resume(struct drm_device *); -extern int nvc0_instmem_populate(struct drm_device *, struct nouveau_gpuobj *, - u32 *size, u32 align); -extern void nvc0_instmem_clear(struct drm_device *, struct nouveau_gpuobj *); -extern int nvc0_instmem_bind(struct drm_device *, struct nouveau_gpuobj *); -extern int nvc0_instmem_unbind(struct drm_device *, struct nouveau_gpuobj *); +extern int nvc0_instmem_get(struct nouveau_gpuobj *, u32 size, u32 align); +extern void nvc0_instmem_put(struct nouveau_gpuobj *); +extern int nvc0_instmem_map(struct nouveau_gpuobj *); +extern void nvc0_instmem_unmap(struct nouveau_gpuobj *); extern void nvc0_instmem_flush(struct drm_device *); /* nv04_mc.c */ diff --git a/drivers/gpu/drm/nouveau/nouveau_object.c b/drivers/gpu/drm/nouveau/nouveau_object.c index 8c5e35cc04df..e8c74de905ec 100644 --- a/drivers/gpu/drm/nouveau/nouveau_object.c +++ b/drivers/gpu/drm/nouveau/nouveau_object.c @@ -168,17 +168,14 @@ nouveau_gpuobj_new(struct drm_device *dev, struct nouveau_channel *chan, struct nouveau_gpuobj **gpuobj_ret) { struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_engine *engine = &dev_priv->engine; + struct nouveau_instmem_engine *instmem = &dev_priv->engine.instmem; struct nouveau_gpuobj *gpuobj; struct drm_mm_node *ramin = NULL; - int ret; + int ret, i; NV_DEBUG(dev, "ch%d size=%u align=%d flags=0x%08x\n", chan ? chan->id : -1, size, align, flags); - if (!dev_priv || !gpuobj_ret || *gpuobj_ret != NULL) - return -EINVAL; - gpuobj = kzalloc(sizeof(*gpuobj), GFP_KERNEL); if (!gpuobj) return -ENOMEM; @@ -193,88 +190,45 @@ nouveau_gpuobj_new(struct drm_device *dev, struct nouveau_channel *chan, spin_unlock(&dev_priv->ramin_lock); if (chan) { - NV_DEBUG(dev, "channel heap\n"); - ramin = drm_mm_search_free(&chan->ramin_heap, size, align, 0); if (ramin) ramin = drm_mm_get_block(ramin, size, align); - if (!ramin) { nouveau_gpuobj_ref(NULL, &gpuobj); return -ENOMEM; } - } else { - NV_DEBUG(dev, "global heap\n"); - - /* allocate backing pages, sets vinst */ - ret = engine->instmem.populate(dev, gpuobj, &size, align); - if (ret) { - nouveau_gpuobj_ref(NULL, &gpuobj); - return ret; - } - /* try and get aperture space */ - do { - if (drm_mm_pre_get(&dev_priv->ramin_heap)) - return -ENOMEM; - - spin_lock(&dev_priv->ramin_lock); - ramin = drm_mm_search_free(&dev_priv->ramin_heap, size, - align, 0); - if (ramin == NULL) { - spin_unlock(&dev_priv->ramin_lock); - nouveau_gpuobj_ref(NULL, &gpuobj); - return -ENOMEM; - } - - ramin = drm_mm_get_block_atomic(ramin, size, align); - spin_unlock(&dev_priv->ramin_lock); - } while (ramin == NULL); + gpuobj->pinst = chan->ramin->pinst; + if (gpuobj->pinst != ~0) + gpuobj->pinst += ramin->start; - /* on nv50 it's ok to fail, we have a fallback path */ - if (!ramin && dev_priv->card_type < NV_50) { - nouveau_gpuobj_ref(NULL, &gpuobj); - return -ENOMEM; - } - } + if (dev_priv->card_type < NV_50) + gpuobj->cinst = gpuobj->pinst; + else + gpuobj->cinst = ramin->start; - /* if we got a chunk of the aperture, map pages into it */ - gpuobj->im_pramin = ramin; - if (!chan && gpuobj->im_pramin && dev_priv->ramin_available) { - ret = engine->instmem.bind(dev, gpuobj); + gpuobj->vinst = ramin->start + chan->ramin->vinst; + gpuobj->node = ramin; + } else { + ret = instmem->get(gpuobj, size, align); if (ret) { nouveau_gpuobj_ref(NULL, &gpuobj); return ret; } - } - - /* calculate the various different addresses for the object */ - if (chan) { - gpuobj->pinst = chan->ramin->pinst; - if (gpuobj->pinst != ~0) - gpuobj->pinst += gpuobj->im_pramin->start; - if (dev_priv->card_type < NV_50) { - gpuobj->cinst = gpuobj->pinst; - } else { - gpuobj->cinst = gpuobj->im_pramin->start; - gpuobj->vinst = gpuobj->im_pramin->start + - chan->ramin->vinst; - } - } else { - if (gpuobj->im_pramin) - gpuobj->pinst = gpuobj->im_pramin->start; - else + ret = -ENOSYS; + if (dev_priv->ramin_available) + ret = instmem->map(gpuobj); + if (ret) gpuobj->pinst = ~0; - gpuobj->cinst = 0xdeadbeef; + + gpuobj->cinst = NVOBJ_CINST_GLOBAL; } if (gpuobj->flags & NVOBJ_FLAG_ZERO_ALLOC) { - int i; - for (i = 0; i < gpuobj->size; i += 4) nv_wo32(gpuobj, i, 0); - engine->instmem.flush(dev); + instmem->flush(dev); } @@ -326,26 +280,34 @@ nouveau_gpuobj_del(struct kref *ref) container_of(ref, struct nouveau_gpuobj, refcount); struct drm_device *dev = gpuobj->dev; struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_engine *engine = &dev_priv->engine; + struct nouveau_instmem_engine *instmem = &dev_priv->engine.instmem; int i; NV_DEBUG(dev, "gpuobj %p\n", gpuobj); - if (gpuobj->im_pramin && (gpuobj->flags & NVOBJ_FLAG_ZERO_FREE)) { + if (gpuobj->node && (gpuobj->flags & NVOBJ_FLAG_ZERO_FREE)) { for (i = 0; i < gpuobj->size; i += 4) nv_wo32(gpuobj, i, 0); - engine->instmem.flush(dev); + instmem->flush(dev); } if (gpuobj->dtor) gpuobj->dtor(dev, gpuobj); - if (gpuobj->im_backing) - engine->instmem.clear(dev, gpuobj); + if (gpuobj->cinst == NVOBJ_CINST_GLOBAL) { + if (gpuobj->node) { + instmem->unmap(gpuobj); + instmem->put(gpuobj); + } + } else { + if (gpuobj->node) { + spin_lock(&dev_priv->ramin_lock); + drm_mm_put_block(gpuobj->node); + spin_unlock(&dev_priv->ramin_lock); + } + } spin_lock(&dev_priv->ramin_lock); - if (gpuobj->im_pramin) - drm_mm_put_block(gpuobj->im_pramin); list_del(&gpuobj->list); spin_unlock(&dev_priv->ramin_lock); @@ -385,7 +347,7 @@ nouveau_gpuobj_new_fake(struct drm_device *dev, u32 pinst, u64 vinst, kref_init(&gpuobj->refcount); gpuobj->size = size; gpuobj->pinst = pinst; - gpuobj->cinst = 0xdeadbeef; + gpuobj->cinst = NVOBJ_CINST_GLOBAL; gpuobj->vinst = vinst; if (gpuobj->flags & NVOBJ_FLAG_ZERO_ALLOC) { @@ -935,7 +897,7 @@ nouveau_gpuobj_suspend(struct drm_device *dev) int i; list_for_each_entry(gpuobj, &dev_priv->gpuobj_list, list) { - if (gpuobj->cinst != 0xdeadbeef) + if (gpuobj->cinst != NVOBJ_CINST_GLOBAL) continue; gpuobj->suspend = vmalloc(gpuobj->size); diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c index b26b34c419cb..b42e29d1935e 100644 --- a/drivers/gpu/drm/nouveau/nouveau_state.c +++ b/drivers/gpu/drm/nouveau/nouveau_state.c @@ -53,10 +53,10 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->instmem.takedown = nv04_instmem_takedown; engine->instmem.suspend = nv04_instmem_suspend; engine->instmem.resume = nv04_instmem_resume; - engine->instmem.populate = nv04_instmem_populate; - engine->instmem.clear = nv04_instmem_clear; - engine->instmem.bind = nv04_instmem_bind; - engine->instmem.unbind = nv04_instmem_unbind; + engine->instmem.get = nv04_instmem_get; + engine->instmem.put = nv04_instmem_put; + engine->instmem.map = nv04_instmem_map; + engine->instmem.unmap = nv04_instmem_unmap; engine->instmem.flush = nv04_instmem_flush; engine->mc.init = nv04_mc_init; engine->mc.takedown = nv04_mc_takedown; @@ -106,10 +106,10 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->instmem.takedown = nv04_instmem_takedown; engine->instmem.suspend = nv04_instmem_suspend; engine->instmem.resume = nv04_instmem_resume; - engine->instmem.populate = nv04_instmem_populate; - engine->instmem.clear = nv04_instmem_clear; - engine->instmem.bind = nv04_instmem_bind; - engine->instmem.unbind = nv04_instmem_unbind; + engine->instmem.get = nv04_instmem_get; + engine->instmem.put = nv04_instmem_put; + engine->instmem.map = nv04_instmem_map; + engine->instmem.unmap = nv04_instmem_unmap; engine->instmem.flush = nv04_instmem_flush; engine->mc.init = nv04_mc_init; engine->mc.takedown = nv04_mc_takedown; @@ -163,10 +163,10 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->instmem.takedown = nv04_instmem_takedown; engine->instmem.suspend = nv04_instmem_suspend; engine->instmem.resume = nv04_instmem_resume; - engine->instmem.populate = nv04_instmem_populate; - engine->instmem.clear = nv04_instmem_clear; - engine->instmem.bind = nv04_instmem_bind; - engine->instmem.unbind = nv04_instmem_unbind; + engine->instmem.get = nv04_instmem_get; + engine->instmem.put = nv04_instmem_put; + engine->instmem.map = nv04_instmem_map; + engine->instmem.unmap = nv04_instmem_unmap; engine->instmem.flush = nv04_instmem_flush; engine->mc.init = nv04_mc_init; engine->mc.takedown = nv04_mc_takedown; @@ -220,10 +220,10 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->instmem.takedown = nv04_instmem_takedown; engine->instmem.suspend = nv04_instmem_suspend; engine->instmem.resume = nv04_instmem_resume; - engine->instmem.populate = nv04_instmem_populate; - engine->instmem.clear = nv04_instmem_clear; - engine->instmem.bind = nv04_instmem_bind; - engine->instmem.unbind = nv04_instmem_unbind; + engine->instmem.get = nv04_instmem_get; + engine->instmem.put = nv04_instmem_put; + engine->instmem.map = nv04_instmem_map; + engine->instmem.unmap = nv04_instmem_unmap; engine->instmem.flush = nv04_instmem_flush; engine->mc.init = nv04_mc_init; engine->mc.takedown = nv04_mc_takedown; @@ -280,10 +280,10 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->instmem.takedown = nv04_instmem_takedown; engine->instmem.suspend = nv04_instmem_suspend; engine->instmem.resume = nv04_instmem_resume; - engine->instmem.populate = nv04_instmem_populate; - engine->instmem.clear = nv04_instmem_clear; - engine->instmem.bind = nv04_instmem_bind; - engine->instmem.unbind = nv04_instmem_unbind; + engine->instmem.get = nv04_instmem_get; + engine->instmem.put = nv04_instmem_put; + engine->instmem.map = nv04_instmem_map; + engine->instmem.unmap = nv04_instmem_unmap; engine->instmem.flush = nv04_instmem_flush; engine->mc.init = nv40_mc_init; engine->mc.takedown = nv40_mc_takedown; @@ -343,10 +343,10 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->instmem.takedown = nv50_instmem_takedown; engine->instmem.suspend = nv50_instmem_suspend; engine->instmem.resume = nv50_instmem_resume; - engine->instmem.populate = nv50_instmem_populate; - engine->instmem.clear = nv50_instmem_clear; - engine->instmem.bind = nv50_instmem_bind; - engine->instmem.unbind = nv50_instmem_unbind; + engine->instmem.get = nv50_instmem_get; + engine->instmem.put = nv50_instmem_put; + engine->instmem.map = nv50_instmem_map; + engine->instmem.unmap = nv50_instmem_unmap; if (dev_priv->chipset == 0x50) engine->instmem.flush = nv50_instmem_flush; else @@ -449,10 +449,10 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->instmem.takedown = nvc0_instmem_takedown; engine->instmem.suspend = nvc0_instmem_suspend; engine->instmem.resume = nvc0_instmem_resume; - engine->instmem.populate = nvc0_instmem_populate; - engine->instmem.clear = nvc0_instmem_clear; - engine->instmem.bind = nvc0_instmem_bind; - engine->instmem.unbind = nvc0_instmem_unbind; + engine->instmem.get = nvc0_instmem_get; + engine->instmem.put = nvc0_instmem_put; + engine->instmem.map = nvc0_instmem_map; + engine->instmem.unmap = nvc0_instmem_unmap; engine->instmem.flush = nvc0_instmem_flush; engine->mc.init = nv50_mc_init; engine->mc.takedown = nv50_mc_takedown; diff --git a/drivers/gpu/drm/nouveau/nv04_instmem.c b/drivers/gpu/drm/nouveau/nv04_instmem.c index 554e55d0ec48..b8e3edb5c063 100644 --- a/drivers/gpu/drm/nouveau/nv04_instmem.c +++ b/drivers/gpu/drm/nouveau/nv04_instmem.c @@ -98,42 +98,66 @@ nv04_instmem_takedown(struct drm_device *dev) } int -nv04_instmem_populate(struct drm_device *dev, struct nouveau_gpuobj *gpuobj, - u32 *size, u32 align) +nv04_instmem_suspend(struct drm_device *dev) { return 0; } void -nv04_instmem_clear(struct drm_device *dev, struct nouveau_gpuobj *gpuobj) -{ -} - -int -nv04_instmem_bind(struct drm_device *dev, struct nouveau_gpuobj *gpuobj) +nv04_instmem_resume(struct drm_device *dev) { - return 0; } int -nv04_instmem_unbind(struct drm_device *dev, struct nouveau_gpuobj *gpuobj) +nv04_instmem_get(struct nouveau_gpuobj *gpuobj, u32 size, u32 align) { + struct drm_nouveau_private *dev_priv = gpuobj->dev->dev_private; + struct drm_mm_node *ramin = NULL; + + do { + if (drm_mm_pre_get(&dev_priv->ramin_heap)) + return -ENOMEM; + + spin_lock(&dev_priv->ramin_lock); + ramin = drm_mm_search_free(&dev_priv->ramin_heap, size, align, 0); + if (ramin == NULL) { + spin_unlock(&dev_priv->ramin_lock); + return -ENOMEM; + } + + ramin = drm_mm_get_block_atomic(ramin, size, align); + spin_unlock(&dev_priv->ramin_lock); + } while (ramin == NULL); + + gpuobj->node = ramin; + gpuobj->vinst = ramin->start; return 0; } void -nv04_instmem_flush(struct drm_device *dev) +nv04_instmem_put(struct nouveau_gpuobj *gpuobj) { + struct drm_nouveau_private *dev_priv = gpuobj->dev->dev_private; + + spin_lock(&dev_priv->ramin_lock); + drm_mm_put_block(gpuobj->node); + gpuobj->node = NULL; + spin_unlock(&dev_priv->ramin_lock); } int -nv04_instmem_suspend(struct drm_device *dev) +nv04_instmem_map(struct nouveau_gpuobj *gpuobj) { + gpuobj->pinst = gpuobj->vinst; return 0; } void -nv04_instmem_resume(struct drm_device *dev) +nv04_instmem_unmap(struct nouveau_gpuobj *gpuobj) { } +void +nv04_instmem_flush(struct drm_device *dev) +{ +} diff --git a/drivers/gpu/drm/nouveau/nv50_instmem.c b/drivers/gpu/drm/nouveau/nv50_instmem.c index 1640c12d8b3a..87160952a30b 100644 --- a/drivers/gpu/drm/nouveau/nv50_instmem.c +++ b/drivers/gpu/drm/nouveau/nv50_instmem.c @@ -157,10 +157,7 @@ nv50_instmem_init(struct drm_device *dev) nv_wo32(priv->pramin_bar, 0x10, 0x00000000); nv_wo32(priv->pramin_bar, 0x14, 0x00000000); - /* map channel into PRAMIN, gpuobj didn't do it for us */ - ret = nv50_instmem_bind(dev, chan->ramin); - if (ret) - return ret; + nv50_instmem_map(chan->ramin); /* poke regs... */ nv_wr32(dev, 0x001704, 0x00000000 | (chan->ramin->vinst >> 12)); @@ -305,72 +302,91 @@ nv50_instmem_resume(struct drm_device *dev) dev_priv->ramin_available = true; } +struct nv50_gpuobj_node { + struct nouveau_bo *vram; + struct drm_mm_node *ramin; + u32 align; +}; + + int -nv50_instmem_populate(struct drm_device *dev, struct nouveau_gpuobj *gpuobj, - u32 *size, u32 align) +nv50_instmem_get(struct nouveau_gpuobj *gpuobj, u32 size, u32 align) { + struct drm_device *dev = gpuobj->dev; + struct nv50_gpuobj_node *node = NULL; int ret; - if (gpuobj->im_backing) - return -EINVAL; - - *size = ALIGN(*size, 4096); - if (*size == 0) - return -EINVAL; + node = kzalloc(sizeof(*node), GFP_KERNEL); + if (!node) + return -ENOMEM; + node->align = align; - ret = nouveau_bo_new(dev, NULL, *size, align, TTM_PL_FLAG_VRAM, - 0, 0x0000, true, false, &gpuobj->im_backing); + ret = nouveau_bo_new(dev, NULL, size, align, TTM_PL_FLAG_VRAM, + 0, 0x0000, true, false, &node->vram); if (ret) { NV_ERROR(dev, "error getting PRAMIN backing pages: %d\n", ret); return ret; } - ret = nouveau_bo_pin(gpuobj->im_backing, TTM_PL_FLAG_VRAM); + ret = nouveau_bo_pin(node->vram, TTM_PL_FLAG_VRAM); if (ret) { NV_ERROR(dev, "error pinning PRAMIN backing VRAM: %d\n", ret); - nouveau_bo_ref(NULL, &gpuobj->im_backing); + nouveau_bo_ref(NULL, &node->vram); return ret; } - gpuobj->vinst = gpuobj->im_backing->bo.mem.start << PAGE_SHIFT; + gpuobj->vinst = node->vram->bo.mem.start << PAGE_SHIFT; + gpuobj->size = node->vram->bo.mem.num_pages << PAGE_SHIFT; + gpuobj->node = node; return 0; } void -nv50_instmem_clear(struct drm_device *dev, struct nouveau_gpuobj *gpuobj) +nv50_instmem_put(struct nouveau_gpuobj *gpuobj) { - struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nv50_gpuobj_node *node; - if (gpuobj && gpuobj->im_backing) { - if (gpuobj->im_bound) - dev_priv->engine.instmem.unbind(dev, gpuobj); - nouveau_bo_unpin(gpuobj->im_backing); - nouveau_bo_ref(NULL, &gpuobj->im_backing); - gpuobj->im_backing = NULL; - } + node = gpuobj->node; + gpuobj->node = NULL; + + nouveau_bo_unpin(node->vram); + nouveau_bo_ref(NULL, &node->vram); + kfree(node); } int -nv50_instmem_bind(struct drm_device *dev, struct nouveau_gpuobj *gpuobj) +nv50_instmem_map(struct nouveau_gpuobj *gpuobj) { - struct drm_nouveau_private *dev_priv = dev->dev_private; + struct drm_nouveau_private *dev_priv = gpuobj->dev->dev_private; struct nv50_instmem_priv *priv = dev_priv->engine.instmem.priv; - struct nouveau_gpuobj *pramin_pt = priv->pramin_pt; - uint32_t pte, pte_end; - uint64_t vram; - - if (!gpuobj->im_backing || !gpuobj->im_pramin || gpuobj->im_bound) - return -EINVAL; + struct nv50_gpuobj_node *node = gpuobj->node; + struct drm_device *dev = gpuobj->dev; + struct drm_mm_node *ramin = NULL; + u32 pte, pte_end; + u64 vram; + + do { + if (drm_mm_pre_get(&dev_priv->ramin_heap)) + return -ENOMEM; + + spin_lock(&dev_priv->ramin_lock); + ramin = drm_mm_search_free(&dev_priv->ramin_heap, gpuobj->size, + node->align, 0); + if (ramin == NULL) { + spin_unlock(&dev_priv->ramin_lock); + return -ENOMEM; + } - NV_DEBUG(dev, "st=0x%lx sz=0x%lx\n", - gpuobj->im_pramin->start, gpuobj->im_pramin->size); + ramin = drm_mm_get_block_atomic(ramin, gpuobj->size, node->align); + spin_unlock(&dev_priv->ramin_lock); + } while (ramin == NULL); - pte = (gpuobj->im_pramin->start >> 12) << 1; - pte_end = ((gpuobj->im_pramin->size >> 12) << 1) + pte; + pte = (ramin->start >> 12) << 1; + pte_end = ((ramin->size >> 12) << 1) + pte; vram = gpuobj->vinst; NV_DEBUG(dev, "pramin=0x%lx, pte=%d, pte_end=%d\n", - gpuobj->im_pramin->start, pte, pte_end); + ramin->start, pte, pte_end); NV_DEBUG(dev, "first vram page: 0x%010llx\n", gpuobj->vinst); vram |= 1; @@ -380,8 +396,8 @@ nv50_instmem_bind(struct drm_device *dev, struct nouveau_gpuobj *gpuobj) } while (pte < pte_end) { - nv_wo32(pramin_pt, (pte * 4) + 0, lower_32_bits(vram)); - nv_wo32(pramin_pt, (pte * 4) + 4, upper_32_bits(vram)); + nv_wo32(priv->pramin_pt, (pte * 4) + 0, lower_32_bits(vram)); + nv_wo32(priv->pramin_pt, (pte * 4) + 4, upper_32_bits(vram)); vram += 0x1000; pte += 2; } @@ -389,36 +405,36 @@ nv50_instmem_bind(struct drm_device *dev, struct nouveau_gpuobj *gpuobj) nv50_vm_flush(dev, 6); - gpuobj->im_bound = 1; + node->ramin = ramin; + gpuobj->pinst = ramin->start; return 0; } -int -nv50_instmem_unbind(struct drm_device *dev, struct nouveau_gpuobj *gpuobj) +void +nv50_instmem_unmap(struct nouveau_gpuobj *gpuobj) { - struct drm_nouveau_private *dev_priv = dev->dev_private; + struct drm_nouveau_private *dev_priv = gpuobj->dev->dev_private; struct nv50_instmem_priv *priv = dev_priv->engine.instmem.priv; - uint32_t pte, pte_end; - - if (gpuobj->im_bound == 0) - return -EINVAL; + struct nv50_gpuobj_node *node = gpuobj->node; + u32 pte, pte_end; - /* can happen during late takedown */ - if (unlikely(!dev_priv->ramin_available)) - return 0; + if (!node->ramin || !dev_priv->ramin_available) + return; - pte = (gpuobj->im_pramin->start >> 12) << 1; - pte_end = ((gpuobj->im_pramin->size >> 12) << 1) + pte; + pte = (node->ramin->start >> 12) << 1; + pte_end = ((node->ramin->size >> 12) << 1) + pte; while (pte < pte_end) { nv_wo32(priv->pramin_pt, (pte * 4) + 0, 0x00000000); nv_wo32(priv->pramin_pt, (pte * 4) + 4, 0x00000000); pte += 2; } - dev_priv->engine.instmem.flush(dev); + dev_priv->engine.instmem.flush(gpuobj->dev); - gpuobj->im_bound = 0; - return 0; + spin_lock(&dev_priv->ramin_lock); + drm_mm_put_block(node->ramin); + node->ramin = NULL; + spin_unlock(&dev_priv->ramin_lock); } void diff --git a/drivers/gpu/drm/nouveau/nvc0_instmem.c b/drivers/gpu/drm/nouveau/nvc0_instmem.c index 7b4e71f5c274..39232085193d 100644 --- a/drivers/gpu/drm/nouveau/nvc0_instmem.c +++ b/drivers/gpu/drm/nouveau/nvc0_instmem.c @@ -26,67 +26,89 @@ #include "nouveau_drv.h" +struct nvc0_gpuobj_node { + struct nouveau_bo *vram; + struct drm_mm_node *ramin; + u32 align; +}; + int -nvc0_instmem_populate(struct drm_device *dev, struct nouveau_gpuobj *gpuobj, - u32 *size, u32 align) +nvc0_instmem_get(struct nouveau_gpuobj *gpuobj, u32 size, u32 align) { + struct drm_device *dev = gpuobj->dev; + struct nvc0_gpuobj_node *node = NULL; int ret; - *size = ALIGN(*size, 4096); - if (*size == 0) - return -EINVAL; + node = kzalloc(sizeof(*node), GFP_KERNEL); + if (!node) + return -ENOMEM; + node->align = align; - ret = nouveau_bo_new(dev, NULL, *size, align, TTM_PL_FLAG_VRAM, - 0, 0x0000, true, false, &gpuobj->im_backing); + ret = nouveau_bo_new(dev, NULL, size, align, TTM_PL_FLAG_VRAM, + 0, 0x0000, true, false, &node->vram); if (ret) { NV_ERROR(dev, "error getting PRAMIN backing pages: %d\n", ret); return ret; } - ret = nouveau_bo_pin(gpuobj->im_backing, TTM_PL_FLAG_VRAM); + ret = nouveau_bo_pin(node->vram, TTM_PL_FLAG_VRAM); if (ret) { NV_ERROR(dev, "error pinning PRAMIN backing VRAM: %d\n", ret); - nouveau_bo_ref(NULL, &gpuobj->im_backing); + nouveau_bo_ref(NULL, &node->vram); return ret; } - gpuobj->vinst = gpuobj->im_backing->bo.mem.start << PAGE_SHIFT; + gpuobj->vinst = node->vram->bo.mem.start << PAGE_SHIFT; + gpuobj->size = node->vram->bo.mem.num_pages << PAGE_SHIFT; + gpuobj->node = node; return 0; } void -nvc0_instmem_clear(struct drm_device *dev, struct nouveau_gpuobj *gpuobj) +nvc0_instmem_put(struct nouveau_gpuobj *gpuobj) { - struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nvc0_gpuobj_node *node; - if (gpuobj && gpuobj->im_backing) { - if (gpuobj->im_bound) - dev_priv->engine.instmem.unbind(dev, gpuobj); - nouveau_bo_unpin(gpuobj->im_backing); - nouveau_bo_ref(NULL, &gpuobj->im_backing); - gpuobj->im_backing = NULL; - } + node = gpuobj->node; + gpuobj->node = NULL; + + nouveau_bo_unpin(node->vram); + nouveau_bo_ref(NULL, &node->vram); + kfree(node); } int -nvc0_instmem_bind(struct drm_device *dev, struct nouveau_gpuobj *gpuobj) +nvc0_instmem_map(struct nouveau_gpuobj *gpuobj) { - struct drm_nouveau_private *dev_priv = dev->dev_private; - uint32_t pte, pte_end; - uint64_t vram; - - if (!gpuobj->im_backing || !gpuobj->im_pramin || gpuobj->im_bound) - return -EINVAL; - - NV_DEBUG(dev, "st=0x%lx sz=0x%lx\n", - gpuobj->im_pramin->start, gpuobj->im_pramin->size); - - pte = gpuobj->im_pramin->start >> 12; - pte_end = (gpuobj->im_pramin->size >> 12) + pte; + struct drm_nouveau_private *dev_priv = gpuobj->dev->dev_private; + struct nvc0_gpuobj_node *node = gpuobj->node; + struct drm_device *dev = gpuobj->dev; + struct drm_mm_node *ramin = NULL; + u32 pte, pte_end; + u64 vram; + + do { + if (drm_mm_pre_get(&dev_priv->ramin_heap)) + return -ENOMEM; + + spin_lock(&dev_priv->ramin_lock); + ramin = drm_mm_search_free(&dev_priv->ramin_heap, gpuobj->size, + node->align, 0); + if (ramin == NULL) { + spin_unlock(&dev_priv->ramin_lock); + return -ENOMEM; + } + + ramin = drm_mm_get_block_atomic(ramin, gpuobj->size, node->align); + spin_unlock(&dev_priv->ramin_lock); + } while (ramin == NULL); + + pte = (ramin->start >> 12) << 1; + pte_end = ((ramin->size >> 12) << 1) + pte; vram = gpuobj->vinst; NV_DEBUG(dev, "pramin=0x%lx, pte=%d, pte_end=%d\n", - gpuobj->im_pramin->start, pte, pte_end); + ramin->start, pte, pte_end); NV_DEBUG(dev, "first vram page: 0x%010llx\n", gpuobj->vinst); while (pte < pte_end) { @@ -103,30 +125,35 @@ nvc0_instmem_bind(struct drm_device *dev, struct nouveau_gpuobj *gpuobj) nv_wr32(dev, 0x100cbc, 0x80000005); } - gpuobj->im_bound = 1; + node->ramin = ramin; + gpuobj->pinst = ramin->start; return 0; } -int -nvc0_instmem_unbind(struct drm_device *dev, struct nouveau_gpuobj *gpuobj) +void +nvc0_instmem_unmap(struct nouveau_gpuobj *gpuobj) { - struct drm_nouveau_private *dev_priv = dev->dev_private; - uint32_t pte, pte_end; + struct drm_nouveau_private *dev_priv = gpuobj->dev->dev_private; + struct nvc0_gpuobj_node *node = gpuobj->node; + u32 pte, pte_end; - if (gpuobj->im_bound == 0) - return -EINVAL; + if (!node->ramin || !dev_priv->ramin_available) + return; + + pte = (node->ramin->start >> 12) << 1; + pte_end = ((node->ramin->size >> 12) << 1) + pte; - pte = gpuobj->im_pramin->start >> 12; - pte_end = (gpuobj->im_pramin->size >> 12) + pte; while (pte < pte_end) { - nv_wr32(dev, 0x702000 + (pte * 8), 0); - nv_wr32(dev, 0x702004 + (pte * 8), 0); + nv_wr32(gpuobj->dev, 0x702000 + (pte * 8), 0); + nv_wr32(gpuobj->dev, 0x702004 + (pte * 8), 0); pte++; } - dev_priv->engine.instmem.flush(dev); + dev_priv->engine.instmem.flush(gpuobj->dev); - gpuobj->im_bound = 0; - return 0; + spin_lock(&dev_priv->ramin_lock); + drm_mm_put_block(node->ramin); + node->ramin = NULL; + spin_unlock(&dev_priv->ramin_lock); } void -- cgit v1.2.3 From 20f63afe988a25b0a4d991e87b41f76ee14e2a84 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 15 Nov 2010 12:50:50 +1000 Subject: drm/nv50: allocate page for unknown PFB object in nv50_fb.c Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_drv.h | 1 + drivers/gpu/drm/nouveau/nv50_fb.c | 56 ++++++++++++++++++++++++++++++++++- 2 files changed, 56 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index 822cd40b3eb4..e1619c674380 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -311,6 +311,7 @@ struct nouveau_timer_engine { struct nouveau_fb_engine { int num_tiles; struct drm_mm tag_heap; + void *priv; int (*init)(struct drm_device *dev); void (*takedown)(struct drm_device *dev); diff --git a/drivers/gpu/drm/nouveau/nv50_fb.c b/drivers/gpu/drm/nouveau/nv50_fb.c index d745c952986a..aa6d78366078 100644 --- a/drivers/gpu/drm/nouveau/nv50_fb.c +++ b/drivers/gpu/drm/nouveau/nv50_fb.c @@ -3,16 +3,58 @@ #include "nouveau_drv.h" #include "nouveau_drm.h" +struct nv50_fb_priv { + struct page *r100c08_page; + dma_addr_t r100c08; +}; + +static int +nv50_fb_create(struct drm_device *dev) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nv50_fb_priv *priv; + + priv = kzalloc(sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + priv->r100c08_page = alloc_page(GFP_KERNEL | __GFP_ZERO); + if (!priv->r100c08_page) { + kfree(priv); + return -ENOMEM; + } + + priv->r100c08 = pci_map_page(dev->pdev, priv->r100c08_page, 0, + PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); + if (pci_dma_mapping_error(dev->pdev, priv->r100c08)) { + __free_page(priv->r100c08_page); + kfree(priv); + return -EFAULT; + } + + dev_priv->engine.fb.priv = priv; + return 0; +} + int nv50_fb_init(struct drm_device *dev) { struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nv50_fb_priv *priv; + int ret; + + if (!dev_priv->engine.fb.priv) { + ret = nv50_fb_create(dev); + if (ret) + return ret; + } + priv = dev_priv->engine.fb.priv; /* Not a clue what this is exactly. Without pointing it at a * scratch page, VRAM->GART blits with M2MF (as in DDX DFS) * cause IOMMU "read from address 0" errors (rh#561267) */ - nv_wr32(dev, 0x100c08, dev_priv->gart_info.sg_dummy_bus >> 8); + nv_wr32(dev, 0x100c08, priv->r100c08 >> 8); /* This is needed to get meaningful information from 100c90 * on traps. No idea what these values mean exactly. */ @@ -36,6 +78,18 @@ nv50_fb_init(struct drm_device *dev) void nv50_fb_takedown(struct drm_device *dev) { + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nv50_fb_priv *priv; + + priv = dev_priv->engine.fb.priv; + if (!priv) + return; + dev_priv->engine.fb.priv = NULL; + + pci_unmap_page(dev->pdev, priv->r100c08, PAGE_SIZE, + PCI_DMA_BIDIRECTIONAL); + __free_page(priv->r100c08_page); + kfree(priv); } void -- cgit v1.2.3 From 9fea1bcbff037cb61f71e0d699180030b1f509a5 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 15 Nov 2010 12:52:23 +1000 Subject: drm/nv50: fix 0x100c90 init for NVAF Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nv50_fb.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nv50_fb.c b/drivers/gpu/drm/nouveau/nv50_fb.c index aa6d78366078..50290dea0ac4 100644 --- a/drivers/gpu/drm/nouveau/nv50_fb.c +++ b/drivers/gpu/drm/nouveau/nv50_fb.c @@ -60,15 +60,18 @@ nv50_fb_init(struct drm_device *dev) * on traps. No idea what these values mean exactly. */ switch (dev_priv->chipset) { case 0x50: - nv_wr32(dev, 0x100c90, 0x0707ff); + nv_wr32(dev, 0x100c90, 0x000707ff); break; case 0xa3: case 0xa5: case 0xa8: - nv_wr32(dev, 0x100c90, 0x0d0fff); + nv_wr32(dev, 0x100c90, 0x000d0fff); + break; + case 0xaf: + nv_wr32(dev, 0x100c90, 0x089d1fff); break; default: - nv_wr32(dev, 0x100c90, 0x1d07ff); + nv_wr32(dev, 0x100c90, 0x001d07ff); break; } -- cgit v1.2.3 From 7b4808bb6ee63c9cc9c9be5a52f0c7babfc50659 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 15 Nov 2010 12:54:57 +1000 Subject: drm/nouveau: remove dummy page use from PCI(E)GART, use PTE present instead Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_drv.h | 2 -- drivers/gpu/drm/nouveau/nouveau_sgdma.c | 38 +++------------------------------ 2 files changed, 3 insertions(+), 37 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index e1619c674380..d76d2c09049d 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -672,8 +672,6 @@ struct drm_nouveau_private { uint64_t aper_free; struct nouveau_gpuobj *sg_ctxdma; - struct page *sg_dummy_page; - dma_addr_t sg_dummy_bus; } gart_info; /* nv10-nv40 tiling regions */ diff --git a/drivers/gpu/drm/nouveau/nouveau_sgdma.c b/drivers/gpu/drm/nouveau/nouveau_sgdma.c index d4ac97007038..54af7608d45c 100644 --- a/drivers/gpu/drm/nouveau/nouveau_sgdma.c +++ b/drivers/gpu/drm/nouveau/nouveau_sgdma.c @@ -144,19 +144,15 @@ nouveau_sgdma_unbind(struct ttm_backend *be) pte = nvbe->pte_start; for (i = 0; i < nvbe->nr_pages; i++) { - dma_addr_t dma_offset = dev_priv->gart_info.sg_dummy_bus; - for (j = 0; j < PAGE_SIZE / NV_CTXDMA_PAGE_SIZE; j++) { if (dev_priv->card_type < NV_50) { - nv_wo32(gpuobj, (pte * 4) + 0, dma_offset | 3); + nv_wo32(gpuobj, (pte * 4) + 0, 0x00000000); pte += 1; } else { nv_wo32(gpuobj, (pte * 4) + 0, 0x00000000); nv_wo32(gpuobj, (pte * 4) + 4, 0x00000000); pte += 2; } - - dma_offset += NV_CTXDMA_PAGE_SIZE; } } dev_priv->engine.instmem.flush(nvbe->dev); @@ -218,7 +214,6 @@ int nouveau_sgdma_init(struct drm_device *dev) { struct drm_nouveau_private *dev_priv = dev->dev_private; - struct pci_dev *pdev = dev->pdev; struct nouveau_gpuobj *gpuobj = NULL; uint32_t aper_size, obj_size; int i, ret; @@ -245,22 +240,6 @@ nouveau_sgdma_init(struct drm_device *dev) return ret; } - dev_priv->gart_info.sg_dummy_page = - alloc_page(GFP_KERNEL|__GFP_DMA32|__GFP_ZERO); - if (!dev_priv->gart_info.sg_dummy_page) { - nouveau_gpuobj_ref(NULL, &gpuobj); - return -ENOMEM; - } - - set_bit(PG_locked, &dev_priv->gart_info.sg_dummy_page->flags); - dev_priv->gart_info.sg_dummy_bus = - pci_map_page(pdev, dev_priv->gart_info.sg_dummy_page, 0, - PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); - if (pci_dma_mapping_error(pdev, dev_priv->gart_info.sg_dummy_bus)) { - nouveau_gpuobj_ref(NULL, &gpuobj); - return -EFAULT; - } - if (dev_priv->card_type < NV_50) { /* special case, allocated from global instmem heap so * cinst is invalid, we use it on all channels though so @@ -277,10 +256,8 @@ nouveau_sgdma_init(struct drm_device *dev) (NV_DMA_ACCESS_RW << 14) | (NV_DMA_TARGET_PCI << 16)); nv_wo32(gpuobj, 4, aper_size - 1); - for (i = 2; i < 2 + (aper_size >> 12); i++) { - nv_wo32(gpuobj, i * 4, - dev_priv->gart_info.sg_dummy_bus | 3); - } + for (i = 2; i < 2 + (aper_size >> 12); i++) + nv_wo32(gpuobj, i * 4, 0x00000000); } else { for (i = 0; i < obj_size; i += 8) { nv_wo32(gpuobj, i + 0, 0x00000000); @@ -301,15 +278,6 @@ nouveau_sgdma_takedown(struct drm_device *dev) { struct drm_nouveau_private *dev_priv = dev->dev_private; - if (dev_priv->gart_info.sg_dummy_page) { - pci_unmap_page(dev->pdev, dev_priv->gart_info.sg_dummy_bus, - NV_CTXDMA_PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); - unlock_page(dev_priv->gart_info.sg_dummy_page); - __free_page(dev_priv->gart_info.sg_dummy_page); - dev_priv->gart_info.sg_dummy_page = NULL; - dev_priv->gart_info.sg_dummy_bus = 0; - } - nouveau_gpuobj_ref(NULL, &dev_priv->gart_info.sg_ctxdma); } -- cgit v1.2.3 From 2cb3d3b6c64d37514fd8865748de66ff35a489af Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 15 Nov 2010 16:28:19 +1000 Subject: drm/nv84: fix minor issues in PCRYPT implementation Fix running of destroy_context() when create_context() has never been called for the channel, and fill in engine's tlb_flush() function pointer. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_state.c | 1 + drivers/gpu/drm/nouveau/nv84_crypt.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c index b42e29d1935e..75e70022fbd3 100644 --- a/drivers/gpu/drm/nouveau/nouveau_state.c +++ b/drivers/gpu/drm/nouveau/nouveau_state.c @@ -437,6 +437,7 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->crypt.takedown = nv84_crypt_fini; engine->crypt.create_context = nv84_crypt_create_context; engine->crypt.destroy_context = nv84_crypt_destroy_context; + engine->crypt.tlb_flush = nv84_crypt_tlb_flush; break; default: engine->crypt.init = nouveau_stub_init; diff --git a/drivers/gpu/drm/nouveau/nv84_crypt.c b/drivers/gpu/drm/nouveau/nv84_crypt.c index 1cda0240f55d..780bb1d66f95 100644 --- a/drivers/gpu/drm/nouveau/nv84_crypt.c +++ b/drivers/gpu/drm/nouveau/nv84_crypt.c @@ -61,7 +61,7 @@ nv84_crypt_destroy_context(struct nouveau_channel *chan) struct drm_device *dev = chan->dev; u32 inst; - if (!chan->ramin) + if (!chan->crypt_ctx) return; inst = (chan->ramin->vinst >> 12); -- cgit v1.2.3 From 6d6c5a157af45a5bd50ab913b07d826811a9ea0a Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 16 Nov 2010 10:17:53 +1000 Subject: drm/nouveau: remove some useless GETPARAMs These have been unused since UMS support was ripped out, so lets remove them completely. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_state.c | 17 +---------------- include/drm/nouveau_drm.h | 3 --- 2 files changed, 1 insertion(+), 19 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c index 75e70022fbd3..35b28406caf6 100644 --- a/drivers/gpu/drm/nouveau/nouveau_state.c +++ b/drivers/gpu/drm/nouveau/nouveau_state.c @@ -1074,21 +1074,6 @@ int nouveau_ioctl_getparam(struct drm_device *dev, void *data, else getparam->value = NV_PCI; break; - case NOUVEAU_GETPARAM_FB_PHYSICAL: - getparam->value = dev_priv->fb_phys; - break; - case NOUVEAU_GETPARAM_AGP_PHYSICAL: - getparam->value = dev_priv->gart_info.aper_base; - break; - case NOUVEAU_GETPARAM_PCI_PHYSICAL: - if (dev->sg) { - getparam->value = (unsigned long)dev->sg->virtual; - } else { - NV_ERROR(dev, "Requested PCIGART address, " - "while no PCIGART was created\n"); - return -EINVAL; - } - break; case NOUVEAU_GETPARAM_FB_SIZE: getparam->value = dev_priv->fb_available_size; break; @@ -1096,7 +1081,7 @@ int nouveau_ioctl_getparam(struct drm_device *dev, void *data, getparam->value = dev_priv->gart_info.aper_size; break; case NOUVEAU_GETPARAM_VM_VRAM_BASE: - getparam->value = dev_priv->vm_vram_base; + getparam->value = 0; /* deprecated */ break; case NOUVEAU_GETPARAM_PTIMER_TIME: getparam->value = dev_priv->engine.timer.read(dev); diff --git a/include/drm/nouveau_drm.h b/include/drm/nouveau_drm.h index 39aa0fd6a529..e2cfe80f6fca 100644 --- a/include/drm/nouveau_drm.h +++ b/include/drm/nouveau_drm.h @@ -71,11 +71,8 @@ struct drm_nouveau_gpuobj_free { #define NOUVEAU_GETPARAM_PCI_VENDOR 3 #define NOUVEAU_GETPARAM_PCI_DEVICE 4 #define NOUVEAU_GETPARAM_BUS_TYPE 5 -#define NOUVEAU_GETPARAM_FB_PHYSICAL 6 -#define NOUVEAU_GETPARAM_AGP_PHYSICAL 7 #define NOUVEAU_GETPARAM_FB_SIZE 8 #define NOUVEAU_GETPARAM_AGP_SIZE 9 -#define NOUVEAU_GETPARAM_PCI_PHYSICAL 10 #define NOUVEAU_GETPARAM_CHIPSET_ID 11 #define NOUVEAU_GETPARAM_VM_VRAM_BASE 12 #define NOUVEAU_GETPARAM_GRAPH_UNITS 13 -- cgit v1.2.3 From 7f4a195fcbd8b16f25f1de7f1419414d7505daa5 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 16 Nov 2010 11:50:09 +1000 Subject: drm/nouveau: tidy up and extend dma object creation interfaces Reviewed-by: Francisco Jerez Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_channel.c | 23 ++- drivers/gpu/drm/nouveau/nouveau_drv.h | 26 +++- drivers/gpu/drm/nouveau/nouveau_fence.c | 4 +- drivers/gpu/drm/nouveau/nouveau_notifier.c | 29 +--- drivers/gpu/drm/nouveau/nouveau_object.c | 235 +++++++++++++++++------------ drivers/gpu/drm/nouveau/nouveau_reg.h | 11 -- drivers/gpu/drm/nouveau/nouveau_sgdma.c | 7 +- drivers/gpu/drm/nouveau/nouveau_state.c | 9 +- 8 files changed, 184 insertions(+), 160 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_channel.c b/drivers/gpu/drm/nouveau/nouveau_channel.c index 11b2370e16da..0f33132fba3b 100644 --- a/drivers/gpu/drm/nouveau/nouveau_channel.c +++ b/drivers/gpu/drm/nouveau/nouveau_channel.c @@ -39,22 +39,22 @@ nouveau_channel_pushbuf_ctxdma_init(struct nouveau_channel *chan) if (dev_priv->card_type >= NV_50) { ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY, 0, - dev_priv->vm_end, NV_DMA_ACCESS_RO, - NV_DMA_TARGET_AGP, &pushbuf); + dev_priv->vm_end, NV_MEM_ACCESS_RO, + NV_MEM_TARGET_VM, &pushbuf); chan->pushbuf_base = pb->bo.offset; } else if (pb->bo.mem.mem_type == TTM_PL_TT) { - ret = nouveau_gpuobj_gart_dma_new(chan, 0, - dev_priv->gart_info.aper_size, - NV_DMA_ACCESS_RO, &pushbuf, - NULL); + ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY, 0, + dev_priv->gart_info.aper_size, + NV_MEM_ACCESS_RO, + NV_MEM_TARGET_GART, &pushbuf); chan->pushbuf_base = pb->bo.mem.start << PAGE_SHIFT; } else if (dev_priv->card_type != NV_04) { ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY, 0, dev_priv->fb_available_size, - NV_DMA_ACCESS_RO, - NV_DMA_TARGET_VIDMEM, &pushbuf); + NV_MEM_ACCESS_RO, + NV_MEM_TARGET_VRAM, &pushbuf); chan->pushbuf_base = pb->bo.mem.start << PAGE_SHIFT; } else { /* NV04 cmdbuf hack, from original ddx.. not sure of it's @@ -62,11 +62,10 @@ nouveau_channel_pushbuf_ctxdma_init(struct nouveau_channel *chan) * VRAM. */ ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY, - pci_resource_start(dev->pdev, - 1), + pci_resource_start(dev->pdev, 1), dev_priv->fb_available_size, - NV_DMA_ACCESS_RO, - NV_DMA_TARGET_PCI, &pushbuf); + NV_MEM_ACCESS_RO, + NV_MEM_TARGET_PCI, &pushbuf); chan->pushbuf_base = pb->bo.mem.start << PAGE_SHIFT; } diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index d76d2c09049d..a52b1da32031 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -886,12 +886,14 @@ extern int nouveau_gpuobj_new_fake(struct drm_device *, u32 pinst, u64 vinst, extern int nouveau_gpuobj_dma_new(struct nouveau_channel *, int class, uint64_t offset, uint64_t size, int access, int target, struct nouveau_gpuobj **); -extern int nouveau_gpuobj_gart_dma_new(struct nouveau_channel *, - uint64_t offset, uint64_t size, - int access, struct nouveau_gpuobj **, - uint32_t *o_ret); extern int nouveau_gpuobj_gr_new(struct nouveau_channel *, int class, struct nouveau_gpuobj **); +extern int nv50_gpuobj_dma_new(struct nouveau_channel *, int class, u64 base, + u64 size, int target, int access, u32 type, + u32 comp, struct nouveau_gpuobj **pobj); +extern void nv50_gpuobj_dma_init(struct nouveau_gpuobj *, u32 offset, + int class, u64 base, u64 size, int target, + int access, u32 type, u32 comp); extern int nouveau_ioctl_grobj_alloc(struct drm_device *, void *data, struct drm_file *); extern int nouveau_ioctl_gpuobj_free(struct drm_device *, void *data, @@ -1545,6 +1547,22 @@ nv_match_device(struct drm_device *dev, unsigned device, dev->pdev->subsystem_device == sub_device; } +/* memory type/access flags, do not match hardware values */ +#define NV_MEM_ACCESS_RO 1 +#define NV_MEM_ACCESS_WO 2 +#define NV_MEM_ACCESS_RW (NV_MEM_ACCESS_RO | NV_MEM_ACCESS_WO) +#define NV_MEM_ACCESS_VM 4 + +#define NV_MEM_TARGET_VRAM 0 +#define NV_MEM_TARGET_PCI 1 +#define NV_MEM_TARGET_PCI_NOSNOOP 2 +#define NV_MEM_TARGET_VM 3 +#define NV_MEM_TARGET_GART 4 + +#define NV_MEM_TYPE_VM 0x7f +#define NV_MEM_COMP_VM 0x03 + +/* NV_SW object class */ #define NV_SW 0x0000506e #define NV_SW_DMA_SEMAPHORE 0x00000060 #define NV_SW_SEMAPHORE_OFFSET 0x00000064 diff --git a/drivers/gpu/drm/nouveau/nouveau_fence.c b/drivers/gpu/drm/nouveau/nouveau_fence.c index 91aa6c54cc96..2579fc69d182 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fence.c +++ b/drivers/gpu/drm/nouveau/nouveau_fence.c @@ -459,8 +459,8 @@ nouveau_fence_channel_init(struct nouveau_channel *chan) ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY, mem->start << PAGE_SHIFT, mem->size << PAGE_SHIFT, - NV_DMA_ACCESS_RW, - NV_DMA_TARGET_VIDMEM, &obj); + NV_MEM_ACCESS_RW, + NV_MEM_TARGET_VRAM, &obj); if (ret) return ret; diff --git a/drivers/gpu/drm/nouveau/nouveau_notifier.c b/drivers/gpu/drm/nouveau/nouveau_notifier.c index 2c5a1f66f7f0..a050b7b69782 100644 --- a/drivers/gpu/drm/nouveau/nouveau_notifier.c +++ b/drivers/gpu/drm/nouveau/nouveau_notifier.c @@ -99,7 +99,6 @@ nouveau_notifier_alloc(struct nouveau_channel *chan, uint32_t handle, int size, uint32_t *b_offset) { struct drm_device *dev = chan->dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; struct nouveau_gpuobj *nobj = NULL; struct drm_mm_node *mem; uint32_t offset; @@ -113,31 +112,15 @@ nouveau_notifier_alloc(struct nouveau_channel *chan, uint32_t handle, return -ENOMEM; } - offset = chan->notifier_bo->bo.mem.start << PAGE_SHIFT; - if (chan->notifier_bo->bo.mem.mem_type == TTM_PL_VRAM) { - target = NV_DMA_TARGET_VIDMEM; - } else - if (chan->notifier_bo->bo.mem.mem_type == TTM_PL_TT) { - if (dev_priv->gart_info.type == NOUVEAU_GART_SGDMA && - dev_priv->card_type < NV_50) { - ret = nouveau_sgdma_get_page(dev, offset, &offset); - if (ret) - return ret; - target = NV_DMA_TARGET_PCI; - } else { - target = NV_DMA_TARGET_AGP; - if (dev_priv->card_type >= NV_50) - offset += dev_priv->vm_gart_base; - } - } else { - NV_ERROR(dev, "Bad DMA target, mem_type %d!\n", - chan->notifier_bo->bo.mem.mem_type); - return -EINVAL; - } + if (chan->notifier_bo->bo.mem.mem_type == TTM_PL_VRAM) + target = NV_MEM_TARGET_VRAM; + else + target = NV_MEM_TARGET_GART; + offset = chan->notifier_bo->bo.mem.start << PAGE_SHIFT; offset += mem->start; ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY, offset, - mem->size, NV_DMA_ACCESS_RW, target, + mem->size, NV_MEM_ACCESS_RW, target, &nobj); if (ret) { drm_mm_put_block(mem); diff --git a/drivers/gpu/drm/nouveau/nouveau_object.c b/drivers/gpu/drm/nouveau/nouveau_object.c index e8c74de905ec..924653c30783 100644 --- a/drivers/gpu/drm/nouveau/nouveau_object.c +++ b/drivers/gpu/drm/nouveau/nouveau_object.c @@ -404,113 +404,157 @@ nouveau_gpuobj_class_instmem_size(struct drm_device *dev, int class) The method below creates a DMA object in instance RAM and returns a handle to it that can be used to set up context objects. */ -int -nouveau_gpuobj_dma_new(struct nouveau_channel *chan, int class, - uint64_t offset, uint64_t size, int access, - int target, struct nouveau_gpuobj **gpuobj) + +void +nv50_gpuobj_dma_init(struct nouveau_gpuobj *obj, u32 offset, int class, + u64 base, u64 size, int target, int access, + u32 type, u32 comp) { - struct drm_device *dev = chan->dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_instmem_engine *instmem = &dev_priv->engine.instmem; - int ret; + struct drm_nouveau_private *dev_priv = obj->dev->dev_private; + struct nouveau_instmem_engine *pinstmem = &dev_priv->engine.instmem; + u32 flags0; - NV_DEBUG(dev, "ch%d class=0x%04x offset=0x%llx size=0x%llx\n", - chan->id, class, offset, size); - NV_DEBUG(dev, "access=%d target=%d\n", access, target); + flags0 = (comp << 29) | (type << 22) | class; + flags0 |= 0x00100000; + + switch (access) { + case NV_MEM_ACCESS_RO: flags0 |= 0x00040000; break; + case NV_MEM_ACCESS_RW: + case NV_MEM_ACCESS_WO: flags0 |= 0x00080000; break; + default: + break; + } switch (target) { - case NV_DMA_TARGET_AGP: - offset += dev_priv->gart_info.aper_base; + case NV_MEM_TARGET_VRAM: + flags0 |= 0x00010000; + break; + case NV_MEM_TARGET_PCI: + flags0 |= 0x00020000; + break; + case NV_MEM_TARGET_PCI_NOSNOOP: + flags0 |= 0x00030000; break; + case NV_MEM_TARGET_GART: + base += dev_priv->vm_gart_base; default: + flags0 &= ~0x00100000; break; } - ret = nouveau_gpuobj_new(dev, chan, - nouveau_gpuobj_class_instmem_size(dev, class), - 16, NVOBJ_FLAG_ZERO_ALLOC | - NVOBJ_FLAG_ZERO_FREE, gpuobj); - if (ret) { - NV_ERROR(dev, "Error creating gpuobj: %d\n", ret); - return ret; - } + /* convert to base + limit */ + size = (base + size) - 1; - if (dev_priv->card_type < NV_50) { - uint32_t frame, adjust, pte_flags = 0; - - if (access != NV_DMA_ACCESS_RO) - pte_flags |= (1<<1); - adjust = offset & 0x00000fff; - frame = offset & ~0x00000fff; - - nv_wo32(*gpuobj, 0, ((1<<12) | (1<<13) | (adjust << 20) | - (access << 14) | (target << 16) | - class)); - nv_wo32(*gpuobj, 4, size - 1); - nv_wo32(*gpuobj, 8, frame | pte_flags); - nv_wo32(*gpuobj, 12, frame | pte_flags); - } else { - uint64_t limit = offset + size - 1; - uint32_t flags0, flags5; + nv_wo32(obj, offset + 0x00, flags0); + nv_wo32(obj, offset + 0x04, lower_32_bits(size)); + nv_wo32(obj, offset + 0x08, lower_32_bits(base)); + nv_wo32(obj, offset + 0x0c, upper_32_bits(size) << 24 | + upper_32_bits(base)); + nv_wo32(obj, offset + 0x10, 0x00000000); + nv_wo32(obj, offset + 0x14, 0x00000000); - if (target == NV_DMA_TARGET_VIDMEM) { - flags0 = 0x00190000; - flags5 = 0x00010000; - } else { - flags0 = 0x7fc00000; - flags5 = 0x00080000; - } + pinstmem->flush(obj->dev); +} - nv_wo32(*gpuobj, 0, flags0 | class); - nv_wo32(*gpuobj, 4, lower_32_bits(limit)); - nv_wo32(*gpuobj, 8, lower_32_bits(offset)); - nv_wo32(*gpuobj, 12, ((upper_32_bits(limit) & 0xff) << 24) | - (upper_32_bits(offset) & 0xff)); - nv_wo32(*gpuobj, 20, flags5); - } +int +nv50_gpuobj_dma_new(struct nouveau_channel *chan, int class, u64 base, u64 size, + int target, int access, u32 type, u32 comp, + struct nouveau_gpuobj **pobj) +{ + struct drm_device *dev = chan->dev; + int ret; - instmem->flush(dev); + ret = nouveau_gpuobj_new(dev, chan, 24, 16, NVOBJ_FLAG_ZERO_ALLOC | + NVOBJ_FLAG_ZERO_FREE, pobj); + if (ret) + return ret; - (*gpuobj)->engine = NVOBJ_ENGINE_SW; - (*gpuobj)->class = class; + nv50_gpuobj_dma_init(*pobj, 0, class, base, size, target, + access, type, comp); return 0; } int -nouveau_gpuobj_gart_dma_new(struct nouveau_channel *chan, - uint64_t offset, uint64_t size, int access, - struct nouveau_gpuobj **gpuobj, - uint32_t *o_ret) +nouveau_gpuobj_dma_new(struct nouveau_channel *chan, int class, u64 base, + u64 size, int access, int target, + struct nouveau_gpuobj **pobj) { + struct drm_nouveau_private *dev_priv = chan->dev->dev_private; struct drm_device *dev = chan->dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_gpuobj *obj; + u32 page_addr, flags0, flags2; int ret; - if (dev_priv->gart_info.type == NOUVEAU_GART_AGP || - (dev_priv->card_type >= NV_50 && - dev_priv->gart_info.type == NOUVEAU_GART_SGDMA)) { - ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY, - offset + dev_priv->vm_gart_base, - size, access, NV_DMA_TARGET_AGP, - gpuobj); - if (o_ret) - *o_ret = 0; - } else - if (dev_priv->gart_info.type == NOUVEAU_GART_SGDMA) { - nouveau_gpuobj_ref(dev_priv->gart_info.sg_ctxdma, gpuobj); - if (offset & ~0xffffffffULL) { - NV_ERROR(dev, "obj offset exceeds 32-bits\n"); - return -EINVAL; + if (dev_priv->card_type >= NV_50) { + u32 comp = (target == NV_MEM_TARGET_VM) ? NV_MEM_COMP_VM : 0; + u32 type = (target == NV_MEM_TARGET_VM) ? NV_MEM_TYPE_VM : 0; + + return nv50_gpuobj_dma_new(chan, class, base, size, + target, access, type, comp, pobj); + } + + if (target == NV_MEM_TARGET_GART) { + if (dev_priv->gart_info.type == NOUVEAU_GART_AGP) { + target = NV_MEM_TARGET_PCI_NOSNOOP; + base += dev_priv->gart_info.aper_base; + } else + if (base != 0) { + ret = nouveau_sgdma_get_page(dev, base, &page_addr); + if (ret) + return ret; + + target = NV_MEM_TARGET_PCI; + base = page_addr; + } else { + nouveau_gpuobj_ref(dev_priv->gart_info.sg_ctxdma, pobj); + return 0; } - if (o_ret) - *o_ret = (uint32_t)offset; - ret = (*gpuobj != NULL) ? 0 : -EINVAL; - } else { - NV_ERROR(dev, "Invalid GART type %d\n", dev_priv->gart_info.type); - return -EINVAL; } - return ret; + flags0 = class; + flags0 |= 0x00003000; /* PT present, PT linear */ + flags2 = 0; + + switch (target) { + case NV_MEM_TARGET_PCI: + flags0 |= 0x00020000; + break; + case NV_MEM_TARGET_PCI_NOSNOOP: + flags0 |= 0x00030000; + break; + default: + break; + } + + switch (access) { + case NV_MEM_ACCESS_RO: + flags0 |= 0x00004000; + break; + case NV_MEM_ACCESS_WO: + flags0 |= 0x00008000; + default: + flags2 |= 0x00000002; + break; + } + + flags0 |= (base & 0x00000fff) << 20; + flags2 |= (base & 0xfffff000); + + ret = nouveau_gpuobj_new(dev, chan, (dev_priv->card_type >= NV_40) ? + 32 : 16, 16, NVOBJ_FLAG_ZERO_ALLOC | + NVOBJ_FLAG_ZERO_FREE, &obj); + if (ret) + return ret; + + nv_wo32(obj, 0x00, flags0); + nv_wo32(obj, 0x04, size - 1); + nv_wo32(obj, 0x08, flags2); + nv_wo32(obj, 0x0c, flags2); + + obj->engine = NVOBJ_ENGINE_SW; + obj->class = class; + *pobj = obj; + return 0; } /* Context objects in the instance RAM have the following structure. @@ -806,8 +850,8 @@ nouveau_gpuobj_channel_init(struct nouveau_channel *chan, if (dev_priv->card_type >= NV_50) { ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY, 0, dev_priv->vm_end, - NV_DMA_ACCESS_RW, - NV_DMA_TARGET_AGP, &vram); + NV_MEM_ACCESS_RW, + NV_MEM_TARGET_VM, &vram); if (ret) { NV_ERROR(dev, "Error creating VRAM ctxdma: %d\n", ret); return ret; @@ -815,8 +859,8 @@ nouveau_gpuobj_channel_init(struct nouveau_channel *chan, } else { ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY, 0, dev_priv->fb_available_size, - NV_DMA_ACCESS_RW, - NV_DMA_TARGET_VIDMEM, &vram); + NV_MEM_ACCESS_RW, + NV_MEM_TARGET_VRAM, &vram); if (ret) { NV_ERROR(dev, "Error creating VRAM ctxdma: %d\n", ret); return ret; @@ -834,20 +878,13 @@ nouveau_gpuobj_channel_init(struct nouveau_channel *chan, if (dev_priv->card_type >= NV_50) { ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY, 0, dev_priv->vm_end, - NV_DMA_ACCESS_RW, - NV_DMA_TARGET_AGP, &tt); - if (ret) { - NV_ERROR(dev, "Error creating VRAM ctxdma: %d\n", ret); - return ret; - } - } else - if (dev_priv->gart_info.type != NOUVEAU_GART_NONE) { - ret = nouveau_gpuobj_gart_dma_new(chan, 0, - dev_priv->gart_info.aper_size, - NV_DMA_ACCESS_RW, &tt, NULL); + NV_MEM_ACCESS_RW, + NV_MEM_TARGET_VM, &tt); } else { - NV_ERROR(dev, "Invalid GART type %d\n", dev_priv->gart_info.type); - ret = -EINVAL; + ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY, + 0, dev_priv->gart_info.aper_size, + NV_MEM_ACCESS_RW, + NV_MEM_TARGET_GART, &tt); } if (ret) { diff --git a/drivers/gpu/drm/nouveau/nouveau_reg.h b/drivers/gpu/drm/nouveau/nouveau_reg.h index df3a87e792f2..04e8fb795269 100644 --- a/drivers/gpu/drm/nouveau/nouveau_reg.h +++ b/drivers/gpu/drm/nouveau/nouveau_reg.h @@ -79,17 +79,6 @@ # define NV40_RAMHT_CONTEXT_ENGINE_SHIFT 20 # define NV40_RAMHT_CONTEXT_INSTANCE_SHIFT 0 -/* DMA object defines */ -#define NV_DMA_ACCESS_RW 0 -#define NV_DMA_ACCESS_RO 1 -#define NV_DMA_ACCESS_WO 2 -#define NV_DMA_TARGET_VIDMEM 0 -#define NV_DMA_TARGET_PCI 2 -#define NV_DMA_TARGET_AGP 3 -/* The following is not a real value used by the card, it's changed by - * nouveau_object_dma_create */ -#define NV_DMA_TARGET_PCI_NONLINEAR 8 - /* Some object classes we care about in the drm */ #define NV_CLASS_DMA_FROM_MEMORY 0x00000002 #define NV_CLASS_DMA_TO_MEMORY 0x00000003 diff --git a/drivers/gpu/drm/nouveau/nouveau_sgdma.c b/drivers/gpu/drm/nouveau/nouveau_sgdma.c index 54af7608d45c..db32644f6114 100644 --- a/drivers/gpu/drm/nouveau/nouveau_sgdma.c +++ b/drivers/gpu/drm/nouveau/nouveau_sgdma.c @@ -247,14 +247,11 @@ nouveau_sgdma_init(struct drm_device *dev) */ gpuobj->cinst = gpuobj->pinst; - /* Maybe use NV_DMA_TARGET_AGP for PCIE? NVIDIA do this, and - * confirmed to work on c51. Perhaps means NV_DMA_TARGET_PCIE - * on those cards? */ nv_wo32(gpuobj, 0, NV_CLASS_DMA_IN_MEMORY | (1 << 12) /* PT present */ | (0 << 13) /* PT *not* linear */ | - (NV_DMA_ACCESS_RW << 14) | - (NV_DMA_TARGET_PCI << 16)); + (0 << 14) /* RW */ | + (2 << 16) /* PCI */); nv_wo32(gpuobj, 4, aper_size - 1); for (i = 2; i < 2 + (aper_size >> 12); i++) nv_wo32(gpuobj, i * 4, 0x00000000); diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c index 35b28406caf6..e779e9320453 100644 --- a/drivers/gpu/drm/nouveau/nouveau_state.c +++ b/drivers/gpu/drm/nouveau/nouveau_state.c @@ -536,7 +536,7 @@ nouveau_card_init_channel(struct drm_device *dev) ret = nouveau_gpuobj_dma_new(dev_priv->channel, NV_CLASS_DMA_IN_MEMORY, 0, dev_priv->vram_size, - NV_DMA_ACCESS_RW, NV_DMA_TARGET_VIDMEM, + NV_MEM_ACCESS_RW, NV_MEM_TARGET_VRAM, &gpuobj); if (ret) goto out_err; @@ -546,9 +546,10 @@ nouveau_card_init_channel(struct drm_device *dev) if (ret) goto out_err; - ret = nouveau_gpuobj_gart_dma_new(dev_priv->channel, 0, - dev_priv->gart_info.aper_size, - NV_DMA_ACCESS_RW, &gpuobj, NULL); + ret = nouveau_gpuobj_dma_new(dev_priv->channel, NV_CLASS_DMA_IN_MEMORY, + 0, dev_priv->gart_info.aper_size, + NV_MEM_ACCESS_RW, NV_MEM_TARGET_GART, + &gpuobj); if (ret) goto out_err; -- cgit v1.2.3 From 2e5702aff39532662198459726c624d5eadbdd78 Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Fri, 19 Nov 2010 18:08:47 +1000 Subject: drm/nouveau: fabricate DCB encoder table for iMac G4 In typical Apple fashion there's no standard information about what encoders are present on this machine, this patch adds a quirk to provide it. Signed-off-by: Francisco Jerez Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_bios.c | 102 ++++++++++++--------------------- 1 file changed, 38 insertions(+), 64 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c index b2293576f278..d3046559bf05 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bios.c +++ b/drivers/gpu/drm/nouveau/nouveau_bios.c @@ -6053,52 +6053,17 @@ static struct dcb_entry *new_dcb_entry(struct dcb_table *dcb) return entry; } -static void fabricate_vga_output(struct dcb_table *dcb, int i2c, int heads) +static void fabricate_dcb_output(struct dcb_table *dcb, int type, int i2c, + int heads, int or) { struct dcb_entry *entry = new_dcb_entry(dcb); - entry->type = 0; + entry->type = type; entry->i2c_index = i2c; entry->heads = heads; - entry->location = DCB_LOC_ON_CHIP; - entry->or = 1; -} - -static void fabricate_dvi_i_output(struct dcb_table *dcb, bool twoHeads) -{ - struct dcb_entry *entry = new_dcb_entry(dcb); - - entry->type = 2; - entry->i2c_index = LEGACY_I2C_PANEL; - entry->heads = twoHeads ? 3 : 1; - entry->location = !DCB_LOC_ON_CHIP; /* ie OFF CHIP */ - entry->or = 1; /* means |0x10 gets set on CRE_LCD__INDEX */ - entry->duallink_possible = false; /* SiI164 and co. are single link */ - -#if 0 - /* - * For dvi-a either crtc probably works, but my card appears to only - * support dvi-d. "nvidia" still attempts to program it for dvi-a, - * doing the full fp output setup (program 0x6808.. fp dimension regs, - * setting 0x680848 to 0x10000111 to enable, maybe setting 0x680880); - * the monitor picks up the mode res ok and lights up, but no pixel - * data appears, so the board manufacturer probably connected up the - * sync lines, but missed the video traces / components - * - * with this introduction, dvi-a left as an exercise for the reader. - */ - fabricate_vga_output(dcb, LEGACY_I2C_PANEL, entry->heads); -#endif -} - -static void fabricate_tv_output(struct dcb_table *dcb, bool twoHeads) -{ - struct dcb_entry *entry = new_dcb_entry(dcb); - - entry->type = 1; - entry->i2c_index = LEGACY_I2C_TV; - entry->heads = twoHeads ? 3 : 1; - entry->location = !DCB_LOC_ON_CHIP; /* ie OFF CHIP */ + if (type != OUTPUT_ANALOG) + entry->location = !DCB_LOC_ON_CHIP; /* ie OFF CHIP */ + entry->or = or; } static bool @@ -6365,8 +6330,36 @@ apply_dcb_encoder_quirks(struct drm_device *dev, int idx, u32 *conn, u32 *conf) return true; } +static void +fabricate_dcb_encoder_table(struct drm_device *dev, struct nvbios *bios) +{ + struct dcb_table *dcb = &bios->dcb; + int all_heads = (nv_two_heads(dev) ? 3 : 1); + +#ifdef __powerpc__ + /* Apple iMac G4 NV17 */ + if (of_machine_is_compatible("PowerMac4,5")) { + fabricate_dcb_output(dcb, OUTPUT_TMDS, 0, all_heads, 1); + fabricate_dcb_output(dcb, OUTPUT_ANALOG, 1, all_heads, 2); + return; + } +#endif + + /* Make up some sane defaults */ + fabricate_dcb_output(dcb, OUTPUT_ANALOG, LEGACY_I2C_CRT, 1, 1); + + if (nv04_tv_identify(dev, bios->legacy.i2c_indices.tv) >= 0) + fabricate_dcb_output(dcb, OUTPUT_TV, LEGACY_I2C_TV, + all_heads, 0); + + else if (bios->tmds.output0_script_ptr || + bios->tmds.output1_script_ptr) + fabricate_dcb_output(dcb, OUTPUT_TMDS, LEGACY_I2C_PANEL, + all_heads, 1); +} + static int -parse_dcb_table(struct drm_device *dev, struct nvbios *bios, bool twoHeads) +parse_dcb_table(struct drm_device *dev, struct nvbios *bios) { struct drm_nouveau_private *dev_priv = dev->dev_private; struct dcb_table *dcb = &bios->dcb; @@ -6386,12 +6379,7 @@ parse_dcb_table(struct drm_device *dev, struct nvbios *bios, bool twoHeads) /* this situation likely means a really old card, pre DCB */ if (dcbptr == 0x0) { - NV_INFO(dev, "Assuming a CRT output exists\n"); - fabricate_vga_output(dcb, LEGACY_I2C_CRT, 1); - - if (nv04_tv_identify(dev, bios->legacy.i2c_indices.tv) >= 0) - fabricate_tv_output(dcb, twoHeads); - + fabricate_dcb_encoder_table(dev, bios); return 0; } @@ -6451,21 +6439,7 @@ parse_dcb_table(struct drm_device *dev, struct nvbios *bios, bool twoHeads) */ NV_TRACEWARN(dev, "No useful information in BIOS output table; " "adding all possible outputs\n"); - fabricate_vga_output(dcb, LEGACY_I2C_CRT, 1); - - /* - * Attempt to detect TV before DVI because the test - * for the former is more accurate and it rules the - * latter out. - */ - if (nv04_tv_identify(dev, - bios->legacy.i2c_indices.tv) >= 0) - fabricate_tv_output(dcb, twoHeads); - - else if (bios->tmds.output0_script_ptr || - bios->tmds.output1_script_ptr) - fabricate_dvi_i_output(dcb, twoHeads); - + fabricate_dcb_encoder_table(dev, bios); return 0; } @@ -6859,7 +6833,7 @@ nouveau_bios_init(struct drm_device *dev) if (ret) return ret; - ret = parse_dcb_table(dev, bios, nv_two_heads(dev)); + ret = parse_dcb_table(dev, bios); if (ret) return ret; -- cgit v1.2.3 From 9c5f8414efd5eeed9f498d4170337a3eb126341f Mon Sep 17 00:00:00 2001 From: Dave Chinner Date: Mon, 20 Dec 2010 11:57:24 +1100 Subject: xfs: fix EFI transaction cancellation. XFS_EFI_CANCELED has not been set in the code base since xfs_efi_cancel() was removed back in 2006 by commit 065d312e15902976d256ddaf396a7950ec0350a8 ("[XFS] Remove unused iop_abort log item operation), and even then xfs_efi_cancel() was never called. I haven't tracked it back further than that (beyond git history), but it indicates that the handling of EFIs in cancelled transactions has been broken for a long time. Basically, when we get an IOP_UNPIN(lip, 1); call from xfs_trans_uncommit() (i.e. remove == 1), if we don't free the log item descriptor we leak it. Fix the behviour to be correct and kill the XFS_EFI_CANCELED flag. Signed-off-by: Dave Chinner Reviewed-by: Christoph Hellwig --- fs/xfs/xfs_extfree_item.c | 20 +++++++++----------- fs/xfs/xfs_extfree_item.h | 1 - 2 files changed, 9 insertions(+), 12 deletions(-) diff --git a/fs/xfs/xfs_extfree_item.c b/fs/xfs/xfs_extfree_item.c index a55e687bf562..5997efae05dc 100644 --- a/fs/xfs/xfs_extfree_item.c +++ b/fs/xfs/xfs_extfree_item.c @@ -99,10 +99,11 @@ xfs_efi_item_pin( } /* - * While EFIs cannot really be pinned, the unpin operation is the - * last place at which the EFI is manipulated during a transaction. - * Here we coordinate with xfs_efi_cancel() to determine who gets to - * free the EFI. + * While EFIs cannot really be pinned, the unpin operation is the last place at + * which the EFI is manipulated during a transaction. If we are being asked to + * remove the EFI it's because the transaction has been cancelled and by + * definition that means the EFI cannot be in the AIL so remove it from the + * transaction and free it. */ STATIC void xfs_efi_item_unpin( @@ -113,17 +114,14 @@ xfs_efi_item_unpin( struct xfs_ail *ailp = lip->li_ailp; spin_lock(&ailp->xa_lock); - if (efip->efi_flags & XFS_EFI_CANCELED) { - if (remove) - xfs_trans_del_item(lip); - - /* xfs_trans_ail_delete() drops the AIL lock. */ - xfs_trans_ail_delete(ailp, lip); + if (remove) { + ASSERT(!(lip->li_flags & XFS_LI_IN_AIL)); + xfs_trans_del_item(lip); xfs_efi_item_free(efip); } else { efip->efi_flags |= XFS_EFI_COMMITTED; - spin_unlock(&ailp->xa_lock); } + spin_unlock(&ailp->xa_lock); } /* diff --git a/fs/xfs/xfs_extfree_item.h b/fs/xfs/xfs_extfree_item.h index 0d22c56fdf64..f7834ec8efad 100644 --- a/fs/xfs/xfs_extfree_item.h +++ b/fs/xfs/xfs_extfree_item.h @@ -115,7 +115,6 @@ typedef struct xfs_efd_log_format_64 { */ #define XFS_EFI_RECOVERED 0x1 #define XFS_EFI_COMMITTED 0x2 -#define XFS_EFI_CANCELED 0x4 /* * This is the "extent free intention" log item. It is used -- cgit v1.2.3 From b199c8a4ba11879df87daad496ceee41fdc6aa82 Mon Sep 17 00:00:00 2001 From: Dave Chinner Date: Mon, 20 Dec 2010 11:59:49 +1100 Subject: xfs: Pull EFI/EFD handling out from under the AIL lock EFI/EFD interactions are protected from races by the AIL lock. They are the only type of log items that require the the AIL lock to serialise internal state, so they need to be separated from the AIL lock before we can do bulk insert operations on the AIL. To acheive this, convert the counter of the number of extents in the EFI to an atomic so it can be safely manipulated by EFD processing without locks. Also, convert the EFI state flag manipulations to use atomic bit operations so no locks are needed to record state changes. Finally, use the state bits to determine when it is safe to free the EFI and clean up the code to do this neatly. Signed-off-by: Dave Chinner Reviewed-by: Christoph Hellwig --- fs/xfs/xfs_extfree_item.c | 81 +++++++++++++++++++++++++--------------------- fs/xfs/xfs_extfree_item.h | 10 +++--- fs/xfs/xfs_log_recover.c | 9 +++--- fs/xfs/xfs_trans_extfree.c | 8 +++-- 4 files changed, 59 insertions(+), 49 deletions(-) diff --git a/fs/xfs/xfs_extfree_item.c b/fs/xfs/xfs_extfree_item.c index 5997efae05dc..75f2ef60e579 100644 --- a/fs/xfs/xfs_extfree_item.c +++ b/fs/xfs/xfs_extfree_item.c @@ -47,6 +47,28 @@ xfs_efi_item_free( kmem_zone_free(xfs_efi_zone, efip); } +/* + * Freeing the efi requires that we remove it from the AIL if it has already + * been placed there. However, the EFI may not yet have been placed in the AIL + * when called by xfs_efi_release() from EFD processing due to the ordering of + * committed vs unpin operations in bulk insert operations. Hence the + * test_and_clear_bit(XFS_EFI_COMMITTED) to ensure only the last caller frees + * the EFI. + */ +STATIC void +__xfs_efi_release( + struct xfs_efi_log_item *efip) +{ + struct xfs_ail *ailp = efip->efi_item.li_ailp; + + if (!test_and_clear_bit(XFS_EFI_COMMITTED, &efip->efi_flags)) { + spin_lock(&ailp->xa_lock); + /* xfs_trans_ail_delete() drops the AIL lock. */ + xfs_trans_ail_delete(ailp, &efip->efi_item); + xfs_efi_item_free(efip); + } +} + /* * This returns the number of iovecs needed to log the given efi item. * We only need 1 iovec for an efi item. It just logs the efi_log_format @@ -74,7 +96,8 @@ xfs_efi_item_format( struct xfs_efi_log_item *efip = EFI_ITEM(lip); uint size; - ASSERT(efip->efi_next_extent == efip->efi_format.efi_nextents); + ASSERT(atomic_read(&efip->efi_next_extent) == + efip->efi_format.efi_nextents); efip->efi_format.efi_type = XFS_LI_EFI; @@ -103,7 +126,8 @@ xfs_efi_item_pin( * which the EFI is manipulated during a transaction. If we are being asked to * remove the EFI it's because the transaction has been cancelled and by * definition that means the EFI cannot be in the AIL so remove it from the - * transaction and free it. + * transaction and free it. Otherwise coordinate with xfs_efi_release() (via + * XFS_EFI_COMMITTED) to determine who gets to free the EFI. */ STATIC void xfs_efi_item_unpin( @@ -111,17 +135,14 @@ xfs_efi_item_unpin( int remove) { struct xfs_efi_log_item *efip = EFI_ITEM(lip); - struct xfs_ail *ailp = lip->li_ailp; - spin_lock(&ailp->xa_lock); if (remove) { ASSERT(!(lip->li_flags & XFS_LI_IN_AIL)); xfs_trans_del_item(lip); xfs_efi_item_free(efip); - } else { - efip->efi_flags |= XFS_EFI_COMMITTED; + return; } - spin_unlock(&ailp->xa_lock); + __xfs_efi_release(efip); } /* @@ -150,16 +171,20 @@ xfs_efi_item_unlock( } /* - * The EFI is logged only once and cannot be moved in the log, so - * simply return the lsn at which it's been logged. The canceled - * flag is not paid any attention here. Checking for that is delayed - * until the EFI is unpinned. + * The EFI is logged only once and cannot be moved in the log, so simply return + * the lsn at which it's been logged. For bulk transaction committed + * processing, the EFI may be processed but not yet unpinned prior to the EFD + * being processed. Set the XFS_EFI_COMMITTED flag so this case can be detected + * when processing the EFD. */ STATIC xfs_lsn_t xfs_efi_item_committed( struct xfs_log_item *lip, xfs_lsn_t lsn) { + struct xfs_efi_log_item *efip = EFI_ITEM(lip); + + set_bit(XFS_EFI_COMMITTED, &efip->efi_flags); return lsn; } @@ -228,6 +253,7 @@ xfs_efi_init( xfs_log_item_init(mp, &efip->efi_item, XFS_LI_EFI, &xfs_efi_item_ops); efip->efi_format.efi_nextents = nextents; efip->efi_format.efi_id = (__psint_t)(void*)efip; + atomic_set(&efip->efi_next_extent, 0); return efip; } @@ -287,37 +313,18 @@ xfs_efi_copy_format(xfs_log_iovec_t *buf, xfs_efi_log_format_t *dst_efi_fmt) } /* - * This is called by the efd item code below to release references to - * the given efi item. Each efd calls this with the number of - * extents that it has logged, and when the sum of these reaches - * the total number of extents logged by this efi item we can free - * the efi item. - * - * Freeing the efi item requires that we remove it from the AIL. - * We'll use the AIL lock to protect our counters as well as - * the removal from the AIL. + * This is called by the efd item code below to release references to the given + * efi item. Each efd calls this with the number of extents that it has + * logged, and when the sum of these reaches the total number of extents logged + * by this efi item we can free the efi item. */ void xfs_efi_release(xfs_efi_log_item_t *efip, uint nextents) { - struct xfs_ail *ailp = efip->efi_item.li_ailp; - int extents_left; - - ASSERT(efip->efi_next_extent > 0); - ASSERT(efip->efi_flags & XFS_EFI_COMMITTED); - - spin_lock(&ailp->xa_lock); - ASSERT(efip->efi_next_extent >= nextents); - efip->efi_next_extent -= nextents; - extents_left = efip->efi_next_extent; - if (extents_left == 0) { - /* xfs_trans_ail_delete() drops the AIL lock. */ - xfs_trans_ail_delete(ailp, (xfs_log_item_t *)efip); - xfs_efi_item_free(efip); - } else { - spin_unlock(&ailp->xa_lock); - } + ASSERT(atomic_read(&efip->efi_next_extent) >= nextents); + if (atomic_sub_and_test(nextents, &efip->efi_next_extent)) + __xfs_efi_release(efip); } static inline struct xfs_efd_log_item *EFD_ITEM(struct xfs_log_item *lip) diff --git a/fs/xfs/xfs_extfree_item.h b/fs/xfs/xfs_extfree_item.h index f7834ec8efad..375f68e42531 100644 --- a/fs/xfs/xfs_extfree_item.h +++ b/fs/xfs/xfs_extfree_item.h @@ -111,10 +111,10 @@ typedef struct xfs_efd_log_format_64 { #define XFS_EFI_MAX_FAST_EXTENTS 16 /* - * Define EFI flags. + * Define EFI flag bits. Manipulated by set/clear/test_bit operators. */ -#define XFS_EFI_RECOVERED 0x1 -#define XFS_EFI_COMMITTED 0x2 +#define XFS_EFI_RECOVERED 1 +#define XFS_EFI_COMMITTED 2 /* * This is the "extent free intention" log item. It is used @@ -124,8 +124,8 @@ typedef struct xfs_efd_log_format_64 { */ typedef struct xfs_efi_log_item { xfs_log_item_t efi_item; - uint efi_flags; /* misc flags */ - uint efi_next_extent; + atomic_t efi_next_extent; + unsigned long efi_flags; /* misc flags */ xfs_efi_log_format_t efi_format; } xfs_efi_log_item_t; diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index 4ab4f6ff48aa..d7219e29d9ab 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c @@ -2567,8 +2567,7 @@ xlog_recover_efi_pass2( xfs_efi_item_free(efip); return error; } - efip->efi_next_extent = efi_formatp->efi_nextents; - efip->efi_flags |= XFS_EFI_COMMITTED; + atomic_set(&efip->efi_next_extent, efi_formatp->efi_nextents); spin_lock(&log->l_ailp->xa_lock); /* @@ -2878,7 +2877,7 @@ xlog_recover_process_efi( xfs_extent_t *extp; xfs_fsblock_t startblock_fsb; - ASSERT(!(efip->efi_flags & XFS_EFI_RECOVERED)); + ASSERT(!test_bit(XFS_EFI_RECOVERED, &efip->efi_flags)); /* * First check the validity of the extents described by the @@ -2917,7 +2916,7 @@ xlog_recover_process_efi( extp->ext_len); } - efip->efi_flags |= XFS_EFI_RECOVERED; + set_bit(XFS_EFI_RECOVERED, &efip->efi_flags); error = xfs_trans_commit(tp, 0); return error; @@ -2974,7 +2973,7 @@ xlog_recover_process_efis( * Skip EFIs that we've already processed. */ efip = (xfs_efi_log_item_t *)lip; - if (efip->efi_flags & XFS_EFI_RECOVERED) { + if (test_bit(XFS_EFI_RECOVERED, &efip->efi_flags)) { lip = xfs_trans_ail_cursor_next(ailp, &cur); continue; } diff --git a/fs/xfs/xfs_trans_extfree.c b/fs/xfs/xfs_trans_extfree.c index f783d5e9fa70..f7590f5badea 100644 --- a/fs/xfs/xfs_trans_extfree.c +++ b/fs/xfs/xfs_trans_extfree.c @@ -69,12 +69,16 @@ xfs_trans_log_efi_extent(xfs_trans_t *tp, tp->t_flags |= XFS_TRANS_DIRTY; efip->efi_item.li_desc->lid_flags |= XFS_LID_DIRTY; - next_extent = efip->efi_next_extent; + /* + * atomic_inc_return gives us the value after the increment; + * we want to use it as an array index so we need to subtract 1 from + * it. + */ + next_extent = atomic_inc_return(&efip->efi_next_extent) - 1; ASSERT(next_extent < efip->efi_format.efi_nextents); extp = &(efip->efi_format.efi_extents[next_extent]); extp->ext_start = start_block; extp->ext_len = ext_len; - efip->efi_next_extent++; } -- cgit v1.2.3 From eb3efa1249b6413be930bdf13d10b6238028a440 Mon Sep 17 00:00:00 2001 From: Dave Chinner Date: Fri, 3 Dec 2010 16:42:57 +1100 Subject: xfs: clean up xfs_ail_delete() xfs_ail_delete() has a needlessly complex interface. It returns the log item that was passed in for deletion (which the callers then assert is identical to the one passed in), and callers of xfs_ail_delete() still need to invalidate current traversal cursors. Make xfs_ail_delete() return void, move the cursor invalidation inside it, and clean up the callers just to use the log item pointer they passed in. While cleaning up, remove the messy and unnecessary "/* ARGUSED */" comments around all these functions. Signed-off-by: Dave Chinner Reviewed-by: Christoph Hellwig --- fs/xfs/xfs_trans_ail.c | 27 +++++++-------------------- 1 file changed, 7 insertions(+), 20 deletions(-) diff --git a/fs/xfs/xfs_trans_ail.c b/fs/xfs/xfs_trans_ail.c index dc9069568ff7..645928cab42d 100644 --- a/fs/xfs/xfs_trans_ail.c +++ b/fs/xfs/xfs_trans_ail.c @@ -29,7 +29,7 @@ #include "xfs_error.h" STATIC void xfs_ail_insert(struct xfs_ail *, xfs_log_item_t *); -STATIC xfs_log_item_t * xfs_ail_delete(struct xfs_ail *, xfs_log_item_t *); +STATIC void xfs_ail_delete(struct xfs_ail *, xfs_log_item_t *); STATIC xfs_log_item_t * xfs_ail_min(struct xfs_ail *); STATIC xfs_log_item_t * xfs_ail_next(struct xfs_ail *, xfs_log_item_t *); @@ -468,16 +468,13 @@ xfs_trans_ail_update( xfs_log_item_t *lip, xfs_lsn_t lsn) __releases(ailp->xa_lock) { - xfs_log_item_t *dlip = NULL; xfs_log_item_t *mlip; /* ptr to minimum lip */ xfs_lsn_t tail_lsn; mlip = xfs_ail_min(ailp); if (lip->li_flags & XFS_LI_IN_AIL) { - dlip = xfs_ail_delete(ailp, lip); - ASSERT(dlip == lip); - xfs_trans_ail_cursor_clear(ailp, dlip); + xfs_ail_delete(ailp, lip); } else { lip->li_flags |= XFS_LI_IN_AIL; } @@ -485,7 +482,7 @@ xfs_trans_ail_update( lip->li_lsn = lsn; xfs_ail_insert(ailp, lip); - if (mlip == dlip) { + if (mlip == lip) { mlip = xfs_ail_min(ailp); /* * It is not safe to access mlip after the AIL lock is @@ -524,21 +521,18 @@ xfs_trans_ail_delete( struct xfs_ail *ailp, xfs_log_item_t *lip) __releases(ailp->xa_lock) { - xfs_log_item_t *dlip; xfs_log_item_t *mlip; xfs_lsn_t tail_lsn; if (lip->li_flags & XFS_LI_IN_AIL) { mlip = xfs_ail_min(ailp); - dlip = xfs_ail_delete(ailp, lip); - ASSERT(dlip == lip); - xfs_trans_ail_cursor_clear(ailp, dlip); + xfs_ail_delete(ailp, lip); lip->li_flags &= ~XFS_LI_IN_AIL; lip->li_lsn = 0; - if (mlip == dlip) { + if (mlip == lip) { mlip = xfs_ail_min(ailp); /* * It is not safe to access mlip after the AIL lock @@ -632,7 +626,6 @@ STATIC void xfs_ail_insert( struct xfs_ail *ailp, xfs_log_item_t *lip) -/* ARGSUSED */ { xfs_log_item_t *next_lip; @@ -661,18 +654,14 @@ xfs_ail_insert( /* * Delete the given item from the AIL. Return a pointer to the item. */ -/*ARGSUSED*/ -STATIC xfs_log_item_t * +STATIC void xfs_ail_delete( struct xfs_ail *ailp, xfs_log_item_t *lip) -/* ARGSUSED */ { xfs_ail_check(ailp, lip); - list_del(&lip->li_ail); - - return lip; + xfs_trans_ail_cursor_clear(ailp, lip); } /* @@ -682,7 +671,6 @@ xfs_ail_delete( STATIC xfs_log_item_t * xfs_ail_min( struct xfs_ail *ailp) -/* ARGSUSED */ { if (list_empty(&ailp->xa_ail)) return NULL; @@ -699,7 +687,6 @@ STATIC xfs_log_item_t * xfs_ail_next( struct xfs_ail *ailp, xfs_log_item_t *lip) -/* ARGSUSED */ { if (lip->li_ail.next == &ailp->xa_ail) return NULL; -- cgit v1.2.3 From f689b34bfbd2154a8fa255060dd872a6db3b4742 Mon Sep 17 00:00:00 2001 From: Miloslav TrmaÄ Date: Fri, 3 Dec 2010 13:51:52 +0800 Subject: include: Install linux/if_alg.h for user-space crypto API MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Miloslav TrmaÄ Signed-off-by: Herbert Xu --- include/linux/Kbuild | 1 + 1 file changed, 1 insertion(+) diff --git a/include/linux/Kbuild b/include/linux/Kbuild index 831c4634162c..b3cca8c88e86 100644 --- a/include/linux/Kbuild +++ b/include/linux/Kbuild @@ -154,6 +154,7 @@ header-y += icmpv6.h header-y += if.h header-y += if_addr.h header-y += if_addrlabel.h +header-y += if_alg.h header-y += if_arcnet.h header-y += if_arp.h header-y += if_bonding.h -- cgit v1.2.3 From 0e57f6a36f9be03e5abb755f524ee91c4aebe854 Mon Sep 17 00:00:00 2001 From: Dave Chinner Date: Mon, 20 Dec 2010 12:02:19 +1100 Subject: xfs: bulk AIL insertion during transaction commit When inserting items into the AIL from the transaction committed callbacks, we take the AIL lock for every single item that is to be inserted. For a CIL checkpoint commit, this can be tens of thousands of individual inserts, yet almost all of the items will be inserted at the same point in the AIL because they have the same index. To reduce the overhead and contention on the AIL lock for such operations, introduce a "bulk insert" operation which allows a list of log items with the same LSN to be inserted in a single operation via a list splice. To do this, we need to pre-sort the log items being committed into a temporary list for insertion. The complexity is that not every log item will end up with the same LSN, and not every item is actually inserted into the AIL. Items that don't match the commit LSN will be inserted and unpinned as per the current one-at-a-time method (relatively rare), while items that are not to be inserted will be unpinned and freed immediately. Items that are to be inserted at the given commit lsn are placed in a temporary array and inserted into the AIL in bulk each time the array fills up. As a result of this, we trade off AIL hold time for a significant reduction in traffic. lock_stat output shows that the worst case hold time is unchanged, but contention from AIL inserts drops by an order of magnitude and the number of lock traversal decreases significantly. Signed-off-by: Dave Chinner Reviewed-by: Christoph Hellwig --- fs/xfs/xfs_log_cil.c | 9 +--- fs/xfs/xfs_trans.c | 79 ++++++++++++++++++++++++++++++++++- fs/xfs/xfs_trans_ail.c | 109 +++++++++++++++++++++++++++++++++++++++++++++++- fs/xfs/xfs_trans_priv.h | 10 ++++- 4 files changed, 195 insertions(+), 12 deletions(-) diff --git a/fs/xfs/xfs_log_cil.c b/fs/xfs/xfs_log_cil.c index 23d6ceb5e97b..f36f1a2f4dc1 100644 --- a/fs/xfs/xfs_log_cil.c +++ b/fs/xfs/xfs_log_cil.c @@ -361,15 +361,10 @@ xlog_cil_committed( int abort) { struct xfs_cil_ctx *ctx = args; - struct xfs_log_vec *lv; - int abortflag = abort ? XFS_LI_ABORTED : 0; struct xfs_busy_extent *busyp, *n; - /* unpin all the log items */ - for (lv = ctx->lv_chain; lv; lv = lv->lv_next ) { - xfs_trans_item_committed(lv->lv_item, ctx->start_lsn, - abortflag); - } + xfs_trans_committed_bulk(ctx->cil->xc_log->l_ailp, ctx->lv_chain, + ctx->start_lsn, abort); list_for_each_entry_safe(busyp, n, &ctx->busy_extents, list) xfs_alloc_busy_clear(ctx->cil->xc_log->l_mp, busyp); diff --git a/fs/xfs/xfs_trans.c b/fs/xfs/xfs_trans.c index f6d956b7711e..f80a067a4658 100644 --- a/fs/xfs/xfs_trans.c +++ b/fs/xfs/xfs_trans.c @@ -1350,7 +1350,7 @@ xfs_trans_fill_vecs( * they could be immediately flushed and we'd have to race with the flusher * trying to pull the item from the AIL as we add it. */ -void +static void xfs_trans_item_committed( struct xfs_log_item *lip, xfs_lsn_t commit_lsn, @@ -1425,6 +1425,83 @@ xfs_trans_committed( xfs_trans_free(tp); } +static inline void +xfs_log_item_batch_insert( + struct xfs_ail *ailp, + struct xfs_log_item **log_items, + int nr_items, + xfs_lsn_t commit_lsn) +{ + int i; + + spin_lock(&ailp->xa_lock); + /* xfs_trans_ail_update_bulk drops ailp->xa_lock */ + xfs_trans_ail_update_bulk(ailp, log_items, nr_items, commit_lsn); + + for (i = 0; i < nr_items; i++) + IOP_UNPIN(log_items[i], 0); +} + +/* + * Bulk operation version of xfs_trans_committed that takes a log vector of + * items to insert into the AIL. This uses bulk AIL insertion techniques to + * minimise lock traffic. + */ +void +xfs_trans_committed_bulk( + struct xfs_ail *ailp, + struct xfs_log_vec *log_vector, + xfs_lsn_t commit_lsn, + int aborted) +{ +#define LOG_ITEM_BATCH_SIZE 32 + struct xfs_log_item *log_items[LOG_ITEM_BATCH_SIZE]; + struct xfs_log_vec *lv; + int i = 0; + + /* unpin all the log items */ + for (lv = log_vector; lv; lv = lv->lv_next ) { + struct xfs_log_item *lip = lv->lv_item; + xfs_lsn_t item_lsn; + + if (aborted) + lip->li_flags |= XFS_LI_ABORTED; + item_lsn = IOP_COMMITTED(lip, commit_lsn); + + /* item_lsn of -1 means the item was freed */ + if (XFS_LSN_CMP(item_lsn, (xfs_lsn_t)-1) == 0) + continue; + + if (item_lsn != commit_lsn) { + + /* + * Not a bulk update option due to unusual item_lsn. + * Push into AIL immediately, rechecking the lsn once + * we have the ail lock. Then unpin the item. + */ + spin_lock(&ailp->xa_lock); + if (XFS_LSN_CMP(item_lsn, lip->li_lsn) > 0) + xfs_trans_ail_update(ailp, lip, item_lsn); + else + spin_unlock(&ailp->xa_lock); + IOP_UNPIN(lip, 0); + continue; + } + + /* Item is a candidate for bulk AIL insert. */ + log_items[i++] = lv->lv_item; + if (i >= LOG_ITEM_BATCH_SIZE) { + xfs_log_item_batch_insert(ailp, log_items, + LOG_ITEM_BATCH_SIZE, commit_lsn); + i = 0; + } + } + + /* make sure we insert the remainder! */ + if (i) + xfs_log_item_batch_insert(ailp, log_items, i, commit_lsn); +} + /* * Called from the trans_commit code when we notice that * the filesystem is in the middle of a forced shutdown. diff --git a/fs/xfs/xfs_trans_ail.c b/fs/xfs/xfs_trans_ail.c index 645928cab42d..fe991a76bf14 100644 --- a/fs/xfs/xfs_trans_ail.c +++ b/fs/xfs/xfs_trans_ail.c @@ -29,6 +29,7 @@ #include "xfs_error.h" STATIC void xfs_ail_insert(struct xfs_ail *, xfs_log_item_t *); +STATIC void xfs_ail_splice(struct xfs_ail *, struct list_head *, xfs_lsn_t); STATIC void xfs_ail_delete(struct xfs_ail *, xfs_log_item_t *); STATIC xfs_log_item_t * xfs_ail_min(struct xfs_ail *); STATIC xfs_log_item_t * xfs_ail_next(struct xfs_ail *, xfs_log_item_t *); @@ -501,6 +502,79 @@ xfs_trans_ail_update( } /* xfs_trans_update_ail */ +/* + * xfs_trans_ail_update - bulk AIL insertion operation. + * + * @xfs_trans_ail_update takes an array of log items that all need to be + * positioned at the same LSN in the AIL. If an item is not in the AIL, it will + * be added. Otherwise, it will be repositioned by removing it and re-adding + * it to the AIL. If we move the first item in the AIL, update the log tail to + * match the new minimum LSN in the AIL. + * + * This function takes the AIL lock once to execute the update operations on + * all the items in the array, and as such should not be called with the AIL + * lock held. As a result, once we have the AIL lock, we need to check each log + * item LSN to confirm it needs to be moved forward in the AIL. + * + * To optimise the insert operation, we delete all the items from the AIL in + * the first pass, moving them into a temporary list, then splice the temporary + * list into the correct position in the AIL. This avoids needing to do an + * insert operation on every item. + * + * This function must be called with the AIL lock held. The lock is dropped + * before returning. + */ +void +xfs_trans_ail_update_bulk( + struct xfs_ail *ailp, + struct xfs_log_item **log_items, + int nr_items, + xfs_lsn_t lsn) __releases(ailp->xa_lock) +{ + xfs_log_item_t *mlip; + xfs_lsn_t tail_lsn; + int mlip_changed = 0; + int i; + LIST_HEAD(tmp); + + mlip = xfs_ail_min(ailp); + + for (i = 0; i < nr_items; i++) { + struct xfs_log_item *lip = log_items[i]; + if (lip->li_flags & XFS_LI_IN_AIL) { + /* check if we really need to move the item */ + if (XFS_LSN_CMP(lsn, lip->li_lsn) <= 0) + continue; + + xfs_ail_delete(ailp, lip); + if (mlip == lip) + mlip_changed = 1; + } else { + lip->li_flags |= XFS_LI_IN_AIL; + } + lip->li_lsn = lsn; + list_add(&lip->li_ail, &tmp); + } + + xfs_ail_splice(ailp, &tmp, lsn); + + if (!mlip_changed) { + spin_unlock(&ailp->xa_lock); + return; + } + + /* + * It is not safe to access mlip after the AIL lock is dropped, so we + * must get a copy of li_lsn before we do so. This is especially + * important on 32-bit platforms where accessing and updating 64-bit + * values like li_lsn is not atomic. + */ + mlip = xfs_ail_min(ailp); + tail_lsn = mlip->li_lsn; + spin_unlock(&ailp->xa_lock); + xfs_log_move_tail(ailp->xa_mount, tail_lsn); +} + /* * Delete the given item from the AIL. It must already be in * the AIL. @@ -642,8 +716,8 @@ xfs_ail_insert( break; } - ASSERT((&next_lip->li_ail == &ailp->xa_ail) || - (XFS_LSN_CMP(next_lip->li_lsn, lip->li_lsn) <= 0)); + ASSERT(&next_lip->li_ail == &ailp->xa_ail || + XFS_LSN_CMP(next_lip->li_lsn, lip->li_lsn) <= 0); list_add(&lip->li_ail, &next_lip->li_ail); @@ -651,6 +725,37 @@ xfs_ail_insert( return; } +/* + * splice the log item list into the AIL at the given LSN. + */ +STATIC void +xfs_ail_splice( + struct xfs_ail *ailp, + struct list_head *list, + xfs_lsn_t lsn) +{ + xfs_log_item_t *next_lip; + + /* + * If the list is empty, just insert the item. + */ + if (list_empty(&ailp->xa_ail)) { + list_splice(list, &ailp->xa_ail); + return; + } + + list_for_each_entry_reverse(next_lip, &ailp->xa_ail, li_ail) { + if (XFS_LSN_CMP(next_lip->li_lsn, lsn) <= 0) + break; + } + + ASSERT((&next_lip->li_ail == &ailp->xa_ail) || + (XFS_LSN_CMP(next_lip->li_lsn, lsn) <= 0)); + + list_splice_init(list, &next_lip->li_ail); + return; +} + /* * Delete the given item from the AIL. Return a pointer to the item. */ diff --git a/fs/xfs/xfs_trans_priv.h b/fs/xfs/xfs_trans_priv.h index 62da86c90de5..e039729186e9 100644 --- a/fs/xfs/xfs_trans_priv.h +++ b/fs/xfs/xfs_trans_priv.h @@ -22,15 +22,17 @@ struct xfs_log_item; struct xfs_log_item_desc; struct xfs_mount; struct xfs_trans; +struct xfs_ail; +struct xfs_log_vec; void xfs_trans_add_item(struct xfs_trans *, struct xfs_log_item *); void xfs_trans_del_item(struct xfs_log_item *); void xfs_trans_free_items(struct xfs_trans *tp, xfs_lsn_t commit_lsn, int flags); -void xfs_trans_item_committed(struct xfs_log_item *lip, - xfs_lsn_t commit_lsn, int aborted); void xfs_trans_unreserve_and_mod_sb(struct xfs_trans *tp); +void xfs_trans_committed_bulk(struct xfs_ail *ailp, struct xfs_log_vec *lv, + xfs_lsn_t commit_lsn, int aborted); /* * AIL traversal cursor. * @@ -76,6 +78,10 @@ struct xfs_ail { void xfs_trans_ail_update(struct xfs_ail *ailp, struct xfs_log_item *lip, xfs_lsn_t lsn) __releases(ailp->xa_lock); +void xfs_trans_ail_update_bulk(struct xfs_ail *ailp, + struct xfs_log_item **log_items, + int nr_items, xfs_lsn_t lsn) + __releases(ailp->xa_lock); void xfs_trans_ail_delete(struct xfs_ail *ailp, struct xfs_log_item *lip) __releases(ailp->xa_lock); -- cgit v1.2.3 From e677d0f9548e2245ee3c2977661ca8ca165af188 Mon Sep 17 00:00:00 2001 From: Dave Chinner Date: Fri, 17 Dec 2010 20:08:04 +1100 Subject: xfs: reduce the number of AIL push wakeups The xfaild often tries to rest to wait for congestion to pass of for IO to complete, but is regularly woken in tail-pushing situations. In severe cases, the xfsaild is getting woken tens of thousands of times a second. Reduce the number needless wakeups by only waking the xfsaild if the new target is larger than the old one. Further make short sleeps uninterruptible as they occur when the xfsaild has decided it needs to back off to allow some IO to complete and being woken early is counter-productive. Signed-off-by: Dave Chinner Reviewed-by: Christoph Hellwig --- fs/xfs/linux-2.6/xfs_super.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/fs/xfs/linux-2.6/xfs_super.c b/fs/xfs/linux-2.6/xfs_super.c index c45b3233d486..c51faaa5e291 100644 --- a/fs/xfs/linux-2.6/xfs_super.c +++ b/fs/xfs/linux-2.6/xfs_super.c @@ -834,8 +834,11 @@ xfsaild_wakeup( struct xfs_ail *ailp, xfs_lsn_t threshold_lsn) { - ailp->xa_target = threshold_lsn; - wake_up_process(ailp->xa_task); + /* only ever move the target forwards */ + if (XFS_LSN_CMP(threshold_lsn, ailp->xa_target) > 0) { + ailp->xa_target = threshold_lsn; + wake_up_process(ailp->xa_task); + } } STATIC int @@ -847,8 +850,17 @@ xfsaild( long tout = 0; /* milliseconds */ while (!kthread_should_stop()) { - schedule_timeout_interruptible(tout ? - msecs_to_jiffies(tout) : MAX_SCHEDULE_TIMEOUT); + /* + * for short sleeps indicating congestion, don't allow us to + * get woken early. Otherwise all we do is bang on the AIL lock + * without making progress. + */ + if (tout && tout <= 20) + __set_current_state(TASK_KILLABLE); + else + __set_current_state(TASK_INTERRUPTIBLE); + schedule_timeout(tout ? + msecs_to_jiffies(tout) : MAX_SCHEDULE_TIMEOUT); /* swsusp */ try_to_freeze(); -- cgit v1.2.3 From c90821a26a8c90ad1e3116393b8a8260ab46bffb Mon Sep 17 00:00:00 2001 From: Dave Chinner Date: Fri, 3 Dec 2010 17:00:52 +1100 Subject: xfs: consume iodone callback items on buffers as they are processed To allow buffer iodone callbacks to consume multiple items off the callback list, first we need to convert the xfs_buf_do_callbacks() to consume items and always pull the next item from the head of the list. The means the item list walk is never dependent on knowing the next item on the list and hence allows callbacks to remove items from the list as well. This allows callbacks to do bulk operations by scanning the list for identical callbacks, consuming them all and then processing them in bulk, negating the need for multiple callbacks of that type. Signed-off-by: Dave Chinner Reviewed-by: Christoph Hellwig --- fs/xfs/xfs_buf_item.c | 32 +++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/fs/xfs/xfs_buf_item.c b/fs/xfs/xfs_buf_item.c index 2686d0d54c5b..ed2b65f3f8b9 100644 --- a/fs/xfs/xfs_buf_item.c +++ b/fs/xfs/xfs_buf_item.c @@ -142,7 +142,7 @@ xfs_buf_item_log_check( #endif STATIC void xfs_buf_error_relse(xfs_buf_t *bp); -STATIC void xfs_buf_do_callbacks(xfs_buf_t *bp, xfs_log_item_t *lip); +STATIC void xfs_buf_do_callbacks(struct xfs_buf *bp); /* * This returns the number of log iovecs needed to log the @@ -450,7 +450,7 @@ xfs_buf_item_unpin( * xfs_trans_ail_delete() drops the AIL lock. */ if (bip->bli_flags & XFS_BLI_STALE_INODE) { - xfs_buf_do_callbacks(bp, (xfs_log_item_t *)bip); + xfs_buf_do_callbacks(bp); XFS_BUF_SET_FSPRIVATE(bp, NULL); XFS_BUF_CLR_IODONE_FUNC(bp); } else { @@ -918,15 +918,26 @@ xfs_buf_attach_iodone( XFS_BUF_SET_IODONE_FUNC(bp, xfs_buf_iodone_callbacks); } +/* + * We can have many callbacks on a buffer. Running the callbacks individually + * can cause a lot of contention on the AIL lock, so we allow for a single + * callback to be able to scan the remaining lip->li_bio_list for other items + * of the same type and callback to be processed in the first call. + * + * As a result, the loop walking the callback list below will also modify the + * list. it removes the first item from the list and then runs the callback. + * The loop then restarts from the new head of the list. This allows the + * callback to scan and modify the list attached to the buffer and we don't + * have to care about maintaining a next item pointer. + */ STATIC void xfs_buf_do_callbacks( - xfs_buf_t *bp, - xfs_log_item_t *lip) + struct xfs_buf *bp) { - xfs_log_item_t *nlip; + struct xfs_log_item *lip; - while (lip != NULL) { - nlip = lip->li_bio_list; + while ((lip = XFS_BUF_FSPRIVATE(bp, xfs_log_item_t *)) != NULL) { + XFS_BUF_SET_FSPRIVATE(bp, lip->li_bio_list); ASSERT(lip->li_cb != NULL); /* * Clear the next pointer so we don't have any @@ -936,7 +947,6 @@ xfs_buf_do_callbacks( */ lip->li_bio_list = NULL; lip->li_cb(bp, lip); - lip = nlip; } } @@ -970,7 +980,7 @@ xfs_buf_iodone_callbacks( ASSERT(XFS_BUF_TARGET(bp) == mp->m_ddev_targp); XFS_BUF_SUPER_STALE(bp); trace_xfs_buf_item_iodone(bp, _RET_IP_); - xfs_buf_do_callbacks(bp, lip); + xfs_buf_do_callbacks(bp); XFS_BUF_SET_FSPRIVATE(bp, NULL); XFS_BUF_CLR_IODONE_FUNC(bp); xfs_buf_ioend(bp, 0); @@ -1029,7 +1039,7 @@ xfs_buf_iodone_callbacks( return; } - xfs_buf_do_callbacks(bp, lip); + xfs_buf_do_callbacks(bp); XFS_BUF_SET_FSPRIVATE(bp, NULL); XFS_BUF_CLR_IODONE_FUNC(bp); xfs_buf_ioend(bp, 0); @@ -1063,7 +1073,7 @@ xfs_buf_error_relse( * We have to unpin the pinned buffers so do the * callbacks. */ - xfs_buf_do_callbacks(bp, lip); + xfs_buf_do_callbacks(bp); XFS_BUF_SET_FSPRIVATE(bp, NULL); XFS_BUF_CLR_IODONE_FUNC(bp); XFS_BUF_SET_BRELSE_FUNC(bp,NULL); -- cgit v1.2.3 From 66bde0b70aa2e348ac2c9b9626743c1402b9d466 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Thu, 28 Oct 2010 15:41:56 +0200 Subject: dma/intel_mid_dma: remove unneeded null check Smatch complains because we dereference "mid" before checking it. It turns out that "mid" is always a valid pointer here so we can just remove the check. Signed-off-by: Dan Carpenter Signed-off-by: Dan Williams --- drivers/dma/intel_mid_dma.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/drivers/dma/intel_mid_dma.c b/drivers/dma/intel_mid_dma.c index 338bc4eed1f3..41941d05bfb9 100644 --- a/drivers/dma/intel_mid_dma.c +++ b/drivers/dma/intel_mid_dma.c @@ -1021,11 +1021,6 @@ static irqreturn_t intel_mid_dma_interrupt(int irq, void *data) /*DMA Interrupt*/ pr_debug("MDMA:Got an interrupt on irq %d\n", irq); - if (!mid) { - pr_err("ERR_MDMA:null pointer mid\n"); - return -EINVAL; - } - pr_debug("MDMA: Status %x, Mask %x\n", tfr_status, mid->intr_mask); tfr_status &= mid->intr_mask; if (tfr_status) { -- cgit v1.2.3 From 3013683253ad04f67d8cfaa25be708353686b90a Mon Sep 17 00:00:00 2001 From: Dave Chinner Date: Mon, 20 Dec 2010 12:03:17 +1100 Subject: xfs: remove all the inodes on a buffer from the AIL in bulk When inode buffer IO completes, usually all of the inodes are removed from the AIL. This involves processing them one at a time and taking the AIL lock once for every inode. When all CPUs are processing inode IO completions, this causes excessive amount sof contention on the AIL lock. Instead, change the way we process inode IO completion in the buffer IO done callback. Allow the inode IO done callback to walk the list of IO done callbacks and pull all the inodes off the buffer in one go and then process them as a batch. Once all the inodes for removal are collected, take the AIL lock once and do a bulk removal operation to minimise traffic on the AIL lock. Signed-off-by: Dave Chinner Reviewed-by: Christoph Hellwig --- fs/xfs/xfs_inode_item.c | 90 ++++++++++++++++++++++++++++++++++++++++--------- fs/xfs/xfs_trans_ail.c | 73 +++++++++++++++++++++++++++++++++++++++ fs/xfs/xfs_trans_priv.h | 4 +++ 3 files changed, 151 insertions(+), 16 deletions(-) diff --git a/fs/xfs/xfs_inode_item.c b/fs/xfs/xfs_inode_item.c index 7c8d30c453c3..fd4f398bd6f1 100644 --- a/fs/xfs/xfs_inode_item.c +++ b/fs/xfs/xfs_inode_item.c @@ -842,15 +842,64 @@ xfs_inode_item_destroy( * flushed to disk. It is responsible for removing the inode item * from the AIL if it has not been re-logged, and unlocking the inode's * flush lock. + * + * To reduce AIL lock traffic as much as possible, we scan the buffer log item + * list for other inodes that will run this function. We remove them from the + * buffer list so we can process all the inode IO completions in one AIL lock + * traversal. */ void xfs_iflush_done( struct xfs_buf *bp, struct xfs_log_item *lip) { - struct xfs_inode_log_item *iip = INODE_ITEM(lip); - xfs_inode_t *ip = iip->ili_inode; + struct xfs_inode_log_item *iip; + struct xfs_log_item *blip; + struct xfs_log_item *next; + struct xfs_log_item *prev; struct xfs_ail *ailp = lip->li_ailp; + int need_ail = 0; + + /* + * Scan the buffer IO completions for other inodes being completed and + * attach them to the current inode log item. + */ + blip = XFS_BUF_FSPRIVATE(bp, xfs_log_item_t *); + prev = NULL; + while (blip != NULL) { + if (lip->li_cb != xfs_iflush_done) { + prev = blip; + blip = blip->li_bio_list; + continue; + } + + /* remove from list */ + next = blip->li_bio_list; + if (!prev) { + XFS_BUF_SET_FSPRIVATE(bp, next); + } else { + prev->li_bio_list = next; + } + + /* add to current list */ + blip->li_bio_list = lip->li_bio_list; + lip->li_bio_list = blip; + + /* + * while we have the item, do the unlocked check for needing + * the AIL lock. + */ + iip = INODE_ITEM(blip); + if (iip->ili_logged && blip->li_lsn == iip->ili_flush_lsn) + need_ail++; + + blip = next; + } + + /* make sure we capture the state of the initial inode. */ + iip = INODE_ITEM(lip); + if (iip->ili_logged && lip->li_lsn == iip->ili_flush_lsn) + need_ail++; /* * We only want to pull the item from the AIL if it is @@ -861,28 +910,37 @@ xfs_iflush_done( * the lock since it's cheaper, and then we recheck while * holding the lock before removing the inode from the AIL. */ - if (iip->ili_logged && lip->li_lsn == iip->ili_flush_lsn) { + if (need_ail) { + struct xfs_log_item *log_items[need_ail]; + int i = 0; spin_lock(&ailp->xa_lock); - if (lip->li_lsn == iip->ili_flush_lsn) { - /* xfs_trans_ail_delete() drops the AIL lock. */ - xfs_trans_ail_delete(ailp, lip); - } else { - spin_unlock(&ailp->xa_lock); + for (blip = lip; blip; blip = blip->li_bio_list) { + iip = INODE_ITEM(blip); + if (iip->ili_logged && + blip->li_lsn == iip->ili_flush_lsn) { + log_items[i++] = blip; + } + ASSERT(i <= need_ail); } + /* xfs_trans_ail_delete_bulk() drops the AIL lock. */ + xfs_trans_ail_delete_bulk(ailp, log_items, i); } - iip->ili_logged = 0; /* - * Clear the ili_last_fields bits now that we know that the - * data corresponding to them is safely on disk. + * clean up and unlock the flush lock now we are done. We can clear the + * ili_last_fields bits now that we know that the data corresponding to + * them is safely on disk. */ - iip->ili_last_fields = 0; + for (blip = lip; blip; blip = next) { + next = blip->li_bio_list; + blip->li_bio_list = NULL; - /* - * Release the inode's flush lock since we're done with it. - */ - xfs_ifunlock(ip); + iip = INODE_ITEM(blip); + iip->ili_logged = 0; + iip->ili_last_fields = 0; + xfs_ifunlock(iip->ili_inode); + } } /* diff --git a/fs/xfs/xfs_trans_ail.c b/fs/xfs/xfs_trans_ail.c index fe991a76bf14..218f96861c80 100644 --- a/fs/xfs/xfs_trans_ail.c +++ b/fs/xfs/xfs_trans_ail.c @@ -639,6 +639,79 @@ xfs_trans_ail_delete( } } +/* + * xfs_trans_ail_delete_bulk - remove multiple log items from the AIL + * + * @xfs_trans_ail_delete_bulk takes an array of log items that all need to + * removed from the AIL. The caller is already holding the AIL lock, and done + * all the checks necessary to ensure the items passed in via @log_items are + * ready for deletion. This includes checking that the items are in the AIL. + * + * For each log item to be removed, unlink it from the AIL, clear the IN_AIL + * flag from the item and reset the item's lsn to 0. If we remove the first + * item in the AIL, update the log tail to match the new minimum LSN in the + * AIL. + * + * This function will not drop the AIL lock until all items are removed from + * the AIL to minimise the amount of lock traffic on the AIL. This does not + * greatly increase the AIL hold time, but does significantly reduce the amount + * of traffic on the lock, especially during IO completion. + * + * This function must be called with the AIL lock held. The lock is dropped + * before returning. + */ +void +xfs_trans_ail_delete_bulk( + struct xfs_ail *ailp, + struct xfs_log_item **log_items, + int nr_items) __releases(ailp->xa_lock) +{ + xfs_log_item_t *mlip; + xfs_lsn_t tail_lsn; + int mlip_changed = 0; + int i; + + mlip = xfs_ail_min(ailp); + + for (i = 0; i < nr_items; i++) { + struct xfs_log_item *lip = log_items[i]; + if (!(lip->li_flags & XFS_LI_IN_AIL)) { + struct xfs_mount *mp = ailp->xa_mount; + + spin_unlock(&ailp->xa_lock); + if (!XFS_FORCED_SHUTDOWN(mp)) { + xfs_cmn_err(XFS_PTAG_AILDELETE, CE_ALERT, mp, + "%s: attempting to delete a log item that is not in the AIL", + __func__); + xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE); + } + return; + } + + xfs_ail_delete(ailp, lip); + lip->li_flags &= ~XFS_LI_IN_AIL; + lip->li_lsn = 0; + if (mlip == lip) + mlip_changed = 1; + } + + if (!mlip_changed) { + spin_unlock(&ailp->xa_lock); + return; + } + + /* + * It is not safe to access mlip after the AIL lock is dropped, so we + * must get a copy of li_lsn before we do so. This is especially + * important on 32-bit platforms where accessing and updating 64-bit + * values like li_lsn is not atomic. It is possible we've emptied the + * AIL here, so if that is the case, pass an LSN of 0 to the tail move. + */ + mlip = xfs_ail_min(ailp); + tail_lsn = mlip ? mlip->li_lsn : 0; + spin_unlock(&ailp->xa_lock); + xfs_log_move_tail(ailp->xa_mount, tail_lsn); +} /* diff --git a/fs/xfs/xfs_trans_priv.h b/fs/xfs/xfs_trans_priv.h index e039729186e9..246ca4dcb5c4 100644 --- a/fs/xfs/xfs_trans_priv.h +++ b/fs/xfs/xfs_trans_priv.h @@ -85,6 +85,10 @@ void xfs_trans_ail_update_bulk(struct xfs_ail *ailp, void xfs_trans_ail_delete(struct xfs_ail *ailp, struct xfs_log_item *lip) __releases(ailp->xa_lock); +void xfs_trans_ail_delete_bulk(struct xfs_ail *ailp, + struct xfs_log_item **log_items, + int nr_items) + __releases(ailp->xa_lock); void xfs_trans_ail_push(struct xfs_ail *, xfs_lsn_t); void xfs_trans_unlocked_item(struct xfs_ail *, xfs_log_item_t *); -- cgit v1.2.3 From e60599492990d1b52c70e9ed2f8e062fe11ca937 Mon Sep 17 00:00:00 2001 From: Dave Chinner Date: Mon, 20 Dec 2010 12:34:26 +1100 Subject: xfs: use AIL bulk update function to implement single updates We now have two copies of AIL insert operations that are mostly duplicate functionality. The single log item updates can be implemented via the bulk updates by turning xfs_trans_ail_update() into a simple wrapper. This removes all the duplicate insert functionality and associated helpers. Signed-off-by: Dave Chinner Reviewed-by: Christoph Hellwig --- fs/xfs/xfs_log_recover.c | 2 +- fs/xfs/xfs_trans_ail.c | 88 ------------------------------------------------ fs/xfs/xfs_trans_priv.h | 19 +++++++---- 3 files changed, 13 insertions(+), 96 deletions(-) diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index d7219e29d9ab..4abe7a9b380e 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c @@ -2573,7 +2573,7 @@ xlog_recover_efi_pass2( /* * xfs_trans_ail_update() drops the AIL lock. */ - xfs_trans_ail_update(log->l_ailp, (xfs_log_item_t *)efip, lsn); + xfs_trans_ail_update(log->l_ailp, &efip->efi_item, lsn); return 0; } diff --git a/fs/xfs/xfs_trans_ail.c b/fs/xfs/xfs_trans_ail.c index 218f96861c80..8481a5a6d6c2 100644 --- a/fs/xfs/xfs_trans_ail.c +++ b/fs/xfs/xfs_trans_ail.c @@ -28,7 +28,6 @@ #include "xfs_trans_priv.h" #include "xfs_error.h" -STATIC void xfs_ail_insert(struct xfs_ail *, xfs_log_item_t *); STATIC void xfs_ail_splice(struct xfs_ail *, struct list_head *, xfs_lsn_t); STATIC void xfs_ail_delete(struct xfs_ail *, xfs_log_item_t *); STATIC xfs_log_item_t * xfs_ail_min(struct xfs_ail *); @@ -450,58 +449,6 @@ xfs_trans_unlocked_item( xfs_log_move_tail(ailp->xa_mount, 1); } /* xfs_trans_unlocked_item */ - -/* - * Update the position of the item in the AIL with the new - * lsn. If it is not yet in the AIL, add it. Otherwise, move - * it to its new position by removing it and re-adding it. - * - * Wakeup anyone with an lsn less than the item's lsn. If the item - * we move in the AIL is the minimum one, update the tail lsn in the - * log manager. - * - * This function must be called with the AIL lock held. The lock - * is dropped before returning. - */ -void -xfs_trans_ail_update( - struct xfs_ail *ailp, - xfs_log_item_t *lip, - xfs_lsn_t lsn) __releases(ailp->xa_lock) -{ - xfs_log_item_t *mlip; /* ptr to minimum lip */ - xfs_lsn_t tail_lsn; - - mlip = xfs_ail_min(ailp); - - if (lip->li_flags & XFS_LI_IN_AIL) { - xfs_ail_delete(ailp, lip); - } else { - lip->li_flags |= XFS_LI_IN_AIL; - } - - lip->li_lsn = lsn; - xfs_ail_insert(ailp, lip); - - if (mlip == lip) { - mlip = xfs_ail_min(ailp); - /* - * It is not safe to access mlip after the AIL lock is - * dropped, so we must get a copy of li_lsn before we do - * so. This is especially important on 32-bit platforms - * where accessing and updating 64-bit values like li_lsn - * is not atomic. - */ - tail_lsn = mlip->li_lsn; - spin_unlock(&ailp->xa_lock); - xfs_log_move_tail(ailp->xa_mount, tail_lsn); - } else { - spin_unlock(&ailp->xa_lock); - } - - -} /* xfs_trans_update_ail */ - /* * xfs_trans_ail_update - bulk AIL insertion operation. * @@ -763,41 +710,6 @@ xfs_trans_ail_destroy( kmem_free(ailp); } -/* - * Insert the given log item into the AIL. - * We almost always insert at the end of the list, so on inserts - * we search from the end of the list to find where the - * new item belongs. - */ -STATIC void -xfs_ail_insert( - struct xfs_ail *ailp, - xfs_log_item_t *lip) -{ - xfs_log_item_t *next_lip; - - /* - * If the list is empty, just insert the item. - */ - if (list_empty(&ailp->xa_ail)) { - list_add(&lip->li_ail, &ailp->xa_ail); - return; - } - - list_for_each_entry_reverse(next_lip, &ailp->xa_ail, li_ail) { - if (XFS_LSN_CMP(next_lip->li_lsn, lip->li_lsn) <= 0) - break; - } - - ASSERT(&next_lip->li_ail == &ailp->xa_ail || - XFS_LSN_CMP(next_lip->li_lsn, lip->li_lsn) <= 0); - - list_add(&lip->li_ail, &next_lip->li_ail); - - xfs_ail_check(ailp, lip); - return; -} - /* * splice the log item list into the AIL at the given LSN. */ diff --git a/fs/xfs/xfs_trans_priv.h b/fs/xfs/xfs_trans_priv.h index 246ca4dcb5c4..f46920589ca5 100644 --- a/fs/xfs/xfs_trans_priv.h +++ b/fs/xfs/xfs_trans_priv.h @@ -75,13 +75,18 @@ struct xfs_ail { /* * From xfs_trans_ail.c */ -void xfs_trans_ail_update(struct xfs_ail *ailp, - struct xfs_log_item *lip, xfs_lsn_t lsn) - __releases(ailp->xa_lock); -void xfs_trans_ail_update_bulk(struct xfs_ail *ailp, - struct xfs_log_item **log_items, - int nr_items, xfs_lsn_t lsn) - __releases(ailp->xa_lock); +void xfs_trans_ail_update_bulk(struct xfs_ail *ailp, + struct xfs_log_item **log_items, int nr_items, + xfs_lsn_t lsn) __releases(ailp->xa_lock); +static inline void +xfs_trans_ail_update( + struct xfs_ail *ailp, + struct xfs_log_item *lip, + xfs_lsn_t lsn) __releases(ailp->xa_lock) +{ + xfs_trans_ail_update_bulk(ailp, &lip, 1, lsn); +} + void xfs_trans_ail_delete(struct xfs_ail *ailp, struct xfs_log_item *lip) __releases(ailp->xa_lock); -- cgit v1.2.3 From 9552e7f2f3dd13a7580e488a7a3582332daad4f5 Mon Sep 17 00:00:00 2001 From: Dave Chinner Date: Mon, 20 Dec 2010 12:36:15 +1100 Subject: xfs: use AIL bulk delete function to implement single delete We now have two copies of AIL delete operations that are mostly duplicate functionality. The single log item deletes can be implemented via the bulk updates by turning xfs_trans_ail_delete() into a simple wrapper. This removes all the duplicate delete functionality and associated helpers. Signed-off-by: Dave Chinner Reviewed-by: Christoph Hellwig --- fs/xfs/xfs_trans_ail.c | 65 ------------------------------------------------- fs/xfs/xfs_trans_priv.h | 18 ++++++++------ 2 files changed, 11 insertions(+), 72 deletions(-) diff --git a/fs/xfs/xfs_trans_ail.c b/fs/xfs/xfs_trans_ail.c index 8481a5a6d6c2..c5bbbc45db91 100644 --- a/fs/xfs/xfs_trans_ail.c +++ b/fs/xfs/xfs_trans_ail.c @@ -522,70 +522,6 @@ xfs_trans_ail_update_bulk( xfs_log_move_tail(ailp->xa_mount, tail_lsn); } -/* - * Delete the given item from the AIL. It must already be in - * the AIL. - * - * Wakeup anyone with an lsn less than item's lsn. If the item - * we delete in the AIL is the minimum one, update the tail lsn in the - * log manager. - * - * Clear the IN_AIL flag from the item, reset its lsn to 0, and - * bump the AIL's generation count to indicate that the tree - * has changed. - * - * This function must be called with the AIL lock held. The lock - * is dropped before returning. - */ -void -xfs_trans_ail_delete( - struct xfs_ail *ailp, - xfs_log_item_t *lip) __releases(ailp->xa_lock) -{ - xfs_log_item_t *mlip; - xfs_lsn_t tail_lsn; - - if (lip->li_flags & XFS_LI_IN_AIL) { - mlip = xfs_ail_min(ailp); - xfs_ail_delete(ailp, lip); - - - lip->li_flags &= ~XFS_LI_IN_AIL; - lip->li_lsn = 0; - - if (mlip == lip) { - mlip = xfs_ail_min(ailp); - /* - * It is not safe to access mlip after the AIL lock - * is dropped, so we must get a copy of li_lsn - * before we do so. This is especially important - * on 32-bit platforms where accessing and updating - * 64-bit values like li_lsn is not atomic. - */ - tail_lsn = mlip ? mlip->li_lsn : 0; - spin_unlock(&ailp->xa_lock); - xfs_log_move_tail(ailp->xa_mount, tail_lsn); - } else { - spin_unlock(&ailp->xa_lock); - } - } - else { - /* - * If the file system is not being shutdown, we are in - * serious trouble if we get to this stage. - */ - struct xfs_mount *mp = ailp->xa_mount; - - spin_unlock(&ailp->xa_lock); - if (!XFS_FORCED_SHUTDOWN(mp)) { - xfs_cmn_err(XFS_PTAG_AILDELETE, CE_ALERT, mp, - "%s: attempting to delete a log item that is not in the AIL", - __func__); - xfs_force_shutdown(mp, SHUTDOWN_CORRUPT_INCORE); - } - } -} - /* * xfs_trans_ail_delete_bulk - remove multiple log items from the AIL * @@ -660,7 +596,6 @@ xfs_trans_ail_delete_bulk( xfs_log_move_tail(ailp->xa_mount, tail_lsn); } - /* * The active item list (AIL) is a doubly linked list of log * items sorted by ascending lsn. The base of the list is diff --git a/fs/xfs/xfs_trans_priv.h b/fs/xfs/xfs_trans_priv.h index f46920589ca5..35162c238fa3 100644 --- a/fs/xfs/xfs_trans_priv.h +++ b/fs/xfs/xfs_trans_priv.h @@ -87,13 +87,17 @@ xfs_trans_ail_update( xfs_trans_ail_update_bulk(ailp, &lip, 1, lsn); } -void xfs_trans_ail_delete(struct xfs_ail *ailp, - struct xfs_log_item *lip) - __releases(ailp->xa_lock); -void xfs_trans_ail_delete_bulk(struct xfs_ail *ailp, - struct xfs_log_item **log_items, - int nr_items) - __releases(ailp->xa_lock); +void xfs_trans_ail_delete_bulk(struct xfs_ail *ailp, + struct xfs_log_item **log_items, int nr_items) + __releases(ailp->xa_lock); +static inline void +xfs_trans_ail_delete( + struct xfs_ail *ailp, + xfs_log_item_t *lip) __releases(ailp->xa_lock) +{ + xfs_trans_ail_delete_bulk(ailp, &lip, 1); +} + void xfs_trans_ail_push(struct xfs_ail *, xfs_lsn_t); void xfs_trans_unlocked_item(struct xfs_ail *, xfs_log_item_t *); -- cgit v1.2.3 From 1054794198e39103cb986618c4c10ec2252b7089 Mon Sep 17 00:00:00 2001 From: Dave Chinner Date: Tue, 21 Dec 2010 12:02:25 +1100 Subject: xfs: convert log grant ticket queues to list heads The grant write and reserve queues use a roll-your-own double linked list, so convert it to a standard list_head structure and convert all the list traversals to use list_for_each_entry(). We can also get rid of the XLOG_TIC_IN_Q flag as we can use the list_empty() check to tell if the ticket is in a list or not. Signed-off-by: Dave Chinner Reviewed-by: Christoph Hellwig --- fs/xfs/linux-2.6/xfs_trace.h | 16 +++--- fs/xfs/xfs_log.c | 123 +++++++++++++++---------------------------- fs/xfs/xfs_log_priv.h | 11 ++-- 3 files changed, 53 insertions(+), 97 deletions(-) diff --git a/fs/xfs/linux-2.6/xfs_trace.h b/fs/xfs/linux-2.6/xfs_trace.h index 83e8760159ef..69b9e1f1baaf 100644 --- a/fs/xfs/linux-2.6/xfs_trace.h +++ b/fs/xfs/linux-2.6/xfs_trace.h @@ -766,8 +766,8 @@ DECLARE_EVENT_CLASS(xfs_loggrant_class, __field(int, curr_res) __field(int, unit_res) __field(unsigned int, flags) - __field(void *, reserve_headq) - __field(void *, write_headq) + __field(int, reserveq) + __field(int, writeq) __field(int, grant_reserve_cycle) __field(int, grant_reserve_bytes) __field(int, grant_write_cycle) @@ -784,8 +784,8 @@ DECLARE_EVENT_CLASS(xfs_loggrant_class, __entry->curr_res = tic->t_curr_res; __entry->unit_res = tic->t_unit_res; __entry->flags = tic->t_flags; - __entry->reserve_headq = log->l_reserve_headq; - __entry->write_headq = log->l_write_headq; + __entry->reserveq = list_empty(&log->l_reserveq); + __entry->writeq = list_empty(&log->l_writeq); __entry->grant_reserve_cycle = log->l_grant_reserve_cycle; __entry->grant_reserve_bytes = log->l_grant_reserve_bytes; __entry->grant_write_cycle = log->l_grant_write_cycle; @@ -795,8 +795,8 @@ DECLARE_EVENT_CLASS(xfs_loggrant_class, __entry->tail_lsn = log->l_tail_lsn; ), TP_printk("dev %d:%d type %s t_ocnt %u t_cnt %u t_curr_res %u " - "t_unit_res %u t_flags %s reserve_headq 0x%p " - "write_headq 0x%p grant_reserve_cycle %d " + "t_unit_res %u t_flags %s reserveq %s " + "writeq %s grant_reserve_cycle %d " "grant_reserve_bytes %d grant_write_cycle %d " "grant_write_bytes %d curr_cycle %d curr_block %d " "tail_cycle %d tail_block %d", @@ -807,8 +807,8 @@ DECLARE_EVENT_CLASS(xfs_loggrant_class, __entry->curr_res, __entry->unit_res, __print_flags(__entry->flags, "|", XLOG_TIC_FLAGS), - __entry->reserve_headq, - __entry->write_headq, + __entry->reserveq ? "empty" : "active", + __entry->writeq ? "empty" : "active", __entry->grant_reserve_cycle, __entry->grant_reserve_bytes, __entry->grant_write_cycle, diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c index cee4ab9f8a9e..1b82735471ab 100644 --- a/fs/xfs/xfs_log.c +++ b/fs/xfs/xfs_log.c @@ -95,38 +95,6 @@ STATIC void xlog_verify_tail_lsn(xlog_t *log, xlog_in_core_t *iclog, STATIC int xlog_iclogs_empty(xlog_t *log); - -static void -xlog_ins_ticketq(struct xlog_ticket **qp, struct xlog_ticket *tic) -{ - if (*qp) { - tic->t_next = (*qp); - tic->t_prev = (*qp)->t_prev; - (*qp)->t_prev->t_next = tic; - (*qp)->t_prev = tic; - } else { - tic->t_prev = tic->t_next = tic; - *qp = tic; - } - - tic->t_flags |= XLOG_TIC_IN_Q; -} - -static void -xlog_del_ticketq(struct xlog_ticket **qp, struct xlog_ticket *tic) -{ - if (tic == tic->t_next) { - *qp = NULL; - } else { - *qp = tic->t_next; - tic->t_next->t_prev = tic->t_prev; - tic->t_prev->t_next = tic->t_next; - } - - tic->t_next = tic->t_prev = NULL; - tic->t_flags &= ~XLOG_TIC_IN_Q; -} - static void xlog_grant_sub_space(struct log *log, int bytes) { @@ -724,7 +692,7 @@ xfs_log_move_tail(xfs_mount_t *mp, log->l_tail_lsn = tail_lsn; } - if ((tic = log->l_write_headq)) { + if (!list_empty(&log->l_writeq)) { #ifdef DEBUG if (log->l_flags & XLOG_ACTIVE_RECOVERY) panic("Recovery problem"); @@ -732,7 +700,7 @@ xfs_log_move_tail(xfs_mount_t *mp, cycle = log->l_grant_write_cycle; bytes = log->l_grant_write_bytes; free_bytes = xlog_space_left(log, cycle, bytes); - do { + list_for_each_entry(tic, &log->l_writeq, t_queue) { ASSERT(tic->t_flags & XLOG_TIC_PERM_RESERV); if (free_bytes < tic->t_unit_res && tail_lsn != 1) @@ -740,10 +708,10 @@ xfs_log_move_tail(xfs_mount_t *mp, tail_lsn = 0; free_bytes -= tic->t_unit_res; sv_signal(&tic->t_wait); - tic = tic->t_next; - } while (tic != log->l_write_headq); + } } - if ((tic = log->l_reserve_headq)) { + + if (!list_empty(&log->l_reserveq)) { #ifdef DEBUG if (log->l_flags & XLOG_ACTIVE_RECOVERY) panic("Recovery problem"); @@ -751,7 +719,7 @@ xfs_log_move_tail(xfs_mount_t *mp, cycle = log->l_grant_reserve_cycle; bytes = log->l_grant_reserve_bytes; free_bytes = xlog_space_left(log, cycle, bytes); - do { + list_for_each_entry(tic, &log->l_reserveq, t_queue) { if (tic->t_flags & XLOG_TIC_PERM_RESERV) need_bytes = tic->t_unit_res*tic->t_cnt; else @@ -761,8 +729,7 @@ xfs_log_move_tail(xfs_mount_t *mp, tail_lsn = 0; free_bytes -= need_bytes; sv_signal(&tic->t_wait); - tic = tic->t_next; - } while (tic != log->l_reserve_headq); + } } spin_unlock(&log->l_grant_lock); } /* xfs_log_move_tail */ @@ -1053,6 +1020,8 @@ xlog_alloc_log(xfs_mount_t *mp, log->l_curr_cycle = 1; /* 0 is bad since this is initial value */ log->l_grant_reserve_cycle = 1; log->l_grant_write_cycle = 1; + INIT_LIST_HEAD(&log->l_reserveq); + INIT_LIST_HEAD(&log->l_writeq); error = EFSCORRUPTED; if (xfs_sb_version_hassector(&mp->m_sb)) { @@ -2550,8 +2519,8 @@ xlog_grant_log_space(xlog_t *log, trace_xfs_log_grant_enter(log, tic); /* something is already sleeping; insert new transaction at end */ - if (log->l_reserve_headq) { - xlog_ins_ticketq(&log->l_reserve_headq, tic); + if (!list_empty(&log->l_reserveq)) { + list_add_tail(&tic->t_queue, &log->l_reserveq); trace_xfs_log_grant_sleep1(log, tic); @@ -2583,8 +2552,8 @@ redo: free_bytes = xlog_space_left(log, log->l_grant_reserve_cycle, log->l_grant_reserve_bytes); if (free_bytes < need_bytes) { - if ((tic->t_flags & XLOG_TIC_IN_Q) == 0) - xlog_ins_ticketq(&log->l_reserve_headq, tic); + if (list_empty(&tic->t_queue)) + list_add_tail(&tic->t_queue, &log->l_reserveq); trace_xfs_log_grant_sleep2(log, tic); @@ -2602,8 +2571,9 @@ redo: trace_xfs_log_grant_wake2(log, tic); goto redo; - } else if (tic->t_flags & XLOG_TIC_IN_Q) - xlog_del_ticketq(&log->l_reserve_headq, tic); + } + + list_del_init(&tic->t_queue); /* we've got enough space */ xlog_grant_add_space(log, need_bytes); @@ -2626,9 +2596,7 @@ redo: return 0; error_return: - if (tic->t_flags & XLOG_TIC_IN_Q) - xlog_del_ticketq(&log->l_reserve_headq, tic); - + list_del_init(&tic->t_queue); trace_xfs_log_grant_error(log, tic); /* @@ -2653,7 +2621,6 @@ xlog_regrant_write_log_space(xlog_t *log, xlog_ticket_t *tic) { int free_bytes, need_bytes; - xlog_ticket_t *ntic; #ifdef DEBUG xfs_lsn_t tail_lsn; #endif @@ -2683,22 +2650,23 @@ xlog_regrant_write_log_space(xlog_t *log, * this transaction. */ need_bytes = tic->t_unit_res; - if ((ntic = log->l_write_headq)) { + if (!list_empty(&log->l_writeq)) { + struct xlog_ticket *ntic; free_bytes = xlog_space_left(log, log->l_grant_write_cycle, log->l_grant_write_bytes); - do { + list_for_each_entry(ntic, &log->l_writeq, t_queue) { ASSERT(ntic->t_flags & XLOG_TIC_PERM_RESERV); if (free_bytes < ntic->t_unit_res) break; free_bytes -= ntic->t_unit_res; sv_signal(&ntic->t_wait); - ntic = ntic->t_next; - } while (ntic != log->l_write_headq); + } - if (ntic != log->l_write_headq) { - if ((tic->t_flags & XLOG_TIC_IN_Q) == 0) - xlog_ins_ticketq(&log->l_write_headq, tic); + if (ntic != list_first_entry(&log->l_writeq, + struct xlog_ticket, t_queue)) { + if (list_empty(&tic->t_queue)) + list_add_tail(&tic->t_queue, &log->l_writeq); trace_xfs_log_regrant_write_sleep1(log, tic); @@ -2727,8 +2695,8 @@ redo: free_bytes = xlog_space_left(log, log->l_grant_write_cycle, log->l_grant_write_bytes); if (free_bytes < need_bytes) { - if ((tic->t_flags & XLOG_TIC_IN_Q) == 0) - xlog_ins_ticketq(&log->l_write_headq, tic); + if (list_empty(&tic->t_queue)) + list_add_tail(&tic->t_queue, &log->l_writeq); spin_unlock(&log->l_grant_lock); xlog_grant_push_ail(log->l_mp, need_bytes); spin_lock(&log->l_grant_lock); @@ -2745,8 +2713,9 @@ redo: trace_xfs_log_regrant_write_wake2(log, tic); goto redo; - } else if (tic->t_flags & XLOG_TIC_IN_Q) - xlog_del_ticketq(&log->l_write_headq, tic); + } + + list_del_init(&tic->t_queue); /* we've got enough space */ xlog_grant_add_space_write(log, need_bytes); @@ -2766,9 +2735,7 @@ redo: error_return: - if (tic->t_flags & XLOG_TIC_IN_Q) - xlog_del_ticketq(&log->l_reserve_headq, tic); - + list_del_init(&tic->t_queue); trace_xfs_log_regrant_write_error(log, tic); /* @@ -3435,6 +3402,7 @@ xlog_ticket_alloc( } atomic_set(&tic->t_ref, 1); + INIT_LIST_HEAD(&tic->t_queue); tic->t_unit_res = unit_bytes; tic->t_curr_res = unit_bytes; tic->t_cnt = cnt; @@ -3742,26 +3710,17 @@ xfs_log_force_umount( spin_unlock(&log->l_icloglock); /* - * We don't want anybody waiting for log reservations - * after this. That means we have to wake up everybody - * queued up on reserve_headq as well as write_headq. - * In addition, we make sure in xlog_{re}grant_log_space - * that we don't enqueue anything once the SHUTDOWN flag - * is set, and this action is protected by the GRANTLOCK. + * We don't want anybody waiting for log reservations after this. That + * means we have to wake up everybody queued up on reserveq as well as + * writeq. In addition, we make sure in xlog_{re}grant_log_space that + * we don't enqueue anything once the SHUTDOWN flag is set, and this + * action is protected by the GRANTLOCK. */ - if ((tic = log->l_reserve_headq)) { - do { - sv_signal(&tic->t_wait); - tic = tic->t_next; - } while (tic != log->l_reserve_headq); - } + list_for_each_entry(tic, &log->l_reserveq, t_queue) + sv_signal(&tic->t_wait); - if ((tic = log->l_write_headq)) { - do { - sv_signal(&tic->t_wait); - tic = tic->t_next; - } while (tic != log->l_write_headq); - } + list_for_each_entry(tic, &log->l_writeq, t_queue) + sv_signal(&tic->t_wait); spin_unlock(&log->l_grant_lock); if (!(log->l_iclog->ic_state & XLOG_STATE_IOERROR)) { diff --git a/fs/xfs/xfs_log_priv.h b/fs/xfs/xfs_log_priv.h index c1ce505313e9..a5b3c021a406 100644 --- a/fs/xfs/xfs_log_priv.h +++ b/fs/xfs/xfs_log_priv.h @@ -132,12 +132,10 @@ static inline uint xlog_get_client_id(__be32 i) */ #define XLOG_TIC_INITED 0x1 /* has been initialized */ #define XLOG_TIC_PERM_RESERV 0x2 /* permanent reservation */ -#define XLOG_TIC_IN_Q 0x4 #define XLOG_TIC_FLAGS \ { XLOG_TIC_INITED, "XLOG_TIC_INITED" }, \ - { XLOG_TIC_PERM_RESERV, "XLOG_TIC_PERM_RESERV" }, \ - { XLOG_TIC_IN_Q, "XLOG_TIC_IN_Q" } + { XLOG_TIC_PERM_RESERV, "XLOG_TIC_PERM_RESERV" } #endif /* __KERNEL__ */ @@ -244,8 +242,7 @@ typedef struct xlog_res { typedef struct xlog_ticket { sv_t t_wait; /* ticket wait queue : 20 */ - struct xlog_ticket *t_next; /* :4|8 */ - struct xlog_ticket *t_prev; /* :4|8 */ + struct list_head t_queue; /* reserve/write queue */ xlog_tid_t t_tid; /* transaction identifier : 4 */ atomic_t t_ref; /* ticket reference count : 4 */ int t_curr_res; /* current reservation in bytes : 4 */ @@ -519,8 +516,8 @@ typedef struct log { /* The following block of fields are changed while holding grant_lock */ spinlock_t l_grant_lock ____cacheline_aligned_in_smp; - xlog_ticket_t *l_reserve_headq; - xlog_ticket_t *l_write_headq; + struct list_head l_reserveq; + struct list_head l_writeq; int l_grant_reserve_cycle; int l_grant_reserve_bytes; int l_grant_write_cycle; -- cgit v1.2.3 From 3f336c6fa17c2b3d14b3dd1bd6e64e9cc97b6359 Mon Sep 17 00:00:00 2001 From: Dave Chinner Date: Tue, 21 Dec 2010 12:02:52 +1100 Subject: xfs: fact out common grant head/log tail verification code Factor repeated debug code out of grant head manipulation functions into a separate function. This removes ifdef DEBUG spagetti from the code and makes the code easier to follow. Signed-off-by: Dave Chinner Reviewed-by: Christoph Hellwig --- fs/xfs/xfs_log.c | 51 ++++++++++++++++++++++----------------------------- 1 file changed, 22 insertions(+), 29 deletions(-) diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c index 1b82735471ab..99c62855432e 100644 --- a/fs/xfs/xfs_log.c +++ b/fs/xfs/xfs_log.c @@ -82,6 +82,7 @@ STATIC void xlog_ungrant_log_space(xlog_t *log, #if defined(DEBUG) STATIC void xlog_verify_dest_ptr(xlog_t *log, char *ptr); STATIC void xlog_verify_grant_head(xlog_t *log, int equals); +STATIC void xlog_verify_grant_tail(struct log *log); STATIC void xlog_verify_iclog(xlog_t *log, xlog_in_core_t *iclog, int count, boolean_t syncing); STATIC void xlog_verify_tail_lsn(xlog_t *log, xlog_in_core_t *iclog, @@ -89,6 +90,7 @@ STATIC void xlog_verify_tail_lsn(xlog_t *log, xlog_in_core_t *iclog, #else #define xlog_verify_dest_ptr(a,b) #define xlog_verify_grant_head(a,b) +#define xlog_verify_grant_tail(a) #define xlog_verify_iclog(a,b,c,d) #define xlog_verify_tail_lsn(a,b,c) #endif @@ -2503,10 +2505,6 @@ xlog_grant_log_space(xlog_t *log, { int free_bytes; int need_bytes; -#ifdef DEBUG - xfs_lsn_t tail_lsn; -#endif - #ifdef DEBUG if (log->l_flags & XLOG_ACTIVE_RECOVERY) @@ -2577,21 +2575,9 @@ redo: /* we've got enough space */ xlog_grant_add_space(log, need_bytes); -#ifdef DEBUG - tail_lsn = log->l_tail_lsn; - /* - * Check to make sure the grant write head didn't just over lap the - * tail. If the cycles are the same, we can't be overlapping. - * Otherwise, make sure that the cycles differ by exactly one and - * check the byte count. - */ - if (CYCLE_LSN(tail_lsn) != log->l_grant_write_cycle) { - ASSERT(log->l_grant_write_cycle-1 == CYCLE_LSN(tail_lsn)); - ASSERT(log->l_grant_write_bytes <= BBTOB(BLOCK_LSN(tail_lsn))); - } -#endif trace_xfs_log_grant_exit(log, tic); xlog_verify_grant_head(log, 1); + xlog_verify_grant_tail(log); spin_unlock(&log->l_grant_lock); return 0; @@ -2621,9 +2607,6 @@ xlog_regrant_write_log_space(xlog_t *log, xlog_ticket_t *tic) { int free_bytes, need_bytes; -#ifdef DEBUG - xfs_lsn_t tail_lsn; -#endif tic->t_curr_res = tic->t_unit_res; xlog_tic_reset_res(tic); @@ -2719,17 +2702,9 @@ redo: /* we've got enough space */ xlog_grant_add_space_write(log, need_bytes); -#ifdef DEBUG - tail_lsn = log->l_tail_lsn; - if (CYCLE_LSN(tail_lsn) != log->l_grant_write_cycle) { - ASSERT(log->l_grant_write_cycle-1 == CYCLE_LSN(tail_lsn)); - ASSERT(log->l_grant_write_bytes <= BBTOB(BLOCK_LSN(tail_lsn))); - } -#endif - trace_xfs_log_regrant_write_exit(log, tic); - xlog_verify_grant_head(log, 1); + xlog_verify_grant_tail(log); spin_unlock(&log->l_grant_lock); return 0; @@ -3465,6 +3440,24 @@ xlog_verify_grant_head(xlog_t *log, int equals) } } /* xlog_verify_grant_head */ +STATIC void +xlog_verify_grant_tail( + struct log *log) +{ + xfs_lsn_t tail_lsn = log->l_tail_lsn; + + /* + * Check to make sure the grant write head didn't just over lap the + * tail. If the cycles are the same, we can't be overlapping. + * Otherwise, make sure that the cycles differ by exactly one and + * check the byte count. + */ + if (CYCLE_LSN(tail_lsn) != log->l_grant_write_cycle) { + ASSERT(log->l_grant_write_cycle - 1 == CYCLE_LSN(tail_lsn)); + ASSERT(log->l_grant_write_bytes <= BBTOB(BLOCK_LSN(tail_lsn))); + } +} + /* check if it will fit */ STATIC void xlog_verify_tail_lsn(xlog_t *log, -- cgit v1.2.3 From 663e496a720a3a9fc08ea70b29724e8906b34e43 Mon Sep 17 00:00:00 2001 From: Dave Chinner Date: Tue, 21 Dec 2010 12:06:05 +1100 Subject: xfs: rework log grant space calculations The log grant space calculations are repeated for both write and reserve grant heads. To make it simpler to convert the calculations toa different algorithm, factor them so both the gratn heads use the same calculation functions. Once this is done we can drop the wrappers that are used in only a couple of place to update both grant heads at once as they don't provide any particular value. Signed-off-by: Dave Chinner Reviewed-by: Christoph Hellwig --- fs/xfs/xfs_log.c | 95 ++++++++++++++++++++++++++++---------------------------- 1 file changed, 48 insertions(+), 47 deletions(-) diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c index 99c62855432e..9a4b9edad847 100644 --- a/fs/xfs/xfs_log.c +++ b/fs/xfs/xfs_log.c @@ -98,53 +98,34 @@ STATIC void xlog_verify_tail_lsn(xlog_t *log, xlog_in_core_t *iclog, STATIC int xlog_iclogs_empty(xlog_t *log); static void -xlog_grant_sub_space(struct log *log, int bytes) -{ - log->l_grant_write_bytes -= bytes; - if (log->l_grant_write_bytes < 0) { - log->l_grant_write_bytes += log->l_logsize; - log->l_grant_write_cycle--; - } - - log->l_grant_reserve_bytes -= bytes; - if ((log)->l_grant_reserve_bytes < 0) { - log->l_grant_reserve_bytes += log->l_logsize; - log->l_grant_reserve_cycle--; - } - -} - -static void -xlog_grant_add_space_write(struct log *log, int bytes) +xlog_grant_sub_space( + struct log *log, + int *cycle, + int *space, + int bytes) { - int tmp = log->l_logsize - log->l_grant_write_bytes; - if (tmp > bytes) - log->l_grant_write_bytes += bytes; - else { - log->l_grant_write_cycle++; - log->l_grant_write_bytes = bytes - tmp; + *space -= bytes; + if (*space < 0) { + *space += log->l_logsize; + (*cycle)--; } } static void -xlog_grant_add_space_reserve(struct log *log, int bytes) +xlog_grant_add_space( + struct log *log, + int *cycle, + int *space, + int bytes) { - int tmp = log->l_logsize - log->l_grant_reserve_bytes; + int tmp = log->l_logsize - *space; if (tmp > bytes) - log->l_grant_reserve_bytes += bytes; + *space += bytes; else { - log->l_grant_reserve_cycle++; - log->l_grant_reserve_bytes = bytes - tmp; + *space = bytes - tmp; + (*cycle)++; } } - -static inline void -xlog_grant_add_space(struct log *log, int bytes) -{ - xlog_grant_add_space_write(log, bytes); - xlog_grant_add_space_reserve(log, bytes); -} - static void xlog_tic_reset_res(xlog_ticket_t *tic) { @@ -1344,7 +1325,10 @@ xlog_sync(xlog_t *log, /* move grant heads by roundoff in sync */ spin_lock(&log->l_grant_lock); - xlog_grant_add_space(log, roundoff); + xlog_grant_add_space(log, &log->l_grant_reserve_cycle, + &log->l_grant_reserve_bytes, roundoff); + xlog_grant_add_space(log, &log->l_grant_write_cycle, + &log->l_grant_write_bytes, roundoff); spin_unlock(&log->l_grant_lock); /* put cycle number in every block */ @@ -2574,7 +2558,10 @@ redo: list_del_init(&tic->t_queue); /* we've got enough space */ - xlog_grant_add_space(log, need_bytes); + xlog_grant_add_space(log, &log->l_grant_reserve_cycle, + &log->l_grant_reserve_bytes, need_bytes); + xlog_grant_add_space(log, &log->l_grant_write_cycle, + &log->l_grant_write_bytes, need_bytes); trace_xfs_log_grant_exit(log, tic); xlog_verify_grant_head(log, 1); xlog_verify_grant_tail(log); @@ -2701,7 +2688,8 @@ redo: list_del_init(&tic->t_queue); /* we've got enough space */ - xlog_grant_add_space_write(log, need_bytes); + xlog_grant_add_space(log, &log->l_grant_write_cycle, + &log->l_grant_write_bytes, need_bytes); trace_xfs_log_regrant_write_exit(log, tic); xlog_verify_grant_head(log, 1); xlog_verify_grant_tail(log); @@ -2742,7 +2730,12 @@ xlog_regrant_reserve_log_space(xlog_t *log, ticket->t_cnt--; spin_lock(&log->l_grant_lock); - xlog_grant_sub_space(log, ticket->t_curr_res); + xlog_grant_sub_space(log, &log->l_grant_reserve_cycle, + &log->l_grant_reserve_bytes, + ticket->t_curr_res); + xlog_grant_sub_space(log, &log->l_grant_write_cycle, + &log->l_grant_write_bytes, + ticket->t_curr_res); ticket->t_curr_res = ticket->t_unit_res; xlog_tic_reset_res(ticket); @@ -2756,7 +2749,9 @@ xlog_regrant_reserve_log_space(xlog_t *log, return; } - xlog_grant_add_space_reserve(log, ticket->t_unit_res); + xlog_grant_add_space(log, &log->l_grant_reserve_cycle, + &log->l_grant_reserve_bytes, + ticket->t_unit_res); trace_xfs_log_regrant_reserve_exit(log, ticket); @@ -2785,24 +2780,30 @@ STATIC void xlog_ungrant_log_space(xlog_t *log, xlog_ticket_t *ticket) { + int bytes; + if (ticket->t_cnt > 0) ticket->t_cnt--; spin_lock(&log->l_grant_lock); trace_xfs_log_ungrant_enter(log, ticket); - - xlog_grant_sub_space(log, ticket->t_curr_res); - trace_xfs_log_ungrant_sub(log, ticket); - /* If this is a permanent reservation ticket, we may be able to free + /* + * If this is a permanent reservation ticket, we may be able to free * up more space based on the remaining count. */ + bytes = ticket->t_curr_res; if (ticket->t_cnt > 0) { ASSERT(ticket->t_flags & XLOG_TIC_PERM_RESERV); - xlog_grant_sub_space(log, ticket->t_unit_res*ticket->t_cnt); + bytes += ticket->t_unit_res*ticket->t_cnt; } + xlog_grant_sub_space(log, &log->l_grant_reserve_cycle, + &log->l_grant_reserve_bytes, bytes); + xlog_grant_sub_space(log, &log->l_grant_write_cycle, + &log->l_grant_write_bytes, bytes); + trace_xfs_log_ungrant_exit(log, ticket); xlog_verify_grant_head(log, 1); -- cgit v1.2.3 From a69ed03c24d4a336c23b7116127713d5a8c5ac4d Mon Sep 17 00:00:00 2001 From: Dave Chinner Date: Tue, 21 Dec 2010 12:08:20 +1100 Subject: xfs: combine grant heads into a single 64 bit integer Prepare for switching the grant heads to atomic variables by combining the two 32 bit values that make up the grant head into a single 64 bit variable. Provide wrapper functions to combine and split the grant heads appropriately for calculations and use them as necessary. Signed-off-by: Dave Chinner Reviewed-by: Christoph Hellwig --- fs/xfs/linux-2.6/xfs_trace.h | 10 +-- fs/xfs/xfs_log.c | 166 +++++++++++++++++++++++-------------------- fs/xfs/xfs_log_priv.h | 26 +++++-- fs/xfs/xfs_log_recover.c | 8 +-- 4 files changed, 119 insertions(+), 91 deletions(-) diff --git a/fs/xfs/linux-2.6/xfs_trace.h b/fs/xfs/linux-2.6/xfs_trace.h index 69b9e1f1baaf..3ff6b35f9207 100644 --- a/fs/xfs/linux-2.6/xfs_trace.h +++ b/fs/xfs/linux-2.6/xfs_trace.h @@ -786,10 +786,12 @@ DECLARE_EVENT_CLASS(xfs_loggrant_class, __entry->flags = tic->t_flags; __entry->reserveq = list_empty(&log->l_reserveq); __entry->writeq = list_empty(&log->l_writeq); - __entry->grant_reserve_cycle = log->l_grant_reserve_cycle; - __entry->grant_reserve_bytes = log->l_grant_reserve_bytes; - __entry->grant_write_cycle = log->l_grant_write_cycle; - __entry->grant_write_bytes = log->l_grant_write_bytes; + xlog_crack_grant_head(&log->l_grant_reserve_head, + &__entry->grant_reserve_cycle, + &__entry->grant_reserve_bytes); + xlog_crack_grant_head(&log->l_grant_write_head, + &__entry->grant_write_cycle, + &__entry->grant_write_bytes); __entry->curr_cycle = log->l_curr_cycle; __entry->curr_block = log->l_curr_block; __entry->tail_lsn = log->l_tail_lsn; diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c index 9a4b9edad847..6bba8b4b8596 100644 --- a/fs/xfs/xfs_log.c +++ b/fs/xfs/xfs_log.c @@ -47,7 +47,7 @@ STATIC xlog_t * xlog_alloc_log(xfs_mount_t *mp, xfs_buftarg_t *log_target, xfs_daddr_t blk_offset, int num_bblks); -STATIC int xlog_space_left(xlog_t *log, int cycle, int bytes); +STATIC int xlog_space_left(struct log *log, int64_t *head); STATIC int xlog_sync(xlog_t *log, xlog_in_core_t *iclog); STATIC void xlog_dealloc_log(xlog_t *log); @@ -100,32 +100,44 @@ STATIC int xlog_iclogs_empty(xlog_t *log); static void xlog_grant_sub_space( struct log *log, - int *cycle, - int *space, + int64_t *head, int bytes) { - *space -= bytes; - if (*space < 0) { - *space += log->l_logsize; - (*cycle)--; + int cycle, space; + + xlog_crack_grant_head(head, &cycle, &space); + + space -= bytes; + if (space < 0) { + space += log->l_logsize; + cycle--; } + + xlog_assign_grant_head(head, cycle, space); } static void xlog_grant_add_space( struct log *log, - int *cycle, - int *space, + int64_t *head, int bytes) { - int tmp = log->l_logsize - *space; + int tmp; + int cycle, space; + + xlog_crack_grant_head(head, &cycle, &space); + + tmp = log->l_logsize - space; if (tmp > bytes) - *space += bytes; + space += bytes; else { - *space = bytes - tmp; - (*cycle)++; + space = bytes - tmp; + cycle++; } + + xlog_assign_grant_head(head, cycle, space); } + static void xlog_tic_reset_res(xlog_ticket_t *tic) { @@ -654,7 +666,7 @@ xfs_log_move_tail(xfs_mount_t *mp, { xlog_ticket_t *tic; xlog_t *log = mp->m_log; - int need_bytes, free_bytes, cycle, bytes; + int need_bytes, free_bytes; if (XLOG_FORCED_SHUTDOWN(log)) return; @@ -680,9 +692,7 @@ xfs_log_move_tail(xfs_mount_t *mp, if (log->l_flags & XLOG_ACTIVE_RECOVERY) panic("Recovery problem"); #endif - cycle = log->l_grant_write_cycle; - bytes = log->l_grant_write_bytes; - free_bytes = xlog_space_left(log, cycle, bytes); + free_bytes = xlog_space_left(log, &log->l_grant_write_head); list_for_each_entry(tic, &log->l_writeq, t_queue) { ASSERT(tic->t_flags & XLOG_TIC_PERM_RESERV); @@ -699,9 +709,7 @@ xfs_log_move_tail(xfs_mount_t *mp, if (log->l_flags & XLOG_ACTIVE_RECOVERY) panic("Recovery problem"); #endif - cycle = log->l_grant_reserve_cycle; - bytes = log->l_grant_reserve_bytes; - free_bytes = xlog_space_left(log, cycle, bytes); + free_bytes = xlog_space_left(log, &log->l_grant_reserve_head); list_for_each_entry(tic, &log->l_reserveq, t_queue) { if (tic->t_flags & XLOG_TIC_PERM_RESERV) need_bytes = tic->t_unit_res*tic->t_cnt; @@ -814,21 +822,26 @@ xlog_assign_tail_lsn(xfs_mount_t *mp) * result is that we return the size of the log as the amount of space left. */ STATIC int -xlog_space_left(xlog_t *log, int cycle, int bytes) +xlog_space_left( + struct log *log, + int64_t *head) { - int free_bytes; - int tail_bytes; - int tail_cycle; + int free_bytes; + int tail_bytes; + int tail_cycle; + int head_cycle; + int head_bytes; + xlog_crack_grant_head(head, &head_cycle, &head_bytes); tail_bytes = BBTOB(BLOCK_LSN(log->l_tail_lsn)); tail_cycle = CYCLE_LSN(log->l_tail_lsn); - if ((tail_cycle == cycle) && (bytes >= tail_bytes)) { - free_bytes = log->l_logsize - (bytes - tail_bytes); - } else if ((tail_cycle + 1) < cycle) { + if (tail_cycle == head_cycle && head_bytes >= tail_bytes) + free_bytes = log->l_logsize - (head_bytes - tail_bytes); + else if (tail_cycle + 1 < head_cycle) return 0; - } else if (tail_cycle < cycle) { - ASSERT(tail_cycle == (cycle - 1)); - free_bytes = tail_bytes - bytes; + else if (tail_cycle < head_cycle) { + ASSERT(tail_cycle == (head_cycle - 1)); + free_bytes = tail_bytes - head_bytes; } else { /* * The reservation head is behind the tail. @@ -839,12 +852,12 @@ xlog_space_left(xlog_t *log, int cycle, int bytes) "xlog_space_left: head behind tail\n" " tail_cycle = %d, tail_bytes = %d\n" " GH cycle = %d, GH bytes = %d", - tail_cycle, tail_bytes, cycle, bytes); + tail_cycle, tail_bytes, head_cycle, head_bytes); ASSERT(0); free_bytes = log->l_logsize; } return free_bytes; -} /* xlog_space_left */ +} /* @@ -1001,8 +1014,8 @@ xlog_alloc_log(xfs_mount_t *mp, /* log->l_tail_lsn = 0x100000000LL; cycle = 1; current block = 0 */ log->l_last_sync_lsn = log->l_tail_lsn; log->l_curr_cycle = 1; /* 0 is bad since this is initial value */ - log->l_grant_reserve_cycle = 1; - log->l_grant_write_cycle = 1; + xlog_assign_grant_head(&log->l_grant_reserve_head, 1, 0); + xlog_assign_grant_head(&log->l_grant_write_head, 1, 0); INIT_LIST_HEAD(&log->l_reserveq); INIT_LIST_HEAD(&log->l_writeq); @@ -1190,9 +1203,7 @@ xlog_grant_push_ail(xfs_mount_t *mp, ASSERT(BTOBB(need_bytes) < log->l_logBBsize); spin_lock(&log->l_grant_lock); - free_bytes = xlog_space_left(log, - log->l_grant_reserve_cycle, - log->l_grant_reserve_bytes); + free_bytes = xlog_space_left(log, &log->l_grant_reserve_head); tail_lsn = log->l_tail_lsn; free_blocks = BTOBBT(free_bytes); @@ -1325,10 +1336,8 @@ xlog_sync(xlog_t *log, /* move grant heads by roundoff in sync */ spin_lock(&log->l_grant_lock); - xlog_grant_add_space(log, &log->l_grant_reserve_cycle, - &log->l_grant_reserve_bytes, roundoff); - xlog_grant_add_space(log, &log->l_grant_write_cycle, - &log->l_grant_write_bytes, roundoff); + xlog_grant_add_space(log, &log->l_grant_reserve_head, roundoff); + xlog_grant_add_space(log, &log->l_grant_write_head, roundoff); spin_unlock(&log->l_grant_lock); /* put cycle number in every block */ @@ -2531,8 +2540,7 @@ redo: if (XLOG_FORCED_SHUTDOWN(log)) goto error_return; - free_bytes = xlog_space_left(log, log->l_grant_reserve_cycle, - log->l_grant_reserve_bytes); + free_bytes = xlog_space_left(log, &log->l_grant_reserve_head); if (free_bytes < need_bytes) { if (list_empty(&tic->t_queue)) list_add_tail(&tic->t_queue, &log->l_reserveq); @@ -2558,10 +2566,8 @@ redo: list_del_init(&tic->t_queue); /* we've got enough space */ - xlog_grant_add_space(log, &log->l_grant_reserve_cycle, - &log->l_grant_reserve_bytes, need_bytes); - xlog_grant_add_space(log, &log->l_grant_write_cycle, - &log->l_grant_write_bytes, need_bytes); + xlog_grant_add_space(log, &log->l_grant_reserve_head, need_bytes); + xlog_grant_add_space(log, &log->l_grant_write_head, need_bytes); trace_xfs_log_grant_exit(log, tic); xlog_verify_grant_head(log, 1); xlog_verify_grant_tail(log); @@ -2622,8 +2628,7 @@ xlog_regrant_write_log_space(xlog_t *log, need_bytes = tic->t_unit_res; if (!list_empty(&log->l_writeq)) { struct xlog_ticket *ntic; - free_bytes = xlog_space_left(log, log->l_grant_write_cycle, - log->l_grant_write_bytes); + free_bytes = xlog_space_left(log, &log->l_grant_write_head); list_for_each_entry(ntic, &log->l_writeq, t_queue) { ASSERT(ntic->t_flags & XLOG_TIC_PERM_RESERV); @@ -2662,8 +2667,7 @@ redo: if (XLOG_FORCED_SHUTDOWN(log)) goto error_return; - free_bytes = xlog_space_left(log, log->l_grant_write_cycle, - log->l_grant_write_bytes); + free_bytes = xlog_space_left(log, &log->l_grant_write_head); if (free_bytes < need_bytes) { if (list_empty(&tic->t_queue)) list_add_tail(&tic->t_queue, &log->l_writeq); @@ -2688,8 +2692,7 @@ redo: list_del_init(&tic->t_queue); /* we've got enough space */ - xlog_grant_add_space(log, &log->l_grant_write_cycle, - &log->l_grant_write_bytes, need_bytes); + xlog_grant_add_space(log, &log->l_grant_write_head, need_bytes); trace_xfs_log_regrant_write_exit(log, tic); xlog_verify_grant_head(log, 1); xlog_verify_grant_tail(log); @@ -2730,12 +2733,10 @@ xlog_regrant_reserve_log_space(xlog_t *log, ticket->t_cnt--; spin_lock(&log->l_grant_lock); - xlog_grant_sub_space(log, &log->l_grant_reserve_cycle, - &log->l_grant_reserve_bytes, - ticket->t_curr_res); - xlog_grant_sub_space(log, &log->l_grant_write_cycle, - &log->l_grant_write_bytes, - ticket->t_curr_res); + xlog_grant_sub_space(log, &log->l_grant_reserve_head, + ticket->t_curr_res); + xlog_grant_sub_space(log, &log->l_grant_write_head, + ticket->t_curr_res); ticket->t_curr_res = ticket->t_unit_res; xlog_tic_reset_res(ticket); @@ -2749,9 +2750,8 @@ xlog_regrant_reserve_log_space(xlog_t *log, return; } - xlog_grant_add_space(log, &log->l_grant_reserve_cycle, - &log->l_grant_reserve_bytes, - ticket->t_unit_res); + xlog_grant_add_space(log, &log->l_grant_reserve_head, + ticket->t_unit_res); trace_xfs_log_regrant_reserve_exit(log, ticket); @@ -2799,10 +2799,8 @@ xlog_ungrant_log_space(xlog_t *log, bytes += ticket->t_unit_res*ticket->t_cnt; } - xlog_grant_sub_space(log, &log->l_grant_reserve_cycle, - &log->l_grant_reserve_bytes, bytes); - xlog_grant_sub_space(log, &log->l_grant_write_cycle, - &log->l_grant_write_bytes, bytes); + xlog_grant_sub_space(log, &log->l_grant_reserve_head, bytes); + xlog_grant_sub_space(log, &log->l_grant_write_head, bytes); trace_xfs_log_ungrant_exit(log, ticket); @@ -3430,22 +3428,31 @@ xlog_verify_dest_ptr( STATIC void xlog_verify_grant_head(xlog_t *log, int equals) { - if (log->l_grant_reserve_cycle == log->l_grant_write_cycle) { - if (equals) - ASSERT(log->l_grant_reserve_bytes >= log->l_grant_write_bytes); - else - ASSERT(log->l_grant_reserve_bytes > log->l_grant_write_bytes); - } else { - ASSERT(log->l_grant_reserve_cycle-1 == log->l_grant_write_cycle); - ASSERT(log->l_grant_write_bytes >= log->l_grant_reserve_bytes); - } -} /* xlog_verify_grant_head */ + int reserve_cycle, reserve_space; + int write_cycle, write_space; + + xlog_crack_grant_head(&log->l_grant_reserve_head, + &reserve_cycle, &reserve_space); + xlog_crack_grant_head(&log->l_grant_write_head, + &write_cycle, &write_space); + + if (reserve_cycle == write_cycle) { + if (equals) + ASSERT(reserve_space >= write_space); + else + ASSERT(reserve_space > write_space); + } else { + ASSERT(reserve_cycle - 1 == write_cycle); + ASSERT(write_space >= reserve_space); + } +} STATIC void xlog_verify_grant_tail( struct log *log) { xfs_lsn_t tail_lsn = log->l_tail_lsn; + int cycle, space; /* * Check to make sure the grant write head didn't just over lap the @@ -3453,9 +3460,10 @@ xlog_verify_grant_tail( * Otherwise, make sure that the cycles differ by exactly one and * check the byte count. */ - if (CYCLE_LSN(tail_lsn) != log->l_grant_write_cycle) { - ASSERT(log->l_grant_write_cycle - 1 == CYCLE_LSN(tail_lsn)); - ASSERT(log->l_grant_write_bytes <= BBTOB(BLOCK_LSN(tail_lsn))); + xlog_crack_grant_head(&log->l_grant_write_head, &cycle, &space); + if (CYCLE_LSN(tail_lsn) != cycle) { + ASSERT(cycle - 1 == CYCLE_LSN(tail_lsn)); + ASSERT(space <= BBTOB(BLOCK_LSN(tail_lsn))); } } diff --git a/fs/xfs/xfs_log_priv.h b/fs/xfs/xfs_log_priv.h index a5b3c021a406..2f74c80a7a40 100644 --- a/fs/xfs/xfs_log_priv.h +++ b/fs/xfs/xfs_log_priv.h @@ -518,10 +518,8 @@ typedef struct log { spinlock_t l_grant_lock ____cacheline_aligned_in_smp; struct list_head l_reserveq; struct list_head l_writeq; - int l_grant_reserve_cycle; - int l_grant_reserve_bytes; - int l_grant_write_cycle; - int l_grant_write_bytes; + int64_t l_grant_reserve_head; + int64_t l_grant_write_head; /* The following field are used for debugging; need to hold icloglock */ #ifdef DEBUG @@ -560,6 +558,26 @@ int xlog_write(struct log *log, struct xfs_log_vec *log_vector, struct xlog_ticket *tic, xfs_lsn_t *start_lsn, xlog_in_core_t **commit_iclog, uint flags); +/* + * When we crack the grrant head, we sample it first so that the value will not + * change while we are cracking it into the component values. This means we + * will always get consistent component values to work from. + */ +static inline void +xlog_crack_grant_head(int64_t *head, int *cycle, int *space) +{ + int64_t val = *head; + + *cycle = val >> 32; + *space = val & 0xffffffff; +} + +static inline void +xlog_assign_grant_head(int64_t *head, int cycle, int space) +{ + *head = ((int64_t)cycle << 32) | space; +} + /* * Committed Item List interfaces */ diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index 4abe7a9b380e..1550404a8aeb 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c @@ -938,10 +938,10 @@ xlog_find_tail( log->l_curr_cycle++; log->l_tail_lsn = be64_to_cpu(rhead->h_tail_lsn); log->l_last_sync_lsn = be64_to_cpu(rhead->h_lsn); - log->l_grant_reserve_cycle = log->l_curr_cycle; - log->l_grant_reserve_bytes = BBTOB(log->l_curr_block); - log->l_grant_write_cycle = log->l_curr_cycle; - log->l_grant_write_bytes = BBTOB(log->l_curr_block); + xlog_assign_grant_head(&log->l_grant_reserve_head, log->l_curr_cycle, + BBTOB(log->l_curr_block)); + xlog_assign_grant_head(&log->l_grant_write_head, log->l_curr_cycle, + BBTOB(log->l_curr_block)); /* * Look for unmount record. If we find it, then we know there -- cgit v1.2.3 From eb40a87500ac2f6be7eaf8ebb35610e6d0e60e9a Mon Sep 17 00:00:00 2001 From: Dave Chinner Date: Tue, 21 Dec 2010 12:09:01 +1100 Subject: xfs: use wait queues directly for the log wait queues The log grant queues are one of the few places left using sv_t constructs for waiting. Given we are touching this code, we should convert them to plain wait queues. While there, convert all the other sv_t users in the log code as well. Seeing as this removes the last users of the sv_t type, remove the header file defining the wrapper and the fragments that still reference it. Signed-off-by: Dave Chinner Reviewed-by: Christoph Hellwig --- fs/xfs/linux-2.6/sv.h | 59 ---------------------------------------- fs/xfs/linux-2.6/xfs_linux.h | 1 - fs/xfs/quota/xfs_dquot.c | 1 - fs/xfs/xfs_log.c | 64 +++++++++++++++++++------------------------- fs/xfs/xfs_log_cil.c | 8 +++--- fs/xfs/xfs_log_priv.h | 25 +++++++++++++---- 6 files changed, 52 insertions(+), 106 deletions(-) delete mode 100644 fs/xfs/linux-2.6/sv.h diff --git a/fs/xfs/linux-2.6/sv.h b/fs/xfs/linux-2.6/sv.h deleted file mode 100644 index 4dfc7c370819..000000000000 --- a/fs/xfs/linux-2.6/sv.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (c) 2000-2002,2005 Silicon Graphics, Inc. - * All Rights Reserved. - * - * 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. - * - * This program is distributed in the hope that it would 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. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ -#ifndef __XFS_SUPPORT_SV_H__ -#define __XFS_SUPPORT_SV_H__ - -#include -#include -#include - -/* - * Synchronisation variables. - * - * (Parameters "pri", "svf" and "rts" are not implemented) - */ - -typedef struct sv_s { - wait_queue_head_t waiters; -} sv_t; - -static inline void _sv_wait(sv_t *sv, spinlock_t *lock) -{ - DECLARE_WAITQUEUE(wait, current); - - add_wait_queue_exclusive(&sv->waiters, &wait); - __set_current_state(TASK_UNINTERRUPTIBLE); - spin_unlock(lock); - - schedule(); - - remove_wait_queue(&sv->waiters, &wait); -} - -#define sv_init(sv,flag,name) \ - init_waitqueue_head(&(sv)->waiters) -#define sv_destroy(sv) \ - /*NOTHING*/ -#define sv_wait(sv, pri, lock, s) \ - _sv_wait(sv, lock) -#define sv_signal(sv) \ - wake_up(&(sv)->waiters) -#define sv_broadcast(sv) \ - wake_up_all(&(sv)->waiters) - -#endif /* __XFS_SUPPORT_SV_H__ */ diff --git a/fs/xfs/linux-2.6/xfs_linux.h b/fs/xfs/linux-2.6/xfs_linux.h index 214ddd71ff79..096494997747 100644 --- a/fs/xfs/linux-2.6/xfs_linux.h +++ b/fs/xfs/linux-2.6/xfs_linux.h @@ -37,7 +37,6 @@ #include #include -#include #include #include diff --git a/fs/xfs/quota/xfs_dquot.c b/fs/xfs/quota/xfs_dquot.c index faf8e1a83a12..d22aa3103106 100644 --- a/fs/xfs/quota/xfs_dquot.c +++ b/fs/xfs/quota/xfs_dquot.c @@ -149,7 +149,6 @@ xfs_qm_dqdestroy( ASSERT(list_empty(&dqp->q_freelist)); mutex_destroy(&dqp->q_qlock); - sv_destroy(&dqp->q_pinwait); kmem_zone_free(xfs_Gqm->qm_dqzone, dqp); atomic_dec(&xfs_Gqm->qm_totaldquots); diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c index 6bba8b4b8596..cc0504e0bb3b 100644 --- a/fs/xfs/xfs_log.c +++ b/fs/xfs/xfs_log.c @@ -547,8 +547,8 @@ xfs_log_unmount_write(xfs_mount_t *mp) if (!(iclog->ic_state == XLOG_STATE_ACTIVE || iclog->ic_state == XLOG_STATE_DIRTY)) { if (!XLOG_FORCED_SHUTDOWN(log)) { - sv_wait(&iclog->ic_force_wait, PMEM, - &log->l_icloglock, s); + xlog_wait(&iclog->ic_force_wait, + &log->l_icloglock); } else { spin_unlock(&log->l_icloglock); } @@ -588,8 +588,8 @@ xfs_log_unmount_write(xfs_mount_t *mp) || iclog->ic_state == XLOG_STATE_DIRTY || iclog->ic_state == XLOG_STATE_IOERROR) ) { - sv_wait(&iclog->ic_force_wait, PMEM, - &log->l_icloglock, s); + xlog_wait(&iclog->ic_force_wait, + &log->l_icloglock); } else { spin_unlock(&log->l_icloglock); } @@ -700,7 +700,7 @@ xfs_log_move_tail(xfs_mount_t *mp, break; tail_lsn = 0; free_bytes -= tic->t_unit_res; - sv_signal(&tic->t_wait); + wake_up(&tic->t_wait); } } @@ -719,7 +719,7 @@ xfs_log_move_tail(xfs_mount_t *mp, break; tail_lsn = 0; free_bytes -= need_bytes; - sv_signal(&tic->t_wait); + wake_up(&tic->t_wait); } } spin_unlock(&log->l_grant_lock); @@ -1060,7 +1060,7 @@ xlog_alloc_log(xfs_mount_t *mp, spin_lock_init(&log->l_icloglock); spin_lock_init(&log->l_grant_lock); - sv_init(&log->l_flush_wait, 0, "flush_wait"); + init_waitqueue_head(&log->l_flush_wait); /* log record size must be multiple of BBSIZE; see xlog_rec_header_t */ ASSERT((XFS_BUF_SIZE(bp) & BBMASK) == 0); @@ -1116,8 +1116,8 @@ xlog_alloc_log(xfs_mount_t *mp, ASSERT(XFS_BUF_ISBUSY(iclog->ic_bp)); ASSERT(XFS_BUF_VALUSEMA(iclog->ic_bp) <= 0); - sv_init(&iclog->ic_force_wait, SV_DEFAULT, "iclog-force"); - sv_init(&iclog->ic_write_wait, SV_DEFAULT, "iclog-write"); + init_waitqueue_head(&iclog->ic_force_wait); + init_waitqueue_head(&iclog->ic_write_wait); iclogp = &iclog->ic_next; } @@ -1132,11 +1132,8 @@ xlog_alloc_log(xfs_mount_t *mp, out_free_iclog: for (iclog = log->l_iclog; iclog; iclog = prev_iclog) { prev_iclog = iclog->ic_next; - if (iclog->ic_bp) { - sv_destroy(&iclog->ic_force_wait); - sv_destroy(&iclog->ic_write_wait); + if (iclog->ic_bp) xfs_buf_free(iclog->ic_bp); - } kmem_free(iclog); } spinlock_destroy(&log->l_icloglock); @@ -1453,8 +1450,6 @@ xlog_dealloc_log(xlog_t *log) iclog = log->l_iclog; for (i=0; il_iclog_bufs; i++) { - sv_destroy(&iclog->ic_force_wait); - sv_destroy(&iclog->ic_write_wait); xfs_buf_free(iclog->ic_bp); next_iclog = iclog->ic_next; kmem_free(iclog); @@ -2261,7 +2256,7 @@ xlog_state_do_callback( xlog_state_clean_log(log); /* wake up threads waiting in xfs_log_force() */ - sv_broadcast(&iclog->ic_force_wait); + wake_up_all(&iclog->ic_force_wait); iclog = iclog->ic_next; } while (first_iclog != iclog); @@ -2308,7 +2303,7 @@ xlog_state_do_callback( spin_unlock(&log->l_icloglock); if (wake) - sv_broadcast(&log->l_flush_wait); + wake_up_all(&log->l_flush_wait); } @@ -2359,7 +2354,7 @@ xlog_state_done_syncing( * iclog buffer, we wake them all, one will get to do the * I/O, the others get to wait for the result. */ - sv_broadcast(&iclog->ic_write_wait); + wake_up_all(&iclog->ic_write_wait); spin_unlock(&log->l_icloglock); xlog_state_do_callback(log, aborted, iclog); /* also cleans log */ } /* xlog_state_done_syncing */ @@ -2408,7 +2403,7 @@ restart: XFS_STATS_INC(xs_log_noiclogs); /* Wait for log writes to have flushed */ - sv_wait(&log->l_flush_wait, 0, &log->l_icloglock, 0); + xlog_wait(&log->l_flush_wait, &log->l_icloglock); goto restart; } @@ -2523,7 +2518,8 @@ xlog_grant_log_space(xlog_t *log, goto error_return; XFS_STATS_INC(xs_sleep_logspace); - sv_wait(&tic->t_wait, PINOD|PLTWAIT, &log->l_grant_lock, s); + xlog_wait(&tic->t_wait, &log->l_grant_lock); + /* * If we got an error, and the filesystem is shutting down, * we'll catch it down below. So just continue... @@ -2552,7 +2548,7 @@ redo: spin_lock(&log->l_grant_lock); XFS_STATS_INC(xs_sleep_logspace); - sv_wait(&tic->t_wait, PINOD|PLTWAIT, &log->l_grant_lock, s); + xlog_wait(&tic->t_wait, &log->l_grant_lock); spin_lock(&log->l_grant_lock); if (XLOG_FORCED_SHUTDOWN(log)) @@ -2635,7 +2631,7 @@ xlog_regrant_write_log_space(xlog_t *log, if (free_bytes < ntic->t_unit_res) break; free_bytes -= ntic->t_unit_res; - sv_signal(&ntic->t_wait); + wake_up(&ntic->t_wait); } if (ntic != list_first_entry(&log->l_writeq, @@ -2650,8 +2646,7 @@ xlog_regrant_write_log_space(xlog_t *log, spin_lock(&log->l_grant_lock); XFS_STATS_INC(xs_sleep_logspace); - sv_wait(&tic->t_wait, PINOD|PLTWAIT, - &log->l_grant_lock, s); + xlog_wait(&tic->t_wait, &log->l_grant_lock); /* If we're shutting down, this tic is already * off the queue */ @@ -2677,8 +2672,7 @@ redo: XFS_STATS_INC(xs_sleep_logspace); trace_xfs_log_regrant_write_sleep2(log, tic); - - sv_wait(&tic->t_wait, PINOD|PLTWAIT, &log->l_grant_lock, s); + xlog_wait(&tic->t_wait, &log->l_grant_lock); /* If we're shutting down, this tic is already off the queue */ spin_lock(&log->l_grant_lock); @@ -3029,7 +3023,7 @@ maybe_sleep: return XFS_ERROR(EIO); } XFS_STATS_INC(xs_log_force_sleep); - sv_wait(&iclog->ic_force_wait, PINOD, &log->l_icloglock, s); + xlog_wait(&iclog->ic_force_wait, &log->l_icloglock); /* * No need to grab the log lock here since we're * only deciding whether or not to return EIO @@ -3147,8 +3141,8 @@ try_again: XFS_STATS_INC(xs_log_force_sleep); - sv_wait(&iclog->ic_prev->ic_write_wait, - PSWP, &log->l_icloglock, s); + xlog_wait(&iclog->ic_prev->ic_write_wait, + &log->l_icloglock); if (log_flushed) *log_flushed = 1; already_slept = 1; @@ -3176,7 +3170,7 @@ try_again: return XFS_ERROR(EIO); } XFS_STATS_INC(xs_log_force_sleep); - sv_wait(&iclog->ic_force_wait, PSWP, &log->l_icloglock, s); + xlog_wait(&iclog->ic_force_wait, &log->l_icloglock); /* * No need to grab the log lock here since we're * only deciding whether or not to return EIO @@ -3251,10 +3245,8 @@ xfs_log_ticket_put( xlog_ticket_t *ticket) { ASSERT(atomic_read(&ticket->t_ref) > 0); - if (atomic_dec_and_test(&ticket->t_ref)) { - sv_destroy(&ticket->t_wait); + if (atomic_dec_and_test(&ticket->t_ref)) kmem_zone_free(xfs_log_ticket_zone, ticket); - } } xlog_ticket_t * @@ -3387,7 +3379,7 @@ xlog_ticket_alloc( tic->t_trans_type = 0; if (xflags & XFS_LOG_PERM_RESERV) tic->t_flags |= XLOG_TIC_PERM_RESERV; - sv_init(&tic->t_wait, SV_DEFAULT, "logtick"); + init_waitqueue_head(&tic->t_wait); xlog_tic_reset_res(tic); @@ -3719,10 +3711,10 @@ xfs_log_force_umount( * action is protected by the GRANTLOCK. */ list_for_each_entry(tic, &log->l_reserveq, t_queue) - sv_signal(&tic->t_wait); + wake_up(&tic->t_wait); list_for_each_entry(tic, &log->l_writeq, t_queue) - sv_signal(&tic->t_wait); + wake_up(&tic->t_wait); spin_unlock(&log->l_grant_lock); if (!(log->l_iclog->ic_state & XLOG_STATE_IOERROR)) { diff --git a/fs/xfs/xfs_log_cil.c b/fs/xfs/xfs_log_cil.c index f36f1a2f4dc1..9dc8125d04e5 100644 --- a/fs/xfs/xfs_log_cil.c +++ b/fs/xfs/xfs_log_cil.c @@ -61,7 +61,7 @@ xlog_cil_init( INIT_LIST_HEAD(&cil->xc_committing); spin_lock_init(&cil->xc_cil_lock); init_rwsem(&cil->xc_ctx_lock); - sv_init(&cil->xc_commit_wait, SV_DEFAULT, "cilwait"); + init_waitqueue_head(&cil->xc_commit_wait); INIT_LIST_HEAD(&ctx->committing); INIT_LIST_HEAD(&ctx->busy_extents); @@ -563,7 +563,7 @@ restart: * It is still being pushed! Wait for the push to * complete, then start again from the beginning. */ - sv_wait(&cil->xc_commit_wait, 0, &cil->xc_cil_lock, 0); + xlog_wait(&cil->xc_commit_wait, &cil->xc_cil_lock); goto restart; } } @@ -587,7 +587,7 @@ restart: */ spin_lock(&cil->xc_cil_lock); ctx->commit_lsn = commit_lsn; - sv_broadcast(&cil->xc_commit_wait); + wake_up_all(&cil->xc_commit_wait); spin_unlock(&cil->xc_cil_lock); /* release the hounds! */ @@ -752,7 +752,7 @@ restart: * It is still being pushed! Wait for the push to * complete, then start again from the beginning. */ - sv_wait(&cil->xc_commit_wait, 0, &cil->xc_cil_lock, 0); + xlog_wait(&cil->xc_commit_wait, &cil->xc_cil_lock); goto restart; } if (ctx->sequence != sequence) diff --git a/fs/xfs/xfs_log_priv.h b/fs/xfs/xfs_log_priv.h index 2f74c80a7a40..e2bb276eb2a7 100644 --- a/fs/xfs/xfs_log_priv.h +++ b/fs/xfs/xfs_log_priv.h @@ -241,7 +241,7 @@ typedef struct xlog_res { } xlog_res_t; typedef struct xlog_ticket { - sv_t t_wait; /* ticket wait queue : 20 */ + wait_queue_head_t t_wait; /* ticket wait queue */ struct list_head t_queue; /* reserve/write queue */ xlog_tid_t t_tid; /* transaction identifier : 4 */ atomic_t t_ref; /* ticket reference count : 4 */ @@ -349,8 +349,8 @@ typedef union xlog_in_core2 { * and move everything else out to subsequent cachelines. */ typedef struct xlog_in_core { - sv_t ic_force_wait; - sv_t ic_write_wait; + wait_queue_head_t ic_force_wait; + wait_queue_head_t ic_write_wait; struct xlog_in_core *ic_next; struct xlog_in_core *ic_prev; struct xfs_buf *ic_bp; @@ -417,7 +417,7 @@ struct xfs_cil { struct xfs_cil_ctx *xc_ctx; struct rw_semaphore xc_ctx_lock; struct list_head xc_committing; - sv_t xc_commit_wait; + wait_queue_head_t xc_commit_wait; xfs_lsn_t xc_current_sequence; }; @@ -499,7 +499,7 @@ typedef struct log { int l_logBBsize; /* size of log in BB chunks */ /* The following block of fields are changed while holding icloglock */ - sv_t l_flush_wait ____cacheline_aligned_in_smp; + wait_queue_head_t l_flush_wait ____cacheline_aligned_in_smp; /* waiting for iclog flush */ int l_covered_state;/* state of "covering disk * log entries" */ @@ -602,6 +602,21 @@ xlog_cil_force(struct log *log) */ #define XLOG_UNMOUNT_REC_TYPE (-1U) +/* + * Wrapper function for waiting on a wait queue serialised against wakeups + * by a spinlock. This matches the semantics of all the wait queues used in the + * log code. + */ +static inline void xlog_wait(wait_queue_head_t *wq, spinlock_t *lock) +{ + DECLARE_WAITQUEUE(wait, current); + + add_wait_queue_exclusive(wq, &wait); + __set_current_state(TASK_UNINTERRUPTIBLE); + spin_unlock(lock); + schedule(); + remove_wait_queue(wq, &wait); +} #endif /* __KERNEL__ */ #endif /* __XFS_LOG_PRIV_H__ */ -- cgit v1.2.3 From 2ced19cbae5448b720919a494606c62095d4f4db Mon Sep 17 00:00:00 2001 From: Dave Chinner Date: Tue, 21 Dec 2010 12:09:20 +1100 Subject: xfs: make AIL tail pushing independent of the grant lock The xlog_grant_push_ail() currently takes the grant lock internally to sample the tail lsn, last sync lsn and the reserve grant head. Most of the callers already hold the grant lock but have to drop it before calling xlog_grant_push_ail(). This is a left over from when the AIL tail pushing was done in line and hence xlog_grant_push_ail had to drop the grant lock. AIL push is now done in another thread and hence we can safely hold the grant lock over the entire xlog_grant_push_ail call. Push the grant lock outside of xlog_grant_push_ail() to simplify the locking and synchronisation needed for tail pushing. This will reduce traffic on the grant lock by itself, but this is only one step in preparing for the complete removal of the grant lock. While there, clean up the formatting of xlog_grant_push_ail() to match the rest of the XFS code. Signed-off-by: Dave Chinner Reviewed-by: Christoph Hellwig --- fs/xfs/xfs_log.c | 111 +++++++++++++++++++++++++++---------------------------- 1 file changed, 54 insertions(+), 57 deletions(-) diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c index cc0504e0bb3b..1e2020d5a8b6 100644 --- a/fs/xfs/xfs_log.c +++ b/fs/xfs/xfs_log.c @@ -70,7 +70,7 @@ STATIC void xlog_state_want_sync(xlog_t *log, xlog_in_core_t *iclog); /* local functions to manipulate grant head */ STATIC int xlog_grant_log_space(xlog_t *log, xlog_ticket_t *xtic); -STATIC void xlog_grant_push_ail(xfs_mount_t *mp, +STATIC void xlog_grant_push_ail(struct log *log, int need_bytes); STATIC void xlog_regrant_reserve_log_space(xlog_t *log, xlog_ticket_t *ticket); @@ -318,7 +318,9 @@ xfs_log_reserve( trace_xfs_log_reserve(log, internal_ticket); - xlog_grant_push_ail(mp, internal_ticket->t_unit_res); + spin_lock(&log->l_grant_lock); + xlog_grant_push_ail(log, internal_ticket->t_unit_res); + spin_unlock(&log->l_grant_lock); retval = xlog_regrant_write_log_space(log, internal_ticket); } else { /* may sleep if need to allocate more tickets */ @@ -332,9 +334,11 @@ xfs_log_reserve( trace_xfs_log_reserve(log, internal_ticket); - xlog_grant_push_ail(mp, + spin_lock(&log->l_grant_lock); + xlog_grant_push_ail(log, (internal_ticket->t_unit_res * internal_ticket->t_cnt)); + spin_unlock(&log->l_grant_lock); retval = xlog_grant_log_space(log, internal_ticket); } @@ -1185,59 +1189,58 @@ xlog_commit_record( * water mark. In this manner, we would be creating a low water mark. */ STATIC void -xlog_grant_push_ail(xfs_mount_t *mp, - int need_bytes) +xlog_grant_push_ail( + struct log *log, + int need_bytes) { - xlog_t *log = mp->m_log; /* pointer to the log */ - xfs_lsn_t tail_lsn; /* lsn of the log tail */ - xfs_lsn_t threshold_lsn = 0; /* lsn we'd like to be at */ - int free_blocks; /* free blocks left to write to */ - int free_bytes; /* free bytes left to write to */ - int threshold_block; /* block in lsn we'd like to be at */ - int threshold_cycle; /* lsn cycle we'd like to be at */ - int free_threshold; - - ASSERT(BTOBB(need_bytes) < log->l_logBBsize); - - spin_lock(&log->l_grant_lock); - free_bytes = xlog_space_left(log, &log->l_grant_reserve_head); - tail_lsn = log->l_tail_lsn; - free_blocks = BTOBBT(free_bytes); - - /* - * Set the threshold for the minimum number of free blocks in the - * log to the maximum of what the caller needs, one quarter of the - * log, and 256 blocks. - */ - free_threshold = BTOBB(need_bytes); - free_threshold = MAX(free_threshold, (log->l_logBBsize >> 2)); - free_threshold = MAX(free_threshold, 256); - if (free_blocks < free_threshold) { + xfs_lsn_t threshold_lsn = 0; + xfs_lsn_t tail_lsn; + int free_blocks; + int free_bytes; + int threshold_block; + int threshold_cycle; + int free_threshold; + + ASSERT(BTOBB(need_bytes) < log->l_logBBsize); + + tail_lsn = log->l_tail_lsn; + free_bytes = xlog_space_left(log, &log->l_grant_reserve_head); + free_blocks = BTOBBT(free_bytes); + + /* + * Set the threshold for the minimum number of free blocks in the + * log to the maximum of what the caller needs, one quarter of the + * log, and 256 blocks. + */ + free_threshold = BTOBB(need_bytes); + free_threshold = MAX(free_threshold, (log->l_logBBsize >> 2)); + free_threshold = MAX(free_threshold, 256); + if (free_blocks >= free_threshold) + return; + threshold_block = BLOCK_LSN(tail_lsn) + free_threshold; threshold_cycle = CYCLE_LSN(tail_lsn); if (threshold_block >= log->l_logBBsize) { - threshold_block -= log->l_logBBsize; - threshold_cycle += 1; + threshold_block -= log->l_logBBsize; + threshold_cycle += 1; } - threshold_lsn = xlog_assign_lsn(threshold_cycle, threshold_block); - - /* Don't pass in an lsn greater than the lsn of the last + threshold_lsn = xlog_assign_lsn(threshold_cycle, + threshold_block); + /* + * Don't pass in an lsn greater than the lsn of the last * log record known to be on disk. */ if (XFS_LSN_CMP(threshold_lsn, log->l_last_sync_lsn) > 0) - threshold_lsn = log->l_last_sync_lsn; - } - spin_unlock(&log->l_grant_lock); - - /* - * Get the transaction layer to kick the dirty buffers out to - * disk asynchronously. No point in trying to do this if - * the filesystem is shutting down. - */ - if (threshold_lsn && - !XLOG_FORCED_SHUTDOWN(log)) - xfs_trans_ail_push(log->l_ailp, threshold_lsn); -} /* xlog_grant_push_ail */ + threshold_lsn = log->l_last_sync_lsn; + + /* + * Get the transaction layer to kick the dirty buffers out to + * disk asynchronously. No point in trying to do this if + * the filesystem is shutting down. + */ + if (!XLOG_FORCED_SHUTDOWN(log)) + xfs_trans_ail_push(log->l_ailp, threshold_lsn); +} /* * The bdstrat callback function for log bufs. This gives us a central @@ -2543,9 +2546,7 @@ redo: trace_xfs_log_grant_sleep2(log, tic); - spin_unlock(&log->l_grant_lock); - xlog_grant_push_ail(log->l_mp, need_bytes); - spin_lock(&log->l_grant_lock); + xlog_grant_push_ail(log, need_bytes); XFS_STATS_INC(xs_sleep_logspace); xlog_wait(&tic->t_wait, &log->l_grant_lock); @@ -2641,9 +2642,7 @@ xlog_regrant_write_log_space(xlog_t *log, trace_xfs_log_regrant_write_sleep1(log, tic); - spin_unlock(&log->l_grant_lock); - xlog_grant_push_ail(log->l_mp, need_bytes); - spin_lock(&log->l_grant_lock); + xlog_grant_push_ail(log, need_bytes); XFS_STATS_INC(xs_sleep_logspace); xlog_wait(&tic->t_wait, &log->l_grant_lock); @@ -2666,9 +2665,7 @@ redo: if (free_bytes < need_bytes) { if (list_empty(&tic->t_queue)) list_add_tail(&tic->t_queue, &log->l_writeq); - spin_unlock(&log->l_grant_lock); - xlog_grant_push_ail(log->l_mp, need_bytes); - spin_lock(&log->l_grant_lock); + xlog_grant_push_ail(log, need_bytes); XFS_STATS_INC(xs_sleep_logspace); trace_xfs_log_regrant_write_sleep2(log, tic); -- cgit v1.2.3 From 84f3c683c4d3f36d3c3ed320babd960a332ac458 Mon Sep 17 00:00:00 2001 From: Dave Chinner Date: Fri, 3 Dec 2010 22:11:29 +1100 Subject: xfs: convert l_last_sync_lsn to an atomic variable log->l_last_sync_lsn is updated in only one critical spot - log buffer Io completion - and is protected by the grant lock here. This requires the grant lock to be taken for every log buffer IO completion. Converting the l_last_sync_lsn variable to an atomic64_t means that we do not need to take the grant lock in log buffer IO completion to update it. This also removes the need for explicitly holding a spinlock to read the l_last_sync_lsn on 32 bit platforms. Signed-off-by: Dave Chinner Reviewed-by: Christoph Hellwig --- fs/xfs/xfs_log.c | 55 ++++++++++++++++++++++-------------------------- fs/xfs/xfs_log_priv.h | 9 +++++++- fs/xfs/xfs_log_recover.c | 6 +++--- 3 files changed, 36 insertions(+), 34 deletions(-) diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c index 1e2020d5a8b6..70790eb48336 100644 --- a/fs/xfs/xfs_log.c +++ b/fs/xfs/xfs_log.c @@ -675,12 +675,8 @@ xfs_log_move_tail(xfs_mount_t *mp, if (XLOG_FORCED_SHUTDOWN(log)) return; - if (tail_lsn == 0) { - /* needed since sync_lsn is 64 bits */ - spin_lock(&log->l_icloglock); - tail_lsn = log->l_last_sync_lsn; - spin_unlock(&log->l_icloglock); - } + if (tail_lsn == 0) + tail_lsn = atomic64_read(&log->l_last_sync_lsn); spin_lock(&log->l_grant_lock); @@ -800,11 +796,9 @@ xlog_assign_tail_lsn(xfs_mount_t *mp) tail_lsn = xfs_trans_ail_tail(mp->m_ail); spin_lock(&log->l_grant_lock); - if (tail_lsn != 0) { - log->l_tail_lsn = tail_lsn; - } else { - tail_lsn = log->l_tail_lsn = log->l_last_sync_lsn; - } + if (!tail_lsn) + tail_lsn = atomic64_read(&log->l_last_sync_lsn); + log->l_tail_lsn = tail_lsn; spin_unlock(&log->l_grant_lock); return tail_lsn; @@ -1014,9 +1008,9 @@ xlog_alloc_log(xfs_mount_t *mp, log->l_flags |= XLOG_ACTIVE_RECOVERY; log->l_prev_block = -1; - log->l_tail_lsn = xlog_assign_lsn(1, 0); /* log->l_tail_lsn = 0x100000000LL; cycle = 1; current block = 0 */ - log->l_last_sync_lsn = log->l_tail_lsn; + log->l_tail_lsn = xlog_assign_lsn(1, 0); + atomic64_set(&log->l_last_sync_lsn, xlog_assign_lsn(1, 0)); log->l_curr_cycle = 1; /* 0 is bad since this is initial value */ xlog_assign_grant_head(&log->l_grant_reserve_head, 1, 0); xlog_assign_grant_head(&log->l_grant_write_head, 1, 0); @@ -1194,6 +1188,7 @@ xlog_grant_push_ail( int need_bytes) { xfs_lsn_t threshold_lsn = 0; + xfs_lsn_t last_sync_lsn; xfs_lsn_t tail_lsn; int free_blocks; int free_bytes; @@ -1228,10 +1223,12 @@ xlog_grant_push_ail( threshold_block); /* * Don't pass in an lsn greater than the lsn of the last - * log record known to be on disk. + * log record known to be on disk. Use a snapshot of the last sync lsn + * so that it doesn't change between the compare and the set. */ - if (XFS_LSN_CMP(threshold_lsn, log->l_last_sync_lsn) > 0) - threshold_lsn = log->l_last_sync_lsn; + last_sync_lsn = atomic64_read(&log->l_last_sync_lsn); + if (XFS_LSN_CMP(threshold_lsn, last_sync_lsn) > 0) + threshold_lsn = last_sync_lsn; /* * Get the transaction layer to kick the dirty buffers out to @@ -2194,7 +2191,7 @@ xlog_state_do_callback( lowest_lsn = xlog_get_lowest_lsn(log); if (lowest_lsn && XFS_LSN_CMP(lowest_lsn, - be64_to_cpu(iclog->ic_header.h_lsn)) < 0) { + be64_to_cpu(iclog->ic_header.h_lsn)) < 0) { iclog = iclog->ic_next; continue; /* Leave this iclog for * another thread */ @@ -2202,23 +2199,21 @@ xlog_state_do_callback( iclog->ic_state = XLOG_STATE_CALLBACK; - spin_unlock(&log->l_icloglock); - /* l_last_sync_lsn field protected by - * l_grant_lock. Don't worry about iclog's lsn. - * No one else can be here except us. + /* + * update the last_sync_lsn before we drop the + * icloglock to ensure we are the only one that + * can update it. */ - spin_lock(&log->l_grant_lock); - ASSERT(XFS_LSN_CMP(log->l_last_sync_lsn, - be64_to_cpu(iclog->ic_header.h_lsn)) <= 0); - log->l_last_sync_lsn = - be64_to_cpu(iclog->ic_header.h_lsn); - spin_unlock(&log->l_grant_lock); + ASSERT(XFS_LSN_CMP(atomic64_read(&log->l_last_sync_lsn), + be64_to_cpu(iclog->ic_header.h_lsn)) <= 0); + atomic64_set(&log->l_last_sync_lsn, + be64_to_cpu(iclog->ic_header.h_lsn)); - } else { - spin_unlock(&log->l_icloglock); + } else ioerrors++; - } + + spin_unlock(&log->l_icloglock); /* * Keep processing entries in the callback list until diff --git a/fs/xfs/xfs_log_priv.h b/fs/xfs/xfs_log_priv.h index e2bb276eb2a7..958f356df10e 100644 --- a/fs/xfs/xfs_log_priv.h +++ b/fs/xfs/xfs_log_priv.h @@ -507,7 +507,6 @@ typedef struct log { spinlock_t l_icloglock; /* grab to change iclog state */ xfs_lsn_t l_tail_lsn; /* lsn of 1st LR with unflushed * buffers */ - xfs_lsn_t l_last_sync_lsn;/* lsn of last LR on disk */ int l_curr_cycle; /* Cycle number of log writes */ int l_prev_cycle; /* Cycle number before last * block increment */ @@ -521,6 +520,14 @@ typedef struct log { int64_t l_grant_reserve_head; int64_t l_grant_write_head; + /* + * l_last_sync_lsn is an atomic so it can be set and read without + * needing to hold specific locks. To avoid operations contending with + * other hot objects, place it on a separate cacheline. + */ + /* lsn of last LR on disk */ + atomic64_t l_last_sync_lsn ____cacheline_aligned_in_smp; + /* The following field are used for debugging; need to hold icloglock */ #ifdef DEBUG char *l_iclog_bak[XLOG_MAX_ICLOGS]; diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index 1550404a8aeb..18e1e18d7147 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c @@ -937,7 +937,7 @@ xlog_find_tail( if (found == 2) log->l_curr_cycle++; log->l_tail_lsn = be64_to_cpu(rhead->h_tail_lsn); - log->l_last_sync_lsn = be64_to_cpu(rhead->h_lsn); + atomic64_set(&log->l_last_sync_lsn, be64_to_cpu(rhead->h_lsn)); xlog_assign_grant_head(&log->l_grant_reserve_head, log->l_curr_cycle, BBTOB(log->l_curr_block)); xlog_assign_grant_head(&log->l_grant_write_head, log->l_curr_cycle, @@ -989,9 +989,9 @@ xlog_find_tail( log->l_tail_lsn = xlog_assign_lsn(log->l_curr_cycle, after_umount_blk); - log->l_last_sync_lsn = + atomic64_set(&log->l_last_sync_lsn, xlog_assign_lsn(log->l_curr_cycle, - after_umount_blk); + after_umount_blk)); *tail_blk = after_umount_blk; /* -- cgit v1.2.3 From a1087ef6abedf0bfd60e5e3fddf33192cb2c1325 Mon Sep 17 00:00:00 2001 From: Julia Lawall Date: Wed, 24 Nov 2010 15:54:18 +0100 Subject: scripts/coccinelle: update for compatability with Coccinelle 0.2.4 For doubleinit.cocci, Coccinelle 0.2.4 requires a comma after ... in a field list. Coccinelle also now behaves gracefully when a definition is provided for a virtual that doesn't exist, so there is no need for the semantic patch code to check for this case. Updated the documentation to reflect the fact that the best results will now be obtained with Coccinelle version 0.2.4 or later. Signed-off-by: Julia Lawall --- Documentation/coccinelle.txt | 4 ++++ scripts/coccinelle/misc/doubleinit.cocci | 6 ++--- scripts/coccinelle/null/deref_null.cocci | 39 ++++++++++++-------------------- 3 files changed, 21 insertions(+), 28 deletions(-) diff --git a/Documentation/coccinelle.txt b/Documentation/coccinelle.txt index 4a276ea7001c..96b690348ba1 100644 --- a/Documentation/coccinelle.txt +++ b/Documentation/coccinelle.txt @@ -36,6 +36,10 @@ as a regular user, and install it with sudo make install +The semantic patches in the kernel will work best with Coccinelle version +0.2.4 or later. Using earlier versions may incur some parse errors in the +semantic patch code, but any results that are obtained should still be +correct. Using Coccinelle on the Linux kernel ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/scripts/coccinelle/misc/doubleinit.cocci b/scripts/coccinelle/misc/doubleinit.cocci index 55d7dc19dfe0..156b20adb351 100644 --- a/scripts/coccinelle/misc/doubleinit.cocci +++ b/scripts/coccinelle/misc/doubleinit.cocci @@ -7,7 +7,7 @@ // Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. // Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. // URL: http://coccinelle.lip6.fr/ -// Comments: +// Comments: requires at least Coccinelle 0.2.4, lex or parse error otherwise // Options: -no_includes -include_headers virtual org @@ -19,7 +19,7 @@ position p0,p; expression E; @@ -struct I s =@p0 { ... .fld@p = E, ...}; +struct I s =@p0 { ..., .fld@p = E, ...}; @s@ identifier I, s, r.fld; @@ -27,7 +27,7 @@ position r.p0,p; expression E; @@ -struct I s =@p0 { ... .fld@p = E, ...}; +struct I s =@p0 { ..., .fld@p = E, ...}; @script:python depends on org@ p0 << r.p0; diff --git a/scripts/coccinelle/null/deref_null.cocci b/scripts/coccinelle/null/deref_null.cocci index 9969d76d0f4b..cdac6cfcce92 100644 --- a/scripts/coccinelle/null/deref_null.cocci +++ b/scripts/coccinelle/null/deref_null.cocci @@ -11,21 +11,10 @@ // Options: virtual context -virtual patch virtual org virtual report -@initialize:python depends on !context && patch && !org && !report@ - -import sys -print >> sys.stderr, "This semantic patch does not support the 'patch' mode." - -@depends on patch@ -@@ - -this_rule_should_never_matches(); - -@ifm depends on !patch@ +@ifm@ expression *E; statement S1,S2; position p1; @@ -35,7 +24,7 @@ if@p1 ((E == NULL && ...) || ...) S1 else S2 // The following two rules are separate, because both can match a single // expression in different ways -@pr1 depends on !patch expression@ +@pr1 expression@ expression *ifm.E; identifier f; position p1; @@ -43,7 +32,7 @@ position p1; (E != NULL && ...) ? <+...E->f@p1...+> : ... -@pr2 depends on !patch expression@ +@pr2 expression@ expression *ifm.E; identifier f; position p2; @@ -59,7 +48,7 @@ position p2; // For org and report modes -@r depends on !context && !patch && (org || report) exists@ +@r depends on !context && (org || report) exists@ expression subE <= ifm.E; expression *ifm.E; expression E1,E2; @@ -99,7 +88,7 @@ if@p1 ((E == NULL && ...) || ...) } else S3 -@script:python depends on !context && !patch && !org && report@ +@script:python depends on !context && !org && report@ p << r.p; p1 << ifm.p1; x << ifm.E; @@ -109,7 +98,7 @@ msg="ERROR: %s is NULL but dereferenced." % (x) coccilib.report.print_report(p[0], msg) cocci.include_match(False) -@script:python depends on !context && !patch && org && !report@ +@script:python depends on !context && org && !report@ p << r.p; p1 << ifm.p1; x << ifm.E; @@ -120,7 +109,7 @@ msg_safe=msg.replace("[","@(").replace("]",")") cocci.print_main(msg_safe,p) cocci.include_match(False) -@s depends on !context && !patch && (org || report) exists@ +@s depends on !context && (org || report) exists@ expression subE <= ifm.E; expression *ifm.E; expression E1,E2; @@ -159,7 +148,7 @@ if@p1 ((E == NULL && ...) || ...) } else S3 -@script:python depends on !context && !patch && !org && report@ +@script:python depends on !context && !org && report@ p << s.p; p1 << ifm.p1; x << ifm.E; @@ -168,7 +157,7 @@ x << ifm.E; msg="ERROR: %s is NULL but dereferenced." % (x) coccilib.report.print_report(p[0], msg) -@script:python depends on !context && !patch && org && !report@ +@script:python depends on !context && org && !report@ p << s.p; p1 << ifm.p1; x << ifm.E; @@ -180,7 +169,7 @@ cocci.print_main(msg_safe,p) // For context mode -@depends on context && !patch && !org && !report exists@ +@depends on context && !org && !report exists@ expression subE <= ifm.E; expression *ifm.E; expression E1,E2; @@ -223,7 +212,7 @@ else S3 // The following three rules are duplicates of ifm, pr1 and pr2 respectively. // It is need because the previous rule as already made a "change". -@ifm1 depends on !patch@ +@ifm1@ expression *E; statement S1,S2; position p1; @@ -231,7 +220,7 @@ position p1; if@p1 ((E == NULL && ...) || ...) S1 else S2 -@pr11 depends on !patch expression@ +@pr11 expression@ expression *ifm1.E; identifier f; position p1; @@ -239,7 +228,7 @@ position p1; (E != NULL && ...) ? <+...E->f@p1...+> : ... -@pr12 depends on !patch expression@ +@pr12 expression@ expression *ifm1.E; identifier f; position p2; @@ -253,7 +242,7 @@ position p2; sizeof(<+...E->f@p2...+>) ) -@depends on context && !patch && !org && !report exists@ +@depends on context && !org && !report exists@ expression subE <= ifm1.E; expression *ifm1.E; expression E1,E2; -- cgit v1.2.3 From a3de8ab8853c5a14e881f0a01aa31e3dc87fc304 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 3 Dec 2010 12:29:14 +0100 Subject: ALSA: hda - Clean up cxt5066 port-D handling & co Instead of hard-coded magic numbers, properly define and use macros for improve the readability. Also, dell_automute is handled samely as thinkpad, since it also sets port_d_mode, too. Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_conexant.c | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index e652b34b1bd9..cb15ac9ee137 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c @@ -2111,6 +2111,11 @@ static struct hda_channel_mode cxt5066_modes[1] = { { 2, NULL }, }; +#define HP_PRESENT_PORT_A (1 << 0) +#define HP_PRESENT_PORT_D (1 << 1) +#define hp_port_a_present(spec) ((spec)->hp_present & HP_PRESENT_PORT_A) +#define hp_port_d_present(spec) ((spec)->hp_present & HP_PRESENT_PORT_D) + static void cxt5066_update_speaker(struct hda_codec *codec) { struct conexant_spec *spec = codec->spec; @@ -2120,24 +2125,20 @@ static void cxt5066_update_speaker(struct hda_codec *codec) spec->hp_present, spec->cur_eapd); /* Port A (HP) */ - pinctl = ((spec->hp_present & 1) && spec->cur_eapd) ? PIN_HP : 0; + pinctl = (hp_port_a_present(spec) && spec->cur_eapd) ? PIN_HP : 0; snd_hda_codec_write(codec, 0x19, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pinctl); /* Port D (HP/LO) */ - if (spec->dell_automute) { - /* DELL AIO Port Rule: PortA> PortD> IntSpk */ - pinctl = (!(spec->hp_present & 1) && spec->cur_eapd) - ? PIN_OUT : 0; - } else if (spec->thinkpad) { - if (spec->cur_eapd) - pinctl = spec->port_d_mode; - /* Mute dock line-out if Port A (laptop HP) is present */ - if (spec->hp_present& 1) + pinctl = spec->cur_eapd ? spec->port_d_mode : 0; + if (spec->dell_automute || spec->thinkpad) { + /* Mute if Port A is connected */ + if (hp_port_a_present(spec)) pinctl = 0; } else { - pinctl = ((spec->hp_present & 2) && spec->cur_eapd) - ? spec->port_d_mode : 0; + /* Thinkpad/Dell doesn't give pin-D status */ + if (!hp_port_d_present(spec)) + pinctl = 0; } snd_hda_codec_write(codec, 0x1c, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pinctl); @@ -2379,8 +2380,8 @@ static void cxt5066_hp_automute(struct hda_codec *codec) /* Port D */ portD = snd_hda_jack_detect(codec, 0x1c); - spec->hp_present = !!(portA); - spec->hp_present |= portD ? 2 : 0; + spec->hp_present = portA ? HP_PRESENT_PORT_A : 0; + spec->hp_present |= portD ? HP_PRESENT_PORT_D : 0; snd_printdd("CXT5066: hp automute portA=%x portD=%x present=%d\n", portA, portD, spec->hp_present); cxt5066_update_speaker(codec); -- cgit v1.2.3 From a00f90f9306c06bee8e909628f39052bb3b0cc9e Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 2 Dec 2010 16:24:24 +0000 Subject: ASoC: Apostrophe patrol in soc-core.c Silly little grammar nit but it bugs the hell out of me. Signed-off-by: Mark Brown Acked-by: Liam Girdwood --- 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 eb950f73076a..20dcc978588f 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -525,7 +525,7 @@ static int soc_pcm_open(struct snd_pcm_substream *substream) } } - /* Check that the codec and cpu DAI's are compatible */ + /* Check that the codec and cpu DAIs are compatible */ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { runtime->hw.rate_min = max(codec_dai_drv->playback.rate_min, @@ -874,7 +874,7 @@ codec_err: } /* - * Free's resources allocated by hw_params, can be called multiple times + * Frees resources allocated by hw_params, can be called multiple times */ static int soc_pcm_hw_free(struct snd_pcm_substream *substream) { @@ -898,7 +898,7 @@ static int soc_pcm_hw_free(struct snd_pcm_substream *substream) if (platform->driver->ops->hw_free) platform->driver->ops->hw_free(substream); - /* now free hw params for the DAI's */ + /* now free hw params for the DAIs */ if (codec_dai->driver->ops->hw_free) codec_dai->driver->ops->hw_free(substream, codec_dai); @@ -1005,7 +1005,7 @@ static int soc_suspend(struct device *dev) /* we're going to block userspace touching us until resume completes */ snd_power_change_state(card->snd_card, SNDRV_CTL_POWER_D3hot); - /* mute any active DAC's */ + /* mute any active DACs */ for (i = 0; i < card->num_rtd; i++) { struct snd_soc_dai *dai = card->rtd[i].codec_dai; struct snd_soc_dai_driver *drv = dai->driver; -- cgit v1.2.3 From 1ee46ebd0435d547c078859c719d7c892ff7ab2d Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 2 Dec 2010 16:10:09 +0000 Subject: ASoC: Make the DAI ops constant in the DAI structure Neither drivers nor the core should be fiddling with the actual ops structure at runtime. Signed-off-by: Mark Brown Acked-by: Liam Girdwood --- include/sound/soc-dai.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/sound/soc-dai.h b/include/sound/soc-dai.h index 0195b7ee17e1..1bafe95dcf41 100644 --- a/include/sound/soc-dai.h +++ b/include/sound/soc-dai.h @@ -203,7 +203,7 @@ struct snd_soc_dai_driver { int (*resume)(struct snd_soc_dai *dai); /* ops */ - struct snd_soc_dai_ops *ops; + const struct snd_soc_dai_ops *ops; /* DAI capabilities */ struct snd_soc_pcm_stream capture; -- cgit v1.2.3 From c3acec2671cc448bc549b06b561ae2454238e9a0 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 2 Dec 2010 16:15:29 +0000 Subject: ASoC: Move active copy of CODEC read and write into runtime structure We shouldn't be assigning to the driver structure (which really ought to be const, further patch to follow) though there's unlikely to be any actual problem except in the unlikely case that two devices with the same driver but different bus types appear in the same system. Signed-off-by: Mark Brown Acked-by: Liam Girdwood --- include/sound/soc.h | 2 ++ sound/soc/soc-cache.c | 4 ++-- sound/soc/soc-core.c | 6 ++++-- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/include/sound/soc.h b/include/sound/soc.h index 4a9195c5ef2d..714a70441bf2 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -476,6 +476,8 @@ struct snd_soc_codec { void *control_data; /* codec control (i2c/3wire) data */ hw_write_t hw_write; unsigned int (*hw_read)(struct snd_soc_codec *, unsigned int); + unsigned int (*read)(struct snd_soc_codec *, unsigned int); + int (*write)(struct snd_soc_codec *, unsigned int, unsigned int); void *reg_cache; const struct snd_soc_cache_ops *cache_ops; struct mutex cache_rw_mutex; diff --git a/sound/soc/soc-cache.c b/sound/soc/soc-cache.c index 514398463f7d..78b25e8c03f6 100644 --- a/sound/soc/soc-cache.c +++ b/sound/soc/soc-cache.c @@ -728,8 +728,8 @@ int snd_soc_codec_set_cache_io(struct snd_soc_codec *codec, return -EINVAL; } - codec->driver->write = io_types[i].write; - codec->driver->read = io_types[i].read; + codec->write = io_types[i].write; + codec->read = io_types[i].read; switch (control) { case SND_SOC_CUSTOM: diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 20dcc978588f..5720dbcefbc4 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -2077,7 +2077,7 @@ unsigned int snd_soc_read(struct snd_soc_codec *codec, unsigned int reg) { unsigned int ret; - ret = codec->driver->read(codec, reg); + ret = codec->read(codec, reg); dev_dbg(codec->dev, "read %x => %x\n", reg, ret); trace_snd_soc_reg_read(codec, reg, ret); @@ -2090,7 +2090,7 @@ unsigned int snd_soc_write(struct snd_soc_codec *codec, { dev_dbg(codec->dev, "write %x = %x\n", reg, val); trace_snd_soc_reg_write(codec, reg, val); - return codec->driver->write(codec, reg, val); + return codec->write(codec, reg, val); } EXPORT_SYMBOL_GPL(snd_soc_write); @@ -3448,6 +3448,8 @@ int snd_soc_register_codec(struct device *dev, INIT_LIST_HEAD(&codec->dapm.widgets); INIT_LIST_HEAD(&codec->dapm.paths); + codec->write = codec_drv->write; + codec->read = codec_drv->read; codec->dapm.bias_level = SND_SOC_BIAS_OFF; codec->dapm.dev = dev; codec->dapm.codec = codec; -- cgit v1.2.3 From f7d711e3bb92fcf01ee14b7decf0059ac184efc2 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Fri, 3 Dec 2010 17:36:24 +0900 Subject: ASoC: sh: fsi: clean up SPDIF defines Signed-off-by: Kuninori Morimoto Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/sh/fsi.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c index 507e709f2807..76ef3f34dd02 100644 --- a/sound/soc/sh/fsi.c +++ b/sound/soc/sh/fsi.c @@ -50,13 +50,20 @@ /* DO_FMT */ /* DI_FMT */ +#define CR_BWS_24 (0x0 << 20) /* FSI2 */ +#define CR_BWS_16 (0x1 << 20) /* FSI2 */ +#define CR_BWS_20 (0x2 << 20) /* FSI2 */ + +#define CR_DTMD_PCM (0x0 << 8) /* FSI2 */ +#define CR_DTMD_SPDIF_PCM (0x1 << 8) /* FSI2 */ +#define CR_DTMD_SPDIF_STREAM (0x2 << 8) /* FSI2 */ + #define CR_MONO (0x0 << 4) #define CR_MONO_D (0x1 << 4) #define CR_PCM (0x2 << 4) #define CR_I2S (0x3 << 4) #define CR_TDM (0x4 << 4) #define CR_TDM_D (0x5 << 4) -#define CR_SPDIF 0x00100120 /* DOFF_CTL */ /* DIFF_CTL */ @@ -93,6 +100,10 @@ #define IR (1 << 4) /* Interrupt Reset */ #define FSISR (1 << 0) /* Software Reset */ +/* OUT_SEL (FSI2) */ +#define DMMD (1 << 4) /* SPDIF output timing 0: Biphase only */ + /* 1: Biphase and serial */ + /* FIFO_SZ */ #define FIFO_SZ_MASK 0x7 @@ -828,10 +839,10 @@ static int fsi_dai_startup(struct snd_pcm_substream *substream, dev_err(dai->dev, "This FSI can not use SPDIF\n"); return -EINVAL; } - data = CR_SPDIF; + data = CR_BWS_16 | CR_DTMD_SPDIF_PCM | CR_PCM; io->chan_num = 2; fsi_spdif_clk_ctrl(fsi, 1); - fsi_reg_mask_set(fsi, OUT_SEL, 0x0010, 0x0010); + fsi_reg_mask_set(fsi, OUT_SEL, DMMD, DMMD); break; default: dev_err(dai->dev, "unknown format.\n"); -- cgit v1.2.3 From 48d78e5879b9f9e1beed341f6a30add127f43907 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Fri, 3 Dec 2010 17:37:31 +0900 Subject: ASoC: sh: fsi: remove fsi_master_write Signed-off-by: Kuninori Morimoto Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/sh/fsi.c | 23 ++--------------------- 1 file changed, 2 insertions(+), 21 deletions(-) diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c index 76ef3f34dd02..41f49776d6f2 100644 --- a/sound/soc/sh/fsi.c +++ b/sound/soc/sh/fsi.c @@ -221,21 +221,6 @@ static void fsi_reg_mask_set(struct fsi_priv *fsi, u32 reg, u32 mask, u32 data) __fsi_reg_mask_set((u32)(fsi->base + reg), mask, data); } -static void fsi_master_write(struct fsi_master *master, u32 reg, u32 data) -{ - unsigned long flags; - - if ((reg < MREG_START) || - (reg > MREG_END)) { - pr_err("fsi: register access err (%s)\n", __func__); - return; - } - - spin_lock_irqsave(&master->lock, flags); - __fsi_reg_write((u32)(master->base + reg), data); - spin_unlock_irqrestore(&master->lock, flags); -} - static u32 fsi_master_read(struct fsi_master *master, u32 reg) { u32 ret; @@ -500,11 +485,6 @@ static u32 fsi_irq_get_status(struct fsi_master *master) return fsi_master_read(master, master->core->int_st); } -static void fsi_irq_clear_all_status(struct fsi_master *master) -{ - fsi_master_write(master, master->core->int_st, 0); -} - static void fsi_irq_clear_status(struct fsi_priv *fsi) { u32 data = 0; @@ -756,7 +736,8 @@ static irqreturn_t fsi_interrupt(int irq, void *data) if (int_st & AB_IO(1, BI_SHIFT)) fsi_data_pop(&master->fsib, 0); - fsi_irq_clear_all_status(master); + fsi_irq_clear_status(&master->fsia); + fsi_irq_clear_status(&master->fsib); return IRQ_HANDLED; } -- cgit v1.2.3 From 2b0e73025f74699e9cc9df60649fcc14cd02481b Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Fri, 3 Dec 2010 17:37:44 +0900 Subject: ASoC: sh: fsi: change fsi->mst_ctrl to master->a/b_mclk There was a strange part where fsi->xxx had been used for fsi_master_xxx function instead of master->xxx in current FSI. This patch modify it. Signed-off-by: Kuninori Morimoto Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/sh/fsi.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c index 41f49776d6f2..3927ee598912 100644 --- a/sound/soc/sh/fsi.c +++ b/sound/soc/sh/fsi.c @@ -142,8 +142,6 @@ struct fsi_priv { struct fsi_stream playback; struct fsi_stream capture; - - u32 mst_ctrl; }; struct fsi_core { @@ -152,6 +150,8 @@ struct fsi_core { u32 int_st; u32 iemsk; u32 imsk; + u32 a_mclk; + u32 b_mclk; }; struct fsi_master { @@ -505,17 +505,19 @@ static void fsi_irq_clear_status(struct fsi_priv *fsi) static void fsi_spdif_clk_ctrl(struct fsi_priv *fsi, int enable) { struct fsi_master *master = fsi_get_master(fsi); - u32 val = BP | SE; + u32 mask, val; if (master->core->ver < 2) { pr_err("fsi: register access err (%s)\n", __func__); return; } - if (enable) - fsi_master_mask_set(master, fsi->mst_ctrl, val, val); - else - fsi_master_mask_set(master, fsi->mst_ctrl, val, 0); + mask = BP | SE; + val = enable ? mask : 0; + + fsi_is_port_a(fsi) ? + fsi_master_mask_set(master, master->core->a_mclk, mask, val) : + fsi_master_mask_set(master, master->core->b_mclk, mask, val); } /* @@ -1157,12 +1159,10 @@ static int fsi_probe(struct platform_device *pdev) /* FSI A setting */ master->fsia.base = master->base; master->fsia.master = master; - master->fsia.mst_ctrl = A_MST_CTLR; /* FSI B setting */ master->fsib.base = master->base + 0x40; master->fsib.master = master; - master->fsib.mst_ctrl = B_MST_CTLR; pm_runtime_enable(&pdev->dev); pm_runtime_resume(&pdev->dev); @@ -1249,6 +1249,8 @@ static struct fsi_core fsi2_core = { .int_st = CPU_INT_ST, .iemsk = CPU_IEMSK, .imsk = CPU_IMSK, + .a_mclk = A_MST_CTLR, + .b_mclk = B_MST_CTLR, }; static struct platform_device_id fsi_id_table[] = { -- cgit v1.2.3 From e8c8b6318c3dad742d03b5fff5360729f7ac2e5a Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Fri, 3 Dec 2010 17:37:55 +0900 Subject: ASoC: sh: fsi: remove runtime register check from fsi_reg_xxx Current FSI driver was checking register range on fsi_reg_xxx function. This runtime check was added to avoid an illegal access from wrong/mistake implementation. But it is useless check under the correct implementation. This patch escape runtime check by using macro technique. If there is wrong implementation, it will be compile error. Signed-off-by: Kuninori Morimoto Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/sh/fsi.c | 101 ++++++++++++++++++++++++----------------------------- 1 file changed, 45 insertions(+), 56 deletions(-) diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c index 3927ee598912..66abb6ec0442 100644 --- a/sound/soc/sh/fsi.c +++ b/sound/soc/sh/fsi.c @@ -19,19 +19,19 @@ #include #include -#define DO_FMT 0x0000 -#define DOFF_CTL 0x0004 -#define DOFF_ST 0x0008 -#define DI_FMT 0x000C -#define DIFF_CTL 0x0010 -#define DIFF_ST 0x0014 -#define CKG1 0x0018 -#define CKG2 0x001C -#define DIDT 0x0020 -#define DODT 0x0024 -#define MUTE_ST 0x0028 -#define OUT_SEL 0x0030 -#define REG_END OUT_SEL +/* PortA/PortB register */ +#define REG_DO_FMT 0x0000 +#define REG_DOFF_CTL 0x0004 +#define REG_DOFF_ST 0x0008 +#define REG_DI_FMT 0x000C +#define REG_DIFF_CTL 0x0010 +#define REG_DIFF_ST 0x0014 +#define REG_CKG1 0x0018 +#define REG_CKG2 0x001C +#define REG_DIDT 0x0020 +#define REG_DODT 0x0024 +#define REG_MUTE_ST 0x0028 +#define REG_OUT_SEL 0x0030 #define A_MST_CTLR 0x0180 #define B_MST_CTLR 0x01A0 @@ -191,35 +191,14 @@ static void __fsi_reg_mask_set(u32 reg, u32 mask, u32 data) __fsi_reg_write(reg, val); } -static void fsi_reg_write(struct fsi_priv *fsi, u32 reg, u32 data) -{ - if (reg > REG_END) { - pr_err("fsi: register access err (%s)\n", __func__); - return; - } +#define fsi_reg_write(p, r, d)\ + __fsi_reg_write((u32)(p->base + REG_##r), d) - __fsi_reg_write((u32)(fsi->base + reg), data); -} - -static u32 fsi_reg_read(struct fsi_priv *fsi, u32 reg) -{ - if (reg > REG_END) { - pr_err("fsi: register access err (%s)\n", __func__); - return 0; - } +#define fsi_reg_read(p, r)\ + __fsi_reg_read((u32)(p->base + REG_##r)) - return __fsi_reg_read((u32)(fsi->base + reg)); -} - -static void fsi_reg_mask_set(struct fsi_priv *fsi, u32 reg, u32 mask, u32 data) -{ - if (reg > REG_END) { - pr_err("fsi: register access err (%s)\n", __func__); - return; - } - - __fsi_reg_mask_set((u32)(fsi->base + reg), mask, data); -} +#define fsi_reg_mask_set(p, r, m, d)\ + __fsi_reg_mask_set((u32)(p->base + REG_##r), m, d) static u32 fsi_master_read(struct fsi_master *master, u32 reg) { @@ -369,11 +348,13 @@ static void fsi_stream_pop(struct fsi_priv *fsi, int is_play) static int fsi_get_fifo_data_num(struct fsi_priv *fsi, int is_play) { u32 status; - u32 reg = is_play ? DOFF_ST : DIFF_ST; struct fsi_stream *io = fsi_get_stream(fsi, is_play); int data_num; - status = fsi_reg_read(fsi, reg); + status = is_play ? + fsi_reg_read(fsi, DOFF_ST) : + fsi_reg_read(fsi, DIFF_ST); + data_num = 0x1ff & (status >> 8); data_num *= io->chan_num; @@ -541,7 +522,7 @@ static void fsi_fifo_init(struct fsi_priv *fsi, { struct fsi_master *master = fsi_get_master(fsi); struct fsi_stream *io = fsi_get_stream(fsi, is_play); - u32 ctrl, shift, i; + u32 shift, i; /* get on-chip RAM capacity */ shift = fsi_master_read(master, FIFO_SZ); @@ -574,13 +555,17 @@ static void fsi_fifo_init(struct fsi_priv *fsi, dev_dbg(dai->dev, "%d channel %d store\n", io->chan_num, io->fifo_max_num); - ctrl = is_play ? DOFF_CTL : DIFF_CTL; - - /* set interrupt generation factor */ - fsi_reg_write(fsi, ctrl, IRQ_HALF); - - /* clear FIFO */ - fsi_reg_mask_set(fsi, ctrl, FIFO_CLR, FIFO_CLR); + /* + * set interrupt generation factor + * clear FIFO + */ + if (is_play) { + fsi_reg_write(fsi, DOFF_CTL, IRQ_HALF); + fsi_reg_mask_set(fsi, DOFF_CTL, FIFO_CLR, FIFO_CLR); + } else { + fsi_reg_write(fsi, DIFF_CTL, IRQ_HALF); + fsi_reg_mask_set(fsi, DIFF_CTL, FIFO_CLR, FIFO_CLR); + } } static void fsi_soft_all_reset(struct fsi_master *master) @@ -601,7 +586,6 @@ static int fsi_fifo_data_ctrl(struct fsi_priv *fsi, int startup, int stream) struct snd_pcm_substream *substream = NULL; int is_play = fsi_stream_is_play(stream); struct fsi_stream *io = fsi_get_stream(fsi, is_play); - u32 status_reg = is_play ? DOFF_ST : DIFF_ST; int data_residue_num; int data_num; int data_num_max; @@ -692,14 +676,19 @@ static int fsi_fifo_data_ctrl(struct fsi_priv *fsi, int startup, int stream) /* check fifo status */ if (!startup) { struct snd_soc_dai *dai = fsi_get_dai(substream); - u32 status = fsi_reg_read(fsi, status_reg); + u32 status = is_play ? + fsi_reg_read(fsi, DOFF_ST) : + fsi_reg_read(fsi, DIFF_ST); if (status & ERR_OVER) dev_err(dai->dev, "over run\n"); if (status & ERR_UNDER) dev_err(dai->dev, "under run\n"); } - fsi_reg_write(fsi, status_reg, 0); + + is_play ? + fsi_reg_write(fsi, DOFF_ST, 0) : + fsi_reg_write(fsi, DIFF_ST, 0); /* re-enable irq */ fsi_irq_enable(fsi, is_play); @@ -756,7 +745,6 @@ static int fsi_dai_startup(struct snd_pcm_substream *substream, struct fsi_stream *io; u32 flags = fsi_get_info_flags(fsi); u32 fmt; - u32 reg; u32 data; int is_play = fsi_is_play(substream); int is_master; @@ -788,7 +776,6 @@ static int fsi_dai_startup(struct snd_pcm_substream *substream, /* do fmt, di fmt */ data = 0; - reg = is_play ? DO_FMT : DI_FMT; fmt = is_play ? SH_FSI_GET_OFMT(flags) : SH_FSI_GET_IFMT(flags); switch (fmt) { case SH_FSI_FMT_MONO: @@ -831,7 +818,9 @@ static int fsi_dai_startup(struct snd_pcm_substream *substream, dev_err(dai->dev, "unknown format.\n"); return -EINVAL; } - fsi_reg_write(fsi, reg, data); + is_play ? + fsi_reg_write(fsi, DO_FMT, data) : + fsi_reg_write(fsi, DI_FMT, data); /* irq clear */ fsi_irq_disable(fsi, is_play); -- cgit v1.2.3 From 43fa95caab86fec0af7333bda407dd14f0c2127c Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Fri, 3 Dec 2010 17:38:03 +0900 Subject: ASoC: sh: fsi: remove runtime register check from fsi_master_xxx Current FSI driver was checking register range on fsi_master_xxx function. This runtime check was added to avoid an illegal access from wrong/mistake implementation. But it is useless check under the correct implementation. This patch escape runtime check by using macro technique. If there is wrong implementation, it will be compile error. Signed-off-by: Kuninori Morimoto Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/sh/fsi.c | 48 ++++++++++++++++++++---------------------------- 1 file changed, 20 insertions(+), 28 deletions(-) diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c index 66abb6ec0442..19a2f99be60c 100644 --- a/sound/soc/sh/fsi.c +++ b/sound/soc/sh/fsi.c @@ -33,6 +33,12 @@ #define REG_MUTE_ST 0x0028 #define REG_OUT_SEL 0x0030 +/* master register */ +#define MST_CLK_RST 0x0210 +#define MST_SOFT_RST 0x0214 +#define MST_FIFO_SZ 0x0218 + +/* core register (depend on FSI version) */ #define A_MST_CTLR 0x0180 #define B_MST_CTLR 0x01A0 #define CPU_INT_ST 0x01F4 @@ -41,12 +47,6 @@ #define INT_ST 0x0200 #define IEMSK 0x0204 #define IMSK 0x0208 -#define MUTE 0x020C -#define CLK_RST 0x0210 -#define SOFT_RST 0x0214 -#define FIFO_SZ 0x0218 -#define MREG_START A_MST_CTLR -#define MREG_END FIFO_SZ /* DO_FMT */ /* DI_FMT */ @@ -200,17 +200,13 @@ static void __fsi_reg_mask_set(u32 reg, u32 mask, u32 data) #define fsi_reg_mask_set(p, r, m, d)\ __fsi_reg_mask_set((u32)(p->base + REG_##r), m, d) -static u32 fsi_master_read(struct fsi_master *master, u32 reg) +#define fsi_master_read(p, r) _fsi_master_read(p, MST_##r) +#define fsi_core_read(p, r) _fsi_master_read(p, p->core->r) +static u32 _fsi_master_read(struct fsi_master *master, u32 reg) { u32 ret; unsigned long flags; - if ((reg < MREG_START) || - (reg > MREG_END)) { - pr_err("fsi: register access err (%s)\n", __func__); - return 0; - } - spin_lock_irqsave(&master->lock, flags); ret = __fsi_reg_read((u32)(master->base + reg)); spin_unlock_irqrestore(&master->lock, flags); @@ -218,17 +214,13 @@ static u32 fsi_master_read(struct fsi_master *master, u32 reg) return ret; } -static void fsi_master_mask_set(struct fsi_master *master, +#define fsi_master_mask_set(p, r, m, d) _fsi_master_mask_set(p, MST_##r, m, d) +#define fsi_core_mask_set(p, r, m, d) _fsi_master_mask_set(p, p->core->r, m, d) +static void _fsi_master_mask_set(struct fsi_master *master, u32 reg, u32 mask, u32 data) { unsigned long flags; - if ((reg < MREG_START) || - (reg > MREG_END)) { - pr_err("fsi: register access err (%s)\n", __func__); - return; - } - spin_lock_irqsave(&master->lock, flags); __fsi_reg_mask_set((u32)(master->base + reg), mask, data); spin_unlock_irqrestore(&master->lock, flags); @@ -448,8 +440,8 @@ static void fsi_irq_enable(struct fsi_priv *fsi, int is_play) u32 data = AB_IO(1, fsi_get_port_shift(fsi, is_play)); struct fsi_master *master = fsi_get_master(fsi); - fsi_master_mask_set(master, master->core->imsk, data, data); - fsi_master_mask_set(master, master->core->iemsk, data, data); + fsi_core_mask_set(master, imsk, data, data); + fsi_core_mask_set(master, iemsk, data, data); } static void fsi_irq_disable(struct fsi_priv *fsi, int is_play) @@ -457,13 +449,13 @@ static void fsi_irq_disable(struct fsi_priv *fsi, int is_play) u32 data = AB_IO(1, fsi_get_port_shift(fsi, is_play)); struct fsi_master *master = fsi_get_master(fsi); - fsi_master_mask_set(master, master->core->imsk, data, 0); - fsi_master_mask_set(master, master->core->iemsk, data, 0); + fsi_core_mask_set(master, imsk, data, 0); + fsi_core_mask_set(master, iemsk, data, 0); } static u32 fsi_irq_get_status(struct fsi_master *master) { - return fsi_master_read(master, master->core->int_st); + return fsi_core_read(master, int_st); } static void fsi_irq_clear_status(struct fsi_priv *fsi) @@ -475,7 +467,7 @@ static void fsi_irq_clear_status(struct fsi_priv *fsi) data |= AB_IO(1, fsi_get_port_shift(fsi, 1)); /* clear interrupt factor */ - fsi_master_mask_set(master, master->core->int_st, data, 0); + fsi_core_mask_set(master, int_st, data, 0); } /* @@ -497,8 +489,8 @@ static void fsi_spdif_clk_ctrl(struct fsi_priv *fsi, int enable) val = enable ? mask : 0; fsi_is_port_a(fsi) ? - fsi_master_mask_set(master, master->core->a_mclk, mask, val) : - fsi_master_mask_set(master, master->core->b_mclk, mask, val); + fsi_core_mask_set(master, a_mclk, mask, val) : + fsi_core_mask_set(master, b_mclk, mask, val); } /* -- cgit v1.2.3 From 4bd3a1f415affa4729856dca7e39c5093a9a954f Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Fri, 3 Dec 2010 17:25:57 +0800 Subject: ASoC: Fix inconsistent meaning of default case while checking alc5623->id In alc5623_i2c_probe(), the default case for checking alc5623->id behaves the same as case 0x23. However, In alc5623_probe() the default case for checking alc5623->id becomes to be the same as case 0x21. This makes the meaning of default case inconsistent. Since we have checked codec id in alc5623_i2c_probe() by comparing vid2 with id->driver_data, it is not possible to run into the default case now. In case we may add more supported devices to alc5623_i2c_table in the future, this patch changes the default case return -EINVAL to let people know that they should not run into this case. They should also add a new case accordingly for the new id. Signed-off-by: Axel Lin Acked-by: Arnaud Patard Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/codecs/alc5623.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/sound/soc/codecs/alc5623.c b/sound/soc/codecs/alc5623.c index 9783e7e2eb93..4f377c9e868d 100644 --- a/sound/soc/codecs/alc5623.c +++ b/sound/soc/codecs/alc5623.c @@ -925,7 +925,6 @@ static int alc5623_probe(struct snd_soc_codec *codec) } switch (alc5623->id) { - default: case 0x21: snd_soc_add_controls(codec, rt5621_vol_snd_controls, ARRAY_SIZE(rt5621_vol_snd_controls)); @@ -938,6 +937,8 @@ static int alc5623_probe(struct snd_soc_codec *codec) snd_soc_add_controls(codec, alc5623_vol_snd_controls, ARRAY_SIZE(alc5623_vol_snd_controls)); break; + default: + return -EINVAL; } snd_soc_add_controls(codec, alc5623_snd_controls, @@ -950,7 +951,6 @@ static int alc5623_probe(struct snd_soc_codec *codec) snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon)); switch (alc5623->id) { - default: case 0x21: case 0x22: snd_soc_dapm_new_controls(dapm, alc5623_dapm_amp_widgets, @@ -962,6 +962,8 @@ static int alc5623_probe(struct snd_soc_codec *codec) snd_soc_dapm_add_routes(dapm, intercon_spk, ARRAY_SIZE(intercon_spk)); break; + default: + return -EINVAL; } return ret; @@ -1039,10 +1041,12 @@ static int alc5623_i2c_probe(struct i2c_client *client, case 0x22: alc5623_dai.name = "alc5622-hifi"; break; - default: case 0x23: alc5623_dai.name = "alc5623-hifi"; break; + default: + kfree(alc5623); + return -EINVAL; } i2c_set_clientdata(client, alc5623); -- cgit v1.2.3 From 676ad98a06a629e6273819a54b70f3987044b608 Mon Sep 17 00:00:00 2001 From: Jarkko Nikula Date: Fri, 3 Dec 2010 09:18:22 +0200 Subject: ASoC: Don't oops in soc_probe_aux_dev in case of missing codec Blind copy of codec finding algorithm from soc_bind_dai_link does not work in soc_probe_aux_dev if matching codec name is not found. In that case the code falls through and tries to start the probing procedure with invalid codec pointer. Fix this and add an error print showing the codec name that cannot be found. Signed-off-by: Jarkko Nikula Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/soc-core.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 5720dbcefbc4..2b1fcae4131e 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -1609,7 +1609,7 @@ static int soc_probe_aux_dev(struct snd_soc_card *card, int num) struct snd_soc_pcm_runtime *rtd = &card->rtd_aux[num]; struct snd_soc_codec *codec; const char *temp; - int ret = 0; + int ret = -ENODEV; /* find CODEC from registered CODECs*/ list_for_each_entry(codec, &codec_list, list) { @@ -1620,10 +1620,14 @@ static int soc_probe_aux_dev(struct snd_soc_card *card, int num) ret = -EBUSY; goto out; } - break; + goto found; } } + /* codec not found */ + dev_err(card->dev, "asoc: codec %s not found", aux_dev->codec_name); + goto out; +found: if (!try_module_get(codec->dev->driver->owner)) return -ENODEV; -- cgit v1.2.3 From 1c3cb9ec07fabf0c0970adc46fd2a1f09c1186dd Mon Sep 17 00:00:00 2001 From: Dave Chinner Date: Tue, 21 Dec 2010 12:28:39 +1100 Subject: xfs: convert l_tail_lsn to an atomic variable. log->l_tail_lsn is currently protected by the log grant lock. The lock is only needed for serialising readers against writers, so we don't really need the lock if we make the l_tail_lsn variable an atomic. Converting the l_tail_lsn variable to an atomic64_t means we can start to peel back the grant lock from various operations. Also, provide functions to safely crack an atomic LSN variable into it's component pieces and to recombined the components into an atomic variable. Use them where appropriate. This also removes the need for explicitly holding a spinlock to read the l_tail_lsn on 32 bit platforms. Signed-off-by: Dave Chinner --- fs/xfs/linux-2.6/xfs_trace.h | 2 +- fs/xfs/xfs_log.c | 56 ++++++++++++++++++++------------------------ fs/xfs/xfs_log_priv.h | 37 ++++++++++++++++++++++++----- fs/xfs/xfs_log_recover.c | 14 +++++------ 4 files changed, 63 insertions(+), 46 deletions(-) diff --git a/fs/xfs/linux-2.6/xfs_trace.h b/fs/xfs/linux-2.6/xfs_trace.h index 3ff6b35f9207..b180e1bf8257 100644 --- a/fs/xfs/linux-2.6/xfs_trace.h +++ b/fs/xfs/linux-2.6/xfs_trace.h @@ -794,7 +794,7 @@ DECLARE_EVENT_CLASS(xfs_loggrant_class, &__entry->grant_write_bytes); __entry->curr_cycle = log->l_curr_cycle; __entry->curr_block = log->l_curr_block; - __entry->tail_lsn = log->l_tail_lsn; + __entry->tail_lsn = atomic64_read(&log->l_tail_lsn); ), TP_printk("dev %d:%d type %s t_ocnt %u t_cnt %u t_curr_res %u " "t_unit_res %u t_flags %s reserveq %s " diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c index 70790eb48336..d118bf804480 100644 --- a/fs/xfs/xfs_log.c +++ b/fs/xfs/xfs_log.c @@ -678,15 +678,11 @@ xfs_log_move_tail(xfs_mount_t *mp, if (tail_lsn == 0) tail_lsn = atomic64_read(&log->l_last_sync_lsn); - spin_lock(&log->l_grant_lock); - - /* Also an invalid lsn. 1 implies that we aren't passing in a valid - * tail_lsn. - */ - if (tail_lsn != 1) { - log->l_tail_lsn = tail_lsn; - } + /* tail_lsn == 1 implies that we weren't passed a valid value. */ + if (tail_lsn != 1) + atomic64_set(&log->l_tail_lsn, tail_lsn); + spin_lock(&log->l_grant_lock); if (!list_empty(&log->l_writeq)) { #ifdef DEBUG if (log->l_flags & XLOG_ACTIVE_RECOVERY) @@ -789,21 +785,19 @@ xfs_log_need_covered(xfs_mount_t *mp) * We may be holding the log iclog lock upon entering this routine. */ xfs_lsn_t -xlog_assign_tail_lsn(xfs_mount_t *mp) +xlog_assign_tail_lsn( + struct xfs_mount *mp) { - xfs_lsn_t tail_lsn; - xlog_t *log = mp->m_log; + xfs_lsn_t tail_lsn; + struct log *log = mp->m_log; tail_lsn = xfs_trans_ail_tail(mp->m_ail); - spin_lock(&log->l_grant_lock); if (!tail_lsn) tail_lsn = atomic64_read(&log->l_last_sync_lsn); - log->l_tail_lsn = tail_lsn; - spin_unlock(&log->l_grant_lock); + atomic64_set(&log->l_tail_lsn, tail_lsn); return tail_lsn; -} /* xlog_assign_tail_lsn */ - +} /* * Return the space in the log between the tail and the head. The head @@ -831,8 +825,8 @@ xlog_space_left( int head_bytes; xlog_crack_grant_head(head, &head_cycle, &head_bytes); - tail_bytes = BBTOB(BLOCK_LSN(log->l_tail_lsn)); - tail_cycle = CYCLE_LSN(log->l_tail_lsn); + xlog_crack_atomic_lsn(&log->l_tail_lsn, &tail_cycle, &tail_bytes); + tail_bytes = BBTOB(tail_bytes); if (tail_cycle == head_cycle && head_bytes >= tail_bytes) free_bytes = log->l_logsize - (head_bytes - tail_bytes); else if (tail_cycle + 1 < head_cycle) @@ -1009,8 +1003,8 @@ xlog_alloc_log(xfs_mount_t *mp, log->l_prev_block = -1; /* log->l_tail_lsn = 0x100000000LL; cycle = 1; current block = 0 */ - log->l_tail_lsn = xlog_assign_lsn(1, 0); - atomic64_set(&log->l_last_sync_lsn, xlog_assign_lsn(1, 0)); + xlog_assign_atomic_lsn(&log->l_tail_lsn, 1, 0); + xlog_assign_atomic_lsn(&log->l_last_sync_lsn, 1, 0); log->l_curr_cycle = 1; /* 0 is bad since this is initial value */ xlog_assign_grant_head(&log->l_grant_reserve_head, 1, 0); xlog_assign_grant_head(&log->l_grant_write_head, 1, 0); @@ -1189,7 +1183,6 @@ xlog_grant_push_ail( { xfs_lsn_t threshold_lsn = 0; xfs_lsn_t last_sync_lsn; - xfs_lsn_t tail_lsn; int free_blocks; int free_bytes; int threshold_block; @@ -1198,7 +1191,6 @@ xlog_grant_push_ail( ASSERT(BTOBB(need_bytes) < log->l_logBBsize); - tail_lsn = log->l_tail_lsn; free_bytes = xlog_space_left(log, &log->l_grant_reserve_head); free_blocks = BTOBBT(free_bytes); @@ -1213,8 +1205,9 @@ xlog_grant_push_ail( if (free_blocks >= free_threshold) return; - threshold_block = BLOCK_LSN(tail_lsn) + free_threshold; - threshold_cycle = CYCLE_LSN(tail_lsn); + xlog_crack_atomic_lsn(&log->l_tail_lsn, &threshold_cycle, + &threshold_block); + threshold_block += free_threshold; if (threshold_block >= log->l_logBBsize) { threshold_block -= log->l_logBBsize; threshold_cycle += 1; @@ -2828,11 +2821,11 @@ xlog_state_release_iclog( if (iclog->ic_state == XLOG_STATE_WANT_SYNC) { /* update tail before writing to iclog */ - xlog_assign_tail_lsn(log->l_mp); + xfs_lsn_t tail_lsn = xlog_assign_tail_lsn(log->l_mp); sync++; iclog->ic_state = XLOG_STATE_SYNCING; - iclog->ic_header.h_tail_lsn = cpu_to_be64(log->l_tail_lsn); - xlog_verify_tail_lsn(log, iclog, log->l_tail_lsn); + iclog->ic_header.h_tail_lsn = cpu_to_be64(tail_lsn); + xlog_verify_tail_lsn(log, iclog, tail_lsn); /* cycle incremented when incrementing curr_block */ } spin_unlock(&log->l_icloglock); @@ -3435,7 +3428,7 @@ STATIC void xlog_verify_grant_tail( struct log *log) { - xfs_lsn_t tail_lsn = log->l_tail_lsn; + int tail_cycle, tail_blocks; int cycle, space; /* @@ -3445,9 +3438,10 @@ xlog_verify_grant_tail( * check the byte count. */ xlog_crack_grant_head(&log->l_grant_write_head, &cycle, &space); - if (CYCLE_LSN(tail_lsn) != cycle) { - ASSERT(cycle - 1 == CYCLE_LSN(tail_lsn)); - ASSERT(space <= BBTOB(BLOCK_LSN(tail_lsn))); + xlog_crack_atomic_lsn(&log->l_tail_lsn, &tail_cycle, &tail_blocks); + if (tail_cycle != cycle) { + ASSERT(cycle - 1 == tail_cycle); + ASSERT(space <= BBTOB(tail_blocks)); } } diff --git a/fs/xfs/xfs_log_priv.h b/fs/xfs/xfs_log_priv.h index 958f356df10e..d34af1c21ed2 100644 --- a/fs/xfs/xfs_log_priv.h +++ b/fs/xfs/xfs_log_priv.h @@ -53,7 +53,6 @@ struct xfs_mount; BTOBB(XLOG_MAX_ICLOGS << (xfs_sb_version_haslogv2(&log->l_mp->m_sb) ? \ XLOG_MAX_RECORD_BSHIFT : XLOG_BIG_RECORD_BSHIFT)) - static inline xfs_lsn_t xlog_assign_lsn(uint cycle, uint block) { return ((xfs_lsn_t)cycle << 32) | block; @@ -505,8 +504,6 @@ typedef struct log { * log entries" */ xlog_in_core_t *l_iclog; /* head log queue */ spinlock_t l_icloglock; /* grab to change iclog state */ - xfs_lsn_t l_tail_lsn; /* lsn of 1st LR with unflushed - * buffers */ int l_curr_cycle; /* Cycle number of log writes */ int l_prev_cycle; /* Cycle number before last * block increment */ @@ -521,12 +518,15 @@ typedef struct log { int64_t l_grant_write_head; /* - * l_last_sync_lsn is an atomic so it can be set and read without - * needing to hold specific locks. To avoid operations contending with - * other hot objects, place it on a separate cacheline. + * l_last_sync_lsn and l_tail_lsn are atomics so they can be set and + * read without needing to hold specific locks. To avoid operations + * contending with other hot objects, place each of them on a separate + * cacheline. */ /* lsn of last LR on disk */ atomic64_t l_last_sync_lsn ____cacheline_aligned_in_smp; + /* lsn of 1st LR with unflushed * buffers */ + atomic64_t l_tail_lsn ____cacheline_aligned_in_smp; /* The following field are used for debugging; need to hold icloglock */ #ifdef DEBUG @@ -565,6 +565,31 @@ int xlog_write(struct log *log, struct xfs_log_vec *log_vector, struct xlog_ticket *tic, xfs_lsn_t *start_lsn, xlog_in_core_t **commit_iclog, uint flags); +/* + * When we crack an atomic LSN, we sample it first so that the value will not + * change while we are cracking it into the component values. This means we + * will always get consistent component values to work from. This should always + * be used to smaple and crack LSNs taht are stored and updated in atomic + * variables. + */ +static inline void +xlog_crack_atomic_lsn(atomic64_t *lsn, uint *cycle, uint *block) +{ + xfs_lsn_t val = atomic64_read(lsn); + + *cycle = CYCLE_LSN(val); + *block = BLOCK_LSN(val); +} + +/* + * Calculate and assign a value to an atomic LSN variable from component pieces. + */ +static inline void +xlog_assign_atomic_lsn(atomic64_t *lsn, uint cycle, uint block) +{ + atomic64_set(lsn, xlog_assign_lsn(cycle, block)); +} + /* * When we crack the grrant head, we sample it first so that the value will not * change while we are cracking it into the component values. This means we diff --git a/fs/xfs/xfs_log_recover.c b/fs/xfs/xfs_log_recover.c index 18e1e18d7147..204d8e5fa7fa 100644 --- a/fs/xfs/xfs_log_recover.c +++ b/fs/xfs/xfs_log_recover.c @@ -936,7 +936,7 @@ xlog_find_tail( log->l_curr_cycle = be32_to_cpu(rhead->h_cycle); if (found == 2) log->l_curr_cycle++; - log->l_tail_lsn = be64_to_cpu(rhead->h_tail_lsn); + atomic64_set(&log->l_tail_lsn, be64_to_cpu(rhead->h_tail_lsn)); atomic64_set(&log->l_last_sync_lsn, be64_to_cpu(rhead->h_lsn)); xlog_assign_grant_head(&log->l_grant_reserve_head, log->l_curr_cycle, BBTOB(log->l_curr_block)); @@ -971,7 +971,7 @@ xlog_find_tail( } after_umount_blk = (i + hblks + (int) BTOBB(be32_to_cpu(rhead->h_len))) % log->l_logBBsize; - tail_lsn = log->l_tail_lsn; + tail_lsn = atomic64_read(&log->l_tail_lsn); if (*head_blk == after_umount_blk && be32_to_cpu(rhead->h_num_logops) == 1) { umount_data_blk = (i + hblks) % log->l_logBBsize; @@ -986,12 +986,10 @@ xlog_find_tail( * log records will point recovery to after the * current unmount record. */ - log->l_tail_lsn = - xlog_assign_lsn(log->l_curr_cycle, - after_umount_blk); - atomic64_set(&log->l_last_sync_lsn, - xlog_assign_lsn(log->l_curr_cycle, - after_umount_blk)); + xlog_assign_atomic_lsn(&log->l_tail_lsn, + log->l_curr_cycle, after_umount_blk); + xlog_assign_atomic_lsn(&log->l_last_sync_lsn, + log->l_curr_cycle, after_umount_blk); *tail_blk = after_umount_blk; /* -- cgit v1.2.3 From c8a09ff8ca2235bccdaea8a52fbd5349646a8ba4 Mon Sep 17 00:00:00 2001 From: Dave Chinner Date: Sat, 4 Dec 2010 00:02:40 +1100 Subject: xfs: convert log grant heads to atomic variables Convert the log grant heads to atomic64_t types in preparation for converting the accounting algorithms to atomic operations. his patch just converts the variables; the algorithmic changes are in a separate patch for clarity. Signed-off-by: Dave Chinner Reviewed-by: Christoph Hellwig --- fs/xfs/xfs_log.c | 8 ++++---- fs/xfs/xfs_log_priv.h | 12 ++++++------ 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c index d118bf804480..a1d7d12fc51f 100644 --- a/fs/xfs/xfs_log.c +++ b/fs/xfs/xfs_log.c @@ -47,7 +47,7 @@ STATIC xlog_t * xlog_alloc_log(xfs_mount_t *mp, xfs_buftarg_t *log_target, xfs_daddr_t blk_offset, int num_bblks); -STATIC int xlog_space_left(struct log *log, int64_t *head); +STATIC int xlog_space_left(struct log *log, atomic64_t *head); STATIC int xlog_sync(xlog_t *log, xlog_in_core_t *iclog); STATIC void xlog_dealloc_log(xlog_t *log); @@ -100,7 +100,7 @@ STATIC int xlog_iclogs_empty(xlog_t *log); static void xlog_grant_sub_space( struct log *log, - int64_t *head, + atomic64_t *head, int bytes) { int cycle, space; @@ -119,7 +119,7 @@ xlog_grant_sub_space( static void xlog_grant_add_space( struct log *log, - int64_t *head, + atomic64_t *head, int bytes) { int tmp; @@ -816,7 +816,7 @@ xlog_assign_tail_lsn( STATIC int xlog_space_left( struct log *log, - int64_t *head) + atomic64_t *head) { int free_bytes; int tail_bytes; diff --git a/fs/xfs/xfs_log_priv.h b/fs/xfs/xfs_log_priv.h index d34af1c21ed2..7619d6a02388 100644 --- a/fs/xfs/xfs_log_priv.h +++ b/fs/xfs/xfs_log_priv.h @@ -514,8 +514,8 @@ typedef struct log { spinlock_t l_grant_lock ____cacheline_aligned_in_smp; struct list_head l_reserveq; struct list_head l_writeq; - int64_t l_grant_reserve_head; - int64_t l_grant_write_head; + atomic64_t l_grant_reserve_head; + atomic64_t l_grant_write_head; /* * l_last_sync_lsn and l_tail_lsn are atomics so they can be set and @@ -596,18 +596,18 @@ xlog_assign_atomic_lsn(atomic64_t *lsn, uint cycle, uint block) * will always get consistent component values to work from. */ static inline void -xlog_crack_grant_head(int64_t *head, int *cycle, int *space) +xlog_crack_grant_head(atomic64_t *head, int *cycle, int *space) { - int64_t val = *head; + int64_t val = atomic64_read(head); *cycle = val >> 32; *space = val & 0xffffffff; } static inline void -xlog_assign_grant_head(int64_t *head, int cycle, int space) +xlog_assign_grant_head(atomic64_t *head, int cycle, int space) { - *head = ((int64_t)cycle << 32) | space; + atomic64_set(head, ((int64_t)cycle << 32) | space); } /* -- cgit v1.2.3 From 1e1675e9c1342a841e87e5427e77da78e980da06 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 3 Dec 2010 14:58:37 +0100 Subject: ALSA: hda - Enable beep for IDT92HD87 / 88 codecs These codecs have the digital beep widget in NID 0x21. Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_sigmatel.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index efa4225f5fd6..a1df0facdda4 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -5471,7 +5471,6 @@ again: spec->num_pins = ARRAY_SIZE(stac92hd88xxx_pin_nids); spec->pin_nids = stac92hd88xxx_pin_nids; spec->mono_nid = 0; - spec->digbeep_nid = 0; spec->num_pwrs = 0; break; case 0x111d7604: -- cgit v1.2.3 From 1db7ccdb2ef4dbd8df0e0f742c9da9b054d899ba Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 3 Dec 2010 15:19:14 +0100 Subject: ALSA: hda - Fix beep-tone on IDT 92HD87/88 codecs It sounds like a non-linear beep tone on my test machines... Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_sigmatel.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index a1df0facdda4..8e2bb0aad0ae 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -5423,7 +5423,7 @@ static int patch_stac92hd83xxx(struct hda_codec *codec) snd_hda_codec_write_cache(codec, codec->afg, 0, 0x7ED, 0); codec->no_trigger_sense = 1; codec->spec = spec; - spec->linear_tone_beep = 1; + spec->linear_tone_beep = 0; codec->slave_dig_outs = stac92hd83xxx_slave_dig_outs; spec->digbeep_nid = 0x21; spec->dmic_nids = stac92hd83xxx_dmic_nids; -- cgit v1.2.3 From 3345cc4f6d779753810c7f13aab6b29417869548 Mon Sep 17 00:00:00 2001 From: Guillaume LECERF Date: Fri, 29 Oct 2010 16:17:49 +0200 Subject: mtd: bcm963xx-flash: try JEDEC probe if CFI fails Signed-off-by: Guillaume LECERF Acked-by: Florian Fainelli Signed-off-by: Artem Bityutskiy Signed-off-by: David Woodhouse --- drivers/mtd/maps/bcm963xx-flash.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/mtd/maps/bcm963xx-flash.c b/drivers/mtd/maps/bcm963xx-flash.c index d175c120ee84..1f3049590d9e 100644 --- a/drivers/mtd/maps/bcm963xx-flash.c +++ b/drivers/mtd/maps/bcm963xx-flash.c @@ -196,10 +196,15 @@ static int bcm963xx_probe(struct platform_device *pdev) bcm963xx_mtd_info = do_map_probe("cfi_probe", &bcm963xx_map); if (!bcm963xx_mtd_info) { dev_err(&pdev->dev, "failed to probe using CFI\n"); + bcm963xx_mtd_info = do_map_probe("jedec_probe", &bcm963xx_map); + if (bcm963xx_mtd_info) + goto probe_ok; + dev_err(&pdev->dev, "failed to probe using JEDEC\n"); err = -EIO; goto err_probe; } +probe_ok: bcm963xx_mtd_info->owner = THIS_MODULE; /* This is mutually exclusive */ -- cgit v1.2.3 From b7b6e08f9265db56129931983fc6c06d62c9f4f9 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Sat, 30 Oct 2010 07:35:02 +0100 Subject: mtd: Fix MTD_OF_PARTS for all arch and minor tidy of MTD_PARTITIONS MTD_OF_PARTS should be possible on all architectures, not just powerpc and microblaze, and it probably should not be a user selectable option. Neither does it need to be in a separate module. Also, rework MTD Kconfig to group options dependant on MTD_PARTITIONS into a if/endif block. Do the same for MTD_REDBOOT_PARTS. Signed-off-by: Grant Likely Signed-off-by: Artem Bityutskiy Signed-off-by: David Woodhouse --- drivers/mtd/Kconfig | 19 +++++++++++-------- drivers/mtd/Makefile | 2 +- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/drivers/mtd/Kconfig b/drivers/mtd/Kconfig index 1e2cbf5d9aa1..77414702cb00 100644 --- a/drivers/mtd/Kconfig +++ b/drivers/mtd/Kconfig @@ -53,9 +53,10 @@ config MTD_PARTITIONS devices. Partitioning on NFTL 'devices' is a different - that's the 'normal' form of partitioning used on a block device. +if MTD_PARTITIONS + config MTD_REDBOOT_PARTS tristate "RedBoot partition table parsing" - depends on MTD_PARTITIONS ---help--- RedBoot is a ROM monitor and bootloader which deals with multiple 'images' in flash devices by putting a table one of the erase @@ -72,9 +73,10 @@ config MTD_REDBOOT_PARTS SA1100 map driver (CONFIG_MTD_SA1100) has an option for this, for example. +if MTD_REDBOOT_PARTS + config MTD_REDBOOT_DIRECTORY_BLOCK int "Location of RedBoot partition table" - depends on MTD_REDBOOT_PARTS default "-1" ---help--- This option is the Linux counterpart to the @@ -91,18 +93,18 @@ config MTD_REDBOOT_DIRECTORY_BLOCK config MTD_REDBOOT_PARTS_UNALLOCATED bool "Include unallocated flash regions" - depends on MTD_REDBOOT_PARTS help If you need to register each unallocated flash region as a MTD 'partition', enable this option. config MTD_REDBOOT_PARTS_READONLY bool "Force read-only for RedBoot system images" - depends on MTD_REDBOOT_PARTS help If you need to force read-only for 'RedBoot', 'RedBoot Config' and 'FIS directory' images, enable this option. +endif # MTD_REDBOOT_PARTS + config MTD_CMDLINE_PARTS bool "Command line partition table parsing" depends on MTD_PARTITIONS = "y" && MTD = "y" @@ -142,7 +144,7 @@ config MTD_CMDLINE_PARTS config MTD_AFS_PARTS tristate "ARM Firmware Suite partition parsing" - depends on ARM && MTD_PARTITIONS + depends on ARM ---help--- The ARM Firmware Suite allows the user to divide flash devices into multiple 'images'. Each such image has a header containing its name @@ -158,8 +160,8 @@ config MTD_AFS_PARTS example. config MTD_OF_PARTS - tristate "Flash partition map based on OF description" - depends on (MICROBLAZE || PPC_OF) && MTD_PARTITIONS + def_bool y + depends on OF help This provides a partition parsing function which derives the partition map from the children of the flash node, @@ -167,10 +169,11 @@ config MTD_OF_PARTS config MTD_AR7_PARTS tristate "TI AR7 partitioning support" - depends on MTD_PARTITIONS ---help--- TI AR7 partitioning support +endif # MTD_PARTITIONS + comment "User Modules And Translation Layers" config MTD_CHAR diff --git a/drivers/mtd/Makefile b/drivers/mtd/Makefile index 760abc533395..d4e7f25b1ebb 100644 --- a/drivers/mtd/Makefile +++ b/drivers/mtd/Makefile @@ -6,13 +6,13 @@ obj-$(CONFIG_MTD) += mtd.o mtd-y := mtdcore.o mtdsuper.o mtd-$(CONFIG_MTD_PARTITIONS) += mtdpart.o +mtd-$(CONFIG_MTD_OF_PARTS) += ofpart.o obj-$(CONFIG_MTD_CONCAT) += mtdconcat.o obj-$(CONFIG_MTD_REDBOOT_PARTS) += redboot.o obj-$(CONFIG_MTD_CMDLINE_PARTS) += cmdlinepart.o obj-$(CONFIG_MTD_AFS_PARTS) += afs.o obj-$(CONFIG_MTD_AR7_PARTS) += ar7part.o -obj-$(CONFIG_MTD_OF_PARTS) += ofpart.o # 'Users' - code which presents functionality to userspace. obj-$(CONFIG_MTD_CHAR) += mtdchar.o -- cgit v1.2.3 From f0dff9bd00d2cffea160fb3fa015b77607458634 Mon Sep 17 00:00:00 2001 From: Kevin Cernekee Date: Sat, 30 Oct 2010 21:11:02 -0700 Subject: mtd: m25p80: Reinstate error print on unrecognized flash Commit b34bc037b26e621e5fc13466767e4da110a7b3d3 removed the "unrecognized JEDEC id" error message, causing the probe function to silently abort if the flash ID is unrecognized. It is desirable to produce diagnostic output in this situation so that the user has some idea what went wrong. Signed-off-by: Kevin Cernekee Signed-off-by: Artem Bityutskiy Signed-off-by: David Woodhouse --- drivers/mtd/devices/m25p80.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c index bf5a002209bd..80404e1a4d5e 100644 --- a/drivers/mtd/devices/m25p80.c +++ b/drivers/mtd/devices/m25p80.c @@ -764,6 +764,7 @@ static const struct spi_device_id *__devinit jedec_probe(struct spi_device *spi) return &m25p_ids[tmp]; } } + dev_err(&spi->dev, "unrecognized JEDEC id %06x\n", jedec); return ERR_PTR(-ENODEV); } -- cgit v1.2.3 From 4b7f7422b0331e802f8b7c593e058ccee981cff5 Mon Sep 17 00:00:00 2001 From: Kevin Cernekee Date: Sat, 30 Oct 2010 21:11:03 -0700 Subject: mtd: m25p80: Add support for Macronix MX25L25635E This is a 256Mbit (32MiB) part so minor changes were made to support 4-byte addressing. Signed-off-by: Kevin Cernekee Signed-off-by: Artem Bityutskiy Signed-off-by: David Woodhouse --- drivers/mtd/devices/m25p80.c | 31 ++++++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c index 80404e1a4d5e..96ae54e9650e 100644 --- a/drivers/mtd/devices/m25p80.c +++ b/drivers/mtd/devices/m25p80.c @@ -51,6 +51,10 @@ #define OPCODE_WRDI 0x04 /* Write disable */ #define OPCODE_AAI_WP 0xad /* Auto address increment word program */ +/* Used for Macronix flashes only. */ +#define OPCODE_EN4B 0xb7 /* Enter 4-byte mode */ +#define OPCODE_EX4B 0xe9 /* Exit 4-byte mode */ + /* Status Register bits. */ #define SR_WIP 1 /* Write in progress */ #define SR_WEL 2 /* Write enable latch */ @@ -62,7 +66,7 @@ /* Define max times to check status register before we give up. */ #define MAX_READY_WAIT_JIFFIES (40 * HZ) /* M25P16 specs 40s max chip erase */ -#define MAX_CMD_SIZE 4 +#define MAX_CMD_SIZE 5 #ifdef CONFIG_M25PXX_USE_FAST_READ #define OPCODE_READ OPCODE_FAST_READ @@ -151,6 +155,16 @@ static inline int write_disable(struct m25p *flash) return spi_write_then_read(flash->spi, &code, 1, NULL, 0); } +/* + * Enable/disable 4-byte addressing mode. + */ +static inline int set_4byte(struct m25p *flash, int enable) +{ + u8 code = enable ? OPCODE_EN4B : OPCODE_EX4B; + + return spi_write_then_read(flash->spi, &code, 1, NULL, 0); +} + /* * Service routine to read status register until ready, or timeout occurs. * Returns non-zero if error. @@ -207,6 +221,7 @@ static void m25p_addr2cmd(struct m25p *flash, unsigned int addr, u8 *cmd) cmd[1] = addr >> (flash->addr_width * 8 - 8); cmd[2] = addr >> (flash->addr_width * 8 - 16); cmd[3] = addr >> (flash->addr_width * 8 - 24); + cmd[4] = addr >> (flash->addr_width * 8 - 32); } static int m25p_cmdsz(struct m25p *flash) @@ -607,7 +622,6 @@ struct flash_info { .sector_size = (_sector_size), \ .n_sectors = (_n_sectors), \ .page_size = 256, \ - .addr_width = 3, \ .flags = (_flags), \ }) @@ -653,6 +667,7 @@ static const struct spi_device_id m25p_ids[] = { { "mx25l6405d", INFO(0xc22017, 0, 64 * 1024, 128, 0) }, { "mx25l12805d", INFO(0xc22018, 0, 64 * 1024, 256, 0) }, { "mx25l12855e", INFO(0xc22618, 0, 64 * 1024, 256, 0) }, + { "mx25l25635e", INFO(0xc22019, 0, 64 * 1024, 512, 0) }, /* Spansion -- single (large) sector size only, at least * for the chips listed here (without boot sectors). @@ -884,7 +899,17 @@ static int __devinit m25p_probe(struct spi_device *spi) flash->mtd.dev.parent = &spi->dev; flash->page_size = info->page_size; - flash->addr_width = info->addr_width; + + if (info->addr_width) + flash->addr_width = info->addr_width; + else { + /* enable 4-byte addressing if the device exceeds 16MiB */ + if (flash->mtd.size > 0x1000000) { + flash->addr_width = 4; + set_4byte(flash, 1); + } else + flash->addr_width = 3; + } dev_info(&spi->dev, "%s (%lld Kbytes)\n", id->name, (long long)flash->mtd.size >> 10); -- cgit v1.2.3 From ac622f583dccb025250becd2d4e60badaf571713 Mon Sep 17 00:00:00 2001 From: Kevin Cernekee Date: Sat, 30 Oct 2010 21:11:04 -0700 Subject: mtd: m25p80: Add support for Macronix MX25L25655E Untested, but expected to be compatible with MX25L25635E which I did test. Signed-off-by: Kevin Cernekee Signed-off-by: Artem Bityutskiy Signed-off-by: David Woodhouse --- drivers/mtd/devices/m25p80.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/mtd/devices/m25p80.c b/drivers/mtd/devices/m25p80.c index 96ae54e9650e..eabe5fb071c6 100644 --- a/drivers/mtd/devices/m25p80.c +++ b/drivers/mtd/devices/m25p80.c @@ -668,6 +668,7 @@ static const struct spi_device_id m25p_ids[] = { { "mx25l12805d", INFO(0xc22018, 0, 64 * 1024, 256, 0) }, { "mx25l12855e", INFO(0xc22618, 0, 64 * 1024, 256, 0) }, { "mx25l25635e", INFO(0xc22019, 0, 64 * 1024, 512, 0) }, + { "mx25l25655e", INFO(0xc22619, 0, 64 * 1024, 512, 0) }, /* Spansion -- single (large) sector size only, at least * for the chips listed here (without boot sectors). -- cgit v1.2.3 From daf05ec00c6e60a2c705820e7f93cbd31c804fe3 Mon Sep 17 00:00:00 2001 From: srimugunthan Date: Sat, 13 Nov 2010 12:46:05 +0200 Subject: mtd: nandsim: spell fixes in comments Signed-off-by: srimugunthan Signed-off-by: Artem Bityutskiy Signed-off-by: David Woodhouse --- drivers/mtd/nand/nandsim.c | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/drivers/mtd/nand/nandsim.c b/drivers/mtd/nand/nandsim.c index a6a73aab1253..c45e06fba154 100644 --- a/drivers/mtd/nand/nandsim.c +++ b/drivers/mtd/nand/nandsim.c @@ -210,12 +210,12 @@ MODULE_PARM_DESC(bbt, "0 OOB, 1 BBT with marker in OOB, 2 BBT with marker in d #define STATE_CMD_READ0 0x00000001 /* read data from the beginning of page */ #define STATE_CMD_READ1 0x00000002 /* read data from the second half of page */ #define STATE_CMD_READSTART 0x00000003 /* read data second command (large page devices) */ -#define STATE_CMD_PAGEPROG 0x00000004 /* start page programm */ +#define STATE_CMD_PAGEPROG 0x00000004 /* start page program */ #define STATE_CMD_READOOB 0x00000005 /* read OOB area */ #define STATE_CMD_ERASE1 0x00000006 /* sector erase first command */ #define STATE_CMD_STATUS 0x00000007 /* read status */ #define STATE_CMD_STATUS_M 0x00000008 /* read multi-plane status (isn't implemented) */ -#define STATE_CMD_SEQIN 0x00000009 /* sequential data imput */ +#define STATE_CMD_SEQIN 0x00000009 /* sequential data input */ #define STATE_CMD_READID 0x0000000A /* read ID */ #define STATE_CMD_ERASE2 0x0000000B /* sector erase second command */ #define STATE_CMD_RESET 0x0000000C /* reset */ @@ -230,7 +230,7 @@ MODULE_PARM_DESC(bbt, "0 OOB, 1 BBT with marker in OOB, 2 BBT with marker in d #define STATE_ADDR_ZERO 0x00000040 /* one byte zero address was accepted */ #define STATE_ADDR_MASK 0x00000070 /* address states mask */ -/* Durind data input/output the simulator is in these states */ +/* During data input/output the simulator is in these states */ #define STATE_DATAIN 0x00000100 /* waiting for data input */ #define STATE_DATAIN_MASK 0x00000100 /* data input states mask */ @@ -248,7 +248,7 @@ MODULE_PARM_DESC(bbt, "0 OOB, 1 BBT with marker in OOB, 2 BBT with marker in d /* Simulator's actions bit masks */ #define ACTION_CPY 0x00100000 /* copy page/OOB to the internal buffer */ -#define ACTION_PRGPAGE 0x00200000 /* programm the internal buffer to flash */ +#define ACTION_PRGPAGE 0x00200000 /* program the internal buffer to flash */ #define ACTION_SECERASE 0x00300000 /* erase sector */ #define ACTION_ZEROOFF 0x00400000 /* don't add any offset to address */ #define ACTION_HALFOFF 0x00500000 /* add to address half of page */ @@ -263,18 +263,18 @@ MODULE_PARM_DESC(bbt, "0 OOB, 1 BBT with marker in OOB, 2 BBT with marker in d #define OPT_PAGE512 0x00000002 /* 512-byte page chips */ #define OPT_PAGE2048 0x00000008 /* 2048-byte page chips */ #define OPT_SMARTMEDIA 0x00000010 /* SmartMedia technology chips */ -#define OPT_AUTOINCR 0x00000020 /* page number auto inctimentation is possible */ +#define OPT_AUTOINCR 0x00000020 /* page number auto incrementation is possible */ #define OPT_PAGE512_8BIT 0x00000040 /* 512-byte page chips with 8-bit bus width */ #define OPT_PAGE4096 0x00000080 /* 4096-byte page chips */ #define OPT_LARGEPAGE (OPT_PAGE2048 | OPT_PAGE4096) /* 2048 & 4096-byte page chips */ #define OPT_SMALLPAGE (OPT_PAGE256 | OPT_PAGE512) /* 256 and 512-byte page chips */ -/* Remove action bits ftom state */ +/* Remove action bits from state */ #define NS_STATE(x) ((x) & ~ACTION_MASK) /* * Maximum previous states which need to be saved. Currently saving is - * only needed for page programm operation with preceeded read command + * only needed for page program operation with preceded read command * (which is only valid for 512-byte pages). */ #define NS_MAX_PREVSTATES 1 @@ -380,16 +380,16 @@ static struct nandsim_operations { /* Read OOB */ {OPT_SMALLPAGE, {STATE_CMD_READOOB | ACTION_OOBOFF, STATE_ADDR_PAGE | ACTION_CPY, STATE_DATAOUT, STATE_READY}}, - /* Programm page starting from the beginning */ + /* Program page starting from the beginning */ {OPT_ANY, {STATE_CMD_SEQIN, STATE_ADDR_PAGE, STATE_DATAIN, STATE_CMD_PAGEPROG | ACTION_PRGPAGE, STATE_READY}}, - /* Programm page starting from the beginning */ + /* Program page starting from the beginning */ {OPT_SMALLPAGE, {STATE_CMD_READ0, STATE_CMD_SEQIN | ACTION_ZEROOFF, STATE_ADDR_PAGE, STATE_DATAIN, STATE_CMD_PAGEPROG | ACTION_PRGPAGE, STATE_READY}}, - /* Programm page starting from the second half */ + /* Program page starting from the second half */ {OPT_PAGE512, {STATE_CMD_READ1, STATE_CMD_SEQIN | ACTION_HALFOFF, STATE_ADDR_PAGE, STATE_DATAIN, STATE_CMD_PAGEPROG | ACTION_PRGPAGE, STATE_READY}}, - /* Programm OOB */ + /* Program OOB */ {OPT_SMALLPAGE, {STATE_CMD_READOOB, STATE_CMD_SEQIN | ACTION_OOBOFF, STATE_ADDR_PAGE, STATE_DATAIN, STATE_CMD_PAGEPROG | ACTION_PRGPAGE, STATE_READY}}, /* Erase sector */ @@ -1171,9 +1171,9 @@ static inline void switch_to_ready_state(struct nandsim *ns, u_char status) * of supported operations. * * Operation can be unknown because of the following. - * 1. New command was accepted and this is the firs call to find the + * 1. New command was accepted and this is the first call to find the * correspondent states chain. In this case ns->npstates = 0; - * 2. There is several operations which begin with the same command(s) + * 2. There are several operations which begin with the same command(s) * (for example program from the second half and read from the * second half operations both begin with the READ1 command). In this * case the ns->pstates[] array contains previous states. @@ -1186,7 +1186,7 @@ static inline void switch_to_ready_state(struct nandsim *ns, u_char status) * ns->ops, ns->state, ns->nxstate are initialized, ns->npstate is * zeroed). * - * If there are several maches, the current state is pushed to the + * If there are several matches, the current state is pushed to the * ns->pstates. * * The operation can be unknown only while commands are input to the chip. @@ -1195,10 +1195,10 @@ static inline void switch_to_ready_state(struct nandsim *ns, u_char status) * operation is searched using the following pattern: * ns->pstates[0], ... ns->pstates[ns->npstates],
* - * It is supposed that this pattern must either match one operation on + * It is supposed that this pattern must either match one operation or * none. There can't be ambiguity in that case. * - * If no matches found, the functions does the following: + * If no matches found, the function does the following: * 1. if there are saved states present, try to ignore them and search * again only using the last command. If nothing was found, switch * to the STATE_READY state. @@ -1668,7 +1668,7 @@ static int do_state_action(struct nandsim *ns, uint32_t action) case ACTION_PRGPAGE: /* - * Programm page - move internal buffer data to the page. + * Program page - move internal buffer data to the page. */ if (ns->lines.wp) { @@ -1933,7 +1933,7 @@ static u_char ns_nand_read_byte(struct mtd_info *mtd) NS_DBG("read_byte: all bytes were read\n"); /* - * The OPT_AUTOINCR allows to read next conseqitive pages without + * The OPT_AUTOINCR allows to read next consecutive pages without * new read operation cycle. */ if ((ns->options & OPT_AUTOINCR) && NS_STATE(ns->state) == STATE_DATAOUT) { -- cgit v1.2.3 From 08b3af3092bb2c284796e4e823c5309c2d0a9bca Mon Sep 17 00:00:00 2001 From: Kyungmin Park Date: Tue, 2 Nov 2010 10:28:46 +0900 Subject: mtd: OneNAND: Fix page offset handling at 2KiB pagesize When use the 2KiB pagesize, it should be set the correct page offset. Signed-off-by: Kyungmin Park Signed-off-by: Artem Bityutskiy Signed-off-by: David Woodhouse --- drivers/mtd/onenand/samsung.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/mtd/onenand/samsung.c b/drivers/mtd/onenand/samsung.c index 0de7a05e6de0..a4c74a9ba430 100644 --- a/drivers/mtd/onenand/samsung.c +++ b/drivers/mtd/onenand/samsung.c @@ -651,7 +651,7 @@ static int s5pc110_read_bufferram(struct mtd_info *mtd, int area, void __iomem *p; void *buf = (void *) buffer; dma_addr_t dma_src, dma_dst; - int err, page_dma = 0; + int err, ofs, page_dma = 0; struct device *dev = &onenand->pdev->dev; p = this->base + area; @@ -677,10 +677,13 @@ static int s5pc110_read_bufferram(struct mtd_info *mtd, int area, if (!page) goto normal; + /* Page offset */ + ofs = ((size_t) buf & ~PAGE_MASK); page_dma = 1; + /* DMA routine */ dma_src = onenand->phys_base + (p - this->base); - dma_dst = dma_map_page(dev, page, 0, count, DMA_FROM_DEVICE); + dma_dst = dma_map_page(dev, page, ofs, count, DMA_FROM_DEVICE); } else { /* DMA routine */ dma_src = onenand->phys_base + (p - this->base); -- cgit v1.2.3 From 309b5e4e4154721f8079bc250d2233fd4b3aa039 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Thu, 4 Nov 2010 20:07:40 -0700 Subject: mtd: use vzalloc Signed-off-by: Joe Perches Signed-off-by: Artem Bityutskiy Signed-off-by: David Woodhouse --- drivers/mtd/nand/nandsim.c | 3 +-- drivers/mtd/ubi/vtbl.c | 6 ++---- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/drivers/mtd/nand/nandsim.c b/drivers/mtd/nand/nandsim.c index c45e06fba154..a5aa99f014ba 100644 --- a/drivers/mtd/nand/nandsim.c +++ b/drivers/mtd/nand/nandsim.c @@ -470,7 +470,7 @@ static int alloc_device(struct nandsim *ns) err = -EINVAL; goto err_close; } - ns->pages_written = vmalloc(ns->geom.pgnum); + ns->pages_written = vzalloc(ns->geom.pgnum); if (!ns->pages_written) { NS_ERR("alloc_device: unable to allocate pages written array\n"); err = -ENOMEM; @@ -483,7 +483,6 @@ static int alloc_device(struct nandsim *ns) goto err_free; } ns->cfile = cfile; - memset(ns->pages_written, 0, ns->geom.pgnum); return 0; } diff --git a/drivers/mtd/ubi/vtbl.c b/drivers/mtd/ubi/vtbl.c index fcdb7f65fe0b..0b8141fc5c26 100644 --- a/drivers/mtd/ubi/vtbl.c +++ b/drivers/mtd/ubi/vtbl.c @@ -425,12 +425,11 @@ static struct ubi_vtbl_record *process_lvol(struct ubi_device *ubi, /* Read both LEB 0 and LEB 1 into memory */ ubi_rb_for_each_entry(rb, seb, &sv->root, u.rb) { - leb[seb->lnum] = vmalloc(ubi->vtbl_size); + leb[seb->lnum] = vzalloc(ubi->vtbl_size); if (!leb[seb->lnum]) { err = -ENOMEM; goto out_free; } - memset(leb[seb->lnum], 0, ubi->vtbl_size); err = ubi_io_read_data(ubi, leb[seb->lnum], seb->pnum, 0, ubi->vtbl_size); @@ -516,10 +515,9 @@ static struct ubi_vtbl_record *create_empty_lvol(struct ubi_device *ubi, int i; struct ubi_vtbl_record *vtbl; - vtbl = vmalloc(ubi->vtbl_size); + vtbl = vzalloc(ubi->vtbl_size); if (!vtbl) return ERR_PTR(-ENOMEM); - memset(vtbl, 0, ubi->vtbl_size); for (i = 0; i < ubi->vtbl_slots; i++) memcpy(&vtbl[i], &empty_vtbl_record, UBI_VTBL_RECORD_SIZE); -- cgit v1.2.3 From 7ddbead6e6d3c730570a215ab9a6b1d126c54d34 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Thu, 4 Nov 2010 20:08:02 -0700 Subject: jffs2: use vzalloc Signed-off-by: Joe Perches Signed-off-by: Artem Bityutskiy Signed-off-by: David Woodhouse --- fs/jffs2/build.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/fs/jffs2/build.c b/fs/jffs2/build.c index 85c6be2db02f..3005ec4520ad 100644 --- a/fs/jffs2/build.c +++ b/fs/jffs2/build.c @@ -336,14 +336,13 @@ int jffs2_do_mount_fs(struct jffs2_sb_info *c) size = sizeof(struct jffs2_eraseblock) * c->nr_blocks; #ifndef __ECOS if (jffs2_blocks_use_vmalloc(c)) - c->blocks = vmalloc(size); + c->blocks = vzalloc(size); else #endif - c->blocks = kmalloc(size, GFP_KERNEL); + c->blocks = kzalloc(size, GFP_KERNEL); if (!c->blocks) return -ENOMEM; - memset(c->blocks, 0, size); for (i=0; inr_blocks; i++) { INIT_LIST_HEAD(&c->blocks[i].list); c->blocks[i].offset = i * c->sector_size; -- cgit v1.2.3 From 3e3198f1adda8e0fbd499bde806781237d6c841f Mon Sep 17 00:00:00 2001 From: Roman Tereshonkov Date: Wed, 3 Nov 2010 12:55:19 +0200 Subject: mtd: onenand: add option and variable for cache program feature A new option is added for cache program feature. A new variable ongoing is introduced for onenand_chip to handle the multi-command cache program operation. Signed-off-by: Roman Tereshonkov Acked-by: Kyungmin Park Signed-off-by: Artem Bityutskiy Signed-off-by: David Woodhouse --- include/linux/mtd/onenand.h | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/include/linux/mtd/onenand.h b/include/linux/mtd/onenand.h index 0c8815bfae1c..6da3fe314828 100644 --- a/include/linux/mtd/onenand.h +++ b/include/linux/mtd/onenand.h @@ -137,6 +137,14 @@ struct onenand_chip { void *bbm; void *priv; + + /* + * Shows that the current operation is composed + * of sequence of commands. For example, cache program. + * Such command status OnGo bit is checked at the end of + * sequence. + */ + unsigned int ongoing; }; /* @@ -171,6 +179,9 @@ struct onenand_chip { #define ONENAND_IS_2PLANE(this) (0) #endif +#define ONENAND_IS_CACHE_PROGRAM(this) \ + (this->options & ONENAND_HAS_CACHE_PROGRAM) + /* Check byte access in OneNAND */ #define ONENAND_CHECK_BYTE_ACCESS(addr) (addr & 0x1) @@ -181,6 +192,7 @@ struct onenand_chip { #define ONENAND_HAS_UNLOCK_ALL (0x0002) #define ONENAND_HAS_2PLANE (0x0004) #define ONENAND_HAS_4KB_PAGE (0x0008) +#define ONENAND_HAS_CACHE_PROGRAM (0x0010) #define ONENAND_SKIP_UNLOCK_CHECK (0x0100) #define ONENAND_PAGEBUF_ALLOC (0x1000) #define ONENAND_OOBBUF_ALLOC (0x2000) -- cgit v1.2.3 From d19d7b46d2b4936be14cfeef779ffeb76cf7b757 Mon Sep 17 00:00:00 2001 From: Roman Tereshonkov Date: Wed, 3 Nov 2010 12:55:20 +0200 Subject: mtd: onenand: fix omap2 code to handle cache program feature Some fixes are introduced into omap2 code to handle errors when cache program feature is used. Signed-off-by: Roman Tereshonkov Signed-off-by: Artem Bityutskiy Signed-off-by: David Woodhouse --- drivers/mtd/onenand/omap2.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/drivers/mtd/onenand/omap2.c b/drivers/mtd/onenand/omap2.c index 9f322f1a7f22..da25a90af4a4 100644 --- a/drivers/mtd/onenand/omap2.c +++ b/drivers/mtd/onenand/omap2.c @@ -108,8 +108,9 @@ static void wait_warn(char *msg, int state, unsigned int ctrl, static int omap2_onenand_wait(struct mtd_info *mtd, int state) { struct omap2_onenand *c = container_of(mtd, struct omap2_onenand, mtd); + struct onenand_chip *this = mtd->priv; unsigned int intr = 0; - unsigned int ctrl; + unsigned int ctrl, ctrl_mask; unsigned long timeout; u32 syscfg; @@ -180,7 +181,8 @@ retry: if (result == 0) { /* Timeout after 20ms */ ctrl = read_reg(c, ONENAND_REG_CTRL_STATUS); - if (ctrl & ONENAND_CTRL_ONGO) { + if (ctrl & ONENAND_CTRL_ONGO && + !this->ongoing) { /* * The operation seems to be still going * so give it some more time. @@ -269,7 +271,11 @@ retry: return -EIO; } - if (ctrl & 0xFE9F) + ctrl_mask = 0xFE9F; + if (this->ongoing) + ctrl_mask &= ~0x8000; + + if (ctrl & ctrl_mask) wait_warn("unexpected controller status", state, ctrl, intr); return 0; -- cgit v1.2.3 From ac80dac00f8630803dc0c7f8fbe6983a8e2a8b5f Mon Sep 17 00:00:00 2001 From: Roman Tereshonkov Date: Wed, 3 Nov 2010 12:55:21 +0200 Subject: mtd: onenand: implement cache program feature for 4KiB page onenand Implement cache program feature for 4KiB page onenand. This feature improves the write data performance. The observed 128KiB data program speed change is from 8827KiB/s to 14156 KiB/s when the feature is enabled. Signed-off-by: Roman Tereshonkov Acked-by: Mike Frysinger Signed-off-by: Artem Bityutskiy Signed-off-by: David Woodhouse --- drivers/mtd/onenand/onenand_base.c | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c index 6b3a875647c9..4d6e6c54cc2c 100644 --- a/drivers/mtd/onenand/onenand_base.c +++ b/drivers/mtd/onenand/onenand_base.c @@ -1845,7 +1845,7 @@ static int onenand_write_ops_nolock(struct mtd_info *mtd, loff_t to, const u_char *buf = ops->datbuf; const u_char *oob = ops->oobbuf; u_char *oobbuf; - int ret = 0; + int ret = 0, cmd; DEBUG(MTD_DEBUG_LEVEL3, "%s: to = 0x%08x, len = %i\n", __func__, (unsigned int) to, (int) len); @@ -1954,7 +1954,19 @@ static int onenand_write_ops_nolock(struct mtd_info *mtd, loff_t to, ONENAND_SET_NEXT_BUFFERRAM(this); } - this->command(mtd, ONENAND_CMD_PROG, to, mtd->writesize); + this->ongoing = 0; + cmd = ONENAND_CMD_PROG; + + /* Exclude 1st OTP and OTP blocks for cache program feature */ + if (ONENAND_IS_CACHE_PROGRAM(this) && + likely(onenand_block(this, to) != 0) && + ONENAND_IS_4KB_PAGE(this) && + ((written + thislen) < len)) { + cmd = ONENAND_CMD_2X_CACHE_PROG; + this->ongoing = 1; + } + + this->command(mtd, cmd, to, mtd->writesize); /* * 2 PLANE, MLC, and Flex-OneNAND wait here @@ -3377,8 +3389,10 @@ static void onenand_check_features(struct mtd_info *mtd) case ONENAND_DEVICE_DENSITY_4Gb: if (ONENAND_IS_DDP(this)) this->options |= ONENAND_HAS_2PLANE; - else if (numbufs == 1) + else if (numbufs == 1) { this->options |= ONENAND_HAS_4KB_PAGE; + this->options |= ONENAND_HAS_CACHE_PROGRAM; + } case ONENAND_DEVICE_DENSITY_2Gb: /* 2Gb DDP does not have 2 plane */ @@ -3415,6 +3429,8 @@ static void onenand_check_features(struct mtd_info *mtd) printk(KERN_DEBUG "Chip has 2 plane\n"); if (this->options & ONENAND_HAS_4KB_PAGE) printk(KERN_DEBUG "Chip has 4KiB pagesize\n"); + if (this->options & ONENAND_HAS_CACHE_PROGRAM) + printk(KERN_DEBUG "Chip has cache program feature\n"); } /** -- cgit v1.2.3 From a0c5a3944ce121bb2417c771f77b18485cd84e18 Mon Sep 17 00:00:00 2001 From: Vasiliy Kulikov Date: Sat, 6 Nov 2010 17:41:24 +0300 Subject: mtd: mtdchar: fix information leak to userland Structure mtd_info_user is copied to userland with padding byted between "type" and "flags" fields uninitialized. It leads to leaking of contents of kernel stack memory. Signed-off-by: Vasiliy Kulikov Signed-off-by: Artem Bityutskiy Signed-off-by: David Woodhouse --- drivers/mtd/mtdchar.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c index 4759d827e8c7..cad8fcc7b239 100644 --- a/drivers/mtd/mtdchar.c +++ b/drivers/mtd/mtdchar.c @@ -601,6 +601,7 @@ static int mtd_ioctl(struct file *file, u_int cmd, u_long arg) } case MEMGETINFO: + memset(&info, 0, sizeof(info)); info.type = mtd->type; info.flags = mtd->flags; info.size = mtd->size; @@ -609,7 +610,6 @@ static int mtd_ioctl(struct file *file, u_int cmd, u_long arg) info.oobsize = mtd->oobsize; /* The below fields are obsolete */ info.ecctype = -1; - info.eccsize = 0; if (copy_to_user(argp, &info, sizeof(struct mtd_info_user))) return -EFAULT; break; -- cgit v1.2.3 From 65ab220c30bc2120eaa39753cadec68616e3f906 Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Mon, 8 Nov 2010 11:17:54 +0530 Subject: mtd: fsmc.h: including linux/io.h for definition of readl Signed-off-by: Viresh Kumar Signed-off-by: Artem Bityutskiy Signed-off-by: David Woodhouse --- include/linux/mtd/fsmc.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/linux/mtd/fsmc.h b/include/linux/mtd/fsmc.h index 5d2556700ec2..e210b87e6cd6 100644 --- a/include/linux/mtd/fsmc.h +++ b/include/linux/mtd/fsmc.h @@ -16,6 +16,7 @@ #ifndef __MTD_FSMC_H #define __MTD_FSMC_H +#include #include #include #include -- cgit v1.2.3 From ce4a37f7c93e9b12ac1452bedd823d73c43c0e63 Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Tue, 9 Nov 2010 00:09:02 +0100 Subject: mtd: remove unnecessary casts of void ptr returning alloc function return values The [vk][cmz]alloc(_node) family of functions return void pointers which it's completely unnecessary/pointless to cast to other pointer types since that happens implicitly. This patch removes such casts from drivers/mtd/ Signed-off-by: Jesper Juhl Signed-off-by: Artem Bityutskiy Signed-off-by: David Woodhouse --- drivers/mtd/maps/tqm8xxl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mtd/maps/tqm8xxl.c b/drivers/mtd/maps/tqm8xxl.c index 60146984f4be..c08e140d40ed 100644 --- a/drivers/mtd/maps/tqm8xxl.c +++ b/drivers/mtd/maps/tqm8xxl.c @@ -139,7 +139,7 @@ static int __init init_tqm_mtd(void) goto error_mem; } - map_banks[idx]->name = (char *)kmalloc(16, GFP_KERNEL); + map_banks[idx]->name = kmalloc(16, GFP_KERNEL); if (!map_banks[idx]->name) { ret = -ENOMEM; -- cgit v1.2.3 From a338adafed0d09d823169161e938b1eab4dce901 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Thu, 11 Nov 2010 19:02:47 +0100 Subject: mtd: NAND: jz4740: Make 'struct platform_driver jz_nand_driver' static Signed-off-by: Lars-Peter Clausen Signed-off-by: Artem Bityutskiy Signed-off-by: David Woodhouse --- drivers/mtd/nand/jz4740_nand.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mtd/nand/jz4740_nand.c b/drivers/mtd/nand/jz4740_nand.c index 67343fc31bd5..c9e2a59fd640 100644 --- a/drivers/mtd/nand/jz4740_nand.c +++ b/drivers/mtd/nand/jz4740_nand.c @@ -489,7 +489,7 @@ static int __devexit jz_nand_remove(struct platform_device *pdev) return 0; } -struct platform_driver jz_nand_driver = { +static struct platform_driver jz_nand_driver = { .probe = jz_nand_probe, .remove = __devexit_p(jz_nand_remove), .driver = { -- cgit v1.2.3 From 9118ea321ee320e3c670540122857ff0eba91e32 Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Thu, 11 Nov 2010 19:02:48 +0100 Subject: mtd: NAND: jz4740: Remove custom {read,write}_page handlers Now that the mtd core supports more then 64 ecc bytes we can use it instead of some a custom hack in the jz4740 nand driver. This patch removes the custom {read,write}_page handlers from the jz4740 nand driver. Thus the driver will now fallback to the default handlers from the nand core. Signed-off-by: Lars-Peter Clausen Signed-off-by: Artem Bityutskiy Signed-off-by: David Woodhouse --- drivers/mtd/nand/jz4740_nand.c | 55 ------------------------------------------ 1 file changed, 55 deletions(-) diff --git a/drivers/mtd/nand/jz4740_nand.c b/drivers/mtd/nand/jz4740_nand.c index c9e2a59fd640..cea38a5d4ac5 100644 --- a/drivers/mtd/nand/jz4740_nand.c +++ b/drivers/mtd/nand/jz4740_nand.c @@ -251,58 +251,6 @@ static int jz_nand_correct_ecc_rs(struct mtd_info *mtd, uint8_t *dat, return 0; } - -/* Copy paste of nand_read_page_hwecc_oob_first except for different eccpos - * handling. The ecc area is for 4k chips 72 bytes long and thus does not fit - * into the eccpos array. */ -static int jz_nand_read_page_hwecc_oob_first(struct mtd_info *mtd, - struct nand_chip *chip, uint8_t *buf, int page) -{ - int i, eccsize = chip->ecc.size; - int eccbytes = chip->ecc.bytes; - int eccsteps = chip->ecc.steps; - uint8_t *p = buf; - unsigned int ecc_offset = chip->page_shift; - - /* Read the OOB area first */ - chip->cmdfunc(mtd, NAND_CMD_READOOB, 0, page); - chip->read_buf(mtd, chip->oob_poi, mtd->oobsize); - chip->cmdfunc(mtd, NAND_CMD_READ0, 0, page); - - for (i = ecc_offset; eccsteps; eccsteps--, i += eccbytes, p += eccsize) { - int stat; - - chip->ecc.hwctl(mtd, NAND_ECC_READ); - chip->read_buf(mtd, p, eccsize); - - stat = chip->ecc.correct(mtd, p, &chip->oob_poi[i], NULL); - if (stat < 0) - mtd->ecc_stats.failed++; - else - mtd->ecc_stats.corrected += stat; - } - return 0; -} - -/* Copy-and-paste of nand_write_page_hwecc with different eccpos handling. */ -static void jz_nand_write_page_hwecc(struct mtd_info *mtd, - struct nand_chip *chip, const uint8_t *buf) -{ - int i, eccsize = chip->ecc.size; - int eccbytes = chip->ecc.bytes; - int eccsteps = chip->ecc.steps; - const uint8_t *p = buf; - unsigned int ecc_offset = chip->page_shift; - - for (i = ecc_offset; eccsteps; eccsteps--, i += eccbytes, p += eccsize) { - chip->ecc.hwctl(mtd, NAND_ECC_WRITE); - chip->write_buf(mtd, p, eccsize); - chip->ecc.calculate(mtd, p, &chip->oob_poi[i]); - } - - chip->write_buf(mtd, chip->oob_poi, mtd->oobsize); -} - #ifdef CONFIG_MTD_CMDLINE_PARTS static const char *part_probes[] = {"cmdline", NULL}; #endif @@ -393,9 +341,6 @@ static int __devinit jz_nand_probe(struct platform_device *pdev) chip->ecc.size = 512; chip->ecc.bytes = 9; - chip->ecc.read_page = jz_nand_read_page_hwecc_oob_first; - chip->ecc.write_page = jz_nand_write_page_hwecc; - if (pdata) chip->ecc.layout = pdata->ecc_layout; -- cgit v1.2.3 From f9a5279c70af10e967872e922b91310a91f87b05 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Fri, 12 Nov 2010 13:37:57 -0800 Subject: mtd: maps: Use printf extension %pR for struct resource Using %pR standardizes the struct resource output. Signed-off-by: Joe Perches Signed-off-by: Artem Bityutskiy Signed-off-by: David Woodhouse --- drivers/mtd/maps/amd76xrom.c | 7 ++----- drivers/mtd/maps/ck804xrom.c | 7 ++----- drivers/mtd/maps/esb2rom.c | 9 +++------ drivers/mtd/maps/ichxrom.c | 9 +++------ drivers/mtd/maps/physmap_of.c | 4 +--- drivers/mtd/maps/scx200_docflash.c | 5 ++--- 6 files changed, 13 insertions(+), 28 deletions(-) diff --git a/drivers/mtd/maps/amd76xrom.c b/drivers/mtd/maps/amd76xrom.c index 19fe92db0c46..77d64ce19e9f 100644 --- a/drivers/mtd/maps/amd76xrom.c +++ b/drivers/mtd/maps/amd76xrom.c @@ -149,11 +149,8 @@ static int __devinit amd76xrom_init_one (struct pci_dev *pdev, if (request_resource(&iomem_resource, &window->rsrc)) { window->rsrc.parent = NULL; printk(KERN_ERR MOD_NAME - " %s(): Unable to register resource" - " 0x%.16llx-0x%.16llx - kernel bug?\n", - __func__, - (unsigned long long)window->rsrc.start, - (unsigned long long)window->rsrc.end); + " %s(): Unable to register resource %pR - kernel bug?\n", + __func__, &window->rsrc); } diff --git a/drivers/mtd/maps/ck804xrom.c b/drivers/mtd/maps/ck804xrom.c index ddb462bea9b5..5fdb7b26cea3 100644 --- a/drivers/mtd/maps/ck804xrom.c +++ b/drivers/mtd/maps/ck804xrom.c @@ -178,11 +178,8 @@ static int __devinit ck804xrom_init_one (struct pci_dev *pdev, if (request_resource(&iomem_resource, &window->rsrc)) { window->rsrc.parent = NULL; printk(KERN_ERR MOD_NAME - " %s(): Unable to register resource" - " 0x%.016llx-0x%.016llx - kernel bug?\n", - __func__, - (unsigned long long)window->rsrc.start, - (unsigned long long)window->rsrc.end); + " %s(): Unable to register resource %pR - kernel bug?\n", + __func__, &window->rsrc); } diff --git a/drivers/mtd/maps/esb2rom.c b/drivers/mtd/maps/esb2rom.c index d12c93dc1aad..4feb7507ab7c 100644 --- a/drivers/mtd/maps/esb2rom.c +++ b/drivers/mtd/maps/esb2rom.c @@ -242,12 +242,9 @@ static int __devinit esb2rom_init_one(struct pci_dev *pdev, window->rsrc.flags = IORESOURCE_MEM | IORESOURCE_BUSY; if (request_resource(&iomem_resource, &window->rsrc)) { window->rsrc.parent = NULL; - printk(KERN_DEBUG MOD_NAME - ": %s(): Unable to register resource" - " 0x%.08llx-0x%.08llx - kernel bug?\n", - __func__, - (unsigned long long)window->rsrc.start, - (unsigned long long)window->rsrc.end); + printk(KERN_DEBUG MOD_NAME ": " + "%s(): Unable to register resource %pR - kernel bug?\n", + __func__, &window->rsrc); } /* Map the firmware hub into my address space. */ diff --git a/drivers/mtd/maps/ichxrom.c b/drivers/mtd/maps/ichxrom.c index f102bf243a74..1337a4191a0c 100644 --- a/drivers/mtd/maps/ichxrom.c +++ b/drivers/mtd/maps/ichxrom.c @@ -175,12 +175,9 @@ static int __devinit ichxrom_init_one (struct pci_dev *pdev, window->rsrc.flags = IORESOURCE_MEM | IORESOURCE_BUSY; if (request_resource(&iomem_resource, &window->rsrc)) { window->rsrc.parent = NULL; - printk(KERN_DEBUG MOD_NAME - ": %s(): Unable to register resource" - " 0x%.16llx-0x%.16llx - kernel bug?\n", - __func__, - (unsigned long long)window->rsrc.start, - (unsigned long long)window->rsrc.end); + printk(KERN_DEBUG MOD_NAME ": " + "%s(): Unable to register resource %pR - kernel bug?\n", + __func__, &window->rsrc); } /* Map the firmware hub into my address space. */ diff --git a/drivers/mtd/maps/physmap_of.c b/drivers/mtd/maps/physmap_of.c index 9861814aa027..8506578e6a35 100644 --- a/drivers/mtd/maps/physmap_of.c +++ b/drivers/mtd/maps/physmap_of.c @@ -274,9 +274,7 @@ static int __devinit of_flash_probe(struct platform_device *dev, continue; } - dev_dbg(&dev->dev, "of_flash device: %.8llx-%.8llx\n", - (unsigned long long)res.start, - (unsigned long long)res.end); + dev_dbg(&dev->dev, "of_flash device: %pR\n", &res); err = -EBUSY; res_size = resource_size(&res); diff --git a/drivers/mtd/maps/scx200_docflash.c b/drivers/mtd/maps/scx200_docflash.c index b5391ebb736e..027e628a4f1d 100644 --- a/drivers/mtd/maps/scx200_docflash.c +++ b/drivers/mtd/maps/scx200_docflash.c @@ -166,9 +166,8 @@ static int __init init_scx200_docflash(void) outl(pmr, scx200_cb_base + SCx200_PMR); } - printk(KERN_INFO NAME ": DOCCS mapped at 0x%llx-0x%llx, width %d\n", - (unsigned long long)docmem.start, - (unsigned long long)docmem.end, width); + printk(KERN_INFO NAME ": DOCCS mapped at %pR, width %d\n", + &docmem, width); scx200_docflash_map.size = size; if (width == 8) -- cgit v1.2.3 From 23079f94daabc4e06436ab2b643fac31dec017d1 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Fri, 12 Nov 2010 13:37:58 -0800 Subject: mtd: nand: Use printf extension %pR for struct resource Using %pR standardizes the struct resource output. Signed-off-by: Joe Perches Signed-off-by: Artem Bityutskiy Signed-off-by: David Woodhouse --- drivers/mtd/nand/pasemi_nand.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mtd/nand/pasemi_nand.c b/drivers/mtd/nand/pasemi_nand.c index 6ddb2461d740..bb277a54986f 100644 --- a/drivers/mtd/nand/pasemi_nand.c +++ b/drivers/mtd/nand/pasemi_nand.c @@ -107,7 +107,7 @@ static int __devinit pasemi_nand_probe(struct platform_device *ofdev, if (pasemi_nand_mtd) return -ENODEV; - pr_debug("pasemi_nand at %llx-%llx\n", res.start, res.end); + pr_debug("pasemi_nand at %pR\n", &res); /* Allocate memory for MTD device structure and private data */ pasemi_nand_mtd = kzalloc(sizeof(struct mtd_info) + -- cgit v1.2.3 From f326966b3df47f4fa7e90425f60efdd30c31fe19 Mon Sep 17 00:00:00 2001 From: Vasiliy Kulikov Date: Sun, 14 Nov 2010 23:08:39 +0300 Subject: jffs2: fix error value sign do_verify_xattr_datum(), do_load_xattr_datum(), load_xattr_datum() and verify_xattr_ref() should return negative value on error. Sometimes they return EIO that is positive. Change this to -EIO. Signed-off-by: Vasiliy Kulikov Signed-off-by: Artem Bityutskiy Signed-off-by: David Woodhouse --- fs/jffs2/xattr.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/fs/jffs2/xattr.c b/fs/jffs2/xattr.c index 9b572ca40a49..4f9cc0482949 100644 --- a/fs/jffs2/xattr.c +++ b/fs/jffs2/xattr.c @@ -151,7 +151,7 @@ static int do_verify_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_dat JFFS2_ERROR("node CRC failed at %#08x, read=%#08x, calc=%#08x\n", offset, je32_to_cpu(rx.hdr_crc), crc); xd->flags |= JFFS2_XFLAGS_INVALID; - return EIO; + return -EIO; } totlen = PAD(sizeof(rx) + rx.name_len + 1 + je16_to_cpu(rx.value_len)); if (je16_to_cpu(rx.magic) != JFFS2_MAGIC_BITMASK @@ -167,7 +167,7 @@ static int do_verify_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_dat je32_to_cpu(rx.xid), xd->xid, je32_to_cpu(rx.version), xd->version); xd->flags |= JFFS2_XFLAGS_INVALID; - return EIO; + return -EIO; } xd->xprefix = rx.xprefix; xd->name_len = rx.name_len; @@ -230,7 +230,7 @@ static int do_load_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum ref_offset(xd->node), xd->data_crc, crc); kfree(data); xd->flags |= JFFS2_XFLAGS_INVALID; - return EIO; + return -EIO; } xd->flags |= JFFS2_XFLAGS_HOT; @@ -268,7 +268,7 @@ static int load_xattr_datum(struct jffs2_sb_info *c, struct jffs2_xattr_datum *x if (xd->xname) return 0; if (xd->flags & JFFS2_XFLAGS_INVALID) - return EIO; + return -EIO; if (unlikely(is_xattr_datum_unchecked(c, xd))) rc = do_verify_xattr_datum(c, xd); if (!rc) @@ -460,7 +460,7 @@ static int verify_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_ref *ref if (crc != je32_to_cpu(rr.node_crc)) { JFFS2_ERROR("node CRC failed at %#08x, read=%#08x, calc=%#08x\n", offset, je32_to_cpu(rr.node_crc), crc); - return EIO; + return -EIO; } if (je16_to_cpu(rr.magic) != JFFS2_MAGIC_BITMASK || je16_to_cpu(rr.nodetype) != JFFS2_NODETYPE_XREF @@ -470,7 +470,7 @@ static int verify_xattr_ref(struct jffs2_sb_info *c, struct jffs2_xattr_ref *ref offset, je16_to_cpu(rr.magic), JFFS2_MAGIC_BITMASK, je16_to_cpu(rr.nodetype), JFFS2_NODETYPE_XREF, je32_to_cpu(rr.totlen), PAD(sizeof(rr))); - return EIO; + return -EIO; } ref->ino = je32_to_cpu(rr.ino); ref->xid = je32_to_cpu(rr.xid); -- cgit v1.2.3 From 027d9ac2c8de9f70b7319e08dee121b8b85c8d88 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Mon, 15 Nov 2010 21:20:05 +0300 Subject: jffs2: typo in comment It says FB instead of FS (file system). Signed-off-by: Dan Carpenter Signed-off-by: Artem Bityutskiy Signed-off-by: David Woodhouse --- fs/jffs2/jffs2_fs_sb.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/jffs2/jffs2_fs_sb.h b/fs/jffs2/jffs2_fs_sb.h index f864005de64c..0bc6a6c80a56 100644 --- a/fs/jffs2/jffs2_fs_sb.h +++ b/fs/jffs2/jffs2_fs_sb.h @@ -144,4 +144,4 @@ struct jffs2_sb_info { void *os_priv; }; -#endif /* _JFFS2_FB_SB */ +#endif /* _JFFS2_FS_SB */ -- cgit v1.2.3 From cc31822250236ec173bb2aa149ebe2ba35405db2 Mon Sep 17 00:00:00 2001 From: Guillaume LECERF Date: Wed, 17 Nov 2010 12:35:50 +0100 Subject: mtd: cfi_fixup: remove unused 'param' parameter The 'param' parameter has never been used since its introduction, so simply remove it. Signed-off-by: Guillaume LECERF Signed-off-by: Artem Bityutskiy Signed-off-by: David Woodhouse --- drivers/mtd/chips/cfi_cmdset_0001.c | 54 ++++++++++----------- drivers/mtd/chips/cfi_cmdset_0002.c | 94 ++++++++++++++++++------------------- drivers/mtd/chips/cfi_util.c | 2 +- drivers/mtd/chips/fwh_lock.h | 2 +- include/linux/mtd/cfi.h | 3 +- 5 files changed, 77 insertions(+), 78 deletions(-) diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c b/drivers/mtd/chips/cfi_cmdset_0001.c index ad9268b44416..44cbfc093ecc 100644 --- a/drivers/mtd/chips/cfi_cmdset_0001.c +++ b/drivers/mtd/chips/cfi_cmdset_0001.c @@ -162,7 +162,7 @@ static void cfi_tell_features(struct cfi_pri_intelext *extp) #endif /* Atmel chips don't use the same PRI format as Intel chips */ -static void fixup_convert_atmel_pri(struct mtd_info *mtd, void *param) +static void fixup_convert_atmel_pri(struct mtd_info *mtd) { struct map_info *map = mtd->priv; struct cfi_private *cfi = map->fldrv_priv; @@ -202,7 +202,7 @@ static void fixup_convert_atmel_pri(struct mtd_info *mtd, void *param) cfi->cfiq->BufWriteTimeoutMax = 0; } -static void fixup_at49bv640dx_lock(struct mtd_info *mtd, void *param) +static void fixup_at49bv640dx_lock(struct mtd_info *mtd) { struct map_info *map = mtd->priv; struct cfi_private *cfi = map->fldrv_priv; @@ -214,7 +214,7 @@ static void fixup_at49bv640dx_lock(struct mtd_info *mtd, void *param) #ifdef CMDSET0001_DISABLE_ERASE_SUSPEND_ON_WRITE /* Some Intel Strata Flash prior to FPO revision C has bugs in this area */ -static void fixup_intel_strataflash(struct mtd_info *mtd, void* param) +static void fixup_intel_strataflash(struct mtd_info *mtd) { struct map_info *map = mtd->priv; struct cfi_private *cfi = map->fldrv_priv; @@ -227,7 +227,7 @@ static void fixup_intel_strataflash(struct mtd_info *mtd, void* param) #endif #ifdef CMDSET0001_DISABLE_WRITE_SUSPEND -static void fixup_no_write_suspend(struct mtd_info *mtd, void* param) +static void fixup_no_write_suspend(struct mtd_info *mtd) { struct map_info *map = mtd->priv; struct cfi_private *cfi = map->fldrv_priv; @@ -240,7 +240,7 @@ static void fixup_no_write_suspend(struct mtd_info *mtd, void* param) } #endif -static void fixup_st_m28w320ct(struct mtd_info *mtd, void* param) +static void fixup_st_m28w320ct(struct mtd_info *mtd) { struct map_info *map = mtd->priv; struct cfi_private *cfi = map->fldrv_priv; @@ -249,7 +249,7 @@ static void fixup_st_m28w320ct(struct mtd_info *mtd, void* param) cfi->cfiq->BufWriteTimeoutMax = 0; /* Not supported */ } -static void fixup_st_m28w320cb(struct mtd_info *mtd, void* param) +static void fixup_st_m28w320cb(struct mtd_info *mtd) { struct map_info *map = mtd->priv; struct cfi_private *cfi = map->fldrv_priv; @@ -259,7 +259,7 @@ static void fixup_st_m28w320cb(struct mtd_info *mtd, void* param) (cfi->cfiq->EraseRegionInfo[1] & 0xffff0000) | 0x3e; }; -static void fixup_use_point(struct mtd_info *mtd, void *param) +static void fixup_use_point(struct mtd_info *mtd) { struct map_info *map = mtd->priv; if (!mtd->point && map_is_linear(map)) { @@ -268,7 +268,7 @@ static void fixup_use_point(struct mtd_info *mtd, void *param) } } -static void fixup_use_write_buffers(struct mtd_info *mtd, void *param) +static void fixup_use_write_buffers(struct mtd_info *mtd) { struct map_info *map = mtd->priv; struct cfi_private *cfi = map->fldrv_priv; @@ -282,7 +282,7 @@ static void fixup_use_write_buffers(struct mtd_info *mtd, void *param) /* * Some chips power-up with all sectors locked by default. */ -static void fixup_unlock_powerup_lock(struct mtd_info *mtd, void *param) +static void fixup_unlock_powerup_lock(struct mtd_info *mtd) { struct map_info *map = mtd->priv; struct cfi_private *cfi = map->fldrv_priv; @@ -295,31 +295,31 @@ static void fixup_unlock_powerup_lock(struct mtd_info *mtd, void *param) } static struct cfi_fixup cfi_fixup_table[] = { - { CFI_MFR_ATMEL, CFI_ID_ANY, fixup_convert_atmel_pri, NULL }, - { CFI_MFR_ATMEL, AT49BV640D, fixup_at49bv640dx_lock, NULL }, - { CFI_MFR_ATMEL, AT49BV640DT, fixup_at49bv640dx_lock, NULL }, + { CFI_MFR_ATMEL, CFI_ID_ANY, fixup_convert_atmel_pri }, + { CFI_MFR_ATMEL, AT49BV640D, fixup_at49bv640dx_lock }, + { CFI_MFR_ATMEL, AT49BV640DT, fixup_at49bv640dx_lock }, #ifdef CMDSET0001_DISABLE_ERASE_SUSPEND_ON_WRITE - { CFI_MFR_ANY, CFI_ID_ANY, fixup_intel_strataflash, NULL }, + { CFI_MFR_ANY, CFI_ID_ANY, fixup_intel_strataflash }, #endif #ifdef CMDSET0001_DISABLE_WRITE_SUSPEND - { CFI_MFR_ANY, CFI_ID_ANY, fixup_no_write_suspend, NULL }, + { CFI_MFR_ANY, CFI_ID_ANY, fixup_no_write_suspend }, #endif #if !FORCE_WORD_WRITE - { CFI_MFR_ANY, CFI_ID_ANY, fixup_use_write_buffers, NULL }, + { CFI_MFR_ANY, CFI_ID_ANY, fixup_use_write_buffers }, #endif - { CFI_MFR_ST, 0x00ba, /* M28W320CT */ fixup_st_m28w320ct, NULL }, - { CFI_MFR_ST, 0x00bb, /* M28W320CB */ fixup_st_m28w320cb, NULL }, - { CFI_MFR_INTEL, CFI_ID_ANY, fixup_unlock_powerup_lock, NULL, }, - { 0, 0, NULL, NULL } + { CFI_MFR_ST, 0x00ba, /* M28W320CT */ fixup_st_m28w320ct }, + { CFI_MFR_ST, 0x00bb, /* M28W320CB */ fixup_st_m28w320cb }, + { CFI_MFR_INTEL, CFI_ID_ANY, fixup_unlock_powerup_lock }, + { 0, 0, NULL } }; static struct cfi_fixup jedec_fixup_table[] = { - { CFI_MFR_INTEL, I82802AB, fixup_use_fwh_lock, NULL, }, - { CFI_MFR_INTEL, I82802AC, fixup_use_fwh_lock, NULL, }, - { CFI_MFR_ST, M50LPW080, fixup_use_fwh_lock, NULL, }, - { CFI_MFR_ST, M50FLW080A, fixup_use_fwh_lock, NULL, }, - { CFI_MFR_ST, M50FLW080B, fixup_use_fwh_lock, NULL, }, - { 0, 0, NULL, NULL } + { CFI_MFR_INTEL, I82802AB, fixup_use_fwh_lock }, + { CFI_MFR_INTEL, I82802AC, fixup_use_fwh_lock }, + { CFI_MFR_ST, M50LPW080, fixup_use_fwh_lock }, + { CFI_MFR_ST, M50FLW080A, fixup_use_fwh_lock }, + { CFI_MFR_ST, M50FLW080B, fixup_use_fwh_lock }, + { 0, 0, NULL } }; static struct cfi_fixup fixup_table[] = { /* The CFI vendor ids and the JEDEC vendor IDs appear @@ -327,8 +327,8 @@ static struct cfi_fixup fixup_table[] = { * well. This table is to pick all cases where * we know that is the case. */ - { CFI_MFR_ANY, CFI_ID_ANY, fixup_use_point, NULL }, - { 0, 0, NULL, NULL } + { CFI_MFR_ANY, CFI_ID_ANY, fixup_use_point }, + { 0, 0, NULL } }; static void cfi_fixup_major_minor(struct cfi_private *cfi, diff --git a/drivers/mtd/chips/cfi_cmdset_0002.c b/drivers/mtd/chips/cfi_cmdset_0002.c index 3b8e32d87977..9d68ab919f31 100644 --- a/drivers/mtd/chips/cfi_cmdset_0002.c +++ b/drivers/mtd/chips/cfi_cmdset_0002.c @@ -134,7 +134,7 @@ static void cfi_tell_features(struct cfi_pri_amdstd *extp) #ifdef AMD_BOOTLOC_BUG /* Wheee. Bring me the head of someone at AMD. */ -static void fixup_amd_bootblock(struct mtd_info *mtd, void* param) +static void fixup_amd_bootblock(struct mtd_info *mtd) { struct map_info *map = mtd->priv; struct cfi_private *cfi = map->fldrv_priv; @@ -186,7 +186,7 @@ static void fixup_amd_bootblock(struct mtd_info *mtd, void* param) } #endif -static void fixup_use_write_buffers(struct mtd_info *mtd, void *param) +static void fixup_use_write_buffers(struct mtd_info *mtd) { struct map_info *map = mtd->priv; struct cfi_private *cfi = map->fldrv_priv; @@ -197,7 +197,7 @@ static void fixup_use_write_buffers(struct mtd_info *mtd, void *param) } /* Atmel chips don't use the same PRI format as AMD chips */ -static void fixup_convert_atmel_pri(struct mtd_info *mtd, void *param) +static void fixup_convert_atmel_pri(struct mtd_info *mtd) { struct map_info *map = mtd->priv; struct cfi_private *cfi = map->fldrv_priv; @@ -228,14 +228,14 @@ static void fixup_convert_atmel_pri(struct mtd_info *mtd, void *param) cfi->cfiq->BufWriteTimeoutMax = 0; } -static void fixup_use_secsi(struct mtd_info *mtd, void *param) +static void fixup_use_secsi(struct mtd_info *mtd) { /* Setup for chips with a secsi area */ mtd->read_user_prot_reg = cfi_amdstd_secsi_read; mtd->read_fact_prot_reg = cfi_amdstd_secsi_read; } -static void fixup_use_erase_chip(struct mtd_info *mtd, void *param) +static void fixup_use_erase_chip(struct mtd_info *mtd) { struct map_info *map = mtd->priv; struct cfi_private *cfi = map->fldrv_priv; @@ -250,7 +250,7 @@ static void fixup_use_erase_chip(struct mtd_info *mtd, void *param) * Some Atmel chips (e.g. the AT49BV6416) power-up with all sectors * locked by default. */ -static void fixup_use_atmel_lock(struct mtd_info *mtd, void *param) +static void fixup_use_atmel_lock(struct mtd_info *mtd) { mtd->lock = cfi_atmel_lock; mtd->unlock = cfi_atmel_unlock; @@ -271,7 +271,7 @@ static void fixup_old_sst_eraseregion(struct mtd_info *mtd) cfi->cfiq->NumEraseRegions = 1; } -static void fixup_sst39vf(struct mtd_info *mtd, void *param) +static void fixup_sst39vf(struct mtd_info *mtd) { struct map_info *map = mtd->priv; struct cfi_private *cfi = map->fldrv_priv; @@ -282,7 +282,7 @@ static void fixup_sst39vf(struct mtd_info *mtd, void *param) cfi->addr_unlock2 = 0x2AAA; } -static void fixup_sst39vf_rev_b(struct mtd_info *mtd, void *param) +static void fixup_sst39vf_rev_b(struct mtd_info *mtd) { struct map_info *map = mtd->priv; struct cfi_private *cfi = map->fldrv_priv; @@ -295,12 +295,12 @@ static void fixup_sst39vf_rev_b(struct mtd_info *mtd, void *param) cfi->sector_erase_cmd = CMD(0x50); } -static void fixup_sst38vf640x_sectorsize(struct mtd_info *mtd, void *param) +static void fixup_sst38vf640x_sectorsize(struct mtd_info *mtd) { struct map_info *map = mtd->priv; struct cfi_private *cfi = map->fldrv_priv; - fixup_sst39vf_rev_b(mtd, param); + fixup_sst39vf_rev_b(mtd); /* * CFI reports 1024 sectors (0x03ff+1) of 64KBytes (0x0100*256) where @@ -310,7 +310,7 @@ static void fixup_sst38vf640x_sectorsize(struct mtd_info *mtd, void *param) pr_warning("%s: Bad 38VF640x CFI data; adjusting sector size from 64 to 8KiB\n", mtd->name); } -static void fixup_s29gl064n_sectors(struct mtd_info *mtd, void *param) +static void fixup_s29gl064n_sectors(struct mtd_info *mtd) { struct map_info *map = mtd->priv; struct cfi_private *cfi = map->fldrv_priv; @@ -321,7 +321,7 @@ static void fixup_s29gl064n_sectors(struct mtd_info *mtd, void *param) } } -static void fixup_s29gl032n_sectors(struct mtd_info *mtd, void *param) +static void fixup_s29gl032n_sectors(struct mtd_info *mtd) { struct map_info *map = mtd->priv; struct cfi_private *cfi = map->fldrv_priv; @@ -334,47 +334,47 @@ static void fixup_s29gl032n_sectors(struct mtd_info *mtd, void *param) /* Used to fix CFI-Tables of chips without Extended Query Tables */ static struct cfi_fixup cfi_nopri_fixup_table[] = { - { CFI_MFR_SST, 0x234A, fixup_sst39vf, NULL, }, /* SST39VF1602 */ - { CFI_MFR_SST, 0x234B, fixup_sst39vf, NULL, }, /* SST39VF1601 */ - { CFI_MFR_SST, 0x235A, fixup_sst39vf, NULL, }, /* SST39VF3202 */ - { CFI_MFR_SST, 0x235B, fixup_sst39vf, NULL, }, /* SST39VF3201 */ - { CFI_MFR_SST, 0x235C, fixup_sst39vf_rev_b, NULL, }, /* SST39VF3202B */ - { CFI_MFR_SST, 0x235D, fixup_sst39vf_rev_b, NULL, }, /* SST39VF3201B */ - { CFI_MFR_SST, 0x236C, fixup_sst39vf_rev_b, NULL, }, /* SST39VF6402B */ - { CFI_MFR_SST, 0x236D, fixup_sst39vf_rev_b, NULL, }, /* SST39VF6401B */ - { 0, 0, NULL, NULL } + { CFI_MFR_SST, 0x234a, fixup_sst39vf }, /* SST39VF1602 */ + { CFI_MFR_SST, 0x234b, fixup_sst39vf }, /* SST39VF1601 */ + { CFI_MFR_SST, 0x235a, fixup_sst39vf }, /* SST39VF3202 */ + { CFI_MFR_SST, 0x235b, fixup_sst39vf }, /* SST39VF3201 */ + { CFI_MFR_SST, 0x235c, fixup_sst39vf_rev_b }, /* SST39VF3202B */ + { CFI_MFR_SST, 0x235d, fixup_sst39vf_rev_b }, /* SST39VF3201B */ + { CFI_MFR_SST, 0x236c, fixup_sst39vf_rev_b }, /* SST39VF6402B */ + { CFI_MFR_SST, 0x236d, fixup_sst39vf_rev_b }, /* SST39VF6401B */ + { 0, 0, NULL } }; static struct cfi_fixup cfi_fixup_table[] = { - { CFI_MFR_ATMEL, CFI_ID_ANY, fixup_convert_atmel_pri, NULL }, + { CFI_MFR_ATMEL, CFI_ID_ANY, fixup_convert_atmel_pri }, #ifdef AMD_BOOTLOC_BUG - { CFI_MFR_AMD, CFI_ID_ANY, fixup_amd_bootblock, NULL }, - { CFI_MFR_MACRONIX, CFI_ID_ANY, fixup_amd_bootblock, NULL }, + { CFI_MFR_AMD, CFI_ID_ANY, fixup_amd_bootblock }, + { CFI_MFR_MACRONIX, CFI_ID_ANY, fixup_amd_bootblock }, #endif - { CFI_MFR_AMD, 0x0050, fixup_use_secsi, NULL, }, - { CFI_MFR_AMD, 0x0053, fixup_use_secsi, NULL, }, - { CFI_MFR_AMD, 0x0055, fixup_use_secsi, NULL, }, - { CFI_MFR_AMD, 0x0056, fixup_use_secsi, NULL, }, - { CFI_MFR_AMD, 0x005C, fixup_use_secsi, NULL, }, - { CFI_MFR_AMD, 0x005F, fixup_use_secsi, NULL, }, - { CFI_MFR_AMD, 0x0c01, fixup_s29gl064n_sectors, NULL, }, - { CFI_MFR_AMD, 0x1301, fixup_s29gl064n_sectors, NULL, }, - { CFI_MFR_AMD, 0x1a00, fixup_s29gl032n_sectors, NULL, }, - { CFI_MFR_AMD, 0x1a01, fixup_s29gl032n_sectors, NULL, }, - { CFI_MFR_SST, 0x536A, fixup_sst38vf640x_sectorsize, NULL, }, /* SST38VF6402 */ - { CFI_MFR_SST, 0x536B, fixup_sst38vf640x_sectorsize, NULL, }, /* SST38VF6401 */ - { CFI_MFR_SST, 0x536C, fixup_sst38vf640x_sectorsize, NULL, }, /* SST38VF6404 */ - { CFI_MFR_SST, 0x536D, fixup_sst38vf640x_sectorsize, NULL, }, /* SST38VF6403 */ + { CFI_MFR_AMD, 0x0050, fixup_use_secsi }, + { CFI_MFR_AMD, 0x0053, fixup_use_secsi }, + { CFI_MFR_AMD, 0x0055, fixup_use_secsi }, + { CFI_MFR_AMD, 0x0056, fixup_use_secsi }, + { CFI_MFR_AMD, 0x005C, fixup_use_secsi }, + { CFI_MFR_AMD, 0x005F, fixup_use_secsi }, + { CFI_MFR_AMD, 0x0c01, fixup_s29gl064n_sectors }, + { CFI_MFR_AMD, 0x1301, fixup_s29gl064n_sectors }, + { CFI_MFR_AMD, 0x1a00, fixup_s29gl032n_sectors }, + { CFI_MFR_AMD, 0x1a01, fixup_s29gl032n_sectors }, + { CFI_MFR_SST, 0x536a, fixup_sst38vf640x_sectorsize }, /* SST38VF6402 */ + { CFI_MFR_SST, 0x536b, fixup_sst38vf640x_sectorsize }, /* SST38VF6401 */ + { CFI_MFR_SST, 0x536c, fixup_sst38vf640x_sectorsize }, /* SST38VF6404 */ + { CFI_MFR_SST, 0x536d, fixup_sst38vf640x_sectorsize }, /* SST38VF6403 */ #if !FORCE_WORD_WRITE - { CFI_MFR_ANY, CFI_ID_ANY, fixup_use_write_buffers, NULL, }, + { CFI_MFR_ANY, CFI_ID_ANY, fixup_use_write_buffers }, #endif - { 0, 0, NULL, NULL } + { 0, 0, NULL } }; static struct cfi_fixup jedec_fixup_table[] = { - { CFI_MFR_SST, SST49LF004B, fixup_use_fwh_lock, NULL, }, - { CFI_MFR_SST, SST49LF040B, fixup_use_fwh_lock, NULL, }, - { CFI_MFR_SST, SST49LF008A, fixup_use_fwh_lock, NULL, }, - { 0, 0, NULL, NULL } + { CFI_MFR_SST, SST49LF004B, fixup_use_fwh_lock }, + { CFI_MFR_SST, SST49LF040B, fixup_use_fwh_lock }, + { CFI_MFR_SST, SST49LF008A, fixup_use_fwh_lock }, + { 0, 0, NULL } }; static struct cfi_fixup fixup_table[] = { @@ -383,9 +383,9 @@ static struct cfi_fixup fixup_table[] = { * well. This table is to pick all cases where * we know that is the case. */ - { CFI_MFR_ANY, CFI_ID_ANY, fixup_use_erase_chip, NULL }, - { CFI_MFR_ATMEL, AT49BV6416, fixup_use_atmel_lock, NULL }, - { 0, 0, NULL, NULL } + { CFI_MFR_ANY, CFI_ID_ANY, fixup_use_erase_chip }, + { CFI_MFR_ATMEL, AT49BV6416, fixup_use_atmel_lock }, + { 0, 0, NULL } }; diff --git a/drivers/mtd/chips/cfi_util.c b/drivers/mtd/chips/cfi_util.c index 360525c637d2..6ae3d111e1e7 100644 --- a/drivers/mtd/chips/cfi_util.c +++ b/drivers/mtd/chips/cfi_util.c @@ -156,7 +156,7 @@ void cfi_fixup(struct mtd_info *mtd, struct cfi_fixup *fixups) for (f=fixups; f->fixup; f++) { if (((f->mfr == CFI_MFR_ANY) || (f->mfr == cfi->mfr)) && ((f->id == CFI_ID_ANY) || (f->id == cfi->id))) { - f->fixup(mtd, f->param); + f->fixup(mtd); } } } diff --git a/drivers/mtd/chips/fwh_lock.h b/drivers/mtd/chips/fwh_lock.h index d18064977192..5e3cc80128aa 100644 --- a/drivers/mtd/chips/fwh_lock.h +++ b/drivers/mtd/chips/fwh_lock.h @@ -98,7 +98,7 @@ static int fwh_unlock_varsize(struct mtd_info *mtd, loff_t ofs, uint64_t len) return ret; } -static void fixup_use_fwh_lock(struct mtd_info *mtd, void *param) +static void fixup_use_fwh_lock(struct mtd_info *mtd) { printk(KERN_NOTICE "using fwh lock/unlock method\n"); /* Setup for the chips with the fwh lock method */ diff --git a/include/linux/mtd/cfi.h b/include/linux/mtd/cfi.h index 4dd0c2cd7659..a9baee6864af 100644 --- a/include/linux/mtd/cfi.h +++ b/include/linux/mtd/cfi.h @@ -527,8 +527,7 @@ struct cfi_extquery *cfi_read_pri(struct map_info *map, uint16_t adr, uint16_t s struct cfi_fixup { uint16_t mfr; uint16_t id; - void (*fixup)(struct mtd_info *mtd, void* param); - void* param; + void (*fixup)(struct mtd_info *mtd); }; #define CFI_MFR_ANY 0xFFFF -- cgit v1.2.3 From 1534b8b09757190ce6e97fa97f9ad77c49082cd8 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Thu, 18 Nov 2010 15:02:21 -0800 Subject: mtd: fix nand kernel-doc warnings Warning(include/linux/mtd/nand.h:543): No description found for parameter 'badblockbits' Warning(drivers/mtd/nand/nand_bbt.c:1101): No description found for parameter 'mtd' Signed-off-by: Randy Dunlap Cc: David Woodhouse Cc: linux-mtd@lists.infradead.org Signed-off-by: Artem Bityutskiy Signed-off-by: David Woodhouse --- drivers/mtd/nand/nand_bbt.c | 3 ++- include/linux/mtd/nand.h | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/mtd/nand/nand_bbt.c b/drivers/mtd/nand/nand_bbt.c index 586b981f0e61..6ebd869993aa 100644 --- a/drivers/mtd/nand/nand_bbt.c +++ b/drivers/mtd/nand/nand_bbt.c @@ -1092,7 +1092,8 @@ static void mark_bbt_region(struct mtd_info *mtd, struct nand_bbt_descr *td) /** * verify_bbt_descr - verify the bad block description - * @bd: the table to verify + * @mtd: MTD device structure + * @bd: the table to verify * * This functions performs a few sanity checks on the bad block description * table. diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h index 63e17d01fde9..1f489b247a29 100644 --- a/include/linux/mtd/nand.h +++ b/include/linux/mtd/nand.h @@ -448,6 +448,8 @@ struct nand_buffers { * See the defines for further explanation. * @badblockpos: [INTERN] position of the bad block marker in the oob * area. + * @badblockbits: [INTERN] number of bits to left-shift the bad block + * number * @cellinfo: [INTERN] MLC/multichip data from chip ident * @numchips: [INTERN] number of physical chips * @chipsize: [INTERN] the size of one chip for multichip arrays -- cgit v1.2.3 From e14feafbe0d5c6d64bb6fe4eba928cb57ac9a4c8 Mon Sep 17 00:00:00 2001 From: Jason Liu Date: Fri, 19 Nov 2010 16:40:45 +0800 Subject: mtd: nand: add check for out of page read When run mtd_oobtest case, there will be one error for step(4), which turned out it need add one check for out of page read in nand_do_read_oob just like mtd_do_write_oob did it already. This commit also fix one typo error for comments in mtd_do_write_oob Signed-off-by: Jason Liu Signed-off-by: Artem Bityutskiy Signed-off-by: David Woodhouse --- drivers/mtd/nand/nand_base.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index 1f75a1b1f7c3..75d199e4f25b 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -1782,6 +1782,13 @@ static int nand_do_read_oob(struct mtd_info *mtd, loff_t from, else len = mtd->oobsize; + /* Do not allow read past end of page */ + if ((ops->ooboffs + readlen) > len) { + DEBUG(MTD_DEBUG_LEVEL0, "%s: Attempt to read " + "past end of page\n", __func__); + return -EINVAL; + } + if (unlikely(ops->ooboffs >= len)) { DEBUG(MTD_DEBUG_LEVEL0, "%s: Attempt to start read " "outside oob\n", __func__); @@ -2377,7 +2384,7 @@ static int nand_do_write_oob(struct mtd_info *mtd, loff_t to, return -EINVAL; } - /* Do not allow reads past end of device */ + /* Do not allow write past end of device */ if (unlikely(to >= mtd->size || ops->ooboffs + ops->ooblen > ((mtd->size >> chip->page_shift) - -- cgit v1.2.3 From a7e93dcd9aacb3ef4acfcc4310577f3ae0741821 Mon Sep 17 00:00:00 2001 From: Roman Tereshonkov Date: Tue, 23 Nov 2010 14:17:17 +0200 Subject: mtd: fix master device identification for mtd repartition Function mtd_has_master renamed as mtd_is_partition to follow the function logic. The patch fixes the problem of checking the right mtd device for partition creation. To delete partition checking is not needed here so as it is done in mtd_del_partition. By master we consider the mtd device which does not belong to any partition. Signed-off-by: Roman Tereshonkov Signed-off-by: Artem Bityutskiy Signed-off-by: David Woodhouse --- drivers/mtd/mtdchar.c | 8 ++++---- drivers/mtd/mtdpart.c | 10 +++++----- include/linux/mtd/partitions.h | 2 +- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c index cad8fcc7b239..16de17b5b829 100644 --- a/drivers/mtd/mtdchar.c +++ b/drivers/mtd/mtdchar.c @@ -522,10 +522,6 @@ static int mtd_blkpg_ioctl(struct mtd_info *mtd, if (!capable(CAP_SYS_ADMIN)) return -EPERM; - /* Only master mtd device must be used to control partitions */ - if (!mtd_is_master(mtd)) - return -EINVAL; - if (copy_from_user(&a, arg, sizeof(struct blkpg_ioctl_arg))) return -EFAULT; @@ -535,6 +531,10 @@ static int mtd_blkpg_ioctl(struct mtd_info *mtd, switch (a.op) { case BLKPG_ADD_PARTITION: + /* Only master mtd device must be used to add partitions */ + if (mtd_is_partition(mtd)) + return -EINVAL; + return mtd_add_partition(mtd, p.devname, p.start, p.length); case BLKPG_DEL_PARTITION: diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c index 79e3689f1e16..1047ff0a4f55 100644 --- a/drivers/mtd/mtdpart.c +++ b/drivers/mtd/mtdpart.c @@ -720,19 +720,19 @@ int parse_mtd_partitions(struct mtd_info *master, const char **types, } EXPORT_SYMBOL_GPL(parse_mtd_partitions); -int mtd_is_master(struct mtd_info *mtd) +int mtd_is_partition(struct mtd_info *mtd) { struct mtd_part *part; - int nopart = 0; + int ispart = 0; mutex_lock(&mtd_partitions_mutex); list_for_each_entry(part, &mtd_partitions, list) if (&part->mtd == mtd) { - nopart = 1; + ispart = 1; break; } mutex_unlock(&mtd_partitions_mutex); - return nopart; + return ispart; } -EXPORT_SYMBOL_GPL(mtd_is_master); +EXPORT_SYMBOL_GPL(mtd_is_partition); diff --git a/include/linux/mtd/partitions.h b/include/linux/mtd/partitions.h index 2b54316591d2..4a0a8ba90a72 100644 --- a/include/linux/mtd/partitions.h +++ b/include/linux/mtd/partitions.h @@ -89,7 +89,7 @@ static inline int mtd_has_cmdlinepart(void) { return 1; } static inline int mtd_has_cmdlinepart(void) { return 0; } #endif -int mtd_is_master(struct mtd_info *mtd); +int mtd_is_partition(struct mtd_info *mtd); int mtd_add_partition(struct mtd_info *master, char *name, long long offset, long long length); int mtd_del_partition(struct mtd_info *master, int partno); -- cgit v1.2.3 From eeda667a29698b9a4d16dce8979afc6f512f3c42 Mon Sep 17 00:00:00 2001 From: "Sergej.Stepanov@ids.de" Date: Tue, 23 Nov 2010 18:38:36 +0100 Subject: mtd: fsl_elbc_nand: fix jffs2 problem after NAND-flash image record in u-boot This patch should fix the following problem: 1. the jffs2-image update in the u-boot was ok 2. first restart and first mount of the NAND-flash-partition was also ok 3. before the restart of controller there are no any activity on NAND-flash except of the jffs2_gcd_mtdX-process ... 4. BUT after the second restart the NAND-flash-partition could not be really used after the second mount, dmesg filled with messages: ... jffs2_scan_eraseblock(): Magic bitmask 0x1985 not found at 0x03ce0000: 0xc0ff instead jffs2_scan_eraseblock(): Magic bitmask 0x1985 not found at 0x03d00000: 0xc0ff instead .... Just for for info: the behaviour observed on mpc8313-based board with the large-page NAND. The only activity on NAND-flash was the garbage collector process, that looks for CLEANMARKER-nodes As Scott said it was broken by commit 3ab8f2a2e7011c5e83363b42950757e46ef06824 Signed-off-by: Sergej Stepanov -- Signed-off-by: David Woodhouse --- drivers/mtd/nand/fsl_elbc_nand.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/mtd/nand/fsl_elbc_nand.c b/drivers/mtd/nand/fsl_elbc_nand.c index c141b07b25d1..7a13d42cbabd 100644 --- a/drivers/mtd/nand/fsl_elbc_nand.c +++ b/drivers/mtd/nand/fsl_elbc_nand.c @@ -388,6 +388,8 @@ static void fsl_elbc_cmdfunc(struct mtd_info *mtd, unsigned int command, "page_addr: 0x%x, column: 0x%x.\n", page_addr, column); + elbc_fcm_ctrl->column = column; + elbc_fcm_ctrl->oob = 0; elbc_fcm_ctrl->use_mdr = 1; fcr = (NAND_CMD_STATUS << FCR_CMD1_SHIFT) | -- cgit v1.2.3 From 2ebf0622cdc5d2b51f22b68a0983d90df8a976c8 Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Tue, 23 Nov 2010 17:02:13 -0200 Subject: mtd: mxc_nand: Fix warning on nr_parts unused variable If CONFIG_MTD_PARTITIONS is not selected, then the following warning is generated: CC drivers/mtd/nand/mxc_nand.o drivers/mtd/nand/mxc_nand.c: In function 'mxcnd_probe': drivers/mtd/nand/mxc_nand.c:1014: warning: unused variable 'nr_parts' Fix it by marking nr_parts as __maybe_unused. Signed-off-by: Fabio Estevam Signed-off-by: Artem Bityutskiy Signed-off-by: David Woodhouse --- drivers/mtd/nand/mxc_nand.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mtd/nand/mxc_nand.c b/drivers/mtd/nand/mxc_nand.c index 214b03afdd48..ef932ba55a0b 100644 --- a/drivers/mtd/nand/mxc_nand.c +++ b/drivers/mtd/nand/mxc_nand.c @@ -1009,7 +1009,7 @@ static int __init mxcnd_probe(struct platform_device *pdev) struct mxc_nand_platform_data *pdata = pdev->dev.platform_data; struct mxc_nand_host *host; struct resource *res; - int err = 0, nr_parts = 0; + int err = 0, __maybe_unused nr_parts = 0; struct nand_ecclayout *oob_smallpage, *oob_largepage; /* Allocate memory for MTD device structure and private data */ -- cgit v1.2.3 From 6b2995b62eba81df0f7d0b4be5b782be623c13eb Mon Sep 17 00:00:00 2001 From: Fabio Estevam Date: Fri, 26 Nov 2010 14:31:44 -0200 Subject: mtd: fix section mismatch on sst25l MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Building the kernel with 'make CONFIG_DEBUG_SECTION_MISMATCH=y´ resulted in: WARNING: vmlinux.o(.data+0x15938): Section mismatch in reference from the variable sst25l_driver to the function .init.text:sst25l_probe() The variable sst25l_driver references the function __init sst25l_probe() If the reference is valid then annotate the variable with __init* or __refdata (see linux/init.h) or name the variable: *_template, *_timer, *_sht, *_ops, *_probe, *_probe_one, *_console, Fix the section mismatch. Signed-off-by: Fabio Estevam Signed-off-by: Artem Bityutskiy Signed-off-by: David Woodhouse --- drivers/mtd/devices/sst25l.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/mtd/devices/sst25l.c b/drivers/mtd/devices/sst25l.c index 684247a8a5ed..c163e619abc9 100644 --- a/drivers/mtd/devices/sst25l.c +++ b/drivers/mtd/devices/sst25l.c @@ -335,7 +335,7 @@ out: return ret; } -static struct flash_info *__init sst25l_match_device(struct spi_device *spi) +static struct flash_info *__devinit sst25l_match_device(struct spi_device *spi) { struct flash_info *flash_info = NULL; struct spi_message m; @@ -375,7 +375,7 @@ static struct flash_info *__init sst25l_match_device(struct spi_device *spi) return flash_info; } -static int __init sst25l_probe(struct spi_device *spi) +static int __devinit sst25l_probe(struct spi_device *spi) { struct flash_info *flash_info; struct sst25l_flash *flash; -- cgit v1.2.3 From 4ad916bca7c372110815e77c2db95fb2eb2f8ab3 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Mon, 29 Nov 2010 13:52:06 +0100 Subject: mtd: FSMC NAND remove PARTITION macro and fix compile noise This removes the PARTITION macro that David didn't like and also removes a local variable that was dangling unused in some #ifdefs by being a bit more clever. Signed-off-by: Linus Walleij Signed-off-by: David Woodhouse --- drivers/mtd/nand/fsmc_nand.c | 66 ++++++++++++++++++++++++++++++++------------ 1 file changed, 48 insertions(+), 18 deletions(-) diff --git a/drivers/mtd/nand/fsmc_nand.c b/drivers/mtd/nand/fsmc_nand.c index 02edfba25b0c..5af4b3c122f5 100644 --- a/drivers/mtd/nand/fsmc_nand.c +++ b/drivers/mtd/nand/fsmc_nand.c @@ -119,21 +119,36 @@ static struct fsmc_eccplace fsmc_ecc4_sp_place = { } }; -/* - * Default partition tables to be used if the partition information not - * provided through platform data - */ -#define PARTITION(n, off, sz) {.name = n, .offset = off, .size = sz} +#ifdef CONFIG_MTD_PARTITIONS /* + * Default partition tables to be used if the partition information not + * provided through platform data. + * * Default partition layout for small page(= 512 bytes) devices * Size for "Root file system" is updated in driver based on actual device size */ static struct mtd_partition partition_info_16KB_blk[] = { - PARTITION("X-loader", 0, 4 * 0x4000), - PARTITION("U-Boot", 0x10000, 20 * 0x4000), - PARTITION("Kernel", 0x60000, 256 * 0x4000), - PARTITION("Root File System", 0x460000, 0), + { + .name = "X-loader", + .offset = 0, + .size = 4*0x4000, + }, + { + .name = "U-Boot", + .offset = 0x10000, + .size = 20*0x4000, + }, + { + .name = "Kernel", + .offset = 0x60000, + .size = 256*0x4000, + }, + { + .name = "Root File System", + .offset = 0x460000, + .size = 0, + }, }; /* @@ -141,15 +156,32 @@ static struct mtd_partition partition_info_16KB_blk[] = { * Size for "Root file system" is updated in driver based on actual device size */ static struct mtd_partition partition_info_128KB_blk[] = { - PARTITION("X-loader", 0, 4 * 0x20000), - PARTITION("U-Boot", 0x80000, 12 * 0x20000), - PARTITION("Kernel", 0x200000, 48 * 0x20000), - PARTITION("Root File System", 0x800000, 0), + { + .name = "X-loader", + .offset = 0, + .size = 4*0x20000, + }, + { + .name = "U-Boot", + .offset = 0x80000, + .size = 12*0x20000, + }, + { + .name = "Kernel", + .offset = 0x200000, + .size = 48*0x20000, + }, + { + .name = "Root File System", + .offset = 0x800000, + .size = 0, + }, }; #ifdef CONFIG_MTD_CMDLINE_PARTS const char *part_probes[] = { "cmdlinepart", NULL }; #endif +#endif /** * struct fsmc_nand_data - atructure for FSMC NAND device state @@ -508,7 +540,7 @@ static int __init fsmc_nand_probe(struct platform_device *pdev) struct nand_chip *nand; struct fsmc_regs *regs; struct resource *res; - int nr_parts, ret = 0; + int ret = 0; if (!pdata) { dev_err(&pdev->dev, "platform data is NULL\n"); @@ -676,11 +708,9 @@ static int __init fsmc_nand_probe(struct platform_device *pdev) * Check if partition info passed via command line */ host->mtd.name = "nand"; - nr_parts = parse_mtd_partitions(&host->mtd, part_probes, + host->nr_partitions = parse_mtd_partitions(&host->mtd, part_probes, &host->partitions, 0); - if (nr_parts > 0) { - host->nr_partitions = nr_parts; - } else { + if (host->nr_partitions <= 0) { #endif /* * Check if partition info passed via command line -- cgit v1.2.3 From 593cd8711221c9661dbf9beb2fb42fecca03e693 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Mon, 29 Nov 2010 13:52:19 +0100 Subject: mtd: FSMC NAND use the PrimeCell identifier macros The FSMC actually has a standard ARM PrimeCell ID register, and the "revision" part of that register contains the thing that the code is looking at. Reuse the infrastructure from the AMBA bus abstraction and rid local defines. Signed-off-by: Linus Walleij Signed-off-by: David Woodhouse --- drivers/mtd/nand/fsmc_nand.c | 23 ++++++++++++++++++++--- include/linux/mtd/fsmc.h | 19 ------------------- 2 files changed, 20 insertions(+), 22 deletions(-) diff --git a/drivers/mtd/nand/fsmc_nand.c b/drivers/mtd/nand/fsmc_nand.c index 5af4b3c122f5..205b10b9f9b9 100644 --- a/drivers/mtd/nand/fsmc_nand.c +++ b/drivers/mtd/nand/fsmc_nand.c @@ -31,6 +31,7 @@ #include #include #include +#include #include static struct nand_ecclayout fsmc_ecc1_layout = { @@ -184,8 +185,9 @@ const char *part_probes[] = { "cmdlinepart", NULL }; #endif /** - * struct fsmc_nand_data - atructure for FSMC NAND device state + * struct fsmc_nand_data - structure for FSMC NAND device state * + * @pid: Part ID on the AMBA PrimeCell format * @mtd: MTD info for a NAND flash. * @nand: Chip related info for a NAND flash. * @partitions: Partition info for a NAND Flash. @@ -201,6 +203,7 @@ const char *part_probes[] = { "cmdlinepart", NULL }; * @regs_va: FSMC regs base address. */ struct fsmc_nand_data { + u32 pid; struct mtd_info mtd; struct nand_chip nand; struct mtd_partition *partitions; @@ -541,6 +544,8 @@ static int __init fsmc_nand_probe(struct platform_device *pdev) struct fsmc_regs *regs; struct resource *res; int ret = 0; + u32 pid; + int i; if (!pdata) { dev_err(&pdev->dev, "platform data is NULL\n"); @@ -630,6 +635,18 @@ static int __init fsmc_nand_probe(struct platform_device *pdev) if (ret) goto err_probe1; + /* + * This device ID is actually a common AMBA ID as used on the + * AMBA PrimeCell bus. However it is not a PrimeCell. + */ + for (pid = 0, i = 0; i < 4; i++) + pid |= (readl(host->regs_va + resource_size(res) - 0x20 + 4 * i) & 255) << (i * 8); + host->pid = pid; + dev_info(&pdev->dev, "FSMC device partno %03x, manufacturer %02x, " + "revision %02x, config %02x\n", + AMBA_PART_BITS(pid), AMBA_MANF_BITS(pid), + AMBA_REV_BITS(pid), AMBA_CONFIG_BITS(pid)); + host->bank = pdata->bank; host->select_chip = pdata->select_bank; regs = host->regs_va; @@ -657,7 +674,7 @@ static int __init fsmc_nand_probe(struct platform_device *pdev) fsmc_nand_setup(regs, host->bank, nand->options & NAND_BUSWIDTH_16); - if (get_fsmc_version(host->regs_va) == FSMC_VER8) { + if (AMBA_REV_BITS(host->pid) >= 8) { nand->ecc.read_page = fsmc_read_page_hwecc; nand->ecc.calculate = fsmc_read_hwecc_ecc4; nand->ecc.correct = fsmc_correct_data; @@ -677,7 +694,7 @@ static int __init fsmc_nand_probe(struct platform_device *pdev) goto err_probe; } - if (get_fsmc_version(host->regs_va) == FSMC_VER8) { + if (AMBA_REV_BITS(host->pid) >= 8) { if (host->mtd.writesize == 512) { nand->ecc.layout = &fsmc_ecc4_sp_layout; host->ecc_place = &fsmc_ecc4_sp_place; diff --git a/include/linux/mtd/fsmc.h b/include/linux/mtd/fsmc.h index e210b87e6cd6..96e8e67a053e 100644 --- a/include/linux/mtd/fsmc.h +++ b/include/linux/mtd/fsmc.h @@ -115,25 +115,6 @@ struct fsmc_regs { #define FSMC_THOLD_4 (4 << 16) #define FSMC_THIZ_1 (1 << 24) -/* peripid2 register definitions */ -#define FSMC_REVISION_MSK (0xf) -#define FSMC_REVISION_SHFT (0x4) - -#define FSMC_VER1 1 -#define FSMC_VER2 2 -#define FSMC_VER3 3 -#define FSMC_VER4 4 -#define FSMC_VER5 5 -#define FSMC_VER6 6 -#define FSMC_VER7 7 -#define FSMC_VER8 8 - -static inline uint32_t get_fsmc_version(struct fsmc_regs *regs) -{ - return (readl(®s->peripid2) >> FSMC_REVISION_SHFT) & - FSMC_REVISION_MSK; -} - /* * There are 13 bytes of ecc for every 512 byte block in FSMC version 8 * and it has to be read consecutively and immediately after the 512 -- cgit v1.2.3 From b5602e86432aaf0cc90dd207bf74e3a2bfb5078b Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Mon, 29 Nov 2010 13:52:27 +0100 Subject: mtd: FSMC NAND fix obvious speling errors Fix spelling in the interface file. Signed-off-by: Linus Walleij Signed-off-by: David Woodhouse --- include/linux/mtd/fsmc.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/linux/mtd/fsmc.h b/include/linux/mtd/fsmc.h index 96e8e67a053e..6987995ad3cf 100644 --- a/include/linux/mtd/fsmc.h +++ b/include/linux/mtd/fsmc.h @@ -28,7 +28,7 @@ /* * The placement of the Command Latch Enable (CLE) and - * Address Latch Enable (ALE) is twised around in the + * Address Latch Enable (ALE) is twisted around in the * SPEAR310 implementation. */ #if defined(CONFIG_MACH_SPEAR310) @@ -63,7 +63,7 @@ struct fsmc_nor_bank_regs { /* ctrl_tim register definitions */ -struct fsms_nand_bank_regs { +struct fsmc_nand_bank_regs { uint32_t pc; uint32_t sts; uint32_t comm; @@ -79,7 +79,7 @@ struct fsms_nand_bank_regs { struct fsmc_regs { struct fsmc_nor_bank_regs nor_bank_regs[FSMC_MAX_NOR_BANKS]; uint8_t reserved_1[0x40 - 0x20]; - struct fsms_nand_bank_regs bank_regs[FSMC_MAX_NAND_BANKS]; + struct fsmc_nand_bank_regs bank_regs[FSMC_MAX_NAND_BANKS]; uint8_t reserved_2[0xfe0 - 0xc0]; uint32_t peripid0; /* 0xfe0 */ uint32_t peripid1; /* 0xfe4 */ -- cgit v1.2.3 From 8a8f632d8534d0c403831341450bd8db9e842f05 Mon Sep 17 00:00:00 2001 From: Kyungmin Park Date: Thu, 2 Dec 2010 09:24:16 +0900 Subject: mtd: OneNAND: Fix 4KiB pagesize OOB handling Original 4KiB pagesize chip (SLC) doesn't support OOB operations at Spec. And it's also same at Flex-OneNAND. Remove the MLC macro if possible and use 4KiB pagesize macro since MLC has 4KiB pagesize. Signed-off-by: Kyungmin Park Signed-off-by: David Woodhouse --- drivers/mtd/onenand/onenand_base.c | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c index 4d6e6c54cc2c..c38bf9c54a11 100644 --- a/drivers/mtd/onenand/onenand_base.c +++ b/drivers/mtd/onenand/onenand_base.c @@ -400,8 +400,7 @@ static int onenand_command(struct mtd_info *mtd, int cmd, loff_t addr, size_t le value = onenand_bufferram_address(this, block); this->write_word(value, this->base + ONENAND_REG_START_ADDRESS2); - if (ONENAND_IS_MLC(this) || ONENAND_IS_2PLANE(this) || - ONENAND_IS_4KB_PAGE(this)) + if (ONENAND_IS_2PLANE(this) || ONENAND_IS_4KB_PAGE(this)) /* It is always BufferRAM0 */ ONENAND_SET_BUFFERRAM0(this); else @@ -430,7 +429,7 @@ static int onenand_command(struct mtd_info *mtd, int cmd, loff_t addr, size_t le case FLEXONENAND_CMD_RECOVER_LSB: case ONENAND_CMD_READ: case ONENAND_CMD_READOOB: - if (ONENAND_IS_MLC(this) || ONENAND_IS_4KB_PAGE(this)) + if (ONENAND_IS_4KB_PAGE(this)) /* It is always BufferRAM0 */ dataram = ONENAND_SET_BUFFERRAM0(this); else @@ -1353,7 +1352,7 @@ static int onenand_read_oob_nolock(struct mtd_info *mtd, loff_t from, stats = mtd->ecc_stats; - readcmd = ONENAND_IS_MLC(this) ? ONENAND_CMD_READ : ONENAND_CMD_READOOB; + readcmd = ONENAND_IS_4KB_PAGE(this) ? ONENAND_CMD_READ : ONENAND_CMD_READOOB; while (read < len) { cond_resched(); @@ -1429,7 +1428,7 @@ static int onenand_read(struct mtd_info *mtd, loff_t from, size_t len, int ret; onenand_get_device(mtd, FL_READING); - ret = ONENAND_IS_MLC(this) || ONENAND_IS_4KB_PAGE(this) ? + ret = ONENAND_IS_4KB_PAGE(this) ? onenand_mlc_read_ops_nolock(mtd, from, &ops) : onenand_read_ops_nolock(mtd, from, &ops); onenand_release_device(mtd); @@ -1464,7 +1463,7 @@ static int onenand_read_oob(struct mtd_info *mtd, loff_t from, onenand_get_device(mtd, FL_READING); if (ops->datbuf) - ret = ONENAND_IS_MLC(this) || ONENAND_IS_4KB_PAGE(this) ? + ret = ONENAND_IS_4KB_PAGE(this) ? onenand_mlc_read_ops_nolock(mtd, from, ops) : onenand_read_ops_nolock(mtd, from, ops); else @@ -1558,7 +1557,7 @@ int onenand_bbt_read_oob(struct mtd_info *mtd, loff_t from, column = from & (mtd->oobsize - 1); - readcmd = ONENAND_IS_MLC(this) ? ONENAND_CMD_READ : ONENAND_CMD_READOOB; + readcmd = ONENAND_IS_4KB_PAGE(this) ? ONENAND_CMD_READ : ONENAND_CMD_READOOB; while (read < len) { cond_resched(); @@ -1612,7 +1611,7 @@ static int onenand_verify_oob(struct mtd_info *mtd, const u_char *buf, loff_t to u_char *oob_buf = this->oob_buf; int status, i, readcmd; - readcmd = ONENAND_IS_MLC(this) ? ONENAND_CMD_READ : ONENAND_CMD_READOOB; + readcmd = ONENAND_IS_4KB_PAGE(this) ? ONENAND_CMD_READ : ONENAND_CMD_READOOB; this->command(mtd, readcmd, to, mtd->oobsize); onenand_update_bufferram(mtd, to, 0); @@ -2079,7 +2078,7 @@ static int onenand_write_oob_nolock(struct mtd_info *mtd, loff_t to, oobbuf = this->oob_buf; - oobcmd = ONENAND_IS_MLC(this) ? ONENAND_CMD_PROG : ONENAND_CMD_PROGOOB; + oobcmd = ONENAND_IS_4KB_PAGE(this) ? ONENAND_CMD_PROG : ONENAND_CMD_PROGOOB; /* Loop until all data write */ while (written < len) { @@ -2098,7 +2097,7 @@ static int onenand_write_oob_nolock(struct mtd_info *mtd, loff_t to, memcpy(oobbuf + column, buf, thislen); this->write_bufferram(mtd, ONENAND_SPARERAM, oobbuf, 0, mtd->oobsize); - if (ONENAND_IS_MLC(this) || ONENAND_IS_4KB_PAGE(this)) { + if (ONENAND_IS_4KB_PAGE(this)) { /* Set main area of DataRAM to 0xff*/ memset(this->page_buf, 0xff, mtd->writesize); this->write_bufferram(mtd, ONENAND_DATARAM, @@ -3041,7 +3040,7 @@ static int do_otp_read(struct mtd_info *mtd, loff_t from, size_t len, this->command(mtd, ONENAND_CMD_OTP_ACCESS, 0, 0); this->wait(mtd, FL_OTPING); - ret = ONENAND_IS_MLC(this) || ONENAND_IS_4KB_PAGE(this) ? + ret = ONENAND_IS_4KB_PAGE(this) ? onenand_mlc_read_ops_nolock(mtd, from, &ops) : onenand_read_ops_nolock(mtd, from, &ops); @@ -3413,7 +3412,11 @@ static void onenand_check_features(struct mtd_info *mtd) break; } - if (ONENAND_IS_MLC(this) || ONENAND_IS_4KB_PAGE(this)) + /* The MLC has 4KiB pagesize. */ + if (ONENAND_IS_MLC(this)) + this->options |= ONENAND_HAS_4KB_PAGE; + + if (ONENAND_IS_4KB_PAGE(this)) this->options &= ~ONENAND_HAS_2PLANE; if (FLEXONENAND(this)) { @@ -3847,7 +3850,7 @@ static int onenand_probe(struct mtd_info *mtd) /* The data buffer size is equal to page size */ mtd->writesize = this->read_word(this->base + ONENAND_REG_DATA_BUFFER_SIZE); /* We use the full BufferRAM */ - if (ONENAND_IS_MLC(this) || ONENAND_IS_4KB_PAGE(this)) + if (ONENAND_IS_4KB_PAGE(this)) mtd->writesize <<= 1; mtd->oobsize = mtd->writesize >> 5; -- cgit v1.2.3 From 23bbce34f47762ce944ea9b8b3b3e05e220c6a2e Mon Sep 17 00:00:00 2001 From: Dimitris Papastamos Date: Thu, 2 Dec 2010 14:53:01 +0000 Subject: ASoC: Add compress_type as a member to snd_soc_codec We need to keep a copy of the compress_type supplied by the codec driver so that we can override it if necessary with whatever the machine driver has provided us with. The reason for not modifying the codec->driver struct directly is that ideally we'd like to keep it const. Adjust the code in soc-cache and soc-core to make use of the compress_type member in the snd_soc_codec struct. Signed-off-by: Dimitris Papastamos Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- include/sound/soc.h | 1 + sound/soc/soc-cache.c | 4 ++-- sound/soc/soc-core.c | 5 +++++ 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/include/sound/soc.h b/include/sound/soc.h index 714a70441bf2..586bfb99fedb 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -460,6 +460,7 @@ struct snd_soc_codec { struct list_head list; struct list_head card_list; int num_dai; + enum snd_soc_compress_type compress_type; /* runtime */ struct snd_ac97 *ac97; /* for ad-hoc ac97 devices */ diff --git a/sound/soc/soc-cache.c b/sound/soc/soc-cache.c index 78b25e8c03f6..cb58b11d4f47 100644 --- a/sound/soc/soc-cache.c +++ b/sound/soc/soc-cache.c @@ -1550,11 +1550,11 @@ int snd_soc_cache_init(struct snd_soc_codec *codec) int i; for (i = 0; i < ARRAY_SIZE(cache_types); ++i) - if (cache_types[i].id == codec->driver->compress_type) + if (cache_types[i].id == codec->compress_type) break; if (i == ARRAY_SIZE(cache_types)) { dev_err(codec->dev, "Could not match compress type: %d\n", - codec->driver->compress_type); + codec->compress_type); return -EINVAL; } diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 2b1fcae4131e..1fd1d1a62af1 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -3450,6 +3450,11 @@ int snd_soc_register_codec(struct device *dev, return -ENOMEM; } + if (codec_drv->compress_type) + codec->compress_type = codec_drv->compress_type; + else + codec->compress_type = SND_SOC_FLAT_COMPRESSION; + INIT_LIST_HEAD(&codec->dapm.widgets); INIT_LIST_HEAD(&codec->dapm.paths); codec->write = codec_drv->write; -- cgit v1.2.3 From 01039e4e63a8ea0d66fcfc71d7b99769bbbed9d6 Mon Sep 17 00:00:00 2001 From: Roman Tereshonkov Date: Thu, 2 Dec 2010 15:28:38 +0200 Subject: mtd: onenand: bugfix for 2x mode bad block handling This bug becomes visible in 2x mode when chip->writesize is different from mtd->writesize (= 2 * chip->writesize). At this case the bad block information is read from the first and the third physical pages instead of the first and the second as specification states. Signed-off-by: Roman Tereshonkov Acked-by: Kyungmin Park Signed-off-by: David Woodhouse --- drivers/mtd/onenand/onenand_bbt.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/mtd/onenand/onenand_bbt.c b/drivers/mtd/onenand/onenand_bbt.c index 01ab5b3c453b..905209bf9465 100644 --- a/drivers/mtd/onenand/onenand_bbt.c +++ b/drivers/mtd/onenand/onenand_bbt.c @@ -91,13 +91,15 @@ static int create_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr for (j = 0; j < len; j++) { /* No need to read pages fully, * just read required OOB bytes */ - ret = onenand_bbt_read_oob(mtd, from + j * mtd->writesize + bd->offs, &ops); + ret = onenand_bbt_read_oob(mtd, + from + j * this->writesize + bd->offs, &ops); /* If it is a initial bad block, just ignore it */ if (ret == ONENAND_BBT_READ_FATAL_ERROR) return -EIO; - if (ret || check_short_pattern(&buf[j * scanlen], scanlen, mtd->writesize, bd)) { + if (ret || check_short_pattern(&buf[j * scanlen], + scanlen, this->writesize, bd)) { bbm->bbt[i >> 3] |= 0x03 << (i & 0x6); printk(KERN_WARNING "Bad eraseblock %d at 0x%08x\n", i >> 1, (unsigned int) from); -- cgit v1.2.3 From 119bd789f6405b8bf351b58561d08d8fc4e2d10b Mon Sep 17 00:00:00 2001 From: Dimitris Papastamos Date: Thu, 2 Dec 2010 14:53:02 +0000 Subject: ASoC: Change the base value of compress_type Ensure that the base value of compress_type starts at 1 so that we know whether the machine driver has provided a compress_type for overriding the codec supplied one. Signed-off-by: Dimitris Papastamos Acked-by: Liam Girdwood 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 586bfb99fedb..24db9101c87d 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -256,7 +256,7 @@ enum snd_soc_control_type { }; enum snd_soc_compress_type { - SND_SOC_FLAT_COMPRESSION, + SND_SOC_FLAT_COMPRESSION = 1, SND_SOC_LZO_COMPRESSION, SND_SOC_RBTREE_COMPRESSION }; -- cgit v1.2.3 From ff819b8357df0ca9903ff7c9ad518b949c410123 Mon Sep 17 00:00:00 2001 From: Dimitris Papastamos Date: Thu, 2 Dec 2010 14:53:03 +0000 Subject: ASoC: soc-core: Generalize snd_soc_prefix_map and rename to snd_soc_codec_conf The snd_soc_codec_conf struct now holds codec specific configuration information. A new configuration option has been added to allow machine drivers to override the compression type set by the codec driver. In the absence of providing an snd_soc_codec_conf struct or when providing one but not setting the compress_type member to anything, the one supplied by the codec driver will be used instead. In all other cases the one set in the snd_soc_codec_conf struct takes effect. Signed-off-by: Dimitris Papastamos Acked-by: Jarkko Nikula Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- include/sound/soc.h | 22 +++++++++++++++------- sound/soc/soc-core.c | 6 +++--- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/include/sound/soc.h b/include/sound/soc.h index 24db9101c87d..cf76021f04a7 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -581,9 +581,20 @@ struct snd_soc_dai_link { struct snd_soc_ops *ops; }; -struct snd_soc_prefix_map { +struct snd_soc_codec_conf { const char *dev_name; + + /* + * optional map of kcontrol, widget and path name prefixes that are + * associated per device + */ const char *name_prefix; + + /* + * set this to the desired compression type if you want to + * override the one supplied in codec->driver->compress_type + */ + enum snd_soc_compress_type compress_type; }; struct snd_soc_aux_dev { @@ -628,12 +639,9 @@ struct snd_soc_card { struct snd_soc_pcm_runtime *rtd; int num_rtd; - /* - * optional map of kcontrol, widget and path name prefixes that are - * associated per device - */ - struct snd_soc_prefix_map *prefix_map; - int num_prefixes; + /* optional codec specific configuration */ + struct snd_soc_codec_conf *codec_conf; + int num_configs; /* * optional auxiliary devices such as amplifiers or codecs with DAI diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 1fd1d1a62af1..4649db6163b8 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -1401,11 +1401,11 @@ static void soc_set_name_prefix(struct snd_soc_card *card, { int i; - if (card->prefix_map == NULL) + if (card->codec_conf == NULL) return; - for (i = 0; i < card->num_prefixes; i++) { - struct snd_soc_prefix_map *map = &card->prefix_map[i]; + for (i = 0; i < card->num_configs; i++) { + struct snd_soc_codec_conf *map = &card->codec_conf[i]; if (map->dev_name && !strcmp(codec->name, map->dev_name)) { codec->name_prefix = map->name_prefix; break; -- cgit v1.2.3 From 4ccb3b4497ce01fab4933704fe21581e30fda1a5 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Fri, 3 Dec 2010 16:36:34 +0000 Subject: mtd: nand: Fix integer overflow in ONFI detection of chips >= 4GiB Signed-off-by: David Woodhouse --- drivers/mtd/nand/nand_base.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c index 75d199e4f25b..33550c43acc2 100644 --- a/drivers/mtd/nand/nand_base.c +++ b/drivers/mtd/nand/nand_base.c @@ -2894,7 +2894,7 @@ static int nand_flash_detect_onfi(struct mtd_info *mtd, struct nand_chip *chip, mtd->writesize = le32_to_cpu(p->byte_per_page); mtd->erasesize = le32_to_cpu(p->pages_per_block) * mtd->writesize; mtd->oobsize = le16_to_cpu(p->spare_bytes_per_page); - chip->chipsize = le32_to_cpu(p->blocks_per_lun) * mtd->erasesize; + chip->chipsize = (uint64_t)le32_to_cpu(p->blocks_per_lun) * mtd->erasesize; busw = 0; if (le16_to_cpu(p->features) & 1) busw = NAND_BUSWIDTH_16; -- cgit v1.2.3 From 3335ddca9367675f4ee0bd50cc70402c4919a10d Mon Sep 17 00:00:00 2001 From: Dimitris Papastamos Date: Thu, 2 Dec 2010 16:11:05 +0000 Subject: ASoC: soc-cache: Use reg_def_copy instead of reg_cache_default Make sure to use codec->reg_def_copy instead of codec_drv->reg_cache_default wherever necessary. This change is necessary because in the next patch we move the cache initialization code outside snd_soc_register_codec() and by that time any data marked as __devinitconst such as the original reg_cache_default array might have already been freed by the kernel. Signed-off-by: Dimitris Papastamos Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- include/sound/soc.h | 1 + sound/soc/soc-cache.c | 36 ++++++++++++++++++++++++------------ sound/soc/soc-core.c | 17 +++++++++++++++++ 3 files changed, 42 insertions(+), 12 deletions(-) diff --git a/include/sound/soc.h b/include/sound/soc.h index cf76021f04a7..017986159d5e 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -480,6 +480,7 @@ struct snd_soc_codec { unsigned int (*read)(struct snd_soc_codec *, unsigned int); int (*write)(struct snd_soc_codec *, unsigned int, unsigned int); void *reg_cache; + const void *reg_def_copy; const struct snd_soc_cache_ops *cache_ops; struct mutex cache_rw_mutex; diff --git a/sound/soc/soc-cache.c b/sound/soc/soc-cache.c index cb58b11d4f47..6c6ced7a3819 100644 --- a/sound/soc/soc-cache.c +++ b/sound/soc/soc-cache.c @@ -933,7 +933,7 @@ static int snd_soc_rbtree_cache_init(struct snd_soc_codec *codec) rbtree_ctx = codec->reg_cache; rbtree_ctx->root = RB_ROOT; - if (!codec->driver->reg_cache_default) + if (!codec->reg_def_copy) return 0; /* @@ -951,7 +951,7 @@ static int snd_soc_rbtree_cache_init(struct snd_soc_codec *codec) struct snd_soc_rbtree_node *rbtree_node; \ \ ret = 0; \ - cache = codec->driver->reg_cache_default; \ + cache = codec->reg_def_copy; \ for (i = 0; i < codec->driver->reg_cache_size; ++i) { \ if (!cache[i]) \ continue; \ @@ -1316,13 +1316,13 @@ static int snd_soc_lzo_cache_init(struct snd_soc_codec *codec) * and remember to free it afterwards. */ tofree = 0; - if (!codec_drv->reg_cache_default) + if (!codec->reg_def_copy) tofree = 1; - if (!codec_drv->reg_cache_default) { - codec_drv->reg_cache_default = kzalloc(reg_size, + if (!codec->reg_def_copy) { + codec->reg_def_copy = kzalloc(reg_size, GFP_KERNEL); - if (!codec_drv->reg_cache_default) + if (!codec->reg_def_copy) return -ENOMEM; } @@ -1368,8 +1368,8 @@ static int snd_soc_lzo_cache_init(struct snd_soc_codec *codec) } blksize = snd_soc_lzo_get_blksize(codec); - p = codec_drv->reg_cache_default; - end = codec_drv->reg_cache_default + reg_size; + p = codec->reg_def_copy; + end = codec->reg_def_copy + reg_size; /* compress the register map and fill the lzo blocks */ for (i = 0; i < blkcount; ++i, p += blksize) { lzo_blocks[i]->src = p; @@ -1385,14 +1385,18 @@ static int snd_soc_lzo_cache_init(struct snd_soc_codec *codec) lzo_blocks[i]->src_len; } - if (tofree) - kfree(codec_drv->reg_cache_default); + if (tofree) { + kfree(codec->reg_def_copy); + codec->reg_def_copy = NULL; + } return 0; err: snd_soc_cache_exit(codec); err_tofree: - if (tofree) - kfree(codec_drv->reg_cache_default); + if (tofree) { + kfree(codec->reg_def_copy); + codec->reg_def_copy = NULL; + } return ret; } @@ -1506,6 +1510,14 @@ static int snd_soc_flat_cache_init(struct snd_soc_codec *codec) codec_drv = codec->driver; reg_size = codec_drv->reg_cache_size * codec_drv->reg_word_size; + /* + * for flat compression, we don't need to keep a copy of the + * original defaults register cache as it will definitely not + * be marked as __devinitconst + */ + kfree(codec->reg_def_copy); + codec->reg_def_copy = NULL; + if (codec_drv->reg_cache_default) codec->reg_cache = kmemdup(codec_drv->reg_cache_default, reg_size, GFP_KERNEL); diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 4649db6163b8..a95d111a6531 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -3434,6 +3434,7 @@ int snd_soc_register_codec(struct device *dev, struct snd_soc_codec_driver *codec_drv, struct snd_soc_dai_driver *dai_drv, int num_dai) { + size_t reg_size; struct snd_soc_codec *codec; int ret, i; @@ -3469,6 +3470,19 @@ int snd_soc_register_codec(struct device *dev, /* allocate CODEC register cache */ if (codec_drv->reg_cache_size && codec_drv->reg_word_size) { + reg_size = codec_drv->reg_cache_size * codec_drv->reg_word_size; + /* it is necessary to make a copy of the default register cache + * because in the case of using a compression type that requires + * the default register cache to be marked as __devinitconst the + * kernel might have freed the array by the time we initialize + * the cache. + */ + codec->reg_def_copy = kmemdup(codec_drv->reg_cache_default, + reg_size, GFP_KERNEL); + if (!codec->reg_def_copy) { + ret = -ENOMEM; + goto error_cache; + } ret = snd_soc_cache_init(codec); if (ret < 0) { dev_err(codec->dev, "Failed to set cache compression type: %d\n", @@ -3500,6 +3514,8 @@ int snd_soc_register_codec(struct device *dev, error_dais: snd_soc_cache_exit(codec); error_cache: + kfree(codec->reg_def_copy); + codec->reg_def_copy = NULL; kfree(codec->name); kfree(codec); return ret; @@ -3534,6 +3550,7 @@ found: pr_debug("Unregistered codec '%s'\n", codec->name); snd_soc_cache_exit(codec); + kfree(codec->reg_def_copy); kfree(codec->name); kfree(codec); } -- cgit v1.2.3 From fdf0f54dab8e401fd9bdd441c3fc4fa5c8837646 Mon Sep 17 00:00:00 2001 From: Dimitris Papastamos Date: Thu, 2 Dec 2010 16:11:06 +0000 Subject: ASoC: soc-core: Allow machine drivers to override compress_type This patch allows machine drivers to override the compression type provided by the codec driver. Signed-off-by: Dimitris Papastamos Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- include/sound/soc.h | 1 + sound/soc/soc-core.c | 74 ++++++++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 64 insertions(+), 11 deletions(-) diff --git a/include/sound/soc.h b/include/sound/soc.h index 017986159d5e..7d53cc453637 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -472,6 +472,7 @@ struct snd_soc_codec { unsigned int ac97_registered:1; /* Codec has been AC97 registered */ unsigned int ac97_created:1; /* Codec has been created by SoC */ unsigned int sysfs_registered:1; /* codec has been sysfs registered */ + unsigned int cache_init:1; /* codec cache has been initialized */ /* codec IO */ void *control_data; /* codec control (i2c/3wire) data */ diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index a95d111a6531..e9aa9ce59c06 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -1730,9 +1730,36 @@ static void soc_remove_aux_dev(struct snd_soc_card *card, int num) } } +static int snd_soc_init_codec_cache(struct snd_soc_codec *codec, + enum snd_soc_compress_type compress_type) +{ + int ret; + + if (codec->cache_init) + return 0; + + /* override the compress_type if necessary */ + if (compress_type && codec->compress_type != compress_type) + codec->compress_type = compress_type; + dev_dbg(codec->dev, "Cache compress_type for %s is %d\n", + codec->name, codec->compress_type); + ret = snd_soc_cache_init(codec); + if (ret < 0) { + dev_err(codec->dev, "Failed to set cache compression type: %d\n", + ret); + return ret; + } + codec->cache_init = 1; + return 0; +} + + static void snd_soc_instantiate_card(struct snd_soc_card *card) { struct platform_device *pdev = to_platform_device(card->dev); + struct snd_soc_codec *codec; + struct snd_soc_codec_conf *codec_conf; + enum snd_soc_compress_type compress_type; int ret, i; mutex_lock(&card->mutex); @@ -1752,6 +1779,39 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card) return; } + /* initialize the register cache for each available codec */ + list_for_each_entry(codec, &codec_list, list) { + if (codec->cache_init) + continue; + /* check to see if we need to override the compress_type */ + for (i = 0; i < card->num_configs; ++i) { + codec_conf = &card->codec_conf[i]; + if (!strcmp(codec->name, codec_conf->dev_name)) { + compress_type = codec_conf->compress_type; + if (compress_type && compress_type + != codec->compress_type) + break; + } + } + if (i == card->num_configs) { + /* no need to override the compress_type so + * go ahead and do the standard thing */ + ret = snd_soc_init_codec_cache(codec, 0); + if (ret < 0) { + mutex_unlock(&card->mutex); + return; + } + continue; + } + /* override the compress_type with the one supplied in + * the machine driver */ + ret = snd_soc_init_codec_cache(codec, compress_type); + if (ret < 0) { + mutex_unlock(&card->mutex); + return; + } + } + /* card bind complete so register a sound card */ ret = snd_card_create(SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1, card->owner, 0, &card->snd_card); @@ -3481,13 +3541,7 @@ int snd_soc_register_codec(struct device *dev, reg_size, GFP_KERNEL); if (!codec->reg_def_copy) { ret = -ENOMEM; - goto error_cache; - } - ret = snd_soc_cache_init(codec); - if (ret < 0) { - dev_err(codec->dev, "Failed to set cache compression type: %d\n", - ret); - goto error_cache; + goto fail; } } @@ -3500,7 +3554,7 @@ int snd_soc_register_codec(struct device *dev, if (num_dai) { ret = snd_soc_register_dais(dev, dai_drv, num_dai); if (ret < 0) - goto error_dais; + goto fail; } mutex_lock(&client_mutex); @@ -3511,9 +3565,7 @@ int snd_soc_register_codec(struct device *dev, pr_debug("Registered codec '%s'\n", codec->name); return 0; -error_dais: - snd_soc_cache_exit(codec); -error_cache: +fail: kfree(codec->reg_def_copy); codec->reg_def_copy = NULL; kfree(codec->name); -- cgit v1.2.3 From 001ae4c0350a35e8358514326e5c3d165357979a Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 2 Dec 2010 16:21:08 +0000 Subject: ASoC: Constify struct snd_soc_codec_driver Allow the CODEC driver structure to be marked const by making all the APIs that use it do so. Signed-off-by: Mark Brown Acked-by: Liam Girdwood --- include/sound/soc.h | 4 ++-- sound/soc/soc-cache.c | 12 ++++++------ sound/soc/soc-core.c | 5 +++-- 3 files changed, 11 insertions(+), 10 deletions(-) diff --git a/include/sound/soc.h b/include/sound/soc.h index 7d53cc453637..0eea08e1bdd5 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -265,7 +265,7 @@ int snd_soc_register_platform(struct device *dev, struct snd_soc_platform_driver *platform_drv); void snd_soc_unregister_platform(struct device *dev); int snd_soc_register_codec(struct device *dev, - struct snd_soc_codec_driver *codec_drv, + const struct snd_soc_codec_driver *codec_drv, struct snd_soc_dai_driver *dai_drv, int num_dai); void snd_soc_unregister_codec(struct device *dev); int snd_soc_codec_volatile_register(struct snd_soc_codec *codec, int reg); @@ -453,7 +453,7 @@ struct snd_soc_codec { const char *name_prefix; int id; struct device *dev; - struct snd_soc_codec_driver *driver; + const struct snd_soc_codec_driver *driver; struct mutex mutex; struct snd_soc_card *card; diff --git a/sound/soc/soc-cache.c b/sound/soc/soc-cache.c index 6c6ced7a3819..ff2bc8beddaa 100644 --- a/sound/soc/soc-cache.c +++ b/sound/soc/soc-cache.c @@ -1078,7 +1078,7 @@ static int snd_soc_lzo_decompress_cache_block(struct snd_soc_codec *codec, static inline int snd_soc_lzo_get_blkindex(struct snd_soc_codec *codec, unsigned int reg) { - struct snd_soc_codec_driver *codec_drv; + const struct snd_soc_codec_driver *codec_drv; size_t reg_size; codec_drv = codec->driver; @@ -1090,7 +1090,7 @@ static inline int snd_soc_lzo_get_blkindex(struct snd_soc_codec *codec, static inline int snd_soc_lzo_get_blkpos(struct snd_soc_codec *codec, unsigned int reg) { - struct snd_soc_codec_driver *codec_drv; + const struct snd_soc_codec_driver *codec_drv; size_t reg_size; codec_drv = codec->driver; @@ -1101,7 +1101,7 @@ static inline int snd_soc_lzo_get_blkpos(struct snd_soc_codec *codec, static inline int snd_soc_lzo_get_blksize(struct snd_soc_codec *codec) { - struct snd_soc_codec_driver *codec_drv; + const struct snd_soc_codec_driver *codec_drv; size_t reg_size; codec_drv = codec->driver; @@ -1301,7 +1301,7 @@ static int snd_soc_lzo_cache_init(struct snd_soc_codec *codec) { struct snd_soc_lzo_ctx **lzo_blocks; size_t reg_size, bmp_size; - struct snd_soc_codec_driver *codec_drv; + const struct snd_soc_codec_driver *codec_drv; int ret, tofree, i, blksize, blkcount; const char *p, *end; unsigned long *sync_bmp; @@ -1404,7 +1404,7 @@ static int snd_soc_flat_cache_sync(struct snd_soc_codec *codec) { int i; int ret; - struct snd_soc_codec_driver *codec_drv; + const struct snd_soc_codec_driver *codec_drv; unsigned int val; codec_drv = codec->driver; @@ -1504,7 +1504,7 @@ static int snd_soc_flat_cache_exit(struct snd_soc_codec *codec) static int snd_soc_flat_cache_init(struct snd_soc_codec *codec) { - struct snd_soc_codec_driver *codec_drv; + const struct snd_soc_codec_driver *codec_drv; size_t reg_size; codec_drv = codec->driver; diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index e9aa9ce59c06..78a01014079a 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -3491,8 +3491,9 @@ static void fixup_codec_formats(struct snd_soc_pcm_stream *stream) * @codec: codec to register */ int snd_soc_register_codec(struct device *dev, - struct snd_soc_codec_driver *codec_drv, - struct snd_soc_dai_driver *dai_drv, int num_dai) + const struct snd_soc_codec_driver *codec_drv, + struct snd_soc_dai_driver *dai_drv, + int num_dai) { size_t reg_size; struct snd_soc_codec *codec; -- cgit v1.2.3 From 062869382bb2821bb8482db1e67850dfd11296fb Mon Sep 17 00:00:00 2001 From: Jassi Brar Date: Fri, 3 Dec 2010 10:34:25 +0900 Subject: ASoC: WM8580: Debug interface index We want the index of DAI's driver here. Signed-off-by: Jassi Brar Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/codecs/wm8580.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sound/soc/codecs/wm8580.c b/sound/soc/codecs/wm8580.c index e2a927684b48..cb7765f7687d 100644 --- a/sound/soc/codecs/wm8580.c +++ b/sound/soc/codecs/wm8580.c @@ -507,13 +507,13 @@ static int wm8580_paif_hw_params(struct snd_pcm_substream *substream, } /* Look up the SYSCLK ratio; accept only exact matches */ - ratio = wm8580->sysclk[dai->id] / params_rate(params); + ratio = wm8580->sysclk[dai->driver->id] / params_rate(params); for (i = 0; i < ARRAY_SIZE(wm8580_sysclk_ratios); i++) if (ratio == wm8580_sysclk_ratios[i]) break; if (i == ARRAY_SIZE(wm8580_sysclk_ratios)) { dev_err(codec->dev, "Invalid clock ratio %d/%d\n", - wm8580->sysclk[dai->id], params_rate(params)); + wm8580->sysclk[dai->driver->id], params_rate(params)); return -EINVAL; } paifa |= i; @@ -716,7 +716,7 @@ static int wm8580_set_sysclk(struct snd_soc_dai *dai, int clk_id, switch (clk_id) { case WM8580_CLKSRC_ADCMCLK: - if (dai->id != WM8580_DAI_PAIFTX) + if (dai->driver->id != WM8580_DAI_PAIFTX) return -EINVAL; sel = 0 << sel_shift; break; @@ -735,7 +735,7 @@ static int wm8580_set_sysclk(struct snd_soc_dai *dai, int clk_id, } /* We really should validate PLL settings but not yet */ - wm8580->sysclk[dai->id] = freq; + wm8580->sysclk[dai->driver->id] = freq; return snd_soc_update_bits(codec, WM8580_CLKSEL, sel_mask, sel); } -- cgit v1.2.3 From 4514e8997fbefd5befd6176ac9785e287b4daed4 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 3 Dec 2010 16:02:10 +0000 Subject: ASoC: When disabling WM8994 FLL force a source selection When we disable the WM8994 FLL code path sharing means that we end up writing out a configuration. Currently this is the currently active input and output frequency (which causes snd_soc_update_bits() to suppress actual writes both immediately and in the common case where we reenable the same configuration later) but we allow machine drivers to pass through a source of zero. Since the register values written are one less than the source constants this causes corruption of other bitfields in the register. Fix this by using the most recently configured FLL source when none is provided. Signed-off-by: Mark Brown Acked-by: Liam Girdwood Cc: stable@kernel.org --- sound/soc/codecs/wm8994.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index af3a98ae0579..b37e95c4e7c7 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c @@ -1677,6 +1677,7 @@ static int _wm8994_set_fll(struct snd_soc_codec *codec, int id, int src, /* Allow no source specification when stopping */ if (freq_out) return -EINVAL; + src = wm8994->fll[id].src; break; case WM8994_FLL_SRC_MCLK1: case WM8994_FLL_SRC_MCLK2: -- cgit v1.2.3 From 1daa38d379932bde0d2036c2e10ced3e8842b74f Mon Sep 17 00:00:00 2001 From: "Emilio G. Cota" Date: Fri, 3 Dec 2010 09:05:08 +0000 Subject: staging/vme_user: fix usage of the slave resources after they've been freed buf_unalloc() frees the memory buffers allocated with vme_alloc_consistent. The associated VME resource is needed in both vme_alloc_consistent and vme_free_consistent; however the slave VME resources are being freed before the calls to vme_free_consistent are made, which means the buffers are never returned. Fix this by freeing the VME resources only after the consistent buffers have been returned. Signed-off-by: Emilio G. Cota Acked-by: Martyn Welch Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vme/devices/vme_user.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/vme/devices/vme_user.c b/drivers/staging/vme/devices/vme_user.c index 36381489b797..dc7175bdfcf9 100644 --- a/drivers/staging/vme/devices/vme_user.c +++ b/drivers/staging/vme/devices/vme_user.c @@ -829,8 +829,8 @@ err_master: err_slave: while (i > SLAVE_MINOR) { i--; - vme_slave_free(image[i].resource); buf_unalloc(i); + vme_slave_free(image[i].resource); } err_class: cdev_del(vme_user_cdev); @@ -855,8 +855,8 @@ static int __exit vme_user_remove(struct device *dev, int cur_bus, int cur_slot) for (i = SLAVE_MINOR; i < (SLAVE_MAX + 1); i++) { vme_slave_set(image[i].resource, 0, 0, 0, 0, VME_A32, 0); - vme_slave_free(image[i].resource); buf_unalloc(i); + vme_slave_free(image[i].resource); } /* Unregister device driver */ -- cgit v1.2.3 From 4740a0846069f6d4cbba9e328a9d92e6dd76110d Mon Sep 17 00:00:00 2001 From: "Emilio G. Cota" Date: Fri, 3 Dec 2010 13:44:15 +0000 Subject: staging/vme/vme_user: use __dev{init, exit} for .probe and .remove Signed-off-by: Emilio G. Cota [martyn.welch@ge.com: Fixed checkpatch line length warnings] Signed-off-by: Martyn Welch Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vme/devices/vme_user.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/drivers/staging/vme/devices/vme_user.c b/drivers/staging/vme/devices/vme_user.c index dc7175bdfcf9..db445ed164c6 100644 --- a/drivers/staging/vme/devices/vme_user.c +++ b/drivers/staging/vme/devices/vme_user.c @@ -135,8 +135,8 @@ static ssize_t vme_user_write(struct file *, const char __user *, size_t, static loff_t vme_user_llseek(struct file *, loff_t, int); static long vme_user_unlocked_ioctl(struct file *, unsigned int, unsigned long); -static int __init vme_user_probe(struct device *, int, int); -static int __exit vme_user_remove(struct device *, int, int); +static int __devinit vme_user_probe(struct device *, int, int); +static int __devexit vme_user_remove(struct device *, int, int); static struct file_operations vme_user_fops = { .open = vme_user_open, @@ -596,7 +596,7 @@ static void buf_unalloc(int num) static struct vme_driver vme_user_driver = { .name = driver_name, .probe = vme_user_probe, - .remove = vme_user_remove, + .remove = __devexit_p(vme_user_remove), }; @@ -666,7 +666,8 @@ err_nocard: * as practical. We will therefore reserve the buffers and request the images * here so that we don't have to do it later. */ -static int __init vme_user_probe(struct device *dev, int cur_bus, int cur_slot) +static int __devinit vme_user_probe(struct device *dev, int cur_bus, + int cur_slot) { int i, err; char name[12]; @@ -841,7 +842,8 @@ err_dev: return err; } -static int __exit vme_user_remove(struct device *dev, int cur_bus, int cur_slot) +static int __devexit vme_user_remove(struct device *dev, int cur_bus, + int cur_slot) { int i; -- cgit v1.2.3 From b62c99b17c2c513eaf6b77a76907a13a1beb86d3 Mon Sep 17 00:00:00 2001 From: "Emilio G. Cota" Date: Fri, 3 Dec 2010 14:20:51 +0000 Subject: staging/vme_user: add missing calls to vme_master_free calls in .remove Signed-off-by: Emilio G. Cota Acked-by: Martyn Welch Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vme/devices/vme_user.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/staging/vme/devices/vme_user.c b/drivers/staging/vme/devices/vme_user.c index db445ed164c6..a571173249cf 100644 --- a/drivers/staging/vme/devices/vme_user.c +++ b/drivers/staging/vme/devices/vme_user.c @@ -852,8 +852,10 @@ static int __devexit vme_user_remove(struct device *dev, int cur_bus, device_destroy(vme_user_sysfs_class, MKDEV(VME_MAJOR, i)); class_destroy(vme_user_sysfs_class); - for (i = MASTER_MINOR; i < (MASTER_MAX + 1); i++) + for (i = MASTER_MINOR; i < (MASTER_MAX + 1); i++) { kfree(image[i].kern_buf); + vme_master_free(image[i].resource); + } for (i = SLAVE_MINOR; i < (SLAVE_MAX + 1); i++) { vme_slave_set(image[i].resource, 0, 0, 0, 0, VME_A32, 0); -- cgit v1.2.3 From 3d44661ad1f6336345a9f7765afef6d0aeac543e Mon Sep 17 00:00:00 2001 From: Roland Vossen Date: Wed, 1 Dec 2010 21:38:31 +0100 Subject: staging: brcm80211: added firmware validation Fix for https://bugzilla.kernel.org/show_bug.cgi?id=21872 New function wl_check_firmwares() checks validity of all firmware images loaded from user space. Signed-off-by: Roland Vossen Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/sys/wl_mac80211.c | 54 ++++++++++++++++++++++++- drivers/staging/brcm80211/sys/wl_ucode.h | 4 ++ drivers/staging/brcm80211/sys/wl_ucode_loader.c | 4 ++ 3 files changed, 60 insertions(+), 2 deletions(-) diff --git a/drivers/staging/brcm80211/sys/wl_mac80211.c b/drivers/staging/brcm80211/sys/wl_mac80211.c index 364b34986621..d41212bca633 100644 --- a/drivers/staging/brcm80211/sys/wl_mac80211.c +++ b/drivers/staging/brcm80211/sys/wl_mac80211.c @@ -1776,8 +1776,7 @@ static int wl_request_fw(struct wl_info *wl, struct pci_dev *pdev) wl->fw.hdr_num_entries[i])); } wl->fw.fw_cnt = i; - wl_ucode_data_init(wl); - return 0; + return wl_ucode_data_init(wl); } void wl_ucode_free_buf(void *p) @@ -1793,3 +1792,54 @@ static void wl_release_fw(struct wl_info *wl) release_firmware(wl->fw.fw_hdr[i]); } } + + +/* + * checks validity of all firmware images loaded from user space + */ +int wl_check_firmwares(struct wl_info *wl) +{ + int i; + int entry; + int rc = 0; + const struct firmware *fw; + const struct firmware *fw_hdr; + struct wl_fw_hdr *ucode_hdr; + for (i = 0; i < WL_MAX_FW && rc == 0; i++) { + fw = wl->fw.fw_bin[i]; + fw_hdr = wl->fw.fw_hdr[i]; + if (fw == NULL && fw_hdr == NULL) { + break; + } else if (fw == NULL || fw_hdr == NULL) { + WL_ERROR(("%s: invalid bin/hdr fw\n", __func__)); + rc = -EBADF; + } else if (fw_hdr->size % sizeof(struct wl_fw_hdr)) { + WL_ERROR(("%s: non integral fw hdr file size %d/%d\n", + __func__, fw_hdr->size, + sizeof(struct wl_fw_hdr))); + rc = -EBADF; + } else if (fw->size < MIN_FW_SIZE || fw->size > MAX_FW_SIZE) { + WL_ERROR(("%s: out of bounds fw file size %d\n", + __func__, fw->size)); + rc = -EBADF; + } else { + /* check if ucode section overruns firmware image */ + ucode_hdr = (struct wl_fw_hdr *)fw_hdr->data; + for (entry = 0; entry < wl->fw.hdr_num_entries[i] && rc; + entry++, ucode_hdr++) { + if (ucode_hdr->offset + ucode_hdr->len > + fw->size) { + WL_ERROR(("%s: conflicting bin/hdr\n", + __func__)); + rc = -EBADF; + } + } + } + } + if (rc == 0 && wl->fw.fw_cnt != i) { + WL_ERROR(("%s: invalid fw_cnt=%d\n", __func__, wl->fw.fw_cnt)); + rc = -EBADF; + } + return rc; +} + diff --git a/drivers/staging/brcm80211/sys/wl_ucode.h b/drivers/staging/brcm80211/sys/wl_ucode.h index b797ab661195..2a0f4028f6f3 100644 --- a/drivers/staging/brcm80211/sys/wl_ucode.h +++ b/drivers/staging/brcm80211/sys/wl_ucode.h @@ -14,6 +14,9 @@ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ +#define MIN_FW_SIZE 40000 /* minimum firmware file size in bytes */ +#define MAX_FW_SIZE 150000 + typedef struct d11init { u16 addr; u16 size; @@ -43,3 +46,4 @@ extern int wl_ucode_init_buf(struct wl_info *wl, void **pbuf, unsigned int idx); extern int wl_ucode_init_uint(struct wl_info *wl, unsigned *data, unsigned int idx); extern void wl_ucode_free_buf(void *); +extern int wl_check_firmwares(struct wl_info *wl); diff --git a/drivers/staging/brcm80211/sys/wl_ucode_loader.c b/drivers/staging/brcm80211/sys/wl_ucode_loader.c index acd24726b0f0..23e10f3dec0d 100644 --- a/drivers/staging/brcm80211/sys/wl_ucode_loader.c +++ b/drivers/staging/brcm80211/sys/wl_ucode_loader.c @@ -39,6 +39,10 @@ u32 *bcm43xx_bomminor; int wl_ucode_data_init(struct wl_info *wl) { + int rc; + rc = wl_check_firmwares(wl); + if (rc < 0) + return rc; wl_ucode_init_buf(wl, (void **)&d11lcn0bsinitvals24, D11LCN0BSINITVALS24); wl_ucode_init_buf(wl, (void **)&d11lcn0initvals24, D11LCN0INITVALS24); -- cgit v1.2.3 From e2c8e425baa01a4c8e6ae1b90194ed3d3cde0c66 Mon Sep 17 00:00:00 2001 From: Li Yang Date: Thu, 11 Nov 2010 20:16:29 +0800 Subject: fsldma: add support to 36-bit physical address Expand the dma_mask of fsldma device to 36-bit, indicating that the DMA engine can deal with 36-bit physical address and does not need the SWIOTLB to create bounce buffer for it when doing dma_map_*(). Signed-off-by: Li Yang Acked-by: Kumar Gala Signed-off-by: Dan Williams --- drivers/dma/fsldma.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/dma/fsldma.c b/drivers/dma/fsldma.c index 286c3ac6bdcc..531230b87976 100644 --- a/drivers/dma/fsldma.c +++ b/drivers/dma/fsldma.c @@ -1,7 +1,7 @@ /* * Freescale MPC85xx, MPC83xx DMA Engine support * - * Copyright (C) 2007 Freescale Semiconductor, Inc. All rights reserved. + * Copyright (C) 2007-2010 Freescale Semiconductor, Inc. All rights reserved. * * Author: * Zhang Wei , Jul 2007 @@ -1322,6 +1322,8 @@ static int __devinit fsldma_of_probe(struct platform_device *op, fdev->common.device_control = fsl_dma_device_control; fdev->common.dev = &op->dev; + dma_set_mask(&(op->dev), DMA_BIT_MASK(36)); + dev_set_drvdata(&op->dev, fdev); /* -- cgit v1.2.3 From 8165984acf825917437debae519209073c32a5a7 Mon Sep 17 00:00:00 2001 From: Tero Roponen Date: Wed, 1 Dec 2010 20:04:20 +0200 Subject: slub: Fix a crash during slabinfo -v Commit f7cb1933621bce66a77f690776a16fe3ebbc4d58 ("SLUB: Pass active and inactive redzone flags instead of boolean to debug functions") missed two instances of check_object(). This caused a lot of warnings during 'slabinfo -v' finally leading to a crash: BUG ext4_xattr: Freepointer corrupt ... BUG buffer_head: Freepointer corrupt ... BUG ext4_alloc_context: Freepointer corrupt ... ... BUG: unable to handle kernel NULL pointer dereference at 0000000000000008 IP: [] file_sb_list_del+0x1c/0x35 PGD 79d78067 PUD 79e67067 PMD 0 Oops: 0002 [#1] SMP last sysfs file: /sys/kernel/slab/:t-0000192/validate This patch fixes the problem by converting the two missed instances. Acked-by: Christoph Lameter Signed-off-by: Tero Roponen Signed-off-by: Pekka Enberg --- mm/slub.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mm/slub.c b/mm/slub.c index 7796a0446b3f..48d82a55f4b6 100644 --- a/mm/slub.c +++ b/mm/slub.c @@ -3417,13 +3417,13 @@ static int validate_slab(struct kmem_cache *s, struct page *page, for_each_free_object(p, s, page->freelist) { set_bit(slab_index(p, s, addr), map); - if (!check_object(s, page, p, 0)) + if (!check_object(s, page, p, SLUB_RED_INACTIVE)) return 0; } for_each_object(p, s, addr, page->objects) if (!test_bit(slab_index(p, s, addr), map)) - if (!check_object(s, page, p, 1)) + if (!check_object(s, page, p, SLUB_RED_ACTIVE)) return 0; return 1; } -- cgit v1.2.3 From 0be035f3485379d812d617ee7eaa255cde97dbfa Mon Sep 17 00:00:00 2001 From: Feng Tang Date: Thu, 2 Dec 2010 17:14:30 +0800 Subject: intel_mid_dma: add support for single item scatter-gather list Current driver's device_prep_slave_sg can't be used by DMAC2 even the sg list contains one item, this patch will enable DMAC2 to use this API. Signed-off-by: Feng Tang Acked-by: Vinod Koul Signed-off-by: Dan Williams --- drivers/dma/intel_mid_dma.c | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/drivers/dma/intel_mid_dma.c b/drivers/dma/intel_mid_dma.c index 41941d05bfb9..0c0feb8834d0 100644 --- a/drivers/dma/intel_mid_dma.c +++ b/drivers/dma/intel_mid_dma.c @@ -664,11 +664,20 @@ static struct dma_async_tx_descriptor *intel_mid_dma_prep_memcpy( /*calculate CTL_LO*/ ctl_lo.ctl_lo = 0; ctl_lo.ctlx.int_en = 1; - ctl_lo.ctlx.dst_tr_width = mids->dma_slave.dst_addr_width; - ctl_lo.ctlx.src_tr_width = mids->dma_slave.src_addr_width; ctl_lo.ctlx.dst_msize = mids->dma_slave.src_maxburst; ctl_lo.ctlx.src_msize = mids->dma_slave.dst_maxburst; + /* + * Here we need some translation from "enum dma_slave_buswidth" + * to the format for our dma controller + * standard intel_mid_dmac's format + * 1 Byte 0b000 + * 2 Bytes 0b001 + * 4 Bytes 0b010 + */ + ctl_lo.ctlx.dst_tr_width = mids->dma_slave.dst_addr_width / 2; + ctl_lo.ctlx.src_tr_width = mids->dma_slave.src_addr_width / 2; + if (mids->cfg_mode == LNW_DMA_MEM_TO_MEM) { ctl_lo.ctlx.tt_fc = 0; ctl_lo.ctlx.sinc = 0; @@ -746,8 +755,18 @@ static struct dma_async_tx_descriptor *intel_mid_dma_prep_slave_sg( BUG_ON(!mids); if (!midc->dma->pimr_mask) { - pr_debug("MDMA: SG list is not supported by this controller\n"); - return NULL; + /* We can still handle sg list with only one item */ + if (sg_len == 1) { + txd = intel_mid_dma_prep_memcpy(chan, + mids->dma_slave.dst_addr, + mids->dma_slave.src_addr, + sgl->length, + flags); + return txd; + } else { + pr_warn("MDMA: SG list is not supported by this controller\n"); + return NULL; + } } pr_debug("MDMA: SG Length = %d, direction = %d, Flags = %#lx\n", @@ -758,6 +777,7 @@ static struct dma_async_tx_descriptor *intel_mid_dma_prep_slave_sg( pr_err("MDMA: Prep memcpy failed\n"); return NULL; } + desc = to_intel_mid_dma_desc(txd); desc->dirn = direction; ctl_lo.ctl_lo = desc->ctl_lo; -- cgit v1.2.3 From 17fe6981109e995f36723e4880a97d48fa38920a Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 3 Dec 2010 20:17:19 +0000 Subject: drm/i915/lvds: Connect the PWM to the LVDS pipe ... and do not just assume to always use pipe B. Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/intel_lvds.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index 23247b235e68..d07055c4d84f 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c @@ -1012,10 +1012,18 @@ bool intel_lvds_init(struct drm_device *dev) out: if (HAS_PCH_SPLIT(dev)) { u32 pwm; - /* make sure PWM is enabled */ + + pipe = (I915_READ(PCH_LVDS) & LVDS_PIPEB_SELECT) ? 1 : 0; + + /* make sure PWM is enabled and locked to the LVDS pipe */ pwm = I915_READ(BLC_PWM_CPU_CTL2); - pwm |= (PWM_ENABLE | PWM_PIPE_B); - I915_WRITE(BLC_PWM_CPU_CTL2, pwm); + if (pipe == 0 && (pwm & PWM_PIPE_B)) + I915_WRITE(BLC_PWM_CPU_CTL2, pwm & ~PWM_ENABLE); + if (pipe) + pwm |= PWM_PIPE_B; + else + pwm &= ~PWM_PIPE_B; + I915_WRITE(BLC_PWM_CPU_CTL2, pwm | PWM_ENABLE); pwm = I915_READ(BLC_PWM_PCH_CTL1); pwm |= PWM_PCH_ENABLE; -- cgit v1.2.3 From a589b9f429ac0e5bcdebda0f74ee313d39d69b7f Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 3 Dec 2010 21:13:16 +0000 Subject: drm/i915: Explain why we need to write DPLL twice ... it's because setting the Pixel Multiply bits only takes effect once the PLL is enabled and stable. Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/intel_display.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index f7962b741c94..e3b8d0dc7a7d 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -4089,13 +4089,13 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, } I915_WRITE(DPLL_MD(pipe), temp); } else { - /* write it again -- the BIOS does, after all */ + /* The pixel multiplier can only be updated once the + * DPLL is enabled and the clocks are stable. + * + * So write it again. + */ I915_WRITE(dpll_reg, dpll); } - - /* Wait for the clocks to stabilize. */ - POSTING_READ(dpll_reg); - udelay(150); } intel_crtc->lowfreq_avail = false; -- cgit v1.2.3 From c1858123dba4a9e40355363ac7a153ea23a5315d Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 3 Dec 2010 21:35:48 +0000 Subject: drm/i915: Enable CB tuning of the Display PLL Magic numbers from the specs. This is supposed to allow the PLL some variance to improve jitter performance and VCO headroom across manufacturing and environmental variations. Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_reg.h | 1 + drivers/gpu/drm/i915/intel_display.c | 17 ++++++++++++++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 998457063d5e..06175e98c5bb 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -2712,6 +2712,7 @@ #define PCH_DPLL(pipe) _PIPE(pipe, PCH_DPLL_A, PCH_DPLL_B) #define PCH_FPA0 0xc6040 +#define FP_CB_TUNE (0x3<<22) #define PCH_FPA1 0xc6044 #define PCH_FPB0 0xc6048 #define PCH_FPB1 0xc604c diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index e3b8d0dc7a7d..f2aa76bd72c0 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -3857,6 +3857,22 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, reduced_clock.m2; } + /* Enable autotuning of the PLL clock (if permissible) */ + if (HAS_PCH_SPLIT(dev)) { + int factor = 21; + + if (is_lvds) { + if ((dev_priv->lvds_use_ssc && + dev_priv->lvds_ssc_freq == 100) || + (I915_READ(PCH_LVDS) & LVDS_CLKB_POWER_MASK) == LVDS_CLKB_POWER_UP) + factor = 25; + } else if (is_sdvo && is_tv) + factor = 20; + + if (clock.m1 < factor * clock.n) + fp |= FP_CB_TUNE; + } + dpll = 0; if (!HAS_PCH_SPLIT(dev)) dpll = DPLL_VGA_MODE_DIS; @@ -4071,7 +4087,6 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, } if (!has_edp_encoder || intel_encoder_is_pch_edp(&has_edp_encoder->base)) { - I915_WRITE(fp_reg, fp); I915_WRITE(dpll_reg, dpll); /* Wait for the clocks to stabilize. */ -- cgit v1.2.3 From f684f5b48cd27a031928c137531aace728d765a6 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sat, 4 Dec 2010 17:22:41 +0000 Subject: drm/i915: Re-enable RC6 for power-savings. Let's see if we've successfully cleared up all the bugs from last time... Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/intel_display.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index f2aa76bd72c0..3063edd2456f 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -5864,7 +5864,6 @@ void intel_init_clock_gating(struct drm_device *dev) _3D_CHICKEN2_WM_READ_PIPELINED << 16 | _3D_CHICKEN2_WM_READ_PIPELINED); } - return; } else if (IS_G4X(dev)) { uint32_t dspclk_gate; I915_WRITE(RENCLK_GATE_D1, 0); -- cgit v1.2.3 From 4add75c43f39573edc884d46b7c2b7414f01171a Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sat, 4 Dec 2010 17:49:46 +0000 Subject: drm/i915: Allow LVDS to be on pipe A for Ironlake+ Previously we enabled this for gen4, only to have to revert it due to it causing a large number of spurious wakeups. Try again hoping that the hardware has become more sane in the mean time... Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/intel_lvds.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index d07055c4d84f..6d1106eafcfd 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c @@ -907,6 +907,8 @@ bool intel_lvds_init(struct drm_device *dev) intel_encoder->clone_mask = (1 << INTEL_LVDS_CLONE_BIT); intel_encoder->crtc_mask = (1 << 1); + if (INTEL_INFO(dev)->gen >= 5) + intel_encoder->crtc_mask |= (1 << 0); drm_encoder_helper_add(encoder, &intel_lvds_helper_funcs); drm_connector_helper_add(connector, &intel_lvds_connector_helper_funcs); connector->display_info.subpixel_order = SubPixelHorizontalRGB; -- cgit v1.2.3 From 340479aac697bc73e225c122a9753d4964eeda3f Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sat, 4 Dec 2010 18:17:15 +0000 Subject: drm/i915: Be paranoid and bail on resetting if we can't take the lock. This will declare the machine wedged, but is better than truly wedging the machine. Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_drv.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 1a15b7886b8c..64844e2e9f86 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -440,7 +440,8 @@ int i915_reset(struct drm_device *dev, u8 flags) bool need_display = true; int ret; - mutex_lock(&dev->struct_mutex); + if (!mutex_trylock(&dev->struct_mutex)) + return -EBUSY; i915_gem_reset(dev); -- cgit v1.2.3 From 1ec14ad3132702694f2e1a90b30641cf111183b9 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sat, 4 Dec 2010 11:30:53 +0000 Subject: drm/i915: Implement GPU semaphores for inter-ring synchronisation on SNB The bulk of the change is to convert the growing list of rings into an array so that the relationship between the rings and the semaphore sync registers can be easily computed. Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_debugfs.c | 75 +++--- drivers/gpu/drm/i915/i915_dma.c | 60 +++-- drivers/gpu/drm/i915/i915_drv.c | 6 +- drivers/gpu/drm/i915/i915_drv.h | 48 ++-- drivers/gpu/drm/i915/i915_gem.c | 86 +++--- drivers/gpu/drm/i915/i915_gem_execbuffer.c | 94 +++++-- drivers/gpu/drm/i915/i915_irq.c | 209 ++++++++------- drivers/gpu/drm/i915/i915_reg.h | 19 +- drivers/gpu/drm/i915/intel_display.c | 4 +- drivers/gpu/drm/i915/intel_opregion.c | 8 +- drivers/gpu/drm/i915/intel_overlay.c | 8 +- drivers/gpu/drm/i915/intel_ringbuffer.c | 415 ++++++++++++++++++----------- drivers/gpu/drm/i915/intel_ringbuffer.h | 41 ++- drivers/gpu/drm/i915/intel_tv.c | 14 +- 14 files changed, 648 insertions(+), 439 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 3c9d4b876865..aedb02157474 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -339,10 +339,10 @@ static int i915_gem_request_info(struct seq_file *m, void *data) return ret; count = 0; - if (!list_empty(&dev_priv->render_ring.request_list)) { + if (!list_empty(&dev_priv->ring[RCS].request_list)) { seq_printf(m, "Render requests:\n"); list_for_each_entry(gem_request, - &dev_priv->render_ring.request_list, + &dev_priv->ring[RCS].request_list, list) { seq_printf(m, " %d @ %d\n", gem_request->seqno, @@ -350,10 +350,10 @@ static int i915_gem_request_info(struct seq_file *m, void *data) } count++; } - if (!list_empty(&dev_priv->bsd_ring.request_list)) { + if (!list_empty(&dev_priv->ring[VCS].request_list)) { seq_printf(m, "BSD requests:\n"); list_for_each_entry(gem_request, - &dev_priv->bsd_ring.request_list, + &dev_priv->ring[VCS].request_list, list) { seq_printf(m, " %d @ %d\n", gem_request->seqno, @@ -361,10 +361,10 @@ static int i915_gem_request_info(struct seq_file *m, void *data) } count++; } - if (!list_empty(&dev_priv->blt_ring.request_list)) { + if (!list_empty(&dev_priv->ring[BCS].request_list)) { seq_printf(m, "BLT requests:\n"); list_for_each_entry(gem_request, - &dev_priv->blt_ring.request_list, + &dev_priv->ring[BCS].request_list, list) { seq_printf(m, " %d @ %d\n", gem_request->seqno, @@ -398,15 +398,14 @@ static int i915_gem_seqno_info(struct seq_file *m, void *data) struct drm_info_node *node = (struct drm_info_node *) m->private; struct drm_device *dev = node->minor->dev; drm_i915_private_t *dev_priv = dev->dev_private; - int ret; + int ret, i; ret = mutex_lock_interruptible(&dev->struct_mutex); if (ret) return ret; - i915_ring_seqno_info(m, &dev_priv->render_ring); - i915_ring_seqno_info(m, &dev_priv->bsd_ring); - i915_ring_seqno_info(m, &dev_priv->blt_ring); + for (i = 0; i < I915_NUM_RINGS; i++) + i915_ring_seqno_info(m, &dev_priv->ring[i]); mutex_unlock(&dev->struct_mutex); @@ -419,7 +418,7 @@ static int i915_interrupt_info(struct seq_file *m, void *data) struct drm_info_node *node = (struct drm_info_node *) m->private; struct drm_device *dev = node->minor->dev; drm_i915_private_t *dev_priv = dev->dev_private; - int ret; + int ret, i; ret = mutex_lock_interruptible(&dev->struct_mutex); if (ret) @@ -458,9 +457,8 @@ static int i915_interrupt_info(struct seq_file *m, void *data) } seq_printf(m, "Interrupts received: %d\n", atomic_read(&dev_priv->irq_received)); - i915_ring_seqno_info(m, &dev_priv->render_ring); - i915_ring_seqno_info(m, &dev_priv->bsd_ring); - i915_ring_seqno_info(m, &dev_priv->blt_ring); + for (i = 0; i < I915_NUM_RINGS; i++) + i915_ring_seqno_info(m, &dev_priv->ring[i]); mutex_unlock(&dev->struct_mutex); return 0; @@ -503,13 +501,7 @@ static int i915_hws_info(struct seq_file *m, void *data) volatile u32 *hws; int i; - switch ((uintptr_t)node->info_ent->data) { - case RING_RENDER: ring = &dev_priv->render_ring; break; - case RING_BSD: ring = &dev_priv->bsd_ring; break; - case RING_BLT: ring = &dev_priv->blt_ring; break; - default: return -EINVAL; - } - + ring = &dev_priv->ring[(uintptr_t)node->info_ent->data]; hws = (volatile u32 *)ring->status_page.page_addr; if (hws == NULL) return 0; @@ -569,17 +561,11 @@ static int i915_ringbuffer_data(struct seq_file *m, void *data) struct intel_ring_buffer *ring; int ret; - switch ((uintptr_t)node->info_ent->data) { - case RING_RENDER: ring = &dev_priv->render_ring; break; - case RING_BSD: ring = &dev_priv->bsd_ring; break; - case RING_BLT: ring = &dev_priv->blt_ring; break; - default: return -EINVAL; - } - ret = mutex_lock_interruptible(&dev->struct_mutex); if (ret) return ret; + ring = &dev_priv->ring[(uintptr_t)node->info_ent->data]; if (!ring->obj) { seq_printf(m, "No ringbuffer setup\n"); } else { @@ -603,21 +589,20 @@ static int i915_ringbuffer_info(struct seq_file *m, void *data) drm_i915_private_t *dev_priv = dev->dev_private; struct intel_ring_buffer *ring; - switch ((uintptr_t)node->info_ent->data) { - case RING_RENDER: ring = &dev_priv->render_ring; break; - case RING_BSD: ring = &dev_priv->bsd_ring; break; - case RING_BLT: ring = &dev_priv->blt_ring; break; - default: return -EINVAL; - } - + ring = &dev_priv->ring[(uintptr_t)node->info_ent->data]; if (ring->size == 0) - return 0; + return 0; seq_printf(m, "Ring %s:\n", ring->name); seq_printf(m, " Head : %08x\n", I915_READ_HEAD(ring) & HEAD_ADDR); seq_printf(m, " Tail : %08x\n", I915_READ_TAIL(ring) & TAIL_ADDR); seq_printf(m, " Size : %08x\n", ring->size); seq_printf(m, " Active : %08x\n", intel_ring_get_active_head(ring)); + seq_printf(m, " NOPID : %08x\n", I915_READ_NOPID(ring)); + if (IS_GEN6(dev)) { + seq_printf(m, " Sync 0 : %08x\n", I915_READ_SYNC_0(ring)); + seq_printf(m, " Sync 1 : %08x\n", I915_READ_SYNC_1(ring)); + } seq_printf(m, " Control : %08x\n", I915_READ_CTL(ring)); seq_printf(m, " Start : %08x\n", I915_READ_START(ring)); @@ -1177,15 +1162,15 @@ static struct drm_info_list i915_debugfs_list[] = { {"i915_gem_seqno", i915_gem_seqno_info, 0}, {"i915_gem_fence_regs", i915_gem_fence_regs_info, 0}, {"i915_gem_interrupt", i915_interrupt_info, 0}, - {"i915_gem_hws", i915_hws_info, 0, (void *)RING_RENDER}, - {"i915_gem_hws_blt", i915_hws_info, 0, (void *)RING_BLT}, - {"i915_gem_hws_bsd", i915_hws_info, 0, (void *)RING_BSD}, - {"i915_ringbuffer_data", i915_ringbuffer_data, 0, (void *)RING_RENDER}, - {"i915_ringbuffer_info", i915_ringbuffer_info, 0, (void *)RING_RENDER}, - {"i915_bsd_ringbuffer_data", i915_ringbuffer_data, 0, (void *)RING_BSD}, - {"i915_bsd_ringbuffer_info", i915_ringbuffer_info, 0, (void *)RING_BSD}, - {"i915_blt_ringbuffer_data", i915_ringbuffer_data, 0, (void *)RING_BLT}, - {"i915_blt_ringbuffer_info", i915_ringbuffer_info, 0, (void *)RING_BLT}, + {"i915_gem_hws", i915_hws_info, 0, (void *)RCS}, + {"i915_gem_hws_blt", i915_hws_info, 0, (void *)BCS}, + {"i915_gem_hws_bsd", i915_hws_info, 0, (void *)VCS}, + {"i915_ringbuffer_data", i915_ringbuffer_data, 0, (void *)RCS}, + {"i915_ringbuffer_info", i915_ringbuffer_info, 0, (void *)RCS}, + {"i915_bsd_ringbuffer_data", i915_ringbuffer_data, 0, (void *)VCS}, + {"i915_bsd_ringbuffer_info", i915_ringbuffer_info, 0, (void *)VCS}, + {"i915_blt_ringbuffer_data", i915_ringbuffer_data, 0, (void *)BCS}, + {"i915_blt_ringbuffer_info", i915_ringbuffer_info, 0, (void *)BCS}, {"i915_batchbuffers", i915_batchbuffer_info, 0}, {"i915_error_state", i915_error_state, 0}, {"i915_rstdby_delays", i915_rstdby_delays, 0}, diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 9a22da9b2083..664300986fb4 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -49,6 +49,8 @@ static int i915_init_phys_hws(struct drm_device *dev) { drm_i915_private_t *dev_priv = dev->dev_private; + struct intel_ring_buffer *ring = LP_RING(dev_priv); + /* Program Hardware Status Page */ dev_priv->status_page_dmah = drm_pci_alloc(dev, PAGE_SIZE, PAGE_SIZE); @@ -57,11 +59,10 @@ static int i915_init_phys_hws(struct drm_device *dev) DRM_ERROR("Can not allocate hardware status page\n"); return -ENOMEM; } - dev_priv->render_ring.status_page.page_addr - = dev_priv->status_page_dmah->vaddr; + ring->status_page.page_addr = dev_priv->status_page_dmah->vaddr; dev_priv->dma_status_page = dev_priv->status_page_dmah->busaddr; - memset(dev_priv->render_ring.status_page.page_addr, 0, PAGE_SIZE); + memset(ring->status_page.page_addr, 0, PAGE_SIZE); if (INTEL_INFO(dev)->gen >= 4) dev_priv->dma_status_page |= (dev_priv->dma_status_page >> 28) & @@ -79,13 +80,15 @@ static int i915_init_phys_hws(struct drm_device *dev) static void i915_free_hws(struct drm_device *dev) { drm_i915_private_t *dev_priv = dev->dev_private; + struct intel_ring_buffer *ring = LP_RING(dev_priv); + if (dev_priv->status_page_dmah) { drm_pci_free(dev, dev_priv->status_page_dmah); dev_priv->status_page_dmah = NULL; } - if (dev_priv->render_ring.status_page.gfx_addr) { - dev_priv->render_ring.status_page.gfx_addr = 0; + if (ring->status_page.gfx_addr) { + ring->status_page.gfx_addr = 0; drm_core_ioremapfree(&dev_priv->hws_map, dev); } @@ -97,7 +100,7 @@ void i915_kernel_lost_context(struct drm_device * dev) { drm_i915_private_t *dev_priv = dev->dev_private; struct drm_i915_master_private *master_priv; - struct intel_ring_buffer *ring = &dev_priv->render_ring; + struct intel_ring_buffer *ring = LP_RING(dev_priv); /* * We should never lose context on the ring with modesetting @@ -123,6 +126,8 @@ void i915_kernel_lost_context(struct drm_device * dev) static int i915_dma_cleanup(struct drm_device * dev) { drm_i915_private_t *dev_priv = dev->dev_private; + int i; + /* Make sure interrupts are disabled here because the uninstall ioctl * may not have been called from userspace and after dev_private * is freed, it's too late. @@ -131,9 +136,8 @@ static int i915_dma_cleanup(struct drm_device * dev) drm_irq_uninstall(dev); mutex_lock(&dev->struct_mutex); - intel_cleanup_ring_buffer(&dev_priv->render_ring); - intel_cleanup_ring_buffer(&dev_priv->bsd_ring); - intel_cleanup_ring_buffer(&dev_priv->blt_ring); + for (i = 0; i < I915_NUM_RINGS; i++) + intel_cleanup_ring_buffer(&dev_priv->ring[i]); mutex_unlock(&dev->struct_mutex); /* Clear the HWS virtual address at teardown */ @@ -147,6 +151,7 @@ static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init) { drm_i915_private_t *dev_priv = dev->dev_private; struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv; + struct intel_ring_buffer *ring = LP_RING(dev_priv); master_priv->sarea = drm_getsarea(dev); if (master_priv->sarea) { @@ -157,24 +162,24 @@ static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init) } if (init->ring_size != 0) { - if (dev_priv->render_ring.obj != NULL) { + if (ring->obj != NULL) { i915_dma_cleanup(dev); DRM_ERROR("Client tried to initialize ringbuffer in " "GEM mode\n"); return -EINVAL; } - dev_priv->render_ring.size = init->ring_size; + ring->size = init->ring_size; - dev_priv->render_ring.map.offset = init->ring_start; - dev_priv->render_ring.map.size = init->ring_size; - dev_priv->render_ring.map.type = 0; - dev_priv->render_ring.map.flags = 0; - dev_priv->render_ring.map.mtrr = 0; + ring->map.offset = init->ring_start; + ring->map.size = init->ring_size; + ring->map.type = 0; + ring->map.flags = 0; + ring->map.mtrr = 0; - drm_core_ioremap_wc(&dev_priv->render_ring.map, dev); + drm_core_ioremap_wc(&ring->map, dev); - if (dev_priv->render_ring.map.handle == NULL) { + if (ring->map.handle == NULL) { i915_dma_cleanup(dev); DRM_ERROR("can not ioremap virtual address for" " ring buffer\n"); @@ -182,7 +187,7 @@ static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init) } } - dev_priv->render_ring.virtual_start = dev_priv->render_ring.map.handle; + ring->virtual_start = ring->map.handle; dev_priv->cpp = init->cpp; dev_priv->back_offset = init->back_offset; @@ -201,12 +206,10 @@ static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init) static int i915_dma_resume(struct drm_device * dev) { drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; + struct intel_ring_buffer *ring = LP_RING(dev_priv); - struct intel_ring_buffer *ring; DRM_DEBUG_DRIVER("%s\n", __func__); - ring = &dev_priv->render_ring; - if (ring->map.handle == NULL) { DRM_ERROR("can not ioremap virtual address for" " ring buffer\n"); @@ -326,7 +329,7 @@ static int i915_emit_cmds(struct drm_device * dev, int *buffer, int dwords) drm_i915_private_t *dev_priv = dev->dev_private; int i, ret; - if ((dwords+1) * sizeof(int) >= dev_priv->render_ring.size - 8) + if ((dwords+1) * sizeof(int) >= LP_RING(dev_priv)->size - 8) return -EINVAL; for (i = 0; i < dwords;) { @@ -565,13 +568,12 @@ static int i915_dispatch_flip(struct drm_device * dev) return 0; } -static int i915_quiescent(struct drm_device * dev) +static int i915_quiescent(struct drm_device *dev) { - drm_i915_private_t *dev_priv = dev->dev_private; + struct intel_ring_buffer *ring = LP_RING(dev->dev_private); i915_kernel_lost_context(dev); - return intel_wait_ring_buffer(&dev_priv->render_ring, - dev_priv->render_ring.size - 8); + return intel_wait_ring_buffer(ring, ring->size - 8); } static int i915_flush_ioctl(struct drm_device *dev, void *data, @@ -828,7 +830,7 @@ static int i915_set_status_page(struct drm_device *dev, void *data, { drm_i915_private_t *dev_priv = dev->dev_private; drm_i915_hws_addr_t *hws = data; - struct intel_ring_buffer *ring = &dev_priv->render_ring; + struct intel_ring_buffer *ring = LP_RING(dev_priv); if (!I915_NEED_GFX_HWS(dev)) return -EINVAL; @@ -1978,7 +1980,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) if (!IS_I945G(dev) && !IS_I945GM(dev)) pci_enable_msi(dev->pdev); - spin_lock_init(&dev_priv->user_irq_lock); + spin_lock_init(&dev_priv->irq_lock); spin_lock_init(&dev_priv->error_lock); dev_priv->trace_irq_seqno = 0; diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 64844e2e9f86..413a040386a9 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -487,11 +487,11 @@ int i915_reset(struct drm_device *dev, u8 flags) !dev_priv->mm.suspended) { dev_priv->mm.suspended = 0; - dev_priv->render_ring.init(&dev_priv->render_ring); + dev_priv->ring[RCS].init(&dev_priv->ring[RCS]); if (HAS_BSD(dev)) - dev_priv->bsd_ring.init(&dev_priv->bsd_ring); + dev_priv->ring[VCS].init(&dev_priv->ring[VCS]); if (HAS_BLT(dev)) - dev_priv->blt_ring.init(&dev_priv->blt_ring); + dev_priv->ring[BCS].init(&dev_priv->ring[BCS]); mutex_unlock(&dev->struct_mutex); drm_irq_uninstall(dev); diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index af9ff40b135b..8b19b5806230 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -269,9 +269,7 @@ typedef struct drm_i915_private { } *gmbus; struct pci_dev *bridge_dev; - struct intel_ring_buffer render_ring; - struct intel_ring_buffer bsd_ring; - struct intel_ring_buffer blt_ring; + struct intel_ring_buffer ring[I915_NUM_RINGS]; uint32_t next_seqno; drm_dma_handle_t *status_page_dmah; @@ -290,19 +288,15 @@ typedef struct drm_i915_private { int page_flipping; atomic_t irq_received; - /** Protects user_irq_refcount and irq_mask_reg */ - spinlock_t user_irq_lock; u32 trace_irq_seqno; + + /* protects the irq masks */ + spinlock_t irq_lock; /** Cached value of IMR to avoid reads in updating the bitfield */ - u32 irq_mask_reg; u32 pipestat[2]; - /** splitted irq regs for graphics and display engine on Ironlake, - irq_mask_reg is still used for display irq. */ - u32 gt_irq_mask_reg; - u32 gt_irq_enable_reg; - u32 de_irq_enable_reg; - u32 pch_irq_mask_reg; - u32 pch_irq_enable_reg; + u32 irq_mask; + u32 gt_irq_mask; + u32 pch_irq_mask; u32 hotplug_supported_mask; struct work_struct hotplug_work; @@ -1104,7 +1098,8 @@ int __must_check i915_mutex_lock_interruptible(struct drm_device *dev); int __must_check i915_gem_object_wait_rendering(struct drm_i915_gem_object *obj, bool interruptible); void i915_gem_object_move_to_active(struct drm_i915_gem_object *obj, - struct intel_ring_buffer *ring); + struct intel_ring_buffer *ring, + u32 seqno); /** * Returns true if seq1 is later than seq2. @@ -1272,6 +1267,17 @@ extern void intel_display_print_error_state(struct seq_file *m, struct intel_display_error_state *error); #endif +#define LP_RING(d) (&((struct drm_i915_private *)(d))->ring[RCS]) + +#define BEGIN_LP_RING(n) \ + intel_ring_begin(LP_RING(dev_priv), (n)) + +#define OUT_RING(x) \ + intel_ring_emit(LP_RING(dev_priv), x) + +#define ADVANCE_LP_RING() \ + intel_ring_advance(LP_RING(dev_priv)) + /** * Lock test for when it's just for synchronization of ring access. * @@ -1279,8 +1285,7 @@ extern void intel_display_print_error_state(struct seq_file *m, * has access to the ring. */ #define RING_LOCK_TEST_WITH_RETURN(dev, file) do { \ - if (((drm_i915_private_t *)dev->dev_private)->render_ring.obj \ - == NULL) \ + if (LP_RING(dev->dev_private)->obj == NULL) \ LOCK_TEST_WITH_RETURN(dev, file); \ } while (0) @@ -1366,15 +1371,6 @@ i915_write(struct drm_i915_private *dev_priv, u32 reg, u64 val, int len) } } -#define BEGIN_LP_RING(n) \ - intel_ring_begin(&dev_priv->render_ring, (n)) - -#define OUT_RING(x) \ - intel_ring_emit(&dev_priv->render_ring, x) - -#define ADVANCE_LP_RING() \ - intel_ring_advance(&dev_priv->render_ring) - /** * Reads a dword out of the status page, which is written to from the command * queue by automatic updates, MI_REPORT_HEAD, MI_STORE_DATA_INDEX, or @@ -1391,7 +1387,7 @@ i915_write(struct drm_i915_private *dev_priv, u32 reg, u64 val, int len) * The area from dword 0x20 to 0x3ff is available for driver usage. */ #define READ_HWSP(dev_priv, reg) (((volatile u32 *)\ - (dev_priv->render_ring.status_page.page_addr))[reg]) + (LP_RING(dev_priv)->status_page.page_addr))[reg]) #define READ_BREADCRUMB(dev_priv) READ_HWSP(dev_priv, I915_BREADCRUMB_INDEX) #define I915_GEM_HWS_INDEX 0x20 #define I915_BREADCRUMB_INDEX 0x21 diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index d99212fe54ed..eeed2e99d247 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1561,11 +1561,11 @@ i915_gem_object_put_pages_gtt(struct drm_i915_gem_object *obj) void i915_gem_object_move_to_active(struct drm_i915_gem_object *obj, - struct intel_ring_buffer *ring) + struct intel_ring_buffer *ring, + u32 seqno) { struct drm_device *dev = obj->base.dev; struct drm_i915_private *dev_priv = dev->dev_private; - uint32_t seqno = i915_gem_next_request_seqno(dev, ring); BUG_ON(ring == NULL); obj->ring = ring; @@ -1679,7 +1679,8 @@ i915_gem_process_flushing_list(struct drm_device *dev, obj->base.write_domain = 0; list_del_init(&obj->gpu_write_list); - i915_gem_object_move_to_active(obj, ring); + i915_gem_object_move_to_active(obj, ring, + i915_gem_next_request_seqno(dev, ring)); trace_i915_gem_object_change_domain(obj, obj->base.read_domains, @@ -1804,10 +1805,10 @@ void i915_gem_reset(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_gem_object *obj; + int i; - i915_gem_reset_ring_lists(dev_priv, &dev_priv->render_ring); - i915_gem_reset_ring_lists(dev_priv, &dev_priv->bsd_ring); - i915_gem_reset_ring_lists(dev_priv, &dev_priv->blt_ring); + for (i = 0; i < I915_NUM_RINGS; i++) + i915_gem_reset_ring_lists(dev_priv, &dev_priv->ring[i]); /* Remove anything from the flushing lists. The GPU cache is likely * to be lost on reset along with the data, so simply move the @@ -1846,6 +1847,7 @@ i915_gem_retire_requests_ring(struct drm_device *dev, { drm_i915_private_t *dev_priv = dev->dev_private; uint32_t seqno; + int i; if (!ring->status_page.page_addr || list_empty(&ring->request_list)) @@ -1854,6 +1856,11 @@ i915_gem_retire_requests_ring(struct drm_device *dev, WARN_ON(i915_verify_lists(dev)); seqno = ring->get_seqno(ring); + + for (i = 0; i < I915_NUM_RINGS; i++) + if (seqno >= ring->sync_seqno[i]) + ring->sync_seqno[i] = 0; + while (!list_empty(&ring->request_list)) { struct drm_i915_gem_request *request; @@ -1892,7 +1899,7 @@ i915_gem_retire_requests_ring(struct drm_device *dev, if (unlikely (dev_priv->trace_irq_seqno && i915_seqno_passed(dev_priv->trace_irq_seqno, seqno))) { - ring->user_irq_put(ring); + ring->irq_put(ring); dev_priv->trace_irq_seqno = 0; } @@ -1903,6 +1910,7 @@ void i915_gem_retire_requests(struct drm_device *dev) { drm_i915_private_t *dev_priv = dev->dev_private; + int i; if (!list_empty(&dev_priv->mm.deferred_free_list)) { struct drm_i915_gem_object *obj, *next; @@ -1918,9 +1926,8 @@ i915_gem_retire_requests(struct drm_device *dev) i915_gem_free_object_tail(obj); } - i915_gem_retire_requests_ring(dev, &dev_priv->render_ring); - i915_gem_retire_requests_ring(dev, &dev_priv->bsd_ring); - i915_gem_retire_requests_ring(dev, &dev_priv->blt_ring); + for (i = 0; i < I915_NUM_RINGS; i++) + i915_gem_retire_requests_ring(dev, &dev_priv->ring[i]); } static void @@ -1942,9 +1949,9 @@ i915_gem_retire_work_handler(struct work_struct *work) i915_gem_retire_requests(dev); if (!dev_priv->mm.suspended && - (!list_empty(&dev_priv->render_ring.request_list) || - !list_empty(&dev_priv->bsd_ring.request_list) || - !list_empty(&dev_priv->blt_ring.request_list))) + (!list_empty(&dev_priv->ring[RCS].request_list) || + !list_empty(&dev_priv->ring[VCS].request_list) || + !list_empty(&dev_priv->ring[BCS].request_list))) queue_delayed_work(dev_priv->wq, &dev_priv->mm.retire_work, HZ); mutex_unlock(&dev->struct_mutex); } @@ -1993,7 +2000,7 @@ i915_do_wait_request(struct drm_device *dev, uint32_t seqno, trace_i915_gem_request_wait_begin(dev, seqno); ring->waiting_seqno = seqno; - ring->user_irq_get(ring); + ring->irq_get(ring); if (interruptible) ret = wait_event_interruptible(ring->irq_queue, i915_seqno_passed(ring->get_seqno(ring), seqno) @@ -2003,7 +2010,7 @@ i915_do_wait_request(struct drm_device *dev, uint32_t seqno, i915_seqno_passed(ring->get_seqno(ring), seqno) || atomic_read(&dev_priv->mm.wedged)); - ring->user_irq_put(ring); + ring->irq_put(ring); ring->waiting_seqno = 0; trace_i915_gem_request_wait_end(dev, seqno); @@ -2159,7 +2166,7 @@ i915_gpu_idle(struct drm_device *dev) { drm_i915_private_t *dev_priv = dev->dev_private; bool lists_empty; - int ret; + int ret, i; lists_empty = (list_empty(&dev_priv->mm.flushing_list) && list_empty(&dev_priv->mm.active_list)); @@ -2167,17 +2174,11 @@ i915_gpu_idle(struct drm_device *dev) return 0; /* Flush everything onto the inactive list. */ - ret = i915_ring_idle(dev, &dev_priv->render_ring); - if (ret) - return ret; - - ret = i915_ring_idle(dev, &dev_priv->bsd_ring); - if (ret) - return ret; - - ret = i915_ring_idle(dev, &dev_priv->blt_ring); - if (ret) - return ret; + for (i = 0; i < I915_NUM_RINGS; i++) { + ret = i915_ring_idle(dev, &dev_priv->ring[i]); + if (ret) + return ret; + } return 0; } @@ -3153,11 +3154,11 @@ i915_gem_ring_throttle(struct drm_device *dev, struct drm_file *file) * generation is designed to be run atomically and so is * lockless. */ - ring->user_irq_get(ring); + ring->irq_get(ring); ret = wait_event_interruptible(ring->irq_queue, i915_seqno_passed(ring->get_seqno(ring), seqno) || atomic_read(&dev_priv->mm.wedged)); - ring->user_irq_put(ring); + ring->irq_put(ring); if (ret == 0 && atomic_read(&dev_priv->mm.wedged)) ret = -EIO; @@ -3584,9 +3585,9 @@ i915_gem_init_ringbuffer(struct drm_device *dev) return 0; cleanup_bsd_ring: - intel_cleanup_ring_buffer(&dev_priv->bsd_ring); + intel_cleanup_ring_buffer(&dev_priv->ring[VCS]); cleanup_render_ring: - intel_cleanup_ring_buffer(&dev_priv->render_ring); + intel_cleanup_ring_buffer(&dev_priv->ring[RCS]); return ret; } @@ -3594,10 +3595,10 @@ void i915_gem_cleanup_ringbuffer(struct drm_device *dev) { drm_i915_private_t *dev_priv = dev->dev_private; + int i; - intel_cleanup_ring_buffer(&dev_priv->render_ring); - intel_cleanup_ring_buffer(&dev_priv->bsd_ring); - intel_cleanup_ring_buffer(&dev_priv->blt_ring); + for (i = 0; i < I915_NUM_RINGS; i++) + intel_cleanup_ring_buffer(&dev_priv->ring[i]); } int @@ -3605,7 +3606,7 @@ i915_gem_entervt_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv) { drm_i915_private_t *dev_priv = dev->dev_private; - int ret; + int ret, i; if (drm_core_check_feature(dev, DRIVER_MODESET)) return 0; @@ -3625,14 +3626,12 @@ i915_gem_entervt_ioctl(struct drm_device *dev, void *data, } BUG_ON(!list_empty(&dev_priv->mm.active_list)); - BUG_ON(!list_empty(&dev_priv->render_ring.active_list)); - BUG_ON(!list_empty(&dev_priv->bsd_ring.active_list)); - BUG_ON(!list_empty(&dev_priv->blt_ring.active_list)); BUG_ON(!list_empty(&dev_priv->mm.flushing_list)); BUG_ON(!list_empty(&dev_priv->mm.inactive_list)); - BUG_ON(!list_empty(&dev_priv->render_ring.request_list)); - BUG_ON(!list_empty(&dev_priv->bsd_ring.request_list)); - BUG_ON(!list_empty(&dev_priv->blt_ring.request_list)); + for (i = 0; i < I915_NUM_RINGS; i++) { + BUG_ON(!list_empty(&dev_priv->ring[i].active_list)); + BUG_ON(!list_empty(&dev_priv->ring[i].request_list)); + } mutex_unlock(&dev->struct_mutex); ret = drm_irq_install(dev); @@ -3695,9 +3694,8 @@ i915_gem_load(struct drm_device *dev) INIT_LIST_HEAD(&dev_priv->mm.fence_list); INIT_LIST_HEAD(&dev_priv->mm.deferred_free_list); INIT_LIST_HEAD(&dev_priv->mm.gtt_list); - init_ring_lists(&dev_priv->render_ring); - init_ring_lists(&dev_priv->bsd_ring); - init_ring_lists(&dev_priv->blt_ring); + for (i = 0; i < I915_NUM_RINGS; i++) + init_ring_lists(&dev_priv->ring[i]); for (i = 0; i < 16; i++) INIT_LIST_HEAD(&dev_priv->fence_regs[i].lru_list); INIT_DELAYED_WORK(&dev_priv->mm.retire_work, diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index 9bdc495e17bb..6fc9cc485781 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c @@ -632,23 +632,59 @@ i915_gem_execbuffer_flush(struct drm_device *dev, uint32_t flush_rings) { drm_i915_private_t *dev_priv = dev->dev_private; + int i; if (flush_domains & I915_GEM_DOMAIN_CPU) intel_gtt_chipset_flush(); if ((flush_domains | invalidate_domains) & I915_GEM_GPU_DOMAINS) { - if (flush_rings & RING_RENDER) - i915_gem_flush_ring(dev, &dev_priv->render_ring, - invalidate_domains, flush_domains); - if (flush_rings & RING_BSD) - i915_gem_flush_ring(dev, &dev_priv->bsd_ring, - invalidate_domains, flush_domains); - if (flush_rings & RING_BLT) - i915_gem_flush_ring(dev, &dev_priv->blt_ring, - invalidate_domains, flush_domains); + for (i = 0; i < I915_NUM_RINGS; i++) + if (flush_rings & (1 << i)) + i915_gem_flush_ring(dev, &dev_priv->ring[i], + invalidate_domains, + flush_domains); } } +static int +i915_gem_execbuffer_sync_rings(struct drm_i915_gem_object *obj, + struct intel_ring_buffer *to) +{ + struct intel_ring_buffer *from = obj->ring; + u32 seqno; + int ret, idx; + + if (from == NULL || to == from) + return 0; + + if (INTEL_INFO(obj->base.dev)->gen < 6) + return i915_gem_object_wait_rendering(obj, true); + + idx = intel_ring_sync_index(from, to); + + seqno = obj->last_rendering_seqno; + if (seqno <= from->sync_seqno[idx]) + return 0; + + if (seqno == from->outstanding_lazy_request) { + struct drm_i915_gem_request *request; + + request = kzalloc(sizeof(*request), GFP_KERNEL); + if (request == NULL) + return -ENOMEM; + + ret = i915_add_request(obj->base.dev, NULL, request, from); + if (ret) { + kfree(request); + return ret; + } + + seqno = request->seqno; + } + + from->sync_seqno[idx] = seqno; + return intel_ring_sync(to, from, seqno - 1); +} static int i915_gem_execbuffer_move_to_gpu(struct intel_ring_buffer *ring, @@ -678,12 +714,9 @@ i915_gem_execbuffer_move_to_gpu(struct intel_ring_buffer *ring, } list_for_each_entry(obj, objects, exec_list) { - /* XXX replace with semaphores */ - if (obj->ring && ring != obj->ring) { - ret = i915_gem_object_wait_rendering(obj, true); - if (ret) - return ret; - } + ret = i915_gem_execbuffer_sync_rings(obj, ring); + if (ret) + return ret; } return 0; @@ -769,7 +802,8 @@ i915_gem_execbuffer_wait_for_flips(struct intel_ring_buffer *ring, static void i915_gem_execbuffer_move_to_active(struct list_head *objects, - struct intel_ring_buffer *ring) + struct intel_ring_buffer *ring, + u32 seqno) { struct drm_i915_gem_object *obj; @@ -778,7 +812,7 @@ i915_gem_execbuffer_move_to_active(struct list_head *objects, obj->base.write_domain = obj->base.pending_write_domain; obj->fenced_gpu_access = obj->pending_fenced_gpu_access; - i915_gem_object_move_to_active(obj, ring); + i915_gem_object_move_to_active(obj, ring, seqno); if (obj->base.write_domain) { obj->dirty = 1; obj->pending_gpu_write = true; @@ -833,6 +867,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, struct drm_clip_rect *cliprects = NULL; struct intel_ring_buffer *ring; u32 exec_start, exec_len; + u32 seqno; int ret, i; if (!i915_gem_check_execbuffer(args)) { @@ -851,21 +886,21 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, switch (args->flags & I915_EXEC_RING_MASK) { case I915_EXEC_DEFAULT: case I915_EXEC_RENDER: - ring = &dev_priv->render_ring; + ring = &dev_priv->ring[RCS]; break; case I915_EXEC_BSD: if (!HAS_BSD(dev)) { DRM_ERROR("execbuf with invalid ring (BSD)\n"); return -EINVAL; } - ring = &dev_priv->bsd_ring; + ring = &dev_priv->ring[VCS]; break; case I915_EXEC_BLT: if (!HAS_BLT(dev)) { DRM_ERROR("execbuf with invalid ring (BLT)\n"); return -EINVAL; } - ring = &dev_priv->blt_ring; + ring = &dev_priv->ring[BCS]; break; default: DRM_ERROR("execbuf with unknown ring: %d\n", @@ -879,7 +914,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, } if (args->num_cliprects != 0) { - if (ring != &dev_priv->render_ring) { + if (ring != &dev_priv->ring[RCS]) { DRM_ERROR("clip rectangles are only valid with the render ring\n"); return -EINVAL; } @@ -972,6 +1007,21 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, if (ret) goto err; + seqno = i915_gem_next_request_seqno(dev, ring); + for (i = 0; i < I915_NUM_RINGS-1; i++) { + if (seqno < ring->sync_seqno[i]) { + /* The GPU can not handle its semaphore value wrapping, + * so every billion or so execbuffers, we need to stall + * the GPU in order to reset the counters. + */ + ret = i915_gpu_idle(dev); + if (ret) + goto err; + + BUG_ON(ring->sync_seqno[i]); + } + } + exec_start = batch_obj->gtt_offset + args->batch_start_offset; exec_len = args->batch_len; if (cliprects) { @@ -992,7 +1042,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, goto err; } - i915_gem_execbuffer_move_to_active(&objects, ring); + i915_gem_execbuffer_move_to_active(&objects, ring, seqno); i915_gem_execbuffer_retire_commands(dev, file, ring); err: diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 9aa1e1dc5fd5..5e831b7eb3f1 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -67,9 +67,9 @@ void ironlake_enable_graphics_irq(drm_i915_private_t *dev_priv, u32 mask) { - if ((dev_priv->gt_irq_mask_reg & mask) != 0) { - dev_priv->gt_irq_mask_reg &= ~mask; - I915_WRITE(GTIMR, dev_priv->gt_irq_mask_reg); + if ((dev_priv->gt_irq_mask & mask) != 0) { + dev_priv->gt_irq_mask &= ~mask; + I915_WRITE(GTIMR, dev_priv->gt_irq_mask); POSTING_READ(GTIMR); } } @@ -77,9 +77,9 @@ ironlake_enable_graphics_irq(drm_i915_private_t *dev_priv, u32 mask) void ironlake_disable_graphics_irq(drm_i915_private_t *dev_priv, u32 mask) { - if ((dev_priv->gt_irq_mask_reg & mask) != mask) { - dev_priv->gt_irq_mask_reg |= mask; - I915_WRITE(GTIMR, dev_priv->gt_irq_mask_reg); + if ((dev_priv->gt_irq_mask & mask) != mask) { + dev_priv->gt_irq_mask |= mask; + I915_WRITE(GTIMR, dev_priv->gt_irq_mask); POSTING_READ(GTIMR); } } @@ -88,9 +88,9 @@ ironlake_disable_graphics_irq(drm_i915_private_t *dev_priv, u32 mask) static void ironlake_enable_display_irq(drm_i915_private_t *dev_priv, u32 mask) { - if ((dev_priv->irq_mask_reg & mask) != 0) { - dev_priv->irq_mask_reg &= ~mask; - I915_WRITE(DEIMR, dev_priv->irq_mask_reg); + if ((dev_priv->irq_mask & mask) != 0) { + dev_priv->irq_mask &= ~mask; + I915_WRITE(DEIMR, dev_priv->irq_mask); POSTING_READ(DEIMR); } } @@ -98,9 +98,9 @@ ironlake_enable_display_irq(drm_i915_private_t *dev_priv, u32 mask) static inline void ironlake_disable_display_irq(drm_i915_private_t *dev_priv, u32 mask) { - if ((dev_priv->irq_mask_reg & mask) != mask) { - dev_priv->irq_mask_reg |= mask; - I915_WRITE(DEIMR, dev_priv->irq_mask_reg); + if ((dev_priv->irq_mask & mask) != mask) { + dev_priv->irq_mask |= mask; + I915_WRITE(DEIMR, dev_priv->irq_mask); POSTING_READ(DEIMR); } } @@ -108,9 +108,9 @@ ironlake_disable_display_irq(drm_i915_private_t *dev_priv, u32 mask) void i915_enable_irq(drm_i915_private_t *dev_priv, u32 mask) { - if ((dev_priv->irq_mask_reg & mask) != 0) { - dev_priv->irq_mask_reg &= ~mask; - I915_WRITE(IMR, dev_priv->irq_mask_reg); + if ((dev_priv->irq_mask & mask) != 0) { + dev_priv->irq_mask &= ~mask; + I915_WRITE(IMR, dev_priv->irq_mask); POSTING_READ(IMR); } } @@ -118,9 +118,9 @@ i915_enable_irq(drm_i915_private_t *dev_priv, u32 mask) void i915_disable_irq(drm_i915_private_t *dev_priv, u32 mask) { - if ((dev_priv->irq_mask_reg & mask) != mask) { - dev_priv->irq_mask_reg |= mask; - I915_WRITE(IMR, dev_priv->irq_mask_reg); + if ((dev_priv->irq_mask & mask) != mask) { + dev_priv->irq_mask |= mask; + I915_WRITE(IMR, dev_priv->irq_mask); POSTING_READ(IMR); } } @@ -163,9 +163,12 @@ i915_disable_pipestat(drm_i915_private_t *dev_priv, int pipe, u32 mask) /** * intel_enable_asle - enable ASLE interrupt for OpRegion */ -void intel_enable_asle (struct drm_device *dev) +void intel_enable_asle(struct drm_device *dev) { - drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; + drm_i915_private_t *dev_priv = dev->dev_private; + unsigned long irqflags; + + spin_lock_irqsave(&dev_priv->irq_lock, irqflags); if (HAS_PCH_SPLIT(dev)) ironlake_enable_display_irq(dev_priv, DE_GSE); @@ -176,6 +179,8 @@ void intel_enable_asle (struct drm_device *dev) i915_enable_pipestat(dev_priv, 0, PIPE_LEGACY_BLC_EVENT_ENABLE); } + + spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); } /** @@ -344,12 +349,12 @@ static irqreturn_t ironlake_irq_handler(struct drm_device *dev) READ_BREADCRUMB(dev_priv); } - if (gt_iir & GT_PIPE_NOTIFY) - notify_ring(dev, &dev_priv->render_ring); + if (gt_iir & (GT_USER_INTERRUPT | GT_PIPE_NOTIFY)) + notify_ring(dev, &dev_priv->ring[RCS]); if (gt_iir & bsd_usr_interrupt) - notify_ring(dev, &dev_priv->bsd_ring); - if (HAS_BLT(dev) && gt_iir & GT_BLT_USER_INTERRUPT) - notify_ring(dev, &dev_priv->blt_ring); + notify_ring(dev, &dev_priv->ring[VCS]); + if (gt_iir & GT_BLT_USER_INTERRUPT) + notify_ring(dev, &dev_priv->ring[BCS]); if (de_iir & DE_GSE) intel_opregion_gse_intr(dev); @@ -640,8 +645,7 @@ static void i915_capture_error_state(struct drm_device *dev) DRM_DEBUG_DRIVER("generating error event\n"); - error->seqno = - dev_priv->render_ring.get_seqno(&dev_priv->render_ring); + error->seqno = dev_priv->ring[RCS].get_seqno(&dev_priv->ring[RCS]); error->eir = I915_READ(EIR); error->pgtbl_er = I915_READ(PGTBL_ER); error->pipeastat = I915_READ(PIPEASTAT); @@ -656,16 +660,16 @@ static void i915_capture_error_state(struct drm_device *dev) error->bcs_ipeir = I915_READ(BCS_IPEIR); error->bcs_instdone = I915_READ(BCS_INSTDONE); error->bcs_seqno = 0; - if (dev_priv->blt_ring.get_seqno) - error->bcs_seqno = dev_priv->blt_ring.get_seqno(&dev_priv->blt_ring); + if (dev_priv->ring[BCS].get_seqno) + error->bcs_seqno = dev_priv->ring[BCS].get_seqno(&dev_priv->ring[BCS]); error->vcs_acthd = I915_READ(VCS_ACTHD); error->vcs_ipehr = I915_READ(VCS_IPEHR); error->vcs_ipeir = I915_READ(VCS_IPEIR); error->vcs_instdone = I915_READ(VCS_INSTDONE); error->vcs_seqno = 0; - if (dev_priv->bsd_ring.get_seqno) - error->vcs_seqno = dev_priv->bsd_ring.get_seqno(&dev_priv->bsd_ring); + if (dev_priv->ring[VCS].get_seqno) + error->vcs_seqno = dev_priv->ring[VCS].get_seqno(&dev_priv->ring[VCS]); } if (INTEL_INFO(dev)->gen >= 4) { error->ipeir = I915_READ(IPEIR_I965); @@ -684,7 +688,7 @@ static void i915_capture_error_state(struct drm_device *dev) } i915_gem_record_fences(dev, error); - bbaddr = i915_ringbuffer_last_batch(dev, &dev_priv->render_ring); + bbaddr = i915_ringbuffer_last_batch(dev, &dev_priv->ring[RCS]); /* Grab the current batchbuffer, most likely to have crashed. */ batchbuffer[0] = NULL; @@ -748,7 +752,7 @@ static void i915_capture_error_state(struct drm_device *dev) /* Record the ringbuffer */ error->ringbuffer = i915_error_object_create(dev, - dev_priv->render_ring.obj); + dev_priv->ring[RCS].obj); /* Record buffers on the active and pinned lists. */ error->active_bo = NULL; @@ -949,11 +953,11 @@ void i915_handle_error(struct drm_device *dev, bool wedged) /* * Wakeup waiting processes so they don't hang */ - wake_up_all(&dev_priv->render_ring.irq_queue); + wake_up_all(&dev_priv->ring[RCS].irq_queue); if (HAS_BSD(dev)) - wake_up_all(&dev_priv->bsd_ring.irq_queue); + wake_up_all(&dev_priv->ring[VCS].irq_queue); if (HAS_BLT(dev)) - wake_up_all(&dev_priv->blt_ring.irq_queue); + wake_up_all(&dev_priv->ring[BCS].irq_queue); } queue_work(dev_priv->wq, &dev_priv->error_work); @@ -1035,7 +1039,7 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) * It doesn't set the bit in iir again, but it still produces * interrupts (for non-MSI). */ - spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags); + spin_lock_irqsave(&dev_priv->irq_lock, irqflags); pipea_stats = I915_READ(PIPEASTAT); pipeb_stats = I915_READ(PIPEBSTAT); @@ -1058,7 +1062,7 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) I915_WRITE(PIPEBSTAT, pipeb_stats); irq_received = 1; } - spin_unlock_irqrestore(&dev_priv->user_irq_lock, irqflags); + spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); if (!irq_received) break; @@ -1091,9 +1095,9 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) } if (iir & I915_USER_INTERRUPT) - notify_ring(dev, &dev_priv->render_ring); - if (HAS_BSD(dev) && (iir & I915_BSD_USER_INTERRUPT)) - notify_ring(dev, &dev_priv->bsd_ring); + notify_ring(dev, &dev_priv->ring[RCS]); + if (iir & I915_BSD_USER_INTERRUPT) + notify_ring(dev, &dev_priv->ring[VCS]); if (iir & I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT) { intel_prepare_page_flip(dev, 0); @@ -1180,10 +1184,10 @@ static int i915_emit_irq(struct drm_device * dev) void i915_trace_irq_get(struct drm_device *dev, u32 seqno) { drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; - struct intel_ring_buffer *render_ring = &dev_priv->render_ring; + struct intel_ring_buffer *ring = LP_RING(dev_priv); if (dev_priv->trace_irq_seqno == 0) - render_ring->user_irq_get(render_ring); + ring->irq_get(ring); dev_priv->trace_irq_seqno = seqno; } @@ -1193,7 +1197,7 @@ static int i915_wait_irq(struct drm_device * dev, int irq_nr) drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv; int ret = 0; - struct intel_ring_buffer *render_ring = &dev_priv->render_ring; + struct intel_ring_buffer *ring = LP_RING(dev_priv); DRM_DEBUG_DRIVER("irq_nr=%d breadcrumb=%d\n", irq_nr, READ_BREADCRUMB(dev_priv)); @@ -1207,10 +1211,10 @@ static int i915_wait_irq(struct drm_device * dev, int irq_nr) if (master_priv->sarea_priv) master_priv->sarea_priv->perf_boxes |= I915_BOX_WAIT; - render_ring->user_irq_get(render_ring); - DRM_WAIT_ON(ret, dev_priv->render_ring.irq_queue, 3 * DRM_HZ, + ring->irq_get(ring); + DRM_WAIT_ON(ret, ring->irq_queue, 3 * DRM_HZ, READ_BREADCRUMB(dev_priv) >= irq_nr); - render_ring->user_irq_put(render_ring); + ring->irq_put(ring); if (ret == -EBUSY) { DRM_ERROR("EBUSY -- rec: %d emitted: %d\n", @@ -1229,7 +1233,7 @@ int i915_irq_emit(struct drm_device *dev, void *data, drm_i915_irq_emit_t *emit = data; int result; - if (!dev_priv || !dev_priv->render_ring.virtual_start) { + if (!dev_priv || !LP_RING(dev_priv)->virtual_start) { DRM_ERROR("called with no initialization\n"); return -EINVAL; } @@ -1275,9 +1279,9 @@ int i915_enable_vblank(struct drm_device *dev, int pipe) if (!i915_pipe_enabled(dev, pipe)) return -EINVAL; - spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags); + spin_lock_irqsave(&dev_priv->irq_lock, irqflags); if (HAS_PCH_SPLIT(dev)) - ironlake_enable_display_irq(dev_priv, (pipe == 0) ? + ironlake_enable_display_irq(dev_priv, (pipe == 0) ? DE_PIPEA_VBLANK: DE_PIPEB_VBLANK); else if (INTEL_INFO(dev)->gen >= 4) i915_enable_pipestat(dev_priv, pipe, @@ -1285,7 +1289,7 @@ int i915_enable_vblank(struct drm_device *dev, int pipe) else i915_enable_pipestat(dev_priv, pipe, PIPE_VBLANK_INTERRUPT_ENABLE); - spin_unlock_irqrestore(&dev_priv->user_irq_lock, irqflags); + spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); return 0; } @@ -1297,15 +1301,15 @@ void i915_disable_vblank(struct drm_device *dev, int pipe) drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; unsigned long irqflags; - spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags); + spin_lock_irqsave(&dev_priv->irq_lock, irqflags); if (HAS_PCH_SPLIT(dev)) - ironlake_disable_display_irq(dev_priv, (pipe == 0) ? + ironlake_disable_display_irq(dev_priv, (pipe == 0) ? DE_PIPEA_VBLANK: DE_PIPEB_VBLANK); else i915_disable_pipestat(dev_priv, pipe, PIPE_VBLANK_INTERRUPT_ENABLE | PIPE_START_VBLANK_INTERRUPT_ENABLE); - spin_unlock_irqrestore(&dev_priv->user_irq_lock, irqflags); + spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); } void i915_enable_interrupt (struct drm_device *dev) @@ -1397,6 +1401,27 @@ static bool i915_hangcheck_ring_idle(struct intel_ring_buffer *ring, bool *err) return false; } +static bool kick_ring(struct intel_ring_buffer *ring) +{ + struct drm_device *dev = ring->dev; + struct drm_i915_private *dev_priv = dev->dev_private; + u32 tmp = I915_READ_CTL(ring); + if (tmp & RING_WAIT) { + DRM_ERROR("Kicking stuck wait on %s\n", + ring->name); + I915_WRITE_CTL(ring, tmp); + return true; + } + if (IS_GEN6(dev) && + (tmp & RING_WAIT_SEMAPHORE)) { + DRM_ERROR("Kicking stuck semaphore on %s\n", + ring->name); + I915_WRITE_CTL(ring, tmp); + return true; + } + return false; +} + /** * This is called when the chip hasn't reported back with completed * batchbuffers in a long time. The first time this is called we simply record @@ -1411,9 +1436,9 @@ void i915_hangcheck_elapsed(unsigned long data) bool err = false; /* If all work is done then ACTHD clearly hasn't advanced. */ - if (i915_hangcheck_ring_idle(&dev_priv->render_ring, &err) && - i915_hangcheck_ring_idle(&dev_priv->bsd_ring, &err) && - i915_hangcheck_ring_idle(&dev_priv->blt_ring, &err)) { + if (i915_hangcheck_ring_idle(&dev_priv->ring[RCS], &err) && + i915_hangcheck_ring_idle(&dev_priv->ring[VCS], &err) && + i915_hangcheck_ring_idle(&dev_priv->ring[BCS], &err)) { dev_priv->hangcheck_count = 0; if (err) goto repeat; @@ -1442,12 +1467,17 @@ void i915_hangcheck_elapsed(unsigned long data) * and break the hang. This should work on * all but the second generation chipsets. */ - struct intel_ring_buffer *ring = &dev_priv->render_ring; - u32 tmp = I915_READ_CTL(ring); - if (tmp & RING_WAIT) { - I915_WRITE_CTL(ring, tmp); + + if (kick_ring(&dev_priv->ring[RCS])) + goto repeat; + + if (HAS_BSD(dev) && + kick_ring(&dev_priv->ring[VCS])) + goto repeat; + + if (HAS_BLT(dev) && + kick_ring(&dev_priv->ring[BCS])) goto repeat; - } } i915_handle_error(dev, true); @@ -1498,37 +1528,37 @@ static int ironlake_irq_postinstall(struct drm_device *dev) /* enable kind of interrupts always enabled */ u32 display_mask = DE_MASTER_IRQ_CONTROL | DE_GSE | DE_PCH_EVENT | DE_PLANEA_FLIP_DONE | DE_PLANEB_FLIP_DONE; - u32 render_mask = GT_PIPE_NOTIFY | GT_BSD_USER_INTERRUPT; + u32 render_irqs; u32 hotplug_mask; - dev_priv->irq_mask_reg = ~display_mask; - dev_priv->de_irq_enable_reg = display_mask | DE_PIPEA_VBLANK | DE_PIPEB_VBLANK; + dev_priv->irq_mask = ~display_mask; /* should always can generate irq */ I915_WRITE(DEIIR, I915_READ(DEIIR)); - I915_WRITE(DEIMR, dev_priv->irq_mask_reg); - I915_WRITE(DEIER, dev_priv->de_irq_enable_reg); + I915_WRITE(DEIMR, dev_priv->irq_mask); + I915_WRITE(DEIER, display_mask | DE_PIPEA_VBLANK | DE_PIPEB_VBLANK); POSTING_READ(DEIER); - if (IS_GEN6(dev)) { - render_mask = - GT_PIPE_NOTIFY | - GT_GEN6_BSD_USER_INTERRUPT | - GT_BLT_USER_INTERRUPT; - } - - dev_priv->gt_irq_mask_reg = ~render_mask; - dev_priv->gt_irq_enable_reg = render_mask; + dev_priv->gt_irq_mask = ~0; I915_WRITE(GTIIR, I915_READ(GTIIR)); - I915_WRITE(GTIMR, dev_priv->gt_irq_mask_reg); + I915_WRITE(GTIMR, dev_priv->gt_irq_mask); if (IS_GEN6(dev)) { - I915_WRITE(GEN6_RENDER_IMR, ~GEN6_RENDER_PIPE_CONTROL_NOTIFY_INTERRUPT); - I915_WRITE(GEN6_BSD_IMR, ~GEN6_BSD_IMR_USER_INTERRUPT); + I915_WRITE(GEN6_RENDER_IMR, ~GEN6_RENDER_USER_INTERRUPT); + I915_WRITE(GEN6_BSD_IMR, ~GEN6_BSD_USER_INTERRUPT); I915_WRITE(GEN6_BLITTER_IMR, ~GEN6_BLITTER_USER_INTERRUPT); } - I915_WRITE(GTIER, dev_priv->gt_irq_enable_reg); + if (IS_GEN6(dev)) + render_irqs = + GT_USER_INTERRUPT | + GT_GEN6_BSD_USER_INTERRUPT | + GT_BLT_USER_INTERRUPT; + else + render_irqs = + GT_PIPE_NOTIFY | + GT_BSD_USER_INTERRUPT; + I915_WRITE(GTIER, render_irqs); POSTING_READ(GTIER); if (HAS_PCH_CPT(dev)) { @@ -1539,12 +1569,11 @@ static int ironlake_irq_postinstall(struct drm_device *dev) SDE_PORTC_HOTPLUG | SDE_PORTD_HOTPLUG; } - dev_priv->pch_irq_mask_reg = ~hotplug_mask; - dev_priv->pch_irq_enable_reg = hotplug_mask; + dev_priv->pch_irq_mask = ~hotplug_mask; I915_WRITE(SDEIIR, I915_READ(SDEIIR)); - I915_WRITE(SDEIMR, dev_priv->pch_irq_mask_reg); - I915_WRITE(SDEIER, dev_priv->pch_irq_enable_reg); + I915_WRITE(SDEIMR, dev_priv->pch_irq_mask); + I915_WRITE(SDEIER, hotplug_mask); POSTING_READ(SDEIER); if (IS_IRONLAKE_M(dev)) { @@ -1594,11 +1623,11 @@ int i915_driver_irq_postinstall(struct drm_device *dev) u32 enable_mask = I915_INTERRUPT_ENABLE_FIX | I915_INTERRUPT_ENABLE_VAR; u32 error_mask; - DRM_INIT_WAITQUEUE(&dev_priv->render_ring.irq_queue); + DRM_INIT_WAITQUEUE(&dev_priv->ring[RCS].irq_queue); if (HAS_BSD(dev)) - DRM_INIT_WAITQUEUE(&dev_priv->bsd_ring.irq_queue); + DRM_INIT_WAITQUEUE(&dev_priv->ring[VCS].irq_queue); if (HAS_BLT(dev)) - DRM_INIT_WAITQUEUE(&dev_priv->blt_ring.irq_queue); + DRM_INIT_WAITQUEUE(&dev_priv->ring[BCS].irq_queue); dev_priv->vblank_pipe = DRM_I915_VBLANK_PIPE_A | DRM_I915_VBLANK_PIPE_B; @@ -1606,7 +1635,7 @@ int i915_driver_irq_postinstall(struct drm_device *dev) return ironlake_irq_postinstall(dev); /* Unmask the interrupts that we always want on. */ - dev_priv->irq_mask_reg = ~I915_INTERRUPT_ENABLE_FIX; + dev_priv->irq_mask = ~I915_INTERRUPT_ENABLE_FIX; dev_priv->pipestat[0] = 0; dev_priv->pipestat[1] = 0; @@ -1615,7 +1644,7 @@ int i915_driver_irq_postinstall(struct drm_device *dev) /* Enable in IER... */ enable_mask |= I915_DISPLAY_PORT_INTERRUPT; /* and unmask in IMR */ - dev_priv->irq_mask_reg &= ~I915_DISPLAY_PORT_INTERRUPT; + dev_priv->irq_mask &= ~I915_DISPLAY_PORT_INTERRUPT; } /* @@ -1633,7 +1662,7 @@ int i915_driver_irq_postinstall(struct drm_device *dev) } I915_WRITE(EMR, error_mask); - I915_WRITE(IMR, dev_priv->irq_mask_reg); + I915_WRITE(IMR, dev_priv->irq_mask); I915_WRITE(IER, enable_mask); POSTING_READ(IER); diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 06175e98c5bb..3e03094cf148 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -176,6 +176,11 @@ #define MI_BATCH_NON_SECURE (1) #define MI_BATCH_NON_SECURE_I965 (1<<8) #define MI_BATCH_BUFFER_START MI_INSTR(0x31, 0) +#define MI_SEMAPHORE_MBOX MI_INSTR(0x16, 1) /* gen6+ */ +#define MI_SEMAPHORE_GLOBAL_GTT (1<<22) +#define MI_SEMAPHORE_UPDATE (1<<21) +#define MI_SEMAPHORE_COMPARE (1<<20) +#define MI_SEMAPHORE_REGISTER (1<<18) /* * 3D instructions used by the kernel */ @@ -276,9 +281,12 @@ #define RING_HEAD(base) ((base)+0x34) #define RING_START(base) ((base)+0x38) #define RING_CTL(base) ((base)+0x3c) +#define RING_SYNC_0(base) ((base)+0x40) +#define RING_SYNC_1(base) ((base)+0x44) #define RING_HWS_PGA(base) ((base)+0x80) #define RING_HWS_PGA_GEN6(base) ((base)+0x2080) #define RING_ACTHD(base) ((base)+0x74) +#define RING_NOPID(base) ((base)+0x94) #define TAIL_ADDR 0x001FFFF8 #define HEAD_WRAP_COUNT 0xFFE00000 #define HEAD_WRAP_ONE 0x00200000 @@ -293,6 +301,7 @@ #define RING_INVALID 0x00000000 #define RING_WAIT_I8XX (1<<0) /* gen2, PRBx_HEAD */ #define RING_WAIT (1<<11) /* gen3+, PRBx_CTL */ +#define RING_WAIT_SEMAPHORE (1<<10) /* gen6+ */ #if 0 #define PRB0_TAIL 0x02030 #define PRB0_HEAD 0x02034 @@ -347,6 +356,14 @@ # define VS_TIMER_DISPATCH (1 << 6) # define MI_FLUSH_ENABLE (1 << 11) +#define GFX_MODE 0x02520 +#define GFX_RUN_LIST_ENABLE (1<<15) +#define GFX_TLB_INVALIDATE_ALWAYS (1<<13) +#define GFX_SURFACE_FAULT_ENABLE (1<<12) +#define GFX_REPLAY_MODE (1<<11) +#define GFX_PSMI_GRANULARITY (1<<10) +#define GFX_PPGTT_ENABLE (1<<9) + #define SCPD0 0x0209c /* 915+ only */ #define IER 0x020a0 #define IIR 0x020a4 @@ -498,7 +515,7 @@ #define GEN6_BSD_SLEEP_PSMI_CONTROL_IDLE_INDICATOR (1 << 3) #define GEN6_BSD_IMR 0x120a8 -#define GEN6_BSD_IMR_USER_INTERRUPT (1 << 12) +#define GEN6_BSD_USER_INTERRUPT (1 << 12) #define GEN6_BSD_RNCID 0x12198 diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 3063edd2456f..0b6272a2edfc 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -1998,7 +1998,7 @@ static void intel_clear_scanline_wait(struct drm_device *dev) /* Can't break the hang on i8xx */ return; - ring = &dev_priv->render_ring; + ring = LP_RING(dev_priv); tmp = I915_READ_CTL(ring); if (tmp & RING_WAIT) I915_WRITE_CTL(ring, tmp); @@ -5124,7 +5124,7 @@ static int intel_crtc_page_flip(struct drm_crtc *crtc, obj = intel_fb->obj; mutex_lock(&dev->struct_mutex); - ret = intel_pin_and_fence_fb_obj(dev, obj, &dev_priv->render_ring); + ret = intel_pin_and_fence_fb_obj(dev, obj, LP_RING(dev_priv)); if (ret) goto cleanup_work; diff --git a/drivers/gpu/drm/i915/intel_opregion.c b/drivers/gpu/drm/i915/intel_opregion.c index 9b0d9a867aea..f295a7aaadf9 100644 --- a/drivers/gpu/drm/i915/intel_opregion.c +++ b/drivers/gpu/drm/i915/intel_opregion.c @@ -273,14 +273,8 @@ void intel_opregion_enable_asle(struct drm_device *dev) struct opregion_asle *asle = dev_priv->opregion.asle; if (asle) { - if (IS_MOBILE(dev)) { - unsigned long irqflags; - - spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags); + if (IS_MOBILE(dev)) intel_enable_asle(dev); - spin_unlock_irqrestore(&dev_priv->user_irq_lock, - irqflags); - } asle->tche = ASLE_ALS_EN | ASLE_BLC_EN | ASLE_PFIT_EN | ASLE_PFMB_EN; diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c index d0c1add393a3..3fbb98b948d6 100644 --- a/drivers/gpu/drm/i915/intel_overlay.c +++ b/drivers/gpu/drm/i915/intel_overlay.c @@ -221,7 +221,7 @@ static int intel_overlay_do_wait_request(struct intel_overlay *overlay, int ret; BUG_ON(overlay->last_flip_req); - ret = i915_add_request(dev, NULL, request, &dev_priv->render_ring); + ret = i915_add_request(dev, NULL, request, LP_RING(dev_priv)); if (ret) { kfree(request); return ret; @@ -230,7 +230,7 @@ static int intel_overlay_do_wait_request(struct intel_overlay *overlay, overlay->flip_tail = tail; ret = i915_do_wait_request(dev, overlay->last_flip_req, true, - &dev_priv->render_ring); + LP_RING(dev_priv)); if (ret) return ret; @@ -364,7 +364,7 @@ static int intel_overlay_continue(struct intel_overlay *overlay, OUT_RING(flip_addr); ADVANCE_LP_RING(); - ret = i915_add_request(dev, NULL, request, &dev_priv->render_ring); + ret = i915_add_request(dev, NULL, request, LP_RING(dev_priv)); if (ret) { kfree(request); return ret; @@ -454,7 +454,7 @@ static int intel_overlay_recover_from_interrupt(struct intel_overlay *overlay, return 0; ret = i915_do_wait_request(dev, overlay->last_flip_req, - interruptible, &dev_priv->render_ring); + interruptible, LP_RING(dev_priv)); if (ret) return ret; diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 21871b0766e2..f71db0cf4909 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -203,6 +203,7 @@ static int init_ring_common(struct intel_ring_buffer *ring) if (ring->space < 0) ring->space += ring->size; } + return 0; } @@ -281,17 +282,18 @@ cleanup_pipe_control(struct intel_ring_buffer *ring) static int init_render_ring(struct intel_ring_buffer *ring) { struct drm_device *dev = ring->dev; + struct drm_i915_private *dev_priv = dev->dev_private; int ret = init_ring_common(ring); if (INTEL_INFO(dev)->gen > 3) { - drm_i915_private_t *dev_priv = dev->dev_private; int mode = VS_TIMER_DISPATCH << 16 | VS_TIMER_DISPATCH; if (IS_GEN6(dev)) mode |= MI_FLUSH_ENABLE << 16 | MI_FLUSH_ENABLE; I915_WRITE(MI_MODE, mode); } - if (HAS_PIPE_CONTROL(dev)) { + if (INTEL_INFO(dev)->gen >= 6) { + } else if (HAS_PIPE_CONTROL(dev)) { ret = init_pipe_control(ring); if (ret) return ret; @@ -308,6 +310,80 @@ static void render_ring_cleanup(struct intel_ring_buffer *ring) cleanup_pipe_control(ring); } +static void +update_semaphore(struct intel_ring_buffer *ring, int i, u32 seqno) +{ + struct drm_device *dev = ring->dev; + struct drm_i915_private *dev_priv = dev->dev_private; + int id; + + /* + * cs -> 1 = vcs, 0 = bcs + * vcs -> 1 = bcs, 0 = cs, + * bcs -> 1 = cs, 0 = vcs. + */ + id = ring - dev_priv->ring; + id += 2 - i; + id %= 3; + + intel_ring_emit(ring, + MI_SEMAPHORE_MBOX | + MI_SEMAPHORE_REGISTER | + MI_SEMAPHORE_UPDATE); + intel_ring_emit(ring, seqno); + intel_ring_emit(ring, + RING_SYNC_0(dev_priv->ring[id].mmio_base) + 4*i); +} + +static int +gen6_add_request(struct intel_ring_buffer *ring, + u32 *result) +{ + u32 seqno; + int ret; + + ret = intel_ring_begin(ring, 10); + if (ret) + return ret; + + seqno = i915_gem_get_seqno(ring->dev); + update_semaphore(ring, 0, seqno); + update_semaphore(ring, 1, seqno); + + intel_ring_emit(ring, MI_STORE_DWORD_INDEX); + intel_ring_emit(ring, I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT); + intel_ring_emit(ring, seqno); + intel_ring_emit(ring, MI_USER_INTERRUPT); + intel_ring_advance(ring); + + *result = seqno; + return 0; +} + +int +intel_ring_sync(struct intel_ring_buffer *ring, + struct intel_ring_buffer *to, + u32 seqno) +{ + int ret; + + ret = intel_ring_begin(ring, 4); + if (ret) + return ret; + + intel_ring_emit(ring, + MI_SEMAPHORE_MBOX | + MI_SEMAPHORE_REGISTER | + intel_ring_sync_index(ring, to) << 17 | + MI_SEMAPHORE_COMPARE); + intel_ring_emit(ring, seqno); + intel_ring_emit(ring, 0); + intel_ring_emit(ring, MI_NOOP); + intel_ring_advance(ring); + + return 0; +} + #define PIPE_CONTROL_FLUSH(ring__, addr__) \ do { \ intel_ring_emit(ring__, GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE | \ @@ -317,131 +393,128 @@ do { \ intel_ring_emit(ring__, 0); \ } while (0) -/** - * Creates a new sequence number, emitting a write of it to the status page - * plus an interrupt, which will trigger i915_user_interrupt_handler. - * - * Must be called with struct_lock held. - * - * Returned sequence numbers are nonzero on success. - */ static int -render_ring_add_request(struct intel_ring_buffer *ring, - u32 *result) +pc_render_add_request(struct intel_ring_buffer *ring, + u32 *result) { struct drm_device *dev = ring->dev; u32 seqno = i915_gem_get_seqno(dev); struct pipe_control *pc = ring->private; + u32 scratch_addr = pc->gtt_offset + 128; int ret; - if (IS_GEN6(dev)) { - ret = intel_ring_begin(ring, 6); - if (ret) - return ret; - - intel_ring_emit(ring, GFX_OP_PIPE_CONTROL | 3); - intel_ring_emit(ring, PIPE_CONTROL_QW_WRITE | - PIPE_CONTROL_WC_FLUSH | PIPE_CONTROL_IS_FLUSH | - PIPE_CONTROL_NOTIFY); - intel_ring_emit(ring, pc->gtt_offset | PIPE_CONTROL_GLOBAL_GTT); - intel_ring_emit(ring, seqno); - intel_ring_emit(ring, 0); - intel_ring_emit(ring, 0); - } else if (HAS_PIPE_CONTROL(dev)) { - u32 scratch_addr = pc->gtt_offset + 128; + /* + * Workaround qword write incoherence by flushing the + * PIPE_NOTIFY buffers out to memory before requesting + * an interrupt. + */ + ret = intel_ring_begin(ring, 32); + if (ret) + return ret; - /* - * Workaround qword write incoherence by flushing the - * PIPE_NOTIFY buffers out to memory before requesting - * an interrupt. - */ - ret = intel_ring_begin(ring, 32); - if (ret) - return ret; + intel_ring_emit(ring, GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE | + PIPE_CONTROL_WC_FLUSH | PIPE_CONTROL_TC_FLUSH); + intel_ring_emit(ring, pc->gtt_offset | PIPE_CONTROL_GLOBAL_GTT); + intel_ring_emit(ring, seqno); + intel_ring_emit(ring, 0); + PIPE_CONTROL_FLUSH(ring, scratch_addr); + scratch_addr += 128; /* write to separate cachelines */ + PIPE_CONTROL_FLUSH(ring, scratch_addr); + scratch_addr += 128; + PIPE_CONTROL_FLUSH(ring, scratch_addr); + scratch_addr += 128; + PIPE_CONTROL_FLUSH(ring, scratch_addr); + scratch_addr += 128; + PIPE_CONTROL_FLUSH(ring, scratch_addr); + scratch_addr += 128; + PIPE_CONTROL_FLUSH(ring, scratch_addr); + intel_ring_emit(ring, GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE | + PIPE_CONTROL_WC_FLUSH | PIPE_CONTROL_TC_FLUSH | + PIPE_CONTROL_NOTIFY); + intel_ring_emit(ring, pc->gtt_offset | PIPE_CONTROL_GLOBAL_GTT); + intel_ring_emit(ring, seqno); + intel_ring_emit(ring, 0); + intel_ring_advance(ring); - intel_ring_emit(ring, GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE | - PIPE_CONTROL_WC_FLUSH | PIPE_CONTROL_TC_FLUSH); - intel_ring_emit(ring, pc->gtt_offset | PIPE_CONTROL_GLOBAL_GTT); - intel_ring_emit(ring, seqno); - intel_ring_emit(ring, 0); - PIPE_CONTROL_FLUSH(ring, scratch_addr); - scratch_addr += 128; /* write to separate cachelines */ - PIPE_CONTROL_FLUSH(ring, scratch_addr); - scratch_addr += 128; - PIPE_CONTROL_FLUSH(ring, scratch_addr); - scratch_addr += 128; - PIPE_CONTROL_FLUSH(ring, scratch_addr); - scratch_addr += 128; - PIPE_CONTROL_FLUSH(ring, scratch_addr); - scratch_addr += 128; - PIPE_CONTROL_FLUSH(ring, scratch_addr); - intel_ring_emit(ring, GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE | - PIPE_CONTROL_WC_FLUSH | PIPE_CONTROL_TC_FLUSH | - PIPE_CONTROL_NOTIFY); - intel_ring_emit(ring, pc->gtt_offset | PIPE_CONTROL_GLOBAL_GTT); - intel_ring_emit(ring, seqno); - intel_ring_emit(ring, 0); - } else { - ret = intel_ring_begin(ring, 4); - if (ret) - return ret; + *result = seqno; + return 0; +} - intel_ring_emit(ring, MI_STORE_DWORD_INDEX); - intel_ring_emit(ring, I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT); - intel_ring_emit(ring, seqno); +static int +render_ring_add_request(struct intel_ring_buffer *ring, + u32 *result) +{ + struct drm_device *dev = ring->dev; + u32 seqno = i915_gem_get_seqno(dev); + int ret; - intel_ring_emit(ring, MI_USER_INTERRUPT); - } + ret = intel_ring_begin(ring, 4); + if (ret) + return ret; + intel_ring_emit(ring, MI_STORE_DWORD_INDEX); + intel_ring_emit(ring, I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT); + intel_ring_emit(ring, seqno); + intel_ring_emit(ring, MI_USER_INTERRUPT); intel_ring_advance(ring); + *result = seqno; return 0; } static u32 -render_ring_get_seqno(struct intel_ring_buffer *ring) +ring_get_seqno(struct intel_ring_buffer *ring) { - struct drm_device *dev = ring->dev; - if (HAS_PIPE_CONTROL(dev)) { - struct pipe_control *pc = ring->private; - return pc->cpu_page[0]; - } else - return intel_read_status_page(ring, I915_GEM_HWS_INDEX); + return intel_read_status_page(ring, I915_GEM_HWS_INDEX); +} + +static u32 +pc_render_get_seqno(struct intel_ring_buffer *ring) +{ + struct pipe_control *pc = ring->private; + return pc->cpu_page[0]; } static void -render_ring_get_user_irq(struct intel_ring_buffer *ring) +render_ring_get_irq(struct intel_ring_buffer *ring) { struct drm_device *dev = ring->dev; - drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; - unsigned long irqflags; - spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags); - if (dev->irq_enabled && (++ring->user_irq_refcount == 1)) { + if (dev->irq_enabled && ++ring->irq_refcount == 1) { + drm_i915_private_t *dev_priv = dev->dev_private; + unsigned long irqflags; + + spin_lock_irqsave(&dev_priv->irq_lock, irqflags); + if (HAS_PCH_SPLIT(dev)) - ironlake_enable_graphics_irq(dev_priv, GT_PIPE_NOTIFY); + ironlake_enable_graphics_irq(dev_priv, + GT_PIPE_NOTIFY | GT_USER_INTERRUPT); else i915_enable_irq(dev_priv, I915_USER_INTERRUPT); + + spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); } - spin_unlock_irqrestore(&dev_priv->user_irq_lock, irqflags); } static void -render_ring_put_user_irq(struct intel_ring_buffer *ring) +render_ring_put_irq(struct intel_ring_buffer *ring) { struct drm_device *dev = ring->dev; - drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; - unsigned long irqflags; - spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags); - BUG_ON(dev->irq_enabled && ring->user_irq_refcount <= 0); - if (dev->irq_enabled && (--ring->user_irq_refcount == 0)) { + BUG_ON(dev->irq_enabled && ring->irq_refcount == 0); + if (dev->irq_enabled && --ring->irq_refcount == 0) { + drm_i915_private_t *dev_priv = dev->dev_private; + unsigned long irqflags; + + spin_lock_irqsave(&dev_priv->irq_lock, irqflags); if (HAS_PCH_SPLIT(dev)) - ironlake_disable_graphics_irq(dev_priv, GT_PIPE_NOTIFY); + ironlake_disable_graphics_irq(dev_priv, + GT_USER_INTERRUPT | + GT_PIPE_NOTIFY); else i915_disable_irq(dev_priv, I915_USER_INTERRUPT); + spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); } - spin_unlock_irqrestore(&dev_priv->user_irq_lock, irqflags); } void intel_ring_setup_status_page(struct intel_ring_buffer *ring) @@ -459,6 +532,9 @@ bsd_ring_flush(struct intel_ring_buffer *ring, u32 invalidate_domains, u32 flush_domains) { + if ((flush_domains & I915_GEM_DOMAIN_RENDER) == 0) + return; + if (intel_ring_begin(ring, 2) == 0) { intel_ring_emit(ring, MI_FLUSH); intel_ring_emit(ring, MI_NOOP); @@ -491,20 +567,45 @@ ring_add_request(struct intel_ring_buffer *ring, } static void -bsd_ring_get_user_irq(struct intel_ring_buffer *ring) +ring_get_irq(struct intel_ring_buffer *ring, u32 flag) { - /* do nothing */ + struct drm_device *dev = ring->dev; + + if (dev->irq_enabled && ++ring->irq_refcount == 1) { + drm_i915_private_t *dev_priv = dev->dev_private; + unsigned long irqflags; + + spin_lock_irqsave(&dev_priv->irq_lock, irqflags); + ironlake_enable_graphics_irq(dev_priv, flag); + spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); + } } + static void -bsd_ring_put_user_irq(struct intel_ring_buffer *ring) +ring_put_irq(struct intel_ring_buffer *ring, u32 flag) { - /* do nothing */ + struct drm_device *dev = ring->dev; + + if (dev->irq_enabled && --ring->irq_refcount == 0) { + drm_i915_private_t *dev_priv = dev->dev_private; + unsigned long irqflags; + + spin_lock_irqsave(&dev_priv->irq_lock, irqflags); + ironlake_disable_graphics_irq(dev_priv, flag); + spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); + } } -static u32 -ring_status_page_get_seqno(struct intel_ring_buffer *ring) + +static void +bsd_ring_get_irq(struct intel_ring_buffer *ring) { - return intel_read_status_page(ring, I915_GEM_HWS_INDEX); + ring_get_irq(ring, GT_BSD_USER_INTERRUPT); +} +static void +bsd_ring_put_irq(struct intel_ring_buffer *ring) +{ + ring_put_irq(ring, GT_BSD_USER_INTERRUPT); } static int @@ -817,9 +918,9 @@ static const struct intel_ring_buffer render_ring = { .write_tail = ring_write_tail, .flush = render_ring_flush, .add_request = render_ring_add_request, - .get_seqno = render_ring_get_seqno, - .user_irq_get = render_ring_get_user_irq, - .user_irq_put = render_ring_put_user_irq, + .get_seqno = ring_get_seqno, + .irq_get = render_ring_get_irq, + .irq_put = render_ring_put_irq, .dispatch_execbuffer = render_ring_dispatch_execbuffer, .cleanup = render_ring_cleanup, }; @@ -835,9 +936,9 @@ static const struct intel_ring_buffer bsd_ring = { .write_tail = ring_write_tail, .flush = bsd_ring_flush, .add_request = ring_add_request, - .get_seqno = ring_status_page_get_seqno, - .user_irq_get = bsd_ring_get_user_irq, - .user_irq_put = bsd_ring_put_user_irq, + .get_seqno = ring_get_seqno, + .irq_get = bsd_ring_get_irq, + .irq_put = bsd_ring_put_irq, .dispatch_execbuffer = ring_dispatch_execbuffer, }; @@ -868,6 +969,9 @@ static void gen6_ring_flush(struct intel_ring_buffer *ring, u32 invalidate_domains, u32 flush_domains) { + if ((flush_domains & I915_GEM_DOMAIN_RENDER) == 0) + return; + if (intel_ring_begin(ring, 4) == 0) { intel_ring_emit(ring, MI_FLUSH_DW); intel_ring_emit(ring, 0); @@ -895,33 +999,46 @@ gen6_ring_dispatch_execbuffer(struct intel_ring_buffer *ring, return 0; } +static void +gen6_bsd_ring_get_irq(struct intel_ring_buffer *ring) +{ + ring_get_irq(ring, GT_GEN6_BSD_USER_INTERRUPT); +} + +static void +gen6_bsd_ring_put_irq(struct intel_ring_buffer *ring) +{ + ring_put_irq(ring, GT_GEN6_BSD_USER_INTERRUPT); +} + /* ring buffer for Video Codec for Gen6+ */ static const struct intel_ring_buffer gen6_bsd_ring = { - .name = "gen6 bsd ring", - .id = RING_BSD, - .mmio_base = GEN6_BSD_RING_BASE, - .size = 32 * PAGE_SIZE, - .init = init_ring_common, - .write_tail = gen6_bsd_ring_write_tail, - .flush = gen6_ring_flush, - .add_request = ring_add_request, - .get_seqno = ring_status_page_get_seqno, - .user_irq_get = bsd_ring_get_user_irq, - .user_irq_put = bsd_ring_put_user_irq, - .dispatch_execbuffer = gen6_ring_dispatch_execbuffer, + .name = "gen6 bsd ring", + .id = RING_BSD, + .mmio_base = GEN6_BSD_RING_BASE, + .size = 32 * PAGE_SIZE, + .init = init_ring_common, + .write_tail = gen6_bsd_ring_write_tail, + .flush = gen6_ring_flush, + .add_request = gen6_add_request, + .get_seqno = ring_get_seqno, + .irq_get = gen6_bsd_ring_get_irq, + .irq_put = gen6_bsd_ring_put_irq, + .dispatch_execbuffer = gen6_ring_dispatch_execbuffer, }; /* Blitter support (SandyBridge+) */ static void -blt_ring_get_user_irq(struct intel_ring_buffer *ring) +blt_ring_get_irq(struct intel_ring_buffer *ring) { - /* do nothing */ + ring_get_irq(ring, GT_BLT_USER_INTERRUPT); } + static void -blt_ring_put_user_irq(struct intel_ring_buffer *ring) +blt_ring_put_irq(struct intel_ring_buffer *ring) { - /* do nothing */ + ring_put_irq(ring, GT_BLT_USER_INTERRUPT); } @@ -994,6 +1111,9 @@ static void blt_ring_flush(struct intel_ring_buffer *ring, u32 invalidate_domains, u32 flush_domains) { + if ((flush_domains & I915_GEM_DOMAIN_RENDER) == 0) + return; + if (blt_ring_begin(ring, 4) == 0) { intel_ring_emit(ring, MI_FLUSH_DW); intel_ring_emit(ring, 0); @@ -1003,30 +1123,6 @@ static void blt_ring_flush(struct intel_ring_buffer *ring, } } -static int -blt_ring_add_request(struct intel_ring_buffer *ring, - u32 *result) -{ - u32 seqno; - int ret; - - ret = blt_ring_begin(ring, 4); - if (ret) - return ret; - - seqno = i915_gem_get_seqno(ring->dev); - - intel_ring_emit(ring, MI_STORE_DWORD_INDEX); - intel_ring_emit(ring, I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT); - intel_ring_emit(ring, seqno); - intel_ring_emit(ring, MI_USER_INTERRUPT); - intel_ring_advance(ring); - - DRM_DEBUG_DRIVER("%s %d\n", ring->name, seqno); - *result = seqno; - return 0; -} - static void blt_ring_cleanup(struct intel_ring_buffer *ring) { if (!ring->private) @@ -1045,10 +1141,10 @@ static const struct intel_ring_buffer gen6_blt_ring = { .init = blt_ring_init, .write_tail = ring_write_tail, .flush = blt_ring_flush, - .add_request = blt_ring_add_request, - .get_seqno = ring_status_page_get_seqno, - .user_irq_get = blt_ring_get_user_irq, - .user_irq_put = blt_ring_put_user_irq, + .add_request = gen6_add_request, + .get_seqno = ring_get_seqno, + .irq_get = blt_ring_get_irq, + .irq_put = blt_ring_put_irq, .dispatch_execbuffer = gen6_ring_dispatch_execbuffer, .cleanup = blt_ring_cleanup, }; @@ -1056,36 +1152,43 @@ static const struct intel_ring_buffer gen6_blt_ring = { int intel_init_render_ring_buffer(struct drm_device *dev) { drm_i915_private_t *dev_priv = dev->dev_private; + struct intel_ring_buffer *ring = &dev_priv->ring[RCS]; - dev_priv->render_ring = render_ring; + *ring = render_ring; + if (INTEL_INFO(dev)->gen >= 6) { + ring->add_request = gen6_add_request; + } else if (HAS_PIPE_CONTROL(dev)) { + ring->add_request = pc_render_add_request; + ring->get_seqno = pc_render_get_seqno; + } if (!I915_NEED_GFX_HWS(dev)) { - dev_priv->render_ring.status_page.page_addr - = dev_priv->status_page_dmah->vaddr; - memset(dev_priv->render_ring.status_page.page_addr, - 0, PAGE_SIZE); + ring->status_page.page_addr = dev_priv->status_page_dmah->vaddr; + memset(ring->status_page.page_addr, 0, PAGE_SIZE); } - return intel_init_ring_buffer(dev, &dev_priv->render_ring); + return intel_init_ring_buffer(dev, ring); } int intel_init_bsd_ring_buffer(struct drm_device *dev) { drm_i915_private_t *dev_priv = dev->dev_private; + struct intel_ring_buffer *ring = &dev_priv->ring[VCS]; if (IS_GEN6(dev)) - dev_priv->bsd_ring = gen6_bsd_ring; + *ring = gen6_bsd_ring; else - dev_priv->bsd_ring = bsd_ring; + *ring = bsd_ring; - return intel_init_ring_buffer(dev, &dev_priv->bsd_ring); + return intel_init_ring_buffer(dev, ring); } int intel_init_blt_ring_buffer(struct drm_device *dev) { drm_i915_private_t *dev_priv = dev->dev_private; + struct intel_ring_buffer *ring = &dev_priv->ring[BCS]; - dev_priv->blt_ring = gen6_blt_ring; + *ring = gen6_blt_ring; - return intel_init_ring_buffer(dev, &dev_priv->blt_ring); + return intel_init_ring_buffer(dev, ring); } diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index 8e3526777926..6a3822bc6af2 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -1,6 +1,13 @@ #ifndef _INTEL_RINGBUFFER_H_ #define _INTEL_RINGBUFFER_H_ +enum { + RCS = 0x0, + VCS, + BCS, + I915_NUM_RINGS, +}; + struct intel_hw_status_page { u32 __iomem *page_addr; unsigned int gfx_addr; @@ -21,7 +28,10 @@ struct intel_hw_status_page { #define I915_READ_CTL(ring) I915_RING_READ(RING_CTL(ring->mmio_base)) #define I915_WRITE_CTL(ring, val) I915_WRITE(RING_CTL(ring->mmio_base), val) -struct drm_i915_gem_execbuffer2; +#define I915_READ_NOPID(ring) I915_RING_READ(RING_NOPID(ring->mmio_base)) +#define I915_READ_SYNC_0(ring) I915_RING_READ(RING_SYNC_0(ring->mmio_base)) +#define I915_READ_SYNC_1(ring) I915_RING_READ(RING_SYNC_1(ring->mmio_base)) + struct intel_ring_buffer { const char *name; enum intel_ring_id { @@ -42,9 +52,10 @@ struct intel_ring_buffer { u32 irq_seqno; /* last seq seem at irq time */ u32 waiting_seqno; - int user_irq_refcount; - void (*user_irq_get)(struct intel_ring_buffer *ring); - void (*user_irq_put)(struct intel_ring_buffer *ring); + u32 sync_seqno[I915_NUM_RINGS-1]; + u32 irq_refcount; + void (*irq_get)(struct intel_ring_buffer *ring); + void (*irq_put)(struct intel_ring_buffer *ring); int (*init)(struct intel_ring_buffer *ring); @@ -98,6 +109,25 @@ struct intel_ring_buffer { void *private; }; +static inline u32 +intel_ring_sync_index(struct intel_ring_buffer *ring, + struct intel_ring_buffer *other) +{ + int idx; + + /* + * cs -> 0 = vcs, 1 = bcs + * vcs -> 0 = bcs, 1 = cs, + * bcs -> 0 = cs, 1 = vcs. + */ + + idx = (other - ring) - 1; + if (idx < 0) + idx += I915_NUM_RINGS; + + return idx; +} + static inline u32 intel_read_status_page(struct intel_ring_buffer *ring, int reg) @@ -119,6 +149,9 @@ static inline void intel_ring_emit(struct intel_ring_buffer *ring, void intel_ring_advance(struct intel_ring_buffer *ring); u32 intel_ring_get_seqno(struct intel_ring_buffer *ring); +int intel_ring_sync(struct intel_ring_buffer *ring, + struct intel_ring_buffer *to, + u32 seqno); int intel_init_render_ring_buffer(struct drm_device *dev); int intel_init_bsd_ring_buffer(struct drm_device *dev); diff --git a/drivers/gpu/drm/i915/intel_tv.c b/drivers/gpu/drm/i915/intel_tv.c index 2f7681989316..93206e4eaa6f 100644 --- a/drivers/gpu/drm/i915/intel_tv.c +++ b/drivers/gpu/drm/i915/intel_tv.c @@ -1245,10 +1245,11 @@ intel_tv_detect_type (struct intel_tv *intel_tv) int type; /* Disable TV interrupts around load detect or we'll recurse */ - spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags); - i915_disable_pipestat(dev_priv, 0, PIPE_HOTPLUG_INTERRUPT_ENABLE | + spin_lock_irqsave(&dev_priv->irq_lock, irqflags); + i915_disable_pipestat(dev_priv, 0, + PIPE_HOTPLUG_INTERRUPT_ENABLE | PIPE_HOTPLUG_TV_INTERRUPT_ENABLE); - spin_unlock_irqrestore(&dev_priv->user_irq_lock, irqflags); + spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); save_tv_dac = tv_dac = I915_READ(TV_DAC); save_tv_ctl = tv_ctl = I915_READ(TV_CTL); @@ -1301,10 +1302,11 @@ intel_tv_detect_type (struct intel_tv *intel_tv) I915_WRITE(TV_CTL, save_tv_ctl); /* Restore interrupt config */ - spin_lock_irqsave(&dev_priv->user_irq_lock, irqflags); - i915_enable_pipestat(dev_priv, 0, PIPE_HOTPLUG_INTERRUPT_ENABLE | + spin_lock_irqsave(&dev_priv->irq_lock, irqflags); + i915_enable_pipestat(dev_priv, 0, + PIPE_HOTPLUG_INTERRUPT_ENABLE | PIPE_HOTPLUG_TV_INTERRUPT_ENABLE); - spin_unlock_irqrestore(&dev_priv->user_irq_lock, irqflags); + spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); return type; } -- cgit v1.2.3 From f7746f0e1f271fbc64b57c29873c47f73e28e5a0 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sat, 4 Dec 2010 23:48:40 +0000 Subject: drm/i915: Enable self-refresh for Ironlake We disabled this a while ago as it was inexplicably broken. However, it now appears to work... Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/intel_display.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 0b6272a2edfc..83446b55f731 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -3456,7 +3456,7 @@ static void ironlake_update_wm(struct drm_device *dev, * display plane is used. */ tmp = 0; - if (enabled == 1 && /* XXX disabled due to buggy implmentation? */ 0) { + if (enabled == 1) { unsigned long line_time_us; int small, large, plane_fbc; int sr_clock, entries; -- cgit v1.2.3 From 36e9c135e2c485cabb24084834ec29efe928bb5c Mon Sep 17 00:00:00 2001 From: Anssi Hannula Date: Sun, 5 Dec 2010 02:34:15 +0200 Subject: ALSA: hda - use generic hdmi parser for ATI R6xx codec Switch to the generic hdmi parser for codec id 1002:aa01 (ATI R6xx HDMI), as the codec appears to work fine with it. Note that the codec is still limited to stereo output only, despite it reportedly being multichannel capable. Some as of yet unknown quirks will be needed to get that working. Testing was done on 2.6.36 by John Ettedgui. Signed-off-by: Anssi Hannula Tested-by: John Ettedgui Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_hdmi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index d3e49aa5b9ec..f2267cfdd992 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c @@ -1533,7 +1533,7 @@ static struct hda_codec_preset snd_hda_preset_hdmi[] = { { .id = 0x1002793c, .name = "RS600 HDMI", .patch = patch_atihdmi }, { .id = 0x10027919, .name = "RS600 HDMI", .patch = patch_atihdmi }, { .id = 0x1002791a, .name = "RS690/780 HDMI", .patch = patch_atihdmi }, -{ .id = 0x1002aa01, .name = "R6xx HDMI", .patch = patch_atihdmi }, +{ .id = 0x1002aa01, .name = "R6xx HDMI", .patch = patch_generic_hdmi }, { .id = 0x10951390, .name = "SiI1390 HDMI", .patch = patch_generic_hdmi }, { .id = 0x10951392, .name = "SiI1392 HDMI", .patch = patch_generic_hdmi }, { .id = 0x17e80047, .name = "Chrontel HDMI", .patch = patch_generic_hdmi }, -- cgit v1.2.3 From 160b1543cdae83e9f8914ac7afc3d2bd686140af Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sun, 5 Dec 2010 14:54:05 +0000 Subject: drm/i915/dp: Trivial code tidy Locally scope the crtc to where it is used. Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/intel_dp.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 1d8d068bc473..2c9601f2f208 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -1374,7 +1374,6 @@ intel_dp_link_down(struct intel_dp *intel_dp) { struct drm_device *dev = intel_dp->base.base.dev; struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_crtc *intel_crtc = to_intel_crtc(intel_dp->base.base.crtc); uint32_t DP = intel_dp->DP; DRM_DEBUG_KMS("\n"); @@ -1401,6 +1400,8 @@ intel_dp_link_down(struct intel_dp *intel_dp) DP |= DP_LINK_TRAIN_OFF; if (!HAS_PCH_CPT(dev) && (DP & DP_PIPEB_SELECT)) { + struct intel_crtc *intel_crtc = to_intel_crtc(intel_dp->base.base.crtc); + /* Hardware workaround: leaving our transcoder select * set to transcoder B while it's off will prevent the * corresponding HDMI output on transcoder A. @@ -1415,8 +1416,7 @@ intel_dp_link_down(struct intel_dp *intel_dp) /* Changes to enable or select take place the vblank * after being written. */ - intel_wait_for_vblank(intel_dp->base.base.dev, - intel_crtc->pipe); + intel_wait_for_vblank(dev, intel_crtc->pipe); } I915_WRITE(intel_dp->output_reg, DP & ~DP_PORT_EN); -- cgit v1.2.3 From 88f23b8fa3e6357c423af24ec31c661fc12f884b Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sun, 5 Dec 2010 15:08:31 +0000 Subject: drm/i915: Avoid using PIPE_CONTROL on Ironlake The workaround is hideous and we are using the STORE_DWORD on all other generations on all other rings, so use for the gen5 render ring as well. Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_irq.c | 4 +- drivers/gpu/drm/i915/intel_ringbuffer.c | 159 +------------------------------- 2 files changed, 4 insertions(+), 159 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 5e831b7eb3f1..02e4dd82f754 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -349,7 +349,7 @@ static irqreturn_t ironlake_irq_handler(struct drm_device *dev) READ_BREADCRUMB(dev_priv); } - if (gt_iir & (GT_USER_INTERRUPT | GT_PIPE_NOTIFY)) + if (gt_iir & GT_USER_INTERRUPT) notify_ring(dev, &dev_priv->ring[RCS]); if (gt_iir & bsd_usr_interrupt) notify_ring(dev, &dev_priv->ring[VCS]); @@ -1556,7 +1556,7 @@ static int ironlake_irq_postinstall(struct drm_device *dev) GT_BLT_USER_INTERRUPT; else render_irqs = - GT_PIPE_NOTIFY | + GT_USER_INTERRUPT | GT_BSD_USER_INTERRUPT; I915_WRITE(GTIER, render_irqs); POSTING_READ(GTIER); diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index f71db0cf4909..0ee78525959a 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -207,78 +207,6 @@ static int init_ring_common(struct intel_ring_buffer *ring) return 0; } -/* - * 965+ support PIPE_CONTROL commands, which provide finer grained control - * over cache flushing. - */ -struct pipe_control { - struct drm_i915_gem_object *obj; - volatile u32 *cpu_page; - u32 gtt_offset; -}; - -static int -init_pipe_control(struct intel_ring_buffer *ring) -{ - struct pipe_control *pc; - struct drm_i915_gem_object *obj; - int ret; - - if (ring->private) - return 0; - - pc = kmalloc(sizeof(*pc), GFP_KERNEL); - if (!pc) - return -ENOMEM; - - obj = i915_gem_alloc_object(ring->dev, 4096); - if (obj == NULL) { - DRM_ERROR("Failed to allocate seqno page\n"); - ret = -ENOMEM; - goto err; - } - obj->agp_type = AGP_USER_CACHED_MEMORY; - - ret = i915_gem_object_pin(obj, 4096, true); - if (ret) - goto err_unref; - - pc->gtt_offset = obj->gtt_offset; - pc->cpu_page = kmap(obj->pages[0]); - if (pc->cpu_page == NULL) - goto err_unpin; - - pc->obj = obj; - ring->private = pc; - return 0; - -err_unpin: - i915_gem_object_unpin(obj); -err_unref: - drm_gem_object_unreference(&obj->base); -err: - kfree(pc); - return ret; -} - -static void -cleanup_pipe_control(struct intel_ring_buffer *ring) -{ - struct pipe_control *pc = ring->private; - struct drm_i915_gem_object *obj; - - if (!ring->private) - return; - - obj = pc->obj; - kunmap(obj->pages[0]); - i915_gem_object_unpin(obj); - drm_gem_object_unreference(&obj->base); - - kfree(pc); - ring->private = NULL; -} - static int init_render_ring(struct intel_ring_buffer *ring) { struct drm_device *dev = ring->dev; @@ -292,24 +220,9 @@ static int init_render_ring(struct intel_ring_buffer *ring) I915_WRITE(MI_MODE, mode); } - if (INTEL_INFO(dev)->gen >= 6) { - } else if (HAS_PIPE_CONTROL(dev)) { - ret = init_pipe_control(ring); - if (ret) - return ret; - } - return ret; } -static void render_ring_cleanup(struct intel_ring_buffer *ring) -{ - if (!ring->private) - return; - - cleanup_pipe_control(ring); -} - static void update_semaphore(struct intel_ring_buffer *ring, int i, u32 seqno) { @@ -384,62 +297,6 @@ intel_ring_sync(struct intel_ring_buffer *ring, return 0; } -#define PIPE_CONTROL_FLUSH(ring__, addr__) \ -do { \ - intel_ring_emit(ring__, GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE | \ - PIPE_CONTROL_DEPTH_STALL | 2); \ - intel_ring_emit(ring__, (addr__) | PIPE_CONTROL_GLOBAL_GTT); \ - intel_ring_emit(ring__, 0); \ - intel_ring_emit(ring__, 0); \ -} while (0) - -static int -pc_render_add_request(struct intel_ring_buffer *ring, - u32 *result) -{ - struct drm_device *dev = ring->dev; - u32 seqno = i915_gem_get_seqno(dev); - struct pipe_control *pc = ring->private; - u32 scratch_addr = pc->gtt_offset + 128; - int ret; - - /* - * Workaround qword write incoherence by flushing the - * PIPE_NOTIFY buffers out to memory before requesting - * an interrupt. - */ - ret = intel_ring_begin(ring, 32); - if (ret) - return ret; - - intel_ring_emit(ring, GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE | - PIPE_CONTROL_WC_FLUSH | PIPE_CONTROL_TC_FLUSH); - intel_ring_emit(ring, pc->gtt_offset | PIPE_CONTROL_GLOBAL_GTT); - intel_ring_emit(ring, seqno); - intel_ring_emit(ring, 0); - PIPE_CONTROL_FLUSH(ring, scratch_addr); - scratch_addr += 128; /* write to separate cachelines */ - PIPE_CONTROL_FLUSH(ring, scratch_addr); - scratch_addr += 128; - PIPE_CONTROL_FLUSH(ring, scratch_addr); - scratch_addr += 128; - PIPE_CONTROL_FLUSH(ring, scratch_addr); - scratch_addr += 128; - PIPE_CONTROL_FLUSH(ring, scratch_addr); - scratch_addr += 128; - PIPE_CONTROL_FLUSH(ring, scratch_addr); - intel_ring_emit(ring, GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE | - PIPE_CONTROL_WC_FLUSH | PIPE_CONTROL_TC_FLUSH | - PIPE_CONTROL_NOTIFY); - intel_ring_emit(ring, pc->gtt_offset | PIPE_CONTROL_GLOBAL_GTT); - intel_ring_emit(ring, seqno); - intel_ring_emit(ring, 0); - intel_ring_advance(ring); - - *result = seqno; - return 0; -} - static int render_ring_add_request(struct intel_ring_buffer *ring, u32 *result) @@ -468,13 +325,6 @@ ring_get_seqno(struct intel_ring_buffer *ring) return intel_read_status_page(ring, I915_GEM_HWS_INDEX); } -static u32 -pc_render_get_seqno(struct intel_ring_buffer *ring) -{ - struct pipe_control *pc = ring->private; - return pc->cpu_page[0]; -} - static void render_ring_get_irq(struct intel_ring_buffer *ring) { @@ -488,7 +338,7 @@ render_ring_get_irq(struct intel_ring_buffer *ring) if (HAS_PCH_SPLIT(dev)) ironlake_enable_graphics_irq(dev_priv, - GT_PIPE_NOTIFY | GT_USER_INTERRUPT); + GT_USER_INTERRUPT); else i915_enable_irq(dev_priv, I915_USER_INTERRUPT); @@ -509,8 +359,7 @@ render_ring_put_irq(struct intel_ring_buffer *ring) spin_lock_irqsave(&dev_priv->irq_lock, irqflags); if (HAS_PCH_SPLIT(dev)) ironlake_disable_graphics_irq(dev_priv, - GT_USER_INTERRUPT | - GT_PIPE_NOTIFY); + GT_USER_INTERRUPT); else i915_disable_irq(dev_priv, I915_USER_INTERRUPT); spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); @@ -922,7 +771,6 @@ static const struct intel_ring_buffer render_ring = { .irq_get = render_ring_get_irq, .irq_put = render_ring_put_irq, .dispatch_execbuffer = render_ring_dispatch_execbuffer, - .cleanup = render_ring_cleanup, }; /* ring buffer for bit-stream decoder */ @@ -1157,9 +1005,6 @@ int intel_init_render_ring_buffer(struct drm_device *dev) *ring = render_ring; if (INTEL_INFO(dev)->gen >= 6) { ring->add_request = gen6_add_request; - } else if (HAS_PIPE_CONTROL(dev)) { - ring->add_request = pc_render_add_request; - ring->get_seqno = pc_render_get_seqno; } if (!I915_NEED_GFX_HWS(dev)) { -- cgit v1.2.3 From 3c8cdf9b60b98c5b408e2cfbcab3160e25e5af5a Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sun, 5 Dec 2010 16:45:02 +0000 Subject: drm/i915: Power Context register is only available for gen4 mobiles The ability to save the hardware context upon powering down the render clock through PWRCTXA is only available on a couple of gen4 chipsets. Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/intel_display.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index a95c69392afc..aba1c33f6407 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -5973,7 +5973,7 @@ void intel_init_clock_gating(struct drm_device *dev) "Disable RC6\n"); } - if (I915_HAS_RC6(dev) && drm_core_check_feature(dev, DRIVER_MODESET)) { + if (IS_GEN4(dev) && IS_MOBILE(dev)) { if (dev_priv->pwrctx == NULL) dev_priv->pwrctx = intel_alloc_context_page(dev); if (dev_priv->pwrctx) { -- cgit v1.2.3 From e3c4e5dd5ad1993a3687862c982272f8f00cae30 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sun, 5 Dec 2010 16:49:51 +0000 Subject: drm/i915: caps.has_rc6 is no longer used, remove it. Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_debugfs.c | 1 - drivers/gpu/drm/i915/i915_drv.c | 6 +++--- drivers/gpu/drm/i915/i915_drv.h | 2 -- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index aedb02157474..22821994b35a 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -73,7 +73,6 @@ static int i915_capabilities(struct seq_file *m, void *data) B(is_broadwater); B(is_crestline); B(has_fbc); - B(has_rc6); B(has_pipe_cxsr); B(has_hotplug); B(cursor_needs_physical); diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 413a040386a9..91a3ad2cf942 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -111,7 +111,7 @@ static const struct intel_device_info intel_i965g_info = { static const struct intel_device_info intel_i965gm_info = { .gen = 4, .is_crestline = 1, - .is_mobile = 1, .has_fbc = 1, .has_rc6 = 1, .has_hotplug = 1, + .is_mobile = 1, .has_fbc = 1, .has_hotplug = 1, .has_overlay = 1, .supports_tv = 1, }; @@ -130,7 +130,7 @@ static const struct intel_device_info intel_g45_info = { static const struct intel_device_info intel_gm45_info = { .gen = 4, .is_g4x = 1, - .is_mobile = 1, .need_gfx_hws = 1, .has_fbc = 1, .has_rc6 = 1, + .is_mobile = 1, .need_gfx_hws = 1, .has_fbc = 1, .has_pipe_cxsr = 1, .has_hotplug = 1, .supports_tv = 1, .has_bsd_ring = 1, @@ -150,7 +150,7 @@ static const struct intel_device_info intel_ironlake_d_info = { static const struct intel_device_info intel_ironlake_m_info = { .gen = 5, .is_mobile = 1, - .need_gfx_hws = 1, .has_rc6 = 1, .has_hotplug = 1, + .need_gfx_hws = 1, .has_hotplug = 1, .has_fbc = 0, /* disabled due to buggy hardware */ .has_bsd_ring = 1, }; diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 8b19b5806230..d9b54a27ccf8 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -223,7 +223,6 @@ struct intel_device_info { u8 is_broadwater : 1; u8 is_crestline : 1; u8 has_fbc : 1; - u8 has_rc6 : 1; u8 has_pipe_cxsr : 1; u8 has_hotplug : 1; u8 cursor_needs_physical : 1; @@ -930,7 +929,6 @@ enum intel_chip_family { #define HAS_FW_BLC(dev) (INTEL_INFO(dev)->gen > 2) #define HAS_PIPE_CXSR(dev) (INTEL_INFO(dev)->has_pipe_cxsr) #define I915_HAS_FBC(dev) (INTEL_INFO(dev)->has_fbc) -#define I915_HAS_RC6(dev) (INTEL_INFO(dev)->has_rc6) #define HAS_PCH_SPLIT(dev) (IS_GEN5(dev) || IS_GEN6(dev)) #define HAS_PIPE_CONTROL(dev) (IS_GEN5(dev) || IS_GEN6(dev)) -- cgit v1.2.3 From 9b3826bf8420e7280d9fffa233d93a7b85dcb1db Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sun, 5 Dec 2010 17:11:54 +0000 Subject: drm/i915: Ignore fenced commands for gpu access on gen4 Userspace should not have been declaring that it needed fenced GPU access with gen4+ as those GPUs have no fenced commands, but to be on the safe side it is easier to ignore userspace in case they did. Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_gem_execbuffer.c | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index 6fc9cc485781..1b2ceacd64f0 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c @@ -432,6 +432,7 @@ i915_gem_execbuffer_reserve(struct intel_ring_buffer *ring, struct drm_i915_gem_object *obj; struct drm_i915_gem_exec_object2 *entry; int ret, retry; + bool has_fenced_gpu_access = INTEL_INFO(ring->dev)->gen < 4; /* Attempt to pin all of the buffers into the GTT. * This is done in 3 phases: @@ -460,6 +461,7 @@ i915_gem_execbuffer_reserve(struct intel_ring_buffer *ring, } need_fence = + has_fenced_gpu_access && entry->flags & EXEC_OBJECT_NEEDS_FENCE && obj->tiling_mode != I915_TILING_NONE; need_mappable = @@ -484,6 +486,7 @@ i915_gem_execbuffer_reserve(struct intel_ring_buffer *ring, bool need_fence; need_fence = + has_fenced_gpu_access && entry->flags & EXEC_OBJECT_NEEDS_FENCE && obj->tiling_mode != I915_TILING_NONE; @@ -498,18 +501,20 @@ i915_gem_execbuffer_reserve(struct intel_ring_buffer *ring, break; } - if (need_fence) { - ret = i915_gem_object_get_fence(obj, ring, 1); - if (ret) - break; - } else if (entry->flags & EXEC_OBJECT_NEEDS_FENCE && - obj->tiling_mode == I915_TILING_NONE) { - /* XXX pipelined! */ - ret = i915_gem_object_put_fence(obj); - if (ret) - break; + if (has_fenced_gpu_access) { + if (need_fence) { + ret = i915_gem_object_get_fence(obj, ring, 1); + if (ret) + break; + } else if (entry->flags & EXEC_OBJECT_NEEDS_FENCE && + obj->tiling_mode == I915_TILING_NONE) { + /* XXX pipelined! */ + ret = i915_gem_object_put_fence(obj); + if (ret) + break; + } + obj->pending_fenced_gpu_access = need_fence; } - obj->pending_fenced_gpu_access = need_fence; entry->offset = obj->gtt_offset; entry++; -- cgit v1.2.3 From 0cdab21f9a1fca50dd27e488839f5a6578e333b2 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sun, 5 Dec 2010 17:27:06 +0000 Subject: drm/i915: Uncouple render/power ctx before suspending Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_suspend.c | 4 ++- drivers/gpu/drm/i915/intel_display.c | 55 ++++++++++++++++++++---------------- drivers/gpu/drm/i915/intel_drv.h | 3 +- 3 files changed, 36 insertions(+), 26 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_suspend.c b/drivers/gpu/drm/i915/i915_suspend.c index 011325e51e3a..a311809f3c80 100644 --- a/drivers/gpu/drm/i915/i915_suspend.c +++ b/drivers/gpu/drm/i915/i915_suspend.c @@ -820,6 +820,8 @@ int i915_save_state(struct drm_device *dev) if (HAS_PCH_SPLIT(dev)) ironlake_disable_drps(dev); + intel_disable_clock_gating(dev); + /* Cache mode state */ dev_priv->saveCACHE_MODE_0 = I915_READ(CACHE_MODE_0); @@ -863,7 +865,7 @@ int i915_restore_state(struct drm_device *dev) } /* Clock gating state */ - intel_init_clock_gating(dev); + intel_enable_clock_gating(dev); if (HAS_PCH_SPLIT(dev)) { ironlake_enable_drps(dev); diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index aba1c33f6407..31fc1d797f8f 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -5828,7 +5828,7 @@ void intel_init_emon(struct drm_device *dev) dev_priv->corr = (lcfuse & LCFUSE_HIV_MASK); } -void intel_init_clock_gating(struct drm_device *dev) +void intel_enable_clock_gating(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; @@ -5985,6 +5985,33 @@ void intel_init_clock_gating(struct drm_device *dev) } } +void intel_disable_clock_gating(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + + if (dev_priv->renderctx) { + struct drm_i915_gem_object *obj = dev_priv->renderctx; + + I915_WRITE(CCID, 0); + POSTING_READ(CCID); + + i915_gem_object_unpin(obj); + drm_gem_object_unreference(&obj->base); + dev_priv->renderctx = NULL; + } + + if (dev_priv->pwrctx) { + struct drm_i915_gem_object *obj = dev_priv->pwrctx; + + I915_WRITE(PWRCTXA, 0); + POSTING_READ(PWRCTXA); + + i915_gem_object_unpin(obj); + drm_gem_object_unreference(&obj->base); + dev_priv->pwrctx = NULL; + } +} + /* Set up chip specific display functions */ static void intel_init_display(struct drm_device *dev) { @@ -6211,7 +6238,7 @@ void intel_modeset_init(struct drm_device *dev) intel_setup_outputs(dev); - intel_init_clock_gating(dev); + intel_enable_clock_gating(dev); /* Just disable it once at startup */ i915_disable_vga(dev); @@ -6252,31 +6279,11 @@ void intel_modeset_cleanup(struct drm_device *dev) if (dev_priv->display.disable_fbc) dev_priv->display.disable_fbc(dev); - if (dev_priv->renderctx) { - struct drm_i915_gem_object *obj = dev_priv->renderctx; - - I915_WRITE(CCID, obj->gtt_offset &~ CCID_EN); - POSTING_READ(CCID); - - i915_gem_object_unpin(obj); - drm_gem_object_unreference(&obj->base); - dev_priv->renderctx = NULL; - } - - if (dev_priv->pwrctx) { - struct drm_i915_gem_object *obj = dev_priv->pwrctx; - - I915_WRITE(PWRCTXA, obj->gtt_offset &~ PWRCTX_EN); - POSTING_READ(PWRCTXA); - - i915_gem_object_unpin(obj); - drm_gem_object_unreference(&obj->base); - dev_priv->pwrctx = NULL; - } - if (IS_IRONLAKE_M(dev)) ironlake_disable_drps(dev); + intel_disable_clock_gating(dev); + mutex_unlock(&dev->struct_mutex); /* Disable the irq before mode object teardown, for the irq might diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 7273c9e7e0dc..acdea6549ec4 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -294,7 +294,8 @@ extern void intel_crtc_fb_gamma_set(struct drm_crtc *crtc, u16 red, u16 green, u16 blue, int regno); extern void intel_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green, u16 *blue, int regno); -extern void intel_init_clock_gating(struct drm_device *dev); +extern void intel_enable_clock_gating(struct drm_device *dev); +extern void intel_disable_clock_gating(struct drm_device *dev); extern void ironlake_enable_drps(struct drm_device *dev); extern void ironlake_disable_drps(struct drm_device *dev); extern void intel_init_emon(struct drm_device *dev); -- cgit v1.2.3 From 6bda10d152735c22baf1dcd92937420b4b0a359a Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sun, 5 Dec 2010 21:04:18 +0000 Subject: drm/i915: Completely disable fence pipelining. I'm still seeing tiling corruption of PutImage and CopyArea (I think) under mutter on pnv, so obviously the pipelining logic is deeply flawed. Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_gem.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index eeed2e99d247..8685b9279029 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -2484,6 +2484,9 @@ i915_gem_object_get_fence(struct drm_i915_gem_object *obj, struct drm_i915_fence_reg *reg; int ret; + /* XXX disable pipelining. There are bugs. Shocking. */ + pipelined = NULL; + /* Just update our place in the LRU if our fence is getting reused. */ if (obj->fence_reg != I915_FENCE_REG_NONE) { reg = &dev_priv->fence_regs[obj->fence_reg]; @@ -2556,9 +2559,8 @@ i915_gem_object_get_fence(struct drm_i915_gem_object *obj, if (old->tiling_mode) i915_gem_release_mmap(old); - /* XXX The pipelined change over appears to be incoherent. */ ret = i915_gem_object_flush_fence(old, - NULL, //pipelined, + pipelined, interruptible); if (ret) { drm_gem_object_unreference(&old->base); -- cgit v1.2.3 From 1badabd980da3bc09933c14970017067940ecd57 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Sat, 4 Dec 2010 12:41:04 +0000 Subject: ASoC: Add post-CODEC bias level callback for machine driver Currently the machine driver can only do bias level configuration before the CODEC bias level is brought up. This means that the machine cannot do any configuration which depends on the CODEC bias level being maintained. Provide a post-CODEC callback which allows the machine driver to do things like enable the FLL on a CODEC which is brought down to BIAS_OFF when idle. Signed-off-by: Mark Brown Acked-by: Liam Girdwood --- include/sound/soc.h | 2 ++ sound/soc/soc-dapm.c | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/include/sound/soc.h b/include/sound/soc.h index 0eea08e1bdd5..4abc2f8fe77a 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -632,6 +632,8 @@ struct snd_soc_card { /* callbacks */ int (*set_bias_level)(struct snd_soc_card *, enum snd_soc_bias_level level); + int (*set_bias_level_post)(struct snd_soc_card *, + enum snd_soc_bias_level level); long pmdown_time; diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index 6a29d59dabaf..9af2d8ad0895 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -162,6 +162,10 @@ static int snd_soc_dapm_set_bias_level(struct snd_soc_card *card, else dapm->bias_level = level; } + if (ret == 0) { + if (card && card->set_bias_level_post) + ret = card->set_bias_level_post(card, level); + } trace_snd_soc_bias_level_done(card, level); -- cgit v1.2.3 From f7e4bad74e1b18aaff6e89cf2bc4a3868a6ba56e Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Thu, 2 Dec 2010 11:36:51 +0100 Subject: ALSA: virtuoso: initialize unknown GPIO bits Initialize the configuration of some unknown GPIO output bits (that might not be used at all) to be the same as in the Windows driver, just to be sure. Signed-off-by: Clemens Ladisch Signed-off-by: Takashi Iwai --- sound/pci/oxygen/xonar_cs43xx.c | 5 ++++- sound/pci/oxygen/xonar_pcm179x.c | 8 ++++++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/sound/pci/oxygen/xonar_cs43xx.c b/sound/pci/oxygen/xonar_cs43xx.c index aa27c31049af..ae4e5b512483 100644 --- a/sound/pci/oxygen/xonar_cs43xx.c +++ b/sound/pci/oxygen/xonar_cs43xx.c @@ -63,6 +63,7 @@ #define GPI_EXT_POWER 0x01 #define GPIO_D1_OUTPUT_ENABLE 0x0001 #define GPIO_D1_FRONT_PANEL 0x0002 +#define GPIO_D1_MAGIC 0x00c0 #define GPIO_D1_INPUT_ROUTE 0x0100 #define I2C_DEVICE_CS4398 0x9e /* 10011, AD1=1, AD0=1, /W=0 */ @@ -169,7 +170,9 @@ static void xonar_d1_init(struct oxygen *chip) cs43xx_registers_init(chip); oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL, - GPIO_D1_FRONT_PANEL | GPIO_D1_INPUT_ROUTE); + GPIO_D1_FRONT_PANEL | + GPIO_D1_MAGIC | + GPIO_D1_INPUT_ROUTE); oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA, GPIO_D1_FRONT_PANEL | GPIO_D1_INPUT_ROUTE); diff --git a/sound/pci/oxygen/xonar_pcm179x.c b/sound/pci/oxygen/xonar_pcm179x.c index d491fd6c0be2..fe4b2655a252 100644 --- a/sound/pci/oxygen/xonar_pcm179x.c +++ b/sound/pci/oxygen/xonar_pcm179x.c @@ -167,12 +167,14 @@ #define GPIO_INPUT_ROUTE 0x0100 #define GPIO_HDAV_OUTPUT_ENABLE 0x0001 +#define GPIO_HDAV_MAGIC 0x00c0 #define GPIO_DB_MASK 0x0030 #define GPIO_DB_H6 0x0000 #define GPIO_ST_OUTPUT_ENABLE 0x0001 #define GPIO_ST_HP_REAR 0x0002 +#define GPIO_ST_MAGIC 0x0040 #define GPIO_ST_HP 0x0080 #define I2C_DEVICE_PCM1796(i) (0x98 + ((i) << 1)) /* 10011, ii, /W=0 */ @@ -350,7 +352,8 @@ static void xonar_hdav_init(struct oxygen *chip) pcm1796_init(chip); - oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL, GPIO_INPUT_ROUTE); + oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL, + GPIO_HDAV_MAGIC | GPIO_INPUT_ROUTE); oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA, GPIO_INPUT_ROUTE); xonar_init_cs53x1(chip); @@ -381,7 +384,8 @@ static void xonar_st_init_common(struct oxygen *chip) pcm1796_init(chip); oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL, - GPIO_INPUT_ROUTE | GPIO_ST_HP_REAR | GPIO_ST_HP); + GPIO_INPUT_ROUTE | GPIO_ST_HP_REAR | + GPIO_ST_MAGIC | GPIO_ST_HP); oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA, GPIO_INPUT_ROUTE | GPIO_ST_HP_REAR | GPIO_ST_HP); -- cgit v1.2.3 From 2509ec623d44320419d44d4060dbedf91b8d192d Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Thu, 2 Dec 2010 11:38:06 +0100 Subject: ALSA: virtuoso: add HDMI enable switch for HDAV1.3 The GPIO bit that enables analog output on the Xonar HDAV1.3 also disables the HDMI audio output, so we better add a switch for it. Hopefully, this is sufficient to make the HDMI output work. Signed-off-by: Clemens Ladisch Signed-off-by: Takashi Iwai --- sound/pci/Kconfig | 2 +- sound/pci/oxygen/xonar.h | 2 ++ sound/pci/oxygen/xonar_lib.c | 6 ++++-- sound/pci/oxygen/xonar_pcm179x.c | 19 ++++++++++++++++++- 4 files changed, 25 insertions(+), 4 deletions(-) diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig index 5add96bdf172..7b2678a25ca0 100644 --- a/sound/pci/Kconfig +++ b/sound/pci/Kconfig @@ -817,7 +817,7 @@ config SND_VIRTUOSO Say Y here to include support for sound cards based on the Asus AV66/AV100/AV200 chips, i.e., Xonar D1, DX, D2, D2X, DS, Essence ST (Deluxe), and Essence STX. - Support for the HDAV1.3 (Deluxe) is incomplete; for the + Support for the HDAV1.3 (Deluxe) is experimental; for the HDAV1.3 Slim and Xense, missing. To compile this driver as a module, choose M here: the module diff --git a/sound/pci/oxygen/xonar.h b/sound/pci/oxygen/xonar.h index b35343b0a9a5..0434c207e811 100644 --- a/sound/pci/oxygen/xonar.h +++ b/sound/pci/oxygen/xonar.h @@ -24,6 +24,8 @@ void xonar_init_ext_power(struct oxygen *chip); void xonar_init_cs53x1(struct oxygen *chip); void xonar_set_cs53x1_params(struct oxygen *chip, struct snd_pcm_hw_params *params); + +#define XONAR_GPIO_BIT_INVERT (1 << 16) int xonar_gpio_bit_switch_get(struct snd_kcontrol *ctl, struct snd_ctl_elem_value *value); int xonar_gpio_bit_switch_put(struct snd_kcontrol *ctl, diff --git a/sound/pci/oxygen/xonar_lib.c b/sound/pci/oxygen/xonar_lib.c index b3ff71316653..0ebe7f5916f9 100644 --- a/sound/pci/oxygen/xonar_lib.c +++ b/sound/pci/oxygen/xonar_lib.c @@ -104,9 +104,10 @@ int xonar_gpio_bit_switch_get(struct snd_kcontrol *ctl, { struct oxygen *chip = ctl->private_data; u16 bit = ctl->private_value; + bool invert = ctl->private_value & XONAR_GPIO_BIT_INVERT; value->value.integer.value[0] = - !!(oxygen_read16(chip, OXYGEN_GPIO_DATA) & bit); + !!(oxygen_read16(chip, OXYGEN_GPIO_DATA) & bit) ^ invert; return 0; } @@ -115,12 +116,13 @@ int xonar_gpio_bit_switch_put(struct snd_kcontrol *ctl, { struct oxygen *chip = ctl->private_data; u16 bit = ctl->private_value; + bool invert = ctl->private_value & XONAR_GPIO_BIT_INVERT; u16 old_bits, new_bits; int changed; spin_lock_irq(&chip->reg_lock); old_bits = oxygen_read16(chip, OXYGEN_GPIO_DATA); - if (value->value.integer.value[0]) + if (!!value->value.integer.value[0] ^ invert) new_bits = old_bits | bit; else new_bits = old_bits & ~bit; diff --git a/sound/pci/oxygen/xonar_pcm179x.c b/sound/pci/oxygen/xonar_pcm179x.c index fe4b2655a252..3850834f989c 100644 --- a/sound/pci/oxygen/xonar_pcm179x.c +++ b/sound/pci/oxygen/xonar_pcm179x.c @@ -776,6 +776,15 @@ static const struct snd_kcontrol_new os_128_control = { .put = os_128_put, }; +static const struct snd_kcontrol_new hdav_hdmi_control = { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "HDMI Playback Switch", + .info = snd_ctl_boolean_mono_info, + .get = xonar_gpio_bit_switch_get, + .put = xonar_gpio_bit_switch_put, + .private_value = GPIO_HDAV_OUTPUT_ENABLE | XONAR_GPIO_BIT_INVERT, +}; + static int st_output_switch_info(struct snd_kcontrol *ctl, struct snd_ctl_elem_info *info) { @@ -960,7 +969,15 @@ static int xonar_d2_mixer_init(struct oxygen *chip) static int xonar_hdav_mixer_init(struct oxygen *chip) { - return add_pcm1796_controls(chip); + int err; + + err = snd_ctl_add(chip->card, snd_ctl_new1(&hdav_hdmi_control, chip)); + if (err < 0) + return err; + err = add_pcm1796_controls(chip); + if (err < 0) + return err; + return 0; } static int xonar_st_mixer_init(struct oxygen *chip) -- cgit v1.2.3 From e96f38f732d24515792296b3738842934c985539 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Thu, 2 Dec 2010 11:39:34 +0100 Subject: ALSA: virtuoso: fix front panel routing for D1/DX/ST(X) The "Front Panel" switch on the Xonar D1/DX actually switches only the output direction, so mark it appropriately. The front panel microphone is controlled by the FMIC2MIC bit of the CM9780. It was unconditionally enabled on the D1/DX and never set on the ST(X); add a control for it. Selecting the front panel microphone as source does not actually disable the microphone jack, but this is bug-compatible with the Windows driver, and users rely on it. Signed-off-by: Clemens Ladisch Signed-off-by: Takashi Iwai --- sound/pci/oxygen/oxygen.h | 1 + sound/pci/oxygen/oxygen_mixer.c | 55 ++++++++++++++++++++++++++++++++++++++++ sound/pci/oxygen/xonar_cs43xx.c | 9 +++---- sound/pci/oxygen/xonar_pcm179x.c | 3 ++- 4 files changed, 62 insertions(+), 6 deletions(-) diff --git a/sound/pci/oxygen/oxygen.h b/sound/pci/oxygen/oxygen.h index 7d5222caa0a9..cf9054ecb97b 100644 --- a/sound/pci/oxygen/oxygen.h +++ b/sound/pci/oxygen/oxygen.h @@ -35,6 +35,7 @@ #define MIDI_OUTPUT 0x0800 #define MIDI_INPUT 0x1000 #define AC97_CD_INPUT 0x2000 +#define AC97_FMIC_SWITCH 0x4000 enum { CONTROL_SPDIF_PCM, diff --git a/sound/pci/oxygen/oxygen_mixer.c b/sound/pci/oxygen/oxygen_mixer.c index 2849b36f5f7e..605e84b9e1ec 100644 --- a/sound/pci/oxygen/oxygen_mixer.c +++ b/sound/pci/oxygen/oxygen_mixer.c @@ -644,6 +644,51 @@ static int ac97_volume_put(struct snd_kcontrol *ctl, return change; } +static int mic_fmic_source_info(struct snd_kcontrol *ctl, + struct snd_ctl_elem_info *info) +{ + static const char *const names[] = { "Mic Jack", "Front Panel" }; + + info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; + info->count = 1; + info->value.enumerated.items = 2; + info->value.enumerated.item &= 1; + strcpy(info->value.enumerated.name, names[info->value.enumerated.item]); + return 0; +} + +static int mic_fmic_source_get(struct snd_kcontrol *ctl, + struct snd_ctl_elem_value *value) +{ + struct oxygen *chip = ctl->private_data; + + mutex_lock(&chip->mutex); + value->value.enumerated.item[0] = + !!(oxygen_read_ac97(chip, 0, CM9780_JACK) & CM9780_FMIC2MIC); + mutex_unlock(&chip->mutex); + return 0; +} + +static int mic_fmic_source_put(struct snd_kcontrol *ctl, + struct snd_ctl_elem_value *value) +{ + struct oxygen *chip = ctl->private_data; + u16 oldreg, newreg; + int change; + + mutex_lock(&chip->mutex); + oldreg = oxygen_read_ac97(chip, 0, CM9780_JACK); + if (value->value.enumerated.item[0]) + newreg = oldreg | CM9780_FMIC2MIC; + else + newreg = oldreg & ~CM9780_FMIC2MIC; + change = newreg != oldreg; + if (change) + oxygen_write_ac97(chip, 0, CM9780_JACK, newreg); + mutex_unlock(&chip->mutex); + return change; +} + static int ac97_fp_rec_volume_info(struct snd_kcontrol *ctl, struct snd_ctl_elem_info *info) { @@ -908,6 +953,13 @@ static const struct snd_kcontrol_new ac97_controls[] = { AC97_VOLUME("Mic Capture Volume", 0, AC97_MIC, 0), AC97_SWITCH("Mic Capture Switch", 0, AC97_MIC, 15, 1), AC97_SWITCH("Mic Boost (+20dB)", 0, AC97_MIC, 6, 0), + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Mic Source Capture Enum", + .info = mic_fmic_source_info, + .get = mic_fmic_source_get, + .put = mic_fmic_source_put, + }, AC97_SWITCH("Line Capture Switch", 0, AC97_LINE, 15, 1), AC97_VOLUME("CD Capture Volume", 0, AC97_CD, 1), AC97_SWITCH("CD Capture Switch", 0, AC97_CD, 15, 1), @@ -972,6 +1024,9 @@ static int add_controls(struct oxygen *chip, if (!strcmp(template.name, "Stereo Upmixing") && chip->model.dac_channels == 2) continue; + if (!strcmp(template.name, "Mic Source Capture Enum") && + !(chip->model.device_config & AC97_FMIC_SWITCH)) + continue; if (!strncmp(template.name, "CD Capture ", 11) && !(chip->model.device_config & AC97_CD_INPUT)) continue; diff --git a/sound/pci/oxygen/xonar_cs43xx.c b/sound/pci/oxygen/xonar_cs43xx.c index ae4e5b512483..501fe45bbdce 100644 --- a/sound/pci/oxygen/xonar_cs43xx.c +++ b/sound/pci/oxygen/xonar_cs43xx.c @@ -28,7 +28,7 @@ * GPI 0 <- external power present (DX only) * * GPIO 0 -> enable output to speakers - * GPIO 1 -> enable front panel I/O + * GPIO 1 -> route output to front panel * GPIO 2 -> M0 of CS5361 * GPIO 3 -> M1 of CS5361 * GPIO 8 -> route input jack to line-in (0) or mic-in (1) @@ -176,8 +176,6 @@ static void xonar_d1_init(struct oxygen *chip) oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA, GPIO_D1_FRONT_PANEL | GPIO_D1_INPUT_ROUTE); - oxygen_ac97_set_bits(chip, 0, CM9780_JACK, CM9780_FMIC2MIC); - xonar_init_cs53x1(chip); xonar_enable_output(chip); @@ -287,7 +285,7 @@ static void update_cs43xx_center_lfe_mix(struct oxygen *chip, bool mixed) static const struct snd_kcontrol_new front_panel_switch = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Front Panel Switch", + .name = "Front Panel Playback Switch", .info = snd_ctl_boolean_mono_info, .get = xonar_gpio_bit_switch_get, .put = xonar_gpio_bit_switch_put, @@ -402,7 +400,8 @@ static const struct oxygen_model model_xonar_d1 = { .model_data_size = sizeof(struct xonar_cs43xx), .device_config = PLAYBACK_0_TO_I2S | PLAYBACK_1_TO_SPDIF | - CAPTURE_0_FROM_I2S_2, + CAPTURE_0_FROM_I2S_2 | + AC97_FMIC_SWITCH, .dac_channels = 8, .dac_volume_min = 127 - 60, .dac_volume_max = 127, diff --git a/sound/pci/oxygen/xonar_pcm179x.c b/sound/pci/oxygen/xonar_pcm179x.c index 3850834f989c..5193d73a916d 100644 --- a/sound/pci/oxygen/xonar_pcm179x.c +++ b/sound/pci/oxygen/xonar_pcm179x.c @@ -1079,7 +1079,8 @@ static const struct oxygen_model model_xonar_st = { .model_data_size = sizeof(struct xonar_pcm179x), .device_config = PLAYBACK_0_TO_I2S | PLAYBACK_1_TO_SPDIF | - CAPTURE_0_FROM_I2S_2, + CAPTURE_0_FROM_I2S_2 | + AC97_FMIC_SWITCH, .dac_channels = 2, .dac_volume_min = 255 - 2*60, .dac_volume_max = 255, -- cgit v1.2.3 From 9719fcaa6a82be59a2d7767725e5cd8233c6a387 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Thu, 2 Dec 2010 11:41:10 +0100 Subject: ALSA: oxygen: allow to dump codec registers To help with debugging, add the registers of the model-specific codecs to the controller and AC97 register dump in the proc file. Signed-off-by: Clemens Ladisch Signed-off-by: Takashi Iwai --- sound/pci/oxygen/oxygen.c | 38 +++++++++++++++++++++++++++ sound/pci/oxygen/oxygen.h | 3 +++ sound/pci/oxygen/oxygen_lib.c | 10 ++++--- sound/pci/oxygen/xonar_cs43xx.c | 25 ++++++++++++++++++ sound/pci/oxygen/xonar_pcm179x.c | 56 +++++++++++++++++++++++++++++++++++----- sound/pci/oxygen/xonar_wm87x6.c | 30 +++++++++++++++++++++ 6 files changed, 151 insertions(+), 11 deletions(-) diff --git a/sound/pci/oxygen/oxygen.c b/sound/pci/oxygen/oxygen.c index ea8fffefad9f..a58e448fc1bf 100644 --- a/sound/pci/oxygen/oxygen.c +++ b/sound/pci/oxygen/oxygen.c @@ -41,6 +41,7 @@ #include #include #include +#include #include #include #include @@ -518,6 +519,39 @@ static int generic_wm8785_mixer_init(struct oxygen *chip) return 0; } +static void dump_ak4396_registers(struct oxygen *chip, + struct snd_info_buffer *buffer) +{ + struct generic_data *data = chip->model_data; + unsigned int dac, i; + + for (dac = 0; dac < data->dacs; ++dac) { + snd_iprintf(buffer, "\nAK4396 %u:", dac + 1); + for (i = 0; i < 5; ++i) + snd_iprintf(buffer, " %02x", data->ak4396_regs[dac][i]); + } + snd_iprintf(buffer, "\n"); +} + +static void dump_wm8785_registers(struct oxygen *chip, + struct snd_info_buffer *buffer) +{ + struct generic_data *data = chip->model_data; + unsigned int i; + + snd_iprintf(buffer, "\nWM8785:"); + for (i = 0; i < 3; ++i) + snd_iprintf(buffer, " %03x", data->wm8785_regs[i]); + snd_iprintf(buffer, "\n"); +} + +static void dump_oxygen_registers(struct oxygen *chip, + struct snd_info_buffer *buffer) +{ + dump_ak4396_registers(chip, buffer); + dump_wm8785_registers(chip, buffer); +} + static const DECLARE_TLV_DB_LINEAR(ak4396_db_scale, TLV_DB_GAIN_MUTE, 0); static const struct oxygen_model model_generic = { @@ -533,6 +567,7 @@ static const struct oxygen_model model_generic = { .set_adc_params = set_wm8785_params, .update_dac_volume = update_ak4396_volume, .update_dac_mute = update_ak4396_mute, + .dump_registers = dump_oxygen_registers, .dac_tlv = ak4396_db_scale, .model_data_size = sizeof(struct generic_data), .device_config = PLAYBACK_0_TO_I2S | @@ -561,6 +596,7 @@ static int __devinit get_oxygen_model(struct oxygen *chip, chip->model.mixer_init = generic_mixer_init; chip->model.resume = meridian_resume; chip->model.set_adc_params = set_ak5385_params; + chip->model.dump_registers = dump_ak4396_registers; chip->model.device_config = PLAYBACK_0_TO_I2S | PLAYBACK_1_TO_SPDIF | CAPTURE_0_FROM_I2S_2 | @@ -579,6 +615,7 @@ static int __devinit get_oxygen_model(struct oxygen *chip, chip->model.suspend = claro_suspend; chip->model.resume = claro_resume; chip->model.set_adc_params = set_ak5385_params; + chip->model.dump_registers = dump_ak4396_registers; chip->model.device_config = PLAYBACK_0_TO_I2S | PLAYBACK_1_TO_SPDIF | CAPTURE_0_FROM_I2S_2 | @@ -595,6 +632,7 @@ static int __devinit get_oxygen_model(struct oxygen *chip, chip->model.resume = stereo_resume; chip->model.mixer_init = generic_mixer_init; chip->model.set_adc_params = set_no_params; + chip->model.dump_registers = dump_ak4396_registers; chip->model.device_config = PLAYBACK_0_TO_I2S | PLAYBACK_1_TO_SPDIF; if (id->driver_data == MODEL_FANTASIA) diff --git a/sound/pci/oxygen/oxygen.h b/sound/pci/oxygen/oxygen.h index cf9054ecb97b..b8fbc15b89a3 100644 --- a/sound/pci/oxygen/oxygen.h +++ b/sound/pci/oxygen/oxygen.h @@ -66,6 +66,7 @@ struct snd_pcm_hardware; struct snd_pcm_hw_params; struct snd_kcontrol_new; struct snd_rawmidi; +struct snd_info_buffer; struct oxygen; struct oxygen_model { @@ -93,6 +94,8 @@ struct oxygen_model { void (*uart_input)(struct oxygen *chip); void (*ac97_switch)(struct oxygen *chip, unsigned int reg, unsigned int mute); + void (*dump_registers)(struct oxygen *chip, + struct snd_info_buffer *buffer); const unsigned int *dac_tlv; unsigned long private_data; size_t model_data_size; diff --git a/sound/pci/oxygen/oxygen_lib.c b/sound/pci/oxygen/oxygen_lib.c index 2e6579962217..e581e7ab216c 100644 --- a/sound/pci/oxygen/oxygen_lib.c +++ b/sound/pci/oxygen/oxygen_lib.c @@ -202,7 +202,7 @@ static void oxygen_proc_read(struct snd_info_entry *entry, struct oxygen *chip = entry->private_data; int i, j; - snd_iprintf(buffer, "CMI8788\n\n"); + snd_iprintf(buffer, "CMI8788:\n"); for (i = 0; i < OXYGEN_IO_SIZE; i += 0x10) { snd_iprintf(buffer, "%02x:", i); for (j = 0; j < 0x10; ++j) @@ -212,7 +212,7 @@ static void oxygen_proc_read(struct snd_info_entry *entry, if (mutex_lock_interruptible(&chip->mutex) < 0) return; if (chip->has_ac97_0) { - snd_iprintf(buffer, "\nAC97\n"); + snd_iprintf(buffer, "\nAC97:\n"); for (i = 0; i < 0x80; i += 0x10) { snd_iprintf(buffer, "%02x:", i); for (j = 0; j < 0x10; j += 2) @@ -222,7 +222,7 @@ static void oxygen_proc_read(struct snd_info_entry *entry, } } if (chip->has_ac97_1) { - snd_iprintf(buffer, "\nAC97 2\n"); + snd_iprintf(buffer, "\nAC97 2:\n"); for (i = 0; i < 0x80; i += 0x10) { snd_iprintf(buffer, "%02x:", i); for (j = 0; j < 0x10; j += 2) @@ -232,13 +232,15 @@ static void oxygen_proc_read(struct snd_info_entry *entry, } } mutex_unlock(&chip->mutex); + if (chip->model.dump_registers) + chip->model.dump_registers(chip, buffer); } static void oxygen_proc_init(struct oxygen *chip) { struct snd_info_entry *entry; - if (!snd_card_proc_new(chip->card, "cmi8788", &entry)) + if (!snd_card_proc_new(chip->card, "oxygen", &entry)) snd_info_set_text_ops(entry, chip, oxygen_proc_read); } #else diff --git a/sound/pci/oxygen/xonar_cs43xx.c b/sound/pci/oxygen/xonar_cs43xx.c index 501fe45bbdce..092addb15e13 100644 --- a/sound/pci/oxygen/xonar_cs43xx.c +++ b/sound/pci/oxygen/xonar_cs43xx.c @@ -381,6 +381,30 @@ static int xonar_d1_mixer_init(struct oxygen *chip) return 0; } +static void dump_cs4362a_registers(struct xonar_cs43xx *data, + struct snd_info_buffer *buffer) +{ + unsigned int i; + + snd_iprintf(buffer, "\nCS4362A:"); + for (i = 1; i <= 14; ++i) + snd_iprintf(buffer, " %02x", data->cs4362a_regs[i]); + snd_iprintf(buffer, "\n"); +} + +static void dump_d1_registers(struct oxygen *chip, + struct snd_info_buffer *buffer) +{ + struct xonar_cs43xx *data = chip->model_data; + unsigned int i; + + snd_iprintf(buffer, "\nCS4398: 7?"); + for (i = 2; i <= 8; ++i) + snd_iprintf(buffer, " %02x", data->cs4398_regs[i]); + snd_iprintf(buffer, "\n"); + dump_cs4362a_registers(data, buffer); +} + static const struct oxygen_model model_xonar_d1 = { .longname = "Asus Virtuoso 100", .chip = "AV200", @@ -396,6 +420,7 @@ static const struct oxygen_model model_xonar_d1 = { .update_dac_mute = update_cs43xx_mute, .update_center_lfe_mix = update_cs43xx_center_lfe_mix, .ac97_switch = xonar_d1_line_mic_ac97_switch, + .dump_registers = dump_d1_registers, .dac_tlv = cs4362a_db_scale, .model_data_size = sizeof(struct xonar_cs43xx), .device_config = PLAYBACK_0_TO_I2S | diff --git a/sound/pci/oxygen/xonar_pcm179x.c b/sound/pci/oxygen/xonar_pcm179x.c index 5193d73a916d..dc69fddf2e6e 100644 --- a/sound/pci/oxygen/xonar_pcm179x.c +++ b/sound/pci/oxygen/xonar_pcm179x.c @@ -150,6 +150,7 @@ #include #include #include +#include #include #include #include @@ -192,7 +193,7 @@ struct xonar_pcm179x { bool hp_active; s8 hp_gain_offset; bool has_cs2000; - u8 cs2000_fun_cfg_1; + u8 cs2000_regs[0x1f]; }; struct xonar_hdav { @@ -251,16 +252,14 @@ static void cs2000_write(struct oxygen *chip, u8 reg, u8 value) struct xonar_pcm179x *data = chip->model_data; oxygen_write_i2c(chip, I2C_DEVICE_CS2000, reg, value); - if (reg == CS2000_FUN_CFG_1) - data->cs2000_fun_cfg_1 = value; + data->cs2000_regs[reg] = value; } static void cs2000_write_cached(struct oxygen *chip, u8 reg, u8 value) { struct xonar_pcm179x *data = chip->model_data; - if (reg != CS2000_FUN_CFG_1 || - value != data->cs2000_fun_cfg_1) + if (value != data->cs2000_regs[reg]) cs2000_write(chip, reg, value); } @@ -414,7 +413,8 @@ static void cs2000_registers_init(struct oxygen *chip) cs2000_write(chip, CS2000_RATIO_0 + 1, 0x10); cs2000_write(chip, CS2000_RATIO_0 + 2, 0x00); cs2000_write(chip, CS2000_RATIO_0 + 3, 0x00); - cs2000_write(chip, CS2000_FUN_CFG_1, data->cs2000_fun_cfg_1); + cs2000_write(chip, CS2000_FUN_CFG_1, + data->cs2000_regs[CS2000_FUN_CFG_1]); cs2000_write(chip, CS2000_FUN_CFG_2, 0); cs2000_write(chip, CS2000_GLOBAL_CFG, CS2000_EN_DEV_CFG_2); } @@ -425,7 +425,7 @@ static void xonar_st_init(struct oxygen *chip) data->generic.anti_pop_delay = 100; data->has_cs2000 = 1; - data->cs2000_fun_cfg_1 = CS2000_REF_CLK_DIV_1; + data->cs2000_regs[CS2000_FUN_CFG_1] = CS2000_REF_CLK_DIV_1; oxygen_write16(chip, OXYGEN_I2S_A_FORMAT, OXYGEN_RATE_48000 | OXYGEN_I2S_FORMAT_I2S | @@ -997,6 +997,45 @@ static int xonar_st_mixer_init(struct oxygen *chip) return 0; } +static void dump_pcm1796_registers(struct oxygen *chip, + struct snd_info_buffer *buffer) +{ + struct xonar_pcm179x *data = chip->model_data; + unsigned int dac, i; + + for (dac = 0; dac < data->dacs; ++dac) { + snd_iprintf(buffer, "\nPCM1796 %u:", dac + 1); + for (i = 0; i < 5; ++i) + snd_iprintf(buffer, " %02x", + data->pcm1796_regs[dac][i]); + } + snd_iprintf(buffer, "\n"); +} + +static void dump_cs2000_registers(struct oxygen *chip, + struct snd_info_buffer *buffer) +{ + struct xonar_pcm179x *data = chip->model_data; + unsigned int i; + + if (data->has_cs2000) { + snd_iprintf(buffer, "\nCS2000:\n00: "); + for (i = 1; i < 0x10; ++i) + snd_iprintf(buffer, " %02x", data->cs2000_regs[i]); + snd_iprintf(buffer, "\n10:"); + for (i = 0x10; i < 0x1f; ++i) + snd_iprintf(buffer, " %02x", data->cs2000_regs[i]); + snd_iprintf(buffer, "\n"); + } +} + +static void dump_st_registers(struct oxygen *chip, + struct snd_info_buffer *buffer) +{ + dump_pcm1796_registers(chip, buffer); + dump_cs2000_registers(chip, buffer); +} + static const struct oxygen_model model_xonar_d2 = { .longname = "Asus Virtuoso 200", .chip = "AV200", @@ -1011,6 +1050,7 @@ static const struct oxygen_model model_xonar_d2 = { .set_adc_params = xonar_set_cs53x1_params, .update_dac_volume = update_pcm1796_volume, .update_dac_mute = update_pcm1796_mute, + .dump_registers = dump_pcm1796_registers, .dac_tlv = pcm1796_db_scale, .model_data_size = sizeof(struct xonar_pcm179x), .device_config = PLAYBACK_0_TO_I2S | @@ -1046,6 +1086,7 @@ static const struct oxygen_model model_xonar_hdav = { .update_dac_mute = update_pcm1796_mute, .uart_input = xonar_hdmi_uart_input, .ac97_switch = xonar_line_mic_ac97_switch, + .dump_registers = dump_pcm1796_registers, .dac_tlv = pcm1796_db_scale, .model_data_size = sizeof(struct xonar_hdav), .device_config = PLAYBACK_0_TO_I2S | @@ -1075,6 +1116,7 @@ static const struct oxygen_model model_xonar_st = { .update_dac_volume = update_pcm1796_volume, .update_dac_mute = update_pcm1796_mute, .ac97_switch = xonar_line_mic_ac97_switch, + .dump_registers = dump_st_registers, .dac_tlv = pcm1796_db_scale, .model_data_size = sizeof(struct xonar_pcm179x), .device_config = PLAYBACK_0_TO_I2S | diff --git a/sound/pci/oxygen/xonar_wm87x6.c b/sound/pci/oxygen/xonar_wm87x6.c index 200f7601276f..2b5e69b64708 100644 --- a/sound/pci/oxygen/xonar_wm87x6.c +++ b/sound/pci/oxygen/xonar_wm87x6.c @@ -42,6 +42,7 @@ #include #include #include +#include #include #include #include @@ -1062,6 +1063,34 @@ static int xonar_ds_mixer_init(struct oxygen *chip) return 0; } +static void dump_wm8776_registers(struct oxygen *chip, + struct snd_info_buffer *buffer) +{ + struct xonar_wm87x6 *data = chip->model_data; + unsigned int i; + + snd_iprintf(buffer, "\nWM8776:\n00:"); + for (i = 0; i < 0x10; ++i) + snd_iprintf(buffer, " %03x", data->wm8776_regs[i]); + snd_iprintf(buffer, "\n10:"); + for (i = 0x10; i < 0x17; ++i) + snd_iprintf(buffer, " %03x", data->wm8776_regs[i]); + snd_iprintf(buffer, "\n"); +} + +static void dump_wm87x6_registers(struct oxygen *chip, + struct snd_info_buffer *buffer) +{ + struct xonar_wm87x6 *data = chip->model_data; + unsigned int i; + + dump_wm8776_registers(chip, buffer); + snd_iprintf(buffer, "\nWM8766:\n00:"); + for (i = 0; i < 0x10; ++i) + snd_iprintf(buffer, " %03x", data->wm8766_regs[i]); + snd_iprintf(buffer, "\n"); +} + static const struct oxygen_model model_xonar_ds = { .shortname = "Xonar DS", .longname = "Asus Virtuoso 66", @@ -1079,6 +1108,7 @@ static const struct oxygen_model model_xonar_ds = { .update_dac_mute = update_wm87x6_mute, .update_center_lfe_mix = update_wm8766_center_lfe_mix, .gpio_changed = xonar_ds_gpio_changed, + .dump_registers = dump_wm87x6_registers, .dac_tlv = wm87x6_dac_db_scale, .model_data_size = sizeof(struct xonar_wm87x6), .device_config = PLAYBACK_0_TO_I2S | -- cgit v1.2.3 From e2943efa4fda376903974e33298b29091fc596b3 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Thu, 2 Dec 2010 11:42:00 +0100 Subject: ALSA: oxygen: show correct package ID Instead of the hardcoded "CMI8788", show the actual chip name. Note: This is neither what the chip is (it's always the same), nor what the chip is actually called. Signed-off-by: Clemens Ladisch Signed-off-by: Takashi Iwai --- sound/pci/oxygen/oxygen_lib.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/sound/pci/oxygen/oxygen_lib.c b/sound/pci/oxygen/oxygen_lib.c index e581e7ab216c..3078ed66ad61 100644 --- a/sound/pci/oxygen/oxygen_lib.c +++ b/sound/pci/oxygen/oxygen_lib.c @@ -202,7 +202,13 @@ static void oxygen_proc_read(struct snd_info_entry *entry, struct oxygen *chip = entry->private_data; int i, j; - snd_iprintf(buffer, "CMI8788:\n"); + switch (oxygen_read8(chip, OXYGEN_REVISION) & OXYGEN_PACKAGE_ID_MASK) { + case OXYGEN_PACKAGE_ID_8786: i = '6'; break; + case OXYGEN_PACKAGE_ID_8787: i = '7'; break; + case OXYGEN_PACKAGE_ID_8788: i = '8'; break; + default: i = '?'; break; + } + snd_iprintf(buffer, "CMI878%c:\n", i); for (i = 0; i < OXYGEN_IO_SIZE; i += 0x10) { snd_iprintf(buffer, "%02x:", i); for (j = 0; j < 0x10; ++j) -- cgit v1.2.3 From de664936930dae5469170f7eed24bcff7e91ef82 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Thu, 2 Dec 2010 11:42:48 +0100 Subject: ALSA: oxygen: update hardware comments Reformat and update the comments that describe the hardware connections on the various models. Signed-off-by: Clemens Ladisch Signed-off-by: Takashi Iwai --- sound/pci/oxygen/oxygen.c | 24 ++++--- sound/pci/oxygen/xonar_cs43xx.c | 33 +++++---- sound/pci/oxygen/xonar_pcm179x.c | 148 ++++++++++++++++++++++++--------------- sound/pci/oxygen/xonar_wm87x6.c | 43 +++++++++--- 4 files changed, 154 insertions(+), 94 deletions(-) diff --git a/sound/pci/oxygen/oxygen.c b/sound/pci/oxygen/oxygen.c index a58e448fc1bf..dc47977becae 100644 --- a/sound/pci/oxygen/oxygen.c +++ b/sound/pci/oxygen/oxygen.c @@ -20,19 +20,25 @@ /* * CMI8788: * - * SPI 0 -> 1st AK4396 (front) - * SPI 1 -> 2nd AK4396 (surround) - * SPI 2 -> 3rd AK4396 (center/LFE) - * SPI 3 -> WM8785 - * SPI 4 -> 4th AK4396 (back) + * SPI 0 -> 1st AK4396 (front) + * SPI 1 -> 2nd AK4396 (surround) + * SPI 2 -> 3rd AK4396 (center/LFE) + * SPI 3 -> WM8785 + * SPI 4 -> 4th AK4396 (back) * - * GPIO 0 -> DFS0 of AK5385 - * GPIO 1 -> DFS1 of AK5385 - * GPIO 8 -> enable headphone amplifier on HT-Omega models + * GPIO 0 -> DFS0 of AK5385 + * GPIO 1 -> DFS1 of AK5385 + * GPIO 8 -> enable headphone amplifier on HT-Omega models * * CM9780: * - * GPO 0 -> route line-in (0) or AC97 output (1) to ADC input + * LINE_OUT -> input of ADC + * + * AUX_IN <- aux + * CD_IN <- CD + * MIC_IN <- mic + * + * GPO 0 -> route line-in (0) or AC97 output (1) to ADC input */ #include diff --git a/sound/pci/oxygen/xonar_cs43xx.c b/sound/pci/oxygen/xonar_cs43xx.c index 092addb15e13..de32895b3172 100644 --- a/sound/pci/oxygen/xonar_cs43xx.c +++ b/sound/pci/oxygen/xonar_cs43xx.c @@ -22,29 +22,28 @@ * * CMI8788: * - * I²C <-> CS4398 (front) - * <-> CS4362A (surround, center/LFE, back) + * I²C <-> CS4398 (addr 1001111) (front) + * <-> CS4362A (addr 0011000) (surround, center/LFE, back) * - * GPI 0 <- external power present (DX only) + * GPI 0 <- external power present (DX only) * - * GPIO 0 -> enable output to speakers - * GPIO 1 -> route output to front panel - * GPIO 2 -> M0 of CS5361 - * GPIO 3 -> M1 of CS5361 - * GPIO 8 -> route input jack to line-in (0) or mic-in (1) + * GPIO 0 -> enable output to speakers + * GPIO 1 -> route output to front panel + * GPIO 2 -> M0 of CS5361 + * GPIO 3 -> M1 of CS5361 + * GPIO 6 -> ? + * GPIO 7 -> ? + * GPIO 8 -> route input jack to line-in (0) or mic-in (1) * - * CS4398: - * - * AD0 <- 1 - * AD1 <- 1 - * - * CS4362A: + * CM9780: * - * AD0 <- 0 + * LINE_OUT -> input of ADC * - * CM9780: + * AUX_IN <- aux + * MIC_IN <- mic + * FMIC_IN <- front mic * - * GPO 0 -> route line-in (0) or AC97 output (1) to CS5361 input + * GPO 0 -> route line-in (0) or AC97 output (1) to CS5361 input */ #include diff --git a/sound/pci/oxygen/xonar_pcm179x.c b/sound/pci/oxygen/xonar_pcm179x.c index dc69fddf2e6e..bf357c01afd2 100644 --- a/sound/pci/oxygen/xonar_pcm179x.c +++ b/sound/pci/oxygen/xonar_pcm179x.c @@ -22,20 +22,26 @@ * * CMI8788: * - * SPI 0 -> 1st PCM1796 (front) - * SPI 1 -> 2nd PCM1796 (surround) - * SPI 2 -> 3rd PCM1796 (center/LFE) - * SPI 4 -> 4th PCM1796 (back) + * SPI 0 -> 1st PCM1796 (front) + * SPI 1 -> 2nd PCM1796 (surround) + * SPI 2 -> 3rd PCM1796 (center/LFE) + * SPI 4 -> 4th PCM1796 (back) * - * GPIO 2 -> M0 of CS5381 - * GPIO 3 -> M1 of CS5381 - * GPIO 5 <- external power present (D2X only) - * GPIO 7 -> ALT - * GPIO 8 -> enable output to speakers + * GPIO 2 -> M0 of CS5381 + * GPIO 3 -> M1 of CS5381 + * GPIO 5 <- external power present (D2X only) + * GPIO 7 -> ALT + * GPIO 8 -> enable output to speakers * * CM9780: * - * GPO 0 -> route line-in (0) or AC97 output (1) to CS5381 input + * LINE_OUT -> input of ADC + * + * AUX_IN <- aux + * VIDEO_IN <- CD + * FMIC_IN <- mic + * + * GPO 0 -> route line-in (0) or AC97 output (1) to CS5381 input */ /* @@ -44,52 +50,53 @@ * * CMI8788: * - * I²C <-> PCM1796 (front) - * - * GPI 0 <- external power present + * I²C <-> PCM1796 (addr 1001100) (front) * - * GPIO 0 -> enable output to speakers - * GPIO 2 -> M0 of CS5381 - * GPIO 3 -> M1 of CS5381 - * GPIO 8 -> route input jack to line-in (0) or mic-in (1) + * GPI 0 <- external power present * - * TXD -> HDMI controller - * RXD <- HDMI controller + * GPIO 0 -> enable HDMI (0) or speaker (1) output + * GPIO 2 -> M0 of CS5381 + * GPIO 3 -> M1 of CS5381 + * GPIO 4 <- daughterboard detection + * GPIO 5 <- daughterboard detection + * GPIO 6 -> ? + * GPIO 7 -> ? + * GPIO 8 -> route input jack to line-in (0) or mic-in (1) * - * PCM1796 front: AD1,0 <- 0,0 + * UART <-> HDMI controller * * CM9780: * - * GPO 0 -> route line-in (0) or AC97 output (1) to CS5381 input + * LINE_OUT -> input of ADC + * + * AUX_IN <- aux + * CD_IN <- CD + * MIC_IN <- mic + * + * GPO 0 -> route line-in (0) or AC97 output (1) to CS5381 input * * no daughterboard * ---------------- * - * GPIO 4 <- 1 + * GPIO 4 <- 1 * * H6 daughterboard * ---------------- * - * GPIO 4 <- 0 - * GPIO 5 <- 0 - * - * I²C <-> PCM1796 (surround) - * <-> PCM1796 (center/LFE) - * <-> PCM1796 (back) + * GPIO 4 <- 0 + * GPIO 5 <- 0 * - * PCM1796 surround: AD1,0 <- 0,1 - * PCM1796 center/LFE: AD1,0 <- 1,0 - * PCM1796 back: AD1,0 <- 1,1 + * I²C <-> PCM1796 (addr 1001101) (surround) + * <-> PCM1796 (addr 1001110) (center/LFE) + * <-> PCM1796 (addr 1001111) (back) * * unknown daughterboard * --------------------- * - * GPIO 4 <- 0 - * GPIO 5 <- 1 - * - * I²C <-> CS4362A (surround, center/LFE, back) + * GPIO 4 <- 0 + * GPIO 5 <- 1 * - * CS4362A: AD0 <- 0 + * I²C <-> CS4362A (addr 0011000) (surround, center/LFE, back) */ /* @@ -98,32 +105,35 @@ * * CMI8788: * - * I²C <-> PCM1792A - * <-> CS2000 (ST only) + * I²C <-> PCM1792A (addr 1001100) + * <-> CS2000 (addr 1001110) (ST only) * - * ADC1 MCLK -> REF_CLK of CS2000 (ST only) + * ADC1 MCLK -> REF_CLK of CS2000 (ST only) * - * GPI 0 <- external power present (STX only) + * GPI 0 <- external power present (STX only) * - * GPIO 0 -> enable output to speakers - * GPIO 1 -> route HP to front panel (0) or rear jack (1) - * GPIO 2 -> M0 of CS5381 - * GPIO 3 -> M1 of CS5381 - * GPIO 7 -> route output to speaker jacks (0) or HP (1) - * GPIO 8 -> route input jack to line-in (0) or mic-in (1) + * GPIO 0 -> enable output to speakers + * GPIO 1 -> route HP to front panel (0) or rear jack (1) + * GPIO 2 -> M0 of CS5381 + * GPIO 3 -> M1 of CS5381 + * GPIO 4 <- daughterboard detection + * GPIO 5 <- daughterboard detection + * GPIO 6 -> ? + * GPIO 7 -> route output to speaker jacks (0) or HP (1) + * GPIO 8 -> route input jack to line-in (0) or mic-in (1) * * PCM1792A: * - * AD1,0 <- 0,0 - * SCK <- CLK_OUT of CS2000 (ST only) + * SCK <- CLK_OUT of CS2000 (ST only) * - * CS2000: + * CM9780: * - * AD0 <- 0 + * LINE_OUT -> input of ADC * - * CM9780: + * AUX_IN <- aux + * MIC_IN <- mic * - * GPO 0 -> route line-in (0) or AC97 output (1) to CS5381 input + * GPO 0 -> route line-in (0) or AC97 output (1) to CS5381 input * * H6 daughterboard * ---------------- @@ -133,15 +143,39 @@ */ /* - * Xonar HDAV1.3 Slim - * ------------------ + * Xonar Xense + * ----------- * * CMI8788: * - * GPIO 1 -> enable output + * I²C <-> PCM1796 (addr 1001100) (front) + * <-> CS4362A (addr 0011000) (surround, center/LFE, back) + * <-> CS2000 (addr 1001110) + * + * ADC1 MCLK -> REF_CLK of CS2000 + * + * GPI 0 <- external power present + * + * GPIO 0 -> enable output + * GPIO 1 -> route HP to front panel (0) or rear jack (1) + * GPIO 2 -> M0 of CS5381 + * GPIO 3 -> M1 of CS5381 + * GPIO 4 -> enable output + * GPIO 5 -> enable output + * GPIO 6 -> ? + * GPIO 7 -> route output to HP (0) or speaker (1) + * GPIO 8 -> route input jack to mic-in (0) or line-in (1) + * + * CM9780: + * + * LINE_OUT -> input of ADC + * + * AUX_IN <- aux + * VIDEO_IN <- ? + * FMIC_IN <- mic * - * TXD -> HDMI controller - * RXD <- HDMI controller + * GPO 0 -> route line-in (0) or AC97 output (1) to CS5381 input + * GPO 1 -> route mic-in from input jack (0) or front panel header (1) */ #include diff --git a/sound/pci/oxygen/xonar_wm87x6.c b/sound/pci/oxygen/xonar_wm87x6.c index 2b5e69b64708..1705d1e93115 100644 --- a/sound/pci/oxygen/xonar_wm87x6.c +++ b/sound/pci/oxygen/xonar_wm87x6.c @@ -22,20 +22,41 @@ * * CMI8788: * - * SPI 0 -> WM8766 (surround, center/LFE, back) - * SPI 1 -> WM8776 (front, input) + * SPI 0 -> WM8766 (surround, center/LFE, back) + * SPI 1 -> WM8776 (front, input) * - * GPIO 4 <- headphone detect, 0 = plugged - * GPIO 6 -> route input jack to mic-in (0) or line-in (1) - * GPIO 7 -> enable output to front L/R speaker channels - * GPIO 8 -> enable output to other speaker channels and front panel headphone + * GPIO 4 <- headphone detect, 0 = plugged + * GPIO 6 -> route input jack to mic-in (0) or line-in (1) + * GPIO 7 -> enable output to front L/R speaker channels + * GPIO 8 -> enable output to other speaker channels and front panel headphone * - * WM8766: + * WM8776: * - * input 1 <- line - * input 2 <- mic - * input 3 <- front mic - * input 4 <- aux + * input 1 <- line + * input 2 <- mic + * input 3 <- front mic + * input 4 <- aux + */ + +/* + * Xonar HDAV1.3 Slim + * ------------------ + * + * CMI8788: + * + * I²C <-> WM8776 (addr 0011010) + * + * GPIO 0 -> disable HDMI output + * GPIO 1 -> enable HP output + * GPIO 6 -> firmware EEPROM I²C clock + * GPIO 7 <-> firmware EEPROM I²C data + * + * UART <-> HDMI controller + * + * WM8776: + * + * input 1 <- mic + * input 2 <- aux */ #include -- cgit v1.2.3 From 3028eb8c51d968b9e7b44a9786a4e521e37afb13 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Sun, 5 Dec 2010 12:22:46 +0000 Subject: ASoC: Add trace events for jack detection As jack detection can trigger DAPM and the latency in debouncing can create confusing windows in operation provide some trace events which will hopefully help in diagnostics. The soc-jack core traces all reports that it gets and the resulting notifications to upper layers. An event for jack IRQs is also provided for instrumentation of debounce, and used in the GPIO jack code. Signed-off-by: Mark Brown Acked-by: Liam Girdwood --- include/trace/events/asoc.h | 59 +++++++++++++++++++++++++++++++++++++++++++++ sound/soc/soc-core.c | 1 + sound/soc/soc-jack.c | 7 ++++++ 3 files changed, 67 insertions(+) diff --git a/include/trace/events/asoc.h b/include/trace/events/asoc.h index 9978856d5897..186e84db4b54 100644 --- a/include/trace/events/asoc.h +++ b/include/trace/events/asoc.h @@ -7,6 +7,7 @@ #include #include +struct snd_soc_jack; struct snd_soc_codec; struct snd_soc_card; struct snd_soc_dapm_widget; @@ -170,6 +171,64 @@ DEFINE_EVENT(snd_soc_dapm_widget, snd_soc_dapm_widget_event_done, ); +TRACE_EVENT(snd_soc_jack_irq, + + TP_PROTO(const char *name), + + TP_ARGS(name), + + TP_STRUCT__entry( + __string( name, name ) + ), + + TP_fast_assign( + __assign_str(name, name); + ), + + TP_printk("%s", __get_str(name)) +); + +TRACE_EVENT(snd_soc_jack_report, + + TP_PROTO(struct snd_soc_jack *jack, int mask, int val), + + TP_ARGS(jack, mask, val), + + TP_STRUCT__entry( + __string( name, jack->jack->name ) + __field( int, mask ) + __field( int, val ) + ), + + TP_fast_assign( + __assign_str(name, jack->jack->name); + __entry->mask = mask; + __entry->val = val; + ), + + TP_printk("jack=%s %x/%x", __get_str(name), (int)__entry->val, + (int)__entry->mask) +); + +TRACE_EVENT(snd_soc_jack_notify, + + TP_PROTO(struct snd_soc_jack *jack, int val), + + TP_ARGS(jack, val), + + TP_STRUCT__entry( + __string( name, jack->jack->name ) + __field( int, val ) + ), + + TP_fast_assign( + __assign_str(name, jack->jack->name); + __entry->val = val; + ), + + TP_printk("jack=%s %x", __get_str(name), (int)__entry->val) +); + #endif /* _TRACE_ASOC_H */ /* This part must be outside protection */ diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 78a01014079a..822bd3bcf148 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include #include diff --git a/sound/soc/soc-jack.c b/sound/soc/soc-jack.c index 0e9b0710928b..ac5a5bc7375a 100644 --- a/sound/soc/soc-jack.c +++ b/sound/soc/soc-jack.c @@ -17,6 +17,7 @@ #include #include #include +#include /** * snd_soc_jack_new - Create a new jack @@ -64,6 +65,8 @@ void snd_soc_jack_report(struct snd_soc_jack *jack, int status, int mask) int enable; int oldstatus; + trace_snd_soc_jack_report(jack, mask, status); + if (!jack) return; @@ -82,6 +85,8 @@ void snd_soc_jack_report(struct snd_soc_jack *jack, int status, int mask) if (mask && (jack->status == oldstatus)) goto out; + trace_snd_soc_jack_notify(jack, status); + list_for_each_entry(pin, &jack->pins, list) { enable = pin->mask & jack->status; @@ -210,6 +215,8 @@ static irqreturn_t gpio_handler(int irq, void *data) struct snd_soc_jack_gpio *gpio = data; struct device *dev = gpio->jack->codec->card->dev; + trace_snd_soc_jack_irq(gpio->name); + if (device_may_wakeup(dev)) pm_wakeup_event(dev, gpio->debounce_time + 50); -- cgit v1.2.3 From b0d8bef417eecc28f51f53bbac501c9984b3bcba Mon Sep 17 00:00:00 2001 From: Seungwhan Youn Date: Mon, 6 Dec 2010 07:56:59 +0900 Subject: ASoC: SAMSUNG: Fix initial return value This patch fixed intial return value to be a '0' as asuccess on set_audio_clock_heirachy(). This avoids unintended error on initialize. Signed-off-by: Seungwhan Youn Acked-by: Jassi Brar Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/samsung/smdk_spdif.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/samsung/smdk_spdif.c b/sound/soc/samsung/smdk_spdif.c index ca779ad1613c..56d058d3fa0c 100644 --- a/sound/soc/samsung/smdk_spdif.c +++ b/sound/soc/samsung/smdk_spdif.c @@ -28,7 +28,7 @@ static int set_audio_clock_heirachy(struct platform_device *pdev) { struct clk *fout_epll, *mout_epll, *sclk_audio0, *sclk_spdif; - int ret; + int ret = 0; fout_epll = clk_get(NULL, "fout_epll"); if (IS_ERR(fout_epll)) { -- cgit v1.2.3 From 9545cd85a6dd1cce793b309800d2a03af9a886a8 Mon Sep 17 00:00:00 2001 From: Seungwhan Youn Date: Mon, 6 Dec 2010 07:57:13 +0900 Subject: ASoC: SAMSUNG: Remove duplicated snd_card on smdk_spdif This patch remove duplicated snd_card defination on smdk_spdif. Signed-off-by: Seungwhan Youn Acked-by: Jassi Brar Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/samsung/smdk_spdif.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/sound/soc/samsung/smdk_spdif.c b/sound/soc/samsung/smdk_spdif.c index 56d058d3fa0c..cb2f4d04ab7e 100644 --- a/sound/soc/samsung/smdk_spdif.c +++ b/sound/soc/samsung/smdk_spdif.c @@ -152,8 +152,6 @@ static struct snd_soc_ops smdk_spdif_ops = { .hw_params = smdk_hw_params, }; -static struct snd_soc_card smdk; - static struct snd_soc_dai_link smdk_dai = { .name = "S/PDIF", .stream_name = "S/PDIF PCM Playback", -- cgit v1.2.3 From 0d735eaa2c1d80c997fd775b679e36b80b8e85d1 Mon Sep 17 00:00:00 2001 From: Dimitris Papastamos Date: Mon, 6 Dec 2010 09:51:57 +0000 Subject: ASoC: soc-cache: Add optional cache name member to snd_soc_cache_ops Added an optional name member to snd_soc_cache_ops to enable more sensible diagnostic messages during cache init, exit and sync. Remove redundant newline in source code. Signed-off-by: Dimitris Papastamos Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- include/sound/soc.h | 1 + sound/soc/soc-cache.c | 18 ++++++++++++++++-- sound/soc/soc-core.c | 3 --- 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/include/sound/soc.h b/include/sound/soc.h index 4abc2f8fe77a..0a962dc42c5b 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -437,6 +437,7 @@ struct snd_soc_ops { /* SoC cache ops */ struct snd_soc_cache_ops { + const char *name; enum snd_soc_compress_type id; int (*init)(struct snd_soc_codec *codec); int (*exit)(struct snd_soc_codec *codec); diff --git a/sound/soc/soc-cache.c b/sound/soc/soc-cache.c index ff2bc8beddaa..678fd75d4511 100644 --- a/sound/soc/soc-cache.c +++ b/sound/soc/soc-cache.c @@ -1533,6 +1533,7 @@ static int snd_soc_flat_cache_init(struct snd_soc_codec *codec) static const struct snd_soc_cache_ops cache_types[] = { { .id = SND_SOC_FLAT_COMPRESSION, + .name = "flat", .init = snd_soc_flat_cache_init, .exit = snd_soc_flat_cache_exit, .read = snd_soc_flat_cache_read, @@ -1541,6 +1542,7 @@ static const struct snd_soc_cache_ops cache_types[] = { }, { .id = SND_SOC_LZO_COMPRESSION, + .name = "LZO", .init = snd_soc_lzo_cache_init, .exit = snd_soc_lzo_cache_exit, .read = snd_soc_lzo_cache_read, @@ -1549,6 +1551,7 @@ static const struct snd_soc_cache_ops cache_types[] = { }, { .id = SND_SOC_RBTREE_COMPRESSION, + .name = "rbtree", .init = snd_soc_rbtree_cache_init, .exit = snd_soc_rbtree_cache_exit, .read = snd_soc_rbtree_cache_read, @@ -1573,8 +1576,12 @@ int snd_soc_cache_init(struct snd_soc_codec *codec) mutex_init(&codec->cache_rw_mutex); codec->cache_ops = &cache_types[i]; - if (codec->cache_ops->init) + if (codec->cache_ops->init) { + if (codec->cache_ops->name) + dev_dbg(codec->dev, "Initializing %s cache for %s codec\n", + codec->cache_ops->name, codec->name); return codec->cache_ops->init(codec); + } return -EINVAL; } @@ -1584,8 +1591,12 @@ int snd_soc_cache_init(struct snd_soc_codec *codec) */ int snd_soc_cache_exit(struct snd_soc_codec *codec) { - if (codec->cache_ops && codec->cache_ops->exit) + if (codec->cache_ops && codec->cache_ops->exit) { + if (codec->cache_ops->name) + dev_dbg(codec->dev, "Destroying %s cache for %s codec\n", + codec->cache_ops->name, codec->name); return codec->cache_ops->exit(codec); + } return -EINVAL; } @@ -1657,6 +1668,9 @@ int snd_soc_cache_sync(struct snd_soc_codec *codec) } if (codec->cache_ops && codec->cache_ops->sync) { + if (codec->cache_ops->name) + dev_dbg(codec->dev, "Syncing %s cache for %s codec\n", + codec->cache_ops->name, codec->name); ret = codec->cache_ops->sync(codec); if (!ret) codec->cache_sync = 0; diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 822bd3bcf148..a90e067fb0ab 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -1742,8 +1742,6 @@ static int snd_soc_init_codec_cache(struct snd_soc_codec *codec, /* override the compress_type if necessary */ if (compress_type && codec->compress_type != compress_type) codec->compress_type = compress_type; - dev_dbg(codec->dev, "Cache compress_type for %s is %d\n", - codec->name, codec->compress_type); ret = snd_soc_cache_init(codec); if (ret < 0) { dev_err(codec->dev, "Failed to set cache compression type: %d\n", @@ -1754,7 +1752,6 @@ static int snd_soc_init_codec_cache(struct snd_soc_codec *codec, return 0; } - static void snd_soc_instantiate_card(struct snd_soc_card *card) { struct platform_device *pdev = to_platform_device(card->dev); -- cgit v1.2.3 From 0ac74c6b3386f0413baf48f6d61850650e0dc4ab Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 6 Dec 2010 14:36:02 +0000 Subject: drm/i915: Only emit a flush if there is an outstanding gpu write Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_gem.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 8685b9279029..e7733333767d 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -2154,8 +2154,9 @@ static int i915_ring_idle(struct drm_device *dev, if (list_empty(&ring->gpu_write_list) && list_empty(&ring->active_list)) return 0; - i915_gem_flush_ring(dev, ring, - I915_GEM_GPU_DOMAINS, I915_GEM_GPU_DOMAINS); + if (!list_empty(&ring->gpu_write_list)) + i915_gem_flush_ring(dev, ring, + I915_GEM_GPU_DOMAINS, I915_GEM_GPU_DOMAINS); return i915_wait_request(dev, i915_gem_next_request_seqno(dev, ring), ring); -- cgit v1.2.3 From 0be732841fb925b6f1242211ea211c022b6ac26c Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 6 Dec 2010 14:36:27 +0000 Subject: drm/i915: Wait for the bo if a display flip is pipelined on the other ring Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_gem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index e7733333767d..b57ce033e42a 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -2926,7 +2926,7 @@ i915_gem_object_set_to_display_plane(struct drm_i915_gem_object *obj, i915_gem_object_flush_gpu_write_domain(obj); /* Currently, we are always called from an non-interruptible context. */ - if (!pipelined) { + if (pipelined != obj->ring) { ret = i915_gem_object_wait_rendering(obj, false); if (ret) return ret; -- cgit v1.2.3 From d0359c6fac18588da04fbefdad096453442653ee Mon Sep 17 00:00:00 2001 From: Jeffrin Jose Date: Mon, 6 Dec 2010 19:27:53 +0530 Subject: sound: Fixed line limit issue in sound/ac97_bus.c This is a patch to the sound/ac97_bus.c file that fixes up a 80 character line limit issue found by the checkpatch.pl tool. Signed-off-by: Jeffrin Jose Signed-off-by: Takashi Iwai --- sound/ac97_bus.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/ac97_bus.c b/sound/ac97_bus.c index a351dd0a09c7..2b50cbe6aca9 100644 --- a/sound/ac97_bus.c +++ b/sound/ac97_bus.c @@ -19,8 +19,8 @@ /* * Let drivers decide whether they want to support given codec from their - * probe method. Drivers have direct access to the struct snd_ac97 structure and may - * decide based on the id field amongst other things. + * probe method. Drivers have direct access to the struct snd_ac97 + * structure and may decide based on the id field amongst other things. */ static int ac97_bus_match(struct device *dev, struct device_driver *drv) { -- cgit v1.2.3 From 589c3563f6476950f26b5bcc9beb1b39a7bcc644 Mon Sep 17 00:00:00 2001 From: Jarkko Nikula Date: Mon, 6 Dec 2010 16:27:07 +0200 Subject: ASoC: Merge common code in DAI link and auxiliary codec probing/removal Commit 2eea392 "ASoC: Add support for optional auxiliary dailess codecs" added much of code that can be shared with DAI link codec probing/removal. Merge now this common code into new soc_probe_codec, soc_remove_codec and soc_post_component_init functions. Error prints in these functions are converted to use dev_err and to print the error code. Signed-off-by: Jarkko Nikula Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/soc-core.c | 284 ++++++++++++++++++++++++--------------------------- 1 file changed, 132 insertions(+), 152 deletions(-) diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 17dcd56a2520..b3605a1c8c46 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -1328,6 +1328,27 @@ out: return 1; } +static void soc_remove_codec(struct snd_soc_codec *codec) +{ + int err; + + if (codec->driver->remove) { + err = codec->driver->remove(codec); + if (err < 0) + dev_err(codec->dev, + "asoc: failed to remove %s: %d\n", + codec->name, err); + } + + /* Make sure all DAPM widgets are freed */ + snd_soc_dapm_free(&codec->dapm); + + soc_cleanup_codec_debugfs(codec); + codec->probed = 0; + list_del(&codec->card_list); + module_put(codec->dev->driver->owner); +} + static void soc_remove_dai_link(struct snd_soc_card *card, int num) { struct snd_soc_pcm_runtime *rtd = &card->rtd[num]; @@ -1339,6 +1360,7 @@ static void soc_remove_dai_link(struct snd_soc_card *card, int num) /* unregister the rtd device */ if (rtd->dev_registered) { device_remove_file(&rtd->dev, &dev_attr_pmdown_time); + device_remove_file(&rtd->dev, &dev_attr_codec_reg); device_unregister(&rtd->dev); rtd->dev_registered = 0; } @@ -1367,22 +1389,8 @@ static void soc_remove_dai_link(struct snd_soc_card *card, int num) } /* remove the CODEC */ - if (codec && codec->probed) { - if (codec->driver->remove) { - err = codec->driver->remove(codec); - if (err < 0) - printk(KERN_ERR "asoc: failed to remove %s\n", codec->name); - } - - /* Make sure all DAPM widgets are freed */ - snd_soc_dapm_free(&codec->dapm); - - soc_cleanup_codec_debugfs(codec); - device_remove_file(&rtd->dev, &dev_attr_codec_reg); - codec->probed = 0; - list_del(&codec->card_list); - module_put(codec->dev->driver->owner); - } + if (codec && codec->probed) + soc_remove_codec(codec); /* remove the cpu_dai */ if (cpu_dai && cpu_dai->probed) { @@ -1414,8 +1422,105 @@ static void soc_set_name_prefix(struct snd_soc_card *card, } } +static int soc_probe_codec(struct snd_soc_card *card, + struct snd_soc_codec *codec) +{ + int ret = 0; + + codec->card = card; + codec->dapm.card = card; + soc_set_name_prefix(card, codec); + + if (codec->driver->probe) { + ret = codec->driver->probe(codec); + if (ret < 0) { + dev_err(codec->dev, + "asoc: failed to probe CODEC %s: %d\n", + codec->name, ret); + return ret; + } + } + + soc_init_codec_debugfs(codec); + + /* mark codec as probed and add to card codec list */ + codec->probed = 1; + list_add(&codec->card_list, &card->codec_dev_list); + + return ret; +} + static void rtd_release(struct device *dev) {} +static int soc_post_component_init(struct snd_soc_card *card, + struct snd_soc_codec *codec, + int num, int dailess) +{ + struct snd_soc_dai_link *dai_link = NULL; + struct snd_soc_aux_dev *aux_dev = NULL; + struct snd_soc_pcm_runtime *rtd; + const char *temp, *name; + int ret = 0; + + if (!dailess) { + dai_link = &card->dai_link[num]; + rtd = &card->rtd[num]; + name = dai_link->name; + } else { + aux_dev = &card->aux_dev[num]; + rtd = &card->rtd_aux[num]; + name = aux_dev->name; + } + + /* machine controls, routes and widgets are not prefixed */ + temp = codec->name_prefix; + codec->name_prefix = NULL; + + /* do machine specific initialization */ + if (!dailess && dai_link->init) + ret = dai_link->init(rtd); + else if (dailess && aux_dev->init) + ret = aux_dev->init(&codec->dapm); + if (ret < 0) { + dev_err(card->dev, "asoc: failed to init %s: %d\n", name, ret); + return ret; + } + codec->name_prefix = temp; + + /* Make sure all DAPM widgets are instantiated */ + snd_soc_dapm_new_widgets(&codec->dapm); + snd_soc_dapm_sync(&codec->dapm); + + /* register the rtd device */ + rtd->codec = codec; + rtd->card = card; + rtd->dev.parent = card->dev; + rtd->dev.release = rtd_release; + rtd->dev.init_name = name; + ret = device_register(&rtd->dev); + if (ret < 0) { + dev_err(card->dev, + "asoc: failed to register runtime device: %d\n", ret); + return ret; + } + rtd->dev_registered = 1; + + /* add DAPM sysfs entries for this codec */ + ret = snd_soc_dapm_sys_add(&rtd->dev); + if (ret < 0) + dev_err(codec->dev, + "asoc: failed to add codec dapm sysfs entries: %d\n", + ret); + + /* add codec sysfs entries */ + ret = device_create_file(&rtd->dev, &dev_attr_codec_reg); + if (ret < 0) + dev_err(codec->dev, + "asoc: failed to add codec sysfs files: %d\n", ret); + + return 0; +} + static int soc_probe_dai_link(struct snd_soc_card *card, int num) { struct snd_soc_dai_link *dai_link = &card->dai_link[num]; @@ -1423,17 +1528,13 @@ static int soc_probe_dai_link(struct snd_soc_card *card, int num) struct snd_soc_codec *codec = rtd->codec; struct snd_soc_platform *platform = rtd->platform; struct snd_soc_dai *codec_dai = rtd->codec_dai, *cpu_dai = rtd->cpu_dai; - const char *temp; int ret; dev_dbg(card->dev, "probe %s dai link %d\n", card->name, num); /* config components */ codec_dai->codec = codec; - codec->card = card; cpu_dai->platform = platform; - rtd->card = card; - rtd->dev.parent = card->dev; codec_dai->card = card; cpu_dai->card = card; @@ -1457,22 +1558,9 @@ static int soc_probe_dai_link(struct snd_soc_card *card, int num) /* probe the CODEC */ if (!codec->probed) { - codec->dapm.card = card; - soc_set_name_prefix(card, codec); - if (codec->driver->probe) { - ret = codec->driver->probe(codec); - if (ret < 0) { - printk(KERN_ERR "asoc: failed to probe CODEC %s\n", - codec->name); - return ret; - } - } - - soc_init_codec_debugfs(codec); - - /* mark codec as probed and add to card codec list */ - codec->probed = 1; - list_add(&codec->card_list, &card->codec_dev_list); + ret = soc_probe_codec(card, codec); + if (ret < 0) + return ret; } /* probe the platform */ @@ -1509,47 +1597,14 @@ static int soc_probe_dai_link(struct snd_soc_card *card, int num) /* DAPM dai link stream work */ INIT_DELAYED_WORK(&rtd->delayed_work, close_delayed_work); - /* now that all clients have probed, initialise the DAI link */ - if (dai_link->init) { - /* machine controls, routes and widgets are not prefixed */ - temp = rtd->codec->name_prefix; - rtd->codec->name_prefix = NULL; - ret = dai_link->init(rtd); - if (ret < 0) { - printk(KERN_ERR "asoc: failed to init %s\n", dai_link->stream_name); - return ret; - } - rtd->codec->name_prefix = temp; - } - - /* Make sure all DAPM widgets are instantiated */ - snd_soc_dapm_new_widgets(&codec->dapm); - snd_soc_dapm_sync(&codec->dapm); - - /* register the rtd device */ - rtd->dev.release = rtd_release; - rtd->dev.init_name = dai_link->name; - ret = device_register(&rtd->dev); - if (ret < 0) { - printk(KERN_ERR "asoc: failed to register DAI runtime device %d\n", ret); + ret = soc_post_component_init(card, codec, num, 0); + if (ret) return ret; - } - rtd->dev_registered = 1; ret = device_create_file(&rtd->dev, &dev_attr_pmdown_time); if (ret < 0) printk(KERN_WARNING "asoc: failed to add pmdown_time sysfs\n"); - /* add DAPM sysfs entries for this codec */ - ret = snd_soc_dapm_sys_add(&rtd->dev); - if (ret < 0) - printk(KERN_WARNING "asoc: failed to add codec dapm sysfs entries\n"); - - /* add codec sysfs entries */ - ret = device_create_file(&rtd->dev, &dev_attr_codec_reg); - if (ret < 0) - printk(KERN_WARNING "asoc: failed to add codec sysfs files\n"); - /* create the pcm */ ret = soc_new_pcm(rtd, num); if (ret < 0) { @@ -1607,9 +1662,7 @@ static void soc_unregister_ac97_dai_link(struct snd_soc_codec *codec) static int soc_probe_aux_dev(struct snd_soc_card *card, int num) { struct snd_soc_aux_dev *aux_dev = &card->aux_dev[num]; - struct snd_soc_pcm_runtime *rtd = &card->rtd_aux[num]; struct snd_soc_codec *codec; - const char *temp; int ret = -ENODEV; /* find CODEC from registered CODECs*/ @@ -1632,67 +1685,11 @@ found: if (!try_module_get(codec->dev->driver->owner)) return -ENODEV; - codec->card = card; - codec->dapm.card = card; - - soc_set_name_prefix(card, codec); - if (codec->driver->probe) { - ret = codec->driver->probe(codec); - if (ret < 0) { - dev_err(codec->dev, "asoc: failed to probe CODEC"); - return ret; - } - } - - soc_init_codec_debugfs(codec); - - /* mark codec as probed and add to card codec list */ - codec->probed = 1; - list_add(&codec->card_list, &card->codec_dev_list); - - /* now that all clients have probed, initialise the DAI link */ - if (aux_dev->init) { - /* machine controls, routes and widgets are not prefixed */ - temp = codec->name_prefix; - codec->name_prefix = NULL; - ret = aux_dev->init(&codec->dapm); - if (ret < 0) { - dev_err(codec->dev, - "asoc: failed to init %s\n", aux_dev->name); - return ret; - } - codec->name_prefix = temp; - } - - /* Make sure all DAPM widgets are instantiated */ - snd_soc_dapm_new_widgets(&codec->dapm); - snd_soc_dapm_sync(&codec->dapm); - - /* register the rtd device */ - rtd->codec = codec; - rtd->card = card; - rtd->dev.parent = card->dev; - rtd->dev.release = rtd_release; - rtd->dev.init_name = aux_dev->name; - ret = device_register(&rtd->dev); - if (ret < 0) { - dev_err(codec->dev, - "asoc: failed to register aux runtime device %d\n", - ret); - return ret; - } - rtd->dev_registered = 1; - - /* add DAPM sysfs entries for this codec */ - ret = snd_soc_dapm_sys_add(&rtd->dev); + ret = soc_probe_codec(card, codec); if (ret < 0) - dev_err(codec->dev, - "asoc: failed to add codec dapm sysfs entries\n"); + return ret; - /* add codec sysfs entries */ - ret = device_create_file(&rtd->dev, &dev_attr_codec_reg); - if (ret < 0) - dev_err(codec->dev, "asoc: failed to add codec sysfs files\n"); + ret = soc_post_component_init(card, codec, num, 1); out: return ret; @@ -1702,33 +1699,16 @@ static void soc_remove_aux_dev(struct snd_soc_card *card, int num) { struct snd_soc_pcm_runtime *rtd = &card->rtd_aux[num]; struct snd_soc_codec *codec = rtd->codec; - int err; /* unregister the rtd device */ if (rtd->dev_registered) { + device_remove_file(&rtd->dev, &dev_attr_codec_reg); device_unregister(&rtd->dev); rtd->dev_registered = 0; } - /* remove the CODEC */ - if (codec && codec->probed) { - if (codec->driver->remove) { - err = codec->driver->remove(codec); - if (err < 0) - dev_err(codec->dev, - "asoc: failed to remove %s\n", - codec->name); - } - - /* Make sure all DAPM widgets are freed */ - snd_soc_dapm_free(&codec->dapm); - - soc_cleanup_codec_debugfs(codec); - device_remove_file(&rtd->dev, &dev_attr_codec_reg); - codec->probed = 0; - list_del(&codec->card_list); - module_put(codec->dev->driver->owner); - } + if (codec && codec->probed) + soc_remove_codec(codec); } static int snd_soc_init_codec_cache(struct snd_soc_codec *codec, -- cgit v1.2.3 From 58818a77cd415e2f76607749de5a1ff24e58cefe Mon Sep 17 00:00:00 2001 From: Dimitris Papastamos Date: Mon, 6 Dec 2010 15:42:17 +0000 Subject: ASoC: soc-core: Replace use of strncpy() with strlcpy() By using strncpy() if the source string does not have a null byte in the first n bytes, then the destination string is not null-terminated. This can be fixed in a two-step process by manually null-terminating the array after the use of strncpy() or by using strlcpy(). Signed-off-by: Dimitris Papastamos Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/soc-core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index b3605a1c8c46..b2c327b14b00 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -3183,7 +3183,7 @@ static inline char *fmt_single_name(struct device *dev, int *id) if (dev_name(dev) == NULL) return NULL; - strncpy(name, dev_name(dev), NAME_SIZE); + strlcpy(name, dev_name(dev), NAME_SIZE); /* are we a "%s.%d" name (platform and SPI components) */ found = strstr(name, dev->driver->name); @@ -3206,7 +3206,7 @@ static inline char *fmt_single_name(struct device *dev, int *id) /* sanitize component name for DAI link creation */ snprintf(tmp, NAME_SIZE, "%s.%s", dev->driver->name, name); - strncpy(name, tmp, NAME_SIZE); + strlcpy(name, tmp, NAME_SIZE); } else *id = 0; } -- cgit v1.2.3 From 0b9a214a606f8c7c7af3e66e7fe0caf3233cfe16 Mon Sep 17 00:00:00 2001 From: Dimitris Papastamos Date: Mon, 6 Dec 2010 15:49:20 +0000 Subject: ASoC: soc-core: Remove useless inline function construct There is no need to mark this function as inline. Inline functions usually are small and concise functions that benefit from not needing to set up a stack frame and undergo a call/ret sequence upon each invocation. Signed-off-by: Dimitris Papastamos Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/soc-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index b2c327b14b00..392d33625327 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -3175,7 +3175,7 @@ static int snd_soc_unregister_card(struct snd_soc_card *card) * Simplify DAI link configuration by removing ".-1" from device names * and sanitizing names. */ -static inline char *fmt_single_name(struct device *dev, int *id) +static char *fmt_single_name(struct device *dev, int *id) { char *found, name[NAME_SIZE]; int id1, id2; -- cgit v1.2.3 From 98ede2ed46cef38e98c8341d410323895f60570e Mon Sep 17 00:00:00 2001 From: Brett Rudley Date: Fri, 3 Dec 2010 16:30:36 -0800 Subject: staging: brcm80211: OSLREGOPS is unused, remove checks for it. Signed-off-by: Brett Rudley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/include/osl.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/staging/brcm80211/include/osl.h b/drivers/staging/brcm80211/include/osl.h index 2368c80db60a..b543bbbae3da 100644 --- a/drivers/staging/brcm80211/include/osl.h +++ b/drivers/staging/brcm80211/include/osl.h @@ -128,8 +128,6 @@ extern void osl_dma_unmap(struct osl_info *osh, uint pa, uint size, #define bcopy(src, dst, len) memcpy((dst), (src), (len)) /* register access macros */ -#if defined(OSLREGOPS) -#else #ifndef IL_BIGENDIAN #ifndef __mips__ #define R_REG(osh, r) (\ @@ -220,8 +218,6 @@ extern void osl_dma_unmap(struct osl_info *osh, uint pa, uint size, } while (0) #endif /* IL_BIGENDIAN */ -#endif /* OSLREGOPS */ - #define AND_REG(osh, r, v) W_REG(osh, (r), R_REG(osh, r) & (v)) #define OR_REG(osh, r, v) W_REG(osh, (r), R_REG(osh, r) | (v)) -- cgit v1.2.3 From 7a9b48b3d3e0f373dc996efde56a5bff0944d8de Mon Sep 17 00:00:00 2001 From: Brett Rudley Date: Fri, 3 Dec 2010 16:30:37 -0800 Subject: staging: brcm80211: Move osl_pub into osl Signed-off-by: Brett Rudley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/include/osl.h | 20 ++++++++------------ drivers/staging/brcm80211/include/siutils.h | 2 +- drivers/staging/brcm80211/sys/wlc_mac80211.c | 6 +++--- drivers/staging/brcm80211/util/linux_osl.c | 8 ++++---- drivers/staging/brcm80211/util/siutils.c | 2 +- 5 files changed, 17 insertions(+), 21 deletions(-) diff --git a/drivers/staging/brcm80211/include/osl.h b/drivers/staging/brcm80211/include/osl.h index b543bbbae3da..2cea5c122c3a 100644 --- a/drivers/staging/brcm80211/include/osl.h +++ b/drivers/staging/brcm80211/include/osl.h @@ -17,14 +17,10 @@ #ifndef _osl_h_ #define _osl_h_ -struct osl_pubinfo { - uint pktalloced; /* Number of allocated packet buffers */ - bool mmbus; /* Bus supports memory-mapped registers */ -}; - /* osl handle type forward declaration */ struct osl_info { - struct osl_pubinfo pub; + uint pktalloced; /* Number of allocated packet buffers */ + bool mmbus; /* Bus supports memory-mapped registers */ uint magic; void *pdev; uint bustype; @@ -106,10 +102,10 @@ extern void osl_dma_unmap(struct osl_info *osh, uint pa, uint size, #if defined(BCMSDIO) #define SELECT_BUS_WRITE(osh, mmap_op, bus_op) \ - if (((struct osl_pubinfo *)(osh))->mmbus) \ + if ((osh)->mmbus) \ mmap_op else bus_op #define SELECT_BUS_READ(osh, mmap_op, bus_op) \ - (((struct osl_pubinfo *)(osh))->mmbus) ? mmap_op : bus_op + ((osh)->mmbus) ? mmap_op : bus_op #else #define SELECT_BUS_WRITE(osh, mmap_op, bus_op) mmap_op #define SELECT_BUS_READ(osh, mmap_op, bus_op) mmap_op @@ -255,7 +251,7 @@ extern void osl_pktfree(struct osl_info *osh, void *skb, bool send); #ifdef BRCM_FULLMAC static inline void * -osl_pkt_frmnative(struct osl_pubinfo *osh, struct sk_buff *skb) +osl_pkt_frmnative(struct osl_info *osh, struct sk_buff *skb) { struct sk_buff *nskb; @@ -265,10 +261,10 @@ osl_pkt_frmnative(struct osl_pubinfo *osh, struct sk_buff *skb) return (void *)skb; } #define PKTFRMNATIVE(osh, skb) \ - osl_pkt_frmnative(((struct osl_pubinfo *)osh), (struct sk_buff*)(skb)) + osl_pkt_frmnative((osh), (struct sk_buff *)(skb)) static inline struct sk_buff * -osl_pkt_tonative(struct osl_pubinfo *osh, void *pkt) +osl_pkt_tonative(struct osl_info *osh, void *pkt) { struct sk_buff *nskb; @@ -278,7 +274,7 @@ osl_pkt_tonative(struct osl_pubinfo *osh, void *pkt) return (struct sk_buff *)pkt; } #define PKTTONATIVE(osh, pkt) \ - osl_pkt_tonative((struct osl_pubinfo *)(osh), (pkt)) + osl_pkt_tonative((osh), (pkt)) #else /* !BRCM_FULLMAC */ #define PKTSETSKIPCT(osh, skb) #define PKTCLRSKIPCT(osh, skb) diff --git a/drivers/staging/brcm80211/include/siutils.h b/drivers/staging/brcm80211/include/siutils.h index d6115cdd94f6..a935092d02df 100644 --- a/drivers/staging/brcm80211/include/siutils.h +++ b/drivers/staging/brcm80211/include/siutils.h @@ -128,7 +128,7 @@ extern uint si_coreid(si_t *sih); extern uint si_flag(si_t *sih); extern uint si_coreidx(si_t *sih); extern uint si_corerev(si_t *sih); -extern void *si_osh(si_t *sih); +struct osl_info *si_osh(si_t *sih); extern uint si_corereg(si_t *sih, uint coreidx, uint regoff, uint mask, uint val); extern void si_write_wrapperreg(si_t *sih, u32 offset, u32 val); diff --git a/drivers/staging/brcm80211/sys/wlc_mac80211.c b/drivers/staging/brcm80211/sys/wlc_mac80211.c index 9aae3405aa11..fcd3bd18f27c 100644 --- a/drivers/staging/brcm80211/sys/wlc_mac80211.c +++ b/drivers/staging/brcm80211/sys/wlc_mac80211.c @@ -2733,9 +2733,9 @@ uint wlc_down(wlc_info_t *wlc) /* Verify all packets are flushed from the driver */ - if (wlc->osh->pub.pktalloced != 0) { + if (wlc->osh->pktalloced != 0) { WL_ERROR(("%d packets not freed at wlc_down!!!!!!\n", - wlc->osh->pub.pktalloced)); + wlc->osh->pktalloced)); } #ifdef BCMDBG /* Since all the packets should have been freed, @@ -6935,7 +6935,7 @@ wlc_recvctl(wlc_info_t *wlc, struct osl_info *osh, d11rxhdr_t *rxh, ieee80211_rx_irqsafe(wlc->pub->ieee_hw, p); WLCNTINCR(wlc->pub->_cnt->ieee_rx); - osh->pub.pktalloced--; + osh->pktalloced--; return; } diff --git a/drivers/staging/brcm80211/util/linux_osl.c b/drivers/staging/brcm80211/util/linux_osl.c index 6a06d61568b9..2efce7aeec78 100644 --- a/drivers/staging/brcm80211/util/linux_osl.c +++ b/drivers/staging/brcm80211/util/linux_osl.c @@ -53,14 +53,14 @@ struct osl_info *osl_attach(void *pdev, uint bustype) case PCI_BUS: case SI_BUS: case PCMCIA_BUS: - osh->pub.mmbus = true; + osh->mmbus = true; break; case JTAG_BUS: case SDIO_BUS: case USB_BUS: case SPI_BUS: case RPC_BUS: - osh->pub.mmbus = false; + osh->mmbus = false; break; default: ASSERT(false); @@ -88,7 +88,7 @@ void *BCMFASTPATH osl_pktget(struct osl_info *osh, uint len) skb_put(skb, len); skb->priority = 0; - osh->pub.pktalloced++; + osh->pktalloced++; } return (void *)skb; @@ -119,7 +119,7 @@ void BCMFASTPATH osl_pktfree(struct osl_info *osh, void *p, bool send) */ dev_kfree_skb(skb); - osh->pub.pktalloced--; + osh->pktalloced--; nest++; skb = nskb; } diff --git a/drivers/staging/brcm80211/util/siutils.c b/drivers/staging/brcm80211/util/siutils.c index 29d2d68354f6..59167122943c 100644 --- a/drivers/staging/brcm80211/util/siutils.c +++ b/drivers/staging/brcm80211/util/siutils.c @@ -729,7 +729,7 @@ void si_detach(si_t *sih) kfree(sii); } -void *si_osh(si_t *sih) +struct osl_info *si_osh(si_t *sih) { si_info_t *sii; -- cgit v1.2.3 From ec7957049668b4fcf755cd8a085cfe258d77fc9b Mon Sep 17 00:00:00 2001 From: Brett Rudley Date: Fri, 3 Dec 2010 16:30:38 -0800 Subject: staging: brcm80211: Remove unused softmac macros Signed-off-by: Brett Rudley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/include/osl.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/staging/brcm80211/include/osl.h b/drivers/staging/brcm80211/include/osl.h index 2cea5c122c3a..f722db59173e 100644 --- a/drivers/staging/brcm80211/include/osl.h +++ b/drivers/staging/brcm80211/include/osl.h @@ -275,10 +275,6 @@ osl_pkt_tonative(struct osl_info *osh, void *pkt) } #define PKTTONATIVE(osh, pkt) \ osl_pkt_tonative((osh), (pkt)) -#else /* !BRCM_FULLMAC */ -#define PKTSETSKIPCT(osh, skb) -#define PKTCLRSKIPCT(osh, skb) -#define PKTSKIPCT(osh, skb) #endif /* BRCM_FULLMAC */ #define PKTSUMNEEDED(skb) \ -- cgit v1.2.3 From 411ee44ad30b2a8c99c3b225a3cf381ec37b000e Mon Sep 17 00:00:00 2001 From: Brett Rudley Date: Fri, 3 Dec 2010 16:30:39 -0800 Subject: staging: brcm80211: move fullmac-only code from osl to fullmac files Signed-off-by: Brett Rudley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmfmac/dhd_cdc.c | 9 +++++++ drivers/staging/brcm80211/brcmfmac/dhd_linux.c | 26 ++++++++++++++++++ drivers/staging/brcm80211/include/osl.h | 37 -------------------------- 3 files changed, 35 insertions(+), 37 deletions(-) diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_cdc.c b/drivers/staging/brcm80211/brcmfmac/dhd_cdc.c index 2fa77cb53040..b3fc2a3eb957 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_cdc.c +++ b/drivers/staging/brcm80211/brcmfmac/dhd_cdc.c @@ -298,6 +298,15 @@ done: return ret; } +#define PKTSUMNEEDED(skb) \ + (((struct sk_buff *)(skb))->ip_summed == CHECKSUM_PARTIAL) +#define PKTSETSUMGOOD(skb, x) \ + (((struct sk_buff *)(skb))->ip_summed = \ + ((x) ? CHECKSUM_UNNECESSARY : CHECKSUM_NONE)) + +/* PKTSETSUMNEEDED and PKTSUMGOOD are not possible because + skb->ip_summed is overloaded */ + int dhd_prot_iovar_op(dhd_pub_t *dhdp, const char *name, void *params, int plen, void *arg, int len, bool set) diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_linux.c b/drivers/staging/brcm80211/brcmfmac/dhd_linux.c index 7f66d7a84b6e..a114deed3134 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_linux.c +++ b/drivers/staging/brcm80211/brcmfmac/dhd_linux.c @@ -1052,6 +1052,32 @@ int dhd_sendpkt(dhd_pub_t *dhdp, int ifidx, struct sk_buff *pktbuf) return ret; } +static inline void * +osl_pkt_frmnative(struct osl_info *osh, struct sk_buff *skb) +{ + struct sk_buff *nskb; + + for (nskb = skb; nskb; nskb = nskb->next) + osh->pktalloced++; + + return (void *)skb; +} +#define PKTFRMNATIVE(osh, skb) \ + osl_pkt_frmnative((osh), (struct sk_buff *)(skb)) + +static inline struct sk_buff * +osl_pkt_tonative(struct osl_info *osh, void *pkt) +{ + struct sk_buff *nskb; + + for (nskb = (struct sk_buff *)pkt; nskb; nskb = nskb->next) + osh->pktalloced--; + + return (struct sk_buff *)pkt; +} +#define PKTTONATIVE(osh, pkt) \ + osl_pkt_tonative((osh), (pkt)) + static int dhd_start_xmit(struct sk_buff *skb, struct net_device *net) { int ret; diff --git a/drivers/staging/brcm80211/include/osl.h b/drivers/staging/brcm80211/include/osl.h index f722db59173e..4e7d07e38782 100644 --- a/drivers/staging/brcm80211/include/osl.h +++ b/drivers/staging/brcm80211/include/osl.h @@ -249,43 +249,6 @@ extern void osl_dma_unmap(struct osl_info *osh, uint pa, uint size, extern void *osl_pktget(struct osl_info *osh, uint len); extern void osl_pktfree(struct osl_info *osh, void *skb, bool send); -#ifdef BRCM_FULLMAC -static inline void * -osl_pkt_frmnative(struct osl_info *osh, struct sk_buff *skb) -{ - struct sk_buff *nskb; - - for (nskb = skb; nskb; nskb = nskb->next) - osh->pktalloced++; - - return (void *)skb; -} -#define PKTFRMNATIVE(osh, skb) \ - osl_pkt_frmnative((osh), (struct sk_buff *)(skb)) - -static inline struct sk_buff * -osl_pkt_tonative(struct osl_info *osh, void *pkt) -{ - struct sk_buff *nskb; - - for (nskb = (struct sk_buff *)pkt; nskb; nskb = nskb->next) - osh->pktalloced--; - - return (struct sk_buff *)pkt; -} -#define PKTTONATIVE(osh, pkt) \ - osl_pkt_tonative((osh), (pkt)) -#endif /* BRCM_FULLMAC */ - -#define PKTSUMNEEDED(skb) \ - (((struct sk_buff *)(skb))->ip_summed == CHECKSUM_PARTIAL) -#define PKTSETSUMGOOD(skb, x) \ - (((struct sk_buff *)(skb))->ip_summed = \ - ((x) ? CHECKSUM_UNNECESSARY : CHECKSUM_NONE)) -/* PKTSETSUMNEEDED and PKTSUMGOOD are not possible because - skb->ip_summed is overloaded */ - - #define SET_REG(osh, r, mask, val) \ W_REG((osh), (r), ((R_REG((osh), r) & ~(mask)) | (val))) -- cgit v1.2.3 From 8968af14f8e2d636fa5b4c055e240c1f359b8716 Mon Sep 17 00:00:00 2001 From: Brett Rudley Date: Fri, 3 Dec 2010 18:00:24 -0800 Subject: staging: brcm80211: move dma specific macros from osl to dma code Signed-off-by: Brett Rudley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/include/bcmutils.h | 8 ++++++++ drivers/staging/brcm80211/include/osl.h | 23 ----------------------- drivers/staging/brcm80211/util/hnddma.c | 16 ++++++++++++---- drivers/staging/brcm80211/util/siutils.c | 2 +- 4 files changed, 21 insertions(+), 28 deletions(-) diff --git a/drivers/staging/brcm80211/include/bcmutils.h b/drivers/staging/brcm80211/include/bcmutils.h index e673dfd21622..3628fd6a997b 100644 --- a/drivers/staging/brcm80211/include/bcmutils.h +++ b/drivers/staging/brcm80211/include/bcmutils.h @@ -361,6 +361,14 @@ extern struct sk_buff *pktq_mdeq(struct pktq *pq, uint prec_bmp, int *prec_out); #define CEIL(x, y) (((x) + ((y)-1)) / (y)) #define ISPOWEROF2(x) ((((x)-1)&(x)) == 0) +/* map physical to virtual I/O */ +#if !defined(CONFIG_MMC_MSM7X00A) +#define REG_MAP(pa, size) ioremap_nocache((unsigned long)(pa), \ + (unsigned long)(size)) +#else +#define REG_MAP(pa, size) (void *)(0) +#endif + /* bit map related macros */ #ifndef setbit #ifndef NBBY /* the BSD family defines NBBY */ diff --git a/drivers/staging/brcm80211/include/osl.h b/drivers/staging/brcm80211/include/osl.h index 4e7d07e38782..b066f1473468 100644 --- a/drivers/staging/brcm80211/include/osl.h +++ b/drivers/staging/brcm80211/include/osl.h @@ -219,29 +219,6 @@ extern void osl_dma_unmap(struct osl_info *osh, uint pa, uint size, #define bcopy(src, dst, len) memcpy((dst), (src), (len)) -/* uncached/cached virtual address */ -#ifdef __mips__ -#include -#define OSL_UNCACHED(va) ((void *)KSEG1ADDR((va))) -#define OSL_CACHED(va) ((void *)KSEG0ADDR((va))) -#else -#define OSL_UNCACHED(va) ((void *)va) -#define OSL_CACHED(va) ((void *)va) -#endif /* mips */ - -/* map/unmap physical to virtual I/O */ -#if !defined(CONFIG_MMC_MSM7X00A) -#define REG_MAP(pa, size) ioremap_nocache((unsigned long)(pa), \ - (unsigned long)(size)) -#else -#define REG_MAP(pa, size) (void *)(0) -#endif /* !defined(CONFIG_MMC_MSM7X00A */ -#define REG_UNMAP(va) iounmap((va)) - -#define R_SM(r) (*(r)) -#define W_SM(r, v) (*(r) = (v)) -#define BZERO_SM(r, len) memset((r), '\0', (len)) - /* packet primitives */ #define PKTGET(osh, len, send) osl_pktget((osh), (len)) #define PKTFREE(osh, skb, send) osl_pktfree((osh), (skb), (send)) diff --git a/drivers/staging/brcm80211/util/hnddma.c b/drivers/staging/brcm80211/util/hnddma.c index 996998d805e0..0c8a1d25d98b 100644 --- a/drivers/staging/brcm80211/util/hnddma.c +++ b/drivers/staging/brcm80211/util/hnddma.c @@ -29,6 +29,10 @@ #include #include +#if defined(__mips__) +#include +#endif + /* debug/trace */ #ifdef BCMDBG #define DMA_ERROR(args) \ @@ -69,6 +73,9 @@ static uint dma_msg_level; #define DI_INFO(dmah) ((dma_info_t *)dmah) +#define R_SM(r) (*(r)) +#define W_SM(r, v) (*(r) = (v)) + /* dma engine software state */ typedef struct dma_info { struct hnddma_pub hnddma; /* exported structure, don't use hnddma_t, @@ -903,7 +910,7 @@ static void _dma_rxinit(dma_info_t *di) /* clear rx descriptor ring */ if (DMA64_ENAB(di) && DMA64_MODE(di)) { - BZERO_SM((void *)di->rxd64, + memset((void *)di->rxd64, '\0', (di->nrxd * sizeof(dma64dd_t))); /* DMA engine with out alignment requirement requires table to be inited @@ -917,7 +924,7 @@ static void _dma_rxinit(dma_info_t *di) if (di->aligndesc_4k) _dma_ddtable_init(di, DMA_RX, di->rxdpa); } else if (DMA32_ENAB(di)) { - BZERO_SM((void *)di->rxd32, + memset((void *)di->rxd32, '\0', (di->nrxd * sizeof(dma32dd_t))); _dma_rxenable(di); _dma_ddtable_init(di, DMA_RX, di->rxdpa); @@ -993,6 +1000,7 @@ static void *BCMFASTPATH _dma_rx(dma_info_t *di) DMA_TRACE(("%s: dma_rx len %d\n", di->name, len)); #if defined(__mips__) +#define OSL_UNCACHED(va) ((void *)KSEG1ADDR((va))) if (!len) { while (!(len = *(u16 *) OSL_UNCACHED(head->data))) udelay(1); @@ -1436,7 +1444,7 @@ static void dma32_txinit(dma_info_t *di) di->hnddma.txavail = di->ntxd - 1; /* clear tx descriptor ring */ - BZERO_SM((void *)di->txd32, (di->ntxd * sizeof(dma32dd_t))); + memset((void *)di->txd32, '\0', (di->ntxd * sizeof(dma32dd_t))); if ((di->hnddma.dmactrlflags & DMA_CTRL_PEN) == 0) control |= XC_PD; @@ -1992,7 +2000,7 @@ static void dma64_txinit(dma_info_t *di) di->hnddma.txavail = di->ntxd - 1; /* clear tx descriptor ring */ - BZERO_SM((void *)di->txd64, (di->ntxd * sizeof(dma64dd_t))); + memset((void *)di->txd64, '\0', (di->ntxd * sizeof(dma64dd_t))); /* DMA engine with out alignment requirement requires table to be inited * before enabling the engine diff --git a/drivers/staging/brcm80211/util/siutils.c b/drivers/staging/brcm80211/util/siutils.c index 59167122943c..b66de9b35a5a 100644 --- a/drivers/staging/brcm80211/util/siutils.c +++ b/drivers/staging/brcm80211/util/siutils.c @@ -710,7 +710,7 @@ void si_detach(si_t *sih) if (sih->bustype == SI_BUS) for (idx = 0; idx < SI_MAXCORES; idx++) if (sii->regs[idx]) { - REG_UNMAP(sii->regs[idx]); + iounmap(sii->regs[idx]); sii->regs[idx] = NULL; } -- cgit v1.2.3 From 326a67977c15715d627525deade9e859f5cd5646 Mon Sep 17 00:00:00 2001 From: Brett Rudley Date: Fri, 3 Dec 2010 18:00:25 -0800 Subject: staging: brcm80211: migrate register ops macros to bcmutils.h Signed-off-by: Brett Rudley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/include/bcmutils.h | 8 +++++++- drivers/staging/brcm80211/include/osl.h | 6 ------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/staging/brcm80211/include/bcmutils.h b/drivers/staging/brcm80211/include/bcmutils.h index 3628fd6a997b..a8f76d8199ff 100644 --- a/drivers/staging/brcm80211/include/bcmutils.h +++ b/drivers/staging/brcm80211/include/bcmutils.h @@ -369,7 +369,13 @@ extern struct sk_buff *pktq_mdeq(struct pktq *pq, uint prec_bmp, int *prec_out); #define REG_MAP(pa, size) (void *)(0) #endif -/* bit map related macros */ +/* Register operations */ +#define AND_REG(osh, r, v) W_REG(osh, (r), R_REG(osh, r) & (v)) +#define OR_REG(osh, r, v) W_REG(osh, (r), R_REG(osh, r) | (v)) + +#define SET_REG(osh, r, mask, val) \ + W_REG((osh), (r), ((R_REG((osh), r) & ~(mask)) | (val))) + #ifndef setbit #ifndef NBBY /* the BSD family defines NBBY */ #define NBBY 8 /* 8 bits per byte */ diff --git a/drivers/staging/brcm80211/include/osl.h b/drivers/staging/brcm80211/include/osl.h index b066f1473468..c99920b52e9d 100644 --- a/drivers/staging/brcm80211/include/osl.h +++ b/drivers/staging/brcm80211/include/osl.h @@ -214,9 +214,6 @@ extern void osl_dma_unmap(struct osl_info *osh, uint pa, uint size, } while (0) #endif /* IL_BIGENDIAN */ -#define AND_REG(osh, r, v) W_REG(osh, (r), R_REG(osh, r) & (v)) -#define OR_REG(osh, r, v) W_REG(osh, (r), R_REG(osh, r) | (v)) - #define bcopy(src, dst, len) memcpy((dst), (src), (len)) /* packet primitives */ @@ -226,7 +223,4 @@ extern void osl_dma_unmap(struct osl_info *osh, uint pa, uint size, extern void *osl_pktget(struct osl_info *osh, uint len); extern void osl_pktfree(struct osl_info *osh, void *skb, bool send); -#define SET_REG(osh, r, mask, val) \ - W_REG((osh), (r), ((R_REG((osh), r) & ~(mask)) | (val))) - #endif /* _osl_h_ */ -- cgit v1.2.3 From e63449b7171fa19d1d2404179665d5ed146e8990 Mon Sep 17 00:00:00 2001 From: Brett Rudley Date: Fri, 3 Dec 2010 18:00:26 -0800 Subject: staging: brcm80211: Removing cruft from osl.h Signed-off-by: Brett Rudley Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/include/osl.h | 9 --------- 1 file changed, 9 deletions(-) diff --git a/drivers/staging/brcm80211/include/osl.h b/drivers/staging/brcm80211/include/osl.h index c99920b52e9d..54fdfd609729 100644 --- a/drivers/staging/brcm80211/include/osl.h +++ b/drivers/staging/brcm80211/include/osl.h @@ -29,15 +29,6 @@ struct osl_info { typedef struct osl_dmainfo osldma_t; -#ifdef BCMSDIO -/* Drivers use REGOPSSET() to register register read/write funcitons */ -typedef unsigned int (*osl_rreg_fn_t) (void *ctx, void *reg, unsigned int size); -typedef void (*osl_wreg_fn_t) (void *ctx, void *reg, unsigned int val, - unsigned int size); -#endif /* BCMSDIO */ - -#include - extern struct osl_info *osl_attach(void *pdev, uint bustype); extern void osl_detach(struct osl_info *osh); -- cgit v1.2.3 From c6a9e1fc715763175842014a83a9ea70f7e19ace Mon Sep 17 00:00:00 2001 From: Roland Vossen Date: Sat, 4 Dec 2010 08:38:02 +0100 Subject: staging: brcm80211: replaced wlc_info_t by struct wlc_info. Part of code cleanup effort. Global replace of wlc_info_t with struct wlc_info. Signed-off-by: Roland Vossen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/sys/wlc_alloc.c | 11 +- drivers/staging/brcm80211/sys/wlc_alloc.h | 6 +- drivers/staging/brcm80211/sys/wlc_ampdu.c | 29 +- drivers/staging/brcm80211/sys/wlc_ampdu.h | 4 +- drivers/staging/brcm80211/sys/wlc_antsel.c | 4 +- drivers/staging/brcm80211/sys/wlc_antsel.h | 3 +- drivers/staging/brcm80211/sys/wlc_bmac.c | 74 ++--- drivers/staging/brcm80211/sys/wlc_bmac.h | 6 +- drivers/staging/brcm80211/sys/wlc_bsscfg.h | 3 +- drivers/staging/brcm80211/sys/wlc_channel.c | 30 +- drivers/staging/brcm80211/sys/wlc_event.h | 2 +- drivers/staging/brcm80211/sys/wlc_mac80211.c | 452 ++++++++++++++------------- drivers/staging/brcm80211/sys/wlc_mac80211.h | 185 +++++------ drivers/staging/brcm80211/sys/wlc_pub.h | 8 +- drivers/staging/brcm80211/sys/wlc_scb.h | 2 +- drivers/staging/brcm80211/sys/wlc_stf.c | 54 ++-- drivers/staging/brcm80211/sys/wlc_stf.h | 31 +- drivers/staging/brcm80211/sys/wlc_types.h | 2 +- 18 files changed, 460 insertions(+), 446 deletions(-) diff --git a/drivers/staging/brcm80211/sys/wlc_alloc.c b/drivers/staging/brcm80211/sys/wlc_alloc.c index 659ebd0ee2de..980945a065fd 100644 --- a/drivers/staging/brcm80211/sys/wlc_alloc.c +++ b/drivers/staging/brcm80211/sys/wlc_alloc.c @@ -156,7 +156,7 @@ void wlc_bsscfg_mfree(struct osl_info *osh, wlc_bsscfg_t *cfg) kfree(cfg); } -void wlc_bsscfg_ID_assign(wlc_info_t *wlc, wlc_bsscfg_t *bsscfg) +void wlc_bsscfg_ID_assign(struct wlc_info *wlc, wlc_bsscfg_t *bsscfg) { bsscfg->ID = wlc->next_bsscfg_ID; wlc->next_bsscfg_ID++; @@ -165,12 +165,13 @@ void wlc_bsscfg_ID_assign(wlc_info_t *wlc, wlc_bsscfg_t *bsscfg) /* * The common driver entry routine. Error codes should be unique */ -wlc_info_t *wlc_attach_malloc(struct osl_info *osh, uint unit, uint *err, +struct wlc_info *wlc_attach_malloc(struct osl_info *osh, uint unit, uint *err, uint devid) { - wlc_info_t *wlc; + struct wlc_info *wlc; - wlc = (wlc_info_t *) wlc_calloc(osh, unit, sizeof(wlc_info_t)); + wlc = (struct wlc_info *) wlc_calloc(osh, unit, + sizeof(struct wlc_info)); if (wlc == NULL) { *err = 1002; goto fail; @@ -301,7 +302,7 @@ wlc_info_t *wlc_attach_malloc(struct osl_info *osh, uint unit, uint *err, return NULL; } -void wlc_detach_mfree(wlc_info_t *wlc, struct osl_info *osh) +void wlc_detach_mfree(struct wlc_info *wlc, struct osl_info *osh) { if (wlc == NULL) return; diff --git a/drivers/staging/brcm80211/sys/wlc_alloc.h b/drivers/staging/brcm80211/sys/wlc_alloc.h index eedf62912698..ac34f782b400 100644 --- a/drivers/staging/brcm80211/sys/wlc_alloc.h +++ b/drivers/staging/brcm80211/sys/wlc_alloc.h @@ -16,9 +16,9 @@ extern void *wlc_calloc(struct osl_info *osh, uint unit, uint size); -extern wlc_info_t *wlc_attach_malloc(struct osl_info *osh, uint unit, uint *err, - uint devid); -extern void wlc_detach_mfree(wlc_info_t *wlc, struct osl_info *osh); +extern struct wlc_info *wlc_attach_malloc(struct osl_info *osh, uint unit, + uint *err, uint devid); +extern void wlc_detach_mfree(struct wlc_info *wlc, struct osl_info *osh); struct wlc_bsscfg; extern struct wlc_bsscfg *wlc_bsscfg_malloc(struct osl_info *osh, uint unit); diff --git a/drivers/staging/brcm80211/sys/wlc_ampdu.c b/drivers/staging/brcm80211/sys/wlc_ampdu.c index 86563b5860a2..9e1816b88108 100644 --- a/drivers/staging/brcm80211/sys/wlc_ampdu.c +++ b/drivers/staging/brcm80211/sys/wlc_ampdu.c @@ -98,7 +98,7 @@ typedef struct wlc_fifo_info { /* AMPDU module specific state */ struct ampdu_info { - wlc_info_t *wlc; /* pointer to main wlc structure */ + struct wlc_info *wlc; /* pointer to main wlc structure */ int scb_handle; /* scb cubby handle to retrieve data from scb */ u8 ini_enable[AMPDU_MAX_SCB_TID]; /* per-tid initiator enable/disable of ampdu */ u8 ba_tx_wsize; /* Tx ba window size (in pdu) */ @@ -131,7 +131,7 @@ struct ampdu_info { #define SCB_AMPDU_INI(scb_ampdu, tid) (&(scb_ampdu->ini[tid])) static void wlc_ffpld_init(ampdu_info_t *ampdu); -static int wlc_ffpld_check_txfunfl(wlc_info_t *wlc, int f); +static int wlc_ffpld_check_txfunfl(struct wlc_info *wlc, int f); static void wlc_ffpld_calc_mcs2ampdu_table(ampdu_info_t *ampdu, int f); static scb_ampdu_tid_ini_t *wlc_ampdu_init_tid_ini(ampdu_info_t *ampdu, @@ -149,7 +149,7 @@ static void wlc_ampdu_dotxstatus_complete(ampdu_info_t *ampdu, struct scb *scb, struct sk_buff *p, tx_status_t *txs, u32 frmtxstatus, u32 frmtxstatus2); -static inline u16 pkt_txh_seqnum(wlc_info_t *wlc, struct sk_buff *p) +static inline u16 pkt_txh_seqnum(struct wlc_info *wlc, struct sk_buff *p) { d11txh_t *txh; struct dot11_header *h; @@ -158,7 +158,7 @@ static inline u16 pkt_txh_seqnum(wlc_info_t *wlc, struct sk_buff *p) return ltoh16(h->seq) >> SEQNUM_SHIFT; } -ampdu_info_t *wlc_ampdu_attach(wlc_info_t *wlc) +ampdu_info_t *wlc_ampdu_attach(struct wlc_info *wlc) { ampdu_info_t *ampdu; int i; @@ -317,7 +317,7 @@ static void wlc_ffpld_init(ampdu_info_t *ampdu) * Return 1 if pre-loading not active, -1 if not an underflow event, * 0 if pre-loading module took care of the event. */ -static int wlc_ffpld_check_txfunfl(wlc_info_t *wlc, int fid) +static int wlc_ffpld_check_txfunfl(struct wlc_info *wlc, int fid) { ampdu_info_t *ampdu = wlc->ampdu; u32 phy_rate = MCS_RATE(FFPLD_MAX_MCS, true, false); @@ -491,7 +491,7 @@ int BCMFASTPATH wlc_sendampdu(ampdu_info_t *ampdu, wlc_txq_info_t *qi, struct sk_buff **pdu, int prec) { - wlc_info_t *wlc; + struct wlc_info *wlc; struct osl_info *osh; struct sk_buff *p, *pkt[AMPDU_MAX_MPDU]; u8 tid, ndelim; @@ -889,7 +889,7 @@ wlc_ampdu_dotxstatus(ampdu_info_t *ampdu, struct scb *scb, struct sk_buff *p, tx_status_t *txs) { scb_ampdu_t *scb_ampdu; - wlc_info_t *wlc = ampdu->wlc; + struct wlc_info *wlc = ampdu->wlc; scb_ampdu_tid_ini_t *ini; u32 s1 = 0, s2 = 0; struct ieee80211_tx_info *tx_info; @@ -932,11 +932,8 @@ wlc_ampdu_dotxstatus(ampdu_info_t *ampdu, struct scb *scb, struct sk_buff *p, wlc_ampdu_txflowcontrol(wlc, scb_ampdu, ini); } -void rate_status(wlc_info_t *wlc, struct ieee80211_tx_info *tx_info, - tx_status_t *txs, u8 mcs); - void -rate_status(wlc_info_t *wlc, struct ieee80211_tx_info *tx_info, +rate_status(struct wlc_info *wlc, struct ieee80211_tx_info *tx_info, tx_status_t *txs, u8 mcs) { struct ieee80211_tx_rate *txrate = tx_info->status.rates; @@ -957,7 +954,7 @@ wlc_ampdu_dotxstatus_complete(ampdu_info_t *ampdu, struct scb *scb, u32 s1, u32 s2) { scb_ampdu_t *scb_ampdu; - wlc_info_t *wlc = ampdu->wlc; + struct wlc_info *wlc = ampdu->wlc; scb_ampdu_tid_ini_t *ini; u8 bitmap[8], queue, tid; d11txh_t *txh; @@ -1226,7 +1223,7 @@ static scb_ampdu_tid_ini_t *wlc_ampdu_init_tid_ini(ampdu_info_t *ampdu, int wlc_ampdu_set(ampdu_info_t *ampdu, bool on) { - wlc_info_t *wlc = ampdu->wlc; + struct wlc_info *wlc = ampdu->wlc; wlc->pub->_ampdu = false; @@ -1313,7 +1310,7 @@ wlc_ampdu_null_delim_cnt(ampdu_info_t *ampdu, struct scb *scb, return 0; } -void wlc_ampdu_macaddr_upd(wlc_info_t *wlc) +void wlc_ampdu_macaddr_upd(struct wlc_info *wlc) { char template[T_RAM_ACCESS_SZ * 2]; @@ -1324,14 +1321,14 @@ void wlc_ampdu_macaddr_upd(wlc_info_t *wlc) template); } -bool wlc_aggregatable(wlc_info_t *wlc, u8 tid) +bool wlc_aggregatable(struct wlc_info *wlc, u8 tid) { return wlc->ampdu->ini_enable[tid]; } void wlc_ampdu_shm_upd(ampdu_info_t *ampdu) { - wlc_info_t *wlc = ampdu->wlc; + struct wlc_info *wlc = ampdu->wlc; /* Extend ucode internal watchdog timer to match larger received frames */ if ((ampdu->rx_factor & HT_PARAMS_RX_FACTOR_MASK) == diff --git a/drivers/staging/brcm80211/sys/wlc_ampdu.h b/drivers/staging/brcm80211/sys/wlc_ampdu.h index c86411beac11..4c3358da89e5 100644 --- a/drivers/staging/brcm80211/sys/wlc_ampdu.h +++ b/drivers/staging/brcm80211/sys/wlc_ampdu.h @@ -17,7 +17,7 @@ #ifndef _wlc_ampdu_h_ #define _wlc_ampdu_h_ -extern ampdu_info_t *wlc_ampdu_attach(wlc_info_t *wlc); +extern ampdu_info_t *wlc_ampdu_attach(struct wlc_info *wlc); extern void wlc_ampdu_detach(ampdu_info_t *ampdu); extern bool wlc_ampdu_cap(ampdu_info_t *ampdu); extern int wlc_ampdu_set(ampdu_info_t *ampdu, bool on); @@ -26,7 +26,7 @@ extern int wlc_sendampdu(ampdu_info_t *ampdu, wlc_txq_info_t *qi, extern void wlc_ampdu_dotxstatus(ampdu_info_t *ampdu, struct scb *scb, struct sk_buff *p, tx_status_t *txs); extern void wlc_ampdu_reset(ampdu_info_t *ampdu); -extern void wlc_ampdu_macaddr_upd(wlc_info_t *wlc); +extern void wlc_ampdu_macaddr_upd(struct wlc_info *wlc); extern void wlc_ampdu_shm_upd(ampdu_info_t *ampdu); extern u8 wlc_ampdu_null_delim_cnt(ampdu_info_t *ampdu, struct scb *scb, diff --git a/drivers/staging/brcm80211/sys/wlc_antsel.c b/drivers/staging/brcm80211/sys/wlc_antsel.c index 4e4571a098f7..ee577c8c80f5 100644 --- a/drivers/staging/brcm80211/sys/wlc_antsel.c +++ b/drivers/staging/brcm80211/sys/wlc_antsel.c @@ -93,7 +93,7 @@ const u8 mimo_2x3_div_antselid_tbl[16] = { 0, 0, 0, 0, 0, 0, 0, 0 /* pat to antselid */ }; -antsel_info_t *wlc_antsel_attach(wlc_info_t *wlc, struct osl_info *osh, +antsel_info_t *wlc_antsel_attach(struct wlc_info *wlc, struct osl_info *osh, wlc_pub_t *pub, wlc_hw_info_t *wlc_hw) { antsel_info_t *asi; @@ -297,7 +297,7 @@ static u16 wlc_antsel_antcfg2antsel(antsel_info_t *asi, u8 ant_cfg) /* boardlevel antenna selection: ucode interface control */ static int wlc_antsel_cfgupd(antsel_info_t *asi, wlc_antselcfg_t *antsel) { - wlc_info_t *wlc = asi->wlc; + struct wlc_info *wlc = asi->wlc; u8 ant_cfg; u16 mimo_antsel; diff --git a/drivers/staging/brcm80211/sys/wlc_antsel.h b/drivers/staging/brcm80211/sys/wlc_antsel.h index f3361f8106e8..30c66dda77ee 100644 --- a/drivers/staging/brcm80211/sys/wlc_antsel.h +++ b/drivers/staging/brcm80211/sys/wlc_antsel.h @@ -16,7 +16,8 @@ #ifndef _wlc_antsel_h_ #define _wlc_antsel_h_ -extern antsel_info_t *wlc_antsel_attach(wlc_info_t *wlc, struct osl_info *osh, +extern antsel_info_t *wlc_antsel_attach(struct wlc_info *wlc, + struct osl_info *osh, wlc_pub_t *pub, wlc_hw_info_t *wlc_hw); extern void wlc_antsel_detach(antsel_info_t *asi); diff --git a/drivers/staging/brcm80211/sys/wlc_bmac.c b/drivers/staging/brcm80211/sys/wlc_bmac.c index 79ee24f3b07f..2abee6f527f9 100644 --- a/drivers/staging/brcm80211/sys/wlc_bmac.c +++ b/drivers/staging/brcm80211/sys/wlc_bmac.c @@ -113,7 +113,7 @@ static u16 xmtfifo_sz[][NFIFO] = { }; static void wlc_clkctl_clk(wlc_hw_info_t *wlc, uint mode); -static void wlc_coreinit(wlc_info_t *wlc); +static void wlc_coreinit(struct wlc_info *wlc); /* used by wlc_wakeucode_init() */ static void wlc_write_inits(wlc_hw_info_t *wlc_hw, const d11init_t *inits); @@ -130,7 +130,7 @@ static bool wlc_bmac_txstatus(wlc_hw_info_t *wlc, bool bound, bool *fatal); static bool wlc_bmac_recv(wlc_hw_info_t *wlc_hw, uint fifo, bool bound); /* used by wlc_down() */ -static void wlc_flushqueues(wlc_info_t *wlc); +static void wlc_flushqueues(struct wlc_info *wlc); static void wlc_write_mhf(wlc_hw_info_t *wlc_hw, u16 *mhfs); static void wlc_mctrl_reset(wlc_hw_info_t *wlc_hw); @@ -141,25 +141,25 @@ static u16 wlc_bmac_read_objmem(wlc_hw_info_t *wlc_hw, uint offset, u32 sel); static void wlc_bmac_write_objmem(wlc_hw_info_t *wlc_hw, uint offset, u16 v, u32 sel); -static bool wlc_bmac_attach_dmapio(wlc_info_t *wlc, uint j, bool wme); +static bool wlc_bmac_attach_dmapio(struct wlc_info *wlc, uint j, bool wme); static void wlc_bmac_detach_dmapio(wlc_hw_info_t *wlc_hw); static void wlc_ucode_bsinit(wlc_hw_info_t *wlc_hw); static bool wlc_validboardtype(wlc_hw_info_t *wlc); static bool wlc_isgoodchip(wlc_hw_info_t *wlc_hw); static char *wlc_get_macaddr(wlc_hw_info_t *wlc_hw); -static void wlc_mhfdef(wlc_info_t *wlc, u16 *mhfs, u16 mhf2_init); +static void wlc_mhfdef(struct wlc_info *wlc, u16 *mhfs, u16 mhf2_init); static void wlc_mctrl_write(wlc_hw_info_t *wlc_hw); static void wlc_ucode_mute_override_set(wlc_hw_info_t *wlc_hw); static void wlc_ucode_mute_override_clear(wlc_hw_info_t *wlc_hw); -static u32 wlc_wlintrsoff(wlc_info_t *wlc); -static void wlc_wlintrsrestore(wlc_info_t *wlc, u32 macintmask); -static void wlc_gpio_init(wlc_info_t *wlc); +static u32 wlc_wlintrsoff(struct wlc_info *wlc); +static void wlc_wlintrsrestore(struct wlc_info *wlc, u32 macintmask); +static void wlc_gpio_init(struct wlc_info *wlc); static void wlc_write_hw_bcntemplate0(wlc_hw_info_t *wlc_hw, void *bcn, int len); static void wlc_write_hw_bcntemplate1(wlc_hw_info_t *wlc_hw, void *bcn, int len); -static void wlc_bmac_bsinit(wlc_info_t *wlc, chanspec_t chanspec); -static u32 wlc_setband_inact(wlc_info_t *wlc, uint bandunit); +static void wlc_bmac_bsinit(struct wlc_info *wlc, chanspec_t chanspec); +static u32 wlc_setband_inact(struct wlc_info *wlc, uint bandunit); static void wlc_bmac_setband(wlc_hw_info_t *wlc_hw, uint bandunit, chanspec_t chanspec); static void wlc_bmac_update_slot_timing(wlc_hw_info_t *wlc_hw, bool shortslot); @@ -231,7 +231,7 @@ static void WLBANDINITFN(wlc_ucode_bsinit) (wlc_hw_info_t *wlc_hw) } /* switch to new band but leave it inactive */ -static u32 WLBANDINITFN(wlc_setband_inact) (wlc_info_t *wlc, uint bandunit) +static u32 WLBANDINITFN(wlc_setband_inact) (struct wlc_info *wlc, uint bandunit) { wlc_hw_info_t *wlc_hw = wlc->hw; u32 macintmask; @@ -322,7 +322,7 @@ wlc_bmac_recv(wlc_hw_info_t *wlc_hw, uint fifo, bool bound) * Return true if another dpc needs to be re-scheduled. false otherwise. * Param 'bounded' indicates if applicable loops should be bounded. */ -bool BCMFASTPATH wlc_dpc(wlc_info_t *wlc, bool bounded) +bool BCMFASTPATH wlc_dpc(struct wlc_info *wlc, bool bounded) { u32 macintstatus; wlc_hw_info_t *wlc_hw = wlc->hw; @@ -451,7 +451,7 @@ bool BCMFASTPATH wlc_dpc(wlc_info_t *wlc, bool bounded) /* common low-level watchdog code */ void wlc_bmac_watchdog(void *arg) { - wlc_info_t *wlc = (wlc_info_t *) arg; + struct wlc_info *wlc = (struct wlc_info *) arg; wlc_hw_info_t *wlc_hw = wlc->hw; WL_TRACE(("wl%d: wlc_bmac_watchdog\n", wlc_hw->unit)); @@ -564,7 +564,7 @@ int wlc_bmac_state_get(wlc_hw_info_t *wlc_hw, wlc_bmac_state_t *state) return 0; } -static bool wlc_bmac_attach_dmapio(wlc_info_t *wlc, uint j, bool wme) +static bool wlc_bmac_attach_dmapio(struct wlc_info *wlc, uint j, bool wme) { uint i; char name[8]; @@ -700,7 +700,7 @@ static void wlc_bmac_detach_dmapio(wlc_hw_info_t *wlc_hw) * initialize software state for each core and band * put the whole chip in reset(driver down state), no clock */ -int wlc_bmac_attach(wlc_info_t *wlc, u16 vendor, u16 device, uint unit, +int wlc_bmac_attach(struct wlc_info *wlc, u16 vendor, u16 device, uint unit, bool piomode, struct osl_info *osh, void *regsva, uint bustype, void *btparam) { @@ -1045,7 +1045,7 @@ int wlc_bmac_attach(wlc_info_t *wlc, u16 vendor, u16 device, uint unit, */ void wlc_bmac_info_init(wlc_hw_info_t *wlc_hw) { - wlc_info_t *wlc = wlc_hw->wlc; + struct wlc_info *wlc = wlc_hw->wlc; /* set default sw macintmask value */ wlc->defmacintmask = DEF_MACINTMASK; @@ -1065,7 +1065,7 @@ void wlc_bmac_info_init(wlc_hw_info_t *wlc_hw) /* * low level detach */ -int wlc_bmac_detach(wlc_info_t *wlc) +int wlc_bmac_detach(struct wlc_info *wlc) { uint i; wlc_hwband_t *band; @@ -1137,7 +1137,7 @@ wlc_bmac_init(wlc_hw_info_t *wlc_hw, chanspec_t chanspec, bool mute) { u32 macintmask; bool fastclk; - wlc_info_t *wlc = wlc_hw->wlc; + struct wlc_info *wlc = wlc_hw->wlc; WL_TRACE(("wl%d: wlc_bmac_init\n", wlc_hw->unit)); @@ -1349,7 +1349,7 @@ int wlc_bmac_bandtype(wlc_hw_info_t *wlc_hw) return wlc_hw->band->bandtype; } -void *wlc_cur_phy(wlc_info_t *wlc) +void *wlc_cur_phy(struct wlc_info *wlc) { wlc_hw_info_t *wlc_hw = wlc->hw; return (void *)wlc_hw->band->pi; @@ -1453,7 +1453,7 @@ static void wlc_clkctl_clk(wlc_hw_info_t *wlc_hw, uint mode) /* set initial host flags value */ static void -wlc_mhfdef(wlc_info_t *wlc, u16 *mhfs, u16 mhf2_init) +wlc_mhfdef(struct wlc_info *wlc, u16 *mhfs, u16 mhf2_init) { wlc_hw_info_t *wlc_hw = wlc->hw; @@ -1912,7 +1912,7 @@ wlc_bmac_write_hw_bcntemplates(wlc_hw_info_t *wlc_hw, void *bcn, int len, static void WLBANDINITFN(wlc_bmac_upd_synthpu) (wlc_hw_info_t *wlc_hw) { u16 v; - wlc_info_t *wlc = wlc_hw->wlc; + struct wlc_info *wlc = wlc_hw->wlc; /* update SYNTHPU_DLY */ if (WLCISLCNPHY(wlc->band)) { @@ -1928,7 +1928,7 @@ static void WLBANDINITFN(wlc_bmac_upd_synthpu) (wlc_hw_info_t *wlc_hw) /* band-specific init */ static void -WLBANDINITFN(wlc_bmac_bsinit) (wlc_info_t *wlc, chanspec_t chanspec) +WLBANDINITFN(wlc_bmac_bsinit) (struct wlc_info *wlc, chanspec_t chanspec) { wlc_hw_info_t *wlc_hw = wlc->hw; @@ -2080,7 +2080,7 @@ void wlc_bmac_phy_reset(wlc_hw_info_t *wlc_hw) static void WLBANDINITFN(wlc_bmac_setband) (wlc_hw_info_t *wlc_hw, uint bandunit, chanspec_t chanspec) { - wlc_info_t *wlc = wlc_hw->wlc; + struct wlc_info *wlc = wlc_hw->wlc; u32 macintmask; ASSERT(NBANDS_HW(wlc_hw) > 1); @@ -2471,7 +2471,7 @@ static void wlc_corerev_fifofixup(wlc_hw_info_t *wlc_hw) * config other core registers * init dma */ -static void wlc_coreinit(wlc_info_t *wlc) +static void wlc_coreinit(struct wlc_info *wlc) { wlc_hw_info_t *wlc_hw = wlc->hw; d11regs_t *regs; @@ -2713,7 +2713,7 @@ void wlc_bmac_switch_macfreq(wlc_hw_info_t *wlc_hw, u8 spurmode) } /* Initialize GPIOs that are controlled by D11 core */ -static void wlc_gpio_init(wlc_info_t *wlc) +static void wlc_gpio_init(struct wlc_info *wlc) { wlc_hw_info_t *wlc_hw = wlc->hw; d11regs_t *regs; @@ -2780,7 +2780,7 @@ static void wlc_gpio_init(wlc_info_t *wlc) static void wlc_ucode_download(wlc_hw_info_t *wlc_hw) { - wlc_info_t *wlc; + struct wlc_info *wlc; wlc = wlc_hw->wlc; if (wlc_hw->ucode_loaded) @@ -2960,7 +2960,7 @@ void wlc_bmac_fifoerrors(wlc_hw_info_t *wlc_hw) } } -void wlc_intrson(wlc_info_t *wlc) +void wlc_intrson(struct wlc_info *wlc) { wlc_hw_info_t *wlc_hw = wlc->hw; ASSERT(wlc->defmacintmask); @@ -2973,7 +2973,7 @@ void wlc_intrson(wlc_info_t *wlc) * but also because per-port code may require sync with valid interrupt. */ -static u32 wlc_wlintrsoff(wlc_info_t *wlc) +static u32 wlc_wlintrsoff(struct wlc_info *wlc) { if (!wlc->hw->up) return 0; @@ -2981,7 +2981,7 @@ static u32 wlc_wlintrsoff(wlc_info_t *wlc) return wl_intrsoff(wlc->wl); } -static void wlc_wlintrsrestore(wlc_info_t *wlc, u32 macintmask) +static void wlc_wlintrsrestore(struct wlc_info *wlc, u32 macintmask) { if (!wlc->hw->up) return; @@ -2989,7 +2989,7 @@ static void wlc_wlintrsrestore(wlc_info_t *wlc, u32 macintmask) wl_intrsrestore(wlc->wl, macintmask); } -u32 wlc_intrsoff(wlc_info_t *wlc) +u32 wlc_intrsoff(struct wlc_info *wlc) { wlc_hw_info_t *wlc_hw = wlc->hw; u32 macintmask; @@ -3008,7 +3008,7 @@ u32 wlc_intrsoff(wlc_info_t *wlc) return wlc->macintstatus ? 0 : macintmask; } -void wlc_intrsrestore(wlc_info_t *wlc, u32 macintmask) +void wlc_intrsrestore(struct wlc_info *wlc, u32 macintmask) { wlc_hw_info_t *wlc_hw = wlc->hw; if (!wlc_hw->clk) @@ -3167,7 +3167,7 @@ void wlc_bmac_tx_fifo_resume(wlc_hw_info_t *wlc_hw, uint tx_fifo) * 0 if the interrupt is not for us, or we are in some special cases; * device interrupt status bits otherwise. */ -static inline u32 wlc_intstatus(wlc_info_t *wlc, bool in_isr) +static inline u32 wlc_intstatus(struct wlc_info *wlc, bool in_isr) { wlc_hw_info_t *wlc_hw = wlc->hw; d11regs_t *regs = wlc_hw->regs; @@ -3257,7 +3257,7 @@ static inline u32 wlc_intstatus(wlc_info_t *wlc, bool in_isr) /* Update wlc->macintstatus and wlc->intstatus[]. */ /* Return true if they are updated successfully. false otherwise */ -bool wlc_intrsupd(wlc_info_t *wlc) +bool wlc_intrsupd(struct wlc_info *wlc) { u32 macintstatus; @@ -3282,7 +3282,7 @@ bool wlc_intrsupd(wlc_info_t *wlc) * *wantdpc will be set to true if further wlc_dpc() processing is required, * false otherwise. */ -bool BCMFASTPATH wlc_isr(wlc_info_t *wlc, bool *wantdpc) +bool BCMFASTPATH wlc_isr(struct wlc_info *wlc, bool *wantdpc) { wlc_hw_info_t *wlc_hw = wlc->hw; u32 macintstatus; @@ -3371,7 +3371,7 @@ static bool BCMFASTPATH wlc_bmac_txstatus(wlc_hw_info_t *wlc_hw, bool bound, bool *fatal) { bool morepending = false; - wlc_info_t *wlc = wlc_hw->wlc; + struct wlc_info *wlc = wlc_hw->wlc; WL_TRACE(("wl%d: wlc_bmac_txstatus\n", wlc_hw->unit)); @@ -3432,7 +3432,7 @@ wlc_bmac_txstatus(wlc_hw_info_t *wlc_hw, bool bound, bool *fatal) return morepending; } -void wlc_suspend_mac_and_wait(wlc_info_t *wlc) +void wlc_suspend_mac_and_wait(struct wlc_info *wlc) { wlc_hw_info_t *wlc_hw = wlc->hw; d11regs_t *regs = wlc_hw->regs; @@ -3496,7 +3496,7 @@ void wlc_suspend_mac_and_wait(wlc_info_t *wlc) ASSERT(!(mc & MCTL_EN_MAC)); } -void wlc_enable_mac(wlc_info_t *wlc) +void wlc_enable_mac(struct wlc_info *wlc) { wlc_hw_info_t *wlc_hw = wlc->hw; d11regs_t *regs = wlc_hw->regs; @@ -3872,7 +3872,7 @@ void wlc_bmac_xtal(wlc_hw_info_t *wlc_hw, bool want) } } -static void wlc_flushqueues(wlc_info_t *wlc) +static void wlc_flushqueues(struct wlc_info *wlc) { wlc_hw_info_t *wlc_hw = wlc->hw; uint i; diff --git a/drivers/staging/brcm80211/sys/wlc_bmac.h b/drivers/staging/brcm80211/sys/wlc_bmac.h index c705f667469c..03ad275cfc58 100644 --- a/drivers/staging/brcm80211/sys/wlc_bmac.h +++ b/drivers/staging/brcm80211/sys/wlc_bmac.h @@ -57,7 +57,7 @@ typedef struct wlc_bmac_revinfo { } band[MAXBANDS]; } wlc_bmac_revinfo_t; -/* dup state between BMAC(wlc_hw_info_t) and HIGH(wlc_info_t) driver */ +/* dup state between BMAC(wlc_hw_info_t) and HIGH(struct wlc_info) driver */ typedef struct wlc_bmac_state { u32 machwcap; /* mac hw capibility */ u32 preamble_ovr; /* preamble override */ @@ -130,10 +130,10 @@ typedef enum { WLCHW_STATE_LAST } wlc_bmac_state_id_t; -extern int wlc_bmac_attach(wlc_info_t *wlc, u16 vendor, u16 device, +extern int wlc_bmac_attach(struct wlc_info *wlc, u16 vendor, u16 device, uint unit, bool piomode, struct osl_info *osh, void *regsva, uint bustype, void *btparam); -extern int wlc_bmac_detach(wlc_info_t *wlc); +extern int wlc_bmac_detach(struct wlc_info *wlc); extern void wlc_bmac_watchdog(void *arg); extern void wlc_bmac_info_init(wlc_hw_info_t *wlc_hw); diff --git a/drivers/staging/brcm80211/sys/wlc_bsscfg.h b/drivers/staging/brcm80211/sys/wlc_bsscfg.h index ae5542ab0334..d6a1971c69a0 100644 --- a/drivers/staging/brcm80211/sys/wlc_bsscfg.h +++ b/drivers/staging/brcm80211/sys/wlc_bsscfg.h @@ -34,7 +34,8 @@ typedef struct wlc_bsscfg wlc_bsscfg_t; #define MAXMACLIST 64 /* max # source MAC matches */ #define BCN_TEMPLATE_COUNT 2 -/* Iterator for "associated" STA bss configs: (wlc_info_t *wlc, int idx, wlc_bsscfg_t *cfg) */ +/* Iterator for "associated" STA bss configs: + (struct wlc_info *wlc, int idx, wlc_bsscfg_t *cfg) */ #define FOREACH_AS_STA(wlc, idx, cfg) \ for (idx = 0; (int) idx < WLC_MAXBSSCFG; idx++) \ if ((cfg = (wlc)->bsscfg[idx]) && BSSCFG_STA(cfg) && cfg->associated) diff --git a/drivers/staging/brcm80211/sys/wlc_channel.c b/drivers/staging/brcm80211/sys/wlc_channel.c index bb82a8c008a4..e367ed4f1e91 100644 --- a/drivers/staging/brcm80211/sys/wlc_channel.c +++ b/drivers/staging/brcm80211/sys/wlc_channel.c @@ -45,7 +45,7 @@ typedef struct wlc_cm_band { struct wlc_cm_info { wlc_pub_t *pub; - wlc_info_t *wlc; + struct wlc_info *wlc; char srom_ccode[WLC_CNTRY_BUF_SZ]; /* Country Code in SROM */ uint srom_regrev; /* Regulatory Rev for the SROM ccode */ const country_info_t *country; /* current country def */ @@ -606,7 +606,7 @@ const locale_mimo_info_t *wlc_get_mimo_5g(u8 locale_idx) return g_mimo_5g_table[locale_idx]; } -wlc_cm_info_t *wlc_channel_mgr_attach(wlc_info_t *wlc) +wlc_cm_info_t *wlc_channel_mgr_attach(struct wlc_info *wlc) { wlc_cm_info_t *wlc_cm; char country_abbrev[WLC_CNTRY_BUF_SZ]; @@ -664,7 +664,7 @@ const char *wlc_channel_country_abbrev(wlc_cm_info_t *wlc_cm) u8 wlc_channel_locale_flags(wlc_cm_info_t *wlc_cm) { - wlc_info_t *wlc = wlc_cm->wlc; + struct wlc_info *wlc = wlc_cm->wlc; return wlc_cm->bandstate[wlc->band->bandunit].locale_flags; } @@ -755,7 +755,7 @@ wlc_set_country_common(wlc_cm_info_t *wlc_cm, { const locale_mimo_info_t *li_mimo; const locale_info_t *locale; - wlc_info_t *wlc = wlc_cm->wlc; + struct wlc_info *wlc = wlc_cm->wlc; char prev_country_abbrev[WLC_CNTRY_BUF_SZ]; ASSERT(country != NULL); @@ -819,7 +819,7 @@ static const country_info_t *wlc_countrycode_map(wlc_cm_info_t *wlc_cm, char *mapped_ccode, uint *mapped_regrev) { - wlc_info_t *wlc = wlc_cm->wlc; + struct wlc_info *wlc = wlc_cm->wlc; const country_info_t *country; uint srom_regrev = wlc_cm->srom_regrev; const char *srom_ccode = wlc_cm->srom_ccode; @@ -903,7 +903,7 @@ static const country_info_t *wlc_country_lookup_direct(const char *ccode, static int wlc_channels_init(wlc_cm_info_t *wlc_cm, const country_info_t *country) { - wlc_info_t *wlc = wlc_cm->wlc; + struct wlc_info *wlc = wlc_cm->wlc; uint i, j; wlcband_t *band; const locale_info_t *li; @@ -957,7 +957,7 @@ wlc_channels_init(wlc_cm_info_t *wlc_cm, const country_info_t *country) */ static void wlc_channels_commit(wlc_cm_info_t *wlc_cm) { - wlc_info_t *wlc = wlc_cm->wlc; + struct wlc_info *wlc = wlc_cm->wlc; uint chan; struct txpwr_limits txpwr; @@ -1003,7 +1003,7 @@ static void wlc_channels_commit(wlc_cm_info_t *wlc_cm) /* reset the quiet channels vector to the union of the restricted and radar channel sets */ void wlc_quiet_channels_reset(wlc_cm_info_t *wlc_cm) { - wlc_info_t *wlc = wlc_cm->wlc; + struct wlc_info *wlc = wlc_cm->wlc; uint i, j; wlcband_t *band; const chanvec_t *chanvec; @@ -1041,7 +1041,7 @@ bool wlc_quiet_chanspec(wlc_cm_info_t *wlc_cm, chanspec_t chspec) */ bool wlc_valid_channel20_db(wlc_cm_info_t *wlc_cm, uint val) { - wlc_info_t *wlc = wlc_cm->wlc; + struct wlc_info *wlc = wlc_cm->wlc; return VALID_CHANNEL20(wlc, val) || (!wlc->bandlocked @@ -1059,7 +1059,7 @@ wlc_valid_channel20_in_band(wlc_cm_info_t *wlc_cm, uint bandunit, uint val) /* Is the channel valid for the current locale and current band? */ bool wlc_valid_channel20(wlc_cm_info_t *wlc_cm, uint val) { - wlc_info_t *wlc = wlc_cm->wlc; + struct wlc_info *wlc = wlc_cm->wlc; return ((val < MAXCHANNEL) && isset(wlc_cm->bandstate[wlc->band->bandunit].valid_channels.vec, @@ -1069,7 +1069,7 @@ bool wlc_valid_channel20(wlc_cm_info_t *wlc_cm, uint val) /* Is the 40 MHz allowed for the current locale and specified band? */ bool wlc_valid_40chanspec_in_band(wlc_cm_info_t *wlc_cm, uint bandunit) { - wlc_info_t *wlc = wlc_cm->wlc; + struct wlc_info *wlc = wlc_cm->wlc; return (((wlc_cm->bandstate[bandunit]. locale_flags & (WLC_NO_MIMO | WLC_NO_40MHZ)) == 0) @@ -1167,7 +1167,7 @@ void wlc_channel_set_chanspec(wlc_cm_info_t *wlc_cm, chanspec_t chanspec, u8 local_constraint_qdbm) { - wlc_info_t *wlc = wlc_cm->wlc; + struct wlc_info *wlc = wlc_cm->wlc; struct txpwr_limits txpwr; wlc_channel_reg_limits(wlc_cm, chanspec, &txpwr); @@ -1184,7 +1184,7 @@ int wlc_channel_set_txpower_limit(wlc_cm_info_t *wlc_cm, u8 local_constraint_qdbm) { - wlc_info_t *wlc = wlc_cm->wlc; + struct wlc_info *wlc = wlc_cm->wlc; struct txpwr_limits txpwr; wlc_channel_reg_limits(wlc_cm, wlc->chanspec, &txpwr); @@ -1304,7 +1304,7 @@ void wlc_channel_reg_limits(wlc_cm_info_t *wlc_cm, chanspec_t chanspec, txpwr_limits_t *txpwr) { - wlc_info_t *wlc = wlc_cm->wlc; + struct wlc_info *wlc = wlc_cm->wlc; uint i; uint chan; int maxpwr; @@ -1533,7 +1533,7 @@ static bool wlc_japan_ccode(const char *ccode) static bool wlc_valid_chanspec_ext(wlc_cm_info_t *wlc_cm, chanspec_t chspec, bool dualband) { - wlc_info_t *wlc = wlc_cm->wlc; + struct wlc_info *wlc = wlc_cm->wlc; u8 channel = CHSPEC_CHANNEL(chspec); /* check the chanspec */ diff --git a/drivers/staging/brcm80211/sys/wlc_event.h b/drivers/staging/brcm80211/sys/wlc_event.h index e443dae258b7..7c8e49550f2d 100644 --- a/drivers/staging/brcm80211/sys/wlc_event.h +++ b/drivers/staging/brcm80211/sys/wlc_event.h @@ -38,7 +38,7 @@ extern int wlc_eventq_query_ind(wlc_eventq_t *eq, void *bitvect); extern int wlc_eventq_test_ind(wlc_eventq_t *eq, int et); extern int wlc_eventq_set_ind(wlc_eventq_t *eq, uint et, bool on); extern void wlc_eventq_flush(wlc_eventq_t *eq); -extern void wlc_assign_event_msg(wlc_info_t *wlc, wl_event_msg_t *msg, +extern void wlc_assign_event_msg(struct wlc_info *wlc, wl_event_msg_t *msg, const wlc_event_t *e, u8 *data, u32 len); diff --git a/drivers/staging/brcm80211/sys/wlc_mac80211.c b/drivers/staging/brcm80211/sys/wlc_mac80211.c index fcd3bd18f27c..3e31f893fcc3 100644 --- a/drivers/staging/brcm80211/sys/wlc_mac80211.c +++ b/drivers/staging/brcm80211/sys/wlc_mac80211.c @@ -120,7 +120,7 @@ uint wl_msg_level = #ifdef BCMDBG /* pointer to most recently allocated wl/wlc */ -static wlc_info_t *wlc_info_dbg = (wlc_info_t *) (NULL); +static struct wlc_info *wlc_info_dbg = (struct wlc_info *) (NULL); #endif /* IOVar table */ @@ -221,7 +221,7 @@ static const u8 acbitmap2maxprio[] = { #define WLC_REPLAY_CNTRS_VALUE WPA_CAP_16_REPLAY_CNTRS /* local prototypes */ -static u16 BCMFASTPATH wlc_d11hdrs_mac80211(wlc_info_t *wlc, +static u16 BCMFASTPATH wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, struct sk_buff *p, struct scb *scb, uint frag, @@ -230,76 +230,76 @@ static u16 BCMFASTPATH wlc_d11hdrs_mac80211(wlc_info_t *wlc, wsec_key_t *key, ratespec_t rspec_override); -static void wlc_bss_default_init(wlc_info_t *wlc); -static void wlc_ucode_mac_upd(wlc_info_t *wlc); -static ratespec_t mac80211_wlc_set_nrate(wlc_info_t *wlc, wlcband_t *cur_band, - u32 int_val); -static void wlc_tx_prec_map_init(wlc_info_t *wlc); +static void wlc_bss_default_init(struct wlc_info *wlc); +static void wlc_ucode_mac_upd(struct wlc_info *wlc); +static ratespec_t mac80211_wlc_set_nrate(struct wlc_info *wlc, + wlcband_t *cur_band, u32 int_val); +static void wlc_tx_prec_map_init(struct wlc_info *wlc); static void wlc_watchdog(void *arg); static void wlc_watchdog_by_timer(void *arg); -static int wlc_set_rateset(wlc_info_t *wlc, wlc_rateset_t *rs_arg); -static int wlc_iovar_rangecheck(wlc_info_t *wlc, u32 val, +static int wlc_set_rateset(struct wlc_info *wlc, wlc_rateset_t *rs_arg); +static int wlc_iovar_rangecheck(struct wlc_info *wlc, u32 val, const bcm_iovar_t *vi); -static u8 wlc_local_constraint_qdbm(wlc_info_t *wlc); +static u8 wlc_local_constraint_qdbm(struct wlc_info *wlc); /* send and receive */ -static wlc_txq_info_t *wlc_txq_alloc(wlc_info_t *wlc, struct osl_info *osh); -static void wlc_txq_free(wlc_info_t *wlc, struct osl_info *osh, +static wlc_txq_info_t *wlc_txq_alloc(struct wlc_info *wlc, + struct osl_info *osh); +static void wlc_txq_free(struct wlc_info *wlc, struct osl_info *osh, wlc_txq_info_t *qi); -static void wlc_txflowcontrol_signal(wlc_info_t *wlc, wlc_txq_info_t *qi, +static void wlc_txflowcontrol_signal(struct wlc_info *wlc, wlc_txq_info_t *qi, bool on, int prio); -static void wlc_txflowcontrol_reset(wlc_info_t *wlc); -static u16 wlc_compute_airtime(wlc_info_t *wlc, ratespec_t rspec, +static void wlc_txflowcontrol_reset(struct wlc_info *wlc); +static u16 wlc_compute_airtime(struct wlc_info *wlc, ratespec_t rspec, uint length); static void wlc_compute_cck_plcp(ratespec_t rate, uint length, u8 *plcp); static void wlc_compute_ofdm_plcp(ratespec_t rate, uint length, u8 *plcp); static void wlc_compute_mimo_plcp(ratespec_t rate, uint length, u8 *plcp); -static u16 wlc_compute_frame_dur(wlc_info_t *wlc, ratespec_t rate, +static u16 wlc_compute_frame_dur(struct wlc_info *wlc, ratespec_t rate, u8 preamble_type, uint next_frag_len); -static void wlc_recvctl(wlc_info_t *wlc, struct osl_info *osh, d11rxhdr_t *rxh, - struct sk_buff *p); -static uint wlc_calc_frame_len(wlc_info_t *wlc, ratespec_t rate, +static void wlc_recvctl(struct wlc_info *wlc, struct osl_info *osh, + d11rxhdr_t *rxh, struct sk_buff *p); +static uint wlc_calc_frame_len(struct wlc_info *wlc, ratespec_t rate, u8 preamble_type, uint dur); -static uint wlc_calc_ack_time(wlc_info_t *wlc, ratespec_t rate, +static uint wlc_calc_ack_time(struct wlc_info *wlc, ratespec_t rate, u8 preamble_type); -static uint wlc_calc_cts_time(wlc_info_t *wlc, ratespec_t rate, +static uint wlc_calc_cts_time(struct wlc_info *wlc, ratespec_t rate, u8 preamble_type); /* interrupt, up/down, band */ -static void wlc_setband(wlc_info_t *wlc, uint bandunit); -static chanspec_t wlc_init_chanspec(wlc_info_t *wlc); -static void wlc_bandinit_ordered(wlc_info_t *wlc, chanspec_t chanspec); -static void wlc_bsinit(wlc_info_t *wlc); -static int wlc_duty_cycle_set(wlc_info_t *wlc, int duty_cycle, bool isOFDM, +static void wlc_setband(struct wlc_info *wlc, uint bandunit); +static chanspec_t wlc_init_chanspec(struct wlc_info *wlc); +static void wlc_bandinit_ordered(struct wlc_info *wlc, chanspec_t chanspec); +static void wlc_bsinit(struct wlc_info *wlc); +static int wlc_duty_cycle_set(struct wlc_info *wlc, int duty_cycle, bool isOFDM, bool writeToShm); -static void wlc_radio_hwdisable_upd(wlc_info_t *wlc); -static bool wlc_radio_monitor_start(wlc_info_t *wlc); +static void wlc_radio_hwdisable_upd(struct wlc_info *wlc); +static bool wlc_radio_monitor_start(struct wlc_info *wlc); static void wlc_radio_timer(void *arg); -static void wlc_radio_enable(wlc_info_t *wlc); -static void wlc_radio_upd(wlc_info_t *wlc); +static void wlc_radio_enable(struct wlc_info *wlc); +static void wlc_radio_upd(struct wlc_info *wlc); /* scan, association, BSS */ -static uint wlc_calc_ba_time(wlc_info_t *wlc, ratespec_t rate, +static uint wlc_calc_ba_time(struct wlc_info *wlc, ratespec_t rate, u8 preamble_type); -static void wlc_update_mimo_band_bwcap(wlc_info_t *wlc, u8 bwcap); -static void wlc_ht_update_sgi_rx(wlc_info_t *wlc, int val); -void wlc_ht_mimops_cap_update(wlc_info_t *wlc, u8 mimops_mode); -static void wlc_ht_update_ldpc(wlc_info_t *wlc, s8 val); -static void wlc_war16165(wlc_info_t *wlc, bool tx); +static void wlc_update_mimo_band_bwcap(struct wlc_info *wlc, u8 bwcap); +static void wlc_ht_update_sgi_rx(struct wlc_info *wlc, int val); +static void wlc_ht_update_ldpc(struct wlc_info *wlc, s8 val); +static void wlc_war16165(struct wlc_info *wlc, bool tx); static void wlc_process_eventq(void *arg); -static void wlc_wme_retries_write(wlc_info_t *wlc); -static bool wlc_attach_stf_ant_init(wlc_info_t *wlc); -static uint wlc_attach_module(wlc_info_t *wlc); -static void wlc_detach_module(wlc_info_t *wlc); -static void wlc_timers_deinit(wlc_info_t *wlc); -static void wlc_down_led_upd(wlc_info_t *wlc); -static uint wlc_down_del_timer(wlc_info_t *wlc); -static void wlc_ofdm_rateset_war(wlc_info_t *wlc); -static int _wlc_ioctl(wlc_info_t *wlc, int cmd, void *arg, int len, +static void wlc_wme_retries_write(struct wlc_info *wlc); +static bool wlc_attach_stf_ant_init(struct wlc_info *wlc); +static uint wlc_attach_module(struct wlc_info *wlc); +static void wlc_detach_module(struct wlc_info *wlc); +static void wlc_timers_deinit(struct wlc_info *wlc); +static void wlc_down_led_upd(struct wlc_info *wlc); +static uint wlc_down_del_timer(struct wlc_info *wlc); +static void wlc_ofdm_rateset_war(struct wlc_info *wlc); +static int _wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, struct wlc_if *wlcif); #if defined(BCMDBG) -void wlc_get_rcmta(wlc_info_t *wlc, int idx, struct ether_addr *addr) +void wlc_get_rcmta(struct wlc_info *wlc, int idx, struct ether_addr *addr) { d11regs_t *regs = wlc->regs; u32 v32; @@ -327,14 +327,14 @@ void wlc_get_rcmta(wlc_info_t *wlc, int idx, struct ether_addr *addr) #endif /* defined(BCMDBG) */ /* keep the chip awake if needed */ -bool wlc_stay_awake(wlc_info_t *wlc) +bool wlc_stay_awake(struct wlc_info *wlc) { return true; } /* conditions under which the PM bit should be set in outgoing frames and STAY_AWAKE is meaningful */ -bool wlc_ps_allowed(wlc_info_t *wlc) +bool wlc_ps_allowed(struct wlc_info *wlc) { int idx; wlc_bsscfg_t *cfg; @@ -361,7 +361,7 @@ bool wlc_ps_allowed(wlc_info_t *wlc) return true; } -void wlc_reset(wlc_info_t *wlc) +void wlc_reset(struct wlc_info *wlc) { WL_TRACE(("wl%d: wlc_reset\n", wlc->pub->unit)); @@ -382,7 +382,7 @@ void wlc_reset(wlc_info_t *wlc) } -void wlc_fatal_error(wlc_info_t *wlc) +void wlc_fatal_error(struct wlc_info *wlc) { WL_ERROR(("wl%d: fatal error, reinitializing\n", wlc->pub->unit)); wl_init(wlc->wl); @@ -393,7 +393,7 @@ void wlc_fatal_error(wlc_info_t *wlc) * if other configurations are in conflict (bandlocked, 11n mode disabled, * invalid channel for current country, etc.) */ -static chanspec_t wlc_init_chanspec(wlc_info_t *wlc) +static chanspec_t wlc_init_chanspec(struct wlc_info *wlc) { chanspec_t chanspec = 1 | WL_CHANSPEC_BW_20 | WL_CHANSPEC_CTL_SB_NONE | @@ -409,7 +409,7 @@ static chanspec_t wlc_init_chanspec(wlc_info_t *wlc) struct scb global_scb; -static void wlc_init_scb(wlc_info_t *wlc, struct scb *scb) +static void wlc_init_scb(struct wlc_info *wlc, struct scb *scb) { int i; scb->flags = SCB_WMECAP | SCB_HTCAP; @@ -417,7 +417,7 @@ static void wlc_init_scb(wlc_info_t *wlc, struct scb *scb) scb->seqnum[i] = 0; } -void wlc_init(wlc_info_t *wlc) +void wlc_init(struct wlc_info *wlc) { d11regs_t *regs; chanspec_t chanspec; @@ -551,13 +551,13 @@ void wlc_init(wlc_info_t *wlc) } } -void wlc_mac_bcn_promisc_change(wlc_info_t *wlc, bool promisc) +void wlc_mac_bcn_promisc_change(struct wlc_info *wlc, bool promisc) { wlc->bcnmisc_monitor = promisc; wlc_mac_bcn_promisc(wlc); } -void wlc_mac_bcn_promisc(wlc_info_t *wlc) +void wlc_mac_bcn_promisc(struct wlc_info *wlc) { if ((AP_ENAB(wlc->pub) && (N_ENAB(wlc->pub) || wlc->band->gmode)) || wlc->bcnmisc_ibss || wlc->bcnmisc_scan || wlc->bcnmisc_monitor) @@ -567,7 +567,7 @@ void wlc_mac_bcn_promisc(wlc_info_t *wlc) } /* set or clear maccontrol bits MCTL_PROMISC and MCTL_KEEPCONTROL */ -void wlc_mac_promisc(wlc_info_t *wlc) +void wlc_mac_promisc(struct wlc_info *wlc) { u32 promisc_bits = 0; @@ -589,7 +589,7 @@ void wlc_mac_promisc(wlc_info_t *wlc) } /* check if hps and wake states of sw and hw are in sync */ -bool wlc_ps_check(wlc_info_t *wlc) +bool wlc_ps_check(struct wlc_info *wlc) { bool res = true; bool hps, wake; @@ -637,7 +637,7 @@ bool wlc_ps_check(wlc_info_t *wlc) } /* push sw hps and wake state through hardware */ -void wlc_set_ps_ctrl(wlc_info_t *wlc) +void wlc_set_ps_ctrl(struct wlc_info *wlc) { u32 v1, v2; bool hps, wake; @@ -672,7 +672,7 @@ void wlc_set_ps_ctrl(wlc_info_t *wlc) int wlc_set_mac(wlc_bsscfg_t *cfg) { int err = 0; - wlc_info_t *wlc = cfg->wlc; + struct wlc_info *wlc = cfg->wlc; if (cfg == wlc->cfg) { /* enter the MAC addr into the RXE match registers */ @@ -689,7 +689,7 @@ int wlc_set_mac(wlc_bsscfg_t *cfg) */ void wlc_set_bssid(wlc_bsscfg_t *cfg) { - wlc_info_t *wlc = cfg->wlc; + struct wlc_info *wlc = cfg->wlc; /* if primary config, we need to update BSSID in RXE match registers */ if (cfg == wlc->cfg) { @@ -706,7 +706,7 @@ void wlc_set_bssid(wlc_bsscfg_t *cfg) * Suspend the the MAC and update the slot timing * for standard 11b/g (20us slots) or shortslot 11g (9us slots). */ -void wlc_switch_shortslot(wlc_info_t *wlc, bool shortslot) +void wlc_switch_shortslot(struct wlc_info *wlc, bool shortslot) { int idx; wlc_bsscfg_t *cfg; @@ -734,7 +734,7 @@ void wlc_switch_shortslot(wlc_info_t *wlc, bool shortslot) wlc_bmac_set_shortslot(wlc->hw, shortslot); } -static u8 wlc_local_constraint_qdbm(wlc_info_t *wlc) +static u8 wlc_local_constraint_qdbm(struct wlc_info *wlc) { u8 local; s16 local_max; @@ -761,7 +761,7 @@ static u8 wlc_local_constraint_qdbm(wlc_info_t *wlc) } /* propagate home chanspec to all bsscfgs in case bsscfg->current_bss->chanspec is referenced */ -void wlc_set_home_chanspec(wlc_info_t *wlc, chanspec_t chanspec) +void wlc_set_home_chanspec(struct wlc_info *wlc, chanspec_t chanspec) { if (wlc->home_chanspec != chanspec) { int idx; @@ -779,7 +779,7 @@ void wlc_set_home_chanspec(wlc_info_t *wlc, chanspec_t chanspec) } } -static void wlc_set_phy_chanspec(wlc_info_t *wlc, chanspec_t chanspec) +static void wlc_set_phy_chanspec(struct wlc_info *wlc, chanspec_t chanspec) { /* Save our copy of the chanspec */ wlc->chanspec = chanspec; @@ -798,7 +798,7 @@ static void wlc_set_phy_chanspec(wlc_info_t *wlc, chanspec_t chanspec) } -void wlc_set_chanspec(wlc_info_t *wlc, chanspec_t chanspec) +void wlc_set_chanspec(struct wlc_info *wlc, chanspec_t chanspec) { uint bandunit; bool switchband = false; @@ -853,7 +853,7 @@ void wlc_set_chanspec(wlc_info_t *wlc, chanspec_t chanspec) } #if defined(BCMDBG) -static int wlc_get_current_txpwr(wlc_info_t *wlc, void *pwr, uint len) +static int wlc_get_current_txpwr(struct wlc_info *wlc, void *pwr, uint len) { txpwr_limits_t txpwr; tx_power_t power; @@ -1022,7 +1022,7 @@ static int wlc_get_current_txpwr(wlc_info_t *wlc, void *pwr, uint len) } #endif /* defined(BCMDBG) */ -static u32 wlc_watchdog_backup_bi(wlc_info_t *wlc) +static u32 wlc_watchdog_backup_bi(struct wlc_info *wlc) { u32 bi; bi = 2 * wlc->cfg->current_bss->dtim_period * @@ -1041,7 +1041,7 @@ static u32 wlc_watchdog_backup_bi(wlc_info_t *wlc) /* Change to run the watchdog either from a periodic timer or from tbtt handler. * Call watchdog from tbtt handler if tbtt is true, watchdog timer otherwise. */ -void wlc_watchdog_upd(wlc_info_t *wlc, bool tbtt) +void wlc_watchdog_upd(struct wlc_info *wlc, bool tbtt) { /* make sure changing watchdog driver is allowed */ if (!wlc->pub->up || !wlc->pub->align_wd_tbtt) @@ -1070,7 +1070,7 @@ void wlc_watchdog_upd(wlc_info_t *wlc, bool tbtt) } } -ratespec_t wlc_lowest_basic_rspec(wlc_info_t *wlc, wlc_rateset_t *rs) +ratespec_t wlc_lowest_basic_rspec(struct wlc_info *wlc, wlc_rateset_t *rs) { ratespec_t lowest_basic_rspec; uint i; @@ -1098,7 +1098,7 @@ ratespec_t wlc_lowest_basic_rspec(wlc_info_t *wlc, wlc_rateset_t *rs) * ratespec CCK ant = wlc->stf->txant * OFDM ant = 3 */ -void wlc_beacon_phytxctl_txant_upd(wlc_info_t *wlc, ratespec_t bcn_rspec) +void wlc_beacon_phytxctl_txant_upd(struct wlc_info *wlc, ratespec_t bcn_rspec) { u16 phyctl; u16 phytxant = wlc->stf->phytxant; @@ -1117,7 +1117,7 @@ void wlc_beacon_phytxctl_txant_upd(wlc_info_t *wlc, ratespec_t bcn_rspec) /* centralized protection config change function to simplify debugging, no consistency checking * this should be called only on changes to avoid overhead in periodic function */ -void wlc_protection_upd(wlc_info_t *wlc, uint idx, int val) +void wlc_protection_upd(struct wlc_info *wlc, uint idx, int val) { WL_TRACE(("wlc_protection_upd: idx %d, val %d\n", idx, val)); @@ -1163,7 +1163,7 @@ void wlc_protection_upd(wlc_info_t *wlc, uint idx, int val) } -static void wlc_ht_update_sgi_rx(wlc_info_t *wlc, int val) +static void wlc_ht_update_sgi_rx(struct wlc_info *wlc, int val) { wlc->ht_cap.cap &= ~(HT_CAP_SHORT_GI_20 | HT_CAP_SHORT_GI_40); wlc->ht_cap.cap |= (val & WLC_N_SGI_20) ? HT_CAP_SHORT_GI_20 : 0; @@ -1175,7 +1175,7 @@ static void wlc_ht_update_sgi_rx(wlc_info_t *wlc, int val) } } -static void wlc_ht_update_ldpc(wlc_info_t *wlc, s8 val) +static void wlc_ht_update_ldpc(struct wlc_info *wlc, s8 val) { wlc->stf->ldpc = val; @@ -1194,7 +1194,7 @@ static void wlc_ht_update_ldpc(wlc_info_t *wlc, s8 val) * ucode, hwmac update * Channel dependent updates for ucode and hw */ -static void wlc_ucode_mac_upd(wlc_info_t *wlc) +static void wlc_ucode_mac_upd(struct wlc_info *wlc) { /* enable or disable any active IBSSs depending on whether or not * we are on the home channel @@ -1221,7 +1221,7 @@ static void wlc_ucode_mac_upd(wlc_info_t *wlc) wlc_mac_promisc(wlc); } -static void wlc_bandinit_ordered(wlc_info_t *wlc, chanspec_t chanspec) +static void wlc_bandinit_ordered(struct wlc_info *wlc, chanspec_t chanspec) { wlc_rateset_t default_rateset; uint parkband; @@ -1268,7 +1268,7 @@ static void wlc_bandinit_ordered(wlc_info_t *wlc, chanspec_t chanspec) } /* band-specific init */ -static void WLBANDINITFN(wlc_bsinit) (wlc_info_t *wlc) +static void WLBANDINITFN(wlc_bsinit) (struct wlc_info *wlc) { WL_TRACE(("wl%d: wlc_bsinit: bandunit %d\n", wlc->pub->unit, wlc->band->bandunit)); @@ -1286,7 +1286,7 @@ static void WLBANDINITFN(wlc_bsinit) (wlc_info_t *wlc) } /* switch to and initialize new band */ -static void WLBANDINITFN(wlc_setband) (wlc_info_t *wlc, uint bandunit) +static void WLBANDINITFN(wlc_setband) (struct wlc_info *wlc, uint bandunit) { int idx; wlc_bsscfg_t *cfg; @@ -1311,7 +1311,7 @@ static void WLBANDINITFN(wlc_setband) (wlc_info_t *wlc, uint bandunit) } /* Initialize a WME Parameter Info Element with default STA parameters from WMM Spec, Table 12 */ -void wlc_wme_initparams_sta(wlc_info_t *wlc, wme_param_ie_t *pe) +void wlc_wme_initparams_sta(struct wlc_info *wlc, wme_param_ie_t *pe) { static const wme_param_ie_t stadef = { WME_OUI, @@ -1336,7 +1336,7 @@ void wlc_wme_initparams_sta(wlc_info_t *wlc, wme_param_ie_t *pe) memcpy(pe, &stadef, sizeof(*pe)); } -void wlc_wme_setparams(wlc_info_t *wlc, u16 aci, void *arg, bool suspend) +void wlc_wme_setparams(struct wlc_info *wlc, u16 aci, void *arg, bool suspend) { int i; shm_acparams_t acp_shm; @@ -1417,7 +1417,7 @@ void wlc_wme_setparams(wlc_info_t *wlc, u16 aci, void *arg, bool suspend) void wlc_edcf_setparams(wlc_bsscfg_t *cfg, bool suspend) { - wlc_info_t *wlc = cfg->wlc; + struct wlc_info *wlc = cfg->wlc; uint aci, i, j; edcf_acparam_t *edcf_acp; shm_acparams_t acp_shm; @@ -1506,7 +1506,7 @@ void wlc_edcf_setparams(wlc_bsscfg_t *cfg, bool suspend) } -bool wlc_timers_init(wlc_info_t *wlc, int unit) +bool wlc_timers_init(struct wlc_info *wlc, int unit) { wlc->wdtimer = wl_init_timer(wlc->wl, wlc_watchdog_by_timer, wlc, "watchdog"); @@ -1533,7 +1533,7 @@ bool wlc_timers_init(wlc_info_t *wlc, int unit) * Initialize wlc_info default values ... * may get overrides later in this function */ -void wlc_info_init(wlc_info_t *wlc, int unit) +void wlc_info_init(struct wlc_info *wlc, int unit) { int i; /* Assume the device is there until proven otherwise */ @@ -1644,7 +1644,7 @@ void wlc_info_init(wlc_info_t *wlc, int unit) wlc->pr80838_war = true; } -static bool wlc_state_bmac_sync(wlc_info_t *wlc) +static bool wlc_state_bmac_sync(struct wlc_info *wlc) { wlc_bmac_state_t state_bmac; @@ -1658,7 +1658,7 @@ static bool wlc_state_bmac_sync(wlc_info_t *wlc) return true; } -static uint wlc_attach_module(wlc_info_t *wlc) +static uint wlc_attach_module(struct wlc_info *wlc) { uint err = 0; uint unit; @@ -1699,7 +1699,7 @@ static uint wlc_attach_module(wlc_info_t *wlc) wlc_pub_t *wlc_pub(void *wlc) { - return ((wlc_info_t *) wlc)->pub; + return ((struct wlc_info *) wlc)->pub; } #define CHIP_SUPPORTS_11N(wlc) 1 @@ -1711,7 +1711,7 @@ void *wlc_attach(void *wl, u16 vendor, u16 device, uint unit, bool piomode, struct osl_info *osh, void *regsva, uint bustype, void *btparam, uint *perr) { - wlc_info_t *wlc; + struct wlc_info *wlc; uint err = 0; uint j; wlc_pub_t *pub; @@ -1757,8 +1757,8 @@ void *wlc_attach(void *wl, u16 vendor, u16 device, uint unit, bool piomode, || (WPA_CAP_4_REPLAY_CNTRS == WLC_REPLAY_CNTRS_VALUE && 4 == WLC_NUMRXIVS)); - /* allocate wlc_info_t state and its substructures */ - wlc = (wlc_info_t *) wlc_attach_malloc(osh, unit, &err, device); + /* allocate struct wlc_info state and its substructures */ + wlc = (struct wlc_info *) wlc_attach_malloc(osh, unit, &err, device); if (wlc == NULL) goto fail; wlc->osh = osh; @@ -1779,7 +1779,7 @@ void *wlc_attach(void *wl, u16 vendor, u16 device, uint unit, bool piomode, /* By default restrict TKIP associations from 11n STA's */ wlc->ht_wsec_restriction = WLC_HT_TKIP_RESTRICT; - /* populate wlc_info_t with default values */ + /* populate struct wlc_info with default values */ wlc_info_init(wlc, unit); /* update sta/ap related parameters */ @@ -2016,7 +2016,7 @@ void *wlc_attach(void *wl, u16 vendor, u16 device, uint unit, bool piomode, return NULL; } -static void wlc_attach_antgain_init(wlc_info_t *wlc) +static void wlc_attach_antgain_init(struct wlc_info *wlc) { uint unit; unit = wlc->pub->unit; @@ -2047,7 +2047,7 @@ static void wlc_attach_antgain_init(wlc_info_t *wlc) } } -static bool wlc_attach_stf_ant_init(wlc_info_t *wlc) +static bool wlc_attach_stf_ant_init(struct wlc_info *wlc) { int aa; uint unit; @@ -2087,7 +2087,7 @@ static bool wlc_attach_stf_ant_init(wlc_info_t *wlc) } -static void wlc_timers_deinit(wlc_info_t *wlc) +static void wlc_timers_deinit(struct wlc_info *wlc) { /* free timer state */ if (wlc->wdtimer) { @@ -2100,7 +2100,7 @@ static void wlc_timers_deinit(wlc_info_t *wlc) } } -static void wlc_detach_module(wlc_info_t *wlc) +static void wlc_detach_module(struct wlc_info *wlc) { if (wlc->asi) { wlc_antsel_detach(wlc->asi); @@ -2123,7 +2123,7 @@ static void wlc_detach_module(wlc_info_t *wlc) * One exception is sb register access, which is possible if crystal is turned on * After "down" state, driver should avoid software timer with the exception of radio_monitor. */ -uint wlc_detach(wlc_info_t *wlc) +uint wlc_detach(struct wlc_info *wlc) { uint i; uint callbacks = 0; @@ -2200,7 +2200,7 @@ uint wlc_detach(wlc_info_t *wlc) } /* update state that depends on the current value of "ap" */ -void wlc_ap_upd(wlc_info_t *wlc) +void wlc_ap_upd(struct wlc_info *wlc) { if (AP_ENAB(wlc->pub)) wlc->PLCPHdr_override = WLC_PLCP_AUTO; /* AP: short not allowed, but not enforced */ @@ -2215,7 +2215,7 @@ void wlc_ap_upd(wlc_info_t *wlc) } /* read hwdisable state and propagate to wlc flag */ -static void wlc_radio_hwdisable_upd(wlc_info_t *wlc) +static void wlc_radio_hwdisable_upd(struct wlc_info *wlc) { if (wlc->pub->wlfeatureflag & WL_SWFL_NOHWRADIO || wlc->pub->hw_off) return; @@ -2228,17 +2228,17 @@ static void wlc_radio_hwdisable_upd(wlc_info_t *wlc) } /* return true if Minimum Power Consumption should be entered, false otherwise */ -bool wlc_is_non_delay_mpc(wlc_info_t *wlc) +bool wlc_is_non_delay_mpc(struct wlc_info *wlc) { return false; } -bool wlc_ismpc(wlc_info_t *wlc) +bool wlc_ismpc(struct wlc_info *wlc) { return (wlc->mpc_delay_off == 0) && (wlc_is_non_delay_mpc(wlc)); } -void wlc_radio_mpc_upd(wlc_info_t *wlc) +void wlc_radio_mpc_upd(struct wlc_info *wlc) { bool mpc_radio, radio_state; @@ -2294,7 +2294,7 @@ void wlc_radio_mpc_upd(wlc_info_t *wlc) * centralized radio disable/enable function, * invoke radio enable/disable after updating hwradio status */ -static void wlc_radio_upd(wlc_info_t *wlc) +static void wlc_radio_upd(struct wlc_info *wlc) { if (wlc->pub->radio_disabled) wlc_radio_disable(wlc); @@ -2303,7 +2303,7 @@ static void wlc_radio_upd(wlc_info_t *wlc) } /* maintain LED behavior in down state */ -static void wlc_down_led_upd(wlc_info_t *wlc) +static void wlc_down_led_upd(struct wlc_info *wlc) { ASSERT(!wlc->pub->up); @@ -2316,7 +2316,7 @@ static void wlc_down_led_upd(wlc_info_t *wlc) } } -void wlc_radio_disable(wlc_info_t *wlc) +void wlc_radio_disable(struct wlc_info *wlc) { if (!wlc->pub->up) { wlc_down_led_upd(wlc); @@ -2327,7 +2327,7 @@ void wlc_radio_disable(wlc_info_t *wlc) wl_down(wlc->wl); } -static void wlc_radio_enable(wlc_info_t *wlc) +static void wlc_radio_enable(struct wlc_info *wlc) { if (wlc->pub->up) return; @@ -2343,7 +2343,7 @@ static void wlc_radio_enable(wlc_info_t *wlc) /* periodical query hw radio button while driver is "down" */ static void wlc_radio_timer(void *arg) { - wlc_info_t *wlc = (wlc_info_t *) arg; + struct wlc_info *wlc = (struct wlc_info *) arg; if (DEVICEREMOVED(wlc)) { WL_ERROR(("wl%d: %s: dead chip\n", wlc->pub->unit, __func__)); @@ -2361,7 +2361,7 @@ static void wlc_radio_timer(void *arg) wlc_radio_upd(wlc); } -static bool wlc_radio_monitor_start(wlc_info_t *wlc) +static bool wlc_radio_monitor_start(struct wlc_info *wlc) { /* Don't start the timer if HWRADIO feature is disabled */ if (wlc->radio_monitor || (wlc->pub->wlfeatureflag & WL_SWFL_NOHWRADIO)) @@ -2373,7 +2373,7 @@ static bool wlc_radio_monitor_start(wlc_info_t *wlc) return true; } -bool wlc_radio_monitor_stop(wlc_info_t *wlc) +bool wlc_radio_monitor_stop(struct wlc_info *wlc) { if (!wlc->radio_monitor) return true; @@ -2387,7 +2387,7 @@ bool wlc_radio_monitor_stop(wlc_info_t *wlc) } /* bring the driver down, but don't reset hardware */ -void wlc_out(wlc_info_t *wlc) +void wlc_out(struct wlc_info *wlc) { wlc_bmac_set_noreset(wlc->hw, true); wlc_radio_upd(wlc); @@ -2408,7 +2408,7 @@ void wlc_out(wlc_info_t *wlc) * if there is no packet pending for the FIFO, then the corresponding prec bits should be set * in prec_map. Of course, ignore this rule when block_datafifo is set */ -static bool wlc_tx_prec_map_verify(wlc_info_t *wlc) +static bool wlc_tx_prec_map_verify(struct wlc_info *wlc) { /* For non-WME, both fifos have overlapping prec_map. So it's an error only if both * fail the check. @@ -2430,7 +2430,7 @@ static bool wlc_tx_prec_map_verify(wlc_info_t *wlc) static void wlc_watchdog_by_timer(void *arg) { - wlc_info_t *wlc = (wlc_info_t *) arg; + struct wlc_info *wlc = (struct wlc_info *) arg; wlc_watchdog(arg); if (WLC_WATCHDOG_TBTT(wlc)) { /* set to normal osl watchdog period */ @@ -2443,7 +2443,7 @@ static void wlc_watchdog_by_timer(void *arg) /* common watchdog code */ static void wlc_watchdog(void *arg) { - wlc_info_t *wlc = (wlc_info_t *) arg; + struct wlc_info *wlc = (struct wlc_info *) arg; int i; wlc_bsscfg_t *cfg; @@ -2523,7 +2523,7 @@ static void wlc_watchdog(void *arg) } /* make interface operational */ -int wlc_up(wlc_info_t *wlc) +int wlc_up(struct wlc_info *wlc) { WL_TRACE(("wl%d: %s:\n", wlc->pub->unit, __func__)); @@ -2631,7 +2631,7 @@ int wlc_up(wlc_info_t *wlc) } /* Initialize the base precedence map for dequeueing from txq based on WME settings */ -static void wlc_tx_prec_map_init(wlc_info_t *wlc) +static void wlc_tx_prec_map_init(struct wlc_info *wlc) { wlc->tx_prec_map = WLC_PREC_BMP_ALL; memset(wlc->fifo2prec_map, 0, NFIFO * sizeof(u16)); @@ -2650,7 +2650,7 @@ static void wlc_tx_prec_map_init(wlc_info_t *wlc) } } -static uint wlc_down_del_timer(wlc_info_t *wlc) +static uint wlc_down_del_timer(struct wlc_info *wlc) { uint callbacks = 0; @@ -2662,7 +2662,7 @@ static uint wlc_down_del_timer(wlc_info_t *wlc) * disable the hardware, free any transient buffer state. * Return a count of the number of driver callbacks still pending. */ -uint wlc_down(wlc_info_t *wlc) +uint wlc_down(struct wlc_info *wlc) { uint callbacks = 0; @@ -2749,7 +2749,7 @@ uint wlc_down(wlc_info_t *wlc) } /* Set the current gmode configuration */ -int wlc_set_gmode(wlc_info_t *wlc, u8 gmode, bool config) +int wlc_set_gmode(struct wlc_info *wlc, u8 gmode, bool config) { int ret = 0; uint i; @@ -2899,7 +2899,7 @@ int wlc_set_gmode(wlc_info_t *wlc, u8 gmode, bool config) return ret; } -static int wlc_nmode_validate(wlc_info_t *wlc, s32 nmode) +static int wlc_nmode_validate(struct wlc_info *wlc, s32 nmode) { int err = 0; @@ -2923,7 +2923,7 @@ static int wlc_nmode_validate(wlc_info_t *wlc, s32 nmode) return err; } -int wlc_set_nmode(wlc_info_t *wlc, s32 nmode) +int wlc_set_nmode(struct wlc_info *wlc, s32 nmode) { uint i; int err; @@ -2982,7 +2982,7 @@ int wlc_set_nmode(wlc_info_t *wlc, s32 nmode) return err; } -static int wlc_set_rateset(wlc_info_t *wlc, wlc_rateset_t *rs_arg) +static int wlc_set_rateset(struct wlc_info *wlc, wlc_rateset_t *rs_arg) { wlc_rateset_t rs, new; uint bandunit; @@ -3025,18 +3025,18 @@ static int wlc_set_rateset(wlc_info_t *wlc, wlc_rateset_t *rs_arg) } /* simplified integer set interface for common ioctl handler */ -int wlc_set(wlc_info_t *wlc, int cmd, int arg) +int wlc_set(struct wlc_info *wlc, int cmd, int arg) { return wlc_ioctl(wlc, cmd, (void *)&arg, sizeof(arg), NULL); } /* simplified integer get interface for common ioctl handler */ -int wlc_get(wlc_info_t *wlc, int cmd, int *arg) +int wlc_get(struct wlc_info *wlc, int cmd, int *arg) { return wlc_ioctl(wlc, cmd, arg, sizeof(int), NULL); } -static void wlc_ofdm_rateset_war(wlc_info_t *wlc) +static void wlc_ofdm_rateset_war(struct wlc_info *wlc) { u8 r; bool war = false; @@ -3052,14 +3052,16 @@ static void wlc_ofdm_rateset_war(wlc_info_t *wlc) } int -wlc_ioctl(wlc_info_t *wlc, int cmd, void *arg, int len, struct wlc_if *wlcif) +wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, + struct wlc_if *wlcif) { return _wlc_ioctl(wlc, cmd, arg, len, wlcif); } /* common ioctl handler. return: 0=ok, -1=error, positive=particular error */ static int -_wlc_ioctl(wlc_info_t *wlc, int cmd, void *arg, int len, struct wlc_if *wlcif) +_wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, + struct wlc_if *wlcif) { int val, *pval; bool bool_val; @@ -4220,7 +4222,7 @@ _wlc_ioctl(wlc_info_t *wlc, int cmd, void *arg, int len, struct wlc_if *wlcif) #if defined(BCMDBG) /* consolidated register access ioctl error checking */ -int wlc_iocregchk(wlc_info_t *wlc, uint band) +int wlc_iocregchk(struct wlc_info *wlc, uint band) { /* if band is specified, it must be the current band */ if ((band != WLC_BAND_AUTO) && (band != (uint) wlc->band->bandtype)) @@ -4240,7 +4242,7 @@ int wlc_iocregchk(wlc_info_t *wlc, uint band) #if defined(BCMDBG) /* For some ioctls, make sure that the pi pointer matches the current phy */ -int wlc_iocpichk(wlc_info_t *wlc, uint phytype) +int wlc_iocpichk(struct wlc_info *wlc, uint phytype) { if (wlc->band->phytype != phytype) return BCME_BADBAND; @@ -4274,21 +4276,21 @@ static const bcm_iovar_t *wlc_iovar_lookup(const bcm_iovar_t *table, } /* simplified integer get interface for common WLC_GET_VAR ioctl handler */ -int wlc_iovar_getint(wlc_info_t *wlc, const char *name, int *arg) +int wlc_iovar_getint(struct wlc_info *wlc, const char *name, int *arg) { return wlc_iovar_op(wlc, name, NULL, 0, arg, sizeof(s32), IOV_GET, NULL); } /* simplified integer set interface for common WLC_SET_VAR ioctl handler */ -int wlc_iovar_setint(wlc_info_t *wlc, const char *name, int arg) +int wlc_iovar_setint(struct wlc_info *wlc, const char *name, int arg) { return wlc_iovar_op(wlc, name, NULL, 0, (void *)&arg, sizeof(arg), IOV_SET, NULL); } /* simplified s8 get interface for common WLC_GET_VAR ioctl handler */ -int wlc_iovar_gets8(wlc_info_t *wlc, const char *name, s8 *arg) +int wlc_iovar_gets8(struct wlc_info *wlc, const char *name, s8 *arg) { int iovar_int; int err; @@ -4311,7 +4313,7 @@ int wlc_module_register(wlc_pub_t *pub, const bcm_iovar_t *iovars, const char *name, void *hdl, iovar_fn_t i_fn, watchdog_fn_t w_fn, down_fn_t d_fn) { - wlc_info_t *wlc = (wlc_info_t *) pub->wlc; + struct wlc_info *wlc = (struct wlc_info *) pub->wlc; int i; ASSERT(name != NULL); @@ -4339,7 +4341,7 @@ int wlc_module_register(wlc_pub_t *pub, const bcm_iovar_t *iovars, /* unregister module callbacks */ int wlc_module_unregister(wlc_pub_t *pub, const char *name, void *hdl) { - wlc_info_t *wlc = (wlc_info_t *) pub->wlc; + struct wlc_info *wlc = (struct wlc_info *) pub->wlc; int i; if (wlc == NULL) @@ -4360,7 +4362,7 @@ int wlc_module_unregister(wlc_pub_t *pub, const char *name, void *hdl) } /* Write WME tunable parameters for retransmit/max rate from wlc struct to ucode */ -static void wlc_wme_retries_write(wlc_info_t *wlc) +static void wlc_wme_retries_write(struct wlc_info *wlc) { int ac; @@ -4382,7 +4384,7 @@ static void wlc_wme_retries_write(wlc_info_t *wlc) * All pointers may point into the same buffer. */ int -wlc_iovar_op(wlc_info_t *wlc, const char *name, +wlc_iovar_op(struct wlc_info *wlc, const char *name, void *params, int p_len, void *arg, int len, bool set, struct wlc_if *wlcif) { @@ -4456,7 +4458,7 @@ int wlc_iovar_check(wlc_pub_t *pub, const bcm_iovar_t *vi, void *arg, int len, bool set) { - wlc_info_t *wlc = (wlc_info_t *) pub->wlc; + struct wlc_info *wlc = (struct wlc_info *) pub->wlc; int err = 0; s32 int_val = 0; @@ -4524,7 +4526,7 @@ wlc_doiovar(void *hdl, const bcm_iovar_t *vi, u32 actionid, const char *name, void *params, uint p_len, void *arg, int len, int val_size, struct wlc_if *wlcif) { - wlc_info_t *wlc = hdl; + struct wlc_info *wlc = hdl; wlc_bsscfg_t *bsscfg; int err = 0; s32 int_val = 0; @@ -4628,7 +4630,7 @@ wlc_doiovar(void *hdl, const bcm_iovar_t *vi, u32 actionid, } static int -wlc_iovar_rangecheck(wlc_info_t *wlc, u32 val, const bcm_iovar_t *vi) +wlc_iovar_rangecheck(struct wlc_info *wlc, u32 val, const bcm_iovar_t *vi) { int err = 0; u32 min_val = 0; @@ -4725,7 +4727,7 @@ void wlc_print_txstatus(tx_status_t *txs) #define MACSTATUPD(name) \ wlc_ctrupd_cache(macstats.name, &wlc->core->macstat_snapshot->name, &wlc->pub->_cnt->name) -void wlc_statsupd(wlc_info_t *wlc) +void wlc_statsupd(struct wlc_info *wlc) { int i; #ifdef BCMDBG @@ -4977,7 +4979,7 @@ int wlc_format_ssid(char *buf, const unsigned char ssid[], uint ssid_len) } #endif /* defined(BCMDBG) */ -u16 wlc_rate_shm_offset(wlc_info_t *wlc, u8 rate) +u16 wlc_rate_shm_offset(struct wlc_info *wlc, u8 rate) { return wlc_bmac_rate_shm_offset(wlc->hw, rate); } @@ -4994,13 +4996,13 @@ u16 wlc_rate_shm_offset(wlc_info_t *wlc, u8 rate) * Returns true if packet consumed (queued), false if not. */ bool BCMFASTPATH -wlc_prec_enq(wlc_info_t *wlc, struct pktq *q, void *pkt, int prec) +wlc_prec_enq(struct wlc_info *wlc, struct pktq *q, void *pkt, int prec) { return wlc_prec_enq_head(wlc, q, pkt, prec, false); } bool BCMFASTPATH -wlc_prec_enq_head(wlc_info_t *wlc, struct pktq *q, struct sk_buff *pkt, +wlc_prec_enq_head(struct wlc_info *wlc, struct pktq *q, struct sk_buff *pkt, int prec, bool head) { struct sk_buff *p; @@ -5067,7 +5069,7 @@ wlc_prec_enq_head(wlc_info_t *wlc, struct pktq *q, struct sk_buff *pkt, void BCMFASTPATH wlc_txq_enq(void *ctx, struct scb *scb, struct sk_buff *sdu, uint prec) { - wlc_info_t *wlc = (wlc_info_t *) ctx; + struct wlc_info *wlc = (struct wlc_info *) ctx; wlc_txq_info_t *qi = wlc->active_queue; /* Check me */ struct pktq *q = &qi->q; int prio; @@ -5105,7 +5107,7 @@ void BCMFASTPATH wlc_txq_enq(void *ctx, struct scb *scb, struct sk_buff *sdu, } bool BCMFASTPATH -wlc_sendpkt_mac80211(wlc_info_t *wlc, struct sk_buff *sdu, +wlc_sendpkt_mac80211(struct wlc_info *wlc, struct sk_buff *sdu, struct ieee80211_hw *hw) { u8 prio; @@ -5141,7 +5143,7 @@ wlc_sendpkt_mac80211(wlc_info_t *wlc, struct sk_buff *sdu, return 0; } -void BCMFASTPATH wlc_send_q(wlc_info_t *wlc, wlc_txq_info_t *qi) +void BCMFASTPATH wlc_send_q(struct wlc_info *wlc, wlc_txq_info_t *qi) { struct sk_buff *pkt[DOT11_MAXNUMFRAGS]; int prec; @@ -5216,7 +5218,7 @@ void BCMFASTPATH wlc_send_q(wlc_info_t *wlc, wlc_txq_info_t *qi) * for MC frames so is used as part of the sequence number. */ static inline u16 -bcmc_fid_generate(wlc_info_t *wlc, wlc_bsscfg_t *bsscfg, d11txh_t *txh) +bcmc_fid_generate(struct wlc_info *wlc, wlc_bsscfg_t *bsscfg, d11txh_t *txh) { u16 frameid; @@ -5230,7 +5232,7 @@ bcmc_fid_generate(wlc_info_t *wlc, wlc_bsscfg_t *bsscfg, d11txh_t *txh) } void BCMFASTPATH -wlc_txfifo(wlc_info_t *wlc, uint fifo, struct sk_buff *p, bool commit, +wlc_txfifo(struct wlc_info *wlc, uint fifo, struct sk_buff *p, bool commit, s8 txpktpend) { u16 frameid = INVALIDFID; @@ -5270,7 +5272,7 @@ wlc_txfifo(wlc_info_t *wlc, uint fifo, struct sk_buff *p, bool commit, } static u16 -wlc_compute_airtime(wlc_info_t *wlc, ratespec_t rspec, uint length) +wlc_compute_airtime(struct wlc_info *wlc, ratespec_t rspec, uint length) { u16 usec = 0; uint mac_rate = RSPEC2RATE(rspec); @@ -5315,7 +5317,7 @@ wlc_compute_airtime(wlc_info_t *wlc, ratespec_t rspec, uint length) } void BCMFASTPATH -wlc_compute_plcp(wlc_info_t *wlc, ratespec_t rspec, uint length, u8 *plcp) +wlc_compute_plcp(struct wlc_info *wlc, ratespec_t rspec, uint length, u8 *plcp) { if (IS_MCS(rspec)) { wlc_compute_mimo_plcp(rspec, length, plcp); @@ -5439,7 +5441,7 @@ static void wlc_compute_cck_plcp(ratespec_t rspec, uint length, u8 *plcp) * preamble_type use short/GF or long/MM PLCP header */ static u16 BCMFASTPATH -wlc_compute_frame_dur(wlc_info_t *wlc, ratespec_t rate, u8 preamble_type, +wlc_compute_frame_dur(struct wlc_info *wlc, ratespec_t rate, u8 preamble_type, uint next_frag_len) { u16 dur, sifs; @@ -5473,7 +5475,7 @@ wlc_compute_frame_dur(wlc_info_t *wlc, ratespec_t rate, u8 preamble_type, * frame_len next MPDU frame length in bytes */ u16 BCMFASTPATH -wlc_compute_rtscts_dur(wlc_info_t *wlc, bool cts_only, ratespec_t rts_rate, +wlc_compute_rtscts_dur(struct wlc_info *wlc, bool cts_only, ratespec_t rts_rate, ratespec_t frame_rate, u8 rts_preamble_type, u8 frame_preamble_type, uint frame_len, bool ba) { @@ -5504,7 +5506,7 @@ wlc_compute_rtscts_dur(wlc_info_t *wlc, bool cts_only, ratespec_t rts_rate, return dur; } -static bool wlc_phy_rspec_check(wlc_info_t *wlc, u16 bw, ratespec_t rspec) +static bool wlc_phy_rspec_check(struct wlc_info *wlc, u16 bw, ratespec_t rspec) { if (IS_MCS(rspec)) { uint mcs = rspec & RSPEC_RATE_MASK; @@ -5530,7 +5532,7 @@ static bool wlc_phy_rspec_check(wlc_info_t *wlc, u16 bw, ratespec_t rspec) return true; } -u16 BCMFASTPATH wlc_phytxctl1_calc(wlc_info_t *wlc, ratespec_t rspec) +u16 BCMFASTPATH wlc_phytxctl1_calc(struct wlc_info *wlc, ratespec_t rspec) { u16 phyctl1 = 0; u16 bw; @@ -5587,7 +5589,7 @@ u16 BCMFASTPATH wlc_phytxctl1_calc(wlc_info_t *wlc, ratespec_t rspec) } ratespec_t BCMFASTPATH -wlc_rspec_to_rts_rspec(wlc_info_t *wlc, ratespec_t rspec, bool use_rspec, +wlc_rspec_to_rts_rspec(struct wlc_info *wlc, ratespec_t rspec, bool use_rspec, u16 mimo_ctlchbw) { ratespec_t rts_rspec = 0; @@ -5643,7 +5645,7 @@ wlc_rspec_to_rts_rspec(wlc_info_t *wlc, ratespec_t rspec, bool use_rspec, * */ static u16 BCMFASTPATH -wlc_d11hdrs_mac80211(wlc_info_t *wlc, struct ieee80211_hw *hw, +wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, struct sk_buff *p, struct scb *scb, uint frag, uint nfrags, uint queue, uint next_frag_len, wsec_key_t *key, ratespec_t rspec_override) @@ -6309,7 +6311,7 @@ wlc_d11hdrs_mac80211(wlc_info_t *wlc, struct ieee80211_hw *hw, return 0; } -void wlc_tbtt(wlc_info_t *wlc, d11regs_t *regs) +void wlc_tbtt(struct wlc_info *wlc, d11regs_t *regs) { wlc_bsscfg_t *cfg = wlc->cfg; @@ -6345,19 +6347,19 @@ void wlc_tbtt(wlc_info_t *wlc, d11regs_t *regs) } /* GP timer is a freerunning 32 bit counter, decrements at 1 us rate */ -void wlc_hwtimer_gptimer_set(wlc_info_t *wlc, uint us) +void wlc_hwtimer_gptimer_set(struct wlc_info *wlc, uint us) { ASSERT(wlc->pub->corerev >= 3); /* no gptimer in earlier revs */ W_REG(wlc->osh, &wlc->regs->gptimer, us); } -void wlc_hwtimer_gptimer_abort(wlc_info_t *wlc) +void wlc_hwtimer_gptimer_abort(struct wlc_info *wlc) { ASSERT(wlc->pub->corerev >= 3); W_REG(wlc->osh, &wlc->regs->gptimer, 0); } -static void wlc_hwtimer_gptimer_cb(wlc_info_t *wlc) +static void wlc_hwtimer_gptimer_cb(struct wlc_info *wlc) { /* when interrupt is generated, the counter is loaded with last value * written and continue to decrement. So it has to be cleaned first @@ -6370,7 +6372,7 @@ static void wlc_hwtimer_gptimer_cb(wlc_info_t *wlc) * POLICY: no macinstatus change, no bounding loop. * All dpc bounding should be handled in BMAC dpc, like txstatus and rxint */ -void wlc_high_dpc(wlc_info_t *wlc, u32 macintstatus) +void wlc_high_dpc(struct wlc_info *wlc, u32 macintstatus) { d11regs_t *regs = wlc->regs; #ifdef BCMDBG @@ -6463,7 +6465,7 @@ void wlc_high_dpc(wlc_info_t *wlc, u32 macintstatus) ASSERT(wlc_ps_check(wlc)); } -static void *wlc_15420war(wlc_info_t *wlc, uint queue) +static void *wlc_15420war(struct wlc_info *wlc, uint queue) { hnddma_t *di; void *p; @@ -6493,7 +6495,7 @@ static void *wlc_15420war(wlc_info_t *wlc, uint queue) return p; } -static void wlc_war16165(wlc_info_t *wlc, bool tx) +static void wlc_war16165(struct wlc_info *wlc, bool tx) { if (tx) { /* the post-increment is used in STAY_AWAKE macro */ @@ -6509,7 +6511,7 @@ static void wlc_war16165(wlc_info_t *wlc, bool tx) /* process an individual tx_status_t */ /* WLC_HIGH_API */ bool BCMFASTPATH -wlc_dotxstatus(wlc_info_t *wlc, tx_status_t *txs, u32 frm_tx2) +wlc_dotxstatus(struct wlc_info *wlc, tx_status_t *txs, u32 frm_tx2) { struct sk_buff *p; uint queue; @@ -6676,7 +6678,7 @@ wlc_dotxstatus(wlc_info_t *wlc, tx_status_t *txs, u32 frm_tx2) } void BCMFASTPATH -wlc_txfifo_complete(wlc_info_t *wlc, uint fifo, s8 txpktpend) +wlc_txfifo_complete(struct wlc_info *wlc, uint fifo, s8 txpktpend) { TXPKTPENDDEC(wlc, fifo, txpktpend); WL_TRACE(("wlc_txfifo_complete, pktpend dec %d to %d\n", txpktpend, @@ -6780,7 +6782,7 @@ u32 wlc_calc_tbtt_offset(u32 bp, u32 tsf_h, u32 tsf_l) } /* Update beacon listen interval in shared memory */ -void wlc_bcn_li_upd(wlc_info_t *wlc) +void wlc_bcn_li_upd(struct wlc_info *wlc) { if (AP_ENAB(wlc->pub)) return; @@ -6794,7 +6796,7 @@ void wlc_bcn_li_upd(wlc_info_t *wlc) } static void -prep_mac80211_status(wlc_info_t *wlc, d11rxhdr_t *rxh, struct sk_buff *p, +prep_mac80211_status(struct wlc_info *wlc, d11rxhdr_t *rxh, struct sk_buff *p, struct ieee80211_rx_status *rx_status) { u32 tsf_l, tsf_h; @@ -6904,7 +6906,7 @@ prep_mac80211_status(wlc_info_t *wlc, d11rxhdr_t *rxh, struct sk_buff *p, } static void -wlc_recvctl(wlc_info_t *wlc, struct osl_info *osh, d11rxhdr_t *rxh, +wlc_recvctl(struct wlc_info *wlc, struct osl_info *osh, d11rxhdr_t *rxh, struct sk_buff *p) { int len_mpdu; @@ -6939,7 +6941,7 @@ wlc_recvctl(wlc_info_t *wlc, struct osl_info *osh, d11rxhdr_t *rxh, return; } -void wlc_bss_list_free(wlc_info_t *wlc, wlc_bss_list_t *bss_list) +void wlc_bss_list_free(struct wlc_info *wlc, wlc_bss_list_t *bss_list) { uint index; wlc_bss_info_t *bi; @@ -6968,7 +6970,7 @@ void wlc_bss_list_free(wlc_info_t *wlc, wlc_bss_list_t *bss_list) * Param 'bound' indicates max. # frames to process before break out. */ /* WLC_HIGH_API */ -void BCMFASTPATH wlc_recv(wlc_info_t *wlc, struct sk_buff *p) +void BCMFASTPATH wlc_recv(struct wlc_info *wlc, struct sk_buff *p) { d11rxhdr_t *rxh; struct dot11_header *h; @@ -7064,7 +7066,7 @@ void BCMFASTPATH wlc_recv(wlc_info_t *wlc, struct sk_buff *p) * len = 3(nsyms + nstream + 3) - 3 */ u16 BCMFASTPATH -wlc_calc_lsig_len(wlc_info_t *wlc, ratespec_t ratespec, uint mac_len) +wlc_calc_lsig_len(struct wlc_info *wlc, ratespec_t ratespec, uint mac_len) { uint nsyms, len = 0, kNdps; @@ -7105,7 +7107,7 @@ wlc_calc_lsig_len(wlc_info_t *wlc, ratespec_t ratespec, uint mac_len) /* calculate frame duration of a given rate and length, return time in usec unit */ uint BCMFASTPATH -wlc_calc_frame_time(wlc_info_t *wlc, ratespec_t ratespec, u8 preamble_type, +wlc_calc_frame_time(struct wlc_info *wlc, ratespec_t ratespec, u8 preamble_type, uint mac_len) { uint nsyms, dur = 0, Ndps, kNdps; @@ -7175,7 +7177,7 @@ wlc_calc_frame_time(wlc_info_t *wlc, ratespec_t ratespec, u8 preamble_type, /* The opposite of wlc_calc_frame_time */ static uint -wlc_calc_frame_len(wlc_info_t *wlc, ratespec_t ratespec, u8 preamble_type, +wlc_calc_frame_len(struct wlc_info *wlc, ratespec_t ratespec, u8 preamble_type, uint dur) { uint nsyms, mac_len, Ndps, kNdps; @@ -7221,7 +7223,7 @@ wlc_calc_frame_len(wlc_info_t *wlc, ratespec_t ratespec, u8 preamble_type, } static uint -wlc_calc_ba_time(wlc_info_t *wlc, ratespec_t rspec, u8 preamble_type) +wlc_calc_ba_time(struct wlc_info *wlc, ratespec_t rspec, u8 preamble_type) { WL_TRACE(("wl%d: wlc_calc_ba_time: rspec 0x%x, preamble_type %d\n", wlc->pub->unit, rspec, preamble_type)); @@ -7238,7 +7240,7 @@ wlc_calc_ba_time(wlc_info_t *wlc, ratespec_t rspec, u8 preamble_type) } static uint BCMFASTPATH -wlc_calc_ack_time(wlc_info_t *wlc, ratespec_t rspec, u8 preamble_type) +wlc_calc_ack_time(struct wlc_info *wlc, ratespec_t rspec, u8 preamble_type) { uint dur = 0; @@ -7258,7 +7260,7 @@ wlc_calc_ack_time(wlc_info_t *wlc, ratespec_t rspec, u8 preamble_type) } static uint -wlc_calc_cts_time(wlc_info_t *wlc, ratespec_t rspec, u8 preamble_type) +wlc_calc_cts_time(struct wlc_info *wlc, ratespec_t rspec, u8 preamble_type) { WL_TRACE(("wl%d: wlc_calc_cts_time: ratespec 0x%x, preamble_type %d\n", wlc->pub->unit, rspec, preamble_type)); @@ -7266,7 +7268,7 @@ wlc_calc_cts_time(wlc_info_t *wlc, ratespec_t rspec, u8 preamble_type) } /* derive wlc->band->basic_rate[] table from 'rateset' */ -void wlc_rate_lookup_init(wlc_info_t *wlc, wlc_rateset_t *rateset) +void wlc_rate_lookup_init(struct wlc_info *wlc, wlc_rateset_t *rateset) { u8 rate; u8 mandatory; @@ -7355,7 +7357,7 @@ void wlc_rate_lookup_init(wlc_info_t *wlc, wlc_rateset_t *rateset) } } -static void wlc_write_rate_shm(wlc_info_t *wlc, u8 rate, u8 basic_rate) +static void wlc_write_rate_shm(struct wlc_info *wlc, u8 rate, u8 basic_rate) { u8 phy_rate, index; u8 basic_phy_rate, basic_index; @@ -7388,7 +7390,7 @@ static void wlc_write_rate_shm(wlc_info_t *wlc, u8 rate, u8 basic_rate) wlc_write_shm(wlc, (basic_table + index * 2), basic_ptr); } -static const wlc_rateset_t *wlc_rateset_get_hwrs(wlc_info_t *wlc) +static const wlc_rateset_t *wlc_rateset_get_hwrs(struct wlc_info *wlc) { const wlc_rateset_t *rs_dflt; @@ -7405,7 +7407,7 @@ static const wlc_rateset_t *wlc_rateset_get_hwrs(wlc_info_t *wlc) return rs_dflt; } -void wlc_set_ratetable(wlc_info_t *wlc) +void wlc_set_ratetable(struct wlc_info *wlc) { const wlc_rateset_t *rs_dflt; wlc_rateset_t rs; @@ -7441,7 +7443,8 @@ void wlc_set_ratetable(wlc_info_t *wlc) * Return true if the specified rate is supported by the specified band. * WLC_BAND_AUTO indicates the current band. */ -bool wlc_valid_rate(wlc_info_t *wlc, ratespec_t rspec, int band, bool verbose) +bool wlc_valid_rate(struct wlc_info *wlc, ratespec_t rspec, int band, + bool verbose) { wlc_rateset_t *hw_rateset; uint i; @@ -7474,7 +7477,7 @@ bool wlc_valid_rate(wlc_info_t *wlc, ratespec_t rspec, int band, bool verbose) return false; } -static void wlc_update_mimo_band_bwcap(wlc_info_t *wlc, u8 bwcap) +static void wlc_update_mimo_band_bwcap(struct wlc_info *wlc, u8 bwcap) { uint i; wlcband_t *band; @@ -7501,7 +7504,7 @@ static void wlc_update_mimo_band_bwcap(wlc_info_t *wlc, u8 bwcap) wlc->mimo_band_bwcap = bwcap; } -void wlc_mod_prb_rsp_rate_table(wlc_info_t *wlc, uint frame_len) +void wlc_mod_prb_rsp_rate_table(struct wlc_info *wlc, uint frame_len) { const wlc_rateset_t *rs_dflt; wlc_rateset_t rs; @@ -7544,8 +7547,8 @@ void wlc_mod_prb_rsp_rate_table(wlc_info_t *wlc, uint frame_len) } u16 -wlc_compute_bcntsfoff(wlc_info_t *wlc, ratespec_t rspec, bool short_preamble, - bool phydelay) +wlc_compute_bcntsfoff(struct wlc_info *wlc, ratespec_t rspec, + bool short_preamble, bool phydelay) { uint bcntsfoff = 0; @@ -7591,7 +7594,7 @@ wlc_compute_bcntsfoff(wlc_info_t *wlc, ratespec_t rspec, bool short_preamble, * and included up to, but not including, the 4 byte FCS. */ static void -wlc_bcn_prb_template(wlc_info_t *wlc, uint type, ratespec_t bcn_rspec, +wlc_bcn_prb_template(struct wlc_info *wlc, uint type, ratespec_t bcn_rspec, wlc_bsscfg_t *cfg, u16 *buf, int *len) { cck_phy_hdr_t *plcp; @@ -7658,7 +7661,7 @@ int wlc_get_header_len() * template updated. * Otherwise, it updates the hardware template. */ -void wlc_bss_update_beacon(wlc_info_t *wlc, wlc_bsscfg_t *cfg) +void wlc_bss_update_beacon(struct wlc_info *wlc, wlc_bsscfg_t *cfg) { int len = BCN_TMPL_LEN; @@ -7711,7 +7714,7 @@ void wlc_bss_update_beacon(wlc_info_t *wlc, wlc_bsscfg_t *cfg) /* * Update all beacons for the system. */ -void wlc_update_beacon(wlc_info_t *wlc) +void wlc_update_beacon(struct wlc_info *wlc) { int idx; wlc_bsscfg_t *bsscfg; @@ -7724,7 +7727,7 @@ void wlc_update_beacon(wlc_info_t *wlc) } /* Write ssid into shared memory */ -void wlc_shm_ssid_upd(wlc_info_t *wlc, wlc_bsscfg_t *cfg) +void wlc_shm_ssid_upd(struct wlc_info *wlc, wlc_bsscfg_t *cfg) { u8 *ssidptr = cfg->SSID; u16 base = M_SSID; @@ -7740,7 +7743,7 @@ void wlc_shm_ssid_upd(wlc_info_t *wlc, wlc_bsscfg_t *cfg) wlc_write_shm(wlc, M_SSIDLEN, (u16) cfg->SSID_len); } -void wlc_update_probe_resp(wlc_info_t *wlc, bool suspend) +void wlc_update_probe_resp(struct wlc_info *wlc, bool suspend) { int idx; wlc_bsscfg_t *bsscfg; @@ -7753,7 +7756,7 @@ void wlc_update_probe_resp(wlc_info_t *wlc, bool suspend) } void -wlc_bss_update_probe_resp(wlc_info_t *wlc, wlc_bsscfg_t *cfg, bool suspend) +wlc_bss_update_probe_resp(struct wlc_info *wlc, wlc_bsscfg_t *cfg, bool suspend) { u16 prb_resp[BCN_TMPL_LEN / 2]; int len = BCN_TMPL_LEN; @@ -7794,7 +7797,7 @@ wlc_bss_update_probe_resp(wlc_info_t *wlc, wlc_bsscfg_t *cfg, bool suspend) } /* prepares pdu for transmission. returns BCM error codes */ -int wlc_prep_pdu(wlc_info_t *wlc, struct sk_buff *pdu, uint *fifop) +int wlc_prep_pdu(struct wlc_info *wlc, struct sk_buff *pdu, uint *fifop) { struct osl_info *osh; uint fifo; @@ -7833,7 +7836,7 @@ int wlc_prep_pdu(wlc_info_t *wlc, struct sk_buff *pdu, uint *fifop) } /* init tx reported rate mechanism */ -void wlc_reprate_init(wlc_info_t *wlc) +void wlc_reprate_init(struct wlc_info *wlc) { int i; wlc_bsscfg_t *bsscfg; @@ -7853,7 +7856,7 @@ void wlc_bsscfg_reprate_init(wlc_bsscfg_t *bsscfg) /* Retrieve a consolidated set of revision information, * typically for the WLC_GET_REVINFO ioctl */ -int wlc_get_revision_info(wlc_info_t *wlc, void *buf, uint len) +int wlc_get_revision_info(struct wlc_info *wlc, void *buf, uint len) { wlc_rev_info_t *rinfo = (wlc_rev_info_t *) buf; @@ -7887,7 +7890,7 @@ int wlc_get_revision_info(wlc_info_t *wlc, void *buf, uint len) return BCME_OK; } -void wlc_default_rateset(wlc_info_t *wlc, wlc_rateset_t *rs) +void wlc_default_rateset(struct wlc_info *wlc, wlc_rateset_t *rs) { wlc_rateset_default(rs, NULL, wlc->band->phytype, wlc->band->bandtype, false, RATE_MASK_FULL, (bool) N_ENAB(wlc->pub), @@ -7895,7 +7898,7 @@ void wlc_default_rateset(wlc_info_t *wlc, wlc_rateset_t *rs) wlc->stf->txstreams); } -static void wlc_bss_default_init(wlc_info_t *wlc) +static void wlc_bss_default_init(struct wlc_info *wlc) { chanspec_t chanspec; wlcband_t *band; @@ -7933,7 +7936,7 @@ static void wlc_bss_default_init(wlc_info_t *wlc) /* Deferred event processing */ static void wlc_process_eventq(void *arg) { - wlc_info_t *wlc = (wlc_info_t *) arg; + struct wlc_info *wlc = (struct wlc_info *) arg; wlc_event_t *etmp; while ((etmp = wlc_eventq_deq(wlc->eventq))) { @@ -7959,7 +7962,7 @@ wlc_uint64_sub(u32 *a_high, u32 *a_low, u32 b_high, u32 b_low) } static ratespec_t -mac80211_wlc_set_nrate(wlc_info_t *wlc, wlcband_t *cur_band, u32 int_val) +mac80211_wlc_set_nrate(struct wlc_info *wlc, wlcband_t *cur_band, u32 int_val) { u8 stf = (int_val & NRATE_STF_MASK) >> NRATE_STF_SHIFT; u8 rate = int_val & NRATE_RATE_MASK; @@ -8073,7 +8076,7 @@ mac80211_wlc_set_nrate(wlc_info_t *wlc, wlcband_t *cur_band, u32 int_val) /* formula: IDLE_BUSY_RATIO_X_16 = (100-duty_cycle)/duty_cycle*16 */ static int -wlc_duty_cycle_set(wlc_info_t *wlc, int duty_cycle, bool isOFDM, +wlc_duty_cycle_set(struct wlc_info *wlc, int duty_cycle, bool isOFDM, bool writeToShm) { int idle_busy_ratio_x_16 = 0; @@ -8102,7 +8105,7 @@ wlc_duty_cycle_set(wlc_info_t *wlc, int duty_cycle, bool isOFDM, /* Read a single u16 from shared memory. * SHM 'offset' needs to be an even address */ -u16 wlc_read_shm(wlc_info_t *wlc, uint offset) +u16 wlc_read_shm(struct wlc_info *wlc, uint offset) { return wlc_bmac_read_shm(wlc->hw, offset); } @@ -8110,7 +8113,7 @@ u16 wlc_read_shm(wlc_info_t *wlc, uint offset) /* Write a single u16 to shared memory. * SHM 'offset' needs to be an even address */ -void wlc_write_shm(wlc_info_t *wlc, uint offset, u16 v) +void wlc_write_shm(struct wlc_info *wlc, uint offset, u16 v) { wlc_bmac_write_shm(wlc->hw, offset, v); } @@ -8119,7 +8122,7 @@ void wlc_write_shm(wlc_info_t *wlc, uint offset, u16 v) * SHM 'offset' needs to be an even address and * Range length 'len' must be an even number of bytes */ -void wlc_set_shm(wlc_info_t *wlc, uint offset, u16 v, int len) +void wlc_set_shm(struct wlc_info *wlc, uint offset, u16 v, int len) { /* offset and len need to be even */ ASSERT((offset & 1) == 0); @@ -8135,7 +8138,7 @@ void wlc_set_shm(wlc_info_t *wlc, uint offset, u16 v, int len) * SHM 'offset' needs to be an even address and * Buffer length 'len' must be an even number of bytes */ -void wlc_copyto_shm(wlc_info_t *wlc, uint offset, const void *buf, int len) +void wlc_copyto_shm(struct wlc_info *wlc, uint offset, const void *buf, int len) { /* offset and len need to be even */ ASSERT((offset & 1) == 0); @@ -8151,7 +8154,7 @@ void wlc_copyto_shm(wlc_info_t *wlc, uint offset, const void *buf, int len) * SHM 'offset' needs to be an even address and * Buffer length 'len' must be an even number of bytes */ -void wlc_copyfrom_shm(wlc_info_t *wlc, uint offset, void *buf, int len) +void wlc_copyfrom_shm(struct wlc_info *wlc, uint offset, void *buf, int len) { /* offset and len need to be even */ ASSERT((offset & 1) == 0); @@ -8164,71 +8167,73 @@ void wlc_copyfrom_shm(wlc_info_t *wlc, uint offset, void *buf, int len) } /* wrapper BMAC functions to for HIGH driver access */ -void wlc_mctrl(wlc_info_t *wlc, u32 mask, u32 val) +void wlc_mctrl(struct wlc_info *wlc, u32 mask, u32 val) { wlc_bmac_mctrl(wlc->hw, mask, val); } -void wlc_corereset(wlc_info_t *wlc, u32 flags) +void wlc_corereset(struct wlc_info *wlc, u32 flags) { wlc_bmac_corereset(wlc->hw, flags); } -void wlc_mhf(wlc_info_t *wlc, u8 idx, u16 mask, u16 val, int bands) +void wlc_mhf(struct wlc_info *wlc, u8 idx, u16 mask, u16 val, int bands) { wlc_bmac_mhf(wlc->hw, idx, mask, val, bands); } -u16 wlc_mhf_get(wlc_info_t *wlc, u8 idx, int bands) +u16 wlc_mhf_get(struct wlc_info *wlc, u8 idx, int bands) { return wlc_bmac_mhf_get(wlc->hw, idx, bands); } -int wlc_xmtfifo_sz_get(wlc_info_t *wlc, uint fifo, uint *blocks) +int wlc_xmtfifo_sz_get(struct wlc_info *wlc, uint fifo, uint *blocks) { return wlc_bmac_xmtfifo_sz_get(wlc->hw, fifo, blocks); } -void wlc_write_template_ram(wlc_info_t *wlc, int offset, int len, void *buf) +void wlc_write_template_ram(struct wlc_info *wlc, int offset, int len, + void *buf) { wlc_bmac_write_template_ram(wlc->hw, offset, len, buf); } -void wlc_write_hw_bcntemplates(wlc_info_t *wlc, void *bcn, int len, bool both) +void wlc_write_hw_bcntemplates(struct wlc_info *wlc, void *bcn, int len, + bool both) { wlc_bmac_write_hw_bcntemplates(wlc->hw, bcn, len, both); } void -wlc_set_addrmatch(wlc_info_t *wlc, int match_reg_offset, +wlc_set_addrmatch(struct wlc_info *wlc, int match_reg_offset, const struct ether_addr *addr) { wlc_bmac_set_addrmatch(wlc->hw, match_reg_offset, addr); } -void wlc_set_rcmta(wlc_info_t *wlc, int idx, const struct ether_addr *addr) +void wlc_set_rcmta(struct wlc_info *wlc, int idx, const struct ether_addr *addr) { wlc_bmac_set_rcmta(wlc->hw, idx, addr); } -void wlc_read_tsf(wlc_info_t *wlc, u32 *tsf_l_ptr, u32 *tsf_h_ptr) +void wlc_read_tsf(struct wlc_info *wlc, u32 *tsf_l_ptr, u32 *tsf_h_ptr) { wlc_bmac_read_tsf(wlc->hw, tsf_l_ptr, tsf_h_ptr); } -void wlc_set_cwmin(wlc_info_t *wlc, u16 newmin) +void wlc_set_cwmin(struct wlc_info *wlc, u16 newmin) { wlc->band->CWmin = newmin; wlc_bmac_set_cwmin(wlc->hw, newmin); } -void wlc_set_cwmax(wlc_info_t *wlc, u16 newmax) +void wlc_set_cwmax(struct wlc_info *wlc, u16 newmax) { wlc->band->CWmax = newmax; wlc_bmac_set_cwmax(wlc->hw, newmax); } -void wlc_fifoerrors(wlc_info_t *wlc) +void wlc_fifoerrors(struct wlc_info *wlc) { wlc_bmac_fifoerrors(wlc->hw); @@ -8236,16 +8241,16 @@ void wlc_fifoerrors(wlc_info_t *wlc) /* Search mem rw utilities */ -void wlc_pllreq(wlc_info_t *wlc, bool set, mbool req_bit) +void wlc_pllreq(struct wlc_info *wlc, bool set, mbool req_bit) { wlc_bmac_pllreq(wlc->hw, set, req_bit); } -void wlc_reset_bmac_done(wlc_info_t *wlc) +void wlc_reset_bmac_done(struct wlc_info *wlc) { } -void wlc_ht_mimops_cap_update(wlc_info_t *wlc, u8 mimops_mode) +void wlc_ht_mimops_cap_update(struct wlc_info *wlc, u8 mimops_mode) { wlc->ht_cap.cap &= ~HT_CAP_MIMO_PS_MASK; wlc->ht_cap.cap |= (mimops_mode << HT_CAP_MIMO_PS_SHIFT); @@ -8258,7 +8263,7 @@ void wlc_ht_mimops_cap_update(wlc_info_t *wlc, u8 mimops_mode) /* check for the particular priority flow control bit being set */ bool -wlc_txflowcontrol_prio_isset(wlc_info_t *wlc, wlc_txq_info_t *q, int prio) +wlc_txflowcontrol_prio_isset(struct wlc_info *wlc, wlc_txq_info_t *q, int prio) { uint prio_mask; @@ -8273,7 +8278,8 @@ wlc_txflowcontrol_prio_isset(wlc_info_t *wlc, wlc_txq_info_t *q, int prio) } /* propogate the flow control to all interfaces using the given tx queue */ -void wlc_txflowcontrol(wlc_info_t *wlc, wlc_txq_info_t *qi, bool on, int prio) +void wlc_txflowcontrol(struct wlc_info *wlc, wlc_txq_info_t *qi, + bool on, int prio) { uint prio_bits; uint cur_bits; @@ -8315,7 +8321,7 @@ void wlc_txflowcontrol(wlc_info_t *wlc, wlc_txq_info_t *qi, bool on, int prio) } void -wlc_txflowcontrol_override(wlc_info_t *wlc, wlc_txq_info_t *qi, bool on, +wlc_txflowcontrol_override(struct wlc_info *wlc, wlc_txq_info_t *qi, bool on, uint override) { uint prev_override; @@ -8362,7 +8368,7 @@ wlc_txflowcontrol_override(wlc_info_t *wlc, wlc_txq_info_t *qi, bool on, } } -static void wlc_txflowcontrol_reset(wlc_info_t *wlc) +static void wlc_txflowcontrol_reset(struct wlc_info *wlc) { wlc_txq_info_t *qi; @@ -8375,7 +8381,7 @@ static void wlc_txflowcontrol_reset(wlc_info_t *wlc) } static void -wlc_txflowcontrol_signal(wlc_info_t *wlc, wlc_txq_info_t *qi, bool on, +wlc_txflowcontrol_signal(struct wlc_info *wlc, wlc_txq_info_t *qi, bool on, int prio) { wlc_if_t *wlcif; @@ -8386,7 +8392,7 @@ wlc_txflowcontrol_signal(wlc_info_t *wlc, wlc_txq_info_t *qi, bool on, } } -static wlc_txq_info_t *wlc_txq_alloc(wlc_info_t *wlc, struct osl_info *osh) +static wlc_txq_info_t *wlc_txq_alloc(struct wlc_info *wlc, struct osl_info *osh) { wlc_txq_info_t *qi, *p; @@ -8416,7 +8422,7 @@ static wlc_txq_info_t *wlc_txq_alloc(wlc_info_t *wlc, struct osl_info *osh) return qi; } -static void wlc_txq_free(wlc_info_t *wlc, struct osl_info *osh, +static void wlc_txq_free(struct wlc_info *wlc, struct osl_info *osh, wlc_txq_info_t *qi) { wlc_txq_info_t *p; diff --git a/drivers/staging/brcm80211/sys/wlc_mac80211.h b/drivers/staging/brcm80211/sys/wlc_mac80211.h index 2a6cf2ab19dd..b246a7c22ab0 100644 --- a/drivers/staging/brcm80211/sys/wlc_mac80211.h +++ b/drivers/staging/brcm80211/sys/wlc_mac80211.h @@ -350,7 +350,7 @@ typedef struct wlcband { typedef void (*cb_fn_t) (void *); /* tx completion callback takes 3 args */ -typedef void (*pkcb_fn_t) (wlc_info_t *wlc, uint txstatus, void *arg); +typedef void (*pkcb_fn_t) (struct wlc_info *wlc, uint txstatus, void *arg); typedef struct pkt_cb { pkcb_fn_t fn; /* function to call when tx frame completes */ @@ -421,7 +421,7 @@ typedef struct wlc_hwband { struct wlc_hw_info { struct osl_info *osh; /* pointer to os handle */ bool _piomode; /* true if pio mode */ - wlc_info_t *wlc; + struct wlc_info *wlc; /* fifo */ hnddma_t *di[NFIFO]; /* hnddma handles, per fifo */ @@ -782,7 +782,7 @@ struct wlc_info { /* antsel module specific state */ struct antsel_info { - wlc_info_t *wlc; /* pointer to main wlc structure */ + struct wlc_info *wlc; /* pointer to main wlc structure */ wlc_pub_t *pub; /* pointer to public fn */ u8 antsel_type; /* Type of boardlevel mimo antenna switch-logic * 0 = N/A, 1 = 2x4 board, 2 = 2x3 CB2 board @@ -815,44 +815,45 @@ struct antsel_info { #define WLC_IS_MATCH_SSID(wlc, ssid1, ssid2, len1, len2) \ ((len1 == len2) && !memcmp(ssid1, ssid2, len1)) -extern void wlc_high_dpc(wlc_info_t *wlc, u32 macintstatus); -extern void wlc_fatal_error(wlc_info_t *wlc); -extern void wlc_bmac_rpc_watchdog(wlc_info_t *wlc); -extern void wlc_recv(wlc_info_t *wlc, struct sk_buff *p); -extern bool wlc_dotxstatus(wlc_info_t *wlc, tx_status_t *txs, u32 frm_tx2); -extern void wlc_txfifo(wlc_info_t *wlc, uint fifo, struct sk_buff *p, +extern void wlc_high_dpc(struct wlc_info *wlc, u32 macintstatus); +extern void wlc_fatal_error(struct wlc_info *wlc); +extern void wlc_bmac_rpc_watchdog(struct wlc_info *wlc); +extern void wlc_recv(struct wlc_info *wlc, struct sk_buff *p); +extern bool wlc_dotxstatus(struct wlc_info *wlc, tx_status_t *txs, u32 frm_tx2); +extern void wlc_txfifo(struct wlc_info *wlc, uint fifo, struct sk_buff *p, bool commit, s8 txpktpend); -extern void wlc_txfifo_complete(wlc_info_t *wlc, uint fifo, s8 txpktpend); +extern void wlc_txfifo_complete(struct wlc_info *wlc, uint fifo, s8 txpktpend); extern void wlc_txq_enq(void *ctx, struct scb *scb, struct sk_buff *sdu, uint prec); -extern void wlc_info_init(wlc_info_t *wlc, int unit); +extern void wlc_info_init(struct wlc_info *wlc, int unit); extern void wlc_print_txstatus(tx_status_t *txs); -extern int wlc_xmtfifo_sz_get(wlc_info_t *wlc, uint fifo, uint *blocks); -extern void wlc_write_template_ram(wlc_info_t *wlc, int offset, int len, +extern int wlc_xmtfifo_sz_get(struct wlc_info *wlc, uint fifo, uint *blocks); +extern void wlc_write_template_ram(struct wlc_info *wlc, int offset, int len, void *buf); -extern void wlc_write_hw_bcntemplates(wlc_info_t *wlc, void *bcn, int len, +extern void wlc_write_hw_bcntemplates(struct wlc_info *wlc, void *bcn, int len, bool both); #if defined(BCMDBG) -extern void wlc_get_rcmta(wlc_info_t *wlc, int idx, struct ether_addr *addr); +extern void wlc_get_rcmta(struct wlc_info *wlc, int idx, + struct ether_addr *addr); #endif -extern void wlc_set_rcmta(wlc_info_t *wlc, int idx, +extern void wlc_set_rcmta(struct wlc_info *wlc, int idx, const struct ether_addr *addr); -extern void wlc_set_addrmatch(wlc_info_t *wlc, int match_reg_offset, +extern void wlc_set_addrmatch(struct wlc_info *wlc, int match_reg_offset, const struct ether_addr *addr); -extern void wlc_read_tsf(wlc_info_t *wlc, u32 *tsf_l_ptr, +extern void wlc_read_tsf(struct wlc_info *wlc, u32 *tsf_l_ptr, u32 *tsf_h_ptr); -extern void wlc_set_cwmin(wlc_info_t *wlc, u16 newmin); -extern void wlc_set_cwmax(wlc_info_t *wlc, u16 newmax); -extern void wlc_fifoerrors(wlc_info_t *wlc); -extern void wlc_pllreq(wlc_info_t *wlc, bool set, mbool req_bit); -extern void wlc_reset_bmac_done(wlc_info_t *wlc); -extern void wlc_protection_upd(wlc_info_t *wlc, uint idx, int val); -extern void wlc_hwtimer_gptimer_set(wlc_info_t *wlc, uint us); -extern void wlc_hwtimer_gptimer_abort(wlc_info_t *wlc); +extern void wlc_set_cwmin(struct wlc_info *wlc, u16 newmin); +extern void wlc_set_cwmax(struct wlc_info *wlc, u16 newmax); +extern void wlc_fifoerrors(struct wlc_info *wlc); +extern void wlc_pllreq(struct wlc_info *wlc, bool set, mbool req_bit); +extern void wlc_reset_bmac_done(struct wlc_info *wlc); +extern void wlc_protection_upd(struct wlc_info *wlc, uint idx, int val); +extern void wlc_hwtimer_gptimer_set(struct wlc_info *wlc, uint us); +extern void wlc_hwtimer_gptimer_abort(struct wlc_info *wlc); #if defined(BCMDBG) extern void wlc_print_rxh(d11rxhdr_t *rxh); -extern void wlc_print_hdrs(wlc_info_t *wlc, const char *prefix, u8 *frame, +extern void wlc_print_hdrs(struct wlc_info *wlc, const char *prefix, u8 *frame, d11txh_t *txh, d11rxhdr_t *rxh, uint len); extern void wlc_print_txdesc(d11txh_t *txh); #endif @@ -863,79 +864,83 @@ extern void wlc_print_dot11_mac_hdr(u8 *buf, int len); extern void wlc_setxband(wlc_hw_info_t *wlc_hw, uint bandunit); extern void wlc_coredisable(wlc_hw_info_t *wlc_hw); -extern bool wlc_valid_rate(wlc_info_t *wlc, ratespec_t rate, int band, +extern bool wlc_valid_rate(struct wlc_info *wlc, ratespec_t rate, int band, bool verbose); -extern void wlc_ap_upd(wlc_info_t *wlc); +extern void wlc_ap_upd(struct wlc_info *wlc); /* helper functions */ -extern void wlc_shm_ssid_upd(wlc_info_t *wlc, wlc_bsscfg_t *cfg); -extern int wlc_set_gmode(wlc_info_t *wlc, u8 gmode, bool config); +extern void wlc_shm_ssid_upd(struct wlc_info *wlc, wlc_bsscfg_t *cfg); +extern int wlc_set_gmode(struct wlc_info *wlc, u8 gmode, bool config); -extern void wlc_mac_bcn_promisc_change(wlc_info_t *wlc, bool promisc); -extern void wlc_mac_bcn_promisc(wlc_info_t *wlc); -extern void wlc_mac_promisc(wlc_info_t *wlc); -extern void wlc_txflowcontrol(wlc_info_t *wlc, wlc_txq_info_t *qi, bool on, +extern void wlc_mac_bcn_promisc_change(struct wlc_info *wlc, bool promisc); +extern void wlc_mac_bcn_promisc(struct wlc_info *wlc); +extern void wlc_mac_promisc(struct wlc_info *wlc); +extern void wlc_txflowcontrol(struct wlc_info *wlc, wlc_txq_info_t *qi, bool on, int prio); -extern void wlc_txflowcontrol_override(wlc_info_t *wlc, wlc_txq_info_t *qi, +extern void wlc_txflowcontrol_override(struct wlc_info *wlc, wlc_txq_info_t *qi, bool on, uint override); -extern bool wlc_txflowcontrol_prio_isset(wlc_info_t *wlc, wlc_txq_info_t *qi, - int prio); -extern void wlc_send_q(wlc_info_t *wlc, wlc_txq_info_t *qi); -extern int wlc_prep_pdu(wlc_info_t *wlc, struct sk_buff *pdu, uint *fifo); +extern bool wlc_txflowcontrol_prio_isset(struct wlc_info *wlc, + wlc_txq_info_t *qi, int prio); +extern void wlc_send_q(struct wlc_info *wlc, wlc_txq_info_t *qi); +extern int wlc_prep_pdu(struct wlc_info *wlc, struct sk_buff *pdu, uint *fifo); -extern u16 wlc_calc_lsig_len(wlc_info_t *wlc, ratespec_t ratespec, +extern u16 wlc_calc_lsig_len(struct wlc_info *wlc, ratespec_t ratespec, uint mac_len); -extern ratespec_t wlc_rspec_to_rts_rspec(wlc_info_t *wlc, ratespec_t rspec, +extern ratespec_t wlc_rspec_to_rts_rspec(struct wlc_info *wlc, ratespec_t rspec, bool use_rspec, u16 mimo_ctlchbw); -extern u16 wlc_compute_rtscts_dur(wlc_info_t *wlc, bool cts_only, +extern u16 wlc_compute_rtscts_dur(struct wlc_info *wlc, bool cts_only, ratespec_t rts_rate, ratespec_t frame_rate, u8 rts_preamble_type, u8 frame_preamble_type, uint frame_len, bool ba); -extern void wlc_tbtt(wlc_info_t *wlc, d11regs_t *regs); +extern void wlc_tbtt(struct wlc_info *wlc, d11regs_t *regs); #if defined(BCMDBG) -extern void wlc_dump_ie(wlc_info_t *wlc, bcm_tlv_t *ie, struct bcmstrbuf *b); +extern void wlc_dump_ie(struct wlc_info *wlc, bcm_tlv_t *ie, + struct bcmstrbuf *b); #endif -extern bool wlc_ps_check(wlc_info_t *wlc); -extern void wlc_reprate_init(wlc_info_t *wlc); +extern bool wlc_ps_check(struct wlc_info *wlc); +extern void wlc_reprate_init(struct wlc_info *wlc); extern void wlc_bsscfg_reprate_init(wlc_bsscfg_t *bsscfg); extern void wlc_uint64_sub(u32 *a_high, u32 *a_low, u32 b_high, u32 b_low); extern u32 wlc_calc_tbtt_offset(u32 bi, u32 tsf_h, u32 tsf_l); /* Shared memory access */ -extern void wlc_write_shm(wlc_info_t *wlc, uint offset, u16 v); -extern u16 wlc_read_shm(wlc_info_t *wlc, uint offset); -extern void wlc_set_shm(wlc_info_t *wlc, uint offset, u16 v, int len); -extern void wlc_copyto_shm(wlc_info_t *wlc, uint offset, const void *buf, +extern void wlc_write_shm(struct wlc_info *wlc, uint offset, u16 v); +extern u16 wlc_read_shm(struct wlc_info *wlc, uint offset); +extern void wlc_set_shm(struct wlc_info *wlc, uint offset, u16 v, int len); +extern void wlc_copyto_shm(struct wlc_info *wlc, uint offset, const void *buf, int len); -extern void wlc_copyfrom_shm(wlc_info_t *wlc, uint offset, void *buf, int len); +extern void wlc_copyfrom_shm(struct wlc_info *wlc, uint offset, void *buf, + int len); -extern void wlc_update_beacon(wlc_info_t *wlc); -extern void wlc_bss_update_beacon(wlc_info_t *wlc, struct wlc_bsscfg *bsscfg); +extern void wlc_update_beacon(struct wlc_info *wlc); +extern void wlc_bss_update_beacon(struct wlc_info *wlc, + struct wlc_bsscfg *bsscfg); -extern void wlc_update_probe_resp(wlc_info_t *wlc, bool suspend); -extern void wlc_bss_update_probe_resp(wlc_info_t *wlc, wlc_bsscfg_t *cfg, +extern void wlc_update_probe_resp(struct wlc_info *wlc, bool suspend); +extern void wlc_bss_update_probe_resp(struct wlc_info *wlc, wlc_bsscfg_t *cfg, bool suspend); -extern bool wlc_ismpc(wlc_info_t *wlc); -extern bool wlc_is_non_delay_mpc(wlc_info_t *wlc); -extern void wlc_radio_mpc_upd(wlc_info_t *wlc); -extern bool wlc_prec_enq(wlc_info_t *wlc, struct pktq *q, void *pkt, int prec); -extern bool wlc_prec_enq_head(wlc_info_t *wlc, struct pktq *q, +extern bool wlc_ismpc(struct wlc_info *wlc); +extern bool wlc_is_non_delay_mpc(struct wlc_info *wlc); +extern void wlc_radio_mpc_upd(struct wlc_info *wlc); +extern bool wlc_prec_enq(struct wlc_info *wlc, struct pktq *q, void *pkt, + int prec); +extern bool wlc_prec_enq_head(struct wlc_info *wlc, struct pktq *q, struct sk_buff *pkt, int prec, bool head); -extern u16 wlc_phytxctl1_calc(wlc_info_t *wlc, ratespec_t rspec); -extern void wlc_compute_plcp(wlc_info_t *wlc, ratespec_t rate, uint length, +extern u16 wlc_phytxctl1_calc(struct wlc_info *wlc, ratespec_t rspec); +extern void wlc_compute_plcp(struct wlc_info *wlc, ratespec_t rate, uint length, u8 *plcp); -extern uint wlc_calc_frame_time(wlc_info_t *wlc, ratespec_t ratespec, +extern uint wlc_calc_frame_time(struct wlc_info *wlc, ratespec_t ratespec, u8 preamble_type, uint mac_len); -extern void wlc_set_chanspec(wlc_info_t *wlc, chanspec_t chanspec); +extern void wlc_set_chanspec(struct wlc_info *wlc, chanspec_t chanspec); -extern bool wlc_timers_init(wlc_info_t *wlc, int unit); +extern bool wlc_timers_init(struct wlc_info *wlc, int unit); extern const bcm_iovar_t wlc_iovars[]; @@ -944,36 +949,38 @@ extern int wlc_doiovar(void *hdl, const bcm_iovar_t *vi, u32 actionid, int len, int val_size, wlc_if_t *wlcif); #if defined(BCMDBG) -extern void wlc_print_ies(wlc_info_t *wlc, u8 *ies, uint ies_len); +extern void wlc_print_ies(struct wlc_info *wlc, u8 *ies, uint ies_len); #endif -extern int wlc_set_nmode(wlc_info_t *wlc, s32 nmode); -extern void wlc_ht_mimops_cap_update(wlc_info_t *wlc, u8 mimops_mode); -extern void wlc_mimops_action_ht_send(wlc_info_t *wlc, wlc_bsscfg_t *bsscfg, - u8 mimops_mode); +extern int wlc_set_nmode(struct wlc_info *wlc, s32 nmode); +extern void wlc_ht_mimops_cap_update(struct wlc_info *wlc, u8 mimops_mode); +extern void wlc_mimops_action_ht_send(struct wlc_info *wlc, + wlc_bsscfg_t *bsscfg, u8 mimops_mode); -extern void wlc_switch_shortslot(wlc_info_t *wlc, bool shortslot); +extern void wlc_switch_shortslot(struct wlc_info *wlc, bool shortslot); extern void wlc_set_bssid(wlc_bsscfg_t *cfg); extern void wlc_edcf_setparams(wlc_bsscfg_t *cfg, bool suspend); -extern void wlc_set_ratetable(wlc_info_t *wlc); +extern void wlc_set_ratetable(struct wlc_info *wlc); extern int wlc_set_mac(wlc_bsscfg_t *cfg); -extern void wlc_beacon_phytxctl_txant_upd(wlc_info_t *wlc, +extern void wlc_beacon_phytxctl_txant_upd(struct wlc_info *wlc, ratespec_t bcn_rate); -extern void wlc_mod_prb_rsp_rate_table(wlc_info_t *wlc, uint frame_len); -extern ratespec_t wlc_lowest_basic_rspec(wlc_info_t *wlc, wlc_rateset_t *rs); -extern u16 wlc_compute_bcntsfoff(wlc_info_t *wlc, ratespec_t rspec, +extern void wlc_mod_prb_rsp_rate_table(struct wlc_info *wlc, uint frame_len); +extern ratespec_t wlc_lowest_basic_rspec(struct wlc_info *wlc, + wlc_rateset_t *rs); +extern u16 wlc_compute_bcntsfoff(struct wlc_info *wlc, ratespec_t rspec, bool short_preamble, bool phydelay); -extern void wlc_radio_disable(wlc_info_t *wlc); -extern void wlc_bcn_li_upd(wlc_info_t *wlc); - -extern int wlc_get_revision_info(wlc_info_t *wlc, void *buf, uint len); -extern void wlc_out(wlc_info_t *wlc); -extern void wlc_set_home_chanspec(wlc_info_t *wlc, chanspec_t chanspec); -extern void wlc_watchdog_upd(wlc_info_t *wlc, bool tbtt); -extern bool wlc_ps_allowed(wlc_info_t *wlc); -extern bool wlc_stay_awake(wlc_info_t *wlc); -extern void wlc_wme_initparams_sta(wlc_info_t *wlc, wme_param_ie_t *pe); - -extern void wlc_bss_list_free(wlc_info_t *wlc, wlc_bss_list_t *bss_list); +extern void wlc_radio_disable(struct wlc_info *wlc); +extern void wlc_bcn_li_upd(struct wlc_info *wlc); + +extern int wlc_get_revision_info(struct wlc_info *wlc, void *buf, uint len); +extern void wlc_out(struct wlc_info *wlc); +extern void wlc_set_home_chanspec(struct wlc_info *wlc, chanspec_t chanspec); +extern void wlc_watchdog_upd(struct wlc_info *wlc, bool tbtt); +extern bool wlc_ps_allowed(struct wlc_info *wlc); +extern bool wlc_stay_awake(struct wlc_info *wlc); +extern void wlc_wme_initparams_sta(struct wlc_info *wlc, wme_param_ie_t *pe); + +extern void wlc_bss_list_free(struct wlc_info *wlc, wlc_bss_list_t *bss_list); +extern void wlc_ht_mimops_cap_update(struct wlc_info *wlc, u8 mimops_mode); #endif /* _wlc_h_ */ diff --git a/drivers/staging/brcm80211/sys/wlc_pub.h b/drivers/staging/brcm80211/sys/wlc_pub.h index ea796cb40b7a..1530efe15f97 100644 --- a/drivers/staging/brcm80211/sys/wlc_pub.h +++ b/drivers/staging/brcm80211/sys/wlc_pub.h @@ -512,7 +512,7 @@ extern bool wlc_isr(struct wlc_info *wlc, bool *wantdpc); extern bool wlc_dpc(struct wlc_info *wlc, bool bounded); extern bool wlc_send80211_raw(struct wlc_info *wlc, wlc_if_t *wlcif, void *p, uint ac); -extern bool wlc_sendpkt_mac80211(wlc_info_t *wlc, struct sk_buff *sdu, +extern bool wlc_sendpkt_mac80211(struct wlc_info *wlc, struct sk_buff *sdu, struct ieee80211_hw *hw); extern int wlc_iovar_op(struct wlc_info *wlc, const char *name, void *params, int p_len, void *arg, int len, bool set, @@ -522,10 +522,10 @@ extern int wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, /* helper functions */ extern void wlc_statsupd(struct wlc_info *wlc); extern int wlc_get_header_len(void); -extern void wlc_mac_bcn_promisc_change(wlc_info_t *wlc, bool promisc); -extern void wlc_set_addrmatch(wlc_info_t *wlc, int match_reg_offset, +extern void wlc_mac_bcn_promisc_change(struct wlc_info *wlc, bool promisc); +extern void wlc_set_addrmatch(struct wlc_info *wlc, int match_reg_offset, const struct ether_addr *addr); -extern void wlc_wme_setparams(wlc_info_t *wlc, u16 aci, void *arg, +extern void wlc_wme_setparams(struct wlc_info *wlc, u16 aci, void *arg, bool suspend); extern wlc_pub_t *wlc_pub(void *wlc); diff --git a/drivers/staging/brcm80211/sys/wlc_scb.h b/drivers/staging/brcm80211/sys/wlc_scb.h index ce26c740e6c1..fe84e993b52a 100644 --- a/drivers/staging/brcm80211/sys/wlc_scb.h +++ b/drivers/staging/brcm80211/sys/wlc_scb.h @@ -19,7 +19,7 @@ #include -extern bool wlc_aggregatable(wlc_info_t *wlc, u8 tid); +extern bool wlc_aggregatable(struct wlc_info *wlc, u8 tid); #define AMPDU_TX_BA_MAX_WSIZE 64 /* max Tx ba window size (in pdu) */ /* structure to store per-tid state for the ampdu initiator */ diff --git a/drivers/staging/brcm80211/sys/wlc_stf.c b/drivers/staging/brcm80211/sys/wlc_stf.c index 2bca0526b44c..ee090746b088 100644 --- a/drivers/staging/brcm80211/sys/wlc_stf.c +++ b/drivers/staging/brcm80211/sys/wlc_stf.c @@ -44,14 +44,14 @@ #define WLC_STF_SS_STBC_RX(wlc) (WLCISNPHY(wlc->band) && \ NREV_GT(wlc->band->phyrev, 3) && NREV_LE(wlc->band->phyrev, 6)) -static s8 wlc_stf_stbc_rx_get(wlc_info_t *wlc); -static bool wlc_stf_stbc_tx_set(wlc_info_t *wlc, s32 int_val); -static int wlc_stf_txcore_set(wlc_info_t *wlc, u8 Nsts, u8 val); -static int wlc_stf_spatial_policy_set(wlc_info_t *wlc, int val); -static void wlc_stf_stbc_rx_ht_update(wlc_info_t *wlc, int val); +static s8 wlc_stf_stbc_rx_get(struct wlc_info *wlc); +static bool wlc_stf_stbc_tx_set(struct wlc_info *wlc, s32 int_val); +static int wlc_stf_txcore_set(struct wlc_info *wlc, u8 Nsts, u8 val); +static int wlc_stf_spatial_policy_set(struct wlc_info *wlc, int val); +static void wlc_stf_stbc_rx_ht_update(struct wlc_info *wlc, int val); -static void _wlc_stf_phy_txant_upd(wlc_info_t *wlc); -static u16 _wlc_stf_phytxchain_sel(wlc_info_t *wlc, ratespec_t rspec); +static void _wlc_stf_phy_txant_upd(struct wlc_info *wlc); +static u16 _wlc_stf_phytxchain_sel(struct wlc_info *wlc, ratespec_t rspec); #define NSTS_1 1 #define NSTS_2 2 @@ -65,7 +65,7 @@ const u8 txcore_default[5] = { (0x0f) /* For Nsts = 4, enable all cores */ }; -static void wlc_stf_stbc_rx_ht_update(wlc_info_t *wlc, int val) +static void wlc_stf_stbc_rx_ht_update(struct wlc_info *wlc, int val) { ASSERT((val == HT_CAP_RX_STBC_NO) || (val == HT_CAP_RX_STBC_ONE_STREAM)); @@ -86,7 +86,7 @@ static void wlc_stf_stbc_rx_ht_update(wlc_info_t *wlc, int val) } /* every WLC_TEMPSENSE_PERIOD seconds temperature check to decide whether to turn on/off txchain */ -void wlc_tempsense_upd(wlc_info_t *wlc) +void wlc_tempsense_upd(struct wlc_info *wlc) { wlc_phy_t *pi = wlc->band->pi; uint active_chains, txchain; @@ -110,7 +110,7 @@ void wlc_tempsense_upd(wlc_info_t *wlc) } void -wlc_stf_ss_algo_channel_get(wlc_info_t *wlc, u16 *ss_algo_channel, +wlc_stf_ss_algo_channel_get(struct wlc_info *wlc, u16 *ss_algo_channel, chanspec_t chanspec) { tx_power_t power; @@ -151,12 +151,12 @@ wlc_stf_ss_algo_channel_get(wlc_info_t *wlc, u16 *ss_algo_channel, setbit(ss_algo_channel, PHY_TXC1_MODE_STBC); } -static s8 wlc_stf_stbc_rx_get(wlc_info_t *wlc) +static s8 wlc_stf_stbc_rx_get(struct wlc_info *wlc) { return (wlc->ht_cap.cap & HT_CAP_RX_STBC_MASK) >> HT_CAP_RX_STBC_SHIFT; } -static bool wlc_stf_stbc_tx_set(wlc_info_t *wlc, s32 int_val) +static bool wlc_stf_stbc_tx_set(struct wlc_info *wlc, s32 int_val) { if ((int_val != AUTO) && (int_val != OFF) && (int_val != ON)) { return false; @@ -177,7 +177,7 @@ static bool wlc_stf_stbc_tx_set(wlc_info_t *wlc, s32 int_val) return true; } -bool wlc_stf_stbc_rx_set(wlc_info_t *wlc, s32 int_val) +bool wlc_stf_stbc_rx_set(struct wlc_info *wlc, s32 int_val) { if ((int_val != HT_CAP_RX_STBC_NO) && (int_val != HT_CAP_RX_STBC_ONE_STREAM)) { @@ -194,7 +194,7 @@ bool wlc_stf_stbc_rx_set(wlc_info_t *wlc, s32 int_val) return true; } -static int wlc_stf_txcore_set(wlc_info_t *wlc, u8 Nsts, u8 core_mask) +static int wlc_stf_txcore_set(struct wlc_info *wlc, u8 Nsts, u8 core_mask) { WL_TRACE(("wl%d: %s: Nsts %d core_mask %x\n", wlc->pub->unit, __func__, Nsts, core_mask)); @@ -231,7 +231,7 @@ static int wlc_stf_txcore_set(wlc_info_t *wlc, u8 Nsts, u8 core_mask) return BCME_OK; } -static int wlc_stf_spatial_policy_set(wlc_info_t *wlc, int val) +static int wlc_stf_spatial_policy_set(struct wlc_info *wlc, int val) { int i; u8 core_mask = 0; @@ -247,7 +247,7 @@ static int wlc_stf_spatial_policy_set(wlc_info_t *wlc, int val) return BCME_OK; } -int wlc_stf_txchain_set(wlc_info_t *wlc, s32 int_val, bool force) +int wlc_stf_txchain_set(struct wlc_info *wlc, s32 int_val, bool force) { u8 txchain = (u8) int_val; u8 txstreams; @@ -307,7 +307,7 @@ int wlc_stf_txchain_set(wlc_info_t *wlc, s32 int_val, bool force) return BCME_OK; } -int wlc_stf_rxchain_set(wlc_info_t *wlc, s32 int_val) +int wlc_stf_rxchain_set(struct wlc_info *wlc, s32 int_val) { u8 rxchain_cnt; u8 rxchain = (u8) int_val; @@ -371,7 +371,7 @@ int wlc_stf_rxchain_set(wlc_info_t *wlc, s32 int_val) } /* update wlc->stf->ss_opmode which represents the operational stf_ss mode we're using */ -int wlc_stf_ss_update(wlc_info_t *wlc, wlcband_t *band) +int wlc_stf_ss_update(struct wlc_info *wlc, wlcband_t *band) { int ret_code = 0; u8 prev_stf_ss; @@ -406,7 +406,7 @@ int wlc_stf_ss_update(wlc_info_t *wlc, wlcband_t *band) return ret_code; } -int wlc_stf_attach(wlc_info_t *wlc) +int wlc_stf_attach(struct wlc_info *wlc) { wlc->bandstate[BAND_2G_INDEX]->band_stf_ss_mode = PHY_TXC1_MODE_SISO; wlc->bandstate[BAND_5G_INDEX]->band_stf_ss_mode = PHY_TXC1_MODE_CDD; @@ -429,11 +429,11 @@ int wlc_stf_attach(wlc_info_t *wlc) return 0; } -void wlc_stf_detach(wlc_info_t *wlc) +void wlc_stf_detach(struct wlc_info *wlc) { } -int wlc_stf_ant_txant_validate(wlc_info_t *wlc, s8 val) +int wlc_stf_ant_txant_validate(struct wlc_info *wlc, s8 val) { int bcmerror = BCME_OK; @@ -480,7 +480,7 @@ int wlc_stf_ant_txant_validate(wlc_info_t *wlc, s8 val) * do tx-antenna selection for SISO transmissions * for NREV>=7, bit 6 and bit 7 mean antenna 0 and 1 respectively, nit6+bit7 means both cores active */ -static void _wlc_stf_phy_txant_upd(wlc_info_t *wlc) +static void _wlc_stf_phy_txant_upd(struct wlc_info *wlc) { s8 txant; @@ -521,12 +521,12 @@ static void _wlc_stf_phy_txant_upd(wlc_info_t *wlc) wlc_bmac_txant_set(wlc->hw, wlc->stf->phytxant); } -void wlc_stf_phy_txant_upd(wlc_info_t *wlc) +void wlc_stf_phy_txant_upd(struct wlc_info *wlc) { _wlc_stf_phy_txant_upd(wlc); } -void wlc_stf_phy_chain_calc(wlc_info_t *wlc) +void wlc_stf_phy_chain_calc(struct wlc_info *wlc) { /* get available rx/tx chains */ wlc->stf->hw_txchain = (u8) getintvar(wlc->pub->vars, "txchain"); @@ -563,7 +563,7 @@ void wlc_stf_phy_chain_calc(wlc_info_t *wlc) wlc_stf_spatial_policy_set(wlc, MIN_SPATIAL_EXPANSION); } -static u16 _wlc_stf_phytxchain_sel(wlc_info_t *wlc, ratespec_t rspec) +static u16 _wlc_stf_phytxchain_sel(struct wlc_info *wlc, ratespec_t rspec) { u16 phytxant = wlc->stf->phytxant; @@ -576,12 +576,12 @@ static u16 _wlc_stf_phytxchain_sel(wlc_info_t *wlc, ratespec_t rspec) return phytxant; } -u16 wlc_stf_phytxchain_sel(wlc_info_t *wlc, ratespec_t rspec) +u16 wlc_stf_phytxchain_sel(struct wlc_info *wlc, ratespec_t rspec) { return _wlc_stf_phytxchain_sel(wlc, rspec); } -u16 wlc_stf_d11hdrs_phyctl_txant(wlc_info_t *wlc, ratespec_t rspec) +u16 wlc_stf_d11hdrs_phyctl_txant(struct wlc_info *wlc, ratespec_t rspec) { u16 phytxant = wlc->stf->phytxant; u16 mask = PHY_TXC_ANT_MASK; diff --git a/drivers/staging/brcm80211/sys/wlc_stf.h b/drivers/staging/brcm80211/sys/wlc_stf.h index ee9b02a119bb..8de6382e620d 100644 --- a/drivers/staging/brcm80211/sys/wlc_stf.h +++ b/drivers/staging/brcm80211/sys/wlc_stf.h @@ -20,23 +20,24 @@ #define MIN_SPATIAL_EXPANSION 0 #define MAX_SPATIAL_EXPANSION 1 -extern int wlc_stf_attach(wlc_info_t *wlc); -extern void wlc_stf_detach(wlc_info_t *wlc); +extern int wlc_stf_attach(struct wlc_info *wlc); +extern void wlc_stf_detach(struct wlc_info *wlc); -extern void wlc_tempsense_upd(wlc_info_t *wlc); -extern void wlc_stf_ss_algo_channel_get(wlc_info_t *wlc, +extern void wlc_tempsense_upd(struct wlc_info *wlc); +extern void wlc_stf_ss_algo_channel_get(struct wlc_info *wlc, u16 *ss_algo_channel, chanspec_t chanspec); -extern int wlc_stf_ss_update(wlc_info_t *wlc, struct wlcband *band); -extern void wlc_stf_phy_txant_upd(wlc_info_t *wlc); -extern int wlc_stf_txchain_set(wlc_info_t *wlc, s32 int_val, bool force); -extern int wlc_stf_rxchain_set(wlc_info_t *wlc, s32 int_val); -extern bool wlc_stf_stbc_rx_set(wlc_info_t *wlc, s32 int_val); +extern int wlc_stf_ss_update(struct wlc_info *wlc, struct wlcband *band); +extern void wlc_stf_phy_txant_upd(struct wlc_info *wlc); +extern int wlc_stf_txchain_set(struct wlc_info *wlc, s32 int_val, bool force); +extern int wlc_stf_rxchain_set(struct wlc_info *wlc, s32 int_val); +extern bool wlc_stf_stbc_rx_set(struct wlc_info *wlc, s32 int_val); -extern int wlc_stf_ant_txant_validate(wlc_info_t *wlc, s8 val); -extern void wlc_stf_phy_txant_upd(wlc_info_t *wlc); -extern void wlc_stf_phy_chain_calc(wlc_info_t *wlc); -extern u16 wlc_stf_phytxchain_sel(wlc_info_t *wlc, ratespec_t rspec); -extern u16 wlc_stf_d11hdrs_phyctl_txant(wlc_info_t *wlc, ratespec_t rspec); -extern u16 wlc_stf_spatial_expansion_get(wlc_info_t *wlc, ratespec_t rspec); +extern int wlc_stf_ant_txant_validate(struct wlc_info *wlc, s8 val); +extern void wlc_stf_phy_txant_upd(struct wlc_info *wlc); +extern void wlc_stf_phy_chain_calc(struct wlc_info *wlc); +extern u16 wlc_stf_phytxchain_sel(struct wlc_info *wlc, ratespec_t rspec); +extern u16 wlc_stf_d11hdrs_phyctl_txant(struct wlc_info *wlc, ratespec_t rspec); +extern u16 wlc_stf_spatial_expansion_get(struct wlc_info *wlc, + ratespec_t rspec); #endif /* _wlc_stf_h_ */ diff --git a/drivers/staging/brcm80211/sys/wlc_types.h b/drivers/staging/brcm80211/sys/wlc_types.h index dffba3e8b62f..52f888690530 100644 --- a/drivers/staging/brcm80211/sys/wlc_types.h +++ b/drivers/staging/brcm80211/sys/wlc_types.h @@ -19,7 +19,7 @@ /* forward declarations */ -typedef struct wlc_info wlc_info_t; +struct wlc_info; typedef struct wlc_hw_info wlc_hw_info_t; typedef struct wlc_if wlc_if_t; typedef struct wl_if wl_if_t; -- cgit v1.2.3 From f09e02322ed36feafba6e3a6373e0bcd93730ce6 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Sat, 4 Dec 2010 16:35:42 +0100 Subject: staging: brcm80211: remove macro usage for sk_buff allocation PKTGET macro calls osl_pktget. This function has been renamed to pkt_buf_get_skb as it comprises of functionality additional to dev_alloc_skb function and to get rid of the OSL concept in this driver. Reviewed-by: Brett Rudley Reviewed-by: Dowan Kim Signed-off-by: Arend van Spriel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c | 8 ++++---- drivers/staging/brcm80211/brcmfmac/dhd_sdio.c | 24 +++++++++++------------ drivers/staging/brcm80211/include/osl.h | 3 +-- drivers/staging/brcm80211/util/hnddma.c | 2 +- drivers/staging/brcm80211/util/linux_osl.c | 4 ++-- 5 files changed, 20 insertions(+), 21 deletions(-) diff --git a/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c b/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c index 2e02d5e58415..b8eb589cdaab 100644 --- a/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c +++ b/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c @@ -1039,9 +1039,9 @@ sdioh_request_buffer(sdioh_info_t *sd, uint pio_dma, uint fix_inc, uint write, if (pkt == NULL) { sd_data(("%s: Creating new %s Packet, len=%d\n", __func__, write ? "TX" : "RX", buflen_u)); - mypkt = PKTGET(sd->osh, buflen_u, write ? true : false); + mypkt = pkt_buf_get_skb(sd->osh, buflen_u); if (!mypkt) { - sd_err(("%s: PKTGET failed: len %d\n", + sd_err(("%s: pkt_buf_get_skb failed: len %d\n", __func__, buflen_u)); return SDIOH_API_RC_FAIL; } @@ -1066,9 +1066,9 @@ sdioh_request_buffer(sdioh_info_t *sd, uint pio_dma, uint fix_inc, uint write, sd_data(("%s: Creating aligned %s Packet, len=%d\n", __func__, write ? "TX" : "RX", pkt->len)); - mypkt = PKTGET(sd->osh, pkt->len, write ? true : false); + mypkt = pkt_buf_get_skb(sd->osh, pkt->len); if (!mypkt) { - sd_err(("%s: PKTGET failed: len %d\n", + sd_err(("%s: pkt_buf_get_skb failed: len %d\n", __func__, pkt->len)); return SDIOH_API_RC_FAIL; } diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c b/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c index 6b41d1f1b764..c054f0d50152 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c +++ b/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c @@ -936,7 +936,7 @@ static int dhdsdio_txpkt(dhd_bus_t *bus, struct sk_buff *pkt, uint chan, DHD_INFO(("%s: insufficient headroom %d for %d pad\n", __func__, skb_headroom(pkt), pad)); bus->dhd->tx_realloc++; - new = PKTGET(osh, (pkt->len + DHD_SDALIGN), true); + new = pkt_buf_get_skb(osh, (pkt->len + DHD_SDALIGN)); if (!new) { DHD_ERROR(("%s: couldn't allocate new %d-byte " "packet\n", @@ -3240,9 +3240,9 @@ static u8 dhdsdio_rxglom(dhd_bus_t *bus, u8 rxseq) } /* Allocate/chain packet for next subframe */ - pnext = PKTGET(osh, sublen + DHD_SDALIGN, false); + pnext = pkt_buf_get_skb(osh, sublen + DHD_SDALIGN); if (pnext == NULL) { - DHD_ERROR(("%s: PKTGET failed, num %d len %d\n", + DHD_ERROR(("%s: pkt_buf_get_skb failed, num %d len %d\n", __func__, num, sublen)); break; } @@ -3680,7 +3680,7 @@ static uint dhdsdio_readframes(dhd_bus_t *bus, uint maxframes, bool *finished) */ /* Allocate a packet buffer */ dhd_os_sdlock_rxq(bus->dhd); - pkt = PKTGET(osh, rdlen + DHD_SDALIGN, false); + pkt = pkt_buf_get_skb(osh, rdlen + DHD_SDALIGN); if (!pkt) { if (bus->bus == SPI_BUS) { bus->usebufpool = false; @@ -3726,7 +3726,7 @@ static uint dhdsdio_readframes(dhd_bus_t *bus, uint maxframes, bool *finished) } else { /* Give up on data, request rtx of events */ - DHD_ERROR(("%s (nextlen): PKTGET failed: len %d rdlen %d " "expected rxseq %d\n", + DHD_ERROR(("%s (nextlen): pkt_buf_get_skb failed: len %d rdlen %d " "expected rxseq %d\n", __func__, len, rdlen, rxseq)); /* Just go try again w/normal header read */ @@ -4091,10 +4091,10 @@ static uint dhdsdio_readframes(dhd_bus_t *bus, uint maxframes, bool *finished) } dhd_os_sdlock_rxq(bus->dhd); - pkt = PKTGET(osh, (rdlen + firstread + DHD_SDALIGN), false); + pkt = pkt_buf_get_skb(osh, (rdlen + firstread + DHD_SDALIGN)); if (!pkt) { /* Give up on data, request rtx of events */ - DHD_ERROR(("%s: PKTGET failed: rdlen %d chan %d\n", + DHD_ERROR(("%s: pkt_buf_get_skb failed: rdlen %d chan %d\n", __func__, rdlen, chan)); bus->dhd->rx_dropped++; dhd_os_sdunlock_rxq(bus->dhd); @@ -4663,11 +4663,11 @@ static void dhdsdio_pktgen(dhd_bus_t *bus) /* Allocate an appropriate-sized packet */ len = bus->pktgen_len; - pkt = PKTGET(osh, + pkt = pkt_buf_get_skb(osh, (len + SDPCM_HDRLEN + SDPCM_TEST_HDRLEN + DHD_SDALIGN), true); if (!pkt) { - DHD_ERROR(("%s: PKTGET failed!\n", __func__)); + DHD_ERROR(("%s: pkt_buf_get_skb failed!\n", __func__)); break; } PKTALIGN(osh, pkt, (len + SDPCM_HDRLEN + SDPCM_TEST_HDRLEN), @@ -4743,10 +4743,10 @@ static void dhdsdio_sdtest_set(dhd_bus_t *bus, bool start) struct osl_info *osh = bus->dhd->osh; /* Allocate the packet */ - pkt = PKTGET(osh, SDPCM_HDRLEN + SDPCM_TEST_HDRLEN + DHD_SDALIGN, + pkt = pkt_buf_get_skb(osh, SDPCM_HDRLEN + SDPCM_TEST_HDRLEN + DHD_SDALIGN, true); if (!pkt) { - DHD_ERROR(("%s: PKTGET failed!\n", __func__)); + DHD_ERROR(("%s: pkt_buf_get_skb failed!\n", __func__)); return; } PKTALIGN(osh, pkt, (SDPCM_HDRLEN + SDPCM_TEST_HDRLEN), DHD_SDALIGN); @@ -5008,7 +5008,7 @@ extern int dhd_bus_console_in(dhd_pub_t *dhdp, unsigned char *msg, uint msglen) /* Bump dongle by sending an empty event pkt. * sdpcm_sendup (RX) checks for virtual console input. */ - pkt = PKTGET(bus->dhd->osh, 4 + SDPCM_RESERVE, true); + pkt = pkt_buf_get_skb(bus->dhd->osh, 4 + SDPCM_RESERVE); if ((pkt != NULL) && bus->clkstate == CLK_AVAIL) dhdsdio_txpkt(bus, pkt, SDPCM_EVENT_CHANNEL, true); diff --git a/drivers/staging/brcm80211/include/osl.h b/drivers/staging/brcm80211/include/osl.h index 54fdfd609729..4d5893a70dd2 100644 --- a/drivers/staging/brcm80211/include/osl.h +++ b/drivers/staging/brcm80211/include/osl.h @@ -208,10 +208,9 @@ extern void osl_dma_unmap(struct osl_info *osh, uint pa, uint size, #define bcopy(src, dst, len) memcpy((dst), (src), (len)) /* packet primitives */ -#define PKTGET(osh, len, send) osl_pktget((osh), (len)) #define PKTFREE(osh, skb, send) osl_pktfree((osh), (skb), (send)) -extern void *osl_pktget(struct osl_info *osh, uint len); +extern struct sk_buff *pkt_buf_get_skb(struct osl_info *osh, uint len); extern void osl_pktfree(struct osl_info *osh, void *skb, bool send); #endif /* _osl_h_ */ diff --git a/drivers/staging/brcm80211/util/hnddma.c b/drivers/staging/brcm80211/util/hnddma.c index 0c8a1d25d98b..a7805a88b5fe 100644 --- a/drivers/staging/brcm80211/util/hnddma.c +++ b/drivers/staging/brcm80211/util/hnddma.c @@ -1094,7 +1094,7 @@ static bool BCMFASTPATH _dma_rxfill(dma_info_t *di) size to be allocated */ - p = osl_pktget(di->osh, di->rxbufsize + extra_offset); + p = pkt_buf_get_skb(di->osh, di->rxbufsize + extra_offset); if (p == NULL) { DMA_ERROR(("%s: dma_rxfill: out of rxbufs\n", diff --git a/drivers/staging/brcm80211/util/linux_osl.c b/drivers/staging/brcm80211/util/linux_osl.c index 2efce7aeec78..cd78edbcf43f 100644 --- a/drivers/staging/brcm80211/util/linux_osl.c +++ b/drivers/staging/brcm80211/util/linux_osl.c @@ -79,7 +79,7 @@ void osl_detach(struct osl_info *osh) kfree(osh); } -void *BCMFASTPATH osl_pktget(struct osl_info *osh, uint len) +struct sk_buff *BCMFASTPATH pkt_buf_get_skb(struct osl_info *osh, uint len) { struct sk_buff *skb; @@ -91,7 +91,7 @@ void *BCMFASTPATH osl_pktget(struct osl_info *osh, uint len) osh->pktalloced++; } - return (void *)skb; + return skb; } /* Free the driver packet. Free the tag if present */ -- cgit v1.2.3 From 8538576474e162e4967532a80305d17e871f2fa5 Mon Sep 17 00:00:00 2001 From: Arend van Spriel Date: Sat, 4 Dec 2010 16:35:43 +0100 Subject: staging: brcm80211: remove macro usage for sk_buff release PKTFREE macro calls osl_pktfree. This function has been renamed to pkt_buf_free_skb as it comprises of functionality additional to dev_kfree_skb(_any) function and to get rid of the OSL concept in this driver. Reviewed-by: Brett Rudley Reviewed-by: Dowan Kim Signed-off-by: Arend van Spriel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c | 4 +- drivers/staging/brcm80211/brcmfmac/dhd_common.c | 2 +- drivers/staging/brcm80211/brcmfmac/dhd_sdio.c | 50 +++++++++++------------ drivers/staging/brcm80211/include/osl.h | 4 +- drivers/staging/brcm80211/sys/wlc_bmac.c | 2 +- drivers/staging/brcm80211/sys/wlc_mac80211.c | 8 ++-- drivers/staging/brcm80211/util/bcmutils.c | 4 +- drivers/staging/brcm80211/util/hnddma.c | 17 +++----- drivers/staging/brcm80211/util/linux_osl.c | 5 +-- 9 files changed, 44 insertions(+), 52 deletions(-) diff --git a/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c b/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c index b8eb589cdaab..d399b5c76f94 100644 --- a/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c +++ b/drivers/staging/brcm80211/brcmfmac/bcmsdh_sdmmc.c @@ -1057,7 +1057,7 @@ sdioh_request_buffer(sdioh_info_t *sd, uint pio_dma, uint fix_inc, uint write, if (!write) bcopy(mypkt->data, buffer, buflen_u); - PKTFREE(sd->osh, mypkt, write ? true : false); + pkt_buf_free_skb(sd->osh, mypkt, write ? true : false); } else if (((u32) (pkt->data) & DMA_ALIGN_MASK) != 0) { /* Case 2: We have a packet, but it is unaligned. */ @@ -1084,7 +1084,7 @@ sdioh_request_buffer(sdioh_info_t *sd, uint pio_dma, uint fix_inc, uint write, if (!write) bcopy(mypkt->data, pkt->data, mypkt->len); - PKTFREE(sd->osh, mypkt, write ? true : false); + pkt_buf_free_skb(sd->osh, mypkt, write ? true : false); } else { /* case 3: We have a packet and it is aligned. */ sd_data(("%s: Aligned %s Packet, direct DMA\n", diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_common.c b/drivers/staging/brcm80211/brcmfmac/dhd_common.c index ce5f9134055c..324d020b864e 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_common.c +++ b/drivers/staging/brcm80211/brcmfmac/dhd_common.c @@ -368,7 +368,7 @@ bool dhd_prec_enq(dhd_pub_t *dhdp, struct pktq *q, struct sk_buff *pkt, ASSERT(p); } - PKTFREE(dhdp->osh, p, true); + pkt_buf_free_skb(dhdp->osh, p, true); } /* Enqueue */ diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c b/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c index c054f0d50152..3edce44978a1 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c +++ b/drivers/staging/brcm80211/brcmfmac/dhd_sdio.c @@ -144,7 +144,7 @@ * bufpool was present for gspi bus. */ #define PKTFREE2() if ((bus->bus != SPI_BUS) || bus->usebufpool) \ - PKTFREE(bus->dhd->osh, pkt, false); + pkt_buf_free_skb(bus->dhd->osh, pkt, false); DHD_SPINWAIT_SLEEP_INIT(sdioh_spinwait_sleep); extern int dhdcdc_set_ioctl(dhd_pub_t *dhd, int ifidx, uint cmd, void *buf, uint len); @@ -948,7 +948,7 @@ static int dhdsdio_txpkt(dhd_bus_t *bus, struct sk_buff *pkt, uint chan, PKTALIGN(osh, new, pkt->len, DHD_SDALIGN); bcopy(pkt->data, new->data, pkt->len); if (free_pkt) - PKTFREE(osh, pkt, true); + pkt_buf_free_skb(osh, pkt, true); /* free the pkt if canned one is not used */ free_pkt = true; pkt = new; @@ -1061,7 +1061,7 @@ done: dhd_os_sdlock(bus->dhd); if (free_pkt) - PKTFREE(osh, pkt, true); + pkt_buf_free_skb(osh, pkt, true); return ret; } @@ -1112,7 +1112,7 @@ int dhd_bus_txdata(struct dhd_bus *bus, struct sk_buff *pkt) if (dhd_prec_enq(bus->dhd, &bus->txq, pkt, prec) == false) { skb_pull(pkt, SDPCM_HDRLEN); dhd_txcomplete(bus->dhd, pkt, false); - PKTFREE(osh, pkt, true); + pkt_buf_free_skb(osh, pkt, true); DHD_ERROR(("%s: out of bus->txq !!!\n", __func__)); ret = BCME_NORESOURCE; } else { @@ -2882,10 +2882,10 @@ void dhd_bus_stop(struct dhd_bus *bus, bool enforce_mutex) /* Clear any held glomming stuff */ if (bus->glomd) - PKTFREE(osh, bus->glomd, false); + pkt_buf_free_skb(osh, bus->glomd, false); if (bus->glom) - PKTFREE(osh, bus->glom, false); + pkt_buf_free_skb(osh, bus->glom, false); bus->glom = bus->glomd = NULL; @@ -3276,13 +3276,13 @@ static u8 dhdsdio_rxglom(dhd_bus_t *bus, u8 rxseq) pfirst = pnext = NULL; } else { if (pfirst) - PKTFREE(osh, pfirst, false); + pkt_buf_free_skb(osh, pfirst, false); bus->glom = NULL; num = 0; } /* Done with descriptor packet */ - PKTFREE(osh, bus->glomd, false); + pkt_buf_free_skb(osh, bus->glomd, false); bus->glomd = NULL; bus->nextlen = 0; @@ -3351,7 +3351,7 @@ static u8 dhdsdio_rxglom(dhd_bus_t *bus, u8 rxseq) bus->glomerr = 0; dhdsdio_rxfail(bus, true, false); dhd_os_sdlock_rxq(bus->dhd); - PKTFREE(osh, bus->glom, false); + pkt_buf_free_skb(osh, bus->glom, false); dhd_os_sdunlock_rxq(bus->dhd); bus->rxglomfail++; bus->glom = NULL; @@ -3480,7 +3480,7 @@ static u8 dhdsdio_rxglom(dhd_bus_t *bus, u8 rxseq) bus->glomerr = 0; dhdsdio_rxfail(bus, true, false); dhd_os_sdlock_rxq(bus->dhd); - PKTFREE(osh, bus->glom, false); + pkt_buf_free_skb(osh, bus->glom, false); dhd_os_sdunlock_rxq(bus->dhd); bus->rxglomfail++; bus->glom = NULL; @@ -3528,7 +3528,7 @@ static u8 dhdsdio_rxglom(dhd_bus_t *bus, u8 rxseq) skb_pull(pfirst, doff); if (pfirst->len == 0) { - PKTFREE(bus->dhd->osh, pfirst, false); + pkt_buf_free_skb(bus->dhd->osh, pfirst, false); if (plast) { plast->next = pnext; } else { @@ -3541,7 +3541,7 @@ static u8 dhdsdio_rxglom(dhd_bus_t *bus, u8 rxseq) DHD_ERROR(("%s: rx protocol error\n", __func__)); bus->dhd->rx_errors++; - PKTFREE(osh, pfirst, false); + pkt_buf_free_skb(osh, pfirst, false); if (plast) { plast->next = pnext; } else { @@ -3753,7 +3753,7 @@ static uint dhdsdio_readframes(dhd_bus_t *bus, uint maxframes, bool *finished) if (sdret < 0) { DHD_ERROR(("%s (nextlen): read %d bytes failed: %d\n", __func__, rdlen, sdret)); - PKTFREE(bus->dhd->osh, pkt, false); + pkt_buf_free_skb(bus->dhd->osh, pkt, false); bus->dhd->rx_errors++; dhd_os_sdunlock_rxq(bus->dhd); /* Force retry w/normal header read. @@ -3901,7 +3901,7 @@ static uint dhdsdio_readframes(dhd_bus_t *bus, uint maxframes, bool *finished) doff); if (bus->usebufpool) { dhd_os_sdlock_rxq(bus->dhd); - PKTFREE(bus->dhd->osh, pkt, + pkt_buf_free_skb(bus->dhd->osh, pkt, false); dhd_os_sdunlock_rxq(bus->dhd); } @@ -4127,7 +4127,7 @@ static uint dhdsdio_readframes(dhd_bus_t *bus, uint maxframes, bool *finished) ? "data" : "test")), sdret)); dhd_os_sdlock_rxq(bus->dhd); - PKTFREE(bus->dhd->osh, pkt, false); + pkt_buf_free_skb(bus->dhd->osh, pkt, false); dhd_os_sdunlock_rxq(bus->dhd); bus->dhd->rx_errors++; dhdsdio_rxfail(bus, true, RETRYCHAN(chan)); @@ -4180,13 +4180,13 @@ deliver: if (pkt->len == 0) { dhd_os_sdlock_rxq(bus->dhd); - PKTFREE(bus->dhd->osh, pkt, false); + pkt_buf_free_skb(bus->dhd->osh, pkt, false); dhd_os_sdunlock_rxq(bus->dhd); continue; } else if (dhd_prot_hdrpull(bus->dhd, &ifidx, pkt) != 0) { DHD_ERROR(("%s: rx protocol error\n", __func__)); dhd_os_sdlock_rxq(bus->dhd); - PKTFREE(bus->dhd->osh, pkt, false); + pkt_buf_free_skb(bus->dhd->osh, pkt, false); dhd_os_sdunlock_rxq(bus->dhd); bus->dhd->rx_errors++; continue; @@ -4694,7 +4694,7 @@ static void dhdsdio_pktgen(dhd_bus_t *bus) default: DHD_ERROR(("Unrecognized pktgen mode %d\n", bus->pktgen_mode)); - PKTFREE(osh, pkt, true); + pkt_buf_free_skb(osh, pkt, true); bus->pktgen_count = 0; return; } @@ -4779,7 +4779,7 @@ static void dhdsdio_testrcv(dhd_bus_t *bus, struct sk_buff *pkt, uint seq) if (pktlen < SDPCM_TEST_HDRLEN) { DHD_ERROR(("dhdsdio_restrcv: toss runt frame, pktlen %d\n", pktlen)); - PKTFREE(osh, pkt, false); + pkt_buf_free_skb(osh, pkt, false); return; } @@ -4797,7 +4797,7 @@ static void dhdsdio_testrcv(dhd_bus_t *bus, struct sk_buff *pkt, uint seq) DHD_ERROR(("dhdsdio_testrcv: frame length mismatch, " "pktlen %d seq %d" " cmd %d extra %d len %d\n", pktlen, seq, cmd, extra, len)); - PKTFREE(osh, pkt, false); + pkt_buf_free_skb(osh, pkt, false); return; } } @@ -4812,14 +4812,14 @@ static void dhdsdio_testrcv(dhd_bus_t *bus, struct sk_buff *pkt, uint seq) bus->pktgen_sent++; } else { bus->pktgen_fail++; - PKTFREE(osh, pkt, false); + pkt_buf_free_skb(osh, pkt, false); } bus->pktgen_rcvd++; break; case SDPCM_TEST_ECHORSP: if (bus->ext_loop) { - PKTFREE(osh, pkt, false); + pkt_buf_free_skb(osh, pkt, false); bus->pktgen_rcvd++; break; } @@ -4832,12 +4832,12 @@ static void dhdsdio_testrcv(dhd_bus_t *bus, struct sk_buff *pkt, uint seq) break; } } - PKTFREE(osh, pkt, false); + pkt_buf_free_skb(osh, pkt, false); bus->pktgen_rcvd++; break; case SDPCM_TEST_DISCARD: - PKTFREE(osh, pkt, false); + pkt_buf_free_skb(osh, pkt, false); bus->pktgen_rcvd++; break; @@ -4847,7 +4847,7 @@ static void dhdsdio_testrcv(dhd_bus_t *bus, struct sk_buff *pkt, uint seq) DHD_INFO(("dhdsdio_testrcv: unsupported or unknown command, " "pktlen %d seq %d" " cmd %d extra %d len %d\n", pktlen, seq, cmd, extra, len)); - PKTFREE(osh, pkt, false); + pkt_buf_free_skb(osh, pkt, false); break; } diff --git a/drivers/staging/brcm80211/include/osl.h b/drivers/staging/brcm80211/include/osl.h index 4d5893a70dd2..b28235618d8b 100644 --- a/drivers/staging/brcm80211/include/osl.h +++ b/drivers/staging/brcm80211/include/osl.h @@ -208,9 +208,7 @@ extern void osl_dma_unmap(struct osl_info *osh, uint pa, uint size, #define bcopy(src, dst, len) memcpy((dst), (src), (len)) /* packet primitives */ -#define PKTFREE(osh, skb, send) osl_pktfree((osh), (skb), (send)) - extern struct sk_buff *pkt_buf_get_skb(struct osl_info *osh, uint len); -extern void osl_pktfree(struct osl_info *osh, void *skb, bool send); +extern void pkt_buf_free_skb(struct osl_info *osh, struct sk_buff *skb, bool send); #endif /* _osl_h_ */ diff --git a/drivers/staging/brcm80211/sys/wlc_bmac.c b/drivers/staging/brcm80211/sys/wlc_bmac.c index 2abee6f527f9..59bfeb063650 100644 --- a/drivers/staging/brcm80211/sys/wlc_bmac.c +++ b/drivers/staging/brcm80211/sys/wlc_bmac.c @@ -3336,7 +3336,7 @@ static bool wlc_bmac_txstatus_corerev4(wlc_hw_info_t *wlc_hw) fatal = wlc_bmac_dotxstatus(wlc_hw, txs, 0); - PKTFREE(osh, status_p, false); + pkt_buf_free_skb(osh, status_p, false); } if (fatal) diff --git a/drivers/staging/brcm80211/sys/wlc_mac80211.c b/drivers/staging/brcm80211/sys/wlc_mac80211.c index 3e31f893fcc3..d3246b754c41 100644 --- a/drivers/staging/brcm80211/sys/wlc_mac80211.c +++ b/drivers/staging/brcm80211/sys/wlc_mac80211.c @@ -5052,7 +5052,7 @@ wlc_prec_enq_head(struct wlc_info *wlc, struct pktq *q, struct sk_buff *pkt, } ASSERT(0); - PKTFREE(wlc->osh, p, true); + pkt_buf_free_skb(wlc->osh, p, true); WLCNTINCR(wlc->pub->_cnt->txnobuf); } @@ -5085,7 +5085,7 @@ void BCMFASTPATH wlc_txq_enq(void *ctx, struct scb *scb, struct sk_buff *sdu, wlc->pub->unit)); /* ASSERT(9 == 8); *//* XXX we might hit this condtion in case packet flooding from mac80211 stack */ - PKTFREE(wlc->osh, sdu, true); + pkt_buf_free_skb(wlc->osh, sdu, true); WLCNTINCR(wlc->pub->_cnt->txnobuf); } @@ -6671,7 +6671,7 @@ wlc_dotxstatus(struct wlc_info *wlc, tx_status_t *txs, u32 frm_tx2) fatal: ASSERT(0); if (p) - PKTFREE(osh, p, true); + pkt_buf_free_skb(osh, p, true); return true; @@ -7056,7 +7056,7 @@ void BCMFASTPATH wlc_recv(struct wlc_info *wlc, struct sk_buff *p) return; toss: - PKTFREE(osh, p, false); + pkt_buf_free_skb(osh, p, false); } /* calculate frame duration for Mixed-mode L-SIG spoofing, return diff --git a/drivers/staging/brcm80211/util/bcmutils.c b/drivers/staging/brcm80211/util/bcmutils.c index 9c4d46764aca..fd30cc6fb7f8 100644 --- a/drivers/staging/brcm80211/util/bcmutils.c +++ b/drivers/staging/brcm80211/util/bcmutils.c @@ -198,7 +198,7 @@ void pktq_pflush(struct osl_info *osh, struct pktq *pq, int prec, bool dir) while (p) { q->head = p->prev; p->prev = NULL; - PKTFREE(osh, p, dir); + pkt_buf_free_skb(osh, p, dir); q->len--; pq->len--; p = q->head; @@ -232,7 +232,7 @@ pktq_pflush(struct osl_info *osh, struct pktq *pq, int prec, bool dir, else prev->prev = p->prev; p->prev = NULL; - PKTFREE(osh, p, dir); + pkt_buf_free_skb(osh, p, dir); q->len--; pq->len--; p = (head ? q->head : prev->prev); diff --git a/drivers/staging/brcm80211/util/hnddma.c b/drivers/staging/brcm80211/util/hnddma.c index a7805a88b5fe..cf9e469af988 100644 --- a/drivers/staging/brcm80211/util/hnddma.c +++ b/drivers/staging/brcm80211/util/hnddma.c @@ -1046,7 +1046,7 @@ static void *BCMFASTPATH _dma_rx(dma_info_t *di) if ((di->hnddma.dmactrlflags & DMA_CTRL_RXMULTI) == 0) { DMA_ERROR(("%s: dma_rx: bad frame length (%d)\n", di->name, len)); - PKTFREE(di->osh, head, false); + pkt_buf_free_skb(di->osh, head, false); di->hnddma.rxgiants++; goto next_frame; } @@ -1230,15 +1230,10 @@ static void _dma_rxreclaim(dma_info_t *di) { void *p; - /* "unused local" warning suppression for OSLs that - * define PKTFREE() without using the di->osh arg - */ - di = di; - DMA_TRACE(("%s: dma_rxreclaim\n", di->name)); while ((p = _dma_getnextrxp(di, true))) - PKTFREE(di->osh, p, false); + pkt_buf_free_skb(di->osh, p, false); } static void *BCMFASTPATH _dma_getnextrxp(dma_info_t *di, bool forceall) @@ -1501,7 +1496,7 @@ static void dma32_txreclaim(dma_info_t *di, txd_range_t range) return; while ((p = dma32_getnexttxp(di, range))) - PKTFREE(di->osh, p, true); + pkt_buf_free_skb(di->osh, p, true); } static bool dma32_txstopped(dma_info_t *di) @@ -1772,7 +1767,7 @@ static int dma32_txfast(dma_info_t *di, struct sk_buff *p0, bool commit) outoftxd: DMA_ERROR(("%s: dma_txfast: out of txds\n", di->name)); - PKTFREE(di->osh, p0, true); + pkt_buf_free_skb(di->osh, p0, true); di->hnddma.txavail = 0; di->hnddma.txnobuf++; return -1; @@ -2071,7 +2066,7 @@ static void BCMFASTPATH dma64_txreclaim(dma_info_t *di, txd_range_t range) while ((p = dma64_getnexttxp(di, range))) { /* For unframed data, we don't have any packets to free */ if (!(di->hnddma.dmactrlflags & DMA_CTRL_UNFRAMED)) - PKTFREE(di->osh, p, true); + pkt_buf_free_skb(di->osh, p, true); } } @@ -2422,7 +2417,7 @@ static int BCMFASTPATH dma64_txfast(dma_info_t *di, struct sk_buff *p0, outoftxd: DMA_ERROR(("%s: dma_txfast: out of txds !!!\n", di->name)); - PKTFREE(di->osh, p0, true); + pkt_buf_free_skb(di->osh, p0, true); di->hnddma.txavail = 0; di->hnddma.txnobuf++; return -1; diff --git a/drivers/staging/brcm80211/util/linux_osl.c b/drivers/staging/brcm80211/util/linux_osl.c index cd78edbcf43f..e6716e823baa 100644 --- a/drivers/staging/brcm80211/util/linux_osl.c +++ b/drivers/staging/brcm80211/util/linux_osl.c @@ -95,12 +95,11 @@ struct sk_buff *BCMFASTPATH pkt_buf_get_skb(struct osl_info *osh, uint len) } /* Free the driver packet. Free the tag if present */ -void BCMFASTPATH osl_pktfree(struct osl_info *osh, void *p, bool send) +void BCMFASTPATH pkt_buf_free_skb(struct osl_info *osh, struct sk_buff *skb, bool send) { - struct sk_buff *skb, *nskb; + struct sk_buff *nskb; int nest = 0; - skb = (struct sk_buff *)p; ASSERT(skb); /* perversion: we use skb->next to chain multi-skb packets */ -- cgit v1.2.3 From e304151f150104412c9a304dffd6dc5c160ea336 Mon Sep 17 00:00:00 2001 From: Roland Vossen Date: Mon, 6 Dec 2010 22:42:48 +0100 Subject: staging: brcm80211: replaced wlc_hw_info_t by struct wlc_hw_info Part of code cleanup effort. Signed-off-by: Roland Vossen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/sys/wlc_alloc.c | 6 +- drivers/staging/brcm80211/sys/wlc_antsel.c | 2 +- drivers/staging/brcm80211/sys/wlc_antsel.h | 2 +- drivers/staging/brcm80211/sys/wlc_bmac.c | 308 ++++++++++++++------------- drivers/staging/brcm80211/sys/wlc_bmac.h | 162 +++++++------- drivers/staging/brcm80211/sys/wlc_mac80211.h | 6 +- drivers/staging/brcm80211/sys/wlc_phy_shim.c | 4 +- drivers/staging/brcm80211/sys/wlc_types.h | 2 +- 8 files changed, 252 insertions(+), 240 deletions(-) diff --git a/drivers/staging/brcm80211/sys/wlc_alloc.c b/drivers/staging/brcm80211/sys/wlc_alloc.c index 980945a065fd..a568e978f6c6 100644 --- a/drivers/staging/brcm80211/sys/wlc_alloc.c +++ b/drivers/staging/brcm80211/sys/wlc_alloc.c @@ -187,10 +187,10 @@ struct wlc_info *wlc_attach_malloc(struct osl_info *osh, uint unit, uint *err, } wlc->pub->wlc = wlc; - /* allocate wlc_hw_info_t state structure */ + /* allocate struct wlc_hw_info state structure */ - wlc->hw = (wlc_hw_info_t *)wlc_calloc(osh, unit, - sizeof(wlc_hw_info_t)); + wlc->hw = (struct wlc_hw_info *)wlc_calloc(osh, unit, + sizeof(struct wlc_hw_info)); if (wlc->hw == NULL) { *err = 1005; goto fail; diff --git a/drivers/staging/brcm80211/sys/wlc_antsel.c b/drivers/staging/brcm80211/sys/wlc_antsel.c index ee577c8c80f5..9533b5687302 100644 --- a/drivers/staging/brcm80211/sys/wlc_antsel.c +++ b/drivers/staging/brcm80211/sys/wlc_antsel.c @@ -95,7 +95,7 @@ const u8 mimo_2x3_div_antselid_tbl[16] = { antsel_info_t *wlc_antsel_attach(struct wlc_info *wlc, struct osl_info *osh, wlc_pub_t *pub, - wlc_hw_info_t *wlc_hw) { + struct wlc_hw_info *wlc_hw) { antsel_info_t *asi; asi = kzalloc(sizeof(antsel_info_t), GFP_ATOMIC); diff --git a/drivers/staging/brcm80211/sys/wlc_antsel.h b/drivers/staging/brcm80211/sys/wlc_antsel.h index 30c66dda77ee..763986dd226e 100644 --- a/drivers/staging/brcm80211/sys/wlc_antsel.h +++ b/drivers/staging/brcm80211/sys/wlc_antsel.h @@ -19,7 +19,7 @@ extern antsel_info_t *wlc_antsel_attach(struct wlc_info *wlc, struct osl_info *osh, wlc_pub_t *pub, - wlc_hw_info_t *wlc_hw); + struct wlc_hw_info *wlc_hw); extern void wlc_antsel_detach(antsel_info_t *asi); extern void wlc_antsel_init(antsel_info_t *asi); extern void wlc_antsel_antcfg_get(antsel_info_t *asi, bool usedef, bool sel, diff --git a/drivers/staging/brcm80211/sys/wlc_bmac.c b/drivers/staging/brcm80211/sys/wlc_bmac.c index 59bfeb063650..4042d5e9d205 100644 --- a/drivers/staging/brcm80211/sys/wlc_bmac.c +++ b/drivers/staging/brcm80211/sys/wlc_bmac.c @@ -112,64 +112,65 @@ static u16 xmtfifo_sz[][NFIFO] = { {9, 58, 22, 14, 14, 5}, /* corerev 24: 2304, 14848, 5632, 3584, 3584, 1280 */ }; -static void wlc_clkctl_clk(wlc_hw_info_t *wlc, uint mode); +static void wlc_clkctl_clk(struct wlc_hw_info *wlc, uint mode); static void wlc_coreinit(struct wlc_info *wlc); /* used by wlc_wakeucode_init() */ -static void wlc_write_inits(wlc_hw_info_t *wlc_hw, const d11init_t *inits); -static void wlc_ucode_write(wlc_hw_info_t *wlc_hw, const u32 ucode[], +static void wlc_write_inits(struct wlc_hw_info *wlc_hw, const d11init_t *inits); +static void wlc_ucode_write(struct wlc_hw_info *wlc_hw, const u32 ucode[], const uint nbytes); -static void wlc_ucode_download(wlc_hw_info_t *wlc); -static void wlc_ucode_txant_set(wlc_hw_info_t *wlc_hw); +static void wlc_ucode_download(struct wlc_hw_info *wlc); +static void wlc_ucode_txant_set(struct wlc_hw_info *wlc_hw); /* used by wlc_dpc() */ -static bool wlc_bmac_dotxstatus(wlc_hw_info_t *wlc, tx_status_t *txs, +static bool wlc_bmac_dotxstatus(struct wlc_hw_info *wlc, tx_status_t *txs, u32 s2); -static bool wlc_bmac_txstatus_corerev4(wlc_hw_info_t *wlc); -static bool wlc_bmac_txstatus(wlc_hw_info_t *wlc, bool bound, bool *fatal); -static bool wlc_bmac_recv(wlc_hw_info_t *wlc_hw, uint fifo, bool bound); +static bool wlc_bmac_txstatus_corerev4(struct wlc_hw_info *wlc); +static bool wlc_bmac_txstatus(struct wlc_hw_info *wlc, bool bound, bool *fatal); +static bool wlc_bmac_recv(struct wlc_hw_info *wlc_hw, uint fifo, bool bound); /* used by wlc_down() */ static void wlc_flushqueues(struct wlc_info *wlc); -static void wlc_write_mhf(wlc_hw_info_t *wlc_hw, u16 *mhfs); -static void wlc_mctrl_reset(wlc_hw_info_t *wlc_hw); -static void wlc_corerev_fifofixup(wlc_hw_info_t *wlc_hw); +static void wlc_write_mhf(struct wlc_hw_info *wlc_hw, u16 *mhfs); +static void wlc_mctrl_reset(struct wlc_hw_info *wlc_hw); +static void wlc_corerev_fifofixup(struct wlc_hw_info *wlc_hw); /* Low Level Prototypes */ -static u16 wlc_bmac_read_objmem(wlc_hw_info_t *wlc_hw, uint offset, +static u16 wlc_bmac_read_objmem(struct wlc_hw_info *wlc_hw, uint offset, u32 sel); -static void wlc_bmac_write_objmem(wlc_hw_info_t *wlc_hw, uint offset, u16 v, - u32 sel); +static void wlc_bmac_write_objmem(struct wlc_hw_info *wlc_hw, uint offset, + u16 v, u32 sel); static bool wlc_bmac_attach_dmapio(struct wlc_info *wlc, uint j, bool wme); -static void wlc_bmac_detach_dmapio(wlc_hw_info_t *wlc_hw); -static void wlc_ucode_bsinit(wlc_hw_info_t *wlc_hw); -static bool wlc_validboardtype(wlc_hw_info_t *wlc); -static bool wlc_isgoodchip(wlc_hw_info_t *wlc_hw); -static char *wlc_get_macaddr(wlc_hw_info_t *wlc_hw); +static void wlc_bmac_detach_dmapio(struct wlc_hw_info *wlc_hw); +static void wlc_ucode_bsinit(struct wlc_hw_info *wlc_hw); +static bool wlc_validboardtype(struct wlc_hw_info *wlc); +static bool wlc_isgoodchip(struct wlc_hw_info *wlc_hw); +static char *wlc_get_macaddr(struct wlc_hw_info *wlc_hw); static void wlc_mhfdef(struct wlc_info *wlc, u16 *mhfs, u16 mhf2_init); -static void wlc_mctrl_write(wlc_hw_info_t *wlc_hw); -static void wlc_ucode_mute_override_set(wlc_hw_info_t *wlc_hw); -static void wlc_ucode_mute_override_clear(wlc_hw_info_t *wlc_hw); +static void wlc_mctrl_write(struct wlc_hw_info *wlc_hw); +static void wlc_ucode_mute_override_set(struct wlc_hw_info *wlc_hw); +static void wlc_ucode_mute_override_clear(struct wlc_hw_info *wlc_hw); static u32 wlc_wlintrsoff(struct wlc_info *wlc); static void wlc_wlintrsrestore(struct wlc_info *wlc, u32 macintmask); static void wlc_gpio_init(struct wlc_info *wlc); -static void wlc_write_hw_bcntemplate0(wlc_hw_info_t *wlc_hw, void *bcn, +static void wlc_write_hw_bcntemplate0(struct wlc_hw_info *wlc_hw, void *bcn, int len); -static void wlc_write_hw_bcntemplate1(wlc_hw_info_t *wlc_hw, void *bcn, +static void wlc_write_hw_bcntemplate1(struct wlc_hw_info *wlc_hw, void *bcn, int len); static void wlc_bmac_bsinit(struct wlc_info *wlc, chanspec_t chanspec); static u32 wlc_setband_inact(struct wlc_info *wlc, uint bandunit); -static void wlc_bmac_setband(wlc_hw_info_t *wlc_hw, uint bandunit, +static void wlc_bmac_setband(struct wlc_hw_info *wlc_hw, uint bandunit, chanspec_t chanspec); -static void wlc_bmac_update_slot_timing(wlc_hw_info_t *wlc_hw, bool shortslot); -static void wlc_upd_ofdm_pctl1_table(wlc_hw_info_t *wlc_hw); -static u16 wlc_bmac_ofdm_ratetable_offset(wlc_hw_info_t *wlc_hw, +static void wlc_bmac_update_slot_timing(struct wlc_hw_info *wlc_hw, + bool shortslot); +static void wlc_upd_ofdm_pctl1_table(struct wlc_hw_info *wlc_hw); +static u16 wlc_bmac_ofdm_ratetable_offset(struct wlc_hw_info *wlc_hw, u8 rate); /* === Low Level functions === */ -void wlc_bmac_set_shortslot(wlc_hw_info_t *wlc_hw, bool shortslot) +void wlc_bmac_set_shortslot(struct wlc_hw_info *wlc_hw, bool shortslot) { wlc_hw->shortslot = shortslot; @@ -185,7 +186,8 @@ void wlc_bmac_set_shortslot(wlc_hw_info_t *wlc_hw, bool shortslot) * or shortslot 11g (9us slots) * The PSM needs to be suspended for this call. */ -static void wlc_bmac_update_slot_timing(wlc_hw_info_t *wlc_hw, bool shortslot) +static void wlc_bmac_update_slot_timing(struct wlc_hw_info *wlc_hw, + bool shortslot) { struct osl_info *osh; d11regs_t *regs; @@ -204,7 +206,7 @@ static void wlc_bmac_update_slot_timing(wlc_hw_info_t *wlc_hw, bool shortslot) } } -static void WLBANDINITFN(wlc_ucode_bsinit) (wlc_hw_info_t *wlc_hw) +static void WLBANDINITFN(wlc_ucode_bsinit) (struct wlc_hw_info *wlc_hw) { /* init microcode host flags */ wlc_write_mhf(wlc_hw, wlc_hw->band->mhfs); @@ -233,7 +235,7 @@ static void WLBANDINITFN(wlc_ucode_bsinit) (wlc_hw_info_t *wlc_hw) /* switch to new band but leave it inactive */ static u32 WLBANDINITFN(wlc_setband_inact) (struct wlc_info *wlc, uint bandunit) { - wlc_hw_info_t *wlc_hw = wlc->hw; + struct wlc_hw_info *wlc_hw = wlc->hw; u32 macintmask; u32 tmp; @@ -268,7 +270,7 @@ static u32 WLBANDINITFN(wlc_setband_inact) (struct wlc_info *wlc, uint bandunit) * Param 'bound' indicates max. # frames to process before break out. */ static bool BCMFASTPATH -wlc_bmac_recv(wlc_hw_info_t *wlc_hw, uint fifo, bool bound) +wlc_bmac_recv(struct wlc_hw_info *wlc_hw, uint fifo, bool bound) { struct sk_buff *p; struct sk_buff *head = NULL; @@ -325,7 +327,7 @@ wlc_bmac_recv(wlc_hw_info_t *wlc_hw, uint fifo, bool bound) bool BCMFASTPATH wlc_dpc(struct wlc_info *wlc, bool bounded) { u32 macintstatus; - wlc_hw_info_t *wlc_hw = wlc->hw; + struct wlc_hw_info *wlc_hw = wlc->hw; d11regs_t *regs = wlc_hw->regs; bool fatal = false; @@ -452,7 +454,7 @@ bool BCMFASTPATH wlc_dpc(struct wlc_info *wlc, bool bounded) void wlc_bmac_watchdog(void *arg) { struct wlc_info *wlc = (struct wlc_info *) arg; - wlc_hw_info_t *wlc_hw = wlc->hw; + struct wlc_hw_info *wlc_hw = wlc->hw; WL_TRACE(("wl%d: wlc_bmac_watchdog\n", wlc_hw->unit)); @@ -475,8 +477,8 @@ void wlc_bmac_watchdog(void *arg) } void -wlc_bmac_set_chanspec(wlc_hw_info_t *wlc_hw, chanspec_t chanspec, bool mute, - struct txpwr_limits *txpwr) +wlc_bmac_set_chanspec(struct wlc_hw_info *wlc_hw, chanspec_t chanspec, + bool mute, struct txpwr_limits *txpwr) { uint bandunit; @@ -519,7 +521,8 @@ wlc_bmac_set_chanspec(wlc_hw_info_t *wlc_hw, chanspec_t chanspec, bool mute, } } -int wlc_bmac_revinfo_get(wlc_hw_info_t *wlc_hw, wlc_bmac_revinfo_t *revinfo) +int wlc_bmac_revinfo_get(struct wlc_hw_info *wlc_hw, + wlc_bmac_revinfo_t *revinfo) { si_t *sih = wlc_hw->sih; uint idx; @@ -557,7 +560,7 @@ int wlc_bmac_revinfo_get(wlc_hw_info_t *wlc_hw, wlc_bmac_revinfo_t *revinfo) return 0; } -int wlc_bmac_state_get(wlc_hw_info_t *wlc_hw, wlc_bmac_state_t *state) +int wlc_bmac_state_get(struct wlc_hw_info *wlc_hw, wlc_bmac_state_t *state) { state->machwcap = wlc_hw->machwcap; @@ -570,7 +573,7 @@ static bool wlc_bmac_attach_dmapio(struct wlc_info *wlc, uint j, bool wme) char name[8]; /* ucode host flag 2 needed for pio mode, independent of band and fifo */ u16 pio_mhf2 = 0; - wlc_hw_info_t *wlc_hw = wlc->hw; + struct wlc_hw_info *wlc_hw = wlc->hw; uint unit = wlc_hw->unit; wlc_tunables_t *tune = wlc->pub->tunables; @@ -682,7 +685,7 @@ static bool wlc_bmac_attach_dmapio(struct wlc_info *wlc, uint j, bool wme) return true; } -static void wlc_bmac_detach_dmapio(wlc_hw_info_t *wlc_hw) +static void wlc_bmac_detach_dmapio(struct wlc_hw_info *wlc_hw) { uint j; @@ -704,7 +707,7 @@ int wlc_bmac_attach(struct wlc_info *wlc, u16 vendor, u16 device, uint unit, bool piomode, struct osl_info *osh, void *regsva, uint bustype, void *btparam) { - wlc_hw_info_t *wlc_hw; + struct wlc_hw_info *wlc_hw; d11regs_t *regs; char *macaddr = NULL; char *vars; @@ -727,7 +730,7 @@ int wlc_bmac_attach(struct wlc_info *wlc, u16 vendor, u16 device, uint unit, wlc_hw->band = wlc_hw->bandstate[0]; wlc_hw->_piomode = piomode; - /* populate wlc_hw_info_t with default values */ + /* populate struct wlc_hw_info with default values */ wlc_bmac_info_init(wlc_hw); /* @@ -1043,7 +1046,7 @@ int wlc_bmac_attach(struct wlc_info *wlc, u16 vendor, u16 device, uint unit, * may get overrides later in this function * BMAC_NOTES, move low out and resolve the dangling ones */ -void wlc_bmac_info_init(wlc_hw_info_t *wlc_hw) +void wlc_bmac_info_init(struct wlc_hw_info *wlc_hw) { struct wlc_info *wlc = wlc_hw->wlc; @@ -1069,7 +1072,7 @@ int wlc_bmac_detach(struct wlc_info *wlc) { uint i; wlc_hwband_t *band; - wlc_hw_info_t *wlc_hw = wlc->hw; + struct wlc_hw_info *wlc_hw = wlc->hw; int callbacks; callbacks = 0; @@ -1116,7 +1119,7 @@ int wlc_bmac_detach(struct wlc_info *wlc) } -void wlc_bmac_reset(wlc_hw_info_t *wlc_hw) +void wlc_bmac_reset(struct wlc_hw_info *wlc_hw) { WL_TRACE(("wl%d: wlc_bmac_reset\n", wlc_hw->unit)); @@ -1133,7 +1136,7 @@ void wlc_bmac_reset(wlc_hw_info_t *wlc_hw) } void -wlc_bmac_init(wlc_hw_info_t *wlc_hw, chanspec_t chanspec, +wlc_bmac_init(struct wlc_hw_info *wlc_hw, chanspec_t chanspec, bool mute) { u32 macintmask; bool fastclk; @@ -1184,7 +1187,7 @@ wlc_bmac_init(wlc_hw_info_t *wlc_hw, chanspec_t chanspec, wlc_clkctl_clk(wlc_hw, CLK_DYNAMIC); } -int wlc_bmac_up_prep(wlc_hw_info_t *wlc_hw) +int wlc_bmac_up_prep(struct wlc_hw_info *wlc_hw) { uint coremask; @@ -1232,7 +1235,7 @@ int wlc_bmac_up_prep(wlc_hw_info_t *wlc_hw) return 0; } -int wlc_bmac_up_finish(wlc_hw_info_t *wlc_hw) +int wlc_bmac_up_finish(struct wlc_hw_info *wlc_hw) { WL_TRACE(("wl%d: %s:\n", wlc_hw->unit, __func__)); @@ -1246,7 +1249,7 @@ int wlc_bmac_up_finish(wlc_hw_info_t *wlc_hw) return 0; } -int wlc_bmac_down_prep(wlc_hw_info_t *wlc_hw) +int wlc_bmac_down_prep(struct wlc_hw_info *wlc_hw) { bool dev_gone; uint callbacks = 0; @@ -1274,7 +1277,7 @@ int wlc_bmac_down_prep(wlc_hw_info_t *wlc_hw) return callbacks; } -int wlc_bmac_down_finish(wlc_hw_info_t *wlc_hw) +int wlc_bmac_down_finish(struct wlc_hw_info *wlc_hw) { uint callbacks = 0; bool dev_gone; @@ -1318,7 +1321,7 @@ int wlc_bmac_down_finish(wlc_hw_info_t *wlc_hw) return callbacks; } -void wlc_bmac_wait_for_wake(wlc_hw_info_t *wlc_hw) +void wlc_bmac_wait_for_wake(struct wlc_hw_info *wlc_hw) { if (D11REV_IS(wlc_hw->corerev, 4)) /* no slowclock */ udelay(5); @@ -1334,29 +1337,30 @@ void wlc_bmac_wait_for_wake(wlc_hw_info_t *wlc_hw) ASSERT(wlc_bmac_read_shm(wlc_hw, M_UCODE_DBGST) != DBGST_ASLEEP); } -void wlc_bmac_hw_etheraddr(wlc_hw_info_t *wlc_hw, struct ether_addr *ea) +void wlc_bmac_hw_etheraddr(struct wlc_hw_info *wlc_hw, struct ether_addr *ea) { bcopy(&wlc_hw->etheraddr, ea, ETHER_ADDR_LEN); } -void wlc_bmac_set_hw_etheraddr(wlc_hw_info_t *wlc_hw, struct ether_addr *ea) +void wlc_bmac_set_hw_etheraddr(struct wlc_hw_info *wlc_hw, + struct ether_addr *ea) { bcopy(ea, &wlc_hw->etheraddr, ETHER_ADDR_LEN); } -int wlc_bmac_bandtype(wlc_hw_info_t *wlc_hw) +int wlc_bmac_bandtype(struct wlc_hw_info *wlc_hw) { return wlc_hw->band->bandtype; } void *wlc_cur_phy(struct wlc_info *wlc) { - wlc_hw_info_t *wlc_hw = wlc->hw; + struct wlc_hw_info *wlc_hw = wlc->hw; return (void *)wlc_hw->band->pi; } /* control chip clock to save power, enable dynamic clock or force fast clock */ -static void wlc_clkctl_clk(wlc_hw_info_t *wlc_hw, uint mode) +static void wlc_clkctl_clk(struct wlc_hw_info *wlc_hw, uint mode) { if (PMUCTL_ENAB(wlc_hw->sih)) { /* new chips with PMU, CCS_FORCEHT will distribute the HT clock on backplane, @@ -1455,7 +1459,7 @@ static void wlc_clkctl_clk(wlc_hw_info_t *wlc_hw, uint mode) static void wlc_mhfdef(struct wlc_info *wlc, u16 *mhfs, u16 mhf2_init) { - wlc_hw_info_t *wlc_hw = wlc->hw; + struct wlc_hw_info *wlc_hw = wlc->hw; memset(mhfs, 0, MHFMAX * sizeof(u16)); @@ -1483,7 +1487,7 @@ wlc_mhfdef(struct wlc_info *wlc, u16 *mhfs, u16 mhf2_init) * WLC_BAND_ALL <--- All bands */ void -wlc_bmac_mhf(wlc_hw_info_t *wlc_hw, u8 idx, u16 mask, u16 val, +wlc_bmac_mhf(struct wlc_hw_info *wlc_hw, u8 idx, u16 mask, u16 val, int bands) { u16 save; @@ -1537,7 +1541,7 @@ wlc_bmac_mhf(wlc_hw_info_t *wlc_hw, u8 idx, u16 mask, u16 val, } } -u16 wlc_bmac_mhf_get(wlc_hw_info_t *wlc_hw, u8 idx, int bands) +u16 wlc_bmac_mhf_get(struct wlc_hw_info *wlc_hw, u8 idx, int bands) { wlc_hwband_t *band; ASSERT(idx < MHFMAX); @@ -1563,7 +1567,7 @@ u16 wlc_bmac_mhf_get(wlc_hw_info_t *wlc_hw, u8 idx, int bands) return band->mhfs[idx]; } -static void wlc_write_mhf(wlc_hw_info_t *wlc_hw, u16 *mhfs) +static void wlc_write_mhf(struct wlc_hw_info *wlc_hw, u16 *mhfs) { u8 idx; u16 addr[] = { @@ -1581,7 +1585,7 @@ static void wlc_write_mhf(wlc_hw_info_t *wlc_hw, u16 *mhfs) /* set the maccontrol register to desired reset state and * initialize the sw cache of the register */ -static void wlc_mctrl_reset(wlc_hw_info_t *wlc_hw) +static void wlc_mctrl_reset(struct wlc_hw_info *wlc_hw) { /* IHR accesses are always enabled, PSM disabled, HPS off and WAKE on */ wlc_hw->maccontrol = 0; @@ -1592,7 +1596,7 @@ static void wlc_mctrl_reset(wlc_hw_info_t *wlc_hw) } /* set or clear maccontrol bits */ -void wlc_bmac_mctrl(wlc_hw_info_t *wlc_hw, u32 mask, u32 val) +void wlc_bmac_mctrl(struct wlc_hw_info *wlc_hw, u32 mask, u32 val) { u32 maccontrol; u32 new_maccontrol; @@ -1614,7 +1618,7 @@ void wlc_bmac_mctrl(wlc_hw_info_t *wlc_hw, u32 mask, u32 val) } /* write the software state of maccontrol and overrides to the maccontrol register */ -static void wlc_mctrl_write(wlc_hw_info_t *wlc_hw) +static void wlc_mctrl_write(struct wlc_hw_info *wlc_hw) { u32 maccontrol = wlc_hw->maccontrol; @@ -1631,7 +1635,7 @@ static void wlc_mctrl_write(wlc_hw_info_t *wlc_hw) W_REG(wlc_hw->osh, &wlc_hw->regs->maccontrol, maccontrol); } -void wlc_ucode_wake_override_set(wlc_hw_info_t *wlc_hw, u32 override_bit) +void wlc_ucode_wake_override_set(struct wlc_hw_info *wlc_hw, u32 override_bit) { ASSERT((wlc_hw->wake_override & override_bit) == 0); @@ -1648,7 +1652,7 @@ void wlc_ucode_wake_override_set(wlc_hw_info_t *wlc_hw, u32 override_bit) return; } -void wlc_ucode_wake_override_clear(wlc_hw_info_t *wlc_hw, u32 override_bit) +void wlc_ucode_wake_override_clear(struct wlc_hw_info *wlc_hw, u32 override_bit) { ASSERT(wlc_hw->wake_override & override_bit); @@ -1669,7 +1673,7 @@ void wlc_ucode_wake_override_clear(wlc_hw_info_t *wlc_hw, u32 override_bit) * STA 0 1 <--- This will ensure no beacons * IBSS 0 0 */ -static void wlc_ucode_mute_override_set(wlc_hw_info_t *wlc_hw) +static void wlc_ucode_mute_override_set(struct wlc_hw_info *wlc_hw) { wlc_hw->mute_override = 1; @@ -1685,7 +1689,7 @@ static void wlc_ucode_mute_override_set(wlc_hw_info_t *wlc_hw) } /* Clear the override on AP and INFRA bits */ -static void wlc_ucode_mute_override_clear(wlc_hw_info_t *wlc_hw) +static void wlc_ucode_mute_override_clear(struct wlc_hw_info *wlc_hw) { if (wlc_hw->mute_override == 0) return; @@ -1705,7 +1709,7 @@ static void wlc_ucode_mute_override_clear(wlc_hw_info_t *wlc_hw) * Write a MAC address to the rcmta structure */ void -wlc_bmac_set_rcmta(wlc_hw_info_t *wlc_hw, int idx, +wlc_bmac_set_rcmta(struct wlc_hw_info *wlc_hw, int idx, const struct ether_addr *addr) { d11regs_t *regs = wlc_hw->regs; @@ -1738,7 +1742,7 @@ wlc_bmac_set_rcmta(wlc_hw_info_t *wlc_hw, int idx, * Write a MAC address to the given match reg offset in the RXE match engine. */ void -wlc_bmac_set_addrmatch(wlc_hw_info_t *wlc_hw, int match_reg_offset, +wlc_bmac_set_addrmatch(struct wlc_hw_info *wlc_hw, int match_reg_offset, const struct ether_addr *addr) { d11regs_t *regs; @@ -1767,7 +1771,7 @@ wlc_bmac_set_addrmatch(wlc_hw_info_t *wlc_hw, int match_reg_offset, } void -wlc_bmac_write_template_ram(wlc_hw_info_t *wlc_hw, int offset, int len, +wlc_bmac_write_template_ram(struct wlc_hw_info *wlc_hw, int offset, int len, void *buf) { d11regs_t *regs; @@ -1810,7 +1814,7 @@ wlc_bmac_write_template_ram(wlc_hw_info_t *wlc_hw, int offset, int len, } } -void wlc_bmac_set_cwmin(wlc_hw_info_t *wlc_hw, u16 newmin) +void wlc_bmac_set_cwmin(struct wlc_hw_info *wlc_hw, u16 newmin) { struct osl_info *osh; @@ -1822,7 +1826,7 @@ void wlc_bmac_set_cwmin(wlc_hw_info_t *wlc_hw, u16 newmin) W_REG(osh, &wlc_hw->regs->objdata, newmin); } -void wlc_bmac_set_cwmax(wlc_hw_info_t *wlc_hw, u16 newmax) +void wlc_bmac_set_cwmax(struct wlc_hw_info *wlc_hw, u16 newmax) { struct osl_info *osh; @@ -1834,7 +1838,7 @@ void wlc_bmac_set_cwmax(wlc_hw_info_t *wlc_hw, u16 newmax) W_REG(osh, &wlc_hw->regs->objdata, newmax); } -void wlc_bmac_bw_set(wlc_hw_info_t *wlc_hw, u16 bw) +void wlc_bmac_bw_set(struct wlc_hw_info *wlc_hw, u16 bw) { bool fastclk; u32 tmp; @@ -1859,7 +1863,7 @@ void wlc_bmac_bw_set(wlc_hw_info_t *wlc_hw, u16 bw) } static void -wlc_write_hw_bcntemplate0(wlc_hw_info_t *wlc_hw, void *bcn, int len) +wlc_write_hw_bcntemplate0(struct wlc_hw_info *wlc_hw, void *bcn, int len) { d11regs_t *regs = wlc_hw->regs; @@ -1873,7 +1877,7 @@ wlc_write_hw_bcntemplate0(wlc_hw_info_t *wlc_hw, void *bcn, int len) } static void -wlc_write_hw_bcntemplate1(wlc_hw_info_t *wlc_hw, void *bcn, int len) +wlc_write_hw_bcntemplate1(struct wlc_hw_info *wlc_hw, void *bcn, int len) { d11regs_t *regs = wlc_hw->regs; @@ -1888,7 +1892,7 @@ wlc_write_hw_bcntemplate1(wlc_hw_info_t *wlc_hw, void *bcn, int len) /* mac is assumed to be suspended at this point */ void -wlc_bmac_write_hw_bcntemplates(wlc_hw_info_t *wlc_hw, void *bcn, int len, +wlc_bmac_write_hw_bcntemplates(struct wlc_hw_info *wlc_hw, void *bcn, int len, bool both) { d11regs_t *regs = wlc_hw->regs; @@ -1909,7 +1913,7 @@ wlc_bmac_write_hw_bcntemplates(wlc_hw_info_t *wlc_hw, void *bcn, int len, } } -static void WLBANDINITFN(wlc_bmac_upd_synthpu) (wlc_hw_info_t *wlc_hw) +static void WLBANDINITFN(wlc_bmac_upd_synthpu) (struct wlc_hw_info *wlc_hw) { u16 v; struct wlc_info *wlc = wlc_hw->wlc; @@ -1930,7 +1934,7 @@ static void WLBANDINITFN(wlc_bmac_upd_synthpu) (wlc_hw_info_t *wlc_hw) static void WLBANDINITFN(wlc_bmac_bsinit) (struct wlc_info *wlc, chanspec_t chanspec) { - wlc_hw_info_t *wlc_hw = wlc->hw; + struct wlc_hw_info *wlc_hw = wlc->hw; WL_TRACE(("wl%d: wlc_bmac_bsinit: bandunit %d\n", wlc_hw->unit, wlc_hw->band->bandunit)); @@ -1967,7 +1971,7 @@ WLBANDINITFN(wlc_bmac_bsinit) (struct wlc_info *wlc, chanspec_t chanspec) wlc_bmac_upd_synthpu(wlc_hw); } -void wlc_bmac_core_phy_clk(wlc_hw_info_t *wlc_hw, bool clk) +void wlc_bmac_core_phy_clk(struct wlc_hw_info *wlc_hw, bool clk) { WL_TRACE(("wl%d: wlc_bmac_core_phy_clk: clk %d\n", wlc_hw->unit, clk)); @@ -1992,7 +1996,7 @@ void wlc_bmac_core_phy_clk(wlc_hw_info_t *wlc_hw, bool clk) } /* Perform a soft reset of the PHY PLL */ -void wlc_bmac_core_phypll_reset(wlc_hw_info_t *wlc_hw) +void wlc_bmac_core_phypll_reset(struct wlc_hw_info *wlc_hw) { WL_TRACE(("wl%d: wlc_bmac_core_phypll_reset\n", wlc_hw->unit)); @@ -2013,7 +2017,7 @@ void wlc_bmac_core_phypll_reset(wlc_hw_info_t *wlc_hw) /* light way to turn on phy clock without reset for NPHY only * refer to wlc_bmac_core_phy_clk for full version */ -void wlc_bmac_phyclk_fgc(wlc_hw_info_t *wlc_hw, bool clk) +void wlc_bmac_phyclk_fgc(struct wlc_hw_info *wlc_hw, bool clk) { /* support(necessary for NPHY and HYPHY) only */ if (!WLCISNPHY(wlc_hw->band)) @@ -2026,7 +2030,7 @@ void wlc_bmac_phyclk_fgc(wlc_hw_info_t *wlc_hw, bool clk) } -void wlc_bmac_macphyclk_set(wlc_hw_info_t *wlc_hw, bool clk) +void wlc_bmac_macphyclk_set(struct wlc_hw_info *wlc_hw, bool clk) { if (ON == clk) si_core_cflags(wlc_hw->sih, SICF_MPCLKE, SICF_MPCLKE); @@ -2034,7 +2038,7 @@ void wlc_bmac_macphyclk_set(wlc_hw_info_t *wlc_hw, bool clk) si_core_cflags(wlc_hw->sih, SICF_MPCLKE, 0); } -void wlc_bmac_phy_reset(wlc_hw_info_t *wlc_hw) +void wlc_bmac_phy_reset(struct wlc_hw_info *wlc_hw) { wlc_phy_t *pih = wlc_hw->band->pi; u32 phy_bw_clkbits; @@ -2078,7 +2082,7 @@ void wlc_bmac_phy_reset(wlc_hw_info_t *wlc_hw) /* switch to and initialize new band */ static void -WLBANDINITFN(wlc_bmac_setband) (wlc_hw_info_t *wlc_hw, uint bandunit, +WLBANDINITFN(wlc_bmac_setband) (struct wlc_hw_info *wlc_hw, uint bandunit, chanspec_t chanspec) { struct wlc_info *wlc = wlc_hw->wlc; u32 macintmask; @@ -2120,7 +2124,7 @@ WLBANDINITFN(wlc_bmac_setband) (wlc_hw_info_t *wlc_hw, uint bandunit, } /* low-level band switch utility routine */ -void WLBANDINITFN(wlc_setxband) (wlc_hw_info_t *wlc_hw, uint bandunit) +void WLBANDINITFN(wlc_setxband) (struct wlc_hw_info *wlc_hw, uint bandunit) { WL_TRACE(("wl%d: wlc_setxband: bandunit %d\n", wlc_hw->unit, bandunit)); @@ -2136,7 +2140,7 @@ void WLBANDINITFN(wlc_setxband) (wlc_hw_info_t *wlc_hw, uint bandunit) } } -static bool wlc_isgoodchip(wlc_hw_info_t *wlc_hw) +static bool wlc_isgoodchip(struct wlc_hw_info *wlc_hw) { /* reject unsupported corerev */ @@ -2148,7 +2152,7 @@ static bool wlc_isgoodchip(wlc_hw_info_t *wlc_hw) return true; } -static bool wlc_validboardtype(wlc_hw_info_t *wlc_hw) +static bool wlc_validboardtype(struct wlc_hw_info *wlc_hw) { bool goodboard = true; uint boardrev = wlc_hw->boardrev; @@ -2172,7 +2176,7 @@ static bool wlc_validboardtype(wlc_hw_info_t *wlc_hw) return goodboard; } -static char *wlc_get_macaddr(wlc_hw_info_t *wlc_hw) +static char *wlc_get_macaddr(struct wlc_hw_info *wlc_hw) { const char *varname = "macaddr"; char *macaddr; @@ -2201,7 +2205,7 @@ static char *wlc_get_macaddr(wlc_hw_info_t *wlc_hw) * this function could be called when driver is down and w/o clock * it operates on different registers depending on corerev and boardflag. */ -bool wlc_bmac_radio_read_hwdisabled(wlc_hw_info_t *wlc_hw) +bool wlc_bmac_radio_read_hwdisabled(struct wlc_hw_info *wlc_hw) { bool v, clk, xtal; u32 resetbits = 0, flags = 0; @@ -2247,7 +2251,7 @@ bool wlc_bmac_radio_read_hwdisabled(wlc_hw_info_t *wlc_hw) } /* Initialize just the hardware when coming out of POR or S3/S5 system states */ -void wlc_bmac_hw_up(wlc_hw_info_t *wlc_hw) +void wlc_bmac_hw_up(struct wlc_hw_info *wlc_hw) { if (wlc_hw->wlc->pub->hw_up) return; @@ -2289,7 +2293,7 @@ void wlc_bmac_hw_up(wlc_hw_info_t *wlc_hw) } } -static bool wlc_dma_rxreset(wlc_hw_info_t *wlc_hw, uint fifo) +static bool wlc_dma_rxreset(struct wlc_hw_info *wlc_hw, uint fifo) { hnddma_t *di = wlc_hw->di[fifo]; struct osl_info *osh; @@ -2322,7 +2326,7 @@ static bool wlc_dma_rxreset(wlc_hw_info_t *wlc_hw, uint fifo) * clear software macintstatus for fresh new start * one testing hack wlc_hw->noreset will bypass the d11/phy reset */ -void wlc_bmac_corereset(wlc_hw_info_t *wlc_hw, u32 flags) +void wlc_bmac_corereset(struct wlc_hw_info *wlc_hw, u32 flags) { d11regs_t *regs; uint i; @@ -2411,7 +2415,7 @@ void wlc_bmac_corereset(wlc_hw_info_t *wlc_hw, u32 flags) * txfifo sizes needs to be modified(increased) since the newer cores * have more memory. */ -static void wlc_corerev_fifofixup(wlc_hw_info_t *wlc_hw) +static void wlc_corerev_fifofixup(struct wlc_hw_info *wlc_hw) { d11regs_t *regs = wlc_hw->regs; u16 fifo_nu; @@ -2473,7 +2477,7 @@ static void wlc_corerev_fifofixup(wlc_hw_info_t *wlc_hw) */ static void wlc_coreinit(struct wlc_info *wlc) { - wlc_hw_info_t *wlc_hw = wlc->hw; + struct wlc_hw_info *wlc_hw = wlc->hw; d11regs_t *regs; u32 sflags; uint bcnint_us; @@ -2682,7 +2686,7 @@ static void wlc_coreinit(struct wlc_info *wlc) * - 559241 = 0x88889 => tsf_clk_frac_h = 0x8, tsf_clk_frac_l = 0x8889 */ -void wlc_bmac_switch_macfreq(wlc_hw_info_t *wlc_hw, u8 spurmode) +void wlc_bmac_switch_macfreq(struct wlc_hw_info *wlc_hw, u8 spurmode) { d11regs_t *regs; struct osl_info *osh; @@ -2715,7 +2719,7 @@ void wlc_bmac_switch_macfreq(wlc_hw_info_t *wlc_hw, u8 spurmode) /* Initialize GPIOs that are controlled by D11 core */ static void wlc_gpio_init(struct wlc_info *wlc) { - wlc_hw_info_t *wlc_hw = wlc->hw; + struct wlc_hw_info *wlc_hw = wlc->hw; d11regs_t *regs; u32 gc, gm; struct osl_info *osh; @@ -2778,7 +2782,7 @@ static void wlc_gpio_init(struct wlc_info *wlc) si_gpiocontrol(wlc_hw->sih, gm, gc, GPIO_DRV_PRIORITY); } -static void wlc_ucode_download(wlc_hw_info_t *wlc_hw) +static void wlc_ucode_download(struct wlc_hw_info *wlc_hw) { struct wlc_info *wlc; wlc = wlc_hw->wlc; @@ -2806,7 +2810,7 @@ static void wlc_ucode_download(wlc_hw_info_t *wlc_hw) } } -static void wlc_ucode_write(wlc_hw_info_t *wlc_hw, const u32 ucode[], +static void wlc_ucode_write(struct wlc_hw_info *wlc_hw, const u32 ucode[], const uint nbytes) { struct osl_info *osh; d11regs_t *regs = wlc_hw->regs; @@ -2827,7 +2831,7 @@ static void wlc_ucode_write(wlc_hw_info_t *wlc_hw, const u32 ucode[], W_REG(osh, ®s->objdata, ucode[i]); } -static void wlc_write_inits(wlc_hw_info_t *wlc_hw, const d11init_t *inits) +static void wlc_write_inits(struct wlc_hw_info *wlc_hw, const d11init_t *inits) { int i; struct osl_info *osh; @@ -2850,7 +2854,7 @@ static void wlc_write_inits(wlc_hw_info_t *wlc_hw, const d11init_t *inits) } } -static void wlc_ucode_txant_set(wlc_hw_info_t *wlc_hw) +static void wlc_ucode_txant_set(struct wlc_hw_info *wlc_hw) { u16 phyctl; u16 phytxant = wlc_hw->bmac_phytxant; @@ -2867,7 +2871,7 @@ static void wlc_ucode_txant_set(wlc_hw_info_t *wlc_hw) wlc_bmac_write_shm(wlc_hw, M_RSP_PCTLWD, phyctl); } -void wlc_bmac_txant_set(wlc_hw_info_t *wlc_hw, u16 phytxant) +void wlc_bmac_txant_set(struct wlc_hw_info *wlc_hw, u16 phytxant) { /* update sw state */ wlc_hw->bmac_phytxant = phytxant; @@ -2879,12 +2883,12 @@ void wlc_bmac_txant_set(wlc_hw_info_t *wlc_hw, u16 phytxant) } -u16 wlc_bmac_get_txant(wlc_hw_info_t *wlc_hw) +u16 wlc_bmac_get_txant(struct wlc_hw_info *wlc_hw) { return (u16) wlc_hw->wlc->stf->txant; } -void wlc_bmac_antsel_type_set(wlc_hw_info_t *wlc_hw, u8 antsel_type) +void wlc_bmac_antsel_type_set(struct wlc_hw_info *wlc_hw, u8 antsel_type) { wlc_hw->antsel_type = antsel_type; @@ -2892,7 +2896,7 @@ void wlc_bmac_antsel_type_set(wlc_hw_info_t *wlc_hw, u8 antsel_type) wlc_phy_antsel_type_set(wlc_hw->band->pi, antsel_type); } -void wlc_bmac_fifoerrors(wlc_hw_info_t *wlc_hw) +void wlc_bmac_fifoerrors(struct wlc_hw_info *wlc_hw) { bool fatal = false; uint unit; @@ -2962,7 +2966,7 @@ void wlc_bmac_fifoerrors(wlc_hw_info_t *wlc_hw) void wlc_intrson(struct wlc_info *wlc) { - wlc_hw_info_t *wlc_hw = wlc->hw; + struct wlc_hw_info *wlc_hw = wlc->hw; ASSERT(wlc->defmacintmask); wlc->macintmask = wlc->defmacintmask; W_REG(wlc_hw->osh, &wlc_hw->regs->macintmask, wlc->macintmask); @@ -2991,7 +2995,7 @@ static void wlc_wlintrsrestore(struct wlc_info *wlc, u32 macintmask) u32 wlc_intrsoff(struct wlc_info *wlc) { - wlc_hw_info_t *wlc_hw = wlc->hw; + struct wlc_hw_info *wlc_hw = wlc->hw; u32 macintmask; if (!wlc_hw->clk) @@ -3010,7 +3014,7 @@ u32 wlc_intrsoff(struct wlc_info *wlc) void wlc_intrsrestore(struct wlc_info *wlc, u32 macintmask) { - wlc_hw_info_t *wlc_hw = wlc->hw; + struct wlc_hw_info *wlc_hw = wlc->hw; if (!wlc_hw->clk) return; @@ -3018,7 +3022,7 @@ void wlc_intrsrestore(struct wlc_info *wlc, u32 macintmask) W_REG(wlc_hw->osh, &wlc_hw->regs->macintmask, wlc->macintmask); } -void wlc_bmac_mute(wlc_hw_info_t *wlc_hw, bool on, mbool flags) +void wlc_bmac_mute(struct wlc_hw_info *wlc_hw, bool on, mbool flags) { struct ether_addr null_ether_addr = { {0, 0, 0, 0, 0, 0} }; @@ -3054,12 +3058,12 @@ void wlc_bmac_mute(wlc_hw_info_t *wlc_hw, bool on, mbool flags) wlc_ucode_mute_override_clear(wlc_hw); } -void wlc_bmac_set_deaf(wlc_hw_info_t *wlc_hw, bool user_flag) +void wlc_bmac_set_deaf(struct wlc_hw_info *wlc_hw, bool user_flag) { wlc_phy_set_deaf(wlc_hw->band->pi, user_flag); } -int wlc_bmac_xmtfifo_sz_get(wlc_hw_info_t *wlc_hw, uint fifo, uint *blocks) +int wlc_bmac_xmtfifo_sz_get(struct wlc_hw_info *wlc_hw, uint fifo, uint *blocks) { if (fifo >= NFIFO) return BCME_RANGE; @@ -3069,7 +3073,7 @@ int wlc_bmac_xmtfifo_sz_get(wlc_hw_info_t *wlc_hw, uint fifo, uint *blocks) return 0; } -int wlc_bmac_xmtfifo_sz_set(wlc_hw_info_t *wlc_hw, uint fifo, uint blocks) +int wlc_bmac_xmtfifo_sz_set(struct wlc_hw_info *wlc_hw, uint fifo, uint blocks) { if (fifo >= NFIFO || blocks > 299) return BCME_RANGE; @@ -3089,7 +3093,7 @@ int wlc_bmac_xmtfifo_sz_set(wlc_hw_info_t *wlc_hw, uint fifo, uint blocks) * be pulling data into a tx fifo, by the time the MAC acks the suspend * request. */ -bool wlc_bmac_tx_fifo_suspended(wlc_hw_info_t *wlc_hw, uint tx_fifo) +bool wlc_bmac_tx_fifo_suspended(struct wlc_hw_info *wlc_hw, uint tx_fifo) { /* check that a suspend has been requested and is no longer pending */ @@ -3108,7 +3112,7 @@ bool wlc_bmac_tx_fifo_suspended(wlc_hw_info_t *wlc_hw, uint tx_fifo) return false; } -void wlc_bmac_tx_fifo_suspend(wlc_hw_info_t *wlc_hw, uint tx_fifo) +void wlc_bmac_tx_fifo_suspend(struct wlc_hw_info *wlc_hw, uint tx_fifo) { u8 fifo = 1 << tx_fifo; @@ -3139,7 +3143,7 @@ void wlc_bmac_tx_fifo_suspend(wlc_hw_info_t *wlc_hw, uint tx_fifo) } } -void wlc_bmac_tx_fifo_resume(wlc_hw_info_t *wlc_hw, uint tx_fifo) +void wlc_bmac_tx_fifo_resume(struct wlc_hw_info *wlc_hw, uint tx_fifo) { /* BMAC_NOTE: WLC_TX_FIFO_ENAB is done in wlc_dpc() for DMA case but need to be done * here for PIO otherwise the watchdog will catch the inconsistency and fire @@ -3169,7 +3173,7 @@ void wlc_bmac_tx_fifo_resume(wlc_hw_info_t *wlc_hw, uint tx_fifo) */ static inline u32 wlc_intstatus(struct wlc_info *wlc, bool in_isr) { - wlc_hw_info_t *wlc_hw = wlc->hw; + struct wlc_hw_info *wlc_hw = wlc->hw; d11regs_t *regs = wlc_hw->regs; u32 macintstatus; u32 intstatus_rxfifo, intstatus_txsfifo; @@ -3284,7 +3288,7 @@ bool wlc_intrsupd(struct wlc_info *wlc) */ bool BCMFASTPATH wlc_isr(struct wlc_info *wlc, bool *wantdpc) { - wlc_hw_info_t *wlc_hw = wlc->hw; + struct wlc_hw_info *wlc_hw = wlc->hw; u32 macintstatus; *wantdpc = false; @@ -3313,7 +3317,7 @@ bool BCMFASTPATH wlc_isr(struct wlc_info *wlc, bool *wantdpc) } /* process tx completion events for corerev < 5 */ -static bool wlc_bmac_txstatus_corerev4(wlc_hw_info_t *wlc_hw) +static bool wlc_bmac_txstatus_corerev4(struct wlc_hw_info *wlc_hw) { struct sk_buff *status_p; tx_status_t *txs; @@ -3349,7 +3353,7 @@ static bool wlc_bmac_txstatus_corerev4(wlc_hw_info_t *wlc_hw) } static bool BCMFASTPATH -wlc_bmac_dotxstatus(wlc_hw_info_t *wlc_hw, tx_status_t *txs, u32 s2) +wlc_bmac_dotxstatus(struct wlc_hw_info *wlc_hw, tx_status_t *txs, u32 s2) { /* discard intermediate indications for ucode with one legitimate case: * e.g. if "useRTS" is set. ucode did a successful rts/cts exchange, but the subsequent @@ -3368,7 +3372,7 @@ wlc_bmac_dotxstatus(wlc_hw_info_t *wlc_hw, tx_status_t *txs, u32 s2) * Return true if more tx status need to be processed. false otherwise. */ static bool BCMFASTPATH -wlc_bmac_txstatus(wlc_hw_info_t *wlc_hw, bool bound, bool *fatal) +wlc_bmac_txstatus(struct wlc_hw_info *wlc_hw, bool bound, bool *fatal) { bool morepending = false; struct wlc_info *wlc = wlc_hw->wlc; @@ -3434,7 +3438,7 @@ wlc_bmac_txstatus(wlc_hw_info_t *wlc_hw, bool bound, bool *fatal) void wlc_suspend_mac_and_wait(struct wlc_info *wlc) { - wlc_hw_info_t *wlc_hw = wlc->hw; + struct wlc_hw_info *wlc_hw = wlc->hw; d11regs_t *regs = wlc_hw->regs; u32 mc, mi; struct osl_info *osh; @@ -3498,7 +3502,7 @@ void wlc_suspend_mac_and_wait(struct wlc_info *wlc) void wlc_enable_mac(struct wlc_info *wlc) { - wlc_hw_info_t *wlc_hw = wlc->hw; + struct wlc_hw_info *wlc_hw = wlc->hw; d11regs_t *regs = wlc_hw->regs; u32 mc, mi; struct osl_info *osh; @@ -3535,7 +3539,7 @@ void wlc_enable_mac(struct wlc_info *wlc) wlc_ucode_wake_override_clear(wlc_hw, WLC_WAKE_OVERRIDE_MACSUSPEND); } -void wlc_bmac_ifsctl_edcrs_set(wlc_hw_info_t *wlc_hw, bool abie, bool isht) +void wlc_bmac_ifsctl_edcrs_set(struct wlc_hw_info *wlc_hw, bool abie, bool isht) { if (!(WLCISNPHY(wlc_hw->band) && (D11REV_GE(wlc_hw->corerev, 16)))) return; @@ -3571,7 +3575,7 @@ void wlc_bmac_ifsctl_edcrs_set(wlc_hw_info_t *wlc_hw, bool abie, bool isht) } } -static void wlc_upd_ofdm_pctl1_table(wlc_hw_info_t *wlc_hw) +static void wlc_upd_ofdm_pctl1_table(struct wlc_hw_info *wlc_hw) { u8 rate; u8 rates[8] = { @@ -3605,7 +3609,7 @@ static void wlc_upd_ofdm_pctl1_table(wlc_hw_info_t *wlc_hw) } } -static u16 wlc_bmac_ofdm_ratetable_offset(wlc_hw_info_t *wlc_hw, u8 rate) +static u16 wlc_bmac_ofdm_ratetable_offset(struct wlc_hw_info *wlc_hw, u8 rate) { uint i; u8 plcp_rate = 0; @@ -3638,7 +3642,7 @@ static u16 wlc_bmac_ofdm_ratetable_offset(wlc_hw_info_t *wlc_hw, u8 rate) return 2 * wlc_bmac_read_shm(wlc_hw, M_RT_DIRMAP_A + (plcp_rate * 2)); } -void wlc_bmac_band_stf_ss_set(wlc_hw_info_t *wlc_hw, u8 stf_mode) +void wlc_bmac_band_stf_ss_set(struct wlc_hw_info *wlc_hw, u8 stf_mode) { wlc_hw->hw_stf_ss_opmode = stf_mode; @@ -3647,7 +3651,7 @@ void wlc_bmac_band_stf_ss_set(wlc_hw_info_t *wlc_hw, u8 stf_mode) } void BCMFASTPATH -wlc_bmac_read_tsf(wlc_hw_info_t *wlc_hw, u32 *tsf_l_ptr, +wlc_bmac_read_tsf(struct wlc_hw_info *wlc_hw, u32 *tsf_l_ptr, u32 *tsf_h_ptr) { d11regs_t *regs = wlc_hw->regs; @@ -3659,7 +3663,7 @@ wlc_bmac_read_tsf(wlc_hw_info_t *wlc_hw, u32 *tsf_l_ptr, return; } -bool wlc_bmac_validate_chip_access(wlc_hw_info_t *wlc_hw) +bool wlc_bmac_validate_chip_access(struct wlc_hw_info *wlc_hw) { d11regs_t *regs; u32 w, val; @@ -3754,7 +3758,7 @@ bool wlc_bmac_validate_chip_access(wlc_hw_info_t *wlc_hw) #define PHYPLL_WAIT_US 100000 -void wlc_bmac_core_phypll_ctl(wlc_hw_info_t *wlc_hw, bool on) +void wlc_bmac_core_phypll_ctl(struct wlc_hw_info *wlc_hw, bool on) { d11regs_t *regs; struct osl_info *osh; @@ -3813,7 +3817,7 @@ void wlc_bmac_core_phypll_ctl(wlc_hw_info_t *wlc_hw, bool on) } } -void wlc_coredisable(wlc_hw_info_t *wlc_hw) +void wlc_coredisable(struct wlc_hw_info *wlc_hw) { bool dev_gone; @@ -3853,7 +3857,7 @@ void wlc_coredisable(wlc_hw_info_t *wlc_hw) } /* power both the pll and external oscillator on/off */ -void wlc_bmac_xtal(wlc_hw_info_t *wlc_hw, bool want) +void wlc_bmac_xtal(struct wlc_hw_info *wlc_hw, bool want) { WL_TRACE(("wl%d: wlc_bmac_xtal: want %d\n", wlc_hw->unit, want)); @@ -3874,7 +3878,7 @@ void wlc_bmac_xtal(wlc_hw_info_t *wlc_hw, bool want) static void wlc_flushqueues(struct wlc_info *wlc) { - wlc_hw_info_t *wlc_hw = wlc->hw; + struct wlc_hw_info *wlc_hw = wlc->hw; uint i; wlc->txpend16165war = 0; @@ -3894,12 +3898,12 @@ static void wlc_flushqueues(struct wlc_info *wlc) dma_rxreclaim(wlc_hw->di[RX_TXSTATUS_FIFO]); } -u16 wlc_bmac_read_shm(wlc_hw_info_t *wlc_hw, uint offset) +u16 wlc_bmac_read_shm(struct wlc_hw_info *wlc_hw, uint offset) { return wlc_bmac_read_objmem(wlc_hw, offset, OBJADDR_SHM_SEL); } -void wlc_bmac_write_shm(wlc_hw_info_t *wlc_hw, uint offset, u16 v) +void wlc_bmac_write_shm(struct wlc_hw_info *wlc_hw, uint offset, u16 v) { wlc_bmac_write_objmem(wlc_hw, offset, v, OBJADDR_SHM_SEL); } @@ -3908,7 +3912,7 @@ void wlc_bmac_write_shm(wlc_hw_info_t *wlc_hw, uint offset, u16 v) * SHM 'offset' needs to be an even address and * Buffer length 'len' must be an even number of bytes */ -void wlc_bmac_set_shm(wlc_hw_info_t *wlc_hw, uint offset, u16 v, int len) +void wlc_bmac_set_shm(struct wlc_hw_info *wlc_hw, uint offset, u16 v, int len) { int i; @@ -3925,7 +3929,7 @@ void wlc_bmac_set_shm(wlc_hw_info_t *wlc_hw, uint offset, u16 v, int len) } static u16 -wlc_bmac_read_objmem(wlc_hw_info_t *wlc_hw, uint offset, u32 sel) +wlc_bmac_read_objmem(struct wlc_hw_info *wlc_hw, uint offset, u32 sel) { d11regs_t *regs = wlc_hw->regs; volatile u16 *objdata_lo = (volatile u16 *)®s->objdata; @@ -3946,7 +3950,7 @@ wlc_bmac_read_objmem(wlc_hw_info_t *wlc_hw, uint offset, u32 sel) } static void -wlc_bmac_write_objmem(wlc_hw_info_t *wlc_hw, uint offset, u16 v, u32 sel) +wlc_bmac_write_objmem(struct wlc_hw_info *wlc_hw, uint offset, u16 v, u32 sel) { d11regs_t *regs = wlc_hw->regs; volatile u16 *objdata_lo = (volatile u16 *)®s->objdata; @@ -3969,7 +3973,7 @@ wlc_bmac_write_objmem(wlc_hw_info_t *wlc_hw, uint offset, u16 v, u32 sel) * 'sel' selects the type of memory */ void -wlc_bmac_copyto_objmem(wlc_hw_info_t *wlc_hw, uint offset, const void *buf, +wlc_bmac_copyto_objmem(struct wlc_hw_info *wlc_hw, uint offset, const void *buf, int len, u32 sel) { u16 v; @@ -3995,7 +3999,7 @@ wlc_bmac_copyto_objmem(wlc_hw_info_t *wlc_hw, uint offset, const void *buf, * 'sel' selects the type of memory */ void -wlc_bmac_copyfrom_objmem(wlc_hw_info_t *wlc_hw, uint offset, void *buf, +wlc_bmac_copyfrom_objmem(struct wlc_hw_info *wlc_hw, uint offset, void *buf, int len, u32 sel) { u16 v; @@ -4016,7 +4020,7 @@ wlc_bmac_copyfrom_objmem(wlc_hw_info_t *wlc_hw, uint offset, void *buf, } } -void wlc_bmac_copyfrom_vars(wlc_hw_info_t *wlc_hw, char **buf, uint *len) +void wlc_bmac_copyfrom_vars(struct wlc_hw_info *wlc_hw, char **buf, uint *len) { WL_TRACE(("wlc_bmac_copyfrom_vars, nvram vars totlen=%d\n", wlc_hw->vars_size)); @@ -4025,7 +4029,7 @@ void wlc_bmac_copyfrom_vars(wlc_hw_info_t *wlc_hw, char **buf, uint *len) *len = wlc_hw->vars_size; } -void wlc_bmac_retrylimit_upd(wlc_hw_info_t *wlc_hw, u16 SRL, u16 LRL) +void wlc_bmac_retrylimit_upd(struct wlc_hw_info *wlc_hw, u16 SRL, u16 LRL) { wlc_hw->SRL = SRL; wlc_hw->LRL = LRL; @@ -4043,17 +4047,17 @@ void wlc_bmac_retrylimit_upd(wlc_hw_info_t *wlc_hw, u16 SRL, u16 LRL) } } -void wlc_bmac_set_noreset(wlc_hw_info_t *wlc_hw, bool noreset_flag) +void wlc_bmac_set_noreset(struct wlc_hw_info *wlc_hw, bool noreset_flag) { wlc_hw->noreset = noreset_flag; } -void wlc_bmac_set_ucode_loaded(wlc_hw_info_t *wlc_hw, bool ucode_loaded) +void wlc_bmac_set_ucode_loaded(struct wlc_hw_info *wlc_hw, bool ucode_loaded) { wlc_hw->ucode_loaded = ucode_loaded; } -void wlc_bmac_pllreq(wlc_hw_info_t *wlc_hw, bool set, mbool req_bit) +void wlc_bmac_pllreq(struct wlc_hw_info *wlc_hw, bool set, mbool req_bit) { ASSERT(req_bit); @@ -4084,7 +4088,7 @@ void wlc_bmac_pllreq(wlc_hw_info_t *wlc_hw, bool set, mbool req_bit) return; } -void wlc_bmac_set_clk(wlc_hw_info_t *wlc_hw, bool on) +void wlc_bmac_set_clk(struct wlc_hw_info *wlc_hw, bool on) { if (on) { /* power up pll and oscillator */ @@ -4106,7 +4110,7 @@ void wlc_bmac_set_clk(wlc_hw_info_t *wlc_hw, bool on) } /* this will be true for all ai chips */ -bool wlc_bmac_taclear(wlc_hw_info_t *wlc_hw, bool ta_ok) +bool wlc_bmac_taclear(struct wlc_hw_info *wlc_hw, bool ta_ok) { return true; } @@ -4114,7 +4118,7 @@ bool wlc_bmac_taclear(wlc_hw_info_t *wlc_hw, bool ta_ok) /* Lower down relevant GPIOs like LED when going down w/o * doing PCI config cycles or touching interrupts */ -void wlc_gpio_fast_deinit(wlc_hw_info_t *wlc_hw) +void wlc_gpio_fast_deinit(struct wlc_hw_info *wlc_hw) { if ((wlc_hw == NULL) || (wlc_hw->sih == NULL)) return; @@ -4132,7 +4136,7 @@ void wlc_gpio_fast_deinit(wlc_hw_info_t *wlc_hw) return; } -bool wlc_bmac_radio_hw(wlc_hw_info_t *wlc_hw, bool enable) +bool wlc_bmac_radio_hw(struct wlc_hw_info *wlc_hw, bool enable) { /* Do not access Phy registers if core is not up */ if (si_iscoreup(wlc_hw->sih) == false) @@ -4167,7 +4171,7 @@ bool wlc_bmac_radio_hw(wlc_hw_info_t *wlc_hw, bool enable) return true; } -u16 wlc_bmac_rate_shm_offset(wlc_hw_info_t *wlc_hw, u8 rate) +u16 wlc_bmac_rate_shm_offset(struct wlc_hw_info *wlc_hw, u8 rate) { u16 table_ptr; u8 phy_rate, index; @@ -4191,12 +4195,12 @@ u16 wlc_bmac_rate_shm_offset(wlc_hw_info_t *wlc_hw, u8 rate) return 2 * wlc_bmac_read_shm(wlc_hw, table_ptr + (index * 2)); } -void wlc_bmac_set_txpwr_percent(wlc_hw_info_t *wlc_hw, u8 val) +void wlc_bmac_set_txpwr_percent(struct wlc_hw_info *wlc_hw, u8 val) { wlc_phy_txpwr_percent_set(wlc_hw->band->pi, val); } -void wlc_bmac_antsel_set(wlc_hw_info_t *wlc_hw, u32 antsel_avail) +void wlc_bmac_antsel_set(struct wlc_hw_info *wlc_hw, u32 antsel_avail) { wlc_hw->antsel_avail = antsel_avail; } diff --git a/drivers/staging/brcm80211/sys/wlc_bmac.h b/drivers/staging/brcm80211/sys/wlc_bmac.h index 03ad275cfc58..98150aaff3a3 100644 --- a/drivers/staging/brcm80211/sys/wlc_bmac.h +++ b/drivers/staging/brcm80211/sys/wlc_bmac.h @@ -57,7 +57,8 @@ typedef struct wlc_bmac_revinfo { } band[MAXBANDS]; } wlc_bmac_revinfo_t; -/* dup state between BMAC(wlc_hw_info_t) and HIGH(struct wlc_info) driver */ +/* dup state between BMAC(struct wlc_hw_info) and HIGH(struct wlc_info) + driver */ typedef struct wlc_bmac_state { u32 machwcap; /* mac hw capibility */ u32 preamble_ovr; /* preamble override */ @@ -135,131 +136,138 @@ extern int wlc_bmac_attach(struct wlc_info *wlc, u16 vendor, u16 device, void *regsva, uint bustype, void *btparam); extern int wlc_bmac_detach(struct wlc_info *wlc); extern void wlc_bmac_watchdog(void *arg); -extern void wlc_bmac_info_init(wlc_hw_info_t *wlc_hw); +extern void wlc_bmac_info_init(struct wlc_hw_info *wlc_hw); /* up/down, reset, clk */ -extern void wlc_bmac_xtal(wlc_hw_info_t *wlc_hw, bool want); +extern void wlc_bmac_xtal(struct wlc_hw_info *wlc_hw, bool want); -extern void wlc_bmac_copyto_objmem(wlc_hw_info_t *wlc_hw, +extern void wlc_bmac_copyto_objmem(struct wlc_hw_info *wlc_hw, uint offset, const void *buf, int len, u32 sel); -extern void wlc_bmac_copyfrom_objmem(wlc_hw_info_t *wlc_hw, uint offset, +extern void wlc_bmac_copyfrom_objmem(struct wlc_hw_info *wlc_hw, uint offset, void *buf, int len, u32 sel); #define wlc_bmac_copyfrom_shm(wlc_hw, offset, buf, len) \ wlc_bmac_copyfrom_objmem(wlc_hw, offset, buf, len, OBJADDR_SHM_SEL) #define wlc_bmac_copyto_shm(wlc_hw, offset, buf, len) \ wlc_bmac_copyto_objmem(wlc_hw, offset, buf, len, OBJADDR_SHM_SEL) -extern void wlc_bmac_core_phy_clk(wlc_hw_info_t *wlc_hw, bool clk); -extern void wlc_bmac_core_phypll_reset(wlc_hw_info_t *wlc_hw); -extern void wlc_bmac_core_phypll_ctl(wlc_hw_info_t *wlc_hw, bool on); -extern void wlc_bmac_phyclk_fgc(wlc_hw_info_t *wlc_hw, bool clk); -extern void wlc_bmac_macphyclk_set(wlc_hw_info_t *wlc_hw, bool clk); -extern void wlc_bmac_phy_reset(wlc_hw_info_t *wlc_hw); -extern void wlc_bmac_corereset(wlc_hw_info_t *wlc_hw, u32 flags); -extern void wlc_bmac_reset(wlc_hw_info_t *wlc_hw); -extern void wlc_bmac_init(wlc_hw_info_t *wlc_hw, chanspec_t chanspec, +extern void wlc_bmac_core_phy_clk(struct wlc_hw_info *wlc_hw, bool clk); +extern void wlc_bmac_core_phypll_reset(struct wlc_hw_info *wlc_hw); +extern void wlc_bmac_core_phypll_ctl(struct wlc_hw_info *wlc_hw, bool on); +extern void wlc_bmac_phyclk_fgc(struct wlc_hw_info *wlc_hw, bool clk); +extern void wlc_bmac_macphyclk_set(struct wlc_hw_info *wlc_hw, bool clk); +extern void wlc_bmac_phy_reset(struct wlc_hw_info *wlc_hw); +extern void wlc_bmac_corereset(struct wlc_hw_info *wlc_hw, u32 flags); +extern void wlc_bmac_reset(struct wlc_hw_info *wlc_hw); +extern void wlc_bmac_init(struct wlc_hw_info *wlc_hw, chanspec_t chanspec, bool mute); -extern int wlc_bmac_up_prep(wlc_hw_info_t *wlc_hw); -extern int wlc_bmac_up_finish(wlc_hw_info_t *wlc_hw); -extern int wlc_bmac_down_prep(wlc_hw_info_t *wlc_hw); -extern int wlc_bmac_down_finish(wlc_hw_info_t *wlc_hw); -extern void wlc_bmac_corereset(wlc_hw_info_t *wlc_hw, u32 flags); -extern void wlc_bmac_switch_macfreq(wlc_hw_info_t *wlc_hw, u8 spurmode); +extern int wlc_bmac_up_prep(struct wlc_hw_info *wlc_hw); +extern int wlc_bmac_up_finish(struct wlc_hw_info *wlc_hw); +extern int wlc_bmac_down_prep(struct wlc_hw_info *wlc_hw); +extern int wlc_bmac_down_finish(struct wlc_hw_info *wlc_hw); +extern void wlc_bmac_corereset(struct wlc_hw_info *wlc_hw, u32 flags); +extern void wlc_bmac_switch_macfreq(struct wlc_hw_info *wlc_hw, u8 spurmode); /* chanspec, ucode interface */ -extern int wlc_bmac_bandtype(wlc_hw_info_t *wlc_hw); -extern void wlc_bmac_set_chanspec(wlc_hw_info_t *wlc_hw, chanspec_t chanspec, +extern int wlc_bmac_bandtype(struct wlc_hw_info *wlc_hw); +extern void wlc_bmac_set_chanspec(struct wlc_hw_info *wlc_hw, + chanspec_t chanspec, bool mute, struct txpwr_limits *txpwr); -extern void wlc_bmac_txfifo(wlc_hw_info_t *wlc_hw, uint fifo, void *p, +extern void wlc_bmac_txfifo(struct wlc_hw_info *wlc_hw, uint fifo, void *p, bool commit, u16 frameid, u8 txpktpend); -extern int wlc_bmac_xmtfifo_sz_get(wlc_hw_info_t *wlc_hw, uint fifo, +extern int wlc_bmac_xmtfifo_sz_get(struct wlc_hw_info *wlc_hw, uint fifo, uint *blocks); -extern void wlc_bmac_mhf(wlc_hw_info_t *wlc_hw, u8 idx, u16 mask, +extern void wlc_bmac_mhf(struct wlc_hw_info *wlc_hw, u8 idx, u16 mask, u16 val, int bands); -extern void wlc_bmac_mctrl(wlc_hw_info_t *wlc_hw, u32 mask, u32 val); -extern u16 wlc_bmac_mhf_get(wlc_hw_info_t *wlc_hw, u8 idx, int bands); -extern int wlc_bmac_xmtfifo_sz_set(wlc_hw_info_t *wlc_hw, uint fifo, +extern void wlc_bmac_mctrl(struct wlc_hw_info *wlc_hw, u32 mask, u32 val); +extern u16 wlc_bmac_mhf_get(struct wlc_hw_info *wlc_hw, u8 idx, int bands); +extern int wlc_bmac_xmtfifo_sz_set(struct wlc_hw_info *wlc_hw, uint fifo, uint blocks); -extern void wlc_bmac_txant_set(wlc_hw_info_t *wlc_hw, u16 phytxant); -extern u16 wlc_bmac_get_txant(wlc_hw_info_t *wlc_hw); -extern void wlc_bmac_antsel_type_set(wlc_hw_info_t *wlc_hw, u8 antsel_type); -extern int wlc_bmac_revinfo_get(wlc_hw_info_t *wlc_hw, +extern void wlc_bmac_txant_set(struct wlc_hw_info *wlc_hw, u16 phytxant); +extern u16 wlc_bmac_get_txant(struct wlc_hw_info *wlc_hw); +extern void wlc_bmac_antsel_type_set(struct wlc_hw_info *wlc_hw, + u8 antsel_type); +extern int wlc_bmac_revinfo_get(struct wlc_hw_info *wlc_hw, wlc_bmac_revinfo_t *revinfo); -extern int wlc_bmac_state_get(wlc_hw_info_t *wlc_hw, wlc_bmac_state_t *state); -extern void wlc_bmac_write_shm(wlc_hw_info_t *wlc_hw, uint offset, u16 v); -extern u16 wlc_bmac_read_shm(wlc_hw_info_t *wlc_hw, uint offset); -extern void wlc_bmac_set_shm(wlc_hw_info_t *wlc_hw, uint offset, u16 v, +extern int wlc_bmac_state_get(struct wlc_hw_info *wlc_hw, + wlc_bmac_state_t *state); +extern void wlc_bmac_write_shm(struct wlc_hw_info *wlc_hw, uint offset, u16 v); +extern u16 wlc_bmac_read_shm(struct wlc_hw_info *wlc_hw, uint offset); +extern void wlc_bmac_set_shm(struct wlc_hw_info *wlc_hw, uint offset, u16 v, int len); -extern void wlc_bmac_write_template_ram(wlc_hw_info_t *wlc_hw, int offset, +extern void wlc_bmac_write_template_ram(struct wlc_hw_info *wlc_hw, int offset, int len, void *buf); -extern void wlc_bmac_copyfrom_vars(wlc_hw_info_t *wlc_hw, char **buf, +extern void wlc_bmac_copyfrom_vars(struct wlc_hw_info *wlc_hw, char **buf, uint *len); -extern void wlc_bmac_process_ps_switch(wlc_hw_info_t *wlc, +extern void wlc_bmac_process_ps_switch(struct wlc_hw_info *wlc, struct ether_addr *ea, s8 ps_on); -extern void wlc_bmac_hw_etheraddr(wlc_hw_info_t *wlc_hw, +extern void wlc_bmac_hw_etheraddr(struct wlc_hw_info *wlc_hw, struct ether_addr *ea); -extern void wlc_bmac_set_hw_etheraddr(wlc_hw_info_t *wlc_hw, +extern void wlc_bmac_set_hw_etheraddr(struct wlc_hw_info *wlc_hw, struct ether_addr *ea); -extern bool wlc_bmac_validate_chip_access(wlc_hw_info_t *wlc_hw); +extern bool wlc_bmac_validate_chip_access(struct wlc_hw_info *wlc_hw); -extern bool wlc_bmac_radio_read_hwdisabled(wlc_hw_info_t *wlc_hw); -extern void wlc_bmac_set_shortslot(wlc_hw_info_t *wlc_hw, bool shortslot); -extern void wlc_bmac_mute(wlc_hw_info_t *wlc_hw, bool want, mbool flags); -extern void wlc_bmac_set_deaf(wlc_hw_info_t *wlc_hw, bool user_flag); -extern void wlc_bmac_band_stf_ss_set(wlc_hw_info_t *wlc_hw, u8 stf_mode); +extern bool wlc_bmac_radio_read_hwdisabled(struct wlc_hw_info *wlc_hw); +extern void wlc_bmac_set_shortslot(struct wlc_hw_info *wlc_hw, bool shortslot); +extern void wlc_bmac_mute(struct wlc_hw_info *wlc_hw, bool want, mbool flags); +extern void wlc_bmac_set_deaf(struct wlc_hw_info *wlc_hw, bool user_flag); +extern void wlc_bmac_band_stf_ss_set(struct wlc_hw_info *wlc_hw, u8 stf_mode); -extern void wlc_bmac_wait_for_wake(wlc_hw_info_t *wlc_hw); -extern bool wlc_bmac_tx_fifo_suspended(wlc_hw_info_t *wlc_hw, uint tx_fifo); -extern void wlc_bmac_tx_fifo_suspend(wlc_hw_info_t *wlc_hw, uint tx_fifo); -extern void wlc_bmac_tx_fifo_resume(wlc_hw_info_t *wlc_hw, uint tx_fifo); +extern void wlc_bmac_wait_for_wake(struct wlc_hw_info *wlc_hw); +extern bool wlc_bmac_tx_fifo_suspended(struct wlc_hw_info *wlc_hw, + uint tx_fifo); +extern void wlc_bmac_tx_fifo_suspend(struct wlc_hw_info *wlc_hw, uint tx_fifo); +extern void wlc_bmac_tx_fifo_resume(struct wlc_hw_info *wlc_hw, uint tx_fifo); -extern void wlc_ucode_wake_override_set(wlc_hw_info_t *wlc_hw, +extern void wlc_ucode_wake_override_set(struct wlc_hw_info *wlc_hw, u32 override_bit); -extern void wlc_ucode_wake_override_clear(wlc_hw_info_t *wlc_hw, +extern void wlc_ucode_wake_override_clear(struct wlc_hw_info *wlc_hw, u32 override_bit); -extern void wlc_bmac_set_rcmta(wlc_hw_info_t *wlc_hw, int idx, +extern void wlc_bmac_set_rcmta(struct wlc_hw_info *wlc_hw, int idx, const struct ether_addr *addr); -extern void wlc_bmac_set_addrmatch(wlc_hw_info_t *wlc_hw, int match_reg_offset, +extern void wlc_bmac_set_addrmatch(struct wlc_hw_info *wlc_hw, + int match_reg_offset, const struct ether_addr *addr); -extern void wlc_bmac_write_hw_bcntemplates(wlc_hw_info_t *wlc_hw, void *bcn, - int len, bool both); +extern void wlc_bmac_write_hw_bcntemplates(struct wlc_hw_info *wlc_hw, + void *bcn, int len, bool both); -extern void wlc_bmac_read_tsf(wlc_hw_info_t *wlc_hw, u32 *tsf_l_ptr, +extern void wlc_bmac_read_tsf(struct wlc_hw_info *wlc_hw, u32 *tsf_l_ptr, u32 *tsf_h_ptr); -extern void wlc_bmac_set_cwmin(wlc_hw_info_t *wlc_hw, u16 newmin); -extern void wlc_bmac_set_cwmax(wlc_hw_info_t *wlc_hw, u16 newmax); -extern void wlc_bmac_set_noreset(wlc_hw_info_t *wlc, bool noreset_flag); -extern void wlc_bmac_set_ucode_loaded(wlc_hw_info_t *wlc, bool ucode_loaded); +extern void wlc_bmac_set_cwmin(struct wlc_hw_info *wlc_hw, u16 newmin); +extern void wlc_bmac_set_cwmax(struct wlc_hw_info *wlc_hw, u16 newmax); +extern void wlc_bmac_set_noreset(struct wlc_hw_info *wlc, bool noreset_flag); +extern void wlc_bmac_set_ucode_loaded(struct wlc_hw_info *wlc, + bool ucode_loaded); -extern void wlc_bmac_retrylimit_upd(wlc_hw_info_t *wlc_hw, u16 SRL, +extern void wlc_bmac_retrylimit_upd(struct wlc_hw_info *wlc_hw, u16 SRL, u16 LRL); -extern void wlc_bmac_fifoerrors(wlc_hw_info_t *wlc_hw); +extern void wlc_bmac_fifoerrors(struct wlc_hw_info *wlc_hw); /* API for BMAC driver (e.g. wlc_phy.c etc) */ -extern void wlc_bmac_bw_set(wlc_hw_info_t *wlc_hw, u16 bw); -extern void wlc_bmac_pllreq(wlc_hw_info_t *wlc_hw, bool set, mbool req_bit); -extern void wlc_bmac_set_clk(wlc_hw_info_t *wlc_hw, bool on); -extern bool wlc_bmac_taclear(wlc_hw_info_t *wlc_hw, bool ta_ok); +extern void wlc_bmac_bw_set(struct wlc_hw_info *wlc_hw, u16 bw); +extern void wlc_bmac_pllreq(struct wlc_hw_info *wlc_hw, bool set, + mbool req_bit); +extern void wlc_bmac_set_clk(struct wlc_hw_info *wlc_hw, bool on); +extern bool wlc_bmac_taclear(struct wlc_hw_info *wlc_hw, bool ta_ok); extern void wlc_bmac_hw_up(struct wlc_hw_info *wlc_hw); -extern void wlc_bmac_dump(wlc_hw_info_t *wlc_hw, struct bcmstrbuf *b, +extern void wlc_bmac_dump(struct wlc_hw_info *wlc_hw, struct bcmstrbuf *b, wlc_bmac_dump_id_t dump_id); -extern void wlc_gpio_fast_deinit(wlc_hw_info_t *wlc_hw); +extern void wlc_gpio_fast_deinit(struct wlc_hw_info *wlc_hw); -extern bool wlc_bmac_radio_hw(wlc_hw_info_t *wlc_hw, bool enable); -extern u16 wlc_bmac_rate_shm_offset(wlc_hw_info_t *wlc_hw, u8 rate); +extern bool wlc_bmac_radio_hw(struct wlc_hw_info *wlc_hw, bool enable); +extern u16 wlc_bmac_rate_shm_offset(struct wlc_hw_info *wlc_hw, u8 rate); -extern void wlc_bmac_assert_type_set(wlc_hw_info_t *wlc_hw, u32 type); -extern void wlc_bmac_set_txpwr_percent(wlc_hw_info_t *wlc_hw, u8 val); -extern void wlc_bmac_blink_sync(wlc_hw_info_t *wlc_hw, u32 led_pins); -extern void wlc_bmac_ifsctl_edcrs_set(wlc_hw_info_t *wlc_hw, bool abie, +extern void wlc_bmac_assert_type_set(struct wlc_hw_info *wlc_hw, u32 type); +extern void wlc_bmac_set_txpwr_percent(struct wlc_hw_info *wlc_hw, u8 val); +extern void wlc_bmac_blink_sync(struct wlc_hw_info *wlc_hw, u32 led_pins); +extern void wlc_bmac_ifsctl_edcrs_set(struct wlc_hw_info *wlc_hw, bool abie, bool isht); -extern void wlc_bmac_antsel_set(wlc_hw_info_t *wlc_hw, u32 antsel_avail); +extern void wlc_bmac_antsel_set(struct wlc_hw_info *wlc_hw, u32 antsel_avail); diff --git a/drivers/staging/brcm80211/sys/wlc_mac80211.h b/drivers/staging/brcm80211/sys/wlc_mac80211.h index b246a7c22ab0..791e9178267e 100644 --- a/drivers/staging/brcm80211/sys/wlc_mac80211.h +++ b/drivers/staging/brcm80211/sys/wlc_mac80211.h @@ -512,7 +512,7 @@ struct wlc_info { struct wl_info *wl; /* pointer to os-specific private state */ d11regs_t *regs; /* pointer to device registers */ - wlc_hw_info_t *hw; /* HW related state used primarily by BMAC */ + struct wlc_hw_info *hw; /* HW related state used primarily by BMAC */ /* clock */ int clkreq_override; /* setting for clkreq for PCIE : Auto, 0, 1 */ @@ -861,8 +861,8 @@ extern void wlc_print_txdesc(d11txh_t *txh); extern void wlc_print_dot11_mac_hdr(u8 *buf, int len); #endif -extern void wlc_setxband(wlc_hw_info_t *wlc_hw, uint bandunit); -extern void wlc_coredisable(wlc_hw_info_t *wlc_hw); +extern void wlc_setxband(struct wlc_hw_info *wlc_hw, uint bandunit); +extern void wlc_coredisable(struct wlc_hw_info *wlc_hw); extern bool wlc_valid_rate(struct wlc_info *wlc, ratespec_t rate, int band, bool verbose); diff --git a/drivers/staging/brcm80211/sys/wlc_phy_shim.c b/drivers/staging/brcm80211/sys/wlc_phy_shim.c index 201ecdb319cd..5dcaa7d70045 100644 --- a/drivers/staging/brcm80211/sys/wlc_phy_shim.c +++ b/drivers/staging/brcm80211/sys/wlc_phy_shim.c @@ -59,12 +59,12 @@ /* PHY SHIM module specific state */ struct wlc_phy_shim_info { - wlc_hw_info_t *wlc_hw; /* pointer to main wlc_hw structure */ + struct wlc_hw_info *wlc_hw; /* pointer to main wlc_hw structure */ void *wlc; /* pointer to main wlc structure */ void *wl; /* pointer to os-specific private state */ }; -wlc_phy_shim_info_t *wlc_phy_shim_attach(wlc_hw_info_t *wlc_hw, +wlc_phy_shim_info_t *wlc_phy_shim_attach(struct wlc_hw_info *wlc_hw, void *wl, void *wlc) { wlc_phy_shim_info_t *physhim = NULL; diff --git a/drivers/staging/brcm80211/sys/wlc_types.h b/drivers/staging/brcm80211/sys/wlc_types.h index 52f888690530..e5c8600c6298 100644 --- a/drivers/staging/brcm80211/sys/wlc_types.h +++ b/drivers/staging/brcm80211/sys/wlc_types.h @@ -20,7 +20,7 @@ /* forward declarations */ struct wlc_info; -typedef struct wlc_hw_info wlc_hw_info_t; +struct wlc_hw_info; typedef struct wlc_if wlc_if_t; typedef struct wl_if wl_if_t; typedef struct led_info led_info_t; -- cgit v1.2.3 From 85c0b1760a7c259679d188bef58866fc641deca5 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Mon, 6 Dec 2010 10:01:16 +0300 Subject: Staging: Beceem: add USB id for BCSM250 Mobile WiMAX Signed-off-by: Dan Carpenter Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/InterfaceInit.c | 1 + drivers/staging/bcm/InterfaceInit.h | 1 + 2 files changed, 2 insertions(+) diff --git a/drivers/staging/bcm/InterfaceInit.c b/drivers/staging/bcm/InterfaceInit.c index 7ffbfecaa117..4a9d8c0d5de7 100644 --- a/drivers/staging/bcm/InterfaceInit.c +++ b/drivers/staging/bcm/InterfaceInit.c @@ -4,6 +4,7 @@ static struct usb_device_id InterfaceUsbtable[] = { { USB_DEVICE(BCM_USB_VENDOR_ID_T3, BCM_USB_PRODUCT_ID_T3) }, { USB_DEVICE(BCM_USB_VENDOR_ID_T3, BCM_USB_PRODUCT_ID_T3B) }, { USB_DEVICE(BCM_USB_VENDOR_ID_T3, BCM_USB_PRODUCT_ID_T3L) }, + { USB_DEVICE(BCM_USB_VENDOR_ID_T3, BCM_USB_PRODUCT_ID_SM250) }, { USB_DEVICE(BCM_USB_VENDOR_ID_ZTE, BCM_USB_PRODUCT_ID_226) }, { USB_DEVICE(BCM_USB_VENDOR_ID_FOXCONN, BCM_USB_PRODUCT_ID_1901) }, { USB_DEVICE(BCM_USB_VENDOR_ID_ZTE, BCM_USB_PRODUCT_ID_ZTE_TU25) }, diff --git a/drivers/staging/bcm/InterfaceInit.h b/drivers/staging/bcm/InterfaceInit.h index 091cf78d63a1..058315a64c05 100644 --- a/drivers/staging/bcm/InterfaceInit.h +++ b/drivers/staging/bcm/InterfaceInit.h @@ -8,6 +8,7 @@ #define BCM_USB_PRODUCT_ID_T3 0x0300 #define BCM_USB_PRODUCT_ID_T3B 0x0210 #define BCM_USB_PRODUCT_ID_T3L 0x0220 +#define BCM_USB_PRODUCT_ID_SM250 0xbccd #define BCM_USB_PRODUCT_ID_SYM 0x15E #define BCM_USB_PRODUCT_ID_1901 0xe017 #define BCM_USB_PRODUCT_ID_226 0x0132 -- cgit v1.2.3 From 2a314742d300edc2010d50a006c77ceb04c75119 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Mon, 6 Dec 2010 10:01:41 +0300 Subject: Staging: Beceem: use lower case "int" instead of "INT" This patch changes: INT => int ULONG => unsigned long VOID => void Signed-off-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/InterfaceInit.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/staging/bcm/InterfaceInit.c b/drivers/staging/bcm/InterfaceInit.c index 4a9d8c0d5de7..5d113334d067 100644 --- a/drivers/staging/bcm/InterfaceInit.c +++ b/drivers/staging/bcm/InterfaceInit.c @@ -21,11 +21,11 @@ static const u32 default_msg = | NETIF_MSG_TIMER | NETIF_MSG_TX_ERR | NETIF_MSG_RX_ERR | NETIF_MSG_IFUP | NETIF_MSG_IFDOWN; -static INT InterfaceAdapterInit(PS_INTERFACE_ADAPTER Adapter); +static int InterfaceAdapterInit(PS_INTERFACE_ADAPTER Adapter); -static VOID InterfaceAdapterFree(PS_INTERFACE_ADAPTER psIntfAdapter) +static void InterfaceAdapterFree(PS_INTERFACE_ADAPTER psIntfAdapter) { - INT i = 0; + int i = 0; // Wake up the wait_queue... if(psIntfAdapter->psAdapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY) { @@ -70,9 +70,9 @@ static VOID InterfaceAdapterFree(PS_INTERFACE_ADAPTER psIntfAdapter) AdapterFree(psIntfAdapter->psAdapter); } -static VOID ConfigureEndPointTypesThroughEEPROM(PMINI_ADAPTER Adapter) +static void ConfigureEndPointTypesThroughEEPROM(PMINI_ADAPTER Adapter) { - ULONG ulReg = 0; + unsigned long ulReg = 0; // Program EP2 MAX_PKT_SIZE ulReg = ntohl(EP2_MPS_REG); @@ -335,7 +335,7 @@ static int AllocUsbCb(PS_INTERFACE_ADAPTER psIntfAdapter) static int device_run(PS_INTERFACE_ADAPTER psIntfAdapter) { - INT value = 0; + int value = 0; UINT status = STATUS_SUCCESS; status = InitCardAndDownloadFirmware(psIntfAdapter->psAdapter); @@ -444,14 +444,14 @@ static inline int bcm_usb_endpoint_is_isoc_out(const struct usb_endpoint_descrip return (bcm_usb_endpoint_xfer_isoc(epd) && bcm_usb_endpoint_dir_out(epd)); } -static INT InterfaceAdapterInit(PS_INTERFACE_ADAPTER psIntfAdapter) +static int InterfaceAdapterInit(PS_INTERFACE_ADAPTER psIntfAdapter) { struct usb_host_interface *iface_desc; struct usb_endpoint_descriptor *endpoint; size_t buffer_size; - ULONG value; - INT retval = 0; - INT usedIntOutForBulkTransfer = 0 ; + unsigned long value; + int retval = 0; + int usedIntOutForBulkTransfer = 0 ; BOOLEAN bBcm16 = FALSE; UINT uiData = 0; -- cgit v1.2.3 From c2a0b162dbce1534cf4e71914597419ae83a70d9 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Mon, 6 Dec 2010 10:02:11 +0300 Subject: Staging: Beceem: white space changes to InterfaceInit.c This patch only changes: 1) spaces, tabs, and newline characters. 2) comment styles. The compiled object file is the same before and after except for line number changes. Signed-off-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/InterfaceInit.c | 535 ++++++++++++++++-------------------- 1 file changed, 236 insertions(+), 299 deletions(-) diff --git a/drivers/staging/bcm/InterfaceInit.c b/drivers/staging/bcm/InterfaceInit.c index 5d113334d067..844e5faacca0 100644 --- a/drivers/staging/bcm/InterfaceInit.c +++ b/drivers/staging/bcm/InterfaceInit.c @@ -1,14 +1,14 @@ #include "headers.h" static struct usb_device_id InterfaceUsbtable[] = { - { USB_DEVICE(BCM_USB_VENDOR_ID_T3, BCM_USB_PRODUCT_ID_T3) }, - { USB_DEVICE(BCM_USB_VENDOR_ID_T3, BCM_USB_PRODUCT_ID_T3B) }, - { USB_DEVICE(BCM_USB_VENDOR_ID_T3, BCM_USB_PRODUCT_ID_T3L) }, - { USB_DEVICE(BCM_USB_VENDOR_ID_T3, BCM_USB_PRODUCT_ID_SM250) }, - { USB_DEVICE(BCM_USB_VENDOR_ID_ZTE, BCM_USB_PRODUCT_ID_226) }, - { USB_DEVICE(BCM_USB_VENDOR_ID_FOXCONN, BCM_USB_PRODUCT_ID_1901) }, - { USB_DEVICE(BCM_USB_VENDOR_ID_ZTE, BCM_USB_PRODUCT_ID_ZTE_TU25) }, - { } + { USB_DEVICE(BCM_USB_VENDOR_ID_T3, BCM_USB_PRODUCT_ID_T3) }, + { USB_DEVICE(BCM_USB_VENDOR_ID_T3, BCM_USB_PRODUCT_ID_T3B) }, + { USB_DEVICE(BCM_USB_VENDOR_ID_T3, BCM_USB_PRODUCT_ID_T3L) }, + { USB_DEVICE(BCM_USB_VENDOR_ID_T3, BCM_USB_PRODUCT_ID_SM250) }, + { USB_DEVICE(BCM_USB_VENDOR_ID_ZTE, BCM_USB_PRODUCT_ID_226) }, + { USB_DEVICE(BCM_USB_VENDOR_ID_FOXCONN, BCM_USB_PRODUCT_ID_1901) }, + { USB_DEVICE(BCM_USB_VENDOR_ID_ZTE, BCM_USB_PRODUCT_ID_ZTE_TU25) }, + { } }; MODULE_DEVICE_TABLE(usb, InterfaceUsbtable); @@ -17,51 +17,48 @@ module_param(debug, uint, 0600); MODULE_PARM_DESC(debug, "Debug level (0=none,...,16=all)"); static const u32 default_msg = - NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_LINK - | NETIF_MSG_TIMER | NETIF_MSG_TX_ERR | NETIF_MSG_RX_ERR - | NETIF_MSG_IFUP | NETIF_MSG_IFDOWN; + NETIF_MSG_DRV | NETIF_MSG_PROBE | NETIF_MSG_LINK + | NETIF_MSG_TIMER | NETIF_MSG_TX_ERR | NETIF_MSG_RX_ERR + | NETIF_MSG_IFUP | NETIF_MSG_IFDOWN; static int InterfaceAdapterInit(PS_INTERFACE_ADAPTER Adapter); static void InterfaceAdapterFree(PS_INTERFACE_ADAPTER psIntfAdapter) { int i = 0; - // Wake up the wait_queue... - if(psIntfAdapter->psAdapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY) - { + + /* Wake up the wait_queue... */ + if (psIntfAdapter->psAdapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY) { psIntfAdapter->psAdapter->DriverState = DRIVER_HALT; wake_up(&psIntfAdapter->psAdapter->LEDInfo.notify_led_event); } reset_card_proc(psIntfAdapter->psAdapter); - //worst case time taken by the RDM/WRM will be 5 sec. will check after every 100 ms - //to accertain the device is not being accessed. After this No RDM/WRM should be made. - while(psIntfAdapter->psAdapter->DeviceAccess) - { - BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL,"Device is being Accessed \n"); + /* + * worst case time taken by the RDM/WRM will be 5 sec. will check after every 100 ms + * to accertain the device is not being accessed. After this No RDM/WRM should be made. + */ + while (psIntfAdapter->psAdapter->DeviceAccess) { + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, + "Device is being Accessed \n"); msleep(100); } /* Free interrupt URB */ - //psIntfAdapter->psAdapter->device_removed = TRUE; - if(psIntfAdapter->psInterruptUrb) - { + /* psIntfAdapter->psAdapter->device_removed = TRUE; */ + if (psIntfAdapter->psInterruptUrb) { usb_free_urb(psIntfAdapter->psInterruptUrb); } /* Free transmit URBs */ - for(i = 0; i < MAXIMUM_USB_TCB; i++) - { - if(psIntfAdapter->asUsbTcb[i].urb != NULL) - { + for (i = 0; i < MAXIMUM_USB_TCB; i++) { + if (psIntfAdapter->asUsbTcb[i].urb != NULL) { usb_free_urb(psIntfAdapter->asUsbTcb[i].urb); psIntfAdapter->asUsbTcb[i].urb = NULL; } } /* Free receive URB and buffers */ - for(i = 0; i < MAXIMUM_USB_RCB; i++) - { - if (psIntfAdapter->asUsbRcb[i].urb != NULL) - { + for (i = 0; i < MAXIMUM_USB_RCB; i++) { + if (psIntfAdapter->asUsbRcb[i].urb != NULL) { kfree(psIntfAdapter->asUsbRcb[i].urb->transfer_buffer); usb_free_urb(psIntfAdapter->asUsbRcb[i].urb); psIntfAdapter->asUsbRcb[i].urb = NULL; @@ -74,84 +71,77 @@ static void ConfigureEndPointTypesThroughEEPROM(PMINI_ADAPTER Adapter) { unsigned long ulReg = 0; -// Program EP2 MAX_PKT_SIZE + /* Program EP2 MAX_PKT_SIZE */ ulReg = ntohl(EP2_MPS_REG); - BeceemEEPROMBulkWrite(Adapter,(PUCHAR)&ulReg,0x128,4,TRUE); + BeceemEEPROMBulkWrite(Adapter, (PUCHAR)&ulReg, 0x128, 4, TRUE); ulReg = ntohl(EP2_MPS); - BeceemEEPROMBulkWrite(Adapter,(PUCHAR)&ulReg,0x12C,4,TRUE); + BeceemEEPROMBulkWrite(Adapter, (PUCHAR)&ulReg, 0x12C, 4, TRUE); ulReg = ntohl(EP2_CFG_REG); - BeceemEEPROMBulkWrite(Adapter,(PUCHAR)&ulReg,0x132,4,TRUE); - if(((PS_INTERFACE_ADAPTER)(Adapter->pvInterfaceAdapter))->bHighSpeedDevice == TRUE) - { + BeceemEEPROMBulkWrite(Adapter, (PUCHAR)&ulReg, 0x132, 4, TRUE); + if (((PS_INTERFACE_ADAPTER)(Adapter->pvInterfaceAdapter))->bHighSpeedDevice == TRUE) { ulReg = ntohl(EP2_CFG_INT); - BeceemEEPROMBulkWrite(Adapter,(PUCHAR)&ulReg,0x136,4,TRUE); - } - else - { -// USE BULK EP as TX in FS mode. + BeceemEEPROMBulkWrite(Adapter, (PUCHAR)&ulReg, 0x136, 4, TRUE); + } else { + /* USE BULK EP as TX in FS mode. */ ulReg = ntohl(EP2_CFG_BULK); - BeceemEEPROMBulkWrite(Adapter,(PUCHAR)&ulReg,0x136,4,TRUE); + BeceemEEPROMBulkWrite(Adapter, (PUCHAR)&ulReg, 0x136, 4, TRUE); } - -// Program EP4 MAX_PKT_SIZE. + /* Program EP4 MAX_PKT_SIZE. */ ulReg = ntohl(EP4_MPS_REG); - BeceemEEPROMBulkWrite(Adapter,(PUCHAR)&ulReg,0x13C,4,TRUE); + BeceemEEPROMBulkWrite(Adapter, (PUCHAR)&ulReg, 0x13C, 4, TRUE); ulReg = ntohl(EP4_MPS); - BeceemEEPROMBulkWrite(Adapter,(PUCHAR)&ulReg,0x140,4,TRUE); + BeceemEEPROMBulkWrite(Adapter, (PUCHAR)&ulReg, 0x140, 4, TRUE); -// Program TX EP as interrupt (Alternate Setting) - if( rdmalt(Adapter,0x0F0110F8, (PUINT)&ulReg,4)) - { - BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "reading of Tx EP is failing"); - return ; + /* Program TX EP as interrupt(Alternate Setting) */ + if (rdmalt(Adapter, 0x0F0110F8, (PUINT)&ulReg, 4)) { + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "reading of Tx EP is failing"); + return; } ulReg |= 0x6; ulReg = ntohl(ulReg); - BeceemEEPROMBulkWrite(Adapter,(PUCHAR)&ulReg,0x1CC,4,TRUE); + BeceemEEPROMBulkWrite(Adapter, (PUCHAR)&ulReg, 0x1CC, 4, TRUE); ulReg = ntohl(EP4_CFG_REG); - BeceemEEPROMBulkWrite(Adapter,(PUCHAR)&ulReg,0x1C8,4,TRUE); -// Program ISOCHRONOUS EP size to zero. + BeceemEEPROMBulkWrite(Adapter, (PUCHAR)&ulReg, 0x1C8, 4, TRUE); + /* Program ISOCHRONOUS EP size to zero. */ ulReg = ntohl(ISO_MPS_REG); - BeceemEEPROMBulkWrite(Adapter,(PUCHAR)&ulReg,0x1D2,4,TRUE); + BeceemEEPROMBulkWrite(Adapter, (PUCHAR)&ulReg, 0x1D2, 4, TRUE); ulReg = ntohl(ISO_MPS); - BeceemEEPROMBulkWrite(Adapter,(PUCHAR)&ulReg,0x1D6,4,TRUE); + BeceemEEPROMBulkWrite(Adapter, (PUCHAR)&ulReg, 0x1D6, 4, TRUE); -// Update EEPROM Version. -// Read 4 bytes from 508 and modify 511 and 510. -// - ReadBeceemEEPROM(Adapter,0x1FC,(PUINT)&ulReg); + /* + * Update EEPROM Version. + * Read 4 bytes from 508 and modify 511 and 510. + */ + ReadBeceemEEPROM(Adapter, 0x1FC, (PUINT)&ulReg); ulReg &= 0x0101FFFF; - BeceemEEPROMBulkWrite(Adapter,(PUCHAR)&ulReg,0x1FC,4,TRUE); -// -//Update length field if required. Also make the string NULL terminated. -// - ReadBeceemEEPROM(Adapter,0xA8,(PUINT)&ulReg); - if((ulReg&0x00FF0000)>>16 > 0x30) - { + BeceemEEPROMBulkWrite(Adapter, (PUCHAR)&ulReg, 0x1FC, 4, TRUE); + + /* Update length field if required. Also make the string NULL terminated. */ + + ReadBeceemEEPROM(Adapter, 0xA8, (PUINT)&ulReg); + if ((ulReg&0x00FF0000)>>16 > 0x30) { ulReg = (ulReg&0xFF00FFFF)|(0x30<<16); - BeceemEEPROMBulkWrite(Adapter,(PUCHAR)&ulReg,0xA8,4,TRUE); + BeceemEEPROMBulkWrite(Adapter, (PUCHAR)&ulReg, 0xA8, 4, TRUE); } - ReadBeceemEEPROM(Adapter,0x148,(PUINT)&ulReg); - if((ulReg&0x00FF0000)>>16 > 0x30) - { + ReadBeceemEEPROM(Adapter, 0x148, (PUINT)&ulReg); + if ((ulReg&0x00FF0000)>>16 > 0x30) { ulReg = (ulReg&0xFF00FFFF)|(0x30<<16); - BeceemEEPROMBulkWrite(Adapter,(PUCHAR)&ulReg,0x148,4,TRUE); + BeceemEEPROMBulkWrite(Adapter, (PUCHAR)&ulReg, 0x148, 4, TRUE); } ulReg = 0; - BeceemEEPROMBulkWrite(Adapter,(PUCHAR)&ulReg,0x122,4,TRUE); + BeceemEEPROMBulkWrite(Adapter, (PUCHAR)&ulReg, 0x122, 4, TRUE); ulReg = 0; - BeceemEEPROMBulkWrite(Adapter,(PUCHAR)&ulReg,0x1C2,4,TRUE); - + BeceemEEPROMBulkWrite(Adapter, (PUCHAR)&ulReg, 0x1C2, 4, TRUE); } static int usbbcm_device_probe(struct usb_interface *intf, const struct usb_device_id *id) { - struct usb_device *udev = interface_to_usbdev (intf); + struct usb_device *udev = interface_to_usbdev(intf); int retval; PMINI_ADAPTER psAdapter; PS_INTERFACE_ADAPTER psIntfAdapter; @@ -159,7 +149,7 @@ usbbcm_device_probe(struct usb_interface *intf, const struct usb_device_id *id) /* Reserve one extra queue for the bit-bucket */ ndev = alloc_etherdev_mq(sizeof(MINI_ADAPTER), NO_OF_QUEUES+1); - if(ndev == NULL) { + if (ndev == NULL) { dev_err(&udev->dev, DRV_NAME ": no memory for device\n"); return -ENOMEM; } @@ -170,12 +160,13 @@ usbbcm_device_probe(struct usb_interface *intf, const struct usb_device_id *id) psAdapter->dev = ndev; psAdapter->msg_enable = netif_msg_init(debug, default_msg); - /* Init default driver debug state */ + /* Init default driver debug state */ psAdapter->stDebugState.debug_level = DBG_LVL_CURR; psAdapter->stDebugState.type = DBG_TYPE_INITEXIT; - /* Technically, one can start using BCM_DEBUG_PRINT after this point. + /* + * Technically, one can start using BCM_DEBUG_PRINT after this point. * However, realize that by default the Type/Subtype bitmaps are all zero now; * so no prints will actually appear until the TestApp turns on debug paths via * the ioctl(); so practically speaking, in early init, no logging happens. @@ -186,12 +177,11 @@ usbbcm_device_probe(struct usb_interface *intf, const struct usb_device_id *id) * Further, we turn this OFF once init_module() completes. */ - psAdapter->stDebugState.subtype[DBG_TYPE_INITEXIT] = 0xff; + psAdapter->stDebugState.subtype[DBG_TYPE_INITEXIT] = 0xff; BCM_SHOW_DEBUG_BITMAP(psAdapter); retval = InitAdapter(psAdapter); - if(retval) - { + if (retval) { dev_err(&udev->dev, DRV_NAME ": InitAdapter Failed\n"); AdapterFree(psAdapter); return retval; @@ -199,10 +189,9 @@ usbbcm_device_probe(struct usb_interface *intf, const struct usb_device_id *id) /* Allocate interface adapter structure */ psIntfAdapter = kzalloc(sizeof(S_INTERFACE_ADAPTER), GFP_KERNEL); - if (psIntfAdapter == NULL) - { + if (psIntfAdapter == NULL) { dev_err(&udev->dev, DRV_NAME ": no memory for Interface adapter\n"); - AdapterFree (psAdapter); + AdapterFree(psAdapter); return -ENOMEM; } @@ -213,84 +202,78 @@ usbbcm_device_probe(struct usb_interface *intf, const struct usb_device_id *id) psIntfAdapter->interface = intf; usb_set_intfdata(intf, psIntfAdapter); - BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "psIntfAdapter 0x%p",psIntfAdapter); + BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "psIntfAdapter 0x%p", psIntfAdapter); retval = InterfaceAdapterInit(psIntfAdapter); - if(retval) - { + if (retval) { /* If the Firmware/Cfg File is not present - * then return success, let the application - * download the files. - */ - if(-ENOENT == retval){ - BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "File Not Found, Use App to Download\n"); + * then return success, let the application + * download the files. + */ + if (-ENOENT == retval) { + BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "File Not Found, Use App to Download\n"); return STATUS_SUCCESS; } - BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "InterfaceAdapterInit Failed \n"); + BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "InterfaceAdapterInit Failed \n"); usb_set_intfdata(intf, NULL); - udev = interface_to_usbdev (intf); + udev = interface_to_usbdev(intf); usb_put_dev(udev); InterfaceAdapterFree(psIntfAdapter); - return retval ; + return retval; } - if(psAdapter->chip_id > T3) - { - uint32_t uiNackZeroLengthInt=4; - if(wrmalt(psAdapter, DISABLE_USB_ZERO_LEN_INT, &uiNackZeroLengthInt, sizeof(uiNackZeroLengthInt))) - { + if (psAdapter->chip_id > T3) { + uint32_t uiNackZeroLengthInt = 4; + + if (wrmalt(psAdapter, DISABLE_USB_ZERO_LEN_INT, &uiNackZeroLengthInt, sizeof(uiNackZeroLengthInt))) { return -EIO; } } /* Check whether the USB-Device Supports remote Wake-Up */ - if(USB_CONFIG_ATT_WAKEUP & udev->actconfig->desc.bmAttributes) - { + if (USB_CONFIG_ATT_WAKEUP & udev->actconfig->desc.bmAttributes) { /* If Suspend then only support dynamic suspend */ - if(psAdapter->bDoSuspend) - { + if (psAdapter->bDoSuspend) { #ifdef CONFIG_PM udev->autosuspend_delay = 0; intf->needs_remote_wakeup = 1; #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 35) - udev->autosuspend_disabled = 0; + udev->autosuspend_disabled = 0; #else usb_enable_autosuspend(udev); #endif - device_init_wakeup(&intf->dev,1); + device_init_wakeup(&intf->dev, 1); #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 32) - usb_autopm_disable(intf); + usb_autopm_disable(intf); #endif INIT_WORK(&psIntfAdapter->usbSuspendWork, putUsbSuspend); - BCM_DEBUG_PRINT(psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Enabling USB Auto-Suspend\n"); + BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Enabling USB Auto-Suspend\n"); #endif - } - else - { + } else { intf->needs_remote_wakeup = 0; #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 35) - udev->autosuspend_disabled = 1; + udev->autosuspend_disabled = 1; #else usb_disable_autosuspend(udev); #endif } } - psAdapter->stDebugState.subtype[DBG_TYPE_INITEXIT] = 0x0; - return retval; + psAdapter->stDebugState.subtype[DBG_TYPE_INITEXIT] = 0x0; + return retval; } -static void usbbcm_disconnect (struct usb_interface *intf) +static void usbbcm_disconnect(struct usb_interface *intf) { PS_INTERFACE_ADAPTER psIntfAdapter = usb_get_intfdata(intf); PMINI_ADAPTER psAdapter; - struct usb_device *udev = interface_to_usbdev (intf); + struct usb_device *udev = interface_to_usbdev(intf); - if(psIntfAdapter == NULL) + if (psIntfAdapter == NULL) return; psAdapter = psIntfAdapter->psAdapter; netif_device_detach(psAdapter->dev); - if(psAdapter->bDoSuspend) + if (psAdapter->bDoSuspend) intf->needs_remote_wakeup = 0; psAdapter->device_removed = TRUE ; @@ -302,28 +285,24 @@ static void usbbcm_disconnect (struct usb_interface *intf) static int AllocUsbCb(PS_INTERFACE_ADAPTER psIntfAdapter) { int i = 0; - for(i = 0; i < MAXIMUM_USB_TCB; i++) - { - if((psIntfAdapter->asUsbTcb[i].urb = - usb_alloc_urb(0, GFP_KERNEL)) == NULL) - { - BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0, "Cant allocate Tx urb for index %d", i); + + for (i = 0; i < MAXIMUM_USB_TCB; i++) { + if ((psIntfAdapter->asUsbTcb[i].urb = + usb_alloc_urb(0, GFP_KERNEL)) == NULL) { + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_PRINTK, 0, 0, "Cant allocate Tx urb for index %d", i); return -ENOMEM; } } - for(i = 0; i < MAXIMUM_USB_RCB; i++) - { + for (i = 0; i < MAXIMUM_USB_RCB; i++) { if ((psIntfAdapter->asUsbRcb[i].urb = - usb_alloc_urb(0, GFP_KERNEL)) == NULL) - { - BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0, "Cant allocate Rx urb for index %d", i); + usb_alloc_urb(0, GFP_KERNEL)) == NULL) { + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_PRINTK, 0, 0, "Cant allocate Rx urb for index %d", i); return -ENOMEM; } - if((psIntfAdapter->asUsbRcb[i].urb->transfer_buffer = - kmalloc(MAX_DATA_BUFFER_SIZE, GFP_KERNEL)) == NULL) - { - BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0, "Cant allocate Rx buffer for index %d", i); + if ((psIntfAdapter->asUsbRcb[i].urb->transfer_buffer = + kmalloc(MAX_DATA_BUFFER_SIZE, GFP_KERNEL)) == NULL) { + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_PRINTK, 0, 0, "Cant allocate Rx buffer for index %d", i); return -ENOMEM; } psIntfAdapter->asUsbRcb[i].urb->transfer_buffer_length = MAX_DATA_BUFFER_SIZE; @@ -331,37 +310,33 @@ static int AllocUsbCb(PS_INTERFACE_ADAPTER psIntfAdapter) return 0; } - - static int device_run(PS_INTERFACE_ADAPTER psIntfAdapter) { int value = 0; UINT status = STATUS_SUCCESS; status = InitCardAndDownloadFirmware(psIntfAdapter->psAdapter); - if(status != STATUS_SUCCESS) - { + if (status != STATUS_SUCCESS) { pr_err(DRV_NAME "InitCardAndDownloadFirmware failed.\n"); return status; } - if(TRUE == psIntfAdapter->psAdapter->fw_download_done) - { - if(StartInterruptUrb(psIntfAdapter)) - { - BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Cannot send interrupt in URB"); + if (TRUE == psIntfAdapter->psAdapter->fw_download_done) { + if (StartInterruptUrb(psIntfAdapter)) { + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Cannot send interrupt in URB"); } - //now register the cntrl interface. - //after downloading the f/w waiting for 5 sec to get the mailbox interrupt. + /* + * now register the cntrl interface. + * after downloading the f/w waiting for 5 sec to get the mailbox interrupt. + */ psIntfAdapter->psAdapter->waiting_to_fw_download_done = FALSE; value = wait_event_timeout(psIntfAdapter->psAdapter->ioctl_fw_dnld_wait_queue, psIntfAdapter->psAdapter->waiting_to_fw_download_done, 5*HZ); - if(value == 0) + if (value == 0) pr_err(DRV_NAME ": Mailbox Interrupt has not reached to Driver..\n"); - if(register_control_device_interface(psIntfAdapter->psAdapter) < 0) - { + if (register_control_device_interface(psIntfAdapter->psAdapter) < 0) { pr_err(DRV_NAME ": Register Control Device failed...\n"); return -EIO; } @@ -462,13 +437,12 @@ static int InterfaceAdapterInit(PS_INTERFACE_ADAPTER psIntfAdapter) psIntfAdapter->psAdapter->interface_rdm = BcmRDM; psIntfAdapter->psAdapter->interface_wrm = BcmWRM; - if(rdmalt(psIntfAdapter->psAdapter, CHIP_ID_REG, (PUINT)&(psIntfAdapter->psAdapter->chip_id), sizeof(UINT)) < 0) - { - BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0, "CHIP ID Read Failed\n"); + if (rdmalt(psIntfAdapter->psAdapter, CHIP_ID_REG, (PUINT)&(psIntfAdapter->psAdapter->chip_id), sizeof(UINT)) < 0) { + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_PRINTK, 0, 0, "CHIP ID Read Failed\n"); return STATUS_FAILURE; } - if(0xbece3200==(psIntfAdapter->psAdapter->chip_id&~(0xF0))) + if (0xbece3200 == (psIntfAdapter->psAdapter->chip_id & ~(0xF0))) psIntfAdapter->psAdapter->chip_id &= ~0xF0; dev_info(&psIntfAdapter->udev->dev, "RDM Chip ID 0x%lx\n", @@ -476,80 +450,70 @@ static int InterfaceAdapterInit(PS_INTERFACE_ADAPTER psIntfAdapter) iface_desc = psIntfAdapter->interface->cur_altsetting; - if(psIntfAdapter->psAdapter->chip_id == T3B) - { - // - //T3B device will have EEPROM,check if EEPROM is proper and BCM16 can be done or not. - // - BeceemEEPROMBulkRead(psIntfAdapter->psAdapter,&uiData,0x0,4); - if(uiData == BECM) + if (psIntfAdapter->psAdapter->chip_id == T3B) { + /* T3B device will have EEPROM, check if EEPROM is proper and BCM16 can be done or not. */ + BeceemEEPROMBulkRead(psIntfAdapter->psAdapter, &uiData, 0x0, 4); + if (uiData == BECM) bBcm16 = TRUE; dev_info(&psIntfAdapter->udev->dev, "number of alternate setting %d\n", psIntfAdapter->interface->num_altsetting); - if(bBcm16 == TRUE) - { - //selecting alternate setting one as a default setting for High Speed modem. - if(psIntfAdapter->bHighSpeedDevice) - retval= usb_set_interface(psIntfAdapter->udev,DEFAULT_SETTING_0,ALTERNATE_SETTING_1); - BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "BCM16 is Applicable on this dongle"); - if(retval || (psIntfAdapter->bHighSpeedDevice == FALSE)) - { + if (bBcm16 == TRUE) { + /* selecting alternate setting one as a default setting for High Speed modem. */ + if (psIntfAdapter->bHighSpeedDevice) + retval= usb_set_interface(psIntfAdapter->udev, DEFAULT_SETTING_0, ALTERNATE_SETTING_1); + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "BCM16 is Applicable on this dongle"); + if (retval || (psIntfAdapter->bHighSpeedDevice == FALSE)) { usedIntOutForBulkTransfer = EP2 ; endpoint = &iface_desc->endpoint[EP2].desc; - BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Interface altsetting got failed or Moemd is configured to FS.hence will work on default setting 0 \n"); + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Interface altsetting got failed or Moemd is configured to FS.hence will work on default setting 0 \n"); /* - If Modem is high speed device EP2 should be INT OUT End point - If Mode is FS then EP2 should be bulk end point - */ - if(((psIntfAdapter->bHighSpeedDevice ==TRUE ) && (bcm_usb_endpoint_is_int_out(endpoint)== FALSE)) - ||((psIntfAdapter->bHighSpeedDevice == FALSE)&& (bcm_usb_endpoint_is_bulk_out(endpoint)== FALSE))) - { - BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL,"Configuring the EEPROM "); - //change the EP2, EP4 to INT OUT end point + * If Modem is high speed device EP2 should be INT OUT End point + * If Mode is FS then EP2 should be bulk end point + */ + if (((psIntfAdapter->bHighSpeedDevice == TRUE) && (bcm_usb_endpoint_is_int_out(endpoint) == FALSE)) + || ((psIntfAdapter->bHighSpeedDevice == FALSE) && (bcm_usb_endpoint_is_bulk_out(endpoint) == FALSE))) { + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Configuring the EEPROM "); + /* change the EP2, EP4 to INT OUT end point */ ConfigureEndPointTypesThroughEEPROM(psIntfAdapter->psAdapter); /* - It resets the device and if any thing gets changed in USB descriptor it will show fail and - re-enumerate the device - */ + * It resets the device and if any thing gets changed + * in USB descriptor it will show fail and re-enumerate + * the device + */ retval = usb_reset_device(psIntfAdapter->udev); - if(retval) - { - BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "reset got failed. hence Re-enumerating the device \n"); + if (retval) { + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "reset got failed. hence Re-enumerating the device \n"); return retval ; } } - if((psIntfAdapter->bHighSpeedDevice == FALSE) && bcm_usb_endpoint_is_bulk_out(endpoint)) - { - // Once BULK is selected in FS mode. Revert it back to INT. Else USB_IF will fail. + if ((psIntfAdapter->bHighSpeedDevice == FALSE) && bcm_usb_endpoint_is_bulk_out(endpoint)) { + /* Once BULK is selected in FS mode. Revert it back to INT. Else USB_IF will fail. */ UINT _uiData = ntohl(EP2_CFG_INT); - BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL,"Reverting Bulk to INT as it is FS MODE"); - BeceemEEPROMBulkWrite(psIntfAdapter->psAdapter,(PUCHAR)&_uiData,0x136,4,TRUE); + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Reverting Bulk to INT as it is FS MODE"); + BeceemEEPROMBulkWrite(psIntfAdapter->psAdapter, (PUCHAR)&_uiData, 0x136, 4, TRUE); } - } - else - { + } else { usedIntOutForBulkTransfer = EP4 ; endpoint = &iface_desc->endpoint[EP4].desc; - BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Choosing AltSetting as a default setting"); - if( bcm_usb_endpoint_is_int_out(endpoint) == FALSE) - { - BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, " Dongle does not have BCM16 Fix"); - //change the EP2, EP4 to INT OUT end point and use EP4 in altsetting + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Choosing AltSetting as a default setting"); + if (bcm_usb_endpoint_is_int_out(endpoint) == FALSE) { + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, " Dongle does not have BCM16 Fix"); + /* change the EP2, EP4 to INT OUT end point and use EP4 in altsetting */ ConfigureEndPointTypesThroughEEPROM(psIntfAdapter->psAdapter); /* - It resets the device and if any thing gets changed in USB descriptor it will show fail and - re-enumerate the device - */ + * It resets the device and if any thing gets changed in + * USB descriptor it will show fail and re-enumerate the + * device + */ retval = usb_reset_device(psIntfAdapter->udev); - if(retval) - { - BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "reset got failed. hence Re-enumerating the device \n"); - return retval ; + if (retval) { + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "reset got failed. hence Re-enumerating the device \n"); + return retval; } } @@ -559,84 +523,65 @@ static int InterfaceAdapterInit(PS_INTERFACE_ADAPTER psIntfAdapter) iface_desc = psIntfAdapter->interface->cur_altsetting; - for (value = 0; value < iface_desc->desc.bNumEndpoints; ++value) - { + for (value = 0; value < iface_desc->desc.bNumEndpoints; ++value) { endpoint = &iface_desc->endpoint[value].desc; - if (!psIntfAdapter->sBulkIn.bulk_in_endpointAddr && bcm_usb_endpoint_is_bulk_in(endpoint)) - { - buffer_size = le16_to_cpu(endpoint->wMaxPacketSize); - psIntfAdapter->sBulkIn.bulk_in_size = buffer_size; - psIntfAdapter->sBulkIn.bulk_in_endpointAddr = - endpoint->bEndpointAddress; - psIntfAdapter->sBulkIn.bulk_in_pipe = + if (!psIntfAdapter->sBulkIn.bulk_in_endpointAddr && bcm_usb_endpoint_is_bulk_in(endpoint)) { + buffer_size = le16_to_cpu(endpoint->wMaxPacketSize); + psIntfAdapter->sBulkIn.bulk_in_size = buffer_size; + psIntfAdapter->sBulkIn.bulk_in_endpointAddr = endpoint->bEndpointAddress; + psIntfAdapter->sBulkIn.bulk_in_pipe = usb_rcvbulkpipe(psIntfAdapter->udev, psIntfAdapter->sBulkIn.bulk_in_endpointAddr); - } - - if (!psIntfAdapter->sBulkOut.bulk_out_endpointAddr && bcm_usb_endpoint_is_bulk_out(endpoint)) - { + } - psIntfAdapter->sBulkOut.bulk_out_endpointAddr = - endpoint->bEndpointAddress; - psIntfAdapter->sBulkOut.bulk_out_pipe = - usb_sndbulkpipe(psIntfAdapter->udev, - psIntfAdapter->sBulkOut.bulk_out_endpointAddr); - } - - if (!psIntfAdapter->sIntrIn.int_in_endpointAddr && bcm_usb_endpoint_is_int_in(endpoint)) - { - buffer_size = le16_to_cpu(endpoint->wMaxPacketSize); - psIntfAdapter->sIntrIn.int_in_size = buffer_size; - psIntfAdapter->sIntrIn.int_in_endpointAddr = - endpoint->bEndpointAddress; - psIntfAdapter->sIntrIn.int_in_interval = endpoint->bInterval; - psIntfAdapter->sIntrIn.int_in_buffer = - kmalloc(buffer_size, GFP_KERNEL); - if (!psIntfAdapter->sIntrIn.int_in_buffer) { - dev_err(&psIntfAdapter->udev->dev, - "could not allocate interrupt_in_buffer\n"); - return -EINVAL; - } - } - - if (!psIntfAdapter->sIntrOut.int_out_endpointAddr && bcm_usb_endpoint_is_int_out(endpoint)) - { - - if( !psIntfAdapter->sBulkOut.bulk_out_endpointAddr && - (psIntfAdapter->psAdapter->chip_id == T3B) && (value == usedIntOutForBulkTransfer)) - { - //use first intout end point as a bulk out end point - buffer_size = le16_to_cpu(endpoint->wMaxPacketSize); - psIntfAdapter->sBulkOut.bulk_out_size = buffer_size; - //printk("\nINT OUT Endpoing buffer size :%x endpoint :%x\n", buffer_size, value +1); - psIntfAdapter->sBulkOut.bulk_out_endpointAddr = - endpoint->bEndpointAddress; - psIntfAdapter->sBulkOut.bulk_out_pipe = - usb_sndintpipe(psIntfAdapter->udev, + if (!psIntfAdapter->sBulkOut.bulk_out_endpointAddr && bcm_usb_endpoint_is_bulk_out(endpoint)) { + psIntfAdapter->sBulkOut.bulk_out_endpointAddr = endpoint->bEndpointAddress; + psIntfAdapter->sBulkOut.bulk_out_pipe = + usb_sndbulkpipe(psIntfAdapter->udev, psIntfAdapter->sBulkOut.bulk_out_endpointAddr); - psIntfAdapter->sBulkOut.int_out_interval = endpoint->bInterval; + } - } - else if(value == EP6) - { - buffer_size = le16_to_cpu(endpoint->wMaxPacketSize); - psIntfAdapter->sIntrOut.int_out_size = buffer_size; - psIntfAdapter->sIntrOut.int_out_endpointAddr = - endpoint->bEndpointAddress; - psIntfAdapter->sIntrOut.int_out_interval = endpoint->bInterval; - psIntfAdapter->sIntrOut.int_out_buffer= kmalloc(buffer_size, - GFP_KERNEL); - if (!psIntfAdapter->sIntrOut.int_out_buffer) - { + if (!psIntfAdapter->sIntrIn.int_in_endpointAddr && bcm_usb_endpoint_is_int_in(endpoint)) { + buffer_size = le16_to_cpu(endpoint->wMaxPacketSize); + psIntfAdapter->sIntrIn.int_in_size = buffer_size; + psIntfAdapter->sIntrIn.int_in_endpointAddr = endpoint->bEndpointAddress; + psIntfAdapter->sIntrIn.int_in_interval = endpoint->bInterval; + psIntfAdapter->sIntrIn.int_in_buffer = + kmalloc(buffer_size, GFP_KERNEL); + if (!psIntfAdapter->sIntrIn.int_in_buffer) { dev_err(&psIntfAdapter->udev->dev, - "could not allocate interrupt_out_buffer\n"); + "could not allocate interrupt_in_buffer\n"); + return -EINVAL; + } + } + + if (!psIntfAdapter->sIntrOut.int_out_endpointAddr && bcm_usb_endpoint_is_int_out(endpoint)) { + if (!psIntfAdapter->sBulkOut.bulk_out_endpointAddr && + (psIntfAdapter->psAdapter->chip_id == T3B) && (value == usedIntOutForBulkTransfer)) { + /* use first intout end point as a bulk out end point */ + buffer_size = le16_to_cpu(endpoint->wMaxPacketSize); + psIntfAdapter->sBulkOut.bulk_out_size = buffer_size; + psIntfAdapter->sBulkOut.bulk_out_endpointAddr = endpoint->bEndpointAddress; + psIntfAdapter->sBulkOut.bulk_out_pipe = usb_sndintpipe(psIntfAdapter->udev, + psIntfAdapter->sBulkOut.bulk_out_endpointAddr); + psIntfAdapter->sBulkOut.int_out_interval = endpoint->bInterval; + } else if (value == EP6) { + buffer_size = le16_to_cpu(endpoint->wMaxPacketSize); + psIntfAdapter->sIntrOut.int_out_size = buffer_size; + psIntfAdapter->sIntrOut.int_out_endpointAddr = endpoint->bEndpointAddress; + psIntfAdapter->sIntrOut.int_out_interval = endpoint->bInterval; + psIntfAdapter->sIntrOut.int_out_buffer= kmalloc(buffer_size, GFP_KERNEL); + if (!psIntfAdapter->sIntrOut.int_out_buffer) { + dev_err(&psIntfAdapter->udev->dev, + "could not allocate interrupt_out_buffer\n"); return -EINVAL; + } } - } - } + } } - usb_set_intfdata(psIntfAdapter->interface, psIntfAdapter); + + usb_set_intfdata(psIntfAdapter->interface, psIntfAdapter); psIntfAdapter->psAdapter->bcm_file_download = InterfaceFileDownload; psIntfAdapter->psAdapter->bcm_file_readback_from_chip = @@ -645,58 +590,51 @@ static int InterfaceAdapterInit(PS_INTERFACE_ADAPTER psIntfAdapter) retval = CreateInterruptUrb(psIntfAdapter); - if(retval) - { - BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0, "Cannot create interrupt urb"); + if (retval) { + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_PRINTK, 0, 0, "Cannot create interrupt urb"); return retval; } retval = AllocUsbCb(psIntfAdapter); - if(retval) - { + if (retval) { return retval; } - return device_run(psIntfAdapter); } -static int InterfaceSuspend (struct usb_interface *intf, pm_message_t message) +static int InterfaceSuspend(struct usb_interface *intf, pm_message_t message) { PS_INTERFACE_ADAPTER psIntfAdapter = usb_get_intfdata(intf); psIntfAdapter->bSuspended = TRUE; - if(TRUE == psIntfAdapter->bPreparingForBusSuspend) - { + if (TRUE == psIntfAdapter->bPreparingForBusSuspend) { psIntfAdapter->bPreparingForBusSuspend = FALSE; - if(psIntfAdapter->psAdapter->LinkStatus == LINKUP_DONE) - { + if (psIntfAdapter->psAdapter->LinkStatus == LINKUP_DONE) { psIntfAdapter->psAdapter->IdleMode = TRUE ; - BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Host Entered in PMU Idle Mode.."); - } - else - { + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Host Entered in PMU Idle Mode.."); + } else { psIntfAdapter->psAdapter->bShutStatus = TRUE; - BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Host Entered in PMU Shutdown Mode.."); + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Host Entered in PMU Shutdown Mode.."); } } psIntfAdapter->psAdapter->bPreparingForLowPowerMode = FALSE; - //Signaling the control pkt path + /* Signaling the control pkt path */ wake_up(&psIntfAdapter->psAdapter->lowpower_mode_wait_queue); return 0; } -static int InterfaceResume (struct usb_interface *intf) +static int InterfaceResume(struct usb_interface *intf) { - PS_INTERFACE_ADAPTER psIntfAdapter = usb_get_intfdata(intf); + PS_INTERFACE_ADAPTER psIntfAdapter = usb_get_intfdata(intf); printk("=================================\n"); mdelay(100); #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 32) - intf->pm_usage_cnt =1 ; + intf->pm_usage_cnt =1 ; #endif psIntfAdapter->bSuspended = FALSE; @@ -706,18 +644,17 @@ static int InterfaceResume (struct usb_interface *intf) } static struct usb_driver usbbcm_driver = { - .name = "usbbcm", - .probe = usbbcm_device_probe, - .disconnect = usbbcm_disconnect, - .suspend = InterfaceSuspend, - .resume = InterfaceResume, - .id_table = InterfaceUsbtable, - .supports_autosuspend = 1, + .name = "usbbcm", + .probe = usbbcm_device_probe, + .disconnect = usbbcm_disconnect, + .suspend = InterfaceSuspend, + .resume = InterfaceResume, + .id_table = InterfaceUsbtable, + .supports_autosuspend = 1, }; struct class *bcm_class; - static __init int bcm_init(void) { printk(KERN_INFO "%s: %s, %s\n", DRV_NAME, DRV_DESCRIPTION, DRV_VERSION); @@ -734,7 +671,7 @@ static __init int bcm_init(void) static __exit void bcm_exit(void) { - class_destroy (bcm_class); + class_destroy(bcm_class); usb_deregister(&usbbcm_driver); } @@ -744,4 +681,4 @@ module_exit(bcm_exit); MODULE_DESCRIPTION(DRV_DESCRIPTION); MODULE_VERSION(DRV_VERSION); -MODULE_LICENSE ("GPL"); +MODULE_LICENSE("GPL"); -- cgit v1.2.3 From cd0b0ebfbe134b9c98fa8e628732b0e41b2cb48c Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Mon, 6 Dec 2010 10:02:36 +0300 Subject: Staging: Beceem: remove old kernel compatibility code This drops compatability for everything from 2.4 to 2.6.35. Now it only works on the latest kernel. Signed-off-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/InterfaceInit.c | 15 +-------------- drivers/staging/bcm/InterfaceTx.c | 11 ----------- drivers/staging/bcm/Misc.c | 2 -- drivers/staging/bcm/headers.h | 2 -- 4 files changed, 1 insertion(+), 29 deletions(-) diff --git a/drivers/staging/bcm/InterfaceInit.c b/drivers/staging/bcm/InterfaceInit.c index 844e5faacca0..dd829409a8c8 100644 --- a/drivers/staging/bcm/InterfaceInit.c +++ b/drivers/staging/bcm/InterfaceInit.c @@ -235,25 +235,14 @@ usbbcm_device_probe(struct usb_interface *intf, const struct usb_device_id *id) #ifdef CONFIG_PM udev->autosuspend_delay = 0; intf->needs_remote_wakeup = 1; -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 35) - udev->autosuspend_disabled = 0; -#else usb_enable_autosuspend(udev); -#endif device_init_wakeup(&intf->dev, 1); -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 32) - usb_autopm_disable(intf); -#endif INIT_WORK(&psIntfAdapter->usbSuspendWork, putUsbSuspend); BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Enabling USB Auto-Suspend\n"); #endif } else { intf->needs_remote_wakeup = 0; -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 35) - udev->autosuspend_disabled = 1; -#else usb_disable_autosuspend(udev); -#endif } } @@ -633,9 +622,7 @@ static int InterfaceResume(struct usb_interface *intf) PS_INTERFACE_ADAPTER psIntfAdapter = usb_get_intfdata(intf); printk("=================================\n"); mdelay(100); -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 32) - intf->pm_usage_cnt =1 ; -#endif + psIntfAdapter->bSuspended = FALSE; StartInterruptUrb(psIntfAdapter); diff --git a/drivers/staging/bcm/InterfaceTx.c b/drivers/staging/bcm/InterfaceTx.c index f434b899a0d0..a842de9de6b5 100644 --- a/drivers/staging/bcm/InterfaceTx.c +++ b/drivers/staging/bcm/InterfaceTx.c @@ -102,13 +102,8 @@ static void write_bulk_callback(struct urb *urb/*, struct pt_regs *regs*/) } err_exit : -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 35) - usb_buffer_free(urb->dev, urb->transfer_buffer_length, - urb->transfer_buffer, urb->transfer_dma); -#else usb_free_coherent(urb->dev, urb->transfer_buffer_length, urb->transfer_buffer, urb->transfer_dma); -#endif } @@ -139,14 +134,8 @@ static int TransmitTcb(PS_INTERFACE_ADAPTER psIntfAdapter, PUSB_TCB pTcb, PVOID struct urb *urb = pTcb->urb; int retval = 0; -#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 35) - urb->transfer_buffer = usb_buffer_alloc(psIntfAdapter->udev, len, - GFP_ATOMIC, &urb->transfer_dma); -#else urb->transfer_buffer = usb_alloc_coherent(psIntfAdapter->udev, len, GFP_ATOMIC, &urb->transfer_dma); -#endif - if (!urb->transfer_buffer) { BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0, "Error allocating memory\n"); diff --git a/drivers/staging/bcm/Misc.c b/drivers/staging/bcm/Misc.c index 9588fbe101d9..f585aae9cf8b 100644 --- a/drivers/staging/bcm/Misc.c +++ b/drivers/staging/bcm/Misc.c @@ -233,9 +233,7 @@ static int BcmFileDownload(PMINI_ADAPTER Adapter,/**< Logical Adapter */ goto exit_download; } oldfs=get_fs();set_fs(get_ds()); -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) vfs_llseek(flp, 0, 0); -#endif set_fs(oldfs); if(Adapter->bcm_file_readback_from_chip(Adapter->pvInterfaceAdapter, flp, loc)) diff --git a/drivers/staging/bcm/headers.h b/drivers/staging/bcm/headers.h index 473f11eebf7c..1148e5e22eb9 100644 --- a/drivers/staging/bcm/headers.h +++ b/drivers/staging/bcm/headers.h @@ -35,9 +35,7 @@ #include #include #include -#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) #include -#endif #include #include #include -- cgit v1.2.3 From 6b74705e15d5c87181008f1ac984df7faaad55c9 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Mon, 6 Dec 2010 10:02:55 +0300 Subject: Staging: Beceem: use after free in bcm_exit() We can't call class_destroy() until after the driver has been deregistered. It leads to a NULL deref on module unload. Signed-off-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/InterfaceInit.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/staging/bcm/InterfaceInit.c b/drivers/staging/bcm/InterfaceInit.c index dd829409a8c8..b4d22562d060 100644 --- a/drivers/staging/bcm/InterfaceInit.c +++ b/drivers/staging/bcm/InterfaceInit.c @@ -658,9 +658,8 @@ static __init int bcm_init(void) static __exit void bcm_exit(void) { - class_destroy(bcm_class); - usb_deregister(&usbbcm_driver); + class_destroy(bcm_class); } module_init(bcm_init); -- cgit v1.2.3 From 07a7f68800a490bc1140de778e196f66ef4596d9 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Mon, 6 Dec 2010 10:03:13 +0300 Subject: Staging: Beceem: improve debug printk statements These are just small changes. Some grammar and wording changes. I added new lines to the end of all the print statements. Signed-off-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/InterfaceInit.c | 66 ++++++++++++++++++++++++------------- 1 file changed, 43 insertions(+), 23 deletions(-) diff --git a/drivers/staging/bcm/InterfaceInit.c b/drivers/staging/bcm/InterfaceInit.c index b4d22562d060..d236b2a054e5 100644 --- a/drivers/staging/bcm/InterfaceInit.c +++ b/drivers/staging/bcm/InterfaceInit.c @@ -40,7 +40,7 @@ static void InterfaceAdapterFree(PS_INTERFACE_ADAPTER psIntfAdapter) */ while (psIntfAdapter->psAdapter->DeviceAccess) { BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, - "Device is being Accessed \n"); + "Device is being accessed.\n"); msleep(100); } /* Free interrupt URB */ @@ -96,7 +96,8 @@ static void ConfigureEndPointTypesThroughEEPROM(PMINI_ADAPTER Adapter) /* Program TX EP as interrupt(Alternate Setting) */ if (rdmalt(Adapter, 0x0F0110F8, (PUINT)&ulReg, 4)) { - BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "reading of Tx EP is failing"); + BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, + "reading of Tx EP failed\n"); return; } ulReg |= 0x6; @@ -202,7 +203,8 @@ usbbcm_device_probe(struct usb_interface *intf, const struct usb_device_id *id) psIntfAdapter->interface = intf; usb_set_intfdata(intf, psIntfAdapter); - BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "psIntfAdapter 0x%p", psIntfAdapter); + BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, + "psIntfAdapter 0x%p\n", psIntfAdapter); retval = InterfaceAdapterInit(psIntfAdapter); if (retval) { /* If the Firmware/Cfg File is not present @@ -210,10 +212,12 @@ usbbcm_device_probe(struct usb_interface *intf, const struct usb_device_id *id) * download the files. */ if (-ENOENT == retval) { - BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "File Not Found, Use App to Download\n"); + BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, + "File Not Found. Use app to download.\n"); return STATUS_SUCCESS; } - BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "InterfaceAdapterInit Failed \n"); + BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, + "InterfaceAdapterInit failed.\n"); usb_set_intfdata(intf, NULL); udev = interface_to_usbdev(intf); usb_put_dev(udev); @@ -238,7 +242,8 @@ usbbcm_device_probe(struct usb_interface *intf, const struct usb_device_id *id) usb_enable_autosuspend(udev); device_init_wakeup(&intf->dev, 1); INIT_WORK(&psIntfAdapter->usbSuspendWork, putUsbSuspend); - BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Enabling USB Auto-Suspend\n"); + BCM_DEBUG_PRINT(psAdapter, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, + "Enabling USB Auto-Suspend\n"); #endif } else { intf->needs_remote_wakeup = 0; @@ -278,7 +283,8 @@ static int AllocUsbCb(PS_INTERFACE_ADAPTER psIntfAdapter) for (i = 0; i < MAXIMUM_USB_TCB; i++) { if ((psIntfAdapter->asUsbTcb[i].urb = usb_alloc_urb(0, GFP_KERNEL)) == NULL) { - BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_PRINTK, 0, 0, "Cant allocate Tx urb for index %d", i); + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_PRINTK, 0, 0, + "Can't allocate Tx urb for index %d\n", i); return -ENOMEM; } } @@ -286,12 +292,14 @@ static int AllocUsbCb(PS_INTERFACE_ADAPTER psIntfAdapter) for (i = 0; i < MAXIMUM_USB_RCB; i++) { if ((psIntfAdapter->asUsbRcb[i].urb = usb_alloc_urb(0, GFP_KERNEL)) == NULL) { - BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_PRINTK, 0, 0, "Cant allocate Rx urb for index %d", i); + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_PRINTK, 0, 0, + "Can't allocate Rx urb for index %d\n", i); return -ENOMEM; } if ((psIntfAdapter->asUsbRcb[i].urb->transfer_buffer = kmalloc(MAX_DATA_BUFFER_SIZE, GFP_KERNEL)) == NULL) { - BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_PRINTK, 0, 0, "Cant allocate Rx buffer for index %d", i); + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_PRINTK, 0, 0, + "Can't allocate Rx buffer for index %d\n", i); return -ENOMEM; } psIntfAdapter->asUsbRcb[i].urb->transfer_buffer_length = MAX_DATA_BUFFER_SIZE; @@ -311,7 +319,8 @@ static int device_run(PS_INTERFACE_ADAPTER psIntfAdapter) } if (TRUE == psIntfAdapter->psAdapter->fw_download_done) { if (StartInterruptUrb(psIntfAdapter)) { - BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Cannot send interrupt in URB"); + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, + "Cannot send interrupt in URB\n"); } /* @@ -323,10 +332,10 @@ static int device_run(PS_INTERFACE_ADAPTER psIntfAdapter) psIntfAdapter->psAdapter->waiting_to_fw_download_done, 5*HZ); if (value == 0) - pr_err(DRV_NAME ": Mailbox Interrupt has not reached to Driver..\n"); + pr_err(DRV_NAME ": Timeout waiting for mailbox interrupt.\n"); if (register_control_device_interface(psIntfAdapter->psAdapter) < 0) { - pr_err(DRV_NAME ": Register Control Device failed...\n"); + pr_err(DRV_NAME ": Register Control Device failed.\n"); return -EIO; } } @@ -452,18 +461,21 @@ static int InterfaceAdapterInit(PS_INTERFACE_ADAPTER psIntfAdapter) /* selecting alternate setting one as a default setting for High Speed modem. */ if (psIntfAdapter->bHighSpeedDevice) retval= usb_set_interface(psIntfAdapter->udev, DEFAULT_SETTING_0, ALTERNATE_SETTING_1); - BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "BCM16 is Applicable on this dongle"); + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, + "BCM16 is applicable on this dongle\n"); if (retval || (psIntfAdapter->bHighSpeedDevice == FALSE)) { usedIntOutForBulkTransfer = EP2 ; endpoint = &iface_desc->endpoint[EP2].desc; - BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Interface altsetting got failed or Moemd is configured to FS.hence will work on default setting 0 \n"); + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, + "Interface altsetting failed or modem is configured to Full Speed, hence will work on default setting 0\n"); /* * If Modem is high speed device EP2 should be INT OUT End point * If Mode is FS then EP2 should be bulk end point */ if (((psIntfAdapter->bHighSpeedDevice == TRUE) && (bcm_usb_endpoint_is_int_out(endpoint) == FALSE)) || ((psIntfAdapter->bHighSpeedDevice == FALSE) && (bcm_usb_endpoint_is_bulk_out(endpoint) == FALSE))) { - BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Configuring the EEPROM "); + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, + "Configuring the EEPROM\n"); /* change the EP2, EP4 to INT OUT end point */ ConfigureEndPointTypesThroughEEPROM(psIntfAdapter->psAdapter); @@ -474,7 +486,8 @@ static int InterfaceAdapterInit(PS_INTERFACE_ADAPTER psIntfAdapter) */ retval = usb_reset_device(psIntfAdapter->udev); if (retval) { - BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "reset got failed. hence Re-enumerating the device \n"); + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, + "reset failed. Re-enumerating the device.\n"); return retval ; } @@ -482,15 +495,18 @@ static int InterfaceAdapterInit(PS_INTERFACE_ADAPTER psIntfAdapter) if ((psIntfAdapter->bHighSpeedDevice == FALSE) && bcm_usb_endpoint_is_bulk_out(endpoint)) { /* Once BULK is selected in FS mode. Revert it back to INT. Else USB_IF will fail. */ UINT _uiData = ntohl(EP2_CFG_INT); - BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Reverting Bulk to INT as it is FS MODE"); + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, + "Reverting Bulk to INT as it is in Full Speed mode.\n"); BeceemEEPROMBulkWrite(psIntfAdapter->psAdapter, (PUCHAR)&_uiData, 0x136, 4, TRUE); } } else { usedIntOutForBulkTransfer = EP4 ; endpoint = &iface_desc->endpoint[EP4].desc; - BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Choosing AltSetting as a default setting"); + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, + "Choosing AltSetting as a default setting.\n"); if (bcm_usb_endpoint_is_int_out(endpoint) == FALSE) { - BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, " Dongle does not have BCM16 Fix"); + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, + "Dongle does not have BCM16 Fix.\n"); /* change the EP2, EP4 to INT OUT end point and use EP4 in altsetting */ ConfigureEndPointTypesThroughEEPROM(psIntfAdapter->psAdapter); @@ -501,7 +517,8 @@ static int InterfaceAdapterInit(PS_INTERFACE_ADAPTER psIntfAdapter) */ retval = usb_reset_device(psIntfAdapter->udev); if (retval) { - BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "reset got failed. hence Re-enumerating the device \n"); + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, + "reset failed. Re-enumerating the device.\n"); return retval; } @@ -580,7 +597,8 @@ static int InterfaceAdapterInit(PS_INTERFACE_ADAPTER psIntfAdapter) retval = CreateInterruptUrb(psIntfAdapter); if (retval) { - BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_PRINTK, 0, 0, "Cannot create interrupt urb"); + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_PRINTK, 0, 0, + "Cannot create interrupt urb\n"); return retval; } @@ -603,10 +621,12 @@ static int InterfaceSuspend(struct usb_interface *intf, pm_message_t message) if (psIntfAdapter->psAdapter->LinkStatus == LINKUP_DONE) { psIntfAdapter->psAdapter->IdleMode = TRUE ; - BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Host Entered in PMU Idle Mode.."); + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, + "Host Entered in PMU Idle Mode.\n"); } else { psIntfAdapter->psAdapter->bShutStatus = TRUE; - BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "Host Entered in PMU Shutdown Mode.."); + BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, + "Host Entered in PMU Shutdown Mode.\n"); } } psIntfAdapter->psAdapter->bPreparingForLowPowerMode = FALSE; -- cgit v1.2.3 From 37db526463a5ad1c96cd803d49fddbf069bbf9b9 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Mon, 6 Dec 2010 10:03:38 +0300 Subject: Staging: Beceem: more checkpatch.pl changes to InterfaceInit.c The only checkpatch.pl issues remaining still remaining are line length complaints. Signed-off-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman --- drivers/staging/bcm/InterfaceInit.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/drivers/staging/bcm/InterfaceInit.c b/drivers/staging/bcm/InterfaceInit.c index d236b2a054e5..082b5e5c01e8 100644 --- a/drivers/staging/bcm/InterfaceInit.c +++ b/drivers/staging/bcm/InterfaceInit.c @@ -45,9 +45,7 @@ static void InterfaceAdapterFree(PS_INTERFACE_ADAPTER psIntfAdapter) } /* Free interrupt URB */ /* psIntfAdapter->psAdapter->device_removed = TRUE; */ - if (psIntfAdapter->psInterruptUrb) { - usb_free_urb(psIntfAdapter->psInterruptUrb); - } + usb_free_urb(psIntfAdapter->psInterruptUrb); /* Free transmit URBs */ for (i = 0; i < MAXIMUM_USB_TCB; i++) { @@ -70,6 +68,7 @@ static void InterfaceAdapterFree(PS_INTERFACE_ADAPTER psIntfAdapter) static void ConfigureEndPointTypesThroughEEPROM(PMINI_ADAPTER Adapter) { unsigned long ulReg = 0; + int ret; /* Program EP2 MAX_PKT_SIZE */ ulReg = ntohl(EP2_MPS_REG); @@ -95,7 +94,8 @@ static void ConfigureEndPointTypesThroughEEPROM(PMINI_ADAPTER Adapter) BeceemEEPROMBulkWrite(Adapter, (PUCHAR)&ulReg, 0x140, 4, TRUE); /* Program TX EP as interrupt(Alternate Setting) */ - if (rdmalt(Adapter, 0x0F0110F8, (PUINT)&ulReg, 4)) { + ret = rdmalt(Adapter, 0x0F0110F8, (u32 *)&ulReg, sizeof(u32)); + if (ret) { BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, DRV_ENTRY, DBG_LVL_ALL, "reading of Tx EP failed\n"); return; @@ -227,9 +227,9 @@ usbbcm_device_probe(struct usb_interface *intf, const struct usb_device_id *id) if (psAdapter->chip_id > T3) { uint32_t uiNackZeroLengthInt = 4; - if (wrmalt(psAdapter, DISABLE_USB_ZERO_LEN_INT, &uiNackZeroLengthInt, sizeof(uiNackZeroLengthInt))) { - return -EIO; - } + retval = wrmalt(psAdapter, DISABLE_USB_ZERO_LEN_INT, &uiNackZeroLengthInt, sizeof(uiNackZeroLengthInt)); + if (retval) + return retval; } /* Check whether the USB-Device Supports remote Wake-Up */ @@ -435,9 +435,11 @@ static int InterfaceAdapterInit(PS_INTERFACE_ADAPTER psIntfAdapter) psIntfAdapter->psAdapter->interface_rdm = BcmRDM; psIntfAdapter->psAdapter->interface_wrm = BcmWRM; - if (rdmalt(psIntfAdapter->psAdapter, CHIP_ID_REG, (PUINT)&(psIntfAdapter->psAdapter->chip_id), sizeof(UINT)) < 0) { + retval = rdmalt(psIntfAdapter->psAdapter, CHIP_ID_REG, + (u32 *)&(psIntfAdapter->psAdapter->chip_id), sizeof(u32)); + if (retval) { BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_PRINTK, 0, 0, "CHIP ID Read Failed\n"); - return STATUS_FAILURE; + return retval; } if (0xbece3200 == (psIntfAdapter->psAdapter->chip_id & ~(0xF0))) @@ -603,9 +605,8 @@ static int InterfaceAdapterInit(PS_INTERFACE_ADAPTER psIntfAdapter) } retval = AllocUsbCb(psIntfAdapter); - if (retval) { + if (retval) return retval; - } return device_run(psIntfAdapter); } @@ -640,7 +641,6 @@ static int InterfaceSuspend(struct usb_interface *intf, pm_message_t message) static int InterfaceResume(struct usb_interface *intf) { PS_INTERFACE_ADAPTER psIntfAdapter = usb_get_intfdata(intf); - printk("=================================\n"); mdelay(100); psIntfAdapter->bSuspended = FALSE; -- cgit v1.2.3 From d2aaba455fed75f231fe30fccfd25bcb8d8ff305 Mon Sep 17 00:00:00 2001 From: Hank Janssen Date: Mon, 6 Dec 2010 12:26:44 -0800 Subject: staging: hv: Convert camel case struct fields in vstorage.h to lowercase Convert camel case struct fields in vstorage.h to lowercase Signed-off-by: Abhishek Kane Signed-off-by: Haiyang Zhang Signed-off-by: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/storvsc.c | 133 +++++++++++++++++++++--------------------- drivers/staging/hv/vstorage.h | 106 ++++++++++++++++----------------- 2 files changed, 120 insertions(+), 119 deletions(-) diff --git a/drivers/staging/hv/storvsc.c b/drivers/staging/hv/storvsc.c index 525c8ee46f07..96b4ed986118 100644 --- a/drivers/staging/hv/storvsc.c +++ b/drivers/staging/hv/storvsc.c @@ -204,8 +204,8 @@ static int StorVscChannelInit(struct hv_device *Device) goto nomem; } - vstorPacket->Operation = VStorOperationBeginInitialization; - vstorPacket->Flags = REQUEST_COMPLETION_FLAG; + vstorPacket->operation = VSTOR_OPERATION_BEGIN_INITIALIZATION; + vstorPacket->flags = REQUEST_COMPLETION_FLAG; /*SpinlockAcquire(gDriverExt.packetListLock); INSERT_TAIL_LIST(&gDriverExt.packetList, &packet->listEntry.entry); @@ -226,11 +226,11 @@ static int StorVscChannelInit(struct hv_device *Device) osd_waitevent_wait(request->WaitEvent); - if (vstorPacket->Operation != VStorOperationCompleteIo || - vstorPacket->Status != 0) { + if (vstorPacket->operation != VSTOR_OPERATION_COMPLETE_IO || + vstorPacket->status != 0) { DPRINT_ERR(STORVSC, "BEGIN_INITIALIZATION_OPERATION failed " "(op %d status 0x%x)", - vstorPacket->Operation, vstorPacket->Status); + vstorPacket->operation, vstorPacket->status); goto Cleanup; } @@ -238,11 +238,11 @@ static int StorVscChannelInit(struct hv_device *Device) /* reuse the packet for version range supported */ memset(vstorPacket, 0, sizeof(struct vstor_packet)); - vstorPacket->Operation = VStorOperationQueryProtocolVersion; - vstorPacket->Flags = REQUEST_COMPLETION_FLAG; + vstorPacket->operation = VSTOR_OPERATION_QUERY_PROTOCOL_VERSION; + vstorPacket->flags = REQUEST_COMPLETION_FLAG; - vstorPacket->Version.MajorMinor = VMSTOR_PROTOCOL_VERSION_CURRENT; - FILL_VMSTOR_REVISION(vstorPacket->Version.Revision); + vstorPacket->version.major_minor = VMSTOR_PROTOCOL_VERSION_CURRENT; + FILL_VMSTOR_REVISION(vstorPacket->version.revision); ret = vmbus_sendpacket(Device->channel, vstorPacket, sizeof(struct vstor_packet), @@ -258,11 +258,11 @@ static int StorVscChannelInit(struct hv_device *Device) osd_waitevent_wait(request->WaitEvent); /* TODO: Check returned version */ - if (vstorPacket->Operation != VStorOperationCompleteIo || - vstorPacket->Status != 0) { + if (vstorPacket->operation != VSTOR_OPERATION_COMPLETE_IO || + vstorPacket->status != 0) { DPRINT_ERR(STORVSC, "QUERY_PROTOCOL_VERSION_OPERATION failed " "(op %d status 0x%x)", - vstorPacket->Operation, vstorPacket->Status); + vstorPacket->operation, vstorPacket->status); goto Cleanup; } @@ -270,9 +270,9 @@ static int StorVscChannelInit(struct hv_device *Device) DPRINT_INFO(STORVSC, "QUERY_PROPERTIES_OPERATION..."); memset(vstorPacket, 0, sizeof(struct vstor_packet)); - vstorPacket->Operation = VStorOperationQueryProperties; - vstorPacket->Flags = REQUEST_COMPLETION_FLAG; - vstorPacket->StorageChannelProperties.PortNumber = + vstorPacket->operation = VSTOR_OPERATION_QUERY_PROPERTIES; + vstorPacket->flags = REQUEST_COMPLETION_FLAG; + vstorPacket->storage_channel_properties.port_number = storDevice->PortNumber; ret = vmbus_sendpacket(Device->channel, vstorPacket, @@ -290,26 +290,27 @@ static int StorVscChannelInit(struct hv_device *Device) osd_waitevent_wait(request->WaitEvent); /* TODO: Check returned version */ - if (vstorPacket->Operation != VStorOperationCompleteIo || - vstorPacket->Status != 0) { + if (vstorPacket->operation != VSTOR_OPERATION_COMPLETE_IO || + vstorPacket->status != 0) { DPRINT_ERR(STORVSC, "QUERY_PROPERTIES_OPERATION failed " "(op %d status 0x%x)", - vstorPacket->Operation, vstorPacket->Status); + vstorPacket->operation, vstorPacket->status); goto Cleanup; } - storDevice->PathId = vstorPacket->StorageChannelProperties.PathId; - storDevice->TargetId = vstorPacket->StorageChannelProperties.TargetId; + storDevice->PathId = vstorPacket->storage_channel_properties.path_id; + storDevice->TargetId + = vstorPacket->storage_channel_properties.target_id; DPRINT_DBG(STORVSC, "channel flag 0x%x, max xfer len 0x%x", - vstorPacket->StorageChannelProperties.Flags, - vstorPacket->StorageChannelProperties.MaxTransferBytes); + vstorPacket->storage_channel_properties.flags, + vstorPacket->storage_channel_properties.max_transfer_bytes); DPRINT_INFO(STORVSC, "END_INITIALIZATION_OPERATION..."); memset(vstorPacket, 0, sizeof(struct vstor_packet)); - vstorPacket->Operation = VStorOperationEndInitialization; - vstorPacket->Flags = REQUEST_COMPLETION_FLAG; + vstorPacket->operation = VSTOR_OPERATION_END_INITIALIZATION; + vstorPacket->flags = REQUEST_COMPLETION_FLAG; ret = vmbus_sendpacket(Device->channel, vstorPacket, sizeof(struct vstor_packet), @@ -325,11 +326,11 @@ static int StorVscChannelInit(struct hv_device *Device) osd_waitevent_wait(request->WaitEvent); - if (vstorPacket->Operation != VStorOperationCompleteIo || - vstorPacket->Status != 0) { + if (vstorPacket->operation != VSTOR_OPERATION_COMPLETE_IO || + vstorPacket->status != 0) { DPRINT_ERR(STORVSC, "END_INITIALIZATION_OPERATION failed " "(op %d status 0x%x)", - vstorPacket->Operation, vstorPacket->Status); + vstorPacket->operation, vstorPacket->status); goto Cleanup; } @@ -359,7 +360,7 @@ static void StorVscOnIOCompletion(struct hv_device *Device, DPRINT_DBG(STORVSC, "IO_COMPLETE_OPERATION - request extension %p " "completed bytes xfer %u", RequestExt, - VStorPacket->VmSrb.DataTransferLength); + VStorPacket->vm_srb.data_transfer_length); /* ASSERT(RequestExt != NULL); */ /* ASSERT(RequestExt->Request != NULL); */ @@ -369,36 +370,36 @@ static void StorVscOnIOCompletion(struct hv_device *Device, /* ASSERT(request->OnIOCompletion != NULL); */ /* Copy over the status...etc */ - request->Status = VStorPacket->VmSrb.ScsiStatus; + request->Status = VStorPacket->vm_srb.scsi_status; - if (request->Status != 0 || VStorPacket->VmSrb.SrbStatus != 1) { + if (request->Status != 0 || VStorPacket->vm_srb.srb_status != 1) { DPRINT_WARN(STORVSC, "cmd 0x%x scsi status 0x%x srb status 0x%x\n", - request->Cdb[0], VStorPacket->VmSrb.ScsiStatus, - VStorPacket->VmSrb.SrbStatus); + request->Cdb[0], VStorPacket->vm_srb.scsi_status, + VStorPacket->vm_srb.srb_status); } if ((request->Status & 0xFF) == 0x02) { /* CHECK_CONDITION */ - if (VStorPacket->VmSrb.SrbStatus & 0x80) { + if (VStorPacket->vm_srb.srb_status & 0x80) { /* autosense data available */ DPRINT_WARN(STORVSC, "storvsc pkt %p autosense data " "valid - len %d\n", RequestExt, - VStorPacket->VmSrb.SenseInfoLength); + VStorPacket->vm_srb.sense_info_length); - /* ASSERT(VStorPacket->VmSrb.SenseInfoLength <= */ + /* ASSERT(VStorPacket->vm_srb.sense_info_length <= */ /* request->SenseBufferSize); */ memcpy(request->SenseBuffer, - VStorPacket->VmSrb.SenseData, - VStorPacket->VmSrb.SenseInfoLength); + VStorPacket->vm_srb.sense_data, + VStorPacket->vm_srb.sense_info_length); request->SenseBufferSize = - VStorPacket->VmSrb.SenseInfoLength; + VStorPacket->vm_srb.sense_info_length; } } /* TODO: */ - request->BytesXfer = VStorPacket->VmSrb.DataTransferLength; + request->BytesXfer = VStorPacket->vm_srb.data_transfer_length; request->OnIOCompletion(request); @@ -411,19 +412,19 @@ static void StorVscOnReceive(struct hv_device *Device, struct vstor_packet *VStorPacket, struct storvsc_request_extension *RequestExt) { - switch (VStorPacket->Operation) { - case VStorOperationCompleteIo: + switch (VStorPacket->operation) { + case VSTOR_OPERATION_COMPLETE_IO: DPRINT_DBG(STORVSC, "IO_COMPLETE_OPERATION"); StorVscOnIOCompletion(Device, VStorPacket, RequestExt); break; - case VStorOperationRemoveDevice: + case VSTOR_OPERATION_REMOVE_DEVICE: DPRINT_INFO(STORVSC, "REMOVE_DEVICE_OPERATION"); /* TODO: */ break; default: DPRINT_INFO(STORVSC, "Unknown operation received - %d", - VStorPacket->Operation); + VStorPacket->operation); break; } } @@ -506,7 +507,7 @@ static int StorVscConnectToVsp(struct hv_device *Device) StorVscOnChannelCallback, Device); DPRINT_DBG(STORVSC, "storage props: path id %d, tgt id %d, max xfer %d", - props.PathId, props.TargetId, props.MaxTransferBytes); + props.path_id, props.target_id, props.max_transfer_bytes); if (ret != 0) { DPRINT_ERR(STORVSC, "unable to open channel: %d", ret); @@ -628,9 +629,9 @@ int StorVscOnHostReset(struct hv_device *Device) goto Cleanup; } - vstorPacket->Operation = VStorOperationResetBus; - vstorPacket->Flags = REQUEST_COMPLETION_FLAG; - vstorPacket->VmSrb.PathId = storDevice->PathId; + vstorPacket->operation = VSTOR_OPERATION_RESET_BUS; + vstorPacket->flags = REQUEST_COMPLETION_FLAG; + vstorPacket->vm_srb.path_id = storDevice->PathId; ret = vmbus_sendpacket(Device->channel, vstorPacket, sizeof(struct vstor_packet), @@ -697,35 +698,35 @@ static int StorVscOnIORequest(struct hv_device *Device, memset(vstorPacket, 0 , sizeof(struct vstor_packet)); - vstorPacket->Flags |= REQUEST_COMPLETION_FLAG; + vstorPacket->flags |= REQUEST_COMPLETION_FLAG; - vstorPacket->VmSrb.Length = sizeof(struct vmscsi_request); + vstorPacket->vm_srb.length = sizeof(struct vmscsi_request); - vstorPacket->VmSrb.PortNumber = Request->Host; - vstorPacket->VmSrb.PathId = Request->Bus; - vstorPacket->VmSrb.TargetId = Request->TargetId; - vstorPacket->VmSrb.Lun = Request->LunId; + vstorPacket->vm_srb.port_number = Request->Host; + vstorPacket->vm_srb.path_id = Request->Bus; + vstorPacket->vm_srb.target_id = Request->TargetId; + vstorPacket->vm_srb.lun = Request->LunId; - vstorPacket->VmSrb.SenseInfoLength = SENSE_BUFFER_SIZE; + vstorPacket->vm_srb.sense_info_length = SENSE_BUFFER_SIZE; /* Copy over the scsi command descriptor block */ - vstorPacket->VmSrb.CdbLength = Request->CdbLen; - memcpy(&vstorPacket->VmSrb.Cdb, Request->Cdb, Request->CdbLen); + vstorPacket->vm_srb.cdb_length = Request->CdbLen; + memcpy(&vstorPacket->vm_srb.cdb, Request->Cdb, Request->CdbLen); - vstorPacket->VmSrb.DataIn = Request->Type; - vstorPacket->VmSrb.DataTransferLength = Request->DataBuffer.Length; + vstorPacket->vm_srb.data_in = Request->Type; + vstorPacket->vm_srb.data_transfer_length = Request->DataBuffer.Length; - vstorPacket->Operation = VStorOperationExecuteSRB; + vstorPacket->operation = VSTOR_OPERATION_EXECUTE_SRB; DPRINT_DBG(STORVSC, "srb - len %d port %d, path %d, target %d, " "lun %d senselen %d cdblen %d", - vstorPacket->VmSrb.Length, - vstorPacket->VmSrb.PortNumber, - vstorPacket->VmSrb.PathId, - vstorPacket->VmSrb.TargetId, - vstorPacket->VmSrb.Lun, - vstorPacket->VmSrb.SenseInfoLength, - vstorPacket->VmSrb.CdbLength); + vstorPacket->vm_srb.length, + vstorPacket->vm_srb.port_number, + vstorPacket->vm_srb.path_id, + vstorPacket->vm_srb.target_id, + vstorPacket->vm_srb.lun, + vstorPacket->vm_srb.sense_info_length, + vstorPacket->vm_srb.cdb_length); if (requestExtension->Request->DataBuffer.Length) { ret = vmbus_sendpacket_multipagebuffer(Device->channel, diff --git a/drivers/staging/hv/vstorage.h b/drivers/staging/hv/vstorage.h index 4ea597d7a7d7..ae8be84394d5 100644 --- a/drivers/staging/hv/vstorage.h +++ b/drivers/staging/hv/vstorage.h @@ -27,15 +27,17 @@ #define REVISION_STRING(REVISION_) #REVISION_ #define FILL_VMSTOR_REVISION(RESULT_LVALUE_) \ -{ \ - char *revisionString = REVISION_STRING($Revision : 6 $) + 11; \ - RESULT_LVALUE_ = 0; \ - while (*revisionString >= '0' && *revisionString <= '9') { \ - RESULT_LVALUE_ *= 10; \ - RESULT_LVALUE_ += *revisionString - '0'; \ - revisionString++; \ - } \ -} + do { \ + char *revision_string \ + = REVISION_STRING($Rev : 6 $) + 6; \ + RESULT_LVALUE_ = 0; \ + while (*revision_string >= '0' \ + && *revision_string <= '9') { \ + RESULT_LVALUE_ *= 10; \ + RESULT_LVALUE_ += *revision_string - '0'; \ + revision_string++; \ + } \ + } while (0) /* Major/minor macros. Minor version is in LSB, meaning that earlier flat */ /* version numbers will be interpreted as "0.x" (i.e., 1 becomes 0.1). */ @@ -65,17 +67,17 @@ /* Packet structure describing virtual storage requests. */ enum vstor_packet_operation { - VStorOperationCompleteIo = 1, - VStorOperationRemoveDevice = 2, - VStorOperationExecuteSRB = 3, - VStorOperationResetLun = 4, - VStorOperationResetAdapter = 5, - VStorOperationResetBus = 6, - VStorOperationBeginInitialization = 7, - VStorOperationEndInitialization = 8, - VStorOperationQueryProtocolVersion = 9, - VStorOperationQueryProperties = 10, - VStorOperationMaximum = 10 + VSTOR_OPERATION_COMPLETE_IO = 1, + VSTOR_OPERATION_REMOVE_DEVICE = 2, + VSTOR_OPERATION_EXECUTE_SRB = 3, + VSTOR_OPERATION_RESET_LUN = 4, + VSTOR_OPERATION_RESET_ADAPTER = 5, + VSTOR_OPERATION_RESET_BUS = 6, + VSTOR_OPERATION_BEGIN_INITIALIZATION = 7, + VSTOR_OPERATION_END_INITIALIZATION = 8, + VSTOR_OPERATION_QUERY_PROTOCOL_VERSION = 9, + VSTOR_OPERATION_QUERY_PROPERTIES = 10, + VSTOR_OPERATION_MAXIMUM = 10 }; /* @@ -89,31 +91,29 @@ enum vstor_packet_operation { #define SENSE_BUFFER_SIZE 0x12 #endif -#define MAX_DATA_BUFFER_LENGTH_WITH_PADDING 0x14 +#define MAX_DATA_BUF_LEN_WITH_PADDING 0x14 struct vmscsi_request { - unsigned short Length; - unsigned char SrbStatus; - unsigned char ScsiStatus; + unsigned short length; + unsigned char srb_status; + unsigned char scsi_status; - unsigned char PortNumber; - unsigned char PathId; - unsigned char TargetId; - unsigned char Lun; + unsigned char port_number; + unsigned char path_id; + unsigned char target_id; + unsigned char lun; - unsigned char CdbLength; - unsigned char SenseInfoLength; - unsigned char DataIn; - unsigned char Reserved; + unsigned char cdb_length; + unsigned char sense_info_length; + unsigned char data_in; + unsigned char reserved; - unsigned int DataTransferLength; + unsigned int data_transfer_length; union { - unsigned char Cdb[CDB16GENERIC_LENGTH]; - - unsigned char SenseData[SENSE_BUFFER_SIZE]; - - unsigned char ReservedArray[MAX_DATA_BUFFER_LENGTH_WITH_PADDING]; + unsigned char cdb[CDB16GENERIC_LENGTH]; + unsigned char sense_data[SENSE_BUFFER_SIZE]; + unsigned char reserved_array[MAX_DATA_BUF_LEN_WITH_PADDING]; }; } __attribute((packed)); @@ -123,24 +123,24 @@ struct vmscsi_request { * properties of the channel. */ struct vmstorage_channel_properties { - unsigned short ProtocolVersion; - unsigned char PathId; - unsigned char TargetId; + unsigned short protocol_version; + unsigned char path_id; + unsigned char target_id; /* Note: port number is only really known on the client side */ - unsigned int PortNumber; - unsigned int Flags; - unsigned int MaxTransferBytes; + unsigned int port_number; + unsigned int flags; + unsigned int max_transfer_bytes; /* This id is unique for each channel and will correspond with */ /* vendor specific data in the inquirydata */ - unsigned long long UniqueId; + unsigned long long unique_id; } __attribute__((packed)); /* This structure is sent during the storage protocol negotiations. */ struct vmstorage_protocol_version { /* Major (MSW) and minor (LSW) version numbers. */ - unsigned short MajorMinor; + unsigned short major_minor; /* * Revision number is auto-incremented whenever this file is changed @@ -148,7 +148,7 @@ struct vmstorage_protocol_version { * definitely indicate incompatibility--but it does indicate mismatched * builds. */ - unsigned short Revision; + unsigned short revision; } __attribute__((packed)); /* Channel Property Flags */ @@ -157,13 +157,13 @@ struct vmstorage_protocol_version { struct vstor_packet { /* Requested operation type */ - enum vstor_packet_operation Operation; + enum vstor_packet_operation operation; /* Flags - see below for values */ - unsigned int Flags; + unsigned int flags; /* Status of the request returned from the server side. */ - unsigned int Status; + unsigned int status; /* Data payload area */ union { @@ -171,13 +171,13 @@ struct vstor_packet { * Structure used to forward SCSI commands from the * client to the server. */ - struct vmscsi_request VmSrb; + struct vmscsi_request vm_srb; /* Structure used to query channel properties. */ - struct vmstorage_channel_properties StorageChannelProperties; + struct vmstorage_channel_properties storage_channel_properties; /* Used during version negotiations. */ - struct vmstorage_protocol_version Version; + struct vmstorage_protocol_version version; }; } __attribute__((packed)); -- cgit v1.2.3 From 8a046024a7cbbe9e4c16f4e34dda0f0dbcbc6723 Mon Sep 17 00:00:00 2001 From: Hank Janssen Date: Mon, 6 Dec 2010 12:26:45 -0800 Subject: staging: hv: Convert camel case struct fields in storvsc_api.h to lowercase Convert camel case struct fields in vstorage.h to lowercase Signed-off-by: Abhishek Kane Signed-off-by: Haiyang Zhang Signed-off-by: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/blkvsc.c | 20 +++---- drivers/staging/hv/blkvsc_drv.c | 115 ++++++++++++++++++++------------------- drivers/staging/hv/storvsc.c | 67 ++++++++++++----------- drivers/staging/hv/storvsc_api.h | 50 ++++++++--------- drivers/staging/hv/storvsc_drv.c | 91 ++++++++++++++++--------------- 5 files changed, 175 insertions(+), 168 deletions(-) diff --git a/drivers/staging/hv/blkvsc.c b/drivers/staging/hv/blkvsc.c index d5b0abd771ab..9ac04c385b15 100644 --- a/drivers/staging/hv/blkvsc.c +++ b/drivers/staging/hv/blkvsc.c @@ -51,12 +51,12 @@ static int BlkVscOnDeviceAdd(struct hv_device *Device, void *AdditionalInfo) * id. For IDE devices, the device instance id is formatted as * * - - 8899 - 000000000000. */ - deviceInfo->PathId = Device->deviceInstance.data[3] << 24 | + deviceInfo->path_id = Device->deviceInstance.data[3] << 24 | Device->deviceInstance.data[2] << 16 | Device->deviceInstance.data[1] << 8 | Device->deviceInstance.data[0]; - deviceInfo->TargetId = Device->deviceInstance.data[5] << 8 | + deviceInfo->target_id = Device->deviceInstance.data[5] << 8 | Device->deviceInstance.data[4]; return ret; @@ -75,7 +75,7 @@ int BlkVscInitialize(struct hv_driver *Driver) Driver->name = gBlkDriverName; memcpy(&Driver->deviceType, &gBlkVscDeviceType, sizeof(struct hv_guid)); - storDriver->RequestExtSize = sizeof(struct storvsc_request_extension); + storDriver->request_ext_size = sizeof(struct storvsc_request_extension); /* * Divide the ring buffer data size (which is 1 page less than the ring @@ -83,20 +83,20 @@ int BlkVscInitialize(struct hv_driver *Driver) * by the max request size (which is * vmbus_channel_packet_multipage_buffer + struct vstor_packet + u64) */ - storDriver->MaxOutstandingRequestsPerChannel = - ((storDriver->RingBufferSize - PAGE_SIZE) / + storDriver->max_outstanding_req_per_channel = + ((storDriver->ring_buffer_size - PAGE_SIZE) / ALIGN_UP(MAX_MULTIPAGE_BUFFER_PACKET + sizeof(struct vstor_packet) + sizeof(u64), sizeof(u64))); DPRINT_INFO(BLKVSC, "max io outstd %u", - storDriver->MaxOutstandingRequestsPerChannel); + storDriver->max_outstanding_req_per_channel); /* Setup the dispatch table */ - storDriver->Base.OnDeviceAdd = BlkVscOnDeviceAdd; - storDriver->Base.OnDeviceRemove = StorVscOnDeviceRemove; - storDriver->Base.OnCleanup = StorVscOnCleanup; - storDriver->OnIORequest = StorVscOnIORequest; + storDriver->base.OnDeviceAdd = BlkVscOnDeviceAdd; + storDriver->base.OnDeviceRemove = StorVscOnDeviceRemove; + storDriver->base.OnCleanup = StorVscOnCleanup; + storDriver->on_io_request = StorVscOnIORequest; return ret; } diff --git a/drivers/staging/hv/blkvsc_drv.c b/drivers/staging/hv/blkvsc_drv.c index 3f81ca591064..d65d69e3ebc2 100644 --- a/drivers/staging/hv/blkvsc_drv.c +++ b/drivers/staging/hv/blkvsc_drv.c @@ -177,13 +177,13 @@ static int blkvsc_drv_init(int (*drv_init)(struct hv_driver *drv)) struct driver_context *drv_ctx = &g_blkvsc_drv.drv_ctx; int ret; - storvsc_drv_obj->RingBufferSize = blkvsc_ringbuffer_size; + storvsc_drv_obj->ring_buffer_size = blkvsc_ringbuffer_size; /* Callback to client driver to complete the initialization */ - drv_init(&storvsc_drv_obj->Base); + drv_init(&storvsc_drv_obj->base); - drv_ctx->driver.name = storvsc_drv_obj->Base.name; - memcpy(&drv_ctx->class_id, &storvsc_drv_obj->Base.deviceType, + drv_ctx->driver.name = storvsc_drv_obj->base.name; + memcpy(&drv_ctx->class_id, &storvsc_drv_obj->base.deviceType, sizeof(struct hv_guid)); drv_ctx->probe = blkvsc_probe; @@ -230,8 +230,8 @@ static void blkvsc_drv_exit(void) device_unregister(current_dev); } - if (storvsc_drv_obj->Base.OnCleanup) - storvsc_drv_obj->Base.OnCleanup(&storvsc_drv_obj->Base); + if (storvsc_drv_obj->base.OnCleanup) + storvsc_drv_obj->base.OnCleanup(&storvsc_drv_obj->base); vmbus_child_driver_unregister(drv_ctx); @@ -262,7 +262,7 @@ static int blkvsc_probe(struct device *device) DPRINT_DBG(BLKVSC_DRV, "blkvsc_probe - enter"); - if (!storvsc_drv_obj->Base.OnDeviceAdd) { + if (!storvsc_drv_obj->base.OnDeviceAdd) { DPRINT_ERR(BLKVSC_DRV, "OnDeviceAdd() not set"); ret = -1; goto Cleanup; @@ -284,7 +284,7 @@ static int blkvsc_probe(struct device *device) blkdev->request_pool = kmem_cache_create(dev_name(&device_ctx->device), sizeof(struct blkvsc_request) + - storvsc_drv_obj->RequestExtSize, 0, + storvsc_drv_obj->request_ext_size, 0, SLAB_HWCACHE_ALIGN, NULL); if (!blkdev->request_pool) { ret = -ENOMEM; @@ -293,7 +293,7 @@ static int blkvsc_probe(struct device *device) /* Call to the vsc driver to add the device */ - ret = storvsc_drv_obj->Base.OnDeviceAdd(device_obj, &device_info); + ret = storvsc_drv_obj->base.OnDeviceAdd(device_obj, &device_info); if (ret != 0) { DPRINT_ERR(BLKVSC_DRV, "unable to add blkvsc device"); goto Cleanup; @@ -301,9 +301,9 @@ static int blkvsc_probe(struct device *device) blkdev->device_ctx = device_ctx; /* this identified the device 0 or 1 */ - blkdev->target = device_info.TargetId; + blkdev->target = device_info.target_id; /* this identified the ide ctrl 0 or 1 */ - blkdev->path = device_info.PathId; + blkdev->path = device_info.path_id; dev_set_drvdata(device, blkdev); @@ -391,7 +391,7 @@ static int blkvsc_probe(struct device *device) return ret; Remove: - storvsc_drv_obj->Base.OnDeviceRemove(device_obj); + storvsc_drv_obj->base.OnDeviceRemove(device_obj); Cleanup: if (blkdev) { @@ -459,9 +459,9 @@ static int blkvsc_do_flush(struct block_device_context *blkdev) blkvsc_req->req = NULL; blkvsc_req->write = 0; - blkvsc_req->request.DataBuffer.PfnArray[0] = 0; - blkvsc_req->request.DataBuffer.Offset = 0; - blkvsc_req->request.DataBuffer.Length = 0; + blkvsc_req->request.data_buffer.PfnArray[0] = 0; + blkvsc_req->request.data_buffer.Offset = 0; + blkvsc_req->request.data_buffer.Length = 0; blkvsc_req->cmnd[0] = SYNCHRONIZE_CACHE; blkvsc_req->cmd_len = 10; @@ -506,9 +506,9 @@ static int blkvsc_do_inquiry(struct block_device_context *blkdev) blkvsc_req->req = NULL; blkvsc_req->write = 0; - blkvsc_req->request.DataBuffer.PfnArray[0] = page_to_pfn(page_buf); - blkvsc_req->request.DataBuffer.Offset = 0; - blkvsc_req->request.DataBuffer.Length = 64; + blkvsc_req->request.data_buffer.PfnArray[0] = page_to_pfn(page_buf); + blkvsc_req->request.data_buffer.Offset = 0; + blkvsc_req->request.data_buffer.Length = 64; blkvsc_req->cmnd[0] = INQUIRY; blkvsc_req->cmnd[1] = 0x1; /* Get product data */ @@ -593,9 +593,9 @@ static int blkvsc_do_read_capacity(struct block_device_context *blkdev) blkvsc_req->req = NULL; blkvsc_req->write = 0; - blkvsc_req->request.DataBuffer.PfnArray[0] = page_to_pfn(page_buf); - blkvsc_req->request.DataBuffer.Offset = 0; - blkvsc_req->request.DataBuffer.Length = 8; + blkvsc_req->request.data_buffer.PfnArray[0] = page_to_pfn(page_buf); + blkvsc_req->request.data_buffer.Offset = 0; + blkvsc_req->request.data_buffer.Length = 8; blkvsc_req->cmnd[0] = READ_CAPACITY; blkvsc_req->cmd_len = 16; @@ -614,7 +614,7 @@ static int blkvsc_do_read_capacity(struct block_device_context *blkdev) wait_event_interruptible(blkvsc_req->wevent, blkvsc_req->cond); /* check error */ - if (blkvsc_req->request.Status) { + if (blkvsc_req->request.status) { scsi_normalize_sense(blkvsc_req->sense_buffer, SCSI_SENSE_BUFFERSIZE, &sense_hdr); @@ -670,9 +670,9 @@ static int blkvsc_do_read_capacity16(struct block_device_context *blkdev) blkvsc_req->req = NULL; blkvsc_req->write = 0; - blkvsc_req->request.DataBuffer.PfnArray[0] = page_to_pfn(page_buf); - blkvsc_req->request.DataBuffer.Offset = 0; - blkvsc_req->request.DataBuffer.Length = 12; + blkvsc_req->request.data_buffer.PfnArray[0] = page_to_pfn(page_buf); + blkvsc_req->request.data_buffer.Offset = 0; + blkvsc_req->request.data_buffer.Length = 12; blkvsc_req->cmnd[0] = 0x9E; /* READ_CAPACITY16; */ blkvsc_req->cmd_len = 16; @@ -691,7 +691,7 @@ static int blkvsc_do_read_capacity16(struct block_device_context *blkdev) wait_event_interruptible(blkvsc_req->wevent, blkvsc_req->cond); /* check error */ - if (blkvsc_req->request.Status) { + if (blkvsc_req->request.status) { scsi_normalize_sense(blkvsc_req->sense_buffer, SCSI_SENSE_BUFFERSIZE, &sense_hdr); if (sense_hdr.asc == 0x3A) { @@ -741,14 +741,14 @@ static int blkvsc_remove(struct device *device) DPRINT_DBG(BLKVSC_DRV, "blkvsc_remove()\n"); - if (!storvsc_drv_obj->Base.OnDeviceRemove) + if (!storvsc_drv_obj->base.OnDeviceRemove) return -1; /* * Call to the vsc driver to let it know that the device is being * removed */ - ret = storvsc_drv_obj->Base.OnDeviceRemove(device_obj); + ret = storvsc_drv_obj->base.OnDeviceRemove(device_obj); if (ret != 0) { /* TODO: */ DPRINT_ERR(BLKVSC_DRV, @@ -865,38 +865,38 @@ static int blkvsc_submit_request(struct blkvsc_request *blkvsc_req, (blkvsc_req->write) ? "WRITE" : "READ", (unsigned long) blkvsc_req->sector_start, blkvsc_req->sector_count, - blkvsc_req->request.DataBuffer.Offset, - blkvsc_req->request.DataBuffer.Length); + blkvsc_req->request.data_buffer.Offset, + blkvsc_req->request.data_buffer.Length); #if 0 - for (i = 0; i < (blkvsc_req->request.DataBuffer.Length >> 12); i++) { + for (i = 0; i < (blkvsc_req->request.data_buffer.Length >> 12); i++) { DPRINT_DBG(BLKVSC_DRV, "blkvsc_submit_request() - " "req %p pfn[%d] %llx\n", blkvsc_req, i, - blkvsc_req->request.DataBuffer.PfnArray[i]); + blkvsc_req->request.data_buffer.PfnArray[i]); } #endif storvsc_req = &blkvsc_req->request; - storvsc_req->Extension = (void *)((unsigned long)blkvsc_req + + storvsc_req->extension = (void *)((unsigned long)blkvsc_req + sizeof(struct blkvsc_request)); - storvsc_req->Type = blkvsc_req->write ? WRITE_TYPE : READ_TYPE; + storvsc_req->type = blkvsc_req->write ? WRITE_TYPE : READ_TYPE; - storvsc_req->OnIOCompletion = request_completion; - storvsc_req->Context = blkvsc_req; + storvsc_req->on_io_completion = request_completion; + storvsc_req->context = blkvsc_req; - storvsc_req->Host = blkdev->port; - storvsc_req->Bus = blkdev->path; - storvsc_req->TargetId = blkdev->target; - storvsc_req->LunId = 0; /* this is not really used at all */ + storvsc_req->host = blkdev->port; + storvsc_req->bus = blkdev->path; + storvsc_req->target_id = blkdev->target; + storvsc_req->lun_id = 0; /* this is not really used at all */ - storvsc_req->CdbLen = blkvsc_req->cmd_len; - storvsc_req->Cdb = blkvsc_req->cmnd; + storvsc_req->cdb_len = blkvsc_req->cmd_len; + storvsc_req->cdb = blkvsc_req->cmnd; - storvsc_req->SenseBuffer = blkvsc_req->sense_buffer; - storvsc_req->SenseBufferSize = SCSI_SENSE_BUFFERSIZE; + storvsc_req->sense_buffer = blkvsc_req->sense_buffer; + storvsc_req->sense_buffer_size = SCSI_SENSE_BUFFERSIZE; - ret = storvsc_drv_obj->OnIORequest(&blkdev->device_ctx->device_obj, + ret = storvsc_drv_obj->on_io_request(&blkdev->device_ctx->device_obj, &blkvsc_req->request); if (ret == 0) blkdev->num_outstanding_reqs++; @@ -992,8 +992,10 @@ static int blkvsc_do_request(struct block_device_context *blkdev, blkvsc_req->dev = blkdev; blkvsc_req->req = req; - blkvsc_req->request.DataBuffer.Offset = bvec->bv_offset; - blkvsc_req->request.DataBuffer.Length = 0; + blkvsc_req->request.data_buffer.Offset + = bvec->bv_offset; + blkvsc_req->request.data_buffer.Length + = 0; /* Add to the group */ blkvsc_req->group = group; @@ -1007,8 +1009,11 @@ static int blkvsc_do_request(struct block_device_context *blkdev, } /* Add the curr bvec/segment to the curr blkvsc_req */ - blkvsc_req->request.DataBuffer.PfnArray[databuf_idx] = page_to_pfn(bvec->bv_page); - blkvsc_req->request.DataBuffer.Length += bvec->bv_len; + blkvsc_req->request.data_buffer. + PfnArray[databuf_idx] + = page_to_pfn(bvec->bv_page); + blkvsc_req->request.data_buffer.Length + += bvec->bv_len; prev_bvec = bvec; @@ -1073,7 +1078,7 @@ static int blkvsc_do_request(struct block_device_context *blkdev, static void blkvsc_cmd_completion(struct hv_storvsc_request *request) { struct blkvsc_request *blkvsc_req = - (struct blkvsc_request *)request->Context; + (struct blkvsc_request *)request->context; struct block_device_context *blkdev = (struct block_device_context *)blkvsc_req->dev; struct scsi_sense_hdr sense_hdr; @@ -1083,7 +1088,7 @@ static void blkvsc_cmd_completion(struct hv_storvsc_request *request) blkdev->num_outstanding_reqs--; - if (blkvsc_req->request.Status) + if (blkvsc_req->request.status) if (scsi_normalize_sense(blkvsc_req->sense_buffer, SCSI_SENSE_BUFFERSIZE, &sense_hdr)) scsi_print_sense_hdr("blkvsc", &sense_hdr); @@ -1095,7 +1100,7 @@ static void blkvsc_cmd_completion(struct hv_storvsc_request *request) static void blkvsc_request_completion(struct hv_storvsc_request *request) { struct blkvsc_request *blkvsc_req = - (struct blkvsc_request *)request->Context; + (struct blkvsc_request *)request->context; struct block_device_context *blkdev = (struct block_device_context *)blkvsc_req->dev; unsigned long flags; @@ -1110,7 +1115,7 @@ static void blkvsc_request_completion(struct hv_storvsc_request *request) (blkvsc_req->write) ? "WRITE" : "READ", (unsigned long)blkvsc_req->sector_start, blkvsc_req->sector_count, - blkvsc_req->request.DataBuffer.Length, + blkvsc_req->request.data_buffer.Length, blkvsc_req->group->outstanding, blkdev->num_outstanding_reqs); @@ -1137,7 +1142,7 @@ static void blkvsc_request_completion(struct hv_storvsc_request *request) list_del(&comp_req->req_entry); if (!__blk_end_request(comp_req->req, - (!comp_req->request.Status ? 0 : -EIO), + (!comp_req->request.status ? 0 : -EIO), comp_req->sector_count * blkdev->sector_size)) { /* * All the sectors have been xferred ie the @@ -1195,7 +1200,7 @@ static int blkvsc_cancel_pending_reqs(struct block_device_context *blkdev) if (comp_req->req) { ret = __blk_end_request(comp_req->req, - (!comp_req->request.Status ? 0 : -EIO), + (!comp_req->request.status ? 0 : -EIO), comp_req->sector_count * blkdev->sector_size); diff --git a/drivers/staging/hv/storvsc.c b/drivers/staging/hv/storvsc.c index 96b4ed986118..c4346c63ed56 100644 --- a/drivers/staging/hv/storvsc.c +++ b/drivers/staging/hv/storvsc.c @@ -370,16 +370,16 @@ static void StorVscOnIOCompletion(struct hv_device *Device, /* ASSERT(request->OnIOCompletion != NULL); */ /* Copy over the status...etc */ - request->Status = VStorPacket->vm_srb.scsi_status; + request->status = VStorPacket->vm_srb.scsi_status; - if (request->Status != 0 || VStorPacket->vm_srb.srb_status != 1) { + if (request->status != 0 || VStorPacket->vm_srb.srb_status != 1) { DPRINT_WARN(STORVSC, "cmd 0x%x scsi status 0x%x srb status 0x%x\n", - request->Cdb[0], VStorPacket->vm_srb.scsi_status, + request->cdb[0], VStorPacket->vm_srb.scsi_status, VStorPacket->vm_srb.srb_status); } - if ((request->Status & 0xFF) == 0x02) { + if ((request->status & 0xFF) == 0x02) { /* CHECK_CONDITION */ if (VStorPacket->vm_srb.srb_status & 0x80) { /* autosense data available */ @@ -389,19 +389,19 @@ static void StorVscOnIOCompletion(struct hv_device *Device, /* ASSERT(VStorPacket->vm_srb.sense_info_length <= */ /* request->SenseBufferSize); */ - memcpy(request->SenseBuffer, + memcpy(request->sense_buffer, VStorPacket->vm_srb.sense_data, VStorPacket->vm_srb.sense_info_length); - request->SenseBufferSize = + request->sense_buffer_size = VStorPacket->vm_srb.sense_info_length; } } /* TODO: */ - request->BytesXfer = VStorPacket->vm_srb.data_transfer_length; + request->bytes_xfer = VStorPacket->vm_srb.data_transfer_length; - request->OnIOCompletion(request); + request->on_io_completion(request); atomic_dec(&storDevice->NumOutstandingRequests); @@ -501,7 +501,8 @@ static int StorVscConnectToVsp(struct hv_device *Device) /* Open the channel */ ret = vmbus_open(Device->channel, - storDriver->RingBufferSize, storDriver->RingBufferSize, + storDriver->ring_buffer_size, + storDriver->ring_buffer_size, (void *)&props, sizeof(struct vmstorage_channel_properties), StorVscOnChannelCallback, Device); @@ -551,13 +552,13 @@ static int StorVscOnDeviceAdd(struct hv_device *Device, void *AdditionalInfo) storChannel->PathId = props->PathId; storChannel->TargetId = props->TargetId; */ - storDevice->PortNumber = deviceInfo->PortNumber; + storDevice->PortNumber = deviceInfo->port_number; /* Send it back up */ ret = StorVscConnectToVsp(Device); /* deviceInfo->PortNumber = storDevice->PortNumber; */ - deviceInfo->PathId = storDevice->PathId; - deviceInfo->TargetId = storDevice->TargetId; + deviceInfo->path_id = storDevice->PathId; + deviceInfo->target_id = storDevice->TargetId; DPRINT_DBG(STORVSC, "assigned port %u, path %u target %u\n", storDevice->PortNumber, storDevice->PathId, @@ -672,7 +673,7 @@ static int StorVscOnIORequest(struct hv_device *Device, int ret = 0; requestExtension = - (struct storvsc_request_extension *)Request->Extension; + (struct storvsc_request_extension *)Request->extension; vstorPacket = &requestExtension->VStorPacket; storDevice = GetStorDevice(Device); @@ -681,8 +682,8 @@ static int StorVscOnIORequest(struct hv_device *Device, requestExtension); DPRINT_DBG(STORVSC, "req %p len %d bus %d, target %d, lun %d cdblen %d", - Request, Request->DataBuffer.Length, Request->Bus, - Request->TargetId, Request->LunId, Request->CdbLen); + Request, Request->data_buffer.Length, Request->bus, + Request->target_id, Request->lun_id, Request->cdb_len); if (!storDevice) { DPRINT_ERR(STORVSC, "unable to get stor device..." @@ -702,19 +703,19 @@ static int StorVscOnIORequest(struct hv_device *Device, vstorPacket->vm_srb.length = sizeof(struct vmscsi_request); - vstorPacket->vm_srb.port_number = Request->Host; - vstorPacket->vm_srb.path_id = Request->Bus; - vstorPacket->vm_srb.target_id = Request->TargetId; - vstorPacket->vm_srb.lun = Request->LunId; + vstorPacket->vm_srb.port_number = Request->host; + vstorPacket->vm_srb.path_id = Request->bus; + vstorPacket->vm_srb.target_id = Request->target_id; + vstorPacket->vm_srb.lun = Request->lun_id; vstorPacket->vm_srb.sense_info_length = SENSE_BUFFER_SIZE; /* Copy over the scsi command descriptor block */ - vstorPacket->vm_srb.cdb_length = Request->CdbLen; - memcpy(&vstorPacket->vm_srb.cdb, Request->Cdb, Request->CdbLen); + vstorPacket->vm_srb.cdb_length = Request->cdb_len; + memcpy(&vstorPacket->vm_srb.cdb, Request->cdb, Request->cdb_len); - vstorPacket->vm_srb.data_in = Request->Type; - vstorPacket->vm_srb.data_transfer_length = Request->DataBuffer.Length; + vstorPacket->vm_srb.data_in = Request->type; + vstorPacket->vm_srb.data_transfer_length = Request->data_buffer.Length; vstorPacket->operation = VSTOR_OPERATION_EXECUTE_SRB; @@ -728,9 +729,9 @@ static int StorVscOnIORequest(struct hv_device *Device, vstorPacket->vm_srb.sense_info_length, vstorPacket->vm_srb.cdb_length); - if (requestExtension->Request->DataBuffer.Length) { + if (requestExtension->Request->data_buffer.Length) { ret = vmbus_sendpacket_multipagebuffer(Device->channel, - &requestExtension->Request->DataBuffer, + &requestExtension->Request->data_buffer, vstorPacket, sizeof(struct vstor_packet), (unsigned long)requestExtension); @@ -785,7 +786,7 @@ int StorVscInitialize(struct hv_driver *Driver) memcpy(&Driver->deviceType, &gStorVscDeviceType, sizeof(struct hv_guid)); - storDriver->RequestExtSize = sizeof(struct storvsc_request_extension); + storDriver->request_ext_size = sizeof(struct storvsc_request_extension); /* * Divide the ring buffer data size (which is 1 page less @@ -793,22 +794,22 @@ int StorVscInitialize(struct hv_driver *Driver) * the ring buffer indices) by the max request size (which is * vmbus_channel_packet_multipage_buffer + struct vstor_packet + u64) */ - storDriver->MaxOutstandingRequestsPerChannel = - ((storDriver->RingBufferSize - PAGE_SIZE) / + storDriver->max_outstanding_req_per_channel = + ((storDriver->ring_buffer_size - PAGE_SIZE) / ALIGN_UP(MAX_MULTIPAGE_BUFFER_PACKET + sizeof(struct vstor_packet) + sizeof(u64), sizeof(u64))); DPRINT_INFO(STORVSC, "max io %u, currently %u\n", - storDriver->MaxOutstandingRequestsPerChannel, + storDriver->max_outstanding_req_per_channel, STORVSC_MAX_IO_REQUESTS); /* Setup the dispatch table */ - storDriver->Base.OnDeviceAdd = StorVscOnDeviceAdd; - storDriver->Base.OnDeviceRemove = StorVscOnDeviceRemove; - storDriver->Base.OnCleanup = StorVscOnCleanup; + storDriver->base.OnDeviceAdd = StorVscOnDeviceAdd; + storDriver->base.OnDeviceRemove = StorVscOnDeviceRemove; + storDriver->base.OnCleanup = StorVscOnCleanup; - storDriver->OnIORequest = StorVscOnIORequest; + storDriver->on_io_request = StorVscOnIORequest; return 0; } diff --git a/drivers/staging/hv/storvsc_api.h b/drivers/staging/hv/storvsc_api.h index 8505a1c5f9ee..46f031e0afc6 100644 --- a/drivers/staging/hv/storvsc_api.h +++ b/drivers/staging/hv/storvsc_api.h @@ -53,58 +53,58 @@ enum storvsc_request_type{ }; struct hv_storvsc_request { - enum storvsc_request_type Type; - u32 Host; - u32 Bus; - u32 TargetId; - u32 LunId; - u8 *Cdb; - u32 CdbLen; - u32 Status; - u32 BytesXfer; + enum storvsc_request_type type; + u32 host; + u32 bus; + u32 target_id; + u32 lun_id; + u8 *cdb; + u32 cdb_len; + u32 status; + u32 bytes_xfer; - unsigned char *SenseBuffer; - u32 SenseBufferSize; + unsigned char *sense_buffer; + u32 sense_buffer_size; - void *Context; + void *context; - void (*OnIOCompletion)(struct hv_storvsc_request *Request); + void (*on_io_completion)(struct hv_storvsc_request *request); /* This points to the memory after DataBuffer */ - void *Extension; + void *extension; - struct hv_multipage_buffer DataBuffer; + struct hv_multipage_buffer data_buffer; }; /* Represents the block vsc driver */ struct storvsc_driver_object { /* Must be the first field */ /* Which is a bug FIXME! */ - struct hv_driver Base; + struct hv_driver base; /* Set by caller (in bytes) */ - u32 RingBufferSize; + u32 ring_buffer_size; /* Allocate this much private extension for each I/O request */ - u32 RequestExtSize; + u32 request_ext_size; /* Maximum # of requests in flight per channel/device */ - u32 MaxOutstandingRequestsPerChannel; + u32 max_outstanding_req_per_channel; /* Specific to this driver */ - int (*OnIORequest)(struct hv_device *Device, - struct hv_storvsc_request *Request); + int (*on_io_request)(struct hv_device *device, + struct hv_storvsc_request *request); }; struct storvsc_device_info { - unsigned int PortNumber; - unsigned char PathId; - unsigned char TargetId; + unsigned int port_number; + unsigned char path_id; + unsigned char target_id; }; /* Interface */ int StorVscInitialize(struct hv_driver *driver); -int StorVscOnHostReset(struct hv_device *Device); +int StorVscOnHostReset(struct hv_device *device); int BlkVscInitialize(struct hv_driver *driver); #endif /* _STORVSC_API_H_ */ diff --git a/drivers/staging/hv/storvsc_drv.c b/drivers/staging/hv/storvsc_drv.c index 41d9acf4cd61..68a8853fa9ca 100644 --- a/drivers/staging/hv/storvsc_drv.c +++ b/drivers/staging/hv/storvsc_drv.c @@ -141,28 +141,28 @@ static int storvsc_drv_init(int (*drv_init)(struct hv_driver *drv)) struct storvsc_driver_object *storvsc_drv_obj = &g_storvsc_drv.drv_obj; struct driver_context *drv_ctx = &g_storvsc_drv.drv_ctx; - storvsc_drv_obj->RingBufferSize = storvsc_ringbuffer_size; + storvsc_drv_obj->ring_buffer_size = storvsc_ringbuffer_size; /* Callback to client driver to complete the initialization */ - drv_init(&storvsc_drv_obj->Base); + drv_init(&storvsc_drv_obj->base); DPRINT_INFO(STORVSC_DRV, "request extension size %u, max outstanding reqs %u", - storvsc_drv_obj->RequestExtSize, - storvsc_drv_obj->MaxOutstandingRequestsPerChannel); + storvsc_drv_obj->request_ext_size, + storvsc_drv_obj->max_outstanding_req_per_channel); - if (storvsc_drv_obj->MaxOutstandingRequestsPerChannel < + if (storvsc_drv_obj->max_outstanding_req_per_channel < STORVSC_MAX_IO_REQUESTS) { DPRINT_ERR(STORVSC_DRV, "The number of outstanding io requests (%d) " "is larger than that supported (%d) internally.", STORVSC_MAX_IO_REQUESTS, - storvsc_drv_obj->MaxOutstandingRequestsPerChannel); + storvsc_drv_obj->max_outstanding_req_per_channel); return -1; } - drv_ctx->driver.name = storvsc_drv_obj->Base.name; - memcpy(&drv_ctx->class_id, &storvsc_drv_obj->Base.deviceType, + drv_ctx->driver.name = storvsc_drv_obj->base.name; + memcpy(&drv_ctx->class_id, &storvsc_drv_obj->base.deviceType, sizeof(struct hv_guid)); drv_ctx->probe = storvsc_probe; @@ -207,8 +207,8 @@ static void storvsc_drv_exit(void) device_unregister(current_dev); } - if (storvsc_drv_obj->Base.OnCleanup) - storvsc_drv_obj->Base.OnCleanup(&storvsc_drv_obj->Base); + if (storvsc_drv_obj->base.OnCleanup) + storvsc_drv_obj->base.OnCleanup(&storvsc_drv_obj->base); vmbus_child_driver_unregister(drv_ctx); return; @@ -232,7 +232,7 @@ static int storvsc_probe(struct device *device) struct host_device_context *host_device_ctx; struct storvsc_device_info device_info; - if (!storvsc_drv_obj->Base.OnDeviceAdd) + if (!storvsc_drv_obj->base.OnDeviceAdd) return -1; host = scsi_host_alloc(&scsi_driver, @@ -253,7 +253,7 @@ static int storvsc_probe(struct device *device) host_device_ctx->request_pool = kmem_cache_create(dev_name(&device_ctx->device), sizeof(struct storvsc_cmd_request) + - storvsc_drv_obj->RequestExtSize, 0, + storvsc_drv_obj->request_ext_size, 0, SLAB_HWCACHE_ALIGN, NULL); if (!host_device_ctx->request_pool) { @@ -261,9 +261,9 @@ static int storvsc_probe(struct device *device) return -ENOMEM; } - device_info.PortNumber = host->host_no; + device_info.port_number = host->host_no; /* Call to the vsc driver to add the device */ - ret = storvsc_drv_obj->Base.OnDeviceAdd(device_obj, + ret = storvsc_drv_obj->base.OnDeviceAdd(device_obj, (void *)&device_info); if (ret != 0) { DPRINT_ERR(STORVSC_DRV, "unable to add scsi vsc device"); @@ -273,8 +273,8 @@ static int storvsc_probe(struct device *device) } /* host_device_ctx->port = device_info.PortNumber; */ - host_device_ctx->path = device_info.PathId; - host_device_ctx->target = device_info.TargetId; + host_device_ctx->path = device_info.path_id; + host_device_ctx->target = device_info.target_id; /* max # of devices per target */ host->max_lun = STORVSC_MAX_LUNS_PER_TARGET; @@ -288,7 +288,7 @@ static int storvsc_probe(struct device *device) if (ret != 0) { DPRINT_ERR(STORVSC_DRV, "unable to add scsi host device"); - storvsc_drv_obj->Base.OnDeviceRemove(device_obj); + storvsc_drv_obj->base.OnDeviceRemove(device_obj); kmem_cache_destroy(host_device_ctx->request_pool); scsi_host_put(host); @@ -318,14 +318,14 @@ static int storvsc_remove(struct device *device) (struct host_device_context *)host->hostdata; - if (!storvsc_drv_obj->Base.OnDeviceRemove) + if (!storvsc_drv_obj->base.OnDeviceRemove) return -1; /* * Call to the vsc driver to let it know that the device is being * removed */ - ret = storvsc_drv_obj->Base.OnDeviceRemove(device_obj); + ret = storvsc_drv_obj->base.OnDeviceRemove(device_obj); if (ret != 0) { /* TODO: */ DPRINT_ERR(STORVSC, "unable to remove vsc device (ret %d)", @@ -351,7 +351,7 @@ static int storvsc_remove(struct device *device) static void storvsc_commmand_completion(struct hv_storvsc_request *request) { struct storvsc_cmd_request *cmd_request = - (struct storvsc_cmd_request *)request->Context; + (struct storvsc_cmd_request *)request->context; struct scsi_cmnd *scmnd = cmd_request->cmd; struct host_device_context *host_device_ctx = (struct host_device_context *)scmnd->device->host->hostdata; @@ -376,16 +376,17 @@ static void storvsc_commmand_completion(struct hv_storvsc_request *request) cmd_request->bounce_sgl_count); } - scmnd->result = request->Status; + scmnd->result = request->status; if (scmnd->result) { if (scsi_normalize_sense(scmnd->sense_buffer, - request->SenseBufferSize, &sense_hdr)) + request->sense_buffer_size, &sense_hdr)) scsi_print_sense_hdr("storvsc", &sense_hdr); } - /* ASSERT(request->BytesXfer <= request->DataBuffer.Length); */ - scsi_set_resid(scmnd, request->DataBuffer.Length - request->BytesXfer); + /* ASSERT(request->BytesXfer <= request->data_buffer.Length); */ + scsi_set_resid(scmnd, + request->data_buffer.Length - request->bytes_xfer); scsi_done_fn = scmnd->scsi_done; @@ -658,42 +659,42 @@ static int storvsc_queuecommand(struct scsi_cmnd *scmnd, request = &cmd_request->request; - request->Extension = + request->extension = (void *)((unsigned long)cmd_request + request_size); DPRINT_DBG(STORVSC_DRV, "req %p size %d ext %d", request, request_size, - storvsc_drv_obj->RequestExtSize); + storvsc_drv_obj->request_ext_size); /* Build the SRB */ switch (scmnd->sc_data_direction) { case DMA_TO_DEVICE: - request->Type = WRITE_TYPE; + request->type = WRITE_TYPE; break; case DMA_FROM_DEVICE: - request->Type = READ_TYPE; + request->type = READ_TYPE; break; default: - request->Type = UNKNOWN_TYPE; + request->type = UNKNOWN_TYPE; break; } - request->OnIOCompletion = storvsc_commmand_completion; - request->Context = cmd_request;/* scmnd; */ + request->on_io_completion = storvsc_commmand_completion; + request->context = cmd_request;/* scmnd; */ /* request->PortId = scmnd->device->channel; */ - request->Host = host_device_ctx->port; - request->Bus = scmnd->device->channel; - request->TargetId = scmnd->device->id; - request->LunId = scmnd->device->lun; + request->host = host_device_ctx->port; + request->bus = scmnd->device->channel; + request->target_id = scmnd->device->id; + request->lun_id = scmnd->device->lun; /* ASSERT(scmnd->cmd_len <= 16); */ - request->CdbLen = scmnd->cmd_len; - request->Cdb = scmnd->cmnd; + request->cdb_len = scmnd->cmd_len; + request->cdb = scmnd->cmnd; - request->SenseBuffer = scmnd->sense_buffer; - request->SenseBufferSize = SCSI_SENSE_BUFFERSIZE; + request->sense_buffer = scmnd->sense_buffer; + request->sense_buffer_size = SCSI_SENSE_BUFFERSIZE; - request->DataBuffer.Length = scsi_bufflen(scmnd); + request->data_buffer.Length = scsi_bufflen(scmnd); if (scsi_sg_count(scmnd)) { sgl = (struct scatterlist *)scsi_sglist(scmnd); sg_count = scsi_sg_count(scmnd); @@ -734,25 +735,25 @@ static int storvsc_queuecommand(struct scsi_cmnd *scmnd, sg_count = cmd_request->bounce_sgl_count; } - request->DataBuffer.Offset = sgl[0].offset; + request->data_buffer.Offset = sgl[0].offset; for (i = 0; i < sg_count; i++) { DPRINT_DBG(STORVSC_DRV, "sgl[%d] len %d offset %d\n", i, sgl[i].length, sgl[i].offset); - request->DataBuffer.PfnArray[i] = + request->data_buffer.PfnArray[i] = page_to_pfn(sg_page((&sgl[i]))); } } else if (scsi_sglist(scmnd)) { /* ASSERT(scsi_bufflen(scmnd) <= PAGE_SIZE); */ - request->DataBuffer.Offset = + request->data_buffer.Offset = virt_to_phys(scsi_sglist(scmnd)) & (PAGE_SIZE-1); - request->DataBuffer.PfnArray[0] = + request->data_buffer.PfnArray[0] = virt_to_phys(scsi_sglist(scmnd)) >> PAGE_SHIFT; } retry_request: /* Invokes the vsc to start an IO */ - ret = storvsc_drv_obj->OnIORequest(&device_ctx->device_obj, + ret = storvsc_drv_obj->on_io_request(&device_ctx->device_obj, &cmd_request->request); if (ret == -1) { /* no more space */ -- cgit v1.2.3 From eb4f3e0aa6bef825b964159923e38a0e4c027084 Mon Sep 17 00:00:00 2001 From: Hank Janssen Date: Mon, 6 Dec 2010 12:26:46 -0800 Subject: staging: hv: Convert camel case functions in storvsc_api.h to lowercase Convert camel case functions in storvsc_api.h to lowercase Signed-off-by: Abhishek Kane Signed-off-by: Haiyang Zhang Signed-off-by: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/blkvsc.c | 2 +- drivers/staging/hv/blkvsc_drv.c | 2 +- drivers/staging/hv/storvsc.c | 6 +++--- drivers/staging/hv/storvsc_api.h | 6 +++--- drivers/staging/hv/storvsc_drv.c | 4 ++-- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/staging/hv/blkvsc.c b/drivers/staging/hv/blkvsc.c index 9ac04c385b15..e62c922f11cb 100644 --- a/drivers/staging/hv/blkvsc.c +++ b/drivers/staging/hv/blkvsc.c @@ -62,7 +62,7 @@ static int BlkVscOnDeviceAdd(struct hv_device *Device, void *AdditionalInfo) return ret; } -int BlkVscInitialize(struct hv_driver *Driver) +int blk_vsc_initialize(struct hv_driver *Driver) { struct storvsc_driver_object *storDriver; int ret = 0; diff --git a/drivers/staging/hv/blkvsc_drv.c b/drivers/staging/hv/blkvsc_drv.c index d65d69e3ebc2..b3d05fcfe6d2 100644 --- a/drivers/staging/hv/blkvsc_drv.c +++ b/drivers/staging/hv/blkvsc_drv.c @@ -1487,7 +1487,7 @@ static int __init blkvsc_init(void) DPRINT_INFO(BLKVSC_DRV, "Blkvsc initializing...."); - ret = blkvsc_drv_init(BlkVscInitialize); + ret = blkvsc_drv_init(blk_vsc_initialize); return ret; } diff --git a/drivers/staging/hv/storvsc.c b/drivers/staging/hv/storvsc.c index c4346c63ed56..770413183306 100644 --- a/drivers/staging/hv/storvsc.c +++ b/drivers/staging/hv/storvsc.c @@ -605,7 +605,7 @@ static int StorVscOnDeviceRemove(struct hv_device *Device) return 0; } -int StorVscOnHostReset(struct hv_device *Device) +int stor_vsc_on_host_reset(struct hv_device *Device) { struct storvsc_device *storDevice; struct storvsc_request_extension *request; @@ -762,9 +762,9 @@ static void StorVscOnCleanup(struct hv_driver *Driver) } /* - * StorVscInitialize - Main entry point + * stor_vsc_initialize - Main entry point */ -int StorVscInitialize(struct hv_driver *Driver) +int stor_vsc_initialize(struct hv_driver *Driver) { struct storvsc_driver_object *storDriver; diff --git a/drivers/staging/hv/storvsc_api.h b/drivers/staging/hv/storvsc_api.h index 46f031e0afc6..fbf57556d890 100644 --- a/drivers/staging/hv/storvsc_api.h +++ b/drivers/staging/hv/storvsc_api.h @@ -103,8 +103,8 @@ struct storvsc_device_info { }; /* Interface */ -int StorVscInitialize(struct hv_driver *driver); -int StorVscOnHostReset(struct hv_device *device); -int BlkVscInitialize(struct hv_driver *driver); +int stor_vsc_initialize(struct hv_driver *driver); +int stor_vsc_on_host_reset(struct hv_device *device); +int blk_vsc_initialize(struct hv_driver *driver); #endif /* _STORVSC_API_H_ */ diff --git a/drivers/staging/hv/storvsc_drv.c b/drivers/staging/hv/storvsc_drv.c index 68a8853fa9ca..b8c5cdde324a 100644 --- a/drivers/staging/hv/storvsc_drv.c +++ b/drivers/staging/hv/storvsc_drv.c @@ -844,7 +844,7 @@ static int storvsc_host_reset_handler(struct scsi_cmnd *scmnd) scmnd->device, &device_ctx->device_obj); /* Invokes the vsc to reset the host/bus */ - ret = StorVscOnHostReset(&device_ctx->device_obj); + ret = stor_vsc_on_host_reset(&device_ctx->device_obj); if (ret != 0) return ret; @@ -939,7 +939,7 @@ static int __init storvsc_init(void) int ret; DPRINT_INFO(STORVSC_DRV, "Storvsc initializing...."); - ret = storvsc_drv_init(StorVscInitialize); + ret = storvsc_drv_init(stor_vsc_initialize); return ret; } -- cgit v1.2.3 From 3d8cdf22b314f84cc4ae85ed650ccd37150a7562 Mon Sep 17 00:00:00 2001 From: Hank Janssen Date: Mon, 6 Dec 2010 12:26:47 -0800 Subject: staging: hv: Convert camel case struct fields in storvsc.c to lowercase Convert camel cased struct fields in storvsc.c to lowercase Signed-off-by: Abhishek Kane Signed-off-by: Haiyang Zhang Signed-off-by: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/storvsc.c | 133 ++++++++++++++++++++++--------------------- 1 file changed, 67 insertions(+), 66 deletions(-) diff --git a/drivers/staging/hv/storvsc.c b/drivers/staging/hv/storvsc.c index 770413183306..3b6e63aa4554 100644 --- a/drivers/staging/hv/storvsc.c +++ b/drivers/staging/hv/storvsc.c @@ -34,43 +34,43 @@ struct storvsc_request_extension { /* LIST_ENTRY ListEntry; */ - struct hv_storvsc_request *Request; - struct hv_device *Device; + struct hv_storvsc_request *request; + struct hv_device *device; /* Synchronize the request/response if needed */ - struct osd_waitevent *WaitEvent; + struct osd_waitevent *wait_event; - struct vstor_packet VStorPacket; + struct vstor_packet vstor_packet; }; /* A storvsc device is a device object that contains a vmbus channel */ struct storvsc_device { - struct hv_device *Device; + struct hv_device *device; /* 0 indicates the device is being destroyed */ - atomic_t RefCount; + atomic_t ref_count; - atomic_t NumOutstandingRequests; + atomic_t num_outstanding_requests; /* * Each unique Port/Path/Target represents 1 channel ie scsi * controller. In reality, the pathid, targetid is always 0 * and the port is set by us */ - unsigned int PortNumber; - unsigned char PathId; - unsigned char TargetId; + unsigned int port_number; + unsigned char path_id; + unsigned char target_id; /* LIST_ENTRY OutstandingRequestList; */ /* HANDLE OutstandingRequestLock; */ /* Used for vsc/vsp channel reset process */ - struct storvsc_request_extension InitRequest; - struct storvsc_request_extension ResetRequest; + struct storvsc_request_extension init_request; + struct storvsc_request_extension reset_request; }; -static const char *gDriverName = "storvsc"; +static const char *g_driver_name = "storvsc"; /* {ba6163d9-04a1-4d29-b605-72e2ffb1dc7f} */ static const struct hv_guid gStorVscDeviceType = { @@ -90,10 +90,10 @@ static inline struct storvsc_device *AllocStorDevice(struct hv_device *Device) return NULL; /* Set to 2 to allow both inbound and outbound traffics */ - /* (ie GetStorDevice() and MustGetStorDevice()) to proceed. */ - atomic_cmpxchg(&storDevice->RefCount, 0, 2); + /* (ie get_stor_device() and must_get_stor_device()) to proceed. */ + atomic_cmpxchg(&storDevice->ref_count, 0, 2); - storDevice->Device = Device; + storDevice->device = Device; Device->Extension = storDevice; return storDevice; @@ -101,7 +101,7 @@ static inline struct storvsc_device *AllocStorDevice(struct hv_device *Device) static inline void FreeStorDevice(struct storvsc_device *Device) { - /* ASSERT(atomic_read(&Device->RefCount) == 0); */ + /* ASSERT(atomic_read(&Device->ref_count) == 0); */ kfree(Device); } @@ -111,8 +111,8 @@ static inline struct storvsc_device *GetStorDevice(struct hv_device *Device) struct storvsc_device *storDevice; storDevice = (struct storvsc_device *)Device->Extension; - if (storDevice && atomic_read(&storDevice->RefCount) > 1) - atomic_inc(&storDevice->RefCount); + if (storDevice && atomic_read(&storDevice->ref_count) > 1) + atomic_inc(&storDevice->ref_count); else storDevice = NULL; @@ -125,8 +125,8 @@ static inline struct storvsc_device *MustGetStorDevice(struct hv_device *Device) struct storvsc_device *storDevice; storDevice = (struct storvsc_device *)Device->Extension; - if (storDevice && atomic_read(&storDevice->RefCount)) - atomic_inc(&storDevice->RefCount); + if (storDevice && atomic_read(&storDevice->ref_count)) + atomic_inc(&storDevice->ref_count); else storDevice = NULL; @@ -140,8 +140,8 @@ static inline void PutStorDevice(struct hv_device *Device) storDevice = (struct storvsc_device *)Device->Extension; /* ASSERT(storDevice); */ - atomic_dec(&storDevice->RefCount); - /* ASSERT(atomic_read(&storDevice->RefCount)); */ + atomic_dec(&storDevice->ref_count); + /* ASSERT(atomic_read(&storDevice->ref_count)); */ } /* Drop ref count to 1 to effectively disable GetStorDevice() */ @@ -153,7 +153,7 @@ static inline struct storvsc_device *ReleaseStorDevice(struct hv_device *Device) /* ASSERT(storDevice); */ /* Busy wait until the ref drop to 2, then set it to 1 */ - while (atomic_cmpxchg(&storDevice->RefCount, 2, 1) != 2) + while (atomic_cmpxchg(&storDevice->ref_count, 2, 1) != 2) udelay(100); return storDevice; @@ -169,7 +169,7 @@ static inline struct storvsc_device *FinalReleaseStorDevice( /* ASSERT(storDevice); */ /* Busy wait until the ref drop to 1, then set it to 0 */ - while (atomic_cmpxchg(&storDevice->RefCount, 1, 0) != 1) + while (atomic_cmpxchg(&storDevice->ref_count, 1, 0) != 1) udelay(100); Device->Extension = NULL; @@ -190,16 +190,16 @@ static int StorVscChannelInit(struct hv_device *Device) return -1; } - request = &storDevice->InitRequest; - vstorPacket = &request->VStorPacket; + request = &storDevice->init_request; + vstorPacket = &request->vstor_packet; /* * Now, initiate the vsc/vsp initialization protocol on the open * channel */ memset(request, 0, sizeof(struct storvsc_request_extension)); - request->WaitEvent = osd_waitevent_create(); - if (!request->WaitEvent) { + request->wait_event = osd_waitevent_create(); + if (!request->wait_event) { ret = -ENOMEM; goto nomem; } @@ -224,7 +224,7 @@ static int StorVscChannelInit(struct hv_device *Device) goto Cleanup; } - osd_waitevent_wait(request->WaitEvent); + osd_waitevent_wait(request->wait_event); if (vstorPacket->operation != VSTOR_OPERATION_COMPLETE_IO || vstorPacket->status != 0) { @@ -255,7 +255,7 @@ static int StorVscChannelInit(struct hv_device *Device) goto Cleanup; } - osd_waitevent_wait(request->WaitEvent); + osd_waitevent_wait(request->wait_event); /* TODO: Check returned version */ if (vstorPacket->operation != VSTOR_OPERATION_COMPLETE_IO || @@ -273,7 +273,7 @@ static int StorVscChannelInit(struct hv_device *Device) vstorPacket->operation = VSTOR_OPERATION_QUERY_PROPERTIES; vstorPacket->flags = REQUEST_COMPLETION_FLAG; vstorPacket->storage_channel_properties.port_number = - storDevice->PortNumber; + storDevice->port_number; ret = vmbus_sendpacket(Device->channel, vstorPacket, sizeof(struct vstor_packet), @@ -287,7 +287,7 @@ static int StorVscChannelInit(struct hv_device *Device) goto Cleanup; } - osd_waitevent_wait(request->WaitEvent); + osd_waitevent_wait(request->wait_event); /* TODO: Check returned version */ if (vstorPacket->operation != VSTOR_OPERATION_COMPLETE_IO || @@ -298,8 +298,8 @@ static int StorVscChannelInit(struct hv_device *Device) goto Cleanup; } - storDevice->PathId = vstorPacket->storage_channel_properties.path_id; - storDevice->TargetId + storDevice->path_id = vstorPacket->storage_channel_properties.path_id; + storDevice->target_id = vstorPacket->storage_channel_properties.target_id; DPRINT_DBG(STORVSC, "channel flag 0x%x, max xfer len 0x%x", @@ -324,7 +324,7 @@ static int StorVscChannelInit(struct hv_device *Device) goto Cleanup; } - osd_waitevent_wait(request->WaitEvent); + osd_waitevent_wait(request->wait_event); if (vstorPacket->operation != VSTOR_OPERATION_COMPLETE_IO || vstorPacket->status != 0) { @@ -337,8 +337,8 @@ static int StorVscChannelInit(struct hv_device *Device) DPRINT_INFO(STORVSC, "**** storage channel up and running!! ****"); Cleanup: - kfree(request->WaitEvent); - request->WaitEvent = NULL; + kfree(request->wait_event); + request->wait_event = NULL; nomem: PutStorDevice(Device); return ret; @@ -365,7 +365,7 @@ static void StorVscOnIOCompletion(struct hv_device *Device, /* ASSERT(RequestExt != NULL); */ /* ASSERT(RequestExt->Request != NULL); */ - request = RequestExt->Request; + request = RequestExt->request; /* ASSERT(request->OnIOCompletion != NULL); */ @@ -403,7 +403,7 @@ static void StorVscOnIOCompletion(struct hv_device *Device, request->on_io_completion(request); - atomic_dec(&storDevice->NumOutstandingRequests); + atomic_dec(&storDevice->num_outstanding_requests); PutStorDevice(Device); } @@ -463,18 +463,18 @@ static void StorVscOnChannelCallback(void *context) /* ASSERT(request);c */ /* if (vstorPacket.Flags & SYNTHETIC_FLAG) */ - if ((request == &storDevice->InitRequest) || - (request == &storDevice->ResetRequest)) { + if ((request == &storDevice->init_request) || + (request == &storDevice->reset_request)) { /* DPRINT_INFO(STORVSC, * "reset completion - operation " * "%u status %u", * vstorPacket.Operation, * vstorPacket.Status); */ - memcpy(&request->VStorPacket, packet, + memcpy(&request->vstor_packet, packet, sizeof(struct vstor_packet)); - osd_waitevent_set(request->WaitEvent); + osd_waitevent_set(request->wait_event); } else { StorVscOnReceive(device, (struct vstor_packet *)packet, @@ -522,6 +522,7 @@ static int StorVscConnectToVsp(struct hv_device *Device) /* * StorVscOnDeviceAdd - Callback when the device belonging to this driver is added + * is added */ static int StorVscOnDeviceAdd(struct hv_device *Device, void *AdditionalInfo) { @@ -552,17 +553,17 @@ static int StorVscOnDeviceAdd(struct hv_device *Device, void *AdditionalInfo) storChannel->PathId = props->PathId; storChannel->TargetId = props->TargetId; */ - storDevice->PortNumber = deviceInfo->port_number; + storDevice->port_number = deviceInfo->port_number; /* Send it back up */ ret = StorVscConnectToVsp(Device); /* deviceInfo->PortNumber = storDevice->PortNumber; */ - deviceInfo->path_id = storDevice->PathId; - deviceInfo->target_id = storDevice->TargetId; + deviceInfo->path_id = storDevice->path_id; + deviceInfo->target_id = storDevice->target_id; DPRINT_DBG(STORVSC, "assigned port %u, path %u target %u\n", - storDevice->PortNumber, storDevice->PathId, - storDevice->TargetId); + storDevice->port_number, storDevice->path_id, + storDevice->target_id); Cleanup: return ret; @@ -585,9 +586,9 @@ static int StorVscOnDeviceRemove(struct hv_device *Device) * only allow inbound traffic (responses) to proceed so that * outstanding requests can be completed. */ - while (atomic_read(&storDevice->NumOutstandingRequests)) { + while (atomic_read(&storDevice->num_outstanding_requests)) { DPRINT_INFO(STORVSC, "waiting for %d requests to complete...", - atomic_read(&storDevice->NumOutstandingRequests)); + atomic_read(&storDevice->num_outstanding_requests)); udelay(100); } @@ -621,22 +622,22 @@ int stor_vsc_on_host_reset(struct hv_device *Device) return -1; } - request = &storDevice->ResetRequest; - vstorPacket = &request->VStorPacket; + request = &storDevice->reset_request; + vstorPacket = &request->vstor_packet; - request->WaitEvent = osd_waitevent_create(); - if (!request->WaitEvent) { + request->wait_event = osd_waitevent_create(); + if (!request->wait_event) { ret = -ENOMEM; goto Cleanup; } vstorPacket->operation = VSTOR_OPERATION_RESET_BUS; vstorPacket->flags = REQUEST_COMPLETION_FLAG; - vstorPacket->vm_srb.path_id = storDevice->PathId; + vstorPacket->vm_srb.path_id = storDevice->path_id; ret = vmbus_sendpacket(Device->channel, vstorPacket, sizeof(struct vstor_packet), - (unsigned long)&storDevice->ResetRequest, + (unsigned long)&storDevice->reset_request, VmbusPacketTypeDataInBand, VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); if (ret != 0) { @@ -646,9 +647,9 @@ int stor_vsc_on_host_reset(struct hv_device *Device) } /* FIXME: Add a timeout */ - osd_waitevent_wait(request->WaitEvent); + osd_waitevent_wait(request->wait_event); - kfree(request->WaitEvent); + kfree(request->wait_event); DPRINT_INFO(STORVSC, "host adapter reset completed"); /* @@ -674,7 +675,7 @@ static int StorVscOnIORequest(struct hv_device *Device, requestExtension = (struct storvsc_request_extension *)Request->extension; - vstorPacket = &requestExtension->VStorPacket; + vstorPacket = &requestExtension->vstor_packet; storDevice = GetStorDevice(Device); DPRINT_DBG(STORVSC, "enter - Device %p, DeviceExt %p, Request %p, " @@ -694,8 +695,8 @@ static int StorVscOnIORequest(struct hv_device *Device, /* print_hex_dump_bytes("", DUMP_PREFIX_NONE, Request->Cdb, * Request->CdbLen); */ - requestExtension->Request = Request; - requestExtension->Device = Device; + requestExtension->request = Request; + requestExtension->device = Device; memset(vstorPacket, 0 , sizeof(struct vstor_packet)); @@ -729,9 +730,9 @@ static int StorVscOnIORequest(struct hv_device *Device, vstorPacket->vm_srb.sense_info_length, vstorPacket->vm_srb.cdb_length); - if (requestExtension->Request->data_buffer.Length) { + if (requestExtension->request->data_buffer.Length) { ret = vmbus_sendpacket_multipagebuffer(Device->channel, - &requestExtension->Request->data_buffer, + &requestExtension->request->data_buffer, vstorPacket, sizeof(struct vstor_packet), (unsigned long)requestExtension); @@ -748,7 +749,7 @@ static int StorVscOnIORequest(struct hv_device *Device, vstorPacket, ret); } - atomic_inc(&storDevice->NumOutstandingRequests); + atomic_inc(&storDevice->num_outstanding_requests); PutStorDevice(Device); return ret; @@ -782,7 +783,7 @@ int stor_vsc_initialize(struct hv_driver *Driver) /* Make sure we are at least 2 pages since 1 page is used for control */ /* ASSERT(storDriver->RingBufferSize >= (PAGE_SIZE << 1)); */ - Driver->name = gDriverName; + Driver->name = g_driver_name; memcpy(&Driver->deviceType, &gStorVscDeviceType, sizeof(struct hv_guid)); -- cgit v1.2.3 From 02e37db7148a5ee98a742a0ff2f7e3acc406049b Mon Sep 17 00:00:00 2001 From: Hank Janssen Date: Mon, 6 Dec 2010 12:26:48 -0800 Subject: staging: hv: Convert camel case function names in storvsc.c to lowercase Convert camel case function names in storvsc.c to lowercase Signed-off-by: Abhishek Kane Signed-off-by: Haiyang Zhang Signed-off-by: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/blkvsc.c | 8 ++-- drivers/staging/hv/storvsc.c | 91 +++++++++++++++++++++++--------------------- 2 files changed, 51 insertions(+), 48 deletions(-) diff --git a/drivers/staging/hv/blkvsc.c b/drivers/staging/hv/blkvsc.c index e62c922f11cb..208492ca781e 100644 --- a/drivers/staging/hv/blkvsc.c +++ b/drivers/staging/hv/blkvsc.c @@ -42,7 +42,7 @@ static int BlkVscOnDeviceAdd(struct hv_device *Device, void *AdditionalInfo) deviceInfo = (struct storvsc_device_info *)AdditionalInfo; - ret = StorVscOnDeviceAdd(Device, AdditionalInfo); + ret = stor_vsc_on_device_add(Device, AdditionalInfo); if (ret != 0) return ret; @@ -94,9 +94,9 @@ int blk_vsc_initialize(struct hv_driver *Driver) /* Setup the dispatch table */ storDriver->base.OnDeviceAdd = BlkVscOnDeviceAdd; - storDriver->base.OnDeviceRemove = StorVscOnDeviceRemove; - storDriver->base.OnCleanup = StorVscOnCleanup; - storDriver->on_io_request = StorVscOnIORequest; + storDriver->base.OnDeviceRemove = stor_vsc_on_device_remove; + storDriver->base.OnCleanup = stor_vsc_on_cleanup; + storDriver->on_io_request = stor_vsc_on_io_request; return ret; } diff --git a/drivers/staging/hv/storvsc.c b/drivers/staging/hv/storvsc.c index 3b6e63aa4554..6643038aa24d 100644 --- a/drivers/staging/hv/storvsc.c +++ b/drivers/staging/hv/storvsc.c @@ -81,7 +81,7 @@ static const struct hv_guid gStorVscDeviceType = { }; -static inline struct storvsc_device *AllocStorDevice(struct hv_device *Device) +static inline struct storvsc_device *alloc_stor_device(struct hv_device *Device) { struct storvsc_device *storDevice; @@ -99,14 +99,14 @@ static inline struct storvsc_device *AllocStorDevice(struct hv_device *Device) return storDevice; } -static inline void FreeStorDevice(struct storvsc_device *Device) +static inline void free_stor_device(struct storvsc_device *Device) { /* ASSERT(atomic_read(&Device->ref_count) == 0); */ kfree(Device); } /* Get the stordevice object iff exists and its refcount > 1 */ -static inline struct storvsc_device *GetStorDevice(struct hv_device *Device) +static inline struct storvsc_device *get_stor_device(struct hv_device *Device) { struct storvsc_device *storDevice; @@ -120,7 +120,8 @@ static inline struct storvsc_device *GetStorDevice(struct hv_device *Device) } /* Get the stordevice object iff exists and its refcount > 0 */ -static inline struct storvsc_device *MustGetStorDevice(struct hv_device *Device) +static inline struct storvsc_device *must_get_stor_device( + struct hv_device *Device) { struct storvsc_device *storDevice; @@ -133,7 +134,7 @@ static inline struct storvsc_device *MustGetStorDevice(struct hv_device *Device) return storDevice; } -static inline void PutStorDevice(struct hv_device *Device) +static inline void put_stor_device(struct hv_device *Device) { struct storvsc_device *storDevice; @@ -144,8 +145,9 @@ static inline void PutStorDevice(struct hv_device *Device) /* ASSERT(atomic_read(&storDevice->ref_count)); */ } -/* Drop ref count to 1 to effectively disable GetStorDevice() */ -static inline struct storvsc_device *ReleaseStorDevice(struct hv_device *Device) +/* Drop ref count to 1 to effectively disable get_stor_device() */ +static inline struct storvsc_device *release_stor_device( + struct hv_device *Device) { struct storvsc_device *storDevice; @@ -160,7 +162,7 @@ static inline struct storvsc_device *ReleaseStorDevice(struct hv_device *Device) } /* Drop ref count to 0. No one can use StorDevice object. */ -static inline struct storvsc_device *FinalReleaseStorDevice( +static inline struct storvsc_device *final_release_stor_device( struct hv_device *Device) { struct storvsc_device *storDevice; @@ -176,14 +178,14 @@ static inline struct storvsc_device *FinalReleaseStorDevice( return storDevice; } -static int StorVscChannelInit(struct hv_device *Device) +static int stor_vsc_channel_init(struct hv_device *Device) { struct storvsc_device *storDevice; struct storvsc_request_extension *request; struct vstor_packet *vstorPacket; int ret; - storDevice = GetStorDevice(Device); + storDevice = get_stor_device(Device); if (!storDevice) { DPRINT_ERR(STORVSC, "unable to get stor device..." "device being destroyed?"); @@ -340,18 +342,18 @@ Cleanup: kfree(request->wait_event); request->wait_event = NULL; nomem: - PutStorDevice(Device); + put_stor_device(Device); return ret; } -static void StorVscOnIOCompletion(struct hv_device *Device, +static void stor_vsc_on_io_completion(struct hv_device *Device, struct vstor_packet *VStorPacket, struct storvsc_request_extension *RequestExt) { struct hv_storvsc_request *request; struct storvsc_device *storDevice; - storDevice = MustGetStorDevice(Device); + storDevice = must_get_stor_device(Device); if (!storDevice) { DPRINT_ERR(STORVSC, "unable to get stor device..." "device being destroyed?"); @@ -405,17 +407,17 @@ static void StorVscOnIOCompletion(struct hv_device *Device, atomic_dec(&storDevice->num_outstanding_requests); - PutStorDevice(Device); + put_stor_device(Device); } -static void StorVscOnReceive(struct hv_device *Device, +static void stor_vsc_on_receive(struct hv_device *Device, struct vstor_packet *VStorPacket, struct storvsc_request_extension *RequestExt) { switch (VStorPacket->operation) { case VSTOR_OPERATION_COMPLETE_IO: DPRINT_DBG(STORVSC, "IO_COMPLETE_OPERATION"); - StorVscOnIOCompletion(Device, VStorPacket, RequestExt); + stor_vsc_on_io_completion(Device, VStorPacket, RequestExt); break; case VSTOR_OPERATION_REMOVE_DEVICE: DPRINT_INFO(STORVSC, "REMOVE_DEVICE_OPERATION"); @@ -429,7 +431,7 @@ static void StorVscOnReceive(struct hv_device *Device, } } -static void StorVscOnChannelCallback(void *context) +static void stor_vsc_on_channel_callback(void *context) { struct hv_device *device = (struct hv_device *)context; struct storvsc_device *storDevice; @@ -441,7 +443,7 @@ static void StorVscOnChannelCallback(void *context) /* ASSERT(device); */ - storDevice = MustGetStorDevice(device); + storDevice = must_get_stor_device(device); if (!storDevice) { DPRINT_ERR(STORVSC, "unable to get stor device..." "device being destroyed?"); @@ -476,7 +478,7 @@ static void StorVscOnChannelCallback(void *context) osd_waitevent_set(request->wait_event); } else { - StorVscOnReceive(device, + stor_vsc_on_receive(device, (struct vstor_packet *)packet, request); } @@ -486,11 +488,11 @@ static void StorVscOnChannelCallback(void *context) } } while (1); - PutStorDevice(device); + put_stor_device(device); return; } -static int StorVscConnectToVsp(struct hv_device *Device) +static int stor_vsc_connect_to_vsp(struct hv_device *Device) { struct vmstorage_channel_properties props; struct storvsc_driver_object *storDriver; @@ -505,7 +507,7 @@ static int StorVscConnectToVsp(struct hv_device *Device) storDriver->ring_buffer_size, (void *)&props, sizeof(struct vmstorage_channel_properties), - StorVscOnChannelCallback, Device); + stor_vsc_on_channel_callback, Device); DPRINT_DBG(STORVSC, "storage props: path id %d, tgt id %d, max xfer %d", props.path_id, props.target_id, props.max_transfer_bytes); @@ -515,16 +517,17 @@ static int StorVscConnectToVsp(struct hv_device *Device) return -1; } - ret = StorVscChannelInit(Device); + ret = stor_vsc_channel_init(Device); return ret; } /* - * StorVscOnDeviceAdd - Callback when the device belonging to this driver is added + * stor_vsc_on_device_add - Callback when the device belonging to this driver * is added */ -static int StorVscOnDeviceAdd(struct hv_device *Device, void *AdditionalInfo) +static int stor_vsc_on_device_add(struct hv_device *Device, + void *AdditionalInfo) { struct storvsc_device *storDevice; /* struct vmstorage_channel_properties *props; */ @@ -532,7 +535,7 @@ static int StorVscOnDeviceAdd(struct hv_device *Device, void *AdditionalInfo) int ret = 0; deviceInfo = (struct storvsc_device_info *)AdditionalInfo; - storDevice = AllocStorDevice(Device); + storDevice = alloc_stor_device(Device); if (!storDevice) { ret = -1; goto Cleanup; @@ -555,7 +558,7 @@ static int StorVscOnDeviceAdd(struct hv_device *Device, void *AdditionalInfo) storDevice->port_number = deviceInfo->port_number; /* Send it back up */ - ret = StorVscConnectToVsp(Device); + ret = stor_vsc_connect_to_vsp(Device); /* deviceInfo->PortNumber = storDevice->PortNumber; */ deviceInfo->path_id = storDevice->path_id; @@ -570,16 +573,16 @@ Cleanup: } /* - * StorVscOnDeviceRemove - Callback when the our device is being removed + * stor_vsc_on_device_remove - Callback when the our device is being removed */ -static int StorVscOnDeviceRemove(struct hv_device *Device) +static int stor_vsc_on_device_remove(struct hv_device *Device) { struct storvsc_device *storDevice; DPRINT_INFO(STORVSC, "disabling storage device (%p)...", Device->Extension); - storDevice = ReleaseStorDevice(Device); + storDevice = release_stor_device(Device); /* * At this point, all outbound traffic should be disable. We @@ -595,14 +598,14 @@ static int StorVscOnDeviceRemove(struct hv_device *Device) DPRINT_INFO(STORVSC, "removing storage device (%p)...", Device->Extension); - storDevice = FinalReleaseStorDevice(Device); + storDevice = final_release_stor_device(Device); DPRINT_INFO(STORVSC, "storage device (%p) safe to remove", storDevice); /* Close the channel */ vmbus_close(Device->channel); - FreeStorDevice(storDevice); + free_stor_device(storDevice); return 0; } @@ -615,7 +618,7 @@ int stor_vsc_on_host_reset(struct hv_device *Device) DPRINT_INFO(STORVSC, "resetting host adapter..."); - storDevice = GetStorDevice(Device); + storDevice = get_stor_device(Device); if (!storDevice) { DPRINT_ERR(STORVSC, "unable to get stor device..." "device being destroyed?"); @@ -658,14 +661,14 @@ int stor_vsc_on_host_reset(struct hv_device *Device) */ Cleanup: - PutStorDevice(Device); + put_stor_device(Device); return ret; } /* - * StorVscOnIORequest - Callback to initiate an I/O request + * stor_vsc_on_io_request - Callback to initiate an I/O request */ -static int StorVscOnIORequest(struct hv_device *Device, +static int stor_vsc_on_io_request(struct hv_device *Device, struct hv_storvsc_request *Request) { struct storvsc_device *storDevice; @@ -676,7 +679,7 @@ static int StorVscOnIORequest(struct hv_device *Device, requestExtension = (struct storvsc_request_extension *)Request->extension; vstorPacket = &requestExtension->vstor_packet; - storDevice = GetStorDevice(Device); + storDevice = get_stor_device(Device); DPRINT_DBG(STORVSC, "enter - Device %p, DeviceExt %p, Request %p, " "Extension %p", Device, storDevice, Request, @@ -751,14 +754,14 @@ static int StorVscOnIORequest(struct hv_device *Device, atomic_inc(&storDevice->num_outstanding_requests); - PutStorDevice(Device); + put_stor_device(Device); return ret; } /* - * StorVscOnCleanup - Perform any cleanup when the driver is removed + * stor_vsc_on_cleanup - Perform any cleanup when the driver is removed */ -static void StorVscOnCleanup(struct hv_driver *Driver) +static void stor_vsc_on_cleanup(struct hv_driver *Driver) { } @@ -806,11 +809,11 @@ int stor_vsc_initialize(struct hv_driver *Driver) STORVSC_MAX_IO_REQUESTS); /* Setup the dispatch table */ - storDriver->base.OnDeviceAdd = StorVscOnDeviceAdd; - storDriver->base.OnDeviceRemove = StorVscOnDeviceRemove; - storDriver->base.OnCleanup = StorVscOnCleanup; + storDriver->base.OnDeviceAdd = stor_vsc_on_device_add; + storDriver->base.OnDeviceRemove = stor_vsc_on_device_remove; + storDriver->base.OnCleanup = stor_vsc_on_cleanup; - storDriver->on_io_request = StorVscOnIORequest; + storDriver->on_io_request = stor_vsc_on_io_request; return 0; } -- cgit v1.2.3 From f638859e3203d1ae933e7f2114cca68f1ac407db Mon Sep 17 00:00:00 2001 From: Hank Janssen Date: Mon, 6 Dec 2010 12:26:49 -0800 Subject: staging: hv: Convert camel case local variables in storvsc.c to lowercase Convert camel case local variables in storvsc.c to lowercase Signed-off-by: Abhishek Kane Signed-off-by: Haiyang Zhang Signed-off-by: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/storvsc.c | 496 ++++++++++++++++++++++--------------------- 1 file changed, 249 insertions(+), 247 deletions(-) diff --git a/drivers/staging/hv/storvsc.c b/drivers/staging/hv/storvsc.c index 6643038aa24d..9295113e09b9 100644 --- a/drivers/staging/hv/storvsc.c +++ b/drivers/staging/hv/storvsc.c @@ -50,7 +50,7 @@ struct storvsc_device { /* 0 indicates the device is being destroyed */ atomic_t ref_count; - atomic_t num_outstanding_requests; + atomic_t num_outstanding_req; /* * Each unique Port/Path/Target represents 1 channel ie scsi @@ -81,119 +81,119 @@ static const struct hv_guid gStorVscDeviceType = { }; -static inline struct storvsc_device *alloc_stor_device(struct hv_device *Device) +static inline struct storvsc_device *alloc_stor_device(struct hv_device *device) { - struct storvsc_device *storDevice; + struct storvsc_device *stor_device; - storDevice = kzalloc(sizeof(struct storvsc_device), GFP_KERNEL); - if (!storDevice) + stor_device = kzalloc(sizeof(struct storvsc_device), GFP_KERNEL); + if (!stor_device) return NULL; /* Set to 2 to allow both inbound and outbound traffics */ /* (ie get_stor_device() and must_get_stor_device()) to proceed. */ - atomic_cmpxchg(&storDevice->ref_count, 0, 2); + atomic_cmpxchg(&stor_device->ref_count, 0, 2); - storDevice->device = Device; - Device->Extension = storDevice; + stor_device->device = device; + device->Extension = stor_device; - return storDevice; + return stor_device; } -static inline void free_stor_device(struct storvsc_device *Device) +static inline void free_stor_device(struct storvsc_device *device) { - /* ASSERT(atomic_read(&Device->ref_count) == 0); */ - kfree(Device); + /* ASSERT(atomic_read(&device->ref_count) == 0); */ + kfree(device); } /* Get the stordevice object iff exists and its refcount > 1 */ -static inline struct storvsc_device *get_stor_device(struct hv_device *Device) +static inline struct storvsc_device *get_stor_device(struct hv_device *device) { - struct storvsc_device *storDevice; + struct storvsc_device *stor_device; - storDevice = (struct storvsc_device *)Device->Extension; - if (storDevice && atomic_read(&storDevice->ref_count) > 1) - atomic_inc(&storDevice->ref_count); + stor_device = (struct storvsc_device *)device->Extension; + if (stor_device && atomic_read(&stor_device->ref_count) > 1) + atomic_inc(&stor_device->ref_count); else - storDevice = NULL; + stor_device = NULL; - return storDevice; + return stor_device; } /* Get the stordevice object iff exists and its refcount > 0 */ static inline struct storvsc_device *must_get_stor_device( - struct hv_device *Device) + struct hv_device *device) { - struct storvsc_device *storDevice; + struct storvsc_device *stor_device; - storDevice = (struct storvsc_device *)Device->Extension; - if (storDevice && atomic_read(&storDevice->ref_count)) - atomic_inc(&storDevice->ref_count); + stor_device = (struct storvsc_device *)device->Extension; + if (stor_device && atomic_read(&stor_device->ref_count)) + atomic_inc(&stor_device->ref_count); else - storDevice = NULL; + stor_device = NULL; - return storDevice; + return stor_device; } -static inline void put_stor_device(struct hv_device *Device) +static inline void put_stor_device(struct hv_device *device) { - struct storvsc_device *storDevice; + struct storvsc_device *stor_device; - storDevice = (struct storvsc_device *)Device->Extension; - /* ASSERT(storDevice); */ + stor_device = (struct storvsc_device *)device->Extension; + /* ASSERT(stor_device); */ - atomic_dec(&storDevice->ref_count); - /* ASSERT(atomic_read(&storDevice->ref_count)); */ + atomic_dec(&stor_device->ref_count); + /* ASSERT(atomic_read(&stor_device->ref_count)); */ } /* Drop ref count to 1 to effectively disable get_stor_device() */ static inline struct storvsc_device *release_stor_device( - struct hv_device *Device) + struct hv_device *device) { - struct storvsc_device *storDevice; + struct storvsc_device *stor_device; - storDevice = (struct storvsc_device *)Device->Extension; - /* ASSERT(storDevice); */ + stor_device = (struct storvsc_device *)device->Extension; + /* ASSERT(stor_device); */ /* Busy wait until the ref drop to 2, then set it to 1 */ - while (atomic_cmpxchg(&storDevice->ref_count, 2, 1) != 2) + while (atomic_cmpxchg(&stor_device->ref_count, 2, 1) != 2) udelay(100); - return storDevice; + return stor_device; } -/* Drop ref count to 0. No one can use StorDevice object. */ +/* Drop ref count to 0. No one can use stor_device object. */ static inline struct storvsc_device *final_release_stor_device( - struct hv_device *Device) + struct hv_device *device) { - struct storvsc_device *storDevice; + struct storvsc_device *stor_device; - storDevice = (struct storvsc_device *)Device->Extension; - /* ASSERT(storDevice); */ + stor_device = (struct storvsc_device *)device->Extension; + /* ASSERT(stor_device); */ /* Busy wait until the ref drop to 1, then set it to 0 */ - while (atomic_cmpxchg(&storDevice->ref_count, 1, 0) != 1) + while (atomic_cmpxchg(&stor_device->ref_count, 1, 0) != 1) udelay(100); - Device->Extension = NULL; - return storDevice; + device->Extension = NULL; + return stor_device; } -static int stor_vsc_channel_init(struct hv_device *Device) +static int stor_vsc_channel_init(struct hv_device *device) { - struct storvsc_device *storDevice; + struct storvsc_device *stor_device; struct storvsc_request_extension *request; - struct vstor_packet *vstorPacket; + struct vstor_packet *vstor_packet; int ret; - storDevice = get_stor_device(Device); - if (!storDevice) { + stor_device = get_stor_device(device); + if (!stor_device) { DPRINT_ERR(STORVSC, "unable to get stor device..." "device being destroyed?"); return -1; } - request = &storDevice->init_request; - vstorPacket = &request->vstor_packet; + request = &stor_device->init_request; + vstor_packet = &request->vstor_packet; /* * Now, initiate the vsc/vsp initialization protocol on the open @@ -206,8 +206,8 @@ static int stor_vsc_channel_init(struct hv_device *Device) goto nomem; } - vstorPacket->operation = VSTOR_OPERATION_BEGIN_INITIALIZATION; - vstorPacket->flags = REQUEST_COMPLETION_FLAG; + vstor_packet->operation = VSTOR_OPERATION_BEGIN_INITIALIZATION; + vstor_packet->flags = REQUEST_COMPLETION_FLAG; /*SpinlockAcquire(gDriverExt.packetListLock); INSERT_TAIL_LIST(&gDriverExt.packetList, &packet->listEntry.entry); @@ -215,7 +215,7 @@ static int stor_vsc_channel_init(struct hv_device *Device) DPRINT_INFO(STORVSC, "BEGIN_INITIALIZATION_OPERATION..."); - ret = vmbus_sendpacket(Device->channel, vstorPacket, + ret = vmbus_sendpacket(device->channel, vstor_packet, sizeof(struct vstor_packet), (unsigned long)request, VmbusPacketTypeDataInBand, @@ -228,25 +228,25 @@ static int stor_vsc_channel_init(struct hv_device *Device) osd_waitevent_wait(request->wait_event); - if (vstorPacket->operation != VSTOR_OPERATION_COMPLETE_IO || - vstorPacket->status != 0) { + if (vstor_packet->operation != VSTOR_OPERATION_COMPLETE_IO || + vstor_packet->status != 0) { DPRINT_ERR(STORVSC, "BEGIN_INITIALIZATION_OPERATION failed " "(op %d status 0x%x)", - vstorPacket->operation, vstorPacket->status); + vstor_packet->operation, vstor_packet->status); goto Cleanup; } DPRINT_INFO(STORVSC, "QUERY_PROTOCOL_VERSION_OPERATION..."); /* reuse the packet for version range supported */ - memset(vstorPacket, 0, sizeof(struct vstor_packet)); - vstorPacket->operation = VSTOR_OPERATION_QUERY_PROTOCOL_VERSION; - vstorPacket->flags = REQUEST_COMPLETION_FLAG; + memset(vstor_packet, 0, sizeof(struct vstor_packet)); + vstor_packet->operation = VSTOR_OPERATION_QUERY_PROTOCOL_VERSION; + vstor_packet->flags = REQUEST_COMPLETION_FLAG; - vstorPacket->version.major_minor = VMSTOR_PROTOCOL_VERSION_CURRENT; - FILL_VMSTOR_REVISION(vstorPacket->version.revision); + vstor_packet->version.major_minor = VMSTOR_PROTOCOL_VERSION_CURRENT; + FILL_VMSTOR_REVISION(vstor_packet->version.revision); - ret = vmbus_sendpacket(Device->channel, vstorPacket, + ret = vmbus_sendpacket(device->channel, vstor_packet, sizeof(struct vstor_packet), (unsigned long)request, VmbusPacketTypeDataInBand, @@ -260,24 +260,24 @@ static int stor_vsc_channel_init(struct hv_device *Device) osd_waitevent_wait(request->wait_event); /* TODO: Check returned version */ - if (vstorPacket->operation != VSTOR_OPERATION_COMPLETE_IO || - vstorPacket->status != 0) { + if (vstor_packet->operation != VSTOR_OPERATION_COMPLETE_IO || + vstor_packet->status != 0) { DPRINT_ERR(STORVSC, "QUERY_PROTOCOL_VERSION_OPERATION failed " "(op %d status 0x%x)", - vstorPacket->operation, vstorPacket->status); + vstor_packet->operation, vstor_packet->status); goto Cleanup; } /* Query channel properties */ DPRINT_INFO(STORVSC, "QUERY_PROPERTIES_OPERATION..."); - memset(vstorPacket, 0, sizeof(struct vstor_packet)); - vstorPacket->operation = VSTOR_OPERATION_QUERY_PROPERTIES; - vstorPacket->flags = REQUEST_COMPLETION_FLAG; - vstorPacket->storage_channel_properties.port_number = - storDevice->port_number; + memset(vstor_packet, 0, sizeof(struct vstor_packet)); + vstor_packet->operation = VSTOR_OPERATION_QUERY_PROPERTIES; + vstor_packet->flags = REQUEST_COMPLETION_FLAG; + vstor_packet->storage_channel_properties.port_number = + stor_device->port_number; - ret = vmbus_sendpacket(Device->channel, vstorPacket, + ret = vmbus_sendpacket(device->channel, vstor_packet, sizeof(struct vstor_packet), (unsigned long)request, VmbusPacketTypeDataInBand, @@ -292,29 +292,29 @@ static int stor_vsc_channel_init(struct hv_device *Device) osd_waitevent_wait(request->wait_event); /* TODO: Check returned version */ - if (vstorPacket->operation != VSTOR_OPERATION_COMPLETE_IO || - vstorPacket->status != 0) { + if (vstor_packet->operation != VSTOR_OPERATION_COMPLETE_IO || + vstor_packet->status != 0) { DPRINT_ERR(STORVSC, "QUERY_PROPERTIES_OPERATION failed " "(op %d status 0x%x)", - vstorPacket->operation, vstorPacket->status); + vstor_packet->operation, vstor_packet->status); goto Cleanup; } - storDevice->path_id = vstorPacket->storage_channel_properties.path_id; - storDevice->target_id - = vstorPacket->storage_channel_properties.target_id; + stor_device->path_id = vstor_packet->storage_channel_properties.path_id; + stor_device->target_id + = vstor_packet->storage_channel_properties.target_id; DPRINT_DBG(STORVSC, "channel flag 0x%x, max xfer len 0x%x", - vstorPacket->storage_channel_properties.flags, - vstorPacket->storage_channel_properties.max_transfer_bytes); + vstor_packet->storage_channel_properties.flags, + vstor_packet->storage_channel_properties.max_transfer_bytes); DPRINT_INFO(STORVSC, "END_INITIALIZATION_OPERATION..."); - memset(vstorPacket, 0, sizeof(struct vstor_packet)); - vstorPacket->operation = VSTOR_OPERATION_END_INITIALIZATION; - vstorPacket->flags = REQUEST_COMPLETION_FLAG; + memset(vstor_packet, 0, sizeof(struct vstor_packet)); + vstor_packet->operation = VSTOR_OPERATION_END_INITIALIZATION; + vstor_packet->flags = REQUEST_COMPLETION_FLAG; - ret = vmbus_sendpacket(Device->channel, vstorPacket, + ret = vmbus_sendpacket(device->channel, vstor_packet, sizeof(struct vstor_packet), (unsigned long)request, VmbusPacketTypeDataInBand, @@ -328,11 +328,11 @@ static int stor_vsc_channel_init(struct hv_device *Device) osd_waitevent_wait(request->wait_event); - if (vstorPacket->operation != VSTOR_OPERATION_COMPLETE_IO || - vstorPacket->status != 0) { + if (vstor_packet->operation != VSTOR_OPERATION_COMPLETE_IO || + vstor_packet->status != 0) { DPRINT_ERR(STORVSC, "END_INITIALIZATION_OPERATION failed " "(op %d status 0x%x)", - vstorPacket->operation, vstorPacket->status); + vstor_packet->operation, vstor_packet->status); goto Cleanup; } @@ -342,82 +342,82 @@ Cleanup: kfree(request->wait_event); request->wait_event = NULL; nomem: - put_stor_device(Device); + put_stor_device(device); return ret; } -static void stor_vsc_on_io_completion(struct hv_device *Device, - struct vstor_packet *VStorPacket, - struct storvsc_request_extension *RequestExt) +static void stor_vsc_on_io_completion(struct hv_device *device, + struct vstor_packet *vstor_packet, + struct storvsc_request_extension *request_ext) { struct hv_storvsc_request *request; - struct storvsc_device *storDevice; + struct storvsc_device *stor_device; - storDevice = must_get_stor_device(Device); - if (!storDevice) { + stor_device = must_get_stor_device(device); + if (!stor_device) { DPRINT_ERR(STORVSC, "unable to get stor device..." "device being destroyed?"); return; } DPRINT_DBG(STORVSC, "IO_COMPLETE_OPERATION - request extension %p " - "completed bytes xfer %u", RequestExt, - VStorPacket->vm_srb.data_transfer_length); + "completed bytes xfer %u", request_ext, + vstor_packet->vm_srb.data_transfer_length); - /* ASSERT(RequestExt != NULL); */ - /* ASSERT(RequestExt->Request != NULL); */ + /* ASSERT(request_ext != NULL); */ + /* ASSERT(request_ext->request != NULL); */ - request = RequestExt->request; + request = request_ext->request; /* ASSERT(request->OnIOCompletion != NULL); */ /* Copy over the status...etc */ - request->status = VStorPacket->vm_srb.scsi_status; + request->status = vstor_packet->vm_srb.scsi_status; - if (request->status != 0 || VStorPacket->vm_srb.srb_status != 1) { + if (request->status != 0 || vstor_packet->vm_srb.srb_status != 1) { DPRINT_WARN(STORVSC, "cmd 0x%x scsi status 0x%x srb status 0x%x\n", - request->cdb[0], VStorPacket->vm_srb.scsi_status, - VStorPacket->vm_srb.srb_status); + request->cdb[0], vstor_packet->vm_srb.scsi_status, + vstor_packet->vm_srb.srb_status); } if ((request->status & 0xFF) == 0x02) { /* CHECK_CONDITION */ - if (VStorPacket->vm_srb.srb_status & 0x80) { + if (vstor_packet->vm_srb.srb_status & 0x80) { /* autosense data available */ DPRINT_WARN(STORVSC, "storvsc pkt %p autosense data " - "valid - len %d\n", RequestExt, - VStorPacket->vm_srb.sense_info_length); + "valid - len %d\n", request_ext, + vstor_packet->vm_srb.sense_info_length); - /* ASSERT(VStorPacket->vm_srb.sense_info_length <= */ + /* ASSERT(vstor_packet->vm_srb.sense_info_length <= */ /* request->SenseBufferSize); */ memcpy(request->sense_buffer, - VStorPacket->vm_srb.sense_data, - VStorPacket->vm_srb.sense_info_length); + vstor_packet->vm_srb.sense_data, + vstor_packet->vm_srb.sense_info_length); request->sense_buffer_size = - VStorPacket->vm_srb.sense_info_length; + vstor_packet->vm_srb.sense_info_length; } } /* TODO: */ - request->bytes_xfer = VStorPacket->vm_srb.data_transfer_length; + request->bytes_xfer = vstor_packet->vm_srb.data_transfer_length; request->on_io_completion(request); - atomic_dec(&storDevice->num_outstanding_requests); + atomic_dec(&stor_device->num_outstanding_req); - put_stor_device(Device); + put_stor_device(device); } -static void stor_vsc_on_receive(struct hv_device *Device, - struct vstor_packet *VStorPacket, - struct storvsc_request_extension *RequestExt) +static void stor_vsc_on_receive(struct hv_device *device, + struct vstor_packet *vstor_packet, + struct storvsc_request_extension *request_ext) { - switch (VStorPacket->operation) { + switch (vstor_packet->operation) { case VSTOR_OPERATION_COMPLETE_IO: DPRINT_DBG(STORVSC, "IO_COMPLETE_OPERATION"); - stor_vsc_on_io_completion(Device, VStorPacket, RequestExt); + stor_vsc_on_io_completion(device, vstor_packet, request_ext); break; case VSTOR_OPERATION_REMOVE_DEVICE: DPRINT_INFO(STORVSC, "REMOVE_DEVICE_OPERATION"); @@ -426,7 +426,7 @@ static void stor_vsc_on_receive(struct hv_device *Device, default: DPRINT_INFO(STORVSC, "Unknown operation received - %d", - VStorPacket->operation); + vstor_packet->operation); break; } } @@ -434,17 +434,17 @@ static void stor_vsc_on_receive(struct hv_device *Device, static void stor_vsc_on_channel_callback(void *context) { struct hv_device *device = (struct hv_device *)context; - struct storvsc_device *storDevice; - u32 bytesRecvd; - u64 requestId; + struct storvsc_device *stor_device; + u32 bytes_recvd; + u64 request_id; unsigned char packet[ALIGN_UP(sizeof(struct vstor_packet), 8)]; struct storvsc_request_extension *request; int ret; /* ASSERT(device); */ - storDevice = must_get_stor_device(device); - if (!storDevice) { + stor_device = must_get_stor_device(device); + if (!stor_device) { DPRINT_ERR(STORVSC, "unable to get stor device..." "device being destroyed?"); return; @@ -453,25 +453,26 @@ static void stor_vsc_on_channel_callback(void *context) do { ret = vmbus_recvpacket(device->channel, packet, ALIGN_UP(sizeof(struct vstor_packet), 8), - &bytesRecvd, &requestId); - if (ret == 0 && bytesRecvd > 0) { + &bytes_recvd, &request_id); + if (ret == 0 && bytes_recvd > 0) { DPRINT_DBG(STORVSC, "receive %d bytes - tid %llx", - bytesRecvd, requestId); + bytes_recvd, request_id); - /* ASSERT(bytesRecvd == sizeof(struct vstor_packet)); */ + /* ASSERT(bytes_recvd == + sizeof(struct vstor_packet)); */ request = (struct storvsc_request_extension *) - (unsigned long)requestId; + (unsigned long)request_id; /* ASSERT(request);c */ - /* if (vstorPacket.Flags & SYNTHETIC_FLAG) */ - if ((request == &storDevice->init_request) || - (request == &storDevice->reset_request)) { + /* if (vstor_packet.Flags & SYNTHETIC_FLAG) */ + if ((request == &stor_device->init_request) || + (request == &stor_device->reset_request)) { /* DPRINT_INFO(STORVSC, * "reset completion - operation " * "%u status %u", - * vstorPacket.Operation, - * vstorPacket.Status); */ + * vstor_packet.Operation, + * vstor_packet.Status); */ memcpy(&request->vstor_packet, packet, sizeof(struct vstor_packet)); @@ -492,22 +493,22 @@ static void stor_vsc_on_channel_callback(void *context) return; } -static int stor_vsc_connect_to_vsp(struct hv_device *Device) +static int stor_vsc_connect_to_vsp(struct hv_device *device) { struct vmstorage_channel_properties props; - struct storvsc_driver_object *storDriver; + struct storvsc_driver_object *stor_driver; int ret; - storDriver = (struct storvsc_driver_object *)Device->Driver; + stor_driver = (struct storvsc_driver_object *)device->Driver; memset(&props, 0, sizeof(struct vmstorage_channel_properties)); /* Open the channel */ - ret = vmbus_open(Device->channel, - storDriver->ring_buffer_size, - storDriver->ring_buffer_size, + ret = vmbus_open(device->channel, + stor_driver->ring_buffer_size, + stor_driver->ring_buffer_size, (void *)&props, sizeof(struct vmstorage_channel_properties), - stor_vsc_on_channel_callback, Device); + stor_vsc_on_channel_callback, device); DPRINT_DBG(STORVSC, "storage props: path id %d, tgt id %d, max xfer %d", props.path_id, props.target_id, props.max_transfer_bytes); @@ -517,7 +518,7 @@ static int stor_vsc_connect_to_vsp(struct hv_device *Device) return -1; } - ret = stor_vsc_channel_init(Device); + ret = stor_vsc_channel_init(device); return ret; } @@ -526,17 +527,17 @@ static int stor_vsc_connect_to_vsp(struct hv_device *Device) * stor_vsc_on_device_add - Callback when the device belonging to this driver * is added */ -static int stor_vsc_on_device_add(struct hv_device *Device, - void *AdditionalInfo) +static int stor_vsc_on_device_add(struct hv_device *device, + void *additional_info) { - struct storvsc_device *storDevice; + struct storvsc_device *stor_device; /* struct vmstorage_channel_properties *props; */ - struct storvsc_device_info *deviceInfo; + struct storvsc_device_info *device_info; int ret = 0; - deviceInfo = (struct storvsc_device_info *)AdditionalInfo; - storDevice = alloc_stor_device(Device); - if (!storDevice) { + device_info = (struct storvsc_device_info *)additional_info; + stor_device = alloc_stor_device(device); + if (!stor_device) { ret = -1; goto Cleanup; } @@ -556,17 +557,17 @@ static int stor_vsc_on_device_add(struct hv_device *Device, storChannel->PathId = props->PathId; storChannel->TargetId = props->TargetId; */ - storDevice->port_number = deviceInfo->port_number; + stor_device->port_number = device_info->port_number; /* Send it back up */ - ret = stor_vsc_connect_to_vsp(Device); + ret = stor_vsc_connect_to_vsp(device); - /* deviceInfo->PortNumber = storDevice->PortNumber; */ - deviceInfo->path_id = storDevice->path_id; - deviceInfo->target_id = storDevice->target_id; + /* device_info->PortNumber = stor_device->PortNumber; */ + device_info->path_id = stor_device->path_id; + device_info->target_id = stor_device->target_id; DPRINT_DBG(STORVSC, "assigned port %u, path %u target %u\n", - storDevice->port_number, storDevice->path_id, - storDevice->target_id); + stor_device->port_number, stor_device->path_id, + stor_device->target_id); Cleanup: return ret; @@ -575,58 +576,58 @@ Cleanup: /* * stor_vsc_on_device_remove - Callback when the our device is being removed */ -static int stor_vsc_on_device_remove(struct hv_device *Device) +static int stor_vsc_on_device_remove(struct hv_device *device) { - struct storvsc_device *storDevice; + struct storvsc_device *stor_device; DPRINT_INFO(STORVSC, "disabling storage device (%p)...", - Device->Extension); + device->Extension); - storDevice = release_stor_device(Device); + stor_device = release_stor_device(device); /* * At this point, all outbound traffic should be disable. We * only allow inbound traffic (responses) to proceed so that * outstanding requests can be completed. */ - while (atomic_read(&storDevice->num_outstanding_requests)) { + while (atomic_read(&stor_device->num_outstanding_req)) { DPRINT_INFO(STORVSC, "waiting for %d requests to complete...", - atomic_read(&storDevice->num_outstanding_requests)); + atomic_read(&stor_device->num_outstanding_req)); udelay(100); } DPRINT_INFO(STORVSC, "removing storage device (%p)...", - Device->Extension); + device->Extension); - storDevice = final_release_stor_device(Device); + stor_device = final_release_stor_device(device); - DPRINT_INFO(STORVSC, "storage device (%p) safe to remove", storDevice); + DPRINT_INFO(STORVSC, "storage device (%p) safe to remove", stor_device); /* Close the channel */ - vmbus_close(Device->channel); + vmbus_close(device->channel); - free_stor_device(storDevice); + free_stor_device(stor_device); return 0; } -int stor_vsc_on_host_reset(struct hv_device *Device) +int stor_vsc_on_host_reset(struct hv_device *device) { - struct storvsc_device *storDevice; + struct storvsc_device *stor_device; struct storvsc_request_extension *request; - struct vstor_packet *vstorPacket; + struct vstor_packet *vstor_packet; int ret; DPRINT_INFO(STORVSC, "resetting host adapter..."); - storDevice = get_stor_device(Device); - if (!storDevice) { + stor_device = get_stor_device(device); + if (!stor_device) { DPRINT_ERR(STORVSC, "unable to get stor device..." "device being destroyed?"); return -1; } - request = &storDevice->reset_request; - vstorPacket = &request->vstor_packet; + request = &stor_device->reset_request; + vstor_packet = &request->vstor_packet; request->wait_event = osd_waitevent_create(); if (!request->wait_event) { @@ -634,18 +635,18 @@ int stor_vsc_on_host_reset(struct hv_device *Device) goto Cleanup; } - vstorPacket->operation = VSTOR_OPERATION_RESET_BUS; - vstorPacket->flags = REQUEST_COMPLETION_FLAG; - vstorPacket->vm_srb.path_id = storDevice->path_id; + vstor_packet->operation = VSTOR_OPERATION_RESET_BUS; + vstor_packet->flags = REQUEST_COMPLETION_FLAG; + vstor_packet->vm_srb.path_id = stor_device->path_id; - ret = vmbus_sendpacket(Device->channel, vstorPacket, + ret = vmbus_sendpacket(device->channel, vstor_packet, sizeof(struct vstor_packet), - (unsigned long)&storDevice->reset_request, + (unsigned long)&stor_device->reset_request, VmbusPacketTypeDataInBand, VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); if (ret != 0) { DPRINT_ERR(STORVSC, "Unable to send reset packet %p ret %d", - vstorPacket, ret); + vstor_packet, ret); goto Cleanup; } @@ -661,118 +662,118 @@ int stor_vsc_on_host_reset(struct hv_device *Device) */ Cleanup: - put_stor_device(Device); + put_stor_device(device); return ret; } /* * stor_vsc_on_io_request - Callback to initiate an I/O request */ -static int stor_vsc_on_io_request(struct hv_device *Device, - struct hv_storvsc_request *Request) +static int stor_vsc_on_io_request(struct hv_device *device, + struct hv_storvsc_request *request) { - struct storvsc_device *storDevice; - struct storvsc_request_extension *requestExtension; - struct vstor_packet *vstorPacket; + struct storvsc_device *stor_device; + struct storvsc_request_extension *request_extension; + struct vstor_packet *vstor_packet; int ret = 0; - requestExtension = - (struct storvsc_request_extension *)Request->extension; - vstorPacket = &requestExtension->vstor_packet; - storDevice = get_stor_device(Device); + request_extension = + (struct storvsc_request_extension *)request->extension; + vstor_packet = &request_extension->vstor_packet; + stor_device = get_stor_device(device); DPRINT_DBG(STORVSC, "enter - Device %p, DeviceExt %p, Request %p, " - "Extension %p", Device, storDevice, Request, - requestExtension); + "Extension %p", device, stor_device, request, + request_extension); DPRINT_DBG(STORVSC, "req %p len %d bus %d, target %d, lun %d cdblen %d", - Request, Request->data_buffer.Length, Request->bus, - Request->target_id, Request->lun_id, Request->cdb_len); + request, request->data_buffer.Length, request->bus, + request->target_id, request->lun_id, request->cdb_len); - if (!storDevice) { + if (!stor_device) { DPRINT_ERR(STORVSC, "unable to get stor device..." "device being destroyed?"); return -2; } - /* print_hex_dump_bytes("", DUMP_PREFIX_NONE, Request->Cdb, - * Request->CdbLen); */ + /* print_hex_dump_bytes("", DUMP_PREFIX_NONE, request->Cdb, + * request->CdbLen); */ - requestExtension->request = Request; - requestExtension->device = Device; + request_extension->request = request; + request_extension->device = device; - memset(vstorPacket, 0 , sizeof(struct vstor_packet)); + memset(vstor_packet, 0 , sizeof(struct vstor_packet)); - vstorPacket->flags |= REQUEST_COMPLETION_FLAG; + vstor_packet->flags |= REQUEST_COMPLETION_FLAG; - vstorPacket->vm_srb.length = sizeof(struct vmscsi_request); + vstor_packet->vm_srb.length = sizeof(struct vmscsi_request); - vstorPacket->vm_srb.port_number = Request->host; - vstorPacket->vm_srb.path_id = Request->bus; - vstorPacket->vm_srb.target_id = Request->target_id; - vstorPacket->vm_srb.lun = Request->lun_id; + vstor_packet->vm_srb.port_number = request->host; + vstor_packet->vm_srb.path_id = request->bus; + vstor_packet->vm_srb.target_id = request->target_id; + vstor_packet->vm_srb.lun = request->lun_id; - vstorPacket->vm_srb.sense_info_length = SENSE_BUFFER_SIZE; + vstor_packet->vm_srb.sense_info_length = SENSE_BUFFER_SIZE; /* Copy over the scsi command descriptor block */ - vstorPacket->vm_srb.cdb_length = Request->cdb_len; - memcpy(&vstorPacket->vm_srb.cdb, Request->cdb, Request->cdb_len); + vstor_packet->vm_srb.cdb_length = request->cdb_len; + memcpy(&vstor_packet->vm_srb.cdb, request->cdb, request->cdb_len); - vstorPacket->vm_srb.data_in = Request->type; - vstorPacket->vm_srb.data_transfer_length = Request->data_buffer.Length; + vstor_packet->vm_srb.data_in = request->type; + vstor_packet->vm_srb.data_transfer_length = request->data_buffer.Length; - vstorPacket->operation = VSTOR_OPERATION_EXECUTE_SRB; + vstor_packet->operation = VSTOR_OPERATION_EXECUTE_SRB; DPRINT_DBG(STORVSC, "srb - len %d port %d, path %d, target %d, " "lun %d senselen %d cdblen %d", - vstorPacket->vm_srb.length, - vstorPacket->vm_srb.port_number, - vstorPacket->vm_srb.path_id, - vstorPacket->vm_srb.target_id, - vstorPacket->vm_srb.lun, - vstorPacket->vm_srb.sense_info_length, - vstorPacket->vm_srb.cdb_length); - - if (requestExtension->request->data_buffer.Length) { - ret = vmbus_sendpacket_multipagebuffer(Device->channel, - &requestExtension->request->data_buffer, - vstorPacket, + vstor_packet->vm_srb.length, + vstor_packet->vm_srb.port_number, + vstor_packet->vm_srb.path_id, + vstor_packet->vm_srb.target_id, + vstor_packet->vm_srb.lun, + vstor_packet->vm_srb.sense_info_length, + vstor_packet->vm_srb.cdb_length); + + if (request_extension->request->data_buffer.Length) { + ret = vmbus_sendpacket_multipagebuffer(device->channel, + &request_extension->request->data_buffer, + vstor_packet, sizeof(struct vstor_packet), - (unsigned long)requestExtension); + (unsigned long)request_extension); } else { - ret = vmbus_sendpacket(Device->channel, vstorPacket, + ret = vmbus_sendpacket(device->channel, vstor_packet, sizeof(struct vstor_packet), - (unsigned long)requestExtension, + (unsigned long)request_extension, VmbusPacketTypeDataInBand, VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); } if (ret != 0) { DPRINT_DBG(STORVSC, "Unable to send packet %p ret %d", - vstorPacket, ret); + vstor_packet, ret); } - atomic_inc(&storDevice->num_outstanding_requests); + atomic_inc(&stor_device->num_outstanding_req); - put_stor_device(Device); + put_stor_device(device); return ret; } /* * stor_vsc_on_cleanup - Perform any cleanup when the driver is removed */ -static void stor_vsc_on_cleanup(struct hv_driver *Driver) +static void stor_vsc_on_cleanup(struct hv_driver *driver) { } /* * stor_vsc_initialize - Main entry point */ -int stor_vsc_initialize(struct hv_driver *Driver) +int stor_vsc_initialize(struct hv_driver *driver) { - struct storvsc_driver_object *storDriver; + struct storvsc_driver_object *stor_driver; - storDriver = (struct storvsc_driver_object *)Driver; + stor_driver = (struct storvsc_driver_object *)driver; DPRINT_DBG(STORVSC, "sizeof(STORVSC_REQUEST)=%zd " "sizeof(struct storvsc_request_extension)=%zd " @@ -784,13 +785,14 @@ int stor_vsc_initialize(struct hv_driver *Driver) sizeof(struct vmscsi_request)); /* Make sure we are at least 2 pages since 1 page is used for control */ - /* ASSERT(storDriver->RingBufferSize >= (PAGE_SIZE << 1)); */ + /* ASSERT(stor_driver->RingBufferSize >= (PAGE_SIZE << 1)); */ - Driver->name = g_driver_name; - memcpy(&Driver->deviceType, &gStorVscDeviceType, + driver->name = g_driver_name; + memcpy(&driver->deviceType, &gStorVscDeviceType, sizeof(struct hv_guid)); - storDriver->request_ext_size = sizeof(struct storvsc_request_extension); + stor_driver->request_ext_size = + sizeof(struct storvsc_request_extension); /* * Divide the ring buffer data size (which is 1 page less @@ -798,22 +800,22 @@ int stor_vsc_initialize(struct hv_driver *Driver) * the ring buffer indices) by the max request size (which is * vmbus_channel_packet_multipage_buffer + struct vstor_packet + u64) */ - storDriver->max_outstanding_req_per_channel = - ((storDriver->ring_buffer_size - PAGE_SIZE) / + stor_driver->max_outstanding_req_per_channel = + ((stor_driver->ring_buffer_size - PAGE_SIZE) / ALIGN_UP(MAX_MULTIPAGE_BUFFER_PACKET + sizeof(struct vstor_packet) + sizeof(u64), sizeof(u64))); DPRINT_INFO(STORVSC, "max io %u, currently %u\n", - storDriver->max_outstanding_req_per_channel, + stor_driver->max_outstanding_req_per_channel, STORVSC_MAX_IO_REQUESTS); /* Setup the dispatch table */ - storDriver->base.OnDeviceAdd = stor_vsc_on_device_add; - storDriver->base.OnDeviceRemove = stor_vsc_on_device_remove; - storDriver->base.OnCleanup = stor_vsc_on_cleanup; + stor_driver->base.OnDeviceAdd = stor_vsc_on_device_add; + stor_driver->base.OnDeviceRemove = stor_vsc_on_device_remove; + stor_driver->base.OnCleanup = stor_vsc_on_cleanup; - storDriver->on_io_request = stor_vsc_on_io_request; + stor_driver->on_io_request = stor_vsc_on_io_request; return 0; } -- cgit v1.2.3 From 2e6484acd28bb5223942d2608387af3ec9bf56f1 Mon Sep 17 00:00:00 2001 From: Hank Janssen Date: Mon, 6 Dec 2010 12:26:50 -0800 Subject: staging: hv: Convert camel case function names in blkvsc.c to lowercase Convert camel case function names in blkvsc.c to lowercase Signed-off-by: Abhishek Kane Signed-off-by: Haiyang Zhang Signed-off-by: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/blkvsc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/hv/blkvsc.c b/drivers/staging/hv/blkvsc.c index 208492ca781e..4f4a65c09a94 100644 --- a/drivers/staging/hv/blkvsc.c +++ b/drivers/staging/hv/blkvsc.c @@ -35,7 +35,7 @@ static const struct hv_guid gBlkVscDeviceType = { } }; -static int BlkVscOnDeviceAdd(struct hv_device *Device, void *AdditionalInfo) +static int blk_vsc_on_device_add(struct hv_device *Device, void *AdditionalInfo) { struct storvsc_device_info *deviceInfo; int ret = 0; @@ -93,7 +93,7 @@ int blk_vsc_initialize(struct hv_driver *Driver) storDriver->max_outstanding_req_per_channel); /* Setup the dispatch table */ - storDriver->base.OnDeviceAdd = BlkVscOnDeviceAdd; + storDriver->base.OnDeviceAdd = blk_vsc_on_device_add; storDriver->base.OnDeviceRemove = stor_vsc_on_device_remove; storDriver->base.OnCleanup = stor_vsc_on_cleanup; storDriver->on_io_request = stor_vsc_on_io_request; -- cgit v1.2.3 From 03fa6fc5a68242ddd7cc3ba4255fe6f65b21ce41 Mon Sep 17 00:00:00 2001 From: Hank Janssen Date: Mon, 6 Dec 2010 12:26:51 -0800 Subject: staging: hv: Convert camel case local variables in blkvsc.c to lowercase Convert camel case local variables in blkvsc.c to lowercase Signed-off-by: Abhishek Kane Signed-off-by: Haiyang Zhang Signed-off-by: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/blkvsc.c | 52 ++++++++++++++++++++++----------------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/drivers/staging/hv/blkvsc.c b/drivers/staging/hv/blkvsc.c index 4f4a65c09a94..bc16d9172eb2 100644 --- a/drivers/staging/hv/blkvsc.c +++ b/drivers/staging/hv/blkvsc.c @@ -25,24 +25,24 @@ #include "osd.h" #include "storvsc.c" -static const char *gBlkDriverName = "blkvsc"; +static const char *g_blk_driver_name = "blkvsc"; /* {32412632-86cb-44a2-9b5c-50d1417354f5} */ -static const struct hv_guid gBlkVscDeviceType = { +static const struct hv_guid g_blk_device_type = { .data = { 0x32, 0x26, 0x41, 0x32, 0xcb, 0x86, 0xa2, 0x44, 0x9b, 0x5c, 0x50, 0xd1, 0x41, 0x73, 0x54, 0xf5 } }; -static int blk_vsc_on_device_add(struct hv_device *Device, void *AdditionalInfo) +static int blk_vsc_on_device_add(struct hv_device *device, void *additional_info) { - struct storvsc_device_info *deviceInfo; + struct storvsc_device_info *device_info; int ret = 0; - deviceInfo = (struct storvsc_device_info *)AdditionalInfo; + device_info = (struct storvsc_device_info *)additional_info; - ret = stor_vsc_on_device_add(Device, AdditionalInfo); + ret = stor_vsc_on_device_add(device, additional_info); if (ret != 0) return ret; @@ -51,31 +51,31 @@ static int blk_vsc_on_device_add(struct hv_device *Device, void *AdditionalInfo) * id. For IDE devices, the device instance id is formatted as * * - - 8899 - 000000000000. */ - deviceInfo->path_id = Device->deviceInstance.data[3] << 24 | - Device->deviceInstance.data[2] << 16 | - Device->deviceInstance.data[1] << 8 | - Device->deviceInstance.data[0]; + device_info->path_id = device->deviceInstance.data[3] << 24 | + device->deviceInstance.data[2] << 16 | + device->deviceInstance.data[1] << 8 | + device->deviceInstance.data[0]; - deviceInfo->target_id = Device->deviceInstance.data[5] << 8 | - Device->deviceInstance.data[4]; + device_info->target_id = device->deviceInstance.data[5] << 8 | + device->deviceInstance.data[4]; return ret; } -int blk_vsc_initialize(struct hv_driver *Driver) +int blk_vsc_initialize(struct hv_driver *driver) { - struct storvsc_driver_object *storDriver; + struct storvsc_driver_object *stor_driver; int ret = 0; - storDriver = (struct storvsc_driver_object *)Driver; + stor_driver = (struct storvsc_driver_object *)driver; /* Make sure we are at least 2 pages since 1 page is used for control */ - /* ASSERT(storDriver->RingBufferSize >= (PAGE_SIZE << 1)); */ + /* ASSERT(stor_driver->RingBufferSize >= (PAGE_SIZE << 1)); */ - Driver->name = gBlkDriverName; - memcpy(&Driver->deviceType, &gBlkVscDeviceType, sizeof(struct hv_guid)); + driver->name = g_blk_driver_name; + memcpy(&driver->deviceType, &g_blk_device_type, sizeof(struct hv_guid)); - storDriver->request_ext_size = sizeof(struct storvsc_request_extension); + stor_driver->request_ext_size = sizeof(struct storvsc_request_extension); /* * Divide the ring buffer data size (which is 1 page less than the ring @@ -83,20 +83,20 @@ int blk_vsc_initialize(struct hv_driver *Driver) * by the max request size (which is * vmbus_channel_packet_multipage_buffer + struct vstor_packet + u64) */ - storDriver->max_outstanding_req_per_channel = - ((storDriver->ring_buffer_size - PAGE_SIZE) / + stor_driver->max_outstanding_req_per_channel = + ((stor_driver->ring_buffer_size - PAGE_SIZE) / ALIGN_UP(MAX_MULTIPAGE_BUFFER_PACKET + sizeof(struct vstor_packet) + sizeof(u64), sizeof(u64))); DPRINT_INFO(BLKVSC, "max io outstd %u", - storDriver->max_outstanding_req_per_channel); + stor_driver->max_outstanding_req_per_channel); /* Setup the dispatch table */ - storDriver->base.OnDeviceAdd = blk_vsc_on_device_add; - storDriver->base.OnDeviceRemove = stor_vsc_on_device_remove; - storDriver->base.OnCleanup = stor_vsc_on_cleanup; - storDriver->on_io_request = stor_vsc_on_io_request; + stor_driver->base.OnDeviceAdd = blk_vsc_on_device_add; + stor_driver->base.OnDeviceRemove = stor_vsc_on_device_remove; + stor_driver->base.OnCleanup = stor_vsc_on_cleanup; + stor_driver->on_io_request = stor_vsc_on_io_request; return ret; } -- cgit v1.2.3 From 1a8e8fab790ea7af81b8f964fdec706ad1ec2271 Mon Sep 17 00:00:00 2001 From: Valentine Barshak Date: Mon, 6 Dec 2010 17:51:41 +0300 Subject: HID: Fix race between disconnect and hiddev_ioctl A USB HID device can be disconnected at any time. If this happens right before or while hiddev_ioctl is in progress, the hiddev_ioctl tries to access invalid hiddev->hid pointer. When the hid device is disconnected, the hiddev_disconnect() ends up with a call to hid_device_release() which frees hid_device, but doesn't set the hiddev->hid pointer to NULL. If the deallocated memory region has been re-used by the kernel, this can cause a crash or memory corruption. Since disconnect can happen at any time, we can't initialize struct hid_device *hid = hiddev->hid at the beginning of ioctl and then use it. This change checks hiddev->exist flag while holding the existancelock and uses hid_device only if it exists. Signed-off-by: Valentine Barshak Signed-off-by: Jiri Kosina --- drivers/hid/usbhid/hiddev.c | 168 ++++++++++++++++++++++++++++++++++---------- 1 file changed, 131 insertions(+), 37 deletions(-) diff --git a/drivers/hid/usbhid/hiddev.c b/drivers/hid/usbhid/hiddev.c index fedd88df9a18..ffee7f205fd5 100644 --- a/drivers/hid/usbhid/hiddev.c +++ b/drivers/hid/usbhid/hiddev.c @@ -586,7 +586,7 @@ static long hiddev_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { struct hiddev_list *list = file->private_data; struct hiddev *hiddev = list->hiddev; - struct hid_device *hid = hiddev->hid; + struct hid_device *hid; struct usb_device *dev; struct hiddev_collection_info cinfo; struct hiddev_report_info rinfo; @@ -594,26 +594,33 @@ static long hiddev_ioctl(struct file *file, unsigned int cmd, unsigned long arg) struct hiddev_devinfo dinfo; struct hid_report *report; struct hid_field *field; - struct usbhid_device *usbhid = hid->driver_data; + struct usbhid_device *usbhid; void __user *user_arg = (void __user *)arg; int i, r; - + /* Called without BKL by compat methods so no BKL taken */ /* FIXME: Who or what stop this racing with a disconnect ?? */ - if (!hiddev->exist || !hid) + if (!hiddev->exist) return -EIO; - dev = hid_to_usb_dev(hid); - switch (cmd) { case HIDIOCGVERSION: return put_user(HID_VERSION, (int __user *)arg); case HIDIOCAPPLICATION: - if (arg < 0 || arg >= hid->maxapplication) - return -EINVAL; + mutex_lock(&hiddev->existancelock); + if (!hiddev->exist) { + r = -ENODEV; + goto ret_unlock; + } + + hid = hiddev->hid; + if (arg < 0 || arg >= hid->maxapplication) { + r = -EINVAL; + goto ret_unlock; + } for (i = 0; i < hid->maxcollection; i++) if (hid->collection[i].type == @@ -621,11 +628,22 @@ static long hiddev_ioctl(struct file *file, unsigned int cmd, unsigned long arg) break; if (i == hid->maxcollection) - return -EINVAL; - - return hid->collection[i].usage; + r = -EINVAL; + else + r = hid->collection[i].usage; + goto ret_unlock; case HIDIOCGDEVINFO: + mutex_lock(&hiddev->existancelock); + if (!hiddev->exist) { + r = -ENODEV; + goto ret_unlock; + } + + hid = hiddev->hid; + dev = hid_to_usb_dev(hid); + usbhid = hid->driver_data; + dinfo.bustype = BUS_USB; dinfo.busnum = dev->bus->busnum; dinfo.devnum = dev->devnum; @@ -634,6 +652,8 @@ static long hiddev_ioctl(struct file *file, unsigned int cmd, unsigned long arg) dinfo.product = le16_to_cpu(dev->descriptor.idProduct); dinfo.version = le16_to_cpu(dev->descriptor.bcdDevice); dinfo.num_applications = hid->maxapplication; + mutex_unlock(&hiddev->existancelock); + if (copy_to_user(user_arg, &dinfo, sizeof(dinfo))) return -EFAULT; @@ -667,6 +687,7 @@ static long hiddev_ioctl(struct file *file, unsigned int cmd, unsigned long arg) r = hiddev_ioctl_string(hiddev, cmd, user_arg); else r = -ENODEV; +ret_unlock: mutex_unlock(&hiddev->existancelock); return r; @@ -676,6 +697,7 @@ static long hiddev_ioctl(struct file *file, unsigned int cmd, unsigned long arg) mutex_unlock(&hiddev->existancelock); return -ENODEV; } + hid = hiddev->hid; usbhid_init_reports(hid); mutex_unlock(&hiddev->existancelock); @@ -688,14 +710,21 @@ static long hiddev_ioctl(struct file *file, unsigned int cmd, unsigned long arg) if (rinfo.report_type == HID_REPORT_TYPE_OUTPUT) return -EINVAL; - if ((report = hiddev_lookup_report(hid, &rinfo)) == NULL) - return -EINVAL; - mutex_lock(&hiddev->existancelock); - if (hiddev->exist) { - usbhid_submit_report(hid, report, USB_DIR_IN); - usbhid_wait_io(hid); + if (!hiddev->exist) { + r = -ENODEV; + goto ret_unlock; + } + + hid = hiddev->hid; + report = hiddev_lookup_report(hid, &rinfo); + if (report == NULL) { + r = -EINVAL; + goto ret_unlock; } + + usbhid_submit_report(hid, report, USB_DIR_IN); + usbhid_wait_io(hid); mutex_unlock(&hiddev->existancelock); return 0; @@ -707,14 +736,21 @@ static long hiddev_ioctl(struct file *file, unsigned int cmd, unsigned long arg) if (rinfo.report_type == HID_REPORT_TYPE_INPUT) return -EINVAL; - if ((report = hiddev_lookup_report(hid, &rinfo)) == NULL) - return -EINVAL; - mutex_lock(&hiddev->existancelock); - if (hiddev->exist) { - usbhid_submit_report(hid, report, USB_DIR_OUT); - usbhid_wait_io(hid); + if (!hiddev->exist) { + r = -ENODEV; + goto ret_unlock; + } + + hid = hiddev->hid; + report = hiddev_lookup_report(hid, &rinfo); + if (report == NULL) { + r = -EINVAL; + goto ret_unlock; } + + usbhid_submit_report(hid, report, USB_DIR_OUT); + usbhid_wait_io(hid); mutex_unlock(&hiddev->existancelock); return 0; @@ -723,10 +759,21 @@ static long hiddev_ioctl(struct file *file, unsigned int cmd, unsigned long arg) if (copy_from_user(&rinfo, user_arg, sizeof(rinfo))) return -EFAULT; - if ((report = hiddev_lookup_report(hid, &rinfo)) == NULL) - return -EINVAL; + mutex_lock(&hiddev->existancelock); + if (!hiddev->exist) { + r = -ENODEV; + goto ret_unlock; + } + + hid = hiddev->hid; + report = hiddev_lookup_report(hid, &rinfo); + if (report == NULL) { + r = -EINVAL; + goto ret_unlock; + } rinfo.num_fields = report->maxfield; + mutex_unlock(&hiddev->existancelock); if (copy_to_user(user_arg, &rinfo, sizeof(rinfo))) return -EFAULT; @@ -738,11 +785,23 @@ static long hiddev_ioctl(struct file *file, unsigned int cmd, unsigned long arg) return -EFAULT; rinfo.report_type = finfo.report_type; rinfo.report_id = finfo.report_id; - if ((report = hiddev_lookup_report(hid, &rinfo)) == NULL) - return -EINVAL; + mutex_lock(&hiddev->existancelock); + if (!hiddev->exist) { + r = -ENODEV; + goto ret_unlock; + } - if (finfo.field_index >= report->maxfield) - return -EINVAL; + hid = hiddev->hid; + report = hiddev_lookup_report(hid, &rinfo); + if (report == NULL) { + r = -EINVAL; + goto ret_unlock; + } + + if (finfo.field_index >= report->maxfield) { + r = -EINVAL; + goto ret_unlock; + } field = report->field[finfo.field_index]; memset(&finfo, 0, sizeof(finfo)); @@ -760,6 +819,7 @@ static long hiddev_ioctl(struct file *file, unsigned int cmd, unsigned long arg) finfo.physical_maximum = field->physical_maximum; finfo.unit_exponent = field->unit_exponent; finfo.unit = field->unit; + mutex_unlock(&hiddev->existancelock); if (copy_to_user(user_arg, &finfo, sizeof(finfo))) return -EFAULT; @@ -785,12 +845,22 @@ static long hiddev_ioctl(struct file *file, unsigned int cmd, unsigned long arg) if (copy_from_user(&cinfo, user_arg, sizeof(cinfo))) return -EFAULT; - if (cinfo.index >= hid->maxcollection) - return -EINVAL; + mutex_lock(&hiddev->existancelock); + if (!hiddev->exist) { + r = -ENODEV; + goto ret_unlock; + } + + hid = hiddev->hid; + if (cinfo.index >= hid->maxcollection) { + r = -EINVAL; + goto ret_unlock; + } cinfo.type = hid->collection[cinfo.index].type; cinfo.usage = hid->collection[cinfo.index].usage; cinfo.level = hid->collection[cinfo.index].level; + mutex_lock(&hiddev->existancelock); if (copy_to_user(user_arg, &cinfo, sizeof(cinfo))) return -EFAULT; @@ -803,24 +873,48 @@ static long hiddev_ioctl(struct file *file, unsigned int cmd, unsigned long arg) if (_IOC_NR(cmd) == _IOC_NR(HIDIOCGNAME(0))) { int len; - if (!hid->name) - return 0; + + mutex_lock(&hiddev->existancelock); + if (!hiddev->exist) { + r = -ENODEV; + goto ret_unlock; + } + + hid = hiddev->hid; + if (!hid->name) { + r = 0; + goto ret_unlock; + } + len = strlen(hid->name) + 1; if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd); - return copy_to_user(user_arg, hid->name, len) ? + r = copy_to_user(user_arg, hid->name, len) ? -EFAULT : len; + goto ret_unlock; } if (_IOC_NR(cmd) == _IOC_NR(HIDIOCGPHYS(0))) { int len; - if (!hid->phys) - return 0; + + mutex_lock(&hiddev->existancelock); + if (!hiddev->exist) { + r = -ENODEV; + goto ret_unlock; + } + + hid = hiddev->hid; + if (!hid->phys) { + r = 0; + goto ret_unlock; + } + len = strlen(hid->phys) + 1; if (len > _IOC_SIZE(cmd)) len = _IOC_SIZE(cmd); - return copy_to_user(user_arg, hid->phys, len) ? + r = copy_to_user(user_arg, hid->phys, len) ? -EFAULT : len; + goto ret_unlock; } } return -EINVAL; -- cgit v1.2.3 From 33d6eb570b1f3fe5ba93cef465c5be66535c2c9a Mon Sep 17 00:00:00 2001 From: Valentine Barshak Date: Mon, 6 Dec 2010 18:16:11 +0300 Subject: HID: Consolidate device existence checks in hiddev_ioctl Currently, if the device has been removed before hiddev_ioctl(), the -EIO is returned. If it's removed while hiddev_ioctl() is in progress, some commands are still processed fine, others return -ENODEV. This change takes the "existancelock" before processing ioctl commands and releases it at the end. If the device has been removed, always returns -ENODEV. Signed-off-by: Valentine Barshak Signed-off-by: Jiri Kosina --- drivers/hid/usbhid/hiddev.c | 287 ++++++++++++++++---------------------------- 1 file changed, 103 insertions(+), 184 deletions(-) diff --git a/drivers/hid/usbhid/hiddev.c b/drivers/hid/usbhid/hiddev.c index ffee7f205fd5..a9935f6709f7 100644 --- a/drivers/hid/usbhid/hiddev.c +++ b/drivers/hid/usbhid/hiddev.c @@ -587,221 +587,167 @@ static long hiddev_ioctl(struct file *file, unsigned int cmd, unsigned long arg) struct hiddev_list *list = file->private_data; struct hiddev *hiddev = list->hiddev; struct hid_device *hid; - struct usb_device *dev; struct hiddev_collection_info cinfo; struct hiddev_report_info rinfo; struct hiddev_field_info finfo; struct hiddev_devinfo dinfo; struct hid_report *report; struct hid_field *field; - struct usbhid_device *usbhid; void __user *user_arg = (void __user *)arg; - int i, r; + int i, r = -EINVAL; /* Called without BKL by compat methods so no BKL taken */ - /* FIXME: Who or what stop this racing with a disconnect ?? */ - if (!hiddev->exist) - return -EIO; + mutex_lock(&hiddev->existancelock); + if (!hiddev->exist) { + r = -ENODEV; + goto ret_unlock; + } + + hid = hiddev->hid; switch (cmd) { case HIDIOCGVERSION: - return put_user(HID_VERSION, (int __user *)arg); + r = put_user(HID_VERSION, (int __user *)arg) ? + -EFAULT : 0; + break; case HIDIOCAPPLICATION: - mutex_lock(&hiddev->existancelock); - if (!hiddev->exist) { - r = -ENODEV; - goto ret_unlock; - } - - hid = hiddev->hid; - if (arg < 0 || arg >= hid->maxapplication) { - r = -EINVAL; - goto ret_unlock; - } + if (arg < 0 || arg >= hid->maxapplication) + break; for (i = 0; i < hid->maxcollection; i++) if (hid->collection[i].type == HID_COLLECTION_APPLICATION && arg-- == 0) break; - if (i == hid->maxcollection) - r = -EINVAL; - else + if (i < hid->maxcollection) r = hid->collection[i].usage; - goto ret_unlock; + break; case HIDIOCGDEVINFO: - mutex_lock(&hiddev->existancelock); - if (!hiddev->exist) { - r = -ENODEV; - goto ret_unlock; + { + struct usb_device *dev = hid_to_usb_dev(hid); + struct usbhid_device *usbhid = hid->driver_data; + + dinfo.bustype = BUS_USB; + dinfo.busnum = dev->bus->busnum; + dinfo.devnum = dev->devnum; + dinfo.ifnum = usbhid->ifnum; + dinfo.vendor = le16_to_cpu(dev->descriptor.idVendor); + dinfo.product = le16_to_cpu(dev->descriptor.idProduct); + dinfo.version = le16_to_cpu(dev->descriptor.bcdDevice); + dinfo.num_applications = hid->maxapplication; + + r = copy_to_user(user_arg, &dinfo, sizeof(dinfo)) ? + -EFAULT : 0; + break; } - hid = hiddev->hid; - dev = hid_to_usb_dev(hid); - usbhid = hid->driver_data; - - dinfo.bustype = BUS_USB; - dinfo.busnum = dev->bus->busnum; - dinfo.devnum = dev->devnum; - dinfo.ifnum = usbhid->ifnum; - dinfo.vendor = le16_to_cpu(dev->descriptor.idVendor); - dinfo.product = le16_to_cpu(dev->descriptor.idProduct); - dinfo.version = le16_to_cpu(dev->descriptor.bcdDevice); - dinfo.num_applications = hid->maxapplication; - mutex_unlock(&hiddev->existancelock); - - if (copy_to_user(user_arg, &dinfo, sizeof(dinfo))) - return -EFAULT; - - return 0; - case HIDIOCGFLAG: - if (put_user(list->flags, (int __user *)arg)) - return -EFAULT; - - return 0; + r = put_user(list->flags, (int __user *)arg) ? + -EFAULT : 0; + break; case HIDIOCSFLAG: { int newflags; - if (get_user(newflags, (int __user *)arg)) - return -EFAULT; + + if (get_user(newflags, (int __user *)arg)) { + r = -EFAULT; + break; + } if ((newflags & ~HIDDEV_FLAGS) != 0 || ((newflags & HIDDEV_FLAG_REPORT) != 0 && (newflags & HIDDEV_FLAG_UREF) == 0)) - return -EINVAL; + break; list->flags = newflags; - return 0; + r = 0; + break; } case HIDIOCGSTRING: - mutex_lock(&hiddev->existancelock); - if (hiddev->exist) - r = hiddev_ioctl_string(hiddev, cmd, user_arg); - else - r = -ENODEV; -ret_unlock: - mutex_unlock(&hiddev->existancelock); - return r; + r = hiddev_ioctl_string(hiddev, cmd, user_arg); + break; case HIDIOCINITREPORT: - mutex_lock(&hiddev->existancelock); - if (!hiddev->exist) { - mutex_unlock(&hiddev->existancelock); - return -ENODEV; - } - hid = hiddev->hid; usbhid_init_reports(hid); - mutex_unlock(&hiddev->existancelock); - - return 0; + r = 0; + break; case HIDIOCGREPORT: - if (copy_from_user(&rinfo, user_arg, sizeof(rinfo))) - return -EFAULT; + if (copy_from_user(&rinfo, user_arg, sizeof(rinfo))) { + r = -EFAULT; + break; + } if (rinfo.report_type == HID_REPORT_TYPE_OUTPUT) - return -EINVAL; + break; - mutex_lock(&hiddev->existancelock); - if (!hiddev->exist) { - r = -ENODEV; - goto ret_unlock; - } - - hid = hiddev->hid; report = hiddev_lookup_report(hid, &rinfo); - if (report == NULL) { - r = -EINVAL; - goto ret_unlock; - } + if (report == NULL) + break; usbhid_submit_report(hid, report, USB_DIR_IN); usbhid_wait_io(hid); - mutex_unlock(&hiddev->existancelock); - return 0; + r = 0; + break; case HIDIOCSREPORT: - if (copy_from_user(&rinfo, user_arg, sizeof(rinfo))) - return -EFAULT; + if (copy_from_user(&rinfo, user_arg, sizeof(rinfo))) { + r = -EFAULT; + break; + } if (rinfo.report_type == HID_REPORT_TYPE_INPUT) - return -EINVAL; - - mutex_lock(&hiddev->existancelock); - if (!hiddev->exist) { - r = -ENODEV; - goto ret_unlock; - } + break; - hid = hiddev->hid; report = hiddev_lookup_report(hid, &rinfo); - if (report == NULL) { - r = -EINVAL; - goto ret_unlock; - } + if (report == NULL) + break; usbhid_submit_report(hid, report, USB_DIR_OUT); usbhid_wait_io(hid); - mutex_unlock(&hiddev->existancelock); - return 0; + r = 0; + break; case HIDIOCGREPORTINFO: - if (copy_from_user(&rinfo, user_arg, sizeof(rinfo))) - return -EFAULT; - - mutex_lock(&hiddev->existancelock); - if (!hiddev->exist) { - r = -ENODEV; - goto ret_unlock; + if (copy_from_user(&rinfo, user_arg, sizeof(rinfo))) { + r = -EFAULT; + break; } - hid = hiddev->hid; report = hiddev_lookup_report(hid, &rinfo); - if (report == NULL) { - r = -EINVAL; - goto ret_unlock; - } + if (report == NULL) + break; rinfo.num_fields = report->maxfield; - mutex_unlock(&hiddev->existancelock); - - if (copy_to_user(user_arg, &rinfo, sizeof(rinfo))) - return -EFAULT; - return 0; + r = copy_to_user(user_arg, &rinfo, sizeof(rinfo)) ? + -EFAULT : 0; + break; case HIDIOCGFIELDINFO: - if (copy_from_user(&finfo, user_arg, sizeof(finfo))) - return -EFAULT; + if (copy_from_user(&finfo, user_arg, sizeof(finfo))) { + r = -EFAULT; + break; + } + rinfo.report_type = finfo.report_type; rinfo.report_id = finfo.report_id; - mutex_lock(&hiddev->existancelock); - if (!hiddev->exist) { - r = -ENODEV; - goto ret_unlock; - } - hid = hiddev->hid; report = hiddev_lookup_report(hid, &rinfo); - if (report == NULL) { - r = -EINVAL; - goto ret_unlock; - } + if (report == NULL) + break; - if (finfo.field_index >= report->maxfield) { - r = -EINVAL; - goto ret_unlock; - } + if (finfo.field_index >= report->maxfield) + break; field = report->field[finfo.field_index]; memset(&finfo, 0, sizeof(finfo)); @@ -819,12 +765,10 @@ ret_unlock: finfo.physical_maximum = field->physical_maximum; finfo.unit_exponent = field->unit_exponent; finfo.unit = field->unit; - mutex_unlock(&hiddev->existancelock); - if (copy_to_user(user_arg, &finfo, sizeof(finfo))) - return -EFAULT; - - return 0; + r = copy_to_user(user_arg, &finfo, sizeof(finfo)) ? + -EFAULT : 0; + break; case HIDIOCGUCODE: /* fall through */ @@ -833,57 +777,36 @@ ret_unlock: case HIDIOCGUSAGES: case HIDIOCSUSAGES: case HIDIOCGCOLLECTIONINDEX: - mutex_lock(&hiddev->existancelock); - if (hiddev->exist) - r = hiddev_ioctl_usage(hiddev, cmd, user_arg); - else - r = -ENODEV; - mutex_unlock(&hiddev->existancelock); - return r; + r = hiddev_ioctl_usage(hiddev, cmd, user_arg); + break; case HIDIOCGCOLLECTIONINFO: - if (copy_from_user(&cinfo, user_arg, sizeof(cinfo))) - return -EFAULT; - - mutex_lock(&hiddev->existancelock); - if (!hiddev->exist) { - r = -ENODEV; - goto ret_unlock; + if (copy_from_user(&cinfo, user_arg, sizeof(cinfo))) { + r = -EFAULT; + break; } - hid = hiddev->hid; - if (cinfo.index >= hid->maxcollection) { - r = -EINVAL; - goto ret_unlock; - } + if (cinfo.index >= hid->maxcollection) + break; cinfo.type = hid->collection[cinfo.index].type; cinfo.usage = hid->collection[cinfo.index].usage; cinfo.level = hid->collection[cinfo.index].level; - mutex_lock(&hiddev->existancelock); - if (copy_to_user(user_arg, &cinfo, sizeof(cinfo))) - return -EFAULT; - return 0; + r = copy_to_user(user_arg, &cinfo, sizeof(cinfo)) ? + -EFAULT : 0; + break; default: - if (_IOC_TYPE(cmd) != 'H' || _IOC_DIR(cmd) != _IOC_READ) - return -EINVAL; + break; if (_IOC_NR(cmd) == _IOC_NR(HIDIOCGNAME(0))) { int len; - mutex_lock(&hiddev->existancelock); - if (!hiddev->exist) { - r = -ENODEV; - goto ret_unlock; - } - - hid = hiddev->hid; if (!hid->name) { r = 0; - goto ret_unlock; + break; } len = strlen(hid->name) + 1; @@ -891,22 +814,15 @@ ret_unlock: len = _IOC_SIZE(cmd); r = copy_to_user(user_arg, hid->name, len) ? -EFAULT : len; - goto ret_unlock; + break; } if (_IOC_NR(cmd) == _IOC_NR(HIDIOCGPHYS(0))) { int len; - mutex_lock(&hiddev->existancelock); - if (!hiddev->exist) { - r = -ENODEV; - goto ret_unlock; - } - - hid = hiddev->hid; if (!hid->phys) { r = 0; - goto ret_unlock; + break; } len = strlen(hid->phys) + 1; @@ -914,10 +830,13 @@ ret_unlock: len = _IOC_SIZE(cmd); r = copy_to_user(user_arg, hid->phys, len) ? -EFAULT : len; - goto ret_unlock; + break; } } - return -EINVAL; + +ret_unlock: + mutex_unlock(&hiddev->existancelock); + return r; } #ifdef CONFIG_COMPAT -- cgit v1.2.3 From 6b3ed78535c5af8c1d25ed7eaaea7557698843a1 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Tue, 7 Dec 2010 16:12:29 +0800 Subject: ASoC: Fix snd_soc_instantiate_card error path Properly free the resources in the case of snd_card_register failure and soc_register_ac97_dai_link failure. Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- sound/soc/soc-core.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 392d33625327..b4c8c3800503 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -1839,18 +1839,20 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card) ret = snd_card_register(card->snd_card); if (ret < 0) { printk(KERN_ERR "asoc: failed to register soundcard for %s\n", card->name); - goto probe_dai_err; + goto probe_aux_dev_err; } #ifdef CONFIG_SND_SOC_AC97_BUS /* register any AC97 codecs */ for (i = 0; i < card->num_rtd; i++) { - ret = soc_register_ac97_dai_link(&card->rtd[i]); - if (ret < 0) { - printk(KERN_ERR "asoc: failed to register AC97 %s\n", card->name); - goto probe_dai_err; - } + ret = soc_register_ac97_dai_link(&card->rtd[i]); + if (ret < 0) { + printk(KERN_ERR "asoc: failed to register AC97 %s\n", card->name); + while (--i >= 0) + soc_unregister_ac97_dai_link(&card->rtd[i]); + goto probe_aux_dev_err; } + } #endif card->instantiated = 1; -- cgit v1.2.3 From 8ac835056ca39b242d98332f46e4d65428a8b7db Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Tue, 7 Dec 2010 20:16:56 +0100 Subject: fuse: ioctl cleanup Get rid of unnecessary page_address()-es. Signed-off-by: Miklos Szeredi CC: Tejun Heo --- fs/fuse/file.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/fs/fuse/file.c b/fs/fuse/file.c index 8b984a2cebbd..ca3b6bbb3790 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -1740,7 +1740,7 @@ long fuse_do_ioctl(struct file *file, unsigned int cmd, unsigned long arg, struct fuse_ioctl_out outarg; struct fuse_req *req = NULL; struct page **pages = NULL; - struct page *iov_page = NULL; + struct iovec *iov_page = NULL; struct iovec *in_iov = NULL, *out_iov = NULL; unsigned int in_iovs = 0, out_iovs = 0, num_pages = 0, max_pages; size_t in_size, out_size, transferred; @@ -1751,7 +1751,7 @@ long fuse_do_ioctl(struct file *file, unsigned int cmd, unsigned long arg, err = -ENOMEM; pages = kzalloc(sizeof(pages[0]) * FUSE_MAX_PAGES_PER_REQ, GFP_KERNEL); - iov_page = alloc_page(GFP_KERNEL); + iov_page = (struct iovec *) __get_free_page(GFP_KERNEL); if (!pages || !iov_page) goto out; @@ -1760,7 +1760,7 @@ long fuse_do_ioctl(struct file *file, unsigned int cmd, unsigned long arg, * RETRY from server is not allowed. */ if (!(flags & FUSE_IOCTL_UNRESTRICTED)) { - struct iovec *iov = page_address(iov_page); + struct iovec *iov = iov_page; iov->iov_base = (void __user *)arg; iov->iov_len = _IOC_SIZE(cmd); @@ -1841,7 +1841,7 @@ long fuse_do_ioctl(struct file *file, unsigned int cmd, unsigned long arg, /* did it ask for retry? */ if (outarg.flags & FUSE_IOCTL_RETRY) { - char *vaddr; + void *vaddr; /* no retry if in restricted mode */ err = -EIO; @@ -1862,14 +1862,14 @@ long fuse_do_ioctl(struct file *file, unsigned int cmd, unsigned long arg, goto out; vaddr = kmap_atomic(pages[0], KM_USER0); - err = fuse_copy_ioctl_iovec(page_address(iov_page), vaddr, + err = fuse_copy_ioctl_iovec(iov_page, vaddr, transferred, in_iovs + out_iovs, (flags & FUSE_IOCTL_COMPAT) != 0); kunmap_atomic(vaddr, KM_USER0); if (err) goto out; - in_iov = page_address(iov_page); + in_iov = iov_page; out_iov = in_iov + in_iovs; err = fuse_verify_ioctl_iov(in_iov, in_iovs); @@ -1891,8 +1891,7 @@ long fuse_do_ioctl(struct file *file, unsigned int cmd, unsigned long arg, out: if (req) fuse_put_request(fc, req); - if (iov_page) - __free_page(iov_page); + free_page((unsigned long) iov_page); while (num_pages) __free_page(pages[--num_pages]); kfree(pages); -- cgit v1.2.3 From 07e77dca8a1f17a724a9b7449f0ca02e70e9d057 Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Tue, 7 Dec 2010 20:16:56 +0100 Subject: fuse: separate queue for FORGET requests Terje Malmedal reports that a fuse filesystem with 32 million inodes on a machine with lots of memory can go unresponsive for up to 30 minutes when all those inodes are evicted from the icache. The reason is that FORGET messages, sent when the inode is evicted, are queued up together with regular filesystem requests, and while the huge queue of FORGET messages are processed no other filesystem operation can proceed. Since a full fuse request structure is allocated for each inode, these take up quite a bit of memory as well. To solve these issues, create a slim 'fuse_forget_link' structure containing just the minimum of information required to send the FORGET request and chain these on a separate queue. When userspace is asking for a request make sure that FORGET and non-FORGET requests are selected fairly: for each 8 non-FORGET allow 16 FORGET requests. This will make sure FORGETs do not pile up, yet other requests are also allowed to proceed while the queued FORGETs are processed. Reported-by: Terje Malmedal Signed-off-by: Miklos Szeredi --- fs/fuse/dev.c | 86 ++++++++++++++++++++++++++++++++++++++++++++++++++------ fs/fuse/dir.c | 53 +++++++++++++++++----------------- fs/fuse/fuse_i.h | 28 ++++++++++++------ fs/fuse/inode.c | 30 ++++++++------------ 4 files changed, 133 insertions(+), 64 deletions(-) diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c index 6e07696308dc..fed65303eeeb 100644 --- a/fs/fuse/dev.c +++ b/fs/fuse/dev.c @@ -251,6 +251,20 @@ static void queue_request(struct fuse_conn *fc, struct fuse_req *req) kill_fasync(&fc->fasync, SIGIO, POLL_IN); } +void fuse_queue_forget(struct fuse_conn *fc, struct fuse_forget_link *forget, + u64 nodeid, u64 nlookup) +{ + forget->nodeid = nodeid; + forget->nlookup = nlookup; + + spin_lock(&fc->lock); + fc->forget_list_tail->next = forget; + fc->forget_list_tail = forget; + wake_up(&fc->waitq); + kill_fasync(&fc->fasync, SIGIO, POLL_IN); + spin_unlock(&fc->lock); +} + static void flush_bg_queue(struct fuse_conn *fc) { while (fc->active_background < fc->max_background && @@ -438,12 +452,6 @@ static void fuse_request_send_nowait(struct fuse_conn *fc, struct fuse_req *req) } } -void fuse_request_send_noreply(struct fuse_conn *fc, struct fuse_req *req) -{ - req->isreply = 0; - fuse_request_send_nowait(fc, req); -} - void fuse_request_send_background(struct fuse_conn *fc, struct fuse_req *req) { req->isreply = 1; @@ -896,9 +904,15 @@ static int fuse_copy_args(struct fuse_copy_state *cs, unsigned numargs, return err; } +static int forget_pending(struct fuse_conn *fc) +{ + return fc->forget_list_head.next != NULL; +} + static int request_pending(struct fuse_conn *fc) { - return !list_empty(&fc->pending) || !list_empty(&fc->interrupts); + return !list_empty(&fc->pending) || !list_empty(&fc->interrupts) || + forget_pending(fc); } /* Wait until a request is available on the pending list */ @@ -960,6 +974,50 @@ __releases(fc->lock) return err ? err : reqsize; } +static struct fuse_forget_link *dequeue_forget(struct fuse_conn *fc) +{ + struct fuse_forget_link *forget = fc->forget_list_head.next; + + fc->forget_list_head.next = forget->next; + if (fc->forget_list_head.next == NULL) + fc->forget_list_tail = &fc->forget_list_head; + + return forget; +} + +static int fuse_read_single_forget(struct fuse_conn *fc, + struct fuse_copy_state *cs, + size_t nbytes) +__releases(fc->lock) +{ + int err; + struct fuse_forget_link *forget = dequeue_forget(fc); + struct fuse_forget_in arg = { + .nlookup = forget->nlookup, + }; + struct fuse_in_header ih = { + .opcode = FUSE_FORGET, + .nodeid = forget->nodeid, + .unique = fuse_get_unique(fc), + .len = sizeof(ih) + sizeof(arg), + }; + + spin_unlock(&fc->lock); + kfree(forget); + if (nbytes < ih.len) + return -EINVAL; + + err = fuse_copy_one(cs, &ih, sizeof(ih)); + if (!err) + err = fuse_copy_one(cs, &arg, sizeof(arg)); + fuse_copy_finish(cs); + + if (err) + return err; + + return ih.len; +} + /* * Read a single request into the userspace filesystem's buffer. This * function waits until a request is available, then removes it from @@ -998,6 +1056,14 @@ static ssize_t fuse_dev_do_read(struct fuse_conn *fc, struct file *file, return fuse_read_interrupt(fc, cs, nbytes, req); } + if (forget_pending(fc)) { + if (list_empty(&fc->pending) || fc->forget_batch-- > 0) + return fuse_read_single_forget(fc, cs, nbytes); + + if (fc->forget_batch <= -8) + fc->forget_batch = 16; + } + req = list_entry(fc->pending.next, struct fuse_req, list); req->state = FUSE_REQ_READING; list_move(&req->list, &fc->io); @@ -1090,7 +1156,7 @@ static ssize_t fuse_dev_splice_read(struct file *in, loff_t *ppos, if (!fc) return -EPERM; - bufs = kmalloc(pipe->buffers * sizeof (struct pipe_buffer), GFP_KERNEL); + bufs = kmalloc(pipe->buffers * sizeof(struct pipe_buffer), GFP_KERNEL); if (!bufs) return -ENOMEM; @@ -1626,7 +1692,7 @@ static ssize_t fuse_dev_splice_write(struct pipe_inode_info *pipe, if (!fc) return -EPERM; - bufs = kmalloc(pipe->buffers * sizeof (struct pipe_buffer), GFP_KERNEL); + bufs = kmalloc(pipe->buffers * sizeof(struct pipe_buffer), GFP_KERNEL); if (!bufs) return -ENOMEM; @@ -1770,6 +1836,8 @@ __acquires(fc->lock) flush_bg_queue(fc); end_requests(fc, &fc->pending); end_requests(fc, &fc->processing); + while (forget_pending(fc)) + kfree(dequeue_forget(fc)); } /* diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index c9627c95482d..6ea42e98cb17 100644 --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c @@ -10,9 +10,9 @@ #include #include -#include #include #include +#include #if BITS_PER_LONG >= 64 static inline void fuse_dentry_settime(struct dentry *entry, u64 time) @@ -165,7 +165,7 @@ static int fuse_dentry_revalidate(struct dentry *entry, struct nameidata *nd) struct fuse_entry_out outarg; struct fuse_conn *fc; struct fuse_req *req; - struct fuse_req *forget_req; + struct fuse_forget_link *forget; struct dentry *parent; u64 attr_version; @@ -178,8 +178,8 @@ static int fuse_dentry_revalidate(struct dentry *entry, struct nameidata *nd) if (IS_ERR(req)) return 0; - forget_req = fuse_get_req(fc); - if (IS_ERR(forget_req)) { + forget = fuse_alloc_forget(); + if (!forget) { fuse_put_request(fc, req); return 0; } @@ -199,15 +199,14 @@ static int fuse_dentry_revalidate(struct dentry *entry, struct nameidata *nd) if (!err) { struct fuse_inode *fi = get_fuse_inode(inode); if (outarg.nodeid != get_node_id(inode)) { - fuse_send_forget(fc, forget_req, - outarg.nodeid, 1); + fuse_queue_forget(fc, forget, outarg.nodeid, 1); return 0; } spin_lock(&fc->lock); fi->nlookup++; spin_unlock(&fc->lock); } - fuse_put_request(fc, forget_req); + kfree(forget); if (err || (outarg.attr.mode ^ inode->i_mode) & S_IFMT) return 0; @@ -259,7 +258,7 @@ int fuse_lookup_name(struct super_block *sb, u64 nodeid, struct qstr *name, { struct fuse_conn *fc = get_fuse_conn_super(sb); struct fuse_req *req; - struct fuse_req *forget_req; + struct fuse_forget_link *forget; u64 attr_version; int err; @@ -273,9 +272,9 @@ int fuse_lookup_name(struct super_block *sb, u64 nodeid, struct qstr *name, if (IS_ERR(req)) goto out; - forget_req = fuse_get_req(fc); - err = PTR_ERR(forget_req); - if (IS_ERR(forget_req)) { + forget = fuse_alloc_forget(); + err = -ENOMEM; + if (!forget) { fuse_put_request(fc, req); goto out; } @@ -301,13 +300,13 @@ int fuse_lookup_name(struct super_block *sb, u64 nodeid, struct qstr *name, attr_version); err = -ENOMEM; if (!*inode) { - fuse_send_forget(fc, forget_req, outarg->nodeid, 1); + fuse_queue_forget(fc, forget, outarg->nodeid, 1); goto out; } err = 0; out_put_forget: - fuse_put_request(fc, forget_req); + kfree(forget); out: return err; } @@ -374,7 +373,7 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry, int mode, struct inode *inode; struct fuse_conn *fc = get_fuse_conn(dir); struct fuse_req *req; - struct fuse_req *forget_req; + struct fuse_forget_link *forget; struct fuse_create_in inarg; struct fuse_open_out outopen; struct fuse_entry_out outentry; @@ -388,9 +387,9 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry, int mode, if (flags & O_DIRECT) return -EINVAL; - forget_req = fuse_get_req(fc); - if (IS_ERR(forget_req)) - return PTR_ERR(forget_req); + forget = fuse_alloc_forget(); + if (!forget) + return -ENOMEM; req = fuse_get_req(fc); err = PTR_ERR(req); @@ -448,10 +447,10 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry, int mode, if (!inode) { flags &= ~(O_CREAT | O_EXCL | O_TRUNC); fuse_sync_release(ff, flags); - fuse_send_forget(fc, forget_req, outentry.nodeid, 1); + fuse_queue_forget(fc, forget, outentry.nodeid, 1); return -ENOMEM; } - fuse_put_request(fc, forget_req); + kfree(forget); d_instantiate(entry, inode); fuse_change_entry_timeout(entry, &outentry); fuse_invalidate_attr(dir); @@ -469,7 +468,7 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry, int mode, out_put_request: fuse_put_request(fc, req); out_put_forget_req: - fuse_put_request(fc, forget_req); + kfree(forget); return err; } @@ -483,12 +482,12 @@ static int create_new_entry(struct fuse_conn *fc, struct fuse_req *req, struct fuse_entry_out outarg; struct inode *inode; int err; - struct fuse_req *forget_req; + struct fuse_forget_link *forget; - forget_req = fuse_get_req(fc); - if (IS_ERR(forget_req)) { + forget = fuse_alloc_forget(); + if (!forget) { fuse_put_request(fc, req); - return PTR_ERR(forget_req); + return -ENOMEM; } memset(&outarg, 0, sizeof(outarg)); @@ -515,10 +514,10 @@ static int create_new_entry(struct fuse_conn *fc, struct fuse_req *req, inode = fuse_iget(dir->i_sb, outarg.nodeid, outarg.generation, &outarg.attr, entry_attr_timeout(&outarg), 0); if (!inode) { - fuse_send_forget(fc, forget_req, outarg.nodeid, 1); + fuse_queue_forget(fc, forget, outarg.nodeid, 1); return -ENOMEM; } - fuse_put_request(fc, forget_req); + kfree(forget); if (S_ISDIR(inode->i_mode)) { struct dentry *alias; @@ -541,7 +540,7 @@ static int create_new_entry(struct fuse_conn *fc, struct fuse_req *req, return 0; out_put_forget_req: - fuse_put_request(fc, forget_req); + kfree(forget); return err; } diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index 57d4a3a0f102..33369c63a522 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h @@ -53,6 +53,13 @@ extern struct mutex fuse_mutex; extern unsigned max_user_bgreq; extern unsigned max_user_congthresh; +/* One forget request */ +struct fuse_forget_link { + u64 nodeid; + u64 nlookup; + struct fuse_forget_link *next; +}; + /** FUSE inode */ struct fuse_inode { /** Inode data */ @@ -66,7 +73,7 @@ struct fuse_inode { u64 nlookup; /** The request used for sending the FORGET message */ - struct fuse_req *forget_req; + struct fuse_forget_link *forget; /** Time in jiffies until the file attributes are valid */ u64 i_time; @@ -255,7 +262,6 @@ struct fuse_req { /** Data for asynchronous requests */ union { - struct fuse_forget_in forget_in; struct { struct fuse_release_in in; struct path path; @@ -369,6 +375,13 @@ struct fuse_conn { /** Pending interrupts */ struct list_head interrupts; + /** Queue of pending forgets */ + struct fuse_forget_link forget_list_head; + struct fuse_forget_link *forget_list_tail; + + /** Batching of FORGET requests (positive indicates FORGET batch) */ + int forget_batch; + /** Flag indicating if connection is blocked. This will be the case before the INIT reply is received, and if there are too many outstading backgrounds requests */ @@ -543,8 +556,10 @@ int fuse_lookup_name(struct super_block *sb, u64 nodeid, struct qstr *name, /** * Send FORGET command */ -void fuse_send_forget(struct fuse_conn *fc, struct fuse_req *req, - u64 nodeid, u64 nlookup); +void fuse_queue_forget(struct fuse_conn *fc, struct fuse_forget_link *forget, + u64 nodeid, u64 nlookup); + +struct fuse_forget_link *fuse_alloc_forget(void); /** * Initialize READ or READDIR request @@ -655,11 +670,6 @@ void fuse_put_request(struct fuse_conn *fc, struct fuse_req *req); */ void fuse_request_send(struct fuse_conn *fc, struct fuse_req *req); -/** - * Send a request with no reply - */ -void fuse_request_send_noreply(struct fuse_conn *fc, struct fuse_req *req); - /** * Send a request in the background */ diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index cfce3ad86a92..7ba4d351da65 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c @@ -71,6 +71,11 @@ struct fuse_mount_data { unsigned blksize; }; +struct fuse_forget_link *fuse_alloc_forget() +{ + return kzalloc(sizeof(struct fuse_forget_link), GFP_KERNEL); +} + static struct inode *fuse_alloc_inode(struct super_block *sb) { struct inode *inode; @@ -90,8 +95,8 @@ static struct inode *fuse_alloc_inode(struct super_block *sb) INIT_LIST_HEAD(&fi->queued_writes); INIT_LIST_HEAD(&fi->writepages); init_waitqueue_head(&fi->page_waitq); - fi->forget_req = fuse_request_alloc(); - if (!fi->forget_req) { + fi->forget = fuse_alloc_forget(); + if (!fi->forget) { kmem_cache_free(fuse_inode_cachep, inode); return NULL; } @@ -104,24 +109,10 @@ static void fuse_destroy_inode(struct inode *inode) struct fuse_inode *fi = get_fuse_inode(inode); BUG_ON(!list_empty(&fi->write_files)); BUG_ON(!list_empty(&fi->queued_writes)); - if (fi->forget_req) - fuse_request_free(fi->forget_req); + kfree(fi->forget); kmem_cache_free(fuse_inode_cachep, inode); } -void fuse_send_forget(struct fuse_conn *fc, struct fuse_req *req, - u64 nodeid, u64 nlookup) -{ - struct fuse_forget_in *inarg = &req->misc.forget_in; - inarg->nlookup = nlookup; - req->in.h.opcode = FUSE_FORGET; - req->in.h.nodeid = nodeid; - req->in.numargs = 1; - req->in.args[0].size = sizeof(struct fuse_forget_in); - req->in.args[0].value = inarg; - fuse_request_send_noreply(fc, req); -} - static void fuse_evict_inode(struct inode *inode) { truncate_inode_pages(&inode->i_data, 0); @@ -129,8 +120,8 @@ static void fuse_evict_inode(struct inode *inode) if (inode->i_sb->s_flags & MS_ACTIVE) { struct fuse_conn *fc = get_fuse_conn(inode); struct fuse_inode *fi = get_fuse_inode(inode); - fuse_send_forget(fc, fi->forget_req, fi->nodeid, fi->nlookup); - fi->forget_req = NULL; + fuse_queue_forget(fc, fi->forget, fi->nodeid, fi->nlookup); + fi->forget = NULL; } } @@ -534,6 +525,7 @@ void fuse_conn_init(struct fuse_conn *fc) INIT_LIST_HEAD(&fc->interrupts); INIT_LIST_HEAD(&fc->bg_queue); INIT_LIST_HEAD(&fc->entry); + fc->forget_list_tail = &fc->forget_list_head; atomic_set(&fc->num_waiting, 0); fc->max_background = FUSE_DEFAULT_MAX_BACKGROUND; fc->congestion_threshold = FUSE_DEFAULT_CONGESTION_THRESHOLD; -- cgit v1.2.3 From 02c048b919455aaa38628563cdcc2e691c8a9f53 Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Tue, 7 Dec 2010 20:16:56 +0100 Subject: fuse: allow batching of FORGET requests Terje Malmedal reports that a fuse filesystem with 32 million inodes on a machine with lots of memory can take up to 30 minutes to process FORGET requests when all those inodes are evicted from the icache. To solve this, create a BATCH_FORGET request that allows up to about 8000 FORGET requests to be sent in a single message. This request is only sent if userspace supports interface version 7.16 or later, otherwise fall back to sending individual FORGET messages. Reported-by: Terje Malmedal Signed-off-by: Miklos Szeredi --- fs/fuse/dev.c | 92 +++++++++++++++++++++++++++++++++++++++++++++------- fs/fuse/fuse_i.h | 3 +- include/linux/fuse.h | 16 ++++++++- 3 files changed, 97 insertions(+), 14 deletions(-) diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c index fed65303eeeb..cf8d28d1fbad 100644 --- a/fs/fuse/dev.c +++ b/fs/fuse/dev.c @@ -254,8 +254,8 @@ static void queue_request(struct fuse_conn *fc, struct fuse_req *req) void fuse_queue_forget(struct fuse_conn *fc, struct fuse_forget_link *forget, u64 nodeid, u64 nlookup) { - forget->nodeid = nodeid; - forget->nlookup = nlookup; + forget->forget_one.nodeid = nodeid; + forget->forget_one.nlookup = nlookup; spin_lock(&fc->lock); fc->forget_list_tail->next = forget; @@ -974,15 +974,26 @@ __releases(fc->lock) return err ? err : reqsize; } -static struct fuse_forget_link *dequeue_forget(struct fuse_conn *fc) +static struct fuse_forget_link *dequeue_forget(struct fuse_conn *fc, + unsigned max, + unsigned *countp) { - struct fuse_forget_link *forget = fc->forget_list_head.next; + struct fuse_forget_link *head = fc->forget_list_head.next; + struct fuse_forget_link **newhead = &head; + unsigned count; - fc->forget_list_head.next = forget->next; + for (count = 0; *newhead != NULL && count < max; count++) + newhead = &(*newhead)->next; + + fc->forget_list_head.next = *newhead; + *newhead = NULL; if (fc->forget_list_head.next == NULL) fc->forget_list_tail = &fc->forget_list_head; - return forget; + if (countp != NULL) + *countp = count; + + return head; } static int fuse_read_single_forget(struct fuse_conn *fc, @@ -991,13 +1002,13 @@ static int fuse_read_single_forget(struct fuse_conn *fc, __releases(fc->lock) { int err; - struct fuse_forget_link *forget = dequeue_forget(fc); + struct fuse_forget_link *forget = dequeue_forget(fc, 1, NULL); struct fuse_forget_in arg = { - .nlookup = forget->nlookup, + .nlookup = forget->forget_one.nlookup, }; struct fuse_in_header ih = { .opcode = FUSE_FORGET, - .nodeid = forget->nodeid, + .nodeid = forget->forget_one.nodeid, .unique = fuse_get_unique(fc), .len = sizeof(ih) + sizeof(arg), }; @@ -1018,6 +1029,65 @@ __releases(fc->lock) return ih.len; } +static int fuse_read_batch_forget(struct fuse_conn *fc, + struct fuse_copy_state *cs, size_t nbytes) +__releases(fc->lock) +{ + int err; + unsigned max_forgets; + unsigned count; + struct fuse_forget_link *head; + struct fuse_batch_forget_in arg = { .count = 0 }; + struct fuse_in_header ih = { + .opcode = FUSE_BATCH_FORGET, + .unique = fuse_get_unique(fc), + .len = sizeof(ih) + sizeof(arg), + }; + + if (nbytes < ih.len) { + spin_unlock(&fc->lock); + return -EINVAL; + } + + max_forgets = (nbytes - ih.len) / sizeof(struct fuse_forget_one); + head = dequeue_forget(fc, max_forgets, &count); + spin_unlock(&fc->lock); + + arg.count = count; + ih.len += count * sizeof(struct fuse_forget_one); + err = fuse_copy_one(cs, &ih, sizeof(ih)); + if (!err) + err = fuse_copy_one(cs, &arg, sizeof(arg)); + + while (head) { + struct fuse_forget_link *forget = head; + + if (!err) { + err = fuse_copy_one(cs, &forget->forget_one, + sizeof(forget->forget_one)); + } + head = forget->next; + kfree(forget); + } + + fuse_copy_finish(cs); + + if (err) + return err; + + return ih.len; +} + +static int fuse_read_forget(struct fuse_conn *fc, struct fuse_copy_state *cs, + size_t nbytes) +__releases(fc->lock) +{ + if (fc->minor < 16 || fc->forget_list_head.next->next == NULL) + return fuse_read_single_forget(fc, cs, nbytes); + else + return fuse_read_batch_forget(fc, cs, nbytes); +} + /* * Read a single request into the userspace filesystem's buffer. This * function waits until a request is available, then removes it from @@ -1058,7 +1128,7 @@ static ssize_t fuse_dev_do_read(struct fuse_conn *fc, struct file *file, if (forget_pending(fc)) { if (list_empty(&fc->pending) || fc->forget_batch-- > 0) - return fuse_read_single_forget(fc, cs, nbytes); + return fuse_read_forget(fc, cs, nbytes); if (fc->forget_batch <= -8) fc->forget_batch = 16; @@ -1837,7 +1907,7 @@ __acquires(fc->lock) end_requests(fc, &fc->pending); end_requests(fc, &fc->processing); while (forget_pending(fc)) - kfree(dequeue_forget(fc)); + kfree(dequeue_forget(fc, 1, NULL)); } /* diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index 33369c63a522..ae5744a2f9e9 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h @@ -55,8 +55,7 @@ extern unsigned max_user_congthresh; /* One forget request */ struct fuse_forget_link { - u64 nodeid; - u64 nlookup; + struct fuse_forget_one forget_one; struct fuse_forget_link *next; }; diff --git a/include/linux/fuse.h b/include/linux/fuse.h index c3c578e09833..cf11881f4938 100644 --- a/include/linux/fuse.h +++ b/include/linux/fuse.h @@ -41,6 +41,9 @@ * 7.15 * - add store notify * - add retrieve notify + * + * 7.16 + * - add BATCH_FORGET request */ #ifndef _LINUX_FUSE_H @@ -72,7 +75,7 @@ #define FUSE_KERNEL_VERSION 7 /** Minor version number of this interface */ -#define FUSE_KERNEL_MINOR_VERSION 15 +#define FUSE_KERNEL_MINOR_VERSION 16 /** The node ID of the root inode */ #define FUSE_ROOT_ID 1 @@ -256,6 +259,7 @@ enum fuse_opcode { FUSE_IOCTL = 39, FUSE_POLL = 40, FUSE_NOTIFY_REPLY = 41, + FUSE_BATCH_FORGET = 42, /* CUSE specific operations */ CUSE_INIT = 4096, @@ -290,6 +294,16 @@ struct fuse_forget_in { __u64 nlookup; }; +struct fuse_forget_one { + __u64 nodeid; + __u64 nlookup; +}; + +struct fuse_batch_forget_in { + __u32 count; + __u32 dummy; +}; + struct fuse_getattr_in { __u32 getattr_flags; __u32 dummy; -- cgit v1.2.3 From 1baa26b2be92fe9917e2f7ef46d423b5dfa4da71 Mon Sep 17 00:00:00 2001 From: Miklos Szeredi Date: Tue, 7 Dec 2010 20:16:56 +0100 Subject: fuse: fix ioctl ABI In kernel ABI version 7.16 and later FUSE_IOCTL_RETRY reply from a unrestricted IOCTL request shall return with an array of 'struct fuse_ioctl_iovec' instead of 'struct iovec'. This fixes the ABI ambiguity of 32bit vs. 64bit. Reported-by: "ccmail111" Signed-off-by: Miklos Szeredi CC: Tejun Heo --- fs/fuse/file.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++----- include/linux/fuse.h | 10 ++++++++++ 2 files changed, 58 insertions(+), 5 deletions(-) diff --git a/fs/fuse/file.c b/fs/fuse/file.c index ca3b6bbb3790..95da1bc1c826 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c @@ -1634,9 +1634,9 @@ static int fuse_ioctl_copy_user(struct page **pages, struct iovec *iov, * and 64bit. Fortunately we can determine which structure the server * used from the size of the reply. */ -static int fuse_copy_ioctl_iovec(struct iovec *dst, void *src, - size_t transferred, unsigned count, - bool is_compat) +static int fuse_copy_ioctl_iovec_old(struct iovec *dst, void *src, + size_t transferred, unsigned count, + bool is_compat) { #ifdef CONFIG_COMPAT if (count * sizeof(struct compat_iovec) == transferred) { @@ -1680,6 +1680,42 @@ static int fuse_verify_ioctl_iov(struct iovec *iov, size_t count) return 0; } +static int fuse_copy_ioctl_iovec(struct fuse_conn *fc, struct iovec *dst, + void *src, size_t transferred, unsigned count, + bool is_compat) +{ + unsigned i; + struct fuse_ioctl_iovec *fiov = src; + + if (fc->minor < 16) { + return fuse_copy_ioctl_iovec_old(dst, src, transferred, + count, is_compat); + } + + if (count * sizeof(struct fuse_ioctl_iovec) != transferred) + return -EIO; + + for (i = 0; i < count; i++) { + /* Did the server supply an inappropriate value? */ + if (fiov[i].base != (unsigned long) fiov[i].base || + fiov[i].len != (unsigned long) fiov[i].len) + return -EIO; + + dst[i].iov_base = (void __user *) (unsigned long) fiov[i].base; + dst[i].iov_len = (size_t) fiov[i].len; + +#ifdef CONFIG_COMPAT + if (is_compat && + (ptr_to_compat(dst[i].iov_base) != fiov[i].base || + (compat_size_t) dst[i].iov_len != fiov[i].len)) + return -EIO; +#endif + } + + return 0; +} + + /* * For ioctls, there is no generic way to determine how much memory * needs to be read and/or written. Furthermore, ioctls are allowed @@ -1746,8 +1782,15 @@ long fuse_do_ioctl(struct file *file, unsigned int cmd, unsigned long arg, size_t in_size, out_size, transferred; int err; +#if BITS_PER_LONG == 32 + inarg.flags |= FUSE_IOCTL_32BIT; +#else + if (flags & FUSE_IOCTL_COMPAT) + inarg.flags |= FUSE_IOCTL_32BIT; +#endif + /* assume all the iovs returned by client always fits in a page */ - BUILD_BUG_ON(sizeof(struct iovec) * FUSE_IOCTL_MAX_IOV > PAGE_SIZE); + BUILD_BUG_ON(sizeof(struct fuse_ioctl_iovec) * FUSE_IOCTL_MAX_IOV > PAGE_SIZE); err = -ENOMEM; pages = kzalloc(sizeof(pages[0]) * FUSE_MAX_PAGES_PER_REQ, GFP_KERNEL); @@ -1862,7 +1905,7 @@ long fuse_do_ioctl(struct file *file, unsigned int cmd, unsigned long arg, goto out; vaddr = kmap_atomic(pages[0], KM_USER0); - err = fuse_copy_ioctl_iovec(iov_page, vaddr, + err = fuse_copy_ioctl_iovec(fc, iov_page, vaddr, transferred, in_iovs + out_iovs, (flags & FUSE_IOCTL_COMPAT) != 0); kunmap_atomic(vaddr, KM_USER0); diff --git a/include/linux/fuse.h b/include/linux/fuse.h index cf11881f4938..d464de53db43 100644 --- a/include/linux/fuse.h +++ b/include/linux/fuse.h @@ -44,6 +44,9 @@ * * 7.16 * - add BATCH_FORGET request + * - FUSE_IOCTL_UNRESTRICTED shall now return with array of 'struct + * fuse_ioctl_iovec' instead of ambiguous 'struct iovec' + * - add FUSE_IOCTL_32BIT flag */ #ifndef _LINUX_FUSE_H @@ -203,12 +206,14 @@ struct fuse_file_lock { * FUSE_IOCTL_COMPAT: 32bit compat ioctl on 64bit machine * FUSE_IOCTL_UNRESTRICTED: not restricted to well-formed ioctls, retry allowed * FUSE_IOCTL_RETRY: retry with new iovecs + * FUSE_IOCTL_32BIT: 32bit ioctl * * FUSE_IOCTL_MAX_IOV: maximum of in_iovecs + out_iovecs */ #define FUSE_IOCTL_COMPAT (1 << 0) #define FUSE_IOCTL_UNRESTRICTED (1 << 1) #define FUSE_IOCTL_RETRY (1 << 2) +#define FUSE_IOCTL_32BIT (1 << 3) #define FUSE_IOCTL_MAX_IOV 256 @@ -524,6 +529,11 @@ struct fuse_ioctl_in { __u32 out_size; }; +struct fuse_ioctl_iovec { + __u64 base; + __u64 len; +}; + struct fuse_ioctl_out { __s32 result; __u32 flags; -- cgit v1.2.3 From c57802706aad9f179f2219415717896b3c177845 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 7 Dec 2010 23:04:14 +0000 Subject: drm/i915: Disable renderctx powersaving support for Ironlake ... still causes a failure during suspend. Reported-by: Daniel Vetter Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/intel_display.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 31fc1d797f8f..1ccf2ad7cd88 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -5952,7 +5952,7 @@ void intel_enable_clock_gating(struct drm_device *dev) * GPU can automatically power down the render unit if given a page * to save state. */ - if (IS_IRONLAKE_M(dev)) { + if (IS_IRONLAKE_M(dev) && 0) { /* XXX causes a failure during suspend */ if (dev_priv->renderctx == NULL) dev_priv->renderctx = intel_alloc_context_page(dev); if (dev_priv->renderctx) { -- cgit v1.2.3 From ca130c2267d0719c92ed188e15082d6baad6c046 Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Sat, 20 Nov 2010 14:42:57 +0100 Subject: drm/nv04-nv40: Give "gpuobj->cinst" the same meaning as on nv50. No functional changes, just simplify some code paths a bit. Signed-off-by: Francisco Jerez Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_object.c | 6 +----- drivers/gpu/drm/nouveau/nouveau_ramht.c | 4 ++-- drivers/gpu/drm/nouveau/nouveau_sgdma.c | 6 ------ 3 files changed, 3 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_object.c b/drivers/gpu/drm/nouveau/nouveau_object.c index 924653c30783..2fb7e9d47500 100644 --- a/drivers/gpu/drm/nouveau/nouveau_object.c +++ b/drivers/gpu/drm/nouveau/nouveau_object.c @@ -202,11 +202,7 @@ nouveau_gpuobj_new(struct drm_device *dev, struct nouveau_channel *chan, if (gpuobj->pinst != ~0) gpuobj->pinst += ramin->start; - if (dev_priv->card_type < NV_50) - gpuobj->cinst = gpuobj->pinst; - else - gpuobj->cinst = ramin->start; - + gpuobj->cinst = ramin->start; gpuobj->vinst = ramin->start + chan->ramin->vinst; gpuobj->node = ramin; } else { diff --git a/drivers/gpu/drm/nouveau/nouveau_ramht.c b/drivers/gpu/drm/nouveau/nouveau_ramht.c index d4a2adc927d8..bef3e6910418 100644 --- a/drivers/gpu/drm/nouveau/nouveau_ramht.c +++ b/drivers/gpu/drm/nouveau/nouveau_ramht.c @@ -104,12 +104,12 @@ nouveau_ramht_insert(struct nouveau_channel *chan, u32 handle, nouveau_gpuobj_ref(gpuobj, &entry->gpuobj); if (dev_priv->card_type < NV_40) { - ctx = NV_RAMHT_CONTEXT_VALID | (gpuobj->cinst >> 4) | + ctx = NV_RAMHT_CONTEXT_VALID | (gpuobj->pinst >> 4) | (chan->id << NV_RAMHT_CONTEXT_CHANNEL_SHIFT) | (gpuobj->engine << NV_RAMHT_CONTEXT_ENGINE_SHIFT); } else if (dev_priv->card_type < NV_50) { - ctx = (gpuobj->cinst >> 4) | + ctx = (gpuobj->pinst >> 4) | (chan->id << NV40_RAMHT_CONTEXT_CHANNEL_SHIFT) | (gpuobj->engine << NV40_RAMHT_CONTEXT_ENGINE_SHIFT); } else { diff --git a/drivers/gpu/drm/nouveau/nouveau_sgdma.c b/drivers/gpu/drm/nouveau/nouveau_sgdma.c index db32644f6114..a0bf130b02d3 100644 --- a/drivers/gpu/drm/nouveau/nouveau_sgdma.c +++ b/drivers/gpu/drm/nouveau/nouveau_sgdma.c @@ -241,12 +241,6 @@ nouveau_sgdma_init(struct drm_device *dev) } if (dev_priv->card_type < NV_50) { - /* special case, allocated from global instmem heap so - * cinst is invalid, we use it on all channels though so - * cinst needs to be valid, set it the same as pinst - */ - gpuobj->cinst = gpuobj->pinst; - nv_wo32(gpuobj, 0, NV_CLASS_DMA_IN_MEMORY | (1 << 12) /* PT present */ | (0 << 13) /* PT *not* linear */ | -- cgit v1.2.3 From 38cf189fa13e988f85efb6de26315e762cecc260 Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Sat, 20 Nov 2010 14:43:51 +0100 Subject: drm/nv04-nv10: Don't re-enable FIFO access multiple times after IRQ dispatch. nvxx_graph_isr is already taking care of it. In some cases this could've made you miss PGRAPH interrupts (e.g. when you were supposed to get several IRQs of the same kind in a row). Signed-off-by: Francisco Jerez Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nv04_graph.c | 3 --- drivers/gpu/drm/nouveau/nv10_graph.c | 12 ------------ 2 files changed, 15 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nv04_graph.c b/drivers/gpu/drm/nouveau/nv04_graph.c index 0bc616d35eb6..af75015068d6 100644 --- a/drivers/gpu/drm/nouveau/nv04_graph.c +++ b/drivers/gpu/drm/nouveau/nv04_graph.c @@ -373,7 +373,6 @@ nv04_graph_context_switch(struct drm_device *dev) struct nouveau_channel *chan = NULL; int chid; - pgraph->fifo_access(dev, false); nouveau_wait_for_idle(dev); /* If previous context is valid, we need to save it */ @@ -384,8 +383,6 @@ nv04_graph_context_switch(struct drm_device *dev) chan = dev_priv->channels.ptr[chid]; if (chan) nv04_graph_load_context(chan); - - pgraph->fifo_access(dev, true); } static uint32_t *ctx_reg(struct graph_state *ctx, uint32_t reg) diff --git a/drivers/gpu/drm/nouveau/nv10_graph.c b/drivers/gpu/drm/nouveau/nv10_graph.c index 536b39e4a9e2..8c92edb7bbcd 100644 --- a/drivers/gpu/drm/nouveau/nv10_graph.c +++ b/drivers/gpu/drm/nouveau/nv10_graph.c @@ -794,11 +794,9 @@ static void nv10_graph_context_switch(struct drm_device *dev) { struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; struct nouveau_channel *chan = NULL; int chid; - pgraph->fifo_access(dev, false); nouveau_wait_for_idle(dev); /* If previous context is valid, we need to save it */ @@ -809,8 +807,6 @@ nv10_graph_context_switch(struct drm_device *dev) chan = dev_priv->channels.ptr[chid]; if (chan && chan->pgraph_ctx) nv10_graph_load_context(chan); - - pgraph->fifo_access(dev, true); } #define NV_WRITE_CTX(reg, val) do { \ @@ -980,8 +976,6 @@ nv17_graph_mthd_lma_window(struct nouveau_channel *chan, struct drm_device *dev = chan->dev; struct graph_state *ctx = chan->pgraph_ctx; struct pipe_state *pipe = &ctx->pipe_state; - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; uint32_t pipe_0x0040[1], pipe_0x64c0[8], pipe_0x6a80[3], pipe_0x6ab0[3]; uint32_t xfmode0, xfmode1; int i; @@ -1048,8 +1042,6 @@ nv17_graph_mthd_lma_window(struct nouveau_channel *chan, nouveau_wait_for_idle(dev); - pgraph->fifo_access(dev, true); - return 0; } @@ -1058,8 +1050,6 @@ nv17_graph_mthd_lma_enable(struct nouveau_channel *chan, u32 class, u32 mthd, u32 data) { struct drm_device *dev = chan->dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; nouveau_wait_for_idle(dev); @@ -1068,8 +1058,6 @@ nv17_graph_mthd_lma_enable(struct nouveau_channel *chan, nv_wr32(dev, 0x004006b0, nv_rd32(dev, 0x004006b0) | 0x8 << 24); - pgraph->fifo_access(dev, true); - return 0; } -- cgit v1.2.3 From 6dccd311dd4b104b3bc53cb67aef414141d11c9f Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Thu, 18 Nov 2010 23:57:46 +0100 Subject: drm/nouveau: Synchronize with the user channel before GPU object destruction. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There have been reports of PFIFO cache errors during context take down (fdo bug 31637). They are caused by some GPU objects being taken out while the channel is still potentially processing commands. Make sure that all the previous rendering has landed before releasing a GPU object. Reported-by: Grzesiek Sójka Reported-by: Patrice Mandin Signed-off-by: Francisco Jerez Acked-by: Ben Skeggs Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_channel.c | 36 +++++++++++++++++++------------ drivers/gpu/drm/nouveau/nouveau_drv.c | 16 ++------------ drivers/gpu/drm/nouveau/nouveau_drv.h | 1 + drivers/gpu/drm/nouveau/nouveau_object.c | 3 +++ 4 files changed, 28 insertions(+), 28 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_channel.c b/drivers/gpu/drm/nouveau/nouveau_channel.c index 0f33132fba3b..3e49babd62ac 100644 --- a/drivers/gpu/drm/nouveau/nouveau_channel.c +++ b/drivers/gpu/drm/nouveau/nouveau_channel.c @@ -284,7 +284,6 @@ nouveau_channel_put_unlocked(struct nouveau_channel **pchan) struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; struct nouveau_crypt_engine *pcrypt = &dev_priv->engine.crypt; unsigned long flags; - int ret; /* decrement the refcount, and we're done if there's still refs */ if (likely(!atomic_dec_and_test(&chan->users))) { @@ -297,19 +296,7 @@ nouveau_channel_put_unlocked(struct nouveau_channel **pchan) nouveau_debugfs_channel_fini(chan); /* give it chance to idle */ - nouveau_fence_update(chan); - if (chan->fence.sequence != chan->fence.sequence_ack) { - struct nouveau_fence *fence = NULL; - - ret = nouveau_fence_new(chan, &fence, true); - if (ret == 0) { - ret = nouveau_fence_wait(fence, false, false); - nouveau_fence_unref(&fence); - } - - if (ret) - NV_ERROR(dev, "Failed to idle channel %d.\n", chan->id); - } + nouveau_channel_idle(chan); /* ensure all outstanding fences are signaled. they should be if the * above attempts at idling were OK, but if we failed this'll tell TTM @@ -388,6 +375,27 @@ nouveau_channel_ref(struct nouveau_channel *chan, *pchan = chan; } +void +nouveau_channel_idle(struct nouveau_channel *chan) +{ + struct drm_device *dev = chan->dev; + struct nouveau_fence *fence = NULL; + int ret; + + nouveau_fence_update(chan); + + if (chan->fence.sequence != chan->fence.sequence_ack) { + ret = nouveau_fence_new(chan, &fence, true); + if (!ret) { + ret = nouveau_fence_wait(fence, false, false); + nouveau_fence_unref(&fence); + } + + if (ret) + NV_ERROR(dev, "Failed to idle channel %d.\n", chan->id); + } +} + /* cleans up all the fifos from file_priv */ void nouveau_channel_cleanup(struct drm_device *dev, struct drm_file *file_priv) diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.c b/drivers/gpu/drm/nouveau/nouveau_drv.c index 7ff5b4369f03..a48c7da133d2 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.c +++ b/drivers/gpu/drm/nouveau/nouveau_drv.c @@ -197,22 +197,10 @@ nouveau_pci_suspend(struct pci_dev *pdev, pm_message_t pm_state) NV_INFO(dev, "Idling channels...\n"); for (i = 0; i < pfifo->channels; i++) { - struct nouveau_fence *fence = NULL; - chan = dev_priv->channels.ptr[i]; - if (!chan || !chan->pushbuf_bo) - continue; - - ret = nouveau_fence_new(chan, &fence, true); - if (ret == 0) { - ret = nouveau_fence_wait(fence, false, false); - nouveau_fence_unref(&fence); - } - if (ret) { - NV_ERROR(dev, "Failed to idle channel %d for suspend\n", - chan->id); - } + if (chan && chan->pushbuf_bo) + nouveau_channel_idle(chan); } pgraph->fifo_access(dev, false); diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index a52b1da32031..d001453e857b 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -847,6 +847,7 @@ extern void nouveau_channel_put_unlocked(struct nouveau_channel **); extern void nouveau_channel_put(struct nouveau_channel **); extern void nouveau_channel_ref(struct nouveau_channel *chan, struct nouveau_channel **pchan); +extern void nouveau_channel_idle(struct nouveau_channel *chan); /* nouveau_object.c */ #define NVOBJ_CLASS(d,c,e) do { \ diff --git a/drivers/gpu/drm/nouveau/nouveau_object.c b/drivers/gpu/drm/nouveau/nouveau_object.c index 2fb7e9d47500..24540862a23f 100644 --- a/drivers/gpu/drm/nouveau/nouveau_object.c +++ b/drivers/gpu/drm/nouveau/nouveau_object.c @@ -1017,6 +1017,9 @@ int nouveau_ioctl_gpuobj_free(struct drm_device *dev, void *data, if (IS_ERR(chan)) return PTR_ERR(chan); + /* Synchronize with the user channel */ + nouveau_channel_idle(chan); + ret = nouveau_ramht_remove(chan, objfree->handle); nouveau_channel_put(&chan); return ret; -- cgit v1.2.3 From a3d487ea5463a9c091b7f9b836b860cf3d82e641 Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Sat, 20 Nov 2010 22:11:22 +0100 Subject: drm/nouveau: Use WC memory on the AGP GART. Signed-off-by: Francisco Jerez Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_bo.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index f4ee43db00aa..f6f51b4259e7 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c @@ -424,8 +424,9 @@ nouveau_bo_init_mem_type(struct ttm_bo_device *bdev, uint32_t type, switch (dev_priv->gart_info.type) { case NOUVEAU_GART_AGP: man->flags = TTM_MEMTYPE_FLAG_MAPPABLE; - man->available_caching = TTM_PL_FLAG_UNCACHED; - man->default_caching = TTM_PL_FLAG_UNCACHED; + man->available_caching = TTM_PL_FLAG_UNCACHED | + TTM_PL_FLAG_WC; + man->default_caching = TTM_PL_FLAG_WC; break; case NOUVEAU_GART_SGDMA: man->flags = TTM_MEMTYPE_FLAG_MAPPABLE | -- cgit v1.2.3 From 395a31ec7ed9b02c5412f4405acbd6fceacca0fc Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Thu, 25 Nov 2010 16:37:17 +0100 Subject: drm/nouveau: Spin for a bit in nouveau_fence_wait() before yielding the CPU. Sleeping doesn't pay off for very short delays in comparison with the minimum granularity of schedule_timeout(). Signed-off-by: Francisco Jerez Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_fence.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_fence.c b/drivers/gpu/drm/nouveau/nouveau_fence.c index 2579fc69d182..abfeff19488e 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fence.c +++ b/drivers/gpu/drm/nouveau/nouveau_fence.c @@ -218,6 +218,7 @@ int __nouveau_fence_wait(void *sync_obj, void *sync_arg, bool lazy, bool intr) { unsigned long timeout = jiffies + (3 * DRM_HZ); + unsigned long sleep_time = jiffies + 1; int ret = 0; while (1) { @@ -231,7 +232,7 @@ __nouveau_fence_wait(void *sync_obj, void *sync_arg, bool lazy, bool intr) __set_current_state(intr ? TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE); - if (lazy) + if (lazy && time_after_eq(jiffies, sleep_time)) schedule_timeout(1); if (intr && signal_pending(current)) { -- cgit v1.2.3 From d908175cca901b95ba1628428b216e6e7188e8fb Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 22 Nov 2010 16:05:54 +1000 Subject: drm/nouveau: make fifo.create_context() responsible for mapping control regs The regs belong to PFIFO, they're different for pretty much the same generations we need different PFIFO control for, and NVC0 is going to be even more different than the rest. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_channel.c | 22 +--------------------- drivers/gpu/drm/nouveau/nv04_fifo.c | 9 +++++++++ drivers/gpu/drm/nouveau/nv10_fifo.c | 5 +++++ drivers/gpu/drm/nouveau/nv40_fifo.c | 5 +++++ drivers/gpu/drm/nouveau/nv50_fifo.c | 9 +++++++++ 5 files changed, 29 insertions(+), 21 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_channel.c b/drivers/gpu/drm/nouveau/nouveau_channel.c index 3e49babd62ac..a3d33a582a98 100644 --- a/drivers/gpu/drm/nouveau/nouveau_channel.c +++ b/drivers/gpu/drm/nouveau/nouveau_channel.c @@ -113,7 +113,7 @@ nouveau_channel_alloc(struct drm_device *dev, struct nouveau_channel **chan_ret, struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo; struct nouveau_channel *chan; unsigned long flags; - int user, ret; + int ret; /* allocate and lock channel structure */ chan = kzalloc(sizeof(*chan), GFP_KERNEL); @@ -160,23 +160,6 @@ nouveau_channel_alloc(struct drm_device *dev, struct nouveau_channel **chan_ret, } nouveau_dma_pre_init(chan); - - /* Locate channel's user control regs */ - if (dev_priv->card_type < NV_40) - user = NV03_USER(chan->id); - else - if (dev_priv->card_type < NV_50) - user = NV40_USER(chan->id); - else - user = NV50_USER(chan->id); - - chan->user = ioremap(pci_resource_start(dev->pdev, 0) + user, - PAGE_SIZE); - if (!chan->user) { - NV_ERROR(dev, "ioremap of regs failed.\n"); - nouveau_channel_put(&chan); - return -ENOMEM; - } chan->user_put = 0x40; chan->user_get = 0x44; @@ -356,9 +339,6 @@ nouveau_channel_del(struct kref *ref) struct nouveau_channel *chan = container_of(ref, struct nouveau_channel, ref); - if (chan->user) - iounmap(chan->user); - kfree(chan); } diff --git a/drivers/gpu/drm/nouveau/nv04_fifo.c b/drivers/gpu/drm/nouveau/nv04_fifo.c index a32ba8ccaae6..f89d104698df 100644 --- a/drivers/gpu/drm/nouveau/nv04_fifo.c +++ b/drivers/gpu/drm/nouveau/nv04_fifo.c @@ -129,6 +129,11 @@ nv04_fifo_create_context(struct nouveau_channel *chan) if (ret) return ret; + chan->user = ioremap(pci_resource_start(dev->pdev, 0) + + NV03_USER(chan->id), PAGE_SIZE); + if (!chan->user) + return -ENOMEM; + spin_lock_irqsave(&dev_priv->context_switch_lock, flags); /* Setup initial state */ @@ -173,6 +178,10 @@ nv04_fifo_destroy_context(struct nouveau_channel *chan) spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags); /* Free the channel resources */ + if (chan->user) { + iounmap(chan->user); + chan->user = NULL; + } nouveau_gpuobj_ref(NULL, &chan->ramfc); } diff --git a/drivers/gpu/drm/nouveau/nv10_fifo.c b/drivers/gpu/drm/nouveau/nv10_fifo.c index acb9216e6d0a..d2ecbff4bee1 100644 --- a/drivers/gpu/drm/nouveau/nv10_fifo.c +++ b/drivers/gpu/drm/nouveau/nv10_fifo.c @@ -53,6 +53,11 @@ nv10_fifo_create_context(struct nouveau_channel *chan) if (ret) return ret; + chan->user = ioremap(pci_resource_start(dev->pdev, 0) + + NV03_USER(chan->id), PAGE_SIZE); + if (!chan->user) + return -ENOMEM; + /* Fill entries that are seen filled in dumps of nvidia driver just * after channel's is put into DMA mode */ diff --git a/drivers/gpu/drm/nouveau/nv40_fifo.c b/drivers/gpu/drm/nouveau/nv40_fifo.c index f6b3580c685a..c86e4d4e9b96 100644 --- a/drivers/gpu/drm/nouveau/nv40_fifo.c +++ b/drivers/gpu/drm/nouveau/nv40_fifo.c @@ -47,6 +47,11 @@ nv40_fifo_create_context(struct nouveau_channel *chan) if (ret) return ret; + chan->user = ioremap(pci_resource_start(dev->pdev, 0) + + NV40_USER(chan->id), PAGE_SIZE); + if (!chan->user) + return -ENOMEM; + spin_lock_irqsave(&dev_priv->context_switch_lock, flags); nv_wi32(dev, fc + 0, chan->pushbuf_base); diff --git a/drivers/gpu/drm/nouveau/nv50_fifo.c b/drivers/gpu/drm/nouveau/nv50_fifo.c index ed18952ae7f4..7add3dfde3df 100644 --- a/drivers/gpu/drm/nouveau/nv50_fifo.c +++ b/drivers/gpu/drm/nouveau/nv50_fifo.c @@ -261,6 +261,11 @@ nv50_fifo_create_context(struct nouveau_channel *chan) } ramfc = chan->ramfc; + chan->user = ioremap(pci_resource_start(dev->pdev, 0) + + NV50_USER(chan->id), PAGE_SIZE); + if (!chan->user) + return -ENOMEM; + spin_lock_irqsave(&dev_priv->context_switch_lock, flags); nv_wo32(ramfc, 0x48, chan->pushbuf->cinst >> 4); @@ -327,6 +332,10 @@ nv50_fifo_destroy_context(struct nouveau_channel *chan) spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags); /* Free the channel resources */ + if (chan->user) { + iounmap(chan->user); + chan->user = NULL; + } nouveau_gpuobj_ref(NULL, &ramfc); nouveau_gpuobj_ref(NULL, &chan->cache); } -- cgit v1.2.3 From ceac30999dfb00ee7b56cfea8b28ef50999a3c95 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 23 Nov 2010 10:10:24 +1000 Subject: drm/nouveau: implicitly insert non-DMA objects into RAMHT Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_dma.c | 10 ++---- drivers/gpu/drm/nouveau/nouveau_drv.h | 3 +- drivers/gpu/drm/nouveau/nouveau_fence.c | 7 +--- drivers/gpu/drm/nouveau/nouveau_object.c | 59 +++++++++++++++----------------- drivers/gpu/drm/nouveau/nv04_fbcon.c | 34 ++++++------------ drivers/gpu/drm/nouveau/nv50_fbcon.c | 10 ++---- 6 files changed, 43 insertions(+), 80 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_dma.c b/drivers/gpu/drm/nouveau/nouveau_dma.c index 82581e600dcd..6ff77cedc008 100644 --- a/drivers/gpu/drm/nouveau/nouveau_dma.c +++ b/drivers/gpu/drm/nouveau/nouveau_dma.c @@ -59,17 +59,11 @@ nouveau_dma_init(struct nouveau_channel *chan) { struct drm_device *dev = chan->dev; struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_gpuobj *obj = NULL; int ret, i; /* Create NV_MEMORY_TO_MEMORY_FORMAT for buffer moves */ - ret = nouveau_gpuobj_gr_new(chan, dev_priv->card_type < NV_50 ? - 0x0039 : 0x5039, &obj); - if (ret) - return ret; - - ret = nouveau_ramht_insert(chan, NvM2MF, obj); - nouveau_gpuobj_ref(NULL, &obj); + ret = nouveau_gpuobj_gr_new(chan, NvM2MF, dev_priv->card_type < NV_50 ? + 0x0039 : 0x5039); if (ret) return ret; diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index d001453e857b..bbf19861b6c8 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -887,8 +887,7 @@ extern int nouveau_gpuobj_new_fake(struct drm_device *, u32 pinst, u64 vinst, extern int nouveau_gpuobj_dma_new(struct nouveau_channel *, int class, uint64_t offset, uint64_t size, int access, int target, struct nouveau_gpuobj **); -extern int nouveau_gpuobj_gr_new(struct nouveau_channel *, int class, - struct nouveau_gpuobj **); +extern int nouveau_gpuobj_gr_new(struct nouveau_channel *, u32 handle, int class); extern int nv50_gpuobj_dma_new(struct nouveau_channel *, int class, u64 base, u64 size, int target, int access, u32 type, u32 comp, struct nouveau_gpuobj **pobj); diff --git a/drivers/gpu/drm/nouveau/nouveau_fence.c b/drivers/gpu/drm/nouveau/nouveau_fence.c index abfeff19488e..3d50d5c3b0fe 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fence.c +++ b/drivers/gpu/drm/nouveau/nouveau_fence.c @@ -438,12 +438,7 @@ nouveau_fence_channel_init(struct nouveau_channel *chan) int ret; /* Create an NV_SW object for various sync purposes */ - ret = nouveau_gpuobj_gr_new(chan, NV_SW, &obj); - if (ret) - return ret; - - ret = nouveau_ramht_insert(chan, NvSw, obj); - nouveau_gpuobj_ref(NULL, &obj); + ret = nouveau_gpuobj_gr_new(chan, NvSw, NV_SW); if (ret) return ret; diff --git a/drivers/gpu/drm/nouveau/nouveau_object.c b/drivers/gpu/drm/nouveau/nouveau_object.c index 24540862a23f..3518ebba6fbd 100644 --- a/drivers/gpu/drm/nouveau/nouveau_object.c +++ b/drivers/gpu/drm/nouveau/nouveau_object.c @@ -608,13 +608,9 @@ static int nouveau_gpuobj_sw_new(struct nouveau_channel *chan, int class, struct nouveau_gpuobj **gpuobj_ret) { - struct drm_nouveau_private *dev_priv; + struct drm_nouveau_private *dev_priv = chan->dev->dev_private; struct nouveau_gpuobj *gpuobj; - if (!chan || !gpuobj_ret || *gpuobj_ret != NULL) - return -EINVAL; - dev_priv = chan->dev->dev_private; - gpuobj = kzalloc(sizeof(*gpuobj), GFP_KERNEL); if (!gpuobj) return -ENOMEM; @@ -632,12 +628,12 @@ nouveau_gpuobj_sw_new(struct nouveau_channel *chan, int class, } int -nouveau_gpuobj_gr_new(struct nouveau_channel *chan, int class, - struct nouveau_gpuobj **gpuobj) +nouveau_gpuobj_gr_new(struct nouveau_channel *chan, u32 handle, int class) { struct drm_nouveau_private *dev_priv = chan->dev->dev_private; struct drm_device *dev = chan->dev; struct nouveau_gpuobj_class *oc; + struct nouveau_gpuobj *gpuobj; int ret; NV_DEBUG(dev, "ch%d class=0x%04x\n", chan->id, class); @@ -651,10 +647,12 @@ nouveau_gpuobj_gr_new(struct nouveau_channel *chan, int class, return -EINVAL; found: - if (oc->engine == NVOBJ_ENGINE_SW) - return nouveau_gpuobj_sw_new(chan, class, gpuobj); - switch (oc->engine) { + case NVOBJ_ENGINE_SW: + ret = nouveau_gpuobj_sw_new(chan, class, &gpuobj); + if (ret) + return ret; + goto insert; case NVOBJ_ENGINE_GR: if (dev_priv->card_type >= NV_50 && !chan->ramin_grctx) { struct nouveau_pgraph_engine *pgraph = @@ -681,41 +679,47 @@ found: nouveau_gpuobj_class_instmem_size(dev, class), 16, NVOBJ_FLAG_ZERO_ALLOC | NVOBJ_FLAG_ZERO_FREE, - gpuobj); + &gpuobj); if (ret) { NV_ERROR(dev, "error creating gpuobj: %d\n", ret); return ret; } if (dev_priv->card_type >= NV_50) { - nv_wo32(*gpuobj, 0, class); - nv_wo32(*gpuobj, 20, 0x00010000); + nv_wo32(gpuobj, 0, class); + nv_wo32(gpuobj, 20, 0x00010000); } else { switch (class) { case NV_CLASS_NULL: - nv_wo32(*gpuobj, 0, 0x00001030); - nv_wo32(*gpuobj, 4, 0xFFFFFFFF); + nv_wo32(gpuobj, 0, 0x00001030); + nv_wo32(gpuobj, 4, 0xFFFFFFFF); break; default: if (dev_priv->card_type >= NV_40) { - nv_wo32(*gpuobj, 0, class); + nv_wo32(gpuobj, 0, class); #ifdef __BIG_ENDIAN - nv_wo32(*gpuobj, 8, 0x01000000); + nv_wo32(gpuobj, 8, 0x01000000); #endif } else { #ifdef __BIG_ENDIAN - nv_wo32(*gpuobj, 0, class | 0x00080000); + nv_wo32(gpuobj, 0, class | 0x00080000); #else - nv_wo32(*gpuobj, 0, class); + nv_wo32(gpuobj, 0, class); #endif } } } dev_priv->engine.instmem.flush(dev); - (*gpuobj)->engine = oc->engine; - (*gpuobj)->class = oc->id; - return 0; + gpuobj->engine = oc->engine; + gpuobj->class = oc->id; + +insert: + ret = nouveau_ramht_insert(chan, handle, gpuobj); + if (ret) + NV_ERROR(dev, "error adding gpuobj to RAMHT: %d\n", ret); + nouveau_gpuobj_ref(NULL, &gpuobj); + return ret; } static int @@ -971,7 +975,6 @@ int nouveau_ioctl_grobj_alloc(struct drm_device *dev, void *data, struct drm_file *file_priv) { struct drm_nouveau_grobj_alloc *init = data; - struct nouveau_gpuobj *gr = NULL; struct nouveau_channel *chan; int ret; @@ -987,18 +990,10 @@ int nouveau_ioctl_grobj_alloc(struct drm_device *dev, void *data, goto out; } - ret = nouveau_gpuobj_gr_new(chan, init->class, &gr); + ret = nouveau_gpuobj_gr_new(chan, init->handle, init->class); if (ret) { NV_ERROR(dev, "Error creating object: %d (%d/0x%08x)\n", ret, init->channel, init->handle); - goto out; - } - - ret = nouveau_ramht_insert(chan, init->handle, gr); - nouveau_gpuobj_ref(NULL, &gr); - if (ret) { - NV_ERROR(dev, "Error referencing object: %d (%d/0x%08x)\n", - ret, init->channel, init->handle); } out: diff --git a/drivers/gpu/drm/nouveau/nv04_fbcon.c b/drivers/gpu/drm/nouveau/nv04_fbcon.c index a32804e7d202..7a1189371096 100644 --- a/drivers/gpu/drm/nouveau/nv04_fbcon.c +++ b/drivers/gpu/drm/nouveau/nv04_fbcon.c @@ -137,22 +137,6 @@ nv04_fbcon_imageblit(struct fb_info *info, const struct fb_image *image) return 0; } -static int -nv04_fbcon_grobj_new(struct drm_device *dev, int class, uint32_t handle) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_gpuobj *obj = NULL; - int ret; - - ret = nouveau_gpuobj_gr_new(dev_priv->channel, class, &obj); - if (ret) - return ret; - - ret = nouveau_ramht_insert(dev_priv->channel, handle, obj); - nouveau_gpuobj_ref(NULL, &obj); - return ret; -} - int nv04_fbcon_accel_init(struct fb_info *info) { @@ -192,29 +176,31 @@ nv04_fbcon_accel_init(struct fb_info *info) return -EINVAL; } - ret = nv04_fbcon_grobj_new(dev, dev_priv->card_type >= NV_10 ? - 0x0062 : 0x0042, NvCtxSurf2D); + ret = nouveau_gpuobj_gr_new(chan, NvCtxSurf2D, + dev_priv->card_type >= NV_10 ? + 0x0062 : 0x0042); if (ret) return ret; - ret = nv04_fbcon_grobj_new(dev, 0x0019, NvClipRect); + ret = nouveau_gpuobj_gr_new(chan, NvClipRect, 0x0019); if (ret) return ret; - ret = nv04_fbcon_grobj_new(dev, 0x0043, NvRop); + ret = nouveau_gpuobj_gr_new(chan, NvRop, 0x0043); if (ret) return ret; - ret = nv04_fbcon_grobj_new(dev, 0x0044, NvImagePatt); + ret = nouveau_gpuobj_gr_new(chan, NvImagePatt, 0x0044); if (ret) return ret; - ret = nv04_fbcon_grobj_new(dev, 0x004a, NvGdiRect); + ret = nouveau_gpuobj_gr_new(chan, NvGdiRect, 0x004a); if (ret) return ret; - ret = nv04_fbcon_grobj_new(dev, dev_priv->chipset >= 0x11 ? - 0x009f : 0x005f, NvImageBlit); + ret = nouveau_gpuobj_gr_new(chan, NvImageBlit, + dev_priv->chipset >= 0x11 ? + 0x009f : 0x005f); if (ret) return ret; diff --git a/drivers/gpu/drm/nouveau/nv50_fbcon.c b/drivers/gpu/drm/nouveau/nv50_fbcon.c index 6edf9dca35ca..156731993907 100644 --- a/drivers/gpu/drm/nouveau/nv50_fbcon.c +++ b/drivers/gpu/drm/nouveau/nv50_fbcon.c @@ -134,9 +134,8 @@ nv50_fbcon_accel_init(struct fb_info *info) struct drm_device *dev = nfbdev->dev; struct drm_nouveau_private *dev_priv = dev->dev_private; struct nouveau_channel *chan = dev_priv->channel; - struct nouveau_gpuobj *eng2d = NULL; - uint64_t fb; int ret, format; + uint64_t fb; fb = info->fix.smem_start - dev_priv->fb_phys + dev_priv->vm_vram_base; @@ -167,12 +166,7 @@ nv50_fbcon_accel_init(struct fb_info *info) return -EINVAL; } - ret = nouveau_gpuobj_gr_new(dev_priv->channel, 0x502d, &eng2d); - if (ret) - return ret; - - ret = nouveau_ramht_insert(dev_priv->channel, Nv2D, eng2d); - nouveau_gpuobj_ref(NULL, &eng2d); + ret = nouveau_gpuobj_gr_new(dev_priv->channel, Nv2D, 0x502d); if (ret) return ret; -- cgit v1.2.3 From 12fb9525075982bc65cfd71427dd7afdf47bafed Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 19 Nov 2010 14:32:56 +1000 Subject: drm/nouveau: introduce a util function to wait on reg != val Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_drv.h | 10 +++++++--- drivers/gpu/drm/nouveau/nouveau_hw.c | 4 ++-- drivers/gpu/drm/nouveau/nouveau_state.c | 22 ++++++++++++++++++++-- drivers/gpu/drm/nouveau/nv04_dac.c | 12 ++++++------ 4 files changed, 35 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index bbf19861b6c8..e82dff4008c9 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -795,8 +795,10 @@ extern int nouveau_ioctl_getparam(struct drm_device *, void *data, struct drm_file *); extern int nouveau_ioctl_setparam(struct drm_device *, void *data, struct drm_file *); -extern bool nouveau_wait_until(struct drm_device *, uint64_t timeout, - uint32_t reg, uint32_t mask, uint32_t val); +extern bool nouveau_wait_eq(struct drm_device *, uint64_t timeout, + uint32_t reg, uint32_t mask, uint32_t val); +extern bool nouveau_wait_ne(struct drm_device *, uint64_t timeout, + uint32_t reg, uint32_t mask, uint32_t val); extern bool nouveau_wait_for_idle(struct drm_device *); extern int nouveau_card_init(struct drm_device *); @@ -1434,7 +1436,9 @@ static inline void nv_wr08(struct drm_device *dev, unsigned reg, u8 val) } #define nv_wait(dev, reg, mask, val) \ - nouveau_wait_until(dev, 2000000000ULL, (reg), (mask), (val)) + nouveau_wait_eq(dev, 2000000000ULL, (reg), (mask), (val)) +#define nv_wait_ne(dev, reg, mask, val) \ + nouveau_wait_ne(dev, 2000000000ULL, (reg), (mask), (val)) /* PRAMIN access */ static inline u32 nv_ri32(struct drm_device *dev, unsigned offset) diff --git a/drivers/gpu/drm/nouveau/nouveau_hw.c b/drivers/gpu/drm/nouveau/nouveau_hw.c index 6ba640e7a7e9..053edf9d2f67 100644 --- a/drivers/gpu/drm/nouveau/nouveau_hw.c +++ b/drivers/gpu/drm/nouveau/nouveau_hw.c @@ -999,8 +999,8 @@ nv_load_state_ext(struct drm_device *dev, int head, if (dev_priv->card_type == NV_10) { /* Not waiting for vertical retrace before modifying CRE_53/CRE_54 causes lockups. */ - nouveau_wait_until(dev, 650000000, NV_PRMCIO_INP0__COLOR, 0x8, 0x8); - nouveau_wait_until(dev, 650000000, NV_PRMCIO_INP0__COLOR, 0x8, 0x0); + nouveau_wait_eq(dev, 650000000, NV_PRMCIO_INP0__COLOR, 0x8, 0x8); + nouveau_wait_eq(dev, 650000000, NV_PRMCIO_INP0__COLOR, 0x8, 0x0); } wr_cio_state(dev, head, regp, NV_CIO_CRE_53); diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c index e779e9320453..e0811f93243d 100644 --- a/drivers/gpu/drm/nouveau/nouveau_state.c +++ b/drivers/gpu/drm/nouveau/nouveau_state.c @@ -1126,8 +1126,9 @@ nouveau_ioctl_setparam(struct drm_device *dev, void *data, } /* Wait until (value(reg) & mask) == val, up until timeout has hit */ -bool nouveau_wait_until(struct drm_device *dev, uint64_t timeout, - uint32_t reg, uint32_t mask, uint32_t val) +bool +nouveau_wait_eq(struct drm_device *dev, uint64_t timeout, + uint32_t reg, uint32_t mask, uint32_t val) { struct drm_nouveau_private *dev_priv = dev->dev_private; struct nouveau_timer_engine *ptimer = &dev_priv->engine.timer; @@ -1141,6 +1142,23 @@ bool nouveau_wait_until(struct drm_device *dev, uint64_t timeout, return false; } +/* Wait until (value(reg) & mask) != val, up until timeout has hit */ +bool +nouveau_wait_ne(struct drm_device *dev, uint64_t timeout, + uint32_t reg, uint32_t mask, uint32_t val) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_timer_engine *ptimer = &dev_priv->engine.timer; + uint64_t start = ptimer->read(dev); + + do { + if ((nv_rd32(dev, reg) & mask) != val) + return true; + } while (ptimer->read(dev) - start < timeout); + + return false; +} + /* Waits for PGRAPH to go completely idle */ bool nouveau_wait_for_idle(struct drm_device *dev) { diff --git a/drivers/gpu/drm/nouveau/nv04_dac.c b/drivers/gpu/drm/nouveau/nv04_dac.c index ba6423f2ffcc..e000455e06d0 100644 --- a/drivers/gpu/drm/nouveau/nv04_dac.c +++ b/drivers/gpu/drm/nouveau/nv04_dac.c @@ -74,14 +74,14 @@ static int sample_load_twice(struct drm_device *dev, bool sense[2]) * use a 10ms timeout (guards against crtc being inactive, in * which case blank state would never change) */ - if (!nouveau_wait_until(dev, 10000000, NV_PRMCIO_INP0__COLOR, - 0x00000001, 0x00000000)) + if (!nouveau_wait_eq(dev, 10000000, NV_PRMCIO_INP0__COLOR, + 0x00000001, 0x00000000)) return -EBUSY; - if (!nouveau_wait_until(dev, 10000000, NV_PRMCIO_INP0__COLOR, - 0x00000001, 0x00000001)) + if (!nouveau_wait_eq(dev, 10000000, NV_PRMCIO_INP0__COLOR, + 0x00000001, 0x00000001)) return -EBUSY; - if (!nouveau_wait_until(dev, 10000000, NV_PRMCIO_INP0__COLOR, - 0x00000001, 0x00000000)) + if (!nouveau_wait_eq(dev, 10000000, NV_PRMCIO_INP0__COLOR, + 0x00000001, 0x00000000)) return -EBUSY; udelay(100); -- cgit v1.2.3 From a0fd9b9f68cd7a5952eae3c5b3c5a3bc0eadfd44 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 26 Nov 2010 10:32:22 +1000 Subject: drm/nouveau: no need to zero dma objects, we fill them completely anyway Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_object.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_object.c b/drivers/gpu/drm/nouveau/nouveau_object.c index 3518ebba6fbd..5cc3f7e59fa1 100644 --- a/drivers/gpu/drm/nouveau/nouveau_object.c +++ b/drivers/gpu/drm/nouveau/nouveau_object.c @@ -460,8 +460,7 @@ nv50_gpuobj_dma_new(struct nouveau_channel *chan, int class, u64 base, u64 size, struct drm_device *dev = chan->dev; int ret; - ret = nouveau_gpuobj_new(dev, chan, 24, 16, NVOBJ_FLAG_ZERO_ALLOC | - NVOBJ_FLAG_ZERO_FREE, pobj); + ret = nouveau_gpuobj_new(dev, chan, 24, 16, NVOBJ_FLAG_ZERO_FREE, pobj); if (ret) return ret; @@ -536,9 +535,7 @@ nouveau_gpuobj_dma_new(struct nouveau_channel *chan, int class, u64 base, flags0 |= (base & 0x00000fff) << 20; flags2 |= (base & 0xfffff000); - ret = nouveau_gpuobj_new(dev, chan, (dev_priv->card_type >= NV_40) ? - 32 : 16, 16, NVOBJ_FLAG_ZERO_ALLOC | - NVOBJ_FLAG_ZERO_FREE, &obj); + ret = nouveau_gpuobj_new(dev, chan, 16, 16, NVOBJ_FLAG_ZERO_FREE, &obj); if (ret) return ret; -- cgit v1.2.3 From 7a45d764a8e3177f0c9cd4a0be9f2ab7965e55cb Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 22 Nov 2010 08:50:27 +1000 Subject: drm/nouveau: wrap calls to ttm_bo_validate() This will be used later to fixup bo.offset with a buffer's fixed GPU virtual address. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_bo.c | 20 +++++++++++++++++--- drivers/gpu/drm/nouveau/nouveau_drv.h | 2 ++ drivers/gpu/drm/nouveau/nouveau_gem.c | 3 +-- 3 files changed, 20 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index f6f51b4259e7..a7883e7db344 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c @@ -242,7 +242,7 @@ nouveau_bo_pin(struct nouveau_bo *nvbo, uint32_t memtype) nouveau_bo_placement_set(nvbo, memtype, 0); - ret = ttm_bo_validate(bo, &nvbo->placement, false, false, false); + ret = nouveau_bo_validate(nvbo, false, false, false); if (ret == 0) { switch (bo->mem.mem_type) { case TTM_PL_VRAM: @@ -278,7 +278,7 @@ nouveau_bo_unpin(struct nouveau_bo *nvbo) nouveau_bo_placement_set(nvbo, bo->mem.placement, 0); - ret = ttm_bo_validate(bo, &nvbo->placement, false, false, false); + ret = nouveau_bo_validate(nvbo, false, false, false); if (ret == 0) { switch (bo->mem.mem_type) { case TTM_PL_VRAM: @@ -317,6 +317,20 @@ nouveau_bo_unmap(struct nouveau_bo *nvbo) ttm_bo_kunmap(&nvbo->kmap); } +int +nouveau_bo_validate(struct nouveau_bo *nvbo, bool interruptible, + bool no_wait_reserve, bool no_wait_gpu) +{ + int ret; + + ret = ttm_bo_validate(&nvbo->bo, &nvbo->placement, interruptible, + no_wait_reserve, no_wait_gpu); + if (ret) + return ret; + + return 0; +} + u16 nouveau_bo_rd16(struct nouveau_bo *nvbo, unsigned index) { @@ -937,7 +951,7 @@ nouveau_ttm_fault_reserve_notify(struct ttm_buffer_object *bo) nvbo->placement.fpfn = 0; nvbo->placement.lpfn = dev_priv->fb_mappable_pages; nouveau_bo_placement_set(nvbo, TTM_PL_VRAM, 0); - return ttm_bo_validate(bo, &nvbo->placement, false, true, false); + return nouveau_bo_validate(nvbo, false, true, false); } void diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index e82dff4008c9..22abe8579912 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -1285,6 +1285,8 @@ extern void nouveau_bo_wr16(struct nouveau_bo *nvbo, unsigned index, u16 val); extern u32 nouveau_bo_rd32(struct nouveau_bo *nvbo, unsigned index); extern void nouveau_bo_wr32(struct nouveau_bo *nvbo, unsigned index, u32 val); extern void nouveau_bo_fence(struct nouveau_bo *, struct nouveau_fence *); +extern int nouveau_bo_validate(struct nouveau_bo *, bool interruptible, + bool no_wait_reserve, bool no_wait_gpu); /* nouveau_fence.c */ struct nouveau_fence; diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c index 9886b644f27d..0adb2a85c143 100644 --- a/drivers/gpu/drm/nouveau/nouveau_gem.c +++ b/drivers/gpu/drm/nouveau/nouveau_gem.c @@ -358,8 +358,7 @@ validate_list(struct nouveau_channel *chan, struct list_head *list, } nvbo->channel = (b->read_domains & (1 << 31)) ? NULL : chan; - ret = ttm_bo_validate(&nvbo->bo, &nvbo->placement, - true, false, false); + ret = nouveau_bo_validate(nvbo, true, false, false); nvbo->channel = NULL; if (unlikely(ret)) { if (ret != -ERESTARTSYS) -- cgit v1.2.3 From a8b214f007e299225d3fcf10c46f7fc603c275fa Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 3 Dec 2010 09:05:20 +1000 Subject: drm/nouveau: fix use of drm_mm_node in semaphore object At some point in the future, this bo won't necessarily be backed by a drm_mm_node, so use the start/size fields of the ttm_mem_reg instead. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_fence.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_fence.c b/drivers/gpu/drm/nouveau/nouveau_fence.c index 3d50d5c3b0fe..01290d2952ae 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fence.c +++ b/drivers/gpu/drm/nouveau/nouveau_fence.c @@ -450,12 +450,11 @@ nouveau_fence_channel_init(struct nouveau_channel *chan) /* Create a DMA object for the shared cross-channel sync area. */ if (USE_SEMA(dev)) { - struct drm_mm_node *mem = dev_priv->fence.bo->bo.mem.mm_node; + struct ttm_mem_reg *mem = &dev_priv->fence.bo->bo.mem; ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY, mem->start << PAGE_SHIFT, - mem->size << PAGE_SHIFT, - NV_MEM_ACCESS_RW, + mem->size, NV_MEM_ACCESS_RW, NV_MEM_TARGET_VRAM, &obj); if (ret) return ret; -- cgit v1.2.3 From 937c3471cc8b7ef8f9e382d9e4ec232db151ea7b Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Wed, 8 Dec 2010 02:35:45 +0100 Subject: drm/nouveau: Avoid potential race between nouveau_fence_update() and context takedown. Signed-off-by: Francisco Jerez Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_fence.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_fence.c b/drivers/gpu/drm/nouveau/nouveau_fence.c index 01290d2952ae..374a9793b85f 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fence.c +++ b/drivers/gpu/drm/nouveau/nouveau_fence.c @@ -77,14 +77,17 @@ nouveau_fence_update(struct nouveau_channel *chan) spin_lock(&chan->fence.lock); - if (USE_REFCNT(dev)) - sequence = nvchan_rd32(chan, 0x48); - else - sequence = atomic_read(&chan->fence.last_sequence_irq); - - if (chan->fence.sequence_ack == sequence) - goto out; - chan->fence.sequence_ack = sequence; + /* Fetch the last sequence if the channel is still up and running */ + if (likely(!list_empty(&chan->fence.pending))) { + if (USE_REFCNT(dev)) + sequence = nvchan_rd32(chan, 0x48); + else + sequence = atomic_read(&chan->fence.last_sequence_irq); + + if (chan->fence.sequence_ack == sequence) + goto out; + chan->fence.sequence_ack = sequence; + } list_for_each_entry_safe(fence, tmp, &chan->fence.pending, entry) { sequence = fence->sequence; -- cgit v1.2.3 From 573a2a37e8648a3249426c816f51e7ef50f6f73e Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 25 Aug 2010 15:26:04 +1000 Subject: drm/nv50: implement custom vram mm This is required on nv50 as we need to be able to have more precise control over physical VRAM allocations to avoid buffer corruption when using buffers of mixed memory types. This removes some nasty overallocation/alignment that we were previously using to "control" this problem. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/Makefile | 5 +- drivers/gpu/drm/nouveau/nouveau_bo.c | 43 +----- drivers/gpu/drm/nouveau/nouveau_drv.h | 10 ++ drivers/gpu/drm/nouveau/nouveau_mem.c | 201 ++++++++++++++---------- drivers/gpu/drm/nouveau/nouveau_mm.c | 271 +++++++++++++++++++++++++++++++++ drivers/gpu/drm/nouveau/nouveau_mm.h | 61 ++++++++ drivers/gpu/drm/nouveau/nv50_instmem.c | 1 + drivers/gpu/drm/nouveau/nv50_vram.c | 180 ++++++++++++++++++++++ 8 files changed, 650 insertions(+), 122 deletions(-) create mode 100644 drivers/gpu/drm/nouveau/nouveau_mm.c create mode 100644 drivers/gpu/drm/nouveau/nouveau_mm.h create mode 100644 drivers/gpu/drm/nouveau/nv50_vram.c diff --git a/drivers/gpu/drm/nouveau/Makefile b/drivers/gpu/drm/nouveau/Makefile index 7ea9a1154ca8..26fdd12561b6 100644 --- a/drivers/gpu/drm/nouveau/Makefile +++ b/drivers/gpu/drm/nouveau/Makefile @@ -9,7 +9,7 @@ nouveau-y := nouveau_drv.o nouveau_state.o nouveau_channel.o nouveau_mem.o \ nouveau_bo.o nouveau_fence.o nouveau_gem.o nouveau_ttm.o \ nouveau_hw.o nouveau_calc.o nouveau_bios.o nouveau_i2c.o \ nouveau_display.o nouveau_connector.o nouveau_fbcon.o \ - nouveau_dp.o nouveau_ramht.o \ + nouveau_dp.o nouveau_ramht.o nouveau_mm.o \ nouveau_pm.o nouveau_volt.o nouveau_perf.o nouveau_temp.o \ nv04_timer.o \ nv04_mc.o nv40_mc.o nv50_mc.o \ @@ -26,7 +26,8 @@ nouveau-y := nouveau_drv.o nouveau_state.o nouveau_channel.o nouveau_mem.o \ nv04_crtc.o nv04_display.o nv04_cursor.o nv04_fbcon.o \ nv10_gpio.o nv50_gpio.o \ nv50_calc.o \ - nv04_pm.o nv50_pm.o nva3_pm.o + nv04_pm.o nv50_pm.o nva3_pm.o \ + nv50_vram.o nouveau-$(CONFIG_DRM_NOUVEAU_DEBUG) += nouveau_debugfs.o nouveau-$(CONFIG_COMPAT) += nouveau_ioc32.o diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index a7883e7db344..5a71ca4346c8 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c @@ -57,42 +57,7 @@ nouveau_bo_fixup_align(struct drm_device *dev, { struct drm_nouveau_private *dev_priv = dev->dev_private; - /* - * Some of the tile_flags have a periodic structure of N*4096 bytes, - * align to to that as well as the page size. Align the size to the - * appropriate boundaries. This does imply that sizes are rounded up - * 3-7 pages, so be aware of this and do not waste memory by allocating - * many small buffers. - */ - if (dev_priv->card_type == NV_50) { - uint32_t block_size = dev_priv->vram_size >> 15; - int i; - - switch (tile_flags) { - case 0x1800: - case 0x2800: - case 0x4800: - case 0x7a00: - if (is_power_of_2(block_size)) { - for (i = 1; i < 10; i++) { - *align = 12 * i * block_size; - if (!(*align % 65536)) - break; - } - } else { - for (i = 1; i < 10; i++) { - *align = 8 * i * block_size; - if (!(*align % 65536)) - break; - } - } - *size = roundup(*size, *align); - break; - default: - break; - } - - } else { + if (dev_priv->card_type < NV_50) { if (tile_mode) { if (dev_priv->chipset >= 0x40) { *align = 65536; @@ -115,7 +80,6 @@ nouveau_bo_fixup_align(struct drm_device *dev, /* ALIGN works only on powers of two. */ *size = roundup(*size, PAGE_SIZE); - if (dev_priv->card_type == NV_50) { *size = roundup(*size, 65536); *align = max(65536, *align); @@ -422,7 +386,10 @@ nouveau_bo_init_mem_type(struct ttm_bo_device *bdev, uint32_t type, man->default_caching = TTM_PL_FLAG_CACHED; break; case TTM_PL_VRAM: - man->func = &ttm_bo_manager_func; + if (dev_priv->card_type == NV_50) + man->func = &nouveau_vram_manager; + else + man->func = &ttm_bo_manager_func; man->flags = TTM_MEMTYPE_FLAG_FIXED | TTM_MEMTYPE_FLAG_MAPPABLE; man->available_caching = TTM_PL_FLAG_UNCACHED | diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index 22abe8579912..1305e2c94201 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -66,6 +66,15 @@ struct nouveau_grctx; #define NV50_VM_BLOCK (512*1024*1024ULL) #define NV50_VM_VRAM_NR (NV50_VM_MAX_VRAM / NV50_VM_BLOCK) +struct nouveau_vram { + struct drm_device *dev; + + struct list_head regions; + u32 memtype; + u64 offset; + u64 size; +}; + struct nouveau_tile_reg { bool used; uint32_t addr; @@ -821,6 +830,7 @@ extern int nv50_mem_vm_bind_linear(struct drm_device *, uint64_t virt, uint64_t phys); extern void nv50_mem_vm_unbind(struct drm_device *, uint64_t virt, uint32_t size); +extern const struct ttm_mem_type_manager_func nouveau_vram_manager; /* nouveau_notifier.c */ extern int nouveau_notifier_init_channel(struct nouveau_channel *); diff --git a/drivers/gpu/drm/nouveau/nouveau_mem.c b/drivers/gpu/drm/nouveau/nouveau_mem.c index 549f59052881..dbeb9e5f6b22 100644 --- a/drivers/gpu/drm/nouveau/nouveau_mem.c +++ b/drivers/gpu/drm/nouveau/nouveau_mem.c @@ -36,6 +36,7 @@ #include "nouveau_drv.h" #include "nouveau_pm.h" +#include "nouveau_mm.h" /* * NV10-NV40 tiling helpers @@ -333,61 +334,6 @@ nouveau_mem_detect_nforce(struct drm_device *dev) return 0; } -static void -nv50_vram_preinit(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - int i, parts, colbits, rowbitsa, rowbitsb, banks; - u64 rowsize, predicted; - u32 r0, r4, rt, ru; - - r0 = nv_rd32(dev, 0x100200); - r4 = nv_rd32(dev, 0x100204); - rt = nv_rd32(dev, 0x100250); - ru = nv_rd32(dev, 0x001540); - NV_DEBUG(dev, "memcfg 0x%08x 0x%08x 0x%08x 0x%08x\n", r0, r4, rt, ru); - - for (i = 0, parts = 0; i < 8; i++) { - if (ru & (0x00010000 << i)) - parts++; - } - - colbits = (r4 & 0x0000f000) >> 12; - rowbitsa = ((r4 & 0x000f0000) >> 16) + 8; - rowbitsb = ((r4 & 0x00f00000) >> 20) + 8; - banks = ((r4 & 0x01000000) ? 8 : 4); - - rowsize = parts * banks * (1 << colbits) * 8; - predicted = rowsize << rowbitsa; - if (r0 & 0x00000004) - predicted += rowsize << rowbitsb; - - if (predicted != dev_priv->vram_size) { - NV_WARN(dev, "memory controller reports %dMiB VRAM\n", - (u32)(dev_priv->vram_size >> 20)); - NV_WARN(dev, "we calculated %dMiB VRAM\n", - (u32)(predicted >> 20)); - } - - dev_priv->vram_rblock_size = rowsize >> 12; - if (rt & 1) - dev_priv->vram_rblock_size *= 3; - - NV_DEBUG(dev, "rblock %lld bytes\n", - (u64)dev_priv->vram_rblock_size << 12); -} - -static void -nvaa_vram_preinit(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - - /* To our knowledge, there's no large scale reordering of pages - * that occurs on IGP chipsets. - */ - dev_priv->vram_rblock_size = 1; -} - static int nouveau_mem_detect(struct drm_device *dev) { @@ -404,22 +350,8 @@ nouveau_mem_detect(struct drm_device *dev) dev_priv->vram_size &= NV10_PFB_FIFO_DATA_RAM_AMOUNT_MB_MASK; } else if (dev_priv->card_type < NV_C0) { - dev_priv->vram_size = nv_rd32(dev, NV04_PFB_FIFO_DATA); - dev_priv->vram_size |= (dev_priv->vram_size & 0xff) << 32; - dev_priv->vram_size &= 0xffffffff00ll; - - switch (dev_priv->chipset) { - case 0xaa: - case 0xac: - case 0xaf: - dev_priv->vram_sys_base = nv_rd32(dev, 0x100e10); - dev_priv->vram_sys_base <<= 12; - nvaa_vram_preinit(dev); - break; - default: - nv50_vram_preinit(dev); - break; - } + if (nv50_vram_init(dev)) + return -ENOMEM; } else { dev_priv->vram_size = nv_rd32(dev, 0x10f20c) << 20; dev_priv->vram_size *= nv_rd32(dev, 0x121c74); @@ -568,10 +500,6 @@ nouveau_mem_vram_init(struct drm_device *dev) if (ret) return ret; - ret = nouveau_mem_detect(dev); - if (ret) - return ret; - dev_priv->fb_phys = pci_resource_start(dev->pdev, 1); ret = nouveau_ttm_global_init(dev_priv); @@ -587,13 +515,6 @@ nouveau_mem_vram_init(struct drm_device *dev) return ret; } - dev_priv->fb_available_size = dev_priv->vram_size; - dev_priv->fb_mappable_pages = dev_priv->fb_available_size; - if (dev_priv->fb_mappable_pages > pci_resource_len(dev->pdev, 1)) - dev_priv->fb_mappable_pages = - pci_resource_len(dev->pdev, 1); - dev_priv->fb_mappable_pages >>= PAGE_SHIFT; - /* reserve space at end of VRAM for PRAMIN */ if (dev_priv->chipset == 0x40 || dev_priv->chipset == 0x47 || dev_priv->chipset == 0x49 || dev_priv->chipset == 0x4b) @@ -604,6 +525,17 @@ nouveau_mem_vram_init(struct drm_device *dev) else dev_priv->ramin_rsvd_vram = (512 * 1024); + /* initialise gpu-specific vram backend */ + ret = nouveau_mem_detect(dev); + if (ret) + return ret; + + dev_priv->fb_available_size = dev_priv->vram_size; + dev_priv->fb_mappable_pages = dev_priv->fb_available_size; + if (dev_priv->fb_mappable_pages > pci_resource_len(dev->pdev, 1)) + dev_priv->fb_mappable_pages = pci_resource_len(dev->pdev, 1); + dev_priv->fb_mappable_pages >>= PAGE_SHIFT; + dev_priv->fb_available_size -= dev_priv->ramin_rsvd_vram; dev_priv->fb_aper_free = dev_priv->fb_available_size; @@ -820,3 +752,108 @@ nouveau_mem_timing_fini(struct drm_device *dev) kfree(mem->timing); } + +static int +nouveau_vram_manager_init(struct ttm_mem_type_manager *man, unsigned long p_size) +{ + struct drm_nouveau_private *dev_priv = nouveau_bdev(man->bdev); + struct nouveau_mm *mm; + u32 b_size; + int ret; + + p_size = (p_size << PAGE_SHIFT) >> 12; + b_size = dev_priv->vram_rblock_size >> 12; + + ret = nouveau_mm_init(&mm, 0, p_size, b_size); + if (ret) + return ret; + + man->priv = mm; + return 0; +} + +static int +nouveau_vram_manager_fini(struct ttm_mem_type_manager *man) +{ + struct nouveau_mm *mm = man->priv; + int ret; + + ret = nouveau_mm_fini(&mm); + if (ret) + return ret; + + man->priv = NULL; + return 0; +} + +static void +nouveau_vram_manager_del(struct ttm_mem_type_manager *man, + struct ttm_mem_reg *mem) +{ + struct drm_nouveau_private *dev_priv = nouveau_bdev(man->bdev); + struct drm_device *dev = dev_priv->dev; + + nv50_vram_del(dev, (struct nouveau_vram **)&mem->mm_node); +} + +static int +nouveau_vram_manager_new(struct ttm_mem_type_manager *man, + struct ttm_buffer_object *bo, + struct ttm_placement *placement, + struct ttm_mem_reg *mem) +{ + struct drm_nouveau_private *dev_priv = nouveau_bdev(man->bdev); + struct drm_device *dev = dev_priv->dev; + struct nouveau_bo *nvbo = nouveau_bo(bo); + struct nouveau_vram *vram; + int ret; + + ret = nv50_vram_new(dev, mem->num_pages << PAGE_SHIFT, 65536, 0, + (nvbo->tile_flags >> 8) & 0x7f, &vram); + if (ret) + return ret; + + mem->mm_node = vram; + mem->start = vram->offset >> PAGE_SHIFT; + return 0; +} + +void +nouveau_vram_manager_debug(struct ttm_mem_type_manager *man, const char *prefix) +{ + struct ttm_bo_global *glob = man->bdev->glob; + struct nouveau_mm *mm = man->priv; + struct nouveau_mm_node *r; + u64 total = 0, ttotal[3] = {}, tused[3] = {}, tfree[3] = {}; + int i; + + mutex_lock(&mm->mutex); + list_for_each_entry(r, &mm->nodes, nl_entry) { + printk(KERN_DEBUG "%s %s-%d: 0x%010llx 0x%010llx\n", + prefix, r->free ? "free" : "used", r->type, + ((u64)r->offset << 12), + (((u64)r->offset + r->length) << 12)); + total += r->length; + ttotal[r->type] += r->length; + if (r->free) + tfree[r->type] += r->length; + else + tused[r->type] += r->length; + } + mutex_unlock(&mm->mutex); + + printk(KERN_DEBUG "%s total: 0x%010llx\n", prefix, total << 12); + for (i = 0; i < 3; i++) { + printk(KERN_DEBUG "%s type %d: 0x%010llx, " + "used 0x%010llx, free 0x%010llx\n", prefix, + i, ttotal[i] << 12, tused[i] << 12, tfree[i] << 12); + } +} + +const struct ttm_mem_type_manager_func nouveau_vram_manager = { + nouveau_vram_manager_init, + nouveau_vram_manager_fini, + nouveau_vram_manager_new, + nouveau_vram_manager_del, + nouveau_vram_manager_debug +}; diff --git a/drivers/gpu/drm/nouveau/nouveau_mm.c b/drivers/gpu/drm/nouveau/nouveau_mm.c new file mode 100644 index 000000000000..cdbb11eb701b --- /dev/null +++ b/drivers/gpu/drm/nouveau/nouveau_mm.c @@ -0,0 +1,271 @@ +/* + * Copyright 2010 Red Hat Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: Ben Skeggs + */ + +#include "drmP.h" +#include "nouveau_drv.h" +#include "nouveau_mm.h" + +static inline void +region_put(struct nouveau_mm *rmm, struct nouveau_mm_node *a) +{ + list_del(&a->nl_entry); + list_del(&a->fl_entry); + kfree(a); +} + +static struct nouveau_mm_node * +region_split(struct nouveau_mm *rmm, struct nouveau_mm_node *a, u32 size) +{ + struct nouveau_mm_node *b; + + if (a->length == size) + return a; + + b = kmalloc(sizeof(*b), GFP_KERNEL); + if (unlikely(b == NULL)) + return NULL; + + b->offset = a->offset; + b->length = size; + b->free = a->free; + b->type = a->type; + a->offset += size; + a->length -= size; + list_add_tail(&b->nl_entry, &a->nl_entry); + if (b->free) + list_add_tail(&b->fl_entry, &a->fl_entry); + return b; +} + +static struct nouveau_mm_node * +nouveau_mm_merge(struct nouveau_mm *rmm, struct nouveau_mm_node *this) +{ + struct nouveau_mm_node *prev, *next; + + /* try to merge with free adjacent entries of same type */ + prev = list_entry(this->nl_entry.prev, struct nouveau_mm_node, nl_entry); + if (this->nl_entry.prev != &rmm->nodes) { + if (prev->free && prev->type == this->type) { + prev->length += this->length; + region_put(rmm, this); + this = prev; + } + } + + next = list_entry(this->nl_entry.next, struct nouveau_mm_node, nl_entry); + if (this->nl_entry.next != &rmm->nodes) { + if (next->free && next->type == this->type) { + next->offset = this->offset; + next->length += this->length; + region_put(rmm, this); + this = next; + } + } + + return this; +} + +void +nouveau_mm_put(struct nouveau_mm *rmm, struct nouveau_mm_node *this) +{ + u32 block_s, block_l; + + this->free = true; + list_add(&this->fl_entry, &rmm->free); + this = nouveau_mm_merge(rmm, this); + + /* any entirely free blocks now? we'll want to remove typing + * on them now so they can be use for any memory allocation + */ + block_s = roundup(this->offset, rmm->block_size); + if (block_s + rmm->block_size > this->offset + this->length) + return; + + /* split off any still-typed region at the start */ + if (block_s != this->offset) { + if (!region_split(rmm, this, block_s - this->offset)) + return; + } + + /* split off the soon-to-be-untyped block(s) */ + block_l = rounddown(this->length, rmm->block_size); + if (block_l != this->length) { + this = region_split(rmm, this, block_l); + if (!this) + return; + } + + /* mark as having no type, and retry merge with any adjacent + * untyped blocks + */ + this->type = 0; + nouveau_mm_merge(rmm, this); +} + +int +nouveau_mm_get(struct nouveau_mm *rmm, int type, u32 size, u32 size_nc, + u32 align, struct nouveau_mm_node **pnode) +{ + struct nouveau_mm_node *this, *tmp, *next; + u32 splitoff, avail, alloc; + + list_for_each_entry_safe(this, tmp, &rmm->free, fl_entry) { + next = list_entry(this->nl_entry.next, struct nouveau_mm_node, nl_entry); + if (this->nl_entry.next == &rmm->nodes) + next = NULL; + + /* skip wrongly typed blocks */ + if (this->type && this->type != type) + continue; + + /* account for alignment */ + splitoff = this->offset & (align - 1); + if (splitoff) + splitoff = align - splitoff; + + if (this->length <= splitoff) + continue; + + /* determine total memory available from this, and + * the next block (if appropriate) + */ + avail = this->length; + if (next && next->free && (!next->type || next->type == type)) + avail += next->length; + + avail -= splitoff; + + /* determine allocation size */ + if (size_nc) { + alloc = min(avail, size); + alloc = rounddown(alloc, size_nc); + if (alloc == 0) + continue; + } else { + alloc = size; + if (avail < alloc) + continue; + } + + /* untyped block, split off a chunk that's a multiple + * of block_size and type it + */ + if (!this->type) { + u32 block = roundup(alloc + splitoff, rmm->block_size); + if (this->length < block) + continue; + + this = region_split(rmm, this, block); + if (!this) + return -ENOMEM; + + this->type = type; + } + + /* stealing memory from adjacent block */ + if (alloc > this->length) { + u32 amount = alloc - (this->length - splitoff); + + if (!next->type) { + amount = roundup(amount, rmm->block_size); + + next = region_split(rmm, next, amount); + if (!next) + return -ENOMEM; + + next->type = type; + } + + this->length += amount; + next->offset += amount; + next->length -= amount; + if (!next->length) { + list_del(&next->nl_entry); + list_del(&next->fl_entry); + kfree(next); + } + } + + if (splitoff) { + if (!region_split(rmm, this, splitoff)) + return -ENOMEM; + } + + this = region_split(rmm, this, alloc); + if (this == NULL) + return -ENOMEM; + + this->free = false; + list_del(&this->fl_entry); + *pnode = this; + return 0; + } + + return -ENOMEM; +} + +int +nouveau_mm_init(struct nouveau_mm **prmm, u32 offset, u32 length, u32 block) +{ + struct nouveau_mm *rmm; + struct nouveau_mm_node *heap; + + heap = kzalloc(sizeof(*heap), GFP_KERNEL); + if (!heap) + return -ENOMEM; + heap->free = true; + heap->offset = roundup(offset, block); + heap->length = rounddown(offset + length, block) - heap->offset; + + rmm = kzalloc(sizeof(*rmm), GFP_KERNEL); + if (!rmm) { + kfree(heap); + return -ENOMEM; + } + rmm->block_size = block; + mutex_init(&rmm->mutex); + INIT_LIST_HEAD(&rmm->nodes); + INIT_LIST_HEAD(&rmm->free); + list_add(&heap->nl_entry, &rmm->nodes); + list_add(&heap->fl_entry, &rmm->free); + + *prmm = rmm; + return 0; +} + +int +nouveau_mm_fini(struct nouveau_mm **prmm) +{ + struct nouveau_mm *rmm = *prmm; + struct nouveau_mm_node *heap = + list_first_entry(&rmm->nodes, struct nouveau_mm_node, nl_entry); + + if (!list_is_singular(&rmm->nodes)) + return -EBUSY; + + kfree(heap); + kfree(rmm); + *prmm = NULL; + return 0; +} diff --git a/drivers/gpu/drm/nouveau/nouveau_mm.h b/drivers/gpu/drm/nouveau/nouveau_mm.h new file mode 100644 index 000000000000..7e8f8bd86d47 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nouveau_mm.h @@ -0,0 +1,61 @@ +/* + * Copyright 2010 Red Hat Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: Ben Skeggs + */ + +#ifndef __NOUVEAU_REGION_H__ +#define __NOUVEAU_REGION_H__ + +struct nouveau_mm_node { + struct list_head nl_entry; + struct list_head fl_entry; + struct list_head rl_entry; + + bool free; + int type; + + u32 offset; + u32 length; +}; + +struct nouveau_mm { + struct list_head nodes; + struct list_head free; + + struct mutex mutex; + + u32 block_size; +}; + +int nouveau_mm_init(struct nouveau_mm **, u32 offset, u32 length, u32 block); +int nouveau_mm_fini(struct nouveau_mm **); +int nouveau_mm_pre(struct nouveau_mm *); +int nouveau_mm_get(struct nouveau_mm *, int type, u32 size, u32 size_nc, + u32 align, struct nouveau_mm_node **); +void nouveau_mm_put(struct nouveau_mm *, struct nouveau_mm_node *); + +int nv50_vram_init(struct drm_device *); +int nv50_vram_new(struct drm_device *, u64 size, u32 align, u32 size_nc, + u32 memtype, struct nouveau_vram **); +void nv50_vram_del(struct drm_device *, struct nouveau_vram **); + +#endif diff --git a/drivers/gpu/drm/nouveau/nv50_instmem.c b/drivers/gpu/drm/nouveau/nv50_instmem.c index 87160952a30b..1e7d50397e4a 100644 --- a/drivers/gpu/drm/nouveau/nv50_instmem.c +++ b/drivers/gpu/drm/nouveau/nv50_instmem.c @@ -325,6 +325,7 @@ nv50_instmem_get(struct nouveau_gpuobj *gpuobj, u32 size, u32 align) 0, 0x0000, true, false, &node->vram); if (ret) { NV_ERROR(dev, "error getting PRAMIN backing pages: %d\n", ret); + WARN_ON(1); return ret; } diff --git a/drivers/gpu/drm/nouveau/nv50_vram.c b/drivers/gpu/drm/nouveau/nv50_vram.c new file mode 100644 index 000000000000..6e753356cd94 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nv50_vram.c @@ -0,0 +1,180 @@ +/* + * Copyright 2010 Red Hat Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: Ben Skeggs + */ + +#include "drmP.h" +#include "nouveau_drv.h" +#include "nouveau_mm.h" + +static int types[0x80] = { + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 0, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 0, 2, 2, 2, 2, 2, 2, 2, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 0, 0, + 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 2, 2, 2, 2, + 1, 0, 2, 0, 1, 0, 2, 0, 1, 1, 2, 2, 1, 1, 0, 0 +}; + +void +nv50_vram_del(struct drm_device *dev, struct nouveau_vram **pvram) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct ttm_bo_device *bdev = &dev_priv->ttm.bdev; + struct ttm_mem_type_manager *man = &bdev->man[TTM_PL_VRAM]; + struct nouveau_mm *mm = man->priv; + struct nouveau_mm_node *this; + struct nouveau_vram *vram; + + vram = *pvram; + *pvram = NULL; + if (unlikely(vram == NULL)) + return; + + mutex_lock(&mm->mutex); + while (!list_empty(&vram->regions)) { + this = list_first_entry(&vram->regions, struct nouveau_mm_node, rl_entry); + + list_del(&this->rl_entry); + nouveau_mm_put(mm, this); + } + mutex_unlock(&mm->mutex); + + kfree(vram); +} + +int +nv50_vram_new(struct drm_device *dev, u64 size, u32 align, u32 size_nc, + u32 type, struct nouveau_vram **pvram) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct ttm_bo_device *bdev = &dev_priv->ttm.bdev; + struct ttm_mem_type_manager *man = &bdev->man[TTM_PL_VRAM]; + struct nouveau_mm *mm = man->priv; + struct nouveau_mm_node *r; + struct nouveau_vram *vram; + int ret; + + if (!types[type]) + return -EINVAL; + size >>= 12; + align >>= 12; + size_nc >>= 12; + + vram = kzalloc(sizeof(*vram), GFP_KERNEL); + if (!vram) + return -ENOMEM; + + INIT_LIST_HEAD(&vram->regions); + vram->dev = dev_priv->dev; + vram->memtype = type; + vram->size = size; + + mutex_lock(&mm->mutex); + do { + ret = nouveau_mm_get(mm, types[type], size, size_nc, align, &r); + if (ret) { + mutex_unlock(&mm->mutex); + nv50_vram_del(dev, &vram); + return ret; + } + + list_add_tail(&r->rl_entry, &vram->regions); + size -= r->length; + } while (size); + mutex_unlock(&mm->mutex); + + r = list_first_entry(&vram->regions, struct nouveau_mm_node, rl_entry); + vram->offset = (u64)r->offset << 12; + *pvram = vram; + return 0; +} + +static u32 +nv50_vram_rblock(struct drm_device *dev) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + int i, parts, colbits, rowbitsa, rowbitsb, banks; + u64 rowsize, predicted; + u32 r0, r4, rt, ru, rblock_size; + + r0 = nv_rd32(dev, 0x100200); + r4 = nv_rd32(dev, 0x100204); + rt = nv_rd32(dev, 0x100250); + ru = nv_rd32(dev, 0x001540); + NV_DEBUG(dev, "memcfg 0x%08x 0x%08x 0x%08x 0x%08x\n", r0, r4, rt, ru); + + for (i = 0, parts = 0; i < 8; i++) { + if (ru & (0x00010000 << i)) + parts++; + } + + colbits = (r4 & 0x0000f000) >> 12; + rowbitsa = ((r4 & 0x000f0000) >> 16) + 8; + rowbitsb = ((r4 & 0x00f00000) >> 20) + 8; + banks = ((r4 & 0x01000000) ? 8 : 4); + + rowsize = parts * banks * (1 << colbits) * 8; + predicted = rowsize << rowbitsa; + if (r0 & 0x00000004) + predicted += rowsize << rowbitsb; + + if (predicted != dev_priv->vram_size) { + NV_WARN(dev, "memory controller reports %dMiB VRAM\n", + (u32)(dev_priv->vram_size >> 20)); + NV_WARN(dev, "we calculated %dMiB VRAM\n", + (u32)(predicted >> 20)); + } + + rblock_size = rowsize; + if (rt & 1) + rblock_size *= 3; + + NV_DEBUG(dev, "rblock %d bytes\n", rblock_size); + return rblock_size; +} + +int +nv50_vram_init(struct drm_device *dev) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + + dev_priv->vram_size = nv_rd32(dev, 0x10020c); + dev_priv->vram_size |= (dev_priv->vram_size & 0xff) << 32; + dev_priv->vram_size &= 0xffffffff00ULL; + + switch (dev_priv->chipset) { + case 0xaa: + case 0xac: + case 0xaf: + dev_priv->vram_sys_base = (u64)nv_rd32(dev, 0x100e10) << 12; + dev_priv->vram_rblock_size = 4096; + break; + default: + dev_priv->vram_rblock_size = nv50_vram_rblock(dev); + break; + } + + return 0; +} -- cgit v1.2.3 From a11c3198c9ba38d81e25b65e3908d531feba1372 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 27 Aug 2010 10:00:25 +1000 Subject: drm/nv50: import new vm code Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/Makefile | 5 +- drivers/gpu/drm/nouveau/nouveau_drv.h | 9 +- drivers/gpu/drm/nouveau/nouveau_mem.c | 5 +- drivers/gpu/drm/nouveau/nouveau_object.c | 2 +- drivers/gpu/drm/nouveau/nouveau_vm.c | 421 +++++++++++++++++++++++++++++++ drivers/gpu/drm/nouveau/nouveau_vm.h | 107 ++++++++ drivers/gpu/drm/nouveau/nv50_fifo.c | 3 +- drivers/gpu/drm/nouveau/nv50_graph.c | 5 +- drivers/gpu/drm/nouveau/nv50_instmem.c | 12 +- drivers/gpu/drm/nouveau/nv50_vm.c | 164 ++++++++++++ drivers/gpu/drm/nouveau/nv84_crypt.c | 3 +- 11 files changed, 714 insertions(+), 22 deletions(-) create mode 100644 drivers/gpu/drm/nouveau/nouveau_vm.c create mode 100644 drivers/gpu/drm/nouveau/nouveau_vm.h create mode 100644 drivers/gpu/drm/nouveau/nv50_vm.c diff --git a/drivers/gpu/drm/nouveau/Makefile b/drivers/gpu/drm/nouveau/Makefile index 26fdd12561b6..b1d8941e04d8 100644 --- a/drivers/gpu/drm/nouveau/Makefile +++ b/drivers/gpu/drm/nouveau/Makefile @@ -9,8 +9,9 @@ nouveau-y := nouveau_drv.o nouveau_state.o nouveau_channel.o nouveau_mem.o \ nouveau_bo.o nouveau_fence.o nouveau_gem.o nouveau_ttm.o \ nouveau_hw.o nouveau_calc.o nouveau_bios.o nouveau_i2c.o \ nouveau_display.o nouveau_connector.o nouveau_fbcon.o \ - nouveau_dp.o nouveau_ramht.o nouveau_mm.o \ + nouveau_dp.o nouveau_ramht.o \ nouveau_pm.o nouveau_volt.o nouveau_perf.o nouveau_temp.o \ + nouveau_mm.o nouveau_vm.o \ nv04_timer.o \ nv04_mc.o nv40_mc.o nv50_mc.o \ nv04_fb.o nv10_fb.o nv30_fb.o nv40_fb.o nv50_fb.o nvc0_fb.o \ @@ -27,7 +28,7 @@ nouveau-y := nouveau_drv.o nouveau_state.o nouveau_channel.o nouveau_mem.o \ nv10_gpio.o nv50_gpio.o \ nv50_calc.o \ nv04_pm.o nv50_pm.o nva3_pm.o \ - nv50_vram.o + nv50_vram.o nv50_vm.o nouveau-$(CONFIG_DRM_NOUVEAU_DEBUG) += nouveau_debugfs.o nouveau-$(CONFIG_COMPAT) += nouveau_ioc32.o diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index 1305e2c94201..ce1dde4a65d6 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -153,6 +153,7 @@ enum nouveau_flags { #define NVOBJ_ENGINE_DISPLAY 0xcafe0001 #define NVOBJ_ENGINE_INT 0xdeadbeef +#define NVOBJ_FLAG_DONT_MAP (1 << 0) #define NVOBJ_FLAG_ZERO_ALLOC (1 << 1) #define NVOBJ_FLAG_ZERO_FREE (1 << 2) @@ -1213,7 +1214,6 @@ extern int nv50_instmem_map(struct nouveau_gpuobj *); extern void nv50_instmem_unmap(struct nouveau_gpuobj *); extern void nv50_instmem_flush(struct drm_device *); extern void nv84_instmem_flush(struct drm_device *); -extern void nv50_vm_flush(struct drm_device *, int engine); /* nvc0_instmem.c */ extern int nvc0_instmem_init(struct drm_device *); @@ -1564,10 +1564,11 @@ nv_match_device(struct drm_device *dev, unsigned device, } /* memory type/access flags, do not match hardware values */ -#define NV_MEM_ACCESS_RO 1 -#define NV_MEM_ACCESS_WO 2 +#define NV_MEM_ACCESS_RO 1 +#define NV_MEM_ACCESS_WO 2 #define NV_MEM_ACCESS_RW (NV_MEM_ACCESS_RO | NV_MEM_ACCESS_WO) -#define NV_MEM_ACCESS_VM 4 +#define NV_MEM_ACCESS_SYS 4 +#define NV_MEM_ACCESS_VM 8 #define NV_MEM_TARGET_VRAM 0 #define NV_MEM_TARGET_PCI 1 diff --git a/drivers/gpu/drm/nouveau/nouveau_mem.c b/drivers/gpu/drm/nouveau/nouveau_mem.c index dbeb9e5f6b22..2d02401e8227 100644 --- a/drivers/gpu/drm/nouveau/nouveau_mem.c +++ b/drivers/gpu/drm/nouveau/nouveau_mem.c @@ -37,6 +37,7 @@ #include "nouveau_drv.h" #include "nouveau_pm.h" #include "nouveau_mm.h" +#include "nouveau_vm.h" /* * NV10-NV40 tiling helpers @@ -201,7 +202,7 @@ nv50_mem_vm_bind_linear(struct drm_device *dev, uint64_t virt, uint32_t size, dev_priv->engine.instmem.flush(dev); dev_priv->engine.fifo.tlb_flush(dev); dev_priv->engine.graph.tlb_flush(dev); - nv50_vm_flush(dev, 6); + nv50_vm_flush_engine(dev, 6); return 0; } @@ -234,7 +235,7 @@ nv50_mem_vm_unbind(struct drm_device *dev, uint64_t virt, uint32_t size) dev_priv->engine.instmem.flush(dev); dev_priv->engine.fifo.tlb_flush(dev); dev_priv->engine.graph.tlb_flush(dev); - nv50_vm_flush(dev, 6); + nv50_vm_flush_engine(dev, 6); } /* diff --git a/drivers/gpu/drm/nouveau/nouveau_object.c b/drivers/gpu/drm/nouveau/nouveau_object.c index 5cc3f7e59fa1..dd1859f7d8b0 100644 --- a/drivers/gpu/drm/nouveau/nouveau_object.c +++ b/drivers/gpu/drm/nouveau/nouveau_object.c @@ -213,7 +213,7 @@ nouveau_gpuobj_new(struct drm_device *dev, struct nouveau_channel *chan, } ret = -ENOSYS; - if (dev_priv->ramin_available) + if (!(flags & NVOBJ_FLAG_DONT_MAP)) ret = instmem->map(gpuobj); if (ret) gpuobj->pinst = ~0; diff --git a/drivers/gpu/drm/nouveau/nouveau_vm.c b/drivers/gpu/drm/nouveau/nouveau_vm.c new file mode 100644 index 000000000000..07ab1749cf7d --- /dev/null +++ b/drivers/gpu/drm/nouveau/nouveau_vm.c @@ -0,0 +1,421 @@ +/* + * Copyright 2010 Red Hat Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: Ben Skeggs + */ + +#include "drmP.h" +#include "nouveau_drv.h" +#include "nouveau_mm.h" +#include "nouveau_vm.h" + +void +nouveau_vm_map_at(struct nouveau_vma *vma, u64 delta, struct nouveau_vram *vram) +{ + struct nouveau_vm *vm = vma->vm; + struct nouveau_mm_node *r; + u32 offset = vma->node->offset + (delta >> 12); + u32 bits = vma->node->type - 12; + u32 pde = (offset >> vm->pgt_bits) - vm->fpde; + u32 pte = (offset & ((1 << vm->pgt_bits) - 1)) >> bits; + u32 max = 1 << (vm->pgt_bits - bits); + u32 end, len; + + list_for_each_entry(r, &vram->regions, rl_entry) { + u64 phys = (u64)r->offset << 12; + u32 num = r->length >> bits; + + while (num) { + struct nouveau_gpuobj *pgt = vm->pgt[pde].obj; + + end = (pte + num); + if (unlikely(end >= max)) + end = max; + len = end - pte; + + vm->map(vma, pgt, vram, pte, len, phys); + + num -= len; + pte += len; + if (unlikely(end >= max)) { + pde++; + pte = 0; + } + } + } + + vm->flush(vm); +} + +void +nouveau_vm_map(struct nouveau_vma *vma, struct nouveau_vram *vram) +{ + nouveau_vm_map_at(vma, 0, vram); +} + +void +nouveau_vm_map_sg(struct nouveau_vma *vma, u64 delta, u64 length, + dma_addr_t *list) +{ + struct nouveau_vm *vm = vma->vm; + u32 offset = vma->node->offset + (delta >> 12); + u32 bits = vma->node->type - 12; + u32 num = length >> vma->node->type; + u32 pde = (offset >> vm->pgt_bits) - vm->fpde; + u32 pte = (offset & ((1 << vm->pgt_bits) - 1)) >> bits; + u32 max = 1 << (vm->pgt_bits - bits); + u32 end, len; + + while (num) { + struct nouveau_gpuobj *pgt = vm->pgt[pde].obj; + + end = (pte + num); + if (unlikely(end >= max)) + end = max; + len = end - pte; + + vm->map_sg(vma, pgt, pte, list, len); + + num -= len; + pte += len; + list += len; + if (unlikely(end >= max)) { + pde++; + pte = 0; + } + } + + vm->flush(vm); +} + +void +nouveau_vm_unmap_at(struct nouveau_vma *vma, u64 delta, u64 length) +{ + struct nouveau_vm *vm = vma->vm; + u32 offset = vma->node->offset + (delta >> 12); + u32 bits = vma->node->type - 12; + u32 num = length >> vma->node->type; + u32 pde = (offset >> vm->pgt_bits) - vm->fpde; + u32 pte = (offset & ((1 << vm->pgt_bits) - 1)) >> bits; + u32 max = 1 << (vm->pgt_bits - bits); + u32 end, len; + + while (num) { + struct nouveau_gpuobj *pgt = vm->pgt[pde].obj; + + end = (pte + num); + if (unlikely(end >= max)) + end = max; + len = end - pte; + + vm->unmap(pgt, pte, len); + + num -= len; + pte += len; + if (unlikely(end >= max)) { + pde++; + pte = 0; + } + } + + vm->flush(vm); +} + +void +nouveau_vm_unmap(struct nouveau_vma *vma) +{ + nouveau_vm_unmap_at(vma, 0, (u64)vma->node->length << 12); +} + +static void +nouveau_vm_unmap_pgt(struct nouveau_vm *vm, u32 fpde, u32 lpde) +{ + struct nouveau_vm_pgd *vpgd; + struct nouveau_vm_pgt *vpgt; + struct nouveau_gpuobj *pgt; + u32 pde; + + for (pde = fpde; pde <= lpde; pde++) { + vpgt = &vm->pgt[pde - vm->fpde]; + if (--vpgt->refcount) + continue; + + list_for_each_entry(vpgd, &vm->pgd_list, head) { + vm->unmap_pgt(vpgd->obj, pde); + } + + pgt = vpgt->obj; + vpgt->obj = NULL; + + mutex_unlock(&vm->mm->mutex); + nouveau_gpuobj_ref(NULL, &pgt); + mutex_lock(&vm->mm->mutex); + } +} + +static int +nouveau_vm_map_pgt(struct nouveau_vm *vm, u32 pde, u32 type) +{ + struct nouveau_vm_pgt *vpgt = &vm->pgt[pde - vm->fpde]; + struct nouveau_vm_pgd *vpgd; + struct nouveau_gpuobj *pgt; + u32 pgt_size; + int ret; + + pgt_size = (1 << (vm->pgt_bits + 12)) >> type; + pgt_size *= 8; + + mutex_unlock(&vm->mm->mutex); + ret = nouveau_gpuobj_new(vm->dev, NULL, pgt_size, 0x1000, + NVOBJ_FLAG_ZERO_ALLOC, &pgt); + mutex_lock(&vm->mm->mutex); + if (unlikely(ret)) + return ret; + + /* someone beat us to filling the PDE while we didn't have the lock */ + if (unlikely(vpgt->refcount++)) { + mutex_unlock(&vm->mm->mutex); + nouveau_gpuobj_ref(NULL, &pgt); + mutex_lock(&vm->mm->mutex); + return 0; + } + + list_for_each_entry(vpgd, &vm->pgd_list, head) { + vm->map_pgt(vpgd->obj, type, pde, pgt); + } + + vpgt->page_shift = type; + vpgt->obj = pgt; + return 0; +} + +int +nouveau_vm_get(struct nouveau_vm *vm, u64 size, u32 page_shift, + u32 access, struct nouveau_vma *vma) +{ + u32 align = (1 << page_shift) >> 12; + u32 msize = size >> 12; + u32 fpde, lpde, pde; + int ret; + + mutex_lock(&vm->mm->mutex); + ret = nouveau_mm_get(vm->mm, page_shift, msize, 0, align, &vma->node); + if (unlikely(ret != 0)) { + mutex_unlock(&vm->mm->mutex); + return ret; + } + + fpde = (vma->node->offset >> vm->pgt_bits); + lpde = (vma->node->offset + vma->node->length - 1) >> vm->pgt_bits; + for (pde = fpde; pde <= lpde; pde++) { + struct nouveau_vm_pgt *vpgt = &vm->pgt[pde - vm->fpde]; + + if (likely(vpgt->refcount)) { + vpgt->refcount++; + continue; + } + + ret = nouveau_vm_map_pgt(vm, pde, vma->node->type); + if (ret) { + if (pde != fpde) + nouveau_vm_unmap_pgt(vm, fpde, pde - 1); + nouveau_mm_put(vm->mm, vma->node); + mutex_unlock(&vm->mm->mutex); + vma->node = NULL; + return ret; + } + } + mutex_unlock(&vm->mm->mutex); + + vma->vm = vm; + vma->offset = (u64)vma->node->offset << 12; + vma->access = access; + return 0; +} + +void +nouveau_vm_put(struct nouveau_vma *vma) +{ + struct nouveau_vm *vm = vma->vm; + u32 fpde, lpde; + + if (unlikely(vma->node == NULL)) + return; + fpde = (vma->node->offset >> vm->pgt_bits); + lpde = (vma->node->offset + vma->node->length - 1) >> vm->pgt_bits; + + mutex_lock(&vm->mm->mutex); + nouveau_mm_put(vm->mm, vma->node); + vma->node = NULL; + nouveau_vm_unmap_pgt(vm, fpde, lpde); + mutex_unlock(&vm->mm->mutex); +} + +int +nouveau_vm_new(struct drm_device *dev, u64 offset, u64 length, u64 mm_offset, + u8 pgt_bits, u8 spg_shift, u8 lpg_shift, + struct nouveau_vm **pvm) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_vm *vm; + u64 mm_length = (offset + length) - mm_offset; + u32 block; + int ret; + + vm = kzalloc(sizeof(*vm), GFP_KERNEL); + if (!vm) + return -ENOMEM; + + if (dev_priv->card_type == NV_50) { + vm->map_pgt = nv50_vm_map_pgt; + vm->unmap_pgt = nv50_vm_unmap_pgt; + vm->map = nv50_vm_map; + vm->map_sg = nv50_vm_map_sg; + vm->unmap = nv50_vm_unmap; + vm->flush = nv50_vm_flush; + } else { + kfree(vm); + return -ENOSYS; + } + + vm->fpde = offset >> pgt_bits; + vm->lpde = (offset + length - 1) >> pgt_bits; + vm->pgt = kcalloc(vm->lpde - vm->fpde + 1, sizeof(*vm->pgt), GFP_KERNEL); + if (!vm->pgt) { + kfree(vm); + return -ENOMEM; + } + + INIT_LIST_HEAD(&vm->pgd_list); + vm->dev = dev; + vm->refcount = 1; + vm->pgt_bits = pgt_bits - 12; + vm->spg_shift = spg_shift; + vm->lpg_shift = lpg_shift; + + block = (1 << pgt_bits); + if (length < block) + block = length; + + ret = nouveau_mm_init(&vm->mm, mm_offset >> 12, mm_length >> 12, + block >> 12); + if (ret) { + kfree(vm); + return ret; + } + + *pvm = vm; + return 0; +} + +static int +nouveau_vm_link(struct nouveau_vm *vm, struct nouveau_gpuobj *pgd) +{ + struct nouveau_vm_pgd *vpgd; + int i; + + if (!pgd) + return 0; + + vpgd = kzalloc(sizeof(*vpgd), GFP_KERNEL); + if (!vpgd) + return -ENOMEM; + + nouveau_gpuobj_ref(pgd, &vpgd->obj); + + mutex_lock(&vm->mm->mutex); + for (i = vm->fpde; i <= vm->lpde; i++) { + struct nouveau_vm_pgt *vpgt = &vm->pgt[i - vm->fpde]; + + if (!vpgt->obj) { + vm->unmap_pgt(pgd, i); + continue; + } + + vm->map_pgt(pgd, vpgt->page_shift, i, vpgt->obj); + } + list_add(&vpgd->head, &vm->pgd_list); + mutex_unlock(&vm->mm->mutex); + return 0; +} + +static void +nouveau_vm_unlink(struct nouveau_vm *vm, struct nouveau_gpuobj *pgd) +{ + struct nouveau_vm_pgd *vpgd, *tmp; + + if (!pgd) + return; + + mutex_lock(&vm->mm->mutex); + list_for_each_entry_safe(vpgd, tmp, &vm->pgd_list, head) { + if (vpgd->obj != pgd) + continue; + + list_del(&vpgd->head); + nouveau_gpuobj_ref(NULL, &vpgd->obj); + kfree(vpgd); + } + mutex_unlock(&vm->mm->mutex); +} + +static void +nouveau_vm_del(struct nouveau_vm *vm) +{ + struct nouveau_vm_pgd *vpgd, *tmp; + + list_for_each_entry_safe(vpgd, tmp, &vm->pgd_list, head) { + nouveau_vm_unlink(vm, vpgd->obj); + } + WARN_ON(nouveau_mm_fini(&vm->mm) != 0); + + kfree(vm->pgt); + kfree(vm); +} + +int +nouveau_vm_ref(struct nouveau_vm *ref, struct nouveau_vm **ptr, + struct nouveau_gpuobj *pgd) +{ + struct nouveau_vm *vm; + int ret; + + vm = ref; + if (vm) { + ret = nouveau_vm_link(vm, pgd); + if (ret) + return ret; + + vm->refcount++; + } + + vm = *ptr; + *ptr = ref; + + if (vm) { + nouveau_vm_unlink(vm, pgd); + + if (--vm->refcount == 0) + nouveau_vm_del(vm); + } + + return 0; +} diff --git a/drivers/gpu/drm/nouveau/nouveau_vm.h b/drivers/gpu/drm/nouveau/nouveau_vm.h new file mode 100644 index 000000000000..b6755cfa7b71 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nouveau_vm.h @@ -0,0 +1,107 @@ +/* + * Copyright 2010 Red Hat Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: Ben Skeggs + */ + +#ifndef __NOUVEAU_VM_H__ +#define __NOUVEAU_VM_H__ + +#include "drmP.h" + +#include "nouveau_drv.h" +#include "nouveau_mm.h" + +struct nouveau_vm_pgt { + struct nouveau_gpuobj *obj; + u32 page_shift; + u32 refcount; +}; + +struct nouveau_vm_pgd { + struct list_head head; + struct nouveau_gpuobj *obj; +}; + +struct nouveau_vma { + struct nouveau_vm *vm; + struct nouveau_mm_node *node; + u64 offset; + u32 access; +}; + +struct nouveau_vm { + struct drm_device *dev; + struct nouveau_mm *mm; + int refcount; + + struct list_head pgd_list; + atomic_t pgraph_refs; + atomic_t pcrypt_refs; + + struct nouveau_vm_pgt *pgt; + u32 fpde; + u32 lpde; + + u32 pgt_bits; + u8 spg_shift; + u8 lpg_shift; + + void (*map_pgt)(struct nouveau_gpuobj *pgd, u32 type, u32 pde, + struct nouveau_gpuobj *pgt); + void (*unmap_pgt)(struct nouveau_gpuobj *pgd, u32 pde); + void (*map)(struct nouveau_vma *, struct nouveau_gpuobj *, + struct nouveau_vram *, u32 pte, u32 cnt, u64 phys); + void (*map_sg)(struct nouveau_vma *, struct nouveau_gpuobj *, + u32 pte, dma_addr_t *, u32 cnt); + void (*unmap)(struct nouveau_gpuobj *pgt, u32 pte, u32 cnt); + void (*flush)(struct nouveau_vm *); +}; + +/* nouveau_vm.c */ +int nouveau_vm_new(struct drm_device *, u64 offset, u64 length, u64 mm_offset, + u8 pgt_bits, u8 spg_shift, u8 lpg_shift, + struct nouveau_vm **); +int nouveau_vm_ref(struct nouveau_vm *, struct nouveau_vm **, + struct nouveau_gpuobj *pgd); +int nouveau_vm_get(struct nouveau_vm *, u64 size, u32 page_shift, + u32 access, struct nouveau_vma *); +void nouveau_vm_put(struct nouveau_vma *); +void nouveau_vm_map(struct nouveau_vma *, struct nouveau_vram *); +void nouveau_vm_map_at(struct nouveau_vma *, u64 offset, struct nouveau_vram *); +void nouveau_vm_unmap(struct nouveau_vma *); +void nouveau_vm_unmap_at(struct nouveau_vma *, u64 offset, u64 length); +void nouveau_vm_map_sg(struct nouveau_vma *, u64 offset, u64 length, + dma_addr_t *); + +/* nv50_vm.c */ +void nv50_vm_map_pgt(struct nouveau_gpuobj *pgd, u32 type, u32 pde, + struct nouveau_gpuobj *pgt); +void nv50_vm_unmap_pgt(struct nouveau_gpuobj *pgd, u32 pde); +void nv50_vm_map(struct nouveau_vma *, struct nouveau_gpuobj *, + struct nouveau_vram *, u32 pte, u32 cnt, u64 phys); +void nv50_vm_map_sg(struct nouveau_vma *, struct nouveau_gpuobj *, + u32 pte, dma_addr_t *, u32 cnt); +void nv50_vm_unmap(struct nouveau_gpuobj *, u32 pte, u32 cnt); +void nv50_vm_flush(struct nouveau_vm *); +void nv50_vm_flush_engine(struct drm_device *, int engine); + +#endif diff --git a/drivers/gpu/drm/nouveau/nv50_fifo.c b/drivers/gpu/drm/nouveau/nv50_fifo.c index 7add3dfde3df..8dd04c5dac67 100644 --- a/drivers/gpu/drm/nouveau/nv50_fifo.c +++ b/drivers/gpu/drm/nouveau/nv50_fifo.c @@ -28,6 +28,7 @@ #include "drm.h" #include "nouveau_drv.h" #include "nouveau_ramht.h" +#include "nouveau_vm.h" static void nv50_fifo_playlist_update(struct drm_device *dev) @@ -498,5 +499,5 @@ nv50_fifo_unload_context(struct drm_device *dev) void nv50_fifo_tlb_flush(struct drm_device *dev) { - nv50_vm_flush(dev, 5); + nv50_vm_flush_engine(dev, 5); } diff --git a/drivers/gpu/drm/nouveau/nv50_graph.c b/drivers/gpu/drm/nouveau/nv50_graph.c index b3900788c66d..f5fd1b296d27 100644 --- a/drivers/gpu/drm/nouveau/nv50_graph.c +++ b/drivers/gpu/drm/nouveau/nv50_graph.c @@ -30,6 +30,7 @@ #include "nouveau_ramht.h" #include "nouveau_grctx.h" #include "nouveau_dma.h" +#include "nouveau_vm.h" #include "nv50_evo.h" static int nv50_graph_register(struct drm_device *); @@ -468,7 +469,7 @@ nv50_graph_register(struct drm_device *dev) void nv50_graph_tlb_flush(struct drm_device *dev) { - nv50_vm_flush(dev, 0); + nv50_vm_flush_engine(dev, 0); } void @@ -511,7 +512,7 @@ nv86_graph_tlb_flush(struct drm_device *dev) nv_rd32(dev, 0x400384), nv_rd32(dev, 0x400388)); } - nv50_vm_flush(dev, 0); + nv50_vm_flush_engine(dev, 0); nv_mask(dev, 0x400500, 0x00000001, 0x00000001); spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags); diff --git a/drivers/gpu/drm/nouveau/nv50_instmem.c b/drivers/gpu/drm/nouveau/nv50_instmem.c index 1e7d50397e4a..4eb2f0835e27 100644 --- a/drivers/gpu/drm/nouveau/nv50_instmem.c +++ b/drivers/gpu/drm/nouveau/nv50_instmem.c @@ -27,7 +27,9 @@ #include "drmP.h" #include "drm.h" + #include "nouveau_drv.h" +#include "nouveau_vm.h" struct nv50_instmem_priv { uint32_t save1700[5]; /* 0x1700->0x1710 */ @@ -404,7 +406,7 @@ nv50_instmem_map(struct nouveau_gpuobj *gpuobj) } dev_priv->engine.instmem.flush(dev); - nv50_vm_flush(dev, 6); + nv50_vm_flush_engine(dev, 6); node->ramin = ramin; gpuobj->pinst = ramin->start; @@ -454,11 +456,3 @@ nv84_instmem_flush(struct drm_device *dev) NV_ERROR(dev, "PRAMIN flush timeout\n"); } -void -nv50_vm_flush(struct drm_device *dev, int engine) -{ - nv_wr32(dev, 0x100c80, (engine << 16) | 1); - if (!nv_wait(dev, 0x100c80, 0x00000001, 0x00000000)) - NV_ERROR(dev, "vm flush timeout: engine %d\n", engine); -} - diff --git a/drivers/gpu/drm/nouveau/nv50_vm.c b/drivers/gpu/drm/nouveau/nv50_vm.c new file mode 100644 index 000000000000..ab6c3d0ce32e --- /dev/null +++ b/drivers/gpu/drm/nouveau/nv50_vm.c @@ -0,0 +1,164 @@ +/* + * Copyright 2010 Red Hat Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: Ben Skeggs + */ + +#include "drmP.h" + +#include "nouveau_drv.h" +#include "nouveau_vm.h" + +void +nv50_vm_map_pgt(struct nouveau_gpuobj *pgd, u32 type, u32 pde, + struct nouveau_gpuobj *pgt) +{ + struct drm_nouveau_private *dev_priv = pgd->dev->dev_private; + u32 coverage = (pgt->size >> 3) << type; + u64 phys; + + phys = pgt->vinst; + phys |= 0x01; /* present */ + phys |= (type == 12) ? 0x02 : 0x00; /* 4KiB pages */ + if (dev_priv->vram_sys_base) { + phys += dev_priv->vram_sys_base; + phys |= 0x30; + } + + if (coverage <= 32 * 1024 * 1024) + phys |= 0x60; + else if (coverage <= 64 * 1024 * 1024) + phys |= 0x40; + else if (coverage < 128 * 1024 * 1024) + phys |= 0x20; + + nv_wo32(pgd, (pde * 8) + 0, lower_32_bits(phys)); + nv_wo32(pgd, (pde * 8) + 4, upper_32_bits(phys)); +} + +void +nv50_vm_unmap_pgt(struct nouveau_gpuobj *pgd, u32 pde) +{ + nv_wo32(pgd, (pde * 8) + 0, 0x00000000); + nv_wo32(pgd, (pde * 8) + 4, 0xdeadcafe); +} + +static inline u64 +nv50_vm_addr(struct nouveau_vma *vma, struct nouveau_gpuobj *pgt, + u64 phys, u32 memtype, u32 target) +{ + struct drm_nouveau_private *dev_priv = pgt->dev->dev_private; + + phys |= 1; /* present */ + phys |= (u64)memtype << 40; + + /* IGPs don't have real VRAM, re-target to stolen system memory */ + if (target == 0 && dev_priv->vram_sys_base) { + phys += dev_priv->vram_sys_base; + target = 3; + } + + phys |= target << 4; + + if (vma->access & NV_MEM_ACCESS_SYS) + phys |= (1 << 6); + + if (!(vma->access & NV_MEM_ACCESS_WO)) + phys |= (1 << 3); + + return phys; +} + +void +nv50_vm_map(struct nouveau_vma *vma, struct nouveau_gpuobj *pgt, + struct nouveau_vram *mem, u32 pte, u32 cnt, u64 phys) +{ + u32 block, i; + + phys = nv50_vm_addr(vma, pgt, phys, mem->memtype, 0); + pte <<= 3; + cnt <<= 3; + + while (cnt) { + u32 offset_h = upper_32_bits(phys); + u32 offset_l = lower_32_bits(phys); + + for (i = 7; i >= 0; i--) { + block = 1 << (i + 3); + if (cnt >= block && !(pte & (block - 1))) + break; + } + offset_l |= (i << 7); + + phys += block << (vma->node->type - 3); + cnt -= block; + + while (block) { + nv_wo32(pgt, pte + 0, offset_l); + nv_wo32(pgt, pte + 4, offset_h); + pte += 8; + block -= 8; + } + } +} + +void +nv50_vm_map_sg(struct nouveau_vma *vma, struct nouveau_gpuobj *pgt, + u32 pte, dma_addr_t *list, u32 cnt) +{ + pte <<= 3; + while (cnt--) { + u64 phys = nv50_vm_addr(vma, pgt, (u64)*list++, 0, 2); + nv_wo32(pgt, pte + 0, lower_32_bits(phys)); + nv_wo32(pgt, pte + 4, upper_32_bits(phys)); + pte += 8; + } +} + +void +nv50_vm_unmap(struct nouveau_gpuobj *pgt, u32 pte, u32 cnt) +{ + pte <<= 3; + while (cnt--) { + nv_wo32(pgt, pte + 0, 0x00000000); + nv_wo32(pgt, pte + 4, 0x00000000); + pte += 8; + } +} + +void +nv50_vm_flush(struct nouveau_vm *vm) +{ + struct drm_nouveau_private *dev_priv = vm->dev->dev_private; + struct nouveau_instmem_engine *pinstmem = &dev_priv->engine.instmem; + + pinstmem->flush(vm->dev); + + nv50_vm_flush_engine(vm->dev, 6); +} + +void +nv50_vm_flush_engine(struct drm_device *dev, int engine) +{ + nv_wr32(dev, 0x100c80, (engine << 16) | 1); + if (!nv_wait(dev, 0x100c80, 0x00000001, 0x00000000)) + NV_ERROR(dev, "vm flush timeout: engine %d\n", engine); +} diff --git a/drivers/gpu/drm/nouveau/nv84_crypt.c b/drivers/gpu/drm/nouveau/nv84_crypt.c index 780bb1d66f95..a333e5905346 100644 --- a/drivers/gpu/drm/nouveau/nv84_crypt.c +++ b/drivers/gpu/drm/nouveau/nv84_crypt.c @@ -25,6 +25,7 @@ #include "drmP.h" #include "nouveau_drv.h" #include "nouveau_util.h" +#include "nouveau_vm.h" static void nv84_crypt_isr(struct drm_device *); @@ -84,7 +85,7 @@ nv84_crypt_destroy_context(struct nouveau_channel *chan) void nv84_crypt_tlb_flush(struct drm_device *dev) { - nv50_vm_flush(dev, 0x0a); + nv50_vm_flush_engine(dev, 0x0a); } int -- cgit v1.2.3 From f869ef882382a4b6cb42d259e399aeec3781d4bb Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 15 Nov 2010 11:53:16 +1000 Subject: drm/nv50: implement BAR1/BAR3 management on top of new VM code Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_bo.c | 46 +++++- drivers/gpu/drm/nouveau/nouveau_drv.h | 10 ++ drivers/gpu/drm/nouveau/nv50_instmem.c | 258 ++++++++++++++------------------- drivers/gpu/drm/nouveau/nv50_vm.c | 1 - 4 files changed, 162 insertions(+), 153 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index 5a71ca4346c8..4d142031d542 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c @@ -32,6 +32,8 @@ #include "nouveau_drm.h" #include "nouveau_drv.h" #include "nouveau_dma.h" +#include "nouveau_mm.h" +#include "nouveau_vm.h" #include #include @@ -386,10 +388,13 @@ nouveau_bo_init_mem_type(struct ttm_bo_device *bdev, uint32_t type, man->default_caching = TTM_PL_FLAG_CACHED; break; case TTM_PL_VRAM: - if (dev_priv->card_type == NV_50) + if (dev_priv->card_type == NV_50) { man->func = &nouveau_vram_manager; - else + man->io_reserve_fastpath = false; + man->use_io_reserve_lru = true; + } else { man->func = &ttm_bo_manager_func; + } man->flags = TTM_MEMTYPE_FLAG_FIXED | TTM_MEMTYPE_FLAG_MAPPABLE; man->available_caching = TTM_PL_FLAG_UNCACHED | @@ -858,6 +863,7 @@ nouveau_ttm_io_mem_reserve(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem) struct ttm_mem_type_manager *man = &bdev->man[mem->mem_type]; struct drm_nouveau_private *dev_priv = nouveau_bdev(bdev); struct drm_device *dev = dev_priv->dev; + int ret; mem->bus.addr = NULL; mem->bus.offset = 0; @@ -880,9 +886,32 @@ nouveau_ttm_io_mem_reserve(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem) #endif break; case TTM_PL_VRAM: - mem->bus.offset = mem->start << PAGE_SHIFT; + { + struct nouveau_vram *vram = mem->mm_node; + + if (!dev_priv->bar1_vm) { + mem->bus.offset = mem->start << PAGE_SHIFT; + mem->bus.base = pci_resource_start(dev->pdev, 1); + mem->bus.is_iomem = true; + break; + } + + ret = nouveau_vm_get(dev_priv->bar1_vm, mem->bus.size, 12, + NV_MEM_ACCESS_RW, &vram->bar_vma); + if (ret) + return ret; + + nouveau_vm_map(&vram->bar_vma, vram); + if (ret) { + nouveau_vm_put(&vram->bar_vma); + return ret; + } + + mem->bus.offset = vram->bar_vma.offset; + mem->bus.offset -= 0x0020000000ULL; mem->bus.base = pci_resource_start(dev->pdev, 1); mem->bus.is_iomem = true; + } break; default: return -EINVAL; @@ -893,6 +922,17 @@ nouveau_ttm_io_mem_reserve(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem) static void nouveau_ttm_io_mem_free(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem) { + struct drm_nouveau_private *dev_priv = nouveau_bdev(bdev); + struct nouveau_vram *vram = mem->mm_node; + + if (!dev_priv->bar1_vm || mem->mem_type != TTM_PL_VRAM) + return; + + if (!vram->bar_vma.node) + return; + + nouveau_vm_unmap(&vram->bar_vma); + nouveau_vm_put(&vram->bar_vma); } static int diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index ce1dde4a65d6..452a8652a498 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -55,7 +55,10 @@ struct nouveau_fpriv { #include "nouveau_reg.h" #include "nouveau_bios.h" #include "nouveau_util.h" + struct nouveau_grctx; +struct nouveau_vram; +#include "nouveau_vm.h" #define MAX_NUM_DCB_ENTRIES 16 @@ -69,6 +72,8 @@ struct nouveau_grctx; struct nouveau_vram { struct drm_device *dev; + struct nouveau_vma bar_vma; + struct list_head regions; u32 memtype; u64 offset; @@ -244,6 +249,7 @@ struct nouveau_channel { void *pgraph_ctx; /* NV50 VM */ + struct nouveau_vm *vm; struct nouveau_gpuobj *vm_pd; struct nouveau_gpuobj *vm_gart_pt; struct nouveau_gpuobj *vm_vram_pt[NV50_VM_VRAM_NR]; @@ -701,6 +707,10 @@ struct drm_nouveau_private { uint64_t fb_aper_free; int fb_mtrr; + /* BAR control (NV50-) */ + struct nouveau_vm *bar1_vm; + struct nouveau_vm *bar3_vm; + /* G8x/G9x virtual address space */ uint64_t vm_gart_base; uint64_t vm_gart_size; diff --git a/drivers/gpu/drm/nouveau/nv50_instmem.c b/drivers/gpu/drm/nouveau/nv50_instmem.c index 4eb2f0835e27..4ba8f74e77b1 100644 --- a/drivers/gpu/drm/nouveau/nv50_instmem.c +++ b/drivers/gpu/drm/nouveau/nv50_instmem.c @@ -31,12 +31,16 @@ #include "nouveau_drv.h" #include "nouveau_vm.h" +#define BAR1_VM_BASE 0x0020000000ULL +#define BAR1_VM_SIZE pci_resource_len(dev->pdev, 1) +#define BAR3_VM_BASE 0x0000000000ULL +#define BAR3_VM_SIZE pci_resource_len(dev->pdev, 3) + struct nv50_instmem_priv { uint32_t save1700[5]; /* 0x1700->0x1710 */ - struct nouveau_gpuobj *pramin_pt; - struct nouveau_gpuobj *pramin_bar; - struct nouveau_gpuobj *fb_bar; + struct nouveau_gpuobj *bar1_dmaobj; + struct nouveau_gpuobj *bar3_dmaobj; }; static void @@ -50,6 +54,7 @@ nv50_channel_del(struct nouveau_channel **pchan) return; nouveau_gpuobj_ref(NULL, &chan->ramfc); + nouveau_vm_ref(NULL, &chan->vm, chan->vm_pd); nouveau_gpuobj_ref(NULL, &chan->vm_pd); if (chan->ramin_heap.free_stack.next) drm_mm_takedown(&chan->ramin_heap); @@ -58,14 +63,14 @@ nv50_channel_del(struct nouveau_channel **pchan) } static int -nv50_channel_new(struct drm_device *dev, u32 size, +nv50_channel_new(struct drm_device *dev, u32 size, struct nouveau_vm *vm, struct nouveau_channel **pchan) { struct drm_nouveau_private *dev_priv = dev->dev_private; u32 pgd = (dev_priv->chipset == 0x50) ? 0x1400 : 0x0200; u32 fc = (dev_priv->chipset == 0x50) ? 0x0000 : 0x4200; struct nouveau_channel *chan; - int ret; + int ret, i; chan = kzalloc(sizeof(*chan), GFP_KERNEL); if (!chan) @@ -94,6 +99,17 @@ nv50_channel_new(struct drm_device *dev, u32 size, return ret; } + for (i = 0; i < 0x4000; i += 8) { + nv_wo32(chan->vm_pd, i + 0, 0x00000000); + nv_wo32(chan->vm_pd, i + 4, 0xdeadcafe); + } + + ret = nouveau_vm_ref(vm, &chan->vm, chan->vm_pd); + if (ret) { + nv50_channel_del(&chan); + return ret; + } + ret = nouveau_gpuobj_new_fake(dev, chan->ramin->pinst == ~0 ? ~0 : chan->ramin->pinst + fc, chan->ramin->vinst + fc, 0x100, @@ -113,6 +129,7 @@ nv50_instmem_init(struct drm_device *dev) struct drm_nouveau_private *dev_priv = dev->dev_private; struct nv50_instmem_priv *priv; struct nouveau_channel *chan; + struct nouveau_vm *vm; int ret, i; u32 tmp; @@ -129,53 +146,75 @@ nv50_instmem_init(struct drm_device *dev) ret = drm_mm_init(&dev_priv->ramin_heap, 0, dev_priv->ramin_size); if (ret) { NV_ERROR(dev, "Failed to init RAMIN heap\n"); - return -ENOMEM; + goto error; } - /* we need a channel to plug into the hw to control the BARs */ - ret = nv50_channel_new(dev, 128*1024, &dev_priv->channels.ptr[0]); + /* BAR3 */ + ret = nouveau_vm_new(dev, BAR3_VM_BASE, BAR3_VM_SIZE, BAR3_VM_BASE, + 29, 12, 16, &dev_priv->bar3_vm); if (ret) - return ret; - chan = dev_priv->channels.ptr[127] = dev_priv->channels.ptr[0]; + goto error; - /* allocate page table for PRAMIN BAR */ - ret = nouveau_gpuobj_new(dev, chan, (dev_priv->ramin_size >> 12) * 8, - 0x1000, NVOBJ_FLAG_ZERO_ALLOC, - &priv->pramin_pt); + ret = nouveau_gpuobj_new(dev, NULL, (BAR3_VM_SIZE >> 12) * 8, + 0x1000, NVOBJ_FLAG_DONT_MAP | + NVOBJ_FLAG_ZERO_ALLOC, + &dev_priv->bar3_vm->pgt[0].obj); if (ret) - return ret; + goto error; + dev_priv->bar3_vm->pgt[0].page_shift = 12; + dev_priv->bar3_vm->pgt[0].refcount = 1; - nv_wo32(chan->vm_pd, 0x0000, priv->pramin_pt->vinst | 0x63); - nv_wo32(chan->vm_pd, 0x0004, 0); + nv50_instmem_map(dev_priv->bar3_vm->pgt[0].obj); - /* DMA object for PRAMIN BAR */ - ret = nouveau_gpuobj_new(dev, chan, 6*4, 16, 0, &priv->pramin_bar); + ret = nv50_channel_new(dev, 128 * 1024, dev_priv->bar3_vm, &chan); if (ret) - return ret; - nv_wo32(priv->pramin_bar, 0x00, 0x7fc00000); - nv_wo32(priv->pramin_bar, 0x04, dev_priv->ramin_size - 1); - nv_wo32(priv->pramin_bar, 0x08, 0x00000000); - nv_wo32(priv->pramin_bar, 0x0c, 0x00000000); - nv_wo32(priv->pramin_bar, 0x10, 0x00000000); - nv_wo32(priv->pramin_bar, 0x14, 0x00000000); + goto error; + dev_priv->channels.ptr[0] = dev_priv->channels.ptr[127] = chan; - nv50_instmem_map(chan->ramin); + ret = nv50_gpuobj_dma_new(chan, 0x0000, BAR3_VM_BASE, BAR3_VM_SIZE, + NV_MEM_TARGET_VM, NV_MEM_ACCESS_VM, + NV_MEM_TYPE_VM, NV_MEM_COMP_VM, + &priv->bar3_dmaobj); + if (ret) + goto error; - /* poke regs... */ nv_wr32(dev, 0x001704, 0x00000000 | (chan->ramin->vinst >> 12)); nv_wr32(dev, 0x001704, 0x40000000 | (chan->ramin->vinst >> 12)); - nv_wr32(dev, 0x00170c, 0x80000000 | (priv->pramin_bar->cinst >> 4)); + nv_wr32(dev, 0x00170c, 0x80000000 | (priv->bar3_dmaobj->cinst >> 4)); tmp = nv_ri32(dev, 0); nv_wi32(dev, 0, ~tmp); if (nv_ri32(dev, 0) != ~tmp) { NV_ERROR(dev, "PRAMIN readback failed\n"); - return -EIO; + ret = -EIO; + goto error; } nv_wi32(dev, 0, tmp); dev_priv->ramin_available = true; + /* BAR1 */ + ret = nouveau_vm_new(dev, BAR1_VM_BASE, BAR1_VM_SIZE, BAR1_VM_BASE, + 29, 12, 16, &vm); + if (ret) + goto error; + + ret = nouveau_vm_ref(vm, &dev_priv->bar1_vm, chan->vm_pd); + if (ret) + goto error; + nouveau_vm_ref(NULL, &vm, NULL); + + ret = nv50_gpuobj_dma_new(chan, 0x0000, BAR1_VM_BASE, BAR1_VM_SIZE, + NV_MEM_TARGET_VM, NV_MEM_ACCESS_VM, + NV_MEM_TYPE_VM, NV_MEM_COMP_VM, + &priv->bar1_dmaobj); + if (ret) + goto error; + + nv_wr32(dev, 0x001708, 0x80000000 | (priv->bar1_dmaobj->cinst >> 4)); + for (i = 0; i < 8; i++) + nv_wr32(dev, 0x1900 + (i*4), 0); + /* Determine VM layout */ dev_priv->vm_gart_base = roundup(NV50_VM_BLOCK, NV50_VM_BLOCK); dev_priv->vm_gart_size = NV50_VM_BLOCK; @@ -200,38 +239,19 @@ nv50_instmem_init(struct drm_device *dev) for (i = 0; i < dev_priv->vm_vram_pt_nr; i++) { ret = nouveau_gpuobj_new(dev, NULL, NV50_VM_BLOCK / 0x10000 * 8, 0, NVOBJ_FLAG_ZERO_ALLOC, - &chan->vm_vram_pt[i]); + &dev_priv->vm_vram_pt[i]); if (ret) { NV_ERROR(dev, "Error creating VRAM PGT: %d\n", ret); dev_priv->vm_vram_pt_nr = i; return ret; } - dev_priv->vm_vram_pt[i] = chan->vm_vram_pt[i]; - - nv_wo32(chan->vm_pd, 0x10 + (i*8), - chan->vm_vram_pt[i]->vinst | 0x61); - nv_wo32(chan->vm_pd, 0x14 + (i*8), 0); } - /* DMA object for FB BAR */ - ret = nouveau_gpuobj_new(dev, chan, 6*4, 16, 0, &priv->fb_bar); - if (ret) - return ret; - nv_wo32(priv->fb_bar, 0x00, 0x7fc00000); - nv_wo32(priv->fb_bar, 0x04, 0x40000000 + - pci_resource_len(dev->pdev, 1) - 1); - nv_wo32(priv->fb_bar, 0x08, 0x40000000); - nv_wo32(priv->fb_bar, 0x0c, 0x00000000); - nv_wo32(priv->fb_bar, 0x10, 0x00000000); - nv_wo32(priv->fb_bar, 0x14, 0x00000000); - - dev_priv->engine.instmem.flush(dev); - - nv_wr32(dev, 0x001708, 0x80000000 | (priv->fb_bar->cinst >> 4)); - for (i = 0; i < 8; i++) - nv_wr32(dev, 0x1900 + (i*4), 0); - return 0; + +error: + nv50_instmem_takedown(dev); + return ret; } void @@ -249,23 +269,25 @@ nv50_instmem_takedown(struct drm_device *dev) dev_priv->ramin_available = false; - /* Restore state from before init */ + for (i = 0; i < dev_priv->vm_vram_pt_nr; i++) + nouveau_gpuobj_ref(NULL, &dev_priv->vm_vram_pt[i]); + dev_priv->vm_vram_pt_nr = 0; + for (i = 0x1700; i <= 0x1710; i += 4) nv_wr32(dev, i, priv->save1700[(i - 0x1700) / 4]); - nouveau_gpuobj_ref(NULL, &priv->fb_bar); - nouveau_gpuobj_ref(NULL, &priv->pramin_bar); - nouveau_gpuobj_ref(NULL, &priv->pramin_pt); + nouveau_gpuobj_ref(NULL, &priv->bar3_dmaobj); + nouveau_gpuobj_ref(NULL, &priv->bar1_dmaobj); - /* Destroy dummy channel */ - if (chan) { - for (i = 0; i < dev_priv->vm_vram_pt_nr; i++) - nouveau_gpuobj_ref(NULL, &chan->vm_vram_pt[i]); - dev_priv->vm_vram_pt_nr = 0; + nouveau_vm_ref(NULL, &dev_priv->bar1_vm, chan->vm_pd); + dev_priv->channels.ptr[127] = 0; + nv50_channel_del(&dev_priv->channels.ptr[0]); - nv50_channel_del(&dev_priv->channels.ptr[0]); - dev_priv->channels.ptr[127] = NULL; - } + nouveau_gpuobj_ref(NULL, &dev_priv->bar3_vm->pgt[0].obj); + nouveau_vm_ref(NULL, &dev_priv->bar3_vm, NULL); + + if (dev_priv->ramin_heap.free_stack.next) + drm_mm_takedown(&dev_priv->ramin_heap); dev_priv->engine.instmem.priv = NULL; kfree(priv); @@ -293,9 +315,9 @@ nv50_instmem_resume(struct drm_device *dev) nv_wr32(dev, NV50_PUNK_UNK1710, 0); nv_wr32(dev, NV50_PUNK_BAR_CFG_BASE, (chan->ramin->vinst >> 12) | NV50_PUNK_BAR_CFG_BASE_VALID); - nv_wr32(dev, NV50_PUNK_BAR1_CTXDMA, (priv->fb_bar->cinst >> 4) | + nv_wr32(dev, NV50_PUNK_BAR1_CTXDMA, (priv->bar1_dmaobj->cinst >> 4) | NV50_PUNK_BAR1_CTXDMA_VALID); - nv_wr32(dev, NV50_PUNK_BAR3_CTXDMA, (priv->pramin_bar->cinst >> 4) | + nv_wr32(dev, NV50_PUNK_BAR3_CTXDMA, (priv->bar3_dmaobj->cinst >> 4) | NV50_PUNK_BAR3_CTXDMA_VALID); for (i = 0; i < 8; i++) @@ -305,8 +327,7 @@ nv50_instmem_resume(struct drm_device *dev) } struct nv50_gpuobj_node { - struct nouveau_bo *vram; - struct drm_mm_node *ramin; + struct nouveau_vram *vram; u32 align; }; @@ -323,23 +344,17 @@ nv50_instmem_get(struct nouveau_gpuobj *gpuobj, u32 size, u32 align) return -ENOMEM; node->align = align; - ret = nouveau_bo_new(dev, NULL, size, align, TTM_PL_FLAG_VRAM, - 0, 0x0000, true, false, &node->vram); - if (ret) { - NV_ERROR(dev, "error getting PRAMIN backing pages: %d\n", ret); - WARN_ON(1); - return ret; - } + size = (size + 4095) & ~4095; + align = max(align, (u32)4096); - ret = nouveau_bo_pin(node->vram, TTM_PL_FLAG_VRAM); + ret = nv50_vram_new(dev, size, align, 0, 0, &node->vram); if (ret) { - NV_ERROR(dev, "error pinning PRAMIN backing VRAM: %d\n", ret); - nouveau_bo_ref(NULL, &node->vram); + kfree(node); return ret; } - gpuobj->vinst = node->vram->bo.mem.start << PAGE_SHIFT; - gpuobj->size = node->vram->bo.mem.num_pages << PAGE_SHIFT; + gpuobj->vinst = node->vram->offset; + gpuobj->size = size; gpuobj->node = node; return 0; } @@ -347,13 +362,13 @@ nv50_instmem_get(struct nouveau_gpuobj *gpuobj, u32 size, u32 align) void nv50_instmem_put(struct nouveau_gpuobj *gpuobj) { + struct drm_device *dev = gpuobj->dev; struct nv50_gpuobj_node *node; node = gpuobj->node; gpuobj->node = NULL; - nouveau_bo_unpin(node->vram); - nouveau_bo_ref(NULL, &node->vram); + nv50_vram_del(dev, &node->vram); kfree(node); } @@ -361,83 +376,28 @@ int nv50_instmem_map(struct nouveau_gpuobj *gpuobj) { struct drm_nouveau_private *dev_priv = gpuobj->dev->dev_private; - struct nv50_instmem_priv *priv = dev_priv->engine.instmem.priv; struct nv50_gpuobj_node *node = gpuobj->node; - struct drm_device *dev = gpuobj->dev; - struct drm_mm_node *ramin = NULL; - u32 pte, pte_end; - u64 vram; - - do { - if (drm_mm_pre_get(&dev_priv->ramin_heap)) - return -ENOMEM; - - spin_lock(&dev_priv->ramin_lock); - ramin = drm_mm_search_free(&dev_priv->ramin_heap, gpuobj->size, - node->align, 0); - if (ramin == NULL) { - spin_unlock(&dev_priv->ramin_lock); - return -ENOMEM; - } - - ramin = drm_mm_get_block_atomic(ramin, gpuobj->size, node->align); - spin_unlock(&dev_priv->ramin_lock); - } while (ramin == NULL); - - pte = (ramin->start >> 12) << 1; - pte_end = ((ramin->size >> 12) << 1) + pte; - vram = gpuobj->vinst; - - NV_DEBUG(dev, "pramin=0x%lx, pte=%d, pte_end=%d\n", - ramin->start, pte, pte_end); - NV_DEBUG(dev, "first vram page: 0x%010llx\n", gpuobj->vinst); - - vram |= 1; - if (dev_priv->vram_sys_base) { - vram += dev_priv->vram_sys_base; - vram |= 0x30; - } - - while (pte < pte_end) { - nv_wo32(priv->pramin_pt, (pte * 4) + 0, lower_32_bits(vram)); - nv_wo32(priv->pramin_pt, (pte * 4) + 4, upper_32_bits(vram)); - vram += 0x1000; - pte += 2; - } - dev_priv->engine.instmem.flush(dev); + int ret; - nv50_vm_flush_engine(dev, 6); + ret = nouveau_vm_get(dev_priv->bar3_vm, gpuobj->size, 12, + NV_MEM_ACCESS_RW, &node->vram->bar_vma); + if (ret) + return ret; - node->ramin = ramin; - gpuobj->pinst = ramin->start; + nouveau_vm_map(&node->vram->bar_vma, node->vram); + gpuobj->pinst = node->vram->bar_vma.offset; return 0; } void nv50_instmem_unmap(struct nouveau_gpuobj *gpuobj) { - struct drm_nouveau_private *dev_priv = gpuobj->dev->dev_private; - struct nv50_instmem_priv *priv = dev_priv->engine.instmem.priv; struct nv50_gpuobj_node *node = gpuobj->node; - u32 pte, pte_end; - if (!node->ramin || !dev_priv->ramin_available) - return; - - pte = (node->ramin->start >> 12) << 1; - pte_end = ((node->ramin->size >> 12) << 1) + pte; - - while (pte < pte_end) { - nv_wo32(priv->pramin_pt, (pte * 4) + 0, 0x00000000); - nv_wo32(priv->pramin_pt, (pte * 4) + 4, 0x00000000); - pte += 2; + if (node->vram->bar_vma.node) { + nouveau_vm_unmap(&node->vram->bar_vma); + nouveau_vm_put(&node->vram->bar_vma); } - dev_priv->engine.instmem.flush(gpuobj->dev); - - spin_lock(&dev_priv->ramin_lock); - drm_mm_put_block(node->ramin); - node->ramin = NULL; - spin_unlock(&dev_priv->ramin_lock); } void diff --git a/drivers/gpu/drm/nouveau/nv50_vm.c b/drivers/gpu/drm/nouveau/nv50_vm.c index ab6c3d0ce32e..efc63c0b0d92 100644 --- a/drivers/gpu/drm/nouveau/nv50_vm.c +++ b/drivers/gpu/drm/nouveau/nv50_vm.c @@ -151,7 +151,6 @@ nv50_vm_flush(struct nouveau_vm *vm) struct nouveau_instmem_engine *pinstmem = &dev_priv->engine.instmem; pinstmem->flush(vm->dev); - nv50_vm_flush_engine(vm->dev, 6); } -- cgit v1.2.3 From 4c1361429841344ce4d164492ee7620cf3286eb7 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 15 Nov 2010 11:54:21 +1000 Subject: drm/nv50: implement global channel address space on new VM code As of this commit, it's guaranteed that if an object is in VRAM that its GPU virtual address will be constant. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_bo.c | 41 ++++++++------ drivers/gpu/drm/nouveau/nouveau_channel.c | 2 +- drivers/gpu/drm/nouveau/nouveau_drv.c | 8 +-- drivers/gpu/drm/nouveau/nouveau_drv.h | 17 +----- drivers/gpu/drm/nouveau/nouveau_fbcon.c | 4 +- drivers/gpu/drm/nouveau/nouveau_mem.c | 94 ------------------------------- drivers/gpu/drm/nouveau/nouveau_object.c | 47 ++++------------ drivers/gpu/drm/nouveau/nv50_crtc.c | 6 +- drivers/gpu/drm/nouveau/nv50_fbcon.c | 13 ++--- drivers/gpu/drm/nouveau/nv50_graph.c | 3 + drivers/gpu/drm/nouveau/nv50_instmem.c | 48 +++++----------- drivers/gpu/drm/nouveau/nv50_vm.c | 17 +++++- drivers/gpu/drm/nouveau/nv84_crypt.c | 2 + 13 files changed, 86 insertions(+), 216 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index 4d142031d542..203e75de4128 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c @@ -49,6 +49,7 @@ nouveau_bo_del_ttm(struct ttm_buffer_object *bo) DRM_ERROR("bo %p still attached to GEM object\n", bo); nv10_mem_put_tile_region(dev, nvbo->tile, NULL); + nouveau_vm_put(&nvbo->vma); kfree(nvbo); } @@ -113,6 +114,15 @@ nouveau_bo_new(struct drm_device *dev, struct nouveau_channel *chan, &align, &size); align >>= PAGE_SHIFT; + if (!nvbo->no_vm && dev_priv->chan_vm) { + ret = nouveau_vm_get(dev_priv->chan_vm, size, 16, + NV_MEM_ACCESS_RW, &nvbo->vma); + if (ret) { + kfree(nvbo); + return ret; + } + } + nouveau_bo_placement_set(nvbo, flags, 0); nvbo->channel = chan; @@ -125,6 +135,11 @@ nouveau_bo_new(struct drm_device *dev, struct nouveau_channel *chan, } nvbo->channel = NULL; + if (nvbo->vma.node) { + if (nvbo->bo.mem.mem_type == TTM_PL_VRAM) + nvbo->bo.offset = nvbo->vma.offset; + } + *pnvbo = nvbo; return 0; } @@ -294,6 +309,11 @@ nouveau_bo_validate(struct nouveau_bo *nvbo, bool interruptible, if (ret) return ret; + if (nvbo->vma.node) { + if (nvbo->bo.mem.mem_type == TTM_PL_VRAM) + nvbo->bo.offset = nvbo->vma.offset; + } + return 0; } @@ -400,10 +420,7 @@ nouveau_bo_init_mem_type(struct ttm_bo_device *bdev, uint32_t type, man->available_caching = TTM_PL_FLAG_UNCACHED | TTM_PL_FLAG_WC; man->default_caching = TTM_PL_FLAG_WC; - if (dev_priv->card_type == NV_50) - man->gpu_offset = 0x40000000; - else - man->gpu_offset = 0; + man->gpu_offset = 0; break; case TTM_PL_TT: man->func = &ttm_bo_manager_func; @@ -507,12 +524,12 @@ nv50_bo_move_m2mf(struct nouveau_channel *chan, struct ttm_buffer_object *bo, dst_offset = new_mem->start << PAGE_SHIFT; if (!nvbo->no_vm) { if (old_mem->mem_type == TTM_PL_VRAM) - src_offset += dev_priv->vm_vram_base; + src_offset = nvbo->vma.offset; else src_offset += dev_priv->vm_gart_base; if (new_mem->mem_type == TTM_PL_VRAM) - dst_offset += dev_priv->vm_vram_base; + dst_offset = nvbo->vma.offset; else dst_offset += dev_priv->vm_gart_base; } @@ -756,7 +773,6 @@ nouveau_bo_vm_bind(struct ttm_buffer_object *bo, struct ttm_mem_reg *new_mem, struct drm_device *dev = dev_priv->dev; struct nouveau_bo *nvbo = nouveau_bo(bo); uint64_t offset; - int ret; if (nvbo->no_vm || new_mem->mem_type != TTM_PL_VRAM) { /* Nothing to do. */ @@ -766,15 +782,8 @@ nouveau_bo_vm_bind(struct ttm_buffer_object *bo, struct ttm_mem_reg *new_mem, offset = new_mem->start << PAGE_SHIFT; - if (dev_priv->card_type == NV_50) { - ret = nv50_mem_vm_bind_linear(dev, - offset + dev_priv->vm_vram_base, - new_mem->size, - nouveau_bo_tile_layout(nvbo), - offset); - if (ret) - return ret; - + if (dev_priv->chan_vm) { + nouveau_vm_map(&nvbo->vma, new_mem->mm_node); } else if (dev_priv->card_type >= NV_10) { *new_tile = nv10_mem_set_tiling(dev, offset, new_mem->size, nvbo->tile_mode, diff --git a/drivers/gpu/drm/nouveau/nouveau_channel.c b/drivers/gpu/drm/nouveau/nouveau_channel.c index a3d33a582a98..6f37995aee2d 100644 --- a/drivers/gpu/drm/nouveau/nouveau_channel.c +++ b/drivers/gpu/drm/nouveau/nouveau_channel.c @@ -39,7 +39,7 @@ nouveau_channel_pushbuf_ctxdma_init(struct nouveau_channel *chan) if (dev_priv->card_type >= NV_50) { ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY, 0, - dev_priv->vm_end, NV_MEM_ACCESS_RO, + (1ULL << 40), NV_MEM_ACCESS_RO, NV_MEM_TARGET_VM, &pushbuf); chan->pushbuf_base = pb->bo.offset; } else diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.c b/drivers/gpu/drm/nouveau/nouveau_drv.c index a48c7da133d2..bb170570938b 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.c +++ b/drivers/gpu/drm/nouveau/nouveau_drv.c @@ -339,13 +339,11 @@ nouveau_pci_resume(struct pci_dev *pdev) list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); + u32 offset = nv_crtc->cursor.nvbo->bo.mem.start << PAGE_SHIFT; - nv_crtc->cursor.set_offset(nv_crtc, - nv_crtc->cursor.nvbo->bo.offset - - dev_priv->vm_vram_base); - + nv_crtc->cursor.set_offset(nv_crtc, offset); nv_crtc->cursor.set_pos(nv_crtc, nv_crtc->cursor_saved_x, - nv_crtc->cursor_saved_y); + nv_crtc->cursor_saved_y); } /* Force CLUT to get re-loaded during modeset */ diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index 452a8652a498..dce9a5f6f6c4 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -65,10 +65,6 @@ struct nouveau_vram; #define NOUVEAU_MAX_CHANNEL_NR 128 #define NOUVEAU_MAX_TILE_NR 15 -#define NV50_VM_MAX_VRAM (2*1024*1024*1024ULL) -#define NV50_VM_BLOCK (512*1024*1024ULL) -#define NV50_VM_VRAM_NR (NV50_VM_MAX_VRAM / NV50_VM_BLOCK) - struct nouveau_vram { struct drm_device *dev; @@ -106,6 +102,7 @@ struct nouveau_bo { struct nouveau_channel *channel; + struct nouveau_vma vma; bool mappable; bool no_vm; @@ -252,7 +249,6 @@ struct nouveau_channel { struct nouveau_vm *vm; struct nouveau_gpuobj *vm_pd; struct nouveau_gpuobj *vm_gart_pt; - struct nouveau_gpuobj *vm_vram_pt[NV50_VM_VRAM_NR]; /* Objects */ struct nouveau_gpuobj *ramin; /* Private instmem */ @@ -712,13 +708,9 @@ struct drm_nouveau_private { struct nouveau_vm *bar3_vm; /* G8x/G9x virtual address space */ + struct nouveau_vm *chan_vm; uint64_t vm_gart_base; uint64_t vm_gart_size; - uint64_t vm_vram_base; - uint64_t vm_vram_size; - uint64_t vm_end; - struct nouveau_gpuobj *vm_vram_pt[NV50_VM_VRAM_NR]; - int vm_vram_pt_nr; struct nvbios vbios; @@ -836,11 +828,6 @@ extern struct nouveau_tile_reg *nv10_mem_set_tiling( extern void nv10_mem_put_tile_region(struct drm_device *dev, struct nouveau_tile_reg *tile, struct nouveau_fence *fence); -extern int nv50_mem_vm_bind_linear(struct drm_device *, uint64_t virt, - uint32_t size, uint32_t flags, - uint64_t phys); -extern void nv50_mem_vm_unbind(struct drm_device *, uint64_t virt, - uint32_t size); extern const struct ttm_mem_type_manager_func nouveau_vram_manager; /* nouveau_notifier.c */ diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/drivers/gpu/drm/nouveau/nouveau_fbcon.c index 0fce4eb914d5..ea861c915149 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fbcon.c +++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c @@ -338,8 +338,8 @@ nouveau_fbcon_create(struct nouveau_fbdev *nfbdev, FBINFO_HWACCEL_IMAGEBLIT; info->flags |= FBINFO_CAN_FORCE_OUTPUT; info->fbops = &nouveau_fbcon_sw_ops; - info->fix.smem_start = dev->mode_config.fb_base + nvbo->bo.offset - - dev_priv->vm_vram_base; + info->fix.smem_start = dev->mode_config.fb_base + + (nvbo->bo.mem.start << PAGE_SHIFT); info->fix.smem_len = size; info->screen_base = nvbo_kmap_obj_iovirtual(nouveau_fb->nvbo); diff --git a/drivers/gpu/drm/nouveau/nouveau_mem.c b/drivers/gpu/drm/nouveau/nouveau_mem.c index 2d02401e8227..4d2d3de97ee9 100644 --- a/drivers/gpu/drm/nouveau/nouveau_mem.c +++ b/drivers/gpu/drm/nouveau/nouveau_mem.c @@ -144,100 +144,6 @@ nv10_mem_set_tiling(struct drm_device *dev, uint32_t addr, uint32_t size, return found; } -/* - * NV50 VM helpers - */ -int -nv50_mem_vm_bind_linear(struct drm_device *dev, uint64_t virt, uint32_t size, - uint32_t flags, uint64_t phys) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_gpuobj *pgt; - unsigned block; - int i; - - virt = ((virt - dev_priv->vm_vram_base) >> 16) << 1; - size = (size >> 16) << 1; - - phys |= ((uint64_t)flags << 32); - phys |= 1; - if (dev_priv->vram_sys_base) { - phys += dev_priv->vram_sys_base; - phys |= 0x30; - } - - while (size) { - unsigned offset_h = upper_32_bits(phys); - unsigned offset_l = lower_32_bits(phys); - unsigned pte, end; - - for (i = 7; i >= 0; i--) { - block = 1 << (i + 1); - if (size >= block && !(virt & (block - 1))) - break; - } - offset_l |= (i << 7); - - phys += block << 15; - size -= block; - - while (block) { - pgt = dev_priv->vm_vram_pt[virt >> 14]; - pte = virt & 0x3ffe; - - end = pte + block; - if (end > 16384) - end = 16384; - block -= (end - pte); - virt += (end - pte); - - while (pte < end) { - nv_wo32(pgt, (pte * 4) + 0, offset_l); - nv_wo32(pgt, (pte * 4) + 4, offset_h); - pte += 2; - } - } - } - - dev_priv->engine.instmem.flush(dev); - dev_priv->engine.fifo.tlb_flush(dev); - dev_priv->engine.graph.tlb_flush(dev); - nv50_vm_flush_engine(dev, 6); - return 0; -} - -void -nv50_mem_vm_unbind(struct drm_device *dev, uint64_t virt, uint32_t size) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_gpuobj *pgt; - unsigned pages, pte, end; - - virt -= dev_priv->vm_vram_base; - pages = (size >> 16) << 1; - - while (pages) { - pgt = dev_priv->vm_vram_pt[virt >> 29]; - pte = (virt & 0x1ffe0000ULL) >> 15; - - end = pte + pages; - if (end > 16384) - end = 16384; - pages -= (end - pte); - virt += (end - pte) << 15; - - while (pte < end) { - nv_wo32(pgt, (pte * 4), 0); - pte++; - } - } - - dev_priv->engine.instmem.flush(dev); - dev_priv->engine.fifo.tlb_flush(dev); - dev_priv->engine.graph.tlb_flush(dev); - nv50_vm_flush_engine(dev, 6); -} - /* * Cleanup everything */ diff --git a/drivers/gpu/drm/nouveau/nouveau_object.c b/drivers/gpu/drm/nouveau/nouveau_object.c index dd1859f7d8b0..573fd7316d63 100644 --- a/drivers/gpu/drm/nouveau/nouveau_object.c +++ b/drivers/gpu/drm/nouveau/nouveau_object.c @@ -35,6 +35,7 @@ #include "nouveau_drv.h" #include "nouveau_drm.h" #include "nouveau_ramht.h" +#include "nouveau_vm.h" struct nouveau_gpuobj_method { struct list_head head; @@ -770,9 +771,8 @@ nouveau_gpuobj_channel_init(struct nouveau_channel *chan, { struct drm_device *dev = chan->dev; struct drm_nouveau_private *dev_priv = dev->dev_private; - struct nouveau_instmem_engine *instmem = &dev_priv->engine.instmem; struct nouveau_gpuobj *vram = NULL, *tt = NULL; - int ret, i; + int ret; NV_DEBUG(dev, "ch%d vram=0x%08x tt=0x%08x\n", chan->id, vram_h, tt_h); @@ -783,16 +783,14 @@ nouveau_gpuobj_channel_init(struct nouveau_channel *chan, return ret; } - /* NV50 VM + /* NV50/NVC0 VM * - Allocate per-channel page-directory - * - Map GART and VRAM into the channel's address space at the - * locations determined during init. + * - Link with shared channel VM */ - if (dev_priv->card_type >= NV_50) { + if (dev_priv->chan_vm) { u32 pgd_offs = (dev_priv->chipset == 0x50) ? 0x1400 : 0x0200; u64 vm_vinst = chan->ramin->vinst + pgd_offs; u32 vm_pinst = chan->ramin->pinst; - u32 pde; if (vm_pinst != ~0) vm_pinst += pgd_offs; @@ -801,29 +799,9 @@ nouveau_gpuobj_channel_init(struct nouveau_channel *chan, 0, &chan->vm_pd); if (ret) return ret; - for (i = 0; i < 0x4000; i += 8) { - nv_wo32(chan->vm_pd, i + 0, 0x00000000); - nv_wo32(chan->vm_pd, i + 4, 0xdeadcafe); - } - - nouveau_gpuobj_ref(dev_priv->gart_info.sg_ctxdma, - &chan->vm_gart_pt); - pde = (dev_priv->vm_gart_base / (512*1024*1024)) * 8; - nv_wo32(chan->vm_pd, pde + 0, chan->vm_gart_pt->vinst | 3); - nv_wo32(chan->vm_pd, pde + 4, 0x00000000); - - pde = (dev_priv->vm_vram_base / (512*1024*1024)) * 8; - for (i = 0; i < dev_priv->vm_vram_pt_nr; i++) { - nouveau_gpuobj_ref(dev_priv->vm_vram_pt[i], - &chan->vm_vram_pt[i]); - - nv_wo32(chan->vm_pd, pde + 0, - chan->vm_vram_pt[i]->vinst | 0x61); - nv_wo32(chan->vm_pd, pde + 4, 0x00000000); - pde += 8; - } - instmem->flush(dev); + nouveau_vm_ref(dev_priv->chan_vm, &chan->vm, chan->vm_pd); + chan->vm->map_pgt(chan->vm_pd, 12, 1, dev_priv->gart_info.sg_ctxdma); } /* RAMHT */ @@ -846,8 +824,7 @@ nouveau_gpuobj_channel_init(struct nouveau_channel *chan, /* VRAM ctxdma */ if (dev_priv->card_type >= NV_50) { ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY, - 0, dev_priv->vm_end, - NV_MEM_ACCESS_RW, + 0, (1ULL << 40), NV_MEM_ACCESS_RW, NV_MEM_TARGET_VM, &vram); if (ret) { NV_ERROR(dev, "Error creating VRAM ctxdma: %d\n", ret); @@ -874,8 +851,7 @@ nouveau_gpuobj_channel_init(struct nouveau_channel *chan, /* TT memory ctxdma */ if (dev_priv->card_type >= NV_50) { ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY, - 0, dev_priv->vm_end, - NV_MEM_ACCESS_RW, + 0, (1ULL << 40), NV_MEM_ACCESS_RW, NV_MEM_TARGET_VM, &tt); } else { ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY, @@ -902,9 +878,7 @@ nouveau_gpuobj_channel_init(struct nouveau_channel *chan, void nouveau_gpuobj_channel_takedown(struct nouveau_channel *chan) { - struct drm_nouveau_private *dev_priv = chan->dev->dev_private; struct drm_device *dev = chan->dev; - int i; NV_DEBUG(dev, "ch%d\n", chan->id); @@ -913,10 +887,9 @@ nouveau_gpuobj_channel_takedown(struct nouveau_channel *chan) nouveau_ramht_ref(NULL, &chan->ramht, chan); + nouveau_vm_ref(NULL, &chan->vm, chan->vm_pd); nouveau_gpuobj_ref(NULL, &chan->vm_pd); nouveau_gpuobj_ref(NULL, &chan->vm_gart_pt); - for (i = 0; i < dev_priv->vm_vram_pt_nr; i++) - nouveau_gpuobj_ref(NULL, &chan->vm_vram_pt[i]); if (chan->ramin_heap.free_stack.next) drm_mm_takedown(&chan->ramin_heap); diff --git a/drivers/gpu/drm/nouveau/nv50_crtc.c b/drivers/gpu/drm/nouveau/nv50_crtc.c index f3570cc45017..2c346f797285 100644 --- a/drivers/gpu/drm/nouveau/nv50_crtc.c +++ b/drivers/gpu/drm/nouveau/nv50_crtc.c @@ -345,7 +345,6 @@ nv50_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv, uint32_t buffer_handle, uint32_t width, uint32_t height) { struct drm_device *dev = crtc->dev; - struct drm_nouveau_private *dev_priv = dev->dev_private; struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); struct nouveau_bo *cursor = NULL; struct drm_gem_object *gem; @@ -374,8 +373,7 @@ nv50_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv, nouveau_bo_unmap(cursor); - nv_crtc->cursor.set_offset(nv_crtc, nv_crtc->cursor.nvbo->bo.offset - - dev_priv->vm_vram_base); + nv_crtc->cursor.set_offset(nv_crtc, nv_crtc->cursor.nvbo->bo.mem.start << PAGE_SHIFT); nv_crtc->cursor.show(nv_crtc, true); out: @@ -548,7 +546,7 @@ nv50_crtc_do_mode_set_base(struct drm_crtc *crtc, return -EINVAL; } - nv_crtc->fb.offset = fb->nvbo->bo.offset - dev_priv->vm_vram_base; + nv_crtc->fb.offset = fb->nvbo->bo.mem.start << PAGE_SHIFT; nv_crtc->fb.tile_flags = nouveau_bo_tile_layout(fb->nvbo); nv_crtc->fb.cpp = drm_fb->bits_per_pixel / 8; if (!nv_crtc->fb.blanked && dev_priv->chipset != 0x50) { diff --git a/drivers/gpu/drm/nouveau/nv50_fbcon.c b/drivers/gpu/drm/nouveau/nv50_fbcon.c index 156731993907..6d38cb1488ae 100644 --- a/drivers/gpu/drm/nouveau/nv50_fbcon.c +++ b/drivers/gpu/drm/nouveau/nv50_fbcon.c @@ -3,6 +3,7 @@ #include "nouveau_dma.h" #include "nouveau_ramht.h" #include "nouveau_fbcon.h" +#include "nouveau_mm.h" int nv50_fbcon_fillrect(struct fb_info *info, const struct fb_fillrect *rect) @@ -134,10 +135,8 @@ nv50_fbcon_accel_init(struct fb_info *info) struct drm_device *dev = nfbdev->dev; struct drm_nouveau_private *dev_priv = dev->dev_private; struct nouveau_channel *chan = dev_priv->channel; + struct nouveau_bo *nvbo = nfbdev->nouveau_fb.nvbo; int ret, format; - uint64_t fb; - - fb = info->fix.smem_start - dev_priv->fb_phys + dev_priv->vm_vram_base; switch (info->var.bits_per_pixel) { case 8: @@ -224,8 +223,8 @@ nv50_fbcon_accel_init(struct fb_info *info) OUT_RING(chan, info->fix.line_length); OUT_RING(chan, info->var.xres_virtual); OUT_RING(chan, info->var.yres_virtual); - OUT_RING(chan, upper_32_bits(fb)); - OUT_RING(chan, lower_32_bits(fb)); + OUT_RING(chan, upper_32_bits(nvbo->vma.offset)); + OUT_RING(chan, lower_32_bits(nvbo->vma.offset)); BEGIN_RING(chan, NvSub2D, 0x0230, 2); OUT_RING(chan, format); OUT_RING(chan, 1); @@ -233,8 +232,8 @@ nv50_fbcon_accel_init(struct fb_info *info) OUT_RING(chan, info->fix.line_length); OUT_RING(chan, info->var.xres_virtual); OUT_RING(chan, info->var.yres_virtual); - OUT_RING(chan, upper_32_bits(fb)); - OUT_RING(chan, lower_32_bits(fb)); + OUT_RING(chan, upper_32_bits(nvbo->vma.offset)); + OUT_RING(chan, lower_32_bits(nvbo->vma.offset)); return 0; } diff --git a/drivers/gpu/drm/nouveau/nv50_graph.c b/drivers/gpu/drm/nouveau/nv50_graph.c index f5fd1b296d27..c510e74acf4d 100644 --- a/drivers/gpu/drm/nouveau/nv50_graph.c +++ b/drivers/gpu/drm/nouveau/nv50_graph.c @@ -246,6 +246,7 @@ nv50_graph_create_context(struct nouveau_channel *chan) nv_wo32(chan->ramin_grctx, 0x00000, chan->ramin->vinst >> 12); dev_priv->engine.instmem.flush(dev); + atomic_inc(&chan->vm->pgraph_refs); return 0; } @@ -277,6 +278,8 @@ nv50_graph_destroy_context(struct nouveau_channel *chan) spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags); nouveau_gpuobj_ref(NULL, &chan->ramin_grctx); + + atomic_dec(&chan->vm->pgraph_refs); } static int diff --git a/drivers/gpu/drm/nouveau/nv50_instmem.c b/drivers/gpu/drm/nouveau/nv50_instmem.c index 4ba8f74e77b1..08202fd682e4 100644 --- a/drivers/gpu/drm/nouveau/nv50_instmem.c +++ b/drivers/gpu/drm/nouveau/nv50_instmem.c @@ -131,6 +131,7 @@ nv50_instmem_init(struct drm_device *dev) struct nouveau_channel *chan; struct nouveau_vm *vm; int ret, i; + u64 nongart_o; u32 tmp; priv = kzalloc(sizeof(*priv), GFP_KERNEL); @@ -215,37 +216,18 @@ nv50_instmem_init(struct drm_device *dev) for (i = 0; i < 8; i++) nv_wr32(dev, 0x1900 + (i*4), 0); - /* Determine VM layout */ - dev_priv->vm_gart_base = roundup(NV50_VM_BLOCK, NV50_VM_BLOCK); - dev_priv->vm_gart_size = NV50_VM_BLOCK; - - dev_priv->vm_vram_base = dev_priv->vm_gart_base + dev_priv->vm_gart_size; - dev_priv->vm_vram_size = dev_priv->vram_size; - if (dev_priv->vm_vram_size > NV50_VM_MAX_VRAM) - dev_priv->vm_vram_size = NV50_VM_MAX_VRAM; - dev_priv->vm_vram_size = roundup(dev_priv->vm_vram_size, NV50_VM_BLOCK); - dev_priv->vm_vram_pt_nr = dev_priv->vm_vram_size / NV50_VM_BLOCK; - - dev_priv->vm_end = dev_priv->vm_vram_base + dev_priv->vm_vram_size; - - NV_DEBUG(dev, "NV50VM: GART 0x%016llx-0x%016llx\n", - dev_priv->vm_gart_base, - dev_priv->vm_gart_base + dev_priv->vm_gart_size - 1); - NV_DEBUG(dev, "NV50VM: VRAM 0x%016llx-0x%016llx\n", - dev_priv->vm_vram_base, - dev_priv->vm_vram_base + dev_priv->vm_vram_size - 1); - - /* VRAM page table(s), mapped into VM at +1GiB */ - for (i = 0; i < dev_priv->vm_vram_pt_nr; i++) { - ret = nouveau_gpuobj_new(dev, NULL, NV50_VM_BLOCK / 0x10000 * 8, - 0, NVOBJ_FLAG_ZERO_ALLOC, - &dev_priv->vm_vram_pt[i]); - if (ret) { - NV_ERROR(dev, "Error creating VRAM PGT: %d\n", ret); - dev_priv->vm_vram_pt_nr = i; - return ret; - } - } + /* Create shared channel VM, space is reserved for GART mappings at + * the beginning of this address space, it's managed separately + * because TTM makes life painful + */ + dev_priv->vm_gart_base = 0x0020000000ULL; + dev_priv->vm_gart_size = 512 * 1024 * 1024; + nongart_o = dev_priv->vm_gart_base + dev_priv->vm_gart_size; + + ret = nouveau_vm_new(dev, 0, (1ULL << 40), nongart_o, + 29, 12, 16, &dev_priv->chan_vm); + if (ret) + return ret; return 0; @@ -269,9 +251,7 @@ nv50_instmem_takedown(struct drm_device *dev) dev_priv->ramin_available = false; - for (i = 0; i < dev_priv->vm_vram_pt_nr; i++) - nouveau_gpuobj_ref(NULL, &dev_priv->vm_vram_pt[i]); - dev_priv->vm_vram_pt_nr = 0; + nouveau_vm_ref(NULL, &dev_priv->chan_vm, NULL); for (i = 0x1700; i <= 0x1710; i += 4) nv_wr32(dev, i, priv->save1700[(i - 0x1700) / 4]); diff --git a/drivers/gpu/drm/nouveau/nv50_vm.c b/drivers/gpu/drm/nouveau/nv50_vm.c index efc63c0b0d92..eebab95f59b2 100644 --- a/drivers/gpu/drm/nouveau/nv50_vm.c +++ b/drivers/gpu/drm/nouveau/nv50_vm.c @@ -149,9 +149,24 @@ nv50_vm_flush(struct nouveau_vm *vm) { struct drm_nouveau_private *dev_priv = vm->dev->dev_private; struct nouveau_instmem_engine *pinstmem = &dev_priv->engine.instmem; + struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo; + struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; + struct nouveau_crypt_engine *pcrypt = &dev_priv->engine.crypt; pinstmem->flush(vm->dev); - nv50_vm_flush_engine(vm->dev, 6); + + /* BAR */ + if (vm != dev_priv->chan_vm) { + nv50_vm_flush_engine(vm->dev, 6); + return; + } + + pfifo->tlb_flush(vm->dev); + + if (atomic_read(&vm->pgraph_refs)) + pgraph->tlb_flush(vm->dev); + if (atomic_read(&vm->pcrypt_refs)) + pcrypt->tlb_flush(vm->dev); } void diff --git a/drivers/gpu/drm/nouveau/nv84_crypt.c b/drivers/gpu/drm/nouveau/nv84_crypt.c index a333e5905346..ec18ae1c3886 100644 --- a/drivers/gpu/drm/nouveau/nv84_crypt.c +++ b/drivers/gpu/drm/nouveau/nv84_crypt.c @@ -53,6 +53,7 @@ nv84_crypt_create_context(struct nouveau_channel *chan) nv_wo32(ramin, 0xb4, 0); dev_priv->engine.instmem.flush(dev); + atomic_inc(&chan->vm->pcrypt_refs); return 0; } @@ -80,6 +81,7 @@ nv84_crypt_destroy_context(struct nouveau_channel *chan) nv_wr32(dev, 0x10200c, 0x00000010); nouveau_gpuobj_ref(NULL, &chan->crypt_ctx); + atomic_dec(&chan->vm->pcrypt_refs); } void -- cgit v1.2.3 From bfd83aca5a1c4cc07fb18d96ed8660f2c338a8f3 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 12 Nov 2010 15:12:51 +1000 Subject: drm/nv50: enable 4KiB pages for small vram allocations Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_bo.c | 41 ++++++++++++++++++++--------------- drivers/gpu/drm/nouveau/nouveau_mem.c | 3 ++- 2 files changed, 25 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index 203e75de4128..bc28aeada8c3 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c @@ -54,39 +54,45 @@ nouveau_bo_del_ttm(struct ttm_buffer_object *bo) } static void -nouveau_bo_fixup_align(struct drm_device *dev, - uint32_t tile_mode, uint32_t tile_flags, - int *align, int *size) +nouveau_bo_fixup_align(struct nouveau_bo *nvbo, int *align, int *size, + int *page_shift) { - struct drm_nouveau_private *dev_priv = dev->dev_private; + struct drm_nouveau_private *dev_priv = nouveau_bdev(nvbo->bo.bdev); if (dev_priv->card_type < NV_50) { - if (tile_mode) { + if (nvbo->tile_mode) { if (dev_priv->chipset >= 0x40) { *align = 65536; - *size = roundup(*size, 64 * tile_mode); + *size = roundup(*size, 64 * nvbo->tile_mode); } else if (dev_priv->chipset >= 0x30) { *align = 32768; - *size = roundup(*size, 64 * tile_mode); + *size = roundup(*size, 64 * nvbo->tile_mode); } else if (dev_priv->chipset >= 0x20) { *align = 16384; - *size = roundup(*size, 64 * tile_mode); + *size = roundup(*size, 64 * nvbo->tile_mode); } else if (dev_priv->chipset >= 0x10) { *align = 16384; - *size = roundup(*size, 32 * tile_mode); + *size = roundup(*size, 32 * nvbo->tile_mode); } } + } else { + if (likely(dev_priv->chan_vm)) { + if (*size > 256 * 1024) + *page_shift = dev_priv->chan_vm->lpg_shift; + else + *page_shift = dev_priv->chan_vm->spg_shift; + } else { + *page_shift = 12; + } + + *size = roundup(*size, (1 << *page_shift)); + *align = max((1 << *page_shift), *align); } - /* ALIGN works only on powers of two. */ *size = roundup(*size, PAGE_SIZE); - if (dev_priv->card_type == NV_50) { - *size = roundup(*size, 65536); - *align = max(65536, *align); - } } int @@ -97,7 +103,7 @@ nouveau_bo_new(struct drm_device *dev, struct nouveau_channel *chan, { struct drm_nouveau_private *dev_priv = dev->dev_private; struct nouveau_bo *nvbo; - int ret = 0; + int ret = 0, page_shift = 0; nvbo = kzalloc(sizeof(struct nouveau_bo), GFP_KERNEL); if (!nvbo) @@ -110,12 +116,11 @@ nouveau_bo_new(struct drm_device *dev, struct nouveau_channel *chan, nvbo->tile_flags = tile_flags; nvbo->bo.bdev = &dev_priv->ttm.bdev; - nouveau_bo_fixup_align(dev, tile_mode, nouveau_bo_tile_layout(nvbo), - &align, &size); + nouveau_bo_fixup_align(nvbo, &align, &size, &page_shift); align >>= PAGE_SHIFT; if (!nvbo->no_vm && dev_priv->chan_vm) { - ret = nouveau_vm_get(dev_priv->chan_vm, size, 16, + ret = nouveau_vm_get(dev_priv->chan_vm, size, page_shift, NV_MEM_ACCESS_RW, &nvbo->vma); if (ret) { kfree(nvbo); diff --git a/drivers/gpu/drm/nouveau/nouveau_mem.c b/drivers/gpu/drm/nouveau/nouveau_mem.c index 4d2d3de97ee9..3a531d53de4d 100644 --- a/drivers/gpu/drm/nouveau/nouveau_mem.c +++ b/drivers/gpu/drm/nouveau/nouveau_mem.c @@ -715,7 +715,8 @@ nouveau_vram_manager_new(struct ttm_mem_type_manager *man, struct nouveau_vram *vram; int ret; - ret = nv50_vram_new(dev, mem->num_pages << PAGE_SHIFT, 65536, 0, + ret = nv50_vram_new(dev, mem->num_pages << PAGE_SHIFT, + mem->page_alignment << PAGE_SHIFT, 0, (nvbo->tile_flags >> 8) & 0x7f, &vram); if (ret) return ret; -- cgit v1.2.3 From 5f6fdca570b13a8a2c9cab9ab6edfc17487049cf Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 12 Nov 2010 15:13:59 +1000 Subject: drm/nv50: enable non-contig vram allocations where requested Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_mem.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_mem.c b/drivers/gpu/drm/nouveau/nouveau_mem.c index 3a531d53de4d..5a1809480388 100644 --- a/drivers/gpu/drm/nouveau/nouveau_mem.c +++ b/drivers/gpu/drm/nouveau/nouveau_mem.c @@ -713,10 +713,14 @@ nouveau_vram_manager_new(struct ttm_mem_type_manager *man, struct drm_device *dev = dev_priv->dev; struct nouveau_bo *nvbo = nouveau_bo(bo); struct nouveau_vram *vram; + u32 size_nc = 0; int ret; + if (nvbo->tile_flags & NOUVEAU_GEM_TILE_NONCONTIG) + size_nc = 1 << nvbo->vma.node->type; + ret = nv50_vram_new(dev, mem->num_pages << PAGE_SHIFT, - mem->page_alignment << PAGE_SHIFT, 0, + mem->page_alignment << PAGE_SHIFT, size_nc, (nvbo->tile_flags >> 8) & 0x7f, &vram); if (ret) return ret; -- cgit v1.2.3 From b571fe21f5c24760368b3fb927af5a7384d7721b Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 16 Nov 2010 10:13:05 +1000 Subject: drm/nv50: tidy up PCIEGART implementation Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_bo.c | 7 +- drivers/gpu/drm/nouveau/nouveau_drv.h | 4 +- drivers/gpu/drm/nouveau/nouveau_object.c | 4 +- drivers/gpu/drm/nouveau/nouveau_sgdma.c | 147 +++++++++++++++---------------- drivers/gpu/drm/nouveau/nv50_instmem.c | 12 +-- 5 files changed, 79 insertions(+), 95 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index bc28aeada8c3..42d1ad62b381 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c @@ -425,7 +425,6 @@ nouveau_bo_init_mem_type(struct ttm_bo_device *bdev, uint32_t type, man->available_caching = TTM_PL_FLAG_UNCACHED | TTM_PL_FLAG_WC; man->default_caching = TTM_PL_FLAG_WC; - man->gpu_offset = 0; break; case TTM_PL_TT: man->func = &ttm_bo_manager_func; @@ -441,13 +440,13 @@ nouveau_bo_init_mem_type(struct ttm_bo_device *bdev, uint32_t type, TTM_MEMTYPE_FLAG_CMA; man->available_caching = TTM_PL_MASK_CACHING; man->default_caching = TTM_PL_FLAG_CACHED; + man->gpu_offset = dev_priv->gart_info.aper_base; break; default: NV_ERROR(dev, "Unknown GART type: %d\n", dev_priv->gart_info.type); return -EINVAL; } - man->gpu_offset = dev_priv->vm_gart_base; break; default: NV_ERROR(dev, "Unsupported memory type %u\n", (unsigned)type); @@ -531,12 +530,12 @@ nv50_bo_move_m2mf(struct nouveau_channel *chan, struct ttm_buffer_object *bo, if (old_mem->mem_type == TTM_PL_VRAM) src_offset = nvbo->vma.offset; else - src_offset += dev_priv->vm_gart_base; + src_offset += dev_priv->gart_info.aper_base; if (new_mem->mem_type == TTM_PL_VRAM) dst_offset = nvbo->vma.offset; else - dst_offset += dev_priv->vm_gart_base; + dst_offset += dev_priv->gart_info.aper_base; } ret = RING_SPACE(chan, 3); diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index dce9a5f6f6c4..4c5fc9c9912b 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -248,7 +248,6 @@ struct nouveau_channel { /* NV50 VM */ struct nouveau_vm *vm; struct nouveau_gpuobj *vm_pd; - struct nouveau_gpuobj *vm_gart_pt; /* Objects */ struct nouveau_gpuobj *ramin; /* Private instmem */ @@ -684,6 +683,7 @@ struct drm_nouveau_private { uint64_t aper_free; struct nouveau_gpuobj *sg_ctxdma; + struct nouveau_vma vma; } gart_info; /* nv10-nv40 tiling regions */ @@ -709,8 +709,6 @@ struct drm_nouveau_private { /* G8x/G9x virtual address space */ struct nouveau_vm *chan_vm; - uint64_t vm_gart_base; - uint64_t vm_gart_size; struct nvbios vbios; diff --git a/drivers/gpu/drm/nouveau/nouveau_object.c b/drivers/gpu/drm/nouveau/nouveau_object.c index 573fd7316d63..d1bed40dc449 100644 --- a/drivers/gpu/drm/nouveau/nouveau_object.c +++ b/drivers/gpu/drm/nouveau/nouveau_object.c @@ -433,7 +433,7 @@ nv50_gpuobj_dma_init(struct nouveau_gpuobj *obj, u32 offset, int class, flags0 |= 0x00030000; break; case NV_MEM_TARGET_GART: - base += dev_priv->vm_gart_base; + base += dev_priv->gart_info.aper_base; default: flags0 &= ~0x00100000; break; @@ -801,7 +801,6 @@ nouveau_gpuobj_channel_init(struct nouveau_channel *chan, return ret; nouveau_vm_ref(dev_priv->chan_vm, &chan->vm, chan->vm_pd); - chan->vm->map_pgt(chan->vm_pd, 12, 1, dev_priv->gart_info.sg_ctxdma); } /* RAMHT */ @@ -889,7 +888,6 @@ nouveau_gpuobj_channel_takedown(struct nouveau_channel *chan) nouveau_vm_ref(NULL, &chan->vm, chan->vm_pd); nouveau_gpuobj_ref(NULL, &chan->vm_pd); - nouveau_gpuobj_ref(NULL, &chan->vm_gart_pt); if (chan->ramin_heap.free_stack.next) drm_mm_takedown(&chan->ramin_heap); diff --git a/drivers/gpu/drm/nouveau/nouveau_sgdma.c b/drivers/gpu/drm/nouveau/nouveau_sgdma.c index a0bf130b02d3..b57201ab538e 100644 --- a/drivers/gpu/drm/nouveau/nouveau_sgdma.c +++ b/drivers/gpu/drm/nouveau/nouveau_sgdma.c @@ -14,7 +14,7 @@ struct nouveau_sgdma_be { dma_addr_t *pages; unsigned nr_pages; - unsigned pte_start; + u64 offset; bool bound; }; @@ -74,18 +74,6 @@ nouveau_sgdma_clear(struct ttm_backend *be) } } -static inline unsigned -nouveau_sgdma_pte(struct drm_device *dev, uint64_t offset) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - unsigned pte = (offset >> NV_CTXDMA_PAGE_SHIFT); - - if (dev_priv->card_type < NV_50) - return pte + 2; - - return pte << 1; -} - static int nouveau_sgdma_bind(struct ttm_backend *be, struct ttm_mem_reg *mem) { @@ -97,32 +85,17 @@ nouveau_sgdma_bind(struct ttm_backend *be, struct ttm_mem_reg *mem) NV_DEBUG(dev, "pg=0x%lx\n", mem->start); - pte = nouveau_sgdma_pte(nvbe->dev, mem->start << PAGE_SHIFT); - nvbe->pte_start = pte; + nvbe->offset = mem->start << PAGE_SHIFT; + pte = (nvbe->offset >> NV_CTXDMA_PAGE_SHIFT) + 2; for (i = 0; i < nvbe->nr_pages; i++) { dma_addr_t dma_offset = nvbe->pages[i]; uint32_t offset_l = lower_32_bits(dma_offset); - uint32_t offset_h = upper_32_bits(dma_offset); - - for (j = 0; j < PAGE_SIZE / NV_CTXDMA_PAGE_SIZE; j++) { - if (dev_priv->card_type < NV_50) { - nv_wo32(gpuobj, (pte * 4) + 0, offset_l | 3); - pte += 1; - } else { - nv_wo32(gpuobj, (pte * 4) + 0, offset_l | 0x21); - nv_wo32(gpuobj, (pte * 4) + 4, offset_h & 0xff); - pte += 2; - } + for (j = 0; j < PAGE_SIZE / NV_CTXDMA_PAGE_SIZE; j++, pte++) { + nv_wo32(gpuobj, (pte * 4) + 0, offset_l | 3); dma_offset += NV_CTXDMA_PAGE_SIZE; } } - dev_priv->engine.instmem.flush(nvbe->dev); - - if (dev_priv->card_type == NV_50) { - dev_priv->engine.fifo.tlb_flush(dev); - dev_priv->engine.graph.tlb_flush(dev); - } nvbe->bound = true; return 0; @@ -142,24 +115,10 @@ nouveau_sgdma_unbind(struct ttm_backend *be) if (!nvbe->bound) return 0; - pte = nvbe->pte_start; + pte = (nvbe->offset >> NV_CTXDMA_PAGE_SHIFT) + 2; for (i = 0; i < nvbe->nr_pages; i++) { - for (j = 0; j < PAGE_SIZE / NV_CTXDMA_PAGE_SIZE; j++) { - if (dev_priv->card_type < NV_50) { - nv_wo32(gpuobj, (pte * 4) + 0, 0x00000000); - pte += 1; - } else { - nv_wo32(gpuobj, (pte * 4) + 0, 0x00000000); - nv_wo32(gpuobj, (pte * 4) + 4, 0x00000000); - pte += 2; - } - } - } - dev_priv->engine.instmem.flush(nvbe->dev); - - if (dev_priv->card_type == NV_50) { - dev_priv->engine.fifo.tlb_flush(dev); - dev_priv->engine.graph.tlb_flush(dev); + for (j = 0; j < PAGE_SIZE / NV_CTXDMA_PAGE_SIZE; j++, pte++) + nv_wo32(gpuobj, (pte * 4) + 0, 0x00000000); } nvbe->bound = false; @@ -182,6 +141,35 @@ nouveau_sgdma_destroy(struct ttm_backend *be) } } +static int +nv50_sgdma_bind(struct ttm_backend *be, struct ttm_mem_reg *mem) +{ + struct nouveau_sgdma_be *nvbe = (struct nouveau_sgdma_be *)be; + struct drm_nouveau_private *dev_priv = nvbe->dev->dev_private; + + nvbe->offset = mem->start << PAGE_SHIFT; + + nouveau_vm_map_sg(&dev_priv->gart_info.vma, nvbe->offset, + nvbe->nr_pages << PAGE_SHIFT, nvbe->pages); + nvbe->bound = true; + return 0; +} + +static int +nv50_sgdma_unbind(struct ttm_backend *be) +{ + struct nouveau_sgdma_be *nvbe = (struct nouveau_sgdma_be *)be; + struct drm_nouveau_private *dev_priv = nvbe->dev->dev_private; + + if (!nvbe->bound) + return 0; + + nouveau_vm_unmap_at(&dev_priv->gart_info.vma, nvbe->offset, + nvbe->nr_pages << PAGE_SHIFT); + nvbe->bound = false; + return 0; +} + static struct ttm_backend_func nouveau_sgdma_backend = { .populate = nouveau_sgdma_populate, .clear = nouveau_sgdma_clear, @@ -190,23 +178,30 @@ static struct ttm_backend_func nouveau_sgdma_backend = { .destroy = nouveau_sgdma_destroy }; +static struct ttm_backend_func nv50_sgdma_backend = { + .populate = nouveau_sgdma_populate, + .clear = nouveau_sgdma_clear, + .bind = nv50_sgdma_bind, + .unbind = nv50_sgdma_unbind, + .destroy = nouveau_sgdma_destroy +}; + struct ttm_backend * nouveau_sgdma_init_ttm(struct drm_device *dev) { struct drm_nouveau_private *dev_priv = dev->dev_private; struct nouveau_sgdma_be *nvbe; - if (!dev_priv->gart_info.sg_ctxdma) - return NULL; - nvbe = kzalloc(sizeof(*nvbe), GFP_KERNEL); if (!nvbe) return NULL; nvbe->dev = dev; - nvbe->backend.func = &nouveau_sgdma_backend; - + if (dev_priv->card_type < NV_50) + nvbe->backend.func = &nouveau_sgdma_backend; + else + nvbe->backend.func = &nv50_sgdma_backend; return &nvbe->backend; } @@ -226,21 +221,15 @@ nouveau_sgdma_init(struct drm_device *dev) obj_size = (aper_size >> NV_CTXDMA_PAGE_SHIFT) * 4; obj_size += 8; /* ctxdma header */ - } else { - /* 1 entire VM page table */ - aper_size = (512 * 1024 * 1024); - obj_size = (aper_size >> NV_CTXDMA_PAGE_SHIFT) * 8; - } - ret = nouveau_gpuobj_new(dev, NULL, obj_size, 16, - NVOBJ_FLAG_ZERO_ALLOC | - NVOBJ_FLAG_ZERO_FREE, &gpuobj); - if (ret) { - NV_ERROR(dev, "Error creating sgdma object: %d\n", ret); - return ret; - } + ret = nouveau_gpuobj_new(dev, NULL, obj_size, 16, + NVOBJ_FLAG_ZERO_ALLOC | + NVOBJ_FLAG_ZERO_FREE, &gpuobj); + if (ret) { + NV_ERROR(dev, "Error creating sgdma object: %d\n", ret); + return ret; + } - if (dev_priv->card_type < NV_50) { nv_wo32(gpuobj, 0, NV_CLASS_DMA_IN_MEMORY | (1 << 12) /* PT present */ | (0 << 13) /* PT *not* linear */ | @@ -249,18 +238,23 @@ nouveau_sgdma_init(struct drm_device *dev) nv_wo32(gpuobj, 4, aper_size - 1); for (i = 2; i < 2 + (aper_size >> 12); i++) nv_wo32(gpuobj, i * 4, 0x00000000); - } else { - for (i = 0; i < obj_size; i += 8) { - nv_wo32(gpuobj, i + 0, 0x00000000); - nv_wo32(gpuobj, i + 4, 0x00000000); - } + + dev_priv->gart_info.sg_ctxdma = gpuobj; + dev_priv->gart_info.aper_base = 0; + dev_priv->gart_info.aper_size = aper_size; + } else + if (dev_priv->chan_vm) { + ret = nouveau_vm_get(dev_priv->chan_vm, 512 * 1024 * 1024, + 12, NV_MEM_ACCESS_RW, + &dev_priv->gart_info.vma); + if (ret) + return ret; + + dev_priv->gart_info.aper_base = dev_priv->gart_info.vma.offset; + dev_priv->gart_info.aper_size = 512 * 1024 * 1024; } - dev_priv->engine.instmem.flush(dev); dev_priv->gart_info.type = NOUVEAU_GART_SGDMA; - dev_priv->gart_info.aper_base = 0; - dev_priv->gart_info.aper_size = aper_size; - dev_priv->gart_info.sg_ctxdma = gpuobj; return 0; } @@ -270,6 +264,7 @@ nouveau_sgdma_takedown(struct drm_device *dev) struct drm_nouveau_private *dev_priv = dev->dev_private; nouveau_gpuobj_ref(NULL, &dev_priv->gart_info.sg_ctxdma); + nouveau_vm_put(&dev_priv->gart_info.vma); } int diff --git a/drivers/gpu/drm/nouveau/nv50_instmem.c b/drivers/gpu/drm/nouveau/nv50_instmem.c index 08202fd682e4..ec102bda8446 100644 --- a/drivers/gpu/drm/nouveau/nv50_instmem.c +++ b/drivers/gpu/drm/nouveau/nv50_instmem.c @@ -131,7 +131,6 @@ nv50_instmem_init(struct drm_device *dev) struct nouveau_channel *chan; struct nouveau_vm *vm; int ret, i; - u64 nongart_o; u32 tmp; priv = kzalloc(sizeof(*priv), GFP_KERNEL); @@ -216,15 +215,10 @@ nv50_instmem_init(struct drm_device *dev) for (i = 0; i < 8; i++) nv_wr32(dev, 0x1900 + (i*4), 0); - /* Create shared channel VM, space is reserved for GART mappings at - * the beginning of this address space, it's managed separately - * because TTM makes life painful + /* Create shared channel VM, space is reserved at the beginning + * to catch "NULL pointer" references */ - dev_priv->vm_gart_base = 0x0020000000ULL; - dev_priv->vm_gart_size = 512 * 1024 * 1024; - nongart_o = dev_priv->vm_gart_base + dev_priv->vm_gart_size; - - ret = nouveau_vm_new(dev, 0, (1ULL << 40), nongart_o, + ret = nouveau_vm_new(dev, 0, (1ULL << 40), 0x0020000000ULL, 29, 12, 16, &dev_priv->chan_vm); if (ret) return ret; -- cgit v1.2.3 From 34cf01bc4b8021cef62cbd79224577c13d01b106 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 22 Nov 2010 10:48:51 +1000 Subject: drm/nouveau: allow gpuobj vinst to be a virtual address when necessary Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_drv.h | 1 + drivers/gpu/drm/nouveau/nv50_instmem.c | 25 +++++++++++++++++++++++-- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index 4c5fc9c9912b..2cd87e6b54b7 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -158,6 +158,7 @@ enum nouveau_flags { #define NVOBJ_FLAG_DONT_MAP (1 << 0) #define NVOBJ_FLAG_ZERO_ALLOC (1 << 1) #define NVOBJ_FLAG_ZERO_FREE (1 << 2) +#define NVOBJ_FLAG_VM (1 << 3) #define NVOBJ_CINST_GLOBAL 0xdeadbeef diff --git a/drivers/gpu/drm/nouveau/nv50_instmem.c b/drivers/gpu/drm/nouveau/nv50_instmem.c index ec102bda8446..e2efd6f22ffb 100644 --- a/drivers/gpu/drm/nouveau/nv50_instmem.c +++ b/drivers/gpu/drm/nouveau/nv50_instmem.c @@ -302,6 +302,7 @@ nv50_instmem_resume(struct drm_device *dev) struct nv50_gpuobj_node { struct nouveau_vram *vram; + struct nouveau_vma chan_vma; u32 align; }; @@ -310,6 +311,7 @@ int nv50_instmem_get(struct nouveau_gpuobj *gpuobj, u32 size, u32 align) { struct drm_device *dev = gpuobj->dev; + struct drm_nouveau_private *dev_priv = dev->dev_private; struct nv50_gpuobj_node *node = NULL; int ret; @@ -328,8 +330,23 @@ nv50_instmem_get(struct nouveau_gpuobj *gpuobj, u32 size, u32 align) } gpuobj->vinst = node->vram->offset; - gpuobj->size = size; - gpuobj->node = node; + + if (gpuobj->flags & NVOBJ_FLAG_VM) { + ret = nouveau_vm_get(dev_priv->chan_vm, size, 12, + NV_MEM_ACCESS_RW | NV_MEM_ACCESS_SYS, + &node->chan_vma); + if (ret) { + nv50_vram_del(dev, &node->vram); + kfree(node); + return ret; + } + + nouveau_vm_map(&node->chan_vma, node->vram); + gpuobj->vinst = node->chan_vma.offset; + } + + gpuobj->size = size; + gpuobj->node = node; return 0; } @@ -342,6 +359,10 @@ nv50_instmem_put(struct nouveau_gpuobj *gpuobj) node = gpuobj->node; gpuobj->node = NULL; + if (node->chan_vma.node) { + nouveau_vm_unmap(&node->chan_vma); + nouveau_vm_put(&node->chan_vma); + } nv50_vram_del(dev, &node->vram); kfree(node); } -- cgit v1.2.3 From 60d2a88ae896ae51c76f8b15c2f4b762d5b00864 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 6 Dec 2010 15:28:54 +1000 Subject: drm/nouveau: kick vram functions out into an "engine" NVC0 will be able to share some of nv50's paths this way. This also makes it the card-specific vram code responsible for deciding if a given set of tile_flags is valid, rather than duplicating the allowed types in nv50_vram.c and nouveau_gem.c Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_drv.h | 12 +++++++++ drivers/gpu/drm/nouveau/nouveau_gem.c | 30 +++------------------ drivers/gpu/drm/nouveau/nouveau_mem.c | 47 ++++++++++++++++++--------------- drivers/gpu/drm/nouveau/nouveau_mm.h | 1 + drivers/gpu/drm/nouveau/nouveau_state.c | 16 +++++++++++ drivers/gpu/drm/nouveau/nv50_instmem.c | 9 ++++--- drivers/gpu/drm/nouveau/nv50_vram.c | 10 +++++++ 7 files changed, 74 insertions(+), 51 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index 2cd87e6b54b7..f8931b2d129b 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -501,6 +501,15 @@ struct nouveau_crypt_engine { void (*tlb_flush)(struct drm_device *dev); }; +struct nouveau_vram_engine { + int (*init)(struct drm_device *); + int (*get)(struct drm_device *, u64, u32 align, u32 size_nc, + u32 type, struct nouveau_vram **); + void (*put)(struct drm_device *, struct nouveau_vram **); + + bool (*flags_valid)(struct drm_device *, u32 tile_flags); +}; + struct nouveau_engine { struct nouveau_instmem_engine instmem; struct nouveau_mc_engine mc; @@ -512,6 +521,7 @@ struct nouveau_engine { struct nouveau_gpio_engine gpio; struct nouveau_pm_engine pm; struct nouveau_crypt_engine crypt; + struct nouveau_vram_engine vram; }; struct nouveau_pll_vals { @@ -821,6 +831,8 @@ extern void nouveau_mem_gart_fini(struct drm_device *); extern int nouveau_mem_init_agp(struct drm_device *); extern int nouveau_mem_reset_agp(struct drm_device *); extern void nouveau_mem_close(struct drm_device *); +extern int nouveau_mem_detect(struct drm_device *); +extern bool nouveau_mem_flags_valid(struct drm_device *, u32 tile_flags); extern struct nouveau_tile_reg *nv10_mem_set_tiling( struct drm_device *dev, uint32_t addr, uint32_t size, uint32_t pitch, uint32_t flags); diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c index 0adb2a85c143..506c508b7eda 100644 --- a/drivers/gpu/drm/nouveau/nouveau_gem.c +++ b/drivers/gpu/drm/nouveau/nouveau_gem.c @@ -103,32 +103,6 @@ nouveau_gem_info(struct drm_gem_object *gem, struct drm_nouveau_gem_info *rep) return 0; } -static bool -nouveau_gem_tile_flags_valid(struct drm_device *dev, uint32_t tile_flags) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - - if (dev_priv->card_type >= NV_50) { - switch (tile_flags & NOUVEAU_GEM_TILE_LAYOUT_MASK) { - case 0x0000: - case 0x1800: - case 0x2800: - case 0x4800: - case 0x7000: - case 0x7400: - case 0x7a00: - case 0xe000: - return true; - } - } else { - if (!(tile_flags & NOUVEAU_GEM_TILE_LAYOUT_MASK)) - return true; - } - - NV_ERROR(dev, "bad page flags: 0x%08x\n", tile_flags); - return false; -} - int nouveau_gem_ioctl_new(struct drm_device *dev, void *data, struct drm_file *file_priv) @@ -150,8 +124,10 @@ nouveau_gem_ioctl_new(struct drm_device *dev, void *data, if (!flags || req->info.domain & NOUVEAU_GEM_DOMAIN_CPU) flags |= TTM_PL_FLAG_SYSTEM; - if (!nouveau_gem_tile_flags_valid(dev, req->info.tile_flags)) + if (!dev_priv->engine.vram.flags_valid(dev, req->info.tile_flags)) { + NV_ERROR(dev, "bad page flags: 0x%08x\n", req->info.tile_flags); return -EINVAL; + } if (req->channel_hint) { chan = nouveau_channel_get(dev, file_priv, req->channel_hint); diff --git a/drivers/gpu/drm/nouveau/nouveau_mem.c b/drivers/gpu/drm/nouveau/nouveau_mem.c index 5a1809480388..224181193a1f 100644 --- a/drivers/gpu/drm/nouveau/nouveau_mem.c +++ b/drivers/gpu/drm/nouveau/nouveau_mem.c @@ -241,7 +241,7 @@ nouveau_mem_detect_nforce(struct drm_device *dev) return 0; } -static int +int nouveau_mem_detect(struct drm_device *dev) { struct drm_nouveau_private *dev_priv = dev->dev_private; @@ -255,26 +255,25 @@ nouveau_mem_detect(struct drm_device *dev) if (dev_priv->card_type < NV_50) { dev_priv->vram_size = nv_rd32(dev, NV04_PFB_FIFO_DATA); dev_priv->vram_size &= NV10_PFB_FIFO_DATA_RAM_AMOUNT_MB_MASK; - } else - if (dev_priv->card_type < NV_C0) { - if (nv50_vram_init(dev)) - return -ENOMEM; } else { dev_priv->vram_size = nv_rd32(dev, 0x10f20c) << 20; dev_priv->vram_size *= nv_rd32(dev, 0x121c74); } - NV_INFO(dev, "Detected %dMiB VRAM\n", (int)(dev_priv->vram_size >> 20)); - if (dev_priv->vram_sys_base) { - NV_INFO(dev, "Stolen system memory at: 0x%010llx\n", - dev_priv->vram_sys_base); - } - if (dev_priv->vram_size) return 0; return -ENOMEM; } +bool +nouveau_mem_flags_valid(struct drm_device *dev, u32 tile_flags) +{ + if (!(tile_flags & NOUVEAU_GEM_TILE_LAYOUT_MASK)) + return true; + + return false; +} + #if __OS_HAS_AGP static unsigned long get_agp_mode(struct drm_device *dev, unsigned long mode) @@ -432,11 +431,16 @@ nouveau_mem_vram_init(struct drm_device *dev) else dev_priv->ramin_rsvd_vram = (512 * 1024); - /* initialise gpu-specific vram backend */ - ret = nouveau_mem_detect(dev); + ret = dev_priv->engine.vram.init(dev); if (ret) return ret; + NV_INFO(dev, "Detected %dMiB VRAM\n", (int)(dev_priv->vram_size >> 20)); + if (dev_priv->vram_sys_base) { + NV_INFO(dev, "Stolen system memory at: 0x%010llx\n", + dev_priv->vram_sys_base); + } + dev_priv->fb_available_size = dev_priv->vram_size; dev_priv->fb_mappable_pages = dev_priv->fb_available_size; if (dev_priv->fb_mappable_pages > pci_resource_len(dev->pdev, 1)) @@ -698,9 +702,10 @@ nouveau_vram_manager_del(struct ttm_mem_type_manager *man, struct ttm_mem_reg *mem) { struct drm_nouveau_private *dev_priv = nouveau_bdev(man->bdev); + struct nouveau_vram_engine *vram = &dev_priv->engine.vram; struct drm_device *dev = dev_priv->dev; - nv50_vram_del(dev, (struct nouveau_vram **)&mem->mm_node); + vram->put(dev, (struct nouveau_vram **)&mem->mm_node); } static int @@ -710,30 +715,30 @@ nouveau_vram_manager_new(struct ttm_mem_type_manager *man, struct ttm_mem_reg *mem) { struct drm_nouveau_private *dev_priv = nouveau_bdev(man->bdev); + struct nouveau_vram_engine *vram = &dev_priv->engine.vram; struct drm_device *dev = dev_priv->dev; struct nouveau_bo *nvbo = nouveau_bo(bo); - struct nouveau_vram *vram; + struct nouveau_vram *node; u32 size_nc = 0; int ret; if (nvbo->tile_flags & NOUVEAU_GEM_TILE_NONCONTIG) size_nc = 1 << nvbo->vma.node->type; - ret = nv50_vram_new(dev, mem->num_pages << PAGE_SHIFT, - mem->page_alignment << PAGE_SHIFT, size_nc, - (nvbo->tile_flags >> 8) & 0x7f, &vram); + ret = vram->get(dev, mem->num_pages << PAGE_SHIFT, + mem->page_alignment << PAGE_SHIFT, size_nc, + (nvbo->tile_flags >> 8) & 0xff, &node); if (ret) return ret; - mem->mm_node = vram; - mem->start = vram->offset >> PAGE_SHIFT; + mem->mm_node = node; + mem->start = node->offset >> PAGE_SHIFT; return 0; } void nouveau_vram_manager_debug(struct ttm_mem_type_manager *man, const char *prefix) { - struct ttm_bo_global *glob = man->bdev->glob; struct nouveau_mm *mm = man->priv; struct nouveau_mm_node *r; u64 total = 0, ttotal[3] = {}, tused[3] = {}, tfree[3] = {}; diff --git a/drivers/gpu/drm/nouveau/nouveau_mm.h b/drivers/gpu/drm/nouveau/nouveau_mm.h index 7e8f8bd86d47..250e642de0a7 100644 --- a/drivers/gpu/drm/nouveau/nouveau_mm.h +++ b/drivers/gpu/drm/nouveau/nouveau_mm.h @@ -57,5 +57,6 @@ int nv50_vram_init(struct drm_device *); int nv50_vram_new(struct drm_device *, u64 size, u32 align, u32 size_nc, u32 memtype, struct nouveau_vram **); void nv50_vram_del(struct drm_device *, struct nouveau_vram **); +bool nv50_vram_flags_valid(struct drm_device *, u32 tile_flags); #endif diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c index e0811f93243d..8eac943e8fd2 100644 --- a/drivers/gpu/drm/nouveau/nouveau_state.c +++ b/drivers/gpu/drm/nouveau/nouveau_state.c @@ -100,6 +100,8 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->pm.clock_set = nv04_pm_clock_set; engine->crypt.init = nouveau_stub_init; engine->crypt.takedown = nouveau_stub_takedown; + engine->vram.init = nouveau_mem_detect; + engine->vram.flags_valid = nouveau_mem_flags_valid; break; case 0x10: engine->instmem.init = nv04_instmem_init; @@ -157,6 +159,8 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->pm.clock_set = nv04_pm_clock_set; engine->crypt.init = nouveau_stub_init; engine->crypt.takedown = nouveau_stub_takedown; + engine->vram.init = nouveau_mem_detect; + engine->vram.flags_valid = nouveau_mem_flags_valid; break; case 0x20: engine->instmem.init = nv04_instmem_init; @@ -214,6 +218,8 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->pm.clock_set = nv04_pm_clock_set; engine->crypt.init = nouveau_stub_init; engine->crypt.takedown = nouveau_stub_takedown; + engine->vram.init = nouveau_mem_detect; + engine->vram.flags_valid = nouveau_mem_flags_valid; break; case 0x30: engine->instmem.init = nv04_instmem_init; @@ -273,6 +279,8 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->pm.voltage_set = nouveau_voltage_gpio_set; engine->crypt.init = nouveau_stub_init; engine->crypt.takedown = nouveau_stub_takedown; + engine->vram.init = nouveau_mem_detect; + engine->vram.flags_valid = nouveau_mem_flags_valid; break; case 0x40: case 0x60: @@ -334,6 +342,8 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->pm.temp_get = nv40_temp_get; engine->crypt.init = nouveau_stub_init; engine->crypt.takedown = nouveau_stub_takedown; + engine->vram.init = nouveau_mem_detect; + engine->vram.flags_valid = nouveau_mem_flags_valid; break; case 0x50: case 0x80: /* gotta love NVIDIA's consistency.. */ @@ -444,6 +454,10 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->crypt.takedown = nouveau_stub_takedown; break; } + engine->vram.init = nv50_vram_init; + engine->vram.get = nv50_vram_new; + engine->vram.put = nv50_vram_del; + engine->vram.flags_valid = nv50_vram_flags_valid; break; case 0xC0: engine->instmem.init = nvc0_instmem_init; @@ -495,6 +509,8 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->gpio.irq_enable = nv50_gpio_irq_enable; engine->crypt.init = nouveau_stub_init; engine->crypt.takedown = nouveau_stub_takedown; + engine->vram.init = nouveau_mem_detect; + engine->vram.flags_valid = nouveau_mem_flags_valid; break; default: NV_ERROR(dev, "NV%02x unsupported\n", dev_priv->chipset); diff --git a/drivers/gpu/drm/nouveau/nv50_instmem.c b/drivers/gpu/drm/nouveau/nv50_instmem.c index e2efd6f22ffb..38f30270cb9f 100644 --- a/drivers/gpu/drm/nouveau/nv50_instmem.c +++ b/drivers/gpu/drm/nouveau/nv50_instmem.c @@ -312,6 +312,7 @@ nv50_instmem_get(struct nouveau_gpuobj *gpuobj, u32 size, u32 align) { struct drm_device *dev = gpuobj->dev; struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_vram_engine *vram = &dev_priv->engine.vram; struct nv50_gpuobj_node *node = NULL; int ret; @@ -323,7 +324,7 @@ nv50_instmem_get(struct nouveau_gpuobj *gpuobj, u32 size, u32 align) size = (size + 4095) & ~4095; align = max(align, (u32)4096); - ret = nv50_vram_new(dev, size, align, 0, 0, &node->vram); + ret = vram->get(dev, size, align, 0, 0, &node->vram); if (ret) { kfree(node); return ret; @@ -336,7 +337,7 @@ nv50_instmem_get(struct nouveau_gpuobj *gpuobj, u32 size, u32 align) NV_MEM_ACCESS_RW | NV_MEM_ACCESS_SYS, &node->chan_vma); if (ret) { - nv50_vram_del(dev, &node->vram); + vram->put(dev, &node->vram); kfree(node); return ret; } @@ -354,6 +355,8 @@ void nv50_instmem_put(struct nouveau_gpuobj *gpuobj) { struct drm_device *dev = gpuobj->dev; + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_vram_engine *vram = &dev_priv->engine.vram; struct nv50_gpuobj_node *node; node = gpuobj->node; @@ -363,7 +366,7 @@ nv50_instmem_put(struct nouveau_gpuobj *gpuobj) nouveau_vm_unmap(&node->chan_vma); nouveau_vm_put(&node->chan_vma); } - nv50_vram_del(dev, &node->vram); + vram->put(dev, &node->vram); kfree(node); } diff --git a/drivers/gpu/drm/nouveau/nv50_vram.c b/drivers/gpu/drm/nouveau/nv50_vram.c index 6e753356cd94..47489ed0a5a8 100644 --- a/drivers/gpu/drm/nouveau/nv50_vram.c +++ b/drivers/gpu/drm/nouveau/nv50_vram.c @@ -37,6 +37,16 @@ static int types[0x80] = { 1, 0, 2, 0, 1, 0, 2, 0, 1, 1, 2, 2, 1, 1, 0, 0 }; +bool +nv50_vram_flags_valid(struct drm_device *dev, u32 tile_flags) +{ + int type = (tile_flags & NOUVEAU_GEM_TILE_LAYOUT_MASK) >> 8; + + if (likely(type < sizeof(types) && types[type])) + return true; + return false; +} + void nv50_vram_del(struct drm_device *dev, struct nouveau_vram **pvram) { -- cgit v1.2.3 From fd70b6cd780742b97f525415bf5e4fb24a4bb6d8 Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Wed, 8 Dec 2010 02:37:12 +0100 Subject: drm/nv04-nv40: Fix up PCI(E) GART DMA object bus address calculation. Signed-off-by: Francisco Jerez Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_drv.h | 4 ++-- drivers/gpu/drm/nouveau/nouveau_object.c | 8 ++------ drivers/gpu/drm/nouveau/nouveau_sgdma.c | 16 ++++++---------- 3 files changed, 10 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index f8931b2d129b..8f13906185b2 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -934,8 +934,8 @@ extern void nouveau_irq_uninstall(struct drm_device *); /* nouveau_sgdma.c */ extern int nouveau_sgdma_init(struct drm_device *); extern void nouveau_sgdma_takedown(struct drm_device *); -extern int nouveau_sgdma_get_page(struct drm_device *, uint32_t offset, - uint32_t *page); +extern uint32_t nouveau_sgdma_get_physical(struct drm_device *, + uint32_t offset); extern struct ttm_backend *nouveau_sgdma_init_ttm(struct drm_device *); /* nouveau_debugfs.c */ diff --git a/drivers/gpu/drm/nouveau/nouveau_object.c b/drivers/gpu/drm/nouveau/nouveau_object.c index d1bed40dc449..55c9fdcfa67f 100644 --- a/drivers/gpu/drm/nouveau/nouveau_object.c +++ b/drivers/gpu/drm/nouveau/nouveau_object.c @@ -478,7 +478,7 @@ nouveau_gpuobj_dma_new(struct nouveau_channel *chan, int class, u64 base, struct drm_nouveau_private *dev_priv = chan->dev->dev_private; struct drm_device *dev = chan->dev; struct nouveau_gpuobj *obj; - u32 page_addr, flags0, flags2; + u32 flags0, flags2; int ret; if (dev_priv->card_type >= NV_50) { @@ -495,12 +495,8 @@ nouveau_gpuobj_dma_new(struct nouveau_channel *chan, int class, u64 base, base += dev_priv->gart_info.aper_base; } else if (base != 0) { - ret = nouveau_sgdma_get_page(dev, base, &page_addr); - if (ret) - return ret; - + base = nouveau_sgdma_get_physical(dev, base); target = NV_MEM_TARGET_PCI; - base = page_addr; } else { nouveau_gpuobj_ref(dev_priv->gart_info.sg_ctxdma, pobj); return 0; diff --git a/drivers/gpu/drm/nouveau/nouveau_sgdma.c b/drivers/gpu/drm/nouveau/nouveau_sgdma.c index b57201ab538e..9a250eb53098 100644 --- a/drivers/gpu/drm/nouveau/nouveau_sgdma.c +++ b/drivers/gpu/drm/nouveau/nouveau_sgdma.c @@ -267,19 +267,15 @@ nouveau_sgdma_takedown(struct drm_device *dev) nouveau_vm_put(&dev_priv->gart_info.vma); } -int -nouveau_sgdma_get_page(struct drm_device *dev, uint32_t offset, uint32_t *page) +uint32_t +nouveau_sgdma_get_physical(struct drm_device *dev, uint32_t offset) { struct drm_nouveau_private *dev_priv = dev->dev_private; struct nouveau_gpuobj *gpuobj = dev_priv->gart_info.sg_ctxdma; - int pte; + int pte = (offset >> NV_CTXDMA_PAGE_SHIFT) + 2; - pte = (offset >> NV_CTXDMA_PAGE_SHIFT) << 2; - if (dev_priv->card_type < NV_50) { - *page = nv_ro32(gpuobj, (pte + 8)) & ~NV_CTXDMA_PAGE_MASK; - return 0; - } + BUG_ON(dev_priv->card_type >= NV_50); - NV_ERROR(dev, "Unimplemented on NV50\n"); - return -EINVAL; + return (nv_ro32(gpuobj, 4 * pte) & ~NV_CTXDMA_PAGE_MASK) | + (offset & NV_CTXDMA_PAGE_MASK); } -- cgit v1.2.3 From 6f107b5861ecb09abfa7e2f9927e3884d1d81f91 Mon Sep 17 00:00:00 2001 From: Miloslav TrmaÄ Date: Wed, 8 Dec 2010 14:35:34 +0800 Subject: net: Add missing lockdep class names for af_alg MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Miloslav TrmaÄ Signed-off-by: Herbert Xu --- net/core/sock.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/net/core/sock.c b/net/core/sock.c index 3eed5424e659..634d5bc409bb 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -157,7 +157,7 @@ static const char *const af_family_key_strings[AF_MAX+1] = { "sk_lock-27" , "sk_lock-28" , "sk_lock-AF_CAN" , "sk_lock-AF_TIPC" , "sk_lock-AF_BLUETOOTH", "sk_lock-IUCV" , "sk_lock-AF_RXRPC" , "sk_lock-AF_ISDN" , "sk_lock-AF_PHONET" , - "sk_lock-AF_IEEE802154", "sk_lock-AF_CAIF" , + "sk_lock-AF_IEEE802154", "sk_lock-AF_CAIF" , "sk_lock-AF_ALG" , "sk_lock-AF_MAX" }; static const char *const af_family_slock_key_strings[AF_MAX+1] = { @@ -173,7 +173,7 @@ static const char *const af_family_slock_key_strings[AF_MAX+1] = { "slock-27" , "slock-28" , "slock-AF_CAN" , "slock-AF_TIPC" , "slock-AF_BLUETOOTH", "slock-AF_IUCV" , "slock-AF_RXRPC" , "slock-AF_ISDN" , "slock-AF_PHONET" , - "slock-AF_IEEE802154", "slock-AF_CAIF" , + "slock-AF_IEEE802154", "slock-AF_CAIF" , "slock-AF_ALG" , "slock-AF_MAX" }; static const char *const af_family_clock_key_strings[AF_MAX+1] = { @@ -189,7 +189,7 @@ static const char *const af_family_clock_key_strings[AF_MAX+1] = { "clock-27" , "clock-28" , "clock-AF_CAN" , "clock-AF_TIPC" , "clock-AF_BLUETOOTH", "clock-AF_IUCV" , "clock-AF_RXRPC" , "clock-AF_ISDN" , "clock-AF_PHONET" , - "clock-AF_IEEE802154", "clock-AF_CAIF" , + "clock-AF_IEEE802154", "clock-AF_CAIF" , "clock-AF_ALG" , "clock-AF_MAX" }; -- cgit v1.2.3 From 507cad355fc9e426f2846c46a4edca2d22d25f44 Mon Sep 17 00:00:00 2001 From: Miloslav TrmaÄ Date: Wed, 8 Dec 2010 14:36:19 +0800 Subject: crypto: af_alg - Make sure sk_security is initialized on accept()ed sockets MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Miloslav TrmaÄ Signed-off-by: Herbert Xu --- crypto/af_alg.c | 1 + 1 file changed, 1 insertion(+) diff --git a/crypto/af_alg.c b/crypto/af_alg.c index cabed0e9c9d8..bd9e53c78026 100644 --- a/crypto/af_alg.c +++ b/crypto/af_alg.c @@ -242,6 +242,7 @@ int af_alg_accept(struct sock *sk, struct socket *newsock) goto unlock; sock_init_data(newsock, sk2); + sock_graft(sk2, newsock); err = type->accept(ask->private, sk2); if (err) { -- cgit v1.2.3 From 9f843706bb87837b823228467f4f83973fd110e9 Mon Sep 17 00:00:00 2001 From: Simon Horman Date: Mon, 6 Dec 2010 00:12:44 +0000 Subject: mmc, sh: Move MMCIF_PROGRESS_* into sh_mmcif.h Allow MMCIF_PROGRESS_* to be shared. Cc: Magnus Damm Signed-off-by: Simon Horman Signed-off-by: Paul Mundt --- arch/sh/boot/romimage/mmcif-sh7724.c | 3 --- include/linux/mmc/sh_mmcif.h | 3 +++ 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/sh/boot/romimage/mmcif-sh7724.c b/arch/sh/boot/romimage/mmcif-sh7724.c index 14863d7292cb..16b9c6fa7ded 100644 --- a/arch/sh/boot/romimage/mmcif-sh7724.c +++ b/arch/sh/boot/romimage/mmcif-sh7724.c @@ -21,9 +21,6 @@ #define HIZCRC 0xa405015c #define DRVCRA 0xa405018a -enum { MMCIF_PROGRESS_ENTER, MMCIF_PROGRESS_INIT, - MMCIF_PROGRESS_LOAD, MMCIF_PROGRESS_DONE }; - /* SH7724 specific MMCIF loader * * loads the romImage from an MMC card starting from block 512 diff --git a/include/linux/mmc/sh_mmcif.h b/include/linux/mmc/sh_mmcif.h index ffabf8c0a531..6a98e97c49f8 100644 --- a/include/linux/mmc/sh_mmcif.h +++ b/include/linux/mmc/sh_mmcif.h @@ -97,6 +97,9 @@ static inline void sh_mmcif_writel(void __iomem *addr, int reg, u32 val) #define SH_MMCIF_BBS 512 /* boot block size */ +enum { MMCIF_PROGRESS_ENTER, MMCIF_PROGRESS_INIT, + MMCIF_PROGRESS_LOAD, MMCIF_PROGRESS_DONE }; + static inline void sh_mmcif_boot_cmd_send(void __iomem *base, unsigned long cmd, unsigned long arg) { -- cgit v1.2.3 From 54b384634f7083bcacf9a9ed2e6f4c3d0a246e49 Mon Sep 17 00:00:00 2001 From: Simon Horman Date: Mon, 6 Dec 2010 00:12:45 +0000 Subject: mmc, sh: Remove sh_mmcif_boot_slurp() As the only caller of sh_mmcif_boot_do_read() is sh_mmcif_boot_slurp() the configuration portion of sh_mmcif_boot_slurp() can be merged into sh_mmcif_boot_do_read(). Once this is done sh_mmcif_boot_slurp() is only a call to sh_mmcif_boot_do_read() with platform specific information - the offset that images are stored on MMC. So make the sh_mmcif_boot_do_read() call directly from platform code and remove sh_mmcif_boot_slurp() altogether. Cc: Magnus Damm Signed-off-by: Simon Horman Signed-off-by: Paul Mundt --- arch/sh/boot/romimage/mmcif-sh7724.c | 4 +++- include/linux/mmc/sh_mmcif.h | 34 +++++++++++----------------------- 2 files changed, 14 insertions(+), 24 deletions(-) diff --git a/arch/sh/boot/romimage/mmcif-sh7724.c b/arch/sh/boot/romimage/mmcif-sh7724.c index 16b9c6fa7ded..c84e7831018d 100644 --- a/arch/sh/boot/romimage/mmcif-sh7724.c +++ b/arch/sh/boot/romimage/mmcif-sh7724.c @@ -60,7 +60,9 @@ asmlinkage void mmcif_loader(unsigned char *buf, unsigned long no_bytes) mmcif_update_progress(MMCIF_PROGRESS_LOAD); /* load kernel via MMCIF interface */ - sh_mmcif_boot_slurp(MMCIF_BASE, buf, no_bytes); + sh_mmcif_boot_do_read(MMCIF_BASE, 512, + (no_bytes + SH_MMCIF_BBS - 1) / SH_MMCIF_BBS, + buf); /* disable clock to the MMCIF hardware block */ __raw_writel(__raw_readl(MSTPCR2) | 0x20000000, MSTPCR2); diff --git a/include/linux/mmc/sh_mmcif.h b/include/linux/mmc/sh_mmcif.h index 6a98e97c49f8..cfcc6e320e2f 100644 --- a/include/linux/mmc/sh_mmcif.h +++ b/include/linux/mmc/sh_mmcif.h @@ -162,6 +162,17 @@ static inline int sh_mmcif_boot_do_read(void __iomem *base, unsigned long k; int ret = 0; + /* In data transfer mode: Set clock to Bus clock/4 (about 20Mhz) */ + sh_mmcif_writel(base, MMCIF_CE_CLK_CTRL, + CLK_ENABLE | CLKDIV_4 | SRSPTO_256 | + SRBSYTO_29 | SRWDTO_29 | SCCSTO_29); + + /* CMD9 - Get CSD */ + sh_mmcif_boot_cmd(base, 0x09806000, 0x00010000); + + /* CMD7 - Select the card */ + sh_mmcif_boot_cmd(base, 0x07400000, 0x00010000); + /* CMD16 - Set the block size */ sh_mmcif_boot_cmd(base, 0x10400000, SH_MMCIF_BBS); @@ -205,27 +216,4 @@ static inline void sh_mmcif_boot_init(void __iomem *base) sh_mmcif_boot_cmd(base, 0x03400040, 0x00010000); } -static inline void sh_mmcif_boot_slurp(void __iomem *base, - unsigned char *buf, - unsigned long no_bytes) -{ - unsigned long tmp; - - /* In data transfer mode: Set clock to Bus clock/4 (about 20Mhz) */ - sh_mmcif_writel(base, MMCIF_CE_CLK_CTRL, - CLK_ENABLE | CLKDIV_4 | SRSPTO_256 | - SRBSYTO_29 | SRWDTO_29 | SCCSTO_29); - - /* CMD9 - Get CSD */ - sh_mmcif_boot_cmd(base, 0x09806000, 0x00010000); - - /* CMD7 - Select the card */ - sh_mmcif_boot_cmd(base, 0x07400000, 0x00010000); - - tmp = no_bytes / SH_MMCIF_BBS; - tmp += (no_bytes % SH_MMCIF_BBS) ? 1 : 0; - - sh_mmcif_boot_do_read(base, 512, tmp, buf); -} - #endif /* __SH_MMCIF_H__ */ -- cgit v1.2.3 From 116dcde638065a6b94344ca570e1e79c8e857826 Mon Sep 17 00:00:00 2001 From: David Henningsson Date: Tue, 23 Nov 2010 10:23:40 +0100 Subject: ALSA: HDA: Remove unconnected PCM devices for Intel HDMI Some newer chips have more than one HDMI output, but usually not all of them are exposed as physical jacks. Removing the unused PCM devices (as indicated by BIOS in the pin config default) will reduce user confusion as they currently have to choose between several HDMI devices, some of them not working anyway. Signed-off-by: David Henningsson Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_hdmi.c | 41 ++++++++++++++++++++++++++++++++--------- 1 file changed, 32 insertions(+), 9 deletions(-) diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index 8f07719ef985..d1b1b5796c98 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c @@ -904,23 +904,28 @@ static int hdmi_add_pin(struct hda_codec *codec, hda_nid_t pin_nid) spec->pin[spec->num_pins] = pin_nid; spec->num_pins++; - /* - * It is assumed that converter nodes come first in the node list and - * hence have been registered and usable now. - */ return hdmi_read_pin_conn(codec, pin_nid); } static int hdmi_add_cvt(struct hda_codec *codec, hda_nid_t nid) { + int i, found_pin = 0; struct hdmi_spec *spec = codec->spec; - if (spec->num_cvts >= MAX_HDMI_CVTS) { - snd_printk(KERN_WARNING - "HDMI: no space for converter %d\n", nid); - return -E2BIG; + for (i = 0; i < spec->num_pins; i++) + if (nid == spec->pin_cvt[i]) { + found_pin = 1; + break; + } + + if (!found_pin) { + snd_printdd("HDMI: Skipping node %d (no connection)\n", nid); + return -EINVAL; } + if (snd_BUG_ON(spec->num_cvts >= MAX_HDMI_CVTS)) + return -E2BIG; + spec->cvt[spec->num_cvts] = nid; spec->num_cvts++; @@ -931,6 +936,8 @@ static int hdmi_parse_codec(struct hda_codec *codec) { hda_nid_t nid; int i, nodes; + int num_tmp_cvts = 0; + hda_nid_t tmp_cvt[MAX_HDMI_CVTS]; nodes = snd_hda_get_sub_nodes(codec, codec->afg, &nid); if (!nid || nodes < 0) { @@ -941,6 +948,7 @@ static int hdmi_parse_codec(struct hda_codec *codec) for (i = 0; i < nodes; i++, nid++) { unsigned int caps; unsigned int type; + unsigned int config; caps = snd_hda_param_read(codec, nid, AC_PAR_AUDIO_WIDGET_CAP); type = get_wcaps_type(caps); @@ -950,17 +958,32 @@ static int hdmi_parse_codec(struct hda_codec *codec) switch (type) { case AC_WID_AUD_OUT: - hdmi_add_cvt(codec, nid); + if (num_tmp_cvts >= MAX_HDMI_CVTS) { + snd_printk(KERN_WARNING + "HDMI: no space for converter %d\n", nid); + continue; + } + tmp_cvt[num_tmp_cvts] = nid; + num_tmp_cvts++; break; case AC_WID_PIN: caps = snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP); if (!(caps & (AC_PINCAP_HDMI | AC_PINCAP_DP))) continue; + + config = snd_hda_codec_read(codec, nid, 0, + AC_VERB_GET_CONFIG_DEFAULT, 0); + if (get_defcfg_connect(config) == AC_JACK_PORT_NONE) + continue; + hdmi_add_pin(codec, nid); break; } } + for (i = 0; i < num_tmp_cvts; i++) + hdmi_add_cvt(codec, tmp_cvt[i]); + /* * G45/IbexPeak don't support EPSS: the unsolicited pin hot plug event * can be lost and presence sense verb will become inaccurate if the -- cgit v1.2.3 From b45756f65d90dca10cbe3e9ef04ecf96c01124a2 Mon Sep 17 00:00:00 2001 From: Changhwan Youn Date: Mon, 29 Nov 2010 16:58:29 +0900 Subject: ARM: S5PV310: Add Interrupt of MCT This patch adds IRQ_MCT0, IRQ_MCT1, IRQ_MCT_L0, and IRQ_MCT_L1. (MCT: Multi-Core Timer). And updated MAX_COMBINER_NR. Signed-off-by: Changhwan Youn Signed-off-by: Kukjin Kim --- arch/arm/mach-s5pv310/include/mach/irqs.h | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/arch/arm/mach-s5pv310/include/mach/irqs.h b/arch/arm/mach-s5pv310/include/mach/irqs.h index 99e7dad8a85a..f9a2830620d8 100644 --- a/arch/arm/mach-s5pv310/include/mach/irqs.h +++ b/arch/arm/mach-s5pv310/include/mach/irqs.h @@ -25,6 +25,8 @@ #define IRQ_SPI(x) S5P_IRQ(x+32) +#define IRQ_MCT1 IRQ_SPI(35) + #define IRQ_EINT0 IRQ_SPI(40) #define IRQ_EINT1 IRQ_SPI(41) #define IRQ_EINT2 IRQ_SPI(42) @@ -36,9 +38,8 @@ #define IRQ_JPEG IRQ_SPI(48) #define IRQ_2D IRQ_SPI(49) #define IRQ_PCIE IRQ_SPI(50) -#define IRQ_SYSTEM_TIMER IRQ_SPI(51) +#define IRQ_MCT0 IRQ_SPI(51) #define IRQ_MFC IRQ_SPI(52) -#define IRQ_WDT IRQ_SPI(53) #define IRQ_AUDIO_SS IRQ_SPI(54) #define IRQ_AC97 IRQ_SPI(55) #define IRQ_SPDIF IRQ_SPI(56) @@ -85,6 +86,8 @@ #define IRQ_ONENAND_AUDI COMBINER_IRQ(34, 0) +#define IRQ_MCT_L1 COMBINER_IRQ(35, 3) + #define IRQ_EINT4 COMBINER_IRQ(37, 0) #define IRQ_EINT5 COMBINER_IRQ(37, 1) #define IRQ_EINT6 COMBINER_IRQ(37, 2) @@ -101,7 +104,11 @@ #define IRQ_EINT16_31 COMBINER_IRQ(39, 0) -#define MAX_COMBINER_NR 40 +#define IRQ_MCT_L0 COMBINER_IRQ(51, 0) + +#define IRQ_WDT COMBINER_IRQ(53, 0) + +#define MAX_COMBINER_NR 54 #define S5P_IRQ_EINT_BASE COMBINER_IRQ(MAX_COMBINER_NR, 0) -- cgit v1.2.3 From 1f2d6c49f087c84ed54ad3e0801faeca3e2ccfdd Mon Sep 17 00:00:00 2001 From: Changhwan Youn Date: Mon, 29 Nov 2010 17:04:46 +0900 Subject: ARM: S5PV310: Limit the irqs which support cascade interrupt The irqs from SPI(0) to SPI(39) and SPI(51), SPI(53) are connected to the interrupt combiner. This patch limits the irqs which should be initialized to support cascade interrupt. Signed-off-by: Changhwan Youn Signed-off-by: Kukjin Kim --- arch/arm/mach-s5pv310/cpu.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/arch/arm/mach-s5pv310/cpu.c b/arch/arm/mach-s5pv310/cpu.c index 82ce4aa6d61a..3d0c1cb68d9e 100644 --- a/arch/arm/mach-s5pv310/cpu.c +++ b/arch/arm/mach-s5pv310/cpu.c @@ -127,6 +127,15 @@ void __init s5pv310_init_irq(void) gic_cpu_init(0, S5P_VA_GIC_CPU); for (irq = 0; irq < MAX_COMBINER_NR; irq++) { + + /* + * From SPI(0) to SPI(39) and SPI(51), SPI(53) are + * connected to the interrupt combiner. These irqs + * should be initialized to support cascade interrupt. + */ + if ((irq >= 40) && !(irq == 51) && !(irq == 53)) + continue; + combiner_init(irq, (void __iomem *)S5P_VA_COMBINER(irq), COMBINER_IRQ(irq, 0)); combiner_cascade_irq(irq, IRQ_SPI(irq)); -- cgit v1.2.3 From 85140ad591e696bc88b0ad7c978256f91099e6c9 Mon Sep 17 00:00:00 2001 From: Changhwan Youn Date: Mon, 29 Nov 2010 17:05:16 +0900 Subject: ARM: S5PV310: Add irq_mask to handle combiner irqs properly The 4 combiner groups use same registers to handle the interrupt. In previous implementation, the whole registers are checked to find which interupt is occurred and thus interrupt in other groups can be detected. This patch adds irq_mask to solve this problem. Signed-off-by: Changhwan Youn Signed-off-by: Kukjin Kim --- arch/arm/mach-s5pv310/irq-combiner.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-s5pv310/irq-combiner.c b/arch/arm/mach-s5pv310/irq-combiner.c index c3f88c3faf6c..aad5c3d525d1 100644 --- a/arch/arm/mach-s5pv310/irq-combiner.c +++ b/arch/arm/mach-s5pv310/irq-combiner.c @@ -24,6 +24,7 @@ static DEFINE_SPINLOCK(irq_controller_lock); struct combiner_chip_data { unsigned int irq_offset; + unsigned int irq_mask; void __iomem *base; }; @@ -62,6 +63,7 @@ static void combiner_handle_cascade_irq(unsigned int irq, struct irq_desc *desc) spin_lock(&irq_controller_lock); status = __raw_readl(chip_data->base + COMBINER_INT_STATUS); spin_unlock(&irq_controller_lock); + status &= chip_data->irq_mask; if (status == 0) goto out; @@ -104,10 +106,12 @@ void __init combiner_init(unsigned int combiner_nr, void __iomem *base, combiner_data[combiner_nr].base = base; combiner_data[combiner_nr].irq_offset = irq_start; + combiner_data[combiner_nr].irq_mask = 0xff << ((combiner_nr % 4) << 3); /* Disable all interrupts */ - __raw_writel(0xffffffff, base + COMBINER_ENABLE_CLEAR); + __raw_writel(combiner_data[combiner_nr].irq_mask, + base + COMBINER_ENABLE_CLEAR); /* Setup the Linux IRQ subsystem */ -- cgit v1.2.3 From 5bea7660bba973dc5e8e9d92b11fb1dd5b524ebf Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Tue, 7 Dec 2010 23:02:48 -0800 Subject: HID: add hid_hw_open/close/power() handlers Instead of exposing the guts of hid->ll_driver relationship to HID sub-drivers provide these helpers to encapsulate the details. Signed-off-by: Dmitry Torokhov Signed-off-by: Jiri Kosina --- drivers/hid/hid-input.c | 4 ++-- drivers/hid/hid-picolcd.c | 6 +++--- drivers/hid/hid-roccat.c | 26 ++++++++++---------------- drivers/hid/hidraw.c | 21 +++++++++------------ include/linux/hid.h | 43 +++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 67 insertions(+), 33 deletions(-) diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index 834ef47b76d6..b718f7144ce1 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c @@ -772,14 +772,14 @@ static int hidinput_open(struct input_dev *dev) { struct hid_device *hid = input_get_drvdata(dev); - return hid->ll_driver->open(hid); + return hid_hw_open(hid); } static void hidinput_close(struct input_dev *dev) { struct hid_device *hid = input_get_drvdata(dev); - hid->ll_driver->close(hid); + hid_hw_close(hid); } /* diff --git a/drivers/hid/hid-picolcd.c b/drivers/hid/hid-picolcd.c index bc2e07740628..38565fee7bf1 100644 --- a/drivers/hid/hid-picolcd.c +++ b/drivers/hid/hid-picolcd.c @@ -2635,7 +2635,7 @@ static int picolcd_probe(struct hid_device *hdev, goto err_cleanup_data; } - error = hdev->ll_driver->open(hdev); + error = hid_hw_open(hdev); if (error) { dev_err(&hdev->dev, "failed to open input interrupt pipe for key and IR events\n"); goto err_cleanup_hid_hw; @@ -2668,7 +2668,7 @@ err_cleanup_sysfs2: err_cleanup_sysfs1: device_remove_file(&hdev->dev, &dev_attr_operation_mode_delay); err_cleanup_hid_ll: - hdev->ll_driver->close(hdev); + hid_hw_close(hdev); err_cleanup_hid_hw: hid_hw_stop(hdev); err_cleanup_data: @@ -2699,7 +2699,7 @@ static void picolcd_remove(struct hid_device *hdev) picolcd_exit_devfs(data); device_remove_file(&hdev->dev, &dev_attr_operation_mode); device_remove_file(&hdev->dev, &dev_attr_operation_mode_delay); - hdev->ll_driver->close(hdev); + hid_hw_close(hdev); hid_hw_stop(hdev); hid_set_drvdata(hdev, NULL); diff --git a/drivers/hid/hid-roccat.c b/drivers/hid/hid-roccat.c index 5a6879e235ac..a9d9b29ff47f 100644 --- a/drivers/hid/hid-roccat.c +++ b/drivers/hid/hid-roccat.c @@ -173,19 +173,15 @@ static int roccat_open(struct inode *inode, struct file *file) if (!device->open++) { /* power on device on adding first reader */ - if (device->hid->ll_driver->power) { - error = device->hid->ll_driver->power(device->hid, - PM_HINT_FULLON); - if (error < 0) { - --device->open; - goto exit_err; - } + error = hid_hw_power(device->hid, PM_HINT_FULLON); + if (error < 0) { + --device->open; + goto exit_err; } - error = device->hid->ll_driver->open(device->hid); + + error = hid_hw_open(device->hid); if (error < 0) { - if (device->hid->ll_driver->power) - device->hid->ll_driver->power(device->hid, - PM_HINT_NORMAL); + hid_hw_power(device->hid, PM_HINT_NORMAL); --device->open; goto exit_err; } @@ -231,10 +227,8 @@ static int roccat_release(struct inode *inode, struct file *file) if (!--device->open) { /* removing last reader */ if (device->exist) { - if (device->hid->ll_driver->power) - device->hid->ll_driver->power(device->hid, - PM_HINT_NORMAL); - device->hid->ll_driver->close(device->hid); + hid_hw_power(device->hid, PM_HINT_NORMAL); + hid_hw_close(device->hid); } else { kfree(device); } @@ -370,7 +364,7 @@ void roccat_disconnect(int minor) device_destroy(roccat_class, MKDEV(roccat_major, minor)); if (device->open) { - device->hid->ll_driver->close(device->hid); + hid_hw_close(device->hid); wake_up_interruptible(&device->wait); } else { kfree(device); diff --git a/drivers/hid/hidraw.c b/drivers/hid/hidraw.c index 8a4b32dca9f7..5aefe73cf795 100644 --- a/drivers/hid/hidraw.c +++ b/drivers/hid/hidraw.c @@ -193,15 +193,13 @@ static int hidraw_open(struct inode *inode, struct file *file) dev = hidraw_table[minor]; if (!dev->open++) { - if (dev->hid->ll_driver->power) { - err = dev->hid->ll_driver->power(dev->hid, PM_HINT_FULLON); - if (err < 0) - goto out_unlock; - } - err = dev->hid->ll_driver->open(dev->hid); + err = hid_hw_power(dev->hid, PM_HINT_FULLON); + if (err < 0) + goto out_unlock; + + err = hid_hw_open(dev->hid); if (err < 0) { - if (dev->hid->ll_driver->power) - dev->hid->ll_driver->power(dev->hid, PM_HINT_NORMAL); + hid_hw_power(dev->hid, PM_HINT_NORMAL); dev->open--; } } @@ -230,9 +228,8 @@ static int hidraw_release(struct inode * inode, struct file * file) dev = hidraw_table[minor]; if (!--dev->open) { if (list->hidraw->exist) { - if (dev->hid->ll_driver->power) - dev->hid->ll_driver->power(dev->hid, PM_HINT_NORMAL); - dev->hid->ll_driver->close(dev->hid); + hid_hw_power(dev->hid, PM_HINT_NORMAL); + hid_hw_close(dev->hid); } else { kfree(list->hidraw); } @@ -434,7 +431,7 @@ void hidraw_disconnect(struct hid_device *hid) device_destroy(hidraw_class, MKDEV(hidraw_major, hidraw->minor)); if (hidraw->open) { - hid->ll_driver->close(hid); + hid_hw_close(hid); wake_up_interruptible(&hidraw->wait); } else { kfree(hidraw); diff --git a/include/linux/hid.h b/include/linux/hid.h index bb0f56f5c01e..e2af195d8b46 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h @@ -820,6 +820,49 @@ static inline void hid_hw_stop(struct hid_device *hdev) hdev->ll_driver->stop(hdev); } +/** + * hid_hw_open - signal underlaying HW to start delivering events + * + * @hdev: hid device + * + * Tell underlying HW to start delivering events from the device. + * This function should be called sometime after successful call + * to hid_hiw_start(). + */ +static inline int __must_check hid_hw_open(struct hid_device *hdev) +{ + return hdev->ll_driver->open(hdev); +} + +/** + * hid_hw_close - signal underlaying HW to stop delivering events + * + * @hdev: hid device + * + * This function indicates that we are not interested in the events + * from this device anymore. Delivery of events may or may not stop, + * depending on the number of users still outstanding. + */ +static inline void hid_hw_close(struct hid_device *hdev) +{ + hdev->ll_driver->close(hdev); +} + +/** + * hid_hw_power - requests underlying HW to go into given power mode + * + * @hdev: hid device + * @level: requested power level (one of %PM_HINT_* defines) + * + * This function requests underlying hardware to enter requested power + * mode. + */ + +static inline int hid_hw_power(struct hid_device *hdev, int level) +{ + return hdev->ll_driver->power ? hdev->ll_driver->power(hdev, level) : 0; +} + void hid_report_raw_event(struct hid_device *hid, int type, u8 *data, int size, int interrupt); -- cgit v1.2.3 From e4f078d8c0790e94e09af975ca0b870e2f050e17 Mon Sep 17 00:00:00 2001 From: Dimitris Papastamos Date: Tue, 7 Dec 2010 16:30:38 +0000 Subject: ASoC: soc-core: Fix null pointer dereference In case the codec driver did not provide a read/write function, codec->driver->read|write will be NULL. Ensure that we use the one specified in codec->read|write to avoid oopsing when we access the debugfs entries. This is achieved by using snd_soc_read() and snd_soc_write(). Signed-off-by: Dimitris Papastamos Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/soc-core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index b4c8c3800503..a14a0507bbd0 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -117,7 +117,7 @@ static ssize_t soc_codec_reg_show(struct snd_soc_codec *codec, char *buf) * the register being volatile and the device being * powered off. */ - ret = codec->driver->read(codec, i); + ret = snd_soc_read(codec, i); if (ret >= 0) count += snprintf(buf + count, PAGE_SIZE - count, @@ -228,7 +228,7 @@ static ssize_t codec_reg_write_file(struct file *file, start++; if (strict_strtoul(start, 16, &value)) return -EINVAL; - codec->driver->write(codec, reg, value); + snd_soc_write(codec, reg, value); return buf_size; } -- cgit v1.2.3 From b1e43d933a3f1183e15d91b1737ecafb7de153eb Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 7 Dec 2010 17:14:56 +0000 Subject: ASoC: Support WM8994 mono AIF configurations The WM8994 supports mono signals - enable this in the driver. With DSP mode an automatic data channel selector is available, activate this when in mono mode. Signed-off-by: Mark Brown Acked-by: Liam Girdwood --- sound/soc/codecs/wm8994.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index b37e95c4e7c7..997fd178563f 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c @@ -2099,10 +2099,12 @@ static int wm8994_hw_params(struct snd_pcm_substream *substream, struct wm8994 *control = codec->control_data; struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); int aif1_reg; + int aif2_reg; int bclk_reg; int lrclk_reg; int rate_reg; int aif1 = 0; + int aif2 = 0; int bclk = 0; int lrclk = 0; int rate_val = 0; @@ -2113,6 +2115,7 @@ static int wm8994_hw_params(struct snd_pcm_substream *substream, switch (dai->id) { case 1: aif1_reg = WM8994_AIF1_CONTROL_1; + aif2_reg = WM8994_AIF1_CONTROL_2; bclk_reg = WM8994_AIF1_BCLK; rate_reg = WM8994_AIF1_RATE; if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK || @@ -2125,6 +2128,7 @@ static int wm8994_hw_params(struct snd_pcm_substream *substream, break; case 2: aif1_reg = WM8994_AIF2_CONTROL_1; + aif2_reg = WM8994_AIF2_CONTROL_2; bclk_reg = WM8994_AIF2_BCLK; rate_reg = WM8994_AIF2_RATE; if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK || @@ -2180,6 +2184,10 @@ static int wm8994_hw_params(struct snd_pcm_substream *substream, dev_dbg(dai->dev, "AIF%dCLK is %dHz, target BCLK %dHz\n", dai->id, wm8994->aifclk[id], bclk_rate); + if (params_channels(params) == 1 && + (snd_soc_read(codec, aif1_reg) & 0x18) == 0x18) + aif2 |= WM8994_AIF1_MONO; + if (wm8994->aifclk[id] == 0) { dev_err(dai->dev, "AIF%dCLK not configured\n", dai->id); return -EINVAL; @@ -2223,6 +2231,7 @@ static int wm8994_hw_params(struct snd_pcm_substream *substream, lrclk, bclk_rate / lrclk); snd_soc_update_bits(codec, aif1_reg, WM8994_AIF1_WL_MASK, aif1); + snd_soc_update_bits(codec, aif2_reg, WM8994_AIF1_MONO, aif2); snd_soc_update_bits(codec, bclk_reg, WM8994_AIF1_BCLK_DIV_MASK, bclk); snd_soc_update_bits(codec, lrclk_reg, WM8994_AIF1DAC_RATE_MASK, lrclk); @@ -2378,14 +2387,14 @@ static struct snd_soc_dai_driver wm8994_dai[] = { .id = 1, .playback = { .stream_name = "AIF1 Playback", - .channels_min = 2, + .channels_min = 1, .channels_max = 2, .rates = WM8994_RATES, .formats = WM8994_FORMATS, }, .capture = { .stream_name = "AIF1 Capture", - .channels_min = 2, + .channels_min = 1, .channels_max = 2, .rates = WM8994_RATES, .formats = WM8994_FORMATS, @@ -2397,14 +2406,14 @@ static struct snd_soc_dai_driver wm8994_dai[] = { .id = 2, .playback = { .stream_name = "AIF2 Playback", - .channels_min = 2, + .channels_min = 1, .channels_max = 2, .rates = WM8994_RATES, .formats = WM8994_FORMATS, }, .capture = { .stream_name = "AIF2 Capture", - .channels_min = 2, + .channels_min = 1, .channels_max = 2, .rates = WM8994_RATES, .formats = WM8994_FORMATS, @@ -2416,14 +2425,14 @@ static struct snd_soc_dai_driver wm8994_dai[] = { .id = 3, .playback = { .stream_name = "AIF3 Playback", - .channels_min = 2, + .channels_min = 1, .channels_max = 2, .rates = WM8994_RATES, .formats = WM8994_FORMATS, }, .capture = { .stream_name = "AIF3 Capture", - .channels_min = 2, + .channels_min = 1, .channels_max = 2, .rates = WM8994_RATES, .formats = WM8994_FORMATS, -- cgit v1.2.3 From 146fd574ec06b1c593805738b1c2c8c5a4128681 Mon Sep 17 00:00:00 2001 From: Uk Kim Date: Tue, 7 Dec 2010 13:58:40 +0000 Subject: ASoC: Add ADC high pass filter support to WM8994 Signed-off-by: Uk Kim Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/codecs/wm8994.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index 997fd178563f..da48802340fc 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c @@ -310,6 +310,19 @@ static const char *sidetone_hpf_text[] = { static const struct soc_enum sidetone_hpf = SOC_ENUM_SINGLE(WM8994_SIDETONE, 7, 7, sidetone_hpf_text); +static const char *adc_hpf_text[] = { + "HiFi", "Voice 1", "Voice 2", "Voice 3" +}; + +static const struct soc_enum aif1adc1_hpf = + SOC_ENUM_SINGLE(WM8994_AIF1_ADC1_FILTERS, 13, 4, adc_hpf_text); + +static const struct soc_enum aif1adc2_hpf = + SOC_ENUM_SINGLE(WM8994_AIF1_ADC2_FILTERS, 13, 4, adc_hpf_text); + +static const struct soc_enum aif2adc_hpf = + SOC_ENUM_SINGLE(WM8994_AIF2_ADC_FILTERS, 13, 4, adc_hpf_text); + static const DECLARE_TLV_DB_SCALE(aif_tlv, 0, 600, 0); static const DECLARE_TLV_DB_SCALE(digital_tlv, -7200, 75, 1); static const DECLARE_TLV_DB_SCALE(st_tlv, -3600, 300, 0); @@ -812,6 +825,15 @@ SOC_SINGLE_TLV("DAC2 Left Sidetone Volume", WM8994_DAC2_MIXER_VOLUMES, SOC_ENUM("Sidetone HPF Mux", sidetone_hpf), SOC_SINGLE("Sidetone HPF Switch", WM8994_SIDETONE, 6, 1, 0), +SOC_ENUM("AIF1ADC1 HPF Mode", aif1adc1_hpf), +SOC_DOUBLE("AIF1ADC1 HPF Switch", WM8994_AIF1_ADC1_FILTERS, 12, 11, 1, 0), + +SOC_ENUM("AIF1ADC2 HPF Mode", aif1adc2_hpf), +SOC_DOUBLE("AIF1ADC2 HPF Switch", WM8994_AIF1_ADC2_FILTERS, 12, 11, 1, 0), + +SOC_ENUM("AIF2ADC HPF Mode", aif2adc_hpf), +SOC_DOUBLE("AIF2ADC HPF Switch", WM8994_AIF2_ADC_FILTERS, 12, 11, 1, 0), + SOC_DOUBLE_R_TLV("DAC1 Volume", WM8994_DAC1_LEFT_VOLUME, WM8994_DAC1_RIGHT_VOLUME, 1, 96, 0, digital_tlv), SOC_DOUBLE_R("DAC1 Switch", WM8994_DAC1_LEFT_VOLUME, -- cgit v1.2.3 From 1226056d9608d241db4b558a0d88a347ad5c66ae Mon Sep 17 00:00:00 2001 From: "Chen, Chien-Chia" Date: Wed, 8 Dec 2010 14:20:33 -0800 Subject: Staging: rt3090: Fix RT3090 scan AP function Fix RT3090 scan AP function. This patch fixes the rt3090 wireless module failed to scan AP around due to Windows driver causing rt3090 module unable to scan AP in Linux. Acked-by: Lee, Chun-Yi Signed-off-by: Chen, Chien-Chia Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rt2860/chips/rt3090.c | 3 ++- drivers/staging/rt2860/chips/rt30xx.c | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/staging/rt2860/chips/rt3090.c b/drivers/staging/rt2860/chips/rt3090.c index 156eb36e56f2..334720ee1345 100644 --- a/drivers/staging/rt2860/chips/rt3090.c +++ b/drivers/staging/rt2860/chips/rt3090.c @@ -52,7 +52,8 @@ void NICInitRT3090RFRegisters(struct rt_rtmp_adapter *pAd) if (IS_RT3090(pAd)) { /* Init RF calibration */ /* Driver should toggle RF R30 bit7 before init RF registers */ - u32 RfReg = 0, data; + u8 RfReg; + u32 data; RT30xxReadRFRegister(pAd, RF_R30, (u8 *)&RfReg); RfReg |= 0x80; diff --git a/drivers/staging/rt2860/chips/rt30xx.c b/drivers/staging/rt2860/chips/rt30xx.c index c8f728257197..e610d39bdca7 100644 --- a/drivers/staging/rt2860/chips/rt30xx.c +++ b/drivers/staging/rt2860/chips/rt30xx.c @@ -54,7 +54,7 @@ struct rt_reg_pair RT30xx_RFRegTable[] = { , {RF_R06, 0x02} , - {RF_R07, 0x70} + {RF_R07, 0x60} , {RF_R09, 0x0F} , -- cgit v1.2.3 From 0dedc37070ba1eabb2d1c7aa7899c7a9100ecf30 Mon Sep 17 00:00:00 2001 From: Roland Vossen Date: Tue, 7 Dec 2010 17:45:35 +0100 Subject: staging: brcm80211: removed unused typedefs Code cleanup. Signed-off-by: Roland Vossen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/include/wlioctl.h | 1 - drivers/staging/brcm80211/sys/wlc_types.h | 9 --------- 2 files changed, 10 deletions(-) diff --git a/drivers/staging/brcm80211/include/wlioctl.h b/drivers/staging/brcm80211/include/wlioctl.h index 45e02e5293eb..9be793c5f10c 100644 --- a/drivers/staging/brcm80211/include/wlioctl.h +++ b/drivers/staging/brcm80211/include/wlioctl.h @@ -559,7 +559,6 @@ typedef struct wl_led_info { u8 activehi; } wl_led_info_t; - /* R_REG and W_REG struct passed through ioctl */ typedef struct { u32 byteoff; /* byte offset of the field in d11regs_t */ diff --git a/drivers/staging/brcm80211/sys/wlc_types.h b/drivers/staging/brcm80211/sys/wlc_types.h index e5c8600c6298..837f72badecd 100644 --- a/drivers/staging/brcm80211/sys/wlc_types.h +++ b/drivers/staging/brcm80211/sys/wlc_types.h @@ -23,17 +23,8 @@ struct wlc_info; struct wlc_hw_info; typedef struct wlc_if wlc_if_t; typedef struct wl_if wl_if_t; -typedef struct led_info led_info_t; -typedef struct bmac_led bmac_led_t; -typedef struct bmac_led_info bmac_led_info_t; -typedef struct scb_module scb_module_t; -typedef struct ba_info ba_info_t; typedef struct ampdu_info ampdu_info_t; -typedef struct ratesel_info ratesel_info_t; typedef struct wlc_ap_info wlc_ap_info_t; -typedef struct wlc_auth_info wlc_auth_info_t; -typedef struct supplicant supplicant_t; -typedef struct authenticator authenticator_t; typedef struct antsel_info antsel_info_t; typedef struct bmac_pmq bmac_pmq_t; -- cgit v1.2.3 From 41224eb2dfe76fffc95cf9613c5bb2f4a518ddbf Mon Sep 17 00:00:00 2001 From: Roland Vossen Date: Tue, 7 Dec 2010 17:45:36 +0100 Subject: staging: brcm80211: removed unused macro's and typedefs from wpa.h Code cleanup. Signed-off-by: Roland Vossen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/include/proto/wpa.h | 94 --------------------------- 1 file changed, 94 deletions(-) diff --git a/drivers/staging/brcm80211/include/proto/wpa.h b/drivers/staging/brcm80211/include/proto/wpa.h index ec84c9f2b5ee..10c2fb62df09 100644 --- a/drivers/staging/brcm80211/include/proto/wpa.h +++ b/drivers/staging/brcm80211/include/proto/wpa.h @@ -19,95 +19,7 @@ #include -#include - -#define DOT11_RC_INVALID_WPA_IE 13 -#define DOT11_RC_MIC_FAILURE 14 -#define DOT11_RC_4WH_TIMEOUT 15 -#define DOT11_RC_GTK_UPDATE_TIMEOUT 16 -#define DOT11_RC_WPA_IE_MISMATCH 17 -#define DOT11_RC_INVALID_MC_CIPHER 18 -#define DOT11_RC_INVALID_UC_CIPHER 19 -#define DOT11_RC_INVALID_AKMP 20 -#define DOT11_RC_BAD_WPA_VERSION 21 -#define DOT11_RC_INVALID_WPA_CAP 22 -#define DOT11_RC_8021X_AUTH_FAIL 23 - #define WPA2_PMKID_LEN 16 - -typedef BWL_PRE_PACKED_STRUCT struct { - u8 tag; - u8 length; - u8 oui[3]; - u8 oui_type; - BWL_PRE_PACKED_STRUCT struct { - u8 low; - u8 high; - } BWL_POST_PACKED_STRUCT version; -} BWL_POST_PACKED_STRUCT wpa_ie_fixed_t; -#define WPA_IE_OUITYPE_LEN 4 -#define WPA_IE_FIXED_LEN 8 -#define WPA_IE_TAG_FIXED_LEN 6 - -typedef BWL_PRE_PACKED_STRUCT struct { - u8 tag; - u8 length; - BWL_PRE_PACKED_STRUCT struct { - u8 low; - u8 high; - } BWL_POST_PACKED_STRUCT version; -} BWL_POST_PACKED_STRUCT wpa_rsn_ie_fixed_t; -#define WPA_RSN_IE_FIXED_LEN 4 -#define WPA_RSN_IE_TAG_FIXED_LEN 2 -typedef u8 wpa_pmkid_t[WPA2_PMKID_LEN]; - -typedef BWL_PRE_PACKED_STRUCT struct { - u8 oui[3]; - u8 type; -} BWL_POST_PACKED_STRUCT wpa_suite_t, wpa_suite_mcast_t; -#define WPA_SUITE_LEN 4 - -typedef BWL_PRE_PACKED_STRUCT struct { - BWL_PRE_PACKED_STRUCT struct { - u8 low; - u8 high; - } BWL_POST_PACKED_STRUCT count; - wpa_suite_t list[1]; -} BWL_POST_PACKED_STRUCT wpa_suite_ucast_t, wpa_suite_auth_key_mgmt_t; -#define WPA_IE_SUITE_COUNT_LEN 2 -typedef BWL_PRE_PACKED_STRUCT struct { - BWL_PRE_PACKED_STRUCT struct { - u8 low; - u8 high; - } BWL_POST_PACKED_STRUCT count; - wpa_pmkid_t list[1]; -} BWL_POST_PACKED_STRUCT wpa_pmkid_list_t; - -#define WPA_CIPHER_NONE 0 -#define WPA_CIPHER_WEP_40 1 -#define WPA_CIPHER_TKIP 2 -#define WPA_CIPHER_AES_OCB 3 -#define WPA_CIPHER_AES_CCM 4 -#define WPA_CIPHER_WEP_104 5 - -#define IS_WPA_CIPHER(cipher) ((cipher) == WPA_CIPHER_NONE || \ - (cipher) == WPA_CIPHER_WEP_40 || \ - (cipher) == WPA_CIPHER_WEP_104 || \ - (cipher) == WPA_CIPHER_TKIP || \ - (cipher) == WPA_CIPHER_AES_OCB || \ - (cipher) == WPA_CIPHER_AES_CCM) - -#define WPA_TKIP_CM_DETECT 60 -#define WPA_TKIP_CM_BLOCK 60 - -#define RSN_CAP_LEN 2 - -#define RSN_CAP_PREAUTH 0x0001 -#define RSN_CAP_NOPAIRWISE 0x0002 -#define RSN_CAP_PTK_REPLAY_CNTR_MASK 0x000C -#define RSN_CAP_PTK_REPLAY_CNTR_SHIFT 2 -#define RSN_CAP_GTK_REPLAY_CNTR_MASK 0x0030 -#define RSN_CAP_GTK_REPLAY_CNTR_SHIFT 4 #define RSN_CAP_1_REPLAY_CNTR 0 #define RSN_CAP_2_REPLAY_CNTRS 1 #define RSN_CAP_4_REPLAY_CNTRS 2 @@ -118,10 +30,4 @@ typedef BWL_PRE_PACKED_STRUCT struct { #define WPA_CAP_REPLAY_CNTR_SHIFT RSN_CAP_PTK_REPLAY_CNTR_SHIFT #define WPA_CAP_REPLAY_CNTR_MASK RSN_CAP_PTK_REPLAY_CNTR_MASK -#define WPA_CAP_LEN RSN_CAP_LEN - -#define WPA_CAP_WPA2_PREAUTH RSN_CAP_PREAUTH - -#include - #endif /* _proto_wpa_h_ */ -- cgit v1.2.3 From 4dc79de1e39957575a784cf79bb214e54a42d44e Mon Sep 17 00:00:00 2001 From: Roland Vossen Date: Tue, 7 Dec 2010 17:45:37 +0100 Subject: staging: brcm80211: replaced typedef wlc_if_t by struct wlc_if Code cleanup. Signed-off-by: Roland Vossen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/sys/wlc_mac80211.c | 2 +- drivers/staging/brcm80211/sys/wlc_mac80211.h | 6 +++--- drivers/staging/brcm80211/sys/wlc_pub.h | 4 ++-- drivers/staging/brcm80211/sys/wlc_types.h | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/staging/brcm80211/sys/wlc_mac80211.c b/drivers/staging/brcm80211/sys/wlc_mac80211.c index d3246b754c41..11cc6539850c 100644 --- a/drivers/staging/brcm80211/sys/wlc_mac80211.c +++ b/drivers/staging/brcm80211/sys/wlc_mac80211.c @@ -8384,7 +8384,7 @@ static void wlc_txflowcontrol_signal(struct wlc_info *wlc, wlc_txq_info_t *qi, bool on, int prio) { - wlc_if_t *wlcif; + struct wlc_if *wlcif; for (wlcif = wlc->wlcif_list; wlcif != NULL; wlcif = wlcif->next) { if (wlcif->qi == qi && wlcif->flags & WLC_IF_LINKED) diff --git a/drivers/staging/brcm80211/sys/wlc_mac80211.h b/drivers/staging/brcm80211/sys/wlc_mac80211.h index 791e9178267e..81efffff391c 100644 --- a/drivers/staging/brcm80211/sys/wlc_mac80211.h +++ b/drivers/staging/brcm80211/sys/wlc_mac80211.h @@ -383,7 +383,7 @@ typedef struct dumpcb_s { /* virtual interface */ struct wlc_if { - wlc_if_t *next; + struct wlc_if *next; u8 type; /* WLC_IFTYPE_BSS or WLC_IFTYPE_WDS */ u8 index; /* assigned in wl_add_if(), index of the wlif if any, * not necessarily corresponding to bsscfg._idx or @@ -768,7 +768,7 @@ struct wlc_info { u16 next_bsscfg_ID; - wlc_if_t *wlcif_list; /* linked list of wlc_if structs */ + struct wlc_if *wlcif_list; /* linked list of wlc_if structs */ wlc_txq_info_t *active_queue; /* txq for the currently active transmit context */ u32 mpc_dur; /* total time (ms) in mpc mode except for the * portion since radio is turned off last time @@ -946,7 +946,7 @@ extern const bcm_iovar_t wlc_iovars[]; extern int wlc_doiovar(void *hdl, const bcm_iovar_t *vi, u32 actionid, const char *name, void *params, uint p_len, void *arg, - int len, int val_size, wlc_if_t *wlcif); + int len, int val_size, struct wlc_if *wlcif); #if defined(BCMDBG) extern void wlc_print_ies(struct wlc_info *wlc, u8 *ies, uint ies_len); diff --git a/drivers/staging/brcm80211/sys/wlc_pub.h b/drivers/staging/brcm80211/sys/wlc_pub.h index 1530efe15f97..80331e8a81ea 100644 --- a/drivers/staging/brcm80211/sys/wlc_pub.h +++ b/drivers/staging/brcm80211/sys/wlc_pub.h @@ -510,8 +510,8 @@ extern void wlc_intrsrestore(struct wlc_info *wlc, u32 macintmask); extern bool wlc_intrsupd(struct wlc_info *wlc); extern bool wlc_isr(struct wlc_info *wlc, bool *wantdpc); extern bool wlc_dpc(struct wlc_info *wlc, bool bounded); -extern bool wlc_send80211_raw(struct wlc_info *wlc, wlc_if_t *wlcif, void *p, - uint ac); +extern bool wlc_send80211_raw(struct wlc_info *wlc, struct wlc_if *wlcif, + void *p, uint ac); extern bool wlc_sendpkt_mac80211(struct wlc_info *wlc, struct sk_buff *sdu, struct ieee80211_hw *hw); extern int wlc_iovar_op(struct wlc_info *wlc, const char *name, void *params, diff --git a/drivers/staging/brcm80211/sys/wlc_types.h b/drivers/staging/brcm80211/sys/wlc_types.h index 837f72badecd..764bc4960699 100644 --- a/drivers/staging/brcm80211/sys/wlc_types.h +++ b/drivers/staging/brcm80211/sys/wlc_types.h @@ -21,7 +21,7 @@ struct wlc_info; struct wlc_hw_info; -typedef struct wlc_if wlc_if_t; +struct wlc_if; typedef struct wl_if wl_if_t; typedef struct ampdu_info ampdu_info_t; typedef struct wlc_ap_info wlc_ap_info_t; -- cgit v1.2.3 From 1f2fd4531d37553e4613f8f5e79cf199f47a82d2 Mon Sep 17 00:00:00 2001 From: Roland Vossen Date: Tue, 7 Dec 2010 17:45:38 +0100 Subject: staging: brcm80211: replaced typedef ampdu_info_t by struct ampdu_info Code cleanup. Signed-off-by: Roland Vossen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/sys/wlc_ampdu.c | 66 ++++++++++++++-------------- drivers/staging/brcm80211/sys/wlc_ampdu.h | 20 ++++----- drivers/staging/brcm80211/sys/wlc_mac80211.h | 2 +- drivers/staging/brcm80211/sys/wlc_types.h | 2 +- 4 files changed, 46 insertions(+), 44 deletions(-) diff --git a/drivers/staging/brcm80211/sys/wlc_ampdu.c b/drivers/staging/brcm80211/sys/wlc_ampdu.c index 9e1816b88108..c0883d01c51b 100644 --- a/drivers/staging/brcm80211/sys/wlc_ampdu.c +++ b/drivers/staging/brcm80211/sys/wlc_ampdu.c @@ -130,22 +130,24 @@ struct ampdu_info { #define SCB_AMPDU_CUBBY(ampdu, scb) (&(scb->scb_ampdu)) #define SCB_AMPDU_INI(scb_ampdu, tid) (&(scb_ampdu->ini[tid])) -static void wlc_ffpld_init(ampdu_info_t *ampdu); +static void wlc_ffpld_init(struct ampdu_info *ampdu); static int wlc_ffpld_check_txfunfl(struct wlc_info *wlc, int f); -static void wlc_ffpld_calc_mcs2ampdu_table(ampdu_info_t *ampdu, int f); +static void wlc_ffpld_calc_mcs2ampdu_table(struct ampdu_info *ampdu, int f); -static scb_ampdu_tid_ini_t *wlc_ampdu_init_tid_ini(ampdu_info_t *ampdu, +static scb_ampdu_tid_ini_t *wlc_ampdu_init_tid_ini(struct ampdu_info *ampdu, scb_ampdu_t *scb_ampdu, u8 tid, bool override); -static void ampdu_cleanup_tid_ini(ampdu_info_t *ampdu, scb_ampdu_t *scb_ampdu, +static void ampdu_cleanup_tid_ini(struct ampdu_info *ampdu, + scb_ampdu_t *scb_ampdu, u8 tid, bool force); -static void ampdu_update_max_txlen(ampdu_info_t *ampdu, u8 dur); -static void scb_ampdu_update_config(ampdu_info_t *ampdu, struct scb *scb); -static void scb_ampdu_update_config_all(ampdu_info_t *ampdu); +static void ampdu_update_max_txlen(struct ampdu_info *ampdu, u8 dur); +static void scb_ampdu_update_config(struct ampdu_info *ampdu, struct scb *scb); +static void scb_ampdu_update_config_all(struct ampdu_info *ampdu); #define wlc_ampdu_txflowcontrol(a, b, c) do {} while (0) -static void wlc_ampdu_dotxstatus_complete(ampdu_info_t *ampdu, struct scb *scb, +static void wlc_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, + struct scb *scb, struct sk_buff *p, tx_status_t *txs, u32 frmtxstatus, u32 frmtxstatus2); @@ -158,9 +160,9 @@ static inline u16 pkt_txh_seqnum(struct wlc_info *wlc, struct sk_buff *p) return ltoh16(h->seq) >> SEQNUM_SHIFT; } -ampdu_info_t *wlc_ampdu_attach(struct wlc_info *wlc) +struct ampdu_info *wlc_ampdu_attach(struct wlc_info *wlc) { - ampdu_info_t *ampdu; + struct ampdu_info *ampdu; int i; /* some code depends on packed structures */ @@ -170,7 +172,7 @@ ampdu_info_t *wlc_ampdu_attach(struct wlc_info *wlc) ASSERT(wlc->pub->tunables->ampdunummpdu <= AMPDU_MAX_MPDU); ASSERT(wlc->pub->tunables->ampdunummpdu > 0); - ampdu = kzalloc(sizeof(ampdu_info_t), GFP_ATOMIC); + ampdu = kzalloc(sizeof(struct ampdu_info), GFP_ATOMIC); if (!ampdu) { WL_ERROR(("wl%d: wlc_ampdu_attach: out of mem\n", wlc->pub->unit)); return NULL; @@ -219,7 +221,7 @@ ampdu_info_t *wlc_ampdu_attach(struct wlc_info *wlc) return ampdu; } -void wlc_ampdu_detach(ampdu_info_t *ampdu) +void wlc_ampdu_detach(struct ampdu_info *ampdu) { int i; @@ -237,7 +239,7 @@ void wlc_ampdu_detach(ampdu_info_t *ampdu) kfree(ampdu); } -void scb_ampdu_cleanup(ampdu_info_t *ampdu, struct scb *scb) +void scb_ampdu_cleanup(struct ampdu_info *ampdu, struct scb *scb) { scb_ampdu_t *scb_ampdu = SCB_AMPDU_CUBBY(ampdu, scb); u8 tid; @@ -253,12 +255,12 @@ void scb_ampdu_cleanup(ampdu_info_t *ampdu, struct scb *scb) /* reset the ampdu state machine so that it can gracefully handle packets that were * freed from the dma and tx queues during reinit */ -void wlc_ampdu_reset(ampdu_info_t *ampdu) +void wlc_ampdu_reset(struct ampdu_info *ampdu) { WL_NONE(("%s: Entering\n", __func__)); } -static void scb_ampdu_update_config(ampdu_info_t *ampdu, struct scb *scb) +static void scb_ampdu_update_config(struct ampdu_info *ampdu, struct scb *scb) { scb_ampdu_t *scb_ampdu = SCB_AMPDU_CUBBY(ampdu, scb); int i; @@ -288,12 +290,12 @@ static void scb_ampdu_update_config(ampdu_info_t *ampdu, struct scb *scb) ASSERT(scb_ampdu->release); } -void scb_ampdu_update_config_all(ampdu_info_t *ampdu) +void scb_ampdu_update_config_all(struct ampdu_info *ampdu) { scb_ampdu_update_config(ampdu, ampdu->wlc->pub->global_scb); } -static void wlc_ffpld_init(ampdu_info_t *ampdu) +static void wlc_ffpld_init(struct ampdu_info *ampdu) { int i, j; wlc_fifo_info_t *fifo; @@ -319,7 +321,7 @@ static void wlc_ffpld_init(ampdu_info_t *ampdu) */ static int wlc_ffpld_check_txfunfl(struct wlc_info *wlc, int fid) { - ampdu_info_t *ampdu = wlc->ampdu; + struct ampdu_info *ampdu = wlc->ampdu; u32 phy_rate = MCS_RATE(FFPLD_MAX_MCS, true, false); u32 txunfl_ratio; u8 max_mpdu; @@ -437,7 +439,7 @@ static int wlc_ffpld_check_txfunfl(struct wlc_info *wlc, int fid) return 0; } -static void wlc_ffpld_calc_mcs2ampdu_table(ampdu_info_t *ampdu, int f) +static void wlc_ffpld_calc_mcs2ampdu_table(struct ampdu_info *ampdu, int f) { int i; u32 phy_rate, dma_rate, tmp; @@ -470,7 +472,7 @@ static void wlc_ffpld_calc_mcs2ampdu_table(ampdu_info_t *ampdu, int f) } static void BCMFASTPATH -wlc_ampdu_agg(ampdu_info_t *ampdu, struct scb *scb, struct sk_buff *p, +wlc_ampdu_agg(struct ampdu_info *ampdu, struct scb *scb, struct sk_buff *p, uint prec) { scb_ampdu_t *scb_ampdu; @@ -488,8 +490,8 @@ wlc_ampdu_agg(ampdu_info_t *ampdu, struct scb *scb, struct sk_buff *p, } int BCMFASTPATH -wlc_sendampdu(ampdu_info_t *ampdu, wlc_txq_info_t *qi, struct sk_buff **pdu, - int prec) +wlc_sendampdu(struct ampdu_info *ampdu, wlc_txq_info_t *qi, + struct sk_buff **pdu, int prec) { struct wlc_info *wlc; struct osl_info *osh; @@ -885,8 +887,8 @@ wlc_sendampdu(ampdu_info_t *ampdu, wlc_txq_info_t *qi, struct sk_buff **pdu, } void BCMFASTPATH -wlc_ampdu_dotxstatus(ampdu_info_t *ampdu, struct scb *scb, struct sk_buff *p, - tx_status_t *txs) +wlc_ampdu_dotxstatus(struct ampdu_info *ampdu, struct scb *scb, + struct sk_buff *p, tx_status_t *txs) { scb_ampdu_t *scb_ampdu; struct wlc_info *wlc = ampdu->wlc; @@ -949,7 +951,7 @@ rate_status(struct wlc_info *wlc, struct ieee80211_tx_info *tx_info, #define SHORTNAME "AMPDU status" static void BCMFASTPATH -wlc_ampdu_dotxstatus_complete(ampdu_info_t *ampdu, struct scb *scb, +wlc_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb, struct sk_buff *p, tx_status_t *txs, u32 s1, u32 s2) { @@ -1173,7 +1175,7 @@ wlc_ampdu_dotxstatus_complete(ampdu_info_t *ampdu, struct scb *scb, } static void -ampdu_cleanup_tid_ini(ampdu_info_t *ampdu, scb_ampdu_t *scb_ampdu, u8 tid, +ampdu_cleanup_tid_ini(struct ampdu_info *ampdu, scb_ampdu_t *scb_ampdu, u8 tid, bool force) { scb_ampdu_tid_ini_t *ini; @@ -1195,7 +1197,7 @@ ampdu_cleanup_tid_ini(ampdu_info_t *ampdu, scb_ampdu_t *scb_ampdu, u8 tid, } /* initialize the initiator code for tid */ -static scb_ampdu_tid_ini_t *wlc_ampdu_init_tid_ini(ampdu_info_t *ampdu, +static scb_ampdu_tid_ini_t *wlc_ampdu_init_tid_ini(struct ampdu_info *ampdu, scb_ampdu_t *scb_ampdu, u8 tid, bool override) { @@ -1221,7 +1223,7 @@ static scb_ampdu_tid_ini_t *wlc_ampdu_init_tid_ini(ampdu_info_t *ampdu, return ini; } -int wlc_ampdu_set(ampdu_info_t *ampdu, bool on) +int wlc_ampdu_set(struct ampdu_info *ampdu, bool on) { struct wlc_info *wlc = ampdu->wlc; @@ -1244,7 +1246,7 @@ int wlc_ampdu_set(ampdu_info_t *ampdu, bool on) return 0; } -bool wlc_ampdu_cap(ampdu_info_t *ampdu) +bool wlc_ampdu_cap(struct ampdu_info *ampdu) { if (WLC_PHY_11N_CAP(ampdu->wlc->band)) return true; @@ -1252,7 +1254,7 @@ bool wlc_ampdu_cap(ampdu_info_t *ampdu) return false; } -static void ampdu_update_max_txlen(ampdu_info_t *ampdu, u8 dur) +static void ampdu_update_max_txlen(struct ampdu_info *ampdu, u8 dur) { u32 rate, mcs; @@ -1274,7 +1276,7 @@ static void ampdu_update_max_txlen(ampdu_info_t *ampdu, u8 dur) } u8 BCMFASTPATH -wlc_ampdu_null_delim_cnt(ampdu_info_t *ampdu, struct scb *scb, +wlc_ampdu_null_delim_cnt(struct ampdu_info *ampdu, struct scb *scb, ratespec_t rspec, int phylen) { scb_ampdu_t *scb_ampdu; @@ -1326,7 +1328,7 @@ bool wlc_aggregatable(struct wlc_info *wlc, u8 tid) return wlc->ampdu->ini_enable[tid]; } -void wlc_ampdu_shm_upd(ampdu_info_t *ampdu) +void wlc_ampdu_shm_upd(struct ampdu_info *ampdu) { struct wlc_info *wlc = ampdu->wlc; diff --git a/drivers/staging/brcm80211/sys/wlc_ampdu.h b/drivers/staging/brcm80211/sys/wlc_ampdu.h index 4c3358da89e5..03457f63f2ab 100644 --- a/drivers/staging/brcm80211/sys/wlc_ampdu.h +++ b/drivers/staging/brcm80211/sys/wlc_ampdu.h @@ -17,20 +17,20 @@ #ifndef _wlc_ampdu_h_ #define _wlc_ampdu_h_ -extern ampdu_info_t *wlc_ampdu_attach(struct wlc_info *wlc); -extern void wlc_ampdu_detach(ampdu_info_t *ampdu); -extern bool wlc_ampdu_cap(ampdu_info_t *ampdu); -extern int wlc_ampdu_set(ampdu_info_t *ampdu, bool on); -extern int wlc_sendampdu(ampdu_info_t *ampdu, wlc_txq_info_t *qi, +extern struct ampdu_info *wlc_ampdu_attach(struct wlc_info *wlc); +extern void wlc_ampdu_detach(struct ampdu_info *ampdu); +extern bool wlc_ampdu_cap(struct ampdu_info *ampdu); +extern int wlc_ampdu_set(struct ampdu_info *ampdu, bool on); +extern int wlc_sendampdu(struct ampdu_info *ampdu, wlc_txq_info_t *qi, struct sk_buff **aggp, int prec); -extern void wlc_ampdu_dotxstatus(ampdu_info_t *ampdu, struct scb *scb, +extern void wlc_ampdu_dotxstatus(struct ampdu_info *ampdu, struct scb *scb, struct sk_buff *p, tx_status_t *txs); -extern void wlc_ampdu_reset(ampdu_info_t *ampdu); +extern void wlc_ampdu_reset(struct ampdu_info *ampdu); extern void wlc_ampdu_macaddr_upd(struct wlc_info *wlc); -extern void wlc_ampdu_shm_upd(ampdu_info_t *ampdu); +extern void wlc_ampdu_shm_upd(struct ampdu_info *ampdu); -extern u8 wlc_ampdu_null_delim_cnt(ampdu_info_t *ampdu, struct scb *scb, +extern u8 wlc_ampdu_null_delim_cnt(struct ampdu_info *ampdu, struct scb *scb, ratespec_t rspec, int phylen); -extern void scb_ampdu_cleanup(ampdu_info_t *ampdu, struct scb *scb); +extern void scb_ampdu_cleanup(struct ampdu_info *ampdu, struct scb *scb); #endif /* _wlc_ampdu_h_ */ diff --git a/drivers/staging/brcm80211/sys/wlc_mac80211.h b/drivers/staging/brcm80211/sys/wlc_mac80211.h index 81efffff391c..59a8d6beca1b 100644 --- a/drivers/staging/brcm80211/sys/wlc_mac80211.h +++ b/drivers/staging/brcm80211/sys/wlc_mac80211.h @@ -548,7 +548,7 @@ struct wlc_info { u8 txpwr_local_constraint; /* local power contraint in dB */ - ampdu_info_t *ampdu; /* ampdu module handler */ + struct ampdu_info *ampdu; /* ampdu module handler */ antsel_info_t *asi; /* antsel module handler */ wlc_cm_info_t *cmi; /* channel manager module handler */ diff --git a/drivers/staging/brcm80211/sys/wlc_types.h b/drivers/staging/brcm80211/sys/wlc_types.h index 764bc4960699..9c18a7f592d3 100644 --- a/drivers/staging/brcm80211/sys/wlc_types.h +++ b/drivers/staging/brcm80211/sys/wlc_types.h @@ -23,7 +23,7 @@ struct wlc_info; struct wlc_hw_info; struct wlc_if; typedef struct wl_if wl_if_t; -typedef struct ampdu_info ampdu_info_t; +struct ampdu_info; typedef struct wlc_ap_info wlc_ap_info_t; typedef struct antsel_info antsel_info_t; typedef struct bmac_pmq bmac_pmq_t; -- cgit v1.2.3 From 0e4934748948b5886c965fe56207b41d3abd58e7 Mon Sep 17 00:00:00 2001 From: Roland Vossen Date: Tue, 7 Dec 2010 17:45:39 +0100 Subject: staging: brcm80211: replaced typedef wlc_ap_info_t by struct wlc_ap_info Code cleanup. Signed-off-by: Roland Vossen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/sys/wlc_mac80211.h | 2 +- drivers/staging/brcm80211/sys/wlc_types.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/brcm80211/sys/wlc_mac80211.h b/drivers/staging/brcm80211/sys/wlc_mac80211.h index 59a8d6beca1b..1d5149ee1207 100644 --- a/drivers/staging/brcm80211/sys/wlc_mac80211.h +++ b/drivers/staging/brcm80211/sys/wlc_mac80211.h @@ -749,7 +749,7 @@ struct wlc_info { ac_bitmap_t apsd_trigger_ac; /* Permissible Acess Category in which APSD Null * Trigger frames can be send */ - wlc_ap_info_t *ap; + struct wlc_ap_info *ap; u8 htphy_membership; /* HT PHY membership */ diff --git a/drivers/staging/brcm80211/sys/wlc_types.h b/drivers/staging/brcm80211/sys/wlc_types.h index 9c18a7f592d3..9634a66582ac 100644 --- a/drivers/staging/brcm80211/sys/wlc_types.h +++ b/drivers/staging/brcm80211/sys/wlc_types.h @@ -24,7 +24,7 @@ struct wlc_hw_info; struct wlc_if; typedef struct wl_if wl_if_t; struct ampdu_info; -typedef struct wlc_ap_info wlc_ap_info_t; +struct wlc_ap_info; typedef struct antsel_info antsel_info_t; typedef struct bmac_pmq bmac_pmq_t; -- cgit v1.2.3 From 299f8a4658e055d9f9713f7bed45860474544e68 Mon Sep 17 00:00:00 2001 From: Roland Vossen Date: Tue, 7 Dec 2010 17:45:40 +0100 Subject: staging: brcm80211: replaced typedef antsel_info_t by struct antsel_info Code cleanup. Signed-off-by: Roland Vossen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/sys/wlc_antsel.c | 32 +++++++++++++++------------- drivers/staging/brcm80211/sys/wlc_antsel.h | 11 +++++----- drivers/staging/brcm80211/sys/wlc_mac80211.h | 7 ++++-- drivers/staging/brcm80211/sys/wlc_types.h | 2 +- 4 files changed, 29 insertions(+), 23 deletions(-) diff --git a/drivers/staging/brcm80211/sys/wlc_antsel.c b/drivers/staging/brcm80211/sys/wlc_antsel.c index 9533b5687302..aaf9985a1995 100644 --- a/drivers/staging/brcm80211/sys/wlc_antsel.c +++ b/drivers/staging/brcm80211/sys/wlc_antsel.c @@ -63,10 +63,11 @@ #define ANT_SELCFG_DEF_2x4 0x02 /* default antenna configuration */ /* static functions */ -static int wlc_antsel_cfgupd(antsel_info_t *asi, wlc_antselcfg_t *antsel); -static u8 wlc_antsel_id2antcfg(antsel_info_t *asi, u8 id); -static u16 wlc_antsel_antcfg2antsel(antsel_info_t *asi, u8 ant_cfg); -static void wlc_antsel_init_cfg(antsel_info_t *asi, wlc_antselcfg_t *antsel, +static int wlc_antsel_cfgupd(struct antsel_info *asi, wlc_antselcfg_t *antsel); +static u8 wlc_antsel_id2antcfg(struct antsel_info *asi, u8 id); +static u16 wlc_antsel_antcfg2antsel(struct antsel_info *asi, u8 ant_cfg); +static void wlc_antsel_init_cfg(struct antsel_info *asi, + wlc_antselcfg_t *antsel, bool auto_sel); const u16 mimo_2x4_div_antselpat_tbl[] = { @@ -93,12 +94,13 @@ const u8 mimo_2x3_div_antselid_tbl[16] = { 0, 0, 0, 0, 0, 0, 0, 0 /* pat to antselid */ }; -antsel_info_t *wlc_antsel_attach(struct wlc_info *wlc, struct osl_info *osh, +struct antsel_info *wlc_antsel_attach(struct wlc_info *wlc, + struct osl_info *osh, wlc_pub_t *pub, struct wlc_hw_info *wlc_hw) { - antsel_info_t *asi; + struct antsel_info *asi; - asi = kzalloc(sizeof(antsel_info_t), GFP_ATOMIC); + asi = kzalloc(sizeof(struct antsel_info), GFP_ATOMIC); if (!asi) { WL_ERROR(("wl%d: wlc_antsel_attach: out of mem\n", pub->unit)); return NULL; @@ -157,7 +159,7 @@ antsel_info_t *wlc_antsel_attach(struct wlc_info *wlc, struct osl_info *osh, return asi; } -void wlc_antsel_detach(antsel_info_t *asi) +void wlc_antsel_detach(struct antsel_info *asi) { if (!asi) return; @@ -165,7 +167,7 @@ void wlc_antsel_detach(antsel_info_t *asi) kfree(asi); } -void wlc_antsel_init(antsel_info_t *asi) +void wlc_antsel_init(struct antsel_info *asi) { if ((asi->antsel_type == ANTSEL_2x3) || (asi->antsel_type == ANTSEL_2x4)) @@ -174,7 +176,7 @@ void wlc_antsel_init(antsel_info_t *asi) /* boardlevel antenna selection: init antenna selection structure */ static void -wlc_antsel_init_cfg(antsel_info_t *asi, wlc_antselcfg_t *antsel, +wlc_antsel_init_cfg(struct antsel_info *asi, wlc_antselcfg_t *antsel, bool auto_sel) { if (asi->antsel_type == ANTSEL_2x3) { @@ -205,7 +207,7 @@ wlc_antsel_init_cfg(antsel_info_t *asi, wlc_antselcfg_t *antsel, } void BCMFASTPATH -wlc_antsel_antcfg_get(antsel_info_t *asi, bool usedef, bool sel, +wlc_antsel_antcfg_get(struct antsel_info *asi, bool usedef, bool sel, u8 antselid, u8 fbantselid, u8 *antcfg, u8 *fbantcfg) { @@ -237,7 +239,7 @@ wlc_antsel_antcfg_get(antsel_info_t *asi, bool usedef, bool sel, } /* boardlevel antenna selection: convert mimo_antsel (ucode interface) to id */ -u8 wlc_antsel_antsel2id(antsel_info_t *asi, u16 antsel) +u8 wlc_antsel_antsel2id(struct antsel_info *asi, u16 antsel) { u8 antselid = 0; @@ -256,7 +258,7 @@ u8 wlc_antsel_antsel2id(antsel_info_t *asi, u16 antsel) } /* boardlevel antenna selection: convert id to ant_cfg */ -static u8 wlc_antsel_id2antcfg(antsel_info_t *asi, u8 id) +static u8 wlc_antsel_id2antcfg(struct antsel_info *asi, u8 id) { u8 antcfg = ANT_SELCFG_DEF_2x2; @@ -275,7 +277,7 @@ static u8 wlc_antsel_id2antcfg(antsel_info_t *asi, u8 id) } /* boardlevel antenna selection: convert ant_cfg to mimo_antsel (ucode interface) */ -static u16 wlc_antsel_antcfg2antsel(antsel_info_t *asi, u8 ant_cfg) +static u16 wlc_antsel_antcfg2antsel(struct antsel_info *asi, u8 ant_cfg) { u8 idx = WLC_ANTIDX_11N(WLC_ANTSEL_11N(ant_cfg)); u16 mimo_antsel = 0; @@ -295,7 +297,7 @@ static u16 wlc_antsel_antcfg2antsel(antsel_info_t *asi, u8 ant_cfg) } /* boardlevel antenna selection: ucode interface control */ -static int wlc_antsel_cfgupd(antsel_info_t *asi, wlc_antselcfg_t *antsel) +static int wlc_antsel_cfgupd(struct antsel_info *asi, wlc_antselcfg_t *antsel) { struct wlc_info *wlc = asi->wlc; u8 ant_cfg; diff --git a/drivers/staging/brcm80211/sys/wlc_antsel.h b/drivers/staging/brcm80211/sys/wlc_antsel.h index 763986dd226e..ba38a2aedbd9 100644 --- a/drivers/staging/brcm80211/sys/wlc_antsel.h +++ b/drivers/staging/brcm80211/sys/wlc_antsel.h @@ -16,14 +16,15 @@ #ifndef _wlc_antsel_h_ #define _wlc_antsel_h_ -extern antsel_info_t *wlc_antsel_attach(struct wlc_info *wlc, +extern struct antsel_info *wlc_antsel_attach(struct wlc_info *wlc, struct osl_info *osh, wlc_pub_t *pub, struct wlc_hw_info *wlc_hw); -extern void wlc_antsel_detach(antsel_info_t *asi); -extern void wlc_antsel_init(antsel_info_t *asi); -extern void wlc_antsel_antcfg_get(antsel_info_t *asi, bool usedef, bool sel, +extern void wlc_antsel_detach(struct antsel_info *asi); +extern void wlc_antsel_init(struct antsel_info *asi); +extern void wlc_antsel_antcfg_get(struct antsel_info *asi, bool usedef, + bool sel, u8 id, u8 fbid, u8 *antcfg, u8 *fbantcfg); -extern u8 wlc_antsel_antsel2id(antsel_info_t *asi, u16 antsel); +extern u8 wlc_antsel_antsel2id(struct antsel_info *asi, u16 antsel); #endif /* _wlc_antsel_h_ */ diff --git a/drivers/staging/brcm80211/sys/wlc_mac80211.h b/drivers/staging/brcm80211/sys/wlc_mac80211.h index 1d5149ee1207..2ad37f612f00 100644 --- a/drivers/staging/brcm80211/sys/wlc_mac80211.h +++ b/drivers/staging/brcm80211/sys/wlc_mac80211.h @@ -487,7 +487,10 @@ struct wlc_hw_info { u8 antsel_type; /* Type of boardlevel mimo antenna switch-logic * 0 = N/A, 1 = 2x4 board, 2 = 2x3 CB2 board */ - u32 antsel_avail; /* put antsel_info_t here if more info is needed */ + u32 antsel_avail; /* + * put struct antsel_info here if more info is + * needed + */ }; /* TX Queue information @@ -549,7 +552,7 @@ struct wlc_info { struct ampdu_info *ampdu; /* ampdu module handler */ - antsel_info_t *asi; /* antsel module handler */ + struct antsel_info *asi; /* antsel module handler */ wlc_cm_info_t *cmi; /* channel manager module handler */ void *btparam; /* bus type specific cookie */ diff --git a/drivers/staging/brcm80211/sys/wlc_types.h b/drivers/staging/brcm80211/sys/wlc_types.h index 9634a66582ac..284e7c350c81 100644 --- a/drivers/staging/brcm80211/sys/wlc_types.h +++ b/drivers/staging/brcm80211/sys/wlc_types.h @@ -25,7 +25,7 @@ struct wlc_if; typedef struct wl_if wl_if_t; struct ampdu_info; struct wlc_ap_info; -typedef struct antsel_info antsel_info_t; +struct antsel_info; typedef struct bmac_pmq bmac_pmq_t; struct d11init; -- cgit v1.2.3 From d65ddb58325ba2c4fef70f6c9ff542df81e5cdb3 Mon Sep 17 00:00:00 2001 From: Roland Vossen Date: Tue, 7 Dec 2010 17:45:41 +0100 Subject: staging: brcm80211: replaced typedef bmac_pmq_t by struct bmac_pmq Code cleanup. Signed-off-by: Roland Vossen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/sys/wlc_mac80211.h | 2 +- drivers/staging/brcm80211/sys/wlc_types.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/brcm80211/sys/wlc_mac80211.h b/drivers/staging/brcm80211/sys/wlc_mac80211.h index 2ad37f612f00..bfd9ad4118ad 100644 --- a/drivers/staging/brcm80211/sys/wlc_mac80211.h +++ b/drivers/staging/brcm80211/sys/wlc_mac80211.h @@ -476,7 +476,7 @@ struct wlc_hw_info { bool forcefastclk; /* true if the h/w is forcing the use of fast clk */ bool clk; /* core is out of reset and has clock */ bool sbclk; /* sb has clock */ - bmac_pmq_t *bmac_pmq; /* bmac PM states derived from ucode PMQ */ + struct bmac_pmq *bmac_pmq; /* bmac PM states derived from ucode PMQ */ bool phyclk; /* phy is out of reset and has clock */ bool dma_lpbk; /* core is in DMA loopback */ diff --git a/drivers/staging/brcm80211/sys/wlc_types.h b/drivers/staging/brcm80211/sys/wlc_types.h index 284e7c350c81..5f63c48b00fd 100644 --- a/drivers/staging/brcm80211/sys/wlc_types.h +++ b/drivers/staging/brcm80211/sys/wlc_types.h @@ -26,7 +26,7 @@ typedef struct wl_if wl_if_t; struct ampdu_info; struct wlc_ap_info; struct antsel_info; -typedef struct bmac_pmq bmac_pmq_t; +struct bmac_pmq; struct d11init; -- cgit v1.2.3 From 6cdeaef203155bd7f12d362e5345323cfecde58a Mon Sep 17 00:00:00 2001 From: Roland Vossen Date: Tue, 7 Dec 2010 17:45:42 +0100 Subject: staging: brcm80211: replaced typedef wl_if_t by struct wl_if Code cleanup. Signed-off-by: Roland Vossen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/sys/wl_mac80211.c | 2 +- drivers/staging/brcm80211/sys/wlc_mac80211.h | 2 +- drivers/staging/brcm80211/sys/wlc_types.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/brcm80211/sys/wl_mac80211.c b/drivers/staging/brcm80211/sys/wl_mac80211.c index d41212bca633..1e7a29d006be 100644 --- a/drivers/staging/brcm80211/sys/wl_mac80211.c +++ b/drivers/staging/brcm80211/sys/wl_mac80211.c @@ -98,7 +98,7 @@ struct ieee80211_tkip_data { u8 rx_hdr[16], tx_hdr[16]; }; -#define WL_DEV_IF(dev) ((wl_if_t *)netdev_priv(dev)) +#define WL_DEV_IF(dev) ((struct wl_if *)netdev_priv(dev)) #define WL_INFO(dev) ((struct wl_info *)(WL_DEV_IF(dev)->wl)) static int wl_request_fw(struct wl_info *wl, struct pci_dev *pdev); static void wl_release_fw(struct wl_info *wl); diff --git a/drivers/staging/brcm80211/sys/wlc_mac80211.h b/drivers/staging/brcm80211/sys/wlc_mac80211.h index bfd9ad4118ad..2054e346eab4 100644 --- a/drivers/staging/brcm80211/sys/wlc_mac80211.h +++ b/drivers/staging/brcm80211/sys/wlc_mac80211.h @@ -390,7 +390,7 @@ struct wlc_if { * AID2PVBMAP(scb). */ u8 flags; /* flags for the interface */ - wl_if_t *wlif; /* pointer to wlif */ + struct wl_if *wlif; /* pointer to wlif */ struct wlc_txq_info *qi; /* pointer to associated tx queue */ union { struct scb *scb; /* pointer to scb if WLC_IFTYPE_WDS */ diff --git a/drivers/staging/brcm80211/sys/wlc_types.h b/drivers/staging/brcm80211/sys/wlc_types.h index 5f63c48b00fd..7e2e198334ca 100644 --- a/drivers/staging/brcm80211/sys/wlc_types.h +++ b/drivers/staging/brcm80211/sys/wlc_types.h @@ -22,7 +22,7 @@ struct wlc_info; struct wlc_hw_info; struct wlc_if; -typedef struct wl_if wl_if_t; +struct wl_if; struct ampdu_info; struct wlc_ap_info; struct antsel_info; -- cgit v1.2.3 From 17d766510b9630cfa723a6711e314565a048c234 Mon Sep 17 00:00:00 2001 From: Roland Vossen Date: Tue, 7 Dec 2010 17:45:43 +0100 Subject: staging: brcm80211: replaced typedef hnddma_t by struct hnddma_pub Code cleanup. Signed-off-by: Roland Vossen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/include/hnddma.h | 89 ++++++++++++++-------------- drivers/staging/brcm80211/sys/wlc_bmac.c | 2 +- drivers/staging/brcm80211/sys/wlc_mac80211.c | 2 +- drivers/staging/brcm80211/sys/wlc_mac80211.h | 2 +- drivers/staging/brcm80211/sys/wlc_types.h | 2 +- drivers/staging/brcm80211/util/hnddma.c | 8 +-- 6 files changed, 53 insertions(+), 52 deletions(-) diff --git a/drivers/staging/brcm80211/include/hnddma.h b/drivers/staging/brcm80211/include/hnddma.h index 05dd9ba19858..4c5462baf11e 100644 --- a/drivers/staging/brcm80211/include/hnddma.h +++ b/drivers/staging/brcm80211/include/hnddma.h @@ -19,7 +19,7 @@ #ifndef _hnddma_pub_ #define _hnddma_pub_ -typedef const struct hnddma_pub hnddma_t; +struct hnddma_pub; #endif /* _hnddma_pub_ */ /* range param for dma_getnexttxp() and dma_txreclaim */ @@ -30,52 +30,54 @@ typedef enum txd_range { } txd_range_t; /* dma function type */ -typedef void (*di_detach_t) (hnddma_t *dmah); -typedef bool(*di_txreset_t) (hnddma_t *dmah); -typedef bool(*di_rxreset_t) (hnddma_t *dmah); -typedef bool(*di_rxidle_t) (hnddma_t *dmah); -typedef void (*di_txinit_t) (hnddma_t *dmah); -typedef bool(*di_txenabled_t) (hnddma_t *dmah); -typedef void (*di_rxinit_t) (hnddma_t *dmah); -typedef void (*di_txsuspend_t) (hnddma_t *dmah); -typedef void (*di_txresume_t) (hnddma_t *dmah); -typedef bool(*di_txsuspended_t) (hnddma_t *dmah); -typedef bool(*di_txsuspendedidle_t) (hnddma_t *dmah); -typedef int (*di_txfast_t) (hnddma_t *dmah, struct sk_buff *p, bool commit); -typedef int (*di_txunframed_t) (hnddma_t *dmah, void *p, uint len, +typedef void (*di_detach_t) (struct hnddma_pub *dmah); +typedef bool(*di_txreset_t) (struct hnddma_pub *dmah); +typedef bool(*di_rxreset_t) (struct hnddma_pub *dmah); +typedef bool(*di_rxidle_t) (struct hnddma_pub *dmah); +typedef void (*di_txinit_t) (struct hnddma_pub *dmah); +typedef bool(*di_txenabled_t) (struct hnddma_pub *dmah); +typedef void (*di_rxinit_t) (struct hnddma_pub *dmah); +typedef void (*di_txsuspend_t) (struct hnddma_pub *dmah); +typedef void (*di_txresume_t) (struct hnddma_pub *dmah); +typedef bool(*di_txsuspended_t) (struct hnddma_pub *dmah); +typedef bool(*di_txsuspendedidle_t) (struct hnddma_pub *dmah); +typedef int (*di_txfast_t) (struct hnddma_pub *dmah, struct sk_buff *p, + bool commit); +typedef int (*di_txunframed_t) (struct hnddma_pub *dmah, void *p, uint len, bool commit); -typedef void *(*di_getpos_t) (hnddma_t *di, bool direction); -typedef void (*di_fifoloopbackenable_t) (hnddma_t *dmah); -typedef bool(*di_txstopped_t) (hnddma_t *dmah); -typedef bool(*di_rxstopped_t) (hnddma_t *dmah); -typedef bool(*di_rxenable_t) (hnddma_t *dmah); -typedef bool(*di_rxenabled_t) (hnddma_t *dmah); -typedef void *(*di_rx_t) (hnddma_t *dmah); -typedef bool(*di_rxfill_t) (hnddma_t *dmah); -typedef void (*di_txreclaim_t) (hnddma_t *dmah, txd_range_t range); -typedef void (*di_rxreclaim_t) (hnddma_t *dmah); -typedef unsigned long (*di_getvar_t) (hnddma_t *dmah, const char *name); -typedef void *(*di_getnexttxp_t) (hnddma_t *dmah, txd_range_t range); -typedef void *(*di_getnextrxp_t) (hnddma_t *dmah, bool forceall); -typedef void *(*di_peeknexttxp_t) (hnddma_t *dmah); -typedef void *(*di_peeknextrxp_t) (hnddma_t *dmah); -typedef void (*di_rxparam_get_t) (hnddma_t *dmah, u16 *rxoffset, +typedef void *(*di_getpos_t) (struct hnddma_pub *di, bool direction); +typedef void (*di_fifoloopbackenable_t) (struct hnddma_pub *dmah); +typedef bool(*di_txstopped_t) (struct hnddma_pub *dmah); +typedef bool(*di_rxstopped_t) (struct hnddma_pub *dmah); +typedef bool(*di_rxenable_t) (struct hnddma_pub *dmah); +typedef bool(*di_rxenabled_t) (struct hnddma_pub *dmah); +typedef void *(*di_rx_t) (struct hnddma_pub *dmah); +typedef bool(*di_rxfill_t) (struct hnddma_pub *dmah); +typedef void (*di_txreclaim_t) (struct hnddma_pub *dmah, txd_range_t range); +typedef void (*di_rxreclaim_t) (struct hnddma_pub *dmah); +typedef unsigned long (*di_getvar_t) (struct hnddma_pub *dmah, + const char *name); +typedef void *(*di_getnexttxp_t) (struct hnddma_pub *dmah, txd_range_t range); +typedef void *(*di_getnextrxp_t) (struct hnddma_pub *dmah, bool forceall); +typedef void *(*di_peeknexttxp_t) (struct hnddma_pub *dmah); +typedef void *(*di_peeknextrxp_t) (struct hnddma_pub *dmah); +typedef void (*di_rxparam_get_t) (struct hnddma_pub *dmah, u16 *rxoffset, u16 *rxbufsize); -typedef void (*di_txblock_t) (hnddma_t *dmah); -typedef void (*di_txunblock_t) (hnddma_t *dmah); -typedef uint(*di_txactive_t) (hnddma_t *dmah); -typedef void (*di_txrotate_t) (hnddma_t *dmah); -typedef void (*di_counterreset_t) (hnddma_t *dmah); -typedef uint(*di_ctrlflags_t) (hnddma_t *dmah, uint mask, uint flags); -typedef char *(*di_dump_t) (hnddma_t *dmah, struct bcmstrbuf *b, +typedef void (*di_txblock_t) (struct hnddma_pub *dmah); +typedef void (*di_txunblock_t) (struct hnddma_pub *dmah); +typedef uint(*di_txactive_t) (struct hnddma_pub *dmah); +typedef void (*di_txrotate_t) (struct hnddma_pub *dmah); +typedef void (*di_counterreset_t) (struct hnddma_pub *dmah); +typedef uint(*di_ctrlflags_t) (struct hnddma_pub *dmah, uint mask, uint flags); +typedef char *(*di_dump_t) (struct hnddma_pub *dmah, struct bcmstrbuf *b, bool dumpring); -typedef char *(*di_dumptx_t) (hnddma_t *dmah, struct bcmstrbuf *b, +typedef char *(*di_dumptx_t) (struct hnddma_pub *dmah, struct bcmstrbuf *b, bool dumpring); -typedef char *(*di_dumprx_t) (hnddma_t *dmah, struct bcmstrbuf *b, +typedef char *(*di_dumprx_t) (struct hnddma_pub *dmah, struct bcmstrbuf *b, bool dumpring); -typedef uint(*di_rxactive_t) (hnddma_t *dmah); -typedef uint(*di_txpending_t) (hnddma_t *dmah); -typedef uint(*di_txcommitted_t) (hnddma_t *dmah); +typedef uint(*di_rxactive_t) (struct hnddma_pub *dmah); +typedef uint(*di_txpending_t) (struct hnddma_pub *dmah); +typedef uint(*di_txcommitted_t) (struct hnddma_pub *dmah); /* dma opsvec */ typedef struct di_fcn_s { @@ -141,7 +143,8 @@ struct hnddma_pub { uint txnobuf; /* tx out of dma descriptors */ }; -extern hnddma_t *dma_attach(struct osl_info *osh, char *name, si_t *sih, +extern struct hnddma_pub *dma_attach(struct osl_info *osh, char *name, + si_t *sih, void *dmaregstx, void *dmaregsrx, uint ntxd, uint nrxd, uint rxbufsize, int rxextheadroom, uint nrxpost, uint rxoffset, uint *msg_level); diff --git a/drivers/staging/brcm80211/sys/wlc_bmac.c b/drivers/staging/brcm80211/sys/wlc_bmac.c index 4042d5e9d205..dff4f6bf77e2 100644 --- a/drivers/staging/brcm80211/sys/wlc_bmac.c +++ b/drivers/staging/brcm80211/sys/wlc_bmac.c @@ -2295,7 +2295,7 @@ void wlc_bmac_hw_up(struct wlc_hw_info *wlc_hw) static bool wlc_dma_rxreset(struct wlc_hw_info *wlc_hw, uint fifo) { - hnddma_t *di = wlc_hw->di[fifo]; + struct hnddma_pub *di = wlc_hw->di[fifo]; struct osl_info *osh; if (D11REV_LT(wlc_hw->corerev, 12)) { diff --git a/drivers/staging/brcm80211/sys/wlc_mac80211.c b/drivers/staging/brcm80211/sys/wlc_mac80211.c index 11cc6539850c..32e7538e6d8a 100644 --- a/drivers/staging/brcm80211/sys/wlc_mac80211.c +++ b/drivers/staging/brcm80211/sys/wlc_mac80211.c @@ -6467,7 +6467,7 @@ void wlc_high_dpc(struct wlc_info *wlc, u32 macintstatus) static void *wlc_15420war(struct wlc_info *wlc, uint queue) { - hnddma_t *di; + struct hnddma_pub *di; void *p; ASSERT(queue < NFIFO); diff --git a/drivers/staging/brcm80211/sys/wlc_mac80211.h b/drivers/staging/brcm80211/sys/wlc_mac80211.h index 2054e346eab4..b8bfbe6ce71d 100644 --- a/drivers/staging/brcm80211/sys/wlc_mac80211.h +++ b/drivers/staging/brcm80211/sys/wlc_mac80211.h @@ -424,7 +424,7 @@ struct wlc_hw_info { struct wlc_info *wlc; /* fifo */ - hnddma_t *di[NFIFO]; /* hnddma handles, per fifo */ + struct hnddma_pub *di[NFIFO]; /* hnddma handles, per fifo */ uint unit; /* device instance number */ diff --git a/drivers/staging/brcm80211/sys/wlc_types.h b/drivers/staging/brcm80211/sys/wlc_types.h index 7e2e198334ca..175ef1e42af2 100644 --- a/drivers/staging/brcm80211/sys/wlc_types.h +++ b/drivers/staging/brcm80211/sys/wlc_types.h @@ -32,7 +32,7 @@ struct d11init; #ifndef _hnddma_pub_ #define _hnddma_pub_ -typedef const struct hnddma_pub hnddma_t; +struct hnddma_pub; #endif /* _hnddma_pub_ */ #endif /* _wlc_types_h_ */ diff --git a/drivers/staging/brcm80211/util/hnddma.c b/drivers/staging/brcm80211/util/hnddma.c index cf9e469af988..d08869239d5b 100644 --- a/drivers/staging/brcm80211/util/hnddma.c +++ b/drivers/staging/brcm80211/util/hnddma.c @@ -78,9 +78,7 @@ static uint dma_msg_level; /* dma engine software state */ typedef struct dma_info { - struct hnddma_pub hnddma; /* exported structure, don't use hnddma_t, - * which could be const - */ + struct hnddma_pub hnddma; /* exported structure */ uint *msg_level; /* message level pointer */ char name[MAXNAMEL]; /* callers name for diag msgs */ @@ -376,7 +374,7 @@ static const di_fcn_t dma32proc = { 39 }; -hnddma_t *dma_attach(struct osl_info *osh, char *name, si_t *sih, +struct hnddma_pub *dma_attach(struct osl_info *osh, char *name, si_t *sih, void *dmaregstx, void *dmaregsrx, uint ntxd, uint nrxd, uint rxbufsize, int rxextheadroom, uint nrxpost, uint rxoffset, uint *msg_level) @@ -578,7 +576,7 @@ hnddma_t *dma_attach(struct osl_info *osh, char *name, si_t *sih, } } - return (hnddma_t *) di; + return (struct hnddma_pub *) di; fail: _dma_detach(di); -- cgit v1.2.3 From f077f7185ce19adc234b96c6f9fb815301770c26 Mon Sep 17 00:00:00 2001 From: Roland Vossen Date: Tue, 7 Dec 2010 17:45:44 +0100 Subject: staging: brcm80211: replaced typedef wlcband_t by struct wlcband Code cleanup. Signed-off-by: Roland Vossen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/sys/wlc_alloc.c | 8 ++++---- drivers/staging/brcm80211/sys/wlc_channel.c | 6 +++--- drivers/staging/brcm80211/sys/wlc_mac80211.c | 11 ++++++----- drivers/staging/brcm80211/sys/wlc_mac80211.h | 9 +++++---- drivers/staging/brcm80211/sys/wlc_stf.c | 2 +- 5 files changed, 19 insertions(+), 17 deletions(-) diff --git a/drivers/staging/brcm80211/sys/wlc_alloc.c b/drivers/staging/brcm80211/sys/wlc_alloc.c index a568e978f6c6..09a1efd7b430 100644 --- a/drivers/staging/brcm80211/sys/wlc_alloc.c +++ b/drivers/staging/brcm80211/sys/wlc_alloc.c @@ -267,8 +267,8 @@ struct wlc_info *wlc_attach_malloc(struct osl_info *osh, uint unit, uint *err, goto fail; } - wlc->bandstate[0] = (wlcband_t *)wlc_calloc(osh, unit, - (sizeof(wlcband_t) * MAXBANDS)); + wlc->bandstate[0] = (struct wlcband *)wlc_calloc(osh, unit, + (sizeof(struct wlcband)*MAXBANDS)); if (wlc->bandstate[0] == NULL) { *err = 1025; goto fail; @@ -277,8 +277,8 @@ struct wlc_info *wlc_attach_malloc(struct osl_info *osh, uint unit, uint *err, for (i = 1; i < MAXBANDS; i++) { wlc->bandstate[i] = - (wlcband_t *) ((unsigned long)wlc->bandstate[0] + - (sizeof(wlcband_t) * i)); + (struct wlcband *) ((unsigned long)wlc->bandstate[0] + + (sizeof(struct wlcband)*i)); } } diff --git a/drivers/staging/brcm80211/sys/wlc_channel.c b/drivers/staging/brcm80211/sys/wlc_channel.c index e367ed4f1e91..741e13af7b67 100644 --- a/drivers/staging/brcm80211/sys/wlc_channel.c +++ b/drivers/staging/brcm80211/sys/wlc_channel.c @@ -905,7 +905,7 @@ wlc_channels_init(wlc_cm_info_t *wlc_cm, const country_info_t *country) { struct wlc_info *wlc = wlc_cm->wlc; uint i, j; - wlcband_t *band; + struct wlcband *band; const locale_info_t *li; chanvec_t sup_chan; const locale_mimo_info_t *li_mimo; @@ -1005,7 +1005,7 @@ void wlc_quiet_channels_reset(wlc_cm_info_t *wlc_cm) { struct wlc_info *wlc = wlc_cm->wlc; uint i, j; - wlcband_t *band; + struct wlcband *band; const chanvec_t *chanvec; memset(&wlc_cm->quiet_channels, 0, sizeof(chanvec_t)); @@ -1310,7 +1310,7 @@ wlc_channel_reg_limits(wlc_cm_info_t *wlc_cm, chanspec_t chanspec, int maxpwr; int delta; const country_info_t *country; - wlcband_t *band; + struct wlcband *band; const locale_info_t *li; int conducted_max; int conducted_ofdm_max; diff --git a/drivers/staging/brcm80211/sys/wlc_mac80211.c b/drivers/staging/brcm80211/sys/wlc_mac80211.c index 32e7538e6d8a..b25b5bd6a110 100644 --- a/drivers/staging/brcm80211/sys/wlc_mac80211.c +++ b/drivers/staging/brcm80211/sys/wlc_mac80211.c @@ -233,7 +233,7 @@ static u16 BCMFASTPATH wlc_d11hdrs_mac80211(struct wlc_info *wlc, static void wlc_bss_default_init(struct wlc_info *wlc); static void wlc_ucode_mac_upd(struct wlc_info *wlc); static ratespec_t mac80211_wlc_set_nrate(struct wlc_info *wlc, - wlcband_t *cur_band, u32 int_val); + struct wlcband *cur_band, u32 int_val); static void wlc_tx_prec_map_init(struct wlc_info *wlc); static void wlc_watchdog(void *arg); static void wlc_watchdog_by_timer(void *arg); @@ -2764,7 +2764,7 @@ int wlc_set_gmode(struct wlc_info *wlc, u8 gmode, bool config) bool preamble_restrict = false; /* Restrict association to stations that support short * preambles */ - wlcband_t *band; + struct wlcband *band; /* if N-support is enabled, allow Gmode set as long as requested * Gmode is not GMODE_LEGACY_B @@ -7480,7 +7480,7 @@ bool wlc_valid_rate(struct wlc_info *wlc, ratespec_t rspec, int band, static void wlc_update_mimo_band_bwcap(struct wlc_info *wlc, u8 bwcap) { uint i; - wlcband_t *band; + struct wlcband *band; for (i = 0; i < NBANDS(wlc); i++) { if (IS_SINGLEBAND_5G(wlc->deviceid)) @@ -7901,7 +7901,7 @@ void wlc_default_rateset(struct wlc_info *wlc, wlc_rateset_t *rs) static void wlc_bss_default_init(struct wlc_info *wlc) { chanspec_t chanspec; - wlcband_t *band; + struct wlcband *band; wlc_bss_info_t *bi = wlc->default_bss; /* init default and target BSS with some sane initial values */ @@ -7962,7 +7962,8 @@ wlc_uint64_sub(u32 *a_high, u32 *a_low, u32 b_high, u32 b_low) } static ratespec_t -mac80211_wlc_set_nrate(struct wlc_info *wlc, wlcband_t *cur_band, u32 int_val) +mac80211_wlc_set_nrate(struct wlc_info *wlc, struct wlcband *cur_band, + u32 int_val) { u8 stf = (int_val & NRATE_STF_MASK) >> NRATE_STF_SHIFT; u8 rate = int_val & NRATE_RATE_MASK; diff --git a/drivers/staging/brcm80211/sys/wlc_mac80211.h b/drivers/staging/brcm80211/sys/wlc_mac80211.h index b8bfbe6ce71d..acd854886df6 100644 --- a/drivers/staging/brcm80211/sys/wlc_mac80211.h +++ b/drivers/staging/brcm80211/sys/wlc_mac80211.h @@ -315,7 +315,7 @@ typedef struct wlccore { /* * band state (phy+ana+radio) */ -typedef struct wlcband { +struct wlcband { int bandtype; /* WLC_BAND_2G, WLC_BAND_5G */ uint bandunit; /* bandstate[] index */ @@ -344,7 +344,7 @@ typedef struct wlcband { u16 CWmin; /* The minimum size of contention window, in unit of aSlotTime */ u16 CWmax; /* The maximum size of contention window, in unit of aSlotTime */ u16 bcntsfoff; /* beacon tsf offset */ -} wlcband_t; +}; /* generic function callback takes just one arg */ typedef void (*cb_fn_t) (void *); @@ -533,9 +533,10 @@ struct wlc_info { /* multiband */ wlccore_t *core; /* pointer to active io core */ - wlcband_t *band; /* pointer to active per-band state */ + struct wlcband *band; /* pointer to active per-band state */ wlccore_t *corestate; /* per-core state (one per hw core) */ - wlcband_t *bandstate[MAXBANDS]; /* per-band state (one per phy/radio) */ + /* per-band state (one per phy/radio): */ + struct wlcband *bandstate[MAXBANDS]; bool war16165; /* PCI slow clock 16165 war flag */ diff --git a/drivers/staging/brcm80211/sys/wlc_stf.c b/drivers/staging/brcm80211/sys/wlc_stf.c index ee090746b088..01ac0d2b3cdb 100644 --- a/drivers/staging/brcm80211/sys/wlc_stf.c +++ b/drivers/staging/brcm80211/sys/wlc_stf.c @@ -371,7 +371,7 @@ int wlc_stf_rxchain_set(struct wlc_info *wlc, s32 int_val) } /* update wlc->stf->ss_opmode which represents the operational stf_ss mode we're using */ -int wlc_stf_ss_update(struct wlc_info *wlc, wlcband_t *band) +int wlc_stf_ss_update(struct wlc_info *wlc, struct wlcband *band) { int ret_code = 0; u8 prev_stf_ss; -- cgit v1.2.3 From c41c858f695b6626e2fc0729edc0dd26b091f354 Mon Sep 17 00:00:00 2001 From: Roland Vossen Date: Tue, 7 Dec 2010 17:45:45 +0100 Subject: staging: brcm80211: replaced typedef wlccore_t by struct wlccore Code cleanup Signed-off-by: Roland Vossen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/sys/wlc_alloc.c | 3 ++- drivers/staging/brcm80211/sys/wlc_mac80211.h | 8 ++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/drivers/staging/brcm80211/sys/wlc_alloc.c b/drivers/staging/brcm80211/sys/wlc_alloc.c index 09a1efd7b430..7d04d532a024 100644 --- a/drivers/staging/brcm80211/sys/wlc_alloc.c +++ b/drivers/staging/brcm80211/sys/wlc_alloc.c @@ -282,7 +282,8 @@ struct wlc_info *wlc_attach_malloc(struct osl_info *osh, uint unit, uint *err, } } - wlc->corestate = (wlccore_t *)wlc_calloc(osh, unit, sizeof(wlccore_t)); + wlc->corestate = (struct wlccore *)wlc_calloc(osh, unit, + sizeof(struct wlccore)); if (wlc->corestate == NULL) { *err = 1026; goto fail; diff --git a/drivers/staging/brcm80211/sys/wlc_mac80211.h b/drivers/staging/brcm80211/sys/wlc_mac80211.h index acd854886df6..ba2b953800e3 100644 --- a/drivers/staging/brcm80211/sys/wlc_mac80211.h +++ b/drivers/staging/brcm80211/sys/wlc_mac80211.h @@ -302,7 +302,7 @@ typedef struct wlc_stf { /* * core state (mac) */ -typedef struct wlccore { +struct wlccore { uint coreidx; /* # sb enumerated core */ /* fifo */ @@ -310,7 +310,7 @@ typedef struct wlccore { s16 txpktpend[NFIFO]; /* tx admission control */ macstat_t *macstat_snapshot; /* mac hw prev read values */ -} wlccore_t; +}; /* * band state (phy+ana+radio) @@ -532,9 +532,9 @@ struct wlc_info { bool clk; /* core is out of reset and has clock */ /* multiband */ - wlccore_t *core; /* pointer to active io core */ + struct wlccore *core; /* pointer to active io core */ struct wlcband *band; /* pointer to active per-band state */ - wlccore_t *corestate; /* per-core state (one per hw core) */ + struct wlccore *corestate; /* per-core state (one per hw core) */ /* per-band state (one per phy/radio): */ struct wlcband *bandstate[MAXBANDS]; -- cgit v1.2.3 From 08db27dc8d829e6df007cd079fdfa83584f66544 Mon Sep 17 00:00:00 2001 From: Roland Vossen Date: Tue, 7 Dec 2010 17:45:46 +0100 Subject: staging: brcm80211: replaced typedef wlc_pub_t by struct wlc_pub Code cleanup Signed-off-by: Roland Vossen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/sys/wl_mac80211.h | 2 +- drivers/staging/brcm80211/sys/wlc_alloc.c | 18 +++++++++--------- drivers/staging/brcm80211/sys/wlc_antsel.c | 4 ++-- drivers/staging/brcm80211/sys/wlc_antsel.h | 2 +- drivers/staging/brcm80211/sys/wlc_channel.c | 4 ++-- drivers/staging/brcm80211/sys/wlc_event.c | 5 +++-- drivers/staging/brcm80211/sys/wlc_event.h | 3 ++- drivers/staging/brcm80211/sys/wlc_mac80211.c | 10 +++++----- drivers/staging/brcm80211/sys/wlc_mac80211.h | 4 ++-- drivers/staging/brcm80211/sys/wlc_pub.h | 14 ++++++++------ 10 files changed, 35 insertions(+), 31 deletions(-) diff --git a/drivers/staging/brcm80211/sys/wl_mac80211.h b/drivers/staging/brcm80211/sys/wl_mac80211.h index 87a8128d1b3c..bb39b7705947 100644 --- a/drivers/staging/brcm80211/sys/wl_mac80211.h +++ b/drivers/staging/brcm80211/sys/wl_mac80211.h @@ -60,7 +60,7 @@ struct wl_firmware { }; struct wl_info { - wlc_pub_t *pub; /* pointer to public wlc state */ + struct wlc_pub *pub; /* pointer to public wlc state */ void *wlc; /* pointer to private common os-independent data */ struct osl_info *osh; /* pointer to os handler */ u32 magic; diff --git a/drivers/staging/brcm80211/sys/wlc_alloc.c b/drivers/staging/brcm80211/sys/wlc_alloc.c index 7d04d532a024..9af2d17a40c0 100644 --- a/drivers/staging/brcm80211/sys/wlc_alloc.c +++ b/drivers/staging/brcm80211/sys/wlc_alloc.c @@ -32,9 +32,9 @@ #include #include -static wlc_pub_t *wlc_pub_malloc(struct osl_info *osh, uint unit, uint *err, - uint devid); -static void wlc_pub_mfree(struct osl_info *osh, wlc_pub_t *pub); +static struct wlc_pub *wlc_pub_malloc(struct osl_info *osh, uint unit, + uint *err, uint devid); +static void wlc_pub_mfree(struct osl_info *osh, struct wlc_pub *pub); static void wlc_tunables_init(wlc_tunables_t *tunables, uint devid); void *wlc_calloc(struct osl_info *osh, uint unit, uint size) @@ -65,12 +65,12 @@ void wlc_tunables_init(wlc_tunables_t *tunables, uint devid) tunables->txsbnd = TXSBND; } -static wlc_pub_t *wlc_pub_malloc(struct osl_info *osh, uint unit, uint *err, - uint devid) +static struct wlc_pub *wlc_pub_malloc(struct osl_info *osh, uint unit, + uint *err, uint devid) { - wlc_pub_t *pub; + struct wlc_pub *pub; - pub = (wlc_pub_t *) wlc_calloc(osh, unit, sizeof(wlc_pub_t)); + pub = (struct wlc_pub *) wlc_calloc(osh, unit, sizeof(struct wlc_pub)); if (pub == NULL) { *err = 1001; goto fail; @@ -100,7 +100,7 @@ static wlc_pub_t *wlc_pub_malloc(struct osl_info *osh, uint unit, uint *err, return NULL; } -static void wlc_pub_mfree(struct osl_info *osh, wlc_pub_t *pub) +static void wlc_pub_mfree(struct osl_info *osh, struct wlc_pub *pub) { if (pub == NULL) return; @@ -179,7 +179,7 @@ struct wlc_info *wlc_attach_malloc(struct osl_info *osh, uint unit, uint *err, wlc->hwrxoff = WL_HWRXOFF; - /* allocate wlc_pub_t state structure */ + /* allocate struct wlc_pub state structure */ wlc->pub = wlc_pub_malloc(osh, unit, err, devid); if (wlc->pub == NULL) { *err = 1003; diff --git a/drivers/staging/brcm80211/sys/wlc_antsel.c b/drivers/staging/brcm80211/sys/wlc_antsel.c index aaf9985a1995..27558fa02ba7 100644 --- a/drivers/staging/brcm80211/sys/wlc_antsel.c +++ b/drivers/staging/brcm80211/sys/wlc_antsel.c @@ -96,8 +96,8 @@ const u8 mimo_2x3_div_antselid_tbl[16] = { struct antsel_info *wlc_antsel_attach(struct wlc_info *wlc, struct osl_info *osh, - wlc_pub_t *pub, - struct wlc_hw_info *wlc_hw) { + struct wlc_pub *pub, + struct wlc_hw_info *wlc_hw) { struct antsel_info *asi; asi = kzalloc(sizeof(struct antsel_info), GFP_ATOMIC); diff --git a/drivers/staging/brcm80211/sys/wlc_antsel.h b/drivers/staging/brcm80211/sys/wlc_antsel.h index ba38a2aedbd9..8875b5848665 100644 --- a/drivers/staging/brcm80211/sys/wlc_antsel.h +++ b/drivers/staging/brcm80211/sys/wlc_antsel.h @@ -18,7 +18,7 @@ #define _wlc_antsel_h_ extern struct antsel_info *wlc_antsel_attach(struct wlc_info *wlc, struct osl_info *osh, - wlc_pub_t *pub, + struct wlc_pub *pub, struct wlc_hw_info *wlc_hw); extern void wlc_antsel_detach(struct antsel_info *asi); extern void wlc_antsel_init(struct antsel_info *asi); diff --git a/drivers/staging/brcm80211/sys/wlc_channel.c b/drivers/staging/brcm80211/sys/wlc_channel.c index 741e13af7b67..33041e36585c 100644 --- a/drivers/staging/brcm80211/sys/wlc_channel.c +++ b/drivers/staging/brcm80211/sys/wlc_channel.c @@ -44,7 +44,7 @@ typedef struct wlc_cm_band { } wlc_cm_band_t; struct wlc_cm_info { - wlc_pub_t *pub; + struct wlc_pub *pub; struct wlc_info *wlc; char srom_ccode[WLC_CNTRY_BUF_SZ]; /* Country Code in SROM */ uint srom_regrev; /* Regulatory Rev for the SROM ccode */ @@ -611,7 +611,7 @@ wlc_cm_info_t *wlc_channel_mgr_attach(struct wlc_info *wlc) wlc_cm_info_t *wlc_cm; char country_abbrev[WLC_CNTRY_BUF_SZ]; const country_info_t *country; - wlc_pub_t *pub = wlc->pub; + struct wlc_pub *pub = wlc->pub; char *ccode; WL_TRACE(("wl%d: wlc_channel_mgr_attach\n", wlc->pub->unit)); diff --git a/drivers/staging/brcm80211/sys/wlc_event.c b/drivers/staging/brcm80211/sys/wlc_event.c index e4ab077bf87f..9b503d839aae 100644 --- a/drivers/staging/brcm80211/sys/wlc_event.c +++ b/drivers/staging/brcm80211/sys/wlc_event.c @@ -47,7 +47,7 @@ struct wlc_eventq { wlc_event_t *tail; struct wlc_info *wlc; void *wl; - wlc_pub_t *pub; + struct wlc_pub *pub; bool tpending; bool workpending; struct wl_timer *timer; @@ -58,7 +58,8 @@ struct wlc_eventq { /* * Export functions */ -wlc_eventq_t *wlc_eventq_attach(wlc_pub_t *pub, struct wlc_info *wlc, void *wl, +wlc_eventq_t *wlc_eventq_attach(struct wlc_pub *pub, struct wlc_info *wlc, + void *wl, wlc_eventq_cb_t cb) { wlc_eventq_t *eq; diff --git a/drivers/staging/brcm80211/sys/wlc_event.h b/drivers/staging/brcm80211/sys/wlc_event.h index 7c8e49550f2d..e75582dcdd93 100644 --- a/drivers/staging/brcm80211/sys/wlc_event.h +++ b/drivers/staging/brcm80211/sys/wlc_event.h @@ -21,7 +21,8 @@ typedef struct wlc_eventq wlc_eventq_t; typedef void (*wlc_eventq_cb_t) (void *arg); -extern wlc_eventq_t *wlc_eventq_attach(wlc_pub_t *pub, struct wlc_info *wlc, +extern wlc_eventq_t *wlc_eventq_attach(struct wlc_pub *pub, + struct wlc_info *wlc, void *wl, wlc_eventq_cb_t cb); extern int wlc_eventq_detach(wlc_eventq_t *eq); extern int wlc_eventq_down(wlc_eventq_t *eq); diff --git a/drivers/staging/brcm80211/sys/wlc_mac80211.c b/drivers/staging/brcm80211/sys/wlc_mac80211.c index b25b5bd6a110..eb4013dab36c 100644 --- a/drivers/staging/brcm80211/sys/wlc_mac80211.c +++ b/drivers/staging/brcm80211/sys/wlc_mac80211.c @@ -1697,7 +1697,7 @@ static uint wlc_attach_module(struct wlc_info *wlc) return err; } -wlc_pub_t *wlc_pub(void *wlc) +struct wlc_pub *wlc_pub(void *wlc) { return ((struct wlc_info *) wlc)->pub; } @@ -1714,7 +1714,7 @@ void *wlc_attach(void *wl, u16 vendor, u16 device, uint unit, bool piomode, struct wlc_info *wlc; uint err = 0; uint j; - wlc_pub_t *pub; + struct wlc_pub *pub; wlc_txq_info_t *qi; uint n_disabled; @@ -4309,7 +4309,7 @@ int wlc_iovar_gets8(struct wlc_info *wlc, const char *name, s8 *arg) * calling function must keep 'iovars' until wlc_module_unregister is called. * 'iovar' must have the last entry's name field being NULL as terminator. */ -int wlc_module_register(wlc_pub_t *pub, const bcm_iovar_t *iovars, +int wlc_module_register(struct wlc_pub *pub, const bcm_iovar_t *iovars, const char *name, void *hdl, iovar_fn_t i_fn, watchdog_fn_t w_fn, down_fn_t d_fn) { @@ -4339,7 +4339,7 @@ int wlc_module_register(wlc_pub_t *pub, const bcm_iovar_t *iovars, } /* unregister module callbacks */ -int wlc_module_unregister(wlc_pub_t *pub, const char *name, void *hdl) +int wlc_module_unregister(struct wlc_pub *pub, const char *name, void *hdl) { struct wlc_info *wlc = (struct wlc_info *) pub->wlc; int i; @@ -4455,7 +4455,7 @@ wlc_iovar_op(struct wlc_info *wlc, const char *name, } int -wlc_iovar_check(wlc_pub_t *pub, const bcm_iovar_t *vi, void *arg, int len, +wlc_iovar_check(struct wlc_pub *pub, const bcm_iovar_t *vi, void *arg, int len, bool set) { struct wlc_info *wlc = (struct wlc_info *) pub->wlc; diff --git a/drivers/staging/brcm80211/sys/wlc_mac80211.h b/drivers/staging/brcm80211/sys/wlc_mac80211.h index ba2b953800e3..d3def7448bf7 100644 --- a/drivers/staging/brcm80211/sys/wlc_mac80211.h +++ b/drivers/staging/brcm80211/sys/wlc_mac80211.h @@ -510,7 +510,7 @@ typedef struct wlc_txq_info { * Principal common (os-independent) software data structure. */ struct wlc_info { - wlc_pub_t *pub; /* pointer to wlc public state */ + struct wlc_pub *pub; /* pointer to wlc public state */ struct osl_info *osh; /* pointer to os handle */ struct wl_info *wl; /* pointer to os-specific private state */ d11regs_t *regs; /* pointer to device registers */ @@ -787,7 +787,7 @@ struct wlc_info { /* antsel module specific state */ struct antsel_info { struct wlc_info *wlc; /* pointer to main wlc structure */ - wlc_pub_t *pub; /* pointer to public fn */ + struct wlc_pub *pub; /* pointer to public fn */ u8 antsel_type; /* Type of boardlevel mimo antenna switch-logic * 0 = N/A, 1 = 2x4 board, 2 = 2x3 CB2 board */ diff --git a/drivers/staging/brcm80211/sys/wlc_pub.h b/drivers/staging/brcm80211/sys/wlc_pub.h index 80331e8a81ea..146a6904a39b 100644 --- a/drivers/staging/brcm80211/sys/wlc_pub.h +++ b/drivers/staging/brcm80211/sys/wlc_pub.h @@ -251,7 +251,7 @@ typedef int (*iovar_fn_t) (void *handle, const bcm_iovar_t *vi, * Public portion of "common" os-independent state structure. * The wlc handle points at this. */ -typedef struct wlc_pub { +struct wlc_pub { void *wlc; struct ieee80211_hw *ieee_hw; @@ -330,7 +330,7 @@ typedef struct wlc_pub { bool _lmacproto; /* lmac protocol module included and enabled */ bool phy_11ncapable; /* the PHY/HW is capable of 802.11N */ bool _ampdumac; /* mac assist ampdu enabled or not */ -} wlc_pub_t; +}; /* wl_monitor rx status per packet */ typedef struct wl_rxsts { @@ -528,7 +528,7 @@ extern void wlc_set_addrmatch(struct wlc_info *wlc, int match_reg_offset, extern void wlc_wme_setparams(struct wlc_info *wlc, u16 aci, void *arg, bool suspend); -extern wlc_pub_t *wlc_pub(void *wlc); +extern struct wlc_pub *wlc_pub(void *wlc); /* common functions for every port */ extern int wlc_bmac_up_prep(struct wlc_hw_info *wlc_hw); @@ -554,13 +554,15 @@ extern void wlc_scb_ratesel_init_all(struct wlc_info *wlc); /* ioctl */ extern int wlc_iovar_gets8(struct wlc_info *wlc, const char *name, s8 *arg); -extern int wlc_iovar_check(wlc_pub_t *pub, const bcm_iovar_t *vi, void *arg, +extern int wlc_iovar_check(struct wlc_pub *pub, const bcm_iovar_t *vi, + void *arg, int len, bool set); -extern int wlc_module_register(wlc_pub_t *pub, const bcm_iovar_t *iovars, +extern int wlc_module_register(struct wlc_pub *pub, const bcm_iovar_t *iovars, const char *name, void *hdl, iovar_fn_t iovar_fn, watchdog_fn_t watchdog_fn, down_fn_t down_fn); -extern int wlc_module_unregister(wlc_pub_t *pub, const char *name, void *hdl); +extern int wlc_module_unregister(struct wlc_pub *pub, const char *name, + void *hdl); extern void wlc_event_if(struct wlc_info *wlc, struct wlc_bsscfg *cfg, wlc_event_t *e, const struct ether_addr *addr); extern void wlc_suspend_mac_and_wait(struct wlc_info *wlc); -- cgit v1.2.3 From baffa2f609863b879703c4b757d63558b2caebdb Mon Sep 17 00:00:00 2001 From: Roland Vossen Date: Wed, 8 Dec 2010 20:16:02 +0100 Subject: staging: brcm80211: removed unused struct wlc_ap_info Code cleanup, reaction on the email from Dan Carpenter. Signed-off-by: Roland Vossen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/sys/wlc_mac80211.h | 2 -- drivers/staging/brcm80211/sys/wlc_types.h | 1 - 2 files changed, 3 deletions(-) diff --git a/drivers/staging/brcm80211/sys/wlc_mac80211.h b/drivers/staging/brcm80211/sys/wlc_mac80211.h index d3def7448bf7..5df996b78911 100644 --- a/drivers/staging/brcm80211/sys/wlc_mac80211.h +++ b/drivers/staging/brcm80211/sys/wlc_mac80211.h @@ -753,8 +753,6 @@ struct wlc_info { ac_bitmap_t apsd_trigger_ac; /* Permissible Acess Category in which APSD Null * Trigger frames can be send */ - struct wlc_ap_info *ap; - u8 htphy_membership; /* HT PHY membership */ bool _regulatory_domain; /* 802.11d enabled? */ diff --git a/drivers/staging/brcm80211/sys/wlc_types.h b/drivers/staging/brcm80211/sys/wlc_types.h index 175ef1e42af2..df6e04c6ac58 100644 --- a/drivers/staging/brcm80211/sys/wlc_types.h +++ b/drivers/staging/brcm80211/sys/wlc_types.h @@ -24,7 +24,6 @@ struct wlc_hw_info; struct wlc_if; struct wl_if; struct ampdu_info; -struct wlc_ap_info; struct antsel_info; struct bmac_pmq; -- cgit v1.2.3 From 818c07b894df8c3a6399800bcc632569cbc1e70a Mon Sep 17 00:00:00 2001 From: Henry Ptasinski Date: Wed, 8 Dec 2010 13:09:49 -0800 Subject: MAINTAINERS: update the entry for the BRCM80211 driver This time with Signed-off-by ... Removed Nohee, added Roland, Arend and Dowan. Changes were previously made to drivers/staging/brcm80211{README,TODO}, but MAINTAINERS was missed. Signed-off-by: Henry Ptasinski Signed-off-by: Greg Kroah-Hartman --- MAINTAINERS | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index 1a1c27b9c557..fdb41370dbf5 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1394,7 +1394,9 @@ F: drivers/net/tg3.* BROADCOM BRCM80211 IEEE802.11n WIRELESS DRIVER M: Brett Rudley M: Henry Ptasinski -M: Nohee Ko +M: Dowan Kim +M: Roland Vossen +M: Arend van Spriel L: linux-wireless@vger.kernel.org S: Supported F: drivers/staging/brcm80211/ -- cgit v1.2.3 From fb657461abf6842b8f7603370ff349f42814ac5b Mon Sep 17 00:00:00 2001 From: Henry Ptasinski Date: Wed, 8 Dec 2010 13:18:04 -0800 Subject: staging: brcm80211: fix documentation on installing firmware Fix the documentation to have the current firmware filenames and use the correct path. Signed-off-by: Henry Ptasinski Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/README | 10 ++-------- drivers/staging/brcm80211/brcmfmac/README | 5 +++-- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/drivers/staging/brcm80211/README b/drivers/staging/brcm80211/README index a27bb0b4f581..99e67669f26b 100644 --- a/drivers/staging/brcm80211/README +++ b/drivers/staging/brcm80211/README @@ -43,14 +43,8 @@ Firmware is available from the Linux firmware repository at: http://git.kernel.org/?p=linux/kernel/git/dwmw2/linux-firmware.git https://git.kernel.org/?p=linux/kernel/git/dwmw2/linux-firmware.git -For all chips, copy brcm/bcm43xx-0-610-809-0.fw and -brcm/bcm43xx_hdr-0-610-809-0.fw to /lib/firmware/brcm (or wherever firmware is -normally installed on the system). In the /lib/firmware/brcm directory, then -create the following symlinks: - - ln -s bcm43xx-0-610-809-0.fw bcm43xx-0.fw - ln -s bcm43xx_hdr-0-610-809-0.fw bcm43xx_hdr-0.fw - +For all chips, copy brcm/bcm43xx-0.fw and brcm/bcm43xx_hdr-0.fw to +/lib/firmware/brcm (or wherever firmware is normally installed on your system). Currently supported chips ============== diff --git a/drivers/staging/brcm80211/brcmfmac/README b/drivers/staging/brcm80211/brcmfmac/README index 43601fa8b17e..be29e4236920 100644 --- a/drivers/staging/brcm80211/brcmfmac/README +++ b/drivers/staging/brcm80211/brcmfmac/README @@ -25,8 +25,9 @@ Firmware is available from the Linux firmware repository at: http://git.kernel.org/?p=linux/kernel/git/dwmw2/linux-firmware.git https://git.kernel.org/?p=linux/kernel/git/dwmw2/linux-firmware.git -For 4329 chip, copy brcm/bcm4329-fullmac-4-218-248-5.bin and -bcm4329-fullmac-4-218-248-5.txt to /lib/firmware/brcm +For 4329 chip, copy brcm/bcm4329-fullmac-4.bin and brcm/bcm4329-fullmac-4.txt +to /lib/firmware/brcm (or wherever firmware is normally installed on your +system). Contact Info: ============= -- cgit v1.2.3 From 597a1e7cccc9a5a0c47629267ac4b23bf8654578 Mon Sep 17 00:00:00 2001 From: Peter Huewe Date: Tue, 7 Dec 2010 23:38:02 +0100 Subject: staging/line6: Fix sparse warning 'Using plain integer as NULL pointer' This patch fixes the warning generated by sparse: "Using plain integer as NULL pointer" by replacing the offending 0s with NULL. Signed-off-by: Peter Huewe Signed-off-by: Greg Kroah-Hartman --- drivers/staging/line6/capture.c | 2 +- drivers/staging/line6/midi.c | 4 ++-- drivers/staging/line6/playback.c | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/drivers/staging/line6/capture.c b/drivers/staging/line6/capture.c index 1e3bb1406331..9647154a4923 100644 --- a/drivers/staging/line6/capture.c +++ b/drivers/staging/line6/capture.c @@ -147,7 +147,7 @@ void line6_capture_copy(struct snd_line6_pcm *line6pcm, char *fbuf, int fsize) const int bytes_per_frame = line6pcm->properties->bytes_per_frame; int frames = fsize / bytes_per_frame; - if (runtime == 0) + if (runtime == NULL) return; if (line6pcm->pos_in_done + frames > runtime->buffer_size) { diff --git a/drivers/staging/line6/midi.c b/drivers/staging/line6/midi.c index ab67e889d2c4..e554a2da643a 100644 --- a/drivers/staging/line6/midi.c +++ b/drivers/staging/line6/midi.c @@ -127,7 +127,7 @@ static int send_midi_async(struct usb_line6 *line6, unsigned char *data, urb = usb_alloc_urb(0, GFP_ATOMIC); - if (urb == 0) { + if (urb == NULL) { dev_err(line6->ifcdev, "Out of memory\n"); return -ENOMEM; } @@ -137,7 +137,7 @@ static int send_midi_async(struct usb_line6 *line6, unsigned char *data, transfer_buffer = kmalloc(length, GFP_ATOMIC); - if (transfer_buffer == 0) { + if (transfer_buffer == NULL) { usb_free_urb(urb); dev_err(line6->ifcdev, "Out of memory\n"); return -ENOMEM; diff --git a/drivers/staging/line6/playback.c b/drivers/staging/line6/playback.c index 29940fd1671b..10c543836583 100644 --- a/drivers/staging/line6/playback.c +++ b/drivers/staging/line6/playback.c @@ -246,7 +246,7 @@ static int submit_audio_out_urb(struct snd_line6_pcm *line6pcm) change_volume(urb_out, line6pcm->volume_playback, bytes_per_frame); - if (line6pcm->prev_fbuf != 0) { + if (line6pcm->prev_fbuf != NULL) { #ifdef CONFIG_LINE6_USB_IMPULSE_RESPONSE if (line6pcm->flags & MASK_PCM_IMPULSE) { create_impulse_test_signal(line6pcm, urb_out, -- cgit v1.2.3 From be3e5b32462790b91c14d5869fbabaf5bfe7c901 Mon Sep 17 00:00:00 2001 From: Peter Huewe Date: Tue, 7 Dec 2010 23:44:33 +0100 Subject: staging/zram: Fix sparse warning 'Using plain integer as NULL pointer' This patch fixes the warning generated by sparse: "Using plain integer as NULL pointer" by replacing the offending 0s with NULL. Signed-off-by: Peter Huewe Signed-off-by: Greg Kroah-Hartman --- drivers/staging/zram/xvmalloc.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/zram/xvmalloc.c b/drivers/staging/zram/xvmalloc.c index 3fdbb8ada827..b64406739d05 100644 --- a/drivers/staging/zram/xvmalloc.c +++ b/drivers/staging/zram/xvmalloc.c @@ -187,7 +187,7 @@ static void insert_block(struct xv_pool *pool, struct page *page, u32 offset, slindex = get_index_for_insert(block->size); flindex = slindex / BITS_PER_LONG; - block->link.prev_page = 0; + block->link.prev_page = NULL; block->link.prev_offset = 0; block->link.next_page = pool->freelist[slindex].page; block->link.next_offset = pool->freelist[slindex].offset; @@ -217,7 +217,7 @@ static void remove_block_head(struct xv_pool *pool, pool->freelist[slindex].page = block->link.next_page; pool->freelist[slindex].offset = block->link.next_offset; - block->link.prev_page = 0; + block->link.prev_page = NULL; block->link.prev_offset = 0; if (!pool->freelist[slindex].page) { @@ -232,7 +232,7 @@ static void remove_block_head(struct xv_pool *pool, */ tmpblock = get_ptr_atomic(pool->freelist[slindex].page, pool->freelist[slindex].offset, KM_USER1); - tmpblock->link.prev_page = 0; + tmpblock->link.prev_page = NULL; tmpblock->link.prev_offset = 0; put_ptr_atomic(tmpblock, KM_USER1); } -- cgit v1.2.3 From b3c73856ae47d43d0d181f9de1c1c6c0820c4515 Mon Sep 17 00:00:00 2001 From: Nishanth Aravamudan Date: Mon, 18 Oct 2010 07:27:04 +0000 Subject: powerpc/iommu: Use coherent_dma_mask for alloc_coherent The IOMMU code has been passing the dma-mask instead of the coherent_dma_mask to the iommu allocator. Coherent allocations should be made using the coherent_dma_mask. Also update the vio code to ensure the coherent_dma_mask is set. Without this change drivers, such as ibmvscsi, fail to load with the corrected dma_iommu_alloc_coherent(). Signed-off-by: Milton Miller Signed-off-by: Nishanth Aravamudan Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/dma-iommu.c | 2 +- arch/powerpc/kernel/vio.c | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/arch/powerpc/kernel/dma-iommu.c b/arch/powerpc/kernel/dma-iommu.c index 6e54a0fd31aa..e7554154a6de 100644 --- a/arch/powerpc/kernel/dma-iommu.c +++ b/arch/powerpc/kernel/dma-iommu.c @@ -19,7 +19,7 @@ static void *dma_iommu_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, gfp_t flag) { return iommu_alloc_coherent(dev, get_iommu_table_base(dev), size, - dma_handle, device_to_mask(dev), flag, + dma_handle, dev->coherent_dma_mask, flag, dev_to_node(dev)); } diff --git a/arch/powerpc/kernel/vio.c b/arch/powerpc/kernel/vio.c index b2654058f2e4..1b695fdc362b 100644 --- a/arch/powerpc/kernel/vio.c +++ b/arch/powerpc/kernel/vio.c @@ -1257,6 +1257,10 @@ struct vio_dev *vio_register_device_node(struct device_node *of_node) viodev->dev.parent = &vio_bus_device.dev; viodev->dev.bus = &vio_bus_type; viodev->dev.release = vio_dev_release; + /* needed to ensure proper operation of coherent allocations + * later, in case driver doesn't set it explicitly */ + dma_set_mask(&viodev->dev, DMA_BIT_MASK(64)); + dma_set_coherent_mask(&viodev->dev, DMA_BIT_MASK(64)); /* register with generic device framework */ if (device_register(&viodev->dev)) { -- cgit v1.2.3 From 7372cfb88f71ed975c8588d1ca5ecc8bb9ec7c7b Mon Sep 17 00:00:00 2001 From: Nishanth Aravamudan Date: Tue, 26 Oct 2010 17:35:13 +0000 Subject: powerpc/pseries: Do not search for dma-window property on dlpar remove The iommu_table pointer in the pci auxiliary struct of device_node has not been used by the iommu ops since the dma refactor of 12d04eef927bf61328af2c7cbe756c96f98ac3bf, however this code still uses it to find tables for dlpar. By only setting the PCI_DN iommu_table pointer on nodes with dma window properties, we will be able to quickly find the node for later checks, and can remove the table without looking for the the dma window property on dlpar remove. Signed-off-by: Milton Miller Signed-off-by: Nishanth Aravamudan Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/platforms/pseries/iommu.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c index 9fecb313a4c9..0dbadbb34f3a 100644 --- a/arch/powerpc/platforms/pseries/iommu.c +++ b/arch/powerpc/platforms/pseries/iommu.c @@ -455,9 +455,6 @@ static void pci_dma_bus_setup_pSeriesLP(struct pci_bus *bus) ppci->iommu_table = iommu_init_table(tbl, ppci->phb->node); pr_debug(" created table: %p\n", ppci->iommu_table); } - - if (pdn != dn) - PCI_DN(dn)->iommu_table = ppci->iommu_table; } @@ -571,8 +568,7 @@ static int iommu_reconfig_notifier(struct notifier_block *nb, unsigned long acti switch (action) { case PSERIES_RECONFIG_REMOVE: - if (pci && pci->iommu_table && - of_get_property(np, "ibm,dma-window", NULL)) + if (pci && pci->iommu_table) iommu_free_table(pci->iommu_table, np->full_name); break; default: -- cgit v1.2.3 From f4133236d6473072b5982c1182991eade6ff5bae Mon Sep 17 00:00:00 2001 From: Nishanth Aravamudan Date: Tue, 26 Oct 2010 17:35:14 +0000 Subject: powerpc/pseries: Checking for pdn->parent is redundant The device tree root is never a pci bus, and will not have a PCI_DN(pdn), so the check for PCI_DN added in 650f7b3b2f0ead0673e90452cf3dedde97c537ba makes the check for pdn->parent redundant and it can be removed. Signed-off-by: Milton Miller Signed-off-by: Nishanth Aravamudan Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/platforms/pseries/iommu.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c index 0dbadbb34f3a..dae3f8847117 100644 --- a/arch/powerpc/platforms/pseries/iommu.c +++ b/arch/powerpc/platforms/pseries/iommu.c @@ -530,10 +530,7 @@ static void pci_dma_dev_setup_pSeriesLP(struct pci_dev *dev) } pr_debug(" parent is %s\n", pdn->full_name); - /* Check for parent == NULL so we don't try to setup the empty EADS - * slots on POWER4 machines. - */ - if (dma_window == NULL || pdn->parent == NULL) { + if (dma_window == NULL) { pr_debug(" no dma window for device, linking to parent\n"); set_iommu_table_base(&dev->dev, PCI_DN(pdn)->iommu_table); return; -- cgit v1.2.3 From 4af2da25ede8af6536254e92b6ed5c4026105870 Mon Sep 17 00:00:00 2001 From: Nishanth Aravamudan Date: Tue, 26 Oct 2010 17:35:15 +0000 Subject: powerpc/pseries: Do not need to check for dma_window == NULL The block in pci_dma_dev_setup_pSeriesLP for dma_window == NULL can be removed because we will only teminate the loop if we had already allocated a iommu table for that node or we found a window. While there may be no window for the device, the intresting part is if we are reusing a table or creating it for the first device under it. Signed-off-by: Milton Miller Signed-off-by: Nishanth Aravamudan Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/platforms/pseries/iommu.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c index dae3f8847117..0c1958ac1011 100644 --- a/arch/powerpc/platforms/pseries/iommu.c +++ b/arch/powerpc/platforms/pseries/iommu.c @@ -530,12 +530,6 @@ static void pci_dma_dev_setup_pSeriesLP(struct pci_dev *dev) } pr_debug(" parent is %s\n", pdn->full_name); - if (dma_window == NULL) { - pr_debug(" no dma window for device, linking to parent\n"); - set_iommu_table_base(&dev->dev, PCI_DN(pdn)->iommu_table); - return; - } - pci = PCI_DN(pdn); if (!pci->iommu_table) { tbl = kzalloc_node(sizeof(struct iommu_table), GFP_KERNEL, -- cgit v1.2.3 From b8c49def6d73321724bab66dd30526744b482f0a Mon Sep 17 00:00:00 2001 From: Benjamin Herrenschmidt Date: Thu, 9 Dec 2010 15:24:01 +1100 Subject: powerpc/pseries: Pass phb only to iommu_table_setparms_lpar iommu_table_setparms_lpar needs either the phb or the subbusnumber (not both), pass the phb to make it similar to iommu_table_setparms. Note: In cases where a caller was passing bus->number previously to iommu_table_setparms_lpar() rather than phb->bus->number, this can lead to a different value in tbl->it_busno. The only example of this was the removed pci_dma_dev_setup_pSeriesLP(), removed in "ppc/iommu: remove unneeded pci_dma_dev_setup_pSeriesLP". [BenH: You updated only one of the two callers. Fixed that for you] Signed-off-by: Milton Miller Signed-off-by: Nishanth Aravamudan Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/platforms/pseries/iommu.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c index 0c1958ac1011..edea60b7ee90 100644 --- a/arch/powerpc/platforms/pseries/iommu.c +++ b/arch/powerpc/platforms/pseries/iommu.c @@ -323,14 +323,13 @@ static void iommu_table_setparms(struct pci_controller *phb, static void iommu_table_setparms_lpar(struct pci_controller *phb, struct device_node *dn, struct iommu_table *tbl, - const void *dma_window, - int bussubno) + const void *dma_window) { unsigned long offset, size; - tbl->it_busno = bussubno; of_parse_dma_window(dn, dma_window, &tbl->it_index, &offset, &size); + tbl->it_busno = phb->bus->number; tbl->it_base = 0; tbl->it_blocksize = 16; tbl->it_type = TCE_PCI; @@ -450,8 +449,7 @@ static void pci_dma_bus_setup_pSeriesLP(struct pci_bus *bus) if (!ppci->iommu_table) { tbl = kzalloc_node(sizeof(struct iommu_table), GFP_KERNEL, ppci->phb->node); - iommu_table_setparms_lpar(ppci->phb, pdn, tbl, dma_window, - bus->number); + iommu_table_setparms_lpar(ppci->phb, pdn, tbl, dma_window); ppci->iommu_table = iommu_init_table(tbl, ppci->phb->node); pr_debug(" created table: %p\n", ppci->iommu_table); } @@ -534,8 +532,7 @@ static void pci_dma_dev_setup_pSeriesLP(struct pci_dev *dev) if (!pci->iommu_table) { tbl = kzalloc_node(sizeof(struct iommu_table), GFP_KERNEL, pci->phb->node); - iommu_table_setparms_lpar(pci->phb, pdn, tbl, dma_window, - pci->phb->bus->number); + iommu_table_setparms_lpar(pci->phb, pdn, tbl, dma_window); pci->iommu_table = iommu_init_table(tbl, pci->phb->node); pr_debug(" created table: %p\n", pci->iommu_table); } else { -- cgit v1.2.3 From b5f9b6665b70b4c844bed5452f6a14743eefa57c Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Tue, 7 Dec 2010 19:58:17 +0000 Subject: powerpc: Hardcode popcnt instructions for old assemblers The popcnt instructions went into binutils relatively recently. As with a number of other instructions, create macros and hardcode them. Signed-off-by: Anton Blanchard Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/include/asm/ppc-opcode.h | 8 ++++++++ arch/powerpc/lib/hweight_64.S | 14 +++++++------- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/arch/powerpc/include/asm/ppc-opcode.h b/arch/powerpc/include/asm/ppc-opcode.h index 43adc8b819ed..1255569387b6 100644 --- a/arch/powerpc/include/asm/ppc-opcode.h +++ b/arch/powerpc/include/asm/ppc-opcode.h @@ -36,6 +36,8 @@ #define PPC_INST_NOP 0x60000000 #define PPC_INST_POPCNTB 0x7c0000f4 #define PPC_INST_POPCNTB_MASK 0xfc0007fe +#define PPC_INST_POPCNTD 0x7c0003f4 +#define PPC_INST_POPCNTW 0x7c0002f4 #define PPC_INST_RFCI 0x4c000066 #define PPC_INST_RFDI 0x4c00004e #define PPC_INST_RFMCI 0x4c00004c @@ -88,6 +90,12 @@ __PPC_RB(b) | __PPC_EH(eh)) #define PPC_MSGSND(b) stringify_in_c(.long PPC_INST_MSGSND | \ __PPC_RB(b)) +#define PPC_POPCNTB(a, s) stringify_in_c(.long PPC_INST_POPCNTB | \ + __PPC_RA(a) | __PPC_RS(s)) +#define PPC_POPCNTD(a, s) stringify_in_c(.long PPC_INST_POPCNTD | \ + __PPC_RA(a) | __PPC_RS(s)) +#define PPC_POPCNTW(a, s) stringify_in_c(.long PPC_INST_POPCNTW | \ + __PPC_RA(a) | __PPC_RS(s)) #define PPC_RFCI stringify_in_c(.long PPC_INST_RFCI) #define PPC_RFDI stringify_in_c(.long PPC_INST_RFDI) #define PPC_RFMCI stringify_in_c(.long PPC_INST_RFMCI) diff --git a/arch/powerpc/lib/hweight_64.S b/arch/powerpc/lib/hweight_64.S index ee2320bb5ddf..fda27868cf8c 100644 --- a/arch/powerpc/lib/hweight_64.S +++ b/arch/powerpc/lib/hweight_64.S @@ -28,7 +28,7 @@ BEGIN_FTR_SECTION nop nop FTR_SECTION_ELSE - popcntb r3,r3 + PPC_POPCNTB(r3,r3) clrldi r3,r3,64-8 blr ALT_FTR_SECTION_END_IFCLR(CPU_FTR_POPCNTB) @@ -42,14 +42,14 @@ BEGIN_FTR_SECTION nop FTR_SECTION_ELSE BEGIN_FTR_SECTION_NESTED(50) - popcntb r3,r3 + PPC_POPCNTB(r3,r3) srdi r4,r3,8 add r3,r4,r3 clrldi r3,r3,64-8 blr FTR_SECTION_ELSE_NESTED(50) clrlwi r3,r3,16 - popcntw r3,r3 + PPC_POPCNTW(r3,r3) clrldi r3,r3,64-8 blr ALT_FTR_SECTION_END_NESTED_IFCLR(CPU_FTR_POPCNTD, 50) @@ -66,7 +66,7 @@ BEGIN_FTR_SECTION nop FTR_SECTION_ELSE BEGIN_FTR_SECTION_NESTED(51) - popcntb r3,r3 + PPC_POPCNTB(r3,r3) srdi r4,r3,16 add r3,r4,r3 srdi r4,r3,8 @@ -74,7 +74,7 @@ FTR_SECTION_ELSE clrldi r3,r3,64-8 blr FTR_SECTION_ELSE_NESTED(51) - popcntw r3,r3 + PPC_POPCNTW(r3,r3) clrldi r3,r3,64-8 blr ALT_FTR_SECTION_END_NESTED_IFCLR(CPU_FTR_POPCNTD, 51) @@ -93,7 +93,7 @@ BEGIN_FTR_SECTION nop FTR_SECTION_ELSE BEGIN_FTR_SECTION_NESTED(52) - popcntb r3,r3 + PPC_POPCNTB(r3,r3) srdi r4,r3,32 add r3,r4,r3 srdi r4,r3,16 @@ -103,7 +103,7 @@ FTR_SECTION_ELSE clrldi r3,r3,64-8 blr FTR_SECTION_ELSE_NESTED(52) - popcntd r3,r3 + PPC_POPCNTD(r3,r3) clrldi r3,r3,64-8 blr ALT_FTR_SECTION_END_NESTED_IFCLR(CPU_FTR_POPCNTD, 52) -- cgit v1.2.3 From 8f4da26e9bf89f54b68d5cc3f3596f45e5f43911 Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Wed, 8 Dec 2010 00:55:03 +0000 Subject: powerpc: Fix incorrect comment about interrupt stack allocation We now allow interrupt stacks anywhere in the first segment which can be 256M or 1TB. Fix the comment. Signed-off-by: Anton Blanchard Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/setup_64.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c index ce6f61c6f871..5a0401fcaebd 100644 --- a/arch/powerpc/kernel/setup_64.c +++ b/arch/powerpc/kernel/setup_64.c @@ -437,8 +437,8 @@ static void __init irqstack_early_init(void) unsigned int i; /* - * interrupt stacks must be under 256MB, we cannot afford to take - * SLB misses on them. + * Interrupt stacks must be in the first segment since we + * cannot afford to take SLB misses on them. */ for_each_possible_cpu(i) { softirq_ctx[i] = (struct thread_info *) -- cgit v1.2.3 From 928a31978115b48ad634a97755915e8ab23c4749 Mon Sep 17 00:00:00 2001 From: Sonny Rao Date: Thu, 18 Nov 2010 00:35:07 +0000 Subject: Powerpc: separate CONFIG_RELOCATABLE from CONFIG_CRASHDUMP in boot code Fix head_64.S so that we can build a relocatable kernel that isn't necessarily a crash-dump kernel Signed-off-by: Milton Miller Signed-off-by: Sonny Rao Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/head_64.S | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S index ce41b97eb512..782f23df7c85 100644 --- a/arch/powerpc/kernel/head_64.S +++ b/arch/powerpc/kernel/head_64.S @@ -97,7 +97,7 @@ __secondary_hold_acknowledge: .llong hvReleaseData-KERNELBASE #endif /* CONFIG_PPC_ISERIES */ -#ifdef CONFIG_CRASH_DUMP +#ifdef CONFIG_RELOCATABLE /* This flag is set to 1 by a loader if the kernel should run * at the loaded address instead of the linked address. This * is used by kexec-tools to keep the the kdump kernel in the @@ -385,12 +385,10 @@ _STATIC(__after_prom_start) /* process relocations for the final address of the kernel */ lis r25,PAGE_OFFSET@highest /* compute virtual base of kernel */ sldi r25,r25,32 -#ifdef CONFIG_CRASH_DUMP lwz r7,__run_at_load-_stext(r26) - cmplwi cr0,r7,1 /* kdump kernel ? - stay where we are */ + cmplwi cr0,r7,1 /* flagged to stay where we are ? */ bne 1f add r25,r25,r26 -#endif 1: mr r3,r25 bl .relocate #endif -- cgit v1.2.3 From bee376ff4c1fc178031dad51ba38ff18a98a39c8 Mon Sep 17 00:00:00 2001 From: Sonny Rao Date: Thu, 18 Nov 2010 00:39:23 +0000 Subject: powerpc: Minor cleanups for machdep.h Remove stale declaration of setup_pci_ptrs, aparently from ppc before 2.4.0 Remove #ifdef around struct existance delcaration Fix spelling of "linear" Signed-off-by: Milton Miller Signed-off-by: Sonny Rao Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/include/asm/machdep.h | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/arch/powerpc/include/asm/machdep.h b/arch/powerpc/include/asm/machdep.h index d045b0145537..8433d36619a1 100644 --- a/arch/powerpc/include/asm/machdep.h +++ b/arch/powerpc/include/asm/machdep.h @@ -27,9 +27,7 @@ struct iommu_table; struct rtc_time; struct file; struct pci_controller; -#ifdef CONFIG_KEXEC struct kimage; -#endif #ifdef CONFIG_SMP struct smp_ops_t { @@ -72,7 +70,7 @@ struct machdep_calls { int psize, int ssize); void (*flush_hash_range)(unsigned long number, int local); - /* special for kexec, to be called in real mode, linar mapping is + /* special for kexec, to be called in real mode, linear mapping is * destroyed as well */ void (*hpte_clear_all)(void); @@ -324,8 +322,6 @@ extern sys_ctrler_t sys_ctrler; #endif /* CONFIG_PPC_PMAC */ -extern void setup_pci_ptrs(void); - #ifdef CONFIG_SMP /* Poor default implementations */ extern void __devinit smp_generic_give_timebase(void); -- cgit v1.2.3 From 364a1246522f99cbe58040e99af007ada31034ed Mon Sep 17 00:00:00 2001 From: Heiko Schocher Date: Mon, 22 Nov 2010 21:30:33 +0000 Subject: powerpc/time: printk time stamp init not correct problem: I see sometimes on my mpc5200 based board such printk timing information: [ 0.000000] NR_IRQS:512 nr_irqs:512 16 [ 0.000000] MPC52xx PIC is up and running! [ 0.000000] clocksource: timebase mult[79364d9] shift[22] registered [ 0.000000] console [ttyPSC0] enabled [ 130.300633] pid_max: default: 32768 minimum: 301 [ 130.305647] Mount-cache hash table entries: 512 [ 130.315818] NET: Registered protocol family 16 reason: if the tbu not starts from 0 when linux boots, boot_tb maybe could not store the real 64 bit tbu value, because boot_tp is only a 32 bit unsigned long. solution: change boot_tb to u64 [BenH: Made it u64 instead of unsigned long long] Signed-off-by: Heiko Schocher cc: Wolfgang Denk Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/time.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c index 010406958d97..09e4dea4a85a 100644 --- a/arch/powerpc/kernel/time.c +++ b/arch/powerpc/kernel/time.c @@ -155,7 +155,7 @@ EXPORT_SYMBOL_GPL(rtc_lock); static u64 tb_to_ns_scale __read_mostly; static unsigned tb_to_ns_shift __read_mostly; -static unsigned long boot_tb __read_mostly; +static u64 boot_tb __read_mostly; extern struct timezone sys_tz; static long timezone_offset; -- cgit v1.2.3 From 4dfbf290aeb9d63a058d9d8237203b0b72bfbbe3 Mon Sep 17 00:00:00 2001 From: Andreas Schwab Date: Sat, 27 Nov 2010 14:24:53 +0000 Subject: powerpc: Fix PPC_PTRACE_SETHWDEBUG on PPC_BOOK3S Properly set the DABR_TRANSLATION/DABR_DATA_READ/DABR_DATA_READ bits in the dabr when setting the debug register via PPC_PTRACE_SETHWDEBUG. Also don't reject trigger type of PPC_BREAKPOINT_TRIGGER_READ. Signed-off-by: Andreas Schwab Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/ptrace.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c index a9b32967cff6..906536998291 100644 --- a/arch/powerpc/kernel/ptrace.c +++ b/arch/powerpc/kernel/ptrace.c @@ -1316,6 +1316,10 @@ static int set_dac_range(struct task_struct *child, static long ppc_set_hwdebug(struct task_struct *child, struct ppc_hw_breakpoint *bp_info) { +#ifndef CONFIG_PPC_ADV_DEBUG_REGS + unsigned long dabr; +#endif + if (bp_info->version != 1) return -ENOTSUPP; #ifdef CONFIG_PPC_ADV_DEBUG_REGS @@ -1353,11 +1357,10 @@ static long ppc_set_hwdebug(struct task_struct *child, /* * We only support one data breakpoint */ - if (((bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_RW) == 0) || - ((bp_info->trigger_type & ~PPC_BREAKPOINT_TRIGGER_RW) != 0) || - (bp_info->trigger_type != PPC_BREAKPOINT_TRIGGER_WRITE) || - (bp_info->addr_mode != PPC_BREAKPOINT_MODE_EXACT) || - (bp_info->condition_mode != PPC_BREAKPOINT_CONDITION_NONE)) + if ((bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_RW) == 0 || + (bp_info->trigger_type & ~PPC_BREAKPOINT_TRIGGER_RW) != 0 || + bp_info->addr_mode != PPC_BREAKPOINT_MODE_EXACT || + bp_info->condition_mode != PPC_BREAKPOINT_CONDITION_NONE) return -EINVAL; if (child->thread.dabr) @@ -1366,7 +1369,14 @@ static long ppc_set_hwdebug(struct task_struct *child, if ((unsigned long)bp_info->addr >= TASK_SIZE) return -EIO; - child->thread.dabr = (unsigned long)bp_info->addr; + dabr = (unsigned long)bp_info->addr & ~7UL; + dabr |= DABR_TRANSLATION; + if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_READ) + dabr |= DABR_DATA_READ; + if (bp_info->trigger_type & PPC_BREAKPOINT_TRIGGER_WRITE) + dabr |= DABR_DATA_WRITE; + + child->thread.dabr = dabr; return 1; #endif /* !CONFIG_PPC_ADV_DEBUG_DVCS */ -- cgit v1.2.3 From bb2c458b8b8c8a53f65b78051d22a0f13d53abcb Mon Sep 17 00:00:00 2001 From: Andreas Schwab Date: Sun, 28 Nov 2010 06:33:14 +0000 Subject: powerpc: Update compat_arch_ptrace Update compat_arch_ptrace to follow recent changes in PTRACE_GET_DEBUGREG and the addition of PPC_PTRACE_{GETHWDBGINFO|{SET|DEL}HWDEBUG}. The latter three can be forwarded to arch_ptrace unchanged. Signed-off-by: Andreas Schwab Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/ptrace32.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/arch/powerpc/kernel/ptrace32.c b/arch/powerpc/kernel/ptrace32.c index 8a6daf4129f6..69c4be917d07 100644 --- a/arch/powerpc/kernel/ptrace32.c +++ b/arch/powerpc/kernel/ptrace32.c @@ -280,7 +280,11 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request, /* We only support one DABR and no IABRS at the moment */ if (addr > 0) break; +#ifdef CONFIG_PPC_ADV_DEBUG_REGS + ret = put_user(child->thread.dac1, (u32 __user *)data); +#else ret = put_user(child->thread.dabr, (u32 __user *)data); +#endif break; } @@ -312,6 +316,9 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request, case PTRACE_SET_DEBUGREG: case PTRACE_SYSCALL: case PTRACE_CONT: + case PPC_PTRACE_GETHWDBGINFO: + case PPC_PTRACE_SETHWDEBUG: + case PPC_PTRACE_DELHWDEBUG: ret = arch_ptrace(child, request, addr, data); break; -- cgit v1.2.3 From 7a9d12568e34e37a72d9e00ce01b62dec527e663 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Sun, 28 Nov 2010 18:26:36 +0000 Subject: powerpc: Record vma->phys_addr in ioremap() The vmalloc code can track the physical address of a vma, when the vma is used for ioremap, if set it is displayed in /proc/vmallocinfo. Because get_vm_area_caller() doesn't know it's being called for ioremap() it's up to the arch code to set the phys_addr. A bunch of other arch's do this, I'm not sure why powerpc doesn't? Signed-off-by: Michael Ellerman Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/mm/pgtable_32.c | 1 + arch/powerpc/mm/pgtable_64.c | 2 ++ 2 files changed, 3 insertions(+) diff --git a/arch/powerpc/mm/pgtable_32.c b/arch/powerpc/mm/pgtable_32.c index a87ead0138b4..71932d000a72 100644 --- a/arch/powerpc/mm/pgtable_32.c +++ b/arch/powerpc/mm/pgtable_32.c @@ -230,6 +230,7 @@ __ioremap_caller(phys_addr_t addr, unsigned long size, unsigned long flags, area = get_vm_area_caller(size, VM_IOREMAP, caller); if (area == 0) return NULL; + area->phys_addr = p; v = (unsigned long) area->addr; } else { v = (ioremap_bot -= size); diff --git a/arch/powerpc/mm/pgtable_64.c b/arch/powerpc/mm/pgtable_64.c index 21d6dfab7942..88927a05cdc2 100644 --- a/arch/powerpc/mm/pgtable_64.c +++ b/arch/powerpc/mm/pgtable_64.c @@ -223,6 +223,8 @@ void __iomem * __ioremap_caller(phys_addr_t addr, unsigned long size, caller); if (area == NULL) return NULL; + + area->phys_addr = paligned; ret = __ioremap_at(paligned, area->addr, size, flags); if (!ret) vunmap(area->addr); -- cgit v1.2.3 From 4dfa9c474859629a2c4a3f8d29804d6a6c994908 Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Tue, 7 Dec 2010 14:36:05 +0000 Subject: powerpc: iommu: Add device name to iommu error printks Right now its difficult to see which device is running out of iommu space: iommu_alloc failed, tbl c00000076e096660 vaddr c000000768806600 npages 1 Use dev_info() so we get the device name and location: ipr 0000:00:01.0: iommu_alloc failed, tbl c00000076e096660 vaddr c000000768806600 npages 1 Signed-off-by: Anton Blanchard Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/iommu.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c index d5839179ec77..961bb03413f3 100644 --- a/arch/powerpc/kernel/iommu.c +++ b/arch/powerpc/kernel/iommu.c @@ -311,8 +311,9 @@ int iommu_map_sg(struct device *dev, struct iommu_table *tbl, /* Handle failure */ if (unlikely(entry == DMA_ERROR_CODE)) { if (printk_ratelimit()) - printk(KERN_INFO "iommu_alloc failed, tbl %p vaddr %lx" - " npages %lx\n", tbl, vaddr, npages); + dev_info(dev, "iommu_alloc failed, tbl %p " + "vaddr %lx npages %lu\n", tbl, vaddr, + npages); goto failure; } @@ -579,9 +580,9 @@ dma_addr_t iommu_map_page(struct device *dev, struct iommu_table *tbl, attrs); if (dma_handle == DMA_ERROR_CODE) { if (printk_ratelimit()) { - printk(KERN_INFO "iommu_alloc failed, " - "tbl %p vaddr %p npages %d\n", - tbl, vaddr, npages); + dev_info(dev, "iommu_alloc failed, tbl %p " + "vaddr %p npages %d\n", tbl, vaddr, + npages); } } else dma_handle |= (uaddr & ~IOMMU_PAGE_MASK); @@ -627,7 +628,8 @@ void *iommu_alloc_coherent(struct device *dev, struct iommu_table *tbl, * the tce tables. */ if (order >= IOMAP_MAX_ORDER) { - printk("iommu_alloc_consistent size too large: 0x%lx\n", size); + dev_info(dev, "iommu_alloc_consistent size too large: 0x%lx\n", + size); return NULL; } -- cgit v1.2.3 From 9eff1a38407c051273fe1a20f03f8155bd32de35 Mon Sep 17 00:00:00 2001 From: Jesse Larrew Date: Wed, 1 Dec 2010 12:31:15 +0000 Subject: powerpc/pseries: Poll VPA for topology changes and update NUMA maps This patch sets a timer during boot that will periodically poll the associativity change counters in the VPA. When a change in associativity is detected, it retrieves the new associativity domain information via the H_HOME_NODE_ASSOCIATIVITY hcall and updates the NUMA node maps and sysfs entries accordingly. Note that since the ibm,associativity device tree property does not exist on configurations with both NUMA and SPLPAR enabled, no device tree updates are necessary. Signed-off-by: Jesse Larrew Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/include/asm/lppaca.h | 5 +- arch/powerpc/mm/numa.c | 277 ++++++++++++++++++++++++++++++++++++-- 2 files changed, 271 insertions(+), 11 deletions(-) diff --git a/arch/powerpc/include/asm/lppaca.h b/arch/powerpc/include/asm/lppaca.h index 7f5e0fefebb0..380d48bacd16 100644 --- a/arch/powerpc/include/asm/lppaca.h +++ b/arch/powerpc/include/asm/lppaca.h @@ -62,7 +62,10 @@ struct lppaca { volatile u32 dyn_pir; // Dynamic ProcIdReg value x20-x23 u32 dsei_data; // DSEI data x24-x27 u64 sprg3; // SPRG3 value x28-x2F - u8 reserved3[80]; // Reserved x30-x7F + u8 reserved3[40]; // Reserved x30-x57 + volatile u8 vphn_assoc_counts[8]; // Virtual processor home node + // associativity change counters x58-x5F + u8 reserved4[32]; // Reserved x60-x7F //============================================================================= // CACHE_LINE_2 0x0080 - 0x00FF Contains local read-write data diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c index 8c0944c465f6..d644ba7e8aba 100644 --- a/arch/powerpc/mm/numa.c +++ b/arch/powerpc/mm/numa.c @@ -20,10 +20,14 @@ #include #include #include +#include +#include #include #include #include #include +#include +#include static int numa_enabled = 1; @@ -246,32 +250,41 @@ static void initialize_distance_lookup_table(int nid, /* Returns nid in the range [0..MAX_NUMNODES-1], or -1 if no useful numa * info is found. */ -static int of_node_to_nid_single(struct device_node *device) +static int associativity_to_nid(const unsigned int *associativity) { int nid = -1; - const unsigned int *tmp; if (min_common_depth == -1) goto out; - tmp = of_get_associativity(device); - if (!tmp) - goto out; - - if (tmp[0] >= min_common_depth) - nid = tmp[min_common_depth]; + if (associativity[0] >= min_common_depth) + nid = associativity[min_common_depth]; /* POWER4 LPAR uses 0xffff as invalid node */ if (nid == 0xffff || nid >= MAX_NUMNODES) nid = -1; - if (nid > 0 && tmp[0] >= distance_ref_points_depth) - initialize_distance_lookup_table(nid, tmp); + if (nid > 0 && associativity[0] >= distance_ref_points_depth) + initialize_distance_lookup_table(nid, associativity); out: return nid; } +/* Returns the nid associated with the given device tree node, + * or -1 if not found. + */ +static int of_node_to_nid_single(struct device_node *device) +{ + int nid = -1; + const unsigned int *tmp; + + tmp = of_get_associativity(device); + if (tmp) + nid = associativity_to_nid(tmp); + return nid; +} + /* Walk the device tree upwards, looking for an associativity id */ int of_node_to_nid(struct device_node *device) { @@ -1274,3 +1287,247 @@ u64 memory_hotplug_max(void) return max(hot_add_drconf_memory_max(), memblock_end_of_DRAM()); } #endif /* CONFIG_MEMORY_HOTPLUG */ + +/* Vrtual Processor Home Node (VPHN) support */ +#define VPHN_NR_CHANGE_CTRS (8) +static u8 vphn_cpu_change_counts[NR_CPUS][VPHN_NR_CHANGE_CTRS]; +static cpumask_t cpu_associativity_changes_mask; +static int vphn_enabled; +static void set_topology_timer(void); +int stop_topology_update(void); + +/* + * Store the current values of the associativity change counters in the + * hypervisor. + */ +static void setup_cpu_associativity_change_counters(void) +{ + int cpu = 0; + + for_each_possible_cpu(cpu) { + int i = 0; + u8 *counts = vphn_cpu_change_counts[cpu]; + volatile u8 *hypervisor_counts = lppaca[cpu].vphn_assoc_counts; + + for (i = 0; i < VPHN_NR_CHANGE_CTRS; i++) { + counts[i] = hypervisor_counts[i]; + } + } +} + +/* + * The hypervisor maintains a set of 8 associativity change counters in + * the VPA of each cpu that correspond to the associativity levels in the + * ibm,associativity-reference-points property. When an associativity + * level changes, the corresponding counter is incremented. + * + * Set a bit in cpu_associativity_changes_mask for each cpu whose home + * node associativity levels have changed. + * + * Returns the number of cpus with unhandled associativity changes. + */ +static int update_cpu_associativity_changes_mask(void) +{ + int cpu = 0, nr_cpus = 0; + cpumask_t *changes = &cpu_associativity_changes_mask; + + cpumask_clear(changes); + + for_each_possible_cpu(cpu) { + int i, changed = 0; + u8 *counts = vphn_cpu_change_counts[cpu]; + volatile u8 *hypervisor_counts = lppaca[cpu].vphn_assoc_counts; + + for (i = 0; i < VPHN_NR_CHANGE_CTRS; i++) { + if (hypervisor_counts[i] > counts[i]) { + counts[i] = hypervisor_counts[i]; + changed = 1; + } + } + if (changed) { + cpumask_set_cpu(cpu, changes); + nr_cpus++; + } + } + + return nr_cpus; +} + +/* 6 64-bit registers unpacked into 12 32-bit associativity values */ +#define VPHN_ASSOC_BUFSIZE (6*sizeof(u64)/sizeof(u32)) + +/* + * Convert the associativity domain numbers returned from the hypervisor + * to the sequence they would appear in the ibm,associativity property. + */ +static int vphn_unpack_associativity(const long *packed, unsigned int *unpacked) +{ + int i = 0; + int nr_assoc_doms = 0; + const u16 *field = (const u16*) packed; + +#define VPHN_FIELD_UNUSED (0xffff) +#define VPHN_FIELD_MSB (0x8000) +#define VPHN_FIELD_MASK (~VPHN_FIELD_MSB) + + for (i = 0; i < VPHN_ASSOC_BUFSIZE; i++) { + if (*field == VPHN_FIELD_UNUSED) { + /* All significant fields processed, and remaining + * fields contain the reserved value of all 1's. + * Just store them. + */ + unpacked[i] = *((u32*)field); + field += 2; + } + else if (*field & VPHN_FIELD_MSB) { + /* Data is in the lower 15 bits of this field */ + unpacked[i] = *field & VPHN_FIELD_MASK; + field++; + nr_assoc_doms++; + } + else { + /* Data is in the lower 15 bits of this field + * concatenated with the next 16 bit field + */ + unpacked[i] = *((u32*)field); + field += 2; + nr_assoc_doms++; + } + } + + return nr_assoc_doms; +} + +/* + * Retrieve the new associativity information for a virtual processor's + * home node. + */ +static long hcall_vphn(unsigned long cpu, unsigned int *associativity) +{ + long rc = 0; + long retbuf[PLPAR_HCALL9_BUFSIZE] = {0}; + u64 flags = 1; + int hwcpu = get_hard_smp_processor_id(cpu); + + rc = plpar_hcall9(H_HOME_NODE_ASSOCIATIVITY, retbuf, flags, hwcpu); + vphn_unpack_associativity(retbuf, associativity); + + return rc; +} + +static long vphn_get_associativity(unsigned long cpu, + unsigned int *associativity) +{ + long rc = 0; + + rc = hcall_vphn(cpu, associativity); + + switch (rc) { + case H_FUNCTION: + printk(KERN_INFO + "VPHN is not supported. Disabling polling...\n"); + stop_topology_update(); + break; + case H_HARDWARE: + printk(KERN_ERR + "hcall_vphn() experienced a hardware fault " + "preventing VPHN. Disabling polling...\n"); + stop_topology_update(); + } + + return rc; +} + +/* + * Update the node maps and sysfs entries for each cpu whose home node + * has changed. + */ +int arch_update_cpu_topology(void) +{ + int cpu = 0, nid = 0, old_nid = 0; + unsigned int associativity[VPHN_ASSOC_BUFSIZE] = {0}; + struct sys_device *sysdev = NULL; + + for_each_cpu_mask(cpu, cpu_associativity_changes_mask) { + vphn_get_associativity(cpu, associativity); + nid = associativity_to_nid(associativity); + + if (nid < 0 || !node_online(nid)) + nid = first_online_node; + + old_nid = numa_cpu_lookup_table[cpu]; + + /* Disable hotplug while we update the cpu + * masks and sysfs. + */ + get_online_cpus(); + unregister_cpu_under_node(cpu, old_nid); + unmap_cpu_from_node(cpu); + map_cpu_to_node(cpu, nid); + register_cpu_under_node(cpu, nid); + put_online_cpus(); + + sysdev = get_cpu_sysdev(cpu); + if (sysdev) + kobject_uevent(&sysdev->kobj, KOBJ_CHANGE); + } + + return 1; +} + +static void topology_work_fn(struct work_struct *work) +{ + rebuild_sched_domains(); +} +static DECLARE_WORK(topology_work, topology_work_fn); + +void topology_schedule_update(void) +{ + schedule_work(&topology_work); +} + +static void topology_timer_fn(unsigned long ignored) +{ + if (!vphn_enabled) + return; + if (update_cpu_associativity_changes_mask() > 0) + topology_schedule_update(); + set_topology_timer(); +} +static struct timer_list topology_timer = + TIMER_INITIALIZER(topology_timer_fn, 0, 0); + +static void set_topology_timer(void) +{ + topology_timer.data = 0; + topology_timer.expires = jiffies + 60 * HZ; + add_timer(&topology_timer); +} + +/* + * Start polling for VPHN associativity changes. + */ +int start_topology_update(void) +{ + int rc = 0; + + if (firmware_has_feature(FW_FEATURE_VPHN)) { + vphn_enabled = 1; + setup_cpu_associativity_change_counters(); + init_timer_deferrable(&topology_timer); + set_topology_timer(); + rc = 1; + } + + return rc; +} +__initcall(start_topology_update); + +/* + * Disable polling for VPHN associativity changes. + */ +int stop_topology_update(void) +{ + vphn_enabled = 0; + return del_timer_sync(&topology_timer); +} -- cgit v1.2.3 From 3b7a27db3b6b5501e3d1c1628e6d5a547ffe76c6 Mon Sep 17 00:00:00 2001 From: Jesse Larrew Date: Wed, 1 Dec 2010 12:31:26 +0000 Subject: powerpc: Disable VPHN polling during a suspend operation Tie the polling mechanism into the ibm,suspend-me rtas call to stop/restart polling before/after a suspend, hibernate, migrate, or checkpoint restart operation. This ensures that the system has a chance to disable the polling if the partition is migrated to a system that does not support VPHN (and vice versa). Signed-off-by: Jesse Larrew Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/include/asm/topology.h | 10 ++++++++++ arch/powerpc/kernel/rtas.c | 3 +++ 2 files changed, 13 insertions(+) diff --git a/arch/powerpc/include/asm/topology.h b/arch/powerpc/include/asm/topology.h index afe4aaa65c3b..aed188bd70db 100644 --- a/arch/powerpc/include/asm/topology.h +++ b/arch/powerpc/include/asm/topology.h @@ -93,6 +93,8 @@ extern void __init dump_numa_cpu_topology(void); extern int sysfs_add_device_to_node(struct sys_device *dev, int nid); extern void sysfs_remove_device_from_node(struct sys_device *dev, int nid); +extern int start_topology_update(void); +extern int stop_topology_update(void); #else static inline void dump_numa_cpu_topology(void) {} @@ -107,6 +109,14 @@ static inline void sysfs_remove_device_from_node(struct sys_device *dev, { } +static inline int start_topology_update(void) +{ + return 0; +} +static inline int stop_topology_update(void) +{ + return 0; +} #endif /* CONFIG_NUMA */ #include diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c index 8fe8bc61c10a..2097f2b3cba8 100644 --- a/arch/powerpc/kernel/rtas.c +++ b/arch/powerpc/kernel/rtas.c @@ -41,6 +41,7 @@ #include #include #include +#include struct rtas_t rtas = { .lock = __ARCH_SPIN_LOCK_UNLOCKED @@ -713,6 +714,7 @@ static int __rtas_suspend_last_cpu(struct rtas_suspend_me_data *data, int wake_w int cpu; slb_set_size(SLB_MIN_SIZE); + stop_topology_update(); printk(KERN_DEBUG "calling ibm,suspend-me on cpu %i\n", smp_processor_id()); while (rc == H_MULTI_THREADS_ACTIVE && !atomic_read(&data->done) && @@ -728,6 +730,7 @@ static int __rtas_suspend_last_cpu(struct rtas_suspend_me_data *data, int wake_w rc = atomic_read(&data->error); atomic_set(&data->error, rc); + start_topology_update(); if (wake_when_done) { atomic_set(&data->done, 1); -- cgit v1.2.3 From ae9fd31a3668ca97e8f37698b927ae7c0b70807a Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Mon, 8 Nov 2010 13:07:57 +0000 Subject: powerpc: Remove unnecessary casts of void ptr Hi, The [vk][cmz]alloc(_node) family of functions return void pointers which it's completely unnecessary/pointless to cast to other pointer types since that happens implicitly. This patch removes such casts from arch/powerpc/ Signed-off-by: Jesper Juhl Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/mm/pgtable_32.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/powerpc/mm/pgtable_32.c b/arch/powerpc/mm/pgtable_32.c index 71932d000a72..8dc41c0157fe 100644 --- a/arch/powerpc/mm/pgtable_32.c +++ b/arch/powerpc/mm/pgtable_32.c @@ -78,7 +78,7 @@ pgd_t *pgd_alloc(struct mm_struct *mm) /* pgdir take page or two with 4K pages and a page fraction otherwise */ #ifndef CONFIG_PPC_4K_PAGES - ret = (pgd_t *)kzalloc(1 << PGDIR_ORDER, GFP_KERNEL); + ret = kzalloc(1 << PGDIR_ORDER, GFP_KERNEL); #else ret = (pgd_t *)__get_free_pages(GFP_KERNEL|__GFP_ZERO, PGDIR_ORDER - PAGE_SHIFT); -- cgit v1.2.3 From 518fdae26a530d3f0f11e3650348ab75e5891cfd Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Fri, 12 Nov 2010 14:49:19 +0000 Subject: powerpc/pci: Use printf extension %pR for struct resource Using %pR standardizes the struct resource output. Signed-off-by: Joe Perches Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/kernel/pci_64.c | 3 +-- arch/powerpc/sysdev/tsi108_dev.c | 8 ++++---- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c index d43fc65749c1..851577608a78 100644 --- a/arch/powerpc/kernel/pci_64.c +++ b/arch/powerpc/kernel/pci_64.c @@ -193,8 +193,7 @@ int __devinit pcibios_map_io_space(struct pci_bus *bus) hose->io_resource.start += io_virt_offset; hose->io_resource.end += io_virt_offset; - pr_debug(" hose->io_resource=0x%016llx...0x%016llx\n", - hose->io_resource.start, hose->io_resource.end); + pr_debug(" hose->io_resource=%pR\n", &hose->io_resource); return 0; } diff --git a/arch/powerpc/sysdev/tsi108_dev.c b/arch/powerpc/sysdev/tsi108_dev.c index d4d15aaf18fa..5e249a85c1c0 100644 --- a/arch/powerpc/sysdev/tsi108_dev.c +++ b/arch/powerpc/sysdev/tsi108_dev.c @@ -83,8 +83,8 @@ static int __init tsi108_eth_of_init(void) memset(&tsi_eth_data, 0, sizeof(tsi_eth_data)); ret = of_address_to_resource(np, 0, &r[0]); - DBG("%s: name:start->end = %s:0x%lx-> 0x%lx\n", - __func__,r[0].name, r[0].start, r[0].end); + DBG("%s: name:start->end = %s:%pR\n", + __func__, r[0].name, &r[0]); if (ret) goto err; @@ -92,8 +92,8 @@ static int __init tsi108_eth_of_init(void) r[1].start = irq_of_parse_and_map(np, 0); r[1].end = irq_of_parse_and_map(np, 0); r[1].flags = IORESOURCE_IRQ; - DBG("%s: name:start->end = %s:0x%lx-> 0x%lx\n", - __func__,r[1].name, r[1].start, r[1].end); + DBG("%s: name:start->end = %s:%pR\n", + __func__, r[1].name, &r[1]); tsi_eth_dev = platform_device_register_simple("tsi-ethernet", i++, &r[0], -- cgit v1.2.3 From 982cf00412a890ca738c2d78528b652ca431ad1a Mon Sep 17 00:00:00 2001 From: Sebastian Siewior Date: Tue, 30 Nov 2010 23:54:46 +0000 Subject: of/address: Use propper endianess in get_flags This patch changes u32 to __be32 for all "ranges", "prop" and "addr" and such. Those variables are pointing to the device tree which containts intergers in big endian format. Most functions are doing it right because of_read_number() is doing the right thing for them. of_bus_isa_get_flags(), of_bus_pci_get_flags() and of_bus_isa_map() were accessing the data directly and were doing it wrong. Signed-off-by: Sebastian Andrzej Siewior Acked-by: Benjamin Herrenschmidt Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/include/asm/prom.h | 2 +- drivers/of/address.c | 54 +++++++++++++++++++++-------------------- include/linux/of_address.h | 6 ++--- 3 files changed, 32 insertions(+), 30 deletions(-) diff --git a/arch/powerpc/include/asm/prom.h b/arch/powerpc/include/asm/prom.h index ae26f2efd089..ab34f6072095 100644 --- a/arch/powerpc/include/asm/prom.h +++ b/arch/powerpc/include/asm/prom.h @@ -42,7 +42,7 @@ extern void pci_create_OF_bus_map(void); /* Translate a DMA address from device space to CPU space */ extern u64 of_translate_dma_address(struct device_node *dev, - const u32 *in_addr); + const __be32 *in_addr); #ifdef CONFIG_PCI extern unsigned long pci_address_to_pio(phys_addr_t address); diff --git a/drivers/of/address.c b/drivers/of/address.c index 3a1c7e70b192..b4559c58c095 100644 --- a/drivers/of/address.c +++ b/drivers/of/address.c @@ -12,13 +12,13 @@ (ns) > 0) static struct of_bus *of_match_bus(struct device_node *np); -static int __of_address_to_resource(struct device_node *dev, const u32 *addrp, - u64 size, unsigned int flags, +static int __of_address_to_resource(struct device_node *dev, + const __be32 *addrp, u64 size, unsigned int flags, struct resource *r); /* Debug utility */ #ifdef DEBUG -static void of_dump_addr(const char *s, const u32 *addr, int na) +static void of_dump_addr(const char *s, const __be32 *addr, int na) { printk(KERN_DEBUG "%s", s); while (na--) @@ -26,7 +26,7 @@ static void of_dump_addr(const char *s, const u32 *addr, int na) printk("\n"); } #else -static void of_dump_addr(const char *s, const u32 *addr, int na) { } +static void of_dump_addr(const char *s, const __be32 *addr, int na) { } #endif /* Callbacks for bus specific translators */ @@ -36,10 +36,10 @@ struct of_bus { int (*match)(struct device_node *parent); void (*count_cells)(struct device_node *child, int *addrc, int *sizec); - u64 (*map)(u32 *addr, const u32 *range, + u64 (*map)(u32 *addr, const __be32 *range, int na, int ns, int pna); int (*translate)(u32 *addr, u64 offset, int na); - unsigned int (*get_flags)(const u32 *addr); + unsigned int (*get_flags)(const __be32 *addr); }; /* @@ -55,7 +55,7 @@ static void of_bus_default_count_cells(struct device_node *dev, *sizec = of_n_size_cells(dev); } -static u64 of_bus_default_map(u32 *addr, const u32 *range, +static u64 of_bus_default_map(u32 *addr, const __be32 *range, int na, int ns, int pna) { u64 cp, s, da; @@ -85,7 +85,7 @@ static int of_bus_default_translate(u32 *addr, u64 offset, int na) return 0; } -static unsigned int of_bus_default_get_flags(const u32 *addr) +static unsigned int of_bus_default_get_flags(const __be32 *addr) { return IORESOURCE_MEM; } @@ -110,10 +110,10 @@ static void of_bus_pci_count_cells(struct device_node *np, *sizec = 2; } -static unsigned int of_bus_pci_get_flags(const u32 *addr) +static unsigned int of_bus_pci_get_flags(const __be32 *addr) { unsigned int flags = 0; - u32 w = addr[0]; + u32 w = be32_to_cpup(addr); switch((w >> 24) & 0x03) { case 0x01: @@ -129,7 +129,8 @@ static unsigned int of_bus_pci_get_flags(const u32 *addr) return flags; } -static u64 of_bus_pci_map(u32 *addr, const u32 *range, int na, int ns, int pna) +static u64 of_bus_pci_map(u32 *addr, const __be32 *range, int na, int ns, + int pna) { u64 cp, s, da; unsigned int af, rf; @@ -160,7 +161,7 @@ static int of_bus_pci_translate(u32 *addr, u64 offset, int na) return of_bus_default_translate(addr + 1, offset, na - 1); } -const u32 *of_get_pci_address(struct device_node *dev, int bar_no, u64 *size, +const __be32 *of_get_pci_address(struct device_node *dev, int bar_no, u64 *size, unsigned int *flags) { const __be32 *prop; @@ -207,7 +208,7 @@ EXPORT_SYMBOL(of_get_pci_address); int of_pci_address_to_resource(struct device_node *dev, int bar, struct resource *r) { - const u32 *addrp; + const __be32 *addrp; u64 size; unsigned int flags; @@ -237,12 +238,13 @@ static void of_bus_isa_count_cells(struct device_node *child, *sizec = 1; } -static u64 of_bus_isa_map(u32 *addr, const u32 *range, int na, int ns, int pna) +static u64 of_bus_isa_map(u32 *addr, const __be32 *range, int na, int ns, + int pna) { u64 cp, s, da; /* Check address type match */ - if ((addr[0] ^ range[0]) & 0x00000001) + if ((addr[0] ^ range[0]) & cpu_to_be32(1)) return OF_BAD_ADDR; /* Read address values, skipping high cell */ @@ -264,10 +266,10 @@ static int of_bus_isa_translate(u32 *addr, u64 offset, int na) return of_bus_default_translate(addr + 1, offset, na - 1); } -static unsigned int of_bus_isa_get_flags(const u32 *addr) +static unsigned int of_bus_isa_get_flags(const __be32 *addr) { unsigned int flags = 0; - u32 w = addr[0]; + u32 w = be32_to_cpup(addr); if (w & 1) flags |= IORESOURCE_IO; @@ -330,7 +332,7 @@ static int of_translate_one(struct device_node *parent, struct of_bus *bus, struct of_bus *pbus, u32 *addr, int na, int ns, int pna, const char *rprop) { - const u32 *ranges; + const __be32 *ranges; unsigned int rlen; int rone; u64 offset = OF_BAD_ADDR; @@ -398,7 +400,7 @@ static int of_translate_one(struct device_node *parent, struct of_bus *bus, * that can be mapped to a cpu physical address). This is not really specified * that way, but this is traditionally the way IBM at least do things */ -u64 __of_translate_address(struct device_node *dev, const u32 *in_addr, +u64 __of_translate_address(struct device_node *dev, const __be32 *in_addr, const char *rprop) { struct device_node *parent = NULL; @@ -475,22 +477,22 @@ u64 __of_translate_address(struct device_node *dev, const u32 *in_addr, return result; } -u64 of_translate_address(struct device_node *dev, const u32 *in_addr) +u64 of_translate_address(struct device_node *dev, const __be32 *in_addr) { return __of_translate_address(dev, in_addr, "ranges"); } EXPORT_SYMBOL(of_translate_address); -u64 of_translate_dma_address(struct device_node *dev, const u32 *in_addr) +u64 of_translate_dma_address(struct device_node *dev, const __be32 *in_addr) { return __of_translate_address(dev, in_addr, "dma-ranges"); } EXPORT_SYMBOL(of_translate_dma_address); -const u32 *of_get_address(struct device_node *dev, int index, u64 *size, +const __be32 *of_get_address(struct device_node *dev, int index, u64 *size, unsigned int *flags) { - const u32 *prop; + const __be32 *prop; unsigned int psize; struct device_node *parent; struct of_bus *bus; @@ -525,8 +527,8 @@ const u32 *of_get_address(struct device_node *dev, int index, u64 *size, } EXPORT_SYMBOL(of_get_address); -static int __of_address_to_resource(struct device_node *dev, const u32 *addrp, - u64 size, unsigned int flags, +static int __of_address_to_resource(struct device_node *dev, + const __be32 *addrp, u64 size, unsigned int flags, struct resource *r) { u64 taddr; @@ -564,7 +566,7 @@ static int __of_address_to_resource(struct device_node *dev, const u32 *addrp, int of_address_to_resource(struct device_node *dev, int index, struct resource *r) { - const u32 *addrp; + const __be32 *addrp; u64 size; unsigned int flags; diff --git a/include/linux/of_address.h b/include/linux/of_address.h index 8aea06f0564c..2feda6ee6140 100644 --- a/include/linux/of_address.h +++ b/include/linux/of_address.h @@ -3,7 +3,7 @@ #include #include -extern u64 of_translate_address(struct device_node *np, const u32 *addr); +extern u64 of_translate_address(struct device_node *np, const __be32 *addr); extern int of_address_to_resource(struct device_node *dev, int index, struct resource *r); extern void __iomem *of_iomap(struct device_node *device, int index); @@ -21,7 +21,7 @@ static inline unsigned long pci_address_to_pio(phys_addr_t addr) { return -1; } #endif #ifdef CONFIG_PCI -extern const u32 *of_get_pci_address(struct device_node *dev, int bar_no, +extern const __be32 *of_get_pci_address(struct device_node *dev, int bar_no, u64 *size, unsigned int *flags); extern int of_pci_address_to_resource(struct device_node *dev, int bar, struct resource *r); @@ -32,7 +32,7 @@ static inline int of_pci_address_to_resource(struct device_node *dev, int bar, return -ENOSYS; } -static inline const u32 *of_get_pci_address(struct device_node *dev, +static inline const __be32 *of_get_pci_address(struct device_node *dev, int bar_no, u64 *size, unsigned int *flags) { return NULL; -- cgit v1.2.3 From 98b14d6b290d96b24ae993ceaccc59b2aa4b130c Mon Sep 17 00:00:00 2001 From: Marc Zyngier Date: Sun, 5 Dec 2010 05:05:37 +0000 Subject: powerpc/powermac: Make auto-loading of therm_pm72 possible The therm_pm72 driver, used on the PowerMac G5 range, cannot be auto-loaded, since the driver itself creates both the device node and the driver instance. Moving the device node creation to the platform setup code and adding the necessary MODULE_DEVICE_TABLE() information allows the driver to be automatically loaded by udev on any semi-modern distribution. It "fixes" a major source of problem on G5 machines where the driver wasn't explicitely loaded by default, and the system would automatically shutdown under load. Tested on an Xserve G5. Signed-off-by: Marc Zyngier Cc: Benjamin Herrenschmidt Signed-off-by: Benjamin Herrenschmidt --- arch/powerpc/platforms/powermac/setup.c | 9 +++++++++ drivers/macintosh/therm_pm72.c | 30 +++++------------------------- 2 files changed, 14 insertions(+), 25 deletions(-) diff --git a/arch/powerpc/platforms/powermac/setup.c b/arch/powerpc/platforms/powermac/setup.c index 9deb274841f1..d5aceb7fb125 100644 --- a/arch/powerpc/platforms/powermac/setup.c +++ b/arch/powerpc/platforms/powermac/setup.c @@ -506,6 +506,15 @@ static int __init pmac_declare_of_platform_devices(void) of_platform_device_create(np, "smu", NULL); of_node_put(np); } + np = of_find_node_by_type(NULL, "fcu"); + if (np == NULL) { + /* Some machines have strangely broken device-tree */ + np = of_find_node_by_path("/u3@0,f8000000/i2c@f8001000/fan@15e"); + } + if (np) { + of_platform_device_create(np, "temperature", NULL); + of_node_put(np); + } return 0; } diff --git a/drivers/macintosh/therm_pm72.c b/drivers/macintosh/therm_pm72.c index 44549272333c..2e041fd0a00c 100644 --- a/drivers/macintosh/therm_pm72.c +++ b/drivers/macintosh/therm_pm72.c @@ -2213,6 +2213,9 @@ static void fcu_lookup_fans(struct device_node *fcu_node) static int fcu_of_probe(struct platform_device* dev, const struct of_device_id *match) { state = state_detached; + of_dev = dev; + + dev_info(&dev->dev, "PowerMac G5 Thermal control driver %s\n", VERSION); /* Lookup the fans in the device tree */ fcu_lookup_fans(dev->dev.of_node); @@ -2235,6 +2238,7 @@ static const struct of_device_id fcu_match[] = }, {}, }; +MODULE_DEVICE_TABLE(of, fcu_match); static struct of_platform_driver fcu_of_platform_driver = { @@ -2252,8 +2256,6 @@ static struct of_platform_driver fcu_of_platform_driver = */ static int __init therm_pm72_init(void) { - struct device_node *np; - rackmac = of_machine_is_compatible("RackMac3,1"); if (!of_machine_is_compatible("PowerMac7,2") && @@ -2261,34 +2263,12 @@ static int __init therm_pm72_init(void) !rackmac) return -ENODEV; - printk(KERN_INFO "PowerMac G5 Thermal control driver %s\n", VERSION); - - np = of_find_node_by_type(NULL, "fcu"); - if (np == NULL) { - /* Some machines have strangely broken device-tree */ - np = of_find_node_by_path("/u3@0,f8000000/i2c@f8001000/fan@15e"); - if (np == NULL) { - printk(KERN_ERR "Can't find FCU in device-tree !\n"); - return -ENODEV; - } - } - of_dev = of_platform_device_create(np, "temperature", NULL); - if (of_dev == NULL) { - printk(KERN_ERR "Can't register FCU platform device !\n"); - return -ENODEV; - } - - of_register_platform_driver(&fcu_of_platform_driver); - - return 0; + return of_register_platform_driver(&fcu_of_platform_driver); } static void __exit therm_pm72_exit(void) { of_unregister_platform_driver(&fcu_of_platform_driver); - - if (of_dev) - of_device_unregister(of_dev); } module_init(therm_pm72_init); -- cgit v1.2.3 From e1eb5f10069b7c393174b3a272ad647537969862 Mon Sep 17 00:00:00 2001 From: Todd Broch Date: Mon, 6 Dec 2010 11:19:51 -0800 Subject: ALSA: hda: Add modelname lookup and fixup for realtek codecs Facilitate fixup for realtek codecs via modelname lookup of fixup data. Fallback to quirk based lookup in absence of model definition. Signed-off-by: Todd Broch Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 61 ++++++++++++++++++++++++++++++++++--------- 1 file changed, 49 insertions(+), 12 deletions(-) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 0badedab1335..9ba4279c690d 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -1677,6 +1677,11 @@ struct alc_pincfg { u32 val; }; +struct alc_model_fixup { + const int id; + const char *name; +}; + struct alc_fixup { unsigned int sku; const struct alc_pincfg *pins; @@ -1685,23 +1690,19 @@ struct alc_fixup { int pre_init); }; -static void alc_pick_fixup(struct hda_codec *codec, - const struct snd_pci_quirk *quirk, - const struct alc_fixup *fix, - int pre_init) +static void __alc_pick_fixup(struct hda_codec *codec, + const struct alc_fixup *fix, + const char *modelname, + int pre_init) { const struct alc_pincfg *cfg; struct alc_spec *spec; - quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk); - if (!quirk) - return; - fix += quirk->value; cfg = fix->pins; if (pre_init && fix->sku) { #ifdef CONFIG_SND_DEBUG_VERBOSE snd_printdd(KERN_INFO "hda_codec: %s: Apply sku override for %s\n", - codec->chip_name, quirk->name); + codec->chip_name, modelname); #endif spec = codec->spec; spec->cdefine.sku_cfg = fix->sku; @@ -1710,7 +1711,7 @@ static void alc_pick_fixup(struct hda_codec *codec, if (pre_init && cfg) { #ifdef CONFIG_SND_DEBUG_VERBOSE snd_printdd(KERN_INFO "hda_codec: %s: Apply pincfg for %s\n", - codec->chip_name, quirk->name); + codec->chip_name, modelname); #endif for (; cfg->nid; cfg++) snd_hda_codec_set_pincfg(codec, cfg->nid, cfg->val); @@ -1718,19 +1719,55 @@ static void alc_pick_fixup(struct hda_codec *codec, if (!pre_init && fix->verbs) { #ifdef CONFIG_SND_DEBUG_VERBOSE snd_printdd(KERN_INFO "hda_codec: %s: Apply fix-verbs for %s\n", - codec->chip_name, quirk->name); + codec->chip_name, modelname); #endif add_verb(codec->spec, fix->verbs); } if (fix->func) { #ifdef CONFIG_SND_DEBUG_VERBOSE snd_printdd(KERN_INFO "hda_codec: %s: Apply fix-func for %s\n", - codec->chip_name, quirk->name); + codec->chip_name, modelname); #endif fix->func(codec, fix, pre_init); } } +static void alc_pick_fixup(struct hda_codec *codec, + const struct snd_pci_quirk *quirk, + const struct alc_fixup *fix, + int pre_init) +{ + quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk); + if (quirk) { + fix += quirk->value; +#ifdef CONFIG_SND_DEBUG_VERBOSE + __alc_pick_fixup(codec, fix, quirk->name, pre_init); +#else + __alc_pick_fixup(codec, fix, NULL, pre_init); +#endif + } +} + +static void alc_pick_fixup_model(struct hda_codec *codec, + const struct alc_model_fixup *models, + const struct snd_pci_quirk *quirk, + const struct alc_fixup *fix, + int pre_init) +{ + if (codec->modelname && models) { + while (models->name) { + if (!strcmp(codec->modelname, models->name)) { + fix += models->id; + break; + } + models++; + } + __alc_pick_fixup(codec, fix, codec->modelname, pre_init); + } else { + alc_pick_fixup(codec, quirk, fix, pre_init); + } +} + static int alc_read_coef_idx(struct hda_codec *codec, unsigned int coef_idx) { -- cgit v1.2.3 From 6be7948ff4fa7662c1ee1994e1798074f8e832ed Mon Sep 17 00:00:00 2001 From: Todd Broch Date: Tue, 7 Dec 2010 16:51:05 -0800 Subject: ALSA: hda: Add fixup for mario system create fixup function for the mario model and override amp capabilities for NID 0x2 Signed-off-by: Todd Broch Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 9ba4279c690d..cd2d3a5efa50 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -19332,9 +19332,21 @@ static void alc662_auto_init(struct hda_codec *codec) alc_inithook(codec); } +static void alc272_fixup_mario(struct hda_codec *codec, + const struct alc_fixup *fix, int pre_init) { + if (snd_hda_override_amp_caps(codec, 0x2, HDA_OUTPUT, + (0x3b << AC_AMPCAP_OFFSET_SHIFT) | + (0x3b << AC_AMPCAP_NUM_STEPS_SHIFT) | + (0x03 << AC_AMPCAP_STEP_SIZE_SHIFT) | + (0 << AC_AMPCAP_MUTE_SHIFT))) + printk(KERN_WARNING + "hda_codec: failed to override amp caps for NID 0x2\n"); +} + enum { ALC662_FIXUP_ASPIRE, ALC662_FIXUP_IDEAPAD, + ALC272_FIXUP_MARIO, }; static const struct alc_fixup alc662_fixups[] = { @@ -19350,6 +19362,9 @@ static const struct alc_fixup alc662_fixups[] = { { } } }, + [ALC272_FIXUP_MARIO] = { + .func = alc272_fixup_mario, + } }; static struct snd_pci_quirk alc662_fixup_tbl[] = { @@ -19360,6 +19375,10 @@ static struct snd_pci_quirk alc662_fixup_tbl[] = { {} }; +static const struct alc_model_fixup alc662_fixup_models[] = { + {.id = ALC272_FIXUP_MARIO, .name = "mario"}, + {} +}; static int patch_alc662(struct hda_codec *codec) @@ -19459,7 +19478,8 @@ static int patch_alc662(struct hda_codec *codec) codec->patch_ops = alc_patch_ops; if (board_config == ALC662_AUTO) { spec->init_hook = alc662_auto_init; - alc_pick_fixup(codec, alc662_fixup_tbl, alc662_fixups, 0); + alc_pick_fixup_model(codec, alc662_fixup_models, + alc662_fixup_tbl, alc662_fixups, 0); } alc_init_jacks(codec); -- cgit v1.2.3 From 93430096f9d757104080f40f51afb2dada8877b5 Mon Sep 17 00:00:00 2001 From: Brian Bloniarz Date: Wed, 8 Dec 2010 12:45:20 -0800 Subject: ALSA: ice1712 - working M-Audio Delta 66E support Rev. E of the M-Audio Delta 66 is partially supported (commit ef2cd2ccad66b4aba518eca7514eface267ee0f3), but the layout of the GPIO pins was still unclear. This patch adds the GPIO definitions so that communication to the CS8247 & 2x AK4524 works correctly. ALSA bug#3327 has more details; users cap & jhunt report there that the GPIO wiring is similar to the Digigram VX442 (chip select: pin 4 = CS8427, pin 5 = AK4524 #0, pin 6 = AK4524 #1). There has been a lot of conflicting information in the bug, but given these definitions, my Delta 66E works; I tested analog in&out at 44.1kHz & 96kHz, analog gain settings, S/PDIF clock sync, and S/PDIF in&out at 44.1kHz. Signed-off-by: Brian Bloniarz Signed-off-by: Takashi Iwai --- sound/pci/ice1712/delta.c | 49 ++++++++++++++++++++++++++++++++++++++++++++++- sound/pci/ice1712/delta.h | 11 +++++++++++ 2 files changed, 59 insertions(+), 1 deletion(-) diff --git a/sound/pci/ice1712/delta.c b/sound/pci/ice1712/delta.c index 712c1710f9a2..7b62de089fee 100644 --- a/sound/pci/ice1712/delta.c +++ b/sound/pci/ice1712/delta.c @@ -96,6 +96,11 @@ static unsigned char ap_cs8427_codec_select(struct snd_ice1712 *ice) tmp |= ICE1712_DELTA_AP_CCLK | ICE1712_DELTA_AP_CS_CODEC; tmp &= ~ICE1712_DELTA_AP_CS_DIGITAL; break; + case ICE1712_SUBDEVICE_DELTA66E: + tmp |= ICE1712_DELTA_66E_CCLK | ICE1712_DELTA_66E_CS_CHIP_A | + ICE1712_DELTA_66E_CS_CHIP_B; + tmp &= ~ICE1712_DELTA_66E_CS_CS8427; + break; case ICE1712_SUBDEVICE_VX442: tmp |= ICE1712_VX442_CCLK | ICE1712_VX442_CODEC_CHIP_A | ICE1712_VX442_CODEC_CHIP_B; tmp &= ~ICE1712_VX442_CS_DIGITAL; @@ -119,6 +124,9 @@ static void ap_cs8427_codec_deassert(struct snd_ice1712 *ice, unsigned char tmp) case ICE1712_SUBDEVICE_DELTA410: tmp |= ICE1712_DELTA_AP_CS_DIGITAL; break; + case ICE1712_SUBDEVICE_DELTA66E: + tmp |= ICE1712_DELTA_66E_CS_CS8427; + break; case ICE1712_SUBDEVICE_VX442: tmp |= ICE1712_VX442_CS_DIGITAL; break; @@ -275,6 +283,20 @@ static void delta1010lt_ak4524_lock(struct snd_akm4xxx *ak, int chip) priv->cs_addr = chip << 4; } +/* + * AK4524 on Delta66 rev E to choose the chip address + */ +static void delta66e_ak4524_lock(struct snd_akm4xxx *ak, int chip) +{ + struct snd_ak4xxx_private *priv = (void *)ak->private_value[0]; + struct snd_ice1712 *ice = ak->private_data[0]; + + snd_ice1712_save_gpio_status(ice); + priv->cs_mask = + priv->cs_addr = chip == 0 ? ICE1712_DELTA_66E_CS_CHIP_A : + ICE1712_DELTA_66E_CS_CHIP_B; +} + /* * AK4528 on VX442 to choose the chip mask */ @@ -487,6 +509,29 @@ static struct snd_ak4xxx_private akm_delta1010lt_priv __devinitdata = { .mask_flags = 0, }; +static struct snd_akm4xxx akm_delta66e __devinitdata = { + .type = SND_AK4524, + .num_adcs = 4, + .num_dacs = 4, + .ops = { + .lock = delta66e_ak4524_lock, + .set_rate_val = delta_ak4524_set_rate_val + } +}; + +static struct snd_ak4xxx_private akm_delta66e_priv __devinitdata = { + .caddr = 2, + .cif = 0, /* the default level of the CIF pin from AK4524 */ + .data_mask = ICE1712_DELTA_66E_DOUT, + .clk_mask = ICE1712_DELTA_66E_CCLK, + .cs_mask = 0, + .cs_addr = 0, /* set later */ + .cs_none = 0, + .add_flags = 0, + .mask_flags = 0, +}; + + static struct snd_akm4xxx akm_delta44 __devinitdata = { .type = SND_AK4524, .num_adcs = 4, @@ -644,9 +689,11 @@ static int __devinit snd_ice1712_delta_init(struct snd_ice1712 *ice) err = snd_ice1712_akm4xxx_init(ak, &akm_delta44, &akm_delta44_priv, ice); break; case ICE1712_SUBDEVICE_VX442: - case ICE1712_SUBDEVICE_DELTA66E: err = snd_ice1712_akm4xxx_init(ak, &akm_vx442, &akm_vx442_priv, ice); break; + case ICE1712_SUBDEVICE_DELTA66E: + err = snd_ice1712_akm4xxx_init(ak, &akm_delta66e, &akm_delta66e_priv, ice); + break; default: snd_BUG(); return -EINVAL; diff --git a/sound/pci/ice1712/delta.h b/sound/pci/ice1712/delta.h index 1a0ac6cd6501..11a9c3a76507 100644 --- a/sound/pci/ice1712/delta.h +++ b/sound/pci/ice1712/delta.h @@ -144,6 +144,17 @@ extern struct snd_ice1712_card_info snd_ice1712_delta_cards[]; #define ICE1712_DELTA_1010LT_CS_NONE 0x50 /* nothing */ #define ICE1712_DELTA_1010LT_WORDCLOCK 0x80 /* sample clock source: 0 = Word Clock Input, 1 = S/PDIF Input ??? */ +/* M-Audio Delta 66 rev. E definitions. + * Newer revisions of Delta 66 have CS8427 over SPI for + * S/PDIF transceiver instead of CS8404/CS8414. */ +/* 0x01 = DFS */ +#define ICE1712_DELTA_66E_CCLK 0x02 /* SPI clock */ +#define ICE1712_DELTA_66E_DIN 0x04 /* data input */ +#define ICE1712_DELTA_66E_DOUT 0x08 /* data output */ +#define ICE1712_DELTA_66E_CS_CS8427 0x10 /* chip select, low = CS8427 */ +#define ICE1712_DELTA_66E_CS_CHIP_A 0x20 /* AK4524 #0 */ +#define ICE1712_DELTA_66E_CS_CHIP_B 0x40 /* AK4524 #1 */ + /* Digigram VX442 definitions */ #define ICE1712_VX442_CCLK 0x02 /* SPI clock */ #define ICE1712_VX442_DIN 0x04 /* data input */ -- cgit v1.2.3 From 9e87186fff939924da58b8f562ec275757e29776 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Wed, 8 Dec 2010 16:04:32 +0200 Subject: ASoC: tlv320dac33: Rename outpup amplifier widget Use better name for the widget, and remove the 'Power' from it's name. Signed-off-by: Peter Ujfalusi Acked-by: Mark Brown Signed-off-by: Liam Girdwood --- sound/soc/codecs/tlv320dac33.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/sound/soc/codecs/tlv320dac33.c b/sound/soc/codecs/tlv320dac33.c index a0ba5d1be1b3..e2e873ee47de 100644 --- a/sound/soc/codecs/tlv320dac33.c +++ b/sound/soc/codecs/tlv320dac33.c @@ -599,9 +599,9 @@ static const struct snd_soc_dapm_widget dac33_dapm_widgets[] = { SND_SOC_DAPM_SWITCH("Analog Right Bypass", SND_SOC_NOPM, 0, 0, &dac33_dapm_abypassr_control), - SND_SOC_DAPM_REG(snd_soc_dapm_mixer, "Output Left Amp Power", + SND_SOC_DAPM_REG(snd_soc_dapm_mixer, "Output Left Amplifier", DAC33_OUT_AMP_PWR_CTRL, 6, 3, 3, 0), - SND_SOC_DAPM_REG(snd_soc_dapm_mixer, "Output Right Amp Power", + SND_SOC_DAPM_REG(snd_soc_dapm_mixer, "Output Right Amplifier", DAC33_OUT_AMP_PWR_CTRL, 4, 3, 3, 0), SND_SOC_DAPM_PRE("Prepare Playback", playback_event), @@ -612,15 +612,15 @@ static const struct snd_soc_dapm_route audio_map[] = { {"Analog Left Bypass", "Switch", "LINEL"}, {"Analog Right Bypass", "Switch", "LINER"}, - {"Output Left Amp Power", NULL, "DACL"}, - {"Output Right Amp Power", NULL, "DACR"}, + {"Output Left Amplifier", NULL, "DACL"}, + {"Output Right Amplifier", NULL, "DACR"}, - {"Output Left Amp Power", NULL, "Analog Left Bypass"}, - {"Output Right Amp Power", NULL, "Analog Right Bypass"}, + {"Output Left Amplifier", NULL, "Analog Left Bypass"}, + {"Output Right Amplifier", NULL, "Analog Right Bypass"}, /* output */ - {"LEFT_LO", NULL, "Output Left Amp Power"}, - {"RIGHT_LO", NULL, "Output Right Amp Power"}, + {"LEFT_LO", NULL, "Output Left Amplifier"}, + {"RIGHT_LO", NULL, "Output Right Amplifier"}, }; static int dac33_add_widgets(struct snd_soc_codec *codec) -- cgit v1.2.3 From 76eac39ce5f64b95931a6026812e902cb8863a6c Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Wed, 8 Dec 2010 16:04:33 +0200 Subject: ASoC: tlv320dac33: Move DAC LR power on to a supply widget The power for the DACs need to be enabled, even when only the analog bypass is in use with the codec, otherwise the audio is going to be distorted. Make sure that the DACs are powered all the time, when there is audio activity. Signed-off-by: Peter Ujfalusi Acked-by: Mark Brown Signed-off-by: Liam Girdwood --- sound/soc/codecs/tlv320dac33.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/tlv320dac33.c b/sound/soc/codecs/tlv320dac33.c index e2e873ee47de..cee0f9912408 100644 --- a/sound/soc/codecs/tlv320dac33.c +++ b/sound/soc/codecs/tlv320dac33.c @@ -590,8 +590,8 @@ static const struct snd_soc_dapm_widget dac33_dapm_widgets[] = { SND_SOC_DAPM_INPUT("LINEL"), SND_SOC_DAPM_INPUT("LINER"), - SND_SOC_DAPM_DAC("DACL", "Left Playback", DAC33_LDAC_PWR_CTRL, 2, 0), - SND_SOC_DAPM_DAC("DACR", "Right Playback", DAC33_RDAC_PWR_CTRL, 2, 0), + SND_SOC_DAPM_DAC("DACL", "Left Playback", SND_SOC_NOPM, 0, 0), + SND_SOC_DAPM_DAC("DACR", "Right Playback", SND_SOC_NOPM, 0, 0), /* Analog bypass */ SND_SOC_DAPM_SWITCH("Analog Left Bypass", SND_SOC_NOPM, 0, 0, @@ -604,6 +604,11 @@ static const struct snd_soc_dapm_widget dac33_dapm_widgets[] = { SND_SOC_DAPM_REG(snd_soc_dapm_mixer, "Output Right Amplifier", DAC33_OUT_AMP_PWR_CTRL, 4, 3, 3, 0), + SND_SOC_DAPM_SUPPLY("Left DAC Power", + DAC33_LDAC_PWR_CTRL, 2, 0, NULL, 0), + SND_SOC_DAPM_SUPPLY("Right DAC Power", + DAC33_RDAC_PWR_CTRL, 2, 0, NULL, 0), + SND_SOC_DAPM_PRE("Prepare Playback", playback_event), }; @@ -618,6 +623,9 @@ static const struct snd_soc_dapm_route audio_map[] = { {"Output Left Amplifier", NULL, "Analog Left Bypass"}, {"Output Right Amplifier", NULL, "Analog Right Bypass"}, + {"Output Left Amplifier", NULL, "Left DAC Power"}, + {"Output Right Amplifier", NULL, "Right DAC Power"}, + /* output */ {"LEFT_LO", NULL, "Output Left Amplifier"}, {"RIGHT_LO", NULL, "Output Right Amplifier"}, -- cgit v1.2.3 From 3ee4fe15aba7531f75be4dcc331caa8f0c6369ec Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Wed, 8 Dec 2010 15:12:56 +0200 Subject: ASoC: tlv320dac33: Fix compillation error Fix the compilation error introduced by patch: ASoC: tlv320dac33: Avoid multiple soft power up Signed-off-by: Peter Ujfalusi Acked-by: Mark Brown Signed-off-by: Liam Girdwood --- sound/soc/codecs/tlv320dac33.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/soc/codecs/tlv320dac33.c b/sound/soc/codecs/tlv320dac33.c index cee0f9912408..b3445b362e96 100644 --- a/sound/soc/codecs/tlv320dac33.c +++ b/sound/soc/codecs/tlv320dac33.c @@ -646,6 +646,7 @@ static int dac33_add_widgets(struct snd_soc_codec *codec) static int dac33_set_bias_level(struct snd_soc_codec *codec, enum snd_soc_bias_level level) { + struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec); int ret; switch (level) { -- cgit v1.2.3 From 23ac3b61331137355064d8b22a3624fe1cd8527a Mon Sep 17 00:00:00 2001 From: Jorge Eduardo Candelaria Date: Wed, 8 Dec 2010 10:55:05 -0600 Subject: ASoC: sdp4430: Enable FM stereo pins Add FM stereo pins to the machine driver and add them as a dapm widget. Signed-off-by: Jorge Eduardo Candelaria Signed-off-by: Margarita Olaya Cabrera Acked-by: Mark Brown Signed-off-by: Liam Girdwood --- sound/soc/omap/sdp4430.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/sound/soc/omap/sdp4430.c b/sound/soc/omap/sdp4430.c index ebbd62fc447c..0c37c51313a8 100644 --- a/sound/soc/omap/sdp4430.c +++ b/sound/soc/omap/sdp4430.c @@ -101,6 +101,7 @@ static const struct snd_soc_dapm_widget sdp4430_twl6040_dapm_widgets[] = { SND_SOC_DAPM_MIC("Headset Mic", NULL), SND_SOC_DAPM_HP("Headset Stereophone", NULL), SND_SOC_DAPM_SPK("Earphone Spk", NULL), + SND_SOC_DAPM_INPUT("Aux/FM Stereo In"), }; static const struct snd_soc_dapm_route audio_map[] = { @@ -123,6 +124,10 @@ static const struct snd_soc_dapm_route audio_map[] = { /* Earphone speaker */ {"Earphone Spk", NULL, "EP"}, + + /* Aux/FM Stereo In: AFML, AFMR */ + {"AFML", NULL, "Aux/FM Stereo In"}, + {"AFMR", NULL, "Aux/FM Stereo In"}, }; static int sdp4430_twl6040_init(struct snd_soc_pcm_runtime *rtd) @@ -149,13 +154,11 @@ static int sdp4430_twl6040_init(struct snd_soc_pcm_runtime *rtd) /* SDP4430 connected pins */ snd_soc_dapm_enable_pin(dapm, "Ext Mic"); snd_soc_dapm_enable_pin(dapm, "Ext Spk"); + snd_soc_dapm_enable_pin(dapm, "AFML"); + snd_soc_dapm_enable_pin(dapm, "AFMR"); snd_soc_dapm_enable_pin(dapm, "Headset Mic"); snd_soc_dapm_enable_pin(dapm, "Headset Stereophone"); - /* TWL6040 not connected pins */ - snd_soc_dapm_nc_pin(dapm, "AFML"); - snd_soc_dapm_nc_pin(dapm, "AFMR"); - ret = snd_soc_dapm_sync(dapm); return ret; -- cgit v1.2.3 From fb67afda49220426af3ca570187faa910403e49a Mon Sep 17 00:00:00 2001 From: Alexander Sverdlin Date: Thu, 9 Dec 2010 03:43:49 +0300 Subject: ASoC: EP93xx: sampling rate range extended Changes to both I2S and PCM code: - Rates list extended up to 96kHz, it's tested on EDB9302 and works for both capture and playback. Signed-off-by: Alexander Sverdlin Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/ep93xx/ep93xx-i2s.c | 4 ++-- sound/soc/ep93xx/ep93xx-pcm.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/sound/soc/ep93xx/ep93xx-i2s.c b/sound/soc/ep93xx/ep93xx-i2s.c index 4f4873359613..9ac93f6b4f85 100644 --- a/sound/soc/ep93xx/ep93xx-i2s.c +++ b/sound/soc/ep93xx/ep93xx-i2s.c @@ -352,13 +352,13 @@ static struct snd_soc_dai_driver ep93xx_i2s_dai = { .playback = { .channels_min = 2, .channels_max = 2, - .rates = SNDRV_PCM_RATE_8000_48000, + .rates = SNDRV_PCM_RATE_8000_96000, .formats = EP93XX_I2S_FORMATS, }, .capture = { .channels_min = 2, .channels_max = 2, - .rates = SNDRV_PCM_RATE_8000_48000, + .rates = SNDRV_PCM_RATE_8000_96000, .formats = EP93XX_I2S_FORMATS, }, .ops = &ep93xx_i2s_dai_ops, diff --git a/sound/soc/ep93xx/ep93xx-pcm.c b/sound/soc/ep93xx/ep93xx-pcm.c index 2f121ddbe4bb..06670776f649 100644 --- a/sound/soc/ep93xx/ep93xx-pcm.c +++ b/sound/soc/ep93xx/ep93xx-pcm.c @@ -35,9 +35,9 @@ static const struct snd_pcm_hardware ep93xx_pcm_hardware = { SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER), - .rates = SNDRV_PCM_RATE_8000_48000, + .rates = SNDRV_PCM_RATE_8000_96000, .rate_min = SNDRV_PCM_RATE_8000, - .rate_max = SNDRV_PCM_RATE_48000, + .rate_max = SNDRV_PCM_RATE_96000, .formats = (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE | -- cgit v1.2.3 From 05d209ad3b66efbb0925f01f1b3369fcbf31c86f Mon Sep 17 00:00:00 2001 From: Seungwhan Youn Date: Thu, 9 Dec 2010 13:17:39 +0900 Subject: ASoC: Remove unnecessary structure definitions This patch removes some legacy structure definitions which are not using in current ASoC drivers. Signed-off-by: Seungwhan Youn Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- include/sound/soc.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/include/sound/soc.h b/include/sound/soc.h index 0a962dc42c5b..7e65b015f8dd 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -222,10 +222,8 @@ enum snd_soc_bias_level { struct snd_jack; struct snd_soc_card; -struct snd_soc_device; struct snd_soc_pcm_stream; struct snd_soc_ops; -struct snd_soc_dai_mode; struct snd_soc_pcm_runtime; struct snd_soc_dai; struct snd_soc_dai_driver; @@ -235,7 +233,6 @@ struct snd_soc_platform_driver; struct snd_soc_codec; struct snd_soc_codec_driver; struct soc_enum; -struct snd_soc_ac97_ops; struct snd_soc_jack; struct snd_soc_jack_pin; struct snd_soc_cache_ops; -- cgit v1.2.3 From 6a66bbd693c12f71697c61207aa18bc5a12da0ab Mon Sep 17 00:00:00 2001 From: Chase Douglas Date: Wed, 8 Dec 2010 15:08:04 -0800 Subject: HID: magicmouse: Don't report REL_{X,Y} for Magic Trackpad With the recent switch to having the hid layer handle standard axis initialization, the Magic Trackpad now reports relative axes. This would be fine in the normal mode, but the driver puts the device in multitouch mode where no relative events are generated. Also, userspace software depends on accurate axis information for device type detection. Thus, ignoring the relative axes from the Magic Trackpad is best. Signed-off-by: Chase Douglas Signed-off-by: Jiri Kosina --- drivers/hid/hid-magicmouse.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c index e6dc15171664..ed732b746c96 100644 --- a/drivers/hid/hid-magicmouse.c +++ b/drivers/hid/hid-magicmouse.c @@ -433,6 +433,11 @@ static int magicmouse_input_mapping(struct hid_device *hdev, if (!msc->input) msc->input = hi->input; + /* Magic Trackpad does not give relative data after switching to MT */ + if (hi->input->id.product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD && + field->flags & HID_MAIN_ITEM_RELATIVE) + return -1; + return 0; } -- cgit v1.2.3 From ff7ea4c04012e01a9a50c5e42dabdaf0794734ce Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 8 Dec 2010 09:43:41 +0000 Subject: drm/i915: Re-arm the idle timers if the device is still busy Don't post a downclocking task if the device is still active when the idle timer fires. A pathological process could queue up several seconds worth of processing and then go to sleep, during which time the idle timer would kick in and downclock the GPU. Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/intel_display.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 1ccf2ad7cd88..6d4faff8121b 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -4758,8 +4758,14 @@ static void intel_gpu_idle_timer(unsigned long arg) struct drm_device *dev = (struct drm_device *)arg; drm_i915_private_t *dev_priv = dev->dev_private; - dev_priv->busy = false; + if (!list_empty(&dev_priv->mm.active_list)) { + /* Still processing requests, so just re-arm the timer. */ + mod_timer(&dev_priv->idle_timer, jiffies + + msecs_to_jiffies(GPU_IDLE_TIMEOUT)); + return; + } + dev_priv->busy = false; queue_work(dev_priv->wq, &dev_priv->idle_work); } @@ -4770,9 +4776,17 @@ static void intel_crtc_idle_timer(unsigned long arg) struct intel_crtc *intel_crtc = (struct intel_crtc *)arg; struct drm_crtc *crtc = &intel_crtc->base; drm_i915_private_t *dev_priv = crtc->dev->dev_private; + struct intel_framebuffer *intel_fb; - intel_crtc->busy = false; + intel_fb = to_intel_framebuffer(crtc->fb); + if (intel_fb && intel_fb->obj->active) { + /* The framebuffer is still being accessed by the GPU. */ + mod_timer(&intel_crtc->idle_timer, jiffies + + msecs_to_jiffies(CRTC_IDLE_TIMEOUT)); + return; + } + intel_crtc->busy = false; queue_work(dev_priv->wq, &dev_priv->idle_work); } -- cgit v1.2.3 From 67731b87e9572801c41f8fe779750babdd362416 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 8 Dec 2010 10:38:14 +0000 Subject: drm/i915: Eliminate drm_gem_object_lookup during relocation As we provide a list of all objects that will be accessed from the batchbuffer, we can build a lut of the handles associated with those objects for this invocation and use that to avoid the overhead of looking up those objects again for every relocation. The cost of building and searching a small hash table is much less than that of acquiring a spinlock, searching a radix tree and manipulating an atomic refcnt per relocation. Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_drv.h | 6 ++ drivers/gpu/drm/i915/i915_gem_execbuffer.c | 150 +++++++++++++++++++++++------ 2 files changed, 129 insertions(+), 27 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index d9b54a27ccf8..b8a55008a1b5 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -788,6 +788,12 @@ struct drm_i915_gem_object { struct scatterlist *sg_list; int num_sg; + /** + * Used for performing relocations during execbuffer insertion. + */ + struct hlist_node exec_node; + unsigned long exec_handle; + /** * Current offset of the object in GTT space. * diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index 1b2ceacd64f0..3305ae528de4 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c @@ -207,9 +207,67 @@ i915_gem_object_set_to_gpu_domain(struct drm_i915_gem_object *obj, cd->flush_rings |= ring->id; } +struct eb_objects { + int and; + struct hlist_head buckets[0]; +}; + +static struct eb_objects * +eb_create(int size) +{ + struct eb_objects *eb; + int count = PAGE_SIZE / sizeof(struct hlist_head) / 2; + while (count > size) + count >>= 1; + eb = kzalloc(count*sizeof(struct hlist_head) + + sizeof(struct eb_objects), + GFP_KERNEL); + if (eb == NULL) + return eb; + + eb->and = count - 1; + return eb; +} + +static void +eb_reset(struct eb_objects *eb) +{ + memset(eb->buckets, 0, (eb->and+1)*sizeof(struct hlist_head)); +} + +static void +eb_add_object(struct eb_objects *eb, struct drm_i915_gem_object *obj) +{ + hlist_add_head(&obj->exec_node, + &eb->buckets[obj->exec_handle & eb->and]); +} + +static struct drm_i915_gem_object * +eb_get_object(struct eb_objects *eb, unsigned long handle) +{ + struct hlist_head *head; + struct hlist_node *node; + struct drm_i915_gem_object *obj; + + head = &eb->buckets[handle & eb->and]; + hlist_for_each(node, head) { + obj = hlist_entry(node, struct drm_i915_gem_object, exec_node); + if (obj->exec_handle == handle) + return obj; + } + + return NULL; +} + +static void +eb_destroy(struct eb_objects *eb) +{ + kfree(eb); +} + static int i915_gem_execbuffer_relocate_entry(struct drm_i915_gem_object *obj, - struct drm_file *file_priv, + struct eb_objects *eb, struct drm_i915_gem_exec_object2 *entry, struct drm_i915_gem_relocation_entry *reloc) { @@ -218,9 +276,9 @@ i915_gem_execbuffer_relocate_entry(struct drm_i915_gem_object *obj, uint32_t target_offset; int ret = -EINVAL; - target_obj = drm_gem_object_lookup(dev, file_priv, - reloc->target_handle); - if (target_obj == NULL) + /* we've already hold a reference to all valid objects */ + target_obj = &eb_get_object(eb, reloc->target_handle)->base; + if (unlikely(target_obj == NULL)) return -ENOENT; target_offset = to_intel_bo(target_obj)->gtt_offset; @@ -246,7 +304,7 @@ i915_gem_execbuffer_relocate_entry(struct drm_i915_gem_object *obj, if (target_offset == 0) { DRM_ERROR("No GTT space found for object %d\n", reloc->target_handle); - goto err; + return ret; } /* Validate that the target is in a valid r/w GPU domain */ @@ -258,7 +316,7 @@ i915_gem_execbuffer_relocate_entry(struct drm_i915_gem_object *obj, (int) reloc->offset, reloc->read_domains, reloc->write_domain); - goto err; + return ret; } if (reloc->write_domain & I915_GEM_DOMAIN_CPU || reloc->read_domains & I915_GEM_DOMAIN_CPU) { @@ -269,7 +327,7 @@ i915_gem_execbuffer_relocate_entry(struct drm_i915_gem_object *obj, (int) reloc->offset, reloc->read_domains, reloc->write_domain); - goto err; + return ret; } if (reloc->write_domain && target_obj->pending_write_domain && reloc->write_domain != target_obj->pending_write_domain) { @@ -280,7 +338,7 @@ i915_gem_execbuffer_relocate_entry(struct drm_i915_gem_object *obj, (int) reloc->offset, reloc->write_domain, target_obj->pending_write_domain); - goto err; + return ret; } target_obj->pending_read_domains |= reloc->read_domains; @@ -290,7 +348,7 @@ i915_gem_execbuffer_relocate_entry(struct drm_i915_gem_object *obj, * more work needs to be done. */ if (target_offset == reloc->presumed_offset) - goto out; + return 0; /* Check that the relocation address is valid... */ if (reloc->offset > obj->base.size - 4) { @@ -299,14 +357,14 @@ i915_gem_execbuffer_relocate_entry(struct drm_i915_gem_object *obj, obj, reloc->target_handle, (int) reloc->offset, (int) obj->base.size); - goto err; + return ret; } if (reloc->offset & 3) { DRM_ERROR("Relocation not 4-byte aligned: " "obj %p target %d offset %d.\n", obj, reloc->target_handle, (int) reloc->offset); - goto err; + return ret; } /* and points to somewhere within the target object. */ @@ -316,7 +374,7 @@ i915_gem_execbuffer_relocate_entry(struct drm_i915_gem_object *obj, obj, reloc->target_handle, (int) reloc->delta, (int) target_obj->size); - goto err; + return ret; } reloc->delta += target_offset; @@ -334,7 +392,7 @@ i915_gem_execbuffer_relocate_entry(struct drm_i915_gem_object *obj, ret = i915_gem_object_set_to_gtt_domain(obj, 1); if (ret) - goto err; + return ret; /* Map the page containing the relocation we're going to perform. */ reloc->offset += obj->gtt_offset; @@ -349,16 +407,12 @@ i915_gem_execbuffer_relocate_entry(struct drm_i915_gem_object *obj, /* and update the user's relocation entry */ reloc->presumed_offset = target_offset; -out: - ret = 0; -err: - drm_gem_object_unreference(target_obj); - return ret; + return 0; } static int i915_gem_execbuffer_relocate_object(struct drm_i915_gem_object *obj, - struct drm_file *file_priv, + struct eb_objects *eb, struct drm_i915_gem_exec_object2 *entry) { struct drm_i915_gem_relocation_entry __user *user_relocs; @@ -373,7 +427,7 @@ i915_gem_execbuffer_relocate_object(struct drm_i915_gem_object *obj, sizeof(reloc))) return -EFAULT; - ret = i915_gem_execbuffer_relocate_entry(obj, file_priv, entry, &reloc); + ret = i915_gem_execbuffer_relocate_entry(obj, eb, entry, &reloc); if (ret) return ret; @@ -388,14 +442,14 @@ i915_gem_execbuffer_relocate_object(struct drm_i915_gem_object *obj, static int i915_gem_execbuffer_relocate_object_slow(struct drm_i915_gem_object *obj, - struct drm_file *file_priv, + struct eb_objects *eb, struct drm_i915_gem_exec_object2 *entry, struct drm_i915_gem_relocation_entry *relocs) { int i, ret; for (i = 0; i < entry->relocation_count; i++) { - ret = i915_gem_execbuffer_relocate_entry(obj, file_priv, entry, &relocs[i]); + ret = i915_gem_execbuffer_relocate_entry(obj, eb, entry, &relocs[i]); if (ret) return ret; } @@ -405,7 +459,7 @@ i915_gem_execbuffer_relocate_object_slow(struct drm_i915_gem_object *obj, static int i915_gem_execbuffer_relocate(struct drm_device *dev, - struct drm_file *file, + struct eb_objects *eb, struct list_head *objects, struct drm_i915_gem_exec_object2 *exec) { @@ -415,7 +469,7 @@ i915_gem_execbuffer_relocate(struct drm_device *dev, list_for_each_entry(obj, objects, exec_list) { obj->base.pending_read_domains = 0; obj->base.pending_write_domain = 0; - ret = i915_gem_execbuffer_relocate_object(obj, file, exec++); + ret = i915_gem_execbuffer_relocate_object(obj, eb, exec++); if (ret) return ret; } @@ -560,6 +614,7 @@ i915_gem_execbuffer_relocate_slow(struct drm_device *dev, struct drm_file *file, struct intel_ring_buffer *ring, struct list_head *objects, + struct eb_objects *eb, struct drm_i915_gem_exec_object2 *exec, int count) { @@ -567,6 +622,15 @@ i915_gem_execbuffer_relocate_slow(struct drm_device *dev, struct drm_i915_gem_object *obj; int i, total, ret; + /* We may process another execbuffer during the unlock... */ + while (list_empty(objects)) { + obj = list_first_entry(objects, + struct drm_i915_gem_object, + exec_list); + list_del_init(&obj->exec_list); + drm_gem_object_unreference(&obj->base); + } + mutex_unlock(&dev->struct_mutex); total = 0; @@ -601,6 +665,26 @@ i915_gem_execbuffer_relocate_slow(struct drm_device *dev, goto err; } + /* reacquire the objects */ + INIT_LIST_HEAD(objects); + eb_reset(eb); + for (i = 0; i < count; i++) { + struct drm_i915_gem_object *obj; + + obj = to_intel_bo(drm_gem_object_lookup(dev, file, + exec[i].handle)); + if (obj == NULL) { + DRM_ERROR("Invalid object handle %d at index %d\n", + exec[i].handle, i); + ret = -ENOENT; + goto err; + } + + list_add_tail(&obj->exec_list, objects); + obj->exec_handle = exec[i].handle; + eb_add_object(eb, obj); + } + ret = i915_gem_execbuffer_reserve(ring, file, objects, exec); if (ret) goto err; @@ -609,7 +693,7 @@ i915_gem_execbuffer_relocate_slow(struct drm_device *dev, list_for_each_entry(obj, objects, exec_list) { obj->base.pending_read_domains = 0; obj->base.pending_write_domain = 0; - ret = i915_gem_execbuffer_relocate_object_slow(obj, file, + ret = i915_gem_execbuffer_relocate_object_slow(obj, eb, exec, reloc + total); if (ret) @@ -868,6 +952,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, { drm_i915_private_t *dev_priv = dev->dev_private; struct list_head objects; + struct eb_objects *eb; struct drm_i915_gem_object *batch_obj; struct drm_clip_rect *cliprects = NULL; struct intel_ring_buffer *ring; @@ -950,6 +1035,13 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, goto pre_mutex_err; } + eb = eb_create(args->buffer_count); + if (eb == NULL) { + mutex_unlock(&dev->struct_mutex); + ret = -ENOMEM; + goto pre_mutex_err; + } + /* Look up object handles */ INIT_LIST_HEAD(&objects); for (i = 0; i < args->buffer_count; i++) { @@ -973,6 +1065,8 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, } list_add_tail(&obj->exec_list, &objects); + obj->exec_handle = exec[i].handle; + eb_add_object(eb, obj); } /* Move the objects en-masse into the GTT, evicting if necessary. */ @@ -981,11 +1075,12 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, goto err; /* The objects are in their final locations, apply the relocations. */ - ret = i915_gem_execbuffer_relocate(dev, file, &objects, exec); + ret = i915_gem_execbuffer_relocate(dev, eb, &objects, exec); if (ret) { if (ret == -EFAULT) { ret = i915_gem_execbuffer_relocate_slow(dev, file, ring, - &objects, exec, + &objects, eb, + exec, args->buffer_count); BUG_ON(!mutex_is_locked(&dev->struct_mutex)); } @@ -1051,6 +1146,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, i915_gem_execbuffer_retire_commands(dev, file, ring); err: + eb_destroy(eb); while (!list_empty(&objects)) { struct drm_i915_gem_object *obj; -- cgit v1.2.3 From b8f7ab1788f23d79084f051bb9ae3cb02b55bff3 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 8 Dec 2010 10:43:06 +0000 Subject: drm/i915: Mark the user reloc error paths as unlikely Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_gem_execbuffer.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index 3305ae528de4..fda0dc858a1f 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c @@ -301,14 +301,14 @@ i915_gem_execbuffer_relocate_entry(struct drm_i915_gem_object *obj, /* The target buffer should have appeared before us in the * exec_object list, so it should have a GTT space bound by now. */ - if (target_offset == 0) { + if (unlikely(target_offset == 0)) { DRM_ERROR("No GTT space found for object %d\n", reloc->target_handle); return ret; } /* Validate that the target is in a valid r/w GPU domain */ - if (reloc->write_domain & (reloc->write_domain - 1)) { + if (unlikely(reloc->write_domain & (reloc->write_domain - 1))) { DRM_ERROR("reloc with multiple write domains: " "obj %p target %d offset %d " "read %08x write %08x", @@ -318,8 +318,7 @@ i915_gem_execbuffer_relocate_entry(struct drm_i915_gem_object *obj, reloc->write_domain); return ret; } - if (reloc->write_domain & I915_GEM_DOMAIN_CPU || - reloc->read_domains & I915_GEM_DOMAIN_CPU) { + if (unlikely((reloc->write_domain | reloc->read_domains) & I915_GEM_DOMAIN_CPU)) { DRM_ERROR("reloc with read/write CPU domains: " "obj %p target %d offset %d " "read %08x write %08x", @@ -329,8 +328,8 @@ i915_gem_execbuffer_relocate_entry(struct drm_i915_gem_object *obj, reloc->write_domain); return ret; } - if (reloc->write_domain && target_obj->pending_write_domain && - reloc->write_domain != target_obj->pending_write_domain) { + if (unlikely(reloc->write_domain && target_obj->pending_write_domain && + reloc->write_domain != target_obj->pending_write_domain)) { DRM_ERROR("Write domain conflict: " "obj %p target %d offset %d " "new %08x old %08x\n", @@ -351,7 +350,7 @@ i915_gem_execbuffer_relocate_entry(struct drm_i915_gem_object *obj, return 0; /* Check that the relocation address is valid... */ - if (reloc->offset > obj->base.size - 4) { + if (unlikely(reloc->offset > obj->base.size - 4)) { DRM_ERROR("Relocation beyond object bounds: " "obj %p target %d offset %d size %d.\n", obj, reloc->target_handle, @@ -359,7 +358,7 @@ i915_gem_execbuffer_relocate_entry(struct drm_i915_gem_object *obj, (int) obj->base.size); return ret; } - if (reloc->offset & 3) { + if (unlikely(reloc->offset & 3)) { DRM_ERROR("Relocation not 4-byte aligned: " "obj %p target %d offset %d.\n", obj, reloc->target_handle, @@ -368,7 +367,7 @@ i915_gem_execbuffer_relocate_entry(struct drm_i915_gem_object *obj, } /* and points to somewhere within the target object. */ - if (reloc->delta >= target_obj->size) { + if (unlikely(reloc->delta >= target_obj->size)) { DRM_ERROR("Relocation beyond target object bounds: " "obj %p target %d delta %d size %d.\n", obj, reloc->target_handle, -- cgit v1.2.3 From 4a19d02e0a8cd8799e5d150d8eb74861e1a4cdec Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 8 Dec 2010 13:31:49 +0000 Subject: drm/i915: driver.suspend and .resume are always set So we can remove the repeated initialisation. Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_drv.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 91a3ad2cf942..ad28b21f4d03 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -700,11 +700,6 @@ static int __init i915_init(void) driver.driver_features &= ~DRIVER_MODESET; #endif - if (!(driver.driver_features & DRIVER_MODESET)) { - driver.suspend = i915_suspend; - driver.resume = i915_resume; - } - return drm_init(&driver); } -- cgit v1.2.3 From d1c3b177b9940541e89015a726ac279caf1a21f3 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 8 Dec 2010 14:26:19 +0000 Subject: drm/i915: Restore GTT mapping first upon resume As suggested by Daniel Vetter, this is a safeguard should any of the registers cause reference to PTE entries. Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_drv.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index ad28b21f4d03..2be344a8e93b 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -304,13 +304,18 @@ static int i915_drm_thaw(struct drm_device *dev) struct drm_i915_private *dev_priv = dev->dev_private; int error = 0; + if (drm_core_check_feature(dev, DRIVER_MODESET)) { + mutex_lock(&dev->struct_mutex); + i915_gem_restore_gtt_mappings(dev); + mutex_unlock(&dev->struct_mutex); + } + i915_restore_state(dev); intel_opregion_setup(dev); /* KMS EnterVT equivalent */ if (drm_core_check_feature(dev, DRIVER_MODESET)) { mutex_lock(&dev->struct_mutex); - i915_gem_restore_gtt_mappings(dev); dev_priv->mm.suspended = 0; error = i915_gem_init_ringbuffer(dev); -- cgit v1.2.3 From a8e93126a6f10d0a14ba8407ec112b1b3a5e2e97 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 8 Dec 2010 14:28:54 +0000 Subject: drm/i915/gtt: Clear the cachelines upon resume Required for my pineview system to not barf after resuming. Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_gem_gtt.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index 71c2b0f3747b..86673e77d7cb 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c @@ -35,6 +35,8 @@ void i915_gem_restore_gtt_mappings(struct drm_device *dev) struct drm_i915_gem_object *obj; list_for_each_entry(obj, &dev_priv->mm.gtt_list, gtt_list) { + i915_gem_clflush_object(obj); + if (dev_priv->mm.gtt->needs_dmar) { BUG_ON(!obj->sg_list); @@ -51,7 +53,6 @@ void i915_gem_restore_gtt_mappings(struct drm_device *dev) obj->agp_type); } - /* Be paranoid and flush the chipset cache. */ intel_gtt_chipset_flush(); } -- cgit v1.2.3 From eb43f4af7ecb7d51ba44f5e96bf74eedf1c27d62 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 8 Dec 2010 17:32:24 +0000 Subject: drm/i915: Terminate the FORCE WAKE after we have finished reading Once we have read the value out of the GT power well, we need to remove the FORCE WAKE bit to allow the system to auto-power down. Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_drv.c | 22 ++++++++++++++++++++++ drivers/gpu/drm/i915/i915_drv.h | 21 ++++++++++++--------- drivers/gpu/drm/i915/i915_reg.h | 1 + 3 files changed, 35 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 2be344a8e93b..5f20cd988612 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -244,6 +244,28 @@ void intel_detect_pch (struct drm_device *dev) } } +void __gen6_force_wake_get(struct drm_i915_private *dev_priv) +{ + int count; + + count = 0; + while (count++ < 50 && (I915_READ_NOTRACE(FORCEWAKE_ACK) & 1)) + udelay(10); + + I915_WRITE_NOTRACE(FORCEWAKE, 1); + POSTING_READ(FORCEWAKE); + + count = 0; + while (count++ < 50 && (I915_READ_NOTRACE(FORCEWAKE_ACK) & 1) == 0) + udelay(10); +} + +void __gen6_force_wake_put(struct drm_i915_private *dev_priv) +{ + I915_WRITE_NOTRACE(FORCEWAKE, 0); + POSTING_READ(FORCEWAKE); +} + static int i915_drm_freeze(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index b8a55008a1b5..30780f2cab6f 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1341,17 +1341,20 @@ __i915_write(64, q) * must be set to prevent GT core from power down and stale values being * returned. */ +void __gen6_force_wake_get(struct drm_i915_private *dev_priv); +void __gen6_force_wake_put (struct drm_i915_private *dev_priv); static inline u32 i915_safe_read(struct drm_i915_private *dev_priv, u32 reg) { - if (IS_GEN6(dev_priv->dev)) { - I915_WRITE_NOTRACE(FORCEWAKE, 1); - POSTING_READ(FORCEWAKE); - /* XXX How long do we really need to wait here? - * Will different registers/engines require different periods? - */ - udelay(100); - } - return I915_READ(reg); + u32 val; + + if (dev_priv->info->gen >= 6) { + __gen6_force_wake_get(dev_priv); + val = I915_READ(reg); + __gen6_force_wake_put(dev_priv); + } else + val = I915_READ(reg); + + return val; } static inline void diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 3e03094cf148..2a36e05f1b85 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -3115,4 +3115,5 @@ #define EDP_LINK_TRAIN_VOL_EMP_MASK_SNB (0x3f<<22) #define FORCEWAKE 0xA18C +#define FORCEWAKE_ACK 0x130090 #endif /* _I915_REG_H_ */ -- cgit v1.2.3 From 8fd2685911cb6c140e6d0588ac04990ce65d4537 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 8 Dec 2010 18:40:43 +0000 Subject: drm/i915: Enable RC6 autodownclocking on Sandybridge Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_reg.h | 59 ++++++++++++++++++++++++ drivers/gpu/drm/i915/intel_display.c | 89 ++++++++++++++++++++++++++++++++++++ 2 files changed, 148 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 2a36e05f1b85..b284c13fd632 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -283,6 +283,7 @@ #define RING_CTL(base) ((base)+0x3c) #define RING_SYNC_0(base) ((base)+0x40) #define RING_SYNC_1(base) ((base)+0x44) +#define RING_MAX_IDLE(base) ((base)+0x54) #define RING_HWS_PGA(base) ((base)+0x80) #define RING_HWS_PGA_GEN6(base) ((base)+0x2080) #define RING_ACTHD(base) ((base)+0x74) @@ -3116,4 +3117,62 @@ #define FORCEWAKE 0xA18C #define FORCEWAKE_ACK 0x130090 + +#define GEN6_RC_NORMAL_FREQ 0xA008 +#define GEN6_TURBO_DISABLE (1<<31) +#define GEN6_FREQUENCY(x) ((x)<<25) +#define GEN6_OFFSET(x) ((x)<<19) +#define GEN6_AGGRESSIVE_TURBO (0<<15) +#define GEN6_RC_VIDEO_FREQ 0xA00C +#define GEN6_RC_CONTROL 0xA090 +#define GEN6_RC_CTL_RC6pp_ENABLE (1<<16) +#define GEN6_RC_CTL_RC6p_ENABLE (1<<17) +#define GEN6_RC_CTL_RC6_ENABLE (1<<18) +#define GEN6_RC_CTL_RC1e_ENABLE (1<<20) +#define GEN6_RC_CTL_RC7_ENABLE (1<<22) +#define GEN6_RC_CTL_EI_MODE(x) ((x)<<27) +#define GEN6_RC_CTL_HW_ENABLE (1<<31) +#define GEN6_RP_DOWN_TIMEOUT 0xA010 +#define GEN6_RP_INTERRUPT_LIMITS 0xA014 +#define GEN6_RP_CONTROL 0xA024 +#define GEN6_RP_MEDIA_TURBO (1<<11) +#define GEN6_RP_USE_NORMAL_FREQ (1<<9) +#define GEN6_RP_MEDIA_IS_GFX (1<<8) +#define GEN6_RP_ENABLE (1<<7) +#define GEN6_RP_UP_BUSY_MAX (0x2<<3) +#define GEN6_RP_DOWN_BUSY_MIN (0x2<<0) +#define GEN6_RP_UP_THRESHOLD 0xA02C +#define GEN6_RP_DOWN_THRESHOLD 0xA030 +#define GEN6_RP_UP_EI 0xA068 +#define GEN6_RP_DOWN_EI 0xA06C +#define GEN6_RP_IDLE_HYSTERSIS 0xA070 +#define GEN6_RC_STATE 0xA094 +#define GEN6_RC1_WAKE_RATE_LIMIT 0xA098 +#define GEN6_RC6_WAKE_RATE_LIMIT 0xA09C +#define GEN6_RC6pp_WAKE_RATE_LIMIT 0xA0A0 +#define GEN6_RC_EVALUATION_INTERVAL 0xA0A8 +#define GEN6_RC_IDLE_HYSTERSIS 0xA0AC +#define GEN6_RC_SLEEP 0xA0B0 +#define GEN6_RC1e_THRESHOLD 0xA0B4 +#define GEN6_RC6_THRESHOLD 0xA0B8 +#define GEN6_RC6p_THRESHOLD 0xA0BC +#define GEN6_RC6pp_THRESHOLD 0xA0C0 + +#define GEN6_PMISR 0x44020 +#define GEN6_PMIMR 0x44024 +#define GEN6_PMIIR 0x44028 +#define GEN6_PMIER 0x4402C +#define GEN6_PM_MBOX_EVENT (1<<25) +#define GEN6_PM_THERMAL_EVENT (1<<24) +#define GEN6_PM_RP_DOWN_TIMEOUT (1<<6) +#define GEN6_PM_RP_UP_THRESHOLD (1<<5) +#define GEN6_PM_RP_DOWN_THRESHOLD (1<<4) +#define GEN6_PM_RP_UP_EI_EXPIRED (1<<2) +#define GEN6_PM_RP_DOWN_EI_EXPIRED (1<<1) + +#define GEN6_PCODE_MAILBOX 0x138124 +#define GEN6_PCODE_READY (1<<31) +#define GEN6_PCODE_WRITE_MIN_FREQ_TABLE 0x9 +#define GEN6_PCODE_DATA 0x138128 + #endif /* _I915_REG_H_ */ diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 6d4faff8121b..17c213fef0ec 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -5842,6 +5842,91 @@ void intel_init_emon(struct drm_device *dev) dev_priv->corr = (lcfuse & LCFUSE_HIV_MASK); } +static void gen6_enable_rc6(struct drm_i915_private *dev_priv) +{ + int i; + + /* Here begins a magic sequence of register writes to enable + * auto-downclocking. + * + * Perhaps there might be some value in exposing these to + * userspace... + */ + I915_WRITE(GEN6_RC_STATE, 0); + __gen6_force_wake_get(dev_priv); + + /* disable the counters and set determistic thresholds */ + I915_WRITE(GEN6_RC_CONTROL, 0); + + I915_WRITE(GEN6_RC1_WAKE_RATE_LIMIT, 1000 << 16); + I915_WRITE(GEN6_RC6_WAKE_RATE_LIMIT, 40 << 16 | 30); + I915_WRITE(GEN6_RC6pp_WAKE_RATE_LIMIT, 30); + I915_WRITE(GEN6_RC_EVALUATION_INTERVAL, 125000); + I915_WRITE(GEN6_RC_IDLE_HYSTERSIS, 25); + + for (i = 0; i < I915_NUM_RINGS; i++) + I915_WRITE(RING_MAX_IDLE(dev_priv->ring[i].mmio_base), 10); + + I915_WRITE(GEN6_RC_SLEEP, 0); + I915_WRITE(GEN6_RC1e_THRESHOLD, 1000); + I915_WRITE(GEN6_RC6_THRESHOLD, 50000); + I915_WRITE(GEN6_RC6p_THRESHOLD, 100000); + I915_WRITE(GEN6_RC6pp_THRESHOLD, 64000); /* unused */ + + I915_WRITE(GEN6_RC_CONTROL, + GEN6_RC_CTL_RC6p_ENABLE | + GEN6_RC_CTL_RC6_ENABLE | + GEN6_RC_CTL_HW_ENABLE); + + I915_WRITE(GEN6_RC_NORMAL_FREQ, + GEN6_FREQUENCY(10) | + GEN6_OFFSET(0) | + GEN6_AGGRESSIVE_TURBO); + I915_WRITE(GEN6_RC_VIDEO_FREQ, + GEN6_FREQUENCY(12)); + + I915_WRITE(GEN6_RP_DOWN_TIMEOUT, 1000000); + I915_WRITE(GEN6_RP_INTERRUPT_LIMITS, + 18 << 24 | + 6 << 16); + I915_WRITE(GEN6_RP_UP_THRESHOLD, 90000); + I915_WRITE(GEN6_RP_DOWN_THRESHOLD, 100000); + I915_WRITE(GEN6_RP_UP_EI, 100000); + I915_WRITE(GEN6_RP_DOWN_EI, 300000); + I915_WRITE(GEN6_RP_IDLE_HYSTERSIS, 10); + I915_WRITE(GEN6_RP_CONTROL, + GEN6_RP_MEDIA_TURBO | + GEN6_RP_USE_NORMAL_FREQ | + GEN6_RP_MEDIA_IS_GFX | + GEN6_RP_ENABLE | + GEN6_RP_UP_BUSY_MAX | + GEN6_RP_DOWN_BUSY_MIN); + + if (wait_for((I915_READ(GEN6_PCODE_MAILBOX) & GEN6_PCODE_READY) == 0, + 500)) + DRM_ERROR("timeout waiting for pcode mailbox to become idle\n"); + + I915_WRITE(GEN6_PCODE_DATA, 0); + I915_WRITE(GEN6_PCODE_MAILBOX, + GEN6_PCODE_READY | + GEN6_PCODE_WRITE_MIN_FREQ_TABLE); + if (wait_for((I915_READ(GEN6_PCODE_MAILBOX) & GEN6_PCODE_READY) == 0, + 500)) + DRM_ERROR("timeout waiting for pcode mailbox to finish\n"); + + /* requires MSI enabled */ + I915_WRITE(GEN6_PMIER, + GEN6_PM_MBOX_EVENT | + GEN6_PM_THERMAL_EVENT | + GEN6_PM_RP_DOWN_TIMEOUT | + GEN6_PM_RP_UP_THRESHOLD | + GEN6_PM_RP_DOWN_THRESHOLD | + GEN6_PM_RP_UP_EI_EXPIRED | + GEN6_PM_RP_DOWN_EI_EXPIRED); + + __gen6_force_wake_put(dev_priv); +} + void intel_enable_clock_gating(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private; @@ -5924,6 +6009,7 @@ void intel_enable_clock_gating(struct drm_device *dev) _3D_CHICKEN2_WM_READ_PIPELINED << 16 | _3D_CHICKEN2_WM_READ_PIPELINED); } + } else if (IS_G4X(dev)) { uint32_t dspclk_gate; I915_WRITE(RENCLK_GATE_D1, 0); @@ -5997,6 +6083,9 @@ void intel_enable_clock_gating(struct drm_device *dev) I915_READ(MCHBAR_RENDER_STANDBY) & ~RCX_SW_EXIT); } } + + if (IS_GEN6(dev)) + gen6_enable_rc6(dev_priv); } void intel_disable_clock_gating(struct drm_device *dev) -- cgit v1.2.3 From d1b758ebc2a82d738092cb42e742470f9d0ea53e Mon Sep 17 00:00:00 2001 From: Konrad Rzeszutek Wilk Date: Thu, 9 Dec 2010 14:53:29 -0500 Subject: xen/irq: Cleanup the find_unbound_irq The "find_unbound_irq" is a bit unusual - it allocates virtual IRQ (event channels) in reverse order. This means starting at the "top" of the available IRQs (nr_irqs) down to the GSI/MSI IRQs (nr_irqs_gsi). Lets document this and also make the variables easier to understand. Signed-off-by: Konrad Rzeszutek Wilk --- drivers/xen/events.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/drivers/xen/events.c b/drivers/xen/events.c index 31af0ac31a98..4d4a23d4c9f6 100644 --- a/drivers/xen/events.c +++ b/drivers/xen/events.c @@ -405,15 +405,21 @@ static int find_unbound_irq(void) { struct irq_data *data; int irq, res; - int start = get_nr_hw_irqs(); + int bottom = get_nr_hw_irqs(); + int top = nr_irqs-1; - if (start == nr_irqs) + if (bottom == nr_irqs) goto no_irqs; - /* nr_irqs is a magic value. Must not use it.*/ - for (irq = nr_irqs-1; irq > start; irq--) { + /* This loop starts from the top of IRQ space and goes down. + * We need this b/c if we have a PCI device in a Xen PV guest + * we do not have an IO-APIC (though the backend might have them) + * mapped in. To not have a collision of physical IRQs with the Xen + * event channels start at the top of the IRQ space for virtual IRQs. + */ + for (irq = top; irq > bottom; irq--) { data = irq_get_irq_data(irq); - /* only 0->15 have init'd desc; handle irq > 16 */ + /* only 15->0 have init'd desc; handle irq > 16 */ if (!data) break; if (data->chip == &no_irq_chip) @@ -424,7 +430,7 @@ static int find_unbound_irq(void) return irq; } - if (irq == start) + if (irq == bottom) goto no_irqs; res = irq_alloc_desc_at(irq, -1); -- cgit v1.2.3 From 747fecab32e47180e2668c2b22b25752d371e636 Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Thu, 9 Dec 2010 23:25:09 +0100 Subject: coda: kill redundant cast in coda_alloc_inode() kmem_cache_alloc() returns a void pointer which there is no need to cast. Signed-off-by: Jesper Juhl Signed-off-by: Jiri Kosina --- fs/coda/inode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/coda/inode.c b/fs/coda/inode.c index 5ea57c8c7f97..1a49c1708a54 100644 --- a/fs/coda/inode.c +++ b/fs/coda/inode.c @@ -45,7 +45,7 @@ static struct kmem_cache * coda_inode_cachep; static struct inode *coda_alloc_inode(struct super_block *sb) { struct coda_inode_info *ei; - ei = (struct coda_inode_info *)kmem_cache_alloc(coda_inode_cachep, GFP_KERNEL); + ei = kmem_cache_alloc(coda_inode_cachep, GFP_KERNEL); if (!ei) return NULL; memset(&ei->c_fid, 0, sizeof(struct CodaFid)); -- cgit v1.2.3 From 1f0613158ea14b399fd7a16470630a729ba9d0c3 Mon Sep 17 00:00:00 2001 From: "Chen, Chien-Chia" Date: Thu, 9 Dec 2010 10:52:08 +0800 Subject: Staging: rt2860: fix previous patch error Somehow Greg messed up the last patch and missed a chunk. This patch contains the missing chunk. Acked-by: Lee, Chun-Yi Signed-off-by: Chen, Chien-Chia Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rt2860/chips/rt30xx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/rt2860/chips/rt30xx.c b/drivers/staging/rt2860/chips/rt30xx.c index e610d39bdca7..354debfe1477 100644 --- a/drivers/staging/rt2860/chips/rt30xx.c +++ b/drivers/staging/rt2860/chips/rt30xx.c @@ -442,7 +442,7 @@ void RT30xxReverseRFSleepModeSetup(struct rt_rtmp_adapter *pAd) /* VCO_IC, RF R7 register Bit 4 & Bit 5 to 1 */ RT30xxReadRFRegister(pAd, RF_R07, &RFValue); - RFValue |= 0x30; + RFValue |= 0x20; RT30xxWriteRFRegister(pAd, RF_R07, RFValue); /* Idoh, RF R9 register Bit 1, Bit 2 & Bit 3 to 1 */ -- cgit v1.2.3 From 310d605293f0ab6dc9c7fe7a3cb5c850c60527b4 Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Thu, 9 Dec 2010 16:01:07 +0100 Subject: staging: brcm80211: Remove redundant unlikely() IS_ERR() already implies unlikely(), so it can be omitted here. Signed-off-by: Tobias Klauser Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c index 0d7aa4adbb77..edf300d4ae70 100644 --- a/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c +++ b/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c @@ -3196,7 +3196,7 @@ s32 wl_cfg80211_attach(struct net_device *ndev, void *data) } WL_DBG(("func %p\n", wl_cfg80211_get_sdio_func())); wdev = wl_alloc_wdev(sizeof(struct wl_iface), &wl_cfg80211_get_sdio_func()->dev); - if (unlikely(IS_ERR(wdev))) + if (IS_ERR(wdev)) return -ENOMEM; wdev->iftype = wl_mode_to_nl80211_iftype(WL_MODE_BSS); -- cgit v1.2.3 From 2cea0cf284048b03a06e4370709cd751ddb9354e Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Fri, 10 Dec 2010 01:40:30 +0900 Subject: Staging: vme_ca91cx42: use DEFINE_PCI_DEVICE_TABLE Convert 'const struct pci_device_id xxx[]' to 'DEFINE_PCI_DEVICE_TABLE(xxx)'. Signed-off-by: Namhyung Kim Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vme/bridges/vme_ca91cx42.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/vme/bridges/vme_ca91cx42.c b/drivers/staging/vme/bridges/vme_ca91cx42.c index 3ddc93ba7049..42de83e6f1d9 100644 --- a/drivers/staging/vme/bridges/vme_ca91cx42.c +++ b/drivers/staging/vme/bridges/vme_ca91cx42.c @@ -44,7 +44,7 @@ static int geoid; static char driver_name[] = "vme_ca91cx42"; -static const struct pci_device_id ca91cx42_ids[] = { +static DEFINE_PCI_DEVICE_TABLE(ca91cx42_ids) = { { PCI_DEVICE(PCI_VENDOR_ID_TUNDRA, PCI_DEVICE_ID_TUNDRA_CA91C142) }, { }, }; -- cgit v1.2.3 From 270b64bb4cf27a2ad7819bad89d8c9d8a66ba1b8 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Fri, 10 Dec 2010 01:40:29 +0900 Subject: Staging: vme_tsi148: use DEFINE_PCI_DEVICE_TABLE Convert 'const struct pci_device_id xxx[]' to 'DEFINE_PCI_DEVICE_TABLE(xxx)'. Signed-off-by: Namhyung Kim Signed-off-by: Greg Kroah-Hartman --- drivers/staging/vme/bridges/vme_tsi148.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/vme/bridges/vme_tsi148.c b/drivers/staging/vme/bridges/vme_tsi148.c index 9550b4a8f93a..26ea42fa784d 100644 --- a/drivers/staging/vme/bridges/vme_tsi148.c +++ b/drivers/staging/vme/bridges/vme_tsi148.c @@ -46,7 +46,7 @@ static int geoid; static char driver_name[] = "vme_tsi148"; -static const struct pci_device_id tsi148_ids[] = { +static DEFINE_PCI_DEVICE_TABLE(tsi148_ids) = { { PCI_DEVICE(PCI_VENDOR_ID_TUNDRA, PCI_DEVICE_ID_TUNDRA_TSI148) }, { }, }; -- cgit v1.2.3 From abb9eb75a34cbd34ee4e9160ac349eff91b926d8 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Fri, 10 Dec 2010 01:40:28 +0900 Subject: Staging: phison: use DEFINE_PCI_DEVICE_TABLE Convert 'const struct pci_device_id xxx[]' to 'DEFINE_PCI_DEVICE_TABLE(xxx)'. Signed-off-by: Namhyung Kim Signed-off-by: Greg Kroah-Hartman --- drivers/staging/phison/phison.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/phison/phison.c b/drivers/staging/phison/phison.c index 677152044f45..683657cb21f5 100644 --- a/drivers/staging/phison/phison.c +++ b/drivers/staging/phison/phison.c @@ -69,7 +69,7 @@ static int phison_init_one(struct pci_dev *pdev, const struct pci_device_id *id) return ret; } -static const struct pci_device_id phison_pci_tbl[] = { +static DEFINE_PCI_DEVICE_TABLE(phison_pci_tbl) = { { PCI_VENDOR_ID_PHISON, PCI_DEVICE_ID_PS5000, PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_STORAGE_IDE << 8, 0xffff00, 0 }, { 0, }, -- cgit v1.2.3 From 94ab896367d5d6e0bc3064852569c1ff9658ec9c Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Fri, 10 Dec 2010 01:40:26 +0900 Subject: Staging: cx25821: use DEFINE_PCI_DEVICE_TABLE Convert 'const struct pci_device_id xxx[]' to 'DEFINE_PCI_DEVICE_TABLE(xxx)'. Signed-off-by: Namhyung Kim Signed-off-by: Greg Kroah-Hartman --- drivers/staging/cx25821/cx25821-alsa.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/cx25821/cx25821-alsa.c b/drivers/staging/cx25821/cx25821-alsa.c index 2a01dc057b2c..1f2e819c4320 100644 --- a/drivers/staging/cx25821/cx25821-alsa.c +++ b/drivers/staging/cx25821/cx25821-alsa.c @@ -629,7 +629,7 @@ static int snd_cx25821_pcm(struct cx25821_audio_dev *chip, int device, * Only boards with eeprom and byte 1 at eeprom=1 have it */ -static const struct pci_device_id cx25821_audio_pci_tbl[] __devinitdata = { +static DEFINE_PCI_DEVICE_TABLE(cx25821_audio_pci_tbl) = { {0x14f1, 0x0920, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {0,} }; -- cgit v1.2.3 From 5eaa53de2d9acd9dbcf737b247a0bb0788e79fdf Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Fri, 10 Dec 2010 01:40:27 +0900 Subject: Staging: rtl8192e: use DEFINE_PCI_DEVICE_TABLE Convert 'const struct pci_device_id xxx[]' to 'DEFINE_PCI_DEVICE_TABLE(xxx)'. Signed-off-by: Namhyung Kim Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192e/r8192E_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/rtl8192e/r8192E_core.c b/drivers/staging/rtl8192e/r8192E_core.c index b7d08605fd00..fac4eee28e4e 100644 --- a/drivers/staging/rtl8192e/r8192E_core.c +++ b/drivers/staging/rtl8192e/r8192E_core.c @@ -89,7 +89,7 @@ u32 rt_global_debug_component = // COMP_INTR | COMP_ERR ; //always open err flags on -static const struct pci_device_id rtl8192_pci_id_tbl[] __devinitdata = { +static DEFINE_PCI_DEVICE_TABLE(rtl8192_pci_id_tbl) = { #ifdef RTL8190P /* Realtek */ /* Dlink */ -- cgit v1.2.3 From 6f475b71605c7ebf6f5b06b8e4dc58f672b4f9b5 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Fri, 10 Dec 2010 01:40:25 +0900 Subject: Staging: sm7xx: use DEFINE_PCI_DEVICE_TABLE Convert 'const struct pci_device_id xxx[]' to 'DEFINE_PCI_DEVICE_TABLE(xxx)'. Signed-off-by: Namhyung Kim Signed-off-by: Greg Kroah-Hartman --- drivers/staging/sm7xx/smtcfb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/sm7xx/smtcfb.c b/drivers/staging/sm7xx/smtcfb.c index 24f47d6388f4..f4b163f7338a 100644 --- a/drivers/staging/sm7xx/smtcfb.c +++ b/drivers/staging/sm7xx/smtcfb.c @@ -996,7 +996,7 @@ failed_free: /* Jason (08/11/2009) PCI_DRV wrapper essential structs */ -static const struct pci_device_id smtcfb_pci_table[] = { +static DEFINE_PCI_DEVICE_TABLE(smtcfb_pci_table) = { {0x126f, 0x710, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {0x126f, 0x712, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, {0x126f, 0x720, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, -- cgit v1.2.3 From 0e0792fef4ea8e9f8f90819ad97918f61e467855 Mon Sep 17 00:00:00 2001 From: Roland Vossen Date: Thu, 9 Dec 2010 19:36:08 +0100 Subject: staging: brcm80211: removed ap related comments Code cleanup, reaction on the 2nd email from Dan Carpenter. Signed-off-by: Roland Vossen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/sys/wlc_mac80211.c | 7 ------- 1 file changed, 7 deletions(-) diff --git a/drivers/staging/brcm80211/sys/wlc_mac80211.c b/drivers/staging/brcm80211/sys/wlc_mac80211.c index eb4013dab36c..e4a4365f4bf7 100644 --- a/drivers/staging/brcm80211/sys/wlc_mac80211.c +++ b/drivers/staging/brcm80211/sys/wlc_mac80211.c @@ -2177,13 +2177,6 @@ uint wlc_detach(struct wlc_info *wlc) /* Detach from iovar manager */ wlc_module_unregister(wlc->pub, "wlc_iovars", wlc); - /* - if (wlc->ap) { - wlc_ap_detach(wlc->ap); - wlc->ap = NULL; - } - */ - while (wlc->tx_queues != NULL) { wlc_txq_free(wlc, wlc->osh, wlc->tx_queues); } -- cgit v1.2.3 From 372058f1b4b3603a7e0c26f38d6eb20a3dd8c453 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Thu, 9 Dec 2010 09:38:34 -0800 Subject: staging: solo6010 depends on I2C This driver uses i2c interfaces, so it should depend on I2C (unless someone wants to break it into pieces or make it more config-dependent). drivers/staging/solo6x10/solo6010-i2c.c:47: error: implicit declaration of function 'i2c_transfer' drivers/staging/solo6x10/solo6010-i2c.c:299: error: implicit declaration of function 'i2c_add_adapter' drivers/staging/solo6x10/solo6010-i2c.c:310: error: implicit declaration of function 'i2c_del_adapter' Signed-off-by: Randy Dunlap Cc: Ben Collins Signed-off-by: Greg Kroah-Hartman --- drivers/staging/solo6x10/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/solo6x10/Kconfig b/drivers/staging/solo6x10/Kconfig index de60ac841b7e..2cf77c940860 100644 --- a/drivers/staging/solo6x10/Kconfig +++ b/drivers/staging/solo6x10/Kconfig @@ -1,6 +1,6 @@ config SOLO6X10 tristate "Softlogic 6x10 MPEG codec cards" - depends on PCI && VIDEO_DEV && SND + depends on PCI && VIDEO_DEV && SND && I2C select VIDEOBUF_DMA_SG ---help--- This driver supports the Softlogic based MPEG-4 and h.264 codec -- cgit v1.2.3 From 9119dee1ce32453dfe24656091d69f8d57397fe0 Mon Sep 17 00:00:00 2001 From: Marek Belisko Date: Thu, 9 Dec 2010 11:26:46 +0100 Subject: staging: ft1000: Convert char device to debugfs. Character device was used only for debugging purposes. Convert it to debugfs functionality. For every plugged device create new directory with one file. Signed-off-by: Marek Belisko Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ft1000/ft1000-usb/ft1000_chdev.c | 68 +++++++++++++++++------- drivers/staging/ft1000/ft1000-usb/ft1000_hw.c | 1 + drivers/staging/ft1000/ft1000-usb/ft1000_usb.h | 8 +++ 3 files changed, 57 insertions(+), 20 deletions(-) diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_chdev.c b/drivers/staging/ft1000/ft1000-usb/ft1000_chdev.c index 1aec926c993c..1238b7759e5b 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_chdev.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_chdev.c @@ -37,7 +37,7 @@ #include #include #include - +#include #include "ft1000_usb.h" //#include "ft1000_ioctl.h" @@ -156,9 +156,11 @@ int ft1000_CreateDevice(struct ft1000_device *dev) struct ft1000_info *info = netdev_priv(dev->net); int result; int i; + struct dentry *dir, *file; + struct ft1000_debug_dirs *tmp; // make a new device name - sprintf(info->DeviceName, "%s%d", "FT100", info->CardNumber); + sprintf(info->DeviceName, "%s%d", "FT1000_", info->CardNumber); DEBUG("ft1000_CreateDevice: number of instance = %d\n", ft1000_flarion_cnt); DEBUG("DeviceCreated = %x\n", info->DeviceCreated); @@ -179,21 +181,31 @@ int ft1000_CreateDevice(struct ft1000_device *dev) DEBUG("ft1000_CreateDevice: \"%s\" device registration\n", info->DeviceName); info->DeviceMajor = 0; - result = register_chrdev(info->DeviceMajor, info->DeviceName, &ft1000fops); - if (result < 0) - { - DEBUG("ft1000_CreateDevice: unable to get major %d\n", info->DeviceMajor); - return result; - } + tmp = kmalloc(sizeof(struct ft1000_debug_dirs), GFP_KERNEL); + if (tmp == NULL) { + result = -1; + goto fail; + } - DEBUG("ft1000_CreateDevice: registered char device \"%s\"\n", info->DeviceName); + dir = debugfs_create_dir(info->DeviceName, 0); + if (IS_ERR(dir)) { + result = PTR_ERR(dir); + goto debug_dir_fail; + } - // save a dynamic device major number - if (info->DeviceMajor == 0) - { - info->DeviceMajor = result; - DEBUG("ft1000_PcdCreateDevice: device major = %d\n", info->DeviceMajor); - } + file = debugfs_create_file("device", S_IRUGO | S_IWUGO, dir, + NULL, &ft1000fops); + if (IS_ERR(file)) { + result = PTR_ERR(file); + goto debug_file_fail; + } + + tmp->dent = dir; + tmp->file = file; + tmp->int_number = info->CardNumber; + list_add(&(tmp->list), &(info->nodes.list)); + + DEBUG("ft1000_CreateDevice: registered char device \"%s\"\n", info->DeviceName); // initialize application information @@ -243,7 +255,14 @@ int ft1000_CreateDevice(struct ft1000_device *dev) info->DeviceCreated = TRUE; ft1000_flarion_cnt++; - return result; + return 0; + +debug_file_fail: + debugfs_remove(dir); +debug_dir_fail: + kfree(tmp); +fail: + return result; } //--------------------------------------------------------------------------- @@ -259,10 +278,11 @@ int ft1000_CreateDevice(struct ft1000_device *dev) void ft1000_DestroyDevice(struct net_device *dev) { struct ft1000_info *info = netdev_priv(dev); - int result = 0; int i; struct dpram_blk *pdpram_blk; struct dpram_blk *ptr; + struct list_head *pos, *q; + struct ft1000_debug_dirs *dir; DEBUG("ft1000_chdev:ft1000_DestroyDevice called\n"); @@ -271,9 +291,17 @@ void ft1000_DestroyDevice(struct net_device *dev) if (info->DeviceCreated) { ft1000_flarion_cnt--; - unregister_chrdev(info->DeviceMajor, info->DeviceName); - DEBUG("ft1000_DestroyDevice: unregistered device \"%s\", result = %d\n", - info->DeviceName, result); + list_for_each_safe(pos, q, &info->nodes.list) { + dir = list_entry(pos, struct ft1000_debug_dirs, list); + if (dir->int_number == info->CardNumber) { + debugfs_remove(dir->file); + debugfs_remove(dir->dent); + list_del(pos); + kfree(dir); + } + } + DEBUG("ft1000_DestroyDevice: unregistered device \"%s\"\n", + info->DeviceName); // Make sure we free any memory reserve for slow Queue for (i=0; iprov_list); + INIT_LIST_HEAD(&pInfo->nodes.list); //mbelian #ifdef HAVE_NET_DEVICE_OPS netdev->netdev_ops = &ftnet_ops; diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_usb.h b/drivers/staging/ft1000/ft1000-usb/ft1000_usb.h index a07db26441f1..5bead6314985 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_usb.h +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_usb.h @@ -473,6 +473,13 @@ struct ft1000_device // struct net_device_stats stats; //mbelian } __attribute__ ((packed)); +struct ft1000_debug_dirs { + struct list_head list; + struct dentry *dent; + struct dentry *file; + int int_number; +}; + struct ft1000_info { struct ft1000_device *pFt1000Dev; struct net_device_stats stats; @@ -508,6 +515,7 @@ struct ft1000_info { u8 CardNumber; u8 DeviceName[15]; int DeviceMajor; + struct ft1000_debug_dirs nodes; int registered; int mediastate; int dhcpflg; -- cgit v1.2.3 From 6d96940b2de8f8ac2bc938ea9249ed380cf906e0 Mon Sep 17 00:00:00 2001 From: Marek Belisko Date: Thu, 9 Dec 2010 11:26:47 +0100 Subject: staging: ft1000: Fix private data pointer usage. Assign private data pointer to device for usage in file operations. Signed-off-by: Marek Belisko Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ft1000/ft1000-usb/ft1000_chdev.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_chdev.c b/drivers/staging/ft1000/ft1000-usb/ft1000_chdev.c index 1238b7759e5b..8b735e489878 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_chdev.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_chdev.c @@ -347,12 +347,15 @@ void ft1000_DestroyDevice(struct net_device *dev) static int ft1000_ChOpen (struct inode *Inode, struct file *File) { struct ft1000_info *info; + struct ft1000_device *dev = (struct ft1000_device *)Inode->i_private; int i,num; DEBUG("ft1000_ChOpen called\n"); num = (MINOR(Inode->i_rdev) & 0xf); DEBUG("ft1000_ChOpen: minor number=%d\n", num); + info = File->private_data = netdev_priv(dev->net); + for (i=0; i<5; i++) DEBUG("pdevobj[%d]=%p\n", i, pdevobj[i]); //aelias [+] reason: down @@ -393,8 +396,6 @@ static int ft1000_ChOpen (struct inode *Inode, struct file *File) info->app_info[i].nTxMsgReject = 0; info->app_info[i].nRxMsgMiss = 0; - File->private_data = pdevobj[num]->net; - nonseekable_open(Inode, File); return 0; } -- cgit v1.2.3 From e34dc580dc4a76106755b88ada5903eaa427c9f4 Mon Sep 17 00:00:00 2001 From: Marek Belisko Date: Thu, 9 Dec 2010 11:26:48 +0100 Subject: staging: ft1000: Remove unused pdevobj array. We don't need to store pointer to device in some local array because we always pass to debugfs correct device pointer. So remove it. Signed-off-by: Marek Belisko Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ft1000/ft1000-usb/ft1000_chdev.c | 23 ----------------------- 1 file changed, 23 deletions(-) diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_chdev.c b/drivers/staging/ft1000/ft1000-usb/ft1000_chdev.c index 8b735e489878..0871e43159c6 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_chdev.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_chdev.c @@ -51,10 +51,6 @@ static long ft1000_ChIoctl(struct file *File, unsigned int Command, unsigned long Argument); static int ft1000_ChRelease (struct inode *Inode, struct file *File); -// Global pointer to device object -static struct ft1000_device *pdevobj[MAX_NUM_CARDS + 2]; -//static devfs_handle_t ft1000Handle[MAX_NUM_CARDS]; - // List to free receive command buffer pool struct list_head freercvpool; @@ -165,11 +161,6 @@ int ft1000_CreateDevice(struct ft1000_device *dev) DEBUG("ft1000_CreateDevice: number of instance = %d\n", ft1000_flarion_cnt); DEBUG("DeviceCreated = %x\n", info->DeviceCreated); - //save the device info to global array - pdevobj[info->CardNumber] = dev; - - DEBUG("ft1000_CreateDevice: ******SAVED pdevobj[%d]=%p\n", info->CardNumber, pdevobj[info->CardNumber]); //aelias [+] reason:up - if (info->DeviceCreated) { DEBUG("ft1000_CreateDevice: \"%s\" already registered\n", info->DeviceName); @@ -327,8 +318,6 @@ void ft1000_DestroyDevice(struct net_device *dev) // devfs_unregister(ft1000Handle[info->CardNumber]); info->DeviceCreated = FALSE; - - pdevobj[info->CardNumber] = NULL; } @@ -356,18 +345,6 @@ static int ft1000_ChOpen (struct inode *Inode, struct file *File) info = File->private_data = netdev_priv(dev->net); - for (i=0; i<5; i++) - DEBUG("pdevobj[%d]=%p\n", i, pdevobj[i]); //aelias [+] reason: down - - if ( pdevobj[num] != NULL ) - //info = (struct ft1000_info *)(pdevobj[num]->net->priv); - info = netdev_priv(pdevobj[num]->net); - else - { - DEBUG("ft1000_ChOpen: can not find device object %d\n", num); - return -1; - } - DEBUG("f_owner = %p number of application = %d\n", (&File->f_owner), info->appcnt ); // Check if maximum number of application exceeded -- cgit v1.2.3 From 67e9f9e26b7d8862ec2e2a3ac0e56590088e9281 Mon Sep 17 00:00:00 2001 From: Marek Belisko Date: Thu, 9 Dec 2010 11:26:49 +0100 Subject: staging: ft1000: Remove unused variable. Signed-off-by: Marek Belisko Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ft1000/ft1000-usb/ft1000_chdev.c | 1 - drivers/staging/ft1000/ft1000-usb/ft1000_hw.c | 1 - drivers/staging/ft1000/ft1000-usb/ft1000_usb.h | 1 - 3 files changed, 3 deletions(-) diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_chdev.c b/drivers/staging/ft1000/ft1000-usb/ft1000_chdev.c index 0871e43159c6..4e5c8a3bc888 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_chdev.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_chdev.c @@ -170,7 +170,6 @@ int ft1000_CreateDevice(struct ft1000_device *dev) // register the device DEBUG("ft1000_CreateDevice: \"%s\" device registration\n", info->DeviceName); - info->DeviceMajor = 0; tmp = kmalloc(sizeof(struct ft1000_debug_dirs), GFP_KERNEL); if (tmp == NULL) { diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c index 22536da75011..69f920fdc12a 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c @@ -835,7 +835,6 @@ u16 init_ft1000_netdev(struct ft1000_device *ft1000dev) pInfo->mediastate = 0; pInfo->fifo_cnt = 0; pInfo->DeviceCreated = FALSE; - pInfo->DeviceMajor = 0; pInfo->CurrentInterruptEnableMask = ISR_DEFAULT_MASK; pInfo->InterruptsEnabled = FALSE; pInfo->CardReady = 0; diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_usb.h b/drivers/staging/ft1000/ft1000-usb/ft1000_usb.h index 5bead6314985..2c89d14807fb 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_usb.h +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_usb.h @@ -514,7 +514,6 @@ struct ft1000_info { int NetDevRegDone; u8 CardNumber; u8 DeviceName[15]; - int DeviceMajor; struct ft1000_debug_dirs nodes; int registered; int mediastate; -- cgit v1.2.3 From 4d791234f484002d57f634e3d90ca2cd51ed144e Mon Sep 17 00:00:00 2001 From: Marek Belisko Date: Thu, 9 Dec 2010 11:26:50 +0100 Subject: staging: ft1000: Fix camelcase functions and variables. Signed-off-by: Marek Belisko Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ft1000/ft1000-usb/ft1000_chdev.c | 156 +++++++++++------------ drivers/staging/ft1000/ft1000-usb/ft1000_hw.c | 2 +- drivers/staging/ft1000/ft1000-usb/ft1000_usb.c | 2 +- drivers/staging/ft1000/ft1000-usb/ft1000_usb.h | 4 +- 4 files changed, 82 insertions(+), 82 deletions(-) diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_chdev.c b/drivers/staging/ft1000/ft1000-usb/ft1000_chdev.c index 4e5c8a3bc888..85f67e564f36 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_chdev.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_chdev.c @@ -45,11 +45,11 @@ static int ft1000_flarion_cnt = 0; //need to looking usage of ft1000Handle -static int ft1000_ChOpen (struct inode *Inode, struct file *File); -static unsigned int ft1000_ChPoll(struct file *file, poll_table *wait); -static long ft1000_ChIoctl(struct file *File, unsigned int Command, - unsigned long Argument); -static int ft1000_ChRelease (struct inode *Inode, struct file *File); +static int ft1000_open (struct inode *inode, struct file *file); +static unsigned int ft1000_poll_dev(struct file *file, poll_table *wait); +static long ft1000_ioctl(struct file *file, unsigned int command, + unsigned long argument); +static int ft1000_release (struct inode *inode, struct file *file); // List to free receive command buffer pool struct list_head freercvpool; @@ -67,10 +67,10 @@ int numofmsgbuf = 0; // static struct file_operations ft1000fops = { - .unlocked_ioctl = ft1000_ChIoctl, - .poll = ft1000_ChPoll, - .open = ft1000_ChOpen, - .release = ft1000_ChRelease, + .unlocked_ioctl = ft1000_ioctl, + .poll = ft1000_poll_dev, + .open = ft1000_open, + .release = ft1000_release, .llseek = no_llseek, }; @@ -147,7 +147,7 @@ void ft1000_free_buffer(struct dpram_blk *pdpram_blk, struct list_head *plist) // Notes: Only called by init_module(). // //--------------------------------------------------------------------------- -int ft1000_CreateDevice(struct ft1000_device *dev) +int ft1000_create_dev(struct ft1000_device *dev) { struct ft1000_info *info = netdev_priv(dev->net); int result; @@ -265,7 +265,7 @@ fail: // Notes: Only called by cleanup_module(). // //--------------------------------------------------------------------------- -void ft1000_DestroyDevice(struct net_device *dev) +void ft1000_destroy_dev(struct net_device *dev) { struct ft1000_info *info = netdev_priv(dev); int i; @@ -323,7 +323,7 @@ void ft1000_DestroyDevice(struct net_device *dev) } //--------------------------------------------------------------------------- -// Function: ft1000_ChOpen +// Function: ft1000_open // // Parameters: // @@ -332,19 +332,19 @@ void ft1000_DestroyDevice(struct net_device *dev) // Notes: // //--------------------------------------------------------------------------- -static int ft1000_ChOpen (struct inode *Inode, struct file *File) +static int ft1000_open (struct inode *inode, struct file *file) { struct ft1000_info *info; - struct ft1000_device *dev = (struct ft1000_device *)Inode->i_private; + struct ft1000_device *dev = (struct ft1000_device *)inode->i_private; int i,num; - DEBUG("ft1000_ChOpen called\n"); - num = (MINOR(Inode->i_rdev) & 0xf); - DEBUG("ft1000_ChOpen: minor number=%d\n", num); + DEBUG("ft1000_open called\n"); + num = (MINOR(inode->i_rdev) & 0xf); + DEBUG("ft1000_open: minor number=%d\n", num); - info = File->private_data = netdev_priv(dev->net); + info = file->private_data = netdev_priv(dev->net); - DEBUG("f_owner = %p number of application = %d\n", (&File->f_owner), info->appcnt ); + DEBUG("f_owner = %p number of application = %d\n", (&file->f_owner), info->appcnt ); // Check if maximum number of application exceeded if (info->appcnt > MAX_NUM_APP) { @@ -366,19 +366,19 @@ static int ft1000_ChOpen (struct inode *Inode, struct file *File) } info->appcnt++; - info->app_info[i].fileobject = &File->f_owner; + info->app_info[i].fileobject = &file->f_owner; info->app_info[i].nTxMsg = 0; info->app_info[i].nRxMsg = 0; info->app_info[i].nTxMsgReject = 0; info->app_info[i].nRxMsgMiss = 0; - nonseekable_open(Inode, File); + nonseekable_open(inode, file); return 0; } //--------------------------------------------------------------------------- -// Function: ft1000_ChPoll +// Function: ft1000_poll_dev // // Parameters: // @@ -388,15 +388,15 @@ static int ft1000_ChOpen (struct inode *Inode, struct file *File) // //--------------------------------------------------------------------------- -static unsigned int ft1000_ChPoll(struct file *file, poll_table *wait) +static unsigned int ft1000_poll_dev(struct file *file, poll_table *wait) { struct net_device *dev = file->private_data; struct ft1000_info *info; int i; - //DEBUG("ft1000_ChPoll called\n"); + //DEBUG("ft1000_poll_dev called\n"); if (ft1000_flarion_cnt == 0) { - DEBUG("FT1000:ft1000_ChPoll called when ft1000_flarion_cnt is zero\n"); + DEBUG("FT1000:ft1000_poll_dev called when ft1000_flarion_cnt is zero\n"); return (-EBADF); } @@ -405,30 +405,30 @@ static unsigned int ft1000_ChPoll(struct file *file, poll_table *wait) // Search for matching file object for (i=0; iapp_info[i].fileobject == &file->f_owner) { - //DEBUG("FT1000:ft1000_ChIoctl: Message is for AppId = %d\n", info->app_info[i].app_id); + //DEBUG("FT1000:ft1000_ioctl: Message is for AppId = %d\n", info->app_info[i].app_id); break; } } // Could not find application info block if (i == MAX_NUM_APP) { - DEBUG("FT1000:ft1000_ChIoctl:Could not find application info block\n"); + DEBUG("FT1000:ft1000_ioctl:Could not find application info block\n"); return ( -EACCES ); } if (list_empty(&info->app_info[i].app_sqlist) == 0) { - DEBUG("FT1000:ft1000_ChPoll:Message detected in slow queue\n"); + DEBUG("FT1000:ft1000_poll_dev:Message detected in slow queue\n"); return(POLLIN | POLLRDNORM | POLLPRI); } poll_wait (file, &info->app_info[i].wait_dpram_msg, wait); - //DEBUG("FT1000:ft1000_ChPoll:Polling for data from DSP\n"); + //DEBUG("FT1000:ft1000_poll_dev:Polling for data from DSP\n"); return (0); } //--------------------------------------------------------------------------- -// Function: ft1000_ChIoctl +// Function: ft1000_ioctl // // Parameters: // @@ -437,10 +437,10 @@ static unsigned int ft1000_ChPoll(struct file *file, poll_table *wait) // Notes: // //--------------------------------------------------------------------------- -static long ft1000_ChIoctl (struct file *File, unsigned int Command, - unsigned long Argument) +static long ft1000_ioctl (struct file *file, unsigned int command, + unsigned long argument) { - void __user *argp = (void __user *)Argument; + void __user *argp = (void __user *)argument; struct net_device *dev; struct ft1000_info *info; struct ft1000_device *ft1000dev; @@ -462,25 +462,25 @@ static long ft1000_ChIoctl (struct file *File, unsigned int Command, unsigned short ledStat=0; unsigned short conStat=0; - //DEBUG("ft1000_ChIoctl called\n"); + //DEBUG("ft1000_ioctl called\n"); if (ft1000_flarion_cnt == 0) { - DEBUG("FT1000:ft1000_ChIoctl called when ft1000_flarion_cnt is zero\n"); + DEBUG("FT1000:ft1000_ioctl called when ft1000_flarion_cnt is zero\n"); return (-EBADF); } - //DEBUG("FT1000:ft1000_ChIoctl:Command = 0x%x Argument = 0x%8x\n", Command, (u32)Argument); + //DEBUG("FT1000:ft1000_ioctl:command = 0x%x argument = 0x%8x\n", command, (u32)argument); - dev = File->private_data; + dev = file->private_data; info = netdev_priv(dev); ft1000dev = info->pFt1000Dev; - cmd = _IOC_NR(Command); - //DEBUG("FT1000:ft1000_ChIoctl:cmd = 0x%x\n", cmd); + cmd = _IOC_NR(command); + //DEBUG("FT1000:ft1000_ioctl:cmd = 0x%x\n", cmd); // process the command switch (cmd) { case IOCTL_REGISTER_CMD: - DEBUG("FT1000:ft1000_ChIoctl: IOCTL_FT1000_REGISTER called\n"); + DEBUG("FT1000:ft1000_ioctl: IOCTL_FT1000_REGISTER called\n"); result = get_user(tempword, (__u16 __user*)argp); if (result) { DEBUG("result = %d failed to get_user\n", result); @@ -489,9 +489,9 @@ static long ft1000_ChIoctl (struct file *File, unsigned int Command, if (tempword == DSPBCMSGID) { // Search for matching file object for (i=0; iapp_info[i].fileobject == &File->f_owner) { + if ( info->app_info[i].fileobject == &file->f_owner) { info->app_info[i].DspBCMsgFlag = 1; - DEBUG("FT1000:ft1000_ChIoctl:Registered for broadcast messages\n"); + DEBUG("FT1000:ft1000_ioctl:Registered for broadcast messages\n"); break; } } @@ -499,34 +499,34 @@ static long ft1000_ChIoctl (struct file *File, unsigned int Command, break; case IOCTL_GET_VER_CMD: - DEBUG("FT1000:ft1000_ChIoctl: IOCTL_FT1000_GET_VER called\n"); + DEBUG("FT1000:ft1000_ioctl: IOCTL_FT1000_GET_VER called\n"); get_ver_data.drv_ver = FT1000_DRV_VER; if (copy_to_user(argp, &get_ver_data, sizeof(get_ver_data)) ) { - DEBUG("FT1000:ft1000_ChIoctl: copy fault occurred\n"); + DEBUG("FT1000:ft1000_ioctl: copy fault occurred\n"); result = -EFAULT; break; } - DEBUG("FT1000:ft1000_ChIoctl:driver version = 0x%x\n",(unsigned int)get_ver_data.drv_ver); + DEBUG("FT1000:ft1000_ioctl:driver version = 0x%x\n",(unsigned int)get_ver_data.drv_ver); break; case IOCTL_CONNECT: // Connect Message - DEBUG("FT1000:ft1000_ChIoctl: IOCTL_FT1000_CONNECT\n"); + DEBUG("FT1000:ft1000_ioctl: IOCTL_FT1000_CONNECT\n"); ConnectionMsg[79] = 0xfc; CardSendCommand(ft1000dev, (unsigned short *)ConnectionMsg, 0x4c); break; case IOCTL_DISCONNECT: // Disconnect Message - DEBUG("FT1000:ft1000_ChIoctl: IOCTL_FT1000_DISCONNECT\n"); + DEBUG("FT1000:ft1000_ioctl: IOCTL_FT1000_DISCONNECT\n"); ConnectionMsg[79] = 0xfd; CardSendCommand(ft1000dev, (unsigned short *)ConnectionMsg, 0x4c); break; case IOCTL_GET_DSP_STAT_CMD: - //DEBUG("FT1000:ft1000_ChIoctl: IOCTL_FT1000_GET_DSP_STAT called\n"); + //DEBUG("FT1000:ft1000_ioctl: IOCTL_FT1000_GET_DSP_STAT called\n"); memset(&get_stat_data, 0, sizeof(get_stat_data)); memcpy(get_stat_data.DspVer, info->DspVer, DSPVERSZ); memcpy(get_stat_data.HwSerNum, info->HwSerNum, HWSERNUMSZ); @@ -536,10 +536,10 @@ static long ft1000_ChIoctl (struct file *File, unsigned int Command, if (info->ProgConStat != 0xFF) { ft1000_read_dpram16(ft1000dev, FT1000_MAG_DSP_LED, (u8 *)&ledStat, FT1000_MAG_DSP_LED_INDX); get_stat_data.LedStat = ntohs(ledStat); - DEBUG("FT1000:ft1000_ChIoctl: LedStat = 0x%x\n", get_stat_data.LedStat); + DEBUG("FT1000:ft1000_ioctl: LedStat = 0x%x\n", get_stat_data.LedStat); ft1000_read_dpram16(ft1000dev, FT1000_MAG_DSP_CON_STATE, (u8 *)&conStat, FT1000_MAG_DSP_CON_STATE_INDX); get_stat_data.ConStat = ntohs(conStat); - DEBUG("FT1000:ft1000_ChIoctl: ConStat = 0x%x\n", get_stat_data.ConStat); + DEBUG("FT1000:ft1000_ioctl: ConStat = 0x%x\n", get_stat_data.ConStat); } else { get_stat_data.ConStat = 0x0f; @@ -554,7 +554,7 @@ static long ft1000_ChIoctl (struct file *File, unsigned int Command, get_stat_data.ConTm = (u32)(tv.tv_sec - info->ConTm); DEBUG("Connection Time = %d\n", (int)get_stat_data.ConTm); if (copy_to_user(argp, &get_stat_data, sizeof(get_stat_data)) ) { - DEBUG("FT1000:ft1000_ChIoctl: copy fault occurred\n"); + DEBUG("FT1000:ft1000_ioctl: copy fault occurred\n"); result = -EFAULT; break; } @@ -572,7 +572,7 @@ static long ft1000_ChIoctl (struct file *File, unsigned int Command, u16 app_index; u16 status; - //DEBUG("FT1000:ft1000_ChIoctl: IOCTL_FT1000_SET_DPRAM called\n"); + //DEBUG("FT1000:ft1000_ioctl: IOCTL_FT1000_SET_DPRAM called\n"); if (ft1000_flarion_cnt == 0) { @@ -591,15 +591,15 @@ static long ft1000_ChIoctl (struct file *File, unsigned int Command, if (info->CardReady) { - //DEBUG("FT1000:ft1000_ChIoctl: try to SET_DPRAM \n"); + //DEBUG("FT1000:ft1000_ioctl: try to SET_DPRAM \n"); // Get the length field to see how many bytes to copy result = get_user(msgsz, (__u16 __user *)argp); msgsz = ntohs (msgsz); - //DEBUG("FT1000:ft1000_ChIoctl: length of message = %d\n", msgsz); + //DEBUG("FT1000:ft1000_ioctl: length of message = %d\n", msgsz); if (msgsz > MAX_CMD_SQSIZE) { - DEBUG("FT1000:ft1000_ChIoctl: bad message length = %d\n", msgsz); + DEBUG("FT1000:ft1000_ioctl: bad message length = %d\n", msgsz); result = -EINVAL; break; } @@ -609,7 +609,7 @@ static long ft1000_ChIoctl (struct file *File, unsigned int Command, if (!dpram_data) break; - //if ( copy_from_user(&(dpram_command.dpram_blk), (PIOCTL_DPRAM_BLK)Argument, msgsz+2) ) { + //if ( copy_from_user(&(dpram_command.dpram_blk), (PIOCTL_DPRAM_BLK)argument, msgsz+2) ) { if ( copy_from_user(dpram_data, argp, msgsz+2) ) { DEBUG("FT1000:ft1000_ChIoctl: copy fault occurred\n"); result = -EFAULT; @@ -624,7 +624,7 @@ static long ft1000_ChIoctl (struct file *File, unsigned int Command, #endif // Check if this message came from a registered application for (i=0; iapp_info[i].fileobject == &File->f_owner) { + if ( info->app_info[i].fileobject == &file->f_owner) { break; } } @@ -639,14 +639,14 @@ static long ft1000_ChIoctl (struct file *File, unsigned int Command, // Check message qtype type which is the lower byte within qos_class //qtype = ntohs(dpram_command.dpram_blk.pseudohdr.qos_class) & 0xff; qtype = ntohs(dpram_data->pseudohdr.qos_class) & 0xff; - //DEBUG("FT1000_ft1000_ChIoctl: qtype = %d\n", qtype); + //DEBUG("FT1000_ft1000_ioctl: qtype = %d\n", qtype); if (qtype) { } else { // Put message into Slow Queue // Only put a message into the DPRAM if msg doorbell is available status = ft1000_read_register(ft1000dev, &tempword, FT1000_REG_DOORBELL); - //DEBUG("FT1000_ft1000_ChIoctl: READ REGISTER tempword=%x\n", tempword); + //DEBUG("FT1000_ft1000_ioctl: READ REGISTER tempword=%x\n", tempword); if (tempword & FT1000_DB_DPRAM_TX) { // Suspend for 2ms and try again due to DSP doorbell busy mdelay(2); @@ -662,7 +662,7 @@ static long ft1000_ChIoctl (struct file *File, unsigned int Command, mdelay(3); status = ft1000_read_register(ft1000dev, &tempword, FT1000_REG_DOORBELL); if (tempword & FT1000_DB_DPRAM_TX) { - DEBUG("FT1000:ft1000_ChIoctl:Doorbell not available\n"); + DEBUG("FT1000:ft1000_ioctl:Doorbell not available\n"); result = -ENOTTY; kfree(dpram_data); break; @@ -672,7 +672,7 @@ static long ft1000_ChIoctl (struct file *File, unsigned int Command, } } - //DEBUG("FT1000_ft1000_ChIoctl: finished reading register\n"); + //DEBUG("FT1000_ft1000_ioctl: finished reading register\n"); // Make sure we are within the limits of the slow queue memory limitation if ( (msgsz < MAX_CMD_SQSIZE) && (msgsz > PSEUDOSZ) ) { @@ -719,7 +719,7 @@ static long ft1000_ChIoctl (struct file *File, unsigned int Command, } } else { - DEBUG("FT1000:ft1000_ChIoctl: Card not ready take messages\n"); + DEBUG("FT1000:ft1000_ioctl: Card not ready take messages\n"); result = -EACCES; } kfree(dpram_data); @@ -732,7 +732,7 @@ static long ft1000_ChIoctl (struct file *File, unsigned int Command, IOCTL_DPRAM_BLK __user *pioctl_dpram; int msglen; - //DEBUG("FT1000:ft1000_ChIoctl: IOCTL_FT1000_GET_DPRAM called\n"); + //DEBUG("FT1000:ft1000_ioctl: IOCTL_FT1000_GET_DPRAM called\n"); if (ft1000_flarion_cnt == 0) { return (-EBADF); @@ -740,15 +740,15 @@ static long ft1000_ChIoctl (struct file *File, unsigned int Command, // Search for matching file object for (i=0; iapp_info[i].fileobject == &File->f_owner) { - //DEBUG("FT1000:ft1000_ChIoctl: Message is for AppId = %d\n", info->app_info[i].app_id); + if ( info->app_info[i].fileobject == &file->f_owner) { + //DEBUG("FT1000:ft1000_ioctl: Message is for AppId = %d\n", info->app_info[i].app_id); break; } } // Could not find application info block if (i == MAX_NUM_APP) { - DEBUG("FT1000:ft1000_ChIoctl:Could not find application info block\n"); + DEBUG("FT1000:ft1000_ioctl:Could not find application info block\n"); result = -EBADF; break; } @@ -756,22 +756,22 @@ static long ft1000_ChIoctl (struct file *File, unsigned int Command, result = 0; pioctl_dpram = argp; if (list_empty(&info->app_info[i].app_sqlist) == 0) { - //DEBUG("FT1000:ft1000_ChIoctl:Message detected in slow queue\n"); + //DEBUG("FT1000:ft1000_ioctl:Message detected in slow queue\n"); spin_lock_irqsave(&free_buff_lock, flags); pdpram_blk = list_entry(info->app_info[i].app_sqlist.next, struct dpram_blk, list); list_del(&pdpram_blk->list); info->app_info[i].NumOfMsg--; - //DEBUG("FT1000:ft1000_ChIoctl:NumOfMsg for app %d = %d\n", i, info->app_info[i].NumOfMsg); + //DEBUG("FT1000:ft1000_ioctl:NumOfMsg for app %d = %d\n", i, info->app_info[i].NumOfMsg); spin_unlock_irqrestore(&free_buff_lock, flags); msglen = ntohs(*(u16 *)pdpram_blk->pbuffer) + PSEUDOSZ; result = get_user(msglen, &pioctl_dpram->total_len); if (result) break; msglen = htons(msglen); - //DEBUG("FT1000:ft1000_ChIoctl:msg length = %x\n", msglen); + //DEBUG("FT1000:ft1000_ioctl:msg length = %x\n", msglen); if(copy_to_user (&pioctl_dpram->pseudohdr, pdpram_blk->pbuffer, msglen)) { - DEBUG("FT1000:ft1000_ChIoctl: copy fault occurred\n"); + DEBUG("FT1000:ft1000_ioctl: copy fault occurred\n"); result = -EFAULT; break; } @@ -779,12 +779,12 @@ static long ft1000_ChIoctl (struct file *File, unsigned int Command, ft1000_free_buffer(pdpram_blk, &freercvpool); result = msglen; } - //DEBUG("FT1000:ft1000_ChIoctl: IOCTL_FT1000_GET_DPRAM no message\n"); + //DEBUG("FT1000:ft1000_ioctl: IOCTL_FT1000_GET_DPRAM no message\n"); } break; default: - DEBUG("FT1000:ft1000_ChIoctl:unknown command: 0x%x\n", Command); + DEBUG("FT1000:ft1000_ioctl:unknown command: 0x%x\n", command); result = -ENOTTY; break; } @@ -793,7 +793,7 @@ static long ft1000_ChIoctl (struct file *File, unsigned int Command, } //--------------------------------------------------------------------------- -// Function: ft1000_ChRelease +// Function: ft1000_release // // Parameters: // @@ -802,16 +802,16 @@ static long ft1000_ChIoctl (struct file *File, unsigned int Command, // Notes: // //--------------------------------------------------------------------------- -static int ft1000_ChRelease (struct inode *Inode, struct file *File) +static int ft1000_release (struct inode *inode, struct file *file) { struct ft1000_info *info; struct net_device *dev; int i; struct dpram_blk *pdpram_blk; - DEBUG("ft1000_ChRelease called\n"); + DEBUG("ft1000_release called\n"); - dev = File->private_data; + dev = file->private_data; info = netdev_priv(dev); if (ft1000_flarion_cnt == 0) { @@ -821,8 +821,8 @@ static int ft1000_ChRelease (struct inode *Inode, struct file *File) // Search for matching file object for (i=0; iapp_info[i].fileobject == &File->f_owner) { - //DEBUG("FT1000:ft1000_ChIoctl: Message is for AppId = %d\n", info->app_info[i].app_id); + if ( info->app_info[i].fileobject == &file->f_owner) { + //DEBUG("FT1000:ft1000_ioctl: Message is for AppId = %d\n", info->app_info[i].app_id); break; } } diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c index 69f920fdc12a..7456787481c8 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c @@ -952,7 +952,7 @@ int reg_ft1000_netdev(struct ft1000_device *ft1000dev, struct usb_interface *int //Create character device, implemented by Jim - ft1000_CreateDevice(ft1000dev); + ft1000_create_dev(ft1000dev); DEBUG ("reg_ft1000_netdev returned\n"); diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_usb.c b/drivers/staging/ft1000/ft1000-usb/ft1000_usb.c index d71ac30629f5..7dfed41b02ac 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_usb.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_usb.c @@ -231,7 +231,7 @@ static void ft1000_disconnect(struct usb_interface *interface) if (pft1000info->pFt1000Dev->net) { DEBUG("ft1000_disconnect: destroy char driver\n"); - ft1000_DestroyDevice(pft1000info->pFt1000Dev->net); + ft1000_destroy_dev(pft1000info->pFt1000Dev->net); unregister_netdev(pft1000info->pFt1000Dev->net); DEBUG ("ft1000_disconnect: network device unregisterd\n"); diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_usb.h b/drivers/staging/ft1000/ft1000-usb/ft1000_usb.h index 2c89d14807fb..045ef30b79a1 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_usb.h +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_usb.h @@ -579,8 +579,8 @@ u16 scram_dnldr(struct ft1000_device *ft1000dev, void *pFileStart, u32 FileLeng extern struct list_head freercvpool; extern spinlock_t free_buff_lock; // lock to arbitrate free buffer list for receive command data -int ft1000_CreateDevice(struct ft1000_device *dev); -void ft1000_DestroyDevice(struct net_device *dev); +int ft1000_create_dev(struct ft1000_device *dev); +void ft1000_destroy_dev(struct net_device *dev); extern void CardSendCommand(struct ft1000_device *ft1000dev, void *ptempbuffer, int size); struct dpram_blk *ft1000_get_buffer(struct list_head *bufflist); -- cgit v1.2.3 From c82632d247ce839bfb001723ad1988d30d9febb9 Mon Sep 17 00:00:00 2001 From: Marek Belisko Date: Thu, 9 Dec 2010 11:26:51 +0100 Subject: staging: ft1000: Remove dead code. Signed-off-by: Marek Belisko Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ft1000/ft1000-usb/ft1000_chdev.c | 61 +----------------------- 1 file changed, 1 insertion(+), 60 deletions(-) diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_chdev.c b/drivers/staging/ft1000/ft1000-usb/ft1000_chdev.c index 85f67e564f36..58aee36498e4 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_chdev.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_chdev.c @@ -39,12 +39,9 @@ #include #include #include "ft1000_usb.h" -//#include "ft1000_ioctl.h" static int ft1000_flarion_cnt = 0; -//need to looking usage of ft1000Handle - static int ft1000_open (struct inode *inode, struct file *file); static unsigned int ft1000_poll_dev(struct file *file, poll_table *wait); static long ft1000_ioctl(struct file *file, unsigned int command, @@ -59,9 +56,6 @@ spinlock_t free_buff_lock; int numofmsgbuf = 0; -// Global variable to indicate that all provisioning data is sent to DSP -//bool fProvComplete; - // // Table of entry-point routines for char device // @@ -197,29 +191,6 @@ int ft1000_create_dev(struct ft1000_device *dev) DEBUG("ft1000_CreateDevice: registered char device \"%s\"\n", info->DeviceName); - // initialize application information - -// if (ft1000_flarion_cnt == 0) { -// -// DEBUG("Initialize free_buff_lock and freercvpool\n"); -// spin_lock_init(&free_buff_lock); -// -// // initialize a list of buffers to be use for queuing up receive command data -// INIT_LIST_HEAD (&freercvpool); -// -// // create list of free buffers -// for (i=0; ipbuffer = kmalloc ( MAX_CMD_SQSIZE, GFP_KERNEL ); -// // link provisioning data -// list_add_tail (&pdpram_blk->list, &freercvpool); -// } -// numofmsgbuf = NUM_OF_FREE_BUFFERS; -// } - - // initialize application information info->appcnt = 0; for (i=0; iapp_info[i].app_sqlist); } - - - -// ft1000Handle[info->CardNumber] = devfs_register(NULL, info->DeviceName, DEVFS_FL_AUTO_DEVNUM, 0, 0, -// S_IFCHR | S_IRUGO | S_IWUGO, &ft1000fops, NULL); - - info->DeviceCreated = TRUE; ft1000_flarion_cnt++; @@ -313,9 +277,6 @@ void ft1000_destroy_dev(struct net_device *dev) kfree(ptr); } } - -// devfs_unregister(ft1000Handle[info->CardNumber]); - info->DeviceCreated = FALSE; } @@ -609,19 +570,11 @@ static long ft1000_ioctl (struct file *file, unsigned int command, if (!dpram_data) break; - //if ( copy_from_user(&(dpram_command.dpram_blk), (PIOCTL_DPRAM_BLK)argument, msgsz+2) ) { if ( copy_from_user(dpram_data, argp, msgsz+2) ) { DEBUG("FT1000:ft1000_ChIoctl: copy fault occurred\n"); result = -EFAULT; } else { -#if 0 - // whc - for debugging only - ptr = (char *)&dpram_data; - for (i=0; iapp_info[i].fileobject == &file->f_owner) { @@ -637,7 +590,6 @@ static long ft1000_ioctl (struct file *file, unsigned int command, app_index = i; // Check message qtype type which is the lower byte within qos_class - //qtype = ntohs(dpram_command.dpram_blk.pseudohdr.qos_class) & 0xff; qtype = ntohs(dpram_data->pseudohdr.qos_class) & 0xff; //DEBUG("FT1000_ft1000_ioctl: qtype = %d\n", qtype); if (qtype) { @@ -677,7 +629,6 @@ static long ft1000_ioctl (struct file *file, unsigned int command, // Make sure we are within the limits of the slow queue memory limitation if ( (msgsz < MAX_CMD_SQSIZE) && (msgsz > PSEUDOSZ) ) { // Need to put sequence number plus new checksum for message - //pmsg = (u16 *)&dpram_command.dpram_blk.pseudohdr; pmsg = (u16 *)&dpram_data->pseudohdr; ppseudo_hdr = (struct pseudo_hdr *)pmsg; total_len = msgsz+2; @@ -697,17 +648,7 @@ static long ft1000_ioctl (struct file *file, unsigned int command, } pmsg++; ppseudo_hdr = (struct pseudo_hdr *)pmsg; -#if 0 - ptr = dpram_data; - DEBUG("FT1000:ft1000_ChIoctl: Command Send\n"); - for (i=0; iapp_info[app_index].nTxMsg++; -- cgit v1.2.3 From 05371d1861df75c7d89985760c9ce75fc806f4b8 Mon Sep 17 00:00:00 2001 From: Marek Belisko Date: Thu, 9 Dec 2010 11:26:52 +0100 Subject: staging: ft1000: Remove unused headers. Signed-off-by: Marek Belisko Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ft1000/ft1000-usb/ft1000_chdev.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_chdev.c b/drivers/staging/ft1000/ft1000-usb/ft1000_chdev.c index 58aee36498e4..d249c8ae4f46 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_chdev.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_chdev.c @@ -27,16 +27,12 @@ #include #include #include -#include #include #include #include #include -#include -#include #include -#include #include #include "ft1000_usb.h" -- cgit v1.2.3 From 115884118a65c18af290476e44ca6c76a2c0a694 Mon Sep 17 00:00:00 2001 From: Marek Belisko Date: Thu, 9 Dec 2010 11:26:53 +0100 Subject: staging: ft1000: Fix debug messages. Signed-off-by: Marek Belisko Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ft1000/ft1000-usb/ft1000_chdev.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_chdev.c b/drivers/staging/ft1000/ft1000-usb/ft1000_chdev.c index d249c8ae4f46..da76f11a552f 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_chdev.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_chdev.c @@ -148,18 +148,18 @@ int ft1000_create_dev(struct ft1000_device *dev) // make a new device name sprintf(info->DeviceName, "%s%d", "FT1000_", info->CardNumber); - DEBUG("ft1000_CreateDevice: number of instance = %d\n", ft1000_flarion_cnt); + DEBUG("%s: number of instance = %d\n", __func__, ft1000_flarion_cnt); DEBUG("DeviceCreated = %x\n", info->DeviceCreated); if (info->DeviceCreated) { - DEBUG("ft1000_CreateDevice: \"%s\" already registered\n", info->DeviceName); + DEBUG("%s: \"%s\" already registered\n", __func__, info->DeviceName); return -EIO; } // register the device - DEBUG("ft1000_CreateDevice: \"%s\" device registration\n", info->DeviceName); + DEBUG("%s: \"%s\" debugfs device registration\n", __func__, info->DeviceName); tmp = kmalloc(sizeof(struct ft1000_debug_dirs), GFP_KERNEL); if (tmp == NULL) { @@ -185,7 +185,7 @@ int ft1000_create_dev(struct ft1000_device *dev) tmp->int_number = info->CardNumber; list_add(&(tmp->list), &(info->nodes.list)); - DEBUG("ft1000_CreateDevice: registered char device \"%s\"\n", info->DeviceName); + DEBUG("%s: registered debugfs directory \"%s\"\n", __func__, info->DeviceName); // initialize application information info->appcnt = 0; @@ -234,7 +234,7 @@ void ft1000_destroy_dev(struct net_device *dev) struct list_head *pos, *q; struct ft1000_debug_dirs *dir; - DEBUG("ft1000_chdev:ft1000_DestroyDevice called\n"); + DEBUG("%s called\n", __func__); @@ -250,7 +250,7 @@ void ft1000_destroy_dev(struct net_device *dev) kfree(dir); } } - DEBUG("ft1000_DestroyDevice: unregistered device \"%s\"\n", + DEBUG("%s: unregistered device \"%s\"\n", __func__, info->DeviceName); // Make sure we free any memory reserve for slow Queue @@ -295,7 +295,7 @@ static int ft1000_open (struct inode *inode, struct file *file) struct ft1000_device *dev = (struct ft1000_device *)inode->i_private; int i,num; - DEBUG("ft1000_open called\n"); + DEBUG("%s called\n", __func__); num = (MINOR(inode->i_rdev) & 0xf); DEBUG("ft1000_open: minor number=%d\n", num); -- cgit v1.2.3 From 5fd866fb6401cf6a912e75e1b9c4b906bf42434e Mon Sep 17 00:00:00 2001 From: Marek Belisko Date: Thu, 9 Dec 2010 16:13:47 +0100 Subject: staging: ft1000: Fix proc initialization handling. Cleaning proc entries when error occures was not handled correctly. So fix and also add proper cleaning. Signed-off-by: Marek Belisko Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ft1000/ft1000-usb/ft1000_proc.c | 40 ++++++++++++++++--------- drivers/staging/ft1000/ft1000-usb/ft1000_usb.h | 2 +- 2 files changed, 27 insertions(+), 15 deletions(-) diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_proc.c b/drivers/staging/ft1000/ft1000-usb/ft1000_proc.c index 105846d104ff..dbd4a1ce9f55 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_proc.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_proc.c @@ -193,32 +193,44 @@ static struct notifier_block ft1000_netdev_notifier = { }; -void -ft1000InitProc (struct net_device *dev) +int ft1000InitProc(struct net_device *dev) { struct ft1000_info *info; struct proc_dir_entry *ft1000_proc_file; - info = netdev_priv(dev); + int ret = 0; + info = netdev_priv(dev); info->ft1000_proc_dir = proc_mkdir (FT1000_PROC_DIR, FTNET_PROC); - if (info->ft1000_proc_dir == NULL) - { - remove_proc_entry (FT1000_PROC_DIR, FTNET_PROC); - } - + if (info->ft1000_proc_dir == NULL) { + printk(KERN_WARNING "Unable to create %s dir.\n", + FT1000_PROC_DIR); + ret = -EINVAL; + goto fail; + } ft1000_proc_file = create_proc_read_entry (dev->name, 0644, info->ft1000_proc_dir, ft1000ReadProc, dev); - if (ft1000_proc_file == NULL) - { - remove_proc_entry (info->netdevname, info->ft1000_proc_dir); - } + if (ft1000_proc_file == NULL) { + printk(KERN_WARNING "Unable to create /proc entry.\n"); + ret = -EINVAL; + goto fail_entry; + } snprintf (info->netdevname, IFNAMSIZ, "%s", dev->name); - register_netdevice_notifier (&ft1000_netdev_notifier); - return; + ret = register_netdevice_notifier(&ft1000_netdev_notifier); + if (ret) + goto fail_notif; + + return 0; + +fail_notif: + remove_proc_entry(info->netdevname, info->ft1000_proc_dir); +fail_entry: + remove_proc_entry(FT1000_PROC_DIR, FTNET_PROC); +fail: + return ret; } void diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_usb.h b/drivers/staging/ft1000/ft1000-usb/ft1000_usb.h index 045ef30b79a1..4a91469e64ff 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_usb.h +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_usb.h @@ -594,7 +594,7 @@ struct usb_interface; int reg_ft1000_netdev(struct ft1000_device *ft1000dev, struct usb_interface *intf); int ft1000_poll(void* dev_id); -void ft1000InitProc(struct net_device *dev); +int ft1000InitProc(struct net_device *dev); void ft1000CleanupProc(struct ft1000_info *info); -- cgit v1.2.3 From 04c6620117488c0ccc612da5f2bcbcde025e9301 Mon Sep 17 00:00:00 2001 From: Marek Belisko Date: Thu, 9 Dec 2010 16:13:48 +0100 Subject: staging: ft1000: Fix coding style. Fix coding style in ft1000CleanupProc and ft1000InitProc functions. Signed-off-by: Marek Belisko Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ft1000/ft1000-usb/ft1000_proc.c | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_proc.c b/drivers/staging/ft1000/ft1000-usb/ft1000_proc.c index dbd4a1ce9f55..f197523d0604 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_proc.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_proc.c @@ -196,12 +196,12 @@ static struct notifier_block ft1000_netdev_notifier = { int ft1000InitProc(struct net_device *dev) { struct ft1000_info *info; - struct proc_dir_entry *ft1000_proc_file; + struct proc_dir_entry *ft1000_proc_file; int ret = 0; info = netdev_priv(dev); - info->ft1000_proc_dir = proc_mkdir (FT1000_PROC_DIR, FTNET_PROC); + info->ft1000_proc_dir = proc_mkdir(FT1000_PROC_DIR, FTNET_PROC); if (info->ft1000_proc_dir == NULL) { printk(KERN_WARNING "Unable to create %s dir.\n", FT1000_PROC_DIR); @@ -209,16 +209,18 @@ int ft1000InitProc(struct net_device *dev) goto fail; } - ft1000_proc_file = - create_proc_read_entry (dev->name, 0644, info->ft1000_proc_dir, - ft1000ReadProc, dev); + ft1000_proc_file = + create_proc_read_entry(dev->name, 0644, + info->ft1000_proc_dir, ft1000ReadProc, dev); + if (ft1000_proc_file == NULL) { printk(KERN_WARNING "Unable to create /proc entry.\n"); ret = -EINVAL; goto fail_entry; } - snprintf (info->netdevname, IFNAMSIZ, "%s", dev->name); + snprintf(info->netdevname, IFNAMSIZ, "%s", dev->name); + ret = register_netdevice_notifier(&ft1000_netdev_notifier); if (ret) goto fail_notif; @@ -233,12 +235,9 @@ fail: return ret; } -void -ft1000CleanupProc(struct ft1000_info *info) +void ft1000CleanupProc(struct ft1000_info *info) { - remove_proc_entry (info->netdevname, info->ft1000_proc_dir); - remove_proc_entry (FT1000_PROC_DIR, FTNET_PROC); - unregister_netdevice_notifier (&ft1000_netdev_notifier); - - return; + remove_proc_entry(info->netdevname, info->ft1000_proc_dir); + remove_proc_entry(FT1000_PROC_DIR, FTNET_PROC); + unregister_netdevice_notifier(&ft1000_netdev_notifier); } -- cgit v1.2.3 From 1c46282421c8b31b37323f7b007c4562ce17578c Mon Sep 17 00:00:00 2001 From: Marek Belisko Date: Thu, 9 Dec 2010 16:13:49 +0100 Subject: staging: ft1000: Use return value for ft1000InitProc. Add checking for return value ft1000InitProc and cleanup if something fail. Signed-off-by: Marek Belisko Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ft1000/ft1000-usb/ft1000_usb.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_usb.c b/drivers/staging/ft1000/ft1000-usb/ft1000_usb.c index 7dfed41b02ac..0e1fc3f1e055 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_usb.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_usb.c @@ -198,12 +198,17 @@ static int ft1000_probe(struct usb_interface *interface, if (ret) goto err_thread; - pft1000info->NetDevRegDone = 1; + ret = ft1000InitProc(ft1000dev->net); + if (ret) + goto err_proc; - ft1000InitProc(ft1000dev->net); + pft1000info->NetDevRegDone = 1; return 0; +err_proc: + unregister_netdev(ft1000dev->net); + free_netdev(ft1000dev->net); err_thread: kthread_stop(pft1000info->pPollThread); err_load: -- cgit v1.2.3 From 92914cc8bb6d2d710d102051c9bb7566b0ac75a0 Mon Sep 17 00:00:00 2001 From: Marek Belisko Date: Thu, 9 Dec 2010 16:13:50 +0100 Subject: staging: ft1000: Fix coding style in ft1000NotifyProc. Signed-off-by: Marek Belisko Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ft1000/ft1000-usb/ft1000_proc.c | 31 ++++++++++++------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_proc.c b/drivers/staging/ft1000/ft1000-usb/ft1000_proc.c index f197523d0604..c3fca23d551c 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_proc.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_proc.c @@ -166,30 +166,29 @@ ft1000ReadProc (char *page, char **start, off_t off, int count, int *eof, } static int -ft1000NotifyProc (struct notifier_block *this, unsigned long event, void *ptr) +ft1000NotifyProc(struct notifier_block *this, unsigned long event, void *ptr) { - struct net_device *dev = ptr; + struct net_device *dev = ptr; struct ft1000_info *info; - struct proc_dir_entry *ft1000_proc_file; + struct proc_dir_entry *ft1000_proc_file; -info = netdev_priv(dev); + info = netdev_priv(dev); + switch (event) { + case NETDEV_CHANGENAME: + remove_proc_entry(info->netdevname, info->ft1000_proc_dir); + ft1000_proc_file = create_proc_read_entry(dev->name, 0644, + info->ft1000_proc_dir, + ft1000ReadProc, dev); + snprintf(info->netdevname, IFNAMSIZ, "%s", dev->name); + break; + } - switch (event) - { - case NETDEV_CHANGENAME: - remove_proc_entry (info->netdevname, info->ft1000_proc_dir); - ft1000_proc_file = create_proc_read_entry (dev->name, 0644, - info->ft1000_proc_dir, - ft1000ReadProc, dev); - snprintf (info->netdevname, IFNAMSIZ, "%s", dev->name); - break; - } - return NOTIFY_DONE; + return NOTIFY_DONE; } static struct notifier_block ft1000_netdev_notifier = { - .notifier_call = ft1000NotifyProc + .notifier_call = ft1000NotifyProc, }; -- cgit v1.2.3 From 85d47cff4ea2ab0d5380ba649ac4515d1a5bcf23 Mon Sep 17 00:00:00 2001 From: Marek Belisko Date: Thu, 9 Dec 2010 16:13:51 +0100 Subject: staging: ft1000: Coding style fix in ft1000ReadProc. Signed-off-by: Marek Belisko Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ft1000/ft1000-usb/ft1000_proc.c | 216 ++++++++++++------------ 1 file changed, 106 insertions(+), 110 deletions(-) diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_proc.c b/drivers/staging/ft1000/ft1000-usb/ft1000_proc.c index c3fca23d551c..773316fcecd7 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_proc.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_proc.c @@ -43,126 +43,122 @@ u16 ft1000_read_dpram16 (struct ft1000_device *ft1000dev, u16 indx, static int -ft1000ReadProc (char *page, char **start, off_t off, int count, int *eof, +ft1000ReadProc(char *page, char **start, off_t off, int count, int *eof, void *data) { - struct net_device *dev; - int len; - int i; - unsigned short ledStat; - unsigned short conStat; + struct net_device *dev; + int len; + int i; + unsigned short ledStat; + unsigned short conStat; struct ft1000_info *info; - char *status[] = { "Idle (Disconnect)", "Searching", "Active (Connected)", - "Waiting for L2", "Sleep", "No Coverage", "", "" - }; - - char *signal[] = { "", "*", "**", "***", "****" }; - int strength; - int quality; - struct timeval tv; - time_t delta; - - dev = (struct net_device *) data; + char *status[] = { + "Idle (Disconnect)", + "Searching", + "Active (Connected)", + "Waiting for L2", + "Sleep", + "No Coverage", + "", + "", + }; + + char *signal[] = { "", "*", "**", "***", "****" }; + int strength; + int quality; + struct timeval tv; + time_t delta; + + dev = (struct net_device *) data; info = netdev_priv(dev); - if (off > 0) - { - *eof = 1; - return 0; - } + if (off > 0) { + *eof = 1; + return 0; + } - if (info->ProgConStat != 0xFF) - { - ft1000_read_dpram16 (info->pFt1000Dev, FT1000_MAG_DSP_LED, + if (info->ProgConStat != 0xFF) { + ft1000_read_dpram16(info->pFt1000Dev, FT1000_MAG_DSP_LED, (u8 *)&ledStat, FT1000_MAG_DSP_LED_INDX); - info->LedStat = ntohs (ledStat); - - ft1000_read_dpram16 (info->pFt1000Dev, FT1000_MAG_DSP_CON_STATE, - (u8 *)&conStat, FT1000_MAG_DSP_CON_STATE_INDX); - info->ConStat = ntohs (conStat); - do_gettimeofday (&tv); - delta = (tv.tv_sec - info->ConTm); - } - else - { - info->ConStat = 0xf; - delta = 0; - } - - - - i = (info->LedStat) & 0xf; - switch (i) - { - case 0x1: - strength = 1; - break; - case 0x3: - strength = 2; - break; - case 0x7: - strength = 3; - break; - case 0xf: - strength = 4; - break; - default: - strength = 0; - } - - i = (info->LedStat >> 8) & 0xf; - switch (i) - { - case 0x1: - quality = 1; - break; - case 0x3: - quality = 2; - break; - case 0x7: - quality = 3; - break; - case 0xf: - quality = 4; - break; - default: - quality = 0; - } - - - len = 0; - PUTM_TO_PAGE (len, page, "Connection Time: %02ld:%02ld:%02ld\n", - ((delta / 3600) % 24), ((delta / 60) % 60), (delta % 60)); - PUTM_TO_PAGE (len, page, "Connection Time[s]: %ld\n", delta); - PUTM_TO_PAGE (len, page, "Asic ID: %s\n", - (info->AsicID) == - ELECTRABUZZ_ID ? "ELECTRABUZZ ASIC" : "MAGNEMITE ASIC"); - PUTX_TO_PAGE (len, page, "SKU: ", SKUSZ, info->Sku); - PUTX_TO_PAGE (len, page, "EUI64: ", EUISZ, info->eui64); - PUTD_TO_PAGE (len, page, "DSP version number: ", DSPVERSZ, info->DspVer); - PUTX_TO_PAGE (len, page, "Hardware Serial Number: ", HWSERNUMSZ, - info->HwSerNum); - PUTX_TO_PAGE (len, page, "Caliberation Version: ", CALVERSZ, - info->RfCalVer); - PUTD_TO_PAGE (len, page, "Caliberation Date: ", CALDATESZ, info->RfCalDate); - PUTM_TO_PAGE (len, page, "Media State: %s\n", - (info->mediastate) ? "link" : "no link"); - PUTM_TO_PAGE (len, page, "Connection Status: %s\n", - status[((info->ConStat) & 0x7)]); - PUTM_TO_PAGE (len, page, "RX packets: %ld\n", info->stats.rx_packets); - PUTM_TO_PAGE (len, page, "TX packets: %ld\n", info->stats.tx_packets); - PUTM_TO_PAGE (len, page, "RX bytes: %ld\n", info->stats.rx_bytes); - PUTM_TO_PAGE (len, page, "TX bytes: %ld\n", info->stats.tx_bytes); - PUTM_TO_PAGE (len, page, "Signal Strength: %s\n", signal[strength]); - PUTM_TO_PAGE (len, page, "Signal Quality: %s\n", signal[quality]); - - - - - return len; + info->LedStat = ntohs(ledStat); + + ft1000_read_dpram16(info->pFt1000Dev, FT1000_MAG_DSP_CON_STATE, + (u8 *)&conStat, FT1000_MAG_DSP_CON_STATE_INDX); + info->ConStat = ntohs(conStat); + do_gettimeofday(&tv); + delta = (tv.tv_sec - info->ConTm); + } else { + info->ConStat = 0xf; + delta = 0; + } + + i = (info->LedStat) & 0xf; + switch (i) { + case 0x1: + strength = 1; + break; + case 0x3: + strength = 2; + break; + case 0x7: + strength = 3; + break; + case 0xf: + strength = 4; + break; + default: + strength = 0; + } + + i = (info->LedStat >> 8) & 0xf; + switch (i) { + case 0x1: + quality = 1; + break; + case 0x3: + quality = 2; + break; + case 0x7: + quality = 3; + break; + case 0xf: + quality = 4; + break; + default: + quality = 0; + } + + len = 0; + PUTM_TO_PAGE(len, page, "Connection Time: %02ld:%02ld:%02ld\n", + ((delta / 3600) % 24), ((delta / 60) % 60), (delta % 60)); + PUTM_TO_PAGE(len, page, "Connection Time[s]: %ld\n", delta); + PUTM_TO_PAGE(len, page, "Asic ID: %s\n", + (info->AsicID) == + ELECTRABUZZ_ID ? "ELECTRABUZZ ASIC" : "MAGNEMITE ASIC"); + PUTX_TO_PAGE(len, page, "SKU: ", SKUSZ, info->Sku); + PUTX_TO_PAGE(len, page, "EUI64: ", EUISZ, info->eui64); + PUTD_TO_PAGE(len, page, "DSP version number: ", DSPVERSZ, info->DspVer); + PUTX_TO_PAGE(len, page, "Hardware Serial Number: ", HWSERNUMSZ, + info->HwSerNum); + PUTX_TO_PAGE(len, page, "Caliberation Version: ", CALVERSZ, + info->RfCalVer); + PUTD_TO_PAGE(len, page, "Caliberation Date: ", CALDATESZ, + info->RfCalDate); + PUTM_TO_PAGE(len, page, "Media State: %s\n", + (info->mediastate) ? "link" : "no link"); + PUTM_TO_PAGE(len, page, "Connection Status: %s\n", + status[((info->ConStat) & 0x7)]); + PUTM_TO_PAGE(len, page, "RX packets: %ld\n", info->stats.rx_packets); + PUTM_TO_PAGE(len, page, "TX packets: %ld\n", info->stats.tx_packets); + PUTM_TO_PAGE(len, page, "RX bytes: %ld\n", info->stats.rx_bytes); + PUTM_TO_PAGE(len, page, "TX bytes: %ld\n", info->stats.tx_bytes); + PUTM_TO_PAGE(len, page, "Signal Strength: %s\n", signal[strength]); + PUTM_TO_PAGE(len, page, "Signal Quality: %s\n", signal[quality]); + + return len; } static int -- cgit v1.2.3 From 96ff77f7350576d1b25908b59f15d2ab5222c432 Mon Sep 17 00:00:00 2001 From: Marek Belisko Date: Thu, 9 Dec 2010 16:13:52 +0100 Subject: staging: ft1000: Fix coding style. Signed-off-by: Marek Belisko Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ft1000/ft1000-usb/ft1000_proc.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_proc.c b/drivers/staging/ft1000/ft1000-usb/ft1000_proc.c index 773316fcecd7..bd28a6bfa86a 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_proc.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_proc.c @@ -14,23 +14,19 @@ #define PUTX_TO_PAGE(len,page,message,size,var) \ len += snprintf(page+len, PAGE_SIZE - len, message); \ - for(i = 0; i < (size - 1); i++) \ - { \ + for (i = 0; i < (size - 1); i++) {\ len += snprintf(page+len, PAGE_SIZE - len, "%02x:", var[i]); \ } \ len += snprintf(page+len, PAGE_SIZE - len, "%02x\n", var[i]) #define PUTD_TO_PAGE(len,page,message,size,var) \ len += snprintf(page+len, PAGE_SIZE - len, message); \ - for(i = 0; i < (size - 1); i++) \ - { \ + for (i = 0; i < (size - 1); i++) {\ len += snprintf(page+len, PAGE_SIZE - len, "%d.", var[i]); \ } \ len += snprintf(page+len, PAGE_SIZE - len, "%d\n", var[i]) - - //#ifdef INIT_NET_NS #define FTNET_PROC init_net.proc_net //#else -- cgit v1.2.3 From e2398c61272f378b257b3107fdb960e0b642eeb6 Mon Sep 17 00:00:00 2001 From: Marek Belisko Date: Thu, 9 Dec 2010 16:13:53 +0100 Subject: staging: ft1000: Remove dead code. Signed-off-by: Marek Belisko Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ft1000/ft1000-usb/ft1000_proc.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_proc.c b/drivers/staging/ft1000/ft1000-usb/ft1000_proc.c index bd28a6bfa86a..da706f84df64 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_proc.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_proc.c @@ -27,11 +27,7 @@ len += snprintf(page+len, PAGE_SIZE - len, "%d\n", var[i]) -//#ifdef INIT_NET_NS #define FTNET_PROC init_net.proc_net -//#else -//#define FTNET_PROC proc_net -//#endif u16 ft1000_read_dpram16 (struct ft1000_device *ft1000dev, u16 indx, -- cgit v1.2.3 From c5e61563e26b5a43646393c5f5020d172b2767c7 Mon Sep 17 00:00:00 2001 From: Marek Belisko Date: Thu, 9 Dec 2010 16:13:54 +0100 Subject: staging: ft1000: Add file header to ft1000_proc.c Signed-off-by: Marek Belisko Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ft1000/ft1000-usb/ft1000_proc.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_proc.c b/drivers/staging/ft1000/ft1000-usb/ft1000_proc.c index da706f84df64..0f271c281b85 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_proc.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_proc.c @@ -1,3 +1,24 @@ +/* + * ft1000_proc.c - ft1000 proc interface + * + * Copyright (C) 2009-2010 Quintec + * (C) 2010 Open-nandra + * + * + * 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. + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + #include #include #include -- cgit v1.2.3 From f15662755f7eb3db4a416d52af24771cc208e7b0 Mon Sep 17 00:00:00 2001 From: Mark Allyn Date: Thu, 9 Dec 2010 09:30:03 -0800 Subject: Staging: sep: remove virtual address being passed to user space application Signed-off-by: Mark Allyn Signed-off-by: Greg Kroah-Hartman --- drivers/staging/sep/sep_driver.c | 23 +++++------------------ drivers/staging/sep/sep_driver_api.h | 14 +------------- 2 files changed, 6 insertions(+), 31 deletions(-) diff --git a/drivers/staging/sep/sep_driver.c b/drivers/staging/sep/sep_driver.c index f2c216df362e..a5c0443b4efc 100644 --- a/drivers/staging/sep/sep_driver.c +++ b/drivers/staging/sep/sep_driver.c @@ -2541,12 +2541,9 @@ static int sep_free_dma_tables_and_dcb(struct sep_device *sep, bool isapplet, * This function sets the bus and virtual addresses of the static pool * and returns the virtual address */ -static int sep_get_static_pool_addr_handler(struct sep_device *sep, - unsigned long arg) +static int sep_get_static_pool_addr_handler(struct sep_device *sep) { - struct stat_pool_addr_struct command_args; u32 *static_pool_addr = NULL; - unsigned long addr_hold; dev_dbg(&sep->pdev->dev, "sep_get_static_pool_addr_handler start\n"); @@ -2554,21 +2551,11 @@ static int sep_get_static_pool_addr_handler(struct sep_device *sep, SEP_DRIVER_SYSTEM_RAR_MEMORY_OFFSET_IN_BYTES); static_pool_addr[0] = SEP_STATIC_POOL_VAL_TOKEN; - static_pool_addr[1] = sep->shared_bus + + static_pool_addr[1] = (u32)sep->shared_bus + SEP_DRIVER_STATIC_AREA_OFFSET_IN_BYTES; - addr_hold = (unsigned long) - (sep->shared_addr + SEP_DRIVER_STATIC_AREA_OFFSET_IN_BYTES); - command_args.static_virt_address = (aligned_u64)addr_hold; - - dev_dbg(&sep->pdev->dev, "static pool: physical %x virtual %x\n", - (u32)static_pool_addr[1], - (u32)command_args.static_virt_address); - - /* Send the parameters to user application */ - if (copy_to_user((void __user *) arg, &command_args, - sizeof(struct stat_pool_addr_struct))) - return -EFAULT; + dev_dbg(&sep->pdev->dev, "static pool: physical %x\n", + (u32)static_pool_addr[1]); dev_dbg(&sep->pdev->dev, "sep_get_static_pool_addr_handler end\n"); @@ -3064,7 +3051,7 @@ static long sep_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) break; case SEP_IOCGETSTATICPOOLADDR: /* Get the physical and virtual addresses of the static pool */ - error = sep_get_static_pool_addr_handler(sep, arg); + error = sep_get_static_pool_addr_handler(sep); break; case SEP_IOCENDTRANSACTION: error = sep_end_transaction_handler(sep); diff --git a/drivers/staging/sep/sep_driver_api.h b/drivers/staging/sep/sep_driver_api.h index 1207722d8b6a..5508769fc5df 100644 --- a/drivers/staging/sep/sep_driver_api.h +++ b/drivers/staging/sep/sep_driver_api.h @@ -114,18 +114,6 @@ struct bld_syn_tab_struct { }; -/* - * command struct for static pool addresses - * Please note that this is a kernel virtual - * address; this will be removed at the next - * release of the Discretix middleware - */ -struct stat_pool_addr_struct { - /* virtual address of the static pool */ - aligned_u64 static_virt_address; -}; - - /* command struct for getting caller id value and address */ struct caller_id_struct { /* pid of the process */ @@ -275,7 +263,7 @@ struct sep_lli_entry { /* get the static pool area addersses (physical and virtual) */ #define SEP_IOCGETSTATICPOOLADDR \ - _IOR(SEP_IOC_MAGIC_NUMBER, 8, struct stat_pool_addr_struct) + _IO(SEP_IOC_MAGIC_NUMBER, 8) /* start sep command */ #define SEP_IOCSEPSTART \ -- cgit v1.2.3 From e957b063abdf0f005ba2c298345c75aa7ac4c22a Mon Sep 17 00:00:00 2001 From: Mark Allyn Date: Thu, 9 Dec 2010 09:30:17 -0800 Subject: Staging: sep: remove spaces at end of lines Signed-off-by: Mark Allyn Signed-off-by: Greg Kroah-Hartman --- drivers/staging/sep/sep_driver.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/staging/sep/sep_driver.c b/drivers/staging/sep/sep_driver.c index a5c0443b4efc..241b1b1bcaed 100644 --- a/drivers/staging/sep/sep_driver.c +++ b/drivers/staging/sep/sep_driver.c @@ -275,7 +275,7 @@ end_function: * @filp: file handle to SEP device * * Open method for the SEP device. Called when userspace opens - * the SEP device node. + * the SEP device node. * * Returns zero on success otherwise an error code. */ @@ -1811,7 +1811,7 @@ static int sep_prepare_input_dma_table(struct sep_device *sep, info_entry_ptr->bus_address = sep_shared_area_virt_to_bus(sep, in_lli_table_ptr); - info_entry_ptr->block_size = + info_entry_ptr->block_size = ((num_entries_in_table) << 24) | (table_data_size); } @@ -2164,7 +2164,7 @@ static int sep_prepare_input_output_dma_table(struct sep_device *sep, error = sep_lock_user_pages(sep, app_virt_in_addr, data_size, &lli_in_array, SEP_DRIVER_IN_FLAG); if (error) { - dev_warn(&sep->pdev->dev, + dev_warn(&sep->pdev->dev, "sep_lock_user_pages for input virtual buffer failed\n"); goto end_function; } @@ -2808,7 +2808,7 @@ static int sep_end_transaction_handler(struct sep_device *sep) } /** - * sep_prepare_dcb_handler - prepare a control block + * sep_prepare_dcb_handler - prepare a control block * @sep: pointer to struct sep_device * @arg: pointer to user parameters * @@ -2873,7 +2873,7 @@ static int sep_free_dcb_handler(struct sep_device *sep) } /** - * sep_rar_prepare_output_msg_handler - prepare an output message + * sep_rar_prepare_output_msg_handler - prepare an output message * @sep: pointer to struct sep_device * @arg: pointer to user parameters * @@ -3557,7 +3557,7 @@ static int __devinit sep_probe(struct pci_dev *pdev, if (error == 0) /* Success */ return 0; - + end_function_free_irq: free_irq(pdev->irq, sep); @@ -3626,7 +3626,7 @@ static int __init sep_init(void) /** - * sep_exit - called to unload driver + * sep_exit - called to unload driver * * Drop the misc devices then remove and unmap the various resources * that are not released by the driver remove method. -- cgit v1.2.3 From b0daf59c5fc9ac6c65645ffb40156f5d5a0052a4 Mon Sep 17 00:00:00 2001 From: Mark Allyn Date: Thu, 9 Dec 2010 09:30:31 -0800 Subject: Staging: sep: sram_addr is 32 bit; this is not a kernel address, but device internal value This does not have to be 64 bits wide Signed-off-by: Mark Allyn Signed-off-by: Greg Kroah-Hartman --- drivers/staging/sep/sep_driver_api.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/sep/sep_driver_api.h b/drivers/staging/sep/sep_driver_api.h index 5508769fc5df..fbbfa2396555 100644 --- a/drivers/staging/sep/sep_driver_api.h +++ b/drivers/staging/sep/sep_driver_api.h @@ -61,7 +61,7 @@ struct init_struct { u32 message_size_in_words; /* offset of the init message in the sep sram */ - aligned_u64 sep_sram_addr; + u32 sep_sram_addr; /* -not used- resident size in bytes*/ u32 unused_resident_size_in_bytes; -- cgit v1.2.3 From 843f65c669c1164897dc5ef79c0df00cb66490bf Mon Sep 17 00:00:00 2001 From: Mark Allyn Date: Thu, 9 Dec 2010 09:31:18 -0800 Subject: Staging: sep: clean up error checking in probe function Add pci_disable Signed-off-by: Mark Allyn Signed-off-by: Greg Kroah-Hartman --- drivers/staging/sep/sep_driver.c | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/drivers/staging/sep/sep_driver.c b/drivers/staging/sep/sep_driver.c index 241b1b1bcaed..821d3b7c6477 100644 --- a/drivers/staging/sep/sep_driver.c +++ b/drivers/staging/sep/sep_driver.c @@ -3437,7 +3437,8 @@ static int __devinit sep_probe(struct pci_dev *pdev, if (sep_dev == NULL) { dev_warn(&pdev->dev, "can't kmalloc the sep_device structure\n"); - return -ENOMEM; + error = -ENOMEM; + goto end_function_disable_device; } /* @@ -3448,7 +3449,7 @@ static int __devinit sep_probe(struct pci_dev *pdev, */ sep = sep_dev; - sep->pdev = pdev; + sep->pdev = pci_dev_get(pdev); init_waitqueue_head(&sep->event); init_waitqueue_head(&sep->event_request_daemon); @@ -3466,23 +3467,23 @@ static int __devinit sep_probe(struct pci_dev *pdev, sep->reg_physical_addr = pci_resource_start(sep->pdev, 0); if (!sep->reg_physical_addr) { dev_warn(&sep->pdev->dev, "Error getting register start\n"); - pci_dev_put(sep->pdev); - return -ENODEV; + error = -ENODEV; + goto end_function_free_sep_dev; } sep->reg_physical_end = pci_resource_end(sep->pdev, 0); if (!sep->reg_physical_end) { dev_warn(&sep->pdev->dev, "Error getting register end\n"); - pci_dev_put(sep->pdev); - return -ENODEV; + error = -ENODEV; + goto end_function_free_sep_dev; } sep->reg_addr = ioremap_nocache(sep->reg_physical_addr, (size_t)(sep->reg_physical_end - sep->reg_physical_addr + 1)); if (!sep->reg_addr) { dev_warn(&sep->pdev->dev, "Error getting register virtual\n"); - pci_dev_put(sep->pdev); - return -ENODEV; + error = -ENODEV; + goto end_function_free_sep_dev; } dev_dbg(&sep->pdev->dev, @@ -3573,9 +3574,15 @@ end_function_deallocate_sep_shared_area: end_function_error: iounmap(sep->reg_addr); + +end_function_free_sep_dev: + pci_dev_put(sep_dev->pdev); kfree(sep_dev); sep_dev = NULL; +end_function_disable_device: + pci_disable_device(pdev); + end_function: return error; } -- cgit v1.2.3 From 08740c97e191d4d5bb1f472a6ec0fa24ebdbc8bc Mon Sep 17 00:00:00 2001 From: Mark Allyn Date: Thu, 9 Dec 2010 09:31:31 -0800 Subject: Staging: sep: initialize driver copy of send and receive count with device Signed-off-by: Mark Allyn Signed-off-by: Greg Kroah-Hartman --- drivers/staging/sep/sep_driver.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/staging/sep/sep_driver.c b/drivers/staging/sep/sep_driver.c index 821d3b7c6477..c8008244d3f9 100644 --- a/drivers/staging/sep/sep_driver.c +++ b/drivers/staging/sep/sep_driver.c @@ -3538,6 +3538,11 @@ static int __devinit sep_probe(struct pci_dev *pdev, /* Set the IMR register - open only GPR 2 */ sep_write_reg(sep, HW_HOST_IMR_REG_ADDR, (~(0x1 << 13))); + /* Read send/receive counters from SEP */ + sep->reply_ct = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR2_REG_ADDR); + sep->reply_ct &= 0x3FFFFFFF; + sep->send_ct = sep->reply_ct; + dev_dbg(&sep->pdev->dev, "about to call request_irq\n"); /* Get the interrupt line */ error = request_irq(pdev->irq, sep_inthandler, IRQF_SHARED, -- cgit v1.2.3 From 0dd12c44510c342282145c8048b447a13ce78a32 Mon Sep 17 00:00:00 2001 From: Mark Allyn Date: Thu, 9 Dec 2010 09:31:43 -0800 Subject: Staging: sep: remove code for Moorestown device The Moorestown (older device) will be added to driver later. Signed-off-by: Mark Allyn Signed-off-by: Greg Kroah-Hartman --- drivers/staging/sep/sep_driver.c | 110 ++++++------------------------- drivers/staging/sep/sep_driver_hw_defs.h | 1 - 2 files changed, 20 insertions(+), 91 deletions(-) diff --git a/drivers/staging/sep/sep_driver.c b/drivers/staging/sep/sep_driver.c index c8008244d3f9..5a54f984e28e 100644 --- a/drivers/staging/sep/sep_driver.c +++ b/drivers/staging/sep/sep_driver.c @@ -940,9 +940,7 @@ static int sep_send_command_handler(struct sep_device *sep) } sep_set_time(sep); - /* Only Medfield has caller id */ - if (sep->mrst == 0) - sep_set_current_caller_id(sep); + sep_set_current_caller_id(sep); sep_dump_message(sep); @@ -3057,8 +3055,6 @@ static long sep_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) error = sep_end_transaction_handler(sep); break; case SEP_IOCREALLOCEXTCACHE: - if (sep->mrst) - error = -ENODEV; if (sep->pdev->revision == 0) /* Only for old chip */ error = sep_realloc_ext_cache_handler(sep, arg); else @@ -3237,55 +3233,6 @@ static irqreturn_t sep_inthandler(int irq, void *dev_id) return int_error; } -/** - * sep_callback - RAR callback - * @sep_context_pointer: pointer to struct sep_device - * - * Function that is called by rar_register when it is ready with - * a region (only for Moorestown) - */ -static int sep_callback(unsigned long sep_context_pointer) -{ - int error; - struct sep_device *sep = (struct sep_device *)sep_context_pointer; - dma_addr_t rar_end_address; - - dev_dbg(&sep->pdev->dev, "callback start\n"); - - error = rar_get_address(RAR_TYPE_IMAGE, &sep->rar_bus, - &rar_end_address); - - if (error) { - dev_warn(&sep->pdev->dev, "mrst can't get rar region\n"); - goto end_function; - } - - sep->rar_size = (size_t)(rar_end_address - sep->rar_bus + 1); - - if (!request_mem_region(sep->rar_bus, sep->rar_size, - "sep_sec_driver")) { - dev_warn(&sep->pdev->dev, - "request mem region for mrst failed\n"); - error = -1; - goto end_function; - } - - sep->rar_addr = ioremap_nocache(sep->rar_bus, sep->rar_size); - if (!sep->rar_addr) { - dev_warn(&sep->pdev->dev, - "ioremap nocache for mrst rar failed\n"); - error = -ENOMEM; - goto end_function; - } - dev_dbg(&sep->pdev->dev, "rar start is %p, phy is %llx, size is %zx\n", - sep->rar_addr, (unsigned long long)sep->rar_bus, - sep->rar_size); - -end_function: - dev_dbg(&sep->pdev->dev, "callback end\n"); - return error; -} - /** * sep_reconfig_shared_area - reconfigure shared area * @sep: pointer to struct sep_device @@ -3390,16 +3337,14 @@ static int sep_register_driver_with_fs(struct sep_device *sep) return ret_val; } - if (!sep->mrst) { - ret_val = misc_register(&sep->miscdev_daemon); - if (ret_val) { - dev_warn(&sep->pdev->dev, "misc reg fails for dmn %x\n", - ret_val); - misc_deregister(&sep->miscdev_sep); - misc_deregister(&sep->miscdev_singleton); + ret_val = misc_register(&sep->miscdev_daemon); + if (ret_val) { + dev_warn(&sep->pdev->dev, "misc reg fails for dmn %x\n", + ret_val); + misc_deregister(&sep->miscdev_sep); + misc_deregister(&sep->miscdev_singleton); - return ret_val; - } + return ret_val; } return ret_val; } @@ -3457,9 +3402,6 @@ static int __devinit sep_probe(struct pci_dev *pdev, mutex_init(&sep->sep_mutex); mutex_init(&sep->ioctl_mutex); - if (pdev->device == MRST_PCI_DEVICE_ID) - sep->mrst = 1; - dev_dbg(&sep->pdev->dev, "PCI obtained, device being prepared\n"); dev_dbg(&sep->pdev->dev, "revision is %d\n", sep->pdev->revision); @@ -3505,31 +3447,20 @@ static int __devinit sep_probe(struct pci_dev *pdev, goto end_function_error; } - /* The next section depends on type of unit */ - if (sep->mrst) { - error = register_rar(RAR_TYPE_IMAGE, &sep_callback, - (unsigned long)sep); - if (error) { - dev_dbg(&sep->pdev->dev, - "error register_rar\n"); - goto end_function_deallocate_sep_shared_area; - } - } else { - sep->rar_size = FAKE_RAR_SIZE; - sep->rar_addr = dma_alloc_coherent(NULL, - sep->rar_size, &sep->rar_bus, GFP_KERNEL); - if (sep->rar_addr == NULL) { - dev_warn(&sep->pdev->dev, "can't allocate mfld rar\n"); - error = -ENOMEM; - goto end_function_deallocate_sep_shared_area; - } - - dev_dbg(&sep->pdev->dev, "rar start is %p, phy is %llx," - " size is %zx\n", sep->rar_addr, - (unsigned long long)sep->rar_bus, - sep->rar_size); + sep->rar_size = FAKE_RAR_SIZE; + sep->rar_addr = dma_alloc_coherent(NULL, + sep->rar_size, &sep->rar_bus, GFP_KERNEL); + if (sep->rar_addr == NULL) { + dev_warn(&sep->pdev->dev, "can't allocate mfld rar\n"); + error = -ENOMEM; + goto end_function_deallocate_sep_shared_area; } + dev_dbg(&sep->pdev->dev, "rar start is %p, phy is %llx," + " size is %zx\n", sep->rar_addr, + (unsigned long long)sep->rar_bus, + sep->rar_size); + dev_dbg(&sep->pdev->dev, "about to write IMR and ICR REG_ADDR\n"); /* Clear ICR register */ @@ -3610,7 +3541,6 @@ static void sep_remove(struct pci_dev *pdev) } static DEFINE_PCI_DEVICE_TABLE(sep_pci_id_tbl) = { - {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MRST_PCI_DEVICE_ID)}, {PCI_DEVICE(PCI_VENDOR_ID_INTEL, MFLD_PCI_DEVICE_ID)}, {0} }; diff --git a/drivers/staging/sep/sep_driver_hw_defs.h b/drivers/staging/sep/sep_driver_hw_defs.h index 29addd7b5dd3..300f90963de3 100644 --- a/drivers/staging/sep/sep_driver_hw_defs.h +++ b/drivers/staging/sep/sep_driver_hw_defs.h @@ -33,7 +33,6 @@ #define SEP_DRIVER_HW_DEFS__H /* PCI ID's */ -#define MRST_PCI_DEVICE_ID 0x080c #define MFLD_PCI_DEVICE_ID 0x0826 /*----------------------- */ -- cgit v1.2.3 From 8f9346a091ac523afa73643aae69f74f0f8a6e80 Mon Sep 17 00:00:00 2001 From: Mark Allyn Date: Thu, 9 Dec 2010 09:31:57 -0800 Subject: Staging: sep: remove completed items in TODO Signed-off-by: Mark Allyn Signed-off-by: Greg Kroah-Hartman --- drivers/staging/sep/TODO | 7 ------- 1 file changed, 7 deletions(-) diff --git a/drivers/staging/sep/TODO b/drivers/staging/sep/TODO index 371ee279f327..089c2406345e 100644 --- a/drivers/staging/sep/TODO +++ b/drivers/staging/sep/TODO @@ -1,12 +1,5 @@ Todo's so far (from Alan Cox) -- Fix firmware loading - Done 09/10 M. Allyn -- Get firmware into firmware git tree - Firmware is non open source -- Review and tidy each algorithm function - Done 09/10 M. Allyn - Check whether it can be plugged into any of the kernel crypto API interfaces - Crypto API 'glue' is still not ready to submit -- Do something about the magic shared memory interface and replace it - with something saner (in Linux terms) - Done 09/10 M. Allyn - Clean up unused ioctls - Needs vendor help - Clean up unused fields in ioctl structures - Needs vendor help -- 64 bit size to be used for all user space addresses passed - to ioctl - Done 10/10 M. Allyn -- cgit v1.2.3 From be38efe11748684d54ff86810443979a59b96cfc Mon Sep 17 00:00:00 2001 From: Mark Allyn Date: Thu, 9 Dec 2010 09:32:13 -0800 Subject: Staging: sep: limit time to wait for reconfig shared area complete Signed-off-by: Mark Allyn Signed-off-by: Greg Kroah-Hartman --- drivers/staging/sep/sep_driver.c | 9 ++++++++- drivers/staging/sep/sep_driver_config.h | 2 ++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/staging/sep/sep_driver.c b/drivers/staging/sep/sep_driver.c index 5a54f984e28e..83475eb77ad8 100644 --- a/drivers/staging/sep/sep_driver.c +++ b/drivers/staging/sep/sep_driver.c @@ -53,6 +53,7 @@ #include #include #include +#include #include #include "../memrar/memrar.h" @@ -3244,6 +3245,9 @@ static int sep_reconfig_shared_area(struct sep_device *sep) { int ret_val; + /* use to limit waiting for SEP */ + unsigned long end_time; + dev_dbg(&sep->pdev->dev, "reconfig shared area start\n"); /* Send the new SHARED MESSAGE AREA to the SEP */ @@ -3255,7 +3259,10 @@ static int sep_reconfig_shared_area(struct sep_device *sep) /* Poll for SEP response */ ret_val = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR1_REG_ADDR); - while (ret_val != 0xffffffff && ret_val != sep->shared_bus) + end_time = jiffies + (WAIT_TIME * HZ); + + while ((time_before(jiffies, end_time)) && (ret_val != 0xffffffff) && + (ret_val != sep->shared_bus)) ret_val = sep_read_reg(sep, HW_HOST_SEP_HOST_GPR1_REG_ADDR); /* Check the return value (register) */ diff --git a/drivers/staging/sep/sep_driver_config.h b/drivers/staging/sep/sep_driver_config.h index b96045f178cd..92338c0f6bd2 100644 --- a/drivers/staging/sep/sep_driver_config.h +++ b/drivers/staging/sep/sep_driver_config.h @@ -230,5 +230,7 @@ held by the proccess (struct file) */ /* the token that defines the data pool pointers address */ #define SEP_EXT_CACHE_ADDR_VAL_TOKEN 0xBABABABA +/* Time limit for SEP to finish */ +#define WAIT_TIME 10 #endif /* SEP DRIVER CONFIG */ -- cgit v1.2.3 From c100fa4d6142271cc6d228fd84a5da2390ec5ec1 Mon Sep 17 00:00:00 2001 From: Mark Allyn Date: Thu, 9 Dec 2010 09:32:26 -0800 Subject: Staging: sep: reduce 64 and 32 bit compile warnings Signed-off-by: Mark Allyn Signed-off-by: Greg Kroah-Hartman --- drivers/staging/sep/sep_driver.c | 101 ++++++++++++++++----------------------- 1 file changed, 40 insertions(+), 61 deletions(-) diff --git a/drivers/staging/sep/sep_driver.c b/drivers/staging/sep/sep_driver.c index 83475eb77ad8..903d6106c0d3 100644 --- a/drivers/staging/sep/sep_driver.c +++ b/drivers/staging/sep/sep_driver.c @@ -91,7 +91,7 @@ static int sep_load_firmware(struct sep_device *sep) char *res_name = "resident.image.bin"; char *extapp_name = "extapp.image.bin"; int error ; - unsigned int work1, work2, work3; + unsigned long work1, work2, work3; /* Set addresses and load resident */ sep->resident_bus = sep->rar_bus; @@ -115,13 +115,13 @@ static int sep_load_firmware(struct sep_device *sep) sep->resident_size); /* Set addresses for dcache (no loading needed) */ - work1 = (unsigned int)sep->resident_bus; - work2 = (unsigned int)sep->resident_size; + work1 = (unsigned long)sep->resident_bus; + work2 = (unsigned long)sep->resident_size; work3 = (work1 + work2 + (1024 * 4)) & 0xfffff000; sep->dcache_bus = (dma_addr_t)work3; - work1 = (unsigned int)sep->resident_addr; - work2 = (unsigned int)sep->resident_size; + work1 = (unsigned long)sep->resident_addr; + work2 = (unsigned long)sep->resident_size; work3 = (work1 + work2 + (1024 * 4)) & 0xfffff000; sep->dcache_addr = (void *)work3; @@ -831,7 +831,7 @@ static unsigned long sep_set_time(struct sep_device *sep) * Inserts the data into the caller id table. Note that this function * falls under the ioctl lock */ -static int sep_set_caller_id_handler(struct sep_device *sep, u32 arg) +static int sep_set_caller_id_handler(struct sep_device *sep, unsigned long arg) { void __user *hash; int error = 0; @@ -1063,7 +1063,7 @@ end_function: * the kernel (when ioctl is not used) */ static int sep_lock_kernel_pages(struct sep_device *sep, - u32 kernel_virt_addr, + unsigned long kernel_virt_addr, u32 data_size, struct sep_lli_entry **lli_array_ptr, int in_out_flag) @@ -1076,8 +1076,8 @@ static int sep_lock_kernel_pages(struct sep_device *sep, struct sep_dma_map *map_array; dev_dbg(&sep->pdev->dev, "sep_lock_kernel_pages start\n"); - dev_dbg(&sep->pdev->dev, "kernel_virt_addr is %08x\n", - kernel_virt_addr); + dev_dbg(&sep->pdev->dev, "kernel_virt_addr is %08lx\n", + (unsigned long)kernel_virt_addr); dev_dbg(&sep->pdev->dev, "data_size is %x\n", data_size); lli_array = kmalloc(sizeof(struct sep_lli_entry), GFP_ATOMIC); @@ -1530,8 +1530,8 @@ static dma_addr_t sep_shared_area_virt_to_bus(struct sep_device *sep, static void *sep_shared_area_bus_to_virt(struct sep_device *sep, dma_addr_t bus_address) { - dev_dbg(&sep->pdev->dev, "shared bus to virt b=%x v=%x\n", - (u32)bus_address, (u32)(sep->shared_addr + + dev_dbg(&sep->pdev->dev, "shared bus to virt b=%lx v=%lx\n", + (unsigned long)bus_address, (unsigned long)(sep->shared_addr + (size_t)(bus_address - sep->shared_bus))); return sep->shared_addr + (size_t)(bus_address - sep->shared_bus); @@ -1556,7 +1556,7 @@ static void sep_debug_print_lli_tables(struct sep_device *sep, dev_dbg(&sep->pdev->dev, "sep_debug_print_lli_tables start\n"); - while ((unsigned long) lli_table_ptr != 0xffffffff) { + while ((unsigned long) lli_table_ptr->bus_address != 0xffffffff) { dev_dbg(&sep->pdev->dev, "lli table %08lx, table_data_size is %lu\n", table_count, table_data_size); @@ -1590,18 +1590,16 @@ static void sep_debug_print_lli_tables(struct sep_device *sep, table_data_size = lli_table_ptr->block_size & 0xffffff; num_table_entries = (lli_table_ptr->block_size >> 24) & 0xff; - lli_table_ptr = (struct sep_lli_entry *) - (lli_table_ptr->bus_address); dev_dbg(&sep->pdev->dev, "phys table_data_size is %lu num_table_entries is" - " %lu lli_table_ptr is%lu\n", table_data_size, - num_table_entries, (unsigned long)lli_table_ptr); + " %lu bus_address is%lu\n", table_data_size, + num_table_entries, (unsigned long)lli_table_ptr->bus_address); - if ((unsigned long)lli_table_ptr != 0xffffffff) + if ((unsigned long)lli_table_ptr->bus_address != 0xffffffff) lli_table_ptr = (struct sep_lli_entry *) sep_shared_bus_to_virt(sep, - (unsigned long)lli_table_ptr); + (unsigned long)lli_table_ptr->bus_address); table_count++; } @@ -1701,7 +1699,7 @@ static int sep_prepare_input_dma_table(struct sep_device *sep, /* Number of entries in lli table */ u32 num_entries_in_table = 0; /* Next table address */ - u32 lli_table_alloc_addr = 0; + void *lli_table_alloc_addr = 0; dev_dbg(&sep->pdev->dev, "sep_prepare_input_dma_table start\n"); dev_dbg(&sep->pdev->dev, "data_size is %x\n", data_size); @@ -1712,7 +1710,7 @@ static int sep_prepare_input_dma_table(struct sep_device *sep, sep->dma_res_arr[sep->nr_dcb_creat].in_num_pages = 0; /* Set the kernel address for first table to be allocated */ - lli_table_alloc_addr = (u32)(sep->shared_addr + + lli_table_alloc_addr = (void *)(sep->shared_addr + SYNCHRONIC_DMA_TABLES_AREA_OFFSET_BYTES + sep->num_lli_tables_created * sizeof(struct sep_lli_entry) * SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP); @@ -1759,7 +1757,7 @@ static int sep_prepare_input_dma_table(struct sep_device *sep, SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP; if (lli_table_alloc_addr > - ((u32)sep->shared_addr + + ((void *)sep->shared_addr + SYNCHRONIC_DMA_TABLES_AREA_OFFSET_BYTES + SYNCHRONIC_DMA_TABLES_AREA_SIZE_BYTES)) { @@ -1874,7 +1872,7 @@ static int sep_construct_dma_tables_from_lli( u32 *table_data_size_ptr) { /* Points to the area where next lli table can be allocated */ - u32 lli_table_alloc_addr = 0; + void *lli_table_alloc_addr = 0; /* Input lli table */ struct sep_lli_entry *in_lli_table_ptr = NULL; /* Output lli table */ @@ -1903,7 +1901,7 @@ static int sep_construct_dma_tables_from_lli( dev_dbg(&sep->pdev->dev, "sep_construct_dma_tables_from_lli start\n"); /* Initiate to point after the message area */ - lli_table_alloc_addr = (u32)(sep->shared_addr + + lli_table_alloc_addr = (void *)(sep->shared_addr + SYNCHRONIC_DMA_TABLES_AREA_OFFSET_BYTES + (sep->num_lli_tables_created * (sizeof(struct sep_lli_entry) * @@ -1925,7 +1923,7 @@ static int sep_construct_dma_tables_from_lli( /* Check if the DMA table area limit was overrun */ if ((lli_table_alloc_addr + sizeof(struct sep_lli_entry) * SEP_DRIVER_ENTRIES_PER_TABLE_IN_SEP) > - ((u32)sep->shared_addr + + ((void *)sep->shared_addr + SYNCHRONIC_DMA_TABLES_AREA_OFFSET_BYTES + SYNCHRONIC_DMA_TABLES_AREA_SIZE_BYTES)) { @@ -2251,13 +2249,13 @@ end_function: * are in 32 bit format; the SEP is a 32 bit device */ static int sep_prepare_input_output_dma_table_in_dcb(struct sep_device *sep, - u32 app_in_address, - u32 app_out_address, - u32 data_in_size, - u32 block_size, - u32 tail_block_size, - bool isapplet, - bool is_kva) + unsigned long app_in_address, + unsigned long app_out_address, + u32 data_in_size, + u32 block_size, + u32 tail_block_size, + bool isapplet, + bool is_kva) { int error = 0; /* Size of tail */ @@ -2366,7 +2364,7 @@ static int sep_prepare_input_output_dma_table_in_dcb(struct sep_device *sep, * according to tail data size */ dcb_table_ptr->out_vr_tail_pt = - app_out_address + data_in_size + (u32)app_out_address + data_in_size - tail_size; /* Save the real tail data size */ @@ -2467,8 +2465,8 @@ static int sep_create_sync_dma_tables_handler(struct sep_device *sep, } error = sep_prepare_input_output_dma_table_in_dcb(sep, - command_args.app_in_address, - command_args.app_out_address, + (unsigned long)command_args.app_in_address, + (unsigned long)command_args.app_out_address, command_args.data_in_size, command_args.block_size, 0x0, @@ -2495,6 +2493,8 @@ static int sep_free_dma_tables_and_dcb(struct sep_device *sep, bool isapplet, int error = 0; int error_temp = 0; struct sep_dcblock *dcb_table_ptr; + unsigned long pt_hold; + void *tail_pt; dev_dbg(&sep->pdev->dev, "sep_free_dma_tables_and_dcb start\n"); @@ -2507,13 +2507,15 @@ static int sep_free_dma_tables_and_dcb(struct sep_device *sep, bool isapplet, /* Go over each DCB and see if tail pointer must be updated */ for (i = 0; i < sep->nr_dcb_creat; i++, dcb_table_ptr++) { if (dcb_table_ptr->out_vr_tail_pt) { + pt_hold = (unsigned long)dcb_table_ptr->out_vr_tail_pt; + tail_pt = (void *)pt_hold; if (is_kva == true) { - memcpy((void *)dcb_table_ptr->out_vr_tail_pt, + memcpy(tail_pt, dcb_table_ptr->tail_data, dcb_table_ptr->tail_data_size); } else { error_temp = copy_to_user( - (void *)dcb_table_ptr->out_vr_tail_pt, + tail_pt, dcb_table_ptr->tail_data, dcb_table_ptr->tail_data_size); } @@ -2841,7 +2843,8 @@ static int sep_prepare_dcb_handler(struct sep_device *sep, unsigned long arg) command_args.tail_block_size); error = sep_prepare_input_output_dma_table_in_dcb(sep, - command_args.app_in_address, command_args.app_out_address, + (unsigned long)command_args.app_in_address, + (unsigned long)command_args.app_out_address, command_args.data_in_size, command_args.block_size, command_args.tail_block_size, true, false); @@ -2971,30 +2974,6 @@ static long sep_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) dev_dbg(&sep->pdev->dev, "ioctl start\n"); dev_dbg(&sep->pdev->dev, "cmd is %x\n", cmd); - dev_dbg(&sep->pdev->dev, - "SEP_IOCSENDSEPCOMMAND is %x\n", SEP_IOCSENDSEPCOMMAND); - dev_dbg(&sep->pdev->dev, - "SEP_IOCALLOCDATAPOLL is %x\n", SEP_IOCALLOCDATAPOLL); - dev_dbg(&sep->pdev->dev, - "SEP_IOCCREATESYMDMATABLE is %x\n", SEP_IOCCREATESYMDMATABLE); - dev_dbg(&sep->pdev->dev, - "SEP_IOCFREEDMATABLEDATA is %x\n", SEP_IOCFREEDMATABLEDATA); - dev_dbg(&sep->pdev->dev, - "SEP_IOCSEPSTART is %x\n", SEP_IOCSEPSTART); - dev_dbg(&sep->pdev->dev, - "SEP_IOCSEPINIT is %x\n", SEP_IOCSEPINIT); - dev_dbg(&sep->pdev->dev, - "SEP_IOCGETSTATICPOOLADDR is %x\n", SEP_IOCGETSTATICPOOLADDR); - dev_dbg(&sep->pdev->dev, - "SEP_IOCENDTRANSACTION is %x\n", SEP_IOCENDTRANSACTION); - dev_dbg(&sep->pdev->dev, - "SEP_IOCREALLOCEXTCACHE is %x\n", SEP_IOCREALLOCEXTCACHE); - dev_dbg(&sep->pdev->dev, - "SEP_IOCRARPREPAREMESSAGE is %x\n", SEP_IOCRARPREPAREMESSAGE); - dev_dbg(&sep->pdev->dev, - "SEP_IOCPREPAREDCB is %x\n", SEP_IOCPREPAREDCB); - dev_dbg(&sep->pdev->dev, - "SEP_IOCFREEDCB is %x\n", SEP_IOCFREEDCB); /* Make sure we own this device */ mutex_lock(&sep->sep_mutex); -- cgit v1.2.3 From 653bf0cfa55896b74d8cbe7e561401813ca359ad Mon Sep 17 00:00:00 2001 From: Mark Allyn Date: Thu, 9 Dec 2010 09:32:38 -0800 Subject: Staging: sep: ensure that caller id buffer is little endian Signed-off-by: Mark Allyn Signed-off-by: Greg Kroah-Hartman --- drivers/staging/sep/sep_driver.c | 8 ++++++++ drivers/staging/sep/sep_driver_config.h | 3 +++ 2 files changed, 11 insertions(+) diff --git a/drivers/staging/sep/sep_driver.c b/drivers/staging/sep/sep_driver.c index 903d6106c0d3..bb42b048f46a 100644 --- a/drivers/staging/sep/sep_driver.c +++ b/drivers/staging/sep/sep_driver.c @@ -897,6 +897,7 @@ end_function: static int sep_set_current_caller_id(struct sep_device *sep) { int i; + u32 *hash_buf_ptr; dev_dbg(&sep->pdev->dev, "sep_set_current_caller_id start\n"); dev_dbg(&sep->pdev->dev, "current process is %d\n", current->pid); @@ -915,6 +916,13 @@ static int sep_set_current_caller_id(struct sep_device *sep) break; } } + /* Ensure data is in little endian */ + hash_buf_ptr = (u32 *)sep->shared_addr + + SEP_CALLER_ID_OFFSET_BYTES; + + for (i = 0; i < SEP_CALLER_ID_HASH_SIZE_IN_WORDS; i++) + hash_buf_ptr[i] = cpu_to_le32(hash_buf_ptr[i]); + dev_dbg(&sep->pdev->dev, "sep_set_current_caller_id end\n"); return 0; } diff --git a/drivers/staging/sep/sep_driver_config.h b/drivers/staging/sep/sep_driver_config.h index 92338c0f6bd2..b18625d2f7f4 100644 --- a/drivers/staging/sep/sep_driver_config.h +++ b/drivers/staging/sep/sep_driver_config.h @@ -201,6 +201,9 @@ held by the proccess (struct file) */ /* size of the caller id hash (sha2) */ #define SEP_CALLER_ID_HASH_SIZE_IN_BYTES 32 +/* size of the caller id hash (sha2) in 32 bit words */ +#define SEP_CALLER_ID_HASH_SIZE_IN_WORDS 8 + /* maximum number of entries in the caller id table */ #define SEP_CALLER_ID_TABLE_NUM_ENTRIES 20 -- cgit v1.2.3 From fd599985e649c71162495d307a2fd1bbddc258e4 Mon Sep 17 00:00:00 2001 From: Mark Allyn Date: Thu, 9 Dec 2010 09:32:53 -0800 Subject: Staging: sep: eliminate kernel crash due to null parameter in dma_alloc_coherent Signed-off-by: Mark Allyn Signed-off-by: Greg Kroah-Hartman --- drivers/staging/sep/sep_driver.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/sep/sep_driver.c b/drivers/staging/sep/sep_driver.c index bb42b048f46a..2681fcf0c34d 100644 --- a/drivers/staging/sep/sep_driver.c +++ b/drivers/staging/sep/sep_driver.c @@ -3442,7 +3442,7 @@ static int __devinit sep_probe(struct pci_dev *pdev, } sep->rar_size = FAKE_RAR_SIZE; - sep->rar_addr = dma_alloc_coherent(NULL, + sep->rar_addr = dma_alloc_coherent(&sep->pdev->dev, sep->rar_size, &sep->rar_bus, GFP_KERNEL); if (sep->rar_addr == NULL) { dev_warn(&sep->pdev->dev, "can't allocate mfld rar\n"); -- cgit v1.2.3 From 88ab8a8445838785e38af378740ab57f8cb6cb8a Mon Sep 17 00:00:00 2001 From: Xenofon Foukas Date: Sat, 4 Dec 2010 00:17:55 +0200 Subject: Staging: comedi: Fix coding style issues in drivers.c This patch fixes line over 80 characters warning issues found in file drivers.c Signed-off-by: Xenofon Foukas Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers.c | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/drivers/staging/comedi/drivers.c b/drivers/staging/comedi/drivers.c index ef24a530278b..dca861ee0466 100644 --- a/drivers/staging/comedi/drivers.c +++ b/drivers/staging/comedi/drivers.c @@ -117,8 +117,7 @@ int comedi_device_attach(struct comedi_device *dev, struct comedi_devconfig *it) for (driv = comedi_drivers; driv; driv = driv->next) { if (!try_module_get(driv->module)) { - printk - (KERN_INFO "comedi: failed to increment module count, skipping\n"); + printk(KERN_INFO "comedi: failed to increment module count, skipping\n"); continue; } if (driv->num_names) { @@ -205,9 +204,8 @@ int comedi_driver_unregister(struct comedi_driver *driver) mutex_lock(&dev->mutex); if (dev->attached && dev->driver == driver) { if (dev->use_count) - printk - (KERN_WARNING "BUG! detaching device with use_count=%d\n", - dev->use_count); + printk(KERN_WARNING "BUG! detaching device with use_count=%d\n", + dev->use_count); comedi_device_detach(dev); } mutex_unlock(&dev->mutex); @@ -442,7 +440,9 @@ int comedi_buf_alloc(struct comedi_device *dev, struct comedi_subdevice *s, unsigned i; for (i = 0; i < async->n_buf_pages; ++i) { if (async->buf_page_list[i].virt_addr) { - clear_bit(PG_reserved, &(virt_to_page(async->buf_page_list[i].virt_addr)->flags)); + clear_bit(PG_reserved, + &(virt_to_page(async->buf_page_list[i]. + virt_addr)->flags)); if (s->async_dma_dir != DMA_NONE) { dma_free_coherent(dev->hw_dev, PAGE_SIZE, @@ -494,8 +494,10 @@ int comedi_buf_alloc(struct comedi_device *dev, struct comedi_subdevice *s, break; set_bit(PG_reserved, - &(virt_to_page(async->buf_page_list[i].virt_addr)->flags)); - pages[i] = virt_to_page(async->buf_page_list[i].virt_addr); + &(virt_to_page(async->buf_page_list[i]. + virt_addr)->flags)); + pages[i] = virt_to_page(async->buf_page_list[i]. + virt_addr); } } if (i == n_pages) { @@ -512,7 +514,10 @@ int comedi_buf_alloc(struct comedi_device *dev, struct comedi_subdevice *s, NULL) { break; } - clear_bit(PG_reserved, &(virt_to_page(async->buf_page_list[i].virt_addr)->flags)); + clear_bit(PG_reserved, + &(virt_to_page(async-> + buf_page_list[i]. + virt_addr)->flags)); if (s->async_dma_dir != DMA_NONE) { dma_free_coherent(dev->hw_dev, PAGE_SIZE, @@ -644,8 +649,7 @@ unsigned comedi_buf_write_free(struct comedi_async *async, unsigned int nbytes) { if ((int)(async->buf_write_count + nbytes - async->buf_write_alloc_count) > 0) { - printk - (KERN_INFO "comedi: attempted to write-free more bytes than have been write-allocated.\n"); + printk(KERN_INFO "comedi: attempted to write-free more bytes than have been write-allocated.\n"); nbytes = async->buf_write_alloc_count - async->buf_write_count; } async->buf_write_count += nbytes; -- cgit v1.2.3 From 5144c534d16529bc469396211131e8935589f833 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Fri, 10 Dec 2010 17:34:26 +0800 Subject: ALSA: aoa: Remove wrong i2c_set_clientdata in onyx_i2c_remove() It does not make sense to set clientdata to onyx in onyx_i2c_remove() as we are going to kfree onyx. What we really want here is i2c_set_clientdata(client, NULL); Since the i2c core will take care of it now, so this patch just removes it. Signed-off-by: Axel Lin Signed-off-by: Takashi Iwai --- sound/aoa/codecs/onyx.c | 1 - 1 file changed, 1 deletion(-) diff --git a/sound/aoa/codecs/onyx.c b/sound/aoa/codecs/onyx.c index 91852e49910e..3687a6cc9881 100644 --- a/sound/aoa/codecs/onyx.c +++ b/sound/aoa/codecs/onyx.c @@ -1114,7 +1114,6 @@ static int onyx_i2c_remove(struct i2c_client *client) of_node_put(onyx->codec.node); if (onyx->codec_info) kfree(onyx->codec_info); - i2c_set_clientdata(client, onyx); kfree(onyx); return 0; } -- cgit v1.2.3 From dac36dd87de10d1fd81dc7b7a40256cb2e965abc Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Fri, 10 Dec 2010 01:57:07 +0900 Subject: poll: fix a typo in comment Convert duplicated sys_poll to select. As Kosaki suggests, sys_poll() and sys_select() are now hidden by SYSCALL_DEFINEx() macros so it would be better to use plain select/poll syscall name. Signed-off-by: Namhyung Kim Reviewed-by: KOSAKI Motohiro Signed-off-by: Jiri Kosina --- include/linux/poll.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/poll.h b/include/linux/poll.h index 56e76af78102..1a2ccd6f3823 100644 --- a/include/linux/poll.h +++ b/include/linux/poll.h @@ -57,7 +57,7 @@ struct poll_table_entry { }; /* - * Structures and helpers for sys_poll/sys_poll + * Structures and helpers for select/poll syscall */ struct poll_wqueues { poll_table pt; -- cgit v1.2.3 From 4291ee305e9bb0699504a66f0e2b7aefcf0512a5 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Thu, 9 Dec 2010 19:29:03 -0800 Subject: HID: Add and use hid_: dev_ equivalents Neaten current uses of dev_ by adding and using hid specific hid_ macros. Convert existing uses of dev_ uses to hid_. Convert hid-pidff printk uses to hid_. Remove err_hid and use hid_err instead. Add missing newlines to logging messages where necessary. Coalesce format strings. Add and use pr_fmt(fmt) KBUILD_MODNAME ": " fmt Other miscellaneous changes: Add const struct hid_device * argument to hid-core functions extract() and implement() so hid_ can be used by them. Fix bad indentation in hid-core hid_input_field function that calls extract() function above. Signed-off-by: Joe Perches Signed-off-by: Jiri Kosina --- drivers/hid/hid-3m-pct.c | 2 +- drivers/hid/hid-a4tech.c | 6 +- drivers/hid/hid-apple.c | 14 ++-- drivers/hid/hid-axff.c | 14 ++-- drivers/hid/hid-belkin.c | 4 +- drivers/hid/hid-cando.c | 2 +- drivers/hid/hid-cherry.c | 3 +- drivers/hid/hid-core.c | 64 +++++++++------- drivers/hid/hid-cypress.c | 4 +- drivers/hid/hid-debug.c | 4 +- drivers/hid/hid-drff.c | 14 ++-- drivers/hid/hid-egalax.c | 2 +- drivers/hid/hid-elecom.c | 3 +- drivers/hid/hid-emsff.c | 13 ++-- drivers/hid/hid-gaff.c | 13 ++-- drivers/hid/hid-input.c | 2 +- drivers/hid/hid-kye.c | 4 +- drivers/hid/hid-lg.c | 15 ++-- drivers/hid/hid-lg2ff.c | 9 +-- drivers/hid/hid-lg3ff.c | 9 +-- drivers/hid/hid-lg4ff.c | 9 +-- drivers/hid/hid-lgff.c | 8 +- drivers/hid/hid-magicmouse.c | 15 ++-- drivers/hid/hid-microsoft.c | 7 +- drivers/hid/hid-monterey.c | 3 +- drivers/hid/hid-mosart.c | 2 +- drivers/hid/hid-ntrig.c | 9 +-- drivers/hid/hid-ortek.c | 3 +- drivers/hid/hid-petalynx.c | 7 +- drivers/hid/hid-picolcd.c | 45 ++++++----- drivers/hid/hid-pl.c | 16 ++-- drivers/hid/hid-prodikeys.c | 21 +++--- drivers/hid/hid-quanta.c | 2 +- drivers/hid/hid-roccat-kone.c | 22 +++--- drivers/hid/hid-roccat-pyra.c | 20 +++-- drivers/hid/hid-roccat.c | 10 +-- drivers/hid/hid-samsung.c | 8 +- drivers/hid/hid-sjoy.c | 16 ++-- drivers/hid/hid-sony.c | 11 ++- drivers/hid/hid-stantum.c | 2 +- drivers/hid/hid-sunplus.c | 3 +- drivers/hid/hid-tmff.c | 27 +++---- drivers/hid/hid-wacom.c | 26 ++++--- drivers/hid/hid-zpff.c | 11 ++- drivers/hid/hid-zydacron.c | 11 ++- drivers/hid/hidraw.c | 12 +-- drivers/hid/usbhid/hid-core.c | 48 ++++++------ drivers/hid/usbhid/hid-pidff.c | 164 +++++++++++++++++++---------------------- drivers/hid/usbhid/hiddev.c | 2 +- drivers/hid/usbhid/usbkbd.c | 24 +++--- include/linux/hid.h | 32 ++++++-- 51 files changed, 398 insertions(+), 399 deletions(-) diff --git a/drivers/hid/hid-3m-pct.c b/drivers/hid/hid-3m-pct.c index 02d8cd3b1b1b..4546c123eb77 100644 --- a/drivers/hid/hid-3m-pct.c +++ b/drivers/hid/hid-3m-pct.c @@ -274,7 +274,7 @@ static int mmm_probe(struct hid_device *hdev, const struct hid_device_id *id) md = kzalloc(sizeof(struct mmm_data), GFP_KERNEL); if (!md) { - dev_err(&hdev->dev, "cannot allocate 3M data\n"); + hid_err(hdev, "cannot allocate 3M data\n"); return -ENOMEM; } hid_set_drvdata(hdev, md); diff --git a/drivers/hid/hid-a4tech.c b/drivers/hid/hid-a4tech.c index 1666c1684e79..902d1dfeb1b5 100644 --- a/drivers/hid/hid-a4tech.c +++ b/drivers/hid/hid-a4tech.c @@ -93,7 +93,7 @@ static int a4_probe(struct hid_device *hdev, const struct hid_device_id *id) a4 = kzalloc(sizeof(*a4), GFP_KERNEL); if (a4 == NULL) { - dev_err(&hdev->dev, "can't alloc device descriptor\n"); + hid_err(hdev, "can't alloc device descriptor\n"); ret = -ENOMEM; goto err_free; } @@ -104,13 +104,13 @@ static int a4_probe(struct hid_device *hdev, const struct hid_device_id *id) ret = hid_parse(hdev); if (ret) { - dev_err(&hdev->dev, "parse failed\n"); + hid_err(hdev, "parse failed\n"); goto err_free; } ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); if (ret) { - dev_err(&hdev->dev, "hw start failed\n"); + hid_err(hdev, "hw start failed\n"); goto err_free; } diff --git a/drivers/hid/hid-apple.c b/drivers/hid/hid-apple.c index 8aa71750a23c..61aa71233392 100644 --- a/drivers/hid/hid-apple.c +++ b/drivers/hid/hid-apple.c @@ -16,6 +16,8 @@ * any later version. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -280,8 +282,8 @@ static __u8 *apple_report_fixup(struct hid_device *hdev, __u8 *rdesc, if ((asc->quirks & APPLE_RDESC_JIS) && *rsize >= 60 && rdesc[53] == 0x65 && rdesc[59] == 0x65) { - dev_info(&hdev->dev, "fixing up MacBook JIS keyboard report " - "descriptor\n"); + hid_info(hdev, + "fixing up MacBook JIS keyboard report descriptor\n"); rdesc[53] = rdesc[59] = 0xe7; } return rdesc; @@ -351,7 +353,7 @@ static int apple_probe(struct hid_device *hdev, asc = kzalloc(sizeof(*asc), GFP_KERNEL); if (asc == NULL) { - dev_err(&hdev->dev, "can't alloc apple descriptor\n"); + hid_err(hdev, "can't alloc apple descriptor\n"); return -ENOMEM; } @@ -361,7 +363,7 @@ static int apple_probe(struct hid_device *hdev, ret = hid_parse(hdev); if (ret) { - dev_err(&hdev->dev, "parse failed\n"); + hid_err(hdev, "parse failed\n"); goto err_free; } @@ -372,7 +374,7 @@ static int apple_probe(struct hid_device *hdev, ret = hid_hw_start(hdev, connect_mask); if (ret) { - dev_err(&hdev->dev, "hw start failed\n"); + hid_err(hdev, "hw start failed\n"); goto err_free; } @@ -512,7 +514,7 @@ static int __init apple_init(void) ret = hid_register_driver(&apple_driver); if (ret) - printk(KERN_ERR "can't register apple driver\n"); + pr_err("can't register apple driver\n"); return ret; } diff --git a/drivers/hid/hid-axff.c b/drivers/hid/hid-axff.c index f42ee140738a..e5b961d6ff22 100644 --- a/drivers/hid/hid-axff.c +++ b/drivers/hid/hid-axff.c @@ -73,14 +73,14 @@ static int axff_init(struct hid_device *hid) int error; if (list_empty(report_list)) { - dev_err(&hid->dev, "no output reports found\n"); + hid_err(hid, "no output reports found\n"); return -ENODEV; } report = list_first_entry(report_list, struct hid_report, list); if (report->maxfield < 4) { - dev_err(&hid->dev, "no fields in the report: %d\n", report->maxfield); + hid_err(hid, "no fields in the report: %d\n", report->maxfield); return -ENODEV; } @@ -101,7 +101,7 @@ static int axff_init(struct hid_device *hid) axff->report->field[3]->value[0] = 0x00; usbhid_submit_report(hid, axff->report, USB_DIR_OUT); - dev_info(&hid->dev, "Force Feedback for ACRUX game controllers by Sergei Kolzun\n"); + hid_info(hid, "Force Feedback for ACRUX game controllers by Sergei Kolzun\n"); return 0; @@ -114,17 +114,17 @@ static int ax_probe(struct hid_device *hdev, const struct hid_device_id *id) { int error; - dev_dbg(&hdev->dev, "ACRUX HID hardware probe..."); + dev_dbg(&hdev->dev, "ACRUX HID hardware probe...\n"); error = hid_parse(hdev); if (error) { - dev_err(&hdev->dev, "parse failed\n"); + hid_err(hdev, "parse failed\n"); return error; } error = hid_hw_start(hdev, HID_CONNECT_DEFAULT & ~HID_CONNECT_FF); if (error) { - dev_err(&hdev->dev, "hw start failed\n"); + hid_err(hdev, "hw start failed\n"); return error; } @@ -134,7 +134,7 @@ static int ax_probe(struct hid_device *hdev, const struct hid_device_id *id) * Do not fail device initialization completely as device * may still be partially operable, just warn. */ - dev_warn(&hdev->dev, + hid_warn(hdev, "Failed to enable force feedback support, error: %d\n", error); } diff --git a/drivers/hid/hid-belkin.c b/drivers/hid/hid-belkin.c index 4ce7aa3a519f..a1a765a5b08a 100644 --- a/drivers/hid/hid-belkin.c +++ b/drivers/hid/hid-belkin.c @@ -56,14 +56,14 @@ static int belkin_probe(struct hid_device *hdev, const struct hid_device_id *id) ret = hid_parse(hdev); if (ret) { - dev_err(&hdev->dev, "parse failed\n"); + hid_err(hdev, "parse failed\n"); goto err_free; } ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT | ((quirks & BELKIN_HIDDEV) ? HID_CONNECT_HIDDEV_FORCE : 0)); if (ret) { - dev_err(&hdev->dev, "hw start failed\n"); + hid_err(hdev, "hw start failed\n"); goto err_free; } diff --git a/drivers/hid/hid-cando.c b/drivers/hid/hid-cando.c index 5925bdcd417d..375b50929a50 100644 --- a/drivers/hid/hid-cando.c +++ b/drivers/hid/hid-cando.c @@ -207,7 +207,7 @@ static int cando_probe(struct hid_device *hdev, const struct hid_device_id *id) td = kmalloc(sizeof(struct cando_data), GFP_KERNEL); if (!td) { - dev_err(&hdev->dev, "cannot allocate Cando Touch data\n"); + hid_err(hdev, "cannot allocate Cando Touch data\n"); return -ENOMEM; } hid_set_drvdata(hdev, td); diff --git a/drivers/hid/hid-cherry.c b/drivers/hid/hid-cherry.c index e880086c2311..888ece68a47c 100644 --- a/drivers/hid/hid-cherry.c +++ b/drivers/hid/hid-cherry.c @@ -30,8 +30,7 @@ static __u8 *ch_report_fixup(struct hid_device *hdev, __u8 *rdesc, unsigned int *rsize) { if (*rsize >= 17 && rdesc[11] == 0x3c && rdesc[12] == 0x02) { - dev_info(&hdev->dev, "fixing up Cherry Cymotion report " - "descriptor\n"); + hid_info(hdev, "fixing up Cherry Cymotion report descriptor\n"); rdesc[11] = rdesc[16] = 0xff; rdesc[12] = rdesc[17] = 0x03; } diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 396f8c7e0076..1fd5e331fa8d 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -14,6 +14,8 @@ * any later version. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -672,7 +674,8 @@ int hid_parse_report(struct hid_device *device, __u8 *start, if (dispatch_type[item.type](parser, &item)) { dbg_hid("item %u %u %u %u parsing failed\n", - item.format, (unsigned)item.size, (unsigned)item.type, (unsigned)item.tag); + item.format, (unsigned)item.size, + (unsigned)item.type, (unsigned)item.tag); goto err; } @@ -737,13 +740,14 @@ static u32 s32ton(__s32 value, unsigned n) * Search linux-kernel and linux-usb-devel archives for "hid-core extract". */ -static __inline__ __u32 extract(__u8 *report, unsigned offset, unsigned n) +static __inline__ __u32 extract(const struct hid_device *hid, __u8 *report, + unsigned offset, unsigned n) { u64 x; if (n > 32) - printk(KERN_WARNING "HID: extract() called with n (%d) > 32! (%s)\n", - n, current->comm); + hid_warn(hid, "extract() called with n (%d) > 32! (%s)\n", + n, current->comm); report += offset >> 3; /* adjust byte index */ offset &= 7; /* now only need bit offset into one byte */ @@ -760,18 +764,19 @@ static __inline__ __u32 extract(__u8 *report, unsigned offset, unsigned n) * endianness of register values by considering a register * a "cached" copy of the little endiad bit stream. */ -static __inline__ void implement(__u8 *report, unsigned offset, unsigned n, __u32 value) +static __inline__ void implement(const struct hid_device *hid, __u8 *report, + unsigned offset, unsigned n, __u32 value) { u64 x; u64 m = (1ULL << n) - 1; if (n > 32) - printk(KERN_WARNING "HID: implement() called with n (%d) > 32! (%s)\n", - n, current->comm); + hid_warn(hid, "%s() called with n (%d) > 32! (%s)\n", + __func__, n, current->comm); if (value > m) - printk(KERN_WARNING "HID: implement() called with too large value %d! (%s)\n", - value, current->comm); + hid_warn(hid, "%s() called with too large value %d! (%s)\n", + __func__, value, current->comm); WARN_ON(value > m); value &= m; @@ -892,13 +897,16 @@ static void hid_input_field(struct hid_device *hid, struct hid_field *field, for (n = 0; n < count; n++) { - value[n] = min < 0 ? snto32(extract(data, offset + n * size, size), size) : - extract(data, offset + n * size, size); + value[n] = min < 0 ? + snto32(extract(hid, data, offset + n * size, size), + size) : + extract(hid, data, offset + n * size, size); - if (!(field->flags & HID_MAIN_ITEM_VARIABLE) /* Ignore report if ErrorRollOver */ - && value[n] >= min && value[n] <= max - && field->usage[value[n] - min].hid == HID_UP_KEYBOARD + 1) - goto exit; + /* Ignore report if ErrorRollOver */ + if (!(field->flags & HID_MAIN_ITEM_VARIABLE) && + value[n] >= min && value[n] <= max && + field->usage[value[n] - min].hid == HID_UP_KEYBOARD + 1) + goto exit; } for (n = 0; n < count; n++) { @@ -928,7 +936,8 @@ exit: * Output the field into the report. */ -static void hid_output_field(struct hid_field *field, __u8 *data) +static void hid_output_field(const struct hid_device *hid, + struct hid_field *field, __u8 *data) { unsigned count = field->report_count; unsigned offset = field->report_offset; @@ -937,9 +946,11 @@ static void hid_output_field(struct hid_field *field, __u8 *data) for (n = 0; n < count; n++) { if (field->logical_minimum < 0) /* signed values */ - implement(data, offset + n * size, size, s32ton(field->value[n], size)); + implement(hid, data, offset + n * size, size, + s32ton(field->value[n], size)); else /* unsigned values */ - implement(data, offset + n * size, size, field->value[n]); + implement(hid, data, offset + n * size, size, + field->value[n]); } } @@ -956,7 +967,7 @@ void hid_output_report(struct hid_report *report, __u8 *data) memset(data, 0, ((report->size - 1) >> 3) + 1); for (n = 0; n < report->maxfield; n++) - hid_output_field(report->field[n], data); + hid_output_field(report->device, report->field[n], data); } EXPORT_SYMBOL_GPL(hid_output_report); @@ -1169,8 +1180,7 @@ int hid_connect(struct hid_device *hdev, unsigned int connect_mask) hdev->claimed |= HID_CLAIMED_HIDRAW; if (!hdev->claimed) { - dev_err(&hdev->dev, "claimed by neither input, hiddev nor " - "hidraw\n"); + hid_err(hdev, "claimed by neither input, hiddev nor hidraw\n"); return -ENODEV; } @@ -1210,9 +1220,9 @@ int hid_connect(struct hid_device *hdev, unsigned int connect_mask) bus = ""; } - dev_info(&hdev->dev, "%s: %s HID v%x.%02x %s [%s] on %s\n", - buf, bus, hdev->version >> 8, hdev->version & 0xff, - type, hdev->name, hdev->phys); + hid_info(hdev, "%s: %s HID v%x.%02x %s [%s] on %s\n", + buf, bus, hdev->version >> 8, hdev->version & 0xff, + type, hdev->name, hdev->phys); return 0; } @@ -1956,12 +1966,12 @@ static int __init hid_init(void) int ret; if (hid_debug) - printk(KERN_WARNING "HID: hid_debug is now used solely for parser and driver debugging.\n" - "HID: debugfs is now used for inspecting the device (report descriptor, reports)\n"); + pr_warn("hid_debug is now used solely for parser and driver debugging.\n" + "debugfs is now used for inspecting the device (report descriptor, reports)\n"); ret = bus_register(&hid_bus_type); if (ret) { - printk(KERN_ERR "HID: can't register hid bus\n"); + pr_err("can't register hid bus\n"); goto err; } diff --git a/drivers/hid/hid-cypress.c b/drivers/hid/hid-cypress.c index 4cd0e2345991..2f0be4c66af7 100644 --- a/drivers/hid/hid-cypress.c +++ b/drivers/hid/hid-cypress.c @@ -107,13 +107,13 @@ static int cp_probe(struct hid_device *hdev, const struct hid_device_id *id) ret = hid_parse(hdev); if (ret) { - dev_err(&hdev->dev, "parse failed\n"); + hid_err(hdev, "parse failed\n"); goto err_free; } ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); if (ret) { - dev_err(&hdev->dev, "hw start failed\n"); + hid_err(hdev, "hw start failed\n"); goto err_free; } diff --git a/drivers/hid/hid-debug.c b/drivers/hid/hid-debug.c index 75c5e23d09d2..555382fc7417 100644 --- a/drivers/hid/hid-debug.c +++ b/drivers/hid/hid-debug.c @@ -26,6 +26,8 @@ * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -393,7 +395,7 @@ char *hid_resolv_usage(unsigned usage, struct seq_file *f) { buf = resolv_usage_page(usage >> 16, f); if (IS_ERR(buf)) { - printk(KERN_ERR "error allocating HID debug buffer\n"); + pr_err("error allocating HID debug buffer\n"); return NULL; } diff --git a/drivers/hid/hid-drff.c b/drivers/hid/hid-drff.c index 968b04f9b796..afcf3d67eb02 100644 --- a/drivers/hid/hid-drff.c +++ b/drivers/hid/hid-drff.c @@ -96,18 +96,18 @@ static int drff_init(struct hid_device *hid) int error; if (list_empty(report_list)) { - dev_err(&hid->dev, "no output reports found\n"); + hid_err(hid, "no output reports found\n"); return -ENODEV; } report = list_first_entry(report_list, struct hid_report, list); if (report->maxfield < 1) { - dev_err(&hid->dev, "no fields in the report\n"); + hid_err(hid, "no fields in the report\n"); return -ENODEV; } if (report->field[0]->report_count < 7) { - dev_err(&hid->dev, "not enough values in the field\n"); + hid_err(hid, "not enough values in the field\n"); return -ENODEV; } @@ -133,8 +133,8 @@ static int drff_init(struct hid_device *hid) drff->report->field[0]->value[6] = 0x00; usbhid_submit_report(hid, drff->report, USB_DIR_OUT); - dev_info(&hid->dev, "Force Feedback for DragonRise Inc. game " - "controllers by Richard Walmsley \n"); + hid_info(hid, "Force Feedback for DragonRise Inc. " + "game controllers by Richard Walmsley \n"); return 0; } @@ -153,13 +153,13 @@ static int dr_probe(struct hid_device *hdev, const struct hid_device_id *id) ret = hid_parse(hdev); if (ret) { - dev_err(&hdev->dev, "parse failed\n"); + hid_err(hdev, "parse failed\n"); goto err; } ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT & ~HID_CONNECT_FF); if (ret) { - dev_err(&hdev->dev, "hw start failed\n"); + hid_err(hdev, "hw start failed\n"); goto err; } diff --git a/drivers/hid/hid-egalax.c b/drivers/hid/hid-egalax.c index 54b017ad258d..bbab6cff3518 100644 --- a/drivers/hid/hid-egalax.c +++ b/drivers/hid/hid-egalax.c @@ -223,7 +223,7 @@ static int egalax_probe(struct hid_device *hdev, const struct hid_device_id *id) td = kmalloc(sizeof(struct egalax_data), GFP_KERNEL); if (!td) { - dev_err(&hdev->dev, "cannot allocate eGalax data\n"); + hid_err(hdev, "cannot allocate eGalax data\n"); return -ENOMEM; } hid_set_drvdata(hdev, td); diff --git a/drivers/hid/hid-elecom.c b/drivers/hid/hid-elecom.c index 6e31f305397d..79d0c61e7214 100644 --- a/drivers/hid/hid-elecom.c +++ b/drivers/hid/hid-elecom.c @@ -24,8 +24,7 @@ static __u8 *elecom_report_fixup(struct hid_device *hdev, __u8 *rdesc, unsigned int *rsize) { if (*rsize >= 48 && rdesc[46] == 0x05 && rdesc[47] == 0x0c) { - dev_info(&hdev->dev, "Fixing up Elecom BM084 " - "report descriptor.\n"); + hid_info(hdev, "Fixing up Elecom BM084 report descriptor\n"); rdesc[47] = 0x00; } return rdesc; diff --git a/drivers/hid/hid-emsff.c b/drivers/hid/hid-emsff.c index c61b192d7cff..81877c67caea 100644 --- a/drivers/hid/hid-emsff.c +++ b/drivers/hid/hid-emsff.c @@ -68,18 +68,18 @@ static int emsff_init(struct hid_device *hid) int error; if (list_empty(report_list)) { - dev_err(&hid->dev, "no output reports found\n"); + hid_err(hid, "no output reports found\n"); return -ENODEV; } report = list_first_entry(report_list, struct hid_report, list); if (report->maxfield < 1) { - dev_err(&hid->dev, "no fields in the report\n"); + hid_err(hid, "no fields in the report\n"); return -ENODEV; } if (report->field[0]->report_count < 7) { - dev_err(&hid->dev, "not enough values in the field\n"); + hid_err(hid, "not enough values in the field\n"); return -ENODEV; } @@ -105,8 +105,7 @@ static int emsff_init(struct hid_device *hid) emsff->report->field[0]->value[6] = 0x00; usbhid_submit_report(hid, emsff->report, USB_DIR_OUT); - dev_info(&hid->dev, "force feedback for EMS based devices by " - "Ignaz Forster \n"); + hid_info(hid, "force feedback for EMS based devices by Ignaz Forster \n"); return 0; } @@ -117,13 +116,13 @@ static int ems_probe(struct hid_device *hdev, const struct hid_device_id *id) ret = hid_parse(hdev); if (ret) { - dev_err(&hdev->dev, "parse failed\n"); + hid_err(hdev, "parse failed\n"); goto err; } ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT & ~HID_CONNECT_FF); if (ret) { - dev_err(&hdev->dev, "hw start failed\n"); + hid_err(hdev, "hw start failed\n"); goto err; } diff --git a/drivers/hid/hid-gaff.c b/drivers/hid/hid-gaff.c index 88dfcf49a5d7..279ba530003c 100644 --- a/drivers/hid/hid-gaff.c +++ b/drivers/hid/hid-gaff.c @@ -87,7 +87,7 @@ static int gaff_init(struct hid_device *hid) int error; if (list_empty(report_list)) { - dev_err(&hid->dev, "no output reports found\n"); + hid_err(hid, "no output reports found\n"); return -ENODEV; } @@ -95,12 +95,12 @@ static int gaff_init(struct hid_device *hid) report = list_entry(report_ptr, struct hid_report, list); if (report->maxfield < 1) { - dev_err(&hid->dev, "no fields in the report\n"); + hid_err(hid, "no fields in the report\n"); return -ENODEV; } if (report->field[0]->report_count < 6) { - dev_err(&hid->dev, "not enough values in the field\n"); + hid_err(hid, "not enough values in the field\n"); return -ENODEV; } @@ -128,8 +128,7 @@ static int gaff_init(struct hid_device *hid) usbhid_submit_report(hid, gaff->report, USB_DIR_OUT); - dev_info(&hid->dev, "Force Feedback for GreenAsia 0x12" - " devices by Lukasz Lubojanski \n"); + hid_info(hid, "Force Feedback for GreenAsia 0x12 devices by Lukasz Lubojanski \n"); return 0; } @@ -148,13 +147,13 @@ static int ga_probe(struct hid_device *hdev, const struct hid_device_id *id) ret = hid_parse(hdev); if (ret) { - dev_err(&hdev->dev, "parse failed\n"); + hid_err(hdev, "parse failed\n"); goto err; } ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT & ~HID_CONNECT_FF); if (ret) { - dev_err(&hdev->dev, "hw start failed\n"); + hid_err(hdev, "hw start failed\n"); goto err; } diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index b718f7144ce1..a1a2206714fc 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c @@ -826,7 +826,7 @@ int hidinput_connect(struct hid_device *hid, unsigned int force) if (!hidinput || !input_dev) { kfree(hidinput); input_free_device(input_dev); - err_hid("Out of memory during hid input probe"); + hid_err(hid, "Out of memory during hid input probe\n"); goto out_unwind; } diff --git a/drivers/hid/hid-kye.c b/drivers/hid/hid-kye.c index 817247ee006c..f2ba9efc3a53 100644 --- a/drivers/hid/hid-kye.c +++ b/drivers/hid/hid-kye.c @@ -32,8 +32,8 @@ static __u8 *kye_report_fixup(struct hid_device *hdev, __u8 *rdesc, rdesc[65] == 0x29 && rdesc[66] == 0x0f && rdesc[71] == 0x75 && rdesc[72] == 0x08 && rdesc[73] == 0x95 && rdesc[74] == 0x01) { - dev_info(&hdev->dev, "fixing up Kye/Genius Ergo Mouse report " - "descriptor\n"); + hid_info(hdev, + "fixing up Kye/Genius Ergo Mouse report descriptor\n"); rdesc[62] = 0x09; rdesc[64] = 0x04; rdesc[66] = 0x07; diff --git a/drivers/hid/hid-lg.c b/drivers/hid/hid-lg.c index b629fba5a057..aef4104da141 100644 --- a/drivers/hid/hid-lg.c +++ b/drivers/hid/hid-lg.c @@ -53,23 +53,22 @@ static __u8 *lg_report_fixup(struct hid_device *hdev, __u8 *rdesc, if ((quirks & LG_RDESC) && *rsize >= 90 && rdesc[83] == 0x26 && rdesc[84] == 0x8c && rdesc[85] == 0x02) { - dev_info(&hdev->dev, "fixing up Logitech keyboard report " - "descriptor\n"); + hid_info(hdev, + "fixing up Logitech keyboard report descriptor\n"); rdesc[84] = rdesc[89] = 0x4d; rdesc[85] = rdesc[90] = 0x10; } if ((quirks & LG_RDESC_REL_ABS) && *rsize >= 50 && rdesc[32] == 0x81 && rdesc[33] == 0x06 && rdesc[49] == 0x81 && rdesc[50] == 0x06) { - dev_info(&hdev->dev, "fixing up rel/abs in Logitech " - "report descriptor\n"); + hid_info(hdev, + "fixing up rel/abs in Logitech report descriptor\n"); rdesc[33] = rdesc[50] = 0x02; } if ((quirks & LG_FF4) && *rsize >= 101 && rdesc[41] == 0x95 && rdesc[42] == 0x0B && rdesc[47] == 0x05 && rdesc[48] == 0x09) { - dev_info(&hdev->dev, "fixing up Logitech Speed Force Wireless " - "button descriptor\n"); + hid_info(hdev, "fixing up Logitech Speed Force Wireless button descriptor\n"); rdesc[41] = 0x05; rdesc[42] = 0x09; rdesc[47] = 0x95; @@ -288,7 +287,7 @@ static int lg_probe(struct hid_device *hdev, const struct hid_device_id *id) ret = hid_parse(hdev); if (ret) { - dev_err(&hdev->dev, "parse failed\n"); + hid_err(hdev, "parse failed\n"); goto err_free; } @@ -297,7 +296,7 @@ static int lg_probe(struct hid_device *hdev, const struct hid_device_id *id) ret = hid_hw_start(hdev, connect_mask); if (ret) { - dev_err(&hdev->dev, "hw start failed\n"); + hid_err(hdev, "hw start failed\n"); goto err_free; } diff --git a/drivers/hid/hid-lg2ff.c b/drivers/hid/hid-lg2ff.c index 4258253c36b3..3c31bc650e5d 100644 --- a/drivers/hid/hid-lg2ff.c +++ b/drivers/hid/hid-lg2ff.c @@ -72,18 +72,18 @@ int lg2ff_init(struct hid_device *hid) int error; if (list_empty(report_list)) { - dev_err(&hid->dev, "no output report found\n"); + hid_err(hid, "no output report found\n"); return -ENODEV; } report = list_entry(report_list->next, struct hid_report, list); if (report->maxfield < 1) { - dev_err(&hid->dev, "output report is empty\n"); + hid_err(hid, "output report is empty\n"); return -ENODEV; } if (report->field[0]->report_count < 7) { - dev_err(&hid->dev, "not enough values in the field\n"); + hid_err(hid, "not enough values in the field\n"); return -ENODEV; } @@ -110,8 +110,7 @@ int lg2ff_init(struct hid_device *hid) usbhid_submit_report(hid, report, USB_DIR_OUT); - dev_info(&hid->dev, "Force feedback for Logitech RumblePad/Rumblepad 2 by " - "Anssi Hannula \n"); + hid_info(hid, "Force feedback for Logitech RumblePad/Rumblepad 2 by Anssi Hannula \n"); return 0; } diff --git a/drivers/hid/hid-lg3ff.c b/drivers/hid/hid-lg3ff.c index 4002832ee4af..f98644c26c1d 100644 --- a/drivers/hid/hid-lg3ff.c +++ b/drivers/hid/hid-lg3ff.c @@ -141,20 +141,20 @@ int lg3ff_init(struct hid_device *hid) /* Find the report to use */ if (list_empty(report_list)) { - err_hid("No output report found"); + hid_err(hid, "No output report found\n"); return -1; } /* Check that the report looks ok */ report = list_entry(report_list->next, struct hid_report, list); if (!report) { - err_hid("NULL output report"); + hid_err(hid, "NULL output report\n"); return -1; } field = report->field[0]; if (!field) { - err_hid("NULL field"); + hid_err(hid, "NULL field\n"); return -1; } @@ -169,8 +169,7 @@ int lg3ff_init(struct hid_device *hid) if (test_bit(FF_AUTOCENTER, dev->ffbit)) dev->ff->set_autocenter = hid_lg3ff_set_autocenter; - dev_info(&hid->dev, "Force feedback for Logitech Flight System G940 by " - "Gary Stein \n"); + hid_info(hid, "Force feedback for Logitech Flight System G940 by Gary Stein \n"); return 0; } diff --git a/drivers/hid/hid-lg4ff.c b/drivers/hid/hid-lg4ff.c index 7eef5a2ce948..fa550c8e1d1b 100644 --- a/drivers/hid/hid-lg4ff.c +++ b/drivers/hid/hid-lg4ff.c @@ -101,20 +101,20 @@ int lg4ff_init(struct hid_device *hid) /* Find the report to use */ if (list_empty(report_list)) { - err_hid("No output report found"); + hid_err(hid, "No output report found\n"); return -1; } /* Check that the report looks ok */ report = list_entry(report_list->next, struct hid_report, list); if (!report) { - err_hid("NULL output report"); + hid_err(hid, "NULL output report\n"); return -1; } field = report->field[0]; if (!field) { - err_hid("NULL field"); + hid_err(hid, "NULL field\n"); return -1; } @@ -129,8 +129,7 @@ int lg4ff_init(struct hid_device *hid) if (test_bit(FF_AUTOCENTER, dev->ffbit)) dev->ff->set_autocenter = hid_lg4ff_set_autocenter; - dev_info(&hid->dev, "Force feedback for Logitech Speed Force Wireless by " - "Simon Wood \n"); + hid_info(hid, "Force feedback for Logitech Speed Force Wireless by Simon Wood \n"); return 0; } diff --git a/drivers/hid/hid-lgff.c b/drivers/hid/hid-lgff.c index 61142b76a9b1..90d0ef2c92be 100644 --- a/drivers/hid/hid-lgff.c +++ b/drivers/hid/hid-lgff.c @@ -27,6 +27,8 @@ * e-mail - mail your message to */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -146,7 +148,7 @@ int lgff_init(struct hid_device* hid) /* Find the report to use */ if (list_empty(report_list)) { - err_hid("No output report found"); + hid_err(hid, "No output report found\n"); return -1; } @@ -154,7 +156,7 @@ int lgff_init(struct hid_device* hid) report = list_entry(report_list->next, struct hid_report, list); field = report->field[0]; if (!field) { - err_hid("NULL field"); + hid_err(hid, "NULL field\n"); return -1; } @@ -176,7 +178,7 @@ int lgff_init(struct hid_device* hid) if ( test_bit(FF_AUTOCENTER, dev->ffbit) ) dev->ff->set_autocenter = hid_lgff_set_autocenter; - printk(KERN_INFO "Force feedback for Logitech force feedback devices by Johann Deneux \n"); + pr_info("Force feedback for Logitech force feedback devices by Johann Deneux \n"); return 0; } diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c index e6dc15171664..11306b3d9c56 100644 --- a/drivers/hid/hid-magicmouse.c +++ b/drivers/hid/hid-magicmouse.c @@ -12,6 +12,8 @@ * any later version. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -446,7 +448,7 @@ static int magicmouse_probe(struct hid_device *hdev, msc = kzalloc(sizeof(*msc), GFP_KERNEL); if (msc == NULL) { - dev_err(&hdev->dev, "can't alloc magicmouse descriptor\n"); + hid_err(hdev, "can't alloc magicmouse descriptor\n"); return -ENOMEM; } @@ -459,13 +461,13 @@ static int magicmouse_probe(struct hid_device *hdev, ret = hid_parse(hdev); if (ret) { - dev_err(&hdev->dev, "magicmouse hid parse failed\n"); + hid_err(hdev, "magicmouse hid parse failed\n"); goto err_free; } ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); if (ret) { - dev_err(&hdev->dev, "magicmouse hw start failed\n"); + hid_err(hdev, "magicmouse hw start failed\n"); goto err_free; } @@ -486,7 +488,7 @@ static int magicmouse_probe(struct hid_device *hdev, } if (!report) { - dev_err(&hdev->dev, "unable to register touch report\n"); + hid_err(hdev, "unable to register touch report\n"); ret = -ENOMEM; goto err_stop_hw; } @@ -495,8 +497,7 @@ static int magicmouse_probe(struct hid_device *hdev, ret = hdev->hid_output_raw_report(hdev, feature, sizeof(feature), HID_FEATURE_REPORT); if (ret != sizeof(feature)) { - dev_err(&hdev->dev, "unable to request touch data (%d)\n", - ret); + hid_err(hdev, "unable to request touch data (%d)\n", ret); goto err_stop_hw; } @@ -540,7 +541,7 @@ static int __init magicmouse_init(void) ret = hid_register_driver(&magicmouse_driver); if (ret) - printk(KERN_ERR "can't register magicmouse driver\n"); + pr_err("can't register magicmouse driver\n"); return ret; } diff --git a/drivers/hid/hid-microsoft.c b/drivers/hid/hid-microsoft.c index dc618c33d0a2..0f6fc54dc196 100644 --- a/drivers/hid/hid-microsoft.c +++ b/drivers/hid/hid-microsoft.c @@ -40,8 +40,7 @@ static __u8 *ms_report_fixup(struct hid_device *hdev, __u8 *rdesc, if ((quirks & MS_RDESC) && *rsize == 571 && rdesc[557] == 0x19 && rdesc[559] == 0x29) { - dev_info(&hdev->dev, "fixing up Microsoft Wireless Receiver " - "Model 1028 report descriptor\n"); + hid_info(hdev, "fixing up Microsoft Wireless Receiver Model 1028 report descriptor\n"); rdesc[557] = 0x35; rdesc[559] = 0x45; } @@ -155,14 +154,14 @@ static int ms_probe(struct hid_device *hdev, const struct hid_device_id *id) ret = hid_parse(hdev); if (ret) { - dev_err(&hdev->dev, "parse failed\n"); + hid_err(hdev, "parse failed\n"); goto err_free; } ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT | ((quirks & MS_HIDINPUT) ? HID_CONNECT_HIDINPUT_FORCE : 0)); if (ret) { - dev_err(&hdev->dev, "hw start failed\n"); + hid_err(hdev, "hw start failed\n"); goto err_free; } diff --git a/drivers/hid/hid-monterey.c b/drivers/hid/hid-monterey.c index c95c31e2d869..dedf757781ae 100644 --- a/drivers/hid/hid-monterey.c +++ b/drivers/hid/hid-monterey.c @@ -26,8 +26,7 @@ static __u8 *mr_report_fixup(struct hid_device *hdev, __u8 *rdesc, unsigned int *rsize) { if (*rsize >= 30 && rdesc[29] == 0x05 && rdesc[30] == 0x09) { - dev_info(&hdev->dev, "fixing up button/consumer in HID report " - "descriptor\n"); + hid_info(hdev, "fixing up button/consumer in HID report descriptor\n"); rdesc[30] = 0x0c; } return rdesc; diff --git a/drivers/hid/hid-mosart.c b/drivers/hid/hid-mosart.c index ac5421d568f1..0668685380d5 100644 --- a/drivers/hid/hid-mosart.c +++ b/drivers/hid/hid-mosart.c @@ -199,7 +199,7 @@ static int mosart_probe(struct hid_device *hdev, const struct hid_device_id *id) td = kmalloc(sizeof(struct mosart_data), GFP_KERNEL); if (!td) { - dev_err(&hdev->dev, "cannot allocate MosArt data\n"); + hid_err(hdev, "cannot allocate MosArt data\n"); return -ENOMEM; } td->valid = false; diff --git a/drivers/hid/hid-ntrig.c b/drivers/hid/hid-ntrig.c index 69169efa1e16..beb403421e72 100644 --- a/drivers/hid/hid-ntrig.c +++ b/drivers/hid/hid-ntrig.c @@ -130,8 +130,7 @@ static void ntrig_report_version(struct hid_device *hdev) if (ret == 8) { ret = ntrig_version_string(&data[2], buf); - dev_info(&hdev->dev, - "Firmware version: %s (%02x%02x %02x%02x)\n", + hid_info(hdev, "Firmware version: %s (%02x%02x %02x%02x)\n", buf, data[2], data[3], data[4], data[5]); } @@ -831,7 +830,7 @@ static int ntrig_probe(struct hid_device *hdev, const struct hid_device_id *id) nd = kmalloc(sizeof(struct ntrig_data), GFP_KERNEL); if (!nd) { - dev_err(&hdev->dev, "cannot allocate N-Trig data\n"); + hid_err(hdev, "cannot allocate N-Trig data\n"); return -ENOMEM; } @@ -850,13 +849,13 @@ static int ntrig_probe(struct hid_device *hdev, const struct hid_device_id *id) ret = hid_parse(hdev); if (ret) { - dev_err(&hdev->dev, "parse failed\n"); + hid_err(hdev, "parse failed\n"); goto err_free; } ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT & ~HID_CONNECT_FF); if (ret) { - dev_err(&hdev->dev, "hw start failed\n"); + hid_err(hdev, "hw start failed\n"); goto err_free; } diff --git a/drivers/hid/hid-ortek.c b/drivers/hid/hid-ortek.c index 2e79716dca31..e90edfc63051 100644 --- a/drivers/hid/hid-ortek.c +++ b/drivers/hid/hid-ortek.c @@ -23,8 +23,7 @@ static __u8 *ortek_report_fixup(struct hid_device *hdev, __u8 *rdesc, unsigned int *rsize) { if (*rsize >= 56 && rdesc[54] == 0x25 && rdesc[55] == 0x01) { - dev_info(&hdev->dev, "Fixing up Ortek WKB-2000 " - "report descriptor.\n"); + hid_info(hdev, "Fixing up Ortek WKB-2000 report descriptor\n"); rdesc[55] = 0x92; } return rdesc; diff --git a/drivers/hid/hid-petalynx.c b/drivers/hid/hid-petalynx.c index 308d6ae48a3e..f1ea3ff8a98d 100644 --- a/drivers/hid/hid-petalynx.c +++ b/drivers/hid/hid-petalynx.c @@ -29,8 +29,7 @@ static __u8 *pl_report_fixup(struct hid_device *hdev, __u8 *rdesc, if (*rsize >= 60 && rdesc[39] == 0x2a && rdesc[40] == 0xf5 && rdesc[41] == 0x00 && rdesc[59] == 0x26 && rdesc[60] == 0xf9 && rdesc[61] == 0x00) { - dev_info(&hdev->dev, "fixing up Petalynx Maxter Remote report " - "descriptor\n"); + hid_info(hdev, "fixing up Petalynx Maxter Remote report descriptor\n"); rdesc[60] = 0xfa; rdesc[40] = 0xfa; } @@ -77,13 +76,13 @@ static int pl_probe(struct hid_device *hdev, const struct hid_device_id *id) ret = hid_parse(hdev); if (ret) { - dev_err(&hdev->dev, "parse failed\n"); + hid_err(hdev, "parse failed\n"); goto err_free; } ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); if (ret) { - dev_err(&hdev->dev, "hw start failed\n"); + hid_err(hdev, "hw start failed\n"); goto err_free; } diff --git a/drivers/hid/hid-picolcd.c b/drivers/hid/hid-picolcd.c index 38565fee7bf1..e4ce47156106 100644 --- a/drivers/hid/hid-picolcd.c +++ b/drivers/hid/hid-picolcd.c @@ -253,7 +253,7 @@ static struct hid_report *picolcd_report(int id, struct hid_device *hdev, int di if (report->id == id) return report; } - dev_warn(&hdev->dev, "No report with id 0x%x found\n", id); + hid_warn(hdev, "No report with id 0x%x found\n", id); return NULL; } @@ -1329,7 +1329,7 @@ static int picolcd_check_version(struct hid_device *hdev) verinfo = picolcd_send_and_wait(hdev, REPORT_VERSION, NULL, 0); if (!verinfo) { - dev_err(&hdev->dev, "no version response from PicoLCD"); + hid_err(hdev, "no version response from PicoLCD\n"); return -ENODEV; } @@ -1337,14 +1337,14 @@ static int picolcd_check_version(struct hid_device *hdev) data->version[0] = verinfo->raw_data[1]; data->version[1] = verinfo->raw_data[0]; if (data->status & PICOLCD_BOOTLOADER) { - dev_info(&hdev->dev, "PicoLCD, bootloader version %d.%d\n", - verinfo->raw_data[1], verinfo->raw_data[0]); + hid_info(hdev, "PicoLCD, bootloader version %d.%d\n", + verinfo->raw_data[1], verinfo->raw_data[0]); } else { - dev_info(&hdev->dev, "PicoLCD, firmware version %d.%d\n", - verinfo->raw_data[1], verinfo->raw_data[0]); + hid_info(hdev, "PicoLCD, firmware version %d.%d\n", + verinfo->raw_data[1], verinfo->raw_data[0]); } } else { - dev_err(&hdev->dev, "confused, got unexpected version response from PicoLCD\n"); + hid_err(hdev, "confused, got unexpected version response from PicoLCD\n"); ret = -EINVAL; } kfree(verinfo); @@ -2328,8 +2328,7 @@ static void picolcd_init_devfs(struct picolcd_data *data, (flash_w ? S_IWUSR : 0) | (flash_r ? S_IRUSR : 0), hdev->debug_dir, data, &picolcd_debug_flash_fops); } else if (flash_r || flash_w) - dev_warn(&hdev->dev, "Unexpected FLASH access reports, " - "please submit rdesc for review\n"); + hid_warn(hdev, "Unexpected FLASH access reports, please submit rdesc for review\n"); } static void picolcd_exit_devfs(struct picolcd_data *data) @@ -2457,13 +2456,13 @@ static int picolcd_init_keys(struct picolcd_data *data, return -ENODEV; if (report->maxfield != 1 || report->field[0]->report_count != 2 || report->field[0]->report_size != 8) { - dev_err(&hdev->dev, "unsupported KEY_STATE report"); + hid_err(hdev, "unsupported KEY_STATE report\n"); return -EINVAL; } idev = input_allocate_device(); if (idev == NULL) { - dev_err(&hdev->dev, "failed to allocate input device"); + hid_err(hdev, "failed to allocate input device\n"); return -ENOMEM; } input_set_drvdata(idev, hdev); @@ -2485,7 +2484,7 @@ static int picolcd_init_keys(struct picolcd_data *data, input_set_capability(idev, EV_KEY, data->keycode[i]); error = input_register_device(idev); if (error) { - dev_err(&hdev->dev, "error registering the input device"); + hid_err(hdev, "error registering the input device\n"); input_free_device(idev); return error; } @@ -2522,9 +2521,8 @@ static int picolcd_probe_lcd(struct hid_device *hdev, struct picolcd_data *data) return error; if (data->version[0] != 0 && data->version[1] != 3) - dev_info(&hdev->dev, "Device with untested firmware revision, " - "please submit /sys/kernel/debug/hid/%s/rdesc for this device.\n", - dev_name(&hdev->dev)); + hid_info(hdev, "Device with untested firmware revision, please submit /sys/kernel/debug/hid/%s/rdesc for this device.\n", + dev_name(&hdev->dev)); /* Setup keypad input device */ error = picolcd_init_keys(data, picolcd_in_report(REPORT_KEY_STATE, hdev)); @@ -2581,9 +2579,8 @@ static int picolcd_probe_bootloader(struct hid_device *hdev, struct picolcd_data return error; if (data->version[0] != 1 && data->version[1] != 0) - dev_info(&hdev->dev, "Device with untested bootloader revision, " - "please submit /sys/kernel/debug/hid/%s/rdesc for this device.\n", - dev_name(&hdev->dev)); + hid_info(hdev, "Device with untested bootloader revision, please submit /sys/kernel/debug/hid/%s/rdesc for this device.\n", + dev_name(&hdev->dev)); picolcd_init_devfs(data, NULL, NULL, picolcd_out_report(REPORT_BL_READ_MEMORY, hdev), @@ -2605,7 +2602,7 @@ static int picolcd_probe(struct hid_device *hdev, */ data = kzalloc(sizeof(struct picolcd_data), GFP_KERNEL); if (data == NULL) { - dev_err(&hdev->dev, "can't allocate space for Minibox PicoLCD device data\n"); + hid_err(hdev, "can't allocate space for Minibox PicoLCD device data\n"); error = -ENOMEM; goto err_no_cleanup; } @@ -2621,7 +2618,7 @@ static int picolcd_probe(struct hid_device *hdev, /* Parse the device reports and start it up */ error = hid_parse(hdev); if (error) { - dev_err(&hdev->dev, "device report parse failed\n"); + hid_err(hdev, "device report parse failed\n"); goto err_cleanup_data; } @@ -2631,25 +2628,25 @@ static int picolcd_probe(struct hid_device *hdev, error = hid_hw_start(hdev, 0); hdev->claimed = 0; if (error) { - dev_err(&hdev->dev, "hardware start failed\n"); + hid_err(hdev, "hardware start failed\n"); goto err_cleanup_data; } error = hid_hw_open(hdev); if (error) { - dev_err(&hdev->dev, "failed to open input interrupt pipe for key and IR events\n"); + hid_err(hdev, "failed to open input interrupt pipe for key and IR events\n"); goto err_cleanup_hid_hw; } error = device_create_file(&hdev->dev, &dev_attr_operation_mode_delay); if (error) { - dev_err(&hdev->dev, "failed to create sysfs attributes\n"); + hid_err(hdev, "failed to create sysfs attributes\n"); goto err_cleanup_hid_ll; } error = device_create_file(&hdev->dev, &dev_attr_operation_mode); if (error) { - dev_err(&hdev->dev, "failed to create sysfs attributes\n"); + hid_err(hdev, "failed to create sysfs attributes\n"); goto err_cleanup_sysfs1; } diff --git a/drivers/hid/hid-pl.c b/drivers/hid/hid-pl.c index 9f41e2bd8483..06e5300d43d2 100644 --- a/drivers/hid/hid-pl.c +++ b/drivers/hid/hid-pl.c @@ -103,7 +103,7 @@ static int plff_init(struct hid_device *hid) */ if (list_empty(report_list)) { - dev_err(&hid->dev, "no output reports found\n"); + hid_err(hid, "no output reports found\n"); return -ENODEV; } @@ -112,14 +112,13 @@ static int plff_init(struct hid_device *hid) report_ptr = report_ptr->next; if (report_ptr == report_list) { - dev_err(&hid->dev, "required output report is " - "missing\n"); + hid_err(hid, "required output report is missing\n"); return -ENODEV; } report = list_entry(report_ptr, struct hid_report, list); if (report->maxfield < 1) { - dev_err(&hid->dev, "no fields in the report\n"); + hid_err(hid, "no fields in the report\n"); return -ENODEV; } @@ -137,7 +136,7 @@ static int plff_init(struct hid_device *hid) weak = &report->field[3]->value[0]; debug("detected 4-field device"); } else { - dev_err(&hid->dev, "not enough fields or values\n"); + hid_err(hid, "not enough fields or values\n"); return -ENODEV; } @@ -164,8 +163,7 @@ static int plff_init(struct hid_device *hid) usbhid_submit_report(hid, plff->report, USB_DIR_OUT); } - dev_info(&hid->dev, "Force feedback for PantherLord/GreenAsia " - "devices by Anssi Hannula \n"); + hid_info(hid, "Force feedback for PantherLord/GreenAsia devices by Anssi Hannula \n"); return 0; } @@ -185,13 +183,13 @@ static int pl_probe(struct hid_device *hdev, const struct hid_device_id *id) ret = hid_parse(hdev); if (ret) { - dev_err(&hdev->dev, "parse failed\n"); + hid_err(hdev, "parse failed\n"); goto err; } ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT & ~HID_CONNECT_FF); if (ret) { - dev_err(&hdev->dev, "hw start failed\n"); + hid_err(hdev, "hw start failed\n"); goto err; } diff --git a/drivers/hid/hid-prodikeys.c b/drivers/hid/hid-prodikeys.c index 5f0fa6c1bf87..ab19f2905d27 100644 --- a/drivers/hid/hid-prodikeys.c +++ b/drivers/hid/hid-prodikeys.c @@ -16,6 +16,8 @@ * any later version. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -285,11 +287,11 @@ static int pcmidi_get_output_report(struct pcmidi_snd *pm) continue; if (report->maxfield < 1) { - dev_err(&hdev->dev, "output report is empty\n"); + hid_err(hdev, "output report is empty\n"); break; } if (report->field[0]->report_count != 2) { - dev_err(&hdev->dev, "field count too low\n"); + hid_err(hdev, "field count too low\n"); break; } pm->pcmidi_report6 = report; @@ -746,8 +748,8 @@ static __u8 *pk_report_fixup(struct hid_device *hdev, __u8 *rdesc, if (*rsize == 178 && rdesc[111] == 0x06 && rdesc[112] == 0x00 && rdesc[113] == 0xff) { - dev_info(&hdev->dev, "fixing up pc-midi keyboard report " - "descriptor\n"); + hid_info(hdev, + "fixing up pc-midi keyboard report descriptor\n"); rdesc[144] = 0x18; /* report 4: was 0x10 report count */ } @@ -805,7 +807,7 @@ static int pk_probe(struct hid_device *hdev, const struct hid_device_id *id) pk = kzalloc(sizeof(*pk), GFP_KERNEL); if (pk == NULL) { - dev_err(&hdev->dev, "prodikeys: can't alloc descriptor\n"); + hid_err(hdev, "can't alloc descriptor\n"); return -ENOMEM; } @@ -813,8 +815,7 @@ static int pk_probe(struct hid_device *hdev, const struct hid_device_id *id) pm = kzalloc(sizeof(*pm), GFP_KERNEL); if (pm == NULL) { - dev_err(&hdev->dev, - "prodikeys: can't alloc descriptor\n"); + hid_err(hdev, "can't alloc descriptor\n"); ret = -ENOMEM; goto err_free; } @@ -827,7 +828,7 @@ static int pk_probe(struct hid_device *hdev, const struct hid_device_id *id) ret = hid_parse(hdev); if (ret) { - dev_err(&hdev->dev, "prodikeys: hid parse failed\n"); + hid_err(hdev, "hid parse failed\n"); goto err_free; } @@ -837,7 +838,7 @@ static int pk_probe(struct hid_device *hdev, const struct hid_device_id *id) ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); if (ret) { - dev_err(&hdev->dev, "prodikeys: hw start failed\n"); + hid_err(hdev, "hw start failed\n"); goto err_free; } @@ -896,7 +897,7 @@ static int pk_init(void) ret = hid_register_driver(&pk_driver); if (ret) - printk(KERN_ERR "can't register prodikeys driver\n"); + pr_err("can't register prodikeys driver\n"); return ret; } diff --git a/drivers/hid/hid-quanta.c b/drivers/hid/hid-quanta.c index 54d3db50605b..87a54df4d4ac 100644 --- a/drivers/hid/hid-quanta.c +++ b/drivers/hid/hid-quanta.c @@ -195,7 +195,7 @@ static int quanta_probe(struct hid_device *hdev, const struct hid_device_id *id) td = kmalloc(sizeof(struct quanta_data), GFP_KERNEL); if (!td) { - dev_err(&hdev->dev, "cannot allocate Quanta Touch data\n"); + hid_err(hdev, "cannot allocate Quanta Touch data\n"); return -ENOMEM; } td->valid = false; diff --git a/drivers/hid/hid-roccat-kone.c b/drivers/hid/hid-roccat-kone.c index f77695762cb5..73199de2e37f 100644 --- a/drivers/hid/hid-roccat-kone.c +++ b/drivers/hid/hid-roccat-kone.c @@ -90,8 +90,7 @@ static int kone_check_write(struct usb_device *usb_dev) kfree(data); return 0; } else { /* unknown answer */ - dev_err(&usb_dev->dev, "got retval %d when checking write\n", - *data); + hid_err(usb_dev, "got retval %d when checking write\n", *data); kfree(data); return -EIO; } @@ -556,7 +555,7 @@ static ssize_t kone_sysfs_set_tcu(struct device *dev, retval = kone_set_settings(usb_dev, &kone->settings); if (retval) { - dev_err(&usb_dev->dev, "couldn't set tcu state\n"); + hid_err(usb_dev, "couldn't set tcu state\n"); /* * try to reread valid settings into buffer overwriting * first error code @@ -570,7 +569,7 @@ static ssize_t kone_sysfs_set_tcu(struct device *dev, retval = size; exit_no_settings: - dev_err(&usb_dev->dev, "couldn't read settings\n"); + hid_err(usb_dev, "couldn't read settings\n"); exit_unlock: mutex_unlock(&kone->kone_lock); return retval; @@ -818,21 +817,20 @@ static int kone_init_specials(struct hid_device *hdev) kone = kzalloc(sizeof(*kone), GFP_KERNEL); if (!kone) { - dev_err(&hdev->dev, "can't alloc device descriptor\n"); + hid_err(hdev, "can't alloc device descriptor\n"); return -ENOMEM; } hid_set_drvdata(hdev, kone); retval = kone_init_kone_device_struct(usb_dev, kone); if (retval) { - dev_err(&hdev->dev, - "couldn't init struct kone_device\n"); + hid_err(hdev, "couldn't init struct kone_device\n"); goto exit_free; } retval = roccat_connect(hdev); if (retval < 0) { - dev_err(&hdev->dev, "couldn't init char dev\n"); + hid_err(hdev, "couldn't init char dev\n"); /* be tolerant about not getting chrdev */ } else { kone->roccat_claimed = 1; @@ -841,7 +839,7 @@ static int kone_init_specials(struct hid_device *hdev) retval = kone_create_sysfs_attributes(intf); if (retval) { - dev_err(&hdev->dev, "cannot create sysfs files\n"); + hid_err(hdev, "cannot create sysfs files\n"); goto exit_free; } } else { @@ -876,19 +874,19 @@ static int kone_probe(struct hid_device *hdev, const struct hid_device_id *id) retval = hid_parse(hdev); if (retval) { - dev_err(&hdev->dev, "parse failed\n"); + hid_err(hdev, "parse failed\n"); goto exit; } retval = hid_hw_start(hdev, HID_CONNECT_DEFAULT); if (retval) { - dev_err(&hdev->dev, "hw start failed\n"); + hid_err(hdev, "hw start failed\n"); goto exit; } retval = kone_init_specials(hdev); if (retval) { - dev_err(&hdev->dev, "couldn't install mouse\n"); + hid_err(hdev, "couldn't install mouse\n"); goto exit_stop; } diff --git a/drivers/hid/hid-roccat-pyra.c b/drivers/hid/hid-roccat-pyra.c index 9bf23047892a..e7b4affe2664 100644 --- a/drivers/hid/hid-roccat-pyra.c +++ b/drivers/hid/hid-roccat-pyra.c @@ -87,9 +87,8 @@ static int pyra_receive_control_status(struct usb_device *usb_dev) control.value == 1) return 0; else { - dev_err(&usb_dev->dev, "receive control status: " - "unknown response 0x%x 0x%x\n", - control.request, control.value); + hid_err(usb_dev, "receive control status: unknown response 0x%x 0x%x\n", + control.request, control.value); return -EINVAL; } } @@ -770,21 +769,20 @@ static int pyra_init_specials(struct hid_device *hdev) pyra = kzalloc(sizeof(*pyra), GFP_KERNEL); if (!pyra) { - dev_err(&hdev->dev, "can't alloc device descriptor\n"); + hid_err(hdev, "can't alloc device descriptor\n"); return -ENOMEM; } hid_set_drvdata(hdev, pyra); retval = pyra_init_pyra_device_struct(usb_dev, pyra); if (retval) { - dev_err(&hdev->dev, - "couldn't init struct pyra_device\n"); + hid_err(hdev, "couldn't init struct pyra_device\n"); goto exit_free; } retval = roccat_connect(hdev); if (retval < 0) { - dev_err(&hdev->dev, "couldn't init char dev\n"); + hid_err(hdev, "couldn't init char dev\n"); } else { pyra->chrdev_minor = retval; pyra->roccat_claimed = 1; @@ -792,7 +790,7 @@ static int pyra_init_specials(struct hid_device *hdev) retval = pyra_create_sysfs_attributes(intf); if (retval) { - dev_err(&hdev->dev, "cannot create sysfs files\n"); + hid_err(hdev, "cannot create sysfs files\n"); goto exit_free; } } else { @@ -826,19 +824,19 @@ static int pyra_probe(struct hid_device *hdev, const struct hid_device_id *id) retval = hid_parse(hdev); if (retval) { - dev_err(&hdev->dev, "parse failed\n"); + hid_err(hdev, "parse failed\n"); goto exit; } retval = hid_hw_start(hdev, HID_CONNECT_DEFAULT); if (retval) { - dev_err(&hdev->dev, "hw start failed\n"); + hid_err(hdev, "hw start failed\n"); goto exit; } retval = pyra_init_specials(hdev); if (retval) { - dev_err(&hdev->dev, "couldn't install mouse\n"); + hid_err(hdev, "couldn't install mouse\n"); goto exit_stop; } return 0; diff --git a/drivers/hid/hid-roccat.c b/drivers/hid/hid-roccat.c index a9d9b29ff47f..4bc7a93dc1f5 100644 --- a/drivers/hid/hid-roccat.c +++ b/drivers/hid/hid-roccat.c @@ -21,6 +21,8 @@ * It is inspired by hidraw, but uses only one circular buffer for all readers. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -165,8 +167,7 @@ static int roccat_open(struct inode *inode, struct file *file) mutex_lock(&device->readers_lock); if (!device) { - printk(KERN_EMERG "roccat device with minor %d doesn't exist\n", - minor); + pr_emerg("roccat device with minor %d doesn't exist\n", minor); error = -ENODEV; goto exit_err; } @@ -214,8 +215,7 @@ static int roccat_release(struct inode *inode, struct file *file) device = devices[minor]; if (!device) { mutex_unlock(&devices_lock); - printk(KERN_EMERG "roccat device with minor %d doesn't exist\n", - minor); + pr_emerg("roccat device with minor %d doesn't exist\n", minor); return -ENODEV; } @@ -392,7 +392,7 @@ static int __init roccat_init(void) roccat_major = MAJOR(dev_id); if (retval < 0) { - printk(KERN_WARNING "roccat: can't get major number\n"); + pr_warn("can't get major number\n"); return retval; } diff --git a/drivers/hid/hid-samsung.c b/drivers/hid/hid-samsung.c index 35894444e000..3c1fd8af5e0c 100644 --- a/drivers/hid/hid-samsung.c +++ b/drivers/hid/hid-samsung.c @@ -57,8 +57,8 @@ static inline void samsung_irda_dev_trace(struct hid_device *hdev, unsigned int rsize) { - dev_info(&hdev->dev, "fixing up Samsung IrDA %d byte report " - "descriptor\n", rsize); + hid_info(hdev, "fixing up Samsung IrDA %d byte report descriptor\n", + rsize); } static __u8 *samsung_irda_report_fixup(struct hid_device *hdev, __u8 *rdesc, @@ -160,7 +160,7 @@ static int samsung_probe(struct hid_device *hdev, ret = hid_parse(hdev); if (ret) { - dev_err(&hdev->dev, "parse failed\n"); + hid_err(hdev, "parse failed\n"); goto err_free; } @@ -174,7 +174,7 @@ static int samsung_probe(struct hid_device *hdev, ret = hid_hw_start(hdev, cmask); if (ret) { - dev_err(&hdev->dev, "hw start failed\n"); + hid_err(hdev, "hw start failed\n"); goto err_free; } diff --git a/drivers/hid/hid-sjoy.c b/drivers/hid/hid-sjoy.c index e10a7687ebf2..16f7cafc9695 100644 --- a/drivers/hid/hid-sjoy.c +++ b/drivers/hid/hid-sjoy.c @@ -74,26 +74,25 @@ static int sjoyff_init(struct hid_device *hid) int error; if (list_empty(report_list)) { - dev_err(&hid->dev, "no output reports found\n"); + hid_err(hid, "no output reports found\n"); return -ENODEV; } report_ptr = report_ptr->next; if (report_ptr == report_list) { - dev_err(&hid->dev, "required output report is " - "missing\n"); + hid_err(hid, "required output report is missing\n"); return -ENODEV; } report = list_entry(report_ptr, struct hid_report, list); if (report->maxfield < 1) { - dev_err(&hid->dev, "no fields in the report\n"); + hid_err(hid, "no fields in the report\n"); return -ENODEV; } if (report->field[0]->report_count < 3) { - dev_err(&hid->dev, "not enough values in the field\n"); + hid_err(hid, "not enough values in the field\n"); return -ENODEV; } @@ -117,8 +116,7 @@ static int sjoyff_init(struct hid_device *hid) sjoyff->report->field[0]->value[2] = 0x00; usbhid_submit_report(hid, sjoyff->report, USB_DIR_OUT); - dev_info(&hid->dev, - "Force feedback for SmartJoy PLUS PS2/USB adapter\n"); + hid_info(hid, "Force feedback for SmartJoy PLUS PS2/USB adapter\n"); return 0; } @@ -135,13 +133,13 @@ static int sjoy_probe(struct hid_device *hdev, const struct hid_device_id *id) ret = hid_parse(hdev); if (ret) { - dev_err(&hdev->dev, "parse failed\n"); + hid_err(hdev, "parse failed\n"); goto err; } ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT & ~HID_CONNECT_FF); if (ret) { - dev_err(&hdev->dev, "hw start failed\n"); + hid_err(hdev, "hw start failed\n"); goto err; } diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c index 677bb3da10e8..68d7b36e31e4 100644 --- a/drivers/hid/hid-sony.c +++ b/drivers/hid/hid-sony.c @@ -40,8 +40,7 @@ static __u8 *sony_report_fixup(struct hid_device *hdev, __u8 *rdesc, if ((sc->quirks & VAIO_RDESC_CONSTANT) && *rsize >= 56 && rdesc[54] == 0x81 && rdesc[55] == 0x07) { - dev_info(&hdev->dev, "Fixing up Sony Vaio VGX report " - "descriptor\n"); + hid_info(hdev, "Fixing up Sony Vaio VGX report descriptor\n"); rdesc[55] = 0x06; } return rdesc; @@ -89,7 +88,7 @@ static int sixaxis_set_operational_usb(struct hid_device *hdev) (3 << 8) | 0xf2, ifnum, buf, 17, USB_CTRL_GET_TIMEOUT); if (ret < 0) - dev_err(&hdev->dev, "can't set operational mode\n"); + hid_err(hdev, "can't set operational mode\n"); kfree(buf); @@ -110,7 +109,7 @@ static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id) sc = kzalloc(sizeof(*sc), GFP_KERNEL); if (sc == NULL) { - dev_err(&hdev->dev, "can't alloc sony descriptor\n"); + hid_err(hdev, "can't alloc sony descriptor\n"); return -ENOMEM; } @@ -119,14 +118,14 @@ static int sony_probe(struct hid_device *hdev, const struct hid_device_id *id) ret = hid_parse(hdev); if (ret) { - dev_err(&hdev->dev, "parse failed\n"); + hid_err(hdev, "parse failed\n"); goto err_free; } ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT | HID_CONNECT_HIDDEV_FORCE); if (ret) { - dev_err(&hdev->dev, "hw start failed\n"); + hid_err(hdev, "hw start failed\n"); goto err_free; } diff --git a/drivers/hid/hid-stantum.c b/drivers/hid/hid-stantum.c index 3171be28c3d5..b2be1d11916b 100644 --- a/drivers/hid/hid-stantum.c +++ b/drivers/hid/hid-stantum.c @@ -222,7 +222,7 @@ static int stantum_probe(struct hid_device *hdev, sd = kmalloc(sizeof(struct stantum_data), GFP_KERNEL); if (!sd) { - dev_err(&hdev->dev, "cannot allocate Stantum data\n"); + hid_err(hdev, "cannot allocate Stantum data\n"); return -ENOMEM; } sd->valid = false; diff --git a/drivers/hid/hid-sunplus.c b/drivers/hid/hid-sunplus.c index 164ed568f6cf..d484a0043dd4 100644 --- a/drivers/hid/hid-sunplus.c +++ b/drivers/hid/hid-sunplus.c @@ -27,8 +27,7 @@ static __u8 *sp_report_fixup(struct hid_device *hdev, __u8 *rdesc, { if (*rsize >= 107 && rdesc[104] == 0x26 && rdesc[105] == 0x80 && rdesc[106] == 0x03) { - dev_info(&hdev->dev, "fixing up Sunplus Wireless Desktop " - "report descriptor\n"); + hid_info(hdev, "fixing up Sunplus Wireless Desktop report descriptor\n"); rdesc[105] = rdesc[110] = 0x03; rdesc[106] = rdesc[111] = 0x21; } diff --git a/drivers/hid/hid-tmff.c b/drivers/hid/hid-tmff.c index 15434c814793..356a98fcb365 100644 --- a/drivers/hid/hid-tmff.c +++ b/drivers/hid/hid-tmff.c @@ -151,28 +151,23 @@ static int tmff_init(struct hid_device *hid, const signed short *ff_bits) switch (field->usage[0].hid) { case THRUSTMASTER_USAGE_FF: if (field->report_count < 2) { - dev_warn(&hid->dev, "ignoring FF field " - "with report_count < 2\n"); + hid_warn(hid, "ignoring FF field with report_count < 2\n"); continue; } if (field->logical_maximum == field->logical_minimum) { - dev_warn(&hid->dev, "ignoring FF field " - "with logical_maximum " - "== logical_minimum\n"); + hid_warn(hid, "ignoring FF field with logical_maximum == logical_minimum\n"); continue; } if (tmff->report && tmff->report != report) { - dev_warn(&hid->dev, "ignoring FF field " - "in other report\n"); + hid_warn(hid, "ignoring FF field in other report\n"); continue; } if (tmff->ff_field && tmff->ff_field != field) { - dev_warn(&hid->dev, "ignoring " - "duplicate FF field\n"); + hid_warn(hid, "ignoring duplicate FF field\n"); continue; } @@ -185,16 +180,15 @@ static int tmff_init(struct hid_device *hid, const signed short *ff_bits) break; default: - dev_warn(&hid->dev, "ignoring unknown output " - "usage %08x\n", - field->usage[0].hid); + hid_warn(hid, "ignoring unknown output usage %08x\n", + field->usage[0].hid); continue; } } } if (!tmff->report) { - dev_err(&hid->dev, "can't find FF field in output reports\n"); + hid_err(hid, "can't find FF field in output reports\n"); error = -ENODEV; goto fail; } @@ -203,8 +197,7 @@ static int tmff_init(struct hid_device *hid, const signed short *ff_bits) if (error) goto fail; - dev_info(&hid->dev, "force feedback for ThrustMaster devices by Zinx " - "Verituse "); + hid_info(hid, "force feedback for ThrustMaster devices by Zinx Verituse \n"); return 0; fail: @@ -224,13 +217,13 @@ static int tm_probe(struct hid_device *hdev, const struct hid_device_id *id) ret = hid_parse(hdev); if (ret) { - dev_err(&hdev->dev, "parse failed\n"); + hid_err(hdev, "parse failed\n"); goto err; } ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT & ~HID_CONNECT_FF); if (ret) { - dev_err(&hdev->dev, "hw start failed\n"); + hid_err(hdev, "hw start failed\n"); goto err; } diff --git a/drivers/hid/hid-wacom.c b/drivers/hid/hid-wacom.c index 94caae731381..06888323828c 100644 --- a/drivers/hid/hid-wacom.c +++ b/drivers/hid/hid-wacom.c @@ -18,6 +18,8 @@ * any later version. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -141,8 +143,8 @@ static void wacom_poke(struct hid_device *hdev, u8 speed) * Note that if the raw queries fail, it's not a hard failure and it * is safe to continue */ - dev_warn(&hdev->dev, "failed to poke device, command %d, err %d\n", - rep_data[0], ret); + hid_warn(hdev, "failed to poke device, command %d, err %d\n", + rep_data[0], ret); return; } @@ -312,7 +314,7 @@ static int wacom_probe(struct hid_device *hdev, wdata = kzalloc(sizeof(*wdata), GFP_KERNEL); if (wdata == NULL) { - dev_err(&hdev->dev, "can't alloc wacom descriptor\n"); + hid_err(hdev, "can't alloc wacom descriptor\n"); return -ENOMEM; } @@ -321,20 +323,20 @@ static int wacom_probe(struct hid_device *hdev, /* Parse the HID report now */ ret = hid_parse(hdev); if (ret) { - dev_err(&hdev->dev, "parse failed\n"); + hid_err(hdev, "parse failed\n"); goto err_free; } ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); if (ret) { - dev_err(&hdev->dev, "hw start failed\n"); + hid_err(hdev, "hw start failed\n"); goto err_free; } ret = device_create_file(&hdev->dev, &dev_attr_speed); if (ret) - dev_warn(&hdev->dev, - "can't create sysfs speed attribute err: %d\n", ret); + hid_warn(hdev, + "can't create sysfs speed attribute err: %d\n", ret); /* Set Wacom mode 2 with high reporting speed */ wacom_poke(hdev, 1); @@ -349,8 +351,8 @@ static int wacom_probe(struct hid_device *hdev, ret = power_supply_register(&hdev->dev, &wdata->battery); if (ret) { - dev_warn(&hdev->dev, - "can't create sysfs battery attribute, err: %d\n", ret); + hid_warn(hdev, "can't create sysfs battery attribute, err: %d\n", + ret); /* * battery attribute is not critical for the tablet, but if it * failed then there is no need to create ac attribute @@ -367,8 +369,8 @@ static int wacom_probe(struct hid_device *hdev, ret = power_supply_register(&hdev->dev, &wdata->ac); if (ret) { - dev_warn(&hdev->dev, - "can't create ac battery attribute, err: %d\n", ret); + hid_warn(hdev, + "can't create ac battery attribute, err: %d\n", ret); /* * ac attribute is not critical for the tablet, but if it * failed then we don't want to battery attribute to exist @@ -454,7 +456,7 @@ static int __init wacom_init(void) ret = hid_register_driver(&wacom_driver); if (ret) - printk(KERN_ERR "can't register wacom driver\n"); + pr_err("can't register wacom driver\n"); return ret; } diff --git a/drivers/hid/hid-zpff.c b/drivers/hid/hid-zpff.c index b7acceabba80..f31fab012f2f 100644 --- a/drivers/hid/hid-zpff.c +++ b/drivers/hid/hid-zpff.c @@ -75,14 +75,14 @@ static int zpff_init(struct hid_device *hid) int error; if (list_empty(report_list)) { - dev_err(&hid->dev, "no output report found\n"); + hid_err(hid, "no output report found\n"); return -ENODEV; } report = list_entry(report_list->next, struct hid_report, list); if (report->maxfield < 4) { - dev_err(&hid->dev, "not enough fields in report\n"); + hid_err(hid, "not enough fields in report\n"); return -ENODEV; } @@ -105,8 +105,7 @@ static int zpff_init(struct hid_device *hid) zpff->report->field[3]->value[0] = 0x00; usbhid_submit_report(hid, zpff->report, USB_DIR_OUT); - dev_info(&hid->dev, "force feedback for Zeroplus based devices by " - "Anssi Hannula \n"); + hid_info(hid, "force feedback for Zeroplus based devices by Anssi Hannula \n"); return 0; } @@ -123,13 +122,13 @@ static int zp_probe(struct hid_device *hdev, const struct hid_device_id *id) ret = hid_parse(hdev); if (ret) { - dev_err(&hdev->dev, "parse failed\n"); + hid_err(hdev, "parse failed\n"); goto err; } ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT & ~HID_CONNECT_FF); if (ret) { - dev_err(&hdev->dev, "hw start failed\n"); + hid_err(hdev, "hw start failed\n"); goto err; } diff --git a/drivers/hid/hid-zydacron.c b/drivers/hid/hid-zydacron.c index aac1f9273149..e90371508fd2 100644 --- a/drivers/hid/hid-zydacron.c +++ b/drivers/hid/hid-zydacron.c @@ -34,9 +34,8 @@ static __u8 *zc_report_fixup(struct hid_device *hdev, __u8 *rdesc, rdesc[0x96] == 0xbc && rdesc[0x97] == 0xff && rdesc[0xca] == 0xbc && rdesc[0xcb] == 0xff && rdesc[0xe1] == 0xbc && rdesc[0xe2] == 0xff) { - dev_info(&hdev->dev, - "fixing up zydacron remote control report " - "descriptor\n"); + hid_info(hdev, + "fixing up zydacron remote control report descriptor\n"); rdesc[0x96] = rdesc[0xca] = rdesc[0xe1] = 0x0c; rdesc[0x97] = rdesc[0xcb] = rdesc[0xe2] = 0x00; } @@ -172,7 +171,7 @@ static int zc_probe(struct hid_device *hdev, const struct hid_device_id *id) zc = kzalloc(sizeof(*zc), GFP_KERNEL); if (zc == NULL) { - dev_err(&hdev->dev, "zydacron: can't alloc descriptor\n"); + hid_err(hdev, "can't alloc descriptor\n"); return -ENOMEM; } @@ -180,13 +179,13 @@ static int zc_probe(struct hid_device *hdev, const struct hid_device_id *id) ret = hid_parse(hdev); if (ret) { - dev_err(&hdev->dev, "zydacron: parse failed\n"); + hid_err(hdev, "parse failed\n"); goto err_free; } ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); if (ret) { - dev_err(&hdev->dev, "zydacron: hw start failed\n"); + hid_err(hdev, "hw start failed\n"); goto err_free; } diff --git a/drivers/hid/hidraw.c b/drivers/hid/hidraw.c index 5aefe73cf795..eb16cd143e2a 100644 --- a/drivers/hid/hidraw.c +++ b/drivers/hid/hidraw.c @@ -19,6 +19,8 @@ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -123,15 +125,15 @@ static ssize_t hidraw_write(struct file *file, const char __user *buffer, size_t } if (count > HID_MAX_BUFFER_SIZE) { - printk(KERN_WARNING "hidraw: pid %d passed too large report\n", - task_pid_nr(current)); + hid_warn(dev, "pid %d passed too large report\n", + task_pid_nr(current)); ret = -EINVAL; goto out; } if (count < 2) { - printk(KERN_WARNING "hidraw: pid %d passed too short report\n", - task_pid_nr(current)); + hid_warn(dev, "pid %d passed too short report\n", + task_pid_nr(current)); ret = -EINVAL; goto out; } @@ -450,7 +452,7 @@ int __init hidraw_init(void) hidraw_major = MAJOR(dev_id); if (result < 0) { - printk(KERN_WARNING "hidraw: can't get major number\n"); + pr_warn("can't get major number\n"); result = 0; goto out; } diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c index 5489eab3a6bd..276758f53ab5 100644 --- a/drivers/hid/usbhid/hid-core.c +++ b/drivers/hid/usbhid/hid-core.c @@ -136,10 +136,10 @@ static void hid_reset(struct work_struct *work) hid_io_error(hid); break; default: - err_hid("can't reset device, %s-%s/input%d, status %d", - hid_to_usb_dev(hid)->bus->bus_name, - hid_to_usb_dev(hid)->devpath, - usbhid->ifnum, rc); + hid_err(hid, "can't reset device, %s-%s/input%d, status %d\n", + hid_to_usb_dev(hid)->bus->bus_name, + hid_to_usb_dev(hid)->devpath, + usbhid->ifnum, rc); /* FALLTHROUGH */ case -EHOSTUNREACH: case -ENODEV: @@ -278,18 +278,18 @@ static void hid_irq_in(struct urb *urb) hid_io_error(hid); return; default: /* error */ - dev_warn(&urb->dev->dev, "input irq status %d " - "received\n", urb->status); + hid_warn(urb->dev, "input irq status %d received\n", + urb->status); } status = usb_submit_urb(urb, GFP_ATOMIC); if (status) { clear_bit(HID_IN_RUNNING, &usbhid->iofl); if (status != -EPERM) { - err_hid("can't resubmit intr, %s-%s/input%d, status %d", - hid_to_usb_dev(hid)->bus->bus_name, - hid_to_usb_dev(hid)->devpath, - usbhid->ifnum, status); + hid_err(hid, "can't resubmit intr, %s-%s/input%d, status %d\n", + hid_to_usb_dev(hid)->bus->bus_name, + hid_to_usb_dev(hid)->devpath, + usbhid->ifnum, status); hid_io_error(hid); } } @@ -313,7 +313,7 @@ static int hid_submit_out(struct hid_device *hid) dbg_hid("submitting out urb\n"); if (usb_submit_urb(usbhid->urbout, GFP_ATOMIC)) { - err_hid("usb_submit_urb(out) failed"); + hid_err(hid, "usb_submit_urb(out) failed\n"); return -1; } usbhid->last_out = jiffies; @@ -375,7 +375,7 @@ static int hid_submit_ctrl(struct hid_device *hid) usbhid->cr->wValue, usbhid->cr->wIndex, usbhid->cr->wLength); if (usb_submit_urb(usbhid->urbctrl, GFP_ATOMIC)) { - err_hid("usb_submit_urb(ctrl) failed"); + hid_err(hid, "usb_submit_urb(ctrl) failed\n"); return -1; } usbhid->last_ctrl = jiffies; @@ -413,8 +413,8 @@ static void hid_irq_out(struct urb *urb) case -ENOENT: break; default: /* error */ - dev_warn(&urb->dev->dev, "output irq status %d " - "received\n", urb->status); + hid_warn(urb->dev, "output irq status %d received\n", + urb->status); } spin_lock_irqsave(&usbhid->lock, flags); @@ -466,8 +466,7 @@ static void hid_ctrl(struct urb *urb) case -EPIPE: /* report not available */ break; default: /* error */ - dev_warn(&urb->dev->dev, "ctrl urb status %d " - "received\n", status); + hid_warn(urb->dev, "ctrl urb status %d received\n", status); } if (unplug) @@ -501,13 +500,13 @@ static void __usbhid_submit_report(struct hid_device *hid, struct hid_report *re if (usbhid->urbout && dir == USB_DIR_OUT && report->type == HID_OUTPUT_REPORT) { if ((head = (usbhid->outhead + 1) & (HID_OUTPUT_FIFO_SIZE - 1)) == usbhid->outtail) { - dev_warn(&hid->dev, "output queue full\n"); + hid_warn(hid, "output queue full\n"); return; } usbhid->out[usbhid->outhead].raw_report = kmalloc(len, GFP_ATOMIC); if (!usbhid->out[usbhid->outhead].raw_report) { - dev_warn(&hid->dev, "output queueing failed\n"); + hid_warn(hid, "output queueing failed\n"); return; } hid_output_report(report, usbhid->out[usbhid->outhead].raw_report); @@ -532,14 +531,14 @@ static void __usbhid_submit_report(struct hid_device *hid, struct hid_report *re } if ((head = (usbhid->ctrlhead + 1) & (HID_CONTROL_FIFO_SIZE - 1)) == usbhid->ctrltail) { - dev_warn(&hid->dev, "control queue full\n"); + hid_warn(hid, "control queue full\n"); return; } if (dir == USB_DIR_OUT) { usbhid->ctrl[usbhid->ctrlhead].raw_report = kmalloc(len, GFP_ATOMIC); if (!usbhid->ctrl[usbhid->ctrlhead].raw_report) { - dev_warn(&hid->dev, "control queueing failed\n"); + hid_warn(hid, "control queueing failed\n"); return; } hid_output_report(report, usbhid->ctrl[usbhid->ctrlhead].raw_report); @@ -590,7 +589,7 @@ static int usb_hidinput_input_event(struct input_dev *dev, unsigned int type, un return -1; if ((offset = hidinput_find_field(hid, type, code, &field)) == -1) { - dev_warn(&dev->dev, "event field not found\n"); + hid_warn(dev, "event field not found\n"); return -1; } @@ -722,7 +721,7 @@ void usbhid_init_reports(struct hid_device *hid) } if (err) - dev_warn(&hid->dev, "timeout initializing reports\n"); + hid_warn(hid, "timeout initializing reports\n"); } /* @@ -1140,8 +1139,7 @@ static int usbhid_probe(struct usb_interface *intf, const struct usb_device_id * if (usb_endpoint_is_int_in(&interface->endpoint[n].desc)) has_in++; if (!has_in) { - dev_err(&intf->dev, "couldn't find an input interrupt " - "endpoint\n"); + hid_err(intf, "couldn't find an input interrupt endpoint\n"); return -ENODEV; } @@ -1213,7 +1211,7 @@ static int usbhid_probe(struct usb_interface *intf, const struct usb_device_id * ret = hid_add_device(hid); if (ret) { if (ret != -ENODEV) - dev_err(&intf->dev, "can't add hid device: %d\n", ret); + hid_err(intf, "can't add hid device: %d\n", ret); goto err_free; } diff --git a/drivers/hid/usbhid/hid-pidff.c b/drivers/hid/usbhid/hid-pidff.c index ef381d79cfa8..f91c136821f7 100644 --- a/drivers/hid/usbhid/hid-pidff.c +++ b/drivers/hid/usbhid/hid-pidff.c @@ -22,7 +22,7 @@ /* #define DEBUG */ -#define debug(format, arg...) pr_debug("hid-pidff: " format "\n" , ## arg) +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #include #include @@ -220,7 +220,7 @@ static int pidff_rescale_signed(int i, struct hid_field *field) static void pidff_set(struct pidff_usage *usage, u16 value) { usage->value[0] = pidff_rescale(value, 0xffff, usage->field); - debug("calculated from %d to %d", value, usage->value[0]); + pr_debug("calculated from %d to %d\n", value, usage->value[0]); } static void pidff_set_signed(struct pidff_usage *usage, s16 value) @@ -235,7 +235,7 @@ static void pidff_set_signed(struct pidff_usage *usage, s16 value) usage->value[0] = pidff_rescale(value, 0x7fff, usage->field); } - debug("calculated from %d to %d", value, usage->value[0]); + pr_debug("calculated from %d to %d\n", value, usage->value[0]); } /* @@ -259,8 +259,9 @@ static void pidff_set_envelope_report(struct pidff_device *pidff, pidff->set_envelope[PID_ATTACK_TIME].value[0] = envelope->attack_length; pidff->set_envelope[PID_FADE_TIME].value[0] = envelope->fade_length; - debug("attack %u => %d", envelope->attack_level, - pidff->set_envelope[PID_ATTACK_LEVEL].value[0]); + hid_dbg(pidff->hid, "attack %u => %d\n", + envelope->attack_level, + pidff->set_envelope[PID_ATTACK_LEVEL].value[0]); usbhid_submit_report(pidff->hid, pidff->reports[PID_SET_ENVELOPE], USB_DIR_OUT); @@ -466,33 +467,33 @@ static int pidff_request_effect_upload(struct pidff_device *pidff, int efnum) pidff->create_new_effect_type->value[0] = efnum; usbhid_submit_report(pidff->hid, pidff->reports[PID_CREATE_NEW_EFFECT], USB_DIR_OUT); - debug("create_new_effect sent, type: %d", efnum); + hid_dbg(pidff->hid, "create_new_effect sent, type: %d\n", efnum); pidff->block_load[PID_EFFECT_BLOCK_INDEX].value[0] = 0; pidff->block_load_status->value[0] = 0; usbhid_wait_io(pidff->hid); for (j = 0; j < 60; j++) { - debug("pid_block_load requested"); + hid_dbg(pidff->hid, "pid_block_load requested\n"); usbhid_submit_report(pidff->hid, pidff->reports[PID_BLOCK_LOAD], USB_DIR_IN); usbhid_wait_io(pidff->hid); if (pidff->block_load_status->value[0] == pidff->status_id[PID_BLOCK_LOAD_SUCCESS]) { - debug("device reported free memory: %d bytes", - pidff->block_load[PID_RAM_POOL_AVAILABLE].value ? - pidff->block_load[PID_RAM_POOL_AVAILABLE].value[0] : -1); + hid_dbg(pidff->hid, "device reported free memory: %d bytes\n", + pidff->block_load[PID_RAM_POOL_AVAILABLE].value ? + pidff->block_load[PID_RAM_POOL_AVAILABLE].value[0] : -1); return 0; } if (pidff->block_load_status->value[0] == pidff->status_id[PID_BLOCK_LOAD_FULL]) { - debug("not enough memory free: %d bytes", - pidff->block_load[PID_RAM_POOL_AVAILABLE].value ? + hid_dbg(pidff->hid, "not enough memory free: %d bytes\n", + pidff->block_load[PID_RAM_POOL_AVAILABLE].value ? pidff->block_load[PID_RAM_POOL_AVAILABLE].value[0] : -1); return -ENOSPC; } } - printk(KERN_ERR "hid-pidff: pid_block_load failed 60 times\n"); + hid_err(pidff->hid, "pid_block_load failed 60 times\n"); return -EIO; } @@ -546,7 +547,8 @@ static int pidff_erase_effect(struct input_dev *dev, int effect_id) struct pidff_device *pidff = dev->ff->private; int pid_id = pidff->pid_id[effect_id]; - debug("starting to erase %d/%d", effect_id, pidff->pid_id[effect_id]); + hid_dbg(pidff->hid, "starting to erase %d/%d\n", + effect_id, pidff->pid_id[effect_id]); /* Wait for the queue to clear. We do not want a full fifo to prevent the effect removal. */ usbhid_wait_io(pidff->hid); @@ -604,8 +606,7 @@ static int pidff_upload_effect(struct input_dev *dev, struct ff_effect *effect, type_id = PID_SAW_DOWN; break; default: - printk(KERN_ERR - "hid-pidff: invalid waveform\n"); + hid_err(pidff->hid, "invalid waveform\n"); return -EINVAL; } @@ -696,7 +697,7 @@ static int pidff_upload_effect(struct input_dev *dev, struct ff_effect *effect, break; default: - printk(KERN_ERR "hid-pidff: invalid type\n"); + hid_err(pidff->hid, "invalid type\n"); return -EINVAL; } @@ -704,7 +705,7 @@ static int pidff_upload_effect(struct input_dev *dev, struct ff_effect *effect, pidff->pid_id[effect->id] = pidff->block_load[PID_EFFECT_BLOCK_INDEX].value[0]; - debug("uploaded"); + hid_dbg(pidff->hid, "uploaded\n"); return 0; } @@ -770,14 +771,14 @@ static int pidff_find_fields(struct pidff_usage *usage, const u8 *table, for (i = 0; i < report->maxfield; i++) { if (report->field[i]->maxusage != report->field[i]->report_count) { - debug("maxusage and report_count do not match, " - "skipping"); + pr_debug("maxusage and report_count do not match, skipping\n"); continue; } for (j = 0; j < report->field[i]->maxusage; j++) { if (report->field[i]->usage[j].hid == (HID_UP_PID | table[k])) { - debug("found %d at %d->%d", k, i, j); + pr_debug("found %d at %d->%d\n", + k, i, j); usage[k].field = report->field[i]; usage[k].value = &report->field[i]->value[j]; @@ -789,7 +790,7 @@ static int pidff_find_fields(struct pidff_usage *usage, const u8 *table, break; } if (!found && strict) { - debug("failed to locate %d", k); + pr_debug("failed to locate %d\n", k); return -1; } } @@ -826,8 +827,8 @@ static void pidff_find_reports(struct hid_device *hid, int report_type, continue; ret = pidff_check_usage(report->field[0]->logical); if (ret != -1) { - debug("found usage 0x%02x from field->logical", - pidff_reports[ret]); + hid_dbg(hid, "found usage 0x%02x from field->logical\n", + pidff_reports[ret]); pidff->reports[ret] = report; continue; } @@ -845,8 +846,9 @@ static void pidff_find_reports(struct hid_device *hid, int report_type, continue; ret = pidff_check_usage(hid->collection[i - 1].usage); if (ret != -1 && !pidff->reports[ret]) { - debug("found usage 0x%02x from collection array", - pidff_reports[ret]); + hid_dbg(hid, + "found usage 0x%02x from collection array\n", + pidff_reports[ret]); pidff->reports[ret] = report; } } @@ -861,7 +863,7 @@ static int pidff_reports_ok(struct pidff_device *pidff) for (i = 0; i <= PID_REQUIRED_REPORTS; i++) { if (!pidff->reports[i]) { - debug("%d missing", i); + hid_dbg(pidff->hid, "%d missing\n", i); return 0; } } @@ -884,8 +886,7 @@ static struct hid_field *pidff_find_special_field(struct hid_report *report, report->field[i]->logical_minimum == 1) return report->field[i]; else { - printk(KERN_ERR "hid-pidff: logical_minimum " - "is not 1 as it should be\n"); + pr_err("logical_minimum is not 1 as it should be\n"); return NULL; } } @@ -924,7 +925,7 @@ static int pidff_find_special_keys(int *keys, struct hid_field *fld, */ static int pidff_find_special_fields(struct pidff_device *pidff) { - debug("finding special fields"); + hid_dbg(pidff->hid, "finding special fields\n"); pidff->create_new_effect_type = pidff_find_special_field(pidff->reports[PID_CREATE_NEW_EFFECT], @@ -945,32 +946,30 @@ static int pidff_find_special_fields(struct pidff_device *pidff) pidff_find_special_field(pidff->reports[PID_EFFECT_OPERATION], 0x78, 1); - debug("search done"); + hid_dbg(pidff->hid, "search done\n"); if (!pidff->create_new_effect_type || !pidff->set_effect_type) { - printk(KERN_ERR "hid-pidff: effect lists not found\n"); + hid_err(pidff->hid, "effect lists not found\n"); return -1; } if (!pidff->effect_direction) { - printk(KERN_ERR "hid-pidff: direction field not found\n"); + hid_err(pidff->hid, "direction field not found\n"); return -1; } if (!pidff->device_control) { - printk(KERN_ERR "hid-pidff: device control field not found\n"); + hid_err(pidff->hid, "device control field not found\n"); return -1; } if (!pidff->block_load_status) { - printk(KERN_ERR - "hid-pidff: block load status field not found\n"); + hid_err(pidff->hid, "block load status field not found\n"); return -1; } if (!pidff->effect_operation_status) { - printk(KERN_ERR - "hid-pidff: effect operation field not found\n"); + hid_err(pidff->hid, "effect operation field not found\n"); return -1; } @@ -982,23 +981,22 @@ static int pidff_find_special_fields(struct pidff_device *pidff) if (!PIDFF_FIND_SPECIAL_KEYS(type_id, create_new_effect_type, effect_types)) { - printk(KERN_ERR "hid-pidff: no effect types found\n"); + hid_err(pidff->hid, "no effect types found\n"); return -1; } if (PIDFF_FIND_SPECIAL_KEYS(status_id, block_load_status, block_load_status) != sizeof(pidff_block_load_status)) { - printk(KERN_ERR - "hidpidff: block load status identifiers not found\n"); + hid_err(pidff->hid, + "block load status identifiers not found\n"); return -1; } if (PIDFF_FIND_SPECIAL_KEYS(operation_id, effect_operation_status, effect_operation_status) != sizeof(pidff_effect_operation_status)) { - printk(KERN_ERR - "hidpidff: effect operation identifiers not found\n"); + hid_err(pidff->hid, "effect operation identifiers not found\n"); return -1; } @@ -1017,8 +1015,8 @@ static int pidff_find_effects(struct pidff_device *pidff, int pidff_type = pidff->type_id[i]; if (pidff->set_effect_type->usage[pidff_type].hid != pidff->create_new_effect_type->usage[pidff_type].hid) { - printk(KERN_ERR "hid-pidff: " - "effect type number %d is invalid\n", i); + hid_err(pidff->hid, + "effect type number %d is invalid\n", i); return -1; } } @@ -1073,27 +1071,23 @@ static int pidff_init_fields(struct pidff_device *pidff, struct input_dev *dev) int envelope_ok = 0; if (PIDFF_FIND_FIELDS(set_effect, PID_SET_EFFECT, 1)) { - printk(KERN_ERR - "hid-pidff: unknown set_effect report layout\n"); + hid_err(pidff->hid, "unknown set_effect report layout\n"); return -ENODEV; } PIDFF_FIND_FIELDS(block_load, PID_BLOCK_LOAD, 0); if (!pidff->block_load[PID_EFFECT_BLOCK_INDEX].value) { - printk(KERN_ERR - "hid-pidff: unknown pid_block_load report layout\n"); + hid_err(pidff->hid, "unknown pid_block_load report layout\n"); return -ENODEV; } if (PIDFF_FIND_FIELDS(effect_operation, PID_EFFECT_OPERATION, 1)) { - printk(KERN_ERR - "hid-pidff: unknown effect_operation report layout\n"); + hid_err(pidff->hid, "unknown effect_operation report layout\n"); return -ENODEV; } if (PIDFF_FIND_FIELDS(block_free, PID_BLOCK_FREE, 1)) { - printk(KERN_ERR - "hid-pidff: unknown pid_block_free report layout\n"); + hid_err(pidff->hid, "unknown pid_block_free report layout\n"); return -ENODEV; } @@ -1105,27 +1099,26 @@ static int pidff_init_fields(struct pidff_device *pidff, struct input_dev *dev) if (!envelope_ok) { if (test_and_clear_bit(FF_CONSTANT, dev->ffbit)) - printk(KERN_WARNING "hid-pidff: " - "has constant effect but no envelope\n"); + hid_warn(pidff->hid, + "has constant effect but no envelope\n"); if (test_and_clear_bit(FF_RAMP, dev->ffbit)) - printk(KERN_WARNING "hid-pidff: " - "has ramp effect but no envelope\n"); + hid_warn(pidff->hid, + "has ramp effect but no envelope\n"); if (test_and_clear_bit(FF_PERIODIC, dev->ffbit)) - printk(KERN_WARNING "hid-pidff: " - "has periodic effect but no envelope\n"); + hid_warn(pidff->hid, + "has periodic effect but no envelope\n"); } if (test_bit(FF_CONSTANT, dev->ffbit) && PIDFF_FIND_FIELDS(set_constant, PID_SET_CONSTANT, 1)) { - printk(KERN_WARNING - "hid-pidff: unknown constant effect layout\n"); + hid_warn(pidff->hid, "unknown constant effect layout\n"); clear_bit(FF_CONSTANT, dev->ffbit); } if (test_bit(FF_RAMP, dev->ffbit) && PIDFF_FIND_FIELDS(set_ramp, PID_SET_RAMP, 1)) { - printk(KERN_WARNING "hid-pidff: unknown ramp effect layout\n"); + hid_warn(pidff->hid, "unknown ramp effect layout\n"); clear_bit(FF_RAMP, dev->ffbit); } @@ -1134,8 +1127,7 @@ static int pidff_init_fields(struct pidff_device *pidff, struct input_dev *dev) test_bit(FF_FRICTION, dev->ffbit) || test_bit(FF_INERTIA, dev->ffbit)) && PIDFF_FIND_FIELDS(set_condition, PID_SET_CONDITION, 1)) { - printk(KERN_WARNING - "hid-pidff: unknown condition effect layout\n"); + hid_warn(pidff->hid, "unknown condition effect layout\n"); clear_bit(FF_SPRING, dev->ffbit); clear_bit(FF_DAMPER, dev->ffbit); clear_bit(FF_FRICTION, dev->ffbit); @@ -1144,8 +1136,7 @@ static int pidff_init_fields(struct pidff_device *pidff, struct input_dev *dev) if (test_bit(FF_PERIODIC, dev->ffbit) && PIDFF_FIND_FIELDS(set_periodic, PID_SET_PERIODIC, 1)) { - printk(KERN_WARNING - "hid-pidff: unknown periodic effect layout\n"); + hid_warn(pidff->hid, "unknown periodic effect layout\n"); clear_bit(FF_PERIODIC, dev->ffbit); } @@ -1184,12 +1175,12 @@ static void pidff_reset(struct pidff_device *pidff) if (pidff->pool[PID_SIMULTANEOUS_MAX].value) { while (pidff->pool[PID_SIMULTANEOUS_MAX].value[0] < 2) { if (i++ > 20) { - printk(KERN_WARNING "hid-pidff: device reports " - "%d simultaneous effects\n", - pidff->pool[PID_SIMULTANEOUS_MAX].value[0]); + hid_warn(pidff->hid, + "device reports %d simultaneous effects\n", + pidff->pool[PID_SIMULTANEOUS_MAX].value[0]); break; } - debug("pid_pool requested again"); + hid_dbg(pidff->hid, "pid_pool requested again\n"); usbhid_submit_report(hid, pidff->reports[PID_POOL], USB_DIR_IN); usbhid_wait_io(hid); @@ -1215,7 +1206,7 @@ static int pidff_check_autocenter(struct pidff_device *pidff, error = pidff_request_effect_upload(pidff, 1); if (error) { - printk(KERN_ERR "hid-pidff: upload request failed\n"); + hid_err(pidff->hid, "upload request failed\n"); return error; } @@ -1224,8 +1215,8 @@ static int pidff_check_autocenter(struct pidff_device *pidff, pidff_autocenter(pidff, 0xffff); set_bit(FF_AUTOCENTER, dev->ffbit); } else { - printk(KERN_NOTICE "hid-pidff: " - "device has unknown autocenter control method\n"); + hid_notice(pidff->hid, + "device has unknown autocenter control method\n"); } pidff_erase_pid(pidff, @@ -1248,10 +1239,10 @@ int hid_pidff_init(struct hid_device *hid) int max_effects; int error; - debug("starting pid init"); + hid_dbg(hid, "starting pid init\n"); if (list_empty(&hid->report_enum[HID_OUTPUT_REPORT].report_list)) { - debug("not a PID device, no output report"); + hid_dbg(hid, "not a PID device, no output report\n"); return -ENODEV; } @@ -1265,7 +1256,7 @@ int hid_pidff_init(struct hid_device *hid) pidff_find_reports(hid, HID_FEATURE_REPORT, pidff); if (!pidff_reports_ok(pidff)) { - debug("reports not ok, aborting"); + hid_dbg(hid, "reports not ok, aborting\n"); error = -ENODEV; goto fail; } @@ -1278,8 +1269,8 @@ int hid_pidff_init(struct hid_device *hid) if (test_bit(FF_GAIN, dev->ffbit)) { pidff_set(&pidff->device_gain[PID_DEVICE_GAIN_FIELD], 0xffff); - usbhid_submit_report(pidff->hid, pidff->reports[PID_DEVICE_GAIN], - USB_DIR_OUT); + usbhid_submit_report(hid, pidff->reports[PID_DEVICE_GAIN], + USB_DIR_OUT); } error = pidff_check_autocenter(pidff, dev); @@ -1290,23 +1281,23 @@ int hid_pidff_init(struct hid_device *hid) pidff->block_load[PID_EFFECT_BLOCK_INDEX].field->logical_maximum - pidff->block_load[PID_EFFECT_BLOCK_INDEX].field->logical_minimum + 1; - debug("max effects is %d", max_effects); + hid_dbg(hid, "max effects is %d\n", max_effects); if (max_effects > PID_EFFECTS_MAX) max_effects = PID_EFFECTS_MAX; if (pidff->pool[PID_SIMULTANEOUS_MAX].value) - debug("max simultaneous effects is %d", - pidff->pool[PID_SIMULTANEOUS_MAX].value[0]); + hid_dbg(hid, "max simultaneous effects is %d\n", + pidff->pool[PID_SIMULTANEOUS_MAX].value[0]); if (pidff->pool[PID_RAM_POOL_SIZE].value) - debug("device memory size is %d bytes", - pidff->pool[PID_RAM_POOL_SIZE].value[0]); + hid_dbg(hid, "device memory size is %d bytes\n", + pidff->pool[PID_RAM_POOL_SIZE].value[0]); if (pidff->pool[PID_DEVICE_MANAGED_POOL].value && pidff->pool[PID_DEVICE_MANAGED_POOL].value[0] == 0) { - printk(KERN_NOTICE "hid-pidff: " - "device does not support device managed pool\n"); + hid_notice(hid, + "device does not support device managed pool\n"); goto fail; } @@ -1322,8 +1313,7 @@ int hid_pidff_init(struct hid_device *hid) ff->set_autocenter = pidff_set_autocenter; ff->playback = pidff_playback; - printk(KERN_INFO "Force feedback for USB HID PID devices by " - "Anssi Hannula \n"); + hid_info(dev, "Force feedback for USB HID PID devices by Anssi Hannula \n"); return 0; diff --git a/drivers/hid/usbhid/hiddev.c b/drivers/hid/usbhid/hiddev.c index a9935f6709f7..fb78f75d49a9 100644 --- a/drivers/hid/usbhid/hiddev.c +++ b/drivers/hid/usbhid/hiddev.c @@ -906,7 +906,7 @@ int hiddev_connect(struct hid_device *hid, unsigned int force) hiddev->exist = 1; retval = usb_register_dev(usbhid->intf, &hiddev_class); if (retval) { - err_hid("Not able to get a minor for this device."); + hid_err(hid, "Not able to get a minor for this device\n"); hid->hiddev = NULL; kfree(hiddev); return -1; diff --git a/drivers/hid/usbhid/usbkbd.c b/drivers/hid/usbhid/usbkbd.c index a948605564fb..065817329f03 100644 --- a/drivers/hid/usbhid/usbkbd.c +++ b/drivers/hid/usbhid/usbkbd.c @@ -24,6 +24,8 @@ * Vojtech Pavlik, Simunkova 1594, Prague 8, 182 00 Czech Republic */ +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + #include #include #include @@ -104,16 +106,18 @@ static void usb_kbd_irq(struct urb *urb) if (usb_kbd_keycode[kbd->old[i]]) input_report_key(kbd->dev, usb_kbd_keycode[kbd->old[i]], 0); else - dev_info(&urb->dev->dev, - "Unknown key (scancode %#x) released.\n", kbd->old[i]); + hid_info(urb->dev, + "Unknown key (scancode %#x) released.\n", + kbd->old[i]); } if (kbd->new[i] > 3 && memscan(kbd->old + 2, kbd->new[i], 6) == kbd->old + 8) { if (usb_kbd_keycode[kbd->new[i]]) input_report_key(kbd->dev, usb_kbd_keycode[kbd->new[i]], 1); else - dev_info(&urb->dev->dev, - "Unknown key (scancode %#x) released.\n", kbd->new[i]); + hid_info(urb->dev, + "Unknown key (scancode %#x) released.\n", + kbd->new[i]); } } @@ -124,9 +128,9 @@ static void usb_kbd_irq(struct urb *urb) resubmit: i = usb_submit_urb (urb, GFP_ATOMIC); if (i) - err_hid ("can't resubmit intr, %s-%s/input0, status %d", - kbd->usbdev->bus->bus_name, - kbd->usbdev->devpath, i); + hid_err(urb->dev, "can't resubmit intr, %s-%s/input0, status %d", + kbd->usbdev->bus->bus_name, + kbd->usbdev->devpath, i); } static int usb_kbd_event(struct input_dev *dev, unsigned int type, @@ -150,7 +154,7 @@ static int usb_kbd_event(struct input_dev *dev, unsigned int type, *(kbd->leds) = kbd->newleds; kbd->led->dev = kbd->usbdev; if (usb_submit_urb(kbd->led, GFP_ATOMIC)) - err_hid("usb_submit_urb(leds) failed"); + pr_err("usb_submit_urb(leds) failed\n"); return 0; } @@ -160,7 +164,7 @@ static void usb_kbd_led(struct urb *urb) struct usb_kbd *kbd = urb->context; if (urb->status) - dev_warn(&urb->dev->dev, "led urb status %d received\n", + hid_warn(urb->dev, "led urb status %d received\n", urb->status); if (*(kbd->leds) == kbd->newleds) @@ -169,7 +173,7 @@ static void usb_kbd_led(struct urb *urb) *(kbd->leds) = kbd->newleds; kbd->led->dev = kbd->usbdev; if (usb_submit_urb(kbd->led, GFP_ATOMIC)) - err_hid("usb_submit_urb(leds) failed"); + hid_err(urb->dev, "usb_submit_urb(leds) failed\n"); } static int usb_kbd_open(struct input_dev *dev) diff --git a/include/linux/hid.h b/include/linux/hid.h index e2af195d8b46..20b9801f669b 100644 --- a/include/linux/hid.h +++ b/include/linux/hid.h @@ -881,12 +881,32 @@ int hid_pidff_init(struct hid_device *hid); #define hid_pidff_init NULL #endif -#define dbg_hid(format, arg...) if (hid_debug) \ - printk(KERN_DEBUG "%s: " format ,\ - __FILE__ , ## arg) -#define err_hid(format, arg...) printk(KERN_ERR "%s: " format "\n" , \ - __FILE__ , ## arg) -#endif /* HID_FF */ +#define dbg_hid(format, arg...) \ +do { \ + if (hid_debug) \ + printk(KERN_DEBUG "%s: " format, __FILE__, ##arg); \ +} while (0) + +#define hid_printk(level, hid, fmt, arg...) \ + dev_printk(level, &(hid)->dev, fmt, ##arg) +#define hid_emerg(hid, fmt, arg...) \ + dev_emerg(&(hid)->dev, fmt, ##arg) +#define hid_crit(hid, fmt, arg...) \ + dev_crit(&(hid)->dev, fmt, ##arg) +#define hid_alert(hid, fmt, arg...) \ + dev_alert(&(hid)->dev, fmt, ##arg) +#define hid_err(hid, fmt, arg...) \ + dev_err(&(hid)->dev, fmt, ##arg) +#define hid_notice(hid, fmt, arg...) \ + dev_notice(&(hid)->dev, fmt, ##arg) +#define hid_warn(hid, fmt, arg...) \ + dev_warn(&(hid)->dev, fmt, ##arg) +#define hid_info(hid, fmt, arg...) \ + dev_info(&(hid)->dev, fmt, ##arg) +#define hid_dbg(hid, fmt, arg...) \ + dev_dbg(&(hid)->dev, fmt, ##arg) + +#endif /* __KERNEL__ */ #endif -- cgit v1.2.3 From fe2580204d8bbcd18540736a283ed0b784c6a024 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Thu, 9 Dec 2010 19:29:04 -0800 Subject: HID: Use vzalloc for vmalloc/memset(,0...) Signed-off-by: Joe Perches Signed-off-by: Jiri Kosina --- drivers/hid/hid-core.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 1fd5e331fa8d..5ddace093f0f 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -654,13 +654,12 @@ int hid_parse_report(struct hid_device *device, __u8 *start, return -ENOMEM; device->rsize = size; - parser = vmalloc(sizeof(struct hid_parser)); + parser = vzalloc(sizeof(struct hid_parser)); if (!parser) { ret = -ENOMEM; goto err; } - memset(parser, 0, sizeof(struct hid_parser)); parser->device = device; end = start + size; -- cgit v1.2.3 From 16ee4cc82b5dbb81a5dbfedcdb268b9467fe4605 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Thu, 9 Dec 2010 19:29:05 -0800 Subject: HID: Remove superfluous __inline__ Signed-off-by: Joe Perches Signed-off-by: Jiri Kosina --- drivers/hid/hid-core.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 5ddace093f0f..e6b90622e4eb 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -739,8 +739,8 @@ static u32 s32ton(__s32 value, unsigned n) * Search linux-kernel and linux-usb-devel archives for "hid-core extract". */ -static __inline__ __u32 extract(const struct hid_device *hid, __u8 *report, - unsigned offset, unsigned n) +static __u32 extract(const struct hid_device *hid, __u8 *report, + unsigned offset, unsigned n) { u64 x; @@ -763,8 +763,8 @@ static __inline__ __u32 extract(const struct hid_device *hid, __u8 *report, * endianness of register values by considering a register * a "cached" copy of the little endiad bit stream. */ -static __inline__ void implement(const struct hid_device *hid, __u8 *report, - unsigned offset, unsigned n, __u32 value) +static void implement(const struct hid_device *hid, __u8 *report, + unsigned offset, unsigned n, __u32 value) { u64 x; u64 m = (1ULL << n) - 1; @@ -792,7 +792,7 @@ static __inline__ void implement(const struct hid_device *hid, __u8 *report, * Search an array for a value. */ -static __inline__ int search(__s32 *array, __s32 value, unsigned n) +static int search(__s32 *array, __s32 value, unsigned n) { while (n--) { if (*array++ == value) -- cgit v1.2.3 From a3789a1783d37f2772ba5046b26416c98dfe1bfa Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Thu, 9 Dec 2010 19:29:07 -0800 Subject: HID: Hoist assigns from ifs Signed-off-by: Joe Perches Signed-off-by: Jiri Kosina --- drivers/hid/hid-core.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index e6b90622e4eb..86b7155632fb 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -61,7 +61,8 @@ struct hid_report *hid_register_report(struct hid_device *device, unsigned type, if (report_enum->report_id_hash[id]) return report_enum->report_id_hash[id]; - if (!(report = kzalloc(sizeof(struct hid_report), GFP_KERNEL))) + report = kzalloc(sizeof(struct hid_report), GFP_KERNEL); + if (!report) return NULL; if (id != 0) @@ -92,8 +93,11 @@ static struct hid_field *hid_register_field(struct hid_report *report, unsigned return NULL; } - if (!(field = kzalloc(sizeof(struct hid_field) + usages * sizeof(struct hid_usage) - + values * sizeof(unsigned), GFP_KERNEL))) return NULL; + field = kzalloc((sizeof(struct hid_field) + + usages * sizeof(struct hid_usage) + + values * sizeof(unsigned)), GFP_KERNEL); + if (!field) + return NULL; field->index = report->maxfield++; report->field[field->index] = field; @@ -211,7 +215,8 @@ static int hid_add_field(struct hid_parser *parser, unsigned report_type, unsign unsigned offset; int i; - if (!(report = hid_register_report(parser->device, report_type, parser->global.report_id))) { + report = hid_register_report(parser->device, report_type, parser->global.report_id); + if (!report) { dbg_hid("hid_register_report failed\n"); return -1; } @@ -229,7 +234,8 @@ static int hid_add_field(struct hid_parser *parser, unsigned report_type, unsign usages = max_t(int, parser->local.usage_index, parser->global.report_count); - if ((field = hid_register_field(report, usages, parser->global.report_count)) == NULL) + field = hid_register_field(report, usages, parser->global.report_count); + if (!field) return 0; field->physical = hid_lookup_collection(parser, HID_COLLECTION_PHYSICAL); @@ -891,7 +897,8 @@ static void hid_input_field(struct hid_device *hid, struct hid_field *field, __s32 max = field->logical_maximum; __s32 *value; - if (!(value = kmalloc(sizeof(__s32) * count, GFP_ATOMIC))) + value = kmalloc(sizeof(__s32) * count, GFP_ATOMIC); + if (!value) return; for (n = 0; n < count; n++) { -- cgit v1.2.3 From 504499f22c08a03e2e19dc88d31aa0ecd2ac815e Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Thu, 9 Dec 2010 19:29:08 -0800 Subject: HID: simplify an index check in hid_lookup_collection Save the struct hid_collection * in a temporary to shorten the generated code a bit and perhaps improve readability. $ size drivers/hid/hid-core.o* text data bss dec hex filename 16460 78 8 16546 40a2 drivers/hid/hid-core.o.new 16469 78 8 16555 40ab drivers/hid/hid-core.o.old Signed-off-by: Joe Perches Signed-off-by: Jiri Kosina --- drivers/hid/hid-core.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 86b7155632fb..d4c1906313d2 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c @@ -178,10 +178,14 @@ static int close_collection(struct hid_parser *parser) static unsigned hid_lookup_collection(struct hid_parser *parser, unsigned type) { + struct hid_collection *collection = parser->device->collection; int n; - for (n = parser->collection_stack_ptr - 1; n >= 0; n--) - if (parser->device->collection[parser->collection_stack[n]].type == type) - return parser->device->collection[parser->collection_stack[n]].usage; + + for (n = parser->collection_stack_ptr - 1; n >= 0; n--) { + unsigned index = parser->collection_stack[n]; + if (collection[index].type == type) + return collection[index].usage; + } return 0; /* we know nothing about this usage type */ } -- cgit v1.2.3 From a34f0b31398020e2d3be653eb695bd17a9cf3b55 Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Fri, 10 Dec 2010 14:55:42 +0100 Subject: fix comment typos concerning "consistent" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Uwe Kleine-König Signed-off-by: Jiri Kosina --- arch/arm/mach-msm/include/mach/entry-macro-qgic.S | 2 +- arch/m68k/mac/psc.c | 2 +- drivers/net/via-velocity.c | 2 +- drivers/net/wimax/i2400m/i2400m.h | 2 +- drivers/scsi/megaraid/megaraid_mm.c | 2 +- fs/jbd/transaction.c | 2 +- fs/jbd2/transaction.c | 2 +- net/ipv6/af_inet6.c | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/arch/arm/mach-msm/include/mach/entry-macro-qgic.S b/arch/arm/mach-msm/include/mach/entry-macro-qgic.S index 4dc99aa65d07..12467157afb9 100644 --- a/arch/arm/mach-msm/include/mach/entry-macro-qgic.S +++ b/arch/arm/mach-msm/include/mach/entry-macro-qgic.S @@ -26,7 +26,7 @@ * The interrupt numbering scheme is defined in the * interrupt controller spec. To wit: * - * Migrated the code from ARM MP port to be more consistant + * Migrated the code from ARM MP port to be more consistent * with interrupt processing , the following still holds true * however, all interrupts are treated the same regardless of * if they are local IPI or PPI diff --git a/arch/m68k/mac/psc.c b/arch/m68k/mac/psc.c index ba6ccab64018..a4c3eb60706e 100644 --- a/arch/m68k/mac/psc.c +++ b/arch/m68k/mac/psc.c @@ -88,7 +88,7 @@ void __init psc_init(void) /* * The PSC is always at the same spot, but using psc - * keeps things consisant with the psc_xxxx functions. + * keeps things consistent with the psc_xxxx functions. */ psc = (void *) PSC_BASE; diff --git a/drivers/net/via-velocity.c b/drivers/net/via-velocity.c index cab96ad49e60..09cac704fdd7 100644 --- a/drivers/net/via-velocity.c +++ b/drivers/net/via-velocity.c @@ -898,7 +898,7 @@ static int velocity_set_media_mode(struct velocity_info *vptr, u32 mii_status) set_mii_flow_control(vptr); /* - Check if new status is consisent with current status + Check if new status is consistent with current status if (((mii_status & curr_status) & VELOCITY_AUTONEG_ENABLE) || (mii_status==curr_status)) { vptr->mii_status=mii_check_media_mode(vptr->mac_regs); diff --git a/drivers/net/wimax/i2400m/i2400m.h b/drivers/net/wimax/i2400m/i2400m.h index 8cde3a52d225..a2dbc94f6232 100644 --- a/drivers/net/wimax/i2400m/i2400m.h +++ b/drivers/net/wimax/i2400m/i2400m.h @@ -186,7 +186,7 @@ enum { * struct i2400m_poke_table - Hardware poke table for the Intel 2400m * * This structure will be used to create a device specific poke table - * to put the device in a consistant state at boot time. + * to put the device in a consistent state at boot time. * * @address: The device address to poke * diff --git a/drivers/scsi/megaraid/megaraid_mm.c b/drivers/scsi/megaraid/megaraid_mm.c index a7008c0c24f9..25506c777381 100644 --- a/drivers/scsi/megaraid/megaraid_mm.c +++ b/drivers/scsi/megaraid/megaraid_mm.c @@ -224,7 +224,7 @@ mraid_mm_unlocked_ioctl(struct file *filep, unsigned int cmd, { int err; - /* inconsistant: mraid_mm_compat_ioctl doesn't take the BKL */ + /* inconsistent: mraid_mm_compat_ioctl doesn't take the BKL */ mutex_lock(&mraid_mm_mutex); err = mraid_mm_ioctl(filep, cmd, arg); mutex_unlock(&mraid_mm_mutex); diff --git a/fs/jbd/transaction.c b/fs/jbd/transaction.c index 846a3f314111..5b2e4c30a2a1 100644 --- a/fs/jbd/transaction.c +++ b/fs/jbd/transaction.c @@ -207,7 +207,7 @@ repeat_locked: * the committing transaction. Really, we only need to give it * committing_transaction->t_outstanding_credits plus "enough" for * the log control blocks. - * Also, this test is inconsitent with the matching one in + * Also, this test is inconsistent with the matching one in * journal_extend(). */ if (__log_space_left(journal) < jbd_space_needed(journal)) { diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c index 6bf0a242613e..c7934900dcdd 100644 --- a/fs/jbd2/transaction.c +++ b/fs/jbd2/transaction.c @@ -251,7 +251,7 @@ repeat: * the committing transaction. Really, we only need to give it * committing_transaction->t_outstanding_credits plus "enough" for * the log control blocks. - * Also, this test is inconsitent with the matching one in + * Also, this test is inconsistent with the matching one in * jbd2_journal_extend(). */ if (__jbd2_log_space_left(journal) < jbd_space_needed(journal)) { diff --git a/net/ipv6/af_inet6.c b/net/ipv6/af_inet6.c index 54e8e42f7a88..0935c5a42b1f 100644 --- a/net/ipv6/af_inet6.c +++ b/net/ipv6/af_inet6.c @@ -300,7 +300,7 @@ int inet6_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) goto out; } - /* Reproduce AF_INET checks to make the bindings consitant */ + /* Reproduce AF_INET checks to make the bindings consistent */ v4addr = addr->sin6_addr.s6_addr32[3]; chk_addr_ret = inet_addr_type(net, v4addr); if (!sysctl_ip_nonlocal_bind && -- cgit v1.2.3 From c0d8768af260e2cbb4bf659ae6094a262c86b085 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Fri, 10 Dec 2010 12:11:50 +0900 Subject: anon_inodes: fix wrong function name in comment Signed-off-by: Namhyung Kim Signed-off-by: Jiri Kosina --- fs/anon_inodes.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/fs/anon_inodes.c b/fs/anon_inodes.c index 57ce55b2564c..73097336ea2a 100644 --- a/fs/anon_inodes.c +++ b/fs/anon_inodes.c @@ -64,9 +64,9 @@ static const struct address_space_operations anon_aops = { }; /** - * anon_inode_getfd - creates a new file instance by hooking it up to an - * anonymous inode, and a dentry that describe the "class" - * of the file + * anon_inode_getfile - creates a new file instance by hooking it up to an + * anonymous inode, and a dentry that describe the "class" + * of the file * * @name: [in] name of the "class" of the new file * @fops: [in] file operations for the new file -- cgit v1.2.3 From 249c5156b8a743e3df5386c5cb7ae3df1d754e50 Mon Sep 17 00:00:00 2001 From: Mario Becroft Date: Sat, 4 Dec 2010 11:51:34 +1300 Subject: ASoC: Optimise WM9081 FLL performance Tune the FLL gain for optimal performance according to evaluation results. Signed-off-by: Mario Becroft Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/codecs/wm9081.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/sound/soc/codecs/wm9081.c b/sound/soc/codecs/wm9081.c index c7060775e88b..e5055b28c638 100644 --- a/sound/soc/codecs/wm9081.c +++ b/sound/soc/codecs/wm9081.c @@ -590,6 +590,10 @@ static int wm9081_set_fll(struct snd_soc_codec *codec, int fll_id, reg5 |= fll_div.fll_clk_ref_div << WM9081_FLL_CLK_REF_DIV_SHIFT; snd_soc_write(codec, WM9081_FLL_CONTROL_5, reg5); + /* Set gain to the recommended value */ + snd_soc_update_bits(codec, WM9081_FLL_CONTROL_4, + WM9081_FLL_GAIN_MASK, 0); + /* Enable the FLL */ snd_soc_write(codec, WM9081_FLL_CONTROL_1, reg1 | WM9081_FLL_ENA); -- cgit v1.2.3 From 154b26aa9ec4aaeaa7258fe85a036613f3713a59 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 9 Dec 2010 12:07:44 +0000 Subject: ASoC: Implement WM8994/58 DAC and ADC oversampling control The oversampling rate of the DAC and ADC can be controlled to optimise for either low power consumption or maximum performance. Signed-off-by: Mark Brown Acked-by: Liam Girdwood --- sound/soc/codecs/wm8994.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index da48802340fc..e59691a7b342 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c @@ -558,6 +558,16 @@ static const struct soc_enum aif2dacl_src = static const struct soc_enum aif2dacr_src = SOC_ENUM_SINGLE(WM8994_AIF2_CONTROL_2, 14, 2, aif_chan_src_text); +static const char *osr_text[] = { + "Low Power", "High Performance", +}; + +static const struct soc_enum dac_osr = + SOC_ENUM_SINGLE(WM8994_OVERSAMPLING, 0, 2, osr_text); + +static const struct soc_enum adc_osr = + SOC_ENUM_SINGLE(WM8994_OVERSAMPLING, 1, 2, osr_text); + static void wm8958_mbc_apply(struct snd_soc_codec *codec, int mbc, int start) { struct wm8994_priv *wm8994 = snd_soc_codec_get_drvdata(codec); @@ -834,6 +844,9 @@ SOC_DOUBLE("AIF1ADC2 HPF Switch", WM8994_AIF1_ADC2_FILTERS, 12, 11, 1, 0), SOC_ENUM("AIF2ADC HPF Mode", aif2adc_hpf), SOC_DOUBLE("AIF2ADC HPF Switch", WM8994_AIF2_ADC_FILTERS, 12, 11, 1, 0), +SOC_ENUM("ADC OSR", adc_osr), +SOC_ENUM("DAC OSR", dac_osr), + SOC_DOUBLE_R_TLV("DAC1 Volume", WM8994_DAC1_LEFT_VOLUME, WM8994_DAC1_RIGHT_VOLUME, 1, 96, 0, digital_tlv), SOC_DOUBLE_R("DAC1 Switch", WM8994_DAC1_LEFT_VOLUME, -- cgit v1.2.3 From 1957668be903b2c98e1dfb295510850531eea135 Mon Sep 17 00:00:00 2001 From: Vasily Khoruzhick Date: Thu, 9 Dec 2010 21:17:56 +0200 Subject: ASoC: Add HP iPAQ H1940 support Add glue driver to make s3c24xx-i2s and uda1380 produce some sound on H1940. Signed-off-by: Vasily Khoruzhick Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/samsung/Kconfig | 8 ++ sound/soc/samsung/Makefile | 2 + sound/soc/samsung/h1940_uda1380.c | 296 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 306 insertions(+) create mode 100644 sound/soc/samsung/h1940_uda1380.c diff --git a/sound/soc/samsung/Kconfig b/sound/soc/samsung/Kconfig index eb45cf90d4e2..67cdad4ee535 100644 --- a/sound/soc/samsung/Kconfig +++ b/sound/soc/samsung/Kconfig @@ -116,6 +116,14 @@ config ASOC_SAMSUNG_SIMTEC_HERMES select SND_SOC_TLV320AIC3X select ASOC_SAMSUNG_SIMTEC +config ASOC_SAMSUNG_H1940_UDA1380 + tristate "Audio support for the HP iPAQ H1940" + depends on ASOC_SAMSUNG && ARCH_H1940 + select SND_S3C24XX_I2S + select SND_SOC_UDA1380 + help + This driver provides audio support for HP iPAQ h1940 PDA. + config ASOC_SAMSUNG_RX1950_UDA1380 tristate "Audio support for the HP iPAQ RX1950" depends on ASOC_SAMSUNG && MACH_RX1950 diff --git a/sound/soc/samsung/Makefile b/sound/soc/samsung/Makefile index 0d24f95c8b1c..622e76eb9775 100644 --- a/sound/soc/samsung/Makefile +++ b/sound/soc/samsung/Makefile @@ -27,6 +27,7 @@ snd-soc-s3c24xx-uda134x-objs := s3c24xx_uda134x.o snd-soc-s3c24xx-simtec-objs := s3c24xx_simtec.o snd-soc-s3c24xx-simtec-hermes-objs := s3c24xx_simtec_hermes.o snd-soc-s3c24xx-simtec-tlv320aic23-objs := s3c24xx_simtec_tlv320aic23.o +snd-soc-h1940-uda1380-objs := h1940_uda1380.o snd-soc-rx1950-uda1380-objs := rx1950_uda1380.o snd-soc-smdk-wm8580-objs := smdk_wm8580.o snd-soc-smdk-wm9713-objs := smdk_wm9713.o @@ -43,6 +44,7 @@ obj-$(CONFIG_ASOC_SAMSUNG_S3C24XX_UDA134X) += snd-soc-s3c24xx-uda134x.o obj-$(CONFIG_ASOC_SAMSUNG_SIMTEC) += snd-soc-s3c24xx-simtec.o obj-$(CONFIG_ASOC_SAMSUNG_SIMTEC_HERMES) += snd-soc-s3c24xx-simtec-hermes.o obj-$(CONFIG_ASOC_SAMSUNG_SIMTEC_TLV320AIC23) += snd-soc-s3c24xx-simtec-tlv320aic23.o +obj-$(CONFIG_ASOC_SAMSUNG_H1940_UDA1380) += snd-soc-h1940-uda1380.o obj-$(CONFIG_ASOC_SAMSUNG_RX1950_UDA1380) += snd-soc-rx1950-uda1380.o obj-$(CONFIG_ASOC_SAMSUNG_SMDK_WM8580) += snd-soc-smdk-wm8580.o obj-$(CONFIG_ASOC_SAMSUNG_SMDK_WM9713) += snd-soc-smdk-wm9713.o diff --git a/sound/soc/samsung/h1940_uda1380.c b/sound/soc/samsung/h1940_uda1380.c new file mode 100644 index 000000000000..c45f7ce14d61 --- /dev/null +++ b/sound/soc/samsung/h1940_uda1380.c @@ -0,0 +1,296 @@ +/* + * h1940-uda1380.c -- ALSA Soc Audio Layer + * + * Copyright (c) 2010 Arnaud Patard + * Copyright (c) 2010 Vasily Khoruzhick + * + * Based on version from Arnaud Patard + * + * 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. + * + */ + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include + +#include + +#include "dma.h" +#include "s3c24xx-i2s.h" +#include "../codecs/uda1380.h" + +static unsigned int rates[] = { + 11025, + 22050, + 44100, +}; + +static struct snd_pcm_hw_constraint_list hw_rates = { + .count = ARRAY_SIZE(rates), + .list = rates, + .mask = 0, +}; + +static struct snd_soc_jack hp_jack; + +static struct snd_soc_jack_pin hp_jack_pins[] = { + { + .pin = "Headphone Jack", + .mask = SND_JACK_HEADPHONE, + }, + { + .pin = "Speaker", + .mask = SND_JACK_HEADPHONE, + .invert = 1, + }, +}; + +static struct snd_soc_jack_gpio hp_jack_gpios[] = { + { + .gpio = S3C2410_GPG(4), + .name = "hp-gpio", + .report = SND_JACK_HEADPHONE, + .invert = 1, + .debounce_time = 200, + }, +}; + +static int h1940_startup(struct snd_pcm_substream *substream) +{ + struct snd_pcm_runtime *runtime = substream->runtime; + + runtime->hw.rate_min = hw_rates.list[0]; + runtime->hw.rate_max = hw_rates.list[hw_rates.count - 1]; + runtime->hw.rates = SNDRV_PCM_RATE_KNOT; + + return snd_pcm_hw_constraint_list(runtime, 0, + SNDRV_PCM_HW_PARAM_RATE, + &hw_rates); +} + +static int h1940_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + struct snd_soc_dai *codec_dai = rtd->codec_dai; + int div; + int ret; + unsigned int rate = params_rate(params); + + switch (rate) { + case 11025: + case 22050: + case 44100: + div = s3c24xx_i2s_get_clockrate() / (384 * rate); + if (s3c24xx_i2s_get_clockrate() % (384 * rate) > (192 * rate)) + div++; + break; + default: + dev_err(&rtd->dev, "%s: rate %d is not supported\n", + __func__, rate); + return -EINVAL; + } + + /* set codec DAI configuration */ + ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S | + SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); + if (ret < 0) + return ret; + + /* set cpu DAI configuration */ + ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S | + SND_SOC_DAIFMT_NB_NF | SND_SOC_DAIFMT_CBS_CFS); + if (ret < 0) + return ret; + + /* select clock source */ + ret = snd_soc_dai_set_sysclk(cpu_dai, S3C24XX_CLKSRC_PCLK, rate, + SND_SOC_CLOCK_OUT); + if (ret < 0) + return ret; + + /* set MCLK division for sample rate */ + ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C24XX_DIV_MCLK, + S3C2410_IISMOD_384FS); + if (ret < 0) + return ret; + + /* set BCLK division for sample rate */ + ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C24XX_DIV_BCLK, + S3C2410_IISMOD_32FS); + if (ret < 0) + return ret; + + /* set prescaler division for sample rate */ + ret = snd_soc_dai_set_clkdiv(cpu_dai, S3C24XX_DIV_PRESCALER, + S3C24XX_PRESCALE(div, div)); + if (ret < 0) + return ret; + + return 0; +} + +static struct snd_soc_ops h1940_ops = { + .startup = h1940_startup, + .hw_params = h1940_hw_params, +}; + +static int h1940_spk_power(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + if (SND_SOC_DAPM_EVENT_ON(event)) + gpio_set_value(H1940_LATCH_AUDIO_POWER, 1); + else + gpio_set_value(H1940_LATCH_AUDIO_POWER, 0); + + return 0; +} + +/* h1940 machine dapm widgets */ +static const struct snd_soc_dapm_widget uda1380_dapm_widgets[] = { + SND_SOC_DAPM_HP("Headphone Jack", NULL), + SND_SOC_DAPM_MIC("Mic Jack", NULL), + SND_SOC_DAPM_SPK("Speaker", h1940_spk_power), +}; + +/* h1940 machine audio_map */ +static const struct snd_soc_dapm_route audio_map[] = { + /* headphone connected to VOUTLHP, VOUTRHP */ + {"Headphone Jack", NULL, "VOUTLHP"}, + {"Headphone Jack", NULL, "VOUTRHP"}, + + /* ext speaker connected to VOUTL, VOUTR */ + {"Speaker", NULL, "VOUTL"}, + {"Speaker", NULL, "VOUTR"}, + + /* mic is connected to VINM */ + {"VINM", NULL, "Mic Jack"}, +}; + +static struct platform_device *s3c24xx_snd_device; + +static int h1940_uda1380_init(struct snd_soc_pcm_runtime *rtd) +{ + struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_dapm_context *dapm = &codec->dapm; + int err; + + /* Add h1940 specific widgets */ + err = snd_soc_dapm_new_controls(dapm, uda1380_dapm_widgets, + ARRAY_SIZE(uda1380_dapm_widgets)); + if (err) + return err; + + /* Set up h1940 specific audio path audio_mapnects */ + err = snd_soc_dapm_add_routes(dapm, audio_map, + ARRAY_SIZE(audio_map)); + if (err) + return err; + + snd_soc_dapm_enable_pin(dapm, "Headphone Jack"); + snd_soc_dapm_enable_pin(dapm, "Speaker"); + snd_soc_dapm_enable_pin(dapm, "Mic Jack"); + + snd_soc_dapm_sync(dapm); + + snd_soc_jack_new(codec, "Headphone Jack", SND_JACK_HEADPHONE, + &hp_jack); + + snd_soc_jack_add_pins(&hp_jack, ARRAY_SIZE(hp_jack_pins), + hp_jack_pins); + + snd_soc_jack_add_gpios(&hp_jack, ARRAY_SIZE(hp_jack_gpios), + hp_jack_gpios); + + return 0; +} + +/* s3c24xx digital audio interface glue - connects codec <--> CPU */ +static struct snd_soc_dai_link h1940_uda1380_dai[] = { + { + .name = "uda1380", + .stream_name = "UDA1380 Duplex", + .cpu_dai_name = "s3c24xx-iis", + .codec_dai_name = "uda1380-hifi", + .init = h1940_uda1380_init, + .platform_name = "samsung-audio", + .codec_name = "uda1380-codec.0-001a", + .ops = &h1940_ops, + }, +}; + +static struct snd_soc_card h1940_asoc = { + .name = "h1940", + .dai_link = h1940_uda1380_dai, + .num_links = ARRAY_SIZE(h1940_uda1380_dai), +}; + +static int __init h1940_init(void) +{ + int ret; + + if (!machine_is_h1940()) + return -ENODEV; + + /* configure some gpios */ + ret = gpio_request(H1940_LATCH_AUDIO_POWER, "speaker-power"); + if (ret) + goto err_out; + + ret = gpio_direction_output(H1940_LATCH_AUDIO_POWER, 0); + if (ret) + goto err_gpio; + + s3c24xx_snd_device = platform_device_alloc("soc-audio", -1); + if (!s3c24xx_snd_device) { + ret = -ENOMEM; + goto err_gpio; + } + + platform_set_drvdata(s3c24xx_snd_device, &h1940_asoc); + ret = platform_device_add(s3c24xx_snd_device); + + if (ret) + goto err_plat; + + return 0; + +err_plat: + platform_device_put(s3c24xx_snd_device); +err_gpio: + gpio_free(H1940_LATCH_AUDIO_POWER); + +err_out: + return ret; +} + +static void __exit h1940_exit(void) +{ + platform_device_unregister(s3c24xx_snd_device); + snd_soc_jack_free_gpios(&hp_jack, ARRAY_SIZE(hp_jack_gpios), + hp_jack_gpios); + gpio_free(H1940_LATCH_AUDIO_POWER); +} + +module_init(h1940_init); +module_exit(h1940_exit); + +/* Module information */ +MODULE_AUTHOR("Arnaud Patard, Vasily Khoruzhick"); +MODULE_DESCRIPTION("ALSA SoC H1940"); +MODULE_LICENSE("GPL"); -- cgit v1.2.3 From e91eb2ff1f713837caebbb86a06974cd4b3e8e46 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Fri, 10 Dec 2010 15:41:18 +0300 Subject: Staging: rtl8192u: add missing curly braces The if condition was ignored in the original code and we just used the default channel. Signed-off-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c index 12858880f95f..20f8c347cae4 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c @@ -509,9 +509,10 @@ void ieee80211_softmac_scan_wq(struct work_struct *work) if (watchdog++ > MAX_CHANNEL_NUMBER) { //if current channel is not in channel map, set to default channel. - if (!channel_map[ieee->current_network.channel]); + if (!channel_map[ieee->current_network.channel]) { ieee->current_network.channel = 6; goto out; /* no good chans */ + } } }while(!channel_map[ieee->current_network.channel]); if (ieee->scanning == 0 ) -- cgit v1.2.3 From bc657f6e9130108651915fe37624e47638c46e0f Mon Sep 17 00:00:00 2001 From: Mark Allyn Date: Fri, 10 Dec 2010 07:37:48 -0800 Subject: staging: sep: fix comments in sep_get_static_pool_addr_handler Original comments were inaccurate Signed-off-by: Mark Allyn Signed-off-by: Greg Kroah-Hartman --- drivers/staging/sep/sep_driver.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/staging/sep/sep_driver.c b/drivers/staging/sep/sep_driver.c index 2681fcf0c34d..ac5d56943d4b 100644 --- a/drivers/staging/sep/sep_driver.c +++ b/drivers/staging/sep/sep_driver.c @@ -2545,10 +2545,8 @@ static int sep_free_dma_tables_and_dcb(struct sep_device *sep, bool isapplet, /** * sep_get_static_pool_addr_handler - get static pool address * @sep: pointer to struct sep_device - * @arg: parameters from user space application * * This function sets the bus and virtual addresses of the static pool - * and returns the virtual address */ static int sep_get_static_pool_addr_handler(struct sep_device *sep) { @@ -3036,7 +3034,7 @@ static long sep_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) error = -EPERM; /* Not permitted on new chip */ break; case SEP_IOCGETSTATICPOOLADDR: - /* Get the physical and virtual addresses of the static pool */ + /* Inform the SEP the bus address of the static pool */ error = sep_get_static_pool_addr_handler(sep); break; case SEP_IOCENDTRANSACTION: -- cgit v1.2.3 From b8b739941eb57ec4c5fc87a73e7e7b554cf395fb Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 10 Dec 2010 10:46:30 -0800 Subject: Staging: cxt1e1: rename global log_level variable The driver should not have such a generic global variable name. Reported-by: Zimny Lech Cc: Bob Beers Signed-off-by: Greg Kroah-Hartman --- drivers/staging/cxt1e1/comet.c | 8 ++-- drivers/staging/cxt1e1/functions.c | 8 ++-- drivers/staging/cxt1e1/hwprobe.c | 4 +- drivers/staging/cxt1e1/linux.c | 18 ++++----- drivers/staging/cxt1e1/musycc.c | 58 ++++++++++++++-------------- drivers/staging/cxt1e1/pmcc4_drv.c | 38 +++++++++--------- drivers/staging/cxt1e1/sbecom_inline_linux.h | 4 +- 7 files changed, 69 insertions(+), 69 deletions(-) diff --git a/drivers/staging/cxt1e1/comet.c b/drivers/staging/cxt1e1/comet.c index dcbe6b628455..52224cdc967d 100644 --- a/drivers/staging/cxt1e1/comet.c +++ b/drivers/staging/cxt1e1/comet.c @@ -29,7 +29,7 @@ #endif -extern int log_level; +extern int cxt1e1_log_level; #define COMET_NUM_SAMPLES 24 /* Number of entries in the waveform table */ #define COMET_NUM_UNITS 5 /* Number of points per entry in table */ @@ -292,12 +292,12 @@ init_comet (void *ci, comet_t * comet, u_int32_t port_mode, int clockmaster, * i.e.FPMODE=0 (@0x20) */ if ((moreParams & CFG_CLK_PORT_MASK) == CFG_CLK_PORT_INTERNAL) { - if (log_level >= LOG_SBEBUG12) + if (cxt1e1_log_level >= LOG_SBEBUG12) pr_info(">> %s: clockmaster internal clock\n", __func__); pci_write_32 ((u_int32_t *) &comet->tx_time, 0x0d); /* internal oscillator */ } else /* external clock source */ { - if (log_level >= LOG_SBEBUG12) + if (cxt1e1_log_level >= LOG_SBEBUG12) pr_info(">> %s: clockmaster external clock\n", __func__); pci_write_32 ((u_int32_t *) &comet->tx_time, 0x09); /* loop timing * (external) */ @@ -312,7 +312,7 @@ init_comet (void *ci, comet_t * comet, u_int32_t port_mode, int clockmaster, pci_write_32 ((u_int32_t *) &comet->brif_cfg, 0x21); /* Slave Mode (CMODE=1) */ pci_write_32 ((u_int32_t *) &comet->brif_fpcfg, 0x20); /* Slave Mode i.e. * FPMODE=1 (@0x20) */ - if (log_level >= LOG_SBEBUG12) + if (cxt1e1_log_level >= LOG_SBEBUG12) pr_info(">> %s: clockslave internal clock\n", __func__); pci_write_32 ((u_int32_t *) &comet->tx_time, 0x0d); /* oscillator timing */ } diff --git a/drivers/staging/cxt1e1/functions.c b/drivers/staging/cxt1e1/functions.c index ab399c2f7488..d9a9aa3571d9 100644 --- a/drivers/staging/cxt1e1/functions.c +++ b/drivers/staging/cxt1e1/functions.c @@ -54,7 +54,7 @@ static int dummy = 0; #endif -extern int log_level; +extern int cxt1e1_log_level; extern int drvr_state; @@ -67,7 +67,7 @@ pci_read_32 (u_int32_t *p) FLUSH_PCI_READ (); v = le32_to_cpu (*p); - if (log_level >= LOG_DEBUG) + if (cxt1e1_log_level >= LOG_DEBUG) pr_info("pci_read : %x = %x\n", (u_int32_t) p, v); return v; #else @@ -80,7 +80,7 @@ void pci_write_32 (u_int32_t *p, u_int32_t v) { #ifdef FLOW_DEBUG - if (log_level >= LOG_DEBUG) + if (cxt1e1_log_level >= LOG_DEBUG) pr_info("pci_write: %x = %x\n", (u_int32_t) p, v); #endif *p = cpu_to_le32 (v); @@ -118,7 +118,7 @@ watchdog_func (unsigned long arg) if (drvr_state != SBE_DRVR_AVAILABLE) { - if (log_level >= LOG_MONITOR) + if (cxt1e1_log_level >= LOG_MONITOR) pr_warning("%s: drvr not available (%x)\n", __func__, drvr_state); return; } diff --git a/drivers/staging/cxt1e1/hwprobe.c b/drivers/staging/cxt1e1/hwprobe.c index 89200e7af26c..c517cc22f391 100644 --- a/drivers/staging/cxt1e1/hwprobe.c +++ b/drivers/staging/cxt1e1/hwprobe.c @@ -37,7 +37,7 @@ #define STATIC static #endif -extern int log_level; +extern int cxt1e1_log_level; extern int error_flag; extern int drvr_state; @@ -143,7 +143,7 @@ hdw_sn_get (hdw_info_t * hi, int brdno) if ((hi->promfmt = pmc_verify_cksum (&hi->mfg_info.data)) == PROM_FORMAT_Unk) { /* bad crc, data is suspect */ - if (log_level >= LOG_WARN) + if (cxt1e1_log_level >= LOG_WARN) pr_info("%s: EEPROM cksum error\n", hi->devname); hi->mfg_info_sts = EEPROM_CRCERR; } else diff --git a/drivers/staging/cxt1e1/linux.c b/drivers/staging/cxt1e1/linux.c index c7930287e3db..0f78f8962751 100644 --- a/drivers/staging/cxt1e1/linux.c +++ b/drivers/staging/cxt1e1/linux.c @@ -108,9 +108,9 @@ extern int unregister_hdlc_device_v7 (hdlc_device *); #endif int error_flag; /* module load error reporting */ -int log_level = LOG_ERROR; +int cxt1e1_log_level = LOG_ERROR; int log_level_default = LOG_ERROR; -module_param(log_level, int, 0444); +module_param(cxt1e1_log_level, int, 0444); int cxt1e1_max_mru = MUSYCC_MRU; int max_mru_default = MUSYCC_MRU; @@ -497,7 +497,7 @@ create_chan (struct net_device * ndev, ci_t * ci, rtnl_lock (); /* needed due to Ioctl calling sequence */ if (ret) { - if (log_level >= LOG_WARN) + if (cxt1e1_log_level >= LOG_WARN) pr_info("%s: create_chan[%d] registration error = %d.\n", ci->devname, cp->channum, ret); free_netdev (dev); /* cleanup */ @@ -722,11 +722,11 @@ do_get_chan_stats (struct net_device * ndev, void *data) STATIC status_t do_set_loglevel (struct net_device * ndev, void *data) { - unsigned int log_level; + unsigned int cxt1e1_log_level; - if (copy_from_user (&log_level, data, sizeof (int))) + if (copy_from_user (&cxt1e1_log_level, data, sizeof (int))) return -EFAULT; - sbecom_set_loglevel (log_level); + sbecom_set_loglevel (cxt1e1_log_level); return 0; } @@ -1115,9 +1115,9 @@ c4_mod_init (void) return -rtn; /* installation failure - see system log */ /* housekeeping notifications */ - if (log_level != log_level_default) - pr_info("NOTE: driver parameter changed from default %d to %d.\n", - log_level_default, log_level); + if (cxt1e1_log_level != log_level_default) + pr_info("NOTE: driver parameter changed from default %d to %d.\n", + log_level_default, cxt1e1_log_level); if (cxt1e1_max_mru != max_mru_default) pr_info("NOTE: driver parameter changed from default %d to %d.\n", max_mru_default, cxt1e1_max_mru); diff --git a/drivers/staging/cxt1e1/musycc.c b/drivers/staging/cxt1e1/musycc.c index fc15610f6974..f274c77fb3fc 100644 --- a/drivers/staging/cxt1e1/musycc.c +++ b/drivers/staging/cxt1e1/musycc.c @@ -97,7 +97,7 @@ char SBEid_pmcc4_musyccc[] = /* global driver variables */ extern ci_t *c4_list; extern int drvr_state; -extern int log_level; +extern int cxt1e1_log_level; extern int cxt1e1_max_mru; extern int cxt1e1_max_mtu; @@ -627,7 +627,7 @@ rewrite: if ((r != req) && (req != SR_CHIP_RESET) && (++rcnt <= MUSYCC_SR_RETRY_CNT)) { - if (log_level >= LOG_MONITOR) + if (cxt1e1_log_level >= LOG_MONITOR) pr_info("%s: %d - reissue srv req/last %x/%x (hdw reads %x), Chan %d.\n", pi->up->devname, rcnt, req, pi->sr_last, r, (pi->portnum * MUSYCC_NCHANS) + (req & 0x1f)); @@ -951,7 +951,7 @@ musycc_bh_tx_eom (mpi_t * pi, int gchan) ch = pi->chan[gchan]; if (ch == 0 || ch->state != UP) { - if (log_level >= LOG_ERROR) + if (cxt1e1_log_level >= LOG_ERROR) pr_info("%s: intr: xmit EOM on uninitialized channel %d\n", pi->up->devname, gchan); } @@ -1002,7 +1002,7 @@ musycc_bh_tx_eom (mpi_t * pi, int gchan) } if (status & MUSYCC_TX_OWNED) { - if (log_level >= LOG_MONITOR) + if (cxt1e1_log_level >= LOG_MONITOR) { pr_info("%s: Port %d Chan %2d - unexpected TX msg ownership intr (md %p sts %x)\n", pi->up->devname, pi->portnum, ch->channum, @@ -1016,7 +1016,7 @@ musycc_bh_tx_eom (mpi_t * pi, int gchan) break; /* Not our mdesc, done */ } else { - if (log_level >= LOG_MONITOR) + if (cxt1e1_log_level >= LOG_MONITOR) pr_info("%s: Port %d Chan %2d - recovered TX msg ownership [%d] (md %p sts %x)\n", pi->up->devname, pi->portnum, ch->channum, readCount, md, status); } @@ -1054,7 +1054,7 @@ musycc_bh_tx_eom (mpi_t * pi, int gchan) } md->status = 0; #ifdef RLD_TXFULL_DEBUG - if (log_level >= LOG_MONITOR2) + if (cxt1e1_log_level >= LOG_MONITOR2) pr_info("~~ tx_eom: tx_full %x txd_free %d -> %d\n", ch->tx_full, ch->txd_free, ch->txd_free + 1); #endif @@ -1063,7 +1063,7 @@ musycc_bh_tx_eom (mpi_t * pi, int gchan) if ((ch->p.chan_mode != CFG_CH_PROTO_TRANS) && (status & EOBIRQ_ENABLE)) { - if (log_level >= LOG_MONITOR) + if (cxt1e1_log_level >= LOG_MONITOR) pr_info("%s: Mode (%x) incorrect EOB status (%x)\n", pi->up->devname, ch->p.chan_mode, status); if ((status & EOMIRQ_ENABLE) == 0) @@ -1094,7 +1094,7 @@ musycc_bh_tx_eom (mpi_t * pi, int gchan) { #ifdef RLD_TXFULL_DEBUG - if (log_level >= LOG_MONITOR2) + if (cxt1e1_log_level >= LOG_MONITOR2) pr_info("tx_eom[%d]: enable xmit tx_full no more, txd_free %d txd_num/2 %d\n", ch->channum, ch->txd_free, ch->txd_num / 2); @@ -1108,7 +1108,7 @@ musycc_bh_tx_eom (mpi_t * pi, int gchan) #ifdef RLD_TXFULL_DEBUG else if (ch->tx_full) { - if (log_level >= LOG_MONITOR2) + if (cxt1e1_log_level >= LOG_MONITOR2) pr_info("tx_eom[%d]: bypass TX enable though room available? (txd_free %d txd_num/2 %d)\n", ch->channum, ch->txd_free, ch->txd_num / 2); @@ -1138,7 +1138,7 @@ musycc_bh_rx_eom (mpi_t * pi, int gchan) ch = pi->chan[gchan]; if (ch == 0 || ch->state != UP) { - if (log_level > LOG_ERROR) + if (cxt1e1_log_level > LOG_ERROR) pr_info("%s: intr: receive EOM on uninitialized channel %d\n", pi->up->devname, gchan); return; @@ -1269,7 +1269,7 @@ musycc_intr_th_handler (void *devp) if (nextInt != INTRPTS_NEXTINT (ci->intlog.this_status_new)) { - if (log_level >= LOG_MONITOR) + if (cxt1e1_log_level >= LOG_MONITOR) { pr_info("%s: note - updated ISD from %08x to %08x\n", ci->devname, status, @@ -1337,11 +1337,11 @@ musycc_intr_th_handler (void *devp) ci->intlog.last_status_new = ci->intlog.this_status_new; ci->intlog.this_status_new = currInt; - if ((log_level >= LOG_WARN) && (status & INTRPTS_INTFULL_M)) + if ((cxt1e1_log_level >= LOG_WARN) && (status & INTRPTS_INTFULL_M)) { pr_info("%s: Interrupt queue full condition occurred\n", ci->devname); } - if (log_level >= LOG_DEBUG) + if (cxt1e1_log_level >= LOG_DEBUG) pr_info("%s: interrupts pending, isd @ 0x%p: %x curr %d cnt %d NEXT %d\n", ci->devname, &ci->reg->isd, status, nextInt, intCnt, (intCnt + nextInt) & (INT_QUEUE_SIZE - 1)); @@ -1448,7 +1448,7 @@ musycc_intr_bh_tasklet (ci_t * ci) if ((currInt == badInt) || (currInt == badInt2)) /* catch failure of Bug * Fix checking */ { - if (log_level >= LOG_WARN) + if (cxt1e1_log_level >= LOG_WARN) pr_info("%s: Illegal Interrupt Detected @ 0x%p, mod %d.)\n", ci->devname, &ci->iqd_p[headx], headx); @@ -1483,7 +1483,7 @@ musycc_intr_bh_tasklet (ci_t * ci) ci->iqd_p[headx] = __constant_cpu_to_le32 (INT_EMPTY_ENTRY); FLUSH_MEM_WRITE (); - if (log_level >= LOG_DEBUG) + if (cxt1e1_log_level >= LOG_DEBUG) { if (err != 0) pr_info(" %08x -> err: %2d,", currInt, err); @@ -1497,7 +1497,7 @@ musycc_intr_bh_tasklet (ci_t * ci) switch (event) { case EVE_SACK: /* Service Request Acknowledge */ - if (log_level >= LOG_DEBUG) + if (cxt1e1_log_level >= LOG_DEBUG) { volatile u_int32_t r; @@ -1534,7 +1534,7 @@ musycc_intr_bh_tasklet (ci_t * ci) } break; default: - if (log_level >= LOG_WARN) + if (cxt1e1_log_level >= LOG_WARN) pr_info("%s: unexpected interrupt event: %d, iqd[%d]: %08x, port: %d\n", ci->devname, event, headx, currInt, group); break; @@ -1573,9 +1573,9 @@ musycc_intr_bh_tasklet (ci_t * ci) { #ifdef RLD_TRANS_DEBUG - if (1 || log_level >= LOG_MONITOR) + if (1 || cxt1e1_log_level >= LOG_MONITOR) #else - if (log_level >= LOG_MONITOR) + if (cxt1e1_log_level >= LOG_MONITOR) #endif { pr_info("%s: TX buffer underflow [ONR] on channel %d, mode %x QStopped %x free %d\n", @@ -1605,7 +1605,7 @@ musycc_intr_bh_tasklet (ci_t * ci) ch->s.rx_over_errors++; ch->ch_start_rx = CH_START_RX_ONR; - if (log_level >= LOG_WARN) + if (cxt1e1_log_level >= LOG_WARN) { pr_info("%s: RX buffer overflow [ONR] on channel %d, mode %x\n", ci->devname, ch->channum, ch->p.chan_mode); @@ -1623,7 +1623,7 @@ musycc_intr_bh_tasklet (ci_t * ci) * Per MUSYCC manual, Section 6.4.8.3 [Transmit Errors], * this BUFF error requires Transmit channel reactivation. */ - if (log_level >= LOG_MONITOR) + if (cxt1e1_log_level >= LOG_MONITOR) pr_info("%s: TX buffer underrun [BUFF] on channel %d, mode %x\n", ci->devname, ch->channum, ch->p.chan_mode); } else /* RX buffer overrun */ @@ -1636,7 +1636,7 @@ musycc_intr_bh_tasklet (ci_t * ci) * space for this channel. Receive channel reactivation is * not required, but data has been lost. */ - if (log_level >= LOG_WARN) + if (cxt1e1_log_level >= LOG_WARN) pr_info("%s: RX buffer overrun [BUFF] on channel %d, mode %x\n", ci->devname, ch->channum, ch->p.chan_mode); /* @@ -1658,7 +1658,7 @@ musycc_intr_bh_tasklet (ci_t * ci) } /* switch on err */ /* Check for interrupt lost condition */ - if ((currInt & INTRPT_ILOST_M) && (log_level >= LOG_ERROR)) + if ((currInt & INTRPT_ILOST_M) && (cxt1e1_log_level >= LOG_ERROR)) { pr_info("%s: Interrupt queue overflow - ILOST asserted\n", ci->devname); @@ -1667,7 +1667,7 @@ musycc_intr_bh_tasklet (ci_t * ci) FLUSH_MEM_WRITE (); FLUSH_MEM_READ (); } /* while */ - if ((log_level >= LOG_MONITOR2) && (ci->iqp_headx != ci->iqp_tailx)) + if ((cxt1e1_log_level >= LOG_MONITOR2) && (ci->iqp_headx != ci->iqp_tailx)) { int bh; @@ -1821,9 +1821,9 @@ musycc_start_xmit (ci_t * ci, int channum, void *mem_token) return EROFS; /* how else to flag unwritable state ? */ #ifdef RLD_TRANS_DEBUGx - if (1 || log_level >= LOG_MONITOR2) + if (1 || cxt1e1_log_level >= LOG_MONITOR2) #else - if (log_level >= LOG_MONITOR2) + if (cxt1e1_log_level >= LOG_MONITOR2) #endif { pr_info("++ start_xmt[%d]: state %x start %x full %d free %d required %d stopped %x\n", @@ -1846,7 +1846,7 @@ musycc_start_xmit (ci_t * ci, int channum, void *mem_token) if (txd_need_cnt == 0) { - if (log_level >= LOG_MONITOR2) + if (cxt1e1_log_level >= LOG_MONITOR2) pr_info("%s channel %d: no TX data in User buffer\n", ci->devname, channum); OS_mem_token_free (mem_token); return 0; /* no data to send */ @@ -1857,7 +1857,7 @@ musycc_start_xmit (ci_t * ci, int channum, void *mem_token) if (txd_need_cnt > ch->txd_num) /* never enough descriptors for this * large a buffer */ { - if (log_level >= LOG_DEBUG) + if (cxt1e1_log_level >= LOG_DEBUG) { pr_info("start_xmit: discarding buffer, insufficient descriptor cnt %d, need %d.\n", ch->txd_num, txd_need_cnt + 1); @@ -1874,7 +1874,7 @@ musycc_start_xmit (ci_t * ci, int channum, void *mem_token) /************************************************************/ if (txd_need_cnt > ch->txd_free) { - if (log_level >= LOG_MONITOR2) + if (cxt1e1_log_level >= LOG_MONITOR2) { pr_info("start_xmit[%d]: EBUSY - need more descriptors, have %d of %d need %d\n", channum, ch->txd_free, ch->txd_num, txd_need_cnt); diff --git a/drivers/staging/cxt1e1/pmcc4_drv.c b/drivers/staging/cxt1e1/pmcc4_drv.c index 5c8a3eb0cfc3..341e7a92f099 100644 --- a/drivers/staging/cxt1e1/pmcc4_drv.c +++ b/drivers/staging/cxt1e1/pmcc4_drv.c @@ -135,7 +135,7 @@ void musycc_serv_req (mpi_t *, u_int32_t); void musycc_update_timeslots (mpi_t *); extern void musycc_update_tx_thp (mch_t *); -extern int log_level; +extern int cxt1e1_log_level; extern int cxt1e1_max_mru; extern int cxt1e1_max_mtu; extern int max_rxdesc_used, max_rxdesc_default; @@ -168,12 +168,12 @@ sbecom_set_loglevel (int d) * for card 0 only */ } else { - if (log_level != d) + if (cxt1e1_log_level != d) { - pr_info("log level changed from %d to %d\n", log_level, d); - log_level = d; /* set new */ + pr_info("log level changed from %d to %d\n", cxt1e1_log_level, d); + cxt1e1_log_level = d; /* set new */ } else - pr_info("log level is %d\n", log_level); + pr_info("log level is %d\n", cxt1e1_log_level); } } @@ -513,7 +513,7 @@ checkPorts (ci_t * ci) if ((value == 0x1c) || (value == 0x19) || (value == 0x12)) c4_loop_port (ci, portnum, COMET_MDIAG_LBOFF); /* take port out of any * loopbk mode */ - if (log_level >= LOG_DEBUG) + if (cxt1e1_log_level >= LOG_DEBUG) if (value != 0x3f) pr_warning("%s: BOC value = %x on Port %d\n", ci->devname, value, portnum); @@ -533,7 +533,7 @@ c4_watchdog (ci_t * ci) { if (drvr_state != SBE_DRVR_AVAILABLE) { - if (log_level >= LOG_MONITOR) + if (cxt1e1_log_level >= LOG_MONITOR) pr_info("drvr not available (%x)\n", drvr_state); return; } @@ -794,19 +794,19 @@ c4_loop_port (ci_t * ci, int portnum, u_int8_t cmd) } pci_write_32 ((u_int32_t *) &comet->mdiag, cmd); - if (log_level >= LOG_WARN) + if (cxt1e1_log_level >= LOG_WARN) pr_info("%s: loopback mode changed to %2x from %2x on Port %d\n", ci->devname, cmd, loopValue, portnum); loopValue = pci_read_32 ((u_int32_t *) &comet->mdiag) & COMET_MDIAG_LBMASK; if (loopValue != cmd) { - if (log_level >= LOG_ERROR) + if (cxt1e1_log_level >= LOG_ERROR) pr_info("%s: write to loop register failed, unknown state for Port %d\n", ci->devname, portnum); } } else { - if (log_level >= LOG_WARN) + if (cxt1e1_log_level >= LOG_WARN) pr_info("%s: loopback already in that mode (%2x)\n", ci->devname, loopValue); } @@ -997,7 +997,7 @@ c4_set_port (ci_t * ci, int portnum) pi = &ci->port[portnum]; pp = &ci->port[portnum].p; e1mode = IS_FRAME_ANY_E1 (pp->port_mode); - if (log_level >= LOG_MONITOR2) + if (cxt1e1_log_level >= LOG_MONITOR2) { pr_info("%s: c4_set_port[%d]: entered, e1mode = %x, openchans %d.\n", ci->devname, @@ -1278,12 +1278,12 @@ c4_fifo_alloc (mpi_t * pi, int chan, int *len) } if (max != *len) { - if (log_level >= LOG_WARN) + if (cxt1e1_log_level >= LOG_WARN) pr_info("%s: wanted to allocate %d fifo space, but got only %d\n", pi->up->devname, *len, max); *len = max; } - if (log_level >= LOG_DEBUG) + if (cxt1e1_log_level >= LOG_DEBUG) pr_info("%s: allocated %d fifo at %d for channel %d/%d\n", pi->up->devname, max, start, chan, pi->p.portnum); for (i = maxstart; i < (maxstart + max); i++) @@ -1296,7 +1296,7 @@ c4_fifo_free (mpi_t * pi, int chan) { int i; - if (log_level >= LOG_DEBUG) + if (cxt1e1_log_level >= LOG_DEBUG) pr_info("%s: deallocated fifo for channel %d/%d\n", pi->up->devname, chan, pi->p.portnum); for (i = 0; i < 32; i++) @@ -1321,7 +1321,7 @@ c4_chan_up (ci_t * ci, int channum) return ENOENT; if (ch->state == UP) { - if (log_level >= LOG_MONITOR) + if (cxt1e1_log_level >= LOG_MONITOR) pr_info("%s: channel already UP, graceful early exit\n", ci->devname); return 0; @@ -1334,7 +1334,7 @@ c4_chan_up (ci_t * ci, int channum) { if (ch->p.bitmask[i] & pi->tsm[i]) { - if (1 || log_level >= LOG_WARN) + if (1 || cxt1e1_log_level >= LOG_WARN) { pr_info("%s: c4_chan_up[%d] EINVAL (attempt to cfg in-use or unavailable TimeSlot[%d])\n", ci->devname, channum, i); @@ -1351,7 +1351,7 @@ c4_chan_up (ci_t * ci, int channum) nbuf = nts / 8 ? nts / 8 : 1; if (!nbuf) { - /* if( log_level >= LOG_WARN) */ + /* if( cxt1e1_log_level >= LOG_WARN) */ pr_info("%s: c4_chan_up[%d] ENOBUFS (no TimeSlots assigned)\n", ci->devname, channum); return ENOBUFS; /* this should not happen */ @@ -1420,7 +1420,7 @@ c4_chan_up (ci_t * ci, int channum) #if 0 /* DEBUG INFO */ - if (log_level >= LOG_MONITOR) + if (cxt1e1_log_level >= LOG_MONITOR) pr_info("%s: mode %x rxnum %d (rxused %d def %d) txnum %d (txused %d def %d)\n", ci->devname, ch->p.chan_mode, rxnum, max_rxdesc_used, max_rxdesc_default, @@ -1451,7 +1451,7 @@ c4_chan_up (ci_t * ci, int channum) if (!(m = OS_mem_token_alloc (cxt1e1_max_mru))) { - if (log_level >= LOG_MONITOR) + if (cxt1e1_log_level >= LOG_MONITOR) pr_info("%s: c4_chan_up[%d] - token alloc failure, size = %d.\n", ci->devname, channum, cxt1e1_max_mru); goto errfree; diff --git a/drivers/staging/cxt1e1/sbecom_inline_linux.h b/drivers/staging/cxt1e1/sbecom_inline_linux.h index 5a72cb5cff42..501a331ded5b 100644 --- a/drivers/staging/cxt1e1/sbecom_inline_linux.h +++ b/drivers/staging/cxt1e1/sbecom_inline_linux.h @@ -86,7 +86,7 @@ pci_read_32 (u_int32_t *p) FLUSH_PCI_READ (); v = le32_to_cpu (*p); - if (log_level >= LOG_DEBUG) + if (cxt1e1_log_level >= LOG_DEBUG) pr_info("pci_read : %x = %x\n", (u_int32_t) p, v); return v; #else @@ -99,7 +99,7 @@ static inline void pci_write_32 (u_int32_t *p, u_int32_t v) { #ifdef FLOW_DEBUG - if (log_level >= LOG_DEBUG) + if (cxt1e1_log_level >= LOG_DEBUG) pr_info("pci_write: %x = %x\n", (u_int32_t) p, v); #endif *p = cpu_to_le32 (v); -- cgit v1.2.3 From 64d74c6cbe52fbec90ead8f3bf53bfb10a1540d5 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 10 Dec 2010 10:55:27 -0800 Subject: Staging: ft1000: fix world writable debugfs file You should not be able to write to a debugfs file from any user. Cc: Marek Belisko Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ft1000/ft1000-usb/ft1000_chdev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_chdev.c b/drivers/staging/ft1000/ft1000-usb/ft1000_chdev.c index da76f11a552f..e39809229d46 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_chdev.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_chdev.c @@ -173,7 +173,7 @@ int ft1000_create_dev(struct ft1000_device *dev) goto debug_dir_fail; } - file = debugfs_create_file("device", S_IRUGO | S_IWUGO, dir, + file = debugfs_create_file("device", S_IRUGO | S_IWUSR, dir, NULL, &ft1000fops); if (IS_ERR(file)) { result = PTR_ERR(file); -- cgit v1.2.3 From 983bbfd091be5b3e1a729f31cce29431fbff2d27 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 10 Dec 2010 10:56:18 -0800 Subject: Staging: iio: fix up world writable sysfs files. You should not be able to write to sysfs files from any user. Cc: Graf Yang Cc: Michael Hennerich Cc: Jonathan Cameron Cc: Mike Frysinger Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/resolver/ad2s1210.c | 28 ++++++++++++++-------------- drivers/staging/iio/sysfs.h | 2 +- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/drivers/staging/iio/resolver/ad2s1210.c b/drivers/staging/iio/resolver/ad2s1210.c index 34fb21aa8b07..c12f64cc40df 100644 --- a/drivers/staging/iio/resolver/ad2s1210.c +++ b/drivers/staging/iio/resolver/ad2s1210.c @@ -661,19 +661,19 @@ error_ret: static IIO_CONST_ATTR(description, "Variable Resolution, 10-Bit to 16Bit R/D\n\ Converter with Reference Oscillator"); -static IIO_DEVICE_ATTR(raw_io, S_IRUGO | S_IWUGO, +static IIO_DEVICE_ATTR(raw_io, S_IRUGO | S_IWUSR, ad2s1210_show_raw, ad2s1210_store_raw, 0); -static IIO_DEVICE_ATTR(reset, S_IWUGO, +static IIO_DEVICE_ATTR(reset, S_IWUSR, NULL, ad2s1210_store_softreset, 0); -static IIO_DEVICE_ATTR(fclkin, S_IRUGO | S_IWUGO, +static IIO_DEVICE_ATTR(fclkin, S_IRUGO | S_IWUSR, ad2s1210_show_fclkin, ad2s1210_store_fclkin, 0); -static IIO_DEVICE_ATTR(fexcit, S_IRUGO | S_IWUGO, +static IIO_DEVICE_ATTR(fexcit, S_IRUGO | S_IWUSR, ad2s1210_show_fexcit, ad2s1210_store_fexcit, 0); -static IIO_DEVICE_ATTR(control, S_IRUGO | S_IWUGO, +static IIO_DEVICE_ATTR(control, S_IRUGO | S_IWUSR, ad2s1210_show_control, ad2s1210_store_control, 0); -static IIO_DEVICE_ATTR(bits, S_IRUGO | S_IWUGO, +static IIO_DEVICE_ATTR(bits, S_IRUGO | S_IWUSR, ad2s1210_show_resolution, ad2s1210_store_resolution, 0); -static IIO_DEVICE_ATTR(fault, S_IRUGO | S_IWUGO, +static IIO_DEVICE_ATTR(fault, S_IRUGO | S_IWUSR, ad2s1210_show_fault, ad2s1210_clear_fault, 0); static IIO_DEVICE_ATTR(pos, S_IRUGO, ad2s1210_show_pos, NULL, 0); @@ -681,19 +681,19 @@ static IIO_DEVICE_ATTR(vel, S_IRUGO, ad2s1210_show_vel, NULL, 0); static IIO_DEVICE_ATTR(pos_vel, S_IRUGO, ad2s1210_show_pos_vel, NULL, 0); -static IIO_DEVICE_ATTR(los_thrd, S_IRUGO | S_IWUGO, +static IIO_DEVICE_ATTR(los_thrd, S_IRUGO | S_IWUSR, ad2s1210_show_reg, ad2s1210_store_reg, REG_LOS_THRD); -static IIO_DEVICE_ATTR(dos_ovr_thrd, S_IRUGO | S_IWUGO, +static IIO_DEVICE_ATTR(dos_ovr_thrd, S_IRUGO | S_IWUSR, ad2s1210_show_reg, ad2s1210_store_reg, REG_DOS_OVR_THRD); -static IIO_DEVICE_ATTR(dos_mis_thrd, S_IRUGO | S_IWUGO, +static IIO_DEVICE_ATTR(dos_mis_thrd, S_IRUGO | S_IWUSR, ad2s1210_show_reg, ad2s1210_store_reg, REG_DOS_MIS_THRD); -static IIO_DEVICE_ATTR(dos_rst_max_thrd, S_IRUGO | S_IWUGO, +static IIO_DEVICE_ATTR(dos_rst_max_thrd, S_IRUGO | S_IWUSR, ad2s1210_show_reg, ad2s1210_store_reg, REG_DOS_RST_MAX_THRD); -static IIO_DEVICE_ATTR(dos_rst_min_thrd, S_IRUGO | S_IWUGO, +static IIO_DEVICE_ATTR(dos_rst_min_thrd, S_IRUGO | S_IWUSR, ad2s1210_show_reg, ad2s1210_store_reg, REG_DOS_RST_MIN_THRD); -static IIO_DEVICE_ATTR(lot_high_thrd, S_IRUGO | S_IWUGO, +static IIO_DEVICE_ATTR(lot_high_thrd, S_IRUGO | S_IWUSR, ad2s1210_show_reg, ad2s1210_store_reg, REG_LOT_HIGH_THRD); -static IIO_DEVICE_ATTR(lot_low_thrd, S_IRUGO | S_IWUGO, +static IIO_DEVICE_ATTR(lot_low_thrd, S_IRUGO | S_IWUSR, ad2s1210_show_reg, ad2s1210_store_reg, REG_LOT_LOW_THRD); static struct attribute *ad2s1210_attributes[] = { diff --git a/drivers/staging/iio/sysfs.h b/drivers/staging/iio/sysfs.h index 18bdaac2509d..24b74ddcd083 100644 --- a/drivers/staging/iio/sysfs.h +++ b/drivers/staging/iio/sysfs.h @@ -111,7 +111,7 @@ struct iio_const_attr { * IIO_DEV_ATTR_RESET: resets the device **/ #define IIO_DEV_ATTR_RESET(_store) \ - IIO_DEVICE_ATTR(reset, S_IWUGO, NULL, _store, 0) + IIO_DEVICE_ATTR(reset, S_IWUSR, NULL, _store, 0) /** * IIO_CONST_ATTR_NAME - constant identifier -- cgit v1.2.3 From a6cea9655bfa821dbf53c6fffb9b2b99fe77367c Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Fri, 10 Dec 2010 13:26:31 +0200 Subject: ASoC: tlv320dac33: Power down digital parts, when not needed If the following scenario has been followed: 1. Enable analog bypass amixer sset 'Analog Left Bypass' on amixer sset 'Analog Right Bypass' on 2. Start playback aplay -fdat -d3 /dev/zero After the playback stopped (3 sec), and the soc timeout (5 sec), the digital parts of the codec will remain powered up. This means that the DAI clocks are continue to run, the oscillator remain operational, etc. Use the SND_SOC_DAPM_POST_PMD widget to get notification about the stopped stream, and power down the digital part of the codec. If the analog bypass is enabled, than the codec will remain in BIAS_ON level, and things will work correctly. In case, if the bypass is disabled, than the codec will fall to BIAS_STANDBY than to BIAS_OFF level, as it used to. The digital part of DAC33 is initialized at every stream start (DAPM_PRE:PRE_PMU event), so subsequent streams (within 5 sec) will have working DAI. When the codec is coming out from BIAS_OFF, the full power-up sequence followed by the same DAPM_PRE widget event will power up the digital part. Signed-off-by: Peter Ujfalusi Acked-by: Mark Brown Signed-off-by: Liam Girdwood --- sound/soc/codecs/tlv320dac33.c | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/tlv320dac33.c b/sound/soc/codecs/tlv320dac33.c index b3445b362e96..776ac80cc1a8 100644 --- a/sound/soc/codecs/tlv320dac33.c +++ b/sound/soc/codecs/tlv320dac33.c @@ -354,6 +354,21 @@ static inline void dac33_soft_power(struct snd_soc_codec *codec, int power) dac33_write(codec, DAC33_PWR_CTRL, reg); } +static inline void dac33_disable_digital(struct snd_soc_codec *codec) +{ + u8 reg; + + /* Stop the DAI clock */ + reg = dac33_read_reg_cache(codec, DAC33_SER_AUDIOIF_CTRL_B); + reg &= ~DAC33_BCLKON; + dac33_write(codec, DAC33_SER_AUDIOIF_CTRL_B, reg); + + /* Power down the Oscillator, and DACs */ + reg = dac33_read_reg_cache(codec, DAC33_PWR_CTRL); + reg &= ~(DAC33_OSCPDNB | DAC33_DACRPDNB | DAC33_DACLPDNB); + dac33_write(codec, DAC33_PWR_CTRL, reg); +} + static int dac33_hard_power(struct snd_soc_codec *codec, int power) { struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec); @@ -402,7 +417,7 @@ exit: return ret; } -static int playback_event(struct snd_soc_dapm_widget *w, +static int dac33_playback_event(struct snd_soc_dapm_widget *w, struct snd_kcontrol *kcontrol, int event) { struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(w->codec); @@ -414,6 +429,9 @@ static int playback_event(struct snd_soc_dapm_widget *w, dac33_prepare_chip(dac33->substream); } break; + case SND_SOC_DAPM_POST_PMD: + dac33_disable_digital(w->codec); + break; } return 0; } @@ -609,7 +627,8 @@ static const struct snd_soc_dapm_widget dac33_dapm_widgets[] = { SND_SOC_DAPM_SUPPLY("Right DAC Power", DAC33_RDAC_PWR_CTRL, 2, 0, NULL, 0), - SND_SOC_DAPM_PRE("Prepare Playback", playback_event), + SND_SOC_DAPM_PRE("Pre Playback", dac33_playback_event), + SND_SOC_DAPM_POST("Post Playback", dac33_playback_event), }; static const struct snd_soc_dapm_route audio_map[] = { -- cgit v1.2.3 From 6610e0893b8bc6f59b14fed7f089c5997f035f88 Mon Sep 17 00:00:00 2001 From: John Stultz Date: Thu, 23 Sep 2010 15:07:34 -0700 Subject: RTC: Rework RTC code to use timerqueue for events This patch reworks a large portion of the generic RTC code to in-effect virtualize the rtc interrupt code. The current RTC interface is very much a raw hardware interface. Via the proc, /dev/, or sysfs interfaces, applciations can set the hardware to trigger interrupts in one of three modes: AIE: Alarm interrupt UIE: Update interrupt (ie: once per second) PIE: Periodic interrupt (sub-second irqs) The problem with this interface is that it limits the RTC hardware so it can only be used by one application at a time. The purpose of this patch is to extend the RTC code so that we can multiplex multiple applications event needs onto a single RTC device. This is done by utilizing the timerqueue infrastructure to manage a list of events, which cause the RTC hardware to be programmed to fire an interrupt for the next event in the list. In order to preserve the functionality of the exsting proc,/dev/ and sysfs interfaces, we emulate the different interrupt modes as follows: AIE: We create a rtc_timer dedicated to AIE mode interrupts. There is only one per device, so we don't change existing interface semantics. UIE: Again, a dedicated rtc_timer, set for periodic mode, is used to emulate UIE interrupts. Again, only one per device. PIE: Since PIE mode interrupts fire faster then the RTC's clock read granularity, we emulate PIE mode interrupts using a hrtimer. Again, one per device. With this patch, the rtctest.c application in Documentation/rtc.txt passes fine on x86 hardware. However, there may very well still be bugs, so greatly I'd appreciate any feedback or testing! Signed-off-by: John Stultz LKML Reference: <1290136329-18291-4-git-send-email-john.stultz@linaro.org> Acked-by: Alessandro Zummo Reviewed-by: Thomas Gleixner CC: Alessandro Zummo CC: Thomas Gleixner CC: Richard Cochran --- drivers/rtc/class.c | 13 ++ drivers/rtc/interface.c | 574 +++++++++++++++++++++++++++++------------------- drivers/rtc/rtc-lib.c | 28 +++ include/linux/rtc.h | 43 +++- 4 files changed, 428 insertions(+), 230 deletions(-) diff --git a/drivers/rtc/class.c b/drivers/rtc/class.c index 565562ba6ac9..95d2b82762d6 100644 --- a/drivers/rtc/class.c +++ b/drivers/rtc/class.c @@ -16,6 +16,7 @@ #include #include #include +#include #include "rtc-core.h" @@ -152,6 +153,18 @@ struct rtc_device *rtc_device_register(const char *name, struct device *dev, spin_lock_init(&rtc->irq_task_lock); init_waitqueue_head(&rtc->irq_queue); + /* Init timerqueue */ + timerqueue_init_head(&rtc->timerqueue); + INIT_WORK(&rtc->irqwork, rtctimer_do_work); + /* Init aie timer */ + rtctimer_init(&rtc->aie_timer, rtc_aie_update_irq, (void *)rtc); + /* Init uie timer */ + rtctimer_init(&rtc->uie_rtctimer, rtc_uie_update_irq, (void *)rtc); + /* Init pie timer */ + hrtimer_init(&rtc->pie_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); + rtc->pie_timer.function = rtc_pie_update_irq; + rtc->pie_enabled = 0; + strlcpy(rtc->name, name, RTC_DEVICE_NAME_SIZE); dev_set_name(&rtc->dev, "rtc%d", id); diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c index a0c816238aa9..c81c50b497b7 100644 --- a/drivers/rtc/interface.c +++ b/drivers/rtc/interface.c @@ -14,15 +14,11 @@ #include #include #include +#include -int rtc_read_time(struct rtc_device *rtc, struct rtc_time *tm) +static int __rtc_read_time(struct rtc_device *rtc, struct rtc_time *tm) { int err; - - err = mutex_lock_interruptible(&rtc->ops_lock); - if (err) - return err; - if (!rtc->ops) err = -ENODEV; else if (!rtc->ops->read_time) @@ -31,7 +27,18 @@ int rtc_read_time(struct rtc_device *rtc, struct rtc_time *tm) memset(tm, 0, sizeof(struct rtc_time)); err = rtc->ops->read_time(rtc->dev.parent, tm); } + return err; +} + +int rtc_read_time(struct rtc_device *rtc, struct rtc_time *tm) +{ + int err; + err = mutex_lock_interruptible(&rtc->ops_lock); + if (err) + return err; + + err = __rtc_read_time(rtc, tm); mutex_unlock(&rtc->ops_lock); return err; } @@ -106,188 +113,54 @@ int rtc_set_mmss(struct rtc_device *rtc, unsigned long secs) } EXPORT_SYMBOL_GPL(rtc_set_mmss); -static int rtc_read_alarm_internal(struct rtc_device *rtc, struct rtc_wkalrm *alarm) +int rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) { int err; err = mutex_lock_interruptible(&rtc->ops_lock); if (err) return err; - - if (rtc->ops == NULL) - err = -ENODEV; - else if (!rtc->ops->read_alarm) - err = -EINVAL; - else { - memset(alarm, 0, sizeof(struct rtc_wkalrm)); - err = rtc->ops->read_alarm(rtc->dev.parent, alarm); - } - + alarm->enabled = rtc->aie_timer.enabled; + if (alarm->enabled) + alarm->time = rtc_ktime_to_tm(rtc->aie_timer.node.expires); mutex_unlock(&rtc->ops_lock); - return err; + + return 0; } +EXPORT_SYMBOL_GPL(rtc_read_alarm); -int rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) +int __rtc_set_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) { + struct rtc_time tm; + long now, scheduled; int err; - struct rtc_time before, now; - int first_time = 1; - unsigned long t_now, t_alm; - enum { none, day, month, year } missing = none; - unsigned days; - - /* The lower level RTC driver may return -1 in some fields, - * creating invalid alarm->time values, for reasons like: - * - * - The hardware may not be capable of filling them in; - * many alarms match only on time-of-day fields, not - * day/month/year calendar data. - * - * - Some hardware uses illegal values as "wildcard" match - * values, which non-Linux firmware (like a BIOS) may try - * to set up as e.g. "alarm 15 minutes after each hour". - * Linux uses only oneshot alarms. - * - * When we see that here, we deal with it by using values from - * a current RTC timestamp for any missing (-1) values. The - * RTC driver prevents "periodic alarm" modes. - * - * But this can be racey, because some fields of the RTC timestamp - * may have wrapped in the interval since we read the RTC alarm, - * which would lead to us inserting inconsistent values in place - * of the -1 fields. - * - * Reading the alarm and timestamp in the reverse sequence - * would have the same race condition, and not solve the issue. - * - * So, we must first read the RTC timestamp, - * then read the RTC alarm value, - * and then read a second RTC timestamp. - * - * If any fields of the second timestamp have changed - * when compared with the first timestamp, then we know - * our timestamp may be inconsistent with that used by - * the low-level rtc_read_alarm_internal() function. - * - * So, when the two timestamps disagree, we just loop and do - * the process again to get a fully consistent set of values. - * - * This could all instead be done in the lower level driver, - * but since more than one lower level RTC implementation needs it, - * then it's probably best best to do it here instead of there.. - */ - /* Get the "before" timestamp */ - err = rtc_read_time(rtc, &before); - if (err < 0) + err = rtc_valid_tm(&alarm->time); + if (err) return err; - do { - if (!first_time) - memcpy(&before, &now, sizeof(struct rtc_time)); - first_time = 0; - - /* get the RTC alarm values, which may be incomplete */ - err = rtc_read_alarm_internal(rtc, alarm); - if (err) - return err; - if (!alarm->enabled) - return 0; - - /* full-function RTCs won't have such missing fields */ - if (rtc_valid_tm(&alarm->time) == 0) - return 0; - - /* get the "after" timestamp, to detect wrapped fields */ - err = rtc_read_time(rtc, &now); - if (err < 0) - return err; - - /* note that tm_sec is a "don't care" value here: */ - } while ( before.tm_min != now.tm_min - || before.tm_hour != now.tm_hour - || before.tm_mon != now.tm_mon - || before.tm_year != now.tm_year); - - /* Fill in the missing alarm fields using the timestamp; we - * know there's at least one since alarm->time is invalid. - */ - if (alarm->time.tm_sec == -1) - alarm->time.tm_sec = now.tm_sec; - if (alarm->time.tm_min == -1) - alarm->time.tm_min = now.tm_min; - if (alarm->time.tm_hour == -1) - alarm->time.tm_hour = now.tm_hour; - - /* For simplicity, only support date rollover for now */ - if (alarm->time.tm_mday == -1) { - alarm->time.tm_mday = now.tm_mday; - missing = day; - } - if (alarm->time.tm_mon == -1) { - alarm->time.tm_mon = now.tm_mon; - if (missing == none) - missing = month; - } - if (alarm->time.tm_year == -1) { - alarm->time.tm_year = now.tm_year; - if (missing == none) - missing = year; - } - - /* with luck, no rollover is needed */ - rtc_tm_to_time(&now, &t_now); - rtc_tm_to_time(&alarm->time, &t_alm); - if (t_now < t_alm) - goto done; - - switch (missing) { + rtc_tm_to_time(&alarm->time, &scheduled); - /* 24 hour rollover ... if it's now 10am Monday, an alarm that - * that will trigger at 5am will do so at 5am Tuesday, which - * could also be in the next month or year. This is a common - * case, especially for PCs. - */ - case day: - dev_dbg(&rtc->dev, "alarm rollover: %s\n", "day"); - t_alm += 24 * 60 * 60; - rtc_time_to_tm(t_alm, &alarm->time); - break; - - /* Month rollover ... if it's the 31th, an alarm on the 3rd will - * be next month. An alarm matching on the 30th, 29th, or 28th - * may end up in the month after that! Many newer PCs support - * this type of alarm. + /* Make sure we're not setting alarms in the past */ + err = __rtc_read_time(rtc, &tm); + rtc_tm_to_time(&tm, &now); + if (scheduled <= now) + return -ETIME; + /* + * XXX - We just checked to make sure the alarm time is not + * in the past, but there is still a race window where if + * the is alarm set for the next second and the second ticks + * over right here, before we set the alarm. */ - case month: - dev_dbg(&rtc->dev, "alarm rollover: %s\n", "month"); - do { - if (alarm->time.tm_mon < 11) - alarm->time.tm_mon++; - else { - alarm->time.tm_mon = 0; - alarm->time.tm_year++; - } - days = rtc_month_days(alarm->time.tm_mon, - alarm->time.tm_year); - } while (days < alarm->time.tm_mday); - break; - - /* Year rollover ... easy except for leap years! */ - case year: - dev_dbg(&rtc->dev, "alarm rollover: %s\n", "year"); - do { - alarm->time.tm_year++; - } while (rtc_valid_tm(&alarm->time) != 0); - break; - - default: - dev_warn(&rtc->dev, "alarm rollover not handled\n"); - } -done: - return 0; + if (!rtc->ops) + err = -ENODEV; + else if (!rtc->ops->set_alarm) + err = -EINVAL; + else + err = rtc->ops->set_alarm(rtc->dev.parent, alarm); + + return err; } -EXPORT_SYMBOL_GPL(rtc_read_alarm); int rtc_set_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) { @@ -300,16 +173,18 @@ int rtc_set_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) err = mutex_lock_interruptible(&rtc->ops_lock); if (err) return err; - - if (!rtc->ops) - err = -ENODEV; - else if (!rtc->ops->set_alarm) - err = -EINVAL; - else - err = rtc->ops->set_alarm(rtc->dev.parent, alarm); - + if (rtc->aie_timer.enabled) { + rtctimer_remove(rtc, &rtc->aie_timer); + rtc->aie_timer.enabled = 0; + } + rtc->aie_timer.node.expires = rtc_tm_to_ktime(alarm->time); + rtc->aie_timer.period = ktime_set(0, 0); + if (alarm->enabled) { + rtc->aie_timer.enabled = 1; + rtctimer_enqueue(rtc, &rtc->aie_timer); + } mutex_unlock(&rtc->ops_lock); - return err; + return 0; } EXPORT_SYMBOL_GPL(rtc_set_alarm); @@ -319,6 +194,16 @@ int rtc_alarm_irq_enable(struct rtc_device *rtc, unsigned int enabled) if (err) return err; + if (rtc->aie_timer.enabled != enabled) { + if (enabled) { + rtc->aie_timer.enabled = 1; + rtctimer_enqueue(rtc, &rtc->aie_timer); + } else { + rtctimer_remove(rtc, &rtc->aie_timer); + rtc->aie_timer.enabled = 0; + } + } + if (!rtc->ops) err = -ENODEV; else if (!rtc->ops->alarm_irq_enable) @@ -337,52 +222,53 @@ int rtc_update_irq_enable(struct rtc_device *rtc, unsigned int enabled) if (err) return err; -#ifdef CONFIG_RTC_INTF_DEV_UIE_EMUL - if (enabled == 0 && rtc->uie_irq_active) { - mutex_unlock(&rtc->ops_lock); - return rtc_dev_update_irq_enable_emul(rtc, enabled); + /* make sure we're changing state */ + if (rtc->uie_rtctimer.enabled == enabled) + goto out; + + if (enabled) { + struct rtc_time tm; + ktime_t now, onesec; + + __rtc_read_time(rtc, &tm); + onesec = ktime_set(1, 0); + now = rtc_tm_to_ktime(tm); + rtc->uie_rtctimer.node.expires = ktime_add(now, onesec); + rtc->uie_rtctimer.period = ktime_set(1, 0); + rtc->uie_rtctimer.enabled = 1; + rtctimer_enqueue(rtc, &rtc->uie_rtctimer); + } else { + rtctimer_remove(rtc, &rtc->uie_rtctimer); + rtc->uie_rtctimer.enabled = 0; } -#endif - - if (!rtc->ops) - err = -ENODEV; - else if (!rtc->ops->update_irq_enable) - err = -EINVAL; - else - err = rtc->ops->update_irq_enable(rtc->dev.parent, enabled); +out: mutex_unlock(&rtc->ops_lock); - -#ifdef CONFIG_RTC_INTF_DEV_UIE_EMUL - /* - * Enable emulation if the driver did not provide - * the update_irq_enable function pointer or if returned - * -EINVAL to signal that it has been configured without - * interrupts or that are not available at the moment. - */ - if (err == -EINVAL) - err = rtc_dev_update_irq_enable_emul(rtc, enabled); -#endif return err; + } EXPORT_SYMBOL_GPL(rtc_update_irq_enable); + /** - * rtc_update_irq - report RTC periodic, alarm, and/or update irqs - * @rtc: the rtc device - * @num: how many irqs are being reported (usually one) - * @events: mask of RTC_IRQF with one or more of RTC_PF, RTC_AF, RTC_UF - * Context: any + * rtc_handle_legacy_irq - AIE, UIE and PIE event hook + * @rtc: pointer to the rtc device + * + * This function is called when an AIE, UIE or PIE mode interrupt + * has occured (or been emulated). + * + * Triggers the registered irq_task function callback. */ -void rtc_update_irq(struct rtc_device *rtc, - unsigned long num, unsigned long events) +static void rtc_handle_legacy_irq(struct rtc_device *rtc, int num, int mode) { unsigned long flags; + /* mark one irq of the appropriate mode */ spin_lock_irqsave(&rtc->irq_lock, flags); - rtc->irq_data = (rtc->irq_data + (num << 8)) | events; + rtc->irq_data = (rtc->irq_data + (num << 8)) | (RTC_IRQF|mode); spin_unlock_irqrestore(&rtc->irq_lock, flags); + /* call the task func */ spin_lock_irqsave(&rtc->irq_task_lock, flags); if (rtc->irq_task) rtc->irq_task->func(rtc->irq_task->private_data); @@ -391,6 +277,69 @@ void rtc_update_irq(struct rtc_device *rtc, wake_up_interruptible(&rtc->irq_queue); kill_fasync(&rtc->async_queue, SIGIO, POLL_IN); } + + +/** + * rtc_aie_update_irq - AIE mode rtctimer hook + * @private: pointer to the rtc_device + * + * This functions is called when the aie_timer expires. + */ +void rtc_aie_update_irq(void *private) +{ + struct rtc_device *rtc = (struct rtc_device *)private; + rtc_handle_legacy_irq(rtc, 1, RTC_AF); +} + + +/** + * rtc_uie_update_irq - UIE mode rtctimer hook + * @private: pointer to the rtc_device + * + * This functions is called when the uie_timer expires. + */ +void rtc_uie_update_irq(void *private) +{ + struct rtc_device *rtc = (struct rtc_device *)private; + rtc_handle_legacy_irq(rtc, 1, RTC_UF); +} + + +/** + * rtc_pie_update_irq - PIE mode hrtimer hook + * @timer: pointer to the pie mode hrtimer + * + * This function is used to emulate PIE mode interrupts + * using an hrtimer. This function is called when the periodic + * hrtimer expires. + */ +enum hrtimer_restart rtc_pie_update_irq(struct hrtimer *timer) +{ + struct rtc_device *rtc; + ktime_t period; + int count; + rtc = container_of(timer, struct rtc_device, pie_timer); + + period = ktime_set(0, NSEC_PER_SEC/rtc->irq_freq); + count = hrtimer_forward_now(timer, period); + + rtc_handle_legacy_irq(rtc, count, RTC_PF); + + return HRTIMER_RESTART; +} + +/** + * rtc_update_irq - Triggered when a RTC interrupt occurs. + * @rtc: the rtc device + * @num: how many irqs are being reported (usually one) + * @events: mask of RTC_IRQF with one or more of RTC_PF, RTC_AF, RTC_UF + * Context: any + */ +void rtc_update_irq(struct rtc_device *rtc, + unsigned long num, unsigned long events) +{ + schedule_work(&rtc->irqwork); +} EXPORT_SYMBOL_GPL(rtc_update_irq); static int __rtc_match(struct device *dev, void *data) @@ -477,18 +426,20 @@ int rtc_irq_set_state(struct rtc_device *rtc, struct rtc_task *task, int enabled int err = 0; unsigned long flags; - if (rtc->ops->irq_set_state == NULL) - return -ENXIO; - spin_lock_irqsave(&rtc->irq_task_lock, flags); if (rtc->irq_task != NULL && task == NULL) err = -EBUSY; if (rtc->irq_task != task) err = -EACCES; - spin_unlock_irqrestore(&rtc->irq_task_lock, flags); - if (err == 0) - err = rtc->ops->irq_set_state(rtc->dev.parent, enabled); + if (enabled) { + ktime_t period = ktime_set(0, NSEC_PER_SEC/rtc->irq_freq); + hrtimer_start(&rtc->pie_timer, period, HRTIMER_MODE_REL); + } else { + hrtimer_cancel(&rtc->pie_timer); + } + rtc->pie_enabled = enabled; + spin_unlock_irqrestore(&rtc->irq_task_lock, flags); return err; } @@ -509,21 +460,194 @@ int rtc_irq_set_freq(struct rtc_device *rtc, struct rtc_task *task, int freq) int err = 0; unsigned long flags; - if (rtc->ops->irq_set_freq == NULL) - return -ENXIO; - spin_lock_irqsave(&rtc->irq_task_lock, flags); if (rtc->irq_task != NULL && task == NULL) err = -EBUSY; if (rtc->irq_task != task) err = -EACCES; - spin_unlock_irqrestore(&rtc->irq_task_lock, flags); - if (err == 0) { - err = rtc->ops->irq_set_freq(rtc->dev.parent, freq); - if (err == 0) - rtc->irq_freq = freq; + rtc->irq_freq = freq; + if (rtc->pie_enabled) { + ktime_t period; + hrtimer_cancel(&rtc->pie_timer); + period = ktime_set(0, NSEC_PER_SEC/rtc->irq_freq); + hrtimer_start(&rtc->pie_timer, period, + HRTIMER_MODE_REL); + } } + spin_unlock_irqrestore(&rtc->irq_task_lock, flags); return err; } EXPORT_SYMBOL_GPL(rtc_irq_set_freq); + +/** + * rtctimer_enqueue - Adds a rtc_timer to the rtc_device timerqueue + * @rtc rtc device + * @timer timer being added. + * + * Enqueues a timer onto the rtc devices timerqueue and sets + * the next alarm event appropriately. + * + * Must hold ops_lock for proper serialization of timerqueue + */ +void rtctimer_enqueue(struct rtc_device *rtc, struct rtc_timer *timer) +{ + timerqueue_add(&rtc->timerqueue, &timer->node); + if (&timer->node == timerqueue_getnext(&rtc->timerqueue)) { + struct rtc_wkalrm alarm; + int err; + alarm.time = rtc_ktime_to_tm(timer->node.expires); + alarm.enabled = 1; + err = __rtc_set_alarm(rtc, &alarm); + if (err == -ETIME) + schedule_work(&rtc->irqwork); + } +} + +/** + * rtctimer_remove - Removes a rtc_timer from the rtc_device timerqueue + * @rtc rtc device + * @timer timer being removed. + * + * Removes a timer onto the rtc devices timerqueue and sets + * the next alarm event appropriately. + * + * Must hold ops_lock for proper serialization of timerqueue + */ +void rtctimer_remove(struct rtc_device *rtc, struct rtc_timer *timer) +{ + struct timerqueue_node *next = timerqueue_getnext(&rtc->timerqueue); + timerqueue_del(&rtc->timerqueue, &timer->node); + + if (next == &timer->node) { + struct rtc_wkalrm alarm; + int err; + next = timerqueue_getnext(&rtc->timerqueue); + if (!next) + return; + alarm.time = rtc_ktime_to_tm(next->expires); + alarm.enabled = 1; + err = __rtc_set_alarm(rtc, &alarm); + if (err == -ETIME) + schedule_work(&rtc->irqwork); + } +} + +/** + * rtctimer_do_work - Expires rtc timers + * @rtc rtc device + * @timer timer being removed. + * + * Expires rtc timers. Reprograms next alarm event if needed. + * Called via worktask. + * + * Serializes access to timerqueue via ops_lock mutex + */ +void rtctimer_do_work(struct work_struct *work) +{ + struct rtc_timer *timer; + struct timerqueue_node *next; + ktime_t now; + struct rtc_time tm; + + struct rtc_device *rtc = + container_of(work, struct rtc_device, irqwork); + + mutex_lock(&rtc->ops_lock); +again: + __rtc_read_time(rtc, &tm); + now = rtc_tm_to_ktime(tm); + while ((next = timerqueue_getnext(&rtc->timerqueue))) { + if (next->expires.tv64 > now.tv64) + break; + + /* expire timer */ + timer = container_of(next, struct rtc_timer, node); + timerqueue_del(&rtc->timerqueue, &timer->node); + timer->enabled = 0; + if (timer->task.func) + timer->task.func(timer->task.private_data); + + /* Re-add/fwd periodic timers */ + if (ktime_to_ns(timer->period)) { + timer->node.expires = ktime_add(timer->node.expires, + timer->period); + timer->enabled = 1; + timerqueue_add(&rtc->timerqueue, &timer->node); + } + } + + /* Set next alarm */ + if (next) { + struct rtc_wkalrm alarm; + int err; + alarm.time = rtc_ktime_to_tm(next->expires); + alarm.enabled = 1; + err = __rtc_set_alarm(rtc, &alarm); + if (err == -ETIME) + goto again; + } + + mutex_unlock(&rtc->ops_lock); +} + + +/* rtctimer_init - Initializes an rtc_timer + * @timer: timer to be intiialized + * @f: function pointer to be called when timer fires + * @data: private data passed to function pointer + * + * Kernel interface to initializing an rtc_timer. + */ +void rtctimer_init(struct rtc_timer *timer, void (*f)(void* p), void* data) +{ + timerqueue_init(&timer->node); + timer->enabled = 0; + timer->task.func = f; + timer->task.private_data = data; +} + +/* rtctimer_start - Sets an rtc_timer to fire in the future + * @ rtc: rtc device to be used + * @ timer: timer being set + * @ expires: time at which to expire the timer + * @ period: period that the timer will recur + * + * Kernel interface to set an rtc_timer + */ +int rtctimer_start(struct rtc_device *rtc, struct rtc_timer* timer, + ktime_t expires, ktime_t period) +{ + int ret = 0; + mutex_lock(&rtc->ops_lock); + if (timer->enabled) + rtctimer_remove(rtc, timer); + + timer->node.expires = expires; + timer->period = period; + + timer->enabled = 1; + rtctimer_enqueue(rtc, timer); + + mutex_unlock(&rtc->ops_lock); + return ret; +} + +/* rtctimer_cancel - Stops an rtc_timer + * @ rtc: rtc device to be used + * @ timer: timer being set + * + * Kernel interface to cancel an rtc_timer + */ +int rtctimer_cancel(struct rtc_device *rtc, struct rtc_timer* timer) +{ + int ret = 0; + mutex_lock(&rtc->ops_lock); + if (timer->enabled) + rtctimer_remove(rtc, timer); + timer->enabled = 0; + mutex_unlock(&rtc->ops_lock); + return ret; +} + + diff --git a/drivers/rtc/rtc-lib.c b/drivers/rtc/rtc-lib.c index 773851f338b8..075f1708deae 100644 --- a/drivers/rtc/rtc-lib.c +++ b/drivers/rtc/rtc-lib.c @@ -117,4 +117,32 @@ int rtc_tm_to_time(struct rtc_time *tm, unsigned long *time) } EXPORT_SYMBOL(rtc_tm_to_time); +/* + * Convert rtc_time to ktime + */ +ktime_t rtc_tm_to_ktime(struct rtc_time tm) +{ + time_t time; + rtc_tm_to_time(&tm, &time); + return ktime_set(time, 0); +} +EXPORT_SYMBOL_GPL(rtc_tm_to_ktime); + +/* + * Convert ktime to rtc_time + */ +struct rtc_time rtc_ktime_to_tm(ktime_t kt) +{ + struct timespec ts; + struct rtc_time ret; + + ts = ktime_to_timespec(kt); + /* Round up any ns */ + if (ts.tv_nsec) + ts.tv_sec++; + rtc_time_to_tm(ts.tv_sec, &ret); + return ret; +} +EXPORT_SYMBOL_GPL(rtc_ktime_to_tm); + MODULE_LICENSE("GPL"); diff --git a/include/linux/rtc.h b/include/linux/rtc.h index 14dbc83ded20..a3421abca703 100644 --- a/include/linux/rtc.h +++ b/include/linux/rtc.h @@ -107,12 +107,17 @@ extern int rtc_year_days(unsigned int day, unsigned int month, unsigned int year extern int rtc_valid_tm(struct rtc_time *tm); extern int rtc_tm_to_time(struct rtc_time *tm, unsigned long *time); extern void rtc_time_to_tm(unsigned long time, struct rtc_time *tm); +ktime_t rtc_tm_to_ktime(struct rtc_time tm); +struct rtc_time rtc_ktime_to_tm(ktime_t kt); + #include #include #include #include #include +#include +#include extern struct class *rtc_class; @@ -151,7 +156,19 @@ struct rtc_class_ops { }; #define RTC_DEVICE_NAME_SIZE 20 -struct rtc_task; +typedef struct rtc_task { + void (*func)(void *private_data); + void *private_data; +} rtc_task_t; + + +struct rtc_timer { + struct rtc_task task; + struct timerqueue_node node; + ktime_t period; + int enabled; +}; + /* flags */ #define RTC_DEV_BUSY 0 @@ -179,6 +196,15 @@ struct rtc_device spinlock_t irq_task_lock; int irq_freq; int max_user_freq; + + struct timerqueue_head timerqueue; + struct rtc_timer aie_timer; + struct rtc_timer uie_rtctimer; + struct hrtimer pie_timer; /* sub second exp, so needs hrtimer */ + int pie_enabled; + struct work_struct irqwork; + + #ifdef CONFIG_RTC_INTF_DEV_UIE_EMUL struct work_struct uie_task; struct timer_list uie_timer; @@ -224,15 +250,22 @@ extern int rtc_alarm_irq_enable(struct rtc_device *rtc, unsigned int enabled); extern int rtc_dev_update_irq_enable_emul(struct rtc_device *rtc, unsigned int enabled); -typedef struct rtc_task { - void (*func)(void *private_data); - void *private_data; -} rtc_task_t; +void rtc_aie_update_irq(void *private); +void rtc_uie_update_irq(void *private); +enum hrtimer_restart rtc_pie_update_irq(struct hrtimer *timer); int rtc_register(rtc_task_t *task); int rtc_unregister(rtc_task_t *task); int rtc_control(rtc_task_t *t, unsigned int cmd, unsigned long arg); +void rtctimer_enqueue(struct rtc_device *rtc, struct rtc_timer *timer); +void rtctimer_remove(struct rtc_device *rtc, struct rtc_timer *timer); +void rtctimer_init(struct rtc_timer *timer, void (*f)(void* p), void* data); +int rtctimer_start(struct rtc_device *rtc, struct rtc_timer* timer, + ktime_t expires, ktime_t period); +int rtctimer_cancel(struct rtc_device *rtc, struct rtc_timer* timer); +void rtctimer_do_work(struct work_struct *work); + static inline bool is_leap_year(unsigned int year) { return (!(year % 4) && (year % 100)) || !(year % 400); -- cgit v1.2.3 From 042620a018afcfba1d678062b62e463b9e43a68d Mon Sep 17 00:00:00 2001 From: John Stultz Date: Thu, 14 Oct 2010 16:22:33 -0700 Subject: RTC: Remove UIE emulation Since we provide UIE interrupts via a rtc_timer, the old emulation code can be removed. Signed-off-by: John Stultz LKML Reference: <1290136329-18291-5-git-send-email-john.stultz@linaro.org> Acked-by: Alessandro Zummo Reviewed-by: Thomas Gleixner CC: Alessandro Zummo CC: Thomas Gleixner CC: Richard Cochran --- drivers/rtc/rtc-dev.c | 104 -------------------------------------------------- include/linux/rtc.h | 12 ------ 2 files changed, 116 deletions(-) diff --git a/drivers/rtc/rtc-dev.c b/drivers/rtc/rtc-dev.c index 62227cd52410..212b16edafc0 100644 --- a/drivers/rtc/rtc-dev.c +++ b/drivers/rtc/rtc-dev.c @@ -46,105 +46,6 @@ static int rtc_dev_open(struct inode *inode, struct file *file) return err; } -#ifdef CONFIG_RTC_INTF_DEV_UIE_EMUL -/* - * Routine to poll RTC seconds field for change as often as possible, - * after first RTC_UIE use timer to reduce polling - */ -static void rtc_uie_task(struct work_struct *work) -{ - struct rtc_device *rtc = - container_of(work, struct rtc_device, uie_task); - struct rtc_time tm; - int num = 0; - int err; - - err = rtc_read_time(rtc, &tm); - - spin_lock_irq(&rtc->irq_lock); - if (rtc->stop_uie_polling || err) { - rtc->uie_task_active = 0; - } else if (rtc->oldsecs != tm.tm_sec) { - num = (tm.tm_sec + 60 - rtc->oldsecs) % 60; - rtc->oldsecs = tm.tm_sec; - rtc->uie_timer.expires = jiffies + HZ - (HZ/10); - rtc->uie_timer_active = 1; - rtc->uie_task_active = 0; - add_timer(&rtc->uie_timer); - } else if (schedule_work(&rtc->uie_task) == 0) { - rtc->uie_task_active = 0; - } - spin_unlock_irq(&rtc->irq_lock); - if (num) - rtc_update_irq(rtc, num, RTC_UF | RTC_IRQF); -} -static void rtc_uie_timer(unsigned long data) -{ - struct rtc_device *rtc = (struct rtc_device *)data; - unsigned long flags; - - spin_lock_irqsave(&rtc->irq_lock, flags); - rtc->uie_timer_active = 0; - rtc->uie_task_active = 1; - if ((schedule_work(&rtc->uie_task) == 0)) - rtc->uie_task_active = 0; - spin_unlock_irqrestore(&rtc->irq_lock, flags); -} - -static int clear_uie(struct rtc_device *rtc) -{ - spin_lock_irq(&rtc->irq_lock); - if (rtc->uie_irq_active) { - rtc->stop_uie_polling = 1; - if (rtc->uie_timer_active) { - spin_unlock_irq(&rtc->irq_lock); - del_timer_sync(&rtc->uie_timer); - spin_lock_irq(&rtc->irq_lock); - rtc->uie_timer_active = 0; - } - if (rtc->uie_task_active) { - spin_unlock_irq(&rtc->irq_lock); - flush_scheduled_work(); - spin_lock_irq(&rtc->irq_lock); - } - rtc->uie_irq_active = 0; - } - spin_unlock_irq(&rtc->irq_lock); - return 0; -} - -static int set_uie(struct rtc_device *rtc) -{ - struct rtc_time tm; - int err; - - err = rtc_read_time(rtc, &tm); - if (err) - return err; - spin_lock_irq(&rtc->irq_lock); - if (!rtc->uie_irq_active) { - rtc->uie_irq_active = 1; - rtc->stop_uie_polling = 0; - rtc->oldsecs = tm.tm_sec; - rtc->uie_task_active = 1; - if (schedule_work(&rtc->uie_task) == 0) - rtc->uie_task_active = 0; - } - rtc->irq_data = 0; - spin_unlock_irq(&rtc->irq_lock); - return 0; -} - -int rtc_dev_update_irq_enable_emul(struct rtc_device *rtc, unsigned int enabled) -{ - if (enabled) - return set_uie(rtc); - else - return clear_uie(rtc); -} -EXPORT_SYMBOL(rtc_dev_update_irq_enable_emul); - -#endif /* CONFIG_RTC_INTF_DEV_UIE_EMUL */ static ssize_t rtc_dev_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) @@ -493,11 +394,6 @@ void rtc_dev_prepare(struct rtc_device *rtc) rtc->dev.devt = MKDEV(MAJOR(rtc_devt), rtc->id); -#ifdef CONFIG_RTC_INTF_DEV_UIE_EMUL - INIT_WORK(&rtc->uie_task, rtc_uie_task); - setup_timer(&rtc->uie_timer, rtc_uie_timer, (unsigned long)rtc); -#endif - cdev_init(&rtc->char_dev, &rtc_dev_fops); rtc->char_dev.owner = rtc->owner; } diff --git a/include/linux/rtc.h b/include/linux/rtc.h index a3421abca703..44e18a2523a3 100644 --- a/include/linux/rtc.h +++ b/include/linux/rtc.h @@ -203,18 +203,6 @@ struct rtc_device struct hrtimer pie_timer; /* sub second exp, so needs hrtimer */ int pie_enabled; struct work_struct irqwork; - - -#ifdef CONFIG_RTC_INTF_DEV_UIE_EMUL - struct work_struct uie_task; - struct timer_list uie_timer; - /* Those fields are protected by rtc->irq_lock */ - unsigned int oldsecs; - unsigned int uie_irq_active:1; - unsigned int stop_uie_polling:1; - unsigned int uie_task_active:1; - unsigned int uie_timer_active:1; -#endif }; #define to_rtc_device(d) container_of(d, struct rtc_device, dev) -- cgit v1.2.3 From 460f4aae8f9c6e414f17bfaaf9b89942ed5984a6 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 10 Dec 2010 18:42:58 +0000 Subject: ASoC: Implement WM8903 high pass filter support Signed-off-by: Mark Brown Acked-by: Liam Girdwood --- sound/soc/codecs/wm8903.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c index 620793e51666..797992c09342 100644 --- a/sound/soc/codecs/wm8903.c +++ b/sound/soc/codecs/wm8903.c @@ -474,6 +474,13 @@ static const DECLARE_TLV_DB_SCALE(drc_tlv_min, 0, 600, 0); static const DECLARE_TLV_DB_SCALE(drc_tlv_max, 1200, 600, 0); static const DECLARE_TLV_DB_SCALE(drc_tlv_startup, -300, 50, 0); +static const char *hpf_mode_text[] = { + "Hi-fi", "Voice 1", "Voice 2", "Voice 3" +}; + +static const struct soc_enum hpf_mode = + SOC_ENUM_SINGLE(WM8903_ADC_DIGITAL_0, 5, 4, hpf_mode_text); + static const char *drc_slope_text[] = { "1", "1/2", "1/4", "1/8", "1/16", "0" }; @@ -612,6 +619,8 @@ SOC_SINGLE("Right Input PGA Common Mode Switch", WM8903_ANALOGUE_RIGHT_INPUT_1, 6, 1, 0), /* ADCs */ +SOC_SINGLE("HPF Switch", WM8903_ADC_DIGITAL_0, 4, 1, 0), +SOC_ENUM("HPF Mode", hpf_mode), SOC_SINGLE("DRC Switch", WM8903_DRC_0, 15, 1, 0), SOC_ENUM("DRC Compressor Slope R0", drc_slope_r0), SOC_ENUM("DRC Compressor Slope R1", drc_slope_r1), -- cgit v1.2.3 From dcf9ada3bce67feab4482845f5e8e78fd278a176 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 10 Dec 2010 19:17:06 +0000 Subject: ASoC: Implement WM8903 oversampling rate controls Signed-off-by: Mark Brown Acked-by: Liam Girdwood --- sound/soc/codecs/wm8903.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c index 797992c09342..542c7c4868ba 100644 --- a/sound/soc/codecs/wm8903.c +++ b/sound/soc/codecs/wm8903.c @@ -481,6 +481,16 @@ static const char *hpf_mode_text[] = { static const struct soc_enum hpf_mode = SOC_ENUM_SINGLE(WM8903_ADC_DIGITAL_0, 5, 4, hpf_mode_text); +static const char *osr_text[] = { + "Low power", "High performance" +}; + +static const struct soc_enum adc_osr = + SOC_ENUM_SINGLE(WM8903_ANALOGUE_ADC_0, 0, 2, osr_text); + +static const struct soc_enum dac_osr = + SOC_ENUM_SINGLE(WM8903_DAC_DIGITAL_1, 0, 2, osr_text); + static const char *drc_slope_text[] = { "1", "1/2", "1/4", "1/8", "1/16", "0" }; @@ -619,6 +629,7 @@ SOC_SINGLE("Right Input PGA Common Mode Switch", WM8903_ANALOGUE_RIGHT_INPUT_1, 6, 1, 0), /* ADCs */ +SOC_ENUM("ADC OSR", adc_osr), SOC_SINGLE("HPF Switch", WM8903_ADC_DIGITAL_0, 4, 1, 0), SOC_ENUM("HPF Mode", hpf_mode), SOC_SINGLE("DRC Switch", WM8903_DRC_0, 15, 1, 0), @@ -650,6 +661,7 @@ SOC_DOUBLE_TLV("Digital Sidetone Volume", WM8903_DAC_DIGITAL_0, 4, 8, 12, 0, digital_sidetone_tlv), /* DAC */ +SOC_ENUM("DAC OSR", dac_osr), SOC_DOUBLE_R_TLV("Digital Playback Volume", WM8903_DAC_DIGITAL_VOLUME_LEFT, WM8903_DAC_DIGITAL_VOLUME_RIGHT, 1, 120, 0, digital_tlv), SOC_ENUM("DAC Soft Mute Rate", soft_mute), -- cgit v1.2.3 From f2c1fe090093ed62271473342f093df53c4f8a59 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 10 Dec 2010 19:17:07 +0000 Subject: ASoC: Remove open coded symmetry implementation from WM8903 We're already flagged as using symmetric rates so we don't need to have a custom implementation. Signed-off-by: Mark Brown Acked-by: Liam Girdwood --- sound/soc/codecs/wm8903.c | 79 +---------------------------------------------- 1 file changed, 1 insertion(+), 78 deletions(-) diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c index 542c7c4868ba..f9ae403715c6 100644 --- a/sound/soc/codecs/wm8903.c +++ b/sound/soc/codecs/wm8903.c @@ -218,10 +218,8 @@ struct wm8903_priv { int sysclk; int irq; - /* Reference counts */ + /* Reference count */ int class_w_users; - int playback_active; - int capture_active; struct completion wseq; @@ -230,9 +228,6 @@ struct wm8903_priv { int mic_short; int mic_last_report; int mic_delay; - - struct snd_pcm_substream *master_substream; - struct snd_pcm_substream *slave_substream; }; static int wm8903_volatile_register(unsigned int reg) @@ -1243,58 +1238,6 @@ static struct { { 0, 0 }, }; -static int wm8903_startup(struct snd_pcm_substream *substream, - struct snd_soc_dai *dai) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_codec *codec = rtd->codec; - struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec); - struct snd_pcm_runtime *master_runtime; - - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - wm8903->playback_active++; - else - wm8903->capture_active++; - - /* The DAI has shared clocks so if we already have a playback or - * capture going then constrain this substream to match it. - */ - if (wm8903->master_substream) { - master_runtime = wm8903->master_substream->runtime; - - dev_dbg(codec->dev, "Constraining to %d bits\n", - master_runtime->sample_bits); - - snd_pcm_hw_constraint_minmax(substream->runtime, - SNDRV_PCM_HW_PARAM_SAMPLE_BITS, - master_runtime->sample_bits, - master_runtime->sample_bits); - - wm8903->slave_substream = substream; - } else - wm8903->master_substream = substream; - - return 0; -} - -static void wm8903_shutdown(struct snd_pcm_substream *substream, - struct snd_soc_dai *dai) -{ - struct snd_soc_pcm_runtime *rtd = substream->private_data; - struct snd_soc_codec *codec = rtd->codec; - struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec); - - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - wm8903->playback_active--; - else - wm8903->capture_active--; - - if (wm8903->master_substream == substream) - wm8903->master_substream = wm8903->slave_substream; - - wm8903->slave_substream = NULL; -} - static int wm8903_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) @@ -1319,11 +1262,6 @@ static int wm8903_hw_params(struct snd_pcm_substream *substream, u16 clock1 = snd_soc_read(codec, WM8903_CLOCK_RATES_1); u16 dac_digital1 = snd_soc_read(codec, WM8903_DAC_DIGITAL_1); - if (substream == wm8903->slave_substream) { - dev_dbg(codec->dev, "Ignoring hw_params for slave substream\n"); - return 0; - } - /* Enable sloping stopband filter for low sample rates */ if (fs <= 24000) dac_digital1 |= WM8903_DAC_SB_FILT; @@ -1341,19 +1279,6 @@ static int wm8903_hw_params(struct snd_pcm_substream *substream, } } - /* Constraints should stop us hitting this but let's make sure */ - if (wm8903->capture_active) - switch (sample_rates[dsp_config].rate) { - case 88200: - case 96000: - dev_err(codec->dev, "%dHz unsupported by ADC\n", - fs); - return -EINVAL; - - default: - break; - } - dev_dbg(codec->dev, "DSP fs = %dHz\n", sample_rates[dsp_config].rate); clock1 &= ~WM8903_SAMPLE_RATE_MASK; clock1 |= sample_rates[dsp_config].value; @@ -1592,8 +1517,6 @@ static irqreturn_t wm8903_irq(int irq, void *data) SNDRV_PCM_FMTBIT_S24_LE) static struct snd_soc_dai_ops wm8903_dai_ops = { - .startup = wm8903_startup, - .shutdown = wm8903_shutdown, .hw_params = wm8903_hw_params, .digital_mute = wm8903_digital_mute, .set_fmt = wm8903_set_dai_fmt, -- cgit v1.2.3 From 69fff9bbbc4d214ed22c8f89681af3871a128e35 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 10 Dec 2010 19:17:08 +0000 Subject: ASoC: Automatically manage WM8903 deemphasis rate Provide the user with a boolean control then automatically select the deemphasis filter most closely matching the sample rate. Signed-off-by: Mark Brown Acked-by: Liam Girdwood --- sound/soc/codecs/wm8903.c | 82 ++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 74 insertions(+), 8 deletions(-) diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c index f9ae403715c6..d015745a886b 100644 --- a/sound/soc/codecs/wm8903.c +++ b/sound/soc/codecs/wm8903.c @@ -218,6 +218,9 @@ struct wm8903_priv { int sysclk; int irq; + int fs; + int deemph; + /* Reference count */ int class_w_users; @@ -457,6 +460,72 @@ static int wm8903_class_w_put(struct snd_kcontrol *kcontrol, .private_value = SOC_SINGLE_VALUE(reg, shift, max, invert) } +static int wm8903_deemph[] = { 0, 32000, 44100, 48000 }; + +static int wm8903_set_deemph(struct snd_soc_codec *codec) +{ + struct wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec); + int val, i, best; + + /* If we're using deemphasis select the nearest available sample + * rate. + */ + if (wm8903->deemph) { + best = 1; + for (i = 2; i < ARRAY_SIZE(wm8903_deemph); i++) { + if (abs(wm8903_deemph[i] - wm8903->fs) < + abs(wm8903_deemph[best] - wm8903->fs)) + best = i; + } + + val = best << WM8903_DEEMPH_SHIFT; + } else { + best = 0; + val = 0; + } + + dev_dbg(codec->dev, "Set deemphasis %d (%dHz)\n", + best, wm8903_deemph[best]); + + return snd_soc_update_bits(codec, WM8903_DAC_DIGITAL_1, + WM8903_DEEMPH_MASK, val); +} + +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 wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec); + + ucontrol->value.enumerated.item[0] = wm8903->deemph; + + return 0; +} + +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 wm8903_priv *wm8903 = snd_soc_codec_get_drvdata(codec); + int deemph = ucontrol->value.enumerated.item[0]; + int ret = 0; + + if (deemph > 1) + return -EINVAL; + + mutex_lock(&codec->mutex); + if (wm8903->deemph != deemph) { + wm8903->deemph = deemph; + + wm8903_set_deemph(codec); + + ret = 1; + } + mutex_unlock(&codec->mutex); + + return ret; +} + /* ALSA can only do steps of .01dB */ static const DECLARE_TLV_DB_SCALE(digital_tlv, -7200, 75, 1); @@ -548,13 +617,6 @@ static const char *mute_mode_text[] = { static const struct soc_enum mute_mode = SOC_ENUM_SINGLE(WM8903_DAC_DIGITAL_1, 9, 2, mute_mode_text); -static const char *dac_deemphasis_text[] = { - "Disabled", "32kHz", "44.1kHz", "48kHz" -}; - -static const struct soc_enum dac_deemphasis = - SOC_ENUM_SINGLE(WM8903_DAC_DIGITAL_1, 1, 4, dac_deemphasis_text); - static const char *companding_text[] = { "ulaw", "alaw" }; @@ -662,9 +724,10 @@ SOC_DOUBLE_R_TLV("Digital Playback Volume", WM8903_DAC_DIGITAL_VOLUME_LEFT, SOC_ENUM("DAC Soft Mute Rate", soft_mute), SOC_ENUM("DAC Mute Mode", mute_mode), SOC_SINGLE("DAC Mono Switch", WM8903_DAC_DIGITAL_1, 12, 1, 0), -SOC_ENUM("DAC De-emphasis", dac_deemphasis), SOC_ENUM("DAC Companding Mode", dac_companding), SOC_SINGLE("DAC Companding Switch", WM8903_AUDIO_INTERFACE_0, 1, 1, 0), +SOC_SINGLE_BOOL_EXT("Playback Deemphasis Switch", 0, + wm8903_get_deemph, wm8903_put_deemph), /* Headphones */ SOC_DOUBLE_R("Headphone Switch", @@ -1374,6 +1437,9 @@ static int wm8903_hw_params(struct snd_pcm_substream *substream, aif2 |= bclk_divs[bclk_div].div; aif3 |= bclk / fs; + wm8903->fs = params_rate(params); + wm8903_set_deemph(codec); + snd_soc_write(codec, WM8903_CLOCK_RATES_0, clock0); snd_soc_write(codec, WM8903_CLOCK_RATES_1, clock1); snd_soc_write(codec, WM8903_AUDIO_INTERFACE_1, aif1); -- cgit v1.2.3 From c4ffafa51bb0bea648a4ca119033a95057799c9d Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sat, 11 Dec 2010 17:51:36 +0100 Subject: HID: hid-picolcd: don't use flush_scheduled_work() flush_scheduled_work() is deprecated and scheduled to be removed. Directly flush picolcd_fb_cleanup on exit instead. Signed-off-by: Tejun Heo Cc: Jiri Kosina Signed-off-by: Jiri Kosina --- drivers/hid/hid-picolcd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/hid/hid-picolcd.c b/drivers/hid/hid-picolcd.c index e4ce47156106..ed0e066b7f07 100644 --- a/drivers/hid/hid-picolcd.c +++ b/drivers/hid/hid-picolcd.c @@ -2750,7 +2750,7 @@ static void __exit picolcd_exit(void) { hid_unregister_driver(&picolcd_driver); #ifdef CONFIG_HID_PICOLCD_FB - flush_scheduled_work(); + flush_work_sync(&picolcd_fb_cleanup); WARN_ON(fb_pending); #endif } -- cgit v1.2.3 From 60a74a6ff86b4e90b9558956589390efdeb4e924 Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Sat, 23 Oct 2010 13:18:56 +0200 Subject: firewire: nosy: char device is not seekable Amend .open handler accordingly and remove the .llseek handler. .llseek = NULL means no_llseek (return error) since commit 776c163b1b93. The only client that uses this interface is nosy-dump in linux/tools/firewire and it knows not to seek in this char dev. Signed-off-by: Stefan Richter --- drivers/firewire/nosy.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/firewire/nosy.c b/drivers/firewire/nosy.c index bf184fb59a5e..0618145376ad 100644 --- a/drivers/firewire/nosy.c +++ b/drivers/firewire/nosy.c @@ -302,7 +302,7 @@ nosy_open(struct inode *inode, struct file *file) file->private_data = client; - return 0; + return nonseekable_open(inode, file); fail: kfree(client); lynx_put(lynx); @@ -405,7 +405,6 @@ static const struct file_operations nosy_ops = { .poll = nosy_poll, .open = nosy_open, .release = nosy_release, - .llseek = noop_llseek, }; #define PHY_PACKET_SIZE 12 /* 1 payload, 1 inverse, 1 ack = 3 quadlets */ -- cgit v1.2.3 From 5878730be4e3d0c9527d6f2f688874e38acacc98 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Sat, 30 Oct 2010 14:08:27 -0700 Subject: firewire: core: Update WARN uses Add missing newlines. Signed-off-by: Joe Perches Signed-off-by: Stefan Richter --- drivers/firewire/core-transaction.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/firewire/core-transaction.c b/drivers/firewire/core-transaction.c index b42a0bde8494..ad864d8cd5e4 100644 --- a/drivers/firewire/core-transaction.c +++ b/drivers/firewire/core-transaction.c @@ -250,7 +250,7 @@ static void fw_fill_request(struct fw_packet *packet, int tcode, int tlabel, break; default: - WARN(1, "wrong tcode %d", tcode); + WARN(1, "wrong tcode %d\n", tcode); } common: packet->speed = speed; @@ -638,7 +638,7 @@ int fw_get_response_length(struct fw_request *r) } default: - WARN(1, "wrong tcode %d", tcode); + WARN(1, "wrong tcode %d\n", tcode); return 0; } } @@ -694,7 +694,7 @@ void fw_fill_response(struct fw_packet *response, u32 *request_header, break; default: - WARN(1, "wrong tcode %d", tcode); + WARN(1, "wrong tcode %d\n", tcode); } response->payload_mapped = false; -- cgit v1.2.3 From 5b84ba26a9672e615897234fa5efd3eea2d6b295 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sat, 11 Dec 2010 17:51:26 +0100 Subject: sound: don't use flush_scheduled_work() flush_scheduled_work() is deprecated and scheduled to be removed. * cancel[_delayed]_work() + flush_scheduled_work() -> cancel[_delayed]_work_sync(). * wm8350, wm8753 and soc-core use custom code to cancel a delayed work, execute it immediately if it was pending and wait for its completion. This is equivalent to flush_delayed_work_sync(). Use it instead. Signed-off-by: Tejun Heo Acked-by: Mark Brown Signed-off-by: Takashi Iwai --- sound/aoa/core/gpio-feature.c | 7 +++---- sound/aoa/core/gpio-pmf.c | 7 +++---- sound/i2c/other/ak4113.c | 5 ++--- sound/i2c/other/ak4114.c | 5 ++--- sound/pci/ac97/ac97_codec.c | 6 ++---- sound/pci/hda/patch_via.c | 3 +-- sound/pci/oxygen/oxygen_lib.c | 6 ++++-- sound/soc/codecs/wm8350.c | 9 +-------- sound/soc/codecs/wm8753.c | 21 +-------------------- sound/soc/soc-core.c | 25 +++---------------------- 10 files changed, 22 insertions(+), 72 deletions(-) diff --git a/sound/aoa/core/gpio-feature.c b/sound/aoa/core/gpio-feature.c index de8e03afa97b..faa317490545 100644 --- a/sound/aoa/core/gpio-feature.c +++ b/sound/aoa/core/gpio-feature.c @@ -287,10 +287,9 @@ static void ftr_gpio_exit(struct gpio_runtime *rt) free_irq(linein_detect_irq, &rt->line_in_notify); if (rt->line_out_notify.gpio_private) free_irq(lineout_detect_irq, &rt->line_out_notify); - cancel_delayed_work(&rt->headphone_notify.work); - cancel_delayed_work(&rt->line_in_notify.work); - cancel_delayed_work(&rt->line_out_notify.work); - flush_scheduled_work(); + cancel_delayed_work_sync(&rt->headphone_notify.work); + cancel_delayed_work_sync(&rt->line_in_notify.work); + cancel_delayed_work_sync(&rt->line_out_notify.work); mutex_destroy(&rt->headphone_notify.mutex); mutex_destroy(&rt->line_in_notify.mutex); mutex_destroy(&rt->line_out_notify.mutex); diff --git a/sound/aoa/core/gpio-pmf.c b/sound/aoa/core/gpio-pmf.c index 7e267c9379bc..c8d8a1a6f964 100644 --- a/sound/aoa/core/gpio-pmf.c +++ b/sound/aoa/core/gpio-pmf.c @@ -107,10 +107,9 @@ static void pmf_gpio_exit(struct gpio_runtime *rt) /* make sure no work is pending before freeing * all things */ - cancel_delayed_work(&rt->headphone_notify.work); - cancel_delayed_work(&rt->line_in_notify.work); - cancel_delayed_work(&rt->line_out_notify.work); - flush_scheduled_work(); + cancel_delayed_work_sync(&rt->headphone_notify.work); + cancel_delayed_work_sync(&rt->line_in_notify.work); + cancel_delayed_work_sync(&rt->line_out_notify.work); mutex_destroy(&rt->headphone_notify.mutex); mutex_destroy(&rt->line_in_notify.mutex); diff --git a/sound/i2c/other/ak4113.c b/sound/i2c/other/ak4113.c index 971a84a4fa77..c424d329f806 100644 --- a/sound/i2c/other/ak4113.c +++ b/sound/i2c/other/ak4113.c @@ -57,8 +57,7 @@ static void snd_ak4113_free(struct ak4113 *chip) { chip->init = 1; /* don't schedule new work */ mb(); - cancel_delayed_work(&chip->work); - flush_scheduled_work(); + cancel_delayed_work_sync(&chip->work); kfree(chip); } @@ -141,7 +140,7 @@ void snd_ak4113_reinit(struct ak4113 *chip) { chip->init = 1; mb(); - flush_scheduled_work(); + flush_delayed_work_sync(&chip->work); ak4113_init_regs(chip); /* bring up statistics / event queing */ chip->init = 0; diff --git a/sound/i2c/other/ak4114.c b/sound/i2c/other/ak4114.c index 0341451f814c..d9fb537b0b94 100644 --- a/sound/i2c/other/ak4114.c +++ b/sound/i2c/other/ak4114.c @@ -67,8 +67,7 @@ static void snd_ak4114_free(struct ak4114 *chip) { chip->init = 1; /* don't schedule new work */ mb(); - cancel_delayed_work(&chip->work); - flush_scheduled_work(); + cancel_delayed_work_sync(&chip->work); kfree(chip); } @@ -154,7 +153,7 @@ void snd_ak4114_reinit(struct ak4114 *chip) { chip->init = 1; mb(); - flush_scheduled_work(); + flush_delayed_work_sync(&chip->work); ak4114_init_regs(chip); /* bring up statistics / event queing */ chip->init = 0; diff --git a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c index a7630e9edf8a..0fc614ce16c1 100644 --- a/sound/pci/ac97/ac97_codec.c +++ b/sound/pci/ac97/ac97_codec.c @@ -1014,8 +1014,7 @@ static int snd_ac97_free(struct snd_ac97 *ac97) { if (ac97) { #ifdef CONFIG_SND_AC97_POWER_SAVE - cancel_delayed_work(&ac97->power_work); - flush_scheduled_work(); + cancel_delayed_work_sync(&ac97->power_work); #endif snd_ac97_proc_done(ac97); if (ac97->bus) @@ -2456,8 +2455,7 @@ void snd_ac97_suspend(struct snd_ac97 *ac97) if (ac97->build_ops->suspend) ac97->build_ops->suspend(ac97); #ifdef CONFIG_SND_AC97_POWER_SAVE - cancel_delayed_work(&ac97->power_work); - flush_scheduled_work(); + cancel_delayed_work_sync(&ac97->power_work); #endif snd_ac97_powerdown(ac97); } diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c index d1c3f8defc48..7f4852a478a1 100644 --- a/sound/pci/hda/patch_via.c +++ b/sound/pci/hda/patch_via.c @@ -263,8 +263,7 @@ static void vt1708_stop_hp_work(struct via_spec *spec) return; snd_hda_codec_write(spec->codec, 0x1, 0, 0xf81, !spec->vt1708_jack_detectect); - cancel_delayed_work(&spec->vt1708_hp_work); - flush_scheduled_work(); + cancel_delayed_work_sync(&spec->vt1708_hp_work); } diff --git a/sound/pci/oxygen/oxygen_lib.c b/sound/pci/oxygen/oxygen_lib.c index e5ebe56fb0c5..969605fbcb7f 100644 --- a/sound/pci/oxygen/oxygen_lib.c +++ b/sound/pci/oxygen/oxygen_lib.c @@ -557,7 +557,8 @@ static void oxygen_card_free(struct snd_card *card) oxygen_shutdown(chip); if (chip->irq >= 0) free_irq(chip->irq, chip); - flush_scheduled_work(); + flush_work_sync(&chip->spdif_input_bits_work); + flush_work_sync(&chip->gpio_work); chip->model.cleanup(chip); kfree(chip->model_data); mutex_destroy(&chip->mutex); @@ -733,7 +734,8 @@ int oxygen_pci_suspend(struct pci_dev *pci, pm_message_t state) spin_unlock_irq(&chip->reg_lock); synchronize_irq(chip->irq); - flush_scheduled_work(); + flush_work_sync(&chip->spdif_input_bits_work); + flush_work_sync(&chip->gpio_work); chip->interrupt_mask = saved_interrupt_mask; pci_disable_device(pci); diff --git a/sound/soc/codecs/wm8350.c b/sound/soc/codecs/wm8350.c index 7611add7f8c3..b3e9fac172e5 100644 --- a/sound/soc/codecs/wm8350.c +++ b/sound/soc/codecs/wm8350.c @@ -1626,7 +1626,6 @@ static int wm8350_codec_remove(struct snd_soc_codec *codec) { struct wm8350_data *priv = snd_soc_codec_get_drvdata(codec); struct wm8350 *wm8350 = dev_get_platdata(codec->dev); - int ret; wm8350_clear_bits(wm8350, WM8350_JACK_DETECT, WM8350_JDL_ENA | WM8350_JDR_ENA); @@ -1641,15 +1640,9 @@ static int wm8350_codec_remove(struct snd_soc_codec *codec) priv->hpr.jack = NULL; priv->mic.jack = NULL; - /* cancel any work waiting to be queued. */ - ret = cancel_delayed_work(&codec->delayed_work); - /* if there was any work waiting then we run it now and * wait for its completion */ - if (ret) { - schedule_delayed_work(&codec->delayed_work, 0); - flush_scheduled_work(); - } + flush_delayed_work_sync(&codec->delayed_work); wm8350_set_bias_level(codec, SND_SOC_BIAS_OFF); diff --git a/sound/soc/codecs/wm8753.c b/sound/soc/codecs/wm8753.c index 8f679a13f2bc..84a23675cba9 100644 --- a/sound/soc/codecs/wm8753.c +++ b/sound/soc/codecs/wm8753.c @@ -1526,25 +1526,6 @@ static int wm8753_resume(struct snd_soc_codec *codec) return 0; } -/* - * This function forces any delayed work to be queued and run. - */ -static int run_delayed_work(struct delayed_work *dwork) -{ - int ret; - - /* cancel any work waiting to be queued. */ - ret = cancel_delayed_work(dwork); - - /* if there was any work waiting then we run it now and - * wait for it's completion */ - if (ret) { - schedule_delayed_work(dwork, 0); - flush_scheduled_work(); - } - return ret; -} - static int wm8753_probe(struct snd_soc_codec *codec) { struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec); @@ -1604,7 +1585,7 @@ static int wm8753_probe(struct snd_soc_codec *codec) /* power down chip */ static int wm8753_remove(struct snd_soc_codec *codec) { - run_delayed_work(&codec->delayed_work); + flush_delayed_work_sync(&codec->delayed_work); wm8753_set_bias_level(codec, SND_SOC_BIAS_OFF); return 0; diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 441285ade024..b54ea9a0a1db 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -67,25 +67,6 @@ static int pmdown_time = 5000; module_param(pmdown_time, int, 0); MODULE_PARM_DESC(pmdown_time, "DAPM stream powerdown time (msecs)"); -/* - * This function forces any delayed work to be queued and run. - */ -static int run_delayed_work(struct delayed_work *dwork) -{ - int ret; - - /* cancel any work waiting to be queued. */ - ret = cancel_delayed_work(dwork); - - /* if there was any work waiting then we run it now and - * wait for it's completion */ - if (ret) { - schedule_delayed_work(dwork, 0); - flush_scheduled_work(); - } - return ret; -} - /* codec register dump */ static ssize_t soc_codec_reg_show(struct snd_soc_codec *codec, char *buf) { @@ -1016,7 +997,7 @@ static int soc_suspend(struct device *dev) /* close any waiting streams and save state */ for (i = 0; i < card->num_rtd; i++) { - run_delayed_work(&card->rtd[i].delayed_work); + flush_delayed_work_sync(&card->rtd[i].delayed_work); card->rtd[i].codec->suspend_bias_level = card->rtd[i].codec->bias_level; } @@ -1687,7 +1668,7 @@ static int soc_remove(struct platform_device *pdev) /* make sure any delayed work runs */ for (i = 0; i < card->num_rtd; i++) { struct snd_soc_pcm_runtime *rtd = &card->rtd[i]; - run_delayed_work(&rtd->delayed_work); + flush_delayed_work_sync(&rtd->delayed_work); } /* remove and free each DAI */ @@ -1718,7 +1699,7 @@ static int soc_poweroff(struct device *dev) * now, we're shutting down so no imminent restart. */ for (i = 0; i < card->num_rtd; i++) { struct snd_soc_pcm_runtime *rtd = &card->rtd[i]; - run_delayed_work(&rtd->delayed_work); + flush_delayed_work_sync(&rtd->delayed_work); } snd_soc_dapm_shutdown(card); -- cgit v1.2.3 From 49db7e7b995f5c61c5e24198f833ed01d99f5e7d Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 8 Dec 2010 13:49:43 +0000 Subject: ASoC: Fix widgets for WM8994/58 AIF2 source control The compiler really ought to have been warning about unreferenced variables... Signed-off-by: Mark Brown Acked-by: Liam Girdwood --- sound/soc/codecs/wm8994.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index e59691a7b342..af104acd75f8 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c @@ -790,13 +790,13 @@ SOC_DOUBLE_R_TLV("AIF2ADC Volume", WM8994_AIF2_ADC_LEFT_VOLUME, SOC_ENUM("AIF1ADCL Source", aif1adcl_src), SOC_ENUM("AIF1ADCR Source", aif1adcr_src), -SOC_ENUM("AIF2ADCL Source", aif1adcl_src), -SOC_ENUM("AIF2ADCR Source", aif1adcr_src), +SOC_ENUM("AIF2ADCL Source", aif2adcl_src), +SOC_ENUM("AIF2ADCR Source", aif2adcr_src), SOC_ENUM("AIF1DACL Source", aif1dacl_src), SOC_ENUM("AIF1DACR Source", aif1dacr_src), -SOC_ENUM("AIF2DACL Source", aif1dacl_src), -SOC_ENUM("AIF2DACR Source", aif1dacr_src), +SOC_ENUM("AIF2DACL Source", aif2dacl_src), +SOC_ENUM("AIF2DACR Source", aif2dacr_src), SOC_DOUBLE_R_TLV("AIF1DAC1 Volume", WM8994_AIF1_DAC1_LEFT_VOLUME, WM8994_AIF1_DAC1_RIGHT_VOLUME, 1, 96, 0, digital_tlv), -- cgit v1.2.3 From fbb5bb563925db138a8bbfa6a0ea0e089fbd2405 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 13 Dec 2010 12:48:35 +0100 Subject: ALSA: hda - Mute speakers when line-out jack is plugged with Conexant auto mode Mute speakers when a line-out jack is plugged as well as headphone jacks with the new Conexant codec parser in the auto mode. Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_conexant.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index 46bbf14e91ae..96b286aebde6 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c @@ -3424,6 +3424,9 @@ static void cx_auto_hp_automute(struct hda_codec *codec) AC_VERB_SET_PIN_WIDGET_CONTROL, present ? 0 : PIN_OUT); } + for (i = 0; !present && i < cfg->line_outs; i++) + if (snd_hda_jack_detect(codec, cfg->line_out_pins[i])) + present = 1; for (i = 0; i < cfg->speaker_outs; i++) { snd_hda_codec_write(codec, cfg->speaker_pins[i], 0, AC_VERB_SET_PIN_WIDGET_CONTROL, -- cgit v1.2.3 From 3c097b800816c0e4c2a34c38f8b2409427770f7a Mon Sep 17 00:00:00 2001 From: Tadeusz Struk Date: Mon, 13 Dec 2010 19:51:15 +0800 Subject: crypto: aesni-intel - Fixed build with binutils 2.16 This patch fixes the problem with 2.16 binutils. Signed-off-by: Aidan O'Mahony Signed-off-by: Adrian Hoban Signed-off-by: Gabriele Paoloni Signed-off-by: Tadeusz Struk Signed-off-by: Herbert Xu --- arch/x86/crypto/aesni-intel_asm.S | 598 +++++++++++++++++++++++++++++++++----- 1 file changed, 519 insertions(+), 79 deletions(-) diff --git a/arch/x86/crypto/aesni-intel_asm.S b/arch/x86/crypto/aesni-intel_asm.S index d528fde219d2..8fe2a4966b7a 100644 --- a/arch/x86/crypto/aesni-intel_asm.S +++ b/arch/x86/crypto/aesni-intel_asm.S @@ -204,9 +204,9 @@ enc: .octa 0x2 * arg1, %arg2, %arg3, %r14 are used as a pointer only, not modified */ -.macro INITIAL_BLOCKS num_initial_blocks TMP1 TMP2 TMP3 TMP4 TMP5 XMM0 XMM1 \ -XMM2 XMM3 XMM4 XMMDst TMP6 TMP7 i i_seq operation +.macro INITIAL_BLOCKS_DEC num_initial_blocks TMP1 TMP2 TMP3 TMP4 TMP5 XMM0 XMM1 \ +XMM2 XMM3 XMM4 XMMDst TMP6 TMP7 i i_seq operation mov arg7, %r10 # %r10 = AAD mov arg8, %r12 # %r12 = aadLen mov %r12, %r11 @@ -228,19 +228,25 @@ _get_AAD_loop2\num_initial_blocks\operation: cmp %r11, %r12 jne _get_AAD_loop2\num_initial_blocks\operation _get_AAD_loop2_done\num_initial_blocks\operation: - pshufb SHUF_MASK(%rip), %xmm\i # byte-reflect the AAD data + movdqa SHUF_MASK(%rip), %xmm14 + PSHUFB_XMM %xmm14, %xmm\i # byte-reflect the AAD data + xor %r11, %r11 # initialise the data pointer offset as zero # start AES for num_initial_blocks blocks mov %arg5, %rax # %rax = *Y0 movdqu (%rax), \XMM0 # XMM0 = Y0 - pshufb SHUF_MASK(%rip), \XMM0 -.if \i_seq != 0 + movdqa SHUF_MASK(%rip), %xmm14 + PSHUFB_XMM %xmm14, \XMM0 + +.if (\i == 5) || (\i == 6) || (\i == 7) .irpc index, \i_seq paddd ONE(%rip), \XMM0 # INCR Y0 movdqa \XMM0, %xmm\index - pshufb SHUF_MASK(%rip), %xmm\index # perform a 16 byte swap + movdqa SHUF_MASK(%rip), %xmm14 + PSHUFB_XMM %xmm14, %xmm\index # perform a 16 byte swap + .endr .irpc index, \i_seq pxor 16*0(%arg1), %xmm\index @@ -291,10 +297,11 @@ _get_AAD_loop2_done\num_initial_blocks\operation: movdqu %xmm\index, (%arg2 , %r11, 1) # write back plaintext/ciphertext for num_initial_blocks add $16, %r11 -.if \operation == dec + movdqa \TMP1, %xmm\index -.endif - pshufb SHUF_MASK(%rip), %xmm\index + movdqa SHUF_MASK(%rip), %xmm14 + PSHUFB_XMM %xmm14, %xmm\index + # prepare plaintext/ciphertext for GHASH computation .endr .endif @@ -327,16 +334,24 @@ _get_AAD_loop2_done\num_initial_blocks\operation: */ paddd ONE(%rip), \XMM0 # INCR Y0 movdqa \XMM0, \XMM1 - pshufb SHUF_MASK(%rip), \XMM1 # perform a 16 byte swap + movdqa SHUF_MASK(%rip), %xmm14 + PSHUFB_XMM %xmm14, \XMM1 # perform a 16 byte swap + paddd ONE(%rip), \XMM0 # INCR Y0 movdqa \XMM0, \XMM2 - pshufb SHUF_MASK(%rip), \XMM2 # perform a 16 byte swap + movdqa SHUF_MASK(%rip), %xmm14 + PSHUFB_XMM %xmm14, \XMM2 # perform a 16 byte swap + paddd ONE(%rip), \XMM0 # INCR Y0 movdqa \XMM0, \XMM3 - pshufb SHUF_MASK(%rip), \XMM3 # perform a 16 byte swap + movdqa SHUF_MASK(%rip), %xmm14 + PSHUFB_XMM %xmm14, \XMM3 # perform a 16 byte swap + paddd ONE(%rip), \XMM0 # INCR Y0 movdqa \XMM0, \XMM4 - pshufb SHUF_MASK(%rip), \XMM4 # perform a 16 byte swap + movdqa SHUF_MASK(%rip), %xmm14 + PSHUFB_XMM %xmm14, \XMM4 # perform a 16 byte swap + pxor 16*0(%arg1), \XMM1 pxor 16*0(%arg1), \XMM2 pxor 16*0(%arg1), \XMM3 @@ -385,41 +400,268 @@ _get_AAD_loop2_done\num_initial_blocks\operation: AESENCLAST \TMP2, \XMM4 movdqu 16*0(%arg3 , %r11 , 1), \TMP1 pxor \TMP1, \XMM1 -.if \operation == dec movdqu \XMM1, 16*0(%arg2 , %r11 , 1) movdqa \TMP1, \XMM1 -.endif movdqu 16*1(%arg3 , %r11 , 1), \TMP1 pxor \TMP1, \XMM2 -.if \operation == dec movdqu \XMM2, 16*1(%arg2 , %r11 , 1) movdqa \TMP1, \XMM2 -.endif movdqu 16*2(%arg3 , %r11 , 1), \TMP1 pxor \TMP1, \XMM3 -.if \operation == dec movdqu \XMM3, 16*2(%arg2 , %r11 , 1) movdqa \TMP1, \XMM3 -.endif movdqu 16*3(%arg3 , %r11 , 1), \TMP1 pxor \TMP1, \XMM4 -.if \operation == dec movdqu \XMM4, 16*3(%arg2 , %r11 , 1) movdqa \TMP1, \XMM4 -.else + add $64, %r11 + movdqa SHUF_MASK(%rip), %xmm14 + PSHUFB_XMM %xmm14, \XMM1 # perform a 16 byte swap + pxor \XMMDst, \XMM1 +# combine GHASHed value with the corresponding ciphertext + movdqa SHUF_MASK(%rip), %xmm14 + PSHUFB_XMM %xmm14, \XMM2 # perform a 16 byte swap + movdqa SHUF_MASK(%rip), %xmm14 + PSHUFB_XMM %xmm14, \XMM3 # perform a 16 byte swap + movdqa SHUF_MASK(%rip), %xmm14 + PSHUFB_XMM %xmm14, \XMM4 # perform a 16 byte swap + +_initial_blocks_done\num_initial_blocks\operation: + +.endm + + +/* +* if a = number of total plaintext bytes +* b = floor(a/16) +* num_initial_blocks = b mod 4 +* encrypt the initial num_initial_blocks blocks and apply ghash on +* the ciphertext +* %r10, %r11, %r12, %rax, %xmm5, %xmm6, %xmm7, %xmm8, %xmm9 registers +* are clobbered +* arg1, %arg2, %arg3, %r14 are used as a pointer only, not modified +*/ + + +.macro INITIAL_BLOCKS_ENC num_initial_blocks TMP1 TMP2 TMP3 TMP4 TMP5 XMM0 XMM1 \ +XMM2 XMM3 XMM4 XMMDst TMP6 TMP7 i i_seq operation + mov arg7, %r10 # %r10 = AAD + mov arg8, %r12 # %r12 = aadLen + mov %r12, %r11 + pxor %xmm\i, %xmm\i +_get_AAD_loop\num_initial_blocks\operation: + movd (%r10), \TMP1 + pslldq $12, \TMP1 + psrldq $4, %xmm\i + pxor \TMP1, %xmm\i + add $4, %r10 + sub $4, %r12 + jne _get_AAD_loop\num_initial_blocks\operation + cmp $16, %r11 + je _get_AAD_loop2_done\num_initial_blocks\operation + mov $16, %r12 +_get_AAD_loop2\num_initial_blocks\operation: + psrldq $4, %xmm\i + sub $4, %r12 + cmp %r11, %r12 + jne _get_AAD_loop2\num_initial_blocks\operation +_get_AAD_loop2_done\num_initial_blocks\operation: + movdqa SHUF_MASK(%rip), %xmm14 + PSHUFB_XMM %xmm14, %xmm\i # byte-reflect the AAD data + + xor %r11, %r11 # initialise the data pointer offset as zero + + # start AES for num_initial_blocks blocks + + mov %arg5, %rax # %rax = *Y0 + movdqu (%rax), \XMM0 # XMM0 = Y0 + movdqa SHUF_MASK(%rip), %xmm14 + PSHUFB_XMM %xmm14, \XMM0 + +.if (\i == 5) || (\i == 6) || (\i == 7) +.irpc index, \i_seq + paddd ONE(%rip), \XMM0 # INCR Y0 + movdqa \XMM0, %xmm\index + movdqa SHUF_MASK(%rip), %xmm14 + PSHUFB_XMM %xmm14, %xmm\index # perform a 16 byte swap + +.endr +.irpc index, \i_seq + pxor 16*0(%arg1), %xmm\index +.endr +.irpc index, \i_seq + movaps 0x10(%rdi), \TMP1 + AESENC \TMP1, %xmm\index # Round 1 +.endr +.irpc index, \i_seq + movaps 0x20(%arg1), \TMP1 + AESENC \TMP1, %xmm\index # Round 2 +.endr +.irpc index, \i_seq + movaps 0x30(%arg1), \TMP1 + AESENC \TMP1, %xmm\index # Round 2 +.endr +.irpc index, \i_seq + movaps 0x40(%arg1), \TMP1 + AESENC \TMP1, %xmm\index # Round 2 +.endr +.irpc index, \i_seq + movaps 0x50(%arg1), \TMP1 + AESENC \TMP1, %xmm\index # Round 2 +.endr +.irpc index, \i_seq + movaps 0x60(%arg1), \TMP1 + AESENC \TMP1, %xmm\index # Round 2 +.endr +.irpc index, \i_seq + movaps 0x70(%arg1), \TMP1 + AESENC \TMP1, %xmm\index # Round 2 +.endr +.irpc index, \i_seq + movaps 0x80(%arg1), \TMP1 + AESENC \TMP1, %xmm\index # Round 2 +.endr +.irpc index, \i_seq + movaps 0x90(%arg1), \TMP1 + AESENC \TMP1, %xmm\index # Round 2 +.endr +.irpc index, \i_seq + movaps 0xa0(%arg1), \TMP1 + AESENCLAST \TMP1, %xmm\index # Round 10 +.endr +.irpc index, \i_seq + movdqu (%arg3 , %r11, 1), \TMP1 + pxor \TMP1, %xmm\index + movdqu %xmm\index, (%arg2 , %r11, 1) + # write back plaintext/ciphertext for num_initial_blocks + add $16, %r11 + + movdqa SHUF_MASK(%rip), %xmm14 + PSHUFB_XMM %xmm14, %xmm\index + + # prepare plaintext/ciphertext for GHASH computation +.endr +.endif + GHASH_MUL %xmm\i, \TMP3, \TMP1, \TMP2, \TMP4, \TMP5, \XMM1 + # apply GHASH on num_initial_blocks blocks + +.if \i == 5 + pxor %xmm5, %xmm6 + GHASH_MUL %xmm6, \TMP3, \TMP1, \TMP2, \TMP4, \TMP5, \XMM1 + pxor %xmm6, %xmm7 + GHASH_MUL %xmm7, \TMP3, \TMP1, \TMP2, \TMP4, \TMP5, \XMM1 + pxor %xmm7, %xmm8 + GHASH_MUL %xmm8, \TMP3, \TMP1, \TMP2, \TMP4, \TMP5, \XMM1 +.elseif \i == 6 + pxor %xmm6, %xmm7 + GHASH_MUL %xmm7, \TMP3, \TMP1, \TMP2, \TMP4, \TMP5, \XMM1 + pxor %xmm7, %xmm8 + GHASH_MUL %xmm8, \TMP3, \TMP1, \TMP2, \TMP4, \TMP5, \XMM1 +.elseif \i == 7 + pxor %xmm7, %xmm8 + GHASH_MUL %xmm8, \TMP3, \TMP1, \TMP2, \TMP4, \TMP5, \XMM1 +.endif + cmp $64, %r13 + jl _initial_blocks_done\num_initial_blocks\operation + # no need for precomputed values +/* +* +* Precomputations for HashKey parallel with encryption of first 4 blocks. +* Haskey_i_k holds XORed values of the low and high parts of the Haskey_i +*/ + paddd ONE(%rip), \XMM0 # INCR Y0 + movdqa \XMM0, \XMM1 + movdqa SHUF_MASK(%rip), %xmm14 + PSHUFB_XMM %xmm14, \XMM1 # perform a 16 byte swap + + paddd ONE(%rip), \XMM0 # INCR Y0 + movdqa \XMM0, \XMM2 + movdqa SHUF_MASK(%rip), %xmm14 + PSHUFB_XMM %xmm14, \XMM2 # perform a 16 byte swap + + paddd ONE(%rip), \XMM0 # INCR Y0 + movdqa \XMM0, \XMM3 + movdqa SHUF_MASK(%rip), %xmm14 + PSHUFB_XMM %xmm14, \XMM3 # perform a 16 byte swap + + paddd ONE(%rip), \XMM0 # INCR Y0 + movdqa \XMM0, \XMM4 + movdqa SHUF_MASK(%rip), %xmm14 + PSHUFB_XMM %xmm14, \XMM4 # perform a 16 byte swap + + pxor 16*0(%arg1), \XMM1 + pxor 16*0(%arg1), \XMM2 + pxor 16*0(%arg1), \XMM3 + pxor 16*0(%arg1), \XMM4 + movdqa \TMP3, \TMP5 + pshufd $78, \TMP3, \TMP1 + pxor \TMP3, \TMP1 + movdqa \TMP1, HashKey_k(%rsp) + GHASH_MUL \TMP5, \TMP3, \TMP1, \TMP2, \TMP4, \TMP6, \TMP7 +# TMP5 = HashKey^2<<1 (mod poly) + movdqa \TMP5, HashKey_2(%rsp) +# HashKey_2 = HashKey^2<<1 (mod poly) + pshufd $78, \TMP5, \TMP1 + pxor \TMP5, \TMP1 + movdqa \TMP1, HashKey_2_k(%rsp) +.irpc index, 1234 # do 4 rounds + movaps 0x10*\index(%arg1), \TMP1 + AESENC \TMP1, \XMM1 + AESENC \TMP1, \XMM2 + AESENC \TMP1, \XMM3 + AESENC \TMP1, \XMM4 +.endr + GHASH_MUL \TMP5, \TMP3, \TMP1, \TMP2, \TMP4, \TMP6, \TMP7 +# TMP5 = HashKey^3<<1 (mod poly) + movdqa \TMP5, HashKey_3(%rsp) + pshufd $78, \TMP5, \TMP1 + pxor \TMP5, \TMP1 + movdqa \TMP1, HashKey_3_k(%rsp) +.irpc index, 56789 # do next 5 rounds + movaps 0x10*\index(%arg1), \TMP1 + AESENC \TMP1, \XMM1 + AESENC \TMP1, \XMM2 + AESENC \TMP1, \XMM3 + AESENC \TMP1, \XMM4 +.endr + GHASH_MUL \TMP5, \TMP3, \TMP1, \TMP2, \TMP4, \TMP6, \TMP7 +# TMP5 = HashKey^3<<1 (mod poly) + movdqa \TMP5, HashKey_4(%rsp) + pshufd $78, \TMP5, \TMP1 + pxor \TMP5, \TMP1 + movdqa \TMP1, HashKey_4_k(%rsp) + movaps 0xa0(%arg1), \TMP2 + AESENCLAST \TMP2, \XMM1 + AESENCLAST \TMP2, \XMM2 + AESENCLAST \TMP2, \XMM3 + AESENCLAST \TMP2, \XMM4 + movdqu 16*0(%arg3 , %r11 , 1), \TMP1 + pxor \TMP1, \XMM1 + movdqu 16*1(%arg3 , %r11 , 1), \TMP1 + pxor \TMP1, \XMM2 + movdqu 16*2(%arg3 , %r11 , 1), \TMP1 + pxor \TMP1, \XMM3 + movdqu 16*3(%arg3 , %r11 , 1), \TMP1 + pxor \TMP1, \XMM4 movdqu \XMM1, 16*0(%arg2 , %r11 , 1) movdqu \XMM2, 16*1(%arg2 , %r11 , 1) movdqu \XMM3, 16*2(%arg2 , %r11 , 1) movdqu \XMM4, 16*3(%arg2 , %r11 , 1) -.endif + add $64, %r11 - pshufb SHUF_MASK(%rip), \XMM1 # perform a 16 byte swap + movdqa SHUF_MASK(%rip), %xmm14 + PSHUFB_XMM %xmm14, \XMM1 # perform a 16 byte swap pxor \XMMDst, \XMM1 # combine GHASHed value with the corresponding ciphertext - pshufb SHUF_MASK(%rip), \XMM2 # perform a 16 byte swap - pshufb SHUF_MASK(%rip), \XMM3 # perform a 16 byte swap - pshufb SHUF_MASK(%rip), \XMM4 # perform a 16 byte swap + movdqa SHUF_MASK(%rip), %xmm14 + PSHUFB_XMM %xmm14, \XMM2 # perform a 16 byte swap + movdqa SHUF_MASK(%rip), %xmm14 + PSHUFB_XMM %xmm14, \XMM3 # perform a 16 byte swap + movdqa SHUF_MASK(%rip), %xmm14 + PSHUFB_XMM %xmm14, \XMM4 # perform a 16 byte swap + _initial_blocks_done\num_initial_blocks\operation: + .endm /* @@ -428,7 +670,199 @@ _initial_blocks_done\num_initial_blocks\operation: * arg1, %arg2, %arg3 are used as pointers only, not modified * %r11 is the data offset value */ -.macro GHASH_4_ENCRYPT_4_PARALLEL TMP1 TMP2 TMP3 TMP4 TMP5 \ +.macro GHASH_4_ENCRYPT_4_PARALLEL_ENC TMP1 TMP2 TMP3 TMP4 TMP5 \ +TMP6 XMM0 XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7 XMM8 operation + + movdqa \XMM1, \XMM5 + movdqa \XMM2, \XMM6 + movdqa \XMM3, \XMM7 + movdqa \XMM4, \XMM8 + + movdqa SHUF_MASK(%rip), %xmm15 + # multiply TMP5 * HashKey using karatsuba + + movdqa \XMM5, \TMP4 + pshufd $78, \XMM5, \TMP6 + pxor \XMM5, \TMP6 + paddd ONE(%rip), \XMM0 # INCR CNT + movdqa HashKey_4(%rsp), \TMP5 + PCLMULQDQ 0x11, \TMP5, \TMP4 # TMP4 = a1*b1 + movdqa \XMM0, \XMM1 + paddd ONE(%rip), \XMM0 # INCR CNT + movdqa \XMM0, \XMM2 + paddd ONE(%rip), \XMM0 # INCR CNT + movdqa \XMM0, \XMM3 + paddd ONE(%rip), \XMM0 # INCR CNT + movdqa \XMM0, \XMM4 + PSHUFB_XMM %xmm15, \XMM1 # perform a 16 byte swap + PCLMULQDQ 0x00, \TMP5, \XMM5 # XMM5 = a0*b0 + PSHUFB_XMM %xmm15, \XMM2 # perform a 16 byte swap + PSHUFB_XMM %xmm15, \XMM3 # perform a 16 byte swap + PSHUFB_XMM %xmm15, \XMM4 # perform a 16 byte swap + + pxor (%arg1), \XMM1 + pxor (%arg1), \XMM2 + pxor (%arg1), \XMM3 + pxor (%arg1), \XMM4 + movdqa HashKey_4_k(%rsp), \TMP5 + PCLMULQDQ 0x00, \TMP5, \TMP6 # TMP6 = (a1+a0)*(b1+b0) + movaps 0x10(%arg1), \TMP1 + AESENC \TMP1, \XMM1 # Round 1 + AESENC \TMP1, \XMM2 + AESENC \TMP1, \XMM3 + AESENC \TMP1, \XMM4 + movaps 0x20(%arg1), \TMP1 + AESENC \TMP1, \XMM1 # Round 2 + AESENC \TMP1, \XMM2 + AESENC \TMP1, \XMM3 + AESENC \TMP1, \XMM4 + movdqa \XMM6, \TMP1 + pshufd $78, \XMM6, \TMP2 + pxor \XMM6, \TMP2 + movdqa HashKey_3(%rsp), \TMP5 + PCLMULQDQ 0x11, \TMP5, \TMP1 # TMP1 = a1 * b1 + movaps 0x30(%arg1), \TMP3 + AESENC \TMP3, \XMM1 # Round 3 + AESENC \TMP3, \XMM2 + AESENC \TMP3, \XMM3 + AESENC \TMP3, \XMM4 + PCLMULQDQ 0x00, \TMP5, \XMM6 # XMM6 = a0*b0 + movaps 0x40(%arg1), \TMP3 + AESENC \TMP3, \XMM1 # Round 4 + AESENC \TMP3, \XMM2 + AESENC \TMP3, \XMM3 + AESENC \TMP3, \XMM4 + movdqa HashKey_3_k(%rsp), \TMP5 + PCLMULQDQ 0x00, \TMP5, \TMP2 # TMP2 = (a1+a0)*(b1+b0) + movaps 0x50(%arg1), \TMP3 + AESENC \TMP3, \XMM1 # Round 5 + AESENC \TMP3, \XMM2 + AESENC \TMP3, \XMM3 + AESENC \TMP3, \XMM4 + pxor \TMP1, \TMP4 +# accumulate the results in TMP4:XMM5, TMP6 holds the middle part + pxor \XMM6, \XMM5 + pxor \TMP2, \TMP6 + movdqa \XMM7, \TMP1 + pshufd $78, \XMM7, \TMP2 + pxor \XMM7, \TMP2 + movdqa HashKey_2(%rsp ), \TMP5 + + # Multiply TMP5 * HashKey using karatsuba + + PCLMULQDQ 0x11, \TMP5, \TMP1 # TMP1 = a1*b1 + movaps 0x60(%arg1), \TMP3 + AESENC \TMP3, \XMM1 # Round 6 + AESENC \TMP3, \XMM2 + AESENC \TMP3, \XMM3 + AESENC \TMP3, \XMM4 + PCLMULQDQ 0x00, \TMP5, \XMM7 # XMM7 = a0*b0 + movaps 0x70(%arg1), \TMP3 + AESENC \TMP3, \XMM1 # Round 7 + AESENC \TMP3, \XMM2 + AESENC \TMP3, \XMM3 + AESENC \TMP3, \XMM4 + movdqa HashKey_2_k(%rsp), \TMP5 + PCLMULQDQ 0x00, \TMP5, \TMP2 # TMP2 = (a1+a0)*(b1+b0) + movaps 0x80(%arg1), \TMP3 + AESENC \TMP3, \XMM1 # Round 8 + AESENC \TMP3, \XMM2 + AESENC \TMP3, \XMM3 + AESENC \TMP3, \XMM4 + pxor \TMP1, \TMP4 +# accumulate the results in TMP4:XMM5, TMP6 holds the middle part + pxor \XMM7, \XMM5 + pxor \TMP2, \TMP6 + + # Multiply XMM8 * HashKey + # XMM8 and TMP5 hold the values for the two operands + + movdqa \XMM8, \TMP1 + pshufd $78, \XMM8, \TMP2 + pxor \XMM8, \TMP2 + movdqa HashKey(%rsp), \TMP5 + PCLMULQDQ 0x11, \TMP5, \TMP1 # TMP1 = a1*b1 + movaps 0x90(%arg1), \TMP3 + AESENC \TMP3, \XMM1 # Round 9 + AESENC \TMP3, \XMM2 + AESENC \TMP3, \XMM3 + AESENC \TMP3, \XMM4 + PCLMULQDQ 0x00, \TMP5, \XMM8 # XMM8 = a0*b0 + movaps 0xa0(%arg1), \TMP3 + AESENCLAST \TMP3, \XMM1 # Round 10 + AESENCLAST \TMP3, \XMM2 + AESENCLAST \TMP3, \XMM3 + AESENCLAST \TMP3, \XMM4 + movdqa HashKey_k(%rsp), \TMP5 + PCLMULQDQ 0x00, \TMP5, \TMP2 # TMP2 = (a1+a0)*(b1+b0) + movdqu (%arg3,%r11,1), \TMP3 + pxor \TMP3, \XMM1 # Ciphertext/Plaintext XOR EK + movdqu 16(%arg3,%r11,1), \TMP3 + pxor \TMP3, \XMM2 # Ciphertext/Plaintext XOR EK + movdqu 32(%arg3,%r11,1), \TMP3 + pxor \TMP3, \XMM3 # Ciphertext/Plaintext XOR EK + movdqu 48(%arg3,%r11,1), \TMP3 + pxor \TMP3, \XMM4 # Ciphertext/Plaintext XOR EK + movdqu \XMM1, (%arg2,%r11,1) # Write to the ciphertext buffer + movdqu \XMM2, 16(%arg2,%r11,1) # Write to the ciphertext buffer + movdqu \XMM3, 32(%arg2,%r11,1) # Write to the ciphertext buffer + movdqu \XMM4, 48(%arg2,%r11,1) # Write to the ciphertext buffer + PSHUFB_XMM %xmm15, \XMM1 # perform a 16 byte swap + PSHUFB_XMM %xmm15, \XMM2 # perform a 16 byte swap + PSHUFB_XMM %xmm15, \XMM3 # perform a 16 byte swap + PSHUFB_XMM %xmm15, \XMM4 # perform a 16 byte swap + + pxor \TMP4, \TMP1 + pxor \XMM8, \XMM5 + pxor \TMP6, \TMP2 + pxor \TMP1, \TMP2 + pxor \XMM5, \TMP2 + movdqa \TMP2, \TMP3 + pslldq $8, \TMP3 # left shift TMP3 2 DWs + psrldq $8, \TMP2 # right shift TMP2 2 DWs + pxor \TMP3, \XMM5 + pxor \TMP2, \TMP1 # accumulate the results in TMP1:XMM5 + + # first phase of reduction + + movdqa \XMM5, \TMP2 + movdqa \XMM5, \TMP3 + movdqa \XMM5, \TMP4 +# move XMM5 into TMP2, TMP3, TMP4 in order to perform shifts independently + pslld $31, \TMP2 # packed right shift << 31 + pslld $30, \TMP3 # packed right shift << 30 + pslld $25, \TMP4 # packed right shift << 25 + pxor \TMP3, \TMP2 # xor the shifted versions + pxor \TMP4, \TMP2 + movdqa \TMP2, \TMP5 + psrldq $4, \TMP5 # right shift T5 1 DW + pslldq $12, \TMP2 # left shift T2 3 DWs + pxor \TMP2, \XMM5 + + # second phase of reduction + + movdqa \XMM5,\TMP2 # make 3 copies of XMM5 into TMP2, TMP3, TMP4 + movdqa \XMM5,\TMP3 + movdqa \XMM5,\TMP4 + psrld $1, \TMP2 # packed left shift >>1 + psrld $2, \TMP3 # packed left shift >>2 + psrld $7, \TMP4 # packed left shift >>7 + pxor \TMP3,\TMP2 # xor the shifted versions + pxor \TMP4,\TMP2 + pxor \TMP5, \TMP2 + pxor \TMP2, \XMM5 + pxor \TMP1, \XMM5 # result is in TMP1 + + pxor \XMM5, \XMM1 +.endm + +/* +* decrypt 4 blocks at a time +* ghash the 4 previously decrypted ciphertext blocks +* arg1, %arg2, %arg3 are used as pointers only, not modified +* %r11 is the data offset value +*/ +.macro GHASH_4_ENCRYPT_4_PARALLEL_DEC TMP1 TMP2 TMP3 TMP4 TMP5 \ TMP6 XMM0 XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7 XMM8 operation movdqa \XMM1, \XMM5 @@ -436,6 +870,7 @@ TMP6 XMM0 XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7 XMM8 operation movdqa \XMM3, \XMM7 movdqa \XMM4, \XMM8 + movdqa SHUF_MASK(%rip), %xmm15 # multiply TMP5 * HashKey using karatsuba movdqa \XMM5, \TMP4 @@ -451,11 +886,12 @@ TMP6 XMM0 XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7 XMM8 operation movdqa \XMM0, \XMM3 paddd ONE(%rip), \XMM0 # INCR CNT movdqa \XMM0, \XMM4 - pshufb SHUF_MASK(%rip), \XMM1 # perform a 16 byte swap + PSHUFB_XMM %xmm15, \XMM1 # perform a 16 byte swap PCLMULQDQ 0x00, \TMP5, \XMM5 # XMM5 = a0*b0 - pshufb SHUF_MASK(%rip), \XMM2 # perform a 16 byte swap - pshufb SHUF_MASK(%rip), \XMM3 # perform a 16 byte swap - pshufb SHUF_MASK(%rip), \XMM4 # perform a 16 byte swap + PSHUFB_XMM %xmm15, \XMM2 # perform a 16 byte swap + PSHUFB_XMM %xmm15, \XMM3 # perform a 16 byte swap + PSHUFB_XMM %xmm15, \XMM4 # perform a 16 byte swap + pxor (%arg1), \XMM1 pxor (%arg1), \XMM2 pxor (%arg1), \XMM3 @@ -553,37 +989,24 @@ TMP6 XMM0 XMM1 XMM2 XMM3 XMM4 XMM5 XMM6 XMM7 XMM8 operation PCLMULQDQ 0x00, \TMP5, \TMP2 # TMP2 = (a1+a0)*(b1+b0) movdqu (%arg3,%r11,1), \TMP3 pxor \TMP3, \XMM1 # Ciphertext/Plaintext XOR EK -.if \operation == dec movdqu \XMM1, (%arg2,%r11,1) # Write to plaintext buffer movdqa \TMP3, \XMM1 -.endif movdqu 16(%arg3,%r11,1), \TMP3 pxor \TMP3, \XMM2 # Ciphertext/Plaintext XOR EK -.if \operation == dec movdqu \XMM2, 16(%arg2,%r11,1) # Write to plaintext buffer movdqa \TMP3, \XMM2 -.endif movdqu 32(%arg3,%r11,1), \TMP3 pxor \TMP3, \XMM3 # Ciphertext/Plaintext XOR EK -.if \operation == dec movdqu \XMM3, 32(%arg2,%r11,1) # Write to plaintext buffer movdqa \TMP3, \XMM3 -.endif movdqu 48(%arg3,%r11,1), \TMP3 pxor \TMP3, \XMM4 # Ciphertext/Plaintext XOR EK -.if \operation == dec movdqu \XMM4, 48(%arg2,%r11,1) # Write to plaintext buffer movdqa \TMP3, \XMM4 -.else - movdqu \XMM1, (%arg2,%r11,1) # Write to the ciphertext buffer - movdqu \XMM2, 16(%arg2,%r11,1) # Write to the ciphertext buffer - movdqu \XMM3, 32(%arg2,%r11,1) # Write to the ciphertext buffer - movdqu \XMM4, 48(%arg2,%r11,1) # Write to the ciphertext buffer -.endif - pshufb SHUF_MASK(%rip), \XMM1 # perform a 16 byte swap - pshufb SHUF_MASK(%rip), \XMM2 # perform a 16 byte swap - pshufb SHUF_MASK(%rip), \XMM3 # perform a 16 byte swap - pshufb SHUF_MASK(%rip), \XMM4 # perform a 16 byte sway + PSHUFB_XMM %xmm15, \XMM1 # perform a 16 byte swap + PSHUFB_XMM %xmm15, \XMM2 # perform a 16 byte swap + PSHUFB_XMM %xmm15, \XMM3 # perform a 16 byte swap + PSHUFB_XMM %xmm15, \XMM4 # perform a 16 byte swap pxor \TMP4, \TMP1 pxor \XMM8, \XMM5 @@ -853,7 +1276,9 @@ ENTRY(aesni_gcm_dec) and $~63, %rsp # align rsp to 64 bytes mov %arg6, %r12 movdqu (%r12), %xmm13 # %xmm13 = HashKey - pshufb SHUF_MASK(%rip), %xmm13 + movdqa SHUF_MASK(%rip), %xmm2 + PSHUFB_XMM %xmm2, %xmm13 + # Precompute HashKey<<1 (mod poly) from the hash key (required for GHASH) @@ -885,22 +1310,22 @@ ENTRY(aesni_gcm_dec) jb _initial_num_blocks_is_1_decrypt je _initial_num_blocks_is_2_decrypt _initial_num_blocks_is_3_decrypt: - INITIAL_BLOCKS 3, %xmm9, %xmm10, %xmm13, %xmm11, %xmm12, %xmm0, \ + INITIAL_BLOCKS_DEC 3, %xmm9, %xmm10, %xmm13, %xmm11, %xmm12, %xmm0, \ %xmm1, %xmm2, %xmm3, %xmm4, %xmm8, %xmm5, %xmm6, 5, 678, dec sub $48, %r13 jmp _initial_blocks_decrypted _initial_num_blocks_is_2_decrypt: - INITIAL_BLOCKS 2, %xmm9, %xmm10, %xmm13, %xmm11, %xmm12, %xmm0, \ + INITIAL_BLOCKS_DEC 2, %xmm9, %xmm10, %xmm13, %xmm11, %xmm12, %xmm0, \ %xmm1, %xmm2, %xmm3, %xmm4, %xmm8, %xmm5, %xmm6, 6, 78, dec sub $32, %r13 jmp _initial_blocks_decrypted _initial_num_blocks_is_1_decrypt: - INITIAL_BLOCKS 1, %xmm9, %xmm10, %xmm13, %xmm11, %xmm12, %xmm0, \ + INITIAL_BLOCKS_DEC 1, %xmm9, %xmm10, %xmm13, %xmm11, %xmm12, %xmm0, \ %xmm1, %xmm2, %xmm3, %xmm4, %xmm8, %xmm5, %xmm6, 7, 8, dec sub $16, %r13 jmp _initial_blocks_decrypted _initial_num_blocks_is_0_decrypt: - INITIAL_BLOCKS 0, %xmm9, %xmm10, %xmm13, %xmm11, %xmm12, %xmm0, \ + INITIAL_BLOCKS_DEC 0, %xmm9, %xmm10, %xmm13, %xmm11, %xmm12, %xmm0, \ %xmm1, %xmm2, %xmm3, %xmm4, %xmm8, %xmm5, %xmm6, 8, 0, dec _initial_blocks_decrypted: cmp $0, %r13 @@ -908,7 +1333,7 @@ _initial_blocks_decrypted: sub $64, %r13 je _four_cipher_left_decrypt _decrypt_by_4: - GHASH_4_ENCRYPT_4_PARALLEL %xmm9, %xmm10, %xmm11, %xmm12, %xmm13, \ + GHASH_4_ENCRYPT_4_PARALLEL_DEC %xmm9, %xmm10, %xmm11, %xmm12, %xmm13, \ %xmm14, %xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %xmm6, %xmm7, %xmm8, dec add $64, %r11 sub $64, %r13 @@ -924,7 +1349,9 @@ _zero_cipher_left_decrypt: # Handle the last <16 byte block seperately paddd ONE(%rip), %xmm0 # increment CNT to get Yn - pshufb SHUF_MASK(%rip), %xmm0 + movdqa SHUF_MASK(%rip), %xmm10 + PSHUFB_XMM %xmm10, %xmm0 + ENCRYPT_SINGLE_BLOCK %xmm0, %xmm1 # E(K, Yn) sub $16, %r11 add %r13, %r11 @@ -934,14 +1361,17 @@ _zero_cipher_left_decrypt: # adjust the shuffle mask pointer to be able to shift 16-%r13 bytes # (%r13 is the number of bytes in plaintext mod 16) movdqu (%r12), %xmm2 # get the appropriate shuffle mask - pshufb %xmm2, %xmm1 # right shift 16-%r13 butes + PSHUFB_XMM %xmm2, %xmm1 # right shift 16-%r13 butes + movdqa %xmm1, %xmm2 pxor %xmm1, %xmm0 # Ciphertext XOR E(K, Yn) movdqu ALL_F-SHIFT_MASK(%r12), %xmm1 # get the appropriate mask to mask out top 16-%r13 bytes of %xmm0 pand %xmm1, %xmm0 # mask out top 16-%r13 bytes of %xmm0 pand %xmm1, %xmm2 - pshufb SHUF_MASK(%rip),%xmm2 + movdqa SHUF_MASK(%rip), %xmm10 + PSHUFB_XMM %xmm10 ,%xmm2 + pxor %xmm2, %xmm8 GHASH_MUL %xmm8, %xmm13, %xmm9, %xmm10, %xmm11, %xmm5, %xmm6 # GHASH computation for the last <16 byte block @@ -949,13 +1379,13 @@ _zero_cipher_left_decrypt: add $16, %r11 # output %r13 bytes - movq %xmm0, %rax + MOVQ_R64_XMM %xmm0, %rax cmp $8, %r13 jle _less_than_8_bytes_left_decrypt mov %rax, (%arg2 , %r11, 1) add $8, %r11 psrldq $8, %xmm0 - movq %xmm0, %rax + MOVQ_R64_XMM %xmm0, %rax sub $8, %r13 _less_than_8_bytes_left_decrypt: mov %al, (%arg2, %r11, 1) @@ -968,13 +1398,15 @@ _multiple_of_16_bytes_decrypt: shl $3, %r12 # convert into number of bits movd %r12d, %xmm15 # len(A) in %xmm15 shl $3, %arg4 # len(C) in bits (*128) - movq %arg4, %xmm1 + MOVQ_R64_XMM %arg4, %xmm1 pslldq $8, %xmm15 # %xmm15 = len(A)||0x0000000000000000 pxor %xmm1, %xmm15 # %xmm15 = len(A)||len(C) pxor %xmm15, %xmm8 GHASH_MUL %xmm8, %xmm13, %xmm9, %xmm10, %xmm11, %xmm5, %xmm6 # final GHASH computation - pshufb SHUF_MASK(%rip), %xmm8 + movdqa SHUF_MASK(%rip), %xmm10 + PSHUFB_XMM %xmm10, %xmm8 + mov %arg5, %rax # %rax = *Y0 movdqu (%rax), %xmm0 # %xmm0 = Y0 ENCRYPT_SINGLE_BLOCK %xmm0, %xmm1 # E(K, Y0) @@ -987,11 +1419,11 @@ _return_T_decrypt: cmp $12, %r11 je _T_12_decrypt _T_8_decrypt: - movq %xmm0, %rax + MOVQ_R64_XMM %xmm0, %rax mov %rax, (%r10) jmp _return_T_done_decrypt _T_12_decrypt: - movq %xmm0, %rax + MOVQ_R64_XMM %xmm0, %rax mov %rax, (%r10) psrldq $8, %xmm0 movd %xmm0, %eax @@ -1103,7 +1535,9 @@ ENTRY(aesni_gcm_enc) and $~63, %rsp mov %arg6, %r12 movdqu (%r12), %xmm13 - pshufb SHUF_MASK(%rip), %xmm13 + movdqa SHUF_MASK(%rip), %xmm2 + PSHUFB_XMM %xmm2, %xmm13 + # precompute HashKey<<1 mod poly from the HashKey (required for GHASH) @@ -1134,22 +1568,22 @@ ENTRY(aesni_gcm_enc) jb _initial_num_blocks_is_1_encrypt je _initial_num_blocks_is_2_encrypt _initial_num_blocks_is_3_encrypt: - INITIAL_BLOCKS 3, %xmm9, %xmm10, %xmm13, %xmm11, %xmm12, %xmm0, \ + INITIAL_BLOCKS_ENC 3, %xmm9, %xmm10, %xmm13, %xmm11, %xmm12, %xmm0, \ %xmm1, %xmm2, %xmm3, %xmm4, %xmm8, %xmm5, %xmm6, 5, 678, enc sub $48, %r13 jmp _initial_blocks_encrypted _initial_num_blocks_is_2_encrypt: - INITIAL_BLOCKS 2, %xmm9, %xmm10, %xmm13, %xmm11, %xmm12, %xmm0, \ + INITIAL_BLOCKS_ENC 2, %xmm9, %xmm10, %xmm13, %xmm11, %xmm12, %xmm0, \ %xmm1, %xmm2, %xmm3, %xmm4, %xmm8, %xmm5, %xmm6, 6, 78, enc sub $32, %r13 jmp _initial_blocks_encrypted _initial_num_blocks_is_1_encrypt: - INITIAL_BLOCKS 1, %xmm9, %xmm10, %xmm13, %xmm11, %xmm12, %xmm0, \ + INITIAL_BLOCKS_ENC 1, %xmm9, %xmm10, %xmm13, %xmm11, %xmm12, %xmm0, \ %xmm1, %xmm2, %xmm3, %xmm4, %xmm8, %xmm5, %xmm6, 7, 8, enc sub $16, %r13 jmp _initial_blocks_encrypted _initial_num_blocks_is_0_encrypt: - INITIAL_BLOCKS 0, %xmm9, %xmm10, %xmm13, %xmm11, %xmm12, %xmm0, \ + INITIAL_BLOCKS_ENC 0, %xmm9, %xmm10, %xmm13, %xmm11, %xmm12, %xmm0, \ %xmm1, %xmm2, %xmm3, %xmm4, %xmm8, %xmm5, %xmm6, 8, 0, enc _initial_blocks_encrypted: @@ -1160,7 +1594,7 @@ _initial_blocks_encrypted: sub $64, %r13 je _four_cipher_left_encrypt _encrypt_by_4_encrypt: - GHASH_4_ENCRYPT_4_PARALLEL %xmm9, %xmm10, %xmm11, %xmm12, %xmm13, \ + GHASH_4_ENCRYPT_4_PARALLEL_ENC %xmm9, %xmm10, %xmm11, %xmm12, %xmm13, \ %xmm14, %xmm0, %xmm1, %xmm2, %xmm3, %xmm4, %xmm5, %xmm6, %xmm7, %xmm8, enc add $64, %r11 sub $64, %r13 @@ -1175,7 +1609,9 @@ _zero_cipher_left_encrypt: # Handle the last <16 Byte block seperately paddd ONE(%rip), %xmm0 # INCR CNT to get Yn - pshufb SHUF_MASK(%rip), %xmm0 + movdqa SHUF_MASK(%rip), %xmm10 + PSHUFB_XMM %xmm10, %xmm0 + ENCRYPT_SINGLE_BLOCK %xmm0, %xmm1 # Encrypt(K, Yn) sub $16, %r11 add %r13, %r11 @@ -1185,29 +1621,31 @@ _zero_cipher_left_encrypt: # adjust the shuffle mask pointer to be able to shift 16-r13 bytes # (%r13 is the number of bytes in plaintext mod 16) movdqu (%r12), %xmm2 # get the appropriate shuffle mask - pshufb %xmm2, %xmm1 # shift right 16-r13 byte + PSHUFB_XMM %xmm2, %xmm1 # shift right 16-r13 byte pxor %xmm1, %xmm0 # Plaintext XOR Encrypt(K, Yn) movdqu ALL_F-SHIFT_MASK(%r12), %xmm1 # get the appropriate mask to mask out top 16-r13 bytes of xmm0 pand %xmm1, %xmm0 # mask out top 16-r13 bytes of xmm0 + movdqa SHUF_MASK(%rip), %xmm10 + PSHUFB_XMM %xmm10,%xmm0 - pshufb SHUF_MASK(%rip),%xmm0 pxor %xmm0, %xmm8 GHASH_MUL %xmm8, %xmm13, %xmm9, %xmm10, %xmm11, %xmm5, %xmm6 # GHASH computation for the last <16 byte block sub %r13, %r11 add $16, %r11 - pshufb SHUF_MASK(%rip), %xmm0 + PSHUFB_XMM %xmm10, %xmm1 + # shuffle xmm0 back to output as ciphertext # Output %r13 bytes - movq %xmm0, %rax + MOVQ_R64_XMM %xmm0, %rax cmp $8, %r13 jle _less_than_8_bytes_left_encrypt mov %rax, (%arg2 , %r11, 1) add $8, %r11 psrldq $8, %xmm0 - movq %xmm0, %rax + MOVQ_R64_XMM %xmm0, %rax sub $8, %r13 _less_than_8_bytes_left_encrypt: mov %al, (%arg2, %r11, 1) @@ -1220,14 +1658,15 @@ _multiple_of_16_bytes_encrypt: shl $3, %r12 movd %r12d, %xmm15 # len(A) in %xmm15 shl $3, %arg4 # len(C) in bits (*128) - movq %arg4, %xmm1 + MOVQ_R64_XMM %arg4, %xmm1 pslldq $8, %xmm15 # %xmm15 = len(A)||0x0000000000000000 pxor %xmm1, %xmm15 # %xmm15 = len(A)||len(C) pxor %xmm15, %xmm8 GHASH_MUL %xmm8, %xmm13, %xmm9, %xmm10, %xmm11, %xmm5, %xmm6 # final GHASH computation + movdqa SHUF_MASK(%rip), %xmm10 + PSHUFB_XMM %xmm10, %xmm8 # perform a 16 byte swap - pshufb SHUF_MASK(%rip), %xmm8 # perform a 16 byte swap mov %arg5, %rax # %rax = *Y0 movdqu (%rax), %xmm0 # %xmm0 = Y0 ENCRYPT_SINGLE_BLOCK %xmm0, %xmm15 # Encrypt(K, Y0) @@ -1240,11 +1679,11 @@ _return_T_encrypt: cmp $12, %r11 je _T_12_encrypt _T_8_encrypt: - movq %xmm0, %rax + MOVQ_R64_XMM %xmm0, %rax mov %rax, (%r10) jmp _return_T_done_encrypt _T_12_encrypt: - movq %xmm0, %rax + MOVQ_R64_XMM %xmm0, %rax mov %rax, (%r10) psrldq $8, %xmm0 movd %xmm0, %eax @@ -1258,6 +1697,7 @@ _return_T_done_encrypt: pop %r13 pop %r12 ret + #endif -- cgit v1.2.3 From fdea0571ddca8e3f22448f66d72a034575abea28 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 13 Dec 2010 12:55:39 +0100 Subject: ASoC: Fix merge errors with flush_scheduled_work() removal delayed_work was moved to dapm in the commit ce6120cca2589ede530200c7cfe11ac9f144333c ASoC: Decouple DAPM from CODECs Signed-off-by: Takashi Iwai --- sound/soc/codecs/wm8350.c | 2 +- sound/soc/codecs/wm8753.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/wm8350.c b/sound/soc/codecs/wm8350.c index f8a8a6944e65..07ba7e3f6a8c 100644 --- a/sound/soc/codecs/wm8350.c +++ b/sound/soc/codecs/wm8350.c @@ -1643,7 +1643,7 @@ static int wm8350_codec_remove(struct snd_soc_codec *codec) /* if there was any work waiting then we run it now and * wait for its completion */ - flush_delayed_work_sync(&codec->delayed_work); + flush_delayed_work_sync(&codec->dapm.delayed_work); wm8350_set_bias_level(codec, SND_SOC_BIAS_OFF); diff --git a/sound/soc/codecs/wm8753.c b/sound/soc/codecs/wm8753.c index 747457193887..73507e71cb79 100644 --- a/sound/soc/codecs/wm8753.c +++ b/sound/soc/codecs/wm8753.c @@ -1587,7 +1587,7 @@ static int wm8753_probe(struct snd_soc_codec *codec) /* power down chip */ static int wm8753_remove(struct snd_soc_codec *codec) { - flush_delayed_work_sync(&codec->delayed_work); + flush_delayed_work_sync(&codec->dapm.delayed_work); wm8753_set_bias_level(codec, SND_SOC_BIAS_OFF); return 0; -- cgit v1.2.3 From e4ea0c16a85d221ebcc3a21f32e321440459e0fc Mon Sep 17 00:00:00 2001 From: Shaohua Li writes Date: Mon, 13 Dec 2010 14:32:22 +0100 Subject: block cfq: select new workload if priority changed If priority is changed, continuing to check workload_expires and service tree count of the previous workload does not make sense. We should always choose the workload with lowest key of new priority in such case. Signed-off-by: Shaohua Li Reviewed-by: Jeff Moyer Signed-off-by: Jens Axboe --- block/cfq-iosched.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c index 5d0349d602fe..9b186fd6bf47 100644 --- a/block/cfq-iosched.c +++ b/block/cfq-iosched.c @@ -2101,6 +2101,7 @@ static void choose_service_tree(struct cfq_data *cfqd, struct cfq_group *cfqg) unsigned count; struct cfq_rb_root *st; unsigned group_slice; + enum wl_prio_t original_prio = cfqd->serving_prio; if (!cfqg) { cfqd->serving_prio = IDLE_WORKLOAD; @@ -2119,6 +2120,9 @@ static void choose_service_tree(struct cfq_data *cfqd, struct cfq_group *cfqg) return; } + if (original_prio != cfqd->serving_prio) + goto new_workload; + /* * For RT and BE, we have to choose also the type * (SYNC, SYNC_NOIDLE, ASYNC), and to compute a workload @@ -2133,6 +2137,7 @@ static void choose_service_tree(struct cfq_data *cfqd, struct cfq_group *cfqg) if (count && !time_after(jiffies, cfqd->workload_expires)) return; +new_workload: /* otherwise select new workload type */ cfqd->serving_type = cfq_choose_wl(cfqd, cfqg, cfqd->serving_prio); -- cgit v1.2.3 From 0f0e25282b93242780a405585a8e3e6f0cc7fa91 Mon Sep 17 00:00:00 2001 From: Jarkko Nikula Date: Fri, 10 Dec 2010 20:54:49 +0200 Subject: ASoC: Fix build error caused by merging a fix for 2.6.37 into 2.6.38 Fix "ASoC: Fix bias power down of non-DAPM codec" for 3.6.37 will cause a build error when merging into ASoC for-2.6.38. Fix the issue by doing a change that commit ce6120c "ASoC: Decouple DAPM from CODECs" would do. Signed-off-by: Jarkko Nikula Acked-by: Liam Girdwood 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 45e6a1120cbd..b521a139305a 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -982,7 +982,7 @@ static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event) sys_power = 1; break; case SND_SOC_DAPM_STREAM_STOP: - sys_power = !!codec->active; + sys_power = !!dapm->codec->active; break; case SND_SOC_DAPM_STREAM_SUSPEND: sys_power = 0; -- cgit v1.2.3 From 7d8316df44053687625eef792d53b3ac62e82248 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Mon, 13 Dec 2010 17:03:27 +0000 Subject: ASoC: Fix AC'97 registration unwind soc_unregister_ac97_dai_link() takes a CODEC as an argument, not a rtd like the registration function, so give it what it's looking for. Signed-off-by: Mark Brown Acked-by: Liam Girdwood --- sound/soc/soc-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 68edc693a8a5..1dc4b11c1988 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -1830,7 +1830,7 @@ static void snd_soc_instantiate_card(struct snd_soc_card *card) if (ret < 0) { printk(KERN_ERR "asoc: failed to register AC97 %s\n", card->name); while (--i >= 0) - soc_unregister_ac97_dai_link(&card->rtd[i]); + soc_unregister_ac97_dai_link(card->rtd[i].codec); goto probe_aux_dev_err; } } -- cgit v1.2.3 From 5a7743edac3d720a52e721229938d21d40f045ce Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Mon, 13 Dec 2010 15:07:40 +0000 Subject: regulator: Update LDO2 for WM8958 LDO2 has a slightly different range of supported voltages on WM8958 so update the selector<->voltage mappings to match. Signed-off-by: Mark Brown Acked-by: Liam Girdwood --- drivers/regulator/wm8994-regulator.c | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/drivers/regulator/wm8994-regulator.c b/drivers/regulator/wm8994-regulator.c index 03713bc66e4a..21fefef02a43 100644 --- a/drivers/regulator/wm8994-regulator.c +++ b/drivers/regulator/wm8994-regulator.c @@ -131,10 +131,19 @@ static struct regulator_ops wm8994_ldo1_ops = { static int wm8994_ldo2_list_voltage(struct regulator_dev *rdev, unsigned int selector) { + struct wm8994_ldo *ldo = rdev_get_drvdata(rdev); + if (selector > WM8994_LDO2_MAX_SELECTOR) return -EINVAL; - return (selector * 100000) + 900000; + switch (ldo->wm8994->type) { + case WM8994: + return (selector * 100000) + 900000; + case WM8958: + return (selector * 100000) + 1000000; + default: + return -EINVAL; + } } static int wm8994_ldo2_get_voltage(struct regulator_dev *rdev) @@ -157,7 +166,17 @@ static int wm8994_ldo2_set_voltage(struct regulator_dev *rdev, struct wm8994_ldo *ldo = rdev_get_drvdata(rdev); int selector, v; - selector = (min_uV - 900000) / 100000; + switch (ldo->wm8994->type) { + case WM8994: + selector = (min_uV - 900000) / 100000; + break; + case WM8958: + selector = (min_uV - 1000000) / 100000; + break; + default: + return -EINVAL; + } + v = wm8994_ldo2_list_voltage(rdev, selector); if (v < 0 || v > max_uV) return -EINVAL; -- cgit v1.2.3 From 448d40140196b33f63a0a3f3f8bcad8f14c9c432 Mon Sep 17 00:00:00 2001 From: Marek Belisko Date: Mon, 13 Dec 2010 10:39:20 +0100 Subject: staging: ft1000: Always extract device number from netdev name. Using gCardIndex as global variable was not correctly used because for every plugged device was set to 0 in init_ft1000_netdev. Remove global definition. Use it locally and for every plugged device extract number from net device name. Signed-off-by: Marek Belisko Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ft1000/ft1000-usb/ft1000_hw.c | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c index 7456787481c8..643a63794ade 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_hw.c @@ -41,7 +41,6 @@ static int ft1000_chkcard (struct ft1000_device *dev); //Jim static u8 tempbuffer[1600]; -static unsigned long gCardIndex; #define MAX_RCV_LOOP 100 @@ -773,8 +772,7 @@ u16 init_ft1000_netdev(struct ft1000_device *ft1000dev) int i, ret_val; struct list_head *cur, *tmp; char card_nr[2]; - - gCardIndex=0; //mbelian + unsigned long gCardIndex = 0; DEBUG("Enter init_ft1000_netdev...\n"); @@ -794,9 +792,6 @@ u16 init_ft1000_netdev(struct ft1000_device *ft1000dev) dev_alloc_name(netdev, netdev->name); - //for the first inserted card, decide the card index beginning number, in case there are existing network interfaces - if ( gCardIndex == 0 ) - { DEBUG("init_ft1000_netdev: network device name is %s\n", netdev->name); if ( strncmp(netdev->name,"eth", 3) == 0) { @@ -816,13 +811,6 @@ u16 init_ft1000_netdev(struct ft1000_device *ft1000dev) ret_val = -ENXIO; goto err_net; } - } - else - { - //not the first inserted card, increase card number by 1 - pInfo->CardNumber = gCardIndex; - /*DEBUG("card number = %d\n", pInfo->CardNumber);*/ //mbelian - } memset(&pInfo->stats, 0, sizeof(struct net_device_stats) ); -- cgit v1.2.3 From ed271e049d4e0bf8c6586c9626964a01d1c62fa2 Mon Sep 17 00:00:00 2001 From: Xenofon Foukas Date: Fri, 10 Dec 2010 21:07:25 +0200 Subject: Staging: comedi: Fix coding style issues in ni_tiocmd.c This patch fixes the following issues in ni_tiocmd.c: WARNING: braces {} are not necessary for any arm of this statement WARNING: braces {} are not necessary for single statement blocks WARNING: printk() should include KERN_ facility level WARNING: line over 80 characters __func__ should be used instead of gcc specific __FUNCTION__ ERROR: that open brace { should be on the previous line WARNING: EXPORT_SYMBOL(foo); should immediately follow its function/variable Signed-off-by: Xenofon Foukas Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ni_tiocmd.c | 71 ++++++++++++++---------------- 1 file changed, 33 insertions(+), 38 deletions(-) diff --git a/drivers/staging/comedi/drivers/ni_tiocmd.c b/drivers/staging/comedi/drivers/ni_tiocmd.c index b0d44b547a69..a9611587460a 100644 --- a/drivers/staging/comedi/drivers/ni_tiocmd.c +++ b/drivers/staging/comedi/drivers/ni_tiocmd.c @@ -62,11 +62,10 @@ static void ni_tio_configure_dma(struct ni_gpct *counter, short enable, unsigned input_select_bits = 0; if (enable) { - if (read_not_write) { + if (read_not_write) input_select_bits |= Gi_Read_Acknowledges_Irq; - } else { + else input_select_bits |= Gi_Write_Acknowledges_Irq; - } } ni_tio_set_bits(counter, NITIO_Gi_Input_Select_Reg(counter->counter_index), @@ -84,9 +83,8 @@ static void ni_tio_configure_dma(struct ni_gpct *counter, short enable, gi_dma_config_bits |= Gi_DMA_Enable_Bit; gi_dma_config_bits |= Gi_DMA_Int_Bit; } - if (read_not_write == 0) { + if (read_not_write == 0) gi_dma_config_bits |= Gi_DMA_Write_Bit; - } ni_tio_set_bits(counter, NITIO_Gi_DMA_Config_Reg(counter-> counter_index), @@ -174,7 +172,7 @@ static int ni_tio_input_cmd(struct ni_gpct *counter, struct comedi_async *async) static int ni_tio_output_cmd(struct ni_gpct *counter, struct comedi_async *async) { - printk("ni_tio: output commands not yet implemented.\n"); + printk(KERN_ERR "ni_tio: output commands not yet implemented.\n"); return -ENOTSUPP; counter->mite_chan->dir = COMEDI_OUTPUT; @@ -198,9 +196,8 @@ static int ni_tio_cmd_setup(struct ni_gpct *counter, struct comedi_async *async) set_gate_source = 1; gate_source = cmd->convert_arg; } - if (set_gate_source) { + if (set_gate_source) retval = ni_tio_set_gate_src(counter, 0, gate_source); - } if (cmd->flags & TRIG_WAKE_EOS) { ni_tio_set_bits(counter, NITIO_Gi_Interrupt_Enable_Reg(counter-> @@ -221,22 +218,21 @@ int ni_tio_cmd(struct ni_gpct *counter, struct comedi_async *async) spin_lock_irqsave(&counter->lock, flags); if (counter->mite_chan == NULL) { - printk - ("ni_tio: commands only supported with DMA. Interrupt-driven commands not yet implemented.\n"); + printk(KERN_ERR "ni_tio: commands only supported with DMA. Interrupt-driven commands not yet implemented.\n"); retval = -EIO; } else { retval = ni_tio_cmd_setup(counter, async); if (retval == 0) { - if (cmd->flags & CMDF_WRITE) { + if (cmd->flags & CMDF_WRITE) retval = ni_tio_output_cmd(counter, async); - } else { + else retval = ni_tio_input_cmd(counter, async); - } } } spin_unlock_irqrestore(&counter->lock, flags); return retval; } +EXPORT_SYMBOL_GPL(ni_tio_cmd); int ni_tio_cmdtest(struct ni_gpct *counter, struct comedi_cmd *cmd) { @@ -342,6 +338,7 @@ int ni_tio_cmdtest(struct ni_gpct *counter, struct comedi_cmd *cmd) return 0; } +EXPORT_SYMBOL_GPL(ni_tio_cmdtest); int ni_tio_cancel(struct ni_gpct *counter) { @@ -349,9 +346,8 @@ int ni_tio_cancel(struct ni_gpct *counter) ni_tio_arm(counter, 0, 0); spin_lock_irqsave(&counter->lock, flags); - if (counter->mite_chan) { + if (counter->mite_chan) mite_dma_disarm(counter->mite_chan); - } spin_unlock_irqrestore(&counter->lock, flags); ni_tio_configure_dma(counter, 0, 0); @@ -361,10 +357,11 @@ int ni_tio_cancel(struct ni_gpct *counter) 0x0); return 0; } +EXPORT_SYMBOL_GPL(ni_tio_cancel); - /* During buffered input counter operation for e-series, the gate interrupt is acked - automatically by the dma controller, due to the Gi_Read/Write_Acknowledges_IRQ bits - in the input select register. */ + /* During buffered input counter operation for e-series, the gate + interrupt is acked automatically by the dma controller, due to the + Gi_Read/Write_Acknowledges_IRQ bits in the input select register. */ static int should_ack_gate(struct ni_gpct *counter) { unsigned long flags; @@ -372,7 +369,10 @@ static int should_ack_gate(struct ni_gpct *counter) switch (counter->counter_dev->variant) { case ni_gpct_variant_m_series: - case ni_gpct_variant_660x: /* not sure if 660x really supports gate interrupts (the bits are not listed in register-level manual) */ + /* not sure if 660x really supports gate + interrupts (the bits are not listed + in register-level manual) */ + case ni_gpct_variant_660x: return 1; break; case ni_gpct_variant_e_series: @@ -416,7 +416,8 @@ void ni_tio_acknowledge_and_confirm(struct ni_gpct *counter, int *gate_error, if (gxx_status & Gi_Gate_Error_Bit(counter->counter_index)) { ack |= Gi_Gate_Error_Confirm_Bit(counter->counter_index); if (gate_error) { - /*660x don't support automatic acknowledgement of gate interrupt via dma read/write + /*660x don't support automatic acknowledgement + of gate interrupt via dma read/write and report bogus gate errors */ if (counter->counter_dev->variant != ni_gpct_variant_660x) { @@ -429,9 +430,8 @@ void ni_tio_acknowledge_and_confirm(struct ni_gpct *counter, int *gate_error, if (tc_error) *tc_error = 1; } - if (gi_status & Gi_TC_Bit) { + if (gi_status & Gi_TC_Bit) ack |= Gi_TC_Interrupt_Ack_Bit; - } if (gi_status & Gi_Gate_Interrupt_Bit) { if (should_ack_gate(counter)) ack |= Gi_Gate_Interrupt_Ack_Bit; @@ -452,13 +452,14 @@ void ni_tio_acknowledge_and_confirm(struct ni_gpct *counter, int *gate_error, NITIO_Gxx_Joint_Status2_Reg (counter->counter_index)) & Gi_Permanent_Stale_Bit(counter->counter_index)) { - printk("%s: Gi_Permanent_Stale_Data detected.\n", - __FUNCTION__); + printk(KERN_INFO "%s: Gi_Permanent_Stale_Data detected.\n", + __func__); if (perm_stale_data) *perm_stale_data = 1; } } } +EXPORT_SYMBOL_GPL(ni_tio_acknowledge_and_confirm); void ni_tio_handle_interrupt(struct ni_gpct *counter, struct comedi_subdevice *s) @@ -472,20 +473,19 @@ void ni_tio_handle_interrupt(struct ni_gpct *counter, ni_tio_acknowledge_and_confirm(counter, &gate_error, &tc_error, &perm_stale_data, NULL); if (gate_error) { - printk("%s: Gi_Gate_Error detected.\n", __FUNCTION__); + printk(KERN_NOTICE "%s: Gi_Gate_Error detected.\n", __func__); s->async->events |= COMEDI_CB_OVERFLOW; } - if (perm_stale_data) { + if (perm_stale_data) s->async->events |= COMEDI_CB_ERROR; - } switch (counter->counter_dev->variant) { case ni_gpct_variant_m_series: case ni_gpct_variant_660x: if (read_register(counter, - NITIO_Gi_DMA_Status_Reg - (counter->counter_index)) & Gi_DRQ_Error_Bit) - { - printk("%s: Gi_DRQ_Error detected.\n", __FUNCTION__); + NITIO_Gi_DMA_Status_Reg + (counter->counter_index)) & Gi_DRQ_Error_Bit) { + printk(KERN_NOTICE "%s: Gi_DRQ_Error detected.\n", + __func__); s->async->events |= COMEDI_CB_OVERFLOW; } break; @@ -506,6 +506,7 @@ void ni_tio_handle_interrupt(struct ni_gpct *counter, mite_sync_input_dma(counter->mite_chan, s->async); spin_unlock_irqrestore(&counter->lock, flags); } +EXPORT_SYMBOL_GPL(ni_tio_handle_interrupt); void ni_tio_set_mite_channel(struct ni_gpct *counter, struct mite_channel *mite_chan) @@ -516,6 +517,7 @@ void ni_tio_set_mite_channel(struct ni_gpct *counter, counter->mite_chan = mite_chan; spin_unlock_irqrestore(&counter->lock, flags); } +EXPORT_SYMBOL_GPL(ni_tio_set_mite_channel); static int __init ni_tiocmd_init_module(void) { @@ -529,10 +531,3 @@ static void __exit ni_tiocmd_cleanup_module(void) } module_exit(ni_tiocmd_cleanup_module); - -EXPORT_SYMBOL_GPL(ni_tio_cmd); -EXPORT_SYMBOL_GPL(ni_tio_cmdtest); -EXPORT_SYMBOL_GPL(ni_tio_cancel); -EXPORT_SYMBOL_GPL(ni_tio_handle_interrupt); -EXPORT_SYMBOL_GPL(ni_tio_set_mite_channel); -EXPORT_SYMBOL_GPL(ni_tio_acknowledge_and_confirm); -- cgit v1.2.3 From 6292817d58637f85dd623cfe563c7f5ec4f4c470 Mon Sep 17 00:00:00 2001 From: Ruben Smits Date: Sat, 11 Dec 2010 08:26:18 +0100 Subject: staging: comedi: add support for newer jr3 1-channel pci board add DEVICE_ID to table Signed-off-by: Ruben Smits Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/jr3_pci.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/staging/comedi/drivers/jr3_pci.c b/drivers/staging/comedi/drivers/jr3_pci.c index 8b383ee959b2..5c6c72744167 100644 --- a/drivers/staging/comedi/drivers/jr3_pci.c +++ b/drivers/staging/comedi/drivers/jr3_pci.c @@ -54,6 +54,7 @@ Devices: [JR3] PCI force sensor board (jr3_pci) #define PCI_VENDOR_ID_JR3 0x1762 #define PCI_DEVICE_ID_JR3_1_CHANNEL 0x3111 +#define PCI_DEVICE_ID_JR3_1_CHANNEL_NEW 0x1111 #define PCI_DEVICE_ID_JR3_2_CHANNEL 0x3112 #define PCI_DEVICE_ID_JR3_3_CHANNEL 0x3113 #define PCI_DEVICE_ID_JR3_4_CHANNEL 0x3114 @@ -73,6 +74,8 @@ static DEFINE_PCI_DEVICE_TABLE(jr3_pci_pci_table) = { { PCI_VENDOR_ID_JR3, PCI_DEVICE_ID_JR3_1_CHANNEL, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { + PCI_VENDOR_ID_JR3, PCI_DEVICE_ID_JR3_1_CHANNEL_NEW, + PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { PCI_VENDOR_ID_JR3, PCI_DEVICE_ID_JR3_2_CHANNEL, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, { PCI_VENDOR_ID_JR3, PCI_DEVICE_ID_JR3_3_CHANNEL, @@ -807,6 +810,10 @@ static int jr3_pci_attach(struct comedi_device *dev, devpriv->n_channels = 1; } break; + case PCI_DEVICE_ID_JR3_1_CHANNEL_NEW:{ + devpriv->n_channels = 1; + } + break; case PCI_DEVICE_ID_JR3_2_CHANNEL:{ devpriv->n_channels = 2; } -- cgit v1.2.3 From ced17a68b727d8509a4bde0b2ee7d0d120371e66 Mon Sep 17 00:00:00 2001 From: "L. Alberto Giménez" Date: Sun, 12 Dec 2010 18:56:29 +0100 Subject: Staging: rt2860: Clean spaces before tabs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix checkpatch complains Signed-off-by: L. Alberto Giménez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rt2860/oid.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/rt2860/oid.h b/drivers/staging/rt2860/oid.h index eaa3fe005088..5a25f0d3cfeb 100644 --- a/drivers/staging/rt2860/oid.h +++ b/drivers/staging/rt2860/oid.h @@ -88,7 +88,7 @@ #define MAX_NUMBER_OF_DLS_ENTRY 4 #define RT_QUERY_SIGNAL_CONTEXT 0x0402 -#define RT_SET_IAPP_PID 0x0404 +#define RT_SET_IAPP_PID 0x0404 #define RT_SET_APD_PID 0x0405 #define RT_SET_DEL_MAC_ENTRY 0x0406 #define RT_QUERY_EVENT_TABLE 0x0407 -- cgit v1.2.3 From e1b8a37ede8b47dbad002ec61a67706b70b23ccf Mon Sep 17 00:00:00 2001 From: "L. Alberto Giménez" Date: Sun, 12 Dec 2010 18:56:30 +0100 Subject: Staging: rt2860: Avoid extern in .c file MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit rt28xx_close and rt28xx_open are already declared in a file included in rt_config.h, so there is no need to declare them again. Signed-off-by: L. Alberto Giménez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rt2860/pci_main_dev.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/drivers/staging/rt2860/pci_main_dev.c b/drivers/staging/rt2860/pci_main_dev.c index c35c804a083e..cd028e7a8f91 100644 --- a/drivers/staging/rt2860/pci_main_dev.c +++ b/drivers/staging/rt2860/pci_main_dev.c @@ -51,9 +51,6 @@ MODULE_ALIAS("rt3090sta"); /* */ /* Function declarations */ /* */ -extern int rt28xx_close(IN struct net_device *net_dev); -extern int rt28xx_open(struct net_device *net_dev); - static void __devexit rt2860_remove_one(struct pci_dev *pci_dev); static int __devinit rt2860_probe(struct pci_dev *pci_dev, const struct pci_device_id *ent); -- cgit v1.2.3 From 85799a37553f89b23797ec4f69e45f6c5e9109df Mon Sep 17 00:00:00 2001 From: Haiyang Zhang Date: Fri, 10 Dec 2010 12:03:54 -0800 Subject: staging: hv: Convert camel cased variables in netvsc.c to lower cases Signed-off-by: Haiyang Zhang Signed-off-by: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/netvsc.c | 852 +++++++++++++++++++++++--------------------- 1 file changed, 445 insertions(+), 407 deletions(-) diff --git a/drivers/staging/hv/netvsc.c b/drivers/staging/hv/netvsc.c index 8022781a9b13..1c1ee57482a5 100644 --- a/drivers/staging/hv/netvsc.c +++ b/drivers/staging/hv/netvsc.c @@ -31,141 +31,141 @@ /* Globals */ -static const char *gDriverName = "netvsc"; +static const char *driver_name = "netvsc"; /* {F8615163-DF3E-46c5-913F-F2D2F965ED0E} */ -static const struct hv_guid gNetVscDeviceType = { +static const struct hv_guid netvsc_device_type = { .data = { 0x63, 0x51, 0x61, 0xF8, 0x3E, 0xDF, 0xc5, 0x46, 0x91, 0x3F, 0xF2, 0xD2, 0xF9, 0x65, 0xED, 0x0E } }; -static int NetVscOnDeviceAdd(struct hv_device *Device, void *AdditionalInfo); +static int NetVscOnDeviceAdd(struct hv_device *device, void *additional_info); -static int NetVscOnDeviceRemove(struct hv_device *Device); +static int NetVscOnDeviceRemove(struct hv_device *device); -static void NetVscOnCleanup(struct hv_driver *Driver); +static void NetVscOnCleanup(struct hv_driver *driver); static void NetVscOnChannelCallback(void *context); -static int NetVscInitializeSendBufferWithNetVsp(struct hv_device *Device); +static int NetVscInitializeSendBufferWithNetVsp(struct hv_device *device); -static int NetVscInitializeReceiveBufferWithNetVsp(struct hv_device *Device); +static int NetVscInitializeReceiveBufferWithNetVsp(struct hv_device *device); -static int NetVscDestroySendBuffer(struct netvsc_device *NetDevice); +static int NetVscDestroySendBuffer(struct netvsc_device *net_device); -static int NetVscDestroyReceiveBuffer(struct netvsc_device *NetDevice); +static int NetVscDestroyReceiveBuffer(struct netvsc_device *net_device); -static int NetVscConnectToVsp(struct hv_device *Device); +static int NetVscConnectToVsp(struct hv_device *device); -static void NetVscOnSendCompletion(struct hv_device *Device, - struct vmpacket_descriptor *Packet); +static void NetVscOnSendCompletion(struct hv_device *device, + struct vmpacket_descriptor *packet); -static int NetVscOnSend(struct hv_device *Device, - struct hv_netvsc_packet *Packet); +static int NetVscOnSend(struct hv_device *device, + struct hv_netvsc_packet *packet); -static void NetVscOnReceive(struct hv_device *Device, - struct vmpacket_descriptor *Packet); +static void NetVscOnReceive(struct hv_device *device, + struct vmpacket_descriptor *packet); -static void NetVscOnReceiveCompletion(void *Context); +static void NetVscOnReceiveCompletion(void *context); -static void NetVscSendReceiveCompletion(struct hv_device *Device, - u64 TransactionId); +static void NetVscSendReceiveCompletion(struct hv_device *device, + u64 transaction_id); -static struct netvsc_device *AllocNetDevice(struct hv_device *Device) +static struct netvsc_device *AllocNetDevice(struct hv_device *device) { - struct netvsc_device *netDevice; + struct netvsc_device *net_device; - netDevice = kzalloc(sizeof(struct netvsc_device), GFP_KERNEL); - if (!netDevice) + net_device = kzalloc(sizeof(struct netvsc_device), GFP_KERNEL); + if (!net_device) return NULL; /* Set to 2 to allow both inbound and outbound traffic */ - atomic_cmpxchg(&netDevice->RefCount, 0, 2); + atomic_cmpxchg(&net_device->RefCount, 0, 2); - netDevice->Device = Device; - Device->Extension = netDevice; + net_device->Device = device; + device->Extension = net_device; - return netDevice; + return net_device; } -static void FreeNetDevice(struct netvsc_device *Device) +static void FreeNetDevice(struct netvsc_device *device) { - WARN_ON(atomic_read(&Device->RefCount) == 0); - Device->Device->Extension = NULL; - kfree(Device); + WARN_ON(atomic_read(&device->RefCount) == 0); + device->Device->Extension = NULL; + kfree(device); } /* Get the net device object iff exists and its refcount > 1 */ -static struct netvsc_device *GetOutboundNetDevice(struct hv_device *Device) +static struct netvsc_device *GetOutboundNetDevice(struct hv_device *device) { - struct netvsc_device *netDevice; + struct netvsc_device *net_device; - netDevice = Device->Extension; - if (netDevice && atomic_read(&netDevice->RefCount) > 1) - atomic_inc(&netDevice->RefCount); + net_device = device->Extension; + if (net_device && atomic_read(&net_device->RefCount) > 1) + atomic_inc(&net_device->RefCount); else - netDevice = NULL; + net_device = NULL; - return netDevice; + return net_device; } /* Get the net device object iff exists and its refcount > 0 */ -static struct netvsc_device *GetInboundNetDevice(struct hv_device *Device) +static struct netvsc_device *GetInboundNetDevice(struct hv_device *device) { - struct netvsc_device *netDevice; + struct netvsc_device *net_device; - netDevice = Device->Extension; - if (netDevice && atomic_read(&netDevice->RefCount)) - atomic_inc(&netDevice->RefCount); + net_device = device->Extension; + if (net_device && atomic_read(&net_device->RefCount)) + atomic_inc(&net_device->RefCount); else - netDevice = NULL; + net_device = NULL; - return netDevice; + return net_device; } -static void PutNetDevice(struct hv_device *Device) +static void PutNetDevice(struct hv_device *device) { - struct netvsc_device *netDevice; + struct netvsc_device *net_device; - netDevice = Device->Extension; + net_device = device->Extension; /* ASSERT(netDevice); */ - atomic_dec(&netDevice->RefCount); + atomic_dec(&net_device->RefCount); } -static struct netvsc_device *ReleaseOutboundNetDevice(struct hv_device *Device) +static struct netvsc_device *ReleaseOutboundNetDevice(struct hv_device *device) { - struct netvsc_device *netDevice; + struct netvsc_device *net_device; - netDevice = Device->Extension; - if (netDevice == NULL) + net_device = device->Extension; + if (net_device == NULL) return NULL; /* Busy wait until the ref drop to 2, then set it to 1 */ - while (atomic_cmpxchg(&netDevice->RefCount, 2, 1) != 2) + while (atomic_cmpxchg(&net_device->RefCount, 2, 1) != 2) udelay(100); - return netDevice; + return net_device; } -static struct netvsc_device *ReleaseInboundNetDevice(struct hv_device *Device) +static struct netvsc_device *ReleaseInboundNetDevice(struct hv_device *device) { - struct netvsc_device *netDevice; + struct netvsc_device *net_device; - netDevice = Device->Extension; - if (netDevice == NULL) + net_device = device->Extension; + if (net_device == NULL) return NULL; /* Busy wait until the ref drop to 1, then set it to 0 */ - while (atomic_cmpxchg(&netDevice->RefCount, 1, 0) != 1) + while (atomic_cmpxchg(&net_device->RefCount, 1, 0) != 1) udelay(100); - Device->Extension = NULL; - return netDevice; + device->Extension = NULL; + return net_device; } /* @@ -185,8 +185,8 @@ int NetVscInitialize(struct hv_driver *drv) /* Make sure we are at least 2 pages since 1 page is used for control */ /* ASSERT(driver->RingBufferSize >= (PAGE_SIZE << 1)); */ - drv->name = gDriverName; - memcpy(&drv->deviceType, &gNetVscDeviceType, sizeof(struct hv_guid)); + drv->name = driver_name; + memcpy(&drv->deviceType, &netvsc_device_type, sizeof(struct hv_guid)); /* Make sure it is set by the caller */ /* FIXME: These probably should still be tested in some way */ @@ -204,14 +204,14 @@ int NetVscInitialize(struct hv_driver *drv) return 0; } -static int NetVscInitializeReceiveBufferWithNetVsp(struct hv_device *Device) +static int NetVscInitializeReceiveBufferWithNetVsp(struct hv_device *device) { int ret = 0; - struct netvsc_device *netDevice; - struct nvsp_message *initPacket; + struct netvsc_device *net_device; + struct nvsp_message *init_packet; - netDevice = GetOutboundNetDevice(Device); - if (!netDevice) { + net_device = GetOutboundNetDevice(device); + if (!net_device) { DPRINT_ERR(NETVSC, "unable to get net device..." "device being destroyed?"); return -1; @@ -220,12 +220,12 @@ static int NetVscInitializeReceiveBufferWithNetVsp(struct hv_device *Device) /* page-size grandularity */ /* ASSERT((netDevice->ReceiveBufferSize & (PAGE_SIZE - 1)) == 0); */ - netDevice->ReceiveBuffer = - osd_page_alloc(netDevice->ReceiveBufferSize >> PAGE_SHIFT); - if (!netDevice->ReceiveBuffer) { + net_device->ReceiveBuffer = + osd_page_alloc(net_device->ReceiveBufferSize >> PAGE_SHIFT); + if (!net_device->ReceiveBuffer) { DPRINT_ERR(NETVSC, "unable to allocate receive buffer of size %d", - netDevice->ReceiveBufferSize); + net_device->ReceiveBufferSize); ret = -1; goto Cleanup; } @@ -240,9 +240,9 @@ static int NetVscInitializeReceiveBufferWithNetVsp(struct hv_device *Device) * channel. Note: This call uses the vmbus connection rather * than the channel to establish the gpadl handle. */ - ret = vmbus_establish_gpadl(Device->channel, netDevice->ReceiveBuffer, - netDevice->ReceiveBufferSize, - &netDevice->ReceiveBufferGpadlHandle); + ret = vmbus_establish_gpadl(device->channel, net_device->ReceiveBuffer, + net_device->ReceiveBufferSize, + &net_device->ReceiveBufferGpadlHandle); if (ret != 0) { DPRINT_ERR(NETVSC, "unable to establish receive buffer's gpadl"); @@ -254,18 +254,20 @@ static int NetVscInitializeReceiveBufferWithNetVsp(struct hv_device *Device) /* Notify the NetVsp of the gpadl handle */ DPRINT_INFO(NETVSC, "Sending NvspMessage1TypeSendReceiveBuffer..."); - initPacket = &netDevice->ChannelInitPacket; + init_packet = &net_device->ChannelInitPacket; - memset(initPacket, 0, sizeof(struct nvsp_message)); + memset(init_packet, 0, sizeof(struct nvsp_message)); - initPacket->Header.MessageType = NvspMessage1TypeSendReceiveBuffer; - initPacket->Messages.Version1Messages.SendReceiveBuffer.GpadlHandle = netDevice->ReceiveBufferGpadlHandle; - initPacket->Messages.Version1Messages.SendReceiveBuffer.Id = NETVSC_RECEIVE_BUFFER_ID; + init_packet->Header.MessageType = NvspMessage1TypeSendReceiveBuffer; + init_packet->Messages.Version1Messages.SendReceiveBuffer. + GpadlHandle = net_device->ReceiveBufferGpadlHandle; + init_packet->Messages.Version1Messages. + SendReceiveBuffer.Id = NETVSC_RECEIVE_BUFFER_ID; /* Send the gpadl notification request */ - ret = vmbus_sendpacket(Device->channel, initPacket, + ret = vmbus_sendpacket(device->channel, init_packet, sizeof(struct nvsp_message), - (unsigned long)initPacket, + (unsigned long)init_packet, VmbusPacketTypeDataInBand, VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); if (ret != 0) { @@ -274,13 +276,15 @@ static int NetVscInitializeReceiveBufferWithNetVsp(struct hv_device *Device) goto Cleanup; } - osd_waitevent_wait(netDevice->ChannelInitEvent); + osd_waitevent_wait(net_device->ChannelInitEvent); /* Check the response */ - if (initPacket->Messages.Version1Messages.SendReceiveBufferComplete.Status != NvspStatusSuccess) { + if (init_packet->Messages.Version1Messages. + SendReceiveBufferComplete.Status != NvspStatusSuccess) { DPRINT_ERR(NETVSC, "Unable to complete receive buffer " "initialzation with NetVsp - status %d", - initPacket->Messages.Version1Messages.SendReceiveBufferComplete.Status); + init_packet->Messages.Version1Messages. + SendReceiveBufferComplete.Status); ret = -1; goto Cleanup; } @@ -289,32 +293,36 @@ static int NetVscInitializeReceiveBufferWithNetVsp(struct hv_device *Device) /* ASSERT(netDevice->ReceiveSectionCount == 0); */ /* ASSERT(netDevice->ReceiveSections == NULL); */ - netDevice->ReceiveSectionCount = initPacket->Messages.Version1Messages.SendReceiveBufferComplete.NumSections; + net_device->ReceiveSectionCount = init_packet->Messages. + Version1Messages.SendReceiveBufferComplete.NumSections; - netDevice->ReceiveSections = kmalloc(netDevice->ReceiveSectionCount * sizeof(struct nvsp_1_receive_buffer_section), GFP_KERNEL); - if (netDevice->ReceiveSections == NULL) { + net_device->ReceiveSections = kmalloc(net_device->ReceiveSectionCount + * sizeof(struct nvsp_1_receive_buffer_section), GFP_KERNEL); + if (net_device->ReceiveSections == NULL) { ret = -1; goto Cleanup; } - memcpy(netDevice->ReceiveSections, - initPacket->Messages.Version1Messages.SendReceiveBufferComplete.Sections, - netDevice->ReceiveSectionCount * sizeof(struct nvsp_1_receive_buffer_section)); + memcpy(net_device->ReceiveSections, + init_packet->Messages.Version1Messages. + SendReceiveBufferComplete.Sections, + net_device->ReceiveSectionCount * + sizeof(struct nvsp_1_receive_buffer_section)); DPRINT_INFO(NETVSC, "Receive sections info (count %d, offset %d, " "endoffset %d, suballoc size %d, num suballocs %d)", - netDevice->ReceiveSectionCount, - netDevice->ReceiveSections[0].Offset, - netDevice->ReceiveSections[0].EndOffset, - netDevice->ReceiveSections[0].SubAllocationSize, - netDevice->ReceiveSections[0].NumSubAllocations); + net_device->ReceiveSectionCount, + net_device->ReceiveSections[0].Offset, + net_device->ReceiveSections[0].EndOffset, + net_device->ReceiveSections[0].SubAllocationSize, + net_device->ReceiveSections[0].NumSubAllocations); /* * For 1st release, there should only be 1 section that represents the * entire receive buffer */ - if (netDevice->ReceiveSectionCount != 1 || - netDevice->ReceiveSections->Offset != 0) { + if (net_device->ReceiveSectionCount != 1 || + net_device->ReceiveSections->Offset != 0) { ret = -1; goto Cleanup; } @@ -322,26 +330,26 @@ static int NetVscInitializeReceiveBufferWithNetVsp(struct hv_device *Device) goto Exit; Cleanup: - NetVscDestroyReceiveBuffer(netDevice); + NetVscDestroyReceiveBuffer(net_device); Exit: - PutNetDevice(Device); + PutNetDevice(device); return ret; } -static int NetVscInitializeSendBufferWithNetVsp(struct hv_device *Device) +static int NetVscInitializeSendBufferWithNetVsp(struct hv_device *device) { int ret = 0; - struct netvsc_device *netDevice; - struct nvsp_message *initPacket; + struct netvsc_device *net_device; + struct nvsp_message *init_packet; - netDevice = GetOutboundNetDevice(Device); - if (!netDevice) { + net_device = GetOutboundNetDevice(device); + if (!net_device) { DPRINT_ERR(NETVSC, "unable to get net device..." "device being destroyed?"); return -1; } - if (netDevice->SendBufferSize <= 0) { + if (net_device->SendBufferSize <= 0) { ret = -EINVAL; goto Cleanup; } @@ -349,11 +357,11 @@ static int NetVscInitializeSendBufferWithNetVsp(struct hv_device *Device) /* page-size grandularity */ /* ASSERT((netDevice->SendBufferSize & (PAGE_SIZE - 1)) == 0); */ - netDevice->SendBuffer = - osd_page_alloc(netDevice->SendBufferSize >> PAGE_SHIFT); - if (!netDevice->SendBuffer) { + net_device->SendBuffer = + osd_page_alloc(net_device->SendBufferSize >> PAGE_SHIFT); + if (!net_device->SendBuffer) { DPRINT_ERR(NETVSC, "unable to allocate send buffer of size %d", - netDevice->SendBufferSize); + net_device->SendBufferSize); ret = -1; goto Cleanup; } @@ -367,9 +375,9 @@ static int NetVscInitializeSendBufferWithNetVsp(struct hv_device *Device) * channel. Note: This call uses the vmbus connection rather * than the channel to establish the gpadl handle. */ - ret = vmbus_establish_gpadl(Device->channel, netDevice->SendBuffer, - netDevice->SendBufferSize, - &netDevice->SendBufferGpadlHandle); + ret = vmbus_establish_gpadl(device->channel, net_device->SendBuffer, + net_device->SendBufferSize, + &net_device->SendBufferGpadlHandle); if (ret != 0) { DPRINT_ERR(NETVSC, "unable to establish send buffer's gpadl"); goto Cleanup; @@ -380,18 +388,20 @@ static int NetVscInitializeSendBufferWithNetVsp(struct hv_device *Device) /* Notify the NetVsp of the gpadl handle */ DPRINT_INFO(NETVSC, "Sending NvspMessage1TypeSendSendBuffer..."); - initPacket = &netDevice->ChannelInitPacket; + init_packet = &net_device->ChannelInitPacket; - memset(initPacket, 0, sizeof(struct nvsp_message)); + memset(init_packet, 0, sizeof(struct nvsp_message)); - initPacket->Header.MessageType = NvspMessage1TypeSendSendBuffer; - initPacket->Messages.Version1Messages.SendReceiveBuffer.GpadlHandle = netDevice->SendBufferGpadlHandle; - initPacket->Messages.Version1Messages.SendReceiveBuffer.Id = NETVSC_SEND_BUFFER_ID; + init_packet->Header.MessageType = NvspMessage1TypeSendSendBuffer; + init_packet->Messages.Version1Messages.SendReceiveBuffer. + GpadlHandle = net_device->SendBufferGpadlHandle; + init_packet->Messages.Version1Messages.SendReceiveBuffer.Id = + NETVSC_SEND_BUFFER_ID; /* Send the gpadl notification request */ - ret = vmbus_sendpacket(Device->channel, initPacket, + ret = vmbus_sendpacket(device->channel, init_packet, sizeof(struct nvsp_message), - (unsigned long)initPacket, + (unsigned long)init_packet, VmbusPacketTypeDataInBand, VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); if (ret != 0) { @@ -400,32 +410,35 @@ static int NetVscInitializeSendBufferWithNetVsp(struct hv_device *Device) goto Cleanup; } - osd_waitevent_wait(netDevice->ChannelInitEvent); + osd_waitevent_wait(net_device->ChannelInitEvent); /* Check the response */ - if (initPacket->Messages.Version1Messages.SendSendBufferComplete.Status != NvspStatusSuccess) { + if (init_packet->Messages.Version1Messages. + SendSendBufferComplete.Status != NvspStatusSuccess) { DPRINT_ERR(NETVSC, "Unable to complete send buffer " "initialzation with NetVsp - status %d", - initPacket->Messages.Version1Messages.SendSendBufferComplete.Status); + init_packet->Messages.Version1Messages. + SendSendBufferComplete.Status); ret = -1; goto Cleanup; } - netDevice->SendSectionSize = initPacket->Messages.Version1Messages.SendSendBufferComplete.SectionSize; + net_device->SendSectionSize = init_packet-> + Messages.Version1Messages.SendSendBufferComplete.SectionSize; goto Exit; Cleanup: - NetVscDestroySendBuffer(netDevice); + NetVscDestroySendBuffer(net_device); Exit: - PutNetDevice(Device); + PutNetDevice(device); return ret; } -static int NetVscDestroyReceiveBuffer(struct netvsc_device *NetDevice) +static int NetVscDestroyReceiveBuffer(struct netvsc_device *net_device) { - struct nvsp_message *revokePacket; + struct nvsp_message *revoke_packet; int ret = 0; /* @@ -434,20 +447,23 @@ static int NetVscDestroyReceiveBuffer(struct netvsc_device *NetDevice) * NvspMessage1TypeSendReceiveBuffer msg) therefore, we need * to send a revoke msg here */ - if (NetDevice->ReceiveSectionCount) { + if (net_device->ReceiveSectionCount) { DPRINT_INFO(NETVSC, "Sending NvspMessage1TypeRevokeReceiveBuffer..."); /* Send the revoke receive buffer */ - revokePacket = &NetDevice->RevokePacket; - memset(revokePacket, 0, sizeof(struct nvsp_message)); + revoke_packet = &net_device->RevokePacket; + memset(revoke_packet, 0, sizeof(struct nvsp_message)); - revokePacket->Header.MessageType = NvspMessage1TypeRevokeReceiveBuffer; - revokePacket->Messages.Version1Messages.RevokeReceiveBuffer.Id = NETVSC_RECEIVE_BUFFER_ID; + revoke_packet->Header.MessageType = + NvspMessage1TypeRevokeReceiveBuffer; + revoke_packet->Messages.Version1Messages. + RevokeReceiveBuffer.Id = NETVSC_RECEIVE_BUFFER_ID; - ret = vmbus_sendpacket(NetDevice->Device->channel, revokePacket, + ret = vmbus_sendpacket(net_device->Device->channel, + revoke_packet, sizeof(struct nvsp_message), - (unsigned long)revokePacket, + (unsigned long)revoke_packet, VmbusPacketTypeDataInBand, 0); /* * If we failed here, we might as well return and @@ -461,11 +477,11 @@ static int NetVscDestroyReceiveBuffer(struct netvsc_device *NetDevice) } /* Teardown the gpadl on the vsp end */ - if (NetDevice->ReceiveBufferGpadlHandle) { + if (net_device->ReceiveBufferGpadlHandle) { DPRINT_INFO(NETVSC, "Tearing down receive buffer's GPADL..."); - ret = vmbus_teardown_gpadl(NetDevice->Device->channel, - NetDevice->ReceiveBufferGpadlHandle); + ret = vmbus_teardown_gpadl(net_device->Device->channel, + net_device->ReceiveBufferGpadlHandle); /* If we failed here, we might as well return and have a leak rather than continue and a bugchk */ if (ret != 0) { @@ -473,30 +489,30 @@ static int NetVscDestroyReceiveBuffer(struct netvsc_device *NetDevice) "unable to teardown receive buffer's gpadl"); return -1; } - NetDevice->ReceiveBufferGpadlHandle = 0; + net_device->ReceiveBufferGpadlHandle = 0; } - if (NetDevice->ReceiveBuffer) { + if (net_device->ReceiveBuffer) { DPRINT_INFO(NETVSC, "Freeing up receive buffer..."); /* Free up the receive buffer */ - osd_page_free(NetDevice->ReceiveBuffer, - NetDevice->ReceiveBufferSize >> PAGE_SHIFT); - NetDevice->ReceiveBuffer = NULL; + osd_page_free(net_device->ReceiveBuffer, + net_device->ReceiveBufferSize >> PAGE_SHIFT); + net_device->ReceiveBuffer = NULL; } - if (NetDevice->ReceiveSections) { - NetDevice->ReceiveSectionCount = 0; - kfree(NetDevice->ReceiveSections); - NetDevice->ReceiveSections = NULL; + if (net_device->ReceiveSections) { + net_device->ReceiveSectionCount = 0; + kfree(net_device->ReceiveSections); + net_device->ReceiveSections = NULL; } return ret; } -static int NetVscDestroySendBuffer(struct netvsc_device *NetDevice) +static int NetVscDestroySendBuffer(struct netvsc_device *net_device) { - struct nvsp_message *revokePacket; + struct nvsp_message *revoke_packet; int ret = 0; /* @@ -505,20 +521,23 @@ static int NetVscDestroySendBuffer(struct netvsc_device *NetDevice) * NvspMessage1TypeSendReceiveBuffer msg) therefore, we need * to send a revoke msg here */ - if (NetDevice->SendSectionSize) { + if (net_device->SendSectionSize) { DPRINT_INFO(NETVSC, "Sending NvspMessage1TypeRevokeSendBuffer..."); /* Send the revoke send buffer */ - revokePacket = &NetDevice->RevokePacket; - memset(revokePacket, 0, sizeof(struct nvsp_message)); + revoke_packet = &net_device->RevokePacket; + memset(revoke_packet, 0, sizeof(struct nvsp_message)); - revokePacket->Header.MessageType = NvspMessage1TypeRevokeSendBuffer; - revokePacket->Messages.Version1Messages.RevokeSendBuffer.Id = NETVSC_SEND_BUFFER_ID; + revoke_packet->Header.MessageType = + NvspMessage1TypeRevokeSendBuffer; + revoke_packet->Messages.Version1Messages. + RevokeSendBuffer.Id = NETVSC_SEND_BUFFER_ID; - ret = vmbus_sendpacket(NetDevice->Device->channel, revokePacket, + ret = vmbus_sendpacket(net_device->Device->channel, + revoke_packet, sizeof(struct nvsp_message), - (unsigned long)revokePacket, + (unsigned long)revoke_packet, VmbusPacketTypeDataInBand, 0); /* * If we failed here, we might as well return and have a leak @@ -532,10 +551,10 @@ static int NetVscDestroySendBuffer(struct netvsc_device *NetDevice) } /* Teardown the gpadl on the vsp end */ - if (NetDevice->SendBufferGpadlHandle) { + if (net_device->SendBufferGpadlHandle) { DPRINT_INFO(NETVSC, "Tearing down send buffer's GPADL..."); - ret = vmbus_teardown_gpadl(NetDevice->Device->channel, - NetDevice->SendBufferGpadlHandle); + ret = vmbus_teardown_gpadl(net_device->Device->channel, + net_device->SendBufferGpadlHandle); /* * If we failed here, we might as well return and have a leak @@ -546,49 +565,51 @@ static int NetVscDestroySendBuffer(struct netvsc_device *NetDevice) "gpadl"); return -1; } - NetDevice->SendBufferGpadlHandle = 0; + net_device->SendBufferGpadlHandle = 0; } - if (NetDevice->SendBuffer) { + if (net_device->SendBuffer) { DPRINT_INFO(NETVSC, "Freeing up send buffer..."); /* Free up the receive buffer */ - osd_page_free(NetDevice->SendBuffer, - NetDevice->SendBufferSize >> PAGE_SHIFT); - NetDevice->SendBuffer = NULL; + osd_page_free(net_device->SendBuffer, + net_device->SendBufferSize >> PAGE_SHIFT); + net_device->SendBuffer = NULL; } return ret; } -static int NetVscConnectToVsp(struct hv_device *Device) +static int NetVscConnectToVsp(struct hv_device *device) { int ret; - struct netvsc_device *netDevice; - struct nvsp_message *initPacket; - int ndisVersion; + struct netvsc_device *net_device; + struct nvsp_message *init_packet; + int ndis_version; - netDevice = GetOutboundNetDevice(Device); - if (!netDevice) { + net_device = GetOutboundNetDevice(device); + if (!net_device) { DPRINT_ERR(NETVSC, "unable to get net device..." "device being destroyed?"); return -1; } - initPacket = &netDevice->ChannelInitPacket; + init_packet = &net_device->ChannelInitPacket; - memset(initPacket, 0, sizeof(struct nvsp_message)); - initPacket->Header.MessageType = NvspMessageTypeInit; - initPacket->Messages.InitMessages.Init.MinProtocolVersion = NVSP_MIN_PROTOCOL_VERSION; - initPacket->Messages.InitMessages.Init.MaxProtocolVersion = NVSP_MAX_PROTOCOL_VERSION; + memset(init_packet, 0, sizeof(struct nvsp_message)); + init_packet->Header.MessageType = NvspMessageTypeInit; + init_packet->Messages.InitMessages.Init.MinProtocolVersion = + NVSP_MIN_PROTOCOL_VERSION; + init_packet->Messages.InitMessages.Init.MaxProtocolVersion = + NVSP_MAX_PROTOCOL_VERSION; DPRINT_INFO(NETVSC, "Sending NvspMessageTypeInit..."); /* Send the init request */ - ret = vmbus_sendpacket(Device->channel, initPacket, + ret = vmbus_sendpacket(device->channel, init_packet, sizeof(struct nvsp_message), - (unsigned long)initPacket, + (unsigned long)init_packet, VmbusPacketTypeDataInBand, VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); @@ -597,47 +618,52 @@ static int NetVscConnectToVsp(struct hv_device *Device) goto Cleanup; } - osd_waitevent_wait(netDevice->ChannelInitEvent); + osd_waitevent_wait(net_device->ChannelInitEvent); /* Now, check the response */ /* ASSERT(initPacket->Messages.InitMessages.InitComplete.MaximumMdlChainLength <= MAX_MULTIPAGE_BUFFER_COUNT); */ DPRINT_INFO(NETVSC, "NvspMessageTypeInit status(%d) max mdl chain (%d)", - initPacket->Messages.InitMessages.InitComplete.Status, - initPacket->Messages.InitMessages.InitComplete.MaximumMdlChainLength); + init_packet->Messages.InitMessages.InitComplete.Status, + init_packet->Messages.InitMessages. + InitComplete.MaximumMdlChainLength); - if (initPacket->Messages.InitMessages.InitComplete.Status != + if (init_packet->Messages.InitMessages.InitComplete.Status != NvspStatusSuccess) { DPRINT_ERR(NETVSC, "unable to initialize with netvsp (status 0x%x)", - initPacket->Messages.InitMessages.InitComplete.Status); + init_packet->Messages.InitMessages.InitComplete.Status); ret = -1; goto Cleanup; } - if (initPacket->Messages.InitMessages.InitComplete.NegotiatedProtocolVersion != NVSP_PROTOCOL_VERSION_1) { + if (init_packet->Messages.InitMessages.InitComplete. + NegotiatedProtocolVersion != NVSP_PROTOCOL_VERSION_1) { DPRINT_ERR(NETVSC, "unable to initialize with netvsp " "(version expected 1 got %d)", - initPacket->Messages.InitMessages.InitComplete.NegotiatedProtocolVersion); + init_packet->Messages.InitMessages. + InitComplete.NegotiatedProtocolVersion); ret = -1; goto Cleanup; } DPRINT_INFO(NETVSC, "Sending NvspMessage1TypeSendNdisVersion..."); /* Send the ndis version */ - memset(initPacket, 0, sizeof(struct nvsp_message)); + memset(init_packet, 0, sizeof(struct nvsp_message)); - ndisVersion = 0x00050000; + ndis_version = 0x00050000; - initPacket->Header.MessageType = NvspMessage1TypeSendNdisVersion; - initPacket->Messages.Version1Messages.SendNdisVersion.NdisMajorVersion = - (ndisVersion & 0xFFFF0000) >> 16; - initPacket->Messages.Version1Messages.SendNdisVersion.NdisMinorVersion = - ndisVersion & 0xFFFF; + init_packet->Header.MessageType = NvspMessage1TypeSendNdisVersion; + init_packet->Messages.Version1Messages. + SendNdisVersion.NdisMajorVersion = + (ndis_version & 0xFFFF0000) >> 16; + init_packet->Messages.Version1Messages. + SendNdisVersion.NdisMinorVersion = + ndis_version & 0xFFFF; /* Send the init request */ - ret = vmbus_sendpacket(Device->channel, initPacket, + ret = vmbus_sendpacket(device->channel, init_packet, sizeof(struct nvsp_message), - (unsigned long)initPacket, + (unsigned long)init_packet, VmbusPacketTypeDataInBand, 0); if (ret != 0) { DPRINT_ERR(NETVSC, @@ -654,48 +680,48 @@ static int NetVscConnectToVsp(struct hv_device *Device) /* osd_waitevent_wait(NetVscChannel->ChannelInitEvent); */ /* Post the big receive buffer to NetVSP */ - ret = NetVscInitializeReceiveBufferWithNetVsp(Device); + ret = NetVscInitializeReceiveBufferWithNetVsp(device); if (ret == 0) - ret = NetVscInitializeSendBufferWithNetVsp(Device); + ret = NetVscInitializeSendBufferWithNetVsp(device); Cleanup: - PutNetDevice(Device); + PutNetDevice(device); return ret; } -static void NetVscDisconnectFromVsp(struct netvsc_device *NetDevice) +static void NetVscDisconnectFromVsp(struct netvsc_device *net_device) { - NetVscDestroyReceiveBuffer(NetDevice); - NetVscDestroySendBuffer(NetDevice); + NetVscDestroyReceiveBuffer(net_device); + NetVscDestroySendBuffer(net_device); } /* * NetVscOnDeviceAdd - Callback when the device belonging to this driver is added */ -static int NetVscOnDeviceAdd(struct hv_device *Device, void *AdditionalInfo) +static int NetVscOnDeviceAdd(struct hv_device *device, void *additional_info) { int ret = 0; int i; - struct netvsc_device *netDevice; + struct netvsc_device *net_device; struct hv_netvsc_packet *packet, *pos; - struct netvsc_driver *netDriver = - (struct netvsc_driver *)Device->Driver; + struct netvsc_driver *net_driver = + (struct netvsc_driver *)device->Driver; - netDevice = AllocNetDevice(Device); - if (!netDevice) { + net_device = AllocNetDevice(device); + if (!net_device) { ret = -1; goto Cleanup; } - DPRINT_DBG(NETVSC, "netvsc channel object allocated - %p", netDevice); + DPRINT_DBG(NETVSC, "netvsc channel object allocated - %p", net_device); /* Initialize the NetVSC channel extension */ - netDevice->ReceiveBufferSize = NETVSC_RECEIVE_BUFFER_SIZE; - spin_lock_init(&netDevice->receive_packet_list_lock); + net_device->ReceiveBufferSize = NETVSC_RECEIVE_BUFFER_SIZE; + spin_lock_init(&net_device->receive_packet_list_lock); - netDevice->SendBufferSize = NETVSC_SEND_BUFFER_SIZE; + net_device->SendBufferSize = NETVSC_SEND_BUFFER_SIZE; - INIT_LIST_HEAD(&netDevice->ReceivePacketList); + INIT_LIST_HEAD(&net_device->ReceivePacketList); for (i = 0; i < NETVSC_RECEIVE_PACKETLIST_COUNT; i++) { packet = kzalloc(sizeof(struct hv_netvsc_packet) + @@ -708,18 +734,18 @@ static int NetVscOnDeviceAdd(struct hv_device *Device, void *AdditionalInfo) break; } list_add_tail(&packet->ListEntry, - &netDevice->ReceivePacketList); + &net_device->ReceivePacketList); } - netDevice->ChannelInitEvent = osd_waitevent_create(); - if (!netDevice->ChannelInitEvent) { + net_device->ChannelInitEvent = osd_waitevent_create(); + if (!net_device->ChannelInitEvent) { ret = -ENOMEM; goto Cleanup; } /* Open the channel */ - ret = vmbus_open(Device->channel, netDriver->RingBufferSize, - netDriver->RingBufferSize, NULL, 0, - NetVscOnChannelCallback, Device); + ret = vmbus_open(device->channel, net_driver->RingBufferSize, + net_driver->RingBufferSize, NULL, 0, + NetVscOnChannelCallback, device); if (ret != 0) { DPRINT_ERR(NETVSC, "unable to open channel: %d", ret); @@ -731,7 +757,7 @@ static int NetVscOnDeviceAdd(struct hv_device *Device, void *AdditionalInfo) DPRINT_INFO(NETVSC, "*** NetVSC channel opened successfully! ***"); /* Connect with the NetVsp */ - ret = NetVscConnectToVsp(Device); + ret = NetVscConnectToVsp(device); if (ret != 0) { DPRINT_ERR(NETVSC, "unable to connect to NetVSP - %d", ret); ret = -1; @@ -745,24 +771,24 @@ static int NetVscOnDeviceAdd(struct hv_device *Device, void *AdditionalInfo) close: /* Now, we can close the channel safely */ - vmbus_close(Device->channel); + vmbus_close(device->channel); Cleanup: - if (netDevice) { - kfree(netDevice->ChannelInitEvent); + if (net_device) { + kfree(net_device->ChannelInitEvent); list_for_each_entry_safe(packet, pos, - &netDevice->ReceivePacketList, + &net_device->ReceivePacketList, ListEntry) { list_del(&packet->ListEntry); kfree(packet); } - ReleaseOutboundNetDevice(Device); - ReleaseInboundNetDevice(Device); + ReleaseOutboundNetDevice(device); + ReleaseInboundNetDevice(device); - FreeNetDevice(netDevice); + FreeNetDevice(net_device); } return ret; @@ -771,53 +797,53 @@ Cleanup: /* * NetVscOnDeviceRemove - Callback when the root bus device is removed */ -static int NetVscOnDeviceRemove(struct hv_device *Device) +static int NetVscOnDeviceRemove(struct hv_device *device) { - struct netvsc_device *netDevice; - struct hv_netvsc_packet *netvscPacket, *pos; + struct netvsc_device *net_device; + struct hv_netvsc_packet *netvsc_packet, *pos; DPRINT_INFO(NETVSC, "Disabling outbound traffic on net device (%p)...", - Device->Extension); + device->Extension); /* Stop outbound traffic ie sends and receives completions */ - netDevice = ReleaseOutboundNetDevice(Device); - if (!netDevice) { + net_device = ReleaseOutboundNetDevice(device); + if (!net_device) { DPRINT_ERR(NETVSC, "No net device present!!"); return -1; } /* Wait for all send completions */ - while (atomic_read(&netDevice->NumOutstandingSends)) { + while (atomic_read(&net_device->NumOutstandingSends)) { DPRINT_INFO(NETVSC, "waiting for %d requests to complete...", - atomic_read(&netDevice->NumOutstandingSends)); + atomic_read(&net_device->NumOutstandingSends)); udelay(100); } DPRINT_INFO(NETVSC, "Disconnecting from netvsp..."); - NetVscDisconnectFromVsp(netDevice); + NetVscDisconnectFromVsp(net_device); DPRINT_INFO(NETVSC, "Disabling inbound traffic on net device (%p)...", - Device->Extension); + device->Extension); /* Stop inbound traffic ie receives and sends completions */ - netDevice = ReleaseInboundNetDevice(Device); + net_device = ReleaseInboundNetDevice(device); /* At this point, no one should be accessing netDevice except in here */ - DPRINT_INFO(NETVSC, "net device (%p) safe to remove", netDevice); + DPRINT_INFO(NETVSC, "net device (%p) safe to remove", net_device); /* Now, we can close the channel safely */ - vmbus_close(Device->channel); + vmbus_close(device->channel); /* Release all resources */ - list_for_each_entry_safe(netvscPacket, pos, - &netDevice->ReceivePacketList, ListEntry) { - list_del(&netvscPacket->ListEntry); - kfree(netvscPacket); + list_for_each_entry_safe(netvsc_packet, pos, + &net_device->ReceivePacketList, ListEntry) { + list_del(&netvsc_packet->ListEntry); + kfree(netvsc_packet); } - kfree(netDevice->ChannelInitEvent); - FreeNetDevice(netDevice); + kfree(net_device->ChannelInitEvent); + FreeNetDevice(net_device); return 0; } @@ -828,69 +854,72 @@ static void NetVscOnCleanup(struct hv_driver *drv) { } -static void NetVscOnSendCompletion(struct hv_device *Device, - struct vmpacket_descriptor *Packet) +static void NetVscOnSendCompletion(struct hv_device *device, + struct vmpacket_descriptor *packet) { - struct netvsc_device *netDevice; - struct nvsp_message *nvspPacket; - struct hv_netvsc_packet *nvscPacket; + struct netvsc_device *net_device; + struct nvsp_message *nvsp_packet; + struct hv_netvsc_packet *nvsc_packet; - netDevice = GetInboundNetDevice(Device); - if (!netDevice) { + net_device = GetInboundNetDevice(device); + if (!net_device) { DPRINT_ERR(NETVSC, "unable to get net device..." "device being destroyed?"); return; } - nvspPacket = (struct nvsp_message *)((unsigned long)Packet + (Packet->DataOffset8 << 3)); + nvsp_packet = (struct nvsp_message *)((unsigned long)packet + + (packet->DataOffset8 << 3)); DPRINT_DBG(NETVSC, "send completion packet - type %d", - nvspPacket->Header.MessageType); + nvsp_packet->Header.MessageType); - if ((nvspPacket->Header.MessageType == NvspMessageTypeInitComplete) || - (nvspPacket->Header.MessageType == + if ((nvsp_packet->Header.MessageType == NvspMessageTypeInitComplete) || + (nvsp_packet->Header.MessageType == NvspMessage1TypeSendReceiveBufferComplete) || - (nvspPacket->Header.MessageType == + (nvsp_packet->Header.MessageType == NvspMessage1TypeSendSendBufferComplete)) { /* Copy the response back */ - memcpy(&netDevice->ChannelInitPacket, nvspPacket, + memcpy(&net_device->ChannelInitPacket, nvsp_packet, sizeof(struct nvsp_message)); - osd_waitevent_set(netDevice->ChannelInitEvent); - } else if (nvspPacket->Header.MessageType == + osd_waitevent_set(net_device->ChannelInitEvent); + } else if (nvsp_packet->Header.MessageType == NvspMessage1TypeSendRNDISPacketComplete) { /* Get the send context */ - nvscPacket = (struct hv_netvsc_packet *)(unsigned long)Packet->TransactionId; + nvsc_packet = (struct hv_netvsc_packet *)(unsigned long) + packet->TransactionId; /* ASSERT(nvscPacket); */ /* Notify the layer above us */ - nvscPacket->Completion.Send.OnSendCompletion(nvscPacket->Completion.Send.SendCompletionContext); + nvsc_packet->Completion.Send.OnSendCompletion( + nvsc_packet->Completion.Send.SendCompletionContext); - atomic_dec(&netDevice->NumOutstandingSends); + atomic_dec(&net_device->NumOutstandingSends); } else { DPRINT_ERR(NETVSC, "Unknown send completion packet type - " - "%d received!!", nvspPacket->Header.MessageType); + "%d received!!", nvsp_packet->Header.MessageType); } - PutNetDevice(Device); + PutNetDevice(device); } -static int NetVscOnSend(struct hv_device *Device, - struct hv_netvsc_packet *Packet) +static int NetVscOnSend(struct hv_device *device, + struct hv_netvsc_packet *packet) { - struct netvsc_device *netDevice; + struct netvsc_device *net_device; int ret = 0; struct nvsp_message sendMessage; - netDevice = GetOutboundNetDevice(Device); - if (!netDevice) { + net_device = GetOutboundNetDevice(device); + if (!net_device) { DPRINT_ERR(NETVSC, "net device (%p) shutting down..." - "ignoring outbound packets", netDevice); + "ignoring outbound packets", net_device); return -2; } sendMessage.Header.MessageType = NvspMessage1TypeSendRNDISPacket; - if (Packet->IsDataPacket) { + if (packet->IsDataPacket) { /* 0 is RMC_DATA; */ sendMessage.Messages.Version1Messages.SendRNDISPacket.ChannelType = 0; } else { @@ -902,17 +931,17 @@ static int NetVscOnSend(struct hv_device *Device, sendMessage.Messages.Version1Messages.SendRNDISPacket.SendBufferSectionIndex = 0xFFFFFFFF; sendMessage.Messages.Version1Messages.SendRNDISPacket.SendBufferSectionSize = 0; - if (Packet->PageBufferCount) { - ret = vmbus_sendpacket_pagebuffer(Device->channel, - Packet->PageBuffers, - Packet->PageBufferCount, + if (packet->PageBufferCount) { + ret = vmbus_sendpacket_pagebuffer(device->channel, + packet->PageBuffers, + packet->PageBufferCount, &sendMessage, sizeof(struct nvsp_message), - (unsigned long)Packet); + (unsigned long)packet); } else { - ret = vmbus_sendpacket(Device->channel, &sendMessage, + ret = vmbus_sendpacket(device->channel, &sendMessage, sizeof(struct nvsp_message), - (unsigned long)Packet, + (unsigned long)packet, VmbusPacketTypeDataInBand, VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); @@ -920,31 +949,31 @@ static int NetVscOnSend(struct hv_device *Device, if (ret != 0) DPRINT_ERR(NETVSC, "Unable to send packet %p ret %d", - Packet, ret); + packet, ret); - atomic_inc(&netDevice->NumOutstandingSends); - PutNetDevice(Device); + atomic_inc(&net_device->NumOutstandingSends); + PutNetDevice(device); return ret; } -static void NetVscOnReceive(struct hv_device *Device, - struct vmpacket_descriptor *Packet) +static void NetVscOnReceive(struct hv_device *device, + struct vmpacket_descriptor *packet) { - struct netvsc_device *netDevice; - struct vmtransfer_page_packet_header *vmxferpagePacket; - struct nvsp_message *nvspPacket; - struct hv_netvsc_packet *netvscPacket = NULL; + struct netvsc_device *net_device; + struct vmtransfer_page_packet_header *vmxferpage_packet; + struct nvsp_message *nvsp_packet; + struct hv_netvsc_packet *netvsc_packet = NULL; unsigned long start; - unsigned long end, endVirtual; + unsigned long end, end_virtual; /* struct netvsc_driver *netvscDriver; */ - struct xferpage_packet *xferpagePacket = NULL; + struct xferpage_packet *xferpage_packet = NULL; int i, j; - int count = 0, bytesRemain = 0; + int count = 0, bytes_remain = 0; unsigned long flags; LIST_HEAD(listHead); - netDevice = GetInboundNetDevice(Device); - if (!netDevice) { + net_device = GetInboundNetDevice(device); + if (!net_device) { DPRINT_ERR(NETVSC, "unable to get net device..." "device being destroyed?"); return; @@ -954,39 +983,40 @@ static void NetVscOnReceive(struct hv_device *Device, * All inbound packets other than send completion should be xfer page * packet */ - if (Packet->Type != VmbusPacketTypeDataUsingTransferPages) { + if (packet->Type != VmbusPacketTypeDataUsingTransferPages) { DPRINT_ERR(NETVSC, "Unknown packet type received - %d", - Packet->Type); - PutNetDevice(Device); + packet->Type); + PutNetDevice(device); return; } - nvspPacket = (struct nvsp_message *)((unsigned long)Packet + - (Packet->DataOffset8 << 3)); + nvsp_packet = (struct nvsp_message *)((unsigned long)packet + + (packet->DataOffset8 << 3)); /* Make sure this is a valid nvsp packet */ - if (nvspPacket->Header.MessageType != NvspMessage1TypeSendRNDISPacket) { + if (nvsp_packet->Header.MessageType != + NvspMessage1TypeSendRNDISPacket) { DPRINT_ERR(NETVSC, "Unknown nvsp packet type received - %d", - nvspPacket->Header.MessageType); - PutNetDevice(Device); + nvsp_packet->Header.MessageType); + PutNetDevice(device); return; } DPRINT_DBG(NETVSC, "NVSP packet received - type %d", - nvspPacket->Header.MessageType); + nvsp_packet->Header.MessageType); - vmxferpagePacket = (struct vmtransfer_page_packet_header *)Packet; + vmxferpage_packet = (struct vmtransfer_page_packet_header *)packet; - if (vmxferpagePacket->TransferPageSetId != NETVSC_RECEIVE_BUFFER_ID) { + if (vmxferpage_packet->TransferPageSetId != NETVSC_RECEIVE_BUFFER_ID) { DPRINT_ERR(NETVSC, "Invalid xfer page set id - " "expecting %x got %x", NETVSC_RECEIVE_BUFFER_ID, - vmxferpagePacket->TransferPageSetId); - PutNetDevice(Device); + vmxferpage_packet->TransferPageSetId); + PutNetDevice(device); return; } DPRINT_DBG(NETVSC, "xfer page - range count %d", - vmxferpagePacket->RangeCount); + vmxferpage_packet->RangeCount); /* * Grab free packets (range count + 1) to represent this xfer @@ -994,13 +1024,13 @@ static void NetVscOnReceive(struct hv_device *Device, * We grab it here so that we know exactly how many we can * fulfil */ - spin_lock_irqsave(&netDevice->receive_packet_list_lock, flags); - while (!list_empty(&netDevice->ReceivePacketList)) { - list_move_tail(netDevice->ReceivePacketList.next, &listHead); - if (++count == vmxferpagePacket->RangeCount + 1) + spin_lock_irqsave(&net_device->receive_packet_list_lock, flags); + while (!list_empty(&net_device->ReceivePacketList)) { + list_move_tail(net_device->ReceivePacketList.next, &listHead); + if (++count == vmxferpage_packet->RangeCount + 1) break; } - spin_unlock_irqrestore(&netDevice->receive_packet_list_lock, flags); + spin_unlock_irqrestore(&net_device->receive_packet_list_lock, flags); /* * We need at least 2 netvsc pkts (1 to represent the xfer @@ -1010,129 +1040,137 @@ static void NetVscOnReceive(struct hv_device *Device, if (count < 2) { DPRINT_ERR(NETVSC, "Got only %d netvsc pkt...needed %d pkts. " "Dropping this xfer page packet completely!", - count, vmxferpagePacket->RangeCount + 1); + count, vmxferpage_packet->RangeCount + 1); /* Return it to the freelist */ - spin_lock_irqsave(&netDevice->receive_packet_list_lock, flags); + spin_lock_irqsave(&net_device->receive_packet_list_lock, flags); for (i = count; i != 0; i--) { list_move_tail(listHead.next, - &netDevice->ReceivePacketList); + &net_device->ReceivePacketList); } - spin_unlock_irqrestore(&netDevice->receive_packet_list_lock, + spin_unlock_irqrestore(&net_device->receive_packet_list_lock, flags); - NetVscSendReceiveCompletion(Device, - vmxferpagePacket->d.TransactionId); + NetVscSendReceiveCompletion(device, + vmxferpage_packet->d.TransactionId); - PutNetDevice(Device); + PutNetDevice(device); return; } /* Remove the 1st packet to represent the xfer page packet itself */ - xferpagePacket = (struct xferpage_packet *)listHead.next; - list_del(&xferpagePacket->ListEntry); + xferpage_packet = (struct xferpage_packet *)listHead.next; + list_del(&xferpage_packet->ListEntry); /* This is how much we can satisfy */ - xferpagePacket->Count = count - 1; + xferpage_packet->Count = count - 1; /* ASSERT(xferpagePacket->Count > 0 && xferpagePacket->Count <= */ /* vmxferpagePacket->RangeCount); */ - if (xferpagePacket->Count != vmxferpagePacket->RangeCount) { + if (xferpage_packet->Count != vmxferpage_packet->RangeCount) { DPRINT_INFO(NETVSC, "Needed %d netvsc pkts to satisy this xfer " - "page...got %d", vmxferpagePacket->RangeCount, - xferpagePacket->Count); + "page...got %d", vmxferpage_packet->RangeCount, + xferpage_packet->Count); } /* Each range represents 1 RNDIS pkt that contains 1 ethernet frame */ for (i = 0; i < (count - 1); i++) { - netvscPacket = (struct hv_netvsc_packet *)listHead.next; - list_del(&netvscPacket->ListEntry); + netvsc_packet = (struct hv_netvsc_packet *)listHead.next; + list_del(&netvsc_packet->ListEntry); /* Initialize the netvsc packet */ - netvscPacket->XferPagePacket = xferpagePacket; - netvscPacket->Completion.Recv.OnReceiveCompletion = + netvsc_packet->XferPagePacket = xferpage_packet; + netvsc_packet->Completion.Recv.OnReceiveCompletion = NetVscOnReceiveCompletion; - netvscPacket->Completion.Recv.ReceiveCompletionContext = - netvscPacket; - netvscPacket->Device = Device; + netvsc_packet->Completion.Recv.ReceiveCompletionContext = + netvsc_packet; + netvsc_packet->Device = device; /* Save this so that we can send it back */ - netvscPacket->Completion.Recv.ReceiveCompletionTid = - vmxferpagePacket->d.TransactionId; + netvsc_packet->Completion.Recv.ReceiveCompletionTid = + vmxferpage_packet->d.TransactionId; - netvscPacket->TotalDataBufferLength = - vmxferpagePacket->Ranges[i].ByteCount; - netvscPacket->PageBufferCount = 1; + netvsc_packet->TotalDataBufferLength = + vmxferpage_packet->Ranges[i].ByteCount; + netvsc_packet->PageBufferCount = 1; /* ASSERT(vmxferpagePacket->Ranges[i].ByteOffset + */ /* vmxferpagePacket->Ranges[i].ByteCount < */ /* netDevice->ReceiveBufferSize); */ - netvscPacket->PageBuffers[0].Length = - vmxferpagePacket->Ranges[i].ByteCount; + netvsc_packet->PageBuffers[0].Length = + vmxferpage_packet->Ranges[i].ByteCount; - start = virt_to_phys((void *)((unsigned long)netDevice->ReceiveBuffer + vmxferpagePacket->Ranges[i].ByteOffset)); + start = virt_to_phys((void *)((unsigned long)net_device-> + ReceiveBuffer + vmxferpage_packet->Ranges[i].ByteOffset)); - netvscPacket->PageBuffers[0].Pfn = start >> PAGE_SHIFT; - endVirtual = (unsigned long)netDevice->ReceiveBuffer - + vmxferpagePacket->Ranges[i].ByteOffset - + vmxferpagePacket->Ranges[i].ByteCount - 1; - end = virt_to_phys((void *)endVirtual); + netvsc_packet->PageBuffers[0].Pfn = start >> PAGE_SHIFT; + end_virtual = (unsigned long)net_device->ReceiveBuffer + + vmxferpage_packet->Ranges[i].ByteOffset + + vmxferpage_packet->Ranges[i].ByteCount - 1; + end = virt_to_phys((void *)end_virtual); /* Calculate the page relative offset */ - netvscPacket->PageBuffers[0].Offset = - vmxferpagePacket->Ranges[i].ByteOffset & (PAGE_SIZE - 1); + netvsc_packet->PageBuffers[0].Offset = + vmxferpage_packet->Ranges[i].ByteOffset & + (PAGE_SIZE - 1); if ((end >> PAGE_SHIFT) != (start >> PAGE_SHIFT)) { /* Handle frame across multiple pages: */ - netvscPacket->PageBuffers[0].Length = - (netvscPacket->PageBuffers[0].Pfn << PAGE_SHIFT) + netvsc_packet->PageBuffers[0].Length = + (netvsc_packet->PageBuffers[0].Pfn << + PAGE_SHIFT) + PAGE_SIZE - start; - bytesRemain = netvscPacket->TotalDataBufferLength - - netvscPacket->PageBuffers[0].Length; + bytes_remain = netvsc_packet->TotalDataBufferLength - + netvsc_packet->PageBuffers[0].Length; for (j = 1; j < NETVSC_PACKET_MAXPAGE; j++) { - netvscPacket->PageBuffers[j].Offset = 0; - if (bytesRemain <= PAGE_SIZE) { - netvscPacket->PageBuffers[j].Length = bytesRemain; - bytesRemain = 0; + netvsc_packet->PageBuffers[j].Offset = 0; + if (bytes_remain <= PAGE_SIZE) { + netvsc_packet->PageBuffers[j].Length = + bytes_remain; + bytes_remain = 0; } else { - netvscPacket->PageBuffers[j].Length = PAGE_SIZE; - bytesRemain -= PAGE_SIZE; + netvsc_packet->PageBuffers[j].Length = + PAGE_SIZE; + bytes_remain -= PAGE_SIZE; } - netvscPacket->PageBuffers[j].Pfn = - virt_to_phys((void *)(endVirtual - bytesRemain)) >> PAGE_SHIFT; - netvscPacket->PageBufferCount++; - if (bytesRemain == 0) + netvsc_packet->PageBuffers[j].Pfn = + virt_to_phys((void *)(end_virtual - + bytes_remain)) >> PAGE_SHIFT; + netvsc_packet->PageBufferCount++; + if (bytes_remain == 0) break; } /* ASSERT(bytesRemain == 0); */ } DPRINT_DBG(NETVSC, "[%d] - (abs offset %u len %u) => " "(pfn %llx, offset %u, len %u)", i, - vmxferpagePacket->Ranges[i].ByteOffset, - vmxferpagePacket->Ranges[i].ByteCount, - netvscPacket->PageBuffers[0].Pfn, - netvscPacket->PageBuffers[0].Offset, - netvscPacket->PageBuffers[0].Length); + vmxferpage_packet->Ranges[i].ByteOffset, + vmxferpage_packet->Ranges[i].ByteCount, + netvsc_packet->PageBuffers[0].Pfn, + netvsc_packet->PageBuffers[0].Offset, + netvsc_packet->PageBuffers[0].Length); /* Pass it to the upper layer */ - ((struct netvsc_driver *)Device->Driver)->OnReceiveCallback(Device, netvscPacket); + ((struct netvsc_driver *)device->Driver)-> + OnReceiveCallback(device, netvsc_packet); - NetVscOnReceiveCompletion(netvscPacket->Completion.Recv.ReceiveCompletionContext); + NetVscOnReceiveCompletion(netvsc_packet-> + Completion.Recv.ReceiveCompletionContext); } /* ASSERT(list_empty(&listHead)); */ - PutNetDevice(Device); + PutNetDevice(device); } -static void NetVscSendReceiveCompletion(struct hv_device *Device, - u64 TransactionId) +static void NetVscSendReceiveCompletion(struct hv_device *device, + u64 transaction_id) { struct nvsp_message recvcompMessage; int retries = 0; int ret; DPRINT_DBG(NETVSC, "Sending receive completion pkt - %llx", - TransactionId); + transaction_id); recvcompMessage.Header.MessageType = NvspMessage1TypeSendRNDISPacketComplete; @@ -1142,8 +1180,8 @@ static void NetVscSendReceiveCompletion(struct hv_device *Device, retry_send_cmplt: /* Send the completion */ - ret = vmbus_sendpacket(Device->channel, &recvcompMessage, - sizeof(struct nvsp_message), TransactionId, + ret = vmbus_sendpacket(device->channel, &recvcompMessage, + sizeof(struct nvsp_message), transaction_id, VmbusPacketTypeCompletion, 0); if (ret == 0) { /* success */ @@ -1152,7 +1190,7 @@ retry_send_cmplt: /* no more room...wait a bit and attempt to retry 3 times */ retries++; DPRINT_ERR(NETVSC, "unable to send receive completion pkt " - "(tid %llx)...retrying %d", TransactionId, retries); + "(tid %llx)...retrying %d", transaction_id, retries); if (retries < 4) { udelay(100); @@ -1160,22 +1198,22 @@ retry_send_cmplt: } else { DPRINT_ERR(NETVSC, "unable to send receive completion " "pkt (tid %llx)...give up retrying", - TransactionId); + transaction_id); } } else { DPRINT_ERR(NETVSC, "unable to send receive completion pkt - " - "%llx", TransactionId); + "%llx", transaction_id); } } /* Send a receive completion packet to RNDIS device (ie NetVsp) */ -static void NetVscOnReceiveCompletion(void *Context) +static void NetVscOnReceiveCompletion(void *context) { - struct hv_netvsc_packet *packet = Context; + struct hv_netvsc_packet *packet = context; struct hv_device *device = (struct hv_device *)packet->Device; - struct netvsc_device *netDevice; - u64 transactionId = 0; - bool fSendReceiveComp = false; + struct netvsc_device *net_device; + u64 transaction_id = 0; + bool fsend_receive_comp = false; unsigned long flags; /* ASSERT(packet->XferPagePacket); */ @@ -1185,15 +1223,15 @@ static void NetVscOnReceiveCompletion(void *Context) * send out receive completion, we are using GetInboundNetDevice() * since we may have disable outbound traffic already. */ - netDevice = GetInboundNetDevice(device); - if (!netDevice) { + net_device = GetInboundNetDevice(device); + if (!net_device) { DPRINT_ERR(NETVSC, "unable to get net device..." "device being destroyed?"); return; } /* Overloading use of the lock. */ - spin_lock_irqsave(&netDevice->receive_packet_list_lock, flags); + spin_lock_irqsave(&net_device->receive_packet_list_lock, flags); /* ASSERT(packet->XferPagePacket->Count > 0); */ packet->XferPagePacket->Count--; @@ -1203,31 +1241,31 @@ static void NetVscOnReceiveCompletion(void *Context) * Return the xfer page packet itself to the freelist */ if (packet->XferPagePacket->Count == 0) { - fSendReceiveComp = true; - transactionId = packet->Completion.Recv.ReceiveCompletionTid; + fsend_receive_comp = true; + transaction_id = packet->Completion.Recv.ReceiveCompletionTid; list_add_tail(&packet->XferPagePacket->ListEntry, - &netDevice->ReceivePacketList); + &net_device->ReceivePacketList); } /* Put the packet back */ - list_add_tail(&packet->ListEntry, &netDevice->ReceivePacketList); - spin_unlock_irqrestore(&netDevice->receive_packet_list_lock, flags); + list_add_tail(&packet->ListEntry, &net_device->ReceivePacketList); + spin_unlock_irqrestore(&net_device->receive_packet_list_lock, flags); /* Send a receive completion for the xfer page packet */ - if (fSendReceiveComp) - NetVscSendReceiveCompletion(device, transactionId); + if (fsend_receive_comp) + NetVscSendReceiveCompletion(device, transaction_id); PutNetDevice(device); } -static void NetVscOnChannelCallback(void *Context) +static void NetVscOnChannelCallback(void *context) { int ret; - struct hv_device *device = Context; - struct netvsc_device *netDevice; - u32 bytesRecvd; - u64 requestId; + struct hv_device *device = context; + struct netvsc_device *net_device; + u32 bytes_recvd; + u64 request_id; unsigned char *packet; struct vmpacket_descriptor *desc; unsigned char *buffer; @@ -1241,20 +1279,20 @@ static void NetVscOnChannelCallback(void *Context) return; buffer = packet; - netDevice = GetInboundNetDevice(device); - if (!netDevice) { + net_device = GetInboundNetDevice(device); + if (!net_device) { DPRINT_ERR(NETVSC, "net device (%p) shutting down..." - "ignoring inbound packets", netDevice); + "ignoring inbound packets", net_device); goto out; } do { ret = vmbus_recvpacket_raw(device->channel, buffer, bufferlen, - &bytesRecvd, &requestId); + &bytes_recvd, &request_id); if (ret == 0) { - if (bytesRecvd > 0) { + if (bytes_recvd > 0) { DPRINT_DBG(NETVSC, "receive %d bytes, tid %llx", - bytesRecvd, requestId); + bytes_recvd, request_id); desc = (struct vmpacket_descriptor *)buffer; switch (desc->Type) { @@ -1270,8 +1308,8 @@ static void NetVscOnChannelCallback(void *Context) DPRINT_ERR(NETVSC, "unhandled packet type %d, " "tid %llx len %d\n", - desc->Type, requestId, - bytesRecvd); + desc->Type, request_id, + bytes_recvd); break; } @@ -1293,16 +1331,16 @@ static void NetVscOnChannelCallback(void *Context) } } else if (ret == -2) { /* Handle large packet */ - buffer = kmalloc(bytesRecvd, GFP_ATOMIC); + buffer = kmalloc(bytes_recvd, GFP_ATOMIC); if (buffer == NULL) { /* Try again next time around */ DPRINT_ERR(NETVSC, "unable to allocate buffer of size " - "(%d)!!", bytesRecvd); + "(%d)!!", bytes_recvd); break; } - bufferlen = bytesRecvd; + bufferlen = bytes_recvd; } } while (1); -- cgit v1.2.3 From 5a71ae303c0f82968d93d86724c1d94d753b34d7 Mon Sep 17 00:00:00 2001 From: Haiyang Zhang Date: Fri, 10 Dec 2010 12:03:55 -0800 Subject: staging: hv: Convert camel cased functions in netvsc.c to lower cases Signed-off-by: Haiyang Zhang Signed-off-by: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/netvsc.c | 173 ++++++++++++++++++++-------------------- drivers/staging/hv/netvsc_api.h | 2 +- drivers/staging/hv/netvsc_drv.c | 2 +- 3 files changed, 90 insertions(+), 87 deletions(-) diff --git a/drivers/staging/hv/netvsc.c b/drivers/staging/hv/netvsc.c index 1c1ee57482a5..781d7bd37102 100644 --- a/drivers/staging/hv/netvsc.c +++ b/drivers/staging/hv/netvsc.c @@ -41,40 +41,40 @@ static const struct hv_guid netvsc_device_type = { } }; -static int NetVscOnDeviceAdd(struct hv_device *device, void *additional_info); +static int netvsc_device_add(struct hv_device *device, void *additional_info); -static int NetVscOnDeviceRemove(struct hv_device *device); +static int netvsc_device_remove(struct hv_device *device); -static void NetVscOnCleanup(struct hv_driver *driver); +static void netvsc_cleanup(struct hv_driver *driver); -static void NetVscOnChannelCallback(void *context); +static void netvsc_channel_cb(void *context); -static int NetVscInitializeSendBufferWithNetVsp(struct hv_device *device); +static int netvsc_init_send_buf(struct hv_device *device); -static int NetVscInitializeReceiveBufferWithNetVsp(struct hv_device *device); +static int netvsc_init_recv_buf(struct hv_device *device); -static int NetVscDestroySendBuffer(struct netvsc_device *net_device); +static int netvsc_destroy_send_buf(struct netvsc_device *net_device); -static int NetVscDestroyReceiveBuffer(struct netvsc_device *net_device); +static int netvsc_destroy_recv_buf(struct netvsc_device *net_device); -static int NetVscConnectToVsp(struct hv_device *device); +static int netvsc_connect_vsp(struct hv_device *device); -static void NetVscOnSendCompletion(struct hv_device *device, +static void netvsc_send_completion(struct hv_device *device, struct vmpacket_descriptor *packet); -static int NetVscOnSend(struct hv_device *device, +static int netvsc_send(struct hv_device *device, struct hv_netvsc_packet *packet); -static void NetVscOnReceive(struct hv_device *device, +static void netvsc_receive(struct hv_device *device, struct vmpacket_descriptor *packet); -static void NetVscOnReceiveCompletion(void *context); +static void netvsc_receive_completion(void *context); -static void NetVscSendReceiveCompletion(struct hv_device *device, +static void netvsc_send_recv_completion(struct hv_device *device, u64 transaction_id); -static struct netvsc_device *AllocNetDevice(struct hv_device *device) +static struct netvsc_device *alloc_net_device(struct hv_device *device) { struct netvsc_device *net_device; @@ -91,7 +91,7 @@ static struct netvsc_device *AllocNetDevice(struct hv_device *device) return net_device; } -static void FreeNetDevice(struct netvsc_device *device) +static void free_net_device(struct netvsc_device *device) { WARN_ON(atomic_read(&device->RefCount) == 0); device->Device->Extension = NULL; @@ -100,7 +100,7 @@ static void FreeNetDevice(struct netvsc_device *device) /* Get the net device object iff exists and its refcount > 1 */ -static struct netvsc_device *GetOutboundNetDevice(struct hv_device *device) +static struct netvsc_device *get_outbound_net_device(struct hv_device *device) { struct netvsc_device *net_device; @@ -114,7 +114,7 @@ static struct netvsc_device *GetOutboundNetDevice(struct hv_device *device) } /* Get the net device object iff exists and its refcount > 0 */ -static struct netvsc_device *GetInboundNetDevice(struct hv_device *device) +static struct netvsc_device *get_inbound_net_device(struct hv_device *device) { struct netvsc_device *net_device; @@ -127,7 +127,7 @@ static struct netvsc_device *GetInboundNetDevice(struct hv_device *device) return net_device; } -static void PutNetDevice(struct hv_device *device) +static void put_net_device(struct hv_device *device) { struct netvsc_device *net_device; @@ -137,7 +137,8 @@ static void PutNetDevice(struct hv_device *device) atomic_dec(&net_device->RefCount); } -static struct netvsc_device *ReleaseOutboundNetDevice(struct hv_device *device) +static struct netvsc_device *release_outbound_net_device( + struct hv_device *device) { struct netvsc_device *net_device; @@ -152,7 +153,8 @@ static struct netvsc_device *ReleaseOutboundNetDevice(struct hv_device *device) return net_device; } -static struct netvsc_device *ReleaseInboundNetDevice(struct hv_device *device) +static struct netvsc_device *release_inbound_net_device( + struct hv_device *device) { struct netvsc_device *net_device; @@ -169,9 +171,9 @@ static struct netvsc_device *ReleaseInboundNetDevice(struct hv_device *device) } /* - * NetVscInitialize - Main entry point + * netvsc_initialize - Main entry point */ -int NetVscInitialize(struct hv_driver *drv) +int netvsc_initialize(struct hv_driver *drv) { struct netvsc_driver *driver = (struct netvsc_driver *)drv; @@ -194,23 +196,23 @@ int NetVscInitialize(struct hv_driver *drv) /* ASSERT(driver->OnLinkStatusChanged); */ /* Setup the dispatch table */ - driver->Base.OnDeviceAdd = NetVscOnDeviceAdd; - driver->Base.OnDeviceRemove = NetVscOnDeviceRemove; - driver->Base.OnCleanup = NetVscOnCleanup; + driver->Base.OnDeviceAdd = netvsc_device_add; + driver->Base.OnDeviceRemove = netvsc_device_remove; + driver->Base.OnCleanup = netvsc_cleanup; - driver->OnSend = NetVscOnSend; + driver->OnSend = netvsc_send; RndisFilterInit(driver); return 0; } -static int NetVscInitializeReceiveBufferWithNetVsp(struct hv_device *device) +static int netvsc_init_recv_buf(struct hv_device *device) { int ret = 0; struct netvsc_device *net_device; struct nvsp_message *init_packet; - net_device = GetOutboundNetDevice(device); + net_device = get_outbound_net_device(device); if (!net_device) { DPRINT_ERR(NETVSC, "unable to get net device..." "device being destroyed?"); @@ -330,20 +332,20 @@ static int NetVscInitializeReceiveBufferWithNetVsp(struct hv_device *device) goto Exit; Cleanup: - NetVscDestroyReceiveBuffer(net_device); + netvsc_destroy_recv_buf(net_device); Exit: - PutNetDevice(device); + put_net_device(device); return ret; } -static int NetVscInitializeSendBufferWithNetVsp(struct hv_device *device) +static int netvsc_init_send_buf(struct hv_device *device) { int ret = 0; struct netvsc_device *net_device; struct nvsp_message *init_packet; - net_device = GetOutboundNetDevice(device); + net_device = get_outbound_net_device(device); if (!net_device) { DPRINT_ERR(NETVSC, "unable to get net device..." "device being destroyed?"); @@ -429,14 +431,14 @@ static int NetVscInitializeSendBufferWithNetVsp(struct hv_device *device) goto Exit; Cleanup: - NetVscDestroySendBuffer(net_device); + netvsc_destroy_send_buf(net_device); Exit: - PutNetDevice(device); + put_net_device(device); return ret; } -static int NetVscDestroyReceiveBuffer(struct netvsc_device *net_device) +static int netvsc_destroy_recv_buf(struct netvsc_device *net_device) { struct nvsp_message *revoke_packet; int ret = 0; @@ -510,7 +512,7 @@ static int NetVscDestroyReceiveBuffer(struct netvsc_device *net_device) return ret; } -static int NetVscDestroySendBuffer(struct netvsc_device *net_device) +static int netvsc_destroy_send_buf(struct netvsc_device *net_device) { struct nvsp_message *revoke_packet; int ret = 0; @@ -581,14 +583,14 @@ static int NetVscDestroySendBuffer(struct netvsc_device *net_device) } -static int NetVscConnectToVsp(struct hv_device *device) +static int netvsc_connect_vsp(struct hv_device *device) { int ret; struct netvsc_device *net_device; struct nvsp_message *init_packet; int ndis_version; - net_device = GetOutboundNetDevice(device); + net_device = get_outbound_net_device(device); if (!net_device) { DPRINT_ERR(NETVSC, "unable to get net device..." "device being destroyed?"); @@ -680,25 +682,26 @@ static int NetVscConnectToVsp(struct hv_device *device) /* osd_waitevent_wait(NetVscChannel->ChannelInitEvent); */ /* Post the big receive buffer to NetVSP */ - ret = NetVscInitializeReceiveBufferWithNetVsp(device); + ret = netvsc_init_recv_buf(device); if (ret == 0) - ret = NetVscInitializeSendBufferWithNetVsp(device); + ret = netvsc_init_send_buf(device); Cleanup: - PutNetDevice(device); + put_net_device(device); return ret; } static void NetVscDisconnectFromVsp(struct netvsc_device *net_device) { - NetVscDestroyReceiveBuffer(net_device); - NetVscDestroySendBuffer(net_device); + netvsc_destroy_recv_buf(net_device); + netvsc_destroy_send_buf(net_device); } /* - * NetVscOnDeviceAdd - Callback when the device belonging to this driver is added + * netvsc_device_add - Callback when the device belonging to this + * driver is added */ -static int NetVscOnDeviceAdd(struct hv_device *device, void *additional_info) +static int netvsc_device_add(struct hv_device *device, void *additional_info) { int ret = 0; int i; @@ -707,7 +710,7 @@ static int NetVscOnDeviceAdd(struct hv_device *device, void *additional_info) struct netvsc_driver *net_driver = (struct netvsc_driver *)device->Driver; - net_device = AllocNetDevice(device); + net_device = alloc_net_device(device); if (!net_device) { ret = -1; goto Cleanup; @@ -745,7 +748,7 @@ static int NetVscOnDeviceAdd(struct hv_device *device, void *additional_info) /* Open the channel */ ret = vmbus_open(device->channel, net_driver->RingBufferSize, net_driver->RingBufferSize, NULL, 0, - NetVscOnChannelCallback, device); + netvsc_channel_cb, device); if (ret != 0) { DPRINT_ERR(NETVSC, "unable to open channel: %d", ret); @@ -757,7 +760,7 @@ static int NetVscOnDeviceAdd(struct hv_device *device, void *additional_info) DPRINT_INFO(NETVSC, "*** NetVSC channel opened successfully! ***"); /* Connect with the NetVsp */ - ret = NetVscConnectToVsp(device); + ret = netvsc_connect_vsp(device); if (ret != 0) { DPRINT_ERR(NETVSC, "unable to connect to NetVSP - %d", ret); ret = -1; @@ -785,19 +788,19 @@ Cleanup: kfree(packet); } - ReleaseOutboundNetDevice(device); - ReleaseInboundNetDevice(device); + release_outbound_net_device(device); + release_inbound_net_device(device); - FreeNetDevice(net_device); + free_net_device(net_device); } return ret; } /* - * NetVscOnDeviceRemove - Callback when the root bus device is removed + * netvsc_device_remove - Callback when the root bus device is removed */ -static int NetVscOnDeviceRemove(struct hv_device *device) +static int netvsc_device_remove(struct hv_device *device) { struct netvsc_device *net_device; struct hv_netvsc_packet *netvsc_packet, *pos; @@ -806,7 +809,7 @@ static int NetVscOnDeviceRemove(struct hv_device *device) device->Extension); /* Stop outbound traffic ie sends and receives completions */ - net_device = ReleaseOutboundNetDevice(device); + net_device = release_outbound_net_device(device); if (!net_device) { DPRINT_ERR(NETVSC, "No net device present!!"); return -1; @@ -827,7 +830,7 @@ static int NetVscOnDeviceRemove(struct hv_device *device) device->Extension); /* Stop inbound traffic ie receives and sends completions */ - net_device = ReleaseInboundNetDevice(device); + net_device = release_inbound_net_device(device); /* At this point, no one should be accessing netDevice except in here */ DPRINT_INFO(NETVSC, "net device (%p) safe to remove", net_device); @@ -843,25 +846,25 @@ static int NetVscOnDeviceRemove(struct hv_device *device) } kfree(net_device->ChannelInitEvent); - FreeNetDevice(net_device); + free_net_device(net_device); return 0; } /* - * NetVscOnCleanup - Perform any cleanup when the driver is removed + * netvsc_cleanup - Perform any cleanup when the driver is removed */ -static void NetVscOnCleanup(struct hv_driver *drv) +static void netvsc_cleanup(struct hv_driver *drv) { } -static void NetVscOnSendCompletion(struct hv_device *device, +static void netvsc_send_completion(struct hv_device *device, struct vmpacket_descriptor *packet) { struct netvsc_device *net_device; struct nvsp_message *nvsp_packet; struct hv_netvsc_packet *nvsc_packet; - net_device = GetInboundNetDevice(device); + net_device = get_inbound_net_device(device); if (!net_device) { DPRINT_ERR(NETVSC, "unable to get net device..." "device being destroyed?"); @@ -900,10 +903,10 @@ static void NetVscOnSendCompletion(struct hv_device *device, "%d received!!", nvsp_packet->Header.MessageType); } - PutNetDevice(device); + put_net_device(device); } -static int NetVscOnSend(struct hv_device *device, +static int netvsc_send(struct hv_device *device, struct hv_netvsc_packet *packet) { struct netvsc_device *net_device; @@ -911,7 +914,7 @@ static int NetVscOnSend(struct hv_device *device, struct nvsp_message sendMessage; - net_device = GetOutboundNetDevice(device); + net_device = get_outbound_net_device(device); if (!net_device) { DPRINT_ERR(NETVSC, "net device (%p) shutting down..." "ignoring outbound packets", net_device); @@ -952,11 +955,11 @@ static int NetVscOnSend(struct hv_device *device, packet, ret); atomic_inc(&net_device->NumOutstandingSends); - PutNetDevice(device); + put_net_device(device); return ret; } -static void NetVscOnReceive(struct hv_device *device, +static void netvsc_receive(struct hv_device *device, struct vmpacket_descriptor *packet) { struct netvsc_device *net_device; @@ -972,7 +975,7 @@ static void NetVscOnReceive(struct hv_device *device, unsigned long flags; LIST_HEAD(listHead); - net_device = GetInboundNetDevice(device); + net_device = get_inbound_net_device(device); if (!net_device) { DPRINT_ERR(NETVSC, "unable to get net device..." "device being destroyed?"); @@ -986,7 +989,7 @@ static void NetVscOnReceive(struct hv_device *device, if (packet->Type != VmbusPacketTypeDataUsingTransferPages) { DPRINT_ERR(NETVSC, "Unknown packet type received - %d", packet->Type); - PutNetDevice(device); + put_net_device(device); return; } @@ -998,7 +1001,7 @@ static void NetVscOnReceive(struct hv_device *device, NvspMessage1TypeSendRNDISPacket) { DPRINT_ERR(NETVSC, "Unknown nvsp packet type received - %d", nvsp_packet->Header.MessageType); - PutNetDevice(device); + put_net_device(device); return; } @@ -1011,7 +1014,7 @@ static void NetVscOnReceive(struct hv_device *device, DPRINT_ERR(NETVSC, "Invalid xfer page set id - " "expecting %x got %x", NETVSC_RECEIVE_BUFFER_ID, vmxferpage_packet->TransferPageSetId); - PutNetDevice(device); + put_net_device(device); return; } @@ -1051,10 +1054,10 @@ static void NetVscOnReceive(struct hv_device *device, spin_unlock_irqrestore(&net_device->receive_packet_list_lock, flags); - NetVscSendReceiveCompletion(device, + netvsc_send_recv_completion(device, vmxferpage_packet->d.TransactionId); - PutNetDevice(device); + put_net_device(device); return; } @@ -1081,7 +1084,7 @@ static void NetVscOnReceive(struct hv_device *device, /* Initialize the netvsc packet */ netvsc_packet->XferPagePacket = xferpage_packet; netvsc_packet->Completion.Recv.OnReceiveCompletion = - NetVscOnReceiveCompletion; + netvsc_receive_completion; netvsc_packet->Completion.Recv.ReceiveCompletionContext = netvsc_packet; netvsc_packet->Device = device; @@ -1153,16 +1156,16 @@ static void NetVscOnReceive(struct hv_device *device, ((struct netvsc_driver *)device->Driver)-> OnReceiveCallback(device, netvsc_packet); - NetVscOnReceiveCompletion(netvsc_packet-> + netvsc_receive_completion(netvsc_packet-> Completion.Recv.ReceiveCompletionContext); } /* ASSERT(list_empty(&listHead)); */ - PutNetDevice(device); + put_net_device(device); } -static void NetVscSendReceiveCompletion(struct hv_device *device, +static void netvsc_send_recv_completion(struct hv_device *device, u64 transaction_id) { struct nvsp_message recvcompMessage; @@ -1207,7 +1210,7 @@ retry_send_cmplt: } /* Send a receive completion packet to RNDIS device (ie NetVsp) */ -static void NetVscOnReceiveCompletion(void *context) +static void netvsc_receive_completion(void *context) { struct hv_netvsc_packet *packet = context; struct hv_device *device = (struct hv_device *)packet->Device; @@ -1223,7 +1226,7 @@ static void NetVscOnReceiveCompletion(void *context) * send out receive completion, we are using GetInboundNetDevice() * since we may have disable outbound traffic already. */ - net_device = GetInboundNetDevice(device); + net_device = get_inbound_net_device(device); if (!net_device) { DPRINT_ERR(NETVSC, "unable to get net device..." "device being destroyed?"); @@ -1254,12 +1257,12 @@ static void NetVscOnReceiveCompletion(void *context) /* Send a receive completion for the xfer page packet */ if (fsend_receive_comp) - NetVscSendReceiveCompletion(device, transaction_id); + netvsc_send_recv_completion(device, transaction_id); - PutNetDevice(device); + put_net_device(device); } -static void NetVscOnChannelCallback(void *context) +static void netvsc_channel_cb(void *context) { int ret; struct hv_device *device = context; @@ -1279,7 +1282,7 @@ static void NetVscOnChannelCallback(void *context) return; buffer = packet; - net_device = GetInboundNetDevice(device); + net_device = get_inbound_net_device(device); if (!net_device) { DPRINT_ERR(NETVSC, "net device (%p) shutting down..." "ignoring inbound packets", net_device); @@ -1297,11 +1300,11 @@ static void NetVscOnChannelCallback(void *context) desc = (struct vmpacket_descriptor *)buffer; switch (desc->Type) { case VmbusPacketTypeCompletion: - NetVscOnSendCompletion(device, desc); + netvsc_send_completion(device, desc); break; case VmbusPacketTypeDataUsingTransferPages: - NetVscOnReceive(device, desc); + netvsc_receive(device, desc); break; default: @@ -1344,7 +1347,7 @@ static void NetVscOnChannelCallback(void *context) } } while (1); - PutNetDevice(device); + put_net_device(device); out: kfree(buffer); return; diff --git a/drivers/staging/hv/netvsc_api.h b/drivers/staging/hv/netvsc_api.h index 4b5b3ac458c8..dbf154acd967 100644 --- a/drivers/staging/hv/netvsc_api.h +++ b/drivers/staging/hv/netvsc_api.h @@ -109,7 +109,7 @@ struct netvsc_device_info { }; /* Interface */ -int NetVscInitialize(struct hv_driver *drv); +int netvsc_initialize(struct hv_driver *drv); int RndisFilterOnOpen(struct hv_device *Device); int RndisFilterOnClose(struct hv_device *Device); diff --git a/drivers/staging/hv/netvsc_drv.c b/drivers/staging/hv/netvsc_drv.c index f527e5f24f56..cd3eef04e59e 100644 --- a/drivers/staging/hv/netvsc_drv.c +++ b/drivers/staging/hv/netvsc_drv.c @@ -539,7 +539,7 @@ static int __init netvsc_init(void) if (!dmi_check_system(hv_netvsc_dmi_table)) return -ENODEV; - return netvsc_drv_init(NetVscInitialize); + return netvsc_drv_init(netvsc_initialize); } static void __exit netvsc_exit(void) -- cgit v1.2.3 From c2a4efddc73bfd44479fc8d84dadbb352c4efb07 Mon Sep 17 00:00:00 2001 From: Haiyang Zhang Date: Fri, 10 Dec 2010 12:03:56 -0800 Subject: staging: hv: Convert camel cased variables in rndis_filter.c to lower cases Signed-off-by: Haiyang Zhang Signed-off-by: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/rndis_filter.c | 582 +++++++++++++++++++------------------- 1 file changed, 296 insertions(+), 286 deletions(-) diff --git a/drivers/staging/hv/rndis_filter.c b/drivers/staging/hv/rndis_filter.c index b85c82542421..28b7e7e59f0a 100644 --- a/drivers/staging/hv/rndis_filter.c +++ b/drivers/staging/hv/rndis_filter.c @@ -32,7 +32,7 @@ /* Data types */ struct rndis_filter_driver_object { /* The original driver */ - struct netvsc_driver InnerDriver; + struct netvsc_driver inner_drv; }; enum rndis_device_state { @@ -43,61 +43,61 @@ enum rndis_device_state { }; struct rndis_device { - struct netvsc_device *NetDevice; + struct netvsc_device *net_dev; - enum rndis_device_state State; - u32 LinkStatus; - atomic_t NewRequestId; + enum rndis_device_state state; + u32 link_stat; + atomic_t new_req_id; spinlock_t request_lock; - struct list_head RequestList; + struct list_head req_list; - unsigned char HwMacAddr[ETH_ALEN]; + unsigned char hw_mac_adr[ETH_ALEN]; }; struct rndis_request { - struct list_head ListEntry; - struct osd_waitevent *WaitEvent; + struct list_head list_ent; + struct osd_waitevent *waitevent; /* * FIXME: We assumed a fixed size response here. If we do ever need to * handle a bigger response, we can either define a max response * message or add a response buffer variable above this field */ - struct rndis_message ResponseMessage; + struct rndis_message response_msg; /* Simplify allocation by having a netvsc packet inline */ - struct hv_netvsc_packet Packet; - struct hv_page_buffer Buffer; + struct hv_netvsc_packet pkt; + struct hv_page_buffer buf; /* FIXME: We assumed a fixed size request here. */ - struct rndis_message RequestMessage; + struct rndis_message request_msg; }; struct rndis_filter_packet { - void *CompletionContext; - void (*OnCompletion)(void *context); - struct rndis_message Message; + void *completion_ctx; + void (*completion)(void *context); + struct rndis_message msg; }; -static int RndisFilterOnDeviceAdd(struct hv_device *Device, - void *AdditionalInfo); +static int RndisFilterOnDeviceAdd(struct hv_device *dev, + void *additional_info); -static int RndisFilterOnDeviceRemove(struct hv_device *Device); +static int RndisFilterOnDeviceRemove(struct hv_device *dev); -static void RndisFilterOnCleanup(struct hv_driver *Driver); +static void RndisFilterOnCleanup(struct hv_driver *drv); -static int RndisFilterOnSend(struct hv_device *Device, - struct hv_netvsc_packet *Packet); +static int RndisFilterOnSend(struct hv_device *dev, + struct hv_netvsc_packet *pkt); -static void RndisFilterOnSendCompletion(void *Context); +static void RndisFilterOnSendCompletion(void *ctx); -static void RndisFilterOnSendRequestCompletion(void *Context); +static void RndisFilterOnSendRequestCompletion(void *ctx); /* The one and only */ -static struct rndis_filter_driver_object gRndisFilter; +static struct rndis_filter_driver_object rndis_filter; static struct rndis_device *GetRndisDevice(void) { @@ -109,19 +109,19 @@ static struct rndis_device *GetRndisDevice(void) spin_lock_init(&device->request_lock); - INIT_LIST_HEAD(&device->RequestList); + INIT_LIST_HEAD(&device->req_list); - device->State = RNDIS_DEV_UNINITIALIZED; + device->state = RNDIS_DEV_UNINITIALIZED; return device; } -static struct rndis_request *GetRndisRequest(struct rndis_device *Device, - u32 MessageType, - u32 MessageLength) +static struct rndis_request *GetRndisRequest(struct rndis_device *dev, + u32 msg_type, + u32 msg_len) { struct rndis_request *request; - struct rndis_message *rndisMessage; + struct rndis_message *rndis_msg; struct rndis_set_request *set; unsigned long flags; @@ -129,61 +129,61 @@ static struct rndis_request *GetRndisRequest(struct rndis_device *Device, if (!request) return NULL; - request->WaitEvent = osd_waitevent_create(); - if (!request->WaitEvent) { + request->waitevent = osd_waitevent_create(); + if (!request->waitevent) { kfree(request); return NULL; } - rndisMessage = &request->RequestMessage; - rndisMessage->NdisMessageType = MessageType; - rndisMessage->MessageLength = MessageLength; + rndis_msg = &request->request_msg; + rndis_msg->NdisMessageType = msg_type; + rndis_msg->MessageLength = msg_len; /* * Set the request id. This field is always after the rndis header for * request/response packet types so we just used the SetRequest as a * template */ - set = &rndisMessage->Message.SetRequest; - set->RequestId = atomic_inc_return(&Device->NewRequestId); + set = &rndis_msg->Message.SetRequest; + set->RequestId = atomic_inc_return(&dev->new_req_id); /* Add to the request list */ - spin_lock_irqsave(&Device->request_lock, flags); - list_add_tail(&request->ListEntry, &Device->RequestList); - spin_unlock_irqrestore(&Device->request_lock, flags); + spin_lock_irqsave(&dev->request_lock, flags); + list_add_tail(&request->list_ent, &dev->req_list); + spin_unlock_irqrestore(&dev->request_lock, flags); return request; } -static void PutRndisRequest(struct rndis_device *Device, - struct rndis_request *Request) +static void PutRndisRequest(struct rndis_device *dev, + struct rndis_request *req) { unsigned long flags; - spin_lock_irqsave(&Device->request_lock, flags); - list_del(&Request->ListEntry); - spin_unlock_irqrestore(&Device->request_lock, flags); + spin_lock_irqsave(&dev->request_lock, flags); + list_del(&req->list_ent); + spin_unlock_irqrestore(&dev->request_lock, flags); - kfree(Request->WaitEvent); - kfree(Request); + kfree(req->waitevent); + kfree(req); } -static void DumpRndisMessage(struct rndis_message *RndisMessage) +static void DumpRndisMessage(struct rndis_message *rndis_msg) { - switch (RndisMessage->NdisMessageType) { + switch (rndis_msg->NdisMessageType) { case REMOTE_NDIS_PACKET_MSG: DPRINT_DBG(NETVSC, "REMOTE_NDIS_PACKET_MSG (len %u, " "data offset %u data len %u, # oob %u, " "oob offset %u, oob len %u, pkt offset %u, " "pkt len %u", - RndisMessage->MessageLength, - RndisMessage->Message.Packet.DataOffset, - RndisMessage->Message.Packet.DataLength, - RndisMessage->Message.Packet.NumOOBDataElements, - RndisMessage->Message.Packet.OOBDataOffset, - RndisMessage->Message.Packet.OOBDataLength, - RndisMessage->Message.Packet.PerPacketInfoOffset, - RndisMessage->Message.Packet.PerPacketInfoLength); + rndis_msg->MessageLength, + rndis_msg->Message.Packet.DataOffset, + rndis_msg->Message.Packet.DataLength, + rndis_msg->Message.Packet.NumOOBDataElements, + rndis_msg->Message.Packet.OOBDataOffset, + rndis_msg->Message.Packet.OOBDataLength, + rndis_msg->Message.Packet.PerPacketInfoOffset, + rndis_msg->Message.Packet.PerPacketInfoLength); break; case REMOTE_NDIS_INITIALIZE_CMPLT: @@ -191,147 +191,157 @@ static void DumpRndisMessage(struct rndis_message *RndisMessage) "(len %u, id 0x%x, status 0x%x, major %d, minor %d, " "device flags %d, max xfer size 0x%x, max pkts %u, " "pkt aligned %u)", - RndisMessage->MessageLength, - RndisMessage->Message.InitializeComplete.RequestId, - RndisMessage->Message.InitializeComplete.Status, - RndisMessage->Message.InitializeComplete.MajorVersion, - RndisMessage->Message.InitializeComplete.MinorVersion, - RndisMessage->Message.InitializeComplete.DeviceFlags, - RndisMessage->Message.InitializeComplete.MaxTransferSize, - RndisMessage->Message.InitializeComplete.MaxPacketsPerMessage, - RndisMessage->Message.InitializeComplete.PacketAlignmentFactor); + rndis_msg->MessageLength, + rndis_msg->Message.InitializeComplete.RequestId, + rndis_msg->Message.InitializeComplete.Status, + rndis_msg->Message.InitializeComplete.MajorVersion, + rndis_msg->Message.InitializeComplete.MinorVersion, + rndis_msg->Message.InitializeComplete.DeviceFlags, + rndis_msg->Message.InitializeComplete.MaxTransferSize, + rndis_msg->Message.InitializeComplete. + MaxPacketsPerMessage, + rndis_msg->Message.InitializeComplete. + PacketAlignmentFactor); break; case REMOTE_NDIS_QUERY_CMPLT: DPRINT_DBG(NETVSC, "REMOTE_NDIS_QUERY_CMPLT " "(len %u, id 0x%x, status 0x%x, buf len %u, " "buf offset %u)", - RndisMessage->MessageLength, - RndisMessage->Message.QueryComplete.RequestId, - RndisMessage->Message.QueryComplete.Status, - RndisMessage->Message.QueryComplete.InformationBufferLength, - RndisMessage->Message.QueryComplete.InformationBufferOffset); + rndis_msg->MessageLength, + rndis_msg->Message.QueryComplete.RequestId, + rndis_msg->Message.QueryComplete.Status, + rndis_msg->Message.QueryComplete. + InformationBufferLength, + rndis_msg->Message.QueryComplete. + InformationBufferOffset); break; case REMOTE_NDIS_SET_CMPLT: DPRINT_DBG(NETVSC, "REMOTE_NDIS_SET_CMPLT (len %u, id 0x%x, status 0x%x)", - RndisMessage->MessageLength, - RndisMessage->Message.SetComplete.RequestId, - RndisMessage->Message.SetComplete.Status); + rndis_msg->MessageLength, + rndis_msg->Message.SetComplete.RequestId, + rndis_msg->Message.SetComplete.Status); break; case REMOTE_NDIS_INDICATE_STATUS_MSG: DPRINT_DBG(NETVSC, "REMOTE_NDIS_INDICATE_STATUS_MSG " "(len %u, status 0x%x, buf len %u, buf offset %u)", - RndisMessage->MessageLength, - RndisMessage->Message.IndicateStatus.Status, - RndisMessage->Message.IndicateStatus.StatusBufferLength, - RndisMessage->Message.IndicateStatus.StatusBufferOffset); + rndis_msg->MessageLength, + rndis_msg->Message.IndicateStatus.Status, + rndis_msg->Message.IndicateStatus.StatusBufferLength, + rndis_msg->Message.IndicateStatus.StatusBufferOffset); break; default: DPRINT_DBG(NETVSC, "0x%x (len %u)", - RndisMessage->NdisMessageType, - RndisMessage->MessageLength); + rndis_msg->NdisMessageType, + rndis_msg->MessageLength); break; } } -static int RndisFilterSendRequest(struct rndis_device *Device, - struct rndis_request *Request) +static int RndisFilterSendRequest(struct rndis_device *dev, + struct rndis_request *req) { int ret; struct hv_netvsc_packet *packet; /* Setup the packet to send it */ - packet = &Request->Packet; + packet = &req->pkt; packet->IsDataPacket = false; - packet->TotalDataBufferLength = Request->RequestMessage.MessageLength; + packet->TotalDataBufferLength = req->request_msg.MessageLength; packet->PageBufferCount = 1; - packet->PageBuffers[0].Pfn = virt_to_phys(&Request->RequestMessage) >> + packet->PageBuffers[0].Pfn = virt_to_phys(&req->request_msg) >> PAGE_SHIFT; - packet->PageBuffers[0].Length = Request->RequestMessage.MessageLength; + packet->PageBuffers[0].Length = req->request_msg.MessageLength; packet->PageBuffers[0].Offset = - (unsigned long)&Request->RequestMessage & (PAGE_SIZE - 1); + (unsigned long)&req->request_msg & (PAGE_SIZE - 1); - packet->Completion.Send.SendCompletionContext = Request;/* packet; */ + packet->Completion.Send.SendCompletionContext = req;/* packet; */ packet->Completion.Send.OnSendCompletion = RndisFilterOnSendRequestCompletion; - packet->Completion.Send.SendCompletionTid = (unsigned long)Device; + packet->Completion.Send.SendCompletionTid = (unsigned long)dev; - ret = gRndisFilter.InnerDriver.OnSend(Device->NetDevice->Device, packet); + ret = rndis_filter.inner_drv.OnSend(dev->net_dev->Device, packet); return ret; } -static void RndisFilterReceiveResponse(struct rndis_device *Device, - struct rndis_message *Response) +static void RndisFilterReceiveResponse(struct rndis_device *dev, + struct rndis_message *resp) { struct rndis_request *request = NULL; bool found = false; unsigned long flags; - spin_lock_irqsave(&Device->request_lock, flags); - list_for_each_entry(request, &Device->RequestList, ListEntry) { + spin_lock_irqsave(&dev->request_lock, flags); + list_for_each_entry(request, &dev->req_list, list_ent) { /* * All request/response message contains RequestId as the 1st * field */ - if (request->RequestMessage.Message.InitializeRequest.RequestId - == Response->Message.InitializeComplete.RequestId) { + if (request->request_msg.Message.InitializeRequest.RequestId + == resp->Message.InitializeComplete.RequestId) { DPRINT_DBG(NETVSC, "found rndis request for " "this response (id 0x%x req type 0x%x res " "type 0x%x)", - request->RequestMessage.Message.InitializeRequest.RequestId, - request->RequestMessage.NdisMessageType, - Response->NdisMessageType); + request->request_msg.Message. + InitializeRequest.RequestId, + request->request_msg.NdisMessageType, + resp->NdisMessageType); found = true; break; } } - spin_unlock_irqrestore(&Device->request_lock, flags); + spin_unlock_irqrestore(&dev->request_lock, flags); if (found) { - if (Response->MessageLength <= sizeof(struct rndis_message)) { - memcpy(&request->ResponseMessage, Response, - Response->MessageLength); + if (resp->MessageLength <= sizeof(struct rndis_message)) { + memcpy(&request->response_msg, resp, + resp->MessageLength); } else { DPRINT_ERR(NETVSC, "rndis response buffer overflow " "detected (size %u max %zu)", - Response->MessageLength, + resp->MessageLength, sizeof(struct rndis_filter_packet)); - if (Response->NdisMessageType == + if (resp->NdisMessageType == REMOTE_NDIS_RESET_CMPLT) { /* does not have a request id field */ - request->ResponseMessage.Message.ResetComplete.Status = STATUS_BUFFER_OVERFLOW; + request->response_msg.Message.ResetComplete. + Status = STATUS_BUFFER_OVERFLOW; } else { - request->ResponseMessage.Message.InitializeComplete.Status = STATUS_BUFFER_OVERFLOW; + request->response_msg.Message. + InitializeComplete.Status = + STATUS_BUFFER_OVERFLOW; } } - osd_waitevent_set(request->WaitEvent); + osd_waitevent_set(request->waitevent); } else { DPRINT_ERR(NETVSC, "no rndis request found for this response " "(id 0x%x res type 0x%x)", - Response->Message.InitializeComplete.RequestId, - Response->NdisMessageType); + resp->Message.InitializeComplete.RequestId, + resp->NdisMessageType); } } -static void RndisFilterReceiveIndicateStatus(struct rndis_device *Device, - struct rndis_message *Response) +static void RndisFilterReceiveIndicateStatus(struct rndis_device *dev, + struct rndis_message *resp) { struct rndis_indicate_status *indicate = - &Response->Message.IndicateStatus; + &resp->Message.IndicateStatus; if (indicate->Status == RNDIS_STATUS_MEDIA_CONNECT) { - gRndisFilter.InnerDriver.OnLinkStatusChanged(Device->NetDevice->Device, 1); + rndis_filter.inner_drv.OnLinkStatusChanged( + dev->net_dev->Device, 1); } else if (indicate->Status == RNDIS_STATUS_MEDIA_DISCONNECT) { - gRndisFilter.InnerDriver.OnLinkStatusChanged(Device->NetDevice->Device, 0); + rndis_filter.inner_drv.OnLinkStatusChanged( + dev->net_dev->Device, 0); } else { /* * TODO: @@ -339,18 +349,18 @@ static void RndisFilterReceiveIndicateStatus(struct rndis_device *Device, } } -static void RndisFilterReceiveData(struct rndis_device *Device, - struct rndis_message *Message, - struct hv_netvsc_packet *Packet) +static void RndisFilterReceiveData(struct rndis_device *dev, + struct rndis_message *msg, + struct hv_netvsc_packet *pkt) { - struct rndis_packet *rndisPacket; - u32 dataOffset; + struct rndis_packet *rndis_pkt; + u32 data_offset; /* empty ethernet frame ?? */ /* ASSERT(Packet->PageBuffers[0].Length > */ /* RNDIS_MESSAGE_SIZE(struct rndis_packet)); */ - rndisPacket = &Message->Message.Packet; + rndis_pkt = &msg->Message.Packet; /* * FIXME: Handle multiple rndis pkt msgs that maybe enclosed in this @@ -358,48 +368,48 @@ static void RndisFilterReceiveData(struct rndis_device *Device, */ /* Remove the rndis header and pass it back up the stack */ - dataOffset = RNDIS_HEADER_SIZE + rndisPacket->DataOffset; + data_offset = RNDIS_HEADER_SIZE + rndis_pkt->DataOffset; - Packet->TotalDataBufferLength -= dataOffset; - Packet->PageBuffers[0].Offset += dataOffset; - Packet->PageBuffers[0].Length -= dataOffset; + pkt->TotalDataBufferLength -= data_offset; + pkt->PageBuffers[0].Offset += data_offset; + pkt->PageBuffers[0].Length -= data_offset; - Packet->IsDataPacket = true; + pkt->IsDataPacket = true; - gRndisFilter.InnerDriver.OnReceiveCallback(Device->NetDevice->Device, - Packet); + rndis_filter.inner_drv.OnReceiveCallback(dev->net_dev->Device, + pkt); } -static int RndisFilterOnReceive(struct hv_device *Device, - struct hv_netvsc_packet *Packet) +static int RndisFilterOnReceive(struct hv_device *dev, + struct hv_netvsc_packet *pkt) { - struct netvsc_device *netDevice = Device->Extension; - struct rndis_device *rndisDevice; - struct rndis_message rndisMessage; - struct rndis_message *rndisHeader; + struct netvsc_device *net_dev = dev->Extension; + struct rndis_device *rndis_dev; + struct rndis_message rndis_msg; + struct rndis_message *rndis_hdr; - if (!netDevice) + if (!net_dev) return -EINVAL; /* Make sure the rndis device state is initialized */ - if (!netDevice->Extension) { + if (!net_dev->Extension) { DPRINT_ERR(NETVSC, "got rndis message but no rndis device..." "dropping this message!"); return -1; } - rndisDevice = (struct rndis_device *)netDevice->Extension; - if (rndisDevice->State == RNDIS_DEV_UNINITIALIZED) { + rndis_dev = (struct rndis_device *)net_dev->Extension; + if (rndis_dev->state == RNDIS_DEV_UNINITIALIZED) { DPRINT_ERR(NETVSC, "got rndis message but rndis device " "uninitialized...dropping this message!"); return -1; } - rndisHeader = (struct rndis_message *)kmap_atomic( - pfn_to_page(Packet->PageBuffers[0].Pfn), KM_IRQ0); + rndis_hdr = (struct rndis_message *)kmap_atomic( + pfn_to_page(pkt->PageBuffers[0].Pfn), KM_IRQ0); - rndisHeader = (void *)((unsigned long)rndisHeader + - Packet->PageBuffers[0].Offset); + rndis_hdr = (void *)((unsigned long)rndis_hdr + + pkt->PageBuffers[0].Offset); /* Make sure we got a valid rndis message */ /* @@ -408,39 +418,39 @@ static int RndisFilterOnReceive(struct hv_device *Device, * range shows 52 bytes * */ #if 0 - if (Packet->TotalDataBufferLength != rndisHeader->MessageLength) { - kunmap_atomic(rndisHeader - Packet->PageBuffers[0].Offset, + if (pkt->TotalDataBufferLength != rndis_hdr->MessageLength) { + kunmap_atomic(rndis_hdr - pkt->PageBuffers[0].Offset, KM_IRQ0); DPRINT_ERR(NETVSC, "invalid rndis message? (expected %u " "bytes got %u)...dropping this message!", - rndisHeader->MessageLength, - Packet->TotalDataBufferLength); + rndis_hdr->MessageLength, + pkt->TotalDataBufferLength); return -1; } #endif - if ((rndisHeader->NdisMessageType != REMOTE_NDIS_PACKET_MSG) && - (rndisHeader->MessageLength > sizeof(struct rndis_message))) { + if ((rndis_hdr->NdisMessageType != REMOTE_NDIS_PACKET_MSG) && + (rndis_hdr->MessageLength > sizeof(struct rndis_message))) { DPRINT_ERR(NETVSC, "incoming rndis message buffer overflow " "detected (got %u, max %zu)...marking it an error!", - rndisHeader->MessageLength, + rndis_hdr->MessageLength, sizeof(struct rndis_message)); } - memcpy(&rndisMessage, rndisHeader, - (rndisHeader->MessageLength > sizeof(struct rndis_message)) ? + memcpy(&rndis_msg, rndis_hdr, + (rndis_hdr->MessageLength > sizeof(struct rndis_message)) ? sizeof(struct rndis_message) : - rndisHeader->MessageLength); + rndis_hdr->MessageLength); - kunmap_atomic(rndisHeader - Packet->PageBuffers[0].Offset, KM_IRQ0); + kunmap_atomic(rndis_hdr - pkt->PageBuffers[0].Offset, KM_IRQ0); - DumpRndisMessage(&rndisMessage); + DumpRndisMessage(&rndis_msg); - switch (rndisMessage.NdisMessageType) { + switch (rndis_msg.NdisMessageType) { case REMOTE_NDIS_PACKET_MSG: /* data msg */ - RndisFilterReceiveData(rndisDevice, &rndisMessage, Packet); + RndisFilterReceiveData(rndis_dev, &rndis_msg, pkt); break; case REMOTE_NDIS_INITIALIZE_CMPLT: @@ -449,37 +459,37 @@ static int RndisFilterOnReceive(struct hv_device *Device, /* case REMOTE_NDIS_RESET_CMPLT: */ /* case REMOTE_NDIS_KEEPALIVE_CMPLT: */ /* completion msgs */ - RndisFilterReceiveResponse(rndisDevice, &rndisMessage); + RndisFilterReceiveResponse(rndis_dev, &rndis_msg); break; case REMOTE_NDIS_INDICATE_STATUS_MSG: /* notification msgs */ - RndisFilterReceiveIndicateStatus(rndisDevice, &rndisMessage); + RndisFilterReceiveIndicateStatus(rndis_dev, &rndis_msg); break; default: DPRINT_ERR(NETVSC, "unhandled rndis message (type %u len %u)", - rndisMessage.NdisMessageType, - rndisMessage.MessageLength); + rndis_msg.NdisMessageType, + rndis_msg.MessageLength); break; } return 0; } -static int RndisFilterQueryDevice(struct rndis_device *Device, u32 Oid, - void *Result, u32 *ResultSize) +static int RndisFilterQueryDevice(struct rndis_device *dev, u32 oid, + void *result, u32 *result_size) { struct rndis_request *request; - u32 inresultSize = *ResultSize; + u32 inresult_size = *result_size; struct rndis_query_request *query; - struct rndis_query_complete *queryComplete; + struct rndis_query_complete *query_complete; int ret = 0; - if (!Result) + if (!result) return -EINVAL; - *ResultSize = 0; - request = GetRndisRequest(Device, REMOTE_NDIS_QUERY_MSG, + *result_size = 0; + request = GetRndisRequest(dev, REMOTE_NDIS_QUERY_MSG, RNDIS_MESSAGE_SIZE(struct rndis_query_request)); if (!request) { ret = -1; @@ -487,71 +497,71 @@ static int RndisFilterQueryDevice(struct rndis_device *Device, u32 Oid, } /* Setup the rndis query */ - query = &request->RequestMessage.Message.QueryRequest; - query->Oid = Oid; + query = &request->request_msg.Message.QueryRequest; + query->Oid = oid; query->InformationBufferOffset = sizeof(struct rndis_query_request); query->InformationBufferLength = 0; query->DeviceVcHandle = 0; - ret = RndisFilterSendRequest(Device, request); + ret = RndisFilterSendRequest(dev, request); if (ret != 0) goto Cleanup; - osd_waitevent_wait(request->WaitEvent); + osd_waitevent_wait(request->waitevent); /* Copy the response back */ - queryComplete = &request->ResponseMessage.Message.QueryComplete; + query_complete = &request->response_msg.Message.QueryComplete; - if (queryComplete->InformationBufferLength > inresultSize) { + if (query_complete->InformationBufferLength > inresult_size) { ret = -1; goto Cleanup; } - memcpy(Result, - (void *)((unsigned long)queryComplete + - queryComplete->InformationBufferOffset), - queryComplete->InformationBufferLength); + memcpy(result, + (void *)((unsigned long)query_complete + + query_complete->InformationBufferOffset), + query_complete->InformationBufferLength); - *ResultSize = queryComplete->InformationBufferLength; + *result_size = query_complete->InformationBufferLength; Cleanup: if (request) - PutRndisRequest(Device, request); + PutRndisRequest(dev, request); return ret; } -static int RndisFilterQueryDeviceMac(struct rndis_device *Device) +static int RndisFilterQueryDeviceMac(struct rndis_device *dev) { u32 size = ETH_ALEN; - return RndisFilterQueryDevice(Device, + return RndisFilterQueryDevice(dev, RNDIS_OID_802_3_PERMANENT_ADDRESS, - Device->HwMacAddr, &size); + dev->hw_mac_adr, &size); } -static int RndisFilterQueryDeviceLinkStatus(struct rndis_device *Device) +static int RndisFilterQueryDeviceLinkStatus(struct rndis_device *dev) { u32 size = sizeof(u32); - return RndisFilterQueryDevice(Device, + return RndisFilterQueryDevice(dev, RNDIS_OID_GEN_MEDIA_CONNECT_STATUS, - &Device->LinkStatus, &size); + &dev->link_stat, &size); } -static int RndisFilterSetPacketFilter(struct rndis_device *Device, - u32 NewFilter) +static int RndisFilterSetPacketFilter(struct rndis_device *dev, + u32 new_filter) { struct rndis_request *request; struct rndis_set_request *set; - struct rndis_set_complete *setComplete; + struct rndis_set_complete *set_complete; u32 status; int ret; /* ASSERT(RNDIS_MESSAGE_SIZE(struct rndis_set_request) + sizeof(u32) <= */ /* sizeof(struct rndis_message)); */ - request = GetRndisRequest(Device, REMOTE_NDIS_SET_MSG, + request = GetRndisRequest(dev, REMOTE_NDIS_SET_MSG, RNDIS_MESSAGE_SIZE(struct rndis_set_request) + sizeof(u32)); if (!request) { @@ -560,19 +570,19 @@ static int RndisFilterSetPacketFilter(struct rndis_device *Device, } /* Setup the rndis set */ - set = &request->RequestMessage.Message.SetRequest; + set = &request->request_msg.Message.SetRequest; set->Oid = RNDIS_OID_GEN_CURRENT_PACKET_FILTER; set->InformationBufferLength = sizeof(u32); set->InformationBufferOffset = sizeof(struct rndis_set_request); memcpy((void *)(unsigned long)set + sizeof(struct rndis_set_request), - &NewFilter, sizeof(u32)); + &new_filter, sizeof(u32)); - ret = RndisFilterSendRequest(Device, request); + ret = RndisFilterSendRequest(dev, request); if (ret != 0) goto Cleanup; - ret = osd_waitevent_waitex(request->WaitEvent, 2000/*2sec*/); + ret = osd_waitevent_waitex(request->waitevent, 2000/*2sec*/); if (!ret) { ret = -1; DPRINT_ERR(NETVSC, "timeout before we got a set response..."); @@ -584,27 +594,27 @@ static int RndisFilterSetPacketFilter(struct rndis_device *Device, } else { if (ret > 0) ret = 0; - setComplete = &request->ResponseMessage.Message.SetComplete; - status = setComplete->Status; + set_complete = &request->response_msg.Message.SetComplete; + status = set_complete->Status; } Cleanup: if (request) - PutRndisRequest(Device, request); + PutRndisRequest(dev, request); Exit: return ret; } -int RndisFilterInit(struct netvsc_driver *Driver) +int RndisFilterInit(struct netvsc_driver *drv) { DPRINT_DBG(NETVSC, "sizeof(struct rndis_filter_packet) == %zd", sizeof(struct rndis_filter_packet)); - Driver->RequestExtSize = sizeof(struct rndis_filter_packet); + drv->RequestExtSize = sizeof(struct rndis_filter_packet); /* Driver->Context = rndisDriver; */ - memset(&gRndisFilter, 0, sizeof(struct rndis_filter_driver_object)); + memset(&rndis_filter, 0, sizeof(struct rndis_filter_driver_object)); /*rndisDriver->Driver = Driver; @@ -612,38 +622,38 @@ int RndisFilterInit(struct netvsc_driver *Driver) rndisDriver->OnLinkStatusChanged = Driver->OnLinkStatusChanged;*/ /* Save the original dispatch handlers before we override it */ - gRndisFilter.InnerDriver.Base.OnDeviceAdd = Driver->Base.OnDeviceAdd; - gRndisFilter.InnerDriver.Base.OnDeviceRemove = - Driver->Base.OnDeviceRemove; - gRndisFilter.InnerDriver.Base.OnCleanup = Driver->Base.OnCleanup; + rndis_filter.inner_drv.Base.OnDeviceAdd = drv->Base.OnDeviceAdd; + rndis_filter.inner_drv.Base.OnDeviceRemove = + drv->Base.OnDeviceRemove; + rndis_filter.inner_drv.Base.OnCleanup = drv->Base.OnCleanup; /* ASSERT(Driver->OnSend); */ /* ASSERT(Driver->OnReceiveCallback); */ - gRndisFilter.InnerDriver.OnSend = Driver->OnSend; - gRndisFilter.InnerDriver.OnReceiveCallback = Driver->OnReceiveCallback; - gRndisFilter.InnerDriver.OnLinkStatusChanged = - Driver->OnLinkStatusChanged; + rndis_filter.inner_drv.OnSend = drv->OnSend; + rndis_filter.inner_drv.OnReceiveCallback = drv->OnReceiveCallback; + rndis_filter.inner_drv.OnLinkStatusChanged = + drv->OnLinkStatusChanged; /* Override */ - Driver->Base.OnDeviceAdd = RndisFilterOnDeviceAdd; - Driver->Base.OnDeviceRemove = RndisFilterOnDeviceRemove; - Driver->Base.OnCleanup = RndisFilterOnCleanup; - Driver->OnSend = RndisFilterOnSend; + drv->Base.OnDeviceAdd = RndisFilterOnDeviceAdd; + drv->Base.OnDeviceRemove = RndisFilterOnDeviceRemove; + drv->Base.OnCleanup = RndisFilterOnCleanup; + drv->OnSend = RndisFilterOnSend; /* Driver->QueryLinkStatus = RndisFilterQueryDeviceLinkStatus; */ - Driver->OnReceiveCallback = RndisFilterOnReceive; + drv->OnReceiveCallback = RndisFilterOnReceive; return 0; } -static int RndisFilterInitDevice(struct rndis_device *Device) +static int RndisFilterInitDevice(struct rndis_device *dev) { struct rndis_request *request; struct rndis_initialize_request *init; - struct rndis_initialize_complete *initComplete; + struct rndis_initialize_complete *init_complete; u32 status; int ret; - request = GetRndisRequest(Device, REMOTE_NDIS_INITIALIZE_MSG, + request = GetRndisRequest(dev, REMOTE_NDIS_INITIALIZE_MSG, RNDIS_MESSAGE_SIZE(struct rndis_initialize_request)); if (!request) { ret = -1; @@ -651,103 +661,103 @@ static int RndisFilterInitDevice(struct rndis_device *Device) } /* Setup the rndis set */ - init = &request->RequestMessage.Message.InitializeRequest; + init = &request->request_msg.Message.InitializeRequest; init->MajorVersion = RNDIS_MAJOR_VERSION; init->MinorVersion = RNDIS_MINOR_VERSION; /* FIXME: Use 1536 - rounded ethernet frame size */ init->MaxTransferSize = 2048; - Device->State = RNDIS_DEV_INITIALIZING; + dev->state = RNDIS_DEV_INITIALIZING; - ret = RndisFilterSendRequest(Device, request); + ret = RndisFilterSendRequest(dev, request); if (ret != 0) { - Device->State = RNDIS_DEV_UNINITIALIZED; + dev->state = RNDIS_DEV_UNINITIALIZED; goto Cleanup; } - osd_waitevent_wait(request->WaitEvent); + osd_waitevent_wait(request->waitevent); - initComplete = &request->ResponseMessage.Message.InitializeComplete; - status = initComplete->Status; + init_complete = &request->response_msg.Message.InitializeComplete; + status = init_complete->Status; if (status == RNDIS_STATUS_SUCCESS) { - Device->State = RNDIS_DEV_INITIALIZED; + dev->state = RNDIS_DEV_INITIALIZED; ret = 0; } else { - Device->State = RNDIS_DEV_UNINITIALIZED; + dev->state = RNDIS_DEV_UNINITIALIZED; ret = -1; } Cleanup: if (request) - PutRndisRequest(Device, request); + PutRndisRequest(dev, request); return ret; } -static void RndisFilterHaltDevice(struct rndis_device *Device) +static void RndisFilterHaltDevice(struct rndis_device *dev) { struct rndis_request *request; struct rndis_halt_request *halt; /* Attempt to do a rndis device halt */ - request = GetRndisRequest(Device, REMOTE_NDIS_HALT_MSG, + request = GetRndisRequest(dev, REMOTE_NDIS_HALT_MSG, RNDIS_MESSAGE_SIZE(struct rndis_halt_request)); if (!request) goto Cleanup; /* Setup the rndis set */ - halt = &request->RequestMessage.Message.HaltRequest; - halt->RequestId = atomic_inc_return(&Device->NewRequestId); + halt = &request->request_msg.Message.HaltRequest; + halt->RequestId = atomic_inc_return(&dev->new_req_id); /* Ignore return since this msg is optional. */ - RndisFilterSendRequest(Device, request); + RndisFilterSendRequest(dev, request); - Device->State = RNDIS_DEV_UNINITIALIZED; + dev->state = RNDIS_DEV_UNINITIALIZED; Cleanup: if (request) - PutRndisRequest(Device, request); + PutRndisRequest(dev, request); return; } -static int RndisFilterOpenDevice(struct rndis_device *Device) +static int RndisFilterOpenDevice(struct rndis_device *dev) { int ret; - if (Device->State != RNDIS_DEV_INITIALIZED) + if (dev->state != RNDIS_DEV_INITIALIZED) return 0; - ret = RndisFilterSetPacketFilter(Device, + ret = RndisFilterSetPacketFilter(dev, NDIS_PACKET_TYPE_BROADCAST | NDIS_PACKET_TYPE_ALL_MULTICAST | NDIS_PACKET_TYPE_DIRECTED); if (ret == 0) - Device->State = RNDIS_DEV_DATAINITIALIZED; + dev->state = RNDIS_DEV_DATAINITIALIZED; return ret; } -static int RndisFilterCloseDevice(struct rndis_device *Device) +static int RndisFilterCloseDevice(struct rndis_device *dev) { int ret; - if (Device->State != RNDIS_DEV_DATAINITIALIZED) + if (dev->state != RNDIS_DEV_DATAINITIALIZED) return 0; - ret = RndisFilterSetPacketFilter(Device, 0); + ret = RndisFilterSetPacketFilter(dev, 0); if (ret == 0) - Device->State = RNDIS_DEV_INITIALIZED; + dev->state = RNDIS_DEV_INITIALIZED; return ret; } -static int RndisFilterOnDeviceAdd(struct hv_device *Device, - void *AdditionalInfo) +static int RndisFilterOnDeviceAdd(struct hv_device *dev, + void *additional_info) { int ret; struct netvsc_device *netDevice; struct rndis_device *rndisDevice; - struct netvsc_device_info *deviceInfo = AdditionalInfo; + struct netvsc_device_info *deviceInfo = additional_info; rndisDevice = GetRndisDevice(); if (!rndisDevice) @@ -760,7 +770,7 @@ static int RndisFilterOnDeviceAdd(struct hv_device *Device, * NOTE! Once the channel is created, we may get a receive callback * (RndisFilterOnReceive()) before this call is completed */ - ret = gRndisFilter.InnerDriver.Base.OnDeviceAdd(Device, AdditionalInfo); + ret = rndis_filter.inner_drv.Base.OnDeviceAdd(dev, additional_info); if (ret != 0) { kfree(rndisDevice); return ret; @@ -768,12 +778,12 @@ static int RndisFilterOnDeviceAdd(struct hv_device *Device, /* Initialize the rndis device */ - netDevice = Device->Extension; + netDevice = dev->Extension; /* ASSERT(netDevice); */ /* ASSERT(netDevice->Device); */ netDevice->Extension = rndisDevice; - rndisDevice->NetDevice = netDevice; + rndisDevice->net_dev = netDevice; /* Send the rndis initialization message */ ret = RndisFilterInitDevice(rndisDevice); @@ -793,43 +803,43 @@ static int RndisFilterOnDeviceAdd(struct hv_device *Device, } DPRINT_INFO(NETVSC, "Device 0x%p mac addr %pM", - rndisDevice, rndisDevice->HwMacAddr); + rndisDevice, rndisDevice->hw_mac_adr); - memcpy(deviceInfo->MacAddr, rndisDevice->HwMacAddr, ETH_ALEN); + memcpy(deviceInfo->MacAddr, rndisDevice->hw_mac_adr, ETH_ALEN); RndisFilterQueryDeviceLinkStatus(rndisDevice); - deviceInfo->LinkState = rndisDevice->LinkStatus; + deviceInfo->LinkState = rndisDevice->link_stat; DPRINT_INFO(NETVSC, "Device 0x%p link state %s", rndisDevice, ((deviceInfo->LinkState) ? ("down") : ("up"))); return ret; } -static int RndisFilterOnDeviceRemove(struct hv_device *Device) +static int RndisFilterOnDeviceRemove(struct hv_device *dev) { - struct netvsc_device *netDevice = Device->Extension; - struct rndis_device *rndisDevice = netDevice->Extension; + struct netvsc_device *net_dev = dev->Extension; + struct rndis_device *rndis_dev = net_dev->Extension; /* Halt and release the rndis device */ - RndisFilterHaltDevice(rndisDevice); + RndisFilterHaltDevice(rndis_dev); - kfree(rndisDevice); - netDevice->Extension = NULL; + kfree(rndis_dev); + net_dev->Extension = NULL; /* Pass control to inner driver to remove the device */ - gRndisFilter.InnerDriver.Base.OnDeviceRemove(Device); + rndis_filter.inner_drv.Base.OnDeviceRemove(dev); return 0; } -static void RndisFilterOnCleanup(struct hv_driver *Driver) +static void RndisFilterOnCleanup(struct hv_driver *drv) { } -int RndisFilterOnOpen(struct hv_device *Device) +int RndisFilterOnOpen(struct hv_device *dev) { - struct netvsc_device *netDevice = Device->Extension; + struct netvsc_device *netDevice = dev->Extension; if (!netDevice) return -EINVAL; @@ -837,9 +847,9 @@ int RndisFilterOnOpen(struct hv_device *Device) return RndisFilterOpenDevice(netDevice->Extension); } -int RndisFilterOnClose(struct hv_device *Device) +int RndisFilterOnClose(struct hv_device *dev) { - struct netvsc_device *netDevice = Device->Extension; + struct netvsc_device *netDevice = dev->Extension; if (!netDevice) return -EINVAL; @@ -847,8 +857,8 @@ int RndisFilterOnClose(struct hv_device *Device) return RndisFilterCloseDevice(netDevice->Extension); } -static int RndisFilterOnSend(struct hv_device *Device, - struct hv_netvsc_packet *Packet) +static int RndisFilterOnSend(struct hv_device *dev, + struct hv_netvsc_packet *pkt) { int ret; struct rndis_filter_packet *filterPacket; @@ -857,62 +867,62 @@ static int RndisFilterOnSend(struct hv_device *Device, u32 rndisMessageSize; /* Add the rndis header */ - filterPacket = (struct rndis_filter_packet *)Packet->Extension; + filterPacket = (struct rndis_filter_packet *)pkt->Extension; /* ASSERT(filterPacket); */ memset(filterPacket, 0, sizeof(struct rndis_filter_packet)); - rndisMessage = &filterPacket->Message; + rndisMessage = &filterPacket->msg; rndisMessageSize = RNDIS_MESSAGE_SIZE(struct rndis_packet); rndisMessage->NdisMessageType = REMOTE_NDIS_PACKET_MSG; - rndisMessage->MessageLength = Packet->TotalDataBufferLength + + rndisMessage->MessageLength = pkt->TotalDataBufferLength + rndisMessageSize; rndisPacket = &rndisMessage->Message.Packet; rndisPacket->DataOffset = sizeof(struct rndis_packet); - rndisPacket->DataLength = Packet->TotalDataBufferLength; + rndisPacket->DataLength = pkt->TotalDataBufferLength; - Packet->IsDataPacket = true; - Packet->PageBuffers[0].Pfn = virt_to_phys(rndisMessage) >> PAGE_SHIFT; - Packet->PageBuffers[0].Offset = + pkt->IsDataPacket = true; + pkt->PageBuffers[0].Pfn = virt_to_phys(rndisMessage) >> PAGE_SHIFT; + pkt->PageBuffers[0].Offset = (unsigned long)rndisMessage & (PAGE_SIZE-1); - Packet->PageBuffers[0].Length = rndisMessageSize; + pkt->PageBuffers[0].Length = rndisMessageSize; /* Save the packet send completion and context */ - filterPacket->OnCompletion = Packet->Completion.Send.OnSendCompletion; - filterPacket->CompletionContext = - Packet->Completion.Send.SendCompletionContext; + filterPacket->completion = pkt->Completion.Send.OnSendCompletion; + filterPacket->completion_ctx = + pkt->Completion.Send.SendCompletionContext; /* Use ours */ - Packet->Completion.Send.OnSendCompletion = RndisFilterOnSendCompletion; - Packet->Completion.Send.SendCompletionContext = filterPacket; + pkt->Completion.Send.OnSendCompletion = RndisFilterOnSendCompletion; + pkt->Completion.Send.SendCompletionContext = filterPacket; - ret = gRndisFilter.InnerDriver.OnSend(Device, Packet); + ret = rndis_filter.inner_drv.OnSend(dev, pkt); if (ret != 0) { /* * Reset the completion to originals to allow retries from * above */ - Packet->Completion.Send.OnSendCompletion = - filterPacket->OnCompletion; - Packet->Completion.Send.SendCompletionContext = - filterPacket->CompletionContext; + pkt->Completion.Send.OnSendCompletion = + filterPacket->completion; + pkt->Completion.Send.SendCompletionContext = + filterPacket->completion_ctx; } return ret; } -static void RndisFilterOnSendCompletion(void *Context) +static void RndisFilterOnSendCompletion(void *ctx) { - struct rndis_filter_packet *filterPacket = Context; + struct rndis_filter_packet *filterPacket = ctx; /* Pass it back to the original handler */ - filterPacket->OnCompletion(filterPacket->CompletionContext); + filterPacket->completion(filterPacket->completion_ctx); } -static void RndisFilterOnSendRequestCompletion(void *Context) +static void RndisFilterOnSendRequestCompletion(void *ctx) { /* Noop */ } -- cgit v1.2.3 From 9c26aa0d763a8390177f50ae841148706a249793 Mon Sep 17 00:00:00 2001 From: Haiyang Zhang Date: Fri, 10 Dec 2010 12:03:57 -0800 Subject: staging: hv: Convert camel cased functions in rndis_filter.c to lower cases Signed-off-by: Haiyang Zhang Signed-off-by: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/netvsc.c | 2 +- drivers/staging/hv/netvsc_api.h | 4 +- drivers/staging/hv/netvsc_drv.c | 4 +- drivers/staging/hv/rndis_filter.c | 132 +++++++++++++++++++------------------- drivers/staging/hv/rndis_filter.h | 2 +- 5 files changed, 72 insertions(+), 72 deletions(-) diff --git a/drivers/staging/hv/netvsc.c b/drivers/staging/hv/netvsc.c index 781d7bd37102..5c327fc0d1fd 100644 --- a/drivers/staging/hv/netvsc.c +++ b/drivers/staging/hv/netvsc.c @@ -202,7 +202,7 @@ int netvsc_initialize(struct hv_driver *drv) driver->OnSend = netvsc_send; - RndisFilterInit(driver); + rndis_filter_init(driver); return 0; } diff --git a/drivers/staging/hv/netvsc_api.h b/drivers/staging/hv/netvsc_api.h index dbf154acd967..315271d69914 100644 --- a/drivers/staging/hv/netvsc_api.h +++ b/drivers/staging/hv/netvsc_api.h @@ -110,7 +110,7 @@ struct netvsc_device_info { /* Interface */ int netvsc_initialize(struct hv_driver *drv); -int RndisFilterOnOpen(struct hv_device *Device); -int RndisFilterOnClose(struct hv_device *Device); +int rndis_filter_open(struct hv_device *dev); +int rndis_filter_close(struct hv_device *dev); #endif /* _NETVSC_API_H_ */ diff --git a/drivers/staging/hv/netvsc_drv.c b/drivers/staging/hv/netvsc_drv.c index cd3eef04e59e..e47681e7be82 100644 --- a/drivers/staging/hv/netvsc_drv.c +++ b/drivers/staging/hv/netvsc_drv.c @@ -81,7 +81,7 @@ static int netvsc_open(struct net_device *net) if (netif_carrier_ok(net)) { /* Open up the device */ - ret = RndisFilterOnOpen(device_obj); + ret = rndis_filter_open(device_obj); if (ret != 0) { DPRINT_ERR(NETVSC_DRV, "unable to open device (ret %d).", ret); @@ -104,7 +104,7 @@ static int netvsc_close(struct net_device *net) netif_stop_queue(net); - ret = RndisFilterOnClose(device_obj); + ret = rndis_filter_close(device_obj); if (ret != 0) DPRINT_ERR(NETVSC_DRV, "unable to close device (ret %d).", ret); diff --git a/drivers/staging/hv/rndis_filter.c b/drivers/staging/hv/rndis_filter.c index 28b7e7e59f0a..e560f380adb5 100644 --- a/drivers/staging/hv/rndis_filter.c +++ b/drivers/staging/hv/rndis_filter.c @@ -81,25 +81,25 @@ struct rndis_filter_packet { }; -static int RndisFilterOnDeviceAdd(struct hv_device *dev, +static int rndis_filte_device_add(struct hv_device *dev, void *additional_info); -static int RndisFilterOnDeviceRemove(struct hv_device *dev); +static int rndis_filter_device_remove(struct hv_device *dev); -static void RndisFilterOnCleanup(struct hv_driver *drv); +static void rndis_filter_cleanup(struct hv_driver *drv); -static int RndisFilterOnSend(struct hv_device *dev, +static int rndis_filter_send(struct hv_device *dev, struct hv_netvsc_packet *pkt); -static void RndisFilterOnSendCompletion(void *ctx); +static void rndis_filter_send_completion(void *ctx); -static void RndisFilterOnSendRequestCompletion(void *ctx); +static void rndis_filter_send_request_completion(void *ctx); /* The one and only */ static struct rndis_filter_driver_object rndis_filter; -static struct rndis_device *GetRndisDevice(void) +static struct rndis_device *get_rndis_device(void) { struct rndis_device *device; @@ -116,7 +116,7 @@ static struct rndis_device *GetRndisDevice(void) return device; } -static struct rndis_request *GetRndisRequest(struct rndis_device *dev, +static struct rndis_request *get_rndis_request(struct rndis_device *dev, u32 msg_type, u32 msg_len) { @@ -155,7 +155,7 @@ static struct rndis_request *GetRndisRequest(struct rndis_device *dev, return request; } -static void PutRndisRequest(struct rndis_device *dev, +static void put_rndis_request(struct rndis_device *dev, struct rndis_request *req) { unsigned long flags; @@ -168,7 +168,7 @@ static void PutRndisRequest(struct rndis_device *dev, kfree(req); } -static void DumpRndisMessage(struct rndis_message *rndis_msg) +static void dump_rndis_message(struct rndis_message *rndis_msg) { switch (rndis_msg->NdisMessageType) { case REMOTE_NDIS_PACKET_MSG: @@ -242,7 +242,7 @@ static void DumpRndisMessage(struct rndis_message *rndis_msg) } } -static int RndisFilterSendRequest(struct rndis_device *dev, +static int rndis_filter_send_request(struct rndis_device *dev, struct rndis_request *req) { int ret; @@ -263,14 +263,14 @@ static int RndisFilterSendRequest(struct rndis_device *dev, packet->Completion.Send.SendCompletionContext = req;/* packet; */ packet->Completion.Send.OnSendCompletion = - RndisFilterOnSendRequestCompletion; + rndis_filter_send_request_completion; packet->Completion.Send.SendCompletionTid = (unsigned long)dev; ret = rndis_filter.inner_drv.OnSend(dev->net_dev->Device, packet); return ret; } -static void RndisFilterReceiveResponse(struct rndis_device *dev, +static void rndis_filter_receive_response(struct rndis_device *dev, struct rndis_message *resp) { struct rndis_request *request = NULL; @@ -330,7 +330,7 @@ static void RndisFilterReceiveResponse(struct rndis_device *dev, } } -static void RndisFilterReceiveIndicateStatus(struct rndis_device *dev, +static void rndis_filter_receive_indicate_status(struct rndis_device *dev, struct rndis_message *resp) { struct rndis_indicate_status *indicate = @@ -349,7 +349,7 @@ static void RndisFilterReceiveIndicateStatus(struct rndis_device *dev, } } -static void RndisFilterReceiveData(struct rndis_device *dev, +static void rndis_filter_receive_data(struct rndis_device *dev, struct rndis_message *msg, struct hv_netvsc_packet *pkt) { @@ -380,7 +380,7 @@ static void RndisFilterReceiveData(struct rndis_device *dev, pkt); } -static int RndisFilterOnReceive(struct hv_device *dev, +static int rndis_filter_receive(struct hv_device *dev, struct hv_netvsc_packet *pkt) { struct netvsc_device *net_dev = dev->Extension; @@ -445,12 +445,12 @@ static int RndisFilterOnReceive(struct hv_device *dev, kunmap_atomic(rndis_hdr - pkt->PageBuffers[0].Offset, KM_IRQ0); - DumpRndisMessage(&rndis_msg); + dump_rndis_message(&rndis_msg); switch (rndis_msg.NdisMessageType) { case REMOTE_NDIS_PACKET_MSG: /* data msg */ - RndisFilterReceiveData(rndis_dev, &rndis_msg, pkt); + rndis_filter_receive_data(rndis_dev, &rndis_msg, pkt); break; case REMOTE_NDIS_INITIALIZE_CMPLT: @@ -459,12 +459,12 @@ static int RndisFilterOnReceive(struct hv_device *dev, /* case REMOTE_NDIS_RESET_CMPLT: */ /* case REMOTE_NDIS_KEEPALIVE_CMPLT: */ /* completion msgs */ - RndisFilterReceiveResponse(rndis_dev, &rndis_msg); + rndis_filter_receive_response(rndis_dev, &rndis_msg); break; case REMOTE_NDIS_INDICATE_STATUS_MSG: /* notification msgs */ - RndisFilterReceiveIndicateStatus(rndis_dev, &rndis_msg); + rndis_filter_receive_indicate_status(rndis_dev, &rndis_msg); break; default: DPRINT_ERR(NETVSC, "unhandled rndis message (type %u len %u)", @@ -476,7 +476,7 @@ static int RndisFilterOnReceive(struct hv_device *dev, return 0; } -static int RndisFilterQueryDevice(struct rndis_device *dev, u32 oid, +static int rndis_filter_query_device(struct rndis_device *dev, u32 oid, void *result, u32 *result_size) { struct rndis_request *request; @@ -489,7 +489,7 @@ static int RndisFilterQueryDevice(struct rndis_device *dev, u32 oid, return -EINVAL; *result_size = 0; - request = GetRndisRequest(dev, REMOTE_NDIS_QUERY_MSG, + request = get_rndis_request(dev, REMOTE_NDIS_QUERY_MSG, RNDIS_MESSAGE_SIZE(struct rndis_query_request)); if (!request) { ret = -1; @@ -503,7 +503,7 @@ static int RndisFilterQueryDevice(struct rndis_device *dev, u32 oid, query->InformationBufferLength = 0; query->DeviceVcHandle = 0; - ret = RndisFilterSendRequest(dev, request); + ret = rndis_filter_send_request(dev, request); if (ret != 0) goto Cleanup; @@ -526,30 +526,30 @@ static int RndisFilterQueryDevice(struct rndis_device *dev, u32 oid, Cleanup: if (request) - PutRndisRequest(dev, request); + put_rndis_request(dev, request); return ret; } -static int RndisFilterQueryDeviceMac(struct rndis_device *dev) +static int rndis_filter_query_device_mac(struct rndis_device *dev) { u32 size = ETH_ALEN; - return RndisFilterQueryDevice(dev, + return rndis_filter_query_device(dev, RNDIS_OID_802_3_PERMANENT_ADDRESS, dev->hw_mac_adr, &size); } -static int RndisFilterQueryDeviceLinkStatus(struct rndis_device *dev) +static int rndis_filter_query_device_link_status(struct rndis_device *dev) { u32 size = sizeof(u32); - return RndisFilterQueryDevice(dev, + return rndis_filter_query_device(dev, RNDIS_OID_GEN_MEDIA_CONNECT_STATUS, &dev->link_stat, &size); } -static int RndisFilterSetPacketFilter(struct rndis_device *dev, +static int rndis_filter_set_packet_filter(struct rndis_device *dev, u32 new_filter) { struct rndis_request *request; @@ -561,7 +561,7 @@ static int RndisFilterSetPacketFilter(struct rndis_device *dev, /* ASSERT(RNDIS_MESSAGE_SIZE(struct rndis_set_request) + sizeof(u32) <= */ /* sizeof(struct rndis_message)); */ - request = GetRndisRequest(dev, REMOTE_NDIS_SET_MSG, + request = get_rndis_request(dev, REMOTE_NDIS_SET_MSG, RNDIS_MESSAGE_SIZE(struct rndis_set_request) + sizeof(u32)); if (!request) { @@ -578,7 +578,7 @@ static int RndisFilterSetPacketFilter(struct rndis_device *dev, memcpy((void *)(unsigned long)set + sizeof(struct rndis_set_request), &new_filter, sizeof(u32)); - ret = RndisFilterSendRequest(dev, request); + ret = rndis_filter_send_request(dev, request); if (ret != 0) goto Cleanup; @@ -600,12 +600,12 @@ static int RndisFilterSetPacketFilter(struct rndis_device *dev, Cleanup: if (request) - PutRndisRequest(dev, request); + put_rndis_request(dev, request); Exit: return ret; } -int RndisFilterInit(struct netvsc_driver *drv) +int rndis_filter_init(struct netvsc_driver *drv) { DPRINT_DBG(NETVSC, "sizeof(struct rndis_filter_packet) == %zd", sizeof(struct rndis_filter_packet)); @@ -635,17 +635,17 @@ int RndisFilterInit(struct netvsc_driver *drv) drv->OnLinkStatusChanged; /* Override */ - drv->Base.OnDeviceAdd = RndisFilterOnDeviceAdd; - drv->Base.OnDeviceRemove = RndisFilterOnDeviceRemove; - drv->Base.OnCleanup = RndisFilterOnCleanup; - drv->OnSend = RndisFilterOnSend; + drv->Base.OnDeviceAdd = rndis_filte_device_add; + drv->Base.OnDeviceRemove = rndis_filter_device_remove; + drv->Base.OnCleanup = rndis_filter_cleanup; + drv->OnSend = rndis_filter_send; /* Driver->QueryLinkStatus = RndisFilterQueryDeviceLinkStatus; */ - drv->OnReceiveCallback = RndisFilterOnReceive; + drv->OnReceiveCallback = rndis_filter_receive; return 0; } -static int RndisFilterInitDevice(struct rndis_device *dev) +static int rndis_filter_init_device(struct rndis_device *dev) { struct rndis_request *request; struct rndis_initialize_request *init; @@ -653,7 +653,7 @@ static int RndisFilterInitDevice(struct rndis_device *dev) u32 status; int ret; - request = GetRndisRequest(dev, REMOTE_NDIS_INITIALIZE_MSG, + request = get_rndis_request(dev, REMOTE_NDIS_INITIALIZE_MSG, RNDIS_MESSAGE_SIZE(struct rndis_initialize_request)); if (!request) { ret = -1; @@ -669,7 +669,7 @@ static int RndisFilterInitDevice(struct rndis_device *dev) dev->state = RNDIS_DEV_INITIALIZING; - ret = RndisFilterSendRequest(dev, request); + ret = rndis_filter_send_request(dev, request); if (ret != 0) { dev->state = RNDIS_DEV_UNINITIALIZED; goto Cleanup; @@ -689,18 +689,18 @@ static int RndisFilterInitDevice(struct rndis_device *dev) Cleanup: if (request) - PutRndisRequest(dev, request); + put_rndis_request(dev, request); return ret; } -static void RndisFilterHaltDevice(struct rndis_device *dev) +static void rndis_filter_halt_device(struct rndis_device *dev) { struct rndis_request *request; struct rndis_halt_request *halt; /* Attempt to do a rndis device halt */ - request = GetRndisRequest(dev, REMOTE_NDIS_HALT_MSG, + request = get_rndis_request(dev, REMOTE_NDIS_HALT_MSG, RNDIS_MESSAGE_SIZE(struct rndis_halt_request)); if (!request) goto Cleanup; @@ -710,24 +710,24 @@ static void RndisFilterHaltDevice(struct rndis_device *dev) halt->RequestId = atomic_inc_return(&dev->new_req_id); /* Ignore return since this msg is optional. */ - RndisFilterSendRequest(dev, request); + rndis_filter_send_request(dev, request); dev->state = RNDIS_DEV_UNINITIALIZED; Cleanup: if (request) - PutRndisRequest(dev, request); + put_rndis_request(dev, request); return; } -static int RndisFilterOpenDevice(struct rndis_device *dev) +static int rndis_filter_open_device(struct rndis_device *dev) { int ret; if (dev->state != RNDIS_DEV_INITIALIZED) return 0; - ret = RndisFilterSetPacketFilter(dev, + ret = rndis_filter_set_packet_filter(dev, NDIS_PACKET_TYPE_BROADCAST | NDIS_PACKET_TYPE_ALL_MULTICAST | NDIS_PACKET_TYPE_DIRECTED); @@ -737,21 +737,21 @@ static int RndisFilterOpenDevice(struct rndis_device *dev) return ret; } -static int RndisFilterCloseDevice(struct rndis_device *dev) +static int rndis_filter_close_device(struct rndis_device *dev) { int ret; if (dev->state != RNDIS_DEV_DATAINITIALIZED) return 0; - ret = RndisFilterSetPacketFilter(dev, 0); + ret = rndis_filter_set_packet_filter(dev, 0); if (ret == 0) dev->state = RNDIS_DEV_INITIALIZED; return ret; } -static int RndisFilterOnDeviceAdd(struct hv_device *dev, +static int rndis_filte_device_add(struct hv_device *dev, void *additional_info) { int ret; @@ -759,7 +759,7 @@ static int RndisFilterOnDeviceAdd(struct hv_device *dev, struct rndis_device *rndisDevice; struct netvsc_device_info *deviceInfo = additional_info; - rndisDevice = GetRndisDevice(); + rndisDevice = get_rndis_device(); if (!rndisDevice) return -1; @@ -786,7 +786,7 @@ static int RndisFilterOnDeviceAdd(struct hv_device *dev, rndisDevice->net_dev = netDevice; /* Send the rndis initialization message */ - ret = RndisFilterInitDevice(rndisDevice); + ret = rndis_filter_init_device(rndisDevice); if (ret != 0) { /* * TODO: If rndis init failed, we will need to shut down the @@ -795,7 +795,7 @@ static int RndisFilterOnDeviceAdd(struct hv_device *dev, } /* Get the mac address */ - ret = RndisFilterQueryDeviceMac(rndisDevice); + ret = rndis_filter_query_device_mac(rndisDevice); if (ret != 0) { /* * TODO: shutdown rndis device and the channel @@ -807,7 +807,7 @@ static int RndisFilterOnDeviceAdd(struct hv_device *dev, memcpy(deviceInfo->MacAddr, rndisDevice->hw_mac_adr, ETH_ALEN); - RndisFilterQueryDeviceLinkStatus(rndisDevice); + rndis_filter_query_device_link_status(rndisDevice); deviceInfo->LinkState = rndisDevice->link_stat; DPRINT_INFO(NETVSC, "Device 0x%p link state %s", rndisDevice, @@ -816,13 +816,13 @@ static int RndisFilterOnDeviceAdd(struct hv_device *dev, return ret; } -static int RndisFilterOnDeviceRemove(struct hv_device *dev) +static int rndis_filter_device_remove(struct hv_device *dev) { struct netvsc_device *net_dev = dev->Extension; struct rndis_device *rndis_dev = net_dev->Extension; /* Halt and release the rndis device */ - RndisFilterHaltDevice(rndis_dev); + rndis_filter_halt_device(rndis_dev); kfree(rndis_dev); net_dev->Extension = NULL; @@ -833,31 +833,31 @@ static int RndisFilterOnDeviceRemove(struct hv_device *dev) return 0; } -static void RndisFilterOnCleanup(struct hv_driver *drv) +static void rndis_filter_cleanup(struct hv_driver *drv) { } -int RndisFilterOnOpen(struct hv_device *dev) +int rndis_filter_open(struct hv_device *dev) { struct netvsc_device *netDevice = dev->Extension; if (!netDevice) return -EINVAL; - return RndisFilterOpenDevice(netDevice->Extension); + return rndis_filter_open_device(netDevice->Extension); } -int RndisFilterOnClose(struct hv_device *dev) +int rndis_filter_close(struct hv_device *dev) { struct netvsc_device *netDevice = dev->Extension; if (!netDevice) return -EINVAL; - return RndisFilterCloseDevice(netDevice->Extension); + return rndis_filter_close_device(netDevice->Extension); } -static int RndisFilterOnSend(struct hv_device *dev, +static int rndis_filter_send(struct hv_device *dev, struct hv_netvsc_packet *pkt) { int ret; @@ -895,7 +895,7 @@ static int RndisFilterOnSend(struct hv_device *dev, pkt->Completion.Send.SendCompletionContext; /* Use ours */ - pkt->Completion.Send.OnSendCompletion = RndisFilterOnSendCompletion; + pkt->Completion.Send.OnSendCompletion = rndis_filter_send_completion; pkt->Completion.Send.SendCompletionContext = filterPacket; ret = rndis_filter.inner_drv.OnSend(dev, pkt); @@ -913,7 +913,7 @@ static int RndisFilterOnSend(struct hv_device *dev, return ret; } -static void RndisFilterOnSendCompletion(void *ctx) +static void rndis_filter_send_completion(void *ctx) { struct rndis_filter_packet *filterPacket = ctx; @@ -922,7 +922,7 @@ static void RndisFilterOnSendCompletion(void *ctx) } -static void RndisFilterOnSendRequestCompletion(void *ctx) +static void rndis_filter_send_request_completion(void *ctx) { /* Noop */ } diff --git a/drivers/staging/hv/rndis_filter.h b/drivers/staging/hv/rndis_filter.h index 764b9bf3e5dc..4da18f3cbade 100644 --- a/drivers/staging/hv/rndis_filter.h +++ b/drivers/staging/hv/rndis_filter.h @@ -50,6 +50,6 @@ /* Interface */ -extern int RndisFilterInit(struct netvsc_driver *driver); +extern int rndis_filter_init(struct netvsc_driver *driver); #endif /* _RNDISFILTER_H_ */ -- cgit v1.2.3 From 72a2f5bd53bf83302f4dcfe8500d4ec440545d27 Mon Sep 17 00:00:00 2001 From: Haiyang Zhang Date: Fri, 10 Dec 2010 12:03:58 -0800 Subject: staging: hv: Convert camel cased struct fields in netvsc_api.h to lower cases Signed-off-by: Haiyang Zhang Signed-off-by: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/netvsc.c | 104 +++++++++++++++++------------------ drivers/staging/hv/netvsc_api.h | 58 ++++++++++---------- drivers/staging/hv/netvsc_drv.c | 74 ++++++++++++------------- drivers/staging/hv/rndis_filter.c | 112 +++++++++++++++++++------------------- 4 files changed, 174 insertions(+), 174 deletions(-) diff --git a/drivers/staging/hv/netvsc.c b/drivers/staging/hv/netvsc.c index 5c327fc0d1fd..d678bf5329ef 100644 --- a/drivers/staging/hv/netvsc.c +++ b/drivers/staging/hv/netvsc.c @@ -196,11 +196,11 @@ int netvsc_initialize(struct hv_driver *drv) /* ASSERT(driver->OnLinkStatusChanged); */ /* Setup the dispatch table */ - driver->Base.OnDeviceAdd = netvsc_device_add; - driver->Base.OnDeviceRemove = netvsc_device_remove; - driver->Base.OnCleanup = netvsc_cleanup; + driver->base.OnDeviceAdd = netvsc_device_add; + driver->base.OnDeviceRemove = netvsc_device_remove; + driver->base.OnCleanup = netvsc_cleanup; - driver->OnSend = netvsc_send; + driver->send = netvsc_send; rndis_filter_init(driver); return 0; @@ -736,7 +736,7 @@ static int netvsc_device_add(struct hv_device *device, void *additional_info) NETVSC_RECEIVE_PACKETLIST_COUNT, i); break; } - list_add_tail(&packet->ListEntry, + list_add_tail(&packet->list_ent, &net_device->ReceivePacketList); } net_device->ChannelInitEvent = osd_waitevent_create(); @@ -746,8 +746,8 @@ static int netvsc_device_add(struct hv_device *device, void *additional_info) } /* Open the channel */ - ret = vmbus_open(device->channel, net_driver->RingBufferSize, - net_driver->RingBufferSize, NULL, 0, + ret = vmbus_open(device->channel, net_driver->ring_buf_size, + net_driver->ring_buf_size, NULL, 0, netvsc_channel_cb, device); if (ret != 0) { @@ -783,8 +783,8 @@ Cleanup: list_for_each_entry_safe(packet, pos, &net_device->ReceivePacketList, - ListEntry) { - list_del(&packet->ListEntry); + list_ent) { + list_del(&packet->list_ent); kfree(packet); } @@ -840,8 +840,8 @@ static int netvsc_device_remove(struct hv_device *device) /* Release all resources */ list_for_each_entry_safe(netvsc_packet, pos, - &net_device->ReceivePacketList, ListEntry) { - list_del(&netvsc_packet->ListEntry); + &net_device->ReceivePacketList, list_ent) { + list_del(&netvsc_packet->list_ent); kfree(netvsc_packet); } @@ -894,8 +894,8 @@ static void netvsc_send_completion(struct hv_device *device, /* ASSERT(nvscPacket); */ /* Notify the layer above us */ - nvsc_packet->Completion.Send.OnSendCompletion( - nvsc_packet->Completion.Send.SendCompletionContext); + nvsc_packet->completion.send.send_completion( + nvsc_packet->completion.send.send_completion_ctx); atomic_dec(&net_device->NumOutstandingSends); } else { @@ -922,7 +922,7 @@ static int netvsc_send(struct hv_device *device, } sendMessage.Header.MessageType = NvspMessage1TypeSendRNDISPacket; - if (packet->IsDataPacket) { + if (packet->is_data_pkt) { /* 0 is RMC_DATA; */ sendMessage.Messages.Version1Messages.SendRNDISPacket.ChannelType = 0; } else { @@ -934,10 +934,10 @@ static int netvsc_send(struct hv_device *device, sendMessage.Messages.Version1Messages.SendRNDISPacket.SendBufferSectionIndex = 0xFFFFFFFF; sendMessage.Messages.Version1Messages.SendRNDISPacket.SendBufferSectionSize = 0; - if (packet->PageBufferCount) { + if (packet->page_buf_cnt) { ret = vmbus_sendpacket_pagebuffer(device->channel, - packet->PageBuffers, - packet->PageBufferCount, + packet->page_buf, + packet->page_buf_cnt, &sendMessage, sizeof(struct nvsp_message), (unsigned long)packet); @@ -1063,82 +1063,82 @@ static void netvsc_receive(struct hv_device *device, /* Remove the 1st packet to represent the xfer page packet itself */ xferpage_packet = (struct xferpage_packet *)listHead.next; - list_del(&xferpage_packet->ListEntry); + list_del(&xferpage_packet->list_ent); /* This is how much we can satisfy */ - xferpage_packet->Count = count - 1; + xferpage_packet->count = count - 1; /* ASSERT(xferpagePacket->Count > 0 && xferpagePacket->Count <= */ /* vmxferpagePacket->RangeCount); */ - if (xferpage_packet->Count != vmxferpage_packet->RangeCount) { + if (xferpage_packet->count != vmxferpage_packet->RangeCount) { DPRINT_INFO(NETVSC, "Needed %d netvsc pkts to satisy this xfer " "page...got %d", vmxferpage_packet->RangeCount, - xferpage_packet->Count); + xferpage_packet->count); } /* Each range represents 1 RNDIS pkt that contains 1 ethernet frame */ for (i = 0; i < (count - 1); i++) { netvsc_packet = (struct hv_netvsc_packet *)listHead.next; - list_del(&netvsc_packet->ListEntry); + list_del(&netvsc_packet->list_ent); /* Initialize the netvsc packet */ - netvsc_packet->XferPagePacket = xferpage_packet; - netvsc_packet->Completion.Recv.OnReceiveCompletion = + netvsc_packet->xfer_page_pkt = xferpage_packet; + netvsc_packet->completion.recv.recv_completion = netvsc_receive_completion; - netvsc_packet->Completion.Recv.ReceiveCompletionContext = + netvsc_packet->completion.recv.recv_completion_ctx = netvsc_packet; - netvsc_packet->Device = device; + netvsc_packet->device = device; /* Save this so that we can send it back */ - netvsc_packet->Completion.Recv.ReceiveCompletionTid = + netvsc_packet->completion.recv.recv_completion_tid = vmxferpage_packet->d.TransactionId; - netvsc_packet->TotalDataBufferLength = + netvsc_packet->total_data_buflen = vmxferpage_packet->Ranges[i].ByteCount; - netvsc_packet->PageBufferCount = 1; + netvsc_packet->page_buf_cnt = 1; /* ASSERT(vmxferpagePacket->Ranges[i].ByteOffset + */ /* vmxferpagePacket->Ranges[i].ByteCount < */ /* netDevice->ReceiveBufferSize); */ - netvsc_packet->PageBuffers[0].Length = + netvsc_packet->page_buf[0].Length = vmxferpage_packet->Ranges[i].ByteCount; start = virt_to_phys((void *)((unsigned long)net_device-> ReceiveBuffer + vmxferpage_packet->Ranges[i].ByteOffset)); - netvsc_packet->PageBuffers[0].Pfn = start >> PAGE_SHIFT; + netvsc_packet->page_buf[0].Pfn = start >> PAGE_SHIFT; end_virtual = (unsigned long)net_device->ReceiveBuffer + vmxferpage_packet->Ranges[i].ByteOffset + vmxferpage_packet->Ranges[i].ByteCount - 1; end = virt_to_phys((void *)end_virtual); /* Calculate the page relative offset */ - netvsc_packet->PageBuffers[0].Offset = + netvsc_packet->page_buf[0].Offset = vmxferpage_packet->Ranges[i].ByteOffset & (PAGE_SIZE - 1); if ((end >> PAGE_SHIFT) != (start >> PAGE_SHIFT)) { /* Handle frame across multiple pages: */ - netvsc_packet->PageBuffers[0].Length = - (netvsc_packet->PageBuffers[0].Pfn << + netvsc_packet->page_buf[0].Length = + (netvsc_packet->page_buf[0].Pfn << PAGE_SHIFT) + PAGE_SIZE - start; - bytes_remain = netvsc_packet->TotalDataBufferLength - - netvsc_packet->PageBuffers[0].Length; + bytes_remain = netvsc_packet->total_data_buflen - + netvsc_packet->page_buf[0].Length; for (j = 1; j < NETVSC_PACKET_MAXPAGE; j++) { - netvsc_packet->PageBuffers[j].Offset = 0; + netvsc_packet->page_buf[j].Offset = 0; if (bytes_remain <= PAGE_SIZE) { - netvsc_packet->PageBuffers[j].Length = + netvsc_packet->page_buf[j].Length = bytes_remain; bytes_remain = 0; } else { - netvsc_packet->PageBuffers[j].Length = + netvsc_packet->page_buf[j].Length = PAGE_SIZE; bytes_remain -= PAGE_SIZE; } - netvsc_packet->PageBuffers[j].Pfn = + netvsc_packet->page_buf[j].Pfn = virt_to_phys((void *)(end_virtual - bytes_remain)) >> PAGE_SHIFT; - netvsc_packet->PageBufferCount++; + netvsc_packet->page_buf_cnt++; if (bytes_remain == 0) break; } @@ -1148,16 +1148,16 @@ static void netvsc_receive(struct hv_device *device, "(pfn %llx, offset %u, len %u)", i, vmxferpage_packet->Ranges[i].ByteOffset, vmxferpage_packet->Ranges[i].ByteCount, - netvsc_packet->PageBuffers[0].Pfn, - netvsc_packet->PageBuffers[0].Offset, - netvsc_packet->PageBuffers[0].Length); + netvsc_packet->page_buf[0].Pfn, + netvsc_packet->page_buf[0].Offset, + netvsc_packet->page_buf[0].Length); /* Pass it to the upper layer */ ((struct netvsc_driver *)device->Driver)-> - OnReceiveCallback(device, netvsc_packet); + recv_cb(device, netvsc_packet); netvsc_receive_completion(netvsc_packet-> - Completion.Recv.ReceiveCompletionContext); + completion.recv.recv_completion_ctx); } /* ASSERT(list_empty(&listHead)); */ @@ -1213,7 +1213,7 @@ retry_send_cmplt: static void netvsc_receive_completion(void *context) { struct hv_netvsc_packet *packet = context; - struct hv_device *device = (struct hv_device *)packet->Device; + struct hv_device *device = (struct hv_device *)packet->device; struct netvsc_device *net_device; u64 transaction_id = 0; bool fsend_receive_comp = false; @@ -1237,22 +1237,22 @@ static void netvsc_receive_completion(void *context) spin_lock_irqsave(&net_device->receive_packet_list_lock, flags); /* ASSERT(packet->XferPagePacket->Count > 0); */ - packet->XferPagePacket->Count--; + packet->xfer_page_pkt->count--; /* * Last one in the line that represent 1 xfer page packet. * Return the xfer page packet itself to the freelist */ - if (packet->XferPagePacket->Count == 0) { + if (packet->xfer_page_pkt->count == 0) { fsend_receive_comp = true; - transaction_id = packet->Completion.Recv.ReceiveCompletionTid; - list_add_tail(&packet->XferPagePacket->ListEntry, + transaction_id = packet->completion.recv.recv_completion_tid; + list_add_tail(&packet->xfer_page_pkt->list_ent, &net_device->ReceivePacketList); } /* Put the packet back */ - list_add_tail(&packet->ListEntry, &net_device->ReceivePacketList); + list_add_tail(&packet->list_ent, &net_device->ReceivePacketList); spin_unlock_irqrestore(&net_device->receive_packet_list_lock, flags); /* Send a receive completion for the xfer page packet */ diff --git a/drivers/staging/hv/netvsc_api.h b/drivers/staging/hv/netvsc_api.h index 315271d69914..ac40db56e1fa 100644 --- a/drivers/staging/hv/netvsc_api.h +++ b/drivers/staging/hv/netvsc_api.h @@ -32,10 +32,10 @@ struct hv_netvsc_packet; /* Represent the xfer page packet which contains 1 or more netvsc packet */ struct xferpage_packet { - struct list_head ListEntry; + struct list_head list_ent; /* # of netvsc packets this xfer packet contains */ - u32 Count; + u32 count; }; /* The number of pages which are enough to cover jumbo frame buffer. */ @@ -47,65 +47,65 @@ struct xferpage_packet { */ struct hv_netvsc_packet { /* Bookkeeping stuff */ - struct list_head ListEntry; + struct list_head list_ent; - struct hv_device *Device; - bool IsDataPacket; + struct hv_device *device; + bool is_data_pkt; /* * Valid only for receives when we break a xfer page packet * into multiple netvsc packets */ - struct xferpage_packet *XferPagePacket; + struct xferpage_packet *xfer_page_pkt; union { struct{ - u64 ReceiveCompletionTid; - void *ReceiveCompletionContext; - void (*OnReceiveCompletion)(void *context); - } Recv; + u64 recv_completion_tid; + void *recv_completion_ctx; + void (*recv_completion)(void *context); + } recv; struct{ - u64 SendCompletionTid; - void *SendCompletionContext; - void (*OnSendCompletion)(void *context); - } Send; - } Completion; + u64 send_completion_tid; + void *send_completion_ctx; + void (*send_completion)(void *context); + } send; + } completion; - /* This points to the memory after PageBuffers */ - void *Extension; + /* This points to the memory after page_buf */ + void *extension; - u32 TotalDataBufferLength; + u32 total_data_buflen; /* Points to the send/receive buffer where the ethernet frame is */ - u32 PageBufferCount; - struct hv_page_buffer PageBuffers[NETVSC_PACKET_MAXPAGE]; + u32 page_buf_cnt; + struct hv_page_buffer page_buf[NETVSC_PACKET_MAXPAGE]; }; /* Represents the net vsc driver */ struct netvsc_driver { /* Must be the first field */ /* Which is a bug FIXME! */ - struct hv_driver Base; + struct hv_driver base; - u32 RingBufferSize; - u32 RequestExtSize; + u32 ring_buf_size; + u32 req_ext_size; /* * This is set by the caller to allow us to callback when we * receive a packet from the "wire" */ - int (*OnReceiveCallback)(struct hv_device *dev, + int (*recv_cb)(struct hv_device *dev, struct hv_netvsc_packet *packet); - void (*OnLinkStatusChanged)(struct hv_device *dev, u32 Status); + void (*link_status_change)(struct hv_device *dev, u32 Status); /* Specific to this driver */ - int (*OnSend)(struct hv_device *dev, struct hv_netvsc_packet *packet); + int (*send)(struct hv_device *dev, struct hv_netvsc_packet *packet); - void *Context; + void *ctx; }; struct netvsc_device_info { - unsigned char MacAddr[6]; - bool LinkState; /* 0 - link up, 1 - link down */ + unsigned char mac_adr[6]; + bool link_state; /* 0 - link up, 1 - link down */ }; /* Interface */ diff --git a/drivers/staging/hv/netvsc_drv.c b/drivers/staging/hv/netvsc_drv.c index e47681e7be82..0147b407512c 100644 --- a/drivers/staging/hv/netvsc_drv.c +++ b/drivers/staging/hv/netvsc_drv.c @@ -115,7 +115,7 @@ static void netvsc_xmit_completion(void *context) { struct hv_netvsc_packet *packet = (struct hv_netvsc_packet *)context; struct sk_buff *skb = (struct sk_buff *) - (unsigned long)packet->Completion.Send.SendCompletionTid; + (unsigned long)packet->completion.send.send_completion_tid; kfree(packet); @@ -154,7 +154,7 @@ static int netvsc_start_xmit(struct sk_buff *skb, struct net_device *net) /* Allocate a netvsc packet based on # of frags. */ packet = kzalloc(sizeof(struct hv_netvsc_packet) + (num_pages * sizeof(struct hv_page_buffer)) + - net_drv_obj->RequestExtSize, GFP_ATOMIC); + net_drv_obj->req_ext_size, GFP_ATOMIC); if (!packet) { /* out of memory, silently drop packet */ DPRINT_ERR(NETVSC_DRV, "unable to allocate hv_netvsc_packet"); @@ -164,40 +164,40 @@ static int netvsc_start_xmit(struct sk_buff *skb, struct net_device *net) return NETDEV_TX_OK; } - packet->Extension = (void *)(unsigned long)packet + + packet->extension = (void *)(unsigned long)packet + sizeof(struct hv_netvsc_packet) + (num_pages * sizeof(struct hv_page_buffer)); /* Setup the rndis header */ - packet->PageBufferCount = num_pages; + packet->page_buf_cnt = num_pages; /* TODO: Flush all write buffers/ memory fence ??? */ /* wmb(); */ /* Initialize it from the skb */ - packet->TotalDataBufferLength = skb->len; + packet->total_data_buflen = skb->len; /* Start filling in the page buffers starting after RNDIS buffer. */ - packet->PageBuffers[1].Pfn = virt_to_phys(skb->data) >> PAGE_SHIFT; - packet->PageBuffers[1].Offset + packet->page_buf[1].Pfn = virt_to_phys(skb->data) >> PAGE_SHIFT; + packet->page_buf[1].Offset = (unsigned long)skb->data & (PAGE_SIZE - 1); - packet->PageBuffers[1].Length = skb_headlen(skb); + packet->page_buf[1].Length = skb_headlen(skb); /* Additional fragments are after SKB data */ for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { skb_frag_t *f = &skb_shinfo(skb)->frags[i]; - packet->PageBuffers[i+2].Pfn = page_to_pfn(f->page); - packet->PageBuffers[i+2].Offset = f->page_offset; - packet->PageBuffers[i+2].Length = f->size; + packet->page_buf[i+2].Pfn = page_to_pfn(f->page); + packet->page_buf[i+2].Offset = f->page_offset; + packet->page_buf[i+2].Length = f->size; } /* Set the completion routine */ - packet->Completion.Send.OnSendCompletion = netvsc_xmit_completion; - packet->Completion.Send.SendCompletionContext = packet; - packet->Completion.Send.SendCompletionTid = (unsigned long)skb; + packet->completion.send.send_completion = netvsc_xmit_completion; + packet->completion.send.send_completion_ctx = packet; + packet->completion.send.send_completion_tid = (unsigned long)skb; - ret = net_drv_obj->OnSend(&net_device_ctx->device_ctx->device_obj, + ret = net_drv_obj->send(&net_device_ctx->device_ctx->device_obj, packet); if (ret == 0) { net->stats.tx_bytes += skb->len; @@ -263,7 +263,7 @@ static int netvsc_recv_callback(struct hv_device *device_obj, } /* Allocate a skb - TODO direct I/O to pages? */ - skb = netdev_alloc_skb_ip_align(net, packet->TotalDataBufferLength); + skb = netdev_alloc_skb_ip_align(net, packet->total_data_buflen); if (unlikely(!skb)) { ++net->stats.rx_dropped; return 0; @@ -276,17 +276,17 @@ static int netvsc_recv_callback(struct hv_device *device_obj, * Copy to skb. This copy is needed here since the memory pointed by * hv_netvsc_packet cannot be deallocated */ - for (i = 0; i < packet->PageBufferCount; i++) { - data = kmap_atomic(pfn_to_page(packet->PageBuffers[i].Pfn), + for (i = 0; i < packet->page_buf_cnt; i++) { + data = kmap_atomic(pfn_to_page(packet->page_buf[i].Pfn), KM_IRQ1); data = (void *)(unsigned long)data + - packet->PageBuffers[i].Offset; + packet->page_buf[i].Offset; - memcpy(skb_put(skb, packet->PageBuffers[i].Length), data, - packet->PageBuffers[i].Length); + memcpy(skb_put(skb, packet->page_buf[i].Length), data, + packet->page_buf[i].Length); kunmap_atomic((void *)((unsigned long)data - - packet->PageBuffers[i].Offset), KM_IRQ1); + packet->page_buf[i].Offset), KM_IRQ1); } local_irq_restore(flags); @@ -349,7 +349,7 @@ static int netvsc_probe(struct device *device) struct netvsc_device_info device_info; int ret; - if (!net_drv_obj->Base.OnDeviceAdd) + if (!net_drv_obj->base.OnDeviceAdd) return -1; net = alloc_etherdev(sizeof(struct net_device_context)); @@ -366,7 +366,7 @@ static int netvsc_probe(struct device *device) dev_set_drvdata(device, net); /* Notify the netvsc driver of the new device */ - ret = net_drv_obj->Base.OnDeviceAdd(device_obj, &device_info); + ret = net_drv_obj->base.OnDeviceAdd(device_obj, &device_info); if (ret != 0) { free_netdev(net); dev_set_drvdata(device, NULL); @@ -385,10 +385,10 @@ static int netvsc_probe(struct device *device) * out of sync with the device's link status */ if (!netif_carrier_ok(net)) - if (!device_info.LinkState) + if (!device_info.link_state) netif_carrier_on(net); - memcpy(net->dev_addr, device_info.MacAddr, ETH_ALEN); + memcpy(net->dev_addr, device_info.mac_adr, ETH_ALEN); net->netdev_ops = &device_ops; @@ -401,7 +401,7 @@ static int netvsc_probe(struct device *device) ret = register_netdev(net); if (ret != 0) { /* Remove the device and release the resource */ - net_drv_obj->Base.OnDeviceRemove(device_obj); + net_drv_obj->base.OnDeviceRemove(device_obj); free_netdev(net); } @@ -425,7 +425,7 @@ static int netvsc_remove(struct device *device) return 0; } - if (!net_drv_obj->Base.OnDeviceRemove) + if (!net_drv_obj->base.OnDeviceRemove) return -1; /* Stop outbound asap */ @@ -438,7 +438,7 @@ static int netvsc_remove(struct device *device) * Call to the vsc driver to let it know that the device is being * removed */ - ret = net_drv_obj->Base.OnDeviceRemove(device_obj); + ret = net_drv_obj->base.OnDeviceRemove(device_obj); if (ret != 0) { /* TODO: */ DPRINT_ERR(NETVSC, "unable to remove vsc device (ret %d)", ret); @@ -484,8 +484,8 @@ static void netvsc_drv_exit(void) device_unregister(current_dev); } - if (netvsc_drv_obj->Base.OnCleanup) - netvsc_drv_obj->Base.OnCleanup(&netvsc_drv_obj->Base); + if (netvsc_drv_obj->base.OnCleanup) + netvsc_drv_obj->base.OnCleanup(&netvsc_drv_obj->base); vmbus_child_driver_unregister(drv_ctx); @@ -498,15 +498,15 @@ static int netvsc_drv_init(int (*drv_init)(struct hv_driver *drv)) struct driver_context *drv_ctx = &g_netvsc_drv.drv_ctx; int ret; - net_drv_obj->RingBufferSize = ring_size * PAGE_SIZE; - net_drv_obj->OnReceiveCallback = netvsc_recv_callback; - net_drv_obj->OnLinkStatusChanged = netvsc_linkstatus_callback; + net_drv_obj->ring_buf_size = ring_size * PAGE_SIZE; + net_drv_obj->recv_cb = netvsc_recv_callback; + net_drv_obj->link_status_change = netvsc_linkstatus_callback; /* Callback to client driver to complete the initialization */ - drv_init(&net_drv_obj->Base); + drv_init(&net_drv_obj->base); - drv_ctx->driver.name = net_drv_obj->Base.name; - memcpy(&drv_ctx->class_id, &net_drv_obj->Base.deviceType, + drv_ctx->driver.name = net_drv_obj->base.name; + memcpy(&drv_ctx->class_id, &net_drv_obj->base.deviceType, sizeof(struct hv_guid)); drv_ctx->probe = netvsc_probe; diff --git a/drivers/staging/hv/rndis_filter.c b/drivers/staging/hv/rndis_filter.c index e560f380adb5..dffcc0397917 100644 --- a/drivers/staging/hv/rndis_filter.c +++ b/drivers/staging/hv/rndis_filter.c @@ -251,22 +251,22 @@ static int rndis_filter_send_request(struct rndis_device *dev, /* Setup the packet to send it */ packet = &req->pkt; - packet->IsDataPacket = false; - packet->TotalDataBufferLength = req->request_msg.MessageLength; - packet->PageBufferCount = 1; + packet->is_data_pkt = false; + packet->total_data_buflen = req->request_msg.MessageLength; + packet->page_buf_cnt = 1; - packet->PageBuffers[0].Pfn = virt_to_phys(&req->request_msg) >> + packet->page_buf[0].Pfn = virt_to_phys(&req->request_msg) >> PAGE_SHIFT; - packet->PageBuffers[0].Length = req->request_msg.MessageLength; - packet->PageBuffers[0].Offset = + packet->page_buf[0].Length = req->request_msg.MessageLength; + packet->page_buf[0].Offset = (unsigned long)&req->request_msg & (PAGE_SIZE - 1); - packet->Completion.Send.SendCompletionContext = req;/* packet; */ - packet->Completion.Send.OnSendCompletion = + packet->completion.send.send_completion_ctx = req;/* packet; */ + packet->completion.send.send_completion = rndis_filter_send_request_completion; - packet->Completion.Send.SendCompletionTid = (unsigned long)dev; + packet->completion.send.send_completion_tid = (unsigned long)dev; - ret = rndis_filter.inner_drv.OnSend(dev->net_dev->Device, packet); + ret = rndis_filter.inner_drv.send(dev->net_dev->Device, packet); return ret; } @@ -337,10 +337,10 @@ static void rndis_filter_receive_indicate_status(struct rndis_device *dev, &resp->Message.IndicateStatus; if (indicate->Status == RNDIS_STATUS_MEDIA_CONNECT) { - rndis_filter.inner_drv.OnLinkStatusChanged( + rndis_filter.inner_drv.link_status_change( dev->net_dev->Device, 1); } else if (indicate->Status == RNDIS_STATUS_MEDIA_DISCONNECT) { - rndis_filter.inner_drv.OnLinkStatusChanged( + rndis_filter.inner_drv.link_status_change( dev->net_dev->Device, 0); } else { /* @@ -370,13 +370,13 @@ static void rndis_filter_receive_data(struct rndis_device *dev, /* Remove the rndis header and pass it back up the stack */ data_offset = RNDIS_HEADER_SIZE + rndis_pkt->DataOffset; - pkt->TotalDataBufferLength -= data_offset; - pkt->PageBuffers[0].Offset += data_offset; - pkt->PageBuffers[0].Length -= data_offset; + pkt->total_data_buflen -= data_offset; + pkt->page_buf[0].Offset += data_offset; + pkt->page_buf[0].Length -= data_offset; - pkt->IsDataPacket = true; + pkt->is_data_pkt = true; - rndis_filter.inner_drv.OnReceiveCallback(dev->net_dev->Device, + rndis_filter.inner_drv.recv_cb(dev->net_dev->Device, pkt); } @@ -406,10 +406,10 @@ static int rndis_filter_receive(struct hv_device *dev, } rndis_hdr = (struct rndis_message *)kmap_atomic( - pfn_to_page(pkt->PageBuffers[0].Pfn), KM_IRQ0); + pfn_to_page(pkt->page_buf[0].Pfn), KM_IRQ0); rndis_hdr = (void *)((unsigned long)rndis_hdr + - pkt->PageBuffers[0].Offset); + pkt->page_buf[0].Offset); /* Make sure we got a valid rndis message */ /* @@ -418,14 +418,14 @@ static int rndis_filter_receive(struct hv_device *dev, * range shows 52 bytes * */ #if 0 - if (pkt->TotalDataBufferLength != rndis_hdr->MessageLength) { - kunmap_atomic(rndis_hdr - pkt->PageBuffers[0].Offset, + if (pkt->total_data_buflen != rndis_hdr->MessageLength) { + kunmap_atomic(rndis_hdr - pkt->page_buf[0].Offset, KM_IRQ0); DPRINT_ERR(NETVSC, "invalid rndis message? (expected %u " "bytes got %u)...dropping this message!", rndis_hdr->MessageLength, - pkt->TotalDataBufferLength); + pkt->total_data_buflen); return -1; } #endif @@ -443,7 +443,7 @@ static int rndis_filter_receive(struct hv_device *dev, sizeof(struct rndis_message) : rndis_hdr->MessageLength); - kunmap_atomic(rndis_hdr - pkt->PageBuffers[0].Offset, KM_IRQ0); + kunmap_atomic(rndis_hdr - pkt->page_buf[0].Offset, KM_IRQ0); dump_rndis_message(&rndis_msg); @@ -610,7 +610,7 @@ int rndis_filter_init(struct netvsc_driver *drv) DPRINT_DBG(NETVSC, "sizeof(struct rndis_filter_packet) == %zd", sizeof(struct rndis_filter_packet)); - drv->RequestExtSize = sizeof(struct rndis_filter_packet); + drv->req_ext_size = sizeof(struct rndis_filter_packet); /* Driver->Context = rndisDriver; */ @@ -622,25 +622,25 @@ int rndis_filter_init(struct netvsc_driver *drv) rndisDriver->OnLinkStatusChanged = Driver->OnLinkStatusChanged;*/ /* Save the original dispatch handlers before we override it */ - rndis_filter.inner_drv.Base.OnDeviceAdd = drv->Base.OnDeviceAdd; - rndis_filter.inner_drv.Base.OnDeviceRemove = - drv->Base.OnDeviceRemove; - rndis_filter.inner_drv.Base.OnCleanup = drv->Base.OnCleanup; + rndis_filter.inner_drv.base.OnDeviceAdd = drv->base.OnDeviceAdd; + rndis_filter.inner_drv.base.OnDeviceRemove = + drv->base.OnDeviceRemove; + rndis_filter.inner_drv.base.OnCleanup = drv->base.OnCleanup; /* ASSERT(Driver->OnSend); */ /* ASSERT(Driver->OnReceiveCallback); */ - rndis_filter.inner_drv.OnSend = drv->OnSend; - rndis_filter.inner_drv.OnReceiveCallback = drv->OnReceiveCallback; - rndis_filter.inner_drv.OnLinkStatusChanged = - drv->OnLinkStatusChanged; + rndis_filter.inner_drv.send = drv->send; + rndis_filter.inner_drv.recv_cb = drv->recv_cb; + rndis_filter.inner_drv.link_status_change = + drv->link_status_change; /* Override */ - drv->Base.OnDeviceAdd = rndis_filte_device_add; - drv->Base.OnDeviceRemove = rndis_filter_device_remove; - drv->Base.OnCleanup = rndis_filter_cleanup; - drv->OnSend = rndis_filter_send; + drv->base.OnDeviceAdd = rndis_filte_device_add; + drv->base.OnDeviceRemove = rndis_filter_device_remove; + drv->base.OnCleanup = rndis_filter_cleanup; + drv->send = rndis_filter_send; /* Driver->QueryLinkStatus = RndisFilterQueryDeviceLinkStatus; */ - drv->OnReceiveCallback = rndis_filter_receive; + drv->recv_cb = rndis_filter_receive; return 0; } @@ -770,7 +770,7 @@ static int rndis_filte_device_add(struct hv_device *dev, * NOTE! Once the channel is created, we may get a receive callback * (RndisFilterOnReceive()) before this call is completed */ - ret = rndis_filter.inner_drv.Base.OnDeviceAdd(dev, additional_info); + ret = rndis_filter.inner_drv.base.OnDeviceAdd(dev, additional_info); if (ret != 0) { kfree(rndisDevice); return ret; @@ -805,13 +805,13 @@ static int rndis_filte_device_add(struct hv_device *dev, DPRINT_INFO(NETVSC, "Device 0x%p mac addr %pM", rndisDevice, rndisDevice->hw_mac_adr); - memcpy(deviceInfo->MacAddr, rndisDevice->hw_mac_adr, ETH_ALEN); + memcpy(deviceInfo->mac_adr, rndisDevice->hw_mac_adr, ETH_ALEN); rndis_filter_query_device_link_status(rndisDevice); - deviceInfo->LinkState = rndisDevice->link_stat; + deviceInfo->link_state = rndisDevice->link_stat; DPRINT_INFO(NETVSC, "Device 0x%p link state %s", rndisDevice, - ((deviceInfo->LinkState) ? ("down") : ("up"))); + ((deviceInfo->link_state) ? ("down") : ("up"))); return ret; } @@ -828,7 +828,7 @@ static int rndis_filter_device_remove(struct hv_device *dev) net_dev->Extension = NULL; /* Pass control to inner driver to remove the device */ - rndis_filter.inner_drv.Base.OnDeviceRemove(dev); + rndis_filter.inner_drv.base.OnDeviceRemove(dev); return 0; } @@ -867,7 +867,7 @@ static int rndis_filter_send(struct hv_device *dev, u32 rndisMessageSize; /* Add the rndis header */ - filterPacket = (struct rndis_filter_packet *)pkt->Extension; + filterPacket = (struct rndis_filter_packet *)pkt->extension; /* ASSERT(filterPacket); */ memset(filterPacket, 0, sizeof(struct rndis_filter_packet)); @@ -876,37 +876,37 @@ static int rndis_filter_send(struct hv_device *dev, rndisMessageSize = RNDIS_MESSAGE_SIZE(struct rndis_packet); rndisMessage->NdisMessageType = REMOTE_NDIS_PACKET_MSG; - rndisMessage->MessageLength = pkt->TotalDataBufferLength + + rndisMessage->MessageLength = pkt->total_data_buflen + rndisMessageSize; rndisPacket = &rndisMessage->Message.Packet; rndisPacket->DataOffset = sizeof(struct rndis_packet); - rndisPacket->DataLength = pkt->TotalDataBufferLength; + rndisPacket->DataLength = pkt->total_data_buflen; - pkt->IsDataPacket = true; - pkt->PageBuffers[0].Pfn = virt_to_phys(rndisMessage) >> PAGE_SHIFT; - pkt->PageBuffers[0].Offset = + pkt->is_data_pkt = true; + pkt->page_buf[0].Pfn = virt_to_phys(rndisMessage) >> PAGE_SHIFT; + pkt->page_buf[0].Offset = (unsigned long)rndisMessage & (PAGE_SIZE-1); - pkt->PageBuffers[0].Length = rndisMessageSize; + pkt->page_buf[0].Length = rndisMessageSize; /* Save the packet send completion and context */ - filterPacket->completion = pkt->Completion.Send.OnSendCompletion; + filterPacket->completion = pkt->completion.send.send_completion; filterPacket->completion_ctx = - pkt->Completion.Send.SendCompletionContext; + pkt->completion.send.send_completion_ctx; /* Use ours */ - pkt->Completion.Send.OnSendCompletion = rndis_filter_send_completion; - pkt->Completion.Send.SendCompletionContext = filterPacket; + pkt->completion.send.send_completion = rndis_filter_send_completion; + pkt->completion.send.send_completion_ctx = filterPacket; - ret = rndis_filter.inner_drv.OnSend(dev, pkt); + ret = rndis_filter.inner_drv.send(dev, pkt); if (ret != 0) { /* * Reset the completion to originals to allow retries from * above */ - pkt->Completion.Send.OnSendCompletion = + pkt->completion.send.send_completion = filterPacket->completion; - pkt->Completion.Send.SendCompletionContext = + pkt->completion.send.send_completion_ctx = filterPacket->completion_ctx; } -- cgit v1.2.3 From 53d21fdbf4d38dcfe27173d746acf74ea1a19958 Mon Sep 17 00:00:00 2001 From: Haiyang Zhang Date: Fri, 10 Dec 2010 12:03:59 -0800 Subject: staging: hv: Convert camel cased struct fields in netvsc.h to lower cases Signed-off-by: Haiyang Zhang Signed-off-by: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/netvsc.c | 340 +++++++++++++++++++------------------- drivers/staging/hv/netvsc.h | 164 +++++++++--------- drivers/staging/hv/netvsc_api.h | 2 +- drivers/staging/hv/rndis_filter.c | 22 +-- 4 files changed, 265 insertions(+), 263 deletions(-) diff --git a/drivers/staging/hv/netvsc.c b/drivers/staging/hv/netvsc.c index d678bf5329ef..df9cd131e953 100644 --- a/drivers/staging/hv/netvsc.c +++ b/drivers/staging/hv/netvsc.c @@ -83,9 +83,9 @@ static struct netvsc_device *alloc_net_device(struct hv_device *device) return NULL; /* Set to 2 to allow both inbound and outbound traffic */ - atomic_cmpxchg(&net_device->RefCount, 0, 2); + atomic_cmpxchg(&net_device->refcnt, 0, 2); - net_device->Device = device; + net_device->dev = device; device->Extension = net_device; return net_device; @@ -93,8 +93,8 @@ static struct netvsc_device *alloc_net_device(struct hv_device *device) static void free_net_device(struct netvsc_device *device) { - WARN_ON(atomic_read(&device->RefCount) == 0); - device->Device->Extension = NULL; + WARN_ON(atomic_read(&device->refcnt) == 0); + device->dev->Extension = NULL; kfree(device); } @@ -105,8 +105,8 @@ static struct netvsc_device *get_outbound_net_device(struct hv_device *device) struct netvsc_device *net_device; net_device = device->Extension; - if (net_device && atomic_read(&net_device->RefCount) > 1) - atomic_inc(&net_device->RefCount); + if (net_device && atomic_read(&net_device->refcnt) > 1) + atomic_inc(&net_device->refcnt); else net_device = NULL; @@ -119,8 +119,8 @@ static struct netvsc_device *get_inbound_net_device(struct hv_device *device) struct netvsc_device *net_device; net_device = device->Extension; - if (net_device && atomic_read(&net_device->RefCount)) - atomic_inc(&net_device->RefCount); + if (net_device && atomic_read(&net_device->refcnt)) + atomic_inc(&net_device->refcnt); else net_device = NULL; @@ -134,7 +134,7 @@ static void put_net_device(struct hv_device *device) net_device = device->Extension; /* ASSERT(netDevice); */ - atomic_dec(&net_device->RefCount); + atomic_dec(&net_device->refcnt); } static struct netvsc_device *release_outbound_net_device( @@ -147,7 +147,7 @@ static struct netvsc_device *release_outbound_net_device( return NULL; /* Busy wait until the ref drop to 2, then set it to 1 */ - while (atomic_cmpxchg(&net_device->RefCount, 2, 1) != 2) + while (atomic_cmpxchg(&net_device->refcnt, 2, 1) != 2) udelay(100); return net_device; @@ -163,7 +163,7 @@ static struct netvsc_device *release_inbound_net_device( return NULL; /* Busy wait until the ref drop to 1, then set it to 0 */ - while (atomic_cmpxchg(&net_device->RefCount, 1, 0) != 1) + while (atomic_cmpxchg(&net_device->refcnt, 1, 0) != 1) udelay(100); device->Extension = NULL; @@ -222,12 +222,12 @@ static int netvsc_init_recv_buf(struct hv_device *device) /* page-size grandularity */ /* ASSERT((netDevice->ReceiveBufferSize & (PAGE_SIZE - 1)) == 0); */ - net_device->ReceiveBuffer = - osd_page_alloc(net_device->ReceiveBufferSize >> PAGE_SHIFT); - if (!net_device->ReceiveBuffer) { + net_device->recv_buf = + osd_page_alloc(net_device->recv_buf_size >> PAGE_SHIFT); + if (!net_device->recv_buf) { DPRINT_ERR(NETVSC, "unable to allocate receive buffer of size %d", - net_device->ReceiveBufferSize); + net_device->recv_buf_size); ret = -1; goto Cleanup; } @@ -242,9 +242,9 @@ static int netvsc_init_recv_buf(struct hv_device *device) * channel. Note: This call uses the vmbus connection rather * than the channel to establish the gpadl handle. */ - ret = vmbus_establish_gpadl(device->channel, net_device->ReceiveBuffer, - net_device->ReceiveBufferSize, - &net_device->ReceiveBufferGpadlHandle); + ret = vmbus_establish_gpadl(device->channel, net_device->recv_buf, + net_device->recv_buf_size, + &net_device->recv_buf_gpadl_handle); if (ret != 0) { DPRINT_ERR(NETVSC, "unable to establish receive buffer's gpadl"); @@ -256,15 +256,15 @@ static int netvsc_init_recv_buf(struct hv_device *device) /* Notify the NetVsp of the gpadl handle */ DPRINT_INFO(NETVSC, "Sending NvspMessage1TypeSendReceiveBuffer..."); - init_packet = &net_device->ChannelInitPacket; + init_packet = &net_device->channel_init_pkt; memset(init_packet, 0, sizeof(struct nvsp_message)); - init_packet->Header.MessageType = NvspMessage1TypeSendReceiveBuffer; - init_packet->Messages.Version1Messages.SendReceiveBuffer. - GpadlHandle = net_device->ReceiveBufferGpadlHandle; - init_packet->Messages.Version1Messages. - SendReceiveBuffer.Id = NETVSC_RECEIVE_BUFFER_ID; + init_packet->hdr.msg_type = NVSP_MSG1_TYPE_SEND_RECV_BUF; + init_packet->msg.v1_msg.send_recv_buf. + gpadl_handle = net_device->recv_buf_gpadl_handle; + init_packet->msg.v1_msg. + send_recv_buf.id = NETVSC_RECEIVE_BUFFER_ID; /* Send the gpadl notification request */ ret = vmbus_sendpacket(device->channel, init_packet, @@ -278,15 +278,15 @@ static int netvsc_init_recv_buf(struct hv_device *device) goto Cleanup; } - osd_waitevent_wait(net_device->ChannelInitEvent); + osd_waitevent_wait(net_device->channel_init_event); /* Check the response */ - if (init_packet->Messages.Version1Messages. - SendReceiveBufferComplete.Status != NvspStatusSuccess) { + if (init_packet->msg.v1_msg. + send_recv_buf_complete.status != NVSP_STAT_SUCCESS) { DPRINT_ERR(NETVSC, "Unable to complete receive buffer " "initialzation with NetVsp - status %d", - init_packet->Messages.Version1Messages. - SendReceiveBufferComplete.Status); + init_packet->msg.v1_msg. + send_recv_buf_complete.status); ret = -1; goto Cleanup; } @@ -295,36 +295,36 @@ static int netvsc_init_recv_buf(struct hv_device *device) /* ASSERT(netDevice->ReceiveSectionCount == 0); */ /* ASSERT(netDevice->ReceiveSections == NULL); */ - net_device->ReceiveSectionCount = init_packet->Messages. - Version1Messages.SendReceiveBufferComplete.NumSections; + net_device->recv_section_cnt = init_packet->msg. + v1_msg.send_recv_buf_complete.num_sections; - net_device->ReceiveSections = kmalloc(net_device->ReceiveSectionCount + net_device->recv_section = kmalloc(net_device->recv_section_cnt * sizeof(struct nvsp_1_receive_buffer_section), GFP_KERNEL); - if (net_device->ReceiveSections == NULL) { + if (net_device->recv_section == NULL) { ret = -1; goto Cleanup; } - memcpy(net_device->ReceiveSections, - init_packet->Messages.Version1Messages. - SendReceiveBufferComplete.Sections, - net_device->ReceiveSectionCount * + memcpy(net_device->recv_section, + init_packet->msg.v1_msg. + send_recv_buf_complete.sections, + net_device->recv_section_cnt * sizeof(struct nvsp_1_receive_buffer_section)); DPRINT_INFO(NETVSC, "Receive sections info (count %d, offset %d, " "endoffset %d, suballoc size %d, num suballocs %d)", - net_device->ReceiveSectionCount, - net_device->ReceiveSections[0].Offset, - net_device->ReceiveSections[0].EndOffset, - net_device->ReceiveSections[0].SubAllocationSize, - net_device->ReceiveSections[0].NumSubAllocations); + net_device->recv_section_cnt, + net_device->recv_section[0].offset, + net_device->recv_section[0].end_offset, + net_device->recv_section[0].sub_alloc_size, + net_device->recv_section[0].num_sub_allocs); /* * For 1st release, there should only be 1 section that represents the * entire receive buffer */ - if (net_device->ReceiveSectionCount != 1 || - net_device->ReceiveSections->Offset != 0) { + if (net_device->recv_section_cnt != 1 || + net_device->recv_section->offset != 0) { ret = -1; goto Cleanup; } @@ -351,7 +351,7 @@ static int netvsc_init_send_buf(struct hv_device *device) "device being destroyed?"); return -1; } - if (net_device->SendBufferSize <= 0) { + if (net_device->send_buf_size <= 0) { ret = -EINVAL; goto Cleanup; } @@ -359,11 +359,11 @@ static int netvsc_init_send_buf(struct hv_device *device) /* page-size grandularity */ /* ASSERT((netDevice->SendBufferSize & (PAGE_SIZE - 1)) == 0); */ - net_device->SendBuffer = - osd_page_alloc(net_device->SendBufferSize >> PAGE_SHIFT); - if (!net_device->SendBuffer) { + net_device->send_buf = + osd_page_alloc(net_device->send_buf_size >> PAGE_SHIFT); + if (!net_device->send_buf) { DPRINT_ERR(NETVSC, "unable to allocate send buffer of size %d", - net_device->SendBufferSize); + net_device->send_buf_size); ret = -1; goto Cleanup; } @@ -377,9 +377,9 @@ static int netvsc_init_send_buf(struct hv_device *device) * channel. Note: This call uses the vmbus connection rather * than the channel to establish the gpadl handle. */ - ret = vmbus_establish_gpadl(device->channel, net_device->SendBuffer, - net_device->SendBufferSize, - &net_device->SendBufferGpadlHandle); + ret = vmbus_establish_gpadl(device->channel, net_device->send_buf, + net_device->send_buf_size, + &net_device->send_buf_gpadl_handle); if (ret != 0) { DPRINT_ERR(NETVSC, "unable to establish send buffer's gpadl"); goto Cleanup; @@ -390,14 +390,14 @@ static int netvsc_init_send_buf(struct hv_device *device) /* Notify the NetVsp of the gpadl handle */ DPRINT_INFO(NETVSC, "Sending NvspMessage1TypeSendSendBuffer..."); - init_packet = &net_device->ChannelInitPacket; + init_packet = &net_device->channel_init_pkt; memset(init_packet, 0, sizeof(struct nvsp_message)); - init_packet->Header.MessageType = NvspMessage1TypeSendSendBuffer; - init_packet->Messages.Version1Messages.SendReceiveBuffer. - GpadlHandle = net_device->SendBufferGpadlHandle; - init_packet->Messages.Version1Messages.SendReceiveBuffer.Id = + init_packet->hdr.msg_type = NVSP_MSG1_TYPE_SEND_SEND_BUF; + init_packet->msg.v1_msg.send_recv_buf. + gpadl_handle = net_device->send_buf_gpadl_handle; + init_packet->msg.v1_msg.send_recv_buf.id = NETVSC_SEND_BUFFER_ID; /* Send the gpadl notification request */ @@ -412,21 +412,21 @@ static int netvsc_init_send_buf(struct hv_device *device) goto Cleanup; } - osd_waitevent_wait(net_device->ChannelInitEvent); + osd_waitevent_wait(net_device->channel_init_event); /* Check the response */ - if (init_packet->Messages.Version1Messages. - SendSendBufferComplete.Status != NvspStatusSuccess) { + if (init_packet->msg.v1_msg. + send_send_buf_complete.status != NVSP_STAT_SUCCESS) { DPRINT_ERR(NETVSC, "Unable to complete send buffer " "initialzation with NetVsp - status %d", - init_packet->Messages.Version1Messages. - SendSendBufferComplete.Status); + init_packet->msg.v1_msg. + send_send_buf_complete.status); ret = -1; goto Cleanup; } - net_device->SendSectionSize = init_packet-> - Messages.Version1Messages.SendSendBufferComplete.SectionSize; + net_device->send_section_size = init_packet-> + msg.v1_msg.send_send_buf_complete.section_size; goto Exit; @@ -449,20 +449,20 @@ static int netvsc_destroy_recv_buf(struct netvsc_device *net_device) * NvspMessage1TypeSendReceiveBuffer msg) therefore, we need * to send a revoke msg here */ - if (net_device->ReceiveSectionCount) { + if (net_device->recv_section_cnt) { DPRINT_INFO(NETVSC, "Sending NvspMessage1TypeRevokeReceiveBuffer..."); /* Send the revoke receive buffer */ - revoke_packet = &net_device->RevokePacket; + revoke_packet = &net_device->revoke_packet; memset(revoke_packet, 0, sizeof(struct nvsp_message)); - revoke_packet->Header.MessageType = - NvspMessage1TypeRevokeReceiveBuffer; - revoke_packet->Messages.Version1Messages. - RevokeReceiveBuffer.Id = NETVSC_RECEIVE_BUFFER_ID; + revoke_packet->hdr.msg_type = + NVSP_MSG1_TYPE_REVOKE_RECV_BUF; + revoke_packet->msg.v1_msg. + revoke_recv_buf.id = NETVSC_RECEIVE_BUFFER_ID; - ret = vmbus_sendpacket(net_device->Device->channel, + ret = vmbus_sendpacket(net_device->dev->channel, revoke_packet, sizeof(struct nvsp_message), (unsigned long)revoke_packet, @@ -479,11 +479,11 @@ static int netvsc_destroy_recv_buf(struct netvsc_device *net_device) } /* Teardown the gpadl on the vsp end */ - if (net_device->ReceiveBufferGpadlHandle) { + if (net_device->recv_buf_gpadl_handle) { DPRINT_INFO(NETVSC, "Tearing down receive buffer's GPADL..."); - ret = vmbus_teardown_gpadl(net_device->Device->channel, - net_device->ReceiveBufferGpadlHandle); + ret = vmbus_teardown_gpadl(net_device->dev->channel, + net_device->recv_buf_gpadl_handle); /* If we failed here, we might as well return and have a leak rather than continue and a bugchk */ if (ret != 0) { @@ -491,22 +491,22 @@ static int netvsc_destroy_recv_buf(struct netvsc_device *net_device) "unable to teardown receive buffer's gpadl"); return -1; } - net_device->ReceiveBufferGpadlHandle = 0; + net_device->recv_buf_gpadl_handle = 0; } - if (net_device->ReceiveBuffer) { + if (net_device->recv_buf) { DPRINT_INFO(NETVSC, "Freeing up receive buffer..."); /* Free up the receive buffer */ - osd_page_free(net_device->ReceiveBuffer, - net_device->ReceiveBufferSize >> PAGE_SHIFT); - net_device->ReceiveBuffer = NULL; + osd_page_free(net_device->recv_buf, + net_device->recv_buf_size >> PAGE_SHIFT); + net_device->recv_buf = NULL; } - if (net_device->ReceiveSections) { - net_device->ReceiveSectionCount = 0; - kfree(net_device->ReceiveSections); - net_device->ReceiveSections = NULL; + if (net_device->recv_section) { + net_device->recv_section_cnt = 0; + kfree(net_device->recv_section); + net_device->recv_section = NULL; } return ret; @@ -523,20 +523,20 @@ static int netvsc_destroy_send_buf(struct netvsc_device *net_device) * NvspMessage1TypeSendReceiveBuffer msg) therefore, we need * to send a revoke msg here */ - if (net_device->SendSectionSize) { + if (net_device->send_section_size) { DPRINT_INFO(NETVSC, "Sending NvspMessage1TypeRevokeSendBuffer..."); /* Send the revoke send buffer */ - revoke_packet = &net_device->RevokePacket; + revoke_packet = &net_device->revoke_packet; memset(revoke_packet, 0, sizeof(struct nvsp_message)); - revoke_packet->Header.MessageType = - NvspMessage1TypeRevokeSendBuffer; - revoke_packet->Messages.Version1Messages. - RevokeSendBuffer.Id = NETVSC_SEND_BUFFER_ID; + revoke_packet->hdr.msg_type = + NVSP_MSG1_TYPE_REVOKE_SEND_BUF; + revoke_packet->msg.v1_msg. + revoke_send_buf.id = NETVSC_SEND_BUFFER_ID; - ret = vmbus_sendpacket(net_device->Device->channel, + ret = vmbus_sendpacket(net_device->dev->channel, revoke_packet, sizeof(struct nvsp_message), (unsigned long)revoke_packet, @@ -553,10 +553,10 @@ static int netvsc_destroy_send_buf(struct netvsc_device *net_device) } /* Teardown the gpadl on the vsp end */ - if (net_device->SendBufferGpadlHandle) { + if (net_device->send_buf_gpadl_handle) { DPRINT_INFO(NETVSC, "Tearing down send buffer's GPADL..."); - ret = vmbus_teardown_gpadl(net_device->Device->channel, - net_device->SendBufferGpadlHandle); + ret = vmbus_teardown_gpadl(net_device->dev->channel, + net_device->send_buf_gpadl_handle); /* * If we failed here, we might as well return and have a leak @@ -567,16 +567,16 @@ static int netvsc_destroy_send_buf(struct netvsc_device *net_device) "gpadl"); return -1; } - net_device->SendBufferGpadlHandle = 0; + net_device->send_buf_gpadl_handle = 0; } - if (net_device->SendBuffer) { + if (net_device->send_buf) { DPRINT_INFO(NETVSC, "Freeing up send buffer..."); /* Free up the receive buffer */ - osd_page_free(net_device->SendBuffer, - net_device->SendBufferSize >> PAGE_SHIFT); - net_device->SendBuffer = NULL; + osd_page_free(net_device->send_buf, + net_device->send_buf_size >> PAGE_SHIFT); + net_device->send_buf = NULL; } return ret; @@ -597,13 +597,13 @@ static int netvsc_connect_vsp(struct hv_device *device) return -1; } - init_packet = &net_device->ChannelInitPacket; + init_packet = &net_device->channel_init_pkt; memset(init_packet, 0, sizeof(struct nvsp_message)); - init_packet->Header.MessageType = NvspMessageTypeInit; - init_packet->Messages.InitMessages.Init.MinProtocolVersion = + init_packet->hdr.msg_type = NVSP_MSG_TYPE_INIT; + init_packet->msg.init_msg.init.min_protocol_ver = NVSP_MIN_PROTOCOL_VERSION; - init_packet->Messages.InitMessages.Init.MaxProtocolVersion = + init_packet->msg.init_msg.init.max_protocol_ver = NVSP_MAX_PROTOCOL_VERSION; DPRINT_INFO(NETVSC, "Sending NvspMessageTypeInit..."); @@ -620,30 +620,30 @@ static int netvsc_connect_vsp(struct hv_device *device) goto Cleanup; } - osd_waitevent_wait(net_device->ChannelInitEvent); + osd_waitevent_wait(net_device->channel_init_event); /* Now, check the response */ /* ASSERT(initPacket->Messages.InitMessages.InitComplete.MaximumMdlChainLength <= MAX_MULTIPAGE_BUFFER_COUNT); */ DPRINT_INFO(NETVSC, "NvspMessageTypeInit status(%d) max mdl chain (%d)", - init_packet->Messages.InitMessages.InitComplete.Status, - init_packet->Messages.InitMessages. - InitComplete.MaximumMdlChainLength); + init_packet->msg.init_msg.init_complete.status, + init_packet->msg.init_msg. + init_complete.max_mdl_chain_len); - if (init_packet->Messages.InitMessages.InitComplete.Status != - NvspStatusSuccess) { + if (init_packet->msg.init_msg.init_complete.status != + NVSP_STAT_SUCCESS) { DPRINT_ERR(NETVSC, "unable to initialize with netvsp (status 0x%x)", - init_packet->Messages.InitMessages.InitComplete.Status); + init_packet->msg.init_msg.init_complete.status); ret = -1; goto Cleanup; } - if (init_packet->Messages.InitMessages.InitComplete. - NegotiatedProtocolVersion != NVSP_PROTOCOL_VERSION_1) { + if (init_packet->msg.init_msg.init_complete. + negotiated_protocol_ver != NVSP_PROTOCOL_VERSION_1) { DPRINT_ERR(NETVSC, "unable to initialize with netvsp " "(version expected 1 got %d)", - init_packet->Messages.InitMessages. - InitComplete.NegotiatedProtocolVersion); + init_packet->msg.init_msg. + init_complete.negotiated_protocol_ver); ret = -1; goto Cleanup; } @@ -654,12 +654,12 @@ static int netvsc_connect_vsp(struct hv_device *device) ndis_version = 0x00050000; - init_packet->Header.MessageType = NvspMessage1TypeSendNdisVersion; - init_packet->Messages.Version1Messages. - SendNdisVersion.NdisMajorVersion = + init_packet->hdr.msg_type = NVSP_MSG1_TYPE_SEND_NDIS_VER; + init_packet->msg.v1_msg. + send_ndis_ver.ndis_major_ver = (ndis_version & 0xFFFF0000) >> 16; - init_packet->Messages.Version1Messages. - SendNdisVersion.NdisMinorVersion = + init_packet->msg.v1_msg. + send_ndis_ver.ndis_minor_ver = ndis_version & 0xFFFF; /* Send the init request */ @@ -719,12 +719,12 @@ static int netvsc_device_add(struct hv_device *device, void *additional_info) DPRINT_DBG(NETVSC, "netvsc channel object allocated - %p", net_device); /* Initialize the NetVSC channel extension */ - net_device->ReceiveBufferSize = NETVSC_RECEIVE_BUFFER_SIZE; - spin_lock_init(&net_device->receive_packet_list_lock); + net_device->recv_buf_size = NETVSC_RECEIVE_BUFFER_SIZE; + spin_lock_init(&net_device->recv_pkt_list_lock); - net_device->SendBufferSize = NETVSC_SEND_BUFFER_SIZE; + net_device->send_buf_size = NETVSC_SEND_BUFFER_SIZE; - INIT_LIST_HEAD(&net_device->ReceivePacketList); + INIT_LIST_HEAD(&net_device->recv_pkt_list); for (i = 0; i < NETVSC_RECEIVE_PACKETLIST_COUNT; i++) { packet = kzalloc(sizeof(struct hv_netvsc_packet) + @@ -737,10 +737,10 @@ static int netvsc_device_add(struct hv_device *device, void *additional_info) break; } list_add_tail(&packet->list_ent, - &net_device->ReceivePacketList); + &net_device->recv_pkt_list); } - net_device->ChannelInitEvent = osd_waitevent_create(); - if (!net_device->ChannelInitEvent) { + net_device->channel_init_event = osd_waitevent_create(); + if (!net_device->channel_init_event) { ret = -ENOMEM; goto Cleanup; } @@ -779,10 +779,10 @@ close: Cleanup: if (net_device) { - kfree(net_device->ChannelInitEvent); + kfree(net_device->channel_init_event); list_for_each_entry_safe(packet, pos, - &net_device->ReceivePacketList, + &net_device->recv_pkt_list, list_ent) { list_del(&packet->list_ent); kfree(packet); @@ -816,9 +816,9 @@ static int netvsc_device_remove(struct hv_device *device) } /* Wait for all send completions */ - while (atomic_read(&net_device->NumOutstandingSends)) { + while (atomic_read(&net_device->num_outstanding_sends)) { DPRINT_INFO(NETVSC, "waiting for %d requests to complete...", - atomic_read(&net_device->NumOutstandingSends)); + atomic_read(&net_device->num_outstanding_sends)); udelay(100); } @@ -840,12 +840,12 @@ static int netvsc_device_remove(struct hv_device *device) /* Release all resources */ list_for_each_entry_safe(netvsc_packet, pos, - &net_device->ReceivePacketList, list_ent) { + &net_device->recv_pkt_list, list_ent) { list_del(&netvsc_packet->list_ent); kfree(netvsc_packet); } - kfree(net_device->ChannelInitEvent); + kfree(net_device->channel_init_event); free_net_device(net_device); return 0; } @@ -875,19 +875,19 @@ static void netvsc_send_completion(struct hv_device *device, (packet->DataOffset8 << 3)); DPRINT_DBG(NETVSC, "send completion packet - type %d", - nvsp_packet->Header.MessageType); + nvsp_packet->hdr.msg_type); - if ((nvsp_packet->Header.MessageType == NvspMessageTypeInitComplete) || - (nvsp_packet->Header.MessageType == - NvspMessage1TypeSendReceiveBufferComplete) || - (nvsp_packet->Header.MessageType == - NvspMessage1TypeSendSendBufferComplete)) { + if ((nvsp_packet->hdr.msg_type == NVSP_MSG_TYPE_INIT_COMPLETE) || + (nvsp_packet->hdr.msg_type == + NVSP_MSG1_TYPE_SEND_RECV_BUF_COMPLETE) || + (nvsp_packet->hdr.msg_type == + NVSP_MSG1_TYPE_SEND_SEND_BUF_COMPLETE)) { /* Copy the response back */ - memcpy(&net_device->ChannelInitPacket, nvsp_packet, + memcpy(&net_device->channel_init_pkt, nvsp_packet, sizeof(struct nvsp_message)); - osd_waitevent_set(net_device->ChannelInitEvent); - } else if (nvsp_packet->Header.MessageType == - NvspMessage1TypeSendRNDISPacketComplete) { + osd_waitevent_set(net_device->channel_init_event); + } else if (nvsp_packet->hdr.msg_type == + NVSP_MSG1_TYPE_SEND_RNDIS_PKT_COMPLETE) { /* Get the send context */ nvsc_packet = (struct hv_netvsc_packet *)(unsigned long) packet->TransactionId; @@ -897,10 +897,10 @@ static void netvsc_send_completion(struct hv_device *device, nvsc_packet->completion.send.send_completion( nvsc_packet->completion.send.send_completion_ctx); - atomic_dec(&net_device->NumOutstandingSends); + atomic_dec(&net_device->num_outstanding_sends); } else { DPRINT_ERR(NETVSC, "Unknown send completion packet type - " - "%d received!!", nvsp_packet->Header.MessageType); + "%d received!!", nvsp_packet->hdr.msg_type); } put_net_device(device); @@ -921,18 +921,19 @@ static int netvsc_send(struct hv_device *device, return -2; } - sendMessage.Header.MessageType = NvspMessage1TypeSendRNDISPacket; + sendMessage.hdr.msg_type = NVSP_MSG1_TYPE_SEND_RNDIS_PKT; if (packet->is_data_pkt) { /* 0 is RMC_DATA; */ - sendMessage.Messages.Version1Messages.SendRNDISPacket.ChannelType = 0; + sendMessage.msg.v1_msg.send_rndis_pkt.channel_type = 0; } else { /* 1 is RMC_CONTROL; */ - sendMessage.Messages.Version1Messages.SendRNDISPacket.ChannelType = 1; + sendMessage.msg.v1_msg.send_rndis_pkt.channel_type = 1; } /* Not using send buffer section */ - sendMessage.Messages.Version1Messages.SendRNDISPacket.SendBufferSectionIndex = 0xFFFFFFFF; - sendMessage.Messages.Version1Messages.SendRNDISPacket.SendBufferSectionSize = 0; + sendMessage.msg.v1_msg.send_rndis_pkt.send_buf_section_index = + 0xFFFFFFFF; + sendMessage.msg.v1_msg.send_rndis_pkt.send_buf_section_size = 0; if (packet->page_buf_cnt) { ret = vmbus_sendpacket_pagebuffer(device->channel, @@ -954,7 +955,7 @@ static int netvsc_send(struct hv_device *device, DPRINT_ERR(NETVSC, "Unable to send packet %p ret %d", packet, ret); - atomic_inc(&net_device->NumOutstandingSends); + atomic_inc(&net_device->num_outstanding_sends); put_net_device(device); return ret; } @@ -997,16 +998,16 @@ static void netvsc_receive(struct hv_device *device, (packet->DataOffset8 << 3)); /* Make sure this is a valid nvsp packet */ - if (nvsp_packet->Header.MessageType != - NvspMessage1TypeSendRNDISPacket) { + if (nvsp_packet->hdr.msg_type != + NVSP_MSG1_TYPE_SEND_RNDIS_PKT) { DPRINT_ERR(NETVSC, "Unknown nvsp packet type received - %d", - nvsp_packet->Header.MessageType); + nvsp_packet->hdr.msg_type); put_net_device(device); return; } DPRINT_DBG(NETVSC, "NVSP packet received - type %d", - nvsp_packet->Header.MessageType); + nvsp_packet->hdr.msg_type); vmxferpage_packet = (struct vmtransfer_page_packet_header *)packet; @@ -1027,13 +1028,13 @@ static void netvsc_receive(struct hv_device *device, * We grab it here so that we know exactly how many we can * fulfil */ - spin_lock_irqsave(&net_device->receive_packet_list_lock, flags); - while (!list_empty(&net_device->ReceivePacketList)) { - list_move_tail(net_device->ReceivePacketList.next, &listHead); + spin_lock_irqsave(&net_device->recv_pkt_list_lock, flags); + while (!list_empty(&net_device->recv_pkt_list)) { + list_move_tail(net_device->recv_pkt_list.next, &listHead); if (++count == vmxferpage_packet->RangeCount + 1) break; } - spin_unlock_irqrestore(&net_device->receive_packet_list_lock, flags); + spin_unlock_irqrestore(&net_device->recv_pkt_list_lock, flags); /* * We need at least 2 netvsc pkts (1 to represent the xfer @@ -1046,12 +1047,12 @@ static void netvsc_receive(struct hv_device *device, count, vmxferpage_packet->RangeCount + 1); /* Return it to the freelist */ - spin_lock_irqsave(&net_device->receive_packet_list_lock, flags); + spin_lock_irqsave(&net_device->recv_pkt_list_lock, flags); for (i = count; i != 0; i--) { list_move_tail(listHead.next, - &net_device->ReceivePacketList); + &net_device->recv_pkt_list); } - spin_unlock_irqrestore(&net_device->receive_packet_list_lock, + spin_unlock_irqrestore(&net_device->recv_pkt_list_lock, flags); netvsc_send_recv_completion(device, @@ -1104,10 +1105,10 @@ static void netvsc_receive(struct hv_device *device, vmxferpage_packet->Ranges[i].ByteCount; start = virt_to_phys((void *)((unsigned long)net_device-> - ReceiveBuffer + vmxferpage_packet->Ranges[i].ByteOffset)); + recv_buf + vmxferpage_packet->Ranges[i].ByteOffset)); netvsc_packet->page_buf[0].Pfn = start >> PAGE_SHIFT; - end_virtual = (unsigned long)net_device->ReceiveBuffer + end_virtual = (unsigned long)net_device->recv_buf + vmxferpage_packet->Ranges[i].ByteOffset + vmxferpage_packet->Ranges[i].ByteCount - 1; end = virt_to_phys((void *)end_virtual); @@ -1175,11 +1176,12 @@ static void netvsc_send_recv_completion(struct hv_device *device, DPRINT_DBG(NETVSC, "Sending receive completion pkt - %llx", transaction_id); - recvcompMessage.Header.MessageType = - NvspMessage1TypeSendRNDISPacketComplete; + recvcompMessage.hdr.msg_type = + NVSP_MSG1_TYPE_SEND_RNDIS_PKT_COMPLETE; /* FIXME: Pass in the status */ - recvcompMessage.Messages.Version1Messages.SendRNDISPacketComplete.Status = NvspStatusSuccess; + recvcompMessage.msg.v1_msg.send_rndis_pkt_complete.status = + NVSP_STAT_SUCCESS; retry_send_cmplt: /* Send the completion */ @@ -1234,7 +1236,7 @@ static void netvsc_receive_completion(void *context) } /* Overloading use of the lock. */ - spin_lock_irqsave(&net_device->receive_packet_list_lock, flags); + spin_lock_irqsave(&net_device->recv_pkt_list_lock, flags); /* ASSERT(packet->XferPagePacket->Count > 0); */ packet->xfer_page_pkt->count--; @@ -1247,13 +1249,13 @@ static void netvsc_receive_completion(void *context) fsend_receive_comp = true; transaction_id = packet->completion.recv.recv_completion_tid; list_add_tail(&packet->xfer_page_pkt->list_ent, - &net_device->ReceivePacketList); + &net_device->recv_pkt_list); } /* Put the packet back */ - list_add_tail(&packet->list_ent, &net_device->ReceivePacketList); - spin_unlock_irqrestore(&net_device->receive_packet_list_lock, flags); + list_add_tail(&packet->list_ent, &net_device->recv_pkt_list); + spin_unlock_irqrestore(&net_device->recv_pkt_list_lock, flags); /* Send a receive completion for the xfer page packet */ if (fsend_receive_comp) diff --git a/drivers/staging/hv/netvsc.h b/drivers/staging/hv/netvsc.h index c71dce5b3f7c..932a77ccdc04 100644 --- a/drivers/staging/hv/netvsc.h +++ b/drivers/staging/hv/netvsc.h @@ -38,48 +38,48 @@ #define NVSP_MAX_PROTOCOL_VERSION NVSP_PROTOCOL_VERSION_1 enum { - NvspMessageTypeNone = 0, + NVSP_MSG_TYPE_NONE = 0, /* Init Messages */ - NvspMessageTypeInit = 1, - NvspMessageTypeInitComplete = 2, + NVSP_MSG_TYPE_INIT = 1, + NVSP_MSG_TYPE_INIT_COMPLETE = 2, - NvspVersionMessageStart = 100, + NVSP_VERSION_MSG_START = 100, /* Version 1 Messages */ - NvspMessage1TypeSendNdisVersion = NvspVersionMessageStart, + NVSP_MSG1_TYPE_SEND_NDIS_VER = NVSP_VERSION_MSG_START, - NvspMessage1TypeSendReceiveBuffer, - NvspMessage1TypeSendReceiveBufferComplete, - NvspMessage1TypeRevokeReceiveBuffer, + NVSP_MSG1_TYPE_SEND_RECV_BUF, + NVSP_MSG1_TYPE_SEND_RECV_BUF_COMPLETE, + NVSP_MSG1_TYPE_REVOKE_RECV_BUF, - NvspMessage1TypeSendSendBuffer, - NvspMessage1TypeSendSendBufferComplete, - NvspMessage1TypeRevokeSendBuffer, + NVSP_MSG1_TYPE_SEND_SEND_BUF, + NVSP_MSG1_TYPE_SEND_SEND_BUF_COMPLETE, + NVSP_MSG1_TYPE_REVOKE_SEND_BUF, - NvspMessage1TypeSendRNDISPacket, - NvspMessage1TypeSendRNDISPacketComplete, + NVSP_MSG1_TYPE_SEND_RNDIS_PKT, + NVSP_MSG1_TYPE_SEND_RNDIS_PKT_COMPLETE, /* * This should be set to the number of messages for the version with * the maximum number of messages. */ - NvspNumMessagePerVersion = 9, + NVSP_NUM_MSG_PER_VERSION = 9, }; enum { - NvspStatusNone = 0, - NvspStatusSuccess, - NvspStatusFailure, - NvspStatusProtocolVersionRangeTooNew, - NvspStatusProtocolVersionRangeTooOld, - NvspStatusInvalidRndisPacket, - NvspStatusBusy, - NvspStatusMax, + NVSP_STAT_NONE = 0, + NVSP_STAT_SUCCESS, + NVSP_STAT_FAIL, + NVSP_STAT_PROTOCOL_TOO_NEW, + NVSP_STAT_PROTOCOL_TOO_OLD, + NVSP_STAT_INVALID_RNDIS_PKT, + NVSP_STAT_BUSY, + NVSP_STAT_MAX, }; struct nvsp_message_header { - u32 MessageType; + u32 msg_type; }; /* Init Messages */ @@ -90,8 +90,8 @@ struct nvsp_message_header { * versioning (i.e. this message will be the same for ever). */ struct nvsp_message_init { - u32 MinProtocolVersion; - u32 MaxProtocolVersion; + u32 min_protocol_ver; + u32 max_protocol_ver; } __attribute__((packed)); /* @@ -100,14 +100,14 @@ struct nvsp_message_init { * (i.e. this message will be the same for ever). */ struct nvsp_message_init_complete { - u32 NegotiatedProtocolVersion; - u32 MaximumMdlChainLength; - u32 Status; + u32 negotiated_protocol_ver; + u32 max_mdl_chain_len; + u32 status; } __attribute__((packed)); union nvsp_message_init_uber { - struct nvsp_message_init Init; - struct nvsp_message_init_complete InitComplete; + struct nvsp_message_init init; + struct nvsp_message_init_complete init_complete; } __attribute__((packed)); /* Version 1 Messages */ @@ -117,8 +117,8 @@ union nvsp_message_init_uber { * can use this information when handling OIDs sent by the VSC. */ struct nvsp_1_message_send_ndis_version { - u32 NdisMajorVersion; - u32 NdisMinorVersion; + u32 ndis_major_ver; + u32 ndis_minor_ver; } __attribute__((packed)); /* @@ -126,15 +126,15 @@ struct nvsp_1_message_send_ndis_version { * can then use the receive buffer to send data to the VSC. */ struct nvsp_1_message_send_receive_buffer { - u32 GpadlHandle; - u16 Id; + u32 gpadl_handle; + u16 id; } __attribute__((packed)); struct nvsp_1_receive_buffer_section { - u32 Offset; - u32 SubAllocationSize; - u32 NumSubAllocations; - u32 EndOffset; + u32 offset; + u32 sub_alloc_size; + u32 num_sub_allocs; + u32 end_offset; } __attribute__((packed)); /* @@ -143,8 +143,8 @@ struct nvsp_1_receive_buffer_section { * buffer. */ struct nvsp_1_message_send_receive_buffer_complete { - u32 Status; - u32 NumSections; + u32 status; + u32 num_sections; /* * The receive buffer is split into two parts, a large suballocation @@ -165,7 +165,7 @@ struct nvsp_1_message_send_receive_buffer_complete { * LargeOffset SmallOffset */ - struct nvsp_1_receive_buffer_section Sections[1]; + struct nvsp_1_receive_buffer_section sections[1]; } __attribute__((packed)); /* @@ -174,7 +174,7 @@ struct nvsp_1_message_send_receive_buffer_complete { * again. */ struct nvsp_1_message_revoke_receive_buffer { - u16 Id; + u16 id; }; /* @@ -182,8 +182,8 @@ struct nvsp_1_message_revoke_receive_buffer { * can then use the send buffer to send data to the VSP. */ struct nvsp_1_message_send_send_buffer { - u32 GpadlHandle; - u16 Id; + u32 gpadl_handle; + u16 id; } __attribute__((packed)); /* @@ -192,7 +192,7 @@ struct nvsp_1_message_send_send_buffer { * buffer. */ struct nvsp_1_message_send_send_buffer_complete { - u32 Status; + u32 status; /* * The VSC gets to choose the size of the send buffer and the VSP gets @@ -200,7 +200,7 @@ struct nvsp_1_message_send_send_buffer_complete { * dynamic reconfigurations when the cost of GPA-direct buffers * decreases. */ - u32 SectionSize; + u32 section_size; } __attribute__((packed)); /* @@ -208,7 +208,7 @@ struct nvsp_1_message_send_send_buffer_complete { * completes this transaction, the vsp should never use the send buffer again. */ struct nvsp_1_message_revoke_send_buffer { - u16 Id; + u16 id; }; /* @@ -221,7 +221,7 @@ struct nvsp_1_message_send_rndis_packet { * channels of communication. However, the Network VSP only has one. * Therefore, the channel travels with the RNDIS packet. */ - u32 ChannelType; + u32 channel_type; /* * This field is used to send part or all of the data through a send @@ -229,8 +229,8 @@ struct nvsp_1_message_send_rndis_packet { * index is 0xFFFFFFFF, then the send buffer is not being used and all * of the data was sent through other VMBus mechanisms. */ - u32 SendBufferSectionIndex; - u32 SendBufferSectionSize; + u32 send_buf_section_index; + u32 send_buf_section_size; } __attribute__((packed)); /* @@ -239,35 +239,35 @@ struct nvsp_1_message_send_rndis_packet { * message cannot use any resources associated with the original RNDIS packet. */ struct nvsp_1_message_send_rndis_packet_complete { - u32 Status; + u32 status; }; union nvsp_1_message_uber { - struct nvsp_1_message_send_ndis_version SendNdisVersion; + struct nvsp_1_message_send_ndis_version send_ndis_ver; - struct nvsp_1_message_send_receive_buffer SendReceiveBuffer; + struct nvsp_1_message_send_receive_buffer send_recv_buf; struct nvsp_1_message_send_receive_buffer_complete - SendReceiveBufferComplete; - struct nvsp_1_message_revoke_receive_buffer RevokeReceiveBuffer; + send_recv_buf_complete; + struct nvsp_1_message_revoke_receive_buffer revoke_recv_buf; - struct nvsp_1_message_send_send_buffer SendSendBuffer; - struct nvsp_1_message_send_send_buffer_complete SendSendBufferComplete; - struct nvsp_1_message_revoke_send_buffer RevokeSendBuffer; + struct nvsp_1_message_send_send_buffer send_send_buf; + struct nvsp_1_message_send_send_buffer_complete send_send_buf_complete; + struct nvsp_1_message_revoke_send_buffer revoke_send_buf; - struct nvsp_1_message_send_rndis_packet SendRNDISPacket; + struct nvsp_1_message_send_rndis_packet send_rndis_pkt; struct nvsp_1_message_send_rndis_packet_complete - SendRNDISPacketComplete; + send_rndis_pkt_complete; } __attribute__((packed)); union nvsp_all_messages { - union nvsp_message_init_uber InitMessages; - union nvsp_1_message_uber Version1Messages; + union nvsp_message_init_uber init_msg; + union nvsp_1_message_uber v1_msg; } __attribute__((packed)); /* ALL Messages */ struct nvsp_message { - struct nvsp_message_header Header; - union nvsp_all_messages Messages; + struct nvsp_message_header hdr; + union nvsp_all_messages msg; } __attribute__((packed)); @@ -293,39 +293,39 @@ struct nvsp_message { /* Per netvsc channel-specific */ struct netvsc_device { - struct hv_device *Device; + struct hv_device *dev; - atomic_t RefCount; - atomic_t NumOutstandingSends; + atomic_t refcnt; + atomic_t num_outstanding_sends; /* * List of free preallocated hv_netvsc_packet to represent receive * packet */ - struct list_head ReceivePacketList; - spinlock_t receive_packet_list_lock; + struct list_head recv_pkt_list; + spinlock_t recv_pkt_list_lock; /* Send buffer allocated by us but manages by NetVSP */ - void *SendBuffer; - u32 SendBufferSize; - u32 SendBufferGpadlHandle; - u32 SendSectionSize; + void *send_buf; + u32 send_buf_size; + u32 send_buf_gpadl_handle; + u32 send_section_size; /* Receive buffer allocated by us but manages by NetVSP */ - void *ReceiveBuffer; - u32 ReceiveBufferSize; - u32 ReceiveBufferGpadlHandle; - u32 ReceiveSectionCount; - struct nvsp_1_receive_buffer_section *ReceiveSections; + void *recv_buf; + u32 recv_buf_size; + u32 recv_buf_gpadl_handle; + u32 recv_section_cnt; + struct nvsp_1_receive_buffer_section *recv_section; /* Used for NetVSP initialization protocol */ - struct osd_waitevent *ChannelInitEvent; - struct nvsp_message ChannelInitPacket; + struct osd_waitevent *channel_init_event; + struct nvsp_message channel_init_pkt; - struct nvsp_message RevokePacket; + struct nvsp_message revoke_packet; /* unsigned char HwMacAddr[HW_MACADDR_LEN]; */ /* Holds rndis device info */ - void *Extension; + void *extension; }; #endif /* _NETVSC_H_ */ diff --git a/drivers/staging/hv/netvsc_api.h b/drivers/staging/hv/netvsc_api.h index ac40db56e1fa..b4bed3636594 100644 --- a/drivers/staging/hv/netvsc_api.h +++ b/drivers/staging/hv/netvsc_api.h @@ -95,7 +95,7 @@ struct netvsc_driver { */ int (*recv_cb)(struct hv_device *dev, struct hv_netvsc_packet *packet); - void (*link_status_change)(struct hv_device *dev, u32 Status); + void (*link_status_change)(struct hv_device *dev, u32 status); /* Specific to this driver */ int (*send)(struct hv_device *dev, struct hv_netvsc_packet *packet); diff --git a/drivers/staging/hv/rndis_filter.c b/drivers/staging/hv/rndis_filter.c index dffcc0397917..63d24c6fadf0 100644 --- a/drivers/staging/hv/rndis_filter.c +++ b/drivers/staging/hv/rndis_filter.c @@ -266,7 +266,7 @@ static int rndis_filter_send_request(struct rndis_device *dev, rndis_filter_send_request_completion; packet->completion.send.send_completion_tid = (unsigned long)dev; - ret = rndis_filter.inner_drv.send(dev->net_dev->Device, packet); + ret = rndis_filter.inner_drv.send(dev->net_dev->dev, packet); return ret; } @@ -338,10 +338,10 @@ static void rndis_filter_receive_indicate_status(struct rndis_device *dev, if (indicate->Status == RNDIS_STATUS_MEDIA_CONNECT) { rndis_filter.inner_drv.link_status_change( - dev->net_dev->Device, 1); + dev->net_dev->dev, 1); } else if (indicate->Status == RNDIS_STATUS_MEDIA_DISCONNECT) { rndis_filter.inner_drv.link_status_change( - dev->net_dev->Device, 0); + dev->net_dev->dev, 0); } else { /* * TODO: @@ -376,7 +376,7 @@ static void rndis_filter_receive_data(struct rndis_device *dev, pkt->is_data_pkt = true; - rndis_filter.inner_drv.recv_cb(dev->net_dev->Device, + rndis_filter.inner_drv.recv_cb(dev->net_dev->dev, pkt); } @@ -392,13 +392,13 @@ static int rndis_filter_receive(struct hv_device *dev, return -EINVAL; /* Make sure the rndis device state is initialized */ - if (!net_dev->Extension) { + if (!net_dev->extension) { DPRINT_ERR(NETVSC, "got rndis message but no rndis device..." "dropping this message!"); return -1; } - rndis_dev = (struct rndis_device *)net_dev->Extension; + rndis_dev = (struct rndis_device *)net_dev->extension; if (rndis_dev->state == RNDIS_DEV_UNINITIALIZED) { DPRINT_ERR(NETVSC, "got rndis message but rndis device " "uninitialized...dropping this message!"); @@ -782,7 +782,7 @@ static int rndis_filte_device_add(struct hv_device *dev, /* ASSERT(netDevice); */ /* ASSERT(netDevice->Device); */ - netDevice->Extension = rndisDevice; + netDevice->extension = rndisDevice; rndisDevice->net_dev = netDevice; /* Send the rndis initialization message */ @@ -819,13 +819,13 @@ static int rndis_filte_device_add(struct hv_device *dev, static int rndis_filter_device_remove(struct hv_device *dev) { struct netvsc_device *net_dev = dev->Extension; - struct rndis_device *rndis_dev = net_dev->Extension; + struct rndis_device *rndis_dev = net_dev->extension; /* Halt and release the rndis device */ rndis_filter_halt_device(rndis_dev); kfree(rndis_dev); - net_dev->Extension = NULL; + net_dev->extension = NULL; /* Pass control to inner driver to remove the device */ rndis_filter.inner_drv.base.OnDeviceRemove(dev); @@ -844,7 +844,7 @@ int rndis_filter_open(struct hv_device *dev) if (!netDevice) return -EINVAL; - return rndis_filter_open_device(netDevice->Extension); + return rndis_filter_open_device(netDevice->extension); } int rndis_filter_close(struct hv_device *dev) @@ -854,7 +854,7 @@ int rndis_filter_close(struct hv_device *dev) if (!netDevice) return -EINVAL; - return rndis_filter_close_device(netDevice->Extension); + return rndis_filter_close_device(netDevice->extension); } static int rndis_filter_send(struct hv_device *dev, -- cgit v1.2.3 From a388eb1727c15a7da1f64fcf16e60fcb7aca40bd Mon Sep 17 00:00:00 2001 From: Haiyang Zhang Date: Fri, 10 Dec 2010 12:04:00 -0800 Subject: staging: hv: Convert camel cased struct fields in rndis.h to lower cases Signed-off-by: Haiyang Zhang Signed-off-by: Hank Janssen Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/rndis.h | 353 +++++++++++++++++++------------------- drivers/staging/hv/rndis_filter.c | 204 +++++++++++----------- 2 files changed, 279 insertions(+), 278 deletions(-) diff --git a/drivers/staging/hv/rndis.h b/drivers/staging/hv/rndis.h index 723e1f15b90d..014de047b86d 100644 --- a/drivers/staging/hv/rndis.h +++ b/drivers/staging/hv/rndis.h @@ -288,24 +288,24 @@ #define RNDIS_DF_RAW_DATA 0x00000004 /* Remote NDIS medium types. */ -#define RNdisMedium802_3 0x00000000 -#define RNdisMedium802_5 0x00000001 -#define RNdisMediumFddi 0x00000002 -#define RNdisMediumWan 0x00000003 -#define RNdisMediumLocalTalk 0x00000004 -#define RNdisMediumArcnetRaw 0x00000006 -#define RNdisMediumArcnet878_2 0x00000007 -#define RNdisMediumAtm 0x00000008 -#define RNdisMediumWirelessWan 0x00000009 -#define RNdisMediumIrda 0x0000000a -#define RNdisMediumCoWan 0x0000000b +#define RNDIS_MEDIUM_802_3 0x00000000 +#define RNDIS_MEDIUM_802_5 0x00000001 +#define RNDIS_MEDIUM_FDDI 0x00000002 +#define RNDIS_MEDIUM_WAN 0x00000003 +#define RNDIS_MEDIUM_LOCAL_TALK 0x00000004 +#define RNDIS_MEDIUM_ARCNET_RAW 0x00000006 +#define RNDIS_MEDIUM_ARCNET_878_2 0x00000007 +#define RNDIS_MEDIUM_ATM 0x00000008 +#define RNDIS_MEDIUM_WIRELESS_WAN 0x00000009 +#define RNDIS_MEDIUM_IRDA 0x0000000a +#define RNDIS_MEDIUM_CO_WAN 0x0000000b /* Not a real medium, defined as an upper-bound */ -#define RNdisMediumMax 0x0000000d +#define RNDIS_MEDIUM_MAX 0x0000000d /* Remote NDIS medium connection states. */ -#define RNdisMediaStateConnected 0x00000000 -#define RNdisMediaStateDisconnected 0x00000001 +#define RNDIS_MEDIA_STATE_CONNECTED 0x00000000 +#define RNDIS_MEDIA_STATE_DISCONNECTED 0x00000001 /* Remote NDIS version numbers */ #define RNDIS_MAJOR_VERSION 0x00000001 @@ -314,106 +314,106 @@ /* NdisInitialize message */ struct rndis_initialize_request { - u32 RequestId; - u32 MajorVersion; - u32 MinorVersion; - u32 MaxTransferSize; + u32 req_id; + u32 major_ver; + u32 minor_ver; + u32 max_xfer_size; }; /* Response to NdisInitialize */ struct rndis_initialize_complete { - u32 RequestId; - u32 Status; - u32 MajorVersion; - u32 MinorVersion; - u32 DeviceFlags; - u32 Medium; - u32 MaxPacketsPerMessage; - u32 MaxTransferSize; - u32 PacketAlignmentFactor; - u32 AFListOffset; - u32 AFListSize; + u32 req_id; + u32 status; + u32 major_ver; + u32 minor_ver; + u32 dev_flags; + u32 medium; + u32 max_pkt_per_msg; + u32 max_xfer_size; + u32 pkt_alignment_factor; + u32 af_list_offset; + u32 af_list_size; }; /* Call manager devices only: Information about an address family */ /* supported by the device is appended to the response to NdisInitialize. */ struct rndis_co_address_family { - u32 AddressFamily; - u32 MajorVersion; - u32 MinorVersion; + u32 address_family; + u32 major_ver; + u32 minor_ver; }; /* NdisHalt message */ struct rndis_halt_request { - u32 RequestId; + u32 req_id; }; /* NdisQueryRequest message */ struct rndis_query_request { - u32 RequestId; - u32 Oid; - u32 InformationBufferLength; - u32 InformationBufferOffset; - u32 DeviceVcHandle; + u32 req_id; + u32 oid; + u32 info_buflen; + u32 info_buf_offset; + u32 dev_vc_handle; }; /* Response to NdisQueryRequest */ struct rndis_query_complete { - u32 RequestId; - u32 Status; - u32 InformationBufferLength; - u32 InformationBufferOffset; + u32 req_id; + u32 status; + u32 info_buflen; + u32 info_buf_offset; }; /* NdisSetRequest message */ struct rndis_set_request { - u32 RequestId; - u32 Oid; - u32 InformationBufferLength; - u32 InformationBufferOffset; - u32 DeviceVcHandle; + u32 req_id; + u32 oid; + u32 info_buflen; + u32 info_buf_offset; + u32 dev_vc_handle; }; /* Response to NdisSetRequest */ struct rndis_set_complete { - u32 RequestId; - u32 Status; + u32 req_id; + u32 status; }; /* NdisReset message */ struct rndis_reset_request { - u32 Reserved; + u32 reserved; }; /* Response to NdisReset */ struct rndis_reset_complete { - u32 Status; - u32 AddressingReset; + u32 status; + u32 addressing_reset; }; /* NdisMIndicateStatus message */ struct rndis_indicate_status { - u32 Status; - u32 StatusBufferLength; - u32 StatusBufferOffset; + u32 status; + u32 status_buflen; + u32 status_buf_offset; }; /* Diagnostic information passed as the status buffer in */ /* struct rndis_indicate_status messages signifying error conditions. */ struct rndis_diagnostic_info { - u32 DiagStatus; - u32 ErrorOffset; + u32 diag_status; + u32 error_offset; }; /* NdisKeepAlive message */ struct rndis_keepalive_request { - u32 RequestId; + u32 req_id; }; /* Response to NdisKeepAlive */ struct rndis_keepalive_complete { - u32 RequestId; - u32 Status; + u32 req_id; + u32 status; }; /* @@ -422,39 +422,39 @@ struct rndis_keepalive_complete { * to 0 for connectionless data, otherwise it contains the VC handle. */ struct rndis_packet { - u32 DataOffset; - u32 DataLength; - u32 OOBDataOffset; - u32 OOBDataLength; - u32 NumOOBDataElements; - u32 PerPacketInfoOffset; - u32 PerPacketInfoLength; - u32 VcHandle; - u32 Reserved; + u32 data_offset; + u32 data_len; + u32 oob_data_offset; + u32 oob_data_len; + u32 num_oob_data_elements; + u32 per_pkt_info_offset; + u32 per_pkt_info_len; + u32 vc_handle; + u32 reserved; }; /* Optional Out of Band data associated with a Data message. */ struct rndis_oobd { - u32 Size; - u32 Type; - u32 ClassInformationOffset; + u32 size; + u32 type; + u32 class_info_offset; }; /* Packet extension field contents associated with a Data message. */ struct rndis_per_packet_info { - u32 Size; - u32 Type; - u32 PerPacketInformationOffset; + u32 size; + u32 type; + u32 per_pkt_info_offset; }; /* Format of Information buffer passed in a SetRequest for the OID */ /* OID_GEN_RNDIS_CONFIG_PARAMETER. */ struct rndis_config_parameter_info { - u32 ParameterNameOffset; - u32 ParameterNameLength; - u32 ParameterType; - u32 ParameterValueOffset; - u32 ParameterValueLength; + u32 parameter_name_offset; + u32 parameter_name_length; + u32 parameter_type; + u32 parameter_value_offset; + u32 parameter_value_length; }; /* Values for ParameterType in struct rndis_config_parameter_info */ @@ -466,187 +466,188 @@ struct rndis_config_parameter_info { /* CoNdisMiniportCreateVc message */ struct rcondis_mp_create_vc { - u32 RequestId; - u32 NdisVcHandle; + u32 req_id; + u32 ndis_vc_handle; }; /* Response to CoNdisMiniportCreateVc */ struct rcondis_mp_create_vc_complete { - u32 RequestId; - u32 DeviceVcHandle; - u32 Status; + u32 req_id; + u32 dev_vc_handle; + u32 status; }; /* CoNdisMiniportDeleteVc message */ struct rcondis_mp_delete_vc { - u32 RequestId; - u32 DeviceVcHandle; + u32 req_id; + u32 dev_vc_handle; }; /* Response to CoNdisMiniportDeleteVc */ struct rcondis_mp_delete_vc_complete { - u32 RequestId; - u32 Status; + u32 req_id; + u32 status; }; /* CoNdisMiniportQueryRequest message */ struct rcondis_mp_query_request { - u32 RequestId; - u32 RequestType; - u32 Oid; - u32 DeviceVcHandle; - u32 InformationBufferLength; - u32 InformationBufferOffset; + u32 req_id; + u32 request_type; + u32 oid; + u32 dev_vc_handle; + u32 info_buflen; + u32 info_buf_offset; }; /* CoNdisMiniportSetRequest message */ struct rcondis_mp_set_request { - u32 RequestId; - u32 RequestType; - u32 Oid; - u32 DeviceVcHandle; - u32 InformationBufferLength; - u32 InformationBufferOffset; + u32 req_id; + u32 request_type; + u32 oid; + u32 dev_vc_handle; + u32 info_buflen; + u32 info_buf_offset; }; /* CoNdisIndicateStatus message */ struct rcondis_indicate_status { - u32 NdisVcHandle; - u32 Status; - u32 StatusBufferLength; - u32 StatusBufferOffset; + u32 ndis_vc_handle; + u32 status; + u32 status_buflen; + u32 status_buf_offset; }; /* CONDIS Call/VC parameters */ struct rcondis_specific_parameters { - u32 ParameterType; - u32 ParameterLength; - u32 ParameterOffset; + u32 parameter_type; + u32 parameter_length; + u32 parameter_lffset; }; struct rcondis_media_parameters { - u32 Flags; - u32 Reserved1; - u32 Reserved2; - struct rcondis_specific_parameters MediaSpecific; + u32 flags; + u32 reserved1; + u32 reserved2; + struct rcondis_specific_parameters media_specific; }; struct rndis_flowspec { - u32 TokenRate; - u32 TokenBucketSize; - u32 PeakBandwidth; - u32 Latency; - u32 DelayVariation; - u32 ServiceType; - u32 MaxSduSize; - u32 MinimumPolicedSize; + u32 token_rate; + u32 token_bucket_size; + u32 peak_bandwidth; + u32 latency; + u32 delay_variation; + u32 service_type; + u32 max_sdu_size; + u32 minimum_policed_size; }; struct rcondis_call_manager_parameters { - struct rndis_flowspec Transmit; - struct rndis_flowspec Receive; - struct rcondis_specific_parameters CallMgrSpecific; + struct rndis_flowspec transmit; + struct rndis_flowspec receive; + struct rcondis_specific_parameters call_mgr_specific; }; /* CoNdisMiniportActivateVc message */ struct rcondis_mp_activate_vc_request { - u32 RequestId; - u32 Flags; - u32 DeviceVcHandle; - u32 MediaParamsOffset; - u32 MediaParamsLength; - u32 CallMgrParamsOffset; - u32 CallMgrParamsLength; + u32 req_id; + u32 flags; + u32 dev_vc_handle; + u32 media_params_offset; + u32 media_params_length; + u32 call_mgr_params_offset; + u32 call_mgr_params_length; }; /* Response to CoNdisMiniportActivateVc */ struct rcondis_mp_activate_vc_complete { - u32 RequestId; - u32 Status; + u32 req_id; + u32 status; }; /* CoNdisMiniportDeactivateVc message */ struct rcondis_mp_deactivate_vc_request { - u32 RequestId; - u32 Flags; - u32 DeviceVcHandle; + u32 req_id; + u32 flags; + u32 dev_vc_handle; }; /* Response to CoNdisMiniportDeactivateVc */ struct rcondis_mp_deactivate_vc_complete { - u32 RequestId; - u32 Status; + u32 req_id; + u32 status; }; /* union with all of the RNDIS messages */ union rndis_message_container { - struct rndis_packet Packet; - struct rndis_initialize_request InitializeRequest; - struct rndis_halt_request HaltRequest; - struct rndis_query_request QueryRequest; - struct rndis_set_request SetRequest; - struct rndis_reset_request ResetRequest; - struct rndis_keepalive_request KeepaliveRequest; - struct rndis_indicate_status IndicateStatus; - struct rndis_initialize_complete InitializeComplete; - struct rndis_query_complete QueryComplete; - struct rndis_set_complete SetComplete; - struct rndis_reset_complete ResetComplete; - struct rndis_keepalive_complete KeepaliveComplete; - struct rcondis_mp_create_vc CoMiniportCreateVc; - struct rcondis_mp_delete_vc CoMiniportDeleteVc; - struct rcondis_indicate_status CoIndicateStatus; - struct rcondis_mp_activate_vc_request CoMiniportActivateVc; - struct rcondis_mp_deactivate_vc_request CoMiniportDeactivateVc; - struct rcondis_mp_create_vc_complete CoMiniportCreateVcComplete; - struct rcondis_mp_delete_vc_complete CoMiniportDeleteVcComplete; - struct rcondis_mp_activate_vc_complete CoMiniportActivateVcComplete; - struct rcondis_mp_deactivate_vc_complete CoMiniportDeactivateVcComplete; + struct rndis_packet pkt; + struct rndis_initialize_request init_req; + struct rndis_halt_request halt_req; + struct rndis_query_request query_req; + struct rndis_set_request set_req; + struct rndis_reset_request reset_req; + struct rndis_keepalive_request keep_alive_req; + struct rndis_indicate_status indicate_status; + struct rndis_initialize_complete init_complete; + struct rndis_query_complete query_complete; + struct rndis_set_complete set_complete; + struct rndis_reset_complete reset_complete; + struct rndis_keepalive_complete keep_alive_complete; + struct rcondis_mp_create_vc co_miniport_create_vc; + struct rcondis_mp_delete_vc co_miniport_delete_vc; + struct rcondis_indicate_status co_indicate_status; + struct rcondis_mp_activate_vc_request co_miniport_activate_vc; + struct rcondis_mp_deactivate_vc_request co_miniport_deactivate_vc; + struct rcondis_mp_create_vc_complete co_miniport_create_vc_complete; + struct rcondis_mp_delete_vc_complete co_miniport_delete_vc_complete; + struct rcondis_mp_activate_vc_complete co_miniport_activate_vc_complete; + struct rcondis_mp_deactivate_vc_complete + co_miniport_deactivate_vc_complete; }; /* Remote NDIS message format */ struct rndis_message { - u32 NdisMessageType; + u32 ndis_msg_type; /* Total length of this message, from the beginning */ /* of the sruct rndis_message, in bytes. */ - u32 MessageLength; + u32 msg_len; /* Actual message */ - union rndis_message_container Message; + union rndis_message_container msg; }; /* Handy macros */ /* get the size of an RNDIS message. Pass in the message type, */ /* struct rndis_set_request, struct rndis_packet for example */ -#define RNDIS_MESSAGE_SIZE(Message) \ - (sizeof(Message) + (sizeof(struct rndis_message) - \ +#define RNDIS_MESSAGE_SIZE(msg) \ + (sizeof(msg) + (sizeof(struct rndis_message) - \ sizeof(union rndis_message_container))) /* get pointer to info buffer with message pointer */ -#define MESSAGE_TO_INFO_BUFFER(Message) \ - (((unsigned char *)(Message)) + Message->InformationBufferOffset) +#define MESSAGE_TO_INFO_BUFFER(msg) \ + (((unsigned char *)(msg)) + msg->info_buf_offset) /* get pointer to status buffer with message pointer */ -#define MESSAGE_TO_STATUS_BUFFER(Message) \ - (((unsigned char *)(Message)) + Message->StatusBufferOffset) +#define MESSAGE_TO_STATUS_BUFFER(msg) \ + (((unsigned char *)(msg)) + msg->status_buf_offset) /* get pointer to OOBD buffer with message pointer */ -#define MESSAGE_TO_OOBD_BUFFER(Message) \ - (((unsigned char *)(Message)) + Message->OOBDataOffset) +#define MESSAGE_TO_OOBD_BUFFER(msg) \ + (((unsigned char *)(msg)) + msg->oob_data_offset) /* get pointer to data buffer with message pointer */ -#define MESSAGE_TO_DATA_BUFFER(Message) \ - (((unsigned char *)(Message)) + Message->PerPacketInfoOffset) +#define MESSAGE_TO_DATA_BUFFER(msg) \ + (((unsigned char *)(msg)) + msg->per_pkt_info_offset) /* get pointer to contained message from NDIS_MESSAGE pointer */ -#define RNDIS_MESSAGE_PTR_TO_MESSAGE_PTR(RndisMessage) \ - ((void *) &RndisMessage->Message) +#define RNDIS_MESSAGE_PTR_TO_MESSAGE_PTR(rndis_msg) \ + ((void *) &rndis_msg->msg) /* get pointer to contained message from NDIS_MESSAGE pointer */ -#define RNDIS_MESSAGE_RAW_PTR_TO_MESSAGE_PTR(RndisMessage) \ - ((void *) RndisMessage) +#define RNDIS_MESSAGE_RAW_PTR_TO_MESSAGE_PTR(rndis_msg) \ + ((void *) rndis_msg) #endif /* _RNDIS_H_ */ diff --git a/drivers/staging/hv/rndis_filter.c b/drivers/staging/hv/rndis_filter.c index 63d24c6fadf0..53676dcbf381 100644 --- a/drivers/staging/hv/rndis_filter.c +++ b/drivers/staging/hv/rndis_filter.c @@ -136,16 +136,16 @@ static struct rndis_request *get_rndis_request(struct rndis_device *dev, } rndis_msg = &request->request_msg; - rndis_msg->NdisMessageType = msg_type; - rndis_msg->MessageLength = msg_len; + rndis_msg->ndis_msg_type = msg_type; + rndis_msg->msg_len = msg_len; /* * Set the request id. This field is always after the rndis header for * request/response packet types so we just used the SetRequest as a * template */ - set = &rndis_msg->Message.SetRequest; - set->RequestId = atomic_inc_return(&dev->new_req_id); + set = &rndis_msg->msg.set_req; + set->req_id = atomic_inc_return(&dev->new_req_id); /* Add to the request list */ spin_lock_irqsave(&dev->request_lock, flags); @@ -170,20 +170,20 @@ static void put_rndis_request(struct rndis_device *dev, static void dump_rndis_message(struct rndis_message *rndis_msg) { - switch (rndis_msg->NdisMessageType) { + switch (rndis_msg->ndis_msg_type) { case REMOTE_NDIS_PACKET_MSG: DPRINT_DBG(NETVSC, "REMOTE_NDIS_PACKET_MSG (len %u, " "data offset %u data len %u, # oob %u, " "oob offset %u, oob len %u, pkt offset %u, " "pkt len %u", - rndis_msg->MessageLength, - rndis_msg->Message.Packet.DataOffset, - rndis_msg->Message.Packet.DataLength, - rndis_msg->Message.Packet.NumOOBDataElements, - rndis_msg->Message.Packet.OOBDataOffset, - rndis_msg->Message.Packet.OOBDataLength, - rndis_msg->Message.Packet.PerPacketInfoOffset, - rndis_msg->Message.Packet.PerPacketInfoLength); + rndis_msg->msg_len, + rndis_msg->msg.pkt.data_offset, + rndis_msg->msg.pkt.data_len, + rndis_msg->msg.pkt.num_oob_data_elements, + rndis_msg->msg.pkt.oob_data_offset, + rndis_msg->msg.pkt.oob_data_len, + rndis_msg->msg.pkt.per_pkt_info_offset, + rndis_msg->msg.pkt.per_pkt_info_len); break; case REMOTE_NDIS_INITIALIZE_CMPLT: @@ -191,53 +191,53 @@ static void dump_rndis_message(struct rndis_message *rndis_msg) "(len %u, id 0x%x, status 0x%x, major %d, minor %d, " "device flags %d, max xfer size 0x%x, max pkts %u, " "pkt aligned %u)", - rndis_msg->MessageLength, - rndis_msg->Message.InitializeComplete.RequestId, - rndis_msg->Message.InitializeComplete.Status, - rndis_msg->Message.InitializeComplete.MajorVersion, - rndis_msg->Message.InitializeComplete.MinorVersion, - rndis_msg->Message.InitializeComplete.DeviceFlags, - rndis_msg->Message.InitializeComplete.MaxTransferSize, - rndis_msg->Message.InitializeComplete. - MaxPacketsPerMessage, - rndis_msg->Message.InitializeComplete. - PacketAlignmentFactor); + rndis_msg->msg_len, + rndis_msg->msg.init_complete.req_id, + rndis_msg->msg.init_complete.status, + rndis_msg->msg.init_complete.major_ver, + rndis_msg->msg.init_complete.minor_ver, + rndis_msg->msg.init_complete.dev_flags, + rndis_msg->msg.init_complete.max_xfer_size, + rndis_msg->msg.init_complete. + max_pkt_per_msg, + rndis_msg->msg.init_complete. + pkt_alignment_factor); break; case REMOTE_NDIS_QUERY_CMPLT: DPRINT_DBG(NETVSC, "REMOTE_NDIS_QUERY_CMPLT " "(len %u, id 0x%x, status 0x%x, buf len %u, " "buf offset %u)", - rndis_msg->MessageLength, - rndis_msg->Message.QueryComplete.RequestId, - rndis_msg->Message.QueryComplete.Status, - rndis_msg->Message.QueryComplete. - InformationBufferLength, - rndis_msg->Message.QueryComplete. - InformationBufferOffset); + rndis_msg->msg_len, + rndis_msg->msg.query_complete.req_id, + rndis_msg->msg.query_complete.status, + rndis_msg->msg.query_complete. + info_buflen, + rndis_msg->msg.query_complete. + info_buf_offset); break; case REMOTE_NDIS_SET_CMPLT: DPRINT_DBG(NETVSC, "REMOTE_NDIS_SET_CMPLT (len %u, id 0x%x, status 0x%x)", - rndis_msg->MessageLength, - rndis_msg->Message.SetComplete.RequestId, - rndis_msg->Message.SetComplete.Status); + rndis_msg->msg_len, + rndis_msg->msg.set_complete.req_id, + rndis_msg->msg.set_complete.status); break; case REMOTE_NDIS_INDICATE_STATUS_MSG: DPRINT_DBG(NETVSC, "REMOTE_NDIS_INDICATE_STATUS_MSG " "(len %u, status 0x%x, buf len %u, buf offset %u)", - rndis_msg->MessageLength, - rndis_msg->Message.IndicateStatus.Status, - rndis_msg->Message.IndicateStatus.StatusBufferLength, - rndis_msg->Message.IndicateStatus.StatusBufferOffset); + rndis_msg->msg_len, + rndis_msg->msg.indicate_status.status, + rndis_msg->msg.indicate_status.status_buflen, + rndis_msg->msg.indicate_status.status_buf_offset); break; default: DPRINT_DBG(NETVSC, "0x%x (len %u)", - rndis_msg->NdisMessageType, - rndis_msg->MessageLength); + rndis_msg->ndis_msg_type, + rndis_msg->msg_len); break; } } @@ -252,12 +252,12 @@ static int rndis_filter_send_request(struct rndis_device *dev, packet = &req->pkt; packet->is_data_pkt = false; - packet->total_data_buflen = req->request_msg.MessageLength; + packet->total_data_buflen = req->request_msg.msg_len; packet->page_buf_cnt = 1; packet->page_buf[0].Pfn = virt_to_phys(&req->request_msg) >> PAGE_SHIFT; - packet->page_buf[0].Length = req->request_msg.MessageLength; + packet->page_buf[0].Length = req->request_msg.msg_len; packet->page_buf[0].Offset = (unsigned long)&req->request_msg & (PAGE_SIZE - 1); @@ -283,15 +283,15 @@ static void rndis_filter_receive_response(struct rndis_device *dev, * All request/response message contains RequestId as the 1st * field */ - if (request->request_msg.Message.InitializeRequest.RequestId - == resp->Message.InitializeComplete.RequestId) { + if (request->request_msg.msg.init_req.req_id + == resp->msg.init_complete.req_id) { DPRINT_DBG(NETVSC, "found rndis request for " "this response (id 0x%x req type 0x%x res " "type 0x%x)", - request->request_msg.Message. - InitializeRequest.RequestId, - request->request_msg.NdisMessageType, - resp->NdisMessageType); + request->request_msg.msg. + init_req.req_id, + request->request_msg.ndis_msg_type, + resp->ndis_msg_type); found = true; break; @@ -300,23 +300,23 @@ static void rndis_filter_receive_response(struct rndis_device *dev, spin_unlock_irqrestore(&dev->request_lock, flags); if (found) { - if (resp->MessageLength <= sizeof(struct rndis_message)) { + if (resp->msg_len <= sizeof(struct rndis_message)) { memcpy(&request->response_msg, resp, - resp->MessageLength); + resp->msg_len); } else { DPRINT_ERR(NETVSC, "rndis response buffer overflow " "detected (size %u max %zu)", - resp->MessageLength, + resp->msg_len, sizeof(struct rndis_filter_packet)); - if (resp->NdisMessageType == + if (resp->ndis_msg_type == REMOTE_NDIS_RESET_CMPLT) { /* does not have a request id field */ - request->response_msg.Message.ResetComplete. - Status = STATUS_BUFFER_OVERFLOW; + request->response_msg.msg.reset_complete. + status = STATUS_BUFFER_OVERFLOW; } else { - request->response_msg.Message. - InitializeComplete.Status = + request->response_msg.msg. + init_complete.status = STATUS_BUFFER_OVERFLOW; } } @@ -325,8 +325,8 @@ static void rndis_filter_receive_response(struct rndis_device *dev, } else { DPRINT_ERR(NETVSC, "no rndis request found for this response " "(id 0x%x res type 0x%x)", - resp->Message.InitializeComplete.RequestId, - resp->NdisMessageType); + resp->msg.init_complete.req_id, + resp->ndis_msg_type); } } @@ -334,12 +334,12 @@ static void rndis_filter_receive_indicate_status(struct rndis_device *dev, struct rndis_message *resp) { struct rndis_indicate_status *indicate = - &resp->Message.IndicateStatus; + &resp->msg.indicate_status; - if (indicate->Status == RNDIS_STATUS_MEDIA_CONNECT) { + if (indicate->status == RNDIS_STATUS_MEDIA_CONNECT) { rndis_filter.inner_drv.link_status_change( dev->net_dev->dev, 1); - } else if (indicate->Status == RNDIS_STATUS_MEDIA_DISCONNECT) { + } else if (indicate->status == RNDIS_STATUS_MEDIA_DISCONNECT) { rndis_filter.inner_drv.link_status_change( dev->net_dev->dev, 0); } else { @@ -360,7 +360,7 @@ static void rndis_filter_receive_data(struct rndis_device *dev, /* ASSERT(Packet->PageBuffers[0].Length > */ /* RNDIS_MESSAGE_SIZE(struct rndis_packet)); */ - rndis_pkt = &msg->Message.Packet; + rndis_pkt = &msg->msg.pkt; /* * FIXME: Handle multiple rndis pkt msgs that maybe enclosed in this @@ -368,7 +368,7 @@ static void rndis_filter_receive_data(struct rndis_device *dev, */ /* Remove the rndis header and pass it back up the stack */ - data_offset = RNDIS_HEADER_SIZE + rndis_pkt->DataOffset; + data_offset = RNDIS_HEADER_SIZE + rndis_pkt->data_offset; pkt->total_data_buflen -= data_offset; pkt->page_buf[0].Offset += data_offset; @@ -418,36 +418,36 @@ static int rndis_filter_receive(struct hv_device *dev, * range shows 52 bytes * */ #if 0 - if (pkt->total_data_buflen != rndis_hdr->MessageLength) { + if (pkt->total_data_buflen != rndis_hdr->msg_len) { kunmap_atomic(rndis_hdr - pkt->page_buf[0].Offset, KM_IRQ0); DPRINT_ERR(NETVSC, "invalid rndis message? (expected %u " "bytes got %u)...dropping this message!", - rndis_hdr->MessageLength, + rndis_hdr->msg_len, pkt->total_data_buflen); return -1; } #endif - if ((rndis_hdr->NdisMessageType != REMOTE_NDIS_PACKET_MSG) && - (rndis_hdr->MessageLength > sizeof(struct rndis_message))) { + if ((rndis_hdr->ndis_msg_type != REMOTE_NDIS_PACKET_MSG) && + (rndis_hdr->msg_len > sizeof(struct rndis_message))) { DPRINT_ERR(NETVSC, "incoming rndis message buffer overflow " "detected (got %u, max %zu)...marking it an error!", - rndis_hdr->MessageLength, + rndis_hdr->msg_len, sizeof(struct rndis_message)); } memcpy(&rndis_msg, rndis_hdr, - (rndis_hdr->MessageLength > sizeof(struct rndis_message)) ? + (rndis_hdr->msg_len > sizeof(struct rndis_message)) ? sizeof(struct rndis_message) : - rndis_hdr->MessageLength); + rndis_hdr->msg_len); kunmap_atomic(rndis_hdr - pkt->page_buf[0].Offset, KM_IRQ0); dump_rndis_message(&rndis_msg); - switch (rndis_msg.NdisMessageType) { + switch (rndis_msg.ndis_msg_type) { case REMOTE_NDIS_PACKET_MSG: /* data msg */ rndis_filter_receive_data(rndis_dev, &rndis_msg, pkt); @@ -468,8 +468,8 @@ static int rndis_filter_receive(struct hv_device *dev, break; default: DPRINT_ERR(NETVSC, "unhandled rndis message (type %u len %u)", - rndis_msg.NdisMessageType, - rndis_msg.MessageLength); + rndis_msg.ndis_msg_type, + rndis_msg.msg_len); break; } @@ -497,11 +497,11 @@ static int rndis_filter_query_device(struct rndis_device *dev, u32 oid, } /* Setup the rndis query */ - query = &request->request_msg.Message.QueryRequest; - query->Oid = oid; - query->InformationBufferOffset = sizeof(struct rndis_query_request); - query->InformationBufferLength = 0; - query->DeviceVcHandle = 0; + query = &request->request_msg.msg.query_req; + query->oid = oid; + query->info_buf_offset = sizeof(struct rndis_query_request); + query->info_buflen = 0; + query->dev_vc_handle = 0; ret = rndis_filter_send_request(dev, request); if (ret != 0) @@ -510,19 +510,19 @@ static int rndis_filter_query_device(struct rndis_device *dev, u32 oid, osd_waitevent_wait(request->waitevent); /* Copy the response back */ - query_complete = &request->response_msg.Message.QueryComplete; + query_complete = &request->response_msg.msg.query_complete; - if (query_complete->InformationBufferLength > inresult_size) { + if (query_complete->info_buflen > inresult_size) { ret = -1; goto Cleanup; } memcpy(result, (void *)((unsigned long)query_complete + - query_complete->InformationBufferOffset), - query_complete->InformationBufferLength); + query_complete->info_buf_offset), + query_complete->info_buflen); - *result_size = query_complete->InformationBufferLength; + *result_size = query_complete->info_buflen; Cleanup: if (request) @@ -570,10 +570,10 @@ static int rndis_filter_set_packet_filter(struct rndis_device *dev, } /* Setup the rndis set */ - set = &request->request_msg.Message.SetRequest; - set->Oid = RNDIS_OID_GEN_CURRENT_PACKET_FILTER; - set->InformationBufferLength = sizeof(u32); - set->InformationBufferOffset = sizeof(struct rndis_set_request); + set = &request->request_msg.msg.set_req; + set->oid = RNDIS_OID_GEN_CURRENT_PACKET_FILTER; + set->info_buflen = sizeof(u32); + set->info_buf_offset = sizeof(struct rndis_set_request); memcpy((void *)(unsigned long)set + sizeof(struct rndis_set_request), &new_filter, sizeof(u32)); @@ -594,8 +594,8 @@ static int rndis_filter_set_packet_filter(struct rndis_device *dev, } else { if (ret > 0) ret = 0; - set_complete = &request->response_msg.Message.SetComplete; - status = set_complete->Status; + set_complete = &request->response_msg.msg.set_complete; + status = set_complete->status; } Cleanup: @@ -661,11 +661,11 @@ static int rndis_filter_init_device(struct rndis_device *dev) } /* Setup the rndis set */ - init = &request->request_msg.Message.InitializeRequest; - init->MajorVersion = RNDIS_MAJOR_VERSION; - init->MinorVersion = RNDIS_MINOR_VERSION; + init = &request->request_msg.msg.init_req; + init->major_ver = RNDIS_MAJOR_VERSION; + init->minor_ver = RNDIS_MINOR_VERSION; /* FIXME: Use 1536 - rounded ethernet frame size */ - init->MaxTransferSize = 2048; + init->max_xfer_size = 2048; dev->state = RNDIS_DEV_INITIALIZING; @@ -677,8 +677,8 @@ static int rndis_filter_init_device(struct rndis_device *dev) osd_waitevent_wait(request->waitevent); - init_complete = &request->response_msg.Message.InitializeComplete; - status = init_complete->Status; + init_complete = &request->response_msg.msg.init_complete; + status = init_complete->status; if (status == RNDIS_STATUS_SUCCESS) { dev->state = RNDIS_DEV_INITIALIZED; ret = 0; @@ -706,8 +706,8 @@ static void rndis_filter_halt_device(struct rndis_device *dev) goto Cleanup; /* Setup the rndis set */ - halt = &request->request_msg.Message.HaltRequest; - halt->RequestId = atomic_inc_return(&dev->new_req_id); + halt = &request->request_msg.msg.halt_req; + halt->req_id = atomic_inc_return(&dev->new_req_id); /* Ignore return since this msg is optional. */ rndis_filter_send_request(dev, request); @@ -875,13 +875,13 @@ static int rndis_filter_send(struct hv_device *dev, rndisMessage = &filterPacket->msg; rndisMessageSize = RNDIS_MESSAGE_SIZE(struct rndis_packet); - rndisMessage->NdisMessageType = REMOTE_NDIS_PACKET_MSG; - rndisMessage->MessageLength = pkt->total_data_buflen + + rndisMessage->ndis_msg_type = REMOTE_NDIS_PACKET_MSG; + rndisMessage->msg_len = pkt->total_data_buflen + rndisMessageSize; - rndisPacket = &rndisMessage->Message.Packet; - rndisPacket->DataOffset = sizeof(struct rndis_packet); - rndisPacket->DataLength = pkt->total_data_buflen; + rndisPacket = &rndisMessage->msg.pkt; + rndisPacket->data_offset = sizeof(struct rndis_packet); + rndisPacket->data_len = pkt->total_data_buflen; pkt->is_data_pkt = true; pkt->page_buf[0].Pfn = virt_to_phys(rndisMessage) >> PAGE_SHIFT; -- cgit v1.2.3 From 7a39d8b82165462729d09066bddb395a19025acd Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Fri, 26 Nov 2010 08:57:31 +0100 Subject: firewire: ohci: Asynchronous Reception rewrite Move the AR DMA descriptors out of the buffer pages, and map the buffer pages linearly into the kernel's address space. This allows the driver to ignore any page boundaries in the DMA data and thus to avoid any copying around of packet payloads. This fixes the bug where S800 packets that are so big (> 4080 bytes) that they can be split over three pages were not handled correctly. Due to the changed algorithm, we can now use arbitrarily many buffer pages, which improves performance because the controller can more easily unload its DMA FIFO. Furthermore, using streaming DMA mappings should improve perfomance on architectures where coherent DMA mappings are not cacheable. Even on other architectures, the caching behaviour should be improved slightly because the CPU no longer writes to the buffer pages. v2: Detect the last filled buffer page by searching the descriptor's residual count value fields in order (like in the old code), instead of going backwards through the transfer status fields; it looks as if some controllers do not set the latter correctly. v3: Fix an old resume bug that would now make the handler run into a BUG_ON, and replace that check with more useful error handling. Increase the buffer size for better performance with non-TI chips. Signed-off-by: Clemens Ladisch Maxim Levitsky writes: Works almost perfectly. I can still see RCODE_BUSY errors sometimes, not very often though. 64K here eliminates these errors completely. This is most likely due to nouveau drivers and lowest perf level I use to lower card temperature. That increases latencies too much I think. Besides that the IO is just perfect. Tested-by: Maxim Levitsky Signed-off-by: Stefan Richter --- drivers/firewire/Kconfig | 2 +- drivers/firewire/ohci.c | 411 ++++++++++++++++++++++++++++++++--------------- 2 files changed, 278 insertions(+), 135 deletions(-) diff --git a/drivers/firewire/Kconfig b/drivers/firewire/Kconfig index 40a222e19b2d..68f942cb30f2 100644 --- a/drivers/firewire/Kconfig +++ b/drivers/firewire/Kconfig @@ -19,7 +19,7 @@ config FIREWIRE config FIREWIRE_OHCI tristate "OHCI-1394 controllers" - depends on PCI && FIREWIRE + depends on PCI && FIREWIRE && MMU help Enable this driver if you have a FireWire controller based on the OHCI specification. For all practical purposes, this diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c index e3c8b60bd86b..be0a01d8cef3 100644 --- a/drivers/firewire/ohci.c +++ b/drivers/firewire/ohci.c @@ -40,6 +40,7 @@ #include #include #include +#include #include #include @@ -80,17 +81,23 @@ struct descriptor { #define COMMAND_PTR(regs) ((regs) + 12) #define CONTEXT_MATCH(regs) ((regs) + 16) -struct ar_buffer { - struct descriptor descriptor; - struct ar_buffer *next; - __le32 data[0]; -}; +#define AR_BUFFER_SIZE (32*1024) +#define AR_BUFFERS_MIN DIV_ROUND_UP(AR_BUFFER_SIZE, PAGE_SIZE) +/* we need at least two pages for proper list management */ +#define AR_BUFFERS (AR_BUFFERS_MIN >= 2 ? AR_BUFFERS_MIN : 2) + +#define MAX_ASYNC_PAYLOAD 4096 +#define MAX_AR_PACKET_SIZE (16 + MAX_ASYNC_PAYLOAD + 4) +#define AR_WRAPAROUND_PAGES DIV_ROUND_UP(MAX_AR_PACKET_SIZE, PAGE_SIZE) struct ar_context { struct fw_ohci *ohci; - struct ar_buffer *current_buffer; - struct ar_buffer *last_buffer; + struct page *pages[AR_BUFFERS]; + void *buffer; + struct descriptor *descriptors; + dma_addr_t descriptors_bus; void *pointer; + unsigned int last_buffer_index; u32 regs; struct tasklet_struct tasklet; }; @@ -594,59 +601,155 @@ static int ohci_update_phy_reg(struct fw_card *card, int addr, return ret; } -static void ar_context_link_page(struct ar_context *ctx, - struct ar_buffer *ab, dma_addr_t ab_bus) +static inline dma_addr_t ar_buffer_bus(struct ar_context *ctx, unsigned int i) +{ + return page_private(ctx->pages[i]); +} + +static void ar_context_link_page(struct ar_context *ctx, unsigned int index) { - size_t offset; + struct descriptor *d; - ab->next = NULL; - memset(&ab->descriptor, 0, sizeof(ab->descriptor)); - ab->descriptor.control = cpu_to_le16(DESCRIPTOR_INPUT_MORE | - DESCRIPTOR_STATUS | - DESCRIPTOR_BRANCH_ALWAYS); - offset = offsetof(struct ar_buffer, data); - ab->descriptor.req_count = cpu_to_le16(PAGE_SIZE - offset); - ab->descriptor.data_address = cpu_to_le32(ab_bus + offset); - ab->descriptor.res_count = cpu_to_le16(PAGE_SIZE - offset); - ab->descriptor.branch_address = 0; + d = &ctx->descriptors[index]; + d->branch_address &= cpu_to_le32(~0xf); + d->res_count = cpu_to_le16(PAGE_SIZE); + d->transfer_status = 0; wmb(); /* finish init of new descriptors before branch_address update */ - ctx->last_buffer->descriptor.branch_address = cpu_to_le32(ab_bus | 1); - ctx->last_buffer->next = ab; - ctx->last_buffer = ab; + d = &ctx->descriptors[ctx->last_buffer_index]; + d->branch_address |= cpu_to_le32(1); + + ctx->last_buffer_index = index; reg_write(ctx->ohci, CONTROL_SET(ctx->regs), CONTEXT_WAKE); flush_writes(ctx->ohci); } -static int ar_context_add_page(struct ar_context *ctx) +static void ar_context_release(struct ar_context *ctx) { - struct device *dev = ctx->ohci->card.device; - struct ar_buffer *ab; - dma_addr_t uninitialized_var(ab_bus); + unsigned int i; - ab = dma_alloc_coherent(dev, PAGE_SIZE, &ab_bus, GFP_ATOMIC); - if (ab == NULL) - return -ENOMEM; + if (ctx->descriptors) + dma_free_coherent(ctx->ohci->card.device, + AR_BUFFERS * sizeof(struct descriptor), + ctx->descriptors, ctx->descriptors_bus); - ar_context_link_page(ctx, ab, ab_bus); + if (ctx->buffer) + vm_unmap_ram(ctx->buffer, AR_BUFFERS + AR_WRAPAROUND_PAGES); - return 0; + for (i = 0; i < AR_BUFFERS; i++) + if (ctx->pages[i]) { + dma_unmap_page(ctx->ohci->card.device, + ar_buffer_bus(ctx, i), + PAGE_SIZE, DMA_FROM_DEVICE); + __free_page(ctx->pages[i]); + } } -static void ar_context_release(struct ar_context *ctx) +static void ar_context_abort(struct ar_context *ctx, const char *error_msg) { - struct ar_buffer *ab, *ab_next; - size_t offset; - dma_addr_t ab_bus; + if (reg_read(ctx->ohci, CONTROL_CLEAR(ctx->regs)) & CONTEXT_RUN) { + reg_write(ctx->ohci, CONTROL_CLEAR(ctx->regs), CONTEXT_RUN); + flush_writes(ctx->ohci); - for (ab = ctx->current_buffer; ab; ab = ab_next) { - ab_next = ab->next; - offset = offsetof(struct ar_buffer, data); - ab_bus = le32_to_cpu(ab->descriptor.data_address) - offset; - dma_free_coherent(ctx->ohci->card.device, PAGE_SIZE, - ab, ab_bus); + fw_error("AR error: %s; DMA stopped\n", error_msg); } + /* FIXME: restart? */ +} + +static inline unsigned int ar_next_buffer_index(unsigned int index) +{ + return (index + 1) % AR_BUFFERS; +} + +static inline unsigned int ar_prev_buffer_index(unsigned int index) +{ + return (index - 1 + AR_BUFFERS) % AR_BUFFERS; +} + +static inline unsigned int ar_first_buffer_index(struct ar_context *ctx) +{ + return ar_next_buffer_index(ctx->last_buffer_index); +} + +/* + * We search for the buffer that contains the last AR packet DMA data written + * by the controller. + */ +static unsigned int ar_search_last_active_buffer(struct ar_context *ctx, + unsigned int *buffer_offset) +{ + unsigned int i, next_i, last = ctx->last_buffer_index; + __le16 res_count, next_res_count; + + i = ar_first_buffer_index(ctx); + res_count = ACCESS_ONCE(ctx->descriptors[i].res_count); + + /* A buffer that is not yet completely filled must be the last one. */ + while (i != last && res_count == 0) { + + /* Peek at the next descriptor. */ + next_i = ar_next_buffer_index(i); + rmb(); /* read descriptors in order */ + next_res_count = ACCESS_ONCE( + ctx->descriptors[next_i].res_count); + /* + * If the next descriptor is still empty, we must stop at this + * descriptor. + */ + if (next_res_count == cpu_to_le16(PAGE_SIZE)) { + /* + * The exception is when the DMA data for one packet is + * split over three buffers; in this case, the middle + * buffer's descriptor might be never updated by the + * controller and look still empty, and we have to peek + * at the third one. + */ + if (MAX_AR_PACKET_SIZE > PAGE_SIZE && i != last) { + next_i = ar_next_buffer_index(next_i); + rmb(); + next_res_count = ACCESS_ONCE( + ctx->descriptors[next_i].res_count); + if (next_res_count != cpu_to_le16(PAGE_SIZE)) + goto next_buffer_is_active; + } + + break; + } + +next_buffer_is_active: + i = next_i; + res_count = next_res_count; + } + + rmb(); /* read res_count before the DMA data */ + + *buffer_offset = PAGE_SIZE - le16_to_cpu(res_count); + if (*buffer_offset > PAGE_SIZE) { + *buffer_offset = 0; + ar_context_abort(ctx, "corrupted descriptor"); + } + + return i; +} + +static void ar_sync_buffers_for_cpu(struct ar_context *ctx, + unsigned int end_buffer_index, + unsigned int end_buffer_offset) +{ + unsigned int i; + + i = ar_first_buffer_index(ctx); + while (i != end_buffer_index) { + dma_sync_single_for_cpu(ctx->ohci->card.device, + ar_buffer_bus(ctx, i), + PAGE_SIZE, DMA_FROM_DEVICE); + i = ar_next_buffer_index(i); + } + if (end_buffer_offset > 0) + dma_sync_single_for_cpu(ctx->ohci->card.device, + ar_buffer_bus(ctx, i), + end_buffer_offset, DMA_FROM_DEVICE); } #if defined(CONFIG_PPC_PMAC) && defined(CONFIG_PPC32) @@ -689,6 +792,10 @@ static __le32 *handle_ar_packet(struct ar_context *ctx, __le32 *buffer) p.header[3] = cond_le32_to_cpu(buffer[3]); p.header_length = 16; p.payload_length = p.header[3] >> 16; + if (p.payload_length > MAX_ASYNC_PAYLOAD) { + ar_context_abort(ctx, "invalid packet length"); + return NULL; + } break; case TCODE_WRITE_RESPONSE: @@ -699,9 +806,8 @@ static __le32 *handle_ar_packet(struct ar_context *ctx, __le32 *buffer) break; default: - /* FIXME: Stop context, discard everything, and restart? */ - p.header_length = 0; - p.payload_length = 0; + ar_context_abort(ctx, "invalid tcode"); + return NULL; } p.payload = (void *) buffer + p.header_length; @@ -751,121 +857,152 @@ static __le32 *handle_ar_packet(struct ar_context *ctx, __le32 *buffer) return buffer + length + 1; } +static void *handle_ar_packets(struct ar_context *ctx, void *p, void *end) +{ + void *next; + + while (p < end) { + next = handle_ar_packet(ctx, p); + if (!next) + return p; + p = next; + } + + return p; +} + +static void ar_recycle_buffers(struct ar_context *ctx, unsigned int end_buffer) +{ + unsigned int i; + + i = ar_first_buffer_index(ctx); + while (i != end_buffer) { + dma_sync_single_for_device(ctx->ohci->card.device, + ar_buffer_bus(ctx, i), + PAGE_SIZE, DMA_FROM_DEVICE); + ar_context_link_page(ctx, i); + i = ar_next_buffer_index(i); + } +} + static void ar_context_tasklet(unsigned long data) { struct ar_context *ctx = (struct ar_context *)data; - struct ar_buffer *ab; - struct descriptor *d; - void *buffer, *end; - __le16 res_count; + unsigned int end_buffer_index, end_buffer_offset; + void *p, *end; - ab = ctx->current_buffer; - d = &ab->descriptor; + p = ctx->pointer; + if (!p) + return; - res_count = ACCESS_ONCE(d->res_count); - if (res_count == 0) { - size_t size, size2, rest, pktsize, size3, offset; - dma_addr_t start_bus; - void *start; + end_buffer_index = ar_search_last_active_buffer(ctx, + &end_buffer_offset); + ar_sync_buffers_for_cpu(ctx, end_buffer_index, end_buffer_offset); + end = ctx->buffer + end_buffer_index * PAGE_SIZE + end_buffer_offset; + if (end_buffer_index < ar_first_buffer_index(ctx)) { /* - * This descriptor is finished and we may have a - * packet split across this and the next buffer. We - * reuse the page for reassembling the split packet. + * The filled part of the overall buffer wraps around; handle + * all packets up to the buffer end here. If the last packet + * wraps around, its tail will be visible after the buffer end + * because the buffer start pages are mapped there again. */ + void *buffer_end = ctx->buffer + AR_BUFFERS * PAGE_SIZE; + p = handle_ar_packets(ctx, p, buffer_end); + if (p < buffer_end) + goto error; + /* adjust p to point back into the actual buffer */ + p -= AR_BUFFERS * PAGE_SIZE; + } - offset = offsetof(struct ar_buffer, data); - start = ab; - start_bus = le32_to_cpu(ab->descriptor.data_address) - offset; - buffer = ab->data; - - ab = ab->next; - d = &ab->descriptor; - size = start + PAGE_SIZE - ctx->pointer; - /* valid buffer data in the next page */ - rest = le16_to_cpu(d->req_count) - le16_to_cpu(d->res_count); - /* what actually fits in this page */ - size2 = min(rest, (size_t)PAGE_SIZE - offset - size); - memmove(buffer, ctx->pointer, size); - memcpy(buffer + size, ab->data, size2); - - while (size > 0) { - void *next = handle_ar_packet(ctx, buffer); - pktsize = next - buffer; - if (pktsize >= size) { - /* - * We have handled all the data that was - * originally in this page, so we can now - * continue in the next page. - */ - buffer = next; - break; - } - /* move the next packet to the start of the buffer */ - memmove(buffer, next, size + size2 - pktsize); - size -= pktsize; - /* fill up this page again */ - size3 = min(rest - size2, - (size_t)PAGE_SIZE - offset - size - size2); - memcpy(buffer + size + size2, - (void *) ab->data + size2, size3); - size2 += size3; - } - - if (rest > 0) { - /* handle the packets that are fully in the next page */ - buffer = (void *) ab->data + - (buffer - (start + offset + size)); - end = (void *) ab->data + rest; + p = handle_ar_packets(ctx, p, end); + if (p != end) { + if (p > end) + ar_context_abort(ctx, "inconsistent descriptor"); + goto error; + } - while (buffer < end) - buffer = handle_ar_packet(ctx, buffer); + ctx->pointer = p; + ar_recycle_buffers(ctx, end_buffer_index); - ctx->current_buffer = ab; - ctx->pointer = end; + return; - ar_context_link_page(ctx, start, start_bus); - } else { - ctx->pointer = start + PAGE_SIZE; - } - } else { - buffer = ctx->pointer; - ctx->pointer = end = - (void *) ab + PAGE_SIZE - le16_to_cpu(res_count); - - while (buffer < end) - buffer = handle_ar_packet(ctx, buffer); - } +error: + ctx->pointer = NULL; } static int ar_context_init(struct ar_context *ctx, struct fw_ohci *ohci, u32 regs) { - struct ar_buffer ab; + unsigned int i; + dma_addr_t dma_addr; + struct page *pages[AR_BUFFERS + AR_WRAPAROUND_PAGES]; + struct descriptor *d; ctx->regs = regs; ctx->ohci = ohci; - ctx->last_buffer = &ab; tasklet_init(&ctx->tasklet, ar_context_tasklet, (unsigned long)ctx); - ar_context_add_page(ctx); - ar_context_add_page(ctx); - ctx->current_buffer = ab.next; - ctx->pointer = ctx->current_buffer->data; + for (i = 0; i < AR_BUFFERS; i++) { + ctx->pages[i] = alloc_page(GFP_KERNEL | GFP_DMA32); + if (!ctx->pages[i]) + goto out_of_memory; + dma_addr = dma_map_page(ohci->card.device, ctx->pages[i], + 0, PAGE_SIZE, DMA_FROM_DEVICE); + if (dma_mapping_error(ohci->card.device, dma_addr)) { + __free_page(ctx->pages[i]); + ctx->pages[i] = NULL; + goto out_of_memory; + } + set_page_private(ctx->pages[i], dma_addr); + } + + for (i = 0; i < AR_BUFFERS; i++) + pages[i] = ctx->pages[i]; + for (i = 0; i < AR_WRAPAROUND_PAGES; i++) + pages[AR_BUFFERS + i] = ctx->pages[i]; + ctx->buffer = vm_map_ram(pages, AR_BUFFERS + AR_WRAPAROUND_PAGES, + -1, PAGE_KERNEL_RO); + if (!ctx->buffer) + goto out_of_memory; + + ctx->descriptors = + dma_alloc_coherent(ohci->card.device, + AR_BUFFERS * sizeof(struct descriptor), + &ctx->descriptors_bus, + GFP_KERNEL); + if (!ctx->descriptors) + goto out_of_memory; + + for (i = 0; i < AR_BUFFERS; i++) { + d = &ctx->descriptors[i]; + d->req_count = cpu_to_le16(PAGE_SIZE); + d->control = cpu_to_le16(DESCRIPTOR_INPUT_MORE | + DESCRIPTOR_STATUS | + DESCRIPTOR_BRANCH_ALWAYS); + d->data_address = cpu_to_le32(ar_buffer_bus(ctx, i)); + d->branch_address = cpu_to_le32(ctx->descriptors_bus + + ar_next_buffer_index(i) * sizeof(struct descriptor)); + } return 0; + +out_of_memory: + ar_context_release(ctx); + + return -ENOMEM; } static void ar_context_run(struct ar_context *ctx) { - struct ar_buffer *ab = ctx->current_buffer; - dma_addr_t ab_bus; - size_t offset; + unsigned int i; + + for (i = 0; i < AR_BUFFERS; i++) + ar_context_link_page(ctx, i); - offset = offsetof(struct ar_buffer, data); - ab_bus = le32_to_cpu(ab->descriptor.data_address) - offset; + ctx->pointer = ctx->buffer; - reg_write(ctx->ohci, COMMAND_PTR(ctx->regs), ab_bus | 1); + reg_write(ctx->ohci, COMMAND_PTR(ctx->regs), ctx->descriptors_bus | 1); reg_write(ctx->ohci, CONTROL_SET(ctx->regs), CONTEXT_RUN); flush_writes(ctx->ohci); } @@ -2955,11 +3092,15 @@ static int __devinit pci_probe(struct pci_dev *dev, if (param_quirks) ohci->quirks = param_quirks; - ar_context_init(&ohci->ar_request_ctx, ohci, - OHCI1394_AsReqRcvContextControlSet); + err = ar_context_init(&ohci->ar_request_ctx, ohci, + OHCI1394_AsReqRcvContextControlSet); + if (err < 0) + goto fail_iounmap; - ar_context_init(&ohci->ar_response_ctx, ohci, - OHCI1394_AsRspRcvContextControlSet); + err = ar_context_init(&ohci->ar_response_ctx, ohci, + OHCI1394_AsRspRcvContextControlSet); + if (err < 0) + goto fail_arreq_ctx; context_init(&ohci->at_request_ctx, ohci, OHCI1394_AsReqTrContextControlSet, handle_at_packet); @@ -3024,7 +3165,9 @@ static int __devinit pci_probe(struct pci_dev *dev, context_release(&ohci->at_response_ctx); context_release(&ohci->at_request_ctx); ar_context_release(&ohci->ar_response_ctx); + fail_arreq_ctx: ar_context_release(&ohci->ar_request_ctx); + fail_iounmap: pci_iounmap(dev, ohci->registers); fail_iomem: pci_release_region(dev, 0); -- cgit v1.2.3 From c088ab30ebf184afae01d919c77cebcfdce39df3 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Tue, 30 Nov 2010 08:24:01 +0100 Subject: firewire: ohci: fix AT context initialization error handling Add proper error handling for the context_init() calls. Signed-off-by: Clemens Ladisch Signed-off-by: Stefan Richter --- drivers/firewire/ohci.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c index be0a01d8cef3..3775364f1b51 100644 --- a/drivers/firewire/ohci.c +++ b/drivers/firewire/ohci.c @@ -3102,11 +3102,15 @@ static int __devinit pci_probe(struct pci_dev *dev, if (err < 0) goto fail_arreq_ctx; - context_init(&ohci->at_request_ctx, ohci, - OHCI1394_AsReqTrContextControlSet, handle_at_packet); + err = context_init(&ohci->at_request_ctx, ohci, + OHCI1394_AsReqTrContextControlSet, handle_at_packet); + if (err < 0) + goto fail_arrsp_ctx; - context_init(&ohci->at_response_ctx, ohci, - OHCI1394_AsRspTrContextControlSet, handle_at_packet); + err = context_init(&ohci->at_response_ctx, ohci, + OHCI1394_AsRspTrContextControlSet, handle_at_packet); + if (err < 0) + goto fail_atreq_ctx; reg_write(ohci, OHCI1394_IsoRecvIntMaskSet, ~0); ohci->ir_context_channels = ~0ULL; @@ -3163,7 +3167,9 @@ static int __devinit pci_probe(struct pci_dev *dev, kfree(ohci->ir_context_list); kfree(ohci->it_context_list); context_release(&ohci->at_response_ctx); + fail_atreq_ctx: context_release(&ohci->at_request_ctx); + fail_arrsp_ctx: ar_context_release(&ohci->ar_response_ctx); fail_arreq_ctx: ar_context_release(&ohci->ar_request_ctx); -- cgit v1.2.3 From e597e9898abe45beff4696159c7fe5c96f53e581 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Tue, 30 Nov 2010 08:24:19 +0100 Subject: firewire: ohci: flush MMIO writes in the interrupt handler Make sure that interrupt event clear bit writes are executed before the interrupt handler returns. Signed-off-by: Clemens Ladisch Signed-off-by: Stefan Richter --- drivers/firewire/ohci.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c index 3775364f1b51..276324d741df 100644 --- a/drivers/firewire/ohci.c +++ b/drivers/firewire/ohci.c @@ -1856,7 +1856,8 @@ static irqreturn_t irq_handler(int irq, void *data) spin_lock(&ohci->lock); update_bus_time(ohci); spin_unlock(&ohci->lock); - } + } else + flush_writes(ohci); return IRQ_HANDLED; } -- cgit v1.2.3 From 8327b37b18addfc6f8cf41a2f1a4490b656377b9 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Tue, 30 Nov 2010 08:24:32 +0100 Subject: firewire: ohci: properly clear posted write errors To remove the error information from the controller's queue and to allow more posted writes, the driver has to read the failed posted write address before clearing the postedWriteErr interrupt bit. Signed-off-by: Clemens Ladisch (Stefan R:) The spec is somewhat fuzzy about the actual requirements. To err on the safe side, let's do these two read accesses. Signed-off-by: Stefan Richter --- drivers/firewire/ohci.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c index 276324d741df..0031ec6e1f00 100644 --- a/drivers/firewire/ohci.c +++ b/drivers/firewire/ohci.c @@ -1790,8 +1790,12 @@ static irqreturn_t irq_handler(int irq, void *data) if (!event || !~event) return IRQ_NONE; - /* busReset must not be cleared yet, see OHCI 1.1 clause 7.2.3.2 */ - reg_write(ohci, OHCI1394_IntEventClear, event & ~OHCI1394_busReset); + /* + * busReset and postedWriteErr must not be cleared yet + * (OHCI 1.1 clauses 7.2.3.2 and 13.2.8.1) + */ + reg_write(ohci, OHCI1394_IntEventClear, + event & ~(OHCI1394_busReset | OHCI1394_postedWriteErr)); log_irqs(event); if (event & OHCI1394_selfIDComplete) @@ -1831,8 +1835,13 @@ static irqreturn_t irq_handler(int irq, void *data) fw_error("Register access failure - " "please notify linux1394-devel@lists.sf.net\n"); - if (unlikely(event & OHCI1394_postedWriteErr)) + if (unlikely(event & OHCI1394_postedWriteErr)) { + reg_read(ohci, OHCI1394_PostedWriteAddressHi); + reg_read(ohci, OHCI1394_PostedWriteAddressLo); + reg_write(ohci, OHCI1394_IntEventClear, + OHCI1394_postedWriteErr); fw_error("PCI posted write error\n"); + } if (unlikely(event & OHCI1394_cycleTooLong)) { if (printk_ratelimit()) -- cgit v1.2.3 From 5b06db166c4d38638980283505259fa165d4f369 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Tue, 30 Nov 2010 08:24:47 +0100 Subject: firewire: make PHY packet header format consistent Change the header of PHY packets to be sent to include a pseudo transaction code. This makes the header consistent with that of received PHY packets, and allows at_context_queue_packet() and log_ar_at_event() to see the packet type directly instead of having to deduce it from the header length or even from the header contents. Signed-off-by: Clemens Ladisch Signed-off-by: Stefan Richter --- drivers/firewire/core-cdev.c | 7 +++--- drivers/firewire/core-transaction.c | 7 +++--- drivers/firewire/core.h | 4 +++- drivers/firewire/ohci.c | 44 ++++++++++++++++++------------------- 4 files changed, 33 insertions(+), 29 deletions(-) diff --git a/drivers/firewire/core-cdev.c b/drivers/firewire/core-cdev.c index 14bb7b7b5dd7..48ae712e2101 100644 --- a/drivers/firewire/core-cdev.c +++ b/drivers/firewire/core-cdev.c @@ -1501,9 +1501,10 @@ static int ioctl_send_phy_packet(struct client *client, union ioctl_arg *arg) e->client = client; e->p.speed = SCODE_100; e->p.generation = a->generation; - e->p.header[0] = a->data[0]; - e->p.header[1] = a->data[1]; - e->p.header_length = 8; + e->p.header[0] = TCODE_LINK_INTERNAL << 4; + e->p.header[1] = a->data[0]; + e->p.header[2] = a->data[1]; + e->p.header_length = 12; e->p.callback = outbound_phy_packet_callback; e->phy_packet.closure = a->closure; e->phy_packet.type = FW_CDEV_EVENT_PHY_PACKET_SENT; diff --git a/drivers/firewire/core-transaction.c b/drivers/firewire/core-transaction.c index ad864d8cd5e4..9e81cc54abd2 100644 --- a/drivers/firewire/core-transaction.c +++ b/drivers/firewire/core-transaction.c @@ -423,7 +423,8 @@ static void transmit_phy_packet_callback(struct fw_packet *packet, } static struct fw_packet phy_config_packet = { - .header_length = 8, + .header_length = 12, + .header[0] = TCODE_LINK_INTERNAL << 4, .payload_length = 0, .speed = SCODE_100, .callback = transmit_phy_packet_callback, @@ -451,8 +452,8 @@ void fw_send_phy_config(struct fw_card *card, mutex_lock(&phy_config_mutex); - phy_config_packet.header[0] = data; - phy_config_packet.header[1] = ~data; + phy_config_packet.header[1] = data; + phy_config_packet.header[2] = ~data; phy_config_packet.generation = generation; INIT_COMPLETION(phy_config_done); diff --git a/drivers/firewire/core.h b/drivers/firewire/core.h index e6239f971be6..f8dfcf1c6cbe 100644 --- a/drivers/firewire/core.h +++ b/drivers/firewire/core.h @@ -215,9 +215,11 @@ static inline bool is_next_generation(int new_generation, int old_generation) /* -transaction */ +#define TCODE_LINK_INTERNAL 0xe + #define TCODE_IS_READ_REQUEST(tcode) (((tcode) & ~1) == 4) #define TCODE_IS_BLOCK_PACKET(tcode) (((tcode) & 1) != 0) -#define TCODE_IS_LINK_INTERNAL(tcode) ((tcode) == 0xe) +#define TCODE_IS_LINK_INTERNAL(tcode) ((tcode) == TCODE_LINK_INTERNAL) #define TCODE_IS_REQUEST(tcode) (((tcode) & 2) == 0) #define TCODE_IS_RESPONSE(tcode) (((tcode) & 2) != 0) #define TCODE_HAS_REQUEST_DATA(tcode) (((tcode) & 12) != 4) diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c index 0031ec6e1f00..29259f3a30bb 100644 --- a/drivers/firewire/ohci.c +++ b/drivers/firewire/ohci.c @@ -418,10 +418,6 @@ static const char *tcodes[] = { [0xc] = "-reserved-", [0xd] = "-reserved-", [0xe] = "link internal", [0xf] = "-reserved-", }; -static const char *phys[] = { - [0x0] = "phy config packet", [0x1] = "link-on packet", - [0x2] = "self-id packet", [0x3] = "-reserved-", -}; static void log_ar_at_event(char dir, int speed, u32 *header, int evt) { @@ -440,12 +436,6 @@ static void log_ar_at_event(char dir, int speed, u32 *header, int evt) return; } - if (header[0] == ~header[1]) { - fw_notify("A%c %s, %s, %08x\n", - dir, evts[evt], phys[header[0] >> 30 & 0x3], header[0]); - return; - } - switch (tcode) { case 0x0: case 0x6: case 0x8: snprintf(specific, sizeof(specific), " = %08x", @@ -460,9 +450,13 @@ static void log_ar_at_event(char dir, int speed, u32 *header, int evt) } switch (tcode) { - case 0xe: case 0xa: + case 0xa: fw_notify("A%c %s, %s\n", dir, evts[evt], tcodes[tcode]); break; + case 0xe: + fw_notify("A%c %s, PHY %08x %08x\n", + dir, evts[evt], header[1], header[2]); + break; case 0x0: case 0x1: case 0x4: case 0x5: case 0x9: fw_notify("A%c spd %x tl %02x, " "%04x -> %04x, %s, " @@ -1250,21 +1244,27 @@ static int at_context_queue_packet(struct context *ctx, /* * The DMA format for asyncronous link packets is different * from the IEEE1394 layout, so shift the fields around - * accordingly. If header_length is 8, it's a PHY packet, to - * which we need to prepend an extra quadlet. + * accordingly. */ + tcode = (packet->header[0] >> 4) & 0x0f; header = (__le32 *) &d[1]; - switch (packet->header_length) { - case 16: - case 12: + switch (tcode) { + case TCODE_WRITE_QUADLET_REQUEST: + case TCODE_WRITE_BLOCK_REQUEST: + case TCODE_WRITE_RESPONSE: + case TCODE_READ_QUADLET_REQUEST: + case TCODE_READ_BLOCK_REQUEST: + case TCODE_READ_QUADLET_RESPONSE: + case TCODE_READ_BLOCK_RESPONSE: + case TCODE_LOCK_REQUEST: + case TCODE_LOCK_RESPONSE: header[0] = cpu_to_le32((packet->header[0] & 0xffff) | (packet->speed << 16)); header[1] = cpu_to_le32((packet->header[1] & 0xffff) | (packet->header[0] & 0xffff0000)); header[2] = cpu_to_le32(packet->header[2]); - tcode = (packet->header[0] >> 4) & 0x0f; if (TCODE_IS_BLOCK_PACKET(tcode)) header[3] = cpu_to_le32(packet->header[3]); else @@ -1273,18 +1273,18 @@ static int at_context_queue_packet(struct context *ctx, d[0].req_count = cpu_to_le16(packet->header_length); break; - case 8: + case TCODE_LINK_INTERNAL: header[0] = cpu_to_le32((OHCI1394_phy_tcode << 4) | (packet->speed << 16)); - header[1] = cpu_to_le32(packet->header[0]); - header[2] = cpu_to_le32(packet->header[1]); + header[1] = cpu_to_le32(packet->header[1]); + header[2] = cpu_to_le32(packet->header[2]); d[0].req_count = cpu_to_le16(12); - if (is_ping_packet(packet->header)) + if (is_ping_packet(&packet->header[1])) d[0].control |= cpu_to_le16(DESCRIPTOR_PING); break; - case 4: + case TCODE_STREAM_DATA: header[0] = cpu_to_le32((packet->header[0] & 0xffff) | (packet->speed << 16)); header[1] = cpu_to_le32(packet->header[0] & 0xffff0000); -- cgit v1.2.3 From 2dd5bed59356e03610bebe1a37c397788df50b9b Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Tue, 30 Nov 2010 08:25:05 +0100 Subject: firewire: ohci: optimize iso context checks in the interrupt handler When the isochRx/isochTx bit is clear, we do not need to read the corresponding iso interrupt event register. Signed-off-by: Clemens Ladisch Signed-off-by: Stefan Richter --- drivers/firewire/ohci.c | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c index 29259f3a30bb..01b3bc9154a6 100644 --- a/drivers/firewire/ohci.c +++ b/drivers/firewire/ohci.c @@ -1813,22 +1813,28 @@ static irqreturn_t irq_handler(int irq, void *data) if (event & OHCI1394_respTxComplete) tasklet_schedule(&ohci->at_response_ctx.tasklet); - iso_event = reg_read(ohci, OHCI1394_IsoRecvIntEventClear); - reg_write(ohci, OHCI1394_IsoRecvIntEventClear, iso_event); - - while (iso_event) { - i = ffs(iso_event) - 1; - tasklet_schedule(&ohci->ir_context_list[i].context.tasklet); - iso_event &= ~(1 << i); + if (event & OHCI1394_isochRx) { + iso_event = reg_read(ohci, OHCI1394_IsoRecvIntEventClear); + reg_write(ohci, OHCI1394_IsoRecvIntEventClear, iso_event); + + while (iso_event) { + i = ffs(iso_event) - 1; + tasklet_schedule( + &ohci->ir_context_list[i].context.tasklet); + iso_event &= ~(1 << i); + } } - iso_event = reg_read(ohci, OHCI1394_IsoXmitIntEventClear); - reg_write(ohci, OHCI1394_IsoXmitIntEventClear, iso_event); + if (event & OHCI1394_isochTx) { + iso_event = reg_read(ohci, OHCI1394_IsoXmitIntEventClear); + reg_write(ohci, OHCI1394_IsoXmitIntEventClear, iso_event); - while (iso_event) { - i = ffs(iso_event) - 1; - tasklet_schedule(&ohci->it_context_list[i].context.tasklet); - iso_event &= ~(1 << i); + while (iso_event) { + i = ffs(iso_event) - 1; + tasklet_schedule( + &ohci->it_context_list[i].context.tasklet); + iso_event &= ~(1 << i); + } } if (unlikely(event & OHCI1394_regAccessFail)) -- cgit v1.2.3 From ec766a7970126f99665992c0b0b10bd60a4d6208 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Tue, 30 Nov 2010 08:25:17 +0100 Subject: firewire: ohci: use common buffer for self IDs and AR descriptors The buffers used for the selfIDs packets and the AR request and response descriptors end up using three pages because dma_alloc_coherent() allocates at least one page per call. However, these data structures would all fit into 4 KB, so we can save space by using a common buffer for them. Signed-off-by: Clemens Ladisch Signed-off-by: Stefan Richter --- drivers/firewire/ohci.c | 66 +++++++++++++++++++++++++------------------------ 1 file changed, 34 insertions(+), 32 deletions(-) diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c index 01b3bc9154a6..eb7b591e1c1b 100644 --- a/drivers/firewire/ohci.c +++ b/drivers/firewire/ohci.c @@ -193,6 +193,9 @@ struct fw_ohci { struct mutex phy_reg_mutex; + void *misc_buffer; + dma_addr_t misc_buffer_bus; + struct ar_context ar_request_ctx; struct ar_context ar_response_ctx; struct context at_request_ctx; @@ -623,11 +626,6 @@ static void ar_context_release(struct ar_context *ctx) { unsigned int i; - if (ctx->descriptors) - dma_free_coherent(ctx->ohci->card.device, - AR_BUFFERS * sizeof(struct descriptor), - ctx->descriptors, ctx->descriptors_bus); - if (ctx->buffer) vm_unmap_ram(ctx->buffer, AR_BUFFERS + AR_WRAPAROUND_PAGES); @@ -925,8 +923,8 @@ error: ctx->pointer = NULL; } -static int ar_context_init(struct ar_context *ctx, - struct fw_ohci *ohci, u32 regs) +static int ar_context_init(struct ar_context *ctx, struct fw_ohci *ohci, + unsigned int descriptors_offset, u32 regs) { unsigned int i; dma_addr_t dma_addr; @@ -960,13 +958,8 @@ static int ar_context_init(struct ar_context *ctx, if (!ctx->buffer) goto out_of_memory; - ctx->descriptors = - dma_alloc_coherent(ohci->card.device, - AR_BUFFERS * sizeof(struct descriptor), - &ctx->descriptors_bus, - GFP_KERNEL); - if (!ctx->descriptors) - goto out_of_memory; + ctx->descriptors = ohci->misc_buffer + descriptors_offset; + ctx->descriptors_bus = ohci->misc_buffer_bus + descriptors_offset; for (i = 0; i < AR_BUFFERS; i++) { d = &ctx->descriptors[i]; @@ -3108,12 +3101,28 @@ static int __devinit pci_probe(struct pci_dev *dev, if (param_quirks) ohci->quirks = param_quirks; - err = ar_context_init(&ohci->ar_request_ctx, ohci, + /* + * Because dma_alloc_coherent() allocates at least one page, + * we save space by using a common buffer for the AR request/ + * response descriptors and the self IDs buffer. + */ + BUILD_BUG_ON(AR_BUFFERS * sizeof(struct descriptor) > PAGE_SIZE/4); + BUILD_BUG_ON(SELF_ID_BUF_SIZE > PAGE_SIZE/2); + ohci->misc_buffer = dma_alloc_coherent(ohci->card.device, + PAGE_SIZE, + &ohci->misc_buffer_bus, + GFP_KERNEL); + if (!ohci->misc_buffer) { + err = -ENOMEM; + goto fail_iounmap; + } + + err = ar_context_init(&ohci->ar_request_ctx, ohci, 0, OHCI1394_AsReqRcvContextControlSet); if (err < 0) - goto fail_iounmap; + goto fail_misc_buf; - err = ar_context_init(&ohci->ar_response_ctx, ohci, + err = ar_context_init(&ohci->ar_response_ctx, ohci, PAGE_SIZE/4, OHCI1394_AsRspRcvContextControlSet); if (err < 0) goto fail_arreq_ctx; @@ -3148,15 +3157,8 @@ static int __devinit pci_probe(struct pci_dev *dev, goto fail_contexts; } - /* self-id dma buffer allocation */ - ohci->self_id_cpu = dma_alloc_coherent(ohci->card.device, - SELF_ID_BUF_SIZE, - &ohci->self_id_bus, - GFP_KERNEL); - if (ohci->self_id_cpu == NULL) { - err = -ENOMEM; - goto fail_contexts; - } + ohci->self_id_cpu = ohci->misc_buffer + PAGE_SIZE/2; + ohci->self_id_bus = ohci->misc_buffer_bus + PAGE_SIZE/2; bus_options = reg_read(ohci, OHCI1394_BusOptions); max_receive = (bus_options >> 12) & 0xf; @@ -3166,7 +3168,7 @@ static int __devinit pci_probe(struct pci_dev *dev, err = fw_card_add(&ohci->card, max_receive, link_speed, guid); if (err) - goto fail_self_id; + goto fail_contexts; version = reg_read(ohci, OHCI1394_Version) & 0x00ff00ff; fw_notify("Added fw-ohci device %s, OHCI v%x.%x, " @@ -3176,9 +3178,6 @@ static int __devinit pci_probe(struct pci_dev *dev, return 0; - fail_self_id: - dma_free_coherent(ohci->card.device, SELF_ID_BUF_SIZE, - ohci->self_id_cpu, ohci->self_id_bus); fail_contexts: kfree(ohci->ir_context_list); kfree(ohci->it_context_list); @@ -3189,6 +3188,9 @@ static int __devinit pci_probe(struct pci_dev *dev, ar_context_release(&ohci->ar_response_ctx); fail_arreq_ctx: ar_context_release(&ohci->ar_request_ctx); + fail_misc_buf: + dma_free_coherent(ohci->card.device, PAGE_SIZE, + ohci->misc_buffer, ohci->misc_buffer_bus); fail_iounmap: pci_iounmap(dev, ohci->registers); fail_iomem: @@ -3228,10 +3230,10 @@ static void pci_remove(struct pci_dev *dev) if (ohci->config_rom) dma_free_coherent(ohci->card.device, CONFIG_ROM_SIZE, ohci->config_rom, ohci->config_rom_bus); - dma_free_coherent(ohci->card.device, SELF_ID_BUF_SIZE, - ohci->self_id_cpu, ohci->self_id_bus); ar_context_release(&ohci->ar_request_ctx); ar_context_release(&ohci->ar_response_ctx); + dma_free_coherent(ohci->card.device, PAGE_SIZE, + ohci->misc_buffer, ohci->misc_buffer_bus); context_release(&ohci->at_request_ctx); context_release(&ohci->at_response_ctx); kfree(ohci->it_context_list); -- cgit v1.2.3 From 8662b6b029636c35e5876e184d90daf6b0072667 Mon Sep 17 00:00:00 2001 From: Maxim Levitsky Date: Mon, 29 Nov 2010 04:09:49 +0200 Subject: firewire: ohci: restore GUID on resume. Some lousy BIOSes, e.g. my Aspire 5720 BIOS forget to restore the GUID register on resume from RAM. Fix that by setting it to the last value that was read from it. Signed-off-by: Maxim Levitsky Signed-off-by: Stefan Richter --- drivers/firewire/ohci.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c index eb7b591e1c1b..3a908038ff62 100644 --- a/drivers/firewire/ohci.c +++ b/drivers/firewire/ohci.c @@ -3284,6 +3284,13 @@ static int pci_resume(struct pci_dev *dev) return err; } + /* Some systems don't setup GUID register on resume from ram */ + if (!reg_read(ohci, OHCI1394_GUIDLo) && + !reg_read(ohci, OHCI1394_GUIDHi)) { + reg_write(ohci, OHCI1394_GUIDLo, (u32)ohci->card.guid); + reg_write(ohci, OHCI1394_GUIDHi, (u32)(ohci->card.guid >> 32)); + } + return ohci_enable(&ohci->card, NULL, 0); } #endif -- cgit v1.2.3 From dd23736e092035b71df1117482b71fdfb5634239 Mon Sep 17 00:00:00 2001 From: Maxim Levitsky Date: Mon, 29 Nov 2010 04:09:50 +0200 Subject: firewire: ohci: restart iso DMA contexts on resume from low power mode Restore iso channels DMA so that iso channels could continue to work after resume from RAM/disk. Signed-off-by: Maxim Levitsky Signed-off-by: Stefan Richter --- drivers/firewire/ohci.c | 54 +++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 46 insertions(+), 8 deletions(-) diff --git a/drivers/firewire/ohci.c b/drivers/firewire/ohci.c index 3a908038ff62..5e5d5d3d43d1 100644 --- a/drivers/firewire/ohci.c +++ b/drivers/firewire/ohci.c @@ -18,6 +18,7 @@ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#include #include #include #include @@ -153,6 +154,7 @@ struct context { descriptor_callback_t callback; struct tasklet_struct tasklet; + bool active; }; #define IT_HEADER_SY(v) ((v) << 0) @@ -168,6 +170,9 @@ struct iso_context { int excess_bytes; void *header; size_t header_length; + + u8 sync; + u8 tags; }; #define CONFIG_ROM_SIZE 1024 @@ -184,7 +189,8 @@ struct fw_ohci { u32 bus_time; bool is_root; bool csr_state_setclear_abdicate; - + int n_ir; + int n_it; /* * Spinlock for accessing fw_ohci data. Never call out of * this driver with this lock held. @@ -1161,6 +1167,7 @@ static struct descriptor *context_get_descriptors(struct context *ctx, static void context_run(struct context *ctx, u32 extra) { struct fw_ohci *ohci = ctx->ohci; + ctx->active = true; reg_write(ohci, COMMAND_PTR(ctx->regs), le32_to_cpu(ctx->last->branch_address)); @@ -1192,6 +1199,7 @@ static void context_stop(struct context *ctx) u32 reg; int i; + ctx->active = false; reg_write(ctx->ohci, CONTROL_CLEAR(ctx->regs), CONTEXT_RUN); flush_writes(ctx->ohci); @@ -2641,6 +2649,10 @@ static int ohci_start_iso(struct fw_iso_context *base, reg_write(ohci, OHCI1394_IsoRecvIntMaskSet, 1 << index); reg_write(ohci, CONTEXT_MATCH(ctx->context.regs), match); context_run(&ctx->context, control); + + ctx->sync = sync; + ctx->tags = tags; + break; } @@ -2738,6 +2750,26 @@ static int ohci_set_iso_channels(struct fw_iso_context *base, u64 *channels) return ret; } +#ifdef CONFIG_PM +static void ohci_resume_iso_dma(struct fw_ohci *ohci) +{ + int i; + struct iso_context *ctx; + + for (i = 0 ; i < ohci->n_ir ; i++) { + ctx = &ohci->ir_context_list[i]; + if (ctx->context.active) + ohci_start_iso(&ctx->base, 0, ctx->sync, ctx->tags); + } + + for (i = 0 ; i < ohci->n_it ; i++) { + ctx = &ohci->it_context_list[i]; + if (ctx->context.active) + ohci_start_iso(&ctx->base, 0, ctx->sync, ctx->tags); + } +} +#endif + static int queue_iso_transmit(struct iso_context *ctx, struct fw_iso_packet *packet, struct fw_iso_buffer *buffer, @@ -3047,7 +3079,7 @@ static int __devinit pci_probe(struct pci_dev *dev, struct fw_ohci *ohci; u32 bus_options, max_receive, link_speed, version; u64 guid; - int i, err, n_ir, n_it; + int i, err; size_t size; ohci = kzalloc(sizeof(*ohci), GFP_KERNEL); @@ -3141,15 +3173,15 @@ static int __devinit pci_probe(struct pci_dev *dev, ohci->ir_context_channels = ~0ULL; ohci->ir_context_mask = reg_read(ohci, OHCI1394_IsoRecvIntMaskSet); reg_write(ohci, OHCI1394_IsoRecvIntMaskClear, ~0); - n_ir = hweight32(ohci->ir_context_mask); - size = sizeof(struct iso_context) * n_ir; + ohci->n_ir = hweight32(ohci->ir_context_mask); + size = sizeof(struct iso_context) * ohci->n_ir; ohci->ir_context_list = kzalloc(size, GFP_KERNEL); reg_write(ohci, OHCI1394_IsoXmitIntMaskSet, ~0); ohci->it_context_mask = reg_read(ohci, OHCI1394_IsoXmitIntMaskSet); reg_write(ohci, OHCI1394_IsoXmitIntMaskClear, ~0); - n_it = hweight32(ohci->it_context_mask); - size = sizeof(struct iso_context) * n_it; + ohci->n_it = hweight32(ohci->it_context_mask); + size = sizeof(struct iso_context) * ohci->n_it; ohci->it_context_list = kzalloc(size, GFP_KERNEL); if (ohci->it_context_list == NULL || ohci->ir_context_list == NULL) { @@ -3174,7 +3206,7 @@ static int __devinit pci_probe(struct pci_dev *dev, fw_notify("Added fw-ohci device %s, OHCI v%x.%x, " "%d IR + %d IT contexts, quirks 0x%x\n", dev_name(&dev->dev), version >> 16, version & 0xff, - n_ir, n_it, ohci->quirks); + ohci->n_ir, ohci->n_it, ohci->quirks); return 0; @@ -3291,7 +3323,13 @@ static int pci_resume(struct pci_dev *dev) reg_write(ohci, OHCI1394_GUIDHi, (u32)(ohci->card.guid >> 32)); } - return ohci_enable(&ohci->card, NULL, 0); + err = ohci_enable(&ohci->card, NULL, 0); + + if (err) + return err; + + ohci_resume_iso_dma(ohci); + return 0; } #endif -- cgit v1.2.3 From c4d6fd40df38eb4c187565d48807f5f902481ba8 Mon Sep 17 00:00:00 2001 From: Maxim Levitsky Date: Mon, 29 Nov 2010 04:09:53 +0200 Subject: firewire: net: ratelimit error messages Unfortunately its easy to trigger such error messages by removing the cable while sending streams of data over the link. Such errors are normal, and therefore this patch stops firewire-net from flooding the kernel log with these errors, by combining series of same errors together. Signed-off-by: Maxim Levitsky (Stefan R:) Eventually we should remove this logging when firewire-net and related firewire-ohci facilities have been stabilized. Signed-off-by: Stefan Richter --- drivers/firewire/net.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/drivers/firewire/net.c b/drivers/firewire/net.c index 1a467a91fb0b..ea31e3084d67 100644 --- a/drivers/firewire/net.c +++ b/drivers/firewire/net.c @@ -996,15 +996,23 @@ static void fwnet_transmit_packet_failed(struct fwnet_packet_task *ptask) static void fwnet_write_complete(struct fw_card *card, int rcode, void *payload, size_t length, void *data) { - struct fwnet_packet_task *ptask; - - ptask = data; + struct fwnet_packet_task *ptask = data; + static unsigned long j; + static int last_rcode, errors_skipped; if (rcode == RCODE_COMPLETE) { fwnet_transmit_packet_done(ptask); } else { - fw_error("fwnet_write_complete: failed: %x\n", rcode); fwnet_transmit_packet_failed(ptask); + + if (printk_timed_ratelimit(&j, 1000) || rcode != last_rcode) { + fw_error("fwnet_write_complete: " + "failed: %x (skipped %d)\n", rcode, errors_skipped); + + errors_skipped = 0; + last_rcode = rcode; + } else + errors_skipped++; } } -- cgit v1.2.3 From b9d41052794385f9d47ebb7acf4a772f3ad02398 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Mon, 13 Dec 2010 13:42:24 -0600 Subject: dlm: sanitize work_start() in lowcomms.c The create_workqueue() returns NULL if failed rather than ERR_PTR(). Fix error checking and remove unnecessary variable 'error'. Signed-off-by: Namhyung Kim Cc: Tejun Heo Signed-off-by: David Teigland --- fs/dlm/lowcomms.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/fs/dlm/lowcomms.c b/fs/dlm/lowcomms.c index 0e75f152eac2..9c64ae9e4c1a 100644 --- a/fs/dlm/lowcomms.c +++ b/fs/dlm/lowcomms.c @@ -1468,22 +1468,19 @@ static void work_stop(void) static int work_start(void) { - int error; recv_workqueue = alloc_workqueue("dlm_recv", WQ_MEM_RECLAIM | WQ_HIGHPRI | WQ_FREEZEABLE, 0); - error = IS_ERR(recv_workqueue); - if (error) { - log_print("can't start dlm_recv %d", error); - return error; + if (!recv_workqueue) { + log_print("can't start dlm_recv"); + return -ENOMEM; } send_workqueue = alloc_workqueue("dlm_send", WQ_MEM_RECLAIM | WQ_HIGHPRI | WQ_FREEZEABLE, 0); - error = IS_ERR(send_workqueue); - if (error) { - log_print("can't start dlm_send %d", error); + if (!send_workqueue) { + log_print("can't start dlm_send"); destroy_workqueue(recv_workqueue); - return error; + return -ENOMEM; } return 0; -- cgit v1.2.3 From 96c8f06a0fb359a9a89701a7afab6d837e466ab0 Mon Sep 17 00:00:00 2001 From: Thomas Gleixner Date: Mon, 13 Dec 2010 22:45:48 +0100 Subject: rtc: Namespace fixup rtctimer_* is already occupied by sound/core/rtctimer.c. Instead of fiddling with that, rename the new functions to rtc_timer_* which reads nicer anyway. Signed-off-by: Thomas Gleixner Cc: John Stultz --- drivers/rtc/class.c | 6 +++--- drivers/rtc/interface.c | 42 +++++++++++++++++++++--------------------- include/linux/rtc.h | 12 ++++++------ 3 files changed, 30 insertions(+), 30 deletions(-) diff --git a/drivers/rtc/class.c b/drivers/rtc/class.c index 95d2b82762d6..3243832a17cd 100644 --- a/drivers/rtc/class.c +++ b/drivers/rtc/class.c @@ -155,11 +155,11 @@ struct rtc_device *rtc_device_register(const char *name, struct device *dev, /* Init timerqueue */ timerqueue_init_head(&rtc->timerqueue); - INIT_WORK(&rtc->irqwork, rtctimer_do_work); + INIT_WORK(&rtc->irqwork, rtc_timer_do_work); /* Init aie timer */ - rtctimer_init(&rtc->aie_timer, rtc_aie_update_irq, (void *)rtc); + rtc_timer_init(&rtc->aie_timer, rtc_aie_update_irq, (void *)rtc); /* Init uie timer */ - rtctimer_init(&rtc->uie_rtctimer, rtc_uie_update_irq, (void *)rtc); + rtc_timer_init(&rtc->uie_rtctimer, rtc_uie_update_irq, (void *)rtc); /* Init pie timer */ hrtimer_init(&rtc->pie_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); rtc->pie_timer.function = rtc_pie_update_irq; diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c index c81c50b497b7..90384b9f6b2c 100644 --- a/drivers/rtc/interface.c +++ b/drivers/rtc/interface.c @@ -174,14 +174,14 @@ int rtc_set_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) if (err) return err; if (rtc->aie_timer.enabled) { - rtctimer_remove(rtc, &rtc->aie_timer); + rtc_timer_remove(rtc, &rtc->aie_timer); rtc->aie_timer.enabled = 0; } rtc->aie_timer.node.expires = rtc_tm_to_ktime(alarm->time); rtc->aie_timer.period = ktime_set(0, 0); if (alarm->enabled) { rtc->aie_timer.enabled = 1; - rtctimer_enqueue(rtc, &rtc->aie_timer); + rtc_timer_enqueue(rtc, &rtc->aie_timer); } mutex_unlock(&rtc->ops_lock); return 0; @@ -197,9 +197,9 @@ int rtc_alarm_irq_enable(struct rtc_device *rtc, unsigned int enabled) if (rtc->aie_timer.enabled != enabled) { if (enabled) { rtc->aie_timer.enabled = 1; - rtctimer_enqueue(rtc, &rtc->aie_timer); + rtc_timer_enqueue(rtc, &rtc->aie_timer); } else { - rtctimer_remove(rtc, &rtc->aie_timer); + rtc_timer_remove(rtc, &rtc->aie_timer); rtc->aie_timer.enabled = 0; } } @@ -236,9 +236,9 @@ int rtc_update_irq_enable(struct rtc_device *rtc, unsigned int enabled) rtc->uie_rtctimer.node.expires = ktime_add(now, onesec); rtc->uie_rtctimer.period = ktime_set(1, 0); rtc->uie_rtctimer.enabled = 1; - rtctimer_enqueue(rtc, &rtc->uie_rtctimer); + rtc_timer_enqueue(rtc, &rtc->uie_rtctimer); } else { - rtctimer_remove(rtc, &rtc->uie_rtctimer); + rtc_timer_remove(rtc, &rtc->uie_rtctimer); rtc->uie_rtctimer.enabled = 0; } @@ -481,7 +481,7 @@ int rtc_irq_set_freq(struct rtc_device *rtc, struct rtc_task *task, int freq) EXPORT_SYMBOL_GPL(rtc_irq_set_freq); /** - * rtctimer_enqueue - Adds a rtc_timer to the rtc_device timerqueue + * rtc_timer_enqueue - Adds a rtc_timer to the rtc_device timerqueue * @rtc rtc device * @timer timer being added. * @@ -490,7 +490,7 @@ EXPORT_SYMBOL_GPL(rtc_irq_set_freq); * * Must hold ops_lock for proper serialization of timerqueue */ -void rtctimer_enqueue(struct rtc_device *rtc, struct rtc_timer *timer) +void rtc_timer_enqueue(struct rtc_device *rtc, struct rtc_timer *timer) { timerqueue_add(&rtc->timerqueue, &timer->node); if (&timer->node == timerqueue_getnext(&rtc->timerqueue)) { @@ -505,7 +505,7 @@ void rtctimer_enqueue(struct rtc_device *rtc, struct rtc_timer *timer) } /** - * rtctimer_remove - Removes a rtc_timer from the rtc_device timerqueue + * rtc_timer_remove - Removes a rtc_timer from the rtc_device timerqueue * @rtc rtc device * @timer timer being removed. * @@ -514,7 +514,7 @@ void rtctimer_enqueue(struct rtc_device *rtc, struct rtc_timer *timer) * * Must hold ops_lock for proper serialization of timerqueue */ -void rtctimer_remove(struct rtc_device *rtc, struct rtc_timer *timer) +void rtc_timer_remove(struct rtc_device *rtc, struct rtc_timer *timer) { struct timerqueue_node *next = timerqueue_getnext(&rtc->timerqueue); timerqueue_del(&rtc->timerqueue, &timer->node); @@ -534,7 +534,7 @@ void rtctimer_remove(struct rtc_device *rtc, struct rtc_timer *timer) } /** - * rtctimer_do_work - Expires rtc timers + * rtc_timer_do_work - Expires rtc timers * @rtc rtc device * @timer timer being removed. * @@ -543,7 +543,7 @@ void rtctimer_remove(struct rtc_device *rtc, struct rtc_timer *timer) * * Serializes access to timerqueue via ops_lock mutex */ -void rtctimer_do_work(struct work_struct *work) +void rtc_timer_do_work(struct work_struct *work) { struct rtc_timer *timer; struct timerqueue_node *next; @@ -592,14 +592,14 @@ again: } -/* rtctimer_init - Initializes an rtc_timer +/* rtc_timer_init - Initializes an rtc_timer * @timer: timer to be intiialized * @f: function pointer to be called when timer fires * @data: private data passed to function pointer * * Kernel interface to initializing an rtc_timer. */ -void rtctimer_init(struct rtc_timer *timer, void (*f)(void* p), void* data) +void rtc_timer_init(struct rtc_timer *timer, void (*f)(void* p), void* data) { timerqueue_init(&timer->node); timer->enabled = 0; @@ -607,7 +607,7 @@ void rtctimer_init(struct rtc_timer *timer, void (*f)(void* p), void* data) timer->task.private_data = data; } -/* rtctimer_start - Sets an rtc_timer to fire in the future +/* rtc_timer_start - Sets an rtc_timer to fire in the future * @ rtc: rtc device to be used * @ timer: timer being set * @ expires: time at which to expire the timer @@ -615,36 +615,36 @@ void rtctimer_init(struct rtc_timer *timer, void (*f)(void* p), void* data) * * Kernel interface to set an rtc_timer */ -int rtctimer_start(struct rtc_device *rtc, struct rtc_timer* timer, +int rtc_timer_start(struct rtc_device *rtc, struct rtc_timer* timer, ktime_t expires, ktime_t period) { int ret = 0; mutex_lock(&rtc->ops_lock); if (timer->enabled) - rtctimer_remove(rtc, timer); + rtc_timer_remove(rtc, timer); timer->node.expires = expires; timer->period = period; timer->enabled = 1; - rtctimer_enqueue(rtc, timer); + rtc_timer_enqueue(rtc, timer); mutex_unlock(&rtc->ops_lock); return ret; } -/* rtctimer_cancel - Stops an rtc_timer +/* rtc_timer_cancel - Stops an rtc_timer * @ rtc: rtc device to be used * @ timer: timer being set * * Kernel interface to cancel an rtc_timer */ -int rtctimer_cancel(struct rtc_device *rtc, struct rtc_timer* timer) +int rtc_timer_cancel(struct rtc_device *rtc, struct rtc_timer* timer) { int ret = 0; mutex_lock(&rtc->ops_lock); if (timer->enabled) - rtctimer_remove(rtc, timer); + rtc_timer_remove(rtc, timer); timer->enabled = 0; mutex_unlock(&rtc->ops_lock); return ret; diff --git a/include/linux/rtc.h b/include/linux/rtc.h index 44e18a2523a3..3c995b4d742c 100644 --- a/include/linux/rtc.h +++ b/include/linux/rtc.h @@ -246,13 +246,13 @@ int rtc_register(rtc_task_t *task); int rtc_unregister(rtc_task_t *task); int rtc_control(rtc_task_t *t, unsigned int cmd, unsigned long arg); -void rtctimer_enqueue(struct rtc_device *rtc, struct rtc_timer *timer); -void rtctimer_remove(struct rtc_device *rtc, struct rtc_timer *timer); -void rtctimer_init(struct rtc_timer *timer, void (*f)(void* p), void* data); -int rtctimer_start(struct rtc_device *rtc, struct rtc_timer* timer, +void rtc_timer_enqueue(struct rtc_device *rtc, struct rtc_timer *timer); +void rtc_timer_remove(struct rtc_device *rtc, struct rtc_timer *timer); +void rtc_timer_init(struct rtc_timer *timer, void (*f)(void* p), void* data); +int rtc_timer_start(struct rtc_device *rtc, struct rtc_timer* timer, ktime_t expires, ktime_t period); -int rtctimer_cancel(struct rtc_device *rtc, struct rtc_timer* timer); -void rtctimer_do_work(struct work_struct *work); +int rtc_timer_cancel(struct rtc_device *rtc, struct rtc_timer* timer); +void rtc_timer_do_work(struct work_struct *work); static inline bool is_leap_year(unsigned int year) { -- cgit v1.2.3 From c9aa308fd5c373faeda588cfb02b04f116904613 Mon Sep 17 00:00:00 2001 From: Huang Ying Date: Tue, 7 Dec 2010 10:22:29 +0800 Subject: Add CPER PCIe error section structure and constants definition On some machine, PCIe error is reported via APEI (ACPI Platform Error Interface). The error data is passed from firmware to Linux via CPER PCIe error section structure. This patch adds CPER PCIe error section structure and constants definition. Signed-off-by: Huang Ying Signed-off-by: Len Brown --- include/linux/cper.h | 86 +++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 82 insertions(+), 4 deletions(-) diff --git a/include/linux/cper.h b/include/linux/cper.h index bf972f81e2a7..3104aaff5dd0 100644 --- a/include/linux/cper.h +++ b/include/linux/cper.h @@ -39,10 +39,12 @@ * Severity difinition for error_severity in struct cper_record_header * and section_severity in struct cper_section_descriptor */ -#define CPER_SEV_RECOVERABLE 0x0 -#define CPER_SEV_FATAL 0x1 -#define CPER_SEV_CORRECTED 0x2 -#define CPER_SEV_INFORMATIONAL 0x3 +enum { + CPER_SEV_RECOVERABLE, + CPER_SEV_FATAL, + CPER_SEV_CORRECTED, + CPER_SEV_INFORMATIONAL, +}; /* * Validation bits difinition for validation_bits in struct @@ -201,6 +203,47 @@ UUID_LE(0x036F84E1, 0x7F37, 0x428c, 0xA7, 0x9E, 0x57, 0x5F, \ 0xDF, 0xAA, 0x84, 0xEC) +#define CPER_PROC_VALID_TYPE 0x0001 +#define CPER_PROC_VALID_ISA 0x0002 +#define CPER_PROC_VALID_ERROR_TYPE 0x0004 +#define CPER_PROC_VALID_OPERATION 0x0008 +#define CPER_PROC_VALID_FLAGS 0x0010 +#define CPER_PROC_VALID_LEVEL 0x0020 +#define CPER_PROC_VALID_VERSION 0x0040 +#define CPER_PROC_VALID_BRAND_INFO 0x0080 +#define CPER_PROC_VALID_ID 0x0100 +#define CPER_PROC_VALID_TARGET_ADDRESS 0x0200 +#define CPER_PROC_VALID_REQUESTOR_ID 0x0400 +#define CPER_PROC_VALID_RESPONDER_ID 0x0800 +#define CPER_PROC_VALID_IP 0x1000 + +#define CPER_MEM_VALID_ERROR_STATUS 0x0001 +#define CPER_MEM_VALID_PHYSICAL_ADDRESS 0x0002 +#define CPER_MEM_VALID_PHYSICAL_ADDRESS_MASK 0x0004 +#define CPER_MEM_VALID_NODE 0x0008 +#define CPER_MEM_VALID_CARD 0x0010 +#define CPER_MEM_VALID_MODULE 0x0020 +#define CPER_MEM_VALID_BANK 0x0040 +#define CPER_MEM_VALID_DEVICE 0x0080 +#define CPER_MEM_VALID_ROW 0x0100 +#define CPER_MEM_VALID_COLUMN 0x0200 +#define CPER_MEM_VALID_BIT_POSITION 0x0400 +#define CPER_MEM_VALID_REQUESTOR_ID 0x0800 +#define CPER_MEM_VALID_RESPONDER_ID 0x1000 +#define CPER_MEM_VALID_TARGET_ID 0x2000 +#define CPER_MEM_VALID_ERROR_TYPE 0x4000 + +#define CPER_PCIE_VALID_PORT_TYPE 0x0001 +#define CPER_PCIE_VALID_VERSION 0x0002 +#define CPER_PCIE_VALID_COMMAND_STATUS 0x0004 +#define CPER_PCIE_VALID_DEVICE_ID 0x0008 +#define CPER_PCIE_VALID_SERIAL_NUMBER 0x0010 +#define CPER_PCIE_VALID_BRIDGE_CONTROL_STATUS 0x0020 +#define CPER_PCIE_VALID_CAPABILITY 0x0040 +#define CPER_PCIE_VALID_AER_INFO 0x0080 + +#define CPER_PCIE_SLOT_SHIFT 3 + /* * All tables and structs must be byte-packed to match CPER * specification, since the tables are provided by the system BIOS @@ -306,6 +349,41 @@ struct cper_sec_mem_err { __u8 error_type; }; +struct cper_sec_pcie { + __u64 validation_bits; + __u32 port_type; + struct { + __u8 minor; + __u8 major; + __u8 reserved[2]; + } version; + __u16 command; + __u16 status; + __u32 reserved; + struct { + __u16 vendor_id; + __u16 device_id; + __u8 class_code[3]; + __u8 function; + __u8 device; + __u16 segment; + __u8 bus; + __u8 secondary_bus; + __u16 slot; + __u8 reserved; + } device_id; + struct { + __u32 lower; + __u32 upper; + } serial_number; + struct { + __u16 secondary_status; + __u16 control; + } bridge; + __u8 capability[60]; + __u8 aer_info[96]; +}; + /* Reset to default packing */ #pragma pack() -- cgit v1.2.3 From f59c55d04b43bd72df8efa692dd07224fe94d1ac Mon Sep 17 00:00:00 2001 From: Huang Ying Date: Tue, 7 Dec 2010 10:22:30 +0800 Subject: ACPI, APEI, Add APEI generic error status printing support In APEI, Hardware error information reported by firmware to Linux kernel is in the data structure of APEI generic error status (struct acpi_hes_generic_status). While now printk is used by Linux kernel to report hardware error information to user space. So, this patch adds printing support for the data structure, so that the corresponding hardware error information can be reported to user space via printk. PCIe AER information printing is not implemented yet. Will refactor the original PCIe AER information printing code to avoid code duplicating. The output format is as follow: := APEI generic hardware error status severity: , section: , severity: , flags:
fru_id: fru_text: section_type:
* := recoverable | fatal | corrected | info
# := [primary][, containment warning][, reset][, threshold exceeded]\ [, resource not accessible][, latent error]
:= generic processor error | memory error | \ PCIe error | unknown,
:= | | \ | := [processor_type: , ] [processor_isa: , ] [error_type: ] [operation: , ] [flags: ] [level: ] [version_info: ] [processor_id: ] [target_address: ] [requestor_id: ] [responder_id: ] [IP: ] * := IA32/X64 | IA64 * := IA32 | IA64 | X64 # := [cache error][, TLB error][, bus error][, micro-architectural error] * := unknown or generic | data read | data write | \ instruction execution # := [restartable][, precise IP][, overflow][, corrected] := [error_status: ] [physical_address: ] [physical_address_mask: ] [node: ] [card: ] [module: ] [bank: ] [device: ] [row: ] [column: ] [bit_position: ] [requestor_id: ] [responder_id: ] [target_id: ] [error_type: , ] * := unknown | no error | single-bit ECC | multi-bit ECC | \ single-symbol chipkill ECC | multi-symbol chipkill ECC | master abort | \ target abort | parity error | watchdog timeout | invalid address | \ mirror Broken | memory sparing | scrub corrected error | \ scrub uncorrected error := [port_type: , ] [version: .] [command: , status: ] [device_id: ::. slot: secondary_bus: vendor_id: , device_id: class_code: ] [serial number: , ] [bridge: secondary_status: , control: ] * := PCIe end point | legacy PCI end point | \ unknown | unknown | root port | upstream switch port | \ downstream switch port | PCIe to PCI/PCI-X bridge | \ PCI/PCI-X to PCIe bridge | root complex integrated endpoint device | \ root complex event collector Where, [] designate corresponding content is optional All description with * has the following format: field: , Where value of should be the position of "string" in description. Otherwise, will be "unknown". All description with # has the following format: field: Where each string in corresponding to one set bit of . The bit position is the position of "string" in description. For more detailed explanation of every field, please refer to UEFI specification version 2.3 or later, section Appendix N: Common Platform Error Record. Signed-off-by: Huang Ying Signed-off-by: Len Brown --- Documentation/acpi/apei/output_format.txt | 122 ++++++++++++ drivers/acpi/apei/apei-internal.h | 2 + drivers/acpi/apei/cper.c | 311 ++++++++++++++++++++++++++++++ 3 files changed, 435 insertions(+) create mode 100644 Documentation/acpi/apei/output_format.txt diff --git a/Documentation/acpi/apei/output_format.txt b/Documentation/acpi/apei/output_format.txt new file mode 100644 index 000000000000..9146952c612a --- /dev/null +++ b/Documentation/acpi/apei/output_format.txt @@ -0,0 +1,122 @@ + APEI output format + ~~~~~~~~~~~~~~~~~~ + +APEI uses printk as hardware error reporting interface, the output +format is as follow. + + := +APEI generic hardware error status +severity: , +section: , severity: , +flags: +
+fru_id: +fru_text: +section_type:
+
+ +* := recoverable | fatal | corrected | info + +
# := +[primary][, containment warning][, reset][, threshold exceeded]\ +[, resource not accessible][, latent error] + +
:= generic processor error | memory error | \ +PCIe error | unknown, + +
:= + | | \ + | + + := +[processor_type: , ] +[processor_isa: , ] +[error_type: +] +[operation: , ] +[flags: +] +[level: ] +[version_info: ] +[processor_id: ] +[target_address: ] +[requestor_id: ] +[responder_id: ] +[IP: ] + +* := IA32/X64 | IA64 + +* := IA32 | IA64 | X64 + +# := +[cache error][, TLB error][, bus error][, micro-architectural error] + +* := unknown or generic | data read | data write | \ +instruction execution + +# := +[restartable][, precise IP][, overflow][, corrected] + + := +[error_status: ] +[physical_address: ] +[physical_address_mask: ] +[node: ] +[card: ] +[module: ] +[bank: ] +[device: ] +[row: ] +[column: ] +[bit_position: ] +[requestor_id: ] +[responder_id: ] +[target_id: ] +[error_type: , ] + +* := +unknown | no error | single-bit ECC | multi-bit ECC | \ +single-symbol chipkill ECC | multi-symbol chipkill ECC | master abort | \ +target abort | parity error | watchdog timeout | invalid address | \ +mirror Broken | memory sparing | scrub corrected error | \ +scrub uncorrected error + + := +[port_type: , ] +[version: .] +[command: , status: ] +[device_id: ::. +slot: +secondary_bus: +vendor_id: , device_id: +class_code: ] +[serial number: , ] +[bridge: secondary_status: , control: ] + +* := PCIe end point | legacy PCI end point | \ +unknown | unknown | root port | upstream switch port | \ +downstream switch port | PCIe to PCI/PCI-X bridge | \ +PCI/PCI-X to PCIe bridge | root complex integrated endpoint device | \ +root complex event collector + +Where, [] designate corresponding content is optional + +All description with * has the following format: + +field: , + +Where value of should be the position of "string" in description. Otherwise, will be "unknown". + +All description with # has the following format: + +field: + + +Where each string in corresponding to one set bit of +. The bit position is the position of "string" in description. + +For more detailed explanation of every field, please refer to UEFI +specification version 2.3 or later, section Appendix N: Common +Platform Error Record. diff --git a/drivers/acpi/apei/apei-internal.h b/drivers/acpi/apei/apei-internal.h index 18df1e940276..ef0581f2094d 100644 --- a/drivers/acpi/apei/apei-internal.h +++ b/drivers/acpi/apei/apei-internal.h @@ -109,6 +109,8 @@ static inline u32 apei_estatus_len(struct acpi_hest_generic_status *estatus) return sizeof(*estatus) + estatus->data_length; } +void apei_estatus_print(const char *pfx, + const struct acpi_hest_generic_status *estatus); int apei_estatus_check_header(const struct acpi_hest_generic_status *estatus); int apei_estatus_check(const struct acpi_hest_generic_status *estatus); #endif diff --git a/drivers/acpi/apei/cper.c b/drivers/acpi/apei/cper.c index f4cf2fc4c8c1..31464a006d76 100644 --- a/drivers/acpi/apei/cper.c +++ b/drivers/acpi/apei/cper.c @@ -46,6 +46,317 @@ u64 cper_next_record_id(void) } EXPORT_SYMBOL_GPL(cper_next_record_id); +static const char *cper_severity_strs[] = { + "recoverable", + "fatal", + "corrected", + "info", +}; + +static const char *cper_severity_str(unsigned int severity) +{ + return severity < ARRAY_SIZE(cper_severity_strs) ? + cper_severity_strs[severity] : "unknown"; +} + +/* + * cper_print_bits - print strings for set bits + * @pfx: prefix for each line, including log level and prefix string + * @bits: bit mask + * @strs: string array, indexed by bit position + * @strs_size: size of the string array: @strs + * + * For each set bit in @bits, print the corresponding string in @strs. + * If the output length is longer than 80, multiple line will be + * printed, with @pfx is printed at the beginning of each line. + */ +static void cper_print_bits(const char *pfx, unsigned int bits, + const char *strs[], unsigned int strs_size) +{ + int i, len = 0; + const char *str; + char buf[84]; + + for (i = 0; i < strs_size; i++) { + if (!(bits & (1U << i))) + continue; + str = strs[i]; + if (len && len + strlen(str) + 2 > 80) { + printk("%s\n", buf); + len = 0; + } + if (!len) + len = snprintf(buf, sizeof(buf), "%s%s", pfx, str); + else + len += snprintf(buf+len, sizeof(buf)-len, ", %s", str); + } + if (len) + printk("%s\n", buf); +} + +static const char *cper_proc_type_strs[] = { + "IA32/X64", + "IA64", +}; + +static const char *cper_proc_isa_strs[] = { + "IA32", + "IA64", + "X64", +}; + +static const char *cper_proc_error_type_strs[] = { + "cache error", + "TLB error", + "bus error", + "micro-architectural error", +}; + +static const char *cper_proc_op_strs[] = { + "unknown or generic", + "data read", + "data write", + "instruction execution", +}; + +static const char *cper_proc_flag_strs[] = { + "restartable", + "precise IP", + "overflow", + "corrected", +}; + +static void cper_print_proc_generic(const char *pfx, + const struct cper_sec_proc_generic *proc) +{ + if (proc->validation_bits & CPER_PROC_VALID_TYPE) + printk("%s""processor_type: %d, %s\n", pfx, proc->proc_type, + proc->proc_type < ARRAY_SIZE(cper_proc_type_strs) ? + cper_proc_type_strs[proc->proc_type] : "unknown"); + if (proc->validation_bits & CPER_PROC_VALID_ISA) + printk("%s""processor_isa: %d, %s\n", pfx, proc->proc_isa, + proc->proc_isa < ARRAY_SIZE(cper_proc_isa_strs) ? + cper_proc_isa_strs[proc->proc_isa] : "unknown"); + if (proc->validation_bits & CPER_PROC_VALID_ERROR_TYPE) { + printk("%s""error_type: 0x%02x\n", pfx, proc->proc_error_type); + cper_print_bits(pfx, proc->proc_error_type, + cper_proc_error_type_strs, + ARRAY_SIZE(cper_proc_error_type_strs)); + } + if (proc->validation_bits & CPER_PROC_VALID_OPERATION) + printk("%s""operation: %d, %s\n", pfx, proc->operation, + proc->operation < ARRAY_SIZE(cper_proc_op_strs) ? + cper_proc_op_strs[proc->operation] : "unknown"); + if (proc->validation_bits & CPER_PROC_VALID_FLAGS) { + printk("%s""flags: 0x%02x\n", pfx, proc->flags); + cper_print_bits(pfx, proc->flags, cper_proc_flag_strs, + ARRAY_SIZE(cper_proc_flag_strs)); + } + if (proc->validation_bits & CPER_PROC_VALID_LEVEL) + printk("%s""level: %d\n", pfx, proc->level); + if (proc->validation_bits & CPER_PROC_VALID_VERSION) + printk("%s""version_info: 0x%016llx\n", pfx, proc->cpu_version); + if (proc->validation_bits & CPER_PROC_VALID_ID) + printk("%s""processor_id: 0x%016llx\n", pfx, proc->proc_id); + if (proc->validation_bits & CPER_PROC_VALID_TARGET_ADDRESS) + printk("%s""target_address: 0x%016llx\n", + pfx, proc->target_addr); + if (proc->validation_bits & CPER_PROC_VALID_REQUESTOR_ID) + printk("%s""requestor_id: 0x%016llx\n", + pfx, proc->requestor_id); + if (proc->validation_bits & CPER_PROC_VALID_RESPONDER_ID) + printk("%s""responder_id: 0x%016llx\n", + pfx, proc->responder_id); + if (proc->validation_bits & CPER_PROC_VALID_IP) + printk("%s""IP: 0x%016llx\n", pfx, proc->ip); +} + +static const char *cper_mem_err_type_strs[] = { + "unknown", + "no error", + "single-bit ECC", + "multi-bit ECC", + "single-symbol chipkill ECC", + "multi-symbol chipkill ECC", + "master abort", + "target abort", + "parity error", + "watchdog timeout", + "invalid address", + "mirror Broken", + "memory sparing", + "scrub corrected error", + "scrub uncorrected error", +}; + +static void cper_print_mem(const char *pfx, const struct cper_sec_mem_err *mem) +{ + if (mem->validation_bits & CPER_MEM_VALID_ERROR_STATUS) + printk("%s""error_status: 0x%016llx\n", pfx, mem->error_status); + if (mem->validation_bits & CPER_MEM_VALID_PHYSICAL_ADDRESS) + printk("%s""physical_address: 0x%016llx\n", + pfx, mem->physical_addr); + if (mem->validation_bits & CPER_MEM_VALID_PHYSICAL_ADDRESS_MASK) + printk("%s""physical_address_mask: 0x%016llx\n", + pfx, mem->physical_addr_mask); + if (mem->validation_bits & CPER_MEM_VALID_NODE) + printk("%s""node: %d\n", pfx, mem->node); + if (mem->validation_bits & CPER_MEM_VALID_CARD) + printk("%s""card: %d\n", pfx, mem->card); + if (mem->validation_bits & CPER_MEM_VALID_MODULE) + printk("%s""module: %d\n", pfx, mem->module); + if (mem->validation_bits & CPER_MEM_VALID_BANK) + printk("%s""bank: %d\n", pfx, mem->bank); + if (mem->validation_bits & CPER_MEM_VALID_DEVICE) + printk("%s""device: %d\n", pfx, mem->device); + if (mem->validation_bits & CPER_MEM_VALID_ROW) + printk("%s""row: %d\n", pfx, mem->row); + if (mem->validation_bits & CPER_MEM_VALID_COLUMN) + printk("%s""column: %d\n", pfx, mem->column); + if (mem->validation_bits & CPER_MEM_VALID_BIT_POSITION) + printk("%s""bit_position: %d\n", pfx, mem->bit_pos); + if (mem->validation_bits & CPER_MEM_VALID_REQUESTOR_ID) + printk("%s""requestor_id: 0x%016llx\n", pfx, mem->requestor_id); + if (mem->validation_bits & CPER_MEM_VALID_RESPONDER_ID) + printk("%s""responder_id: 0x%016llx\n", pfx, mem->responder_id); + if (mem->validation_bits & CPER_MEM_VALID_TARGET_ID) + printk("%s""target_id: 0x%016llx\n", pfx, mem->target_id); + if (mem->validation_bits & CPER_MEM_VALID_ERROR_TYPE) { + u8 etype = mem->error_type; + printk("%s""error_type: %d, %s\n", pfx, etype, + etype < ARRAY_SIZE(cper_mem_err_type_strs) ? + cper_mem_err_type_strs[etype] : "unknown"); + } +} + +static const char *cper_pcie_port_type_strs[] = { + "PCIe end point", + "legacy PCI end point", + "unknown", + "unknown", + "root port", + "upstream switch port", + "downstream switch port", + "PCIe to PCI/PCI-X bridge", + "PCI/PCI-X to PCIe bridge", + "root complex integrated endpoint device", + "root complex event collector", +}; + +static void cper_print_pcie(const char *pfx, const struct cper_sec_pcie *pcie) +{ + if (pcie->validation_bits & CPER_PCIE_VALID_PORT_TYPE) + printk("%s""port_type: %d, %s\n", pfx, pcie->port_type, + pcie->port_type < ARRAY_SIZE(cper_pcie_port_type_strs) ? + cper_pcie_port_type_strs[pcie->port_type] : "unknown"); + if (pcie->validation_bits & CPER_PCIE_VALID_VERSION) + printk("%s""version: %d.%d\n", pfx, + pcie->version.major, pcie->version.minor); + if (pcie->validation_bits & CPER_PCIE_VALID_COMMAND_STATUS) + printk("%s""command: 0x%04x, status: 0x%04x\n", pfx, + pcie->command, pcie->status); + if (pcie->validation_bits & CPER_PCIE_VALID_DEVICE_ID) { + const __u8 *p; + printk("%s""device_id: %04x:%02x:%02x.%x\n", pfx, + pcie->device_id.segment, pcie->device_id.bus, + pcie->device_id.device, pcie->device_id.function); + printk("%s""slot: %d\n", pfx, + pcie->device_id.slot >> CPER_PCIE_SLOT_SHIFT); + printk("%s""secondary_bus: 0x%02x\n", pfx, + pcie->device_id.secondary_bus); + printk("%s""vendor_id: 0x%04x, device_id: 0x%04x\n", pfx, + pcie->device_id.vendor_id, pcie->device_id.device_id); + p = pcie->device_id.class_code; + printk("%s""class_code: %02x%02x%02x\n", pfx, p[0], p[1], p[2]); + } + if (pcie->validation_bits & CPER_PCIE_VALID_SERIAL_NUMBER) + printk("%s""serial number: 0x%04x, 0x%04x\n", pfx, + pcie->serial_number.lower, pcie->serial_number.upper); + if (pcie->validation_bits & CPER_PCIE_VALID_BRIDGE_CONTROL_STATUS) + printk( + "%s""bridge: secondary_status: 0x%04x, control: 0x%04x\n", + pfx, pcie->bridge.secondary_status, pcie->bridge.control); +} + +static const char *apei_estatus_section_flag_strs[] = { + "primary", + "containment warning", + "reset", + "threshold exceeded", + "resource not accessible", + "latent error", +}; + +static void apei_estatus_print_section( + const char *pfx, const struct acpi_hest_generic_data *gdata, int sec_no) +{ + uuid_le *sec_type = (uuid_le *)gdata->section_type; + __u16 severity; + + severity = gdata->error_severity; + printk("%s""section: %d, severity: %d, %s\n", pfx, sec_no, severity, + cper_severity_str(severity)); + printk("%s""flags: 0x%02x\n", pfx, gdata->flags); + cper_print_bits(pfx, gdata->flags, apei_estatus_section_flag_strs, + ARRAY_SIZE(apei_estatus_section_flag_strs)); + if (gdata->validation_bits & CPER_SEC_VALID_FRU_ID) + printk("%s""fru_id: %pUl\n", pfx, (uuid_le *)gdata->fru_id); + if (gdata->validation_bits & CPER_SEC_VALID_FRU_TEXT) + printk("%s""fru_text: %.20s\n", pfx, gdata->fru_text); + + if (!uuid_le_cmp(*sec_type, CPER_SEC_PROC_GENERIC)) { + struct cper_sec_proc_generic *proc_err = (void *)(gdata + 1); + printk("%s""section_type: general processor error\n", pfx); + if (gdata->error_data_length >= sizeof(*proc_err)) + cper_print_proc_generic(pfx, proc_err); + else + goto err_section_too_small; + } else if (!uuid_le_cmp(*sec_type, CPER_SEC_PLATFORM_MEM)) { + struct cper_sec_mem_err *mem_err = (void *)(gdata + 1); + printk("%s""section_type: memory error\n", pfx); + if (gdata->error_data_length >= sizeof(*mem_err)) + cper_print_mem(pfx, mem_err); + else + goto err_section_too_small; + } else if (!uuid_le_cmp(*sec_type, CPER_SEC_PCIE)) { + struct cper_sec_pcie *pcie = (void *)(gdata + 1); + printk("%s""section_type: PCIe error\n", pfx); + if (gdata->error_data_length >= sizeof(*pcie)) + cper_print_pcie(pfx, pcie); + else + goto err_section_too_small; + } else + printk("%s""section type: unknown, %pUl\n", pfx, sec_type); + + return; + +err_section_too_small: + pr_err(FW_WARN "error section length is too small\n"); +} + +void apei_estatus_print(const char *pfx, + const struct acpi_hest_generic_status *estatus) +{ + struct acpi_hest_generic_data *gdata; + unsigned int data_len, gedata_len; + int sec_no = 0; + __u16 severity; + + printk("%s""APEI generic hardware error status\n", pfx); + severity = estatus->error_severity; + printk("%s""severity: %d, %s\n", pfx, severity, + cper_severity_str(severity)); + data_len = estatus->data_length; + gdata = (struct acpi_hest_generic_data *)(estatus + 1); + while (data_len > sizeof(*gdata)) { + gedata_len = gdata->error_data_length; + apei_estatus_print_section(pfx, gdata, sec_no); + data_len -= gedata_len + sizeof(*gdata); + sec_no++; + } +} +EXPORT_SYMBOL_GPL(apei_estatus_print); + int apei_estatus_check_header(const struct acpi_hest_generic_status *estatus) { if (estatus->data_length && -- cgit v1.2.3 From 32c361f574f85fa47600d84900598e2efc99082e Mon Sep 17 00:00:00 2001 From: Huang Ying Date: Tue, 7 Dec 2010 10:22:31 +0800 Subject: ACPI, APEI, Report GHES error information via printk printk is one of the methods to report hardware errors to user space. This patch implements hardware error reporting for GHES via printk. Signed-off-by: Huang Ying Signed-off-by: Len Brown --- drivers/acpi/apei/ghes.c | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c index 0d505e59214d..51905d07a4d9 100644 --- a/drivers/acpi/apei/ghes.c +++ b/drivers/acpi/apei/ghes.c @@ -43,6 +43,7 @@ #include #include #include +#include #include #include #include @@ -255,11 +256,26 @@ static void ghes_do_proc(struct ghes *ghes) } #endif } +} - if (!processed && printk_ratelimit()) - pr_warning(GHES_PFX - "Unknown error record from generic hardware error source: %d\n", - ghes->generic->header.source_id); +static void ghes_print_estatus(const char *pfx, struct ghes *ghes) +{ + /* Not more than 2 messages every 5 seconds */ + static DEFINE_RATELIMIT_STATE(ratelimit, 5*HZ, 2); + + if (pfx == NULL) { + if (ghes_severity(ghes->estatus->error_severity) <= + GHES_SEV_CORRECTED) + pfx = KERN_WARNING HW_ERR; + else + pfx = KERN_ERR HW_ERR; + } + if (__ratelimit(&ratelimit)) { + printk( + "%s""Hardware error from APEI Generic Hardware Error Source: %d\n", + pfx, ghes->generic->header.source_id); + apei_estatus_print(pfx, ghes->estatus); + } } static int ghes_proc(struct ghes *ghes) @@ -269,6 +285,7 @@ static int ghes_proc(struct ghes *ghes) rc = ghes_read_estatus(ghes, 0); if (rc) goto out; + ghes_print_estatus(NULL, ghes); ghes_do_proc(ghes); out: -- cgit v1.2.3 From cef6e8a3790d6bdc305496629c357a56001d59a6 Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Mon, 6 Dec 2010 15:04:15 +0800 Subject: ACPI processor: remove processor throttling control procfs I/F Remove deprecated ACPI process procfs I/F for throttling control. This is because the t-state control should only be done in kernel, when system is in a overheating state. Now users can only change the processor t-state indirectly, by poking the cooling device sysfs I/F of the processor. Signed-off-by: Zhang Rui Signed-off-by: Len Brown --- drivers/acpi/Kconfig | 4 -- drivers/acpi/processor_driver.c | 75 +----------------------- drivers/acpi/processor_throttling.c | 114 ------------------------------------ 3 files changed, 1 insertion(+), 192 deletions(-) diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index 3f3489c5ca8c..5959077be0a4 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig @@ -53,10 +53,6 @@ config ACPI_PROCFS they have been replaced by functions in /sys. The deprecated files (and their replacements) include: - /proc/acpi/processor/*/throttling (/sys/class/thermal/ - cooling_device*/*) - /proc/acpi/video/*/brightness (/sys/class/backlight/) - /proc/acpi/thermal_zone/*/* (/sys/class/thermal/) This option has no effect on /proc/acpi/ files and functions which do not yet exist in /sys. diff --git a/drivers/acpi/processor_driver.c b/drivers/acpi/processor_driver.c index 85e48047d7b0..29572debc65d 100644 --- a/drivers/acpi/processor_driver.c +++ b/drivers/acpi/processor_driver.c @@ -40,10 +40,6 @@ #include #include #include -#ifdef CONFIG_ACPI_PROCFS -#include -#include -#endif #include #include #include @@ -246,53 +242,6 @@ static int acpi_processor_errata(struct acpi_processor *pr) return result; } -#ifdef CONFIG_ACPI_PROCFS -static struct proc_dir_entry *acpi_processor_dir = NULL; - -static int __cpuinit acpi_processor_add_fs(struct acpi_device *device) -{ - struct proc_dir_entry *entry = NULL; - - - if (!acpi_device_dir(device)) { - acpi_device_dir(device) = proc_mkdir(acpi_device_bid(device), - acpi_processor_dir); - if (!acpi_device_dir(device)) - return -ENODEV; - } - - /* 'throttling' [R/W] */ - entry = proc_create_data(ACPI_PROCESSOR_FILE_THROTTLING, - S_IFREG | S_IRUGO | S_IWUSR, - acpi_device_dir(device), - &acpi_processor_throttling_fops, - acpi_driver_data(device)); - if (!entry) - return -EIO; - return 0; -} -static int acpi_processor_remove_fs(struct acpi_device *device) -{ - - if (acpi_device_dir(device)) { - remove_proc_entry(ACPI_PROCESSOR_FILE_THROTTLING, - acpi_device_dir(device)); - remove_proc_entry(acpi_device_bid(device), acpi_processor_dir); - acpi_device_dir(device) = NULL; - } - - return 0; -} -#else -static inline int acpi_processor_add_fs(struct acpi_device *device) -{ - return 0; -} -static inline int acpi_processor_remove_fs(struct acpi_device *device) -{ - return 0; -} -#endif /* -------------------------------------------------------------------------- Driver Interface -------------------------------------------------------------------------- */ @@ -537,14 +486,10 @@ static int __cpuinit acpi_processor_add(struct acpi_device *device) per_cpu(processors, pr->id) = pr; - result = acpi_processor_add_fs(device); - if (result) - goto err_free_cpumask; - sysdev = get_cpu_sysdev(pr->id); if (sysfs_create_link(&device->dev.kobj, &sysdev->kobj, "sysdev")) { result = -EFAULT; - goto err_remove_fs; + goto err_free_cpumask; } #ifdef CONFIG_CPU_FREQ @@ -590,8 +535,6 @@ err_thermal_unregister: thermal_cooling_device_unregister(pr->cdev); err_power_exit: acpi_processor_power_exit(pr, device); -err_remove_fs: - acpi_processor_remove_fs(device); err_free_cpumask: free_cpumask_var(pr->throttling.shared_cpu_map); @@ -620,8 +563,6 @@ static int acpi_processor_remove(struct acpi_device *device, int type) sysfs_remove_link(&device->dev.kobj, "sysdev"); - acpi_processor_remove_fs(device); - if (pr->cdev) { sysfs_remove_link(&device->dev.kobj, "thermal_cooling"); sysfs_remove_link(&pr->cdev->device.kobj, "device"); @@ -854,12 +795,6 @@ static int __init acpi_processor_init(void) memset(&errata, 0, sizeof(errata)); -#ifdef CONFIG_ACPI_PROCFS - acpi_processor_dir = proc_mkdir(ACPI_PROCESSOR_CLASS, acpi_root_dir); - if (!acpi_processor_dir) - return -ENOMEM; -#endif - if (!cpuidle_register_driver(&acpi_idle_driver)) { printk(KERN_DEBUG "ACPI: %s registered with cpuidle\n", acpi_idle_driver.name); @@ -885,10 +820,6 @@ static int __init acpi_processor_init(void) out_cpuidle: cpuidle_unregister_driver(&acpi_idle_driver); -#ifdef CONFIG_ACPI_PROCFS - remove_proc_entry(ACPI_PROCESSOR_CLASS, acpi_root_dir); -#endif - return result; } @@ -907,10 +838,6 @@ static void __exit acpi_processor_exit(void) cpuidle_unregister_driver(&acpi_idle_driver); -#ifdef CONFIG_ACPI_PROCFS - remove_proc_entry(ACPI_PROCESSOR_CLASS, acpi_root_dir); -#endif - return; } diff --git a/drivers/acpi/processor_throttling.c b/drivers/acpi/processor_throttling.c index ff3632717c51..4a0eec5dd24a 100644 --- a/drivers/acpi/processor_throttling.c +++ b/drivers/acpi/processor_throttling.c @@ -32,10 +32,6 @@ #include #include #include -#ifdef CONFIG_ACPI_PROCFS -#include -#include -#endif #include #include @@ -1216,113 +1212,3 @@ int acpi_processor_get_throttling_info(struct acpi_processor *pr) return result; } -#ifdef CONFIG_ACPI_PROCFS -/* proc interface */ -static int acpi_processor_throttling_seq_show(struct seq_file *seq, - void *offset) -{ - struct acpi_processor *pr = seq->private; - int i = 0; - int result = 0; - - if (!pr) - goto end; - - if (!(pr->throttling.state_count > 0)) { - seq_puts(seq, "\n"); - goto end; - } - - result = acpi_processor_get_throttling(pr); - - if (result) { - seq_puts(seq, - "Could not determine current throttling state.\n"); - goto end; - } - - seq_printf(seq, "state count: %d\n" - "active state: T%d\n" - "state available: T%d to T%d\n", - pr->throttling.state_count, pr->throttling.state, - pr->throttling_platform_limit, - pr->throttling.state_count - 1); - - seq_puts(seq, "states:\n"); - if (pr->throttling.acpi_processor_get_throttling == - acpi_processor_get_throttling_fadt) { - for (i = 0; i < pr->throttling.state_count; i++) - seq_printf(seq, " %cT%d: %02d%%\n", - (i == pr->throttling.state ? '*' : ' '), i, - (pr->throttling.states[i].performance ? pr-> - throttling.states[i].performance / 10 : 0)); - } else { - for (i = 0; i < pr->throttling.state_count; i++) - seq_printf(seq, " %cT%d: %02d%%\n", - (i == pr->throttling.state ? '*' : ' '), i, - (int)pr->throttling.states_tss[i]. - freqpercentage); - } - - end: - return 0; -} - -static int acpi_processor_throttling_open_fs(struct inode *inode, - struct file *file) -{ - return single_open(file, acpi_processor_throttling_seq_show, - PDE(inode)->data); -} - -static ssize_t acpi_processor_write_throttling(struct file *file, - const char __user * buffer, - size_t count, loff_t * data) -{ - int result = 0; - struct seq_file *m = file->private_data; - struct acpi_processor *pr = m->private; - char state_string[5] = ""; - char *charp = NULL; - size_t state_val = 0; - char tmpbuf[5] = ""; - - if (!pr || (count > sizeof(state_string) - 1)) - return -EINVAL; - - if (copy_from_user(state_string, buffer, count)) - return -EFAULT; - - state_string[count] = '\0'; - if ((count > 0) && (state_string[count-1] == '\n')) - state_string[count-1] = '\0'; - - charp = state_string; - if ((state_string[0] == 't') || (state_string[0] == 'T')) - charp++; - - state_val = simple_strtoul(charp, NULL, 0); - if (state_val >= pr->throttling.state_count) - return -EINVAL; - - snprintf(tmpbuf, 5, "%zu", state_val); - - if (strcmp(tmpbuf, charp) != 0) - return -EINVAL; - - result = acpi_processor_set_throttling(pr, state_val, false); - if (result) - return result; - - return count; -} - -const struct file_operations acpi_processor_throttling_fops = { - .owner = THIS_MODULE, - .open = acpi_processor_throttling_open_fs, - .read = seq_read, - .write = acpi_processor_write_throttling, - .llseek = seq_lseek, - .release = single_release, -}; -#endif -- cgit v1.2.3 From 677bd810eedce61edf15452491781ff046b92edc Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Mon, 6 Dec 2010 15:04:21 +0800 Subject: ACPI video: remove output switching control Remove the ACPI video output switching control as it never works. With the patch applied, ACPI video driver still catches the video output notification, but it does nothing but raises the notification to userspace. Signed-off-by: Zhang Rui Signed-off-by: Len Brown --- Documentation/kernel-parameters.txt | 5 --- drivers/acpi/video.c | 86 ------------------------------------- drivers/acpi/video_detect.c | 57 ++---------------------- drivers/gpu/drm/Kconfig | 1 - drivers/gpu/stub/Kconfig | 1 - 5 files changed, 4 insertions(+), 146 deletions(-) diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index cdd2a6e8a3b7..f91fc5a65034 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -199,11 +199,6 @@ and is between 256 and 4096 characters. It is defined in the file unusable. The "log_buf_len" parameter may be useful if you need to capture more output. - acpi_display_output= [HW,ACPI] - acpi_display_output=vendor - acpi_display_output=video - See above. - acpi_irq_balance [HW,ACPI] ACPI will balance active IRQs default in APIC mode diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index 5cd0228d2daa..81766ebec843 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c @@ -33,7 +33,6 @@ #include #include #include -#include #include #include #include @@ -172,9 +171,6 @@ struct acpi_video_device_cap { u8 _BQC:1; /* Get current brightness level */ u8 _BCQ:1; /* Some buggy BIOS uses _BCQ instead of _BQC */ u8 _DDC:1; /*Return the EDID for this device */ - u8 _DCS:1; /*Return status of output device */ - u8 _DGS:1; /*Query graphics state */ - u8 _DSS:1; /*Device state set */ }; struct acpi_video_brightness_flags { @@ -202,7 +198,6 @@ struct acpi_video_device { struct acpi_video_device_brightness *brightness; struct backlight_device *backlight; struct thermal_cooling_device *cooling_dev; - struct output_device *output_dev; }; static const char device_decode[][30] = { @@ -226,10 +221,6 @@ static int acpi_video_get_next_level(struct acpi_video_device *device, u32 level_current, u32 event); static int acpi_video_switch_brightness(struct acpi_video_device *device, int event); -static int acpi_video_device_get_state(struct acpi_video_device *device, - unsigned long long *state); -static int acpi_video_output_get(struct output_device *od); -static int acpi_video_device_set_state(struct acpi_video_device *device, int state); /*backlight device sysfs support*/ static int acpi_video_get_brightness(struct backlight_device *bd) @@ -265,30 +256,6 @@ static struct backlight_ops acpi_backlight_ops = { .update_status = acpi_video_set_brightness, }; -/*video output device sysfs support*/ -static int acpi_video_output_get(struct output_device *od) -{ - unsigned long long state; - struct acpi_video_device *vd = - (struct acpi_video_device *)dev_get_drvdata(&od->dev); - acpi_video_device_get_state(vd, &state); - return (int)state; -} - -static int acpi_video_output_set(struct output_device *od) -{ - unsigned long state = od->request_state; - struct acpi_video_device *vd= - (struct acpi_video_device *)dev_get_drvdata(&od->dev); - return acpi_video_device_set_state(vd, state); -} - -static struct output_properties acpi_output_properties = { - .set_state = acpi_video_output_set, - .get_status = acpi_video_output_get, -}; - - /* thermal cooling device callbacks */ static int video_get_max_state(struct thermal_cooling_device *cooling_dev, unsigned long *state) @@ -344,34 +311,6 @@ static struct thermal_cooling_device_ops video_cooling_ops = { Video Management -------------------------------------------------------------------------- */ -/* device */ - -static int -acpi_video_device_get_state(struct acpi_video_device *device, - unsigned long long *state) -{ - int status; - - status = acpi_evaluate_integer(device->dev->handle, "_DCS", NULL, state); - - return status; -} - -static int -acpi_video_device_set_state(struct acpi_video_device *device, int state) -{ - int status; - union acpi_object arg0 = { ACPI_TYPE_INTEGER }; - struct acpi_object_list args = { 1, &arg0 }; - unsigned long long ret; - - - arg0.integer.value = state; - status = acpi_evaluate_integer(device->dev->handle, "_DSS", &args, &ret); - - return status; -} - static int acpi_video_device_lcd_query_levels(struct acpi_video_device *device, union acpi_object **levels) @@ -831,15 +770,6 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device) if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_DDC", &h_dummy1))) { device->cap._DDC = 1; } - if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_DCS", &h_dummy1))) { - device->cap._DCS = 1; - } - if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_DGS", &h_dummy1))) { - device->cap._DGS = 1; - } - if (ACPI_SUCCESS(acpi_get_handle(device->dev->handle, "_DSS", &h_dummy1))) { - device->cap._DSS = 1; - } if (acpi_video_backlight_support()) { struct backlight_properties props; @@ -904,21 +834,6 @@ static void acpi_video_device_find_cap(struct acpi_video_device *device) printk(KERN_ERR PREFIX "Create sysfs link\n"); } - - if (acpi_video_display_switch_support()) { - - if (device->cap._DCS && device->cap._DSS) { - static int count; - char *name; - name = kasprintf(GFP_KERNEL, "acpi_video%d", count); - if (!name) - return; - count++; - device->output_dev = video_output_register(name, - NULL, device, &acpi_output_properties); - kfree(name); - } - } } /* @@ -1452,7 +1367,6 @@ static int acpi_video_bus_put_one_device(struct acpi_video_device *device) thermal_cooling_device_unregister(device->cooling_dev); device->cooling_dev = NULL; } - video_output_unregister(device->output_dev); return 0; } diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c index b83676126598..42d3d72dae85 100644 --- a/drivers/acpi/video_detect.c +++ b/drivers/acpi/video_detect.c @@ -17,15 +17,14 @@ * capabilities the graphics cards plugged in support. The check for general * video capabilities will be triggered by the first caller of * acpi_video_get_capabilities(NULL); which will happen when the first - * backlight (or display output) switching supporting driver calls: + * backlight switching supporting driver calls: * acpi_video_backlight_support(); * * Depending on whether ACPI graphics extensions (cmp. ACPI spec Appendix B) * are available, video.ko should be used to handle the device. * * Otherwise vendor specific drivers like thinkpad_acpi, asus_acpi, - * sony_acpi,... can take care about backlight brightness and display output - * switching. + * sony_acpi,... can take care about backlight brightness. * * If CONFIG_ACPI_VIDEO is neither set as "compiled in" (y) nor as a module (m) * this file will not be compiled, acpi_video_get_capabilities() and @@ -83,11 +82,6 @@ long acpi_is_video_device(struct acpi_device *device) if (!device) return 0; - /* Is this device able to support video switching ? */ - if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_DOD", &h_dummy)) || - ACPI_SUCCESS(acpi_get_handle(device->handle, "_DOS", &h_dummy))) - video_caps |= ACPI_VIDEO_OUTPUT_SWITCHING; - /* Is this device able to retrieve a video ROM ? */ if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_ROM", &h_dummy))) video_caps |= ACPI_VIDEO_ROM_AVAILABLE; @@ -161,8 +155,6 @@ long acpi_video_get_capabilities(acpi_handle graphics_handle) * * if (dmi_name_in_vendors("XY")) { * acpi_video_support |= - * ACPI_VIDEO_OUTPUT_SWITCHING_DMI_VENDOR; - * acpi_video_support |= * ACPI_VIDEO_BACKLIGHT_DMI_VENDOR; *} */ @@ -212,33 +204,8 @@ int acpi_video_backlight_support(void) EXPORT_SYMBOL(acpi_video_backlight_support); /* - * Returns true if video.ko can do display output switching. - * This does not work well/at all with binary graphics drivers - * which disable system io ranges and do it on their own. - */ -int acpi_video_display_switch_support(void) -{ - if (!acpi_video_caps_checked) - acpi_video_get_capabilities(NULL); - - if (acpi_video_support & ACPI_VIDEO_OUTPUT_SWITCHING_FORCE_VENDOR) - return 0; - else if (acpi_video_support & ACPI_VIDEO_OUTPUT_SWITCHING_FORCE_VIDEO) - return 1; - - if (acpi_video_support & ACPI_VIDEO_OUTPUT_SWITCHING_DMI_VENDOR) - return 0; - else if (acpi_video_support & ACPI_VIDEO_OUTPUT_SWITCHING_DMI_VIDEO) - return 1; - - return acpi_video_support & ACPI_VIDEO_OUTPUT_SWITCHING; -} -EXPORT_SYMBOL(acpi_video_display_switch_support); - -/* - * Use acpi_display_output=vendor/video or acpi_backlight=vendor/video - * To force that backlight or display output switching is processed by vendor - * specific acpi drivers or video.ko driver. + * Use acpi_backlight=vendor/video to force that backlight switching + * is processed by vendor specific acpi drivers or video.ko driver. */ static int __init acpi_backlight(char *str) { @@ -255,19 +222,3 @@ static int __init acpi_backlight(char *str) return 1; } __setup("acpi_backlight=", acpi_backlight); - -static int __init acpi_display_output(char *str) -{ - if (str == NULL || *str == '\0') - return 1; - else { - if (!strcmp("vendor", str)) - acpi_video_support |= - ACPI_VIDEO_OUTPUT_SWITCHING_FORCE_VENDOR; - if (!strcmp("video", str)) - acpi_video_support |= - ACPI_VIDEO_OUTPUT_SWITCHING_FORCE_VIDEO; - } - return 1; -} -__setup("acpi_display_output=", acpi_display_output); diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig index 7af443672626..64828a7db77b 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig @@ -107,7 +107,6 @@ config DRM_I915 select FB_CFB_IMAGEBLIT # i915 depends on ACPI_VIDEO when ACPI is enabled # but for select to work, need to select ACPI_VIDEO's dependencies, ick - select VIDEO_OUTPUT_CONTROL if ACPI select BACKLIGHT_CLASS_DEVICE if ACPI select INPUT if ACPI select ACPI_VIDEO if ACPI diff --git a/drivers/gpu/stub/Kconfig b/drivers/gpu/stub/Kconfig index 0e1edd7311ff..09aea5f1556d 100644 --- a/drivers/gpu/stub/Kconfig +++ b/drivers/gpu/stub/Kconfig @@ -3,7 +3,6 @@ config STUB_POULSBO depends on PCI # Poulsbo stub depends on ACPI_VIDEO when ACPI is enabled # but for select to work, need to select ACPI_VIDEO's dependencies, ick - select VIDEO_OUTPUT_CONTROL if ACPI select BACKLIGHT_CLASS_DEVICE if ACPI select INPUT if ACPI select ACPI_VIDEO if ACPI -- cgit v1.2.3 From 82069552555cf951d9ade5c1aec61dd40b0765b5 Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Mon, 6 Dec 2010 15:04:24 +0800 Subject: ACPI video: check cap._DDC flag before getting EDID cap._DDC is defined but never used. Check this flag now and don't try to get EDID for video output devices with this flag cleared. Signed-off-by: Zhang Rui Signed-off-by: Len Brown --- drivers/acpi/video.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index 81766ebec843..177b4ddc3479 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c @@ -1275,6 +1275,9 @@ int acpi_video_get_edid(struct acpi_device *device, int type, int device_id, if (!video_device) continue; + if (!video_device->cap._DDC) + continue; + if (type) { switch (type) { case ACPI_VIDEO_DISPLAY_CRT: -- cgit v1.2.3 From 99fd1895ef603f1a0fa9af478c96c637a7b4529d Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Mon, 6 Dec 2010 15:04:27 +0800 Subject: ACPI video: introduce module parameter video.use_bios_initial_backlight Introduce module parameter video.use_bios_initial_backlight. Some BIOSes claim they use the minimum backlight at boot, and this may bring dimming screen after boot. https://bugzilla.kernel.org/show_bug.cgi?id=21212 use video.use_bios_initl_backlight=0 to use the maximum backlight level after boot. Signed-off-by: Zhang Rui Signed-off-by: Len Brown --- drivers/acpi/video.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index 5cd0228d2daa..89f19a8fc726 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c @@ -81,6 +81,13 @@ module_param(brightness_switch_enabled, bool, 0644); static int allow_duplicates; module_param(allow_duplicates, bool, 0644); +/* + * Some BIOSes claim they use minimum backlight at boot, + * and this may bring dimming screen after boot + */ +static int use_bios_initial_backlight = 1; +module_param(use_bios_initial_backlight, bool, 0644); + static int register_count = 0; static int acpi_video_bus_add(struct acpi_device *device); static int acpi_video_bus_remove(struct acpi_device *device, int type); @@ -766,9 +773,11 @@ acpi_video_init_brightness(struct acpi_video_device *device) * when invoked for the first time, i.e. level_old is invalid. * set the backlight to max_level in this case */ - for (i = 2; i < br->count; i++) - if (level_old == br->levels[i]) - level = level_old; + if (use_bios_initial_backlight) { + for (i = 2; i < br->count; i++) + if (level_old == br->levels[i]) + level = level_old; + } goto set_level; } -- cgit v1.2.3 From 16f4232ce4d6855361b4eb56262f4a202295c978 Mon Sep 17 00:00:00 2001 From: Zhao Yakui Date: Wed, 8 Dec 2010 10:10:16 +0800 Subject: IPMI: Add one interface to get more info of low-level IPMI device The IPMI smi_watcher will be used to catch the IPMI interface as they come or go. In order to communicate with the correct IPMI device, it should be confirmed whether it is what we wanted especially on the system with multiple IPMI devices. But the new_smi callback function of smi_watcher provides very limited info(only the interface number and dev pointer) and there is no detailed info about the low level interface. For example: which mechansim registers the IPMI interface(ACPI, PCI, DMI and so on). This is to add one interface that can get more info of low-level IPMI device. For example: the ACPI device handle will be returned for the pnp_acpi IPMI device. Signed-off-by: Zhao Yakui Signed-off-by: Corey Minyard Signed-off-by: Len Brown --- drivers/char/ipmi/ipmi_msghandler.c | 27 ++++++++++++++++++++++++++ drivers/char/ipmi/ipmi_si_intf.c | 20 +++++++++++++++---- include/linux/ipmi.h | 38 +++++++++++++++++++++++++++++++++++++ include/linux/ipmi_smi.h | 8 ++++++++ 4 files changed, 89 insertions(+), 4 deletions(-) diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c index 2fe72f8edf44..38223e93aa98 100644 --- a/drivers/char/ipmi/ipmi_msghandler.c +++ b/drivers/char/ipmi/ipmi_msghandler.c @@ -970,6 +970,33 @@ out_kfree: } EXPORT_SYMBOL(ipmi_create_user); +int ipmi_get_smi_info(int if_num, struct ipmi_smi_info *data) +{ + int rv = 0; + ipmi_smi_t intf; + struct ipmi_smi_handlers *handlers; + + mutex_lock(&ipmi_interfaces_mutex); + list_for_each_entry_rcu(intf, &ipmi_interfaces, link) { + if (intf->intf_num == if_num) + goto found; + } + /* Not found, return an error */ + rv = -EINVAL; + mutex_unlock(&ipmi_interfaces_mutex); + return rv; + +found: + handlers = intf->handlers; + rv = -ENOSYS; + if (handlers->get_smi_info) + rv = handlers->get_smi_info(intf->send_info, data); + mutex_unlock(&ipmi_interfaces_mutex); + + return rv; +} +EXPORT_SYMBOL(ipmi_get_smi_info); + static void free_user(struct kref *ref) { ipmi_user_t user = container_of(ref, struct ipmi_user, refcount); diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index 035da9e64a17..945ae4d5d21f 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c @@ -57,6 +57,7 @@ #include #include #include +#include #include #include #include "ipmi_si_sm.h" @@ -107,10 +108,6 @@ enum si_type { }; static char *si_to_str[] = { "kcs", "smic", "bt" }; -enum ipmi_addr_src { - SI_INVALID = 0, SI_HOTMOD, SI_HARDCODED, SI_SPMI, SI_ACPI, SI_SMBIOS, - SI_PCI, SI_DEVICETREE, SI_DEFAULT -}; static char *ipmi_addr_src_to_str[] = { NULL, "hotmod", "hardcoded", "SPMI", "ACPI", "SMBIOS", "PCI", "device-tree", "default" }; @@ -291,6 +288,7 @@ struct smi_info { struct task_struct *thread; struct list_head link; + union ipmi_smi_info_union addr_info; }; #define smi_inc_stat(smi, stat) \ @@ -1186,6 +1184,18 @@ static int smi_start_processing(void *send_info, return 0; } +static int get_smi_info(void *send_info, struct ipmi_smi_info *data) +{ + struct smi_info *smi = send_info; + + data->addr_src = smi->addr_source; + data->dev = smi->dev; + data->addr_info = smi->addr_info; + get_device(smi->dev); + + return 0; +} + static void set_maintenance_mode(void *send_info, int enable) { struct smi_info *smi_info = send_info; @@ -1197,6 +1207,7 @@ static void set_maintenance_mode(void *send_info, int enable) static struct ipmi_smi_handlers handlers = { .owner = THIS_MODULE, .start_processing = smi_start_processing, + .get_smi_info = get_smi_info, .sender = sender, .request_events = request_events, .set_maintenance_mode = set_maintenance_mode, @@ -2156,6 +2167,7 @@ static int __devinit ipmi_pnp_probe(struct pnp_dev *dev, printk(KERN_INFO PFX "probing via ACPI\n"); handle = acpi_dev->handle; + info->addr_info.acpi_info.acpi_handle = handle; /* _IFT tells us the interface type: KCS, BT, etc */ status = acpi_evaluate_integer(handle, "_IFT", NULL, &tmp); diff --git a/include/linux/ipmi.h b/include/linux/ipmi.h index 65aae34759de..045f2f275cd0 100644 --- a/include/linux/ipmi.h +++ b/include/linux/ipmi.h @@ -454,6 +454,44 @@ unsigned int ipmi_addr_length(int addr_type); /* Validate that the given IPMI address is valid. */ int ipmi_validate_addr(struct ipmi_addr *addr, int len); +/* + * How did the IPMI driver find out about the device? + */ +enum ipmi_addr_src { + SI_INVALID = 0, SI_HOTMOD, SI_HARDCODED, SI_SPMI, SI_ACPI, SI_SMBIOS, + SI_PCI, SI_DEVICETREE, SI_DEFAULT +}; + +union ipmi_smi_info_union { + /* + * the acpi_info element is defined for the SI_ACPI + * address type + */ + struct { + void *acpi_handle; + } acpi_info; +}; + +struct ipmi_smi_info { + enum ipmi_addr_src addr_src; + + /* + * Base device for the interface. Don't forget to put this when + * you are done. + */ + struct device *dev; + + /* + * The addr_info provides more detailed info for some IPMI + * devices, depending on the addr_src. Currently only SI_ACPI + * info is provided. + */ + union ipmi_smi_info_union addr_info; +}; + +/* This is to get the private info of ipmi_smi_t */ +extern int ipmi_get_smi_info(int if_num, struct ipmi_smi_info *data); + #endif /* __KERNEL__ */ diff --git a/include/linux/ipmi_smi.h b/include/linux/ipmi_smi.h index 4b48318ac542..906590aa6907 100644 --- a/include/linux/ipmi_smi.h +++ b/include/linux/ipmi_smi.h @@ -39,6 +39,7 @@ #include #include #include +#include /* This files describes the interface for IPMI system management interface drivers to bind into the IPMI message handler. */ @@ -86,6 +87,13 @@ struct ipmi_smi_handlers { int (*start_processing)(void *send_info, ipmi_smi_t new_intf); + /* + * Get the detailed private info of the low level interface and store + * it into the structure of ipmi_smi_data. For example: the + * ACPI device handle will be returned for the pnp_acpi IPMI device. + */ + int (*get_smi_info)(void *send_info, struct ipmi_smi_info *data); + /* Called to enqueue an SMI message to be sent. This operation is not allowed to fail. If an error occurs, it should report back the error in a received message. It may -- cgit v1.2.3 From 37bf501bdda1d5d6ea73ce29d4b00d291b6f3811 Mon Sep 17 00:00:00 2001 From: Zhao Yakui Date: Wed, 8 Dec 2010 10:10:17 +0800 Subject: IPMI: Add the document description of ipmi_get_smi_info Add the document description about how to use ipmi_get_smi_info. Signed-off-by: Zhao Yakui Signed-off-by: Corey Minyard Signed-off-by: Len Brown --- Documentation/IPMI.txt | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/Documentation/IPMI.txt b/Documentation/IPMI.txt index 69dd29ed824e..b2bea15137d2 100644 --- a/Documentation/IPMI.txt +++ b/Documentation/IPMI.txt @@ -533,6 +533,33 @@ completion during sending a panic event. Other Pieces ------------ +Get the detailed info related with the IPMI device +-------------------------------------------------- + +Some users need more detailed information about a device, like where +the address came from or the raw base device for the IPMI interface. +You can use the IPMI smi_watcher to catch the IPMI interfaces as they +come or go, and to grab the information, you can use the function +ipmi_get_smi_info(), which returns the following structure: + +struct ipmi_smi_info { + enum ipmi_addr_src addr_src; + struct device *dev; + union { + struct { + void *acpi_handle; + } acpi_info; + } addr_info; +}; + +Currently special info for only for SI_ACPI address sources is +returned. Others may be added as necessary. + +Note that the dev pointer is included in the above structure, and +assuming ipmi_smi_get_info returns success, you must call put_device +on the dev pointer. + + Watchdog -------- -- cgit v1.2.3 From e92b297cc72ade7a58eaec7e01c906d856f8ab6e Mon Sep 17 00:00:00 2001 From: Zhao Yakui Date: Wed, 8 Dec 2010 10:10:18 +0800 Subject: IPMI/ACPI: Add the IPMI opregion driver to enable ACPI to access BMC controller ACPI 4.0 spec adds the ACPI IPMI opregion, which means that the ACPI AML code can also communicate with the BMC controller. This is to install the ACPI IPMI opregion and enable the ACPI to access the BMC controller through the IPMI message. It will create IPMI user interface for every IPMI device detected in ACPI namespace and install the corresponding IPMI opregion space handler. Then it can enable ACPI to access the BMC controller through the IPMI message. The following describes how to process the IPMI request in IPMI space handler: 1. format the IPMI message based on the request in AML code. IPMI system address. Now the address type is SYSTEM_INTERFACE_ADDR_TYPE IPMI net function & command IPMI message payload 2. send the IPMI message by using the function of ipmi_request_settime 3. wait for the completion of IPMI message. It can be done in different routes: One is in handled in IPMI user recv callback function. Another is handled in timeout function. 4. format the IPMI response and return it to ACPI AML code. At the same time it also addes the module dependency. The ACPI IPMI opregion will depend on the IPMI subsystem. Signed-off-by: Zhao Yakui cc: Bjorn Helgaas Signed-off-by: Corey Minyard Signed-off-by: Len Brown --- drivers/acpi/Kconfig | 11 + drivers/acpi/Makefile | 1 + drivers/acpi/acpi_ipmi.c | 525 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 537 insertions(+) create mode 100644 drivers/acpi/acpi_ipmi.c diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index 3f3489c5ca8c..a0c03658b2ea 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig @@ -209,6 +209,17 @@ config ACPI_PROCESSOR To compile this driver as a module, choose M here: the module will be called processor. +config ACPI_IPMI + tristate "IPMI" + depends on EXPERIMENTAL && IPMI_SI && IPMI_HANDLER + default n + help + This driver enables the ACPI to access the BMC controller. And it + uses the IPMI request/response message to communicate with BMC + controller, which can be found on on the server. + + To compile this driver as a module, choose M here: + the module will be called as acpi_ipmi. config ACPI_HOTPLUG_CPU bool diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile index 3d031d02e54b..df4c4f030388 100644 --- a/drivers/acpi/Makefile +++ b/drivers/acpi/Makefile @@ -69,5 +69,6 @@ processor-y += processor_idle.o processor_thermal.o processor-$(CONFIG_CPU_FREQ) += processor_perflib.o obj-$(CONFIG_ACPI_PROCESSOR_AGGREGATOR) += acpi_pad.o +obj-$(CONFIG_ACPI_IPMI) += acpi_ipmi.o obj-$(CONFIG_ACPI_APEI) += apei/ diff --git a/drivers/acpi/acpi_ipmi.c b/drivers/acpi/acpi_ipmi.c new file mode 100644 index 000000000000..f40acef80269 --- /dev/null +++ b/drivers/acpi/acpi_ipmi.c @@ -0,0 +1,525 @@ +/* + * acpi_ipmi.c - ACPI IPMI opregion + * + * Copyright (C) 2010 Intel Corporation + * Copyright (C) 2010 Zhao Yakui + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + * + * 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. + * + * 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. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. + * + * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +MODULE_AUTHOR("Zhao Yakui"); +MODULE_DESCRIPTION("ACPI IPMI Opregion driver"); +MODULE_LICENSE("GPL"); + +#define IPMI_FLAGS_HANDLER_INSTALL 0 + +#define ACPI_IPMI_OK 0 +#define ACPI_IPMI_TIMEOUT 0x10 +#define ACPI_IPMI_UNKNOWN 0x07 +/* the IPMI timeout is 5s */ +#define IPMI_TIMEOUT (5 * HZ) + +struct acpi_ipmi_device { + /* the device list attached to driver_data.ipmi_devices */ + struct list_head head; + /* the IPMI request message list */ + struct list_head tx_msg_list; + struct mutex tx_msg_lock; + acpi_handle handle; + struct pnp_dev *pnp_dev; + ipmi_user_t user_interface; + int ipmi_ifnum; /* IPMI interface number */ + long curr_msgid; + unsigned long flags; + struct ipmi_smi_info smi_data; +}; + +struct ipmi_driver_data { + struct list_head ipmi_devices; + struct ipmi_smi_watcher bmc_events; + struct ipmi_user_hndl ipmi_hndlrs; + struct mutex ipmi_lock; +}; + +struct acpi_ipmi_msg { + struct list_head head; + /* + * General speaking the addr type should be SI_ADDR_TYPE. And + * the addr channel should be BMC. + * In fact it can also be IPMB type. But we will have to + * parse it from the Netfn command buffer. It is so complex + * that it is skipped. + */ + struct ipmi_addr addr; + long tx_msgid; + /* it is used to track whether the IPMI message is finished */ + struct completion tx_complete; + struct kernel_ipmi_msg tx_message; + int msg_done; + /* tx data . And copy it from ACPI object buffer */ + u8 tx_data[64]; + int tx_len; + u8 rx_data[64]; + int rx_len; + struct acpi_ipmi_device *device; +}; + +/* IPMI request/response buffer per ACPI 4.0, sec 5.5.2.4.3.2 */ +struct acpi_ipmi_buffer { + u8 status; + u8 length; + u8 data[64]; +}; + +static void ipmi_register_bmc(int iface, struct device *dev); +static void ipmi_bmc_gone(int iface); +static void ipmi_msg_handler(struct ipmi_recv_msg *msg, void *user_msg_data); +static void acpi_add_ipmi_device(struct acpi_ipmi_device *ipmi_device); +static void acpi_remove_ipmi_device(struct acpi_ipmi_device *ipmi_device); + +static struct ipmi_driver_data driver_data = { + .ipmi_devices = LIST_HEAD_INIT(driver_data.ipmi_devices), + .bmc_events = { + .owner = THIS_MODULE, + .new_smi = ipmi_register_bmc, + .smi_gone = ipmi_bmc_gone, + }, + .ipmi_hndlrs = { + .ipmi_recv_hndl = ipmi_msg_handler, + }, +}; + +static struct acpi_ipmi_msg *acpi_alloc_ipmi_msg(struct acpi_ipmi_device *ipmi) +{ + struct acpi_ipmi_msg *ipmi_msg; + struct pnp_dev *pnp_dev = ipmi->pnp_dev; + + ipmi_msg = kzalloc(sizeof(struct acpi_ipmi_msg), GFP_KERNEL); + if (!ipmi_msg) { + dev_warn(&pnp_dev->dev, "Can't allocate memory for ipmi_msg\n"); + return NULL; + } + init_completion(&ipmi_msg->tx_complete); + INIT_LIST_HEAD(&ipmi_msg->head); + ipmi_msg->device = ipmi; + return ipmi_msg; +} + +#define IPMI_OP_RGN_NETFN(offset) ((offset >> 8) & 0xff) +#define IPMI_OP_RGN_CMD(offset) (offset & 0xff) +static void acpi_format_ipmi_msg(struct acpi_ipmi_msg *tx_msg, + acpi_physical_address address, + acpi_integer *value) +{ + struct kernel_ipmi_msg *msg; + struct acpi_ipmi_buffer *buffer; + struct acpi_ipmi_device *device; + + msg = &tx_msg->tx_message; + /* + * IPMI network function and command are encoded in the address + * within the IPMI OpRegion; see ACPI 4.0, sec 5.5.2.4.3. + */ + msg->netfn = IPMI_OP_RGN_NETFN(address); + msg->cmd = IPMI_OP_RGN_CMD(address); + msg->data = tx_msg->tx_data; + /* + * value is the parameter passed by the IPMI opregion space handler. + * It points to the IPMI request message buffer + */ + buffer = (struct acpi_ipmi_buffer *)value; + /* copy the tx message data */ + msg->data_len = buffer->length; + memcpy(tx_msg->tx_data, buffer->data, msg->data_len); + /* + * now the default type is SYSTEM_INTERFACE and channel type is BMC. + * If the netfn is APP_REQUEST and the cmd is SEND_MESSAGE, + * the addr type should be changed to IPMB. Then we will have to parse + * the IPMI request message buffer to get the IPMB address. + * If so, please fix me. + */ + tx_msg->addr.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE; + tx_msg->addr.channel = IPMI_BMC_CHANNEL; + tx_msg->addr.data[0] = 0; + + /* Get the msgid */ + device = tx_msg->device; + mutex_lock(&device->tx_msg_lock); + device->curr_msgid++; + tx_msg->tx_msgid = device->curr_msgid; + mutex_unlock(&device->tx_msg_lock); +} + +static void acpi_format_ipmi_response(struct acpi_ipmi_msg *msg, + acpi_integer *value, int rem_time) +{ + struct acpi_ipmi_buffer *buffer; + + /* + * value is also used as output parameter. It represents the response + * IPMI message returned by IPMI command. + */ + buffer = (struct acpi_ipmi_buffer *)value; + if (!rem_time && !msg->msg_done) { + buffer->status = ACPI_IPMI_TIMEOUT; + return; + } + /* + * If the flag of msg_done is not set or the recv length is zero, it + * means that the IPMI command is not executed correctly. + * The status code will be ACPI_IPMI_UNKNOWN. + */ + if (!msg->msg_done || !msg->rx_len) { + buffer->status = ACPI_IPMI_UNKNOWN; + return; + } + /* + * If the IPMI response message is obtained correctly, the status code + * will be ACPI_IPMI_OK + */ + buffer->status = ACPI_IPMI_OK; + buffer->length = msg->rx_len; + memcpy(buffer->data, msg->rx_data, msg->rx_len); +} + +static void ipmi_flush_tx_msg(struct acpi_ipmi_device *ipmi) +{ + struct acpi_ipmi_msg *tx_msg, *temp; + int count = HZ / 10; + struct pnp_dev *pnp_dev = ipmi->pnp_dev; + + list_for_each_entry_safe(tx_msg, temp, &ipmi->tx_msg_list, head) { + /* wake up the sleep thread on the Tx msg */ + complete(&tx_msg->tx_complete); + } + + /* wait for about 100ms to flush the tx message list */ + while (count--) { + if (list_empty(&ipmi->tx_msg_list)) + break; + schedule_timeout(1); + } + if (!list_empty(&ipmi->tx_msg_list)) + dev_warn(&pnp_dev->dev, "tx msg list is not NULL\n"); +} + +static void ipmi_msg_handler(struct ipmi_recv_msg *msg, void *user_msg_data) +{ + struct acpi_ipmi_device *ipmi_device = user_msg_data; + int msg_found = 0; + struct acpi_ipmi_msg *tx_msg; + struct pnp_dev *pnp_dev = ipmi_device->pnp_dev; + + if (msg->user != ipmi_device->user_interface) { + dev_warn(&pnp_dev->dev, "Unexpected response is returned. " + "returned user %p, expected user %p\n", + msg->user, ipmi_device->user_interface); + ipmi_free_recv_msg(msg); + return; + } + mutex_lock(&ipmi_device->tx_msg_lock); + list_for_each_entry(tx_msg, &ipmi_device->tx_msg_list, head) { + if (msg->msgid == tx_msg->tx_msgid) { + msg_found = 1; + break; + } + } + + mutex_unlock(&ipmi_device->tx_msg_lock); + if (!msg_found) { + dev_warn(&pnp_dev->dev, "Unexpected response (msg id %ld) is " + "returned.\n", msg->msgid); + ipmi_free_recv_msg(msg); + return; + } + + if (msg->msg.data_len) { + /* copy the response data to Rx_data buffer */ + memcpy(tx_msg->rx_data, msg->msg_data, msg->msg.data_len); + tx_msg->rx_len = msg->msg.data_len; + tx_msg->msg_done = 1; + } + complete(&tx_msg->tx_complete); + ipmi_free_recv_msg(msg); +}; + +static void ipmi_register_bmc(int iface, struct device *dev) +{ + struct acpi_ipmi_device *ipmi_device, *temp; + struct pnp_dev *pnp_dev; + ipmi_user_t user; + int err; + struct ipmi_smi_info smi_data; + acpi_handle handle; + + err = ipmi_get_smi_info(iface, &smi_data); + + if (err) + return; + + if (smi_data.addr_src != SI_ACPI) { + put_device(smi_data.dev); + return; + } + + handle = smi_data.addr_info.acpi_info.acpi_handle; + + mutex_lock(&driver_data.ipmi_lock); + list_for_each_entry(temp, &driver_data.ipmi_devices, head) { + /* + * if the corresponding ACPI handle is already added + * to the device list, don't add it again. + */ + if (temp->handle == handle) + goto out; + } + + ipmi_device = kzalloc(sizeof(*ipmi_device), GFP_KERNEL); + + if (!ipmi_device) + goto out; + + pnp_dev = to_pnp_dev(smi_data.dev); + ipmi_device->handle = handle; + ipmi_device->pnp_dev = pnp_dev; + + err = ipmi_create_user(iface, &driver_data.ipmi_hndlrs, + ipmi_device, &user); + if (err) { + dev_warn(&pnp_dev->dev, "Can't create IPMI user interface\n"); + kfree(ipmi_device); + goto out; + } + acpi_add_ipmi_device(ipmi_device); + ipmi_device->user_interface = user; + ipmi_device->ipmi_ifnum = iface; + mutex_unlock(&driver_data.ipmi_lock); + memcpy(&ipmi_device->smi_data, &smi_data, sizeof(struct ipmi_smi_info)); + return; + +out: + mutex_unlock(&driver_data.ipmi_lock); + put_device(smi_data.dev); + return; +} + +static void ipmi_bmc_gone(int iface) +{ + struct acpi_ipmi_device *ipmi_device, *temp; + + mutex_lock(&driver_data.ipmi_lock); + list_for_each_entry_safe(ipmi_device, temp, + &driver_data.ipmi_devices, head) { + if (ipmi_device->ipmi_ifnum != iface) + continue; + + acpi_remove_ipmi_device(ipmi_device); + put_device(ipmi_device->smi_data.dev); + kfree(ipmi_device); + break; + } + mutex_unlock(&driver_data.ipmi_lock); +} +/* -------------------------------------------------------------------------- + * Address Space Management + * -------------------------------------------------------------------------- */ +/* + * This is the IPMI opregion space handler. + * @function: indicates the read/write. In fact as the IPMI message is driven + * by command, only write is meaningful. + * @address: This contains the netfn/command of IPMI request message. + * @bits : not used. + * @value : it is an in/out parameter. It points to the IPMI message buffer. + * Before the IPMI message is sent, it represents the actual request + * IPMI message. After the IPMI message is finished, it represents + * the response IPMI message returned by IPMI command. + * @handler_context: IPMI device context. + */ + +static acpi_status +acpi_ipmi_space_handler(u32 function, acpi_physical_address address, + u32 bits, acpi_integer *value, + void *handler_context, void *region_context) +{ + struct acpi_ipmi_msg *tx_msg; + struct acpi_ipmi_device *ipmi_device = handler_context; + int err, rem_time; + acpi_status status; + /* + * IPMI opregion message. + * IPMI message is firstly written to the BMC and system software + * can get the respsonse. So it is unmeaningful for the read access + * of IPMI opregion. + */ + if ((function & ACPI_IO_MASK) == ACPI_READ) + return AE_TYPE; + + if (!ipmi_device->user_interface) + return AE_NOT_EXIST; + + tx_msg = acpi_alloc_ipmi_msg(ipmi_device); + if (!tx_msg) + return AE_NO_MEMORY; + + acpi_format_ipmi_msg(tx_msg, address, value); + mutex_lock(&ipmi_device->tx_msg_lock); + list_add_tail(&tx_msg->head, &ipmi_device->tx_msg_list); + mutex_unlock(&ipmi_device->tx_msg_lock); + err = ipmi_request_settime(ipmi_device->user_interface, + &tx_msg->addr, + tx_msg->tx_msgid, + &tx_msg->tx_message, + NULL, 0, 0, 0); + if (err) { + status = AE_ERROR; + goto end_label; + } + rem_time = wait_for_completion_timeout(&tx_msg->tx_complete, + IPMI_TIMEOUT); + acpi_format_ipmi_response(tx_msg, value, rem_time); + status = AE_OK; + +end_label: + mutex_lock(&ipmi_device->tx_msg_lock); + list_del(&tx_msg->head); + mutex_unlock(&ipmi_device->tx_msg_lock); + kfree(tx_msg); + return status; +} + +static void ipmi_remove_space_handler(struct acpi_ipmi_device *ipmi) +{ + if (!test_bit(IPMI_FLAGS_HANDLER_INSTALL, &ipmi->flags)) + return; + + acpi_remove_address_space_handler(ipmi->handle, + ACPI_ADR_SPACE_IPMI, &acpi_ipmi_space_handler); + + clear_bit(IPMI_FLAGS_HANDLER_INSTALL, &ipmi->flags); +} + +static int ipmi_install_space_handler(struct acpi_ipmi_device *ipmi) +{ + acpi_status status; + + if (test_bit(IPMI_FLAGS_HANDLER_INSTALL, &ipmi->flags)) + return 0; + + status = acpi_install_address_space_handler(ipmi->handle, + ACPI_ADR_SPACE_IPMI, + &acpi_ipmi_space_handler, + NULL, ipmi); + if (ACPI_FAILURE(status)) { + struct pnp_dev *pnp_dev = ipmi->pnp_dev; + dev_warn(&pnp_dev->dev, "Can't register IPMI opregion space " + "handle\n"); + return -EINVAL; + } + set_bit(IPMI_FLAGS_HANDLER_INSTALL, &ipmi->flags); + return 0; +} + +static void acpi_add_ipmi_device(struct acpi_ipmi_device *ipmi_device) +{ + + INIT_LIST_HEAD(&ipmi_device->head); + + mutex_init(&ipmi_device->tx_msg_lock); + INIT_LIST_HEAD(&ipmi_device->tx_msg_list); + ipmi_install_space_handler(ipmi_device); + + list_add_tail(&ipmi_device->head, &driver_data.ipmi_devices); +} + +static void acpi_remove_ipmi_device(struct acpi_ipmi_device *ipmi_device) +{ + /* + * If the IPMI user interface is created, it should be + * destroyed. + */ + if (ipmi_device->user_interface) { + ipmi_destroy_user(ipmi_device->user_interface); + ipmi_device->user_interface = NULL; + } + /* flush the Tx_msg list */ + if (!list_empty(&ipmi_device->tx_msg_list)) + ipmi_flush_tx_msg(ipmi_device); + + list_del(&ipmi_device->head); + ipmi_remove_space_handler(ipmi_device); +} + +static int __init acpi_ipmi_init(void) +{ + int result = 0; + + if (acpi_disabled) + return result; + + mutex_init(&driver_data.ipmi_lock); + + result = ipmi_smi_watcher_register(&driver_data.bmc_events); + + return result; +} + +static void __exit acpi_ipmi_exit(void) +{ + struct acpi_ipmi_device *ipmi_device, *temp; + + if (acpi_disabled) + return; + + ipmi_smi_watcher_unregister(&driver_data.bmc_events); + + /* + * When one smi_watcher is unregistered, it is only deleted + * from the smi_watcher list. But the smi_gone callback function + * is not called. So explicitly uninstall the ACPI IPMI oregion + * handler and free it. + */ + mutex_lock(&driver_data.ipmi_lock); + list_for_each_entry_safe(ipmi_device, temp, + &driver_data.ipmi_devices, head) { + acpi_remove_ipmi_device(ipmi_device); + put_device(ipmi_device->smi_data.dev); + kfree(ipmi_device); + } + mutex_unlock(&driver_data.ipmi_lock); +} + +module_init(acpi_ipmi_init); +module_exit(acpi_ipmi_exit); -- cgit v1.2.3 From a8cc0f421b37956262a92591f7397b200d232da6 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 13 Dec 2010 13:42:22 -0800 Subject: ALSA: ml403-ac97cr: Use vsprintf extension %pR for struct resource Signed-off-by: Joe Perches Signed-off-by: Takashi Iwai --- sound/drivers/ml403-ac97cr.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/drivers/ml403-ac97cr.c b/sound/drivers/ml403-ac97cr.c index a1282c1c0591..5cfcb908c430 100644 --- a/sound/drivers/ml403-ac97cr.c +++ b/sound/drivers/ml403-ac97cr.c @@ -1143,8 +1143,8 @@ snd_ml403_ac97cr_create(struct snd_card *card, struct platform_device *pfdev, (resource->start) + 1); if (ml403_ac97cr->port == NULL) { snd_printk(KERN_ERR SND_ML403_AC97CR_DRIVER ": " - "unable to remap memory region (%x to %x)\n", - resource->start, resource->end); + "unable to remap memory region (%pR)\n", + resource); snd_ml403_ac97cr_free(ml403_ac97cr); return -EBUSY; } -- cgit v1.2.3 From ad6d42670279da8f33f633f8a96a67cd7ef3b1da Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires Date: Tue, 14 Dec 2010 11:38:18 +0100 Subject: HID: hid-mosart: ignore buttons report This commit allows the device to be recognized as a touchscreen, and not a touchpad by xf86-input-evdev. The device has 2 modes. The first one is an emulation of a touchscreen by sending left and right button, and the second mode is the one used in dual-touch (sending trackingID, touch and else). That's why there is a hid report containing left and right buttons (9000001 and 9000002). The point is that xorg relies on these fields to determine if it's a touchpad or a touchscreen. Clearing the report (return -1) makes xorg detecting it out of the box as a quite pleasant (dual)touchscreen. Signed-off-by: Benjamin Tissoires Acked-by: Chase Douglas Signed-off-by: Jiri Kosina --- drivers/hid/hid-mosart.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/hid/hid-mosart.c b/drivers/hid/hid-mosart.c index ac5421d568f1..acd8a4983c09 100644 --- a/drivers/hid/hid-mosart.c +++ b/drivers/hid/hid-mosart.c @@ -90,6 +90,10 @@ static int mosart_input_mapping(struct hid_device *hdev, struct hid_input *hi, case 0xff000000: /* ignore HID features */ return -1; + + case HID_UP_BUTTON: + /* ignore buttons */ + return -1; } return 0; -- cgit v1.2.3 From c25bcd340033bf5b8dc30c16a99e64259f099446 Mon Sep 17 00:00:00 2001 From: Benjamin Tissoires Date: Mon, 13 Dec 2010 15:59:13 +0100 Subject: HID: hid-mosart: support suspend/resume The device has 2 modes. The first one is an emulation of a touchscreen by sending left and right button, and the second mode is the one used in dual-touch (sending trackingID, touch and else). In case of a suspend/resume, the device switch back to the first mode described above (with left and right buttons). This adds a hook in .reset_resume for the device to be switched to the correct mode (I just copied the code in mosart_probe). Signed-off-by: Benjamin Tissoires Signed-off-by: Jiri Kosina --- drivers/hid/hid-mosart.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/drivers/hid/hid-mosart.c b/drivers/hid/hid-mosart.c index acd8a4983c09..15d03811f96a 100644 --- a/drivers/hid/hid-mosart.c +++ b/drivers/hid/hid-mosart.c @@ -234,6 +234,19 @@ static int mosart_probe(struct hid_device *hdev, const struct hid_device_id *id) return ret; } +#ifdef CONFIG_PM +static int mosart_reset_resume(struct hid_device *hdev) +{ + struct hid_report_enum *re = hdev->report_enum + + HID_FEATURE_REPORT; + struct hid_report *r = re->report_id_hash[7]; + + r->field[0]->value[0] = 0x02; + usbhid_submit_report(hdev, r, USB_DIR_OUT); + return 0; +} +#endif + static void mosart_remove(struct hid_device *hdev) { hid_hw_stop(hdev); @@ -262,6 +275,9 @@ static struct hid_driver mosart_driver = { .input_mapped = mosart_input_mapped, .usage_table = mosart_grabbed_usages, .event = mosart_event, +#ifdef CONFIG_PM + .reset_resume = mosart_reset_resume, +#endif }; static int __init mosart_init(void) -- cgit v1.2.3 From d88429a695a4a9ec66e90068956bbccb25d4ac6d Mon Sep 17 00:00:00 2001 From: "Olaya, Margarita" Date: Fri, 10 Dec 2010 21:11:44 -0600 Subject: ASoC: dapm: Add output driver widget In some cases it was not possible to follow the appropiate power ON/OFF sequence like in cases where the PGA needs to be enabled before the driver and disabled before the PGA for pop reduction. Add a widget to support output driver (speaker, haptic, vibra, etc) drivers where power ON/OFF ordering is important. Signed-off-by: Margarita Olaya Cabrera Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- include/sound/soc-dapm.h | 10 ++++++++++ sound/soc/soc-dapm.c | 6 ++++++ 2 files changed, 16 insertions(+) diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h index 041e98b493b7..2f76a51bbaac 100644 --- a/include/sound/soc-dapm.h +++ b/include/sound/soc-dapm.h @@ -71,6 +71,10 @@ wcontrols, wncontrols) \ { .id = snd_soc_dapm_pga, .name = wname, .reg = wreg, .shift = wshift, \ .invert = winvert, .kcontrols = wcontrols, .num_kcontrols = wncontrols} +#define SND_SOC_DAPM_OUT_DRV(wname, wreg, wshift, winvert,\ + wcontrols, wncontrols) \ +{ .id = snd_soc_dapm_out_drv, .name = wname, .reg = wreg, .shift = wshift, \ + .invert = winvert, .kcontrols = wcontrols, .num_kcontrols = wncontrols} #define SND_SOC_DAPM_MIXER(wname, wreg, wshift, winvert, \ wcontrols, wncontrols)\ { .id = snd_soc_dapm_mixer, .name = wname, .reg = wreg, .shift = wshift, \ @@ -115,6 +119,11 @@ { .id = snd_soc_dapm_pga, .name = wname, .reg = wreg, .shift = wshift, \ .invert = winvert, .kcontrols = wcontrols, .num_kcontrols = wncontrols, \ .event = wevent, .event_flags = wflags} +#define SND_SOC_DAPM_OUT_DRV_E(wname, wreg, wshift, winvert, wcontrols, \ + wncontrols, wevent, wflags) \ +{ .id = snd_soc_dapm_out_drv, .name = wname, .reg = wreg, .shift = wshift, \ + .invert = winvert, .kcontrols = wcontrols, .num_kcontrols = wncontrols, \ + .event = wevent, .event_flags = wflags} #define SND_SOC_DAPM_MIXER_E(wname, wreg, wshift, winvert, wcontrols, \ wncontrols, wevent, wflags) \ { .id = snd_soc_dapm_mixer, .name = wname, .reg = wreg, .shift = wshift, \ @@ -368,6 +377,7 @@ enum snd_soc_dapm_type { snd_soc_dapm_mixer, /* mixes several analog signals together */ snd_soc_dapm_mixer_named_ctl, /* mixer with named controls */ snd_soc_dapm_pga, /* programmable gain/attenuation (volume) */ + snd_soc_dapm_out_drv, /* output driver */ snd_soc_dapm_adc, /* analog to digital converter */ snd_soc_dapm_dac, /* digital to analog converter */ snd_soc_dapm_micbias, /* microphone bias (power) */ diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index b521a139305a..3d310af28907 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -62,6 +62,7 @@ static int dapm_up_seq[] = { [snd_soc_dapm_mixer_named_ctl] = 7, [snd_soc_dapm_pga] = 8, [snd_soc_dapm_adc] = 9, + [snd_soc_dapm_out_drv] = 10, [snd_soc_dapm_hp] = 10, [snd_soc_dapm_spk] = 10, [snd_soc_dapm_post] = 11, @@ -72,6 +73,7 @@ static int dapm_down_seq[] = { [snd_soc_dapm_adc] = 1, [snd_soc_dapm_hp] = 2, [snd_soc_dapm_spk] = 2, + [snd_soc_dapm_out_drv] = 2, [snd_soc_dapm_pga] = 4, [snd_soc_dapm_mixer_named_ctl] = 5, [snd_soc_dapm_mixer] = 5, @@ -235,6 +237,7 @@ static void dapm_set_path_status(struct snd_soc_dapm_widget *w, break; /* does not effect routing - always connected */ case snd_soc_dapm_pga: + case snd_soc_dapm_out_drv: case snd_soc_dapm_output: case snd_soc_dapm_adc: case snd_soc_dapm_input: @@ -1250,6 +1253,7 @@ static ssize_t dapm_widget_show(struct device *dev, case snd_soc_dapm_dac: case snd_soc_dapm_adc: case snd_soc_dapm_pga: + case snd_soc_dapm_out_drv: case snd_soc_dapm_mixer: case snd_soc_dapm_mixer_named_ctl: case snd_soc_dapm_supply: @@ -1428,6 +1432,7 @@ static int snd_soc_dapm_add_route(struct snd_soc_dapm_context *dapm, case snd_soc_dapm_adc: case snd_soc_dapm_dac: case snd_soc_dapm_pga: + case snd_soc_dapm_out_drv: case snd_soc_dapm_input: case snd_soc_dapm_output: case snd_soc_dapm_micbias: @@ -1545,6 +1550,7 @@ int snd_soc_dapm_new_widgets(struct snd_soc_dapm_context *dapm) w->power_check = dapm_dac_check_power; break; case snd_soc_dapm_pga: + case snd_soc_dapm_out_drv: w->power_check = dapm_generic_check_power; dapm_new_pga(dapm, w); break; -- cgit v1.2.3 From b13c2b96bf15b9dd0f1a45fd788f3a3025c5aec6 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 13 Dec 2010 16:54:50 +0000 Subject: drm/i915/ringbuffer: Make IRQ refcnting atomic In order to enforce the correct memory barriers for irq get/put, we need to perform the actual counting using atomic operations. Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_gem.c | 37 ++++++++++++++------------- drivers/gpu/drm/i915/i915_irq.c | 17 +++++++------ drivers/gpu/drm/i915/intel_ringbuffer.c | 44 +++++++++++++++++++-------------- drivers/gpu/drm/i915/intel_ringbuffer.h | 4 +-- 4 files changed, 56 insertions(+), 46 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 27fa2a1b26a5..726c2ccd674c 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -2000,17 +2000,19 @@ i915_do_wait_request(struct drm_device *dev, uint32_t seqno, trace_i915_gem_request_wait_begin(dev, seqno); ring->waiting_seqno = seqno; - ring->irq_get(ring); - if (interruptible) - ret = wait_event_interruptible(ring->irq_queue, - i915_seqno_passed(ring->get_seqno(ring), seqno) - || atomic_read(&dev_priv->mm.wedged)); - else - wait_event(ring->irq_queue, - i915_seqno_passed(ring->get_seqno(ring), seqno) - || atomic_read(&dev_priv->mm.wedged)); + ret = -ENODEV; + if (ring->irq_get(ring)) { + if (interruptible) + ret = wait_event_interruptible(ring->irq_queue, + i915_seqno_passed(ring->get_seqno(ring), seqno) + || atomic_read(&dev_priv->mm.wedged)); + else + wait_event(ring->irq_queue, + i915_seqno_passed(ring->get_seqno(ring), seqno) + || atomic_read(&dev_priv->mm.wedged)); - ring->irq_put(ring); + ring->irq_put(ring); + } ring->waiting_seqno = 0; trace_i915_gem_request_wait_end(dev, seqno); @@ -3157,14 +3159,15 @@ i915_gem_ring_throttle(struct drm_device *dev, struct drm_file *file) * generation is designed to be run atomically and so is * lockless. */ - ring->irq_get(ring); - ret = wait_event_interruptible(ring->irq_queue, - i915_seqno_passed(ring->get_seqno(ring), seqno) - || atomic_read(&dev_priv->mm.wedged)); - ring->irq_put(ring); + if (ring->irq_get(ring)) { + ret = wait_event_interruptible(ring->irq_queue, + i915_seqno_passed(ring->get_seqno(ring), seqno) + || atomic_read(&dev_priv->mm.wedged)); + ring->irq_put(ring); - if (ret == 0 && atomic_read(&dev_priv->mm.wedged)) - ret = -EIO; + if (ret == 0 && atomic_read(&dev_priv->mm.wedged)) + ret = -EIO; + } } if (ret == 0) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 02e4dd82f754..2ddb98b5c90f 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -1186,10 +1186,9 @@ void i915_trace_irq_get(struct drm_device *dev, u32 seqno) drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; struct intel_ring_buffer *ring = LP_RING(dev_priv); - if (dev_priv->trace_irq_seqno == 0) - ring->irq_get(ring); - - dev_priv->trace_irq_seqno = seqno; + if (dev_priv->trace_irq_seqno == 0 && + ring->irq_get(ring)) + dev_priv->trace_irq_seqno = seqno; } static int i915_wait_irq(struct drm_device * dev, int irq_nr) @@ -1211,10 +1210,12 @@ static int i915_wait_irq(struct drm_device * dev, int irq_nr) if (master_priv->sarea_priv) master_priv->sarea_priv->perf_boxes |= I915_BOX_WAIT; - ring->irq_get(ring); - DRM_WAIT_ON(ret, ring->irq_queue, 3 * DRM_HZ, - READ_BREADCRUMB(dev_priv) >= irq_nr); - ring->irq_put(ring); + ret = -ENODEV; + if (ring->irq_get(ring)) { + DRM_WAIT_ON(ret, ring->irq_queue, 3 * DRM_HZ, + READ_BREADCRUMB(dev_priv) >= irq_nr); + ring->irq_put(ring); + } if (ret == -EBUSY) { DRM_ERROR("EBUSY -- rec: %d emitted: %d\n", diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 74b99718a1fb..a3fd993e0de0 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -327,25 +327,28 @@ ring_get_seqno(struct intel_ring_buffer *ring) return intel_read_status_page(ring, I915_GEM_HWS_INDEX); } -static void +static bool render_ring_get_irq(struct intel_ring_buffer *ring) { struct drm_device *dev = ring->dev; - if (dev->irq_enabled && ++ring->irq_refcount == 1) { + if (!dev->irq_enabled) + return false; + + if (atomic_inc_return(&ring->irq_refcount) == 1) { drm_i915_private_t *dev_priv = dev->dev_private; unsigned long irqflags; spin_lock_irqsave(&dev_priv->irq_lock, irqflags); - if (HAS_PCH_SPLIT(dev)) ironlake_enable_graphics_irq(dev_priv, GT_USER_INTERRUPT); else i915_enable_irq(dev_priv, I915_USER_INTERRUPT); - spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); } + + return true; } static void @@ -353,8 +356,7 @@ render_ring_put_irq(struct intel_ring_buffer *ring) { struct drm_device *dev = ring->dev; - BUG_ON(dev->irq_enabled && ring->irq_refcount == 0); - if (dev->irq_enabled && --ring->irq_refcount == 0) { + if (atomic_dec_and_test(&ring->irq_refcount)) { drm_i915_private_t *dev_priv = dev->dev_private; unsigned long irqflags; @@ -417,12 +419,15 @@ ring_add_request(struct intel_ring_buffer *ring, return 0; } -static void +static bool ring_get_irq(struct intel_ring_buffer *ring, u32 flag) { struct drm_device *dev = ring->dev; - if (dev->irq_enabled && ++ring->irq_refcount == 1) { + if (!dev->irq_enabled) + return false; + + if (atomic_inc_return(&ring->irq_refcount) == 1) { drm_i915_private_t *dev_priv = dev->dev_private; unsigned long irqflags; @@ -430,6 +435,8 @@ ring_get_irq(struct intel_ring_buffer *ring, u32 flag) ironlake_enable_graphics_irq(dev_priv, flag); spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); } + + return true; } static void @@ -437,7 +444,7 @@ ring_put_irq(struct intel_ring_buffer *ring, u32 flag) { struct drm_device *dev = ring->dev; - if (dev->irq_enabled && --ring->irq_refcount == 0) { + if (atomic_dec_and_test(&ring->irq_refcount)) { drm_i915_private_t *dev_priv = dev->dev_private; unsigned long irqflags; @@ -447,16 +454,15 @@ ring_put_irq(struct intel_ring_buffer *ring, u32 flag) } } - -static void +static bool bsd_ring_get_irq(struct intel_ring_buffer *ring) { - ring_get_irq(ring, GT_BSD_USER_INTERRUPT); + return ring_get_irq(ring, GT_BSD_USER_INTERRUPT); } static void bsd_ring_put_irq(struct intel_ring_buffer *ring) { - ring_put_irq(ring, GT_BSD_USER_INTERRUPT); + ring_put_irq(ring, GT_BSD_USER_INTERRUPT); } static int @@ -846,16 +852,16 @@ gen6_ring_dispatch_execbuffer(struct intel_ring_buffer *ring, return 0; } -static void +static bool gen6_bsd_ring_get_irq(struct intel_ring_buffer *ring) { - ring_get_irq(ring, GT_GEN6_BSD_USER_INTERRUPT); + return ring_get_irq(ring, GT_GEN6_BSD_USER_INTERRUPT); } static void gen6_bsd_ring_put_irq(struct intel_ring_buffer *ring) { - ring_put_irq(ring, GT_GEN6_BSD_USER_INTERRUPT); + ring_put_irq(ring, GT_GEN6_BSD_USER_INTERRUPT); } /* ring buffer for Video Codec for Gen6+ */ @@ -876,16 +882,16 @@ static const struct intel_ring_buffer gen6_bsd_ring = { /* Blitter support (SandyBridge+) */ -static void +static bool blt_ring_get_irq(struct intel_ring_buffer *ring) { - ring_get_irq(ring, GT_BLT_USER_INTERRUPT); + return ring_get_irq(ring, GT_BLT_USER_INTERRUPT); } static void blt_ring_put_irq(struct intel_ring_buffer *ring) { - ring_put_irq(ring, GT_BLT_USER_INTERRUPT); + ring_put_irq(ring, GT_BLT_USER_INTERRUPT); } diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index 9652e4600b5e..8e2e357ad6ee 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -54,8 +54,8 @@ struct intel_ring_buffer { u32 irq_seqno; /* last seq seem at irq time */ u32 waiting_seqno; u32 sync_seqno[I915_NUM_RINGS-1]; - u32 irq_refcount; - void (*irq_get)(struct intel_ring_buffer *ring); + atomic_t irq_refcount; + bool __must_check (*irq_get)(struct intel_ring_buffer *ring); void (*irq_put)(struct intel_ring_buffer *ring); int (*init)(struct intel_ring_buffer *ring); -- cgit v1.2.3 From b5ba177d8d71f011c23b1cabec99fdaddae65c4d Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 14 Dec 2010 12:17:15 +0000 Subject: drm/i915: Poll for seqno completion if IRQ is disabled Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=32288 Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_gem.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 726c2ccd674c..5a0fbe59dd5b 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -2000,7 +2000,6 @@ i915_do_wait_request(struct drm_device *dev, uint32_t seqno, trace_i915_gem_request_wait_begin(dev, seqno); ring->waiting_seqno = seqno; - ret = -ENODEV; if (ring->irq_get(ring)) { if (interruptible) ret = wait_event_interruptible(ring->irq_queue, @@ -2012,7 +2011,10 @@ i915_do_wait_request(struct drm_device *dev, uint32_t seqno, || atomic_read(&dev_priv->mm.wedged)); ring->irq_put(ring); - } + } else if (wait_for(i915_seqno_passed(ring->get_seqno(ring), + seqno) || + atomic_read(&dev_priv->mm.wedged), 3000)) + ret = -EBUSY; ring->waiting_seqno = 0; trace_i915_gem_request_wait_end(dev, seqno); -- cgit v1.2.3 From 1874542d952bbea01997191aee868b472555fd9a Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Tue, 14 Dec 2010 11:56:56 +0100 Subject: HID: replace offsets values with their corresponding BTN_* defines Instead of using magic values, use their corresponding BTN_* defines from linux/input.h. Signed-off-by: Florian Fainelli Signed-off-by: Jiri Kosina --- drivers/hid/hid-input.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c index c0757821b1fc..e60fdb88101f 100644 --- a/drivers/hid/hid-input.c +++ b/drivers/hid/hid-input.c @@ -319,21 +319,21 @@ static void hidinput_configure_usage(struct hid_input *hidinput, struct hid_fiel switch (field->application) { case HID_GD_MOUSE: - case HID_GD_POINTER: code += 0x110; break; + case HID_GD_POINTER: code += BTN_MOUSE; break; case HID_GD_JOYSTICK: if (code <= 0xf) code += BTN_JOYSTICK; else code += BTN_TRIGGER_HAPPY; break; - case HID_GD_GAMEPAD: code += 0x130; break; + case HID_GD_GAMEPAD: code += BTN_GAMEPAD; break; default: switch (field->physical) { case HID_GD_MOUSE: - case HID_GD_POINTER: code += 0x110; break; - case HID_GD_JOYSTICK: code += 0x120; break; - case HID_GD_GAMEPAD: code += 0x130; break; - default: code += 0x100; + case HID_GD_POINTER: code += BTN_MOUSE; break; + case HID_GD_JOYSTICK: code += BTN_JOYSTICK; break; + case HID_GD_GAMEPAD: code += BTN_GAMEPAD; break; + default: code += BTN_MISC; } } -- cgit v1.2.3 From 2979076fbf17a0947d6eba367b0cac19c907c160 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Tue, 23 Nov 2010 19:54:02 -0500 Subject: headers_install: check exit status of unifdef MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If unifdef fails for any reason (like segfaulting), we should be aborting the install steps. So check its exit status in this unlikely scenario. Reported-by: Diego Elio Pettenò Signed-off-by: Mike Frysinger Signed-off-by: Michal Marek --- scripts/headers_install.pl | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/scripts/headers_install.pl b/scripts/headers_install.pl index 4ca3be3b2e50..efb3be10d428 100644 --- a/scripts/headers_install.pl +++ b/scripts/headers_install.pl @@ -45,6 +45,13 @@ foreach my $file (@files) { close $in; system $unifdef . " $tmpfile > $installdir/$file"; + # unifdef will exit 0 on success, and will exit 1 when the + # file was processed successfully but no changes were made, + # so abort only when it's higher than that. + my $e = $? >> 8; + if ($e > 1) { + die "$tmpfile: $!\n"; + } unlink $tmpfile; } exit 0; -- cgit v1.2.3 From de323f22a83b024b7432e813609c6efb74b1bbfc Mon Sep 17 00:00:00 2001 From: "akpm@linux-foundation.org" Date: Tue, 30 Nov 2010 13:51:13 -0800 Subject: headers_check: better search for functions in headers Some headers don't bother with "extern" in function prototypes, which results in said prototypes being unnoticed and exported to userland. This patch slightly improves detection of such cases by checking for C type names as well in the beginning of a line. Signed-off-by: Alexander Shishkin Cc: Stephen Hemminger Cc: Michal Marek Cc: WANG Cong Cc: Randy Dunlap Signed-off-by: Andrew Morton Signed-off-by: Michal Marek --- scripts/headers_check.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/headers_check.pl b/scripts/headers_check.pl index 50d6cfd1fa77..e0e25a1c2c12 100644 --- a/scripts/headers_check.pl +++ b/scripts/headers_check.pl @@ -64,7 +64,7 @@ sub check_include sub check_declarations { - if ($line =~m/^\s*extern\b/) { + if ($line =~m/^(\s*extern|unsigned|char|short|int|long|void)\b/) { printf STDERR "$filename:$lineno: " . "userspace cannot call function or variable " . "defined in the kernel\n"; -- cgit v1.2.3 From d52784eb3607bf887628742f99041b4f18d7d1de Mon Sep 17 00:00:00 2001 From: "akpm@linux-foundation.org" Date: Tue, 30 Nov 2010 13:52:14 -0800 Subject: headers_check: Fix warning text Fix the warning text too, per Randy. Cc: Alexander Shishkin Cc: Michal Marek Cc: Randy Dunlap Cc: Stephen Hemminger Cc: WANG Cong Signed-off-by: Andrew Morton Signed-off-by: Michal Marek --- scripts/headers_check.pl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/headers_check.pl b/scripts/headers_check.pl index e0e25a1c2c12..7957e7a5166a 100644 --- a/scripts/headers_check.pl +++ b/scripts/headers_check.pl @@ -66,8 +66,8 @@ sub check_declarations { if ($line =~m/^(\s*extern|unsigned|char|short|int|long|void)\b/) { printf STDERR "$filename:$lineno: " . - "userspace cannot call function or variable " . - "defined in the kernel\n"; + "userspace cannot reference function or " . + "variable defined in the kernel\n"; } } -- cgit v1.2.3 From 83b6542533859d6ed6c95f8b869291e885eab5bd Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 14 Dec 2010 11:25:18 +0000 Subject: ASoC: Explicitly clear WM8993 ramp controls on power down This helps ensure that the ramp logic is reset when powering back up. Signed-off-by: Mark Brown Acked-by: Liam Girdwood --- sound/soc/codecs/wm8993.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/sound/soc/codecs/wm8993.c b/sound/soc/codecs/wm8993.c index 77b1d441c3d0..15f34a26debf 100644 --- a/sound/soc/codecs/wm8993.c +++ b/sound/soc/codecs/wm8993.c @@ -1030,6 +1030,12 @@ static int wm8993_set_bias_level(struct snd_soc_codec *codec, WM8993_VMID_SEL_MASK | WM8993_BIAS_ENA, 0); + snd_soc_update_bits(codec, WM8993_ANTIPOP2, + WM8993_STARTUP_BIAS_ENA | + WM8993_VMID_BUF_ENA | + WM8993_VMID_RAMP_MASK | + WM8993_BIAS_SRC, 0); + #ifdef CONFIG_REGULATOR /* Post 2.6.34 we will be able to get a callback when * the regulators are disabled which we can use but -- cgit v1.2.3 From 465d7fcc913373783dbb4cdcf03ea05b430930d4 Mon Sep 17 00:00:00 2001 From: Dimitris Papastamos Date: Tue, 14 Dec 2010 15:15:36 +0000 Subject: ASoC: soc-cache: A few minor stylistic changes Remove redundant parentheses/spaces in the use of the sizeof operator. Signed-off-by: Dimitris Papastamos Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/soc-cache.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/sound/soc/soc-cache.c b/sound/soc/soc-cache.c index 678fd75d4511..0e17b4050425 100644 --- a/sound/soc/soc-cache.c +++ b/sound/soc/soc-cache.c @@ -85,7 +85,7 @@ static int snd_soc_4_12_spi_write(void *control_data, const char *data, msg[1] = data[0]; spi_message_init(&m); - memset(&t, 0, (sizeof t)); + memset(&t, 0, sizeof t); t.tx_buf = &msg[0]; t.len = len; @@ -166,7 +166,7 @@ static int snd_soc_7_9_spi_write(void *control_data, const char *data, msg[1] = data[1]; spi_message_init(&m); - memset(&t, 0, (sizeof t)); + memset(&t, 0, sizeof t); t.tx_buf = &msg[0]; t.len = len; @@ -246,7 +246,7 @@ static int snd_soc_8_8_spi_write(void *control_data, const char *data, msg[1] = data[1]; spi_message_init(&m); - memset(&t, 0, (sizeof t)); + memset(&t, 0, sizeof t); t.tx_buf = &msg[0]; t.len = len; @@ -326,7 +326,7 @@ static int snd_soc_8_16_spi_write(void *control_data, const char *data, msg[2] = data[2]; spi_message_init(&m); - memset(&t, 0, (sizeof t)); + memset(&t, 0, sizeof t); t.tx_buf = &msg[0]; t.len = len; @@ -513,7 +513,7 @@ static int snd_soc_16_8_spi_write(void *control_data, const char *data, msg[2] = data[2]; spi_message_init(&m); - memset(&t, 0, (sizeof t)); + memset(&t, 0, sizeof t); t.tx_buf = &msg[0]; t.len = len; @@ -633,7 +633,7 @@ static int snd_soc_16_16_spi_write(void *control_data, const char *data, msg[3] = data[3]; spi_message_init(&m); - memset(&t, 0, (sizeof t)); + memset(&t, 0, sizeof t); t.tx_buf = &msg[0]; t.len = len; @@ -1342,7 +1342,7 @@ static int snd_soc_lzo_cache_init(struct snd_soc_codec *codec) * that register. */ bmp_size = codec_drv->reg_cache_size; - sync_bmp = kmalloc(BITS_TO_LONGS(bmp_size) * sizeof (long), + sync_bmp = kmalloc(BITS_TO_LONGS(bmp_size) * sizeof(long), GFP_KERNEL); if (!sync_bmp) { ret = -ENOMEM; -- cgit v1.2.3 From dcdeda4a60b2046dd18d3dd20cbd888f25d8916b Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Tue, 14 Dec 2010 13:45:29 +0200 Subject: ASoC: TWL4030: Fix 24bit support twl4030 series of codecs supports S32_LE with msbits=24. Replace the S24_LE with S32_LE format, and add constraint for 24msbit in case of 32 S32_LE format. Signed-off-by: Peter Ujfalusi Acked-by: Mark Brown Signed-off-by: Liam Girdwood --- sound/soc/codecs/twl4030.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c index c173cf00f5cb..e4d464b937d6 100644 --- a/sound/soc/codecs/twl4030.c +++ b/sound/soc/codecs/twl4030.c @@ -1724,6 +1724,7 @@ static int twl4030_startup(struct snd_pcm_substream *substream, struct snd_soc_codec *codec = rtd->codec; struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); + snd_pcm_hw_constraint_msbits(substream->runtime, 0, 32, 24); if (twl4030->master_substream) { twl4030->slave_substream = substream; /* The DAI has one configuration for playback and capture, so @@ -1848,7 +1849,7 @@ static int twl4030_hw_params(struct snd_pcm_substream *substream, case SNDRV_PCM_FORMAT_S16_LE: format |= TWL4030_DATA_WIDTH_16S_16W; break; - case SNDRV_PCM_FORMAT_S24_LE: + case SNDRV_PCM_FORMAT_S32_LE: format |= TWL4030_DATA_WIDTH_32S_24W; break; default: @@ -2181,7 +2182,7 @@ static int twl4030_voice_set_tristate(struct snd_soc_dai *dai, int tristate) } #define TWL4030_RATES (SNDRV_PCM_RATE_8000_48000) -#define TWL4030_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FORMAT_S24_LE) +#define TWL4030_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE) static struct snd_soc_dai_ops twl4030_dai_hifi_ops = { .startup = twl4030_startup, -- cgit v1.2.3 From 1b894b59247728b02d6363d458088cf438f5ec92 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 14 Dec 2010 20:04:54 +0000 Subject: drm/i915: Pass clock limits down to PLL matcher As we already know the limits for the hardware clock, pass it down rather than recomputing them for each match. Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/intel_display.c | 34 ++++++++++++++++------------------ 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 17c213fef0ec..f2d50141e0c2 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -642,26 +642,23 @@ static const intel_limit_t intel_limits_ironlake_display_port = { .find_pll = intel_find_pll_ironlake_dp, }; -static const intel_limit_t *intel_ironlake_limit(struct drm_crtc *crtc) +static const intel_limit_t *intel_ironlake_limit(struct drm_crtc *crtc, + int refclk) { struct drm_device *dev = crtc->dev; struct drm_i915_private *dev_priv = dev->dev_private; const intel_limit_t *limit; - int refclk = 120; if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) { - if (dev_priv->lvds_use_ssc && dev_priv->lvds_ssc_freq == 100) - refclk = 100; - if ((I915_READ(PCH_LVDS) & LVDS_CLKB_POWER_MASK) == LVDS_CLKB_POWER_UP) { /* LVDS dual channel */ - if (refclk == 100) + if (refclk == 100000) limit = &intel_limits_ironlake_dual_lvds_100m; else limit = &intel_limits_ironlake_dual_lvds; } else { - if (refclk == 100) + if (refclk == 100000) limit = &intel_limits_ironlake_single_lvds_100m; else limit = &intel_limits_ironlake_single_lvds; @@ -702,13 +699,13 @@ static const intel_limit_t *intel_g4x_limit(struct drm_crtc *crtc) return limit; } -static const intel_limit_t *intel_limit(struct drm_crtc *crtc) +static const intel_limit_t *intel_limit(struct drm_crtc *crtc, int refclk) { struct drm_device *dev = crtc->dev; const intel_limit_t *limit; if (HAS_PCH_SPLIT(dev)) - limit = intel_ironlake_limit(crtc); + limit = intel_ironlake_limit(crtc, refclk); else if (IS_G4X(dev)) { limit = intel_g4x_limit(crtc); } else if (IS_PINEVIEW(dev)) { @@ -773,11 +770,10 @@ bool intel_pipe_has_type(struct drm_crtc *crtc, int type) * the given connectors. */ -static bool intel_PLL_is_valid(struct drm_crtc *crtc, intel_clock_t *clock) +static bool intel_PLL_is_valid(struct drm_device *dev, + const intel_limit_t *limit, + const intel_clock_t *clock) { - const intel_limit_t *limit = intel_limit (crtc); - struct drm_device *dev = crtc->dev; - if (clock->p1 < limit->p1.min || limit->p1.max < clock->p1) INTELPllInvalid ("p1 out of range\n"); if (clock->p < limit->p.min || limit->p.max < clock->p) @@ -849,8 +845,8 @@ intel_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, int this_err; intel_clock(dev, refclk, &clock); - - if (!intel_PLL_is_valid(crtc, &clock)) + if (!intel_PLL_is_valid(dev, limit, + &clock)) continue; this_err = abs(clock.dot - target); @@ -912,9 +908,11 @@ intel_g4x_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, int this_err; intel_clock(dev, refclk, &clock); - if (!intel_PLL_is_valid(crtc, &clock)) + if (!intel_PLL_is_valid(dev, limit, + &clock)) continue; - this_err = abs(clock.dot - target) ; + + this_err = abs(clock.dot - target); if (this_err < err_most) { *best_clock = clock; err_most = this_err; @@ -3655,7 +3653,7 @@ static int intel_crtc_mode_set(struct drm_crtc *crtc, * refclk, or FALSE. The returned values represent the clock equation: * reflck * (5 * (m1 + 2) + (m2 + 2)) / (n + 2) / p1 / p2. */ - limit = intel_limit(crtc); + limit = intel_limit(crtc, refclk); ok = limit->find_pll(limit, crtc, adjusted_mode->clock, refclk, &clock); if (!ok) { DRM_ERROR("Couldn't find PLL settings for mode!\n"); -- cgit v1.2.3 From a2d2362edf9f068bdee7d0411e0603b322f8415d Mon Sep 17 00:00:00 2001 From: Jorge Eduardo Candelaria Date: Fri, 10 Dec 2010 20:45:17 -0600 Subject: ASoC: twl6040: Add jack support for headset and handset This patch adds support for reporting twl6040 headset and handset jack events. The machine driver retrieves and report the status through twl6040_hs_jack_detect. A workq is used to debounce of the irq. Signed-off-by: Jorge Eduardo Candelaria Signed-off-by: Misael Lopez Cruz Signed-off-by: Margarita Olaya Cabrera Signed-off-by: Liam Girdwood --- sound/soc/codecs/twl6040.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++ sound/soc/codecs/twl6040.h | 7 +++++ 2 files changed, 74 insertions(+) diff --git a/sound/soc/codecs/twl6040.c b/sound/soc/codecs/twl6040.c index b92f2b737e4c..5d7e2f7b194c 100644 --- a/sound/soc/codecs/twl6040.c +++ b/sound/soc/codecs/twl6040.c @@ -42,6 +42,11 @@ #define TWL6040_RATES (SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000) #define TWL6040_FORMATS (SNDRV_PCM_FMTBIT_S32_LE) +struct twl6040_jack_data { + struct snd_soc_jack *jack; + int report; +}; + /* codec private data */ struct twl6040_data { int audpwron; @@ -52,6 +57,11 @@ struct twl6040_data { unsigned int sysclk; struct snd_pcm_hw_constraint_list *sysclk_constraints; struct completion ready; + struct twl6040_jack_data hs_jack; + struct snd_soc_codec *codec; + struct workqueue_struct *workqueue; + struct delayed_work delayed_work; + struct mutex mutex; }; /* @@ -381,6 +391,47 @@ static int twl6040_power_mode_event(struct snd_soc_dapm_widget *w, return 0; } +void twl6040_hs_jack_report(struct snd_soc_codec *codec, + struct snd_soc_jack *jack, int report) +{ + struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec); + int status; + + mutex_lock(&priv->mutex); + + /* Sync status */ + status = twl6040_read_reg_volatile(codec, TWL6040_REG_STATUS); + if (status & TWL6040_PLUGCOMP) + snd_soc_jack_report(jack, report, report); + else + snd_soc_jack_report(jack, 0, report); + + mutex_unlock(&priv->mutex); +} + +void twl6040_hs_jack_detect(struct snd_soc_codec *codec, + struct snd_soc_jack *jack, int report) +{ + struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec); + struct twl6040_jack_data *hs_jack = &priv->hs_jack; + + hs_jack->jack = jack; + hs_jack->report = report; + + twl6040_hs_jack_report(codec, hs_jack->jack, hs_jack->report); +} +EXPORT_SYMBOL_GPL(twl6040_hs_jack_detect); + +static void twl6040_accessory_work(struct work_struct *work) +{ + struct twl6040_data *priv = container_of(work, + struct twl6040_data, delayed_work.work); + struct snd_soc_codec *codec = priv->codec; + struct twl6040_jack_data *hs_jack = &priv->hs_jack; + + twl6040_hs_jack_report(codec, hs_jack->jack, hs_jack->report); +} + /* audio interrupt handler */ static irqreturn_t twl6040_naudint_handler(int irq, void *data) { @@ -396,6 +447,9 @@ static irqreturn_t twl6040_naudint_handler(int irq, void *data) break; case TWL6040_PLUGINT: case TWL6040_UNPLUGINT: + queue_delayed_work(priv->workqueue, &priv->delayed_work, + msecs_to_jiffies(200)); + break; case TWL6040_HOOKINT: break; case TWL6040_HFINT: @@ -1023,6 +1077,8 @@ static int twl6040_probe(struct snd_soc_codec *codec) return -ENOMEM; snd_soc_codec_set_drvdata(codec, priv); + priv->codec = codec; + if (twl_codec) { audpwron = twl_codec->audpwron_gpio; naudint = twl_codec->naudint_irq; @@ -1033,6 +1089,14 @@ static int twl6040_probe(struct snd_soc_codec *codec) priv->audpwron = audpwron; priv->naudint = naudint; + priv->workqueue = create_singlethread_workqueue("twl6040-codec"); + + if (!priv->workqueue) + goto work_err; + + INIT_DELAYED_WORK(&priv->delayed_work, twl6040_accessory_work); + + mutex_init(&priv->mutex); init_completion(&priv->ready); @@ -1089,6 +1153,8 @@ gpio2_err: if (gpio_is_valid(audpwron)) gpio_free(audpwron); gpio1_err: + destroy_workqueue(priv->workqueue); +work_err: kfree(priv); return ret; } @@ -1107,6 +1173,7 @@ static int twl6040_remove(struct snd_soc_codec *codec) if (naudint) free_irq(naudint, codec); + destroy_workqueue(priv->workqueue); kfree(priv); return 0; diff --git a/sound/soc/codecs/twl6040.h b/sound/soc/codecs/twl6040.h index f7c77fa58a3c..67396f63c1ec 100644 --- a/sound/soc/codecs/twl6040.h +++ b/sound/soc/codecs/twl6040.h @@ -135,4 +135,11 @@ #define TWL6040_HPPLL_ID 1 #define TWL6040_LPPLL_ID 2 +/* STATUS (0x2E) fields */ + +#define TWL6040_PLUGCOMP 0x02 + +void twl6040_hs_jack_detect(struct snd_soc_codec *codec, + struct snd_soc_jack *jack, int report); + #endif /* End of __TWL6040_H__ */ -- cgit v1.2.3 From 96dc227c9086bc84ca23af70741b2a76e3dd08eb Mon Sep 17 00:00:00 2001 From: Jorge Eduardo Candelaria Date: Fri, 10 Dec 2010 20:45:19 -0600 Subject: ASoC: sdp4430: Add Jack support Use jack framework to enable detection for the headset microphone and stereo output in the sdp4430. Signed-off-by: Jorge Eduardo Candelaria Signed-off-by: David Anders Signed-off-by: Margarita Olaya Cabrera Acked-by: Mark Brown Signed-off-by: Liam Girdwood --- sound/soc/omap/sdp4430.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/sound/soc/omap/sdp4430.c b/sound/soc/omap/sdp4430.c index 0c37c51313a8..189e03900637 100644 --- a/sound/soc/omap/sdp4430.c +++ b/sound/soc/omap/sdp4430.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -65,6 +66,21 @@ static struct snd_soc_ops sdp4430_ops = { .hw_params = sdp4430_hw_params, }; +/* Headset jack */ +static struct snd_soc_jack hs_jack; + +/*Headset jack detection DAPM pins */ +static struct snd_soc_jack_pin hs_jack_pins[] = { + { + .pin = "Headset Mic", + .mask = SND_JACK_MICROPHONE, + }, + { + .pin = "Headset Stereophone", + .mask = SND_JACK_HEADPHONE, + }, +}; + static int sdp4430_get_power_mode(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -160,6 +176,22 @@ static int sdp4430_twl6040_init(struct snd_soc_pcm_runtime *rtd) snd_soc_dapm_enable_pin(dapm, "Headset Stereophone"); ret = snd_soc_dapm_sync(dapm); + if (ret) + return ret; + + /* Headset jack detection */ + ret = snd_soc_jack_new(codec, "Headset Jack", + SND_JACK_HEADSET, &hs_jack); + if (ret) + return ret; + + ret = snd_soc_jack_add_pins(&hs_jack, ARRAY_SIZE(hs_jack_pins), + hs_jack_pins); + + if (machine_is_omap_4430sdp()) + twl6040_hs_jack_detect(codec, &hs_jack, SND_JACK_HEADSET); + else + snd_soc_jack_report(&hs_jack, SND_JACK_HEADSET, SND_JACK_HEADSET); return ret; } -- cgit v1.2.3 From 0dec1ec72317caa64f0174f8190c714ae4d51040 Mon Sep 17 00:00:00 2001 From: "Olaya, Margarita" Date: Fri, 10 Dec 2010 21:05:24 -0600 Subject: ASoC: twl6040: Update twl IO macro Update the codec to use the new twl core register macros Signed-off-by: Margarita Olaya Cabrera Acked-by: Mark Brown Signed-off-by: Liam Girdwood --- sound/soc/codecs/twl6040.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sound/soc/codecs/twl6040.c b/sound/soc/codecs/twl6040.c index 5d7e2f7b194c..d33d2b4769f3 100644 --- a/sound/soc/codecs/twl6040.c +++ b/sound/soc/codecs/twl6040.c @@ -210,7 +210,7 @@ static int twl6040_read_reg_volatile(struct snd_soc_codec *codec, if (reg >= TWL6040_CACHEREGNUM) return -EIO; - twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, &value, reg); + twl_i2c_read_u8(TWL_MODULE_AUDIO_VOICE, &value, reg); twl6040_write_reg_cache(codec, reg, value); return value; @@ -226,7 +226,7 @@ static int twl6040_write(struct snd_soc_codec *codec, return -EIO; twl6040_write_reg_cache(codec, reg, value); - return twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, value, reg); + return twl_i2c_write_u8(TWL_MODULE_AUDIO_VOICE, value, reg); } static void twl6040_init_vio_regs(struct snd_soc_codec *codec) @@ -439,7 +439,7 @@ static irqreturn_t twl6040_naudint_handler(int irq, void *data) struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec); u8 intid; - twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, &intid, TWL6040_REG_INTID); + twl_i2c_read_u8(TWL_MODULE_AUDIO_VOICE, &intid, TWL6040_REG_INTID); switch (intid) { case TWL6040_THINT: @@ -715,7 +715,7 @@ static int twl6040_power_up_completion(struct snd_soc_codec *codec, msecs_to_jiffies(48)); if (!time_left) { - twl_i2c_read_u8(TWL4030_MODULE_AUDIO_VOICE, &intid, + twl_i2c_read_u8(TWL_MODULE_AUDIO_VOICE, &intid, TWL6040_REG_INTID); if (!(intid & TWL6040_READYINT)) { dev_err(codec->dev, "timeout waiting for READYINT\n"); -- cgit v1.2.3 From cf370a5a0e9d3b111f93216a55f275d66daed952 Mon Sep 17 00:00:00 2001 From: "Olaya, Margarita" Date: Fri, 10 Dec 2010 21:05:30 -0600 Subject: ASoC: twl6040: Modify the IRQ handler Multiples interrupts can be received. The irq handler is modified to attend all of them. Signed-off-by: Margarita Olaya Cabrera Acked-by: Mark Brown Signed-off-by: Liam Girdwood --- sound/soc/codecs/twl6040.c | 30 ++++++++++++------------------ 1 file changed, 12 insertions(+), 18 deletions(-) diff --git a/sound/soc/codecs/twl6040.c b/sound/soc/codecs/twl6040.c index d33d2b4769f3..8a6c62339e39 100644 --- a/sound/soc/codecs/twl6040.c +++ b/sound/soc/codecs/twl6040.c @@ -441,30 +441,24 @@ static irqreturn_t twl6040_naudint_handler(int irq, void *data) twl_i2c_read_u8(TWL_MODULE_AUDIO_VOICE, &intid, TWL6040_REG_INTID); - switch (intid) { - case TWL6040_THINT: + if (intid & TWL6040_THINT) dev_alert(codec->dev, "die temp over-limit detection\n"); - break; - case TWL6040_PLUGINT: - case TWL6040_UNPLUGINT: + + if ((intid & TWL6040_PLUGINT) || (intid & TWL6040_UNPLUGINT)) queue_delayed_work(priv->workqueue, &priv->delayed_work, msecs_to_jiffies(200)); - break; - case TWL6040_HOOKINT: - break; - case TWL6040_HFINT: + + if (intid & TWL6040_HOOKINT) + dev_info(codec->dev, "hook detection\n"); + + if (intid & TWL6040_HFINT) dev_alert(codec->dev, "hf drivers over current detection\n"); - break; - case TWL6040_VIBINT: + + if (intid & TWL6040_VIBINT) dev_alert(codec->dev, "vib drivers over current detection\n"); - break; - case TWL6040_READYINT: + + if (intid & TWL6040_READYINT) complete(&priv->ready); - break; - default: - dev_err(codec->dev, "unknown audio interrupt %d\n", intid); - break; - } return IRQ_HANDLED; } -- cgit v1.2.3 From 370a0314ff3e1315e7fdec32a88a7ae49ccd22c8 Mon Sep 17 00:00:00 2001 From: Jorge Eduardo Candelaria Date: Fri, 10 Dec 2010 21:05:32 -0600 Subject: ASoC: twl6040: Add headset and handset mux controls This patch adds support for the twl6040 headset and handset MUX controls. Signed-off-by: Jorge Eduardo Candelaria Signed-off-by: Margarita Olaya Cabrera Acked-by: Mark Brown Signed-off-by: Liam Girdwood --- sound/soc/codecs/twl6040.c | 100 +++++++++++++++++++++++++++++++++------------ 1 file changed, 73 insertions(+), 27 deletions(-) diff --git a/sound/soc/codecs/twl6040.c b/sound/soc/codecs/twl6040.c index 8a6c62339e39..b575fd3ba3fb 100644 --- a/sound/soc/codecs/twl6040.c +++ b/sound/soc/codecs/twl6040.c @@ -475,6 +475,12 @@ static DECLARE_TLV_DB_SCALE(mic_preamp_tlv, -600, 600, 0); */ static DECLARE_TLV_DB_SCALE(mic_amp_tlv, 600, 600, 0); +/* + * AFMGAIN volume control: + * from 18 to 24 dB in 6 dB steps + */ +static DECLARE_TLV_DB_SCALE(afm_amp_tlv, 1800, 600, 0); + /* * HSGAIN volume control: * from -30 to 0 dB in 2 dB steps @@ -506,6 +512,28 @@ static const struct soc_enum twl6040_enum[] = { SOC_ENUM_SINGLE(TWL6040_REG_MICRCTL, 3, 3, twl6040_amicr_texts), }; +static const char *twl6040_hs_texts[] = { + "Off", "HS DAC", "Line-In amp" +}; + +static const struct soc_enum twl6040_hs_enum[] = { + SOC_ENUM_SINGLE(TWL6040_REG_HSLCTL, 5, ARRAY_SIZE(twl6040_hs_texts), + twl6040_hs_texts), + SOC_ENUM_SINGLE(TWL6040_REG_HSRCTL, 5, ARRAY_SIZE(twl6040_hs_texts), + twl6040_hs_texts), +}; + +static const char *twl6040_hf_texts[] = { + "Off", "HF DAC", "Line-In amp" +}; + +static const struct soc_enum twl6040_hf_enum[] = { + SOC_ENUM_SINGLE(TWL6040_REG_HFLCTL, 2, ARRAY_SIZE(twl6040_hf_texts), + twl6040_hf_texts), + SOC_ENUM_SINGLE(TWL6040_REG_HFRCTL, 2, ARRAY_SIZE(twl6040_hf_texts), + twl6040_hf_texts), +}; + static const struct snd_kcontrol_new amicl_control = SOC_DAPM_ENUM("Route", twl6040_enum[0]); @@ -513,18 +541,18 @@ static const struct snd_kcontrol_new amicr_control = SOC_DAPM_ENUM("Route", twl6040_enum[1]); /* Headset DAC playback switches */ -static const struct snd_kcontrol_new hsdacl_switch_controls = - SOC_DAPM_SINGLE("Switch", TWL6040_REG_HSLCTL, 5, 1, 0); +static const struct snd_kcontrol_new hsl_mux_controls = + SOC_DAPM_ENUM("Route", twl6040_hs_enum[0]); -static const struct snd_kcontrol_new hsdacr_switch_controls = - SOC_DAPM_SINGLE("Switch", TWL6040_REG_HSRCTL, 5, 1, 0); +static const struct snd_kcontrol_new hsr_mux_controls = + SOC_DAPM_ENUM("Route", twl6040_hs_enum[1]); /* Handsfree DAC playback switches */ -static const struct snd_kcontrol_new hfdacl_switch_controls = - SOC_DAPM_SINGLE("Switch", TWL6040_REG_HFLCTL, 2, 1, 0); +static const struct snd_kcontrol_new hfl_mux_controls = + SOC_DAPM_ENUM("Route", twl6040_hf_enum[0]); -static const struct snd_kcontrol_new hfdacr_switch_controls = - SOC_DAPM_SINGLE("Switch", TWL6040_REG_HFRCTL, 2, 1, 0); +static const struct snd_kcontrol_new hfr_mux_controls = + SOC_DAPM_ENUM("Route", twl6040_hf_enum[1]); static const struct snd_kcontrol_new ep_driver_switch_controls = SOC_DAPM_SINGLE("Switch", TWL6040_REG_EARCTL, 0, 1, 0); @@ -536,6 +564,10 @@ static const struct snd_kcontrol_new twl6040_snd_controls[] = { SOC_DOUBLE_TLV("Capture Volume", TWL6040_REG_MICGAIN, 0, 3, 4, 0, mic_amp_tlv), + /* AFM gains */ + SOC_DOUBLE_TLV("Aux FM Volume", + TWL6040_REG_LINEGAIN, 0, 5, 0xF, 0, afm_amp_tlv), + /* Playback gains */ SOC_DOUBLE_TLV("Headset Playback Volume", TWL6040_REG_HSGAIN, 0, 4, 0xF, 1, hs_tlv), @@ -572,6 +604,12 @@ static const struct snd_soc_dapm_widget twl6040_dapm_widgets[] = { SND_SOC_DAPM_PGA("MicAmpR", TWL6040_REG_MICRCTL, 0, 0, NULL, 0), + /* Auxiliary FM PGAs */ + SND_SOC_DAPM_PGA("AFMAmpL", + TWL6040_REG_MICLCTL, 1, 0, NULL, 0), + SND_SOC_DAPM_PGA("AFMAmpR", + TWL6040_REG_MICRCTL, 1, 0, NULL, 0), + /* ADCs */ SND_SOC_DAPM_ADC("ADC Left", "Left Front Capture", TWL6040_REG_MICLCTL, 2, 0), @@ -606,15 +644,15 @@ static const struct snd_soc_dapm_widget twl6040_dapm_widgets[] = { twl6040_power_mode_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), - /* Analog playback switches */ - SND_SOC_DAPM_SWITCH("HSDAC Left Playback", - SND_SOC_NOPM, 0, 0, &hsdacl_switch_controls), - SND_SOC_DAPM_SWITCH("HSDAC Right Playback", - SND_SOC_NOPM, 0, 0, &hsdacr_switch_controls), - SND_SOC_DAPM_SWITCH("HFDAC Left Playback", - SND_SOC_NOPM, 0, 0, &hfdacl_switch_controls), - SND_SOC_DAPM_SWITCH("HFDAC Right Playback", - SND_SOC_NOPM, 0, 0, &hfdacr_switch_controls), + SND_SOC_DAPM_MUX("HF Left Playback", + SND_SOC_NOPM, 0, 0, &hfl_mux_controls), + SND_SOC_DAPM_MUX("HF Right Playback", + SND_SOC_NOPM, 0, 0, &hfr_mux_controls), + /* Analog playback Muxes */ + SND_SOC_DAPM_MUX("HS Left Playback", + SND_SOC_NOPM, 0, 0, &hsl_mux_controls), + SND_SOC_DAPM_MUX("HS Right Playback", + SND_SOC_NOPM, 0, 0, &hsr_mux_controls), /* Analog playback drivers */ SND_SOC_DAPM_PGA_E("Handsfree Left Driver", @@ -658,12 +696,18 @@ static const struct snd_soc_dapm_route intercon[] = { {"ADC Left", NULL, "MicAmpL"}, {"ADC Right", NULL, "MicAmpR"}, - /* Headset playback path */ - {"HSDAC Left Playback", "Switch", "HSDAC Left"}, - {"HSDAC Right Playback", "Switch", "HSDAC Right"}, + /* AFM path */ + {"AFMAmpL", "NULL", "AFML"}, + {"AFMAmpR", "NULL", "AFMR"}, + + {"HS Left Playback", "HS DAC", "HSDAC Left"}, + {"HS Left Playback", "Line-In amp", "AFMAmpL"}, - {"Headset Left Driver", NULL, "HSDAC Left Playback"}, - {"Headset Right Driver", NULL, "HSDAC Right Playback"}, + {"HS Right Playback", "HS DAC", "HSDAC Right"}, + {"HS Right Playback", "Line-In amp", "AFMAmpR"}, + + {"Headset Left Driver", "NULL", "HS Left Playback"}, + {"Headset Right Driver", "NULL", "HS Right Playback"}, {"HSOL", NULL, "Headset Left Driver"}, {"HSOR", NULL, "Headset Right Driver"}, @@ -672,12 +716,14 @@ static const struct snd_soc_dapm_route intercon[] = { {"Earphone Driver", "Switch", "HSDAC Left"}, {"EP", NULL, "Earphone Driver"}, - /* Handsfree playback path */ - {"HFDAC Left Playback", "Switch", "HFDAC Left"}, - {"HFDAC Right Playback", "Switch", "HFDAC Right"}, + {"HF Left Playback", "HF DAC", "HFDAC Left"}, + {"HF Left Playback", "Line-In amp", "AFMAmpL"}, + + {"HF Right Playback", "HF DAC", "HFDAC Right"}, + {"HF Right Playback", "Line-In amp", "AFMAmpR"}, - {"HFDAC Left PGA", NULL, "HFDAC Left Playback"}, - {"HFDAC Right PGA", NULL, "HFDAC Right Playback"}, + {"HFDAC Left PGA", NULL, "HF Left Playback"}, + {"HFDAC Right PGA", NULL, "HF Right Playback"}, {"Handsfree Left Driver", "Switch", "HFDAC Left PGA"}, {"Handsfree Right Driver", "Switch", "HFDAC Right PGA"}, -- cgit v1.2.3 From 6c311041c1d3d0b9d1fc6ddacd49e50d83ba158a Mon Sep 17 00:00:00 2001 From: "Olaya, Margarita" Date: Fri, 10 Dec 2010 21:05:46 -0600 Subject: ASoC: twl6040: Restore bias level at resume This patch restores the CODEC bias level at resume(). Signed-off-by: Margarita Olaya Cabrera Acked-by: Mark Brown Signed-off-by: Liam Girdwood --- sound/soc/codecs/twl6040.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/soc/codecs/twl6040.c b/sound/soc/codecs/twl6040.c index b575fd3ba3fb..3973bf6889c0 100644 --- a/sound/soc/codecs/twl6040.c +++ b/sound/soc/codecs/twl6040.c @@ -1097,6 +1097,7 @@ static int twl6040_suspend(struct snd_soc_codec *codec, pm_message_t state) static int twl6040_resume(struct snd_soc_codec *codec) { twl6040_set_bias_level(codec, SND_SOC_BIAS_STANDBY); + twl6040_set_bias_level(codec, codec->dapm.suspend_bias_level); return 0; } -- cgit v1.2.3 From 4e624d0609081e4394695fba3d7c3b7ebb6171ce Mon Sep 17 00:00:00 2001 From: "Olaya, Margarita" Date: Fri, 10 Dec 2010 21:05:54 -0600 Subject: ASoC: twl6040: Fix PCM error handling ops This patch moves all the PCM error handling for clock config out of trigger() and startup() and into prepare(). Signed-off-by: Margarita Olaya Cabrera Acked-by: Mark Brown Signed-off-by: Liam Girdwood --- sound/soc/codecs/twl6040.c | 55 +++++++++++++++++++--------------------------- 1 file changed, 22 insertions(+), 33 deletions(-) diff --git a/sound/soc/codecs/twl6040.c b/sound/soc/codecs/twl6040.c index 3973bf6889c0..fd9a3ab91a19 100644 --- a/sound/soc/codecs/twl6040.c +++ b/sound/soc/codecs/twl6040.c @@ -865,23 +865,6 @@ static int twl6040_startup(struct snd_pcm_substream *substream, struct snd_soc_codec *codec = rtd->codec; struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec); - if (!priv->sysclk) { - dev_err(codec->dev, - "no mclk configured, call set_sysclk() on init\n"); - return -EINVAL; - } - - /* - * capture is not supported at 17.64 MHz, - * it's reserved for headset low-power playback scenario - */ - if ((priv->sysclk == 17640000) && substream->stream) { - dev_err(codec->dev, - "capture mode is not supported at %dHz\n", - priv->sysclk); - return -EINVAL; - } - snd_pcm_hw_constraint_list(substream->runtime, 0, SNDRV_PCM_HW_PARAM_RATE, priv->sysclk_constraints); @@ -925,31 +908,37 @@ static int twl6040_hw_params(struct snd_pcm_substream *substream, return 0; } -static int twl6040_trigger(struct snd_pcm_substream *substream, - int cmd, struct snd_soc_dai *dai) +static int twl6040_prepare(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_codec *codec = rtd->codec; struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec); - switch (cmd) { - case SNDRV_PCM_TRIGGER_START: - case SNDRV_PCM_TRIGGER_RESUME: - /* - * low-power playback mode is restricted - * for headset path only - */ - if ((priv->sysclk == 17640000) && priv->non_lp) { + if (!priv->sysclk) { + dev_err(codec->dev, + "no mclk configured, call set_sysclk() on init\n"); + return -EINVAL; + } + + /* + * capture is not supported at 17.64 MHz, + * it's reserved for headset low-power playback scenario + */ + if ((priv->sysclk == 17640000) && + substream->stream == SNDRV_PCM_STREAM_CAPTURE) { + dev_err(codec->dev, + "capture mode is not supported at %dHz\n", + priv->sysclk); + return -EINVAL; + } + + if ((priv->sysclk == 17640000) && priv->non_lp) { dev_err(codec->dev, "some enabled paths aren't supported at %dHz\n", priv->sysclk); return -EPERM; - } - break; - default: - break; } - return 0; } @@ -1063,7 +1052,7 @@ static int twl6040_set_dai_sysclk(struct snd_soc_dai *codec_dai, static struct snd_soc_dai_ops twl6040_dai_ops = { .startup = twl6040_startup, .hw_params = twl6040_hw_params, - .trigger = twl6040_trigger, + .prepare = twl6040_prepare, .set_sysclk = twl6040_set_dai_sysclk, }; -- cgit v1.2.3 From 60ea4cecddd03ed86b91bc8c057d3d305dc678be Mon Sep 17 00:00:00 2001 From: "Olaya, Margarita" Date: Fri, 10 Dec 2010 21:05:58 -0600 Subject: ASoC: twl6040: Support other sample rates. The twl6040 can support more sample rates other than 88.2 and 96k. Signed-off-by: Margarita Olaya Cabrera Acked-by: Mark Brown Signed-off-by: Liam Girdwood --- sound/soc/codecs/twl6040.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/sound/soc/codecs/twl6040.c b/sound/soc/codecs/twl6040.c index fd9a3ab91a19..b59d947d0bfe 100644 --- a/sound/soc/codecs/twl6040.c +++ b/sound/soc/codecs/twl6040.c @@ -39,7 +39,7 @@ #include "twl6040.h" -#define TWL6040_RATES (SNDRV_PCM_RATE_88200 | SNDRV_PCM_RATE_96000) +#define TWL6040_RATES SNDRV_PCM_RATE_8000_96000 #define TWL6040_FORMATS (SNDRV_PCM_FMTBIT_S32_LE) struct twl6040_jack_data { @@ -890,10 +890,17 @@ static int twl6040_hw_params(struct snd_pcm_substream *substream, rate = params_rate(params); switch (rate) { + case 11250: + case 22500: + case 44100: case 88200: lppllctl |= TWL6040_LPLLFIN; priv->sysclk = 17640000; break; + case 8000: + case 16000: + case 32000: + case 48000: case 96000: lppllctl &= ~TWL6040_LPLLFIN; priv->sysclk = 19200000; -- cgit v1.2.3 From cb973d78f82f038c7d8d78d469fb89842d246871 Mon Sep 17 00:00:00 2001 From: Francois Mazard Date: Fri, 10 Dec 2010 21:06:03 -0600 Subject: ASoC: twl6040: Fix analog Mic L & R mux controls The mux control has 4 elements not 3 Signed-off-by: Margarita Olaya Cabrera Acked-by: Mark Brown Signed-off-by: Liam Girdwood --- sound/soc/codecs/twl6040.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/twl6040.c b/sound/soc/codecs/twl6040.c index b59d947d0bfe..5081e812c528 100644 --- a/sound/soc/codecs/twl6040.c +++ b/sound/soc/codecs/twl6040.c @@ -508,8 +508,8 @@ static const char *twl6040_amicr_texts[] = {"Headset Mic", "Sub Mic", "Aux/FM Right", "Off"}; static const struct soc_enum twl6040_enum[] = { - SOC_ENUM_SINGLE(TWL6040_REG_MICLCTL, 3, 3, twl6040_amicl_texts), - SOC_ENUM_SINGLE(TWL6040_REG_MICRCTL, 3, 3, twl6040_amicr_texts), + SOC_ENUM_SINGLE(TWL6040_REG_MICLCTL, 3, 4, twl6040_amicl_texts), + SOC_ENUM_SINGLE(TWL6040_REG_MICRCTL, 3, 4, twl6040_amicr_texts), }; static const char *twl6040_hs_texts[] = { -- cgit v1.2.3 From 99903ea23655a43ce4f75b64fef69e341fd0b7df Mon Sep 17 00:00:00 2001 From: "Olaya, Margarita" Date: Fri, 10 Dec 2010 21:06:07 -0600 Subject: ASoC: twl6040: Enable automatic power for phoenix 1.1 Phoenix 1.1 supports automatic power on sequence, a verification is added to use it with new revision of the chip. Signed-off-by: Margarita Olaya Cabrera Acked-by: Mark Brown Signed-off-by: Liam Girdwood --- sound/soc/codecs/twl6040.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/sound/soc/codecs/twl6040.c b/sound/soc/codecs/twl6040.c index 5081e812c528..c54350445d0c 100644 --- a/sound/soc/codecs/twl6040.c +++ b/sound/soc/codecs/twl6040.c @@ -1108,6 +1108,7 @@ static int twl6040_probe(struct snd_soc_codec *codec) struct twl6040_data *priv; int audpwron, naudint; int ret = 0; + u8 icrev; priv = kzalloc(sizeof(struct twl6040_data), GFP_KERNEL); if (priv == NULL) @@ -1116,13 +1117,17 @@ static int twl6040_probe(struct snd_soc_codec *codec) priv->codec = codec; - if (twl_codec) { + twl_i2c_read_u8(TWL_MODULE_AUDIO_VOICE, &icrev, TWL6040_REG_ASICREV); + + if (twl_codec && (icrev > 0)) audpwron = twl_codec->audpwron_gpio; - naudint = twl_codec->naudint_irq; - } else { + else audpwron = -EINVAL; + + if (twl_codec) + naudint = twl_codec->naudint_irq; + else naudint = 0; - } priv->audpwron = audpwron; priv->naudint = naudint; -- cgit v1.2.3 From f1f489a6aa89993892cd7b4d08f67e7e110492cb Mon Sep 17 00:00:00 2001 From: Jorge Eduardo Candelaria Date: Fri, 10 Dec 2010 21:06:13 -0600 Subject: ASoC: twl6040: Clear interrupt status at boot time On Phoenix 1.1, the INTID register default value is an invalid one, causing the interrupt handler to think the phoenix power on sequence is ready before it actually finishes. This causes some i2c errors when trying to configure twl. Signed-off-by: Jorge Eduardo Candelaria Signed-off-by: Margarita Olaya Cabrera Acked-by: Mark Brown Signed-off-by: Liam Girdwood --- sound/soc/codecs/twl6040.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/sound/soc/codecs/twl6040.c b/sound/soc/codecs/twl6040.c index c54350445d0c..f5d5f89a2216 100644 --- a/sound/soc/codecs/twl6040.c +++ b/sound/soc/codecs/twl6040.c @@ -1152,6 +1152,17 @@ static int twl6040_probe(struct snd_soc_codec *codec) goto gpio2_err; priv->codec_powered = 0; + + /* enable only codec ready interrupt */ + twl6040_write(codec, TWL6040_REG_INTMR, + ~TWL6040_READYMSK & TWL6040_ALLINT_MSK); + + /* reset interrupt status to allow correct power up sequence */ + twl6040_read_reg_volatile(codec, TWL6040_REG_INTID); + } else { + /* no interrupts at all */ + twl6040_write_reg_cache(codec, TWL6040_REG_INTMR, + TWL6040_ALLINT_MSK); } if (naudint) { @@ -1162,16 +1173,6 @@ static int twl6040_probe(struct snd_soc_codec *codec) "twl6040_codec", codec); if (ret) goto gpio2_err; - } else { - if (gpio_is_valid(audpwron)) { - /* enable only codec ready interrupt */ - twl6040_write_reg_cache(codec, TWL6040_REG_INTMR, - ~TWL6040_READYMSK & TWL6040_ALLINT_MSK); - } else { - /* no interrupts at all */ - twl6040_write_reg_cache(codec, TWL6040_REG_INTMR, - TWL6040_ALLINT_MSK); - } } /* init vio registers */ -- cgit v1.2.3 From 4f44ee1f494edef1fea3db20565b2e209bef6280 Mon Sep 17 00:00:00 2001 From: Misael Lopez Cruz Date: Fri, 10 Dec 2010 21:06:24 -0600 Subject: ASoC: twl6040: Enable plug detection interrupts Enable plug detection interrupt mask in order to get headset PLUGINT/UNPLUGINT interrupts. Signed-off-by: Misael Lopez Cruz Signed-off-by: Margarita Olaya Cabrera Acked-by: Mark Brown Signed-off-by: Liam Girdwood --- sound/soc/codecs/twl6040.c | 10 +++------- sound/soc/codecs/twl6040.h | 1 + 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/sound/soc/codecs/twl6040.c b/sound/soc/codecs/twl6040.c index f5d5f89a2216..a8ec9113cc33 100644 --- a/sound/soc/codecs/twl6040.c +++ b/sound/soc/codecs/twl6040.c @@ -1108,7 +1108,7 @@ static int twl6040_probe(struct snd_soc_codec *codec) struct twl6040_data *priv; int audpwron, naudint; int ret = 0; - u8 icrev; + u8 icrev, intmr = TWL6040_ALLINT_MSK; priv = kzalloc(sizeof(struct twl6040_data), GFP_KERNEL); if (priv == NULL) @@ -1154,16 +1154,12 @@ static int twl6040_probe(struct snd_soc_codec *codec) priv->codec_powered = 0; /* enable only codec ready interrupt */ - twl6040_write(codec, TWL6040_REG_INTMR, - ~TWL6040_READYMSK & TWL6040_ALLINT_MSK); + intmr &= ~(TWL6040_READYMSK | TWL6040_PLUGMSK); /* reset interrupt status to allow correct power up sequence */ twl6040_read_reg_volatile(codec, TWL6040_REG_INTID); - } else { - /* no interrupts at all */ - twl6040_write_reg_cache(codec, TWL6040_REG_INTMR, - TWL6040_ALLINT_MSK); } + twl6040_write(codec, TWL6040_REG_INTMR, intmr); if (naudint) { /* audio interrupt */ diff --git a/sound/soc/codecs/twl6040.h b/sound/soc/codecs/twl6040.h index 67396f63c1ec..23aeed0963e6 100644 --- a/sound/soc/codecs/twl6040.h +++ b/sound/soc/codecs/twl6040.h @@ -79,6 +79,7 @@ /* INTMR (0x04) fields */ +#define TWL6040_PLUGMSK 0x02 #define TWL6040_READYMSK 0x40 #define TWL6040_ALLINT_MSK 0x7B -- cgit v1.2.3 From cbd9cb5de3182d688544611c019b06bf04e2ad06 Mon Sep 17 00:00:00 2001 From: Jorge Eduardo Candelaria Date: Fri, 10 Dec 2010 21:06:30 -0600 Subject: ASoC: twl6040: Increase timeout for power up After coming back from suspend, the timeout waiting for Phoenix chip to complete its power up sequence is not enough, which leaves the codec cache value for some registers in an outdated state. Increase the timeout value to wait for the power up sequence to correclty complete. Signed-off-by: Jorge Eduardo Candelaria Signed-off-by: Margarita Olaya Cabrera Acked-by: Mark Brown Signed-off-by: Liam Girdwood --- sound/soc/codecs/twl6040.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/codecs/twl6040.c b/sound/soc/codecs/twl6040.c index a8ec9113cc33..39f0bc5145c0 100644 --- a/sound/soc/codecs/twl6040.c +++ b/sound/soc/codecs/twl6040.c @@ -752,7 +752,7 @@ static int twl6040_power_up_completion(struct snd_soc_codec *codec, u8 intid; time_left = wait_for_completion_timeout(&priv->ready, - msecs_to_jiffies(48)); + msecs_to_jiffies(144)); if (!time_left) { twl_i2c_read_u8(TWL_MODULE_AUDIO_VOICE, &intid, -- cgit v1.2.3 From 9020808b4d9ff6b7eebb026492dba6a805309df8 Mon Sep 17 00:00:00 2001 From: "Olaya, Margarita" Date: Fri, 10 Dec 2010 21:06:39 -0600 Subject: ASoC: twl6040: Fix TLV dB step values for gains Some gains were incorrectly configured for dB values. Signed-off-by: Margarita Olaya Cabrera Acked-by: Mark Brown Signed-off-by: Liam Girdwood --- sound/soc/codecs/twl6040.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/twl6040.c b/sound/soc/codecs/twl6040.c index 39f0bc5145c0..b0ca9f9b70f7 100644 --- a/sound/soc/codecs/twl6040.c +++ b/sound/soc/codecs/twl6040.c @@ -471,9 +471,9 @@ static DECLARE_TLV_DB_SCALE(mic_preamp_tlv, -600, 600, 0); /* * MICGAIN volume control: - * from 6 to 30 dB in 6 dB steps + * from -6 to 30 dB in 6 dB steps */ -static DECLARE_TLV_DB_SCALE(mic_amp_tlv, 600, 600, 0); +static DECLARE_TLV_DB_SCALE(mic_amp_tlv, -600, 600, 0); /* * AFMGAIN volume control: -- cgit v1.2.3 From 53a9ef15df8c0dc688fae33277a252f0dd2faf2d Mon Sep 17 00:00:00 2001 From: Misael Lopez Cruz Date: Fri, 10 Dec 2010 21:06:34 -0600 Subject: ASoC: twl6040: Use correct offset for LineInAmp Right Gain for LineInAmp Right uses LINEGAIN[5:3], which means that offset for right channel should be 4. Signed-off-by: Misael Lopez Cruz Signed-off-by: Margarita Olaya Cabrera Acked-by: Mark Brown Signed-off-by: Liam Girdwood --- sound/soc/codecs/twl6040.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/codecs/twl6040.c b/sound/soc/codecs/twl6040.c index b0ca9f9b70f7..9dfe208e6539 100644 --- a/sound/soc/codecs/twl6040.c +++ b/sound/soc/codecs/twl6040.c @@ -566,7 +566,7 @@ static const struct snd_kcontrol_new twl6040_snd_controls[] = { /* AFM gains */ SOC_DOUBLE_TLV("Aux FM Volume", - TWL6040_REG_LINEGAIN, 0, 5, 0xF, 0, afm_amp_tlv), + TWL6040_REG_LINEGAIN, 0, 4, 0xF, 0, afm_amp_tlv), /* Playback gains */ SOC_DOUBLE_TLV("Headset Playback Volume", -- cgit v1.2.3 From f6820308e025d645d9d766c97586badd4ddb8754 Mon Sep 17 00:00:00 2001 From: "Kirill A. Shutemov" Date: Mon, 13 Dec 2010 19:10:28 +0200 Subject: kbuild: introduce HDR_ARCH_LIST for headers_install_all Using HDR_ARCH_LIST you can specify subset of architectures you want to get headers for. Signed-off-by: Kirill A. Shutemov Signed-off-by: Michal Marek --- Documentation/make/headers_install.txt | 5 +++-- scripts/headers.sh | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Documentation/make/headers_install.txt b/Documentation/make/headers_install.txt index f2481cabffcb..951eb9f1e040 100644 --- a/Documentation/make/headers_install.txt +++ b/Documentation/make/headers_install.txt @@ -39,8 +39,9 @@ INSTALL_HDR_PATH indicates where to install the headers. It defaults to The command "make headers_install_all" exports headers for all architectures simultaneously. (This is mostly of interest to distribution maintainers, who create an architecture-independent tarball from the resulting include -directory.) Remember to provide the appropriate linux/asm directory via "mv" -or "ln -s" before building a C library with headers exported this way. +directory.) You also can use HDR_ARCH_LIST to specify list of architectures. +Remember to provide the appropriate linux/asm directory via "mv" or "ln -s" +before building a C library with headers exported this way. The kernel header export infrastructure is maintained by David Woodhouse . diff --git a/scripts/headers.sh b/scripts/headers.sh index 1ddcdd38d97f..978b42b3acd7 100755 --- a/scripts/headers.sh +++ b/scripts/headers.sh @@ -13,7 +13,7 @@ do_command() fi } -archs=$(ls ${srctree}/arch) +archs=${HDR_ARCH_LIST:-$(ls ${srctree}/arch)} for arch in ${archs}; do case ${arch} in -- cgit v1.2.3 From ba9effa2ecdc08325bd297d541b4207b2df38184 Mon Sep 17 00:00:00 2001 From: "Kirill A. Shutemov" Date: Mon, 13 Dec 2010 19:10:29 +0200 Subject: kbuild: export linux/{a.out,kvm,kvm_para}.h on headers_install_all Export linux/a.out.h, linux/kvm.h and linux/kvm_para.h on headers_install_all if at least one architecture has appropriate files in arch-dependent headers. Signed-off-by: Kirill A. Shutemov Signed-off-by: Michal Marek --- include/linux/Kbuild | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/include/linux/Kbuild b/include/linux/Kbuild index 97319a8fc1e0..ae31f9521a6d 100644 --- a/include/linux/Kbuild +++ b/include/linux/Kbuild @@ -20,15 +20,18 @@ header-y += wimax/ objhdr-y += version.h ifneq ($(wildcard $(srctree)/arch/$(SRCARCH)/include/asm/a.out.h \ - $(srctree)/include/asm-$(SRCARCH)/a.out.h),) + $(srctree)/include/asm-$(SRCARCH)/a.out.h \ + $(INSTALL_HDR_PATH)/include/asm-*/a.out.h),) header-y += a.out.h endif ifneq ($(wildcard $(srctree)/arch/$(SRCARCH)/include/asm/kvm.h \ - $(srctree)/include/asm-$(SRCARCH)/kvm.h),) + $(srctree)/include/asm-$(SRCARCH)/kvm.h \ + $(INSTALL_HDR_PATH)/include/asm-*/kvm.h),) header-y += kvm.h endif ifneq ($(wildcard $(srctree)/arch/$(SRCARCH)/include/asm/kvm_para.h \ - $(srctree)/include/asm-$(SRCARCH)/kvm_para.h),) + $(srctree)/include/asm-$(SRCARCH)/kvm_para.h \ + $(INSTALL_HDR_PATH)/include/asm-*/kvm_para.h),) header-y += kvm_para.h endif -- cgit v1.2.3 From 41263fc6716dea402125c95f38ed83ebf59d5172 Mon Sep 17 00:00:00 2001 From: Ben Gardiner Date: Tue, 14 Dec 2010 11:39:44 -0500 Subject: kbuild: fix interaction of CONFIG_IKCONFIG and KCONFIG_CONFIG If you try to build a kernel with KCONFIG_CONFIG set (to a value not equal to .config) and that config sets CONFIG_IKCONFIG then the build will fail with: make[1]: *** No rule to make target `.config', needed by \ `kernel/config_data.gz'. Stop. because the kernel/Makefile contains a direct reference to .config. This issue has been present since the introduction of KCONFIG_CONFIG in 14cdd3c402bf7c66f0bcd76e290f0770a54a4b21. Signed-off-by: Ben Gardiner CC: Roman Zippel CC: Michal Marek Reviewed-by: Michal Marek Signed-off-by: Michal Marek --- Makefile | 1 + kernel/Makefile | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 6619720f50dd..ee77a3d88e0a 100644 --- a/Makefile +++ b/Makefile @@ -224,6 +224,7 @@ ifeq ($(ARCH),m68knommu) endif KCONFIG_CONFIG ?= .config +export KCONFIG_CONFIG # SHELL used by kbuild CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \ diff --git a/kernel/Makefile b/kernel/Makefile index 0b5ff083fa22..33e0a39cf359 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -121,7 +121,7 @@ $(obj)/configs.o: $(obj)/config_data.h # config_data.h contains the same information as ikconfig.h but gzipped. # Info from config_data can be extracted from /proc/config* targets += config_data.gz -$(obj)/config_data.gz: .config FORCE +$(obj)/config_data.gz: $(KCONFIG_CONFIG) FORCE $(call if_changed,gzip) quiet_cmd_ikconfiggz = IKCFG $@ -- cgit v1.2.3 From c6df541c00e53a4fdff7a130d4365f848075adcc Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Wed, 15 Dec 2010 09:56:50 +0000 Subject: Revert "drm/i915: Avoid using PIPE_CONTROL on Ironlake" Restore PIPE_CONTROL once again just for Ironlake, as it appears that MI_USER_INTERRUPT does not have the same coherency guarantees, that is on Ironlake the interrupt following a GPU write is not guaranteed to arrive after the write is coherent from the CPU, as it does on the other generations. Reported-by: Zhenyu Wang Reported-by: Shuang He Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=32402 Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_irq.c | 3 +- drivers/gpu/drm/i915/intel_ringbuffer.c | 162 +++++++++++++++++++++++++++++++- 2 files changed, 162 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 2ddb98b5c90f..e4a2e2c3dbe3 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -349,7 +349,7 @@ static irqreturn_t ironlake_irq_handler(struct drm_device *dev) READ_BREADCRUMB(dev_priv); } - if (gt_iir & GT_USER_INTERRUPT) + if (gt_iir & (GT_USER_INTERRUPT | GT_PIPE_NOTIFY)) notify_ring(dev, &dev_priv->ring[RCS]); if (gt_iir & bsd_usr_interrupt) notify_ring(dev, &dev_priv->ring[VCS]); @@ -1558,6 +1558,7 @@ static int ironlake_irq_postinstall(struct drm_device *dev) else render_irqs = GT_USER_INTERRUPT | + GT_PIPE_NOTIFY | GT_BSD_USER_INTERRUPT; I915_WRITE(GTIER, render_irqs); POSTING_READ(GTIER); diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index a3fd993e0de0..56bc95c056dd 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -209,6 +209,78 @@ static int init_ring_common(struct intel_ring_buffer *ring) return 0; } +/* + * 965+ support PIPE_CONTROL commands, which provide finer grained control + * over cache flushing. + */ +struct pipe_control { + struct drm_i915_gem_object *obj; + volatile u32 *cpu_page; + u32 gtt_offset; +}; + +static int +init_pipe_control(struct intel_ring_buffer *ring) +{ + struct pipe_control *pc; + struct drm_i915_gem_object *obj; + int ret; + + if (ring->private) + return 0; + + pc = kmalloc(sizeof(*pc), GFP_KERNEL); + if (!pc) + return -ENOMEM; + + obj = i915_gem_alloc_object(ring->dev, 4096); + if (obj == NULL) { + DRM_ERROR("Failed to allocate seqno page\n"); + ret = -ENOMEM; + goto err; + } + obj->agp_type = AGP_USER_CACHED_MEMORY; + + ret = i915_gem_object_pin(obj, 4096, true); + if (ret) + goto err_unref; + + pc->gtt_offset = obj->gtt_offset; + pc->cpu_page = kmap(obj->pages[0]); + if (pc->cpu_page == NULL) + goto err_unpin; + + pc->obj = obj; + ring->private = pc; + return 0; + +err_unpin: + i915_gem_object_unpin(obj); +err_unref: + drm_gem_object_unreference(&obj->base); +err: + kfree(pc); + return ret; +} + +static void +cleanup_pipe_control(struct intel_ring_buffer *ring) +{ + struct pipe_control *pc = ring->private; + struct drm_i915_gem_object *obj; + + if (!ring->private) + return; + + obj = pc->obj; + kunmap(obj->pages[0]); + i915_gem_object_unpin(obj); + drm_gem_object_unreference(&obj->base); + + kfree(pc); + ring->private = NULL; +} + static int init_render_ring(struct intel_ring_buffer *ring) { struct drm_device *dev = ring->dev; @@ -222,9 +294,24 @@ static int init_render_ring(struct intel_ring_buffer *ring) I915_WRITE(MI_MODE, mode); } + if (INTEL_INFO(dev)->gen >= 6) { + } else if (IS_GEN5(dev)) { + ret = init_pipe_control(ring); + if (ret) + return ret; + } + return ret; } +static void render_ring_cleanup(struct intel_ring_buffer *ring) +{ + if (!ring->private) + return; + + cleanup_pipe_control(ring); +} + static void update_semaphore(struct intel_ring_buffer *ring, int i, u32 seqno) { @@ -299,6 +386,65 @@ intel_ring_sync(struct intel_ring_buffer *ring, return 0; } +#define PIPE_CONTROL_FLUSH(ring__, addr__) \ +do { \ + intel_ring_emit(ring__, GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE | \ + PIPE_CONTROL_DEPTH_STALL | 2); \ + intel_ring_emit(ring__, (addr__) | PIPE_CONTROL_GLOBAL_GTT); \ + intel_ring_emit(ring__, 0); \ + intel_ring_emit(ring__, 0); \ +} while (0) + +static int +pc_render_add_request(struct intel_ring_buffer *ring, + u32 *result) +{ + struct drm_device *dev = ring->dev; + u32 seqno = i915_gem_get_seqno(dev); + struct pipe_control *pc = ring->private; + u32 scratch_addr = pc->gtt_offset + 128; + int ret; + + /* For Ironlake, MI_USER_INTERRUPT was deprecated and apparently + * incoherent with writes to memory, i.e. completely fubar, + * so we need to use PIPE_NOTIFY instead. + * + * However, we also need to workaround the qword write + * incoherence by flushing the 6 PIPE_NOTIFY buffers out to + * memory before requesting an interrupt. + */ + ret = intel_ring_begin(ring, 32); + if (ret) + return ret; + + intel_ring_emit(ring, GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE | + PIPE_CONTROL_WC_FLUSH | PIPE_CONTROL_TC_FLUSH); + intel_ring_emit(ring, pc->gtt_offset | PIPE_CONTROL_GLOBAL_GTT); + intel_ring_emit(ring, seqno); + intel_ring_emit(ring, 0); + PIPE_CONTROL_FLUSH(ring, scratch_addr); + scratch_addr += 128; /* write to separate cachelines */ + PIPE_CONTROL_FLUSH(ring, scratch_addr); + scratch_addr += 128; + PIPE_CONTROL_FLUSH(ring, scratch_addr); + scratch_addr += 128; + PIPE_CONTROL_FLUSH(ring, scratch_addr); + scratch_addr += 128; + PIPE_CONTROL_FLUSH(ring, scratch_addr); + scratch_addr += 128; + PIPE_CONTROL_FLUSH(ring, scratch_addr); + intel_ring_emit(ring, GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE | + PIPE_CONTROL_WC_FLUSH | PIPE_CONTROL_TC_FLUSH | + PIPE_CONTROL_NOTIFY); + intel_ring_emit(ring, pc->gtt_offset | PIPE_CONTROL_GLOBAL_GTT); + intel_ring_emit(ring, seqno); + intel_ring_emit(ring, 0); + intel_ring_advance(ring); + + *result = seqno; + return 0; +} + static int render_ring_add_request(struct intel_ring_buffer *ring, u32 *result) @@ -327,6 +473,13 @@ ring_get_seqno(struct intel_ring_buffer *ring) return intel_read_status_page(ring, I915_GEM_HWS_INDEX); } +static u32 +pc_render_get_seqno(struct intel_ring_buffer *ring) +{ + struct pipe_control *pc = ring->private; + return pc->cpu_page[0]; +} + static bool render_ring_get_irq(struct intel_ring_buffer *ring) { @@ -342,7 +495,7 @@ render_ring_get_irq(struct intel_ring_buffer *ring) spin_lock_irqsave(&dev_priv->irq_lock, irqflags); if (HAS_PCH_SPLIT(dev)) ironlake_enable_graphics_irq(dev_priv, - GT_USER_INTERRUPT); + GT_PIPE_NOTIFY | GT_USER_INTERRUPT); else i915_enable_irq(dev_priv, I915_USER_INTERRUPT); spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); @@ -363,7 +516,8 @@ render_ring_put_irq(struct intel_ring_buffer *ring) spin_lock_irqsave(&dev_priv->irq_lock, irqflags); if (HAS_PCH_SPLIT(dev)) ironlake_disable_graphics_irq(dev_priv, - GT_USER_INTERRUPT); + GT_USER_INTERRUPT | + GT_PIPE_NOTIFY); else i915_disable_irq(dev_priv, I915_USER_INTERRUPT); spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); @@ -776,6 +930,7 @@ static const struct intel_ring_buffer render_ring = { .irq_get = render_ring_get_irq, .irq_put = render_ring_put_irq, .dispatch_execbuffer = render_ring_dispatch_execbuffer, + .cleanup = render_ring_cleanup, }; /* ring buffer for bit-stream decoder */ @@ -1010,6 +1165,9 @@ int intel_init_render_ring_buffer(struct drm_device *dev) *ring = render_ring; if (INTEL_INFO(dev)->gen >= 6) { ring->add_request = gen6_add_request; + } else if (IS_GEN5(dev)) { + ring->add_request = pc_render_add_request; + ring->get_seqno = pc_render_get_seqno; } if (!I915_NEED_GFX_HWS(dev)) { -- cgit v1.2.3 From b7f1de289c50beb4998611ba5373e539efd0f79f Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Tue, 14 Dec 2010 16:09:31 +0000 Subject: drm/i915: Wait for vblank before unpinning old fb Be paranoid and ensure that the vblank has passed and the scanout has switched to the new fb, before unpinning the old one and possibly tearing down its PTEs. Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/intel_display.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index f2d50141e0c2..840bfc3ae719 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -1626,8 +1626,10 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, return ret; } - if (old_fb) + if (old_fb) { + intel_wait_for_vblank(dev, intel_crtc->pipe); i915_gem_object_unpin(to_intel_framebuffer(old_fb)->obj); + } mutex_unlock(&dev->struct_mutex); -- cgit v1.2.3 From 1398261a2e84c537c409259cfe9db3d0abcd9f99 Mon Sep 17 00:00:00 2001 From: Yuanhan Liu Date: Wed, 15 Dec 2010 15:42:31 +0800 Subject: drm/i915: Add self-refresh support on Sandybridge Add the support of memory self-refresh on Sandybridge, which is now support 3 levels of watermarks and the source of the latency values for watermarks has changed. On Sandybridge, the LP0 WM value is not hardcoded any more. All the latency value is now should be extracted from MCHBAR SSKPD register. And the MCHBAR base address is changed, too. For the WM values, if any calculated watermark values is larger than the maximum value that can be programmed into the associated watermark register, that watermark must be disabled. Signed-off-by: Yuanhan Liu [ickle: remove duplicate compute routines and fixup for checkpatch] Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_debugfs.c | 2 +- drivers/gpu/drm/i915/i915_reg.h | 40 +++++ drivers/gpu/drm/i915/intel_display.c | 310 +++++++++++++++++++++++++++++++++-- 3 files changed, 334 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 22821994b35a..864e75d762e6 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -933,7 +933,7 @@ static int i915_sr_status(struct seq_file *m, void *unused) drm_i915_private_t *dev_priv = dev->dev_private; bool sr_enabled = false; - if (IS_GEN5(dev)) + if (HAS_PCH_SPLIT(dev)) sr_enabled = I915_READ(WM1_LP_ILK) & WM1_LP_SR_EN; else if (IS_CRESTLINE(dev) || IS_I945G(dev) || IS_I945GM(dev)) sr_enabled = I915_READ(FW_BLC_SELF) & FW_BLC_SELF_EN; diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index b284c13fd632..61ef98db9ff0 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -596,6 +596,8 @@ #define ILK_DISPLAY_CHICKEN1 0x42000 #define ILK_FBCQ_DIS (1<<22) +#define ILK_PABSTRETCH_DIS (1<<21) + /* * GPIO regs @@ -955,6 +957,8 @@ */ #define MCHBAR_MIRROR_BASE 0x10000 +#define MCHBAR_MIRROR_BASE_SNB 0x140000 + /** 915-945 and GM965 MCH register controlling DRAM channel access */ #define DCC 0x10200 #define DCC_ADDRESSING_MODE_SINGLE_CHANNEL (0 << 0) @@ -2346,6 +2350,40 @@ #define ILK_FIFO_LINE_SIZE 64 +/* define the WM info on Sandybridge */ +#define SNB_DISPLAY_FIFO 128 +#define SNB_DISPLAY_MAXWM 0x7f /* bit 16:22 */ +#define SNB_DISPLAY_DFTWM 8 +#define SNB_CURSOR_FIFO 32 +#define SNB_CURSOR_MAXWM 0x1f /* bit 4:0 */ +#define SNB_CURSOR_DFTWM 8 + +#define SNB_DISPLAY_SR_FIFO 512 +#define SNB_DISPLAY_MAX_SRWM 0x1ff /* bit 16:8 */ +#define SNB_DISPLAY_DFT_SRWM 0x3f +#define SNB_CURSOR_SR_FIFO 64 +#define SNB_CURSOR_MAX_SRWM 0x3f /* bit 5:0 */ +#define SNB_CURSOR_DFT_SRWM 8 + +#define SNB_FBC_MAX_SRWM 0xf /* bit 23:20 */ + +#define SNB_FIFO_LINE_SIZE 64 + + +/* the address where we get all kinds of latency value */ +#define SSKPD 0x5d10 +#define SSKPD_WM_MASK 0x3f +#define SSKPD_WM0_SHIFT 0 +#define SSKPD_WM1_SHIFT 8 +#define SSKPD_WM2_SHIFT 16 +#define SSKPD_WM3_SHIFT 24 + +#define SNB_LATENCY(shift) (I915_READ(MCHBAR_MIRROR_BASE_SNB + SSKPD) >> (shift) & SSKPD_WM_MASK) +#define SNB_READ_WM0_LATENCY() SNB_LATENCY(SSKPD_WM0_SHIFT) +#define SNB_READ_WM1_LATENCY() SNB_LATENCY(SSKPD_WM1_SHIFT) +#define SNB_READ_WM2_LATENCY() SNB_LATENCY(SSKPD_WM2_SHIFT) +#define SNB_READ_WM3_LATENCY() SNB_LATENCY(SSKPD_WM3_SHIFT) + /* * The two pipe frame counter registers are not synchronized, so * reading a stable value is somewhat tricky. The following code @@ -2651,6 +2689,8 @@ #define ILK_VSDPFD_FULL (1<<21) #define ILK_DSPCLK_GATE 0x42020 #define ILK_DPARB_CLK_GATE (1<<5) +#define ILK_DPFD_CLK_GATE (1<<7) + /* According to spec this bit 7/8/9 of 0x42020 should be set to enable FBC */ #define ILK_CLK_FBC (1<<7) #define ILK_DPFC_DIS1 (1<<8) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 840bfc3ae719..eaf2bc6b537d 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -2845,6 +2845,39 @@ static struct intel_watermark_params ironlake_cursor_srwm_info = { ILK_FIFO_LINE_SIZE }; +static struct intel_watermark_params sandybridge_display_wm_info = { + SNB_DISPLAY_FIFO, + SNB_DISPLAY_MAXWM, + SNB_DISPLAY_DFTWM, + 2, + SNB_FIFO_LINE_SIZE +}; + +static struct intel_watermark_params sandybridge_cursor_wm_info = { + SNB_CURSOR_FIFO, + SNB_CURSOR_MAXWM, + SNB_CURSOR_DFTWM, + 2, + SNB_FIFO_LINE_SIZE +}; + +static struct intel_watermark_params sandybridge_display_srwm_info = { + SNB_DISPLAY_SR_FIFO, + SNB_DISPLAY_MAX_SRWM, + SNB_DISPLAY_DFT_SRWM, + 2, + SNB_FIFO_LINE_SIZE +}; + +static struct intel_watermark_params sandybridge_cursor_srwm_info = { + SNB_CURSOR_SR_FIFO, + SNB_CURSOR_MAX_SRWM, + SNB_CURSOR_DFT_SRWM, + 2, + SNB_FIFO_LINE_SIZE +}; + + /** * intel_calculate_wm - calculate watermark level * @clock_in_khz: pixel clock @@ -3378,6 +3411,10 @@ static void i830_update_wm(struct drm_device *dev, int planea_clock, int unused, static bool ironlake_compute_wm0(struct drm_device *dev, int pipe, + const struct intel_watermark_params *display, + int display_latency, + const struct intel_watermark_params *cursor, + int cursor_latency, int *plane_wm, int *cursor_wm) { @@ -3395,22 +3432,20 @@ static bool ironlake_compute_wm0(struct drm_device *dev, pixel_size = crtc->fb->bits_per_pixel / 8; /* Use the small buffer method to calculate plane watermark */ - entries = ((clock * pixel_size / 1000) * ILK_LP0_PLANE_LATENCY) / 1000; - entries = DIV_ROUND_UP(entries, - ironlake_display_wm_info.cacheline_size); - *plane_wm = entries + ironlake_display_wm_info.guard_size; - if (*plane_wm > (int)ironlake_display_wm_info.max_wm) - *plane_wm = ironlake_display_wm_info.max_wm; + entries = ((clock * pixel_size / 1000) * display_latency * 100) / 1000; + entries = DIV_ROUND_UP(entries, display->cacheline_size); + *plane_wm = entries + display->guard_size; + if (*plane_wm > (int)display->max_wm) + *plane_wm = display->max_wm; /* Use the large buffer method to calculate cursor watermark */ line_time_us = ((htotal * 1000) / clock); - line_count = (ILK_LP0_CURSOR_LATENCY / line_time_us + 1000) / 1000; + line_count = (cursor_latency * 100 / line_time_us + 1000) / 1000; entries = line_count * 64 * pixel_size; - entries = DIV_ROUND_UP(entries, - ironlake_cursor_wm_info.cacheline_size); - *cursor_wm = entries + ironlake_cursor_wm_info.guard_size; - if (*cursor_wm > ironlake_cursor_wm_info.max_wm) - *cursor_wm = ironlake_cursor_wm_info.max_wm; + entries = DIV_ROUND_UP(entries, cursor->cacheline_size); + *cursor_wm = entries + cursor->guard_size; + if (*cursor_wm > (int)cursor->max_wm) + *cursor_wm = (int)cursor->max_wm; return true; } @@ -3425,7 +3460,12 @@ static void ironlake_update_wm(struct drm_device *dev, int tmp; enabled = 0; - if (ironlake_compute_wm0(dev, 0, &plane_wm, &cursor_wm)) { + if (ironlake_compute_wm0(dev, 0, + &ironlake_display_wm_info, + ILK_LP0_PLANE_LATENCY, + &ironlake_cursor_wm_info, + ILK_LP0_CURSOR_LATENCY, + &plane_wm, &cursor_wm)) { I915_WRITE(WM0_PIPEA_ILK, (plane_wm << WM0_PIPE_PLANE_SHIFT) | cursor_wm); DRM_DEBUG_KMS("FIFO watermarks For pipe A -" @@ -3434,7 +3474,12 @@ static void ironlake_update_wm(struct drm_device *dev, enabled++; } - if (ironlake_compute_wm0(dev, 1, &plane_wm, &cursor_wm)) { + if (ironlake_compute_wm0(dev, 1, + &ironlake_display_wm_info, + ILK_LP0_PLANE_LATENCY, + &ironlake_cursor_wm_info, + ILK_LP0_CURSOR_LATENCY, + &plane_wm, &cursor_wm)) { I915_WRITE(WM0_PIPEB_ILK, (plane_wm << WM0_PIPE_PLANE_SHIFT) | cursor_wm); DRM_DEBUG_KMS("FIFO watermarks For pipe B -" @@ -3500,6 +3545,197 @@ static void ironlake_update_wm(struct drm_device *dev, /* XXX setup WM2 and WM3 */ } +/* + * Check the wm result. + * + * If any calculated watermark values is larger than the maximum value that + * can be programmed into the associated watermark register, that watermark + * must be disabled. + * + * Also return true if all of those watermark values is 0, which is set by + * sandybridge_compute_srwm, to indicate the latency is ZERO. + */ +static bool sandybridge_check_srwm(struct drm_device *dev, int level, + int fbc_wm, int display_wm, int cursor_wm) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + + DRM_DEBUG_KMS("watermark %d: display plane %d, fbc lines %d," + " cursor %d\n", level, display_wm, fbc_wm, cursor_wm); + + if (fbc_wm > SNB_FBC_MAX_SRWM) { + DRM_DEBUG_KMS("fbc watermark(%d) is too large(%d), disabling wm%d+\n", + fbc_wm, SNB_FBC_MAX_SRWM, level); + + /* fbc has it's own way to disable FBC WM */ + I915_WRITE(DISP_ARB_CTL, + I915_READ(DISP_ARB_CTL) | DISP_FBC_WM_DIS); + return false; + } + + if (display_wm > SNB_DISPLAY_MAX_SRWM) { + DRM_DEBUG_KMS("display watermark(%d) is too large(%d), disabling wm%d+\n", + display_wm, SNB_DISPLAY_MAX_SRWM, level); + return false; + } + + if (cursor_wm > SNB_CURSOR_MAX_SRWM) { + DRM_DEBUG_KMS("cursor watermark(%d) is too large(%d), disabling wm%d+\n", + cursor_wm, SNB_CURSOR_MAX_SRWM, level); + return false; + } + + if (!(fbc_wm || display_wm || cursor_wm)) { + DRM_DEBUG_KMS("latency %d is 0, disabling wm%d+\n", level, level); + return false; + } + + return true; +} + +/* + * Compute watermark values of WM[1-3], + */ +static bool sandybridge_compute_srwm(struct drm_device *dev, int level, + int hdisplay, int htotal, int pixel_size, + int clock, int latency_ns, int *fbc_wm, + int *display_wm, int *cursor_wm) +{ + + unsigned long line_time_us; + int small, large; + int entries; + int line_count, line_size; + + if (!latency_ns) { + *fbc_wm = *display_wm = *cursor_wm = 0; + return false; + } + + line_time_us = (htotal * 1000) / clock; + line_count = (latency_ns / line_time_us + 1000) / 1000; + line_size = hdisplay * pixel_size; + + /* Use the minimum of the small and large buffer method for primary */ + small = ((clock * pixel_size / 1000) * latency_ns) / 1000; + large = line_count * line_size; + + entries = DIV_ROUND_UP(min(small, large), + sandybridge_display_srwm_info.cacheline_size); + *display_wm = entries + sandybridge_display_srwm_info.guard_size; + + /* + * Spec said: + * FBC WM = ((Final Primary WM * 64) / number of bytes per line) + 2 + */ + *fbc_wm = DIV_ROUND_UP(*display_wm * 64, line_size) + 2; + + /* calculate the self-refresh watermark for display cursor */ + entries = line_count * pixel_size * 64; + entries = DIV_ROUND_UP(entries, + sandybridge_cursor_srwm_info.cacheline_size); + *cursor_wm = entries + sandybridge_cursor_srwm_info.guard_size; + + return sandybridge_check_srwm(dev, level, + *fbc_wm, *display_wm, *cursor_wm); +} + +static void sandybridge_update_wm(struct drm_device *dev, + int planea_clock, int planeb_clock, + int hdisplay, int htotal, + int pixel_size) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + int latency = SNB_READ_WM0_LATENCY(); + int fbc_wm, plane_wm, cursor_wm, enabled; + int clock; + + enabled = 0; + if (ironlake_compute_wm0(dev, 0, + &sandybridge_display_wm_info, latency, + &sandybridge_cursor_wm_info, latency, + &plane_wm, &cursor_wm)) { + I915_WRITE(WM0_PIPEA_ILK, + (plane_wm << WM0_PIPE_PLANE_SHIFT) | cursor_wm); + DRM_DEBUG_KMS("FIFO watermarks For pipe A -" + " plane %d, " "cursor: %d\n", + plane_wm, cursor_wm); + enabled++; + } + + if (ironlake_compute_wm0(dev, 1, + &sandybridge_display_wm_info, latency, + &sandybridge_cursor_wm_info, latency, + &plane_wm, &cursor_wm)) { + I915_WRITE(WM0_PIPEB_ILK, + (plane_wm << WM0_PIPE_PLANE_SHIFT) | cursor_wm); + DRM_DEBUG_KMS("FIFO watermarks For pipe B -" + " plane %d, cursor: %d\n", + plane_wm, cursor_wm); + enabled++; + } + + /* + * Calculate and update the self-refresh watermark only when one + * display plane is used. + * + * SNB support 3 levels of watermark. + * + * WM1/WM2/WM2 watermarks have to be enabled in the ascending order, + * and disabled in the descending order + * + */ + I915_WRITE(WM3_LP_ILK, 0); + I915_WRITE(WM2_LP_ILK, 0); + I915_WRITE(WM1_LP_ILK, 0); + + if (enabled != 1) + return; + + clock = planea_clock ? planea_clock : planeb_clock; + + /* WM1 */ + if (!sandybridge_compute_srwm(dev, 1, hdisplay, htotal, pixel_size, + clock, SNB_READ_WM1_LATENCY() * 500, + &fbc_wm, &plane_wm, &cursor_wm)) + return; + + I915_WRITE(WM1_LP_ILK, + WM1_LP_SR_EN | + (SNB_READ_WM1_LATENCY() << WM1_LP_LATENCY_SHIFT) | + (fbc_wm << WM1_LP_FBC_SHIFT) | + (plane_wm << WM1_LP_SR_SHIFT) | + cursor_wm); + + /* WM2 */ + if (!sandybridge_compute_srwm(dev, 2, + hdisplay, htotal, pixel_size, + clock, SNB_READ_WM2_LATENCY() * 500, + &fbc_wm, &plane_wm, &cursor_wm)) + return; + + I915_WRITE(WM2_LP_ILK, + WM2_LP_EN | + (SNB_READ_WM2_LATENCY() << WM1_LP_LATENCY_SHIFT) | + (fbc_wm << WM1_LP_FBC_SHIFT) | + (plane_wm << WM1_LP_SR_SHIFT) | + cursor_wm); + + /* WM3 */ + if (!sandybridge_compute_srwm(dev, 3, + hdisplay, htotal, pixel_size, + clock, SNB_READ_WM3_LATENCY() * 500, + &fbc_wm, &plane_wm, &cursor_wm)) + return; + + I915_WRITE(WM3_LP_ILK, + WM3_LP_EN | + (SNB_READ_WM3_LATENCY() << WM1_LP_LATENCY_SHIFT) | + (fbc_wm << WM1_LP_FBC_SHIFT) | + (plane_wm << WM1_LP_SR_SHIFT) | + cursor_wm); +} + /** * intel_update_watermarks - update FIFO watermark values based on current modes * @@ -5975,9 +6211,9 @@ void intel_enable_clock_gating(struct drm_device *dev) I915_WRITE(DISP_ARB_CTL, (I915_READ(DISP_ARB_CTL) | DISP_FBC_WM_DIS)); - I915_WRITE(WM3_LP_ILK, 0); - I915_WRITE(WM2_LP_ILK, 0); - I915_WRITE(WM1_LP_ILK, 0); + I915_WRITE(WM3_LP_ILK, 0); + I915_WRITE(WM2_LP_ILK, 0); + I915_WRITE(WM1_LP_ILK, 0); } /* * Based on the document from hardware guys the following bits @@ -6010,6 +6246,38 @@ void intel_enable_clock_gating(struct drm_device *dev) _3D_CHICKEN2_WM_READ_PIPELINED); } + if (IS_GEN6(dev)) { + I915_WRITE(WM3_LP_ILK, 0); + I915_WRITE(WM2_LP_ILK, 0); + I915_WRITE(WM1_LP_ILK, 0); + + /* + * According to the spec the following bits should be + * set in order to enable memory self-refresh and fbc: + * The bit21 and bit22 of 0x42000 + * The bit21 and bit22 of 0x42004 + * The bit5 and bit7 of 0x42020 + * The bit14 of 0x70180 + * The bit14 of 0x71180 + */ + I915_WRITE(ILK_DISPLAY_CHICKEN1, + I915_READ(ILK_DISPLAY_CHICKEN1) | + ILK_FBCQ_DIS | ILK_PABSTRETCH_DIS); + I915_WRITE(ILK_DISPLAY_CHICKEN2, + I915_READ(ILK_DISPLAY_CHICKEN2) | + ILK_DPARB_GATE | ILK_VSDPFD_FULL); + I915_WRITE(ILK_DSPCLK_GATE, + I915_READ(ILK_DSPCLK_GATE) | + ILK_DPARB_CLK_GATE | + ILK_DPFD_CLK_GATE); + + I915_WRITE(DSPACNTR, + I915_READ(DSPACNTR) | + DISPPLANE_TRICKLE_FEED_DISABLE); + I915_WRITE(DSPBCNTR, + I915_READ(DSPBCNTR) | + DISPPLANE_TRICKLE_FEED_DISABLE); + } } else if (IS_G4X(dev)) { uint32_t dspclk_gate; I915_WRITE(RENCLK_GATE_D1, 0); @@ -6176,6 +6444,14 @@ static void intel_init_display(struct drm_device *dev) "Disable CxSR\n"); dev_priv->display.update_wm = NULL; } + } else if (IS_GEN6(dev)) { + if (SNB_READ_WM0_LATENCY()) { + dev_priv->display.update_wm = sandybridge_update_wm; + } else { + DRM_DEBUG_KMS("Failed to read display plane latency. " + "Disable CxSR\n"); + dev_priv->display.update_wm = NULL; + } } else dev_priv->display.update_wm = NULL; } else if (IS_PINEVIEW(dev)) { -- cgit v1.2.3 From 9c04f015ebc2cc2cca5a4a576deb82a311578edc Mon Sep 17 00:00:00 2001 From: Yuanhan Liu Date: Wed, 15 Dec 2010 15:42:32 +0800 Subject: drm/i915: Add frame buffer compression on Sandybridge Add frame buffer compression on Sandybridge. The method is similar to Ironlake, except that two new registers of type GTTMMADR must be written with the right fence info. Signed-off-by: Yuanhan Liu Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_dma.c | 4 ++-- drivers/gpu/drm/i915/i915_drv.c | 1 + drivers/gpu/drm/i915/i915_reg.h | 10 ++++++++++ drivers/gpu/drm/i915/intel_display.c | 8 +++++++- 4 files changed, 20 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index e9fb8953c606..3f7b20392e26 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -1078,7 +1078,7 @@ static void i915_setup_compression(struct drm_device *dev, int size) if (!cfb_base) goto err_fb; - if (!(IS_GM45(dev) || IS_IRONLAKE_M(dev))) { + if (!(IS_GM45(dev) || HAS_PCH_SPLIT(dev))) { compressed_llb = drm_mm_search_free(&dev_priv->mm.stolen, 4096, 4096, 0); if (compressed_llb) @@ -1096,7 +1096,7 @@ static void i915_setup_compression(struct drm_device *dev, int size) intel_disable_fbc(dev); dev_priv->compressed_fb = compressed_fb; - if (IS_IRONLAKE_M(dev)) + if (HAS_PCH_SPLIT(dev)) I915_WRITE(ILK_DPFC_CB_BASE, compressed_fb->start); else if (IS_GM45(dev)) { I915_WRITE(DPFC_CB_BASE, compressed_fb->start); diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 5f20cd988612..bdb29b2a01ed 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -165,6 +165,7 @@ static const struct intel_device_info intel_sandybridge_d_info = { static const struct intel_device_info intel_sandybridge_m_info = { .gen = 6, .is_mobile = 1, .need_gfx_hws = 1, .has_hotplug = 1, + .has_fbc = 1, .has_bsd_ring = 1, .has_blt_ring = 1, }; diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 61ef98db9ff0..820e9dfaadc7 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -599,6 +599,16 @@ #define ILK_PABSTRETCH_DIS (1<<21) +/* + * Framebuffer compression for Sandybridge + * + * The following two registers are of type GTTMMADR + */ +#define SNB_DPFC_CTL_SA 0x100100 +#define SNB_CPU_FENCE_ENABLE (1<<29) +#define DPFC_CPU_FENCE_OFFSET 0x100104 + + /* * GPIO regs */ diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index eaf2bc6b537d..8645a974a499 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -1262,6 +1262,12 @@ static void ironlake_enable_fbc(struct drm_crtc *crtc, unsigned long interval) /* enable it... */ I915_WRITE(ILK_DPFC_CONTROL, dpfc_ctl | DPFC_CTL_EN); + if (IS_GEN6(dev)) { + I915_WRITE(SNB_DPFC_CTL_SA, + SNB_CPU_FENCE_ENABLE | dev_priv->cfb_fence); + I915_WRITE(DPFC_CPU_FENCE_OFFSET, crtc->y); + } + DRM_DEBUG_KMS("enabled fbc on plane %d\n", intel_crtc->plane); } @@ -6395,7 +6401,7 @@ static void intel_init_display(struct drm_device *dev) dev_priv->display.dpms = i9xx_crtc_dpms; if (I915_HAS_FBC(dev)) { - if (IS_IRONLAKE_M(dev)) { + if (HAS_PCH_SPLIT(dev)) { dev_priv->display.fbc_enabled = ironlake_fbc_enabled; dev_priv->display.enable_fbc = ironlake_enable_fbc; dev_priv->display.disable_fbc = ironlake_disable_fbc; -- cgit v1.2.3 From 6e71fabe9e60b1c6db587fbeac349848647920ab Mon Sep 17 00:00:00 2001 From: Arnaud Lacombe Date: Sun, 5 Dec 2010 01:31:57 -0500 Subject: kconfig: do not define AUTOCONF_INCLUDED AUTOCONF_INCLUDED is not checked is not used within the tree and its parent header, `autoconf.h', is safe to be re-included. Signed-off-by: Arnaud Lacombe Signed-off-by: Michal Marek --- scripts/kconfig/confdata.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c index 9df80114b47b..f349bdcffa98 100644 --- a/scripts/kconfig/confdata.c +++ b/scripts/kconfig/confdata.c @@ -833,8 +833,7 @@ int conf_write_autoconf(void) " * Automatically generated C config: don't edit\n" " * %s\n" " * %s" - " */\n" - "#define AUTOCONF_INCLUDED\n", + " */\n", rootmenu.prompt->text, ctime(&now)); for_all_symbols(i, sym) { -- cgit v1.2.3 From 0dce631092f410bb22b21b3d47ef20d69389dfd9 Mon Sep 17 00:00:00 2001 From: Arnaud Lacombe Date: Sun, 5 Dec 2010 01:33:16 -0500 Subject: kconfig: nuke second argument of conf_write_symbol() Replacing S_TRISTATE by S_BOOLEAN is a no-op for conf_write_symbol(). Signed-off-by: Arnaud Lacombe [mmarek: Fix unused variable warning in conf_write()] Signed-off-by: Michal Marek --- scripts/kconfig/confdata.c | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c index f349bdcffa98..d1bab0f42d10 100644 --- a/scripts/kconfig/confdata.c +++ b/scripts/kconfig/confdata.c @@ -440,12 +440,11 @@ static void conf_write_string(bool headerfile, const char *name, fputs("\"\n", out); } -static void conf_write_symbol(struct symbol *sym, enum symbol_type type, - FILE *out, bool write_no) +static void conf_write_symbol(struct symbol *sym, FILE *out, bool write_no) { const char *str; - switch (type) { + switch (sym->type) { case S_BOOLEAN: case S_TRISTATE: switch (sym_get_tristate_value(sym)) { @@ -532,7 +531,7 @@ int conf_write_defconfig(const char *filename) goto next_menu; } } - conf_write_symbol(sym, sym->type, out, true); + conf_write_symbol(sym, out, true); } next_menu: if (menu->list != NULL) { @@ -561,7 +560,6 @@ int conf_write(const char *name) const char *basename; const char *str; char dirname[PATH_MAX+1], tmpname[PATH_MAX+1], newname[PATH_MAX+1]; - enum symbol_type type; time_t now; int use_timestamp = 1; char *env; @@ -633,14 +631,8 @@ int conf_write(const char *name) if (!(sym->flags & SYMBOL_WRITE)) goto next; sym->flags &= ~SYMBOL_WRITE; - type = sym->type; - if (type == S_TRISTATE) { - sym_calc_value(modules_sym); - if (modules_sym->curr.tri == no) - type = S_BOOLEAN; - } /* Write config symbol to file */ - conf_write_symbol(sym, type, out, true); + conf_write_symbol(sym, out, true); } next: @@ -842,7 +834,7 @@ int conf_write_autoconf(void) continue; /* write symbol to config file */ - conf_write_symbol(sym, sym->type, out, false); + conf_write_symbol(sym, out, false); /* update autoconf and tristate files */ switch (sym->type) { -- cgit v1.2.3 From fe04ce0bf955eaf53f7e4cd6bb35976fa94e0925 Mon Sep 17 00:00:00 2001 From: Arnaud Lacombe Date: Sun, 5 Dec 2010 01:41:14 -0500 Subject: kbuild/nconf: fix spaces damage Signed-off-by: Arnaud Lacombe Signed-off-by: Michal Marek --- scripts/kconfig/nconf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/kconfig/nconf.c b/scripts/kconfig/nconf.c index 272a987f23e0..eda49ffc1c8c 100644 --- a/scripts/kconfig/nconf.c +++ b/scripts/kconfig/nconf.c @@ -248,7 +248,7 @@ search_help[] = N_( "Only relevant lines are shown.\n" "\n\n" "Search examples:\n" -"Examples: USB = > find all symbols containing USB\n" +"Examples: USB => find all symbols containing USB\n" " ^USB => find all symbols starting with USB\n" " USB$ => find all symbols ending with USB\n" "\n"); -- cgit v1.2.3 From 1ebfa5198ee96f34f2ee4ae95c92318f07341fbd Mon Sep 17 00:00:00 2001 From: Arnaud Lacombe Date: Sun, 5 Dec 2010 01:41:15 -0500 Subject: kbuild/gconf: add dummy inline for bind_textdomain_codeset() This symbols is used by gconf. Signed-off-by: Arnaud Lacombe Signed-off-by: Michal Marek --- scripts/kconfig/lkc.h | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/kconfig/lkc.h b/scripts/kconfig/lkc.h index 753cdbd7b805..a542c6ba84b3 100644 --- a/scripts/kconfig/lkc.h +++ b/scripts/kconfig/lkc.h @@ -14,6 +14,7 @@ static inline const char *gettext(const char *txt) { return txt; } static inline void textdomain(const char *domainname) {} static inline void bindtextdomain(const char *name, const char *dir) {} +static inline char *bind_textdomain_codeset(const char *dn, char *c) { return c; } #endif #ifdef __cplusplus -- cgit v1.2.3 From 579fb8e741fecef7dfd64afcc7b0b0c68ea207cc Mon Sep 17 00:00:00 2001 From: Arnaud Lacombe Date: Sun, 5 Dec 2010 01:41:16 -0500 Subject: kconfig: fix typos Signed-off-by: Arnaud Lacombe Signed-off-by: Michal Marek --- scripts/kconfig/confdata.c | 6 +++--- scripts/kconfig/symbol.c | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/scripts/kconfig/confdata.c b/scripts/kconfig/confdata.c index d1bab0f42d10..61c35bf2d9cb 100644 --- a/scripts/kconfig/confdata.c +++ b/scripts/kconfig/confdata.c @@ -937,7 +937,7 @@ static void randomize_choice_values(struct symbol *csym) int cnt, def; /* - * If choice is mod then we may have more items slected + * If choice is mod then we may have more items selected * and if no then no-one. * In both cases stop. */ @@ -1033,10 +1033,10 @@ void conf_set_all_new_symbols(enum conf_def_mode mode) /* * We have different type of choice blocks. - * If curr.tri equal to mod then we can select several + * If curr.tri equals to mod then we can select several * choice symbols in one block. * In this case we do nothing. - * If curr.tri equal yes then only one symbol can be + * If curr.tri equals yes then only one symbol can be * selected in a choice block and we set it to yes, * and the rest to no. */ diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c index c0efe102d655..60830ce4a0a9 100644 --- a/scripts/kconfig/symbol.c +++ b/scripts/kconfig/symbol.c @@ -686,7 +686,7 @@ const char *sym_get_string_default(struct symbol *sym) switch (sym->type) { case S_BOOLEAN: case S_TRISTATE: - /* The visibility imay limit the value from yes => mod */ + /* The visibility may limit the value from yes => mod */ val = EXPR_AND(expr_calc_value(prop->expr), prop->visible.tri); break; default: -- cgit v1.2.3 From bf128f5265625b8015789ea8f12b3582dc29faa3 Mon Sep 17 00:00:00 2001 From: Arnaud Lacombe Date: Sun, 5 Dec 2010 01:41:17 -0500 Subject: kconfig/conf: merge duplicate switch's case Signed-off-by: Arnaud Lacombe Signed-off-by: Michal Marek --- scripts/kconfig/conf.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/scripts/kconfig/conf.c b/scripts/kconfig/conf.c index 5459a38be866..659326c3e895 100644 --- a/scripts/kconfig/conf.c +++ b/scripts/kconfig/conf.c @@ -529,8 +529,6 @@ int main(int ac, char **av) } break; case savedefconfig: - conf_read(NULL); - break; case silentoldconfig: case oldaskconfig: case oldconfig: -- cgit v1.2.3 From 4ce2c1e8e899831dd152bd0d534a60da6fb1582a Mon Sep 17 00:00:00 2001 From: Arnaud Lacombe Date: Sun, 5 Dec 2010 01:41:18 -0500 Subject: kconfig: fix `zconfdebug' extern declaration This symbol is only exist if YYDEBUG is defined. Signed-off-by: Arnaud Lacombe Signed-off-by: Michal Marek --- scripts/kconfig/lkc.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/scripts/kconfig/lkc.h b/scripts/kconfig/lkc.h index a542c6ba84b3..6d38b7c9c824 100644 --- a/scripts/kconfig/lkc.h +++ b/scripts/kconfig/lkc.h @@ -68,10 +68,12 @@ struct kconf_id { enum symbol_type stype; }; +#ifdef YYDEBUG +extern int zconfdebug; +#endif + int zconfparse(void); void zconfdump(FILE *out); - -extern int zconfdebug; void zconf_starthelp(void); FILE *zconf_fopen(const char *name); void zconf_initscan(const char *name); -- cgit v1.2.3 From 656d4b1edeb32a87042caee5694603706e399929 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 14 Dec 2010 17:16:56 +0000 Subject: ASoC: Remove unused DAPM_DOUBLE control types There are no users of these and it's not clear what they would do given the mono flow modelling which DAPM does. If need arises we can add them again. Signed-off-by: Mark Brown Acked-by: Liam Girdwood --- include/sound/soc-dapm.h | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h index 2f76a51bbaac..aef975f47bad 100644 --- a/include/sound/soc-dapm.h +++ b/include/sound/soc-dapm.h @@ -227,13 +227,6 @@ .info = snd_soc_info_volsw, \ .get = snd_soc_dapm_get_volsw, .put = snd_soc_dapm_put_volsw, \ .private_value = SOC_SINGLE_VALUE(reg, shift, max, invert) } -#define SOC_DAPM_DOUBLE(xname, reg, shift_left, shift_right, max, invert, \ - power) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \ - .info = snd_soc_info_volsw, \ - .get = snd_soc_dapm_get_volsw, .put = snd_soc_dapm_put_volsw, \ - .private_value = (reg) | ((shift_left) << 8) | ((shift_right) << 12) |\ - ((max) << 16) | ((invert) << 24) } #define SOC_DAPM_SINGLE_TLV(xname, reg, shift, max, invert, tlv_array) \ { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ .info = snd_soc_info_volsw, \ @@ -241,15 +234,6 @@ .tlv.p = (tlv_array), \ .get = snd_soc_dapm_get_volsw, .put = snd_soc_dapm_put_volsw, \ .private_value = SOC_SINGLE_VALUE(reg, shift, max, invert) } -#define SOC_DAPM_DOUBLE_TLV(xname, reg, shift_left, shift_right, max, invert, \ - power, tlv_array) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \ - .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | SNDRV_CTL_ELEM_ACCESS_READWRITE,\ - .tlv.p = (tlv_array), \ - .info = snd_soc_info_volsw, \ - .get = snd_soc_dapm_get_volsw, .put = snd_soc_dapm_put_volsw, \ - .private_value = (reg) | ((shift_left) << 8) | ((shift_right) << 12) |\ - ((max) << 16) | ((invert) << 24) } #define SOC_DAPM_ENUM(xname, xenum) \ { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ .info = snd_soc_info_enum_double, \ -- cgit v1.2.3 From f0a6332ce221614fbd0731af92f668892fa4b700 Mon Sep 17 00:00:00 2001 From: Jonas Aaberg Date: Wed, 15 Dec 2010 08:37:00 +0100 Subject: kbuild: add numeric --set-val option to scripts/config Add new option to scripts/config for changing .config numeric values Acked-by: Linus Walleij Signed-off-by: Jonas Aaberg Signed-off-by: Michal Marek --- scripts/config | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/scripts/config b/scripts/config index dfd4732f7099..a7c7c4b8e957 100755 --- a/scripts/config +++ b/scripts/config @@ -10,8 +10,10 @@ commands: --enable|-e option Enable option --disable|-d option Disable option --module|-m option Turn option into a module - --set-str option value - Set option to "value" + --set-str option string + Set option to "string" + --set-val option value + Set option to value --state|-s option Print state of option (n,y,m,undef) --enable-after|-E beforeopt option @@ -109,6 +111,11 @@ while [ "$1" != "" ] ; do shift ;; + --set-val) + set_var "CONFIG_$ARG" "CONFIG_$ARG=$1" + shift + ;; + --state|-s) if grep -q "# CONFIG_$ARG is not set" $FN ; then echo n -- cgit v1.2.3 From 8ddab3f5107c3955e70e87a632d4d179ddba1189 Mon Sep 17 00:00:00 2001 From: Jarkko Nikula Date: Tue, 14 Dec 2010 12:18:30 +0200 Subject: ASoC: Move DAPM paths from DAPM context to snd_soc_card Decoupling DAPM paths from DAPM context is a first prerequisite when extending ASoC core to cross-device paths. This patch is almost a nullop and does not allow to construct cross-device setup but the path clean-up part in dapm_free_widgets is prepared to remove cross-device paths between a device being removed and others. Signed-off-by: Jarkko Nikula Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- include/sound/soc-dapm.h | 1 - include/sound/soc.h | 2 ++ sound/soc/codecs/tlv320aic3x.c | 2 +- sound/soc/soc-core.c | 2 +- sound/soc/soc-dapm.c | 41 +++++++++++++++++++++++++++-------------- 5 files changed, 31 insertions(+), 17 deletions(-) diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h index aef975f47bad..2c1e0eed43d5 100644 --- a/include/sound/soc-dapm.h +++ b/include/sound/soc-dapm.h @@ -463,7 +463,6 @@ struct snd_soc_dapm_widget { /* DAPM context */ struct snd_soc_dapm_context { struct list_head widgets; - struct list_head paths; enum snd_soc_bias_level bias_level; enum snd_soc_bias_level suspend_bias_level; struct delayed_work delayed_work; diff --git a/include/sound/soc.h b/include/sound/soc.h index 7e65b015f8dd..466895b627b5 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -661,6 +661,8 @@ struct snd_soc_card { struct list_head platform_dev_list; struct list_head dai_dev_list; + struct list_head paths; + #ifdef CONFIG_DEBUG_FS struct dentry *debugfs_card_root; struct dentry *debugfs_pop_time; diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c index fc5abdf0bcb0..899af41787c1 100644 --- a/sound/soc/codecs/tlv320aic3x.c +++ b/sound/soc/codecs/tlv320aic3x.c @@ -185,7 +185,7 @@ static int snd_soc_dapm_put_volsw_aic3x(struct snd_kcontrol *kcontrol, if (snd_soc_test_bits(widget->codec, reg, val_mask, val)) { /* find dapm widget path assoc with kcontrol */ - list_for_each_entry(path, &widget->dapm->paths, list) { + list_for_each_entry(path, &widget->dapm->card->paths, list) { if (path->kcontrol != kcontrol) continue; diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 1dc4b11c1988..bdb2ca9da58b 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -1879,6 +1879,7 @@ static int soc_probe(struct platform_device *pdev) INIT_LIST_HEAD(&card->dai_dev_list); INIT_LIST_HEAD(&card->codec_dev_list); INIT_LIST_HEAD(&card->platform_dev_list); + INIT_LIST_HEAD(&card->paths); soc_init_card_debugfs(card); @@ -3481,7 +3482,6 @@ int snd_soc_register_codec(struct device *dev, codec->compress_type = SND_SOC_FLAT_COMPRESSION; INIT_LIST_HEAD(&codec->dapm.widgets); - INIT_LIST_HEAD(&codec->dapm.paths); codec->write = codec_drv->write; codec->read = codec_drv->read; codec->dapm.bias_level = SND_SOC_BIAS_OFF; diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index 3d310af28907..5d9ec4a3a9f1 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -272,7 +272,7 @@ static int dapm_connect_mux(struct snd_soc_dapm_context *dapm, for (i = 0; i < e->max; i++) { if (!(strcmp(control_name, e->texts[i]))) { - list_add(&path->list, &dapm->paths); + list_add(&path->list, &dapm->card->paths); list_add(&path->list_sink, &dest->sources); list_add(&path->list_source, &src->sinks); path->name = (char*)e->texts[i]; @@ -294,7 +294,7 @@ static int dapm_connect_mixer(struct snd_soc_dapm_context *dapm, /* search for mixer kcontrol */ for (i = 0; i < dest->num_kcontrols; i++) { if (!strcmp(control_name, dest->kcontrols[i].name)) { - list_add(&path->list, &dapm->paths); + list_add(&path->list, &dapm->card->paths); list_add(&path->list_sink, &dest->sources); list_add(&path->list_source, &src->sinks); path->name = dest->kcontrols[i].name; @@ -453,7 +453,7 @@ static inline void dapm_clear_walk(struct snd_soc_dapm_context *dapm) { struct snd_soc_dapm_path *p; - list_for_each_entry(p, &dapm->paths, list) + list_for_each_entry(p, &dapm->card->paths, list) p->walked = 0; } @@ -1180,7 +1180,7 @@ static int dapm_mux_update_power(struct snd_soc_dapm_widget *widget, return 0; /* find dapm widget path assoc with kcontrol */ - list_for_each_entry(path, &widget->dapm->paths, list) { + list_for_each_entry(path, &widget->dapm->card->paths, list) { if (path->kcontrol != kcontrol) continue; @@ -1214,7 +1214,7 @@ static int dapm_mixer_update_power(struct snd_soc_dapm_widget *widget, return -ENODEV; /* find dapm widget path assoc with kcontrol */ - list_for_each_entry(path, &widget->dapm->paths, list) { + list_for_each_entry(path, &widget->dapm->card->paths, list) { if (path->kcontrol != kcontrol) continue; @@ -1305,15 +1305,28 @@ static void dapm_free_widgets(struct snd_soc_dapm_context *dapm) list_for_each_entry_safe(w, next_w, &dapm->widgets, list) { list_del(&w->list); + /* + * remove source and sink paths associated to this widget. + * While removing the path, remove reference to it from both + * source and sink widgets so that path is removed only once. + */ + list_for_each_entry_safe(p, next_p, &w->sources, list_sink) { + list_del(&p->list_sink); + list_del(&p->list_source); + list_del(&p->list); + kfree(p->long_name); + kfree(p); + } + list_for_each_entry_safe(p, next_p, &w->sinks, list_source) { + list_del(&p->list_sink); + list_del(&p->list_source); + list_del(&p->list); + kfree(p->long_name); + kfree(p); + } kfree(w->name); kfree(w); } - - list_for_each_entry_safe(p, next_p, &dapm->paths, list) { - list_del(&p->list); - kfree(p->long_name); - kfree(p); - } } static int snd_soc_dapm_set_pin(struct snd_soc_dapm_context *dapm, @@ -1420,7 +1433,7 @@ static int snd_soc_dapm_add_route(struct snd_soc_dapm_context *dapm, /* connect static paths */ if (control == NULL) { - list_add(&path->list, &dapm->paths); + list_add(&path->list, &dapm->card->paths); list_add(&path->list_sink, &wsink->sources); list_add(&path->list_source, &wsource->sinks); path->connect = 1; @@ -1442,7 +1455,7 @@ static int snd_soc_dapm_add_route(struct snd_soc_dapm_context *dapm, case snd_soc_dapm_supply: case snd_soc_dapm_aif_in: case snd_soc_dapm_aif_out: - list_add(&path->list, &dapm->paths); + list_add(&path->list, &dapm->card->paths); list_add(&path->list_sink, &wsink->sources); list_add(&path->list_source, &wsource->sinks); path->connect = 1; @@ -1465,7 +1478,7 @@ static int snd_soc_dapm_add_route(struct snd_soc_dapm_context *dapm, case snd_soc_dapm_mic: case snd_soc_dapm_line: case snd_soc_dapm_spk: - list_add(&path->list, &dapm->paths); + list_add(&path->list, &dapm->card->paths); list_add(&path->list_sink, &wsink->sources); list_add(&path->list_source, &wsource->sinks); path->connect = 0; -- cgit v1.2.3 From 97c866defc0fc6e18b49603ac19f732f53e79c46 Mon Sep 17 00:00:00 2001 From: Jarkko Nikula Date: Tue, 14 Dec 2010 12:18:31 +0200 Subject: ASoC: Move widgets from DAPM context to snd_soc_card Decoupling widgets from DAPM context is required when extending the ASoC core to cross-device paths. Even the list of widgets are now kept in struct snd_soc_card, the widget listing in sysfs and debugs remain sorted per device. This patch makes possible to build cross-device paths but does not extend yet the DAPM to handle codec bias and widget power changes of an another device. Cross-device paths are registered by listing the widgets from device A in a map for device B. In case of conflicting widget names between the devices, a uniform name prefix is needed to separate them. See commit ead9b91 "ASoC: Add optional name_prefix for kcontrol, widget and route names" for help. An example below shows a path that connects MONO out of A into Line In of B: static const struct snd_soc_dapm_route mapA[] = { {"MONO", NULL, "DAC"}, }; static const struct snd_soc_dapm_route mapB[] = { {"Line In", NULL, "MONO"}, }; Signed-off-by: Jarkko Nikula Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- include/sound/soc-dapm.h | 2 +- include/sound/soc.h | 1 + sound/soc/codecs/wm8960.c | 4 ++- sound/soc/soc-core.c | 2 +- sound/soc/soc-dapm.c | 69 +++++++++++++++++++++++++++++++++-------------- 5 files changed, 55 insertions(+), 23 deletions(-) diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h index 2c1e0eed43d5..c0e7c47469fc 100644 --- a/include/sound/soc-dapm.h +++ b/include/sound/soc-dapm.h @@ -462,7 +462,7 @@ struct snd_soc_dapm_widget { /* DAPM context */ struct snd_soc_dapm_context { - struct list_head widgets; + int n_widgets; /* number of widgets in this context */ enum snd_soc_bias_level bias_level; enum snd_soc_bias_level suspend_bias_level; struct delayed_work delayed_work; diff --git a/include/sound/soc.h b/include/sound/soc.h index 466895b627b5..d5fb8618fdba 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -661,6 +661,7 @@ struct snd_soc_card { struct list_head platform_dev_list; struct list_head dai_dev_list; + struct list_head widgets; struct list_head paths; #ifdef CONFIG_DEBUG_FS diff --git a/sound/soc/codecs/wm8960.c b/sound/soc/codecs/wm8960.c index 2c5712dce1d5..054f5737319c 100644 --- a/sound/soc/codecs/wm8960.c +++ b/sound/soc/codecs/wm8960.c @@ -418,7 +418,9 @@ static int wm8960_add_widgets(struct snd_soc_codec *codec) * list each time to find the desired power state do so now * and save the result. */ - list_for_each_entry(w, &codec->dapm.widgets, list) { + list_for_each_entry(w, &codec->card->widgets, list) { + if (w->dapm != &codec->dapm) + continue; if (strcmp(w->name, "LOUT1 PGA") == 0) wm8960->lout1 = w; if (strcmp(w->name, "ROUT1 PGA") == 0) diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index bdb2ca9da58b..bd183a7ed696 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -1879,6 +1879,7 @@ static int soc_probe(struct platform_device *pdev) INIT_LIST_HEAD(&card->dai_dev_list); INIT_LIST_HEAD(&card->codec_dev_list); INIT_LIST_HEAD(&card->platform_dev_list); + INIT_LIST_HEAD(&card->widgets); INIT_LIST_HEAD(&card->paths); soc_init_card_debugfs(card); @@ -3481,7 +3482,6 @@ int snd_soc_register_codec(struct device *dev, else codec->compress_type = SND_SOC_FLAT_COMPRESSION; - INIT_LIST_HEAD(&codec->dapm.widgets); codec->write = codec_drv->write; codec->read = codec_drv->read; codec->dapm.bias_level = SND_SOC_BIAS_OFF; diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index 5d9ec4a3a9f1..8731e89646ae 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -940,7 +940,9 @@ static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event) /* Check which widgets we need to power and store them in * lists indicating if they should be powered up or down. */ - list_for_each_entry(w, &dapm->widgets, list) { + list_for_each_entry(w, &card->widgets, list) { + if (w->dapm != dapm) + continue; switch (w->id) { case snd_soc_dapm_pre: dapm_seq_insert(w, &down_list, dapm_down_seq); @@ -978,7 +980,7 @@ static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event) /* If there are no DAPM widgets then try to figure out power from the * event type. */ - if (list_empty(&dapm->widgets)) { + if (!dapm->n_widgets) { switch (event) { case SND_SOC_DAPM_STREAM_START: case SND_SOC_DAPM_STREAM_RESUME: @@ -1145,8 +1147,8 @@ void snd_soc_dapm_debugfs_init(struct snd_soc_dapm_context *dapm) if (!dapm->debugfs_dapm) return; - list_for_each_entry(w, &dapm->widgets, list) { - if (!w->name) + list_for_each_entry(w, &dapm->card->widgets, list) { + if (!w->name || w->dapm != dapm) continue; d = debugfs_create_file(w->name, 0444, @@ -1241,7 +1243,9 @@ static ssize_t dapm_widget_show(struct device *dev, int count = 0; char *state = "not set"; - list_for_each_entry(w, &codec->dapm.widgets, list) { + list_for_each_entry(w, &codec->card->widgets, list) { + if (w->dapm != &codec->dapm) + continue; /* only display widgets that burnm power */ switch (w->id) { @@ -1303,7 +1307,9 @@ static void dapm_free_widgets(struct snd_soc_dapm_context *dapm) struct snd_soc_dapm_widget *w, *next_w; struct snd_soc_dapm_path *p, *next_p; - list_for_each_entry_safe(w, next_w, &dapm->widgets, list) { + list_for_each_entry_safe(w, next_w, &dapm->card->widgets, list) { + if (w->dapm != dapm) + continue; list_del(&w->list); /* * remove source and sink paths associated to this widget. @@ -1334,7 +1340,9 @@ static int snd_soc_dapm_set_pin(struct snd_soc_dapm_context *dapm, { struct snd_soc_dapm_widget *w; - list_for_each_entry(w, &dapm->widgets, list) { + list_for_each_entry(w, &dapm->card->widgets, list) { + if (w->dapm != dapm) + continue; if (!strcmp(w->name, pin)) { dev_dbg(w->dapm->dev, "dapm: pin %s = %d\n", pin, status); @@ -1370,6 +1378,7 @@ static int snd_soc_dapm_add_route(struct snd_soc_dapm_context *dapm, { struct snd_soc_dapm_path *path; struct snd_soc_dapm_widget *wsource = NULL, *wsink = NULL, *w; + struct snd_soc_dapm_widget *wtsource = NULL, *wtsink = NULL; const char *sink; const char *control = route->control; const char *source; @@ -1389,17 +1398,28 @@ static int snd_soc_dapm_add_route(struct snd_soc_dapm_context *dapm, source = route->source; } - /* find src and dest widgets */ - list_for_each_entry(w, &dapm->widgets, list) { - + /* + * find src and dest widgets over all widgets but favor a widget from + * current DAPM context + */ + list_for_each_entry(w, &dapm->card->widgets, list) { if (!wsink && !(strcmp(w->name, sink))) { - wsink = w; + wtsink = w; + if (w->dapm == dapm) + wsink = w; continue; } if (!wsource && !(strcmp(w->name, source))) { - wsource = w; + wtsource = w; + if (w->dapm == dapm) + wsource = w; } } + /* use widget from another DAPM context if not found from this */ + if (!wsink) + wsink = wtsink; + if (!wsource) + wsource = wtsource; if (wsource == NULL || wsink == NULL) return -ENODEV; @@ -1537,7 +1557,7 @@ int snd_soc_dapm_new_widgets(struct snd_soc_dapm_context *dapm) { struct snd_soc_dapm_widget *w; - list_for_each_entry(w, &dapm->widgets, list) + list_for_each_entry(w, &dapm->card->widgets, list) { if (w->new) continue; @@ -2037,12 +2057,13 @@ int snd_soc_dapm_new_control(struct snd_soc_dapm_context *dapm, else snprintf(w->name, name_len, "%s", widget->name); + dapm->n_widgets++; w->dapm = dapm; w->codec = dapm->codec; INIT_LIST_HEAD(&w->sources); INIT_LIST_HEAD(&w->sinks); INIT_LIST_HEAD(&w->list); - list_add(&w->list, &dapm->widgets); + list_add(&w->list, &dapm->card->widgets); /* machine layer set ups unconnected pins and insertions */ w->connected = 1; @@ -2085,9 +2106,9 @@ static void soc_dapm_stream_event(struct snd_soc_dapm_context *dapm, { struct snd_soc_dapm_widget *w; - list_for_each_entry(w, &dapm->widgets, list) + list_for_each_entry(w, &dapm->card->widgets, list) { - if (!w->sname) + if (!w->sname || w->dapm != dapm) continue; dev_dbg(w->dapm->dev, "widget %s\n %s stream %s event %d\n", w->name, w->sname, stream, event); @@ -2170,7 +2191,9 @@ int snd_soc_dapm_force_enable_pin(struct snd_soc_dapm_context *dapm, { struct snd_soc_dapm_widget *w; - list_for_each_entry(w, &dapm->widgets, list) { + list_for_each_entry(w, &dapm->card->widgets, list) { + if (w->dapm != dapm) + continue; if (!strcmp(w->name, pin)) { dev_dbg(w->dapm->dev, "dapm: force enable pin %s\n", pin); @@ -2235,7 +2258,9 @@ int snd_soc_dapm_get_pin_status(struct snd_soc_dapm_context *dapm, { struct snd_soc_dapm_widget *w; - list_for_each_entry(w, &dapm->widgets, list) { + list_for_each_entry(w, &dapm->card->widgets, list) { + if (w->dapm != dapm) + continue; if (!strcmp(w->name, pin)) return w->connected; } @@ -2260,7 +2285,9 @@ int snd_soc_dapm_ignore_suspend(struct snd_soc_dapm_context *dapm, { struct snd_soc_dapm_widget *w; - list_for_each_entry(w, &dapm->widgets, list) { + list_for_each_entry(w, &dapm->card->widgets, list) { + if (w->dapm != dapm) + continue; if (!strcmp(w->name, pin)) { w->ignore_suspend = 1; return 0; @@ -2291,7 +2318,9 @@ static void soc_dapm_shutdown_codec(struct snd_soc_dapm_context *dapm) LIST_HEAD(down_list); int powerdown = 0; - list_for_each_entry(w, &dapm->widgets, list) { + list_for_each_entry(w, &dapm->card->widgets, list) { + if (w->dapm != dapm) + continue; if (w->power) { dapm_seq_insert(w, &down_list, dapm_down_seq); w->power = 0; -- cgit v1.2.3 From 7be31be880ee00c6f8d38184368e8a834923b469 Mon Sep 17 00:00:00 2001 From: Jarkko Nikula Date: Tue, 14 Dec 2010 12:18:32 +0200 Subject: ASoC: Extend DAPM to handle power changes on cross-device paths Power change event like stream start/stop or kcontrol change in a cross-device path originates from one device but codec bias and widget power changes must be populated to another devices on that path as well. This patch modifies the dapm_power_widgets so that all the widgets on a sound card are checked for a power change, not just those that are specific to originating device. Also bias management is extended to check all the devices. Only exception in bias management are widgetless codecs whose bias state is changed only if power change is originating from that context. DAPM context test is added to dapm_seq_run to take care of if power sequence extends to an another device which requires separate register writes. Signed-off-by: Jarkko Nikula Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- include/sound/soc-dapm.h | 5 +++ include/sound/soc.h | 1 + sound/soc/soc-core.c | 2 + sound/soc/soc-dapm.c | 109 +++++++++++++++++++++++++++-------------------- 4 files changed, 71 insertions(+), 46 deletions(-) diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h index c0e7c47469fc..98783510d2f1 100644 --- a/include/sound/soc-dapm.h +++ b/include/sound/soc-dapm.h @@ -471,6 +471,11 @@ struct snd_soc_dapm_context { struct device *dev; /* from parent - for debug */ struct snd_soc_codec *codec; /* parent codec */ struct snd_soc_card *card; /* parent card */ + + /* used during DAPM updates */ + int dev_power; + struct list_head list; + #ifdef CONFIG_DEBUG_FS struct dentry *debugfs_dapm; #endif diff --git a/include/sound/soc.h b/include/sound/soc.h index d5fb8618fdba..74921f20a1d8 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -663,6 +663,7 @@ struct snd_soc_card { struct list_head widgets; struct list_head paths; + struct list_head dapm_list; #ifdef CONFIG_DEBUG_FS struct dentry *debugfs_card_root; diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index bd183a7ed696..a233607a73c6 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -1427,6 +1427,7 @@ static int soc_probe_codec(struct snd_soc_card *card, /* mark codec as probed and add to card codec list */ codec->probed = 1; list_add(&codec->card_list, &card->codec_dev_list); + list_add(&codec->dapm.list, &card->dapm_list); return ret; } @@ -1881,6 +1882,7 @@ static int soc_probe(struct platform_device *pdev) INIT_LIST_HEAD(&card->platform_dev_list); INIT_LIST_HEAD(&card->widgets); INIT_LIST_HEAD(&card->paths); + INIT_LIST_HEAD(&card->dapm_list); soc_init_card_debugfs(card); diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index 8731e89646ae..f362d1de78f3 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -847,19 +847,22 @@ static void dapm_seq_run(struct snd_soc_dapm_context *dapm, LIST_HEAD(pending); int cur_sort = -1; int cur_reg = SND_SOC_NOPM; + struct snd_soc_dapm_context *cur_dapm = NULL; int ret; list_for_each_entry_safe(w, n, list, power_list) { ret = 0; /* Do we need to apply any queued changes? */ - if (sort[w->id] != cur_sort || w->reg != cur_reg) { + if (sort[w->id] != cur_sort || w->reg != cur_reg || + w->dapm != cur_dapm) { if (!list_empty(&pending)) - dapm_seq_run_coalesced(dapm, &pending); + dapm_seq_run_coalesced(cur_dapm, &pending); INIT_LIST_HEAD(&pending); cur_sort = -1; cur_reg = SND_SOC_NOPM; + cur_dapm = NULL; } switch (w->id) { @@ -903,6 +906,7 @@ static void dapm_seq_run(struct snd_soc_dapm_context *dapm, /* Queue it up for application */ cur_sort = sort[w->id]; cur_reg = w->reg; + cur_dapm = w->dapm; list_move(&w->power_list, &pending); break; } @@ -929,20 +933,22 @@ static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event) { struct snd_soc_card *card = dapm->codec->card; struct snd_soc_dapm_widget *w; + struct snd_soc_dapm_context *d; LIST_HEAD(up_list); LIST_HEAD(down_list); int ret = 0; int power; - int sys_power = 0; trace_snd_soc_dapm_start(card); + list_for_each_entry(d, &card->dapm_list, list) + if (d->n_widgets) + d->dev_power = 0; + /* Check which widgets we need to power and store them in * lists indicating if they should be powered up or down. */ list_for_each_entry(w, &card->widgets, list) { - if (w->dapm != dapm) - continue; switch (w->id) { case snd_soc_dapm_pre: dapm_seq_insert(w, &down_list, dapm_down_seq); @@ -960,7 +966,7 @@ static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event) else power = 1; if (power) - sys_power = 1; + w->dapm->dev_power = 1; if (w->power == power) continue; @@ -984,22 +990,22 @@ static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event) switch (event) { case SND_SOC_DAPM_STREAM_START: case SND_SOC_DAPM_STREAM_RESUME: - sys_power = 1; + dapm->dev_power = 1; break; case SND_SOC_DAPM_STREAM_STOP: - sys_power = !!dapm->codec->active; + dapm->dev_power = !!dapm->codec->active; break; case SND_SOC_DAPM_STREAM_SUSPEND: - sys_power = 0; + dapm->dev_power = 0; break; case SND_SOC_DAPM_STREAM_NOP: switch (dapm->bias_level) { case SND_SOC_BIAS_STANDBY: case SND_SOC_BIAS_OFF: - sys_power = 0; + dapm->dev_power = 0; break; default: - sys_power = 1; + dapm->dev_power = 1; break; } break; @@ -1008,21 +1014,24 @@ static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event) } } - if (sys_power && dapm->bias_level == SND_SOC_BIAS_OFF) { - ret = snd_soc_dapm_set_bias_level(card, dapm, - SND_SOC_BIAS_STANDBY); - if (ret != 0) - dev_err(dapm->dev, - "Failed to turn on bias: %d\n", ret); - } + list_for_each_entry(d, &dapm->card->dapm_list, list) { + if (d->dev_power && d->bias_level == SND_SOC_BIAS_OFF) { + ret = snd_soc_dapm_set_bias_level(card, d, + SND_SOC_BIAS_STANDBY); + if (ret != 0) + dev_err(d->dev, + "Failed to turn on bias: %d\n", ret); + } - /* If we're changing to all on or all off then prepare */ - if ((sys_power && dapm->bias_level == SND_SOC_BIAS_STANDBY) || - (!sys_power && dapm->bias_level == SND_SOC_BIAS_ON)) { - ret = snd_soc_dapm_set_bias_level(card, dapm, SND_SOC_BIAS_PREPARE); - if (ret != 0) - dev_err(dapm->dev, - "Failed to prepare bias: %d\n", ret); + /* If we're changing to all on or all off then prepare */ + if ((d->dev_power && d->bias_level == SND_SOC_BIAS_STANDBY) || + (!d->dev_power && d->bias_level == SND_SOC_BIAS_ON)) { + ret = snd_soc_dapm_set_bias_level(card, d, + SND_SOC_BIAS_PREPARE); + if (ret != 0) + dev_err(d->dev, + "Failed to prepare bias: %d\n", ret); + } } /* Power down widgets first; try to avoid amplifying pops. */ @@ -1031,29 +1040,36 @@ static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event) /* Now power up. */ dapm_seq_run(dapm, &up_list, event, dapm_up_seq); - /* If we just powered the last thing off drop to standby bias */ - if (dapm->bias_level == SND_SOC_BIAS_PREPARE && !sys_power) { - ret = snd_soc_dapm_set_bias_level(card, dapm, SND_SOC_BIAS_STANDBY); - if (ret != 0) - dev_err(dapm->dev, - "Failed to apply standby bias: %d\n", ret); - } + list_for_each_entry(d, &dapm->card->dapm_list, list) { + /* If we just powered the last thing off drop to standby bias */ + if (d->bias_level == SND_SOC_BIAS_PREPARE && !d->dev_power) { + ret = snd_soc_dapm_set_bias_level(card, d, + SND_SOC_BIAS_STANDBY); + if (ret != 0) + dev_err(d->dev, + "Failed to apply standby bias: %d\n", + ret); + } - /* If we're in standby and can support bias off then do that */ - if (dapm->bias_level == SND_SOC_BIAS_STANDBY && - dapm->idle_bias_off) { - ret = snd_soc_dapm_set_bias_level(card, dapm, SND_SOC_BIAS_OFF); - if (ret != 0) - dev_err(dapm->dev, - "Failed to turn off bias: %d\n", ret); - } + /* If we're in standby and can support bias off then do that */ + if (d->bias_level == SND_SOC_BIAS_STANDBY && + d->idle_bias_off) { + ret = snd_soc_dapm_set_bias_level(card, d, + SND_SOC_BIAS_OFF); + if (ret != 0) + dev_err(d->dev, + "Failed to turn off bias: %d\n", ret); + } - /* If we just powered up then move to active bias */ - if (dapm->bias_level == SND_SOC_BIAS_PREPARE && sys_power) { - ret = snd_soc_dapm_set_bias_level(card, dapm, SND_SOC_BIAS_ON); - if (ret != 0) - dev_err(dapm->dev, - "Failed to apply active bias: %d\n", ret); + /* If we just powered up then move to active bias */ + if (d->bias_level == SND_SOC_BIAS_PREPARE && d->dev_power) { + ret = snd_soc_dapm_set_bias_level(card, d, + SND_SOC_BIAS_ON); + if (ret != 0) + dev_err(d->dev, + "Failed to apply active bias: %d\n", + ret); + } } pop_dbg(dapm->dev, card->pop_time, @@ -2309,6 +2325,7 @@ void snd_soc_dapm_free(struct snd_soc_dapm_context *dapm) { snd_soc_dapm_sys_remove(dapm->dev); dapm_free_widgets(dapm); + list_del(&dapm->list); } EXPORT_SYMBOL_GPL(snd_soc_dapm_free); -- cgit v1.2.3 From 65b7cecc85b9bb7bb8ce74c6a3b280464b00c86c Mon Sep 17 00:00:00 2001 From: "Olaya, Margarita" Date: Tue, 14 Dec 2010 19:18:36 -0600 Subject: ASoC: twl6040: Set default gains to minimun value Updated default values to improve power consumption. Signed-off-by: Jorge Eduardo Candelaria Signed-off-by: Margarita Olaya Cabrera Acked-by: Mark Brown Signed-off-by: Liam Girdwood --- sound/soc/codecs/twl6040.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/sound/soc/codecs/twl6040.c b/sound/soc/codecs/twl6040.c index 9dfe208e6539..b252cf8f0ce1 100644 --- a/sound/soc/codecs/twl6040.c +++ b/sound/soc/codecs/twl6040.c @@ -806,6 +806,15 @@ static int twl6040_set_bias_level(struct snd_soc_codec *codec, /* initialize vdd/vss registers with reg_cache */ twl6040_init_vdd_regs(codec); + + /* Set external boost GPO */ + twl6040_write(codec, TWL6040_REG_GPOCTL, 0x02); + + /* Set initial minimal gain values */ + twl6040_write(codec, TWL6040_REG_HSGAIN, 0xFF); + twl6040_write(codec, TWL6040_REG_EARCTL, 0x1E); + twl6040_write(codec, TWL6040_REG_HFLGAIN, 0x1D); + twl6040_write(codec, TWL6040_REG_HFRGAIN, 0x1D); break; case SND_SOC_BIAS_OFF: if (!priv->codec_powered) -- cgit v1.2.3 From ab60bd0b92ec57c98df08616b7d0664be5551eae Mon Sep 17 00:00:00 2001 From: Arnaud Lacombe Date: Sun, 5 Dec 2010 01:29:25 -0500 Subject: kconfig: add more S_INT and S_HEX consistency checks This patch add more number consistency checkg, trying to catch the following situation: config FOO0 hex default 42 config FOO1 string config BAR0 int default FOO1 config BAR1 hex default FOO1 config FOO2 hex default 42h config FOO3 int default "1bar" Signed-off-by: Arnaud Lacombe Signed-off-by: Michal Marek --- scripts/kconfig/menu.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/scripts/kconfig/menu.c b/scripts/kconfig/menu.c index 7e83aef42c6d..8a8bc9be7831 100644 --- a/scripts/kconfig/menu.c +++ b/scripts/kconfig/menu.c @@ -183,7 +183,7 @@ void menu_add_option(int token, char *arg) } } -static int menu_range_valid_sym(struct symbol *sym, struct symbol *sym2) +static int menu_validate_number(struct symbol *sym, struct symbol *sym2) { return sym2->type == S_INT || sym2->type == S_HEX || (sym2->type == S_UNKNOWN && sym_string_valid(sym, sym2->name)); @@ -201,6 +201,15 @@ static void sym_check_prop(struct symbol *sym) prop_warn(prop, "default for config symbol '%s'" " must be a single symbol", sym->name); + if (prop->expr->type != E_SYMBOL) + break; + sym2 = prop_get_symbol(prop); + if (sym->type == S_HEX || sym->type == S_INT) { + if (!menu_validate_number(sym, sym2)) + prop_warn(prop, + "'%s': number is invalid", + sym->name); + } break; case P_SELECT: sym2 = prop_get_symbol(prop); @@ -220,8 +229,8 @@ static void sym_check_prop(struct symbol *sym) if (sym->type != S_INT && sym->type != S_HEX) prop_warn(prop, "range is only allowed " "for int or hex symbols"); - if (!menu_range_valid_sym(sym, prop->expr->left.sym) || - !menu_range_valid_sym(sym, prop->expr->right.sym)) + if (!menu_validate_number(sym, prop->expr->left.sym) || + !menu_validate_number(sym, prop->expr->right.sym)) prop_warn(prop, "range is invalid"); break; default: -- cgit v1.2.3 From c45aadabb961501b3e64bc92d0bf12fdce26d37d Mon Sep 17 00:00:00 2001 From: Francisco Jerez Date: Thu, 16 Dec 2010 10:30:35 +1000 Subject: drm/nv50: fix a couple of vm init issues Fixes overwriting the first page table entry when testing that the PRAMIN BAR can be correctly read/written, and adds an additional bar flush after poking the BAR3 control regs. Signed-off-by: Francisco Jerez Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nv50_instmem.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nv50_instmem.c b/drivers/gpu/drm/nouveau/nv50_instmem.c index 38f30270cb9f..adac4da98f7e 100644 --- a/drivers/gpu/drm/nouveau/nv50_instmem.c +++ b/drivers/gpu/drm/nouveau/nv50_instmem.c @@ -182,16 +182,17 @@ nv50_instmem_init(struct drm_device *dev) nv_wr32(dev, 0x001704, 0x40000000 | (chan->ramin->vinst >> 12)); nv_wr32(dev, 0x00170c, 0x80000000 | (priv->bar3_dmaobj->cinst >> 4)); - tmp = nv_ri32(dev, 0); - nv_wi32(dev, 0, ~tmp); - if (nv_ri32(dev, 0) != ~tmp) { + dev_priv->engine.instmem.flush(dev); + dev_priv->ramin_available = true; + + tmp = nv_ro32(chan->ramin, 0); + nv_wo32(chan->ramin, 0, ~tmp); + if (nv_ro32(chan->ramin, 0) != ~tmp) { NV_ERROR(dev, "PRAMIN readback failed\n"); ret = -EIO; goto error; } - nv_wi32(dev, 0, tmp); - - dev_priv->ramin_available = true; + nv_wo32(chan->ramin, 0, tmp); /* BAR1 */ ret = nouveau_vm_new(dev, BAR1_VM_BASE, BAR1_VM_SIZE, BAR1_VM_BASE, -- cgit v1.2.3 From 4722d194e648fb5755faecee895b96b26f9732f3 Mon Sep 17 00:00:00 2001 From: Andres Salomon Date: Fri, 12 Nov 2010 05:45:26 +0000 Subject: x86, of: Define irq functions to allow drivers/of/* to build on x86 - Define a stub irq_create_of_mapping for x86 as a stop-gap solution until drivers/of/irq is further along. - Define irq_dispose_mapping for x86 to appease of_i2c.c These are needed to allow stuff in drivers/of/ to build on x86. This stuff will eventually get replaced; quoting Grant, "The long term plan is to have the drivers/of/ code handling the mapping intelligently like powerpc currently does." But for now, just provide these functions. Signed-off-by: Andres Salomon LKML-Reference: <20101111214526.5de7121b@queued.net> Signed-off-by: H. Peter Anvin --- arch/x86/include/asm/irq.h | 3 +++ arch/x86/kernel/irq.c | 10 ++++++++++ 2 files changed, 13 insertions(+) diff --git a/arch/x86/include/asm/irq.h b/arch/x86/include/asm/irq.h index 13b0ebaa512f..8d2c6717a5c3 100644 --- a/arch/x86/include/asm/irq.h +++ b/arch/x86/include/asm/irq.h @@ -10,6 +10,9 @@ #include #include +/* Even though we don't support this, supply it to appease OF */ +static inline void irq_dispose_mapping(unsigned int virq) { } + static inline int irq_canonicalize(int irq) { return ((irq == 2) ? 9 : irq); diff --git a/arch/x86/kernel/irq.c b/arch/x86/kernel/irq.c index 83ec0175f986..d833d1b962a5 100644 --- a/arch/x86/kernel/irq.c +++ b/arch/x86/kernel/irq.c @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -275,6 +276,15 @@ void smp_x86_platform_ipi(struct pt_regs *regs) EXPORT_SYMBOL_GPL(vector_used_by_percpu_irq); +#ifdef CONFIG_OF +unsigned int irq_create_of_mapping(struct device_node *controller, + const u32 *intspec, unsigned int intsize) +{ + return intspec[0]; +} +EXPORT_SYMBOL_GPL(irq_create_of_mapping); +#endif + #ifdef CONFIG_HOTPLUG_CPU /* A cpu has been removed from cpu_online_mask. Reset irq affinities. */ void fixup_irqs(void) -- cgit v1.2.3 From c10d1e260f7cb6766dc76b4e36ed8f4be53f195a Mon Sep 17 00:00:00 2001 From: Andres Salomon Date: Wed, 17 Nov 2010 06:09:52 +0000 Subject: x86, olpc: Add OLPC device-tree support Make use of PROC_DEVICETREE to export the tree, and sparc's PROMTREE code to call into OLPC's Open Firmware to build the tree. v5: fix buglet with root node check (introduced in v4) v4: address some minor style issues pointed out by Grant, and explicitly cast negative phandle checks to s32. v3: rename olpc_prom to olpc_dt - rework Kconfig entries - drop devtree build hook from proc, instead adding a call to x86's paging_init (similarly to how sparc64 does it) - switch allocation from using slab to alloc_bootmem. this allows the DT to be built earlier during boot (during setup_arch); the downside is that there are some 1200 bootmem reservations that are done during boot. Not ideal.. - add a helper olpc_ofw_is_installed function to test for the existence and successful detection of OLPC's OFW. Signed-off-by: Andres Salomon LKML-Reference: <20101116220952.26526a80@queued.net> Signed-off-by: H. Peter Anvin --- arch/x86/Kconfig | 6 ++ arch/x86/include/asm/olpc_ofw.h | 9 +++ arch/x86/include/asm/prom.h | 1 + arch/x86/mm/init_32.c | 2 + arch/x86/platform/olpc/Makefile | 1 + arch/x86/platform/olpc/olpc_dt.c | 165 ++++++++++++++++++++++++++++++++++++++ arch/x86/platform/olpc/olpc_ofw.c | 5 ++ 7 files changed, 189 insertions(+) create mode 100644 arch/x86/include/asm/prom.h create mode 100644 arch/x86/platform/olpc/olpc_dt.c diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index e330da21b84f..ef34031a8339 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -2049,11 +2049,17 @@ config OLPC_OPENFIRMWARE bool "Support for OLPC's Open Firmware" depends on !X86_64 && !X86_PAE default n + select OF help This option adds support for the implementation of Open Firmware that is used on the OLPC XO-1 Children's Machine. If unsure, say N here. +config OLPC_OPENFIRMWARE_DT + bool + default y if OLPC_OPENFIRMWARE && PROC_DEVICETREE + select OF_PROMTREE + endif # X86_32 config AMD_NB diff --git a/arch/x86/include/asm/olpc_ofw.h b/arch/x86/include/asm/olpc_ofw.h index 2a8478140bb3..641988efe063 100644 --- a/arch/x86/include/asm/olpc_ofw.h +++ b/arch/x86/include/asm/olpc_ofw.h @@ -8,6 +8,8 @@ #ifdef CONFIG_OLPC_OPENFIRMWARE +extern bool olpc_ofw_is_installed(void); + /* run an OFW command by calling into the firmware */ #define olpc_ofw(name, args, res) \ __olpc_ofw((name), ARRAY_SIZE(args), args, ARRAY_SIZE(res), res) @@ -26,10 +28,17 @@ extern bool olpc_ofw_present(void); #else /* !CONFIG_OLPC_OPENFIRMWARE */ +static inline bool olpc_ofw_is_installed(void) { return false; } static inline void olpc_ofw_detect(void) { } static inline void setup_olpc_ofw_pgd(void) { } static inline bool olpc_ofw_present(void) { return false; } #endif /* !CONFIG_OLPC_OPENFIRMWARE */ +#ifdef CONFIG_OLPC_OPENFIRMWARE_DT +extern void olpc_dt_build_devicetree(void); +#else +static inline void olpc_dt_build_devicetree(void) { } +#endif /* CONFIG_OLPC_OPENFIRMWARE_DT */ + #endif /* _ASM_X86_OLPC_OFW_H */ diff --git a/arch/x86/include/asm/prom.h b/arch/x86/include/asm/prom.h new file mode 100644 index 000000000000..b4ec95f07518 --- /dev/null +++ b/arch/x86/include/asm/prom.h @@ -0,0 +1 @@ +/* dummy prom.h; here to make linux/of.h's #includes happy */ diff --git a/arch/x86/mm/init_32.c b/arch/x86/mm/init_32.c index 0e969f9f401b..8c852e4af452 100644 --- a/arch/x86/mm/init_32.c +++ b/arch/x86/mm/init_32.c @@ -45,6 +45,7 @@ #include #include #include +#include #include #include #include @@ -715,6 +716,7 @@ void __init paging_init(void) /* * NOTE: at this point the bootmem allocator is fully available. */ + olpc_dt_build_devicetree(); sparse_init(); zone_sizes_init(); } diff --git a/arch/x86/platform/olpc/Makefile b/arch/x86/platform/olpc/Makefile index c31b8fcb5a86..e797428b163b 100644 --- a/arch/x86/platform/olpc/Makefile +++ b/arch/x86/platform/olpc/Makefile @@ -1,3 +1,4 @@ obj-$(CONFIG_OLPC) += olpc.o obj-$(CONFIG_OLPC_XO1) += olpc-xo1.o obj-$(CONFIG_OLPC_OPENFIRMWARE) += olpc_ofw.o +obj-$(CONFIG_OLPC_OPENFIRMWARE_DT) += olpc_dt.o diff --git a/arch/x86/platform/olpc/olpc_dt.c b/arch/x86/platform/olpc/olpc_dt.c new file mode 100644 index 000000000000..70546975a920 --- /dev/null +++ b/arch/x86/platform/olpc/olpc_dt.c @@ -0,0 +1,165 @@ +/* + * OLPC-specific OFW device tree support code. + * + * Paul Mackerras August 1996. + * Copyright (C) 1996-2005 Paul Mackerras. + * + * Adapted for 64bit PowerPC by Dave Engebretsen and Peter Bergner. + * {engebret|bergner}@us.ibm.com + * + * Adapted for sparc by David S. Miller davem@davemloft.net + * Adapted for x86/OLPC by Andres Salomon + * + * 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. + */ + +#include +#include +#include +#include +#include + +static phandle __init olpc_dt_getsibling(phandle node) +{ + const void *args[] = { (void *)node }; + void *res[] = { &node }; + + if ((s32)node == -1) + return 0; + + if (olpc_ofw("peer", args, res) || (s32)node == -1) + return 0; + + return node; +} + +static phandle __init olpc_dt_getchild(phandle node) +{ + const void *args[] = { (void *)node }; + void *res[] = { &node }; + + if ((s32)node == -1) + return 0; + + if (olpc_ofw("child", args, res) || (s32)node == -1) { + pr_err("PROM: %s: fetching child failed!\n", __func__); + return 0; + } + + return node; +} + +static int __init olpc_dt_getproplen(phandle node, const char *prop) +{ + const void *args[] = { (void *)node, prop }; + int len; + void *res[] = { &len }; + + if ((s32)node == -1) + return -1; + + if (olpc_ofw("getproplen", args, res)) { + pr_err("PROM: %s: getproplen failed!\n", __func__); + return -1; + } + + return len; +} + +static int __init olpc_dt_getproperty(phandle node, const char *prop, + char *buf, int bufsize) +{ + int plen; + + plen = olpc_dt_getproplen(node, prop); + if (plen > bufsize || plen < 1) { + return -1; + } else { + const void *args[] = { (void *)node, prop, buf, (void *)plen }; + void *res[] = { &plen }; + + if (olpc_ofw("getprop", args, res)) { + pr_err("PROM: %s: getprop failed!\n", __func__); + return -1; + } + } + + return plen; +} + +static int __init olpc_dt_nextprop(phandle node, char *prev, char *buf) +{ + const void *args[] = { (void *)node, prev, buf }; + int success; + void *res[] = { &success }; + + buf[0] = '\0'; + + if ((s32)node == -1) + return -1; + + if (olpc_ofw("nextprop", args, res) || success != 1) + return -1; + + return 0; +} + +static int __init olpc_dt_pkg2path(phandle node, char *buf, + const int buflen, int *len) +{ + const void *args[] = { (void *)node, buf, (void *)buflen }; + void *res[] = { len }; + + if ((s32)node == -1) + return -1; + + if (olpc_ofw("package-to-path", args, res) || *len < 1) + return -1; + + return 0; +} + +static unsigned int prom_early_allocated __initdata; + +void * __init prom_early_alloc(unsigned long size) +{ + void *res; + + res = alloc_bootmem(size); + if (res) + memset(res, 0, size); + + prom_early_allocated += size; + + return res; +} + +static struct of_pdt_ops prom_olpc_ops __initdata = { + .nextprop = olpc_dt_nextprop, + .getproplen = olpc_dt_getproplen, + .getproperty = olpc_dt_getproperty, + .getchild = olpc_dt_getchild, + .getsibling = olpc_dt_getsibling, + .pkg2path = olpc_dt_pkg2path, +}; + +void __init olpc_dt_build_devicetree(void) +{ + phandle root; + + if (!olpc_ofw_is_installed()) + return; + + root = olpc_dt_getsibling(0); + if (!root) { + pr_err("PROM: unable to get root node from OFW!\n"); + return; + } + of_pdt_build_devicetree(root, &prom_olpc_ops); + + pr_info("PROM DT: Built device tree with %u bytes of memory.\n", + prom_early_allocated); +} diff --git a/arch/x86/platform/olpc/olpc_ofw.c b/arch/x86/platform/olpc/olpc_ofw.c index 787320464379..e7604f62870d 100644 --- a/arch/x86/platform/olpc/olpc_ofw.c +++ b/arch/x86/platform/olpc/olpc_ofw.c @@ -110,3 +110,8 @@ void __init olpc_ofw_detect(void) (unsigned long)olpc_ofw_cif, (-start) >> 20); reserve_top_address(-start); } + +bool __init olpc_ofw_is_installed(void) +{ + return olpc_ofw_cif != NULL; +} -- cgit v1.2.3 From b5318d302f8a20eacbbfc01b0ee35b108085a363 Mon Sep 17 00:00:00 2001 From: Andres Salomon Date: Mon, 29 Nov 2010 23:39:51 +0000 Subject: x86, olpc: Speed up device tree creation during boot Calling alloc_bootmem() for tiny chunks of memory over and over is really slow; on an XO-1, it caused the time between when the kernel started booting and when the display came alive (post-lxfb probe) to increase to 44s. This patch optimizes the prom_early_alloc function by calling alloc_bootmem for 4k-sized blocks of memory, and handing out chunks of that to callers. With this patch, the time between kernel load and display initialization decreased to 23s. If there's a better way to do this early in the boot process, please let me know. (Note: increasing the chunk size to 16k didn't noticably affect boot time, and wasted 9k.) v4: clarify comment, requested by hpa v3: fix wasted memory buglet found by Milton Miller, and style fix. v2: reorder prom_early_alloc as suggested by Grant. Signed-off-by: Andres Salomon LKML-Reference: <20101129153951.74202a84@queued.net> Signed-off-by: H. Peter Anvin --- arch/x86/platform/olpc/olpc_dt.c | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/arch/x86/platform/olpc/olpc_dt.c b/arch/x86/platform/olpc/olpc_dt.c index 70546975a920..dab874647530 100644 --- a/arch/x86/platform/olpc/olpc_dt.c +++ b/arch/x86/platform/olpc/olpc_dt.c @@ -126,14 +126,32 @@ static unsigned int prom_early_allocated __initdata; void * __init prom_early_alloc(unsigned long size) { + static u8 *mem; + static size_t free_mem; void *res; - res = alloc_bootmem(size); - if (res) - memset(res, 0, size); - - prom_early_allocated += size; + if (free_mem < size) { + const size_t chunk_size = max(PAGE_SIZE, size); + + /* + * To mimimize the number of allocations, grab at least + * PAGE_SIZE of memory (that's an arbitrary choice that's + * fast enough on the platforms we care about while minimizing + * wasted bootmem) and hand off chunks of it to callers. + */ + res = alloc_bootmem(chunk_size); + if (!res) + return NULL; + prom_early_allocated += chunk_size; + memset(res, 0, chunk_size); + free_mem = chunk_size; + mem = res; + } + /* allocate from the local cache */ + free_mem -= size; + res = mem; + mem += size; return res; } -- cgit v1.2.3 From fd8c37eccdda21153298997417144b38b1623196 Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Wed, 15 Dec 2010 20:26:48 -0500 Subject: ext4: Simplify the usage of clear_opt() and set_opt() macros Change clear_opt() and set_opt() to take a superblock pointer instead of a pointer to EXT4_SB(sb)->s_mount_opt. This makes it easier for us to support a second mount option field. Signed-off-by: "Theodore Ts'o" --- fs/ext4/ext4.h | 6 +- fs/ext4/mballoc.c | 2 +- fs/ext4/super.c | 162 +++++++++++++++++++++++++++--------------------------- 3 files changed, 86 insertions(+), 84 deletions(-) diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index 94ce3d7a1c4b..2d93620d092e 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h @@ -917,8 +917,10 @@ struct ext4_inode_info { #define EXT4_MOUNT_DISCARD 0x40000000 /* Issue DISCARD requests */ #define EXT4_MOUNT_INIT_INODE_TABLE 0x80000000 /* Initialize uninitialized itables */ -#define clear_opt(o, opt) o &= ~EXT4_MOUNT_##opt -#define set_opt(o, opt) o |= EXT4_MOUNT_##opt +#define clear_opt(sb, opt) EXT4_SB(sb)->s_mount_opt &= \ + ~EXT4_MOUNT_##opt +#define set_opt(sb, opt) EXT4_SB(sb)->s_mount_opt |= \ + EXT4_MOUNT_##opt #define test_opt(sb, opt) (EXT4_SB(sb)->s_mount_opt & \ EXT4_MOUNT_##opt) diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index 5b4d4e3a4d58..731b6f738a03 100644 --- a/fs/ext4/mballoc.c +++ b/fs/ext4/mballoc.c @@ -2617,7 +2617,7 @@ static inline int ext4_issue_discard(struct super_block *sb, ret = sb_issue_discard(sb, discard_block, count, GFP_NOFS, 0); if (ret == -EOPNOTSUPP) { ext4_warning(sb, "discard not supported, disabling"); - clear_opt(EXT4_SB(sb)->s_mount_opt, DISCARD); + clear_opt(sb, DISCARD); } return ret; } diff --git a/fs/ext4/super.c b/fs/ext4/super.c index fb15c9c0be74..cf7d9131d785 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -1386,7 +1386,7 @@ static int set_qf_name(struct super_block *sb, int qtype, substring_t *args) sbi->s_qf_names[qtype] = NULL; return 0; } - set_opt(sbi->s_mount_opt, QUOTA); + set_opt(sb, QUOTA); return 1; } @@ -1441,21 +1441,21 @@ static int parse_options(char *options, struct super_block *sb, switch (token) { case Opt_bsd_df: ext4_msg(sb, KERN_WARNING, deprecated_msg, p, "2.6.38"); - clear_opt(sbi->s_mount_opt, MINIX_DF); + clear_opt(sb, MINIX_DF); break; case Opt_minix_df: ext4_msg(sb, KERN_WARNING, deprecated_msg, p, "2.6.38"); - set_opt(sbi->s_mount_opt, MINIX_DF); + set_opt(sb, MINIX_DF); break; case Opt_grpid: ext4_msg(sb, KERN_WARNING, deprecated_msg, p, "2.6.38"); - set_opt(sbi->s_mount_opt, GRPID); + set_opt(sb, GRPID); break; case Opt_nogrpid: ext4_msg(sb, KERN_WARNING, deprecated_msg, p, "2.6.38"); - clear_opt(sbi->s_mount_opt, GRPID); + clear_opt(sb, GRPID); break; case Opt_resuid: @@ -1473,38 +1473,38 @@ static int parse_options(char *options, struct super_block *sb, /* *sb_block = match_int(&args[0]); */ break; case Opt_err_panic: - clear_opt(sbi->s_mount_opt, ERRORS_CONT); - clear_opt(sbi->s_mount_opt, ERRORS_RO); - set_opt(sbi->s_mount_opt, ERRORS_PANIC); + clear_opt(sb, ERRORS_CONT); + clear_opt(sb, ERRORS_RO); + set_opt(sb, ERRORS_PANIC); break; case Opt_err_ro: - clear_opt(sbi->s_mount_opt, ERRORS_CONT); - clear_opt(sbi->s_mount_opt, ERRORS_PANIC); - set_opt(sbi->s_mount_opt, ERRORS_RO); + clear_opt(sb, ERRORS_CONT); + clear_opt(sb, ERRORS_PANIC); + set_opt(sb, ERRORS_RO); break; case Opt_err_cont: - clear_opt(sbi->s_mount_opt, ERRORS_RO); - clear_opt(sbi->s_mount_opt, ERRORS_PANIC); - set_opt(sbi->s_mount_opt, ERRORS_CONT); + clear_opt(sb, ERRORS_RO); + clear_opt(sb, ERRORS_PANIC); + set_opt(sb, ERRORS_CONT); break; case Opt_nouid32: - set_opt(sbi->s_mount_opt, NO_UID32); + set_opt(sb, NO_UID32); break; case Opt_debug: - set_opt(sbi->s_mount_opt, DEBUG); + set_opt(sb, DEBUG); break; case Opt_oldalloc: - set_opt(sbi->s_mount_opt, OLDALLOC); + set_opt(sb, OLDALLOC); break; case Opt_orlov: - clear_opt(sbi->s_mount_opt, OLDALLOC); + clear_opt(sb, OLDALLOC); break; #ifdef CONFIG_EXT4_FS_XATTR case Opt_user_xattr: - set_opt(sbi->s_mount_opt, XATTR_USER); + set_opt(sb, XATTR_USER); break; case Opt_nouser_xattr: - clear_opt(sbi->s_mount_opt, XATTR_USER); + clear_opt(sb, XATTR_USER); break; #else case Opt_user_xattr: @@ -1514,10 +1514,10 @@ static int parse_options(char *options, struct super_block *sb, #endif #ifdef CONFIG_EXT4_FS_POSIX_ACL case Opt_acl: - set_opt(sbi->s_mount_opt, POSIX_ACL); + set_opt(sb, POSIX_ACL); break; case Opt_noacl: - clear_opt(sbi->s_mount_opt, POSIX_ACL); + clear_opt(sb, POSIX_ACL); break; #else case Opt_acl: @@ -1536,7 +1536,7 @@ static int parse_options(char *options, struct super_block *sb, "Cannot specify journal on remount"); return 0; } - set_opt(sbi->s_mount_opt, UPDATE_JOURNAL); + set_opt(sb, UPDATE_JOURNAL); break; case Opt_journal_dev: if (is_remount) { @@ -1549,14 +1549,14 @@ static int parse_options(char *options, struct super_block *sb, *journal_devnum = option; break; case Opt_journal_checksum: - set_opt(sbi->s_mount_opt, JOURNAL_CHECKSUM); + set_opt(sb, JOURNAL_CHECKSUM); break; case Opt_journal_async_commit: - set_opt(sbi->s_mount_opt, JOURNAL_ASYNC_COMMIT); - set_opt(sbi->s_mount_opt, JOURNAL_CHECKSUM); + set_opt(sb, JOURNAL_ASYNC_COMMIT); + set_opt(sb, JOURNAL_CHECKSUM); break; case Opt_noload: - set_opt(sbi->s_mount_opt, NOLOAD); + set_opt(sb, NOLOAD); break; case Opt_commit: if (match_int(&args[0], &option)) @@ -1599,15 +1599,15 @@ static int parse_options(char *options, struct super_block *sb, return 0; } } else { - clear_opt(sbi->s_mount_opt, DATA_FLAGS); + clear_opt(sb, DATA_FLAGS); sbi->s_mount_opt |= data_opt; } break; case Opt_data_err_abort: - set_opt(sbi->s_mount_opt, DATA_ERR_ABORT); + set_opt(sb, DATA_ERR_ABORT); break; case Opt_data_err_ignore: - clear_opt(sbi->s_mount_opt, DATA_ERR_ABORT); + clear_opt(sb, DATA_ERR_ABORT); break; #ifdef CONFIG_QUOTA case Opt_usrjquota: @@ -1647,12 +1647,12 @@ set_qf_format: break; case Opt_quota: case Opt_usrquota: - set_opt(sbi->s_mount_opt, QUOTA); - set_opt(sbi->s_mount_opt, USRQUOTA); + set_opt(sb, QUOTA); + set_opt(sb, USRQUOTA); break; case Opt_grpquota: - set_opt(sbi->s_mount_opt, QUOTA); - set_opt(sbi->s_mount_opt, GRPQUOTA); + set_opt(sb, QUOTA); + set_opt(sb, GRPQUOTA); break; case Opt_noquota: if (sb_any_quota_loaded(sb)) { @@ -1660,9 +1660,9 @@ set_qf_format: "options when quota turned on"); return 0; } - clear_opt(sbi->s_mount_opt, QUOTA); - clear_opt(sbi->s_mount_opt, USRQUOTA); - clear_opt(sbi->s_mount_opt, GRPQUOTA); + clear_opt(sb, QUOTA); + clear_opt(sb, USRQUOTA); + clear_opt(sb, GRPQUOTA); break; #else case Opt_quota: @@ -1688,7 +1688,7 @@ set_qf_format: sbi->s_mount_flags |= EXT4_MF_FS_ABORTED; break; case Opt_nobarrier: - clear_opt(sbi->s_mount_opt, BARRIER); + clear_opt(sb, BARRIER); break; case Opt_barrier: if (args[0].from) { @@ -1697,9 +1697,9 @@ set_qf_format: } else option = 1; /* No argument, default to 1 */ if (option) - set_opt(sbi->s_mount_opt, BARRIER); + set_opt(sb, BARRIER); else - clear_opt(sbi->s_mount_opt, BARRIER); + clear_opt(sb, BARRIER); break; case Opt_ignore: break; @@ -1723,17 +1723,17 @@ set_qf_format: "Ignoring deprecated bh option"); break; case Opt_i_version: - set_opt(sbi->s_mount_opt, I_VERSION); + set_opt(sb, I_VERSION); sb->s_flags |= MS_I_VERSION; break; case Opt_nodelalloc: - clear_opt(sbi->s_mount_opt, DELALLOC); + clear_opt(sb, DELALLOC); break; case Opt_mblk_io_submit: - set_opt(sbi->s_mount_opt, MBLK_IO_SUBMIT); + set_opt(sb, MBLK_IO_SUBMIT); break; case Opt_nomblk_io_submit: - clear_opt(sbi->s_mount_opt, MBLK_IO_SUBMIT); + clear_opt(sb, MBLK_IO_SUBMIT); break; case Opt_stripe: if (match_int(&args[0], &option)) @@ -1743,13 +1743,13 @@ set_qf_format: sbi->s_stripe = option; break; case Opt_delalloc: - set_opt(sbi->s_mount_opt, DELALLOC); + set_opt(sb, DELALLOC); break; case Opt_block_validity: - set_opt(sbi->s_mount_opt, BLOCK_VALIDITY); + set_opt(sb, BLOCK_VALIDITY); break; case Opt_noblock_validity: - clear_opt(sbi->s_mount_opt, BLOCK_VALIDITY); + clear_opt(sb, BLOCK_VALIDITY); break; case Opt_inode_readahead_blks: if (match_int(&args[0], &option)) @@ -1773,7 +1773,7 @@ set_qf_format: option); break; case Opt_noauto_da_alloc: - set_opt(sbi->s_mount_opt,NO_AUTO_DA_ALLOC); + set_opt(sb, NO_AUTO_DA_ALLOC); break; case Opt_auto_da_alloc: if (args[0].from) { @@ -1782,24 +1782,24 @@ set_qf_format: } else option = 1; /* No argument, default to 1 */ if (option) - clear_opt(sbi->s_mount_opt, NO_AUTO_DA_ALLOC); + clear_opt(sb, NO_AUTO_DA_ALLOC); else - set_opt(sbi->s_mount_opt,NO_AUTO_DA_ALLOC); + set_opt(sb,NO_AUTO_DA_ALLOC); break; case Opt_discard: - set_opt(sbi->s_mount_opt, DISCARD); + set_opt(sb, DISCARD); break; case Opt_nodiscard: - clear_opt(sbi->s_mount_opt, DISCARD); + clear_opt(sb, DISCARD); break; case Opt_dioread_nolock: - set_opt(sbi->s_mount_opt, DIOREAD_NOLOCK); + set_opt(sb, DIOREAD_NOLOCK); break; case Opt_dioread_lock: - clear_opt(sbi->s_mount_opt, DIOREAD_NOLOCK); + clear_opt(sb, DIOREAD_NOLOCK); break; case Opt_init_inode_table: - set_opt(sbi->s_mount_opt, INIT_INODE_TABLE); + set_opt(sb, INIT_INODE_TABLE); if (args[0].from) { if (match_int(&args[0], &option)) return 0; @@ -1810,7 +1810,7 @@ set_qf_format: sbi->s_li_wait_mult = option; break; case Opt_noinit_inode_table: - clear_opt(sbi->s_mount_opt, INIT_INODE_TABLE); + clear_opt(sb, INIT_INODE_TABLE); break; default: ext4_msg(sb, KERN_ERR, @@ -1822,10 +1822,10 @@ set_qf_format: #ifdef CONFIG_QUOTA if (sbi->s_qf_names[USRQUOTA] || sbi->s_qf_names[GRPQUOTA]) { if (test_opt(sb, USRQUOTA) && sbi->s_qf_names[USRQUOTA]) - clear_opt(sbi->s_mount_opt, USRQUOTA); + clear_opt(sb, USRQUOTA); if (test_opt(sb, GRPQUOTA) && sbi->s_qf_names[GRPQUOTA]) - clear_opt(sbi->s_mount_opt, GRPQUOTA); + clear_opt(sb, GRPQUOTA); if (test_opt(sb, GRPQUOTA) || test_opt(sb, USRQUOTA)) { ext4_msg(sb, KERN_ERR, "old and new quota " @@ -3071,41 +3071,41 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) /* Set defaults before we parse the mount options */ def_mount_opts = le32_to_cpu(es->s_default_mount_opts); - set_opt(sbi->s_mount_opt, INIT_INODE_TABLE); + set_opt(sb, INIT_INODE_TABLE); if (def_mount_opts & EXT4_DEFM_DEBUG) - set_opt(sbi->s_mount_opt, DEBUG); + set_opt(sb, DEBUG); if (def_mount_opts & EXT4_DEFM_BSDGROUPS) { ext4_msg(sb, KERN_WARNING, deprecated_msg, "bsdgroups", "2.6.38"); - set_opt(sbi->s_mount_opt, GRPID); + set_opt(sb, GRPID); } if (def_mount_opts & EXT4_DEFM_UID16) - set_opt(sbi->s_mount_opt, NO_UID32); + set_opt(sb, NO_UID32); #ifdef CONFIG_EXT4_FS_XATTR if (def_mount_opts & EXT4_DEFM_XATTR_USER) - set_opt(sbi->s_mount_opt, XATTR_USER); + set_opt(sb, XATTR_USER); #endif #ifdef CONFIG_EXT4_FS_POSIX_ACL if (def_mount_opts & EXT4_DEFM_ACL) - set_opt(sbi->s_mount_opt, POSIX_ACL); + set_opt(sb, POSIX_ACL); #endif if ((def_mount_opts & EXT4_DEFM_JMODE) == EXT4_DEFM_JMODE_DATA) - set_opt(sbi->s_mount_opt, JOURNAL_DATA); + set_opt(sb, JOURNAL_DATA); else if ((def_mount_opts & EXT4_DEFM_JMODE) == EXT4_DEFM_JMODE_ORDERED) - set_opt(sbi->s_mount_opt, ORDERED_DATA); + set_opt(sb, ORDERED_DATA); else if ((def_mount_opts & EXT4_DEFM_JMODE) == EXT4_DEFM_JMODE_WBACK) - set_opt(sbi->s_mount_opt, WRITEBACK_DATA); + set_opt(sb, WRITEBACK_DATA); if (le16_to_cpu(sbi->s_es->s_errors) == EXT4_ERRORS_PANIC) - set_opt(sbi->s_mount_opt, ERRORS_PANIC); + set_opt(sb, ERRORS_PANIC); else if (le16_to_cpu(sbi->s_es->s_errors) == EXT4_ERRORS_CONTINUE) - set_opt(sbi->s_mount_opt, ERRORS_CONT); + set_opt(sb, ERRORS_CONT); else - set_opt(sbi->s_mount_opt, ERRORS_RO); + set_opt(sb, ERRORS_RO); if (def_mount_opts & EXT4_DEFM_BLOCK_VALIDITY) - set_opt(sbi->s_mount_opt, BLOCK_VALIDITY); + set_opt(sb, BLOCK_VALIDITY); if (def_mount_opts & EXT4_DEFM_DISCARD) - set_opt(sbi->s_mount_opt, DISCARD); + set_opt(sb, DISCARD); sbi->s_resuid = le16_to_cpu(es->s_def_resuid); sbi->s_resgid = le16_to_cpu(es->s_def_resgid); @@ -3114,7 +3114,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) sbi->s_max_batch_time = EXT4_DEF_MAX_BATCH_TIME; if ((def_mount_opts & EXT4_DEFM_NOBARRIER) == 0) - set_opt(sbi->s_mount_opt, BARRIER); + set_opt(sb, BARRIER); /* * enable delayed allocation by default @@ -3122,7 +3122,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) */ if (!IS_EXT3_SB(sb) && ((def_mount_opts & EXT4_DEFM_NODELALLOC) == 0)) - set_opt(sbi->s_mount_opt, DELALLOC); + set_opt(sb, DELALLOC); if (!parse_options((char *) sbi->s_es->s_mount_opts, sb, &journal_devnum, &journal_ioprio, NULL, 0)) { @@ -3425,8 +3425,8 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) "suppressed and not mounted read-only"); goto failed_mount_wq; } else { - clear_opt(sbi->s_mount_opt, DATA_FLAGS); - set_opt(sbi->s_mount_opt, WRITEBACK_DATA); + clear_opt(sb, DATA_FLAGS); + set_opt(sb, WRITEBACK_DATA); sbi->s_journal = NULL; needs_recovery = 0; goto no_journal; @@ -3464,9 +3464,9 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) */ if (jbd2_journal_check_available_features (sbi->s_journal, 0, 0, JBD2_FEATURE_INCOMPAT_REVOKE)) - set_opt(sbi->s_mount_opt, ORDERED_DATA); + set_opt(sb, ORDERED_DATA); else - set_opt(sbi->s_mount_opt, JOURNAL_DATA); + set_opt(sb, JOURNAL_DATA); break; case EXT4_MOUNT_ORDERED_DATA: @@ -3556,18 +3556,18 @@ no_journal: (test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_JOURNAL_DATA)) { ext4_msg(sb, KERN_WARNING, "Ignoring delalloc option - " "requested data journaling mode"); - clear_opt(sbi->s_mount_opt, DELALLOC); + clear_opt(sb, DELALLOC); } if (test_opt(sb, DIOREAD_NOLOCK)) { if (test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_JOURNAL_DATA) { ext4_msg(sb, KERN_WARNING, "Ignoring dioread_nolock " "option - requested data journaling mode"); - clear_opt(sbi->s_mount_opt, DIOREAD_NOLOCK); + clear_opt(sb, DIOREAD_NOLOCK); } if (sb->s_blocksize < PAGE_SIZE) { ext4_msg(sb, KERN_WARNING, "Ignoring dioread_nolock " "option - block size is too small"); - clear_opt(sbi->s_mount_opt, DIOREAD_NOLOCK); + clear_opt(sb, DIOREAD_NOLOCK); } } -- cgit v1.2.3 From 673c610033a8202c037ecd068c7a235495acda17 Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Wed, 15 Dec 2010 20:28:48 -0500 Subject: ext4: Move struct ext4_mount_options from ext4.h to super.c Move the ext4_mount_options structure definition from ext4.h, since it is only used in super.c. Signed-off-by: "Theodore Ts'o" --- fs/ext4/ext4.h | 16 ---------------- fs/ext4/super.c | 15 +++++++++++++++ 2 files changed, 15 insertions(+), 16 deletions(-) diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index 2d93620d092e..ddae3c435138 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h @@ -561,22 +561,6 @@ struct ext4_new_group_data { #define EXT4_IOC32_SETVERSION_OLD FS_IOC32_SETVERSION #endif - -/* - * Mount options - */ -struct ext4_mount_options { - unsigned long s_mount_opt; - uid_t s_resuid; - gid_t s_resgid; - unsigned long s_commit_interval; - u32 s_min_batch_time, s_max_batch_time; -#ifdef CONFIG_QUOTA - int s_jquota_fmt; - char *s_qf_names[MAXQUOTAS]; -#endif -}; - /* Max physical block we can addres w/o extents */ #define EXT4_MAX_BLOCK_FILE_PHYS 0xFFFFFFFF diff --git a/fs/ext4/super.c b/fs/ext4/super.c index cf7d9131d785..7aa3a790363a 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -4166,6 +4166,21 @@ static int ext4_unfreeze(struct super_block *sb) return 0; } +/* + * Structure to save mount options for ext4_remount's benefit + */ +struct ext4_mount_options { + unsigned long s_mount_opt; + uid_t s_resuid; + gid_t s_resgid; + unsigned long s_commit_interval; + u32 s_min_batch_time, s_max_batch_time; +#ifdef CONFIG_QUOTA + int s_jquota_fmt; + char *s_qf_names[MAXQUOTAS]; +#endif +}; + static int ext4_remount(struct super_block *sb, int *flags, char *data) { struct ext4_super_block *es; -- cgit v1.2.3 From a2595b8aa67011419dae26b47e474f46df902989 Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Wed, 15 Dec 2010 20:30:48 -0500 Subject: ext4: Add second mount options field since the s_mount_opt is full up Signed-off-by: "Theodore Ts'o" --- fs/ext4/ext4.h | 8 ++++++++ fs/ext4/super.c | 7 +++++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index ddae3c435138..17baecbf8cda 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h @@ -908,6 +908,13 @@ struct ext4_inode_info { #define test_opt(sb, opt) (EXT4_SB(sb)->s_mount_opt & \ EXT4_MOUNT_##opt) +#define clear_opt2(sb, opt) EXT4_SB(sb)->s_mount_opt2 &= \ + ~EXT4_MOUNT2_##opt +#define set_opt2(sb, opt) EXT4_SB(sb)->s_mount_opt2 |= \ + EXT4_MOUNT2_##opt +#define test_opt2(sb, opt) (EXT4_SB(sb)->s_mount_opt2 & \ + EXT4_MOUNT2_##opt) + #define ext4_set_bit ext2_set_bit #define ext4_set_bit_atomic ext2_set_bit_atomic #define ext4_clear_bit ext2_clear_bit @@ -1073,6 +1080,7 @@ struct ext4_sb_info { struct ext4_super_block *s_es; /* Pointer to the super block in the buffer */ struct buffer_head **s_group_desc; unsigned int s_mount_opt; + unsigned int s_mount_opt2; unsigned int s_mount_flags; ext4_fsblk_t s_sb_block; uid_t s_resuid; diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 7aa3a790363a..072ff973ff2b 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -1895,12 +1895,12 @@ static int ext4_setup_super(struct super_block *sb, struct ext4_super_block *es, ext4_commit_super(sb, 1); if (test_opt(sb, DEBUG)) printk(KERN_INFO "[EXT4 FS bs=%lu, gc=%u, " - "bpg=%lu, ipg=%lu, mo=%04x]\n", + "bpg=%lu, ipg=%lu, mo=%04x, mo2=%04x]\n", sb->s_blocksize, sbi->s_groups_count, EXT4_BLOCKS_PER_GROUP(sb), EXT4_INODES_PER_GROUP(sb), - sbi->s_mount_opt); + sbi->s_mount_opt, sbi->s_mount_opt2); return res; } @@ -4171,6 +4171,7 @@ static int ext4_unfreeze(struct super_block *sb) */ struct ext4_mount_options { unsigned long s_mount_opt; + unsigned long s_mount_opt2; uid_t s_resuid; gid_t s_resgid; unsigned long s_commit_interval; @@ -4201,6 +4202,7 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data) lock_super(sb); old_sb_flags = sb->s_flags; old_opts.s_mount_opt = sbi->s_mount_opt; + old_opts.s_mount_opt2 = sbi->s_mount_opt2; old_opts.s_resuid = sbi->s_resuid; old_opts.s_resgid = sbi->s_resgid; old_opts.s_commit_interval = sbi->s_commit_interval; @@ -4354,6 +4356,7 @@ static int ext4_remount(struct super_block *sb, int *flags, char *data) restore_opts: sb->s_flags = old_sb_flags; sbi->s_mount_opt = old_opts.s_mount_opt; + sbi->s_mount_opt2 = old_opts.s_mount_opt2; sbi->s_resuid = old_opts.s_resuid; sbi->s_resgid = old_opts.s_resgid; sbi->s_commit_interval = old_opts.s_commit_interval; -- cgit v1.2.3 From 99ee7fac189893c90145a22b86bbcfdc98f69a9c Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Tue, 23 Nov 2010 11:47:49 +1000 Subject: drm/radeon: add initial tracepoint support. this adds a bo create, and fence seq tracking tracepoints. This is just an initial set to play around with, we should investigate what others we need would be useful. Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/Makefile | 5 +- drivers/gpu/drm/radeon/radeon_fence.c | 4 ++ drivers/gpu/drm/radeon/radeon_object.c | 2 + drivers/gpu/drm/radeon/radeon_trace.h | 82 ++++++++++++++++++++++++++++ drivers/gpu/drm/radeon/radeon_trace_points.c | 9 +++ 5 files changed, 101 insertions(+), 1 deletion(-) create mode 100644 drivers/gpu/drm/radeon/radeon_trace.h create mode 100644 drivers/gpu/drm/radeon/radeon_trace_points.c diff --git a/drivers/gpu/drm/radeon/Makefile b/drivers/gpu/drm/radeon/Makefile index 6cae4f2028d2..e97e6f842699 100644 --- a/drivers/gpu/drm/radeon/Makefile +++ b/drivers/gpu/drm/radeon/Makefile @@ -65,10 +65,13 @@ radeon-y += radeon_device.o radeon_asic.o radeon_kms.o \ rs400.o rs600.o rs690.o rv515.o r520.o r600.o rv770.o radeon_test.o \ r200.o radeon_legacy_tv.o r600_cs.o r600_blit.o r600_blit_shaders.o \ r600_blit_kms.o radeon_pm.o atombios_dp.o r600_audio.o r600_hdmi.o \ - evergreen.o evergreen_cs.o evergreen_blit_shaders.o evergreen_blit_kms.o + evergreen.o evergreen_cs.o evergreen_blit_shaders.o evergreen_blit_kms.o \ + radeon_trace_points.o radeon-$(CONFIG_COMPAT) += radeon_ioc32.o radeon-$(CONFIG_VGA_SWITCHEROO) += radeon_atpx_handler.o radeon-$(CONFIG_ACPI) += radeon_acpi.o obj-$(CONFIG_DRM_RADEON)+= radeon.o + +CFLAGS_radeon_trace_points.o := -I$(src) \ No newline at end of file diff --git a/drivers/gpu/drm/radeon/radeon_fence.c b/drivers/gpu/drm/radeon/radeon_fence.c index daacb281dfaf..171b0b2e3a64 100644 --- a/drivers/gpu/drm/radeon/radeon_fence.c +++ b/drivers/gpu/drm/radeon/radeon_fence.c @@ -38,6 +38,7 @@ #include "drm.h" #include "radeon_reg.h" #include "radeon.h" +#include "radeon_trace.h" int radeon_fence_emit(struct radeon_device *rdev, struct radeon_fence *fence) { @@ -57,6 +58,7 @@ int radeon_fence_emit(struct radeon_device *rdev, struct radeon_fence *fence) } else radeon_fence_ring_emit(rdev, fence); + trace_radeon_fence_emit(rdev->ddev, fence->seq); fence->emited = true; list_del(&fence->list); list_add_tail(&fence->list, &rdev->fence_drv.emited); @@ -213,6 +215,7 @@ int radeon_fence_wait(struct radeon_fence *fence, bool intr) retry: /* save current sequence used to check for GPU lockup */ seq = rdev->fence_drv.last_seq; + trace_radeon_fence_wait_begin(rdev->ddev, seq); if (intr) { radeon_irq_kms_sw_irq_get(rdev); r = wait_event_interruptible_timeout(rdev->fence_drv.queue, @@ -227,6 +230,7 @@ retry: radeon_fence_signaled(fence), timeout); radeon_irq_kms_sw_irq_put(rdev); } + trace_radeon_fence_wait_end(rdev->ddev, seq); if (unlikely(!radeon_fence_signaled(fence))) { /* we were interrupted for some reason and fence isn't * isn't signaled yet, resume wait diff --git a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/radeon/radeon_object.c index a8594d289bcf..8bdf0ba2983a 100644 --- a/drivers/gpu/drm/radeon/radeon_object.c +++ b/drivers/gpu/drm/radeon/radeon_object.c @@ -34,6 +34,7 @@ #include #include "radeon_drm.h" #include "radeon.h" +#include "radeon_trace.h" int radeon_ttm_init(struct radeon_device *rdev); @@ -137,6 +138,7 @@ retry: list_add_tail(&bo->list, &rdev->gem.objects); mutex_unlock(&bo->rdev->gem.mutex); } + trace_radeon_bo_create(bo); return 0; } diff --git a/drivers/gpu/drm/radeon/radeon_trace.h b/drivers/gpu/drm/radeon/radeon_trace.h new file mode 100644 index 000000000000..eafd8160a155 --- /dev/null +++ b/drivers/gpu/drm/radeon/radeon_trace.h @@ -0,0 +1,82 @@ +#if !defined(_RADEON_TRACE_H) || defined(TRACE_HEADER_MULTI_READ) +#define _RADEON_TRACE_H_ + +#include +#include +#include + +#include + +#undef TRACE_SYSTEM +#define TRACE_SYSTEM radeon +#define TRACE_SYSTEM_STRING __stringify(TRACE_SYSTEM) +#define TRACE_INCLUDE_FILE radeon_trace + +TRACE_EVENT(radeon_bo_create, + TP_PROTO(struct radeon_bo *bo), + TP_ARGS(bo), + TP_STRUCT__entry( + __field(struct radeon_bo *, bo) + __field(u32, pages) + ), + + TP_fast_assign( + __entry->bo = bo; + __entry->pages = bo->tbo.num_pages; + ), + TP_printk("bo=%p, pages=%u", __entry->bo, __entry->pages) +); + +DECLARE_EVENT_CLASS(radeon_fence_request, + + TP_PROTO(struct drm_device *dev, u32 seqno), + + TP_ARGS(dev, seqno), + + TP_STRUCT__entry( + __field(u32, dev) + __field(u32, seqno) + ), + + TP_fast_assign( + __entry->dev = dev->primary->index; + __entry->seqno = seqno; + ), + + TP_printk("dev=%u, seqno=%u", __entry->dev, __entry->seqno) +); + +DEFINE_EVENT(radeon_fence_request, radeon_fence_emit, + + TP_PROTO(struct drm_device *dev, u32 seqno), + + TP_ARGS(dev, seqno) +); + +DEFINE_EVENT(radeon_fence_request, radeon_fence_retire, + + TP_PROTO(struct drm_device *dev, u32 seqno), + + TP_ARGS(dev, seqno) +); + +DEFINE_EVENT(radeon_fence_request, radeon_fence_wait_begin, + + TP_PROTO(struct drm_device *dev, u32 seqno), + + TP_ARGS(dev, seqno) +); + +DEFINE_EVENT(radeon_fence_request, radeon_fence_wait_end, + + TP_PROTO(struct drm_device *dev, u32 seqno), + + TP_ARGS(dev, seqno) +); + +#endif + +/* This part must be outside protection */ +#undef TRACE_INCLUDE_PATH +#define TRACE_INCLUDE_PATH . +#include diff --git a/drivers/gpu/drm/radeon/radeon_trace_points.c b/drivers/gpu/drm/radeon/radeon_trace_points.c new file mode 100644 index 000000000000..8175993df84d --- /dev/null +++ b/drivers/gpu/drm/radeon/radeon_trace_points.c @@ -0,0 +1,9 @@ +/* Copyright Red Hat Inc 2010. + * Author : Dave Airlie + */ +#include +#include "radeon_drm.h" +#include "radeon.h" + +#define CREATE_TRACE_POINTS +#include "radeon_trace.h" -- cgit v1.2.3 From b921bae2eedc806b118a03d986cf0be9ffd3af40 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Thu, 16 Dec 2010 14:47:46 +1000 Subject: drm/ttm: delay freeing of old node during move_memcpy until after iounmap Drivers using their own implementation of io_mem_reserve/io_mem_free are likely to store the tracking information for the map in mem.mm_node, so it can't be freed while still mapped. Signed-off-by: Ben Skeggs Reviewed-by: Thomas Hellstrom Signed-off-by: Dave Airlie --- drivers/gpu/drm/ttm/ttm_bo_util.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/ttm/ttm_bo_util.c b/drivers/gpu/drm/ttm/ttm_bo_util.c index a89839f83f6c..77dbf408c0d0 100644 --- a/drivers/gpu/drm/ttm/ttm_bo_util.c +++ b/drivers/gpu/drm/ttm/ttm_bo_util.c @@ -370,7 +370,6 @@ int ttm_bo_move_memcpy(struct ttm_buffer_object *bo, } mb(); out2: - ttm_bo_free_old_node(bo); old_copy = *old_mem; *old_mem = *new_mem; new_mem->mm_node = NULL; @@ -385,6 +384,7 @@ out1: ttm_mem_reg_iounmap(bdev, old_mem, new_iomap); out: ttm_mem_reg_iounmap(bdev, &old_copy, old_iomap); + ttm_bo_mem_put(bo, &old_copy); return ret; } EXPORT_SYMBOL(ttm_bo_move_memcpy); -- cgit v1.2.3 From b4183e301ac1dfaf93e3e92fd70a0c3203c5a27d Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Wed, 15 Dec 2010 11:04:10 -0500 Subject: drm/radeon/kms: fix vram start calculation on ontario (v2) Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/evergreen.c | 6 ++++++ drivers/gpu/drm/radeon/evergreend.h | 1 + drivers/gpu/drm/radeon/rv770.c | 13 +------------ drivers/gpu/drm/radeon/rv770d.h | 1 - 4 files changed, 8 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index 522d29b37007..f7d7477daffb 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c @@ -1134,6 +1134,12 @@ static void evergreen_mc_program(struct radeon_device *rdev) rdev->mc.vram_end >> 12); } WREG32(MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR, 0); + if (rdev->flags & RADEON_IS_IGP) { + tmp = RREG32(MC_FUS_VM_FB_OFFSET) & 0x000FFFFF; + tmp |= ((rdev->mc.vram_end >> 20) & 0xF) << 24; + tmp |= ((rdev->mc.vram_start >> 20) & 0xF) << 20; + WREG32(MC_FUS_VM_FB_OFFSET, tmp); + } tmp = ((rdev->mc.vram_end >> 24) & 0xFFFF) << 16; tmp |= ((rdev->mc.vram_start >> 24) & 0xFFFF); WREG32(MC_VM_FB_LOCATION, tmp); diff --git a/drivers/gpu/drm/radeon/evergreend.h b/drivers/gpu/drm/radeon/evergreend.h index 87fcaba76695..5b869ce86917 100644 --- a/drivers/gpu/drm/radeon/evergreend.h +++ b/drivers/gpu/drm/radeon/evergreend.h @@ -202,6 +202,7 @@ #define MC_VM_AGP_BOT 0x202C #define MC_VM_AGP_BASE 0x2030 #define MC_VM_FB_LOCATION 0x2024 +#define MC_FUS_VM_FB_OFFSET 0x2898 #define MC_VM_MB_L1_TLB0_CNTL 0x2234 #define MC_VM_MB_L1_TLB1_CNTL 0x2238 #define MC_VM_MB_L1_TLB2_CNTL 0x223C diff --git a/drivers/gpu/drm/radeon/rv770.c b/drivers/gpu/drm/radeon/rv770.c index 7c2e0b19a558..645aa1fd7611 100644 --- a/drivers/gpu/drm/radeon/rv770.c +++ b/drivers/gpu/drm/radeon/rv770.c @@ -271,12 +271,6 @@ static void rv770_mc_program(struct radeon_device *rdev) rdev->mc.vram_end >> 12); } WREG32(MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR, 0); - if (rdev->flags & RADEON_IS_IGP) { - tmp = RREG32(MC_FUS_VM_FB_OFFSET) & 0x000FFFFF; - tmp |= ((rdev->mc.vram_end >> 20) & 0xF) << 24; - tmp |= ((rdev->mc.vram_start >> 20) & 0xF) << 20; - WREG32(MC_FUS_VM_FB_OFFSET, tmp); - } tmp = ((rdev->mc.vram_end >> 24) & 0xFFFF) << 16; tmp |= ((rdev->mc.vram_start >> 24) & 0xFFFF); WREG32(MC_VM_FB_LOCATION, tmp); @@ -1074,12 +1068,7 @@ void r700_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc) mc->mc_vram_size >> 20, mc->vram_start, mc->vram_end, mc->real_vram_size >> 20); } else { - u64 base = 0; - if (rdev->flags & RADEON_IS_IGP) { - base = (RREG32(MC_VM_FB_LOCATION) & 0xFFFF) << 24; - base |= RREG32(MC_FUS_VM_FB_OFFSET) & 0x00F00000; - } - radeon_vram_location(rdev, &rdev->mc, base); + radeon_vram_location(rdev, &rdev->mc, 0); rdev->mc.gtt_base_align = 0; radeon_gtt_location(rdev, mc); } diff --git a/drivers/gpu/drm/radeon/rv770d.h b/drivers/gpu/drm/radeon/rv770d.h index 98f9ad256d3d..fc77e1e1a179 100644 --- a/drivers/gpu/drm/radeon/rv770d.h +++ b/drivers/gpu/drm/radeon/rv770d.h @@ -158,7 +158,6 @@ #define MC_VM_AGP_BOT 0x202C #define MC_VM_AGP_BASE 0x2030 #define MC_VM_FB_LOCATION 0x2024 -#define MC_FUS_VM_FB_OFFSET 0x2898 #define MC_VM_MB_L1_TLB0_CNTL 0x2234 #define MC_VM_MB_L1_TLB1_CNTL 0x2238 #define MC_VM_MB_L1_TLB2_CNTL 0x223C -- cgit v1.2.3 From b08ebe7e776e5be0271ed1e1bbb384e1f29dd117 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Fri, 3 Dec 2010 15:34:16 -0500 Subject: drm/radeon/kms: properly print ontario chip id Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/radeon_device.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index dd93c9c94144..3952cf3d0ee9 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c @@ -81,6 +81,7 @@ static const char radeon_family_name[][16] = { "JUNIPER", "CYPRESS", "HEMLOCK", + "PALM", "LAST", }; -- cgit v1.2.3 From 50308d813bf26500fed671882469939fd19403a3 Mon Sep 17 00:00:00 2001 From: Tao Ma Date: Thu, 4 Nov 2010 15:14:11 +0800 Subject: ocfs2: Try to free truncate log when meeting ENOSPC in write. Recently, one of our colleagues meet with a problem that if we write/delete a 32mb files repeatly, we will get an ENOSPC in the end. And the corresponding bug is 1288. http://oss.oracle.com/bugzilla/show_bug.cgi?id=1288 The real problem is that although we have freed the clusters, they are in truncate log and they will be summed up so that we can free them once in a whole. So this patch just try to resolve it. In case we see -ENOSPC in ocfs2_write_begin_no_lock, we will check whether the truncate log has enough clusters for our need, if yes, we will try to flush the truncate log at that point and try again. This method is inspired by Mark Fasheh . Thanks. Cc: Mark Fasheh Signed-off-by: Tao Ma Signed-off-by: Joel Becker --- fs/ocfs2/alloc.c | 3 +++ fs/ocfs2/aops.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- fs/ocfs2/ocfs2.h | 5 +++++ 3 files changed, 66 insertions(+), 1 deletion(-) diff --git a/fs/ocfs2/alloc.c b/fs/ocfs2/alloc.c index 592fae5007d1..8ec418dd9e36 100644 --- a/fs/ocfs2/alloc.c +++ b/fs/ocfs2/alloc.c @@ -5858,6 +5858,7 @@ int ocfs2_truncate_log_append(struct ocfs2_super *osb, ocfs2_journal_dirty(handle, tl_bh); + osb->truncated_clusters += num_clusters; bail: mlog_exit(status); return status; @@ -5929,6 +5930,8 @@ static int ocfs2_replay_truncate_records(struct ocfs2_super *osb, i--; } + osb->truncated_clusters = 0; + bail: mlog_exit(status); return status; diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c index f1e962cb3b73..d55a10e2f300 100644 --- a/fs/ocfs2/aops.c +++ b/fs/ocfs2/aops.c @@ -1627,6 +1627,43 @@ static int ocfs2_zero_tail(struct inode *inode, struct buffer_head *di_bh, return ret; } +/* + * Try to flush truncate logs if we can free enough clusters from it. + * As for return value, "< 0" means error, "0" no space and "1" means + * we have freed enough spaces and let the caller try to allocate again. + */ +static int ocfs2_try_to_free_truncate_log(struct ocfs2_super *osb, + unsigned int needed) +{ + tid_t target; + int ret = 0; + unsigned int truncated_clusters; + + mutex_lock(&osb->osb_tl_inode->i_mutex); + truncated_clusters = osb->truncated_clusters; + mutex_unlock(&osb->osb_tl_inode->i_mutex); + + /* + * Check whether we can succeed in allocating if we free + * the truncate log. + */ + if (truncated_clusters < needed) + goto out; + + ret = ocfs2_flush_truncate_log(osb); + if (ret) { + mlog_errno(ret); + goto out; + } + + if (jbd2_journal_start_commit(osb->journal->j_journal, &target)) { + jbd2_log_wait_commit(osb->journal->j_journal, target); + ret = 1; + } +out: + return ret; +} + int ocfs2_write_begin_nolock(struct file *filp, struct address_space *mapping, loff_t pos, unsigned len, unsigned flags, @@ -1634,7 +1671,7 @@ int ocfs2_write_begin_nolock(struct file *filp, struct buffer_head *di_bh, struct page *mmap_page) { int ret, cluster_of_pages, credits = OCFS2_INODE_UPDATE_CREDITS; - unsigned int clusters_to_alloc, extents_to_split; + unsigned int clusters_to_alloc, extents_to_split, clusters_need = 0; struct ocfs2_write_ctxt *wc; struct inode *inode = mapping->host; struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); @@ -1643,7 +1680,9 @@ int ocfs2_write_begin_nolock(struct file *filp, struct ocfs2_alloc_context *meta_ac = NULL; handle_t *handle; struct ocfs2_extent_tree et; + int try_free = 1, ret1; +try_again: ret = ocfs2_alloc_write_ctxt(&wc, osb, pos, len, di_bh); if (ret) { mlog_errno(ret); @@ -1678,6 +1717,7 @@ int ocfs2_write_begin_nolock(struct file *filp, mlog_errno(ret); goto out; } else if (ret == 1) { + clusters_need = wc->w_clen; ret = ocfs2_refcount_cow(inode, filp, di_bh, wc->w_cpos, wc->w_clen, UINT_MAX); if (ret) { @@ -1692,6 +1732,7 @@ int ocfs2_write_begin_nolock(struct file *filp, mlog_errno(ret); goto out; } + clusters_need += clusters_to_alloc; di = (struct ocfs2_dinode *)wc->w_di_bh->b_data; @@ -1814,6 +1855,22 @@ out: ocfs2_free_alloc_context(data_ac); if (meta_ac) ocfs2_free_alloc_context(meta_ac); + + if (ret == -ENOSPC && try_free) { + /* + * Try to free some truncate log so that we can have enough + * clusters to allocate. + */ + try_free = 0; + + ret1 = ocfs2_try_to_free_truncate_log(osb, clusters_need); + if (ret1 == 1) + goto try_again; + + if (ret1 < 0) + mlog_errno(ret1); + } + return ret; } diff --git a/fs/ocfs2/ocfs2.h b/fs/ocfs2/ocfs2.h index 70dd3b1798f1..51cd6898e7f1 100644 --- a/fs/ocfs2/ocfs2.h +++ b/fs/ocfs2/ocfs2.h @@ -420,6 +420,11 @@ struct ocfs2_super struct inode *osb_tl_inode; struct buffer_head *osb_tl_bh; struct delayed_work osb_truncate_log_wq; + /* + * How many clusters in our truncate log. + * It must be protected by osb_tl_inode->i_mutex. + */ + unsigned int truncated_clusters; struct ocfs2_node_map osb_recovering_orphan_dirs; unsigned int *osb_orphan_wipes; -- cgit v1.2.3 From 8e17d16f401f7c60908726e070bfa5cbdf31e2f3 Mon Sep 17 00:00:00 2001 From: Sunil Mushran Date: Fri, 19 Nov 2010 15:06:49 -0800 Subject: ocfs2/dlm: Cleanup mlogs in dlmthread.c, dlmast.c and dlmdomain.c Add the domain name and the resource name in the mlogs. Signed-off-by: Sunil Mushran Signed-off-by: Joel Becker --- fs/ocfs2/dlm/dlmast.c | 76 ++++++++++++++++++--------- fs/ocfs2/dlm/dlmdomain.c | 2 - fs/ocfs2/dlm/dlmthread.c | 132 ++++++++++++++++++++++++----------------------- 3 files changed, 120 insertions(+), 90 deletions(-) diff --git a/fs/ocfs2/dlm/dlmast.c b/fs/ocfs2/dlm/dlmast.c index f44999156839..3a3ed4bb794b 100644 --- a/fs/ocfs2/dlm/dlmast.c +++ b/fs/ocfs2/dlm/dlmast.c @@ -90,19 +90,29 @@ static int dlm_should_cancel_bast(struct dlm_ctxt *dlm, struct dlm_lock *lock) void __dlm_queue_ast(struct dlm_ctxt *dlm, struct dlm_lock *lock) { - mlog_entry_void(); + struct dlm_lock_resource *res; BUG_ON(!dlm); BUG_ON(!lock); + res = lock->lockres; + assert_spin_locked(&dlm->ast_lock); + if (!list_empty(&lock->ast_list)) { - mlog(ML_ERROR, "ast list not empty!! pending=%d, newlevel=%d\n", + mlog(ML_ERROR, "%s: res %.*s, lock %u:%llu, " + "AST list not empty, pending %d, newlevel %d\n", + dlm->name, res->lockname.len, res->lockname.name, + dlm_get_lock_cookie_node(be64_to_cpu(lock->ml.cookie)), + dlm_get_lock_cookie_seq(be64_to_cpu(lock->ml.cookie)), lock->ast_pending, lock->ml.type); BUG(); } if (lock->ast_pending) - mlog(0, "lock has an ast getting flushed right now\n"); + mlog(0, "%s: res %.*s, lock %u:%llu, AST getting flushed\n", + dlm->name, res->lockname.len, res->lockname.name, + dlm_get_lock_cookie_node(be64_to_cpu(lock->ml.cookie)), + dlm_get_lock_cookie_seq(be64_to_cpu(lock->ml.cookie))); /* putting lock on list, add a ref */ dlm_lock_get(lock); @@ -110,9 +120,10 @@ void __dlm_queue_ast(struct dlm_ctxt *dlm, struct dlm_lock *lock) /* check to see if this ast obsoletes the bast */ if (dlm_should_cancel_bast(dlm, lock)) { - struct dlm_lock_resource *res = lock->lockres; - mlog(0, "%s: cancelling bast for %.*s\n", - dlm->name, res->lockname.len, res->lockname.name); + mlog(0, "%s: res %.*s, lock %u:%llu, Cancelling BAST\n", + dlm->name, res->lockname.len, res->lockname.name, + dlm_get_lock_cookie_node(be64_to_cpu(lock->ml.cookie)), + dlm_get_lock_cookie_seq(be64_to_cpu(lock->ml.cookie))); lock->bast_pending = 0; list_del_init(&lock->bast_list); lock->ml.highest_blocked = LKM_IVMODE; @@ -134,8 +145,6 @@ void __dlm_queue_ast(struct dlm_ctxt *dlm, struct dlm_lock *lock) void dlm_queue_ast(struct dlm_ctxt *dlm, struct dlm_lock *lock) { - mlog_entry_void(); - BUG_ON(!dlm); BUG_ON(!lock); @@ -147,15 +156,21 @@ void dlm_queue_ast(struct dlm_ctxt *dlm, struct dlm_lock *lock) void __dlm_queue_bast(struct dlm_ctxt *dlm, struct dlm_lock *lock) { - mlog_entry_void(); + struct dlm_lock_resource *res; BUG_ON(!dlm); BUG_ON(!lock); + assert_spin_locked(&dlm->ast_lock); + res = lock->lockres; + BUG_ON(!list_empty(&lock->bast_list)); if (lock->bast_pending) - mlog(0, "lock has a bast getting flushed right now\n"); + mlog(0, "%s: res %.*s, lock %u:%llu, BAST getting flushed\n", + dlm->name, res->lockname.len, res->lockname.name, + dlm_get_lock_cookie_node(be64_to_cpu(lock->ml.cookie)), + dlm_get_lock_cookie_seq(be64_to_cpu(lock->ml.cookie))); /* putting lock on list, add a ref */ dlm_lock_get(lock); @@ -167,8 +182,6 @@ void __dlm_queue_bast(struct dlm_ctxt *dlm, struct dlm_lock *lock) void dlm_queue_bast(struct dlm_ctxt *dlm, struct dlm_lock *lock) { - mlog_entry_void(); - BUG_ON(!dlm); BUG_ON(!lock); @@ -213,7 +226,10 @@ void dlm_do_local_ast(struct dlm_ctxt *dlm, struct dlm_lock_resource *res, dlm_astlockfunc_t *fn; struct dlm_lockstatus *lksb; - mlog_entry_void(); + mlog(0, "%s: res %.*s, lock %u:%llu, Local AST\n", dlm->name, + res->lockname.len, res->lockname.name, + dlm_get_lock_cookie_node(be64_to_cpu(lock->ml.cookie)), + dlm_get_lock_cookie_seq(be64_to_cpu(lock->ml.cookie))); lksb = lock->lksb; fn = lock->ast; @@ -231,7 +247,10 @@ int dlm_do_remote_ast(struct dlm_ctxt *dlm, struct dlm_lock_resource *res, struct dlm_lockstatus *lksb; int lksbflags; - mlog_entry_void(); + mlog(0, "%s: res %.*s, lock %u:%llu, Remote AST\n", dlm->name, + res->lockname.len, res->lockname.name, + dlm_get_lock_cookie_node(be64_to_cpu(lock->ml.cookie)), + dlm_get_lock_cookie_seq(be64_to_cpu(lock->ml.cookie))); lksb = lock->lksb; BUG_ON(lock->ml.node == dlm->node_num); @@ -250,9 +269,14 @@ void dlm_do_local_bast(struct dlm_ctxt *dlm, struct dlm_lock_resource *res, { dlm_bastlockfunc_t *fn = lock->bast; - mlog_entry_void(); BUG_ON(lock->ml.node != dlm->node_num); + mlog(0, "%s: res %.*s, lock %u:%llu, Local BAST, blocked %d\n", + dlm->name, res->lockname.len, res->lockname.name, + dlm_get_lock_cookie_node(be64_to_cpu(lock->ml.cookie)), + dlm_get_lock_cookie_seq(be64_to_cpu(lock->ml.cookie)), + blocked_type); + (*fn)(lock->astdata, blocked_type); } @@ -332,7 +356,8 @@ int dlm_proxy_ast_handler(struct o2net_msg *msg, u32 len, void *data, /* cannot get a proxy ast message if this node owns it */ BUG_ON(res->owner == dlm->node_num); - mlog(0, "lockres %.*s\n", res->lockname.len, res->lockname.name); + mlog(0, "%s: res %.*s\n", dlm->name, res->lockname.len, + res->lockname.name); spin_lock(&res->spinlock); if (res->state & DLM_LOCK_RES_RECOVERING) { @@ -382,8 +407,12 @@ do_ast: if (past->type == DLM_AST) { /* do not alter lock refcount. switching lists. */ list_move_tail(&lock->list, &res->granted); - mlog(0, "ast: Adding to granted list... type=%d, " - "convert_type=%d\n", lock->ml.type, lock->ml.convert_type); + mlog(0, "%s: res %.*s, lock %u:%llu, Granted type %d => %d\n", + dlm->name, res->lockname.len, res->lockname.name, + dlm_get_lock_cookie_node(be64_to_cpu(cookie)), + dlm_get_lock_cookie_seq(be64_to_cpu(cookie)), + lock->ml.type, lock->ml.convert_type); + if (lock->ml.convert_type != LKM_IVMODE) { lock->ml.type = lock->ml.convert_type; lock->ml.convert_type = LKM_IVMODE; @@ -426,9 +455,9 @@ int dlm_send_proxy_ast_msg(struct dlm_ctxt *dlm, struct dlm_lock_resource *res, size_t veclen = 1; int status; - mlog_entry("res %.*s, to=%u, type=%d, blocked_type=%d\n", - res->lockname.len, res->lockname.name, lock->ml.node, - msg_type, blocked_type); + mlog(0, "%s: res %.*s, to %u, type %d, blocked_type %d\n", dlm->name, + res->lockname.len, res->lockname.name, lock->ml.node, msg_type, + blocked_type); memset(&past, 0, sizeof(struct dlm_proxy_ast)); past.node_idx = dlm->node_num; @@ -441,7 +470,6 @@ int dlm_send_proxy_ast_msg(struct dlm_ctxt *dlm, struct dlm_lock_resource *res, vec[0].iov_len = sizeof(struct dlm_proxy_ast); vec[0].iov_base = &past; if (flags & DLM_LKSB_GET_LVB) { - mlog(0, "returning requested LVB data\n"); be32_add_cpu(&past.flags, LKM_GET_LVB); vec[1].iov_len = DLM_LVB_LEN; vec[1].iov_base = lock->lksb->lvb; @@ -451,8 +479,8 @@ int dlm_send_proxy_ast_msg(struct dlm_ctxt *dlm, struct dlm_lock_resource *res, ret = o2net_send_message_vec(DLM_PROXY_AST_MSG, dlm->key, vec, veclen, lock->ml.node, &status); if (ret < 0) - mlog(ML_ERROR, "Error %d when sending message %u (key 0x%x) to " - "node %u\n", ret, DLM_PROXY_AST_MSG, dlm->key, + mlog(ML_ERROR, "%s: res %.*s, error %d send AST to node %u\n", + dlm->name, res->lockname.len, res->lockname.name, ret, lock->ml.node); else { if (status == DLM_RECOVERING) { diff --git a/fs/ocfs2/dlm/dlmdomain.c b/fs/ocfs2/dlm/dlmdomain.c index cc2aaa96cfe5..fcc40c33489d 100644 --- a/fs/ocfs2/dlm/dlmdomain.c +++ b/fs/ocfs2/dlm/dlmdomain.c @@ -460,8 +460,6 @@ redo_bucket: } cond_resched_lock(&dlm->spinlock); num += n; - mlog(0, "%s: touched %d lockreses in bucket %d " - "(tot=%d)\n", dlm->name, n, i, num); } spin_unlock(&dlm->spinlock); wake_up(&dlm->dlm_thread_wq); diff --git a/fs/ocfs2/dlm/dlmthread.c b/fs/ocfs2/dlm/dlmthread.c index 2211acf33d9b..1d6d1d22c471 100644 --- a/fs/ocfs2/dlm/dlmthread.c +++ b/fs/ocfs2/dlm/dlmthread.c @@ -122,15 +122,13 @@ int __dlm_lockres_unused(struct dlm_lock_resource *res) void __dlm_lockres_calc_usage(struct dlm_ctxt *dlm, struct dlm_lock_resource *res) { - mlog_entry("%.*s\n", res->lockname.len, res->lockname.name); - assert_spin_locked(&dlm->spinlock); assert_spin_locked(&res->spinlock); if (__dlm_lockres_unused(res)){ if (list_empty(&res->purge)) { - mlog(0, "putting lockres %.*s:%p onto purge list\n", - res->lockname.len, res->lockname.name, res); + mlog(0, "%s: Adding res %.*s to purge list\n", + dlm->name, res->lockname.len, res->lockname.name); res->last_used = jiffies; dlm_lockres_get(res); @@ -138,8 +136,8 @@ void __dlm_lockres_calc_usage(struct dlm_ctxt *dlm, dlm->purge_count++; } } else if (!list_empty(&res->purge)) { - mlog(0, "removing lockres %.*s:%p from purge list, owner=%u\n", - res->lockname.len, res->lockname.name, res, res->owner); + mlog(0, "%s: Removing res %.*s from purge list\n", + dlm->name, res->lockname.len, res->lockname.name); list_del_init(&res->purge); dlm_lockres_put(res); @@ -150,7 +148,6 @@ void __dlm_lockres_calc_usage(struct dlm_ctxt *dlm, void dlm_lockres_calc_usage(struct dlm_ctxt *dlm, struct dlm_lock_resource *res) { - mlog_entry("%.*s\n", res->lockname.len, res->lockname.name); spin_lock(&dlm->spinlock); spin_lock(&res->spinlock); @@ -171,9 +168,8 @@ static void dlm_purge_lockres(struct dlm_ctxt *dlm, master = (res->owner == dlm->node_num); - - mlog(0, "purging lockres %.*s, master = %d\n", res->lockname.len, - res->lockname.name, master); + mlog(0, "%s: Purging res %.*s, master %d\n", dlm->name, + res->lockname.len, res->lockname.name, master); if (!master) { res->state |= DLM_LOCK_RES_DROPPING_REF; @@ -189,27 +185,25 @@ static void dlm_purge_lockres(struct dlm_ctxt *dlm, /* clear our bit from the master's refmap, ignore errors */ ret = dlm_drop_lockres_ref(dlm, res); if (ret < 0) { - mlog_errno(ret); + mlog(ML_ERROR, "%s: deref %.*s failed %d\n", dlm->name, + res->lockname.len, res->lockname.name, ret); if (!dlm_is_host_down(ret)) BUG(); } - mlog(0, "%s:%.*s: dlm_deref_lockres returned %d\n", - dlm->name, res->lockname.len, res->lockname.name, ret); spin_lock(&dlm->spinlock); spin_lock(&res->spinlock); } if (!list_empty(&res->purge)) { - mlog(0, "removing lockres %.*s:%p from purgelist, " - "master = %d\n", res->lockname.len, res->lockname.name, - res, master); + mlog(0, "%s: Removing res %.*s from purgelist, master %d\n", + dlm->name, res->lockname.len, res->lockname.name, master); list_del_init(&res->purge); dlm_lockres_put(res); dlm->purge_count--; } if (!__dlm_lockres_unused(res)) { - mlog(ML_ERROR, "found lockres %s:%.*s: in use after deref\n", + mlog(ML_ERROR, "%s: res %.*s in use after deref\n", dlm->name, res->lockname.len, res->lockname.name); __dlm_print_one_lock_resource(res); BUG(); @@ -266,10 +260,10 @@ static void dlm_run_purge_list(struct dlm_ctxt *dlm, unused = __dlm_lockres_unused(lockres); if (!unused || (lockres->state & DLM_LOCK_RES_MIGRATING)) { - mlog(0, "lockres %s:%.*s: is in use or " - "being remastered, used %d, state %d\n", - dlm->name, lockres->lockname.len, - lockres->lockname.name, !unused, lockres->state); + mlog(0, "%s: res %.*s is in use or being remastered, " + "used %d, state %d\n", dlm->name, + lockres->lockname.len, lockres->lockname.name, + !unused, lockres->state); list_move_tail(&dlm->purge_list, &lockres->purge); spin_unlock(&lockres->spinlock); continue; @@ -296,15 +290,12 @@ static void dlm_shuffle_lists(struct dlm_ctxt *dlm, struct list_head *head; int can_grant = 1; - //mlog(0, "res->lockname.len=%d\n", res->lockname.len); - //mlog(0, "res->lockname.name=%p\n", res->lockname.name); - //mlog(0, "shuffle res %.*s\n", res->lockname.len, - // res->lockname.name); - - /* because this function is called with the lockres + /* + * Because this function is called with the lockres * spinlock, and because we know that it is not migrating/ * recovering/in-progress, it is fine to reserve asts and - * basts right before queueing them all throughout */ + * basts right before queueing them all throughout + */ assert_spin_locked(&dlm->ast_lock); assert_spin_locked(&res->spinlock); BUG_ON((res->state & (DLM_LOCK_RES_MIGRATING| @@ -314,13 +305,13 @@ static void dlm_shuffle_lists(struct dlm_ctxt *dlm, converting: if (list_empty(&res->converting)) goto blocked; - mlog(0, "res %.*s has locks on a convert queue\n", res->lockname.len, - res->lockname.name); + mlog(0, "%s: res %.*s has locks on the convert queue\n", dlm->name, + res->lockname.len, res->lockname.name); target = list_entry(res->converting.next, struct dlm_lock, list); if (target->ml.convert_type == LKM_IVMODE) { - mlog(ML_ERROR, "%.*s: converting a lock with no " - "convert_type!\n", res->lockname.len, res->lockname.name); + mlog(ML_ERROR, "%s: res %.*s converting lock to invalid mode\n", + dlm->name, res->lockname.len, res->lockname.name); BUG(); } head = &res->granted; @@ -365,9 +356,12 @@ converting: spin_lock(&target->spinlock); BUG_ON(target->ml.highest_blocked != LKM_IVMODE); - mlog(0, "calling ast for converting lock: %.*s, have: %d, " - "granting: %d, node: %u\n", res->lockname.len, - res->lockname.name, target->ml.type, + mlog(0, "%s: res %.*s, AST for Converting lock %u:%llu, type " + "%d => %d, node %u\n", dlm->name, res->lockname.len, + res->lockname.name, + dlm_get_lock_cookie_node(be64_to_cpu(target->ml.cookie)), + dlm_get_lock_cookie_seq(be64_to_cpu(target->ml.cookie)), + target->ml.type, target->ml.convert_type, target->ml.node); target->ml.type = target->ml.convert_type; @@ -428,11 +422,14 @@ blocked: spin_lock(&target->spinlock); BUG_ON(target->ml.highest_blocked != LKM_IVMODE); - mlog(0, "calling ast for blocked lock: %.*s, granting: %d, " - "node: %u\n", res->lockname.len, res->lockname.name, + mlog(0, "%s: res %.*s, AST for Blocked lock %u:%llu, type %d, " + "node %u\n", dlm->name, res->lockname.len, + res->lockname.name, + dlm_get_lock_cookie_node(be64_to_cpu(target->ml.cookie)), + dlm_get_lock_cookie_seq(be64_to_cpu(target->ml.cookie)), target->ml.type, target->ml.node); - // target->ml.type is already correct + /* target->ml.type is already correct */ list_move_tail(&target->list, &res->granted); BUG_ON(!target->lksb); @@ -453,7 +450,6 @@ leave: /* must have NO locks when calling this with res !=NULL * */ void dlm_kick_thread(struct dlm_ctxt *dlm, struct dlm_lock_resource *res) { - mlog_entry("dlm=%p, res=%p\n", dlm, res); if (res) { spin_lock(&dlm->spinlock); spin_lock(&res->spinlock); @@ -466,8 +462,6 @@ void dlm_kick_thread(struct dlm_ctxt *dlm, struct dlm_lock_resource *res) void __dlm_dirty_lockres(struct dlm_ctxt *dlm, struct dlm_lock_resource *res) { - mlog_entry("dlm=%p, res=%p\n", dlm, res); - assert_spin_locked(&dlm->spinlock); assert_spin_locked(&res->spinlock); @@ -484,13 +478,16 @@ void __dlm_dirty_lockres(struct dlm_ctxt *dlm, struct dlm_lock_resource *res) res->state |= DLM_LOCK_RES_DIRTY; } } + + mlog(0, "%s: res %.*s\n", dlm->name, res->lockname.len, + res->lockname.name); } /* Launch the NM thread for the mounted volume */ int dlm_launch_thread(struct dlm_ctxt *dlm) { - mlog(0, "starting dlm thread...\n"); + mlog(0, "Starting dlm_thread...\n"); dlm->dlm_thread_task = kthread_run(dlm_thread, dlm, "dlm_thread"); if (IS_ERR(dlm->dlm_thread_task)) { @@ -505,7 +502,7 @@ int dlm_launch_thread(struct dlm_ctxt *dlm) void dlm_complete_thread(struct dlm_ctxt *dlm) { if (dlm->dlm_thread_task) { - mlog(ML_KTHREAD, "waiting for dlm thread to exit\n"); + mlog(ML_KTHREAD, "Waiting for dlm thread to exit\n"); kthread_stop(dlm->dlm_thread_task); dlm->dlm_thread_task = NULL; } @@ -536,7 +533,12 @@ static void dlm_flush_asts(struct dlm_ctxt *dlm) /* get an extra ref on lock */ dlm_lock_get(lock); res = lock->lockres; - mlog(0, "delivering an ast for this lockres\n"); + mlog(0, "%s: res %.*s, Flush AST for lock %u:%llu, type %d, " + "node %u\n", dlm->name, res->lockname.len, + res->lockname.name, + dlm_get_lock_cookie_node(be64_to_cpu(lock->ml.cookie)), + dlm_get_lock_cookie_seq(be64_to_cpu(lock->ml.cookie)), + lock->ml.type, lock->ml.node); BUG_ON(!lock->ast_pending); @@ -557,9 +559,9 @@ static void dlm_flush_asts(struct dlm_ctxt *dlm) /* possible that another ast was queued while * we were delivering the last one */ if (!list_empty(&lock->ast_list)) { - mlog(0, "aha another ast got queued while " - "we were finishing the last one. will " - "keep the ast_pending flag set.\n"); + mlog(0, "%s: res %.*s, AST queued while flushing last " + "one\n", dlm->name, res->lockname.len, + res->lockname.name); } else lock->ast_pending = 0; @@ -590,8 +592,12 @@ static void dlm_flush_asts(struct dlm_ctxt *dlm) dlm_lock_put(lock); spin_unlock(&dlm->ast_lock); - mlog(0, "delivering a bast for this lockres " - "(blocked = %d\n", hi); + mlog(0, "%s: res %.*s, Flush BAST for lock %u:%llu, " + "blocked %d, node %u\n", + dlm->name, res->lockname.len, res->lockname.name, + dlm_get_lock_cookie_node(be64_to_cpu(lock->ml.cookie)), + dlm_get_lock_cookie_seq(be64_to_cpu(lock->ml.cookie)), + hi, lock->ml.node); if (lock->ml.node != dlm->node_num) { ret = dlm_send_proxy_bast(dlm, res, lock, hi); @@ -605,9 +611,9 @@ static void dlm_flush_asts(struct dlm_ctxt *dlm) /* possible that another bast was queued while * we were delivering the last one */ if (!list_empty(&lock->bast_list)) { - mlog(0, "aha another bast got queued while " - "we were finishing the last one. will " - "keep the bast_pending flag set.\n"); + mlog(0, "%s: res %.*s, BAST queued while flushing last " + "one\n", dlm->name, res->lockname.len, + res->lockname.name); } else lock->bast_pending = 0; @@ -675,11 +681,12 @@ static int dlm_thread(void *data) spin_lock(&res->spinlock); if (res->owner != dlm->node_num) { __dlm_print_one_lock_resource(res); - mlog(ML_ERROR, "inprog:%s, mig:%s, reco:%s, dirty:%s\n", - res->state & DLM_LOCK_RES_IN_PROGRESS ? "yes" : "no", - res->state & DLM_LOCK_RES_MIGRATING ? "yes" : "no", - res->state & DLM_LOCK_RES_RECOVERING ? "yes" : "no", - res->state & DLM_LOCK_RES_DIRTY ? "yes" : "no"); + mlog(ML_ERROR, "%s: inprog %d, mig %d, reco %d," + " dirty %d\n", dlm->name, + !!(res->state & DLM_LOCK_RES_IN_PROGRESS), + !!(res->state & DLM_LOCK_RES_MIGRATING), + !!(res->state & DLM_LOCK_RES_RECOVERING), + !!(res->state & DLM_LOCK_RES_DIRTY)); } BUG_ON(res->owner != dlm->node_num); @@ -693,8 +700,8 @@ static int dlm_thread(void *data) res->state &= ~DLM_LOCK_RES_DIRTY; spin_unlock(&res->spinlock); spin_unlock(&dlm->ast_lock); - mlog(0, "delaying list shuffling for in-" - "progress lockres %.*s, state=%d\n", + mlog(0, "%s: res %.*s, inprogress, delay list " + "shuffle, state %d\n", dlm->name, res->lockname.len, res->lockname.name, res->state); delay = 1; @@ -706,10 +713,6 @@ static int dlm_thread(void *data) * spinlock and do NOT have the dlm lock. * safe to reserve/queue asts and run the lists. */ - mlog(0, "calling dlm_shuffle_lists with dlm=%s, " - "res=%.*s\n", dlm->name, - res->lockname.len, res->lockname.name); - /* called while holding lockres lock */ dlm_shuffle_lists(dlm, res); res->state &= ~DLM_LOCK_RES_DIRTY; @@ -733,7 +736,8 @@ in_progress: /* unlikely, but we may need to give time to * other tasks */ if (!--n) { - mlog(0, "throttling dlm_thread\n"); + mlog(0, "%s: Throttling dlm thread\n", + dlm->name); break; } } -- cgit v1.2.3 From 66f4500573fe5a1b455e5f7b30068a623a94117f Mon Sep 17 00:00:00 2001 From: Wengang Wang Date: Wed, 8 Dec 2010 20:34:39 +0800 Subject: ocfs2/dlm: make existing convertion precedent over new lock Make existing convertion precedent over new lock. It makes o2dlm locking more like fair locking. Signed-off-by: Wengang Wang Signed-off-by: Joel Becker --- fs/ocfs2/dlm/dlmlock.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/fs/ocfs2/dlm/dlmlock.c b/fs/ocfs2/dlm/dlmlock.c index 69cf369961c4..7009292aac5a 100644 --- a/fs/ocfs2/dlm/dlmlock.c +++ b/fs/ocfs2/dlm/dlmlock.c @@ -106,6 +106,9 @@ static int dlm_can_grant_new_lock(struct dlm_lock_resource *res, if (!dlm_lock_compatible(tmplock->ml.type, lock->ml.type)) return 0; + if (!dlm_lock_compatible(tmplock->ml.convert_type, + lock->ml.type)) + return 0; } return 1; -- cgit v1.2.3 From 2b190ce9bf923fb1fd8ccff18e9bab72da40da06 Mon Sep 17 00:00:00 2001 From: Sunil Mushran Date: Tue, 14 Dec 2010 14:14:27 -0800 Subject: ocfs2/cluster: Pin the remote node item in configfs o2net pins the node item of the remote node in configfs before initiating the connection. It is unpinned on disconnect. This is to prevent the node item from being unlinked while it is still in use. Signed-off-by: Sunil Mushran Signed-off-by: Joel Becker --- fs/ocfs2/cluster/tcp.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/fs/ocfs2/cluster/tcp.c b/fs/ocfs2/cluster/tcp.c index 9aa426e42123..92de96cd247d 100644 --- a/fs/ocfs2/cluster/tcp.c +++ b/fs/ocfs2/cluster/tcp.c @@ -355,6 +355,7 @@ static void sc_kref_release(struct kref *kref) sc->sc_sock = NULL; } + o2nm_undepend_item(&sc->sc_node->nd_item); o2nm_node_put(sc->sc_node); sc->sc_node = NULL; @@ -376,6 +377,7 @@ static struct o2net_sock_container *sc_alloc(struct o2nm_node *node) { struct o2net_sock_container *sc, *ret = NULL; struct page *page = NULL; + int status = 0; page = alloc_page(GFP_NOFS); sc = kzalloc(sizeof(*sc), GFP_NOFS); @@ -386,6 +388,13 @@ static struct o2net_sock_container *sc_alloc(struct o2nm_node *node) o2nm_node_get(node); sc->sc_node = node; + /* pin the node item of the remote node */ + status = o2nm_depend_item(&node->nd_item); + if (status) { + mlog_errno(status); + o2nm_node_put(node); + goto out; + } INIT_WORK(&sc->sc_connect_work, o2net_sc_connect_completed); INIT_WORK(&sc->sc_rx_work, o2net_rx_until_empty); INIT_WORK(&sc->sc_shutdown_work, o2net_shutdown_sc); -- cgit v1.2.3 From ffee223a9af4c5124beb56fa5c84132949923d23 Mon Sep 17 00:00:00 2001 From: Sunil Mushran Date: Tue, 14 Dec 2010 14:14:28 -0800 Subject: ocfs2/cluster: Remove dropped region from o2hb quorum region bitmap Patch removes a dropped region from the quorum region bitmap maintained by o2hb. Signed-off-by: Sunil Mushran Signed-off-by: Joel Becker --- fs/ocfs2/cluster/heartbeat.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fs/ocfs2/cluster/heartbeat.c b/fs/ocfs2/cluster/heartbeat.c index 9f26ac9be2a4..9f21dd785364 100644 --- a/fs/ocfs2/cluster/heartbeat.c +++ b/fs/ocfs2/cluster/heartbeat.c @@ -2009,6 +2009,7 @@ static void o2hb_heartbeat_group_drop_item(struct config_group *group, if (o2hb_global_heartbeat_active()) { clear_bit(reg->hr_region_num, o2hb_region_bitmap); clear_bit(reg->hr_region_num, o2hb_live_region_bitmap); + clear_bit(reg->hr_region_num, o2hb_quorum_region_bitmap); } hb_task = reg->hr_task; reg->hr_task = NULL; -- cgit v1.2.3 From 58a3158a5d17ddf4894db9e8ccaf92093ff8e42e Mon Sep 17 00:00:00 2001 From: Sunil Mushran Date: Tue, 14 Dec 2010 14:14:29 -0800 Subject: ocfs2/cluster: Pin/unpin o2hb regions This patch adds support for pinning o2hb regions in configfs. Pinning disallows a region to be cleanly stopped as long as it has an active dependent user (read o2dlm). In local heartbeat mode, the region uuid matching the domain name is pinned as long as the o2dlm domain is active. In global heartbeat mode, all regions are pinned as long as there is atleast one dependent user and the region count is 3 or less. All regions are unpinned if the number of dependent users is zero or region count is greater than 3. Signed-off-by: Sunil Mushran Signed-off-by: Joel Becker --- fs/ocfs2/cluster/heartbeat.c | 216 +++++++++++++++++++++++++++++++++++-------- fs/ocfs2/dlm/dlmdomain.c | 8 +- 2 files changed, 182 insertions(+), 42 deletions(-) diff --git a/fs/ocfs2/cluster/heartbeat.c b/fs/ocfs2/cluster/heartbeat.c index 9f21dd785364..ad2e41d6879d 100644 --- a/fs/ocfs2/cluster/heartbeat.c +++ b/fs/ocfs2/cluster/heartbeat.c @@ -132,6 +132,33 @@ char *o2hb_heartbeat_mode_desc[O2HB_HEARTBEAT_NUM_MODES] = { unsigned int o2hb_dead_threshold = O2HB_DEFAULT_DEAD_THRESHOLD; unsigned int o2hb_heartbeat_mode = O2HB_HEARTBEAT_LOCAL; +/* + * o2hb_dependent_users tracks the number of registered callbacks that depend + * on heartbeat. o2net and o2dlm are two entities that register this callback. + * However only o2dlm depends on the heartbeat. It does not want the heartbeat + * to stop while a dlm domain is still active. + */ +unsigned int o2hb_dependent_users; + +/* + * In global heartbeat mode, all regions are pinned if there are one or more + * dependent users and the quorum region count is <= O2HB_PIN_CUT_OFF. All + * regions are unpinned if the region count exceeds the cut off or the number + * of dependent users falls to zero. + */ +#define O2HB_PIN_CUT_OFF 3 + +/* + * In local heartbeat mode, we assume the dlm domain name to be the same as + * region uuid. This is true for domains created for the file system but not + * necessarily true for userdlm domains. This is a known limitation. + * + * In global heartbeat mode, we pin/unpin all o2hb regions. This solution + * works for both file system and userdlm domains. + */ +static int o2hb_region_pin(const char *region_uuid); +static void o2hb_region_unpin(const char *region_uuid); + /* Only sets a new threshold if there are no active regions. * * No locking or otherwise interesting code is required for reading @@ -186,7 +213,9 @@ struct o2hb_region { struct config_item hr_item; struct list_head hr_all_item; - unsigned hr_unclean_stop:1; + unsigned hr_unclean_stop:1, + hr_item_pinned:1, + hr_item_dropped:1; /* protected by the hr_callback_sem */ struct task_struct *hr_task; @@ -702,6 +731,14 @@ static void o2hb_set_quorum_device(struct o2hb_region *reg, config_item_name(®->hr_item)); set_bit(reg->hr_region_num, o2hb_quorum_region_bitmap); + + /* + * If global heartbeat active, unpin all regions if the + * region count > CUT_OFF + */ + if (o2hb_pop_count(&o2hb_quorum_region_bitmap, + O2NM_MAX_REGIONS) > O2HB_PIN_CUT_OFF) + o2hb_region_unpin(NULL); } static int o2hb_check_slot(struct o2hb_region *reg, @@ -1316,6 +1353,8 @@ int o2hb_init(void) memset(o2hb_quorum_region_bitmap, 0, sizeof(o2hb_quorum_region_bitmap)); memset(o2hb_failed_region_bitmap, 0, sizeof(o2hb_failed_region_bitmap)); + o2hb_dependent_users = 0; + return o2hb_debug_init(); } @@ -2003,16 +2042,20 @@ static void o2hb_heartbeat_group_drop_item(struct config_group *group, { struct task_struct *hb_task; struct o2hb_region *reg = to_o2hb_region(item); + int quorum_region = 0; /* stop the thread when the user removes the region dir */ spin_lock(&o2hb_live_lock); if (o2hb_global_heartbeat_active()) { clear_bit(reg->hr_region_num, o2hb_region_bitmap); clear_bit(reg->hr_region_num, o2hb_live_region_bitmap); + if (test_bit(reg->hr_region_num, o2hb_quorum_region_bitmap)) + quorum_region = 1; clear_bit(reg->hr_region_num, o2hb_quorum_region_bitmap); } hb_task = reg->hr_task; reg->hr_task = NULL; + reg->hr_item_dropped = 1; spin_unlock(&o2hb_live_lock); if (hb_task) @@ -2030,7 +2073,27 @@ static void o2hb_heartbeat_group_drop_item(struct config_group *group, if (o2hb_global_heartbeat_active()) printk(KERN_NOTICE "o2hb: Heartbeat stopped on region %s\n", config_item_name(®->hr_item)); + config_item_put(item); + + if (!o2hb_global_heartbeat_active() || !quorum_region) + return; + + /* + * If global heartbeat active and there are dependent users, + * pin all regions if quorum region count <= CUT_OFF + */ + spin_lock(&o2hb_live_lock); + + if (!o2hb_dependent_users) + goto unlock; + + if (o2hb_pop_count(&o2hb_quorum_region_bitmap, + O2NM_MAX_REGIONS) <= O2HB_PIN_CUT_OFF) + o2hb_region_pin(NULL); + +unlock: + spin_unlock(&o2hb_live_lock); } struct o2hb_heartbeat_group_attribute { @@ -2216,63 +2279,138 @@ void o2hb_setup_callback(struct o2hb_callback_func *hc, } EXPORT_SYMBOL_GPL(o2hb_setup_callback); -static struct o2hb_region *o2hb_find_region(const char *region_uuid) +/* + * In local heartbeat mode, region_uuid passed matches the dlm domain name. + * In global heartbeat mode, region_uuid passed is NULL. + * + * In local, we only pin the matching region. In global we pin all the active + * regions. + */ +static int o2hb_region_pin(const char *region_uuid) { - struct o2hb_region *p, *reg = NULL; + int ret = 0, found = 0; + struct o2hb_region *reg; + char *uuid; assert_spin_locked(&o2hb_live_lock); - list_for_each_entry(p, &o2hb_all_regions, hr_all_item) { - if (!strcmp(region_uuid, config_item_name(&p->hr_item))) { - reg = p; - break; + list_for_each_entry(reg, &o2hb_all_regions, hr_all_item) { + uuid = config_item_name(®->hr_item); + + /* local heartbeat */ + if (region_uuid) { + if (strcmp(region_uuid, uuid)) + continue; + found = 1; } + + if (reg->hr_item_pinned || reg->hr_item_dropped) + goto skip_pin; + + /* Ignore ENOENT only for local hb (userdlm domain) */ + ret = o2nm_depend_item(®->hr_item); + if (!ret) { + mlog(ML_CLUSTER, "Pin region %s\n", uuid); + reg->hr_item_pinned = 1; + } else { + if (ret == -ENOENT && found) + ret = 0; + else { + mlog(ML_ERROR, "Pin region %s fails with %d\n", + uuid, ret); + break; + } + } +skip_pin: + if (found) + break; } - return reg; + return ret; } -static int o2hb_region_get(const char *region_uuid) +/* + * In local heartbeat mode, region_uuid passed matches the dlm domain name. + * In global heartbeat mode, region_uuid passed is NULL. + * + * In local, we only unpin the matching region. In global we unpin all the + * active regions. + */ +static void o2hb_region_unpin(const char *region_uuid) { - int ret = 0; struct o2hb_region *reg; + char *uuid; + int found = 0; - spin_lock(&o2hb_live_lock); + assert_spin_locked(&o2hb_live_lock); - reg = o2hb_find_region(region_uuid); - if (!reg) - ret = -ENOENT; - spin_unlock(&o2hb_live_lock); + list_for_each_entry(reg, &o2hb_all_regions, hr_all_item) { + uuid = config_item_name(®->hr_item); + if (region_uuid) { + if (strcmp(region_uuid, uuid)) + continue; + found = 1; + } - if (ret) - goto out; + if (reg->hr_item_pinned) { + mlog(ML_CLUSTER, "Unpin region %s\n", uuid); + o2nm_undepend_item(®->hr_item); + reg->hr_item_pinned = 0; + } + if (found) + break; + } +} - ret = o2nm_depend_this_node(); - if (ret) - goto out; +static int o2hb_region_inc_user(const char *region_uuid) +{ + int ret = 0; - ret = o2nm_depend_item(®->hr_item); - if (ret) - o2nm_undepend_this_node(); + spin_lock(&o2hb_live_lock); -out: + /* local heartbeat */ + if (!o2hb_global_heartbeat_active()) { + ret = o2hb_region_pin(region_uuid); + goto unlock; + } + + /* + * if global heartbeat active and this is the first dependent user, + * pin all regions if quorum region count <= CUT_OFF + */ + o2hb_dependent_users++; + if (o2hb_dependent_users > 1) + goto unlock; + + if (o2hb_pop_count(&o2hb_quorum_region_bitmap, + O2NM_MAX_REGIONS) <= O2HB_PIN_CUT_OFF) + ret = o2hb_region_pin(NULL); + +unlock: + spin_unlock(&o2hb_live_lock); return ret; } -static void o2hb_region_put(const char *region_uuid) +void o2hb_region_dec_user(const char *region_uuid) { - struct o2hb_region *reg; - spin_lock(&o2hb_live_lock); - reg = o2hb_find_region(region_uuid); + /* local heartbeat */ + if (!o2hb_global_heartbeat_active()) { + o2hb_region_unpin(region_uuid); + goto unlock; + } - spin_unlock(&o2hb_live_lock); + /* + * if global heartbeat active and there are no dependent users, + * unpin all quorum regions + */ + o2hb_dependent_users--; + if (!o2hb_dependent_users) + o2hb_region_unpin(NULL); - if (reg) { - o2nm_undepend_item(®->hr_item); - o2nm_undepend_this_node(); - } +unlock: + spin_unlock(&o2hb_live_lock); } int o2hb_register_callback(const char *region_uuid, @@ -2293,9 +2431,11 @@ int o2hb_register_callback(const char *region_uuid, } if (region_uuid) { - ret = o2hb_region_get(region_uuid); - if (ret) + ret = o2hb_region_inc_user(region_uuid); + if (ret) { + mlog_errno(ret); goto out; + } } down_write(&o2hb_callback_sem); @@ -2313,7 +2453,7 @@ int o2hb_register_callback(const char *region_uuid, up_write(&o2hb_callback_sem); ret = 0; out: - mlog(ML_HEARTBEAT, "returning %d on behalf of %p for funcs %p\n", + mlog(ML_CLUSTER, "returning %d on behalf of %p for funcs %p\n", ret, __builtin_return_address(0), hc); return ret; } @@ -2324,7 +2464,7 @@ void o2hb_unregister_callback(const char *region_uuid, { BUG_ON(hc->hc_magic != O2HB_CB_MAGIC); - mlog(ML_HEARTBEAT, "on behalf of %p for funcs %p\n", + mlog(ML_CLUSTER, "on behalf of %p for funcs %p\n", __builtin_return_address(0), hc); /* XXX Can this happen _with_ a region reference? */ @@ -2332,7 +2472,7 @@ void o2hb_unregister_callback(const char *region_uuid, return; if (region_uuid) - o2hb_region_put(region_uuid); + o2hb_region_dec_user(region_uuid); down_write(&o2hb_callback_sem); diff --git a/fs/ocfs2/dlm/dlmdomain.c b/fs/ocfs2/dlm/dlmdomain.c index fcc40c33489d..7e38a072d720 100644 --- a/fs/ocfs2/dlm/dlmdomain.c +++ b/fs/ocfs2/dlm/dlmdomain.c @@ -1659,8 +1659,8 @@ bail: static void dlm_unregister_domain_handlers(struct dlm_ctxt *dlm) { - o2hb_unregister_callback(NULL, &dlm->dlm_hb_up); - o2hb_unregister_callback(NULL, &dlm->dlm_hb_down); + o2hb_unregister_callback(dlm->name, &dlm->dlm_hb_up); + o2hb_unregister_callback(dlm->name, &dlm->dlm_hb_down); o2net_unregister_handler_list(&dlm->dlm_domain_handlers); } @@ -1672,13 +1672,13 @@ static int dlm_register_domain_handlers(struct dlm_ctxt *dlm) o2hb_setup_callback(&dlm->dlm_hb_down, O2HB_NODE_DOWN_CB, dlm_hb_node_down_cb, dlm, DLM_HB_NODE_DOWN_PRI); - status = o2hb_register_callback(NULL, &dlm->dlm_hb_down); + status = o2hb_register_callback(dlm->name, &dlm->dlm_hb_down); if (status) goto bail; o2hb_setup_callback(&dlm->dlm_hb_up, O2HB_NODE_UP_CB, dlm_hb_node_up_cb, dlm, DLM_HB_NODE_UP_PRI); - status = o2hb_register_callback(NULL, &dlm->dlm_hb_up); + status = o2hb_register_callback(dlm->name, &dlm->dlm_hb_up); if (status) goto bail; -- cgit v1.2.3 From cb0586bd4c77c531fe0be4ae860ec642450eeda5 Mon Sep 17 00:00:00 2001 From: Sunil Mushran Date: Tue, 14 Dec 2010 14:14:30 -0800 Subject: ocfs2/cluster: Show pin state for each o2hb region This patch adds a per o2hb region debugfs file that shows whether that region is pinned or not. Signed-off-by: Sunil Mushran Signed-off-by: Joel Becker --- fs/ocfs2/cluster/heartbeat.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/fs/ocfs2/cluster/heartbeat.c b/fs/ocfs2/cluster/heartbeat.c index ad2e41d6879d..3722e3850a1f 100644 --- a/fs/ocfs2/cluster/heartbeat.c +++ b/fs/ocfs2/cluster/heartbeat.c @@ -82,6 +82,7 @@ static unsigned long o2hb_failed_region_bitmap[BITS_TO_LONGS(O2NM_MAX_REGIONS)]; #define O2HB_DB_TYPE_REGION_LIVENODES 4 #define O2HB_DB_TYPE_REGION_NUMBER 5 #define O2HB_DB_TYPE_REGION_ELAPSED_TIME 6 +#define O2HB_DB_TYPE_REGION_PINNED 7 struct o2hb_debug_buf { int db_type; int db_size; @@ -101,6 +102,7 @@ static struct o2hb_debug_buf *o2hb_db_failedregions; #define O2HB_DEBUG_FAILEDREGIONS "failed_regions" #define O2HB_DEBUG_REGION_NUMBER "num" #define O2HB_DEBUG_REGION_ELAPSED_TIME "elapsed_time_in_ms" +#define O2HB_DEBUG_REGION_PINNED "pinned" static struct dentry *o2hb_debug_dir; static struct dentry *o2hb_debug_livenodes; @@ -241,9 +243,11 @@ struct o2hb_region { struct dentry *hr_debug_livenodes; struct dentry *hr_debug_regnum; struct dentry *hr_debug_elapsed_time; + struct dentry *hr_debug_pinned; struct o2hb_debug_buf *hr_db_livenodes; struct o2hb_debug_buf *hr_db_regnum; struct o2hb_debug_buf *hr_db_elapsed_time; + struct o2hb_debug_buf *hr_db_pinned; /* let the person setting up hb wait for it to return until it * has reached a 'steady' state. This will be fixed when we have @@ -1180,6 +1184,12 @@ static int o2hb_debug_open(struct inode *inode, struct file *file) reg->hr_last_timeout_start)); goto done; + case O2HB_DB_TYPE_REGION_PINNED: + reg = (struct o2hb_region *)db->db_data; + out += snprintf(buf + out, PAGE_SIZE - out, "%u\n", + !!reg->hr_item_pinned); + goto done; + default: goto done; } @@ -1424,6 +1434,7 @@ static void o2hb_region_release(struct config_item *item) debugfs_remove(reg->hr_debug_livenodes); debugfs_remove(reg->hr_debug_regnum); debugfs_remove(reg->hr_debug_elapsed_time); + debugfs_remove(reg->hr_debug_pinned); debugfs_remove(reg->hr_debug_dir); spin_lock(&o2hb_live_lock); @@ -1988,6 +1999,18 @@ static int o2hb_debug_region_init(struct o2hb_region *reg, struct dentry *dir) goto bail; } + reg->hr_debug_pinned = + o2hb_debug_create(O2HB_DEBUG_REGION_PINNED, + reg->hr_debug_dir, + &(reg->hr_db_pinned), + sizeof(*(reg->hr_db_pinned)), + O2HB_DB_TYPE_REGION_PINNED, + 0, 0, reg); + if (!reg->hr_debug_pinned) { + mlog_errno(ret); + goto bail; + } + ret = 0; bail: return ret; -- cgit v1.2.3 From cfc069d3fa24d7c6357e3b731e97f94db495bf0c Mon Sep 17 00:00:00 2001 From: Sunil Mushran Date: Tue, 14 Dec 2010 14:14:31 -0800 Subject: ocfs2/cluster: Pin the local node when o2hb thread starts The patch pins the node item of the local node when the o2hb thread starts and unpins on stop. An earlier patch pinned the node item of the remote node on o2net connect and unpinned on disconnect. Signed-off-by Sunil Mushran Signed-off-by: Joel Becker --- fs/ocfs2/cluster/heartbeat.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/fs/ocfs2/cluster/heartbeat.c b/fs/ocfs2/cluster/heartbeat.c index 3722e3850a1f..8b50c1ad7a69 100644 --- a/fs/ocfs2/cluster/heartbeat.c +++ b/fs/ocfs2/cluster/heartbeat.c @@ -1083,6 +1083,9 @@ static int o2hb_thread(void *data) set_user_nice(current, -20); + /* Pin node */ + o2nm_depend_this_node(); + while (!kthread_should_stop() && !reg->hr_unclean_stop) { /* We track the time spent inside * o2hb_do_disk_heartbeat so that we avoid more than @@ -1132,6 +1135,9 @@ static int o2hb_thread(void *data) mlog_errno(ret); } + /* Unpin node */ + o2nm_undepend_this_node(); + mlog(ML_HEARTBEAT|ML_KTHREAD, "hb thread exiting\n"); return 0; -- cgit v1.2.3 From 1bf84759bdcc08933b22ee70722f1575ad84f9b9 Mon Sep 17 00:00:00 2001 From: Margarita Olaya Cabrera Date: Tue, 14 Dec 2010 19:00:21 -0600 Subject: ASoC: twl6040: Add ramp up/down volume for HS and HF Add ramp functions for the headset and handsfree outputs in order to reduce the pops during power on/off sequences. In order to give more control to volume ramp, step size and delay between steps can be specified. The patches are based on wm8350 implementation from Liam Girdwood. Signed-off-by: Margarita Olaya Cabrera Signed-off-by: Misael Lopez Cruz Acked-by: Mark Brown Signed-off-by: Liam Girdwood --- sound/soc/codecs/twl6040.c | 533 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 521 insertions(+), 12 deletions(-) diff --git a/sound/soc/codecs/twl6040.c b/sound/soc/codecs/twl6040.c index b252cf8f0ce1..2f68f5949a63 100644 --- a/sound/soc/codecs/twl6040.c +++ b/sound/soc/codecs/twl6040.c @@ -40,7 +40,35 @@ #include "twl6040.h" #define TWL6040_RATES SNDRV_PCM_RATE_8000_96000 -#define TWL6040_FORMATS (SNDRV_PCM_FMTBIT_S32_LE) +#define TWL6040_FORMATS (SNDRV_PCM_FMTBIT_S32_LE) + +#define TWL6040_OUTHS_0dB 0x00 +#define TWL6040_OUTHS_M30dB 0x0F +#define TWL6040_OUTHF_0dB 0x03 +#define TWL6040_OUTHF_M52dB 0x1D + +#define TWL6040_RAMP_NONE 0 +#define TWL6040_RAMP_UP 1 +#define TWL6040_RAMP_DOWN 2 + +#define TWL6040_HSL_VOL_MASK 0x0F +#define TWL6040_HSL_VOL_SHIFT 0 +#define TWL6040_HSR_VOL_MASK 0xF0 +#define TWL6040_HSR_VOL_SHIFT 4 +#define TWL6040_HF_VOL_MASK 0x1F +#define TWL6040_HF_VOL_SHIFT 0 + +struct twl6040_output { + u16 active; + u16 left_vol; + u16 right_vol; + u16 left_step; + u16 right_step; + unsigned int step_delay; + u16 ramp; + u16 mute; + struct completion ramp_done; +}; struct twl6040_jack_data { struct snd_soc_jack *jack; @@ -62,6 +90,12 @@ struct twl6040_data { struct workqueue_struct *workqueue; struct delayed_work delayed_work; struct mutex mutex; + struct twl6040_output headset; + struct twl6040_output handsfree; + struct workqueue_struct *hf_workqueue; + struct workqueue_struct *hs_workqueue; + struct delayed_work hs_delayed_work; + struct delayed_work hf_delayed_work; }; /* @@ -263,6 +297,305 @@ static void twl6040_init_vdd_regs(struct snd_soc_codec *codec) } } +/* + * Ramp HS PGA volume to minimise pops at stream startup and shutdown. + */ +static inline int twl6040_hs_ramp_step(struct snd_soc_codec *codec, + unsigned int left_step, unsigned int right_step) +{ + + struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec); + struct twl6040_output *headset = &priv->headset; + int left_complete = 0, right_complete = 0; + u8 reg, val; + + /* left channel */ + left_step = (left_step > 0xF) ? 0xF : left_step; + reg = twl6040_read_reg_cache(codec, TWL6040_REG_HSGAIN); + val = (~reg & TWL6040_HSL_VOL_MASK); + + if (headset->ramp == TWL6040_RAMP_UP) { + /* ramp step up */ + if (val < headset->left_vol) { + val += left_step; + reg &= ~TWL6040_HSL_VOL_MASK; + twl6040_write(codec, TWL6040_REG_HSGAIN, + (reg | (~val & TWL6040_HSL_VOL_MASK))); + } else { + left_complete = 1; + } + } else if (headset->ramp == TWL6040_RAMP_DOWN) { + /* ramp step down */ + if (val > 0x0) { + val -= left_step; + reg &= ~TWL6040_HSL_VOL_MASK; + twl6040_write(codec, TWL6040_REG_HSGAIN, reg | + (~val & TWL6040_HSL_VOL_MASK)); + } else { + left_complete = 1; + } + } + + /* right channel */ + right_step = (right_step > 0xF) ? 0xF : right_step; + reg = twl6040_read_reg_cache(codec, TWL6040_REG_HSGAIN); + val = (~reg & TWL6040_HSR_VOL_MASK) >> TWL6040_HSR_VOL_SHIFT; + + if (headset->ramp == TWL6040_RAMP_UP) { + /* ramp step up */ + if (val < headset->right_vol) { + val += right_step; + reg &= ~TWL6040_HSR_VOL_MASK; + twl6040_write(codec, TWL6040_REG_HSGAIN, + (reg | (~val << TWL6040_HSR_VOL_SHIFT))); + } else { + right_complete = 1; + } + } else if (headset->ramp == TWL6040_RAMP_DOWN) { + /* ramp step down */ + if (val > 0x0) { + val -= right_step; + reg &= ~TWL6040_HSR_VOL_MASK; + twl6040_write(codec, TWL6040_REG_HSGAIN, + reg | (~val << TWL6040_HSR_VOL_SHIFT)); + } else { + right_complete = 1; + } + } + + return left_complete & right_complete; +} + +/* + * Ramp HF PGA volume to minimise pops at stream startup and shutdown. + */ +static inline int twl6040_hf_ramp_step(struct snd_soc_codec *codec, + unsigned int left_step, unsigned int right_step) +{ + struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec); + struct twl6040_output *handsfree = &priv->handsfree; + int left_complete = 0, right_complete = 0; + u16 reg, val; + + /* left channel */ + left_step = (left_step > 0x1D) ? 0x1D : left_step; + reg = twl6040_read_reg_cache(codec, TWL6040_REG_HFLGAIN); + reg = 0x1D - reg; + val = (reg & TWL6040_HF_VOL_MASK); + if (handsfree->ramp == TWL6040_RAMP_UP) { + /* ramp step up */ + if (val < handsfree->left_vol) { + val += left_step; + reg &= ~TWL6040_HF_VOL_MASK; + twl6040_write(codec, TWL6040_REG_HFLGAIN, + reg | (0x1D - val)); + } else { + left_complete = 1; + } + } else if (handsfree->ramp == TWL6040_RAMP_DOWN) { + /* ramp step down */ + if (val > 0) { + val -= left_step; + reg &= ~TWL6040_HF_VOL_MASK; + twl6040_write(codec, TWL6040_REG_HFLGAIN, + reg | (0x1D - val)); + } else { + left_complete = 1; + } + } + + /* right channel */ + right_step = (right_step > 0x1D) ? 0x1D : right_step; + reg = twl6040_read_reg_cache(codec, TWL6040_REG_HFRGAIN); + reg = 0x1D - reg; + val = (reg & TWL6040_HF_VOL_MASK); + if (handsfree->ramp == TWL6040_RAMP_UP) { + /* ramp step up */ + if (val < handsfree->right_vol) { + val += right_step; + reg &= ~TWL6040_HF_VOL_MASK; + twl6040_write(codec, TWL6040_REG_HFRGAIN, + reg | (0x1D - val)); + } else { + right_complete = 1; + } + } else if (handsfree->ramp == TWL6040_RAMP_DOWN) { + /* ramp step down */ + if (val > 0) { + val -= right_step; + reg &= ~TWL6040_HF_VOL_MASK; + twl6040_write(codec, TWL6040_REG_HFRGAIN, + reg | (0x1D - val)); + } + } + + return left_complete & right_complete; +} + +/* + * This work ramps both output PGAs at stream start/stop time to + * minimise pop associated with DAPM power switching. + */ +static void twl6040_pga_hs_work(struct work_struct *work) +{ + struct twl6040_data *priv = + container_of(work, struct twl6040_data, hs_delayed_work.work); + struct snd_soc_codec *codec = priv->codec; + struct twl6040_output *headset = &priv->headset; + unsigned int delay = headset->step_delay; + int i, headset_complete; + + /* do we need to ramp at all ? */ + if (headset->ramp == TWL6040_RAMP_NONE) + return; + + /* HS PGA volumes have 4 bits of resolution to ramp */ + for (i = 0; i <= 16; i++) { + headset_complete = 1; + if (headset->ramp != TWL6040_RAMP_NONE) + headset_complete = twl6040_hs_ramp_step(codec, + headset->left_step, + headset->right_step); + + /* ramp finished ? */ + if (headset_complete) + break; + + /* + * TODO: tune: delay is longer over 0dB + * as increases are larger. + */ + if (i >= 8) + schedule_timeout_interruptible(msecs_to_jiffies(delay + + (delay >> 1))); + else + schedule_timeout_interruptible(msecs_to_jiffies(delay)); + } + + if (headset->ramp == TWL6040_RAMP_DOWN) { + headset->active = 0; + complete(&headset->ramp_done); + } else { + headset->active = 1; + } + headset->ramp = TWL6040_RAMP_NONE; +} + +static void twl6040_pga_hf_work(struct work_struct *work) +{ + struct twl6040_data *priv = + container_of(work, struct twl6040_data, hf_delayed_work.work); + struct snd_soc_codec *codec = priv->codec; + struct twl6040_output *handsfree = &priv->handsfree; + unsigned int delay = handsfree->step_delay; + int i, handsfree_complete; + + /* do we need to ramp at all ? */ + if (handsfree->ramp == TWL6040_RAMP_NONE) + return; + + /* HF PGA volumes have 5 bits of resolution to ramp */ + for (i = 0; i <= 32; i++) { + handsfree_complete = 1; + if (handsfree->ramp != TWL6040_RAMP_NONE) + handsfree_complete = twl6040_hf_ramp_step(codec, + handsfree->left_step, + handsfree->right_step); + + /* ramp finished ? */ + if (handsfree_complete) + break; + + /* + * TODO: tune: delay is longer over 0dB + * as increases are larger. + */ + if (i >= 16) + schedule_timeout_interruptible(msecs_to_jiffies(delay + + (delay >> 1))); + else + schedule_timeout_interruptible(msecs_to_jiffies(delay)); + } + + + if (handsfree->ramp == TWL6040_RAMP_DOWN) { + handsfree->active = 0; + complete(&handsfree->ramp_done); + } else + handsfree->active = 1; + handsfree->ramp = TWL6040_RAMP_NONE; +} + +static int pga_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec = w->codec; + struct twl6040_data *priv = snd_soc_codec_get_drvdata(codec); + struct twl6040_output *out; + struct delayed_work *work; + struct workqueue_struct *queue; + + switch (w->shift) { + case 2: + case 3: + out = &priv->headset; + work = &priv->hs_delayed_work; + queue = priv->hs_workqueue; + out->step_delay = 5; /* 5 ms between volume ramp steps */ + break; + case 4: + out = &priv->handsfree; + work = &priv->hf_delayed_work; + queue = priv->hf_workqueue; + out->step_delay = 5; /* 5 ms between volume ramp steps */ + if (SND_SOC_DAPM_EVENT_ON(event)) + priv->non_lp++; + else + priv->non_lp--; + break; + default: + return -1; + } + + switch (event) { + case SND_SOC_DAPM_POST_PMU: + if (out->active) + break; + + /* don't use volume ramp for power-up */ + out->left_step = out->left_vol; + out->right_step = out->right_vol; + + if (!delayed_work_pending(work)) { + out->ramp = TWL6040_RAMP_UP; + queue_delayed_work(queue, work, + msecs_to_jiffies(1)); + } + break; + + case SND_SOC_DAPM_PRE_PMD: + if (!out->active) + break; + + if (!delayed_work_pending(work)) { + /* use volume ramp for power-down */ + out->left_step = 1; + out->right_step = 1; + out->ramp = TWL6040_RAMP_DOWN; + INIT_COMPLETION(out->ramp_done); + + queue_delayed_work(queue, work, + msecs_to_jiffies(1)); + + wait_for_completion_timeout(&out->ramp_done, + msecs_to_jiffies(2000)); + } + break; + } + + return 0; +} + /* twl6040 codec manual power-up sequence */ static void twl6040_power_up(struct snd_soc_codec *codec) { @@ -463,6 +796,156 @@ static irqreturn_t twl6040_naudint_handler(int irq, void *data) return IRQ_HANDLED; } +static int twl6040_put_volsw(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct twl6040_data *twl6040_priv = snd_soc_codec_get_drvdata(codec); + struct twl6040_output *out = NULL; + struct soc_mixer_control *mc = + (struct soc_mixer_control *)kcontrol->private_value; + int ret; + unsigned int reg = mc->reg; + + /* For HS and HF we shadow the values and only actually write + * them out when active in order to ensure the amplifier comes on + * as quietly as possible. */ + switch (reg) { + case TWL6040_REG_HSGAIN: + out = &twl6040_priv->headset; + break; + default: + break; + } + + if (out) { + out->left_vol = ucontrol->value.integer.value[0]; + out->right_vol = ucontrol->value.integer.value[1]; + if (!out->active) + return 1; + } + + ret = snd_soc_put_volsw(kcontrol, ucontrol); + if (ret < 0) + return ret; + + return 1; +} + +static int twl6040_get_volsw(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct twl6040_data *twl6040_priv = snd_soc_codec_get_drvdata(codec); + struct twl6040_output *out = &twl6040_priv->headset; + struct soc_mixer_control *mc = + (struct soc_mixer_control *)kcontrol->private_value; + unsigned int reg = mc->reg; + + switch (reg) { + case TWL6040_REG_HSGAIN: + out = &twl6040_priv->headset; + ucontrol->value.integer.value[0] = out->left_vol; + ucontrol->value.integer.value[1] = out->right_vol; + return 0; + + default: + break; + } + + return snd_soc_get_volsw(kcontrol, ucontrol); +} + +static int twl6040_put_volsw_2r_vu(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct twl6040_data *twl6040_priv = snd_soc_codec_get_drvdata(codec); + struct twl6040_output *out = NULL; + struct soc_mixer_control *mc = + (struct soc_mixer_control *)kcontrol->private_value; + int ret; + unsigned int reg = mc->reg; + + /* For HS and HF we shadow the values and only actually write + * them out when active in order to ensure the amplifier comes on + * as quietly as possible. */ + switch (reg) { + case TWL6040_REG_HFLGAIN: + case TWL6040_REG_HFRGAIN: + out = &twl6040_priv->handsfree; + break; + default: + break; + } + + if (out) { + out->left_vol = ucontrol->value.integer.value[0]; + out->right_vol = ucontrol->value.integer.value[1]; + if (!out->active) + return 1; + } + + ret = snd_soc_put_volsw_2r(kcontrol, ucontrol); + if (ret < 0) + return ret; + + return 1; +} + +static int twl6040_get_volsw_2r(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); + struct twl6040_data *twl6040_priv = snd_soc_codec_get_drvdata(codec); + struct twl6040_output *out = &twl6040_priv->handsfree; + struct soc_mixer_control *mc = + (struct soc_mixer_control *)kcontrol->private_value; + unsigned int reg = mc->reg; + + /* If these are cached registers use the cache */ + switch (reg) { + case TWL6040_REG_HFLGAIN: + case TWL6040_REG_HFRGAIN: + out = &twl6040_priv->handsfree; + ucontrol->value.integer.value[0] = out->left_vol; + ucontrol->value.integer.value[1] = out->right_vol; + return 0; + + default: + break; + } + + return snd_soc_get_volsw_2r(kcontrol, ucontrol); +} + +/* double control with volume update */ +#define SOC_TWL6040_DOUBLE_TLV(xname, xreg, shift_left, shift_right, xmax,\ + xinvert, tlv_array)\ +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\ + .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ |\ + SNDRV_CTL_ELEM_ACCESS_READWRITE,\ + .tlv.p = (tlv_array), \ + .info = snd_soc_info_volsw, .get = twl6040_get_volsw, \ + .put = twl6040_put_volsw, \ + .private_value = (unsigned long)&(struct soc_mixer_control) \ + {.reg = xreg, .shift = shift_left, .rshift = shift_right,\ + .max = xmax, .platform_max = xmax, .invert = xinvert} } + +/* double control with volume update */ +#define SOC_TWL6040_DOUBLE_R_TLV(xname, reg_left, reg_right, xshift, xmax,\ + xinvert, tlv_array)\ +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname),\ + .access = SNDRV_CTL_ELEM_ACCESS_TLV_READ | \ + SNDRV_CTL_ELEM_ACCESS_READWRITE | \ + SNDRV_CTL_ELEM_ACCESS_VOLATILE, \ + .tlv.p = (tlv_array), \ + .info = snd_soc_info_volsw_2r, \ + .get = twl6040_get_volsw_2r, .put = twl6040_put_volsw_2r_vu, \ + .private_value = (unsigned long)&(struct soc_mixer_control) \ + {.reg = reg_left, .rreg = reg_right, .shift = xshift, \ + .rshift = xshift, .max = xmax, .invert = xinvert}, } + /* * MICATT volume control: * from -6 to 0 dB in 6 dB steps @@ -569,9 +1052,9 @@ static const struct snd_kcontrol_new twl6040_snd_controls[] = { TWL6040_REG_LINEGAIN, 0, 4, 0xF, 0, afm_amp_tlv), /* Playback gains */ - SOC_DOUBLE_TLV("Headset Playback Volume", + SOC_TWL6040_DOUBLE_TLV("Headset Playback Volume", TWL6040_REG_HSGAIN, 0, 4, 0xF, 1, hs_tlv), - SOC_DOUBLE_R_TLV("Handsfree Playback Volume", + SOC_TWL6040_DOUBLE_R_TLV("Handsfree Playback Volume", TWL6040_REG_HFLGAIN, TWL6040_REG_HFRGAIN, 0, 0x1D, 1, hf_tlv), SOC_SINGLE_TLV("Earphone Playback Volume", TWL6040_REG_EARCTL, 1, 0xF, 1, ep_tlv), @@ -657,16 +1140,20 @@ static const struct snd_soc_dapm_widget twl6040_dapm_widgets[] = { /* Analog playback drivers */ SND_SOC_DAPM_PGA_E("Handsfree Left Driver", TWL6040_REG_HFLCTL, 4, 0, NULL, 0, - twl6040_power_mode_event, - SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), + pga_event, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), SND_SOC_DAPM_PGA_E("Handsfree Right Driver", TWL6040_REG_HFRCTL, 4, 0, NULL, 0, - twl6040_power_mode_event, - SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD), - SND_SOC_DAPM_PGA("Headset Left Driver", - TWL6040_REG_HSLCTL, 2, 0, NULL, 0), - SND_SOC_DAPM_PGA("Headset Right Driver", - TWL6040_REG_HSRCTL, 2, 0, NULL, 0), + pga_event, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), + SND_SOC_DAPM_PGA_E("Headset Left Driver", + TWL6040_REG_HSLCTL, 2, 0, NULL, 0, + pga_event, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), + SND_SOC_DAPM_PGA_E("Headset Right Driver", + TWL6040_REG_HSRCTL, 2, 0, NULL, 0, + pga_event, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), SND_SOC_DAPM_SWITCH_E("Earphone Driver", SND_SOC_NOPM, 0, 0, &ep_driver_switch_controls, twl6040_power_mode_event, @@ -1150,6 +1637,8 @@ static int twl6040_probe(struct snd_soc_codec *codec) mutex_init(&priv->mutex); init_completion(&priv->ready); + init_completion(&priv->headset.ramp_done); + init_completion(&priv->handsfree.ramp_done); if (gpio_is_valid(audpwron)) { ret = gpio_request(audpwron, "audpwron"); @@ -1183,10 +1672,24 @@ static int twl6040_probe(struct snd_soc_codec *codec) /* init vio registers */ twl6040_init_vio_regs(codec); + priv->hf_workqueue = create_singlethread_workqueue("twl6040-hf"); + if (priv->hf_workqueue == NULL) { + ret = -ENOMEM; + goto irq_err; + } + priv->hs_workqueue = create_singlethread_workqueue("twl6040-hs"); + if (priv->hs_workqueue == NULL) { + ret = -ENOMEM; + goto wq_err; + } + + INIT_DELAYED_WORK(&priv->hs_delayed_work, twl6040_pga_hs_work); + INIT_DELAYED_WORK(&priv->hf_delayed_work, twl6040_pga_hf_work); + /* power on device */ ret = twl6040_set_bias_level(codec, SND_SOC_BIAS_STANDBY); if (ret) - goto irq_err; + goto bias_err; snd_soc_add_controls(codec, twl6040_snd_controls, ARRAY_SIZE(twl6040_snd_controls)); @@ -1194,6 +1697,10 @@ static int twl6040_probe(struct snd_soc_codec *codec) return 0; +bias_err: + destroy_workqueue(priv->hs_workqueue); +wq_err: + destroy_workqueue(priv->hf_workqueue); irq_err: if (naudint) free_irq(naudint, codec); @@ -1222,6 +1729,8 @@ static int twl6040_remove(struct snd_soc_codec *codec) free_irq(naudint, codec); destroy_workqueue(priv->workqueue); + destroy_workqueue(priv->hf_workqueue); + destroy_workqueue(priv->hs_workqueue); kfree(priv); return 0; -- cgit v1.2.3 From eeb433876cf59438a1e1600a957ff6cc99c860eb Mon Sep 17 00:00:00 2001 From: Anisse Astier Date: Thu, 16 Dec 2010 12:19:47 +0100 Subject: ALSA: hda - factorize an automute_mic realtek quirk function Multiple quirk functions were using the exact same code to verify if the Mic jack was plugged and mute the Mic accordingly Signed-off-by: Anisse Astier Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 35 +++++++---------------------------- 1 file changed, 7 insertions(+), 28 deletions(-) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index cd2d3a5efa50..fc435b59a52f 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -3352,7 +3352,7 @@ static struct hda_verb alc880_beep_init_verbs[] = { }; /* auto-toggle front mic */ -static void alc880_uniwill_mic_automute(struct hda_codec *codec) +static void alc88x_simple_mic_automute(struct hda_codec *codec) { unsigned int present; unsigned char bits; @@ -3374,7 +3374,7 @@ static void alc880_uniwill_setup(struct hda_codec *codec) static void alc880_uniwill_init_hook(struct hda_codec *codec) { alc_automute_amp(codec); - alc880_uniwill_mic_automute(codec); + alc88x_simple_mic_automute(codec); } static void alc880_uniwill_unsol_event(struct hda_codec *codec, @@ -3385,7 +3385,7 @@ static void alc880_uniwill_unsol_event(struct hda_codec *codec, */ switch (res >> 28) { case ALC880_MIC_EVENT: - alc880_uniwill_mic_automute(codec); + alc88x_simple_mic_automute(codec); break; default: alc_automute_amp_unsol_event(codec, res); @@ -9480,15 +9480,6 @@ static void alc883_lenovo_nb0763_setup(struct hda_codec *codec) #define alc883_targa_init_hook alc882_targa_init_hook #define alc883_targa_unsol_event alc882_targa_unsol_event -static void alc883_clevo_m720_mic_automute(struct hda_codec *codec) -{ - unsigned int present; - - present = snd_hda_jack_detect(codec, 0x18); - snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, - HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); -} - static void alc883_clevo_m720_setup(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; @@ -9500,7 +9491,7 @@ static void alc883_clevo_m720_setup(struct hda_codec *codec) static void alc883_clevo_m720_init_hook(struct hda_codec *codec) { alc_automute_amp(codec); - alc883_clevo_m720_mic_automute(codec); + alc88x_simple_mic_automute(codec); } static void alc883_clevo_m720_unsol_event(struct hda_codec *codec, @@ -9508,7 +9499,7 @@ static void alc883_clevo_m720_unsol_event(struct hda_codec *codec, { switch (res >> 26) { case ALC880_MIC_EVENT: - alc883_clevo_m720_mic_automute(codec); + alc88x_simple_mic_automute(codec); break; default: alc_automute_amp_unsol_event(codec, res); @@ -16697,18 +16688,6 @@ static struct hda_verb alc861vd_lenovo_unsol_verbs[] = { {} }; -static void alc861vd_lenovo_mic_automute(struct hda_codec *codec) -{ - unsigned int present; - unsigned char bits; - - present = snd_hda_jack_detect(codec, 0x18); - bits = present ? HDA_AMP_MUTE : 0; - - snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, - HDA_AMP_MUTE, bits); -} - static void alc861vd_lenovo_setup(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; @@ -16719,7 +16698,7 @@ static void alc861vd_lenovo_setup(struct hda_codec *codec) static void alc861vd_lenovo_init_hook(struct hda_codec *codec) { alc_automute_amp(codec); - alc861vd_lenovo_mic_automute(codec); + alc88x_simple_mic_automute(codec); } static void alc861vd_lenovo_unsol_event(struct hda_codec *codec, @@ -16727,7 +16706,7 @@ static void alc861vd_lenovo_unsol_event(struct hda_codec *codec, { switch (res >> 26) { case ALC880_MIC_EVENT: - alc861vd_lenovo_mic_automute(codec); + alc88x_simple_mic_automute(codec); break; default: alc_automute_amp_unsol_event(codec, res); -- cgit v1.2.3 From dddd9dc340ae1a41d90e084529ca979c77c4ecfe Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 8 Dec 2010 20:57:35 +0100 Subject: block: kill genhd_media_change_notify() There's no user of the facility. Kill it. Signed-off-by: Tejun Heo Signed-off-by: Jens Axboe --- block/genhd.c | 25 ------------------------- include/linux/genhd.h | 1 - 2 files changed, 26 deletions(-) diff --git a/block/genhd.c b/block/genhd.c index 5fa2b44a72ff..0905ab22c8cf 100644 --- a/block/genhd.c +++ b/block/genhd.c @@ -1110,29 +1110,6 @@ static int __init proc_genhd_init(void) module_init(proc_genhd_init); #endif /* CONFIG_PROC_FS */ -static void media_change_notify_thread(struct work_struct *work) -{ - struct gendisk *gd = container_of(work, struct gendisk, async_notify); - char event[] = "MEDIA_CHANGE=1"; - char *envp[] = { event, NULL }; - - /* - * set enviroment vars to indicate which event this is for - * so that user space will know to go check the media status. - */ - kobject_uevent_env(&disk_to_dev(gd)->kobj, KOBJ_CHANGE, envp); - put_device(gd->driverfs_dev); -} - -#if 0 -void genhd_media_change_notify(struct gendisk *disk) -{ - get_device(disk->driverfs_dev); - schedule_work(&disk->async_notify); -} -EXPORT_SYMBOL_GPL(genhd_media_change_notify); -#endif /* 0 */ - dev_t blk_lookup_devt(const char *name, int partno) { dev_t devt = MKDEV(0, 0); @@ -1198,8 +1175,6 @@ struct gendisk *alloc_disk_node(int minors, int node_id) disk_to_dev(disk)->class = &block_class; disk_to_dev(disk)->type = &disk_type; device_initialize(disk_to_dev(disk)); - INIT_WORK(&disk->async_notify, - media_change_notify_thread); } return disk; } diff --git a/include/linux/genhd.h b/include/linux/genhd.h index 7a7b9c1644e4..5e4e6928387c 100644 --- a/include/linux/genhd.h +++ b/include/linux/genhd.h @@ -173,7 +173,6 @@ struct gendisk { struct timer_rand_state *random; atomic_t sync_io; /* RAID */ - struct work_struct async_notify; #ifdef CONFIG_BLK_DEV_INTEGRITY struct blk_integrity *integrity; #endif -- cgit v1.2.3 From d2bf1b6723ed0eab378363649d15b7893bf14e91 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 8 Dec 2010 20:57:36 +0100 Subject: block: move register_disk() and del_gendisk() to block/genhd.c There's no reason for register_disk() and del_gendisk() to be in fs/partitions/check.c. Move both to genhd.c. While at it, collapse unlink_gendisk(), which was artificially in a separate function due to genhd.c / check.c split, into del_gendisk(). Signed-off-by: Tejun Heo Signed-off-by: Jens Axboe --- block/genhd.c | 90 ++++++++++++++++++++++++++++++++++++++++++++++++-- fs/partitions/check.c | 89 ------------------------------------------------- include/linux/blkdev.h | 1 - include/linux/genhd.h | 1 - 4 files changed, 87 insertions(+), 94 deletions(-) diff --git a/block/genhd.c b/block/genhd.c index 0905ab22c8cf..2e5e4c0a1133 100644 --- a/block/genhd.c +++ b/block/genhd.c @@ -502,6 +502,64 @@ static int exact_lock(dev_t devt, void *data) return 0; } +void register_disk(struct gendisk *disk) +{ + struct device *ddev = disk_to_dev(disk); + struct block_device *bdev; + struct disk_part_iter piter; + struct hd_struct *part; + int err; + + ddev->parent = disk->driverfs_dev; + + dev_set_name(ddev, disk->disk_name); + + /* delay uevents, until we scanned partition table */ + dev_set_uevent_suppress(ddev, 1); + + if (device_add(ddev)) + return; + if (!sysfs_deprecated) { + err = sysfs_create_link(block_depr, &ddev->kobj, + kobject_name(&ddev->kobj)); + if (err) { + device_del(ddev); + return; + } + } + disk->part0.holder_dir = kobject_create_and_add("holders", &ddev->kobj); + disk->slave_dir = kobject_create_and_add("slaves", &ddev->kobj); + + /* No minors to use for partitions */ + if (!disk_partitionable(disk)) + goto exit; + + /* No such device (e.g., media were just removed) */ + if (!get_capacity(disk)) + goto exit; + + bdev = bdget_disk(disk, 0); + if (!bdev) + goto exit; + + bdev->bd_invalidated = 1; + err = blkdev_get(bdev, FMODE_READ, NULL); + if (err < 0) + goto exit; + blkdev_put(bdev, FMODE_READ); + +exit: + /* announce disk after possible partitions are created */ + dev_set_uevent_suppress(ddev, 0); + kobject_uevent(&ddev->kobj, KOBJ_ADD); + + /* announce possible partitions */ + disk_part_iter_init(&piter, disk, 0); + while ((part = disk_part_iter_next(&piter))) + kobject_uevent(&part_to_dev(part)->kobj, KOBJ_ADD); + disk_part_iter_exit(&piter); +} + /** * add_disk - add partitioning information to kernel list * @disk: per-device partitioning information @@ -552,17 +610,43 @@ void add_disk(struct gendisk *disk) "bdi"); WARN_ON(retval); } - EXPORT_SYMBOL(add_disk); -EXPORT_SYMBOL(del_gendisk); /* in partitions/check.c */ -void unlink_gendisk(struct gendisk *disk) +void del_gendisk(struct gendisk *disk) { + struct disk_part_iter piter; + struct hd_struct *part; + + /* invalidate stuff */ + disk_part_iter_init(&piter, disk, + DISK_PITER_INCL_EMPTY | DISK_PITER_REVERSE); + while ((part = disk_part_iter_next(&piter))) { + invalidate_partition(disk, part->partno); + delete_partition(disk, part->partno); + } + disk_part_iter_exit(&piter); + + invalidate_partition(disk, 0); + blk_free_devt(disk_to_dev(disk)->devt); + set_capacity(disk, 0); + disk->flags &= ~GENHD_FL_UP; + sysfs_remove_link(&disk_to_dev(disk)->kobj, "bdi"); bdi_unregister(&disk->queue->backing_dev_info); blk_unregister_queue(disk); blk_unregister_region(disk_devt(disk), disk->minors); + + part_stat_set_all(&disk->part0, 0); + disk->part0.stamp = 0; + + kobject_put(disk->part0.holder_dir); + kobject_put(disk->slave_dir); + disk->driverfs_dev = NULL; + if (!sysfs_deprecated) + sysfs_remove_link(block_depr, dev_name(disk_to_dev(disk))); + device_del(disk_to_dev(disk)); } +EXPORT_SYMBOL(del_gendisk); /** * get_gendisk - get partitioning information for a given device diff --git a/fs/partitions/check.c b/fs/partitions/check.c index bdf8d3cc95a4..9a48d65d9855 100644 --- a/fs/partitions/check.c +++ b/fs/partitions/check.c @@ -516,65 +516,6 @@ out_put: return ERR_PTR(err); } -/* Not exported, helper to add_disk(). */ -void register_disk(struct gendisk *disk) -{ - struct device *ddev = disk_to_dev(disk); - struct block_device *bdev; - struct disk_part_iter piter; - struct hd_struct *part; - int err; - - ddev->parent = disk->driverfs_dev; - - dev_set_name(ddev, disk->disk_name); - - /* delay uevents, until we scanned partition table */ - dev_set_uevent_suppress(ddev, 1); - - if (device_add(ddev)) - return; - if (!sysfs_deprecated) { - err = sysfs_create_link(block_depr, &ddev->kobj, - kobject_name(&ddev->kobj)); - if (err) { - device_del(ddev); - return; - } - } - disk->part0.holder_dir = kobject_create_and_add("holders", &ddev->kobj); - disk->slave_dir = kobject_create_and_add("slaves", &ddev->kobj); - - /* No minors to use for partitions */ - if (!disk_partitionable(disk)) - goto exit; - - /* No such device (e.g., media were just removed) */ - if (!get_capacity(disk)) - goto exit; - - bdev = bdget_disk(disk, 0); - if (!bdev) - goto exit; - - bdev->bd_invalidated = 1; - err = blkdev_get(bdev, FMODE_READ, NULL); - if (err < 0) - goto exit; - blkdev_put(bdev, FMODE_READ); - -exit: - /* announce disk after possible partitions are created */ - dev_set_uevent_suppress(ddev, 0); - kobject_uevent(&ddev->kobj, KOBJ_ADD); - - /* announce possible partitions */ - disk_part_iter_init(&piter, disk, 0); - while ((part = disk_part_iter_next(&piter))) - kobject_uevent(&part_to_dev(part)->kobj, KOBJ_ADD); - disk_part_iter_exit(&piter); -} - static bool disk_unlock_native_capacity(struct gendisk *disk) { const struct block_device_operations *bdops = disk->fops; @@ -737,33 +678,3 @@ fail: } EXPORT_SYMBOL(read_dev_sector); - -void del_gendisk(struct gendisk *disk) -{ - struct disk_part_iter piter; - struct hd_struct *part; - - /* invalidate stuff */ - disk_part_iter_init(&piter, disk, - DISK_PITER_INCL_EMPTY | DISK_PITER_REVERSE); - while ((part = disk_part_iter_next(&piter))) { - invalidate_partition(disk, part->partno); - delete_partition(disk, part->partno); - } - disk_part_iter_exit(&piter); - - invalidate_partition(disk, 0); - blk_free_devt(disk_to_dev(disk)->devt); - set_capacity(disk, 0); - disk->flags &= ~GENHD_FL_UP; - unlink_gendisk(disk); - part_stat_set_all(&disk->part0, 0); - disk->part0.stamp = 0; - - kobject_put(disk->part0.holder_dir); - kobject_put(disk->slave_dir); - disk->driverfs_dev = NULL; - if (!sysfs_deprecated) - sysfs_remove_link(block_depr, dev_name(disk_to_dev(disk))); - device_del(disk_to_dev(disk)); -} diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index aae86fd10c4f..83031bcf8366 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -643,7 +643,6 @@ static inline void rq_flush_dcache_pages(struct request *rq) extern int blk_register_queue(struct gendisk *disk); extern void blk_unregister_queue(struct gendisk *disk); -extern void register_disk(struct gendisk *dev); extern void generic_make_request(struct bio *bio); extern void blk_rq_init(struct request_queue *q, struct request *rq); extern void blk_put_request(struct request *); diff --git a/include/linux/genhd.h b/include/linux/genhd.h index 5e4e6928387c..56e17ed24816 100644 --- a/include/linux/genhd.h +++ b/include/linux/genhd.h @@ -394,7 +394,6 @@ extern void part_round_stats(int cpu, struct hd_struct *part); /* block/genhd.c */ extern void add_disk(struct gendisk *disk); extern void del_gendisk(struct gendisk *gp); -extern void unlink_gendisk(struct gendisk *gp); extern struct gendisk *get_gendisk(dev_t dev, int *partno); extern struct block_device *bdget_disk(struct gendisk *disk, int partno); -- cgit v1.2.3 From 77ea887e433ad8389d416826936c110fa7910f80 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 8 Dec 2010 20:57:37 +0100 Subject: implement in-kernel gendisk events handling Currently, media presence polling for removeable block devices is done from userland. There are several issues with this. * Polling is done by periodically opening the device. For SCSI devices, the command sequence generated by such action involves a few different commands including TEST_UNIT_READY. This behavior, while perfectly legal, is different from Windows which only issues single command, GET_EVENT_STATUS_NOTIFICATION. Unfortunately, some ATAPI devices lock up after being periodically queried such command sequences. * There is no reliable and unintrusive way for a userland program to tell whether the target device is safe for media presence polling. For example, polling for media presence during an on-going burning session can make it fail. The polling program can avoid this by opening the device with O_EXCL but then it risks making a valid exclusive user of the device fail w/ -EBUSY. * Userland polling is unnecessarily heavy and in-kernel implementation is lighter and better coordinated (workqueue, timer slack). This patch implements framework for in-kernel disk event handling, which includes media presence polling. * bdops->check_events() is added, which supercedes ->media_changed(). It should check whether there's any pending event and return if so. Currently, two events are defined - DISK_EVENT_MEDIA_CHANGE and DISK_EVENT_EJECT_REQUEST. ->check_events() is guaranteed not to be called parallelly. * gendisk->events and ->async_events are added. These should be initialized by block driver before passing the device to add_disk(). The former contains the mask of all supported events and the latter the mask of all events which the device can report without polling. /sys/block/*/events[_async] export these to userland. * Kernel parameter block.events_dfl_poll_msecs controls the system polling interval (default is 0 which means disable) and /sys/block/*/events_poll_msecs control polling intervals for individual devices (default is -1 meaning use system setting). Note that if a device can report all supported events asynchronously and its polling interval isn't explicitly set, the device won't be polled regardless of the system polling interval. * If a device is opened exclusively with write access, event checking is automatically disabled until all write exclusive accesses are released. * There are event 'clearing' events. For example, both of currently defined events are cleared after the device has been successfully opened. This information is passed to ->check_events() callback using @clearing argument as a hint. * Event checking is always performed from system_nrt_wq and timer slack is set to 25% for polling. * Nothing changes for drivers which implement ->media_changed() but not ->check_events(). Going forward, all drivers will be converted to ->check_events() and ->media_change() will be dropped. Signed-off-by: Tejun Heo Cc: Kay Sievers Cc: Jan Kara Signed-off-by: Jens Axboe --- block/genhd.c | 429 +++++++++++++++++++++++++++++++++++++++++++++++++ fs/block_dev.c | 41 ++++- include/linux/blkdev.h | 3 + include/linux/fs.h | 1 + include/linux/genhd.h | 18 ++- 5 files changed, 484 insertions(+), 8 deletions(-) diff --git a/block/genhd.c b/block/genhd.c index 2e5e4c0a1133..5465a824d489 100644 --- a/block/genhd.c +++ b/block/genhd.c @@ -18,6 +18,7 @@ #include #include #include +#include #include "blk.h" @@ -35,6 +36,10 @@ static DEFINE_IDR(ext_devt_idr); static struct device_type disk_type; +static void disk_add_events(struct gendisk *disk); +static void disk_del_events(struct gendisk *disk); +static void disk_release_events(struct gendisk *disk); + /** * disk_get_part - get partition * @disk: disk to look partition from @@ -609,6 +614,8 @@ void add_disk(struct gendisk *disk) retval = sysfs_create_link(&disk_to_dev(disk)->kobj, &bdi->dev->kobj, "bdi"); WARN_ON(retval); + + disk_add_events(disk); } EXPORT_SYMBOL(add_disk); @@ -617,6 +624,8 @@ void del_gendisk(struct gendisk *disk) struct disk_part_iter piter; struct hd_struct *part; + disk_del_events(disk); + /* invalidate stuff */ disk_part_iter_init(&piter, disk, DISK_PITER_INCL_EMPTY | DISK_PITER_REVERSE); @@ -1089,6 +1098,7 @@ static void disk_release(struct device *dev) { struct gendisk *disk = dev_to_disk(dev); + disk_release_events(disk); kfree(disk->random); disk_replace_part_tbl(disk, NULL); free_part_stats(&disk->part0); @@ -1350,3 +1360,422 @@ int invalidate_partition(struct gendisk *disk, int partno) } EXPORT_SYMBOL(invalidate_partition); + +/* + * Disk events - monitor disk events like media change and eject request. + */ +struct disk_events { + struct list_head node; /* all disk_event's */ + struct gendisk *disk; /* the associated disk */ + spinlock_t lock; + + int block; /* event blocking depth */ + unsigned int pending; /* events already sent out */ + unsigned int clearing; /* events being cleared */ + + long poll_msecs; /* interval, -1 for default */ + struct delayed_work dwork; +}; + +static const char *disk_events_strs[] = { + [ilog2(DISK_EVENT_MEDIA_CHANGE)] = "media_change", + [ilog2(DISK_EVENT_EJECT_REQUEST)] = "eject_request", +}; + +static char *disk_uevents[] = { + [ilog2(DISK_EVENT_MEDIA_CHANGE)] = "DISK_MEDIA_CHANGE=1", + [ilog2(DISK_EVENT_EJECT_REQUEST)] = "DISK_EJECT_REQUEST=1", +}; + +/* list of all disk_events */ +static DEFINE_MUTEX(disk_events_mutex); +static LIST_HEAD(disk_events); + +/* disable in-kernel polling by default */ +static unsigned long disk_events_dfl_poll_msecs = 0; + +static unsigned long disk_events_poll_jiffies(struct gendisk *disk) +{ + struct disk_events *ev = disk->ev; + long intv_msecs = 0; + + /* + * If device-specific poll interval is set, always use it. If + * the default is being used, poll iff there are events which + * can't be monitored asynchronously. + */ + if (ev->poll_msecs >= 0) + intv_msecs = ev->poll_msecs; + else if (disk->events & ~disk->async_events) + intv_msecs = disk_events_dfl_poll_msecs; + + return msecs_to_jiffies(intv_msecs); +} + +static void __disk_block_events(struct gendisk *disk, bool sync) +{ + struct disk_events *ev = disk->ev; + unsigned long flags; + bool cancel; + + spin_lock_irqsave(&ev->lock, flags); + cancel = !ev->block++; + spin_unlock_irqrestore(&ev->lock, flags); + + if (cancel) { + if (sync) + cancel_delayed_work_sync(&disk->ev->dwork); + else + cancel_delayed_work(&disk->ev->dwork); + } +} + +static void __disk_unblock_events(struct gendisk *disk, bool check_now) +{ + struct disk_events *ev = disk->ev; + unsigned long intv; + unsigned long flags; + + spin_lock_irqsave(&ev->lock, flags); + + if (WARN_ON_ONCE(ev->block <= 0)) + goto out_unlock; + + if (--ev->block) + goto out_unlock; + + /* + * Not exactly a latency critical operation, set poll timer + * slack to 25% and kick event check. + */ + intv = disk_events_poll_jiffies(disk); + set_timer_slack(&ev->dwork.timer, intv / 4); + if (check_now) + queue_delayed_work(system_nrt_wq, &ev->dwork, 0); + else if (intv) + queue_delayed_work(system_nrt_wq, &ev->dwork, intv); +out_unlock: + spin_unlock_irqrestore(&ev->lock, flags); +} + +/** + * disk_block_events - block and flush disk event checking + * @disk: disk to block events for + * + * On return from this function, it is guaranteed that event checking + * isn't in progress and won't happen until unblocked by + * disk_unblock_events(). Events blocking is counted and the actual + * unblocking happens after the matching number of unblocks are done. + * + * Note that this intentionally does not block event checking from + * disk_clear_events(). + * + * CONTEXT: + * Might sleep. + */ +void disk_block_events(struct gendisk *disk) +{ + if (disk->ev) + __disk_block_events(disk, true); +} + +/** + * disk_unblock_events - unblock disk event checking + * @disk: disk to unblock events for + * + * Undo disk_block_events(). When the block count reaches zero, it + * starts events polling if configured. + * + * CONTEXT: + * Don't care. Safe to call from irq context. + */ +void disk_unblock_events(struct gendisk *disk) +{ + if (disk->ev) + __disk_unblock_events(disk, true); +} + +/** + * disk_check_events - schedule immediate event checking + * @disk: disk to check events for + * + * Schedule immediate event checking on @disk if not blocked. + * + * CONTEXT: + * Don't care. Safe to call from irq context. + */ +void disk_check_events(struct gendisk *disk) +{ + if (disk->ev) { + __disk_block_events(disk, false); + __disk_unblock_events(disk, true); + } +} +EXPORT_SYMBOL_GPL(disk_check_events); + +/** + * disk_clear_events - synchronously check, clear and return pending events + * @disk: disk to fetch and clear events from + * @mask: mask of events to be fetched and clearted + * + * Disk events are synchronously checked and pending events in @mask + * are cleared and returned. This ignores the block count. + * + * CONTEXT: + * Might sleep. + */ +unsigned int disk_clear_events(struct gendisk *disk, unsigned int mask) +{ + const struct block_device_operations *bdops = disk->fops; + struct disk_events *ev = disk->ev; + unsigned int pending; + + if (!ev) { + /* for drivers still using the old ->media_changed method */ + if ((mask & DISK_EVENT_MEDIA_CHANGE) && + bdops->media_changed && bdops->media_changed(disk)) + return DISK_EVENT_MEDIA_CHANGE; + return 0; + } + + /* tell the workfn about the events being cleared */ + spin_lock_irq(&ev->lock); + ev->clearing |= mask; + spin_unlock_irq(&ev->lock); + + /* uncondtionally schedule event check and wait for it to finish */ + __disk_block_events(disk, true); + queue_delayed_work(system_nrt_wq, &ev->dwork, 0); + flush_delayed_work(&ev->dwork); + __disk_unblock_events(disk, false); + + /* then, fetch and clear pending events */ + spin_lock_irq(&ev->lock); + WARN_ON_ONCE(ev->clearing & mask); /* cleared by workfn */ + pending = ev->pending & mask; + ev->pending &= ~mask; + spin_unlock_irq(&ev->lock); + + return pending; +} + +static void disk_events_workfn(struct work_struct *work) +{ + struct delayed_work *dwork = to_delayed_work(work); + struct disk_events *ev = container_of(dwork, struct disk_events, dwork); + struct gendisk *disk = ev->disk; + char *envp[ARRAY_SIZE(disk_uevents) + 1] = { }; + unsigned int clearing = ev->clearing; + unsigned int events; + unsigned long intv; + int nr_events = 0, i; + + /* check events */ + events = disk->fops->check_events(disk, clearing); + + /* accumulate pending events and schedule next poll if necessary */ + spin_lock_irq(&ev->lock); + + events &= ~ev->pending; + ev->pending |= events; + ev->clearing &= ~clearing; + + intv = disk_events_poll_jiffies(disk); + if (!ev->block && intv) + queue_delayed_work(system_nrt_wq, &ev->dwork, intv); + + spin_unlock_irq(&ev->lock); + + /* tell userland about new events */ + for (i = 0; i < ARRAY_SIZE(disk_uevents); i++) + if (events & (1 << i)) + envp[nr_events++] = disk_uevents[i]; + + if (nr_events) + kobject_uevent_env(&disk_to_dev(disk)->kobj, KOBJ_CHANGE, envp); +} + +/* + * A disk events enabled device has the following sysfs nodes under + * its /sys/block/X/ directory. + * + * events : list of all supported events + * events_async : list of events which can be detected w/o polling + * events_poll_msecs : polling interval, 0: disable, -1: system default + */ +static ssize_t __disk_events_show(unsigned int events, char *buf) +{ + const char *delim = ""; + ssize_t pos = 0; + int i; + + for (i = 0; i < ARRAY_SIZE(disk_events_strs); i++) + if (events & (1 << i)) { + pos += sprintf(buf + pos, "%s%s", + delim, disk_events_strs[i]); + delim = " "; + } + if (pos) + pos += sprintf(buf + pos, "\n"); + return pos; +} + +static ssize_t disk_events_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct gendisk *disk = dev_to_disk(dev); + + return __disk_events_show(disk->events, buf); +} + +static ssize_t disk_events_async_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct gendisk *disk = dev_to_disk(dev); + + return __disk_events_show(disk->async_events, buf); +} + +static ssize_t disk_events_poll_msecs_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct gendisk *disk = dev_to_disk(dev); + + return sprintf(buf, "%ld\n", disk->ev->poll_msecs); +} + +static ssize_t disk_events_poll_msecs_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct gendisk *disk = dev_to_disk(dev); + long intv; + + if (!count || !sscanf(buf, "%ld", &intv)) + return -EINVAL; + + if (intv < 0 && intv != -1) + return -EINVAL; + + __disk_block_events(disk, true); + disk->ev->poll_msecs = intv; + __disk_unblock_events(disk, true); + + return count; +} + +static const DEVICE_ATTR(events, S_IRUGO, disk_events_show, NULL); +static const DEVICE_ATTR(events_async, S_IRUGO, disk_events_async_show, NULL); +static const DEVICE_ATTR(events_poll_msecs, S_IRUGO|S_IWUSR, + disk_events_poll_msecs_show, + disk_events_poll_msecs_store); + +static const struct attribute *disk_events_attrs[] = { + &dev_attr_events.attr, + &dev_attr_events_async.attr, + &dev_attr_events_poll_msecs.attr, + NULL, +}; + +/* + * The default polling interval can be specified by the kernel + * parameter block.events_dfl_poll_msecs which defaults to 0 + * (disable). This can also be modified runtime by writing to + * /sys/module/block/events_dfl_poll_msecs. + */ +static int disk_events_set_dfl_poll_msecs(const char *val, + const struct kernel_param *kp) +{ + struct disk_events *ev; + int ret; + + ret = param_set_ulong(val, kp); + if (ret < 0) + return ret; + + mutex_lock(&disk_events_mutex); + + list_for_each_entry(ev, &disk_events, node) + disk_check_events(ev->disk); + + mutex_unlock(&disk_events_mutex); + + return 0; +} + +static const struct kernel_param_ops disk_events_dfl_poll_msecs_param_ops = { + .set = disk_events_set_dfl_poll_msecs, + .get = param_get_ulong, +}; + +#undef MODULE_PARAM_PREFIX +#define MODULE_PARAM_PREFIX "block." + +module_param_cb(events_dfl_poll_msecs, &disk_events_dfl_poll_msecs_param_ops, + &disk_events_dfl_poll_msecs, 0644); + +/* + * disk_{add|del|release}_events - initialize and destroy disk_events. + */ +static void disk_add_events(struct gendisk *disk) +{ + struct disk_events *ev; + + if (!disk->fops->check_events || !(disk->events | disk->async_events)) + return; + + ev = kzalloc(sizeof(*ev), GFP_KERNEL); + if (!ev) { + pr_warn("%s: failed to initialize events\n", disk->disk_name); + return; + } + + if (sysfs_create_files(&disk_to_dev(disk)->kobj, + disk_events_attrs) < 0) { + pr_warn("%s: failed to create sysfs files for events\n", + disk->disk_name); + kfree(ev); + return; + } + + disk->ev = ev; + + INIT_LIST_HEAD(&ev->node); + ev->disk = disk; + spin_lock_init(&ev->lock); + ev->block = 1; + ev->poll_msecs = -1; + INIT_DELAYED_WORK(&ev->dwork, disk_events_workfn); + + mutex_lock(&disk_events_mutex); + list_add_tail(&ev->node, &disk_events); + mutex_unlock(&disk_events_mutex); + + /* + * Block count is initialized to 1 and the following initial + * unblock kicks it into action. + */ + __disk_unblock_events(disk, true); +} + +static void disk_del_events(struct gendisk *disk) +{ + if (!disk->ev) + return; + + __disk_block_events(disk, true); + + mutex_lock(&disk_events_mutex); + list_del_init(&disk->ev->node); + mutex_unlock(&disk_events_mutex); + + sysfs_remove_files(&disk_to_dev(disk)->kobj, disk_events_attrs); +} + +static void disk_release_events(struct gendisk *disk) +{ + /* the block count should be 1 from disk_del_events() */ + WARN_ON_ONCE(disk->ev && disk->ev->block != 1); + kfree(disk->ev); +} diff --git a/fs/block_dev.c b/fs/block_dev.c index c1c1b8c3fb99..6017389711ee 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c @@ -948,10 +948,11 @@ int check_disk_change(struct block_device *bdev) { struct gendisk *disk = bdev->bd_disk; const struct block_device_operations *bdops = disk->fops; + unsigned int events; - if (!bdops->media_changed) - return 0; - if (!bdops->media_changed(bdev->bd_disk)) + events = disk_clear_events(disk, DISK_EVENT_MEDIA_CHANGE | + DISK_EVENT_EJECT_REQUEST); + if (!(events & DISK_EVENT_MEDIA_CHANGE)) return 0; flush_disk(bdev); @@ -1158,9 +1159,10 @@ int blkdev_get(struct block_device *bdev, fmode_t mode, void *holder) if (whole) { /* finish claiming */ + mutex_lock(&bdev->bd_mutex); spin_lock(&bdev_lock); - if (res == 0) { + if (!res) { BUG_ON(!bd_may_claim(bdev, whole, holder)); /* * Note that for a whole device bd_holders @@ -1180,6 +1182,20 @@ int blkdev_get(struct block_device *bdev, fmode_t mode, void *holder) wake_up_bit(&whole->bd_claiming, 0); spin_unlock(&bdev_lock); + + /* + * Block event polling for write claims. Any write + * holder makes the write_holder state stick until all + * are released. This is good enough and tracking + * individual writeable reference is too fragile given + * the way @mode is used in blkdev_get/put(). + */ + if (!res && (mode & FMODE_WRITE) && !bdev->bd_write_holder) { + bdev->bd_write_holder = true; + disk_block_events(bdev->bd_disk); + } + + mutex_unlock(&bdev->bd_mutex); bdput(whole); } @@ -1353,12 +1369,23 @@ int blkdev_put(struct block_device *bdev, fmode_t mode) spin_unlock(&bdev_lock); - /* if this was the last claim, holder link should go too */ - if (bdev_free) + /* + * If this was the last claim, remove holder link and + * unblock evpoll if it was a write holder. + */ + if (bdev_free) { bd_unlink_disk_holder(bdev); + if (bdev->bd_write_holder) { + disk_unblock_events(bdev->bd_disk); + bdev->bd_write_holder = false; + } else + disk_check_events(bdev->bd_disk); + } mutex_unlock(&bdev->bd_mutex); - } + } else + disk_check_events(bdev->bd_disk); + return __blkdev_put(bdev, mode, 0); } EXPORT_SYMBOL(blkdev_put); diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h index 83031bcf8366..05667e6989f1 100644 --- a/include/linux/blkdev.h +++ b/include/linux/blkdev.h @@ -1251,6 +1251,9 @@ struct block_device_operations { int (*compat_ioctl) (struct block_device *, fmode_t, unsigned, unsigned long); int (*direct_access) (struct block_device *, sector_t, void **, unsigned long *); + unsigned int (*check_events) (struct gendisk *disk, + unsigned int clearing); + /* ->media_changed() is DEPRECATED, use ->check_events() instead */ int (*media_changed) (struct gendisk *); void (*unlock_native_capacity) (struct gendisk *); int (*revalidate_disk) (struct gendisk *); diff --git a/include/linux/fs.h b/include/linux/fs.h index f48501563917..997d22efdef0 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -662,6 +662,7 @@ struct block_device { void * bd_claiming; void * bd_holder; int bd_holders; + bool bd_write_holder; #ifdef CONFIG_SYSFS struct gendisk * bd_holder_disk; /* for sysfs slave linkng */ #endif diff --git a/include/linux/genhd.h b/include/linux/genhd.h index 56e17ed24816..13893aa2ac9d 100644 --- a/include/linux/genhd.h +++ b/include/linux/genhd.h @@ -127,6 +127,11 @@ struct hd_struct { #define GENHD_FL_EXT_DEVT 64 /* allow extended devt */ #define GENHD_FL_NATIVE_CAPACITY 128 +enum { + DISK_EVENT_MEDIA_CHANGE = 1 << 0, /* media changed */ + DISK_EVENT_EJECT_REQUEST = 1 << 1, /* eject requested */ +}; + #define BLK_SCSI_MAX_CMDS (256) #define BLK_SCSI_CMD_PER_LONG (BLK_SCSI_MAX_CMDS / (sizeof(long) * 8)) @@ -143,6 +148,8 @@ struct disk_part_tbl { struct hd_struct __rcu *part[]; }; +struct disk_events; + struct gendisk { /* major, first_minor and minors are input parameters only, * don't use directly. Use disk_devt() and disk_max_parts(). @@ -154,6 +161,10 @@ struct gendisk { char disk_name[DISK_NAME_LEN]; /* name of major driver */ char *(*devnode)(struct gendisk *gd, mode_t *mode); + + unsigned int events; /* supported events */ + unsigned int async_events; /* async events, subset of all */ + /* Array of pointers to partitions indexed by partno. * Protected with matching bdev lock but stat and other * non-critical accesses use RCU. Always access through @@ -171,8 +182,8 @@ struct gendisk { struct kobject *slave_dir; struct timer_rand_state *random; - atomic_t sync_io; /* RAID */ + struct disk_events *ev; #ifdef CONFIG_BLK_DEV_INTEGRITY struct blk_integrity *integrity; #endif @@ -405,6 +416,11 @@ static inline int get_disk_ro(struct gendisk *disk) return disk->part0.policy; } +extern void disk_block_events(struct gendisk *disk); +extern void disk_unblock_events(struct gendisk *disk); +extern void disk_check_events(struct gendisk *disk); +extern unsigned int disk_clear_events(struct gendisk *disk, unsigned int mask); + /* drivers/char/random.c */ extern void add_disk_randomness(struct gendisk *disk); extern void rand_initialize_disk(struct gendisk *disk); -- cgit v1.2.3 From 2d9217296bfa6fdc0d3707264076e5296faffdbd Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 8 Dec 2010 20:57:38 +0100 Subject: cdrom: add ->check_events() support In principle, cdrom just needs to pass through ->check_events() but CDROM_MEDIA_CHANGED ioctl makes things a bit more complex. Just as with ->media_changed() support, cdrom code needs to buffer the events and serve them to ioctl and vfs as requested. As the code has to deal with both ->check_events() and ->media_changed(), and vfs and ioctl event buffering, this patch adds check_events caching on top of the existing cdi->mc_flags buffering. It may be a good idea to deprecate CDROM_MEDIA_CHANGED ioctl and remove all this mess. Signed-off-by: Tejun Heo Signed-off-by: Jens Axboe --- drivers/cdrom/cdrom.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++++--- include/linux/cdrom.h | 6 ++++++ 2 files changed, 58 insertions(+), 3 deletions(-) diff --git a/drivers/cdrom/cdrom.c b/drivers/cdrom/cdrom.c index af13c62dc473..1ea8f8d363c6 100644 --- a/drivers/cdrom/cdrom.c +++ b/drivers/cdrom/cdrom.c @@ -1348,7 +1348,10 @@ static int cdrom_select_disc(struct cdrom_device_info *cdi, int slot) if (!CDROM_CAN(CDC_SELECT_DISC)) return -EDRIVE_CANT_DO_THIS; - (void) cdi->ops->media_changed(cdi, slot); + if (cdi->ops->check_events) + cdi->ops->check_events(cdi, 0, slot); + else + cdi->ops->media_changed(cdi, slot); if (slot == CDSL_NONE) { /* set media changed bits, on both queues */ @@ -1392,6 +1395,41 @@ static int cdrom_select_disc(struct cdrom_device_info *cdi, int slot) return slot; } +/* + * As cdrom implements an extra ioctl consumer for media changed + * event, it needs to buffer ->check_events() output, such that event + * is not lost for both the usual VFS and ioctl paths. + * cdi->{vfs|ioctl}_events are used to buffer pending events for each + * path. + * + * XXX: Locking is non-existent. cdi->ops->check_events() can be + * called in parallel and buffering fields are accessed without any + * exclusion. The original media_changed code had the same problem. + * It might be better to simply deprecate CDROM_MEDIA_CHANGED ioctl + * and remove this cruft altogether. It doesn't have much usefulness + * at this point. + */ +static void cdrom_update_events(struct cdrom_device_info *cdi, + unsigned int clearing) +{ + unsigned int events; + + events = cdi->ops->check_events(cdi, clearing, CDSL_CURRENT); + cdi->vfs_events |= events; + cdi->ioctl_events |= events; +} + +unsigned int cdrom_check_events(struct cdrom_device_info *cdi, + unsigned int clearing) +{ + unsigned int events; + + cdrom_update_events(cdi, clearing); + events = cdi->vfs_events; + cdi->vfs_events = 0; + return events; +} + /* We want to make media_changed accessible to the user through an * ioctl. The main problem now is that we must double-buffer the * low-level implementation, to assure that the VFS and the user both @@ -1403,15 +1441,26 @@ int media_changed(struct cdrom_device_info *cdi, int queue) { unsigned int mask = (1 << (queue & 1)); int ret = !!(cdi->mc_flags & mask); + bool changed; if (!CDROM_CAN(CDC_MEDIA_CHANGED)) - return ret; + return ret; + /* changed since last call? */ - if (cdi->ops->media_changed(cdi, CDSL_CURRENT)) { + if (cdi->ops->check_events) { + BUG_ON(!queue); /* shouldn't be called from VFS path */ + cdrom_update_events(cdi, DISK_EVENT_MEDIA_CHANGE); + changed = cdi->ioctl_events & DISK_EVENT_MEDIA_CHANGE; + cdi->ioctl_events = 0; + } else + changed = cdi->ops->media_changed(cdi, CDSL_CURRENT); + + if (changed) { cdi->mc_flags = 0x3; /* set bit on both queues */ ret |= 1; cdi->media_written = 0; } + cdi->mc_flags &= ~mask; /* clear bit */ return ret; } diff --git a/include/linux/cdrom.h b/include/linux/cdrom.h index 78e904796622..35eae4b67503 100644 --- a/include/linux/cdrom.h +++ b/include/linux/cdrom.h @@ -946,6 +946,8 @@ struct cdrom_device_info { /* device-related storage */ unsigned int options : 30; /* options flags */ unsigned mc_flags : 2; /* media change buffer flags */ + unsigned int vfs_events; /* cached events for vfs path */ + unsigned int ioctl_events; /* cached events for ioctl path */ int use_count; /* number of times device opened */ char name[20]; /* name of the device type */ /* per-device flags */ @@ -965,6 +967,8 @@ struct cdrom_device_ops { int (*open) (struct cdrom_device_info *, int); void (*release) (struct cdrom_device_info *); int (*drive_status) (struct cdrom_device_info *, int); + unsigned int (*check_events) (struct cdrom_device_info *cdi, + unsigned int clearing, int slot); int (*media_changed) (struct cdrom_device_info *, int); int (*tray_move) (struct cdrom_device_info *, int); int (*lock_door) (struct cdrom_device_info *, int); @@ -993,6 +997,8 @@ extern int cdrom_open(struct cdrom_device_info *cdi, struct block_device *bdev, extern void cdrom_release(struct cdrom_device_info *cdi, fmode_t mode); extern int cdrom_ioctl(struct cdrom_device_info *cdi, struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long arg); +extern unsigned int cdrom_check_events(struct cdrom_device_info *cdi, + unsigned int clearing); extern int cdrom_media_changed(struct cdrom_device_info *); extern int register_cdrom(struct cdrom_device_info *cdi); -- cgit v1.2.3 From 638428ece619495edc9579b1e21493eb00f9687c Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Thu, 9 Dec 2010 11:18:42 +0100 Subject: scsi: fix TUR error handling in sr_media_change() sr_test_unit_ready() returns 0 iff TUR succeeded - IOW, when media is present and the device is actually ready, so the return value wouldn't be zero when TUR ends with sense data. sr_media_change() incorrectly tests (retval || (scsi_sense_valid(sshdr)...)) when it tries to test whether TUR failed without sense data or with sense data indicating media-not-present. Fix the test using scsi_status_is_good() and update comments. - Fixed a comment typo spotted by Eike. Signed-off-by: Tejun Heo Cc: Rolf Eike Beer Signed-off-by: Jens Axboe --- drivers/scsi/sr.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c index d7b383c96d5d..c7e29bdec2cd 100644 --- a/drivers/scsi/sr.c +++ b/drivers/scsi/sr.c @@ -214,13 +214,17 @@ static int sr_media_change(struct cdrom_device_info *cdi, int slot) sshdr = kzalloc(sizeof(*sshdr), GFP_KERNEL); retval = sr_test_unit_ready(cd->device, sshdr); - if (retval || (scsi_sense_valid(sshdr) && - /* 0x3a is medium not present */ - sshdr->asc == 0x3a)) { - /* Media not present or unable to test, unit probably not - * ready. This usually means there is no disc in the drive. - * Mark as changed, and we will figure it out later once - * the drive is available again. + /* + * Media is considered to be present if TUR succeeds or fails with + * sense data indicating something other than media-not-present + * (ASC 0x3a). + */ + if (!scsi_status_is_good(retval) && + (!scsi_sense_valid(sshdr) || sshdr->asc == 0x3a)) { + /* + * Probably no media in the device. Mark as changed, and + * we will figure it out later once the drive is available + * again. */ cd->device->changed = 1; /* This will force a flush, if called from check_disk_change */ -- cgit v1.2.3 From 9f8a2c23c6c1140f515f601265c4dff7522110b7 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 8 Dec 2010 20:57:40 +0100 Subject: scsi: replace sr_test_unit_ready() with scsi_test_unit_ready() The usage of TUR has been confusing involving several different commits updating different parts over time. Currently, the only differences between scsi_test_unit_ready() and sr_test_unit_ready() are, * scsi_test_unit_ready() also sets sdev->changed on NOT_READY. * scsi_test_unit_ready() returns 0 if TUR ended with UNIT_ATTENTION or NOT_READY. Due to the above two differences, sr is using its own sr_test_unit_ready(), but sd - the sole user of the above extra handling - doesn't even need them. Where scsi_test_unit_ready() is used in sd_media_changed(), the code is looking for device ready w/ media present state which is true iff TUR succeeds w/o sense data or UA, and when the device is not ready for whatever reason sd_media_changed() explicitly marks media as missing so there's no reason to set sdev->changed automatically from scsi_test_unit_ready() on NOT_READY. Drop both special handlings from scsi_test_unit_ready(), which makes it equivalant to sr_test_unit_ready(), and replace sr_test_unit_ready() with scsi_test_unit_ready(). Also, drop the unnecessary explicit NOT_READY check from sd_media_changed(). Checking return value is enough for testing device readiness. Signed-off-by: Tejun Heo Signed-off-by: Jens Axboe --- drivers/scsi/scsi_lib.c | 13 +------------ drivers/scsi/sd.c | 10 +--------- drivers/scsi/sr.c | 31 +++---------------------------- drivers/scsi/sr.h | 1 - drivers/scsi/sr_ioctl.c | 2 +- 5 files changed, 6 insertions(+), 51 deletions(-) diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index eafeeda6e194..13bf89145b18 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -1984,8 +1984,7 @@ EXPORT_SYMBOL(scsi_mode_sense); * in. * * Returns zero if unsuccessful or an error if TUR failed. For - * removable media, a return of NOT_READY or UNIT_ATTENTION is - * translated to success, with the ->changed flag updated. + * removable media, UNIT_ATTENTION sets ->changed flag. **/ int scsi_test_unit_ready(struct scsi_device *sdev, int timeout, int retries, @@ -2012,16 +2011,6 @@ scsi_test_unit_ready(struct scsi_device *sdev, int timeout, int retries, } while (scsi_sense_valid(sshdr) && sshdr->sense_key == UNIT_ATTENTION && --retries); - if (!sshdr) - /* could not allocate sense buffer, so can't process it */ - return result; - - if (sdev->removable && scsi_sense_valid(sshdr) && - (sshdr->sense_key == UNIT_ATTENTION || - sshdr->sense_key == NOT_READY)) { - sdev->changed = 1; - result = 0; - } if (!sshdr_external) kfree(sshdr); return result; diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index b9ab3a590e4b..8d488a9fef00 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -1045,15 +1045,7 @@ static int sd_media_changed(struct gendisk *disk) sshdr); } - /* - * Unable to test, unit probably not ready. This usually - * means there is no disc in the drive. Mark as changed, - * and we will figure it out later once the drive is - * available again. - */ - if (retval || (scsi_sense_valid(sshdr) && - /* 0x3a is medium not present */ - sshdr->asc == 0x3a)) { + if (retval) { set_media_not_present(sdkp); retval = 1; goto out; diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c index c7e29bdec2cd..310b3fac6313 100644 --- a/drivers/scsi/sr.c +++ b/drivers/scsi/sr.c @@ -165,32 +165,6 @@ static void scsi_cd_put(struct scsi_cd *cd) mutex_unlock(&sr_ref_mutex); } -/* identical to scsi_test_unit_ready except that it doesn't - * eat the NOT_READY returns for removable media */ -int sr_test_unit_ready(struct scsi_device *sdev, struct scsi_sense_hdr *sshdr) -{ - int retries = MAX_RETRIES; - int the_result; - u8 cmd[] = {TEST_UNIT_READY, 0, 0, 0, 0, 0 }; - - /* issue TEST_UNIT_READY until the initial startup UNIT_ATTENTION - * conditions are gone, or a timeout happens - */ - do { - the_result = scsi_execute_req(sdev, cmd, DMA_NONE, NULL, - 0, sshdr, SR_TIMEOUT, - retries--, NULL); - if (scsi_sense_valid(sshdr) && - sshdr->sense_key == UNIT_ATTENTION) - sdev->changed = 1; - - } while (retries > 0 && - (!scsi_status_is_good(the_result) || - (scsi_sense_valid(sshdr) && - sshdr->sense_key == UNIT_ATTENTION))); - return the_result; -} - /* * This function checks to see if the media has been changed in the * CDROM drive. It is possible that we have already sensed a change, @@ -213,7 +187,8 @@ static int sr_media_change(struct cdrom_device_info *cdi, int slot) } sshdr = kzalloc(sizeof(*sshdr), GFP_KERNEL); - retval = sr_test_unit_ready(cd->device, sshdr); + retval = scsi_test_unit_ready(cd->device, SR_TIMEOUT, MAX_RETRIES, + sshdr); /* * Media is considered to be present if TUR succeeds or fails with * sense data indicating something other than media-not-present @@ -784,7 +759,7 @@ static void get_capabilities(struct scsi_cd *cd) } /* eat unit attentions */ - sr_test_unit_ready(cd->device, &sshdr); + scsi_test_unit_ready(cd->device, SR_TIMEOUT, MAX_RETRIES, &sshdr); /* ask for mode page 0x2a */ rc = scsi_mode_sense(cd->device, 0, 0x2a, buffer, 128, diff --git a/drivers/scsi/sr.h b/drivers/scsi/sr.h index 1e144dfdbd4b..81fbc0b78a52 100644 --- a/drivers/scsi/sr.h +++ b/drivers/scsi/sr.h @@ -61,7 +61,6 @@ int sr_select_speed(struct cdrom_device_info *cdi, int speed); int sr_audio_ioctl(struct cdrom_device_info *, unsigned int, void *); int sr_is_xa(Scsi_CD *); -int sr_test_unit_ready(struct scsi_device *sdev, struct scsi_sense_hdr *sshdr); /* sr_vendor.c */ void sr_vendor_init(Scsi_CD *); diff --git a/drivers/scsi/sr_ioctl.c b/drivers/scsi/sr_ioctl.c index 3cd8ffbad577..8be30554119b 100644 --- a/drivers/scsi/sr_ioctl.c +++ b/drivers/scsi/sr_ioctl.c @@ -307,7 +307,7 @@ int sr_drive_status(struct cdrom_device_info *cdi, int slot) /* we have no changer support */ return -EINVAL; } - if (0 == sr_test_unit_ready(cd->device, &sshdr)) + if (!scsi_test_unit_ready(cd->device, SR_TIMEOUT, MAX_RETRIES, &sshdr)) return CDS_DISC_OK; /* SK/ASC/ASCQ of 2/4/1 means "unit is becoming ready" */ -- cgit v1.2.3 From 93aae17af1172c40c6f74b7294e93a90c3cfaa5d Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Thu, 16 Dec 2010 17:52:17 +0100 Subject: sr: implement sr_check_events() Replace sr_media_change() with sr_check_events(). It normally only uses GET_EVENT_STATUS_NOTIFICATION to check both media change and eject request. If @clearing includes DISK_EVENT_MEDIA_CHANGE, it issues TUR and compares whether media presence has changed. The SCSI specific media change uevent is kept for compatibility. sr_media_change() was doing both media change check and revalidation. The revalidation part is split into sr_block_revalidate_disk(). Signed-off-by: Tejun Heo Cc: Kay Sievers Signed-off-by: Jens Axboe --- drivers/scsi/sr.c | 149 ++++++++++++++++++++++++++++++++++------------------ drivers/scsi/sr.h | 2 +- include/scsi/scsi.h | 1 + 3 files changed, 99 insertions(+), 53 deletions(-) diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c index 310b3fac6313..be6baf8ad704 100644 --- a/drivers/scsi/sr.c +++ b/drivers/scsi/sr.c @@ -104,14 +104,15 @@ static void sr_release(struct cdrom_device_info *); static void get_sectorsize(struct scsi_cd *); static void get_capabilities(struct scsi_cd *); -static int sr_media_change(struct cdrom_device_info *, int); +static unsigned int sr_check_events(struct cdrom_device_info *cdi, + unsigned int clearing, int slot); static int sr_packet(struct cdrom_device_info *, struct packet_command *); static struct cdrom_device_ops sr_dops = { .open = sr_open, .release = sr_release, .drive_status = sr_drive_status, - .media_changed = sr_media_change, + .check_events = sr_check_events, .tray_move = sr_tray_move, .lock_door = sr_lock_door, .select_speed = sr_select_speed, @@ -165,69 +166,96 @@ static void scsi_cd_put(struct scsi_cd *cd) mutex_unlock(&sr_ref_mutex); } +static unsigned int sr_get_events(struct scsi_device *sdev) +{ + u8 buf[8]; + u8 cmd[] = { GET_EVENT_STATUS_NOTIFICATION, + 1, /* polled */ + 0, 0, /* reserved */ + 1 << 4, /* notification class: media */ + 0, 0, /* reserved */ + 0, sizeof(buf), /* allocation length */ + 0, /* control */ + }; + struct event_header *eh = (void *)buf; + struct media_event_desc *med = (void *)(buf + 4); + struct scsi_sense_hdr sshdr; + int result; + + result = scsi_execute_req(sdev, cmd, DMA_FROM_DEVICE, buf, sizeof(buf), + &sshdr, SR_TIMEOUT, MAX_RETRIES, NULL); + if (scsi_sense_valid(&sshdr) && sshdr.sense_key == UNIT_ATTENTION) + return DISK_EVENT_MEDIA_CHANGE; + + if (result || be16_to_cpu(eh->data_len) < sizeof(*med)) + return 0; + + if (eh->nea || eh->notification_class != 0x4) + return 0; + + if (med->media_event_code == 1) + return DISK_EVENT_EJECT_REQUEST; + else if (med->media_event_code == 2) + return DISK_EVENT_MEDIA_CHANGE; + return 0; +} + /* - * This function checks to see if the media has been changed in the - * CDROM drive. It is possible that we have already sensed a change, - * or the drive may have sensed one and not yet reported it. We must - * be ready for either case. This function always reports the current - * value of the changed bit. If flag is 0, then the changed bit is reset. - * This function could be done as an ioctl, but we would need to have - * an inode for that to work, and we do not always have one. + * This function checks to see if the media has been changed or eject + * button has been pressed. It is possible that we have already + * sensed a change, or the drive may have sensed one and not yet + * reported it. The past events are accumulated in sdev->changed and + * returned together with the current state. */ - -static int sr_media_change(struct cdrom_device_info *cdi, int slot) +static unsigned int sr_check_events(struct cdrom_device_info *cdi, + unsigned int clearing, int slot) { struct scsi_cd *cd = cdi->handle; - int retval; - struct scsi_sense_hdr *sshdr; + bool last_present; + struct scsi_sense_hdr sshdr; + unsigned int events; + int ret; - if (CDSL_CURRENT != slot) { - /* no changer support */ - return -EINVAL; - } + /* no changer support */ + if (CDSL_CURRENT != slot) + return 0; + + events = sr_get_events(cd->device); + /* + * GET_EVENT_STATUS_NOTIFICATION is enough unless MEDIA_CHANGE + * is being cleared. Note that there are devices which hang + * if asked to execute TUR repeatedly. + */ + if (!(clearing & DISK_EVENT_MEDIA_CHANGE)) + goto skip_tur; + + /* let's see whether the media is there with TUR */ + last_present = cd->media_present; + ret = scsi_test_unit_ready(cd->device, SR_TIMEOUT, MAX_RETRIES, &sshdr); - sshdr = kzalloc(sizeof(*sshdr), GFP_KERNEL); - retval = scsi_test_unit_ready(cd->device, SR_TIMEOUT, MAX_RETRIES, - sshdr); /* * Media is considered to be present if TUR succeeds or fails with * sense data indicating something other than media-not-present * (ASC 0x3a). */ - if (!scsi_status_is_good(retval) && - (!scsi_sense_valid(sshdr) || sshdr->asc == 0x3a)) { - /* - * Probably no media in the device. Mark as changed, and - * we will figure it out later once the drive is available - * again. - */ - cd->device->changed = 1; - /* This will force a flush, if called from check_disk_change */ - retval = 1; - goto out; - }; + cd->media_present = scsi_status_is_good(ret) || + (scsi_sense_valid(&sshdr) && sshdr.asc != 0x3a); - retval = cd->device->changed; - cd->device->changed = 0; - /* If the disk changed, the capacity will now be different, - * so we force a re-read of this information */ - if (retval) { - /* check multisession offset etc */ - sr_cd_check(cdi); - get_sectorsize(cd); + if (last_present != cd->media_present) + events |= DISK_EVENT_MEDIA_CHANGE; +skip_tur: + if (cd->device->changed) { + events |= DISK_EVENT_MEDIA_CHANGE; + cd->device->changed = 0; } -out: - /* Notify userspace, that media has changed. */ - if (retval != cd->previous_state) + /* for backward compatibility */ + if (events & DISK_EVENT_MEDIA_CHANGE) sdev_evt_send_simple(cd->device, SDEV_EVT_MEDIA_CHANGE, GFP_KERNEL); - cd->previous_state = retval; - kfree(sshdr); - - return retval; + return events; } - + /* * sr_done is the interrupt routine for the device driver. * @@ -512,10 +540,25 @@ out: return ret; } -static int sr_block_media_changed(struct gendisk *disk) +static unsigned int sr_block_check_events(struct gendisk *disk, + unsigned int clearing) { struct scsi_cd *cd = scsi_cd(disk); - return cdrom_media_changed(&cd->cdi); + return cdrom_check_events(&cd->cdi, clearing); +} + +static int sr_block_revalidate_disk(struct gendisk *disk) +{ + struct scsi_cd *cd = scsi_cd(disk); + struct scsi_sense_hdr sshdr; + + /* if the unit is not ready, nothing more to do */ + if (scsi_test_unit_ready(cd->device, SR_TIMEOUT, MAX_RETRIES, &sshdr)) + return 0; + + sr_cd_check(&cd->cdi); + get_sectorsize(cd); + return 0; } static const struct block_device_operations sr_bdops = @@ -524,7 +567,8 @@ static const struct block_device_operations sr_bdops = .open = sr_block_open, .release = sr_block_release, .ioctl = sr_block_ioctl, - .media_changed = sr_block_media_changed, + .check_events = sr_block_check_events, + .revalidate_disk = sr_block_revalidate_disk, /* * No compat_ioctl for now because sr_block_ioctl never * seems to pass arbitary ioctls down to host drivers. @@ -597,6 +641,7 @@ static int sr_probe(struct device *dev) sprintf(disk->disk_name, "sr%d", minor); disk->fops = &sr_bdops; disk->flags = GENHD_FL_CD; + disk->events = DISK_EVENT_MEDIA_CHANGE | DISK_EVENT_EJECT_REQUEST; blk_queue_rq_timeout(sdev->request_queue, SR_TIMEOUT); @@ -606,7 +651,7 @@ static int sr_probe(struct device *dev) cd->disk = disk; cd->capacity = 0x1fffff; cd->device->changed = 1; /* force recheck CD type */ - cd->previous_state = 1; + cd->media_present = 1; cd->use = 1; cd->readcd_known = 0; cd->readcd_cdda = 0; diff --git a/drivers/scsi/sr.h b/drivers/scsi/sr.h index 81fbc0b78a52..e036f1dc83c8 100644 --- a/drivers/scsi/sr.h +++ b/drivers/scsi/sr.h @@ -40,7 +40,7 @@ typedef struct scsi_cd { unsigned xa_flag:1; /* CD has XA sectors ? */ unsigned readcd_known:1; /* drive supports READ_CD (0xbe) */ unsigned readcd_cdda:1; /* reading audio data using READ_CD */ - unsigned previous_state:1; /* media has changed */ + unsigned media_present:1; /* media is present */ struct cdrom_device_info cdi; /* We hold gendisk and scsi_device references on probe and use * the refs on this kref to decide when to release them */ diff --git a/include/scsi/scsi.h b/include/scsi/scsi.h index 216af8538cc9..86758618d4f8 100644 --- a/include/scsi/scsi.h +++ b/include/scsi/scsi.h @@ -104,6 +104,7 @@ struct scsi_cmnd; #define UNMAP 0x42 #define READ_TOC 0x43 #define READ_HEADER 0x44 +#define GET_EVENT_STATUS_NOTIFICATION 0x4a #define LOG_SELECT 0x4c #define LOG_SENSE 0x4d #define XDWRITEREAD_10 0x53 -- cgit v1.2.3 From c8d2e937355d02db3055c2fc203e5f017297ee1f Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 8 Dec 2010 20:57:42 +0100 Subject: sd: implement sd_check_events() Replace sd_media_change() with sd_check_events(). sd used to set the changed state whenever the device is not ready, which can cause event loop while the device is not ready. Media presence handling code is changed such that the changed state is set iff the media presence actually changes. UA still always sets the changed state and NOT_READY always (at least where it used to set ->changed) clears media presence, so no event is lost. Signed-off-by: Tejun Heo Cc: Kay Sievers Signed-off-by: Jens Axboe --- drivers/scsi/sd.c | 87 ++++++++++++++++++++++++++++++------------------------- drivers/scsi/sd.h | 1 - 2 files changed, 47 insertions(+), 41 deletions(-) diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 8d488a9fef00..b179b0e39a3b 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -991,30 +991,50 @@ out: static void set_media_not_present(struct scsi_disk *sdkp) { + if (sdkp->media_present) + sdkp->device->changed = 1; sdkp->media_present = 0; sdkp->capacity = 0; - sdkp->device->changed = 1; +} + +static int media_not_present(struct scsi_disk *sdkp, + struct scsi_sense_hdr *sshdr) +{ + if (!scsi_sense_valid(sshdr)) + return 0; + + /* not invoked for commands that could return deferred errors */ + switch (sshdr->sense_key) { + case UNIT_ATTENTION: + sdkp->device->changed = 1; + /* fall through */ + case NOT_READY: + /* medium not present */ + if (sshdr->asc == 0x3A) { + set_media_not_present(sdkp); + return 1; + } + } + return 0; } /** - * sd_media_changed - check if our medium changed - * @disk: kernel device descriptor + * sd_check_events - check media events + * @disk: kernel device descriptor + * @clearing: disk events currently being cleared * - * Returns 0 if not applicable or no change; 1 if change + * Returns mask of DISK_EVENT_*. * * Note: this function is invoked from the block subsystem. **/ -static int sd_media_changed(struct gendisk *disk) +static unsigned int sd_check_events(struct gendisk *disk, unsigned int clearing) { struct scsi_disk *sdkp = scsi_disk(disk); struct scsi_device *sdp = sdkp->device; struct scsi_sense_hdr *sshdr = NULL; int retval; - SCSI_LOG_HLQUEUE(3, sd_printk(KERN_INFO, sdkp, "sd_media_changed\n")); - - if (!sdp->removable) - return 0; + SCSI_LOG_HLQUEUE(3, sd_printk(KERN_INFO, sdkp, "sd_check_events\n")); /* * If the device is offline, don't send any commands - just pretend as @@ -1024,7 +1044,6 @@ static int sd_media_changed(struct gendisk *disk) */ if (!scsi_device_online(sdp)) { set_media_not_present(sdkp); - retval = 1; goto out; } @@ -1045,26 +1064,30 @@ static int sd_media_changed(struct gendisk *disk) sshdr); } - if (retval) { + /* failed to execute TUR, assume media not present */ + if (host_byte(retval)) { set_media_not_present(sdkp); - retval = 1; goto out; } + if (media_not_present(sdkp, sshdr)) + goto out; + /* * For removable scsi disk we have to recognise the presence - * of a disk in the drive. This is kept in the struct scsi_disk - * struct and tested at open ! Daniel Roche (dan@lectra.fr) + * of a disk in the drive. */ + if (!sdkp->media_present) + sdp->changed = 1; sdkp->media_present = 1; - - retval = sdp->changed; - sdp->changed = 0; out: - if (retval != sdkp->previous_state) + /* for backward compatibility */ + if (sdp->changed) sdev_evt_send_simple(sdp, SDEV_EVT_MEDIA_CHANGE, GFP_KERNEL); - sdkp->previous_state = retval; kfree(sshdr); + + retval = sdp->changed ? DISK_EVENT_MEDIA_CHANGE : 0; + sdp->changed = 0; return retval; } @@ -1157,7 +1180,7 @@ static const struct block_device_operations sd_fops = { #ifdef CONFIG_COMPAT .compat_ioctl = sd_compat_ioctl, #endif - .media_changed = sd_media_changed, + .check_events = sd_check_events, .revalidate_disk = sd_revalidate_disk, .unlock_native_capacity = sd_unlock_native_capacity, }; @@ -1293,23 +1316,6 @@ static int sd_done(struct scsi_cmnd *SCpnt) return good_bytes; } -static int media_not_present(struct scsi_disk *sdkp, - struct scsi_sense_hdr *sshdr) -{ - - if (!scsi_sense_valid(sshdr)) - return 0; - /* not invoked for commands that could return deferred errors */ - if (sshdr->sense_key != NOT_READY && - sshdr->sense_key != UNIT_ATTENTION) - return 0; - if (sshdr->asc != 0x3A) /* medium not present */ - return 0; - - set_media_not_present(sdkp); - return 1; -} - /* * spinup disk - called only in sd_revalidate_disk() */ @@ -1484,7 +1490,7 @@ static void read_capacity_error(struct scsi_disk *sdkp, struct scsi_device *sdp, */ if (sdp->removable && sense_valid && sshdr->sense_key == NOT_READY) - sdp->changed = 1; + set_media_not_present(sdkp); /* * We used to set media_present to 0 here to indicate no media @@ -2339,8 +2345,10 @@ static void sd_probe_async(void *data, async_cookie_t cookie) gd->driverfs_dev = &sdp->sdev_gendev; gd->flags = GENHD_FL_EXT_DEVT; - if (sdp->removable) + if (sdp->removable) { gd->flags |= GENHD_FL_REMOVABLE; + gd->events |= DISK_EVENT_MEDIA_CHANGE; + } add_disk(gd); sd_dif_config_host(sdkp); @@ -2422,7 +2430,6 @@ static int sd_probe(struct device *dev) sdkp->disk = gd; sdkp->index = index; atomic_set(&sdkp->openers, 0); - sdkp->previous_state = 1; if (!sdp->request_queue->rq_timeout) { if (sdp->type != TYPE_MOD) diff --git a/drivers/scsi/sd.h b/drivers/scsi/sd.h index 55488faf0815..c9d8f6ca49e2 100644 --- a/drivers/scsi/sd.h +++ b/drivers/scsi/sd.h @@ -55,7 +55,6 @@ struct scsi_disk { u8 media_present; u8 write_prot; u8 protection_type;/* Data Integrity Field */ - unsigned previous_state : 1; unsigned ATO : 1; /* state of disk ATO bit */ unsigned WCE : 1; /* state of disk WCE bit */ unsigned RCD : 1; /* state of disk RCD bit, unused */ -- cgit v1.2.3 From 30fac30103185d853cb5cdb4bbed70d629d6da7e Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 16 Dec 2010 17:55:42 +0100 Subject: ALSA: hda - Clean up dead code in patch_realtek.c Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index fc435b59a52f..4e6f4f6d342f 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -9214,16 +9214,6 @@ static void alc883_mitac_setup(struct hda_codec *codec) spec->autocfg.speaker_pins[1] = 0x17; } -/* auto-toggle front mic */ -/* -static void alc883_mitac_mic_automute(struct hda_codec *codec) -{ - unsigned char bits = snd_hda_jack_detect(codec, 0x18) ? HDA_AMP_MUTE : 0; - - snd_hda_codec_amp_stereo(codec, 0x0b, HDA_INPUT, 1, HDA_AMP_MUTE, bits); -} -*/ - static struct hda_verb alc883_mitac_verbs[] = { /* HP */ {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, -- cgit v1.2.3 From 30a7caabbb8e8702b9cf453fee83f773d8b3430d Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Thu, 16 Dec 2010 17:58:50 +0100 Subject: cdrom: export cdrom_check_events() It's used by sr, so we need to export it. Signed-off-by: Jens Axboe --- drivers/cdrom/cdrom.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/cdrom/cdrom.c b/drivers/cdrom/cdrom.c index 1ea8f8d363c6..14033a36bcd0 100644 --- a/drivers/cdrom/cdrom.c +++ b/drivers/cdrom/cdrom.c @@ -1429,6 +1429,7 @@ unsigned int cdrom_check_events(struct cdrom_device_info *cdi, cdi->vfs_events = 0; return events; } +EXPORT_SYMBOL(cdrom_check_events); /* We want to make media_changed accessible to the user through an * ioctl. The main problem now is that we must double-buffer the -- cgit v1.2.3 From 25a0866cc63281b480cc0c11ddeaccb2ffc57dc9 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Tue, 14 Dec 2010 14:54:30 +0000 Subject: NFS: Introduce new-style XDR encoding functions for NFSv2 We're interested in taking advantage of the safety benefits of xdr_streams. These data structures allow more careful checking for buffer overflow while encoding. More careful type checking is also introduced in the new functions. For efficiency, we also eventually want to be able to pass xdr_streams from call_encode() to all XDR encoding functions, rather than building an xdr_stream in every XDR encoding function in the kernel. To do this means all encoders must be ready to handle a passed-in xdr_stream. The new encoders follow the modern paradigm for XDR encoders: BUG on any error, and always return a zero status code. Static helper functions are left without the "inline" directive. This allows the compiler to choose automatically how to optimize these for size or speed. Signed-off-by: Chuck Lever Tested-by: J. Bruce Fields Signed-off-by: Trond Myklebust --- fs/nfs/nfs2xdr.c | 406 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 403 insertions(+), 3 deletions(-) diff --git a/fs/nfs/nfs2xdr.c b/fs/nfs/nfs2xdr.c index 5914a1911c95..869e2151a2b1 100644 --- a/fs/nfs/nfs2xdr.c +++ b/fs/nfs/nfs2xdr.c @@ -61,6 +61,23 @@ #define NFS_readdirres_sz (1) #define NFS_statfsres_sz (1+NFS_info_sz) + +/* + * While encoding arguments, set up the reply buffer in advance to + * receive reply data directly into the page cache. + */ +static void prepare_reply_buffer(struct rpc_rqst *req, struct page **pages, + unsigned int base, unsigned int len, + unsigned int bufsize) +{ + struct rpc_auth *auth = req->rq_cred->cr_auth; + unsigned int replen; + + replen = RPC_REPHDRSIZE + auth->au_rslack + bufsize; + xdr_inline_pages(&req->rq_rcv_buf, replen << 2, pages, base, len); +} + + /* * Common NFS XDR functions as inlines */ @@ -81,7 +98,7 @@ xdr_decode_fhandle(__be32 *p, struct nfs_fh *fhandle) } static inline __be32* -xdr_encode_time(__be32 *p, struct timespec *timep) +xdr_encode_time(__be32 *p, const struct timespec *timep) { *p++ = htonl(timep->tv_sec); /* Convert nanoseconds into microseconds */ @@ -90,7 +107,7 @@ xdr_encode_time(__be32 *p, struct timespec *timep) } static inline __be32* -xdr_encode_current_server_time(__be32 *p, struct timespec *timep) +xdr_encode_current_server_time(__be32 *p, const struct timespec *timep) { /* * Passing the invalid value useconds=1000000 is a @@ -173,6 +190,136 @@ xdr_encode_sattr(__be32 *p, struct iattr *attr) return p; } +/* + * Encode/decode NFSv2 basic data types + * + * Basic NFSv2 data types are defined in section 2.3 of RFC 1094: + * "NFS: Network File System Protocol Specification". + * + * Not all basic data types have their own encoding and decoding + * functions. For run-time efficiency, some data types are encoded + * or decoded inline. + */ + +/* + * 2.3.3. fhandle + * + * typedef opaque fhandle[FHSIZE]; + */ +static void encode_fhandle(struct xdr_stream *xdr, const struct nfs_fh *fh) +{ + __be32 *p; + + BUG_ON(fh->size != NFS2_FHSIZE); + p = xdr_reserve_space(xdr, NFS2_FHSIZE); + memcpy(p, fh->data, NFS2_FHSIZE); +} + +/* + * 2.3.6. sattr + * + * struct sattr { + * unsigned int mode; + * unsigned int uid; + * unsigned int gid; + * unsigned int size; + * timeval atime; + * timeval mtime; + * }; + */ + +#define NFS2_SATTR_NOT_SET (0xffffffff) + +static __be32 *xdr_time_not_set(__be32 *p) +{ + *p++ = cpu_to_be32(NFS2_SATTR_NOT_SET); + *p++ = cpu_to_be32(NFS2_SATTR_NOT_SET); + return p; +} + +static void encode_sattr(struct xdr_stream *xdr, const struct iattr *attr) +{ + __be32 *p; + + p = xdr_reserve_space(xdr, NFS_sattr_sz << 2); + + if (attr->ia_valid & ATTR_MODE) + *p++ = cpu_to_be32(attr->ia_mode); + else + *p++ = cpu_to_be32(NFS2_SATTR_NOT_SET); + if (attr->ia_valid & ATTR_UID) + *p++ = cpu_to_be32(attr->ia_uid); + else + *p++ = cpu_to_be32(NFS2_SATTR_NOT_SET); + if (attr->ia_valid & ATTR_GID) + *p++ = cpu_to_be32(attr->ia_gid); + else + *p++ = cpu_to_be32(NFS2_SATTR_NOT_SET); + if (attr->ia_valid & ATTR_SIZE) + *p++ = cpu_to_be32((u32)attr->ia_size); + else + *p++ = cpu_to_be32(NFS2_SATTR_NOT_SET); + + if (attr->ia_valid & ATTR_ATIME_SET) + p = xdr_encode_time(p, &attr->ia_atime); + else if (attr->ia_valid & ATTR_ATIME) + p = xdr_encode_current_server_time(p, &attr->ia_atime); + else + p = xdr_time_not_set(p); + if (attr->ia_valid & ATTR_MTIME_SET) + xdr_encode_time(p, &attr->ia_mtime); + else if (attr->ia_valid & ATTR_MTIME) + xdr_encode_current_server_time(p, &attr->ia_mtime); + else + xdr_time_not_set(p); +} + +/* + * 2.3.7. filename + * + * typedef string filename; + */ +static void encode_filename(struct xdr_stream *xdr, + const char *name, u32 length) +{ + __be32 *p; + + BUG_ON(length > NFS2_MAXNAMLEN); + p = xdr_reserve_space(xdr, 4 + length); + xdr_encode_opaque(p, name, length); +} + +/* + * 2.3.8. path + * + * typedef string path; + */ +static void encode_path(struct xdr_stream *xdr, struct page **pages, u32 length) +{ + __be32 *p; + + BUG_ON(length > NFS2_MAXPATHLEN); + p = xdr_reserve_space(xdr, 4); + *p = cpu_to_be32(length); + xdr_write_pages(xdr, pages, 0, length); +} + +/* + * 2.3.10. diropargs + * + * struct diropargs { + * fhandle dir; + * filename name; + * }; + */ +static void encode_diropargs(struct xdr_stream *xdr, const struct nfs_fh *fh, + const char *name, u32 length) +{ + encode_fhandle(xdr, fh); + encode_filename(xdr, name, length); +} + + /* * NFS encode functions */ @@ -188,6 +335,16 @@ nfs_xdr_fhandle(struct rpc_rqst *req, __be32 *p, struct nfs_fh *fh) return 0; } +static int nfs2_xdr_enc_fhandle(struct rpc_rqst *req, __be32 *p, + const struct nfs_fh *fh) +{ + struct xdr_stream xdr; + + xdr_init_encode(&xdr, &req->rq_snd_buf, p); + encode_fhandle(&xdr, fh); + return 0; +} + /* * Encode SETATTR arguments */ @@ -200,6 +357,25 @@ nfs_xdr_sattrargs(struct rpc_rqst *req, __be32 *p, struct nfs_sattrargs *args) return 0; } +/* + * 2.2.3. sattrargs + * + * struct sattrargs { + * fhandle file; + * sattr attributes; + * }; + */ +static int nfs2_xdr_enc_sattrargs(struct rpc_rqst *req, __be32 *p, + const struct nfs_sattrargs *args) +{ + struct xdr_stream xdr; + + xdr_init_encode(&xdr, &req->rq_snd_buf, p); + encode_fhandle(&xdr, args->fh); + encode_sattr(&xdr, args->sattr); + return 0; +} + /* * Encode directory ops argument * LOOKUP, RMDIR @@ -213,6 +389,16 @@ nfs_xdr_diropargs(struct rpc_rqst *req, __be32 *p, struct nfs_diropargs *args) return 0; } +static int nfs2_xdr_enc_diropargs(struct rpc_rqst *req, __be32 *p, + const struct nfs_diropargs *args) +{ + struct xdr_stream xdr; + + xdr_init_encode(&xdr, &req->rq_snd_buf, p); + encode_diropargs(&xdr, args->fh, args->name, args->len); + return 0; +} + /* * Encode REMOVE argument */ @@ -225,6 +411,18 @@ nfs_xdr_removeargs(struct rpc_rqst *req, __be32 *p, const struct nfs_removeargs return 0; } +static int nfs2_xdr_enc_readlinkargs(struct rpc_rqst *req, __be32 *p, + const struct nfs_readlinkargs *args) +{ + struct xdr_stream xdr; + + xdr_init_encode(&xdr, &req->rq_snd_buf, p); + encode_fhandle(&xdr, args->fh); + prepare_reply_buffer(req, args->pages, args->pgbase, + args->pglen, NFS_readlinkres_sz); + return 0; +} + /* * Arguments to a READ call. Since we read data directly into the page * cache, we also set up the reply iovec here so that iov[1] points @@ -252,6 +450,44 @@ nfs_xdr_readargs(struct rpc_rqst *req, __be32 *p, struct nfs_readargs *args) return 0; } +/* + * 2.2.7. readargs + * + * struct readargs { + * fhandle file; + * unsigned offset; + * unsigned count; + * unsigned totalcount; + * }; + */ +static void encode_readargs(struct xdr_stream *xdr, + const struct nfs_readargs *args) +{ + u32 offset = args->offset; + u32 count = args->count; + __be32 *p; + + encode_fhandle(xdr, args->fh); + + p = xdr_reserve_space(xdr, 4 + 4 + 4); + *p++ = cpu_to_be32(offset); + *p++ = cpu_to_be32(count); + *p = cpu_to_be32(count); +} + +static int nfs2_xdr_enc_readargs(struct rpc_rqst *req, __be32 *p, + const struct nfs_readargs *args) +{ + struct xdr_stream xdr; + + xdr_init_encode(&xdr, &req->rq_snd_buf, p); + encode_readargs(&xdr, args); + prepare_reply_buffer(req, args->pages, args->pgbase, + args->count, NFS_readres_sz); + req->rq_rcv_buf.flags |= XDRBUF_READ; + return 0; +} + /* * Decode READ reply */ @@ -317,6 +553,47 @@ nfs_xdr_writeargs(struct rpc_rqst *req, __be32 *p, struct nfs_writeargs *args) return 0; } +/* + * 2.2.9. writeargs + * + * struct writeargs { + * fhandle file; + * unsigned beginoffset; + * unsigned offset; + * unsigned totalcount; + * nfsdata data; + * }; + */ +static void encode_writeargs(struct xdr_stream *xdr, + const struct nfs_writeargs *args) +{ + u32 offset = args->offset; + u32 count = args->count; + __be32 *p; + + encode_fhandle(xdr, args->fh); + + p = xdr_reserve_space(xdr, 4 + 4 + 4 + 4); + *p++ = cpu_to_be32(offset); + *p++ = cpu_to_be32(offset); + *p++ = cpu_to_be32(count); + + /* nfsdata */ + *p = cpu_to_be32(count); + xdr_write_pages(xdr, args->pages, args->pgbase, count); +} + +static int nfs2_xdr_enc_writeargs(struct rpc_rqst *req, __be32 *p, + const struct nfs_writeargs *args) +{ + struct xdr_stream xdr; + + xdr_init_encode(&xdr, &req->rq_snd_buf, p); + encode_writeargs(&xdr, args); + xdr.buf->flags |= XDRBUF_WRITE; + return 0; +} + /* * Encode create arguments * CREATE, MKDIR @@ -331,6 +608,35 @@ nfs_xdr_createargs(struct rpc_rqst *req, __be32 *p, struct nfs_createargs *args) return 0; } +/* + * 2.2.10. createargs + * + * struct createargs { + * diropargs where; + * sattr attributes; + * }; + */ +static int nfs2_xdr_enc_createargs(struct rpc_rqst *req, __be32 *p, + const struct nfs_createargs *args) +{ + struct xdr_stream xdr; + + xdr_init_encode(&xdr, &req->rq_snd_buf, p); + encode_diropargs(&xdr, args->fh, args->name, args->len); + encode_sattr(&xdr, args->sattr); + return 0; +} + +static int nfs2_xdr_enc_removeargs(struct rpc_rqst *req, __be32 *p, + const struct nfs_removeargs *args) +{ + struct xdr_stream xdr; + + xdr_init_encode(&xdr, &req->rq_snd_buf, p); + encode_diropargs(&xdr, args->fh, args->name.name, args->name.len); + return 0; +} + /* * Encode RENAME arguments */ @@ -345,6 +651,27 @@ nfs_xdr_renameargs(struct rpc_rqst *req, __be32 *p, struct nfs_renameargs *args) return 0; } +/* + * 2.2.12. renameargs + * + * struct renameargs { + * diropargs from; + * diropargs to; + * }; + */ +static int nfs2_xdr_enc_renameargs(struct rpc_rqst *req, __be32 *p, + const struct nfs_renameargs *args) +{ + const struct qstr *old = args->old_name; + const struct qstr *new = args->new_name; + struct xdr_stream xdr; + + xdr_init_encode(&xdr, &req->rq_snd_buf, p); + encode_diropargs(&xdr, args->old_dir, old->name, old->len); + encode_diropargs(&xdr, args->new_dir, new->name, new->len); + return 0; +} + /* * Encode LINK arguments */ @@ -358,6 +685,25 @@ nfs_xdr_linkargs(struct rpc_rqst *req, __be32 *p, struct nfs_linkargs *args) return 0; } +/* + * 2.2.13. linkargs + * + * struct linkargs { + * fhandle from; + * diropargs to; + * }; + */ +static int nfs2_xdr_enc_linkargs(struct rpc_rqst *req, __be32 *p, + const struct nfs_linkargs *args) +{ + struct xdr_stream xdr; + + xdr_init_encode(&xdr, &req->rq_snd_buf, p); + encode_fhandle(&xdr, args->fromfh); + encode_diropargs(&xdr, args->tofh, args->toname, args->tolen); + return 0; +} + /* * Encode SYMLINK arguments */ @@ -387,6 +733,27 @@ nfs_xdr_symlinkargs(struct rpc_rqst *req, __be32 *p, struct nfs_symlinkargs *arg return 0; } +/* + * 2.2.14. symlinkargs + * + * struct symlinkargs { + * diropargs from; + * path to; + * sattr attributes; + * }; + */ +static int nfs2_xdr_enc_symlinkargs(struct rpc_rqst *req, __be32 *p, + const struct nfs_symlinkargs *args) +{ + struct xdr_stream xdr; + + xdr_init_encode(&xdr, &req->rq_snd_buf, p); + encode_diropargs(&xdr, args->fromfh, args->fromname, args->fromlen); + encode_path(&xdr, args->pages, args->pathlen); + encode_sattr(&xdr, args->sattr); + return 0; +} + /* * Encode arguments to readdir call */ @@ -408,6 +775,39 @@ nfs_xdr_readdirargs(struct rpc_rqst *req, __be32 *p, struct nfs_readdirargs *arg return 0; } +/* + * 2.2.17. readdirargs + * + * struct readdirargs { + * fhandle dir; + * nfscookie cookie; + * unsigned count; + * }; + */ +static void encode_readdirargs(struct xdr_stream *xdr, + const struct nfs_readdirargs *args) +{ + __be32 *p; + + encode_fhandle(xdr, args->fh); + + p = xdr_reserve_space(xdr, 4 + 4); + *p++ = cpu_to_be32(args->cookie); + *p = cpu_to_be32(args->count); +} + +static int nfs2_xdr_enc_readdirargs(struct rpc_rqst *req, __be32 *p, + const struct nfs_readdirargs *args) +{ + struct xdr_stream xdr; + + xdr_init_encode(&xdr, &req->rq_snd_buf, p); + encode_readdirargs(&xdr, args); + prepare_reply_buffer(req, args->pages, 0, + args->count, NFS_readdirres_sz); + return 0; +} + /* * Decode the result of a readdir call. * We're not really decoding anymore, we just leave the buffer untouched @@ -698,7 +1098,7 @@ nfs_stat_to_errno(int stat) #define PROC(proc, argtype, restype, timer) \ [NFSPROC_##proc] = { \ .p_proc = NFSPROC_##proc, \ - .p_encode = (kxdrproc_t) nfs_xdr_##argtype, \ + .p_encode = (kxdrproc_t)nfs2_xdr_enc_##argtype, \ .p_decode = (kxdrproc_t) nfs_xdr_##restype, \ .p_arglen = NFS_##argtype##_sz, \ .p_replen = NFS_##restype##_sz, \ -- cgit v1.2.3 From 2d70f533eab0a0cabd05ee878b6709707bf63c86 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Tue, 14 Dec 2010 14:54:40 +0000 Subject: NFS: Remove old NFSv2 encoder functions Clean up: Remove unused legacy argument encoder functions, and any now unused encoder helper functions. Signed-off-by: Chuck Lever Tested-by: J. Bruce Fields Signed-off-by: Trond Myklebust --- fs/nfs/nfs2xdr.c | 249 +------------------------------------------------------ 1 file changed, 4 insertions(+), 245 deletions(-) diff --git a/fs/nfs/nfs2xdr.c b/fs/nfs/nfs2xdr.c index 869e2151a2b1..f5ea9dcf08d6 100644 --- a/fs/nfs/nfs2xdr.c +++ b/fs/nfs/nfs2xdr.c @@ -81,13 +81,6 @@ static void prepare_reply_buffer(struct rpc_rqst *req, struct page **pages, /* * Common NFS XDR functions as inlines */ -static inline __be32 * -xdr_encode_fhandle(__be32 *p, const struct nfs_fh *fhandle) -{ - memcpy(p, fhandle->data, NFS2_FHSIZE); - return p + XDR_QUADLEN(NFS2_FHSIZE); -} - static inline __be32 * xdr_decode_fhandle(__be32 *p, struct nfs_fh *fhandle) { @@ -160,36 +153,6 @@ xdr_decode_fattr(__be32 *p, struct nfs_fattr *fattr) return p; } -static inline __be32 * -xdr_encode_sattr(__be32 *p, struct iattr *attr) -{ - const __be32 not_set = __constant_htonl(0xFFFFFFFF); - - *p++ = (attr->ia_valid & ATTR_MODE) ? htonl(attr->ia_mode) : not_set; - *p++ = (attr->ia_valid & ATTR_UID) ? htonl(attr->ia_uid) : not_set; - *p++ = (attr->ia_valid & ATTR_GID) ? htonl(attr->ia_gid) : not_set; - *p++ = (attr->ia_valid & ATTR_SIZE) ? htonl(attr->ia_size) : not_set; - - if (attr->ia_valid & ATTR_ATIME_SET) { - p = xdr_encode_time(p, &attr->ia_atime); - } else if (attr->ia_valid & ATTR_ATIME) { - p = xdr_encode_current_server_time(p, &attr->ia_atime); - } else { - *p++ = not_set; - *p++ = not_set; - } - - if (attr->ia_valid & ATTR_MTIME_SET) { - p = xdr_encode_time(p, &attr->ia_mtime); - } else if (attr->ia_valid & ATTR_MTIME) { - p = xdr_encode_current_server_time(p, &attr->ia_mtime); - } else { - *p++ = not_set; - *p++ = not_set; - } - return p; -} - /* * Encode/decode NFSv2 basic data types * @@ -321,19 +284,11 @@ static void encode_diropargs(struct xdr_stream *xdr, const struct nfs_fh *fh, /* - * NFS encode functions - */ -/* - * Encode file handle argument - * GETATTR, READLINK, STATFS + * NFSv2 XDR encode functions + * + * NFSv2 argument types are defined in section 2.2 of RFC 1094: + * "NFS: Network File System Protocol Specification". */ -static int -nfs_xdr_fhandle(struct rpc_rqst *req, __be32 *p, struct nfs_fh *fh) -{ - p = xdr_encode_fhandle(p, fh); - req->rq_slen = xdr_adjust_iovec(req->rq_svec, p); - return 0; -} static int nfs2_xdr_enc_fhandle(struct rpc_rqst *req, __be32 *p, const struct nfs_fh *fh) @@ -345,18 +300,6 @@ static int nfs2_xdr_enc_fhandle(struct rpc_rqst *req, __be32 *p, return 0; } -/* - * Encode SETATTR arguments - */ -static int -nfs_xdr_sattrargs(struct rpc_rqst *req, __be32 *p, struct nfs_sattrargs *args) -{ - p = xdr_encode_fhandle(p, args->fh); - p = xdr_encode_sattr(p, args->sattr); - req->rq_slen = xdr_adjust_iovec(req->rq_svec, p); - return 0; -} - /* * 2.2.3. sattrargs * @@ -376,19 +319,6 @@ static int nfs2_xdr_enc_sattrargs(struct rpc_rqst *req, __be32 *p, return 0; } -/* - * Encode directory ops argument - * LOOKUP, RMDIR - */ -static int -nfs_xdr_diropargs(struct rpc_rqst *req, __be32 *p, struct nfs_diropargs *args) -{ - p = xdr_encode_fhandle(p, args->fh); - p = xdr_encode_array(p, args->name, args->len); - req->rq_slen = xdr_adjust_iovec(req->rq_svec, p); - return 0; -} - static int nfs2_xdr_enc_diropargs(struct rpc_rqst *req, __be32 *p, const struct nfs_diropargs *args) { @@ -399,18 +329,6 @@ static int nfs2_xdr_enc_diropargs(struct rpc_rqst *req, __be32 *p, return 0; } -/* - * Encode REMOVE argument - */ -static int -nfs_xdr_removeargs(struct rpc_rqst *req, __be32 *p, const struct nfs_removeargs *args) -{ - p = xdr_encode_fhandle(p, args->fh); - p = xdr_encode_array(p, args->name.name, args->name.len); - req->rq_slen = xdr_adjust_iovec(req->rq_svec, p); - return 0; -} - static int nfs2_xdr_enc_readlinkargs(struct rpc_rqst *req, __be32 *p, const struct nfs_readlinkargs *args) { @@ -423,33 +341,6 @@ static int nfs2_xdr_enc_readlinkargs(struct rpc_rqst *req, __be32 *p, return 0; } -/* - * Arguments to a READ call. Since we read data directly into the page - * cache, we also set up the reply iovec here so that iov[1] points - * exactly to the page we want to fetch. - */ -static int -nfs_xdr_readargs(struct rpc_rqst *req, __be32 *p, struct nfs_readargs *args) -{ - struct rpc_auth *auth = req->rq_cred->cr_auth; - unsigned int replen; - u32 offset = (u32)args->offset; - u32 count = args->count; - - p = xdr_encode_fhandle(p, args->fh); - *p++ = htonl(offset); - *p++ = htonl(count); - *p++ = htonl(count); - req->rq_slen = xdr_adjust_iovec(req->rq_svec, p); - - /* Inline the page array */ - replen = (RPC_REPHDRSIZE + auth->au_rslack + NFS_readres_sz) << 2; - xdr_inline_pages(&req->rq_rcv_buf, replen, - args->pages, args->pgbase, count); - req->rq_rcv_buf.flags |= XDRBUF_READ; - return 0; -} - /* * 2.2.7. readargs * @@ -530,29 +421,6 @@ nfs_xdr_readres(struct rpc_rqst *req, __be32 *p, struct nfs_readres *res) } -/* - * Write arguments. Splice the buffer to be written into the iovec. - */ -static int -nfs_xdr_writeargs(struct rpc_rqst *req, __be32 *p, struct nfs_writeargs *args) -{ - struct xdr_buf *sndbuf = &req->rq_snd_buf; - u32 offset = (u32)args->offset; - u32 count = args->count; - - p = xdr_encode_fhandle(p, args->fh); - *p++ = htonl(offset); - *p++ = htonl(offset); - *p++ = htonl(count); - *p++ = htonl(count); - sndbuf->len = xdr_adjust_iovec(sndbuf->head, p); - - /* Copy the page array */ - xdr_encode_pages(sndbuf, args->pages, args->pgbase, count); - sndbuf->flags |= XDRBUF_WRITE; - return 0; -} - /* * 2.2.9. writeargs * @@ -594,20 +462,6 @@ static int nfs2_xdr_enc_writeargs(struct rpc_rqst *req, __be32 *p, return 0; } -/* - * Encode create arguments - * CREATE, MKDIR - */ -static int -nfs_xdr_createargs(struct rpc_rqst *req, __be32 *p, struct nfs_createargs *args) -{ - p = xdr_encode_fhandle(p, args->fh); - p = xdr_encode_array(p, args->name, args->len); - p = xdr_encode_sattr(p, args->sattr); - req->rq_slen = xdr_adjust_iovec(req->rq_svec, p); - return 0; -} - /* * 2.2.10. createargs * @@ -637,20 +491,6 @@ static int nfs2_xdr_enc_removeargs(struct rpc_rqst *req, __be32 *p, return 0; } -/* - * Encode RENAME arguments - */ -static int -nfs_xdr_renameargs(struct rpc_rqst *req, __be32 *p, struct nfs_renameargs *args) -{ - p = xdr_encode_fhandle(p, args->old_dir); - p = xdr_encode_array(p, args->old_name->name, args->old_name->len); - p = xdr_encode_fhandle(p, args->new_dir); - p = xdr_encode_array(p, args->new_name->name, args->new_name->len); - req->rq_slen = xdr_adjust_iovec(req->rq_svec, p); - return 0; -} - /* * 2.2.12. renameargs * @@ -672,19 +512,6 @@ static int nfs2_xdr_enc_renameargs(struct rpc_rqst *req, __be32 *p, return 0; } -/* - * Encode LINK arguments - */ -static int -nfs_xdr_linkargs(struct rpc_rqst *req, __be32 *p, struct nfs_linkargs *args) -{ - p = xdr_encode_fhandle(p, args->fromfh); - p = xdr_encode_fhandle(p, args->tofh); - p = xdr_encode_array(p, args->toname, args->tolen); - req->rq_slen = xdr_adjust_iovec(req->rq_svec, p); - return 0; -} - /* * 2.2.13. linkargs * @@ -704,35 +531,6 @@ static int nfs2_xdr_enc_linkargs(struct rpc_rqst *req, __be32 *p, return 0; } -/* - * Encode SYMLINK arguments - */ -static int -nfs_xdr_symlinkargs(struct rpc_rqst *req, __be32 *p, struct nfs_symlinkargs *args) -{ - struct xdr_buf *sndbuf = &req->rq_snd_buf; - size_t pad; - - p = xdr_encode_fhandle(p, args->fromfh); - p = xdr_encode_array(p, args->fromname, args->fromlen); - *p++ = htonl(args->pathlen); - sndbuf->len = xdr_adjust_iovec(sndbuf->head, p); - - xdr_encode_pages(sndbuf, args->pages, 0, args->pathlen); - - /* - * xdr_encode_pages may have added a few bytes to ensure the - * pathname ends on a 4-byte boundary. Start encoding the - * attributes after the pad bytes. - */ - pad = sndbuf->tail->iov_len; - if (pad > 0) - p++; - p = xdr_encode_sattr(p, args->sattr); - sndbuf->len += xdr_adjust_iovec(sndbuf->tail, p) - pad; - return 0; -} - /* * 2.2.14. symlinkargs * @@ -754,27 +552,6 @@ static int nfs2_xdr_enc_symlinkargs(struct rpc_rqst *req, __be32 *p, return 0; } -/* - * Encode arguments to readdir call - */ -static int -nfs_xdr_readdirargs(struct rpc_rqst *req, __be32 *p, struct nfs_readdirargs *args) -{ - struct rpc_auth *auth = req->rq_cred->cr_auth; - unsigned int replen; - u32 count = args->count; - - p = xdr_encode_fhandle(p, args->fh); - *p++ = htonl(args->cookie); - *p++ = htonl(count); /* see above */ - req->rq_slen = xdr_adjust_iovec(req->rq_svec, p); - - /* Inline the page array */ - replen = (RPC_REPHDRSIZE + auth->au_rslack + NFS_readdirres_sz) << 2; - xdr_inline_pages(&req->rq_rcv_buf, replen, args->pages, 0, count); - return 0; -} - /* * 2.2.17. readdirargs * @@ -947,24 +724,6 @@ nfs_xdr_diropres(struct rpc_rqst *req, __be32 *p, struct nfs_diropok *res) return 0; } -/* - * Encode READLINK args - */ -static int -nfs_xdr_readlinkargs(struct rpc_rqst *req, __be32 *p, struct nfs_readlinkargs *args) -{ - struct rpc_auth *auth = req->rq_cred->cr_auth; - unsigned int replen; - - p = xdr_encode_fhandle(p, args->fh); - req->rq_slen = xdr_adjust_iovec(req->rq_svec, p); - - /* Inline the page array */ - replen = (RPC_REPHDRSIZE + auth->au_rslack + NFS_readlinkres_sz) << 2; - xdr_inline_pages(&req->rq_rcv_buf, replen, args->pages, args->pgbase, args->pglen); - return 0; -} - /* * Decode READLINK reply */ -- cgit v1.2.3 From 282ac2a573dd1be4230710932cd471ed5a3a94b8 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Tue, 14 Dec 2010 14:54:50 +0000 Subject: NFS: Update xdr_encode_foo() functions that we're keeping Clean up. The new helper functions are kept in order by section of RFC 1094. Move the two timestamp encoders we're keeping, update their coding style, and refresh their documenting comments. Signed-off-by: Chuck Lever Tested-by: J. Bruce Fields Signed-off-by: Trond Myklebust --- fs/nfs/nfs2xdr.c | 59 +++++++++++++++++++++++++++++++------------------------- 1 file changed, 33 insertions(+), 26 deletions(-) diff --git a/fs/nfs/nfs2xdr.c b/fs/nfs/nfs2xdr.c index f5ea9dcf08d6..c79977304af8 100644 --- a/fs/nfs/nfs2xdr.c +++ b/fs/nfs/nfs2xdr.c @@ -90,32 +90,6 @@ xdr_decode_fhandle(__be32 *p, struct nfs_fh *fhandle) return p + XDR_QUADLEN(NFS2_FHSIZE); } -static inline __be32* -xdr_encode_time(__be32 *p, const struct timespec *timep) -{ - *p++ = htonl(timep->tv_sec); - /* Convert nanoseconds into microseconds */ - *p++ = htonl(timep->tv_nsec ? timep->tv_nsec / 1000 : 0); - return p; -} - -static inline __be32* -xdr_encode_current_server_time(__be32 *p, const struct timespec *timep) -{ - /* - * Passing the invalid value useconds=1000000 is a - * Sun convention for "set to current server time". - * It's needed to make permissions checks for the - * "touch" program across v2 mounts to Solaris and - * Irix boxes work correctly. See description of - * sattr in section 6.1 of "NFS Illustrated" by - * Brent Callaghan, Addison-Wesley, ISBN 0-201-32750-5 - */ - *p++ = htonl(timep->tv_sec); - *p++ = htonl(1000000); - return p; -} - static inline __be32* xdr_decode_time(__be32 *p, struct timespec *timep) { @@ -178,6 +152,39 @@ static void encode_fhandle(struct xdr_stream *xdr, const struct nfs_fh *fh) memcpy(p, fh->data, NFS2_FHSIZE); } +/* + * 2.3.4. timeval + * + * struct timeval { + * unsigned int seconds; + * unsigned int useconds; + * }; + */ +static __be32 *xdr_encode_time(__be32 *p, const struct timespec *timep) +{ + *p++ = cpu_to_be32(timep->tv_sec); + if (timep->tv_nsec != 0) + *p++ = cpu_to_be32(timep->tv_nsec / NSEC_PER_USEC); + else + *p++ = cpu_to_be32(0); + return p; +} + +/* + * Passing the invalid value useconds=1000000 is a Sun convention for + * "set to current server time". It's needed to make permissions checks + * for the "touch" program across v2 mounts to Solaris and Irix servers + * work correctly. See description of sattr in section 6.1 of "NFS + * Illustrated" by Brent Callaghan, Addison-Wesley, ISBN 0-201-32750-5. + */ +static __be32 *xdr_encode_current_server_time(__be32 *p, + const struct timespec *timep) +{ + *p++ = cpu_to_be32(timep->tv_sec); + *p++ = cpu_to_be32(1000000); + return p; +} + /* * 2.3.6. sattr * -- cgit v1.2.3 From 858284932462cec260f3d1d7426aeb03f5dbc2ad Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Tue, 14 Dec 2010 14:55:00 +0000 Subject: NFS: Use the "nfs_stat" enum for nfs_stat_to_errno()'s argument Clean up. To distinguish more clearly between the on-the-wire NFSERR_ value and our local errno values, use the proper type for the argument of nfs_stat_to_errno(). Add a documenting comment appropriate for a global function shared outside this source file. Signed-off-by: Chuck Lever Tested-by: J. Bruce Fields Signed-off-by: Trond Myklebust --- fs/nfs/internal.h | 2 +- fs/nfs/nfs2xdr.c | 18 ++++++++++-------- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h index e6356b750b77..8c2d9d83771e 100644 --- a/fs/nfs/internal.h +++ b/fs/nfs/internal.h @@ -185,7 +185,7 @@ extern int __init nfs_init_directcache(void); extern void nfs_destroy_directcache(void); /* nfs2xdr.c */ -extern int nfs_stat_to_errno(int); +extern int nfs_stat_to_errno(enum nfs_stat); extern struct rpc_procinfo nfs_procedures[]; extern __be32 *nfs_decode_dirent(struct xdr_stream *, struct nfs_entry *, struct nfs_server *, int); diff --git a/fs/nfs/nfs2xdr.c b/fs/nfs/nfs2xdr.c index c79977304af8..2da9824d432a 100644 --- a/fs/nfs/nfs2xdr.c +++ b/fs/nfs/nfs2xdr.c @@ -804,7 +804,7 @@ nfs_xdr_statfsres(struct rpc_rqst *req, __be32 *p, struct nfs2_fsstat *res) * We need to translate between nfs status return values and * the local errno values which may not be the same. */ -static struct { +static const struct { int stat; int errno; } nfs_errtbl[] = { @@ -844,20 +844,22 @@ static struct { { -1, -EIO } }; -/* - * Convert an NFS error code to a local one. - * This one is used jointly by NFSv2 and NFSv3. +/** + * nfs_stat_to_errno - convert an NFS status code to a local errno + * @status: NFS status code to convert + * + * Returns a local errno value, or -EIO if the NFS status code is + * not recognized. This function is used jointly by NFSv2 and NFSv3. */ -int -nfs_stat_to_errno(int stat) +int nfs_stat_to_errno(enum nfs_stat status) { int i; for (i = 0; nfs_errtbl[i].stat != -1; i++) { - if (nfs_errtbl[i].stat == stat) + if (nfs_errtbl[i].stat == (int)status) return nfs_errtbl[i].errno; } - dprintk("nfs_stat_to_errno: bad nfs status return value: %d\n", stat); + dprintk("NFS: Unrecognized nfs status value: %u\n", status); return nfs_errtbl[i].errno; } -- cgit v1.2.3 From f796f8b3ae292abb9cb2931e8db6fc1d69bba09d Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Tue, 14 Dec 2010 14:55:10 +0000 Subject: NFS: Introduce new-style XDR decoding functions for NFSv2 We'd like to prevent local buffer overflows caused by malicious or broken servers. New xdr_stream style decoders can do that. For efficiency, we also eventually want to be able to pass xdr_streams from call_decode() to all XDR decoding functions, rather than building an xdr_stream in every XDR decoding function in the kernel. nfs_decode_dirent() is renamed to follow the naming convention of the other two dirent decoders. Static helper functions are left without the "inline" directive. This allows the compiler to choose automatically how to optimize these for size or speed. Signed-off-by: Chuck Lever Tested-by: J. Bruce Fields Signed-off-by: Trond Myklebust --- fs/nfs/internal.h | 2 +- fs/nfs/nfs2xdr.c | 564 +++++++++++++++++++++++++++++++++++++++++++++++++++++- fs/nfs/proc.c | 2 +- 3 files changed, 558 insertions(+), 10 deletions(-) diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h index 8c2d9d83771e..6c6a9955bae9 100644 --- a/fs/nfs/internal.h +++ b/fs/nfs/internal.h @@ -187,7 +187,7 @@ extern void nfs_destroy_directcache(void); /* nfs2xdr.c */ extern int nfs_stat_to_errno(enum nfs_stat); extern struct rpc_procinfo nfs_procedures[]; -extern __be32 *nfs_decode_dirent(struct xdr_stream *, struct nfs_entry *, struct nfs_server *, int); +extern __be32 *nfs2_decode_dirent(struct xdr_stream *, struct nfs_entry *, struct nfs_server *, int); /* nfs3xdr.c */ extern struct rpc_procinfo nfs3_procedures[]; diff --git a/fs/nfs/nfs2xdr.c b/fs/nfs/nfs2xdr.c index 2da9824d432a..827d1b8ad55b 100644 --- a/fs/nfs/nfs2xdr.c +++ b/fs/nfs/nfs2xdr.c @@ -77,6 +77,16 @@ static void prepare_reply_buffer(struct rpc_rqst *req, struct page **pages, xdr_inline_pages(&req->rq_rcv_buf, replen << 2, pages, base, len); } +/* + * Handle decode buffer overflows out-of-line. + */ +static void print_overflow_msg(const char *func, const struct xdr_stream *xdr) +{ + dprintk("NFS: %s prematurely hit the end of our receive buffer. " + "Remaining buffer length is %tu words.\n", + func, xdr->end - xdr->p); +} + /* * Common NFS XDR functions as inlines @@ -138,6 +148,74 @@ xdr_decode_fattr(__be32 *p, struct nfs_fattr *fattr) * or decoded inline. */ +/* + * typedef opaque nfsdata<>; + */ +static int decode_nfsdata(struct xdr_stream *xdr, struct nfs_readres *result) +{ + u32 recvd, count; + size_t hdrlen; + __be32 *p; + + p = xdr_inline_decode(xdr, 4); + if (unlikely(p == NULL)) + goto out_overflow; + count = be32_to_cpup(p); + hdrlen = (u8 *)xdr->p - (u8 *)xdr->iov->iov_base; + recvd = xdr->buf->len - hdrlen; + if (unlikely(count > recvd)) + goto out_cheating; +out: + xdr_read_pages(xdr, count); + result->eof = 0; /* NFSv2 does not pass EOF flag on the wire. */ + result->count = count; + return count; +out_cheating: + dprintk("NFS: server cheating in read result: " + "count %u > recvd %u\n", count, recvd); + count = recvd; + goto out; +out_overflow: + print_overflow_msg(__func__, xdr); + return -EIO; +} + +/* + * enum stat { + * NFS_OK = 0, + * NFSERR_PERM = 1, + * NFSERR_NOENT = 2, + * NFSERR_IO = 5, + * NFSERR_NXIO = 6, + * NFSERR_ACCES = 13, + * NFSERR_EXIST = 17, + * NFSERR_NODEV = 19, + * NFSERR_NOTDIR = 20, + * NFSERR_ISDIR = 21, + * NFSERR_FBIG = 27, + * NFSERR_NOSPC = 28, + * NFSERR_ROFS = 30, + * NFSERR_NAMETOOLONG = 63, + * NFSERR_NOTEMPTY = 66, + * NFSERR_DQUOT = 69, + * NFSERR_STALE = 70, + * NFSERR_WFLUSH = 99 + * }; + */ +static int decode_stat(struct xdr_stream *xdr, enum nfs_stat *status) +{ + __be32 *p; + + p = xdr_inline_decode(xdr, 4); + if (unlikely(p == NULL)) + goto out_overflow; + *status = be32_to_cpup(p); + return 0; +out_overflow: + print_overflow_msg(__func__, xdr); + return -EIO; +} + /* * 2.3.3. fhandle * @@ -152,6 +230,21 @@ static void encode_fhandle(struct xdr_stream *xdr, const struct nfs_fh *fh) memcpy(p, fh->data, NFS2_FHSIZE); } +static int decode_fhandle(struct xdr_stream *xdr, struct nfs_fh *fh) +{ + __be32 *p; + + p = xdr_inline_decode(xdr, NFS2_FHSIZE); + if (unlikely(p == NULL)) + goto out_overflow; + fh->size = NFS2_FHSIZE; + memcpy(fh->data, p, NFS2_FHSIZE); + return 0; +out_overflow: + print_overflow_msg(__func__, xdr); + return -EIO; +} + /* * 2.3.4. timeval * @@ -185,6 +278,41 @@ static __be32 *xdr_encode_current_server_time(__be32 *p, return p; } +/* + * 2.3.5. fattr + * + * struct fattr { + * ftype type; + * unsigned int mode; + * unsigned int nlink; + * unsigned int uid; + * unsigned int gid; + * unsigned int size; + * unsigned int blocksize; + * unsigned int rdev; + * unsigned int blocks; + * unsigned int fsid; + * unsigned int fileid; + * timeval atime; + * timeval mtime; + * timeval ctime; + * }; + * + */ +static int decode_fattr(struct xdr_stream *xdr, struct nfs_fattr *fattr) +{ + __be32 *p; + + p = xdr_inline_decode(xdr, NFS_fattr_sz << 2); + if (unlikely(p == NULL)) + goto out_overflow; + xdr_decode_fattr(p, fattr); + return 0; +out_overflow: + print_overflow_msg(__func__, xdr); + return -EIO; +} + /* * 2.3.6. sattr * @@ -259,6 +387,32 @@ static void encode_filename(struct xdr_stream *xdr, xdr_encode_opaque(p, name, length); } +static int decode_filename_inline(struct xdr_stream *xdr, + const char **name, u32 *length) +{ + __be32 *p; + u32 count; + + p = xdr_inline_decode(xdr, 4); + if (unlikely(p == NULL)) + goto out_overflow; + count = be32_to_cpup(p); + if (count > NFS3_MAXNAMLEN) + goto out_nametoolong; + p = xdr_inline_decode(xdr, count); + if (unlikely(p == NULL)) + goto out_overflow; + *name = (const char *)p; + *length = count; + return 0; +out_nametoolong: + dprintk("NFS: returned filename too long: %u\n", count); + return -ENAMETOOLONG; +out_overflow: + print_overflow_msg(__func__, xdr); + return -EIO; +} + /* * 2.3.8. path * @@ -274,6 +428,65 @@ static void encode_path(struct xdr_stream *xdr, struct page **pages, u32 length) xdr_write_pages(xdr, pages, 0, length); } +static int decode_path(struct xdr_stream *xdr) +{ + u32 length, recvd; + size_t hdrlen; + __be32 *p; + + p = xdr_inline_decode(xdr, 4); + if (unlikely(p == NULL)) + goto out_overflow; + length = be32_to_cpup(p); + if (unlikely(length >= xdr->buf->page_len || length > NFS_MAXPATHLEN)) + goto out_size; + hdrlen = (u8 *)xdr->p - (u8 *)xdr->iov->iov_base; + recvd = xdr->buf->len - hdrlen; + if (unlikely(length > recvd)) + goto out_cheating; + + xdr_read_pages(xdr, length); + xdr_terminate_string(xdr->buf, length); + return 0; +out_size: + dprintk("NFS: returned pathname too long: %u\n", length); + return -ENAMETOOLONG; +out_cheating: + dprintk("NFS: server cheating in pathname result: " + "length %u > received %u\n", length, recvd); + return -EIO; +out_overflow: + print_overflow_msg(__func__, xdr); + return -EIO; +} + +/* + * 2.3.9. attrstat + * + * union attrstat switch (stat status) { + * case NFS_OK: + * fattr attributes; + * default: + * void; + * }; + */ +static int decode_attrstat(struct xdr_stream *xdr, struct nfs_fattr *result) +{ + enum nfs_stat status; + int error; + + error = decode_stat(xdr, &status); + if (unlikely(error)) + goto out; + if (status != NFS_OK) + goto out_default; + error = decode_fattr(xdr, result); +out: + return error; +out_default: + return nfs_stat_to_errno(status); +} + /* * 2.3.10. diropargs * @@ -289,6 +502,48 @@ static void encode_diropargs(struct xdr_stream *xdr, const struct nfs_fh *fh, encode_filename(xdr, name, length); } +/* + * 2.3.11. diropres + * + * union diropres switch (stat status) { + * case NFS_OK: + * struct { + * fhandle file; + * fattr attributes; + * } diropok; + * default: + * void; + * }; + */ +static int decode_diropok(struct xdr_stream *xdr, struct nfs_diropok *result) +{ + int error; + + error = decode_fhandle(xdr, result->fh); + if (unlikely(error)) + goto out; + error = decode_fattr(xdr, result->fattr); +out: + return error; +} + +static int decode_diropres(struct xdr_stream *xdr, struct nfs_diropok *result) +{ + enum nfs_stat status; + int error; + + error = decode_stat(xdr, &status); + if (unlikely(error)) + goto out; + if (status != NFS_OK) + goto out_default; + error = decode_diropok(xdr, result); +out: + return error; +out_default: + return nfs_stat_to_errno(status); +} + /* * NFSv2 XDR encode functions @@ -630,13 +885,6 @@ nfs_xdr_readdirres(struct rpc_rqst *req, __be32 *p, void *dummy) return pglen; } -static void print_overflow_msg(const char *func, const struct xdr_stream *xdr) -{ - dprintk("nfs: %s: prematurely hit end of receive buffer. " - "Remaining buffer length is %tu words.\n", - func, xdr->end - xdr->p); -} - __be32 * nfs_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry, struct nfs_server *server, int plus) { @@ -700,6 +948,25 @@ nfs_xdr_stat(struct rpc_rqst *req, __be32 *p, void *dummy) return status; } +static int nfs2_xdr_dec_stat(struct rpc_rqst *req, __be32 *p, + void *__unused) +{ + struct xdr_stream xdr; + enum nfs_stat status; + int error; + + xdr_init_decode(&xdr, &req->rq_rcv_buf, p); + error = decode_stat(&xdr, &status); + if (unlikely(error)) + goto out; + if (status != NFS_OK) + goto out_default; +out: + return error; +out_default: + return nfs_stat_to_errno(status); +} + /* * Decode attrstat reply * GETATTR, SETATTR, WRITE @@ -715,6 +982,15 @@ nfs_xdr_attrstat(struct rpc_rqst *req, __be32 *p, struct nfs_fattr *fattr) return 0; } +static int nfs2_xdr_dec_attrstat(struct rpc_rqst *req, __be32 *p, + struct nfs_fattr *result) +{ + struct xdr_stream xdr; + + xdr_init_decode(&xdr, &req->rq_rcv_buf, p); + return decode_attrstat(&xdr, result); +} + /* * Decode diropres reply * LOOKUP, CREATE, MKDIR @@ -731,6 +1007,15 @@ nfs_xdr_diropres(struct rpc_rqst *req, __be32 *p, struct nfs_diropok *res) return 0; } +static int nfs2_xdr_dec_diropres(struct rpc_rqst *req, __be32 *p, + struct nfs_diropok *result) +{ + struct xdr_stream xdr; + + xdr_init_decode(&xdr, &req->rq_rcv_buf, p); + return decode_diropres(&xdr, result); +} + /* * Decode READLINK reply */ @@ -771,6 +1056,70 @@ nfs_xdr_readlinkres(struct rpc_rqst *req, __be32 *p, void *dummy) return 0; } +/* + * 2.2.6. readlinkres + * + * union readlinkres switch (stat status) { + * case NFS_OK: + * path data; + * default: + * void; + * }; + */ +static int nfs2_xdr_dec_readlinkres(struct rpc_rqst *req, __be32 *p, + void *__unused) +{ + struct xdr_stream xdr; + enum nfs_stat status; + int error; + + xdr_init_decode(&xdr, &req->rq_rcv_buf, p); + error = decode_stat(&xdr, &status); + if (unlikely(error)) + goto out; + if (status != NFS_OK) + goto out_default; + error = decode_path(&xdr); +out: + return error; +out_default: + return nfs_stat_to_errno(status); +} + +/* + * 2.2.7. readres + * + * union readres switch (stat status) { + * case NFS_OK: + * fattr attributes; + * nfsdata data; + * default: + * void; + * }; + */ +static int nfs2_xdr_dec_readres(struct rpc_rqst *req, __be32 *p, + struct nfs_readres *result) +{ + struct xdr_stream xdr; + enum nfs_stat status; + int error; + + xdr_init_decode(&xdr, &req->rq_rcv_buf, p); + error = decode_stat(&xdr, &status); + if (unlikely(error)) + goto out; + if (status != NFS_OK) + goto out_default; + error = decode_fattr(&xdr, result->fattr); + if (unlikely(error)) + goto out; + error = decode_nfsdata(&xdr, result); +out: + return error; +out_default: + return nfs_stat_to_errno(status); +} + /* * Decode WRITE reply */ @@ -781,6 +1130,150 @@ nfs_xdr_writeres(struct rpc_rqst *req, __be32 *p, struct nfs_writeres *res) return nfs_xdr_attrstat(req, p, res->fattr); } +static int nfs2_xdr_dec_writeres(struct rpc_rqst *req, __be32 *p, + struct nfs_writeres *result) +{ + struct xdr_stream xdr; + + /* All NFSv2 writes are "file sync" writes */ + result->verf->committed = NFS_FILE_SYNC; + + xdr_init_decode(&xdr, &req->rq_rcv_buf, p); + return decode_attrstat(&xdr, result->fattr); +} + +/** + * nfs2_decode_dirent - Decode a single NFSv2 directory entry stored in + * the local page cache. + * @xdr: XDR stream where entry resides + * @entry: buffer to fill in with entry data + * @server: nfs_server data for this directory + * @plus: boolean indicating whether this should be a readdirplus entry + * + * Returns the position of the next item in the buffer, or an ERR_PTR. + * + * This function is not invoked during READDIR reply decoding, but + * rather whenever an application invokes the getdents(2) system call + * on a directory already in our cache. + * + * 2.2.17. entry + * + * struct entry { + * unsigned fileid; + * filename name; + * nfscookie cookie; + * entry *nextentry; + * }; + */ +__be32 *nfs2_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry, + struct nfs_server *server, int plus) +{ + __be32 *p; + int error; + + p = xdr_inline_decode(xdr, 4); + if (unlikely(p == NULL)) + goto out_overflow; + if (*p++ == xdr_zero) { + p = xdr_inline_decode(xdr, 4); + if (unlikely(p == NULL)) + goto out_overflow; + if (*p++ == xdr_zero) + return ERR_PTR(-EAGAIN); + entry->eof = 1; + return ERR_PTR(-EBADCOOKIE); + } + + p = xdr_inline_decode(xdr, 4); + if (unlikely(p == NULL)) + goto out_overflow; + entry->ino = be32_to_cpup(p); + + error = decode_filename_inline(xdr, &entry->name, &entry->len); + if (unlikely(error)) + return ERR_PTR(error); + + /* + * The type (size and byte order) of nfscookie isn't defined in + * RFC 1094. This implementation assumes that it's an XDR uint32. + */ + entry->prev_cookie = entry->cookie; + p = xdr_inline_decode(xdr, 4); + if (unlikely(p == NULL)) + goto out_overflow; + entry->cookie = be32_to_cpup(p); + + entry->d_type = DT_UNKNOWN; + + /* Peek at the next entry to see if we're at EOD */ + p = xdr_inline_peek(xdr, 4 + 4); + entry->eof = 0; + if (p != NULL) + entry->eof = (p[0] == xdr_zero) && (p[1] != xdr_zero); + return p; + +out_overflow: + print_overflow_msg(__func__, xdr); + return ERR_PTR(-EAGAIN); +} + +/* + * 2.2.17. readdirres + * + * union readdirres switch (stat status) { + * case NFS_OK: + * struct { + * entry *entries; + * bool eof; + * } readdirok; + * default: + * void; + * }; + * + * Read the directory contents into the page cache, but don't + * touch them. The actual decoding is done by nfs2_decode_dirent() + * during subsequent nfs_readdir() calls. + */ +static int decode_readdirok(struct xdr_stream *xdr) +{ + u32 recvd, pglen; + size_t hdrlen; + + pglen = xdr->buf->page_len; + hdrlen = (u8 *)xdr->p - (u8 *)xdr->iov->iov_base; + recvd = xdr->buf->len - hdrlen; + if (unlikely(pglen > recvd)) + goto out_cheating; +out: + xdr_read_pages(xdr, pglen); + return pglen; +out_cheating: + dprintk("NFS: server cheating in readdir result: " + "pglen %u > recvd %u\n", pglen, recvd); + pglen = recvd; + goto out; +} + +static int nfs2_xdr_dec_readdirres(struct rpc_rqst *req, __be32 *p, + void *__unused) +{ + struct xdr_stream xdr; + enum nfs_stat status; + int error; + + xdr_init_decode(&xdr, &req->rq_rcv_buf, p); + error = decode_stat(&xdr, &status); + if (unlikely(error)) + goto out; + if (status != NFS_OK) + goto out_default; + error = decode_readdirok(&xdr); +out: + return error; +out_default: + return nfs_stat_to_errno(status); +} + /* * Decode STATFS reply */ @@ -800,6 +1293,61 @@ nfs_xdr_statfsres(struct rpc_rqst *req, __be32 *p, struct nfs2_fsstat *res) return 0; } +/* + * 2.2.18. statfsres + * + * union statfsres (stat status) { + * case NFS_OK: + * struct { + * unsigned tsize; + * unsigned bsize; + * unsigned blocks; + * unsigned bfree; + * unsigned bavail; + * } info; + * default: + * void; + * }; + */ +static int decode_info(struct xdr_stream *xdr, struct nfs2_fsstat *result) +{ + __be32 *p; + + p = xdr_inline_decode(xdr, NFS_info_sz << 2); + if (unlikely(p == NULL)) + goto out_overflow; + result->tsize = be32_to_cpup(p++); + result->bsize = be32_to_cpup(p++); + result->blocks = be32_to_cpup(p++); + result->bfree = be32_to_cpup(p++); + result->bavail = be32_to_cpup(p); + return 0; +out_overflow: + print_overflow_msg(__func__, xdr); + return -EIO; +} + +static int nfs2_xdr_dec_statfsres(struct rpc_rqst *req, __be32 *p, + struct nfs2_fsstat *result) +{ + struct xdr_stream xdr; + enum nfs_stat status; + int error; + + xdr_init_decode(&xdr, &req->rq_rcv_buf, p); + error = decode_stat(&xdr, &status); + if (unlikely(error)) + goto out; + if (status != NFS_OK) + goto out_default; + error = decode_info(&xdr, result); +out: + return error; +out_default: + return nfs_stat_to_errno(status); +} + + /* * We need to translate between nfs status return values and * the local errno values which may not be the same. @@ -867,7 +1415,7 @@ int nfs_stat_to_errno(enum nfs_stat status) [NFSPROC_##proc] = { \ .p_proc = NFSPROC_##proc, \ .p_encode = (kxdrproc_t)nfs2_xdr_enc_##argtype, \ - .p_decode = (kxdrproc_t) nfs_xdr_##restype, \ + .p_decode = (kxdrproc_t)nfs2_xdr_dec_##restype, \ .p_arglen = NFS_##argtype##_sz, \ .p_replen = NFS_##restype##_sz, \ .p_timer = timer, \ diff --git a/fs/nfs/proc.c b/fs/nfs/proc.c index 58e7f84fc1fd..00df60523aac 100644 --- a/fs/nfs/proc.c +++ b/fs/nfs/proc.c @@ -731,7 +731,7 @@ const struct nfs_rpc_ops nfs_v2_clientops = { .statfs = nfs_proc_statfs, .fsinfo = nfs_proc_fsinfo, .pathconf = nfs_proc_pathconf, - .decode_dirent = nfs_decode_dirent, + .decode_dirent = nfs2_decode_dirent, .read_setup = nfs_proc_read_setup, .read_done = nfs_read_done, .write_setup = nfs_proc_write_setup, -- cgit v1.2.3 From 661ad4239a51a2169a366a227c68cf3b654ab936 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Tue, 14 Dec 2010 14:55:20 +0000 Subject: NFS: Replace old NFSv2 decoder functions with xdr_stream-based ones Clean up. Remove unused legacy result decoder functions, and any now unused decoder helper functions. Signed-off-by: Chuck Lever Tested-by: J. Bruce Fields Signed-off-by: Trond Myklebust --- fs/nfs/nfs2xdr.c | 253 +------------------------------------------------------ 1 file changed, 4 insertions(+), 249 deletions(-) diff --git a/fs/nfs/nfs2xdr.c b/fs/nfs/nfs2xdr.c index 827d1b8ad55b..ae751163da8b 100644 --- a/fs/nfs/nfs2xdr.c +++ b/fs/nfs/nfs2xdr.c @@ -91,15 +91,6 @@ static void print_overflow_msg(const char *func, const struct xdr_stream *xdr) /* * Common NFS XDR functions as inlines */ -static inline __be32 * -xdr_decode_fhandle(__be32 *p, struct nfs_fh *fhandle) -{ - /* NFSv2 handles have a fixed length */ - fhandle->size = NFS2_FHSIZE; - memcpy(fhandle->data, p, NFS2_FHSIZE); - return p + XDR_QUADLEN(NFS2_FHSIZE); -} - static inline __be32* xdr_decode_time(__be32 *p, struct timespec *timep) { @@ -641,48 +632,6 @@ static int nfs2_xdr_enc_readargs(struct rpc_rqst *req, __be32 *p, return 0; } -/* - * Decode READ reply - */ -static int -nfs_xdr_readres(struct rpc_rqst *req, __be32 *p, struct nfs_readres *res) -{ - struct kvec *iov = req->rq_rcv_buf.head; - size_t hdrlen; - u32 count, recvd; - int status; - - if ((status = ntohl(*p++))) - return nfs_stat_to_errno(status); - p = xdr_decode_fattr(p, res->fattr); - - count = ntohl(*p++); - res->eof = 0; - hdrlen = (u8 *) p - (u8 *) iov->iov_base; - if (iov->iov_len < hdrlen) { - dprintk("NFS: READ reply header overflowed:" - "length %Zu > %Zu\n", hdrlen, iov->iov_len); - return -errno_NFSERR_IO; - } else if (iov->iov_len != hdrlen) { - dprintk("NFS: READ header is short. iovec will be shifted.\n"); - xdr_shift_buf(&req->rq_rcv_buf, iov->iov_len - hdrlen); - } - - recvd = req->rq_rcv_buf.len - hdrlen; - if (count > recvd) { - dprintk("NFS: server cheating in read reply: " - "count %u > recvd %u\n", count, recvd); - count = recvd; - } - - dprintk("RPC: readres OK count %u\n", count); - if (count < res->count) - res->count = count; - - return count; -} - - /* * 2.2.9. writeargs * @@ -848,105 +797,11 @@ static int nfs2_xdr_enc_readdirargs(struct rpc_rqst *req, __be32 *p, } /* - * Decode the result of a readdir call. - * We're not really decoding anymore, we just leave the buffer untouched - * and only check that it is syntactically correct. - * The real decoding happens in nfs_decode_entry below, called directly - * from nfs_readdir for each entry. - */ -static int -nfs_xdr_readdirres(struct rpc_rqst *req, __be32 *p, void *dummy) -{ - struct xdr_buf *rcvbuf = &req->rq_rcv_buf; - struct kvec *iov = rcvbuf->head; - struct page **page; - size_t hdrlen; - unsigned int pglen, recvd; - int status; - - if ((status = ntohl(*p++))) - return nfs_stat_to_errno(status); - - hdrlen = (u8 *) p - (u8 *) iov->iov_base; - if (iov->iov_len < hdrlen) { - dprintk("NFS: READDIR reply header overflowed:" - "length %Zu > %Zu\n", hdrlen, iov->iov_len); - return -errno_NFSERR_IO; - } else if (iov->iov_len != hdrlen) { - dprintk("NFS: READDIR header is short. iovec will be shifted.\n"); - xdr_shift_buf(rcvbuf, iov->iov_len - hdrlen); - } - - pglen = rcvbuf->page_len; - recvd = rcvbuf->len - hdrlen; - if (pglen > recvd) - pglen = recvd; - page = rcvbuf->pages; - return pglen; -} - -__be32 * -nfs_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry, struct nfs_server *server, int plus) -{ - __be32 *p; - p = xdr_inline_decode(xdr, 4); - if (unlikely(!p)) - goto out_overflow; - if (!ntohl(*p++)) { - p = xdr_inline_decode(xdr, 4); - if (unlikely(!p)) - goto out_overflow; - if (!ntohl(*p++)) - return ERR_PTR(-EAGAIN); - entry->eof = 1; - return ERR_PTR(-EBADCOOKIE); - } - - p = xdr_inline_decode(xdr, 8); - if (unlikely(!p)) - goto out_overflow; - - entry->ino = ntohl(*p++); - entry->len = ntohl(*p++); - - p = xdr_inline_decode(xdr, entry->len + 4); - if (unlikely(!p)) - goto out_overflow; - entry->name = (const char *) p; - p += XDR_QUADLEN(entry->len); - entry->prev_cookie = entry->cookie; - entry->cookie = ntohl(*p++); - - entry->d_type = DT_UNKNOWN; - - p = xdr_inline_peek(xdr, 8); - if (p != NULL) - entry->eof = !p[0] && p[1]; - else - entry->eof = 0; - - return p; - -out_overflow: - print_overflow_msg(__func__, xdr); - return ERR_PTR(-EAGAIN); -} - -/* - * NFS XDR decode functions - */ -/* - * Decode simple status reply + * NFSv2 XDR decode functions + * + * NFSv2 result types are defined in section 2.2 of RFC 1094: + * "NFS: Network File System Protocol Specification". */ -static int -nfs_xdr_stat(struct rpc_rqst *req, __be32 *p, void *dummy) -{ - int status; - - if ((status = ntohl(*p++)) != 0) - status = nfs_stat_to_errno(status); - return status; -} static int nfs2_xdr_dec_stat(struct rpc_rqst *req, __be32 *p, void *__unused) @@ -967,21 +822,6 @@ out_default: return nfs_stat_to_errno(status); } -/* - * Decode attrstat reply - * GETATTR, SETATTR, WRITE - */ -static int -nfs_xdr_attrstat(struct rpc_rqst *req, __be32 *p, struct nfs_fattr *fattr) -{ - int status; - - if ((status = ntohl(*p++))) - return nfs_stat_to_errno(status); - xdr_decode_fattr(p, fattr); - return 0; -} - static int nfs2_xdr_dec_attrstat(struct rpc_rqst *req, __be32 *p, struct nfs_fattr *result) { @@ -991,22 +831,6 @@ static int nfs2_xdr_dec_attrstat(struct rpc_rqst *req, __be32 *p, return decode_attrstat(&xdr, result); } -/* - * Decode diropres reply - * LOOKUP, CREATE, MKDIR - */ -static int -nfs_xdr_diropres(struct rpc_rqst *req, __be32 *p, struct nfs_diropok *res) -{ - int status; - - if ((status = ntohl(*p++))) - return nfs_stat_to_errno(status); - p = xdr_decode_fhandle(p, res->fh); - xdr_decode_fattr(p, res->fattr); - return 0; -} - static int nfs2_xdr_dec_diropres(struct rpc_rqst *req, __be32 *p, struct nfs_diropok *result) { @@ -1016,46 +840,6 @@ static int nfs2_xdr_dec_diropres(struct rpc_rqst *req, __be32 *p, return decode_diropres(&xdr, result); } -/* - * Decode READLINK reply - */ -static int -nfs_xdr_readlinkres(struct rpc_rqst *req, __be32 *p, void *dummy) -{ - struct xdr_buf *rcvbuf = &req->rq_rcv_buf; - struct kvec *iov = rcvbuf->head; - size_t hdrlen; - u32 len, recvd; - int status; - - if ((status = ntohl(*p++))) - return nfs_stat_to_errno(status); - /* Convert length of symlink */ - len = ntohl(*p++); - if (len >= rcvbuf->page_len) { - dprintk("nfs: server returned giant symlink!\n"); - return -ENAMETOOLONG; - } - hdrlen = (u8 *) p - (u8 *) iov->iov_base; - if (iov->iov_len < hdrlen) { - dprintk("NFS: READLINK reply header overflowed:" - "length %Zu > %Zu\n", hdrlen, iov->iov_len); - return -errno_NFSERR_IO; - } else if (iov->iov_len != hdrlen) { - dprintk("NFS: READLINK header is short. iovec will be shifted.\n"); - xdr_shift_buf(rcvbuf, iov->iov_len - hdrlen); - } - recvd = req->rq_rcv_buf.len - hdrlen; - if (recvd < len) { - dprintk("NFS: server cheating in readlink reply: " - "count %u > recvd %u\n", len, recvd); - return -EIO; - } - - xdr_terminate_string(rcvbuf, len); - return 0; -} - /* * 2.2.6. readlinkres * @@ -1120,16 +904,6 @@ out_default: return nfs_stat_to_errno(status); } -/* - * Decode WRITE reply - */ -static int -nfs_xdr_writeres(struct rpc_rqst *req, __be32 *p, struct nfs_writeres *res) -{ - res->verf->committed = NFS_FILE_SYNC; - return nfs_xdr_attrstat(req, p, res->fattr); -} - static int nfs2_xdr_dec_writeres(struct rpc_rqst *req, __be32 *p, struct nfs_writeres *result) { @@ -1274,25 +1048,6 @@ out_default: return nfs_stat_to_errno(status); } -/* - * Decode STATFS reply - */ -static int -nfs_xdr_statfsres(struct rpc_rqst *req, __be32 *p, struct nfs2_fsstat *res) -{ - int status; - - if ((status = ntohl(*p++))) - return nfs_stat_to_errno(status); - - res->tsize = ntohl(*p++); - res->bsize = ntohl(*p++); - res->blocks = ntohl(*p++); - res->bfree = ntohl(*p++); - res->bavail = ntohl(*p++); - return 0; -} - /* * 2.2.18. statfsres * -- cgit v1.2.3 From 5f96e5e31b4f4a2f126adfe0586a7555c11b0562 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Tue, 14 Dec 2010 14:55:30 +0000 Subject: NFS: Move and update xdr_decode_foo() functions that we're keeping Clean up. Move the timestamp decoder to match the placement and naming conventions of the other helpers. Fold xdr_decode_fattr() into decode_fattr(), which is now it's only user. Signed-off-by: Chuck Lever Tested-by: J. Bruce Fields Signed-off-by: Trond Myklebust --- fs/nfs/nfs2xdr.c | 97 ++++++++++++++++++++++++++++++++------------------------ 1 file changed, 56 insertions(+), 41 deletions(-) diff --git a/fs/nfs/nfs2xdr.c b/fs/nfs/nfs2xdr.c index ae751163da8b..70df08a84ead 100644 --- a/fs/nfs/nfs2xdr.c +++ b/fs/nfs/nfs2xdr.c @@ -88,46 +88,6 @@ static void print_overflow_msg(const char *func, const struct xdr_stream *xdr) } -/* - * Common NFS XDR functions as inlines - */ -static inline __be32* -xdr_decode_time(__be32 *p, struct timespec *timep) -{ - timep->tv_sec = ntohl(*p++); - /* Convert microseconds into nanoseconds */ - timep->tv_nsec = ntohl(*p++) * 1000; - return p; -} - -static __be32 * -xdr_decode_fattr(__be32 *p, struct nfs_fattr *fattr) -{ - u32 rdev, type; - type = ntohl(*p++); - fattr->mode = ntohl(*p++); - fattr->nlink = ntohl(*p++); - fattr->uid = ntohl(*p++); - fattr->gid = ntohl(*p++); - fattr->size = ntohl(*p++); - fattr->du.nfs2.blocksize = ntohl(*p++); - rdev = ntohl(*p++); - fattr->du.nfs2.blocks = ntohl(*p++); - fattr->fsid.major = ntohl(*p++); - fattr->fsid.minor = 0; - fattr->fileid = ntohl(*p++); - p = xdr_decode_time(p, &fattr->atime); - p = xdr_decode_time(p, &fattr->mtime); - p = xdr_decode_time(p, &fattr->ctime); - fattr->valid |= NFS_ATTR_FATTR_V2; - fattr->rdev = new_decode_dev(rdev); - if (type == NFCHR && rdev == NFS2_FIFO_DEV) { - fattr->mode = (fattr->mode & ~S_IFMT) | S_IFIFO; - fattr->rdev = 0; - } - return p; -} - /* * Encode/decode NFSv2 basic data types * @@ -207,6 +167,27 @@ out_overflow: return -EIO; } +/* + * 2.3.2. ftype + * + * enum ftype { + * NFNON = 0, + * NFREG = 1, + * NFDIR = 2, + * NFBLK = 3, + * NFCHR = 4, + * NFLNK = 5 + * }; + * + */ +static __be32 *xdr_decode_ftype(__be32 *p, u32 *type) +{ + *type = be32_to_cpup(p++); + if (unlikely(*type > NF2FIFO)) + *type = NFBAD; + return p; +} + /* * 2.3.3. fhandle * @@ -269,6 +250,13 @@ static __be32 *xdr_encode_current_server_time(__be32 *p, return p; } +static __be32 *xdr_decode_time(__be32 *p, struct timespec *timep) +{ + timep->tv_sec = be32_to_cpup(p++); + timep->tv_nsec = be32_to_cpup(p++) * NSEC_PER_USEC; + return p; +} + /* * 2.3.5. fattr * @@ -292,12 +280,39 @@ static __be32 *xdr_encode_current_server_time(__be32 *p, */ static int decode_fattr(struct xdr_stream *xdr, struct nfs_fattr *fattr) { + u32 rdev, type; __be32 *p; p = xdr_inline_decode(xdr, NFS_fattr_sz << 2); if (unlikely(p == NULL)) goto out_overflow; - xdr_decode_fattr(p, fattr); + + fattr->valid |= NFS_ATTR_FATTR_V2; + + p = xdr_decode_ftype(p, &type); + + fattr->mode = be32_to_cpup(p++); + fattr->nlink = be32_to_cpup(p++); + fattr->uid = be32_to_cpup(p++); + fattr->gid = be32_to_cpup(p++); + fattr->size = be32_to_cpup(p++); + fattr->du.nfs2.blocksize = be32_to_cpup(p++); + + rdev = be32_to_cpup(p++); + fattr->rdev = new_decode_dev(rdev); + if (type == (u32)NFCHR && rdev == (u32)NFS2_FIFO_DEV) { + fattr->mode = (fattr->mode & ~S_IFMT) | S_IFIFO; + fattr->rdev = 0; + } + + fattr->du.nfs2.blocks = be32_to_cpup(p++); + fattr->fsid.major = be32_to_cpup(p++); + fattr->fsid.minor = 0; + fattr->fileid = be32_to_cpup(p++); + + p = xdr_decode_time(p, &fattr->atime); + p = xdr_decode_time(p, &fattr->mtime); + xdr_decode_time(p, &fattr->ctime); return 0; out_overflow: print_overflow_msg(__func__, xdr); -- cgit v1.2.3 From 2b061f9ef216b6d229b06267f188167fd6ab3d9b Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Tue, 14 Dec 2010 14:55:40 +0000 Subject: lockd: Introduce new-style XDR functions for NLMv3 We'd like to prevent local buffer overflows caused by malicious or broken servers. New xdr_stream style decoders can do that. For efficiency, we also eventually want to be able to pass xdr_streams from call_encode() and call_decode() to all XDR encoding functions, rather than building an xdr_stream in every XDR encoding and decoding function in the kernel. To do all of this, rewrite the XDR encoding and decoding functions in fs/lockd/xdr.c to use xdr_streams. This makes them more or less incompatible with server-side XDR helper functions, so break them out into a separate source file. Static helper functions are left without the "inline" directive. This allows the compiler to choose automatically how to optimize these for size or speed. SHARE-related functionality doesn't seem to be used, as those functions are hiding behind a #define that isn't set anywhere that I can find. And, they've been in there forever (at least as far back as the kernel's git history goes), yet remain unused. Let's take the opportunity to bin them. It should be easy enough for someone to introduce proper XDR functions if at some point SHARE-related NLM functionality is desired. Signed-off-by: Chuck Lever Tested-by: J. Bruce Fields Signed-off-by: Trond Myklebust --- fs/lockd/Makefile | 4 +- fs/lockd/clntxdr.c | 643 +++++++++++++++++++++++++++++++++++++++++++++++++++++ fs/lockd/xdr.c | 258 --------------------- 3 files changed, 645 insertions(+), 260 deletions(-) create mode 100644 fs/lockd/clntxdr.c diff --git a/fs/lockd/Makefile b/fs/lockd/Makefile index 97f6073ab339..d0488b3bd00b 100644 --- a/fs/lockd/Makefile +++ b/fs/lockd/Makefile @@ -4,7 +4,7 @@ obj-$(CONFIG_LOCKD) += lockd.o -lockd-objs-y := clntlock.o clntproc.o host.o svc.o svclock.o svcshare.o \ - svcproc.o svcsubs.o mon.o xdr.o grace.o +lockd-objs-y := clntlock.o clntproc.o clntxdr.o host.o svc.o svclock.o \ + svcshare.o svcproc.o svcsubs.o mon.o xdr.o grace.o lockd-objs-$(CONFIG_LOCKD_V4) += xdr4.o svc4proc.o lockd-objs := $(lockd-objs-y) diff --git a/fs/lockd/clntxdr.c b/fs/lockd/clntxdr.c new file mode 100644 index 000000000000..0472f2aff509 --- /dev/null +++ b/fs/lockd/clntxdr.c @@ -0,0 +1,643 @@ +/* + * linux/fs/lockd/clntxdr.c + * + * XDR functions to encode/decode NLM version 3 RPC arguments and results. + * NLM version 3 is backwards compatible with NLM versions 1 and 2. + * + * NLM client-side only. + * + * Copyright (C) 2010, Oracle. All rights reserved. + */ + +#include +#include +#include +#include +#include + +#define NLMDBG_FACILITY NLMDBG_XDR + +#if (NLMCLNT_OHSIZE > XDR_MAX_NETOBJ) +# error "NLM host name cannot be larger than XDR_MAX_NETOBJ!" +#endif + +/* + * Declare the space requirements for NLM arguments and replies as + * number of 32bit-words + */ +#define NLM_cookie_sz (1+(NLM_MAXCOOKIELEN>>2)) +#define NLM_caller_sz (1+(NLMCLNT_OHSIZE>>2)) +#define NLM_owner_sz (1+(NLMCLNT_OHSIZE>>2)) +#define NLM_fhandle_sz (1+(NFS2_FHSIZE>>2)) +#define NLM_lock_sz (3+NLM_caller_sz+NLM_owner_sz+NLM_fhandle_sz) +#define NLM_holder_sz (4+NLM_owner_sz) + +#define NLM_testargs_sz (NLM_cookie_sz+1+NLM_lock_sz) +#define NLM_lockargs_sz (NLM_cookie_sz+4+NLM_lock_sz) +#define NLM_cancargs_sz (NLM_cookie_sz+2+NLM_lock_sz) +#define NLM_unlockargs_sz (NLM_cookie_sz+NLM_lock_sz) + +#define NLM_testres_sz (NLM_cookie_sz+1+NLM_holder_sz) +#define NLM_res_sz (NLM_cookie_sz+1) +#define NLM_norep_sz (0) + + +static s32 loff_t_to_s32(loff_t offset) +{ + s32 res; + + if (offset >= NLM_OFFSET_MAX) + res = NLM_OFFSET_MAX; + else if (offset <= -NLM_OFFSET_MAX) + res = -NLM_OFFSET_MAX; + else + res = offset; + return res; +} + +static void nlm_compute_offsets(const struct nlm_lock *lock, + u32 *l_offset, u32 *l_len) +{ + const struct file_lock *fl = &lock->fl; + + BUG_ON(fl->fl_start > NLM_OFFSET_MAX); + BUG_ON(fl->fl_end > NLM_OFFSET_MAX && + fl->fl_end != OFFSET_MAX); + + *l_offset = loff_t_to_s32(fl->fl_start); + if (fl->fl_end == OFFSET_MAX) + *l_len = 0; + else + *l_len = loff_t_to_s32(fl->fl_end - fl->fl_start + 1); +} + +/* + * Handle decode buffer overflows out-of-line. + */ +static void print_overflow_msg(const char *func, const struct xdr_stream *xdr) +{ + dprintk("lockd: %s prematurely hit the end of our receive buffer. " + "Remaining buffer length is %tu words.\n", + func, xdr->end - xdr->p); +} + + +/* + * Encode/decode NLMv3 basic data types + * + * Basic NLMv3 data types are not defined in an IETF standards + * document. X/Open has a description of these data types that + * is useful. See Chapter 10 of "Protocols for Interworking: + * XNFS, Version 3W". + * + * Not all basic data types have their own encoding and decoding + * functions. For run-time efficiency, some data types are encoded + * or decoded inline. + */ + +static void encode_bool(struct xdr_stream *xdr, const int value) +{ + __be32 *p; + + p = xdr_reserve_space(xdr, 4); + *p = value ? xdr_one : xdr_zero; +} + +static void encode_int32(struct xdr_stream *xdr, const s32 value) +{ + __be32 *p; + + p = xdr_reserve_space(xdr, 4); + *p = cpu_to_be32(value); +} + +/* + * typedef opaque netobj + */ +static void encode_netobj(struct xdr_stream *xdr, + const u8 *data, const unsigned int length) +{ + __be32 *p; + + BUG_ON(length > XDR_MAX_NETOBJ); + p = xdr_reserve_space(xdr, 4 + length); + xdr_encode_opaque(p, data, length); +} + +static int decode_netobj(struct xdr_stream *xdr, + struct xdr_netobj *obj) +{ + u32 length; + __be32 *p; + + p = xdr_inline_decode(xdr, 4); + if (unlikely(p == NULL)) + goto out_overflow; + length = be32_to_cpup(p++); + if (unlikely(length > XDR_MAX_NETOBJ)) + goto out_size; + obj->len = length; + obj->data = (u8 *)p; + return 0; +out_size: + dprintk("NFS: returned netobj was too long: %u\n", length); + return -EIO; +out_overflow: + print_overflow_msg(__func__, xdr); + return -EIO; +} + +/* + * netobj cookie; + */ +static void encode_cookie(struct xdr_stream *xdr, + const struct nlm_cookie *cookie) +{ + BUG_ON(cookie->len > NLM_MAXCOOKIELEN); + encode_netobj(xdr, (u8 *)&cookie->data, cookie->len); +} + +static int decode_cookie(struct xdr_stream *xdr, + struct nlm_cookie *cookie) +{ + u32 length; + __be32 *p; + + p = xdr_inline_decode(xdr, 4); + if (unlikely(p == NULL)) + goto out_overflow; + length = be32_to_cpup(p++); + /* apparently HPUX can return empty cookies */ + if (length == 0) + goto out_hpux; + if (length > NLM_MAXCOOKIELEN) + goto out_size; + p = xdr_inline_decode(xdr, length); + if (unlikely(p == NULL)) + goto out_overflow; + cookie->len = length; + memcpy(cookie->data, p, length); + return 0; +out_hpux: + cookie->len = 4; + memset(cookie->data, 0, 4); + return 0; +out_size: + dprintk("NFS: returned cookie was too long: %u\n", length); + return -EIO; +out_overflow: + print_overflow_msg(__func__, xdr); + return -EIO; +} + +/* + * netobj fh; + */ +static void encode_fh(struct xdr_stream *xdr, const struct nfs_fh *fh) +{ + BUG_ON(fh->size != NFS2_FHSIZE); + encode_netobj(xdr, (u8 *)&fh->data, NFS2_FHSIZE); +} + +/* + * enum nlm_stats { + * LCK_GRANTED = 0, + * LCK_DENIED = 1, + * LCK_DENIED_NOLOCKS = 2, + * LCK_BLOCKED = 3, + * LCK_DENIED_GRACE_PERIOD = 4 + * }; + * + * + * struct nlm_stat { + * nlm_stats stat; + * }; + * + * NB: we don't swap bytes for the NLM status values. The upper + * layers deal directly with the status value in network byte + * order. + */ + +static void encode_nlm_stat(struct xdr_stream *xdr, + const __be32 stat) +{ + __be32 *p; + + BUG_ON(be32_to_cpu(stat) > NLM_LCK_DENIED_GRACE_PERIOD); + p = xdr_reserve_space(xdr, 4); + *p = stat; +} + +static int decode_nlm_stat(struct xdr_stream *xdr, + __be32 *stat) +{ + __be32 *p; + + p = xdr_inline_decode(xdr, 4); + if (unlikely(p == NULL)) + goto out_overflow; + if (unlikely(*p > nlm_lck_denied_grace_period)) + goto out_enum; + *stat = *p; + return 0; +out_enum: + dprintk("%s: server returned invalid nlm_stats value: %u\n", + __func__, be32_to_cpup(p)); + return -EIO; +out_overflow: + print_overflow_msg(__func__, xdr); + return -EIO; +} + +/* + * struct nlm_holder { + * bool exclusive; + * int uppid; + * netobj oh; + * unsigned l_offset; + * unsigned l_len; + * }; + */ +static void encode_nlm_holder(struct xdr_stream *xdr, + const struct nlm_res *result) +{ + const struct nlm_lock *lock = &result->lock; + u32 l_offset, l_len; + __be32 *p; + + encode_bool(xdr, lock->fl.fl_type == F_RDLCK); + encode_int32(xdr, lock->svid); + encode_netobj(xdr, lock->oh.data, lock->oh.len); + + p = xdr_reserve_space(xdr, 4 + 4); + nlm_compute_offsets(lock, &l_offset, &l_len); + *p++ = cpu_to_be32(l_offset); + *p = cpu_to_be32(l_len); +} + +static int decode_nlm_holder(struct xdr_stream *xdr, struct nlm_res *result) +{ + struct nlm_lock *lock = &result->lock; + struct file_lock *fl = &lock->fl; + u32 exclusive, l_offset, l_len; + int error; + __be32 *p; + s32 end; + + memset(lock, 0, sizeof(*lock)); + locks_init_lock(fl); + + p = xdr_inline_decode(xdr, 4 + 4); + if (unlikely(p == NULL)) + goto out_overflow; + exclusive = be32_to_cpup(p++); + lock->svid = be32_to_cpup(p); + fl->fl_pid = (pid_t)lock->svid; + + error = decode_netobj(xdr, &lock->oh); + if (unlikely(error)) + goto out; + + p = xdr_inline_decode(xdr, 4 + 4); + if (unlikely(p == NULL)) + goto out_overflow; + + fl->fl_flags = FL_POSIX; + fl->fl_type = exclusive != 0 ? F_WRLCK : F_RDLCK; + l_offset = be32_to_cpup(p++); + l_len = be32_to_cpup(p); + end = l_offset + l_len - 1; + + fl->fl_start = (loff_t)l_offset; + if (l_len == 0 || end < 0) + fl->fl_end = OFFSET_MAX; + else + fl->fl_end = (loff_t)end; + error = 0; +out: + return error; +out_overflow: + print_overflow_msg(__func__, xdr); + return -EIO; +} + +/* + * string caller_name; + */ +static void encode_caller_name(struct xdr_stream *xdr, const char *name) +{ + /* NB: client-side does not set lock->len */ + u32 length = strlen(name); + __be32 *p; + + BUG_ON(length > NLM_MAXSTRLEN); + p = xdr_reserve_space(xdr, 4 + length); + xdr_encode_opaque(p, name, length); +} + +/* + * struct nlm_lock { + * string caller_name; + * netobj fh; + * netobj oh; + * int uppid; + * unsigned l_offset; + * unsigned l_len; + * }; + */ +static void encode_nlm_lock(struct xdr_stream *xdr, + const struct nlm_lock *lock) +{ + u32 l_offset, l_len; + __be32 *p; + + encode_caller_name(xdr, lock->caller); + encode_fh(xdr, &lock->fh); + encode_netobj(xdr, lock->oh.data, lock->oh.len); + + p = xdr_reserve_space(xdr, 4 + 4 + 4); + *p++ = cpu_to_be32(lock->svid); + + nlm_compute_offsets(lock, &l_offset, &l_len); + *p++ = cpu_to_be32(l_offset); + *p = cpu_to_be32(l_len); +} + + +/* + * NLMv3 XDR encode functions + * + * NLMv3 argument types are defined in Chapter 10 of The Open Group's + * "Protocols for Interworking: XNFS, Version 3W". + */ + +/* + * struct nlm_testargs { + * netobj cookie; + * bool exclusive; + * struct nlm_lock alock; + * }; + */ +static int nlm_xdr_enc_testargs(struct rpc_rqst *req, __be32 *p, + const struct nlm_args *args) +{ + const struct nlm_lock *lock = &args->lock; + struct xdr_stream xdr; + + xdr_init_encode(&xdr, &req->rq_snd_buf, p); + encode_cookie(&xdr, &args->cookie); + encode_bool(&xdr, lock->fl.fl_type == F_WRLCK); + encode_nlm_lock(&xdr, lock); + return 0; +} + +/* + * struct nlm_lockargs { + * netobj cookie; + * bool block; + * bool exclusive; + * struct nlm_lock alock; + * bool reclaim; + * int state; + * }; + */ +static int nlm_xdr_enc_lockargs(struct rpc_rqst *req, __be32 *p, + const struct nlm_args *args) +{ + const struct nlm_lock *lock = &args->lock; + struct xdr_stream xdr; + + xdr_init_encode(&xdr, &req->rq_snd_buf, p); + encode_cookie(&xdr, &args->cookie); + encode_bool(&xdr, args->block); + encode_bool(&xdr, lock->fl.fl_type == F_WRLCK); + encode_nlm_lock(&xdr, lock); + encode_bool(&xdr, args->reclaim); + encode_int32(&xdr, args->state); + return 0; +} + +/* + * struct nlm_cancargs { + * netobj cookie; + * bool block; + * bool exclusive; + * struct nlm_lock alock; + * }; + */ +static int nlm_xdr_enc_cancargs(struct rpc_rqst *req, __be32 *p, + const struct nlm_args *args) +{ + const struct nlm_lock *lock = &args->lock; + struct xdr_stream xdr; + + xdr_init_encode(&xdr, &req->rq_snd_buf, p); + encode_cookie(&xdr, &args->cookie); + encode_bool(&xdr, args->block); + encode_bool(&xdr, lock->fl.fl_type == F_WRLCK); + encode_nlm_lock(&xdr, lock); + return 0; +} + +/* + * struct nlm_unlockargs { + * netobj cookie; + * struct nlm_lock alock; + * }; + */ +static int nlm_xdr_enc_unlockargs(struct rpc_rqst *req, __be32 *p, + const struct nlm_args *args) +{ + const struct nlm_lock *lock = &args->lock; + struct xdr_stream xdr; + + xdr_init_encode(&xdr, &req->rq_snd_buf, p); + encode_cookie(&xdr, &args->cookie); + encode_nlm_lock(&xdr, lock); + return 0; +} + +/* + * struct nlm_res { + * netobj cookie; + * nlm_stat stat; + * }; + */ +static int nlm_xdr_enc_res(struct rpc_rqst *req, __be32 *p, + const struct nlm_res *result) +{ + struct xdr_stream xdr; + + xdr_init_encode(&xdr, &req->rq_snd_buf, p); + encode_cookie(&xdr, &result->cookie); + encode_nlm_stat(&xdr, result->status); + return 0; +} + +/* + * union nlm_testrply switch (nlm_stats stat) { + * case LCK_DENIED: + * struct nlm_holder holder; + * default: + * void; + * }; + * + * struct nlm_testres { + * netobj cookie; + * nlm_testrply test_stat; + * }; + */ +static void encode_nlm_testrply(struct xdr_stream *xdr, + const struct nlm_res *result) +{ + if (result->status == nlm_lck_denied) + encode_nlm_holder(xdr, result); +} + +static int nlm_xdr_enc_testres(struct rpc_rqst *req, __be32 *p, + const struct nlm_res *result) +{ + struct xdr_stream xdr; + + xdr_init_encode(&xdr, &req->rq_snd_buf, p); + encode_cookie(&xdr, &result->cookie); + encode_nlm_stat(&xdr, result->status); + encode_nlm_testrply(&xdr, result); + return 0; +} + + +/* + * NLMv3 XDR decode functions + * + * NLMv3 result types are defined in Chapter 10 of The Open Group's + * "Protocols for Interworking: XNFS, Version 3W". + */ + +/* + * union nlm_testrply switch (nlm_stats stat) { + * case LCK_DENIED: + * struct nlm_holder holder; + * default: + * void; + * }; + * + * struct nlm_testres { + * netobj cookie; + * nlm_testrply test_stat; + * }; + */ +static int decode_nlm_testrply(struct xdr_stream *xdr, + struct nlm_res *result) +{ + int error; + + error = decode_nlm_stat(xdr, &result->status); + if (unlikely(error)) + goto out; + if (result->status == nlm_lck_denied) + error = decode_nlm_holder(xdr, result); +out: + return error; +} + +static int nlm_xdr_dec_testres(struct rpc_rqst *req, __be32 *p, + struct nlm_res *result) +{ + struct xdr_stream xdr; + int error; + + xdr_init_decode(&xdr, &req->rq_rcv_buf, p); + error = decode_cookie(&xdr, &result->cookie); + if (unlikely(error)) + goto out; + error = decode_nlm_testrply(&xdr, result); +out: + return error; +} + +/* + * struct nlm_res { + * netobj cookie; + * nlm_stat stat; + * }; + */ +static int nlm_xdr_dec_res(struct rpc_rqst *req, __be32 *p, + struct nlm_res *result) +{ + struct xdr_stream xdr; + int error; + + xdr_init_decode(&xdr, &req->rq_rcv_buf, p); + error = decode_cookie(&xdr, &result->cookie); + if (unlikely(error)) + goto out; + error = decode_nlm_stat(&xdr, &result->status); +out: + return error; +} + + +/* + * For NLM, a void procedure really returns nothing + */ +#define nlm_xdr_dec_norep NULL + +#define PROC(proc, argtype, restype) \ +[NLMPROC_##proc] = { \ + .p_proc = NLMPROC_##proc, \ + .p_encode = (kxdrproc_t)nlm_xdr_enc_##argtype, \ + .p_decode = (kxdrproc_t)nlm_xdr_dec_##restype, \ + .p_arglen = NLM_##argtype##_sz, \ + .p_replen = NLM_##restype##_sz, \ + .p_statidx = NLMPROC_##proc, \ + .p_name = #proc, \ + } + +static struct rpc_procinfo nlm_procedures[] = { + PROC(TEST, testargs, testres), + PROC(LOCK, lockargs, res), + PROC(CANCEL, cancargs, res), + PROC(UNLOCK, unlockargs, res), + PROC(GRANTED, testargs, res), + PROC(TEST_MSG, testargs, norep), + PROC(LOCK_MSG, lockargs, norep), + PROC(CANCEL_MSG, cancargs, norep), + PROC(UNLOCK_MSG, unlockargs, norep), + PROC(GRANTED_MSG, testargs, norep), + PROC(TEST_RES, testres, norep), + PROC(LOCK_RES, res, norep), + PROC(CANCEL_RES, res, norep), + PROC(UNLOCK_RES, res, norep), + PROC(GRANTED_RES, res, norep), +}; + +static struct rpc_version nlm_version1 = { + .number = 1, + .nrprocs = ARRAY_SIZE(nlm_procedures), + .procs = nlm_procedures, +}; + +static struct rpc_version nlm_version3 = { + .number = 3, + .nrprocs = ARRAY_SIZE(nlm_procedures), + .procs = nlm_procedures, +}; + +static struct rpc_version *nlm_versions[] = { + [1] = &nlm_version1, + [3] = &nlm_version3, +#ifdef CONFIG_LOCKD_V4 + [4] = &nlm_version4, +#endif +}; + +static struct rpc_stat nlm_rpc_stats; + +struct rpc_program nlm_program = { + .name = "lockd", + .number = NLM_PROGRAM, + .nrvers = ARRAY_SIZE(nlm_versions), + .version = nlm_versions, + .stats = &nlm_rpc_stats, +}; diff --git a/fs/lockd/xdr.c b/fs/lockd/xdr.c index b583ab0a4cbb..0eb694dc497b 100644 --- a/fs/lockd/xdr.c +++ b/fs/lockd/xdr.c @@ -148,37 +148,6 @@ nlm_decode_lock(__be32 *p, struct nlm_lock *lock) return p; } -/* - * Encode a lock as part of an NLM call - */ -static __be32 * -nlm_encode_lock(__be32 *p, struct nlm_lock *lock) -{ - struct file_lock *fl = &lock->fl; - __s32 start, len; - - if (!(p = xdr_encode_string(p, lock->caller)) - || !(p = nlm_encode_fh(p, &lock->fh)) - || !(p = nlm_encode_oh(p, &lock->oh))) - return NULL; - - if (fl->fl_start > NLM_OFFSET_MAX - || (fl->fl_end > NLM_OFFSET_MAX && fl->fl_end != OFFSET_MAX)) - return NULL; - - start = loff_t_to_s32(fl->fl_start); - if (fl->fl_end == OFFSET_MAX) - len = 0; - else - len = loff_t_to_s32(fl->fl_end - fl->fl_start + 1); - - *p++ = htonl(lock->svid); - *p++ = htonl(start); - *p++ = htonl(len); - - return p; -} - /* * Encode result of a TEST/TEST_MSG call */ @@ -373,233 +342,6 @@ nlmsvc_encode_void(struct svc_rqst *rqstp, __be32 *p, void *dummy) return xdr_ressize_check(rqstp, p); } -/* - * Now, the client side XDR functions - */ -#ifdef NLMCLNT_SUPPORT_SHARES -static int -nlmclt_decode_void(struct rpc_rqst *req, u32 *p, void *ptr) -{ - return 0; -} -#endif - -static int -nlmclt_encode_testargs(struct rpc_rqst *req, __be32 *p, nlm_args *argp) -{ - struct nlm_lock *lock = &argp->lock; - - if (!(p = nlm_encode_cookie(p, &argp->cookie))) - return -EIO; - *p++ = (lock->fl.fl_type == F_WRLCK)? xdr_one : xdr_zero; - if (!(p = nlm_encode_lock(p, lock))) - return -EIO; - req->rq_slen = xdr_adjust_iovec(req->rq_svec, p); - return 0; -} - -static int -nlmclt_decode_testres(struct rpc_rqst *req, __be32 *p, struct nlm_res *resp) -{ - if (!(p = nlm_decode_cookie(p, &resp->cookie))) - return -EIO; - resp->status = *p++; - if (resp->status == nlm_lck_denied) { - struct file_lock *fl = &resp->lock.fl; - u32 excl; - s32 start, len, end; - - memset(&resp->lock, 0, sizeof(resp->lock)); - locks_init_lock(fl); - excl = ntohl(*p++); - resp->lock.svid = ntohl(*p++); - fl->fl_pid = (pid_t)resp->lock.svid; - if (!(p = nlm_decode_oh(p, &resp->lock.oh))) - return -EIO; - - fl->fl_flags = FL_POSIX; - fl->fl_type = excl? F_WRLCK : F_RDLCK; - start = ntohl(*p++); - len = ntohl(*p++); - end = start + len - 1; - - fl->fl_start = s32_to_loff_t(start); - if (len == 0 || end < 0) - fl->fl_end = OFFSET_MAX; - else - fl->fl_end = s32_to_loff_t(end); - } - return 0; -} - - -static int -nlmclt_encode_lockargs(struct rpc_rqst *req, __be32 *p, nlm_args *argp) -{ - struct nlm_lock *lock = &argp->lock; - - if (!(p = nlm_encode_cookie(p, &argp->cookie))) - return -EIO; - *p++ = argp->block? xdr_one : xdr_zero; - *p++ = (lock->fl.fl_type == F_WRLCK)? xdr_one : xdr_zero; - if (!(p = nlm_encode_lock(p, lock))) - return -EIO; - *p++ = argp->reclaim? xdr_one : xdr_zero; - *p++ = htonl(argp->state); - req->rq_slen = xdr_adjust_iovec(req->rq_svec, p); - return 0; -} - -static int -nlmclt_encode_cancargs(struct rpc_rqst *req, __be32 *p, nlm_args *argp) -{ - struct nlm_lock *lock = &argp->lock; - - if (!(p = nlm_encode_cookie(p, &argp->cookie))) - return -EIO; - *p++ = argp->block? xdr_one : xdr_zero; - *p++ = (lock->fl.fl_type == F_WRLCK)? xdr_one : xdr_zero; - if (!(p = nlm_encode_lock(p, lock))) - return -EIO; - req->rq_slen = xdr_adjust_iovec(req->rq_svec, p); - return 0; -} - -static int -nlmclt_encode_unlockargs(struct rpc_rqst *req, __be32 *p, nlm_args *argp) -{ - struct nlm_lock *lock = &argp->lock; - - if (!(p = nlm_encode_cookie(p, &argp->cookie))) - return -EIO; - if (!(p = nlm_encode_lock(p, lock))) - return -EIO; - req->rq_slen = xdr_adjust_iovec(req->rq_svec, p); - return 0; -} - -static int -nlmclt_encode_res(struct rpc_rqst *req, __be32 *p, struct nlm_res *resp) -{ - if (!(p = nlm_encode_cookie(p, &resp->cookie))) - return -EIO; - *p++ = resp->status; - req->rq_slen = xdr_adjust_iovec(req->rq_svec, p); - return 0; -} - -static int -nlmclt_encode_testres(struct rpc_rqst *req, __be32 *p, struct nlm_res *resp) -{ - if (!(p = nlm_encode_testres(p, resp))) - return -EIO; - req->rq_slen = xdr_adjust_iovec(req->rq_svec, p); - return 0; -} - -static int -nlmclt_decode_res(struct rpc_rqst *req, __be32 *p, struct nlm_res *resp) -{ - if (!(p = nlm_decode_cookie(p, &resp->cookie))) - return -EIO; - resp->status = *p++; - return 0; -} - -#if (NLMCLNT_OHSIZE > XDR_MAX_NETOBJ) -# error "NLM host name cannot be larger than XDR_MAX_NETOBJ!" -#endif - -/* - * Buffer requirements for NLM - */ -#define NLM_void_sz 0 -#define NLM_cookie_sz 1+XDR_QUADLEN(NLM_MAXCOOKIELEN) -#define NLM_caller_sz 1+XDR_QUADLEN(NLMCLNT_OHSIZE) -#define NLM_owner_sz 1+XDR_QUADLEN(NLMCLNT_OHSIZE) -#define NLM_fhandle_sz 1+XDR_QUADLEN(NFS2_FHSIZE) -#define NLM_lock_sz 3+NLM_caller_sz+NLM_owner_sz+NLM_fhandle_sz -#define NLM_holder_sz 4+NLM_owner_sz - -#define NLM_testargs_sz NLM_cookie_sz+1+NLM_lock_sz -#define NLM_lockargs_sz NLM_cookie_sz+4+NLM_lock_sz -#define NLM_cancargs_sz NLM_cookie_sz+2+NLM_lock_sz -#define NLM_unlockargs_sz NLM_cookie_sz+NLM_lock_sz - -#define NLM_testres_sz NLM_cookie_sz+1+NLM_holder_sz -#define NLM_res_sz NLM_cookie_sz+1 -#define NLM_norep_sz 0 - -/* - * For NLM, a void procedure really returns nothing - */ -#define nlmclt_decode_norep NULL - -#define PROC(proc, argtype, restype) \ -[NLMPROC_##proc] = { \ - .p_proc = NLMPROC_##proc, \ - .p_encode = (kxdrproc_t) nlmclt_encode_##argtype, \ - .p_decode = (kxdrproc_t) nlmclt_decode_##restype, \ - .p_arglen = NLM_##argtype##_sz, \ - .p_replen = NLM_##restype##_sz, \ - .p_statidx = NLMPROC_##proc, \ - .p_name = #proc, \ - } - -static struct rpc_procinfo nlm_procedures[] = { - PROC(TEST, testargs, testres), - PROC(LOCK, lockargs, res), - PROC(CANCEL, cancargs, res), - PROC(UNLOCK, unlockargs, res), - PROC(GRANTED, testargs, res), - PROC(TEST_MSG, testargs, norep), - PROC(LOCK_MSG, lockargs, norep), - PROC(CANCEL_MSG, cancargs, norep), - PROC(UNLOCK_MSG, unlockargs, norep), - PROC(GRANTED_MSG, testargs, norep), - PROC(TEST_RES, testres, norep), - PROC(LOCK_RES, res, norep), - PROC(CANCEL_RES, res, norep), - PROC(UNLOCK_RES, res, norep), - PROC(GRANTED_RES, res, norep), -#ifdef NLMCLNT_SUPPORT_SHARES - PROC(SHARE, shareargs, shareres), - PROC(UNSHARE, shareargs, shareres), - PROC(NM_LOCK, lockargs, res), - PROC(FREE_ALL, notify, void), -#endif -}; - -static struct rpc_version nlm_version1 = { - .number = 1, - .nrprocs = 16, - .procs = nlm_procedures, -}; - -static struct rpc_version nlm_version3 = { - .number = 3, - .nrprocs = 24, - .procs = nlm_procedures, -}; - -static struct rpc_version * nlm_versions[] = { - [1] = &nlm_version1, - [3] = &nlm_version3, -#ifdef CONFIG_LOCKD_V4 - [4] = &nlm_version4, -#endif -}; - -static struct rpc_stat nlm_stats; - -struct rpc_program nlm_program = { - .name = "lockd", - .number = NLM_PROGRAM, - .nrvers = ARRAY_SIZE(nlm_versions), - .version = nlm_versions, - .stats = &nlm_stats, -}; - #ifdef RPC_DEBUG const char *nlmdbg_cookie2a(const struct nlm_cookie *cookie) { -- cgit v1.2.3 From d9c407b138926132e1f93c01fb2dee50eb0bb615 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Tue, 14 Dec 2010 14:55:50 +0000 Subject: NFS: Introduce new-style XDR encoding functions for NFSv3 We're interested in taking advantage of the safety benefits of xdr_streams. These data structures allow more careful checking for buffer overflow while encoding. More careful type checking is also introduced in the new functions. For efficiency, we also eventually want to be able to pass xdr_streams from call_encode() to all XDR encoding functions, rather than building an xdr_stream in every XDR encoding function in the kernel. To do this means all encoders must be ready to handle a passed-in xdr_stream. The new encoders follow the modern paradigm for XDR encoders: BUG on error, and always return a zero status code. Static helper functions are left without the "inline" directive. This allows the compiler to choose automatically how to optimize these for size or speed. Signed-off-by: Chuck Lever Tested-by: J. Bruce Fields Signed-off-by: Trond Myklebust --- fs/nfs/nfs3xdr.c | 833 ++++++++++++++++++++++++++++++++++++++++++++++++++- include/linux/nfs3.h | 2 + 2 files changed, 832 insertions(+), 3 deletions(-) diff --git a/fs/nfs/nfs3xdr.c b/fs/nfs/nfs3xdr.c index f6cc60f06dac..3d1043f7667c 100644 --- a/fs/nfs/nfs3xdr.c +++ b/fs/nfs/nfs3xdr.c @@ -37,6 +37,7 @@ #define NFS3_filename_sz (1+(NFS3_MAXNAMLEN>>2)) #define NFS3_path_sz (1+(NFS3_MAXPATHLEN>>2)) #define NFS3_fattr_sz (21) +#define NFS3_cookieverf_sz (NFS3_COOKIEVERFSIZE>>2) #define NFS3_wcc_attr_sz (6) #define NFS3_pre_op_attr_sz (1+NFS3_wcc_attr_sz) #define NFS3_post_op_attr_sz (1+NFS3_fattr_sz) @@ -59,7 +60,8 @@ #define NFS3_mknodargs_sz (NFS3_diropargs_sz+2+NFS3_sattr_sz) #define NFS3_renameargs_sz (NFS3_diropargs_sz+NFS3_diropargs_sz) #define NFS3_linkargs_sz (NFS3_fh_sz+NFS3_diropargs_sz) -#define NFS3_readdirargs_sz (NFS3_fh_sz+2) +#define NFS3_readdirargs_sz (NFS3_fh_sz+NFS3_cookieverf_sz+3) +#define NFS3_readdirplusargs_sz (NFS3_fh_sz+NFS3_cookieverf_sz+4) #define NFS3_commitargs_sz (NFS3_fh_sz+3) #define NFS3_attrstat_sz (1+NFS3_fattr_sz) @@ -107,6 +109,22 @@ static void print_overflow_msg(const char *func, const struct xdr_stream *xdr) func, xdr->end - xdr->p); } +/* + * While encoding arguments, set up the reply buffer in advance to + * receive reply data directly into the page cache. + */ +static void prepare_reply_buffer(struct rpc_rqst *req, struct page **pages, + unsigned int base, unsigned int len, + unsigned int bufsize) +{ + struct rpc_auth *auth = req->rq_cred->cr_auth; + unsigned int replen; + + replen = RPC_REPHDRSIZE + auth->au_rslack + bufsize; + xdr_inline_pages(&req->rq_rcv_buf, replen << 2, pages, base, len); +} + + /* * Common NFS XDR functions as inlines */ @@ -153,7 +171,7 @@ out_overflow: * Encode/decode time. */ static inline __be32 * -xdr_encode_time3(__be32 *p, struct timespec *timep) +xdr_encode_time3(__be32 *p, const struct timespec *timep) { *p++ = htonl(timep->tv_sec); *p++ = htonl(timep->tv_nsec); @@ -205,7 +223,7 @@ xdr_decode_fattr(__be32 *p, struct nfs_fattr *fattr) } static inline __be32 * -xdr_encode_sattr(__be32 *p, struct iattr *attr) +xdr_encode_sattr(__be32 *p, const struct iattr *attr) { if (attr->ia_valid & ATTR_MODE) { *p++ = xdr_one; @@ -306,6 +324,243 @@ xdr_decode_wcc_data(__be32 *p, struct nfs_fattr *fattr) return xdr_decode_post_op_attr(p, fattr); } + +/* + * Encode/decode NFSv3 basic data types + * + * Basic NFSv3 data types are defined in section 2.5 of RFC 1813: + * "NFS Version 3 Protocol Specification". + * + * Not all basic data types have their own encoding and decoding + * functions. For run-time efficiency, some data types are encoded + * or decoded inline. + */ + +static void encode_uint32(struct xdr_stream *xdr, u32 value) +{ + __be32 *p = xdr_reserve_space(xdr, 4); + *p = cpu_to_be32(value); +} + +/* + * filename3 + * + * typedef string filename3<>; + */ +static void encode_filename3(struct xdr_stream *xdr, + const char *name, u32 length) +{ + __be32 *p; + + BUG_ON(length > NFS3_MAXNAMLEN); + p = xdr_reserve_space(xdr, 4 + length); + xdr_encode_opaque(p, name, length); +} + +/* + * nfspath3 + * + * typedef string nfspath3<>; + */ +static void encode_nfspath3(struct xdr_stream *xdr, struct page **pages, + const u32 length) +{ + BUG_ON(length > NFS3_MAXPATHLEN); + encode_uint32(xdr, length); + xdr_write_pages(xdr, pages, 0, length); +} + +/* + * cookie3 + * + * typedef uint64 cookie3 + */ +static __be32 *xdr_encode_cookie3(__be32 *p, u64 cookie) +{ + return xdr_encode_hyper(p, cookie); +} + +/* + * cookieverf3 + * + * typedef opaque cookieverf3[NFS3_COOKIEVERFSIZE]; + */ +static __be32 *xdr_encode_cookieverf3(__be32 *p, const __be32 *verifier) +{ + memcpy(p, verifier, NFS3_COOKIEVERFSIZE); + return p + XDR_QUADLEN(NFS3_COOKIEVERFSIZE); +} + +/* + * createverf3 + * + * typedef opaque createverf3[NFS3_CREATEVERFSIZE]; + */ +static void encode_createverf3(struct xdr_stream *xdr, const __be32 *verifier) +{ + __be32 *p; + + p = xdr_reserve_space(xdr, NFS3_CREATEVERFSIZE); + memcpy(p, verifier, NFS3_CREATEVERFSIZE); +} + +/* + * ftype3 + * + * enum ftype3 { + * NF3REG = 1, + * NF3DIR = 2, + * NF3BLK = 3, + * NF3CHR = 4, + * NF3LNK = 5, + * NF3SOCK = 6, + * NF3FIFO = 7 + * }; + */ +static void encode_ftype3(struct xdr_stream *xdr, const u32 type) +{ + BUG_ON(type > NF3FIFO); + encode_uint32(xdr, type); +} + +/* + * specdata3 + * + * struct specdata3 { + * uint32 specdata1; + * uint32 specdata2; + * }; + */ +static void encode_specdata3(struct xdr_stream *xdr, const dev_t rdev) +{ + __be32 *p; + + p = xdr_reserve_space(xdr, 8); + *p++ = cpu_to_be32(MAJOR(rdev)); + *p = cpu_to_be32(MINOR(rdev)); +} + +/* + * nfs_fh3 + * + * struct nfs_fh3 { + * opaque data; + * }; + */ +static void encode_nfs_fh3(struct xdr_stream *xdr, const struct nfs_fh *fh) +{ + __be32 *p; + + BUG_ON(fh->size > NFS3_FHSIZE); + p = xdr_reserve_space(xdr, 4 + fh->size); + xdr_encode_opaque(p, fh->data, fh->size); +} + +/* + * sattr3 + * + * enum time_how { + * DONT_CHANGE = 0, + * SET_TO_SERVER_TIME = 1, + * SET_TO_CLIENT_TIME = 2 + * }; + * + * union set_mode3 switch (bool set_it) { + * case TRUE: + * mode3 mode; + * default: + * void; + * }; + * + * union set_uid3 switch (bool set_it) { + * case TRUE: + * uid3 uid; + * default: + * void; + * }; + * + * union set_gid3 switch (bool set_it) { + * case TRUE: + * gid3 gid; + * default: + * void; + * }; + * + * union set_size3 switch (bool set_it) { + * case TRUE: + * size3 size; + * default: + * void; + * }; + * + * union set_atime switch (time_how set_it) { + * case SET_TO_CLIENT_TIME: + * nfstime3 atime; + * default: + * void; + * }; + * + * union set_mtime switch (time_how set_it) { + * case SET_TO_CLIENT_TIME: + * nfstime3 mtime; + * default: + * void; + * }; + * + * struct sattr3 { + * set_mode3 mode; + * set_uid3 uid; + * set_gid3 gid; + * set_size3 size; + * set_atime atime; + * set_mtime mtime; + * }; + */ +static void encode_sattr3(struct xdr_stream *xdr, const struct iattr *attr) +{ + u32 nbytes; + __be32 *p; + + /* + * In order to make only a single xdr_reserve_space() call, + * pre-compute the total number of bytes to be reserved. + * Six boolean values, one for each set_foo field, are always + * present in the encoded result, so start there. + */ + nbytes = 6 * 4; + if (attr->ia_valid & ATTR_MODE) + nbytes += 4; + if (attr->ia_valid & ATTR_UID) + nbytes += 4; + if (attr->ia_valid & ATTR_GID) + nbytes += 4; + if (attr->ia_valid & ATTR_SIZE) + nbytes += 8; + if (attr->ia_valid & ATTR_ATIME_SET) + nbytes += 8; + if (attr->ia_valid & ATTR_MTIME_SET) + nbytes += 8; + p = xdr_reserve_space(xdr, nbytes); + + xdr_encode_sattr(p, attr); +} + +/* + * diropargs3 + * + * struct diropargs3 { + * nfs_fh3 dir; + * filename3 name; + * }; + */ +static void encode_diropargs3(struct xdr_stream *xdr, const struct nfs_fh *fh, + const char *name, u32 length) +{ + encode_nfs_fh3(xdr, fh); + encode_filename3(xdr, name, length); +} + + /* * NFS encode functions */ @@ -321,6 +576,23 @@ nfs3_xdr_fhandle(struct rpc_rqst *req, __be32 *p, struct nfs_fh *fh) return 0; } +/* + * 3.3.1 GETATTR3args + * + * struct GETATTR3args { + * nfs_fh3 object; + * }; + */ +static int nfs3_xdr_enc_getattr3args(struct rpc_rqst *req, __be32 *p, + const struct nfs_fh *fh) +{ + struct xdr_stream xdr; + + xdr_init_encode(&xdr, &req->rq_snd_buf, p); + encode_nfs_fh3(&xdr, fh); + return 0; +} + /* * Encode SETATTR arguments */ @@ -336,6 +608,49 @@ nfs3_xdr_sattrargs(struct rpc_rqst *req, __be32 *p, struct nfs3_sattrargs *args) return 0; } +/* + * 3.3.2 SETATTR3args + * + * union sattrguard3 switch (bool check) { + * case TRUE: + * nfstime3 obj_ctime; + * case FALSE: + * void; + * }; + * + * struct SETATTR3args { + * nfs_fh3 object; + * sattr3 new_attributes; + * sattrguard3 guard; + * }; + */ +static void encode_sattrguard3(struct xdr_stream *xdr, + const struct nfs3_sattrargs *args) +{ + __be32 *p; + + if (args->guard) { + p = xdr_reserve_space(xdr, 4 + 8); + *p++ = xdr_one; + xdr_encode_time3(p, &args->guardtime); + } else { + p = xdr_reserve_space(xdr, 4); + *p = xdr_zero; + } +} + +static int nfs3_xdr_enc_setattr3args(struct rpc_rqst *req, __be32 *p, + const struct nfs3_sattrargs *args) +{ + struct xdr_stream xdr; + + xdr_init_encode(&xdr, &req->rq_snd_buf, p); + encode_nfs_fh3(&xdr, args->fh); + encode_sattr3(&xdr, args->sattr); + encode_sattrguard3(&xdr, args); + return 0; +} + /* * Encode directory ops argument */ @@ -348,6 +663,23 @@ nfs3_xdr_diropargs(struct rpc_rqst *req, __be32 *p, struct nfs3_diropargs *args) return 0; } +/* + * 3.3.3 LOOKUP3args + * + * struct LOOKUP3args { + * diropargs3 what; + * }; + */ +static int nfs3_xdr_enc_lookup3args(struct rpc_rqst *req, __be32 *p, + const struct nfs3_diropargs *args) +{ + struct xdr_stream xdr; + + xdr_init_encode(&xdr, &req->rq_snd_buf, p); + encode_diropargs3(&xdr, args->fh, args->name, args->len); + return 0; +} + /* * Encode REMOVE argument */ @@ -372,6 +704,50 @@ nfs3_xdr_accessargs(struct rpc_rqst *req, __be32 *p, struct nfs3_accessargs *arg return 0; } +/* + * 3.3.4 ACCESS3args + * + * struct ACCESS3args { + * nfs_fh3 object; + * uint32 access; + * }; + */ +static void encode_access3args(struct xdr_stream *xdr, + const struct nfs3_accessargs *args) +{ + encode_nfs_fh3(xdr, args->fh); + encode_uint32(xdr, args->access); +} + +static int nfs3_xdr_enc_access3args(struct rpc_rqst *req, __be32 *p, + const struct nfs3_accessargs *args) +{ + struct xdr_stream xdr; + + xdr_init_encode(&xdr, &req->rq_snd_buf, p); + encode_access3args(&xdr, args); + return 0; +} + +/* + * 3.3.5 READLINK3args + * + * struct READLINK3args { + * nfs_fh3 symlink; + * }; + */ +static int nfs3_xdr_enc_readlink3args(struct rpc_rqst *req, __be32 *p, + const struct nfs3_readlinkargs *args) +{ + struct xdr_stream xdr; + + xdr_init_encode(&xdr, &req->rq_snd_buf, p); + encode_nfs_fh3(&xdr, args->fh); + prepare_reply_buffer(req, args->pages, args->pgbase, + args->pglen, NFS3_readlinkres_sz); + return 0; +} + /* * Arguments to a READ call. Since we read data directly into the page * cache, we also set up the reply iovec here so that iov[1] points @@ -397,6 +773,40 @@ nfs3_xdr_readargs(struct rpc_rqst *req, __be32 *p, struct nfs_readargs *args) return 0; } +/* + * 3.3.6 READ3args + * + * struct READ3args { + * nfs_fh3 file; + * offset3 offset; + * count3 count; + * }; + */ +static void encode_read3args(struct xdr_stream *xdr, + const struct nfs_readargs *args) +{ + __be32 *p; + + encode_nfs_fh3(xdr, args->fh); + + p = xdr_reserve_space(xdr, 8 + 4); + p = xdr_encode_hyper(p, args->offset); + *p = cpu_to_be32(args->count); +} + +static int nfs3_xdr_enc_read3args(struct rpc_rqst *req, __be32 *p, + const struct nfs_readargs *args) +{ + struct xdr_stream xdr; + + xdr_init_encode(&xdr, &req->rq_snd_buf, p); + encode_read3args(&xdr, args); + prepare_reply_buffer(req, args->pages, args->pgbase, + args->count, NFS3_readres_sz); + req->rq_rcv_buf.flags |= XDRBUF_READ; + return 0; +} + /* * Write arguments. Splice the buffer to be written into the iovec. */ @@ -419,6 +829,52 @@ nfs3_xdr_writeargs(struct rpc_rqst *req, __be32 *p, struct nfs_writeargs *args) return 0; } +/* + * 3.3.7 WRITE3args + * + * enum stable_how { + * UNSTABLE = 0, + * DATA_SYNC = 1, + * FILE_SYNC = 2 + * }; + * + * struct WRITE3args { + * nfs_fh3 file; + * offset3 offset; + * count3 count; + * stable_how stable; + * opaque data<>; + * }; + */ +static void encode_write3args(struct xdr_stream *xdr, + const struct nfs_writeargs *args) +{ + __be32 *p; + + encode_nfs_fh3(xdr, args->fh); + + p = xdr_reserve_space(xdr, 8 + 4 + 4 + 4); + p = xdr_encode_hyper(p, args->offset); + *p++ = cpu_to_be32(args->count); + + BUG_ON(args->stable > NFS_FILE_SYNC); + *p++ = cpu_to_be32(args->stable); + + *p = cpu_to_be32(args->count); + xdr_write_pages(xdr, args->pages, args->pgbase, args->count); +} + +static int nfs3_xdr_enc_write3args(struct rpc_rqst *req, __be32 *p, + const struct nfs_writeargs *args) +{ + struct xdr_stream xdr; + + xdr_init_encode(&xdr, &req->rq_snd_buf, p); + encode_write3args(&xdr, args); + xdr.buf->flags |= XDRBUF_WRITE; + return 0; +} + /* * Encode CREATE arguments */ @@ -439,6 +895,56 @@ nfs3_xdr_createargs(struct rpc_rqst *req, __be32 *p, struct nfs3_createargs *arg return 0; } +/* + * 3.3.8 CREATE3args + * + * enum createmode3 { + * UNCHECKED = 0, + * GUARDED = 1, + * EXCLUSIVE = 2 + * }; + * + * union createhow3 switch (createmode3 mode) { + * case UNCHECKED: + * case GUARDED: + * sattr3 obj_attributes; + * case EXCLUSIVE: + * createverf3 verf; + * }; + * + * struct CREATE3args { + * diropargs3 where; + * createhow3 how; + * }; + */ +static void encode_createhow3(struct xdr_stream *xdr, + const struct nfs3_createargs *args) +{ + encode_uint32(xdr, args->createmode); + switch (args->createmode) { + case NFS3_CREATE_UNCHECKED: + case NFS3_CREATE_GUARDED: + encode_sattr3(xdr, args->sattr); + break; + case NFS3_CREATE_EXCLUSIVE: + encode_createverf3(xdr, args->verifier); + break; + default: + BUG(); + } +} + +static int nfs3_xdr_enc_create3args(struct rpc_rqst *req, __be32 *p, + const struct nfs3_createargs *args) +{ + struct xdr_stream xdr; + + xdr_init_encode(&xdr, &req->rq_snd_buf, p); + encode_diropargs3(&xdr, args->fh, args->name, args->len); + encode_createhow3(&xdr, args); + return 0; +} + /* * Encode MKDIR arguments */ @@ -452,6 +958,25 @@ nfs3_xdr_mkdirargs(struct rpc_rqst *req, __be32 *p, struct nfs3_mkdirargs *args) return 0; } +/* + * 3.3.9 MKDIR3args + * + * struct MKDIR3args { + * diropargs3 where; + * sattr3 attributes; + * }; + */ +static int nfs3_xdr_enc_mkdir3args(struct rpc_rqst *req, __be32 *p, + const struct nfs3_mkdirargs *args) +{ + struct xdr_stream xdr; + + xdr_init_encode(&xdr, &req->rq_snd_buf, p); + encode_diropargs3(&xdr, args->fh, args->name, args->len); + encode_sattr3(&xdr, args->sattr); + return 0; +} + /* * Encode SYMLINK arguments */ @@ -469,6 +994,37 @@ nfs3_xdr_symlinkargs(struct rpc_rqst *req, __be32 *p, struct nfs3_symlinkargs *a return 0; } +/* + * 3.3.10 SYMLINK3args + * + * struct symlinkdata3 { + * sattr3 symlink_attributes; + * nfspath3 symlink_data; + * }; + * + * struct SYMLINK3args { + * diropargs3 where; + * symlinkdata3 symlink; + * }; + */ +static void encode_symlinkdata3(struct xdr_stream *xdr, + const struct nfs3_symlinkargs *args) +{ + encode_sattr3(xdr, args->sattr); + encode_nfspath3(xdr, args->pages, args->pathlen); +} + +static int nfs3_xdr_enc_symlink3args(struct rpc_rqst *req, __be32 *p, + const struct nfs3_symlinkargs *args) +{ + struct xdr_stream xdr; + + xdr_init_encode(&xdr, &req->rq_snd_buf, p); + encode_diropargs3(&xdr, args->fromfh, args->fromname, args->fromlen); + encode_symlinkdata3(&xdr, args); + return 0; +} + /* * Encode MKNOD arguments */ @@ -488,6 +1044,86 @@ nfs3_xdr_mknodargs(struct rpc_rqst *req, __be32 *p, struct nfs3_mknodargs *args) return 0; } +/* + * 3.3.11 MKNOD3args + * + * struct devicedata3 { + * sattr3 dev_attributes; + * specdata3 spec; + * }; + * + * union mknoddata3 switch (ftype3 type) { + * case NF3CHR: + * case NF3BLK: + * devicedata3 device; + * case NF3SOCK: + * case NF3FIFO: + * sattr3 pipe_attributes; + * default: + * void; + * }; + * + * struct MKNOD3args { + * diropargs3 where; + * mknoddata3 what; + * }; + */ +static void encode_devicedata3(struct xdr_stream *xdr, + const struct nfs3_mknodargs *args) +{ + encode_sattr3(xdr, args->sattr); + encode_specdata3(xdr, args->rdev); +} + +static void encode_mknoddata3(struct xdr_stream *xdr, + const struct nfs3_mknodargs *args) +{ + encode_ftype3(xdr, args->type); + switch (args->type) { + case NF3CHR: + case NF3BLK: + encode_devicedata3(xdr, args); + break; + case NF3SOCK: + case NF3FIFO: + encode_sattr3(xdr, args->sattr); + break; + case NF3REG: + case NF3DIR: + break; + default: + BUG(); + } +} + +static int nfs3_xdr_enc_mknod3args(struct rpc_rqst *req, __be32 *p, + const struct nfs3_mknodargs *args) +{ + struct xdr_stream xdr; + + xdr_init_encode(&xdr, &req->rq_snd_buf, p); + encode_diropargs3(&xdr, args->fh, args->name, args->len); + encode_mknoddata3(&xdr, args); + return 0; +} + +/* + * 3.3.12 REMOVE3args + * + * struct REMOVE3args { + * diropargs3 object; + * }; + */ +static int nfs3_xdr_enc_remove3args(struct rpc_rqst *req, __be32 *p, + const struct nfs_removeargs *args) +{ + struct xdr_stream xdr; + + xdr_init_encode(&xdr, &req->rq_snd_buf, p); + encode_diropargs3(&xdr, args->fh, args->name.name, args->name.len); + return 0; +} + /* * Encode RENAME arguments */ @@ -502,6 +1138,27 @@ nfs3_xdr_renameargs(struct rpc_rqst *req, __be32 *p, struct nfs_renameargs *args return 0; } +/* + * 3.3.14 RENAME3args + * + * struct RENAME3args { + * diropargs3 from; + * diropargs3 to; + * }; + */ +static int nfs3_xdr_enc_rename3args(struct rpc_rqst *req, __be32 *p, + const struct nfs_renameargs *args) +{ + const struct qstr *old = args->old_name; + const struct qstr *new = args->new_name; + struct xdr_stream xdr; + + xdr_init_encode(&xdr, &req->rq_snd_buf, p); + encode_diropargs3(&xdr, args->old_dir, old->name, old->len); + encode_diropargs3(&xdr, args->new_dir, new->name, new->len); + return 0; +} + /* * Encode LINK arguments */ @@ -515,6 +1172,25 @@ nfs3_xdr_linkargs(struct rpc_rqst *req, __be32 *p, struct nfs3_linkargs *args) return 0; } +/* + * 3.3.15 LINK3args + * + * struct LINK3args { + * nfs_fh3 file; + * diropargs3 link; + * }; + */ +static int nfs3_xdr_enc_link3args(struct rpc_rqst *req, __be32 *p, + const struct nfs3_linkargs *args) +{ + struct xdr_stream xdr; + + xdr_init_encode(&xdr, &req->rq_snd_buf, p); + encode_nfs_fh3(&xdr, args->fromfh); + encode_diropargs3(&xdr, args->tofh, args->toname, args->tolen); + return 0; +} + /* * Encode arguments to readdir call */ @@ -543,6 +1219,84 @@ nfs3_xdr_readdirargs(struct rpc_rqst *req, __be32 *p, struct nfs3_readdirargs *a return 0; } +/* + * 3.3.16 READDIR3args + * + * struct READDIR3args { + * nfs_fh3 dir; + * cookie3 cookie; + * cookieverf3 cookieverf; + * count3 count; + * }; + */ +static void encode_readdir3args(struct xdr_stream *xdr, + const struct nfs3_readdirargs *args) +{ + __be32 *p; + + encode_nfs_fh3(xdr, args->fh); + + p = xdr_reserve_space(xdr, 8 + NFS3_COOKIEVERFSIZE + 4); + p = xdr_encode_cookie3(p, args->cookie); + p = xdr_encode_cookieverf3(p, args->verf); + *p = cpu_to_be32(args->count); +} + +static int nfs3_xdr_enc_readdir3args(struct rpc_rqst *req, __be32 *p, + const struct nfs3_readdirargs *args) +{ + struct xdr_stream xdr; + + xdr_init_encode(&xdr, &req->rq_snd_buf, p); + encode_readdir3args(&xdr, args); + prepare_reply_buffer(req, args->pages, 0, + args->count, NFS3_readdirres_sz); + return 0; +} + +/* + * 3.3.17 READDIRPLUS3args + * + * struct READDIRPLUS3args { + * nfs_fh3 dir; + * cookie3 cookie; + * cookieverf3 cookieverf; + * count3 dircount; + * count3 maxcount; + * }; + */ +static void encode_readdirplus3args(struct xdr_stream *xdr, + const struct nfs3_readdirargs *args) +{ + __be32 *p; + + encode_nfs_fh3(xdr, args->fh); + + p = xdr_reserve_space(xdr, 8 + NFS3_COOKIEVERFSIZE + 4 + 4); + p = xdr_encode_cookie3(p, args->cookie); + p = xdr_encode_cookieverf3(p, args->verf); + + /* + * readdirplus: need dircount + buffer size. + * We just make sure we make dircount big enough + */ + *p++ = cpu_to_be32(args->count >> 3); + + *p = cpu_to_be32(args->count); +} + +static int nfs3_xdr_enc_readdirplus3args(struct rpc_rqst *req, __be32 *p, + const struct nfs3_readdirargs *args) +{ + struct xdr_stream xdr; + + xdr_init_encode(&xdr, &req->rq_snd_buf, p); + encode_readdirplus3args(&xdr, args); + prepare_reply_buffer(req, args->pages, 0, + args->count, NFS3_readdirres_sz); + return 0; +} + /* * Decode the result of a readdir call. * We just check for syntactical correctness. @@ -674,6 +1428,37 @@ nfs3_xdr_commitargs(struct rpc_rqst *req, __be32 *p, struct nfs_writeargs *args) return 0; } +/* + * 3.3.21 COMMIT3args + * + * struct COMMIT3args { + * nfs_fh3 file; + * offset3 offset; + * count3 count; + * }; + */ +static void encode_commit3args(struct xdr_stream *xdr, + const struct nfs_writeargs *args) +{ + __be32 *p; + + encode_nfs_fh3(xdr, args->fh); + + p = xdr_reserve_space(xdr, 8 + 4); + p = xdr_encode_hyper(p, args->offset); + *p = cpu_to_be32(args->count); +} + +static int nfs3_xdr_enc_commit3args(struct rpc_rqst *req, __be32 *p, + const struct nfs_writeargs *args) +{ + struct xdr_stream xdr; + + xdr_init_encode(&xdr, &req->rq_snd_buf, p); + encode_commit3args(&xdr, args); + return 0; +} + #ifdef CONFIG_NFS_V3_ACL /* * Encode GETACL arguments @@ -699,6 +1484,21 @@ nfs3_xdr_getaclargs(struct rpc_rqst *req, __be32 *p, return 0; } +static int nfs3_xdr_enc_getacl3args(struct rpc_rqst *req, __be32 *p, + const struct nfs3_getaclargs *args) +{ + struct xdr_stream xdr; + + xdr_init_encode(&xdr, &req->rq_snd_buf, p); + encode_nfs_fh3(&xdr, args->fh); + encode_uint32(&xdr, args->mask); + if (args->mask & (NFS_ACL | NFS_DFACL)) + prepare_reply_buffer(req, args->pages, 0, + NFSACL_MAXPAGES << PAGE_SHIFT, + ACL3_getaclres_sz); + return 0; +} + /* * Encode SETACL arguments */ @@ -731,6 +1531,33 @@ nfs3_xdr_setaclargs(struct rpc_rqst *req, __be32 *p, NFS_ACL_DEFAULT); return (err > 0) ? 0 : err; } + +static int nfs3_xdr_enc_setacl3args(struct rpc_rqst *req, __be32 *p, + const struct nfs3_setaclargs *args) +{ + struct xdr_stream xdr; + unsigned int base; + int error; + + xdr_init_encode(&xdr, &req->rq_snd_buf, p); + encode_nfs_fh3(&xdr, NFS_FH(args->inode)); + encode_uint32(&xdr, args->mask); + if (args->npages != 0) + xdr_write_pages(&xdr, args->pages, 0, args->len); + + base = req->rq_slen; + error = nfsacl_encode(xdr.buf, base, args->inode, + (args->mask & NFS_ACL) ? + args->acl_access : NULL, 1, 0); + BUG_ON(error < 0); + error = nfsacl_encode(xdr.buf, base + error, args->inode, + (args->mask & NFS_DFACL) ? + args->acl_default : NULL, 1, + NFS_ACL_DEFAULT); + BUG_ON(error < 0); + return 0; +} + #endif /* CONFIG_NFS_V3_ACL */ /* diff --git a/include/linux/nfs3.h b/include/linux/nfs3.h index ac33806ec7f9..e2ee14fd0083 100644 --- a/include/linux/nfs3.h +++ b/include/linux/nfs3.h @@ -11,6 +11,8 @@ #define NFS3_MAXGROUPS 16 #define NFS3_FHSIZE 64 #define NFS3_COOKIESIZE 4 +#define NFS3_CREATEVERFSIZE 8 +#define NFS3_COOKIEVERFSIZE 8 #define NFS3_FIFO_DEV (-1) #define NFS3MODE_FMT 0170000 #define NFS3MODE_DIR 0040000 -- cgit v1.2.3 From ad96b5b5eae59696b97e207d730b8c8cfb9d4e42 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Tue, 14 Dec 2010 14:56:01 +0000 Subject: NFS: Replace old NFSv3 encoder functions with xdr_stream-based ones The naming scheme of the new encoder functions, which follows the NFSv4 XDR encoder functions, is slightly different than the scheme used for the old functions. Rename the functions as a separate step to keep the patches clean. Signed-off-by: Chuck Lever Tested-by: J. Bruce Fields Signed-off-by: Trond Myklebust --- fs/nfs/nfs3xdr.c | 58 +++++++++++++++++++++++++++++--------------------------- 1 file changed, 30 insertions(+), 28 deletions(-) diff --git a/fs/nfs/nfs3xdr.c b/fs/nfs/nfs3xdr.c index 3d1043f7667c..bbda89042053 100644 --- a/fs/nfs/nfs3xdr.c +++ b/fs/nfs/nfs3xdr.c @@ -46,10 +46,11 @@ #define NFS3_fsinfo_sz #define NFS3_pathconf_sz #define NFS3_entry_sz (NFS3_filename_sz+3) - -#define NFS3_sattrargs_sz (NFS3_fh_sz+NFS3_sattr_sz+3) #define NFS3_diropargs_sz (NFS3_fh_sz+NFS3_filename_sz) -#define NFS3_removeargs_sz (NFS3_fh_sz+NFS3_filename_sz) + +#define NFS3_getattrargs_sz (NFS3_fh_sz) +#define NFS3_setattrargs_sz (NFS3_fh_sz+NFS3_sattr_sz+3) +#define NFS3_lookupargs_sz (NFS3_fh_sz+NFS3_filename_sz) #define NFS3_accessargs_sz (NFS3_fh_sz+1) #define NFS3_readlinkargs_sz (NFS3_fh_sz) #define NFS3_readargs_sz (NFS3_fh_sz+3) @@ -58,6 +59,7 @@ #define NFS3_mkdirargs_sz (NFS3_diropargs_sz+NFS3_sattr_sz) #define NFS3_symlinkargs_sz (NFS3_diropargs_sz+1+NFS3_sattr_sz) #define NFS3_mknodargs_sz (NFS3_diropargs_sz+2+NFS3_sattr_sz) +#define NFS3_removeargs_sz (NFS3_fh_sz+NFS3_filename_sz) #define NFS3_renameargs_sz (NFS3_diropargs_sz+NFS3_diropargs_sz) #define NFS3_linkargs_sz (NFS3_fh_sz+NFS3_diropargs_sz) #define NFS3_readdirargs_sz (NFS3_fh_sz+NFS3_cookieverf_sz+3) @@ -1969,9 +1971,9 @@ nfs3_xdr_setaclres(struct rpc_rqst *req, __be32 *p, struct nfs_fattr *fattr) #define PROC(proc, argtype, restype, timer) \ [NFS3PROC_##proc] = { \ .p_proc = NFS3PROC_##proc, \ - .p_encode = (kxdrproc_t) nfs3_xdr_##argtype, \ + .p_encode = (kxdrproc_t)nfs3_xdr_enc_##argtype##3args, \ .p_decode = (kxdrproc_t) nfs3_xdr_##restype, \ - .p_arglen = NFS3_##argtype##_sz, \ + .p_arglen = NFS3_##argtype##args_sz, \ .p_replen = NFS3_##restype##_sz, \ .p_timer = timer, \ .p_statidx = NFS3PROC_##proc, \ @@ -1979,27 +1981,27 @@ nfs3_xdr_setaclres(struct rpc_rqst *req, __be32 *p, struct nfs_fattr *fattr) } struct rpc_procinfo nfs3_procedures[] = { - PROC(GETATTR, fhandle, attrstat, 1), - PROC(SETATTR, sattrargs, wccstat, 0), - PROC(LOOKUP, diropargs, lookupres, 2), - PROC(ACCESS, accessargs, accessres, 1), - PROC(READLINK, readlinkargs, readlinkres, 3), - PROC(READ, readargs, readres, 3), - PROC(WRITE, writeargs, writeres, 4), - PROC(CREATE, createargs, createres, 0), - PROC(MKDIR, mkdirargs, createres, 0), - PROC(SYMLINK, symlinkargs, createres, 0), - PROC(MKNOD, mknodargs, createres, 0), - PROC(REMOVE, removeargs, removeres, 0), - PROC(RMDIR, diropargs, wccstat, 0), - PROC(RENAME, renameargs, renameres, 0), - PROC(LINK, linkargs, linkres, 0), - PROC(READDIR, readdirargs, readdirres, 3), - PROC(READDIRPLUS, readdirargs, readdirres, 3), - PROC(FSSTAT, fhandle, fsstatres, 0), - PROC(FSINFO, fhandle, fsinfores, 0), - PROC(PATHCONF, fhandle, pathconfres, 0), - PROC(COMMIT, commitargs, commitres, 5), + PROC(GETATTR, getattr, attrstat, 1), + PROC(SETATTR, setattr, wccstat, 0), + PROC(LOOKUP, lookup, lookupres, 2), + PROC(ACCESS, access, accessres, 1), + PROC(READLINK, readlink, readlinkres, 3), + PROC(READ, read, readres, 3), + PROC(WRITE, write, writeres, 4), + PROC(CREATE, create, createres, 0), + PROC(MKDIR, mkdir, createres, 0), + PROC(SYMLINK, symlink, createres, 0), + PROC(MKNOD, mknod, createres, 0), + PROC(REMOVE, remove, removeres, 0), + PROC(RMDIR, lookup, wccstat, 0), + PROC(RENAME, rename, renameres, 0), + PROC(LINK, link, linkres, 0), + PROC(READDIR, readdir, readdirres, 3), + PROC(READDIRPLUS, readdirplus, readdirres, 3), + PROC(FSSTAT, getattr, fsstatres, 0), + PROC(FSINFO, getattr, fsinfores, 0), + PROC(PATHCONF, getattr, pathconfres, 0), + PROC(COMMIT, commit, commitres, 5), }; struct rpc_version nfs_version3 = { @@ -2012,7 +2014,7 @@ struct rpc_version nfs_version3 = { static struct rpc_procinfo nfs3_acl_procedures[] = { [ACLPROC3_GETACL] = { .p_proc = ACLPROC3_GETACL, - .p_encode = (kxdrproc_t) nfs3_xdr_getaclargs, + .p_encode = (kxdrproc_t)nfs3_xdr_enc_getacl3args, .p_decode = (kxdrproc_t) nfs3_xdr_getaclres, .p_arglen = ACL3_getaclargs_sz, .p_replen = ACL3_getaclres_sz, @@ -2021,7 +2023,7 @@ static struct rpc_procinfo nfs3_acl_procedures[] = { }, [ACLPROC3_SETACL] = { .p_proc = ACLPROC3_SETACL, - .p_encode = (kxdrproc_t) nfs3_xdr_setaclargs, + .p_encode = (kxdrproc_t)nfs3_xdr_enc_setacl3args, .p_decode = (kxdrproc_t) nfs3_xdr_setaclres, .p_arglen = ACL3_setaclargs_sz, .p_replen = ACL3_setaclres_sz, -- cgit v1.2.3 From 499ff710b2fd3a03c8195c82340e5166eed04205 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Tue, 14 Dec 2010 14:56:10 +0000 Subject: NFS: Remove unused old NFSv3 encoder functions Clean up. Remove unused legacy argument encoder functions, and any now unused encoder helper functions. Signed-off-by: Chuck Lever Tested-by: J. Bruce Fields Signed-off-by: Trond Myklebust --- fs/nfs/nfs3xdr.c | 328 +------------------------------------------------------ 1 file changed, 4 insertions(+), 324 deletions(-) diff --git a/fs/nfs/nfs3xdr.c b/fs/nfs/nfs3xdr.c index bbda89042053..b0af263e4db9 100644 --- a/fs/nfs/nfs3xdr.c +++ b/fs/nfs/nfs3xdr.c @@ -130,12 +130,6 @@ static void prepare_reply_buffer(struct rpc_rqst *req, struct page **pages, /* * Common NFS XDR functions as inlines */ -static inline __be32 * -xdr_encode_fhandle(__be32 *p, const struct nfs_fh *fh) -{ - return xdr_encode_array(p, fh->data, fh->size); -} - static inline __be32 * xdr_decode_fhandle(__be32 *p, struct nfs_fh *fh) { @@ -564,20 +558,12 @@ static void encode_diropargs3(struct xdr_stream *xdr, const struct nfs_fh *fh, /* - * NFS encode functions + * NFSv3 XDR encode functions + * + * NFSv3 argument types are defined in section 3.3 of RFC 1813: + * "NFS Version 3 Protocol Specification". */ -/* - * Encode file handle argument - */ -static int -nfs3_xdr_fhandle(struct rpc_rqst *req, __be32 *p, struct nfs_fh *fh) -{ - p = xdr_encode_fhandle(p, fh); - req->rq_slen = xdr_adjust_iovec(req->rq_svec, p); - return 0; -} - /* * 3.3.1 GETATTR3args * @@ -595,21 +581,6 @@ static int nfs3_xdr_enc_getattr3args(struct rpc_rqst *req, __be32 *p, return 0; } -/* - * Encode SETATTR arguments - */ -static int -nfs3_xdr_sattrargs(struct rpc_rqst *req, __be32 *p, struct nfs3_sattrargs *args) -{ - p = xdr_encode_fhandle(p, args->fh); - p = xdr_encode_sattr(p, args->sattr); - *p++ = htonl(args->guard); - if (args->guard) - p = xdr_encode_time3(p, &args->guardtime); - req->rq_slen = xdr_adjust_iovec(req->rq_svec, p); - return 0; -} - /* * 3.3.2 SETATTR3args * @@ -653,18 +624,6 @@ static int nfs3_xdr_enc_setattr3args(struct rpc_rqst *req, __be32 *p, return 0; } -/* - * Encode directory ops argument - */ -static int -nfs3_xdr_diropargs(struct rpc_rqst *req, __be32 *p, struct nfs3_diropargs *args) -{ - p = xdr_encode_fhandle(p, args->fh); - p = xdr_encode_array(p, args->name, args->len); - req->rq_slen = xdr_adjust_iovec(req->rq_svec, p); - return 0; -} - /* * 3.3.3 LOOKUP3args * @@ -682,30 +641,6 @@ static int nfs3_xdr_enc_lookup3args(struct rpc_rqst *req, __be32 *p, return 0; } -/* - * Encode REMOVE argument - */ -static int -nfs3_xdr_removeargs(struct rpc_rqst *req, __be32 *p, const struct nfs_removeargs *args) -{ - p = xdr_encode_fhandle(p, args->fh); - p = xdr_encode_array(p, args->name.name, args->name.len); - req->rq_slen = xdr_adjust_iovec(req->rq_svec, p); - return 0; -} - -/* - * Encode access() argument - */ -static int -nfs3_xdr_accessargs(struct rpc_rqst *req, __be32 *p, struct nfs3_accessargs *args) -{ - p = xdr_encode_fhandle(p, args->fh); - *p++ = htonl(args->access); - req->rq_slen = xdr_adjust_iovec(req->rq_svec, p); - return 0; -} - /* * 3.3.4 ACCESS3args * @@ -750,31 +685,6 @@ static int nfs3_xdr_enc_readlink3args(struct rpc_rqst *req, __be32 *p, return 0; } -/* - * Arguments to a READ call. Since we read data directly into the page - * cache, we also set up the reply iovec here so that iov[1] points - * exactly to the page we want to fetch. - */ -static int -nfs3_xdr_readargs(struct rpc_rqst *req, __be32 *p, struct nfs_readargs *args) -{ - struct rpc_auth *auth = req->rq_cred->cr_auth; - unsigned int replen; - u32 count = args->count; - - p = xdr_encode_fhandle(p, args->fh); - p = xdr_encode_hyper(p, args->offset); - *p++ = htonl(count); - req->rq_slen = xdr_adjust_iovec(req->rq_svec, p); - - /* Inline the page array */ - replen = (RPC_REPHDRSIZE + auth->au_rslack + NFS3_readres_sz) << 2; - xdr_inline_pages(&req->rq_rcv_buf, replen, - args->pages, args->pgbase, count); - req->rq_rcv_buf.flags |= XDRBUF_READ; - return 0; -} - /* * 3.3.6 READ3args * @@ -809,28 +719,6 @@ static int nfs3_xdr_enc_read3args(struct rpc_rqst *req, __be32 *p, return 0; } -/* - * Write arguments. Splice the buffer to be written into the iovec. - */ -static int -nfs3_xdr_writeargs(struct rpc_rqst *req, __be32 *p, struct nfs_writeargs *args) -{ - struct xdr_buf *sndbuf = &req->rq_snd_buf; - u32 count = args->count; - - p = xdr_encode_fhandle(p, args->fh); - p = xdr_encode_hyper(p, args->offset); - *p++ = htonl(count); - *p++ = htonl(args->stable); - *p++ = htonl(count); - sndbuf->len = xdr_adjust_iovec(sndbuf->head, p); - - /* Copy the page array */ - xdr_encode_pages(sndbuf, args->pages, args->pgbase, count); - sndbuf->flags |= XDRBUF_WRITE; - return 0; -} - /* * 3.3.7 WRITE3args * @@ -877,26 +765,6 @@ static int nfs3_xdr_enc_write3args(struct rpc_rqst *req, __be32 *p, return 0; } -/* - * Encode CREATE arguments - */ -static int -nfs3_xdr_createargs(struct rpc_rqst *req, __be32 *p, struct nfs3_createargs *args) -{ - p = xdr_encode_fhandle(p, args->fh); - p = xdr_encode_array(p, args->name, args->len); - - *p++ = htonl(args->createmode); - if (args->createmode == NFS3_CREATE_EXCLUSIVE) { - *p++ = args->verifier[0]; - *p++ = args->verifier[1]; - } else - p = xdr_encode_sattr(p, args->sattr); - - req->rq_slen = xdr_adjust_iovec(req->rq_svec, p); - return 0; -} - /* * 3.3.8 CREATE3args * @@ -947,19 +815,6 @@ static int nfs3_xdr_enc_create3args(struct rpc_rqst *req, __be32 *p, return 0; } -/* - * Encode MKDIR arguments - */ -static int -nfs3_xdr_mkdirargs(struct rpc_rqst *req, __be32 *p, struct nfs3_mkdirargs *args) -{ - p = xdr_encode_fhandle(p, args->fh); - p = xdr_encode_array(p, args->name, args->len); - p = xdr_encode_sattr(p, args->sattr); - req->rq_slen = xdr_adjust_iovec(req->rq_svec, p); - return 0; -} - /* * 3.3.9 MKDIR3args * @@ -979,23 +834,6 @@ static int nfs3_xdr_enc_mkdir3args(struct rpc_rqst *req, __be32 *p, return 0; } -/* - * Encode SYMLINK arguments - */ -static int -nfs3_xdr_symlinkargs(struct rpc_rqst *req, __be32 *p, struct nfs3_symlinkargs *args) -{ - p = xdr_encode_fhandle(p, args->fromfh); - p = xdr_encode_array(p, args->fromname, args->fromlen); - p = xdr_encode_sattr(p, args->sattr); - *p++ = htonl(args->pathlen); - req->rq_slen = xdr_adjust_iovec(req->rq_svec, p); - - /* Copy the page */ - xdr_encode_pages(&req->rq_snd_buf, args->pages, 0, args->pathlen); - return 0; -} - /* * 3.3.10 SYMLINK3args * @@ -1027,25 +865,6 @@ static int nfs3_xdr_enc_symlink3args(struct rpc_rqst *req, __be32 *p, return 0; } -/* - * Encode MKNOD arguments - */ -static int -nfs3_xdr_mknodargs(struct rpc_rqst *req, __be32 *p, struct nfs3_mknodargs *args) -{ - p = xdr_encode_fhandle(p, args->fh); - p = xdr_encode_array(p, args->name, args->len); - *p++ = htonl(args->type); - p = xdr_encode_sattr(p, args->sattr); - if (args->type == NF3CHR || args->type == NF3BLK) { - *p++ = htonl(MAJOR(args->rdev)); - *p++ = htonl(MINOR(args->rdev)); - } - - req->rq_slen = xdr_adjust_iovec(req->rq_svec, p); - return 0; -} - /* * 3.3.11 MKNOD3args * @@ -1126,20 +945,6 @@ static int nfs3_xdr_enc_remove3args(struct rpc_rqst *req, __be32 *p, return 0; } -/* - * Encode RENAME arguments - */ -static int -nfs3_xdr_renameargs(struct rpc_rqst *req, __be32 *p, struct nfs_renameargs *args) -{ - p = xdr_encode_fhandle(p, args->old_dir); - p = xdr_encode_array(p, args->old_name->name, args->old_name->len); - p = xdr_encode_fhandle(p, args->new_dir); - p = xdr_encode_array(p, args->new_name->name, args->new_name->len); - req->rq_slen = xdr_adjust_iovec(req->rq_svec, p); - return 0; -} - /* * 3.3.14 RENAME3args * @@ -1161,19 +966,6 @@ static int nfs3_xdr_enc_rename3args(struct rpc_rqst *req, __be32 *p, return 0; } -/* - * Encode LINK arguments - */ -static int -nfs3_xdr_linkargs(struct rpc_rqst *req, __be32 *p, struct nfs3_linkargs *args) -{ - p = xdr_encode_fhandle(p, args->fromfh); - p = xdr_encode_fhandle(p, args->tofh); - p = xdr_encode_array(p, args->toname, args->tolen); - req->rq_slen = xdr_adjust_iovec(req->rq_svec, p); - return 0; -} - /* * 3.3.15 LINK3args * @@ -1193,34 +985,6 @@ static int nfs3_xdr_enc_link3args(struct rpc_rqst *req, __be32 *p, return 0; } -/* - * Encode arguments to readdir call - */ -static int -nfs3_xdr_readdirargs(struct rpc_rqst *req, __be32 *p, struct nfs3_readdirargs *args) -{ - struct rpc_auth *auth = req->rq_cred->cr_auth; - unsigned int replen; - u32 count = args->count; - - p = xdr_encode_fhandle(p, args->fh); - p = xdr_encode_hyper(p, args->cookie); - *p++ = args->verf[0]; - *p++ = args->verf[1]; - if (args->plus) { - /* readdirplus: need dircount + buffer size. - * We just make sure we make dircount big enough */ - *p++ = htonl(count >> 3); - } - *p++ = htonl(count); - req->rq_slen = xdr_adjust_iovec(req->rq_svec, p); - - /* Inline the page array */ - replen = (RPC_REPHDRSIZE + auth->au_rslack + NFS3_readdirres_sz) << 2; - xdr_inline_pages(&req->rq_rcv_buf, replen, args->pages, 0, count); - return 0; -} - /* * 3.3.16 READDIR3args * @@ -1417,19 +1181,6 @@ out_overflow_exit: return ERR_PTR(-EAGAIN); } -/* - * Encode COMMIT arguments - */ -static int -nfs3_xdr_commitargs(struct rpc_rqst *req, __be32 *p, struct nfs_writeargs *args) -{ - p = xdr_encode_fhandle(p, args->fh); - p = xdr_encode_hyper(p, args->offset); - *p++ = htonl(args->count); - req->rq_slen = xdr_adjust_iovec(req->rq_svec, p); - return 0; -} - /* * 3.3.21 COMMIT3args * @@ -1462,29 +1213,6 @@ static int nfs3_xdr_enc_commit3args(struct rpc_rqst *req, __be32 *p, } #ifdef CONFIG_NFS_V3_ACL -/* - * Encode GETACL arguments - */ -static int -nfs3_xdr_getaclargs(struct rpc_rqst *req, __be32 *p, - struct nfs3_getaclargs *args) -{ - struct rpc_auth *auth = req->rq_cred->cr_auth; - unsigned int replen; - - p = xdr_encode_fhandle(p, args->fh); - *p++ = htonl(args->mask); - req->rq_slen = xdr_adjust_iovec(req->rq_svec, p); - - if (args->mask & (NFS_ACL | NFS_DFACL)) { - /* Inline the page array */ - replen = (RPC_REPHDRSIZE + auth->au_rslack + - ACL3_getaclres_sz) << 2; - xdr_inline_pages(&req->rq_rcv_buf, replen, args->pages, 0, - NFSACL_MAXPAGES << PAGE_SHIFT); - } - return 0; -} static int nfs3_xdr_enc_getacl3args(struct rpc_rqst *req, __be32 *p, const struct nfs3_getaclargs *args) @@ -1501,39 +1229,6 @@ static int nfs3_xdr_enc_getacl3args(struct rpc_rqst *req, __be32 *p, return 0; } -/* - * Encode SETACL arguments - */ -static int -nfs3_xdr_setaclargs(struct rpc_rqst *req, __be32 *p, - struct nfs3_setaclargs *args) -{ - struct xdr_buf *buf = &req->rq_snd_buf; - unsigned int base; - int err; - - p = xdr_encode_fhandle(p, NFS_FH(args->inode)); - *p++ = htonl(args->mask); - req->rq_slen = xdr_adjust_iovec(req->rq_svec, p); - base = req->rq_slen; - - if (args->npages != 0) - xdr_encode_pages(buf, args->pages, 0, args->len); - else - req->rq_slen = xdr_adjust_iovec(req->rq_svec, - p + XDR_QUADLEN(args->len)); - - err = nfsacl_encode(buf, base, args->inode, - (args->mask & NFS_ACL) ? - args->acl_access : NULL, 1, 0); - if (err > 0) - err = nfsacl_encode(buf, base + err, args->inode, - (args->mask & NFS_DFACL) ? - args->acl_default : NULL, 1, - NFS_ACL_DEFAULT); - return (err > 0) ? 0 : err; -} - static int nfs3_xdr_enc_setacl3args(struct rpc_rqst *req, __be32 *p, const struct nfs3_setaclargs *args) { @@ -1635,21 +1330,6 @@ nfs3_xdr_accessres(struct rpc_rqst *req, __be32 *p, struct nfs3_accessres *res) return 0; } -static int -nfs3_xdr_readlinkargs(struct rpc_rqst *req, __be32 *p, struct nfs3_readlinkargs *args) -{ - struct rpc_auth *auth = req->rq_cred->cr_auth; - unsigned int replen; - - p = xdr_encode_fhandle(p, args->fh); - req->rq_slen = xdr_adjust_iovec(req->rq_svec, p); - - /* Inline the page array */ - replen = (RPC_REPHDRSIZE + auth->au_rslack + NFS3_readlinkres_sz) << 2; - xdr_inline_pages(&req->rq_rcv_buf, replen, args->pages, args->pgbase, args->pglen); - return 0; -} - /* * Decode READLINK reply */ -- cgit v1.2.3 From 9d5a64343925a152e1907c652a0d71d6640868b3 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Tue, 14 Dec 2010 14:56:20 +0000 Subject: NFS: Update xdr_encode_foo() functions that we're keeping Clean up. Move the timestamp and the sattr encoder to match the placement convention of the other helpers, update their coding style, and refresh their documenting comments. Signed-off-by: Chuck Lever Tested-by: J. Bruce Fields Signed-off-by: Trond Myklebust --- fs/nfs/nfs3xdr.c | 111 +++++++++++++++++++++++++++---------------------------- 1 file changed, 55 insertions(+), 56 deletions(-) diff --git a/fs/nfs/nfs3xdr.c b/fs/nfs/nfs3xdr.c index b0af263e4db9..119844d0b4d5 100644 --- a/fs/nfs/nfs3xdr.c +++ b/fs/nfs/nfs3xdr.c @@ -166,14 +166,6 @@ out_overflow: /* * Encode/decode time. */ -static inline __be32 * -xdr_encode_time3(__be32 *p, const struct timespec *timep) -{ - *p++ = htonl(timep->tv_sec); - *p++ = htonl(timep->tv_nsec); - return p; -} - static inline __be32 * xdr_decode_time3(__be32 *p, struct timespec *timep) { @@ -218,52 +210,6 @@ xdr_decode_fattr(__be32 *p, struct nfs_fattr *fattr) return p; } -static inline __be32 * -xdr_encode_sattr(__be32 *p, const struct iattr *attr) -{ - if (attr->ia_valid & ATTR_MODE) { - *p++ = xdr_one; - *p++ = htonl(attr->ia_mode & S_IALLUGO); - } else { - *p++ = xdr_zero; - } - if (attr->ia_valid & ATTR_UID) { - *p++ = xdr_one; - *p++ = htonl(attr->ia_uid); - } else { - *p++ = xdr_zero; - } - if (attr->ia_valid & ATTR_GID) { - *p++ = xdr_one; - *p++ = htonl(attr->ia_gid); - } else { - *p++ = xdr_zero; - } - if (attr->ia_valid & ATTR_SIZE) { - *p++ = xdr_one; - p = xdr_encode_hyper(p, (__u64) attr->ia_size); - } else { - *p++ = xdr_zero; - } - if (attr->ia_valid & ATTR_ATIME_SET) { - *p++ = xdr_two; - p = xdr_encode_time3(p, &attr->ia_atime); - } else if (attr->ia_valid & ATTR_ATIME) { - *p++ = xdr_one; - } else { - *p++ = xdr_zero; - } - if (attr->ia_valid & ATTR_MTIME_SET) { - *p++ = xdr_two; - p = xdr_encode_time3(p, &attr->ia_mtime); - } else if (attr->ia_valid & ATTR_MTIME) { - *p++ = xdr_one; - } else { - *p++ = xdr_zero; - } - return p; -} - static inline __be32 * xdr_decode_wcc_attr(__be32 *p, struct nfs_fattr *fattr) { @@ -452,6 +398,21 @@ static void encode_nfs_fh3(struct xdr_stream *xdr, const struct nfs_fh *fh) xdr_encode_opaque(p, fh->data, fh->size); } +/* + * nfstime3 + * + * struct nfstime3 { + * uint32 seconds; + * uint32 nseconds; + * }; + */ +static __be32 *xdr_encode_nfstime3(__be32 *p, const struct timespec *timep) +{ + *p++ = cpu_to_be32(timep->tv_sec); + *p++ = cpu_to_be32(timep->tv_nsec); + return p; +} + /* * sattr3 * @@ -538,7 +499,45 @@ static void encode_sattr3(struct xdr_stream *xdr, const struct iattr *attr) nbytes += 8; p = xdr_reserve_space(xdr, nbytes); - xdr_encode_sattr(p, attr); + if (attr->ia_valid & ATTR_MODE) { + *p++ = xdr_one; + *p++ = cpu_to_be32(attr->ia_mode & S_IALLUGO); + } else + *p++ = xdr_zero; + + if (attr->ia_valid & ATTR_UID) { + *p++ = xdr_one; + *p++ = cpu_to_be32(attr->ia_uid); + } else + *p++ = xdr_zero; + + if (attr->ia_valid & ATTR_GID) { + *p++ = xdr_one; + *p++ = cpu_to_be32(attr->ia_gid); + } else + *p++ = xdr_zero; + + if (attr->ia_valid & ATTR_SIZE) { + *p++ = xdr_one; + p = xdr_encode_hyper(p, (u64)attr->ia_size); + } else + *p++ = xdr_zero; + + if (attr->ia_valid & ATTR_ATIME_SET) { + *p++ = xdr_two; + p = xdr_encode_nfstime3(p, &attr->ia_atime); + } else if (attr->ia_valid & ATTR_ATIME) { + *p++ = xdr_one; + } else + *p++ = xdr_zero; + + if (attr->ia_valid & ATTR_MTIME_SET) { + *p++ = xdr_two; + xdr_encode_nfstime3(p, &attr->ia_mtime); + } else if (attr->ia_valid & ATTR_MTIME) { + *p = xdr_one; + } else + *p = xdr_zero; } /* @@ -605,7 +604,7 @@ static void encode_sattrguard3(struct xdr_stream *xdr, if (args->guard) { p = xdr_reserve_space(xdr, 4 + 8); *p++ = xdr_one; - xdr_encode_time3(p, &args->guardtime); + xdr_encode_nfstime3(p, &args->guardtime); } else { p = xdr_reserve_space(xdr, 4); *p = xdr_zero; -- cgit v1.2.3 From e4f9323409369a3aeb01885c0c4409d2eeec794a Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Tue, 14 Dec 2010 14:56:30 +0000 Subject: NFS: Introduce new-style XDR decoding functions for NFSv2 We'd like to prevent local buffer overflows caused by malicious or broken servers. New xdr_stream style decoders can do that. For efficiency, we also eventually want to be able to pass xdr_streams from call_decode() to all XDR decoding functions, rather than building an xdr_stream in every XDR decoding function in the kernel. Static helper functions are left without the "inline" directive. This allows the compiler to choose automatically how to optimize these for size or speed. Signed-off-by: Chuck Lever Tested-by: J. Bruce Fields Signed-off-by: Trond Myklebust --- fs/nfs/nfs3xdr.c | 1534 +++++++++++++++++++++++++++++++++++++++++++++++--- include/linux/nfs3.h | 1 + 2 files changed, 1451 insertions(+), 84 deletions(-) diff --git a/fs/nfs/nfs3xdr.c b/fs/nfs/nfs3xdr.c index 119844d0b4d5..0f07c6d55131 100644 --- a/fs/nfs/nfs3xdr.c +++ b/fs/nfs/nfs3xdr.c @@ -104,13 +104,6 @@ static const umode_t nfs_type2fmt[] = { [NF3FIFO] = S_IFIFO, }; -static void print_overflow_msg(const char *func, const struct xdr_stream *xdr) -{ - dprintk("nfs: %s: prematurely hit end of receive buffer. " - "Remaining buffer length is %tu words.\n", - func, xdr->end - xdr->p); -} - /* * While encoding arguments, set up the reply buffer in advance to * receive reply data directly into the page cache. @@ -126,6 +119,16 @@ static void prepare_reply_buffer(struct rpc_rqst *req, struct page **pages, xdr_inline_pages(&req->rq_rcv_buf, replen << 2, pages, base, len); } +/* + * Handle decode buffer overflows out-of-line. + */ +static void print_overflow_msg(const char *func, const struct xdr_stream *xdr) +{ + dprintk("NFS: %s prematurely hit the end of our receive buffer. " + "Remaining buffer length is %tu words.\n", + func, xdr->end - xdr->p); +} + /* * Common NFS XDR functions as inlines @@ -284,6 +287,44 @@ static void encode_uint32(struct xdr_stream *xdr, u32 value) *p = cpu_to_be32(value); } +static int decode_uint32(struct xdr_stream *xdr, u32 *value) +{ + __be32 *p; + + p = xdr_inline_decode(xdr, 4); + if (unlikely(p == NULL)) + goto out_overflow; + *value = be32_to_cpup(p); + return 0; +out_overflow: + print_overflow_msg(__func__, xdr); + return -EIO; +} + +static int decode_uint64(struct xdr_stream *xdr, u64 *value) +{ + __be32 *p; + + p = xdr_inline_decode(xdr, 8); + if (unlikely(p == NULL)) + goto out_overflow; + xdr_decode_hyper(p, value); + return 0; +out_overflow: + print_overflow_msg(__func__, xdr); + return -EIO; +} + +/* + * fileid3 + * + * typedef uint64 fileid3; + */ +static int decode_fileid3(struct xdr_stream *xdr, u64 *fileid) +{ + return decode_uint64(xdr, fileid); +} + /* * filename3 * @@ -299,6 +340,33 @@ static void encode_filename3(struct xdr_stream *xdr, xdr_encode_opaque(p, name, length); } +static int decode_inline_filename3(struct xdr_stream *xdr, + const char **name, u32 *length) +{ + __be32 *p; + u32 count; + + p = xdr_inline_decode(xdr, 4); + if (unlikely(p == NULL)) + goto out_overflow; + count = be32_to_cpup(p); + if (count > NFS3_MAXNAMLEN) + goto out_nametoolong; + p = xdr_inline_decode(xdr, count); + if (unlikely(p == NULL)) + goto out_overflow; + *name = (const char *)p; + *length = count; + return 0; + +out_nametoolong: + dprintk("NFS: returned filename too long: %u\n", count); + return -ENAMETOOLONG; +out_overflow: + print_overflow_msg(__func__, xdr); + return -EIO; +} + /* * nfspath3 * @@ -312,6 +380,39 @@ static void encode_nfspath3(struct xdr_stream *xdr, struct page **pages, xdr_write_pages(xdr, pages, 0, length); } +static int decode_nfspath3(struct xdr_stream *xdr) +{ + u32 recvd, count; + size_t hdrlen; + __be32 *p; + + p = xdr_inline_decode(xdr, 4); + if (unlikely(p == NULL)) + goto out_overflow; + count = be32_to_cpup(p); + if (unlikely(count >= xdr->buf->page_len || count > NFS3_MAXPATHLEN)) + goto out_nametoolong; + hdrlen = (u8 *)xdr->p - (u8 *)xdr->iov->iov_base; + recvd = xdr->buf->len - hdrlen; + if (unlikely(count > recvd)) + goto out_cheating; + + xdr_read_pages(xdr, count); + xdr_terminate_string(xdr->buf, count); + return 0; + +out_nametoolong: + dprintk("NFS: returned pathname too long: %u\n", count); + return -ENAMETOOLONG; +out_cheating: + dprintk("NFS: server cheating in pathname result: " + "count %u > recvd %u\n", count, recvd); + return -EIO; +out_overflow: + print_overflow_msg(__func__, xdr); + return -EIO; +} + /* * cookie3 * @@ -322,6 +423,11 @@ static __be32 *xdr_encode_cookie3(__be32 *p, u64 cookie) return xdr_encode_hyper(p, cookie); } +static int decode_cookie3(struct xdr_stream *xdr, u64 *cookie) +{ + return decode_uint64(xdr, cookie); +} + /* * cookieverf3 * @@ -333,6 +439,20 @@ static __be32 *xdr_encode_cookieverf3(__be32 *p, const __be32 *verifier) return p + XDR_QUADLEN(NFS3_COOKIEVERFSIZE); } +static int decode_cookieverf3(struct xdr_stream *xdr, __be32 *verifier) +{ + __be32 *p; + + p = xdr_inline_decode(xdr, NFS3_COOKIEVERFSIZE); + if (unlikely(p == NULL)) + goto out_overflow; + memcpy(verifier, p, NFS3_COOKIEVERFSIZE); + return 0; +out_overflow: + print_overflow_msg(__func__, xdr); + return -EIO; +} + /* * createverf3 * @@ -346,6 +466,54 @@ static void encode_createverf3(struct xdr_stream *xdr, const __be32 *verifier) memcpy(p, verifier, NFS3_CREATEVERFSIZE); } +static int decode_writeverf3(struct xdr_stream *xdr, __be32 *verifier) +{ + __be32 *p; + + p = xdr_inline_decode(xdr, NFS3_WRITEVERFSIZE); + if (unlikely(p == NULL)) + goto out_overflow; + memcpy(verifier, p, NFS3_WRITEVERFSIZE); + return 0; +out_overflow: + print_overflow_msg(__func__, xdr); + return -EIO; +} + +/* + * size3 + * + * typedef uint64 size3; + */ +static __be32 *xdr_decode_size3(__be32 *p, u64 *size) +{ + return xdr_decode_hyper(p, size); +} + +/* + * nfsstat3 + * + * enum nfsstat3 { + * NFS3_OK = 0, + * ... + * } + */ +#define NFS3_OK NFS_OK + +static int decode_nfsstat3(struct xdr_stream *xdr, enum nfs_stat *status) +{ + __be32 *p; + + p = xdr_inline_decode(xdr, 4); + if (unlikely(p == NULL)) + goto out_overflow; + *status = be32_to_cpup(p); + return 0; +out_overflow: + print_overflow_msg(__func__, xdr); + return -EIO; +} + /* * ftype3 * @@ -398,6 +566,36 @@ static void encode_nfs_fh3(struct xdr_stream *xdr, const struct nfs_fh *fh) xdr_encode_opaque(p, fh->data, fh->size); } +static int decode_nfs_fh3(struct xdr_stream *xdr, struct nfs_fh *fh) +{ + u32 length; + __be32 *p; + + p = xdr_inline_decode(xdr, 4); + if (unlikely(p == NULL)) + goto out_overflow; + length = be32_to_cpup(p++); + if (unlikely(length > NFS3_FHSIZE)) + goto out_toobig; + p = xdr_inline_decode(xdr, length); + if (unlikely(p == NULL)) + goto out_overflow; + fh->size = length; + memcpy(fh->data, p, length); + return 0; +out_toobig: + dprintk("NFS: file handle size (%u) too big\n", length); + return -E2BIG; +out_overflow: + print_overflow_msg(__func__, xdr); + return -EIO; +} + +static void zero_nfs_fh3(struct nfs_fh *fh) +{ + memset(fh, 0, sizeof(*fh)); +} + /* * nfstime3 * @@ -540,6 +738,153 @@ static void encode_sattr3(struct xdr_stream *xdr, const struct iattr *attr) *p = xdr_zero; } +/* + * fattr3 + * + * struct fattr3 { + * ftype3 type; + * mode3 mode; + * uint32 nlink; + * uid3 uid; + * gid3 gid; + * size3 size; + * size3 used; + * specdata3 rdev; + * uint64 fsid; + * fileid3 fileid; + * nfstime3 atime; + * nfstime3 mtime; + * nfstime3 ctime; + * }; + */ +static int decode_fattr3(struct xdr_stream *xdr, struct nfs_fattr *fattr) +{ + __be32 *p; + + p = xdr_inline_decode(xdr, NFS3_fattr_sz << 2); + if (unlikely(p == NULL)) + goto out_overflow; + xdr_decode_fattr(p, fattr); + return 0; +out_overflow: + print_overflow_msg(__func__, xdr); + return -EIO; +} + +/* + * post_op_attr + * + * union post_op_attr switch (bool attributes_follow) { + * case TRUE: + * fattr3 attributes; + * case FALSE: + * void; + * }; + */ +static int decode_post_op_attr(struct xdr_stream *xdr, struct nfs_fattr *fattr) +{ + __be32 *p; + + p = xdr_inline_decode(xdr, 4); + if (unlikely(p == NULL)) + goto out_overflow; + if (*p != xdr_zero) + return decode_fattr3(xdr, fattr); + return 0; +out_overflow: + print_overflow_msg(__func__, xdr); + return -EIO; +} + +/* + * wcc_attr + * struct wcc_attr { + * size3 size; + * nfstime3 mtime; + * nfstime3 ctime; + * }; + */ +static int decode_wcc_attr(struct xdr_stream *xdr, struct nfs_fattr *fattr) +{ + __be32 *p; + + p = xdr_inline_decode(xdr, NFS3_wcc_attr_sz << 2); + if (unlikely(p == NULL)) + goto out_overflow; + xdr_decode_wcc_attr(p, fattr); + return 0; +out_overflow: + print_overflow_msg(__func__, xdr); + return -EIO; +} + +/* + * pre_op_attr + * union pre_op_attr switch (bool attributes_follow) { + * case TRUE: + * wcc_attr attributes; + * case FALSE: + * void; + * }; + * + * wcc_data + * + * struct wcc_data { + * pre_op_attr before; + * post_op_attr after; + * }; + */ +static int decode_pre_op_attr(struct xdr_stream *xdr, struct nfs_fattr *fattr) +{ + __be32 *p; + + p = xdr_inline_decode(xdr, 4); + if (unlikely(p == NULL)) + goto out_overflow; + if (*p != xdr_zero) + return decode_wcc_attr(xdr, fattr); + return 0; +out_overflow: + print_overflow_msg(__func__, xdr); + return -EIO; +} + +static int decode_wcc_data(struct xdr_stream *xdr, struct nfs_fattr *fattr) +{ + int error; + + error = decode_pre_op_attr(xdr, fattr); + if (unlikely(error)) + goto out; + error = decode_post_op_attr(xdr, fattr); +out: + return error; +} + +/* + * post_op_fh3 + * + * union post_op_fh3 switch (bool handle_follows) { + * case TRUE: + * nfs_fh3 handle; + * case FALSE: + * void; + * }; + */ +static int decode_post_op_fh3(struct xdr_stream *xdr, struct nfs_fh *fh) +{ + __be32 *p = xdr_inline_decode(xdr, 4); + if (unlikely(p == NULL)) + goto out_overflow; + if (*p != xdr_zero) + return decode_nfs_fh3(xdr, fh); + zero_nfs_fh3(fh); + return 0; +out_overflow: + print_overflow_msg(__func__, xdr); + return -EIO; +} + /* * diropargs3 * @@ -1108,78 +1453,6 @@ nfs3_xdr_readdirres(struct rpc_rqst *req, __be32 *p, struct nfs3_readdirres *res return pglen; } -__be32 * -nfs3_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry, struct nfs_server *server, int plus) -{ - __be32 *p; - struct nfs_entry old = *entry; - - p = xdr_inline_decode(xdr, 4); - if (unlikely(!p)) - goto out_overflow; - if (!ntohl(*p++)) { - p = xdr_inline_decode(xdr, 4); - if (unlikely(!p)) - goto out_overflow; - if (!ntohl(*p++)) - return ERR_PTR(-EAGAIN); - entry->eof = 1; - return ERR_PTR(-EBADCOOKIE); - } - - p = xdr_inline_decode(xdr, 12); - if (unlikely(!p)) - goto out_overflow; - p = xdr_decode_hyper(p, &entry->ino); - entry->len = ntohl(*p++); - - p = xdr_inline_decode(xdr, entry->len + 8); - if (unlikely(!p)) - goto out_overflow; - entry->name = (const char *) p; - p += XDR_QUADLEN(entry->len); - entry->prev_cookie = entry->cookie; - p = xdr_decode_hyper(p, &entry->cookie); - - entry->d_type = DT_UNKNOWN; - if (plus) { - entry->fattr->valid = 0; - p = xdr_decode_post_op_attr_stream(xdr, entry->fattr); - if (IS_ERR(p)) - goto out_overflow_exit; - entry->d_type = nfs_umode_to_dtype(entry->fattr->mode); - /* In fact, a post_op_fh3: */ - p = xdr_inline_decode(xdr, 4); - if (unlikely(!p)) - goto out_overflow; - if (*p++) { - p = xdr_decode_fhandle_stream(xdr, entry->fh); - if (IS_ERR(p)) - goto out_overflow_exit; - /* Ugh -- server reply was truncated */ - if (p == NULL) { - dprintk("NFS: FH truncated\n"); - *entry = old; - return ERR_PTR(-EAGAIN); - } - } else - memset((u8*)(entry->fh), 0, sizeof(*entry->fh)); - } - - p = xdr_inline_peek(xdr, 8); - if (p != NULL) - entry->eof = !p[0] && p[1]; - else - entry->eof = 0; - - return p; - -out_overflow: - print_overflow_msg(__func__, xdr); -out_overflow_exit: - return ERR_PTR(-EAGAIN); -} - /* * 3.3.21 COMMIT3args * @@ -1275,13 +1548,47 @@ nfs3_xdr_attrstat(struct rpc_rqst *req, __be32 *p, struct nfs_fattr *fattr) } /* - * Decode status+wcc_data reply - * SATTR, REMOVE, RMDIR + * 3.3.1 GETATTR3res + * + * struct GETATTR3resok { + * fattr3 obj_attributes; + * }; + * + * union GETATTR3res switch (nfsstat3 status) { + * case NFS3_OK: + * GETATTR3resok resok; + * default: + * void; + * }; */ -static int -nfs3_xdr_wccstat(struct rpc_rqst *req, __be32 *p, struct nfs_fattr *fattr) +static int nfs3_xdr_dec_getattr3res(struct rpc_rqst *req, __be32 *p, + struct nfs_fattr *result) { - int status; + struct xdr_stream xdr; + enum nfs_stat status; + int error; + + xdr_init_decode(&xdr, &req->rq_rcv_buf, p); + error = decode_nfsstat3(&xdr, &status); + if (unlikely(error)) + goto out; + if (status != NFS3_OK) + goto out_default; + error = decode_fattr3(&xdr, result); +out: + return error; +out_default: + return nfs_stat_to_errno(status); +} + +/* + * Decode status+wcc_data reply + * SATTR, REMOVE, RMDIR + */ +static int +nfs3_xdr_wccstat(struct rpc_rqst *req, __be32 *p, struct nfs_fattr *fattr) +{ + int status; if ((status = ntohl(*p++))) status = nfs_stat_to_errno(status); @@ -1289,6 +1596,46 @@ nfs3_xdr_wccstat(struct rpc_rqst *req, __be32 *p, struct nfs_fattr *fattr) return status; } +/* + * 3.3.2 SETATTR3res + * + * struct SETATTR3resok { + * wcc_data obj_wcc; + * }; + * + * struct SETATTR3resfail { + * wcc_data obj_wcc; + * }; + * + * union SETATTR3res switch (nfsstat3 status) { + * case NFS3_OK: + * SETATTR3resok resok; + * default: + * SETATTR3resfail resfail; + * }; + */ +static int nfs3_xdr_dec_setattr3res(struct rpc_rqst *req, __be32 *p, + struct nfs_fattr *result) +{ + struct xdr_stream xdr; + enum nfs_stat status; + int error; + + xdr_init_decode(&xdr, &req->rq_rcv_buf, p); + error = decode_nfsstat3(&xdr, &status); + if (unlikely(error)) + goto out; + error = decode_wcc_data(&xdr, result); + if (unlikely(error)) + goto out; + if (status != NFS3_OK) + goto out_status; +out: + return error; +out_status: + return nfs_stat_to_errno(status); +} + static int nfs3_xdr_removeres(struct rpc_rqst *req, __be32 *p, struct nfs_removeres *res) { @@ -1314,6 +1661,55 @@ nfs3_xdr_lookupres(struct rpc_rqst *req, __be32 *p, struct nfs3_diropres *res) return status; } +/* + * 3.3.3 LOOKUP3res + * + * struct LOOKUP3resok { + * nfs_fh3 object; + * post_op_attr obj_attributes; + * post_op_attr dir_attributes; + * }; + * + * struct LOOKUP3resfail { + * post_op_attr dir_attributes; + * }; + * + * union LOOKUP3res switch (nfsstat3 status) { + * case NFS3_OK: + * LOOKUP3resok resok; + * default: + * LOOKUP3resfail resfail; + * }; + */ +static int nfs3_xdr_dec_lookup3res(struct rpc_rqst *req, __be32 *p, + struct nfs3_diropres *result) +{ + struct xdr_stream xdr; + enum nfs_stat status; + int error; + + xdr_init_decode(&xdr, &req->rq_rcv_buf, p); + error = decode_nfsstat3(&xdr, &status); + if (unlikely(error)) + goto out; + if (status != NFS3_OK) + goto out_default; + error = decode_nfs_fh3(&xdr, result->fh); + if (unlikely(error)) + goto out; + error = decode_post_op_attr(&xdr, result->fattr); + if (unlikely(error)) + goto out; + error = decode_post_op_attr(&xdr, result->dir_attr); +out: + return error; +out_default: + error = decode_post_op_attr(&xdr, result->dir_attr); + if (unlikely(error)) + goto out; + return nfs_stat_to_errno(status); +} + /* * Decode ACCESS reply */ @@ -1329,6 +1725,48 @@ nfs3_xdr_accessres(struct rpc_rqst *req, __be32 *p, struct nfs3_accessres *res) return 0; } +/* + * 3.3.4 ACCESS3res + * + * struct ACCESS3resok { + * post_op_attr obj_attributes; + * uint32 access; + * }; + * + * struct ACCESS3resfail { + * post_op_attr obj_attributes; + * }; + * + * union ACCESS3res switch (nfsstat3 status) { + * case NFS3_OK: + * ACCESS3resok resok; + * default: + * ACCESS3resfail resfail; + * }; + */ +static int nfs3_xdr_dec_access3res(struct rpc_rqst *req, __be32 *p, + struct nfs3_accessres *result) +{ + struct xdr_stream xdr; + enum nfs_stat status; + int error; + + xdr_init_decode(&xdr, &req->rq_rcv_buf, p); + error = decode_nfsstat3(&xdr, &status); + if (unlikely(error)) + goto out; + error = decode_post_op_attr(&xdr, result->fattr); + if (unlikely(error)) + goto out; + if (status != NFS3_OK) + goto out_default; + error = decode_uint32(&xdr, &result->access); +out: + return error; +out_default: + return nfs_stat_to_errno(status); +} + /* * Decode READLINK reply */ @@ -1375,6 +1813,48 @@ nfs3_xdr_readlinkres(struct rpc_rqst *req, __be32 *p, struct nfs_fattr *fattr) return 0; } +/* + * 3.3.5 READLINK3res + * + * struct READLINK3resok { + * post_op_attr symlink_attributes; + * nfspath3 data; + * }; + * + * struct READLINK3resfail { + * post_op_attr symlink_attributes; + * }; + * + * union READLINK3res switch (nfsstat3 status) { + * case NFS3_OK: + * READLINK3resok resok; + * default: + * READLINK3resfail resfail; + * }; + */ +static int nfs3_xdr_dec_readlink3res(struct rpc_rqst *req, __be32 *p, + struct nfs_fattr *result) +{ + struct xdr_stream xdr; + enum nfs_stat status; + int error; + + xdr_init_decode(&xdr, &req->rq_rcv_buf, p); + error = decode_nfsstat3(&xdr, &status); + if (unlikely(error)) + goto out; + error = decode_post_op_attr(&xdr, result); + if (unlikely(error)) + goto out; + if (status != NFS3_OK) + goto out_default; + error = decode_nfspath3(&xdr); +out: + return error; +out_default: + return nfs_stat_to_errno(status); +} + /* * Decode READ reply */ @@ -1428,6 +1908,90 @@ nfs3_xdr_readres(struct rpc_rqst *req, __be32 *p, struct nfs_readres *res) return count; } +/* + * 3.3.6 READ3res + * + * struct READ3resok { + * post_op_attr file_attributes; + * count3 count; + * bool eof; + * opaque data<>; + * }; + * + * struct READ3resfail { + * post_op_attr file_attributes; + * }; + * + * union READ3res switch (nfsstat3 status) { + * case NFS3_OK: + * READ3resok resok; + * default: + * READ3resfail resfail; + * }; + */ +static int decode_read3resok(struct xdr_stream *xdr, + struct nfs_readres *result) +{ + u32 eof, count, ocount, recvd; + size_t hdrlen; + __be32 *p; + + p = xdr_inline_decode(xdr, 4 + 4 + 4); + if (unlikely(p == NULL)) + goto out_overflow; + count = be32_to_cpup(p++); + eof = be32_to_cpup(p++); + ocount = be32_to_cpup(p++); + if (unlikely(ocount != count)) + goto out_mismatch; + hdrlen = (u8 *)xdr->p - (u8 *)xdr->iov->iov_base; + recvd = xdr->buf->len - hdrlen; + if (unlikely(count > recvd)) + goto out_cheating; + +out: + xdr_read_pages(xdr, count); + result->eof = eof; + result->count = count; + return count; +out_mismatch: + dprintk("NFS: READ count doesn't match length of opaque: " + "count %u != ocount %u\n", count, ocount); + return -EIO; +out_cheating: + dprintk("NFS: server cheating in read result: " + "count %u > recvd %u\n", count, recvd); + count = recvd; + eof = 0; + goto out; +out_overflow: + print_overflow_msg(__func__, xdr); + return -EIO; +} + +static int nfs3_xdr_dec_read3res(struct rpc_rqst *req, __be32 *p, + struct nfs_readres *result) +{ + struct xdr_stream xdr; + enum nfs_stat status; + int error; + + xdr_init_decode(&xdr, &req->rq_rcv_buf, p); + error = decode_nfsstat3(&xdr, &status); + if (unlikely(error)) + goto out; + error = decode_post_op_attr(&xdr, result->fattr); + if (unlikely(error)) + goto out; + if (status != NFS3_OK) + goto out_status; + error = decode_read3resok(&xdr, result); +out: + return error; +out_status: + return nfs_stat_to_errno(status); +} + /* * Decode WRITE response */ @@ -1450,6 +2014,78 @@ nfs3_xdr_writeres(struct rpc_rqst *req, __be32 *p, struct nfs_writeres *res) return res->count; } +/* + * 3.3.7 WRITE3res + * + * enum stable_how { + * UNSTABLE = 0, + * DATA_SYNC = 1, + * FILE_SYNC = 2 + * }; + * + * struct WRITE3resok { + * wcc_data file_wcc; + * count3 count; + * stable_how committed; + * writeverf3 verf; + * }; + * + * struct WRITE3resfail { + * wcc_data file_wcc; + * }; + * + * union WRITE3res switch (nfsstat3 status) { + * case NFS3_OK: + * WRITE3resok resok; + * default: + * WRITE3resfail resfail; + * }; + */ +static int decode_write3resok(struct xdr_stream *xdr, + struct nfs_writeres *result) +{ + __be32 *p; + + p = xdr_inline_decode(xdr, 4 + 4 + NFS3_WRITEVERFSIZE); + if (unlikely(p == NULL)) + goto out_overflow; + result->count = be32_to_cpup(p++); + result->verf->committed = be32_to_cpup(p++); + if (unlikely(result->verf->committed > NFS_FILE_SYNC)) + goto out_badvalue; + memcpy(result->verf->verifier, p, NFS3_WRITEVERFSIZE); + return result->count; +out_badvalue: + dprintk("NFS: bad stable_how value: %u\n", result->verf->committed); + return -EIO; +out_overflow: + print_overflow_msg(__func__, xdr); + return -EIO; +} + +static int nfs3_xdr_dec_write3res(struct rpc_rqst *req, __be32 *p, + struct nfs_writeres *result) +{ + struct xdr_stream xdr; + enum nfs_stat status; + int error; + + xdr_init_decode(&xdr, &req->rq_rcv_buf, p); + error = decode_nfsstat3(&xdr, &status); + if (unlikely(error)) + goto out; + error = decode_wcc_data(&xdr, result->fattr); + if (unlikely(error)) + goto out; + if (status != NFS3_OK) + goto out_status; + error = decode_write3resok(&xdr, result); +out: + return error; +out_status: + return nfs_stat_to_errno(status); +} + /* * Decode a CREATE response */ @@ -1477,6 +2113,111 @@ nfs3_xdr_createres(struct rpc_rqst *req, __be32 *p, struct nfs3_diropres *res) return status; } +/* + * 3.3.8 CREATE3res + * + * struct CREATE3resok { + * post_op_fh3 obj; + * post_op_attr obj_attributes; + * wcc_data dir_wcc; + * }; + * + * struct CREATE3resfail { + * wcc_data dir_wcc; + * }; + * + * union CREATE3res switch (nfsstat3 status) { + * case NFS3_OK: + * CREATE3resok resok; + * default: + * CREATE3resfail resfail; + * }; + */ +static int decode_create3resok(struct xdr_stream *xdr, + struct nfs3_diropres *result) +{ + int error; + + error = decode_post_op_fh3(xdr, result->fh); + if (unlikely(error)) + goto out; + error = decode_post_op_attr(xdr, result->fattr); + if (unlikely(error)) + goto out; + /* The server isn't required to return a file handle. + * If it didn't, force the client to perform a LOOKUP + * to determine the correct file handle and attribute + * values for the new object. */ + if (result->fh->size == 0) + result->fattr->valid = 0; + error = decode_wcc_data(xdr, result->dir_attr); +out: + return error; +} + +static int nfs3_xdr_dec_create3res(struct rpc_rqst *req, __be32 *p, + struct nfs3_diropres *result) +{ + struct xdr_stream xdr; + enum nfs_stat status; + int error; + + xdr_init_decode(&xdr, &req->rq_rcv_buf, p); + error = decode_nfsstat3(&xdr, &status); + if (unlikely(error)) + goto out; + if (status != NFS3_OK) + goto out_default; + error = decode_create3resok(&xdr, result); +out: + return error; +out_default: + error = decode_wcc_data(&xdr, result->dir_attr); + if (unlikely(error)) + goto out; + return nfs_stat_to_errno(status); +} + +/* + * 3.3.12 REMOVE3res + * + * struct REMOVE3resok { + * wcc_data dir_wcc; + * }; + * + * struct REMOVE3resfail { + * wcc_data dir_wcc; + * }; + * + * union REMOVE3res switch (nfsstat3 status) { + * case NFS3_OK: + * REMOVE3resok resok; + * default: + * REMOVE3resfail resfail; + * }; + */ +static int nfs3_xdr_dec_remove3res(struct rpc_rqst *req, __be32 *p, + struct nfs_removeres *result) +{ + struct xdr_stream xdr; + enum nfs_stat status; + int error; + + xdr_init_decode(&xdr, &req->rq_rcv_buf, p); + error = decode_nfsstat3(&xdr, &status); + if (unlikely(error)) + goto out; + error = decode_wcc_data(&xdr, result->dir_attr); + if (unlikely(error)) + goto out; + if (status != NFS3_OK) + goto out_status; +out: + return error; +out_status: + return nfs_stat_to_errno(status); +} + /* * Decode RENAME reply */ @@ -1492,6 +2233,51 @@ nfs3_xdr_renameres(struct rpc_rqst *req, __be32 *p, struct nfs_renameres *res) return status; } +/* + * 3.3.14 RENAME3res + * + * struct RENAME3resok { + * wcc_data fromdir_wcc; + * wcc_data todir_wcc; + * }; + * + * struct RENAME3resfail { + * wcc_data fromdir_wcc; + * wcc_data todir_wcc; + * }; + * + * union RENAME3res switch (nfsstat3 status) { + * case NFS3_OK: + * RENAME3resok resok; + * default: + * RENAME3resfail resfail; + * }; + */ +static int nfs3_xdr_dec_rename3res(struct rpc_rqst *req, __be32 *p, + struct nfs_renameres *result) +{ + struct xdr_stream xdr; + enum nfs_stat status; + int error; + + xdr_init_decode(&xdr, &req->rq_rcv_buf, p); + error = decode_nfsstat3(&xdr, &status); + if (unlikely(error)) + goto out; + error = decode_wcc_data(&xdr, result->old_fattr); + if (unlikely(error)) + goto out; + error = decode_wcc_data(&xdr, result->new_fattr); + if (unlikely(error)) + goto out; + if (status != NFS3_OK) + goto out_status; +out: + return error; +out_status: + return nfs_stat_to_errno(status); +} + /* * Decode LINK reply */ @@ -1507,6 +2293,249 @@ nfs3_xdr_linkres(struct rpc_rqst *req, __be32 *p, struct nfs3_linkres *res) return status; } +/* + * 3.3.15 LINK3res + * + * struct LINK3resok { + * post_op_attr file_attributes; + * wcc_data linkdir_wcc; + * }; + * + * struct LINK3resfail { + * post_op_attr file_attributes; + * wcc_data linkdir_wcc; + * }; + * + * union LINK3res switch (nfsstat3 status) { + * case NFS3_OK: + * LINK3resok resok; + * default: + * LINK3resfail resfail; + * }; + */ +static int nfs3_xdr_dec_link3res(struct rpc_rqst *req, __be32 *p, + struct nfs3_linkres *result) +{ + struct xdr_stream xdr; + enum nfs_stat status; + int error; + + xdr_init_decode(&xdr, &req->rq_rcv_buf, p); + error = decode_nfsstat3(&xdr, &status); + if (unlikely(error)) + goto out; + error = decode_post_op_attr(&xdr, result->fattr); + if (unlikely(error)) + goto out; + error = decode_wcc_data(&xdr, result->dir_attr); + if (unlikely(error)) + goto out; + if (status != NFS3_OK) + goto out_status; +out: + return error; +out_status: + return nfs_stat_to_errno(status); +} + +/** + * nfs3_decode_dirent - Decode a single NFSv3 directory entry stored in + * the local page cache + * @xdr: XDR stream where entry resides + * @entry: buffer to fill in with entry data + * @server: nfs_server data for this directory + * @plus: boolean indicating whether this should be a readdirplus entry + * + * Returns the position of the next item in the buffer, or an ERR_PTR. + * + * This function is not invoked during READDIR reply decoding, but + * rather whenever an application invokes the getdents(2) system call + * on a directory already in our cache. + * + * 3.3.16 entry3 + * + * struct entry3 { + * fileid3 fileid; + * filename3 name; + * cookie3 cookie; + * fhandle3 filehandle; + * post_op_attr3 attributes; + * entry3 *nextentry; + * }; + * + * 3.3.17 entryplus3 + * struct entryplus3 { + * fileid3 fileid; + * filename3 name; + * cookie3 cookie; + * post_op_attr name_attributes; + * post_op_fh3 name_handle; + * entryplus3 *nextentry; + * }; + */ +__be32 *nfs3_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry, + struct nfs_server *server, int plus) +{ + struct nfs_entry old = *entry; + __be32 *p; + int error; + + p = xdr_inline_decode(xdr, 4); + if (unlikely(p == NULL)) + goto out_overflow; + if (*p == xdr_zero) { + p = xdr_inline_decode(xdr, 4); + if (unlikely(p == NULL)) + goto out_overflow; + if (*p == xdr_zero) + return ERR_PTR(-EAGAIN); + entry->eof = 1; + return ERR_PTR(-EBADCOOKIE); + } + + error = decode_fileid3(xdr, &entry->ino); + if (unlikely(error)) + return ERR_PTR(error); + + error = decode_inline_filename3(xdr, &entry->name, &entry->len); + if (unlikely(error)) + return ERR_PTR(error); + + entry->prev_cookie = entry->cookie; + error = decode_cookie3(xdr, &entry->cookie); + if (unlikely(error)) + return ERR_PTR(error); + + entry->d_type = DT_UNKNOWN; + + if (plus) { + entry->fattr->valid = 0; + error = decode_post_op_attr(xdr, entry->fattr); + if (unlikely(error)) + return ERR_PTR(error); + if (entry->fattr->valid & NFS_ATTR_FATTR_V3) + entry->d_type = nfs_umode_to_dtype(entry->fattr->mode); + + /* In fact, a post_op_fh3: */ + p = xdr_inline_decode(xdr, 4); + if (unlikely(p == NULL)) + goto out_overflow; + if (*p != xdr_zero) { + error = decode_nfs_fh3(xdr, entry->fh); + if (unlikely(error)) { + if (error == -E2BIG) + goto out_truncated; + return ERR_PTR(error); + } + } else + zero_nfs_fh3(entry->fh); + } + + /* Peek at the next entry to see if we're at EOD */ + p = xdr_inline_peek(xdr, 4 + 4); + entry->eof = 0; + if (p != NULL) + entry->eof = (p[0] == xdr_zero) && (p[1] != xdr_zero); + return p; + +out_overflow: + print_overflow_msg(__func__, xdr); + return ERR_PTR(-EAGAIN); +out_truncated: + dprintk("NFS: directory entry contains invalid file handle\n"); + *entry = old; + return ERR_PTR(-EAGAIN); +} + +/* + * 3.3.16 READDIR3res + * + * struct dirlist3 { + * entry3 *entries; + * bool eof; + * }; + * + * struct READDIR3resok { + * post_op_attr dir_attributes; + * cookieverf3 cookieverf; + * dirlist3 reply; + * }; + * + * struct READDIR3resfail { + * post_op_attr dir_attributes; + * }; + * + * union READDIR3res switch (nfsstat3 status) { + * case NFS3_OK: + * READDIR3resok resok; + * default: + * READDIR3resfail resfail; + * }; + * + * Read the directory contents into the page cache, but otherwise + * don't touch them. The actual decoding is done by nfs3_decode_entry() + * during subsequent nfs_readdir() calls. + */ +static int decode_dirlist3(struct xdr_stream *xdr) +{ + u32 recvd, pglen; + size_t hdrlen; + + pglen = xdr->buf->page_len; + hdrlen = (u8 *)xdr->p - (u8 *)xdr->iov->iov_base; + recvd = xdr->buf->len - hdrlen; + if (unlikely(pglen > recvd)) + goto out_cheating; +out: + xdr_read_pages(xdr, pglen); + return pglen; +out_cheating: + dprintk("NFS: server cheating in readdir result: " + "pglen %u > recvd %u\n", pglen, recvd); + pglen = recvd; + goto out; +} + +static int decode_readdir3resok(struct xdr_stream *xdr, + struct nfs3_readdirres *result) +{ + int error; + + error = decode_post_op_attr(xdr, result->dir_attr); + if (unlikely(error)) + goto out; + /* XXX: do we need to check if result->verf != NULL ? */ + error = decode_cookieverf3(xdr, result->verf); + if (unlikely(error)) + goto out; + error = decode_dirlist3(xdr); +out: + return error; +} + +static int nfs3_xdr_dec_readdir3res(struct rpc_rqst *req, __be32 *p, + struct nfs3_readdirres *result) +{ + struct xdr_stream xdr; + enum nfs_stat status; + int error; + + xdr_init_decode(&xdr, &req->rq_rcv_buf, p); + error = decode_nfsstat3(&xdr, &status); + if (unlikely(error)) + goto out; + if (status != NFS3_OK) + goto out_default; + error = decode_readdir3resok(&xdr, result); +out: + return error; +out_default: + error = decode_post_op_attr(&xdr, result->dir_attr); + if (unlikely(error)) + goto out; + return nfs_stat_to_errno(status); +} + /* * Decode FSSTAT reply */ @@ -1532,6 +2561,75 @@ nfs3_xdr_fsstatres(struct rpc_rqst *req, __be32 *p, struct nfs_fsstat *res) return 0; } +/* + * 3.3.18 FSSTAT3res + * + * struct FSSTAT3resok { + * post_op_attr obj_attributes; + * size3 tbytes; + * size3 fbytes; + * size3 abytes; + * size3 tfiles; + * size3 ffiles; + * size3 afiles; + * uint32 invarsec; + * }; + * + * struct FSSTAT3resfail { + * post_op_attr obj_attributes; + * }; + * + * union FSSTAT3res switch (nfsstat3 status) { + * case NFS3_OK: + * FSSTAT3resok resok; + * default: + * FSSTAT3resfail resfail; + * }; + */ +static int decode_fsstat3resok(struct xdr_stream *xdr, + struct nfs_fsstat *result) +{ + __be32 *p; + + p = xdr_inline_decode(xdr, 8 * 6 + 4); + if (unlikely(p == NULL)) + goto out_overflow; + p = xdr_decode_size3(p, &result->tbytes); + p = xdr_decode_size3(p, &result->fbytes); + p = xdr_decode_size3(p, &result->abytes); + p = xdr_decode_size3(p, &result->tfiles); + p = xdr_decode_size3(p, &result->ffiles); + xdr_decode_size3(p, &result->afiles); + /* ignore invarsec */ + return 0; +out_overflow: + print_overflow_msg(__func__, xdr); + return -EIO; +} + +static int nfs3_xdr_dec_fsstat3res(struct rpc_rqst *req, __be32 *p, + struct nfs_fsstat *result) +{ + struct xdr_stream xdr; + enum nfs_stat status; + int error; + + xdr_init_decode(&xdr, &req->rq_rcv_buf, p); + error = decode_nfsstat3(&xdr, &status); + if (unlikely(error)) + goto out; + error = decode_post_op_attr(&xdr, result->fattr); + if (unlikely(error)) + goto out; + if (status != NFS3_OK) + goto out_status; + error = decode_fsstat3resok(&xdr, result); +out: + return error; +out_status: + return nfs_stat_to_errno(status); +} + /* * Decode FSINFO reply */ @@ -1561,6 +2659,83 @@ nfs3_xdr_fsinfores(struct rpc_rqst *req, __be32 *p, struct nfs_fsinfo *res) return 0; } +/* + * 3.3.19 FSINFO3res + * + * struct FSINFO3resok { + * post_op_attr obj_attributes; + * uint32 rtmax; + * uint32 rtpref; + * uint32 rtmult; + * uint32 wtmax; + * uint32 wtpref; + * uint32 wtmult; + * uint32 dtpref; + * size3 maxfilesize; + * nfstime3 time_delta; + * uint32 properties; + * }; + * + * struct FSINFO3resfail { + * post_op_attr obj_attributes; + * }; + * + * union FSINFO3res switch (nfsstat3 status) { + * case NFS3_OK: + * FSINFO3resok resok; + * default: + * FSINFO3resfail resfail; + * }; + */ +static int decode_fsinfo3resok(struct xdr_stream *xdr, + struct nfs_fsinfo *result) +{ + __be32 *p; + + p = xdr_inline_decode(xdr, 4 * 7 + 8 + 8 + 4); + if (unlikely(p == NULL)) + goto out_overflow; + result->rtmax = be32_to_cpup(p++); + result->rtpref = be32_to_cpup(p++); + result->rtmult = be32_to_cpup(p++); + result->wtmax = be32_to_cpup(p++); + result->wtpref = be32_to_cpup(p++); + result->wtmult = be32_to_cpup(p++); + result->dtpref = be32_to_cpup(p++); + p = xdr_decode_size3(p, &result->maxfilesize); + xdr_decode_time3(p, &result->time_delta); + + /* ignore properties */ + result->lease_time = 0; + return 0; +out_overflow: + print_overflow_msg(__func__, xdr); + return -EIO; +} + +static int nfs3_xdr_dec_fsinfo3res(struct rpc_rqst *req, __be32 *p, + struct nfs_fsinfo *result) +{ + struct xdr_stream xdr; + enum nfs_stat status; + int error; + + xdr_init_decode(&xdr, &req->rq_rcv_buf, p); + error = decode_nfsstat3(&xdr, &status); + if (unlikely(error)) + goto out; + error = decode_post_op_attr(&xdr, result->fattr); + if (unlikely(error)) + goto out; + if (status != NFS3_OK) + goto out_status; + error = decode_fsinfo3resok(&xdr, result); +out: + return error; +out_status: + return nfs_stat_to_errno(status); +} + /* * Decode PATHCONF reply */ @@ -1581,6 +2756,70 @@ nfs3_xdr_pathconfres(struct rpc_rqst *req, __be32 *p, struct nfs_pathconf *res) return 0; } +/* + * 3.3.20 PATHCONF3res + * + * struct PATHCONF3resok { + * post_op_attr obj_attributes; + * uint32 linkmax; + * uint32 name_max; + * bool no_trunc; + * bool chown_restricted; + * bool case_insensitive; + * bool case_preserving; + * }; + * + * struct PATHCONF3resfail { + * post_op_attr obj_attributes; + * }; + * + * union PATHCONF3res switch (nfsstat3 status) { + * case NFS3_OK: + * PATHCONF3resok resok; + * default: + * PATHCONF3resfail resfail; + * }; + */ +static int decode_pathconf3resok(struct xdr_stream *xdr, + struct nfs_pathconf *result) +{ + __be32 *p; + + p = xdr_inline_decode(xdr, 4 * 6); + if (unlikely(p == NULL)) + goto out_overflow; + result->max_link = be32_to_cpup(p++); + result->max_namelen = be32_to_cpup(p); + /* ignore remaining fields */ + return 0; +out_overflow: + print_overflow_msg(__func__, xdr); + return -EIO; +} + +static int nfs3_xdr_dec_pathconf3res(struct rpc_rqst *req, __be32 *p, + struct nfs_pathconf *result) +{ + struct xdr_stream xdr; + enum nfs_stat status; + int error; + + xdr_init_decode(&xdr, &req->rq_rcv_buf, p); + error = decode_nfsstat3(&xdr, &status); + if (unlikely(error)) + goto out; + error = decode_post_op_attr(&xdr, result->fattr); + if (unlikely(error)) + goto out; + if (status != NFS3_OK) + goto out_status; + error = decode_pathconf3resok(&xdr, result); +out: + return error; +out_status: + return nfs_stat_to_errno(status); +} + /* * Decode COMMIT reply */ @@ -1599,6 +2838,48 @@ nfs3_xdr_commitres(struct rpc_rqst *req, __be32 *p, struct nfs_writeres *res) return 0; } +/* + * 3.3.21 COMMIT3res + * + * struct COMMIT3resok { + * wcc_data file_wcc; + * writeverf3 verf; + * }; + * + * struct COMMIT3resfail { + * wcc_data file_wcc; + * }; + * + * union COMMIT3res switch (nfsstat3 status) { + * case NFS3_OK: + * COMMIT3resok resok; + * default: + * COMMIT3resfail resfail; + * }; + */ +static int nfs3_xdr_dec_commit3res(struct rpc_rqst *req, __be32 *p, + struct nfs_writeres *result) +{ + struct xdr_stream xdr; + enum nfs_stat status; + int error; + + xdr_init_decode(&xdr, &req->rq_rcv_buf, p); + error = decode_nfsstat3(&xdr, &status); + if (unlikely(error)) + goto out; + error = decode_wcc_data(&xdr, result->fattr); + if (unlikely(error)) + goto out; + if (status != NFS3_OK) + goto out_status; + error = decode_writeverf3(&xdr, result->verf->verifier); +out: + return error; +out_status: + return nfs_stat_to_errno(status); +} + #ifdef CONFIG_NFS_V3_ACL /* * Decode GETACL reply @@ -1632,6 +2913,70 @@ nfs3_xdr_getaclres(struct rpc_rqst *req, __be32 *p, return (err > 0) ? 0 : err; } +static inline int decode_getacl3resok(struct xdr_stream *xdr, + struct nfs3_getaclres *result) +{ + struct posix_acl **acl; + unsigned int *aclcnt; + size_t hdrlen; + int error; + + error = decode_post_op_attr(xdr, result->fattr); + if (unlikely(error)) + goto out; + error = decode_uint32(xdr, &result->mask); + if (unlikely(error)) + goto out; + error = -EINVAL; + if (result->mask & ~(NFS_ACL|NFS_ACLCNT|NFS_DFACL|NFS_DFACLCNT)) + goto out; + + hdrlen = (u8 *)xdr->p - (u8 *)xdr->iov->iov_base; + + acl = NULL; + if (result->mask & NFS_ACL) + acl = &result->acl_access; + aclcnt = NULL; + if (result->mask & NFS_ACLCNT) + aclcnt = &result->acl_access_count; + error = nfsacl_decode(xdr->buf, hdrlen, aclcnt, acl); + if (unlikely(error <= 0)) + goto out; + + acl = NULL; + if (result->mask & NFS_DFACL) + acl = &result->acl_default; + aclcnt = NULL; + if (result->mask & NFS_DFACLCNT) + aclcnt = &result->acl_default_count; + error = nfsacl_decode(xdr->buf, hdrlen + error, aclcnt, acl); + if (unlikely(error <= 0)) + return error; + error = 0; +out: + return error; +} + +static int nfs3_xdr_dec_getacl3res(struct rpc_rqst *req, __be32 *p, + struct nfs3_getaclres *result) +{ + struct xdr_stream xdr; + enum nfs_stat status; + int error; + + xdr_init_decode(&xdr, &req->rq_rcv_buf, p); + error = decode_nfsstat3(&xdr, &status); + if (unlikely(error)) + goto out; + if (status != NFS3_OK) + goto out_default; + error = decode_getacl3resok(&xdr, result); +out: + return error; +out_default: + return nfs_stat_to_errno(status); +} + /* * Decode setacl reply. */ @@ -1645,6 +2990,27 @@ nfs3_xdr_setaclres(struct rpc_rqst *req, __be32 *p, struct nfs_fattr *fattr) xdr_decode_post_op_attr(p, fattr); return 0; } + +static int nfs3_xdr_dec_setacl3res(struct rpc_rqst *req, __be32 *p, + struct nfs_fattr *result) +{ + struct xdr_stream xdr; + enum nfs_stat status; + int error; + + xdr_init_decode(&xdr, &req->rq_rcv_buf, p); + error = decode_nfsstat3(&xdr, &status); + if (unlikely(error)) + goto out; + if (status != NFS3_OK) + goto out_default; + error = decode_post_op_attr(&xdr, result); +out: + return error; +out_default: + return nfs_stat_to_errno(status); +} + #endif /* CONFIG_NFS_V3_ACL */ #define PROC(proc, argtype, restype, timer) \ diff --git a/include/linux/nfs3.h b/include/linux/nfs3.h index e2ee14fd0083..6ccfe3b641e1 100644 --- a/include/linux/nfs3.h +++ b/include/linux/nfs3.h @@ -13,6 +13,7 @@ #define NFS3_COOKIESIZE 4 #define NFS3_CREATEVERFSIZE 8 #define NFS3_COOKIEVERFSIZE 8 +#define NFS3_WRITEVERFSIZE 8 #define NFS3_FIFO_DEV (-1) #define NFS3MODE_FMT 0170000 #define NFS3MODE_DIR 0040000 -- cgit v1.2.3 From f5fc3c50c99a7df2bf908dfe66f112d35178ee07 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Tue, 14 Dec 2010 14:56:42 +0000 Subject: NFS: Switch in new NFSv3 decoder functions The naming scheme of the new decoder functions, which follows the NFSv4 XDR decoder functions, is slightly different than the scheme used for the old functions. Rename the functions as a separate step to keep the patches clean. Signed-off-by: Chuck Lever Tested-by: J. Bruce Fields Signed-off-by: Trond Myklebust --- fs/nfs/nfs3xdr.c | 64 ++++++++++++++++++++++++++------------------------------ 1 file changed, 30 insertions(+), 34 deletions(-) diff --git a/fs/nfs/nfs3xdr.c b/fs/nfs/nfs3xdr.c index 0f07c6d55131..19c791101928 100644 --- a/fs/nfs/nfs3xdr.c +++ b/fs/nfs/nfs3xdr.c @@ -38,14 +38,10 @@ #define NFS3_path_sz (1+(NFS3_MAXPATHLEN>>2)) #define NFS3_fattr_sz (21) #define NFS3_cookieverf_sz (NFS3_COOKIEVERFSIZE>>2) -#define NFS3_wcc_attr_sz (6) +#define NFS3_wcc_attr_sz (6) #define NFS3_pre_op_attr_sz (1+NFS3_wcc_attr_sz) #define NFS3_post_op_attr_sz (1+NFS3_fattr_sz) -#define NFS3_wcc_data_sz (NFS3_pre_op_attr_sz+NFS3_post_op_attr_sz) -#define NFS3_fsstat_sz -#define NFS3_fsinfo_sz -#define NFS3_pathconf_sz -#define NFS3_entry_sz (NFS3_filename_sz+3) +#define NFS3_wcc_data_sz (NFS3_pre_op_attr_sz+NFS3_post_op_attr_sz) #define NFS3_diropargs_sz (NFS3_fh_sz+NFS3_filename_sz) #define NFS3_getattrargs_sz (NFS3_fh_sz) @@ -66,9 +62,9 @@ #define NFS3_readdirplusargs_sz (NFS3_fh_sz+NFS3_cookieverf_sz+4) #define NFS3_commitargs_sz (NFS3_fh_sz+3) -#define NFS3_attrstat_sz (1+NFS3_fattr_sz) -#define NFS3_wccstat_sz (1+NFS3_wcc_data_sz) -#define NFS3_removeres_sz (NFS3_wccstat_sz) +#define NFS3_getattrres_sz (1+NFS3_fattr_sz) +#define NFS3_setattrres_sz (1+NFS3_wcc_data_sz) +#define NFS3_removeres_sz (NFS3_setattrres_sz) #define NFS3_lookupres_sz (1+NFS3_fh_sz+(2 * NFS3_post_op_attr_sz)) #define NFS3_accessres_sz (1+NFS3_post_op_attr_sz+1) #define NFS3_readlinkres_sz (1+NFS3_post_op_attr_sz+1) @@ -3017,36 +3013,36 @@ out_default: [NFS3PROC_##proc] = { \ .p_proc = NFS3PROC_##proc, \ .p_encode = (kxdrproc_t)nfs3_xdr_enc_##argtype##3args, \ - .p_decode = (kxdrproc_t) nfs3_xdr_##restype, \ + .p_decode = (kxdrproc_t)nfs3_xdr_dec_##restype##3res, \ .p_arglen = NFS3_##argtype##args_sz, \ - .p_replen = NFS3_##restype##_sz, \ + .p_replen = NFS3_##restype##res_sz, \ .p_timer = timer, \ .p_statidx = NFS3PROC_##proc, \ .p_name = #proc, \ } struct rpc_procinfo nfs3_procedures[] = { - PROC(GETATTR, getattr, attrstat, 1), - PROC(SETATTR, setattr, wccstat, 0), - PROC(LOOKUP, lookup, lookupres, 2), - PROC(ACCESS, access, accessres, 1), - PROC(READLINK, readlink, readlinkres, 3), - PROC(READ, read, readres, 3), - PROC(WRITE, write, writeres, 4), - PROC(CREATE, create, createres, 0), - PROC(MKDIR, mkdir, createres, 0), - PROC(SYMLINK, symlink, createres, 0), - PROC(MKNOD, mknod, createres, 0), - PROC(REMOVE, remove, removeres, 0), - PROC(RMDIR, lookup, wccstat, 0), - PROC(RENAME, rename, renameres, 0), - PROC(LINK, link, linkres, 0), - PROC(READDIR, readdir, readdirres, 3), - PROC(READDIRPLUS, readdirplus, readdirres, 3), - PROC(FSSTAT, getattr, fsstatres, 0), - PROC(FSINFO, getattr, fsinfores, 0), - PROC(PATHCONF, getattr, pathconfres, 0), - PROC(COMMIT, commit, commitres, 5), + PROC(GETATTR, getattr, getattr, 1), + PROC(SETATTR, setattr, setattr, 0), + PROC(LOOKUP, lookup, lookup, 2), + PROC(ACCESS, access, access, 1), + PROC(READLINK, readlink, readlink, 3), + PROC(READ, read, read, 3), + PROC(WRITE, write, write, 4), + PROC(CREATE, create, create, 0), + PROC(MKDIR, mkdir, create, 0), + PROC(SYMLINK, symlink, create, 0), + PROC(MKNOD, mknod, create, 0), + PROC(REMOVE, remove, remove, 0), + PROC(RMDIR, lookup, setattr, 0), + PROC(RENAME, rename, rename, 0), + PROC(LINK, link, link, 0), + PROC(READDIR, readdir, readdir, 3), + PROC(READDIRPLUS, readdirplus, readdir, 3), + PROC(FSSTAT, getattr, fsstat, 0), + PROC(FSINFO, getattr, fsinfo, 0), + PROC(PATHCONF, getattr, pathconf, 0), + PROC(COMMIT, commit, commit, 5), }; struct rpc_version nfs_version3 = { @@ -3060,7 +3056,7 @@ static struct rpc_procinfo nfs3_acl_procedures[] = { [ACLPROC3_GETACL] = { .p_proc = ACLPROC3_GETACL, .p_encode = (kxdrproc_t)nfs3_xdr_enc_getacl3args, - .p_decode = (kxdrproc_t) nfs3_xdr_getaclres, + .p_decode = (kxdrproc_t)nfs3_xdr_dec_getacl3res, .p_arglen = ACL3_getaclargs_sz, .p_replen = ACL3_getaclres_sz, .p_timer = 1, @@ -3069,7 +3065,7 @@ static struct rpc_procinfo nfs3_acl_procedures[] = { [ACLPROC3_SETACL] = { .p_proc = ACLPROC3_SETACL, .p_encode = (kxdrproc_t)nfs3_xdr_enc_setacl3args, - .p_decode = (kxdrproc_t) nfs3_xdr_setaclres, + .p_decode = (kxdrproc_t)nfs3_xdr_dec_setacl3res, .p_arglen = ACL3_setaclargs_sz, .p_replen = ACL3_setaclres_sz, .p_timer = 0, -- cgit v1.2.3 From b2cdd9c9c95e0e389a8b75fe25f266fc5267bbb6 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Tue, 14 Dec 2010 14:56:52 +0000 Subject: NFS: Remove unused old NFSv3 decoder functions Clean up. Remove unused legacy result decoder functions, and any now unused decoder helper functions. Signed-off-by: Chuck Lever Tested-by: J. Bruce Fields Signed-off-by: Trond Myklebust --- fs/nfs/nfs3xdr.c | 512 +------------------------------------------------------ 1 file changed, 4 insertions(+), 508 deletions(-) diff --git a/fs/nfs/nfs3xdr.c b/fs/nfs/nfs3xdr.c index 19c791101928..586587f42fc9 100644 --- a/fs/nfs/nfs3xdr.c +++ b/fs/nfs/nfs3xdr.c @@ -129,38 +129,6 @@ static void print_overflow_msg(const char *func, const struct xdr_stream *xdr) /* * Common NFS XDR functions as inlines */ -static inline __be32 * -xdr_decode_fhandle(__be32 *p, struct nfs_fh *fh) -{ - if ((fh->size = ntohl(*p++)) <= NFS3_FHSIZE) { - memcpy(fh->data, p, fh->size); - return p + XDR_QUADLEN(fh->size); - } - return NULL; -} - -static inline __be32 * -xdr_decode_fhandle_stream(struct xdr_stream *xdr, struct nfs_fh *fh) -{ - __be32 *p; - p = xdr_inline_decode(xdr, 4); - if (unlikely(!p)) - goto out_overflow; - fh->size = ntohl(*p++); - - if (fh->size <= NFS3_FHSIZE) { - p = xdr_inline_decode(xdr, fh->size); - if (unlikely(!p)) - goto out_overflow; - memcpy(fh->data, p, fh->size); - return p + XDR_QUADLEN(fh->size); - } - return NULL; - -out_overflow: - print_overflow_msg(__func__, xdr); - return ERR_PTR(-EIO); -} /* * Encode/decode time. @@ -221,51 +189,6 @@ xdr_decode_wcc_attr(__be32 *p, struct nfs_fattr *fattr) return p; } -static inline __be32 * -xdr_decode_post_op_attr(__be32 *p, struct nfs_fattr *fattr) -{ - if (*p++) - p = xdr_decode_fattr(p, fattr); - return p; -} - -static inline __be32 * -xdr_decode_post_op_attr_stream(struct xdr_stream *xdr, struct nfs_fattr *fattr) -{ - __be32 *p; - - p = xdr_inline_decode(xdr, 4); - if (unlikely(!p)) - goto out_overflow; - if (ntohl(*p++)) { - p = xdr_inline_decode(xdr, 84); - if (unlikely(!p)) - goto out_overflow; - p = xdr_decode_fattr(p, fattr); - } - return p; -out_overflow: - print_overflow_msg(__func__, xdr); - return ERR_PTR(-EIO); -} - -static inline __be32 * -xdr_decode_pre_op_attr(__be32 *p, struct nfs_fattr *fattr) -{ - if (*p++) - return xdr_decode_wcc_attr(p, fattr); - return p; -} - - -static inline __be32 * -xdr_decode_wcc_data(__be32 *p, struct nfs_fattr *fattr) -{ - p = xdr_decode_pre_op_attr(p, fattr); - return xdr_decode_post_op_attr(p, fattr); -} - - /* * Encode/decode NFSv3 basic data types * @@ -1403,52 +1326,6 @@ static int nfs3_xdr_enc_readdirplus3args(struct rpc_rqst *req, __be32 *p, return 0; } -/* - * Decode the result of a readdir call. - * We just check for syntactical correctness. - */ -static int -nfs3_xdr_readdirres(struct rpc_rqst *req, __be32 *p, struct nfs3_readdirres *res) -{ - struct xdr_buf *rcvbuf = &req->rq_rcv_buf; - struct kvec *iov = rcvbuf->head; - struct page **page; - size_t hdrlen; - u32 recvd, pglen; - int status; - - status = ntohl(*p++); - /* Decode post_op_attrs */ - p = xdr_decode_post_op_attr(p, res->dir_attr); - if (status) - return nfs_stat_to_errno(status); - /* Decode verifier cookie */ - if (res->verf) { - res->verf[0] = *p++; - res->verf[1] = *p++; - } else { - p += 2; - } - - hdrlen = (u8 *) p - (u8 *) iov->iov_base; - if (iov->iov_len < hdrlen) { - dprintk("NFS: READDIR reply header overflowed:" - "length %Zu > %Zu\n", hdrlen, iov->iov_len); - return -errno_NFSERR_IO; - } else if (iov->iov_len != hdrlen) { - dprintk("NFS: READDIR header is short. iovec will be shifted.\n"); - xdr_shift_buf(rcvbuf, iov->iov_len - hdrlen); - } - - pglen = rcvbuf->page_len; - recvd = rcvbuf->len - hdrlen; - if (pglen > recvd) - pglen = recvd; - page = rcvbuf->pages; - - return pglen; -} - /* * 3.3.21 COMMIT3args * @@ -1526,22 +1403,11 @@ static int nfs3_xdr_enc_setacl3args(struct rpc_rqst *req, __be32 *p, #endif /* CONFIG_NFS_V3_ACL */ /* - * NFS XDR decode functions - */ - -/* - * Decode attrstat reply. + * NFSv3 XDR decode functions + * + * NFSv3 result types are defined in section 3.3 of RFC 1813: + * "NFS Version 3 Protocol Specification". */ -static int -nfs3_xdr_attrstat(struct rpc_rqst *req, __be32 *p, struct nfs_fattr *fattr) -{ - int status; - - if ((status = ntohl(*p++))) - return nfs_stat_to_errno(status); - xdr_decode_fattr(p, fattr); - return 0; -} /* * 3.3.1 GETATTR3res @@ -1577,21 +1443,6 @@ out_default: return nfs_stat_to_errno(status); } -/* - * Decode status+wcc_data reply - * SATTR, REMOVE, RMDIR - */ -static int -nfs3_xdr_wccstat(struct rpc_rqst *req, __be32 *p, struct nfs_fattr *fattr) -{ - int status; - - if ((status = ntohl(*p++))) - status = nfs_stat_to_errno(status); - xdr_decode_wcc_data(p, fattr); - return status; -} - /* * 3.3.2 SETATTR3res * @@ -1632,31 +1483,6 @@ out_status: return nfs_stat_to_errno(status); } -static int -nfs3_xdr_removeres(struct rpc_rqst *req, __be32 *p, struct nfs_removeres *res) -{ - return nfs3_xdr_wccstat(req, p, res->dir_attr); -} - -/* - * Decode LOOKUP reply - */ -static int -nfs3_xdr_lookupres(struct rpc_rqst *req, __be32 *p, struct nfs3_diropres *res) -{ - int status; - - if ((status = ntohl(*p++))) { - status = nfs_stat_to_errno(status); - } else { - if (!(p = xdr_decode_fhandle(p, res->fh))) - return -errno_NFSERR_IO; - p = xdr_decode_post_op_attr(p, res->fattr); - } - xdr_decode_post_op_attr(p, res->dir_attr); - return status; -} - /* * 3.3.3 LOOKUP3res * @@ -1706,21 +1532,6 @@ out_default: return nfs_stat_to_errno(status); } -/* - * Decode ACCESS reply - */ -static int -nfs3_xdr_accessres(struct rpc_rqst *req, __be32 *p, struct nfs3_accessres *res) -{ - int status = ntohl(*p++); - - p = xdr_decode_post_op_attr(p, res->fattr); - if (status) - return nfs_stat_to_errno(status); - res->access = ntohl(*p++); - return 0; -} - /* * 3.3.4 ACCESS3res * @@ -1763,52 +1574,6 @@ out_default: return nfs_stat_to_errno(status); } -/* - * Decode READLINK reply - */ -static int -nfs3_xdr_readlinkres(struct rpc_rqst *req, __be32 *p, struct nfs_fattr *fattr) -{ - struct xdr_buf *rcvbuf = &req->rq_rcv_buf; - struct kvec *iov = rcvbuf->head; - size_t hdrlen; - u32 len, recvd; - int status; - - status = ntohl(*p++); - p = xdr_decode_post_op_attr(p, fattr); - - if (status != 0) - return nfs_stat_to_errno(status); - - /* Convert length of symlink */ - len = ntohl(*p++); - if (len >= rcvbuf->page_len) { - dprintk("nfs: server returned giant symlink!\n"); - return -ENAMETOOLONG; - } - - hdrlen = (u8 *) p - (u8 *) iov->iov_base; - if (iov->iov_len < hdrlen) { - dprintk("NFS: READLINK reply header overflowed:" - "length %Zu > %Zu\n", hdrlen, iov->iov_len); - return -errno_NFSERR_IO; - } else if (iov->iov_len != hdrlen) { - dprintk("NFS: READLINK header is short. " - "iovec will be shifted.\n"); - xdr_shift_buf(rcvbuf, iov->iov_len - hdrlen); - } - recvd = req->rq_rcv_buf.len - hdrlen; - if (recvd < len) { - dprintk("NFS: server cheating in readlink reply: " - "count %u > recvd %u\n", len, recvd); - return -EIO; - } - - xdr_terminate_string(rcvbuf, len); - return 0; -} - /* * 3.3.5 READLINK3res * @@ -1851,59 +1616,6 @@ out_default: return nfs_stat_to_errno(status); } -/* - * Decode READ reply - */ -static int -nfs3_xdr_readres(struct rpc_rqst *req, __be32 *p, struct nfs_readres *res) -{ - struct kvec *iov = req->rq_rcv_buf.head; - size_t hdrlen; - u32 count, ocount, recvd; - int status; - - status = ntohl(*p++); - p = xdr_decode_post_op_attr(p, res->fattr); - - if (status != 0) - return nfs_stat_to_errno(status); - - /* Decode reply count and EOF flag. NFSv3 is somewhat redundant - * in that it puts the count both in the res struct and in the - * opaque data count. */ - count = ntohl(*p++); - res->eof = ntohl(*p++); - ocount = ntohl(*p++); - - if (ocount != count) { - dprintk("NFS: READ count doesn't match RPC opaque count.\n"); - return -errno_NFSERR_IO; - } - - hdrlen = (u8 *) p - (u8 *) iov->iov_base; - if (iov->iov_len < hdrlen) { - dprintk("NFS: READ reply header overflowed:" - "length %Zu > %Zu\n", hdrlen, iov->iov_len); - return -errno_NFSERR_IO; - } else if (iov->iov_len != hdrlen) { - dprintk("NFS: READ header is short. iovec will be shifted.\n"); - xdr_shift_buf(&req->rq_rcv_buf, iov->iov_len - hdrlen); - } - - recvd = req->rq_rcv_buf.len - hdrlen; - if (count > recvd) { - dprintk("NFS: server cheating in read reply: " - "count %u > recvd %u\n", count, recvd); - count = recvd; - res->eof = 0; - } - - if (count < res->count) - res->count = count; - - return count; -} - /* * 3.3.6 READ3res * @@ -1988,28 +1700,6 @@ out_status: return nfs_stat_to_errno(status); } -/* - * Decode WRITE response - */ -static int -nfs3_xdr_writeres(struct rpc_rqst *req, __be32 *p, struct nfs_writeres *res) -{ - int status; - - status = ntohl(*p++); - p = xdr_decode_wcc_data(p, res->fattr); - - if (status != 0) - return nfs_stat_to_errno(status); - - res->count = ntohl(*p++); - res->verf->committed = (enum nfs3_stable_how)ntohl(*p++); - res->verf->verifier[0] = *p++; - res->verf->verifier[1] = *p++; - - return res->count; -} - /* * 3.3.7 WRITE3res * @@ -2082,33 +1772,6 @@ out_status: return nfs_stat_to_errno(status); } -/* - * Decode a CREATE response - */ -static int -nfs3_xdr_createres(struct rpc_rqst *req, __be32 *p, struct nfs3_diropres *res) -{ - int status; - - status = ntohl(*p++); - if (status == 0) { - if (*p++) { - if (!(p = xdr_decode_fhandle(p, res->fh))) - return -errno_NFSERR_IO; - p = xdr_decode_post_op_attr(p, res->fattr); - } else { - memset(res->fh, 0, sizeof(*res->fh)); - /* Do decode post_op_attr but set it to NULL */ - p = xdr_decode_post_op_attr(p, res->fattr); - res->fattr->valid = 0; - } - } else { - status = nfs_stat_to_errno(status); - } - p = xdr_decode_wcc_data(p, res->dir_attr); - return status; -} - /* * 3.3.8 CREATE3res * @@ -2214,21 +1877,6 @@ out_status: return nfs_stat_to_errno(status); } -/* - * Decode RENAME reply - */ -static int -nfs3_xdr_renameres(struct rpc_rqst *req, __be32 *p, struct nfs_renameres *res) -{ - int status; - - if ((status = ntohl(*p++)) != 0) - status = nfs_stat_to_errno(status); - p = xdr_decode_wcc_data(p, res->old_fattr); - p = xdr_decode_wcc_data(p, res->new_fattr); - return status; -} - /* * 3.3.14 RENAME3res * @@ -2274,21 +1922,6 @@ out_status: return nfs_stat_to_errno(status); } -/* - * Decode LINK reply - */ -static int -nfs3_xdr_linkres(struct rpc_rqst *req, __be32 *p, struct nfs3_linkres *res) -{ - int status; - - if ((status = ntohl(*p++)) != 0) - status = nfs_stat_to_errno(status); - p = xdr_decode_post_op_attr(p, res->fattr); - p = xdr_decode_wcc_data(p, res->dir_attr); - return status; -} - /* * 3.3.15 LINK3res * @@ -2532,31 +2165,6 @@ out_default: return nfs_stat_to_errno(status); } -/* - * Decode FSSTAT reply - */ -static int -nfs3_xdr_fsstatres(struct rpc_rqst *req, __be32 *p, struct nfs_fsstat *res) -{ - int status; - - status = ntohl(*p++); - - p = xdr_decode_post_op_attr(p, res->fattr); - if (status != 0) - return nfs_stat_to_errno(status); - - p = xdr_decode_hyper(p, &res->tbytes); - p = xdr_decode_hyper(p, &res->fbytes); - p = xdr_decode_hyper(p, &res->abytes); - p = xdr_decode_hyper(p, &res->tfiles); - p = xdr_decode_hyper(p, &res->ffiles); - p = xdr_decode_hyper(p, &res->afiles); - - /* ignore invarsec */ - return 0; -} - /* * 3.3.18 FSSTAT3res * @@ -2626,35 +2234,6 @@ out_status: return nfs_stat_to_errno(status); } -/* - * Decode FSINFO reply - */ -static int -nfs3_xdr_fsinfores(struct rpc_rqst *req, __be32 *p, struct nfs_fsinfo *res) -{ - int status; - - status = ntohl(*p++); - - p = xdr_decode_post_op_attr(p, res->fattr); - if (status != 0) - return nfs_stat_to_errno(status); - - res->rtmax = ntohl(*p++); - res->rtpref = ntohl(*p++); - res->rtmult = ntohl(*p++); - res->wtmax = ntohl(*p++); - res->wtpref = ntohl(*p++); - res->wtmult = ntohl(*p++); - res->dtpref = ntohl(*p++); - p = xdr_decode_hyper(p, &res->maxfilesize); - p = xdr_decode_time3(p, &res->time_delta); - - /* ignore properties */ - res->lease_time = 0; - return 0; -} - /* * 3.3.19 FSINFO3res * @@ -2732,26 +2311,6 @@ out_status: return nfs_stat_to_errno(status); } -/* - * Decode PATHCONF reply - */ -static int -nfs3_xdr_pathconfres(struct rpc_rqst *req, __be32 *p, struct nfs_pathconf *res) -{ - int status; - - status = ntohl(*p++); - - p = xdr_decode_post_op_attr(p, res->fattr); - if (status != 0) - return nfs_stat_to_errno(status); - res->max_link = ntohl(*p++); - res->max_namelen = ntohl(*p++); - - /* ignore remaining fields */ - return 0; -} - /* * 3.3.20 PATHCONF3res * @@ -2816,24 +2375,6 @@ out_status: return nfs_stat_to_errno(status); } -/* - * Decode COMMIT reply - */ -static int -nfs3_xdr_commitres(struct rpc_rqst *req, __be32 *p, struct nfs_writeres *res) -{ - int status; - - status = ntohl(*p++); - p = xdr_decode_wcc_data(p, res->fattr); - if (status != 0) - return nfs_stat_to_errno(status); - - res->verf->verifier[0] = *p++; - res->verf->verifier[1] = *p++; - return 0; -} - /* * 3.3.21 COMMIT3res * @@ -2877,37 +2418,6 @@ out_status: } #ifdef CONFIG_NFS_V3_ACL -/* - * Decode GETACL reply - */ -static int -nfs3_xdr_getaclres(struct rpc_rqst *req, __be32 *p, - struct nfs3_getaclres *res) -{ - struct xdr_buf *buf = &req->rq_rcv_buf; - int status = ntohl(*p++); - struct posix_acl **acl; - unsigned int *aclcnt; - int err, base; - - if (status != 0) - return nfs_stat_to_errno(status); - p = xdr_decode_post_op_attr(p, res->fattr); - res->mask = ntohl(*p++); - if (res->mask & ~(NFS_ACL|NFS_ACLCNT|NFS_DFACL|NFS_DFACLCNT)) - return -EINVAL; - base = (char *)p - (char *)req->rq_rcv_buf.head->iov_base; - - acl = (res->mask & NFS_ACL) ? &res->acl_access : NULL; - aclcnt = (res->mask & NFS_ACLCNT) ? &res->acl_access_count : NULL; - err = nfsacl_decode(buf, base, aclcnt, acl); - - acl = (res->mask & NFS_DFACL) ? &res->acl_default : NULL; - aclcnt = (res->mask & NFS_DFACLCNT) ? &res->acl_default_count : NULL; - if (err > 0) - err = nfsacl_decode(buf, base + err, aclcnt, acl); - return (err > 0) ? 0 : err; -} static inline int decode_getacl3resok(struct xdr_stream *xdr, struct nfs3_getaclres *result) @@ -2973,20 +2483,6 @@ out_default: return nfs_stat_to_errno(status); } -/* - * Decode setacl reply. - */ -static int -nfs3_xdr_setaclres(struct rpc_rqst *req, __be32 *p, struct nfs_fattr *fattr) -{ - int status = ntohl(*p++); - - if (status) - return nfs_stat_to_errno(status); - xdr_decode_post_op_attr(p, fattr); - return 0; -} - static int nfs3_xdr_dec_setacl3res(struct rpc_rqst *req, __be32 *p, struct nfs_fattr *result) { -- cgit v1.2.3 From f6048709391336cf27fb5c1cfca8e792103e5a73 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Tue, 14 Dec 2010 14:57:02 +0000 Subject: NFS: Move and update xdr_decode_foo() functions that we're keeping Clean up. Move the timestamp decoder to match the placement and naming conventions of the other helpers. Fold xdr_decode_fattr() into decode_fattr3(), which is now it's only user. Fold xdr_decode_wcc_attr() into decode_wcc_attr(), which is now it's only user. Signed-off-by: Chuck Lever Tested-by: J. Bruce Fields Signed-off-by: Trond Myklebust --- fs/nfs/nfs3xdr.c | 136 +++++++++++++++++++++++++++---------------------------- 1 file changed, 67 insertions(+), 69 deletions(-) diff --git a/fs/nfs/nfs3xdr.c b/fs/nfs/nfs3xdr.c index 586587f42fc9..c97d00fe849a 100644 --- a/fs/nfs/nfs3xdr.c +++ b/fs/nfs/nfs3xdr.c @@ -126,69 +126,6 @@ static void print_overflow_msg(const char *func, const struct xdr_stream *xdr) } -/* - * Common NFS XDR functions as inlines - */ - -/* - * Encode/decode time. - */ -static inline __be32 * -xdr_decode_time3(__be32 *p, struct timespec *timep) -{ - timep->tv_sec = ntohl(*p++); - timep->tv_nsec = ntohl(*p++); - return p; -} - -static __be32 * -xdr_decode_fattr(__be32 *p, struct nfs_fattr *fattr) -{ - unsigned int type, major, minor; - umode_t fmode; - - type = ntohl(*p++); - if (type > NF3FIFO) - type = NF3NON; - fmode = nfs_type2fmt[type]; - fattr->mode = (ntohl(*p++) & ~S_IFMT) | fmode; - fattr->nlink = ntohl(*p++); - fattr->uid = ntohl(*p++); - fattr->gid = ntohl(*p++); - p = xdr_decode_hyper(p, &fattr->size); - p = xdr_decode_hyper(p, &fattr->du.nfs3.used); - - /* Turn remote device info into Linux-specific dev_t */ - major = ntohl(*p++); - minor = ntohl(*p++); - fattr->rdev = MKDEV(major, minor); - if (MAJOR(fattr->rdev) != major || MINOR(fattr->rdev) != minor) - fattr->rdev = 0; - - p = xdr_decode_hyper(p, &fattr->fsid.major); - fattr->fsid.minor = 0; - p = xdr_decode_hyper(p, &fattr->fileid); - p = xdr_decode_time3(p, &fattr->atime); - p = xdr_decode_time3(p, &fattr->mtime); - p = xdr_decode_time3(p, &fattr->ctime); - - /* Update the mode bits */ - fattr->valid |= NFS_ATTR_FATTR_V3; - return p; -} - -static inline __be32 * -xdr_decode_wcc_attr(__be32 *p, struct nfs_fattr *fattr) -{ - p = xdr_decode_hyper(p, &fattr->pre_size); - p = xdr_decode_time3(p, &fattr->pre_mtime); - p = xdr_decode_time3(p, &fattr->pre_ctime); - fattr->valid |= NFS_ATTR_FATTR_PRESIZE - | NFS_ATTR_FATTR_PREMTIME - | NFS_ATTR_FATTR_PRECTIME; - return p; -} - /* * Encode/decode NFSv3 basic data types * @@ -239,6 +176,11 @@ out_overflow: * * typedef uint64 fileid3; */ +static __be32 *xdr_decode_fileid3(__be32 *p, u64 *fileid) +{ + return xdr_decode_hyper(p, fileid); +} + static int decode_fileid3(struct xdr_stream *xdr, u64 *fileid) { return decode_uint64(xdr, fileid); @@ -452,6 +394,17 @@ static void encode_ftype3(struct xdr_stream *xdr, const u32 type) encode_uint32(xdr, type); } +static __be32 *xdr_decode_ftype3(__be32 *p, umode_t *mode) +{ + u32 type; + + type = be32_to_cpup(p++); + if (type > NF3FIFO) + type = NF3NON; + *mode = nfs_type2fmt[type]; + return p; +} + /* * specdata3 * @@ -469,6 +422,18 @@ static void encode_specdata3(struct xdr_stream *xdr, const dev_t rdev) *p = cpu_to_be32(MINOR(rdev)); } +static __be32 *xdr_decode_specdata3(__be32 *p, dev_t *rdev) +{ + unsigned int major, minor; + + major = be32_to_cpup(p++); + minor = be32_to_cpup(p++); + *rdev = MKDEV(major, minor); + if (MAJOR(*rdev) != major || MINOR(*rdev) != minor) + *rdev = 0; + return p; +} + /* * nfs_fh3 * @@ -530,6 +495,13 @@ static __be32 *xdr_encode_nfstime3(__be32 *p, const struct timespec *timep) return p; } +static __be32 *xdr_decode_nfstime3(__be32 *p, struct timespec *timep) +{ + timep->tv_sec = be32_to_cpup(p++); + timep->tv_nsec = be32_to_cpup(p++); + return p; +} + /* * sattr3 * @@ -678,12 +650,33 @@ static void encode_sattr3(struct xdr_stream *xdr, const struct iattr *attr) */ static int decode_fattr3(struct xdr_stream *xdr, struct nfs_fattr *fattr) { + umode_t fmode; __be32 *p; p = xdr_inline_decode(xdr, NFS3_fattr_sz << 2); if (unlikely(p == NULL)) goto out_overflow; - xdr_decode_fattr(p, fattr); + + p = xdr_decode_ftype3(p, &fmode); + + fattr->mode = (be32_to_cpup(p++) & ~S_IFMT) | fmode; + fattr->nlink = be32_to_cpup(p++); + fattr->uid = be32_to_cpup(p++); + fattr->gid = be32_to_cpup(p++); + + p = xdr_decode_size3(p, &fattr->size); + p = xdr_decode_size3(p, &fattr->du.nfs3.used); + p = xdr_decode_specdata3(p, &fattr->rdev); + + p = xdr_decode_hyper(p, &fattr->fsid.major); + fattr->fsid.minor = 0; + + p = xdr_decode_fileid3(p, &fattr->fileid); + p = xdr_decode_nfstime3(p, &fattr->atime); + p = xdr_decode_nfstime3(p, &fattr->mtime); + xdr_decode_nfstime3(p, &fattr->ctime); + + fattr->valid |= NFS_ATTR_FATTR_V3; return 0; out_overflow: print_overflow_msg(__func__, xdr); @@ -730,7 +723,15 @@ static int decode_wcc_attr(struct xdr_stream *xdr, struct nfs_fattr *fattr) p = xdr_inline_decode(xdr, NFS3_wcc_attr_sz << 2); if (unlikely(p == NULL)) goto out_overflow; - xdr_decode_wcc_attr(p, fattr); + + fattr->valid |= NFS_ATTR_FATTR_PRESIZE + | NFS_ATTR_FATTR_PREMTIME + | NFS_ATTR_FATTR_PRECTIME; + + p = xdr_decode_size3(p, &fattr->pre_size); + p = xdr_decode_nfstime3(p, &fattr->pre_mtime); + xdr_decode_nfstime3(p, &fattr->pre_ctime); + return 0; out_overflow: print_overflow_msg(__func__, xdr); @@ -1009,10 +1010,7 @@ static void encode_write3args(struct xdr_stream *xdr, p = xdr_reserve_space(xdr, 8 + 4 + 4 + 4); p = xdr_encode_hyper(p, args->offset); *p++ = cpu_to_be32(args->count); - - BUG_ON(args->stable > NFS_FILE_SYNC); *p++ = cpu_to_be32(args->stable); - *p = cpu_to_be32(args->count); xdr_write_pages(xdr, args->pages, args->pgbase, args->count); } @@ -2278,7 +2276,7 @@ static int decode_fsinfo3resok(struct xdr_stream *xdr, result->wtmult = be32_to_cpup(p++); result->dtpref = be32_to_cpup(p++); p = xdr_decode_size3(p, &result->maxfilesize); - xdr_decode_time3(p, &result->time_delta); + xdr_decode_nfstime3(p, &result->time_delta); /* ignore properties */ result->lease_time = 0; -- cgit v1.2.3 From 3460f29a27344db8c7af62cafdb961286ef0b6cd Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Tue, 14 Dec 2010 14:57:12 +0000 Subject: lockd: Introduce new-style XDR functions for NLMv4 We'd like to prevent local buffer overflows caused by malicious or broken servers. New xdr_stream style decoders can do that. For efficiency, we also want to be able to pass xdr_streams from call_encode() to all XDR encoding functions, rather than building an xdr_stream in every XDR encoding function in the kernel. Same idea as the NLM v3 XDR overhaul. Signed-off-by: Chuck Lever Tested-by: J. Bruce Fields Signed-off-by: Trond Myklebust --- fs/lockd/Makefile | 2 +- fs/lockd/clnt4xdr.c | 621 ++++++++++++++++++++++++++++++++++++++++++++++++++++ fs/lockd/xdr4.c | 255 --------------------- 3 files changed, 622 insertions(+), 256 deletions(-) create mode 100644 fs/lockd/clnt4xdr.c diff --git a/fs/lockd/Makefile b/fs/lockd/Makefile index d0488b3bd00b..ca58d64374ca 100644 --- a/fs/lockd/Makefile +++ b/fs/lockd/Makefile @@ -6,5 +6,5 @@ obj-$(CONFIG_LOCKD) += lockd.o lockd-objs-y := clntlock.o clntproc.o clntxdr.o host.o svc.o svclock.o \ svcshare.o svcproc.o svcsubs.o mon.o xdr.o grace.o -lockd-objs-$(CONFIG_LOCKD_V4) += xdr4.o svc4proc.o +lockd-objs-$(CONFIG_LOCKD_V4) += clnt4xdr.o xdr4.o svc4proc.o lockd-objs := $(lockd-objs-y) diff --git a/fs/lockd/clnt4xdr.c b/fs/lockd/clnt4xdr.c new file mode 100644 index 000000000000..1a1c3e21ed2c --- /dev/null +++ b/fs/lockd/clnt4xdr.c @@ -0,0 +1,621 @@ +/* + * linux/fs/lockd/clnt4xdr.c + * + * XDR functions to encode/decode NLM version 4 RPC arguments and results. + * + * NLM client-side only. + * + * Copyright (C) 2010, Oracle. All rights reserved. + */ + +#include +#include +#include +#include +#include + +#define NLMDBG_FACILITY NLMDBG_XDR + +#if (NLMCLNT_OHSIZE > XDR_MAX_NETOBJ) +# error "NLM host name cannot be larger than XDR_MAX_NETOBJ!" +#endif + +#if (NLMCLNT_OHSIZE > NLM_MAXSTRLEN) +# error "NLM host name cannot be larger than NLM's maximum string length!" +#endif + +/* + * Declare the space requirements for NLM arguments and replies as + * number of 32bit-words + */ +#define NLM4_void_sz (0) +#define NLM4_cookie_sz (1+(NLM_MAXCOOKIELEN>>2)) +#define NLM4_caller_sz (1+(NLMCLNT_OHSIZE>>2)) +#define NLM4_owner_sz (1+(NLMCLNT_OHSIZE>>2)) +#define NLM4_fhandle_sz (1+(NFS3_FHSIZE>>2)) +#define NLM4_lock_sz (5+NLM4_caller_sz+NLM4_owner_sz+NLM4_fhandle_sz) +#define NLM4_holder_sz (6+NLM4_owner_sz) + +#define NLM4_testargs_sz (NLM4_cookie_sz+1+NLM4_lock_sz) +#define NLM4_lockargs_sz (NLM4_cookie_sz+4+NLM4_lock_sz) +#define NLM4_cancargs_sz (NLM4_cookie_sz+2+NLM4_lock_sz) +#define NLM4_unlockargs_sz (NLM4_cookie_sz+NLM4_lock_sz) + +#define NLM4_testres_sz (NLM4_cookie_sz+1+NLM4_holder_sz) +#define NLM4_res_sz (NLM4_cookie_sz+1) +#define NLM4_norep_sz (0) + + +static s64 loff_t_to_s64(loff_t offset) +{ + s64 res; + + if (offset >= NLM4_OFFSET_MAX) + res = NLM4_OFFSET_MAX; + else if (offset <= -NLM4_OFFSET_MAX) + res = -NLM4_OFFSET_MAX; + else + res = offset; + return res; +} + +static void nlm4_compute_offsets(const struct nlm_lock *lock, + u64 *l_offset, u64 *l_len) +{ + const struct file_lock *fl = &lock->fl; + + BUG_ON(fl->fl_start > NLM4_OFFSET_MAX); + BUG_ON(fl->fl_end > NLM4_OFFSET_MAX && + fl->fl_end != OFFSET_MAX); + + *l_offset = loff_t_to_s64(fl->fl_start); + if (fl->fl_end == OFFSET_MAX) + *l_len = 0; + else + *l_len = loff_t_to_s64(fl->fl_end - fl->fl_start + 1); +} + +/* + * Handle decode buffer overflows out-of-line. + */ +static void print_overflow_msg(const char *func, const struct xdr_stream *xdr) +{ + dprintk("lockd: %s prematurely hit the end of our receive buffer. " + "Remaining buffer length is %tu words.\n", + func, xdr->end - xdr->p); +} + + +/* + * Encode/decode NLMv4 basic data types + * + * Basic NLMv4 data types are defined in Appendix II, section 6.1.4 + * of RFC 1813: "NFS Version 3 Protocol Specification" and in Chapter + * 10 of X/Open's "Protocols for Interworking: XNFS, Version 3W". + * + * Not all basic data types have their own encoding and decoding + * functions. For run-time efficiency, some data types are encoded + * or decoded inline. + */ + +static void encode_bool(struct xdr_stream *xdr, const int value) +{ + __be32 *p; + + p = xdr_reserve_space(xdr, 4); + *p = value ? xdr_one : xdr_zero; +} + +static void encode_int32(struct xdr_stream *xdr, const s32 value) +{ + __be32 *p; + + p = xdr_reserve_space(xdr, 4); + *p = cpu_to_be32(value); +} + +/* + * typedef opaque netobj + */ +static void encode_netobj(struct xdr_stream *xdr, + const u8 *data, const unsigned int length) +{ + __be32 *p; + + BUG_ON(length > XDR_MAX_NETOBJ); + p = xdr_reserve_space(xdr, 4 + length); + xdr_encode_opaque(p, data, length); +} + +static int decode_netobj(struct xdr_stream *xdr, + struct xdr_netobj *obj) +{ + u32 length; + __be32 *p; + + p = xdr_inline_decode(xdr, 4); + if (unlikely(p == NULL)) + goto out_overflow; + length = be32_to_cpup(p++); + if (unlikely(length > XDR_MAX_NETOBJ)) + goto out_size; + obj->len = length; + obj->data = (u8 *)p; + return 0; +out_size: + dprintk("NFS: returned netobj was too long: %u\n", length); + return -EIO; +out_overflow: + print_overflow_msg(__func__, xdr); + return -EIO; +} + +/* + * netobj cookie; + */ +static void encode_cookie(struct xdr_stream *xdr, + const struct nlm_cookie *cookie) +{ + BUG_ON(cookie->len > NLM_MAXCOOKIELEN); + encode_netobj(xdr, (u8 *)&cookie->data, cookie->len); +} + +static int decode_cookie(struct xdr_stream *xdr, + struct nlm_cookie *cookie) +{ + u32 length; + __be32 *p; + + p = xdr_inline_decode(xdr, 4); + if (unlikely(p == NULL)) + goto out_overflow; + length = be32_to_cpup(p++); + /* apparently HPUX can return empty cookies */ + if (length == 0) + goto out_hpux; + if (length > NLM_MAXCOOKIELEN) + goto out_size; + p = xdr_inline_decode(xdr, length); + if (unlikely(p == NULL)) + goto out_overflow; + cookie->len = length; + memcpy(cookie->data, p, length); + return 0; +out_hpux: + cookie->len = 4; + memset(cookie->data, 0, 4); + return 0; +out_size: + dprintk("NFS: returned cookie was too long: %u\n", length); + return -EIO; +out_overflow: + print_overflow_msg(__func__, xdr); + return -EIO; +} + +/* + * netobj fh; + */ +static void encode_fh(struct xdr_stream *xdr, const struct nfs_fh *fh) +{ + BUG_ON(fh->size > NFS3_FHSIZE); + encode_netobj(xdr, (u8 *)&fh->data, fh->size); +} + +/* + * enum nlm4_stats { + * NLM4_GRANTED = 0, + * NLM4_DENIED = 1, + * NLM4_DENIED_NOLOCKS = 2, + * NLM4_BLOCKED = 3, + * NLM4_DENIED_GRACE_PERIOD = 4, + * NLM4_DEADLCK = 5, + * NLM4_ROFS = 6, + * NLM4_STALE_FH = 7, + * NLM4_FBIG = 8, + * NLM4_FAILED = 9 + * }; + * + * struct nlm4_stat { + * nlm4_stats stat; + * }; + * + * NB: we don't swap bytes for the NLM status values. The upper + * layers deal directly with the status value in network byte + * order. + */ +static void encode_nlm4_stat(struct xdr_stream *xdr, + const __be32 stat) +{ + __be32 *p; + + BUG_ON(be32_to_cpu(stat) > NLM_FAILED); + p = xdr_reserve_space(xdr, 4); + *p = stat; +} + +static int decode_nlm4_stat(struct xdr_stream *xdr, __be32 *stat) +{ + __be32 *p; + + p = xdr_inline_decode(xdr, 4); + if (unlikely(p == NULL)) + goto out_overflow; + if (unlikely(*p > nlm4_failed)) + goto out_bad_xdr; + *stat = *p; + return 0; +out_bad_xdr: + dprintk("%s: server returned invalid nlm4_stats value: %u\n", + __func__, be32_to_cpup(p)); + return -EIO; +out_overflow: + print_overflow_msg(__func__, xdr); + return -EIO; +} + +/* + * struct nlm4_holder { + * bool exclusive; + * int32 svid; + * netobj oh; + * uint64 l_offset; + * uint64 l_len; + * }; + */ +static void encode_nlm4_holder(struct xdr_stream *xdr, + const struct nlm_res *result) +{ + const struct nlm_lock *lock = &result->lock; + u64 l_offset, l_len; + __be32 *p; + + encode_bool(xdr, lock->fl.fl_type == F_RDLCK); + encode_int32(xdr, lock->svid); + encode_netobj(xdr, lock->oh.data, lock->oh.len); + + p = xdr_reserve_space(xdr, 4 + 4); + nlm4_compute_offsets(lock, &l_offset, &l_len); + p = xdr_encode_hyper(p, l_offset); + xdr_encode_hyper(p, l_len); +} + +static int decode_nlm4_holder(struct xdr_stream *xdr, struct nlm_res *result) +{ + struct nlm_lock *lock = &result->lock; + struct file_lock *fl = &lock->fl; + u64 l_offset, l_len; + u32 exclusive; + int error; + __be32 *p; + s32 end; + + memset(lock, 0, sizeof(*lock)); + locks_init_lock(fl); + + p = xdr_inline_decode(xdr, 4 + 4); + if (unlikely(p == NULL)) + goto out_overflow; + exclusive = be32_to_cpup(p++); + lock->svid = be32_to_cpup(p); + fl->fl_pid = (pid_t)lock->svid; + + error = decode_netobj(xdr, &lock->oh); + if (unlikely(error)) + goto out; + + p = xdr_inline_decode(xdr, 8 + 8); + if (unlikely(p == NULL)) + goto out_overflow; + + fl->fl_flags = FL_POSIX; + fl->fl_type = exclusive != 0 ? F_WRLCK : F_RDLCK; + p = xdr_decode_hyper(p, &l_offset); + xdr_decode_hyper(p, &l_len); + end = l_offset + l_len - 1; + + fl->fl_start = (loff_t)l_offset; + if (l_len == 0 || end < 0) + fl->fl_end = OFFSET_MAX; + else + fl->fl_end = (loff_t)end; + error = 0; +out: + return error; +out_overflow: + print_overflow_msg(__func__, xdr); + return -EIO; +} + +/* + * string caller_name; + */ +static void encode_caller_name(struct xdr_stream *xdr, const char *name) +{ + /* NB: client-side does not set lock->len */ + u32 length = strlen(name); + __be32 *p; + + BUG_ON(length > NLM_MAXSTRLEN); + p = xdr_reserve_space(xdr, 4 + length); + xdr_encode_opaque(p, name, length); +} + +/* + * struct nlm4_lock { + * string caller_name; + * netobj fh; + * netobj oh; + * int32 svid; + * uint64 l_offset; + * uint64 l_len; + * }; + */ +static void encode_nlm4_lock(struct xdr_stream *xdr, + const struct nlm_lock *lock) +{ + u64 l_offset, l_len; + __be32 *p; + + encode_caller_name(xdr, lock->caller); + encode_fh(xdr, &lock->fh); + encode_netobj(xdr, lock->oh.data, lock->oh.len); + + p = xdr_reserve_space(xdr, 4 + 8 + 8); + *p++ = cpu_to_be32(lock->svid); + + nlm4_compute_offsets(lock, &l_offset, &l_len); + p = xdr_encode_hyper(p, l_offset); + xdr_encode_hyper(p, l_len); +} + + +/* + * NLMv4 XDR encode functions + * + * NLMv4 argument types are defined in Appendix II of RFC 1813: + * "NFS Version 3 Protocol Specification" and Chapter 10 of X/Open's + * "Protocols for Interworking: XNFS, Version 3W". + */ + +/* + * struct nlm4_testargs { + * netobj cookie; + * bool exclusive; + * struct nlm4_lock alock; + * }; + */ +static int nlm4_xdr_enc_testargs(struct rpc_rqst *req, __be32 *p, + const struct nlm_args *args) +{ + const struct nlm_lock *lock = &args->lock; + struct xdr_stream xdr; + + xdr_init_encode(&xdr, &req->rq_snd_buf, p); + encode_cookie(&xdr, &args->cookie); + encode_bool(&xdr, lock->fl.fl_type == F_WRLCK); + encode_nlm4_lock(&xdr, lock); + return 0; +} + +/* + * struct nlm4_lockargs { + * netobj cookie; + * bool block; + * bool exclusive; + * struct nlm4_lock alock; + * bool reclaim; + * int state; + * }; + */ +static int nlm4_xdr_enc_lockargs(struct rpc_rqst *req, __be32 *p, + const struct nlm_args *args) +{ + const struct nlm_lock *lock = &args->lock; + struct xdr_stream xdr; + + xdr_init_encode(&xdr, &req->rq_snd_buf, p); + encode_cookie(&xdr, &args->cookie); + encode_bool(&xdr, args->block); + encode_bool(&xdr, lock->fl.fl_type == F_WRLCK); + encode_nlm4_lock(&xdr, lock); + encode_bool(&xdr, args->reclaim); + encode_int32(&xdr, args->state); + return 0; +} + +/* + * struct nlm4_cancargs { + * netobj cookie; + * bool block; + * bool exclusive; + * struct nlm4_lock alock; + * }; + */ +static int nlm4_xdr_enc_cancargs(struct rpc_rqst *req, __be32 *p, + const struct nlm_args *args) +{ + const struct nlm_lock *lock = &args->lock; + struct xdr_stream xdr; + + xdr_init_encode(&xdr, &req->rq_snd_buf, p); + encode_cookie(&xdr, &args->cookie); + encode_bool(&xdr, args->block); + encode_bool(&xdr, lock->fl.fl_type == F_WRLCK); + encode_nlm4_lock(&xdr, lock); + return 0; +} + +/* + * struct nlm4_unlockargs { + * netobj cookie; + * struct nlm4_lock alock; + * }; + */ +static int nlm4_xdr_enc_unlockargs(struct rpc_rqst *req, __be32 *p, + const struct nlm_args *args) +{ + const struct nlm_lock *lock = &args->lock; + struct xdr_stream xdr; + + xdr_init_encode(&xdr, &req->rq_snd_buf, p); + encode_cookie(&xdr, &args->cookie); + encode_nlm4_lock(&xdr, lock); + return 0; +} + +/* + * struct nlm4_res { + * netobj cookie; + * nlm4_stat stat; + * }; + */ +static int nlm4_xdr_enc_res(struct rpc_rqst *req, __be32 *p, + const struct nlm_res *result) +{ + struct xdr_stream xdr; + + xdr_init_encode(&xdr, &req->rq_snd_buf, p); + encode_cookie(&xdr, &result->cookie); + encode_nlm4_stat(&xdr, result->status); + return 0; +} + +/* + * union nlm4_testrply switch (nlm4_stats stat) { + * case NLM4_DENIED: + * struct nlm4_holder holder; + * default: + * void; + * }; + * + * struct nlm4_testres { + * netobj cookie; + * nlm4_testrply test_stat; + * }; + */ +static int nlm4_xdr_enc_testres(struct rpc_rqst *req, __be32 *p, + const struct nlm_res *result) +{ + struct xdr_stream xdr; + + xdr_init_encode(&xdr, &req->rq_snd_buf, p); + encode_cookie(&xdr, &result->cookie); + encode_nlm4_stat(&xdr, result->status); + if (result->status == nlm_lck_denied) + encode_nlm4_holder(&xdr, result); + return 0; +} + + +/* + * NLMv4 XDR decode functions + * + * NLMv4 argument types are defined in Appendix II of RFC 1813: + * "NFS Version 3 Protocol Specification" and Chapter 10 of X/Open's + * "Protocols for Interworking: XNFS, Version 3W". + */ + +/* + * union nlm4_testrply switch (nlm4_stats stat) { + * case NLM4_DENIED: + * struct nlm4_holder holder; + * default: + * void; + * }; + * + * struct nlm4_testres { + * netobj cookie; + * nlm4_testrply test_stat; + * }; + */ +static int decode_nlm4_testrply(struct xdr_stream *xdr, + struct nlm_res *result) +{ + int error; + + error = decode_nlm4_stat(xdr, &result->status); + if (unlikely(error)) + goto out; + if (result->status == nlm_lck_denied) + error = decode_nlm4_holder(xdr, result); +out: + return error; +} + +static int nlm4_xdr_dec_testres(struct rpc_rqst *req, __be32 *p, + struct nlm_res *result) +{ + struct xdr_stream xdr; + int error; + + xdr_init_decode(&xdr, &req->rq_rcv_buf, p); + error = decode_cookie(&xdr, &result->cookie); + if (unlikely(error)) + goto out; + error = decode_nlm4_testrply(&xdr, result); +out: + return error; +} + +/* + * struct nlm4_res { + * netobj cookie; + * nlm4_stat stat; + * }; + */ +static int nlm4_xdr_dec_res(struct rpc_rqst *req, __be32 *p, + struct nlm_res *result) +{ + struct xdr_stream xdr; + int error; + + xdr_init_decode(&xdr, &req->rq_rcv_buf, p); + error = decode_cookie(&xdr, &result->cookie); + if (unlikely(error)) + goto out; + error = decode_nlm4_stat(&xdr, &result->status); +out: + return error; +} + + +/* + * For NLM, a void procedure really returns nothing + */ +#define nlm4_xdr_dec_norep NULL + +#define PROC(proc, argtype, restype) \ +[NLMPROC_##proc] = { \ + .p_proc = NLMPROC_##proc, \ + .p_encode = (kxdrproc_t)nlm4_xdr_enc_##argtype, \ + .p_decode = (kxdrproc_t)nlm4_xdr_dec_##restype, \ + .p_arglen = NLM4_##argtype##_sz, \ + .p_replen = NLM4_##restype##_sz, \ + .p_statidx = NLMPROC_##proc, \ + .p_name = #proc, \ + } + +static struct rpc_procinfo nlm4_procedures[] = { + PROC(TEST, testargs, testres), + PROC(LOCK, lockargs, res), + PROC(CANCEL, cancargs, res), + PROC(UNLOCK, unlockargs, res), + PROC(GRANTED, testargs, res), + PROC(TEST_MSG, testargs, norep), + PROC(LOCK_MSG, lockargs, norep), + PROC(CANCEL_MSG, cancargs, norep), + PROC(UNLOCK_MSG, unlockargs, norep), + PROC(GRANTED_MSG, testargs, norep), + PROC(TEST_RES, testres, norep), + PROC(LOCK_RES, res, norep), + PROC(CANCEL_RES, res, norep), + PROC(UNLOCK_RES, res, norep), + PROC(GRANTED_RES, res, norep), +}; + +struct rpc_version nlm_version4 = { + .number = 4, + .nrprocs = ARRAY_SIZE(nlm4_procedures), + .procs = nlm4_procedures, +}; diff --git a/fs/lockd/xdr4.c b/fs/lockd/xdr4.c index ad9dbbc9145d..dfa4789cd460 100644 --- a/fs/lockd/xdr4.c +++ b/fs/lockd/xdr4.c @@ -93,15 +93,6 @@ nlm4_decode_fh(__be32 *p, struct nfs_fh *f) return p + XDR_QUADLEN(f->size); } -static __be32 * -nlm4_encode_fh(__be32 *p, struct nfs_fh *f) -{ - *p++ = htonl(f->size); - if (f->size) p[XDR_QUADLEN(f->size)-1] = 0; /* don't leak anything */ - memcpy(p, f->data, f->size); - return p + XDR_QUADLEN(f->size); -} - /* * Encode and decode owner handle */ @@ -111,12 +102,6 @@ nlm4_decode_oh(__be32 *p, struct xdr_netobj *oh) return xdr_decode_netobj(p, oh); } -static __be32 * -nlm4_encode_oh(__be32 *p, struct xdr_netobj *oh) -{ - return xdr_encode_netobj(p, oh); -} - static __be32 * nlm4_decode_lock(__be32 *p, struct nlm_lock *lock) { @@ -149,38 +134,6 @@ nlm4_decode_lock(__be32 *p, struct nlm_lock *lock) return p; } -/* - * Encode a lock as part of an NLM call - */ -static __be32 * -nlm4_encode_lock(__be32 *p, struct nlm_lock *lock) -{ - struct file_lock *fl = &lock->fl; - __s64 start, len; - - if (!(p = xdr_encode_string(p, lock->caller)) - || !(p = nlm4_encode_fh(p, &lock->fh)) - || !(p = nlm4_encode_oh(p, &lock->oh))) - return NULL; - - if (fl->fl_start > NLM4_OFFSET_MAX - || (fl->fl_end > NLM4_OFFSET_MAX && fl->fl_end != OFFSET_MAX)) - return NULL; - - *p++ = htonl(lock->svid); - - start = loff_t_to_s64(fl->fl_start); - if (fl->fl_end == OFFSET_MAX) - len = 0; - else - len = loff_t_to_s64(fl->fl_end - fl->fl_start + 1); - - p = xdr_encode_hyper(p, start); - p = xdr_encode_hyper(p, len); - - return p; -} - /* * Encode result of a TEST/TEST_MSG call */ @@ -379,211 +332,3 @@ nlm4svc_encode_void(struct svc_rqst *rqstp, __be32 *p, void *dummy) { return xdr_ressize_check(rqstp, p); } - -/* - * Now, the client side XDR functions - */ -#ifdef NLMCLNT_SUPPORT_SHARES -static int -nlm4clt_decode_void(struct rpc_rqst *req, __be32 *p, void *ptr) -{ - return 0; -} -#endif - -static int -nlm4clt_encode_testargs(struct rpc_rqst *req, __be32 *p, nlm_args *argp) -{ - struct nlm_lock *lock = &argp->lock; - - if (!(p = nlm4_encode_cookie(p, &argp->cookie))) - return -EIO; - *p++ = (lock->fl.fl_type == F_WRLCK)? xdr_one : xdr_zero; - if (!(p = nlm4_encode_lock(p, lock))) - return -EIO; - req->rq_slen = xdr_adjust_iovec(req->rq_svec, p); - return 0; -} - -static int -nlm4clt_decode_testres(struct rpc_rqst *req, __be32 *p, struct nlm_res *resp) -{ - if (!(p = nlm4_decode_cookie(p, &resp->cookie))) - return -EIO; - resp->status = *p++; - if (resp->status == nlm_lck_denied) { - struct file_lock *fl = &resp->lock.fl; - u32 excl; - __u64 start, len; - __s64 end; - - memset(&resp->lock, 0, sizeof(resp->lock)); - locks_init_lock(fl); - excl = ntohl(*p++); - resp->lock.svid = ntohl(*p++); - fl->fl_pid = (pid_t)resp->lock.svid; - if (!(p = nlm4_decode_oh(p, &resp->lock.oh))) - return -EIO; - - fl->fl_flags = FL_POSIX; - fl->fl_type = excl? F_WRLCK : F_RDLCK; - p = xdr_decode_hyper(p, &start); - p = xdr_decode_hyper(p, &len); - end = start + len - 1; - - fl->fl_start = s64_to_loff_t(start); - if (len == 0 || end < 0) - fl->fl_end = OFFSET_MAX; - else - fl->fl_end = s64_to_loff_t(end); - } - return 0; -} - - -static int -nlm4clt_encode_lockargs(struct rpc_rqst *req, __be32 *p, nlm_args *argp) -{ - struct nlm_lock *lock = &argp->lock; - - if (!(p = nlm4_encode_cookie(p, &argp->cookie))) - return -EIO; - *p++ = argp->block? xdr_one : xdr_zero; - *p++ = (lock->fl.fl_type == F_WRLCK)? xdr_one : xdr_zero; - if (!(p = nlm4_encode_lock(p, lock))) - return -EIO; - *p++ = argp->reclaim? xdr_one : xdr_zero; - *p++ = htonl(argp->state); - req->rq_slen = xdr_adjust_iovec(req->rq_svec, p); - return 0; -} - -static int -nlm4clt_encode_cancargs(struct rpc_rqst *req, __be32 *p, nlm_args *argp) -{ - struct nlm_lock *lock = &argp->lock; - - if (!(p = nlm4_encode_cookie(p, &argp->cookie))) - return -EIO; - *p++ = argp->block? xdr_one : xdr_zero; - *p++ = (lock->fl.fl_type == F_WRLCK)? xdr_one : xdr_zero; - if (!(p = nlm4_encode_lock(p, lock))) - return -EIO; - req->rq_slen = xdr_adjust_iovec(req->rq_svec, p); - return 0; -} - -static int -nlm4clt_encode_unlockargs(struct rpc_rqst *req, __be32 *p, nlm_args *argp) -{ - struct nlm_lock *lock = &argp->lock; - - if (!(p = nlm4_encode_cookie(p, &argp->cookie))) - return -EIO; - if (!(p = nlm4_encode_lock(p, lock))) - return -EIO; - req->rq_slen = xdr_adjust_iovec(req->rq_svec, p); - return 0; -} - -static int -nlm4clt_encode_res(struct rpc_rqst *req, __be32 *p, struct nlm_res *resp) -{ - if (!(p = nlm4_encode_cookie(p, &resp->cookie))) - return -EIO; - *p++ = resp->status; - req->rq_slen = xdr_adjust_iovec(req->rq_svec, p); - return 0; -} - -static int -nlm4clt_encode_testres(struct rpc_rqst *req, __be32 *p, struct nlm_res *resp) -{ - if (!(p = nlm4_encode_testres(p, resp))) - return -EIO; - req->rq_slen = xdr_adjust_iovec(req->rq_svec, p); - return 0; -} - -static int -nlm4clt_decode_res(struct rpc_rqst *req, __be32 *p, struct nlm_res *resp) -{ - if (!(p = nlm4_decode_cookie(p, &resp->cookie))) - return -EIO; - resp->status = *p++; - return 0; -} - -#if (NLMCLNT_OHSIZE > XDR_MAX_NETOBJ) -# error "NLM host name cannot be larger than XDR_MAX_NETOBJ!" -#endif - -#if (NLMCLNT_OHSIZE > NLM_MAXSTRLEN) -# error "NLM host name cannot be larger than NLM's maximum string length!" -#endif - -/* - * Buffer requirements for NLM - */ -#define NLM4_void_sz 0 -#define NLM4_cookie_sz 1+XDR_QUADLEN(NLM_MAXCOOKIELEN) -#define NLM4_caller_sz 1+XDR_QUADLEN(NLMCLNT_OHSIZE) -#define NLM4_owner_sz 1+XDR_QUADLEN(NLMCLNT_OHSIZE) -#define NLM4_fhandle_sz 1+XDR_QUADLEN(NFS3_FHSIZE) -#define NLM4_lock_sz 5+NLM4_caller_sz+NLM4_owner_sz+NLM4_fhandle_sz -#define NLM4_holder_sz 6+NLM4_owner_sz - -#define NLM4_testargs_sz NLM4_cookie_sz+1+NLM4_lock_sz -#define NLM4_lockargs_sz NLM4_cookie_sz+4+NLM4_lock_sz -#define NLM4_cancargs_sz NLM4_cookie_sz+2+NLM4_lock_sz -#define NLM4_unlockargs_sz NLM4_cookie_sz+NLM4_lock_sz - -#define NLM4_testres_sz NLM4_cookie_sz+1+NLM4_holder_sz -#define NLM4_res_sz NLM4_cookie_sz+1 -#define NLM4_norep_sz 0 - -/* - * For NLM, a void procedure really returns nothing - */ -#define nlm4clt_decode_norep NULL - -#define PROC(proc, argtype, restype) \ -[NLMPROC_##proc] = { \ - .p_proc = NLMPROC_##proc, \ - .p_encode = (kxdrproc_t) nlm4clt_encode_##argtype, \ - .p_decode = (kxdrproc_t) nlm4clt_decode_##restype, \ - .p_arglen = NLM4_##argtype##_sz, \ - .p_replen = NLM4_##restype##_sz, \ - .p_statidx = NLMPROC_##proc, \ - .p_name = #proc, \ - } - -static struct rpc_procinfo nlm4_procedures[] = { - PROC(TEST, testargs, testres), - PROC(LOCK, lockargs, res), - PROC(CANCEL, cancargs, res), - PROC(UNLOCK, unlockargs, res), - PROC(GRANTED, testargs, res), - PROC(TEST_MSG, testargs, norep), - PROC(LOCK_MSG, lockargs, norep), - PROC(CANCEL_MSG, cancargs, norep), - PROC(UNLOCK_MSG, unlockargs, norep), - PROC(GRANTED_MSG, testargs, norep), - PROC(TEST_RES, testres, norep), - PROC(LOCK_RES, res, norep), - PROC(CANCEL_RES, res, norep), - PROC(UNLOCK_RES, res, norep), - PROC(GRANTED_RES, res, norep), -#ifdef NLMCLNT_SUPPORT_SHARES - PROC(SHARE, shareargs, shareres), - PROC(UNSHARE, shareargs, shareres), - PROC(NM_LOCK, lockargs, res), - PROC(FREE_ALL, notify, void), -#endif -}; - -struct rpc_version nlm_version4 = { - .number = 4, - .nrprocs = 24, - .procs = nlm4_procedures, -}; -- cgit v1.2.3 From a033db487eec09afde00a3562842982a8053c887 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Tue, 14 Dec 2010 14:57:22 +0000 Subject: NFSD: Update XDR encoders in NFSv4 callback client Clean up. Remove old-style NFSv4 XDR macros in favor of the style now used in fs/nfs/nfs4xdr.c. These were forgotten during the recent nfs4xdr.c rewrite. Signed-off-by: Chuck Lever Tested-by: J. Bruce Fields Signed-off-by: Trond Myklebust --- fs/nfsd/nfs4callback.c | 255 ++++++++++++++++++++++++++++++++++--------------- 1 file changed, 178 insertions(+), 77 deletions(-) diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c index 143da2eecd7b..d8148cc461e7 100644 --- a/fs/nfsd/nfs4callback.c +++ b/fs/nfsd/nfs4callback.c @@ -50,11 +50,6 @@ enum { NFSPROC4_CLNT_CB_SEQUENCE, }; -enum nfs_cb_opnum4 { - OP_CB_RECALL = 4, - OP_CB_SEQUENCE = 11, -}; - #define NFS4_MAXTAGLEN 20 #define NFS4_enc_cb_null_sz 0 @@ -79,30 +74,6 @@ enum nfs_cb_opnum4 { cb_sequence_dec_sz + \ op_dec_sz) -/* -* Generic encode routines from fs/nfs/nfs4xdr.c -*/ -static inline __be32 * -xdr_writemem(__be32 *p, const void *ptr, int nbytes) -{ - int tmp = XDR_QUADLEN(nbytes); - if (!tmp) - return p; - p[tmp-1] = 0; - memcpy(p, ptr, nbytes); - return p + tmp; -} - -#define WRITE32(n) *p++ = htonl(n) -#define WRITEMEM(ptr,nbytes) do { \ - p = xdr_writemem(p, ptr, nbytes); \ -} while (0) -#define RESERVE_SPACE(nbytes) do { \ - p = xdr_reserve_space(xdr, nbytes); \ - if (!p) dprintk("NFSD: RESERVE_SPACE(%d) failed in function %s\n", (int) (nbytes), __func__); \ - BUG_ON(!p); \ -} while (0) - /* * Generic decode routines from fs/nfs/nfs4xdr.c */ @@ -197,102 +168,232 @@ nfs_cb_stat_to_errno(int stat) return stat; } +static __be32 *xdr_encode_empty_array(__be32 *p) +{ + *p++ = xdr_zero; + return p; +} + +/* + * Encode/decode NFSv4 CB basic data types + * + * Basic NFSv4 callback data types are defined in section 15 of RFC + * 3530: "Network File System (NFS) version 4 Protocol" and section + * 20 of RFC 5661: "Network File System (NFS) Version 4 Minor Version + * 1 Protocol" + */ + +/* + * nfs_cb_opnum4 + * + * enum nfs_cb_opnum4 { + * OP_CB_GETATTR = 3, + * ... + * }; + */ +enum nfs_cb_opnum4 { + OP_CB_GETATTR = 3, + OP_CB_RECALL = 4, + OP_CB_LAYOUTRECALL = 5, + OP_CB_NOTIFY = 6, + OP_CB_PUSH_DELEG = 7, + OP_CB_RECALL_ANY = 8, + OP_CB_RECALLABLE_OBJ_AVAIL = 9, + OP_CB_RECALL_SLOT = 10, + OP_CB_SEQUENCE = 11, + OP_CB_WANTS_CANCELLED = 12, + OP_CB_NOTIFY_LOCK = 13, + OP_CB_NOTIFY_DEVICEID = 14, + OP_CB_ILLEGAL = 10044 +}; + +static void encode_nfs_cb_opnum4(struct xdr_stream *xdr, enum nfs_cb_opnum4 op) +{ + __be32 *p; + + p = xdr_reserve_space(xdr, 4); + *p = cpu_to_be32(op); +} + +/* + * nfs_fh4 + * + * typedef opaque nfs_fh4; + */ +static void encode_nfs_fh4(struct xdr_stream *xdr, const struct knfsd_fh *fh) +{ + u32 length = fh->fh_size; + __be32 *p; + + BUG_ON(length > NFS4_FHSIZE); + p = xdr_reserve_space(xdr, 4 + length); + xdr_encode_opaque(p, &fh->fh_base, length); +} + /* - * XDR encode + * stateid4 + * + * struct stateid4 { + * uint32_t seqid; + * opaque other[12]; + * }; */ +static void encode_stateid4(struct xdr_stream *xdr, const stateid_t *sid) +{ + __be32 *p; + + p = xdr_reserve_space(xdr, NFS4_STATEID_SIZE); + *p++ = cpu_to_be32(sid->si_generation); + xdr_encode_opaque_fixed(p, &sid->si_opaque, NFS4_STATEID_OTHER_SIZE); +} -static void -encode_stateid(struct xdr_stream *xdr, stateid_t *sid) +/* + * sessionid4 + * + * typedef opaque sessionid4[NFS4_SESSIONID_SIZE]; + */ +static void encode_sessionid4(struct xdr_stream *xdr, + const struct nfsd4_session *session) { __be32 *p; - RESERVE_SPACE(sizeof(stateid_t)); - WRITE32(sid->si_generation); - WRITEMEM(&sid->si_opaque, sizeof(stateid_opaque_t)); + p = xdr_reserve_space(xdr, NFS4_MAX_SESSIONID_LEN); + xdr_encode_opaque_fixed(p, session->se_sessionid.data, + NFS4_MAX_SESSIONID_LEN); } -static void -encode_cb_compound_hdr(struct xdr_stream *xdr, struct nfs4_cb_compound_hdr *hdr) +/* + * CB_COMPOUND4args + * + * struct CB_COMPOUND4args { + * utf8str_cs tag; + * uint32_t minorversion; + * uint32_t callback_ident; + * nfs_cb_argop4 argarray<>; + * }; +*/ +static void encode_cb_compound4args(struct xdr_stream *xdr, + struct nfs4_cb_compound_hdr *hdr) { __be32 * p; - RESERVE_SPACE(16); - WRITE32(0); /* tag length is always 0 */ - WRITE32(hdr->minorversion); - WRITE32(hdr->ident); + p = xdr_reserve_space(xdr, 4 + 4 + 4 + 4); + p = xdr_encode_empty_array(p); /* empty tag */ + *p++ = cpu_to_be32(hdr->minorversion); + *p++ = cpu_to_be32(hdr->ident); + hdr->nops_p = p; - WRITE32(hdr->nops); + *p = cpu_to_be32(hdr->nops); /* argarray element count */ } +/* + * Update argarray element count + */ static void encode_cb_nops(struct nfs4_cb_compound_hdr *hdr) { - *hdr->nops_p = htonl(hdr->nops); + BUG_ON(hdr->nops > NFS4_MAX_BACK_CHANNEL_OPS); + *hdr->nops_p = cpu_to_be32(hdr->nops); } -static void -encode_cb_recall(struct xdr_stream *xdr, struct nfs4_delegation *dp, - struct nfs4_cb_compound_hdr *hdr) +/* + * CB_RECALL4args + * + * struct CB_RECALL4args { + * stateid4 stateid; + * bool truncate; + * nfs_fh4 fh; + * }; + */ +static void encode_cb_recall4args(struct xdr_stream *xdr, + const struct nfs4_delegation *dp, + struct nfs4_cb_compound_hdr *hdr) { __be32 *p; - int len = dp->dl_fh.fh_size; - - RESERVE_SPACE(4); - WRITE32(OP_CB_RECALL); - encode_stateid(xdr, &dp->dl_stateid); - RESERVE_SPACE(8 + (XDR_QUADLEN(len) << 2)); - WRITE32(0); /* truncate optimization not implemented */ - WRITE32(len); - WRITEMEM(&dp->dl_fh.fh_base, len); + + encode_nfs_cb_opnum4(xdr, OP_CB_RECALL); + encode_stateid4(xdr, &dp->dl_stateid); + + p = xdr_reserve_space(xdr, 4); + *p++ = xdr_zero; /* truncate */ + + encode_nfs_fh4(xdr, &dp->dl_fh); + hdr->nops++; } -static void -encode_cb_sequence(struct xdr_stream *xdr, struct nfsd4_callback *cb, - struct nfs4_cb_compound_hdr *hdr) +/* + * CB_SEQUENCE4args + * + * struct CB_SEQUENCE4args { + * sessionid4 csa_sessionid; + * sequenceid4 csa_sequenceid; + * slotid4 csa_slotid; + * slotid4 csa_highest_slotid; + * bool csa_cachethis; + * referring_call_list4 csa_referring_call_lists<>; + * }; + */ +static void encode_cb_sequence4args(struct xdr_stream *xdr, + const struct nfsd4_callback *cb, + struct nfs4_cb_compound_hdr *hdr) { + struct nfsd4_session *session = cb->cb_clp->cl_cb_session; __be32 *p; - struct nfsd4_session *ses = cb->cb_clp->cl_cb_session; if (hdr->minorversion == 0) return; - RESERVE_SPACE(1 + NFS4_MAX_SESSIONID_LEN + 20); + encode_nfs_cb_opnum4(xdr, OP_CB_SEQUENCE); + encode_sessionid4(xdr, session); + + p = xdr_reserve_space(xdr, 4 + 4 + 4 + 4 + 4); + *p++ = cpu_to_be32(session->se_cb_seq_nr); /* csa_sequenceid */ + *p++ = xdr_zero; /* csa_slotid */ + *p++ = xdr_zero; /* csa_highest_slotid */ + *p++ = xdr_zero; /* csa_cachethis */ + xdr_encode_empty_array(p); /* csa_referring_call_lists */ - WRITE32(OP_CB_SEQUENCE); - WRITEMEM(ses->se_sessionid.data, NFS4_MAX_SESSIONID_LEN); - WRITE32(ses->se_cb_seq_nr); - WRITE32(0); /* slotid, always 0 */ - WRITE32(0); /* highest slotid always 0 */ - WRITE32(0); /* cachethis always 0 */ - WRITE32(0); /* FIXME: support referring_call_lists */ hdr->nops++; } -static int -nfs4_xdr_enc_cb_null(struct rpc_rqst *req, __be32 *p) +/* + * NFSv4.0 and NFSv4.1 XDR encode functions + * + * NFSv4.0 callback argument types are defined in section 15 of RFC + * 3530: "Network File System (NFS) version 4 Protocol" and section 20 + * of RFC 5661: "Network File System (NFS) Version 4 Minor Version 1 + * Protocol". + */ + +/* + * NB: Without this zero space reservation, callbacks over krb5p fail + */ +static int nfs4_xdr_enc_cb_null(struct rpc_rqst *req, __be32 *p, void *__unused) { struct xdr_stream xdrs, *xdr = &xdrs; xdr_init_encode(&xdrs, &req->rq_snd_buf, p); - RESERVE_SPACE(0); + xdr_reserve_space(xdr, 0); return 0; } -static int -nfs4_xdr_enc_cb_recall(struct rpc_rqst *req, __be32 *p, - struct nfsd4_callback *cb) +/* + * 20.2. Operation 4: CB_RECALL - Recall a Delegation + */ +static int nfs4_xdr_enc_cb_recall(struct rpc_rqst *req, __be32 *p, + const struct nfsd4_callback *cb) { struct xdr_stream xdr; - struct nfs4_delegation *args = cb->cb_op; + const struct nfs4_delegation *args = cb->cb_op; struct nfs4_cb_compound_hdr hdr = { .ident = cb->cb_clp->cl_cb_ident, .minorversion = cb->cb_minorversion, }; xdr_init_encode(&xdr, &req->rq_snd_buf, p); - encode_cb_compound_hdr(&xdr, &hdr); - encode_cb_sequence(&xdr, cb, &hdr); - encode_cb_recall(&xdr, args, &hdr); + encode_cb_compound4args(&xdr, &hdr); + encode_cb_sequence4args(&xdr, cb, &hdr); + encode_cb_recall4args(&xdr, args, &hdr); encode_cb_nops(&hdr); return 0; } -- cgit v1.2.3 From 85a56480191ca9f08fc775c129b9eb5c8c1f2c05 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Tue, 14 Dec 2010 14:57:32 +0000 Subject: NFSD: Update XDR decoders in NFSv4 callback client Clean up. Remove old-style NFSv4 XDR macros in favor of the style now used in fs/nfs/nfs4xdr.c. These were forgotten during the recent nfs4xdr.c rewrite. Additional whitespace cleanup adds to the size of this patch. Signed-off-by: Chuck Lever Tested-by: J. Bruce Fields Signed-off-by: Trond Myklebust --- fs/nfsd/nfs4callback.c | 415 ++++++++++++++++++++++++++++--------------------- 1 file changed, 239 insertions(+), 176 deletions(-) diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c index d8148cc461e7..c3c6a903144c 100644 --- a/fs/nfsd/nfs4callback.c +++ b/fs/nfsd/nfs4callback.c @@ -74,37 +74,6 @@ enum { cb_sequence_dec_sz + \ op_dec_sz) -/* - * Generic decode routines from fs/nfs/nfs4xdr.c - */ -#define DECODE_TAIL \ - status = 0; \ -out: \ - return status; \ -xdr_error: \ - dprintk("NFSD: xdr error! (%s:%d)\n", __FILE__, __LINE__); \ - status = -EIO; \ - goto out - -#define READ32(x) (x) = ntohl(*p++) -#define READ64(x) do { \ - (x) = (u64)ntohl(*p++) << 32; \ - (x) |= ntohl(*p++); \ -} while (0) -#define READTIME(x) do { \ - p++; \ - (x.tv_sec) = ntohl(*p++); \ - (x.tv_nsec) = ntohl(*p++); \ -} while (0) -#define READ_BUF(nbytes) do { \ - p = xdr_inline_decode(xdr, nbytes); \ - if (!p) { \ - dprintk("NFSD: %s: reply buffer overflowed in line %d.\n", \ - __func__, __LINE__); \ - return -EIO; \ - } \ -} while (0) - struct nfs4_cb_compound_hdr { /* args */ u32 ident; /* minorversion 0 only */ @@ -115,57 +84,14 @@ struct nfs4_cb_compound_hdr { int status; }; -static struct { -int stat; -int errno; -} nfs_cb_errtbl[] = { - { NFS4_OK, 0 }, - { NFS4ERR_PERM, EPERM }, - { NFS4ERR_NOENT, ENOENT }, - { NFS4ERR_IO, EIO }, - { NFS4ERR_NXIO, ENXIO }, - { NFS4ERR_ACCESS, EACCES }, - { NFS4ERR_EXIST, EEXIST }, - { NFS4ERR_XDEV, EXDEV }, - { NFS4ERR_NOTDIR, ENOTDIR }, - { NFS4ERR_ISDIR, EISDIR }, - { NFS4ERR_INVAL, EINVAL }, - { NFS4ERR_FBIG, EFBIG }, - { NFS4ERR_NOSPC, ENOSPC }, - { NFS4ERR_ROFS, EROFS }, - { NFS4ERR_MLINK, EMLINK }, - { NFS4ERR_NAMETOOLONG, ENAMETOOLONG }, - { NFS4ERR_NOTEMPTY, ENOTEMPTY }, - { NFS4ERR_DQUOT, EDQUOT }, - { NFS4ERR_STALE, ESTALE }, - { NFS4ERR_BADHANDLE, EBADHANDLE }, - { NFS4ERR_BAD_COOKIE, EBADCOOKIE }, - { NFS4ERR_NOTSUPP, ENOTSUPP }, - { NFS4ERR_TOOSMALL, ETOOSMALL }, - { NFS4ERR_SERVERFAULT, ESERVERFAULT }, - { NFS4ERR_BADTYPE, EBADTYPE }, - { NFS4ERR_LOCKED, EAGAIN }, - { NFS4ERR_RESOURCE, EREMOTEIO }, - { NFS4ERR_SYMLINK, ELOOP }, - { NFS4ERR_OP_ILLEGAL, EOPNOTSUPP }, - { NFS4ERR_DEADLOCK, EDEADLK }, - { -1, EIO } -}; - -static int -nfs_cb_stat_to_errno(int stat) +/* + * Handle decode buffer overflows out-of-line. + */ +static void print_overflow_msg(const char *func, const struct xdr_stream *xdr) { - int i; - for (i = 0; nfs_cb_errtbl[i].stat != -1; i++) { - if (nfs_cb_errtbl[i].stat == stat) - return nfs_cb_errtbl[i].errno; - } - /* If we cannot translate the error, the recovery routines should - * handle it. - * Note: remaining NFSv4 error codes have values > 10000, so should - * not conflict with native Linux error codes. - */ - return stat; + dprintk("NFS: %s prematurely hit the end of our receive buffer. " + "Remaining buffer length is %tu words.\n", + func, xdr->end - xdr->p); } static __be32 *xdr_encode_empty_array(__be32 *p) @@ -262,6 +188,89 @@ static void encode_sessionid4(struct xdr_stream *xdr, NFS4_MAX_SESSIONID_LEN); } +/* + * nfsstat4 + */ +static const struct { + int stat; + int errno; +} nfs_cb_errtbl[] = { + { NFS4_OK, 0 }, + { NFS4ERR_PERM, -EPERM }, + { NFS4ERR_NOENT, -ENOENT }, + { NFS4ERR_IO, -EIO }, + { NFS4ERR_NXIO, -ENXIO }, + { NFS4ERR_ACCESS, -EACCES }, + { NFS4ERR_EXIST, -EEXIST }, + { NFS4ERR_XDEV, -EXDEV }, + { NFS4ERR_NOTDIR, -ENOTDIR }, + { NFS4ERR_ISDIR, -EISDIR }, + { NFS4ERR_INVAL, -EINVAL }, + { NFS4ERR_FBIG, -EFBIG }, + { NFS4ERR_NOSPC, -ENOSPC }, + { NFS4ERR_ROFS, -EROFS }, + { NFS4ERR_MLINK, -EMLINK }, + { NFS4ERR_NAMETOOLONG, -ENAMETOOLONG }, + { NFS4ERR_NOTEMPTY, -ENOTEMPTY }, + { NFS4ERR_DQUOT, -EDQUOT }, + { NFS4ERR_STALE, -ESTALE }, + { NFS4ERR_BADHANDLE, -EBADHANDLE }, + { NFS4ERR_BAD_COOKIE, -EBADCOOKIE }, + { NFS4ERR_NOTSUPP, -ENOTSUPP }, + { NFS4ERR_TOOSMALL, -ETOOSMALL }, + { NFS4ERR_SERVERFAULT, -ESERVERFAULT }, + { NFS4ERR_BADTYPE, -EBADTYPE }, + { NFS4ERR_LOCKED, -EAGAIN }, + { NFS4ERR_RESOURCE, -EREMOTEIO }, + { NFS4ERR_SYMLINK, -ELOOP }, + { NFS4ERR_OP_ILLEGAL, -EOPNOTSUPP }, + { NFS4ERR_DEADLOCK, -EDEADLK }, + { -1, -EIO } +}; + +/* + * If we cannot translate the error, the recovery routines should + * handle it. + * + * Note: remaining NFSv4 error codes have values > 10000, so should + * not conflict with native Linux error codes. + */ +static int nfs_cb_stat_to_errno(int status) +{ + int i; + + for (i = 0; nfs_cb_errtbl[i].stat != -1; i++) { + if (nfs_cb_errtbl[i].stat == status) + return nfs_cb_errtbl[i].errno; + } + + dprintk("NFSD: Unrecognized NFS CB status value: %u\n", status); + return -status; +} + +static int decode_cb_op_status(struct xdr_stream *xdr, enum nfs_opnum4 expected, + enum nfsstat4 *status) +{ + __be32 *p; + u32 op; + + p = xdr_inline_decode(xdr, 4 + 4); + if (unlikely(p == NULL)) + goto out_overflow; + op = be32_to_cpup(p++); + if (unlikely(op != expected)) + goto out_unexpected; + *status = be32_to_cpup(p); + return 0; +out_overflow: + print_overflow_msg(__func__, xdr); + return -EIO; +out_unexpected: + dprintk("NFSD: Callback server returned operation %d but " + "we issued a request for %d\n", op, expected); + return -EIO; +} + /* * CB_COMPOUND4args * @@ -295,6 +304,37 @@ static void encode_cb_nops(struct nfs4_cb_compound_hdr *hdr) *hdr->nops_p = cpu_to_be32(hdr->nops); } +/* + * CB_COMPOUND4res + * + * struct CB_COMPOUND4res { + * nfsstat4 status; + * utf8str_cs tag; + * nfs_cb_resop4 resarray<>; + * }; + */ +static int decode_cb_compound4res(struct xdr_stream *xdr, + struct nfs4_cb_compound_hdr *hdr) +{ + u32 length; + __be32 *p; + + p = xdr_inline_decode(xdr, 4 + 4); + if (unlikely(p == NULL)) + goto out_overflow; + hdr->status = be32_to_cpup(p++); + /* Ignore the tag */ + length = be32_to_cpup(p++); + p = xdr_inline_decode(xdr, length + 4); + if (unlikely(p == NULL)) + goto out_overflow; + hdr->nops = be32_to_cpup(p); + return 0; +out_overflow: + print_overflow_msg(__func__, xdr); + return -EIO; +} + /* * CB_RECALL4args * @@ -356,6 +396,97 @@ static void encode_cb_sequence4args(struct xdr_stream *xdr, hdr->nops++; } +/* + * CB_SEQUENCE4resok + * + * struct CB_SEQUENCE4resok { + * sessionid4 csr_sessionid; + * sequenceid4 csr_sequenceid; + * slotid4 csr_slotid; + * slotid4 csr_highest_slotid; + * slotid4 csr_target_highest_slotid; + * }; + * + * union CB_SEQUENCE4res switch (nfsstat4 csr_status) { + * case NFS4_OK: + * CB_SEQUENCE4resok csr_resok4; + * default: + * void; + * }; + * + * Our current back channel implmentation supports a single backchannel + * with a single slot. + */ +static int decode_cb_sequence4resok(struct xdr_stream *xdr, + struct nfsd4_callback *cb) +{ + struct nfsd4_session *session = cb->cb_clp->cl_cb_session; + struct nfs4_sessionid id; + int status; + __be32 *p; + u32 dummy; + + status = -ESERVERFAULT; + + /* + * If the server returns different values for sessionID, slotID or + * sequence number, the server is looney tunes. + */ + p = xdr_inline_decode(xdr, NFS4_MAX_SESSIONID_LEN + 4 + 4); + if (unlikely(p == NULL)) + goto out_overflow; + memcpy(id.data, p, NFS4_MAX_SESSIONID_LEN); + if (memcmp(id.data, session->se_sessionid.data, + NFS4_MAX_SESSIONID_LEN) != 0) { + dprintk("NFS: %s Invalid session id\n", __func__); + goto out; + } + p += XDR_QUADLEN(NFS4_MAX_SESSIONID_LEN); + + dummy = be32_to_cpup(p++); + if (dummy != session->se_cb_seq_nr) { + dprintk("NFS: %s Invalid sequence number\n", __func__); + goto out; + } + + dummy = be32_to_cpup(p++); + if (dummy != 0) { + dprintk("NFS: %s Invalid slotid\n", __func__); + goto out; + } + + /* + * FIXME: process highest slotid and target highest slotid + */ + status = 0; +out: + return status; +out_overflow: + print_overflow_msg(__func__, xdr); + return -EIO; +} + +static int decode_cb_sequence4res(struct xdr_stream *xdr, + struct nfsd4_callback *cb) +{ + enum nfsstat4 nfserr; + int status; + + if (cb->cb_minorversion == 0) + return 0; + + status = decode_cb_op_status(xdr, OP_CB_SEQUENCE, &nfserr); + if (unlikely(status)) + goto out; + if (unlikely(nfserr != NFS4_OK)) + goto out_default; + status = decode_cb_sequence4resok(xdr, cb); +out: + return status; +out_default: + return nfs_cb_stat_to_errno(status); +} + /* * NFSv4.0 and NFSv4.1 XDR encode functions * @@ -399,119 +530,51 @@ static int nfs4_xdr_enc_cb_recall(struct rpc_rqst *req, __be32 *p, } -static int -decode_cb_compound_hdr(struct xdr_stream *xdr, struct nfs4_cb_compound_hdr *hdr){ - __be32 *p; - u32 taglen; - - READ_BUF(8); - READ32(hdr->status); - /* We've got no use for the tag; ignore it: */ - READ32(taglen); - READ_BUF(taglen + 4); - p += XDR_QUADLEN(taglen); - READ32(hdr->nops); - return 0; -} - -static int -decode_cb_op_hdr(struct xdr_stream *xdr, enum nfs_opnum4 expected) -{ - __be32 *p; - u32 op; - int32_t nfserr; - - READ_BUF(8); - READ32(op); - if (op != expected) { - dprintk("NFSD: decode_cb_op_hdr: Callback server returned " - " operation %d but we issued a request for %d\n", - op, expected); - return -EIO; - } - READ32(nfserr); - if (nfserr != NFS_OK) - return -nfs_cb_stat_to_errno(nfserr); - return 0; -} - /* - * Our current back channel implmentation supports a single backchannel - * with a single slot. + * NFSv4.0 and NFSv4.1 XDR decode functions + * + * NFSv4.0 callback result types are defined in section 15 of RFC + * 3530: "Network File System (NFS) version 4 Protocol" and section 20 + * of RFC 5661: "Network File System (NFS) Version 4 Minor Version 1 + * Protocol". */ -static int -decode_cb_sequence(struct xdr_stream *xdr, struct nfsd4_callback *cb, - struct rpc_rqst *rqstp) -{ - struct nfsd4_session *ses = cb->cb_clp->cl_cb_session; - struct nfs4_sessionid id; - int status; - u32 dummy; - __be32 *p; - - if (cb->cb_minorversion == 0) - return 0; - - status = decode_cb_op_hdr(xdr, OP_CB_SEQUENCE); - if (status) - return status; - - /* - * If the server returns different values for sessionID, slotID or - * sequence number, the server is looney tunes. - */ - status = -ESERVERFAULT; - - READ_BUF(NFS4_MAX_SESSIONID_LEN + 16); - memcpy(id.data, p, NFS4_MAX_SESSIONID_LEN); - p += XDR_QUADLEN(NFS4_MAX_SESSIONID_LEN); - if (memcmp(id.data, ses->se_sessionid.data, NFS4_MAX_SESSIONID_LEN)) { - dprintk("%s Invalid session id\n", __func__); - goto out; - } - READ32(dummy); - if (dummy != ses->se_cb_seq_nr) { - dprintk("%s Invalid sequence number\n", __func__); - goto out; - } - READ32(dummy); /* slotid must be 0 */ - if (dummy != 0) { - dprintk("%s Invalid slotid\n", __func__); - goto out; - } - /* FIXME: process highest slotid and target highest slotid */ - status = 0; -out: - return status; -} - -static int -nfs4_xdr_dec_cb_null(struct rpc_rqst *req, __be32 *p) +static int nfs4_xdr_dec_cb_null(struct rpc_rqst *req, __be32 *p, void *__unused) { return 0; } -static int -nfs4_xdr_dec_cb_recall(struct rpc_rqst *rqstp, __be32 *p, - struct nfsd4_callback *cb) +/* + * 20.2. Operation 4: CB_RECALL - Recall a Delegation + */ +static int nfs4_xdr_dec_cb_recall(struct rpc_rqst *rqstp, __be32 *p, + struct nfsd4_callback *cb) { struct xdr_stream xdr; struct nfs4_cb_compound_hdr hdr; + enum nfsstat4 nfserr; int status; xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p); - status = decode_cb_compound_hdr(&xdr, &hdr); - if (status) + status = decode_cb_compound4res(&xdr, &hdr); + if (unlikely(status)) goto out; - if (cb) { - status = decode_cb_sequence(&xdr, cb, rqstp); - if (status) + + if (cb != NULL) { + status = decode_cb_sequence4res(&xdr, cb); + if (unlikely(status)) goto out; } - status = decode_cb_op_hdr(&xdr, OP_CB_RECALL); + + status = decode_cb_op_status(&xdr, OP_CB_RECALL, &nfserr); + if (unlikely(status)) + goto out; + if (unlikely(nfserr != NFS4_OK)) + goto out_default; out: return status; +out_default: + return nfs_cb_stat_to_errno(status); } /* -- cgit v1.2.3 From 7d93bd71cb3e2629cc88bc59f393bd4df4162b94 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Tue, 14 Dec 2010 14:57:42 +0000 Subject: NFS: Repair whitespace damage in NFS PROC macro Clean up. When I was making other changes in this area, checkscript.pl complained about the use of leading blanks in the PROC macros in the xdr files. Signed-off-by: Chuck Lever Tested-by: J. Bruce Fields Signed-off-by: Trond Myklebust --- fs/nfs/nfs2xdr.c | 30 ++++++++--------- fs/nfs/nfs4xdr.c | 90 +++++++++++++++++++++++++------------------------- fs/nfsd/nfs4callback.c | 52 ++++++++++++++--------------- 3 files changed, 86 insertions(+), 86 deletions(-) diff --git a/fs/nfs/nfs2xdr.c b/fs/nfs/nfs2xdr.c index 70df08a84ead..0343175fe6c0 100644 --- a/fs/nfs/nfs2xdr.c +++ b/fs/nfs/nfs2xdr.c @@ -1193,21 +1193,21 @@ int nfs_stat_to_errno(enum nfs_stat status) .p_name = #proc, \ } struct rpc_procinfo nfs_procedures[] = { - PROC(GETATTR, fhandle, attrstat, 1), - PROC(SETATTR, sattrargs, attrstat, 0), - PROC(LOOKUP, diropargs, diropres, 2), - PROC(READLINK, readlinkargs, readlinkres, 3), - PROC(READ, readargs, readres, 3), - PROC(WRITE, writeargs, writeres, 4), - PROC(CREATE, createargs, diropres, 0), - PROC(REMOVE, removeargs, stat, 0), - PROC(RENAME, renameargs, stat, 0), - PROC(LINK, linkargs, stat, 0), - PROC(SYMLINK, symlinkargs, stat, 0), - PROC(MKDIR, createargs, diropres, 0), - PROC(RMDIR, diropargs, stat, 0), - PROC(READDIR, readdirargs, readdirres, 3), - PROC(STATFS, fhandle, statfsres, 0), + PROC(GETATTR, fhandle, attrstat, 1), + PROC(SETATTR, sattrargs, attrstat, 0), + PROC(LOOKUP, diropargs, diropres, 2), + PROC(READLINK, readlinkargs, readlinkres, 3), + PROC(READ, readargs, readres, 3), + PROC(WRITE, writeargs, writeres, 4), + PROC(CREATE, createargs, diropres, 0), + PROC(REMOVE, removeargs, stat, 0), + PROC(RENAME, renameargs, stat, 0), + PROC(LINK, linkargs, stat, 0), + PROC(SYMLINK, symlinkargs, stat, 0), + PROC(MKDIR, createargs, diropres, 0), + PROC(RMDIR, diropargs, stat, 0), + PROC(READDIR, readdirargs, readdirres, 3), + PROC(STATFS, fhandle, statfsres, 0), }; struct rpc_version nfs_version2 = { diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index 9f1826b012e6..a48a43c75111 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c @@ -6301,8 +6301,8 @@ nfs4_stat_to_errno(int stat) #define PROC(proc, argtype, restype) \ [NFSPROC4_CLNT_##proc] = { \ .p_proc = NFSPROC4_COMPOUND, \ - .p_encode = (kxdrproc_t) nfs4_xdr_##argtype, \ - .p_decode = (kxdrproc_t) nfs4_xdr_##restype, \ + .p_encode = (kxdrproc_t)nfs4_xdr_##argtype, \ + .p_decode = (kxdrproc_t)nfs4_xdr_##restype, \ .p_arglen = NFS4_##argtype##_sz, \ .p_replen = NFS4_##restype##_sz, \ .p_statidx = NFSPROC4_CLNT_##proc, \ @@ -6310,50 +6310,50 @@ nfs4_stat_to_errno(int stat) } struct rpc_procinfo nfs4_procedures[] = { - PROC(READ, enc_read, dec_read), - PROC(WRITE, enc_write, dec_write), - PROC(COMMIT, enc_commit, dec_commit), - PROC(OPEN, enc_open, dec_open), - PROC(OPEN_CONFIRM, enc_open_confirm, dec_open_confirm), - PROC(OPEN_NOATTR, enc_open_noattr, dec_open_noattr), - PROC(OPEN_DOWNGRADE, enc_open_downgrade, dec_open_downgrade), - PROC(CLOSE, enc_close, dec_close), - PROC(SETATTR, enc_setattr, dec_setattr), - PROC(FSINFO, enc_fsinfo, dec_fsinfo), - PROC(RENEW, enc_renew, dec_renew), - PROC(SETCLIENTID, enc_setclientid, dec_setclientid), - PROC(SETCLIENTID_CONFIRM, enc_setclientid_confirm, dec_setclientid_confirm), - PROC(LOCK, enc_lock, dec_lock), - PROC(LOCKT, enc_lockt, dec_lockt), - PROC(LOCKU, enc_locku, dec_locku), - PROC(ACCESS, enc_access, dec_access), - PROC(GETATTR, enc_getattr, dec_getattr), - PROC(LOOKUP, enc_lookup, dec_lookup), - PROC(LOOKUP_ROOT, enc_lookup_root, dec_lookup_root), - PROC(REMOVE, enc_remove, dec_remove), - PROC(RENAME, enc_rename, dec_rename), - PROC(LINK, enc_link, dec_link), - PROC(SYMLINK, enc_symlink, dec_symlink), - PROC(CREATE, enc_create, dec_create), - PROC(PATHCONF, enc_pathconf, dec_pathconf), - PROC(STATFS, enc_statfs, dec_statfs), - PROC(READLINK, enc_readlink, dec_readlink), - PROC(READDIR, enc_readdir, dec_readdir), - PROC(SERVER_CAPS, enc_server_caps, dec_server_caps), - PROC(DELEGRETURN, enc_delegreturn, dec_delegreturn), - PROC(GETACL, enc_getacl, dec_getacl), - PROC(SETACL, enc_setacl, dec_setacl), - PROC(FS_LOCATIONS, enc_fs_locations, dec_fs_locations), - PROC(RELEASE_LOCKOWNER, enc_release_lockowner, dec_release_lockowner), + PROC(READ, enc_read, dec_read), + PROC(WRITE, enc_write, dec_write), + PROC(COMMIT, enc_commit, dec_commit), + PROC(OPEN, enc_open, dec_open), + PROC(OPEN_CONFIRM, enc_open_confirm, dec_open_confirm), + PROC(OPEN_NOATTR, enc_open_noattr, dec_open_noattr), + PROC(OPEN_DOWNGRADE, enc_open_downgrade, dec_open_downgrade), + PROC(CLOSE, enc_close, dec_close), + PROC(SETATTR, enc_setattr, dec_setattr), + PROC(FSINFO, enc_fsinfo, dec_fsinfo), + PROC(RENEW, enc_renew, dec_renew), + PROC(SETCLIENTID, enc_setclientid, dec_setclientid), + PROC(SETCLIENTID_CONFIRM, enc_setclientid_confirm, dec_setclientid_confirm), + PROC(LOCK, enc_lock, dec_lock), + PROC(LOCKT, enc_lockt, dec_lockt), + PROC(LOCKU, enc_locku, dec_locku), + PROC(ACCESS, enc_access, dec_access), + PROC(GETATTR, enc_getattr, dec_getattr), + PROC(LOOKUP, enc_lookup, dec_lookup), + PROC(LOOKUP_ROOT, enc_lookup_root, dec_lookup_root), + PROC(REMOVE, enc_remove, dec_remove), + PROC(RENAME, enc_rename, dec_rename), + PROC(LINK, enc_link, dec_link), + PROC(SYMLINK, enc_symlink, dec_symlink), + PROC(CREATE, enc_create, dec_create), + PROC(PATHCONF, enc_pathconf, dec_pathconf), + PROC(STATFS, enc_statfs, dec_statfs), + PROC(READLINK, enc_readlink, dec_readlink), + PROC(READDIR, enc_readdir, dec_readdir), + PROC(SERVER_CAPS, enc_server_caps, dec_server_caps), + PROC(DELEGRETURN, enc_delegreturn, dec_delegreturn), + PROC(GETACL, enc_getacl, dec_getacl), + PROC(SETACL, enc_setacl, dec_setacl), + PROC(FS_LOCATIONS, enc_fs_locations, dec_fs_locations), + PROC(RELEASE_LOCKOWNER, enc_release_lockowner, dec_release_lockowner), #if defined(CONFIG_NFS_V4_1) - PROC(EXCHANGE_ID, enc_exchange_id, dec_exchange_id), - PROC(CREATE_SESSION, enc_create_session, dec_create_session), - PROC(DESTROY_SESSION, enc_destroy_session, dec_destroy_session), - PROC(SEQUENCE, enc_sequence, dec_sequence), - PROC(GET_LEASE_TIME, enc_get_lease_time, dec_get_lease_time), - PROC(RECLAIM_COMPLETE, enc_reclaim_complete, dec_reclaim_complete), - PROC(GETDEVICEINFO, enc_getdeviceinfo, dec_getdeviceinfo), - PROC(LAYOUTGET, enc_layoutget, dec_layoutget), + PROC(EXCHANGE_ID, enc_exchange_id, dec_exchange_id), + PROC(CREATE_SESSION, enc_create_session, dec_create_session), + PROC(DESTROY_SESSION, enc_destroy_session, dec_destroy_session), + PROC(SEQUENCE, enc_sequence, dec_sequence), + PROC(GET_LEASE_TIME, enc_get_lease_time, dec_get_lease_time), + PROC(RECLAIM_COMPLETE, enc_reclaim_complete, dec_reclaim_complete), + PROC(GETDEVICEINFO, enc_getdeviceinfo, dec_getdeviceinfo), + PROC(LAYOUTGET, enc_layoutget, dec_layoutget), #endif /* CONFIG_NFS_V4_1 */ }; diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c index c3c6a903144c..6529534d7aae 100644 --- a/fs/nfsd/nfs4callback.c +++ b/fs/nfsd/nfs4callback.c @@ -580,23 +580,23 @@ out_default: /* * RPC procedure tables */ -#define PROC(proc, call, argtype, restype) \ -[NFSPROC4_CLNT_##proc] = { \ - .p_proc = NFSPROC4_CB_##call, \ - .p_encode = (kxdrproc_t) nfs4_xdr_##argtype, \ - .p_decode = (kxdrproc_t) nfs4_xdr_##restype, \ - .p_arglen = NFS4_##argtype##_sz, \ - .p_replen = NFS4_##restype##_sz, \ - .p_statidx = NFSPROC4_CB_##call, \ - .p_name = #proc, \ -} - -static struct rpc_procinfo nfs4_cb_procedures[] = { - PROC(CB_NULL, NULL, enc_cb_null, dec_cb_null), - PROC(CB_RECALL, COMPOUND, enc_cb_recall, dec_cb_recall), +#define PROC(proc, call, argtype, restype) \ +[NFSPROC4_CLNT_##proc] = { \ + .p_proc = NFSPROC4_CB_##call, \ + .p_encode = (kxdrproc_t)nfs4_xdr_enc_##argtype, \ + .p_decode = (kxdrproc_t)nfs4_xdr_dec_##restype, \ + .p_arglen = NFS4_enc_##argtype##_sz, \ + .p_replen = NFS4_dec_##restype##_sz, \ + .p_statidx = NFSPROC4_CB_##call, \ + .p_name = #proc, \ +} + +static struct rpc_procinfo nfs4_cb_procedures[] = { + PROC(CB_NULL, NULL, cb_null, cb_null), + PROC(CB_RECALL, COMPOUND, cb_recall, cb_recall), }; -static struct rpc_version nfs_cb_version4 = { +static struct rpc_version nfs_cb_version4 = { /* * Note on the callback rpc program version number: despite language in rfc * 5661 section 18.36.3 requiring servers to use 4 in this field, the @@ -604,29 +604,29 @@ static struct rpc_version nfs_cb_version4 = { * in practice that appears to be what implementations use. The section * 18.36.3 language is expected to be fixed in an erratum. */ - .number = 1, - .nrprocs = ARRAY_SIZE(nfs4_cb_procedures), - .procs = nfs4_cb_procedures + .number = 1, + .nrprocs = ARRAY_SIZE(nfs4_cb_procedures), + .procs = nfs4_cb_procedures }; -static struct rpc_version * nfs_cb_version[] = { +static struct rpc_version *nfs_cb_version[] = { &nfs_cb_version4, }; static struct rpc_program cb_program; static struct rpc_stat cb_stats = { - .program = &cb_program + .program = &cb_program }; #define NFS4_CALLBACK 0x40000000 static struct rpc_program cb_program = { - .name = "nfs4_cb", - .number = NFS4_CALLBACK, - .nrvers = ARRAY_SIZE(nfs_cb_version), - .version = nfs_cb_version, - .stats = &cb_stats, - .pipe_dir_name = "/nfsd4_cb", + .name = "nfs4_cb", + .number = NFS4_CALLBACK, + .nrvers = ARRAY_SIZE(nfs_cb_version), + .version = nfs_cb_version, + .stats = &cb_stats, + .pipe_dir_name = "/nfsd4_cb", }; static int max_cb_time(void) -- cgit v1.2.3 From d8367c504e39528a057a5d7a267b6724f7fdb4b8 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Tue, 14 Dec 2010 14:57:52 +0000 Subject: lockd: Move nlmdbg_cookie2a() to svclock.c Clean up. nlmdbg_cookie2a() is used only in svclock.c. Signed-off-by: Chuck Lever Tested-by: J. Bruce Fields Signed-off-by: Trond Myklebust --- fs/lockd/svclock.c | 30 ++++++++++++++++++++++++++++++ fs/lockd/xdr.c | 29 ----------------------------- include/linux/lockd/debug.h | 10 ---------- 3 files changed, 30 insertions(+), 39 deletions(-) diff --git a/fs/lockd/svclock.c b/fs/lockd/svclock.c index ef5659b211e9..9266c4600208 100644 --- a/fs/lockd/svclock.c +++ b/fs/lockd/svclock.c @@ -46,6 +46,7 @@ static void nlmsvc_remove_block(struct nlm_block *block); static int nlmsvc_setgrantargs(struct nlm_rqst *call, struct nlm_lock *lock); static void nlmsvc_freegrantargs(struct nlm_rqst *call); static const struct rpc_call_ops nlmsvc_grant_ops; +static const char *nlmdbg_cookie2a(const struct nlm_cookie *cookie); /* * The list of blocked locks to retry @@ -934,3 +935,32 @@ nlmsvc_retry_blocked(void) return timeout; } + +#ifdef RPC_DEBUG +static const char *nlmdbg_cookie2a(const struct nlm_cookie *cookie) +{ + /* + * We can get away with a static buffer because we're only + * called with BKL held. + */ + static char buf[2*NLM_MAXCOOKIELEN+1]; + unsigned int i, len = sizeof(buf); + char *p = buf; + + len--; /* allow for trailing \0 */ + if (len < 3) + return "???"; + for (i = 0 ; i < cookie->len ; i++) { + if (len < 2) { + strcpy(p-3, "..."); + break; + } + sprintf(p, "%02x", cookie->data[i]); + p += 2; + len -= 2; + } + *p = '\0'; + + return buf; +} +#endif diff --git a/fs/lockd/xdr.c b/fs/lockd/xdr.c index 0eb694dc497b..964666c68a86 100644 --- a/fs/lockd/xdr.c +++ b/fs/lockd/xdr.c @@ -341,32 +341,3 @@ nlmsvc_encode_void(struct svc_rqst *rqstp, __be32 *p, void *dummy) { return xdr_ressize_check(rqstp, p); } - -#ifdef RPC_DEBUG -const char *nlmdbg_cookie2a(const struct nlm_cookie *cookie) -{ - /* - * We can get away with a static buffer because we're only - * called with BKL held. - */ - static char buf[2*NLM_MAXCOOKIELEN+1]; - unsigned int i, len = sizeof(buf); - char *p = buf; - - len--; /* allow for trailing \0 */ - if (len < 3) - return "???"; - for (i = 0 ; i < cookie->len ; i++) { - if (len < 2) { - strcpy(p-3, "..."); - break; - } - sprintf(p, "%02x", cookie->data[i]); - p += 2; - len -= 2; - } - *p = '\0'; - - return buf; -} -#endif diff --git a/include/linux/lockd/debug.h b/include/linux/lockd/debug.h index 34b2b7f33c3b..257d3779f2ab 100644 --- a/include/linux/lockd/debug.h +++ b/include/linux/lockd/debug.h @@ -44,14 +44,4 @@ #define NLMDBG_XDR 0x0100 #define NLMDBG_ALL 0x7fff - -/* - * Support for printing NLM cookies in dprintk() - */ -#ifdef RPC_DEBUG -struct nlm_cookie; -/* Call this function with the BKL held (it uses a static buffer) */ -extern const char *nlmdbg_cookie2a(const struct nlm_cookie *); -#endif - #endif /* LINUX_LOCKD_DEBUG_H */ -- cgit v1.2.3 From 8111f373600cd43b3198b48b9238e3ad2fd9908d Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Tue, 14 Dec 2010 14:58:01 +0000 Subject: NFS: Fix hdrlen calculation in NFSv4's decode_read() When computing the length of the header, be sure to include the four octets consumed by "count". Signed-off-by: Chuck Lever Tested-by: J. Bruce Fields Signed-off-by: Trond Myklebust --- fs/nfs/nfs4xdr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index a48a43c75111..868815c55450 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c @@ -4475,7 +4475,7 @@ static int decode_read(struct xdr_stream *xdr, struct rpc_rqst *req, struct nfs_ goto out_overflow; eof = be32_to_cpup(p++); count = be32_to_cpup(p); - hdrlen = (u8 *) p - (u8 *) iov->iov_base; + hdrlen = (u8 *) xdr->p - (u8 *) iov->iov_base; recvd = req->rq_rcv_buf.len - hdrlen; if (count > recvd) { dprintk("NFS: server cheating in read reply: " -- cgit v1.2.3 From 573c4e1ef53a6b891b73cc2257e1604da754a2e4 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Tue, 14 Dec 2010 14:58:11 +0000 Subject: NFS: Simplify ->decode_dirent() calling sequence Clean up. The pointer returned by ->decode_dirent() is no longer used as a pointer. The only call site (xdr_decode() in fs/nfs/dir.c) simply extracts the errno value encoded in the pointer. Replace the returned pointer with a standard integer errno return value. Also, pass the "server" argument as part of the nfs_entry instead of as a separate parameter. It's faster to derive "server" in nfs_readdir_xdr_to_array() since we already have the directory's inode handy. "server" ought to be invariant for a set of entries in the same directory, right? The legacy versions of decode_dirent() don't use "server" anyway, so it's wasted work for them to derive and pass "server" for each entry. Signed-off-by: Chuck Lever Tested-by: J. Bruce Fields Signed-off-by: Trond Myklebust --- fs/nfs/dir.c | 15 ++++++++------- fs/nfs/internal.h | 9 ++++++--- fs/nfs/nfs2xdr.c | 18 +++++++++--------- fs/nfs/nfs3xdr.c | 28 ++++++++++++++-------------- fs/nfs/nfs4_fs.h | 1 - fs/nfs/nfs4xdr.c | 29 ++++++++++++++++++++++------- include/linux/nfs_xdr.h | 3 ++- 7 files changed, 61 insertions(+), 42 deletions(-) diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index 996dd8989a91..3e2123fe79f5 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c @@ -172,7 +172,7 @@ struct nfs_cache_array { struct nfs_cache_array_entry array[0]; }; -typedef __be32 * (*decode_dirent_t)(struct xdr_stream *, struct nfs_entry *, struct nfs_server *, int); +typedef int (*decode_dirent_t)(struct xdr_stream *, struct nfs_entry *, int); typedef struct { struct file *file; struct page *page; @@ -378,14 +378,14 @@ error: return error; } -/* Fill in an entry based on the xdr code stored in desc->page */ -static -int xdr_decode(nfs_readdir_descriptor_t *desc, struct nfs_entry *entry, struct xdr_stream *stream) +static int xdr_decode(nfs_readdir_descriptor_t *desc, + struct nfs_entry *entry, struct xdr_stream *xdr) { - __be32 *p = desc->decode(stream, entry, NFS_SERVER(desc->file->f_path.dentry->d_inode), desc->plus); - if (IS_ERR(p)) - return PTR_ERR(p); + int error; + error = desc->decode(xdr, entry, desc->plus); + if (error) + return error; entry->fattr->time_start = desc->timestamp; entry->fattr->gencount = desc->gencount; return 0; @@ -566,6 +566,7 @@ int nfs_readdir_xdr_to_array(nfs_readdir_descriptor_t *desc, struct page *page, entry.eof = 0; entry.fh = nfs_alloc_fhandle(); entry.fattr = nfs_alloc_fattr(); + entry.server = NFS_SERVER(inode); if (entry.fh == NULL || entry.fattr == NULL) goto out; diff --git a/fs/nfs/internal.h b/fs/nfs/internal.h index 6c6a9955bae9..435eae3666bd 100644 --- a/fs/nfs/internal.h +++ b/fs/nfs/internal.h @@ -187,15 +187,18 @@ extern void nfs_destroy_directcache(void); /* nfs2xdr.c */ extern int nfs_stat_to_errno(enum nfs_stat); extern struct rpc_procinfo nfs_procedures[]; -extern __be32 *nfs2_decode_dirent(struct xdr_stream *, struct nfs_entry *, struct nfs_server *, int); +extern int nfs2_decode_dirent(struct xdr_stream *, + struct nfs_entry *, int); /* nfs3xdr.c */ extern struct rpc_procinfo nfs3_procedures[]; -extern __be32 *nfs3_decode_dirent(struct xdr_stream *, struct nfs_entry *, struct nfs_server *, int); +extern int nfs3_decode_dirent(struct xdr_stream *, + struct nfs_entry *, int); /* nfs4xdr.c */ #ifdef CONFIG_NFS_V4 -extern __be32 *nfs4_decode_dirent(struct xdr_stream *, struct nfs_entry *, struct nfs_server *, int); +extern int nfs4_decode_dirent(struct xdr_stream *, + struct nfs_entry *, int); #endif #ifdef CONFIG_NFS_V4_1 extern const u32 nfs41_maxread_overhead; diff --git a/fs/nfs/nfs2xdr.c b/fs/nfs/nfs2xdr.c index 0343175fe6c0..a9b848edbd2e 100644 --- a/fs/nfs/nfs2xdr.c +++ b/fs/nfs/nfs2xdr.c @@ -936,10 +936,10 @@ static int nfs2_xdr_dec_writeres(struct rpc_rqst *req, __be32 *p, * the local page cache. * @xdr: XDR stream where entry resides * @entry: buffer to fill in with entry data - * @server: nfs_server data for this directory * @plus: boolean indicating whether this should be a readdirplus entry * - * Returns the position of the next item in the buffer, or an ERR_PTR. + * Returns zero if successful, otherwise a negative errno value is + * returned. * * This function is not invoked during READDIR reply decoding, but * rather whenever an application invokes the getdents(2) system call @@ -954,8 +954,8 @@ static int nfs2_xdr_dec_writeres(struct rpc_rqst *req, __be32 *p, * entry *nextentry; * }; */ -__be32 *nfs2_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry, - struct nfs_server *server, int plus) +int nfs2_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry, + int plus) { __be32 *p; int error; @@ -968,9 +968,9 @@ __be32 *nfs2_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry, if (unlikely(p == NULL)) goto out_overflow; if (*p++ == xdr_zero) - return ERR_PTR(-EAGAIN); + return -EAGAIN; entry->eof = 1; - return ERR_PTR(-EBADCOOKIE); + return -EBADCOOKIE; } p = xdr_inline_decode(xdr, 4); @@ -980,7 +980,7 @@ __be32 *nfs2_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry, error = decode_filename_inline(xdr, &entry->name, &entry->len); if (unlikely(error)) - return ERR_PTR(error); + return error; /* * The type (size and byte order) of nfscookie isn't defined in @@ -999,11 +999,11 @@ __be32 *nfs2_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry, entry->eof = 0; if (p != NULL) entry->eof = (p[0] == xdr_zero) && (p[1] != xdr_zero); - return p; + return 0; out_overflow: print_overflow_msg(__func__, xdr); - return ERR_PTR(-EAGAIN); + return -EAGAIN; } /* diff --git a/fs/nfs/nfs3xdr.c b/fs/nfs/nfs3xdr.c index c97d00fe849a..15c93ccd90c5 100644 --- a/fs/nfs/nfs3xdr.c +++ b/fs/nfs/nfs3xdr.c @@ -1970,10 +1970,10 @@ out_status: * the local page cache * @xdr: XDR stream where entry resides * @entry: buffer to fill in with entry data - * @server: nfs_server data for this directory * @plus: boolean indicating whether this should be a readdirplus entry * - * Returns the position of the next item in the buffer, or an ERR_PTR. + * Returns zero if successful, otherwise a negative errno value is + * returned. * * This function is not invoked during READDIR reply decoding, but * rather whenever an application invokes the getdents(2) system call @@ -2000,8 +2000,8 @@ out_status: * entryplus3 *nextentry; * }; */ -__be32 *nfs3_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry, - struct nfs_server *server, int plus) +int nfs3_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry, + int plus) { struct nfs_entry old = *entry; __be32 *p; @@ -2015,23 +2015,23 @@ __be32 *nfs3_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry, if (unlikely(p == NULL)) goto out_overflow; if (*p == xdr_zero) - return ERR_PTR(-EAGAIN); + return -EAGAIN; entry->eof = 1; - return ERR_PTR(-EBADCOOKIE); + return -EBADCOOKIE; } error = decode_fileid3(xdr, &entry->ino); if (unlikely(error)) - return ERR_PTR(error); + return error; error = decode_inline_filename3(xdr, &entry->name, &entry->len); if (unlikely(error)) - return ERR_PTR(error); + return error; entry->prev_cookie = entry->cookie; error = decode_cookie3(xdr, &entry->cookie); if (unlikely(error)) - return ERR_PTR(error); + return error; entry->d_type = DT_UNKNOWN; @@ -2039,7 +2039,7 @@ __be32 *nfs3_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry, entry->fattr->valid = 0; error = decode_post_op_attr(xdr, entry->fattr); if (unlikely(error)) - return ERR_PTR(error); + return error; if (entry->fattr->valid & NFS_ATTR_FATTR_V3) entry->d_type = nfs_umode_to_dtype(entry->fattr->mode); @@ -2052,7 +2052,7 @@ __be32 *nfs3_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry, if (unlikely(error)) { if (error == -E2BIG) goto out_truncated; - return ERR_PTR(error); + return error; } } else zero_nfs_fh3(entry->fh); @@ -2063,15 +2063,15 @@ __be32 *nfs3_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry, entry->eof = 0; if (p != NULL) entry->eof = (p[0] == xdr_zero) && (p[1] != xdr_zero); - return p; + return 0; out_overflow: print_overflow_msg(__func__, xdr); - return ERR_PTR(-EAGAIN); + return -EAGAIN; out_truncated: dprintk("NFS: directory entry contains invalid file handle\n"); *entry = old; - return ERR_PTR(-EAGAIN); + return -EAGAIN; } /* diff --git a/fs/nfs/nfs4_fs.h b/fs/nfs/nfs4_fs.h index 9fa496387fdf..7a6eecffcaeb 100644 --- a/fs/nfs/nfs4_fs.h +++ b/fs/nfs/nfs4_fs.h @@ -331,7 +331,6 @@ extern void nfs_free_seqid(struct nfs_seqid *seqid); extern const nfs4_stateid zero_stateid; /* nfs4xdr.c */ -extern __be32 *nfs4_decode_dirent(struct xdr_stream *, struct nfs_entry *, struct nfs_server *, int); extern struct rpc_procinfo nfs4_procedures[]; struct nfs4_mount_data; diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index 868815c55450..be9f00ab0d18 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c @@ -6159,8 +6159,22 @@ out: } #endif /* CONFIG_NFS_V4_1 */ -__be32 *nfs4_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry, - struct nfs_server *server, int plus) +/** + * nfs4_decode_dirent - Decode a single NFSv4 directory entry stored in + * the local page cache. + * @xdr: XDR stream where entry resides + * @entry: buffer to fill in with entry data + * @plus: boolean indicating whether this should be a readdirplus entry + * + * Returns zero if successful, otherwise a negative errno value is + * returned. + * + * This function is not invoked during READDIR reply decoding, but + * rather whenever an application invokes the getdents(2) system call + * on a directory already in our cache. + */ +int nfs4_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry, + int plus) { uint32_t bitmap[2] = {0}; uint32_t len; @@ -6172,9 +6186,9 @@ __be32 *nfs4_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry, if (unlikely(!p)) goto out_overflow; if (!ntohl(*p++)) - return ERR_PTR(-EAGAIN); + return -EAGAIN; entry->eof = 1; - return ERR_PTR(-EBADCOOKIE); + return -EBADCOOKIE; } p = xdr_inline_decode(xdr, 12); @@ -6203,7 +6217,8 @@ __be32 *nfs4_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry, if (decode_attr_length(xdr, &len, &p) < 0) goto out_overflow; - if (decode_getfattr_attrs(xdr, bitmap, entry->fattr, entry->fh, server, 1) < 0) + if (decode_getfattr_attrs(xdr, bitmap, entry->fattr, entry->fh, + entry->server, 1) < 0) goto out_overflow; if (entry->fattr->valid & NFS_ATTR_FATTR_FILEID) entry->ino = entry->fattr->fileid; @@ -6221,11 +6236,11 @@ __be32 *nfs4_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry, else entry->eof = 0; - return p; + return 0; out_overflow: print_overflow_msg(__func__, xdr); - return ERR_PTR(-EAGAIN); + return -EAGAIN; } /* diff --git a/include/linux/nfs_xdr.h b/include/linux/nfs_xdr.h index 80f07198a31a..236e7e4b99a0 100644 --- a/include/linux/nfs_xdr.h +++ b/include/linux/nfs_xdr.h @@ -484,6 +484,7 @@ struct nfs_entry { struct nfs_fh * fh; struct nfs_fattr * fattr; unsigned char d_type; + struct nfs_server * server; }; /* @@ -1089,7 +1090,7 @@ struct nfs_rpc_ops { int (*pathconf) (struct nfs_server *, struct nfs_fh *, struct nfs_pathconf *); int (*set_capabilities)(struct nfs_server *, struct nfs_fh *); - __be32 *(*decode_dirent)(struct xdr_stream *, struct nfs_entry *, struct nfs_server *, int plus); + int (*decode_dirent)(struct xdr_stream *, struct nfs_entry *, int); void (*read_setup) (struct nfs_read_data *, struct rpc_message *); int (*read_done) (struct rpc_task *, struct nfs_read_data *); void (*write_setup) (struct nfs_write_data *, struct rpc_message *); -- cgit v1.2.3 From ead00597882c4ee3c534d6880cc3bcb4d412cc4b Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Tue, 14 Dec 2010 14:58:21 +0000 Subject: NFS: Squelch compiler warning in decode_getdeviceinfo() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Clean up. .../linux/nfs-2.6/fs/nfs/nfs4xdr.c: In function ‘decode_getdeviceinfo’: .../linux/nfs-2.6/fs/nfs/nfs4xdr.c:5008: warning: comparison between signed and unsigned integer expressions Signed-off-by: Chuck Lever Tested-by: J. Bruce Fields Signed-off-by: Trond Myklebust --- fs/nfs/nfs4xdr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index be9f00ab0d18..a15fe99fea86 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c @@ -5000,7 +5000,7 @@ static int decode_getdeviceinfo(struct xdr_stream *xdr, goto out_overflow; len = be32_to_cpup(p); if (len) { - int i; + uint32_t i; p = xdr_inline_decode(xdr, 4 * len); if (unlikely(!p)) -- cgit v1.2.3 From 49b170047f4a9fe1483132e14a11bdf493bdb8af Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Tue, 14 Dec 2010 14:58:30 +0000 Subject: NSM: Avoid return code checking in NSM XDR encoder functions Clean up. The trend in the other XDR encoder functions is to BUG() when encoding problems occur, since a problem here is always due to a local coding error. Then, instead of a status, zero is unconditionally returned. Update the NSM XDR encoders to behave this way. To finish the update, use the new-style be32_to_cpup() and cpu_to_be32() macros, and compute the buffer sizes using raw integers instead of sizeof(). This matches the conventions used in other XDR functions Signed-off-by: Chuck Lever Tested-by: J. Bruce Fields Signed-off-by: Trond Myklebust --- fs/lockd/mon.c | 68 +++++++++++++++++++++------------------------------------- 1 file changed, 25 insertions(+), 43 deletions(-) diff --git a/fs/lockd/mon.c b/fs/lockd/mon.c index e0c918949644..d812818d0258 100644 --- a/fs/lockd/mon.c +++ b/fs/lockd/mon.c @@ -401,26 +401,22 @@ void nsm_release(struct nsm_handle *nsm) * Status Monitor wire protocol. */ -static int encode_nsm_string(struct xdr_stream *xdr, const char *string) +static void encode_nsm_string(struct xdr_stream *xdr, const char *string) { const u32 len = strlen(string); __be32 *p; - if (unlikely(len > SM_MAXSTRLEN)) - return -EIO; - p = xdr_reserve_space(xdr, sizeof(u32) + len); - if (unlikely(p == NULL)) - return -EIO; + BUG_ON(len > SM_MAXSTRLEN); + p = xdr_reserve_space(xdr, 4 + len); xdr_encode_opaque(p, string, len); - return 0; } /* * "mon_name" specifies the host to be monitored. */ -static int encode_mon_name(struct xdr_stream *xdr, const struct nsm_args *argp) +static void encode_mon_name(struct xdr_stream *xdr, const struct nsm_args *argp) { - return encode_nsm_string(xdr, argp->mon_name); + encode_nsm_string(xdr, argp->mon_name); } /* @@ -429,35 +425,25 @@ static int encode_mon_name(struct xdr_stream *xdr, const struct nsm_args *argp) * (via the NLMPROC_SM_NOTIFY call) that the state of host "mon_name" * has changed. */ -static int encode_my_id(struct xdr_stream *xdr, const struct nsm_args *argp) +static void encode_my_id(struct xdr_stream *xdr, const struct nsm_args *argp) { - int status; __be32 *p; - status = encode_nsm_string(xdr, utsname()->nodename); - if (unlikely(status != 0)) - return status; - p = xdr_reserve_space(xdr, 3 * sizeof(u32)); - if (unlikely(p == NULL)) - return -EIO; - *p++ = htonl(argp->prog); - *p++ = htonl(argp->vers); - *p++ = htonl(argp->proc); - return 0; + encode_nsm_string(xdr, utsname()->nodename); + p = xdr_reserve_space(xdr, 4 + 4 + 4); + *p++ = cpu_to_be32(argp->prog); + *p++ = cpu_to_be32(argp->vers); + *p = cpu_to_be32(argp->proc); } /* * The "mon_id" argument specifies the non-private arguments * of an NSMPROC_MON or NSMPROC_UNMON call. */ -static int encode_mon_id(struct xdr_stream *xdr, const struct nsm_args *argp) +static void encode_mon_id(struct xdr_stream *xdr, const struct nsm_args *argp) { - int status; - - status = encode_mon_name(xdr, argp); - if (unlikely(status != 0)) - return status; - return encode_my_id(xdr, argp); + encode_mon_name(xdr, argp); + encode_my_id(xdr, argp); } /* @@ -465,28 +451,23 @@ static int encode_mon_id(struct xdr_stream *xdr, const struct nsm_args *argp) * by the NSMPROC_MON call. This information will be supplied in the * NLMPROC_SM_NOTIFY call. */ -static int encode_priv(struct xdr_stream *xdr, const struct nsm_args *argp) +static void encode_priv(struct xdr_stream *xdr, const struct nsm_args *argp) { __be32 *p; p = xdr_reserve_space(xdr, SM_PRIV_SIZE); - if (unlikely(p == NULL)) - return -EIO; xdr_encode_opaque_fixed(p, argp->priv->data, SM_PRIV_SIZE); - return 0; } static int xdr_enc_mon(struct rpc_rqst *req, __be32 *p, const struct nsm_args *argp) { struct xdr_stream xdr; - int status; xdr_init_encode(&xdr, &req->rq_snd_buf, p); - status = encode_mon_id(&xdr, argp); - if (unlikely(status)) - return status; - return encode_priv(&xdr, argp); + encode_mon_id(&xdr, argp); + encode_priv(&xdr, argp); + return 0; } static int xdr_enc_unmon(struct rpc_rqst *req, __be32 *p, @@ -495,7 +476,8 @@ static int xdr_enc_unmon(struct rpc_rqst *req, __be32 *p, struct xdr_stream xdr; xdr_init_encode(&xdr, &req->rq_snd_buf, p); - return encode_mon_id(&xdr, argp); + encode_mon_id(&xdr, argp); + return 0; } static int xdr_dec_stat_res(struct rpc_rqst *rqstp, __be32 *p, @@ -504,11 +486,11 @@ static int xdr_dec_stat_res(struct rpc_rqst *rqstp, __be32 *p, struct xdr_stream xdr; xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p); - p = xdr_inline_decode(&xdr, 2 * sizeof(u32)); + p = xdr_inline_decode(&xdr, 4 + 4); if (unlikely(p == NULL)) return -EIO; - resp->status = ntohl(*p++); - resp->state = ntohl(*p); + resp->status = be32_to_cpup(p++); + resp->state = be32_to_cpup(p); dprintk("lockd: xdr_dec_stat_res status %d state %d\n", resp->status, resp->state); @@ -521,10 +503,10 @@ static int xdr_dec_stat(struct rpc_rqst *rqstp, __be32 *p, struct xdr_stream xdr; xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p); - p = xdr_inline_decode(&xdr, sizeof(u32)); + p = xdr_inline_decode(&xdr, 4); if (unlikely(p == NULL)) return -EIO; - resp->state = ntohl(*p); + resp->state = be32_to_cpup(p); dprintk("lockd: xdr_dec_stat state %d\n", resp->state); return 0; -- cgit v1.2.3 From 98eb2b4f9323bcf2a46476576d3155758cb0a473 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Tue, 14 Dec 2010 14:58:40 +0000 Subject: NFS: Avoid return code checking in mount XDR encoder functions Clean up. The trend in the other XDR encoder functions is to BUG() when encoding problems occur, since a problem here is always due to a local coding error. Then, instead of a status, zero is unconditionally returned. Update the mount client XDR encoders to behave this way. To finish the update, use the new-style be32_to_cpup() and cpu_to_be32() macros, and compute the buffer sizes using raw integers instead of sizeof(). This matches the conventions used in other XDR functions. Signed-off-by: Chuck Lever Tested-by: J. Bruce Fields Signed-off-by: Trond Myklebust --- fs/nfs/mount_clnt.c | 35 +++++++++++++++-------------------- 1 file changed, 15 insertions(+), 20 deletions(-) diff --git a/fs/nfs/mount_clnt.c b/fs/nfs/mount_clnt.c index 4f981f1f6689..c82547e49ba1 100644 --- a/fs/nfs/mount_clnt.c +++ b/fs/nfs/mount_clnt.c @@ -280,20 +280,14 @@ out_call_err: * XDR encode/decode functions for MOUNT */ -static int encode_mntdirpath(struct xdr_stream *xdr, const char *pathname) +static void encode_mntdirpath(struct xdr_stream *xdr, const char *pathname) { const u32 pathname_len = strlen(pathname); __be32 *p; - if (unlikely(pathname_len > MNTPATHLEN)) - return -EIO; - - p = xdr_reserve_space(xdr, sizeof(u32) + pathname_len); - if (unlikely(p == NULL)) - return -EIO; + BUG_ON(pathname_len > MNTPATHLEN); + p = xdr_reserve_space(xdr, 4 + pathname_len); xdr_encode_opaque(p, pathname, pathname_len); - - return 0; } static int mnt_enc_dirpath(struct rpc_rqst *req, __be32 *p, @@ -302,7 +296,8 @@ static int mnt_enc_dirpath(struct rpc_rqst *req, __be32 *p, struct xdr_stream xdr; xdr_init_encode(&xdr, &req->rq_snd_buf, p); - return encode_mntdirpath(&xdr, dirpath); + encode_mntdirpath(&xdr, dirpath); + return 0; } /* @@ -320,10 +315,10 @@ static int decode_status(struct xdr_stream *xdr, struct mountres *res) u32 status; __be32 *p; - p = xdr_inline_decode(xdr, sizeof(status)); + p = xdr_inline_decode(xdr, 4); if (unlikely(p == NULL)) return -EIO; - status = ntohl(*p); + status = be32_to_cpup(p); for (i = 0; i < ARRAY_SIZE(mnt_errtbl); i++) { if (mnt_errtbl[i].status == status) { @@ -371,10 +366,10 @@ static int decode_fhs_status(struct xdr_stream *xdr, struct mountres *res) u32 status; __be32 *p; - p = xdr_inline_decode(xdr, sizeof(status)); + p = xdr_inline_decode(xdr, 4); if (unlikely(p == NULL)) return -EIO; - status = ntohl(*p); + status = be32_to_cpup(p); for (i = 0; i < ARRAY_SIZE(mnt3_errtbl); i++) { if (mnt3_errtbl[i].status == status) { @@ -394,11 +389,11 @@ static int decode_fhandle3(struct xdr_stream *xdr, struct mountres *res) u32 size; __be32 *p; - p = xdr_inline_decode(xdr, sizeof(size)); + p = xdr_inline_decode(xdr, 4); if (unlikely(p == NULL)) return -EIO; - size = ntohl(*p++); + size = be32_to_cpup(p); if (size > NFS3_FHSIZE || size == 0) return -EIO; @@ -421,15 +416,15 @@ static int decode_auth_flavors(struct xdr_stream *xdr, struct mountres *res) if (*count == 0) return 0; - p = xdr_inline_decode(xdr, sizeof(entries)); + p = xdr_inline_decode(xdr, 4); if (unlikely(p == NULL)) return -EIO; - entries = ntohl(*p); + entries = be32_to_cpup(p); dprintk("NFS: received %u auth flavors\n", entries); if (entries > NFS_MAX_SECFLAVORS) entries = NFS_MAX_SECFLAVORS; - p = xdr_inline_decode(xdr, sizeof(u32) * entries); + p = xdr_inline_decode(xdr, 4 * entries); if (unlikely(p == NULL)) return -EIO; @@ -437,7 +432,7 @@ static int decode_auth_flavors(struct xdr_stream *xdr, struct mountres *res) entries = *count; for (i = 0; i < entries; i++) { - flavors[i] = ntohl(*p++); + flavors[i] = be32_to_cpup(p++); dprintk("NFS: auth flavor[%u]: %d\n", i, flavors[i]); } *count = i; -- cgit v1.2.3 From b43cd8c153f6902100ed50c1f7e11a470c73a73f Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Tue, 14 Dec 2010 14:58:49 +0000 Subject: NFS: Remove unused UMNT response data structure Clean up. The UMNT request has a NULL response. There's no need to set up a mountres structure for it. Signed-off-by: Chuck Lever Signed-off-by: Trond Myklebust --- fs/nfs/mount_clnt.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/fs/nfs/mount_clnt.c b/fs/nfs/mount_clnt.c index c82547e49ba1..97c3ec793305 100644 --- a/fs/nfs/mount_clnt.c +++ b/fs/nfs/mount_clnt.c @@ -236,10 +236,8 @@ void nfs_umount(const struct nfs_mount_request *info) .authflavor = RPC_AUTH_UNIX, .flags = RPC_CLNT_CREATE_NOPING, }; - struct mountres result; struct rpc_message msg = { .rpc_argp = info->dirpath, - .rpc_resp = &result, }; struct rpc_clnt *clnt; int status; -- cgit v1.2.3 From 4129ccf303593a1922a934697f99e682ff491504 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Tue, 14 Dec 2010 14:58:59 +0000 Subject: SUNRPC: Avoid return code checking in rpcbind XDR encoder functions Clean up. The trend in the other XDR encoder functions is to BUG() when encoding problems occur, since a problem here is always due to a local coding error. Then, instead of a status, zero is unconditionally returned. Update the rpcbind XDR encoders to behave this way. To finish the update, use the new-style be32_to_cpup() and cpu_to_be32() macros, and compute the buffer sizes using raw integers instead of sizeof(). This matches the conventions used in other XDR functions. Signed-off-by: Chuck Lever Tested-by: J. Bruce Fields Signed-off-by: Trond Myklebust --- net/sunrpc/rpcb_clnt.c | 60 ++++++++++++++++++-------------------------------- 1 file changed, 21 insertions(+), 39 deletions(-) diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c index fa6d7ca2c851..d2a2ea090f95 100644 --- a/net/sunrpc/rpcb_clnt.c +++ b/net/sunrpc/rpcb_clnt.c @@ -705,14 +705,11 @@ static int rpcb_enc_mapping(struct rpc_rqst *req, __be32 *p, xdr_init_encode(&xdr, &req->rq_snd_buf, p); - p = xdr_reserve_space(&xdr, sizeof(__be32) * RPCB_mappingargs_sz); - if (unlikely(p == NULL)) - return -EIO; - - *p++ = htonl(rpcb->r_prog); - *p++ = htonl(rpcb->r_vers); - *p++ = htonl(rpcb->r_prot); - *p = htonl(rpcb->r_port); + p = xdr_reserve_space(&xdr, RPCB_mappingargs_sz << 2); + *p++ = cpu_to_be32(rpcb->r_prog); + *p++ = cpu_to_be32(rpcb->r_vers); + *p++ = cpu_to_be32(rpcb->r_prot); + *p = cpu_to_be32(rpcb->r_port); return 0; } @@ -728,11 +725,11 @@ static int rpcb_dec_getport(struct rpc_rqst *req, __be32 *p, rpcb->r_port = 0; - p = xdr_inline_decode(&xdr, sizeof(__be32)); + p = xdr_inline_decode(&xdr, 4); if (unlikely(p == NULL)) return -EIO; - port = ntohl(*p); + port = be32_to_cpup(p); dprintk("RPC: %5u PMAP_%s result: %lu\n", task->tk_pid, task->tk_msg.rpc_proc->p_name, port); if (unlikely(port > USHRT_MAX)) @@ -750,7 +747,7 @@ static int rpcb_dec_set(struct rpc_rqst *req, __be32 *p, xdr_init_decode(&xdr, &req->rq_rcv_buf, p); - p = xdr_inline_decode(&xdr, sizeof(__be32)); + p = xdr_inline_decode(&xdr, 4); if (unlikely(p == NULL)) return -EIO; @@ -764,24 +761,16 @@ static int rpcb_dec_set(struct rpc_rqst *req, __be32 *p, return 0; } -static int encode_rpcb_string(struct xdr_stream *xdr, const char *string, - const u32 maxstrlen) +static void encode_rpcb_string(struct xdr_stream *xdr, const char *string, + const u32 maxstrlen) { - u32 len; __be32 *p; + u32 len; - if (unlikely(string == NULL)) - return -EIO; len = strlen(string); - if (unlikely(len > maxstrlen)) - return -EIO; - - p = xdr_reserve_space(xdr, sizeof(__be32) + len); - if (unlikely(p == NULL)) - return -EIO; + BUG_ON(len > maxstrlen); + p = xdr_reserve_space(xdr, 4 + len); xdr_encode_opaque(p, string, len); - - return 0; } static int rpcb_enc_getaddr(struct rpc_rqst *req, __be32 *p, @@ -797,20 +786,13 @@ static int rpcb_enc_getaddr(struct rpc_rqst *req, __be32 *p, xdr_init_encode(&xdr, &req->rq_snd_buf, p); - p = xdr_reserve_space(&xdr, - sizeof(__be32) * (RPCB_program_sz + RPCB_version_sz)); - if (unlikely(p == NULL)) - return -EIO; - *p++ = htonl(rpcb->r_prog); - *p = htonl(rpcb->r_vers); - - if (encode_rpcb_string(&xdr, rpcb->r_netid, RPCBIND_MAXNETIDLEN)) - return -EIO; - if (encode_rpcb_string(&xdr, rpcb->r_addr, RPCBIND_MAXUADDRLEN)) - return -EIO; - if (encode_rpcb_string(&xdr, rpcb->r_owner, RPCB_MAXOWNERLEN)) - return -EIO; + p = xdr_reserve_space(&xdr, (RPCB_program_sz + RPCB_version_sz) << 2); + *p++ = cpu_to_be32(rpcb->r_prog); + *p = cpu_to_be32(rpcb->r_vers); + encode_rpcb_string(&xdr, rpcb->r_netid, RPCBIND_MAXNETIDLEN); + encode_rpcb_string(&xdr, rpcb->r_addr, RPCBIND_MAXUADDRLEN); + encode_rpcb_string(&xdr, rpcb->r_owner, RPCB_MAXOWNERLEN); return 0; } @@ -827,10 +809,10 @@ static int rpcb_dec_getaddr(struct rpc_rqst *req, __be32 *p, xdr_init_decode(&xdr, &req->rq_rcv_buf, p); - p = xdr_inline_decode(&xdr, sizeof(__be32)); + p = xdr_inline_decode(&xdr, 4); if (unlikely(p == NULL)) goto out_fail; - len = ntohl(*p); + len = be32_to_cpup(p); /* * If the returned universal address is a null string, -- cgit v1.2.3 From 1ac7c23e4af5e83525137661595000099f1ce94f Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Tue, 14 Dec 2010 14:59:09 +0000 Subject: SUNRPC: Determine value of "nrprocs" automatically Clean up. Just fixed a panic where the nrprocs field in a different upper layer client was set by hand incorrectly. Use the compiler-generated method used by the other upper layer protocols. Signed-off-by: Chuck Lever Signed-off-by: Trond Myklebust --- net/sunrpc/rpcb_clnt.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c index d2a2ea090f95..43838c72b778 100644 --- a/net/sunrpc/rpcb_clnt.c +++ b/net/sunrpc/rpcb_clnt.c @@ -57,10 +57,6 @@ enum { RPCBPROC_GETSTAT, }; -#define RPCB_HIGHPROC_2 RPCBPROC_CALLIT -#define RPCB_HIGHPROC_3 RPCBPROC_TADDR2UADDR -#define RPCB_HIGHPROC_4 RPCBPROC_GETSTAT - /* * r_owner * @@ -975,19 +971,19 @@ static struct rpcb_info rpcb_next_version6[] = { static struct rpc_version rpcb_version2 = { .number = RPCBVERS_2, - .nrprocs = RPCB_HIGHPROC_2, + .nrprocs = ARRAY_SIZE(rpcb_procedures2), .procs = rpcb_procedures2 }; static struct rpc_version rpcb_version3 = { .number = RPCBVERS_3, - .nrprocs = RPCB_HIGHPROC_3, + .nrprocs = ARRAY_SIZE(rpcb_procedures3), .procs = rpcb_procedures3 }; static struct rpc_version rpcb_version4 = { .number = RPCBVERS_4, - .nrprocs = RPCB_HIGHPROC_4, + .nrprocs = ARRAY_SIZE(rpcb_procedures4), .procs = rpcb_procedures4 }; -- cgit v1.2.3 From 9f06c719f474be7003763284a990bed6377bb0d4 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Tue, 14 Dec 2010 14:59:18 +0000 Subject: SUNRPC: New xdr_streams XDR encoder API Now that all client-side XDR encoder routines use xdr_streams, there should be no need to support the legacy calling sequence [rpc_rqst *, __be32 *, RPC arg *] anywhere. We can construct an xdr_stream in the generic RPC code, instead of in each encoder function. Also, all the client-side encoder functions return 0 now, making a return value superfluous. Take this opportunity to convert them to return void instead. This is a refactoring change. It should not cause different behavior. Signed-off-by: Chuck Lever Tested-by: J. Bruce Fields Signed-off-by: Trond Myklebust --- fs/lockd/clnt4xdr.c | 92 +++--- fs/lockd/clntxdr.c | 92 +++--- fs/lockd/mon.c | 26 +- fs/nfs/mount_clnt.c | 18 +- fs/nfs/nfs2xdr.c | 147 ++++----- fs/nfs/nfs3xdr.c | 241 ++++++--------- fs/nfs/nfs4xdr.c | 663 ++++++++++++++++++----------------------- fs/nfsd/nfs4callback.c | 22 +- include/linux/sunrpc/auth.h | 4 +- include/linux/sunrpc/clnt.h | 2 +- include/linux/sunrpc/xdr.h | 9 +- net/sunrpc/auth.c | 14 +- net/sunrpc/auth_gss/auth_gss.c | 31 +- net/sunrpc/clnt.c | 5 +- net/sunrpc/rpcb_clnt.c | 47 ++- 15 files changed, 606 insertions(+), 807 deletions(-) diff --git a/fs/lockd/clnt4xdr.c b/fs/lockd/clnt4xdr.c index 1a1c3e21ed2c..974f1d9cd323 100644 --- a/fs/lockd/clnt4xdr.c +++ b/fs/lockd/clnt4xdr.c @@ -385,17 +385,15 @@ static void encode_nlm4_lock(struct xdr_stream *xdr, * struct nlm4_lock alock; * }; */ -static int nlm4_xdr_enc_testargs(struct rpc_rqst *req, __be32 *p, - const struct nlm_args *args) +static void nlm4_xdr_enc_testargs(struct rpc_rqst *req, + struct xdr_stream *xdr, + const struct nlm_args *args) { const struct nlm_lock *lock = &args->lock; - struct xdr_stream xdr; - xdr_init_encode(&xdr, &req->rq_snd_buf, p); - encode_cookie(&xdr, &args->cookie); - encode_bool(&xdr, lock->fl.fl_type == F_WRLCK); - encode_nlm4_lock(&xdr, lock); - return 0; + encode_cookie(xdr, &args->cookie); + encode_bool(xdr, lock->fl.fl_type == F_WRLCK); + encode_nlm4_lock(xdr, lock); } /* @@ -408,20 +406,18 @@ static int nlm4_xdr_enc_testargs(struct rpc_rqst *req, __be32 *p, * int state; * }; */ -static int nlm4_xdr_enc_lockargs(struct rpc_rqst *req, __be32 *p, - const struct nlm_args *args) +static void nlm4_xdr_enc_lockargs(struct rpc_rqst *req, + struct xdr_stream *xdr, + const struct nlm_args *args) { const struct nlm_lock *lock = &args->lock; - struct xdr_stream xdr; - xdr_init_encode(&xdr, &req->rq_snd_buf, p); - encode_cookie(&xdr, &args->cookie); - encode_bool(&xdr, args->block); - encode_bool(&xdr, lock->fl.fl_type == F_WRLCK); - encode_nlm4_lock(&xdr, lock); - encode_bool(&xdr, args->reclaim); - encode_int32(&xdr, args->state); - return 0; + encode_cookie(xdr, &args->cookie); + encode_bool(xdr, args->block); + encode_bool(xdr, lock->fl.fl_type == F_WRLCK); + encode_nlm4_lock(xdr, lock); + encode_bool(xdr, args->reclaim); + encode_int32(xdr, args->state); } /* @@ -432,18 +428,16 @@ static int nlm4_xdr_enc_lockargs(struct rpc_rqst *req, __be32 *p, * struct nlm4_lock alock; * }; */ -static int nlm4_xdr_enc_cancargs(struct rpc_rqst *req, __be32 *p, - const struct nlm_args *args) +static void nlm4_xdr_enc_cancargs(struct rpc_rqst *req, + struct xdr_stream *xdr, + const struct nlm_args *args) { const struct nlm_lock *lock = &args->lock; - struct xdr_stream xdr; - xdr_init_encode(&xdr, &req->rq_snd_buf, p); - encode_cookie(&xdr, &args->cookie); - encode_bool(&xdr, args->block); - encode_bool(&xdr, lock->fl.fl_type == F_WRLCK); - encode_nlm4_lock(&xdr, lock); - return 0; + encode_cookie(xdr, &args->cookie); + encode_bool(xdr, args->block); + encode_bool(xdr, lock->fl.fl_type == F_WRLCK); + encode_nlm4_lock(xdr, lock); } /* @@ -452,16 +446,14 @@ static int nlm4_xdr_enc_cancargs(struct rpc_rqst *req, __be32 *p, * struct nlm4_lock alock; * }; */ -static int nlm4_xdr_enc_unlockargs(struct rpc_rqst *req, __be32 *p, - const struct nlm_args *args) +static void nlm4_xdr_enc_unlockargs(struct rpc_rqst *req, + struct xdr_stream *xdr, + const struct nlm_args *args) { const struct nlm_lock *lock = &args->lock; - struct xdr_stream xdr; - xdr_init_encode(&xdr, &req->rq_snd_buf, p); - encode_cookie(&xdr, &args->cookie); - encode_nlm4_lock(&xdr, lock); - return 0; + encode_cookie(xdr, &args->cookie); + encode_nlm4_lock(xdr, lock); } /* @@ -470,15 +462,12 @@ static int nlm4_xdr_enc_unlockargs(struct rpc_rqst *req, __be32 *p, * nlm4_stat stat; * }; */ -static int nlm4_xdr_enc_res(struct rpc_rqst *req, __be32 *p, - const struct nlm_res *result) +static void nlm4_xdr_enc_res(struct rpc_rqst *req, + struct xdr_stream *xdr, + const struct nlm_res *result) { - struct xdr_stream xdr; - - xdr_init_encode(&xdr, &req->rq_snd_buf, p); - encode_cookie(&xdr, &result->cookie); - encode_nlm4_stat(&xdr, result->status); - return 0; + encode_cookie(xdr, &result->cookie); + encode_nlm4_stat(xdr, result->status); } /* @@ -494,17 +483,14 @@ static int nlm4_xdr_enc_res(struct rpc_rqst *req, __be32 *p, * nlm4_testrply test_stat; * }; */ -static int nlm4_xdr_enc_testres(struct rpc_rqst *req, __be32 *p, - const struct nlm_res *result) +static void nlm4_xdr_enc_testres(struct rpc_rqst *req, + struct xdr_stream *xdr, + const struct nlm_res *result) { - struct xdr_stream xdr; - - xdr_init_encode(&xdr, &req->rq_snd_buf, p); - encode_cookie(&xdr, &result->cookie); - encode_nlm4_stat(&xdr, result->status); + encode_cookie(xdr, &result->cookie); + encode_nlm4_stat(xdr, result->status); if (result->status == nlm_lck_denied) - encode_nlm4_holder(&xdr, result); - return 0; + encode_nlm4_holder(xdr, result); } @@ -588,7 +574,7 @@ out: #define PROC(proc, argtype, restype) \ [NLMPROC_##proc] = { \ .p_proc = NLMPROC_##proc, \ - .p_encode = (kxdrproc_t)nlm4_xdr_enc_##argtype, \ + .p_encode = (kxdreproc_t)nlm4_xdr_enc_##argtype, \ .p_decode = (kxdrproc_t)nlm4_xdr_dec_##restype, \ .p_arglen = NLM4_##argtype##_sz, \ .p_replen = NLM4_##restype##_sz, \ diff --git a/fs/lockd/clntxdr.c b/fs/lockd/clntxdr.c index 0472f2aff509..c6fda8fb1c5b 100644 --- a/fs/lockd/clntxdr.c +++ b/fs/lockd/clntxdr.c @@ -378,17 +378,15 @@ static void encode_nlm_lock(struct xdr_stream *xdr, * struct nlm_lock alock; * }; */ -static int nlm_xdr_enc_testargs(struct rpc_rqst *req, __be32 *p, - const struct nlm_args *args) +static void nlm_xdr_enc_testargs(struct rpc_rqst *req, + struct xdr_stream *xdr, + const struct nlm_args *args) { const struct nlm_lock *lock = &args->lock; - struct xdr_stream xdr; - xdr_init_encode(&xdr, &req->rq_snd_buf, p); - encode_cookie(&xdr, &args->cookie); - encode_bool(&xdr, lock->fl.fl_type == F_WRLCK); - encode_nlm_lock(&xdr, lock); - return 0; + encode_cookie(xdr, &args->cookie); + encode_bool(xdr, lock->fl.fl_type == F_WRLCK); + encode_nlm_lock(xdr, lock); } /* @@ -401,20 +399,18 @@ static int nlm_xdr_enc_testargs(struct rpc_rqst *req, __be32 *p, * int state; * }; */ -static int nlm_xdr_enc_lockargs(struct rpc_rqst *req, __be32 *p, - const struct nlm_args *args) +static void nlm_xdr_enc_lockargs(struct rpc_rqst *req, + struct xdr_stream *xdr, + const struct nlm_args *args) { const struct nlm_lock *lock = &args->lock; - struct xdr_stream xdr; - xdr_init_encode(&xdr, &req->rq_snd_buf, p); - encode_cookie(&xdr, &args->cookie); - encode_bool(&xdr, args->block); - encode_bool(&xdr, lock->fl.fl_type == F_WRLCK); - encode_nlm_lock(&xdr, lock); - encode_bool(&xdr, args->reclaim); - encode_int32(&xdr, args->state); - return 0; + encode_cookie(xdr, &args->cookie); + encode_bool(xdr, args->block); + encode_bool(xdr, lock->fl.fl_type == F_WRLCK); + encode_nlm_lock(xdr, lock); + encode_bool(xdr, args->reclaim); + encode_int32(xdr, args->state); } /* @@ -425,18 +421,16 @@ static int nlm_xdr_enc_lockargs(struct rpc_rqst *req, __be32 *p, * struct nlm_lock alock; * }; */ -static int nlm_xdr_enc_cancargs(struct rpc_rqst *req, __be32 *p, - const struct nlm_args *args) +static void nlm_xdr_enc_cancargs(struct rpc_rqst *req, + struct xdr_stream *xdr, + const struct nlm_args *args) { const struct nlm_lock *lock = &args->lock; - struct xdr_stream xdr; - xdr_init_encode(&xdr, &req->rq_snd_buf, p); - encode_cookie(&xdr, &args->cookie); - encode_bool(&xdr, args->block); - encode_bool(&xdr, lock->fl.fl_type == F_WRLCK); - encode_nlm_lock(&xdr, lock); - return 0; + encode_cookie(xdr, &args->cookie); + encode_bool(xdr, args->block); + encode_bool(xdr, lock->fl.fl_type == F_WRLCK); + encode_nlm_lock(xdr, lock); } /* @@ -445,16 +439,14 @@ static int nlm_xdr_enc_cancargs(struct rpc_rqst *req, __be32 *p, * struct nlm_lock alock; * }; */ -static int nlm_xdr_enc_unlockargs(struct rpc_rqst *req, __be32 *p, - const struct nlm_args *args) +static void nlm_xdr_enc_unlockargs(struct rpc_rqst *req, + struct xdr_stream *xdr, + const struct nlm_args *args) { const struct nlm_lock *lock = &args->lock; - struct xdr_stream xdr; - xdr_init_encode(&xdr, &req->rq_snd_buf, p); - encode_cookie(&xdr, &args->cookie); - encode_nlm_lock(&xdr, lock); - return 0; + encode_cookie(xdr, &args->cookie); + encode_nlm_lock(xdr, lock); } /* @@ -463,15 +455,12 @@ static int nlm_xdr_enc_unlockargs(struct rpc_rqst *req, __be32 *p, * nlm_stat stat; * }; */ -static int nlm_xdr_enc_res(struct rpc_rqst *req, __be32 *p, - const struct nlm_res *result) +static void nlm_xdr_enc_res(struct rpc_rqst *req, + struct xdr_stream *xdr, + const struct nlm_res *result) { - struct xdr_stream xdr; - - xdr_init_encode(&xdr, &req->rq_snd_buf, p); - encode_cookie(&xdr, &result->cookie); - encode_nlm_stat(&xdr, result->status); - return 0; + encode_cookie(xdr, &result->cookie); + encode_nlm_stat(xdr, result->status); } /* @@ -494,16 +483,13 @@ static void encode_nlm_testrply(struct xdr_stream *xdr, encode_nlm_holder(xdr, result); } -static int nlm_xdr_enc_testres(struct rpc_rqst *req, __be32 *p, - const struct nlm_res *result) +static void nlm_xdr_enc_testres(struct rpc_rqst *req, + struct xdr_stream *xdr, + const struct nlm_res *result) { - struct xdr_stream xdr; - - xdr_init_encode(&xdr, &req->rq_snd_buf, p); - encode_cookie(&xdr, &result->cookie); - encode_nlm_stat(&xdr, result->status); - encode_nlm_testrply(&xdr, result); - return 0; + encode_cookie(xdr, &result->cookie); + encode_nlm_stat(xdr, result->status); + encode_nlm_testrply(xdr, result); } @@ -586,7 +572,7 @@ out: #define PROC(proc, argtype, restype) \ [NLMPROC_##proc] = { \ .p_proc = NLMPROC_##proc, \ - .p_encode = (kxdrproc_t)nlm_xdr_enc_##argtype, \ + .p_encode = (kxdreproc_t)nlm_xdr_enc_##argtype, \ .p_decode = (kxdrproc_t)nlm_xdr_dec_##restype, \ .p_arglen = NLM_##argtype##_sz, \ .p_replen = NLM_##restype##_sz, \ diff --git a/fs/lockd/mon.c b/fs/lockd/mon.c index d812818d0258..baa77bc9d825 100644 --- a/fs/lockd/mon.c +++ b/fs/lockd/mon.c @@ -459,25 +459,17 @@ static void encode_priv(struct xdr_stream *xdr, const struct nsm_args *argp) xdr_encode_opaque_fixed(p, argp->priv->data, SM_PRIV_SIZE); } -static int xdr_enc_mon(struct rpc_rqst *req, __be32 *p, - const struct nsm_args *argp) +static void nsm_xdr_enc_mon(struct rpc_rqst *req, struct xdr_stream *xdr, + const struct nsm_args *argp) { - struct xdr_stream xdr; - - xdr_init_encode(&xdr, &req->rq_snd_buf, p); - encode_mon_id(&xdr, argp); - encode_priv(&xdr, argp); - return 0; + encode_mon_id(xdr, argp); + encode_priv(xdr, argp); } -static int xdr_enc_unmon(struct rpc_rqst *req, __be32 *p, - const struct nsm_args *argp) +static void nsm_xdr_enc_unmon(struct rpc_rqst *req, struct xdr_stream *xdr, + const struct nsm_args *argp) { - struct xdr_stream xdr; - - xdr_init_encode(&xdr, &req->rq_snd_buf, p); - encode_mon_id(&xdr, argp); - return 0; + encode_mon_id(xdr, argp); } static int xdr_dec_stat_res(struct rpc_rqst *rqstp, __be32 *p, @@ -524,7 +516,7 @@ static int xdr_dec_stat(struct rpc_rqst *rqstp, __be32 *p, static struct rpc_procinfo nsm_procedures[] = { [NSMPROC_MON] = { .p_proc = NSMPROC_MON, - .p_encode = (kxdrproc_t)xdr_enc_mon, + .p_encode = (kxdreproc_t)nsm_xdr_enc_mon, .p_decode = (kxdrproc_t)xdr_dec_stat_res, .p_arglen = SM_mon_sz, .p_replen = SM_monres_sz, @@ -533,7 +525,7 @@ static struct rpc_procinfo nsm_procedures[] = { }, [NSMPROC_UNMON] = { .p_proc = NSMPROC_UNMON, - .p_encode = (kxdrproc_t)xdr_enc_unmon, + .p_encode = (kxdreproc_t)nsm_xdr_enc_unmon, .p_decode = (kxdrproc_t)xdr_dec_stat, .p_arglen = SM_mon_id_sz, .p_replen = SM_unmonres_sz, diff --git a/fs/nfs/mount_clnt.c b/fs/nfs/mount_clnt.c index 97c3ec793305..979ebd7af3cb 100644 --- a/fs/nfs/mount_clnt.c +++ b/fs/nfs/mount_clnt.c @@ -288,14 +288,10 @@ static void encode_mntdirpath(struct xdr_stream *xdr, const char *pathname) xdr_encode_opaque(p, pathname, pathname_len); } -static int mnt_enc_dirpath(struct rpc_rqst *req, __be32 *p, - const char *dirpath) +static void mnt_xdr_enc_dirpath(struct rpc_rqst *req, struct xdr_stream *xdr, + const char *dirpath) { - struct xdr_stream xdr; - - xdr_init_encode(&xdr, &req->rq_snd_buf, p); - encode_mntdirpath(&xdr, dirpath); - return 0; + encode_mntdirpath(xdr, dirpath); } /* @@ -460,7 +456,7 @@ static int mnt_dec_mountres3(struct rpc_rqst *req, __be32 *p, static struct rpc_procinfo mnt_procedures[] = { [MOUNTPROC_MNT] = { .p_proc = MOUNTPROC_MNT, - .p_encode = (kxdrproc_t)mnt_enc_dirpath, + .p_encode = (kxdreproc_t)mnt_xdr_enc_dirpath, .p_decode = (kxdrproc_t)mnt_dec_mountres, .p_arglen = MNT_enc_dirpath_sz, .p_replen = MNT_dec_mountres_sz, @@ -469,7 +465,7 @@ static struct rpc_procinfo mnt_procedures[] = { }, [MOUNTPROC_UMNT] = { .p_proc = MOUNTPROC_UMNT, - .p_encode = (kxdrproc_t)mnt_enc_dirpath, + .p_encode = (kxdreproc_t)mnt_xdr_enc_dirpath, .p_arglen = MNT_enc_dirpath_sz, .p_statidx = MOUNTPROC_UMNT, .p_name = "UMOUNT", @@ -479,7 +475,7 @@ static struct rpc_procinfo mnt_procedures[] = { static struct rpc_procinfo mnt3_procedures[] = { [MOUNTPROC3_MNT] = { .p_proc = MOUNTPROC3_MNT, - .p_encode = (kxdrproc_t)mnt_enc_dirpath, + .p_encode = (kxdreproc_t)mnt_xdr_enc_dirpath, .p_decode = (kxdrproc_t)mnt_dec_mountres3, .p_arglen = MNT_enc_dirpath_sz, .p_replen = MNT_dec_mountres3_sz, @@ -488,7 +484,7 @@ static struct rpc_procinfo mnt3_procedures[] = { }, [MOUNTPROC3_UMNT] = { .p_proc = MOUNTPROC3_UMNT, - .p_encode = (kxdrproc_t)mnt_enc_dirpath, + .p_encode = (kxdreproc_t)mnt_xdr_enc_dirpath, .p_arglen = MNT_enc_dirpath_sz, .p_statidx = MOUNTPROC3_UMNT, .p_name = "UMOUNT", diff --git a/fs/nfs/nfs2xdr.c b/fs/nfs/nfs2xdr.c index a9b848edbd2e..8f3acbec761f 100644 --- a/fs/nfs/nfs2xdr.c +++ b/fs/nfs/nfs2xdr.c @@ -558,14 +558,11 @@ out_default: * "NFS: Network File System Protocol Specification". */ -static int nfs2_xdr_enc_fhandle(struct rpc_rqst *req, __be32 *p, - const struct nfs_fh *fh) +static void nfs2_xdr_enc_fhandle(struct rpc_rqst *req, + struct xdr_stream *xdr, + const struct nfs_fh *fh) { - struct xdr_stream xdr; - - xdr_init_encode(&xdr, &req->rq_snd_buf, p); - encode_fhandle(&xdr, fh); - return 0; + encode_fhandle(xdr, fh); } /* @@ -576,37 +573,28 @@ static int nfs2_xdr_enc_fhandle(struct rpc_rqst *req, __be32 *p, * sattr attributes; * }; */ -static int nfs2_xdr_enc_sattrargs(struct rpc_rqst *req, __be32 *p, - const struct nfs_sattrargs *args) +static void nfs2_xdr_enc_sattrargs(struct rpc_rqst *req, + struct xdr_stream *xdr, + const struct nfs_sattrargs *args) { - struct xdr_stream xdr; - - xdr_init_encode(&xdr, &req->rq_snd_buf, p); - encode_fhandle(&xdr, args->fh); - encode_sattr(&xdr, args->sattr); - return 0; + encode_fhandle(xdr, args->fh); + encode_sattr(xdr, args->sattr); } -static int nfs2_xdr_enc_diropargs(struct rpc_rqst *req, __be32 *p, - const struct nfs_diropargs *args) +static void nfs2_xdr_enc_diropargs(struct rpc_rqst *req, + struct xdr_stream *xdr, + const struct nfs_diropargs *args) { - struct xdr_stream xdr; - - xdr_init_encode(&xdr, &req->rq_snd_buf, p); - encode_diropargs(&xdr, args->fh, args->name, args->len); - return 0; + encode_diropargs(xdr, args->fh, args->name, args->len); } -static int nfs2_xdr_enc_readlinkargs(struct rpc_rqst *req, __be32 *p, - const struct nfs_readlinkargs *args) +static void nfs2_xdr_enc_readlinkargs(struct rpc_rqst *req, + struct xdr_stream *xdr, + const struct nfs_readlinkargs *args) { - struct xdr_stream xdr; - - xdr_init_encode(&xdr, &req->rq_snd_buf, p); - encode_fhandle(&xdr, args->fh); + encode_fhandle(xdr, args->fh); prepare_reply_buffer(req, args->pages, args->pgbase, args->pglen, NFS_readlinkres_sz); - return 0; } /* @@ -634,17 +622,14 @@ static void encode_readargs(struct xdr_stream *xdr, *p = cpu_to_be32(count); } -static int nfs2_xdr_enc_readargs(struct rpc_rqst *req, __be32 *p, - const struct nfs_readargs *args) +static void nfs2_xdr_enc_readargs(struct rpc_rqst *req, + struct xdr_stream *xdr, + const struct nfs_readargs *args) { - struct xdr_stream xdr; - - xdr_init_encode(&xdr, &req->rq_snd_buf, p); - encode_readargs(&xdr, args); + encode_readargs(xdr, args); prepare_reply_buffer(req, args->pages, args->pgbase, args->count, NFS_readres_sz); req->rq_rcv_buf.flags |= XDRBUF_READ; - return 0; } /* @@ -677,15 +662,12 @@ static void encode_writeargs(struct xdr_stream *xdr, xdr_write_pages(xdr, args->pages, args->pgbase, count); } -static int nfs2_xdr_enc_writeargs(struct rpc_rqst *req, __be32 *p, - const struct nfs_writeargs *args) +static void nfs2_xdr_enc_writeargs(struct rpc_rqst *req, + struct xdr_stream *xdr, + const struct nfs_writeargs *args) { - struct xdr_stream xdr; - - xdr_init_encode(&xdr, &req->rq_snd_buf, p); - encode_writeargs(&xdr, args); - xdr.buf->flags |= XDRBUF_WRITE; - return 0; + encode_writeargs(xdr, args); + xdr->buf->flags |= XDRBUF_WRITE; } /* @@ -696,25 +678,19 @@ static int nfs2_xdr_enc_writeargs(struct rpc_rqst *req, __be32 *p, * sattr attributes; * }; */ -static int nfs2_xdr_enc_createargs(struct rpc_rqst *req, __be32 *p, - const struct nfs_createargs *args) +static void nfs2_xdr_enc_createargs(struct rpc_rqst *req, + struct xdr_stream *xdr, + const struct nfs_createargs *args) { - struct xdr_stream xdr; - - xdr_init_encode(&xdr, &req->rq_snd_buf, p); - encode_diropargs(&xdr, args->fh, args->name, args->len); - encode_sattr(&xdr, args->sattr); - return 0; + encode_diropargs(xdr, args->fh, args->name, args->len); + encode_sattr(xdr, args->sattr); } -static int nfs2_xdr_enc_removeargs(struct rpc_rqst *req, __be32 *p, - const struct nfs_removeargs *args) +static void nfs2_xdr_enc_removeargs(struct rpc_rqst *req, + struct xdr_stream *xdr, + const struct nfs_removeargs *args) { - struct xdr_stream xdr; - - xdr_init_encode(&xdr, &req->rq_snd_buf, p); - encode_diropargs(&xdr, args->fh, args->name.name, args->name.len); - return 0; + encode_diropargs(xdr, args->fh, args->name.name, args->name.len); } /* @@ -725,17 +701,15 @@ static int nfs2_xdr_enc_removeargs(struct rpc_rqst *req, __be32 *p, * diropargs to; * }; */ -static int nfs2_xdr_enc_renameargs(struct rpc_rqst *req, __be32 *p, - const struct nfs_renameargs *args) +static void nfs2_xdr_enc_renameargs(struct rpc_rqst *req, + struct xdr_stream *xdr, + const struct nfs_renameargs *args) { const struct qstr *old = args->old_name; const struct qstr *new = args->new_name; - struct xdr_stream xdr; - xdr_init_encode(&xdr, &req->rq_snd_buf, p); - encode_diropargs(&xdr, args->old_dir, old->name, old->len); - encode_diropargs(&xdr, args->new_dir, new->name, new->len); - return 0; + encode_diropargs(xdr, args->old_dir, old->name, old->len); + encode_diropargs(xdr, args->new_dir, new->name, new->len); } /* @@ -746,15 +720,12 @@ static int nfs2_xdr_enc_renameargs(struct rpc_rqst *req, __be32 *p, * diropargs to; * }; */ -static int nfs2_xdr_enc_linkargs(struct rpc_rqst *req, __be32 *p, - const struct nfs_linkargs *args) +static void nfs2_xdr_enc_linkargs(struct rpc_rqst *req, + struct xdr_stream *xdr, + const struct nfs_linkargs *args) { - struct xdr_stream xdr; - - xdr_init_encode(&xdr, &req->rq_snd_buf, p); - encode_fhandle(&xdr, args->fromfh); - encode_diropargs(&xdr, args->tofh, args->toname, args->tolen); - return 0; + encode_fhandle(xdr, args->fromfh); + encode_diropargs(xdr, args->tofh, args->toname, args->tolen); } /* @@ -766,16 +737,13 @@ static int nfs2_xdr_enc_linkargs(struct rpc_rqst *req, __be32 *p, * sattr attributes; * }; */ -static int nfs2_xdr_enc_symlinkargs(struct rpc_rqst *req, __be32 *p, - const struct nfs_symlinkargs *args) +static void nfs2_xdr_enc_symlinkargs(struct rpc_rqst *req, + struct xdr_stream *xdr, + const struct nfs_symlinkargs *args) { - struct xdr_stream xdr; - - xdr_init_encode(&xdr, &req->rq_snd_buf, p); - encode_diropargs(&xdr, args->fromfh, args->fromname, args->fromlen); - encode_path(&xdr, args->pages, args->pathlen); - encode_sattr(&xdr, args->sattr); - return 0; + encode_diropargs(xdr, args->fromfh, args->fromname, args->fromlen); + encode_path(xdr, args->pages, args->pathlen); + encode_sattr(xdr, args->sattr); } /* @@ -799,16 +767,13 @@ static void encode_readdirargs(struct xdr_stream *xdr, *p = cpu_to_be32(args->count); } -static int nfs2_xdr_enc_readdirargs(struct rpc_rqst *req, __be32 *p, - const struct nfs_readdirargs *args) +static void nfs2_xdr_enc_readdirargs(struct rpc_rqst *req, + struct xdr_stream *xdr, + const struct nfs_readdirargs *args) { - struct xdr_stream xdr; - - xdr_init_encode(&xdr, &req->rq_snd_buf, p); - encode_readdirargs(&xdr, args); + encode_readdirargs(xdr, args); prepare_reply_buffer(req, args->pages, 0, args->count, NFS_readdirres_sz); - return 0; } /* @@ -1184,7 +1149,7 @@ int nfs_stat_to_errno(enum nfs_stat status) #define PROC(proc, argtype, restype, timer) \ [NFSPROC_##proc] = { \ .p_proc = NFSPROC_##proc, \ - .p_encode = (kxdrproc_t)nfs2_xdr_enc_##argtype, \ + .p_encode = (kxdreproc_t)nfs2_xdr_enc_##argtype, \ .p_decode = (kxdrproc_t)nfs2_xdr_dec_##restype, \ .p_arglen = NFS_##argtype##_sz, \ .p_replen = NFS_##restype##_sz, \ diff --git a/fs/nfs/nfs3xdr.c b/fs/nfs/nfs3xdr.c index 15c93ccd90c5..ae1b1a43f05e 100644 --- a/fs/nfs/nfs3xdr.c +++ b/fs/nfs/nfs3xdr.c @@ -835,14 +835,11 @@ static void encode_diropargs3(struct xdr_stream *xdr, const struct nfs_fh *fh, * nfs_fh3 object; * }; */ -static int nfs3_xdr_enc_getattr3args(struct rpc_rqst *req, __be32 *p, - const struct nfs_fh *fh) +static void nfs3_xdr_enc_getattr3args(struct rpc_rqst *req, + struct xdr_stream *xdr, + const struct nfs_fh *fh) { - struct xdr_stream xdr; - - xdr_init_encode(&xdr, &req->rq_snd_buf, p); - encode_nfs_fh3(&xdr, fh); - return 0; + encode_nfs_fh3(xdr, fh); } /* @@ -876,16 +873,13 @@ static void encode_sattrguard3(struct xdr_stream *xdr, } } -static int nfs3_xdr_enc_setattr3args(struct rpc_rqst *req, __be32 *p, - const struct nfs3_sattrargs *args) +static void nfs3_xdr_enc_setattr3args(struct rpc_rqst *req, + struct xdr_stream *xdr, + const struct nfs3_sattrargs *args) { - struct xdr_stream xdr; - - xdr_init_encode(&xdr, &req->rq_snd_buf, p); - encode_nfs_fh3(&xdr, args->fh); - encode_sattr3(&xdr, args->sattr); - encode_sattrguard3(&xdr, args); - return 0; + encode_nfs_fh3(xdr, args->fh); + encode_sattr3(xdr, args->sattr); + encode_sattrguard3(xdr, args); } /* @@ -895,14 +889,11 @@ static int nfs3_xdr_enc_setattr3args(struct rpc_rqst *req, __be32 *p, * diropargs3 what; * }; */ -static int nfs3_xdr_enc_lookup3args(struct rpc_rqst *req, __be32 *p, - const struct nfs3_diropargs *args) +static void nfs3_xdr_enc_lookup3args(struct rpc_rqst *req, + struct xdr_stream *xdr, + const struct nfs3_diropargs *args) { - struct xdr_stream xdr; - - xdr_init_encode(&xdr, &req->rq_snd_buf, p); - encode_diropargs3(&xdr, args->fh, args->name, args->len); - return 0; + encode_diropargs3(xdr, args->fh, args->name, args->len); } /* @@ -920,14 +911,11 @@ static void encode_access3args(struct xdr_stream *xdr, encode_uint32(xdr, args->access); } -static int nfs3_xdr_enc_access3args(struct rpc_rqst *req, __be32 *p, - const struct nfs3_accessargs *args) +static void nfs3_xdr_enc_access3args(struct rpc_rqst *req, + struct xdr_stream *xdr, + const struct nfs3_accessargs *args) { - struct xdr_stream xdr; - - xdr_init_encode(&xdr, &req->rq_snd_buf, p); - encode_access3args(&xdr, args); - return 0; + encode_access3args(xdr, args); } /* @@ -937,16 +925,13 @@ static int nfs3_xdr_enc_access3args(struct rpc_rqst *req, __be32 *p, * nfs_fh3 symlink; * }; */ -static int nfs3_xdr_enc_readlink3args(struct rpc_rqst *req, __be32 *p, - const struct nfs3_readlinkargs *args) +static void nfs3_xdr_enc_readlink3args(struct rpc_rqst *req, + struct xdr_stream *xdr, + const struct nfs3_readlinkargs *args) { - struct xdr_stream xdr; - - xdr_init_encode(&xdr, &req->rq_snd_buf, p); - encode_nfs_fh3(&xdr, args->fh); + encode_nfs_fh3(xdr, args->fh); prepare_reply_buffer(req, args->pages, args->pgbase, args->pglen, NFS3_readlinkres_sz); - return 0; } /* @@ -970,17 +955,14 @@ static void encode_read3args(struct xdr_stream *xdr, *p = cpu_to_be32(args->count); } -static int nfs3_xdr_enc_read3args(struct rpc_rqst *req, __be32 *p, - const struct nfs_readargs *args) +static void nfs3_xdr_enc_read3args(struct rpc_rqst *req, + struct xdr_stream *xdr, + const struct nfs_readargs *args) { - struct xdr_stream xdr; - - xdr_init_encode(&xdr, &req->rq_snd_buf, p); - encode_read3args(&xdr, args); + encode_read3args(xdr, args); prepare_reply_buffer(req, args->pages, args->pgbase, args->count, NFS3_readres_sz); req->rq_rcv_buf.flags |= XDRBUF_READ; - return 0; } /* @@ -1015,15 +997,12 @@ static void encode_write3args(struct xdr_stream *xdr, xdr_write_pages(xdr, args->pages, args->pgbase, args->count); } -static int nfs3_xdr_enc_write3args(struct rpc_rqst *req, __be32 *p, - const struct nfs_writeargs *args) +static void nfs3_xdr_enc_write3args(struct rpc_rqst *req, + struct xdr_stream *xdr, + const struct nfs_writeargs *args) { - struct xdr_stream xdr; - - xdr_init_encode(&xdr, &req->rq_snd_buf, p); - encode_write3args(&xdr, args); - xdr.buf->flags |= XDRBUF_WRITE; - return 0; + encode_write3args(xdr, args); + xdr->buf->flags |= XDRBUF_WRITE; } /* @@ -1065,15 +1044,12 @@ static void encode_createhow3(struct xdr_stream *xdr, } } -static int nfs3_xdr_enc_create3args(struct rpc_rqst *req, __be32 *p, - const struct nfs3_createargs *args) +static void nfs3_xdr_enc_create3args(struct rpc_rqst *req, + struct xdr_stream *xdr, + const struct nfs3_createargs *args) { - struct xdr_stream xdr; - - xdr_init_encode(&xdr, &req->rq_snd_buf, p); - encode_diropargs3(&xdr, args->fh, args->name, args->len); - encode_createhow3(&xdr, args); - return 0; + encode_diropargs3(xdr, args->fh, args->name, args->len); + encode_createhow3(xdr, args); } /* @@ -1084,15 +1060,12 @@ static int nfs3_xdr_enc_create3args(struct rpc_rqst *req, __be32 *p, * sattr3 attributes; * }; */ -static int nfs3_xdr_enc_mkdir3args(struct rpc_rqst *req, __be32 *p, - const struct nfs3_mkdirargs *args) +static void nfs3_xdr_enc_mkdir3args(struct rpc_rqst *req, + struct xdr_stream *xdr, + const struct nfs3_mkdirargs *args) { - struct xdr_stream xdr; - - xdr_init_encode(&xdr, &req->rq_snd_buf, p); - encode_diropargs3(&xdr, args->fh, args->name, args->len); - encode_sattr3(&xdr, args->sattr); - return 0; + encode_diropargs3(xdr, args->fh, args->name, args->len); + encode_sattr3(xdr, args->sattr); } /* @@ -1115,15 +1088,12 @@ static void encode_symlinkdata3(struct xdr_stream *xdr, encode_nfspath3(xdr, args->pages, args->pathlen); } -static int nfs3_xdr_enc_symlink3args(struct rpc_rqst *req, __be32 *p, - const struct nfs3_symlinkargs *args) +static void nfs3_xdr_enc_symlink3args(struct rpc_rqst *req, + struct xdr_stream *xdr, + const struct nfs3_symlinkargs *args) { - struct xdr_stream xdr; - - xdr_init_encode(&xdr, &req->rq_snd_buf, p); - encode_diropargs3(&xdr, args->fromfh, args->fromname, args->fromlen); - encode_symlinkdata3(&xdr, args); - return 0; + encode_diropargs3(xdr, args->fromfh, args->fromname, args->fromlen); + encode_symlinkdata3(xdr, args); } /* @@ -1178,15 +1148,12 @@ static void encode_mknoddata3(struct xdr_stream *xdr, } } -static int nfs3_xdr_enc_mknod3args(struct rpc_rqst *req, __be32 *p, - const struct nfs3_mknodargs *args) +static void nfs3_xdr_enc_mknod3args(struct rpc_rqst *req, + struct xdr_stream *xdr, + const struct nfs3_mknodargs *args) { - struct xdr_stream xdr; - - xdr_init_encode(&xdr, &req->rq_snd_buf, p); - encode_diropargs3(&xdr, args->fh, args->name, args->len); - encode_mknoddata3(&xdr, args); - return 0; + encode_diropargs3(xdr, args->fh, args->name, args->len); + encode_mknoddata3(xdr, args); } /* @@ -1196,14 +1163,11 @@ static int nfs3_xdr_enc_mknod3args(struct rpc_rqst *req, __be32 *p, * diropargs3 object; * }; */ -static int nfs3_xdr_enc_remove3args(struct rpc_rqst *req, __be32 *p, - const struct nfs_removeargs *args) +static void nfs3_xdr_enc_remove3args(struct rpc_rqst *req, + struct xdr_stream *xdr, + const struct nfs_removeargs *args) { - struct xdr_stream xdr; - - xdr_init_encode(&xdr, &req->rq_snd_buf, p); - encode_diropargs3(&xdr, args->fh, args->name.name, args->name.len); - return 0; + encode_diropargs3(xdr, args->fh, args->name.name, args->name.len); } /* @@ -1214,17 +1178,15 @@ static int nfs3_xdr_enc_remove3args(struct rpc_rqst *req, __be32 *p, * diropargs3 to; * }; */ -static int nfs3_xdr_enc_rename3args(struct rpc_rqst *req, __be32 *p, - const struct nfs_renameargs *args) +static void nfs3_xdr_enc_rename3args(struct rpc_rqst *req, + struct xdr_stream *xdr, + const struct nfs_renameargs *args) { const struct qstr *old = args->old_name; const struct qstr *new = args->new_name; - struct xdr_stream xdr; - xdr_init_encode(&xdr, &req->rq_snd_buf, p); - encode_diropargs3(&xdr, args->old_dir, old->name, old->len); - encode_diropargs3(&xdr, args->new_dir, new->name, new->len); - return 0; + encode_diropargs3(xdr, args->old_dir, old->name, old->len); + encode_diropargs3(xdr, args->new_dir, new->name, new->len); } /* @@ -1235,15 +1197,12 @@ static int nfs3_xdr_enc_rename3args(struct rpc_rqst *req, __be32 *p, * diropargs3 link; * }; */ -static int nfs3_xdr_enc_link3args(struct rpc_rqst *req, __be32 *p, - const struct nfs3_linkargs *args) +static void nfs3_xdr_enc_link3args(struct rpc_rqst *req, + struct xdr_stream *xdr, + const struct nfs3_linkargs *args) { - struct xdr_stream xdr; - - xdr_init_encode(&xdr, &req->rq_snd_buf, p); - encode_nfs_fh3(&xdr, args->fromfh); - encode_diropargs3(&xdr, args->tofh, args->toname, args->tolen); - return 0; + encode_nfs_fh3(xdr, args->fromfh); + encode_diropargs3(xdr, args->tofh, args->toname, args->tolen); } /* @@ -1269,16 +1228,13 @@ static void encode_readdir3args(struct xdr_stream *xdr, *p = cpu_to_be32(args->count); } -static int nfs3_xdr_enc_readdir3args(struct rpc_rqst *req, __be32 *p, - const struct nfs3_readdirargs *args) +static void nfs3_xdr_enc_readdir3args(struct rpc_rqst *req, + struct xdr_stream *xdr, + const struct nfs3_readdirargs *args) { - struct xdr_stream xdr; - - xdr_init_encode(&xdr, &req->rq_snd_buf, p); - encode_readdir3args(&xdr, args); + encode_readdir3args(xdr, args); prepare_reply_buffer(req, args->pages, 0, args->count, NFS3_readdirres_sz); - return 0; } /* @@ -1312,16 +1268,13 @@ static void encode_readdirplus3args(struct xdr_stream *xdr, *p = cpu_to_be32(args->count); } -static int nfs3_xdr_enc_readdirplus3args(struct rpc_rqst *req, __be32 *p, - const struct nfs3_readdirargs *args) +static void nfs3_xdr_enc_readdirplus3args(struct rpc_rqst *req, + struct xdr_stream *xdr, + const struct nfs3_readdirargs *args) { - struct xdr_stream xdr; - - xdr_init_encode(&xdr, &req->rq_snd_buf, p); - encode_readdirplus3args(&xdr, args); + encode_readdirplus3args(xdr, args); prepare_reply_buffer(req, args->pages, 0, args->count, NFS3_readdirres_sz); - return 0; } /* @@ -1345,57 +1298,49 @@ static void encode_commit3args(struct xdr_stream *xdr, *p = cpu_to_be32(args->count); } -static int nfs3_xdr_enc_commit3args(struct rpc_rqst *req, __be32 *p, - const struct nfs_writeargs *args) +static void nfs3_xdr_enc_commit3args(struct rpc_rqst *req, + struct xdr_stream *xdr, + const struct nfs_writeargs *args) { - struct xdr_stream xdr; - - xdr_init_encode(&xdr, &req->rq_snd_buf, p); - encode_commit3args(&xdr, args); - return 0; + encode_commit3args(xdr, args); } #ifdef CONFIG_NFS_V3_ACL -static int nfs3_xdr_enc_getacl3args(struct rpc_rqst *req, __be32 *p, - const struct nfs3_getaclargs *args) +static void nfs3_xdr_enc_getacl3args(struct rpc_rqst *req, + struct xdr_stream *xdr, + const struct nfs3_getaclargs *args) { - struct xdr_stream xdr; - - xdr_init_encode(&xdr, &req->rq_snd_buf, p); - encode_nfs_fh3(&xdr, args->fh); - encode_uint32(&xdr, args->mask); + encode_nfs_fh3(xdr, args->fh); + encode_uint32(xdr, args->mask); if (args->mask & (NFS_ACL | NFS_DFACL)) prepare_reply_buffer(req, args->pages, 0, NFSACL_MAXPAGES << PAGE_SHIFT, ACL3_getaclres_sz); - return 0; } -static int nfs3_xdr_enc_setacl3args(struct rpc_rqst *req, __be32 *p, - const struct nfs3_setaclargs *args) +static void nfs3_xdr_enc_setacl3args(struct rpc_rqst *req, + struct xdr_stream *xdr, + const struct nfs3_setaclargs *args) { - struct xdr_stream xdr; unsigned int base; int error; - xdr_init_encode(&xdr, &req->rq_snd_buf, p); - encode_nfs_fh3(&xdr, NFS_FH(args->inode)); - encode_uint32(&xdr, args->mask); + encode_nfs_fh3(xdr, NFS_FH(args->inode)); + encode_uint32(xdr, args->mask); if (args->npages != 0) - xdr_write_pages(&xdr, args->pages, 0, args->len); + xdr_write_pages(xdr, args->pages, 0, args->len); base = req->rq_slen; - error = nfsacl_encode(xdr.buf, base, args->inode, + error = nfsacl_encode(xdr->buf, base, args->inode, (args->mask & NFS_ACL) ? args->acl_access : NULL, 1, 0); BUG_ON(error < 0); - error = nfsacl_encode(xdr.buf, base + error, args->inode, + error = nfsacl_encode(xdr->buf, base + error, args->inode, (args->mask & NFS_DFACL) ? args->acl_default : NULL, 1, NFS_ACL_DEFAULT); BUG_ON(error < 0); - return 0; } #endif /* CONFIG_NFS_V3_ACL */ @@ -2506,7 +2451,7 @@ out_default: #define PROC(proc, argtype, restype, timer) \ [NFS3PROC_##proc] = { \ .p_proc = NFS3PROC_##proc, \ - .p_encode = (kxdrproc_t)nfs3_xdr_enc_##argtype##3args, \ + .p_encode = (kxdreproc_t)nfs3_xdr_enc_##argtype##3args, \ .p_decode = (kxdrproc_t)nfs3_xdr_dec_##restype##3res, \ .p_arglen = NFS3_##argtype##args_sz, \ .p_replen = NFS3_##restype##res_sz, \ @@ -2549,7 +2494,7 @@ struct rpc_version nfs_version3 = { static struct rpc_procinfo nfs3_acl_procedures[] = { [ACLPROC3_GETACL] = { .p_proc = ACLPROC3_GETACL, - .p_encode = (kxdrproc_t)nfs3_xdr_enc_getacl3args, + .p_encode = (kxdreproc_t)nfs3_xdr_enc_getacl3args, .p_decode = (kxdrproc_t)nfs3_xdr_dec_getacl3res, .p_arglen = ACL3_getaclargs_sz, .p_replen = ACL3_getaclres_sz, @@ -2558,7 +2503,7 @@ static struct rpc_procinfo nfs3_acl_procedures[] = { }, [ACLPROC3_SETACL] = { .p_proc = ACLPROC3_SETACL, - .p_encode = (kxdrproc_t)nfs3_xdr_enc_setacl3args, + .p_encode = (kxdreproc_t)nfs3_xdr_enc_setacl3args, .p_decode = (kxdrproc_t)nfs3_xdr_dec_setacl3res, .p_arglen = ACL3_setaclargs_sz, .p_replen = ACL3_setaclres_sz, diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index a15fe99fea86..6ec38b3e4a3d 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c @@ -1510,7 +1510,7 @@ encode_restorefh(struct xdr_stream *xdr, struct compound_hdr *hdr) hdr->replen += decode_restorefh_maxsz; } -static int +static void encode_setacl(struct xdr_stream *xdr, struct nfs_setaclargs *arg, struct compound_hdr *hdr) { __be32 *p; @@ -1521,14 +1521,12 @@ encode_setacl(struct xdr_stream *xdr, struct nfs_setaclargs *arg, struct compoun p = reserve_space(xdr, 2*4); *p++ = cpu_to_be32(1); *p = cpu_to_be32(FATTR4_WORD0_ACL); - if (arg->acl_len % 4) - return -EINVAL; + BUG_ON(arg->acl_len % 4); p = reserve_space(xdr, 4); *p = cpu_to_be32(arg->acl_len); xdr_write_pages(xdr, arg->acl_pages, arg->acl_pgbase, arg->acl_len); hdr->nops++; hdr->replen += decode_setacl_maxsz; - return 0; } static void @@ -1833,393 +1831,362 @@ static u32 nfs4_xdr_minorversion(const struct nfs4_sequence_args *args) /* * Encode an ACCESS request */ -static int nfs4_xdr_enc_access(struct rpc_rqst *req, __be32 *p, const struct nfs4_accessargs *args) +static void nfs4_xdr_enc_access(struct rpc_rqst *req, struct xdr_stream *xdr, + const struct nfs4_accessargs *args) { - struct xdr_stream xdr; struct compound_hdr hdr = { .minorversion = nfs4_xdr_minorversion(&args->seq_args), }; - xdr_init_encode(&xdr, &req->rq_snd_buf, p); - encode_compound_hdr(&xdr, req, &hdr); - encode_sequence(&xdr, &args->seq_args, &hdr); - encode_putfh(&xdr, args->fh, &hdr); - encode_access(&xdr, args->access, &hdr); - encode_getfattr(&xdr, args->bitmask, &hdr); + encode_compound_hdr(xdr, req, &hdr); + encode_sequence(xdr, &args->seq_args, &hdr); + encode_putfh(xdr, args->fh, &hdr); + encode_access(xdr, args->access, &hdr); + encode_getfattr(xdr, args->bitmask, &hdr); encode_nops(&hdr); - return 0; } /* * Encode LOOKUP request */ -static int nfs4_xdr_enc_lookup(struct rpc_rqst *req, __be32 *p, const struct nfs4_lookup_arg *args) +static void nfs4_xdr_enc_lookup(struct rpc_rqst *req, struct xdr_stream *xdr, + const struct nfs4_lookup_arg *args) { - struct xdr_stream xdr; struct compound_hdr hdr = { .minorversion = nfs4_xdr_minorversion(&args->seq_args), }; - xdr_init_encode(&xdr, &req->rq_snd_buf, p); - encode_compound_hdr(&xdr, req, &hdr); - encode_sequence(&xdr, &args->seq_args, &hdr); - encode_putfh(&xdr, args->dir_fh, &hdr); - encode_lookup(&xdr, args->name, &hdr); - encode_getfh(&xdr, &hdr); - encode_getfattr(&xdr, args->bitmask, &hdr); + encode_compound_hdr(xdr, req, &hdr); + encode_sequence(xdr, &args->seq_args, &hdr); + encode_putfh(xdr, args->dir_fh, &hdr); + encode_lookup(xdr, args->name, &hdr); + encode_getfh(xdr, &hdr); + encode_getfattr(xdr, args->bitmask, &hdr); encode_nops(&hdr); - return 0; } /* * Encode LOOKUP_ROOT request */ -static int nfs4_xdr_enc_lookup_root(struct rpc_rqst *req, __be32 *p, const struct nfs4_lookup_root_arg *args) +static void nfs4_xdr_enc_lookup_root(struct rpc_rqst *req, + struct xdr_stream *xdr, + const struct nfs4_lookup_root_arg *args) { - struct xdr_stream xdr; struct compound_hdr hdr = { .minorversion = nfs4_xdr_minorversion(&args->seq_args), }; - xdr_init_encode(&xdr, &req->rq_snd_buf, p); - encode_compound_hdr(&xdr, req, &hdr); - encode_sequence(&xdr, &args->seq_args, &hdr); - encode_putrootfh(&xdr, &hdr); - encode_getfh(&xdr, &hdr); - encode_getfattr(&xdr, args->bitmask, &hdr); + encode_compound_hdr(xdr, req, &hdr); + encode_sequence(xdr, &args->seq_args, &hdr); + encode_putrootfh(xdr, &hdr); + encode_getfh(xdr, &hdr); + encode_getfattr(xdr, args->bitmask, &hdr); encode_nops(&hdr); - return 0; } /* * Encode REMOVE request */ -static int nfs4_xdr_enc_remove(struct rpc_rqst *req, __be32 *p, const struct nfs_removeargs *args) +static void nfs4_xdr_enc_remove(struct rpc_rqst *req, struct xdr_stream *xdr, + const struct nfs_removeargs *args) { - struct xdr_stream xdr; struct compound_hdr hdr = { .minorversion = nfs4_xdr_minorversion(&args->seq_args), }; - xdr_init_encode(&xdr, &req->rq_snd_buf, p); - encode_compound_hdr(&xdr, req, &hdr); - encode_sequence(&xdr, &args->seq_args, &hdr); - encode_putfh(&xdr, args->fh, &hdr); - encode_remove(&xdr, &args->name, &hdr); - encode_getfattr(&xdr, args->bitmask, &hdr); + encode_compound_hdr(xdr, req, &hdr); + encode_sequence(xdr, &args->seq_args, &hdr); + encode_putfh(xdr, args->fh, &hdr); + encode_remove(xdr, &args->name, &hdr); + encode_getfattr(xdr, args->bitmask, &hdr); encode_nops(&hdr); - return 0; } /* * Encode RENAME request */ -static int nfs4_xdr_enc_rename(struct rpc_rqst *req, __be32 *p, const struct nfs_renameargs *args) +static void nfs4_xdr_enc_rename(struct rpc_rqst *req, struct xdr_stream *xdr, + const struct nfs_renameargs *args) { - struct xdr_stream xdr; struct compound_hdr hdr = { .minorversion = nfs4_xdr_minorversion(&args->seq_args), }; - xdr_init_encode(&xdr, &req->rq_snd_buf, p); - encode_compound_hdr(&xdr, req, &hdr); - encode_sequence(&xdr, &args->seq_args, &hdr); - encode_putfh(&xdr, args->old_dir, &hdr); - encode_savefh(&xdr, &hdr); - encode_putfh(&xdr, args->new_dir, &hdr); - encode_rename(&xdr, args->old_name, args->new_name, &hdr); - encode_getfattr(&xdr, args->bitmask, &hdr); - encode_restorefh(&xdr, &hdr); - encode_getfattr(&xdr, args->bitmask, &hdr); + encode_compound_hdr(xdr, req, &hdr); + encode_sequence(xdr, &args->seq_args, &hdr); + encode_putfh(xdr, args->old_dir, &hdr); + encode_savefh(xdr, &hdr); + encode_putfh(xdr, args->new_dir, &hdr); + encode_rename(xdr, args->old_name, args->new_name, &hdr); + encode_getfattr(xdr, args->bitmask, &hdr); + encode_restorefh(xdr, &hdr); + encode_getfattr(xdr, args->bitmask, &hdr); encode_nops(&hdr); - return 0; } /* * Encode LINK request */ -static int nfs4_xdr_enc_link(struct rpc_rqst *req, __be32 *p, const struct nfs4_link_arg *args) +static void nfs4_xdr_enc_link(struct rpc_rqst *req, struct xdr_stream *xdr, + const struct nfs4_link_arg *args) { - struct xdr_stream xdr; struct compound_hdr hdr = { .minorversion = nfs4_xdr_minorversion(&args->seq_args), }; - xdr_init_encode(&xdr, &req->rq_snd_buf, p); - encode_compound_hdr(&xdr, req, &hdr); - encode_sequence(&xdr, &args->seq_args, &hdr); - encode_putfh(&xdr, args->fh, &hdr); - encode_savefh(&xdr, &hdr); - encode_putfh(&xdr, args->dir_fh, &hdr); - encode_link(&xdr, args->name, &hdr); - encode_getfattr(&xdr, args->bitmask, &hdr); - encode_restorefh(&xdr, &hdr); - encode_getfattr(&xdr, args->bitmask, &hdr); + encode_compound_hdr(xdr, req, &hdr); + encode_sequence(xdr, &args->seq_args, &hdr); + encode_putfh(xdr, args->fh, &hdr); + encode_savefh(xdr, &hdr); + encode_putfh(xdr, args->dir_fh, &hdr); + encode_link(xdr, args->name, &hdr); + encode_getfattr(xdr, args->bitmask, &hdr); + encode_restorefh(xdr, &hdr); + encode_getfattr(xdr, args->bitmask, &hdr); encode_nops(&hdr); - return 0; } /* * Encode CREATE request */ -static int nfs4_xdr_enc_create(struct rpc_rqst *req, __be32 *p, const struct nfs4_create_arg *args) +static void nfs4_xdr_enc_create(struct rpc_rqst *req, struct xdr_stream *xdr, + const struct nfs4_create_arg *args) { - struct xdr_stream xdr; struct compound_hdr hdr = { .minorversion = nfs4_xdr_minorversion(&args->seq_args), }; - xdr_init_encode(&xdr, &req->rq_snd_buf, p); - encode_compound_hdr(&xdr, req, &hdr); - encode_sequence(&xdr, &args->seq_args, &hdr); - encode_putfh(&xdr, args->dir_fh, &hdr); - encode_savefh(&xdr, &hdr); - encode_create(&xdr, args, &hdr); - encode_getfh(&xdr, &hdr); - encode_getfattr(&xdr, args->bitmask, &hdr); - encode_restorefh(&xdr, &hdr); - encode_getfattr(&xdr, args->bitmask, &hdr); + encode_compound_hdr(xdr, req, &hdr); + encode_sequence(xdr, &args->seq_args, &hdr); + encode_putfh(xdr, args->dir_fh, &hdr); + encode_savefh(xdr, &hdr); + encode_create(xdr, args, &hdr); + encode_getfh(xdr, &hdr); + encode_getfattr(xdr, args->bitmask, &hdr); + encode_restorefh(xdr, &hdr); + encode_getfattr(xdr, args->bitmask, &hdr); encode_nops(&hdr); - return 0; } /* * Encode SYMLINK request */ -static int nfs4_xdr_enc_symlink(struct rpc_rqst *req, __be32 *p, const struct nfs4_create_arg *args) +static void nfs4_xdr_enc_symlink(struct rpc_rqst *req, struct xdr_stream *xdr, + const struct nfs4_create_arg *args) { - return nfs4_xdr_enc_create(req, p, args); + nfs4_xdr_enc_create(req, xdr, args); } /* * Encode GETATTR request */ -static int nfs4_xdr_enc_getattr(struct rpc_rqst *req, __be32 *p, const struct nfs4_getattr_arg *args) +static void nfs4_xdr_enc_getattr(struct rpc_rqst *req, struct xdr_stream *xdr, + const struct nfs4_getattr_arg *args) { - struct xdr_stream xdr; struct compound_hdr hdr = { .minorversion = nfs4_xdr_minorversion(&args->seq_args), }; - xdr_init_encode(&xdr, &req->rq_snd_buf, p); - encode_compound_hdr(&xdr, req, &hdr); - encode_sequence(&xdr, &args->seq_args, &hdr); - encode_putfh(&xdr, args->fh, &hdr); - encode_getfattr(&xdr, args->bitmask, &hdr); + encode_compound_hdr(xdr, req, &hdr); + encode_sequence(xdr, &args->seq_args, &hdr); + encode_putfh(xdr, args->fh, &hdr); + encode_getfattr(xdr, args->bitmask, &hdr); encode_nops(&hdr); - return 0; } /* * Encode a CLOSE request */ -static int nfs4_xdr_enc_close(struct rpc_rqst *req, __be32 *p, struct nfs_closeargs *args) +static void nfs4_xdr_enc_close(struct rpc_rqst *req, struct xdr_stream *xdr, + struct nfs_closeargs *args) { - struct xdr_stream xdr; struct compound_hdr hdr = { .minorversion = nfs4_xdr_minorversion(&args->seq_args), }; - xdr_init_encode(&xdr, &req->rq_snd_buf, p); - encode_compound_hdr(&xdr, req, &hdr); - encode_sequence(&xdr, &args->seq_args, &hdr); - encode_putfh(&xdr, args->fh, &hdr); - encode_close(&xdr, args, &hdr); - encode_getfattr(&xdr, args->bitmask, &hdr); + encode_compound_hdr(xdr, req, &hdr); + encode_sequence(xdr, &args->seq_args, &hdr); + encode_putfh(xdr, args->fh, &hdr); + encode_close(xdr, args, &hdr); + encode_getfattr(xdr, args->bitmask, &hdr); encode_nops(&hdr); - return 0; } /* * Encode an OPEN request */ -static int nfs4_xdr_enc_open(struct rpc_rqst *req, __be32 *p, struct nfs_openargs *args) +static void nfs4_xdr_enc_open(struct rpc_rqst *req, struct xdr_stream *xdr, + struct nfs_openargs *args) { - struct xdr_stream xdr; struct compound_hdr hdr = { .minorversion = nfs4_xdr_minorversion(&args->seq_args), }; - xdr_init_encode(&xdr, &req->rq_snd_buf, p); - encode_compound_hdr(&xdr, req, &hdr); - encode_sequence(&xdr, &args->seq_args, &hdr); - encode_putfh(&xdr, args->fh, &hdr); - encode_savefh(&xdr, &hdr); - encode_open(&xdr, args, &hdr); - encode_getfh(&xdr, &hdr); - encode_getfattr(&xdr, args->bitmask, &hdr); - encode_restorefh(&xdr, &hdr); - encode_getfattr(&xdr, args->bitmask, &hdr); + encode_compound_hdr(xdr, req, &hdr); + encode_sequence(xdr, &args->seq_args, &hdr); + encode_putfh(xdr, args->fh, &hdr); + encode_savefh(xdr, &hdr); + encode_open(xdr, args, &hdr); + encode_getfh(xdr, &hdr); + encode_getfattr(xdr, args->bitmask, &hdr); + encode_restorefh(xdr, &hdr); + encode_getfattr(xdr, args->bitmask, &hdr); encode_nops(&hdr); - return 0; } /* * Encode an OPEN_CONFIRM request */ -static int nfs4_xdr_enc_open_confirm(struct rpc_rqst *req, __be32 *p, struct nfs_open_confirmargs *args) +static void nfs4_xdr_enc_open_confirm(struct rpc_rqst *req, + struct xdr_stream *xdr, + struct nfs_open_confirmargs *args) { - struct xdr_stream xdr; struct compound_hdr hdr = { .nops = 0, }; - xdr_init_encode(&xdr, &req->rq_snd_buf, p); - encode_compound_hdr(&xdr, req, &hdr); - encode_putfh(&xdr, args->fh, &hdr); - encode_open_confirm(&xdr, args, &hdr); + encode_compound_hdr(xdr, req, &hdr); + encode_putfh(xdr, args->fh, &hdr); + encode_open_confirm(xdr, args, &hdr); encode_nops(&hdr); - return 0; } /* * Encode an OPEN request with no attributes. */ -static int nfs4_xdr_enc_open_noattr(struct rpc_rqst *req, __be32 *p, struct nfs_openargs *args) +static void nfs4_xdr_enc_open_noattr(struct rpc_rqst *req, + struct xdr_stream *xdr, + struct nfs_openargs *args) { - struct xdr_stream xdr; struct compound_hdr hdr = { .minorversion = nfs4_xdr_minorversion(&args->seq_args), }; - xdr_init_encode(&xdr, &req->rq_snd_buf, p); - encode_compound_hdr(&xdr, req, &hdr); - encode_sequence(&xdr, &args->seq_args, &hdr); - encode_putfh(&xdr, args->fh, &hdr); - encode_open(&xdr, args, &hdr); - encode_getfattr(&xdr, args->bitmask, &hdr); + encode_compound_hdr(xdr, req, &hdr); + encode_sequence(xdr, &args->seq_args, &hdr); + encode_putfh(xdr, args->fh, &hdr); + encode_open(xdr, args, &hdr); + encode_getfattr(xdr, args->bitmask, &hdr); encode_nops(&hdr); - return 0; } /* * Encode an OPEN_DOWNGRADE request */ -static int nfs4_xdr_enc_open_downgrade(struct rpc_rqst *req, __be32 *p, struct nfs_closeargs *args) +static void nfs4_xdr_enc_open_downgrade(struct rpc_rqst *req, + struct xdr_stream *xdr, + struct nfs_closeargs *args) { - struct xdr_stream xdr; struct compound_hdr hdr = { .minorversion = nfs4_xdr_minorversion(&args->seq_args), }; - xdr_init_encode(&xdr, &req->rq_snd_buf, p); - encode_compound_hdr(&xdr, req, &hdr); - encode_sequence(&xdr, &args->seq_args, &hdr); - encode_putfh(&xdr, args->fh, &hdr); - encode_open_downgrade(&xdr, args, &hdr); - encode_getfattr(&xdr, args->bitmask, &hdr); + encode_compound_hdr(xdr, req, &hdr); + encode_sequence(xdr, &args->seq_args, &hdr); + encode_putfh(xdr, args->fh, &hdr); + encode_open_downgrade(xdr, args, &hdr); + encode_getfattr(xdr, args->bitmask, &hdr); encode_nops(&hdr); - return 0; } /* * Encode a LOCK request */ -static int nfs4_xdr_enc_lock(struct rpc_rqst *req, __be32 *p, struct nfs_lock_args *args) +static void nfs4_xdr_enc_lock(struct rpc_rqst *req, struct xdr_stream *xdr, + struct nfs_lock_args *args) { - struct xdr_stream xdr; struct compound_hdr hdr = { .minorversion = nfs4_xdr_minorversion(&args->seq_args), }; - xdr_init_encode(&xdr, &req->rq_snd_buf, p); - encode_compound_hdr(&xdr, req, &hdr); - encode_sequence(&xdr, &args->seq_args, &hdr); - encode_putfh(&xdr, args->fh, &hdr); - encode_lock(&xdr, args, &hdr); + encode_compound_hdr(xdr, req, &hdr); + encode_sequence(xdr, &args->seq_args, &hdr); + encode_putfh(xdr, args->fh, &hdr); + encode_lock(xdr, args, &hdr); encode_nops(&hdr); - return 0; } /* * Encode a LOCKT request */ -static int nfs4_xdr_enc_lockt(struct rpc_rqst *req, __be32 *p, struct nfs_lockt_args *args) +static void nfs4_xdr_enc_lockt(struct rpc_rqst *req, struct xdr_stream *xdr, + struct nfs_lockt_args *args) { - struct xdr_stream xdr; struct compound_hdr hdr = { .minorversion = nfs4_xdr_minorversion(&args->seq_args), }; - xdr_init_encode(&xdr, &req->rq_snd_buf, p); - encode_compound_hdr(&xdr, req, &hdr); - encode_sequence(&xdr, &args->seq_args, &hdr); - encode_putfh(&xdr, args->fh, &hdr); - encode_lockt(&xdr, args, &hdr); + encode_compound_hdr(xdr, req, &hdr); + encode_sequence(xdr, &args->seq_args, &hdr); + encode_putfh(xdr, args->fh, &hdr); + encode_lockt(xdr, args, &hdr); encode_nops(&hdr); - return 0; } /* * Encode a LOCKU request */ -static int nfs4_xdr_enc_locku(struct rpc_rqst *req, __be32 *p, struct nfs_locku_args *args) +static void nfs4_xdr_enc_locku(struct rpc_rqst *req, struct xdr_stream *xdr, + struct nfs_locku_args *args) { - struct xdr_stream xdr; struct compound_hdr hdr = { .minorversion = nfs4_xdr_minorversion(&args->seq_args), }; - xdr_init_encode(&xdr, &req->rq_snd_buf, p); - encode_compound_hdr(&xdr, req, &hdr); - encode_sequence(&xdr, &args->seq_args, &hdr); - encode_putfh(&xdr, args->fh, &hdr); - encode_locku(&xdr, args, &hdr); + encode_compound_hdr(xdr, req, &hdr); + encode_sequence(xdr, &args->seq_args, &hdr); + encode_putfh(xdr, args->fh, &hdr); + encode_locku(xdr, args, &hdr); encode_nops(&hdr); - return 0; } -static int nfs4_xdr_enc_release_lockowner(struct rpc_rqst *req, __be32 *p, struct nfs_release_lockowner_args *args) +static void nfs4_xdr_enc_release_lockowner(struct rpc_rqst *req, + struct xdr_stream *xdr, + struct nfs_release_lockowner_args *args) { - struct xdr_stream xdr; struct compound_hdr hdr = { .minorversion = 0, }; - xdr_init_encode(&xdr, &req->rq_snd_buf, p); - encode_compound_hdr(&xdr, req, &hdr); - encode_release_lockowner(&xdr, &args->lock_owner, &hdr); + encode_compound_hdr(xdr, req, &hdr); + encode_release_lockowner(xdr, &args->lock_owner, &hdr); encode_nops(&hdr); - return 0; } /* * Encode a READLINK request */ -static int nfs4_xdr_enc_readlink(struct rpc_rqst *req, __be32 *p, const struct nfs4_readlink *args) +static void nfs4_xdr_enc_readlink(struct rpc_rqst *req, struct xdr_stream *xdr, + const struct nfs4_readlink *args) { - struct xdr_stream xdr; struct compound_hdr hdr = { .minorversion = nfs4_xdr_minorversion(&args->seq_args), }; - xdr_init_encode(&xdr, &req->rq_snd_buf, p); - encode_compound_hdr(&xdr, req, &hdr); - encode_sequence(&xdr, &args->seq_args, &hdr); - encode_putfh(&xdr, args->fh, &hdr); - encode_readlink(&xdr, args, req, &hdr); + encode_compound_hdr(xdr, req, &hdr); + encode_sequence(xdr, &args->seq_args, &hdr); + encode_putfh(xdr, args->fh, &hdr); + encode_readlink(xdr, args, req, &hdr); xdr_inline_pages(&req->rq_rcv_buf, hdr.replen << 2, args->pages, args->pgbase, args->pglen); encode_nops(&hdr); - return 0; } /* * Encode a READDIR request */ -static int nfs4_xdr_enc_readdir(struct rpc_rqst *req, __be32 *p, const struct nfs4_readdir_arg *args) +static void nfs4_xdr_enc_readdir(struct rpc_rqst *req, struct xdr_stream *xdr, + const struct nfs4_readdir_arg *args) { - struct xdr_stream xdr; struct compound_hdr hdr = { .minorversion = nfs4_xdr_minorversion(&args->seq_args), }; - xdr_init_encode(&xdr, &req->rq_snd_buf, p); - encode_compound_hdr(&xdr, req, &hdr); - encode_sequence(&xdr, &args->seq_args, &hdr); - encode_putfh(&xdr, args->fh, &hdr); - encode_readdir(&xdr, args, req, &hdr); + encode_compound_hdr(xdr, req, &hdr); + encode_sequence(xdr, &args->seq_args, &hdr); + encode_putfh(xdr, args->fh, &hdr); + encode_readdir(xdr, args, req, &hdr); xdr_inline_pages(&req->rq_rcv_buf, hdr.replen << 2, args->pages, args->pgbase, args->count); @@ -2227,428 +2194,387 @@ static int nfs4_xdr_enc_readdir(struct rpc_rqst *req, __be32 *p, const struct nf __func__, hdr.replen << 2, args->pages, args->pgbase, args->count); encode_nops(&hdr); - return 0; } /* * Encode a READ request */ -static int nfs4_xdr_enc_read(struct rpc_rqst *req, __be32 *p, struct nfs_readargs *args) +static void nfs4_xdr_enc_read(struct rpc_rqst *req, struct xdr_stream *xdr, + struct nfs_readargs *args) { - struct xdr_stream xdr; struct compound_hdr hdr = { .minorversion = nfs4_xdr_minorversion(&args->seq_args), }; - xdr_init_encode(&xdr, &req->rq_snd_buf, p); - encode_compound_hdr(&xdr, req, &hdr); - encode_sequence(&xdr, &args->seq_args, &hdr); - encode_putfh(&xdr, args->fh, &hdr); - encode_read(&xdr, args, &hdr); + encode_compound_hdr(xdr, req, &hdr); + encode_sequence(xdr, &args->seq_args, &hdr); + encode_putfh(xdr, args->fh, &hdr); + encode_read(xdr, args, &hdr); xdr_inline_pages(&req->rq_rcv_buf, hdr.replen << 2, args->pages, args->pgbase, args->count); req->rq_rcv_buf.flags |= XDRBUF_READ; encode_nops(&hdr); - return 0; } /* * Encode an SETATTR request */ -static int nfs4_xdr_enc_setattr(struct rpc_rqst *req, __be32 *p, struct nfs_setattrargs *args) +static void nfs4_xdr_enc_setattr(struct rpc_rqst *req, struct xdr_stream *xdr, + struct nfs_setattrargs *args) { - struct xdr_stream xdr; struct compound_hdr hdr = { .minorversion = nfs4_xdr_minorversion(&args->seq_args), }; - xdr_init_encode(&xdr, &req->rq_snd_buf, p); - encode_compound_hdr(&xdr, req, &hdr); - encode_sequence(&xdr, &args->seq_args, &hdr); - encode_putfh(&xdr, args->fh, &hdr); - encode_setattr(&xdr, args, args->server, &hdr); - encode_getfattr(&xdr, args->bitmask, &hdr); + encode_compound_hdr(xdr, req, &hdr); + encode_sequence(xdr, &args->seq_args, &hdr); + encode_putfh(xdr, args->fh, &hdr); + encode_setattr(xdr, args, args->server, &hdr); + encode_getfattr(xdr, args->bitmask, &hdr); encode_nops(&hdr); - return 0; } /* * Encode a GETACL request */ -static int -nfs4_xdr_enc_getacl(struct rpc_rqst *req, __be32 *p, - struct nfs_getaclargs *args) +static void nfs4_xdr_enc_getacl(struct rpc_rqst *req, struct xdr_stream *xdr, + struct nfs_getaclargs *args) { - struct xdr_stream xdr; struct compound_hdr hdr = { .minorversion = nfs4_xdr_minorversion(&args->seq_args), }; uint32_t replen; - xdr_init_encode(&xdr, &req->rq_snd_buf, p); - encode_compound_hdr(&xdr, req, &hdr); - encode_sequence(&xdr, &args->seq_args, &hdr); - encode_putfh(&xdr, args->fh, &hdr); + encode_compound_hdr(xdr, req, &hdr); + encode_sequence(xdr, &args->seq_args, &hdr); + encode_putfh(xdr, args->fh, &hdr); replen = hdr.replen + op_decode_hdr_maxsz + nfs4_fattr_bitmap_maxsz + 1; - encode_getattr_two(&xdr, FATTR4_WORD0_ACL, 0, &hdr); + encode_getattr_two(xdr, FATTR4_WORD0_ACL, 0, &hdr); xdr_inline_pages(&req->rq_rcv_buf, replen << 2, args->acl_pages, args->acl_pgbase, args->acl_len); encode_nops(&hdr); - return 0; } /* * Encode a WRITE request */ -static int nfs4_xdr_enc_write(struct rpc_rqst *req, __be32 *p, struct nfs_writeargs *args) +static void nfs4_xdr_enc_write(struct rpc_rqst *req, struct xdr_stream *xdr, + struct nfs_writeargs *args) { - struct xdr_stream xdr; struct compound_hdr hdr = { .minorversion = nfs4_xdr_minorversion(&args->seq_args), }; - xdr_init_encode(&xdr, &req->rq_snd_buf, p); - encode_compound_hdr(&xdr, req, &hdr); - encode_sequence(&xdr, &args->seq_args, &hdr); - encode_putfh(&xdr, args->fh, &hdr); - encode_write(&xdr, args, &hdr); + encode_compound_hdr(xdr, req, &hdr); + encode_sequence(xdr, &args->seq_args, &hdr); + encode_putfh(xdr, args->fh, &hdr); + encode_write(xdr, args, &hdr); req->rq_snd_buf.flags |= XDRBUF_WRITE; - encode_getfattr(&xdr, args->bitmask, &hdr); + encode_getfattr(xdr, args->bitmask, &hdr); encode_nops(&hdr); - return 0; } /* * a COMMIT request */ -static int nfs4_xdr_enc_commit(struct rpc_rqst *req, __be32 *p, struct nfs_writeargs *args) +static void nfs4_xdr_enc_commit(struct rpc_rqst *req, struct xdr_stream *xdr, + struct nfs_writeargs *args) { - struct xdr_stream xdr; struct compound_hdr hdr = { .minorversion = nfs4_xdr_minorversion(&args->seq_args), }; - xdr_init_encode(&xdr, &req->rq_snd_buf, p); - encode_compound_hdr(&xdr, req, &hdr); - encode_sequence(&xdr, &args->seq_args, &hdr); - encode_putfh(&xdr, args->fh, &hdr); - encode_commit(&xdr, args, &hdr); - encode_getfattr(&xdr, args->bitmask, &hdr); + encode_compound_hdr(xdr, req, &hdr); + encode_sequence(xdr, &args->seq_args, &hdr); + encode_putfh(xdr, args->fh, &hdr); + encode_commit(xdr, args, &hdr); + encode_getfattr(xdr, args->bitmask, &hdr); encode_nops(&hdr); - return 0; } /* * FSINFO request */ -static int nfs4_xdr_enc_fsinfo(struct rpc_rqst *req, __be32 *p, struct nfs4_fsinfo_arg *args) +static void nfs4_xdr_enc_fsinfo(struct rpc_rqst *req, struct xdr_stream *xdr, + struct nfs4_fsinfo_arg *args) { - struct xdr_stream xdr; struct compound_hdr hdr = { .minorversion = nfs4_xdr_minorversion(&args->seq_args), }; - xdr_init_encode(&xdr, &req->rq_snd_buf, p); - encode_compound_hdr(&xdr, req, &hdr); - encode_sequence(&xdr, &args->seq_args, &hdr); - encode_putfh(&xdr, args->fh, &hdr); - encode_fsinfo(&xdr, args->bitmask, &hdr); + encode_compound_hdr(xdr, req, &hdr); + encode_sequence(xdr, &args->seq_args, &hdr); + encode_putfh(xdr, args->fh, &hdr); + encode_fsinfo(xdr, args->bitmask, &hdr); encode_nops(&hdr); - return 0; } /* * a PATHCONF request */ -static int nfs4_xdr_enc_pathconf(struct rpc_rqst *req, __be32 *p, const struct nfs4_pathconf_arg *args) +static void nfs4_xdr_enc_pathconf(struct rpc_rqst *req, struct xdr_stream *xdr, + const struct nfs4_pathconf_arg *args) { - struct xdr_stream xdr; struct compound_hdr hdr = { .minorversion = nfs4_xdr_minorversion(&args->seq_args), }; - xdr_init_encode(&xdr, &req->rq_snd_buf, p); - encode_compound_hdr(&xdr, req, &hdr); - encode_sequence(&xdr, &args->seq_args, &hdr); - encode_putfh(&xdr, args->fh, &hdr); - encode_getattr_one(&xdr, args->bitmask[0] & nfs4_pathconf_bitmap[0], + encode_compound_hdr(xdr, req, &hdr); + encode_sequence(xdr, &args->seq_args, &hdr); + encode_putfh(xdr, args->fh, &hdr); + encode_getattr_one(xdr, args->bitmask[0] & nfs4_pathconf_bitmap[0], &hdr); encode_nops(&hdr); - return 0; } /* * a STATFS request */ -static int nfs4_xdr_enc_statfs(struct rpc_rqst *req, __be32 *p, const struct nfs4_statfs_arg *args) +static void nfs4_xdr_enc_statfs(struct rpc_rqst *req, struct xdr_stream *xdr, + const struct nfs4_statfs_arg *args) { - struct xdr_stream xdr; struct compound_hdr hdr = { .minorversion = nfs4_xdr_minorversion(&args->seq_args), }; - xdr_init_encode(&xdr, &req->rq_snd_buf, p); - encode_compound_hdr(&xdr, req, &hdr); - encode_sequence(&xdr, &args->seq_args, &hdr); - encode_putfh(&xdr, args->fh, &hdr); - encode_getattr_two(&xdr, args->bitmask[0] & nfs4_statfs_bitmap[0], + encode_compound_hdr(xdr, req, &hdr); + encode_sequence(xdr, &args->seq_args, &hdr); + encode_putfh(xdr, args->fh, &hdr); + encode_getattr_two(xdr, args->bitmask[0] & nfs4_statfs_bitmap[0], args->bitmask[1] & nfs4_statfs_bitmap[1], &hdr); encode_nops(&hdr); - return 0; } /* * GETATTR_BITMAP request */ -static int nfs4_xdr_enc_server_caps(struct rpc_rqst *req, __be32 *p, - struct nfs4_server_caps_arg *args) +static void nfs4_xdr_enc_server_caps(struct rpc_rqst *req, + struct xdr_stream *xdr, + struct nfs4_server_caps_arg *args) { - struct xdr_stream xdr; struct compound_hdr hdr = { .minorversion = nfs4_xdr_minorversion(&args->seq_args), }; - xdr_init_encode(&xdr, &req->rq_snd_buf, p); - encode_compound_hdr(&xdr, req, &hdr); - encode_sequence(&xdr, &args->seq_args, &hdr); - encode_putfh(&xdr, args->fhandle, &hdr); - encode_getattr_one(&xdr, FATTR4_WORD0_SUPPORTED_ATTRS| + encode_compound_hdr(xdr, req, &hdr); + encode_sequence(xdr, &args->seq_args, &hdr); + encode_putfh(xdr, args->fhandle, &hdr); + encode_getattr_one(xdr, FATTR4_WORD0_SUPPORTED_ATTRS| FATTR4_WORD0_LINK_SUPPORT| FATTR4_WORD0_SYMLINK_SUPPORT| FATTR4_WORD0_ACLSUPPORT, &hdr); encode_nops(&hdr); - return 0; } /* * a RENEW request */ -static int nfs4_xdr_enc_renew(struct rpc_rqst *req, __be32 *p, struct nfs_client *clp) +static void nfs4_xdr_enc_renew(struct rpc_rqst *req, struct xdr_stream *xdr, + struct nfs_client *clp) { - struct xdr_stream xdr; struct compound_hdr hdr = { .nops = 0, }; - xdr_init_encode(&xdr, &req->rq_snd_buf, p); - encode_compound_hdr(&xdr, req, &hdr); - encode_renew(&xdr, clp, &hdr); + encode_compound_hdr(xdr, req, &hdr); + encode_renew(xdr, clp, &hdr); encode_nops(&hdr); - return 0; } /* * a SETCLIENTID request */ -static int nfs4_xdr_enc_setclientid(struct rpc_rqst *req, __be32 *p, struct nfs4_setclientid *sc) +static void nfs4_xdr_enc_setclientid(struct rpc_rqst *req, + struct xdr_stream *xdr, + struct nfs4_setclientid *sc) { - struct xdr_stream xdr; struct compound_hdr hdr = { .nops = 0, }; - xdr_init_encode(&xdr, &req->rq_snd_buf, p); - encode_compound_hdr(&xdr, req, &hdr); - encode_setclientid(&xdr, sc, &hdr); + encode_compound_hdr(xdr, req, &hdr); + encode_setclientid(xdr, sc, &hdr); encode_nops(&hdr); - return 0; } /* * a SETCLIENTID_CONFIRM request */ -static int nfs4_xdr_enc_setclientid_confirm(struct rpc_rqst *req, __be32 *p, struct nfs4_setclientid_res *arg) +static void nfs4_xdr_enc_setclientid_confirm(struct rpc_rqst *req, + struct xdr_stream *xdr, + struct nfs4_setclientid_res *arg) { - struct xdr_stream xdr; struct compound_hdr hdr = { .nops = 0, }; const u32 lease_bitmap[2] = { FATTR4_WORD0_LEASE_TIME, 0 }; - xdr_init_encode(&xdr, &req->rq_snd_buf, p); - encode_compound_hdr(&xdr, req, &hdr); - encode_setclientid_confirm(&xdr, arg, &hdr); - encode_putrootfh(&xdr, &hdr); - encode_fsinfo(&xdr, lease_bitmap, &hdr); + encode_compound_hdr(xdr, req, &hdr); + encode_setclientid_confirm(xdr, arg, &hdr); + encode_putrootfh(xdr, &hdr); + encode_fsinfo(xdr, lease_bitmap, &hdr); encode_nops(&hdr); - return 0; } /* * DELEGRETURN request */ -static int nfs4_xdr_enc_delegreturn(struct rpc_rqst *req, __be32 *p, const struct nfs4_delegreturnargs *args) +static void nfs4_xdr_enc_delegreturn(struct rpc_rqst *req, + struct xdr_stream *xdr, + const struct nfs4_delegreturnargs *args) { - struct xdr_stream xdr; struct compound_hdr hdr = { .minorversion = nfs4_xdr_minorversion(&args->seq_args), }; - xdr_init_encode(&xdr, &req->rq_snd_buf, p); - encode_compound_hdr(&xdr, req, &hdr); - encode_sequence(&xdr, &args->seq_args, &hdr); - encode_putfh(&xdr, args->fhandle, &hdr); - encode_delegreturn(&xdr, args->stateid, &hdr); - encode_getfattr(&xdr, args->bitmask, &hdr); + encode_compound_hdr(xdr, req, &hdr); + encode_sequence(xdr, &args->seq_args, &hdr); + encode_putfh(xdr, args->fhandle, &hdr); + encode_delegreturn(xdr, args->stateid, &hdr); + encode_getfattr(xdr, args->bitmask, &hdr); encode_nops(&hdr); - return 0; } /* * Encode FS_LOCATIONS request */ -static int nfs4_xdr_enc_fs_locations(struct rpc_rqst *req, __be32 *p, struct nfs4_fs_locations_arg *args) +static void nfs4_xdr_enc_fs_locations(struct rpc_rqst *req, + struct xdr_stream *xdr, + struct nfs4_fs_locations_arg *args) { - struct xdr_stream xdr; struct compound_hdr hdr = { .minorversion = nfs4_xdr_minorversion(&args->seq_args), }; uint32_t replen; - xdr_init_encode(&xdr, &req->rq_snd_buf, p); - encode_compound_hdr(&xdr, req, &hdr); - encode_sequence(&xdr, &args->seq_args, &hdr); - encode_putfh(&xdr, args->dir_fh, &hdr); - encode_lookup(&xdr, args->name, &hdr); + encode_compound_hdr(xdr, req, &hdr); + encode_sequence(xdr, &args->seq_args, &hdr); + encode_putfh(xdr, args->dir_fh, &hdr); + encode_lookup(xdr, args->name, &hdr); replen = hdr.replen; /* get the attribute into args->page */ - encode_fs_locations(&xdr, args->bitmask, &hdr); + encode_fs_locations(xdr, args->bitmask, &hdr); xdr_inline_pages(&req->rq_rcv_buf, replen << 2, &args->page, 0, PAGE_SIZE); encode_nops(&hdr); - return 0; } #if defined(CONFIG_NFS_V4_1) /* * EXCHANGE_ID request */ -static int nfs4_xdr_enc_exchange_id(struct rpc_rqst *req, uint32_t *p, - struct nfs41_exchange_id_args *args) +static void nfs4_xdr_enc_exchange_id(struct rpc_rqst *req, + struct xdr_stream *xdr, + struct nfs41_exchange_id_args *args) { - struct xdr_stream xdr; struct compound_hdr hdr = { .minorversion = args->client->cl_mvops->minor_version, }; - xdr_init_encode(&xdr, &req->rq_snd_buf, p); - encode_compound_hdr(&xdr, req, &hdr); - encode_exchange_id(&xdr, args, &hdr); + encode_compound_hdr(xdr, req, &hdr); + encode_exchange_id(xdr, args, &hdr); encode_nops(&hdr); - return 0; } /* * a CREATE_SESSION request */ -static int nfs4_xdr_enc_create_session(struct rpc_rqst *req, uint32_t *p, - struct nfs41_create_session_args *args) +static void nfs4_xdr_enc_create_session(struct rpc_rqst *req, + struct xdr_stream *xdr, + struct nfs41_create_session_args *args) { - struct xdr_stream xdr; struct compound_hdr hdr = { .minorversion = args->client->cl_mvops->minor_version, }; - xdr_init_encode(&xdr, &req->rq_snd_buf, p); - encode_compound_hdr(&xdr, req, &hdr); - encode_create_session(&xdr, args, &hdr); + encode_compound_hdr(xdr, req, &hdr); + encode_create_session(xdr, args, &hdr); encode_nops(&hdr); - return 0; } /* * a DESTROY_SESSION request */ -static int nfs4_xdr_enc_destroy_session(struct rpc_rqst *req, uint32_t *p, - struct nfs4_session *session) +static void nfs4_xdr_enc_destroy_session(struct rpc_rqst *req, + struct xdr_stream *xdr, + struct nfs4_session *session) { - struct xdr_stream xdr; struct compound_hdr hdr = { .minorversion = session->clp->cl_mvops->minor_version, }; - xdr_init_encode(&xdr, &req->rq_snd_buf, p); - encode_compound_hdr(&xdr, req, &hdr); - encode_destroy_session(&xdr, session, &hdr); + encode_compound_hdr(xdr, req, &hdr); + encode_destroy_session(xdr, session, &hdr); encode_nops(&hdr); - return 0; } /* * a SEQUENCE request */ -static int nfs4_xdr_enc_sequence(struct rpc_rqst *req, uint32_t *p, - struct nfs4_sequence_args *args) +static void nfs4_xdr_enc_sequence(struct rpc_rqst *req, struct xdr_stream *xdr, + struct nfs4_sequence_args *args) { - struct xdr_stream xdr; struct compound_hdr hdr = { .minorversion = nfs4_xdr_minorversion(args), }; - xdr_init_encode(&xdr, &req->rq_snd_buf, p); - encode_compound_hdr(&xdr, req, &hdr); - encode_sequence(&xdr, args, &hdr); + encode_compound_hdr(xdr, req, &hdr); + encode_sequence(xdr, args, &hdr); encode_nops(&hdr); - return 0; } /* * a GET_LEASE_TIME request */ -static int nfs4_xdr_enc_get_lease_time(struct rpc_rqst *req, uint32_t *p, - struct nfs4_get_lease_time_args *args) +static void nfs4_xdr_enc_get_lease_time(struct rpc_rqst *req, + struct xdr_stream *xdr, + struct nfs4_get_lease_time_args *args) { - struct xdr_stream xdr; struct compound_hdr hdr = { .minorversion = nfs4_xdr_minorversion(&args->la_seq_args), }; const u32 lease_bitmap[2] = { FATTR4_WORD0_LEASE_TIME, 0 }; - xdr_init_encode(&xdr, &req->rq_snd_buf, p); - encode_compound_hdr(&xdr, req, &hdr); - encode_sequence(&xdr, &args->la_seq_args, &hdr); - encode_putrootfh(&xdr, &hdr); - encode_fsinfo(&xdr, lease_bitmap, &hdr); + encode_compound_hdr(xdr, req, &hdr); + encode_sequence(xdr, &args->la_seq_args, &hdr); + encode_putrootfh(xdr, &hdr); + encode_fsinfo(xdr, lease_bitmap, &hdr); encode_nops(&hdr); - return 0; } /* * a RECLAIM_COMPLETE request */ -static int nfs4_xdr_enc_reclaim_complete(struct rpc_rqst *req, uint32_t *p, - struct nfs41_reclaim_complete_args *args) +static void nfs4_xdr_enc_reclaim_complete(struct rpc_rqst *req, + struct xdr_stream *xdr, + struct nfs41_reclaim_complete_args *args) { - struct xdr_stream xdr; struct compound_hdr hdr = { .minorversion = nfs4_xdr_minorversion(&args->seq_args) }; - xdr_init_encode(&xdr, &req->rq_snd_buf, p); - encode_compound_hdr(&xdr, req, &hdr); - encode_sequence(&xdr, &args->seq_args, &hdr); - encode_reclaim_complete(&xdr, args, &hdr); + encode_compound_hdr(xdr, req, &hdr); + encode_sequence(xdr, &args->seq_args, &hdr); + encode_reclaim_complete(xdr, args, &hdr); encode_nops(&hdr); - return 0; } /* * Encode GETDEVICEINFO request */ -static int nfs4_xdr_enc_getdeviceinfo(struct rpc_rqst *req, uint32_t *p, - struct nfs4_getdeviceinfo_args *args) +static void nfs4_xdr_enc_getdeviceinfo(struct rpc_rqst *req, + struct xdr_stream *xdr, + struct nfs4_getdeviceinfo_args *args) { - struct xdr_stream xdr; struct compound_hdr hdr = { .minorversion = nfs4_xdr_minorversion(&args->seq_args), }; - xdr_init_encode(&xdr, &req->rq_snd_buf, p); - encode_compound_hdr(&xdr, req, &hdr); - encode_sequence(&xdr, &args->seq_args, &hdr); - encode_getdeviceinfo(&xdr, args, &hdr); + encode_compound_hdr(xdr, req, &hdr); + encode_sequence(xdr, &args->seq_args, &hdr); + encode_getdeviceinfo(xdr, args, &hdr); /* set up reply kvec. Subtract notification bitmap max size (2) * so that notification bitmap is put in xdr_buf tail */ @@ -2657,27 +2583,24 @@ static int nfs4_xdr_enc_getdeviceinfo(struct rpc_rqst *req, uint32_t *p, args->pdev->pglen); encode_nops(&hdr); - return 0; } /* * Encode LAYOUTGET request */ -static int nfs4_xdr_enc_layoutget(struct rpc_rqst *req, uint32_t *p, - struct nfs4_layoutget_args *args) +static void nfs4_xdr_enc_layoutget(struct rpc_rqst *req, + struct xdr_stream *xdr, + struct nfs4_layoutget_args *args) { - struct xdr_stream xdr; struct compound_hdr hdr = { .minorversion = nfs4_xdr_minorversion(&args->seq_args), }; - xdr_init_encode(&xdr, &req->rq_snd_buf, p); - encode_compound_hdr(&xdr, req, &hdr); - encode_sequence(&xdr, &args->seq_args, &hdr); - encode_putfh(&xdr, NFS_FH(args->inode), &hdr); - encode_layoutget(&xdr, args, &hdr); + encode_compound_hdr(xdr, req, &hdr); + encode_sequence(xdr, &args->seq_args, &hdr); + encode_putfh(xdr, NFS_FH(args->inode), &hdr); + encode_layoutget(xdr, args, &hdr); encode_nops(&hdr); - return 0; } #endif /* CONFIG_NFS_V4_1 */ @@ -5368,22 +5291,18 @@ out: /* * Encode an SETACL request */ -static int -nfs4_xdr_enc_setacl(struct rpc_rqst *req, __be32 *p, struct nfs_setaclargs *args) +static void nfs4_xdr_enc_setacl(struct rpc_rqst *req, struct xdr_stream *xdr, + struct nfs_setaclargs *args) { - struct xdr_stream xdr; struct compound_hdr hdr = { .minorversion = nfs4_xdr_minorversion(&args->seq_args), }; - int status; - xdr_init_encode(&xdr, &req->rq_snd_buf, p); - encode_compound_hdr(&xdr, req, &hdr); - encode_sequence(&xdr, &args->seq_args, &hdr); - encode_putfh(&xdr, args->fh, &hdr); - status = encode_setacl(&xdr, args, &hdr); + encode_compound_hdr(xdr, req, &hdr); + encode_sequence(xdr, &args->seq_args, &hdr); + encode_putfh(xdr, args->fh, &hdr); + encode_setacl(xdr, args, &hdr); encode_nops(&hdr); - return status; } /* @@ -6316,7 +6235,7 @@ nfs4_stat_to_errno(int stat) #define PROC(proc, argtype, restype) \ [NFSPROC4_CLNT_##proc] = { \ .p_proc = NFSPROC4_COMPOUND, \ - .p_encode = (kxdrproc_t)nfs4_xdr_##argtype, \ + .p_encode = (kxdreproc_t)nfs4_xdr_##argtype, \ .p_decode = (kxdrproc_t)nfs4_xdr_##restype, \ .p_arglen = NFS4_##argtype##_sz, \ .p_replen = NFS4_##restype##_sz, \ diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c index 6529534d7aae..c363efda8ecf 100644 --- a/fs/nfsd/nfs4callback.c +++ b/fs/nfsd/nfs4callback.c @@ -499,34 +499,28 @@ out_default: /* * NB: Without this zero space reservation, callbacks over krb5p fail */ -static int nfs4_xdr_enc_cb_null(struct rpc_rqst *req, __be32 *p, void *__unused) +static void nfs4_xdr_enc_cb_null(struct rpc_rqst *req, struct xdr_stream *xdr, + void *__unused) { - struct xdr_stream xdrs, *xdr = &xdrs; - - xdr_init_encode(&xdrs, &req->rq_snd_buf, p); xdr_reserve_space(xdr, 0); - return 0; } /* * 20.2. Operation 4: CB_RECALL - Recall a Delegation */ -static int nfs4_xdr_enc_cb_recall(struct rpc_rqst *req, __be32 *p, - const struct nfsd4_callback *cb) +static void nfs4_xdr_enc_cb_recall(struct rpc_rqst *req, struct xdr_stream *xdr, + const struct nfsd4_callback *cb) { - struct xdr_stream xdr; const struct nfs4_delegation *args = cb->cb_op; struct nfs4_cb_compound_hdr hdr = { .ident = cb->cb_clp->cl_cb_ident, .minorversion = cb->cb_minorversion, }; - xdr_init_encode(&xdr, &req->rq_snd_buf, p); - encode_cb_compound4args(&xdr, &hdr); - encode_cb_sequence4args(&xdr, cb, &hdr); - encode_cb_recall4args(&xdr, args, &hdr); + encode_cb_compound4args(xdr, &hdr); + encode_cb_sequence4args(xdr, cb, &hdr); + encode_cb_recall4args(xdr, args, &hdr); encode_cb_nops(&hdr); - return 0; } @@ -583,7 +577,7 @@ out_default: #define PROC(proc, call, argtype, restype) \ [NFSPROC4_CLNT_##proc] = { \ .p_proc = NFSPROC4_CB_##call, \ - .p_encode = (kxdrproc_t)nfs4_xdr_enc_##argtype, \ + .p_encode = (kxdreproc_t)nfs4_xdr_enc_##argtype, \ .p_decode = (kxdrproc_t)nfs4_xdr_dec_##restype, \ .p_arglen = NFS4_enc_##argtype##_sz, \ .p_replen = NFS4_dec_##restype##_sz, \ diff --git a/include/linux/sunrpc/auth.h b/include/linux/sunrpc/auth.h index b2024757edd5..d88cffbaa6df 100644 --- a/include/linux/sunrpc/auth.h +++ b/include/linux/sunrpc/auth.h @@ -110,7 +110,7 @@ struct rpc_credops { __be32 * (*crmarshal)(struct rpc_task *, __be32 *); int (*crrefresh)(struct rpc_task *); __be32 * (*crvalidate)(struct rpc_task *, __be32 *); - int (*crwrap_req)(struct rpc_task *, kxdrproc_t, + int (*crwrap_req)(struct rpc_task *, kxdreproc_t, void *, __be32 *, void *); int (*crunwrap_resp)(struct rpc_task *, kxdrproc_t, void *, __be32 *, void *); @@ -139,7 +139,7 @@ struct rpc_cred * rpcauth_generic_bind_cred(struct rpc_task *, struct rpc_cred * void put_rpccred(struct rpc_cred *); __be32 * rpcauth_marshcred(struct rpc_task *, __be32 *); __be32 * rpcauth_checkverf(struct rpc_task *, __be32 *); -int rpcauth_wrap_req(struct rpc_task *task, kxdrproc_t encode, void *rqstp, __be32 *data, void *obj); +int rpcauth_wrap_req(struct rpc_task *task, kxdreproc_t encode, void *rqstp, __be32 *data, void *obj); int rpcauth_unwrap_resp(struct rpc_task *task, kxdrproc_t decode, void *rqstp, __be32 *data, void *obj); int rpcauth_refreshcred(struct rpc_task *); void rpcauth_invalcred(struct rpc_task *); diff --git a/include/linux/sunrpc/clnt.h b/include/linux/sunrpc/clnt.h index a5a55f284b7d..7b19c4e1ce53 100644 --- a/include/linux/sunrpc/clnt.h +++ b/include/linux/sunrpc/clnt.h @@ -89,7 +89,7 @@ struct rpc_version { */ struct rpc_procinfo { u32 p_proc; /* RPC procedure number */ - kxdrproc_t p_encode; /* XDR encode function */ + kxdreproc_t p_encode; /* XDR encode function */ kxdrproc_t p_decode; /* XDR decode function */ unsigned int p_arglen; /* argument hdr length (u32) */ unsigned int p_replen; /* reply hdr length (u32) */ diff --git a/include/linux/sunrpc/xdr.h b/include/linux/sunrpc/xdr.h index 498ab93a81e4..a21cf5378c1d 100644 --- a/include/linux/sunrpc/xdr.h +++ b/include/linux/sunrpc/xdr.h @@ -33,8 +33,8 @@ struct xdr_netobj { }; /* - * This is the generic XDR function. rqstp is either a rpc_rqst (client - * side) or svc_rqst pointer (server side). + * This is the legacy generic XDR function. rqstp is either a rpc_rqst + * (client side) or svc_rqst pointer (server side). * Encode functions always assume there's enough room in the buffer. */ typedef int (*kxdrproc_t)(void *rqstp, __be32 *data, void *obj); @@ -203,6 +203,11 @@ struct xdr_stream { struct kvec *iov; /* pointer to the current kvec */ }; +/* + * This is the xdr_stream style generic XDR function. + */ +typedef void (*kxdreproc_t)(void *rqstp, struct xdr_stream *xdr, void *obj); + extern void xdr_init_encode(struct xdr_stream *xdr, struct xdr_buf *buf, __be32 *p); extern __be32 *xdr_reserve_space(struct xdr_stream *xdr, size_t nbytes); extern void xdr_write_pages(struct xdr_stream *xdr, struct page **pages, diff --git a/net/sunrpc/auth.c b/net/sunrpc/auth.c index afe67849269f..651c9da703cb 100644 --- a/net/sunrpc/auth.c +++ b/net/sunrpc/auth.c @@ -563,8 +563,17 @@ rpcauth_checkverf(struct rpc_task *task, __be32 *p) return cred->cr_ops->crvalidate(task, p); } +static void rpcauth_wrap_req_encode(kxdreproc_t encode, struct rpc_rqst *rqstp, + __be32 *data, void *obj) +{ + struct xdr_stream xdr; + + xdr_init_encode(&xdr, &rqstp->rq_snd_buf, data); + encode(rqstp, &xdr, obj); +} + int -rpcauth_wrap_req(struct rpc_task *task, kxdrproc_t encode, void *rqstp, +rpcauth_wrap_req(struct rpc_task *task, kxdreproc_t encode, void *rqstp, __be32 *data, void *obj) { struct rpc_cred *cred = task->tk_rqstp->rq_cred; @@ -574,7 +583,8 @@ rpcauth_wrap_req(struct rpc_task *task, kxdrproc_t encode, void *rqstp, if (cred->cr_ops->crwrap_req) return cred->cr_ops->crwrap_req(task, encode, rqstp, data, obj); /* By default, we encode the arguments normally. */ - return encode(rqstp, data, obj); + rpcauth_wrap_req_encode(encode, rqstp, data, obj); + return 0; } int diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c index 3835ce35e224..42b46f9a670a 100644 --- a/net/sunrpc/auth_gss/auth_gss.c +++ b/net/sunrpc/auth_gss/auth_gss.c @@ -1231,9 +1231,19 @@ out_bad: return NULL; } +static void gss_wrap_req_encode(kxdreproc_t encode, struct rpc_rqst *rqstp, + __be32 *p, void *obj) +{ + struct xdr_stream xdr; + + xdr_init_encode(&xdr, &rqstp->rq_snd_buf, p); + encode(rqstp, &xdr, obj); +} + static inline int gss_wrap_req_integ(struct rpc_cred *cred, struct gss_cl_ctx *ctx, - kxdrproc_t encode, struct rpc_rqst *rqstp, __be32 *p, void *obj) + kxdreproc_t encode, struct rpc_rqst *rqstp, + __be32 *p, void *obj) { struct xdr_buf *snd_buf = &rqstp->rq_snd_buf; struct xdr_buf integ_buf; @@ -1249,9 +1259,7 @@ gss_wrap_req_integ(struct rpc_cred *cred, struct gss_cl_ctx *ctx, offset = (u8 *)p - (u8 *)snd_buf->head[0].iov_base; *p++ = htonl(rqstp->rq_seqno); - status = encode(rqstp, p, obj); - if (status) - return status; + gss_wrap_req_encode(encode, rqstp, p, obj); if (xdr_buf_subsegment(snd_buf, &integ_buf, offset, snd_buf->len - offset)) @@ -1325,7 +1333,8 @@ out: static inline int gss_wrap_req_priv(struct rpc_cred *cred, struct gss_cl_ctx *ctx, - kxdrproc_t encode, struct rpc_rqst *rqstp, __be32 *p, void *obj) + kxdreproc_t encode, struct rpc_rqst *rqstp, + __be32 *p, void *obj) { struct xdr_buf *snd_buf = &rqstp->rq_snd_buf; u32 offset; @@ -1342,9 +1351,7 @@ gss_wrap_req_priv(struct rpc_cred *cred, struct gss_cl_ctx *ctx, offset = (u8 *)p - (u8 *)snd_buf->head[0].iov_base; *p++ = htonl(rqstp->rq_seqno); - status = encode(rqstp, p, obj); - if (status) - return status; + gss_wrap_req_encode(encode, rqstp, p, obj); status = alloc_enc_pages(rqstp); if (status) @@ -1394,7 +1401,7 @@ gss_wrap_req_priv(struct rpc_cred *cred, struct gss_cl_ctx *ctx, static int gss_wrap_req(struct rpc_task *task, - kxdrproc_t encode, void *rqstp, __be32 *p, void *obj) + kxdreproc_t encode, void *rqstp, __be32 *p, void *obj) { struct rpc_cred *cred = task->tk_rqstp->rq_cred; struct gss_cred *gss_cred = container_of(cred, struct gss_cred, @@ -1407,12 +1414,14 @@ gss_wrap_req(struct rpc_task *task, /* The spec seems a little ambiguous here, but I think that not * wrapping context destruction requests makes the most sense. */ - status = encode(rqstp, p, obj); + gss_wrap_req_encode(encode, rqstp, p, obj); + status = 0; goto out; } switch (gss_cred->gc_service) { case RPC_GSS_SVC_NONE: - status = encode(rqstp, p, obj); + gss_wrap_req_encode(encode, rqstp, p, obj); + status = 0; break; case RPC_GSS_SVC_INTEGRITY: status = gss_wrap_req_integ(cred, ctx, encode, diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c index 92ce94f5146b..d446a32be667 100644 --- a/net/sunrpc/clnt.c +++ b/net/sunrpc/clnt.c @@ -1095,7 +1095,7 @@ static void rpc_xdr_encode(struct rpc_task *task) { struct rpc_rqst *req = task->tk_rqstp; - kxdrproc_t encode; + kxdreproc_t encode; __be32 *p; dprint_status(task); @@ -1776,9 +1776,8 @@ out_overflow: goto out_garbage; } -static int rpcproc_encode_null(void *rqstp, __be32 *data, void *obj) +static void rpcproc_encode_null(void *rqstp, struct xdr_stream *xdr, void *obj) { - return 0; } static int rpcproc_decode_null(void *rqstp, __be32 *data, void *obj) diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c index 43838c72b778..63912a1a2983 100644 --- a/net/sunrpc/rpcb_clnt.c +++ b/net/sunrpc/rpcb_clnt.c @@ -689,25 +689,21 @@ static void rpcb_getport_done(struct rpc_task *child, void *data) * XDR functions for rpcbind */ -static int rpcb_enc_mapping(struct rpc_rqst *req, __be32 *p, - const struct rpcbind_args *rpcb) +static void rpcb_enc_mapping(struct rpc_rqst *req, struct xdr_stream *xdr, + const struct rpcbind_args *rpcb) { struct rpc_task *task = req->rq_task; - struct xdr_stream xdr; + __be32 *p; dprintk("RPC: %5u encoding PMAP_%s call (%u, %u, %d, %u)\n", task->tk_pid, task->tk_msg.rpc_proc->p_name, rpcb->r_prog, rpcb->r_vers, rpcb->r_prot, rpcb->r_port); - xdr_init_encode(&xdr, &req->rq_snd_buf, p); - - p = xdr_reserve_space(&xdr, RPCB_mappingargs_sz << 2); + p = xdr_reserve_space(xdr, RPCB_mappingargs_sz << 2); *p++ = cpu_to_be32(rpcb->r_prog); *p++ = cpu_to_be32(rpcb->r_vers); *p++ = cpu_to_be32(rpcb->r_prot); *p = cpu_to_be32(rpcb->r_port); - - return 0; } static int rpcb_dec_getport(struct rpc_rqst *req, __be32 *p, @@ -769,27 +765,24 @@ static void encode_rpcb_string(struct xdr_stream *xdr, const char *string, xdr_encode_opaque(p, string, len); } -static int rpcb_enc_getaddr(struct rpc_rqst *req, __be32 *p, - const struct rpcbind_args *rpcb) +static void rpcb_enc_getaddr(struct rpc_rqst *req, struct xdr_stream *xdr, + const struct rpcbind_args *rpcb) { struct rpc_task *task = req->rq_task; - struct xdr_stream xdr; + __be32 *p; dprintk("RPC: %5u encoding RPCB_%s call (%u, %u, '%s', '%s')\n", task->tk_pid, task->tk_msg.rpc_proc->p_name, rpcb->r_prog, rpcb->r_vers, rpcb->r_netid, rpcb->r_addr); - xdr_init_encode(&xdr, &req->rq_snd_buf, p); - - p = xdr_reserve_space(&xdr, (RPCB_program_sz + RPCB_version_sz) << 2); + p = xdr_reserve_space(xdr, (RPCB_program_sz + RPCB_version_sz) << 2); *p++ = cpu_to_be32(rpcb->r_prog); *p = cpu_to_be32(rpcb->r_vers); - encode_rpcb_string(&xdr, rpcb->r_netid, RPCBIND_MAXNETIDLEN); - encode_rpcb_string(&xdr, rpcb->r_addr, RPCBIND_MAXUADDRLEN); - encode_rpcb_string(&xdr, rpcb->r_owner, RPCB_MAXOWNERLEN); - return 0; + encode_rpcb_string(xdr, rpcb->r_netid, RPCBIND_MAXNETIDLEN); + encode_rpcb_string(xdr, rpcb->r_addr, RPCBIND_MAXUADDRLEN); + encode_rpcb_string(xdr, rpcb->r_owner, RPCB_MAXOWNERLEN); } static int rpcb_dec_getaddr(struct rpc_rqst *req, __be32 *p, @@ -849,7 +842,7 @@ out_fail: static struct rpc_procinfo rpcb_procedures2[] = { [RPCBPROC_SET] = { .p_proc = RPCBPROC_SET, - .p_encode = (kxdrproc_t)rpcb_enc_mapping, + .p_encode = (kxdreproc_t)rpcb_enc_mapping, .p_decode = (kxdrproc_t)rpcb_dec_set, .p_arglen = RPCB_mappingargs_sz, .p_replen = RPCB_setres_sz, @@ -859,7 +852,7 @@ static struct rpc_procinfo rpcb_procedures2[] = { }, [RPCBPROC_UNSET] = { .p_proc = RPCBPROC_UNSET, - .p_encode = (kxdrproc_t)rpcb_enc_mapping, + .p_encode = (kxdreproc_t)rpcb_enc_mapping, .p_decode = (kxdrproc_t)rpcb_dec_set, .p_arglen = RPCB_mappingargs_sz, .p_replen = RPCB_setres_sz, @@ -869,7 +862,7 @@ static struct rpc_procinfo rpcb_procedures2[] = { }, [RPCBPROC_GETPORT] = { .p_proc = RPCBPROC_GETPORT, - .p_encode = (kxdrproc_t)rpcb_enc_mapping, + .p_encode = (kxdreproc_t)rpcb_enc_mapping, .p_decode = (kxdrproc_t)rpcb_dec_getport, .p_arglen = RPCB_mappingargs_sz, .p_replen = RPCB_getportres_sz, @@ -882,7 +875,7 @@ static struct rpc_procinfo rpcb_procedures2[] = { static struct rpc_procinfo rpcb_procedures3[] = { [RPCBPROC_SET] = { .p_proc = RPCBPROC_SET, - .p_encode = (kxdrproc_t)rpcb_enc_getaddr, + .p_encode = (kxdreproc_t)rpcb_enc_getaddr, .p_decode = (kxdrproc_t)rpcb_dec_set, .p_arglen = RPCB_getaddrargs_sz, .p_replen = RPCB_setres_sz, @@ -892,7 +885,7 @@ static struct rpc_procinfo rpcb_procedures3[] = { }, [RPCBPROC_UNSET] = { .p_proc = RPCBPROC_UNSET, - .p_encode = (kxdrproc_t)rpcb_enc_getaddr, + .p_encode = (kxdreproc_t)rpcb_enc_getaddr, .p_decode = (kxdrproc_t)rpcb_dec_set, .p_arglen = RPCB_getaddrargs_sz, .p_replen = RPCB_setres_sz, @@ -902,7 +895,7 @@ static struct rpc_procinfo rpcb_procedures3[] = { }, [RPCBPROC_GETADDR] = { .p_proc = RPCBPROC_GETADDR, - .p_encode = (kxdrproc_t)rpcb_enc_getaddr, + .p_encode = (kxdreproc_t)rpcb_enc_getaddr, .p_decode = (kxdrproc_t)rpcb_dec_getaddr, .p_arglen = RPCB_getaddrargs_sz, .p_replen = RPCB_getaddrres_sz, @@ -915,7 +908,7 @@ static struct rpc_procinfo rpcb_procedures3[] = { static struct rpc_procinfo rpcb_procedures4[] = { [RPCBPROC_SET] = { .p_proc = RPCBPROC_SET, - .p_encode = (kxdrproc_t)rpcb_enc_getaddr, + .p_encode = (kxdreproc_t)rpcb_enc_getaddr, .p_decode = (kxdrproc_t)rpcb_dec_set, .p_arglen = RPCB_getaddrargs_sz, .p_replen = RPCB_setres_sz, @@ -925,7 +918,7 @@ static struct rpc_procinfo rpcb_procedures4[] = { }, [RPCBPROC_UNSET] = { .p_proc = RPCBPROC_UNSET, - .p_encode = (kxdrproc_t)rpcb_enc_getaddr, + .p_encode = (kxdreproc_t)rpcb_enc_getaddr, .p_decode = (kxdrproc_t)rpcb_dec_set, .p_arglen = RPCB_getaddrargs_sz, .p_replen = RPCB_setres_sz, @@ -935,7 +928,7 @@ static struct rpc_procinfo rpcb_procedures4[] = { }, [RPCBPROC_GETADDR] = { .p_proc = RPCBPROC_GETADDR, - .p_encode = (kxdrproc_t)rpcb_enc_getaddr, + .p_encode = (kxdreproc_t)rpcb_enc_getaddr, .p_decode = (kxdrproc_t)rpcb_dec_getaddr, .p_arglen = RPCB_getaddrargs_sz, .p_replen = RPCB_getaddrres_sz, -- cgit v1.2.3 From bf2695516db982e90a22fc94f93491b481796bb1 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Tue, 14 Dec 2010 14:59:29 +0000 Subject: SUNRPC: New xdr_streams XDR decoder API Now that all client-side XDR decoder routines use xdr_streams, there should be no need to support the legacy calling sequence [rpc_rqst *, __be32 *, RPC res *] anywhere. We can construct an xdr_stream in the generic RPC code, instead of in each decoder function. This is a refactoring change. It should not cause different behavior. Signed-off-by: Chuck Lever Tested-by: J. Bruce Fields Signed-off-by: Trond Myklebust --- fs/lockd/clnt4xdr.c | 20 +- fs/lockd/clntxdr.c | 20 +- fs/lockd/mon.c | 30 +- fs/nfs/mount_clnt.c | 30 +- fs/nfs/nfs2xdr.c | 68 ++--- fs/nfs/nfs3xdr.c | 195 ++++++------- fs/nfs/nfs4xdr.c | 619 ++++++++++++++++++++--------------------- fs/nfsd/nfs4callback.c | 16 +- include/linux/sunrpc/auth.h | 4 +- include/linux/sunrpc/clnt.h | 2 +- include/linux/sunrpc/xdr.h | 3 +- net/sunrpc/auth.c | 14 +- net/sunrpc/auth_gss/auth_gss.c | 13 +- net/sunrpc/clnt.c | 4 +- net/sunrpc/rpcb_clnt.c | 46 ++- 15 files changed, 518 insertions(+), 566 deletions(-) diff --git a/fs/lockd/clnt4xdr.c b/fs/lockd/clnt4xdr.c index 974f1d9cd323..f848b52c67b1 100644 --- a/fs/lockd/clnt4xdr.c +++ b/fs/lockd/clnt4xdr.c @@ -529,17 +529,16 @@ out: return error; } -static int nlm4_xdr_dec_testres(struct rpc_rqst *req, __be32 *p, +static int nlm4_xdr_dec_testres(struct rpc_rqst *req, + struct xdr_stream *xdr, struct nlm_res *result) { - struct xdr_stream xdr; int error; - xdr_init_decode(&xdr, &req->rq_rcv_buf, p); - error = decode_cookie(&xdr, &result->cookie); + error = decode_cookie(xdr, &result->cookie); if (unlikely(error)) goto out; - error = decode_nlm4_testrply(&xdr, result); + error = decode_nlm4_testrply(xdr, result); out: return error; } @@ -550,17 +549,16 @@ out: * nlm4_stat stat; * }; */ -static int nlm4_xdr_dec_res(struct rpc_rqst *req, __be32 *p, +static int nlm4_xdr_dec_res(struct rpc_rqst *req, + struct xdr_stream *xdr, struct nlm_res *result) { - struct xdr_stream xdr; int error; - xdr_init_decode(&xdr, &req->rq_rcv_buf, p); - error = decode_cookie(&xdr, &result->cookie); + error = decode_cookie(xdr, &result->cookie); if (unlikely(error)) goto out; - error = decode_nlm4_stat(&xdr, &result->status); + error = decode_nlm4_stat(xdr, &result->status); out: return error; } @@ -575,7 +573,7 @@ out: [NLMPROC_##proc] = { \ .p_proc = NLMPROC_##proc, \ .p_encode = (kxdreproc_t)nlm4_xdr_enc_##argtype, \ - .p_decode = (kxdrproc_t)nlm4_xdr_dec_##restype, \ + .p_decode = (kxdrdproc_t)nlm4_xdr_dec_##restype, \ .p_arglen = NLM4_##argtype##_sz, \ .p_replen = NLM4_##restype##_sz, \ .p_statidx = NLMPROC_##proc, \ diff --git a/fs/lockd/clntxdr.c b/fs/lockd/clntxdr.c index c6fda8fb1c5b..180ac34feb9a 100644 --- a/fs/lockd/clntxdr.c +++ b/fs/lockd/clntxdr.c @@ -527,17 +527,16 @@ out: return error; } -static int nlm_xdr_dec_testres(struct rpc_rqst *req, __be32 *p, +static int nlm_xdr_dec_testres(struct rpc_rqst *req, + struct xdr_stream *xdr, struct nlm_res *result) { - struct xdr_stream xdr; int error; - xdr_init_decode(&xdr, &req->rq_rcv_buf, p); - error = decode_cookie(&xdr, &result->cookie); + error = decode_cookie(xdr, &result->cookie); if (unlikely(error)) goto out; - error = decode_nlm_testrply(&xdr, result); + error = decode_nlm_testrply(xdr, result); out: return error; } @@ -548,17 +547,16 @@ out: * nlm_stat stat; * }; */ -static int nlm_xdr_dec_res(struct rpc_rqst *req, __be32 *p, +static int nlm_xdr_dec_res(struct rpc_rqst *req, + struct xdr_stream *xdr, struct nlm_res *result) { - struct xdr_stream xdr; int error; - xdr_init_decode(&xdr, &req->rq_rcv_buf, p); - error = decode_cookie(&xdr, &result->cookie); + error = decode_cookie(xdr, &result->cookie); if (unlikely(error)) goto out; - error = decode_nlm_stat(&xdr, &result->status); + error = decode_nlm_stat(xdr, &result->status); out: return error; } @@ -573,7 +571,7 @@ out: [NLMPROC_##proc] = { \ .p_proc = NLMPROC_##proc, \ .p_encode = (kxdreproc_t)nlm_xdr_enc_##argtype, \ - .p_decode = (kxdrproc_t)nlm_xdr_dec_##restype, \ + .p_decode = (kxdrdproc_t)nlm_xdr_dec_##restype, \ .p_arglen = NLM_##argtype##_sz, \ .p_replen = NLM_##restype##_sz, \ .p_statidx = NLMPROC_##proc, \ diff --git a/fs/lockd/mon.c b/fs/lockd/mon.c index baa77bc9d825..23d7451b2938 100644 --- a/fs/lockd/mon.c +++ b/fs/lockd/mon.c @@ -472,35 +472,35 @@ static void nsm_xdr_enc_unmon(struct rpc_rqst *req, struct xdr_stream *xdr, encode_mon_id(xdr, argp); } -static int xdr_dec_stat_res(struct rpc_rqst *rqstp, __be32 *p, - struct nsm_res *resp) +static int nsm_xdr_dec_stat_res(struct rpc_rqst *rqstp, + struct xdr_stream *xdr, + struct nsm_res *resp) { - struct xdr_stream xdr; + __be32 *p; - xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p); - p = xdr_inline_decode(&xdr, 4 + 4); + p = xdr_inline_decode(xdr, 4 + 4); if (unlikely(p == NULL)) return -EIO; resp->status = be32_to_cpup(p++); resp->state = be32_to_cpup(p); - dprintk("lockd: xdr_dec_stat_res status %d state %d\n", - resp->status, resp->state); + dprintk("lockd: %s status %d state %d\n", + __func__, resp->status, resp->state); return 0; } -static int xdr_dec_stat(struct rpc_rqst *rqstp, __be32 *p, - struct nsm_res *resp) +static int nsm_xdr_dec_stat(struct rpc_rqst *rqstp, + struct xdr_stream *xdr, + struct nsm_res *resp) { - struct xdr_stream xdr; + __be32 *p; - xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p); - p = xdr_inline_decode(&xdr, 4); + p = xdr_inline_decode(xdr, 4); if (unlikely(p == NULL)) return -EIO; resp->state = be32_to_cpup(p); - dprintk("lockd: xdr_dec_stat state %d\n", resp->state); + dprintk("lockd: %s state %d\n", __func__, resp->state); return 0; } @@ -517,7 +517,7 @@ static struct rpc_procinfo nsm_procedures[] = { [NSMPROC_MON] = { .p_proc = NSMPROC_MON, .p_encode = (kxdreproc_t)nsm_xdr_enc_mon, - .p_decode = (kxdrproc_t)xdr_dec_stat_res, + .p_decode = (kxdrdproc_t)nsm_xdr_dec_stat_res, .p_arglen = SM_mon_sz, .p_replen = SM_monres_sz, .p_statidx = NSMPROC_MON, @@ -526,7 +526,7 @@ static struct rpc_procinfo nsm_procedures[] = { [NSMPROC_UNMON] = { .p_proc = NSMPROC_UNMON, .p_encode = (kxdreproc_t)nsm_xdr_enc_unmon, - .p_decode = (kxdrproc_t)xdr_dec_stat, + .p_decode = (kxdrdproc_t)nsm_xdr_dec_stat, .p_arglen = SM_mon_id_sz, .p_replen = SM_unmonres_sz, .p_statidx = NSMPROC_UNMON, diff --git a/fs/nfs/mount_clnt.c b/fs/nfs/mount_clnt.c index 979ebd7af3cb..697e07235f30 100644 --- a/fs/nfs/mount_clnt.c +++ b/fs/nfs/mount_clnt.c @@ -340,18 +340,16 @@ static int decode_fhandle(struct xdr_stream *xdr, struct mountres *res) return 0; } -static int mnt_dec_mountres(struct rpc_rqst *req, __be32 *p, - struct mountres *res) +static int mnt_xdr_dec_mountres(struct rpc_rqst *req, + struct xdr_stream *xdr, + struct mountres *res) { - struct xdr_stream xdr; int status; - xdr_init_decode(&xdr, &req->rq_rcv_buf, p); - - status = decode_status(&xdr, res); + status = decode_status(xdr, res); if (unlikely(status != 0 || res->errno != 0)) return status; - return decode_fhandle(&xdr, res); + return decode_fhandle(xdr, res); } static int decode_fhs_status(struct xdr_stream *xdr, struct mountres *res) @@ -434,30 +432,28 @@ static int decode_auth_flavors(struct xdr_stream *xdr, struct mountres *res) return 0; } -static int mnt_dec_mountres3(struct rpc_rqst *req, __be32 *p, - struct mountres *res) +static int mnt_xdr_dec_mountres3(struct rpc_rqst *req, + struct xdr_stream *xdr, + struct mountres *res) { - struct xdr_stream xdr; int status; - xdr_init_decode(&xdr, &req->rq_rcv_buf, p); - - status = decode_fhs_status(&xdr, res); + status = decode_fhs_status(xdr, res); if (unlikely(status != 0 || res->errno != 0)) return status; - status = decode_fhandle3(&xdr, res); + status = decode_fhandle3(xdr, res); if (unlikely(status != 0)) { res->errno = -EBADHANDLE; return 0; } - return decode_auth_flavors(&xdr, res); + return decode_auth_flavors(xdr, res); } static struct rpc_procinfo mnt_procedures[] = { [MOUNTPROC_MNT] = { .p_proc = MOUNTPROC_MNT, .p_encode = (kxdreproc_t)mnt_xdr_enc_dirpath, - .p_decode = (kxdrproc_t)mnt_dec_mountres, + .p_decode = (kxdrdproc_t)mnt_xdr_dec_mountres, .p_arglen = MNT_enc_dirpath_sz, .p_replen = MNT_dec_mountres_sz, .p_statidx = MOUNTPROC_MNT, @@ -476,7 +472,7 @@ static struct rpc_procinfo mnt3_procedures[] = { [MOUNTPROC3_MNT] = { .p_proc = MOUNTPROC3_MNT, .p_encode = (kxdreproc_t)mnt_xdr_enc_dirpath, - .p_decode = (kxdrproc_t)mnt_dec_mountres3, + .p_decode = (kxdrdproc_t)mnt_xdr_dec_mountres3, .p_arglen = MNT_enc_dirpath_sz, .p_replen = MNT_dec_mountres3_sz, .p_statidx = MOUNTPROC3_MNT, diff --git a/fs/nfs/nfs2xdr.c b/fs/nfs/nfs2xdr.c index 8f3acbec761f..51f1cfa04d27 100644 --- a/fs/nfs/nfs2xdr.c +++ b/fs/nfs/nfs2xdr.c @@ -783,15 +783,13 @@ static void nfs2_xdr_enc_readdirargs(struct rpc_rqst *req, * "NFS: Network File System Protocol Specification". */ -static int nfs2_xdr_dec_stat(struct rpc_rqst *req, __be32 *p, +static int nfs2_xdr_dec_stat(struct rpc_rqst *req, struct xdr_stream *xdr, void *__unused) { - struct xdr_stream xdr; enum nfs_stat status; int error; - xdr_init_decode(&xdr, &req->rq_rcv_buf, p); - error = decode_stat(&xdr, &status); + error = decode_stat(xdr, &status); if (unlikely(error)) goto out; if (status != NFS_OK) @@ -802,22 +800,16 @@ out_default: return nfs_stat_to_errno(status); } -static int nfs2_xdr_dec_attrstat(struct rpc_rqst *req, __be32 *p, +static int nfs2_xdr_dec_attrstat(struct rpc_rqst *req, struct xdr_stream *xdr, struct nfs_fattr *result) { - struct xdr_stream xdr; - - xdr_init_decode(&xdr, &req->rq_rcv_buf, p); - return decode_attrstat(&xdr, result); + return decode_attrstat(xdr, result); } -static int nfs2_xdr_dec_diropres(struct rpc_rqst *req, __be32 *p, +static int nfs2_xdr_dec_diropres(struct rpc_rqst *req, struct xdr_stream *xdr, struct nfs_diropok *result) { - struct xdr_stream xdr; - - xdr_init_decode(&xdr, &req->rq_rcv_buf, p); - return decode_diropres(&xdr, result); + return decode_diropres(xdr, result); } /* @@ -830,20 +822,18 @@ static int nfs2_xdr_dec_diropres(struct rpc_rqst *req, __be32 *p, * void; * }; */ -static int nfs2_xdr_dec_readlinkres(struct rpc_rqst *req, __be32 *p, - void *__unused) +static int nfs2_xdr_dec_readlinkres(struct rpc_rqst *req, + struct xdr_stream *xdr, void *__unused) { - struct xdr_stream xdr; enum nfs_stat status; int error; - xdr_init_decode(&xdr, &req->rq_rcv_buf, p); - error = decode_stat(&xdr, &status); + error = decode_stat(xdr, &status); if (unlikely(error)) goto out; if (status != NFS_OK) goto out_default; - error = decode_path(&xdr); + error = decode_path(xdr); out: return error; out_default: @@ -861,39 +851,33 @@ out_default: * void; * }; */ -static int nfs2_xdr_dec_readres(struct rpc_rqst *req, __be32 *p, +static int nfs2_xdr_dec_readres(struct rpc_rqst *req, struct xdr_stream *xdr, struct nfs_readres *result) { - struct xdr_stream xdr; enum nfs_stat status; int error; - xdr_init_decode(&xdr, &req->rq_rcv_buf, p); - error = decode_stat(&xdr, &status); + error = decode_stat(xdr, &status); if (unlikely(error)) goto out; if (status != NFS_OK) goto out_default; - error = decode_fattr(&xdr, result->fattr); + error = decode_fattr(xdr, result->fattr); if (unlikely(error)) goto out; - error = decode_nfsdata(&xdr, result); + error = decode_nfsdata(xdr, result); out: return error; out_default: return nfs_stat_to_errno(status); } -static int nfs2_xdr_dec_writeres(struct rpc_rqst *req, __be32 *p, +static int nfs2_xdr_dec_writeres(struct rpc_rqst *req, struct xdr_stream *xdr, struct nfs_writeres *result) { - struct xdr_stream xdr; - /* All NFSv2 writes are "file sync" writes */ result->verf->committed = NFS_FILE_SYNC; - - xdr_init_decode(&xdr, &req->rq_rcv_buf, p); - return decode_attrstat(&xdr, result->fattr); + return decode_attrstat(xdr, result->fattr); } /** @@ -1008,20 +992,18 @@ out_cheating: goto out; } -static int nfs2_xdr_dec_readdirres(struct rpc_rqst *req, __be32 *p, - void *__unused) +static int nfs2_xdr_dec_readdirres(struct rpc_rqst *req, + struct xdr_stream *xdr, void *__unused) { - struct xdr_stream xdr; enum nfs_stat status; int error; - xdr_init_decode(&xdr, &req->rq_rcv_buf, p); - error = decode_stat(&xdr, &status); + error = decode_stat(xdr, &status); if (unlikely(error)) goto out; if (status != NFS_OK) goto out_default; - error = decode_readdirok(&xdr); + error = decode_readdirok(xdr); out: return error; out_default: @@ -1062,20 +1044,18 @@ out_overflow: return -EIO; } -static int nfs2_xdr_dec_statfsres(struct rpc_rqst *req, __be32 *p, +static int nfs2_xdr_dec_statfsres(struct rpc_rqst *req, struct xdr_stream *xdr, struct nfs2_fsstat *result) { - struct xdr_stream xdr; enum nfs_stat status; int error; - xdr_init_decode(&xdr, &req->rq_rcv_buf, p); - error = decode_stat(&xdr, &status); + error = decode_stat(xdr, &status); if (unlikely(error)) goto out; if (status != NFS_OK) goto out_default; - error = decode_info(&xdr, result); + error = decode_info(xdr, result); out: return error; out_default: @@ -1150,7 +1130,7 @@ int nfs_stat_to_errno(enum nfs_stat status) [NFSPROC_##proc] = { \ .p_proc = NFSPROC_##proc, \ .p_encode = (kxdreproc_t)nfs2_xdr_enc_##argtype, \ - .p_decode = (kxdrproc_t)nfs2_xdr_dec_##restype, \ + .p_decode = (kxdrdproc_t)nfs2_xdr_dec_##restype, \ .p_arglen = NFS_##argtype##_sz, \ .p_replen = NFS_##restype##_sz, \ .p_timer = timer, \ diff --git a/fs/nfs/nfs3xdr.c b/fs/nfs/nfs3xdr.c index ae1b1a43f05e..df30a26cc4fa 100644 --- a/fs/nfs/nfs3xdr.c +++ b/fs/nfs/nfs3xdr.c @@ -1366,20 +1366,19 @@ static void nfs3_xdr_enc_setacl3args(struct rpc_rqst *req, * void; * }; */ -static int nfs3_xdr_dec_getattr3res(struct rpc_rqst *req, __be32 *p, +static int nfs3_xdr_dec_getattr3res(struct rpc_rqst *req, + struct xdr_stream *xdr, struct nfs_fattr *result) { - struct xdr_stream xdr; enum nfs_stat status; int error; - xdr_init_decode(&xdr, &req->rq_rcv_buf, p); - error = decode_nfsstat3(&xdr, &status); + error = decode_nfsstat3(xdr, &status); if (unlikely(error)) goto out; if (status != NFS3_OK) goto out_default; - error = decode_fattr3(&xdr, result); + error = decode_fattr3(xdr, result); out: return error; out_default: @@ -1404,18 +1403,17 @@ out_default: * SETATTR3resfail resfail; * }; */ -static int nfs3_xdr_dec_setattr3res(struct rpc_rqst *req, __be32 *p, +static int nfs3_xdr_dec_setattr3res(struct rpc_rqst *req, + struct xdr_stream *xdr, struct nfs_fattr *result) { - struct xdr_stream xdr; enum nfs_stat status; int error; - xdr_init_decode(&xdr, &req->rq_rcv_buf, p); - error = decode_nfsstat3(&xdr, &status); + error = decode_nfsstat3(xdr, &status); if (unlikely(error)) goto out; - error = decode_wcc_data(&xdr, result); + error = decode_wcc_data(xdr, result); if (unlikely(error)) goto out; if (status != NFS3_OK) @@ -1446,30 +1444,29 @@ out_status: * LOOKUP3resfail resfail; * }; */ -static int nfs3_xdr_dec_lookup3res(struct rpc_rqst *req, __be32 *p, +static int nfs3_xdr_dec_lookup3res(struct rpc_rqst *req, + struct xdr_stream *xdr, struct nfs3_diropres *result) { - struct xdr_stream xdr; enum nfs_stat status; int error; - xdr_init_decode(&xdr, &req->rq_rcv_buf, p); - error = decode_nfsstat3(&xdr, &status); + error = decode_nfsstat3(xdr, &status); if (unlikely(error)) goto out; if (status != NFS3_OK) goto out_default; - error = decode_nfs_fh3(&xdr, result->fh); + error = decode_nfs_fh3(xdr, result->fh); if (unlikely(error)) goto out; - error = decode_post_op_attr(&xdr, result->fattr); + error = decode_post_op_attr(xdr, result->fattr); if (unlikely(error)) goto out; - error = decode_post_op_attr(&xdr, result->dir_attr); + error = decode_post_op_attr(xdr, result->dir_attr); out: return error; out_default: - error = decode_post_op_attr(&xdr, result->dir_attr); + error = decode_post_op_attr(xdr, result->dir_attr); if (unlikely(error)) goto out; return nfs_stat_to_errno(status); @@ -1494,23 +1491,22 @@ out_default: * ACCESS3resfail resfail; * }; */ -static int nfs3_xdr_dec_access3res(struct rpc_rqst *req, __be32 *p, +static int nfs3_xdr_dec_access3res(struct rpc_rqst *req, + struct xdr_stream *xdr, struct nfs3_accessres *result) { - struct xdr_stream xdr; enum nfs_stat status; int error; - xdr_init_decode(&xdr, &req->rq_rcv_buf, p); - error = decode_nfsstat3(&xdr, &status); + error = decode_nfsstat3(xdr, &status); if (unlikely(error)) goto out; - error = decode_post_op_attr(&xdr, result->fattr); + error = decode_post_op_attr(xdr, result->fattr); if (unlikely(error)) goto out; if (status != NFS3_OK) goto out_default; - error = decode_uint32(&xdr, &result->access); + error = decode_uint32(xdr, &result->access); out: return error; out_default: @@ -1536,23 +1532,22 @@ out_default: * READLINK3resfail resfail; * }; */ -static int nfs3_xdr_dec_readlink3res(struct rpc_rqst *req, __be32 *p, +static int nfs3_xdr_dec_readlink3res(struct rpc_rqst *req, + struct xdr_stream *xdr, struct nfs_fattr *result) { - struct xdr_stream xdr; enum nfs_stat status; int error; - xdr_init_decode(&xdr, &req->rq_rcv_buf, p); - error = decode_nfsstat3(&xdr, &status); + error = decode_nfsstat3(xdr, &status); if (unlikely(error)) goto out; - error = decode_post_op_attr(&xdr, result); + error = decode_post_op_attr(xdr, result); if (unlikely(error)) goto out; if (status != NFS3_OK) goto out_default; - error = decode_nfspath3(&xdr); + error = decode_nfspath3(xdr); out: return error; out_default: @@ -1620,23 +1615,21 @@ out_overflow: return -EIO; } -static int nfs3_xdr_dec_read3res(struct rpc_rqst *req, __be32 *p, +static int nfs3_xdr_dec_read3res(struct rpc_rqst *req, struct xdr_stream *xdr, struct nfs_readres *result) { - struct xdr_stream xdr; enum nfs_stat status; int error; - xdr_init_decode(&xdr, &req->rq_rcv_buf, p); - error = decode_nfsstat3(&xdr, &status); + error = decode_nfsstat3(xdr, &status); if (unlikely(error)) goto out; - error = decode_post_op_attr(&xdr, result->fattr); + error = decode_post_op_attr(xdr, result->fattr); if (unlikely(error)) goto out; if (status != NFS3_OK) goto out_status; - error = decode_read3resok(&xdr, result); + error = decode_read3resok(xdr, result); out: return error; out_status: @@ -1692,23 +1685,21 @@ out_overflow: return -EIO; } -static int nfs3_xdr_dec_write3res(struct rpc_rqst *req, __be32 *p, +static int nfs3_xdr_dec_write3res(struct rpc_rqst *req, struct xdr_stream *xdr, struct nfs_writeres *result) { - struct xdr_stream xdr; enum nfs_stat status; int error; - xdr_init_decode(&xdr, &req->rq_rcv_buf, p); - error = decode_nfsstat3(&xdr, &status); + error = decode_nfsstat3(xdr, &status); if (unlikely(error)) goto out; - error = decode_wcc_data(&xdr, result->fattr); + error = decode_wcc_data(xdr, result->fattr); if (unlikely(error)) goto out; if (status != NFS3_OK) goto out_status; - error = decode_write3resok(&xdr, result); + error = decode_write3resok(xdr, result); out: return error; out_status: @@ -1757,24 +1748,23 @@ out: return error; } -static int nfs3_xdr_dec_create3res(struct rpc_rqst *req, __be32 *p, +static int nfs3_xdr_dec_create3res(struct rpc_rqst *req, + struct xdr_stream *xdr, struct nfs3_diropres *result) { - struct xdr_stream xdr; enum nfs_stat status; int error; - xdr_init_decode(&xdr, &req->rq_rcv_buf, p); - error = decode_nfsstat3(&xdr, &status); + error = decode_nfsstat3(xdr, &status); if (unlikely(error)) goto out; if (status != NFS3_OK) goto out_default; - error = decode_create3resok(&xdr, result); + error = decode_create3resok(xdr, result); out: return error; out_default: - error = decode_wcc_data(&xdr, result->dir_attr); + error = decode_wcc_data(xdr, result->dir_attr); if (unlikely(error)) goto out; return nfs_stat_to_errno(status); @@ -1798,18 +1788,17 @@ out_default: * REMOVE3resfail resfail; * }; */ -static int nfs3_xdr_dec_remove3res(struct rpc_rqst *req, __be32 *p, +static int nfs3_xdr_dec_remove3res(struct rpc_rqst *req, + struct xdr_stream *xdr, struct nfs_removeres *result) { - struct xdr_stream xdr; enum nfs_stat status; int error; - xdr_init_decode(&xdr, &req->rq_rcv_buf, p); - error = decode_nfsstat3(&xdr, &status); + error = decode_nfsstat3(xdr, &status); if (unlikely(error)) goto out; - error = decode_wcc_data(&xdr, result->dir_attr); + error = decode_wcc_data(xdr, result->dir_attr); if (unlikely(error)) goto out; if (status != NFS3_OK) @@ -1840,21 +1829,20 @@ out_status: * RENAME3resfail resfail; * }; */ -static int nfs3_xdr_dec_rename3res(struct rpc_rqst *req, __be32 *p, +static int nfs3_xdr_dec_rename3res(struct rpc_rqst *req, + struct xdr_stream *xdr, struct nfs_renameres *result) { - struct xdr_stream xdr; enum nfs_stat status; int error; - xdr_init_decode(&xdr, &req->rq_rcv_buf, p); - error = decode_nfsstat3(&xdr, &status); + error = decode_nfsstat3(xdr, &status); if (unlikely(error)) goto out; - error = decode_wcc_data(&xdr, result->old_fattr); + error = decode_wcc_data(xdr, result->old_fattr); if (unlikely(error)) goto out; - error = decode_wcc_data(&xdr, result->new_fattr); + error = decode_wcc_data(xdr, result->new_fattr); if (unlikely(error)) goto out; if (status != NFS3_OK) @@ -1885,21 +1873,19 @@ out_status: * LINK3resfail resfail; * }; */ -static int nfs3_xdr_dec_link3res(struct rpc_rqst *req, __be32 *p, +static int nfs3_xdr_dec_link3res(struct rpc_rqst *req, struct xdr_stream *xdr, struct nfs3_linkres *result) { - struct xdr_stream xdr; enum nfs_stat status; int error; - xdr_init_decode(&xdr, &req->rq_rcv_buf, p); - error = decode_nfsstat3(&xdr, &status); + error = decode_nfsstat3(xdr, &status); if (unlikely(error)) goto out; - error = decode_post_op_attr(&xdr, result->fattr); + error = decode_post_op_attr(xdr, result->fattr); if (unlikely(error)) goto out; - error = decode_wcc_data(&xdr, result->dir_attr); + error = decode_wcc_data(xdr, result->dir_attr); if (unlikely(error)) goto out; if (status != NFS3_OK) @@ -2085,24 +2071,23 @@ out: return error; } -static int nfs3_xdr_dec_readdir3res(struct rpc_rqst *req, __be32 *p, +static int nfs3_xdr_dec_readdir3res(struct rpc_rqst *req, + struct xdr_stream *xdr, struct nfs3_readdirres *result) { - struct xdr_stream xdr; enum nfs_stat status; int error; - xdr_init_decode(&xdr, &req->rq_rcv_buf, p); - error = decode_nfsstat3(&xdr, &status); + error = decode_nfsstat3(xdr, &status); if (unlikely(error)) goto out; if (status != NFS3_OK) goto out_default; - error = decode_readdir3resok(&xdr, result); + error = decode_readdir3resok(xdr, result); out: return error; out_default: - error = decode_post_op_attr(&xdr, result->dir_attr); + error = decode_post_op_attr(xdr, result->dir_attr); if (unlikely(error)) goto out; return nfs_stat_to_errno(status); @@ -2154,23 +2139,22 @@ out_overflow: return -EIO; } -static int nfs3_xdr_dec_fsstat3res(struct rpc_rqst *req, __be32 *p, +static int nfs3_xdr_dec_fsstat3res(struct rpc_rqst *req, + struct xdr_stream *xdr, struct nfs_fsstat *result) { - struct xdr_stream xdr; enum nfs_stat status; int error; - xdr_init_decode(&xdr, &req->rq_rcv_buf, p); - error = decode_nfsstat3(&xdr, &status); + error = decode_nfsstat3(xdr, &status); if (unlikely(error)) goto out; - error = decode_post_op_attr(&xdr, result->fattr); + error = decode_post_op_attr(xdr, result->fattr); if (unlikely(error)) goto out; if (status != NFS3_OK) goto out_status; - error = decode_fsstat3resok(&xdr, result); + error = decode_fsstat3resok(xdr, result); out: return error; out_status: @@ -2231,23 +2215,22 @@ out_overflow: return -EIO; } -static int nfs3_xdr_dec_fsinfo3res(struct rpc_rqst *req, __be32 *p, +static int nfs3_xdr_dec_fsinfo3res(struct rpc_rqst *req, + struct xdr_stream *xdr, struct nfs_fsinfo *result) { - struct xdr_stream xdr; enum nfs_stat status; int error; - xdr_init_decode(&xdr, &req->rq_rcv_buf, p); - error = decode_nfsstat3(&xdr, &status); + error = decode_nfsstat3(xdr, &status); if (unlikely(error)) goto out; - error = decode_post_op_attr(&xdr, result->fattr); + error = decode_post_op_attr(xdr, result->fattr); if (unlikely(error)) goto out; if (status != NFS3_OK) goto out_status; - error = decode_fsinfo3resok(&xdr, result); + error = decode_fsinfo3resok(xdr, result); out: return error; out_status: @@ -2295,23 +2278,22 @@ out_overflow: return -EIO; } -static int nfs3_xdr_dec_pathconf3res(struct rpc_rqst *req, __be32 *p, +static int nfs3_xdr_dec_pathconf3res(struct rpc_rqst *req, + struct xdr_stream *xdr, struct nfs_pathconf *result) { - struct xdr_stream xdr; enum nfs_stat status; int error; - xdr_init_decode(&xdr, &req->rq_rcv_buf, p); - error = decode_nfsstat3(&xdr, &status); + error = decode_nfsstat3(xdr, &status); if (unlikely(error)) goto out; - error = decode_post_op_attr(&xdr, result->fattr); + error = decode_post_op_attr(xdr, result->fattr); if (unlikely(error)) goto out; if (status != NFS3_OK) goto out_status; - error = decode_pathconf3resok(&xdr, result); + error = decode_pathconf3resok(xdr, result); out: return error; out_status: @@ -2337,23 +2319,22 @@ out_status: * COMMIT3resfail resfail; * }; */ -static int nfs3_xdr_dec_commit3res(struct rpc_rqst *req, __be32 *p, +static int nfs3_xdr_dec_commit3res(struct rpc_rqst *req, + struct xdr_stream *xdr, struct nfs_writeres *result) { - struct xdr_stream xdr; enum nfs_stat status; int error; - xdr_init_decode(&xdr, &req->rq_rcv_buf, p); - error = decode_nfsstat3(&xdr, &status); + error = decode_nfsstat3(xdr, &status); if (unlikely(error)) goto out; - error = decode_wcc_data(&xdr, result->fattr); + error = decode_wcc_data(xdr, result->fattr); if (unlikely(error)) goto out; if (status != NFS3_OK) goto out_status; - error = decode_writeverf3(&xdr, result->verf->verifier); + error = decode_writeverf3(xdr, result->verf->verifier); out: return error; out_status: @@ -2406,40 +2387,38 @@ out: return error; } -static int nfs3_xdr_dec_getacl3res(struct rpc_rqst *req, __be32 *p, +static int nfs3_xdr_dec_getacl3res(struct rpc_rqst *req, + struct xdr_stream *xdr, struct nfs3_getaclres *result) { - struct xdr_stream xdr; enum nfs_stat status; int error; - xdr_init_decode(&xdr, &req->rq_rcv_buf, p); - error = decode_nfsstat3(&xdr, &status); + error = decode_nfsstat3(xdr, &status); if (unlikely(error)) goto out; if (status != NFS3_OK) goto out_default; - error = decode_getacl3resok(&xdr, result); + error = decode_getacl3resok(xdr, result); out: return error; out_default: return nfs_stat_to_errno(status); } -static int nfs3_xdr_dec_setacl3res(struct rpc_rqst *req, __be32 *p, +static int nfs3_xdr_dec_setacl3res(struct rpc_rqst *req, + struct xdr_stream *xdr, struct nfs_fattr *result) { - struct xdr_stream xdr; enum nfs_stat status; int error; - xdr_init_decode(&xdr, &req->rq_rcv_buf, p); - error = decode_nfsstat3(&xdr, &status); + error = decode_nfsstat3(xdr, &status); if (unlikely(error)) goto out; if (status != NFS3_OK) goto out_default; - error = decode_post_op_attr(&xdr, result); + error = decode_post_op_attr(xdr, result); out: return error; out_default: @@ -2452,7 +2431,7 @@ out_default: [NFS3PROC_##proc] = { \ .p_proc = NFS3PROC_##proc, \ .p_encode = (kxdreproc_t)nfs3_xdr_enc_##argtype##3args, \ - .p_decode = (kxdrproc_t)nfs3_xdr_dec_##restype##3res, \ + .p_decode = (kxdrdproc_t)nfs3_xdr_dec_##restype##3res, \ .p_arglen = NFS3_##argtype##args_sz, \ .p_replen = NFS3_##restype##res_sz, \ .p_timer = timer, \ @@ -2495,7 +2474,7 @@ static struct rpc_procinfo nfs3_acl_procedures[] = { [ACLPROC3_GETACL] = { .p_proc = ACLPROC3_GETACL, .p_encode = (kxdreproc_t)nfs3_xdr_enc_getacl3args, - .p_decode = (kxdrproc_t)nfs3_xdr_dec_getacl3res, + .p_decode = (kxdrdproc_t)nfs3_xdr_dec_getacl3res, .p_arglen = ACL3_getaclargs_sz, .p_replen = ACL3_getaclres_sz, .p_timer = 1, @@ -2504,7 +2483,7 @@ static struct rpc_procinfo nfs3_acl_procedures[] = { [ACLPROC3_SETACL] = { .p_proc = ACLPROC3_SETACL, .p_encode = (kxdreproc_t)nfs3_xdr_enc_setacl3args, - .p_decode = (kxdrproc_t)nfs3_xdr_dec_setacl3res, + .p_decode = (kxdrdproc_t)nfs3_xdr_dec_setacl3res, .p_arglen = ACL3_setaclargs_sz, .p_replen = ACL3_setaclres_sz, .p_timer = 0, diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c index 6ec38b3e4a3d..f3f99156bfcb 100644 --- a/fs/nfs/nfs4xdr.c +++ b/fs/nfs/nfs4xdr.c @@ -5013,26 +5013,26 @@ out_overflow: /* * Decode OPEN_DOWNGRADE response */ -static int nfs4_xdr_dec_open_downgrade(struct rpc_rqst *rqstp, __be32 *p, struct nfs_closeres *res) +static int nfs4_xdr_dec_open_downgrade(struct rpc_rqst *rqstp, + struct xdr_stream *xdr, + struct nfs_closeres *res) { - struct xdr_stream xdr; struct compound_hdr hdr; int status; - xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p); - status = decode_compound_hdr(&xdr, &hdr); + status = decode_compound_hdr(xdr, &hdr); if (status) goto out; - status = decode_sequence(&xdr, &res->seq_res, rqstp); + status = decode_sequence(xdr, &res->seq_res, rqstp); if (status) goto out; - status = decode_putfh(&xdr); + status = decode_putfh(xdr); if (status) goto out; - status = decode_open_downgrade(&xdr, res); + status = decode_open_downgrade(xdr, res); if (status != 0) goto out; - decode_getfattr(&xdr, res->fattr, res->server, + decode_getfattr(xdr, res->fattr, res->server, !RPC_IS_ASYNC(rqstp->rq_task)); out: return status; @@ -5041,26 +5041,25 @@ out: /* * Decode ACCESS response */ -static int nfs4_xdr_dec_access(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_accessres *res) +static int nfs4_xdr_dec_access(struct rpc_rqst *rqstp, struct xdr_stream *xdr, + struct nfs4_accessres *res) { - struct xdr_stream xdr; struct compound_hdr hdr; int status; - xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p); - status = decode_compound_hdr(&xdr, &hdr); + status = decode_compound_hdr(xdr, &hdr); if (status) goto out; - status = decode_sequence(&xdr, &res->seq_res, rqstp); + status = decode_sequence(xdr, &res->seq_res, rqstp); if (status) goto out; - status = decode_putfh(&xdr); + status = decode_putfh(xdr); if (status != 0) goto out; - status = decode_access(&xdr, res); + status = decode_access(xdr, res); if (status != 0) goto out; - decode_getfattr(&xdr, res->fattr, res->server, + decode_getfattr(xdr, res->fattr, res->server, !RPC_IS_ASYNC(rqstp->rq_task)); out: return status; @@ -5069,26 +5068,28 @@ out: /* * Decode LOOKUP response */ -static int nfs4_xdr_dec_lookup(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_lookup_res *res) +static int nfs4_xdr_dec_lookup(struct rpc_rqst *rqstp, struct xdr_stream *xdr, + struct nfs4_lookup_res *res) { - struct xdr_stream xdr; struct compound_hdr hdr; int status; - xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p); - status = decode_compound_hdr(&xdr, &hdr); + status = decode_compound_hdr(xdr, &hdr); if (status) goto out; - status = decode_sequence(&xdr, &res->seq_res, rqstp); + status = decode_sequence(xdr, &res->seq_res, rqstp); if (status) goto out; - if ((status = decode_putfh(&xdr)) != 0) + status = decode_putfh(xdr); + if (status) goto out; - if ((status = decode_lookup(&xdr)) != 0) + status = decode_lookup(xdr); + if (status) goto out; - if ((status = decode_getfh(&xdr, res->fh)) != 0) + status = decode_getfh(xdr, res->fh); + if (status) goto out; - status = decode_getfattr(&xdr, res->fattr, res->server + status = decode_getfattr(xdr, res->fattr, res->server ,!RPC_IS_ASYNC(rqstp->rq_task)); out: return status; @@ -5097,23 +5098,25 @@ out: /* * Decode LOOKUP_ROOT response */ -static int nfs4_xdr_dec_lookup_root(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_lookup_res *res) +static int nfs4_xdr_dec_lookup_root(struct rpc_rqst *rqstp, + struct xdr_stream *xdr, + struct nfs4_lookup_res *res) { - struct xdr_stream xdr; struct compound_hdr hdr; int status; - xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p); - status = decode_compound_hdr(&xdr, &hdr); + status = decode_compound_hdr(xdr, &hdr); if (status) goto out; - status = decode_sequence(&xdr, &res->seq_res, rqstp); + status = decode_sequence(xdr, &res->seq_res, rqstp); if (status) goto out; - if ((status = decode_putrootfh(&xdr)) != 0) + status = decode_putrootfh(xdr); + if (status) goto out; - if ((status = decode_getfh(&xdr, res->fh)) == 0) - status = decode_getfattr(&xdr, res->fattr, res->server, + status = decode_getfh(xdr, res->fh); + if (status == 0) + status = decode_getfattr(xdr, res->fattr, res->server, !RPC_IS_ASYNC(rqstp->rq_task)); out: return status; @@ -5122,24 +5125,25 @@ out: /* * Decode REMOVE response */ -static int nfs4_xdr_dec_remove(struct rpc_rqst *rqstp, __be32 *p, struct nfs_removeres *res) +static int nfs4_xdr_dec_remove(struct rpc_rqst *rqstp, struct xdr_stream *xdr, + struct nfs_removeres *res) { - struct xdr_stream xdr; struct compound_hdr hdr; int status; - xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p); - status = decode_compound_hdr(&xdr, &hdr); + status = decode_compound_hdr(xdr, &hdr); if (status) goto out; - status = decode_sequence(&xdr, &res->seq_res, rqstp); + status = decode_sequence(xdr, &res->seq_res, rqstp); if (status) goto out; - if ((status = decode_putfh(&xdr)) != 0) + status = decode_putfh(xdr); + if (status) goto out; - if ((status = decode_remove(&xdr, &res->cinfo)) != 0) + status = decode_remove(xdr, &res->cinfo); + if (status) goto out; - decode_getfattr(&xdr, res->dir_attr, res->server, + decode_getfattr(xdr, res->dir_attr, res->server, !RPC_IS_ASYNC(rqstp->rq_task)); out: return status; @@ -5148,34 +5152,38 @@ out: /* * Decode RENAME response */ -static int nfs4_xdr_dec_rename(struct rpc_rqst *rqstp, __be32 *p, struct nfs_renameres *res) +static int nfs4_xdr_dec_rename(struct rpc_rqst *rqstp, struct xdr_stream *xdr, + struct nfs_renameres *res) { - struct xdr_stream xdr; struct compound_hdr hdr; int status; - xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p); - status = decode_compound_hdr(&xdr, &hdr); + status = decode_compound_hdr(xdr, &hdr); if (status) goto out; - status = decode_sequence(&xdr, &res->seq_res, rqstp); + status = decode_sequence(xdr, &res->seq_res, rqstp); if (status) goto out; - if ((status = decode_putfh(&xdr)) != 0) + status = decode_putfh(xdr); + if (status) goto out; - if ((status = decode_savefh(&xdr)) != 0) + status = decode_savefh(xdr); + if (status) goto out; - if ((status = decode_putfh(&xdr)) != 0) + status = decode_putfh(xdr); + if (status) goto out; - if ((status = decode_rename(&xdr, &res->old_cinfo, &res->new_cinfo)) != 0) + status = decode_rename(xdr, &res->old_cinfo, &res->new_cinfo); + if (status) goto out; /* Current FH is target directory */ - if (decode_getfattr(&xdr, res->new_fattr, res->server, + if (decode_getfattr(xdr, res->new_fattr, res->server, !RPC_IS_ASYNC(rqstp->rq_task)) != 0) goto out; - if ((status = decode_restorefh(&xdr)) != 0) + status = decode_restorefh(xdr); + if (status) goto out; - decode_getfattr(&xdr, res->old_fattr, res->server, + decode_getfattr(xdr, res->old_fattr, res->server, !RPC_IS_ASYNC(rqstp->rq_task)); out: return status; @@ -5184,37 +5192,41 @@ out: /* * Decode LINK response */ -static int nfs4_xdr_dec_link(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_link_res *res) +static int nfs4_xdr_dec_link(struct rpc_rqst *rqstp, struct xdr_stream *xdr, + struct nfs4_link_res *res) { - struct xdr_stream xdr; struct compound_hdr hdr; int status; - xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p); - status = decode_compound_hdr(&xdr, &hdr); + status = decode_compound_hdr(xdr, &hdr); if (status) goto out; - status = decode_sequence(&xdr, &res->seq_res, rqstp); + status = decode_sequence(xdr, &res->seq_res, rqstp); if (status) goto out; - if ((status = decode_putfh(&xdr)) != 0) + status = decode_putfh(xdr); + if (status) goto out; - if ((status = decode_savefh(&xdr)) != 0) + status = decode_savefh(xdr); + if (status) goto out; - if ((status = decode_putfh(&xdr)) != 0) + status = decode_putfh(xdr); + if (status) goto out; - if ((status = decode_link(&xdr, &res->cinfo)) != 0) + status = decode_link(xdr, &res->cinfo); + if (status) goto out; /* * Note order: OP_LINK leaves the directory as the current * filehandle. */ - if (decode_getfattr(&xdr, res->dir_attr, res->server, + if (decode_getfattr(xdr, res->dir_attr, res->server, !RPC_IS_ASYNC(rqstp->rq_task)) != 0) goto out; - if ((status = decode_restorefh(&xdr)) != 0) + status = decode_restorefh(xdr); + if (status) goto out; - decode_getfattr(&xdr, res->fattr, res->server, + decode_getfattr(xdr, res->fattr, res->server, !RPC_IS_ASYNC(rqstp->rq_task)); out: return status; @@ -5223,33 +5235,37 @@ out: /* * Decode CREATE response */ -static int nfs4_xdr_dec_create(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_create_res *res) +static int nfs4_xdr_dec_create(struct rpc_rqst *rqstp, struct xdr_stream *xdr, + struct nfs4_create_res *res) { - struct xdr_stream xdr; struct compound_hdr hdr; int status; - xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p); - status = decode_compound_hdr(&xdr, &hdr); + status = decode_compound_hdr(xdr, &hdr); if (status) goto out; - status = decode_sequence(&xdr, &res->seq_res, rqstp); + status = decode_sequence(xdr, &res->seq_res, rqstp); if (status) goto out; - if ((status = decode_putfh(&xdr)) != 0) + status = decode_putfh(xdr); + if (status) goto out; - if ((status = decode_savefh(&xdr)) != 0) + status = decode_savefh(xdr); + if (status) goto out; - if ((status = decode_create(&xdr,&res->dir_cinfo)) != 0) + status = decode_create(xdr, &res->dir_cinfo); + if (status) goto out; - if ((status = decode_getfh(&xdr, res->fh)) != 0) + status = decode_getfh(xdr, res->fh); + if (status) goto out; - if (decode_getfattr(&xdr, res->fattr, res->server, + if (decode_getfattr(xdr, res->fattr, res->server, !RPC_IS_ASYNC(rqstp->rq_task)) != 0) goto out; - if ((status = decode_restorefh(&xdr)) != 0) + status = decode_restorefh(xdr); + if (status) goto out; - decode_getfattr(&xdr, res->dir_fattr, res->server, + decode_getfattr(xdr, res->dir_fattr, res->server, !RPC_IS_ASYNC(rqstp->rq_task)); out: return status; @@ -5258,31 +5274,31 @@ out: /* * Decode SYMLINK response */ -static int nfs4_xdr_dec_symlink(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_create_res *res) +static int nfs4_xdr_dec_symlink(struct rpc_rqst *rqstp, struct xdr_stream *xdr, + struct nfs4_create_res *res) { - return nfs4_xdr_dec_create(rqstp, p, res); + return nfs4_xdr_dec_create(rqstp, xdr, res); } /* * Decode GETATTR response */ -static int nfs4_xdr_dec_getattr(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_getattr_res *res) +static int nfs4_xdr_dec_getattr(struct rpc_rqst *rqstp, struct xdr_stream *xdr, + struct nfs4_getattr_res *res) { - struct xdr_stream xdr; struct compound_hdr hdr; int status; - xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p); - status = decode_compound_hdr(&xdr, &hdr); + status = decode_compound_hdr(xdr, &hdr); if (status) goto out; - status = decode_sequence(&xdr, &res->seq_res, rqstp); + status = decode_sequence(xdr, &res->seq_res, rqstp); if (status) goto out; - status = decode_putfh(&xdr); + status = decode_putfh(xdr); if (status) goto out; - status = decode_getfattr(&xdr, res->fattr, res->server, + status = decode_getfattr(xdr, res->fattr, res->server, !RPC_IS_ASYNC(rqstp->rq_task)); out: return status; @@ -5309,24 +5325,22 @@ static void nfs4_xdr_enc_setacl(struct rpc_rqst *req, struct xdr_stream *xdr, * Decode SETACL response */ static int -nfs4_xdr_dec_setacl(struct rpc_rqst *rqstp, __be32 *p, +nfs4_xdr_dec_setacl(struct rpc_rqst *rqstp, struct xdr_stream *xdr, struct nfs_setaclres *res) { - struct xdr_stream xdr; struct compound_hdr hdr; int status; - xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p); - status = decode_compound_hdr(&xdr, &hdr); + status = decode_compound_hdr(xdr, &hdr); if (status) goto out; - status = decode_sequence(&xdr, &res->seq_res, rqstp); + status = decode_sequence(xdr, &res->seq_res, rqstp); if (status) goto out; - status = decode_putfh(&xdr); + status = decode_putfh(xdr); if (status) goto out; - status = decode_setattr(&xdr); + status = decode_setattr(xdr); out: return status; } @@ -5335,24 +5349,22 @@ out: * Decode GETACL response */ static int -nfs4_xdr_dec_getacl(struct rpc_rqst *rqstp, __be32 *p, +nfs4_xdr_dec_getacl(struct rpc_rqst *rqstp, struct xdr_stream *xdr, struct nfs_getaclres *res) { - struct xdr_stream xdr; struct compound_hdr hdr; int status; - xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p); - status = decode_compound_hdr(&xdr, &hdr); + status = decode_compound_hdr(xdr, &hdr); if (status) goto out; - status = decode_sequence(&xdr, &res->seq_res, rqstp); + status = decode_sequence(xdr, &res->seq_res, rqstp); if (status) goto out; - status = decode_putfh(&xdr); + status = decode_putfh(xdr); if (status) goto out; - status = decode_getacl(&xdr, rqstp, &res->acl_len); + status = decode_getacl(xdr, rqstp, &res->acl_len); out: return status; @@ -5361,23 +5373,22 @@ out: /* * Decode CLOSE response */ -static int nfs4_xdr_dec_close(struct rpc_rqst *rqstp, __be32 *p, struct nfs_closeres *res) +static int nfs4_xdr_dec_close(struct rpc_rqst *rqstp, struct xdr_stream *xdr, + struct nfs_closeres *res) { - struct xdr_stream xdr; struct compound_hdr hdr; int status; - xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p); - status = decode_compound_hdr(&xdr, &hdr); + status = decode_compound_hdr(xdr, &hdr); if (status) goto out; - status = decode_sequence(&xdr, &res->seq_res, rqstp); + status = decode_sequence(xdr, &res->seq_res, rqstp); if (status) goto out; - status = decode_putfh(&xdr); + status = decode_putfh(xdr); if (status) goto out; - status = decode_close(&xdr, res); + status = decode_close(xdr, res); if (status != 0) goto out; /* @@ -5386,7 +5397,7 @@ static int nfs4_xdr_dec_close(struct rpc_rqst *rqstp, __be32 *p, struct nfs_clos * an ESTALE error. Shouldn't be a problem, * though, since fattr->valid will remain unset. */ - decode_getfattr(&xdr, res->fattr, res->server, + decode_getfattr(xdr, res->fattr, res->server, !RPC_IS_ASYNC(rqstp->rq_task)); out: return status; @@ -5395,36 +5406,35 @@ out: /* * Decode OPEN response */ -static int nfs4_xdr_dec_open(struct rpc_rqst *rqstp, __be32 *p, struct nfs_openres *res) +static int nfs4_xdr_dec_open(struct rpc_rqst *rqstp, struct xdr_stream *xdr, + struct nfs_openres *res) { - struct xdr_stream xdr; struct compound_hdr hdr; int status; - xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p); - status = decode_compound_hdr(&xdr, &hdr); + status = decode_compound_hdr(xdr, &hdr); if (status) goto out; - status = decode_sequence(&xdr, &res->seq_res, rqstp); + status = decode_sequence(xdr, &res->seq_res, rqstp); if (status) goto out; - status = decode_putfh(&xdr); + status = decode_putfh(xdr); if (status) goto out; - status = decode_savefh(&xdr); + status = decode_savefh(xdr); if (status) goto out; - status = decode_open(&xdr, res); + status = decode_open(xdr, res); if (status) goto out; - if (decode_getfh(&xdr, &res->fh) != 0) + if (decode_getfh(xdr, &res->fh) != 0) goto out; - if (decode_getfattr(&xdr, res->f_attr, res->server, + if (decode_getfattr(xdr, res->f_attr, res->server, !RPC_IS_ASYNC(rqstp->rq_task)) != 0) goto out; - if (decode_restorefh(&xdr) != 0) + if (decode_restorefh(xdr) != 0) goto out; - decode_getfattr(&xdr, res->dir_attr, res->server, + decode_getfattr(xdr, res->dir_attr, res->server, !RPC_IS_ASYNC(rqstp->rq_task)); out: return status; @@ -5433,20 +5443,20 @@ out: /* * Decode OPEN_CONFIRM response */ -static int nfs4_xdr_dec_open_confirm(struct rpc_rqst *rqstp, __be32 *p, struct nfs_open_confirmres *res) +static int nfs4_xdr_dec_open_confirm(struct rpc_rqst *rqstp, + struct xdr_stream *xdr, + struct nfs_open_confirmres *res) { - struct xdr_stream xdr; struct compound_hdr hdr; int status; - xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p); - status = decode_compound_hdr(&xdr, &hdr); + status = decode_compound_hdr(xdr, &hdr); if (status) goto out; - status = decode_putfh(&xdr); + status = decode_putfh(xdr); if (status) goto out; - status = decode_open_confirm(&xdr, res); + status = decode_open_confirm(xdr, res); out: return status; } @@ -5454,26 +5464,26 @@ out: /* * Decode OPEN response */ -static int nfs4_xdr_dec_open_noattr(struct rpc_rqst *rqstp, __be32 *p, struct nfs_openres *res) +static int nfs4_xdr_dec_open_noattr(struct rpc_rqst *rqstp, + struct xdr_stream *xdr, + struct nfs_openres *res) { - struct xdr_stream xdr; struct compound_hdr hdr; int status; - xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p); - status = decode_compound_hdr(&xdr, &hdr); + status = decode_compound_hdr(xdr, &hdr); if (status) goto out; - status = decode_sequence(&xdr, &res->seq_res, rqstp); + status = decode_sequence(xdr, &res->seq_res, rqstp); if (status) goto out; - status = decode_putfh(&xdr); + status = decode_putfh(xdr); if (status) goto out; - status = decode_open(&xdr, res); + status = decode_open(xdr, res); if (status) goto out; - decode_getfattr(&xdr, res->f_attr, res->server, + decode_getfattr(xdr, res->f_attr, res->server, !RPC_IS_ASYNC(rqstp->rq_task)); out: return status; @@ -5482,26 +5492,26 @@ out: /* * Decode SETATTR response */ -static int nfs4_xdr_dec_setattr(struct rpc_rqst *rqstp, __be32 *p, struct nfs_setattrres *res) +static int nfs4_xdr_dec_setattr(struct rpc_rqst *rqstp, + struct xdr_stream *xdr, + struct nfs_setattrres *res) { - struct xdr_stream xdr; struct compound_hdr hdr; int status; - xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p); - status = decode_compound_hdr(&xdr, &hdr); + status = decode_compound_hdr(xdr, &hdr); if (status) goto out; - status = decode_sequence(&xdr, &res->seq_res, rqstp); + status = decode_sequence(xdr, &res->seq_res, rqstp); if (status) goto out; - status = decode_putfh(&xdr); + status = decode_putfh(xdr); if (status) goto out; - status = decode_setattr(&xdr); + status = decode_setattr(xdr); if (status) goto out; - decode_getfattr(&xdr, res->fattr, res->server, + decode_getfattr(xdr, res->fattr, res->server, !RPC_IS_ASYNC(rqstp->rq_task)); out: return status; @@ -5510,23 +5520,22 @@ out: /* * Decode LOCK response */ -static int nfs4_xdr_dec_lock(struct rpc_rqst *rqstp, __be32 *p, struct nfs_lock_res *res) +static int nfs4_xdr_dec_lock(struct rpc_rqst *rqstp, struct xdr_stream *xdr, + struct nfs_lock_res *res) { - struct xdr_stream xdr; struct compound_hdr hdr; int status; - xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p); - status = decode_compound_hdr(&xdr, &hdr); + status = decode_compound_hdr(xdr, &hdr); if (status) goto out; - status = decode_sequence(&xdr, &res->seq_res, rqstp); + status = decode_sequence(xdr, &res->seq_res, rqstp); if (status) goto out; - status = decode_putfh(&xdr); + status = decode_putfh(xdr); if (status) goto out; - status = decode_lock(&xdr, res); + status = decode_lock(xdr, res); out: return status; } @@ -5534,23 +5543,22 @@ out: /* * Decode LOCKT response */ -static int nfs4_xdr_dec_lockt(struct rpc_rqst *rqstp, __be32 *p, struct nfs_lockt_res *res) +static int nfs4_xdr_dec_lockt(struct rpc_rqst *rqstp, struct xdr_stream *xdr, + struct nfs_lockt_res *res) { - struct xdr_stream xdr; struct compound_hdr hdr; int status; - xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p); - status = decode_compound_hdr(&xdr, &hdr); + status = decode_compound_hdr(xdr, &hdr); if (status) goto out; - status = decode_sequence(&xdr, &res->seq_res, rqstp); + status = decode_sequence(xdr, &res->seq_res, rqstp); if (status) goto out; - status = decode_putfh(&xdr); + status = decode_putfh(xdr); if (status) goto out; - status = decode_lockt(&xdr, res); + status = decode_lockt(xdr, res); out: return status; } @@ -5558,61 +5566,58 @@ out: /* * Decode LOCKU response */ -static int nfs4_xdr_dec_locku(struct rpc_rqst *rqstp, __be32 *p, struct nfs_locku_res *res) +static int nfs4_xdr_dec_locku(struct rpc_rqst *rqstp, struct xdr_stream *xdr, + struct nfs_locku_res *res) { - struct xdr_stream xdr; struct compound_hdr hdr; int status; - xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p); - status = decode_compound_hdr(&xdr, &hdr); + status = decode_compound_hdr(xdr, &hdr); if (status) goto out; - status = decode_sequence(&xdr, &res->seq_res, rqstp); + status = decode_sequence(xdr, &res->seq_res, rqstp); if (status) goto out; - status = decode_putfh(&xdr); + status = decode_putfh(xdr); if (status) goto out; - status = decode_locku(&xdr, res); + status = decode_locku(xdr, res); out: return status; } -static int nfs4_xdr_dec_release_lockowner(struct rpc_rqst *rqstp, __be32 *p, void *dummy) +static int nfs4_xdr_dec_release_lockowner(struct rpc_rqst *rqstp, + struct xdr_stream *xdr, void *dummy) { - struct xdr_stream xdr; struct compound_hdr hdr; int status; - xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p); - status = decode_compound_hdr(&xdr, &hdr); + status = decode_compound_hdr(xdr, &hdr); if (!status) - status = decode_release_lockowner(&xdr); + status = decode_release_lockowner(xdr); return status; } /* * Decode READLINK response */ -static int nfs4_xdr_dec_readlink(struct rpc_rqst *rqstp, __be32 *p, +static int nfs4_xdr_dec_readlink(struct rpc_rqst *rqstp, + struct xdr_stream *xdr, struct nfs4_readlink_res *res) { - struct xdr_stream xdr; struct compound_hdr hdr; int status; - xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p); - status = decode_compound_hdr(&xdr, &hdr); + status = decode_compound_hdr(xdr, &hdr); if (status) goto out; - status = decode_sequence(&xdr, &res->seq_res, rqstp); + status = decode_sequence(xdr, &res->seq_res, rqstp); if (status) goto out; - status = decode_putfh(&xdr); + status = decode_putfh(xdr); if (status) goto out; - status = decode_readlink(&xdr, rqstp); + status = decode_readlink(xdr, rqstp); out: return status; } @@ -5620,23 +5625,22 @@ out: /* * Decode READDIR response */ -static int nfs4_xdr_dec_readdir(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_readdir_res *res) +static int nfs4_xdr_dec_readdir(struct rpc_rqst *rqstp, struct xdr_stream *xdr, + struct nfs4_readdir_res *res) { - struct xdr_stream xdr; struct compound_hdr hdr; int status; - xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p); - status = decode_compound_hdr(&xdr, &hdr); + status = decode_compound_hdr(xdr, &hdr); if (status) goto out; - status = decode_sequence(&xdr, &res->seq_res, rqstp); + status = decode_sequence(xdr, &res->seq_res, rqstp); if (status) goto out; - status = decode_putfh(&xdr); + status = decode_putfh(xdr); if (status) goto out; - status = decode_readdir(&xdr, rqstp, res); + status = decode_readdir(xdr, rqstp, res); out: return status; } @@ -5644,23 +5648,22 @@ out: /* * Decode Read response */ -static int nfs4_xdr_dec_read(struct rpc_rqst *rqstp, __be32 *p, struct nfs_readres *res) +static int nfs4_xdr_dec_read(struct rpc_rqst *rqstp, struct xdr_stream *xdr, + struct nfs_readres *res) { - struct xdr_stream xdr; struct compound_hdr hdr; int status; - xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p); - status = decode_compound_hdr(&xdr, &hdr); + status = decode_compound_hdr(xdr, &hdr); if (status) goto out; - status = decode_sequence(&xdr, &res->seq_res, rqstp); + status = decode_sequence(xdr, &res->seq_res, rqstp); if (status) goto out; - status = decode_putfh(&xdr); + status = decode_putfh(xdr); if (status) goto out; - status = decode_read(&xdr, rqstp, res); + status = decode_read(xdr, rqstp, res); if (!status) status = res->count; out: @@ -5670,26 +5673,25 @@ out: /* * Decode WRITE response */ -static int nfs4_xdr_dec_write(struct rpc_rqst *rqstp, __be32 *p, struct nfs_writeres *res) +static int nfs4_xdr_dec_write(struct rpc_rqst *rqstp, struct xdr_stream *xdr, + struct nfs_writeres *res) { - struct xdr_stream xdr; struct compound_hdr hdr; int status; - xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p); - status = decode_compound_hdr(&xdr, &hdr); + status = decode_compound_hdr(xdr, &hdr); if (status) goto out; - status = decode_sequence(&xdr, &res->seq_res, rqstp); + status = decode_sequence(xdr, &res->seq_res, rqstp); if (status) goto out; - status = decode_putfh(&xdr); + status = decode_putfh(xdr); if (status) goto out; - status = decode_write(&xdr, res); + status = decode_write(xdr, res); if (status) goto out; - decode_getfattr(&xdr, res->fattr, res->server, + decode_getfattr(xdr, res->fattr, res->server, !RPC_IS_ASYNC(rqstp->rq_task)); if (!status) status = res->count; @@ -5700,26 +5702,25 @@ out: /* * Decode COMMIT response */ -static int nfs4_xdr_dec_commit(struct rpc_rqst *rqstp, __be32 *p, struct nfs_writeres *res) +static int nfs4_xdr_dec_commit(struct rpc_rqst *rqstp, struct xdr_stream *xdr, + struct nfs_writeres *res) { - struct xdr_stream xdr; struct compound_hdr hdr; int status; - xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p); - status = decode_compound_hdr(&xdr, &hdr); + status = decode_compound_hdr(xdr, &hdr); if (status) goto out; - status = decode_sequence(&xdr, &res->seq_res, rqstp); + status = decode_sequence(xdr, &res->seq_res, rqstp); if (status) goto out; - status = decode_putfh(&xdr); + status = decode_putfh(xdr); if (status) goto out; - status = decode_commit(&xdr, res); + status = decode_commit(xdr, res); if (status) goto out; - decode_getfattr(&xdr, res->fattr, res->server, + decode_getfattr(xdr, res->fattr, res->server, !RPC_IS_ASYNC(rqstp->rq_task)); out: return status; @@ -5728,85 +5729,80 @@ out: /* * Decode FSINFO response */ -static int nfs4_xdr_dec_fsinfo(struct rpc_rqst *req, __be32 *p, +static int nfs4_xdr_dec_fsinfo(struct rpc_rqst *req, struct xdr_stream *xdr, struct nfs4_fsinfo_res *res) { - struct xdr_stream xdr; struct compound_hdr hdr; int status; - xdr_init_decode(&xdr, &req->rq_rcv_buf, p); - status = decode_compound_hdr(&xdr, &hdr); + status = decode_compound_hdr(xdr, &hdr); if (!status) - status = decode_sequence(&xdr, &res->seq_res, req); + status = decode_sequence(xdr, &res->seq_res, req); if (!status) - status = decode_putfh(&xdr); + status = decode_putfh(xdr); if (!status) - status = decode_fsinfo(&xdr, res->fsinfo); + status = decode_fsinfo(xdr, res->fsinfo); return status; } /* * Decode PATHCONF response */ -static int nfs4_xdr_dec_pathconf(struct rpc_rqst *req, __be32 *p, +static int nfs4_xdr_dec_pathconf(struct rpc_rqst *req, struct xdr_stream *xdr, struct nfs4_pathconf_res *res) { - struct xdr_stream xdr; struct compound_hdr hdr; int status; - xdr_init_decode(&xdr, &req->rq_rcv_buf, p); - status = decode_compound_hdr(&xdr, &hdr); + status = decode_compound_hdr(xdr, &hdr); if (!status) - status = decode_sequence(&xdr, &res->seq_res, req); + status = decode_sequence(xdr, &res->seq_res, req); if (!status) - status = decode_putfh(&xdr); + status = decode_putfh(xdr); if (!status) - status = decode_pathconf(&xdr, res->pathconf); + status = decode_pathconf(xdr, res->pathconf); return status; } /* * Decode STATFS response */ -static int nfs4_xdr_dec_statfs(struct rpc_rqst *req, __be32 *p, +static int nfs4_xdr_dec_statfs(struct rpc_rqst *req, struct xdr_stream *xdr, struct nfs4_statfs_res *res) { - struct xdr_stream xdr; struct compound_hdr hdr; int status; - xdr_init_decode(&xdr, &req->rq_rcv_buf, p); - status = decode_compound_hdr(&xdr, &hdr); + status = decode_compound_hdr(xdr, &hdr); if (!status) - status = decode_sequence(&xdr, &res->seq_res, req); + status = decode_sequence(xdr, &res->seq_res, req); if (!status) - status = decode_putfh(&xdr); + status = decode_putfh(xdr); if (!status) - status = decode_statfs(&xdr, res->fsstat); + status = decode_statfs(xdr, res->fsstat); return status; } /* * Decode GETATTR_BITMAP response */ -static int nfs4_xdr_dec_server_caps(struct rpc_rqst *req, __be32 *p, struct nfs4_server_caps_res *res) +static int nfs4_xdr_dec_server_caps(struct rpc_rqst *req, + struct xdr_stream *xdr, + struct nfs4_server_caps_res *res) { - struct xdr_stream xdr; struct compound_hdr hdr; int status; - xdr_init_decode(&xdr, &req->rq_rcv_buf, p); - status = decode_compound_hdr(&xdr, &hdr); + status = decode_compound_hdr(xdr, &hdr); if (status) goto out; - status = decode_sequence(&xdr, &res->seq_res, req); + status = decode_sequence(xdr, &res->seq_res, req); if (status) goto out; - if ((status = decode_putfh(&xdr)) != 0) + status = decode_putfh(xdr); + if (status) goto out; - status = decode_server_caps(&xdr, res); + status = decode_server_caps(xdr, res); out: return status; } @@ -5814,79 +5810,77 @@ out: /* * Decode RENEW response */ -static int nfs4_xdr_dec_renew(struct rpc_rqst *rqstp, __be32 *p, void *dummy) +static int nfs4_xdr_dec_renew(struct rpc_rqst *rqstp, struct xdr_stream *xdr, + void *__unused) { - struct xdr_stream xdr; struct compound_hdr hdr; int status; - xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p); - status = decode_compound_hdr(&xdr, &hdr); + status = decode_compound_hdr(xdr, &hdr); if (!status) - status = decode_renew(&xdr); + status = decode_renew(xdr); return status; } /* * Decode SETCLIENTID response */ -static int nfs4_xdr_dec_setclientid(struct rpc_rqst *req, __be32 *p, - struct nfs4_setclientid_res *res) +static int nfs4_xdr_dec_setclientid(struct rpc_rqst *req, + struct xdr_stream *xdr, + struct nfs4_setclientid_res *res) { - struct xdr_stream xdr; struct compound_hdr hdr; int status; - xdr_init_decode(&xdr, &req->rq_rcv_buf, p); - status = decode_compound_hdr(&xdr, &hdr); + status = decode_compound_hdr(xdr, &hdr); if (!status) - status = decode_setclientid(&xdr, res); + status = decode_setclientid(xdr, res); return status; } /* * Decode SETCLIENTID_CONFIRM response */ -static int nfs4_xdr_dec_setclientid_confirm(struct rpc_rqst *req, __be32 *p, struct nfs_fsinfo *fsinfo) +static int nfs4_xdr_dec_setclientid_confirm(struct rpc_rqst *req, + struct xdr_stream *xdr, + struct nfs_fsinfo *fsinfo) { - struct xdr_stream xdr; struct compound_hdr hdr; int status; - xdr_init_decode(&xdr, &req->rq_rcv_buf, p); - status = decode_compound_hdr(&xdr, &hdr); + status = decode_compound_hdr(xdr, &hdr); if (!status) - status = decode_setclientid_confirm(&xdr); + status = decode_setclientid_confirm(xdr); if (!status) - status = decode_putrootfh(&xdr); + status = decode_putrootfh(xdr); if (!status) - status = decode_fsinfo(&xdr, fsinfo); + status = decode_fsinfo(xdr, fsinfo); return status; } /* * Decode DELEGRETURN response */ -static int nfs4_xdr_dec_delegreturn(struct rpc_rqst *rqstp, __be32 *p, struct nfs4_delegreturnres *res) +static int nfs4_xdr_dec_delegreturn(struct rpc_rqst *rqstp, + struct xdr_stream *xdr, + struct nfs4_delegreturnres *res) { - struct xdr_stream xdr; struct compound_hdr hdr; int status; - xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p); - status = decode_compound_hdr(&xdr, &hdr); + status = decode_compound_hdr(xdr, &hdr); if (status) goto out; - status = decode_sequence(&xdr, &res->seq_res, rqstp); + status = decode_sequence(xdr, &res->seq_res, rqstp); if (status) goto out; - status = decode_putfh(&xdr); + status = decode_putfh(xdr); if (status != 0) goto out; - status = decode_delegreturn(&xdr); + status = decode_delegreturn(xdr); if (status != 0) goto out; - decode_getfattr(&xdr, res->fattr, res->server, + decode_getfattr(xdr, res->fattr, res->server, !RPC_IS_ASYNC(rqstp->rq_task)); out: return status; @@ -5895,26 +5889,27 @@ out: /* * Decode FS_LOCATIONS response */ -static int nfs4_xdr_dec_fs_locations(struct rpc_rqst *req, __be32 *p, +static int nfs4_xdr_dec_fs_locations(struct rpc_rqst *req, + struct xdr_stream *xdr, struct nfs4_fs_locations_res *res) { - struct xdr_stream xdr; struct compound_hdr hdr; int status; - xdr_init_decode(&xdr, &req->rq_rcv_buf, p); - status = decode_compound_hdr(&xdr, &hdr); + status = decode_compound_hdr(xdr, &hdr); if (status) goto out; - status = decode_sequence(&xdr, &res->seq_res, req); + status = decode_sequence(xdr, &res->seq_res, req); if (status) goto out; - if ((status = decode_putfh(&xdr)) != 0) + status = decode_putfh(xdr); + if (status) goto out; - if ((status = decode_lookup(&xdr)) != 0) + status = decode_lookup(xdr); + if (status) goto out; - xdr_enter_page(&xdr, PAGE_SIZE); - status = decode_getfattr(&xdr, &res->fs_locations->fattr, + xdr_enter_page(xdr, PAGE_SIZE); + status = decode_getfattr(xdr, &res->fs_locations->fattr, res->fs_locations->server, !RPC_IS_ASYNC(req->rq_task)); out: @@ -5925,129 +5920,122 @@ out: /* * Decode EXCHANGE_ID response */ -static int nfs4_xdr_dec_exchange_id(struct rpc_rqst *rqstp, uint32_t *p, +static int nfs4_xdr_dec_exchange_id(struct rpc_rqst *rqstp, + struct xdr_stream *xdr, void *res) { - struct xdr_stream xdr; struct compound_hdr hdr; int status; - xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p); - status = decode_compound_hdr(&xdr, &hdr); + status = decode_compound_hdr(xdr, &hdr); if (!status) - status = decode_exchange_id(&xdr, res); + status = decode_exchange_id(xdr, res); return status; } /* * Decode CREATE_SESSION response */ -static int nfs4_xdr_dec_create_session(struct rpc_rqst *rqstp, uint32_t *p, +static int nfs4_xdr_dec_create_session(struct rpc_rqst *rqstp, + struct xdr_stream *xdr, struct nfs41_create_session_res *res) { - struct xdr_stream xdr; struct compound_hdr hdr; int status; - xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p); - status = decode_compound_hdr(&xdr, &hdr); + status = decode_compound_hdr(xdr, &hdr); if (!status) - status = decode_create_session(&xdr, res); + status = decode_create_session(xdr, res); return status; } /* * Decode DESTROY_SESSION response */ -static int nfs4_xdr_dec_destroy_session(struct rpc_rqst *rqstp, uint32_t *p, - void *dummy) +static int nfs4_xdr_dec_destroy_session(struct rpc_rqst *rqstp, + struct xdr_stream *xdr, + void *res) { - struct xdr_stream xdr; struct compound_hdr hdr; int status; - xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p); - status = decode_compound_hdr(&xdr, &hdr); + status = decode_compound_hdr(xdr, &hdr); if (!status) - status = decode_destroy_session(&xdr, dummy); + status = decode_destroy_session(xdr, res); return status; } /* * Decode SEQUENCE response */ -static int nfs4_xdr_dec_sequence(struct rpc_rqst *rqstp, uint32_t *p, +static int nfs4_xdr_dec_sequence(struct rpc_rqst *rqstp, + struct xdr_stream *xdr, struct nfs4_sequence_res *res) { - struct xdr_stream xdr; struct compound_hdr hdr; int status; - xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p); - status = decode_compound_hdr(&xdr, &hdr); + status = decode_compound_hdr(xdr, &hdr); if (!status) - status = decode_sequence(&xdr, res, rqstp); + status = decode_sequence(xdr, res, rqstp); return status; } /* * Decode GET_LEASE_TIME response */ -static int nfs4_xdr_dec_get_lease_time(struct rpc_rqst *rqstp, uint32_t *p, +static int nfs4_xdr_dec_get_lease_time(struct rpc_rqst *rqstp, + struct xdr_stream *xdr, struct nfs4_get_lease_time_res *res) { - struct xdr_stream xdr; struct compound_hdr hdr; int status; - xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p); - status = decode_compound_hdr(&xdr, &hdr); + status = decode_compound_hdr(xdr, &hdr); if (!status) - status = decode_sequence(&xdr, &res->lr_seq_res, rqstp); + status = decode_sequence(xdr, &res->lr_seq_res, rqstp); if (!status) - status = decode_putrootfh(&xdr); + status = decode_putrootfh(xdr); if (!status) - status = decode_fsinfo(&xdr, res->lr_fsinfo); + status = decode_fsinfo(xdr, res->lr_fsinfo); return status; } /* * Decode RECLAIM_COMPLETE response */ -static int nfs4_xdr_dec_reclaim_complete(struct rpc_rqst *rqstp, uint32_t *p, +static int nfs4_xdr_dec_reclaim_complete(struct rpc_rqst *rqstp, + struct xdr_stream *xdr, struct nfs41_reclaim_complete_res *res) { - struct xdr_stream xdr; struct compound_hdr hdr; int status; - xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p); - status = decode_compound_hdr(&xdr, &hdr); + status = decode_compound_hdr(xdr, &hdr); if (!status) - status = decode_sequence(&xdr, &res->seq_res, rqstp); + status = decode_sequence(xdr, &res->seq_res, rqstp); if (!status) - status = decode_reclaim_complete(&xdr, (void *)NULL); + status = decode_reclaim_complete(xdr, (void *)NULL); return status; } /* * Decode GETDEVINFO response */ -static int nfs4_xdr_dec_getdeviceinfo(struct rpc_rqst *rqstp, uint32_t *p, +static int nfs4_xdr_dec_getdeviceinfo(struct rpc_rqst *rqstp, + struct xdr_stream *xdr, struct nfs4_getdeviceinfo_res *res) { - struct xdr_stream xdr; struct compound_hdr hdr; int status; - xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p); - status = decode_compound_hdr(&xdr, &hdr); + status = decode_compound_hdr(xdr, &hdr); if (status != 0) goto out; - status = decode_sequence(&xdr, &res->seq_res, rqstp); + status = decode_sequence(xdr, &res->seq_res, rqstp); if (status != 0) goto out; - status = decode_getdeviceinfo(&xdr, res->pdev); + status = decode_getdeviceinfo(xdr, res->pdev); out: return status; } @@ -6055,24 +6043,23 @@ out: /* * Decode LAYOUTGET response */ -static int nfs4_xdr_dec_layoutget(struct rpc_rqst *rqstp, uint32_t *p, +static int nfs4_xdr_dec_layoutget(struct rpc_rqst *rqstp, + struct xdr_stream *xdr, struct nfs4_layoutget_res *res) { - struct xdr_stream xdr; struct compound_hdr hdr; int status; - xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p); - status = decode_compound_hdr(&xdr, &hdr); + status = decode_compound_hdr(xdr, &hdr); if (status) goto out; - status = decode_sequence(&xdr, &res->seq_res, rqstp); + status = decode_sequence(xdr, &res->seq_res, rqstp); if (status) goto out; - status = decode_putfh(&xdr); + status = decode_putfh(xdr); if (status) goto out; - status = decode_layoutget(&xdr, rqstp, res); + status = decode_layoutget(xdr, rqstp, res); out: return status; } @@ -6236,7 +6223,7 @@ nfs4_stat_to_errno(int stat) [NFSPROC4_CLNT_##proc] = { \ .p_proc = NFSPROC4_COMPOUND, \ .p_encode = (kxdreproc_t)nfs4_xdr_##argtype, \ - .p_decode = (kxdrproc_t)nfs4_xdr_##restype, \ + .p_decode = (kxdrdproc_t)nfs4_xdr_##restype, \ .p_arglen = NFS4_##argtype##_sz, \ .p_replen = NFS4_##restype##_sz, \ .p_statidx = NFSPROC4_CLNT_##proc, \ diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c index c363efda8ecf..21a63da305ff 100644 --- a/fs/nfsd/nfs4callback.c +++ b/fs/nfsd/nfs4callback.c @@ -533,7 +533,8 @@ static void nfs4_xdr_enc_cb_recall(struct rpc_rqst *req, struct xdr_stream *xdr, * Protocol". */ -static int nfs4_xdr_dec_cb_null(struct rpc_rqst *req, __be32 *p, void *__unused) +static int nfs4_xdr_dec_cb_null(struct rpc_rqst *req, struct xdr_stream *xdr, + void *__unused) { return 0; } @@ -541,26 +542,25 @@ static int nfs4_xdr_dec_cb_null(struct rpc_rqst *req, __be32 *p, void *__unused) /* * 20.2. Operation 4: CB_RECALL - Recall a Delegation */ -static int nfs4_xdr_dec_cb_recall(struct rpc_rqst *rqstp, __be32 *p, +static int nfs4_xdr_dec_cb_recall(struct rpc_rqst *rqstp, + struct xdr_stream *xdr, struct nfsd4_callback *cb) { - struct xdr_stream xdr; struct nfs4_cb_compound_hdr hdr; enum nfsstat4 nfserr; int status; - xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p); - status = decode_cb_compound4res(&xdr, &hdr); + status = decode_cb_compound4res(xdr, &hdr); if (unlikely(status)) goto out; if (cb != NULL) { - status = decode_cb_sequence4res(&xdr, cb); + status = decode_cb_sequence4res(xdr, cb); if (unlikely(status)) goto out; } - status = decode_cb_op_status(&xdr, OP_CB_RECALL, &nfserr); + status = decode_cb_op_status(xdr, OP_CB_RECALL, &nfserr); if (unlikely(status)) goto out; if (unlikely(nfserr != NFS4_OK)) @@ -578,7 +578,7 @@ out_default: [NFSPROC4_CLNT_##proc] = { \ .p_proc = NFSPROC4_CB_##call, \ .p_encode = (kxdreproc_t)nfs4_xdr_enc_##argtype, \ - .p_decode = (kxdrproc_t)nfs4_xdr_dec_##restype, \ + .p_decode = (kxdrdproc_t)nfs4_xdr_dec_##restype, \ .p_arglen = NFS4_enc_##argtype##_sz, \ .p_replen = NFS4_dec_##restype##_sz, \ .p_statidx = NFSPROC4_CB_##call, \ diff --git a/include/linux/sunrpc/auth.h b/include/linux/sunrpc/auth.h index d88cffbaa6df..8521067ed4f7 100644 --- a/include/linux/sunrpc/auth.h +++ b/include/linux/sunrpc/auth.h @@ -112,7 +112,7 @@ struct rpc_credops { __be32 * (*crvalidate)(struct rpc_task *, __be32 *); int (*crwrap_req)(struct rpc_task *, kxdreproc_t, void *, __be32 *, void *); - int (*crunwrap_resp)(struct rpc_task *, kxdrproc_t, + int (*crunwrap_resp)(struct rpc_task *, kxdrdproc_t, void *, __be32 *, void *); }; @@ -140,7 +140,7 @@ void put_rpccred(struct rpc_cred *); __be32 * rpcauth_marshcred(struct rpc_task *, __be32 *); __be32 * rpcauth_checkverf(struct rpc_task *, __be32 *); int rpcauth_wrap_req(struct rpc_task *task, kxdreproc_t encode, void *rqstp, __be32 *data, void *obj); -int rpcauth_unwrap_resp(struct rpc_task *task, kxdrproc_t decode, void *rqstp, __be32 *data, void *obj); +int rpcauth_unwrap_resp(struct rpc_task *task, kxdrdproc_t decode, void *rqstp, __be32 *data, void *obj); int rpcauth_refreshcred(struct rpc_task *); void rpcauth_invalcred(struct rpc_task *); int rpcauth_uptodatecred(struct rpc_task *); diff --git a/include/linux/sunrpc/clnt.h b/include/linux/sunrpc/clnt.h index 7b19c4e1ce53..ef9476a36ff7 100644 --- a/include/linux/sunrpc/clnt.h +++ b/include/linux/sunrpc/clnt.h @@ -90,7 +90,7 @@ struct rpc_version { struct rpc_procinfo { u32 p_proc; /* RPC procedure number */ kxdreproc_t p_encode; /* XDR encode function */ - kxdrproc_t p_decode; /* XDR decode function */ + kxdrdproc_t p_decode; /* XDR decode function */ unsigned int p_arglen; /* argument hdr length (u32) */ unsigned int p_replen; /* reply hdr length (u32) */ unsigned int p_count; /* call count */ diff --git a/include/linux/sunrpc/xdr.h b/include/linux/sunrpc/xdr.h index a21cf5378c1d..9a21e8102c42 100644 --- a/include/linux/sunrpc/xdr.h +++ b/include/linux/sunrpc/xdr.h @@ -204,9 +204,10 @@ struct xdr_stream { }; /* - * This is the xdr_stream style generic XDR function. + * These are the xdr_stream style generic XDR encode and decode functions. */ typedef void (*kxdreproc_t)(void *rqstp, struct xdr_stream *xdr, void *obj); +typedef int (*kxdrdproc_t)(void *rqstp, struct xdr_stream *xdr, void *obj); extern void xdr_init_encode(struct xdr_stream *xdr, struct xdr_buf *buf, __be32 *p); extern __be32 *xdr_reserve_space(struct xdr_stream *xdr, size_t nbytes); diff --git a/net/sunrpc/auth.c b/net/sunrpc/auth.c index 651c9da703cb..67e31276682a 100644 --- a/net/sunrpc/auth.c +++ b/net/sunrpc/auth.c @@ -587,8 +587,18 @@ rpcauth_wrap_req(struct rpc_task *task, kxdreproc_t encode, void *rqstp, return 0; } +static int +rpcauth_unwrap_req_decode(kxdrdproc_t decode, struct rpc_rqst *rqstp, + __be32 *data, void *obj) +{ + struct xdr_stream xdr; + + xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, data); + return decode(rqstp, &xdr, obj); +} + int -rpcauth_unwrap_resp(struct rpc_task *task, kxdrproc_t decode, void *rqstp, +rpcauth_unwrap_resp(struct rpc_task *task, kxdrdproc_t decode, void *rqstp, __be32 *data, void *obj) { struct rpc_cred *cred = task->tk_rqstp->rq_cred; @@ -599,7 +609,7 @@ rpcauth_unwrap_resp(struct rpc_task *task, kxdrproc_t decode, void *rqstp, return cred->cr_ops->crunwrap_resp(task, decode, rqstp, data, obj); /* By default, we decode the arguments normally. */ - return decode(rqstp, data, obj); + return rpcauth_unwrap_req_decode(decode, rqstp, data, obj); } int diff --git a/net/sunrpc/auth_gss/auth_gss.c b/net/sunrpc/auth_gss/auth_gss.c index 42b46f9a670a..45dbf1521b9a 100644 --- a/net/sunrpc/auth_gss/auth_gss.c +++ b/net/sunrpc/auth_gss/auth_gss.c @@ -1503,10 +1503,19 @@ gss_unwrap_resp_priv(struct rpc_cred *cred, struct gss_cl_ctx *ctx, return 0; } +static int +gss_unwrap_req_decode(kxdrdproc_t decode, struct rpc_rqst *rqstp, + __be32 *p, void *obj) +{ + struct xdr_stream xdr; + + xdr_init_decode(&xdr, &rqstp->rq_rcv_buf, p); + return decode(rqstp, &xdr, obj); +} static int gss_unwrap_resp(struct rpc_task *task, - kxdrproc_t decode, void *rqstp, __be32 *p, void *obj) + kxdrdproc_t decode, void *rqstp, __be32 *p, void *obj) { struct rpc_cred *cred = task->tk_rqstp->rq_cred; struct gss_cred *gss_cred = container_of(cred, struct gss_cred, @@ -1537,7 +1546,7 @@ gss_unwrap_resp(struct rpc_task *task, cred->cr_auth->au_rslack = cred->cr_auth->au_verfsize + (p - savedp) + (savedlen - head->iov_len); out_decode: - status = decode(rqstp, p, obj); + status = gss_unwrap_req_decode(decode, rqstp, p, obj); out: gss_put_ctx(ctx); dprintk("RPC: %5u gss_unwrap_resp returning %d\n", task->tk_pid, diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c index d446a32be667..4e8210dcda72 100644 --- a/net/sunrpc/clnt.c +++ b/net/sunrpc/clnt.c @@ -1535,7 +1535,7 @@ call_decode(struct rpc_task *task) { struct rpc_clnt *clnt = task->tk_client; struct rpc_rqst *req = task->tk_rqstp; - kxdrproc_t decode = task->tk_msg.rpc_proc->p_decode; + kxdrdproc_t decode = task->tk_msg.rpc_proc->p_decode; __be32 *p; dprintk("RPC: %5u call_decode (status %d)\n", @@ -1780,7 +1780,7 @@ static void rpcproc_encode_null(void *rqstp, struct xdr_stream *xdr, void *obj) { } -static int rpcproc_decode_null(void *rqstp, __be32 *data, void *obj) +static int rpcproc_decode_null(void *rqstp, struct xdr_stream *xdr, void *obj) { return 0; } diff --git a/net/sunrpc/rpcb_clnt.c b/net/sunrpc/rpcb_clnt.c index 63912a1a2983..c652e4cc9fe9 100644 --- a/net/sunrpc/rpcb_clnt.c +++ b/net/sunrpc/rpcb_clnt.c @@ -706,18 +706,16 @@ static void rpcb_enc_mapping(struct rpc_rqst *req, struct xdr_stream *xdr, *p = cpu_to_be32(rpcb->r_port); } -static int rpcb_dec_getport(struct rpc_rqst *req, __be32 *p, +static int rpcb_dec_getport(struct rpc_rqst *req, struct xdr_stream *xdr, struct rpcbind_args *rpcb) { struct rpc_task *task = req->rq_task; - struct xdr_stream xdr; unsigned long port; - - xdr_init_decode(&xdr, &req->rq_rcv_buf, p); + __be32 *p; rpcb->r_port = 0; - p = xdr_inline_decode(&xdr, 4); + p = xdr_inline_decode(xdr, 4); if (unlikely(p == NULL)) return -EIO; @@ -731,20 +729,18 @@ static int rpcb_dec_getport(struct rpc_rqst *req, __be32 *p, return 0; } -static int rpcb_dec_set(struct rpc_rqst *req, __be32 *p, +static int rpcb_dec_set(struct rpc_rqst *req, struct xdr_stream *xdr, unsigned int *boolp) { struct rpc_task *task = req->rq_task; - struct xdr_stream xdr; - - xdr_init_decode(&xdr, &req->rq_rcv_buf, p); + __be32 *p; - p = xdr_inline_decode(&xdr, 4); + p = xdr_inline_decode(xdr, 4); if (unlikely(p == NULL)) return -EIO; *boolp = 0; - if (*p) + if (*p != xdr_zero) *boolp = 1; dprintk("RPC: %5u RPCB_%s call %s\n", @@ -785,20 +781,18 @@ static void rpcb_enc_getaddr(struct rpc_rqst *req, struct xdr_stream *xdr, encode_rpcb_string(xdr, rpcb->r_owner, RPCB_MAXOWNERLEN); } -static int rpcb_dec_getaddr(struct rpc_rqst *req, __be32 *p, +static int rpcb_dec_getaddr(struct rpc_rqst *req, struct xdr_stream *xdr, struct rpcbind_args *rpcb) { struct sockaddr_storage address; struct sockaddr *sap = (struct sockaddr *)&address; struct rpc_task *task = req->rq_task; - struct xdr_stream xdr; + __be32 *p; u32 len; rpcb->r_port = 0; - xdr_init_decode(&xdr, &req->rq_rcv_buf, p); - - p = xdr_inline_decode(&xdr, 4); + p = xdr_inline_decode(xdr, 4); if (unlikely(p == NULL)) goto out_fail; len = be32_to_cpup(p); @@ -816,7 +810,7 @@ static int rpcb_dec_getaddr(struct rpc_rqst *req, __be32 *p, if (unlikely(len > RPCBIND_MAXUADDRLEN)) goto out_fail; - p = xdr_inline_decode(&xdr, len); + p = xdr_inline_decode(xdr, len); if (unlikely(p == NULL)) goto out_fail; dprintk("RPC: %5u RPCB_%s reply: %s\n", task->tk_pid, @@ -843,7 +837,7 @@ static struct rpc_procinfo rpcb_procedures2[] = { [RPCBPROC_SET] = { .p_proc = RPCBPROC_SET, .p_encode = (kxdreproc_t)rpcb_enc_mapping, - .p_decode = (kxdrproc_t)rpcb_dec_set, + .p_decode = (kxdrdproc_t)rpcb_dec_set, .p_arglen = RPCB_mappingargs_sz, .p_replen = RPCB_setres_sz, .p_statidx = RPCBPROC_SET, @@ -853,7 +847,7 @@ static struct rpc_procinfo rpcb_procedures2[] = { [RPCBPROC_UNSET] = { .p_proc = RPCBPROC_UNSET, .p_encode = (kxdreproc_t)rpcb_enc_mapping, - .p_decode = (kxdrproc_t)rpcb_dec_set, + .p_decode = (kxdrdproc_t)rpcb_dec_set, .p_arglen = RPCB_mappingargs_sz, .p_replen = RPCB_setres_sz, .p_statidx = RPCBPROC_UNSET, @@ -863,7 +857,7 @@ static struct rpc_procinfo rpcb_procedures2[] = { [RPCBPROC_GETPORT] = { .p_proc = RPCBPROC_GETPORT, .p_encode = (kxdreproc_t)rpcb_enc_mapping, - .p_decode = (kxdrproc_t)rpcb_dec_getport, + .p_decode = (kxdrdproc_t)rpcb_dec_getport, .p_arglen = RPCB_mappingargs_sz, .p_replen = RPCB_getportres_sz, .p_statidx = RPCBPROC_GETPORT, @@ -876,7 +870,7 @@ static struct rpc_procinfo rpcb_procedures3[] = { [RPCBPROC_SET] = { .p_proc = RPCBPROC_SET, .p_encode = (kxdreproc_t)rpcb_enc_getaddr, - .p_decode = (kxdrproc_t)rpcb_dec_set, + .p_decode = (kxdrdproc_t)rpcb_dec_set, .p_arglen = RPCB_getaddrargs_sz, .p_replen = RPCB_setres_sz, .p_statidx = RPCBPROC_SET, @@ -886,7 +880,7 @@ static struct rpc_procinfo rpcb_procedures3[] = { [RPCBPROC_UNSET] = { .p_proc = RPCBPROC_UNSET, .p_encode = (kxdreproc_t)rpcb_enc_getaddr, - .p_decode = (kxdrproc_t)rpcb_dec_set, + .p_decode = (kxdrdproc_t)rpcb_dec_set, .p_arglen = RPCB_getaddrargs_sz, .p_replen = RPCB_setres_sz, .p_statidx = RPCBPROC_UNSET, @@ -896,7 +890,7 @@ static struct rpc_procinfo rpcb_procedures3[] = { [RPCBPROC_GETADDR] = { .p_proc = RPCBPROC_GETADDR, .p_encode = (kxdreproc_t)rpcb_enc_getaddr, - .p_decode = (kxdrproc_t)rpcb_dec_getaddr, + .p_decode = (kxdrdproc_t)rpcb_dec_getaddr, .p_arglen = RPCB_getaddrargs_sz, .p_replen = RPCB_getaddrres_sz, .p_statidx = RPCBPROC_GETADDR, @@ -909,7 +903,7 @@ static struct rpc_procinfo rpcb_procedures4[] = { [RPCBPROC_SET] = { .p_proc = RPCBPROC_SET, .p_encode = (kxdreproc_t)rpcb_enc_getaddr, - .p_decode = (kxdrproc_t)rpcb_dec_set, + .p_decode = (kxdrdproc_t)rpcb_dec_set, .p_arglen = RPCB_getaddrargs_sz, .p_replen = RPCB_setres_sz, .p_statidx = RPCBPROC_SET, @@ -919,7 +913,7 @@ static struct rpc_procinfo rpcb_procedures4[] = { [RPCBPROC_UNSET] = { .p_proc = RPCBPROC_UNSET, .p_encode = (kxdreproc_t)rpcb_enc_getaddr, - .p_decode = (kxdrproc_t)rpcb_dec_set, + .p_decode = (kxdrdproc_t)rpcb_dec_set, .p_arglen = RPCB_getaddrargs_sz, .p_replen = RPCB_setres_sz, .p_statidx = RPCBPROC_UNSET, @@ -929,7 +923,7 @@ static struct rpc_procinfo rpcb_procedures4[] = { [RPCBPROC_GETADDR] = { .p_proc = RPCBPROC_GETADDR, .p_encode = (kxdreproc_t)rpcb_enc_getaddr, - .p_decode = (kxdrproc_t)rpcb_dec_getaddr, + .p_decode = (kxdrdproc_t)rpcb_dec_getaddr, .p_arglen = RPCB_getaddrargs_sz, .p_replen = RPCB_getaddrres_sz, .p_statidx = RPCBPROC_GETADDR, -- cgit v1.2.3 From b113746888c260a02f6ae1e92b0b9ef7e9c38993 Mon Sep 17 00:00:00 2001 From: "J. Bruce Fields" Date: Tue, 14 Dec 2010 15:05:03 +0000 Subject: lockd: define host_for_each{_safe} macros We've got a lot of loops like this, and I find them a little easier to read with the macros. More such loops are coming. Signed-off-by: J. Bruce Fields [ cel: Forward-ported to 2.6.37 ] Signed-off-by: Chuck Lever Signed-off-by: Trond Myklebust --- fs/lockd/host.c | 107 +++++++++++++++++++++++++++++--------------------------- 1 file changed, 55 insertions(+), 52 deletions(-) diff --git a/fs/lockd/host.c b/fs/lockd/host.c index ed0c59fe23ce..cada3a12d557 100644 --- a/fs/lockd/host.c +++ b/fs/lockd/host.c @@ -26,6 +26,18 @@ #define NLM_HOST_COLLECT (120 * HZ) static struct hlist_head nlm_hosts[NLM_HOST_NRHASH]; + +#define for_each_host(host, pos, chain, table) \ + for ((chain) = (table); \ + (chain) < (table) + NLM_HOST_NRHASH; ++(chain)) \ + hlist_for_each_entry((host), (pos), (chain), h_hash) + +#define for_each_host_safe(host, pos, next, chain, table) \ + for ((chain) = (table); \ + (chain) < (table) + NLM_HOST_NRHASH; ++(chain)) \ + hlist_for_each_entry_safe((host), (pos), (next), \ + (chain), h_hash) + static unsigned long next_gc; static int nrhosts; static DEFINE_MUTEX(nlm_host_mutex); @@ -453,28 +465,26 @@ void nlm_host_rebooted(const struct nlm_reboot *info) * To avoid processing a host several times, we match the nsmstate. */ again: mutex_lock(&nlm_host_mutex); - for (chain = nlm_hosts; chain < nlm_hosts + NLM_HOST_NRHASH; ++chain) { - hlist_for_each_entry(host, pos, chain, h_hash) { - if (host->h_nsmhandle == nsm - && host->h_nsmstate != info->state) { - host->h_nsmstate = info->state; - host->h_state++; - - nlm_get_host(host); - mutex_unlock(&nlm_host_mutex); - - if (host->h_server) { - /* We're server for this guy, just ditch - * all the locks he held. */ - nlmsvc_free_host_resources(host); - } else { - /* He's the server, initiate lock recovery. */ - nlmclnt_recovery(host); - } - - nlm_release_host(host); - goto again; + for_each_host(host, pos, chain, nlm_hosts) { + if (host->h_nsmhandle == nsm + && host->h_nsmstate != info->state) { + host->h_nsmstate = info->state; + host->h_state++; + + nlm_get_host(host); + mutex_unlock(&nlm_host_mutex); + + if (host->h_server) { + /* We're server for this guy, just ditch + * all the locks he held. */ + nlmsvc_free_host_resources(host); + } else { + /* He's the server, initiate lock recovery. */ + nlmclnt_recovery(host); } + + nlm_release_host(host); + goto again; } } mutex_unlock(&nlm_host_mutex); @@ -497,13 +507,11 @@ nlm_shutdown_hosts(void) /* First, make all hosts eligible for gc */ dprintk("lockd: nuking all hosts...\n"); - for (chain = nlm_hosts; chain < nlm_hosts + NLM_HOST_NRHASH; ++chain) { - hlist_for_each_entry(host, pos, chain, h_hash) { - host->h_expires = jiffies - 1; - if (host->h_rpcclnt) { - rpc_shutdown_client(host->h_rpcclnt); - host->h_rpcclnt = NULL; - } + for_each_host(host, pos, chain, nlm_hosts) { + host->h_expires = jiffies - 1; + if (host->h_rpcclnt) { + rpc_shutdown_client(host->h_rpcclnt); + host->h_rpcclnt = NULL; } } @@ -515,12 +523,10 @@ nlm_shutdown_hosts(void) if (nrhosts) { printk(KERN_WARNING "lockd: couldn't shutdown host module!\n"); dprintk("lockd: %d hosts left:\n", nrhosts); - for (chain = nlm_hosts; chain < nlm_hosts + NLM_HOST_NRHASH; ++chain) { - hlist_for_each_entry(host, pos, chain, h_hash) { - dprintk(" %s (cnt %d use %d exp %ld)\n", - host->h_name, atomic_read(&host->h_count), - host->h_inuse, host->h_expires); - } + for_each_host(host, pos, chain, nlm_hosts) { + dprintk(" %s (cnt %d use %d exp %ld)\n", + host->h_name, atomic_read(&host->h_count), + host->h_inuse, host->h_expires); } } } @@ -538,29 +544,26 @@ nlm_gc_hosts(void) struct nlm_host *host; dprintk("lockd: host garbage collection\n"); - for (chain = nlm_hosts; chain < nlm_hosts + NLM_HOST_NRHASH; ++chain) { - hlist_for_each_entry(host, pos, chain, h_hash) - host->h_inuse = 0; - } + for_each_host(host, pos, chain, nlm_hosts) + host->h_inuse = 0; /* Mark all hosts that hold locks, blocks or shares */ nlmsvc_mark_resources(); - for (chain = nlm_hosts; chain < nlm_hosts + NLM_HOST_NRHASH; ++chain) { - hlist_for_each_entry_safe(host, pos, next, chain, h_hash) { - if (atomic_read(&host->h_count) || host->h_inuse - || time_before(jiffies, host->h_expires)) { - dprintk("nlm_gc_hosts skipping %s (cnt %d use %d exp %ld)\n", - host->h_name, atomic_read(&host->h_count), - host->h_inuse, host->h_expires); - continue; - } - dprintk("lockd: delete host %s\n", host->h_name); - hlist_del_init(&host->h_hash); - - nlm_destroy_host(host); - nrhosts--; + for_each_host_safe(host, pos, next, chain, nlm_hosts) { + if (atomic_read(&host->h_count) || host->h_inuse + || time_before(jiffies, host->h_expires)) { + dprintk("nlm_gc_hosts skipping %s " + "(cnt %d use %d exp %ld)\n", + host->h_name, atomic_read(&host->h_count), + host->h_inuse, host->h_expires); + continue; } + dprintk("lockd: delete host %s\n", host->h_name); + hlist_del_init(&host->h_hash); + + nlm_destroy_host(host); + nrhosts--; } next_gc = jiffies + NLM_HOST_COLLECT; -- cgit v1.2.3 From b10e30f6559978e3c8ca2a70c1cb35d6680a4021 Mon Sep 17 00:00:00 2001 From: "J. Bruce Fields" Date: Tue, 14 Dec 2010 15:05:13 +0000 Subject: lockd: reorganize nlm_host_rebooted Minor reorganization; no change in behavior. This will save some duplicated code after we split the client and server host caches. Signed-off-by: J. Bruce Fields [ cel: Forward-ported to 2.6.37 ] Signed-off-by: Chuck Lever Signed-off-by: Trond Myklebust --- fs/lockd/host.c | 58 +++++++++++++++++++++++++++++++++------------------------ 1 file changed, 34 insertions(+), 24 deletions(-) diff --git a/fs/lockd/host.c b/fs/lockd/host.c index cada3a12d557..2dbf1392acfc 100644 --- a/fs/lockd/host.c +++ b/fs/lockd/host.c @@ -441,6 +441,31 @@ void nlm_release_host(struct nlm_host *host) } } +static struct nlm_host *next_host_state(struct hlist_head *cache, + struct nsm_handle *nsm, + const struct nlm_reboot *info) +{ + struct nlm_host *host = NULL; + struct hlist_head *chain; + struct hlist_node *pos; + + mutex_lock(&nlm_host_mutex); + for_each_host(host, pos, chain, cache) { + if (host->h_nsmhandle == nsm + && host->h_nsmstate != info->state) { + host->h_nsmstate = info->state; + host->h_state++; + + nlm_get_host(host); + mutex_unlock(&nlm_host_mutex); + goto out; + } + } +out: + mutex_unlock(&nlm_host_mutex); + return host; +} + /** * nlm_host_rebooted - Release all resources held by rebooted host * @info: pointer to decoded results of NLM_SM_NOTIFY call @@ -450,8 +475,6 @@ void nlm_release_host(struct nlm_host *host) */ void nlm_host_rebooted(const struct nlm_reboot *info) { - struct hlist_head *chain; - struct hlist_node *pos; struct nsm_handle *nsm; struct nlm_host *host; @@ -464,30 +487,17 @@ void nlm_host_rebooted(const struct nlm_reboot *info) * lock for this. * To avoid processing a host several times, we match the nsmstate. */ -again: mutex_lock(&nlm_host_mutex); - for_each_host(host, pos, chain, nlm_hosts) { - if (host->h_nsmhandle == nsm - && host->h_nsmstate != info->state) { - host->h_nsmstate = info->state; - host->h_state++; - - nlm_get_host(host); - mutex_unlock(&nlm_host_mutex); - - if (host->h_server) { - /* We're server for this guy, just ditch - * all the locks he held. */ - nlmsvc_free_host_resources(host); - } else { - /* He's the server, initiate lock recovery. */ - nlmclnt_recovery(host); - } - - nlm_release_host(host); - goto again; + while ((host = next_host_state(nlm_hosts, nsm, info)) != NULL) { + if (host->h_server) { + /* We're server for this guy, just ditch + * all the locks he held. */ + nlmsvc_free_host_resources(host); + } else { + /* He's the server, initiate lock recovery. */ + nlmclnt_recovery(host); } + nlm_release_host(host); } - mutex_unlock(&nlm_host_mutex); nsm_release(nsm); } -- cgit v1.2.3 From a7952f4056d4d9c63c70534bcfd4f2c11e487000 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Tue, 14 Dec 2010 15:05:23 +0000 Subject: lockd: Add nlm_alloc_host() Refactor nlm_host allocation and initialization into a separate function. This will be the common piece of server and client nlm_host lookup logic after the nlm_host cache is split. Small change: use kmalloc() instead of kzalloc(), as we're overwriting almost all fields in the new nlm_host struct with non-zero values immediately after it is allocated. An added benefit is we now have an explicit reference to each field name where it is initialized (for all you cscope fans out there). Signed-off-by: Chuck Lever Signed-off-by: Trond Myklebust --- fs/lockd/host.c | 110 +++++++++++++++++++++++++++++++++----------------------- 1 file changed, 65 insertions(+), 45 deletions(-) diff --git a/fs/lockd/host.c b/fs/lockd/host.c index 2dbf1392acfc..1911f34be976 100644 --- a/fs/lockd/host.c +++ b/fs/lockd/host.c @@ -99,6 +99,68 @@ static unsigned int nlm_hash_address(const struct sockaddr *sap) return hash & (NLM_HOST_NRHASH - 1); } +/* + * Allocate and initialize an nlm_host. Common to both client and server. + */ +static struct nlm_host *nlm_alloc_host(struct nlm_lookup_host_info *ni, + struct nsm_handle *nsm) +{ + struct nlm_host *host = NULL; + unsigned long now = jiffies; + + if (nsm != NULL) + atomic_inc(&nsm->sm_count); + else { + host = NULL; + nsm = nsm_get_handle(ni->sap, ni->salen, + ni->hostname, ni->hostname_len); + if (unlikely(nsm == NULL)) { + dprintk("lockd: %s failed; no nsm handle\n", + __func__); + goto out; + } + } + + host = kmalloc(sizeof(*host), GFP_KERNEL); + if (unlikely(host == NULL)) { + dprintk("lockd: %s failed; no memory\n", __func__); + nsm_release(nsm); + goto out; + } + + memcpy(nlm_addr(host), ni->sap, ni->salen); + host->h_addrlen = ni->salen; + rpc_set_port(nlm_addr(host), 0); + host->h_srcaddrlen = 0; + + host->h_rpcclnt = NULL; + host->h_name = nsm->sm_name; + host->h_version = ni->version; + host->h_proto = ni->protocol; + host->h_reclaiming = 0; + host->h_server = ni->server; + host->h_noresvport = ni->noresvport; + host->h_inuse = 0; + init_waitqueue_head(&host->h_gracewait); + init_rwsem(&host->h_rwsem); + host->h_state = 0; + host->h_nsmstate = 0; + host->h_pidcount = 0; + atomic_set(&host->h_count, 1); + mutex_init(&host->h_mutex); + host->h_nextrebind = now + NLM_HOST_REBIND; + host->h_expires = now + NLM_HOST_EXPIRE; + INIT_LIST_HEAD(&host->h_lockowners); + spin_lock_init(&host->h_lock); + INIT_LIST_HEAD(&host->h_granted); + INIT_LIST_HEAD(&host->h_reclaim); + host->h_nsmhandle = nsm; + host->h_addrbuf = nsm->sm_addrbuf; + +out: + return host; +} + /* * Common host lookup routine for server & client */ @@ -150,55 +212,13 @@ static struct nlm_host *nlm_lookup_host(struct nlm_lookup_host_info *ni) goto out; } - /* - * The host wasn't in our hash table. If we don't - * have an NSM handle for it yet, create one. - */ - if (nsm) - atomic_inc(&nsm->sm_count); - else { - host = NULL; - nsm = nsm_get_handle(ni->sap, ni->salen, - ni->hostname, ni->hostname_len); - if (!nsm) { - dprintk("lockd: nlm_lookup_host failed; " - "no nsm handle\n"); - goto out; - } - } - - host = kzalloc(sizeof(*host), GFP_KERNEL); - if (!host) { - nsm_release(nsm); - dprintk("lockd: nlm_lookup_host failed; no memory\n"); + host = nlm_alloc_host(ni, nsm); + if (unlikely(host == NULL)) goto out; - } - host->h_name = nsm->sm_name; - host->h_addrbuf = nsm->sm_addrbuf; - memcpy(nlm_addr(host), ni->sap, ni->salen); - host->h_addrlen = ni->salen; - rpc_set_port(nlm_addr(host), 0); + memcpy(nlm_srcaddr(host), ni->src_sap, ni->src_len); host->h_srcaddrlen = ni->src_len; - host->h_version = ni->version; - host->h_proto = ni->protocol; - host->h_rpcclnt = NULL; - mutex_init(&host->h_mutex); - host->h_nextrebind = jiffies + NLM_HOST_REBIND; - host->h_expires = jiffies + NLM_HOST_EXPIRE; - atomic_set(&host->h_count, 1); - init_waitqueue_head(&host->h_gracewait); - init_rwsem(&host->h_rwsem); - host->h_state = 0; /* pseudo NSM state */ - host->h_nsmstate = 0; /* real NSM state */ - host->h_nsmhandle = nsm; - host->h_server = ni->server; - host->h_noresvport = ni->noresvport; hlist_add_head(&host->h_hash, chain); - INIT_LIST_HEAD(&host->h_lockowners); - spin_lock_init(&host->h_lock); - INIT_LIST_HEAD(&host->h_granted); - INIT_LIST_HEAD(&host->h_reclaim); nrhosts++; -- cgit v1.2.3 From 723bb5b5052faba57060a2feb564ced22416b5bc Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Tue, 14 Dec 2010 15:05:33 +0000 Subject: lockd: Add nlm_destroy_host_locked() Refactor the tail of nlm_gc_hosts() into nlm_destroy_host() so that this logic can be used separately from garbage collection. Rename it _locked() to document that it must be called with the hosts cache mutex held. Signed-off-by: Chuck Lever Signed-off-by: Trond Myklebust --- fs/lockd/host.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/fs/lockd/host.c b/fs/lockd/host.c index 1911f34be976..e58e1426d161 100644 --- a/fs/lockd/host.c +++ b/fs/lockd/host.c @@ -231,16 +231,21 @@ out: } /* - * Destroy a host + * Destroy an nlm_host and free associated resources + * + * Caller must hold nlm_host_mutex. */ -static void -nlm_destroy_host(struct nlm_host *host) +static void nlm_destroy_host_locked(struct nlm_host *host) { struct rpc_clnt *clnt; + dprintk("lockd: destroy host %s\n", host->h_name); + BUG_ON(!list_empty(&host->h_lockowners)); BUG_ON(atomic_read(&host->h_count)); + hlist_del_init(&host->h_hash); + nsm_unmonitor(host); nsm_release(host->h_nsmhandle); @@ -248,6 +253,8 @@ nlm_destroy_host(struct nlm_host *host) if (clnt != NULL) rpc_shutdown_client(clnt); kfree(host); + + nrhosts--; } /** @@ -589,11 +596,7 @@ nlm_gc_hosts(void) host->h_inuse, host->h_expires); continue; } - dprintk("lockd: delete host %s\n", host->h_name); - hlist_del_init(&host->h_hash); - - nlm_destroy_host(host); - nrhosts--; + nlm_destroy_host_locked(host); } next_gc = jiffies + NLM_HOST_COLLECT; -- cgit v1.2.3 From 7db836d4a427c3c64406b00b6d8d745d6335d72a Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Tue, 14 Dec 2010 15:05:42 +0000 Subject: lockd: Split nlm_release_call() The nlm_release_call() function is invoked from both the server and the client side. We're about to introduce a distinct server- and client-side nlm_release_host(), so nlm_release_call() must first be split into a client-side and a server-side version. Signed-off-by: Chuck Lever Signed-off-by: Trond Myklebust --- fs/lockd/clntproc.c | 12 ++++++------ fs/lockd/svc4proc.c | 4 ++-- fs/lockd/svclock.c | 4 ++-- fs/lockd/svcproc.c | 12 ++++++++++-- include/linux/lockd/lockd.h | 3 ++- 5 files changed, 22 insertions(+), 13 deletions(-) diff --git a/fs/lockd/clntproc.c b/fs/lockd/clntproc.c index 332c54cf75e0..fbc6617f76c4 100644 --- a/fs/lockd/clntproc.c +++ b/fs/lockd/clntproc.c @@ -211,7 +211,7 @@ struct nlm_rqst *nlm_alloc_call(struct nlm_host *host) return NULL; } -void nlm_release_call(struct nlm_rqst *call) +void nlmclnt_release_call(struct nlm_rqst *call) { if (!atomic_dec_and_test(&call->a_count)) return; @@ -222,7 +222,7 @@ void nlm_release_call(struct nlm_rqst *call) static void nlmclnt_rpc_release(void *data) { - nlm_release_call(data); + nlmclnt_release_call(data); } static int nlm_wait_on_grace(wait_queue_head_t *queue) @@ -436,7 +436,7 @@ nlmclnt_test(struct nlm_rqst *req, struct file_lock *fl) status = nlm_stat_to_errno(req->a_res.status); } out: - nlm_release_call(req); + nlmclnt_release_call(req); return status; } @@ -593,7 +593,7 @@ again: out_unblock: nlmclnt_finish_block(block); out: - nlm_release_call(req); + nlmclnt_release_call(req); return status; out_unlock: /* Fatal error: ensure that we remove the lock altogether */ @@ -694,7 +694,7 @@ nlmclnt_unlock(struct nlm_rqst *req, struct file_lock *fl) /* What to do now? I'm out of my depth... */ status = -ENOLCK; out: - nlm_release_call(req); + nlmclnt_release_call(req); return status; } @@ -755,7 +755,7 @@ static int nlmclnt_cancel(struct nlm_host *host, int block, struct file_lock *fl NLMPROC_CANCEL, &nlmclnt_cancel_ops); if (status == 0 && req->a_res.status == nlm_lck_denied) status = -ENOLCK; - nlm_release_call(req); + nlmclnt_release_call(req); return status; } diff --git a/fs/lockd/svc4proc.c b/fs/lockd/svc4proc.c index 38d261192453..c187422026d8 100644 --- a/fs/lockd/svc4proc.c +++ b/fs/lockd/svc4proc.c @@ -229,7 +229,7 @@ static void nlm4svc_callback_exit(struct rpc_task *task, void *data) static void nlm4svc_callback_release(void *data) { - nlm_release_call(data); + nlmsvc_release_call(data); } static const struct rpc_call_ops nlm4svc_callback_ops = { @@ -261,7 +261,7 @@ static __be32 nlm4svc_callback(struct svc_rqst *rqstp, u32 proc, struct nlm_args stat = func(rqstp, argp, &call->a_res); if (stat != 0) { - nlm_release_call(call); + nlmsvc_release_call(call); return stat; } diff --git a/fs/lockd/svclock.c b/fs/lockd/svclock.c index 9266c4600208..6e31695d046f 100644 --- a/fs/lockd/svclock.c +++ b/fs/lockd/svclock.c @@ -234,7 +234,7 @@ nlmsvc_create_block(struct svc_rqst *rqstp, struct nlm_host *host, failed_free: kfree(block); failed: - nlm_release_call(call); + nlmsvc_release_call(call); return NULL; } @@ -267,7 +267,7 @@ static void nlmsvc_free_block(struct kref *kref) mutex_unlock(&file->f_mutex); nlmsvc_freegrantargs(block->b_call); - nlm_release_call(block->b_call); + nlmsvc_release_call(block->b_call); nlm_release_file(block->b_file); kfree(block->b_fl); kfree(block); diff --git a/fs/lockd/svcproc.c b/fs/lockd/svcproc.c index 0caea5310ac3..0df65ec29e43 100644 --- a/fs/lockd/svcproc.c +++ b/fs/lockd/svcproc.c @@ -257,9 +257,17 @@ static void nlmsvc_callback_exit(struct rpc_task *task, void *data) -task->tk_status); } +void nlmsvc_release_call(struct nlm_rqst *call) +{ + if (!atomic_dec_and_test(&call->a_count)) + return; + nlm_release_host(call->a_host); + kfree(call); +} + static void nlmsvc_callback_release(void *data) { - nlm_release_call(data); + nlmsvc_release_call(data); } static const struct rpc_call_ops nlmsvc_callback_ops = { @@ -291,7 +299,7 @@ static __be32 nlmsvc_callback(struct svc_rqst *rqstp, u32 proc, struct nlm_args stat = func(rqstp, argp, &call->a_res); if (stat != 0) { - nlm_release_call(call); + nlmsvc_release_call(call); return stat; } diff --git a/include/linux/lockd/lockd.h b/include/linux/lockd/lockd.h index 2dee05e5119a..a32ba62455af 100644 --- a/include/linux/lockd/lockd.h +++ b/include/linux/lockd/lockd.h @@ -202,9 +202,9 @@ extern u32 nsm_local_state; * Lockd client functions */ struct nlm_rqst * nlm_alloc_call(struct nlm_host *host); -void nlm_release_call(struct nlm_rqst *); int nlm_async_call(struct nlm_rqst *, u32, const struct rpc_call_ops *); int nlm_async_reply(struct nlm_rqst *, u32, const struct rpc_call_ops *); +void nlmclnt_release_call(struct nlm_rqst *); struct nlm_wait * nlmclnt_prepare_block(struct nlm_host *host, struct file_lock *fl); void nlmclnt_finish_block(struct nlm_wait *block); int nlmclnt_block(struct nlm_wait *block, struct nlm_rqst *req, long timeout); @@ -267,6 +267,7 @@ unsigned long nlmsvc_retry_blocked(void); void nlmsvc_traverse_blocks(struct nlm_host *, struct nlm_file *, nlm_host_match_fn_t match); void nlmsvc_grant_reply(struct nlm_cookie *, __be32); +void nlmsvc_release_call(struct nlm_rqst *); /* * File handling for the server personality -- cgit v1.2.3 From 8ea6ecc8b0759756a766c05dc7c98c51ec90de37 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Tue, 14 Dec 2010 15:05:52 +0000 Subject: lockd: Create client-side nlm_host cache NFS clients don't need the garbage collection processing that is performed on nlm_host structures. The client picks up an nlm_host at mount time and holds a reference to it until the file system is unmounted. Servers, on the other hand, don't have a precise way to tell when an nlm_host is no longer being used, so zero refcount nlm_host entries are left to expire in the cache after a time. Basically there's nothing holding a reference to an nlm_host between individual server-side NLM requests, but we can't afford the expense of recreating them for every new NLM request from a client. The nlm_host cache adds some lifetime hysteresis to entries in the cache so the next time a particular nlm_host is needed, it's likely to be discovered by a lookup rather than created from whole cloth. With the new implementation, client nlm_host cache items are no longer garbage collected, and are destroyed directly by a new release function specialized for client entries, nlmclnt_release_host(). They are cached in their own data structure, and have their own lookup logic, simplified and specialized for client nlm_host entries. However, the client nlm_host cache still shares reboot recovery logic with the server nlm_host cache. The NSM "peer rebooted" downcall for clients and servers still come through the same RPC call. This is a legacy formal API that would be difficult to alter, and besides, the user space NSM implementation can't tell the difference between peers that are clients or servers. For this reason, the client cache continues to share the nlm_host_mutex (and reboot recovery logic) with the server cache. Signed-off-by: Chuck Lever Signed-off-by: Trond Myklebust --- fs/lockd/clntlock.c | 4 +-- fs/lockd/clntproc.c | 6 ++-- fs/lockd/host.c | 81 ++++++++++++++++++++++++++++++++++++++++----- include/linux/lockd/lockd.h | 1 + 4 files changed, 78 insertions(+), 14 deletions(-) diff --git a/fs/lockd/clntlock.c b/fs/lockd/clntlock.c index 25509eb28fd7..8d4ea8351e3d 100644 --- a/fs/lockd/clntlock.c +++ b/fs/lockd/clntlock.c @@ -79,7 +79,7 @@ EXPORT_SYMBOL_GPL(nlmclnt_init); */ void nlmclnt_done(struct nlm_host *host) { - nlm_release_host(host); + nlmclnt_release_host(host); lockd_down(); } EXPORT_SYMBOL_GPL(nlmclnt_done); @@ -273,7 +273,7 @@ restart: spin_unlock(&nlm_blocked_lock); /* Release host handle after use */ - nlm_release_host(host); + nlmclnt_release_host(host); lockd_down(); return 0; } diff --git a/fs/lockd/clntproc.c b/fs/lockd/clntproc.c index fbc6617f76c4..adb45ec9038c 100644 --- a/fs/lockd/clntproc.c +++ b/fs/lockd/clntproc.c @@ -58,7 +58,7 @@ static void nlm_put_lockowner(struct nlm_lockowner *lockowner) return; list_del(&lockowner->list); spin_unlock(&lockowner->host->h_lock); - nlm_release_host(lockowner->host); + nlmclnt_release_host(lockowner->host); kfree(lockowner); } @@ -207,7 +207,7 @@ struct nlm_rqst *nlm_alloc_call(struct nlm_host *host) printk("nlm_alloc_call: failed, waiting for memory\n"); schedule_timeout_interruptible(5*HZ); } - nlm_release_host(host); + nlmclnt_release_host(host); return NULL; } @@ -215,7 +215,7 @@ void nlmclnt_release_call(struct nlm_rqst *call) { if (!atomic_dec_and_test(&call->a_count)) return; - nlm_release_host(call->a_host); + nlmclnt_release_host(call->a_host); nlmclnt_release_lockargs(call); kfree(call); } diff --git a/fs/lockd/host.c b/fs/lockd/host.c index e58e1426d161..c6942fb4bd0d 100644 --- a/fs/lockd/host.c +++ b/fs/lockd/host.c @@ -26,6 +26,7 @@ #define NLM_HOST_COLLECT (120 * HZ) static struct hlist_head nlm_hosts[NLM_HOST_NRHASH]; +static struct hlist_head nlm_client_hosts[NLM_HOST_NRHASH]; #define for_each_host(host, pos, chain, table) \ for ((chain) = (table); \ @@ -288,12 +289,76 @@ struct nlm_host *nlmclnt_lookup_host(const struct sockaddr *sap, .hostname_len = strlen(hostname), .noresvport = noresvport, }; + struct hlist_head *chain; + struct hlist_node *pos; + struct nlm_host *host; + struct nsm_handle *nsm = NULL; dprintk("lockd: %s(host='%s', vers=%u, proto=%s)\n", __func__, (hostname ? hostname : ""), version, (protocol == IPPROTO_UDP ? "udp" : "tcp")); - return nlm_lookup_host(&ni); + mutex_lock(&nlm_host_mutex); + + chain = &nlm_client_hosts[nlm_hash_address(sap)]; + hlist_for_each_entry(host, pos, chain, h_hash) { + if (!rpc_cmp_addr(nlm_addr(host), sap)) + continue; + + /* Same address. Share an NSM handle if we already have one */ + if (nsm == NULL) + nsm = host->h_nsmhandle; + + if (host->h_proto != protocol) + continue; + if (host->h_version != version) + continue; + + nlm_get_host(host); + dprintk("lockd: %s found host %s (%s)\n", __func__, + host->h_name, host->h_addrbuf); + goto out; + } + + host = nlm_alloc_host(&ni, nsm); + if (unlikely(host == NULL)) + goto out; + + hlist_add_head(&host->h_hash, chain); + nrhosts++; + + dprintk("lockd: %s created host %s (%s)\n", __func__, + host->h_name, host->h_addrbuf); + +out: + mutex_unlock(&nlm_host_mutex); + return host; +} + +/** + * nlmclnt_release_host - release client nlm_host + * @host: nlm_host to release + * + */ +void nlmclnt_release_host(struct nlm_host *host) +{ + if (host == NULL) + return; + + dprintk("lockd: release client host %s\n", host->h_name); + + BUG_ON(atomic_read(&host->h_count) < 0); + BUG_ON(host->h_server); + + if (atomic_dec_and_test(&host->h_count)) { + BUG_ON(!list_empty(&host->h_lockowners)); + BUG_ON(!list_empty(&host->h_granted)); + BUG_ON(!list_empty(&host->h_reclaim)); + + mutex_lock(&nlm_host_mutex); + nlm_destroy_host_locked(host); + mutex_unlock(&nlm_host_mutex); + } } /** @@ -515,16 +580,14 @@ void nlm_host_rebooted(const struct nlm_reboot *info) * To avoid processing a host several times, we match the nsmstate. */ while ((host = next_host_state(nlm_hosts, nsm, info)) != NULL) { - if (host->h_server) { - /* We're server for this guy, just ditch - * all the locks he held. */ - nlmsvc_free_host_resources(host); - } else { - /* He's the server, initiate lock recovery. */ - nlmclnt_recovery(host); - } + nlmsvc_free_host_resources(host); nlm_release_host(host); } + while ((host = next_host_state(nlm_client_hosts, nsm, info)) != NULL) { + nlmclnt_recovery(host); + nlmclnt_release_host(host); + } + nsm_release(nsm); } diff --git a/include/linux/lockd/lockd.h b/include/linux/lockd/lockd.h index a32ba62455af..6c2a0e2f298e 100644 --- a/include/linux/lockd/lockd.h +++ b/include/linux/lockd/lockd.h @@ -223,6 +223,7 @@ struct nlm_host *nlmclnt_lookup_host(const struct sockaddr *sap, const u32 version, const char *hostname, int noresvport); +void nlmclnt_release_host(struct nlm_host *); struct nlm_host *nlmsvc_lookup_host(const struct svc_rqst *rqstp, const char *hostname, const size_t hostname_len); -- cgit v1.2.3 From 67216b94d498f5880d8bba2a6b841880739dd524 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Tue, 14 Dec 2010 15:06:12 +0000 Subject: lockd: Clean up nlmsvc_lookup_host() Clean up. Change nlmsvc_lookup_host() to be purpose-built for server-side nlm_host management. This replaces the generic nlm_lookup_host() helper function, just like on the client side. The lookup logic is specialized for server host lookups. The server side cache also gets its own specialized equivalent of the nlm_release_host() function. Signed-off-by: Chuck Lever Signed-off-by: Trond Myklebust --- fs/lockd/host.c | 91 +++++++++++++++++++++++++++++++++++---------- fs/lockd/svc4proc.c | 16 ++++---- fs/lockd/svcproc.c | 18 ++++----- include/linux/lockd/lockd.h | 2 +- 4 files changed, 90 insertions(+), 37 deletions(-) diff --git a/fs/lockd/host.c b/fs/lockd/host.c index c6942fb4bd0d..0250b0e4f5e9 100644 --- a/fs/lockd/host.c +++ b/fs/lockd/host.c @@ -383,6 +383,10 @@ struct nlm_host *nlmsvc_lookup_host(const struct svc_rqst *rqstp, const char *hostname, const size_t hostname_len) { + struct hlist_head *chain; + struct hlist_node *pos; + struct nlm_host *host = NULL; + struct nsm_handle *nsm = NULL; struct sockaddr_in sin = { .sin_family = AF_INET, }; @@ -404,6 +408,8 @@ struct nlm_host *nlmsvc_lookup_host(const struct svc_rqst *rqstp, (int)hostname_len, hostname, rqstp->rq_vers, (rqstp->rq_prot == IPPROTO_UDP ? "udp" : "tcp")); + mutex_lock(&nlm_host_mutex); + switch (ni.sap->sa_family) { case AF_INET: sin.sin_addr.s_addr = rqstp->rq_daddr.addr.s_addr; @@ -414,10 +420,73 @@ struct nlm_host *nlmsvc_lookup_host(const struct svc_rqst *rqstp, ni.src_sap = (struct sockaddr *)&sin6; break; default: - return NULL; + dprintk("lockd: %s failed; unrecognized address family\n", + __func__); + goto out; } - return nlm_lookup_host(&ni); + if (time_after_eq(jiffies, next_gc)) + nlm_gc_hosts(); + + chain = &nlm_hosts[nlm_hash_address(ni.sap)]; + hlist_for_each_entry(host, pos, chain, h_hash) { + if (!rpc_cmp_addr(nlm_addr(host), ni.sap)) + continue; + + /* Same address. Share an NSM handle if we already have one */ + if (nsm == NULL) + nsm = host->h_nsmhandle; + + if (host->h_proto != ni.protocol) + continue; + if (host->h_version != ni.version) + continue; + if (!rpc_cmp_addr(nlm_srcaddr(host), ni.src_sap)) + continue; + + /* Move to head of hash chain. */ + hlist_del(&host->h_hash); + hlist_add_head(&host->h_hash, chain); + + nlm_get_host(host); + dprintk("lockd: %s found host %s (%s)\n", + __func__, host->h_name, host->h_addrbuf); + goto out; + } + + host = nlm_alloc_host(&ni, nsm); + if (unlikely(host == NULL)) + goto out; + + memcpy(nlm_srcaddr(host), ni.src_sap, ni.src_len); + host->h_srcaddrlen = ni.src_len; + hlist_add_head(&host->h_hash, chain); + nrhosts++; + + dprintk("lockd: %s created host %s (%s)\n", + __func__, host->h_name, host->h_addrbuf); + +out: + mutex_unlock(&nlm_host_mutex); + return host; +} + +/** + * nlmsvc_release_host - release server nlm_host + * @host: nlm_host to release + * + * Host is destroyed later in nlm_gc_host(). + */ +void nlmsvc_release_host(struct nlm_host *host) +{ + if (host == NULL) + return; + + dprintk("lockd: release server host %s\n", host->h_name); + + BUG_ON(atomic_read(&host->h_count) < 0); + BUG_ON(!host->h_server); + atomic_dec(&host->h_count); } /* @@ -517,22 +586,6 @@ struct nlm_host * nlm_get_host(struct nlm_host *host) return host; } -/* - * Release NLM host after use - */ -void nlm_release_host(struct nlm_host *host) -{ - if (host != NULL) { - dprintk("lockd: release host %s\n", host->h_name); - BUG_ON(atomic_read(&host->h_count) < 0); - if (atomic_dec_and_test(&host->h_count)) { - BUG_ON(!list_empty(&host->h_lockowners)); - BUG_ON(!list_empty(&host->h_granted)); - BUG_ON(!list_empty(&host->h_reclaim)); - } - } -} - static struct nlm_host *next_host_state(struct hlist_head *cache, struct nsm_handle *nsm, const struct nlm_reboot *info) @@ -581,7 +634,7 @@ void nlm_host_rebooted(const struct nlm_reboot *info) */ while ((host = next_host_state(nlm_hosts, nsm, info)) != NULL) { nlmsvc_free_host_resources(host); - nlm_release_host(host); + nlmsvc_release_host(host); } while ((host = next_host_state(nlm_client_hosts, nsm, info)) != NULL) { nlmclnt_recovery(host); diff --git a/fs/lockd/svc4proc.c b/fs/lockd/svc4proc.c index c187422026d8..9a41fdc19511 100644 --- a/fs/lockd/svc4proc.c +++ b/fs/lockd/svc4proc.c @@ -51,7 +51,7 @@ nlm4svc_retrieve_args(struct svc_rqst *rqstp, struct nlm_args *argp, return 0; no_locks: - nlm_release_host(host); + nlmsvc_release_host(host); if (error) return error; return nlm_lck_denied_nolocks; @@ -92,7 +92,7 @@ nlm4svc_proc_test(struct svc_rqst *rqstp, struct nlm_args *argp, else dprintk("lockd: TEST4 status %d\n", ntohl(resp->status)); - nlm_release_host(host); + nlmsvc_release_host(host); nlm_release_file(file); return rc; } @@ -134,7 +134,7 @@ nlm4svc_proc_lock(struct svc_rqst *rqstp, struct nlm_args *argp, else dprintk("lockd: LOCK status %d\n", ntohl(resp->status)); - nlm_release_host(host); + nlmsvc_release_host(host); nlm_release_file(file); return rc; } @@ -164,7 +164,7 @@ nlm4svc_proc_cancel(struct svc_rqst *rqstp, struct nlm_args *argp, resp->status = nlmsvc_cancel_blocked(file, &argp->lock); dprintk("lockd: CANCEL status %d\n", ntohl(resp->status)); - nlm_release_host(host); + nlmsvc_release_host(host); nlm_release_file(file); return rpc_success; } @@ -197,7 +197,7 @@ nlm4svc_proc_unlock(struct svc_rqst *rqstp, struct nlm_args *argp, resp->status = nlmsvc_unlock(file, &argp->lock); dprintk("lockd: UNLOCK status %d\n", ntohl(resp->status)); - nlm_release_host(host); + nlmsvc_release_host(host); nlm_release_file(file); return rpc_success; } @@ -334,7 +334,7 @@ nlm4svc_proc_share(struct svc_rqst *rqstp, struct nlm_args *argp, resp->status = nlmsvc_share_file(host, file, argp); dprintk("lockd: SHARE status %d\n", ntohl(resp->status)); - nlm_release_host(host); + nlmsvc_release_host(host); nlm_release_file(file); return rpc_success; } @@ -367,7 +367,7 @@ nlm4svc_proc_unshare(struct svc_rqst *rqstp, struct nlm_args *argp, resp->status = nlmsvc_unshare_file(host, file, argp); dprintk("lockd: UNSHARE status %d\n", ntohl(resp->status)); - nlm_release_host(host); + nlmsvc_release_host(host); nlm_release_file(file); return rpc_success; } @@ -399,7 +399,7 @@ nlm4svc_proc_free_all(struct svc_rqst *rqstp, struct nlm_args *argp, return rpc_success; nlmsvc_free_host_resources(host); - nlm_release_host(host); + nlmsvc_release_host(host); return rpc_success; } diff --git a/fs/lockd/svcproc.c b/fs/lockd/svcproc.c index 0df65ec29e43..d27aab11f324 100644 --- a/fs/lockd/svcproc.c +++ b/fs/lockd/svcproc.c @@ -80,7 +80,7 @@ nlmsvc_retrieve_args(struct svc_rqst *rqstp, struct nlm_args *argp, return 0; no_locks: - nlm_release_host(host); + nlmsvc_release_host(host); if (error) return error; return nlm_lck_denied_nolocks; @@ -122,7 +122,7 @@ nlmsvc_proc_test(struct svc_rqst *rqstp, struct nlm_args *argp, dprintk("lockd: TEST status %d vers %d\n", ntohl(resp->status), rqstp->rq_vers); - nlm_release_host(host); + nlmsvc_release_host(host); nlm_release_file(file); return rc; } @@ -164,7 +164,7 @@ nlmsvc_proc_lock(struct svc_rqst *rqstp, struct nlm_args *argp, else dprintk("lockd: LOCK status %d\n", ntohl(resp->status)); - nlm_release_host(host); + nlmsvc_release_host(host); nlm_release_file(file); return rc; } @@ -194,7 +194,7 @@ nlmsvc_proc_cancel(struct svc_rqst *rqstp, struct nlm_args *argp, resp->status = cast_status(nlmsvc_cancel_blocked(file, &argp->lock)); dprintk("lockd: CANCEL status %d\n", ntohl(resp->status)); - nlm_release_host(host); + nlmsvc_release_host(host); nlm_release_file(file); return rpc_success; } @@ -227,7 +227,7 @@ nlmsvc_proc_unlock(struct svc_rqst *rqstp, struct nlm_args *argp, resp->status = cast_status(nlmsvc_unlock(file, &argp->lock)); dprintk("lockd: UNLOCK status %d\n", ntohl(resp->status)); - nlm_release_host(host); + nlmsvc_release_host(host); nlm_release_file(file); return rpc_success; } @@ -261,7 +261,7 @@ void nlmsvc_release_call(struct nlm_rqst *call) { if (!atomic_dec_and_test(&call->a_count)) return; - nlm_release_host(call->a_host); + nlmsvc_release_host(call->a_host); kfree(call); } @@ -374,7 +374,7 @@ nlmsvc_proc_share(struct svc_rqst *rqstp, struct nlm_args *argp, resp->status = cast_status(nlmsvc_share_file(host, file, argp)); dprintk("lockd: SHARE status %d\n", ntohl(resp->status)); - nlm_release_host(host); + nlmsvc_release_host(host); nlm_release_file(file); return rpc_success; } @@ -407,7 +407,7 @@ nlmsvc_proc_unshare(struct svc_rqst *rqstp, struct nlm_args *argp, resp->status = cast_status(nlmsvc_unshare_file(host, file, argp)); dprintk("lockd: UNSHARE status %d\n", ntohl(resp->status)); - nlm_release_host(host); + nlmsvc_release_host(host); nlm_release_file(file); return rpc_success; } @@ -439,7 +439,7 @@ nlmsvc_proc_free_all(struct svc_rqst *rqstp, struct nlm_args *argp, return rpc_success; nlmsvc_free_host_resources(host); - nlm_release_host(host); + nlmsvc_release_host(host); return rpc_success; } diff --git a/include/linux/lockd/lockd.h b/include/linux/lockd/lockd.h index 6c2a0e2f298e..ff9abff55aa0 100644 --- a/include/linux/lockd/lockd.h +++ b/include/linux/lockd/lockd.h @@ -227,10 +227,10 @@ void nlmclnt_release_host(struct nlm_host *); struct nlm_host *nlmsvc_lookup_host(const struct svc_rqst *rqstp, const char *hostname, const size_t hostname_len); +void nlmsvc_release_host(struct nlm_host *); struct rpc_clnt * nlm_bind_host(struct nlm_host *); void nlm_rebind_host(struct nlm_host *); struct nlm_host * nlm_get_host(struct nlm_host *); -void nlm_release_host(struct nlm_host *); void nlm_shutdown_hosts(void); void nlm_host_rebooted(const struct nlm_reboot *); -- cgit v1.2.3 From d2df0484bb38f2e0d9754b00597d4a6d1cf666d0 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Tue, 14 Dec 2010 15:06:22 +0000 Subject: lockd: Rename nlm_hosts Clean up. nlm_hosts now contains only server-side entries. Rename it to match convention of client side cache. Signed-off-by: Chuck Lever Signed-off-by: Trond Myklebust --- fs/lockd/host.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/fs/lockd/host.c b/fs/lockd/host.c index 0250b0e4f5e9..87fbde1d1a1f 100644 --- a/fs/lockd/host.c +++ b/fs/lockd/host.c @@ -25,7 +25,7 @@ #define NLM_HOST_EXPIRE (300 * HZ) #define NLM_HOST_COLLECT (120 * HZ) -static struct hlist_head nlm_hosts[NLM_HOST_NRHASH]; +static struct hlist_head nlm_server_hosts[NLM_HOST_NRHASH]; static struct hlist_head nlm_client_hosts[NLM_HOST_NRHASH]; #define for_each_host(host, pos, chain, table) \ @@ -184,7 +184,7 @@ static struct nlm_host *nlm_lookup_host(struct nlm_lookup_host_info *ni) * different NLM rpc_clients into one single nlm_host object. * This would allow us to have one nlm_host per address. */ - chain = &nlm_hosts[nlm_hash_address(ni->sap)]; + chain = &nlm_server_hosts[nlm_hash_address(ni->sap)]; hlist_for_each_entry(host, pos, chain, h_hash) { if (!rpc_cmp_addr(nlm_addr(host), ni->sap)) continue; @@ -428,7 +428,7 @@ struct nlm_host *nlmsvc_lookup_host(const struct svc_rqst *rqstp, if (time_after_eq(jiffies, next_gc)) nlm_gc_hosts(); - chain = &nlm_hosts[nlm_hash_address(ni.sap)]; + chain = &nlm_server_hosts[nlm_hash_address(ni.sap)]; hlist_for_each_entry(host, pos, chain, h_hash) { if (!rpc_cmp_addr(nlm_addr(host), ni.sap)) continue; @@ -632,7 +632,7 @@ void nlm_host_rebooted(const struct nlm_reboot *info) * lock for this. * To avoid processing a host several times, we match the nsmstate. */ - while ((host = next_host_state(nlm_hosts, nsm, info)) != NULL) { + while ((host = next_host_state(nlm_server_hosts, nsm, info)) != NULL) { nlmsvc_free_host_resources(host); nlmsvc_release_host(host); } @@ -660,7 +660,7 @@ nlm_shutdown_hosts(void) /* First, make all hosts eligible for gc */ dprintk("lockd: nuking all hosts...\n"); - for_each_host(host, pos, chain, nlm_hosts) { + for_each_host(host, pos, chain, nlm_server_hosts) { host->h_expires = jiffies - 1; if (host->h_rpcclnt) { rpc_shutdown_client(host->h_rpcclnt); @@ -676,7 +676,7 @@ nlm_shutdown_hosts(void) if (nrhosts) { printk(KERN_WARNING "lockd: couldn't shutdown host module!\n"); dprintk("lockd: %d hosts left:\n", nrhosts); - for_each_host(host, pos, chain, nlm_hosts) { + for_each_host(host, pos, chain, nlm_server_hosts) { dprintk(" %s (cnt %d use %d exp %ld)\n", host->h_name, atomic_read(&host->h_count), host->h_inuse, host->h_expires); @@ -697,13 +697,13 @@ nlm_gc_hosts(void) struct nlm_host *host; dprintk("lockd: host garbage collection\n"); - for_each_host(host, pos, chain, nlm_hosts) + for_each_host(host, pos, chain, nlm_server_hosts) host->h_inuse = 0; /* Mark all hosts that hold locks, blocks or shares */ nlmsvc_mark_resources(); - for_each_host_safe(host, pos, next, chain, nlm_hosts) { + for_each_host_safe(host, pos, next, chain, nlm_server_hosts) { if (atomic_read(&host->h_count) || host->h_inuse || time_before(jiffies, host->h_expires)) { dprintk("nlm_gc_hosts skipping %s " -- cgit v1.2.3 From fcc072c783491ca465e4d1e74da7dbb48dbf7a31 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Tue, 14 Dec 2010 15:06:32 +0000 Subject: lockd: Make nrhosts an unsigned long Clean up. Signed-off-by: Chuck Lever Signed-off-by: Trond Myklebust --- fs/lockd/host.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/fs/lockd/host.c b/fs/lockd/host.c index 87fbde1d1a1f..77ec21a808db 100644 --- a/fs/lockd/host.c +++ b/fs/lockd/host.c @@ -40,7 +40,7 @@ static struct hlist_head nlm_client_hosts[NLM_HOST_NRHASH]; (chain), h_hash) static unsigned long next_gc; -static int nrhosts; +static unsigned long nrhosts; static DEFINE_MUTEX(nlm_host_mutex); static void nlm_gc_hosts(void); @@ -673,9 +673,9 @@ nlm_shutdown_hosts(void) mutex_unlock(&nlm_host_mutex); /* complain if any hosts are left */ - if (nrhosts) { + if (nrhosts != 0) { printk(KERN_WARNING "lockd: couldn't shutdown host module!\n"); - dprintk("lockd: %d hosts left:\n", nrhosts); + dprintk("lockd: %lu hosts left:\n", nrhosts); for_each_host(host, pos, chain, nlm_server_hosts) { dprintk(" %s (cnt %d use %d exp %ld)\n", host->h_name, atomic_read(&host->h_count), -- cgit v1.2.3 From 2025889828bb14b56d9aa4c1a785bd9847ccdc4b Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Tue, 14 Dec 2010 15:06:41 +0000 Subject: lockd: Remove nlm_lookup_host() Clean up. Remove the now unused helper nlm_lookup_host(). Signed-off-by: Chuck Lever Signed-off-by: Trond Myklebust --- fs/lockd/host.c | 69 --------------------------------------------------------- 1 file changed, 69 deletions(-) diff --git a/fs/lockd/host.c b/fs/lockd/host.c index 77ec21a808db..6d4aa8b3d610 100644 --- a/fs/lockd/host.c +++ b/fs/lockd/host.c @@ -162,75 +162,6 @@ out: return host; } -/* - * Common host lookup routine for server & client - */ -static struct nlm_host *nlm_lookup_host(struct nlm_lookup_host_info *ni) -{ - struct hlist_head *chain; - struct hlist_node *pos; - struct nlm_host *host; - struct nsm_handle *nsm = NULL; - - mutex_lock(&nlm_host_mutex); - - if (time_after_eq(jiffies, next_gc)) - nlm_gc_hosts(); - - /* We may keep several nlm_host objects for a peer, because each - * nlm_host is identified by - * (address, protocol, version, server/client) - * We could probably simplify this a little by putting all those - * different NLM rpc_clients into one single nlm_host object. - * This would allow us to have one nlm_host per address. - */ - chain = &nlm_server_hosts[nlm_hash_address(ni->sap)]; - hlist_for_each_entry(host, pos, chain, h_hash) { - if (!rpc_cmp_addr(nlm_addr(host), ni->sap)) - continue; - - /* See if we have an NSM handle for this client */ - if (!nsm) - nsm = host->h_nsmhandle; - - if (host->h_proto != ni->protocol) - continue; - if (host->h_version != ni->version) - continue; - if (host->h_server != ni->server) - continue; - if (ni->server && ni->src_len != 0 && - !rpc_cmp_addr(nlm_srcaddr(host), ni->src_sap)) - continue; - - /* Move to head of hash chain. */ - hlist_del(&host->h_hash); - hlist_add_head(&host->h_hash, chain); - - nlm_get_host(host); - dprintk("lockd: nlm_lookup_host found host %s (%s)\n", - host->h_name, host->h_addrbuf); - goto out; - } - - host = nlm_alloc_host(ni, nsm); - if (unlikely(host == NULL)) - goto out; - - memcpy(nlm_srcaddr(host), ni->src_sap, ni->src_len); - host->h_srcaddrlen = ni->src_len; - hlist_add_head(&host->h_hash, chain); - - nrhosts++; - - dprintk("lockd: nlm_lookup_host created host %s\n", - host->h_name); - -out: - mutex_unlock(&nlm_host_mutex); - return host; -} - /* * Destroy an nlm_host and free associated resources * -- cgit v1.2.3 From 79691836603541e81a3793970826ac4a75429572 Mon Sep 17 00:00:00 2001 From: Chuck Lever Date: Tue, 14 Dec 2010 15:06:52 +0000 Subject: lockd: Remove src_sap and src_len from nlm_lookup_host_info struct Clean up. The contents of the src_sap field is not used in nlm_alloc_host(). Signed-off-by: Chuck Lever Signed-off-by: Trond Myklebust --- fs/lockd/host.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/fs/lockd/host.c b/fs/lockd/host.c index 6d4aa8b3d610..c106d6a93e5d 100644 --- a/fs/lockd/host.c +++ b/fs/lockd/host.c @@ -53,8 +53,6 @@ struct nlm_lookup_host_info { const u32 version; /* NLM version to search for */ const char *hostname; /* remote's hostname */ const size_t hostname_len; /* it's length */ - const struct sockaddr *src_sap; /* our address (optional) */ - const size_t src_len; /* it's length */ const int noresvport; /* use non-priv port */ }; @@ -324,6 +322,8 @@ struct nlm_host *nlmsvc_lookup_host(const struct svc_rqst *rqstp, struct sockaddr_in6 sin6 = { .sin6_family = AF_INET6, }; + struct sockaddr *src_sap; + size_t src_len = rqstp->rq_addrlen; struct nlm_lookup_host_info ni = { .server = 1, .sap = svc_addr(rqstp), @@ -332,7 +332,6 @@ struct nlm_host *nlmsvc_lookup_host(const struct svc_rqst *rqstp, .version = rqstp->rq_vers, .hostname = hostname, .hostname_len = hostname_len, - .src_len = rqstp->rq_addrlen, }; dprintk("lockd: %s(host='%*s', vers=%u, proto=%s)\n", __func__, @@ -344,11 +343,11 @@ struct nlm_host *nlmsvc_lookup_host(const struct svc_rqst *rqstp, switch (ni.sap->sa_family) { case AF_INET: sin.sin_addr.s_addr = rqstp->rq_daddr.addr.s_addr; - ni.src_sap = (struct sockaddr *)&sin; + src_sap = (struct sockaddr *)&sin; break; case AF_INET6: ipv6_addr_copy(&sin6.sin6_addr, &rqstp->rq_daddr.addr6); - ni.src_sap = (struct sockaddr *)&sin6; + src_sap = (struct sockaddr *)&sin6; break; default: dprintk("lockd: %s failed; unrecognized address family\n", @@ -372,7 +371,7 @@ struct nlm_host *nlmsvc_lookup_host(const struct svc_rqst *rqstp, continue; if (host->h_version != ni.version) continue; - if (!rpc_cmp_addr(nlm_srcaddr(host), ni.src_sap)) + if (!rpc_cmp_addr(nlm_srcaddr(host), src_sap)) continue; /* Move to head of hash chain. */ @@ -389,8 +388,8 @@ struct nlm_host *nlmsvc_lookup_host(const struct svc_rqst *rqstp, if (unlikely(host == NULL)) goto out; - memcpy(nlm_srcaddr(host), ni.src_sap, ni.src_len); - host->h_srcaddrlen = ni.src_len; + memcpy(nlm_srcaddr(host), src_sap, src_len); + host->h_srcaddrlen = src_len; hlist_add_head(&host->h_hash, chain); nrhosts++; -- cgit v1.2.3 From 3be305fd7c0d07cdbb175467b4fe706ea10eb732 Mon Sep 17 00:00:00 2001 From: "L. Alberto Giménez" Date: Tue, 14 Dec 2010 02:01:54 +0100 Subject: Staging: rt2860: include KERN_* in printk MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix checkpatch complains. Signed-off-by: L. Alberto Giménez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rt2860/common/ee_efuse.c | 15 +++++++++++---- drivers/staging/rt2860/pci_main_dev.c | 2 +- drivers/staging/rt2860/rt_linux.c | 21 ++++++++++----------- drivers/staging/rt2860/rt_main_dev.c | 2 +- drivers/staging/rt2860/rt_usb.c | 32 ++++++++++++++++---------------- drivers/staging/rt2860/usb_main_dev.c | 12 ++++++------ 6 files changed, 45 insertions(+), 39 deletions(-) diff --git a/drivers/staging/rt2860/common/ee_efuse.c b/drivers/staging/rt2860/common/ee_efuse.c index 03412f5bc990..fed0ba452271 100644 --- a/drivers/staging/rt2860/common/ee_efuse.c +++ b/drivers/staging/rt2860/common/ee_efuse.c @@ -264,7 +264,7 @@ int set_eFuseGetFreeBlockCount_Proc(struct rt_rtmp_adapter *pAd, char *arg) if (i == EFUSE_USAGE_MAP_END) efusefreenum = 0; } - printk("efuseFreeNumber is %d\n", efusefreenum); + printk(KERN_DEBUG "efuseFreeNumber is %d\n", efusefreenum); return TRUE; } @@ -274,16 +274,23 @@ int set_eFusedump_Proc(struct rt_rtmp_adapter *pAd, char *arg) int i = 0; if (!pAd->bUseEfuse) return FALSE; + + printk(KERN_DEBUG "Block 0: "); + for (i = 0; i < EFUSE_USAGE_MAP_END / 2; i++) { InBuf[0] = 2 * i; InBuf[1] = 2; InBuf[2] = 0x0; eFuseReadPhysical(pAd, &InBuf[0], 4, &InBuf[2], 2); - if (i % 4 == 0) - printk("\nBlock %x:", i / 8); - printk("%04x ", InBuf[2]); + if (i && i % 4 == 0) { + printk(KERN_CONT "\n"); + printk(KERN_DEBUG "Block %x:", i / 8); + } + printk(KERN_CONT "%04x ", InBuf[2]); } + printk(KERN_CONT "\n"); + return TRUE; } diff --git a/drivers/staging/rt2860/pci_main_dev.c b/drivers/staging/rt2860/pci_main_dev.c index cd028e7a8f91..25fbb1880ff2 100644 --- a/drivers/staging/rt2860/pci_main_dev.c +++ b/drivers/staging/rt2860/pci_main_dev.c @@ -203,7 +203,7 @@ static int rt2860_resume(struct pci_dev *pci_dev) /* initialize device before it's used by a driver */ if (pci_enable_device(pci_dev)) { - printk("pci enable fail!\n"); + printk(KERN_ERR "rt2860: pci enable fail!\n"); return 0; } diff --git a/drivers/staging/rt2860/rt_linux.c b/drivers/staging/rt2860/rt_linux.c index 0bbd04a71a6a..728864e18a18 100644 --- a/drivers/staging/rt2860/rt_linux.c +++ b/drivers/staging/rt2860/rt_linux.c @@ -321,7 +321,7 @@ int RTMPCloneNdisPacket(struct rt_rtmp_adapter *pAd, RTMP_SET_PACKET_SOURCE(OSPKT_TO_RTPKT(pkt), PKTSRC_NDIS); - printk("###Clone###\n"); + printk(KERN_DEBUG "###Clone###\n"); return NDIS_STATUS_SUCCESS; } @@ -343,9 +343,8 @@ int RTMPAllocateNdisPacket(struct rt_rtmp_adapter *pAd, RTMP_PKT_TAIL_PADDING); if (pPacket == NULL) { *ppPacket = NULL; -#ifdef DEBUG - printk("RTMPAllocateNdisPacket Fail\n"); -#endif + pr_devel("RTMPAllocateNdisPacket Fail\n"); + return NDIS_STATUS_FAILURE; } /* 2. clone the frame content */ @@ -601,15 +600,15 @@ void hex_dump(char *str, unsigned char *pSrcBufVA, unsigned int SrcBufLen) return; pt = pSrcBufVA; - printk("%s: %p, len = %d\n", str, pSrcBufVA, SrcBufLen); + printk(KERN_DEBUG "%s: %p, len = %d\n", str, pSrcBufVA, SrcBufLen); for (x = 0; x < SrcBufLen; x++) { if (x % 16 == 0) - printk("0x%04x : ", x); - printk("%02x ", ((unsigned char)pt[x])); + printk(KERN_DEBUG "0x%04x : ", x); + printk(KERN_DEBUG "%02x ", ((unsigned char)pt[x])); if (x % 16 == 15) - printk("\n"); + printk(KERN_DEBUG "\n"); } - printk("\n"); + printk(KERN_DEBUG "\n"); } /* @@ -926,7 +925,7 @@ int RtmpOSIRQRequest(struct net_device *pNetDev) request_irq(_pObj->pci_dev->irq, rt2860_interrupt, SA_SHIRQ, (net_dev)->name, (net_dev)); if (retval != 0) - printk("RT2860: request_irq ERROR(%d)\n", retval); + printk(KERN_ERR "rt2860: request_irq ERROR(%d)\n", retval); } return retval; @@ -1022,7 +1021,7 @@ int RtmpOSTaskKill(struct rt_rtmp_os_task *pTask) } #else CHECK_PID_LEGALITY(pTask->taskPID) { - printk("Terminate the task(%s) with pid(%d)!\n", + printk(KERN_INFO "Terminate the task(%s) with pid(%d)!\n", pTask->taskName, GET_PID_NUMBER(pTask->taskPID)); mb(); pTask->task_killed = 1; diff --git a/drivers/staging/rt2860/rt_main_dev.c b/drivers/staging/rt2860/rt_main_dev.c index e8648219e0b5..701561d6b6fd 100644 --- a/drivers/staging/rt2860/rt_main_dev.c +++ b/drivers/staging/rt2860/rt_main_dev.c @@ -421,7 +421,7 @@ int rt28xx_open(struct net_device *dev) { u32 reg = 0; RTMP_IO_READ32(pAd, 0x1300, ®); /* clear garbage interrupts */ - printk("0x1300 = %08x\n", reg); + printk(KERN_DEBUG "0x1300 = %08x\n", reg); } { diff --git a/drivers/staging/rt2860/rt_usb.c b/drivers/staging/rt2860/rt_usb.c index 580a20dd6e9d..eb037d2e04a2 100644 --- a/drivers/staging/rt2860/rt_usb.c +++ b/drivers/staging/rt2860/rt_usb.c @@ -41,25 +41,25 @@ void dump_urb(struct urb *purb) { - printk("urb :0x%08lx\n", (unsigned long)purb); - printk("\tdev :0x%08lx\n", (unsigned long)purb->dev); - printk("\t\tdev->state :0x%d\n", purb->dev->state); - printk("\tpipe :0x%08x\n", purb->pipe); - printk("\tstatus :%d\n", purb->status); - printk("\ttransfer_flags :0x%08x\n", purb->transfer_flags); - printk("\ttransfer_buffer :0x%08lx\n", + printk(KERN_DEBUG "urb :0x%08lx\n", (unsigned long)purb); + printk(KERN_DEBUG "\tdev :0x%08lx\n", (unsigned long)purb->dev); + printk(KERN_DEBUG "\t\tdev->state :0x%d\n", purb->dev->state); + printk(KERN_DEBUG "\tpipe :0x%08x\n", purb->pipe); + printk(KERN_DEBUG "\tstatus :%d\n", purb->status); + printk(KERN_DEBUG "\ttransfer_flags :0x%08x\n", purb->transfer_flags); + printk(KERN_DEBUG "\ttransfer_buffer :0x%08lx\n", (unsigned long)purb->transfer_buffer); - printk("\ttransfer_buffer_length:%d\n", purb->transfer_buffer_length); - printk("\tactual_length :%d\n", purb->actual_length); - printk("\tsetup_packet :0x%08lx\n", + printk(KERN_DEBUG "\ttransfer_buffer_length:%d\n", purb->transfer_buffer_length); + printk(KERN_DEBUG "\tactual_length :%d\n", purb->actual_length); + printk(KERN_DEBUG "\tsetup_packet :0x%08lx\n", (unsigned long)purb->setup_packet); - printk("\tstart_frame :%d\n", purb->start_frame); - printk("\tnumber_of_packets :%d\n", purb->number_of_packets); - printk("\tinterval :%d\n", purb->interval); - printk("\terror_count :%d\n", purb->error_count); - printk("\tcontext :0x%08lx\n", + printk(KERN_DEBUG "\tstart_frame :%d\n", purb->start_frame); + printk(KERN_DEBUG "\tnumber_of_packets :%d\n", purb->number_of_packets); + printk(KERN_DEBUG "\tinterval :%d\n", purb->interval); + printk(KERN_DEBUG "\terror_count :%d\n", purb->error_count); + printk(KERN_DEBUG "\tcontext :0x%08lx\n", (unsigned long)purb->context); - printk("\tcomplete :0x%08lx\n\n", + printk(KERN_DEBUG "\tcomplete :0x%08lx\n\n", (unsigned long)purb->complete); } diff --git a/drivers/staging/rt2860/usb_main_dev.c b/drivers/staging/rt2860/usb_main_dev.c index c8cdbc234eba..ee68d51caa4e 100644 --- a/drivers/staging/rt2860/usb_main_dev.c +++ b/drivers/staging/rt2860/usb_main_dev.c @@ -233,7 +233,7 @@ BOOLEAN RT28XXChipsetCheck(IN void *_dev_p) for (i = 0; i < rtusb_usb_id_len; i++) { if (dev_p->descriptor.idVendor == rtusb_usb_id[i].idVendor && dev_p->descriptor.idProduct == rtusb_usb_id[i].idProduct) { - printk("rt2870: idVendor = 0x%x, idProduct = 0x%x\n", + printk(KERN_INFO "rt2870: idVendor = 0x%x, idProduct = 0x%x\n", dev_p->descriptor.idVendor, dev_p->descriptor.idProduct); break; @@ -241,7 +241,7 @@ BOOLEAN RT28XXChipsetCheck(IN void *_dev_p) } if (i == rtusb_usb_id_len) { - printk("rt2870: Error! Device Descriptor not matching!\n"); + printk(KERN_ERR "rt2870: Error! Device Descriptor not matching!\n"); return FALSE; } @@ -323,7 +323,7 @@ static BOOLEAN USBDevConfigInit(IN struct usb_device *dev, if (!(pAd->BulkInEpAddr && pAd->BulkOutEpAddr[0])) { printk - ("%s: Could not find both bulk-in and bulk-out endpoints\n", + (KERN_ERR "%s: Could not find both bulk-in and bulk-out endpoints\n", __FUNCTION__); return FALSE; } @@ -423,7 +423,7 @@ static int rt2870_resume(struct usb_interface *intf) /* Init driver module */ int __init rtusb_init(void) { - printk("rtusb init --->\n"); + printk(KERN_DEBUG "rtusb init --->\n"); return usb_register(&rtusb_driver); } @@ -431,7 +431,7 @@ int __init rtusb_init(void) void __exit rtusb_exit(void) { usb_deregister(&rtusb_driver); - printk("<--- rtusb exit\n"); + printk(KERN_DEBUG "<--- rtusb exit\n"); } module_init(rtusb_init); @@ -814,7 +814,7 @@ static void rt2870_disconnect(struct usb_device *dev, struct rt_rtmp_adapter *pA dev->bus->bus_name, dev->devpath)); if (!pAd) { usb_put_dev(dev); - printk("rtusb_disconnect: pAd == NULL!\n"); + printk(KERN_ERR "rtusb_disconnect: pAd == NULL!\n"); return; } RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST); -- cgit v1.2.3 From 8c3d90921604951e306a898669c46a88578c5848 Mon Sep 17 00:00:00 2001 From: "L. Alberto Giménez" Date: Tue, 14 Dec 2010 02:01:55 +0100 Subject: Staging: rt2860: Sanitize DBGPRINT_ERR macro MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cleaner implementation. Avoids the need of the double parenthesis to call the macro. Signed-off-by: L. Alberto Giménez Signed-off-by: Greg Kroah-Hartman --- drivers/staging/rt2860/chip/rtmp_phy.h | 14 +++++++------- drivers/staging/rt2860/common/ba_action.c | 6 +++--- drivers/staging/rt2860/common/cmm_data.c | 2 +- drivers/staging/rt2860/common/cmm_mac_pci.c | 10 +++++----- drivers/staging/rt2860/common/cmm_mac_usb.c | 2 +- drivers/staging/rt2860/common/cmm_wpa.c | 22 +++++++++------------- drivers/staging/rt2860/common/mlme.c | 13 ++++++------- drivers/staging/rt2860/common/rt_rf.c | 3 +-- drivers/staging/rt2860/common/rtmp_init.c | 24 ++++++++++-------------- drivers/staging/rt2860/common/rtmp_mcu.c | 4 ++-- drivers/staging/rt2860/common/spectrum.c | 2 +- drivers/staging/rt2860/rt_linux.h | 6 +----- drivers/staging/rt2860/sta/assoc.c | 2 +- drivers/staging/rt2860/sta/auth.c | 3 +-- drivers/staging/rt2860/sta/connect.c | 3 +-- drivers/staging/rt2860/sta/rtmp_data.c | 2 +- drivers/staging/rt2860/sta/sync.c | 6 +++--- 17 files changed, 54 insertions(+), 70 deletions(-) diff --git a/drivers/staging/rt2860/chip/rtmp_phy.h b/drivers/staging/rt2860/chip/rtmp_phy.h index 9f924ea6ca35..98454df30a22 100644 --- a/drivers/staging/rt2860/chip/rtmp_phy.h +++ b/drivers/staging/rt2860/chip/rtmp_phy.h @@ -247,7 +247,7 @@ } \ } \ if (BbpCsr.field.Busy == BUSY) { \ - DBGPRINT_ERR(("BBP(viaMCU=%d) read R%d fail\n", (_bViaMCU), _bbpID)); \ + DBGPRINT_ERR("BBP(viaMCU=%d) read R%d fail\n", (_bViaMCU), _bbpID); \ *(_pV) = (_pAd)->BbpWriteLatch[_bbpID]; \ if ((_bViaMCU) == TRUE) { \ RTMP_IO_READ32(_pAd, _regID, &BbpCsr.word); \ @@ -336,11 +336,11 @@ } \ } \ } else { \ - DBGPRINT_ERR((" , brt30xxBanMcuCmd = %d, Read BBP %d \n", (_A)->brt30xxBanMcuCmd, (_I))); \ + DBGPRINT_ERR(" , brt30xxBanMcuCmd = %d, Read BBP %d \n", (_A)->brt30xxBanMcuCmd, (_I)); \ *(_pV) = (_A)->BbpWriteLatch[_I]; \ } \ if ((BbpCsr.field.Busy == BUSY) || ((_A)->bPCIclkOff == TRUE)) { \ - DBGPRINT_ERR(("BBP read R%d=0x%x fail\n", _I, BbpCsr.word)); \ + DBGPRINT_ERR("BBP read R%d=0x%x fail\n", _I, BbpCsr.word); \ *(_pV) = (_A)->BbpWriteLatch[_I]; \ } \ } @@ -378,7 +378,7 @@ break; \ } \ if (_busyCnt == MAX_BUSY_COUNT) { \ - DBGPRINT_ERR(("BBP write R%d fail\n", _bbpID)); \ + DBGPRINT_ERR("BBP write R%d fail\n", _bbpID); \ if ((_bViaMCU) == TRUE) { \ RTMP_IO_READ32(_pAd, H2M_BBP_AGENT, &BbpCsr.word); \ BbpCsr.field.Busy = 0; \ @@ -459,15 +459,15 @@ break; \ } \ } else { \ - DBGPRINT_ERR((" brt30xxBanMcuCmd = %d. Write BBP %d \n", (_A)->brt30xxBanMcuCmd, (_I))); \ + DBGPRINT_ERR(" brt30xxBanMcuCmd = %d. Write BBP %d \n", (_A)->brt30xxBanMcuCmd, (_I)); \ } \ if ((BusyCnt == MAX_BUSY_COUNT) || ((_A)->bPCIclkOff == TRUE)) { \ if (BusyCnt == MAX_BUSY_COUNT) \ (_A)->AccessBBPFailCount++; \ - DBGPRINT_ERR(("BBP write R%d=0x%x fail. BusyCnt= %d.bPCIclkOff = %d. \n", _I, BbpCsr.word, BusyCnt, (_A)->bPCIclkOff)); \ + DBGPRINT_ERR("BBP write R%d=0x%x fail. BusyCnt= %d.bPCIclkOff = %d. \n", _I, BbpCsr.word, BusyCnt, (_A)->bPCIclkOff); \ } \ } else { \ - DBGPRINT_ERR(("****** BBP_Write_Latch Buffer exceeds max boundry ****** \n")); \ + DBGPRINT_ERR("****** BBP_Write_Latch Buffer exceeds max boundry ****** \n"); \ } \ } #endif /* RTMP_MAC_PCI // */ diff --git a/drivers/staging/rt2860/common/ba_action.c b/drivers/staging/rt2860/common/ba_action.c index ed8854b902d1..b046c2b814c5 100644 --- a/drivers/staging/rt2860/common/ba_action.c +++ b/drivers/staging/rt2860/common/ba_action.c @@ -1270,13 +1270,13 @@ BOOLEAN CntlEnqueueForRecv(struct rt_rtmp_adapter *pAd, /* First check the size, it MUST not exceed the mlme queue size */ if (MsgLen > MGMT_DMA_BUFFER_SIZE) { - DBGPRINT_ERR(("CntlEnqueueForRecv: frame too large, size = %ld \n", MsgLen)); + DBGPRINT_ERR("CntlEnqueueForRecv: frame too large, size = %ld \n", MsgLen); return FALSE; } else if (MsgLen != sizeof(struct rt_frame_ba_req)) { - DBGPRINT_ERR(("CntlEnqueueForRecv: BlockAck Request frame length size = %ld incorrect\n", MsgLen)); + DBGPRINT_ERR("CntlEnqueueForRecv: BlockAck Request frame length size = %ld incorrect\n", MsgLen); return FALSE; } else if (MsgLen != sizeof(struct rt_frame_ba_req)) { - DBGPRINT_ERR(("CntlEnqueueForRecv: BlockAck Request frame length size = %ld incorrect\n", MsgLen)); + DBGPRINT_ERR("CntlEnqueueForRecv: BlockAck Request frame length size = %ld incorrect\n", MsgLen); return FALSE; } diff --git a/drivers/staging/rt2860/common/cmm_data.c b/drivers/staging/rt2860/common/cmm_data.c index 93a53479d766..2204c2bda386 100644 --- a/drivers/staging/rt2860/common/cmm_data.c +++ b/drivers/staging/rt2860/common/cmm_data.c @@ -1366,7 +1366,7 @@ void RTMPResumeMsduTransmission(struct rt_rtmp_adapter *pAd) /* R66 should not be 0 */ if (pAd->BbpTuning.R66CurrentValue == 0) { pAd->BbpTuning.R66CurrentValue = 0x38; - DBGPRINT_ERR(("RTMPResumeMsduTransmission, R66CurrentValue=0...\n")); + DBGPRINT_ERR("RTMPResumeMsduTransmission, R66CurrentValue=0...\n"); } RTMP_BBP_IO_WRITE8_BY_REG_ID(pAd, BBP_R66, diff --git a/drivers/staging/rt2860/common/cmm_mac_pci.c b/drivers/staging/rt2860/common/cmm_mac_pci.c index e26ba4942877..850f0fbc6d90 100644 --- a/drivers/staging/rt2860/common/cmm_mac_pci.c +++ b/drivers/staging/rt2860/common/cmm_mac_pci.c @@ -89,7 +89,7 @@ int RTMPAllocTxRxRingMemory(struct rt_rtmp_adapter *pAd) if (pAd->TxDescRing[num].AllocVa == NULL) { ErrorValue = ERRLOG_OUT_OF_SHARED_MEMORY; - DBGPRINT_ERR(("Failed to allocate a big buffer\n")); + DBGPRINT_ERR("Failed to allocate a big buffer\n"); Status = NDIS_STATUS_RESOURCES; break; } @@ -121,7 +121,7 @@ int RTMPAllocTxRxRingMemory(struct rt_rtmp_adapter *pAd) if (pAd->TxBufSpace[num].AllocVa == NULL) { ErrorValue = ERRLOG_OUT_OF_SHARED_MEMORY; - DBGPRINT_ERR(("Failed to allocate a big buffer\n")); + DBGPRINT_ERR("Failed to allocate a big buffer\n"); Status = NDIS_STATUS_RESOURCES; break; } @@ -197,7 +197,7 @@ int RTMPAllocTxRxRingMemory(struct rt_rtmp_adapter *pAd) if (pAd->MgmtDescRing.AllocVa == NULL) { ErrorValue = ERRLOG_OUT_OF_SHARED_MEMORY; - DBGPRINT_ERR(("Failed to allocate a big buffer\n")); + DBGPRINT_ERR("Failed to allocate a big buffer\n"); Status = NDIS_STATUS_RESOURCES; break; } @@ -251,7 +251,7 @@ int RTMPAllocTxRxRingMemory(struct rt_rtmp_adapter *pAd) if (pAd->RxDescRing.AllocVa == NULL) { ErrorValue = ERRLOG_OUT_OF_SHARED_MEMORY; - DBGPRINT_ERR(("Failed to allocate a big buffer\n")); + DBGPRINT_ERR("Failed to allocate a big buffer\n"); Status = NDIS_STATUS_RESOURCES; break; } @@ -304,7 +304,7 @@ int RTMPAllocTxRxRingMemory(struct rt_rtmp_adapter *pAd) /* Error handling */ if (pDmaBuf->AllocVa == NULL) { ErrorValue = ERRLOG_OUT_OF_SHARED_MEMORY; - DBGPRINT_ERR(("Failed to allocate RxRing's 1st buffer\n")); + DBGPRINT_ERR("Failed to allocate RxRing's 1st buffer\n"); Status = NDIS_STATUS_RESOURCES; break; } diff --git a/drivers/staging/rt2860/common/cmm_mac_usb.c b/drivers/staging/rt2860/common/cmm_mac_usb.c index 72731cbb81df..64a65a460c29 100644 --- a/drivers/staging/rt2860/common/cmm_mac_usb.c +++ b/drivers/staging/rt2860/common/cmm_mac_usb.c @@ -236,7 +236,7 @@ int NICInitTransmit(struct rt_rtmp_adapter *pAd) os_alloc_mem(pAd, (u8 **) (&pAd->MgmtDescRing.AllocVa), pAd->MgmtDescRing.AllocSize); if (pAd->MgmtDescRing.AllocVa == NULL) { - DBGPRINT_ERR(("Failed to allocate a big buffer for MgmtDescRing!\n")); + DBGPRINT_ERR("Failed to allocate a big buffer for MgmtDescRing!\n"); Status = NDIS_STATUS_RESOURCES; goto out1; } diff --git a/drivers/staging/rt2860/common/cmm_wpa.c b/drivers/staging/rt2860/common/cmm_wpa.c index e37b64b6a608..0040f45b629b 100644 --- a/drivers/staging/rt2860/common/cmm_wpa.c +++ b/drivers/staging/rt2860/common/cmm_wpa.c @@ -2794,7 +2794,7 @@ u8 *GetSuiteFromRSNIE(u8 *rsnie, /* Check length */ if ((len <= 0) || (pEid->Len != len)) { - DBGPRINT_ERR(("%s : The length is invalid\n", __func__)); + DBGPRINT_ERR("%s : The length is invalid\n", __func__); return NULL; } /* Check WPA or WPA2 */ @@ -2803,14 +2803,13 @@ u8 *GetSuiteFromRSNIE(u8 *rsnie, u16 ucount; if (len < sizeof(struct rt_rsnie)) { - DBGPRINT_ERR(("%s : The length is too short for WPA\n", - __func__)); + DBGPRINT_ERR("%s : The length is too short for WPA\n", __func__); return NULL; } /* Get the count of pairwise cipher */ ucount = cpu2le16(pRsnie->ucount); if (ucount > 2) { - DBGPRINT_ERR(("%s : The count(%d) of pairwise cipher is invlaid\n", __func__, ucount)); + DBGPRINT_ERR("%s : The count(%d) of pairwise cipher is invlaid\n", __func__, ucount); return NULL; } /* Get the group cipher */ @@ -2836,14 +2835,13 @@ u8 *GetSuiteFromRSNIE(u8 *rsnie, isWPA2 = TRUE; if (len < sizeof(struct rt_rsnie2)) { - DBGPRINT_ERR(("%s : The length is too short for WPA2\n", - __func__)); + DBGPRINT_ERR("%s : The length is too short for WPA2\n", __func__); return NULL; } /* Get the count of pairwise cipher */ ucount = cpu2le16(pRsnie->ucount); if (ucount > 2) { - DBGPRINT_ERR(("%s : The count(%d) of pairwise cipher is invlaid\n", __func__, ucount)); + DBGPRINT_ERR("%s : The count(%d) of pairwise cipher is invlaid\n", __func__, ucount); return NULL; } /* Get the group cipher */ @@ -2863,7 +2861,7 @@ u8 *GetSuiteFromRSNIE(u8 *rsnie, offset = sizeof(struct rt_rsnie2) + (4 * (ucount - 1)); } else { - DBGPRINT_ERR(("%s : Unknown IE (%d)\n", __func__, pEid->Eid)); + DBGPRINT_ERR("%s : Unknown IE (%d)\n", __func__, pEid->Eid); return NULL; } @@ -2872,8 +2870,7 @@ u8 *GetSuiteFromRSNIE(u8 *rsnie, len -= offset; if (len < sizeof(struct rt_rsnie_auth)) { - DBGPRINT_ERR(("%s : The length of RSNIE is too short\n", - __func__)); + DBGPRINT_ERR("%s : The length of RSNIE is too short\n", __func__); return NULL; } /* pointer to AKM count */ @@ -2882,8 +2879,7 @@ u8 *GetSuiteFromRSNIE(u8 *rsnie, /* Get the count of pairwise cipher */ acount = cpu2le16(pAkm->acount); if (acount > 2) { - DBGPRINT_ERR(("%s : The count(%d) of AKM is invlaid\n", - __func__, acount)); + DBGPRINT_ERR("%s : The count(%d) of AKM is invlaid\n", __func__, acount); return NULL; } /* Get the AKM suite */ @@ -2910,7 +2906,7 @@ u8 *GetSuiteFromRSNIE(u8 *rsnie, return pBuf; } } else { - DBGPRINT_ERR(("%s : it can't get any more information beyond AKM \n", __func__)); + DBGPRINT_ERR("%s : it can't get any more information beyond AKM \n", __func__); return NULL; } diff --git a/drivers/staging/rt2860/common/mlme.c b/drivers/staging/rt2860/common/mlme.c index 7300c6e9c175..d9c3fd5c2166 100644 --- a/drivers/staging/rt2860/common/mlme.c +++ b/drivers/staging/rt2860/common/mlme.c @@ -550,7 +550,7 @@ void MlmeHandler(struct rt_rtmp_adapter *pAd) Elem->MsgLen = 0; } else { - DBGPRINT_ERR(("MlmeHandler: MlmeQueue empty\n")); + DBGPRINT_ERR("MlmeHandler: MlmeQueue empty\n"); } } @@ -4698,8 +4698,7 @@ BOOLEAN MlmeEnqueue(struct rt_rtmp_adapter *pAd, /* First check the size, it MUST not exceed the mlme queue size */ if (MsgLen > MGMT_DMA_BUFFER_SIZE) { - DBGPRINT_ERR(("MlmeEnqueue: msg too large, size = %ld \n", - MsgLen)); + DBGPRINT_ERR("MlmeEnqueue: msg too large, size = %ld \n", MsgLen); return FALSE; } @@ -4762,12 +4761,12 @@ BOOLEAN MlmeEnqueueForRecv(struct rt_rtmp_adapter *pAd, if (RTMP_TEST_FLAG (pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST)) { - DBGPRINT_ERR(("MlmeEnqueueForRecv: fRTMP_ADAPTER_HALT_IN_PROGRESS\n")); + DBGPRINT_ERR("MlmeEnqueueForRecv: fRTMP_ADAPTER_HALT_IN_PROGRESS\n"); return FALSE; } /* First check the size, it MUST not exceed the mlme queue size */ if (MsgLen > MGMT_DMA_BUFFER_SIZE) { - DBGPRINT_ERR(("MlmeEnqueueForRecv: frame too large, size = %ld \n", MsgLen)); + DBGPRINT_ERR("MlmeEnqueueForRecv: frame too large, size = %ld \n", MsgLen); return FALSE; } @@ -4777,7 +4776,7 @@ BOOLEAN MlmeEnqueueForRecv(struct rt_rtmp_adapter *pAd, { if (!MsgTypeSubst(pAd, pFrame, &Machine, &MsgType)) { - DBGPRINT_ERR(("MlmeEnqueueForRecv: un-recongnized mgmt->subtype=%d\n", pFrame->Hdr.FC.SubType)); + DBGPRINT_ERR("MlmeEnqueueForRecv: un-recongnized mgmt->subtype=%d\n", pFrame->Hdr.FC.SubType); return FALSE; } } @@ -4867,7 +4866,7 @@ void MlmeRestartStateMachine(struct rt_rtmp_adapter *pAd) Elem->MsgLen = 0; } else { - DBGPRINT_ERR(("MlmeRestartStateMachine: MlmeQueue empty\n")); + DBGPRINT_ERR("MlmeRestartStateMachine: MlmeQueue empty\n"); } } #endif /* RTMP_MAC_PCI // */ diff --git a/drivers/staging/rt2860/common/rt_rf.c b/drivers/staging/rt2860/common/rt_rf.c index 519121d81040..2895447ffc48 100644 --- a/drivers/staging/rt2860/common/rt_rf.c +++ b/drivers/staging/rt2860/common/rt_rf.c @@ -131,8 +131,7 @@ int RT30xxReadRFRegister(struct rt_rtmp_adapter *pAd, } } if (rfcsr.field.RF_CSR_KICK == BUSY) { - DBGPRINT_ERR(("RF read R%d=0x%x fail, i[%d], k[%d]\n", regID, - rfcsr.word, i, k)); + DBGPRINT_ERR("RF read R%d=0x%x fail, i[%d], k[%d]\n", regID, rfcsr.word, i, k); return STATUS_UNSUCCESSFUL; } diff --git a/drivers/staging/rt2860/common/rtmp_init.c b/drivers/staging/rt2860/common/rtmp_init.c index 3628e85802e3..d359a14f5d4d 100644 --- a/drivers/staging/rt2860/common/rtmp_init.c +++ b/drivers/staging/rt2860/common/rtmp_init.c @@ -169,14 +169,14 @@ int RTMPAllocAdapterBlock(void *handle, pBeaconBuf = kmalloc(MAX_BEACON_SIZE, MEM_ALLOC_FLAG); if (pBeaconBuf == NULL) { Status = NDIS_STATUS_FAILURE; - DBGPRINT_ERR(("Failed to allocate memory - BeaconBuf!\n")); + DBGPRINT_ERR("Failed to allocate memory - BeaconBuf!\n"); break; } NdisZeroMemory(pBeaconBuf, MAX_BEACON_SIZE); Status = AdapterBlockAllocateMemory(handle, (void **) & pAd); if (Status != NDIS_STATUS_SUCCESS) { - DBGPRINT_ERR(("Failed to allocate memory - ADAPTER\n")); + DBGPRINT_ERR("Failed to allocate memory - ADAPTER\n"); break; } pAd->BeaconBuf = pBeaconBuf; @@ -785,8 +785,7 @@ void NICReadEEPROMParameters(struct rt_rtmp_adapter *pAd, u8 *mac_addr) Version.field.Version, Version.field.FaeReleaseNumber)); if (Version.field.Version > VALID_EEPROM_VERSION) { - DBGPRINT_ERR(("E2PROM: WRONG VERSION 0x%x, should be %d\n", - Version.field.Version, VALID_EEPROM_VERSION)); + DBGPRINT_ERR("E2PROM: WRONG VERSION 0x%x, should be %d\n", Version.field.Version, VALID_EEPROM_VERSION); /*pAd->SystemErrorBitmap |= 0x00000001; // hard-code default value when no proper E2PROM installed @@ -2911,7 +2910,7 @@ void RTMPSetTimer(struct rt_ralink_timer *pTimer, unsigned long Value) RTMP_OS_Add_Timer(&pTimer->TimerObj, Value); } } else { - DBGPRINT_ERR(("RTMPSetTimer failed, Timer hasn't been initialize!\n")); + DBGPRINT_ERR("RTMPSetTimer failed, Timer hasn't been initialize!\n"); } } @@ -2947,7 +2946,7 @@ void RTMPModTimer(struct rt_ralink_timer *pTimer, unsigned long Value) RTMP_OS_Mod_Timer(&pTimer->TimerObj, Value); } } else { - DBGPRINT_ERR(("RTMPModTimer failed, Timer hasn't been initialize!\n")); + DBGPRINT_ERR("RTMPModTimer failed, Timer hasn't been initialize!\n"); } } @@ -2989,7 +2988,7 @@ void RTMPCancelTimer(struct rt_ralink_timer *pTimer, OUT BOOLEAN * pCancelled) RtmpTimerQRemove(pTimer->pAd, pTimer); #endif /* RTMP_TIMER_TASK_SUPPORT // */ } else { - DBGPRINT_ERR(("RTMPCancelTimer failed, Timer hasn't been initialize!\n")); + DBGPRINT_ERR("RTMPCancelTimer failed, Timer hasn't been initialize!\n"); } } @@ -3251,8 +3250,7 @@ int rt28xx_init(struct rt_rtmp_adapter *pAd, /* Load 8051 firmware */ Status = NICLoadFirmware(pAd); if (Status != NDIS_STATUS_SUCCESS) { - DBGPRINT_ERR(("NICLoadFirmware failed, Status[=0x%08x]\n", - Status)); + DBGPRINT_ERR("NICLoadFirmware failed, Status[=0x%08x]\n", Status); goto err1; } @@ -3268,8 +3266,7 @@ int rt28xx_init(struct rt_rtmp_adapter *pAd, Status = RTMPAllocTxRxRingMemory(pAd); if (Status != NDIS_STATUS_SUCCESS) { - DBGPRINT_ERR(("RTMPAllocDMAMemory failed, Status[=0x%08x]\n", - Status)); + DBGPRINT_ERR("RTMPAllocDMAMemory failed, Status[=0x%08x]\n", Status); goto err1; } @@ -3284,7 +3281,7 @@ int rt28xx_init(struct rt_rtmp_adapter *pAd, Status = MlmeInit(pAd); if (Status != NDIS_STATUS_SUCCESS) { - DBGPRINT_ERR(("MlmeInit failed, Status[=0x%08x]\n", Status)); + DBGPRINT_ERR("MlmeInit failed, Status[=0x%08x]\n", Status); goto err2; } /* Initialize pAd->StaCfg, pAd->ApCfg, pAd->CommonCfg to manufacture default */ @@ -3309,8 +3306,7 @@ int rt28xx_init(struct rt_rtmp_adapter *pAd, /* */ Status = NICInitializeAdapter(pAd, TRUE); if (Status != NDIS_STATUS_SUCCESS) { - DBGPRINT_ERR(("NICInitializeAdapter failed, Status[=0x%08x]\n", - Status)); + DBGPRINT_ERR("NICInitializeAdapter failed, Status[=0x%08x]\n", Status); if (Status != NDIS_STATUS_SUCCESS) goto err3; } diff --git a/drivers/staging/rt2860/common/rtmp_mcu.c b/drivers/staging/rt2860/common/rtmp_mcu.c index 844d4b987b78..80fa4160ed62 100644 --- a/drivers/staging/rt2860/common/rtmp_mcu.c +++ b/drivers/staging/rt2860/common/rtmp_mcu.c @@ -267,7 +267,7 @@ int RtmpAsicSendCommandToMcu(struct rt_rtmp_adapter *pAd, } while (i++ < 100); if (i > 100) { - DBGPRINT_ERR(("H2M_MAILBOX still hold by MCU. command fail\n")); + DBGPRINT_ERR("H2M_MAILBOX still hold by MCU. command fail\n"); return FALSE; } @@ -296,7 +296,7 @@ int RtmpAsicSendCommandToMcu(struct rt_rtmp_adapter *pAd, #ifdef RTMP_MAC_PCI #endif /* RTMP_MAC_PCI // */ { - DBGPRINT_ERR(("H2M_MAILBOX still hold by MCU. command fail\n")); + DBGPRINT_ERR("H2M_MAILBOX still hold by MCU. command fail\n"); } return FALSE; } diff --git a/drivers/staging/rt2860/common/spectrum.c b/drivers/staging/rt2860/common/spectrum.c index 2d5f847e6cc6..1dfb802aab9a 100644 --- a/drivers/staging/rt2860/common/spectrum.c +++ b/drivers/staging/rt2860/common/spectrum.c @@ -1837,7 +1837,7 @@ static void PeerChSwAnnAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_ } if (index >= pAd->ChannelListNum) { - DBGPRINT_ERR(("&&&&&&&&&&&&&&&&&&&&&&&&&&PeerChSwAnnAction(can not find New Channel=%d in ChannelList[%d]\n", pAd->CommonCfg.Channel, pAd->ChannelListNum)); + DBGPRINT_ERR("&&&&&&&&&&&&&&&&&&&&&&&&&&PeerChSwAnnAction(can not find New Channel=%d in ChannelList[%d]\n", pAd->CommonCfg.Channel, pAd->ChannelListNum); } } } diff --git a/drivers/staging/rt2860/rt_linux.h b/drivers/staging/rt2860/rt_linux.h index a449b0bb85f1..92ff5438e777 100644 --- a/drivers/staging/rt2860/rt_linux.h +++ b/drivers/staging/rt2860/rt_linux.h @@ -423,11 +423,7 @@ do{ \ #define DBGPRINT(Level, Fmt) DBGPRINT_RAW(Level, Fmt) -#define DBGPRINT_ERR(Fmt) \ -{ \ - printk("ERROR! "); \ - printk Fmt; \ -} +#define DBGPRINT_ERR(fmt, args...) printk(KERN_ERR fmt, ##args) #define DBGPRINT_S(Status, Fmt) \ { \ diff --git a/drivers/staging/rt2860/sta/assoc.c b/drivers/staging/rt2860/sta/assoc.c index ab0a83bf76ef..59e931c3190d 100644 --- a/drivers/staging/rt2860/sta/assoc.c +++ b/drivers/staging/rt2860/sta/assoc.c @@ -1055,7 +1055,7 @@ void AssocPostProc(struct rt_rtmp_adapter *pAd, u8 *pAddr2, u16 CapabilityInfo, /* Set New WPA information */ Idx = BssTableSearch(&pAd->ScanTab, pAddr2, pAd->MlmeAux.Channel); if (Idx == BSS_NOT_FOUND) { - DBGPRINT_ERR(("ASSOC - Can't find BSS after receiving Assoc response\n")); + DBGPRINT_ERR("ASSOC - Can't find BSS after receiving Assoc response\n"); } else { /* Init variable */ pAd->MacTab.Content[BSSID_WCID].RSNIE_Len = 0; diff --git a/drivers/staging/rt2860/sta/auth.c b/drivers/staging/rt2860/sta/auth.c index a2bfafddb20e..23ea00b896b0 100644 --- a/drivers/staging/rt2860/sta/auth.c +++ b/drivers/staging/rt2860/sta/auth.c @@ -509,8 +509,7 @@ BOOLEAN AUTH_ReqSend(struct rt_rtmp_adapter *pAd, RTMPSetTimer(pAuthTimer, Timeout); return TRUE; } else { - DBGPRINT_ERR(("%s - MlmeAuthReqAction() sanity check failed\n", - pSMName)); + DBGPRINT_ERR("%s - MlmeAuthReqAction() sanity check failed\n", pSMName); return FALSE; } diff --git a/drivers/staging/rt2860/sta/connect.c b/drivers/staging/rt2860/sta/connect.c index 4b2c84e6509e..4996258f6ecd 100644 --- a/drivers/staging/rt2860/sta/connect.c +++ b/drivers/staging/rt2860/sta/connect.c @@ -215,8 +215,7 @@ void MlmeCntlMachinePerformAction(struct rt_rtmp_adapter *pAd, break; #endif /* RTMP_MAC_USB // */ default: - DBGPRINT_ERR(("ERROR! CNTL - Illegal message type(=%ld)", - Elem->MsgType)); + DBGPRINT_ERR("ERROR! CNTL - Illegal message type(=%ld)", Elem->MsgType); break; } } diff --git a/drivers/staging/rt2860/sta/rtmp_data.c b/drivers/staging/rt2860/sta/rtmp_data.c index d7c2012be8a5..e82c6b669eb2 100644 --- a/drivers/staging/rt2860/sta/rtmp_data.c +++ b/drivers/staging/rt2860/sta/rtmp_data.c @@ -645,7 +645,7 @@ void STAHandleRxMgmtFrame(struct rt_rtmp_adapter *pAd, struct rt_rx_blk *pRxBlk) /* First check the size, it MUST not exceed the mlme queue size */ if (pRxWI->MPDUtotalByteCount > MGMT_DMA_BUFFER_SIZE) { - DBGPRINT_ERR(("STAHandleRxMgmtFrame: frame too large, size = %d \n", pRxWI->MPDUtotalByteCount)); + DBGPRINT_ERR("STAHandleRxMgmtFrame: frame too large, size = %d \n", pRxWI->MPDUtotalByteCount); break; } diff --git a/drivers/staging/rt2860/sta/sync.c b/drivers/staging/rt2860/sta/sync.c index 05007d9c9b69..7054ba1323d0 100644 --- a/drivers/staging/rt2860/sta/sync.c +++ b/drivers/staging/rt2860/sta/sync.c @@ -284,7 +284,7 @@ void MlmeScanReqAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *E DBGPRINT(RT_DEBUG_TRACE, ("SYNC - BBP R4 to 20MHz.l\n")); ScanNextChannel(pAd); } else { - DBGPRINT_ERR(("SYNC - MlmeScanReqAction() sanity check fail\n")); + DBGPRINT_ERR("SYNC - MlmeScanReqAction() sanity check fail\n"); pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE; Status = MLME_INVALID_FORMAT; MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_SCAN_CONF, 2, @@ -536,7 +536,7 @@ void MlmeStartReqAction(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem * MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_START_CONF, 2, &Status); } else { - DBGPRINT_ERR(("SYNC - MlmeStartReqAction() sanity check fail.\n")); + DBGPRINT_ERR("SYNC - MlmeStartReqAction() sanity check fail.\n"); pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE; Status = MLME_INVALID_FORMAT; MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, MT2_START_CONF, 2, @@ -1208,7 +1208,7 @@ void PeerBeacon(struct rt_rtmp_adapter *pAd, struct rt_mlme_queue_elem *Elem) } if (index >= pAd->ChannelListNum) { - DBGPRINT_ERR(("PeerBeacon(can not find New Channel=%d in ChannelList[%d]\n", pAd->CommonCfg.Channel, pAd->ChannelListNum)); + DBGPRINT_ERR("PeerBeacon(can not find New Channel=%d in ChannelList[%d]\n", pAd->CommonCfg.Channel, pAd->ChannelListNum); } } /* if the ssid matched & bssid unmatched, we should select the bssid with large value. */ -- cgit v1.2.3 From dab56ffe9acc59a6cbe8f857a95adf75f42970b9 Mon Sep 17 00:00:00 2001 From: Marek Belisko Date: Tue, 14 Dec 2010 09:42:27 +0100 Subject: staging: ft1000: Fix camelcase function names. Signed-off-by: Marek Belisko Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ft1000/ft1000-usb/ft1000_proc.c | 4 ++-- drivers/staging/ft1000/ft1000-usb/ft1000_usb.c | 4 ++-- drivers/staging/ft1000/ft1000-usb/ft1000_usb.h | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_proc.c b/drivers/staging/ft1000/ft1000-usb/ft1000_proc.c index 0f271c281b85..b87542abbe86 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_proc.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_proc.c @@ -201,7 +201,7 @@ static struct notifier_block ft1000_netdev_notifier = { }; -int ft1000InitProc(struct net_device *dev) +int ft1000_init_proc(struct net_device *dev) { struct ft1000_info *info; struct proc_dir_entry *ft1000_proc_file; @@ -243,7 +243,7 @@ fail: return ret; } -void ft1000CleanupProc(struct ft1000_info *info) +void ft1000_cleanup_proc(struct ft1000_info *info) { remove_proc_entry(info->netdevname, info->ft1000_proc_dir); remove_proc_entry(FT1000_PROC_DIR, FTNET_PROC); diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_usb.c b/drivers/staging/ft1000/ft1000-usb/ft1000_usb.c index 0e1fc3f1e055..79482ac1c489 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_usb.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_usb.c @@ -198,7 +198,7 @@ static int ft1000_probe(struct usb_interface *interface, if (ret) goto err_thread; - ret = ft1000InitProc(ft1000dev->net); + ret = ft1000_init_proc(ft1000dev->net); if (ret) goto err_proc; @@ -228,7 +228,7 @@ static void ft1000_disconnect(struct usb_interface *interface) DEBUG("In disconnect pft1000info=%p\n", pft1000info); if (pft1000info) { - ft1000CleanupProc(pft1000info); + ft1000_cleanup_proc(pft1000info); if (pft1000info->pPollThread) kthread_stop(pft1000info->pPollThread); diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_usb.h b/drivers/staging/ft1000/ft1000-usb/ft1000_usb.h index 4a91469e64ff..a143e9ca4f08 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_usb.h +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_usb.h @@ -594,8 +594,8 @@ struct usb_interface; int reg_ft1000_netdev(struct ft1000_device *ft1000dev, struct usb_interface *intf); int ft1000_poll(void* dev_id); -int ft1000InitProc(struct net_device *dev); -void ft1000CleanupProc(struct ft1000_info *info); +int ft1000_init_proc(struct net_device *dev); +void ft1000_cleanup_proc(struct ft1000_info *info); -- cgit v1.2.3 From c346541f3d8c6e90b6aadc0511c27a6de15fdee5 Mon Sep 17 00:00:00 2001 From: Marek Belisko Date: Tue, 14 Dec 2010 09:42:28 +0100 Subject: staging: ft1000: Rename ft1000_chdev.c to ft1000_debug.c. Name of old file was misleading because it is currently updated to debugfs so change also file name. Signed-off-by: Marek Belisko Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ft1000/ft1000-usb/Makefile | 2 +- drivers/staging/ft1000/ft1000-usb/ft1000_chdev.c | 784 ----------------------- drivers/staging/ft1000/ft1000-usb/ft1000_debug.c | 784 +++++++++++++++++++++++ 3 files changed, 785 insertions(+), 785 deletions(-) delete mode 100644 drivers/staging/ft1000/ft1000-usb/ft1000_chdev.c create mode 100644 drivers/staging/ft1000/ft1000-usb/ft1000_debug.c diff --git a/drivers/staging/ft1000/ft1000-usb/Makefile b/drivers/staging/ft1000/ft1000-usb/Makefile index dd87ecd7918e..f0f524015888 100644 --- a/drivers/staging/ft1000/ft1000-usb/Makefile +++ b/drivers/staging/ft1000/ft1000-usb/Makefile @@ -1,3 +1,3 @@ obj-$(CONFIG_FT1000_USB) += ft1000.o -ft1000-y := ft1000_chdev.o ft1000_download.o ft1000_hw.o ft1000_proc.o ft1000_usb.o +ft1000-y := ft1000_debug.o ft1000_download.o ft1000_hw.o ft1000_proc.o ft1000_usb.o diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_chdev.c b/drivers/staging/ft1000/ft1000-usb/ft1000_chdev.c deleted file mode 100644 index e39809229d46..000000000000 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_chdev.c +++ /dev/null @@ -1,784 +0,0 @@ -//--------------------------------------------------------------------------- -// FT1000 driver for Flarion Flash OFDM NIC Device -// -// Copyright (C) 2006 Flarion Technologies, All rights reserved. -// -// 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. 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. You should have received a copy of the GNU General Public -// License along with this program; if not, write to the -// Free Software Foundation, Inc., 59 Temple Place - -// Suite 330, Boston, MA 02111-1307, USA. -//--------------------------------------------------------------------------- -// -// File: ft1000_chdev.c -// -// Description: Custom character device dispatch routines. -// -// History: -// 8/29/02 Whc Ported to Linux. -// 6/05/06 Whc Porting to Linux 2.6.9 -// -//--------------------------------------------------------------------------- -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include "ft1000_usb.h" - -static int ft1000_flarion_cnt = 0; - -static int ft1000_open (struct inode *inode, struct file *file); -static unsigned int ft1000_poll_dev(struct file *file, poll_table *wait); -static long ft1000_ioctl(struct file *file, unsigned int command, - unsigned long argument); -static int ft1000_release (struct inode *inode, struct file *file); - -// List to free receive command buffer pool -struct list_head freercvpool; - -// lock to arbitrate free buffer list for receive command data -spinlock_t free_buff_lock; - -int numofmsgbuf = 0; - -// -// Table of entry-point routines for char device -// -static struct file_operations ft1000fops = -{ - .unlocked_ioctl = ft1000_ioctl, - .poll = ft1000_poll_dev, - .open = ft1000_open, - .release = ft1000_release, - .llseek = no_llseek, -}; - -//--------------------------------------------------------------------------- -// Function: ft1000_get_buffer -// -// Parameters: -// -// Returns: -// -// Description: -// -// Notes: -// -//--------------------------------------------------------------------------- -struct dpram_blk *ft1000_get_buffer(struct list_head *bufflist) -{ - unsigned long flags; - struct dpram_blk *ptr; - - spin_lock_irqsave(&free_buff_lock, flags); - // Check if buffer is available - if ( list_empty(bufflist) ) { - DEBUG("ft1000_get_buffer: No more buffer - %d\n", numofmsgbuf); - ptr = NULL; - } - else { - numofmsgbuf--; - ptr = list_entry(bufflist->next, struct dpram_blk, list); - list_del(&ptr->list); - //DEBUG("ft1000_get_buffer: number of free msg buffers = %d\n", numofmsgbuf); - } - spin_unlock_irqrestore(&free_buff_lock, flags); - - return ptr; -} - - - - -//--------------------------------------------------------------------------- -// Function: ft1000_free_buffer -// -// Parameters: -// -// Returns: -// -// Description: -// -// Notes: -// -//--------------------------------------------------------------------------- -void ft1000_free_buffer(struct dpram_blk *pdpram_blk, struct list_head *plist) -{ - unsigned long flags; - - spin_lock_irqsave(&free_buff_lock, flags); - // Put memory back to list - list_add_tail(&pdpram_blk->list, plist); - numofmsgbuf++; - //DEBUG("ft1000_free_buffer: number of free msg buffers = %d\n", numofmsgbuf); - spin_unlock_irqrestore(&free_buff_lock, flags); -} - -//--------------------------------------------------------------------------- -// Function: ft1000_CreateDevice -// -// Parameters: dev - pointer to adapter object -// -// Returns: 0 if successful -// -// Description: Creates a private char device. -// -// Notes: Only called by init_module(). -// -//--------------------------------------------------------------------------- -int ft1000_create_dev(struct ft1000_device *dev) -{ - struct ft1000_info *info = netdev_priv(dev->net); - int result; - int i; - struct dentry *dir, *file; - struct ft1000_debug_dirs *tmp; - - // make a new device name - sprintf(info->DeviceName, "%s%d", "FT1000_", info->CardNumber); - - DEBUG("%s: number of instance = %d\n", __func__, ft1000_flarion_cnt); - DEBUG("DeviceCreated = %x\n", info->DeviceCreated); - - if (info->DeviceCreated) - { - DEBUG("%s: \"%s\" already registered\n", __func__, info->DeviceName); - return -EIO; - } - - - // register the device - DEBUG("%s: \"%s\" debugfs device registration\n", __func__, info->DeviceName); - - tmp = kmalloc(sizeof(struct ft1000_debug_dirs), GFP_KERNEL); - if (tmp == NULL) { - result = -1; - goto fail; - } - - dir = debugfs_create_dir(info->DeviceName, 0); - if (IS_ERR(dir)) { - result = PTR_ERR(dir); - goto debug_dir_fail; - } - - file = debugfs_create_file("device", S_IRUGO | S_IWUSR, dir, - NULL, &ft1000fops); - if (IS_ERR(file)) { - result = PTR_ERR(file); - goto debug_file_fail; - } - - tmp->dent = dir; - tmp->file = file; - tmp->int_number = info->CardNumber; - list_add(&(tmp->list), &(info->nodes.list)); - - DEBUG("%s: registered debugfs directory \"%s\"\n", __func__, info->DeviceName); - - // initialize application information - info->appcnt = 0; - for (i=0; iapp_info[i].nTxMsg = 0; - info->app_info[i].nRxMsg = 0; - info->app_info[i].nTxMsgReject = 0; - info->app_info[i].nRxMsgMiss = 0; - info->app_info[i].fileobject = NULL; - info->app_info[i].app_id = i+1; - info->app_info[i].DspBCMsgFlag = 0; - info->app_info[i].NumOfMsg = 0; - init_waitqueue_head(&info->app_info[i].wait_dpram_msg); - INIT_LIST_HEAD (&info->app_info[i].app_sqlist); - } - - info->DeviceCreated = TRUE; - ft1000_flarion_cnt++; - - return 0; - -debug_file_fail: - debugfs_remove(dir); -debug_dir_fail: - kfree(tmp); -fail: - return result; -} - -//--------------------------------------------------------------------------- -// Function: ft1000_DestroyDeviceDEBUG -// -// Parameters: dev - pointer to adapter object -// -// Description: Destroys a private char device. -// -// Notes: Only called by cleanup_module(). -// -//--------------------------------------------------------------------------- -void ft1000_destroy_dev(struct net_device *dev) -{ - struct ft1000_info *info = netdev_priv(dev); - int i; - struct dpram_blk *pdpram_blk; - struct dpram_blk *ptr; - struct list_head *pos, *q; - struct ft1000_debug_dirs *dir; - - DEBUG("%s called\n", __func__); - - - - if (info->DeviceCreated) - { - ft1000_flarion_cnt--; - list_for_each_safe(pos, q, &info->nodes.list) { - dir = list_entry(pos, struct ft1000_debug_dirs, list); - if (dir->int_number == info->CardNumber) { - debugfs_remove(dir->file); - debugfs_remove(dir->dent); - list_del(pos); - kfree(dir); - } - } - DEBUG("%s: unregistered device \"%s\"\n", __func__, - info->DeviceName); - - // Make sure we free any memory reserve for slow Queue - for (i=0; iapp_info[i].app_sqlist) == 0) { - pdpram_blk = list_entry(info->app_info[i].app_sqlist.next, struct dpram_blk, list); - list_del(&pdpram_blk->list); - ft1000_free_buffer(pdpram_blk, &freercvpool); - - } - wake_up_interruptible(&info->app_info[i].wait_dpram_msg); - } - - // Remove buffer allocated for receive command data - if (ft1000_flarion_cnt == 0) { - while (list_empty(&freercvpool) == 0) { - ptr = list_entry(freercvpool.next, struct dpram_blk, list); - list_del(&ptr->list); - kfree(ptr->pbuffer); - kfree(ptr); - } - } - info->DeviceCreated = FALSE; - } - - -} - -//--------------------------------------------------------------------------- -// Function: ft1000_open -// -// Parameters: -// -// Description: -// -// Notes: -// -//--------------------------------------------------------------------------- -static int ft1000_open (struct inode *inode, struct file *file) -{ - struct ft1000_info *info; - struct ft1000_device *dev = (struct ft1000_device *)inode->i_private; - int i,num; - - DEBUG("%s called\n", __func__); - num = (MINOR(inode->i_rdev) & 0xf); - DEBUG("ft1000_open: minor number=%d\n", num); - - info = file->private_data = netdev_priv(dev->net); - - DEBUG("f_owner = %p number of application = %d\n", (&file->f_owner), info->appcnt ); - - // Check if maximum number of application exceeded - if (info->appcnt > MAX_NUM_APP) { - DEBUG("Maximum number of application exceeded\n"); - return -EACCES; - } - - // Search for available application info block - for (i=0; iapp_info[i].fileobject == NULL) ) { - break; - } - } - - // Fail due to lack of application info block - if (i == MAX_NUM_APP) { - DEBUG("Could not find an application info block\n"); - return -EACCES; - } - - info->appcnt++; - info->app_info[i].fileobject = &file->f_owner; - info->app_info[i].nTxMsg = 0; - info->app_info[i].nRxMsg = 0; - info->app_info[i].nTxMsgReject = 0; - info->app_info[i].nRxMsgMiss = 0; - - nonseekable_open(inode, file); - return 0; -} - - -//--------------------------------------------------------------------------- -// Function: ft1000_poll_dev -// -// Parameters: -// -// Description: -// -// Notes: -// -//--------------------------------------------------------------------------- - -static unsigned int ft1000_poll_dev(struct file *file, poll_table *wait) -{ - struct net_device *dev = file->private_data; - struct ft1000_info *info; - int i; - - //DEBUG("ft1000_poll_dev called\n"); - if (ft1000_flarion_cnt == 0) { - DEBUG("FT1000:ft1000_poll_dev called when ft1000_flarion_cnt is zero\n"); - return (-EBADF); - } - - info = netdev_priv(dev); - - // Search for matching file object - for (i=0; iapp_info[i].fileobject == &file->f_owner) { - //DEBUG("FT1000:ft1000_ioctl: Message is for AppId = %d\n", info->app_info[i].app_id); - break; - } - } - - // Could not find application info block - if (i == MAX_NUM_APP) { - DEBUG("FT1000:ft1000_ioctl:Could not find application info block\n"); - return ( -EACCES ); - } - - if (list_empty(&info->app_info[i].app_sqlist) == 0) { - DEBUG("FT1000:ft1000_poll_dev:Message detected in slow queue\n"); - return(POLLIN | POLLRDNORM | POLLPRI); - } - - poll_wait (file, &info->app_info[i].wait_dpram_msg, wait); - //DEBUG("FT1000:ft1000_poll_dev:Polling for data from DSP\n"); - - return (0); -} - -//--------------------------------------------------------------------------- -// Function: ft1000_ioctl -// -// Parameters: -// -// Description: -// -// Notes: -// -//--------------------------------------------------------------------------- -static long ft1000_ioctl (struct file *file, unsigned int command, - unsigned long argument) -{ - void __user *argp = (void __user *)argument; - struct net_device *dev; - struct ft1000_info *info; - struct ft1000_device *ft1000dev; - int result=0; - int cmd; - int i; - u16 tempword; - unsigned long flags; - struct timeval tv; - IOCTL_GET_VER get_ver_data; - IOCTL_GET_DSP_STAT get_stat_data; - u8 ConnectionMsg[] = {0x00,0x44,0x10,0x20,0x80,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x93,0x64, - 0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x00,0x00,0x00,0x0a, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x12,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, - 0x00,0x00,0x02,0x37,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x01,0x00,0x01,0x7f,0x00, - 0x00,0x01,0x00,0x00}; - - unsigned short ledStat=0; - unsigned short conStat=0; - - //DEBUG("ft1000_ioctl called\n"); - - if (ft1000_flarion_cnt == 0) { - DEBUG("FT1000:ft1000_ioctl called when ft1000_flarion_cnt is zero\n"); - return (-EBADF); - } - - //DEBUG("FT1000:ft1000_ioctl:command = 0x%x argument = 0x%8x\n", command, (u32)argument); - - dev = file->private_data; - info = netdev_priv(dev); - ft1000dev = info->pFt1000Dev; - cmd = _IOC_NR(command); - //DEBUG("FT1000:ft1000_ioctl:cmd = 0x%x\n", cmd); - - // process the command - switch (cmd) { - case IOCTL_REGISTER_CMD: - DEBUG("FT1000:ft1000_ioctl: IOCTL_FT1000_REGISTER called\n"); - result = get_user(tempword, (__u16 __user*)argp); - if (result) { - DEBUG("result = %d failed to get_user\n", result); - break; - } - if (tempword == DSPBCMSGID) { - // Search for matching file object - for (i=0; iapp_info[i].fileobject == &file->f_owner) { - info->app_info[i].DspBCMsgFlag = 1; - DEBUG("FT1000:ft1000_ioctl:Registered for broadcast messages\n"); - break; - } - } - } - break; - - case IOCTL_GET_VER_CMD: - DEBUG("FT1000:ft1000_ioctl: IOCTL_FT1000_GET_VER called\n"); - - get_ver_data.drv_ver = FT1000_DRV_VER; - - if (copy_to_user(argp, &get_ver_data, sizeof(get_ver_data)) ) { - DEBUG("FT1000:ft1000_ioctl: copy fault occurred\n"); - result = -EFAULT; - break; - } - - DEBUG("FT1000:ft1000_ioctl:driver version = 0x%x\n",(unsigned int)get_ver_data.drv_ver); - - break; - case IOCTL_CONNECT: - // Connect Message - DEBUG("FT1000:ft1000_ioctl: IOCTL_FT1000_CONNECT\n"); - ConnectionMsg[79] = 0xfc; - CardSendCommand(ft1000dev, (unsigned short *)ConnectionMsg, 0x4c); - - break; - case IOCTL_DISCONNECT: - // Disconnect Message - DEBUG("FT1000:ft1000_ioctl: IOCTL_FT1000_DISCONNECT\n"); - ConnectionMsg[79] = 0xfd; - CardSendCommand(ft1000dev, (unsigned short *)ConnectionMsg, 0x4c); - break; - case IOCTL_GET_DSP_STAT_CMD: - //DEBUG("FT1000:ft1000_ioctl: IOCTL_FT1000_GET_DSP_STAT called\n"); - memset(&get_stat_data, 0, sizeof(get_stat_data)); - memcpy(get_stat_data.DspVer, info->DspVer, DSPVERSZ); - memcpy(get_stat_data.HwSerNum, info->HwSerNum, HWSERNUMSZ); - memcpy(get_stat_data.Sku, info->Sku, SKUSZ); - memcpy(get_stat_data.eui64, info->eui64, EUISZ); - - if (info->ProgConStat != 0xFF) { - ft1000_read_dpram16(ft1000dev, FT1000_MAG_DSP_LED, (u8 *)&ledStat, FT1000_MAG_DSP_LED_INDX); - get_stat_data.LedStat = ntohs(ledStat); - DEBUG("FT1000:ft1000_ioctl: LedStat = 0x%x\n", get_stat_data.LedStat); - ft1000_read_dpram16(ft1000dev, FT1000_MAG_DSP_CON_STATE, (u8 *)&conStat, FT1000_MAG_DSP_CON_STATE_INDX); - get_stat_data.ConStat = ntohs(conStat); - DEBUG("FT1000:ft1000_ioctl: ConStat = 0x%x\n", get_stat_data.ConStat); - } - else { - get_stat_data.ConStat = 0x0f; - } - - - get_stat_data.nTxPkts = info->stats.tx_packets; - get_stat_data.nRxPkts = info->stats.rx_packets; - get_stat_data.nTxBytes = info->stats.tx_bytes; - get_stat_data.nRxBytes = info->stats.rx_bytes; - do_gettimeofday ( &tv ); - get_stat_data.ConTm = (u32)(tv.tv_sec - info->ConTm); - DEBUG("Connection Time = %d\n", (int)get_stat_data.ConTm); - if (copy_to_user(argp, &get_stat_data, sizeof(get_stat_data)) ) { - DEBUG("FT1000:ft1000_ioctl: copy fault occurred\n"); - result = -EFAULT; - break; - } - DEBUG("ft1000_chioctl: GET_DSP_STAT succeed\n"); - break; - case IOCTL_SET_DPRAM_CMD: - { - IOCTL_DPRAM_BLK *dpram_data = NULL; - //IOCTL_DPRAM_COMMAND dpram_command; - u16 qtype; - u16 msgsz; - struct pseudo_hdr *ppseudo_hdr; - u16 *pmsg; - u16 total_len; - u16 app_index; - u16 status; - - //DEBUG("FT1000:ft1000_ioctl: IOCTL_FT1000_SET_DPRAM called\n"); - - - if (ft1000_flarion_cnt == 0) { - return (-EBADF); - } - - if (info->DrvMsgPend) { - return (-ENOTTY); - } - - if ( (info->DspAsicReset) || (info->fProvComplete == 0) ) { - return (-EACCES); - } - - info->fAppMsgPend = 1; - - if (info->CardReady) { - - //DEBUG("FT1000:ft1000_ioctl: try to SET_DPRAM \n"); - - // Get the length field to see how many bytes to copy - result = get_user(msgsz, (__u16 __user *)argp); - msgsz = ntohs (msgsz); - //DEBUG("FT1000:ft1000_ioctl: length of message = %d\n", msgsz); - - if (msgsz > MAX_CMD_SQSIZE) { - DEBUG("FT1000:ft1000_ioctl: bad message length = %d\n", msgsz); - result = -EINVAL; - break; - } - - result = -ENOMEM; - dpram_data = kmalloc(msgsz + 2, GFP_KERNEL); - if (!dpram_data) - break; - - if ( copy_from_user(dpram_data, argp, msgsz+2) ) { - DEBUG("FT1000:ft1000_ChIoctl: copy fault occurred\n"); - result = -EFAULT; - } - else { - // Check if this message came from a registered application - for (i=0; iapp_info[i].fileobject == &file->f_owner) { - break; - } - } - if (i==MAX_NUM_APP) { - DEBUG("FT1000:No matching application fileobject\n"); - result = -EINVAL; - kfree(dpram_data); - break; - } - app_index = i; - - // Check message qtype type which is the lower byte within qos_class - qtype = ntohs(dpram_data->pseudohdr.qos_class) & 0xff; - //DEBUG("FT1000_ft1000_ioctl: qtype = %d\n", qtype); - if (qtype) { - } - else { - // Put message into Slow Queue - // Only put a message into the DPRAM if msg doorbell is available - status = ft1000_read_register(ft1000dev, &tempword, FT1000_REG_DOORBELL); - //DEBUG("FT1000_ft1000_ioctl: READ REGISTER tempword=%x\n", tempword); - if (tempword & FT1000_DB_DPRAM_TX) { - // Suspend for 2ms and try again due to DSP doorbell busy - mdelay(2); - status = ft1000_read_register(ft1000dev, &tempword, FT1000_REG_DOORBELL); - if (tempword & FT1000_DB_DPRAM_TX) { - // Suspend for 1ms and try again due to DSP doorbell busy - mdelay(1); - status = ft1000_read_register(ft1000dev, &tempword, FT1000_REG_DOORBELL); - if (tempword & FT1000_DB_DPRAM_TX) { - status = ft1000_read_register(ft1000dev, &tempword, FT1000_REG_DOORBELL); - if (tempword & FT1000_DB_DPRAM_TX) { - // Suspend for 3ms and try again due to DSP doorbell busy - mdelay(3); - status = ft1000_read_register(ft1000dev, &tempword, FT1000_REG_DOORBELL); - if (tempword & FT1000_DB_DPRAM_TX) { - DEBUG("FT1000:ft1000_ioctl:Doorbell not available\n"); - result = -ENOTTY; - kfree(dpram_data); - break; - } - } - } - } - } - - //DEBUG("FT1000_ft1000_ioctl: finished reading register\n"); - - // Make sure we are within the limits of the slow queue memory limitation - if ( (msgsz < MAX_CMD_SQSIZE) && (msgsz > PSEUDOSZ) ) { - // Need to put sequence number plus new checksum for message - pmsg = (u16 *)&dpram_data->pseudohdr; - ppseudo_hdr = (struct pseudo_hdr *)pmsg; - total_len = msgsz+2; - if (total_len & 0x1) { - total_len++; - } - - // Insert slow queue sequence number - ppseudo_hdr->seq_num = info->squeseqnum++; - ppseudo_hdr->portsrc = info->app_info[app_index].app_id; - // Calculate new checksum - ppseudo_hdr->checksum = *pmsg++; - //DEBUG("checksum = 0x%x\n", ppseudo_hdr->checksum); - for (i=1; i<7; i++) { - ppseudo_hdr->checksum ^= *pmsg++; - //DEBUG("checksum = 0x%x\n", ppseudo_hdr->checksum); - } - pmsg++; - ppseudo_hdr = (struct pseudo_hdr *)pmsg; - CardSendCommand(ft1000dev,(unsigned short*)dpram_data,total_len+2); - - - info->app_info[app_index].nTxMsg++; - } - else { - result = -EINVAL; - } - } - } - } - else { - DEBUG("FT1000:ft1000_ioctl: Card not ready take messages\n"); - result = -EACCES; - } - kfree(dpram_data); - - } - break; - case IOCTL_GET_DPRAM_CMD: - { - struct dpram_blk *pdpram_blk; - IOCTL_DPRAM_BLK __user *pioctl_dpram; - int msglen; - - //DEBUG("FT1000:ft1000_ioctl: IOCTL_FT1000_GET_DPRAM called\n"); - - if (ft1000_flarion_cnt == 0) { - return (-EBADF); - } - - // Search for matching file object - for (i=0; iapp_info[i].fileobject == &file->f_owner) { - //DEBUG("FT1000:ft1000_ioctl: Message is for AppId = %d\n", info->app_info[i].app_id); - break; - } - } - - // Could not find application info block - if (i == MAX_NUM_APP) { - DEBUG("FT1000:ft1000_ioctl:Could not find application info block\n"); - result = -EBADF; - break; - } - - result = 0; - pioctl_dpram = argp; - if (list_empty(&info->app_info[i].app_sqlist) == 0) { - //DEBUG("FT1000:ft1000_ioctl:Message detected in slow queue\n"); - spin_lock_irqsave(&free_buff_lock, flags); - pdpram_blk = list_entry(info->app_info[i].app_sqlist.next, struct dpram_blk, list); - list_del(&pdpram_blk->list); - info->app_info[i].NumOfMsg--; - //DEBUG("FT1000:ft1000_ioctl:NumOfMsg for app %d = %d\n", i, info->app_info[i].NumOfMsg); - spin_unlock_irqrestore(&free_buff_lock, flags); - msglen = ntohs(*(u16 *)pdpram_blk->pbuffer) + PSEUDOSZ; - result = get_user(msglen, &pioctl_dpram->total_len); - if (result) - break; - msglen = htons(msglen); - //DEBUG("FT1000:ft1000_ioctl:msg length = %x\n", msglen); - if(copy_to_user (&pioctl_dpram->pseudohdr, pdpram_blk->pbuffer, msglen)) - { - DEBUG("FT1000:ft1000_ioctl: copy fault occurred\n"); - result = -EFAULT; - break; - } - - ft1000_free_buffer(pdpram_blk, &freercvpool); - result = msglen; - } - //DEBUG("FT1000:ft1000_ioctl: IOCTL_FT1000_GET_DPRAM no message\n"); - } - break; - - default: - DEBUG("FT1000:ft1000_ioctl:unknown command: 0x%x\n", command); - result = -ENOTTY; - break; - } - info->fAppMsgPend = 0; - return result; -} - -//--------------------------------------------------------------------------- -// Function: ft1000_release -// -// Parameters: -// -// Description: -// -// Notes: -// -//--------------------------------------------------------------------------- -static int ft1000_release (struct inode *inode, struct file *file) -{ - struct ft1000_info *info; - struct net_device *dev; - int i; - struct dpram_blk *pdpram_blk; - - DEBUG("ft1000_release called\n"); - - dev = file->private_data; - info = netdev_priv(dev); - - if (ft1000_flarion_cnt == 0) { - info->appcnt--; - return (-EBADF); - } - - // Search for matching file object - for (i=0; iapp_info[i].fileobject == &file->f_owner) { - //DEBUG("FT1000:ft1000_ioctl: Message is for AppId = %d\n", info->app_info[i].app_id); - break; - } - } - - if (i==MAX_NUM_APP) - return 0; - - while (list_empty(&info->app_info[i].app_sqlist) == 0) { - DEBUG("Remove and free memory queue up on slow queue\n"); - pdpram_blk = list_entry(info->app_info[i].app_sqlist.next, struct dpram_blk, list); - list_del(&pdpram_blk->list); - ft1000_free_buffer(pdpram_blk, &freercvpool); - } - - // initialize application information - info->appcnt--; - DEBUG("ft1000_chdev:%s:appcnt = %d\n", __FUNCTION__, info->appcnt); - info->app_info[i].fileobject = NULL; - - return 0; -} - diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_debug.c b/drivers/staging/ft1000/ft1000-usb/ft1000_debug.c new file mode 100644 index 000000000000..e39809229d46 --- /dev/null +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_debug.c @@ -0,0 +1,784 @@ +//--------------------------------------------------------------------------- +// FT1000 driver for Flarion Flash OFDM NIC Device +// +// Copyright (C) 2006 Flarion Technologies, All rights reserved. +// +// 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. 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. You should have received a copy of the GNU General Public +// License along with this program; if not, write to the +// Free Software Foundation, Inc., 59 Temple Place - +// Suite 330, Boston, MA 02111-1307, USA. +//--------------------------------------------------------------------------- +// +// File: ft1000_chdev.c +// +// Description: Custom character device dispatch routines. +// +// History: +// 8/29/02 Whc Ported to Linux. +// 6/05/06 Whc Porting to Linux 2.6.9 +// +//--------------------------------------------------------------------------- +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include "ft1000_usb.h" + +static int ft1000_flarion_cnt = 0; + +static int ft1000_open (struct inode *inode, struct file *file); +static unsigned int ft1000_poll_dev(struct file *file, poll_table *wait); +static long ft1000_ioctl(struct file *file, unsigned int command, + unsigned long argument); +static int ft1000_release (struct inode *inode, struct file *file); + +// List to free receive command buffer pool +struct list_head freercvpool; + +// lock to arbitrate free buffer list for receive command data +spinlock_t free_buff_lock; + +int numofmsgbuf = 0; + +// +// Table of entry-point routines for char device +// +static struct file_operations ft1000fops = +{ + .unlocked_ioctl = ft1000_ioctl, + .poll = ft1000_poll_dev, + .open = ft1000_open, + .release = ft1000_release, + .llseek = no_llseek, +}; + +//--------------------------------------------------------------------------- +// Function: ft1000_get_buffer +// +// Parameters: +// +// Returns: +// +// Description: +// +// Notes: +// +//--------------------------------------------------------------------------- +struct dpram_blk *ft1000_get_buffer(struct list_head *bufflist) +{ + unsigned long flags; + struct dpram_blk *ptr; + + spin_lock_irqsave(&free_buff_lock, flags); + // Check if buffer is available + if ( list_empty(bufflist) ) { + DEBUG("ft1000_get_buffer: No more buffer - %d\n", numofmsgbuf); + ptr = NULL; + } + else { + numofmsgbuf--; + ptr = list_entry(bufflist->next, struct dpram_blk, list); + list_del(&ptr->list); + //DEBUG("ft1000_get_buffer: number of free msg buffers = %d\n", numofmsgbuf); + } + spin_unlock_irqrestore(&free_buff_lock, flags); + + return ptr; +} + + + + +//--------------------------------------------------------------------------- +// Function: ft1000_free_buffer +// +// Parameters: +// +// Returns: +// +// Description: +// +// Notes: +// +//--------------------------------------------------------------------------- +void ft1000_free_buffer(struct dpram_blk *pdpram_blk, struct list_head *plist) +{ + unsigned long flags; + + spin_lock_irqsave(&free_buff_lock, flags); + // Put memory back to list + list_add_tail(&pdpram_blk->list, plist); + numofmsgbuf++; + //DEBUG("ft1000_free_buffer: number of free msg buffers = %d\n", numofmsgbuf); + spin_unlock_irqrestore(&free_buff_lock, flags); +} + +//--------------------------------------------------------------------------- +// Function: ft1000_CreateDevice +// +// Parameters: dev - pointer to adapter object +// +// Returns: 0 if successful +// +// Description: Creates a private char device. +// +// Notes: Only called by init_module(). +// +//--------------------------------------------------------------------------- +int ft1000_create_dev(struct ft1000_device *dev) +{ + struct ft1000_info *info = netdev_priv(dev->net); + int result; + int i; + struct dentry *dir, *file; + struct ft1000_debug_dirs *tmp; + + // make a new device name + sprintf(info->DeviceName, "%s%d", "FT1000_", info->CardNumber); + + DEBUG("%s: number of instance = %d\n", __func__, ft1000_flarion_cnt); + DEBUG("DeviceCreated = %x\n", info->DeviceCreated); + + if (info->DeviceCreated) + { + DEBUG("%s: \"%s\" already registered\n", __func__, info->DeviceName); + return -EIO; + } + + + // register the device + DEBUG("%s: \"%s\" debugfs device registration\n", __func__, info->DeviceName); + + tmp = kmalloc(sizeof(struct ft1000_debug_dirs), GFP_KERNEL); + if (tmp == NULL) { + result = -1; + goto fail; + } + + dir = debugfs_create_dir(info->DeviceName, 0); + if (IS_ERR(dir)) { + result = PTR_ERR(dir); + goto debug_dir_fail; + } + + file = debugfs_create_file("device", S_IRUGO | S_IWUSR, dir, + NULL, &ft1000fops); + if (IS_ERR(file)) { + result = PTR_ERR(file); + goto debug_file_fail; + } + + tmp->dent = dir; + tmp->file = file; + tmp->int_number = info->CardNumber; + list_add(&(tmp->list), &(info->nodes.list)); + + DEBUG("%s: registered debugfs directory \"%s\"\n", __func__, info->DeviceName); + + // initialize application information + info->appcnt = 0; + for (i=0; iapp_info[i].nTxMsg = 0; + info->app_info[i].nRxMsg = 0; + info->app_info[i].nTxMsgReject = 0; + info->app_info[i].nRxMsgMiss = 0; + info->app_info[i].fileobject = NULL; + info->app_info[i].app_id = i+1; + info->app_info[i].DspBCMsgFlag = 0; + info->app_info[i].NumOfMsg = 0; + init_waitqueue_head(&info->app_info[i].wait_dpram_msg); + INIT_LIST_HEAD (&info->app_info[i].app_sqlist); + } + + info->DeviceCreated = TRUE; + ft1000_flarion_cnt++; + + return 0; + +debug_file_fail: + debugfs_remove(dir); +debug_dir_fail: + kfree(tmp); +fail: + return result; +} + +//--------------------------------------------------------------------------- +// Function: ft1000_DestroyDeviceDEBUG +// +// Parameters: dev - pointer to adapter object +// +// Description: Destroys a private char device. +// +// Notes: Only called by cleanup_module(). +// +//--------------------------------------------------------------------------- +void ft1000_destroy_dev(struct net_device *dev) +{ + struct ft1000_info *info = netdev_priv(dev); + int i; + struct dpram_blk *pdpram_blk; + struct dpram_blk *ptr; + struct list_head *pos, *q; + struct ft1000_debug_dirs *dir; + + DEBUG("%s called\n", __func__); + + + + if (info->DeviceCreated) + { + ft1000_flarion_cnt--; + list_for_each_safe(pos, q, &info->nodes.list) { + dir = list_entry(pos, struct ft1000_debug_dirs, list); + if (dir->int_number == info->CardNumber) { + debugfs_remove(dir->file); + debugfs_remove(dir->dent); + list_del(pos); + kfree(dir); + } + } + DEBUG("%s: unregistered device \"%s\"\n", __func__, + info->DeviceName); + + // Make sure we free any memory reserve for slow Queue + for (i=0; iapp_info[i].app_sqlist) == 0) { + pdpram_blk = list_entry(info->app_info[i].app_sqlist.next, struct dpram_blk, list); + list_del(&pdpram_blk->list); + ft1000_free_buffer(pdpram_blk, &freercvpool); + + } + wake_up_interruptible(&info->app_info[i].wait_dpram_msg); + } + + // Remove buffer allocated for receive command data + if (ft1000_flarion_cnt == 0) { + while (list_empty(&freercvpool) == 0) { + ptr = list_entry(freercvpool.next, struct dpram_blk, list); + list_del(&ptr->list); + kfree(ptr->pbuffer); + kfree(ptr); + } + } + info->DeviceCreated = FALSE; + } + + +} + +//--------------------------------------------------------------------------- +// Function: ft1000_open +// +// Parameters: +// +// Description: +// +// Notes: +// +//--------------------------------------------------------------------------- +static int ft1000_open (struct inode *inode, struct file *file) +{ + struct ft1000_info *info; + struct ft1000_device *dev = (struct ft1000_device *)inode->i_private; + int i,num; + + DEBUG("%s called\n", __func__); + num = (MINOR(inode->i_rdev) & 0xf); + DEBUG("ft1000_open: minor number=%d\n", num); + + info = file->private_data = netdev_priv(dev->net); + + DEBUG("f_owner = %p number of application = %d\n", (&file->f_owner), info->appcnt ); + + // Check if maximum number of application exceeded + if (info->appcnt > MAX_NUM_APP) { + DEBUG("Maximum number of application exceeded\n"); + return -EACCES; + } + + // Search for available application info block + for (i=0; iapp_info[i].fileobject == NULL) ) { + break; + } + } + + // Fail due to lack of application info block + if (i == MAX_NUM_APP) { + DEBUG("Could not find an application info block\n"); + return -EACCES; + } + + info->appcnt++; + info->app_info[i].fileobject = &file->f_owner; + info->app_info[i].nTxMsg = 0; + info->app_info[i].nRxMsg = 0; + info->app_info[i].nTxMsgReject = 0; + info->app_info[i].nRxMsgMiss = 0; + + nonseekable_open(inode, file); + return 0; +} + + +//--------------------------------------------------------------------------- +// Function: ft1000_poll_dev +// +// Parameters: +// +// Description: +// +// Notes: +// +//--------------------------------------------------------------------------- + +static unsigned int ft1000_poll_dev(struct file *file, poll_table *wait) +{ + struct net_device *dev = file->private_data; + struct ft1000_info *info; + int i; + + //DEBUG("ft1000_poll_dev called\n"); + if (ft1000_flarion_cnt == 0) { + DEBUG("FT1000:ft1000_poll_dev called when ft1000_flarion_cnt is zero\n"); + return (-EBADF); + } + + info = netdev_priv(dev); + + // Search for matching file object + for (i=0; iapp_info[i].fileobject == &file->f_owner) { + //DEBUG("FT1000:ft1000_ioctl: Message is for AppId = %d\n", info->app_info[i].app_id); + break; + } + } + + // Could not find application info block + if (i == MAX_NUM_APP) { + DEBUG("FT1000:ft1000_ioctl:Could not find application info block\n"); + return ( -EACCES ); + } + + if (list_empty(&info->app_info[i].app_sqlist) == 0) { + DEBUG("FT1000:ft1000_poll_dev:Message detected in slow queue\n"); + return(POLLIN | POLLRDNORM | POLLPRI); + } + + poll_wait (file, &info->app_info[i].wait_dpram_msg, wait); + //DEBUG("FT1000:ft1000_poll_dev:Polling for data from DSP\n"); + + return (0); +} + +//--------------------------------------------------------------------------- +// Function: ft1000_ioctl +// +// Parameters: +// +// Description: +// +// Notes: +// +//--------------------------------------------------------------------------- +static long ft1000_ioctl (struct file *file, unsigned int command, + unsigned long argument) +{ + void __user *argp = (void __user *)argument; + struct net_device *dev; + struct ft1000_info *info; + struct ft1000_device *ft1000dev; + int result=0; + int cmd; + int i; + u16 tempword; + unsigned long flags; + struct timeval tv; + IOCTL_GET_VER get_ver_data; + IOCTL_GET_DSP_STAT get_stat_data; + u8 ConnectionMsg[] = {0x00,0x44,0x10,0x20,0x80,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x93,0x64, + 0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x00,0x00,0x00,0x0a, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x12,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x02,0x37,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x01,0x00,0x01,0x7f,0x00, + 0x00,0x01,0x00,0x00}; + + unsigned short ledStat=0; + unsigned short conStat=0; + + //DEBUG("ft1000_ioctl called\n"); + + if (ft1000_flarion_cnt == 0) { + DEBUG("FT1000:ft1000_ioctl called when ft1000_flarion_cnt is zero\n"); + return (-EBADF); + } + + //DEBUG("FT1000:ft1000_ioctl:command = 0x%x argument = 0x%8x\n", command, (u32)argument); + + dev = file->private_data; + info = netdev_priv(dev); + ft1000dev = info->pFt1000Dev; + cmd = _IOC_NR(command); + //DEBUG("FT1000:ft1000_ioctl:cmd = 0x%x\n", cmd); + + // process the command + switch (cmd) { + case IOCTL_REGISTER_CMD: + DEBUG("FT1000:ft1000_ioctl: IOCTL_FT1000_REGISTER called\n"); + result = get_user(tempword, (__u16 __user*)argp); + if (result) { + DEBUG("result = %d failed to get_user\n", result); + break; + } + if (tempword == DSPBCMSGID) { + // Search for matching file object + for (i=0; iapp_info[i].fileobject == &file->f_owner) { + info->app_info[i].DspBCMsgFlag = 1; + DEBUG("FT1000:ft1000_ioctl:Registered for broadcast messages\n"); + break; + } + } + } + break; + + case IOCTL_GET_VER_CMD: + DEBUG("FT1000:ft1000_ioctl: IOCTL_FT1000_GET_VER called\n"); + + get_ver_data.drv_ver = FT1000_DRV_VER; + + if (copy_to_user(argp, &get_ver_data, sizeof(get_ver_data)) ) { + DEBUG("FT1000:ft1000_ioctl: copy fault occurred\n"); + result = -EFAULT; + break; + } + + DEBUG("FT1000:ft1000_ioctl:driver version = 0x%x\n",(unsigned int)get_ver_data.drv_ver); + + break; + case IOCTL_CONNECT: + // Connect Message + DEBUG("FT1000:ft1000_ioctl: IOCTL_FT1000_CONNECT\n"); + ConnectionMsg[79] = 0xfc; + CardSendCommand(ft1000dev, (unsigned short *)ConnectionMsg, 0x4c); + + break; + case IOCTL_DISCONNECT: + // Disconnect Message + DEBUG("FT1000:ft1000_ioctl: IOCTL_FT1000_DISCONNECT\n"); + ConnectionMsg[79] = 0xfd; + CardSendCommand(ft1000dev, (unsigned short *)ConnectionMsg, 0x4c); + break; + case IOCTL_GET_DSP_STAT_CMD: + //DEBUG("FT1000:ft1000_ioctl: IOCTL_FT1000_GET_DSP_STAT called\n"); + memset(&get_stat_data, 0, sizeof(get_stat_data)); + memcpy(get_stat_data.DspVer, info->DspVer, DSPVERSZ); + memcpy(get_stat_data.HwSerNum, info->HwSerNum, HWSERNUMSZ); + memcpy(get_stat_data.Sku, info->Sku, SKUSZ); + memcpy(get_stat_data.eui64, info->eui64, EUISZ); + + if (info->ProgConStat != 0xFF) { + ft1000_read_dpram16(ft1000dev, FT1000_MAG_DSP_LED, (u8 *)&ledStat, FT1000_MAG_DSP_LED_INDX); + get_stat_data.LedStat = ntohs(ledStat); + DEBUG("FT1000:ft1000_ioctl: LedStat = 0x%x\n", get_stat_data.LedStat); + ft1000_read_dpram16(ft1000dev, FT1000_MAG_DSP_CON_STATE, (u8 *)&conStat, FT1000_MAG_DSP_CON_STATE_INDX); + get_stat_data.ConStat = ntohs(conStat); + DEBUG("FT1000:ft1000_ioctl: ConStat = 0x%x\n", get_stat_data.ConStat); + } + else { + get_stat_data.ConStat = 0x0f; + } + + + get_stat_data.nTxPkts = info->stats.tx_packets; + get_stat_data.nRxPkts = info->stats.rx_packets; + get_stat_data.nTxBytes = info->stats.tx_bytes; + get_stat_data.nRxBytes = info->stats.rx_bytes; + do_gettimeofday ( &tv ); + get_stat_data.ConTm = (u32)(tv.tv_sec - info->ConTm); + DEBUG("Connection Time = %d\n", (int)get_stat_data.ConTm); + if (copy_to_user(argp, &get_stat_data, sizeof(get_stat_data)) ) { + DEBUG("FT1000:ft1000_ioctl: copy fault occurred\n"); + result = -EFAULT; + break; + } + DEBUG("ft1000_chioctl: GET_DSP_STAT succeed\n"); + break; + case IOCTL_SET_DPRAM_CMD: + { + IOCTL_DPRAM_BLK *dpram_data = NULL; + //IOCTL_DPRAM_COMMAND dpram_command; + u16 qtype; + u16 msgsz; + struct pseudo_hdr *ppseudo_hdr; + u16 *pmsg; + u16 total_len; + u16 app_index; + u16 status; + + //DEBUG("FT1000:ft1000_ioctl: IOCTL_FT1000_SET_DPRAM called\n"); + + + if (ft1000_flarion_cnt == 0) { + return (-EBADF); + } + + if (info->DrvMsgPend) { + return (-ENOTTY); + } + + if ( (info->DspAsicReset) || (info->fProvComplete == 0) ) { + return (-EACCES); + } + + info->fAppMsgPend = 1; + + if (info->CardReady) { + + //DEBUG("FT1000:ft1000_ioctl: try to SET_DPRAM \n"); + + // Get the length field to see how many bytes to copy + result = get_user(msgsz, (__u16 __user *)argp); + msgsz = ntohs (msgsz); + //DEBUG("FT1000:ft1000_ioctl: length of message = %d\n", msgsz); + + if (msgsz > MAX_CMD_SQSIZE) { + DEBUG("FT1000:ft1000_ioctl: bad message length = %d\n", msgsz); + result = -EINVAL; + break; + } + + result = -ENOMEM; + dpram_data = kmalloc(msgsz + 2, GFP_KERNEL); + if (!dpram_data) + break; + + if ( copy_from_user(dpram_data, argp, msgsz+2) ) { + DEBUG("FT1000:ft1000_ChIoctl: copy fault occurred\n"); + result = -EFAULT; + } + else { + // Check if this message came from a registered application + for (i=0; iapp_info[i].fileobject == &file->f_owner) { + break; + } + } + if (i==MAX_NUM_APP) { + DEBUG("FT1000:No matching application fileobject\n"); + result = -EINVAL; + kfree(dpram_data); + break; + } + app_index = i; + + // Check message qtype type which is the lower byte within qos_class + qtype = ntohs(dpram_data->pseudohdr.qos_class) & 0xff; + //DEBUG("FT1000_ft1000_ioctl: qtype = %d\n", qtype); + if (qtype) { + } + else { + // Put message into Slow Queue + // Only put a message into the DPRAM if msg doorbell is available + status = ft1000_read_register(ft1000dev, &tempword, FT1000_REG_DOORBELL); + //DEBUG("FT1000_ft1000_ioctl: READ REGISTER tempword=%x\n", tempword); + if (tempword & FT1000_DB_DPRAM_TX) { + // Suspend for 2ms and try again due to DSP doorbell busy + mdelay(2); + status = ft1000_read_register(ft1000dev, &tempword, FT1000_REG_DOORBELL); + if (tempword & FT1000_DB_DPRAM_TX) { + // Suspend for 1ms and try again due to DSP doorbell busy + mdelay(1); + status = ft1000_read_register(ft1000dev, &tempword, FT1000_REG_DOORBELL); + if (tempword & FT1000_DB_DPRAM_TX) { + status = ft1000_read_register(ft1000dev, &tempword, FT1000_REG_DOORBELL); + if (tempword & FT1000_DB_DPRAM_TX) { + // Suspend for 3ms and try again due to DSP doorbell busy + mdelay(3); + status = ft1000_read_register(ft1000dev, &tempword, FT1000_REG_DOORBELL); + if (tempword & FT1000_DB_DPRAM_TX) { + DEBUG("FT1000:ft1000_ioctl:Doorbell not available\n"); + result = -ENOTTY; + kfree(dpram_data); + break; + } + } + } + } + } + + //DEBUG("FT1000_ft1000_ioctl: finished reading register\n"); + + // Make sure we are within the limits of the slow queue memory limitation + if ( (msgsz < MAX_CMD_SQSIZE) && (msgsz > PSEUDOSZ) ) { + // Need to put sequence number plus new checksum for message + pmsg = (u16 *)&dpram_data->pseudohdr; + ppseudo_hdr = (struct pseudo_hdr *)pmsg; + total_len = msgsz+2; + if (total_len & 0x1) { + total_len++; + } + + // Insert slow queue sequence number + ppseudo_hdr->seq_num = info->squeseqnum++; + ppseudo_hdr->portsrc = info->app_info[app_index].app_id; + // Calculate new checksum + ppseudo_hdr->checksum = *pmsg++; + //DEBUG("checksum = 0x%x\n", ppseudo_hdr->checksum); + for (i=1; i<7; i++) { + ppseudo_hdr->checksum ^= *pmsg++; + //DEBUG("checksum = 0x%x\n", ppseudo_hdr->checksum); + } + pmsg++; + ppseudo_hdr = (struct pseudo_hdr *)pmsg; + CardSendCommand(ft1000dev,(unsigned short*)dpram_data,total_len+2); + + + info->app_info[app_index].nTxMsg++; + } + else { + result = -EINVAL; + } + } + } + } + else { + DEBUG("FT1000:ft1000_ioctl: Card not ready take messages\n"); + result = -EACCES; + } + kfree(dpram_data); + + } + break; + case IOCTL_GET_DPRAM_CMD: + { + struct dpram_blk *pdpram_blk; + IOCTL_DPRAM_BLK __user *pioctl_dpram; + int msglen; + + //DEBUG("FT1000:ft1000_ioctl: IOCTL_FT1000_GET_DPRAM called\n"); + + if (ft1000_flarion_cnt == 0) { + return (-EBADF); + } + + // Search for matching file object + for (i=0; iapp_info[i].fileobject == &file->f_owner) { + //DEBUG("FT1000:ft1000_ioctl: Message is for AppId = %d\n", info->app_info[i].app_id); + break; + } + } + + // Could not find application info block + if (i == MAX_NUM_APP) { + DEBUG("FT1000:ft1000_ioctl:Could not find application info block\n"); + result = -EBADF; + break; + } + + result = 0; + pioctl_dpram = argp; + if (list_empty(&info->app_info[i].app_sqlist) == 0) { + //DEBUG("FT1000:ft1000_ioctl:Message detected in slow queue\n"); + spin_lock_irqsave(&free_buff_lock, flags); + pdpram_blk = list_entry(info->app_info[i].app_sqlist.next, struct dpram_blk, list); + list_del(&pdpram_blk->list); + info->app_info[i].NumOfMsg--; + //DEBUG("FT1000:ft1000_ioctl:NumOfMsg for app %d = %d\n", i, info->app_info[i].NumOfMsg); + spin_unlock_irqrestore(&free_buff_lock, flags); + msglen = ntohs(*(u16 *)pdpram_blk->pbuffer) + PSEUDOSZ; + result = get_user(msglen, &pioctl_dpram->total_len); + if (result) + break; + msglen = htons(msglen); + //DEBUG("FT1000:ft1000_ioctl:msg length = %x\n", msglen); + if(copy_to_user (&pioctl_dpram->pseudohdr, pdpram_blk->pbuffer, msglen)) + { + DEBUG("FT1000:ft1000_ioctl: copy fault occurred\n"); + result = -EFAULT; + break; + } + + ft1000_free_buffer(pdpram_blk, &freercvpool); + result = msglen; + } + //DEBUG("FT1000:ft1000_ioctl: IOCTL_FT1000_GET_DPRAM no message\n"); + } + break; + + default: + DEBUG("FT1000:ft1000_ioctl:unknown command: 0x%x\n", command); + result = -ENOTTY; + break; + } + info->fAppMsgPend = 0; + return result; +} + +//--------------------------------------------------------------------------- +// Function: ft1000_release +// +// Parameters: +// +// Description: +// +// Notes: +// +//--------------------------------------------------------------------------- +static int ft1000_release (struct inode *inode, struct file *file) +{ + struct ft1000_info *info; + struct net_device *dev; + int i; + struct dpram_blk *pdpram_blk; + + DEBUG("ft1000_release called\n"); + + dev = file->private_data; + info = netdev_priv(dev); + + if (ft1000_flarion_cnt == 0) { + info->appcnt--; + return (-EBADF); + } + + // Search for matching file object + for (i=0; iapp_info[i].fileobject == &file->f_owner) { + //DEBUG("FT1000:ft1000_ioctl: Message is for AppId = %d\n", info->app_info[i].app_id); + break; + } + } + + if (i==MAX_NUM_APP) + return 0; + + while (list_empty(&info->app_info[i].app_sqlist) == 0) { + DEBUG("Remove and free memory queue up on slow queue\n"); + pdpram_blk = list_entry(info->app_info[i].app_sqlist.next, struct dpram_blk, list); + list_del(&pdpram_blk->list); + ft1000_free_buffer(pdpram_blk, &freercvpool); + } + + // initialize application information + info->appcnt--; + DEBUG("ft1000_chdev:%s:appcnt = %d\n", __FUNCTION__, info->appcnt); + info->app_info[i].fileobject = NULL; + + return 0; +} + -- cgit v1.2.3 From 0ce72ea3b2f29e5755b095a5b217b9bab8386a03 Mon Sep 17 00:00:00 2001 From: Marek Belisko Date: Tue, 14 Dec 2010 14:02:54 +0100 Subject: staging: ft1000: Fix camelcase variable names. Signed-off-by: Marek Belisko Signed-off-by: Greg Kroah-Hartman --- .../staging/ft1000/ft1000-usb/ft1000_download.c | 204 ++++++++++----------- 1 file changed, 102 insertions(+), 102 deletions(-) diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_download.c b/drivers/staging/ft1000/ft1000-usb/ft1000_download.c index e4905ad2badc..17546d8ec08d 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_download.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_download.c @@ -772,26 +772,26 @@ static u32 write_blk_fifo (struct ft1000_device *ft1000dev, u16 **pUsFile, u8 ** u16 scram_dnldr(struct ft1000_device *ft1000dev, void *pFileStart, u32 FileLength) { - u16 Status = STATUS_SUCCESS; - u32 uiState; + u16 status = STATUS_SUCCESS; + u32 state; u16 handshake; - struct pseudo_hdr *pHdr; - u16 usHdrLength; + struct pseudo_hdr *pseudo_header; + u16 pseudo_header_len; long word_length; u16 request; u16 temp; u16 tempword; - struct dsp_file_hdr *pFileHdr5; - struct dsp_image_info *pDspImageInfoV6 = NULL; + struct dsp_file_hdr *file_hdr; + struct dsp_image_info *dsp_img_info = NULL; long requested_version; - bool bGoodVersion; - struct drv_msg *pMailBoxData; - u16 *pUsData = NULL; - u16 *pUsFile = NULL; - u8 *pUcFile = NULL; - u8 *pBootEnd = NULL, *pCodeEnd= NULL; - int imageN; + bool correct_version; + struct drv_msg *mailbox_data; + u16 *data = NULL; + u16 *s_file = NULL; + u8 *c_file = NULL; + u8 *boot_end = NULL, *code_end= NULL; + int image; long loader_code_address, loader_code_size = 0; long run_address = 0, run_size = 0; @@ -814,24 +814,24 @@ u16 scram_dnldr(struct ft1000_device *ft1000dev, void *pFileStart, u32 FileLeng // Get version id of file, at first 4 bytes of file, for newer files. // - uiState = STATE_START_DWNLD; + state = STATE_START_DWNLD; - pFileHdr5 = (struct dsp_file_hdr *)pFileStart; + file_hdr = (struct dsp_file_hdr *)pFileStart; ft1000_write_register (ft1000dev, 0x800, FT1000_REG_MAG_WATERMARK); - pUsFile = (u16 *)(pFileStart + pFileHdr5->loader_offset); - pUcFile = (u8 *)(pFileStart + pFileHdr5->loader_offset); + s_file = (u16 *)(pFileStart + file_hdr->loader_offset); + c_file = (u8 *)(pFileStart + file_hdr->loader_offset); - pBootEnd = (u8 *)(pFileStart + pFileHdr5->loader_code_end); + boot_end = (u8 *)(pFileStart + file_hdr->loader_code_end); - loader_code_address = pFileHdr5->loader_code_address; - loader_code_size = pFileHdr5->loader_code_size; - bGoodVersion = FALSE; + loader_code_address = file_hdr->loader_code_address; + loader_code_size = file_hdr->loader_code_size; + correct_version = FALSE; - while ((Status == STATUS_SUCCESS) && (uiState != STATE_DONE_FILE)) + while ((status == STATUS_SUCCESS) && (state != STATE_DONE_FILE)) { - switch (uiState) + switch (state) { case STATE_START_DWNLD: DEBUG("FT1000:STATE_START_DWNLD\n"); @@ -848,10 +848,10 @@ u16 scram_dnldr(struct ft1000_device *ft1000dev, void *pFileStart, u32 FileLeng else { DEBUG("FT1000:download:Download error: Handshake failed\n"); - Status = STATUS_FAILURE; + status = STATUS_FAILURE; } - uiState = STATE_BOOT_DWNLD; + state = STATE_BOOT_DWNLD; break; @@ -878,11 +878,11 @@ u16 scram_dnldr(struct ft1000_device *ft1000dev, void *pFileStart, u32 FileLeng case REQUEST_DONE_BL: DEBUG("FT1000:REQUEST_DONE_BL\n"); /* Reposition ptrs to beginning of code section */ - pUsFile = (u16 *)(pBootEnd); - pUcFile = (u8 *)(pBootEnd); - //DEBUG("FT1000:download:pUsFile = 0x%8x\n", (int)pUsFile); - //DEBUG("FT1000:download:pUcFile = 0x%8x\n", (int)pUcFile); - uiState = STATE_CODE_DWNLD; + s_file = (u16 *)(boot_end); + c_file = (u8 *)(boot_end); + //DEBUG("FT1000:download:s_file = 0x%8x\n", (int)s_file); + //DEBUG("FT1000:download:c_file = 0x%8x\n", (int)c_file); + state = STATE_CODE_DWNLD; pft1000info->fcodeldr = 1; break; case REQUEST_CODE_SEGMENT: @@ -893,17 +893,17 @@ u16 scram_dnldr(struct ft1000_device *ft1000dev, void *pFileStart, u32 FileLeng if (word_length > MAX_LENGTH) { DEBUG("FT1000:download:Download error: Max length exceeded\n"); - Status = STATUS_FAILURE; + status = STATUS_FAILURE; break; } - if ( (word_length*2 + pUcFile) > pBootEnd) + if ( (word_length*2 + c_file) > boot_end) { /* * Error, beyond boot code range. */ DEBUG("FT1000:download:Download error: Requested len=%d exceeds BOOT code boundry.\n", (int)word_length); - Status = STATUS_FAILURE; + status = STATUS_FAILURE; break; } /* @@ -914,12 +914,12 @@ u16 scram_dnldr(struct ft1000_device *ft1000dev, void *pFileStart, u32 FileLeng word_length++; word_length = word_length / 2; - Status = write_blk(ft1000dev, &pUsFile, &pUcFile, word_length); - //DEBUG("write_blk returned %d\n", Status); + status = write_blk(ft1000dev, &s_file, &c_file, word_length); + //DEBUG("write_blk returned %d\n", status); break; default: DEBUG("FT1000:download:Download error: Bad request type=%d in BOOT download state.\n",request); - Status = STATUS_FAILURE; + status = STATUS_FAILURE; break; } if (pft1000info->usbboot) @@ -930,7 +930,7 @@ u16 scram_dnldr(struct ft1000_device *ft1000dev, void *pFileStart, u32 FileLeng else { DEBUG("FT1000:download:Download error: Handshake failed\n"); - Status = STATUS_FAILURE; + status = STATUS_FAILURE; } break; @@ -959,7 +959,7 @@ u16 scram_dnldr(struct ft1000_device *ft1000dev, void *pFileStart, u32 FileLeng break; case REQUEST_RUN_ADDRESS: DEBUG("FT1000:download: REQUEST_RUN_ADDRESS\n"); - if (bGoodVersion) + if (correct_version) { DEBUG("FT1000:download:run_address = 0x%8x\n", (int)run_address); put_request_value(ft1000dev, run_address); @@ -967,13 +967,13 @@ u16 scram_dnldr(struct ft1000_device *ft1000dev, void *pFileStart, u32 FileLeng else { DEBUG("FT1000:download:Download error: Got Run address request before image offset request.\n"); - Status = STATUS_FAILURE; + status = STATUS_FAILURE; break; } break; case REQUEST_CODE_LENGTH: DEBUG("FT1000:download:REQUEST_CODE_LENGTH\n"); - if (bGoodVersion) + if (correct_version) { DEBUG("FT1000:download:run_size = 0x%8x\n", (int)run_size); put_request_value(ft1000dev, run_size); @@ -981,23 +981,23 @@ u16 scram_dnldr(struct ft1000_device *ft1000dev, void *pFileStart, u32 FileLeng else { DEBUG("FT1000:download:Download error: Got Size request before image offset request.\n"); - Status = STATUS_FAILURE; + status = STATUS_FAILURE; break; } break; case REQUEST_DONE_CL: pft1000info->usbboot = 3; /* Reposition ptrs to beginning of provisioning section */ - pUsFile = (u16 *)(pFileStart + pFileHdr5->commands_offset); - pUcFile = (u8 *)(pFileStart + pFileHdr5->commands_offset); - uiState = STATE_DONE_DWNLD; + s_file = (u16 *)(pFileStart + file_hdr->commands_offset); + c_file = (u8 *)(pFileStart + file_hdr->commands_offset); + state = STATE_DONE_DWNLD; break; case REQUEST_CODE_SEGMENT: //DEBUG("FT1000:download: REQUEST_CODE_SEGMENT - CODELOADER\n"); - if (!bGoodVersion) + if (!correct_version) { DEBUG("FT1000:download:Download error: Got Code Segment request before image offset request.\n"); - Status = STATUS_FAILURE; + status = STATUS_FAILURE; break; } #if 0 @@ -1011,17 +1011,17 @@ u16 scram_dnldr(struct ft1000_device *ft1000dev, void *pFileStart, u32 FileLeng #endif { DEBUG("FT1000:download:Download error: Max length exceeded\n"); - Status = STATUS_FAILURE; + status = STATUS_FAILURE; break; } - if ( (word_length*2 + pUcFile) > pCodeEnd) + if ( (word_length*2 + c_file) > code_end) { /* * Error, beyond boot code range. */ DEBUG("FT1000:download:Download error: Requested len=%d exceeds DSP code boundry.\n", (int)word_length); - Status = STATUS_FAILURE; + status = STATUS_FAILURE; break; } /* @@ -1032,7 +1032,7 @@ u16 scram_dnldr(struct ft1000_device *ft1000dev, void *pFileStart, u32 FileLeng word_length++; word_length = word_length / 2; - write_blk_fifo (ft1000dev, &pUsFile, &pUcFile, word_length); + write_blk_fifo (ft1000dev, &s_file, &c_file, word_length); if (pft1000info->usbboot == 0) pft1000info->usbboot++; if (pft1000info->usbboot == 1) { @@ -1047,13 +1047,13 @@ u16 scram_dnldr(struct ft1000_device *ft1000dev, void *pFileStart, u32 FileLeng // Convert length from byte count to word count. Make sure we round up. word_length = (long)(pft1000info->DSPInfoBlklen + 1)/2; put_request_value(ft1000dev, word_length); - pMailBoxData = (struct drv_msg *)&(pft1000info->DSPInfoBlk[0]); + mailbox_data = (struct drv_msg *)&(pft1000info->DSPInfoBlk[0]); /* * Position ASIC DPRAM auto-increment pointer. */ - pUsData = (u16 *)&pMailBoxData->data[0]; + data = (u16 *)&mailbox_data->data[0]; dpram = (u16)DWNLD_MAG1_PS_HDR_LOC; if (word_length & 0x1) word_length++; @@ -1064,22 +1064,22 @@ u16 scram_dnldr(struct ft1000_device *ft1000dev, void *pFileStart, u32 FileLeng for (; word_length > 0; word_length--) /* In words */ { - templong = *pUsData++; - templong |= (*pUsData++ << 16); - Status = fix_ft1000_write_dpram32 (ft1000dev, dpram++, (u8 *)&templong); + templong = *data++; + templong |= (*data++ << 16); + status = fix_ft1000_write_dpram32 (ft1000dev, dpram++, (u8 *)&templong); } break; case REQUEST_VERSION_INFO: DEBUG("FT1000:download:REQUEST_VERSION_INFO\n"); - word_length = pFileHdr5->version_data_size; + word_length = file_hdr->version_data_size; put_request_value(ft1000dev, word_length); /* * Position ASIC DPRAM auto-increment pointer. */ - pUsFile = (u16 *)(pFileStart + pFileHdr5->version_data_offset); + s_file = (u16 *)(pFileStart + file_hdr->version_data_offset); dpram = (u16)DWNLD_MAG1_PS_HDR_LOC; @@ -1092,59 +1092,59 @@ u16 scram_dnldr(struct ft1000_device *ft1000dev, void *pFileStart, u32 FileLeng for (; word_length > 0; word_length--) /* In words */ { - templong = ntohs(*pUsFile++); - temp = ntohs(*pUsFile++); + templong = ntohs(*s_file++); + temp = ntohs(*s_file++); templong |= (temp << 16); - Status = fix_ft1000_write_dpram32 (ft1000dev, dpram++, (u8 *)&templong); + status = fix_ft1000_write_dpram32 (ft1000dev, dpram++, (u8 *)&templong); } break; case REQUEST_CODE_BY_VERSION: DEBUG("FT1000:download:REQUEST_CODE_BY_VERSION\n"); - bGoodVersion = FALSE; + correct_version = FALSE; requested_version = get_request_value(ft1000dev); - pDspImageInfoV6 = (struct dsp_image_info *)(pFileStart + sizeof(struct dsp_file_hdr )); + dsp_img_info = (struct dsp_image_info *)(pFileStart + sizeof(struct dsp_file_hdr )); - for (imageN = 0; imageN < pFileHdr5->nDspImages; imageN++) + for (image = 0; image < file_hdr->nDspImages; image++) { - temp = (u16)(pDspImageInfoV6->version); + temp = (u16)(dsp_img_info->version); templong = temp; - temp = (u16)(pDspImageInfoV6->version >> 16); + temp = (u16)(dsp_img_info->version >> 16); templong |= (temp << 16); if (templong == (u32)requested_version) { - bGoodVersion = TRUE; - DEBUG("FT1000:download: bGoodVersion is TRUE\n"); - pUsFile = (u16 *)(pFileStart + pDspImageInfoV6->begin_offset); - pUcFile = (u8 *)(pFileStart + pDspImageInfoV6->begin_offset); - pCodeEnd = (u8 *)(pFileStart + pDspImageInfoV6->end_offset); - run_address = pDspImageInfoV6->run_address; - run_size = pDspImageInfoV6->image_size; - image_chksum = (u32)pDspImageInfoV6->checksum; + correct_version = TRUE; + DEBUG("FT1000:download: correct_version is TRUE\n"); + s_file = (u16 *)(pFileStart + dsp_img_info->begin_offset); + c_file = (u8 *)(pFileStart + dsp_img_info->begin_offset); + code_end = (u8 *)(pFileStart + dsp_img_info->end_offset); + run_address = dsp_img_info->run_address; + run_size = dsp_img_info->image_size; + image_chksum = (u32)dsp_img_info->checksum; break; } - pDspImageInfoV6++; + dsp_img_info++; } //end of for - if (!bGoodVersion) + if (!correct_version) { /* * Error, beyond boot code range. */ DEBUG("FT1000:download:Download error: Bad Version Request = 0x%x.\n",(int)requested_version); - Status = STATUS_FAILURE; + status = STATUS_FAILURE; break; } break; default: DEBUG("FT1000:download:Download error: Bad request type=%d in CODE download state.\n",request); - Status = STATUS_FAILURE; + status = STATUS_FAILURE; break; } if (pft1000info->usbboot) @@ -1155,94 +1155,94 @@ u16 scram_dnldr(struct ft1000_device *ft1000dev, void *pFileStart, u32 FileLeng else { DEBUG("FT1000:download:Download error: Handshake failed\n"); - Status = STATUS_FAILURE; + status = STATUS_FAILURE; } break; case STATE_DONE_DWNLD: DEBUG("FT1000:download:Code loader is done...\n"); - uiState = STATE_SECTION_PROV; + state = STATE_SECTION_PROV; break; case STATE_SECTION_PROV: DEBUG("FT1000:download:STATE_SECTION_PROV\n"); - pHdr = (struct pseudo_hdr *)pUcFile; + pseudo_header = (struct pseudo_hdr *)c_file; - if (pHdr->checksum == hdr_checksum(pHdr)) + if (pseudo_header->checksum == hdr_checksum(pseudo_header)) { - if (pHdr->portdest != 0x80 /* Dsp OAM */) + if (pseudo_header->portdest != 0x80 /* Dsp OAM */) { - uiState = STATE_DONE_PROV; + state = STATE_DONE_PROV; break; } - usHdrLength = ntohs(pHdr->length); /* Byte length for PROV records */ + pseudo_header_len = ntohs(pseudo_header->length); /* Byte length for PROV records */ // Get buffer for provisioning data - pbuffer = kmalloc((usHdrLength + sizeof(struct pseudo_hdr)), GFP_ATOMIC); + pbuffer = kmalloc((pseudo_header_len + sizeof(struct pseudo_hdr)), GFP_ATOMIC); if (pbuffer) { - memcpy(pbuffer, (void *)pUcFile, (u32)(usHdrLength + sizeof(struct pseudo_hdr))); + memcpy(pbuffer, (void *)c_file, (u32)(pseudo_header_len + sizeof(struct pseudo_hdr))); // link provisioning data pprov_record = kmalloc(sizeof(struct prov_record), GFP_ATOMIC); if (pprov_record) { pprov_record->pprov_data = pbuffer; list_add_tail (&pprov_record->list, &pft1000info->prov_list); // Move to next entry if available - pUcFile = (u8 *)((unsigned long)pUcFile + (u32)((usHdrLength + 1) & 0xFFFFFFFE) + sizeof(struct pseudo_hdr)); - if ( (unsigned long)(pUcFile) - (unsigned long)(pFileStart) >= (unsigned long)FileLength) { - uiState = STATE_DONE_FILE; + c_file = (u8 *)((unsigned long)c_file + (u32)((pseudo_header_len + 1) & 0xFFFFFFFE) + sizeof(struct pseudo_hdr)); + if ( (unsigned long)(c_file) - (unsigned long)(pFileStart) >= (unsigned long)FileLength) { + state = STATE_DONE_FILE; } } else { kfree(pbuffer); - Status = STATUS_FAILURE; + status = STATUS_FAILURE; } } else { - Status = STATUS_FAILURE; + status = STATUS_FAILURE; } } else { /* Checksum did not compute */ - Status = STATUS_FAILURE; + status = STATUS_FAILURE; } - DEBUG("ft1000:download: after STATE_SECTION_PROV, uiState = %d, Status= %d\n", uiState, Status); + DEBUG("ft1000:download: after STATE_SECTION_PROV, state = %d, status= %d\n", state, status); break; case STATE_DONE_PROV: DEBUG("FT1000:download:STATE_DONE_PROV\n"); - uiState = STATE_DONE_FILE; + state = STATE_DONE_FILE; break; default: - Status = STATUS_FAILURE; + status = STATUS_FAILURE; break; } /* End Switch */ - if (Status != STATUS_SUCCESS) { + if (status != STATUS_SUCCESS) { break; } /**** // Check if Card is present - Status = Harley_Read_Register(&temp, FT1000_REG_SUP_IMASK); - if ( (Status != NDIS_STATUS_SUCCESS) || (temp == 0x0000) ) { + status = Harley_Read_Register(&temp, FT1000_REG_SUP_IMASK); + if ( (status != NDIS_STATUS_SUCCESS) || (temp == 0x0000) ) { break; } - Status = Harley_Read_Register(&temp, FT1000_REG_ASIC_ID); - if ( (Status != NDIS_STATUS_SUCCESS) || (temp == 0xffff) ) { + status = Harley_Read_Register(&temp, FT1000_REG_ASIC_ID); + if ( (status != NDIS_STATUS_SUCCESS) || (temp == 0xffff) ) { break; } ****/ } /* End while */ - DEBUG("Download exiting with status = 0x%8x\n", Status); + DEBUG("Download exiting with status = 0x%8x\n", status); ft1000_write_register(ft1000dev, FT1000_DB_DNLD_TX, FT1000_REG_DOORBELL); - return Status; + return status; } -- cgit v1.2.3 From 91cda632ebc6ea84fd7a45efb6d4452c34985731 Mon Sep 17 00:00:00 2001 From: Marek Belisko Date: Tue, 14 Dec 2010 14:02:55 +0100 Subject: staging: ft1000: Fix kernel panic when use ioctl. During ioctl testing was observed kernel panic beuase file->private_data pointer was not correctly set when debugfs file was created. Add correct pointer setup. Signed-off-by: Marek Belisko Signed-off-by: Greg Kroah-Hartman --- drivers/staging/ft1000/ft1000-usb/ft1000_debug.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/drivers/staging/ft1000/ft1000-usb/ft1000_debug.c b/drivers/staging/ft1000/ft1000-usb/ft1000_debug.c index e39809229d46..149ba59f96bf 100644 --- a/drivers/staging/ft1000/ft1000-usb/ft1000_debug.c +++ b/drivers/staging/ft1000/ft1000-usb/ft1000_debug.c @@ -174,7 +174,7 @@ int ft1000_create_dev(struct ft1000_device *dev) } file = debugfs_create_file("device", S_IRUGO | S_IWUSR, dir, - NULL, &ft1000fops); + dev, &ft1000fops); if (IS_ERR(file)) { result = PTR_ERR(file); goto debug_file_fail; @@ -398,7 +398,6 @@ static long ft1000_ioctl (struct file *file, unsigned int command, unsigned long argument) { void __user *argp = (void __user *)argument; - struct net_device *dev; struct ft1000_info *info; struct ft1000_device *ft1000dev; int result=0; @@ -428,9 +427,8 @@ static long ft1000_ioctl (struct file *file, unsigned int command, //DEBUG("FT1000:ft1000_ioctl:command = 0x%x argument = 0x%8x\n", command, (u32)argument); - dev = file->private_data; - info = netdev_priv(dev); - ft1000dev = info->pFt1000Dev; + info = file->private_data; + ft1000dev = info->pFt1000Dev; cmd = _IOC_NR(command); //DEBUG("FT1000:ft1000_ioctl:cmd = 0x%x\n", cmd); -- cgit v1.2.3 From 3555a4c35e59c0217983f5df0cfe39a9fa65c2df Mon Sep 17 00:00:00 2001 From: Xenofon Foukas Date: Wed, 15 Dec 2010 00:14:30 +0200 Subject: Staging: comedi: Fix coding style issues in ii_pci20kc.c This patch fixes the following issues in file ii_pci20kc.c: WARNING: please, no space before tabs WARNING: unnecessary whitespace before a quoted newline WARNING: line over 80 characters Signed-off-by: Xenofon Foukas Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/ii_pci20kc.c | 66 ++++++++++++++++++++--------- 1 file changed, 46 insertions(+), 20 deletions(-) diff --git a/drivers/staging/comedi/drivers/ii_pci20kc.c b/drivers/staging/comedi/drivers/ii_pci20kc.c index 39a6a850d63c..e4711ef54719 100644 --- a/drivers/staging/comedi/drivers/ii_pci20kc.c +++ b/drivers/staging/comedi/drivers/ii_pci20kc.c @@ -19,7 +19,7 @@ * - 16 bit * * only ONE PCI-20341 module possible - * only ONE PCI-20006 module possible + * only ONE PCI-20006 module possible * no extern trigger implemented * * NOT WORKING (but soon) only 4 on-board differential channels supported @@ -83,11 +83,11 @@ options for PCI-20341M: #include "../comedidev.h" #define PCI20000_ID 0x1d -#define PCI20341_ID 0x77 -#define PCI20006_ID 0xe3 +#define PCI20341_ID 0x77 +#define PCI20006_ID 0xe3 #define PCI20xxx_EMPTY_ID 0xff -#define PCI20000_OFFSET 0x100 +#define PCI20000_OFFSET 0x100 #define PCI20000_MODULES 3 #define PCI20000_DIO_0 0x80 @@ -246,7 +246,7 @@ static int pci20xxx_attach(struct comedi_device *dev, pci20006_init(dev, s, it->options[2 * i + 2], it->options[2 * i + 3]); printk(KERN_INFO "comedi%d: " - "ii_pci20kc PCI-20006 module in slot %d \n", + "ii_pci20kc PCI-20006 module in slot %d\n", dev->minor, i + 1); break; case PCI20341_ID: @@ -255,7 +255,7 @@ static int pci20xxx_attach(struct comedi_device *dev, pci20341_init(dev, s, it->options[2 * i + 2], it->options[2 * i + 3]); printk(KERN_INFO "comedi%d: " - "ii_pci20kc PCI-20341 module in slot %d \n", + "ii_pci20kc PCI-20341 module in slot %d\n", dev->minor, i + 1); break; default: @@ -376,9 +376,20 @@ static int pci20341_insn_read(struct comedi_device *dev, static const int pci20341_timebase[] = { 0x00, 0x00, 0x00, 0x04 }; static const int pci20341_settling_time[] = { 0x58, 0x58, 0x93, 0x99 }; -static const struct comedi_lrange range_bipolar0_5 = { 1, {BIP_RANGE(0.5)} }; -static const struct comedi_lrange range_bipolar0_05 = { 1, {BIP_RANGE(0.05)} }; -static const struct comedi_lrange range_bipolar0_025 = { 1, {BIP_RANGE(0.025)} }; +static const struct comedi_lrange range_bipolar0_5 = { + 1, + {BIP_RANGE(0.5)} +}; + +static const struct comedi_lrange range_bipolar0_05 = { + 1, + {BIP_RANGE(0.05)} +}; + +static const struct comedi_lrange range_bipolar0_025 = { + 1, + {BIP_RANGE(0.025)} +}; static const struct comedi_lrange *const pci20341_ranges[] = { &range_bipolar5, @@ -408,12 +419,18 @@ static int pci20341_init(struct comedi_device *dev, struct comedi_subdevice *s, s->maxdata = 0xffff; s->range_table = pci20341_ranges[opt0]; - option = sdp->pci20341.timebase | PCI20341_REPMODE; /* depends on gain, trigger, repetition mode */ - - writeb(PCI20341_INIT, sdp->iobase + PCI20341_CONFIG_REG); /* initialize Module */ - writeb(PCI20341_PACER, sdp->iobase + PCI20341_MOD_STATUS); /* set Pacer */ - writeb(option, sdp->iobase + PCI20341_OPT_REG); /* option register */ - writeb(sdp->pci20341.settling_time, sdp->iobase + PCI20341_SET_TIME_REG); /* settling time counter */ + /* depends on gain, trigger, repetition mode */ + option = sdp->pci20341.timebase | PCI20341_REPMODE; + + /* initialize Module */ + writeb(PCI20341_INIT, sdp->iobase + PCI20341_CONFIG_REG); + /* set Pacer */ + writeb(PCI20341_PACER, sdp->iobase + PCI20341_MOD_STATUS); + /* option register */ + writeb(option, sdp->iobase + PCI20341_OPT_REG); + /* settling time counter */ + writeb(sdp->pci20341.settling_time, + sdp->iobase + PCI20341_SET_TIME_REG); /* trigger not implemented */ return 0; } @@ -429,11 +446,15 @@ static int pci20341_insn_read(struct comedi_device *dev, unsigned int clb; /* channel list byte */ unsigned int boarddata; - writeb(1, sdp->iobase + PCI20341_LCHAN_ADDR_REG); /* write number of input channels */ + /* write number of input channels */ + writeb(1, sdp->iobase + PCI20341_LCHAN_ADDR_REG); clb = PCI20341_DAISY_CHAIN | PCI20341_MUX | (sdp->pci20341.ai_gain << 3) | CR_CHAN(insn->chanspec); writeb(clb, sdp->iobase + PCI20341_CHAN_LIST); - writeb(0x00, sdp->iobase + PCI20341_CC_RESET); /* reset settling time counter and trigger delay counter */ + + /* reset settling time counter and trigger delay counter */ + writeb(0x00, sdp->iobase + PCI20341_CC_RESET); + writeb(0x00, sdp->iobase + PCI20341_CHAN_RESET); /* generate Pacer */ @@ -444,9 +465,12 @@ static int pci20341_insn_read(struct comedi_device *dev, * the whole interrupt stuff */ j = 0; - readb(sdp->iobase + PCI20341_SOFT_PACER); /* generate Pacer */ + /* generate Pacer */ + readb(sdp->iobase + PCI20341_SOFT_PACER); + eoc = readb(sdp->iobase + PCI20341_STATUS_REG); - while ((eoc < 0x80) && j < 100) { /* poll Interrupt Flag */ + /* poll Interrupt Flag */ + while ((eoc < 0x80) && j < 100) { j++; eoc = readb(sdp->iobase + PCI20341_STATUS_REG); } @@ -460,7 +484,9 @@ static int pci20341_insn_read(struct comedi_device *dev, lo = readb(sdp->iobase + PCI20341_LDATA); hi = readb(sdp->iobase + PCI20341_LDATA + 1); boarddata = lo + 0x100 * hi; - data[i] = (short)((boarddata + 0x8000) & 0xffff); /* board-data -> comedi-data */ + + /* board-data -> comedi-data */ + data[i] = (short)((boarddata + 0x8000) & 0xffff); } return i; -- cgit v1.2.3 From c9c62f4e2c9b526c5cbade3f3a61f126e6587c16 Mon Sep 17 00:00:00 2001 From: Xenofon Foukas Date: Wed, 15 Dec 2010 19:44:20 +0200 Subject: Staging: comedi: Fix checkpatch.pl issues in file s526.c This patch fixes the following issues in s526.c: WARNING: printk() should include KERN_ facility level WARNING: line over 80 characters ERROR: do not use C99 // comments WARNING: space prohibited between function name and open parenthesis '(' WARNING: braces {} are not necessary for any arm of this statement WARNING: suspect code indent for conditional statements (16, 16) Signed-off-by: Xenofon Foukas Signed-off-by: Greg Kroah-Hartman --- drivers/staging/comedi/drivers/s526.c | 139 ++++++++++++++++++++-------------- 1 file changed, 82 insertions(+), 57 deletions(-) diff --git a/drivers/staging/comedi/drivers/s526.c b/drivers/staging/comedi/drivers/s526.c index 3607aaee4af6..2b34daedc3d7 100644 --- a/drivers/staging/comedi/drivers/s526.c +++ b/drivers/staging/comedi/drivers/s526.c @@ -114,7 +114,7 @@ static const int s526_ports[] = { }; struct counter_mode_register_t { -#if defined (__LITTLE_ENDIAN_BITFIELD) +#if defined(__LITTLE_ENDIAN_BITFIELD) unsigned short coutSource:1; unsigned short coutPolarity:1; unsigned short autoLoadResetRcap:3; @@ -207,7 +207,9 @@ static const struct s526_board s526_boards[] = { /* this structure is for data unique to this hardware driver. If several hardware drivers keep similar information in this structure, - feel free to suggest moving the variable to the struct comedi_device struct. */ + feel free to suggest moving the variable to the struct comedi_device + struct. +*/ struct s526_private { int data; @@ -304,7 +306,7 @@ static int s526_attach(struct comedi_device *dev, struct comedi_devconfig *it) /* int subdev_channel = 0; */ union cmReg cmReg; - printk("comedi%d: s526: ", dev->minor); + printk(KERN_INFO "comedi%d: s526: ", dev->minor); iobase = it->options[0]; if (!iobase || !request_region(iobase, S526_IOSIZE, thisboard->name)) { @@ -317,7 +319,8 @@ static int s526_attach(struct comedi_device *dev, struct comedi_devconfig *it) /*** make it a little quieter, exw, 8/29/06 for (i = 0; i < S526_NUM_PORTS; i++) { - printk("0x%02x: 0x%04x\n", ADDR_REG(s526_ports[i]), inw(ADDR_REG(s526_ports[i]))); + printk("0x%02x: 0x%04x\n", ADDR_REG(s526_ports[i]), + inw(ADDR_REG(s526_ports[i]))); } ***/ @@ -402,7 +405,7 @@ static int s526_attach(struct comedi_device *dev, struct comedi_devconfig *it) s->type = COMEDI_SUBD_UNUSED; } - printk("attached\n"); + printk(KERN_INFO "attached\n"); return 1; @@ -411,7 +414,7 @@ static int s526_attach(struct comedi_device *dev, struct comedi_devconfig *it) /* One-shot (software trigger) */ cmReg.reg.coutSource = 0; /* out RCAP */ cmReg.reg.coutPolarity = 1; /* Polarity inverted */ - cmReg.reg.autoLoadResetRcap = 1; /* Auto load 0:disabled, 1:enabled */ + cmReg.reg.autoLoadResetRcap = 1;/* Auto load 0:disabled, 1:enabled */ cmReg.reg.hwCtEnableSource = 3; /* NOT RCAP */ cmReg.reg.ctEnableCtrl = 2; /* Hardware */ cmReg.reg.clockSource = 2; /* Internal */ @@ -426,10 +429,12 @@ static int s526_attach(struct comedi_device *dev, struct comedi_devconfig *it) outw(0x0001, ADDR_CHAN_REG(REG_C0H, subdev_channel)); outw(0x3C68, ADDR_CHAN_REG(REG_C0L, subdev_channel)); - outw(0x8000, ADDR_CHAN_REG(REG_C0C, subdev_channel)); /* Reset the counter */ - outw(0x4000, ADDR_CHAN_REG(REG_C0C, subdev_channel)); /* Load the counter from PR0 */ - - outw(0x0008, ADDR_CHAN_REG(REG_C0C, subdev_channel)); /* Reset RCAP (fires one-shot) */ + /* Reset the counter */ + outw(0x8000, ADDR_CHAN_REG(REG_C0C, subdev_channel)); + /* Load the counter from PR0 */ + outw(0x4000, ADDR_CHAN_REG(REG_C0C, subdev_channel)); + /* Reset RCAP (fires one-shot) */ + outw(0x0008, ADDR_CHAN_REG(REG_C0C, subdev_channel)); #else @@ -447,11 +452,12 @@ static int s526_attach(struct comedi_device *dev, struct comedi_devconfig *it) cmReg.reg.reserved = 0; n = 0; - printk("Mode reg=0x%04x, 0x%04lx\n", cmReg.value, ADDR_CHAN_REG(REG_C0M, - n)); + printk(KERN_INFO "Mode reg=0x%04x, 0x%04lx\n", + cmReg.value, ADDR_CHAN_REG(REG_C0M, n)); outw(cmReg.value, ADDR_CHAN_REG(REG_C0M, n)); udelay(1000); - printk("Read back mode reg=0x%04x\n", inw(ADDR_CHAN_REG(REG_C0M, n))); + printk(KERN_INFO "Read back mode reg=0x%04x\n", + inw(ADDR_CHAN_REG(REG_C0M, n))); /* Load the pre-load register high word */ /* value = (short) (0x55); */ @@ -466,20 +472,23 @@ static int s526_attach(struct comedi_device *dev, struct comedi_devconfig *it) /* Reset the counter if it is software preload */ if (cmReg.reg.autoLoadResetRcap == 0) { - outw(0x8000, ADDR_CHAN_REG(REG_C0C, n)); /* Reset the counter */ - outw(0x4000, ADDR_CHAN_REG(REG_C0C, n)); /* Load the counter from PR0 */ + /* Reset the counter */ + outw(0x8000, ADDR_CHAN_REG(REG_C0C, n)); + /* Load the counter from PR0 */ + outw(0x4000, ADDR_CHAN_REG(REG_C0C, n)); } outw(cmReg.value, ADDR_CHAN_REG(REG_C0M, n)); udelay(1000); - printk("Read back mode reg=0x%04x\n", inw(ADDR_CHAN_REG(REG_C0M, n))); + printk(KERN_INFO "Read back mode reg=0x%04x\n", + inw(ADDR_CHAN_REG(REG_C0M, n))); #endif - printk("Current registres:\n"); + printk(KERN_INFO "Current registres:\n"); for (i = 0; i < S526_NUM_PORTS; i++) { - printk("0x%02lx: 0x%04x\n", ADDR_REG(s526_ports[i]), - inw(ADDR_REG(s526_ports[i]))); + printk(KERN_INFO "0x%02lx: 0x%04x\n", + ADDR_REG(s526_ports[i]), inw(ADDR_REG(s526_ports[i]))); } return 1; } @@ -494,7 +503,7 @@ static int s526_attach(struct comedi_device *dev, struct comedi_devconfig *it) */ static int s526_detach(struct comedi_device *dev) { - printk("comedi%d: s526: remove\n", dev->minor); + printk(KERN_INFO "comedi%d: s526: remove\n", dev->minor); if (dev->iobase > 0) release_region(dev->iobase, S526_IOSIZE); @@ -513,7 +522,7 @@ static int s526_gpct_rinsn(struct comedi_device *dev, /* Check if (n > 0) */ if (insn->n <= 0) { - printk("s526: INSN_READ: n should be > 0\n"); + printk(KERN_ERR "s526: INSN_READ: n should be > 0\n"); return -EINVAL; } /* Read the low word first */ @@ -522,7 +531,8 @@ static int s526_gpct_rinsn(struct comedi_device *dev, datahigh = inw(ADDR_CHAN_REG(REG_C0H, counter_channel)); data[i] = (int)(datahigh & 0x00FF); data[i] = (data[i] << 16) | (datalow & 0xFFFF); -/* printk("s526 GPCT[%d]: %x(0x%04x, 0x%04x)\n", counter_channel, data[i], datahigh, datalow); */ + /* printk("s526 GPCT[%d]: %x(0x%04x, 0x%04x)\n", + counter_channel, data[i], datahigh, datalow); */ } return i; } @@ -536,7 +546,8 @@ static int s526_gpct_insn_config(struct comedi_device *dev, short value; union cmReg cmReg; -/* printk("s526: GPCT_INSN_CONFIG: Configuring Channel %d\n", subdev_channel); */ + /* printk("s526: GPCT_INSN_CONFIG: Configuring Channel %d\n", + subdev_channel); */ for (i = 0; i < MAX_GPCT_CONFIG_DATA; i++) { devpriv->s526_gpct_config[subdev_channel].data[i] = @@ -554,7 +565,7 @@ static int s526_gpct_insn_config(struct comedi_device *dev, data[2]: Pre-load Register Value data[3]: Conter Control Register */ - printk("s526: GPCT_INSN_CONFIG: Configuring Encoder\n"); + printk(KERN_INFO "s526: GPCT_INSN_CONFIG: Configuring Encoder\n"); devpriv->s526_gpct_config[subdev_channel].app = PositionMeasurement; @@ -563,7 +574,7 @@ static int s526_gpct_insn_config(struct comedi_device *dev, /* One-shot (software trigger) */ cmReg.reg.coutSource = 0; /* out RCAP */ cmReg.reg.coutPolarity = 1; /* Polarity inverted */ - cmReg.reg.autoLoadResetRcap = 0; /* Auto load disabled */ + cmReg.reg.autoLoadResetRcap = 0;/* Auto load disabled */ cmReg.reg.hwCtEnableSource = 3; /* NOT RCAP */ cmReg.reg.ctEnableCtrl = 2; /* Hardware */ cmReg.reg.clockSource = 2; /* Internal */ @@ -578,10 +589,13 @@ static int s526_gpct_insn_config(struct comedi_device *dev, outw(0x0001, ADDR_CHAN_REG(REG_C0H, subdev_channel)); outw(0x3C68, ADDR_CHAN_REG(REG_C0L, subdev_channel)); - outw(0x8000, ADDR_CHAN_REG(REG_C0C, subdev_channel)); /* Reset the counter */ - outw(0x4000, ADDR_CHAN_REG(REG_C0C, subdev_channel)); /* Load the counter from PR0 */ + /* Reset the counter */ + outw(0x8000, ADDR_CHAN_REG(REG_C0C, subdev_channel)); + /* Load the counter from PR0 */ + outw(0x4000, ADDR_CHAN_REG(REG_C0C, subdev_channel)); - outw(0x0008, ADDR_CHAN_REG(REG_C0C, subdev_channel)); /* Reset RCAP (fires one-shot) */ + /* Reset RCAP (fires one-shot) */ + outw(0x0008, ADDR_CHAN_REG(REG_C0C, subdev_channel)); #endif @@ -594,30 +608,34 @@ static int s526_gpct_insn_config(struct comedi_device *dev, /* Reset the counter if it is software preload */ if (cmReg.reg.autoLoadResetRcap == 0) { - outw(0x8000, ADDR_CHAN_REG(REG_C0C, subdev_channel)); /* Reset the counter */ -/* outw(0x4000, ADDR_CHAN_REG(REG_C0C, subdev_channel)); Load the counter from PR0 */ + /* Reset the counter */ + outw(0x8000, ADDR_CHAN_REG(REG_C0C, subdev_channel)); + /* Load the counter from PR0 + * outw(0x4000, ADDR_CHAN_REG(REG_C0C, subdev_channel)); + */ } #else - cmReg.reg.countDirCtrl = 0; /* 0 quadrature, 1 software control */ + /* 0 quadrature, 1 software control */ + cmReg.reg.countDirCtrl = 0; /* data[1] contains GPCT_X1, GPCT_X2 or GPCT_X4 */ - if (insn->data[1] == GPCT_X2) { + if (insn->data[1] == GPCT_X2) cmReg.reg.clockSource = 1; - } else if (insn->data[1] == GPCT_X4) { + else if (insn->data[1] == GPCT_X4) cmReg.reg.clockSource = 2; - } else { + else cmReg.reg.clockSource = 0; - } /* When to take into account the indexpulse: */ - if (insn->data[2] == GPCT_IndexPhaseLowLow) { + /*if (insn->data[2] == GPCT_IndexPhaseLowLow) { } else if (insn->data[2] == GPCT_IndexPhaseLowHigh) { } else if (insn->data[2] == GPCT_IndexPhaseHighLow) { } else if (insn->data[2] == GPCT_IndexPhaseHighHigh) { - } + }*/ /* Take into account the index pulse? */ if (insn->data[3] == GPCT_RESET_COUNTER_ON_INDEX) - cmReg.reg.autoLoadResetRcap = 4; /* Auto load with INDEX^ */ + /* Auto load with INDEX^ */ + cmReg.reg.autoLoadResetRcap = 4; /* Set Counter Mode Register */ cmReg.value = (short)(insn->data[1] & 0xFFFF); @@ -638,8 +656,10 @@ static int s526_gpct_insn_config(struct comedi_device *dev, } /* Reset the counter if it is software preload */ if (cmReg.reg.autoLoadResetRcap == 0) { - outw(0x8000, ADDR_CHAN_REG(REG_C0C, subdev_channel)); /* Reset the counter */ - outw(0x4000, ADDR_CHAN_REG(REG_C0C, subdev_channel)); /* Load the counter from PR0 */ + /* Reset the counter */ + outw(0x8000, ADDR_CHAN_REG(REG_C0C, subdev_channel)); + /* Load the counter from PR0 */ + outw(0x4000, ADDR_CHAN_REG(REG_C0C, subdev_channel)); } #endif break; @@ -652,7 +672,7 @@ static int s526_gpct_insn_config(struct comedi_device *dev, data[3]: Pre-load Register 1 Value data[4]: Conter Control Register */ - printk("s526: GPCT_INSN_CONFIG: Configuring SPG\n"); + printk(KERN_INFO "s526: GPCT_INSN_CONFIG: Configuring SPG\n"); devpriv->s526_gpct_config[subdev_channel].app = SinglePulseGeneration; @@ -697,7 +717,7 @@ static int s526_gpct_insn_config(struct comedi_device *dev, data[3]: Pre-load Register 1 Value data[4]: Conter Control Register */ - printk("s526: GPCT_INSN_CONFIG: Configuring PTG\n"); + printk(KERN_INFO "s526: GPCT_INSN_CONFIG: Configuring PTG\n"); devpriv->s526_gpct_config[subdev_channel].app = PulseTrainGeneration; @@ -735,7 +755,7 @@ static int s526_gpct_insn_config(struct comedi_device *dev, break; default: - printk("s526: unsupported GPCT_insn_config\n"); + printk(KERN_ERR "s526: unsupported GPCT_insn_config\n"); return -EINVAL; break; } @@ -751,20 +771,21 @@ static int s526_gpct_winsn(struct comedi_device *dev, short value; union cmReg cmReg; - printk("s526: GPCT_INSN_WRITE on channel %d\n", subdev_channel); + printk(KERN_INFO "s526: GPCT_INSN_WRITE on channel %d\n", + subdev_channel); cmReg.value = inw(ADDR_CHAN_REG(REG_C0M, subdev_channel)); - printk("s526: Counter Mode Register: %x\n", cmReg.value); + printk(KERN_INFO "s526: Counter Mode Register: %x\n", cmReg.value); /* Check what Application of Counter this channel is configured for */ switch (devpriv->s526_gpct_config[subdev_channel].app) { case PositionMeasurement: - printk("S526: INSN_WRITE: PM\n"); + printk(KERN_INFO "S526: INSN_WRITE: PM\n"); outw(0xFFFF & ((*data) >> 16), ADDR_CHAN_REG(REG_C0H, subdev_channel)); outw(0xFFFF & (*data), ADDR_CHAN_REG(REG_C0L, subdev_channel)); break; case SinglePulseGeneration: - printk("S526: INSN_WRITE: SPG\n"); + printk(KERN_INFO "S526: INSN_WRITE: SPG\n"); outw(0xFFFF & ((*data) >> 16), ADDR_CHAN_REG(REG_C0H, subdev_channel)); outw(0xFFFF & (*data), ADDR_CHAN_REG(REG_C0L, subdev_channel)); @@ -777,14 +798,14 @@ static int s526_gpct_winsn(struct comedi_device *dev, The above periods must be expressed as a multiple of the pulse frequency on the selected source */ - printk("S526: INSN_WRITE: PTG\n"); + printk(KERN_INFO "S526: INSN_WRITE: PTG\n"); if ((insn->data[1] > insn->data[0]) && (insn->data[0] > 0)) { (devpriv->s526_gpct_config[subdev_channel]).data[0] = insn->data[0]; (devpriv->s526_gpct_config[subdev_channel]).data[1] = insn->data[1]; } else { - printk("s526: INSN_WRITE: PTG: Problem with Pulse params -> %d %d\n", + printk(KERN_ERR "s526: INSN_WRITE: PTG: Problem with Pulse params -> %d %d\n", insn->data[0], insn->data[1]); return -EINVAL; } @@ -873,7 +894,7 @@ static int s526_ai_rinsn(struct comedi_device *dev, struct comedi_subdevice *s, if (i == TIMEOUT) { /* printk() should be used instead of printk() * whenever the code can be called from real-time. */ - printk("s526: ADC(0x%04x) timeout\n", + printk(KERN_ERR "s526: ADC(0x%04x) timeout\n", inw(ADDR_REG(REG_ISR))); return -ETIMEDOUT; } @@ -906,11 +927,14 @@ static int s526_ao_winsn(struct comedi_device *dev, struct comedi_subdevice *s, * very useful, but that's how the interface is defined. */ for (i = 0; i < insn->n; i++) { /* a typical programming sequence */ -/* outw(data[i], dev->iobase + REG_ADD); write the data to preload register */ - outw(data[i], ADDR_REG(REG_ADD)); /* write the data to preload register */ + /* write the data to preload register + * outw(data[i], dev->iobase + REG_ADD); + */ + /* write the data to preload register */ + outw(data[i], ADDR_REG(REG_ADD)); devpriv->ao_readback[chan] = data[i]; /* outw(val + 1, dev->iobase + REG_DAC); starts the D/A conversion. */ - outw(val + 1, ADDR_REG(REG_DAC)); /* starts the D/A conversion. */ + outw(val + 1, ADDR_REG(REG_DAC)); /*starts the D/A conversion.*/ } /* return the number of samples read/written */ @@ -954,7 +978,7 @@ static int s526_dio_insn_bits(struct comedi_device *dev, /* on return, data[1] contains the value of the digital * input and output lines. */ - data[1] = inw(ADDR_REG(REG_DIO)) & 0xFF; /* low 8 bits are the data */ + data[1] = inw(ADDR_REG(REG_DIO)) & 0xFF; /* low 8 bits are the data */ /* or we could just return the software copy of the output values if * it was a purely digital output subdevice */ /* data[1]=s->state & 0xFF; */ @@ -969,7 +993,7 @@ static int s526_dio_insn_config(struct comedi_device *dev, int chan = CR_CHAN(insn->chanspec); int group, mask; - printk("S526 DIO insn_config\n"); + printk(KERN_INFO "S526 DIO insn_config\n"); /* The input or output configuration of each digital line is * configured by a special insn_config instruction. chanspec @@ -980,11 +1004,12 @@ static int s526_dio_insn_config(struct comedi_device *dev, mask = 0xF << (group << 2); switch (data[0]) { case INSN_CONFIG_DIO_OUTPUT: - s->state |= 1 << (group + 10); // bit 10/11 set the group 1/2's mode + /* bit 10/11 set the group 1/2's mode */ + s->state |= 1 << (group + 10); s->io_bits |= mask; break; case INSN_CONFIG_DIO_INPUT: - s->state &= ~(1 << (group + 10));// 1 is output, 0 is input. + s->state &= ~(1 << (group + 10)); /* 1 is output, 0 is input. */ s->io_bits &= ~mask; break; case INSN_CONFIG_DIO_QUERY: -- cgit v1.2.3 From ee417a79567030ce726e9627aa52779e47c49ff0 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 13 Dec 2010 16:56:57 -0800 Subject: staging: brcm80211: Remove unused #defines ETHER__LOCALADDR Signed-off-by: Joe Perches Acked-by: Arend van Spriel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/include/proto/ethernet.h | 7 ------- 1 file changed, 7 deletions(-) diff --git a/drivers/staging/brcm80211/include/proto/ethernet.h b/drivers/staging/brcm80211/include/proto/ethernet.h index cc17b428dd3f..a8981f610347 100644 --- a/drivers/staging/brcm80211/include/proto/ethernet.h +++ b/drivers/staging/brcm80211/include/proto/ethernet.h @@ -62,13 +62,6 @@ BWL_PRE_PACKED_STRUCT struct ether_addr { u8 octet[ETHER_ADDR_LEN]; } BWL_POST_PACKED_STRUCT; -#define ETHER_SET_LOCALADDR(ea) (((u8 *)(ea))[0] = (((u8 *)(ea))[0] | 2)) -#define ETHER_IS_LOCALADDR(ea) (((u8 *)(ea))[0] & 2) -#define ETHER_CLR_LOCALADDR(ea) (((u8 *)(ea))[0] = \ - (((u8 *)(ea))[0] & 0xd)) -#define ETHER_TOGGLE_LOCALADDR(ea) (((u8 *)(ea))[0] = \ - (((u8 *)(ea))[0] ^ 2)) - #define ETHER_SET_UNICAST(ea) (((u8 *)(ea))[0] = (((u8 *)(ea))[0] & ~1)) #define ETHER_ISMULTI(ea) (((const u8 *)(ea))[0] & 1) -- cgit v1.2.3 From 3ca5ada504a41d9a8afd1e25f85f11d1761efa5f Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 13 Dec 2010 16:56:58 -0800 Subject: staging: brcm80211: Convert ETHER_IS_MULTI to is_multicast_ether_addr Use the standard kernel function. Change callers to add .octet to addressing to avoid warnings. Add #include where necessary. Signed-off-by: Joe Perches Acked-by: Arend van Spriel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmfmac/dhd_linux.c | 2 +- drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c | 2 +- drivers/staging/brcm80211/brcmfmac/wl_iw.c | 2 +- drivers/staging/brcm80211/include/proto/ethernet.h | 2 -- drivers/staging/brcm80211/sys/wlc_mac80211.c | 16 ++++++++++------ drivers/staging/brcm80211/util/bcmsrom.c | 11 ++++++----- 6 files changed, 19 insertions(+), 16 deletions(-) diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_linux.c b/drivers/staging/brcm80211/brcmfmac/dhd_linux.c index a114deed3134..b37539cd2902 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_linux.c +++ b/drivers/staging/brcm80211/brcmfmac/dhd_linux.c @@ -1032,7 +1032,7 @@ int dhd_sendpkt(dhd_pub_t *dhdp, int ifidx, struct sk_buff *pktbuf) u8 *pktdata = (u8 *) (pktbuf->data); struct ether_header *eh = (struct ether_header *)pktdata; - if (ETHER_ISMULTI(eh->ether_dhost)) + if (is_multicast_ether_addr(eh->ether_dhost)) dhdp->tx_multicast++; if (ntoh16(eh->ether_type) == ETHER_TYPE_802_1X) atomic_inc(&dhd->pend_8021x_cnt); diff --git a/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c index edf300d4ae70..59f7ca53364b 100644 --- a/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c +++ b/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c @@ -1532,7 +1532,7 @@ wl_add_keyext(struct wiphy *wiphy, struct net_device *dev, key.index = (u32) key_idx; /* Instead of bcast for ea address for default wep keys, driver needs it to be Null */ - if (!ETHER_ISMULTI(mac_addr)) + if (!is_multicast_ether_addr(mac_addr)) memcpy((char *)&key.ea, (void *)mac_addr, ETHER_ADDR_LEN); key.len = (u32) params->key_len; /* check for key index change */ diff --git a/drivers/staging/brcm80211/brcmfmac/wl_iw.c b/drivers/staging/brcm80211/brcmfmac/wl_iw.c index d8600bfc304e..2e0eab121e97 100644 --- a/drivers/staging/brcm80211/brcmfmac/wl_iw.c +++ b/drivers/staging/brcm80211/brcmfmac/wl_iw.c @@ -2548,7 +2548,7 @@ wl_iw_set_encodeext(struct net_device *dev, key.len = iwe->key_len; - if (!ETHER_ISMULTI(iwe->addr.sa_data)) + if (!is_multicast_ether_addr(iwe->addr.sa_data)) bcopy((void *)&iwe->addr.sa_data, (char *)&key.ea, ETHER_ADDR_LEN); diff --git a/drivers/staging/brcm80211/include/proto/ethernet.h b/drivers/staging/brcm80211/include/proto/ethernet.h index a8981f610347..a2353a50874e 100644 --- a/drivers/staging/brcm80211/include/proto/ethernet.h +++ b/drivers/staging/brcm80211/include/proto/ethernet.h @@ -64,8 +64,6 @@ BWL_PRE_PACKED_STRUCT struct ether_addr { #define ETHER_SET_UNICAST(ea) (((u8 *)(ea))[0] = (((u8 *)(ea))[0] & ~1)) -#define ETHER_ISMULTI(ea) (((const u8 *)(ea))[0] & 1) - #define ether_cmp(a, b) (!(((short *)a)[0] == ((short *)b)[0]) | \ !(((short *)a)[1] == ((short *)b)[1]) | \ !(((short *)a)[2] == ((short *)b)[2])) diff --git a/drivers/staging/brcm80211/sys/wlc_mac80211.c b/drivers/staging/brcm80211/sys/wlc_mac80211.c index e4a4365f4bf7..24bf64d66227 100644 --- a/drivers/staging/brcm80211/sys/wlc_mac80211.c +++ b/drivers/staging/brcm80211/sys/wlc_mac80211.c @@ -15,6 +15,7 @@ */ #include #include +#include #include #include #include @@ -5802,7 +5803,8 @@ wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, ASSERT(RSPEC_ACTIVE(rspec[k])); rspec[k] = WLC_RATE_1M; } else { - if (WLANTSEL_ENAB(wlc) && !ETHER_ISMULTI(&h->a1)) { + if (WLANTSEL_ENAB(wlc) && + !is_multicast_ether_addr(h->a1.octet)) { /* set tx antenna config */ wlc_antsel_antcfg_get(wlc->asi, false, false, 0, 0, &antcfg, &fbantcfg); @@ -5963,7 +5965,8 @@ wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, plcp[0]; /* DUR field for main rate */ - if ((fc != FC_PS_POLL) && !ETHER_ISMULTI(&h->a1) && !use_rifs) { + if ((fc != FC_PS_POLL) && + !is_multicast_ether_addr(h->a1.octet) && !use_rifs) { durid = wlc_compute_frame_dur(wlc, rspec[0], preamble_type[0], next_frag_len); @@ -5981,7 +5984,7 @@ wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, /* DUR field for fallback rate */ if (fc == FC_PS_POLL) txh->FragDurFallback = h->durid; - else if (ETHER_ISMULTI(&h->a1) || use_rifs) + else if (is_multicast_ether_addr(h->a1.octet) || use_rifs) txh->FragDurFallback = 0; else { durid = wlc_compute_frame_dur(wlc, rspec[1], @@ -5993,7 +5996,7 @@ wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, if (frag == 0) mcl |= TXC_STARTMSDU; - if (!ETHER_ISMULTI(&h->a1)) + if (!is_multicast_ether_addr(h->a1.octet)) mcl |= TXC_IMMEDACK; if (BAND_5G(wlc->band->bandtype)) @@ -6222,7 +6225,7 @@ wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, if (SCB_WME(scb) && qos && wlc->edcf_txop[ac]) { uint frag_dur, dur, dur_fallback; - ASSERT(!ETHER_ISMULTI(&h->a1)); + ASSERT(!is_multicast_ether_addr(h->a1.octet)); /* WME: Update TXOP threshold */ if ((!(tx_info->flags & IEEE80211_TX_CTL_AMPDU)) && (frag == 0)) { @@ -7023,7 +7026,8 @@ void BCMFASTPATH wlc_recv(struct wlc_info *wlc, struct sk_buff *p) if (!is_amsdu) { /* CTS and ACK CTL frames are w/o a2 */ if (FC_TYPE(fc) == FC_TYPE_DATA || FC_TYPE(fc) == FC_TYPE_MNG) { - if ((ETHER_ISNULLADDR(&h->a2) || ETHER_ISMULTI(&h->a2))) { + if ((ETHER_ISNULLADDR(&h->a2) || + is_multicast_ether_addr(h->a2.octet))) { WL_ERROR(("wl%d: %s: dropping a frame with " "invalid src mac address, a2: %pM\n", wlc->pub->unit, __func__, &h->a2)); diff --git a/drivers/staging/brcm80211/util/bcmsrom.c b/drivers/staging/brcm80211/util/bcmsrom.c index 3a0beb93c0b6..8393d58bab57 100644 --- a/drivers/staging/brcm80211/util/bcmsrom.c +++ b/drivers/staging/brcm80211/util/bcmsrom.c @@ -15,6 +15,7 @@ */ #include #include +#include #include #include #include @@ -499,10 +500,10 @@ int srom_parsecis(struct osl_info *osh, u8 *pcis[], uint ciscnt, char **vars, break; default: /* set macaddr if HNBU_MACADDR not seen yet */ - if (eabuf[0] == '\0' - && cis[i] == LAN_NID - && !(ETHER_ISNULLADDR(&cis[i + 2])) - && !(ETHER_ISMULTI(&cis[i + 2]))) { + if (eabuf[0] == '\0' && + cis[i] == LAN_NID && + !(ETHER_ISNULLADDR(&cis[i + 2])) && + !is_multicast_ether_addr(&cis[i + 2])) { ASSERT(cis[i + 1] == ETHER_ADDR_LEN); snprintf(eabuf, sizeof(eabuf), @@ -974,7 +975,7 @@ int srom_parsecis(struct osl_info *osh, u8 *pcis[], uint ciscnt, char **vars, case HNBU_MACADDR: if (!(ETHER_ISNULLADDR(&cis[i + 1])) && - !(ETHER_ISMULTI(&cis[i + 1]))) { + !is_multicast_ether_addr(&cis[i + 1])) { snprintf(eabuf, sizeof(eabuf), "%pM", &cis[i + 1]); -- cgit v1.2.3 From 47c6de7d37619d105de0367aece9ab10288225bc Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 13 Dec 2010 16:56:59 -0800 Subject: staging: brcm80211: Remove unused ether_ #defines and struct These are unused, just remove them. Signed-off-by: Joe Perches Acked-by: Arend van Spriel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/include/proto/ethernet.h | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/drivers/staging/brcm80211/include/proto/ethernet.h b/drivers/staging/brcm80211/include/proto/ethernet.h index a2353a50874e..1b352c5e29b8 100644 --- a/drivers/staging/brcm80211/include/proto/ethernet.h +++ b/drivers/staging/brcm80211/include/proto/ethernet.h @@ -64,17 +64,7 @@ BWL_PRE_PACKED_STRUCT struct ether_addr { #define ETHER_SET_UNICAST(ea) (((u8 *)(ea))[0] = (((u8 *)(ea))[0] & ~1)) -#define ether_cmp(a, b) (!(((short *)a)[0] == ((short *)b)[0]) | \ - !(((short *)a)[1] == ((short *)b)[1]) | \ - !(((short *)a)[2] == ((short *)b)[2])) - -#define ether_copy(s, d) { \ - ((short *)d)[0] = ((short *)s)[0]; \ - ((short *)d)[1] = ((short *)s)[1]; \ - ((short *)d)[2] = ((short *)s)[2]; } - static const struct ether_addr ether_bcast = { {255, 255, 255, 255, 255, 255} }; -static const struct ether_addr ether_null = { {0, 0, 0, 0, 0, 0} }; #define ETHER_ISBCAST(ea) ((((u8 *)(ea))[0] & \ ((u8 *)(ea))[1] & \ -- cgit v1.2.3 From ed9568687e82c56017ca1aacf6eda9902939bf4a Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 13 Dec 2010 16:57:00 -0800 Subject: staging: brcm80211: Convert ETHER_IS to is__ether_addr Use the normal kernel calls and remove the #defines for ETHER_IS_BCAST and ETHER_IS_NULLADDR. Add #include for etherdevice.h where necessary. Signed-off-by: Joe Perches Acked-by: Arend van Spriel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmfmac/wl_iw.c | 3 ++- drivers/staging/brcm80211/include/proto/ethernet.h | 13 ------------- drivers/staging/brcm80211/sys/wlc_bmac.c | 5 +++-- drivers/staging/brcm80211/sys/wlc_mac80211.c | 6 +++--- drivers/staging/brcm80211/util/bcmsrom.c | 4 ++-- 5 files changed, 10 insertions(+), 21 deletions(-) diff --git a/drivers/staging/brcm80211/brcmfmac/wl_iw.c b/drivers/staging/brcm80211/brcmfmac/wl_iw.c index 2e0eab121e97..abf5d743b373 100644 --- a/drivers/staging/brcm80211/brcmfmac/wl_iw.c +++ b/drivers/staging/brcm80211/brcmfmac/wl_iw.c @@ -772,7 +772,8 @@ wl_iw_set_wap(struct net_device *dev, return -EINVAL; } - if (ETHER_ISBCAST(awrq->sa_data) || ETHER_ISNULLADDR(awrq->sa_data)) { + if (is_broadcast_ether_addr(awrq->sa_data) || + is_zero_ether_addr(awrq->sa_data)) { scb_val_t scbval; memset(&scbval, 0, sizeof(scb_val_t)); (void)dev_wlc_ioctl(dev, WLC_DISASSOC, &scbval, diff --git a/drivers/staging/brcm80211/include/proto/ethernet.h b/drivers/staging/brcm80211/include/proto/ethernet.h index 1b352c5e29b8..086b9b962125 100644 --- a/drivers/staging/brcm80211/include/proto/ethernet.h +++ b/drivers/staging/brcm80211/include/proto/ethernet.h @@ -66,19 +66,6 @@ BWL_PRE_PACKED_STRUCT struct ether_addr { static const struct ether_addr ether_bcast = { {255, 255, 255, 255, 255, 255} }; -#define ETHER_ISBCAST(ea) ((((u8 *)(ea))[0] & \ - ((u8 *)(ea))[1] & \ - ((u8 *)(ea))[2] & \ - ((u8 *)(ea))[3] & \ - ((u8 *)(ea))[4] & \ - ((u8 *)(ea))[5]) == 0xff) -#define ETHER_ISNULLADDR(ea) ((((u8 *)(ea))[0] | \ - ((u8 *)(ea))[1] | \ - ((u8 *)(ea))[2] | \ - ((u8 *)(ea))[3] | \ - ((u8 *)(ea))[4] | \ - ((u8 *)(ea))[5]) == 0) - #define ETHER_MOVE_HDR(d, s) \ do { \ struct ether_header t; \ diff --git a/drivers/staging/brcm80211/sys/wlc_bmac.c b/drivers/staging/brcm80211/sys/wlc_bmac.c index dff4f6bf77e2..2baacfd3ba91 100644 --- a/drivers/staging/brcm80211/sys/wlc_bmac.c +++ b/drivers/staging/brcm80211/sys/wlc_bmac.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -1022,8 +1023,8 @@ int wlc_bmac_attach(struct wlc_info *wlc, u16 vendor, u16 device, uint unit, goto fail; } bcm_ether_atoe(macaddr, &wlc_hw->etheraddr); - if (ETHER_ISBCAST((char *)&wlc_hw->etheraddr) || - ETHER_ISNULLADDR((char *)&wlc_hw->etheraddr)) { + if (is_broadcast_ether_addr(wlc_hw->etheraddr.octet) || + is_zero_ether_addr(wlc_hw->etheraddr.octet)) { WL_ERROR(("wl%d: wlc_bmac_attach: bad macaddr %s\n", unit, macaddr)); err = 22; diff --git a/drivers/staging/brcm80211/sys/wlc_mac80211.c b/drivers/staging/brcm80211/sys/wlc_mac80211.c index 24bf64d66227..daa67c9641a8 100644 --- a/drivers/staging/brcm80211/sys/wlc_mac80211.c +++ b/drivers/staging/brcm80211/sys/wlc_mac80211.c @@ -3633,8 +3633,8 @@ _wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, u16 lo; u32 hi; /* group keys in WPA-NONE (IBSS only, AES and TKIP) use a global TXIV */ - if ((bsscfg->WPA_auth & WPA_AUTH_NONE) - && ETHER_ISNULLADDR(&key->ea)) { + if ((bsscfg->WPA_auth & WPA_AUTH_NONE) && + is_zero_ether_addr(key->ea.octet)) { lo = bsscfg->wpa_none_txiv.lo; hi = bsscfg->wpa_none_txiv.hi; } else { @@ -7026,7 +7026,7 @@ void BCMFASTPATH wlc_recv(struct wlc_info *wlc, struct sk_buff *p) if (!is_amsdu) { /* CTS and ACK CTL frames are w/o a2 */ if (FC_TYPE(fc) == FC_TYPE_DATA || FC_TYPE(fc) == FC_TYPE_MNG) { - if ((ETHER_ISNULLADDR(&h->a2) || + if ((is_zero_ether_addr(h->a2.octet) || is_multicast_ether_addr(h->a2.octet))) { WL_ERROR(("wl%d: %s: dropping a frame with " "invalid src mac address, a2: %pM\n", diff --git a/drivers/staging/brcm80211/util/bcmsrom.c b/drivers/staging/brcm80211/util/bcmsrom.c index 8393d58bab57..668dac6d4415 100644 --- a/drivers/staging/brcm80211/util/bcmsrom.c +++ b/drivers/staging/brcm80211/util/bcmsrom.c @@ -502,7 +502,7 @@ int srom_parsecis(struct osl_info *osh, u8 *pcis[], uint ciscnt, char **vars, /* set macaddr if HNBU_MACADDR not seen yet */ if (eabuf[0] == '\0' && cis[i] == LAN_NID && - !(ETHER_ISNULLADDR(&cis[i + 2])) && + !is_zero_ether_addr(&cis[i + 2]) && !is_multicast_ether_addr(&cis[i + 2])) { ASSERT(cis[i + 1] == ETHER_ADDR_LEN); @@ -974,7 +974,7 @@ int srom_parsecis(struct osl_info *osh, u8 *pcis[], uint ciscnt, char **vars, break; case HNBU_MACADDR: - if (!(ETHER_ISNULLADDR(&cis[i + 1])) && + if (!is_zero_ether_addr(&cis[i + 1]) && !is_multicast_ether_addr(&cis[i + 1])) { snprintf(eabuf, sizeof(eabuf), "%pM", &cis[i + 1]); -- cgit v1.2.3 From b8d6307894a73a10be6395b8ed3ffb3cb9255f9d Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 13 Dec 2010 16:57:01 -0800 Subject: staging: brcm80211: Convert ETHER_ADDR_LEN to ETH_ALEN Add an #include of to include/proto/ethernet.h Convert ETHER_ADDR_LEN, remove the #define for ETHER_ADDR_LEN. Signed-off-by: Joe Perches Acked-by: Arend van Spriel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmfmac/dhd_cdc.c | 2 +- drivers/staging/brcm80211/brcmfmac/dhd_common.c | 8 +-- drivers/staging/brcm80211/brcmfmac/dhd_linux.c | 26 +++++----- drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c | 36 +++++++------- drivers/staging/brcm80211/brcmfmac/wl_cfg80211.h | 2 +- drivers/staging/brcm80211/brcmfmac/wl_iw.c | 58 +++++++++++----------- drivers/staging/brcm80211/include/proto/ethernet.h | 17 ++++--- drivers/staging/brcm80211/sys/wl_mac80211.c | 2 +- drivers/staging/brcm80211/sys/wlc_ampdu.c | 2 +- drivers/staging/brcm80211/sys/wlc_bmac.c | 4 +- drivers/staging/brcm80211/sys/wlc_mac80211.c | 18 +++---- drivers/staging/brcm80211/util/bcmsrom.c | 2 +- 12 files changed, 89 insertions(+), 88 deletions(-) diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_cdc.c b/drivers/staging/brcm80211/brcmfmac/dhd_cdc.c index b3fc2a3eb957..b7b527f5024c 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_cdc.c +++ b/drivers/staging/brcm80211/brcmfmac/dhd_cdc.c @@ -477,7 +477,7 @@ int dhd_prot_init(dhd_pub_t *dhd) dhd_os_proto_unblock(dhd); return ret; } - memcpy(dhd->mac.octet, buf, ETHER_ADDR_LEN); + memcpy(dhd->mac.octet, buf, ETH_ALEN); dhd_os_proto_unblock(dhd); diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_common.c b/drivers/staging/brcm80211/brcmfmac/dhd_common.c index 324d020b864e..3dbf72eebd4a 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_common.c +++ b/drivers/staging/brcm80211/brcmfmac/dhd_common.c @@ -1256,7 +1256,7 @@ int dhd_preinit_ioctls(dhd_pub_t *dhd) */ ret = dhd_custom_get_mac_address(ea_addr.octet); if (!ret) { - bcm_mkiovar("cur_etheraddr", (void *)&ea_addr, ETHER_ADDR_LEN, + bcm_mkiovar("cur_etheraddr", (void *)&ea_addr, ETH_ALEN, buf, sizeof(buf)); ret = dhdcdc_set_ioctl(dhd, 0, WLC_SET_VAR, buf, sizeof(buf)); if (ret < 0) { @@ -1264,7 +1264,7 @@ int dhd_preinit_ioctls(dhd_pub_t *dhd) __func__, ret)); } else memcpy(dhd->mac.octet, (void *)&ea_addr, - ETHER_ADDR_LEN); + ETH_ALEN); } #endif /* GET_CUSTOM_MAC_ENABLE */ @@ -1534,7 +1534,7 @@ int dhd_iscan_delete_bss(void *dhdp, void *addr, iscan_buf_t *iscan_skip) break; if (!memcmp - (bi->BSSID.octet, addr, ETHER_ADDR_LEN)) { + (bi->BSSID.octet, addr, ETH_ALEN)) { DHD_ISCAN(("%s: Del BSS[%2.2d:%2.2d] " "%X:%X:%X:%X:%X:%X\n", __func__, l, i, bi->BSSID.octet[0], @@ -1672,7 +1672,7 @@ int dhd_iscan_request(void *dhdp, u16 action) char buf[WLC_IOCTL_SMLEN]; memset(¶ms, 0, sizeof(wl_iscan_params_t)); - memcpy(¶ms.params.bssid, ðer_bcast, ETHER_ADDR_LEN); + memcpy(¶ms.params.bssid, ðer_bcast, ETH_ALEN); params.params.bss_type = DOT11_BSSTYPE_ANY; params.params.scan_type = DOT11_SCANTYPE_ACTIVE; diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_linux.c b/drivers/staging/brcm80211/brcmfmac/dhd_linux.c index b37539cd2902..ec6202b117f9 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_linux.c +++ b/drivers/staging/brcm80211/brcmfmac/dhd_linux.c @@ -210,7 +210,7 @@ typedef struct dhd_if { int idx; /* iface idx in dongle */ int state; /* interface state */ uint subunit; /* subunit */ - u8 mac_addr[ETHER_ADDR_LEN]; /* assigned MAC address */ + u8 mac_addr[ETH_ALEN]; /* assigned MAC address */ bool attached; /* Delayed attachment when unset */ bool txflowcontrol; /* Per interface flow control indicator */ char name[IFNAMSIZ]; /* linux interface name */ @@ -708,7 +708,7 @@ static void _dhd_set_multicast_list(dhd_info_t *dhd, int ifidx) /* Send down the multicast list first. */ - buflen = sizeof("mcast_list") + sizeof(cnt) + (cnt * ETHER_ADDR_LEN); + buflen = sizeof("mcast_list") + sizeof(cnt) + (cnt * ETH_ALEN); bufp = buf = kmalloc(buflen, GFP_ATOMIC); if (!bufp) { DHD_ERROR(("%s: out of memory for mcast_list, cnt %d\n", @@ -726,8 +726,8 @@ static void _dhd_set_multicast_list(dhd_info_t *dhd, int ifidx) netdev_for_each_mc_addr(ha, dev) { if (!cnt) break; - memcpy(bufp, ha->addr, ETHER_ADDR_LEN); - bufp += ETHER_ADDR_LEN; + memcpy(bufp, ha->addr, ETH_ALEN); + bufp += ETH_ALEN; cnt--; } @@ -811,7 +811,7 @@ _dhd_set_mac_address(dhd_info_t *dhd, int ifidx, struct ether_addr *addr) DHD_TRACE(("%s enter\n", __func__)); if (!bcm_mkiovar - ("cur_etheraddr", (char *)addr, ETHER_ADDR_LEN, buf, 32)) { + ("cur_etheraddr", (char *)addr, ETH_ALEN, buf, 32)) { DHD_ERROR(("%s: mkiovar failed for cur_etheraddr\n", dhd_ifname(&dhd->pub, ifidx))); return -1; @@ -827,7 +827,7 @@ _dhd_set_mac_address(dhd_info_t *dhd, int ifidx, struct ether_addr *addr) DHD_ERROR(("%s: set cur_etheraddr failed\n", dhd_ifname(&dhd->pub, ifidx))); } else { - memcpy(dhd->iflist[ifidx]->net->dev_addr, addr, ETHER_ADDR_LEN); + memcpy(dhd->iflist[ifidx]->net->dev_addr, addr, ETH_ALEN); } return ret; @@ -997,7 +997,7 @@ static int dhd_set_mac_address(struct net_device *dev, void *addr) return -1; ASSERT(dhd->sysioc_tsk); - memcpy(&dhd->macvalue, sa->sa_data, ETHER_ADDR_LEN); + memcpy(&dhd->macvalue, sa->sa_data, ETH_ALEN); dhd->set_macaddress = true; up(&dhd->sysioc_sem); @@ -1028,7 +1028,7 @@ int dhd_sendpkt(dhd_pub_t *dhdp, int ifidx, struct sk_buff *pktbuf) return -ENODEV; /* Update multicast statistic */ - if (pktbuf->len >= ETHER_ADDR_LEN) { + if (pktbuf->len >= ETH_ALEN) { u8 *pktdata = (u8 *) (pktbuf->data); struct ether_header *eh = (struct ether_header *)pktdata; @@ -1866,7 +1866,7 @@ static int dhd_open(struct net_device *net) } atomic_set(&dhd->pend_8021x_cnt, 0); - memcpy(net->dev_addr, dhd->pub.mac.octet, ETHER_ADDR_LEN); + memcpy(net->dev_addr, dhd->pub.mac.octet, ETH_ALEN); #ifdef TOE /* Get current TOE mode from dongle */ @@ -1922,7 +1922,7 @@ dhd_add_if(dhd_info_t *dhd, int ifidx, void *handle, char *name, dhd->iflist[ifidx] = ifp; strlcpy(ifp->name, name, IFNAMSIZ); if (mac_addr != NULL) - memcpy(&ifp->mac_addr, mac_addr, ETHER_ADDR_LEN); + memcpy(&ifp->mac_addr, mac_addr, ETH_ALEN); if (handle == NULL) { ifp->state = WLC_E_IF_ADD; @@ -2281,7 +2281,7 @@ int dhd_net_attach(dhd_pub_t *dhdp, int ifidx) { dhd_info_t *dhd = (dhd_info_t *) dhdp->info; struct net_device *net; - u8 temp_addr[ETHER_ADDR_LEN] = { + u8 temp_addr[ETH_ALEN] = { 0x00, 0x90, 0x4c, 0x11, 0x22, 0x33}; DHD_TRACE(("%s: ifidx %d\n", __func__, ifidx)); @@ -2299,7 +2299,7 @@ int dhd_net_attach(dhd_pub_t *dhdp, int ifidx) */ if (ifidx != 0) { /* for virtual interfaces use the primary MAC */ - memcpy(temp_addr, dhd->pub.mac.octet, ETHER_ADDR_LEN); + memcpy(temp_addr, dhd->pub.mac.octet, ETH_ALEN); } @@ -2327,7 +2327,7 @@ int dhd_net_attach(dhd_pub_t *dhdp, int ifidx) dhd->pub.rxsz = net->mtu + net->hard_header_len + dhd->pub.hdrlen; - memcpy(net->dev_addr, temp_addr, ETHER_ADDR_LEN); + memcpy(net->dev_addr, temp_addr, ETH_ALEN); if (register_netdev(net) != 0) { DHD_ERROR(("%s: couldn't register the net device\n", diff --git a/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c index 59f7ca53364b..1e92f2e230fe 100644 --- a/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c +++ b/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c @@ -648,7 +648,7 @@ wl_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev, static void wl_iscan_prep(struct wl_scan_params *params, struct wlc_ssid *ssid) { - memcpy(¶ms->bssid, ðer_bcast, ETHER_ADDR_LEN); + memcpy(¶ms->bssid, ðer_bcast, ETH_ALEN); params->bss_type = DOT11_BSSTYPE_ANY; params->scan_type = 0; params->nprobes = -1; @@ -1044,9 +1044,9 @@ wl_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev, join_params.ssid.SSID_len = htod32(params->ssid_len); if (params->bssid) memcpy(&join_params.params.bssid, params->bssid, - ETHER_ADDR_LEN); + ETH_ALEN); else - memset(&join_params.params.bssid, 0, ETHER_ADDR_LEN); + memset(&join_params.params.bssid, 0, ETH_ALEN); err = wl_dev_ioctl(dev, WLC_SET_SSID, &join_params, sizeof(join_params)); @@ -1373,7 +1373,7 @@ wl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, memcpy(&join_params.ssid.SSID, sme->ssid, join_params.ssid.SSID_len); join_params.ssid.SSID_len = htod32(join_params.ssid.SSID_len); wl_update_prof(wl, NULL, &join_params.ssid, WL_PROF_SSID); - memcpy(&join_params.params.bssid, ðer_bcast, ETHER_ADDR_LEN); + memcpy(&join_params.params.bssid, ðer_bcast, ETH_ALEN); wl_ch_to_chanspec(wl->channel, &join_params, &join_params_size); WL_DBG(("join_param_size %d\n", join_params_size)); @@ -1406,7 +1406,7 @@ wl_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev, act = *(bool *) wl_read_prof(wl, WL_PROF_ACT); if (likely(act)) { scbval.val = reason_code; - memcpy(&scbval.ea, &wl->bssid, ETHER_ADDR_LEN); + memcpy(&scbval.ea, &wl->bssid, ETH_ALEN); scbval.val = htod32(scbval.val); err = wl_dev_ioctl(dev, WLC_DISASSOC, &scbval, sizeof(scb_val_t)); @@ -1533,7 +1533,7 @@ wl_add_keyext(struct wiphy *wiphy, struct net_device *dev, /* Instead of bcast for ea address for default wep keys, driver needs it to be Null */ if (!is_multicast_ether_addr(mac_addr)) - memcpy((char *)&key.ea, (void *)mac_addr, ETHER_ADDR_LEN); + memcpy((char *)&key.ea, (void *)mac_addr, ETH_ALEN); key.len = (u32) params->key_len; /* check for key index change */ if (key.len == 0) { @@ -1826,7 +1826,7 @@ wl_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev, CHECK_SYS_UP(); if (unlikely - (memcmp(mac, wl_read_prof(wl, WL_PROF_BSSID), ETHER_ADDR_LEN))) { + (memcmp(mac, wl_read_prof(wl, WL_PROF_BSSID), ETH_ALEN))) { WL_ERR(("Wrong Mac address\n")); return -ENOENT; } @@ -2029,11 +2029,11 @@ wl_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev, CHECK_SYS_UP(); for (i = 0; i < wl->pmk_list->pmkids.npmkid; i++) if (!memcmp(pmksa->bssid, &wl->pmk_list->pmkids.pmkid[i].BSSID, - ETHER_ADDR_LEN)) + ETH_ALEN)) break; if (i < WL_NUM_PMKIDS_MAX) { memcpy(&wl->pmk_list->pmkids.pmkid[i].BSSID, pmksa->bssid, - ETHER_ADDR_LEN); + ETH_ALEN); memcpy(&wl->pmk_list->pmkids.pmkid[i].PMKID, pmksa->pmkid, WPA2_PMKID_LEN); if (i == wl->pmk_list->pmkids.npmkid) @@ -2064,7 +2064,7 @@ wl_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev, int i; CHECK_SYS_UP(); - memcpy(&pmkid.pmkid[0].BSSID, pmksa->bssid, ETHER_ADDR_LEN); + memcpy(&pmkid.pmkid[0].BSSID, pmksa->bssid, ETH_ALEN); memcpy(&pmkid.pmkid[0].PMKID, pmksa->pmkid, WPA2_PMKID_LEN); WL_DBG(("del_pmksa,IW_PMKSA_REMOVE - PMKID: %pM =\n", @@ -2076,7 +2076,7 @@ wl_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev, for (i = 0; i < wl->pmk_list->pmkids.npmkid; i++) if (!memcmp (pmksa->bssid, &wl->pmk_list->pmkids.pmkid[i].BSSID, - ETHER_ADDR_LEN)) + ETH_ALEN)) break; if ((wl->pmk_list->pmkids.npmkid > 0) @@ -2085,7 +2085,7 @@ wl_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev, for (; i < (wl->pmk_list->pmkids.npmkid - 1); i++) { memcpy(&wl->pmk_list->pmkids.pmkid[i].BSSID, &wl->pmk_list->pmkids.pmkid[i + 1].BSSID, - ETHER_ADDR_LEN); + ETH_ALEN); memcpy(&wl->pmk_list->pmkids.pmkid[i].PMKID, &wl->pmk_list->pmkids.pmkid[i + 1].PMKID, WPA2_PMKID_LEN); @@ -2284,7 +2284,7 @@ static s32 wl_inform_single_bss(struct wl_priv *wl, struct wl_bss_info *bi) else band = wiphy->bands[IEEE80211_BAND_5GHZ]; notif_bss_info->rssi = bi->RSSI; - memcpy(mgmt->bssid, &bi->BSSID, ETHER_ADDR_LEN); + memcpy(mgmt->bssid, &bi->BSSID, ETH_ALEN); mgmt_type = wl->active_scan ? IEEE80211_STYPE_PROBE_RESP : IEEE80211_STYPE_BEACON; if (!memcmp(bi->SSID, sr->ssid.SSID, bi->SSID_len)) { @@ -2579,7 +2579,7 @@ static s32 wl_update_bss_info(struct wl_priv *wl) goto update_bss_info_out; } bi = (struct wl_bss_info *)(wl->extra_buf + 4); - if (unlikely(memcmp(&bi->BSSID, &wl->bssid, ETHER_ADDR_LEN))) { + if (unlikely(memcmp(&bi->BSSID, &wl->bssid, ETH_ALEN))) { err = -EIO; goto update_bss_info_out; } @@ -2631,7 +2631,7 @@ wl_bss_roaming_done(struct wl_priv *wl, struct net_device *ndev, s32 err = 0; wl_get_assoc_ies(wl); - memcpy(&wl->bssid, &e->addr, ETHER_ADDR_LEN); + memcpy(&wl->bssid, &e->addr, ETH_ALEN); wl_update_bss_info(wl); cfg80211_roamed(ndev, (u8 *)&wl->bssid, @@ -2652,7 +2652,7 @@ wl_bss_connect_done(struct wl_priv *wl, struct net_device *ndev, s32 err = 0; wl_get_assoc_ies(wl); - memcpy(&wl->bssid, &e->addr, ETHER_ADDR_LEN); + memcpy(&wl->bssid, &e->addr, ETH_ALEN); wl_update_bss_info(wl); if (test_and_clear_bit(WL_STATUS_CONNECTING, &wl->status)) { cfg80211_connect_result(ndev, @@ -3926,9 +3926,9 @@ wl_update_prof(struct wl_priv *wl, const wl_event_msg_t *e, void *data, break; case WL_PROF_BSSID: if (data) - memcpy(wl->profile->bssid, data, ETHER_ADDR_LEN); + memcpy(wl->profile->bssid, data, ETH_ALEN); else - memset(wl->profile->bssid, 0, ETHER_ADDR_LEN); + memset(wl->profile->bssid, 0, ETH_ALEN); break; case WL_PROF_SEC: memcpy(&wl->profile->sec, data, sizeof(wl->profile->sec)); diff --git a/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.h b/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.h index 770e63f0c8ef..1069e65f8ce6 100644 --- a/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.h +++ b/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.h @@ -237,7 +237,7 @@ struct wl_ibss { struct wl_profile { u32 mode; struct wlc_ssid ssid; - u8 bssid[ETHER_ADDR_LEN]; + u8 bssid[ETH_ALEN]; u16 beacon_interval; u8 dtim_period; struct wl_security sec; diff --git a/drivers/staging/brcm80211/brcmfmac/wl_iw.c b/drivers/staging/brcm80211/brcmfmac/wl_iw.c index abf5d743b373..14580b2ea198 100644 --- a/drivers/staging/brcm80211/brcmfmac/wl_iw.c +++ b/drivers/staging/brcm80211/brcmfmac/wl_iw.c @@ -347,7 +347,7 @@ wl_iw_config_commit(struct net_device *dev, return 0; memset(&bssid, 0, sizeof(struct sockaddr)); - error = dev_wlc_ioctl(dev, WLC_REASSOC, &bssid, ETHER_ADDR_LEN); + error = dev_wlc_ioctl(dev, WLC_REASSOC, &bssid, ETH_ALEN); if (error) { WL_ERROR(("%s: WLC_REASSOC to %s failed\n", __func__, ssid.SSID)); @@ -691,7 +691,7 @@ wl_iw_set_spy(struct net_device *dev, iw->spy_num = min_t(int, ARRAY_SIZE(iw->spy_addr), dwrq->length); for (i = 0; i < iw->spy_num; i++) - memcpy(&iw->spy_addr[i], addr[i].sa_data, ETHER_ADDR_LEN); + memcpy(&iw->spy_addr[i], addr[i].sa_data, ETH_ALEN); memset(iw->spy_qual, 0, sizeof(iw->spy_qual)); return 0; @@ -713,7 +713,7 @@ wl_iw_get_spy(struct net_device *dev, dwrq->length = iw->spy_num; for (i = 0; i < iw->spy_num; i++) { - memcpy(addr[i].sa_data, &iw->spy_addr[i], ETHER_ADDR_LEN); + memcpy(addr[i].sa_data, &iw->spy_addr[i], ETH_ALEN); addr[i].sa_family = AF_UNIX; memcpy(&qual[i], &iw->spy_qual[i], sizeof(struct iw_quality)); iw->spy_qual[i].updated = 0; @@ -786,7 +786,7 @@ wl_iw_set_wap(struct net_device *dev, memcpy(join_params.ssid.SSID, g_ssid.SSID, g_ssid.SSID_len); join_params.ssid.SSID_len = htod32(g_ssid.SSID_len); - memcpy(&join_params.params.bssid, awrq->sa_data, ETHER_ADDR_LEN); + memcpy(&join_params.params.bssid, awrq->sa_data, ETH_ALEN); WL_TRACE(("%s target_channel=%d\n", __func__, g_wl_iw_params.target_channel)); @@ -816,9 +816,9 @@ wl_iw_get_wap(struct net_device *dev, WL_TRACE(("%s: SIOCGIWAP\n", dev->name)); awrq->sa_family = ARPHRD_ETHER; - memset(awrq->sa_data, 0, ETHER_ADDR_LEN); + memset(awrq->sa_data, 0, ETH_ALEN); - (void)dev_wlc_ioctl(dev, WLC_GET_BSSID, awrq->sa_data, ETHER_ADDR_LEN); + (void)dev_wlc_ioctl(dev, WLC_GET_BSSID, awrq->sa_data, ETH_ALEN); return 0; } @@ -841,7 +841,7 @@ wl_iw_mlme(struct net_device *dev, } scbval.val = mlme->reason_code; - bcopy(&mlme->addr.sa_data, &scbval.ea, ETHER_ADDR_LEN); + bcopy(&mlme->addr.sa_data, &scbval.ea, ETH_ALEN); if (mlme->cmd == IW_MLME_DISASSOC) { scbval.val = htod32(scbval.val); @@ -912,7 +912,7 @@ wl_iw_get_aplist(struct net_device *dev, if (!(dtoh16(bi->capability) & DOT11_CAP_ESS)) continue; - memcpy(addr[dwrq->length].sa_data, &bi->BSSID, ETHER_ADDR_LEN); + memcpy(addr[dwrq->length].sa_data, &bi->BSSID, ETH_ALEN); addr[dwrq->length].sa_family = ARPHRD_ETHER; qual[dwrq->length].qual = rssi_to_qual(dtoh16(bi->RSSI)); qual[dwrq->length].level = 0x100 + dtoh16(bi->RSSI); @@ -986,7 +986,7 @@ wl_iw_iscan_get_aplist(struct net_device *dev, continue; memcpy(addr[dwrq->length].sa_data, &bi->BSSID, - ETHER_ADDR_LEN); + ETH_ALEN); addr[dwrq->length].sa_family = ARPHRD_ETHER; qual[dwrq->length].qual = rssi_to_qual(dtoh16(bi->RSSI)); @@ -1017,7 +1017,7 @@ static int wl_iw_iscan_prep(wl_scan_params_t *params, wlc_ssid_t *ssid) { int err = 0; - memcpy(¶ms->bssid, ðer_bcast, ETHER_ADDR_LEN); + memcpy(¶ms->bssid, ðer_bcast, ETH_ALEN); params->bss_type = DOT11_BSSTYPE_ANY; params->scan_type = 0; params->nprobes = -1; @@ -1516,7 +1516,7 @@ wl_iw_get_scan_prep(wl_scan_results_t *list, iwe.cmd = SIOCGIWAP; iwe.u.ap_addr.sa_family = ARPHRD_ETHER; - memcpy(iwe.u.ap_addr.sa_data, &bi->BSSID, ETHER_ADDR_LEN); + memcpy(iwe.u.ap_addr.sa_data, &bi->BSSID, ETH_ALEN); event = IWE_STREAM_ADD_EVENT(info, event, end, &iwe, IW_EV_ADDR_LEN); @@ -1780,14 +1780,14 @@ wl_iw_iscan_get_scan(struct net_device *dev, ASSERT(((unsigned long)bi + dtoh32(bi->length)) <= ((unsigned long)list + WLC_IW_ISCAN_MAXLEN)); - if (event + ETHER_ADDR_LEN + bi->SSID_len + + if (event + ETH_ALEN + bi->SSID_len + IW_EV_UINT_LEN + IW_EV_FREQ_LEN + IW_EV_QUAL_LEN >= end) return -E2BIG; iwe.cmd = SIOCGIWAP; iwe.u.ap_addr.sa_family = ARPHRD_ETHER; memcpy(iwe.u.ap_addr.sa_data, &bi->BSSID, - ETHER_ADDR_LEN); + ETH_ALEN); event = IWE_STREAM_ADD_EVENT(info, event, end, &iwe, IW_EV_ADDR_LEN); @@ -1924,7 +1924,7 @@ wl_iw_set_essid(struct net_device *dev, memcpy(&join_params.ssid.SSID, g_ssid.SSID, g_ssid.SSID_len); join_params.ssid.SSID_len = htod32(g_ssid.SSID_len); - memcpy(&join_params.params.bssid, ðer_bcast, ETHER_ADDR_LEN); + memcpy(&join_params.params.bssid, ðer_bcast, ETH_ALEN); wl_iw_ch_to_chanspec(g_wl_iw_params.target_channel, &join_params, &join_params_size); @@ -2551,7 +2551,7 @@ wl_iw_set_encodeext(struct net_device *dev, if (!is_multicast_ether_addr(iwe->addr.sa_data)) bcopy((void *)&iwe->addr.sa_data, (char *)&key.ea, - ETHER_ADDR_LEN); + ETH_ALEN); if (key.len == 0) { if (iwe->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) { @@ -2657,7 +2657,7 @@ wl_iw_set_pmksa(struct net_device *dev, pmkidptr = &pmkid; bcopy(&iwpmksa->bssid.sa_data[0], - &pmkidptr->pmkid[0].BSSID, ETHER_ADDR_LEN); + &pmkidptr->pmkid[0].BSSID, ETH_ALEN); bcopy(&iwpmksa->pmkid[0], &pmkidptr->pmkid[0].PMKID, WPA2_PMKID_LEN); @@ -2671,7 +2671,7 @@ wl_iw_set_pmksa(struct net_device *dev, for (i = 0; i < pmkid_list.pmkids.npmkid; i++) if (!memcmp (&iwpmksa->bssid.sa_data[0], - &pmkid_list.pmkids.pmkid[i].BSSID, ETHER_ADDR_LEN)) + &pmkid_list.pmkids.pmkid[i].BSSID, ETH_ALEN)) break; if ((pmkid_list.pmkids.npmkid > 0) @@ -2680,7 +2680,7 @@ wl_iw_set_pmksa(struct net_device *dev, for (; i < (pmkid_list.pmkids.npmkid - 1); i++) { bcopy(&pmkid_list.pmkids.pmkid[i + 1].BSSID, &pmkid_list.pmkids.pmkid[i].BSSID, - ETHER_ADDR_LEN); + ETH_ALEN); bcopy(&pmkid_list.pmkids.pmkid[i + 1].PMKID, &pmkid_list.pmkids.pmkid[i].PMKID, WPA2_PMKID_LEN); @@ -2694,12 +2694,12 @@ wl_iw_set_pmksa(struct net_device *dev, for (i = 0; i < pmkid_list.pmkids.npmkid; i++) if (!memcmp (&iwpmksa->bssid.sa_data[0], - &pmkid_list.pmkids.pmkid[i].BSSID, ETHER_ADDR_LEN)) + &pmkid_list.pmkids.pmkid[i].BSSID, ETH_ALEN)) break; if (i < MAXPMKID) { bcopy(&iwpmksa->bssid.sa_data[0], &pmkid_list.pmkids.pmkid[i].BSSID, - ETHER_ADDR_LEN); + ETH_ALEN); bcopy(&iwpmksa->pmkid[0], &pmkid_list.pmkids.pmkid[i].PMKID, WPA2_PMKID_LEN); @@ -3395,34 +3395,34 @@ void wl_iw_event(struct net_device *dev, wl_event_msg_t *e, void *data) switch (event_type) { case WLC_E_TXFAIL: cmd = IWEVTXDROP; - memcpy(wrqu.addr.sa_data, &e->addr, ETHER_ADDR_LEN); + memcpy(wrqu.addr.sa_data, &e->addr, ETH_ALEN); wrqu.addr.sa_family = ARPHRD_ETHER; break; #if WIRELESS_EXT > 14 case WLC_E_JOIN: case WLC_E_ASSOC_IND: case WLC_E_REASSOC_IND: - memcpy(wrqu.addr.sa_data, &e->addr, ETHER_ADDR_LEN); + memcpy(wrqu.addr.sa_data, &e->addr, ETH_ALEN); wrqu.addr.sa_family = ARPHRD_ETHER; cmd = IWEVREGISTERED; break; case WLC_E_DEAUTH_IND: case WLC_E_DISASSOC_IND: cmd = SIOCGIWAP; - memset(wrqu.addr.sa_data, 0, ETHER_ADDR_LEN); + memset(wrqu.addr.sa_data, 0, ETH_ALEN); wrqu.addr.sa_family = ARPHRD_ETHER; - memset(&extra, 0, ETHER_ADDR_LEN); + memset(&extra, 0, ETH_ALEN); break; case WLC_E_LINK: case WLC_E_NDIS_LINK: cmd = SIOCGIWAP; if (!(flags & WLC_EVENT_MSG_LINK)) { - memset(wrqu.addr.sa_data, 0, ETHER_ADDR_LEN); - memset(&extra, 0, ETHER_ADDR_LEN); + memset(wrqu.addr.sa_data, 0, ETH_ALEN); + memset(&extra, 0, ETH_ALEN); WAKE_LOCK_TIMEOUT(iw->pub, WAKE_LOCK_LINK_DOWN_TMOUT, 20 * HZ); } else { - memcpy(wrqu.addr.sa_data, &e->addr, ETHER_ADDR_LEN); + memcpy(wrqu.addr.sa_data, &e->addr, ETH_ALEN); WL_TRACE(("Link UP\n")); } @@ -3465,7 +3465,7 @@ void wl_iw_event(struct net_device *dev, wl_event_msg_t *e, void *data) else micerrevt->flags |= IW_MICFAILURE_PAIRWISE; memcpy(micerrevt->src_addr.sa_data, &e->addr, - ETHER_ADDR_LEN); + ETH_ALEN); micerrevt->src_addr.sa_family = ARPHRD_ETHER; break; @@ -3495,7 +3495,7 @@ void wl_iw_event(struct net_device *dev, wl_event_msg_t *e, void *data) IW_PMKID_CAND_PREAUTH; bcopy(&pmkidcand->BSSID, &iwpmkidcand->bssid.sa_data, - ETHER_ADDR_LEN); + ETH_ALEN); #ifndef SANDGATE2G wireless_send_event(dev, cmd, &wrqu, extra); diff --git a/drivers/staging/brcm80211/include/proto/ethernet.h b/drivers/staging/brcm80211/include/proto/ethernet.h index 086b9b962125..a8638db431db 100644 --- a/drivers/staging/brcm80211/include/proto/ethernet.h +++ b/drivers/staging/brcm80211/include/proto/ethernet.h @@ -17,12 +17,13 @@ #ifndef _NET_ETHERNET_H_ #define _NET_ETHERNET_H_ +#include + #include -#define ETHER_ADDR_LEN 6 #define ETHER_TYPE_LEN 2 #define ETHER_CRC_LEN 4 -#define ETHER_HDR_LEN (ETHER_ADDR_LEN * 2 + ETHER_TYPE_LEN) +#define ETHER_HDR_LEN (ETH_ALEN * 2 + ETHER_TYPE_LEN) #define ETHER_MIN_LEN 64 #define ETHER_MIN_DATA 46 #define ETHER_MAX_LEN 1518 @@ -36,9 +37,9 @@ #define ETHER_TYPE_802_1X 0x888e #define ETHER_TYPE_802_1X_PREAUTH 0x88c7 -#define ETHER_DEST_OFFSET (0 * ETHER_ADDR_LEN) -#define ETHER_SRC_OFFSET (1 * ETHER_ADDR_LEN) -#define ETHER_TYPE_OFFSET (2 * ETHER_ADDR_LEN) +#define ETHER_DEST_OFFSET (0 * ETH_ALEN) +#define ETHER_SRC_OFFSET (1 * ETH_ALEN) +#define ETHER_TYPE_OFFSET (2 * ETH_ALEN) #define ETHER_IS_VALID_LEN(foo) \ ((foo) >= ETHER_MIN_LEN && (foo) <= ETHER_MAX_LEN) @@ -53,13 +54,13 @@ } BWL_PRE_PACKED_STRUCT struct ether_header { - u8 ether_dhost[ETHER_ADDR_LEN]; - u8 ether_shost[ETHER_ADDR_LEN]; + u8 ether_dhost[ETH_ALEN]; + u8 ether_shost[ETH_ALEN]; u16 ether_type; } BWL_POST_PACKED_STRUCT; BWL_PRE_PACKED_STRUCT struct ether_addr { - u8 octet[ETHER_ADDR_LEN]; + u8 octet[ETH_ALEN]; } BWL_POST_PACKED_STRUCT; #define ETHER_SET_UNICAST(ea) (((u8 *)(ea))[0] = (((u8 *)(ea))[0] & ~1)) diff --git a/drivers/staging/brcm80211/sys/wl_mac80211.c b/drivers/staging/brcm80211/sys/wl_mac80211.c index 1e7a29d006be..4ae99749ac70 100644 --- a/drivers/staging/brcm80211/sys/wl_mac80211.c +++ b/drivers/staging/brcm80211/sys/wl_mac80211.c @@ -749,7 +749,7 @@ static struct wl_info *wl_attach(u16 vendor, u16 device, unsigned long regs, goto fail; } - bcopy(&wl->pub->cur_etheraddr, perm, ETHER_ADDR_LEN); + bcopy(&wl->pub->cur_etheraddr, perm, ETH_ALEN); ASSERT(is_valid_ether_addr(perm)); SET_IEEE80211_PERM_ADDR(hw, perm); diff --git a/drivers/staging/brcm80211/sys/wlc_ampdu.c b/drivers/staging/brcm80211/sys/wlc_ampdu.c index c0883d01c51b..0419c528e40e 100644 --- a/drivers/staging/brcm80211/sys/wlc_ampdu.c +++ b/drivers/staging/brcm80211/sys/wlc_ampdu.c @@ -1318,7 +1318,7 @@ void wlc_ampdu_macaddr_upd(struct wlc_info *wlc) /* driver needs to write the ta in the template; ta is at offset 16 */ memset(template, 0, sizeof(template)); - bcopy((char *)wlc->pub->cur_etheraddr.octet, template, ETHER_ADDR_LEN); + bcopy((char *)wlc->pub->cur_etheraddr.octet, template, ETH_ALEN); wlc_write_template_ram(wlc, (T_BA_TPL_BASE + 16), (T_RAM_ACCESS_SZ * 2), template); } diff --git a/drivers/staging/brcm80211/sys/wlc_bmac.c b/drivers/staging/brcm80211/sys/wlc_bmac.c index 2baacfd3ba91..0c2625dc440b 100644 --- a/drivers/staging/brcm80211/sys/wlc_bmac.c +++ b/drivers/staging/brcm80211/sys/wlc_bmac.c @@ -1340,13 +1340,13 @@ void wlc_bmac_wait_for_wake(struct wlc_hw_info *wlc_hw) void wlc_bmac_hw_etheraddr(struct wlc_hw_info *wlc_hw, struct ether_addr *ea) { - bcopy(&wlc_hw->etheraddr, ea, ETHER_ADDR_LEN); + bcopy(&wlc_hw->etheraddr, ea, ETH_ALEN); } void wlc_bmac_set_hw_etheraddr(struct wlc_hw_info *wlc_hw, struct ether_addr *ea) { - bcopy(ea, &wlc_hw->etheraddr, ETHER_ADDR_LEN); + bcopy(ea, &wlc_hw->etheraddr, ETH_ALEN); } int wlc_bmac_bandtype(struct wlc_hw_info *wlc_hw) diff --git a/drivers/staging/brcm80211/sys/wlc_mac80211.c b/drivers/staging/brcm80211/sys/wlc_mac80211.c index daa67c9641a8..407f5ec55230 100644 --- a/drivers/staging/brcm80211/sys/wlc_mac80211.c +++ b/drivers/staging/brcm80211/sys/wlc_mac80211.c @@ -1726,7 +1726,7 @@ void *wlc_attach(void *wl, u16 vendor, u16 device, uint unit, bool piomode, ASSERT(WSEC_MAX_DEFAULT_KEYS == WLC_DEFAULT_KEYS); /* some code depends on packed structures */ - ASSERT(sizeof(struct ether_addr) == ETHER_ADDR_LEN); + ASSERT(sizeof(struct ether_addr) == ETH_ALEN); ASSERT(sizeof(struct ether_header) == ETHER_HDR_LEN); ASSERT(sizeof(d11regs_t) == SI_CORE_SIZE); ASSERT(sizeof(ofdm_phy_hdr_t) == D11_PHY_HDR_LEN); @@ -1839,7 +1839,7 @@ void *wlc_attach(void *wl, u16 vendor, u16 device, uint unit, bool piomode, wlc_bmac_hw_etheraddr(wlc->hw, &wlc->perm_etheraddr); bcopy((char *)&wlc->perm_etheraddr, (char *)&pub->cur_etheraddr, - ETHER_ADDR_LEN); + ETH_ALEN); for (j = 0; j < NBANDS(wlc); j++) { /* Use band 1 for single band 11a */ @@ -3598,7 +3598,7 @@ _wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, key.flags |= WL_PRIMARY_KEY; bcopy(src_key->ea.octet, key.ea.octet, - ETHER_ADDR_LEN); + ETH_ALEN); } bcopy((char *)&key, arg, sizeof(key)); @@ -6031,7 +6031,7 @@ wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, txh->TxFesTimeFallback = htol16(0); /* TxFrameRA */ - bcopy((char *)&h->a1, (char *)&txh->TxFrameRA, ETHER_ADDR_LEN); + bcopy((char *)&h->a1, (char *)&txh->TxFrameRA, ETH_ALEN); /* TxFrameID */ txh->TxFrameID = htol16(frameid); @@ -6118,11 +6118,11 @@ wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, if (use_cts) { rts->fc = htol16(FC_CTS); - bcopy((char *)&h->a2, (char *)&rts->ra, ETHER_ADDR_LEN); + bcopy((char *)&h->a2, (char *)&rts->ra, ETH_ALEN); } else { rts->fc = htol16((u16) FC_RTS); bcopy((char *)&h->a1, (char *)&rts->ra, - 2 * ETHER_ADDR_LEN); + 2 * ETH_ALEN); } /* mainrate @@ -7639,9 +7639,9 @@ wlc_bcn_prb_template(struct wlc_info *wlc, uint type, ratespec_t bcn_rspec, /* A1 filled in by MAC for prb resp, broadcast for bcn */ if (type == FC_BEACON) bcopy((const char *)ðer_bcast, (char *)&h->da, - ETHER_ADDR_LEN); - bcopy((char *)&cfg->cur_etheraddr, (char *)&h->sa, ETHER_ADDR_LEN); - bcopy((char *)&cfg->BSSID, (char *)&h->bssid, ETHER_ADDR_LEN); + ETH_ALEN); + bcopy((char *)&cfg->cur_etheraddr, (char *)&h->sa, ETH_ALEN); + bcopy((char *)&cfg->BSSID, (char *)&h->bssid, ETH_ALEN); /* SEQ filled in by MAC */ diff --git a/drivers/staging/brcm80211/util/bcmsrom.c b/drivers/staging/brcm80211/util/bcmsrom.c index 668dac6d4415..19d45026a5ee 100644 --- a/drivers/staging/brcm80211/util/bcmsrom.c +++ b/drivers/staging/brcm80211/util/bcmsrom.c @@ -505,7 +505,7 @@ int srom_parsecis(struct osl_info *osh, u8 *pcis[], uint ciscnt, char **vars, !is_zero_ether_addr(&cis[i + 2]) && !is_multicast_ether_addr(&cis[i + 2])) { ASSERT(cis[i + 1] == - ETHER_ADDR_LEN); + ETH_ALEN); snprintf(eabuf, sizeof(eabuf), "%pM", &cis[i + 2]); -- cgit v1.2.3 From d659a3ec838866482779f594c4520f553468c492 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 13 Dec 2010 16:57:02 -0800 Subject: staging: brcm80211: Remove ETHER_HDR_LEN, use ETH_HLEN Signed-off-by: Joe Perches Acked-by: Arend van Spriel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/include/proto/ethernet.h | 1 - drivers/staging/brcm80211/sys/wlc_mac80211.c | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/staging/brcm80211/include/proto/ethernet.h b/drivers/staging/brcm80211/include/proto/ethernet.h index a8638db431db..888165e1ab5c 100644 --- a/drivers/staging/brcm80211/include/proto/ethernet.h +++ b/drivers/staging/brcm80211/include/proto/ethernet.h @@ -23,7 +23,6 @@ #define ETHER_TYPE_LEN 2 #define ETHER_CRC_LEN 4 -#define ETHER_HDR_LEN (ETH_ALEN * 2 + ETHER_TYPE_LEN) #define ETHER_MIN_LEN 64 #define ETHER_MIN_DATA 46 #define ETHER_MAX_LEN 1518 diff --git a/drivers/staging/brcm80211/sys/wlc_mac80211.c b/drivers/staging/brcm80211/sys/wlc_mac80211.c index 407f5ec55230..8a89b5fe8e60 100644 --- a/drivers/staging/brcm80211/sys/wlc_mac80211.c +++ b/drivers/staging/brcm80211/sys/wlc_mac80211.c @@ -1727,7 +1727,7 @@ void *wlc_attach(void *wl, u16 vendor, u16 device, uint unit, bool piomode, /* some code depends on packed structures */ ASSERT(sizeof(struct ether_addr) == ETH_ALEN); - ASSERT(sizeof(struct ether_header) == ETHER_HDR_LEN); + ASSERT(sizeof(struct ether_header) == ETH_HLEN); ASSERT(sizeof(d11regs_t) == SI_CORE_SIZE); ASSERT(sizeof(ofdm_phy_hdr_t) == D11_PHY_HDR_LEN); ASSERT(sizeof(cck_phy_hdr_t) == D11_PHY_HDR_LEN); -- cgit v1.2.3 From d7ec915abc98795a4cb88e369e2918696dd0ea01 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 13 Dec 2010 16:57:03 -0800 Subject: staging: brcm80211: Remove unused ETHER_TYPE_ #defines Signed-off-by: Joe Perches Acked-by: Arend van Spriel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/include/proto/ethernet.h | 5 ----- 1 file changed, 5 deletions(-) diff --git a/drivers/staging/brcm80211/include/proto/ethernet.h b/drivers/staging/brcm80211/include/proto/ethernet.h index 888165e1ab5c..ad55b565c847 100644 --- a/drivers/staging/brcm80211/include/proto/ethernet.h +++ b/drivers/staging/brcm80211/include/proto/ethernet.h @@ -28,13 +28,8 @@ #define ETHER_MAX_LEN 1518 #define ETHER_MAX_DATA 1500 -#define ETHER_TYPE_MIN 0x0600 -#define ETHER_TYPE_IP 0x0800 -#define ETHER_TYPE_ARP 0x0806 -#define ETHER_TYPE_8021Q 0x8100 #define ETHER_TYPE_BRCM 0x886c #define ETHER_TYPE_802_1X 0x888e -#define ETHER_TYPE_802_1X_PREAUTH 0x88c7 #define ETHER_DEST_OFFSET (0 * ETH_ALEN) #define ETHER_SRC_OFFSET (1 * ETH_ALEN) -- cgit v1.2.3 From fcbdbed01633bac6271708d86d569e06ed3e4c34 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Mon, 13 Dec 2010 16:57:04 -0800 Subject: staging: brcm80211: Convert ETHER_TYPE_802_1X to ETH_P_PAE Remove now unused #define. Signed-off-by: Joe Perches Acked-by: Arend van Spriel Signed-off-by: Greg Kroah-Hartman --- drivers/staging/brcm80211/brcmfmac/dhd_linux.c | 4 ++-- drivers/staging/brcm80211/include/proto/ethernet.h | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_linux.c b/drivers/staging/brcm80211/brcmfmac/dhd_linux.c index ec6202b117f9..db4508378775 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_linux.c +++ b/drivers/staging/brcm80211/brcmfmac/dhd_linux.c @@ -1034,7 +1034,7 @@ int dhd_sendpkt(dhd_pub_t *dhdp, int ifidx, struct sk_buff *pktbuf) if (is_multicast_ether_addr(eh->ether_dhost)) dhdp->tx_multicast++; - if (ntoh16(eh->ether_type) == ETHER_TYPE_802_1X) + if (ntoh16(eh->ether_type) == ETH_P_PAE) atomic_inc(&dhd->pend_8021x_cnt); } @@ -1262,7 +1262,7 @@ void dhd_txcomplete(dhd_pub_t *dhdp, struct sk_buff *txp, bool success) eh = (struct ether_header *)(txp->data); type = ntoh16(eh->ether_type); - if (type == ETHER_TYPE_802_1X) + if (type == ETH_P_PAE) atomic_dec(&dhd->pend_8021x_cnt); } diff --git a/drivers/staging/brcm80211/include/proto/ethernet.h b/drivers/staging/brcm80211/include/proto/ethernet.h index ad55b565c847..567407de020e 100644 --- a/drivers/staging/brcm80211/include/proto/ethernet.h +++ b/drivers/staging/brcm80211/include/proto/ethernet.h @@ -29,7 +29,6 @@ #define ETHER_MAX_DATA 1500 #define ETHER_TYPE_BRCM 0x886c -#define ETHER_TYPE_802_1X 0x888e #define ETHER_DEST_OFFSET (0 * ETH_ALEN) #define ETHER_SRC_OFFSET (1 * ETH_ALEN) -- cgit v1.2.3 From f8ce33bbd57a0c9c302ebb273fd963c5efb1a264 Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Tue, 14 Dec 2010 17:04:00 +0100 Subject: Staging: IIO: Direct digital synthesis abi documentation Changes since RFC/v1: IIO: Apply list review feedback: Apply list review feedback: Restructure documentation according to list feedback. Rename attributes to fit IIO convention used in other drivers. Fix typos. Provide ddsX_out_enable as opposed to ddsX_out_disable Changes since v2: IIO: sysfs-bus-iio-dds: Apply more list review feedback Fix mixture of X and [n] notation for indices. Fix some wording in the descriptions. Signed-off-by: Michael Hennerich Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- .../staging/iio/Documentation/sysfs-bus-iio-dds | 93 ++++++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 drivers/staging/iio/Documentation/sysfs-bus-iio-dds diff --git a/drivers/staging/iio/Documentation/sysfs-bus-iio-dds b/drivers/staging/iio/Documentation/sysfs-bus-iio-dds new file mode 100644 index 000000000000..ffdd5478a35d --- /dev/null +++ b/drivers/staging/iio/Documentation/sysfs-bus-iio-dds @@ -0,0 +1,93 @@ + +What: /sys/bus/iio/devices/.../ddsX_freqY +KernelVersion: 2.6.37 +Contact: linux-iio@vger.kernel.org +Description: + Stores frequency into tuning word Y. + There will be more than one ddsX_freqY file, which allows for + pin controlled FSK Frequency Shift Keying + (ddsX_pincontrol_freq_en is active) or the user can control + the desired active tuning word by writing Y to the + ddsX_freqsymbol file. + +What: /sys/bus/iio/devices/.../ddsX_freqY_scale +KernelVersion: 2.6.37 +Contact: linux-iio@vger.kernel.org +Description: + Scale to be applied to ddsX_freqY in order to obtain the + desired value in Hz. If shared across all frequency registers + Y is not present. It is also possible X is not present if + shared across all channels. + +What: /sys/bus/iio/devices/.../ddsX_freqsymbol +KernelVersion: 2.6.37 +Contact: linux-iio@vger.kernel.org +Description: + Specifies the active output frequency tuning word. The value + corresponds to the Y in ddsX_freqY. To exit this mode the user + can write ddsX_pincontrol_freq_en or ddsX_out_enable file. + +What: /sys/bus/iio/devices/.../ddsX_phaseY +KernelVersion: 2.6.37 +Contact: linux-iio@vger.kernel.org +Description: + Stores phase into Y. + There will be more than one ddsX_phaseY file, which allows for + pin controlled PSK Phase Shift Keying + (ddsX_pincontrol_phase_en is active) or the user can + control the desired phase Y which is added to the phase + accumulator output by writing Y to the en_phase file. + +What: /sys/bus/iio/devices/.../ddsX_phaseY_scale +KernelVersion: 2.6.37 +Contact: linux-iio@vger.kernel.org +Description: + Scale to be applied to ddsX_phaseY in order to obtain the + desired value in rad. If shared across all phase registers + Y is not present. It is also possible X is not present if + shared across all channels. + +What: /sys/bus/iio/devices/.../ddsX_phasesymbol +KernelVersion: 2.6.37 +Contact: linux-iio@vger.kernel.org +Description: + Specifies the active phase Y which is added to the phase + accumulator output. The value corresponds to the Y in + ddsX_phaseY. To exit this mode the user can write + ddsX_pincontrol_phase_en or disable file. + +What: /sys/bus/iio/devices/.../ddsX_pincontrol_en +What: /sys/bus/iio/devices/.../ddsX_pincontrol_freq_en +What: /sys/bus/iio/devices/.../ddsX_pincontrol_phase_en +KernelVersion: 2.6.37 +Contact: linux-iio@vger.kernel.org +Description: + ddsX_pincontrol_en: Both, the active frequency and phase is + controlled by the respective phase and frequency control inputs. + In case the device in question allows to independent controls, + then there are dedicated files (ddsX_pincontrol_freq_en, + ddsX_pincontrol_phase_en). + +What: /sys/bus/iio/devices/.../ddsX_out_enable +What: /sys/bus/iio/devices/.../ddsX_outY_enable +KernelVersion: 2.6.37 +Contact: linux-iio@vger.kernel.org +Description: + ddsX_outY_enable controls signal generation on output Y of + channel X. Y may be suppressed if all channels are + controlled together. + +What: /sys/bus/iio/devices/.../ddsX_outY_wavetype +KernelVersion: 2.6.37 +Contact: linux-iio@vger.kernel.org +Description: + Specifies the output waveform. + (sine, triangle, ramp, square, ...) + For a list of available output waveform options read + available_output_modes. + +What: /sys/bus/iio/devices/.../ddsX_outY_wavetype_available +KernelVersion: 2.6.37 +Contact: linux-iio@vger.kernel.org +Description: + Lists all available output waveform options. -- cgit v1.2.3 From 4851d97d87c8dfa8c97037965690cdefe99a767d Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Tue, 14 Dec 2010 17:04:01 +0100 Subject: Staging: IIO: dds.h convenience macros Changes since RFC/v1: IIO: Apply list review feedback Apply list review feedback: Rename attributes to fit IIO convention used in other drivers. Provide ddsX_out_enable as opposed to ddsX_out_disable. Fix typos. Changes since v2: IIO: dds.h: Apply more list review feedback Fix mixture of X and [n] notation for indices. Remove duplicated descriptions. Add store methods to some dds convenience macros. Signed-off-by: Michael Hennerich Reviewed-by: Jonathan Cameron Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/dds/dds.h | 110 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 110 insertions(+) create mode 100644 drivers/staging/iio/dds/dds.h diff --git a/drivers/staging/iio/dds/dds.h b/drivers/staging/iio/dds/dds.h new file mode 100644 index 000000000000..d8ac3a93baf6 --- /dev/null +++ b/drivers/staging/iio/dds/dds.h @@ -0,0 +1,110 @@ +/* + * dds.h - sysfs attributes associated with DDS devices + * + * Copyright (c) 2010 Analog Devices Inc. + * + * Licensed under the GPL-2 or later. + */ + +/** + * /sys/bus/iio/devices/.../ddsX_freqY + */ + +#define IIO_DEV_ATTR_FREQ(_channel, _num, _mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(dds##_channel##_freq##_num, \ + _mode, _show, _store, _addr) + +/** + * /sys/bus/iio/devices/.../ddsX_freqY_scale + */ + +#define IIO_CONST_ATTR_FREQ_SCALE(_channel, _string) \ + IIO_CONST_ATTR(dds##_channel##_freq_scale, _string) + +/** + * /sys/bus/iio/devices/.../ddsX_freqsymbol + */ + +#define IIO_DEV_ATTR_FREQSYMBOL(_channel, _mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(dds##_channel##_freqsymbol, \ + _mode, _show, _store, _addr); + +/** + * /sys/bus/iio/devices/.../ddsX_phaseY + */ + +#define IIO_DEV_ATTR_PHASE(_channel, _num, _mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(dds##_channel##_phase##_num, \ + _mode, _show, _store, _addr) + +/** + * /sys/bus/iio/devices/.../ddsX_phaseY_scale + */ + +#define IIO_CONST_ATTR_PHASE_SCALE(_channel, _string) \ + IIO_CONST_ATTR(dds##_channel##_phase_scale, _string) + +/** + * /sys/bus/iio/devices/.../ddsX_phasesymbol + */ + +#define IIO_DEV_ATTR_PHASESYMBOL(_channel, _mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(dds##_channel##_phasesymbol, \ + _mode, _show, _store, _addr); + +/** + * /sys/bus/iio/devices/.../ddsX_pincontrol_en + */ + +#define IIO_DEV_ATTR_PINCONTROL_EN(_channel, _mode, _show, _store, _addr)\ + IIO_DEVICE_ATTR(dds##_channel##_pincontrol_en, \ + _mode, _show, _store, _addr); + +/** + * /sys/bus/iio/devices/.../ddsX_pincontrol_freq_en + */ + +#define IIO_DEV_ATTR_PINCONTROL_FREQ_EN(_channel, _mode, _show, _store, _addr)\ + IIO_DEVICE_ATTR(dds##_channel##_pincontrol_freq_en, \ + _mode, _show, _store, _addr); + +/** + * /sys/bus/iio/devices/.../ddsX_pincontrol_phase_en + */ + +#define IIO_DEV_ATTR_PINCONTROL_PHASE_EN(_channel, _mode, _show, _store, _addr)\ + IIO_DEVICE_ATTR(dds##_channel##_pincontrol_phase_en, \ + _mode, _show, _store, _addr); + +/** + * /sys/bus/iio/devices/.../ddsX_out_enable + */ + +#define IIO_DEV_ATTR_OUT_ENABLE(_channel, _mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(dds##_channel##_out_enable, \ + _mode, _show, _store, _addr); + +/** + * /sys/bus/iio/devices/.../ddsX_outY_enable + */ + +#define IIO_DEV_ATTR_OUTY_ENABLE(_channel, _output, \ + _mode, _show, _store, _addr) \ + IIO_DEVICE_ATTR(dds##_channel##_out##_output##_enable, \ + _mode, _show, _store, _addr); + +/** + * /sys/bus/iio/devices/.../ddsX_outY_wavetype + */ + +#define IIO_DEV_ATTR_OUT_WAVETYPE(_channel, _output, _store, _addr) \ + IIO_DEVICE_ATTR(dds##_channel##_out##_output##_wavetype, \ + S_IWUSR, NULL, _store, _addr); + +/** + * /sys/bus/iio/devices/.../ddsX_outY_wavetype_available + */ + +#define IIO_CONST_ATTR_OUT_WAVETYPES_AVAILABLE(_channel, _output, _modes)\ + IIO_CONST_ATTR(dds##_channel##_out##_output##_wavetype_available,\ + _modes); -- cgit v1.2.3 From 12b9d5bf76bfa20d3207ef24fca9c8254a586a58 Mon Sep 17 00:00:00 2001 From: Michael Hennerich Date: Tue, 14 Dec 2010 17:04:02 +0100 Subject: Staging: IIO: DDS: AD9833 / AD9834 driver Changes since RFC/v1: IIO: Apply list review feedback Apply list review feedback: Rename attributes to fit IIO convention used in other drivers. Fix typos. Provide ddsX_out_enable as opposed to ddsX_out_disable. Use proper __devexit marking. Use strict_strtoul() to avoid negatives. Changes since v2: IIO: ad9834.c: Apply more list review feedback Update use of dds convenience macros. Fix tabbing. Remove superfluous brackets. Keep output disabled after probe. Remove unnecessary code. Signed-off-by: Michael Hennerich Reviewed-by: Datta Shubhrajyoti Acked-by: Jonathan Cameron Signed-off-by: Greg Kroah-Hartman --- drivers/staging/iio/dds/Kconfig | 10 + drivers/staging/iio/dds/Makefile | 1 + drivers/staging/iio/dds/ad9834.c | 477 +++++++++++++++++++++++++++++++++++++++ drivers/staging/iio/dds/ad9834.h | 112 +++++++++ 4 files changed, 600 insertions(+) create mode 100644 drivers/staging/iio/dds/ad9834.c create mode 100644 drivers/staging/iio/dds/ad9834.h diff --git a/drivers/staging/iio/dds/Kconfig b/drivers/staging/iio/dds/Kconfig index 7969be29b0eb..a047da62daf0 100644 --- a/drivers/staging/iio/dds/Kconfig +++ b/drivers/staging/iio/dds/Kconfig @@ -17,6 +17,16 @@ config AD9832 Say yes here to build support for Analog Devices DDS chip ad9832 and ad9835, provides direct access via sysfs. +config AD9834 + tristate "Analog Devices ad9833/4/ driver" + depends on SPI + help + Say yes here to build support for Analog Devices DDS chip + AD9833 and AD9834, provides direct access via sysfs. + + To compile this driver as a module, choose M here: the + module will be called ad9834. + config AD9850 tristate "Analog Devices ad9850/1 driver" depends on SPI diff --git a/drivers/staging/iio/dds/Makefile b/drivers/staging/iio/dds/Makefile index 6f274acb0fcf..147746176b9b 100644 --- a/drivers/staging/iio/dds/Makefile +++ b/drivers/staging/iio/dds/Makefile @@ -4,6 +4,7 @@ obj-$(CONFIG_AD5930) += ad5930.o obj-$(CONFIG_AD9832) += ad9832.o +obj-$(CONFIG_AD9834) += ad9834.o obj-$(CONFIG_AD9850) += ad9850.o obj-$(CONFIG_AD9852) += ad9852.o obj-$(CONFIG_AD9910) += ad9910.o diff --git a/drivers/staging/iio/dds/ad9834.c b/drivers/staging/iio/dds/ad9834.c new file mode 100644 index 000000000000..eb1a681874f9 --- /dev/null +++ b/drivers/staging/iio/dds/ad9834.c @@ -0,0 +1,477 @@ +/* + * AD9834 SPI DAC driver + * + * Copyright 2010 Analog Devices Inc. + * + * Licensed under the GPL-2 or later. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../iio.h" +#include "../sysfs.h" +#include "dds.h" + +#include "ad9834.h" + +static unsigned int ad9834_calc_freqreg(unsigned long mclk, unsigned long fout) +{ + unsigned long long freqreg = (u64) fout * (u64) (1 << AD9834_FREQ_BITS); + do_div(freqreg, mclk); + return freqreg; +} + +static int ad9834_write_frequency(struct ad9834_state *st, + unsigned long addr, unsigned long fout) +{ + unsigned long regval; + + if (fout > (st->mclk / 2)) + return -EINVAL; + + regval = ad9834_calc_freqreg(st->mclk, fout); + + st->freq_data[0] = cpu_to_be16(addr | (regval & + RES_MASK(AD9834_FREQ_BITS / 2))); + st->freq_data[1] = cpu_to_be16(addr | ((regval >> + (AD9834_FREQ_BITS / 2)) & + RES_MASK(AD9834_FREQ_BITS / 2))); + + return spi_sync(st->spi, &st->freq_msg);; +} + +static int ad9834_write_phase(struct ad9834_state *st, + unsigned long addr, unsigned long phase) +{ + if (phase > (1 << AD9834_PHASE_BITS)) + return -EINVAL; + st->data = cpu_to_be16(addr | phase); + + return spi_sync(st->spi, &st->msg); +} + +static ssize_t ad9834_write(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad9834_state *st = dev_info->dev_data; + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + int ret; + long val; + + ret = strict_strtoul(buf, 10, &val); + if (ret) + goto error_ret; + + mutex_lock(&dev_info->mlock); + switch (this_attr->address) { + case AD9834_REG_FREQ0: + case AD9834_REG_FREQ1: + ret = ad9834_write_frequency(st, this_attr->address, val); + break; + case AD9834_REG_PHASE0: + case AD9834_REG_PHASE1: + ret = ad9834_write_phase(st, this_attr->address, val); + break; + case AD9834_OPBITEN: + if (st->control & AD9834_MODE) { + ret = -EINVAL; /* AD9843 reserved mode */ + break; + } + + if (val) + st->control |= AD9834_OPBITEN; + else + st->control &= ~AD9834_OPBITEN; + + st->data = cpu_to_be16(AD9834_REG_CMD | st->control); + ret = spi_sync(st->spi, &st->msg); + break; + case AD9834_PIN_SW: + if (val) + st->control |= AD9834_PIN_SW; + else + st->control &= ~AD9834_PIN_SW; + st->data = cpu_to_be16(AD9834_REG_CMD | st->control); + ret = spi_sync(st->spi, &st->msg); + break; + case AD9834_FSEL: + case AD9834_PSEL: + if (val == 0) + st->control &= ~(this_attr->address | AD9834_PIN_SW); + else if (val == 1) { + st->control |= this_attr->address; + st->control &= ~AD9834_PIN_SW; + } else { + ret = -EINVAL; + break; + } + st->data = cpu_to_be16(AD9834_REG_CMD | st->control); + ret = spi_sync(st->spi, &st->msg); + break; + case AD9834_RESET: + if (val) + st->control &= ~AD9834_RESET; + else + st->control |= AD9834_RESET; + + st->data = cpu_to_be16(AD9834_REG_CMD | st->control); + ret = spi_sync(st->spi, &st->msg); + break; + default: + ret = -ENODEV; + } + mutex_unlock(&dev_info->mlock); + +error_ret: + return ret ? ret : len; +} + +static ssize_t ad9834_store_wavetype(struct device *dev, + struct device_attribute *attr, + const char *buf, + size_t len) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad9834_state *st = dev_info->dev_data; + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + int ret = 0; + bool is_ad9833 = st->devid == ID_AD9833; + + mutex_lock(&dev_info->mlock); + + switch (this_attr->address) { + case 0: + if (sysfs_streq(buf, "sine")) { + st->control &= ~AD9834_MODE; + if (is_ad9833) + st->control &= ~AD9834_OPBITEN; + } else if (sysfs_streq(buf, "triangle")) { + if (is_ad9833) { + st->control &= ~AD9834_OPBITEN; + st->control |= AD9834_MODE; + } else if (st->control & AD9834_OPBITEN) { + ret = -EINVAL; /* AD9843 reserved mode */ + } else { + st->control |= AD9834_MODE; + } + } else if (is_ad9833 && sysfs_streq(buf, "square")) { + st->control &= ~AD9834_MODE; + st->control |= AD9834_OPBITEN; + } else { + ret = -EINVAL; + } + + break; + case 1: + if (sysfs_streq(buf, "square") && + !(st->control & AD9834_MODE)) { + st->control &= ~AD9834_MODE; + st->control |= AD9834_OPBITEN; + } else { + ret = -EINVAL; + } + break; + default: + ret = -EINVAL; + break; + } + + if (!ret) { + st->data = cpu_to_be16(AD9834_REG_CMD | st->control); + ret = spi_sync(st->spi, &st->msg); + } + mutex_unlock(&dev_info->mlock); + + return ret ? ret : len; +} + +static ssize_t ad9834_show_name(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad9834_state *st = iio_dev_get_devdata(dev_info); + + return sprintf(buf, "%s\n", spi_get_device_id(st->spi)->name); +} +static IIO_DEVICE_ATTR(name, S_IRUGO, ad9834_show_name, NULL, 0); + +static ssize_t ad9834_show_out0_wavetype_available(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad9834_state *st = iio_dev_get_devdata(dev_info); + char *str; + + if (st->devid == ID_AD9833) + str = "sine triangle square"; + else if (st->control & AD9834_OPBITEN) + str = "sine"; + else + str = "sine triangle"; + + return sprintf(buf, "%s\n", str); +} + + +static IIO_DEVICE_ATTR(dds0_out0_wavetype_available, S_IRUGO, + ad9834_show_out0_wavetype_available, NULL, 0); + +static ssize_t ad9834_show_out1_wavetype_available(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad9834_state *st = iio_dev_get_devdata(dev_info); + char *str; + + if (st->control & AD9834_MODE) + str = ""; + else + str = "square"; + + return sprintf(buf, "%s\n", str); +} + +static IIO_DEVICE_ATTR(dds0_out1_wavetype_available, S_IRUGO, + ad9834_show_out1_wavetype_available, NULL, 0); + +/** + * see dds.h for further information + */ + +static IIO_DEV_ATTR_FREQ(0, 0, S_IWUSR, NULL, ad9834_write, AD9834_REG_FREQ0); +static IIO_DEV_ATTR_FREQ(0, 1, S_IWUSR, NULL, ad9834_write, AD9834_REG_FREQ1); +static IIO_DEV_ATTR_FREQSYMBOL(0, S_IWUSR, NULL, ad9834_write, AD9834_FSEL); +static IIO_CONST_ATTR_FREQ_SCALE(0, "1"); /* 1Hz */ + +static IIO_DEV_ATTR_PHASE(0, 0, S_IWUSR, NULL, ad9834_write, AD9834_REG_PHASE0); +static IIO_DEV_ATTR_PHASE(0, 1, S_IWUSR, NULL, ad9834_write, AD9834_REG_PHASE1); +static IIO_DEV_ATTR_PHASESYMBOL(0, S_IWUSR, NULL, ad9834_write, AD9834_PSEL); +static IIO_CONST_ATTR_PHASE_SCALE(0, "0.0015339808"); /* 2PI/2^12 rad*/ + +static IIO_DEV_ATTR_PINCONTROL_EN(0, S_IWUSR, NULL, + ad9834_write, AD9834_PIN_SW); +static IIO_DEV_ATTR_OUT_ENABLE(0, S_IWUSR, NULL, ad9834_write, AD9834_RESET); +static IIO_DEV_ATTR_OUTY_ENABLE(0, 1, S_IWUSR, NULL, + ad9834_write, AD9834_OPBITEN); +static IIO_DEV_ATTR_OUT_WAVETYPE(0, 0, ad9834_store_wavetype, 0); +static IIO_DEV_ATTR_OUT_WAVETYPE(0, 1, ad9834_store_wavetype, 1); + +static struct attribute *ad9834_attributes[] = { + &iio_dev_attr_dds0_freq0.dev_attr.attr, + &iio_dev_attr_dds0_freq1.dev_attr.attr, + &iio_const_attr_dds0_freq_scale.dev_attr.attr, + &iio_dev_attr_dds0_phase0.dev_attr.attr, + &iio_dev_attr_dds0_phase1.dev_attr.attr, + &iio_const_attr_dds0_phase_scale.dev_attr.attr, + &iio_dev_attr_dds0_pincontrol_en.dev_attr.attr, + &iio_dev_attr_dds0_freqsymbol.dev_attr.attr, + &iio_dev_attr_dds0_phasesymbol.dev_attr.attr, + &iio_dev_attr_dds0_out_enable.dev_attr.attr, + &iio_dev_attr_dds0_out1_enable.dev_attr.attr, + &iio_dev_attr_dds0_out0_wavetype.dev_attr.attr, + &iio_dev_attr_dds0_out1_wavetype.dev_attr.attr, + &iio_dev_attr_dds0_out0_wavetype_available.dev_attr.attr, + &iio_dev_attr_dds0_out1_wavetype_available.dev_attr.attr, + &iio_dev_attr_name.dev_attr.attr, + NULL, +}; + +static mode_t ad9834_attr_is_visible(struct kobject *kobj, + struct attribute *attr, int n) +{ + struct device *dev = container_of(kobj, struct device, kobj); + struct iio_dev *dev_info = dev_get_drvdata(dev); + struct ad9834_state *st = iio_dev_get_devdata(dev_info); + + mode_t mode = attr->mode; + + if (st->devid == ID_AD9834) + return mode; + + if ((attr == &iio_dev_attr_dds0_out1_enable.dev_attr.attr) || + (attr == &iio_dev_attr_dds0_out1_wavetype.dev_attr.attr) || + (attr == + &iio_dev_attr_dds0_out1_wavetype_available.dev_attr.attr)) + mode = 0; + + return mode; +} + +static const struct attribute_group ad9834_attribute_group = { + .attrs = ad9834_attributes, + .is_visible = ad9834_attr_is_visible, +}; + +static int __devinit ad9834_probe(struct spi_device *spi) +{ + struct ad9834_platform_data *pdata = spi->dev.platform_data; + struct ad9834_state *st; + int ret; + + if (!pdata) { + dev_dbg(&spi->dev, "no platform data?\n"); + return -ENODEV; + } + + st = kzalloc(sizeof(*st), GFP_KERNEL); + if (st == NULL) { + ret = -ENOMEM; + goto error_ret; + } + + st->reg = regulator_get(&spi->dev, "vcc"); + if (!IS_ERR(st->reg)) { + ret = regulator_enable(st->reg); + if (ret) + goto error_put_reg; + } + + st->mclk = pdata->mclk; + + spi_set_drvdata(spi, st); + + st->spi = spi; + st->devid = spi_get_device_id(spi)->driver_data; + + st->indio_dev = iio_allocate_device(); + if (st->indio_dev == NULL) { + ret = -ENOMEM; + goto error_disable_reg; + } + + st->indio_dev->dev.parent = &spi->dev; + st->indio_dev->attrs = &ad9834_attribute_group; + st->indio_dev->dev_data = (void *) st; + st->indio_dev->driver_module = THIS_MODULE; + st->indio_dev->modes = INDIO_DIRECT_MODE; + + /* Setup default messages */ + + st->xfer.tx_buf = &st->data; + st->xfer.len = 2; + + spi_message_init(&st->msg); + spi_message_add_tail(&st->xfer, &st->msg); + + st->freq_xfer[0].tx_buf = &st->freq_data[0]; + st->freq_xfer[0].len = 2; + st->freq_xfer[0].cs_change = 1; + st->freq_xfer[1].tx_buf = &st->freq_data[1]; + st->freq_xfer[1].len = 2; + + spi_message_init(&st->freq_msg); + spi_message_add_tail(&st->freq_xfer[0], &st->freq_msg); + spi_message_add_tail(&st->freq_xfer[1], &st->freq_msg); + + st->control = AD9834_B28 | AD9834_RESET; + + if (!pdata->en_div2) + st->control |= AD9834_DIV2; + + if (!pdata->en_signbit_msb_out && (st->devid == ID_AD9834)) + st->control |= AD9834_SIGN_PIB; + + st->data = cpu_to_be16(AD9834_REG_CMD | st->control); + ret = spi_sync(st->spi, &st->msg); + if (ret) { + dev_err(&spi->dev, "device init failed\n"); + goto error_free_device; + } + + ret = ad9834_write_frequency(st, AD9834_REG_FREQ0, pdata->freq0); + if (ret) + goto error_free_device; + + ret = ad9834_write_frequency(st, AD9834_REG_FREQ1, pdata->freq1); + if (ret) + goto error_free_device; + + ret = ad9834_write_phase(st, AD9834_REG_PHASE0, pdata->phase0); + if (ret) + goto error_free_device; + + ret = ad9834_write_phase(st, AD9834_REG_PHASE1, pdata->phase1); + if (ret) + goto error_free_device; + + ret = iio_device_register(st->indio_dev); + if (ret) + goto error_free_device; + + return 0; + +error_free_device: + iio_free_device(st->indio_dev); +error_disable_reg: + if (!IS_ERR(st->reg)) + regulator_disable(st->reg); +error_put_reg: + if (!IS_ERR(st->reg)) + regulator_put(st->reg); + kfree(st); +error_ret: + return ret; +} + +static int __devexit ad9834_remove(struct spi_device *spi) +{ + struct ad9834_state *st = spi_get_drvdata(spi); + + iio_device_unregister(st->indio_dev); + if (!IS_ERR(st->reg)) { + regulator_disable(st->reg); + regulator_put(st->reg); + } + kfree(st); + return 0; +} + +static const struct spi_device_id ad9834_id[] = { + {"ad9833", ID_AD9833}, + {"ad9834", ID_AD9834}, + {} +}; + +static struct spi_driver ad9834_driver = { + .driver = { + .name = "ad9834", + .bus = &spi_bus_type, + .owner = THIS_MODULE, + }, + .probe = ad9834_probe, + .remove = __devexit_p(ad9834_remove), + .id_table = ad9834_id, +}; + +static int __init ad9834_init(void) +{ + return spi_register_driver(&ad9834_driver); +} +module_init(ad9834_init); + +static void __exit ad9834_exit(void) +{ + spi_unregister_driver(&ad9834_driver); +} +module_exit(ad9834_exit); + +MODULE_AUTHOR("Michael Hennerich "); +MODULE_DESCRIPTION("Analog Devices AD9833/AD9834 DDS"); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("spi:ad9834"); diff --git a/drivers/staging/iio/dds/ad9834.h b/drivers/staging/iio/dds/ad9834.h new file mode 100644 index 000000000000..0fc3b8859e9e --- /dev/null +++ b/drivers/staging/iio/dds/ad9834.h @@ -0,0 +1,112 @@ +/* + * AD9834 SPI DDS driver + * + * Copyright 2010 Analog Devices Inc. + * + * Licensed under the GPL-2 or later. + */ +#ifndef IIO_DDS_AD9834_H_ +#define IIO_DDS_AD9834_H_ + +/* Registers */ + +#define AD9834_REG_CMD (0 << 14) +#define AD9834_REG_FREQ0 (1 << 14) +#define AD9834_REG_FREQ1 (2 << 14) +#define AD9834_REG_PHASE0 (6 << 13) +#define AD9834_REG_PHASE1 (7 << 13) + +/* Command Control Bits */ + +#define AD9834_B28 (1 << 13) +#define AD9834_HLB (1 << 12) +#define AD9834_FSEL (1 << 11) +#define AD9834_PSEL (1 << 10) +#define AD9834_PIN_SW (1 << 9) +#define AD9834_RESET (1 << 8) +#define AD9834_SLEEP1 (1 << 7) +#define AD9834_SLEEP12 (1 << 6) +#define AD9834_OPBITEN (1 << 5) +#define AD9834_SIGN_PIB (1 << 4) +#define AD9834_DIV2 (1 << 3) +#define AD9834_MODE (1 << 1) + +#define AD9834_FREQ_BITS 28 +#define AD9834_PHASE_BITS 12 + +#define RES_MASK(bits) ((1 << (bits)) - 1) + +/** + * struct ad9834_state - driver instance specific data + * @indio_dev: the industrial I/O device + * @spi: spi_device + * @reg: supply regulator + * @mclk: external master clock + * @control: cached control word + * @xfer: default spi transfer + * @msg: default spi message + * @freq_xfer: tuning word spi transfer + * @freq_msg: tuning word spi message + * @data: spi transmit buffer + * @freq_data: tuning word spi transmit buffer + */ + +struct ad9834_state { + struct iio_dev *indio_dev; + struct spi_device *spi; + struct regulator *reg; + unsigned int mclk; + unsigned short control; + unsigned short devid; + struct spi_transfer xfer; + struct spi_message msg; + struct spi_transfer freq_xfer[2]; + struct spi_message freq_msg; + + /* + * DMA (thus cache coherency maintenance) requires the + * transfer buffers to live in their own cache lines. + */ + unsigned short data ____cacheline_aligned; + unsigned short freq_data[2] ; +}; + + +/* + * TODO: struct ad7887_platform_data needs to go into include/linux/iio + */ + +/** + * struct ad9834_platform_data - platform specific information + * @mclk: master clock in Hz + * @freq0: power up freq0 tuning word in Hz + * @freq1: power up freq1 tuning word in Hz + * @phase0: power up phase0 value [0..4095] correlates with 0..2PI + * @phase1: power up phase1 value [0..4095] correlates with 0..2PI + * @en_div2: digital output/2 is passed to the SIGN BIT OUT pin + * @en_signbit_msb_out: the MSB (or MSB/2) of the DAC data is connected to the + * SIGN BIT OUT pin. en_div2 controls whether it is the MSB + * or MSB/2 that is output. if en_signbit_msb_out=false, + * the on-board comparator is connected to SIGN BIT OUT + */ + +struct ad9834_platform_data { + unsigned int mclk; + unsigned int freq0; + unsigned int freq1; + unsigned short phase0; + unsigned short phase1; + bool en_div2; + bool en_signbit_msb_out; +}; + +/** + * ad9834_supported_device_ids: + */ + +enum ad9834_supported_device_ids { + ID_AD9833, + ID_AD9834, +}; + +#endif /* IIO_DDS_AD9834_H_ */ -- cgit v1.2.3 From f4528696d803749892eac27422a6fd7748cffee1 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Tue, 14 Dec 2010 12:51:52 -0800 Subject: staging: brcm80211: Fix WL_ logging macros These macros use the equivalent of "#define WL_(x) printk x" which requires an extra level of parentheses. Convert the macros to use the normal WL_(fmt, args...) style and remove the extra parentheses from the uses. Add format argument verification using no_printk as appropriate. Couple of spelling typo fixes in the formats and argument alignment at the same time. Also coalesced long formats. Signed-off-by: Joe Perches Signed-off-by: Greg Kroah-Hartman --- .../staging/brcm80211/brcmfmac/dhd_custom_gpio.c | 34 +- drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c | 518 ++++++++++----------- drivers/staging/brcm80211/brcmfmac/wl_cfg80211.h | 46 +- drivers/staging/brcm80211/brcmfmac/wl_iw.c | 480 ++++++++++--------- drivers/staging/brcm80211/brcmfmac/wl_iw.h | 2 +- drivers/staging/brcm80211/sys/wl_dbg.h | 72 +-- drivers/staging/brcm80211/sys/wl_mac80211.c | 247 +++++----- drivers/staging/brcm80211/sys/wlc_alloc.c | 2 +- drivers/staging/brcm80211/sys/wlc_ampdu.c | 99 ++-- drivers/staging/brcm80211/sys/wlc_antsel.c | 4 +- drivers/staging/brcm80211/sys/wlc_bmac.c | 285 +++++++----- drivers/staging/brcm80211/sys/wlc_channel.c | 45 +- drivers/staging/brcm80211/sys/wlc_event.c | 4 +- drivers/staging/brcm80211/sys/wlc_mac80211.c | 340 +++++++------- drivers/staging/brcm80211/sys/wlc_phy_shim.c | 3 +- drivers/staging/brcm80211/sys/wlc_stf.c | 12 +- 16 files changed, 1136 insertions(+), 1057 deletions(-) diff --git a/drivers/staging/brcm80211/brcmfmac/dhd_custom_gpio.c b/drivers/staging/brcm80211/brcmfmac/dhd_custom_gpio.c index bb3c7b8c4b98..c3f18bb3b27c 100644 --- a/drivers/staging/brcm80211/brcmfmac/dhd_custom_gpio.c +++ b/drivers/staging/brcm80211/brcmfmac/dhd_custom_gpio.c @@ -24,8 +24,8 @@ #include #include -#define WL_ERROR(x) printf x -#define WL_TRACE(x) +#define WL_ERROR(fmt, args...) printk(fmt, ##args) +#define WL_TRACE(fmt, args...) no_printk(fmt, ##args) #ifdef CUSTOMER_HW extern void bcm_wlan_power_off(int); @@ -67,13 +67,13 @@ int dhd_customer_oob_irq_map(unsigned long *irq_flags_ptr) #endif if (dhd_oob_gpio_num < 0) { - WL_ERROR(("%s: ERROR customer specific Host GPIO is NOT defined\n", - __func__)); + WL_ERROR("%s: ERROR customer specific Host GPIO is NOT defined\n", + __func__); return dhd_oob_gpio_num; } - WL_ERROR(("%s: customer specific Host GPIO number is (%d)\n", - __func__, dhd_oob_gpio_num)); + WL_ERROR("%s: customer specific Host GPIO number is (%d)\n", + __func__, dhd_oob_gpio_num); #if defined CUSTOMER_HW host_oob_irq = MSM_GPIO_TO_INT(dhd_oob_gpio_num); @@ -93,40 +93,40 @@ void dhd_customer_gpio_wlan_ctrl(int onoff) { switch (onoff) { case WLAN_RESET_OFF: - WL_TRACE(("%s: call customer specific GPIO to insert WLAN RESET\n", - __func__)); + WL_TRACE("%s: call customer specific GPIO to insert WLAN RESET\n", + __func__); #ifdef CUSTOMER_HW bcm_wlan_power_off(2); #endif /* CUSTOMER_HW */ #ifdef CUSTOMER_HW2 wifi_set_power(0, 0); #endif - WL_ERROR(("=========== WLAN placed in RESET ========\n")); + WL_ERROR("=========== WLAN placed in RESET ========\n"); break; case WLAN_RESET_ON: - WL_TRACE(("%s: callc customer specific GPIO to remove WLAN RESET\n", - __func__)); + WL_TRACE("%s: callc customer specific GPIO to remove WLAN RESET\n", + __func__); #ifdef CUSTOMER_HW bcm_wlan_power_on(2); #endif /* CUSTOMER_HW */ #ifdef CUSTOMER_HW2 wifi_set_power(1, 0); #endif - WL_ERROR(("=========== WLAN going back to live ========\n")); + WL_ERROR("=========== WLAN going back to live ========\n"); break; case WLAN_POWER_OFF: - WL_TRACE(("%s: call customer specific GPIO to turn off WL_REG_ON\n", - __func__)); + WL_TRACE("%s: call customer specific GPIO to turn off WL_REG_ON\n", + __func__); #ifdef CUSTOMER_HW bcm_wlan_power_off(1); #endif /* CUSTOMER_HW */ break; case WLAN_POWER_ON: - WL_TRACE(("%s: call customer specific GPIO to turn on WL_REG_ON\n", - __func__)); + WL_TRACE("%s: call customer specific GPIO to turn on WL_REG_ON\n", + __func__); #ifdef CUSTOMER_HW bcm_wlan_power_on(1); #endif /* CUSTOMER_HW */ @@ -140,7 +140,7 @@ void dhd_customer_gpio_wlan_ctrl(int onoff) /* Function to get custom MAC address */ int dhd_custom_get_mac_address(unsigned char *buf) { - WL_TRACE(("%s Enter\n", __func__)); + WL_TRACE("%s Enter\n", __func__); if (!buf) return -EINVAL; diff --git a/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c b/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c index 1e92f2e230fe..991463f4a7f4 100644 --- a/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c +++ b/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.c @@ -337,7 +337,7 @@ static void wl_debugfs_remove_netdev(struct wl_priv *wl); struct wl_iface *ci; \ if (unlikely(!(wl_cfg80211_dev && \ (ci = wl_get_drvdata(wl_cfg80211_dev))))) { \ - WL_ERR(("wl_cfg80211_dev is unavailable\n")); \ + WL_ERR("wl_cfg80211_dev is unavailable\n"); \ BUG(); \ } \ ci_to_wl(ci); \ @@ -347,8 +347,8 @@ static void wl_debugfs_remove_netdev(struct wl_priv *wl); do { \ struct wl_priv *wl = wiphy_to_wl(wiphy); \ if (unlikely(!test_bit(WL_STATUS_READY, &wl->status))) { \ - WL_INFO(("device is not ready : status (%d)\n", \ - (int)wl->status)); \ + WL_INFO("device is not ready : status (%d)\n", \ + (int)wl->status); \ return -EIO; \ } \ } while (0) @@ -613,8 +613,8 @@ wl_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev, switch (type) { case NL80211_IFTYPE_MONITOR: case NL80211_IFTYPE_WDS: - WL_ERR(("type (%d) : currently we do not support this type\n", - type)); + WL_ERR("type (%d) : currently we do not support this type\n", + type); return -EOPNOTSUPP; case NL80211_IFTYPE_ADHOC: wl->conf->mode = WL_MODE_IBSS; @@ -630,15 +630,15 @@ wl_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev, ap = htod32(ap); wdev = ndev->ieee80211_ptr; wdev->iftype = type; - WL_DBG(("%s : ap (%d), infra (%d)\n", ndev->name, ap, infra)); + WL_DBG("%s : ap (%d), infra (%d)\n", ndev->name, ap, infra); err = wl_dev_ioctl(ndev, WLC_SET_INFRA, &infra, sizeof(infra)); if (unlikely(err)) { - WL_ERR(("WLC_SET_INFRA error (%d)\n", err)); + WL_ERR("WLC_SET_INFRA error (%d)\n", err); return err; } err = wl_dev_ioctl(ndev, WLC_SET_AP, &ap, sizeof(ap)); if (unlikely(err)) { - WL_ERR(("WLC_SET_AP error (%d)\n", err)); + WL_ERR("WLC_SET_AP error (%d)\n", err); return err; } @@ -717,9 +717,9 @@ wl_run_iscan(struct wl_iscan_ctrl *iscan, struct wlc_ssid *ssid, u16 action) iscan->ioctl_buf, WLC_IOCTL_SMLEN); if (unlikely(err)) { if (err == -EBUSY) { - WL_INFO(("system busy : iscan canceled\n")); + WL_INFO("system busy : iscan canceled\n"); } else { - WL_ERR(("error (%d)\n", err)); + WL_ERR("error (%d)\n", err); } } kfree(params); @@ -743,7 +743,7 @@ static s32 wl_do_iscan(struct wl_priv *wl) err = wl_dev_ioctl(wl_to_ndev(wl), WLC_SET_PASSIVE_SCAN, &passive_scan, sizeof(passive_scan)); if (unlikely(err)) { - WL_DBG(("error (%d)\n", err)); + WL_DBG("error (%d)\n", err); return err; } wl_set_mpc(ndev, 0); @@ -769,12 +769,12 @@ __wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev, s32 err = 0; if (unlikely(test_bit(WL_STATUS_SCANNING, &wl->status))) { - WL_ERR(("Scanning already : status (%d)\n", (int)wl->status)); + WL_ERR("Scanning already : status (%d)\n", (int)wl->status); return -EAGAIN; } if (unlikely(test_bit(WL_STATUS_SCAN_ABORTING, &wl->status))) { - WL_ERR(("Scanning being aborted : status (%d)\n", - (int)wl->status)); + WL_ERR("Scanning being aborted : status (%d)\n", + (int)wl->status); return -EAGAIN; } @@ -806,26 +806,26 @@ __wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev, else goto scan_out; } else { - WL_DBG(("ssid \"%s\", ssid_len (%d)\n", - ssids->ssid, ssids->ssid_len)); + WL_DBG("ssid \"%s\", ssid_len (%d)\n", + ssids->ssid, ssids->ssid_len); memset(&sr->ssid, 0, sizeof(sr->ssid)); sr->ssid.SSID_len = min_t(u8, sizeof(sr->ssid.SSID), ssids->ssid_len); if (sr->ssid.SSID_len) { memcpy(sr->ssid.SSID, ssids->ssid, sr->ssid.SSID_len); sr->ssid.SSID_len = htod32(sr->ssid.SSID_len); - WL_DBG(("Specific scan ssid=\"%s\" len=%d\n", - sr->ssid.SSID, sr->ssid.SSID_len)); + WL_DBG("Specific scan ssid=\"%s\" len=%d\n", + sr->ssid.SSID, sr->ssid.SSID_len); spec_scan = true; } else { - WL_DBG(("Broadcast scan\n")); + WL_DBG("Broadcast scan\n"); } - WL_DBG(("sr->ssid.SSID_len (%d)\n", sr->ssid.SSID_len)); + WL_DBG("sr->ssid.SSID_len (%d)\n", sr->ssid.SSID_len); passive_scan = wl->active_scan ? 0 : 1; err = wl_dev_ioctl(ndev, WLC_SET_PASSIVE_SCAN, &passive_scan, sizeof(passive_scan)); if (unlikely(err)) { - WL_ERR(("WLC_SET_PASSIVE_SCAN error (%d)\n", err)); + WL_ERR("WLC_SET_PASSIVE_SCAN error (%d)\n", err); goto scan_out; } wl_set_mpc(ndev, 0); @@ -833,10 +833,10 @@ __wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev, sizeof(sr->ssid)); if (err) { if (err == -EBUSY) { - WL_INFO(("system busy : scan for \"%s\" " - "canceled\n", sr->ssid.SSID)); + WL_INFO("system busy : scan for \"%s\" canceled\n", + sr->ssid.SSID); } else { - WL_ERR(("WLC_SCAN error (%d)\n", err)); + WL_ERR("WLC_SCAN error (%d)\n", err); } wl_set_mpc(ndev, 1); goto scan_out; @@ -860,7 +860,7 @@ wl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev, CHECK_SYS_UP(); err = __wl_cfg80211_scan(wiphy, ndev, request, NULL); if (unlikely(err)) { - WL_DBG(("scan error (%d)\n", err)); + WL_DBG("scan error (%d)\n", err); return err; } @@ -879,7 +879,7 @@ static s32 wl_dev_intvar_set(struct net_device *dev, s8 *name, s32 val) err = wl_dev_ioctl(dev, WLC_SET_VAR, buf, len); if (unlikely(err)) { - WL_ERR(("error (%d)\n", err)); + WL_ERR("error (%d)\n", err); } return err; @@ -902,7 +902,7 @@ wl_dev_intvar_get(struct net_device *dev, s8 *name, s32 *retval) BUG_ON(unlikely(!len)); err = wl_dev_ioctl(dev, WLC_GET_VAR, &var, len); if (unlikely(err)) { - WL_ERR(("error (%d)\n", err)); + WL_ERR("error (%d)\n", err); } *retval = dtoh32(var.val); @@ -915,7 +915,7 @@ static s32 wl_set_rts(struct net_device *dev, u32 rts_threshold) err = wl_dev_intvar_set(dev, "rtsthresh", rts_threshold); if (unlikely(err)) { - WL_ERR(("Error (%d)\n", err)); + WL_ERR("Error (%d)\n", err); return err; } return err; @@ -927,7 +927,7 @@ static s32 wl_set_frag(struct net_device *dev, u32 frag_threshold) err = wl_dev_intvar_set(dev, "fragthresh", frag_threshold); if (unlikely(err)) { - WL_ERR(("Error (%d)\n", err)); + WL_ERR("Error (%d)\n", err); return err; } return err; @@ -941,7 +941,7 @@ static s32 wl_set_retry(struct net_device *dev, u32 retry, bool l) retry = htod32(retry); err = wl_dev_ioctl(dev, cmd, &retry, sizeof(retry)); if (unlikely(err)) { - WL_ERR(("cmd (%d) , error (%d)\n", cmd, err)); + WL_ERR("cmd (%d) , error (%d)\n", cmd, err); return err; } return err; @@ -1001,7 +1001,7 @@ wl_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev, CHECK_SYS_UP(); if (params->bssid) { - WL_ERR(("Invalid bssid\n")); + WL_ERR("Invalid bssid\n"); return -EOPNOTSUPP; } bss = cfg80211_get_ibss(wiphy, NULL, params->ssid, params->ssid_len); @@ -1027,7 +1027,7 @@ wl_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev, } if (bss) { wl->ibss_starter = false; - WL_DBG(("Found IBSS\n")); + WL_DBG("Found IBSS\n"); } else { wl->ibss_starter = true; } @@ -1051,7 +1051,7 @@ wl_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev, err = wl_dev_ioctl(dev, WLC_SET_SSID, &join_params, sizeof(join_params)); if (unlikely(err)) { - WL_ERR(("Error (%d)\n", err)); + WL_ERR("Error (%d)\n", err); return err; } return err; @@ -1082,10 +1082,10 @@ wl_set_wpa_version(struct net_device *dev, struct cfg80211_connect_params *sme) val = WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED; else val = WPA_AUTH_DISABLED; - WL_DBG(("setting wpa_auth to 0x%0x\n", val)); + WL_DBG("setting wpa_auth to 0x%0x\n", val); err = wl_dev_intvar_set(dev, "wpa_auth", val); if (unlikely(err)) { - WL_ERR(("set wpa_auth failed (%d)\n", err)); + WL_ERR("set wpa_auth failed (%d)\n", err); return err; } sec = wl_read_prof(wl, WL_PROF_SEC); @@ -1104,27 +1104,27 @@ wl_set_auth_type(struct net_device *dev, struct cfg80211_connect_params *sme) switch (sme->auth_type) { case NL80211_AUTHTYPE_OPEN_SYSTEM: val = 0; - WL_DBG(("open system\n")); + WL_DBG("open system\n"); break; case NL80211_AUTHTYPE_SHARED_KEY: val = 1; - WL_DBG(("shared key\n")); + WL_DBG("shared key\n"); break; case NL80211_AUTHTYPE_AUTOMATIC: val = 2; - WL_DBG(("automatic\n")); + WL_DBG("automatic\n"); break; case NL80211_AUTHTYPE_NETWORK_EAP: - WL_DBG(("network eap\n")); + WL_DBG("network eap\n"); default: val = 2; - WL_ERR(("invalid auth type (%d)\n", sme->auth_type)); + WL_ERR("invalid auth type (%d)\n", sme->auth_type); break; } err = wl_dev_intvar_set(dev, "auth", val); if (unlikely(err)) { - WL_ERR(("set auth failed (%d)\n", err)); + WL_ERR("set auth failed (%d)\n", err); return err; } sec = wl_read_prof(wl, WL_PROF_SEC); @@ -1157,8 +1157,8 @@ wl_set_set_cipher(struct net_device *dev, struct cfg80211_connect_params *sme) pval = AES_ENABLED; break; default: - WL_ERR(("invalid cipher pairwise (%d)\n", - sme->crypto.ciphers_pairwise[0])); + WL_ERR("invalid cipher pairwise (%d)\n", + sme->crypto.ciphers_pairwise[0]); return -EINVAL; } } @@ -1178,16 +1178,16 @@ wl_set_set_cipher(struct net_device *dev, struct cfg80211_connect_params *sme) gval = AES_ENABLED; break; default: - WL_ERR(("invalid cipher group (%d)\n", - sme->crypto.cipher_group)); + WL_ERR("invalid cipher group (%d)\n", + sme->crypto.cipher_group); return -EINVAL; } } - WL_DBG(("pval (%d) gval (%d)\n", pval, gval)); + WL_DBG("pval (%d) gval (%d)\n", pval, gval); err = wl_dev_intvar_set(dev, "wsec", pval | gval); if (unlikely(err)) { - WL_ERR(("error (%d)\n", err)); + WL_ERR("error (%d)\n", err); return err; } @@ -1209,7 +1209,7 @@ wl_set_key_mgmt(struct net_device *dev, struct cfg80211_connect_params *sme) if (sme->crypto.n_akm_suites) { err = wl_dev_intvar_get(dev, "wpa_auth", &val); if (unlikely(err)) { - WL_ERR(("could not get wpa_auth (%d)\n", err)); + WL_ERR("could not get wpa_auth (%d)\n", err); return err; } if (val & (WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED)) { @@ -1221,8 +1221,8 @@ wl_set_key_mgmt(struct net_device *dev, struct cfg80211_connect_params *sme) val = WPA_AUTH_PSK; break; default: - WL_ERR(("invalid cipher group (%d)\n", - sme->crypto.cipher_group)); + WL_ERR("invalid cipher group (%d)\n", + sme->crypto.cipher_group); return -EINVAL; } } else if (val & (WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED)) { @@ -1234,16 +1234,16 @@ wl_set_key_mgmt(struct net_device *dev, struct cfg80211_connect_params *sme) val = WPA2_AUTH_PSK; break; default: - WL_ERR(("invalid cipher group (%d)\n", - sme->crypto.cipher_group)); + WL_ERR("invalid cipher group (%d)\n", + sme->crypto.cipher_group); return -EINVAL; } } - WL_DBG(("setting wpa_auth to %d\n", val)); + WL_DBG("setting wpa_auth to %d\n", val); err = wl_dev_intvar_set(dev, "wpa_auth", val); if (unlikely(err)) { - WL_ERR(("could not set wpa_auth (%d)\n", err)); + WL_ERR("could not set wpa_auth (%d)\n", err); return err; } } @@ -1263,11 +1263,11 @@ wl_set_set_sharedkey(struct net_device *dev, s32 val; s32 err = 0; - WL_DBG(("key len (%d)\n", sme->key_len)); + WL_DBG("key len (%d)\n", sme->key_len); if (sme->key_len) { sec = wl_read_prof(wl, WL_PROF_SEC); - WL_DBG(("wpa_versions 0x%x cipher_pairwise 0x%x\n", - sec->wpa_versions, sec->cipher_pairwise)); + WL_DBG("wpa_versions 0x%x cipher_pairwise 0x%x\n", + sec->wpa_versions, sec->cipher_pairwise); if (! (sec->wpa_versions & (NL80211_WPA_VERSION_1 | NL80211_WPA_VERSION_2)) @@ -1277,7 +1277,7 @@ wl_set_set_sharedkey(struct net_device *dev, key.len = (u32) sme->key_len; key.index = (u32) sme->key_idx; if (unlikely(key.len > sizeof(key.data))) { - WL_ERR(("Too long key length (%u)\n", key.len)); + WL_ERR("Too long key length (%u)\n", key.len); return -EINVAL; } memcpy(key.data, sme->key, key.len); @@ -1290,27 +1290,27 @@ wl_set_set_sharedkey(struct net_device *dev, key.algo = CRYPTO_ALGO_WEP128; break; default: - WL_ERR(("Invalid algorithm (%d)\n", - sme->crypto.ciphers_pairwise[0])); + WL_ERR("Invalid algorithm (%d)\n", + sme->crypto.ciphers_pairwise[0]); return -EINVAL; } /* Set the new key/index */ - WL_DBG(("key length (%d) key index (%d) algo (%d)\n", - key.len, key.index, key.algo)); - WL_DBG(("key \"%s\"\n", key.data)); + WL_DBG("key length (%d) key index (%d) algo (%d)\n", + key.len, key.index, key.algo); + WL_DBG("key \"%s\"\n", key.data); swap_key_from_BE(&key); err = wl_dev_ioctl(dev, WLC_SET_KEY, &key, sizeof(key)); if (unlikely(err)) { - WL_ERR(("WLC_SET_KEY error (%d)\n", err)); + WL_ERR("WLC_SET_KEY error (%d)\n", err); return err; } if (sec->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM) { - WL_DBG(("set auth_type to shared key\n")); + WL_DBG("set auth_type to shared key\n"); val = 1; /* shared key */ err = wl_dev_intvar_set(dev, "auth", val); if (unlikely(err)) { - WL_ERR(("set auth failed (%d)\n", err)); + WL_ERR("set auth failed (%d)\n", err); return err; } } @@ -1332,15 +1332,15 @@ wl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, CHECK_SYS_UP(); if (unlikely(!sme->ssid)) { - WL_ERR(("Invalid ssid\n")); + WL_ERR("Invalid ssid\n"); return -EOPNOTSUPP; } if (chan) { wl->channel = ieee80211_frequency_to_channel(chan->center_freq); - WL_DBG(("channel (%d), center_req (%d)\n", wl->channel, - chan->center_freq)); + WL_DBG("channel (%d), center_req (%d)\n", + wl->channel, chan->center_freq); } - WL_DBG(("ie (%p), ie_len (%zd)\n", sme->ie, sme->ie_len)); + WL_DBG("ie (%p), ie_len (%zd)\n", sme->ie, sme->ie_len); err = wl_set_wpa_version(dev, sme); if (unlikely(err)) return err; @@ -1376,15 +1376,15 @@ wl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev, memcpy(&join_params.params.bssid, ðer_bcast, ETH_ALEN); wl_ch_to_chanspec(wl->channel, &join_params, &join_params_size); - WL_DBG(("join_param_size %d\n", join_params_size)); + WL_DBG("join_param_size %d\n", join_params_size); if (join_params.ssid.SSID_len < IEEE80211_MAX_SSID_LEN) { - WL_DBG(("ssid \"%s\", len (%d)\n", join_params.ssid.SSID, - join_params.ssid.SSID_len)); + WL_DBG("ssid \"%s\", len (%d)\n", + join_params.ssid.SSID, join_params.ssid.SSID_len); } err = wl_dev_ioctl(dev, WLC_SET_SSID, &join_params, join_params_size); if (unlikely(err)) { - WL_ERR(("error (%d)\n", err)); + WL_ERR("error (%d)\n", err); return err; } set_bit(WL_STATUS_CONNECTING, &wl->status); @@ -1401,7 +1401,7 @@ wl_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev, bool act = false; s32 err = 0; - WL_DBG(("Reason %d\n", reason_code)); + WL_DBG("Reason %d\n", reason_code); CHECK_SYS_UP(); act = *(bool *) wl_read_prof(wl, WL_PROF_ACT); if (likely(act)) { @@ -1411,7 +1411,7 @@ wl_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev, err = wl_dev_ioctl(dev, WLC_DISASSOC, &scbval, sizeof(scb_val_t)); if (unlikely(err)) { - WL_ERR(("error (%d)\n", err)); + WL_ERR("error (%d)\n", err); return err; } } @@ -1436,13 +1436,13 @@ wl_cfg80211_set_tx_power(struct wiphy *wiphy, break; case NL80211_TX_POWER_LIMITED: if (dbm < 0) { - WL_ERR(("TX_POWER_LIMITTED - dbm is negative\n")); + WL_ERR("TX_POWER_LIMITED - dbm is negative\n"); return -EINVAL; } break; case NL80211_TX_POWER_FIXED: if (dbm < 0) { - WL_ERR(("TX_POWER_FIXED - dbm is negative..\n")); + WL_ERR("TX_POWER_FIXED - dbm is negative\n"); return -EINVAL; } break; @@ -1452,7 +1452,7 @@ wl_cfg80211_set_tx_power(struct wiphy *wiphy, disable = htod32(disable); err = wl_dev_ioctl(ndev, WLC_SET_RADIO, &disable, sizeof(disable)); if (unlikely(err)) { - WL_ERR(("WLC_SET_RADIO error (%d)\n", err)); + WL_ERR("WLC_SET_RADIO error (%d)\n", err); return err; } @@ -1463,7 +1463,7 @@ wl_cfg80211_set_tx_power(struct wiphy *wiphy, err = wl_dev_intvar_set(ndev, "qtxpower", (s32) (bcm_mw_to_qdbm(txpwrmw))); if (unlikely(err)) { - WL_ERR(("qtxpower error (%d)\n", err)); + WL_ERR("qtxpower error (%d)\n", err); return err; } wl->conf->tx_power = dbm; @@ -1482,7 +1482,7 @@ static s32 wl_cfg80211_get_tx_power(struct wiphy *wiphy, s32 *dbm) CHECK_SYS_UP(); err = wl_dev_intvar_get(ndev, "qtxpower", &txpwrdbm); if (unlikely(err)) { - WL_ERR(("error (%d)\n", err)); + WL_ERR("error (%d)\n", err); return err; } result = (u8) (txpwrdbm & ~WL_TXPWR_OVERRIDE); @@ -1499,12 +1499,12 @@ wl_cfg80211_config_default_key(struct wiphy *wiphy, struct net_device *dev, s32 wsec; s32 err = 0; - WL_DBG(("key index (%d)\n", key_idx)); + WL_DBG("key index (%d)\n", key_idx); CHECK_SYS_UP(); err = wl_dev_ioctl(dev, WLC_GET_WSEC, &wsec, sizeof(wsec)); if (unlikely(err)) { - WL_ERR(("WLC_GET_WSEC error (%d)\n", err)); + WL_ERR("WLC_GET_WSEC error (%d)\n", err); return err; } wsec = dtoh32(wsec); @@ -1515,7 +1515,7 @@ wl_cfg80211_config_default_key(struct wiphy *wiphy, struct net_device *dev, err = wl_dev_ioctl(dev, WLC_SET_KEY_PRIMARY, &index, sizeof(index)); if (unlikely(err)) { - WL_ERR(("error (%d)\n", err)); + WL_ERR("error (%d)\n", err); } } return err; @@ -1541,16 +1541,16 @@ wl_add_keyext(struct wiphy *wiphy, struct net_device *dev, swap_key_from_BE(&key); err = wl_dev_ioctl(dev, WLC_SET_KEY, &key, sizeof(key)); if (unlikely(err)) { - WL_ERR(("key delete error (%d)\n", err)); + WL_ERR("key delete error (%d)\n", err); return err; } } else { if (key.len > sizeof(key.data)) { - WL_ERR(("Invalid key length (%d)\n", key.len)); + WL_ERR("Invalid key length (%d)\n", key.len); return -EINVAL; } - WL_DBG(("Setting the key index %d\n", key.index)); + WL_DBG("Setting the key index %d\n", key.index); memcpy(key.data, params->key, key.len); if (params->cipher == WLAN_CIPHER_SUITE_TKIP) { @@ -1574,26 +1574,26 @@ wl_add_keyext(struct wiphy *wiphy, struct net_device *dev, switch (params->cipher) { case WLAN_CIPHER_SUITE_WEP40: key.algo = CRYPTO_ALGO_WEP1; - WL_DBG(("WLAN_CIPHER_SUITE_WEP40\n")); + WL_DBG("WLAN_CIPHER_SUITE_WEP40\n"); break; case WLAN_CIPHER_SUITE_WEP104: key.algo = CRYPTO_ALGO_WEP128; - WL_DBG(("WLAN_CIPHER_SUITE_WEP104\n")); + WL_DBG("WLAN_CIPHER_SUITE_WEP104\n"); break; case WLAN_CIPHER_SUITE_TKIP: key.algo = CRYPTO_ALGO_TKIP; - WL_DBG(("WLAN_CIPHER_SUITE_TKIP\n")); + WL_DBG("WLAN_CIPHER_SUITE_TKIP\n"); break; case WLAN_CIPHER_SUITE_AES_CMAC: key.algo = CRYPTO_ALGO_AES_CCM; - WL_DBG(("WLAN_CIPHER_SUITE_AES_CMAC\n")); + WL_DBG("WLAN_CIPHER_SUITE_AES_CMAC\n"); break; case WLAN_CIPHER_SUITE_CCMP: key.algo = CRYPTO_ALGO_AES_CCM; - WL_DBG(("WLAN_CIPHER_SUITE_CCMP\n")); + WL_DBG("WLAN_CIPHER_SUITE_CCMP\n"); break; default: - WL_ERR(("Invalid cipher (0x%x)\n", params->cipher)); + WL_ERR("Invalid cipher (0x%x)\n", params->cipher); return -EINVAL; } swap_key_from_BE(&key); @@ -1601,7 +1601,7 @@ wl_add_keyext(struct wiphy *wiphy, struct net_device *dev, dhd_wait_pend8021x(dev); err = wl_dev_ioctl(dev, WLC_SET_KEY, &key, sizeof(key)); if (unlikely(err)) { - WL_ERR(("WLC_SET_KEY error (%d)\n", err)); + WL_ERR("WLC_SET_KEY error (%d)\n", err); return err; } } @@ -1618,7 +1618,7 @@ wl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *dev, s32 wsec; s32 err = 0; - WL_DBG(("key index (%d)\n", key_idx)); + WL_DBG("key index (%d)\n", key_idx); CHECK_SYS_UP(); if (mac_addr) @@ -1629,7 +1629,7 @@ wl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *dev, key.index = (u32) key_idx; if (unlikely(key.len > sizeof(key.data))) { - WL_ERR(("Too long key length (%u)\n", key.len)); + WL_ERR("Too long key length (%u)\n", key.len); return -EINVAL; } memcpy(key.data, params->key, key.len); @@ -1638,26 +1638,26 @@ wl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *dev, switch (params->cipher) { case WLAN_CIPHER_SUITE_WEP40: key.algo = CRYPTO_ALGO_WEP1; - WL_DBG(("WLAN_CIPHER_SUITE_WEP40\n")); + WL_DBG("WLAN_CIPHER_SUITE_WEP40\n"); break; case WLAN_CIPHER_SUITE_WEP104: key.algo = CRYPTO_ALGO_WEP128; - WL_DBG(("WLAN_CIPHER_SUITE_WEP104\n")); + WL_DBG("WLAN_CIPHER_SUITE_WEP104\n"); break; case WLAN_CIPHER_SUITE_TKIP: key.algo = CRYPTO_ALGO_TKIP; - WL_DBG(("WLAN_CIPHER_SUITE_TKIP\n")); + WL_DBG("WLAN_CIPHER_SUITE_TKIP\n"); break; case WLAN_CIPHER_SUITE_AES_CMAC: key.algo = CRYPTO_ALGO_AES_CCM; - WL_DBG(("WLAN_CIPHER_SUITE_AES_CMAC\n")); + WL_DBG("WLAN_CIPHER_SUITE_AES_CMAC\n"); break; case WLAN_CIPHER_SUITE_CCMP: key.algo = CRYPTO_ALGO_AES_CCM; - WL_DBG(("WLAN_CIPHER_SUITE_CCMP\n")); + WL_DBG("WLAN_CIPHER_SUITE_CCMP\n"); break; default: - WL_ERR(("Invalid cipher (0x%x)\n", params->cipher)); + WL_ERR("Invalid cipher (0x%x)\n", params->cipher); return -EINVAL; } @@ -1665,21 +1665,21 @@ wl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *dev, swap_key_from_BE(&key); err = wl_dev_ioctl(dev, WLC_SET_KEY, &key, sizeof(key)); if (unlikely(err)) { - WL_ERR(("WLC_SET_KEY error (%d)\n", err)); + WL_ERR("WLC_SET_KEY error (%d)\n", err); return err; } val = WEP_ENABLED; err = wl_dev_intvar_get(dev, "wsec", &wsec); if (unlikely(err)) { - WL_ERR(("get wsec error (%d)\n", err)); + WL_ERR("get wsec error (%d)\n", err); return err; } wsec &= ~(WEP_ENABLED); wsec |= val; err = wl_dev_intvar_set(dev, "wsec", wsec); if (unlikely(err)) { - WL_ERR(("set wsec error (%d)\n", err)); + WL_ERR("set wsec error (%d)\n", err); return err; } @@ -1687,7 +1687,7 @@ wl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *dev, val = htod32(val); err = wl_dev_ioctl(dev, WLC_SET_AUTH, &val, sizeof(val)); if (unlikely(err)) { - WL_ERR(("WLC_SET_AUTH error (%d)\n", err)); + WL_ERR("WLC_SET_AUTH error (%d)\n", err); return err; } return err; @@ -1709,7 +1709,7 @@ wl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *dev, key.flags = WL_PRIMARY_KEY; key.algo = CRYPTO_ALGO_OFF; - WL_DBG(("key index (%d)\n", key_idx)); + WL_DBG("key index (%d)\n", key_idx); /* Set the new key/index */ swap_key_from_BE(&key); err = wl_dev_ioctl(dev, WLC_SET_KEY, &key, sizeof(key)); @@ -1717,10 +1717,10 @@ wl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *dev, if (err == -EINVAL) { if (key.index >= DOT11_MAX_DEFAULT_KEYS) { /* we ignore this key index in this case */ - WL_DBG(("invalid key index (%d)\n", key_idx)); + WL_DBG("invalid key index (%d)\n", key_idx); } } else { - WL_ERR(("WLC_SET_KEY error (%d)\n", err)); + WL_ERR("WLC_SET_KEY error (%d)\n", err); } return err; } @@ -1728,14 +1728,14 @@ wl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *dev, val = 0; err = wl_dev_intvar_get(dev, "wsec", &wsec); if (unlikely(err)) { - WL_ERR(("get wsec error (%d)\n", err)); + WL_ERR("get wsec error (%d)\n", err); return err; } wsec &= ~(WEP_ENABLED); wsec |= val; err = wl_dev_intvar_set(dev, "wsec", wsec); if (unlikely(err)) { - WL_ERR(("set wsec error (%d)\n", err)); + WL_ERR("set wsec error (%d)\n", err); return err; } @@ -1743,7 +1743,7 @@ wl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *dev, val = htod32(val); err = wl_dev_ioctl(dev, WLC_SET_AUTH, &val, sizeof(val)); if (unlikely(err)) { - WL_ERR(("WLC_SET_AUTH error (%d)\n", err)); + WL_ERR("WLC_SET_AUTH error (%d)\n", err); return err; } return err; @@ -1761,7 +1761,7 @@ wl_cfg80211_get_key(struct wiphy *wiphy, struct net_device *dev, s32 wsec; s32 err = 0; - WL_DBG(("key index (%d)\n", key_idx)); + WL_DBG("key index (%d)\n", key_idx); CHECK_SYS_UP(); memset(&key, 0, sizeof(key)); @@ -1773,7 +1773,7 @@ wl_cfg80211_get_key(struct wiphy *wiphy, struct net_device *dev, err = wl_dev_ioctl(dev, WLC_GET_WSEC, &wsec, sizeof(wsec)); if (unlikely(err)) { - WL_ERR(("WLC_GET_WSEC error (%d)\n", err)); + WL_ERR("WLC_GET_WSEC error (%d)\n", err); return err; } wsec = dtoh32(wsec); @@ -1782,22 +1782,22 @@ wl_cfg80211_get_key(struct wiphy *wiphy, struct net_device *dev, sec = wl_read_prof(wl, WL_PROF_SEC); if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP40) { params.cipher = WLAN_CIPHER_SUITE_WEP40; - WL_DBG(("WLAN_CIPHER_SUITE_WEP40\n")); + WL_DBG("WLAN_CIPHER_SUITE_WEP40\n"); } else if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP104) { params.cipher = WLAN_CIPHER_SUITE_WEP104; - WL_DBG(("WLAN_CIPHER_SUITE_WEP104\n")); + WL_DBG("WLAN_CIPHER_SUITE_WEP104\n"); } break; case TKIP_ENABLED: params.cipher = WLAN_CIPHER_SUITE_TKIP; - WL_DBG(("WLAN_CIPHER_SUITE_TKIP\n")); + WL_DBG("WLAN_CIPHER_SUITE_TKIP\n"); break; case AES_ENABLED: params.cipher = WLAN_CIPHER_SUITE_AES_CMAC; - WL_DBG(("WLAN_CIPHER_SUITE_AES_CMAC\n")); + WL_DBG("WLAN_CIPHER_SUITE_AES_CMAC\n"); break; default: - WL_ERR(("Invalid algo (0x%x)\n", wsec)); + WL_ERR("Invalid algo (0x%x)\n", wsec); return -EINVAL; } @@ -1809,7 +1809,7 @@ static s32 wl_cfg80211_config_default_mgmt_key(struct wiphy *wiphy, struct net_device *dev, u8 key_idx) { - WL_INFO(("Not supported\n")); + WL_INFO("Not supported\n"); CHECK_SYS_UP(); return -EOPNOTSUPP; } @@ -1827,19 +1827,19 @@ wl_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev, CHECK_SYS_UP(); if (unlikely (memcmp(mac, wl_read_prof(wl, WL_PROF_BSSID), ETH_ALEN))) { - WL_ERR(("Wrong Mac address\n")); + WL_ERR("Wrong Mac address\n"); return -ENOENT; } /* Report the current tx rate */ err = wl_dev_ioctl(dev, WLC_GET_RATE, &rate, sizeof(rate)); if (err) { - WL_ERR(("Could not get rate (%d)\n", err)); + WL_ERR("Could not get rate (%d)\n", err); } else { rate = dtoh32(rate); sinfo->filled |= STATION_INFO_TX_BITRATE; sinfo->txrate.legacy = rate * 5; - WL_DBG(("Rate %d Mbps\n", (rate / 2))); + WL_DBG("Rate %d Mbps\n", rate / 2); } if (test_bit(WL_STATUS_CONNECTED, &wl->status)) { @@ -1847,13 +1847,13 @@ wl_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev, err = wl_dev_ioctl(dev, WLC_GET_RSSI, &scb_val, sizeof(scb_val_t)); if (unlikely(err)) { - WL_ERR(("Could not get rssi (%d)\n", err)); + WL_ERR("Could not get rssi (%d)\n", err); return err; } rssi = dtoh32(scb_val.val); sinfo->filled |= STATION_INFO_SIGNAL; sinfo->signal = rssi; - WL_DBG(("RSSI %d dBm\n", rssi)); + WL_DBG("RSSI %d dBm\n", rssi); } return err; @@ -1869,13 +1869,13 @@ wl_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev, CHECK_SYS_UP(); pm = enabled ? PM_FAST : PM_OFF; pm = htod32(pm); - WL_DBG(("power save %s\n", (pm ? "enabled" : "disabled"))); + WL_DBG("power save %s\n", (pm ? "enabled" : "disabled")); err = wl_dev_ioctl(dev, WLC_SET_PM, &pm, sizeof(pm)); if (unlikely(err)) { if (err == -ENODEV) - WL_DBG(("net_device is not ready yet\n")); + WL_DBG("net_device is not ready yet\n"); else - WL_ERR(("error (%d)\n", err)); + WL_ERR("error (%d)\n", err); return err; } return err; @@ -1927,7 +1927,7 @@ wl_cfg80211_set_bitrate_mask(struct wiphy *wiphy, struct net_device *dev, err = wl_dev_ioctl(dev, WLC_GET_CURR_RATESET, &rateset, sizeof(rateset)); if (unlikely(err)) { - WL_ERR(("could not get current rateset (%d)\n", err)); + WL_ERR("could not get current rateset (%d)\n", err); return err; } @@ -1947,7 +1947,7 @@ wl_cfg80211_set_bitrate_mask(struct wiphy *wiphy, struct net_device *dev, rate = val / 500000; } - WL_DBG(("rate %d mbps\n", (rate / 2))); + WL_DBG("rate %d mbps\n", rate / 2); /* * @@ -1957,7 +1957,7 @@ wl_cfg80211_set_bitrate_mask(struct wiphy *wiphy, struct net_device *dev, err_bg = wl_dev_intvar_set(dev, "bg_rate", rate); err_a = wl_dev_intvar_set(dev, "a_rate", rate); if (unlikely(err_bg && err_a)) { - WL_ERR(("could not set fixed rate (%d) (%d)\n", err_bg, err_a)); + WL_ERR("could not set fixed rate (%d) (%d)\n", err_bg, err_a); return err_bg | err_a; } @@ -2002,12 +2002,12 @@ wl_update_pmklist(struct net_device *dev, struct wl_pmk_list *pmk_list, { int i, j; - WL_DBG(("No of elements %d\n", pmk_list->pmkids.npmkid)); + WL_DBG("No of elements %d\n", pmk_list->pmkids.npmkid); for (i = 0; i < pmk_list->pmkids.npmkid; i++) { - WL_DBG(("PMKID[%d]: %pM =\n", i, - &pmk_list->pmkids.pmkid[i].BSSID)); + WL_DBG("PMKID[%d]: %pM =\n", i, + &pmk_list->pmkids.pmkid[i].BSSID); for (j = 0; j < WPA2_PMKID_LEN; j++) { - WL_DBG(("%02x\n", pmk_list->pmkids.pmkid[i].PMKID[j])); + WL_DBG("%02x\n", pmk_list->pmkids.pmkid[i].PMKID[j]); } } if (likely(!err)) { @@ -2041,12 +2041,12 @@ wl_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev, } else { err = -EINVAL; } - WL_DBG(("set_pmksa,IW_PMKSA_ADD - PMKID: %pM =\n", - &wl->pmk_list->pmkids.pmkid[wl->pmk_list->pmkids.npmkid].BSSID)); + WL_DBG("set_pmksa,IW_PMKSA_ADD - PMKID: %pM =\n", + &wl->pmk_list->pmkids.pmkid[wl->pmk_list->pmkids.npmkid].BSSID); for (i = 0; i < WPA2_PMKID_LEN; i++) { - WL_DBG(("%02x\n", - wl->pmk_list->pmkids.pmkid[wl->pmk_list->pmkids.npmkid]. - PMKID[i])); + WL_DBG("%02x\n", + wl->pmk_list->pmkids.pmkid[wl->pmk_list->pmkids.npmkid]. + PMKID[i]); } err = wl_update_pmklist(dev, wl->pmk_list, err); @@ -2067,10 +2067,10 @@ wl_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev, memcpy(&pmkid.pmkid[0].BSSID, pmksa->bssid, ETH_ALEN); memcpy(&pmkid.pmkid[0].PMKID, pmksa->pmkid, WPA2_PMKID_LEN); - WL_DBG(("del_pmksa,IW_PMKSA_REMOVE - PMKID: %pM =\n", - &pmkid.pmkid[0].BSSID)); + WL_DBG("del_pmksa,IW_PMKSA_REMOVE - PMKID: %pM =\n", + &pmkid.pmkid[0].BSSID); for (i = 0; i < WPA2_PMKID_LEN; i++) { - WL_DBG(("%02x\n", pmkid.pmkid[0].PMKID[i])); + WL_DBG("%02x\n", pmkid.pmkid[0].PMKID[i]); } for (i = 0; i < wl->pmk_list->pmkids.npmkid; i++) @@ -2163,13 +2163,13 @@ static struct wireless_dev *wl_alloc_wdev(s32 sizeof_iface, wdev = kzalloc(sizeof(*wdev), GFP_KERNEL); if (unlikely(!wdev)) { - WL_ERR(("Could not allocate wireless device\n")); + WL_ERR("Could not allocate wireless device\n"); return ERR_PTR(-ENOMEM); } wdev->wiphy = wiphy_new(&wl_cfg80211_ops, sizeof(struct wl_priv) + sizeof_iface); if (unlikely(!wdev->wiphy)) { - WL_ERR(("Couldn not allocate wiphy device\n")); + WL_ERR("Couldn not allocate wiphy device\n"); err = -ENOMEM; goto wiphy_new_out; } @@ -2199,7 +2199,7 @@ static struct wireless_dev *wl_alloc_wdev(s32 sizeof_iface, #endif /* !WL_POWERSAVE_DISABLED */ err = wiphy_register(wdev->wiphy); if (unlikely(err < 0)) { - WL_ERR(("Couldn not register wiphy device (%d)\n", err)); + WL_ERR("Couldn not register wiphy device (%d)\n", err); goto wiphy_register_out; } return wdev; @@ -2218,7 +2218,7 @@ static void wl_free_wdev(struct wl_priv *wl) struct wireless_dev *wdev = wl_to_wdev(wl); if (unlikely(!wdev)) { - WL_ERR(("wdev is invalid\n")); + WL_ERR("wdev is invalid\n"); return; } wiphy_unregister(wdev->wiphy); @@ -2236,11 +2236,11 @@ static s32 wl_inform_bss(struct wl_priv *wl) bss_list = wl->bss_list; if (unlikely(bss_list->version != WL_BSS_INFO_VERSION)) { - WL_ERR(("Version %d != WL_BSS_INFO_VERSION\n", - bss_list->version)); + WL_ERR("Version %d != WL_BSS_INFO_VERSION\n", + bss_list->version); return -EOPNOTSUPP; } - WL_DBG(("scanned AP count (%d)\n", bss_list->count)); + WL_DBG("scanned AP count (%d)\n", bss_list->count); bi = next_bss(bss_list, bi); for_each_bss(bss_list, bi, i) { err = wl_inform_single_bss(wl, bi); @@ -2265,14 +2265,14 @@ static s32 wl_inform_single_bss(struct wl_priv *wl, struct wl_bss_info *bi) s32 err = 0; if (unlikely(dtoh32(bi->length) > WL_BSS_INFO_MAX)) { - WL_DBG(("Beacon is larger than buffer. Discarding\n")); + WL_DBG("Beacon is larger than buffer. Discarding\n"); return err; } notif_bss_info = kzalloc(sizeof(*notif_bss_info) + sizeof(*mgmt) - sizeof(u8) + WL_BSS_INFO_MAX, GFP_KERNEL); if (unlikely(!notif_bss_info)) { - WL_ERR(("notif_bss_info alloc failed\n")); + WL_ERR("notif_bss_info alloc failed\n"); return -ENOMEM; } mgmt = (struct ieee80211_mgmt *)notif_bss_info->frame_buf; @@ -2316,17 +2316,17 @@ static s32 wl_inform_single_bss(struct wl_priv *wl, struct wl_bss_info *bi) freq = ieee80211_channel_to_frequency(notif_bss_info->channel); channel = ieee80211_get_channel(wiphy, freq); - WL_DBG(("SSID : \"%s\", rssi %d, channel %d, capability : 0x04%x, bssid %pM\n", - bi->SSID, - notif_bss_info->rssi, notif_bss_info->channel, - mgmt->u.beacon.capab_info, &bi->BSSID)); + WL_DBG("SSID : \"%s\", rssi %d, channel %d, capability : 0x04%x, bssid %pM\n", + bi->SSID, + notif_bss_info->rssi, notif_bss_info->channel, + mgmt->u.beacon.capab_info, &bi->BSSID); signal = notif_bss_info->rssi * 100; if (unlikely(!cfg80211_inform_bss_frame(wiphy, channel, mgmt, le16_to_cpu (notif_bss_info->frame_len), signal, GFP_KERNEL))) { - WL_ERR(("cfg80211_inform_bss_frame error\n")); + WL_ERR("cfg80211_inform_bss_frame error\n"); kfree(notif_bss_info); return -EINVAL; } @@ -2394,12 +2394,12 @@ wl_notify_connect_status(struct wl_priv *wl, struct net_device *ndev, if (wl_is_ibssmode(wl)) { cfg80211_ibss_joined(ndev, (s8 *)&e->addr, GFP_KERNEL); - WL_DBG(("joined in IBSS network\n")); + WL_DBG("joined in IBSS network\n"); } else { wl_bss_connect_done(wl, ndev, e, data, true); - WL_DBG(("joined in BSS network \"%s\"\n", - ((struct wlc_ssid *) - wl_read_prof(wl, WL_PROF_SSID))->SSID)); + WL_DBG("joined in BSS network \"%s\"\n", + ((struct wlc_ssid *) + wl_read_prof(wl, WL_PROF_SSID))->SSID); } act = true; wl_update_prof(wl, e, &act, WL_PROF_ACT); @@ -2454,7 +2454,7 @@ wl_dev_bufvar_get(struct net_device *dev, s8 *name, s8 *buf, err = wl_dev_ioctl(dev, WLC_GET_VAR, (void *)wl->ioctl_buf, WL_IOCTL_LEN_MAX); if (unlikely(err)) { - WL_ERR(("error (%d)\n", err)); + WL_ERR("error (%d)\n", err); return err; } memcpy(buf, wl->ioctl_buf, buf_len); @@ -2474,7 +2474,7 @@ static s32 wl_get_assoc_ies(struct wl_priv *wl) err = wl_dev_bufvar_get(ndev, "assoc_info", wl->extra_buf, WL_ASSOC_INFO_MAX); if (unlikely(err)) { - WL_ERR(("could not get assoc info (%d)\n", err)); + WL_ERR("could not get assoc info (%d)\n", err); return err; } assoc_info = (struct wl_assoc_ielen *)wl->extra_buf; @@ -2484,7 +2484,7 @@ static s32 wl_get_assoc_ies(struct wl_priv *wl) err = wl_dev_bufvar_get(ndev, "assoc_req_ies", wl->extra_buf, WL_ASSOC_INFO_MAX); if (unlikely(err)) { - WL_ERR(("could not get assoc req (%d)\n", err)); + WL_ERR("could not get assoc req (%d)\n", err); return err; } conn_info->req_ie_len = req_len; @@ -2498,7 +2498,7 @@ static s32 wl_get_assoc_ies(struct wl_priv *wl) err = wl_dev_bufvar_get(ndev, "assoc_resp_ies", wl->extra_buf, WL_ASSOC_INFO_MAX); if (unlikely(err)) { - WL_ERR(("could not get assoc resp (%d)\n", err)); + WL_ERR("could not get assoc resp (%d)\n", err); return err; } conn_info->resp_ie_len = resp_len; @@ -2508,8 +2508,8 @@ static s32 wl_get_assoc_ies(struct wl_priv *wl) conn_info->resp_ie_len = 0; conn_info->resp_ie = NULL; } - WL_DBG(("req len (%d) resp len (%d)\n", conn_info->req_ie_len, - conn_info->resp_ie_len)); + WL_DBG("req len (%d) resp len (%d)\n", + conn_info->req_ie_len, conn_info->resp_ie_len); return err; } @@ -2542,8 +2542,8 @@ static void wl_ch_to_chanspec(int ch, struct wl_join_params *join_params, join_params->params.chanspec_num = htod32(join_params->params.chanspec_num); - WL_DBG(("join_params->params.chanspec_list[0]= %#X, channel %d, chanspec %#X\n", - join_params->params.chanspec_list[0], ch, chanspec)); + WL_DBG("join_params->params.chanspec_list[0]= %#X, channel %d, chanspec %#X\n", + join_params->params.chanspec_list[0], ch, chanspec); } } @@ -2570,12 +2570,12 @@ static s32 wl_update_bss_info(struct wl_priv *wl) rtnl_lock(); if (unlikely(!bss)) { - WL_DBG(("Could not find the AP\n")); + WL_DBG("Could not find the AP\n"); *(u32 *) wl->extra_buf = htod32(WL_EXTRA_BUF_MAX); err = wl_dev_ioctl(wl_to_ndev(wl), WLC_GET_BSS_INFO, wl->extra_buf, WL_EXTRA_BUF_MAX); if (unlikely(err)) { - WL_ERR(("Could not get bss info %d\n", err)); + WL_ERR("Could not get bss info %d\n", err); goto update_bss_info_out; } bi = (struct wl_bss_info *)(wl->extra_buf + 4); @@ -2591,7 +2591,7 @@ static s32 wl_update_bss_info(struct wl_priv *wl) ie_len = bi->ie_length; beacon_interval = cpu_to_le16(bi->beacon_period); } else { - WL_DBG(("Found the AP in the list - BSSID %pM\n", bss->bssid)); + WL_DBG("Found the AP in the list - BSSID %pM\n", bss->bssid); ie = bss->information_elements; ie_len = bss->len_information_elements; beacon_interval = bss->beacon_interval; @@ -2610,7 +2610,7 @@ static s32 wl_update_bss_info(struct wl_priv *wl) err = wl_dev_ioctl(wl_to_ndev(wl), WLC_GET_DTIMPRD, &dtim_period, sizeof(dtim_period)); if (unlikely(err)) { - WL_ERR(("WLC_GET_DTIMPRD error (%d)\n", err)); + WL_ERR("WLC_GET_DTIMPRD error (%d)\n", err); goto update_bss_info_out; } } @@ -2637,7 +2637,7 @@ wl_bss_roaming_done(struct wl_priv *wl, struct net_device *ndev, (u8 *)&wl->bssid, conn_info->req_ie, conn_info->req_ie_len, conn_info->resp_ie, conn_info->resp_ie_len, GFP_KERNEL); - WL_DBG(("Report roaming result\n")); + WL_DBG("Report roaming result\n"); set_bit(WL_STATUS_CONNECTED, &wl->status); @@ -2663,15 +2663,15 @@ wl_bss_connect_done(struct wl_priv *wl, struct net_device *ndev, conn_info->resp_ie_len, completed ? WLAN_STATUS_SUCCESS : WLAN_STATUS_AUTH_TIMEOUT, GFP_KERNEL); - WL_DBG(("Report connect result - connection %s\n", - completed ? "succeeded" : "failed")); + WL_DBG("Report connect result - connection %s\n", + completed ? "succeeded" : "failed"); } else { cfg80211_roamed(ndev, (u8 *)&wl->bssid, conn_info->req_ie, conn_info->req_ie_len, conn_info->resp_ie, conn_info->resp_ie_len, GFP_KERNEL); - WL_DBG(("Report roaming result\n")); + WL_DBG("Report roaming result\n"); } set_bit(WL_STATUS_CONNECTED, &wl->status); @@ -2711,7 +2711,7 @@ wl_notify_scan_status(struct wl_priv *wl, struct net_device *ndev, return wl_wakeup_iscan(wl_to_iscan(wl)); if (unlikely(!test_and_clear_bit(WL_STATUS_SCANNING, &wl->status))) { - WL_ERR(("Scan complete while device not scanning\n")); + WL_ERR("Scan complete while device not scanning\n"); return -EINVAL; } if (unlikely(!wl->scan_request)) { @@ -2720,14 +2720,14 @@ wl_notify_scan_status(struct wl_priv *wl, struct net_device *ndev, err = wl_dev_ioctl(ndev, WLC_GET_CHANNEL, &channel_inform, sizeof(channel_inform)); if (unlikely(err)) { - WL_ERR(("scan busy (%d)\n", err)); + WL_ERR("scan busy (%d)\n", err); goto scan_done_out; } channel_inform.scan_channel = dtoh32(channel_inform.scan_channel); if (unlikely(channel_inform.scan_channel)) { - WL_DBG(("channel_inform.scan_channel (%d)\n", - channel_inform.scan_channel)); + WL_DBG("channel_inform.scan_channel (%d)\n", + channel_inform.scan_channel); } wl->bss_list = wl->scan_results; bss_list = wl->bss_list; @@ -2735,7 +2735,7 @@ wl_notify_scan_status(struct wl_priv *wl, struct net_device *ndev, bss_list->buflen = htod32(len); err = wl_dev_ioctl(ndev, WLC_SCAN_RESULTS, bss_list, len); if (unlikely(err)) { - WL_ERR(("%s Scan_results error (%d)\n", ndev->name, err)); + WL_ERR("%s Scan_results error (%d)\n", ndev->name, err); err = -EINVAL; goto scan_done_out; } @@ -2791,52 +2791,52 @@ static s32 wl_init_priv_mem(struct wl_priv *wl) { wl->scan_results = kzalloc(WL_SCAN_BUF_MAX, GFP_KERNEL); if (unlikely(!wl->scan_results)) { - WL_ERR(("Scan results alloc failed\n")); + WL_ERR("Scan results alloc failed\n"); goto init_priv_mem_out; } wl->conf = kzalloc(sizeof(*wl->conf), GFP_KERNEL); if (unlikely(!wl->conf)) { - WL_ERR(("wl_conf alloc failed\n")); + WL_ERR("wl_conf alloc failed\n"); goto init_priv_mem_out; } wl->profile = kzalloc(sizeof(*wl->profile), GFP_KERNEL); if (unlikely(!wl->profile)) { - WL_ERR(("wl_profile alloc failed\n")); + WL_ERR("wl_profile alloc failed\n"); goto init_priv_mem_out; } wl->bss_info = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL); if (unlikely(!wl->bss_info)) { - WL_ERR(("Bss information alloc failed\n")); + WL_ERR("Bss information alloc failed\n"); goto init_priv_mem_out; } wl->scan_req_int = kzalloc(sizeof(*wl->scan_req_int), GFP_KERNEL); if (unlikely(!wl->scan_req_int)) { - WL_ERR(("Scan req alloc failed\n")); + WL_ERR("Scan req alloc failed\n"); goto init_priv_mem_out; } wl->ioctl_buf = kzalloc(WL_IOCTL_LEN_MAX, GFP_KERNEL); if (unlikely(!wl->ioctl_buf)) { - WL_ERR(("Ioctl buf alloc failed\n")); + WL_ERR("Ioctl buf alloc failed\n"); goto init_priv_mem_out; } wl->extra_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL); if (unlikely(!wl->extra_buf)) { - WL_ERR(("Extra buf alloc failed\n")); + WL_ERR("Extra buf alloc failed\n"); goto init_priv_mem_out; } wl->iscan = kzalloc(sizeof(*wl->iscan), GFP_KERNEL); if (unlikely(!wl->iscan)) { - WL_ERR(("Iscan buf alloc failed\n")); + WL_ERR("Iscan buf alloc failed\n"); goto init_priv_mem_out; } wl->fw = kzalloc(sizeof(*wl->fw), GFP_KERNEL); if (unlikely(!wl->fw)) { - WL_ERR(("fw object alloc failed\n")); + WL_ERR("fw object alloc failed\n"); goto init_priv_mem_out; } wl->pmk_list = kzalloc(sizeof(*wl->pmk_list), GFP_KERNEL); if (unlikely(!wl->pmk_list)) { - WL_ERR(("pmk list alloc failed\n")); + WL_ERR("pmk list alloc failed\n"); goto init_priv_mem_out; } @@ -2878,7 +2878,7 @@ static s32 wl_create_event_handler(struct wl_priv *wl) wl->event_tsk = kthread_run(wl_event_handler, wl, "wl_event_handler"); if (IS_ERR(wl->event_tsk)) { wl->event_tsk = NULL; - WL_ERR(("failed to create event thread\n")); + WL_ERR("failed to create event thread\n"); return -ENOMEM; } return 0; @@ -2911,7 +2911,7 @@ static void wl_notify_iscan_complete(struct wl_iscan_ctrl *iscan, bool aborted) struct net_device *ndev = wl_to_ndev(wl); if (unlikely(!test_and_clear_bit(WL_STATUS_SCANNING, &wl->status))) { - WL_ERR(("Scan complete while device not scanning\n")); + WL_ERR("Scan complete while device not scanning\n"); return; } if (likely(wl->scan_request)) { @@ -2925,7 +2925,7 @@ static void wl_notify_iscan_complete(struct wl_iscan_ctrl *iscan, bool aborted) static s32 wl_wakeup_iscan(struct wl_iscan_ctrl *iscan) { if (likely(iscan->state != WL_ISCAN_STATE_IDLE)) { - WL_DBG(("wake up iscan\n")); + WL_DBG("wake up iscan\n"); up(&iscan->sync); return 0; } @@ -2955,14 +2955,14 @@ wl_get_iscan_results(struct wl_iscan_ctrl *iscan, u32 *status, WL_ISCAN_RESULTS_FIXED_SIZE, iscan->scan_buf, WL_ISCAN_BUF_MAX); if (unlikely(err)) { - WL_ERR(("error (%d)\n", err)); + WL_ERR("error (%d)\n", err); return err; } results->buflen = dtoh32(results->buflen); results->version = dtoh32(results->version); results->count = dtoh32(results->count); - WL_DBG(("results->count = %d\n", results->count)); - WL_DBG(("results->buflen = %d\n", results->buflen)); + WL_DBG("results->count = %d\n", results->count); + WL_DBG("results->buflen = %d\n", results->buflen); *status = dtoh32(list_buf->status); *bss_list = results; @@ -3047,7 +3047,7 @@ static s32 wl_iscan_thread(void *data) err = wl_get_iscan_results(iscan, &status, &wl->bss_list); if (unlikely(err)) { status = WL_SCAN_RESULTS_ABORTED; - WL_ERR(("Abort iscan\n")); + WL_ERR("Abort iscan\n"); } rtnl_unlock(); el->handler[status] (wl); @@ -3056,7 +3056,7 @@ static s32 wl_iscan_thread(void *data) del_timer_sync(&iscan->timer); iscan->timer_on = 0; } - WL_DBG(("%s was terminated\n", __func__)); + WL_DBG("%s was terminated\n", __func__); return 0; } @@ -3067,7 +3067,7 @@ static void wl_iscan_timer(unsigned long data) if (iscan) { iscan->timer_on = 0; - WL_DBG(("timer expired\n")); + WL_DBG("timer expired\n"); wl_wakeup_iscan(iscan); } } @@ -3082,7 +3082,7 @@ static s32 wl_invoke_iscan(struct wl_priv *wl) sema_init(&iscan->sync, 0); iscan->tsk = kthread_run(wl_iscan_thread, iscan, "wl_iscan"); if (IS_ERR(iscan->tsk)) { - WL_ERR(("Could not create iscan thread\n")); + WL_ERR("Could not create iscan thread\n"); iscan->tsk = NULL; return -ENOMEM; } @@ -3117,7 +3117,7 @@ static s32 wl_init_iscan(struct wl_priv *wl) sema_init(&iscan->sync, 0); iscan->tsk = kthread_run(wl_iscan_thread, iscan, "wl_iscan"); if (IS_ERR(iscan->tsk)) { - WL_ERR(("Could not create iscan thread\n")); + WL_ERR("Could not create iscan thread\n"); iscan->tsk = NULL; return -ENOMEM; } @@ -3186,15 +3186,15 @@ s32 wl_cfg80211_attach(struct net_device *ndev, void *data) s32 err = 0; if (unlikely(!ndev)) { - WL_ERR(("ndev is invaild\n")); + WL_ERR("ndev is invalid\n"); return -ENODEV; } wl_cfg80211_dev = kzalloc(sizeof(struct wl_dev), GFP_KERNEL); if (unlikely(!wl_cfg80211_dev)) { - WL_ERR(("wl_cfg80211_dev is invalid\n")); + WL_ERR("wl_cfg80211_dev is invalid\n"); return -ENOMEM; } - WL_DBG(("func %p\n", wl_cfg80211_get_sdio_func())); + WL_DBG("func %p\n", wl_cfg80211_get_sdio_func()); wdev = wl_alloc_wdev(sizeof(struct wl_iface), &wl_cfg80211_get_sdio_func()->dev); if (IS_ERR(wdev)) return -ENOMEM; @@ -3210,7 +3210,7 @@ s32 wl_cfg80211_attach(struct net_device *ndev, void *data) wdev->netdev = ndev; err = wl_init_priv(wl); if (unlikely(err)) { - WL_ERR(("Failed to init iwm_priv (%d)\n", err)); + WL_ERR("Failed to init iwm_priv (%d)\n", err); goto cfg80211_attach_out; } wl_set_drvdata(wl_cfg80211_dev, ci); @@ -3255,19 +3255,19 @@ static s32 wl_event_handler(void *data) break; e = wl_deq_event(wl); if (unlikely(!e)) { - WL_ERR(("eqeue empty..\n")); + WL_ERR("event queue empty...\n"); BUG(); } - WL_DBG(("event type (%d)\n", e->etype)); + WL_DBG("event type (%d)\n", e->etype); if (wl->el.handler[e->etype]) { wl->el.handler[e->etype] (wl, wl_to_ndev(wl), &e->emsg, e->edata); } else { - WL_DBG(("Unknown Event (%d): ignoring\n", e->etype)); + WL_DBG("Unknown Event (%d): ignoring\n", e->etype); } wl_put_event(e); } - WL_DBG(("%s was terminated\n", __func__)); + WL_DBG("%s was terminated\n", __func__); return 0; } @@ -3280,7 +3280,7 @@ wl_cfg80211_event(struct net_device *ndev, const wl_event_msg_t * e, void *data) s8 *estr = (event_type <= sizeof(wl_dbg_estr) / WL_DBG_ESTR_MAX - 1) ? wl_dbg_estr[event_type] : (s8 *) "Unknown"; #endif /* (WL_DBG_LEVEL > 0) */ - WL_DBG(("event_type (%d):" "WLC_E_" "%s\n", event_type, estr)); + WL_DBG("event_type (%d):" "WLC_E_" "%s\n", event_type, estr); if (likely(!wl_enq_event(wl, event_type, e, data))) wl_wakeup_event(wl); } @@ -3335,7 +3335,7 @@ wl_enq_event(struct wl_priv *wl, u32 event, const wl_event_msg_t *msg, e = kzalloc(sizeof(struct wl_event_q), GFP_KERNEL); if (unlikely(!e)) { - WL_ERR(("event alloc failed\n")); + WL_ERR("event alloc failed\n"); return -ENOMEM; } @@ -3379,8 +3379,8 @@ static s32 wl_dongle_mode(struct net_device *ndev, s32 iftype) switch (iftype) { case NL80211_IFTYPE_MONITOR: case NL80211_IFTYPE_WDS: - WL_ERR(("type (%d) : currently we do not support this mode\n", - iftype)); + WL_ERR("type (%d) : currently we do not support this mode\n", + iftype); err = -EINVAL; return err; case NL80211_IFTYPE_ADHOC: @@ -3390,20 +3390,20 @@ static s32 wl_dongle_mode(struct net_device *ndev, s32 iftype) break; default: err = -EINVAL; - WL_ERR(("invalid type (%d)\n", iftype)); + WL_ERR("invalid type (%d)\n", iftype); return err; } infra = htod32(infra); ap = htod32(ap); - WL_DBG(("%s ap (%d), infra (%d)\n", ndev->name, ap, infra)); + WL_DBG("%s ap (%d), infra (%d)\n", ndev->name, ap, infra); err = wl_dev_ioctl(ndev, WLC_SET_INFRA, &infra, sizeof(infra)); if (unlikely(err)) { - WL_ERR(("WLC_SET_INFRA error (%d)\n", err)); + WL_ERR("WLC_SET_INFRA error (%d)\n", err); return err; } err = wl_dev_ioctl(ndev, WLC_SET_AP, &ap, sizeof(ap)); if (unlikely(err)) { - WL_ERR(("WLC_SET_AP error (%d)\n", err)); + WL_ERR("WLC_SET_AP error (%d)\n", err); return err; } @@ -3425,7 +3425,7 @@ static s32 wl_dongle_up(struct net_device *ndev, u32 up) err = wl_dev_ioctl(ndev, WLC_UP, &up, sizeof(up)); if (unlikely(err)) { - WL_ERR(("WLC_UP error (%d)\n", err)); + WL_ERR("WLC_UP error (%d)\n", err); } return err; } @@ -3436,7 +3436,7 @@ static s32 wl_dongle_power(struct net_device *ndev, u32 power_mode) err = wl_dev_ioctl(ndev, WLC_SET_PM, &power_mode, sizeof(power_mode)); if (unlikely(err)) { - WL_ERR(("WLC_SET_PM error (%d)\n", err)); + WL_ERR("WLC_SET_PM error (%d)\n", err); } return err; } @@ -3453,14 +3453,14 @@ wl_dongle_glom(struct net_device *ndev, u32 glom, u32 dongle_align) sizeof(iovbuf)); err = wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf)); if (unlikely(err)) { - WL_ERR(("txglomalign error (%d)\n", err)); + WL_ERR("txglomalign error (%d)\n", err); goto dongle_glom_out; } /* disable glom option per default */ bcm_mkiovar("bus:txglom", (char *)&glom, 4, iovbuf, sizeof(iovbuf)); err = wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf)); if (unlikely(err)) { - WL_ERR(("txglom error (%d)\n", err)); + WL_ERR("txglom error (%d)\n", err); goto dongle_glom_out; } dongle_glom_out: @@ -3481,7 +3481,7 @@ wl_dongle_roam(struct net_device *ndev, u32 roamvar, u32 bcn_timeout) sizeof(iovbuf)); err = wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf)); if (unlikely(err)) { - WL_ERR(("bcn_timeout error (%d)\n", err)); + WL_ERR("bcn_timeout error (%d)\n", err); goto dongle_rom_out; } } @@ -3490,7 +3490,7 @@ wl_dongle_roam(struct net_device *ndev, u32 roamvar, u32 bcn_timeout) bcm_mkiovar("roam_off", (char *)&roamvar, 4, iovbuf, sizeof(iovbuf)); err = wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf)); if (unlikely(err)) { - WL_ERR(("roam_off error (%d)\n", err)); + WL_ERR("roam_off error (%d)\n", err); goto dongle_rom_out; } dongle_rom_out: @@ -3510,7 +3510,7 @@ static s32 wl_dongle_eventmsg(struct net_device *ndev) sizeof(iovbuf)); err = wl_dev_ioctl(ndev, WLC_GET_VAR, iovbuf, sizeof(iovbuf)); if (unlikely(err)) { - WL_ERR(("Get event_msgs error (%d)\n", err)); + WL_ERR("Get event_msgs error (%d)\n", err); goto dongle_eventmsg_out; } memcpy(eventmask, iovbuf, WL_EVENTING_MASK_LEN); @@ -3538,7 +3538,7 @@ static s32 wl_dongle_eventmsg(struct net_device *ndev) sizeof(iovbuf)); err = wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf)); if (unlikely(err)) { - WL_ERR(("Set event_msgs error (%d)\n", err)); + WL_ERR("Set event_msgs error (%d)\n", err); goto dongle_eventmsg_out; } @@ -3556,9 +3556,9 @@ wl_dongle_scantime(struct net_device *ndev, s32 scan_assoc_time, sizeof(scan_assoc_time)); if (err) { if (err == -EOPNOTSUPP) { - WL_INFO(("Scan assoc time is not supported\n")); + WL_INFO("Scan assoc time is not supported\n"); } else { - WL_ERR(("Scan assoc time error (%d)\n", err)); + WL_ERR("Scan assoc time error (%d)\n", err); } goto dongle_scantime_out; } @@ -3566,9 +3566,9 @@ wl_dongle_scantime(struct net_device *ndev, s32 scan_assoc_time, sizeof(scan_unassoc_time)); if (err) { if (err == -EOPNOTSUPP) { - WL_INFO(("Scan unassoc time is not supported\n")); + WL_INFO("Scan unassoc time is not supported\n"); } else { - WL_ERR(("Scan unassoc time error (%d)\n", err)); + WL_ERR("Scan unassoc time error (%d)\n", err); } goto dongle_scantime_out; } @@ -3589,9 +3589,9 @@ wl_dongle_offload(struct net_device *ndev, s32 arpoe, s32 arp_ol) err = wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf)); if (err) { if (err == -EOPNOTSUPP) - WL_INFO(("arpoe is not supported\n")); + WL_INFO("arpoe is not supported\n"); else - WL_ERR(("arpoe error (%d)\n", err)); + WL_ERR("arpoe error (%d)\n", err); goto dongle_offload_out; } @@ -3599,9 +3599,9 @@ wl_dongle_offload(struct net_device *ndev, s32 arpoe, s32 arp_ol) err = wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf)); if (err) { if (err == -EOPNOTSUPP) - WL_INFO(("arp_ol is not supported\n")); + WL_INFO("arp_ol is not supported\n"); else - WL_ERR(("arp_ol error (%d)\n", err)); + WL_ERR("arp_ol error (%d)\n", err); goto dongle_offload_out; } @@ -3614,12 +3614,12 @@ static s32 wl_pattern_atoh(s8 *src, s8 *dst) { int i; if (strncmp(src, "0x", 2) != 0 && strncmp(src, "0X", 2) != 0) { - WL_ERR(("Mask invalid format. Needs to start with 0x\n")); + WL_ERR("Mask invalid format. Needs to start with 0x\n"); return -1; } src = src + 2; /* Skip past 0x */ if (strlen(src) % 2 != 0) { - WL_ERR(("Mask invalid format. Needs to be of even length\n")); + WL_ERR("Mask invalid format. Needs to be of even length\n"); return -1; } for (i = 0; *src != '\0'; i++) { @@ -3678,7 +3678,7 @@ static s32 wl_dongle_filter(struct net_device *ndev, u32 filter_mode) mask_and_pattern[mask_size])); if (mask_size != pattern_size) { - WL_ERR(("Mask and pattern not the same size\n")); + WL_ERR("Mask and pattern not the same size\n"); err = -EINVAL; goto dongle_filter_out; } @@ -3698,9 +3698,9 @@ static s32 wl_dongle_filter(struct net_device *ndev, u32 filter_mode) err = wl_dev_ioctl(ndev, WLC_SET_VAR, buf, buf_len); if (err) { if (err == -EOPNOTSUPP) { - WL_INFO(("filter not supported\n")); + WL_INFO("filter not supported\n"); } else { - WL_ERR(("filter (%d)\n", err)); + WL_ERR("filter (%d)\n", err); } goto dongle_filter_out; } @@ -3711,9 +3711,9 @@ static s32 wl_dongle_filter(struct net_device *ndev, u32 filter_mode) err = wl_dev_ioctl(ndev, WLC_SET_VAR, iovbuf, sizeof(iovbuf)); if (err) { if (err == -EOPNOTSUPP) { - WL_INFO(("filter_mode not supported\n")); + WL_INFO("filter_mode not supported\n"); } else { - WL_ERR(("filter_mode (%d)\n", err)); + WL_ERR("filter_mode (%d)\n", err); } goto dongle_filter_out; } @@ -3794,12 +3794,12 @@ static s32 wl_update_wiphybands(struct wl_priv *wl) err = wl_dev_ioctl(wl_to_ndev(wl), WLC_GET_PHYLIST, &phy_list, sizeof(phy_list)); if (unlikely(err)) { - WL_ERR(("error (%d)\n", err)); + WL_ERR("error (%d)\n", err); return err; } phy = ((char *)&phy_list)[1]; - WL_DBG(("%c phy\n", phy)); + WL_DBG("%c phy\n", phy); if (phy == 'n' || phy == 'a') { wiphy = wl_to_wiphy(wl); wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_n; @@ -3905,7 +3905,7 @@ static void *wl_read_prof(struct wl_priv *wl, s32 item) case WL_PROF_SSID: return &wl->profile->ssid; } - WL_ERR(("invalid item (%d)\n", item)); + WL_ERR("invalid item (%d)\n", item); return NULL; } @@ -3943,7 +3943,7 @@ wl_update_prof(struct wl_priv *wl, const wl_event_msg_t *e, void *data, wl->profile->dtim_period = *(u8 *)data; break; default: - WL_ERR(("unsupported item (%d)\n", item)); + WL_ERR("unsupported item (%d)\n", item); err = -EOPNOTSUPP; break; } @@ -3985,7 +3985,7 @@ static __used s32 wl_add_ie(struct wl_priv *wl, u8 t, u8 l, u8 *v) s32 err = 0; if (unlikely(ie->offset + l + 2 > WL_TLV_INFO_MAX)) { - WL_ERR(("ei crosses buffer boundary\n")); + WL_ERR("ei crosses buffer boundary\n"); return -ENOSPC; } ie->buf[ie->offset] = t; @@ -4002,7 +4002,7 @@ static s32 wl_mrg_ie(struct wl_priv *wl, u8 *ie_stream, u16 ie_size) s32 err = 0; if (unlikely(ie->offset + ie_size > WL_TLV_INFO_MAX)) { - WL_ERR(("ei_stream crosses buffer boundary\n")); + WL_ERR("ei_stream crosses buffer boundary\n"); return -ENOSPC; } memcpy(&ie->buf[ie->offset], ie_stream, ie_size); @@ -4017,7 +4017,7 @@ static s32 wl_cp_ie(struct wl_priv *wl, u8 *dst, u16 dst_size) s32 err = 0; if (unlikely(ie->offset > dst_size)) { - WL_ERR(("dst_size is not enough\n")); + WL_ERR("dst_size is not enough\n"); return -ENOSPC; } memcpy(dst, &ie->buf[0], ie->offset); @@ -4117,37 +4117,37 @@ void *wl_cfg80211_request_fw(s8 *file_name) const struct firmware *fw_entry = NULL; s32 err = 0; - WL_DBG(("file name : \"%s\"\n", file_name)); + WL_DBG("file name : \"%s\"\n", file_name); wl = WL_PRIV_GET(); if (!test_bit(WL_FW_LOADING_DONE, &wl->fw->status)) { err = request_firmware(&wl->fw->fw_entry, file_name, &wl_cfg80211_get_sdio_func()->dev); if (unlikely(err)) { - WL_ERR(("Could not download fw (%d)\n", err)); + WL_ERR("Could not download fw (%d)\n", err); goto req_fw_out; } set_bit(WL_FW_LOADING_DONE, &wl->fw->status); fw_entry = wl->fw->fw_entry; if (fw_entry) { - WL_DBG(("fw size (%zd), data (%p)\n", fw_entry->size, - fw_entry->data)); + WL_DBG("fw size (%zd), data (%p)\n", + fw_entry->size, fw_entry->data); } } else if (!test_bit(WL_NVRAM_LOADING_DONE, &wl->fw->status)) { err = request_firmware(&wl->fw->fw_entry, file_name, &wl_cfg80211_get_sdio_func()->dev); if (unlikely(err)) { - WL_ERR(("Could not download nvram (%d)\n", err)); + WL_ERR("Could not download nvram (%d)\n", err); goto req_fw_out; } set_bit(WL_NVRAM_LOADING_DONE, &wl->fw->status); fw_entry = wl->fw->fw_entry; if (fw_entry) { - WL_DBG(("nvram size (%zd), data (%p)\n", fw_entry->size, - fw_entry->data)); + WL_DBG("nvram size (%zd), data (%p)\n", + fw_entry->size, fw_entry->data); } } else { - WL_DBG(("Downloading already done. Nothing to do more\n")); + WL_DBG("Downloading already done. Nothing to do more\n"); err = -EPERM; } @@ -4183,10 +4183,10 @@ static void wl_set_mpc(struct net_device *ndev, int mpc) err = wl_dev_intvar_set(ndev, "mpc", mpc); if (unlikely(err)) { - WL_ERR(("fail to set mpc\n")); + WL_ERR("fail to set mpc\n"); return; } - WL_DBG(("MPC : %d\n", mpc)); + WL_DBG("MPC : %d\n", mpc); } static int wl_debugfs_add_netdev_params(struct wl_priv *wl) diff --git a/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.h b/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.h index 1069e65f8ce6..482691be210a 100644 --- a/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.h +++ b/drivers/staging/brcm80211/brcmfmac/wl_cfg80211.h @@ -54,34 +54,36 @@ struct wl_ibss; #define WL_DBG_LEVEL 1 /* 0 invalidates all debug messages. default is 1 */ -#define WL_ERR(args) \ -do { \ - if (wl_dbg_level & WL_DBG_ERR) { \ - if (net_ratelimit()) { \ - printk(KERN_ERR "ERROR @%s : ", __func__); \ - printk args; \ - } \ - } \ +#define WL_ERR(fmt, args...) \ +do { \ + if (wl_dbg_level & WL_DBG_ERR) { \ + if (net_ratelimit()) { \ + printk(KERN_ERR "ERROR @%s : " fmt, \ + __func__, ##args); \ + } \ + } \ } while (0) -#define WL_INFO(args) \ -do { \ - if (wl_dbg_level & WL_DBG_INFO) { \ - if (net_ratelimit()) { \ - printk(KERN_ERR "INFO @%s : ", __func__); \ - printk args; \ - } \ - } \ + +#define WL_INFO(fmt, args...) \ +do { \ + if (wl_dbg_level & WL_DBG_INFO) { \ + if (net_ratelimit()) { \ + printk(KERN_ERR "INFO @%s : " fmt, \ + __func__, ##args); \ + } \ + } \ } while (0) + #if (WL_DBG_LEVEL > 0) -#define WL_DBG(args) \ -do { \ +#define WL_DBG(fmt, args...) \ +do { \ if (wl_dbg_level & WL_DBG_DBG) { \ - printk(KERN_ERR "DEBUG @%s :", __func__); \ - printk args; \ - } \ + printk(KERN_ERR "DEBUG @%s :" fmt, \ + __func__, ##args); \ + } \ } while (0) #else /* !(WL_DBG_LEVEL > 0) */ -#define WL_DBG(args) +#define WL_DBG(fmt, args...) noprintk(fmt, ##args) #endif /* (WL_DBG_LEVEL > 0) */ #define WL_SCAN_RETRY_MAX 3 /* used for ibss scan */ diff --git a/drivers/staging/brcm80211/brcmfmac/wl_iw.c b/drivers/staging/brcm80211/brcmfmac/wl_iw.c index 14580b2ea198..db6e68eab290 100644 --- a/drivers/staging/brcm80211/brcmfmac/wl_iw.c +++ b/drivers/staging/brcm80211/brcmfmac/wl_iw.c @@ -39,12 +39,11 @@ typedef const struct si_pub si_t; #include #include -#define WL_ERROR(x) printf x -#define WL_TRACE(x) -#define WL_ASSOC(x) -#define WL_INFORM(x) -#define WL_WSEC(x) -#define WL_SCAN(x) +#define WL_ERROR(fmt, args...) printk(fmt, ##args) +#define WL_TRACE(fmt, args...) no_printk(fmt, ##args) +#define WL_INFORM(fmt, args...) no_printk(fmt, ##args) +#define WL_WSEC(fmt, args...) no_printk(fmt, ##args) +#define WL_SCAN(fmt, args...) no_printk(fmt, ##args) #include @@ -187,12 +186,12 @@ static int dev_wlc_ioctl(struct net_device *dev, int cmd, void *arg, int len) int ret = -EINVAL; if (!dev) { - WL_ERROR(("%s: dev is null\n", __func__)); + WL_ERROR("%s: dev is null\n", __func__); return ret; } - WL_INFORM(("\n%s, PID:%x: send Local IOCTL -> dhd: cmd:0x%x, buf:%p, " - "len:%d ,\n", __func__, current->pid, cmd, arg, len)); + WL_INFORM("\n%s, PID:%x: send Local IOCTL -> dhd: cmd:0x%x, buf:%p, len:%d\n", + __func__, current->pid, cmd, arg, len); if (g_onoff == G_WLAN_SET_ON) { memset(&ioc, 0, sizeof(ioc)); @@ -205,7 +204,7 @@ static int dev_wlc_ioctl(struct net_device *dev, int cmd, void *arg, int len) ret = dev_open(dev); if (ret) { - WL_ERROR(("%s: Error dev_open: %d\n", __func__, ret)); + WL_ERROR("%s: Error dev_open: %d\n", __func__, ret); return ret; } @@ -214,7 +213,7 @@ static int dev_wlc_ioctl(struct net_device *dev, int cmd, void *arg, int len) ret = dev->netdev_ops->ndo_do_ioctl(dev, &ifr, SIOCDEVPRIVATE); set_fs(fs); } else { - WL_TRACE(("%s: call after driver stop : ignored\n", __func__)); + WL_TRACE("%s: call after driver stop : ignored\n", __func__); } return ret; } @@ -335,7 +334,7 @@ wl_iw_config_commit(struct net_device *dev, int error; struct sockaddr bssid; - WL_TRACE(("%s: SIOCSIWCOMMIT\n", dev->name)); + WL_TRACE("%s: SIOCSIWCOMMIT\n", dev->name); error = dev_wlc_ioctl(dev, WLC_GET_SSID, &ssid, sizeof(ssid)); if (error) @@ -349,8 +348,8 @@ wl_iw_config_commit(struct net_device *dev, memset(&bssid, 0, sizeof(struct sockaddr)); error = dev_wlc_ioctl(dev, WLC_REASSOC, &bssid, ETH_ALEN); if (error) { - WL_ERROR(("%s: WLC_REASSOC to %s failed\n", __func__, - ssid.SSID)); + WL_ERROR("%s: WLC_REASSOC to %s failed\n", + __func__, ssid.SSID); return error; } @@ -361,7 +360,7 @@ static int wl_iw_get_name(struct net_device *dev, struct iw_request_info *info, char *cwrq, char *extra) { - WL_TRACE(("%s: SIOCGIWNAME\n", dev->name)); + WL_TRACE("%s: SIOCGIWNAME\n", dev->name); strcpy(cwrq, "IEEE 802.11-DS"); @@ -375,7 +374,7 @@ wl_iw_set_freq(struct net_device *dev, int error, chan; uint sf = 0; - WL_TRACE(("\n %s %s: SIOCSIWFREQ\n", __func__, dev->name)); + WL_TRACE("\n %s %s: SIOCSIWFREQ\n", __func__, dev->name); if (fwrq->e == 0 && fwrq->m < MAXCHANNEL) { chan = fwrq->m; @@ -410,7 +409,7 @@ wl_iw_get_freq(struct net_device *dev, channel_info_t ci; int error; - WL_TRACE(("%s: SIOCGIWFREQ\n", dev->name)); + WL_TRACE("%s: SIOCGIWFREQ\n", dev->name); error = dev_wlc_ioctl(dev, WLC_GET_CHANNEL, &ci, sizeof(ci)); if (error) @@ -427,7 +426,7 @@ wl_iw_set_mode(struct net_device *dev, { int infra = 0, ap = 0, error = 0; - WL_TRACE(("%s: SIOCSIWMODE\n", dev->name)); + WL_TRACE("%s: SIOCSIWMODE\n", dev->name); switch (*uwrq) { case IW_MODE_MASTER: @@ -462,7 +461,7 @@ wl_iw_get_mode(struct net_device *dev, { int error, infra = 0, ap = 0; - WL_TRACE(("%s: SIOCGIWMODE\n", dev->name)); + WL_TRACE("%s: SIOCGIWMODE\n", dev->name); error = dev_wlc_ioctl(dev, WLC_GET_INFRA, &infra, sizeof(infra)); if (error) @@ -501,14 +500,14 @@ wl_iw_get_range(struct net_device *dev, {30, 60, 90, 120, 180, 240, 270, 300} }; - WL_TRACE(("%s: SIOCGIWRANGE\n", dev->name)); + WL_TRACE("%s: SIOCGIWRANGE\n", dev->name); if (!extra) return -EINVAL; channels = kmalloc((MAXCHANNEL + 1) * 4, GFP_KERNEL); if (!channels) { - WL_ERROR(("Could not alloc channels\n")); + WL_ERROR("Could not alloc channels\n"); return -ENOMEM; } list = (wl_u32_list_t *) channels; @@ -684,7 +683,7 @@ wl_iw_set_spy(struct net_device *dev, struct sockaddr *addr = (struct sockaddr *)extra; int i; - WL_TRACE(("%s: SIOCSIWSPY\n", dev->name)); + WL_TRACE("%s: SIOCSIWSPY\n", dev->name); if (!extra) return -EINVAL; @@ -706,7 +705,7 @@ wl_iw_get_spy(struct net_device *dev, struct iw_quality *qual = (struct iw_quality *)&addr[iw->spy_num]; int i; - WL_TRACE(("%s: SIOCGIWSPY\n", dev->name)); + WL_TRACE("%s: SIOCGIWSPY\n", dev->name); if (!extra) return -EINVAL; @@ -751,8 +750,8 @@ wl_iw_ch_to_chanspec(int ch, wl_join_params_t *join_params, join_params->params.chanspec_num = htod32(join_params->params.chanspec_num); - WL_TRACE(("%s join_params->params.chanspec_list[0]= %X\n", - __func__, join_params->params.chanspec_list[0])); + WL_TRACE("%s join_params->params.chanspec_list[0]= %X\n", + __func__, join_params->params.chanspec_list[0]); } return 1; } @@ -765,10 +764,10 @@ wl_iw_set_wap(struct net_device *dev, wl_join_params_t join_params; int join_params_size; - WL_TRACE(("%s: SIOCSIWAP\n", dev->name)); + WL_TRACE("%s: SIOCSIWAP\n", dev->name); if (awrq->sa_family != ARPHRD_ETHER) { - WL_ERROR(("Invalid Header...sa_family\n")); + WL_ERROR("Invalid Header...sa_family\n"); return -EINVAL; } @@ -788,21 +787,21 @@ wl_iw_set_wap(struct net_device *dev, join_params.ssid.SSID_len = htod32(g_ssid.SSID_len); memcpy(&join_params.params.bssid, awrq->sa_data, ETH_ALEN); - WL_TRACE(("%s target_channel=%d\n", __func__, - g_wl_iw_params.target_channel)); + WL_TRACE("%s target_channel=%d\n", + __func__, g_wl_iw_params.target_channel); wl_iw_ch_to_chanspec(g_wl_iw_params.target_channel, &join_params, &join_params_size); error = dev_wlc_ioctl(dev, WLC_SET_SSID, &join_params, join_params_size); if (error) { - WL_ERROR(("%s Invalid ioctl data=%d\n", __func__, error)); + WL_ERROR("%s Invalid ioctl data=%d\n", __func__, error); } if (g_ssid.SSID_len) { - WL_TRACE(("%s: join SSID=%s BSSID=%pM ch=%d\n", - __func__, g_ssid.SSID, awrq->sa_data, - g_wl_iw_params.target_channel)); + WL_TRACE("%s: join SSID=%s BSSID=%pM ch=%d\n", + __func__, g_ssid.SSID, awrq->sa_data, + g_wl_iw_params.target_channel); } memset(&g_ssid, 0, sizeof(g_ssid)); @@ -813,7 +812,7 @@ static int wl_iw_get_wap(struct net_device *dev, struct iw_request_info *info, struct sockaddr *awrq, char *extra) { - WL_TRACE(("%s: SIOCGIWAP\n", dev->name)); + WL_TRACE("%s: SIOCGIWAP\n", dev->name); awrq->sa_family = ARPHRD_ETHER; memset(awrq->sa_data, 0, ETH_ALEN); @@ -832,11 +831,11 @@ wl_iw_mlme(struct net_device *dev, scb_val_t scbval; int error = -EINVAL; - WL_TRACE(("%s: SIOCSIWMLME DISASSOC/DEAUTH\n", dev->name)); + WL_TRACE("%s: SIOCSIWMLME DISASSOC/DEAUTH\n", dev->name); mlme = (struct iw_mlme *)extra; if (mlme == NULL) { - WL_ERROR(("Invalid ioctl data.\n")); + WL_ERROR("Invalid ioctl data\n"); return error; } @@ -854,7 +853,7 @@ wl_iw_mlme(struct net_device *dev, dev_wlc_ioctl(dev, WLC_SCB_DEAUTHENTICATE_FOR_REASON, &scbval, sizeof(scb_val_t)); } else { - WL_ERROR(("Invalid ioctl data.\n")); + WL_ERROR("Invalid ioctl data\n"); return error; } @@ -875,7 +874,7 @@ wl_iw_get_aplist(struct net_device *dev, int error, i; uint buflen = dwrq->length; - WL_TRACE(("%s: SIOCGIWAPLIST\n", dev->name)); + WL_TRACE("%s: SIOCGIWAPLIST\n", dev->name); if (!extra) return -EINVAL; @@ -887,7 +886,7 @@ wl_iw_get_aplist(struct net_device *dev, list->buflen = htod32(buflen); error = dev_wlc_ioctl(dev, WLC_SCAN_RESULTS, list, buflen); if (error) { - WL_ERROR(("%d: Scan results error %d\n", __LINE__, error)); + WL_ERROR("%d: Scan results error %d\n", __LINE__, error); kfree(list); return error; } @@ -895,8 +894,8 @@ wl_iw_get_aplist(struct net_device *dev, list->version = dtoh32(list->version); list->count = dtoh32(list->count); if (list->version != WL_BSS_INFO_VERSION) { - WL_ERROR(("%s : list->version %d != WL_BSS_INFO_VERSION\n", - __func__, list->version)); + WL_ERROR("%s : list->version %d != WL_BSS_INFO_VERSION\n", + __func__, list->version); kfree(list); return -EINVAL; } @@ -953,13 +952,13 @@ wl_iw_iscan_get_aplist(struct net_device *dev, wl_bss_info_t *bi = NULL; int i; - WL_TRACE(("%s: SIOCGIWAPLIST\n", dev->name)); + WL_TRACE("%s: SIOCGIWAPLIST\n", dev->name); if (!extra) return -EINVAL; if ((!iscan) || (!iscan->sysioc_tsk)) { - WL_ERROR(("%s error\n", __func__)); + WL_ERROR("%s error\n", __func__); return 0; } @@ -967,9 +966,8 @@ wl_iw_iscan_get_aplist(struct net_device *dev, while (buf) { list = &((wl_iscan_results_t *) buf->iscan_buf)->results; if (list->version != WL_BSS_INFO_VERSION) { - WL_ERROR(("%s : list->version %d != " - "WL_BSS_INFO_VERSION\n", - __func__, list->version)); + WL_ERROR("%s : list->version %d != WL_BSS_INFO_VERSION\n", + __func__, list->version); return -EINVAL; } @@ -1044,15 +1042,15 @@ static int wl_iw_iscan(iscan_info_t *iscan, wlc_ssid_t *ssid, u16 action) iscan->iscan_ex_params_p->action = htod16(action); iscan->iscan_ex_params_p->scan_duration = htod16(0); - WL_SCAN(("%s : nprobes=%d\n", __func__, - iscan->iscan_ex_params_p->params.nprobes)); - WL_SCAN(("active_time=%d\n", - iscan->iscan_ex_params_p->params.active_time)); - WL_SCAN(("passive_time=%d\n", - iscan->iscan_ex_params_p->params.passive_time)); - WL_SCAN(("home_time=%d\n", iscan->iscan_ex_params_p->params.home_time)); - WL_SCAN(("scan_type=%d\n", iscan->iscan_ex_params_p->params.scan_type)); - WL_SCAN(("bss_type=%d\n", iscan->iscan_ex_params_p->params.bss_type)); + WL_SCAN("%s : nprobes=%d\n", + __func__, iscan->iscan_ex_params_p->params.nprobes); + WL_SCAN("active_time=%d\n", + iscan->iscan_ex_params_p->params.active_time); + WL_SCAN("passive_time=%d\n", + iscan->iscan_ex_params_p->params.passive_time); + WL_SCAN("home_time=%d\n", iscan->iscan_ex_params_p->params.home_time); + WL_SCAN("scan_type=%d\n", iscan->iscan_ex_params_p->params.scan_type); + WL_SCAN("bss_type=%d\n", iscan->iscan_ex_params_p->params.bss_type); (void)dev_iw_iovar_setbuf(iscan->dev, "iscan", iscan->iscan_ex_params_p, iscan->iscan_ex_param_size, iscan->ioctlbuf, @@ -1067,7 +1065,7 @@ static void wl_iw_timerfunc(unsigned long data) if (iscan) { iscan->timer_on = 0; if (iscan->iscan_state != ISCAN_STATE_IDLE) { - WL_TRACE(("timer trigger\n")); + WL_TRACE("timer trigger\n"); up(&iscan->sysioc_sem); } } @@ -1102,8 +1100,8 @@ static u32 wl_iw_iscan_get(iscan_info_t *iscan) } else { buf = kmalloc(sizeof(iscan_buf_t), GFP_KERNEL); if (!buf) { - WL_ERROR(("%s can't alloc iscan_buf_t : going to abort " - "currect iscan\n", __func__)); + WL_ERROR("%s can't alloc iscan_buf_t : going to abort current iscan\n", + __func__); MUTEX_UNLOCK_WL_SCAN_SET(); return WL_SCAN_RESULTS_NO_MEM; } @@ -1136,11 +1134,11 @@ static u32 wl_iw_iscan_get(iscan_info_t *iscan) results->buflen = dtoh32(results->buflen); results->version = dtoh32(results->version); results->count = dtoh32(results->count); - WL_TRACE(("results->count = %d\n", results->count)); - WL_TRACE(("results->buflen = %d\n", results->buflen)); + WL_TRACE("results->count = %d\n", results->count); + WL_TRACE("results->buflen = %d\n", results->buflen); status = dtoh32(list_buf->status); } else { - WL_ERROR(("%s returns error %d\n", __func__, res)); + WL_ERROR("%s returns error %d\n", __func__, res); status = WL_SCAN_RESULTS_NO_MEM; } MUTEX_UNLOCK_WL_SCAN_SET(); @@ -1149,8 +1147,8 @@ static u32 wl_iw_iscan_get(iscan_info_t *iscan) static void wl_iw_force_specific_scan(iscan_info_t *iscan) { - WL_TRACE(("%s force Specific SCAN for %s\n", __func__, - g_specific_ssid.SSID)); + WL_TRACE("%s force Specific SCAN for %s\n", + __func__, g_specific_ssid.SSID); rtnl_lock(); (void)dev_wlc_ioctl(iscan->dev, WLC_SCAN, &g_specific_ssid, @@ -1167,7 +1165,7 @@ static void wl_iw_send_scan_complete(iscan_info_t *iscan) memset(&wrqu, 0, sizeof(wrqu)); wireless_send_event(iscan->dev, SIOCGIWSCAN, &wrqu, NULL); - WL_TRACE(("Send Event ISCAN complete\n")); + WL_TRACE("Send Event ISCAN complete\n"); #endif } @@ -1191,8 +1189,8 @@ static int _iscan_sysioc_thread(void *data) status = wl_iw_iscan_get(iscan); rtnl_unlock(); if (g_scan_specified_ssid && (iscan_pass_abort == true)) { - WL_TRACE(("%s Get results from specific scan " - "status = %d\n", __func__, status)); + WL_TRACE("%s Get results from specific scan status = %d\n", + __func__, status); wl_iw_send_scan_complete(iscan); iscan_pass_abort = false; status = -1; @@ -1200,7 +1198,7 @@ static int _iscan_sysioc_thread(void *data) switch (status) { case WL_SCAN_RESULTS_PARTIAL: - WL_TRACE(("iscanresults incomplete\n")); + WL_TRACE("iscanresults incomplete\n"); rtnl_lock(); wl_iw_iscan(iscan, NULL, WL_SCAN_ACTION_CONTINUE); rtnl_unlock(); @@ -1209,18 +1207,18 @@ static int _iscan_sysioc_thread(void *data) iscan->timer_on = 1; break; case WL_SCAN_RESULTS_SUCCESS: - WL_TRACE(("iscanresults complete\n")); + WL_TRACE("iscanresults complete\n"); iscan->iscan_state = ISCAN_STATE_IDLE; wl_iw_send_scan_complete(iscan); break; case WL_SCAN_RESULTS_PENDING: - WL_TRACE(("iscanresults pending\n")); + WL_TRACE("iscanresults pending\n"); mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000); iscan->timer_on = 1; break; case WL_SCAN_RESULTS_ABORTED: - WL_TRACE(("iscanresults aborted\n")); + WL_TRACE("iscanresults aborted\n"); iscan->iscan_state = ISCAN_STATE_IDLE; if (g_scan_specified_ssid == 0) wl_iw_send_scan_complete(iscan); @@ -1230,12 +1228,12 @@ static int _iscan_sysioc_thread(void *data) } break; case WL_SCAN_RESULTS_NO_MEM: - WL_TRACE(("iscanresults can't alloc memory: skip\n")); + WL_TRACE("iscanresults can't alloc memory: skip\n"); iscan->iscan_state = ISCAN_STATE_IDLE; break; default: - WL_TRACE(("iscanresults returned unknown status %d\n", - status)); + WL_TRACE("iscanresults returned unknown status %d\n", + status); break; } } @@ -1254,11 +1252,11 @@ wl_iw_set_scan(struct net_device *dev, union iwreq_data *wrqu, char *extra) { int error; - WL_TRACE(("\n:%s dev:%s: SIOCSIWSCAN : SCAN\n", __func__, dev->name)); + WL_TRACE("\n:%s dev:%s: SIOCSIWSCAN : SCAN\n", __func__, dev->name); g_set_essid_before_scan = false; #if defined(CSCAN) - WL_ERROR(("%s: Scan from SIOCGIWSCAN not supported\n", __func__)); + WL_ERROR("%s: Scan from SIOCGIWSCAN not supported\n", __func__); return -EINVAL; #endif @@ -1275,9 +1273,8 @@ wl_iw_set_scan(struct net_device *dev, if (wrqu->data.flags & IW_SCAN_THIS_ESSID) { struct iw_scan_req *req = (struct iw_scan_req *)extra; if (g_scan_specified_ssid) { - WL_TRACE(("%s Specific SCAN is not done ignore " - "scan for = %s\n", - __func__, req->essid)); + WL_TRACE("%s Specific SCAN is not done ignore scan for = %s\n", + __func__, req->essid); return -EBUSY; } else { g_specific_ssid.SSID_len = min_t(size_t, @@ -1288,9 +1285,9 @@ wl_iw_set_scan(struct net_device *dev, g_specific_ssid.SSID_len = htod32(g_specific_ssid.SSID_len); g_scan_specified_ssid = 1; - WL_TRACE(("### Specific scan ssid=%s len=%d\n", - g_specific_ssid.SSID, - g_specific_ssid.SSID_len)); + WL_TRACE("### Specific scan ssid=%s len=%d\n", + g_specific_ssid.SSID, + g_specific_ssid.SSID_len); } } } @@ -1298,8 +1295,8 @@ wl_iw_set_scan(struct net_device *dev, error = dev_wlc_ioctl(dev, WLC_SCAN, &g_specific_ssid, sizeof(g_specific_ssid)); if (error) { - WL_TRACE(("#### Set SCAN for %s failed with %d\n", - g_specific_ssid.SSID, error)); + WL_TRACE("#### Set SCAN for %s failed with %d\n", + g_specific_ssid.SSID, error); g_scan_specified_ssid = 0; return -EBUSY; } @@ -1318,7 +1315,7 @@ int wl_iw_iscan_set_scan_broadcast_prep(struct net_device *dev, uint flag) wl_iw_set_event_mask(dev); - WL_TRACE(("+++: Set Broadcast ISCAN\n")); + WL_TRACE("+++: Set Broadcast ISCAN\n"); memset(&ssid, 0, sizeof(ssid)); iscan->list_cur = iscan->list_hdr; @@ -1347,20 +1344,20 @@ wl_iw_iscan_set_scan(struct net_device *dev, wlc_ssid_t ssid; iscan_info_t *iscan = g_iscan; - WL_TRACE(("%s: SIOCSIWSCAN : ISCAN\n", dev->name)); + WL_TRACE("%s: SIOCSIWSCAN : ISCAN\n", dev->name); #if defined(CSCAN) - WL_ERROR(("%s: Scan from SIOCGIWSCAN not supported\n", __func__)); + WL_ERROR("%s: Scan from SIOCGIWSCAN not supported\n", __func__); return -EINVAL; #endif if (g_onoff == G_WLAN_SET_OFF) { - WL_TRACE(("%s: driver is not up yet after START\n", __func__)); + WL_TRACE("%s: driver is not up yet after START\n", __func__); return 0; } #ifdef PNO_SUPPORT if (dhd_dev_get_pno_status(dev)) { - WL_ERROR(("%s: Scan called when PNO is active\n", __func__)); + WL_ERROR("%s: Scan called when PNO is active\n", __func__); } #endif @@ -1368,8 +1365,8 @@ wl_iw_iscan_set_scan(struct net_device *dev, return wl_iw_set_scan(dev, info, wrqu, extra); if (g_scan_specified_ssid) { - WL_TRACE(("%s Specific SCAN already running ignoring BC scan\n", - __func__)); + WL_TRACE("%s Specific SCAN already running ignoring BC scan\n", + __func__); return EBUSY; } @@ -1387,8 +1384,8 @@ wl_iw_iscan_set_scan(struct net_device *dev, g_scan_specified_ssid = 0; if (iscan->iscan_state == ISCAN_STATE_SCANING) { - WL_TRACE(("%s ISCAN already in progress \n", - __func__)); + WL_TRACE("%s ISCAN already in progress\n", + __func__); return 0; } } @@ -1502,9 +1499,8 @@ wl_iw_get_scan_prep(wl_scan_results_t *list, for (i = 0; i < list->count && i < IW_MAX_AP; i++) { if (list->version != WL_BSS_INFO_VERSION) { - WL_ERROR(("%s : list->version %d != " - "WL_BSS_INFO_VERSION\n", - __func__, list->version)); + WL_ERROR("%s : list->version %d != WL_BSS_INFO_VERSION\n", + __func__, list->version); return ret; } @@ -1512,7 +1508,7 @@ wl_iw_get_scan_prep(wl_scan_results_t *list, dtoh32(bi->length)) : list-> bss_info; - WL_TRACE(("%s : %s\n", __func__, bi->SSID)); + WL_TRACE("%s : %s\n", __func__, bi->SSID); iwe.cmd = SIOCGIWAP; iwe.u.ap_addr.sa_family = ARPHRD_ETHER; @@ -1591,11 +1587,11 @@ wl_iw_get_scan_prep(wl_scan_results_t *list, ret = event - extra; if (ret < 0) { - WL_ERROR(("==> Wrong size\n")); + WL_ERROR("==> Wrong size\n"); ret = 0; } - WL_TRACE(("%s: size=%d bytes prepared\n", __func__, - (unsigned int)(event - extra))); + WL_TRACE("%s: size=%d bytes prepared\n", + __func__, (unsigned int)(event - extra)); return (uint)ret; } @@ -1615,10 +1611,10 @@ wl_iw_get_scan(struct net_device *dev, iscan_buf_t *p_buf; #endif - WL_TRACE(("%s: buflen_from_user %d: \n", dev->name, buflen_from_user)); + WL_TRACE("%s: buflen_from_user %d:\n", dev->name, buflen_from_user); if (!extra) { - WL_TRACE(("%s: wl_iw_get_scan return -EINVAL\n", dev->name)); + WL_TRACE("%s: wl_iw_get_scan return -EINVAL\n", dev->name); return -EINVAL; } @@ -1632,8 +1628,8 @@ wl_iw_get_scan(struct net_device *dev, if (g_scan_specified_ssid) { list = kmalloc(len, GFP_KERNEL); if (!list) { - WL_TRACE(("%s: wl_iw_get_scan return -ENOMEM\n", - dev->name)); + WL_TRACE("%s: wl_iw_get_scan return -ENOMEM\n", + dev->name); g_scan_specified_ssid = 0; return -ENOMEM; } @@ -1643,8 +1639,8 @@ wl_iw_get_scan(struct net_device *dev, list->buflen = htod32(len); error = dev_wlc_ioctl(dev, WLC_SCAN_RESULTS, list, len); if (error) { - WL_ERROR(("%s: %s : Scan_results ERROR %d\n", dev->name, - __func__, error)); + WL_ERROR("%s: %s : Scan_results ERROR %d\n", + dev->name, __func__, error); dwrq->length = len; if (g_scan_specified_ssid) { g_scan_specified_ssid = 0; @@ -1657,8 +1653,8 @@ wl_iw_get_scan(struct net_device *dev, list->count = dtoh32(list->count); if (list->version != WL_BSS_INFO_VERSION) { - WL_ERROR(("%s : list->version %d != WL_BSS_INFO_VERSION\n", - __func__, list->version)); + WL_ERROR("%s : list->version %d != WL_BSS_INFO_VERSION\n", + __func__, list->version); if (g_scan_specified_ssid) { g_scan_specified_ssid = 0; kfree(list); @@ -1667,8 +1663,8 @@ wl_iw_get_scan(struct net_device *dev, } if (g_scan_specified_ssid) { - WL_TRACE(("%s: Specified scan APs in the list =%d\n", - __func__, list->count)); + WL_TRACE("%s: Specified scan APs in the list =%d\n", + __func__, list->count); len_ret = (__u16) wl_iw_get_scan_prep(list, info, extra, buflen_from_user); @@ -1679,8 +1675,8 @@ wl_iw_get_scan(struct net_device *dev, while (p_buf != iscan->list_cur) { list_merge = &((wl_iscan_results_t *) p_buf->iscan_buf)->results; - WL_TRACE(("%s: Bcast APs list=%d\n", __func__, - list_merge->count)); + WL_TRACE("%s: Bcast APs list=%d\n", + __func__, list_merge->count); if (list_merge->count > 0) len_ret += (__u16) wl_iw_get_scan_prep(list_merge, @@ -1690,8 +1686,8 @@ wl_iw_get_scan(struct net_device *dev, } #else list_merge = (wl_scan_results_t *) g_scan; - WL_TRACE(("%s: Bcast APs list=%d\n", __func__, - list_merge->count)); + WL_TRACE("%s: Bcast APs list=%d\n", + __func__, list_merge->count); if (list_merge->count > 0) len_ret += (__u16) wl_iw_get_scan_prep(list_merge, info, @@ -1715,8 +1711,8 @@ wl_iw_get_scan(struct net_device *dev, dwrq->length = len; dwrq->flags = 0; - WL_TRACE(("%s return to WE %d bytes APs=%d\n", __func__, - dwrq->length, list->count)); + WL_TRACE("%s return to WE %d bytes APs=%d\n", + __func__, dwrq->length, list->count); return 0; } @@ -1737,26 +1733,26 @@ wl_iw_iscan_get_scan(struct net_device *dev, u32 counter = 0; u8 channel; - WL_TRACE(("%s %s buflen_from_user %d:\n", dev->name, __func__, - dwrq->length)); + WL_TRACE("%s %s buflen_from_user %d:\n", + dev->name, __func__, dwrq->length); if (!extra) { - WL_TRACE(("%s: INVALID SIOCGIWSCAN GET bad parameter\n", - dev->name)); + WL_TRACE("%s: INVALID SIOCGIWSCAN GET bad parameter\n", + dev->name); return -EINVAL; } if ((!iscan) || (!iscan->sysioc_tsk)) { - WL_ERROR(("%ssysioc_tsk\n", __func__)); + WL_ERROR("%ssysioc_tsk\n", __func__); return wl_iw_get_scan(dev, info, dwrq, extra); } if (iscan->iscan_state == ISCAN_STATE_SCANING) { - WL_TRACE(("%s: SIOCGIWSCAN GET still scanning\n", dev->name)); + WL_TRACE("%s: SIOCGIWSCAN GET still scanning\n", dev->name); return -EAGAIN; } - WL_TRACE(("%s: SIOCGIWSCAN GET broadcast results\n", dev->name)); + WL_TRACE("%s: SIOCGIWSCAN GET broadcast results\n", dev->name); apcnt = 0; p_buf = iscan->list_hdr; while (p_buf != iscan->list_cur) { @@ -1765,9 +1761,8 @@ wl_iw_iscan_get_scan(struct net_device *dev, counter += list->count; if (list->version != WL_BSS_INFO_VERSION) { - WL_ERROR(("%s : list->version %d != " - "WL_BSS_INFO_VERSION\n", - __func__, list->version)); + WL_ERROR("%s : list->version %d != WL_BSS_INFO_VERSION\n", + __func__, list->version); return -EINVAL; } @@ -1877,8 +1872,8 @@ wl_iw_iscan_get_scan(struct net_device *dev, dwrq->length = event - extra; dwrq->flags = 0; - WL_TRACE(("%s return to WE %d bytes APs=%d\n", __func__, - dwrq->length, counter)); + WL_TRACE("%s return to WE %d bytes APs=%d\n", + __func__, dwrq->length, counter); if (!dwrq->length) return -EAGAIN; @@ -1896,7 +1891,7 @@ wl_iw_set_essid(struct net_device *dev, wl_join_params_t join_params; int join_params_size; - WL_TRACE(("%s: SIOCSIWESSID\n", dev->name)); + WL_TRACE("%s: SIOCSIWESSID\n", dev->name); if (g_set_essid_before_scan) return -EAGAIN; @@ -1932,11 +1927,11 @@ wl_iw_set_essid(struct net_device *dev, error = dev_wlc_ioctl(dev, WLC_SET_SSID, &join_params, join_params_size); if (error) - WL_ERROR(("Invalid ioctl data=%d\n", error)); + WL_ERROR("Invalid ioctl data=%d\n", error); if (g_ssid.SSID_len) { - WL_TRACE(("%s: join SSID=%s ch=%d\n", __func__, - g_ssid.SSID, g_wl_iw_params.target_channel)); + WL_TRACE("%s: join SSID=%s ch=%d\n", + __func__, g_ssid.SSID, g_wl_iw_params.target_channel); } return 0; } @@ -1949,14 +1944,14 @@ wl_iw_get_essid(struct net_device *dev, wlc_ssid_t ssid; int error; - WL_TRACE(("%s: SIOCGIWESSID\n", dev->name)); + WL_TRACE("%s: SIOCGIWESSID\n", dev->name); if (!extra) return -EINVAL; error = dev_wlc_ioctl(dev, WLC_GET_SSID, &ssid, sizeof(ssid)); if (error) { - WL_ERROR(("Error getting the SSID\n")); + WL_ERROR("Error getting the SSID\n"); return error; } @@ -1977,7 +1972,7 @@ wl_iw_set_nick(struct net_device *dev, { wl_iw_t *iw = *(wl_iw_t **) netdev_priv(dev); - WL_TRACE(("%s: SIOCSIWNICKN\n", dev->name)); + WL_TRACE("%s: SIOCSIWNICKN\n", dev->name); if (!extra) return -EINVAL; @@ -1997,7 +1992,7 @@ wl_iw_get_nick(struct net_device *dev, { wl_iw_t *iw = *(wl_iw_t **) netdev_priv(dev); - WL_TRACE(("%s: SIOCGIWNICKN\n", dev->name)); + WL_TRACE("%s: SIOCGIWNICKN\n", dev->name); if (!extra) return -EINVAL; @@ -2015,7 +2010,7 @@ wl_iw_set_rate(struct net_device *dev, wl_rateset_t rateset; int error, rate, i, error_bg, error_a; - WL_TRACE(("%s: SIOCSIWRATE\n", dev->name)); + WL_TRACE("%s: SIOCSIWRATE\n", dev->name); error = dev_wlc_ioctl(dev, WLC_GET_CURR_RATESET, &rateset, sizeof(rateset)); @@ -2064,7 +2059,7 @@ wl_iw_get_rate(struct net_device *dev, { int error, rate; - WL_TRACE(("%s: SIOCGIWRATE\n", dev->name)); + WL_TRACE("%s: SIOCGIWRATE\n", dev->name); error = dev_wlc_ioctl(dev, WLC_GET_RATE, &rate, sizeof(rate)); if (error) @@ -2081,7 +2076,7 @@ wl_iw_set_rts(struct net_device *dev, { int error, rts; - WL_TRACE(("%s: SIOCSIWRTS\n", dev->name)); + WL_TRACE("%s: SIOCSIWRTS\n", dev->name); if (vwrq->disabled) rts = DOT11_DEFAULT_RTS_LEN; @@ -2103,7 +2098,7 @@ wl_iw_get_rts(struct net_device *dev, { int error, rts; - WL_TRACE(("%s: SIOCGIWRTS\n", dev->name)); + WL_TRACE("%s: SIOCGIWRTS\n", dev->name); error = dev_wlc_intvar_get(dev, "rtsthresh", &rts); if (error) @@ -2122,7 +2117,7 @@ wl_iw_set_frag(struct net_device *dev, { int error, frag; - WL_TRACE(("%s: SIOCSIWFRAG\n", dev->name)); + WL_TRACE("%s: SIOCSIWFRAG\n", dev->name); if (vwrq->disabled) frag = DOT11_DEFAULT_FRAG_LEN; @@ -2144,7 +2139,7 @@ wl_iw_get_frag(struct net_device *dev, { int error, fragthreshold; - WL_TRACE(("%s: SIOCGIWFRAG\n", dev->name)); + WL_TRACE("%s: SIOCGIWFRAG\n", dev->name); error = dev_wlc_intvar_get(dev, "fragthresh", &fragthreshold); if (error) @@ -2164,7 +2159,7 @@ wl_iw_set_txpow(struct net_device *dev, { int error, disable; u16 txpwrmw; - WL_TRACE(("%s: SIOCSIWTXPOW\n", dev->name)); + WL_TRACE("%s: SIOCSIWTXPOW\n", dev->name); disable = vwrq->disabled ? WL_RADIO_SW_DISABLE : 0; disable += WL_RADIO_SW_DISABLE << 16; @@ -2201,7 +2196,7 @@ wl_iw_get_txpow(struct net_device *dev, int error, disable, txpwrdbm; u8 result; - WL_TRACE(("%s: SIOCGIWTXPOW\n", dev->name)); + WL_TRACE("%s: SIOCGIWTXPOW\n", dev->name); error = dev_wlc_ioctl(dev, WLC_GET_RADIO, &disable, sizeof(disable)); if (error) @@ -2230,7 +2225,7 @@ wl_iw_set_retry(struct net_device *dev, { int error, lrl, srl; - WL_TRACE(("%s: SIOCSIWRETRY\n", dev->name)); + WL_TRACE("%s: SIOCSIWRETRY\n", dev->name); if (vwrq->disabled || (vwrq->flags & IW_RETRY_LIFETIME)) return -EINVAL; @@ -2278,7 +2273,7 @@ wl_iw_get_retry(struct net_device *dev, { int error, lrl, srl; - WL_TRACE(("%s: SIOCGIWRETRY\n", dev->name)); + WL_TRACE("%s: SIOCGIWRETRY\n", dev->name); vwrq->disabled = 0; @@ -2318,7 +2313,7 @@ wl_iw_set_encode(struct net_device *dev, wl_wsec_key_t key; int error, val, wsec; - WL_TRACE(("%s: SIOCSIWENCODE\n", dev->name)); + WL_TRACE("%s: SIOCSIWENCODE\n", dev->name); memset(&key, 0, sizeof(key)); @@ -2410,7 +2405,7 @@ wl_iw_get_encode(struct net_device *dev, wl_wsec_key_t key; int error, val, wsec, auth; - WL_TRACE(("%s: SIOCGIWENCODE\n", dev->name)); + WL_TRACE("%s: SIOCGIWENCODE\n", dev->name); memset(&key, 0, sizeof(wl_wsec_key_t)); @@ -2466,7 +2461,7 @@ wl_iw_set_power(struct net_device *dev, { int error, pm; - WL_TRACE(("%s: SIOCSIWPOWER\n", dev->name)); + WL_TRACE("%s: SIOCSIWPOWER\n", dev->name); pm = vwrq->disabled ? PM_OFF : PM_MAX; @@ -2485,7 +2480,7 @@ wl_iw_get_power(struct net_device *dev, { int error, pm; - WL_TRACE(("%s: SIOCGIWPOWER\n", dev->name)); + WL_TRACE("%s: SIOCGIWPOWER\n", dev->name); error = dev_wlc_ioctl(dev, WLC_GET_PM, &pm, sizeof(pm)); if (error) @@ -2504,7 +2499,7 @@ wl_iw_set_wpaie(struct net_device *dev, struct iw_request_info *info, struct iw_point *iwp, char *extra) { - WL_TRACE(("%s: SIOCSIWGENIE\n", dev->name)); + WL_TRACE("%s: SIOCSIWGENIE\n", dev->name); CHECK_EXTRA_FOR_NULL(extra); @@ -2517,7 +2512,7 @@ static int wl_iw_get_wpaie(struct net_device *dev, struct iw_request_info *info, struct iw_point *iwp, char *extra) { - WL_TRACE(("%s: SIOCGIWGENIE\n", dev->name)); + WL_TRACE("%s: SIOCGIWGENIE\n", dev->name); iwp->length = 64; dev_wlc_bufvar_get(dev, "wpaie", extra, iwp->length); return 0; @@ -2532,7 +2527,7 @@ wl_iw_set_encodeext(struct net_device *dev, int error; struct iw_encode_ext *iwe; - WL_TRACE(("%s: SIOCSIWENCODEEXT\n", dev->name)); + WL_TRACE("%s: SIOCSIWENCODEEXT\n", dev->name); CHECK_EXTRA_FOR_NULL(extra); @@ -2555,8 +2550,8 @@ wl_iw_set_encodeext(struct net_device *dev, if (key.len == 0) { if (iwe->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) { - WL_WSEC(("Changing the the primary Key to %d\n", - key.index)); + WL_WSEC("Changing the the primary Key to %d\n", + key.index); key.index = htod32(key.index); error = dev_wlc_ioctl(dev, WLC_SET_KEY_PRIMARY, &key.index, sizeof(key.index)); @@ -2570,9 +2565,9 @@ wl_iw_set_encodeext(struct net_device *dev, if (iwe->key_len > sizeof(key.data)) return -EINVAL; - WL_WSEC(("Setting the key index %d\n", key.index)); + WL_WSEC("Setting the key index %d\n", key.index); if (iwe->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) { - WL_WSEC(("key is a Primary Key\n")); + WL_WSEC("key is a Primary Key\n"); key.flags = WL_PRIMARY_KEY; } @@ -2639,14 +2634,14 @@ wl_iw_set_pmksa(struct net_device *dev, uint i; int ret = 0; - WL_WSEC(("%s: SIOCSIWPMKSA\n", dev->name)); + WL_WSEC("%s: SIOCSIWPMKSA\n", dev->name); CHECK_EXTRA_FOR_NULL(extra); iwpmksa = (struct iw_pmksa *)extra; if (iwpmksa->cmd == IW_PMKSA_FLUSH) { - WL_WSEC(("wl_iw_set_pmksa - IW_PMKSA_FLUSH\n")); + WL_WSEC("wl_iw_set_pmksa - IW_PMKSA_FLUSH\n"); memset((char *)&pmkid_list, 0, sizeof(pmkid_list)); } @@ -2661,11 +2656,11 @@ wl_iw_set_pmksa(struct net_device *dev, bcopy(&iwpmksa->pmkid[0], &pmkidptr->pmkid[0].PMKID, WPA2_PMKID_LEN); - WL_WSEC(("wl_iw_set_pmksa:IW_PMKSA_REMOVE:PMKID: " - "%pM = ", &pmkidptr->pmkid[0].BSSID)); + WL_WSEC("wl_iw_set_pmksa:IW_PMKSA_REMOVE:PMKID: %pM = ", + &pmkidptr->pmkid[0].BSSID); for (j = 0; j < WPA2_PMKID_LEN; j++) - WL_WSEC(("%02x ", pmkidptr->pmkid[0].PMKID[j])); - WL_WSEC(("\n")); + WL_WSEC("%02x ", pmkidptr->pmkid[0].PMKID[j]); + WL_WSEC("\n"); } for (i = 0; i < pmkid_list.pmkids.npmkid; i++) @@ -2711,25 +2706,25 @@ wl_iw_set_pmksa(struct net_device *dev, uint j; uint k; k = pmkid_list.pmkids.npmkid; - WL_WSEC(("wl_iw_set_pmksa,IW_PMKSA_ADD - PMKID: %pM = ", - &pmkid_list.pmkids.pmkid[k].BSSID)); + WL_WSEC("wl_iw_set_pmksa,IW_PMKSA_ADD - PMKID: %pM = ", + &pmkid_list.pmkids.pmkid[k].BSSID); for (j = 0; j < WPA2_PMKID_LEN; j++) - WL_WSEC(("%02x ", - pmkid_list.pmkids.pmkid[k].PMKID[j])); - WL_WSEC(("\n")); + WL_WSEC("%02x ", + pmkid_list.pmkids.pmkid[k].PMKID[j]); + WL_WSEC("\n"); } } - WL_WSEC(("PRINTING pmkid LIST - No of elements %d\n", - pmkid_list.pmkids.npmkid)); + WL_WSEC("PRINTING pmkid LIST - No of elements %d\n", + pmkid_list.pmkids.npmkid); for (i = 0; i < pmkid_list.pmkids.npmkid; i++) { uint j; - WL_WSEC(("PMKID[%d]: %pM = ", i, - &pmkid_list.pmkids.pmkid[i].BSSID)); + WL_WSEC("PMKID[%d]: %pM = ", + i, &pmkid_list.pmkids.pmkid[i].BSSID); for (j = 0; j < WPA2_PMKID_LEN; j++) - WL_WSEC(("%02x ", pmkid_list.pmkids.pmkid[i].PMKID[j])); - WL_WSEC(("\n")); + WL_WSEC("%02x ", pmkid_list.pmkids.pmkid[i].PMKID[j]); + WL_WSEC("\n"); } - WL_WSEC(("\n")); + WL_WSEC("\n"); if (!ret) ret = dev_wlc_bufvar_set(dev, "pmkid_info", (char *)&pmkid_list, @@ -2743,7 +2738,7 @@ wl_iw_get_encodeext(struct net_device *dev, struct iw_request_info *info, struct iw_param *vwrq, char *extra) { - WL_TRACE(("%s: SIOCGIWENCODEEXT\n", dev->name)); + WL_TRACE("%s: SIOCGIWENCODEEXT\n", dev->name); return 0; } @@ -2758,13 +2753,13 @@ wl_iw_set_wpaauth(struct net_device *dev, int val = 0; wl_iw_t *iw = *(wl_iw_t **) netdev_priv(dev); - WL_TRACE(("%s: SIOCSIWAUTH\n", dev->name)); + WL_TRACE("%s: SIOCSIWAUTH\n", dev->name); paramid = vwrq->flags & IW_AUTH_INDEX; paramval = vwrq->value; - WL_TRACE(("%s: SIOCSIWAUTH, paramid = 0x%0x, paramval = 0x%0x\n", - dev->name, paramid, paramval)); + WL_TRACE("%s: SIOCSIWAUTH, paramid = 0x%0x, paramval = 0x%0x\n", + dev->name, paramid, paramval); switch (paramid) { case IW_AUTH_WPA_VERSION: @@ -2774,8 +2769,8 @@ wl_iw_set_wpaauth(struct net_device *dev, val = WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED; else if (paramval & IW_AUTH_WPA_VERSION_WPA2) val = WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED; - WL_INFORM(("%s: %d: setting wpa_auth to 0x%0x\n", __func__, - __LINE__, val)); + WL_INFORM("%s: %d: setting wpa_auth to 0x%0x\n", + __func__, __LINE__, val); error = dev_wlc_intvar_set(dev, "wpa_auth", val); if (error) return error; @@ -2798,20 +2793,19 @@ wl_iw_set_wpaauth(struct net_device *dev, } if (iw->privacy_invoked && !val) { - WL_WSEC(("%s: %s: 'Privacy invoked' true but clearing " - "wsec, assuming " "we're a WPS enrollee\n", - dev->name, __func__)); + WL_WSEC("%s: %s: 'Privacy invoked' true but clearing wsec, assuming we're a WPS enrollee\n", + dev->name, __func__); error = dev_wlc_intvar_set(dev, "is_WPS_enrollee", true); if (error) { - WL_WSEC(("Failed to set is_WPS_enrollee\n")); + WL_WSEC("Failed to set is_WPS_enrollee\n"); return error; } } else if (val) { error = dev_wlc_intvar_set(dev, "is_WPS_enrollee", false); if (error) { - WL_WSEC(("Failed to clear is_WPS_enrollee\n")); + WL_WSEC("Failed to clear is_WPS_enrollee\n"); return error; } } @@ -2838,8 +2832,8 @@ wl_iw_set_wpaauth(struct net_device *dev, else val = WPA2_AUTH_UNSPECIFIED; } - WL_INFORM(("%s: %d: setting wpa_auth to %d\n", __func__, - __LINE__, val)); + WL_INFORM("%s: %d: setting wpa_auth to %d\n", + __func__, __LINE__, val); error = dev_wlc_intvar_set(dev, "wpa_auth", val); if (error) return error; @@ -2851,7 +2845,7 @@ wl_iw_set_wpaauth(struct net_device *dev, break; case IW_AUTH_80211_AUTH_ALG: - WL_INFORM(("Setting the D11auth %d\n", paramval)); + WL_INFORM("Setting the D11auth %d\n", paramval); if (paramval == IW_AUTH_ALG_OPEN_SYSTEM) val = 0; else if (paramval == IW_AUTH_ALG_SHARED_KEY) @@ -2880,8 +2874,8 @@ wl_iw_set_wpaauth(struct net_device *dev, dev_wlc_intvar_set(dev, "wsec", val); } val = 0; - WL_INFORM(("%s: %d: setting wpa_auth to %d\n", - __func__, __LINE__, val)); + WL_INFORM("%s: %d: setting wpa_auth to %d\n", + __func__, __LINE__, val); dev_wlc_intvar_set(dev, "wpa_auth", 0); return error; } @@ -2898,7 +2892,7 @@ wl_iw_set_wpaauth(struct net_device *dev, #if WIRELESS_EXT > 17 case IW_AUTH_ROAMING_CONTROL: - WL_INFORM(("%s: IW_AUTH_ROAMING_CONTROL\n", __func__)); + WL_INFORM("%s: IW_AUTH_ROAMING_CONTROL\n", __func__); break; case IW_AUTH_PRIVACY_INVOKED: { @@ -2909,8 +2903,7 @@ wl_iw_set_wpaauth(struct net_device *dev, error = dev_wlc_intvar_set(dev, "is_WPS_enrollee", false); if (error) { - WL_WSEC(("Failed to clear iovar " - "is_WPS_enrollee\n")); + WL_WSEC("Failed to clear iovar is_WPS_enrollee\n"); return error; } } else { @@ -2924,8 +2917,7 @@ wl_iw_set_wpaauth(struct net_device *dev, "is_WPS_enrollee", true); if (error) { - WL_WSEC(("Failed to set iovar " - "is_WPS_enrollee\n")); + WL_WSEC("Failed to set iovar is_WPS_enrollee\n"); return error; } } else { @@ -2933,8 +2925,7 @@ wl_iw_set_wpaauth(struct net_device *dev, "is_WPS_enrollee", false); if (error) { - WL_WSEC(("Failed to clear " - "is_WPS_enrollee\n")); + WL_WSEC("Failed to clear is_WPS_enrollee\n"); return error; } } @@ -2961,7 +2952,7 @@ wl_iw_get_wpaauth(struct net_device *dev, int val; wl_iw_t *iw = *(wl_iw_t **) netdev_priv(dev); - WL_TRACE(("%s: SIOCGIWAUTH\n", dev->name)); + WL_TRACE("%s: SIOCGIWAUTH\n", dev->name); paramid = vwrq->flags & IW_AUTH_INDEX; @@ -3041,7 +3032,7 @@ wl_iw_get_wpaauth(struct net_device *dev, break; #if WIRELESS_EXT > 17 case IW_AUTH_ROAMING_CONTROL: - WL_ERROR(("%s: IW_AUTH_ROAMING_CONTROL\n", __func__)); + WL_ERROR("%s: IW_AUTH_ROAMING_CONTROL\n", __func__); break; case IW_AUTH_PRIVACY_INVOKED: paramval = iw->privacy_invoked; @@ -3158,19 +3149,19 @@ int wl_iw_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) char *extra = NULL; int token_size = 1, max_tokens = 0, ret = 0; - WL_TRACE(("\n%s, cmd:%x alled via dhd->do_ioctl()entry point\n", - __func__, cmd)); + WL_TRACE("\n%s, cmd:%x alled via dhd->do_ioctl()entry point\n", + __func__, cmd); if (cmd < SIOCIWFIRST || IW_IOCTL_IDX(cmd) >= ARRAY_SIZE(wl_iw_handler)) { - WL_ERROR(("%s: error in cmd=%x : out of range\n", __func__, - cmd)); + WL_ERROR("%s: error in cmd=%x : out of range\n", + __func__, cmd); return -EOPNOTSUPP; } handler = wl_iw_handler[IW_IOCTL_IDX(cmd)]; if (!handler) { - WL_ERROR(("%s: error in cmd=%x : not supported\n", - __func__, cmd)); + WL_ERROR("%s: error in cmd=%x : not supported\n", + __func__, cmd); return -EOPNOTSUPP; } @@ -3235,9 +3226,8 @@ int wl_iw_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) if (max_tokens && wrq->u.data.pointer) { if (wrq->u.data.length > max_tokens) { - WL_ERROR(("%s: error in cmd=%x wrq->u.data.length=%d " - "> max_tokens=%d\n", - __func__, cmd, wrq->u.data.length, max_tokens)); + WL_ERROR("%s: error in cmd=%x wrq->u.data.length=%d > max_tokens=%d\n", + __func__, cmd, wrq->u.data.length, max_tokens); return -E2BIG; } extra = kmalloc(max_tokens * token_size, GFP_KERNEL); @@ -3340,7 +3330,7 @@ wl_iw_conn_status_str(u32 event_type, u32 status, u32 reason, memset(stringBuf, 0, buflen); snprintf(stringBuf, buflen, "%s %s %02d %02d", name, cause, status, reason); - WL_INFORM(("Connection status: %s\n", stringBuf)); + WL_INFORM("Connection status: %s\n", stringBuf); return true; } else { return false; @@ -3384,13 +3374,13 @@ void wl_iw_event(struct net_device *dev, wl_event_msg_t *e, void *data) iw = 0; if (!dev) { - WL_ERROR(("%s: dev is null\n", __func__)); + WL_ERROR("%s: dev is null\n", __func__); return; } iw = *(wl_iw_t **) netdev_priv(dev); - WL_TRACE(("%s: dev=%s event=%d\n", __func__, dev->name, event_type)); + WL_TRACE("%s: dev=%s event=%d\n", __func__, dev->name, event_type); switch (event_type) { case WLC_E_TXFAIL: @@ -3423,7 +3413,7 @@ void wl_iw_event(struct net_device *dev, wl_event_msg_t *e, void *data) 20 * HZ); } else { memcpy(wrqu.addr.sa_data, &e->addr, ETH_ALEN); - WL_TRACE(("Link UP\n")); + WL_TRACE("Link UP\n"); } wrqu.addr.sa_family = ARPHRD_ETHER; @@ -3434,8 +3424,8 @@ void wl_iw_event(struct net_device *dev, wl_event_msg_t *e, void *data) wrqu.data.length = datalen + 1; extra[0] = WLC_E_ACTION_FRAME; memcpy(&extra[1], data, datalen); - WL_TRACE(("WLC_E_ACTION_FRAME len %d \n", - wrqu.data.length)); + WL_TRACE("WLC_E_ACTION_FRAME len %d\n", + wrqu.data.length); } break; @@ -3516,13 +3506,13 @@ void wl_iw_event(struct net_device *dev, wl_event_msg_t *e, void *data) } else { cmd = SIOCGIWSCAN; wrqu.data.length = strlen(extra); - WL_TRACE(("Event WLC_E_SCAN_COMPLETE from specific " - "scan %d\n", g_iscan->iscan_state)); + WL_TRACE("Event WLC_E_SCAN_COMPLETE from specific scan %d\n", + g_iscan->iscan_state); } #else cmd = SIOCGIWSCAN; wrqu.data.length = strlen(extra); - WL_TRACE(("Event WLC_E_SCAN_COMPLETE\n")); + WL_TRACE("Event WLC_E_SCAN_COMPLETE\n"); #endif break; @@ -3530,9 +3520,9 @@ void wl_iw_event(struct net_device *dev, wl_event_msg_t *e, void *data) { wlc_ssid_t *ssid; ssid = (wlc_ssid_t *) data; - WL_ERROR(("%s Event WLC_E_PFN_NET_FOUND, send %s up : " - "find %s len=%d\n", __func__, PNO_EVENT_UP, - ssid->SSID, ssid->SSID_len)); + WL_ERROR("%s Event WLC_E_PFN_NET_FOUND, send %s up : find %s len=%d\n", + __func__, PNO_EVENT_UP, + ssid->SSID, ssid->SSID_len); WAKE_LOCK_TIMEOUT(iw->pub, WAKE_LOCK_PNO_FIND_TMOUT, 20 * HZ); cmd = IWEVCUSTOM; @@ -3543,7 +3533,7 @@ void wl_iw_event(struct net_device *dev, wl_event_msg_t *e, void *data) break; default: - WL_TRACE(("Unknown Event %d: ignoring\n", event_type)); + WL_TRACE("Unknown Event %d: ignoring\n", event_type); break; } #ifndef SANDGATE2G @@ -3584,7 +3574,7 @@ wl_iw_get_wireless_stats(struct net_device *dev, struct iw_statistics *wstats) goto done; phy_noise = dtoh32(phy_noise); - WL_TRACE(("wl_iw_get_wireless_stats phy noise=%d\n", phy_noise)); + WL_TRACE("wl_iw_get_wireless_stats phy noise=%d\n", phy_noise); memset(&scb_val, 0, sizeof(scb_val_t)); res = dev_wlc_ioctl(dev, WLC_GET_RSSI, &scb_val, sizeof(scb_val_t)); @@ -3592,7 +3582,7 @@ wl_iw_get_wireless_stats(struct net_device *dev, struct iw_statistics *wstats) goto done; rssi = dtoh32(scb_val.val); - WL_TRACE(("wl_iw_get_wireless_stats rssi=%d\n", rssi)); + WL_TRACE("wl_iw_get_wireless_stats rssi=%d\n", rssi); if (rssi <= WL_IW_RSSI_NO_SIGNAL) wstats->qual.qual = 0; else if (rssi <= WL_IW_RSSI_VERY_LOW) @@ -3615,23 +3605,21 @@ wl_iw_get_wireless_stats(struct net_device *dev, struct iw_statistics *wstats) #endif #if WIRELESS_EXT > 11 - WL_TRACE(("wl_iw_get_wireless_stats counters=%d\n", - (int)sizeof(wl_cnt_t))); + WL_TRACE("wl_iw_get_wireless_stats counters=%zu\n", sizeof(wl_cnt_t)); memset(&cnt, 0, sizeof(wl_cnt_t)); res = dev_wlc_bufvar_get(dev, "counters", (char *)&cnt, sizeof(wl_cnt_t)); if (res) { - WL_ERROR(("wl_iw_get_wireless_stats counters failed error=%d\n", - res)); + WL_ERROR("wl_iw_get_wireless_stats counters failed error=%d\n", + res); goto done; } cnt.version = dtoh16(cnt.version); if (cnt.version != WL_CNT_T_VERSION) { - WL_TRACE(("\tIncorrect version of counters struct: expected " - "%d; got %d\n", - WL_CNT_T_VERSION, cnt.version)); + WL_TRACE("\tIncorrect version of counters struct: expected %d; got %d\n", + WL_CNT_T_VERSION, cnt.version); goto done; } @@ -3642,22 +3630,22 @@ wl_iw_get_wireless_stats(struct net_device *dev, struct iw_statistics *wstats) wstats->discard.misc = dtoh32(cnt.rxrunt) + dtoh32(cnt.rxgiant); wstats->miss.beacon = 0; - WL_TRACE(("wl_iw_get_wireless_stats counters txframe=%d txbyte=%d\n", - dtoh32(cnt.txframe), dtoh32(cnt.txbyte))); - WL_TRACE(("wl_iw_get_wireless_stats counters rxfrmtoolong=%d\n", - dtoh32(cnt.rxfrmtoolong))); - WL_TRACE(("wl_iw_get_wireless_stats counters rxbadplcp=%d\n", - dtoh32(cnt.rxbadplcp))); - WL_TRACE(("wl_iw_get_wireless_stats counters rxundec=%d\n", - dtoh32(cnt.rxundec))); - WL_TRACE(("wl_iw_get_wireless_stats counters rxfragerr=%d\n", - dtoh32(cnt.rxfragerr))); - WL_TRACE(("wl_iw_get_wireless_stats counters txfail=%d\n", - dtoh32(cnt.txfail))); - WL_TRACE(("wl_iw_get_wireless_stats counters rxrunt=%d\n", - dtoh32(cnt.rxrunt))); - WL_TRACE(("wl_iw_get_wireless_stats counters rxgiant=%d\n", - dtoh32(cnt.rxgiant))); + WL_TRACE("wl_iw_get_wireless_stats counters txframe=%d txbyte=%d\n", + dtoh32(cnt.txframe), dtoh32(cnt.txbyte)); + WL_TRACE("wl_iw_get_wireless_stats counters rxfrmtoolong=%d\n", + dtoh32(cnt.rxfrmtoolong)); + WL_TRACE("wl_iw_get_wireless_stats counters rxbadplcp=%d\n", + dtoh32(cnt.rxbadplcp)); + WL_TRACE("wl_iw_get_wireless_stats counters rxundec=%d\n", + dtoh32(cnt.rxundec)); + WL_TRACE("wl_iw_get_wireless_stats counters rxfragerr=%d\n", + dtoh32(cnt.rxfragerr)); + WL_TRACE("wl_iw_get_wireless_stats counters txfail=%d\n", + dtoh32(cnt.txfail)); + WL_TRACE("wl_iw_get_wireless_stats counters rxrunt=%d\n", + dtoh32(cnt.rxrunt)); + WL_TRACE("wl_iw_get_wireless_stats counters rxgiant=%d\n", + dtoh32(cnt.rxgiant)); #endif /* WIRELESS_EXT > 11 */ done: diff --git a/drivers/staging/brcm80211/brcmfmac/wl_iw.h b/drivers/staging/brcm80211/brcmfmac/wl_iw.h index edbf61f30b47..c8637c50dc17 100644 --- a/drivers/staging/brcm80211/brcmfmac/wl_iw.h +++ b/drivers/staging/brcm80211/brcmfmac/wl_iw.h @@ -78,7 +78,7 @@ typedef struct wl_iw_extra_params { #define CHECK_EXTRA_FOR_NULL(extra) \ if (!extra) { \ - WL_ERROR(("%s: error : extra is null pointer\n", __func__)); \ + WL_ERROR("%s: error : extra is null pointer\n", __func__); \ return -EINVAL; \ } diff --git a/drivers/staging/brcm80211/sys/wl_dbg.h b/drivers/staging/brcm80211/sys/wl_dbg.h index e63b27ebad5e..54af257598c2 100644 --- a/drivers/staging/brcm80211/sys/wl_dbg.h +++ b/drivers/staging/brcm80211/sys/wl_dbg.h @@ -20,15 +20,20 @@ /* wl_msg_level is a bit vector with defs in wlioctl.h */ extern u32 wl_msg_level; -#define WL_PRINT(args) printf args -#define WL_NONE(args) +#define WL_NONE(fmt, args...) no_printk(fmt, ##args) + +#define WL_PRINT(level, fmt, args...) \ +do { \ + if (wl_msg_level & level) \ + printk(fmt, ##args); \ +} while (0) #ifdef BCMDBG -#define WL_ERROR(args) do {if ((wl_msg_level & WL_ERROR_VAL)) WL_PRINT(args); } while (0) -#define WL_TRACE(args) do {if (wl_msg_level & WL_TRACE_VAL) WL_PRINT(args); } while (0) -#define WL_AMPDU(args) do {if (wl_msg_level & WL_AMPDU_VAL) WL_PRINT(args); } while (0) -#define WL_FFPLD(args) do {if (wl_msg_level & WL_FFPLD_VAL) WL_PRINT(args); } while (0) +#define WL_ERROR(fmt, args...) WL_PRINT(WL_ERROR_VAL, fmt, ##args) +#define WL_TRACE(fmt, args...) WL_PRINT(WL_TRACE_VAL, fmt, ##args) +#define WL_AMPDU(fmt, args...) WL_PRINT(WL_AMPDU_VAL, fmt, ##args) +#define WL_FFPLD(fmt, args...) WL_PRINT(WL_FFPLD_VAL, fmt, ##args) #define WL_ERROR_ON() (wl_msg_level & WL_ERROR_VAL) @@ -44,35 +49,50 @@ extern u32 wl_msg_level; extern u32 wl_ampdu_dbg; -#define WL_AMPDU_UPDN(args) do {if (wl_ampdu_dbg & WL_AMPDU_UPDN_VAL) {WL_AMPDU(args); } } while (0) -#define WL_AMPDU_RX(args) do {if (wl_ampdu_dbg & WL_AMPDU_RX_VAL) {WL_AMPDU(args); } } while (0) -#define WL_AMPDU_ERR(args) do {if (wl_ampdu_dbg & WL_AMPDU_ERR_VAL) {WL_AMPDU(args); } } while (0) -#define WL_AMPDU_TX(args) do {if (wl_ampdu_dbg & WL_AMPDU_TX_VAL) {WL_AMPDU(args); } } while (0) -#define WL_AMPDU_CTL(args) do {if (wl_ampdu_dbg & WL_AMPDU_CTL_VAL) {WL_AMPDU(args); } } while (0) -#define WL_AMPDU_HW(args) do {if (wl_ampdu_dbg & WL_AMPDU_HW_VAL) {WL_AMPDU(args); } } while (0) -#define WL_AMPDU_HWTXS(args) do {if (wl_ampdu_dbg & WL_AMPDU_HWTXS_VAL) {WL_AMPDU(args); } } while (0) -#define WL_AMPDU_HWDBG(args) do {if (wl_ampdu_dbg & WL_AMPDU_HWDBG_VAL) {WL_AMPDU(args); } } while (0) +#define WL_AMPDU_PRINT(level, fmt, args...) \ +do { \ + if (wl_ampdu_dbg & level) { \ + WL_AMPDU(fmt, ##args); \ + } \ +} while (0) + +#define WL_AMPDU_UPDN(fmt, args...) \ + WL_AMPDU_PRINT(WL_AMPDU_UPDN_VAL, fmt, ##args) +#define WL_AMPDU_RX(fmt, args...) \ + WL_AMPDU_PRINT(WL_AMPDU_RX_VAL, fmt, ##args) +#define WL_AMPDU_ERR(fmt, args...) \ + WL_AMPDU_PRINT(WL_AMPDU_ERR_VAL, fmt, ##args) +#define WL_AMPDU_TX(fmt, args...) \ + WL_AMPDU_PRINT(WL_AMPDU_TX_VAL, fmt, ##args) +#define WL_AMPDU_CTL(fmt, args...) \ + WL_AMPDU_PRINT(WL_AMPDU_CTL_VAL, fmt, ##args) +#define WL_AMPDU_HW(fmt, args...) \ + WL_AMPDU_PRINT(WL_AMPDU_HW_VAL, fmt, ##args) +#define WL_AMPDU_HWTXS(fmt, args...) \ + WL_AMPDU_PRINT(WL_AMPDU_HWTXS_VAL, fmt, ##args) +#define WL_AMPDU_HWDBG(fmt, args...) \ + WL_AMPDU_PRINT(WL_AMPDU_HWDBG_VAL, fmt, ##args) #define WL_AMPDU_ERR_ON() (wl_ampdu_dbg & WL_AMPDU_ERR_VAL) #define WL_AMPDU_HW_ON() (wl_ampdu_dbg & WL_AMPDU_HW_VAL) #define WL_AMPDU_HWTXS_ON() (wl_ampdu_dbg & WL_AMPDU_HWTXS_VAL) #else /* BCMDBG */ -#define WL_ERROR(args) -#define WL_TRACE(args) -#define WL_AMPDU(args) -#define WL_FFPLD(args) +#define WL_ERROR(fmt, args...) no_printk(fmt, ##args) +#define WL_TRACE(fmt, args...) no_printk(fmt, ##args) +#define WL_AMPDU(fmt, args...) no_printk(fmt, ##args) +#define WL_FFPLD(fmt, args...) no_printk(fmt, ##args) #define WL_ERROR_ON() 0 -#define WL_AMPDU_UPDN(args) -#define WL_AMPDU_RX(args) -#define WL_AMPDU_ERR(args) -#define WL_AMPDU_TX(args) -#define WL_AMPDU_CTL(args) -#define WL_AMPDU_HW(args) -#define WL_AMPDU_HWTXS(args) -#define WL_AMPDU_HWDBG(args) +#define WL_AMPDU_UPDN(fmt, args...) no_printk(fmt, ##args) +#define WL_AMPDU_RX(fmt, args...) no_printk(fmt, ##args) +#define WL_AMPDU_ERR(fmt, args...) no_printk(fmt, ##args) +#define WL_AMPDU_TX(fmt, args...) no_printk(fmt, ##args) +#define WL_AMPDU_CTL(fmt, args...) no_printk(fmt, ##args) +#define WL_AMPDU_HW(fmt, args...) no_printk(fmt, ##args) +#define WL_AMPDU_HWTXS(fmt, args...) no_printk(fmt, ##args) +#define WL_AMPDU_HWDBG(fmt, args...) no_printk(fmt, ##args) #define WL_AMPDU_ERR_ON() 0 #define WL_AMPDU_HW_ON() 0 #define WL_AMPDU_HWTXS_ON() 0 diff --git a/drivers/staging/brcm80211/sys/wl_mac80211.c b/drivers/staging/brcm80211/sys/wl_mac80211.c index 4ae99749ac70..bdd629d72a75 100644 --- a/drivers/staging/brcm80211/sys/wl_mac80211.c +++ b/drivers/staging/brcm80211/sys/wl_mac80211.c @@ -179,7 +179,7 @@ static int wl_ops_tx(struct ieee80211_hw *hw, struct sk_buff *skb) struct wl_info *wl = hw->priv; WL_LOCK(wl); if (!wl->pub->up) { - WL_ERROR(("ops->tx called while down\n")); + WL_ERROR("ops->tx called while down\n"); status = -ENETDOWN; goto done; } @@ -192,8 +192,10 @@ static int wl_ops_tx(struct ieee80211_hw *hw, struct sk_buff *skb) static int wl_ops_start(struct ieee80211_hw *hw) { struct wl_info *wl = hw->priv; - /* struct ieee80211_channel *curchan = hw->conf.channel; */ - WL_NONE(("%s : Initial channel: %d\n", __func__, curchan->hw_value)); + /* + struct ieee80211_channel *curchan = hw->conf.channel; + WL_NONE("%s : Initial channel: %d\n", __func__, curchan->hw_value); + */ WL_LOCK(wl); ieee80211_wake_queues(hw); @@ -226,8 +228,8 @@ wl_ops_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) vif->type != NL80211_IFTYPE_STATION && vif->type != NL80211_IFTYPE_WDS && vif->type != NL80211_IFTYPE_ADHOC) { - WL_ERROR(("%s: Attempt to add type %d, only STA for now\n", - __func__, vif->type)); + WL_ERROR("%s: Attempt to add type %d, only STA for now\n", + __func__, vif->type); return -EOPNOTSUPP; } @@ -237,7 +239,7 @@ wl_ops_add_interface(struct ieee80211_hw *hw, struct ieee80211_vif *vif) WL_UNLOCK(wl); if (err != 0) - WL_ERROR(("%s: wl_up() returned %d\n", __func__, err)); + WL_ERROR("%s: wl_up() returned %d\n", __func__, err); return err; } @@ -263,8 +265,7 @@ ieee_set_channel(struct ieee80211_hw *hw, struct ieee80211_channel *chan, break; case NL80211_CHAN_HT40MINUS: case NL80211_CHAN_HT40PLUS: - WL_ERROR(("%s: Need to implement 40 Mhz Channels!\n", - __func__)); + WL_ERROR("%s: Need to implement 40 Mhz Channels!\n", __func__); break; } @@ -281,12 +282,12 @@ static int wl_ops_config(struct ieee80211_hw *hw, u32 changed) int new_int; if (changed & IEEE80211_CONF_CHANGE_LISTEN_INTERVAL) { - WL_NONE(("%s: Setting listen interval to %d\n", - __func__, conf->listen_interval)); + WL_NONE("%s: Setting listen interval to %d\n", + __func__, conf->listen_interval); if (wlc_iovar_setint (wl->wlc, "bcn_li_bcn", conf->listen_interval)) { - WL_ERROR(("%s: Error setting listen_interval\n", - __func__)); + WL_ERROR("%s: Error setting listen_interval\n", + __func__); err = -EIO; goto config_out; } @@ -294,41 +295,42 @@ static int wl_ops_config(struct ieee80211_hw *hw, u32 changed) ASSERT(new_int == conf->listen_interval); } if (changed & IEEE80211_CONF_CHANGE_MONITOR) - WL_NONE(("Need to set monitor mode\n")); + WL_NONE("Need to set monitor mode\n"); if (changed & IEEE80211_CONF_CHANGE_PS) - WL_NONE(("Need to set Power-save mode\n")); + WL_NONE("Need to set Power-save mode\n"); if (changed & IEEE80211_CONF_CHANGE_POWER) { - WL_NONE(("%s: Setting tx power to %d dbm\n", __func__, - conf->power_level)); + WL_NONE("%s: Setting tx power to %d dbm\n", + __func__, conf->power_level); if (wlc_iovar_setint (wl->wlc, "qtxpower", conf->power_level * 4)) { - WL_ERROR(("%s: Error setting power_level\n", __func__)); + WL_ERROR("%s: Error setting power_level\n", __func__); err = -EIO; goto config_out; } wlc_iovar_getint(wl->wlc, "qtxpower", &new_int); if (new_int != (conf->power_level * 4)) - WL_ERROR(("%s: Power level req != actual, %d %d\n", - __func__, conf->power_level * 4, new_int)); + WL_ERROR("%s: Power level req != actual, %d %d\n", + __func__, conf->power_level * 4, new_int); } if (changed & IEEE80211_CONF_CHANGE_CHANNEL) { err = ieee_set_channel(hw, conf->channel, conf->channel_type); } if (changed & IEEE80211_CONF_CHANGE_RETRY_LIMITS) { - WL_NONE(("%s: srl %d, lrl %d\n", __func__, - conf->short_frame_max_tx_count, - conf->long_frame_max_tx_count)); + WL_NONE("%s: srl %d, lrl %d\n", + __func__, + conf->short_frame_max_tx_count, + conf->long_frame_max_tx_count); if (wlc_set (wl->wlc, WLC_SET_SRL, conf->short_frame_max_tx_count) < 0) { - WL_ERROR(("%s: Error setting srl\n", __func__)); + WL_ERROR("%s: Error setting srl\n", __func__); err = -EIO; goto config_out; } if (wlc_set(wl->wlc, WLC_SET_LRL, conf->long_frame_max_tx_count) < 0) { - WL_ERROR(("%s: Error setting lrl\n", __func__)); + WL_ERROR("%s: Error setting lrl\n", __func__); err = -EIO; goto config_out; } @@ -348,24 +350,24 @@ wl_ops_bss_info_changed(struct ieee80211_hw *hw, if (changed & BSS_CHANGED_ASSOC) { - WL_ERROR(("Associated:\t%s\n", info->assoc ? "True" : "False")); + WL_ERROR("Associated:\t%s\n", info->assoc ? "True" : "False"); /* association status changed (associated/disassociated) * also implies a change in the AID. */ } if (changed & BSS_CHANGED_ERP_CTS_PROT) { - WL_NONE(("Use_cts_prot:\t%s Implement me\n", - info->use_cts_prot ? "True" : "False")); + WL_NONE("Use_cts_prot:\t%s Implement me\n", + info->use_cts_prot ? "True" : "False"); /* CTS protection changed */ } if (changed & BSS_CHANGED_ERP_PREAMBLE) { - WL_NONE(("Short preamble:\t%s Implement me\n", - info->use_short_preamble ? "True" : "False")); + WL_NONE("Short preamble:\t%s Implement me\n", + info->use_short_preamble ? "True" : "False"); /* preamble changed */ } if (changed & BSS_CHANGED_ERP_SLOT) { - WL_NONE(("Changing short slot:\t%s\n", - info->use_short_slot ? "True" : "False")); + WL_NONE("Changing short slot:\t%s\n", + info->use_short_slot ? "True" : "False"); if (info->use_short_slot) val = 1; else @@ -375,34 +377,34 @@ wl_ops_bss_info_changed(struct ieee80211_hw *hw, } if (changed & BSS_CHANGED_HT) { - WL_NONE(("%s: HT mode - Implement me\n", __func__)); + WL_NONE("%s: HT mode - Implement me\n", __func__); /* 802.11n parameters changed */ } if (changed & BSS_CHANGED_BASIC_RATES) { - WL_NONE(("Need to change Basic Rates:\t0x%x! Implement me\n", - (u32) info->basic_rates)); + WL_NONE("Need to change Basic Rates:\t0x%x! Implement me\n", + (u32) info->basic_rates); /* Basic rateset changed */ } if (changed & BSS_CHANGED_BEACON_INT) { - WL_NONE(("Beacon Interval:\t%d Implement me\n", - info->beacon_int)); + WL_NONE("Beacon Interval:\t%d Implement me\n", + info->beacon_int); /* Beacon interval changed */ } if (changed & BSS_CHANGED_BSSID) { - WL_NONE(("new BSSID:\taid %d bss:%pM\n", info->aid, - info->bssid)); + WL_NONE("new BSSID:\taid %d bss:%pM\n", + info->aid, info->bssid); /* BSSID changed, for whatever reason (IBSS and managed mode) */ /* FIXME: need to store bssid in bsscfg */ wlc_set_addrmatch(wl->wlc, RCM_BSSID_OFFSET, (struct ether_addr *)info->bssid); } if (changed & BSS_CHANGED_BEACON) { - WL_ERROR(("BSS_CHANGED_BEACON\n")); + WL_ERROR("BSS_CHANGED_BEACON\n"); /* Beacon data changed, retrieve new beacon (beaconing modes) */ } if (changed & BSS_CHANGED_BEACON_ENABLED) { - WL_ERROR(("Beacon enabled:\t%s\n", - info->enable_beacon ? "True" : "False")); + WL_ERROR("Beacon enabled:\t%s\n", + info->enable_beacon ? "True" : "False"); /* Beaconing should be enabled/disabled (beaconing modes) */ } return; @@ -418,19 +420,19 @@ wl_ops_configure_filter(struct ieee80211_hw *hw, changed_flags &= MAC_FILTERS; *total_flags &= MAC_FILTERS; if (changed_flags & FIF_PROMISC_IN_BSS) - WL_ERROR(("FIF_PROMISC_IN_BSS\n")); + WL_ERROR("FIF_PROMISC_IN_BSS\n"); if (changed_flags & FIF_ALLMULTI) - WL_ERROR(("FIF_ALLMULTI\n")); + WL_ERROR("FIF_ALLMULTI\n"); if (changed_flags & FIF_FCSFAIL) - WL_ERROR(("FIF_FCSFAIL\n")); + WL_ERROR("FIF_FCSFAIL\n"); if (changed_flags & FIF_PLCPFAIL) - WL_ERROR(("FIF_PLCPFAIL\n")); + WL_ERROR("FIF_PLCPFAIL\n"); if (changed_flags & FIF_CONTROL) - WL_ERROR(("FIF_CONTROL\n")); + WL_ERROR("FIF_CONTROL\n"); if (changed_flags & FIF_OTHER_BSS) - WL_ERROR(("FIF_OTHER_BSS\n")); + WL_ERROR("FIF_OTHER_BSS\n"); if (changed_flags & FIF_BCN_PRBRESP_PROMISC) { - WL_NONE(("FIF_BCN_PRBRESP_PROMISC\n")); + WL_NONE("FIF_BCN_PRBRESP_PROMISC\n"); WL_LOCK(wl); if (*total_flags & FIF_BCN_PRBRESP_PROMISC) { wl->pub->mac80211_state |= MAC80211_PROMISC_BCNS; @@ -447,25 +449,25 @@ wl_ops_configure_filter(struct ieee80211_hw *hw, static int wl_ops_set_tim(struct ieee80211_hw *hw, struct ieee80211_sta *sta, bool set) { - WL_ERROR(("%s: Enter\n", __func__)); + WL_ERROR("%s: Enter\n", __func__); return 0; } static void wl_ops_sw_scan_start(struct ieee80211_hw *hw) { - WL_NONE(("Scan Start\n")); + WL_NONE("Scan Start\n"); return; } static void wl_ops_sw_scan_complete(struct ieee80211_hw *hw) { - WL_NONE(("Scan Complete\n")); + WL_NONE("Scan Complete\n"); return; } static void wl_ops_set_tsf(struct ieee80211_hw *hw, u64 tsf) { - WL_ERROR(("%s: Enter\n", __func__)); + WL_ERROR("%s: Enter\n", __func__); return; } @@ -473,13 +475,13 @@ static int wl_ops_get_stats(struct ieee80211_hw *hw, struct ieee80211_low_level_stats *stats) { - WL_ERROR(("%s: Enter\n", __func__)); + WL_ERROR("%s: Enter\n", __func__); return 0; } static int wl_ops_set_rts_threshold(struct ieee80211_hw *hw, u32 value) { - WL_ERROR(("%s: Enter\n", __func__)); + WL_ERROR("%s: Enter\n", __func__); return 0; } @@ -487,10 +489,10 @@ static void wl_ops_sta_notify(struct ieee80211_hw *hw, struct ieee80211_vif *vif, enum sta_notify_cmd cmd, struct ieee80211_sta *sta) { - WL_NONE(("%s: Enter\n", __func__)); + WL_NONE("%s: Enter\n", __func__); switch (cmd) { default: - WL_ERROR(("%s: Uknown cmd = %d\n", __func__, cmd)); + WL_ERROR("%s: Unknown cmd = %d\n", __func__, cmd); break; } return; @@ -502,9 +504,9 @@ wl_ops_conf_tx(struct ieee80211_hw *hw, u16 queue, { struct wl_info *wl = hw->priv; - WL_NONE(("%s: Enter (WME config)\n", __func__)); - WL_NONE(("queue %d, txop %d, cwmin %d, cwmax %d, aifs %d\n", queue, - params->txop, params->cw_min, params->cw_max, params->aifs)); + WL_NONE("%s: Enter (WME config)\n", __func__); + WL_NONE("queue %d, txop %d, cwmin %d, cwmax %d, aifs %d\n", queue, + params->txop, params->cw_min, params->cw_max, params->aifs); WL_LOCK(wl); wlc_wme_setparams(wl->wlc, queue, (void *)params, true); @@ -515,7 +517,7 @@ wl_ops_conf_tx(struct ieee80211_hw *hw, u16 queue, static u64 wl_ops_get_tsf(struct ieee80211_hw *hw) { - WL_ERROR(("%s: Enter\n", __func__)); + WL_ERROR("%s: Enter\n", __func__); return 0; } @@ -558,7 +560,7 @@ static int wl_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif, struct ieee80211_sta *sta) { - WL_NONE(("%s: Enter\n", __func__)); + WL_NONE("%s: Enter\n", __func__); return 0; } @@ -576,14 +578,14 @@ wl_ampdu_action(struct ieee80211_hw *hw, ASSERT(scb->magic == SCB_MAGIC); switch (action) { case IEEE80211_AMPDU_RX_START: - WL_NONE(("%s: action = IEEE80211_AMPDU_RX_START\n", __func__)); + WL_NONE("%s: action = IEEE80211_AMPDU_RX_START\n", __func__); break; case IEEE80211_AMPDU_RX_STOP: - WL_NONE(("%s: action = IEEE80211_AMPDU_RX_STOP\n", __func__)); + WL_NONE("%s: action = IEEE80211_AMPDU_RX_STOP\n", __func__); break; case IEEE80211_AMPDU_TX_START: if (!wlc_aggregatable(wl->wlc, tid)) { - /* WL_ERROR(("START: tid %d is not agg' able, return FAILURE to stack\n", tid)); */ + /* WL_ERROR("START: tid %d is not agg' able, return FAILURE to stack\n", tid); */ return -1; } /* XXX: Use the starting sequence number provided ... */ @@ -597,11 +599,11 @@ wl_ampdu_action(struct ieee80211_hw *hw, case IEEE80211_AMPDU_TX_OPERATIONAL: /* Not sure what to do here */ /* Power save wakeup */ - WL_NONE(("%s: action = IEEE80211_AMPDU_TX_OPERATIONAL\n", - __func__)); + WL_NONE("%s: action = IEEE80211_AMPDU_TX_OPERATIONAL\n", + __func__); break; default: - WL_ERROR(("%s: Invalid command, ignoring\n", __func__)); + WL_ERROR("%s: Invalid command, ignoring\n", __func__); } return 0; @@ -632,8 +634,8 @@ static const struct ieee80211_ops wl_ops = { static int wl_set_hint(struct wl_info *wl, char *abbrev) { - WL_ERROR(("%s: Sending country code %c%c to MAC80211\n", __func__, - abbrev[0], abbrev[1])); + WL_ERROR("%s: Sending country code %c%c to MAC80211\n", + __func__, abbrev[0], abbrev[1]); return regulatory_hint(wl->pub->ieee_hw->wiphy, abbrev); } @@ -663,7 +665,7 @@ static struct wl_info *wl_attach(u16 vendor, u16 device, unsigned long regs, err = 0; if (unit < 0) { - WL_ERROR(("wl%d: unit number overflow, exiting\n", unit)); + WL_ERROR("wl%d: unit number overflow, exiting\n", unit); return NULL; } @@ -691,13 +693,13 @@ static struct wl_info *wl_attach(u16 vendor, u16 device, unsigned long regs, /* Do nothing */ } else { bustype = PCI_BUS; - WL_TRACE(("force to PCI\n")); + WL_TRACE("force to PCI\n"); } wl->bcm_bustype = bustype; wl->regsva = ioremap_nocache(base_addr, PCI_BAR0_WINSZ); if (wl->regsva == NULL) { - WL_ERROR(("wl%d: ioremap() failed\n", unit)); + WL_ERROR("wl%d: ioremap() failed\n", unit); goto fail; } spin_lock_init(&wl->lock); @@ -729,13 +731,12 @@ static struct wl_info *wl_attach(u16 vendor, u16 device, unsigned long regs, if (wlc_iovar_setint(wl->wlc, "mpc", 0)) { - WL_ERROR(("wl%d: Error setting MPC variable to 0\n", - unit)); + WL_ERROR("wl%d: Error setting MPC variable to 0\n", unit); } /* register our interrupt handler */ if (request_irq(irq, wl_isr, IRQF_SHARED, KBUILD_MODNAME, wl)) { - WL_ERROR(("wl%d: request_irq() failed\n", unit)); + WL_ERROR("wl%d: request_irq() failed\n", unit); goto fail; } wl->irq = irq; @@ -745,7 +746,7 @@ static struct wl_info *wl_attach(u16 vendor, u16 device, unsigned long regs, NULL); if (ieee_hw_init(hw)) { - WL_ERROR(("wl%d: %s: ieee_hw_init failed!\n", unit, __func__)); + WL_ERROR("wl%d: %s: ieee_hw_init failed!\n", unit, __func__); goto fail; } @@ -755,8 +756,8 @@ static struct wl_info *wl_attach(u16 vendor, u16 device, unsigned long regs, err = ieee80211_register_hw(hw); if (err) { - WL_ERROR(("%s: ieee80211_register_hw failed, status %d\n", - __func__, err)); + WL_ERROR("%s: ieee80211_register_hw failed, status %d\n", + __func__, err); } if (wl->pub->srom_ccode[0]) @@ -764,11 +765,11 @@ static struct wl_info *wl_attach(u16 vendor, u16 device, unsigned long regs, else err = wl_set_hint(wl, "US"); if (err) { - WL_ERROR(("%s: regulatory_hint failed, status %d\n", __func__, - err)); + WL_ERROR("%s: regulatory_hint failed, status %d\n", + __func__, err); } - WL_ERROR(("wl%d: Broadcom BCM43xx 802.11 MAC80211 Driver " - " (" PHY_VERSION_STR ")", unit)); + WL_ERROR("wl%d: Broadcom BCM43xx 802.11 MAC80211 Driver (" PHY_VERSION_STR ")", + unit); #ifdef BCMDBG printf(" (Compiled at " __TIME__ " on " __DATE__ ")"); @@ -964,9 +965,9 @@ static int ieee_hw_rate_init(struct ieee80211_hw *hw) hw->wiphy->bands[IEEE80211_BAND_5GHZ] = NULL; if (wlc_get(wl->wlc, WLC_GET_PHYLIST, (int *)&phy_list) < 0) { - WL_ERROR(("Phy list failed\n")); + WL_ERROR("Phy list failed\n"); } - WL_NONE(("%s: phylist = %c\n", __func__, phy_list[0])); + WL_NONE("%s: phylist = %c\n", __func__, phy_list[0]); if (phy_list[0] == 'n' || phy_list[0] == 'c') { if (phy_list[0] == 'c') { @@ -991,7 +992,7 @@ static int ieee_hw_rate_init(struct ieee80211_hw *hw) } } - WL_NONE(("%s: 2ghz = %d, 5ghz = %d\n", __func__, 1, has_5g)); + WL_NONE("%s: 2ghz = %d, 5ghz = %d\n", __func__, 1, has_5g); return 0; } @@ -1039,9 +1040,9 @@ wl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ASSERT(pdev); - WL_TRACE(("%s: bus %d slot %d func %d irq %d\n", __func__, - pdev->bus->number, PCI_SLOT(pdev->devfn), - PCI_FUNC(pdev->devfn), pdev->irq)); + WL_TRACE("%s: bus %d slot %d func %d irq %d\n", + __func__, pdev->bus->number, PCI_SLOT(pdev->devfn), + PCI_FUNC(pdev->devfn), pdev->irq); if ((pdev->vendor != PCI_VENDOR_ID_BROADCOM) || (((pdev->device & 0xff00) != 0x4300) && @@ -1051,9 +1052,9 @@ wl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) rc = pci_enable_device(pdev); if (rc) { - WL_ERROR(("%s: Cannot enable device %d-%d_%d\n", __func__, - pdev->bus->number, PCI_SLOT(pdev->devfn), - PCI_FUNC(pdev->devfn))); + WL_ERROR("%s: Cannot enable device %d-%d_%d\n", + __func__, pdev->bus->number, PCI_SLOT(pdev->devfn), + PCI_FUNC(pdev->devfn)); return -ENODEV; } pci_set_master(pdev); @@ -1064,7 +1065,7 @@ wl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) hw = ieee80211_alloc_hw(sizeof(struct wl_info), &wl_ops); if (!hw) { - WL_ERROR(("%s: ieee80211_alloc_hw failed\n", __func__)); + WL_ERROR("%s: ieee80211_alloc_hw failed\n", __func__); rc = -ENOMEM; goto err_1; } @@ -1079,13 +1080,13 @@ wl_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) PCI_BUS, pdev, pdev->irq); if (!wl) { - WL_ERROR(("%s: %s: wl_attach failed!\n", - KBUILD_MODNAME, __func__)); + WL_ERROR("%s: %s: wl_attach failed!\n", + KBUILD_MODNAME, __func__); return -ENODEV; } return 0; err_1: - WL_ERROR(("%s: err_1: Major hoarkage\n", __func__)); + WL_ERROR("%s: err_1: Major hoarkage\n", __func__); return 0; } @@ -1095,12 +1096,12 @@ static int wl_suspend(struct pci_dev *pdev, pm_message_t state) struct wl_info *wl; struct ieee80211_hw *hw; - WL_TRACE(("wl: wl_suspend\n")); + WL_TRACE("wl: wl_suspend\n"); hw = pci_get_drvdata(pdev); wl = HW_TO_WL(hw); if (!wl) { - WL_ERROR(("wl: wl_suspend: pci_get_drvdata failed\n")); + WL_ERROR("wl: wl_suspend: pci_get_drvdata failed\n"); return -ENODEV; } @@ -1120,11 +1121,11 @@ static int wl_resume(struct pci_dev *pdev) int err = 0; u32 val; - WL_TRACE(("wl: wl_resume\n")); + WL_TRACE("wl: wl_resume\n"); hw = pci_get_drvdata(pdev); wl = HW_TO_WL(hw); if (!wl) { - WL_ERROR(("wl: wl_resume: pci_get_drvdata failed\n")); + WL_ERROR("wl: wl_resume: pci_get_drvdata failed\n"); return -ENODEV; } @@ -1160,11 +1161,11 @@ static void wl_remove(struct pci_dev *pdev) hw = pci_get_drvdata(pdev); wl = HW_TO_WL(hw); if (!wl) { - WL_ERROR(("wl: wl_remove: pci_get_drvdata failed\n")); + WL_ERROR("wl: wl_remove: pci_get_drvdata failed\n"); return; } if (!wlc_chipmatch(pdev->vendor, pdev->device)) { - WL_ERROR(("wl: wl_remove: wlc_chipmatch failed\n")); + WL_ERROR("wl: wl_remove: wlc_chipmatch failed\n"); return; } if (wl->wlc) { @@ -1172,7 +1173,7 @@ static void wl_remove(struct pci_dev *pdev) WL_LOCK(wl); wl_down(wl); WL_UNLOCK(wl); - WL_NONE(("%s: Down\n", __func__)); + WL_NONE("%s: Down\n", __func__); } pci_disable_device(pdev); @@ -1334,12 +1335,12 @@ wl_start_int(struct wl_info *wl, struct ieee80211_hw *hw, struct sk_buff *skb) void wl_txflowcontrol(struct wl_info *wl, struct wl_if *wlif, bool state, int prio) { - WL_ERROR(("Shouldn't be here %s\n", __func__)); + WL_ERROR("Shouldn't be here %s\n", __func__); } void wl_init(struct wl_info *wl) { - WL_TRACE(("wl%d: wl_init\n", wl->pub->unit)); + WL_TRACE("wl%d: wl_init\n", wl->pub->unit); wl_reset(wl); @@ -1348,7 +1349,7 @@ void wl_init(struct wl_info *wl) uint wl_reset(struct wl_info *wl) { - WL_TRACE(("wl%d: wl_reset\n", wl->pub->unit)); + WL_TRACE("wl%d: wl_reset\n", wl->pub->unit); wlc_reset(wl->wlc); @@ -1494,12 +1495,12 @@ static void BCMFASTPATH wl_dpc(unsigned long data) static void wl_link_up(struct wl_info *wl, char *ifname) { - WL_ERROR(("wl%d: link up (%s)\n", wl->pub->unit, ifname)); + WL_ERROR("wl%d: link up (%s)\n", wl->pub->unit, ifname); } static void wl_link_down(struct wl_info *wl, char *ifname) { - WL_ERROR(("wl%d: link down (%s)\n", wl->pub->unit, ifname)); + WL_ERROR("wl%d: link down (%s)\n", wl->pub->unit, ifname); } void wl_event(struct wl_info *wl, char *ifname, wlc_event_t *e) @@ -1551,7 +1552,7 @@ wl_timer_t *wl_init_timer(struct wl_info *wl, void (*fn) (void *arg), void *arg, t = kmalloc(sizeof(wl_timer_t), GFP_ATOMIC); if (!t) { - WL_ERROR(("wl%d: wl_init_timer: out of memory\n", wl->pub->unit)); + WL_ERROR("wl%d: wl_init_timer: out of memory\n", wl->pub->unit); return 0; } @@ -1582,8 +1583,8 @@ void wl_add_timer(struct wl_info *wl, wl_timer_t *t, uint ms, int periodic) { #ifdef BCMDBG if (t->set) { - WL_ERROR(("%s: Already set. Name: %s, per %d\n", - __func__, t->name, periodic)); + WL_ERROR("%s: Already set. Name: %s, per %d\n", + __func__, t->name, periodic); } #endif ASSERT(!t->set); @@ -1752,7 +1753,7 @@ static int wl_request_fw(struct wl_info *wl, struct pci_dev *pdev) break; sprintf(fw_name, "%s-%d.fw", wl_firmwares[i], UCODE_LOADER_API_VER); - WL_NONE(("request fw %s\n", fw_name)); + WL_NONE("request fw %s\n", fw_name); status = request_firmware(&wl->fw.fw_bin[i], fw_name, device); if (status) { printf("%s: fail to load firmware %s\n", @@ -1760,7 +1761,7 @@ static int wl_request_fw(struct wl_info *wl, struct pci_dev *pdev) wl_release_fw(wl); return status; } - WL_NONE(("request fw %s\n", fw_name)); + WL_NONE("request fw %s\n", fw_name); sprintf(fw_name, "%s_hdr-%d.fw", wl_firmwares[i], UCODE_LOADER_API_VER); status = request_firmware(&wl->fw.fw_hdr[i], fw_name, device); @@ -1772,8 +1773,8 @@ static int wl_request_fw(struct wl_info *wl, struct pci_dev *pdev) } wl->fw.hdr_num_entries[i] = wl->fw.fw_hdr[i]->size / (sizeof(struct wl_fw_hdr)); - WL_NONE(("request fw %s find: %d entries\n", fw_name, - wl->fw.hdr_num_entries[i])); + WL_NONE("request fw %s find: %d entries\n", + fw_name, wl->fw.hdr_num_entries[i]); } wl->fw.fw_cnt = i; return wl_ucode_data_init(wl); @@ -1811,16 +1812,16 @@ int wl_check_firmwares(struct wl_info *wl) if (fw == NULL && fw_hdr == NULL) { break; } else if (fw == NULL || fw_hdr == NULL) { - WL_ERROR(("%s: invalid bin/hdr fw\n", __func__)); + WL_ERROR("%s: invalid bin/hdr fw\n", __func__); rc = -EBADF; } else if (fw_hdr->size % sizeof(struct wl_fw_hdr)) { - WL_ERROR(("%s: non integral fw hdr file size %d/%d\n", - __func__, fw_hdr->size, - sizeof(struct wl_fw_hdr))); + WL_ERROR("%s: non integral fw hdr file size %d/%zu\n", + __func__, fw_hdr->size, + sizeof(struct wl_fw_hdr)); rc = -EBADF; } else if (fw->size < MIN_FW_SIZE || fw->size > MAX_FW_SIZE) { - WL_ERROR(("%s: out of bounds fw file size %d\n", - __func__, fw->size)); + WL_ERROR("%s: out of bounds fw file size %d\n", + __func__, fw->size); rc = -EBADF; } else { /* check if ucode section overruns firmware image */ @@ -1829,15 +1830,15 @@ int wl_check_firmwares(struct wl_info *wl) entry++, ucode_hdr++) { if (ucode_hdr->offset + ucode_hdr->len > fw->size) { - WL_ERROR(("%s: conflicting bin/hdr\n", - __func__)); + WL_ERROR("%s: conflicting bin/hdr\n", + __func__); rc = -EBADF; } } } } if (rc == 0 && wl->fw.fw_cnt != i) { - WL_ERROR(("%s: invalid fw_cnt=%d\n", __func__, wl->fw.fw_cnt)); + WL_ERROR("%s: invalid fw_cnt=%d\n", __func__, wl->fw.fw_cnt); rc = -EBADF; } return rc; diff --git a/drivers/staging/brcm80211/sys/wlc_alloc.c b/drivers/staging/brcm80211/sys/wlc_alloc.c index 9af2d17a40c0..746439e8fd57 100644 --- a/drivers/staging/brcm80211/sys/wlc_alloc.c +++ b/drivers/staging/brcm80211/sys/wlc_alloc.c @@ -43,7 +43,7 @@ void *wlc_calloc(struct osl_info *osh, uint unit, uint size) item = kzalloc(size, GFP_ATOMIC); if (item == NULL) - WL_ERROR(("wl%d: %s: out of memory\n", unit, __func__)); + WL_ERROR("wl%d: %s: out of memory\n", unit, __func__); return item; } diff --git a/drivers/staging/brcm80211/sys/wlc_ampdu.c b/drivers/staging/brcm80211/sys/wlc_ampdu.c index 0419c528e40e..d749917f5912 100644 --- a/drivers/staging/brcm80211/sys/wlc_ampdu.c +++ b/drivers/staging/brcm80211/sys/wlc_ampdu.c @@ -174,7 +174,8 @@ struct ampdu_info *wlc_ampdu_attach(struct wlc_info *wlc) ampdu = kzalloc(sizeof(struct ampdu_info), GFP_ATOMIC); if (!ampdu) { - WL_ERROR(("wl%d: wlc_ampdu_attach: out of mem\n", wlc->pub->unit)); + WL_ERROR("wl%d: wlc_ampdu_attach: out of mem\n", + wlc->pub->unit); return NULL; } ampdu->wlc = wlc; @@ -244,7 +245,7 @@ void scb_ampdu_cleanup(struct ampdu_info *ampdu, struct scb *scb) scb_ampdu_t *scb_ampdu = SCB_AMPDU_CUBBY(ampdu, scb); u8 tid; - WL_AMPDU_UPDN(("scb_ampdu_cleanup: enter\n")); + WL_AMPDU_UPDN("scb_ampdu_cleanup: enter\n"); ASSERT(scb_ampdu); for (tid = 0; tid < AMPDU_MAX_SCB_TID; tid++) { @@ -257,7 +258,7 @@ void scb_ampdu_cleanup(struct ampdu_info *ampdu, struct scb *scb) */ void wlc_ampdu_reset(struct ampdu_info *ampdu) { - WL_NONE(("%s: Entering\n", __func__)); + WL_NONE("%s: Entering\n", __func__); } static void scb_ampdu_update_config(struct ampdu_info *ampdu, struct scb *scb) @@ -338,7 +339,7 @@ static int wlc_ffpld_check_txfunfl(struct wlc_info *wlc, int fid) M_UCODE_MACSTAT + offsetof(macstat_t, txfunfl[fid])); new_txunfl = (u16) (cur_txunfl - fifo->prev_txfunfl); if (new_txunfl == 0) { - WL_FFPLD(("check_txunfl : TX status FRAG set but no tx underflows\n")); + WL_FFPLD("check_txunfl : TX status FRAG set but no tx underflows\n"); return -1; } fifo->prev_txfunfl = cur_txunfl; @@ -348,7 +349,7 @@ static int wlc_ffpld_check_txfunfl(struct wlc_info *wlc, int fid) /* check if fifo is big enough */ if (wlc_xmtfifo_sz_get(wlc, fid, &xmtfifo_sz)) { - WL_FFPLD(("check_txunfl : get xmtfifo_sz failed.\n")); + WL_FFPLD("check_txunfl : get xmtfifo_sz failed\n"); return -1; } @@ -362,8 +363,8 @@ static int wlc_ffpld_check_txfunfl(struct wlc_info *wlc, int fid) if (fifo->accum_txfunfl < 10) return 0; - WL_FFPLD(("ampdu_count %d tx_underflows %d\n", - current_ampdu_cnt, fifo->accum_txfunfl)); + WL_FFPLD("ampdu_count %d tx_underflows %d\n", + current_ampdu_cnt, fifo->accum_txfunfl); /* compute the current ratio of tx unfl per ampdu. @@ -416,8 +417,8 @@ static int wlc_ffpld_check_txfunfl(struct wlc_info *wlc, int fid) (max_mpdu * FFPLD_MPDU_SIZE - fifo->ampdu_pld_size)) / (max_mpdu * FFPLD_MPDU_SIZE)) * 100; - WL_FFPLD(("DMA estimated transfer rate %d; pre-load size %d\n", - fifo->dmaxferrate, fifo->ampdu_pld_size)); + WL_FFPLD("DMA estimated transfer rate %d; pre-load size %d\n", + fifo->dmaxferrate, fifo->ampdu_pld_size); } else { /* decrease ampdu size */ @@ -552,7 +553,7 @@ wlc_sendampdu(struct ampdu_info *ampdu, wlc_txq_info_t *qi, wlc_ampdu_agg(ampdu, scb, p, tid); if (wlc->block_datafifo) { - WL_ERROR(("%s: Fifo blocked\n", __func__)); + WL_ERROR("%s: Fifo blocked\n", __func__); return BCME_BUSY; } rr_retry_limit = ampdu->rr_retry_limit_tid[tid]; @@ -567,7 +568,7 @@ wlc_sendampdu(struct ampdu_info *ampdu, wlc_txq_info_t *qi, if (tx_info->flags & IEEE80211_TX_CTL_AMPDU) { err = wlc_prep_pdu(wlc, p, &fifo); } else { - WL_ERROR(("%s: AMPDU flag is off!\n", __func__)); + WL_ERROR("%s: AMPDU flag is off!\n", __func__); *pdu = NULL; err = 0; break; @@ -575,14 +576,16 @@ wlc_sendampdu(struct ampdu_info *ampdu, wlc_txq_info_t *qi, if (err) { if (err == BCME_BUSY) { - WL_ERROR(("wl%d: wlc_sendampdu: prep_xdu retry; seq 0x%x\n", wlc->pub->unit, seq)); + WL_ERROR("wl%d: wlc_sendampdu: prep_xdu retry; seq 0x%x\n", + wlc->pub->unit, seq); WLCNTINCR(ampdu->cnt->sduretry); *pdu = p; break; } /* error in the packet; reject it */ - WL_AMPDU_ERR(("wl%d: wlc_sendampdu: prep_xdu rejected; seq 0x%x\n", wlc->pub->unit, seq)); + WL_AMPDU_ERR("wl%d: wlc_sendampdu: prep_xdu rejected; seq 0x%x\n", + wlc->pub->unit, seq); WLCNTINCR(ampdu->cnt->sdurejected); *pdu = NULL; @@ -624,8 +627,8 @@ wlc_sendampdu(struct ampdu_info *ampdu, wlc_txq_info_t *qi, ndelim = txh->RTSPLCPFallback[AMPDU_FBR_NULL_DELIM]; seg_cnt += 1; - WL_AMPDU_TX(("wl%d: wlc_sendampdu: mpdu %d plcp_len %d\n", - wlc->pub->unit, count, len)); + WL_AMPDU_TX("wl%d: wlc_sendampdu: mpdu %d plcp_len %d\n", + wlc->pub->unit, count, len); /* * aggregateable mpdu. For ucode/hw agg, @@ -656,7 +659,8 @@ wlc_sendampdu(struct ampdu_info *ampdu, wlc_txq_info_t *qi, dma_len += (u16) pkttotlen(osh, p); - WL_AMPDU_TX(("wl%d: wlc_sendampdu: ampdu_len %d seg_cnt %d null delim %d\n", wlc->pub->unit, ampdu_len, seg_cnt, ndelim)); + WL_AMPDU_TX("wl%d: wlc_sendampdu: ampdu_len %d seg_cnt %d null delim %d\n", + wlc->pub->unit, ampdu_len, seg_cnt, ndelim); txh->MacTxControlLow = htol16(mcl); @@ -686,8 +690,8 @@ wlc_sendampdu(struct ampdu_info *ampdu, wlc_txq_info_t *qi, min(scb_ampdu->max_rxlen, ampdu->max_txlen[mcs][is40][sgi]); - WL_NONE(("sendampdu: sgi %d, is40 %d, mcs %d\n", sgi, - is40, mcs)); + WL_NONE("sendampdu: sgi %d, is40 %d, mcs %d\n", + sgi, is40, mcs); maxlen = 64 * 1024; /* XXX Fix me to honor real max_rxlen */ @@ -730,13 +734,14 @@ wlc_sendampdu(struct ampdu_info *ampdu, wlc_txq_info_t *qi, /* test whether to add more */ if ((MCS_RATE(mcs, true, false) >= f->dmaxferrate) && (count == f->mcs2ampdu_table[mcs])) { - WL_AMPDU_ERR(("wl%d: PR 37644: stopping ampdu at %d for mcs %d", wlc->pub->unit, count, mcs)); + WL_AMPDU_ERR("wl%d: PR 37644: stopping ampdu at %d for mcs %d\n", + wlc->pub->unit, count, mcs); break; } if (count == scb_ampdu->max_pdu) { - WL_NONE(("Stop taking from q, reached %d deep\n", - scb_ampdu->max_pdu)); + WL_NONE("Stop taking from q, reached %d deep\n", + scb_ampdu->max_pdu); break; } @@ -754,15 +759,16 @@ wlc_sendampdu(struct ampdu_info *ampdu, wlc_txq_info_t *qi, if ((plen + ampdu_len) > maxlen) { p = NULL; - WL_ERROR(("%s: Bogus plen #1\n", - __func__)); + WL_ERROR("%s: Bogus plen #1\n", + __func__); ASSERT(3 == 4); continue; } /* check if there are enough descriptors available */ if (TXAVAIL(wlc, fifo) <= (seg_cnt + 1)) { - WL_ERROR(("%s: No fifo space !!!!!!\n", __func__)); + WL_ERROR("%s: No fifo space !!!!!!\n", + __func__); p = NULL; continue; } @@ -869,13 +875,14 @@ wlc_sendampdu(struct ampdu_info *ampdu, wlc_txq_info_t *qi, WLC_SET_MIMO_PLCP_AMPDU(txh->FragPLCPFallback); } - WL_AMPDU_TX(("wl%d: wlc_sendampdu: count %d ampdu_len %d\n", - wlc->pub->unit, count, ampdu_len)); + WL_AMPDU_TX("wl%d: wlc_sendampdu: count %d ampdu_len %d\n", + wlc->pub->unit, count, ampdu_len); /* inform rate_sel if it this is a rate probe pkt */ frameid = ltoh16(txh->TxFrameID); if (frameid & TXFID_RATE_PROBE_MASK) { - WL_ERROR(("%s: XXX what to do with TXFID_RATE_PROBE_MASK!?\n", __func__)); + WL_ERROR("%s: XXX what to do with TXFID_RATE_PROBE_MASK!?\n", + __func__); } for (i = 0; i < count; i++) wlc_txfifo(wlc, fifo, pkt[i], i == (count - 1), @@ -1029,13 +1036,16 @@ wlc_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb, if (supr_status) { update_rate = false; if (supr_status == TX_STATUS_SUPR_BADCH) { - WL_ERROR(("%s: Pkt tx suppressed, illegal channel possibly %d\n", __func__, CHSPEC_CHANNEL(wlc->default_bss->chanspec))); + WL_ERROR("%s: Pkt tx suppressed, illegal channel possibly %d\n", + __func__, + CHSPEC_CHANNEL(wlc->default_bss->chanspec)); } else { if (supr_status == TX_STATUS_SUPR_FRAG) - WL_NONE(("%s: AMPDU frag err\n", - __func__)); + WL_NONE("%s: AMPDU frag err\n", + __func__); else - WL_ERROR(("%s: wlc_ampdu_dotxstatus: supr_status 0x%x\n", __func__, supr_status)); + WL_ERROR("%s: wlc_ampdu_dotxstatus: supr_status 0x%x\n", + __func__, supr_status); } /* no need to retry for badch; will fail again */ if (supr_status == TX_STATUS_SUPR_BADCH || @@ -1059,7 +1069,8 @@ wlc_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb, } else if (txs->phyerr) { update_rate = false; WLCNTINCR(wlc->pub->_cnt->txphyerr); - WL_ERROR(("wl%d: wlc_ampdu_dotxstatus: tx phy error (0x%x)\n", wlc->pub->unit, txs->phyerr)); + WL_ERROR("wl%d: wlc_ampdu_dotxstatus: tx phy error (0x%x)\n", + wlc->pub->unit, txs->phyerr); #ifdef BCMDBG if (WL_ERROR_ON()) { @@ -1091,10 +1102,9 @@ wlc_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb, if (ba_recd) { bindex = MODSUB_POW2(seq, start_seq, SEQNUM_MAX); - WL_AMPDU_TX(("%s: tid %d seq is %d, start_seq is %d, " - "bindex is %d set %d, index %d\n", - __func__, tid, seq, start_seq, bindex, - isset(bitmap, bindex), index)); + WL_AMPDU_TX("%s: tid %d seq is %d, start_seq is %d, bindex is %d set %d, index %d\n", + __func__, tid, seq, start_seq, bindex, + isset(bitmap, bindex), index); /* if acked then clear bit and free packet */ if ((bindex < AMPDU_TX_BA_MAX_WSIZE) @@ -1147,7 +1157,8 @@ wlc_ampdu_dotxstatus_complete(struct ampdu_info *ampdu, struct scb *scb, IEEE80211_TX_STAT_AMPDU_NO_BACK; skb_pull(p, D11_PHY_HDR_LEN); skb_pull(p, D11_TXH_LEN); - WL_ERROR(("%s: BA Timeout, seq %d, in_transit %d\n", SHORTNAME, seq, ini->tx_in_transit)); + WL_ERROR("%s: BA Timeout, seq %d, in_transit %d\n", + SHORTNAME, seq, ini->tx_in_transit); ieee80211_tx_status_irqsafe(wlc->pub->ieee_hw, p); } @@ -1183,8 +1194,8 @@ ampdu_cleanup_tid_ini(struct ampdu_info *ampdu, scb_ampdu_t *scb_ampdu, u8 tid, if (!ini) return; - WL_AMPDU_CTL(("wl%d: ampdu_cleanup_tid_ini: tid %d\n", - ampdu->wlc->pub->unit, tid)); + WL_AMPDU_CTL("wl%d: ampdu_cleanup_tid_ini: tid %d\n", + ampdu->wlc->pub->unit, tid); if (ini->tx_in_transit && !force) return; @@ -1210,7 +1221,7 @@ static scb_ampdu_tid_ini_t *wlc_ampdu_init_tid_ini(struct ampdu_info *ampdu, /* check for per-tid control of ampdu */ if (!ampdu->ini_enable[tid]) { - WL_ERROR(("%s: Rejecting tid %d\n", __func__, tid)); + WL_ERROR("%s: Rejecting tid %d\n", __func__, tid); return NULL; } @@ -1231,13 +1242,13 @@ int wlc_ampdu_set(struct ampdu_info *ampdu, bool on) if (on) { if (!N_ENAB(wlc->pub)) { - WL_AMPDU_ERR(("wl%d: driver not nmode enabled\n", - wlc->pub->unit)); + WL_AMPDU_ERR("wl%d: driver not nmode enabled\n", + wlc->pub->unit); return BCME_UNSUPPORTED; } if (!wlc_ampdu_cap(ampdu)) { - WL_AMPDU_ERR(("wl%d: device not ampdu capable\n", - wlc->pub->unit)); + WL_AMPDU_ERR("wl%d: device not ampdu capable\n", + wlc->pub->unit); return BCME_UNSUPPORTED; } wlc->pub->_ampdu = on; diff --git a/drivers/staging/brcm80211/sys/wlc_antsel.c b/drivers/staging/brcm80211/sys/wlc_antsel.c index 27558fa02ba7..402ddf8f3371 100644 --- a/drivers/staging/brcm80211/sys/wlc_antsel.c +++ b/drivers/staging/brcm80211/sys/wlc_antsel.c @@ -102,7 +102,7 @@ struct antsel_info *wlc_antsel_attach(struct wlc_info *wlc, asi = kzalloc(sizeof(struct antsel_info), GFP_ATOMIC); if (!asi) { - WL_ERROR(("wl%d: wlc_antsel_attach: out of mem\n", pub->unit)); + WL_ERROR("wl%d: wlc_antsel_attach: out of mem\n", pub->unit); return NULL; } @@ -131,7 +131,7 @@ struct antsel_info *wlc_antsel_attach(struct wlc_info *wlc, asi->antsel_avail = false; } else { asi->antsel_avail = false; - WL_ERROR(("wlc_antsel_attach: 2o3 board cfg invalid\n")); + WL_ERROR("wlc_antsel_attach: 2o3 board cfg invalid\n"); ASSERT(0); } break; diff --git a/drivers/staging/brcm80211/sys/wlc_bmac.c b/drivers/staging/brcm80211/sys/wlc_bmac.c index 0c2625dc440b..69f600affa46 100644 --- a/drivers/staging/brcm80211/sys/wlc_bmac.c +++ b/drivers/staging/brcm80211/sys/wlc_bmac.c @@ -217,18 +217,20 @@ static void WLBANDINITFN(wlc_ucode_bsinit) (struct wlc_hw_info *wlc_hw) if (WLCISNPHY(wlc_hw->band)) { wlc_write_inits(wlc_hw, d11n0bsinitvals16); } else { - WL_ERROR(("%s: wl%d: unsupported phy in corerev %d\n", - __func__, wlc_hw->unit, wlc_hw->corerev)); + WL_ERROR("%s: wl%d: unsupported phy in corerev %d\n", + __func__, wlc_hw->unit, wlc_hw->corerev); } } else { if (D11REV_IS(wlc_hw->corerev, 24)) { if (WLCISLCNPHY(wlc_hw->band)) { wlc_write_inits(wlc_hw, d11lcn0bsinitvals24); } else - WL_ERROR(("%s: wl%d: unsupported phy in corerev %d\n", __func__, wlc_hw->unit, wlc_hw->corerev)); + WL_ERROR("%s: wl%d: unsupported phy in corerev %d\n", + __func__, wlc_hw->unit, + wlc_hw->corerev); } else { - WL_ERROR(("%s: wl%d: unsupported corerev %d\n", - __func__, wlc_hw->unit, wlc_hw->corerev)); + WL_ERROR("%s: wl%d: unsupported corerev %d\n", + __func__, wlc_hw->unit, wlc_hw->corerev); } } } @@ -240,7 +242,7 @@ static u32 WLBANDINITFN(wlc_setband_inact) (struct wlc_info *wlc, uint bandunit) u32 macintmask; u32 tmp; - WL_TRACE(("wl%d: wlc_setband_inact\n", wlc_hw->unit)); + WL_TRACE("wl%d: wlc_setband_inact\n", wlc_hw->unit); ASSERT(bandunit != wlc_hw->band->bandunit); ASSERT(si_iscoreup(wlc_hw->sih)); @@ -281,7 +283,7 @@ wlc_bmac_recv(struct wlc_hw_info *wlc_hw, uint fifo, bool bound) u32 tsf_h, tsf_l; wlc_d11rxhdr_t *wlc_rxhdr = NULL; - WL_TRACE(("wl%d: %s\n", wlc_hw->unit, __func__)); + WL_TRACE("wl%d: %s\n", wlc_hw->unit, __func__); /* gather received frames */ while ((p = dma_rx(wlc_hw->di[fifo]))) { @@ -333,7 +335,7 @@ bool BCMFASTPATH wlc_dpc(struct wlc_info *wlc, bool bounded) bool fatal = false; if (DEVICEREMOVED(wlc)) { - WL_ERROR(("wl%d: %s: dead chip\n", wlc_hw->unit, __func__)); + WL_ERROR("wl%d: %s: dead chip\n", wlc_hw->unit, __func__); wl_down(wlc->wl); return false; } @@ -342,8 +344,8 @@ bool BCMFASTPATH wlc_dpc(struct wlc_info *wlc, bool bounded) macintstatus = wlc->macintstatus; wlc->macintstatus = 0; - WL_TRACE(("wl%d: wlc_dpc: macintstatus 0x%x\n", wlc_hw->unit, - macintstatus)); + WL_TRACE("wl%d: wlc_dpc: macintstatus 0x%x\n", + wlc_hw->unit, macintstatus); if (macintstatus & MI_PRQ) { /* Process probe request FIFO */ @@ -366,7 +368,7 @@ bool BCMFASTPATH wlc_dpc(struct wlc_info *wlc, bool bounded) if (wlc_bmac_txstatus(wlc->hw, bounded, &fatal)) wlc->macintstatus |= MI_TFS; if (fatal) { - WL_ERROR(("MI_TFS: fatal\n")); + WL_ERROR("MI_TFS: fatal\n"); goto fatal; } } @@ -376,7 +378,7 @@ bool BCMFASTPATH wlc_dpc(struct wlc_info *wlc, bool bounded) /* ATIM window end */ if (macintstatus & MI_ATIMWINEND) { - WL_TRACE(("wlc_isr: end of ATIM window\n")); + WL_TRACE("wlc_isr: end of ATIM window\n"); OR_REG(wlc_hw->osh, ®s->maccommand, wlc->qvalid); wlc->qvalid = 0; @@ -397,7 +399,7 @@ bool BCMFASTPATH wlc_dpc(struct wlc_info *wlc, bool bounded) /* TX FIFO suspend/flush completion */ if (macintstatus & MI_TXSTOP) { if (wlc_bmac_tx_fifo_suspended(wlc_hw, TX_DATA_FIFO)) { - /* WL_ERROR(("dpc: fifo_suspend_comlete\n")); */ + /* WL_ERROR("dpc: fifo_suspend_comlete\n"); */ } } @@ -407,7 +409,8 @@ bool BCMFASTPATH wlc_dpc(struct wlc_info *wlc, bool bounded) } if (macintstatus & MI_GP0) { - WL_ERROR(("wl%d: PSM microcode watchdog fired at %d (seconds). Resetting.\n", wlc_hw->unit, wlc_hw->now)); + WL_ERROR("wl%d: PSM microcode watchdog fired at %d (seconds). Resetting.\n", + wlc_hw->unit, wlc_hw->now); printk_once("%s : PSM Watchdog, chipid 0x%x, chiprev 0x%x\n", __func__, wlc_hw->sih->chip, @@ -429,7 +432,8 @@ bool BCMFASTPATH wlc_dpc(struct wlc_info *wlc, bool bounded) u32 rfd = R_REG(wlc_hw->osh, ®s->phydebug) & PDBG_RFD; #endif - WL_ERROR(("wl%d: MAC Detected a change on the RF Disable Input 0x%x\n", wlc_hw->unit, rfd)); + WL_ERROR("wl%d: MAC Detected a change on the RF Disable Input 0x%x\n", + wlc_hw->unit, rfd); WLCNTINCR(wlc->pub->_cnt->rfdisable); } @@ -457,7 +461,7 @@ void wlc_bmac_watchdog(void *arg) struct wlc_info *wlc = (struct wlc_info *) arg; struct wlc_hw_info *wlc_hw = wlc->hw; - WL_TRACE(("wl%d: wlc_bmac_watchdog\n", wlc_hw->unit)); + WL_TRACE("wl%d: wlc_bmac_watchdog\n", wlc_hw->unit); if (!wlc_hw->up) return; @@ -483,8 +487,8 @@ wlc_bmac_set_chanspec(struct wlc_hw_info *wlc_hw, chanspec_t chanspec, { uint bandunit; - WL_TRACE(("wl%d: wlc_bmac_set_chanspec 0x%x\n", wlc_hw->unit, - chanspec)); + WL_TRACE("wl%d: wlc_bmac_set_chanspec 0x%x\n", + wlc_hw->unit, chanspec); wlc_hw->chanspec = chanspec; @@ -594,7 +598,8 @@ static bool wlc_bmac_attach_dmapio(struct wlc_info *wlc, uint j, bool wme) dma_addrwidth(wlc_hw->sih, DMAREG(wlc_hw, DMA_TX, 0)); if (!wl_alloc_dma_resources(wlc_hw->wlc->wl, addrwidth)) { - WL_ERROR(("wl%d: wlc_attach: alloc_dma_resources failed\n", unit)); + WL_ERROR("wl%d: wlc_attach: alloc_dma_resources failed\n", + unit); return false; } @@ -667,8 +672,7 @@ static bool wlc_bmac_attach_dmapio(struct wlc_info *wlc, uint j, bool wme) /* Cleaner to leave this as if with AP defined */ if (dma_attach_err) { - WL_ERROR(("wl%d: wlc_attach: dma_attach failed\n", - unit)); + WL_ERROR("wl%d: wlc_attach: dma_attach failed\n", unit); return false; } @@ -717,8 +721,8 @@ int wlc_bmac_attach(struct wlc_info *wlc, u16 vendor, u16 device, uint unit, bool wme = false; shared_phy_params_t sha_params; - WL_TRACE(("wl%d: wlc_bmac_attach: vendor 0x%x device 0x%x\n", unit, - vendor, device)); + WL_TRACE("wl%d: wlc_bmac_attach: vendor 0x%x device 0x%x\n", + unit, vendor, device); ASSERT(sizeof(wlc_d11rxhdr_t) <= WL_HWRXOFF); @@ -742,7 +746,7 @@ int wlc_bmac_attach(struct wlc_info *wlc, u16 vendor, u16 device, uint unit, wlc_hw->sih = si_attach((uint) device, osh, regsva, bustype, btparam, &wlc_hw->vars, &wlc_hw->vars_size); if (wlc_hw->sih == NULL) { - WL_ERROR(("wl%d: wlc_bmac_attach: si_attach failed\n", unit)); + WL_ERROR("wl%d: wlc_bmac_attach: si_attach failed\n", unit); err = 11; goto fail; } @@ -762,21 +766,22 @@ int wlc_bmac_attach(struct wlc_info *wlc, u16 vendor, u16 device, uint unit, var = getvar(vars, "vendid"); if (var) { vendor = (u16) simple_strtoul(var, NULL, 0); - WL_ERROR(("Overriding vendor id = 0x%x\n", vendor)); + WL_ERROR("Overriding vendor id = 0x%x\n", vendor); } var = getvar(vars, "devid"); if (var) { u16 devid = (u16) simple_strtoul(var, NULL, 0); if (devid != 0xffff) { device = devid; - WL_ERROR(("Overriding device id = 0x%x\n", - device)); + WL_ERROR("Overriding device id = 0x%x\n", + device); } } /* verify again the device is supported */ if (!wlc_chipmatch(vendor, device)) { - WL_ERROR(("wl%d: wlc_bmac_attach: Unsupported vendor/device (0x%x/0x%x)\n", unit, vendor, device)); + WL_ERROR("wl%d: wlc_bmac_attach: Unsupported vendor/device (0x%x/0x%x)\n", + unit, vendor, device); err = 12; goto fail; } @@ -811,7 +816,8 @@ int wlc_bmac_attach(struct wlc_info *wlc, u16 vendor, u16 device, uint unit, wlc_bmac_corereset(wlc_hw, WLC_USE_COREFLAGS); if (!wlc_bmac_validate_chip_access(wlc_hw)) { - WL_ERROR(("wl%d: wlc_bmac_attach: validate_chip_access failed\n", unit)); + WL_ERROR("wl%d: wlc_bmac_attach: validate_chip_access failed\n", + unit); err = 14; goto fail; } @@ -823,7 +829,8 @@ int wlc_bmac_attach(struct wlc_info *wlc, u16 vendor, u16 device, uint unit, j = BOARDREV_PROMOTED; wlc_hw->boardrev = (u16) j; if (!wlc_validboardtype(wlc_hw)) { - WL_ERROR(("wl%d: wlc_bmac_attach: Unsupported Broadcom board type (0x%x)" " or revision level (0x%x)\n", unit, wlc_hw->sih->boardtype, wlc_hw->boardrev)); + WL_ERROR("wl%d: wlc_bmac_attach: Unsupported Broadcom board type (0x%x)" " or revision level (0x%x)\n", + unit, wlc_hw->sih->boardtype, wlc_hw->boardrev); err = 15; goto fail; } @@ -865,8 +872,8 @@ int wlc_bmac_attach(struct wlc_info *wlc, u16 vendor, u16 device, uint unit, wlc_hw->physhim = wlc_phy_shim_attach(wlc_hw, wlc->wl, wlc); if (wlc_hw->physhim == NULL) { - WL_ERROR(("wl%d: wlc_bmac_attach: wlc_phy_shim_attach failed\n", - unit)); + WL_ERROR("wl%d: wlc_bmac_attach: wlc_phy_shim_attach failed\n", + unit); err = 25; goto fail; } @@ -933,7 +940,8 @@ int wlc_bmac_attach(struct wlc_info *wlc, u16 vendor, u16 device, uint unit, wlc_hw->band->pi = wlc_phy_attach(wlc_hw->phy_sh, (void *)regs, wlc_hw->band->bandtype, vars); if (wlc_hw->band->pi == NULL) { - WL_ERROR(("wl%d: wlc_bmac_attach: wlc_phy_attach failed\n", unit)); + WL_ERROR("wl%d: wlc_bmac_attach: wlc_phy_attach failed\n", + unit); err = 17; goto fail; } @@ -963,7 +971,9 @@ int wlc_bmac_attach(struct wlc_info *wlc, u16 vendor, u16 device, uint unit, goto bad_phy; } else { bad_phy: - WL_ERROR(("wl%d: wlc_bmac_attach: unsupported phy type/rev (%d/%d)\n", unit, wlc_hw->band->phytype, wlc_hw->band->phyrev)); + WL_ERROR("wl%d: wlc_bmac_attach: unsupported phy type/rev (%d/%d)\n", + unit, + wlc_hw->band->phytype, wlc_hw->band->phyrev); err = 18; goto fail; } @@ -1018,27 +1028,27 @@ int wlc_bmac_attach(struct wlc_info *wlc, u16 vendor, u16 device, uint unit, /* init etheraddr state variables */ macaddr = wlc_get_macaddr(wlc_hw); if (macaddr == NULL) { - WL_ERROR(("wl%d: wlc_bmac_attach: macaddr not found\n", unit)); + WL_ERROR("wl%d: wlc_bmac_attach: macaddr not found\n", unit); err = 21; goto fail; } bcm_ether_atoe(macaddr, &wlc_hw->etheraddr); if (is_broadcast_ether_addr(wlc_hw->etheraddr.octet) || is_zero_ether_addr(wlc_hw->etheraddr.octet)) { - WL_ERROR(("wl%d: wlc_bmac_attach: bad macaddr %s\n", unit, - macaddr)); + WL_ERROR("wl%d: wlc_bmac_attach: bad macaddr %s\n", + unit, macaddr); err = 22; goto fail; } - WL_ERROR(("%s:: deviceid 0x%x nbands %d board 0x%x macaddr: %s\n", - __func__, wlc_hw->deviceid, wlc_hw->_nbands, - wlc_hw->sih->boardtype, macaddr)); + WL_ERROR("%s:: deviceid 0x%x nbands %d board 0x%x macaddr: %s\n", + __func__, wlc_hw->deviceid, wlc_hw->_nbands, + wlc_hw->sih->boardtype, macaddr); return err; fail: - WL_ERROR(("wl%d: wlc_bmac_attach: failed with err %d\n", unit, err)); + WL_ERROR("wl%d: wlc_bmac_attach: failed with err %d\n", unit, err); return err; } @@ -1122,7 +1132,7 @@ int wlc_bmac_detach(struct wlc_info *wlc) void wlc_bmac_reset(struct wlc_hw_info *wlc_hw) { - WL_TRACE(("wl%d: wlc_bmac_reset\n", wlc_hw->unit)); + WL_TRACE("wl%d: wlc_bmac_reset\n", wlc_hw->unit); WLCNTINCR(wlc_hw->wlc->pub->_cnt->reset); @@ -1143,7 +1153,7 @@ wlc_bmac_init(struct wlc_hw_info *wlc_hw, chanspec_t chanspec, bool fastclk; struct wlc_info *wlc = wlc_hw->wlc; - WL_TRACE(("wl%d: wlc_bmac_init\n", wlc_hw->unit)); + WL_TRACE("wl%d: wlc_bmac_init\n", wlc_hw->unit); /* request FAST clock if not on */ fastclk = wlc_hw->forcefastclk; @@ -1192,7 +1202,7 @@ int wlc_bmac_up_prep(struct wlc_hw_info *wlc_hw) { uint coremask; - WL_TRACE(("wl%d: %s:\n", wlc_hw->unit, __func__)); + WL_TRACE("wl%d: %s:\n", wlc_hw->unit, __func__); ASSERT(wlc_hw->wlc->pub->hw_up && wlc_hw->wlc->macintmask == 0); @@ -1238,7 +1248,7 @@ int wlc_bmac_up_prep(struct wlc_hw_info *wlc_hw) int wlc_bmac_up_finish(struct wlc_hw_info *wlc_hw) { - WL_TRACE(("wl%d: %s:\n", wlc_hw->unit, __func__)); + WL_TRACE("wl%d: %s:\n", wlc_hw->unit, __func__); wlc_hw->up = true; wlc_phy_hw_state_upd(wlc_hw->band->pi, true); @@ -1255,7 +1265,7 @@ int wlc_bmac_down_prep(struct wlc_hw_info *wlc_hw) bool dev_gone; uint callbacks = 0; - WL_TRACE(("wl%d: %s:\n", wlc_hw->unit, __func__)); + WL_TRACE("wl%d: %s:\n", wlc_hw->unit, __func__); if (!wlc_hw->up) return callbacks; @@ -1283,7 +1293,7 @@ int wlc_bmac_down_finish(struct wlc_hw_info *wlc_hw) uint callbacks = 0; bool dev_gone; - WL_TRACE(("wl%d: %s:\n", wlc_hw->unit, __func__)); + WL_TRACE("wl%d: %s:\n", wlc_hw->unit, __func__); if (!wlc_hw->up) return callbacks; @@ -1719,7 +1729,7 @@ wlc_bmac_set_rcmta(struct wlc_hw_info *wlc_hw, int idx, u16 mac_l; struct osl_info *osh; - WL_TRACE(("wl%d: %s\n", wlc_hw->unit, __func__)); + WL_TRACE("wl%d: %s\n", wlc_hw->unit, __func__); ASSERT(wlc_hw->corerev > 4); @@ -1752,7 +1762,7 @@ wlc_bmac_set_addrmatch(struct wlc_hw_info *wlc_hw, int match_reg_offset, u16 mac_h; struct osl_info *osh; - WL_TRACE(("wl%d: wlc_bmac_set_addrmatch\n", wlc_hw->unit)); + WL_TRACE("wl%d: wlc_bmac_set_addrmatch\n", wlc_hw->unit); ASSERT((match_reg_offset < RCM_SIZE) || (wlc_hw->corerev == 4)); @@ -1783,7 +1793,7 @@ wlc_bmac_write_template_ram(struct wlc_hw_info *wlc_hw, int offset, int len, #endif /* IL_BIGENDIAN */ struct osl_info *osh; - WL_TRACE(("wl%d: wlc_bmac_write_template_ram\n", wlc_hw->unit)); + WL_TRACE("wl%d: wlc_bmac_write_template_ram\n", wlc_hw->unit); regs = wlc_hw->regs; osh = wlc_hw->osh; @@ -1937,8 +1947,8 @@ WLBANDINITFN(wlc_bmac_bsinit) (struct wlc_info *wlc, chanspec_t chanspec) { struct wlc_hw_info *wlc_hw = wlc->hw; - WL_TRACE(("wl%d: wlc_bmac_bsinit: bandunit %d\n", wlc_hw->unit, - wlc_hw->band->bandunit)); + WL_TRACE("wl%d: wlc_bmac_bsinit: bandunit %d\n", + wlc_hw->unit, wlc_hw->band->bandunit); /* sanity check */ if (PHY_TYPE(R_REG(wlc_hw->osh, &wlc_hw->regs->phyversion)) != @@ -1974,7 +1984,7 @@ WLBANDINITFN(wlc_bmac_bsinit) (struct wlc_info *wlc, chanspec_t chanspec) void wlc_bmac_core_phy_clk(struct wlc_hw_info *wlc_hw, bool clk) { - WL_TRACE(("wl%d: wlc_bmac_core_phy_clk: clk %d\n", wlc_hw->unit, clk)); + WL_TRACE("wl%d: wlc_bmac_core_phy_clk: clk %d\n", wlc_hw->unit, clk); wlc_hw->phyclk = clk; @@ -1999,7 +2009,7 @@ void wlc_bmac_core_phy_clk(struct wlc_hw_info *wlc_hw, bool clk) /* Perform a soft reset of the PHY PLL */ void wlc_bmac_core_phypll_reset(struct wlc_hw_info *wlc_hw) { - WL_TRACE(("wl%d: wlc_bmac_core_phypll_reset\n", wlc_hw->unit)); + WL_TRACE("wl%d: wlc_bmac_core_phypll_reset\n", wlc_hw->unit); si_corereg(wlc_hw->sih, SI_CC_IDX, offsetof(chipcregs_t, chipcontrol_addr), ~0, 0); @@ -2045,7 +2055,7 @@ void wlc_bmac_phy_reset(struct wlc_hw_info *wlc_hw) u32 phy_bw_clkbits; bool phy_in_reset = false; - WL_TRACE(("wl%d: wlc_bmac_phy_reset\n", wlc_hw->unit)); + WL_TRACE("wl%d: wlc_bmac_phy_reset\n", wlc_hw->unit); if (pih == NULL) return; @@ -2127,7 +2137,7 @@ WLBANDINITFN(wlc_bmac_setband) (struct wlc_hw_info *wlc_hw, uint bandunit, /* low-level band switch utility routine */ void WLBANDINITFN(wlc_setxband) (struct wlc_hw_info *wlc_hw, uint bandunit) { - WL_TRACE(("wl%d: wlc_setxband: bandunit %d\n", wlc_hw->unit, bandunit)); + WL_TRACE("wl%d: wlc_setxband: bandunit %d\n", wlc_hw->unit, bandunit); wlc_hw->band = wlc_hw->bandstate[bandunit]; @@ -2146,7 +2156,7 @@ static bool wlc_isgoodchip(struct wlc_hw_info *wlc_hw) /* reject unsupported corerev */ if (!VALID_COREREV(wlc_hw->corerev)) { - WL_ERROR(("unsupported core rev %d\n", wlc_hw->corerev)); + WL_ERROR("unsupported core rev %d\n", wlc_hw->corerev); return false; } @@ -2194,7 +2204,8 @@ static char *wlc_get_macaddr(struct wlc_hw_info *wlc_hw) macaddr = getvar(wlc_hw->vars, varname); if (macaddr == NULL) { - WL_ERROR(("wl%d: wlc_get_macaddr: macaddr getvar(%s) not found\n", wlc_hw->unit, varname)); + WL_ERROR("wl%d: wlc_get_macaddr: macaddr getvar(%s) not found\n", + wlc_hw->unit, varname); } return macaddr; @@ -2257,7 +2268,7 @@ void wlc_bmac_hw_up(struct wlc_hw_info *wlc_hw) if (wlc_hw->wlc->pub->hw_up) return; - WL_TRACE(("wl%d: %s:\n", wlc_hw->unit, __func__)); + WL_TRACE("wl%d: %s:\n", wlc_hw->unit, __func__); /* * Enable pll and xtal, initialize the power control registers, @@ -2312,7 +2323,8 @@ static bool wlc_dma_rxreset(struct wlc_hw_info *wlc_hw, uint fifo) 50000); if (!rxidle && (rcv_frm_cnt != 0)) - WL_ERROR(("wl%d: %s: rxdma[%d] not idle && rcv_frm_cnt(%d) not zero\n", wlc_hw->unit, __func__, fifo, rcv_frm_cnt)); + WL_ERROR("wl%d: %s: rxdma[%d] not idle && rcv_frm_cnt(%d) not zero\n", + wlc_hw->unit, __func__, fifo, rcv_frm_cnt); mdelay(2); } @@ -2337,7 +2349,7 @@ void wlc_bmac_corereset(struct wlc_hw_info *wlc_hw, u32 flags) if (flags == WLC_USE_COREFLAGS) flags = (wlc_hw->band->pi ? wlc_hw->band->core_flags : 0); - WL_TRACE(("wl%d: %s\n", wlc_hw->unit, __func__)); + WL_TRACE("wl%d: %s\n", wlc_hw->unit, __func__); regs = wlc_hw->regs; @@ -2350,17 +2362,20 @@ void wlc_bmac_corereset(struct wlc_hw_info *wlc_hw, u32 flags) if (si_iscoreup(wlc_hw->sih)) { for (i = 0; i < NFIFO; i++) if ((wlc_hw->di[i]) && (!dma_txreset(wlc_hw->di[i]))) { - WL_ERROR(("wl%d: %s: dma_txreset[%d]: cannot stop dma\n", wlc_hw->unit, __func__, i)); + WL_ERROR("wl%d: %s: dma_txreset[%d]: cannot stop dma\n", + wlc_hw->unit, __func__, i); } if ((wlc_hw->di[RX_FIFO]) && (!wlc_dma_rxreset(wlc_hw, RX_FIFO))) { - WL_ERROR(("wl%d: %s: dma_rxreset[%d]: cannot stop dma\n", wlc_hw->unit, __func__, RX_FIFO)); + WL_ERROR("wl%d: %s: dma_rxreset[%d]: cannot stop dma\n", + wlc_hw->unit, __func__, RX_FIFO); } if (D11REV_IS(wlc_hw->corerev, 4) && wlc_hw->di[RX_TXSTATUS_FIFO] && (!wlc_dma_rxreset(wlc_hw, RX_TXSTATUS_FIFO))) { - WL_ERROR(("wl%d: %s: dma_rxreset[%d]: cannot stop dma\n", wlc_hw->unit, __func__, RX_TXSTATUS_FIFO)); + WL_ERROR("wl%d: %s: dma_rxreset[%d]: cannot stop dma\n", + wlc_hw->unit, __func__, RX_TXSTATUS_FIFO); } } /* if noreset, just stop the psm and return */ @@ -2491,7 +2506,7 @@ static void wlc_coreinit(struct wlc_info *wlc) regs = wlc_hw->regs; osh = wlc_hw->osh; - WL_TRACE(("wl%d: wlc_coreinit\n", wlc_hw->unit)); + WL_TRACE("wl%d: wlc_coreinit\n", wlc_hw->unit); /* reset PSM */ wlc_bmac_mctrl(wlc_hw, ~0, (MCTL_IHR_EN | MCTL_PSM_JMP_0 | MCTL_WAKE)); @@ -2514,8 +2529,8 @@ static void wlc_coreinit(struct wlc_info *wlc) SPINWAIT(((R_REG(osh, ®s->macintstatus) & MI_MACSSPNDD) == 0), 1000 * 1000); if ((R_REG(osh, ®s->macintstatus) & MI_MACSSPNDD) == 0) - WL_ERROR(("wl%d: wlc_coreinit: ucode did not self-suspend!\n", - wlc_hw->unit)); + WL_ERROR("wl%d: wlc_coreinit: ucode did not self-suspend!\n", + wlc_hw->unit); wlc_gpio_init(wlc); @@ -2525,18 +2540,18 @@ static void wlc_coreinit(struct wlc_info *wlc) if (WLCISNPHY(wlc_hw->band)) wlc_write_inits(wlc_hw, d11n0initvals16); else - WL_ERROR(("%s: wl%d: unsupported phy in corerev %d\n", - __func__, wlc_hw->unit, wlc_hw->corerev)); + WL_ERROR("%s: wl%d: unsupported phy in corerev %d\n", + __func__, wlc_hw->unit, wlc_hw->corerev); } else if (D11REV_IS(wlc_hw->corerev, 24)) { if (WLCISLCNPHY(wlc_hw->band)) { wlc_write_inits(wlc_hw, d11lcn0initvals24); } else { - WL_ERROR(("%s: wl%d: unsupported phy in corerev %d\n", - __func__, wlc_hw->unit, wlc_hw->corerev)); + WL_ERROR("%s: wl%d: unsupported phy in corerev %d\n", + __func__, wlc_hw->unit, wlc_hw->corerev); } } else { - WL_ERROR(("%s: wl%d: unsupported corerev %d\n", - __func__, wlc_hw->unit, wlc_hw->corerev)); + WL_ERROR("%s: wl%d: unsupported corerev %d\n", + __func__, wlc_hw->unit, wlc_hw->corerev); } /* For old ucode, txfifo sizes needs to be modified(increased) for Corerev >= 9 */ @@ -2578,7 +2593,8 @@ static void wlc_coreinit(struct wlc_info *wlc) err = -1; } if (err != 0) { - WL_ERROR(("wlc_coreinit: txfifo mismatch: ucode size %d driver size %d index %d\n", buf[i], wlc_hw->xmtfifo_sz[i], i)); + WL_ERROR("wlc_coreinit: txfifo mismatch: ucode size %d driver size %d index %d\n", + buf[i], wlc_hw->xmtfifo_sz[i], i); /* DO NOT ASSERT corerev < 4 even there is a mismatch * shmem, since driver don't overwrite those chip and * ucode initialize data will be used. @@ -2797,16 +2813,16 @@ static void wlc_ucode_download(struct wlc_hw_info *wlc_hw) bcm43xx_16_mimosz); wlc_hw->ucode_loaded = true; } else - WL_ERROR(("%s: wl%d: unsupported phy in corerev %d\n", - __func__, wlc_hw->unit, wlc_hw->corerev)); + WL_ERROR("%s: wl%d: unsupported phy in corerev %d\n", + __func__, wlc_hw->unit, wlc_hw->corerev); } else if (D11REV_IS(wlc_hw->corerev, 24)) { if (WLCISLCNPHY(wlc_hw->band)) { wlc_ucode_write(wlc_hw, bcm43xx_24_lcn, bcm43xx_24_lcnsz); wlc_hw->ucode_loaded = true; } else { - WL_ERROR(("%s: wl%d: unsupported phy in corerev %d\n", - __func__, wlc_hw->unit, wlc_hw->corerev)); + WL_ERROR("%s: wl%d: unsupported phy in corerev %d\n", + __func__, wlc_hw->unit, wlc_hw->corerev); } } } @@ -2820,7 +2836,7 @@ static void wlc_ucode_write(struct wlc_hw_info *wlc_hw, const u32 ucode[], osh = wlc_hw->osh; - WL_TRACE(("wl%d: wlc_ucode_write\n", wlc_hw->unit)); + WL_TRACE("wl%d: wlc_ucode_write\n", wlc_hw->unit); ASSERT(IS_ALIGNED(nbytes, sizeof(u32))); @@ -2838,7 +2854,7 @@ static void wlc_write_inits(struct wlc_hw_info *wlc_hw, const d11init_t *inits) struct osl_info *osh; volatile u8 *base; - WL_TRACE(("wl%d: wlc_write_inits\n", wlc_hw->unit)); + WL_TRACE("wl%d: wlc_write_inits\n", wlc_hw->unit); osh = wlc_hw->osh; base = (volatile u8 *)wlc_hw->regs; @@ -2914,44 +2930,45 @@ void wlc_bmac_fifoerrors(struct wlc_hw_info *wlc_hw) if (!intstatus) continue; - WL_TRACE(("wl%d: wlc_bmac_fifoerrors: intstatus%d 0x%x\n", unit, - idx, intstatus)); + WL_TRACE("wl%d: wlc_bmac_fifoerrors: intstatus%d 0x%x\n", + unit, idx, intstatus); if (intstatus & I_RO) { - WL_ERROR(("wl%d: fifo %d: receive fifo overflow\n", - unit, idx)); + WL_ERROR("wl%d: fifo %d: receive fifo overflow\n", + unit, idx); WLCNTINCR(wlc_hw->wlc->pub->_cnt->rxoflo); fatal = true; } if (intstatus & I_PC) { - WL_ERROR(("wl%d: fifo %d: descriptor error\n", unit, - idx)); + WL_ERROR("wl%d: fifo %d: descriptor error\n", + unit, idx); WLCNTINCR(wlc_hw->wlc->pub->_cnt->dmade); fatal = true; } if (intstatus & I_PD) { - WL_ERROR(("wl%d: fifo %d: data error\n", unit, idx)); + WL_ERROR("wl%d: fifo %d: data error\n", unit, idx); WLCNTINCR(wlc_hw->wlc->pub->_cnt->dmada); fatal = true; } if (intstatus & I_DE) { - WL_ERROR(("wl%d: fifo %d: descriptor protocol error\n", - unit, idx)); + WL_ERROR("wl%d: fifo %d: descriptor protocol error\n", + unit, idx); WLCNTINCR(wlc_hw->wlc->pub->_cnt->dmape); fatal = true; } if (intstatus & I_RU) { - WL_ERROR(("wl%d: fifo %d: receive descriptor underflow\n", unit, idx)); + WL_ERROR("wl%d: fifo %d: receive descriptor underflow\n", + idx, unit); WLCNTINCR(wlc_hw->wlc->pub->_cnt->rxuflo[idx]); } if (intstatus & I_XU) { - WL_ERROR(("wl%d: fifo %d: transmit fifo underflow\n", - idx, unit)); + WL_ERROR("wl%d: fifo %d: transmit fifo underflow\n", + idx, unit); WLCNTINCR(wlc_hw->wlc->pub->_cnt->txuflo); fatal = true; } @@ -3185,7 +3202,7 @@ static inline u32 wlc_intstatus(struct wlc_info *wlc, bool in_isr) /* macintstatus includes a DMA interrupt summary bit */ macintstatus = R_REG(osh, ®s->macintstatus); - WL_TRACE(("wl%d: macintstatus: 0x%x\n", wlc_hw->unit, macintstatus)); + WL_TRACE("wl%d: macintstatus: 0x%x\n", wlc_hw->unit, macintstatus); /* detect cardbus removed, in power down(suspend) and in reset */ if (DEVICEREMOVED(wlc)) @@ -3225,7 +3242,9 @@ static inline u32 wlc_intstatus(struct wlc_info *wlc, bool in_isr) R_REG(osh, ®s->intctrlregs[RX_TXSTATUS_FIFO]. intstatus); - WL_TRACE(("wl%d: intstatus_rxfifo 0x%x, intstatus_txsfifo 0x%x\n", wlc_hw->unit, intstatus_rxfifo, intstatus_txsfifo)); + WL_TRACE("wl%d: intstatus_rxfifo 0x%x, intstatus_txsfifo 0x%x\n", + wlc_hw->unit, + intstatus_rxfifo, intstatus_txsfifo); /* defer unsolicited interrupt hints */ intstatus_rxfifo &= DEF_RXINTMASK; @@ -3301,7 +3320,7 @@ bool BCMFASTPATH wlc_isr(struct wlc_info *wlc, bool *wantdpc) macintstatus = wlc_intstatus(wlc, true); if (macintstatus == 0xffffffff) - WL_ERROR(("DEVICEREMOVED detected in the ISR code path.\n")); + WL_ERROR("DEVICEREMOVED detected in the ISR code path\n"); /* it is not for us */ if (macintstatus == 0) @@ -3325,7 +3344,7 @@ static bool wlc_bmac_txstatus_corerev4(struct wlc_hw_info *wlc_hw) struct osl_info *osh; bool fatal = false; - WL_TRACE(("wl%d: wlc_txstatusrecv\n", wlc_hw->unit)); + WL_TRACE("wl%d: wlc_txstatusrecv\n", wlc_hw->unit); osh = wlc_hw->osh; @@ -3378,7 +3397,7 @@ wlc_bmac_txstatus(struct wlc_hw_info *wlc_hw, bool bound, bool *fatal) bool morepending = false; struct wlc_info *wlc = wlc_hw->wlc; - WL_TRACE(("wl%d: wlc_bmac_txstatus\n", wlc_hw->unit)); + WL_TRACE("wl%d: wlc_bmac_txstatus\n", wlc_hw->unit); if (D11REV_IS(wlc_hw->corerev, 4)) { /* to retire soon */ @@ -3403,8 +3422,8 @@ wlc_bmac_txstatus(struct wlc_hw_info *wlc_hw, bool bound, bool *fatal) && (s1 = R_REG(osh, ®s->frmtxstatus)) & TXS_V) { if (s1 == 0xffffffff) { - WL_ERROR(("wl%d: %s: dead chip\n", - wlc_hw->unit, __func__)); + WL_ERROR("wl%d: %s: dead chip\n", + wlc_hw->unit, __func__); ASSERT(s1 != 0xffffffff); return morepending; } @@ -3444,8 +3463,8 @@ void wlc_suspend_mac_and_wait(struct wlc_info *wlc) u32 mc, mi; struct osl_info *osh; - WL_TRACE(("wl%d: wlc_suspend_mac_and_wait: bandunit %d\n", wlc_hw->unit, - wlc_hw->band->bandunit)); + WL_TRACE("wl%d: wlc_suspend_mac_and_wait: bandunit %d\n", + wlc_hw->unit, wlc_hw->band->bandunit); /* * Track overlapping suspend requests @@ -3462,7 +3481,7 @@ void wlc_suspend_mac_and_wait(struct wlc_info *wlc) mc = R_REG(osh, ®s->maccontrol); if (mc == 0xffffffff) { - WL_ERROR(("wl%d: %s: dead chip\n", wlc_hw->unit, __func__)); + WL_ERROR("wl%d: %s: dead chip\n", wlc_hw->unit, __func__); wl_down(wlc->wl); return; } @@ -3472,7 +3491,7 @@ void wlc_suspend_mac_and_wait(struct wlc_info *wlc) mi = R_REG(osh, ®s->macintstatus); if (mi == 0xffffffff) { - WL_ERROR(("wl%d: %s: dead chip\n", wlc_hw->unit, __func__)); + WL_ERROR("wl%d: %s: dead chip\n", wlc_hw->unit, __func__); wl_down(wlc->wl); return; } @@ -3484,15 +3503,18 @@ void wlc_suspend_mac_and_wait(struct wlc_info *wlc) WLC_MAX_MAC_SUSPEND); if (!(R_REG(osh, ®s->macintstatus) & MI_MACSSPNDD)) { - WL_ERROR(("wl%d: wlc_suspend_mac_and_wait: waited %d uS and " - "MI_MACSSPNDD is still not on.\n", - wlc_hw->unit, WLC_MAX_MAC_SUSPEND)); - WL_ERROR(("wl%d: psmdebug 0x%08x, phydebug 0x%08x, psm_brc 0x%04x\n", wlc_hw->unit, R_REG(osh, ®s->psmdebug), R_REG(osh, ®s->phydebug), R_REG(osh, ®s->psm_brc))); + WL_ERROR("wl%d: wlc_suspend_mac_and_wait: waited %d uS and MI_MACSSPNDD is still not on.\n", + wlc_hw->unit, WLC_MAX_MAC_SUSPEND); + WL_ERROR("wl%d: psmdebug 0x%08x, phydebug 0x%08x, psm_brc 0x%04x\n", + wlc_hw->unit, + R_REG(osh, ®s->psmdebug), + R_REG(osh, ®s->phydebug), + R_REG(osh, ®s->psm_brc)); } mc = R_REG(osh, ®s->maccontrol); if (mc == 0xffffffff) { - WL_ERROR(("wl%d: %s: dead chip\n", wlc_hw->unit, __func__)); + WL_ERROR("wl%d: %s: dead chip\n", wlc_hw->unit, __func__); wl_down(wlc->wl); return; } @@ -3508,8 +3530,8 @@ void wlc_enable_mac(struct wlc_info *wlc) u32 mc, mi; struct osl_info *osh; - WL_TRACE(("wl%d: wlc_enable_mac: bandunit %d\n", wlc_hw->unit, - wlc->band->bandunit)); + WL_TRACE("wl%d: wlc_enable_mac: bandunit %d\n", + wlc_hw->unit, wlc->band->bandunit); /* * Track overlapping suspend requests @@ -3671,7 +3693,7 @@ bool wlc_bmac_validate_chip_access(struct wlc_hw_info *wlc_hw) volatile u16 *reg16; struct osl_info *osh; - WL_TRACE(("wl%d: validate_chip_access\n", wlc_hw->unit)); + WL_TRACE("wl%d: validate_chip_access\n", wlc_hw->unit); regs = wlc_hw->regs; osh = wlc_hw->osh; @@ -3691,7 +3713,8 @@ bool wlc_bmac_validate_chip_access(struct wlc_hw_info *wlc_hw) (void)R_REG(osh, ®s->objaddr); val = R_REG(osh, ®s->objdata); if (val != (u32) 0xaa5555aa) { - WL_ERROR(("wl%d: validate_chip_access: SHM = 0x%x, expected 0xaa5555aa\n", wlc_hw->unit, val)); + WL_ERROR("wl%d: validate_chip_access: SHM = 0x%x, expected 0xaa5555aa\n", + wlc_hw->unit, val); return false; } @@ -3703,7 +3726,8 @@ bool wlc_bmac_validate_chip_access(struct wlc_hw_info *wlc_hw) (void)R_REG(osh, ®s->objaddr); val = R_REG(osh, ®s->objdata); if (val != (u32) 0x55aaaa55) { - WL_ERROR(("wl%d: validate_chip_access: SHM = 0x%x, expected 0x55aaaa55\n", wlc_hw->unit, val)); + WL_ERROR("wl%d: validate_chip_access: SHM = 0x%x, expected 0x55aaaa55\n", + wlc_hw->unit, val); return false; } @@ -3733,12 +3757,14 @@ bool wlc_bmac_validate_chip_access(struct wlc_hw_info *wlc_hw) /* verify with the 16 bit registers that have no side effects */ val = R_REG(osh, ®s->tsf_cfpstrt_l); if (val != (uint) 0xBBBB) { - WL_ERROR(("wl%d: validate_chip_access: tsf_cfpstrt_l = 0x%x, expected" " 0x%x\n", wlc_hw->unit, val, 0xBBBB)); + WL_ERROR("wl%d: validate_chip_access: tsf_cfpstrt_l = 0x%x, expected 0x%x\n", + wlc_hw->unit, val, 0xBBBB); return false; } val = R_REG(osh, ®s->tsf_cfpstrt_h); if (val != (uint) 0xCCCC) { - WL_ERROR(("wl%d: validate_chip_access: tsf_cfpstrt_h = 0x%x, expected" " 0x%x\n", wlc_hw->unit, val, 0xCCCC)); + WL_ERROR("wl%d: validate_chip_access: tsf_cfpstrt_h = 0x%x, expected 0x%x\n", + wlc_hw->unit, val, 0xCCCC); return false; } @@ -3750,7 +3776,10 @@ bool wlc_bmac_validate_chip_access(struct wlc_hw_info *wlc_hw) w = R_REG(osh, ®s->maccontrol); if ((w != (MCTL_IHR_EN | MCTL_WAKE)) && (w != (MCTL_IHR_EN | MCTL_GMODE | MCTL_WAKE))) { - WL_ERROR(("wl%d: validate_chip_access: maccontrol = 0x%x, expected 0x%x or 0x%x\n", wlc_hw->unit, w, (MCTL_IHR_EN | MCTL_WAKE), (MCTL_IHR_EN | MCTL_GMODE | MCTL_WAKE))); + WL_ERROR("wl%d: validate_chip_access: maccontrol = 0x%x, expected 0x%x or 0x%x\n", + wlc_hw->unit, w, + (MCTL_IHR_EN | MCTL_WAKE), + (MCTL_IHR_EN | MCTL_GMODE | MCTL_WAKE)); return false; } @@ -3765,7 +3794,7 @@ void wlc_bmac_core_phypll_ctl(struct wlc_hw_info *wlc_hw, bool on) struct osl_info *osh; u32 tmp; - WL_TRACE(("wl%d: wlc_bmac_core_phypll_ctl\n", wlc_hw->unit)); + WL_TRACE("wl%d: wlc_bmac_core_phypll_ctl\n", wlc_hw->unit); tmp = 0; regs = wlc_hw->regs; @@ -3786,8 +3815,8 @@ void wlc_bmac_core_phypll_ctl(struct wlc_hw_info *wlc_hw, bool on) tmp = R_REG(osh, ®s->clk_ctl_st); if ((tmp & (CCS_ERSRC_AVAIL_HT)) != (CCS_ERSRC_AVAIL_HT)) { - WL_ERROR(("%s: turn on PHY PLL failed\n", - __func__)); + WL_ERROR("%s: turn on PHY PLL failed\n", + __func__); ASSERT(0); } } else { @@ -3804,8 +3833,8 @@ void wlc_bmac_core_phypll_ctl(struct wlc_hw_info *wlc_hw, bool on) (CCS_ERSRC_AVAIL_D11PLL | CCS_ERSRC_AVAIL_PHYPLL)) != (CCS_ERSRC_AVAIL_D11PLL | CCS_ERSRC_AVAIL_PHYPLL)) { - WL_ERROR(("%s: turn on PHY PLL failed\n", - __func__)); + WL_ERROR("%s: turn on PHY PLL failed\n", + __func__); ASSERT(0); } } @@ -3822,7 +3851,7 @@ void wlc_coredisable(struct wlc_hw_info *wlc_hw) { bool dev_gone; - WL_TRACE(("wl%d: %s\n", wlc_hw->unit, __func__)); + WL_TRACE("wl%d: %s\n", wlc_hw->unit, __func__); ASSERT(!wlc_hw->up); @@ -3860,7 +3889,7 @@ void wlc_coredisable(struct wlc_hw_info *wlc_hw) /* power both the pll and external oscillator on/off */ void wlc_bmac_xtal(struct wlc_hw_info *wlc_hw, bool want) { - WL_TRACE(("wl%d: wlc_bmac_xtal: want %d\n", wlc_hw->unit, want)); + WL_TRACE("wl%d: wlc_bmac_xtal: want %d\n", wlc_hw->unit, want); /* dont power down if plldown is false or we must poll hw radio disable */ if (!want && wlc_hw->pllreq) @@ -3889,8 +3918,8 @@ static void wlc_flushqueues(struct wlc_info *wlc) if (wlc_hw->di[i]) { dma_txreclaim(wlc_hw->di[i], HNDDMA_RANGE_ALL); TXPKTPENDCLR(wlc, i); - WL_TRACE(("wlc_flushqueues: pktpend fifo %d cleared\n", - i)); + WL_TRACE("wlc_flushqueues: pktpend fifo %d cleared\n", + i); } /* free any posted rx packets */ @@ -4023,8 +4052,8 @@ wlc_bmac_copyfrom_objmem(struct wlc_hw_info *wlc_hw, uint offset, void *buf, void wlc_bmac_copyfrom_vars(struct wlc_hw_info *wlc_hw, char **buf, uint *len) { - WL_TRACE(("wlc_bmac_copyfrom_vars, nvram vars totlen=%d\n", - wlc_hw->vars_size)); + WL_TRACE("wlc_bmac_copyfrom_vars, nvram vars totlen=%d\n", + wlc_hw->vars_size); *buf = wlc_hw->vars; *len = wlc_hw->vars_size; @@ -4133,7 +4162,7 @@ void wlc_gpio_fast_deinit(struct wlc_hw_info *wlc_hw) (wlc_hw->sih->buscorerev >= 13))))) return; - WL_TRACE(("wl%d: %s\n", wlc_hw->unit, __func__)); + WL_TRACE("wl%d: %s\n", wlc_hw->unit, __func__); return; } diff --git a/drivers/staging/brcm80211/sys/wlc_channel.c b/drivers/staging/brcm80211/sys/wlc_channel.c index 33041e36585c..a35c15214880 100644 --- a/drivers/staging/brcm80211/sys/wlc_channel.c +++ b/drivers/staging/brcm80211/sys/wlc_channel.c @@ -567,8 +567,8 @@ struct chan20_info chan20_info[] = { const locale_info_t *wlc_get_locale_2g(u8 locale_idx) { if (locale_idx >= ARRAY_SIZE(g_locale_2g_table)) { - WL_ERROR(("%s: locale 2g index size out of range %d\n", - __func__, locale_idx)); + WL_ERROR("%s: locale 2g index size out of range %d\n", + __func__, locale_idx); ASSERT(locale_idx < ARRAY_SIZE(g_locale_2g_table)); return NULL; } @@ -578,8 +578,8 @@ const locale_info_t *wlc_get_locale_2g(u8 locale_idx) const locale_info_t *wlc_get_locale_5g(u8 locale_idx) { if (locale_idx >= ARRAY_SIZE(g_locale_5g_table)) { - WL_ERROR(("%s: locale 5g index size out of range %d\n", - __func__, locale_idx)); + WL_ERROR("%s: locale 5g index size out of range %d\n", + __func__, locale_idx); ASSERT(locale_idx < ARRAY_SIZE(g_locale_5g_table)); return NULL; } @@ -589,8 +589,8 @@ const locale_info_t *wlc_get_locale_5g(u8 locale_idx) const locale_mimo_info_t *wlc_get_mimo_2g(u8 locale_idx) { if (locale_idx >= ARRAY_SIZE(g_mimo_2g_table)) { - WL_ERROR(("%s: mimo 2g index size out of range %d\n", __func__, - locale_idx)); + WL_ERROR("%s: mimo 2g index size out of range %d\n", + __func__, locale_idx); return NULL; } return g_mimo_2g_table[locale_idx]; @@ -599,8 +599,8 @@ const locale_mimo_info_t *wlc_get_mimo_2g(u8 locale_idx) const locale_mimo_info_t *wlc_get_mimo_5g(u8 locale_idx) { if (locale_idx >= ARRAY_SIZE(g_mimo_5g_table)) { - WL_ERROR(("%s: mimo 5g index size out of range %d\n", __func__, - locale_idx)); + WL_ERROR("%s: mimo 5g index size out of range %d\n", + __func__, locale_idx); return NULL; } return g_mimo_5g_table[locale_idx]; @@ -614,11 +614,11 @@ wlc_cm_info_t *wlc_channel_mgr_attach(struct wlc_info *wlc) struct wlc_pub *pub = wlc->pub; char *ccode; - WL_TRACE(("wl%d: wlc_channel_mgr_attach\n", wlc->pub->unit)); + WL_TRACE("wl%d: wlc_channel_mgr_attach\n", wlc->pub->unit); wlc_cm = kzalloc(sizeof(wlc_cm_info_t), GFP_ATOMIC); if (wlc_cm == NULL) { - WL_ERROR(("wl%d: %s: out of memory", pub->unit, __func__)); + WL_ERROR("wl%d: %s: out of memory", pub->unit, __func__); return NULL; } wlc_cm->pub = pub; @@ -629,8 +629,9 @@ wlc_cm_info_t *wlc_channel_mgr_attach(struct wlc_info *wlc) ccode = getvar(wlc->pub->vars, "ccode"); if (ccode) { strncpy(wlc->pub->srom_ccode, ccode, WLC_CNTRY_BUF_SZ - 1); - WL_NONE(("%s: SROM country code is %c%c\n", __func__, - wlc->pub->srom_ccode[0], wlc->pub->srom_ccode[1])); + WL_NONE("%s: SROM country code is %c%c\n", + __func__, + wlc->pub->srom_ccode[0], wlc->pub->srom_ccode[1]); } /* internal country information which must match regulatory constraints in firmware */ @@ -716,7 +717,9 @@ wlc_set_countrycode_rev(wlc_cm_info_t *wlc_cm, char mapped_ccode[WLC_CNTRY_BUF_SZ]; uint mapped_regrev; - WL_NONE(("%s: (country_abbrev \"%s\", ccode \"%s\", regrev %d) SPROM \"%s\"/%u\n", __func__, country_abbrev, ccode, regrev, wlc_cm->srom_ccode, wlc_cm->srom_regrev)); + WL_NONE("%s: (country_abbrev \"%s\", ccode \"%s\", regrev %d) SPROM \"%s\"/%u\n", + __func__, country_abbrev, ccode, regrev, + wlc_cm->srom_ccode, wlc_cm->srom_regrev); /* if regrev is -1, lookup the mapped country code, * otherwise use the ccode and regrev directly @@ -827,8 +830,8 @@ static const country_info_t *wlc_countrycode_map(wlc_cm_info_t *wlc_cm, /* check for currently supported ccode size */ if (strlen(ccode) > (WLC_CNTRY_BUF_SZ - 1)) { - WL_ERROR(("wl%d: %s: ccode \"%s\" too long for match\n", - wlc->pub->unit, __func__, ccode)); + WL_ERROR("wl%d: %s: ccode \"%s\" too long for match\n", + wlc->pub->unit, __func__, ccode); return NULL; } @@ -843,7 +846,7 @@ static const country_info_t *wlc_countrycode_map(wlc_cm_info_t *wlc_cm, if (!strcmp(srom_ccode, ccode)) { *mapped_regrev = srom_regrev; mapped = 0; - WL_ERROR(("srom_code == ccode %s\n", __func__)); + WL_ERROR("srom_code == ccode %s\n", __func__); ASSERT(0); } else { mapped = @@ -895,7 +898,7 @@ static const country_info_t *wlc_country_lookup_direct(const char *ccode, } } - WL_ERROR(("%s: Returning NULL\n", __func__)); + WL_ERROR("%s: Returning NULL\n", __func__); ASSERT(0); return NULL; } @@ -974,7 +977,9 @@ static void wlc_channels_commit(wlc_cm_info_t *wlc_cm) if (chan == INVCHANNEL) { /* country/locale with no valid channels, set the radio disable bit */ mboolset(wlc->pub->radio_disabled, WL_RADIO_COUNTRY_DISABLE); - WL_ERROR(("wl%d: %s: no valid channel for \"%s\" nbands %d bandlocked %d\n", wlc->pub->unit, __func__, wlc_cm->country_abbrev, NBANDS(wlc), wlc->bandlocked)); + WL_ERROR("wl%d: %s: no valid channel for \"%s\" nbands %d bandlocked %d\n", + wlc->pub->unit, __func__, + wlc_cm->country_abbrev, NBANDS(wlc), wlc->bandlocked); } else if (mboolisset(wlc->pub->radio_disabled, WL_RADIO_COUNTRY_DISABLE)) { @@ -1538,8 +1543,8 @@ wlc_valid_chanspec_ext(wlc_cm_info_t *wlc_cm, chanspec_t chspec, bool dualband) /* check the chanspec */ if (wf_chspec_malformed(chspec)) { - WL_ERROR(("wl%d: malformed chanspec 0x%x\n", wlc->pub->unit, - chspec)); + WL_ERROR("wl%d: malformed chanspec 0x%x\n", + wlc->pub->unit, chspec); ASSERT(0); return false; } diff --git a/drivers/staging/brcm80211/sys/wlc_event.c b/drivers/staging/brcm80211/sys/wlc_event.c index 9b503d839aae..dabd7094cd73 100644 --- a/drivers/staging/brcm80211/sys/wlc_event.c +++ b/drivers/staging/brcm80211/sys/wlc_event.c @@ -75,8 +75,8 @@ wlc_eventq_t *wlc_eventq_attach(struct wlc_pub *pub, struct wlc_info *wlc, eq->timer = wl_init_timer(eq->wl, wlc_timer_cb, eq, "eventq"); if (!eq->timer) { - WL_ERROR(("wl%d: wlc_eventq_attach: timer failed\n", - pub->unit)); + WL_ERROR("wl%d: wlc_eventq_attach: timer failed\n", + pub->unit); kfree(eq); return NULL; } diff --git a/drivers/staging/brcm80211/sys/wlc_mac80211.c b/drivers/staging/brcm80211/sys/wlc_mac80211.c index 8a89b5fe8e60..1d5d01ac0a9b 100644 --- a/drivers/staging/brcm80211/sys/wlc_mac80211.c +++ b/drivers/staging/brcm80211/sys/wlc_mac80211.c @@ -306,7 +306,7 @@ void wlc_get_rcmta(struct wlc_info *wlc, int idx, struct ether_addr *addr) u32 v32; struct osl_info *osh; - WL_TRACE(("wl%d: %s\n", WLCWLUNIT(wlc), __func__)); + WL_TRACE("wl%d: %s\n", WLCWLUNIT(wlc), __func__); ASSERT(wlc->pub->corerev > 4); @@ -364,7 +364,7 @@ bool wlc_ps_allowed(struct wlc_info *wlc) void wlc_reset(struct wlc_info *wlc) { - WL_TRACE(("wl%d: wlc_reset\n", wlc->pub->unit)); + WL_TRACE("wl%d: wlc_reset\n", wlc->pub->unit); wlc->check_for_unaligned_tbtt = false; @@ -385,7 +385,7 @@ void wlc_reset(struct wlc_info *wlc) void wlc_fatal_error(struct wlc_info *wlc) { - WL_ERROR(("wl%d: fatal error, reinitializing\n", wlc->pub->unit)); + WL_ERROR("wl%d: fatal error, reinitializing\n", wlc->pub->unit); wl_init(wlc->wl); } @@ -426,7 +426,7 @@ void wlc_init(struct wlc_info *wlc) wlc_bsscfg_t *bsscfg; bool mute = false; - WL_TRACE(("wl%d: wlc_init\n", wlc->pub->unit)); + WL_TRACE("wl%d: wlc_init\n", wlc->pub->unit); regs = wlc->regs; @@ -605,8 +605,8 @@ bool wlc_ps_check(struct wlc_info *wlc) * to avoid assert */ if (tmp == 0xffffffff) { - WL_ERROR(("wl%d: %s: dead chip\n", wlc->pub->unit, - __func__)); + WL_ERROR("wl%d: %s: dead chip\n", + wlc->pub->unit, __func__); return DEVICEREMOVED(wlc); } @@ -615,7 +615,8 @@ bool wlc_ps_check(struct wlc_info *wlc) if (hps != ((tmp & MCTL_HPS) != 0)) { int idx; wlc_bsscfg_t *cfg; - WL_ERROR(("wl%d: hps not sync, sw %d, maccontrol 0x%x\n", wlc->pub->unit, hps, tmp)); + WL_ERROR("wl%d: hps not sync, sw %d, maccontrol 0x%x\n", + wlc->pub->unit, hps, tmp); FOREACH_BSS(wlc, idx, cfg) { if (!BSSCFG_STA(cfg)) continue; @@ -629,7 +630,8 @@ bool wlc_ps_check(struct wlc_info *wlc) wake = STAY_AWAKE(wlc) || wlc->hw->wake_override; wake_ok = (wake == ((tmp & MCTL_WAKE) != 0)); if (hps && !wake_ok) { - WL_ERROR(("wl%d: wake not sync, sw %d maccontrol 0x%x\n", wlc->pub->unit, wake, tmp)); + WL_ERROR("wl%d: wake not sync, sw %d maccontrol 0x%x\n", + wlc->pub->unit, wake, tmp); res = false; } } @@ -647,8 +649,8 @@ void wlc_set_ps_ctrl(struct wlc_info *wlc) hps = PS_ALLOWED(wlc); wake = hps ? (STAY_AWAKE(wlc)) : true; - WL_TRACE(("wl%d: wlc_set_ps_ctrl: hps %d wake %d\n", wlc->pub->unit, - hps, wake)); + WL_TRACE("wl%d: wlc_set_ps_ctrl: hps %d wake %d\n", + wlc->pub->unit, hps, wake); v1 = R_REG(wlc->osh, &wlc->regs->maccontrol); v2 = 0; @@ -806,8 +808,8 @@ void wlc_set_chanspec(struct wlc_info *wlc, chanspec_t chanspec) chanspec_t old_chanspec = wlc->chanspec; if (!wlc_valid_chanspec_db(wlc->cmi, chanspec)) { - WL_ERROR(("wl%d: %s: Bad channel %d\n", - wlc->pub->unit, __func__, CHSPEC_CHANNEL(chanspec))); + WL_ERROR("wl%d: %s: Bad channel %d\n", + wlc->pub->unit, __func__, CHSPEC_CHANNEL(chanspec)); ASSERT(wlc_valid_chanspec_db(wlc->cmi, chanspec)); return; } @@ -818,7 +820,9 @@ void wlc_set_chanspec(struct wlc_info *wlc, chanspec_t chanspec) if (wlc->band->bandunit != bandunit || wlc->bandinit_pending) { switchband = true; if (wlc->bandlocked) { - WL_ERROR(("wl%d: %s: chspec %d band is locked!\n", wlc->pub->unit, __func__, CHSPEC_CHANNEL(chanspec))); + WL_ERROR("wl%d: %s: chspec %d band is locked!\n", + wlc->pub->unit, __func__, + CHSPEC_CHANNEL(chanspec)); return; } /* BMAC_NOTE: should the setband call come after the wlc_bmac_chanspec() ? @@ -1120,7 +1124,7 @@ void wlc_beacon_phytxctl_txant_upd(struct wlc_info *wlc, ratespec_t bcn_rspec) */ void wlc_protection_upd(struct wlc_info *wlc, uint idx, int val) { - WL_TRACE(("wlc_protection_upd: idx %d, val %d\n", idx, val)); + WL_TRACE("wlc_protection_upd: idx %d, val %d\n", idx, val); switch (idx) { case WLC_PROT_G_SPEC: @@ -1228,7 +1232,7 @@ static void wlc_bandinit_ordered(struct wlc_info *wlc, chanspec_t chanspec) uint parkband; uint i, band_order[2]; - WL_TRACE(("wl%d: wlc_bandinit_ordered\n", wlc->pub->unit)); + WL_TRACE("wl%d: wlc_bandinit_ordered\n", wlc->pub->unit); /* * We might have been bandlocked during down and the chip power-cycled (hibernate). * figure out the right band to park on @@ -1271,8 +1275,8 @@ static void wlc_bandinit_ordered(struct wlc_info *wlc, chanspec_t chanspec) /* band-specific init */ static void WLBANDINITFN(wlc_bsinit) (struct wlc_info *wlc) { - WL_TRACE(("wl%d: wlc_bsinit: bandunit %d\n", wlc->pub->unit, - wlc->band->bandunit)); + WL_TRACE("wl%d: wlc_bsinit: bandunit %d\n", + wlc->pub->unit, wlc->band->bandunit); /* write ucode ACK/CTS rate table */ wlc_set_ratetable(wlc); @@ -1348,7 +1352,7 @@ void wlc_wme_setparams(struct wlc_info *wlc, u16 aci, void *arg, bool suspend) /* Only apply params if the core is out of reset and has clocks */ if (!wlc->clk) { - WL_ERROR(("wl%d: %s : no-clock\n", wlc->pub->unit, __func__)); + WL_ERROR("wl%d: %s : no-clock\n", wlc->pub->unit, __func__); return; } @@ -1380,8 +1384,8 @@ void wlc_wme_setparams(struct wlc_info *wlc, u16 aci, void *arg, bool suspend) if (acp_shm.aifs < EDCF_AIFSN_MIN || acp_shm.aifs > EDCF_AIFSN_MAX) { - WL_ERROR(("wl%d: wlc_edcf_setparams: bad aifs %d\n", - wlc->pub->unit, acp_shm.aifs)); + WL_ERROR("wl%d: wlc_edcf_setparams: bad aifs %d\n", + wlc->pub->unit, acp_shm.aifs); continue; } @@ -1464,8 +1468,8 @@ void wlc_edcf_setparams(wlc_bsscfg_t *cfg, bool suspend) if (acp_shm.aifs < EDCF_AIFSN_MIN || acp_shm.aifs > EDCF_AIFSN_MAX) { - WL_ERROR(("wl%d: wlc_edcf_setparams: bad aifs %d\n", - wlc->pub->unit, acp_shm.aifs)); + WL_ERROR("wl%d: wlc_edcf_setparams: bad aifs %d\n", + wlc->pub->unit, acp_shm.aifs); continue; } @@ -1512,15 +1516,14 @@ bool wlc_timers_init(struct wlc_info *wlc, int unit) wlc->wdtimer = wl_init_timer(wlc->wl, wlc_watchdog_by_timer, wlc, "watchdog"); if (!wlc->wdtimer) { - WL_ERROR(("wl%d: wl_init_timer for wdtimer failed\n", unit)); + WL_ERROR("wl%d: wl_init_timer for wdtimer failed\n", unit); goto fail; } wlc->radio_timer = wl_init_timer(wlc->wl, wlc_radio_timer, wlc, "radio"); if (!wlc->radio_timer) { - WL_ERROR(("wl%d: wl_init_timer for radio_timer failed\n", - unit)); + WL_ERROR("wl%d: wl_init_timer for radio_timer failed\n", unit); goto fail; } @@ -1667,15 +1670,14 @@ static uint wlc_attach_module(struct wlc_info *wlc) wlc->asi = wlc_antsel_attach(wlc, wlc->osh, wlc->pub, wlc->hw); if (wlc->asi == NULL) { - WL_ERROR(("wl%d: wlc_attach: wlc_antsel_attach failed\n", - unit)); + WL_ERROR("wl%d: wlc_attach: wlc_antsel_attach failed\n", unit); err = 44; goto fail; } wlc->ampdu = wlc_ampdu_attach(wlc); if (wlc->ampdu == NULL) { - WL_ERROR(("wl%d: wlc_attach: wlc_ampdu_attach failed\n", unit)); + WL_ERROR("wl%d: wlc_attach: wlc_ampdu_attach failed\n", unit); err = 50; goto fail; } @@ -1684,13 +1686,13 @@ static uint wlc_attach_module(struct wlc_info *wlc) wlc->eventq = wlc_eventq_attach(wlc->pub, wlc, wlc->wl, wlc_process_eventq); if (wlc->eventq == NULL) { - WL_ERROR(("wl%d: wlc_attach: wlc_eventq_attachfailed\n", unit)); + WL_ERROR("wl%d: wlc_attach: wlc_eventq_attachfailed\n", unit); err = 57; goto fail; } if ((wlc_stf_attach(wlc) != 0)) { - WL_ERROR(("wl%d: wlc_attach: wlc_stf_attach failed\n", unit)); + WL_ERROR("wl%d: wlc_attach: wlc_stf_attach failed\n", unit); err = 68; goto fail; } @@ -1719,8 +1721,8 @@ void *wlc_attach(void *wl, u16 vendor, u16 device, uint unit, bool piomode, wlc_txq_info_t *qi; uint n_disabled; - WL_NONE(("wl%d: %s: vendor 0x%x device 0x%x\n", unit, __func__, vendor, - device)); + WL_NONE("wl%d: %s: vendor 0x%x device 0x%x\n", + unit, __func__, vendor, device); ASSERT(WSEC_MAX_RCMTA_KEYS <= WSEC_MAX_KEYS); ASSERT(WSEC_MAX_DEFAULT_KEYS == WLC_DEFAULT_KEYS); @@ -1897,7 +1899,7 @@ void *wlc_attach(void *wl, u16 vendor, u16 device, uint unit, bool piomode, goto fail; if (!wlc_timers_init(wlc, unit)) { - WL_ERROR(("wl%d: %s: wlc_init_timer failed\n", unit, __func__)); + WL_ERROR("wl%d: %s: wlc_init_timer failed\n", unit, __func__); err = 32; goto fail; } @@ -1905,8 +1907,8 @@ void *wlc_attach(void *wl, u16 vendor, u16 device, uint unit, bool piomode, /* depend on rateset, gmode */ wlc->cmi = wlc_channel_mgr_attach(wlc); if (!wlc->cmi) { - WL_ERROR(("wl%d: %s: wlc_channel_mgr_attach failed\n", unit, - __func__)); + WL_ERROR("wl%d: %s: wlc_channel_mgr_attach failed\n", + unit, __func__); err = 33; goto fail; } @@ -1921,8 +1923,8 @@ void *wlc_attach(void *wl, u16 vendor, u16 device, uint unit, bool piomode, /* allocate our initial queue */ qi = wlc_txq_alloc(wlc, osh); if (qi == NULL) { - WL_ERROR(("wl%d: %s: failed to malloc tx queue\n", unit, - __func__)); + WL_ERROR("wl%d: %s: failed to malloc tx queue\n", + unit, __func__); err = 100; goto fail; } @@ -2008,7 +2010,7 @@ void *wlc_attach(void *wl, u16 vendor, u16 device, uint unit, bool piomode, return (void *)wlc; fail: - WL_ERROR(("wl%d: %s: failed with err %d\n", unit, __func__, err)); + WL_ERROR("wl%d: %s: failed with err %d\n", unit, __func__, err); if (wlc) wlc_detach(wlc); @@ -2026,7 +2028,8 @@ static void wlc_attach_antgain_init(struct wlc_info *wlc) /* default antenna gain for srom rev 1 is 2 dBm (8 qdbm) */ wlc->band->antgain = 8; } else if (wlc->band->antgain == -1) { - WL_ERROR(("wl%d: %s: Invalid antennas available in srom, using 2dB\n", unit, __func__)); + WL_ERROR("wl%d: %s: Invalid antennas available in srom, using 2dB\n", + unit, __func__); wlc->band->antgain = 8; } else { s8 gain, fract; @@ -2065,7 +2068,8 @@ static bool wlc_attach_stf_ant_init(struct wlc_info *wlc) aa = (s8) getintvar(vars, (BAND_5G(bandtype) ? "aa1" : "aa0")); if ((aa < 1) || (aa > 15)) { - WL_ERROR(("wl%d: %s: Invalid antennas available in srom (0x%x), using 3.\n", unit, __func__, aa)); + WL_ERROR("wl%d: %s: Invalid antennas available in srom (0x%x), using 3\n", + unit, __func__, aa); aa = 3; } @@ -2132,7 +2136,7 @@ uint wlc_detach(struct wlc_info *wlc) if (wlc == NULL) return 0; - WL_TRACE(("wl%d: %s\n", wlc->pub->unit, __func__)); + WL_TRACE("wl%d: %s\n", wlc->pub->unit, __func__); ASSERT(!wlc->pub->up); @@ -2340,7 +2344,7 @@ static void wlc_radio_timer(void *arg) struct wlc_info *wlc = (struct wlc_info *) arg; if (DEVICEREMOVED(wlc)) { - WL_ERROR(("wl%d: %s: dead chip\n", wlc->pub->unit, __func__)); + WL_ERROR("wl%d: %s: dead chip\n", wlc->pub->unit, __func__); wl_down(wlc->wl); return; } @@ -2441,13 +2445,13 @@ static void wlc_watchdog(void *arg) int i; wlc_bsscfg_t *cfg; - WL_TRACE(("wl%d: wlc_watchdog\n", wlc->pub->unit)); + WL_TRACE("wl%d: wlc_watchdog\n", wlc->pub->unit); if (!wlc->pub->up) return; if (DEVICEREMOVED(wlc)) { - WL_ERROR(("wl%d: %s: dead chip\n", wlc->pub->unit, __func__)); + WL_ERROR("wl%d: %s: dead chip\n", wlc->pub->unit, __func__); wl_down(wlc->wl); return; } @@ -2519,7 +2523,7 @@ static void wlc_watchdog(void *arg) /* make interface operational */ int wlc_up(struct wlc_info *wlc) { - WL_TRACE(("wl%d: %s:\n", wlc->pub->unit, __func__)); + WL_TRACE("wl%d: %s:\n", wlc->pub->unit, __func__); /* HW is turned off so don't try to access it */ if (wlc->pub->hw_off || DEVICEREMOVED(wlc)) @@ -2564,7 +2568,8 @@ int wlc_up(struct wlc_info *wlc) if (!BSSCFG_STA(bsscfg) || !bsscfg->enable || !bsscfg->BSS) continue; - WL_ERROR(("wl%d.%d: wlc_up: rfdisable -> " "wlc_bsscfg_disable()\n", wlc->pub->unit, idx)); + WL_ERROR("wl%d.%d: wlc_up: rfdisable -> " "wlc_bsscfg_disable()\n", + wlc->pub->unit, idx); } } } else @@ -2664,12 +2669,12 @@ uint wlc_down(struct wlc_info *wlc) bool dev_gone = false; wlc_txq_info_t *qi; - WL_TRACE(("wl%d: %s:\n", wlc->pub->unit, __func__)); + WL_TRACE("wl%d: %s:\n", wlc->pub->unit, __func__); /* check if we are already in the going down path */ if (wlc->going_down) { - WL_ERROR(("wl%d: %s: Driver going down so return\n", - wlc->pub->unit, __func__)); + WL_ERROR("wl%d: %s: Driver going down so return\n", + wlc->pub->unit, __func__); return 0; } if (!wlc->pub->up) @@ -2728,8 +2733,8 @@ uint wlc_down(struct wlc_info *wlc) /* Verify all packets are flushed from the driver */ if (wlc->osh->pktalloced != 0) { - WL_ERROR(("%d packets not freed at wlc_down!!!!!!\n", - wlc->osh->pktalloced)); + WL_ERROR("%d packets not freed at wlc_down!!!!!!\n", + wlc->osh->pktalloced); } #ifdef BCMDBG /* Since all the packets should have been freed, @@ -2826,8 +2831,8 @@ int wlc_set_gmode(struct wlc_info *wlc, u8 gmode, bool config) default: /* Error */ - WL_ERROR(("wl%d: %s: invalid gmode %d\n", wlc->pub->unit, - __func__, gmode)); + WL_ERROR("wl%d: %s: invalid gmode %d\n", + wlc->pub->unit, __func__, gmode); return BCME_UNSUPPORTED; } @@ -3082,7 +3087,7 @@ _wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, /* If the device is turned off, then it's not "removed" */ if (!wlc->pub->hw_off && DEVICEREMOVED(wlc)) { - WL_ERROR(("wl%d: %s: dead chip\n", wlc->pub->unit, __func__)); + WL_ERROR("wl%d: %s: dead chip\n", wlc->pub->unit, __func__); wl_down(wlc->wl); return BCME_ERROR; } @@ -3102,8 +3107,8 @@ _wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, bool_val = val != 0; if (cmd != WLC_SET_CHANNEL) - WL_NONE(("WLC_IOCTL: cmd %d val 0x%x (%d) len %d\n", cmd, - (uint) val, val, len)); + WL_NONE("WLC_IOCTL: cmd %d val 0x%x (%d) len %d\n", + cmd, (uint)val, val, len); bcmerror = 0; regs = wlc->regs; @@ -3123,8 +3128,8 @@ _wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, default: if ((arg == NULL) || (len <= 0)) { - WL_ERROR(("wl%d: %s: Command %d needs arguments\n", - wlc->pub->unit, __func__, cmd)); + WL_ERROR("wl%d: %s: Command %d needs arguments\n", + wlc->pub->unit, __func__, cmd); bcmerror = BCME_BADARG; goto done; } @@ -3457,8 +3462,8 @@ _wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, /* 4322 supports antdiv in phy, no need to set it to ucode */ if (WLCISNPHY(wlc->band) && D11REV_IS(wlc->pub->corerev, 16)) { - WL_ERROR(("wl%d: can't set ucantdiv for 4322\n", - wlc->pub->unit)); + WL_ERROR("wl%d: can't set ucantdiv for 4322\n", + wlc->pub->unit); bcmerror = BCME_UNSUPPORTED; } else wlc_mhf(wlc, MHF1, MHF1_ANTDIV, @@ -3555,8 +3560,8 @@ _wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, if ((radiomask == 0) || (radiomask & ~validbits) || (radioval & ~validbits) || ((radioval & ~radiomask) != 0)) { - WL_ERROR(("SET_RADIO with wrong bits 0x%x\n", - val)); + WL_ERROR("SET_RADIO with wrong bits 0x%x\n", + val); bcmerror = BCME_RANGE; break; } @@ -4192,7 +4197,7 @@ _wlc_ioctl(struct wlc_info *wlc, int cmd, void *arg, int len, #endif case WLC_LAST: - WL_ERROR(("%s: WLC_LAST\n", __func__)); + WL_ERROR("%s: WLC_LAST\n", __func__); } done: @@ -4402,8 +4407,8 @@ wlc_iovar_op(struct wlc_info *wlc, const char *name, if (!set && (len == sizeof(int)) && !(IS_ALIGNED((unsigned long)(arg), (uint) sizeof(int)))) { - WL_ERROR(("wl%d: %s unaligned get ptr for %s\n", - wlc->pub->unit, __func__, name)); + WL_ERROR("wl%d: %s unaligned get ptr for %s\n", + wlc->pub->unit, __func__, name); ASSERT(0); } @@ -4530,7 +4535,7 @@ wlc_doiovar(void *hdl, const bcm_iovar_t *vi, u32 actionid, bool bool_val2; wlc_bss_info_t *current_bss; - WL_TRACE(("wl%d: %s\n", wlc->pub->unit, __func__)); + WL_TRACE("wl%d: %s\n", wlc->pub->unit, __func__); bsscfg = NULL; current_bss = NULL; @@ -4553,8 +4558,8 @@ wlc_doiovar(void *hdl, const bcm_iovar_t *vi, u32 actionid, bool_val = (int_val != 0) ? true : false; bool_val2 = (int_val2 != 0) ? true : false; - WL_TRACE(("wl%d: %s: id %d\n", wlc->pub->unit, __func__, - IOV_ID(actionid))); + WL_TRACE("wl%d: %s: id %d\n", + wlc->pub->unit, __func__, IOV_ID(actionid)); /* Do the actual parameter implementation */ switch (actionid) { @@ -4612,7 +4617,7 @@ wlc_doiovar(void *hdl, const bcm_iovar_t *vi, u32 actionid, break; default: - WL_ERROR(("wl%d: %s: unsupported\n", wlc->pub->unit, __func__)); + WL_ERROR("wl%d: %s: unsupported\n", wlc->pub->unit, __func__); err = BCME_UNSUPPORTED; break; } @@ -4747,8 +4752,8 @@ void wlc_statsupd(struct wlc_info *wlc) /* check for rx fifo 0 overflow */ delta = (u16) (wlc->core->macstat_snapshot->rxf0ovfl - rxf0ovfl); if (delta) - WL_ERROR(("wl%d: %u rx fifo 0 overflows!\n", wlc->pub->unit, - delta)); + WL_ERROR("wl%d: %u rx fifo 0 overflows!\n", + wlc->pub->unit, delta); /* check for tx fifo underflows */ for (i = 0; i < NFIFO; i++) { @@ -4756,8 +4761,8 @@ void wlc_statsupd(struct wlc_info *wlc) (u16) (wlc->core->macstat_snapshot->txfunfl[i] - txfunfl[i]); if (delta) - WL_ERROR(("wl%d: %u tx fifo %d underflows!\n", - wlc->pub->unit, delta, i)); + WL_ERROR("wl%d: %u tx fifo %d underflows!\n", + wlc->pub->unit, delta, i); } #endif /* BCMDBG */ @@ -4806,7 +4811,7 @@ void wlc_statsupd(struct wlc_info *wlc) bool wlc_chipmatch(u16 vendor, u16 device) { if (vendor != VENDOR_BROADCOM) { - WL_ERROR(("wlc_chipmatch: unknown vendor id %04x\n", vendor)); + WL_ERROR("wlc_chipmatch: unknown vendor id %04x\n", vendor); return false; } @@ -4818,7 +4823,7 @@ bool wlc_chipmatch(u16 vendor, u16 device) if ((device == BCM43236_D11N_ID) || (device == BCM43236_D11N2G_ID)) return true; - WL_ERROR(("wlc_chipmatch: unknown device id %04x\n", device)); + WL_ERROR("wlc_chipmatch: unknown device id %04x\n", device); return false; } @@ -5009,8 +5014,8 @@ wlc_prec_enq_head(struct wlc_info *wlc, struct pktq *q, struct sk_buff *pkt, p = pktq_peek_tail(q, &eprec); ASSERT(p != NULL); if (eprec > prec) { - WL_ERROR(("%s: Failing: eprec %d > prec %d\n", __func__, - eprec, prec)); + WL_ERROR("%s: Failing: eprec %d > prec %d\n", + __func__, eprec, prec); return false; } } @@ -5026,8 +5031,8 @@ wlc_prec_enq_head(struct wlc_info *wlc, struct pktq *q, struct sk_buff *pkt, /* Refuse newer packet unless configured to discard oldest */ if (eprec == prec && !discard_oldest) { - WL_ERROR(("%s: No where to go, prec == %d\n", __func__, - prec)); + WL_ERROR("%s: No where to go, prec == %d\n", + __func__, prec); return false; } @@ -5075,8 +5080,8 @@ void BCMFASTPATH wlc_txq_enq(void *ctx, struct scb *scb, struct sk_buff *sdu, if (!wlc_prec_enq(wlc, q, sdu, prec)) { if (!EDCF_ENAB(wlc->pub) || (wlc->pub->wlfeatureflag & WL_SWFL_FLOWCONTROL)) - WL_ERROR(("wl%d: wlc_txq_enq: txq overflow\n", - wlc->pub->unit)); + WL_ERROR("wl%d: wlc_txq_enq: txq overflow\n", + wlc->pub->unit); /* ASSERT(9 == 8); *//* XXX we might hit this condtion in case packet flooding from mac80211 stack */ pkt_buf_free_skb(wlc->osh, sdu, true); @@ -5252,8 +5257,8 @@ wlc_txfifo(struct wlc_info *wlc, uint fifo, struct sk_buff *p, bool commit, */ if (commit) { TXPKTPENDINC(wlc, fifo, txpktpend); - WL_TRACE(("wlc_txfifo, pktpend inc %d to %d\n", txpktpend, - TXPKTPENDGET(wlc, fifo))); + WL_TRACE("wlc_txfifo, pktpend inc %d to %d\n", + txpktpend, TXPKTPENDGET(wlc, fifo)); } /* Commit BCMC sequence number in the SHM frame ID location */ @@ -5261,7 +5266,7 @@ wlc_txfifo(struct wlc_info *wlc, uint fifo, struct sk_buff *p, bool commit, BCMCFID(wlc, frameid); if (dma_txfast(wlc->hw->di[fifo], p, commit) < 0) { - WL_ERROR(("wlc_txfifo: fatal, toss frames !!!\n")); + WL_ERROR("wlc_txfifo: fatal, toss frames !!!\n"); } } @@ -5301,7 +5306,8 @@ wlc_compute_airtime(struct wlc_info *wlc, ratespec_t rspec, uint length) usec = (length << 3) / 11; break; default: - WL_ERROR(("wl%d: wlc_compute_airtime: unsupported rspec 0x%x\n", wlc->pub->unit, rspec)); + WL_ERROR("wl%d: wlc_compute_airtime: unsupported rspec 0x%x\n", + wlc->pub->unit, rspec); ASSERT((const char *)"Bad phy_rate" == NULL); break; } @@ -5397,7 +5403,7 @@ static void wlc_cck_plcp_set(int rate_500, uint length, u8 *plcp) break; default: - WL_ERROR(("wlc_cck_plcp_set: unsupported rate %d\n", rate_500)); + WL_ERROR("wlc_cck_plcp_set: unsupported rate %d\n", rate_500); rate_500 = WLC_RATE_1M; usec = length << 3; break; @@ -5537,7 +5543,8 @@ u16 BCMFASTPATH wlc_phytxctl1_calc(struct wlc_info *wlc, ratespec_t rspec) bw = RSPEC_GET_BW(rspec); /* 10Mhz is not supported yet */ if (bw < PHY_TXC1_BW_20MHZ) { - WL_ERROR(("wlc_phytxctl1_calc: bw %d is not supported yet, set to 20L\n", bw)); + WL_ERROR("wlc_phytxctl1_calc: bw %d is not supported yet, set to 20L\n", + bw); bw = PHY_TXC1_BW_20MHZ; } @@ -5562,7 +5569,7 @@ u16 BCMFASTPATH wlc_phytxctl1_calc(struct wlc_info *wlc, ratespec_t rspec) /* get the phyctl byte from rate phycfg table */ phycfg = wlc_rate_legacy_phyctl(RSPEC2RATE(rspec)); if (phycfg == -1) { - WL_ERROR(("wlc_phytxctl1_calc: wrong legacy OFDM/CCK rate\n")); + WL_ERROR("wlc_phytxctl1_calc: wrong legacy OFDM/CCK rate\n"); ASSERT(0); phycfg = 0; } @@ -5722,8 +5729,8 @@ wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, /* non-AP STA should never use BCMC queue */ ASSERT(queue != TX_BCMC_FIFO); if (queue == TX_BCMC_FIFO) { - WL_ERROR(("wl%d: %s: ASSERT queue == TX_BCMC!\n", - WLCWLUNIT(wlc), __func__)); + WL_ERROR("wl%d: %s: ASSERT queue == TX_BCMC!\n", + WLCWLUNIT(wlc), __func__); frameid = bcmc_fid_generate(wlc, NULL, txh); } else { /* Increment the counter for first fragment */ @@ -5901,7 +5908,8 @@ wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, if ((txrate[k]->flags & IEEE80211_TX_RC_MCS) && (!IS_MCS(rspec[k]))) { - WL_ERROR(("wl%d: %s: IEEE80211_TX_RC_MCS != IS_MCS(rspec)\n", WLCWLUNIT(wlc), __func__)); + WL_ERROR("wl%d: %s: IEEE80211_TX_RC_MCS != IS_MCS(rspec)\n", + WLCWLUNIT(wlc), __func__); ASSERT(0 && "Rate mismatch"); } @@ -6295,12 +6303,16 @@ wlc_d11hdrs_mac80211(struct wlc_info *wlc, struct ieee80211_hw *hw, } } } else - WL_ERROR(("wl%d: %s txop invalid for rate %d\n", - wlc->pub->unit, fifo_names[queue], - RSPEC2RATE(rspec[0]))); + WL_ERROR("wl%d: %s txop invalid for rate %d\n", + wlc->pub->unit, fifo_names[queue], + RSPEC2RATE(rspec[0])); if (dur > wlc->edcf_txop[ac]) - WL_ERROR(("wl%d: %s: %s txop exceeded phylen %d/%d dur %d/%d\n", wlc->pub->unit, __func__, fifo_names[queue], phylen, wlc->fragthresh[queue], dur, wlc->edcf_txop[ac])); + WL_ERROR("wl%d: %s: %s txop exceeded phylen %d/%d dur %d/%d\n", + wlc->pub->unit, __func__, + fifo_names[queue], + phylen, wlc->fragthresh[queue], + dur, wlc->edcf_txop[ac]); } } @@ -6406,8 +6418,8 @@ void wlc_high_dpc(struct wlc_info *wlc, u32 macintstatus) if (macintstatus & ~(MI_TBTT | MI_TXSTOP)) { bcm_format_flags(int_flags, macintstatus, flagstr, sizeof(flagstr)); - WL_TRACE(("wl%d: macintstatus 0x%x %s\n", wlc->pub->unit, - macintstatus, flagstr)); + WL_TRACE("wl%d: macintstatus 0x%x %s\n", + wlc->pub->unit, macintstatus, flagstr); } #endif /* BCMDBG */ @@ -6422,7 +6434,8 @@ void wlc_high_dpc(struct wlc_info *wlc, u32 macintstatus) wlc_tbtt(wlc, regs); if (macintstatus & MI_GP0) { - WL_ERROR(("wl%d: PSM microcode watchdog fired at %d (seconds). Resetting.\n", wlc->pub->unit, wlc->pub->now)); + WL_ERROR("wl%d: PSM microcode watchdog fired at %d (seconds). Resetting.\n", + wlc->pub->unit, wlc->pub->now); printk_once("%s : PSM Watchdog, chipid 0x%x, chiprev 0x%x\n", __func__, wlc->pub->sih->chip, @@ -6440,7 +6453,9 @@ void wlc_high_dpc(struct wlc_info *wlc, u32 macintstatus) } if (macintstatus & MI_RFDISABLE) { - WL_ERROR(("wl%d: MAC Detected a change on the RF Disable Input 0x%x\n", wlc->pub->unit, R_REG(wlc->osh, ®s->phydebug) & PDBG_RFD)); + WL_ERROR("wl%d: MAC Detected a change on the RF Disable Input 0x%x\n", + wlc->pub->unit, + R_REG(wlc->osh, ®s->phydebug) & PDBG_RFD); /* delay the cleanup to wl_down in IBSS case */ if ((R_REG(wlc->osh, ®s->phydebug) & PDBG_RFD)) { int idx; @@ -6449,7 +6464,8 @@ void wlc_high_dpc(struct wlc_info *wlc, u32 macintstatus) if (!BSSCFG_STA(bsscfg) || !bsscfg->enable || !bsscfg->BSS) continue; - WL_ERROR(("wl%d: wlc_dpc: rfdisable -> wlc_bsscfg_disable()\n", wlc->pub->unit)); + WL_ERROR("wl%d: wlc_dpc: rfdisable -> wlc_bsscfg_disable()\n", + wlc->pub->unit); } } } @@ -6485,7 +6501,8 @@ static void *wlc_15420war(struct wlc_info *wlc, uint queue) if (dma_txactive(wlc->hw->di[queue]) == 0) { WLCNTINCR(wlc->pub->_cnt->txdmawar); if (!dma_txreset(di)) - WL_ERROR(("wl%d: %s: dma_txreset[%d]: cannot stop dma\n", wlc->pub->unit, __func__, queue)); + WL_ERROR("wl%d: %s: dma_txreset[%d]: cannot stop dma\n", + wlc->pub->unit, __func__, queue); dma_txinit(di); } return p; @@ -6538,7 +6555,7 @@ wlc_dotxstatus(struct wlc_info *wlc, tx_status_t *txs, u32 frm_tx2) ((txs-> status & TX_STATUS_FRM_RTX_MASK) >> TX_STATUS_FRM_RTX_SHIFT)); - WL_ERROR(("%s: INTERMEDIATE but not AMPDU\n", __func__)); + WL_ERROR("%s: INTERMEDIATE but not AMPDU\n", __func__); return false; } @@ -6563,8 +6580,8 @@ wlc_dotxstatus(struct wlc_info *wlc, tx_status_t *txs, u32 frm_tx2) mcl = ltoh16(txh->MacTxControlLow); if (txs->phyerr) { - WL_ERROR(("phyerr 0x%x, rate 0x%x\n", txs->phyerr, - txh->MainRates)); + WL_ERROR("phyerr 0x%x, rate 0x%x\n", + txs->phyerr, txh->MainRates); wlc_print_txdesc(txh); wlc_print_txstatus(txs); } @@ -6595,8 +6612,8 @@ wlc_dotxstatus(struct wlc_info *wlc, tx_status_t *txs, u32 frm_tx2) supr_status = txs->status & TX_STATUS_SUPR_MASK; if (supr_status == TX_STATUS_SUPR_BADCH) - WL_NONE(("%s: Pkt tx suppressed, possibly channel %d\n", - __func__, CHSPEC_CHANNEL(wlc->default_bss->chanspec))); + WL_NONE("%s: Pkt tx suppressed, possibly channel %d\n", + __func__, CHSPEC_CHANNEL(wlc->default_bss->chanspec)); tx_rts = htol16(txh->MacTxControlLow) & TXC_SENDRTS; tx_frame_count = @@ -6607,7 +6624,7 @@ wlc_dotxstatus(struct wlc_info *wlc, tx_status_t *txs, u32 frm_tx2) lastframe = (fc & FC_MOREFRAG) == 0; if (!lastframe) { - WL_ERROR(("Not last frame!\n")); + WL_ERROR("Not last frame!\n"); } else { u16 sfbl, lfbl; ieee80211_tx_info_clear_status(tx_info); @@ -6658,8 +6675,8 @@ wlc_dotxstatus(struct wlc_info *wlc, tx_status_t *txs, u32 frm_tx2) ieee80211_tx_status_irqsafe(wlc->pub->ieee_hw, p); WLCNTINCR(wlc->pub->_cnt->ieee_tx_status); } else { - WL_ERROR(("%s: Not last frame => not calling tx_status\n", - __func__)); + WL_ERROR("%s: Not last frame => not calling tx_status\n", + __func__); } return false; @@ -6677,8 +6694,8 @@ void BCMFASTPATH wlc_txfifo_complete(struct wlc_info *wlc, uint fifo, s8 txpktpend) { TXPKTPENDDEC(wlc, fifo, txpktpend); - WL_TRACE(("wlc_txfifo_complete, pktpend dec %d to %d\n", txpktpend, - TXPKTPENDGET(wlc, fifo))); + WL_TRACE("wlc_txfifo_complete, pktpend dec %d to %d\n", + txpktpend, TXPKTPENDGET(wlc, fifo)); /* There is more room; mark precedences related to this FIFO sendable */ WLC_TX_FIFO_ENAB(wlc, fifo); @@ -6872,19 +6889,19 @@ prep_mac80211_status(struct wlc_info *wlc, d11rxhdr_t *rxh, struct sk_buff *p, rx_status->rate_idx = 11; break; default: - WL_ERROR(("%s: Unknown rate\n", __func__)); + WL_ERROR("%s: Unknown rate\n", __func__); } /* Determine short preamble and rate_idx */ preamble = 0; if (IS_CCK(rspec)) { if (rxh->PhyRxStatus_0 & PRXS0_SHORTH) - WL_ERROR(("Short CCK\n")); + WL_ERROR("Short CCK\n"); rx_status->flag |= RX_FLAG_SHORTPRE; } else if (IS_OFDM(rspec)) { rx_status->flag |= RX_FLAG_SHORTPRE; } else { - WL_ERROR(("%s: Unknown modulation\n", __func__)); + WL_ERROR("%s: Unknown modulation\n", __func__); } } @@ -6893,11 +6910,11 @@ prep_mac80211_status(struct wlc_info *wlc, d11rxhdr_t *rxh, struct sk_buff *p, if (rxh->RxStatus1 & RXS_DECERR) { rx_status->flag |= RX_FLAG_FAILED_PLCP_CRC; - WL_ERROR(("%s: RX_FLAG_FAILED_PLCP_CRC\n", __func__)); + WL_ERROR("%s: RX_FLAG_FAILED_PLCP_CRC\n", __func__); } if (rxh->RxStatus1 & RXS_FCSERR) { rx_status->flag |= RX_FLAG_FAILED_FCS_CRC; - WL_ERROR(("%s: RX_FLAG_FAILED_FCS_CRC\n", __func__)); + WL_ERROR("%s: RX_FLAG_FAILED_FCS_CRC\n", __func__); } } @@ -6943,7 +6960,7 @@ void wlc_bss_list_free(struct wlc_info *wlc, wlc_bss_list_t *bss_list) wlc_bss_info_t *bi; if (!bss_list) { - WL_ERROR(("%s: Attempting to free NULL list\n", __func__)); + WL_ERROR("%s: Attempting to free NULL list\n", __func__); return; } /* inspect all BSS descriptor */ @@ -6975,7 +6992,7 @@ void BCMFASTPATH wlc_recv(struct wlc_info *wlc, struct sk_buff *p) uint len; bool is_amsdu; - WL_TRACE(("wl%d: wlc_recv\n", wlc->pub->unit)); + WL_TRACE("wl%d: wlc_recv\n", wlc->pub->unit); osh = wlc->osh; @@ -6992,8 +7009,8 @@ void BCMFASTPATH wlc_recv(struct wlc_info *wlc, struct sk_buff *p) if (rxh->RxStatus1 & RXS_PBPRES) { if (p->len < 2) { WLCNTINCR(wlc->pub->_cnt->rxrunt); - WL_ERROR(("wl%d: wlc_recv: rcvd runt of len %d\n", - wlc->pub->unit, p->len)); + WL_ERROR("wl%d: wlc_recv: rcvd runt of len %d\n", + wlc->pub->unit, p->len); goto toss; } skb_pull(p, 2); @@ -7004,10 +7021,10 @@ void BCMFASTPATH wlc_recv(struct wlc_info *wlc, struct sk_buff *p) if (rxh->RxStatus1 & RXS_FCSERR) { if (wlc->pub->mac80211_state & MAC80211_PROMISC_BCNS) { - WL_ERROR(("FCSERR while scanning******* - tossing\n")); + WL_ERROR("FCSERR while scanning******* - tossing\n"); goto toss; } else { - WL_ERROR(("RCSERR!!!\n")); + WL_ERROR("RCSERR!!!\n"); goto toss; } } @@ -7028,9 +7045,8 @@ void BCMFASTPATH wlc_recv(struct wlc_info *wlc, struct sk_buff *p) if (FC_TYPE(fc) == FC_TYPE_DATA || FC_TYPE(fc) == FC_TYPE_MNG) { if ((is_zero_ether_addr(h->a2.octet) || is_multicast_ether_addr(h->a2.octet))) { - WL_ERROR(("wl%d: %s: dropping a frame with " - "invalid src mac address, a2: %pM\n", - wlc->pub->unit, __func__, &h->a2)); + WL_ERROR("wl%d: %s: dropping a frame with invalid src mac address, a2: %pM\n", + wlc->pub->unit, __func__, &h->a2); WLCNTINCR(wlc->pub->_cnt->rxbadsrcmac); goto toss; } @@ -7045,7 +7061,7 @@ void BCMFASTPATH wlc_recv(struct wlc_info *wlc, struct sk_buff *p) } if (is_amsdu) { - WL_ERROR(("%s: is_amsdu causing toss\n", __func__)); + WL_ERROR("%s: is_amsdu causing toss\n", __func__); goto toss; } @@ -7067,8 +7083,8 @@ wlc_calc_lsig_len(struct wlc_info *wlc, ratespec_t ratespec, uint mac_len) { uint nsyms, len = 0, kNdps; - WL_TRACE(("wl%d: wlc_calc_lsig_len: rate %d, len%d\n", wlc->pub->unit, - RSPEC2RATE(ratespec), mac_len)); + WL_TRACE("wl%d: wlc_calc_lsig_len: rate %d, len%d\n", + wlc->pub->unit, RSPEC2RATE(ratespec), mac_len); if (IS_MCS(ratespec)) { uint mcs = ratespec & RSPEC_RATE_MASK; @@ -7112,11 +7128,12 @@ wlc_calc_frame_time(struct wlc_info *wlc, ratespec_t ratespec, u8 preamble_type, if (rate == 0) { ASSERT(0); - WL_ERROR(("wl%d: WAR: using rate of 1 mbps\n", wlc->pub->unit)); + WL_ERROR("wl%d: WAR: using rate of 1 mbps\n", wlc->pub->unit); rate = WLC_RATE_1M; } - WL_TRACE(("wl%d: wlc_calc_frame_time: rspec 0x%x, preamble_type %d, len%d\n", wlc->pub->unit, ratespec, preamble_type, mac_len)); + WL_TRACE("wl%d: wlc_calc_frame_time: rspec 0x%x, preamble_type %d, len%d\n", + wlc->pub->unit, ratespec, preamble_type, mac_len); if (IS_MCS(ratespec)) { uint mcs = ratespec & RSPEC_RATE_MASK; @@ -7180,7 +7197,8 @@ wlc_calc_frame_len(struct wlc_info *wlc, ratespec_t ratespec, u8 preamble_type, uint nsyms, mac_len, Ndps, kNdps; uint rate = RSPEC2RATE(ratespec); - WL_TRACE(("wl%d: wlc_calc_frame_len: rspec 0x%x, preamble_type %d, dur %d\n", wlc->pub->unit, ratespec, preamble_type, dur)); + WL_TRACE("wl%d: wlc_calc_frame_len: rspec 0x%x, preamble_type %d, dur %d\n", + wlc->pub->unit, ratespec, preamble_type, dur); if (IS_MCS(ratespec)) { uint mcs = ratespec & RSPEC_RATE_MASK; @@ -7222,8 +7240,8 @@ wlc_calc_frame_len(struct wlc_info *wlc, ratespec_t ratespec, u8 preamble_type, static uint wlc_calc_ba_time(struct wlc_info *wlc, ratespec_t rspec, u8 preamble_type) { - WL_TRACE(("wl%d: wlc_calc_ba_time: rspec 0x%x, preamble_type %d\n", - wlc->pub->unit, rspec, preamble_type)); + WL_TRACE("wl%d: wlc_calc_ba_time: rspec 0x%x, preamble_type %d\n", + wlc->pub->unit, rspec, preamble_type); /* Spec 9.6: ack rate is the highest rate in BSSBasicRateSet that is less than * or equal to the rate of the immediately previous frame in the FES */ @@ -7241,8 +7259,8 @@ wlc_calc_ack_time(struct wlc_info *wlc, ratespec_t rspec, u8 preamble_type) { uint dur = 0; - WL_TRACE(("wl%d: wlc_calc_ack_time: rspec 0x%x, preamble_type %d\n", - wlc->pub->unit, rspec, preamble_type)); + WL_TRACE("wl%d: wlc_calc_ack_time: rspec 0x%x, preamble_type %d\n", + wlc->pub->unit, rspec, preamble_type); /* Spec 9.6: ack rate is the highest rate in BSSBasicRateSet that is less than * or equal to the rate of the immediately previous frame in the FES */ @@ -7259,8 +7277,8 @@ wlc_calc_ack_time(struct wlc_info *wlc, ratespec_t rspec, u8 preamble_type) static uint wlc_calc_cts_time(struct wlc_info *wlc, ratespec_t rspec, u8 preamble_type) { - WL_TRACE(("wl%d: wlc_calc_cts_time: ratespec 0x%x, preamble_type %d\n", - wlc->pub->unit, rspec, preamble_type)); + WL_TRACE("wl%d: wlc_calc_cts_time: ratespec 0x%x, preamble_type %d\n", + wlc->pub->unit, rspec, preamble_type); return wlc_calc_ack_time(wlc, rspec, preamble_type); } @@ -7289,7 +7307,8 @@ void wlc_rate_lookup_init(struct wlc_info *wlc, wlc_rateset_t *rateset) rate = (rateset->rates[i] & RATE_MASK); if (rate > WLC_MAXRATE) { - WL_ERROR(("wlc_rate_lookup_init: invalid rate 0x%X in rate set\n", rateset->rates[i])); + WL_ERROR("wlc_rate_lookup_init: invalid rate 0x%X in rate set\n", + rateset->rates[i]); continue; } @@ -7468,7 +7487,8 @@ bool wlc_valid_rate(struct wlc_info *wlc, ratespec_t rspec, int band, return true; error: if (verbose) { - WL_ERROR(("wl%d: wlc_valid_rate: rate spec 0x%x not in hw_rateset\n", wlc->pub->unit, rspec)); + WL_ERROR("wl%d: wlc_valid_rate: rate spec 0x%x not in hw_rateset\n", + wlc->pub->unit, rspec); } return false; @@ -7550,8 +7570,8 @@ wlc_compute_bcntsfoff(struct wlc_info *wlc, ratespec_t rspec, uint bcntsfoff = 0; if (IS_MCS(rspec)) { - WL_ERROR(("wl%d: recd beacon with mcs rate; rspec 0x%x\n", - wlc->pub->unit, rspec)); + WL_ERROR("wl%d: recd beacon with mcs rate; rspec 0x%x\n", + wlc->pub->unit, rspec); } else if (IS_OFDM(rspec)) { /* tx delay from MAC through phy to air (2.1 usec) + * phy header time (preamble + PLCP SIGNAL == 20 usec) + @@ -7979,8 +7999,8 @@ mac80211_wlc_set_nrate(struct wlc_info *wlc, struct wlcband *cur_band, if (N_ENAB(wlc->pub) && ismcs) { /* mcs only allowed when nmode */ if (stf > PHY_TXC1_MODE_SDM) { - WL_ERROR(("wl%d: %s: Invalid stf\n", WLCWLUNIT(wlc), - __func__)); + WL_ERROR("wl%d: %s: Invalid stf\n", + WLCWLUNIT(wlc), __func__); bcmerror = BCME_RANGE; goto done; } @@ -7990,8 +8010,8 @@ mac80211_wlc_set_nrate(struct wlc_info *wlc, struct wlcband *cur_band, if (!CHSPEC_IS40(wlc->home_chanspec) || ((stf != PHY_TXC1_MODE_SISO) && (stf != PHY_TXC1_MODE_CDD))) { - WL_ERROR(("wl%d: %s: Invalid mcs 32\n", - WLCWLUNIT(wlc), __func__)); + WL_ERROR("wl%d: %s: Invalid mcs 32\n", + WLCWLUNIT(wlc), __func__); bcmerror = BCME_RANGE; goto done; } @@ -7999,7 +8019,8 @@ mac80211_wlc_set_nrate(struct wlc_info *wlc, struct wlcband *cur_band, } else if (rate > HIGHEST_SINGLE_STREAM_MCS) { /* mcs > 7 must use stf SDM */ if (stf != PHY_TXC1_MODE_SDM) { - WL_TRACE(("wl%d: %s: enabling SDM mode for mcs %d\n", WLCWLUNIT(wlc), __func__, rate)); + WL_TRACE("wl%d: %s: enabling SDM mode for mcs %d\n", + WLCWLUNIT(wlc), __func__, rate); stf = PHY_TXC1_MODE_SDM; } } else { @@ -8007,37 +8028,37 @@ mac80211_wlc_set_nrate(struct wlc_info *wlc, struct wlcband *cur_band, if ((stf > PHY_TXC1_MODE_STBC) || (!WLC_STBC_CAP_PHY(wlc) && (stf == PHY_TXC1_MODE_STBC))) { - WL_ERROR(("wl%d: %s: Invalid STBC\n", - WLCWLUNIT(wlc), __func__)); + WL_ERROR("wl%d: %s: Invalid STBC\n", + WLCWLUNIT(wlc), __func__); bcmerror = BCME_RANGE; goto done; } } } else if (IS_OFDM(rate)) { if ((stf != PHY_TXC1_MODE_CDD) && (stf != PHY_TXC1_MODE_SISO)) { - WL_ERROR(("wl%d: %s: Invalid OFDM\n", WLCWLUNIT(wlc), - __func__)); + WL_ERROR("wl%d: %s: Invalid OFDM\n", + WLCWLUNIT(wlc), __func__); bcmerror = BCME_RANGE; goto done; } } else if (IS_CCK(rate)) { if ((cur_band->bandtype != WLC_BAND_2G) || (stf != PHY_TXC1_MODE_SISO)) { - WL_ERROR(("wl%d: %s: Invalid CCK\n", WLCWLUNIT(wlc), - __func__)); + WL_ERROR("wl%d: %s: Invalid CCK\n", + WLCWLUNIT(wlc), __func__); bcmerror = BCME_RANGE; goto done; } } else { - WL_ERROR(("wl%d: %s: Unknown rate type\n", WLCWLUNIT(wlc), - __func__)); + WL_ERROR("wl%d: %s: Unknown rate type\n", + WLCWLUNIT(wlc), __func__); bcmerror = BCME_RANGE; goto done; } /* make sure multiple antennae are available for non-siso rates */ if ((stf != PHY_TXC1_MODE_SISO) && (wlc->stf->txstreams == 1)) { - WL_ERROR(("wl%d: %s: SISO antenna but !SISO request\n", - WLCWLUNIT(wlc), __func__)); + WL_ERROR("wl%d: %s: SISO antenna but !SISO request\n", + WLCWLUNIT(wlc), __func__); bcmerror = BCME_RANGE; goto done; } @@ -8068,7 +8089,7 @@ mac80211_wlc_set_nrate(struct wlc_info *wlc, struct wlcband *cur_band, return rspec; done: - WL_ERROR(("Hoark\n")); + WL_ERROR("Hoark\n"); return rate; } @@ -8082,8 +8103,7 @@ wlc_duty_cycle_set(struct wlc_info *wlc, int duty_cycle, bool isOFDM, isOFDM ? M_TX_IDLE_BUSY_RATIO_X_16_OFDM : M_TX_IDLE_BUSY_RATIO_X_16_CCK; if (duty_cycle > 100 || duty_cycle < 0) { - WL_ERROR(("wl%d: duty cycle value off limit\n", - wlc->pub->unit)); + WL_ERROR("wl%d: duty cycle value off limit\n", wlc->pub->unit); return BCME_RANGE; } if (duty_cycle) @@ -8282,7 +8302,7 @@ void wlc_txflowcontrol(struct wlc_info *wlc, wlc_txq_info_t *qi, uint prio_bits; uint cur_bits; - WL_ERROR(("%s: flow contro kicks in\n", __func__)); + WL_ERROR("%s: flow control kicks in\n", __func__); if (prio == ALLPRIO) { prio_bits = TXQ_STOP_FOR_PRIOFC_MASK; diff --git a/drivers/staging/brcm80211/sys/wlc_phy_shim.c b/drivers/staging/brcm80211/sys/wlc_phy_shim.c index 5dcaa7d70045..8bd4ede4c92a 100644 --- a/drivers/staging/brcm80211/sys/wlc_phy_shim.c +++ b/drivers/staging/brcm80211/sys/wlc_phy_shim.c @@ -70,7 +70,8 @@ wlc_phy_shim_info_t *wlc_phy_shim_attach(struct wlc_hw_info *wlc_hw, physhim = kzalloc(sizeof(wlc_phy_shim_info_t), GFP_ATOMIC); if (!physhim) { - WL_ERROR(("wl%d: wlc_phy_shim_attach: out of mem\n", wlc_hw->unit)); + WL_ERROR("wl%d: wlc_phy_shim_attach: out of mem\n", + wlc_hw->unit); return NULL; } physhim->wlc_hw = wlc_hw; diff --git a/drivers/staging/brcm80211/sys/wlc_stf.c b/drivers/staging/brcm80211/sys/wlc_stf.c index 01ac0d2b3cdb..8975b09a7438 100644 --- a/drivers/staging/brcm80211/sys/wlc_stf.c +++ b/drivers/staging/brcm80211/sys/wlc_stf.c @@ -196,8 +196,8 @@ bool wlc_stf_stbc_rx_set(struct wlc_info *wlc, s32 int_val) static int wlc_stf_txcore_set(struct wlc_info *wlc, u8 Nsts, u8 core_mask) { - WL_TRACE(("wl%d: %s: Nsts %d core_mask %x\n", - wlc->pub->unit, __func__, Nsts, core_mask)); + WL_TRACE("wl%d: %s: Nsts %d core_mask %x\n", + wlc->pub->unit, __func__, Nsts, core_mask); ASSERT((Nsts > 0) && (Nsts <= MAX_STREAMS_SUPPORTED)); @@ -236,7 +236,7 @@ static int wlc_stf_spatial_policy_set(struct wlc_info *wlc, int val) int i; u8 core_mask = 0; - WL_TRACE(("wl%d: %s: val %x\n", wlc->pub->unit, __func__, val)); + WL_TRACE("wl%d: %s: val %x\n", wlc->pub->unit, __func__, val); wlc->stf->spatial_policy = (s8) val; for (i = 1; i <= MAX_STREAMS_SUPPORTED; i++) { @@ -278,13 +278,15 @@ int wlc_stf_txchain_set(struct wlc_info *wlc, s32 int_val, bool force) if (RSPEC_STF(wlc->bandstate[i]->rspec_override) != PHY_TXC1_MODE_SISO) { wlc->bandstate[i]->rspec_override = 0; - WL_ERROR(("%s(): temp sense override non-SISO" " rspec_override.\n", __func__)); + WL_ERROR("%s(): temp sense override non-SISO rspec_override\n", + __func__); } if (RSPEC_STF (wlc->bandstate[i]->mrspec_override) != PHY_TXC1_MODE_SISO) { wlc->bandstate[i]->mrspec_override = 0; - WL_ERROR(("%s(): temp sense override non-SISO" " mrspec_override.\n", __func__)); + WL_ERROR("%s(): temp sense override non-SISO mrspec_override\n", + __func__); } } } -- cgit v1.2.3 From bf6506f60c46c8a709df534408cc6d470df657ff Mon Sep 17 00:00:00 2001 From: Timo Teräs Date: Wed, 15 Dec 2010 20:48:08 +0200 Subject: staging: hv: convert vmbus_on_msg_dpc to not call osd_schedule_callback MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The additional abstraction is unneeded. This also fixes a sleeping while atomic issue as osd_schedule_callback can sleep which is not allowed for vmbus_on_msg_dpc running in a tasklet. Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=16701 Reviewed-By: Hank Janssen Cc: Haiyang Zhang Signed-off-by: Timo Teräs Cc: stable Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/channel_mgmt.c | 4 ---- drivers/staging/hv/vmbus_drv.c | 28 +++++++++++++++++++++------- 2 files changed, 21 insertions(+), 11 deletions(-) diff --git a/drivers/staging/hv/channel_mgmt.c b/drivers/staging/hv/channel_mgmt.c index 0f4d6093f674..6f393e7d8e25 100644 --- a/drivers/staging/hv/channel_mgmt.c +++ b/drivers/staging/hv/channel_mgmt.c @@ -753,7 +753,6 @@ void vmbus_onmessage(void *context) hdr->msgtype, size); print_hex_dump_bytes("", DUMP_PREFIX_NONE, (unsigned char *)msg->u.payload, size); - kfree(msg); return; } @@ -762,9 +761,6 @@ void vmbus_onmessage(void *context) else DPRINT_ERR(VMBUS, "Unhandled channel message type %d", hdr->msgtype); - - /* Free the msg that was allocated in VmbusOnMsgDPC() */ - kfree(msg); } /* diff --git a/drivers/staging/hv/vmbus_drv.c b/drivers/staging/hv/vmbus_drv.c index d794b603bf17..84fdb64d3ceb 100644 --- a/drivers/staging/hv/vmbus_drv.c +++ b/drivers/staging/hv/vmbus_drv.c @@ -203,6 +203,21 @@ static void VmbusOnCleanup(struct hv_driver *drv) hv_cleanup(); } +struct onmessage_work_context { + struct work_struct work; + struct hv_message msg; +}; + +static void vmbus_onmessage_work(struct work_struct *work) +{ + struct onmessage_work_context *ctx; + + ctx = container_of(work, struct onmessage_work_context, + work); + vmbus_onmessage(&ctx->msg); + kfree(ctx); +} + /* * vmbus_on_msg_dpc - DPC routine to handle messages from the hypervisior */ @@ -212,20 +227,19 @@ static void vmbus_on_msg_dpc(struct hv_driver *drv) void *page_addr = hv_context.synic_message_page[cpu]; struct hv_message *msg = (struct hv_message *)page_addr + VMBUS_MESSAGE_SINT; - struct hv_message *copied; + struct onmessage_work_context *ctx; while (1) { if (msg->header.message_type == HVMSG_NONE) { /* no msg */ break; } else { - copied = kmemdup(msg, sizeof(*copied), GFP_ATOMIC); - if (copied == NULL) + ctx = kmalloc(sizeof(*ctx), GFP_ATOMIC); + if (ctx == NULL) continue; - - osd_schedule_callback(gVmbusConnection.WorkQueue, - vmbus_onmessage, - (void *)copied); + INIT_WORK(&ctx->work, vmbus_onmessage_work); + memcpy(&ctx->msg, msg, sizeof(*msg)); + queue_work(gVmbusConnection.WorkQueue, &ctx->work); } msg->header.message_type = HVMSG_NONE; -- cgit v1.2.3 From 4b2f9abea52af3782d349080fca5e189b0693792 Mon Sep 17 00:00:00 2001 From: Timo Teräs Date: Wed, 15 Dec 2010 20:48:09 +0200 Subject: staging: hv: convert channel_mgmt.c to not call osd_schedule_callback MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The additional abstraction is unneeded. The three calls are assumed to not be pending simultaneously: - vmbus_onoffer queues work exactly once when a new channel is created, the channel is not attached to lists until the work is executed - vmbus_onoffer_rescind is received only when the channel is active it is enough to process the work once - free_channel is called exactly once when the channel is getting destroyed; I assumed that vmbus_process_rescind_offer cannot be pending while free_channel is called Reviewed-By: Hank Janssen Cc: Haiyang Zhang Signed-off-by: Timo Teräs Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/channel_mgmt.c | 52 ++++++++++++++++++++++----------------- drivers/staging/hv/channel_mgmt.h | 1 + 2 files changed, 31 insertions(+), 22 deletions(-) diff --git a/drivers/staging/hv/channel_mgmt.c b/drivers/staging/hv/channel_mgmt.c index 6f393e7d8e25..d44d5c39f68b 100644 --- a/drivers/staging/hv/channel_mgmt.c +++ b/drivers/staging/hv/channel_mgmt.c @@ -263,9 +263,11 @@ static struct vmbus_channel *alloc_channel(void) /* * release_hannel - Release the vmbus channel object itself */ -static inline void release_channel(void *context) +static void release_channel(struct work_struct *work) { - struct vmbus_channel *channel = context; + struct vmbus_channel *channel = container_of(work, + struct vmbus_channel, + work); DPRINT_DBG(VMBUS, "releasing channel (%p)", channel); destroy_workqueue(channel->controlwq); @@ -286,8 +288,8 @@ void free_channel(struct vmbus_channel *channel) * workqueue/thread context * ie we can't destroy ourselves. */ - osd_schedule_callback(gVmbusConnection.WorkQueue, release_channel, - channel); + INIT_WORK(&channel->work, release_channel); + queue_work(gVmbusConnection.WorkQueue, &channel->work); } @@ -308,20 +310,37 @@ static void count_hv_channel(void) spin_unlock_irqrestore(&gVmbusConnection.channel_lock, flags); } +/* + * vmbus_process_rescind_offer - + * Rescind the offer by initiating a device removal + */ +static void vmbus_process_rescind_offer(struct work_struct *work) +{ + struct vmbus_channel *channel = container_of(work, + struct vmbus_channel, + work); + + vmbus_child_device_unregister(channel->device_obj); +} /* * vmbus_process_offer - Process the offer by creating a channel/device * associated with this offer */ -static void vmbus_process_offer(void *context) +static void vmbus_process_offer(struct work_struct *work) { - struct vmbus_channel *newchannel = context; + struct vmbus_channel *newchannel = container_of(work, + struct vmbus_channel, + work); struct vmbus_channel *channel; bool fnew = true; int ret; int cnt; unsigned long flags; + /* The next possible work is rescind handling */ + INIT_WORK(&newchannel->work, vmbus_process_rescind_offer); + /* Make sure this is a new offer */ spin_lock_irqsave(&gVmbusConnection.channel_lock, flags); @@ -405,17 +424,6 @@ static void vmbus_process_offer(void *context) } } -/* - * vmbus_process_rescind_offer - - * Rescind the offer by initiating a device removal - */ -static void vmbus_process_rescind_offer(void *context) -{ - struct vmbus_channel *channel = context; - - vmbus_child_device_unregister(channel->device_obj); -} - /* * vmbus_onoffer - Handler for channel offers from vmbus in parent partition. * @@ -490,8 +498,8 @@ static void vmbus_onoffer(struct vmbus_channel_message_header *hdr) newchannel->monitor_bit = (u8)offer->monitorid % 32; /* TODO: Make sure the offer comes from our parent partition */ - osd_schedule_callback(newchannel->controlwq, vmbus_process_offer, - newchannel); + INIT_WORK(&newchannel->work, vmbus_process_offer); + queue_work(newchannel->controlwq, &newchannel->work); } /* @@ -512,9 +520,9 @@ static void vmbus_onoffer_rescind(struct vmbus_channel_message_header *hdr) return; } - osd_schedule_callback(channel->controlwq, - vmbus_process_rescind_offer, - channel); + /* work is initialized for vmbus_process_rescind_offer() from + * vmbus_process_offer() where the channel got created */ + queue_work(channel->controlwq, &channel->work); } /* diff --git a/drivers/staging/hv/channel_mgmt.h b/drivers/staging/hv/channel_mgmt.h index 12f30aff152d..de6b2a0ebf70 100644 --- a/drivers/staging/hv/channel_mgmt.h +++ b/drivers/staging/hv/channel_mgmt.h @@ -231,6 +231,7 @@ struct vmbus_channel { struct hv_device *device_obj; struct timer_list poll_timer; /* SA-111 workaround */ + struct work_struct work; enum vmbus_channel_state state; -- cgit v1.2.3 From 244ba85606b567e6e990d2fac61e3bde5ff8f0ad Mon Sep 17 00:00:00 2001 From: Timo Teräs Date: Wed, 15 Dec 2010 20:48:10 +0200 Subject: staging: hv: remove unneeded osd_schedule_callback MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit No one calls it anymore, so remove it. Reviewed-By: Hank Janssen Cc: Haiyang Zhang Signed-off-by: Timo Teräs Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/osd.c | 34 ---------------------------------- drivers/staging/hv/osd.h | 4 ---- 2 files changed, 38 deletions(-) diff --git a/drivers/staging/hv/osd.c b/drivers/staging/hv/osd.c index b699ee27f07f..b5a3940331b3 100644 --- a/drivers/staging/hv/osd.c +++ b/drivers/staging/hv/osd.c @@ -43,12 +43,6 @@ #include #include "osd.h" -struct osd_callback_struct { - struct work_struct work; - void (*callback)(void *); - void *data; -}; - void *osd_virtual_alloc_exec(unsigned int size) { #ifdef __x86_64__ @@ -198,31 +192,3 @@ int osd_waitevent_waitex(struct osd_waitevent *wait_event, u32 timeout_in_ms) return ret; } EXPORT_SYMBOL_GPL(osd_waitevent_waitex); - -static void osd_callback_work(struct work_struct *work) -{ - struct osd_callback_struct *cb = container_of(work, - struct osd_callback_struct, - work); - (cb->callback)(cb->data); - kfree(cb); -} - -int osd_schedule_callback(struct workqueue_struct *wq, - void (*func)(void *), - void *data) -{ - struct osd_callback_struct *cb; - - cb = kmalloc(sizeof(*cb), GFP_KERNEL); - if (!cb) { - printk(KERN_ERR "unable to allocate memory in osd_schedule_callback\n"); - return -1; - } - - cb->callback = func; - cb->data = data; - INIT_WORK(&cb->work, osd_callback_work); - return queue_work(wq, &cb->work); -} - diff --git a/drivers/staging/hv/osd.h b/drivers/staging/hv/osd.h index cae126ff6b9a..870ef0768833 100644 --- a/drivers/staging/hv/osd.h +++ b/drivers/staging/hv/osd.h @@ -63,8 +63,4 @@ extern int osd_waitevent_wait(struct osd_waitevent *wait_event); extern int osd_waitevent_waitex(struct osd_waitevent *wait_event, u32 timeout_in_ms); -int osd_schedule_callback(struct workqueue_struct *wq, - void (*func)(void *), - void *data); - #endif /* _OSD_H_ */ -- cgit v1.2.3 From 45241e50e3e741ee2a148693888b48e90e806de9 Mon Sep 17 00:00:00 2001 From: Hank Janssen Date: Mon, 13 Dec 2010 16:23:36 -0800 Subject: Staging: hv: Use only one txf buffer per channel and kmalloc/GFP_KERNEL on initialize Correct issue with not checking kmalloc return value. This fix now only uses one receive buffer for all hv_utils channels, and will do only one kmalloc on init and will return with a -ENOMEM if kmalloc fails on initialize. And properly clean up memory on failure. Thanks to Evgeniy Polyakov for pointing this out. And thanks to Jesper Juhl and Ky Srinivasan for suggesting a better implementation of my original patch. Signed-off-by: Haiyang Zhang Signed-off-by: Hank Janssen Reviewed-by: Jesper Juhl Cc: Evgeniy Polyakov Cc: Jesper Juhl Cc: Ky Srinivasan Signed-off-by: Greg Kroah-Hartman --- drivers/staging/hv/hv_utils.c | 87 +++++++++++++++++++++++-------------------- 1 file changed, 47 insertions(+), 40 deletions(-) diff --git a/drivers/staging/hv/hv_utils.c b/drivers/staging/hv/hv_utils.c index 53e1e290b0f1..0074581f20e8 100644 --- a/drivers/staging/hv/hv_utils.c +++ b/drivers/staging/hv/hv_utils.c @@ -38,12 +38,14 @@ #include "vmbus_api.h" #include "utils.h" +static u8 *shut_txf_buf; +static u8 *time_txf_buf; +static u8 *hbeat_txf_buf; static void shutdown_onchannelcallback(void *context) { struct vmbus_channel *channel = context; - u8 *buf; - u32 buflen, recvlen; + u32 recvlen; u64 requestid; u8 execute_shutdown = false; @@ -52,24 +54,23 @@ static void shutdown_onchannelcallback(void *context) struct icmsg_hdr *icmsghdrp; struct icmsg_negotiate *negop = NULL; - buflen = PAGE_SIZE; - buf = kmalloc(buflen, GFP_ATOMIC); - - vmbus_recvpacket(channel, buf, buflen, &recvlen, &requestid); + vmbus_recvpacket(channel, shut_txf_buf, + PAGE_SIZE, &recvlen, &requestid); if (recvlen > 0) { DPRINT_DBG(VMBUS, "shutdown packet: len=%d, requestid=%lld", recvlen, requestid); - icmsghdrp = (struct icmsg_hdr *)&buf[ + icmsghdrp = (struct icmsg_hdr *)&shut_txf_buf[ sizeof(struct vmbuspipe_hdr)]; if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) { - prep_negotiate_resp(icmsghdrp, negop, buf); + prep_negotiate_resp(icmsghdrp, negop, shut_txf_buf); } else { - shutdown_msg = (struct shutdown_msg_data *)&buf[ - sizeof(struct vmbuspipe_hdr) + - sizeof(struct icmsg_hdr)]; + shutdown_msg = + (struct shutdown_msg_data *)&shut_txf_buf[ + sizeof(struct vmbuspipe_hdr) + + sizeof(struct icmsg_hdr)]; switch (shutdown_msg->flags) { case 0: @@ -93,13 +94,11 @@ static void shutdown_onchannelcallback(void *context) icmsghdrp->icflags = ICMSGHDRFLAG_TRANSACTION | ICMSGHDRFLAG_RESPONSE; - vmbus_sendpacket(channel, buf, + vmbus_sendpacket(channel, shut_txf_buf, recvlen, requestid, VmbusPacketTypeDataInBand, 0); } - kfree(buf); - if (execute_shutdown == true) orderly_poweroff(false); } @@ -150,28 +149,25 @@ static inline void adj_guesttime(u64 hosttime, u8 flags) static void timesync_onchannelcallback(void *context) { struct vmbus_channel *channel = context; - u8 *buf; - u32 buflen, recvlen; + u32 recvlen; u64 requestid; struct icmsg_hdr *icmsghdrp; struct ictimesync_data *timedatap; - buflen = PAGE_SIZE; - buf = kmalloc(buflen, GFP_ATOMIC); - - vmbus_recvpacket(channel, buf, buflen, &recvlen, &requestid); + vmbus_recvpacket(channel, time_txf_buf, + PAGE_SIZE, &recvlen, &requestid); if (recvlen > 0) { DPRINT_DBG(VMBUS, "timesync packet: recvlen=%d, requestid=%lld", recvlen, requestid); - icmsghdrp = (struct icmsg_hdr *)&buf[ + icmsghdrp = (struct icmsg_hdr *)&time_txf_buf[ sizeof(struct vmbuspipe_hdr)]; if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) { - prep_negotiate_resp(icmsghdrp, NULL, buf); + prep_negotiate_resp(icmsghdrp, NULL, time_txf_buf); } else { - timedatap = (struct ictimesync_data *)&buf[ + timedatap = (struct ictimesync_data *)&time_txf_buf[ sizeof(struct vmbuspipe_hdr) + sizeof(struct icmsg_hdr)]; adj_guesttime(timedatap->parenttime, timedatap->flags); @@ -180,12 +176,10 @@ static void timesync_onchannelcallback(void *context) icmsghdrp->icflags = ICMSGHDRFLAG_TRANSACTION | ICMSGHDRFLAG_RESPONSE; - vmbus_sendpacket(channel, buf, + vmbus_sendpacket(channel, time_txf_buf, recvlen, requestid, VmbusPacketTypeDataInBand, 0); } - - kfree(buf); } /* @@ -196,30 +190,28 @@ static void timesync_onchannelcallback(void *context) static void heartbeat_onchannelcallback(void *context) { struct vmbus_channel *channel = context; - u8 *buf; - u32 buflen, recvlen; + u32 recvlen; u64 requestid; struct icmsg_hdr *icmsghdrp; struct heartbeat_msg_data *heartbeat_msg; - buflen = PAGE_SIZE; - buf = kmalloc(buflen, GFP_ATOMIC); - - vmbus_recvpacket(channel, buf, buflen, &recvlen, &requestid); + vmbus_recvpacket(channel, hbeat_txf_buf, + PAGE_SIZE, &recvlen, &requestid); if (recvlen > 0) { DPRINT_DBG(VMBUS, "heartbeat packet: len=%d, requestid=%lld", recvlen, requestid); - icmsghdrp = (struct icmsg_hdr *)&buf[ + icmsghdrp = (struct icmsg_hdr *)&hbeat_txf_buf[ sizeof(struct vmbuspipe_hdr)]; if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) { - prep_negotiate_resp(icmsghdrp, NULL, buf); + prep_negotiate_resp(icmsghdrp, NULL, hbeat_txf_buf); } else { - heartbeat_msg = (struct heartbeat_msg_data *)&buf[ - sizeof(struct vmbuspipe_hdr) + - sizeof(struct icmsg_hdr)]; + heartbeat_msg = + (struct heartbeat_msg_data *)&hbeat_txf_buf[ + sizeof(struct vmbuspipe_hdr) + + sizeof(struct icmsg_hdr)]; DPRINT_DBG(VMBUS, "heartbeat seq = %lld", heartbeat_msg->seq_num); @@ -230,12 +222,10 @@ static void heartbeat_onchannelcallback(void *context) icmsghdrp->icflags = ICMSGHDRFLAG_TRANSACTION | ICMSGHDRFLAG_RESPONSE; - vmbus_sendpacket(channel, buf, + vmbus_sendpacket(channel, hbeat_txf_buf, recvlen, requestid, VmbusPacketTypeDataInBand, 0); } - - kfree(buf); } static const struct pci_device_id __initconst @@ -268,6 +258,19 @@ static int __init init_hyperv_utils(void) if (!dmi_check_system(hv_utils_dmi_table)) return -ENODEV; + shut_txf_buf = kmalloc(PAGE_SIZE, GFP_KERNEL); + time_txf_buf = kmalloc(PAGE_SIZE, GFP_KERNEL); + hbeat_txf_buf = kmalloc(PAGE_SIZE, GFP_KERNEL); + + if (!shut_txf_buf || !time_txf_buf || !hbeat_txf_buf) { + printk(KERN_INFO + "Unable to allocate memory for receive buffer\n"); + kfree(shut_txf_buf); + kfree(time_txf_buf); + kfree(hbeat_txf_buf); + return -ENOMEM; + } + hv_cb_utils[HV_SHUTDOWN_MSG].channel->onchannel_callback = &shutdown_onchannelcallback; hv_cb_utils[HV_SHUTDOWN_MSG].callback = &shutdown_onchannelcallback; @@ -298,6 +301,10 @@ static void exit_hyperv_utils(void) hv_cb_utils[HV_HEARTBEAT_MSG].channel->onchannel_callback = &chn_cb_negotiate; hv_cb_utils[HV_HEARTBEAT_MSG].callback = &chn_cb_negotiate; + + kfree(shut_txf_buf); + kfree(time_txf_buf); + kfree(hbeat_txf_buf); } module_init(init_hyperv_utils); -- cgit v1.2.3 From 0af7e4dff50454905092d468e91c1ef92e10e6b4 Mon Sep 17 00:00:00 2001 From: Mario Kleiner Date: Wed, 8 Dec 2010 04:07:19 +0100 Subject: drm/i915: Add support for precise vblank timestamping (v2) v2: Change IS_IRONLAKE to IS_GEN5 to adapt to 2.6.37 This patch adds new functions for use by the drm core: .get_vblank_timestamp() provides a precise timestamp for the end of the most recent (or current) vblank interval of a given crtc, as needed for the DRI2 implementation of the OML_sync_control extension. It is a thin wrapper around the drm function drm_calc_vbltimestamp_from_scanoutpos() which does almost all the work. .get_scanout_position() provides the current horizontal and vertical video scanout position and "in vblank" status of a given crtc, as needed by the drm for use by drm_calc_vbltimestamp_from_scanoutpos(). The patch modifies the pageflip completion routine to use these precise vblank timestamps as the timestamps for pageflip completion events. This code has been only tested on a HP-Mini Netbook with Atom processor and Intel 945GME gpu. The codepath for (IS_G4X(dev) || IS_GEN5(dev) || IS_GEN6(dev)) gpu's has not been tested so far due to lack of hardware. Signed-off-by: Mario Kleiner Acked-by: Jesse Barnes Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_drv.c | 2 + drivers/gpu/drm/i915/i915_drv.h | 7 +++ drivers/gpu/drm/i915/i915_irq.c | 86 ++++++++++++++++++++++++++++++++++++ drivers/gpu/drm/i915/i915_reg.h | 1 + drivers/gpu/drm/i915/intel_display.c | 29 +++++++++--- 5 files changed, 119 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index bdb29b2a01ed..9eee6cf7901e 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c @@ -652,6 +652,8 @@ static struct drm_driver driver = { .device_is_agp = i915_driver_device_is_agp, .enable_vblank = i915_enable_vblank, .disable_vblank = i915_disable_vblank, + .get_vblank_timestamp = i915_get_vblank_timestamp, + .get_scanout_position = i915_get_crtc_scanoutpos, .irq_preinstall = i915_driver_irq_preinstall, .irq_postinstall = i915_driver_irq_postinstall, .irq_uninstall = i915_driver_irq_uninstall, diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 30780f2cab6f..53dfc8398a96 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1019,6 +1019,13 @@ void i915_disable_pipestat(drm_i915_private_t *dev_priv, int pipe, u32 mask); void intel_enable_asle (struct drm_device *dev); +int i915_get_vblank_timestamp(struct drm_device *dev, int crtc, + int *max_error, + struct timeval *vblank_time, + unsigned flags); + +int i915_get_crtc_scanoutpos(struct drm_device *dev, int pipe, + int *vpos, int *hpos); #ifdef CONFIG_DEBUG_FS extern void i915_destroy_error_state(struct drm_device *dev); diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index e4a2e2c3dbe3..adf983f01dda 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -248,6 +248,92 @@ u32 gm45_get_vblank_counter(struct drm_device *dev, int pipe) return I915_READ(reg); } +int i915_get_crtc_scanoutpos(struct drm_device *dev, int pipe, + int *vpos, int *hpos) +{ + drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; + u32 vbl = 0, position = 0; + int vbl_start, vbl_end, htotal, vtotal; + bool in_vbl = true; + int ret = 0; + + if (!i915_pipe_enabled(dev, pipe)) { + DRM_DEBUG_DRIVER("trying to get scanoutpos for disabled " + "pipe %d\n", pipe); + return 0; + } + + /* Get vtotal. */ + vtotal = 1 + ((I915_READ(VTOTAL(pipe)) >> 16) & 0x1fff); + + if (INTEL_INFO(dev)->gen >= 4) { + /* No obvious pixelcount register. Only query vertical + * scanout position from Display scan line register. + */ + position = I915_READ(PIPEDSL(pipe)); + + /* Decode into vertical scanout position. Don't have + * horizontal scanout position. + */ + *vpos = position & 0x1fff; + *hpos = 0; + } else { + /* Have access to pixelcount since start of frame. + * We can split this into vertical and horizontal + * scanout position. + */ + position = (I915_READ(PIPEFRAMEPIXEL(pipe)) & PIPE_PIXEL_MASK) >> PIPE_PIXEL_SHIFT; + + htotal = 1 + ((I915_READ(HTOTAL(pipe)) >> 16) & 0x1fff); + *vpos = position / htotal; + *hpos = position - (*vpos * htotal); + } + + /* Query vblank area. */ + vbl = I915_READ(VBLANK(pipe)); + + /* Test position against vblank region. */ + vbl_start = vbl & 0x1fff; + vbl_end = (vbl >> 16) & 0x1fff; + + if ((*vpos < vbl_start) || (*vpos > vbl_end)) + in_vbl = false; + + /* Inside "upper part" of vblank area? Apply corrective offset: */ + if (in_vbl && (*vpos >= vbl_start)) + *vpos = *vpos - vtotal; + + /* Readouts valid? */ + if (vbl > 0) + ret |= DRM_SCANOUTPOS_VALID | DRM_SCANOUTPOS_ACCURATE; + + /* In vblank? */ + if (in_vbl) + ret |= DRM_SCANOUTPOS_INVBL; + + return ret; +} + +int i915_get_vblank_timestamp(struct drm_device *dev, int crtc, + int *max_error, + struct timeval *vblank_time, + unsigned flags) +{ + struct drm_crtc *drmcrtc; + + if (crtc < 0 || crtc >= dev->num_crtcs) { + DRM_ERROR("Invalid crtc %d\n", crtc); + return -EINVAL; + } + + /* Get drm_crtc to timestamp: */ + drmcrtc = intel_get_crtc_for_pipe(dev, crtc); + + /* Helper routine in DRM core does all the work: */ + return drm_calc_vbltimestamp_from_scanoutpos(dev, crtc, max_error, + vblank_time, flags, drmcrtc); +} + /* * Handle hotplug events outside the interrupt handler proper. */ diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 820e9dfaadc7..c2231f7d2d97 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -2253,6 +2253,7 @@ #define PIPESRC(pipe) _PIPE(pipe, PIPEASRC, PIPEBSRC) #define PIPECONF(pipe) _PIPE(pipe, PIPEACONF, PIPEBCONF) #define PIPEDSL(pipe) _PIPE(pipe, PIPEADSL, PIPEBDSL) +#define PIPEFRAMEPIXEL(pipe) _PIPE(pipe, PIPEAFRAMEPIXEL, PIPEBFRAMEPIXEL) #define DSPARB 0x70030 #define DSPARB_CSTART_MASK (0x7f << 7) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 8645a974a499..0c201d684584 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -5252,7 +5252,8 @@ static void intel_unpin_work_fn(struct work_struct *__work) } static void do_intel_finish_page_flip(struct drm_device *dev, - struct drm_crtc *crtc) + struct drm_crtc *crtc, + int called_before_vblirq) { drm_i915_private_t *dev_priv = dev->dev_private; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); @@ -5274,19 +5275,33 @@ static void do_intel_finish_page_flip(struct drm_device *dev, } intel_crtc->unpin_work = NULL; - drm_vblank_put(dev, intel_crtc->pipe); if (work->event) { e = work->event; - do_gettimeofday(&now); - e->event.sequence = drm_vblank_count(dev, intel_crtc->pipe); + e->event.sequence = drm_vblank_count_and_time(dev, intel_crtc->pipe, &now); + + /* Called before vblank count and timestamps have + * been updated for the vblank interval of flip + * completion? Need to increment vblank count and + * add one videorefresh duration to returned timestamp + * to account for this. + */ + if (called_before_vblirq) { + e->event.sequence++; + now = ns_to_timeval(timeval_to_ns(&now) + + crtc->framedur_ns); + } + e->event.tv_sec = now.tv_sec; e->event.tv_usec = now.tv_usec; + list_add_tail(&e->base.link, &e->base.file_priv->event_list); wake_up_interruptible(&e->base.file_priv->event_wait); } + drm_vblank_put(dev, intel_crtc->pipe); + spin_unlock_irqrestore(&dev->event_lock, flags); obj = work->old_fb_obj; @@ -5306,7 +5321,8 @@ void intel_finish_page_flip(struct drm_device *dev, int pipe) drm_i915_private_t *dev_priv = dev->dev_private; struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe]; - do_intel_finish_page_flip(dev, crtc); + /* Called after drm_handle_vblank has run for finish vblank. */ + do_intel_finish_page_flip(dev, crtc, 0); } void intel_finish_page_flip_plane(struct drm_device *dev, int plane) @@ -5314,7 +5330,8 @@ void intel_finish_page_flip_plane(struct drm_device *dev, int plane) drm_i915_private_t *dev_priv = dev->dev_private; struct drm_crtc *crtc = dev_priv->plane_to_crtc_mapping[plane]; - do_intel_finish_page_flip(dev, crtc); + /* Called before drm_handle_vblank has run for finish vblank. */ + do_intel_finish_page_flip(dev, crtc, 1); } void intel_prepare_page_flip(struct drm_device *dev, int plane) -- cgit v1.2.3 From 49b14a5ca26fc18bafe33bd9704a1a1cea681fbf Mon Sep 17 00:00:00 2001 From: Mario Kleiner Date: Thu, 9 Dec 2010 07:00:07 +0100 Subject: drm/i915: Add Guess-o-matic for pageflip timestamping. This patch changes the strategy for pageflip completion timestamping. It detects if the pageflip completion routine gets executed before or after drm_handle_vblank, and thereby decides if the returned vblank count and timestamp must be incremented by 1 frame(duration) or not. It compares the current system time at invocation against the current vblank timestamp. If the difference is more than 0.9 video refresh interval durations then it assumes the vblank timestamp and count are outdated and need to be incremented and does so. Otherwise it assumes a delayed pageflip irq and doesn't correct the timestamp and count. Advantage of this patch: Pageflip timestamping becomes more robust against implementation errors and is maintenance free for future GPU's. Disadvantage: A few dozen (hundred?) nsecs extra time spent in pageflip irq handler for each flip, compared to hard-coded per-gpu settings? Signed-off-by: Mario Kleiner Acked-by: Jesse Barnes Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/intel_display.c | 34 ++++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 0c201d684584..fe6538297872 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -5252,21 +5252,22 @@ static void intel_unpin_work_fn(struct work_struct *__work) } static void do_intel_finish_page_flip(struct drm_device *dev, - struct drm_crtc *crtc, - int called_before_vblirq) + struct drm_crtc *crtc) { drm_i915_private_t *dev_priv = dev->dev_private; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); struct intel_unpin_work *work; struct drm_i915_gem_object *obj; struct drm_pending_vblank_event *e; - struct timeval now; + struct timeval tnow, tvbl; unsigned long flags; /* Ignore early vblank irqs */ if (intel_crtc == NULL) return; + do_gettimeofday(&tnow); + spin_lock_irqsave(&dev->event_lock, flags); work = intel_crtc->unpin_work; if (work == NULL || !work->pending) { @@ -5278,22 +5279,29 @@ static void do_intel_finish_page_flip(struct drm_device *dev, if (work->event) { e = work->event; - e->event.sequence = drm_vblank_count_and_time(dev, intel_crtc->pipe, &now); + e->event.sequence = drm_vblank_count_and_time(dev, intel_crtc->pipe, &tvbl); /* Called before vblank count and timestamps have * been updated for the vblank interval of flip * completion? Need to increment vblank count and * add one videorefresh duration to returned timestamp - * to account for this. + * to account for this. We assume this happened if we + * get called over 0.9 frame durations after the last + * timestamped vblank. + * + * This calculation can not be used with vrefresh rates + * below 5Hz (10Hz to be on the safe side) without + * promoting to 64 integers. */ - if (called_before_vblirq) { + if (10 * (timeval_to_ns(&tnow) - timeval_to_ns(&tvbl)) > + 9 * crtc->framedur_ns) { e->event.sequence++; - now = ns_to_timeval(timeval_to_ns(&now) + - crtc->framedur_ns); + tvbl = ns_to_timeval(timeval_to_ns(&tvbl) + + crtc->framedur_ns); } - e->event.tv_sec = now.tv_sec; - e->event.tv_usec = now.tv_usec; + e->event.tv_sec = tvbl.tv_sec; + e->event.tv_usec = tvbl.tv_usec; list_add_tail(&e->base.link, &e->base.file_priv->event_list); @@ -5321,8 +5329,7 @@ void intel_finish_page_flip(struct drm_device *dev, int pipe) drm_i915_private_t *dev_priv = dev->dev_private; struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe]; - /* Called after drm_handle_vblank has run for finish vblank. */ - do_intel_finish_page_flip(dev, crtc, 0); + do_intel_finish_page_flip(dev, crtc); } void intel_finish_page_flip_plane(struct drm_device *dev, int plane) @@ -5330,8 +5337,7 @@ void intel_finish_page_flip_plane(struct drm_device *dev, int plane) drm_i915_private_t *dev_priv = dev->dev_private; struct drm_crtc *crtc = dev_priv->plane_to_crtc_mapping[plane]; - /* Called before drm_handle_vblank has run for finish vblank. */ - do_intel_finish_page_flip(dev, crtc, 1); + do_intel_finish_page_flip(dev, crtc); } void intel_prepare_page_flip(struct drm_device *dev, int plane) -- cgit v1.2.3 From 6714afb108b4973a07413ec58cb300b6d90b8df4 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 17 Dec 2010 04:10:51 +0000 Subject: drm/i915/sdvo: Border and stall select became test bits in gen5 This is even more important as those bits will be moved in future. Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/intel_sdvo.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index 27e63abf2a73..6c0bb18a26e8 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c @@ -1045,7 +1045,9 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, /* Set the SDVO control regs. */ if (INTEL_INFO(dev)->gen >= 4) { - sdvox = SDVO_BORDER_ENABLE; + sdvox = 0; + if (INTEL_INFO(dev)->gen < 5) + sdvox |= SDVO_BORDER_ENABLE; if (adjusted_mode->flags & DRM_MODE_FLAG_PVSYNC) sdvox |= SDVO_VSYNC_ACTIVE_HIGH; if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC) @@ -1075,7 +1077,8 @@ static void intel_sdvo_mode_set(struct drm_encoder *encoder, sdvox |= (pixel_multiplier - 1) << SDVO_PORT_MULTIPLY_SHIFT; } - if (input_dtd.part2.sdvo_flags & SDVO_NEED_TO_STALL) + if (input_dtd.part2.sdvo_flags & SDVO_NEED_TO_STALL && + INTEL_INFO(dev)->gen < 5) sdvox |= SDVO_STALL_SELECT; intel_sdvo_write_sdvox(intel_sdvo, sdvox); } -- cgit v1.2.3 From 225db7d35c33f076115a583abec238a696f4467e Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Thu, 16 Dec 2010 16:38:26 -0500 Subject: ext4: Fix up comments in inode.c This fixes up some broken argument descriptions that Namhyung Kim had originally submitted for ext3. This fixes the comments that were still applicable in ext4. Signed-off-by: "Theodore Ts'o" --- fs/ext4/inode.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index e659597b690b..db3cc913ee8f 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -552,7 +552,7 @@ static ext4_fsblk_t ext4_find_goal(struct inode *inode, ext4_lblk_t block, } /** - * ext4_blks_to_allocate: Look up the block map and count the number + * ext4_blks_to_allocate - Look up the block map and count the number * of direct blocks need to be allocated for the given branch. * * @branch: chain of indirect blocks @@ -591,13 +591,19 @@ static int ext4_blks_to_allocate(Indirect *branch, int k, unsigned int blks, /** * ext4_alloc_blocks: multiple allocate blocks needed for a branch + * @handle: handle for this transaction + * @inode: inode which needs allocated blocks + * @iblock: the logical block to start allocated at + * @goal: preferred physical block of allocation * @indirect_blks: the number of blocks need to allocate for indirect * blocks - * + * @blks: number of desired blocks * @new_blocks: on return it will store the new block numbers for * the indirect blocks(if needed) and the first direct block, - * @blks: on return it will store the total number of allocated - * direct blocks + * @err: on return it will store the error code + * + * This function will return the number of blocks allocated as + * requested by the passed-in parameters. */ static int ext4_alloc_blocks(handle_t *handle, struct inode *inode, ext4_lblk_t iblock, ext4_fsblk_t goal, @@ -711,9 +717,11 @@ failed_out: /** * ext4_alloc_branch - allocate and set up a chain of blocks. + * @handle: handle for this transaction * @inode: owner * @indirect_blks: number of allocated indirect blocks * @blks: number of allocated direct blocks + * @goal: preferred place for allocation * @offsets: offsets (in the blocks) to store the pointers to next. * @branch: place to store the chain in. * @@ -826,6 +834,7 @@ failed: /** * ext4_splice_branch - splice the allocated branch onto inode. + * @handle: handle for this transaction * @inode: owner * @block: (logical) number of block we are adding * @chain: chain of indirect blocks (with a missing link - see -- cgit v1.2.3 From 1121584f5db8a99a7ad94c6c5d62431b3187ad98 Mon Sep 17 00:00:00 2001 From: "H.J. Lu" Date: Wed, 15 Dec 2010 17:11:22 -0800 Subject: modpost: Put .zdebug* section on white list "as --compress-debug-sections" will generate compressed debug sections with section names ".zdebug*". This patch puts .zdebug* section on white list. Signed-off-by: H.J. Lu Signed-off-by: Michal Marek --- scripts/mod/modpost.c | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 33122ca04e7c..194e2c453609 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -790,6 +790,7 @@ static const char *section_white_list[] = { ".comment*", ".debug*", + ".zdebug*", /* Compressed debug sections. */ ".GCC-command-line", /* mn10300 */ ".mdebug*", /* alpha, score, mips etc. */ ".pdr", /* alpha, score, mips etc. */ -- cgit v1.2.3 From 63d5e5a727240b317b0c2fa2abeb32b367aea196 Mon Sep 17 00:00:00 2001 From: Sven Eckelmann Date: Thu, 16 Dec 2010 23:28:17 +0100 Subject: Staging: batman-adv: Remove batman-adv from staging batman-adv is now moved to net/batman-adv/ and can be removed from staging. Signed-off-by: Sven Eckelmann Cc: David S. Miller Signed-off-by: Greg Kroah-Hartman --- drivers/staging/Kconfig | 2 - drivers/staging/Makefile | 1 - drivers/staging/batman-adv/Kconfig | 26 - drivers/staging/batman-adv/Makefile | 39 - drivers/staging/batman-adv/README | 240 ---- drivers/staging/batman-adv/TODO | 10 - drivers/staging/batman-adv/aggregation.c | 273 ---- drivers/staging/batman-adv/aggregation.h | 43 - drivers/staging/batman-adv/bat_debugfs.c | 360 ----- drivers/staging/batman-adv/bat_debugfs.h | 33 - drivers/staging/batman-adv/bat_sysfs.c | 593 --------- drivers/staging/batman-adv/bat_sysfs.h | 42 - drivers/staging/batman-adv/bitarray.c | 201 --- drivers/staging/batman-adv/bitarray.h | 47 - drivers/staging/batman-adv/gateway_client.c | 477 ------- drivers/staging/batman-adv/gateway_client.h | 36 - drivers/staging/batman-adv/gateway_common.c | 177 --- drivers/staging/batman-adv/gateway_common.h | 38 - drivers/staging/batman-adv/hard-interface.c | 652 --------- drivers/staging/batman-adv/hard-interface.h | 53 - drivers/staging/batman-adv/hash.c | 83 -- drivers/staging/batman-adv/hash.h | 259 ---- drivers/staging/batman-adv/icmp_socket.c | 357 ----- drivers/staging/batman-adv/icmp_socket.h | 34 - drivers/staging/batman-adv/main.c | 187 --- drivers/staging/batman-adv/main.h | 180 --- drivers/staging/batman-adv/originator.c | 546 -------- drivers/staging/batman-adv/originator.h | 64 - drivers/staging/batman-adv/packet.h | 136 -- drivers/staging/batman-adv/ring_buffer.c | 52 - drivers/staging/batman-adv/ring_buffer.h | 28 - drivers/staging/batman-adv/routing.c | 1393 -------------------- drivers/staging/batman-adv/routing.h | 48 - drivers/staging/batman-adv/send.c | 586 -------- drivers/staging/batman-adv/send.h | 41 - drivers/staging/batman-adv/soft-interface.c | 697 ---------- drivers/staging/batman-adv/soft-interface.h | 35 - .../staging/batman-adv/sysfs-class-net-batman-adv | 14 - drivers/staging/batman-adv/sysfs-class-net-mesh | 69 - drivers/staging/batman-adv/translation-table.c | 528 -------- drivers/staging/batman-adv/translation-table.h | 45 - drivers/staging/batman-adv/types.h | 271 ---- drivers/staging/batman-adv/unicast.c | 343 ----- drivers/staging/batman-adv/unicast.h | 35 - drivers/staging/batman-adv/vis.c | 903 ------------- drivers/staging/batman-adv/vis.h | 37 - 46 files changed, 10314 deletions(-) delete mode 100644 drivers/staging/batman-adv/Kconfig delete mode 100644 drivers/staging/batman-adv/Makefile delete mode 100644 drivers/staging/batman-adv/README delete mode 100644 drivers/staging/batman-adv/TODO delete mode 100644 drivers/staging/batman-adv/aggregation.c delete mode 100644 drivers/staging/batman-adv/aggregation.h delete mode 100644 drivers/staging/batman-adv/bat_debugfs.c delete mode 100644 drivers/staging/batman-adv/bat_debugfs.h delete mode 100644 drivers/staging/batman-adv/bat_sysfs.c delete mode 100644 drivers/staging/batman-adv/bat_sysfs.h delete mode 100644 drivers/staging/batman-adv/bitarray.c delete mode 100644 drivers/staging/batman-adv/bitarray.h delete mode 100644 drivers/staging/batman-adv/gateway_client.c delete mode 100644 drivers/staging/batman-adv/gateway_client.h delete mode 100644 drivers/staging/batman-adv/gateway_common.c delete mode 100644 drivers/staging/batman-adv/gateway_common.h delete mode 100644 drivers/staging/batman-adv/hard-interface.c delete mode 100644 drivers/staging/batman-adv/hard-interface.h delete mode 100644 drivers/staging/batman-adv/hash.c delete mode 100644 drivers/staging/batman-adv/hash.h delete mode 100644 drivers/staging/batman-adv/icmp_socket.c delete mode 100644 drivers/staging/batman-adv/icmp_socket.h delete mode 100644 drivers/staging/batman-adv/main.c delete mode 100644 drivers/staging/batman-adv/main.h delete mode 100644 drivers/staging/batman-adv/originator.c delete mode 100644 drivers/staging/batman-adv/originator.h delete mode 100644 drivers/staging/batman-adv/packet.h delete mode 100644 drivers/staging/batman-adv/ring_buffer.c delete mode 100644 drivers/staging/batman-adv/ring_buffer.h delete mode 100644 drivers/staging/batman-adv/routing.c delete mode 100644 drivers/staging/batman-adv/routing.h delete mode 100644 drivers/staging/batman-adv/send.c delete mode 100644 drivers/staging/batman-adv/send.h delete mode 100644 drivers/staging/batman-adv/soft-interface.c delete mode 100644 drivers/staging/batman-adv/soft-interface.h delete mode 100644 drivers/staging/batman-adv/sysfs-class-net-batman-adv delete mode 100644 drivers/staging/batman-adv/sysfs-class-net-mesh delete mode 100644 drivers/staging/batman-adv/translation-table.c delete mode 100644 drivers/staging/batman-adv/translation-table.h delete mode 100644 drivers/staging/batman-adv/types.h delete mode 100644 drivers/staging/batman-adv/unicast.c delete mode 100644 drivers/staging/batman-adv/unicast.h delete mode 100644 drivers/staging/batman-adv/vis.c delete mode 100644 drivers/staging/batman-adv/vis.h diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index f2d9fe8cde5f..923e28f83208 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -129,8 +129,6 @@ source "drivers/staging/wlags49_h2/Kconfig" source "drivers/staging/wlags49_h25/Kconfig" -source "drivers/staging/batman-adv/Kconfig" - source "drivers/staging/samsung-laptop/Kconfig" source "drivers/staging/sm7xx/Kconfig" diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index 10c72bb1940d..4e6797f6444a 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -47,7 +47,6 @@ obj-$(CONFIG_IIO) += iio/ obj-$(CONFIG_ZRAM) += zram/ obj-$(CONFIG_WLAGS49_H2) += wlags49_h2/ obj-$(CONFIG_WLAGS49_H25) += wlags49_h25/ -obj-$(CONFIG_BATMAN_ADV) += batman-adv/ obj-$(CONFIG_SAMSUNG_LAPTOP) += samsung-laptop/ obj-$(CONFIG_FB_SM7XX) += sm7xx/ obj-$(CONFIG_VIDEO_DT3155) += dt3155v4l/ diff --git a/drivers/staging/batman-adv/Kconfig b/drivers/staging/batman-adv/Kconfig deleted file mode 100644 index 8553f3517454..000000000000 --- a/drivers/staging/batman-adv/Kconfig +++ /dev/null @@ -1,26 +0,0 @@ -# -# B.A.T.M.A.N meshing protocol -# - -config BATMAN_ADV - tristate "B.A.T.M.A.N. Advanced Meshing Protocol" - depends on NET - default n - ---help--- - - B.A.T.M.A.N. (better approach to mobile ad-hoc networking) is - a routing protocol for multi-hop ad-hoc mesh networks. The - networks may be wired or wireless. See - http://www.open-mesh.org/ for more information and user space - tools. - -config BATMAN_ADV_DEBUG - bool "B.A.T.M.A.N. debugging" - depends on BATMAN_ADV != n - ---help--- - - This is an option for use by developers; most people should - say N here. This enables compilation of support for - outputting debugging information to the kernel log. The - output is controlled via the module parameter debug. - diff --git a/drivers/staging/batman-adv/Makefile b/drivers/staging/batman-adv/Makefile deleted file mode 100644 index d936aeccd194..000000000000 --- a/drivers/staging/batman-adv/Makefile +++ /dev/null @@ -1,39 +0,0 @@ -# -# Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: -# -# Marek Lindner, Simon Wunderlich -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of version 2 of the GNU General Public -# License 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. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -# 02110-1301, USA -# - -obj-$(CONFIG_BATMAN_ADV) += batman-adv.o -batman-adv-y += aggregation.o -batman-adv-y += bat_debugfs.o -batman-adv-y += bat_sysfs.o -batman-adv-y += bitarray.o -batman-adv-y += gateway_client.o -batman-adv-y += gateway_common.o -batman-adv-y += hard-interface.o -batman-adv-y += hash.o -batman-adv-y += icmp_socket.o -batman-adv-y += main.o -batman-adv-y += originator.o -batman-adv-y += ring_buffer.o -batman-adv-y += routing.o -batman-adv-y += send.o -batman-adv-y += soft-interface.o -batman-adv-y += translation-table.o -batman-adv-y += unicast.o -batman-adv-y += vis.o diff --git a/drivers/staging/batman-adv/README b/drivers/staging/batman-adv/README deleted file mode 100644 index 77f0cdd5b0dd..000000000000 --- a/drivers/staging/batman-adv/README +++ /dev/null @@ -1,240 +0,0 @@ -[state: 21-11-2010] - -BATMAN-ADV ----------- - -Batman advanced is a new approach to wireless networking which -does no longer operate on the IP basis. Unlike the batman daemon, -which exchanges information using UDP packets and sets routing -tables, batman-advanced operates on ISO/OSI Layer 2 only and uses -and routes (or better: bridges) Ethernet Frames. It emulates a -virtual network switch of all nodes participating. Therefore all -nodes appear to be link local, thus all higher operating proto- -cols won't be affected by any changes within the network. You can -run almost any protocol above batman advanced, prominent examples -are: IPv4, IPv6, DHCP, IPX. - -Batman advanced was implemented as a Linux kernel driver to re- -duce the overhead to a minimum. It does not depend on any (other) -network driver, and can be used on wifi as well as ethernet lan, -vpn, etc ... (anything with ethernet-style layer 2). - -CONFIGURATION -------------- - -Load the batman-adv module into your kernel: - -# insmod batman-adv.ko - -The module is now waiting for activation. You must add some in- -terfaces on which batman can operate. After loading the module -batman advanced will scan your systems interfaces to search for -compatible interfaces. Once found, it will create subfolders in -the /sys directories of each supported interface, e.g. - -# ls /sys/class/net/eth0/batman_adv/ -# iface_status mesh_iface - -If an interface does not have the "batman_adv" subfolder it prob- -ably is not supported. Not supported interfaces are: loopback, -non-ethernet and batman's own interfaces. - -Note: After the module was loaded it will continuously watch for -new interfaces to verify the compatibility. There is no need to -reload the module if you plug your USB wifi adapter into your ma- -chine after batman advanced was initially loaded. - -To activate a given interface simply write "bat0" into its -"mesh_iface" file inside the batman_adv subfolder: - -# echo bat0 > /sys/class/net/eth0/batman_adv/mesh_iface - -Repeat this step for all interfaces you wish to add. Now batman -starts using/broadcasting on this/these interface(s). - -By reading the "iface_status" file you can check its status: - -# cat /sys/class/net/eth0/batman_adv/iface_status -# active - -To deactivate an interface you have to write "none" into its -"mesh_iface" file: - -# echo none > /sys/class/net/eth0/batman_adv/mesh_iface - - -All mesh wide settings can be found in batman's own interface -folder: - -# ls /sys/class/net/bat0/mesh/ -# aggregated_ogms bonding fragmentation orig_interval -# vis_mode - - -There is a special folder for debugging informations: - -# ls /sys/kernel/debug/batman_adv/bat0/ -# originators socket transtable_global transtable_local -# vis_data - - -Some of the files contain all sort of status information regard- -ing the mesh network. For example, you can view the table of -originators (mesh participants) with: - -# cat /sys/kernel/debug/batman_adv/bat0/originators - -Other files allow to change batman's behaviour to better fit your -requirements. For instance, you can check the current originator -interval (value in milliseconds which determines how often batman -sends its broadcast packets): - -# cat /sys/class/net/bat0/mesh/orig_interval -# 1000 - -and also change its value: - -# echo 3000 > /sys/class/net/bat0/mesh/orig_interval - -In very mobile scenarios, you might want to adjust the originator -interval to a lower value. This will make the mesh more respon- -sive to topology changes, but will also increase the overhead. - - -USAGE ------ - -To make use of your newly created mesh, batman advanced provides -a new interface "bat0" which you should use from this point on. -All interfaces added to batman advanced are not relevant any -longer because batman handles them for you. Basically, one "hands -over" the data by using the batman interface and batman will make -sure it reaches its destination. - -The "bat0" interface can be used like any other regular inter- -face. It needs an IP address which can be either statically con- -figured or dynamically (by using DHCP or similar services): - -# NodeA: ifconfig bat0 192.168.0.1 -# NodeB: ifconfig bat0 192.168.0.2 -# NodeB: ping 192.168.0.1 - -Note: In order to avoid problems remove all IP addresses previ- -ously assigned to interfaces now used by batman advanced, e.g. - -# ifconfig eth0 0.0.0.0 - - -VISUALIZATION -------------- - -If you want topology visualization, at least one mesh node must -be configured as VIS-server: - -# echo "server" > /sys/class/net/bat0/mesh/vis_mode - -Each node is either configured as "server" or as "client" (de- -fault: "client"). Clients send their topology data to the server -next to them, and server synchronize with other servers. If there -is no server configured (default) within the mesh, no topology -information will be transmitted. With these "synchronizing -servers", there can be 1 or more vis servers sharing the same (or -at least very similar) data. - -When configured as server, you can get a topology snapshot of -your mesh: - -# cat /sys/kernel/debug/batman_adv/bat0/vis_data - -This raw output is intended to be easily parsable and convertable -with other tools. Have a look at the batctl README if you want a -vis output in dot or json format for instance and how those out- -puts could then be visualised in an image. - -The raw format consists of comma separated values per entry where -each entry is giving information about a certain source inter- -face. Each entry can/has to have the following values: --> "mac" - mac address of an originator's source interface - (each line begins with it) --> "TQ mac value" - src mac's link quality towards mac address - of a neighbor originator's interface which - is being used for routing --> "HNA mac" - HNA announced by source mac --> "PRIMARY" - this is a primary interface --> "SEC mac" - secondary mac address of source - (requires preceding PRIMARY) - -The TQ value has a range from 4 to 255 with 255 being the best. -The HNA entries are showing which hosts are connected to the mesh -via bat0 or being bridged into the mesh network. The PRIMARY/SEC -values are only applied on primary interfaces - - -LOGGING/DEBUGGING ------------------ - -All error messages, warnings and information messages are sent to -the kernel log. Depending on your operating system distribution -this can be read in one of a number of ways. Try using the com- -mands: dmesg, logread, or looking in the files /var/log/kern.log -or /var/log/syslog. All batman-adv messages are prefixed with -"batman-adv:" So to see just these messages try - -# dmesg | grep batman-adv - -When investigating problems with your mesh network it is some- -times necessary to see more detail debug messages. This must be -enabled when compiling the batman-adv module. When building bat- -man-adv as part of kernel, use "make menuconfig" and enable the -option "B.A.T.M.A.N. debugging". - -Those additional debug messages can be accessed using a special -file in debugfs - -# cat /sys/kernel/debug/batman_adv/bat0/log - -The additional debug output is by default disabled. It can be en- -abled during run time. Following log_levels are defined: - -0 - All debug output disabled -1 - Enable messages related to routing / flooding / broadcasting -2 - Enable route or hna added / changed / deleted -3 - Enable all messages - -The debug output can be changed at runtime using the file -/sys/class/net/bat0/mesh/log_level. e.g. - -# echo 2 > /sys/class/net/bat0/mesh/log_level - -will enable debug messages for when routes or HNAs change. - - -BATCTL ------- - -As batman advanced operates on layer 2 all hosts participating in -the virtual switch are completely transparent for all protocols -above layer 2. Therefore the common diagnosis tools do not work -as expected. To overcome these problems batctl was created. At -the moment the batctl contains ping, traceroute, tcpdump and -interfaces to the kernel module settings. - -For more information, please see the manpage (man batctl). - -batctl is available on http://www.open-mesh.org/ - - -CONTACT -------- - -Please send us comments, experiences, questions, anything :) - -IRC: #batman on irc.freenode.org -Mailing-list: b.a.t.m.a.n@b.a.t.m.a.n@lists.open-mesh.org - (optional subscription at - https://lists.open-mesh.org/mm/listinfo/b.a.t.m.a.n) - -You can also contact the Authors: - -Marek Lindner -Simon Wunderlich diff --git a/drivers/staging/batman-adv/TODO b/drivers/staging/batman-adv/TODO deleted file mode 100644 index ba69ba3ab62d..000000000000 --- a/drivers/staging/batman-adv/TODO +++ /dev/null @@ -1,10 +0,0 @@ - * Request a new review - * Process the comments from the review - * Move into mainline proper - -Please send all patches to: - Marek Lindner - Simon Wunderlich - Sven Eckelmann - b.a.t.m.a.n@lists.open-mesh.org - Greg Kroah-Hartman diff --git a/drivers/staging/batman-adv/aggregation.c b/drivers/staging/batman-adv/aggregation.c deleted file mode 100644 index 0c92e3b35abf..000000000000 --- a/drivers/staging/batman-adv/aggregation.c +++ /dev/null @@ -1,273 +0,0 @@ -/* - * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: - * - * Marek Lindner, Simon Wunderlich - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License 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. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA - * - */ - -#include "main.h" -#include "aggregation.h" -#include "send.h" -#include "routing.h" - -/* calculate the size of the hna information for a given packet */ -static int hna_len(struct batman_packet *batman_packet) -{ - return batman_packet->num_hna * ETH_ALEN; -} - -/* return true if new_packet can be aggregated with forw_packet */ -static bool can_aggregate_with(struct batman_packet *new_batman_packet, - int packet_len, - unsigned long send_time, - bool directlink, - struct batman_if *if_incoming, - struct forw_packet *forw_packet) -{ - struct batman_packet *batman_packet = - (struct batman_packet *)forw_packet->skb->data; - int aggregated_bytes = forw_packet->packet_len + packet_len; - - /** - * we can aggregate the current packet to this aggregated packet - * if: - * - * - the send time is within our MAX_AGGREGATION_MS time - * - the resulting packet wont be bigger than - * MAX_AGGREGATION_BYTES - */ - - if (time_before(send_time, forw_packet->send_time) && - time_after_eq(send_time + msecs_to_jiffies(MAX_AGGREGATION_MS), - forw_packet->send_time) && - (aggregated_bytes <= MAX_AGGREGATION_BYTES)) { - - /** - * check aggregation compatibility - * -> direct link packets are broadcasted on - * their interface only - * -> aggregate packet if the current packet is - * a "global" packet as well as the base - * packet - */ - - /* packets without direct link flag and high TTL - * are flooded through the net */ - if ((!directlink) && - (!(batman_packet->flags & DIRECTLINK)) && - (batman_packet->ttl != 1) && - - /* own packets originating non-primary - * interfaces leave only that interface */ - ((!forw_packet->own) || - (forw_packet->if_incoming->if_num == 0))) - return true; - - /* if the incoming packet is sent via this one - * interface only - we still can aggregate */ - if ((directlink) && - (new_batman_packet->ttl == 1) && - (forw_packet->if_incoming == if_incoming) && - - /* packets from direct neighbors or - * own secondary interface packets - * (= secondary interface packets in general) */ - (batman_packet->flags & DIRECTLINK || - (forw_packet->own && - forw_packet->if_incoming->if_num != 0))) - return true; - } - - return false; -} - -#define atomic_dec_not_zero(v) atomic_add_unless((v), -1, 0) -/* create a new aggregated packet and add this packet to it */ -static void new_aggregated_packet(unsigned char *packet_buff, int packet_len, - unsigned long send_time, bool direct_link, - struct batman_if *if_incoming, - int own_packet) -{ - struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface); - struct forw_packet *forw_packet_aggr; - unsigned char *skb_buff; - - /* own packet should always be scheduled */ - if (!own_packet) { - if (!atomic_dec_not_zero(&bat_priv->batman_queue_left)) { - bat_dbg(DBG_BATMAN, bat_priv, - "batman packet queue full\n"); - return; - } - } - - forw_packet_aggr = kmalloc(sizeof(struct forw_packet), GFP_ATOMIC); - if (!forw_packet_aggr) { - if (!own_packet) - atomic_inc(&bat_priv->batman_queue_left); - return; - } - - if ((atomic_read(&bat_priv->aggregated_ogms)) && - (packet_len < MAX_AGGREGATION_BYTES)) - forw_packet_aggr->skb = dev_alloc_skb(MAX_AGGREGATION_BYTES + - sizeof(struct ethhdr)); - else - forw_packet_aggr->skb = dev_alloc_skb(packet_len + - sizeof(struct ethhdr)); - - if (!forw_packet_aggr->skb) { - if (!own_packet) - atomic_inc(&bat_priv->batman_queue_left); - kfree(forw_packet_aggr); - return; - } - skb_reserve(forw_packet_aggr->skb, sizeof(struct ethhdr)); - - INIT_HLIST_NODE(&forw_packet_aggr->list); - - skb_buff = skb_put(forw_packet_aggr->skb, packet_len); - forw_packet_aggr->packet_len = packet_len; - memcpy(skb_buff, packet_buff, packet_len); - - forw_packet_aggr->own = own_packet; - forw_packet_aggr->if_incoming = if_incoming; - forw_packet_aggr->num_packets = 0; - forw_packet_aggr->direct_link_flags = 0; - forw_packet_aggr->send_time = send_time; - - /* save packet direct link flag status */ - if (direct_link) - forw_packet_aggr->direct_link_flags |= 1; - - /* add new packet to packet list */ - spin_lock_bh(&bat_priv->forw_bat_list_lock); - hlist_add_head(&forw_packet_aggr->list, &bat_priv->forw_bat_list); - spin_unlock_bh(&bat_priv->forw_bat_list_lock); - - /* start timer for this packet */ - INIT_DELAYED_WORK(&forw_packet_aggr->delayed_work, - send_outstanding_bat_packet); - queue_delayed_work(bat_event_workqueue, - &forw_packet_aggr->delayed_work, - send_time - jiffies); -} - -/* aggregate a new packet into the existing aggregation */ -static void aggregate(struct forw_packet *forw_packet_aggr, - unsigned char *packet_buff, - int packet_len, - bool direct_link) -{ - unsigned char *skb_buff; - - skb_buff = skb_put(forw_packet_aggr->skb, packet_len); - memcpy(skb_buff, packet_buff, packet_len); - forw_packet_aggr->packet_len += packet_len; - forw_packet_aggr->num_packets++; - - /* save packet direct link flag status */ - if (direct_link) - forw_packet_aggr->direct_link_flags |= - (1 << forw_packet_aggr->num_packets); -} - -void add_bat_packet_to_list(struct bat_priv *bat_priv, - unsigned char *packet_buff, int packet_len, - struct batman_if *if_incoming, char own_packet, - unsigned long send_time) -{ - /** - * _aggr -> pointer to the packet we want to aggregate with - * _pos -> pointer to the position in the queue - */ - struct forw_packet *forw_packet_aggr = NULL, *forw_packet_pos = NULL; - struct hlist_node *tmp_node; - struct batman_packet *batman_packet = - (struct batman_packet *)packet_buff; - bool direct_link = batman_packet->flags & DIRECTLINK ? 1 : 0; - - /* find position for the packet in the forward queue */ - spin_lock_bh(&bat_priv->forw_bat_list_lock); - /* own packets are not to be aggregated */ - if ((atomic_read(&bat_priv->aggregated_ogms)) && (!own_packet)) { - hlist_for_each_entry(forw_packet_pos, tmp_node, - &bat_priv->forw_bat_list, list) { - if (can_aggregate_with(batman_packet, - packet_len, - send_time, - direct_link, - if_incoming, - forw_packet_pos)) { - forw_packet_aggr = forw_packet_pos; - break; - } - } - } - - /* nothing to aggregate with - either aggregation disabled or no - * suitable aggregation packet found */ - if (forw_packet_aggr == NULL) { - /* the following section can run without the lock */ - spin_unlock_bh(&bat_priv->forw_bat_list_lock); - - /** - * if we could not aggregate this packet with one of the others - * we hold it back for a while, so that it might be aggregated - * later on - */ - if ((!own_packet) && - (atomic_read(&bat_priv->aggregated_ogms))) - send_time += msecs_to_jiffies(MAX_AGGREGATION_MS); - - new_aggregated_packet(packet_buff, packet_len, - send_time, direct_link, - if_incoming, own_packet); - } else { - aggregate(forw_packet_aggr, - packet_buff, packet_len, - direct_link); - spin_unlock_bh(&bat_priv->forw_bat_list_lock); - } -} - -/* unpack the aggregated packets and process them one by one */ -void receive_aggr_bat_packet(struct ethhdr *ethhdr, unsigned char *packet_buff, - int packet_len, struct batman_if *if_incoming) -{ - struct batman_packet *batman_packet; - int buff_pos = 0; - unsigned char *hna_buff; - - batman_packet = (struct batman_packet *)packet_buff; - - do { - /* network to host order for our 32bit seqno, and the - orig_interval. */ - batman_packet->seqno = ntohl(batman_packet->seqno); - - hna_buff = packet_buff + buff_pos + BAT_PACKET_LEN; - receive_bat_packet(ethhdr, batman_packet, - hna_buff, hna_len(batman_packet), - if_incoming); - - buff_pos += BAT_PACKET_LEN + hna_len(batman_packet); - batman_packet = (struct batman_packet *) - (packet_buff + buff_pos); - } while (aggregated_packet(buff_pos, packet_len, - batman_packet->num_hna)); -} diff --git a/drivers/staging/batman-adv/aggregation.h b/drivers/staging/batman-adv/aggregation.h deleted file mode 100644 index 71a91b3da913..000000000000 --- a/drivers/staging/batman-adv/aggregation.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: - * - * Marek Lindner, Simon Wunderlich - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License 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. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA - * - */ - -#ifndef _NET_BATMAN_ADV_AGGREGATION_H_ -#define _NET_BATMAN_ADV_AGGREGATION_H_ - -#include "main.h" - -/* is there another aggregated packet here? */ -static inline int aggregated_packet(int buff_pos, int packet_len, int num_hna) -{ - int next_buff_pos = buff_pos + BAT_PACKET_LEN + (num_hna * ETH_ALEN); - - return (next_buff_pos <= packet_len) && - (next_buff_pos <= MAX_AGGREGATION_BYTES); -} - -void add_bat_packet_to_list(struct bat_priv *bat_priv, - unsigned char *packet_buff, int packet_len, - struct batman_if *if_incoming, char own_packet, - unsigned long send_time); -void receive_aggr_bat_packet(struct ethhdr *ethhdr, unsigned char *packet_buff, - int packet_len, struct batman_if *if_incoming); - -#endif /* _NET_BATMAN_ADV_AGGREGATION_H_ */ diff --git a/drivers/staging/batman-adv/bat_debugfs.c b/drivers/staging/batman-adv/bat_debugfs.c deleted file mode 100644 index 0ae81d07f102..000000000000 --- a/drivers/staging/batman-adv/bat_debugfs.c +++ /dev/null @@ -1,360 +0,0 @@ -/* - * Copyright (C) 2010 B.A.T.M.A.N. contributors: - * - * Marek Lindner - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License 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. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA - * - */ - -#include "main.h" - -#include - -#include "bat_debugfs.h" -#include "translation-table.h" -#include "originator.h" -#include "hard-interface.h" -#include "gateway_common.h" -#include "gateway_client.h" -#include "soft-interface.h" -#include "vis.h" -#include "icmp_socket.h" - -static struct dentry *bat_debugfs; - -#ifdef CONFIG_BATMAN_ADV_DEBUG -#define LOG_BUFF_MASK (log_buff_len-1) -#define LOG_BUFF(idx) (debug_log->log_buff[(idx) & LOG_BUFF_MASK]) - -static int log_buff_len = LOG_BUF_LEN; - -static void emit_log_char(struct debug_log *debug_log, char c) -{ - LOG_BUFF(debug_log->log_end) = c; - debug_log->log_end++; - - if (debug_log->log_end - debug_log->log_start > log_buff_len) - debug_log->log_start = debug_log->log_end - log_buff_len; -} - -static int fdebug_log(struct debug_log *debug_log, char *fmt, ...) -{ - int printed_len; - va_list args; - static char debug_log_buf[256]; - char *p; - - if (!debug_log) - return 0; - - spin_lock_bh(&debug_log->lock); - va_start(args, fmt); - printed_len = vscnprintf(debug_log_buf, sizeof(debug_log_buf), - fmt, args); - va_end(args); - - for (p = debug_log_buf; *p != 0; p++) - emit_log_char(debug_log, *p); - - spin_unlock_bh(&debug_log->lock); - - wake_up(&debug_log->queue_wait); - - return 0; -} - -int debug_log(struct bat_priv *bat_priv, char *fmt, ...) -{ - va_list args; - char tmp_log_buf[256]; - - va_start(args, fmt); - vscnprintf(tmp_log_buf, sizeof(tmp_log_buf), fmt, args); - fdebug_log(bat_priv->debug_log, "[%10u] %s", - (jiffies / HZ), tmp_log_buf); - va_end(args); - - return 0; -} - -static int log_open(struct inode *inode, struct file *file) -{ - nonseekable_open(inode, file); - file->private_data = inode->i_private; - inc_module_count(); - return 0; -} - -static int log_release(struct inode *inode, struct file *file) -{ - dec_module_count(); - return 0; -} - -static ssize_t log_read(struct file *file, char __user *buf, - size_t count, loff_t *ppos) -{ - struct bat_priv *bat_priv = file->private_data; - struct debug_log *debug_log = bat_priv->debug_log; - int error, i = 0; - char c; - - if ((file->f_flags & O_NONBLOCK) && - !(debug_log->log_end - debug_log->log_start)) - return -EAGAIN; - - if ((!buf) || (count < 0)) - return -EINVAL; - - if (count == 0) - return 0; - - if (!access_ok(VERIFY_WRITE, buf, count)) - return -EFAULT; - - error = wait_event_interruptible(debug_log->queue_wait, - (debug_log->log_start - debug_log->log_end)); - - if (error) - return error; - - spin_lock_bh(&debug_log->lock); - - while ((!error) && (i < count) && - (debug_log->log_start != debug_log->log_end)) { - c = LOG_BUFF(debug_log->log_start); - - debug_log->log_start++; - - spin_unlock_bh(&debug_log->lock); - - error = __put_user(c, buf); - - spin_lock_bh(&debug_log->lock); - - buf++; - i++; - - } - - spin_unlock_bh(&debug_log->lock); - - if (!error) - return i; - - return error; -} - -static unsigned int log_poll(struct file *file, poll_table *wait) -{ - struct bat_priv *bat_priv = file->private_data; - struct debug_log *debug_log = bat_priv->debug_log; - - poll_wait(file, &debug_log->queue_wait, wait); - - if (debug_log->log_end - debug_log->log_start) - return POLLIN | POLLRDNORM; - - return 0; -} - -static const struct file_operations log_fops = { - .open = log_open, - .release = log_release, - .read = log_read, - .poll = log_poll, - .llseek = no_llseek, -}; - -static int debug_log_setup(struct bat_priv *bat_priv) -{ - struct dentry *d; - - if (!bat_priv->debug_dir) - goto err; - - bat_priv->debug_log = kzalloc(sizeof(struct debug_log), GFP_ATOMIC); - if (!bat_priv->debug_log) - goto err; - - spin_lock_init(&bat_priv->debug_log->lock); - init_waitqueue_head(&bat_priv->debug_log->queue_wait); - - d = debugfs_create_file("log", S_IFREG | S_IRUSR, - bat_priv->debug_dir, bat_priv, &log_fops); - if (d) - goto err; - - return 0; - -err: - return 1; -} - -static void debug_log_cleanup(struct bat_priv *bat_priv) -{ - kfree(bat_priv->debug_log); - bat_priv->debug_log = NULL; -} -#else /* CONFIG_BATMAN_ADV_DEBUG */ -static int debug_log_setup(struct bat_priv *bat_priv) -{ - bat_priv->debug_log = NULL; - return 0; -} - -static void debug_log_cleanup(struct bat_priv *bat_priv) -{ - return; -} -#endif - -static int originators_open(struct inode *inode, struct file *file) -{ - struct net_device *net_dev = (struct net_device *)inode->i_private; - return single_open(file, orig_seq_print_text, net_dev); -} - -static int gateways_open(struct inode *inode, struct file *file) -{ - struct net_device *net_dev = (struct net_device *)inode->i_private; - return single_open(file, gw_client_seq_print_text, net_dev); -} - -static int softif_neigh_open(struct inode *inode, struct file *file) -{ - struct net_device *net_dev = (struct net_device *)inode->i_private; - return single_open(file, softif_neigh_seq_print_text, net_dev); -} - -static int transtable_global_open(struct inode *inode, struct file *file) -{ - struct net_device *net_dev = (struct net_device *)inode->i_private; - return single_open(file, hna_global_seq_print_text, net_dev); -} - -static int transtable_local_open(struct inode *inode, struct file *file) -{ - struct net_device *net_dev = (struct net_device *)inode->i_private; - return single_open(file, hna_local_seq_print_text, net_dev); -} - -static int vis_data_open(struct inode *inode, struct file *file) -{ - struct net_device *net_dev = (struct net_device *)inode->i_private; - return single_open(file, vis_seq_print_text, net_dev); -} - -struct bat_debuginfo { - struct attribute attr; - const struct file_operations fops; -}; - -#define BAT_DEBUGINFO(_name, _mode, _open) \ -struct bat_debuginfo bat_debuginfo_##_name = { \ - .attr = { .name = __stringify(_name), \ - .mode = _mode, }, \ - .fops = { .owner = THIS_MODULE, \ - .open = _open, \ - .read = seq_read, \ - .llseek = seq_lseek, \ - .release = single_release, \ - } \ -}; - -static BAT_DEBUGINFO(originators, S_IRUGO, originators_open); -static BAT_DEBUGINFO(gateways, S_IRUGO, gateways_open); -static BAT_DEBUGINFO(softif_neigh, S_IRUGO, softif_neigh_open); -static BAT_DEBUGINFO(transtable_global, S_IRUGO, transtable_global_open); -static BAT_DEBUGINFO(transtable_local, S_IRUGO, transtable_local_open); -static BAT_DEBUGINFO(vis_data, S_IRUGO, vis_data_open); - -static struct bat_debuginfo *mesh_debuginfos[] = { - &bat_debuginfo_originators, - &bat_debuginfo_gateways, - &bat_debuginfo_softif_neigh, - &bat_debuginfo_transtable_global, - &bat_debuginfo_transtable_local, - &bat_debuginfo_vis_data, - NULL, -}; - -void debugfs_init(void) -{ - bat_debugfs = debugfs_create_dir(DEBUGFS_BAT_SUBDIR, NULL); - if (bat_debugfs == ERR_PTR(-ENODEV)) - bat_debugfs = NULL; -} - -void debugfs_destroy(void) -{ - if (bat_debugfs) { - debugfs_remove_recursive(bat_debugfs); - bat_debugfs = NULL; - } -} - -int debugfs_add_meshif(struct net_device *dev) -{ - struct bat_priv *bat_priv = netdev_priv(dev); - struct bat_debuginfo **bat_debug; - struct dentry *file; - - if (!bat_debugfs) - goto out; - - bat_priv->debug_dir = debugfs_create_dir(dev->name, bat_debugfs); - if (!bat_priv->debug_dir) - goto out; - - bat_socket_setup(bat_priv); - debug_log_setup(bat_priv); - - for (bat_debug = mesh_debuginfos; *bat_debug; ++bat_debug) { - file = debugfs_create_file(((*bat_debug)->attr).name, - S_IFREG | ((*bat_debug)->attr).mode, - bat_priv->debug_dir, - dev, &(*bat_debug)->fops); - if (!file) { - bat_err(dev, "Can't add debugfs file: %s/%s\n", - dev->name, ((*bat_debug)->attr).name); - goto rem_attr; - } - } - - return 0; -rem_attr: - debugfs_remove_recursive(bat_priv->debug_dir); - bat_priv->debug_dir = NULL; -out: -#ifdef CONFIG_DEBUG_FS - return -ENOMEM; -#else - return 0; -#endif /* CONFIG_DEBUG_FS */ -} - -void debugfs_del_meshif(struct net_device *dev) -{ - struct bat_priv *bat_priv = netdev_priv(dev); - - debug_log_cleanup(bat_priv); - - if (bat_debugfs) { - debugfs_remove_recursive(bat_priv->debug_dir); - bat_priv->debug_dir = NULL; - } -} diff --git a/drivers/staging/batman-adv/bat_debugfs.h b/drivers/staging/batman-adv/bat_debugfs.h deleted file mode 100644 index 72df532b7d5f..000000000000 --- a/drivers/staging/batman-adv/bat_debugfs.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (C) 2010 B.A.T.M.A.N. contributors: - * - * Marek Lindner - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License 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. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA - * - */ - - -#ifndef _NET_BATMAN_ADV_DEBUGFS_H_ -#define _NET_BATMAN_ADV_DEBUGFS_H_ - -#define DEBUGFS_BAT_SUBDIR "batman_adv" - -void debugfs_init(void); -void debugfs_destroy(void); -int debugfs_add_meshif(struct net_device *dev); -void debugfs_del_meshif(struct net_device *dev); - -#endif /* _NET_BATMAN_ADV_DEBUGFS_H_ */ diff --git a/drivers/staging/batman-adv/bat_sysfs.c b/drivers/staging/batman-adv/bat_sysfs.c deleted file mode 100644 index cd7bb51825f1..000000000000 --- a/drivers/staging/batman-adv/bat_sysfs.c +++ /dev/null @@ -1,593 +0,0 @@ -/* - * Copyright (C) 2010 B.A.T.M.A.N. contributors: - * - * Marek Lindner - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License 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. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA - * - */ - -#include "main.h" -#include "bat_sysfs.h" -#include "translation-table.h" -#include "originator.h" -#include "hard-interface.h" -#include "gateway_common.h" -#include "gateway_client.h" -#include "vis.h" - -#define to_dev(obj) container_of(obj, struct device, kobj) -#define kobj_to_netdev(obj) to_net_dev(to_dev(obj->parent)) -#define kobj_to_batpriv(obj) netdev_priv(kobj_to_netdev(obj)) - -/* Use this, if you have customized show and store functions */ -#define BAT_ATTR(_name, _mode, _show, _store) \ -struct bat_attribute bat_attr_##_name = { \ - .attr = {.name = __stringify(_name), \ - .mode = _mode }, \ - .show = _show, \ - .store = _store, \ -}; - -#define BAT_ATTR_STORE_BOOL(_name, _post_func) \ -ssize_t store_##_name(struct kobject *kobj, struct attribute *attr, \ - char *buff, size_t count) \ -{ \ - struct net_device *net_dev = kobj_to_netdev(kobj); \ - struct bat_priv *bat_priv = netdev_priv(net_dev); \ - return __store_bool_attr(buff, count, _post_func, attr, \ - &bat_priv->_name, net_dev); \ -} - -#define BAT_ATTR_SHOW_BOOL(_name) \ -ssize_t show_##_name(struct kobject *kobj, struct attribute *attr, \ - char *buff) \ -{ \ - struct bat_priv *bat_priv = kobj_to_batpriv(kobj); \ - return sprintf(buff, "%s\n", \ - atomic_read(&bat_priv->_name) == 0 ? \ - "disabled" : "enabled"); \ -} \ - -/* Use this, if you are going to turn a [name] in bat_priv on or off */ -#define BAT_ATTR_BOOL(_name, _mode, _post_func) \ - static BAT_ATTR_STORE_BOOL(_name, _post_func) \ - static BAT_ATTR_SHOW_BOOL(_name) \ - static BAT_ATTR(_name, _mode, show_##_name, store_##_name) - - -#define BAT_ATTR_STORE_UINT(_name, _min, _max, _post_func) \ -ssize_t store_##_name(struct kobject *kobj, struct attribute *attr, \ - char *buff, size_t count) \ -{ \ - struct net_device *net_dev = kobj_to_netdev(kobj); \ - struct bat_priv *bat_priv = netdev_priv(net_dev); \ - return __store_uint_attr(buff, count, _min, _max, _post_func, \ - attr, &bat_priv->_name, net_dev); \ -} - -#define BAT_ATTR_SHOW_UINT(_name) \ -ssize_t show_##_name(struct kobject *kobj, struct attribute *attr, \ - char *buff) \ -{ \ - struct bat_priv *bat_priv = kobj_to_batpriv(kobj); \ - return sprintf(buff, "%i\n", atomic_read(&bat_priv->_name)); \ -} \ - -/* Use this, if you are going to set [name] in bat_priv to unsigned integer - * values only */ -#define BAT_ATTR_UINT(_name, _mode, _min, _max, _post_func) \ - static BAT_ATTR_STORE_UINT(_name, _min, _max, _post_func) \ - static BAT_ATTR_SHOW_UINT(_name) \ - static BAT_ATTR(_name, _mode, show_##_name, store_##_name) - - -static int store_bool_attr(char *buff, size_t count, - struct net_device *net_dev, - char *attr_name, atomic_t *attr) -{ - int enabled = -1; - - if (buff[count - 1] == '\n') - buff[count - 1] = '\0'; - - if ((strncmp(buff, "1", 2) == 0) || - (strncmp(buff, "enable", 7) == 0) || - (strncmp(buff, "enabled", 8) == 0)) - enabled = 1; - - if ((strncmp(buff, "0", 2) == 0) || - (strncmp(buff, "disable", 8) == 0) || - (strncmp(buff, "disabled", 9) == 0)) - enabled = 0; - - if (enabled < 0) { - bat_info(net_dev, - "%s: Invalid parameter received: %s\n", - attr_name, buff); - return -EINVAL; - } - - if (atomic_read(attr) == enabled) - return count; - - bat_info(net_dev, "%s: Changing from: %s to: %s\n", attr_name, - atomic_read(attr) == 1 ? "enabled" : "disabled", - enabled == 1 ? "enabled" : "disabled"); - - atomic_set(attr, (unsigned)enabled); - return count; -} - -static inline ssize_t __store_bool_attr(char *buff, size_t count, - void (*post_func)(struct net_device *), - struct attribute *attr, - atomic_t *attr_store, struct net_device *net_dev) -{ - int ret; - - ret = store_bool_attr(buff, count, net_dev, (char *)attr->name, - attr_store); - if (post_func && ret) - post_func(net_dev); - - return ret; -} - -static int store_uint_attr(char *buff, size_t count, - struct net_device *net_dev, char *attr_name, - unsigned int min, unsigned int max, atomic_t *attr) -{ - unsigned long uint_val; - int ret; - - ret = strict_strtoul(buff, 10, &uint_val); - if (ret) { - bat_info(net_dev, - "%s: Invalid parameter received: %s\n", - attr_name, buff); - return -EINVAL; - } - - if (uint_val < min) { - bat_info(net_dev, "%s: Value is too small: %lu min: %u\n", - attr_name, uint_val, min); - return -EINVAL; - } - - if (uint_val > max) { - bat_info(net_dev, "%s: Value is too big: %lu max: %u\n", - attr_name, uint_val, max); - return -EINVAL; - } - - if (atomic_read(attr) == uint_val) - return count; - - bat_info(net_dev, "%s: Changing from: %i to: %lu\n", - attr_name, atomic_read(attr), uint_val); - - atomic_set(attr, uint_val); - return count; -} - -static inline ssize_t __store_uint_attr(char *buff, size_t count, - int min, int max, - void (*post_func)(struct net_device *), - struct attribute *attr, - atomic_t *attr_store, struct net_device *net_dev) -{ - int ret; - - ret = store_uint_attr(buff, count, net_dev, (char *)attr->name, - min, max, attr_store); - if (post_func && ret) - post_func(net_dev); - - return ret; -} - -static ssize_t show_vis_mode(struct kobject *kobj, struct attribute *attr, - char *buff) -{ - struct bat_priv *bat_priv = kobj_to_batpriv(kobj); - int vis_mode = atomic_read(&bat_priv->vis_mode); - - return sprintf(buff, "%s\n", - vis_mode == VIS_TYPE_CLIENT_UPDATE ? - "client" : "server"); -} - -static ssize_t store_vis_mode(struct kobject *kobj, struct attribute *attr, - char *buff, size_t count) -{ - struct net_device *net_dev = kobj_to_netdev(kobj); - struct bat_priv *bat_priv = netdev_priv(net_dev); - unsigned long val; - int ret, vis_mode_tmp = -1; - - ret = strict_strtoul(buff, 10, &val); - - if (((count == 2) && (!ret) && (val == VIS_TYPE_CLIENT_UPDATE)) || - (strncmp(buff, "client", 6) == 0) || - (strncmp(buff, "off", 3) == 0)) - vis_mode_tmp = VIS_TYPE_CLIENT_UPDATE; - - if (((count == 2) && (!ret) && (val == VIS_TYPE_SERVER_SYNC)) || - (strncmp(buff, "server", 6) == 0)) - vis_mode_tmp = VIS_TYPE_SERVER_SYNC; - - if (vis_mode_tmp < 0) { - if (buff[count - 1] == '\n') - buff[count - 1] = '\0'; - - bat_info(net_dev, - "Invalid parameter for 'vis mode' setting received: " - "%s\n", buff); - return -EINVAL; - } - - if (atomic_read(&bat_priv->vis_mode) == vis_mode_tmp) - return count; - - bat_info(net_dev, "Changing vis mode from: %s to: %s\n", - atomic_read(&bat_priv->vis_mode) == VIS_TYPE_CLIENT_UPDATE ? - "client" : "server", vis_mode_tmp == VIS_TYPE_CLIENT_UPDATE ? - "client" : "server"); - - atomic_set(&bat_priv->vis_mode, (unsigned)vis_mode_tmp); - return count; -} - -static void post_gw_deselect(struct net_device *net_dev) -{ - struct bat_priv *bat_priv = netdev_priv(net_dev); - gw_deselect(bat_priv); -} - -static ssize_t show_gw_mode(struct kobject *kobj, struct attribute *attr, - char *buff) -{ - struct bat_priv *bat_priv = kobj_to_batpriv(kobj); - int bytes_written; - - switch (atomic_read(&bat_priv->gw_mode)) { - case GW_MODE_CLIENT: - bytes_written = sprintf(buff, "%s\n", GW_MODE_CLIENT_NAME); - break; - case GW_MODE_SERVER: - bytes_written = sprintf(buff, "%s\n", GW_MODE_SERVER_NAME); - break; - default: - bytes_written = sprintf(buff, "%s\n", GW_MODE_OFF_NAME); - break; - } - - return bytes_written; -} - -static ssize_t store_gw_mode(struct kobject *kobj, struct attribute *attr, - char *buff, size_t count) -{ - struct net_device *net_dev = kobj_to_netdev(kobj); - struct bat_priv *bat_priv = netdev_priv(net_dev); - char *curr_gw_mode_str; - int gw_mode_tmp = -1; - - if (buff[count - 1] == '\n') - buff[count - 1] = '\0'; - - if (strncmp(buff, GW_MODE_OFF_NAME, strlen(GW_MODE_OFF_NAME)) == 0) - gw_mode_tmp = GW_MODE_OFF; - - if (strncmp(buff, GW_MODE_CLIENT_NAME, - strlen(GW_MODE_CLIENT_NAME)) == 0) - gw_mode_tmp = GW_MODE_CLIENT; - - if (strncmp(buff, GW_MODE_SERVER_NAME, - strlen(GW_MODE_SERVER_NAME)) == 0) - gw_mode_tmp = GW_MODE_SERVER; - - if (gw_mode_tmp < 0) { - bat_info(net_dev, - "Invalid parameter for 'gw mode' setting received: " - "%s\n", buff); - return -EINVAL; - } - - if (atomic_read(&bat_priv->gw_mode) == gw_mode_tmp) - return count; - - switch (atomic_read(&bat_priv->gw_mode)) { - case GW_MODE_CLIENT: - curr_gw_mode_str = GW_MODE_CLIENT_NAME; - break; - case GW_MODE_SERVER: - curr_gw_mode_str = GW_MODE_SERVER_NAME; - break; - default: - curr_gw_mode_str = GW_MODE_OFF_NAME; - break; - } - - bat_info(net_dev, "Changing gw mode from: %s to: %s\n", - curr_gw_mode_str, buff); - - gw_deselect(bat_priv); - atomic_set(&bat_priv->gw_mode, (unsigned)gw_mode_tmp); - return count; -} - -static ssize_t show_gw_bwidth(struct kobject *kobj, struct attribute *attr, - char *buff) -{ - struct bat_priv *bat_priv = kobj_to_batpriv(kobj); - int down, up; - int gw_bandwidth = atomic_read(&bat_priv->gw_bandwidth); - - gw_bandwidth_to_kbit(gw_bandwidth, &down, &up); - return sprintf(buff, "%i%s/%i%s\n", - (down > 2048 ? down / 1024 : down), - (down > 2048 ? "MBit" : "KBit"), - (up > 2048 ? up / 1024 : up), - (up > 2048 ? "MBit" : "KBit")); -} - -static ssize_t store_gw_bwidth(struct kobject *kobj, struct attribute *attr, - char *buff, size_t count) -{ - struct net_device *net_dev = kobj_to_netdev(kobj); - - if (buff[count - 1] == '\n') - buff[count - 1] = '\0'; - - return gw_bandwidth_set(net_dev, buff, count); -} - -BAT_ATTR_BOOL(aggregated_ogms, S_IRUGO | S_IWUSR, NULL); -BAT_ATTR_BOOL(bonding, S_IRUGO | S_IWUSR, NULL); -BAT_ATTR_BOOL(fragmentation, S_IRUGO | S_IWUSR, update_min_mtu); -static BAT_ATTR(vis_mode, S_IRUGO | S_IWUSR, show_vis_mode, store_vis_mode); -static BAT_ATTR(gw_mode, S_IRUGO | S_IWUSR, show_gw_mode, store_gw_mode); -BAT_ATTR_UINT(orig_interval, S_IRUGO | S_IWUSR, 2 * JITTER, INT_MAX, NULL); -BAT_ATTR_UINT(hop_penalty, S_IRUGO | S_IWUSR, 0, TQ_MAX_VALUE, NULL); -BAT_ATTR_UINT(gw_sel_class, S_IRUGO | S_IWUSR, 1, TQ_MAX_VALUE, - post_gw_deselect); -static BAT_ATTR(gw_bandwidth, S_IRUGO | S_IWUSR, show_gw_bwidth, - store_gw_bwidth); -#ifdef CONFIG_BATMAN_ADV_DEBUG -BAT_ATTR_UINT(log_level, S_IRUGO | S_IWUSR, 0, 3, NULL); -#endif - -static struct bat_attribute *mesh_attrs[] = { - &bat_attr_aggregated_ogms, - &bat_attr_bonding, - &bat_attr_fragmentation, - &bat_attr_vis_mode, - &bat_attr_gw_mode, - &bat_attr_orig_interval, - &bat_attr_hop_penalty, - &bat_attr_gw_sel_class, - &bat_attr_gw_bandwidth, -#ifdef CONFIG_BATMAN_ADV_DEBUG - &bat_attr_log_level, -#endif - NULL, -}; - -int sysfs_add_meshif(struct net_device *dev) -{ - struct kobject *batif_kobject = &dev->dev.kobj; - struct bat_priv *bat_priv = netdev_priv(dev); - struct bat_attribute **bat_attr; - int err; - - bat_priv->mesh_obj = kobject_create_and_add(SYSFS_IF_MESH_SUBDIR, - batif_kobject); - if (!bat_priv->mesh_obj) { - bat_err(dev, "Can't add sysfs directory: %s/%s\n", dev->name, - SYSFS_IF_MESH_SUBDIR); - goto out; - } - - for (bat_attr = mesh_attrs; *bat_attr; ++bat_attr) { - err = sysfs_create_file(bat_priv->mesh_obj, - &((*bat_attr)->attr)); - if (err) { - bat_err(dev, "Can't add sysfs file: %s/%s/%s\n", - dev->name, SYSFS_IF_MESH_SUBDIR, - ((*bat_attr)->attr).name); - goto rem_attr; - } - } - - return 0; - -rem_attr: - for (bat_attr = mesh_attrs; *bat_attr; ++bat_attr) - sysfs_remove_file(bat_priv->mesh_obj, &((*bat_attr)->attr)); - - kobject_put(bat_priv->mesh_obj); - bat_priv->mesh_obj = NULL; -out: - return -ENOMEM; -} - -void sysfs_del_meshif(struct net_device *dev) -{ - struct bat_priv *bat_priv = netdev_priv(dev); - struct bat_attribute **bat_attr; - - for (bat_attr = mesh_attrs; *bat_attr; ++bat_attr) - sysfs_remove_file(bat_priv->mesh_obj, &((*bat_attr)->attr)); - - kobject_put(bat_priv->mesh_obj); - bat_priv->mesh_obj = NULL; -} - -static ssize_t show_mesh_iface(struct kobject *kobj, struct attribute *attr, - char *buff) -{ - struct net_device *net_dev = kobj_to_netdev(kobj); - struct batman_if *batman_if = get_batman_if_by_netdev(net_dev); - ssize_t length; - - if (!batman_if) - return 0; - - length = sprintf(buff, "%s\n", batman_if->if_status == IF_NOT_IN_USE ? - "none" : batman_if->soft_iface->name); - - kref_put(&batman_if->refcount, hardif_free_ref); - - return length; -} - -static ssize_t store_mesh_iface(struct kobject *kobj, struct attribute *attr, - char *buff, size_t count) -{ - struct net_device *net_dev = kobj_to_netdev(kobj); - struct batman_if *batman_if = get_batman_if_by_netdev(net_dev); - int status_tmp = -1; - int ret; - - if (!batman_if) - return count; - - if (buff[count - 1] == '\n') - buff[count - 1] = '\0'; - - if (strlen(buff) >= IFNAMSIZ) { - pr_err("Invalid parameter for 'mesh_iface' setting received: " - "interface name too long '%s'\n", buff); - kref_put(&batman_if->refcount, hardif_free_ref); - return -EINVAL; - } - - if (strncmp(buff, "none", 4) == 0) - status_tmp = IF_NOT_IN_USE; - else - status_tmp = IF_I_WANT_YOU; - - if ((batman_if->if_status == status_tmp) || ((batman_if->soft_iface) && - (strncmp(batman_if->soft_iface->name, buff, IFNAMSIZ) == 0))) { - kref_put(&batman_if->refcount, hardif_free_ref); - return count; - } - - if (status_tmp == IF_NOT_IN_USE) { - rtnl_lock(); - hardif_disable_interface(batman_if); - rtnl_unlock(); - kref_put(&batman_if->refcount, hardif_free_ref); - return count; - } - - /* if the interface already is in use */ - if (batman_if->if_status != IF_NOT_IN_USE) { - rtnl_lock(); - hardif_disable_interface(batman_if); - rtnl_unlock(); - } - - ret = hardif_enable_interface(batman_if, buff); - kref_put(&batman_if->refcount, hardif_free_ref); - - return ret; -} - -static ssize_t show_iface_status(struct kobject *kobj, struct attribute *attr, - char *buff) -{ - struct net_device *net_dev = kobj_to_netdev(kobj); - struct batman_if *batman_if = get_batman_if_by_netdev(net_dev); - ssize_t length; - - if (!batman_if) - return 0; - - switch (batman_if->if_status) { - case IF_TO_BE_REMOVED: - length = sprintf(buff, "disabling\n"); - break; - case IF_INACTIVE: - length = sprintf(buff, "inactive\n"); - break; - case IF_ACTIVE: - length = sprintf(buff, "active\n"); - break; - case IF_TO_BE_ACTIVATED: - length = sprintf(buff, "enabling\n"); - break; - case IF_NOT_IN_USE: - default: - length = sprintf(buff, "not in use\n"); - break; - } - - kref_put(&batman_if->refcount, hardif_free_ref); - - return length; -} - -static BAT_ATTR(mesh_iface, S_IRUGO | S_IWUSR, - show_mesh_iface, store_mesh_iface); -static BAT_ATTR(iface_status, S_IRUGO, show_iface_status, NULL); - -static struct bat_attribute *batman_attrs[] = { - &bat_attr_mesh_iface, - &bat_attr_iface_status, - NULL, -}; - -int sysfs_add_hardif(struct kobject **hardif_obj, struct net_device *dev) -{ - struct kobject *hardif_kobject = &dev->dev.kobj; - struct bat_attribute **bat_attr; - int err; - - *hardif_obj = kobject_create_and_add(SYSFS_IF_BAT_SUBDIR, - hardif_kobject); - - if (!*hardif_obj) { - bat_err(dev, "Can't add sysfs directory: %s/%s\n", dev->name, - SYSFS_IF_BAT_SUBDIR); - goto out; - } - - for (bat_attr = batman_attrs; *bat_attr; ++bat_attr) { - err = sysfs_create_file(*hardif_obj, &((*bat_attr)->attr)); - if (err) { - bat_err(dev, "Can't add sysfs file: %s/%s/%s\n", - dev->name, SYSFS_IF_BAT_SUBDIR, - ((*bat_attr)->attr).name); - goto rem_attr; - } - } - - return 0; - -rem_attr: - for (bat_attr = batman_attrs; *bat_attr; ++bat_attr) - sysfs_remove_file(*hardif_obj, &((*bat_attr)->attr)); -out: - return -ENOMEM; -} - -void sysfs_del_hardif(struct kobject **hardif_obj) -{ - kobject_put(*hardif_obj); - *hardif_obj = NULL; -} diff --git a/drivers/staging/batman-adv/bat_sysfs.h b/drivers/staging/batman-adv/bat_sysfs.h deleted file mode 100644 index 7f186c007b4f..000000000000 --- a/drivers/staging/batman-adv/bat_sysfs.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (C) 2010 B.A.T.M.A.N. contributors: - * - * Marek Lindner - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License 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. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA - * - */ - - -#ifndef _NET_BATMAN_ADV_SYSFS_H_ -#define _NET_BATMAN_ADV_SYSFS_H_ - -#define SYSFS_IF_MESH_SUBDIR "mesh" -#define SYSFS_IF_BAT_SUBDIR "batman_adv" - -struct bat_attribute { - struct attribute attr; - ssize_t (*show)(struct kobject *kobj, struct attribute *attr, - char *buf); - ssize_t (*store)(struct kobject *kobj, struct attribute *attr, - char *buf, size_t count); -}; - -int sysfs_add_meshif(struct net_device *dev); -void sysfs_del_meshif(struct net_device *dev); -int sysfs_add_hardif(struct kobject **hardif_obj, struct net_device *dev); -void sysfs_del_hardif(struct kobject **hardif_obj); - -#endif /* _NET_BATMAN_ADV_SYSFS_H_ */ diff --git a/drivers/staging/batman-adv/bitarray.c b/drivers/staging/batman-adv/bitarray.c deleted file mode 100644 index 814274fbaa2f..000000000000 --- a/drivers/staging/batman-adv/bitarray.c +++ /dev/null @@ -1,201 +0,0 @@ -/* - * Copyright (C) 2006-2010 B.A.T.M.A.N. contributors: - * - * Simon Wunderlich, Marek Lindner - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License 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. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA - * - */ - -#include "main.h" -#include "bitarray.h" - -#include - -/* returns true if the corresponding bit in the given seq_bits indicates true - * and curr_seqno is within range of last_seqno */ -uint8_t get_bit_status(TYPE_OF_WORD *seq_bits, uint32_t last_seqno, - uint32_t curr_seqno) -{ - int32_t diff, word_offset, word_num; - - diff = last_seqno - curr_seqno; - if (diff < 0 || diff >= TQ_LOCAL_WINDOW_SIZE) { - return 0; - } else { - /* which word */ - word_num = (last_seqno - curr_seqno) / WORD_BIT_SIZE; - /* which position in the selected word */ - word_offset = (last_seqno - curr_seqno) % WORD_BIT_SIZE; - - if (seq_bits[word_num] & 1 << word_offset) - return 1; - else - return 0; - } -} - -/* turn corresponding bit on, so we can remember that we got the packet */ -void bit_mark(TYPE_OF_WORD *seq_bits, int32_t n) -{ - int32_t word_offset, word_num; - - /* if too old, just drop it */ - if (n < 0 || n >= TQ_LOCAL_WINDOW_SIZE) - return; - - /* which word */ - word_num = n / WORD_BIT_SIZE; - /* which position in the selected word */ - word_offset = n % WORD_BIT_SIZE; - - seq_bits[word_num] |= 1 << word_offset; /* turn the position on */ -} - -/* shift the packet array by n places. */ -static void bit_shift(TYPE_OF_WORD *seq_bits, int32_t n) -{ - int32_t word_offset, word_num; - int32_t i; - - if (n <= 0 || n >= TQ_LOCAL_WINDOW_SIZE) - return; - - word_offset = n % WORD_BIT_SIZE;/* shift how much inside each word */ - word_num = n / WORD_BIT_SIZE; /* shift over how much (full) words */ - - for (i = NUM_WORDS - 1; i > word_num; i--) { - /* going from old to new, so we don't overwrite the data we copy - * from. - * - * left is high, right is low: FEDC BA98 7654 3210 - * ^^ ^^ - * vvvv - * ^^^^ = from, vvvvv =to, we'd have word_num==1 and - * word_offset==WORD_BIT_SIZE/2 ????? in this example. - * (=24 bits) - * - * our desired output would be: 9876 5432 1000 0000 - * */ - - seq_bits[i] = - (seq_bits[i - word_num] << word_offset) + - /* take the lower port from the left half, shift it left - * to its final position */ - (seq_bits[i - word_num - 1] >> - (WORD_BIT_SIZE-word_offset)); - /* and the upper part of the right half and shift it left to - * it's position */ - /* for our example that would be: word[0] = 9800 + 0076 = - * 9876 */ - } - /* now for our last word, i==word_num, we only have the it's "left" - * half. that's the 1000 word in our example.*/ - - seq_bits[i] = (seq_bits[i - word_num] << word_offset); - - /* pad the rest with 0, if there is anything */ - i--; - - for (; i >= 0; i--) - seq_bits[i] = 0; -} - -static void bit_reset_window(TYPE_OF_WORD *seq_bits) -{ - int i; - for (i = 0; i < NUM_WORDS; i++) - seq_bits[i] = 0; -} - - -/* receive and process one packet within the sequence number window. - * - * returns: - * 1 if the window was moved (either new or very old) - * 0 if the window was not moved/shifted. - */ -char bit_get_packet(void *priv, TYPE_OF_WORD *seq_bits, - int32_t seq_num_diff, int8_t set_mark) -{ - struct bat_priv *bat_priv = (struct bat_priv *)priv; - - /* sequence number is slightly older. We already got a sequence number - * higher than this one, so we just mark it. */ - - if ((seq_num_diff <= 0) && (seq_num_diff > -TQ_LOCAL_WINDOW_SIZE)) { - if (set_mark) - bit_mark(seq_bits, -seq_num_diff); - return 0; - } - - /* sequence number is slightly newer, so we shift the window and - * set the mark if required */ - - if ((seq_num_diff > 0) && (seq_num_diff < TQ_LOCAL_WINDOW_SIZE)) { - bit_shift(seq_bits, seq_num_diff); - - if (set_mark) - bit_mark(seq_bits, 0); - return 1; - } - - /* sequence number is much newer, probably missed a lot of packets */ - - if ((seq_num_diff >= TQ_LOCAL_WINDOW_SIZE) - || (seq_num_diff < EXPECTED_SEQNO_RANGE)) { - bat_dbg(DBG_BATMAN, bat_priv, - "We missed a lot of packets (%i) !\n", - seq_num_diff - 1); - bit_reset_window(seq_bits); - if (set_mark) - bit_mark(seq_bits, 0); - return 1; - } - - /* received a much older packet. The other host either restarted - * or the old packet got delayed somewhere in the network. The - * packet should be dropped without calling this function if the - * seqno window is protected. */ - - if ((seq_num_diff <= -TQ_LOCAL_WINDOW_SIZE) - || (seq_num_diff >= EXPECTED_SEQNO_RANGE)) { - - bat_dbg(DBG_BATMAN, bat_priv, - "Other host probably restarted!\n"); - - bit_reset_window(seq_bits); - if (set_mark) - bit_mark(seq_bits, 0); - - return 1; - } - - /* never reached */ - return 0; -} - -/* count the hamming weight, how many good packets did we receive? just count - * the 1's. - */ -int bit_packet_count(TYPE_OF_WORD *seq_bits) -{ - int i, hamming = 0; - - for (i = 0; i < NUM_WORDS; i++) - hamming += hweight_long(seq_bits[i]); - - return hamming; -} diff --git a/drivers/staging/batman-adv/bitarray.h b/drivers/staging/batman-adv/bitarray.h deleted file mode 100644 index 77b1e61847e8..000000000000 --- a/drivers/staging/batman-adv/bitarray.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (C) 2006-2010 B.A.T.M.A.N. contributors: - * - * Simon Wunderlich, Marek Lindner - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License 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. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA - * - */ - -#ifndef _NET_BATMAN_ADV_BITARRAY_H_ -#define _NET_BATMAN_ADV_BITARRAY_H_ - -/* you should choose something big, if you don't want to waste cpu - * and keep the type in sync with bit_packet_count */ -#define TYPE_OF_WORD unsigned long -#define WORD_BIT_SIZE (sizeof(TYPE_OF_WORD) * 8) - -/* returns true if the corresponding bit in the given seq_bits indicates true - * and curr_seqno is within range of last_seqno */ -uint8_t get_bit_status(TYPE_OF_WORD *seq_bits, uint32_t last_seqno, - uint32_t curr_seqno); - -/* turn corresponding bit on, so we can remember that we got the packet */ -void bit_mark(TYPE_OF_WORD *seq_bits, int32_t n); - - -/* receive and process one packet, returns 1 if received seq_num is considered - * new, 0 if old */ -char bit_get_packet(void *priv, TYPE_OF_WORD *seq_bits, - int32_t seq_num_diff, int8_t set_mark); - -/* count the hamming weight, how many good packets did we receive? */ -int bit_packet_count(TYPE_OF_WORD *seq_bits); - -#endif /* _NET_BATMAN_ADV_BITARRAY_H_ */ diff --git a/drivers/staging/batman-adv/gateway_client.c b/drivers/staging/batman-adv/gateway_client.c deleted file mode 100644 index 0065ffb8d96d..000000000000 --- a/drivers/staging/batman-adv/gateway_client.c +++ /dev/null @@ -1,477 +0,0 @@ -/* - * Copyright (C) 2009-2010 B.A.T.M.A.N. contributors: - * - * Marek Lindner - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License 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. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA - * - */ - -#include "main.h" -#include "gateway_client.h" -#include "gateway_common.h" -#include "hard-interface.h" -#include -#include -#include -#include - -static void gw_node_free_ref(struct kref *refcount) -{ - struct gw_node *gw_node; - - gw_node = container_of(refcount, struct gw_node, refcount); - kfree(gw_node); -} - -static void gw_node_free_rcu(struct rcu_head *rcu) -{ - struct gw_node *gw_node; - - gw_node = container_of(rcu, struct gw_node, rcu); - kref_put(&gw_node->refcount, gw_node_free_ref); -} - -void *gw_get_selected(struct bat_priv *bat_priv) -{ - struct gw_node *curr_gateway_tmp = bat_priv->curr_gw; - - if (!curr_gateway_tmp) - return NULL; - - return curr_gateway_tmp->orig_node; -} - -void gw_deselect(struct bat_priv *bat_priv) -{ - struct gw_node *gw_node = bat_priv->curr_gw; - - bat_priv->curr_gw = NULL; - - if (gw_node) - kref_put(&gw_node->refcount, gw_node_free_ref); -} - -static struct gw_node *gw_select(struct bat_priv *bat_priv, - struct gw_node *new_gw_node) -{ - struct gw_node *curr_gw_node = bat_priv->curr_gw; - - if (new_gw_node) - kref_get(&new_gw_node->refcount); - - bat_priv->curr_gw = new_gw_node; - return curr_gw_node; -} - -void gw_election(struct bat_priv *bat_priv) -{ - struct hlist_node *node; - struct gw_node *gw_node, *curr_gw_tmp = NULL, *old_gw_node = NULL; - uint8_t max_tq = 0; - uint32_t max_gw_factor = 0, tmp_gw_factor = 0; - int down, up; - - /** - * The batman daemon checks here if we already passed a full originator - * cycle in order to make sure we don't choose the first gateway we - * hear about. This check is based on the daemon's uptime which we - * don't have. - **/ - if (atomic_read(&bat_priv->gw_mode) != GW_MODE_CLIENT) - return; - - if (bat_priv->curr_gw) - return; - - rcu_read_lock(); - if (hlist_empty(&bat_priv->gw_list)) { - rcu_read_unlock(); - - if (bat_priv->curr_gw) { - bat_dbg(DBG_BATMAN, bat_priv, - "Removing selected gateway - " - "no gateway in range\n"); - gw_deselect(bat_priv); - } - - return; - } - - hlist_for_each_entry_rcu(gw_node, node, &bat_priv->gw_list, list) { - if (!gw_node->orig_node->router) - continue; - - if (gw_node->deleted) - continue; - - switch (atomic_read(&bat_priv->gw_sel_class)) { - case 1: /* fast connection */ - gw_bandwidth_to_kbit(gw_node->orig_node->gw_flags, - &down, &up); - - tmp_gw_factor = (gw_node->orig_node->router->tq_avg * - gw_node->orig_node->router->tq_avg * - down * 100 * 100) / - (TQ_LOCAL_WINDOW_SIZE * - TQ_LOCAL_WINDOW_SIZE * 64); - - if ((tmp_gw_factor > max_gw_factor) || - ((tmp_gw_factor == max_gw_factor) && - (gw_node->orig_node->router->tq_avg > max_tq))) - curr_gw_tmp = gw_node; - break; - - default: /** - * 2: stable connection (use best statistic) - * 3: fast-switch (use best statistic but change as - * soon as a better gateway appears) - * XX: late-switch (use best statistic but change as - * soon as a better gateway appears which has - * $routing_class more tq points) - **/ - if (gw_node->orig_node->router->tq_avg > max_tq) - curr_gw_tmp = gw_node; - break; - } - - if (gw_node->orig_node->router->tq_avg > max_tq) - max_tq = gw_node->orig_node->router->tq_avg; - - if (tmp_gw_factor > max_gw_factor) - max_gw_factor = tmp_gw_factor; - } - - if (bat_priv->curr_gw != curr_gw_tmp) { - if ((bat_priv->curr_gw) && (!curr_gw_tmp)) - bat_dbg(DBG_BATMAN, bat_priv, - "Removing selected gateway - " - "no gateway in range\n"); - else if ((!bat_priv->curr_gw) && (curr_gw_tmp)) - bat_dbg(DBG_BATMAN, bat_priv, - "Adding route to gateway %pM " - "(gw_flags: %i, tq: %i)\n", - curr_gw_tmp->orig_node->orig, - curr_gw_tmp->orig_node->gw_flags, - curr_gw_tmp->orig_node->router->tq_avg); - else - bat_dbg(DBG_BATMAN, bat_priv, - "Changing route to gateway %pM " - "(gw_flags: %i, tq: %i)\n", - curr_gw_tmp->orig_node->orig, - curr_gw_tmp->orig_node->gw_flags, - curr_gw_tmp->orig_node->router->tq_avg); - - old_gw_node = gw_select(bat_priv, curr_gw_tmp); - } - - rcu_read_unlock(); - - /* the kfree() has to be outside of the rcu lock */ - if (old_gw_node) - kref_put(&old_gw_node->refcount, gw_node_free_ref); -} - -void gw_check_election(struct bat_priv *bat_priv, struct orig_node *orig_node) -{ - struct gw_node *curr_gateway_tmp = bat_priv->curr_gw; - uint8_t gw_tq_avg, orig_tq_avg; - - if (!curr_gateway_tmp) - return; - - if (!curr_gateway_tmp->orig_node) - goto deselect; - - if (!curr_gateway_tmp->orig_node->router) - goto deselect; - - /* this node already is the gateway */ - if (curr_gateway_tmp->orig_node == orig_node) - return; - - if (!orig_node->router) - return; - - gw_tq_avg = curr_gateway_tmp->orig_node->router->tq_avg; - orig_tq_avg = orig_node->router->tq_avg; - - /* the TQ value has to be better */ - if (orig_tq_avg < gw_tq_avg) - return; - - /** - * if the routing class is greater than 3 the value tells us how much - * greater the TQ value of the new gateway must be - **/ - if ((atomic_read(&bat_priv->gw_sel_class) > 3) && - (orig_tq_avg - gw_tq_avg < atomic_read(&bat_priv->gw_sel_class))) - return; - - bat_dbg(DBG_BATMAN, bat_priv, - "Restarting gateway selection: better gateway found (tq curr: " - "%i, tq new: %i)\n", - gw_tq_avg, orig_tq_avg); - -deselect: - gw_deselect(bat_priv); -} - -static void gw_node_add(struct bat_priv *bat_priv, - struct orig_node *orig_node, uint8_t new_gwflags) -{ - struct gw_node *gw_node; - int down, up; - - gw_node = kmalloc(sizeof(struct gw_node), GFP_ATOMIC); - if (!gw_node) - return; - - memset(gw_node, 0, sizeof(struct gw_node)); - INIT_HLIST_NODE(&gw_node->list); - gw_node->orig_node = orig_node; - kref_init(&gw_node->refcount); - - spin_lock_bh(&bat_priv->gw_list_lock); - hlist_add_head_rcu(&gw_node->list, &bat_priv->gw_list); - spin_unlock_bh(&bat_priv->gw_list_lock); - - gw_bandwidth_to_kbit(new_gwflags, &down, &up); - bat_dbg(DBG_BATMAN, bat_priv, - "Found new gateway %pM -> gw_class: %i - %i%s/%i%s\n", - orig_node->orig, new_gwflags, - (down > 2048 ? down / 1024 : down), - (down > 2048 ? "MBit" : "KBit"), - (up > 2048 ? up / 1024 : up), - (up > 2048 ? "MBit" : "KBit")); -} - -void gw_node_update(struct bat_priv *bat_priv, - struct orig_node *orig_node, uint8_t new_gwflags) -{ - struct hlist_node *node; - struct gw_node *gw_node; - - rcu_read_lock(); - hlist_for_each_entry_rcu(gw_node, node, &bat_priv->gw_list, list) { - if (gw_node->orig_node != orig_node) - continue; - - bat_dbg(DBG_BATMAN, bat_priv, - "Gateway class of originator %pM changed from " - "%i to %i\n", - orig_node->orig, gw_node->orig_node->gw_flags, - new_gwflags); - - gw_node->deleted = 0; - - if (new_gwflags == 0) { - gw_node->deleted = jiffies; - bat_dbg(DBG_BATMAN, bat_priv, - "Gateway %pM removed from gateway list\n", - orig_node->orig); - - if (gw_node == bat_priv->curr_gw) { - rcu_read_unlock(); - gw_deselect(bat_priv); - return; - } - } - - rcu_read_unlock(); - return; - } - rcu_read_unlock(); - - if (new_gwflags == 0) - return; - - gw_node_add(bat_priv, orig_node, new_gwflags); -} - -void gw_node_delete(struct bat_priv *bat_priv, struct orig_node *orig_node) -{ - return gw_node_update(bat_priv, orig_node, 0); -} - -void gw_node_purge(struct bat_priv *bat_priv) -{ - struct gw_node *gw_node; - struct hlist_node *node, *node_tmp; - unsigned long timeout = 2 * PURGE_TIMEOUT * HZ; - - spin_lock_bh(&bat_priv->gw_list_lock); - - hlist_for_each_entry_safe(gw_node, node, node_tmp, - &bat_priv->gw_list, list) { - if (((!gw_node->deleted) || - (time_before(jiffies, gw_node->deleted + timeout))) && - atomic_read(&bat_priv->mesh_state) == MESH_ACTIVE) - continue; - - if (bat_priv->curr_gw == gw_node) - gw_deselect(bat_priv); - - hlist_del_rcu(&gw_node->list); - call_rcu(&gw_node->rcu, gw_node_free_rcu); - } - - - spin_unlock_bh(&bat_priv->gw_list_lock); -} - -static int _write_buffer_text(struct bat_priv *bat_priv, - struct seq_file *seq, struct gw_node *gw_node) -{ - int down, up; - - gw_bandwidth_to_kbit(gw_node->orig_node->gw_flags, &down, &up); - - return seq_printf(seq, "%s %pM (%3i) %pM [%10s]: %3i - %i%s/%i%s\n", - (bat_priv->curr_gw == gw_node ? "=>" : " "), - gw_node->orig_node->orig, - gw_node->orig_node->router->tq_avg, - gw_node->orig_node->router->addr, - gw_node->orig_node->router->if_incoming->net_dev->name, - gw_node->orig_node->gw_flags, - (down > 2048 ? down / 1024 : down), - (down > 2048 ? "MBit" : "KBit"), - (up > 2048 ? up / 1024 : up), - (up > 2048 ? "MBit" : "KBit")); -} - -int gw_client_seq_print_text(struct seq_file *seq, void *offset) -{ - struct net_device *net_dev = (struct net_device *)seq->private; - struct bat_priv *bat_priv = netdev_priv(net_dev); - struct gw_node *gw_node; - struct hlist_node *node; - int gw_count = 0; - - if (!bat_priv->primary_if) { - - return seq_printf(seq, "BATMAN mesh %s disabled - please " - "specify interfaces to enable it\n", - net_dev->name); - } - - if (bat_priv->primary_if->if_status != IF_ACTIVE) { - - return seq_printf(seq, "BATMAN mesh %s disabled - " - "primary interface not active\n", - net_dev->name); - } - - seq_printf(seq, " %-12s (%s/%i) %17s [%10s]: gw_class ... " - "[B.A.T.M.A.N. adv %s%s, MainIF/MAC: %s/%pM (%s)]\n", - "Gateway", "#", TQ_MAX_VALUE, "Nexthop", - "outgoingIF", SOURCE_VERSION, REVISION_VERSION_STR, - bat_priv->primary_if->net_dev->name, - bat_priv->primary_if->net_dev->dev_addr, net_dev->name); - - rcu_read_lock(); - hlist_for_each_entry_rcu(gw_node, node, &bat_priv->gw_list, list) { - if (gw_node->deleted) - continue; - - if (!gw_node->orig_node->router) - continue; - - _write_buffer_text(bat_priv, seq, gw_node); - gw_count++; - } - rcu_read_unlock(); - - if (gw_count == 0) - seq_printf(seq, "No gateways in range ...\n"); - - return 0; -} - -int gw_is_target(struct bat_priv *bat_priv, struct sk_buff *skb) -{ - struct ethhdr *ethhdr; - struct iphdr *iphdr; - struct ipv6hdr *ipv6hdr; - struct udphdr *udphdr; - unsigned int header_len = 0; - - if (atomic_read(&bat_priv->gw_mode) == GW_MODE_OFF) - return 0; - - /* check for ethernet header */ - if (!pskb_may_pull(skb, header_len + ETH_HLEN)) - return 0; - ethhdr = (struct ethhdr *)skb->data; - header_len += ETH_HLEN; - - /* check for initial vlan header */ - if (ntohs(ethhdr->h_proto) == ETH_P_8021Q) { - if (!pskb_may_pull(skb, header_len + VLAN_HLEN)) - return 0; - ethhdr = (struct ethhdr *)(skb->data + VLAN_HLEN); - header_len += VLAN_HLEN; - } - - /* check for ip header */ - switch (ntohs(ethhdr->h_proto)) { - case ETH_P_IP: - if (!pskb_may_pull(skb, header_len + sizeof(struct iphdr))) - return 0; - iphdr = (struct iphdr *)(skb->data + header_len); - header_len += iphdr->ihl * 4; - - /* check for udp header */ - if (iphdr->protocol != IPPROTO_UDP) - return 0; - - break; - case ETH_P_IPV6: - if (!pskb_may_pull(skb, header_len + sizeof(struct ipv6hdr))) - return 0; - ipv6hdr = (struct ipv6hdr *)(skb->data + header_len); - header_len += sizeof(struct ipv6hdr); - - /* check for udp header */ - if (ipv6hdr->nexthdr != IPPROTO_UDP) - return 0; - - break; - default: - return 0; - } - - if (!pskb_may_pull(skb, header_len + sizeof(struct udphdr))) - return 0; - udphdr = (struct udphdr *)(skb->data + header_len); - header_len += sizeof(struct udphdr); - - /* check for bootp port */ - if ((ntohs(ethhdr->h_proto) == ETH_P_IP) && - (ntohs(udphdr->dest) != 67)) - return 0; - - if ((ntohs(ethhdr->h_proto) == ETH_P_IPV6) && - (ntohs(udphdr->dest) != 547)) - return 0; - - if (atomic_read(&bat_priv->gw_mode) == GW_MODE_SERVER) - return -1; - - if (!bat_priv->curr_gw) - return 0; - - return 1; -} diff --git a/drivers/staging/batman-adv/gateway_client.h b/drivers/staging/batman-adv/gateway_client.h deleted file mode 100644 index 4585e6549844..000000000000 --- a/drivers/staging/batman-adv/gateway_client.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (C) 2009-2010 B.A.T.M.A.N. contributors: - * - * Marek Lindner - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License 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. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA - * - */ - -#ifndef _NET_BATMAN_ADV_GATEWAY_CLIENT_H_ -#define _NET_BATMAN_ADV_GATEWAY_CLIENT_H_ - -void gw_deselect(struct bat_priv *bat_priv); -void gw_election(struct bat_priv *bat_priv); -void *gw_get_selected(struct bat_priv *bat_priv); -void gw_check_election(struct bat_priv *bat_priv, struct orig_node *orig_node); -void gw_node_update(struct bat_priv *bat_priv, - struct orig_node *orig_node, uint8_t new_gwflags); -void gw_node_delete(struct bat_priv *bat_priv, struct orig_node *orig_node); -void gw_node_purge(struct bat_priv *bat_priv); -int gw_client_seq_print_text(struct seq_file *seq, void *offset); -int gw_is_target(struct bat_priv *bat_priv, struct sk_buff *skb); - -#endif /* _NET_BATMAN_ADV_GATEWAY_CLIENT_H_ */ diff --git a/drivers/staging/batman-adv/gateway_common.c b/drivers/staging/batman-adv/gateway_common.c deleted file mode 100644 index b962982f017e..000000000000 --- a/drivers/staging/batman-adv/gateway_common.c +++ /dev/null @@ -1,177 +0,0 @@ -/* - * Copyright (C) 2009-2010 B.A.T.M.A.N. contributors: - * - * Marek Lindner - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License 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. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA - * - */ - -#include "main.h" -#include "gateway_common.h" -#include "gateway_client.h" - -/* calculates the gateway class from kbit */ -static void kbit_to_gw_bandwidth(int down, int up, long *gw_srv_class) -{ - int mdown = 0, tdown, tup, difference; - uint8_t sbit, part; - - *gw_srv_class = 0; - difference = 0x0FFFFFFF; - - /* test all downspeeds */ - for (sbit = 0; sbit < 2; sbit++) { - for (part = 0; part < 16; part++) { - tdown = 32 * (sbit + 2) * (1 << part); - - if (abs(tdown - down) < difference) { - *gw_srv_class = (sbit << 7) + (part << 3); - difference = abs(tdown - down); - mdown = tdown; - } - } - } - - /* test all upspeeds */ - difference = 0x0FFFFFFF; - - for (part = 0; part < 8; part++) { - tup = ((part + 1) * (mdown)) / 8; - - if (abs(tup - up) < difference) { - *gw_srv_class = (*gw_srv_class & 0xF8) | part; - difference = abs(tup - up); - } - } -} - -/* returns the up and downspeeds in kbit, calculated from the class */ -void gw_bandwidth_to_kbit(uint8_t gw_srv_class, int *down, int *up) -{ - char sbit = (gw_srv_class & 0x80) >> 7; - char dpart = (gw_srv_class & 0x78) >> 3; - char upart = (gw_srv_class & 0x07); - - if (!gw_srv_class) { - *down = 0; - *up = 0; - return; - } - - *down = 32 * (sbit + 2) * (1 << dpart); - *up = ((upart + 1) * (*down)) / 8; -} - -static bool parse_gw_bandwidth(struct net_device *net_dev, char *buff, - long *up, long *down) -{ - int ret, multi = 1; - char *slash_ptr, *tmp_ptr; - - slash_ptr = strchr(buff, '/'); - if (slash_ptr) - *slash_ptr = 0; - - if (strlen(buff) > 4) { - tmp_ptr = buff + strlen(buff) - 4; - - if (strnicmp(tmp_ptr, "mbit", 4) == 0) - multi = 1024; - - if ((strnicmp(tmp_ptr, "kbit", 4) == 0) || - (multi > 1)) - *tmp_ptr = '\0'; - } - - ret = strict_strtoul(buff, 10, down); - if (ret) { - bat_err(net_dev, - "Download speed of gateway mode invalid: %s\n", - buff); - return false; - } - - *down *= multi; - - /* we also got some upload info */ - if (slash_ptr) { - multi = 1; - - if (strlen(slash_ptr + 1) > 4) { - tmp_ptr = slash_ptr + 1 - 4 + strlen(slash_ptr + 1); - - if (strnicmp(tmp_ptr, "mbit", 4) == 0) - multi = 1024; - - if ((strnicmp(tmp_ptr, "kbit", 4) == 0) || - (multi > 1)) - *tmp_ptr = '\0'; - } - - ret = strict_strtoul(slash_ptr + 1, 10, up); - if (ret) { - bat_err(net_dev, - "Upload speed of gateway mode invalid: " - "%s\n", slash_ptr + 1); - return false; - } - - *up *= multi; - } - - return true; -} - -ssize_t gw_bandwidth_set(struct net_device *net_dev, char *buff, size_t count) -{ - struct bat_priv *bat_priv = netdev_priv(net_dev); - long gw_bandwidth_tmp = 0, up = 0, down = 0; - bool ret; - - ret = parse_gw_bandwidth(net_dev, buff, &up, &down); - if (!ret) - goto end; - - if ((!down) || (down < 256)) - down = 2000; - - if (!up) - up = down / 5; - - kbit_to_gw_bandwidth(down, up, &gw_bandwidth_tmp); - - /** - * the gw bandwidth we guessed above might not match the given - * speeds, hence we need to calculate it back to show the number - * that is going to be propagated - **/ - gw_bandwidth_to_kbit((uint8_t)gw_bandwidth_tmp, - (int *)&down, (int *)&up); - - gw_deselect(bat_priv); - bat_info(net_dev, "Changing gateway bandwidth from: '%i' to: '%ld' " - "(propagating: %ld%s/%ld%s)\n", - atomic_read(&bat_priv->gw_bandwidth), gw_bandwidth_tmp, - (down > 2048 ? down / 1024 : down), - (down > 2048 ? "MBit" : "KBit"), - (up > 2048 ? up / 1024 : up), - (up > 2048 ? "MBit" : "KBit")); - - atomic_set(&bat_priv->gw_bandwidth, gw_bandwidth_tmp); - -end: - return count; -} diff --git a/drivers/staging/batman-adv/gateway_common.h b/drivers/staging/batman-adv/gateway_common.h deleted file mode 100644 index 5e728d0b7959..000000000000 --- a/drivers/staging/batman-adv/gateway_common.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (C) 2009-2010 B.A.T.M.A.N. contributors: - * - * Marek Lindner - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License 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. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA - * - */ - -#ifndef _NET_BATMAN_ADV_GATEWAY_COMMON_H_ -#define _NET_BATMAN_ADV_GATEWAY_COMMON_H_ - -enum gw_modes { - GW_MODE_OFF, - GW_MODE_CLIENT, - GW_MODE_SERVER, -}; - -#define GW_MODE_OFF_NAME "off" -#define GW_MODE_CLIENT_NAME "client" -#define GW_MODE_SERVER_NAME "server" - -void gw_bandwidth_to_kbit(uint8_t gw_class, int *down, int *up); -ssize_t gw_bandwidth_set(struct net_device *net_dev, char *buff, size_t count); - -#endif /* _NET_BATMAN_ADV_GATEWAY_COMMON_H_ */ diff --git a/drivers/staging/batman-adv/hard-interface.c b/drivers/staging/batman-adv/hard-interface.c deleted file mode 100644 index c3c7b7ac0946..000000000000 --- a/drivers/staging/batman-adv/hard-interface.c +++ /dev/null @@ -1,652 +0,0 @@ -/* - * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: - * - * Marek Lindner, Simon Wunderlich - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License 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. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA - * - */ - -#include "main.h" -#include "hard-interface.h" -#include "soft-interface.h" -#include "send.h" -#include "translation-table.h" -#include "routing.h" -#include "bat_sysfs.h" -#include "originator.h" -#include "hash.h" - -#include - -/* protect update critical side of if_list - but not the content */ -static DEFINE_SPINLOCK(if_list_lock); - -static void hardif_free_rcu(struct rcu_head *rcu) -{ - struct batman_if *batman_if; - - batman_if = container_of(rcu, struct batman_if, rcu); - dev_put(batman_if->net_dev); - kref_put(&batman_if->refcount, hardif_free_ref); -} - -struct batman_if *get_batman_if_by_netdev(struct net_device *net_dev) -{ - struct batman_if *batman_if; - - rcu_read_lock(); - list_for_each_entry_rcu(batman_if, &if_list, list) { - if (batman_if->net_dev == net_dev) - goto out; - } - - batman_if = NULL; - -out: - if (batman_if) - kref_get(&batman_if->refcount); - - rcu_read_unlock(); - return batman_if; -} - -static int is_valid_iface(struct net_device *net_dev) -{ - if (net_dev->flags & IFF_LOOPBACK) - return 0; - - if (net_dev->type != ARPHRD_ETHER) - return 0; - - if (net_dev->addr_len != ETH_ALEN) - return 0; - - /* no batman over batman */ -#ifdef HAVE_NET_DEVICE_OPS - if (net_dev->netdev_ops->ndo_start_xmit == interface_tx) - return 0; -#else - if (net_dev->hard_start_xmit == interface_tx) - return 0; -#endif - - /* Device is being bridged */ - /* if (net_dev->priv_flags & IFF_BRIDGE_PORT) - return 0; */ - - return 1; -} - -static struct batman_if *get_active_batman_if(struct net_device *soft_iface) -{ - struct batman_if *batman_if; - - rcu_read_lock(); - list_for_each_entry_rcu(batman_if, &if_list, list) { - if (batman_if->soft_iface != soft_iface) - continue; - - if (batman_if->if_status == IF_ACTIVE) - goto out; - } - - batman_if = NULL; - -out: - if (batman_if) - kref_get(&batman_if->refcount); - - rcu_read_unlock(); - return batman_if; -} - -static void update_primary_addr(struct bat_priv *bat_priv) -{ - struct vis_packet *vis_packet; - - vis_packet = (struct vis_packet *) - bat_priv->my_vis_info->skb_packet->data; - memcpy(vis_packet->vis_orig, - bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN); - memcpy(vis_packet->sender_orig, - bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN); -} - -static void set_primary_if(struct bat_priv *bat_priv, - struct batman_if *batman_if) -{ - struct batman_packet *batman_packet; - struct batman_if *old_if; - - if (batman_if) - kref_get(&batman_if->refcount); - - old_if = bat_priv->primary_if; - bat_priv->primary_if = batman_if; - - if (old_if) - kref_put(&old_if->refcount, hardif_free_ref); - - if (!bat_priv->primary_if) - return; - - batman_packet = (struct batman_packet *)(batman_if->packet_buff); - batman_packet->flags = PRIMARIES_FIRST_HOP; - batman_packet->ttl = TTL; - - update_primary_addr(bat_priv); - - /*** - * hacky trick to make sure that we send the HNA information via - * our new primary interface - */ - atomic_set(&bat_priv->hna_local_changed, 1); -} - -static bool hardif_is_iface_up(struct batman_if *batman_if) -{ - if (batman_if->net_dev->flags & IFF_UP) - return true; - - return false; -} - -static void update_mac_addresses(struct batman_if *batman_if) -{ - memcpy(((struct batman_packet *)(batman_if->packet_buff))->orig, - batman_if->net_dev->dev_addr, ETH_ALEN); - memcpy(((struct batman_packet *)(batman_if->packet_buff))->prev_sender, - batman_if->net_dev->dev_addr, ETH_ALEN); -} - -static void check_known_mac_addr(struct net_device *net_dev) -{ - struct batman_if *batman_if; - - rcu_read_lock(); - list_for_each_entry_rcu(batman_if, &if_list, list) { - if ((batman_if->if_status != IF_ACTIVE) && - (batman_if->if_status != IF_TO_BE_ACTIVATED)) - continue; - - if (batman_if->net_dev == net_dev) - continue; - - if (!compare_orig(batman_if->net_dev->dev_addr, - net_dev->dev_addr)) - continue; - - pr_warning("The newly added mac address (%pM) already exists " - "on: %s\n", net_dev->dev_addr, - batman_if->net_dev->name); - pr_warning("It is strongly recommended to keep mac addresses " - "unique to avoid problems!\n"); - } - rcu_read_unlock(); -} - -int hardif_min_mtu(struct net_device *soft_iface) -{ - struct bat_priv *bat_priv = netdev_priv(soft_iface); - struct batman_if *batman_if; - /* allow big frames if all devices are capable to do so - * (have MTU > 1500 + BAT_HEADER_LEN) */ - int min_mtu = ETH_DATA_LEN; - - if (atomic_read(&bat_priv->fragmentation)) - goto out; - - rcu_read_lock(); - list_for_each_entry_rcu(batman_if, &if_list, list) { - if ((batman_if->if_status != IF_ACTIVE) && - (batman_if->if_status != IF_TO_BE_ACTIVATED)) - continue; - - if (batman_if->soft_iface != soft_iface) - continue; - - min_mtu = min_t(int, batman_if->net_dev->mtu - BAT_HEADER_LEN, - min_mtu); - } - rcu_read_unlock(); -out: - return min_mtu; -} - -/* adjusts the MTU if a new interface with a smaller MTU appeared. */ -void update_min_mtu(struct net_device *soft_iface) -{ - int min_mtu; - - min_mtu = hardif_min_mtu(soft_iface); - if (soft_iface->mtu != min_mtu) - soft_iface->mtu = min_mtu; -} - -static void hardif_activate_interface(struct batman_if *batman_if) -{ - struct bat_priv *bat_priv; - - if (batman_if->if_status != IF_INACTIVE) - return; - - bat_priv = netdev_priv(batman_if->soft_iface); - - update_mac_addresses(batman_if); - batman_if->if_status = IF_TO_BE_ACTIVATED; - - /** - * the first active interface becomes our primary interface or - * the next active interface after the old primay interface was removed - */ - if (!bat_priv->primary_if) - set_primary_if(bat_priv, batman_if); - - bat_info(batman_if->soft_iface, "Interface activated: %s\n", - batman_if->net_dev->name); - - update_min_mtu(batman_if->soft_iface); - return; -} - -static void hardif_deactivate_interface(struct batman_if *batman_if) -{ - if ((batman_if->if_status != IF_ACTIVE) && - (batman_if->if_status != IF_TO_BE_ACTIVATED)) - return; - - batman_if->if_status = IF_INACTIVE; - - bat_info(batman_if->soft_iface, "Interface deactivated: %s\n", - batman_if->net_dev->name); - - update_min_mtu(batman_if->soft_iface); -} - -int hardif_enable_interface(struct batman_if *batman_if, char *iface_name) -{ - struct bat_priv *bat_priv; - struct batman_packet *batman_packet; - - if (batman_if->if_status != IF_NOT_IN_USE) - goto out; - - batman_if->soft_iface = dev_get_by_name(&init_net, iface_name); - - if (!batman_if->soft_iface) { - batman_if->soft_iface = softif_create(iface_name); - - if (!batman_if->soft_iface) - goto err; - - /* dev_get_by_name() increases the reference counter for us */ - dev_hold(batman_if->soft_iface); - } - - bat_priv = netdev_priv(batman_if->soft_iface); - batman_if->packet_len = BAT_PACKET_LEN; - batman_if->packet_buff = kmalloc(batman_if->packet_len, GFP_ATOMIC); - - if (!batman_if->packet_buff) { - bat_err(batman_if->soft_iface, "Can't add interface packet " - "(%s): out of memory\n", batman_if->net_dev->name); - goto err; - } - - batman_packet = (struct batman_packet *)(batman_if->packet_buff); - batman_packet->packet_type = BAT_PACKET; - batman_packet->version = COMPAT_VERSION; - batman_packet->flags = 0; - batman_packet->ttl = 2; - batman_packet->tq = TQ_MAX_VALUE; - batman_packet->num_hna = 0; - - batman_if->if_num = bat_priv->num_ifaces; - bat_priv->num_ifaces++; - batman_if->if_status = IF_INACTIVE; - orig_hash_add_if(batman_if, bat_priv->num_ifaces); - - batman_if->batman_adv_ptype.type = __constant_htons(ETH_P_BATMAN); - batman_if->batman_adv_ptype.func = batman_skb_recv; - batman_if->batman_adv_ptype.dev = batman_if->net_dev; - kref_get(&batman_if->refcount); - dev_add_pack(&batman_if->batman_adv_ptype); - - atomic_set(&batman_if->seqno, 1); - atomic_set(&batman_if->frag_seqno, 1); - bat_info(batman_if->soft_iface, "Adding interface: %s\n", - batman_if->net_dev->name); - - if (atomic_read(&bat_priv->fragmentation) && batman_if->net_dev->mtu < - ETH_DATA_LEN + BAT_HEADER_LEN) - bat_info(batman_if->soft_iface, - "The MTU of interface %s is too small (%i) to handle " - "the transport of batman-adv packets. Packets going " - "over this interface will be fragmented on layer2 " - "which could impact the performance. Setting the MTU " - "to %zi would solve the problem.\n", - batman_if->net_dev->name, batman_if->net_dev->mtu, - ETH_DATA_LEN + BAT_HEADER_LEN); - - if (!atomic_read(&bat_priv->fragmentation) && batman_if->net_dev->mtu < - ETH_DATA_LEN + BAT_HEADER_LEN) - bat_info(batman_if->soft_iface, - "The MTU of interface %s is too small (%i) to handle " - "the transport of batman-adv packets. If you experience" - " problems getting traffic through try increasing the " - "MTU to %zi.\n", - batman_if->net_dev->name, batman_if->net_dev->mtu, - ETH_DATA_LEN + BAT_HEADER_LEN); - - if (hardif_is_iface_up(batman_if)) - hardif_activate_interface(batman_if); - else - bat_err(batman_if->soft_iface, "Not using interface %s " - "(retrying later): interface not active\n", - batman_if->net_dev->name); - - /* begin scheduling originator messages on that interface */ - schedule_own_packet(batman_if); - -out: - return 0; - -err: - return -ENOMEM; -} - -void hardif_disable_interface(struct batman_if *batman_if) -{ - struct bat_priv *bat_priv = netdev_priv(batman_if->soft_iface); - - if (batman_if->if_status == IF_ACTIVE) - hardif_deactivate_interface(batman_if); - - if (batman_if->if_status != IF_INACTIVE) - return; - - bat_info(batman_if->soft_iface, "Removing interface: %s\n", - batman_if->net_dev->name); - dev_remove_pack(&batman_if->batman_adv_ptype); - kref_put(&batman_if->refcount, hardif_free_ref); - - bat_priv->num_ifaces--; - orig_hash_del_if(batman_if, bat_priv->num_ifaces); - - if (batman_if == bat_priv->primary_if) { - struct batman_if *new_if; - - new_if = get_active_batman_if(batman_if->soft_iface); - set_primary_if(bat_priv, new_if); - - if (new_if) - kref_put(&new_if->refcount, hardif_free_ref); - } - - kfree(batman_if->packet_buff); - batman_if->packet_buff = NULL; - batman_if->if_status = IF_NOT_IN_USE; - - /* delete all references to this batman_if */ - purge_orig_ref(bat_priv); - purge_outstanding_packets(bat_priv, batman_if); - dev_put(batman_if->soft_iface); - - /* nobody uses this interface anymore */ - if (!bat_priv->num_ifaces) - softif_destroy(batman_if->soft_iface); - - batman_if->soft_iface = NULL; -} - -static struct batman_if *hardif_add_interface(struct net_device *net_dev) -{ - struct batman_if *batman_if; - int ret; - - ret = is_valid_iface(net_dev); - if (ret != 1) - goto out; - - dev_hold(net_dev); - - batman_if = kmalloc(sizeof(struct batman_if), GFP_ATOMIC); - if (!batman_if) { - pr_err("Can't add interface (%s): out of memory\n", - net_dev->name); - goto release_dev; - } - - ret = sysfs_add_hardif(&batman_if->hardif_obj, net_dev); - if (ret) - goto free_if; - - batman_if->if_num = -1; - batman_if->net_dev = net_dev; - batman_if->soft_iface = NULL; - batman_if->if_status = IF_NOT_IN_USE; - INIT_LIST_HEAD(&batman_if->list); - kref_init(&batman_if->refcount); - - check_known_mac_addr(batman_if->net_dev); - - spin_lock(&if_list_lock); - list_add_tail_rcu(&batman_if->list, &if_list); - spin_unlock(&if_list_lock); - - /* extra reference for return */ - kref_get(&batman_if->refcount); - return batman_if; - -free_if: - kfree(batman_if); -release_dev: - dev_put(net_dev); -out: - return NULL; -} - -static void hardif_remove_interface(struct batman_if *batman_if) -{ - /* first deactivate interface */ - if (batman_if->if_status != IF_NOT_IN_USE) - hardif_disable_interface(batman_if); - - if (batman_if->if_status != IF_NOT_IN_USE) - return; - - batman_if->if_status = IF_TO_BE_REMOVED; - synchronize_rcu(); - sysfs_del_hardif(&batman_if->hardif_obj); - call_rcu(&batman_if->rcu, hardif_free_rcu); -} - -void hardif_remove_interfaces(void) -{ - struct batman_if *batman_if, *batman_if_tmp; - struct list_head if_queue; - - INIT_LIST_HEAD(&if_queue); - - spin_lock(&if_list_lock); - list_for_each_entry_safe(batman_if, batman_if_tmp, &if_list, list) { - list_del_rcu(&batman_if->list); - list_add_tail(&batman_if->list, &if_queue); - } - spin_unlock(&if_list_lock); - - rtnl_lock(); - list_for_each_entry_safe(batman_if, batman_if_tmp, &if_queue, list) { - hardif_remove_interface(batman_if); - } - rtnl_unlock(); -} - -static int hard_if_event(struct notifier_block *this, - unsigned long event, void *ptr) -{ - struct net_device *net_dev = (struct net_device *)ptr; - struct batman_if *batman_if = get_batman_if_by_netdev(net_dev); - struct bat_priv *bat_priv; - - if (!batman_if && event == NETDEV_REGISTER) - batman_if = hardif_add_interface(net_dev); - - if (!batman_if) - goto out; - - switch (event) { - case NETDEV_UP: - hardif_activate_interface(batman_if); - break; - case NETDEV_GOING_DOWN: - case NETDEV_DOWN: - hardif_deactivate_interface(batman_if); - break; - case NETDEV_UNREGISTER: - spin_lock(&if_list_lock); - list_del_rcu(&batman_if->list); - spin_unlock(&if_list_lock); - - hardif_remove_interface(batman_if); - break; - case NETDEV_CHANGEMTU: - if (batman_if->soft_iface) - update_min_mtu(batman_if->soft_iface); - break; - case NETDEV_CHANGEADDR: - if (batman_if->if_status == IF_NOT_IN_USE) - goto hardif_put; - - check_known_mac_addr(batman_if->net_dev); - update_mac_addresses(batman_if); - - bat_priv = netdev_priv(batman_if->soft_iface); - if (batman_if == bat_priv->primary_if) - update_primary_addr(bat_priv); - break; - default: - break; - }; - -hardif_put: - kref_put(&batman_if->refcount, hardif_free_ref); -out: - return NOTIFY_DONE; -} - -/* receive a packet with the batman ethertype coming on a hard - * interface */ -int batman_skb_recv(struct sk_buff *skb, struct net_device *dev, - struct packet_type *ptype, struct net_device *orig_dev) -{ - struct bat_priv *bat_priv; - struct batman_packet *batman_packet; - struct batman_if *batman_if; - int ret; - - batman_if = container_of(ptype, struct batman_if, batman_adv_ptype); - skb = skb_share_check(skb, GFP_ATOMIC); - - /* skb was released by skb_share_check() */ - if (!skb) - goto err_out; - - /* packet should hold at least type and version */ - if (unlikely(!pskb_may_pull(skb, 2))) - goto err_free; - - /* expect a valid ethernet header here. */ - if (unlikely(skb->mac_len != sizeof(struct ethhdr) - || !skb_mac_header(skb))) - goto err_free; - - if (!batman_if->soft_iface) - goto err_free; - - bat_priv = netdev_priv(batman_if->soft_iface); - - if (atomic_read(&bat_priv->mesh_state) != MESH_ACTIVE) - goto err_free; - - /* discard frames on not active interfaces */ - if (batman_if->if_status != IF_ACTIVE) - goto err_free; - - batman_packet = (struct batman_packet *)skb->data; - - if (batman_packet->version != COMPAT_VERSION) { - bat_dbg(DBG_BATMAN, bat_priv, - "Drop packet: incompatible batman version (%i)\n", - batman_packet->version); - goto err_free; - } - - /* all receive handlers return whether they received or reused - * the supplied skb. if not, we have to free the skb. */ - - switch (batman_packet->packet_type) { - /* batman originator packet */ - case BAT_PACKET: - ret = recv_bat_packet(skb, batman_if); - break; - - /* batman icmp packet */ - case BAT_ICMP: - ret = recv_icmp_packet(skb, batman_if); - break; - - /* unicast packet */ - case BAT_UNICAST: - ret = recv_unicast_packet(skb, batman_if); - break; - - /* fragmented unicast packet */ - case BAT_UNICAST_FRAG: - ret = recv_ucast_frag_packet(skb, batman_if); - break; - - /* broadcast packet */ - case BAT_BCAST: - ret = recv_bcast_packet(skb, batman_if); - break; - - /* vis packet */ - case BAT_VIS: - ret = recv_vis_packet(skb, batman_if); - break; - default: - ret = NET_RX_DROP; - } - - if (ret == NET_RX_DROP) - kfree_skb(skb); - - /* return NET_RX_SUCCESS in any case as we - * most probably dropped the packet for - * routing-logical reasons. */ - - return NET_RX_SUCCESS; - -err_free: - kfree_skb(skb); -err_out: - return NET_RX_DROP; -} - -struct notifier_block hard_if_notifier = { - .notifier_call = hard_if_event, -}; diff --git a/drivers/staging/batman-adv/hard-interface.h b/drivers/staging/batman-adv/hard-interface.h deleted file mode 100644 index 30ec3b8db459..000000000000 --- a/drivers/staging/batman-adv/hard-interface.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: - * - * Marek Lindner, Simon Wunderlich - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License 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. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA - * - */ - -#ifndef _NET_BATMAN_ADV_HARD_INTERFACE_H_ -#define _NET_BATMAN_ADV_HARD_INTERFACE_H_ - -#define IF_NOT_IN_USE 0 -#define IF_TO_BE_REMOVED 1 -#define IF_INACTIVE 2 -#define IF_ACTIVE 3 -#define IF_TO_BE_ACTIVATED 4 -#define IF_I_WANT_YOU 5 - -extern struct notifier_block hard_if_notifier; - -struct batman_if *get_batman_if_by_netdev(struct net_device *net_dev); -int hardif_enable_interface(struct batman_if *batman_if, char *iface_name); -void hardif_disable_interface(struct batman_if *batman_if); -void hardif_remove_interfaces(void); -int batman_skb_recv(struct sk_buff *skb, - struct net_device *dev, - struct packet_type *ptype, - struct net_device *orig_dev); -int hardif_min_mtu(struct net_device *soft_iface); -void update_min_mtu(struct net_device *soft_iface); - -static inline void hardif_free_ref(struct kref *refcount) -{ - struct batman_if *batman_if; - - batman_if = container_of(refcount, struct batman_if, refcount); - kfree(batman_if); -} - -#endif /* _NET_BATMAN_ADV_HARD_INTERFACE_H_ */ diff --git a/drivers/staging/batman-adv/hash.c b/drivers/staging/batman-adv/hash.c deleted file mode 100644 index 8605e2fd0427..000000000000 --- a/drivers/staging/batman-adv/hash.c +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (C) 2006-2010 B.A.T.M.A.N. contributors: - * - * Simon Wunderlich, Marek Lindner - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License 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. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA - * - */ - -#include "main.h" -#include "hash.h" - -/* clears the hash */ -static void hash_init(struct hashtable_t *hash) -{ - int i; - - hash->elements = 0; - - for (i = 0 ; i < hash->size; i++) - INIT_HLIST_HEAD(&hash->table[i]); -} - -/* free only the hashtable and the hash itself. */ -void hash_destroy(struct hashtable_t *hash) -{ - kfree(hash->table); - kfree(hash); -} - -/* allocates and clears the hash */ -struct hashtable_t *hash_new(int size) -{ - struct hashtable_t *hash; - - hash = kmalloc(sizeof(struct hashtable_t) , GFP_ATOMIC); - - if (hash == NULL) - return NULL; - - hash->size = size; - hash->table = kmalloc(sizeof(struct element_t *) * size, GFP_ATOMIC); - - if (hash->table == NULL) { - kfree(hash); - return NULL; - } - - hash_init(hash); - - return hash; -} - -/* remove bucket (this might be used in hash_iterate() if you already found the - * bucket you want to delete and don't need the overhead to find it again with - * hash_remove(). But usually, you don't want to use this function, as it - * fiddles with hash-internals. */ -void *hash_remove_bucket(struct hashtable_t *hash, struct hash_it_t *hash_it_t) -{ - void *data_save; - struct element_t *bucket; - - bucket = hlist_entry(hash_it_t->walk, struct element_t, hlist); - data_save = bucket->data; - - hlist_del(hash_it_t->walk); - kfree(bucket); - hash->elements--; - - return data_save; -} diff --git a/drivers/staging/batman-adv/hash.h b/drivers/staging/batman-adv/hash.h deleted file mode 100644 index 0b61c6e3e7cf..000000000000 --- a/drivers/staging/batman-adv/hash.h +++ /dev/null @@ -1,259 +0,0 @@ -/* - * Copyright (C) 2006-2010 B.A.T.M.A.N. contributors: - * - * Simon Wunderlich, Marek Lindner - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License 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. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA - * - */ - -#ifndef _NET_BATMAN_ADV_HASH_H_ -#define _NET_BATMAN_ADV_HASH_H_ - -#include - -#define HASHIT(name) struct hash_it_t name = { \ - .index = 0, .walk = NULL, \ - .safe = NULL} - -/* callback to a compare function. should - * compare 2 element datas for their keys, - * return 0 if same and not 0 if not - * same */ -typedef int (*hashdata_compare_cb)(void *, void *); - -/* the hashfunction, should return an index - * based on the key in the data of the first - * argument and the size the second */ -typedef int (*hashdata_choose_cb)(void *, int); -typedef void (*hashdata_free_cb)(void *, void *); - -struct element_t { - void *data; /* pointer to the data */ - struct hlist_node hlist; /* bucket list pointer */ -}; - -struct hash_it_t { - size_t index; - struct hlist_node *walk; - struct hlist_node *safe; -}; - -struct hashtable_t { - struct hlist_head *table; /* the hashtable itself, with the buckets */ - int elements; /* number of elements registered */ - int size; /* size of hashtable */ -}; - -/* allocates and clears the hash */ -struct hashtable_t *hash_new(int size); - -/* remove bucket (this might be used in hash_iterate() if you already found the - * bucket you want to delete and don't need the overhead to find it again with - * hash_remove(). But usually, you don't want to use this function, as it - * fiddles with hash-internals. */ -void *hash_remove_bucket(struct hashtable_t *hash, struct hash_it_t *hash_it_t); - -/* free only the hashtable and the hash itself. */ -void hash_destroy(struct hashtable_t *hash); - -/* remove the hash structure. if hashdata_free_cb != NULL, this function will be - * called to remove the elements inside of the hash. if you don't remove the - * elements, memory might be leaked. */ -static inline void hash_delete(struct hashtable_t *hash, - hashdata_free_cb free_cb, void *arg) -{ - struct hlist_head *head; - struct hlist_node *walk, *safe; - struct element_t *bucket; - int i; - - for (i = 0; i < hash->size; i++) { - head = &hash->table[i]; - - hlist_for_each_safe(walk, safe, head) { - bucket = hlist_entry(walk, struct element_t, hlist); - if (free_cb != NULL) - free_cb(bucket->data, arg); - - hlist_del(walk); - kfree(bucket); - } - } - - hash_destroy(hash); -} - -/* adds data to the hashtable. returns 0 on success, -1 on error */ -static inline int hash_add(struct hashtable_t *hash, - hashdata_compare_cb compare, - hashdata_choose_cb choose, void *data) -{ - int index; - struct hlist_head *head; - struct hlist_node *walk, *safe; - struct element_t *bucket; - - if (!hash) - return -1; - - index = choose(data, hash->size); - head = &hash->table[index]; - - hlist_for_each_safe(walk, safe, head) { - bucket = hlist_entry(walk, struct element_t, hlist); - if (compare(bucket->data, data)) - return -1; - } - - /* no duplicate found in list, add new element */ - bucket = kmalloc(sizeof(struct element_t), GFP_ATOMIC); - - if (bucket == NULL) - return -1; - - bucket->data = data; - hlist_add_head(&bucket->hlist, head); - - hash->elements++; - return 0; -} - -/* removes data from hash, if found. returns pointer do data on success, so you - * can remove the used structure yourself, or NULL on error . data could be the - * structure you use with just the key filled, we just need the key for - * comparing. */ -static inline void *hash_remove(struct hashtable_t *hash, - hashdata_compare_cb compare, - hashdata_choose_cb choose, void *data) -{ - struct hash_it_t hash_it_t; - struct element_t *bucket; - struct hlist_head *head; - - hash_it_t.index = choose(data, hash->size); - head = &hash->table[hash_it_t.index]; - - hlist_for_each(hash_it_t.walk, head) { - bucket = hlist_entry(hash_it_t.walk, struct element_t, hlist); - if (compare(bucket->data, data)) - return hash_remove_bucket(hash, &hash_it_t); - } - - return NULL; -} - -/* finds data, based on the key in keydata. returns the found data on success, - * or NULL on error */ -static inline void *hash_find(struct hashtable_t *hash, - hashdata_compare_cb compare, - hashdata_choose_cb choose, void *keydata) -{ - int index; - struct hlist_head *head; - struct hlist_node *walk; - struct element_t *bucket; - - if (!hash) - return NULL; - - index = choose(keydata , hash->size); - head = &hash->table[index]; - - hlist_for_each(walk, head) { - bucket = hlist_entry(walk, struct element_t, hlist); - if (compare(bucket->data, keydata)) - return bucket->data; - } - - return NULL; -} - -/* resize the hash, returns the pointer to the new hash or NULL on - * error. removes the old hash on success */ -static inline struct hashtable_t *hash_resize(struct hashtable_t *hash, - hashdata_choose_cb choose, - int size) -{ - struct hashtable_t *new_hash; - struct hlist_head *head, *new_head; - struct hlist_node *walk, *safe; - struct element_t *bucket; - int i, new_index; - - /* initialize a new hash with the new size */ - new_hash = hash_new(size); - - if (new_hash == NULL) - return NULL; - - /* copy the elements */ - for (i = 0; i < hash->size; i++) { - head = &hash->table[i]; - - hlist_for_each_safe(walk, safe, head) { - bucket = hlist_entry(walk, struct element_t, hlist); - - new_index = choose(bucket->data, size); - new_head = &new_hash->table[new_index]; - - hlist_del(walk); - hlist_add_head(walk, new_head); - } - } - - hash_destroy(hash); - - return new_hash; -} - -/* iterate though the hash. First element is selected if an iterator - * initialized with HASHIT() is supplied as iter. Use the returned - * (or supplied) iterator to access the elements until hash_iterate returns - * NULL. */ -static inline struct hash_it_t *hash_iterate(struct hashtable_t *hash, - struct hash_it_t *iter) -{ - if (!hash) - return NULL; - if (!iter) - return NULL; - - iter->walk = iter->safe; - - /* we search for the next head with list entries */ - if (!iter->walk) { - while (iter->index < hash->size) { - if (hlist_empty(&hash->table[iter->index])) - iter->index++; - else { - iter->walk = hash->table[iter->index].first; - - /* search next time */ - ++iter->index; - break; - } - } - } - - /* return iter when we found bucket otherwise null */ - if (!iter->walk) - return NULL; - - iter->safe = iter->walk->next; - return iter; -} - -#endif /* _NET_BATMAN_ADV_HASH_H_ */ diff --git a/drivers/staging/batman-adv/icmp_socket.c b/drivers/staging/batman-adv/icmp_socket.c deleted file mode 100644 index a933ca609b74..000000000000 --- a/drivers/staging/batman-adv/icmp_socket.c +++ /dev/null @@ -1,357 +0,0 @@ -/* - * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: - * - * Marek Lindner - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License 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. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA - * - */ - -#include "main.h" -#include -#include -#include "icmp_socket.h" -#include "send.h" -#include "types.h" -#include "hash.h" -#include "originator.h" -#include "hard-interface.h" - - -static struct socket_client *socket_client_hash[256]; - -static void bat_socket_add_packet(struct socket_client *socket_client, - struct icmp_packet_rr *icmp_packet, - size_t icmp_len); - -void bat_socket_init(void) -{ - memset(socket_client_hash, 0, sizeof(socket_client_hash)); -} - -static int bat_socket_open(struct inode *inode, struct file *file) -{ - unsigned int i; - struct socket_client *socket_client; - - nonseekable_open(inode, file); - - socket_client = kmalloc(sizeof(struct socket_client), GFP_KERNEL); - - if (!socket_client) - return -ENOMEM; - - for (i = 0; i < ARRAY_SIZE(socket_client_hash); i++) { - if (!socket_client_hash[i]) { - socket_client_hash[i] = socket_client; - break; - } - } - - if (i == ARRAY_SIZE(socket_client_hash)) { - pr_err("Error - can't add another packet client: " - "maximum number of clients reached\n"); - kfree(socket_client); - return -EXFULL; - } - - INIT_LIST_HEAD(&socket_client->queue_list); - socket_client->queue_len = 0; - socket_client->index = i; - socket_client->bat_priv = inode->i_private; - spin_lock_init(&socket_client->lock); - init_waitqueue_head(&socket_client->queue_wait); - - file->private_data = socket_client; - - inc_module_count(); - return 0; -} - -static int bat_socket_release(struct inode *inode, struct file *file) -{ - struct socket_client *socket_client = file->private_data; - struct socket_packet *socket_packet; - struct list_head *list_pos, *list_pos_tmp; - - spin_lock_bh(&socket_client->lock); - - /* for all packets in the queue ... */ - list_for_each_safe(list_pos, list_pos_tmp, &socket_client->queue_list) { - socket_packet = list_entry(list_pos, - struct socket_packet, list); - - list_del(list_pos); - kfree(socket_packet); - } - - socket_client_hash[socket_client->index] = NULL; - spin_unlock_bh(&socket_client->lock); - - kfree(socket_client); - dec_module_count(); - - return 0; -} - -static ssize_t bat_socket_read(struct file *file, char __user *buf, - size_t count, loff_t *ppos) -{ - struct socket_client *socket_client = file->private_data; - struct socket_packet *socket_packet; - size_t packet_len; - int error; - - if ((file->f_flags & O_NONBLOCK) && (socket_client->queue_len == 0)) - return -EAGAIN; - - if ((!buf) || (count < sizeof(struct icmp_packet))) - return -EINVAL; - - if (!access_ok(VERIFY_WRITE, buf, count)) - return -EFAULT; - - error = wait_event_interruptible(socket_client->queue_wait, - socket_client->queue_len); - - if (error) - return error; - - spin_lock_bh(&socket_client->lock); - - socket_packet = list_first_entry(&socket_client->queue_list, - struct socket_packet, list); - list_del(&socket_packet->list); - socket_client->queue_len--; - - spin_unlock_bh(&socket_client->lock); - - error = __copy_to_user(buf, &socket_packet->icmp_packet, - socket_packet->icmp_len); - - packet_len = socket_packet->icmp_len; - kfree(socket_packet); - - if (error) - return -EFAULT; - - return packet_len; -} - -static ssize_t bat_socket_write(struct file *file, const char __user *buff, - size_t len, loff_t *off) -{ - struct socket_client *socket_client = file->private_data; - struct bat_priv *bat_priv = socket_client->bat_priv; - struct sk_buff *skb; - struct icmp_packet_rr *icmp_packet; - - struct orig_node *orig_node; - struct batman_if *batman_if; - size_t packet_len = sizeof(struct icmp_packet); - uint8_t dstaddr[ETH_ALEN]; - - if (len < sizeof(struct icmp_packet)) { - bat_dbg(DBG_BATMAN, bat_priv, - "Error - can't send packet from char device: " - "invalid packet size\n"); - return -EINVAL; - } - - if (!bat_priv->primary_if) - return -EFAULT; - - if (len >= sizeof(struct icmp_packet_rr)) - packet_len = sizeof(struct icmp_packet_rr); - - skb = dev_alloc_skb(packet_len + sizeof(struct ethhdr)); - if (!skb) - return -ENOMEM; - - skb_reserve(skb, sizeof(struct ethhdr)); - icmp_packet = (struct icmp_packet_rr *)skb_put(skb, packet_len); - - if (!access_ok(VERIFY_READ, buff, packet_len)) { - len = -EFAULT; - goto free_skb; - } - - if (__copy_from_user(icmp_packet, buff, packet_len)) { - len = -EFAULT; - goto free_skb; - } - - if (icmp_packet->packet_type != BAT_ICMP) { - bat_dbg(DBG_BATMAN, bat_priv, - "Error - can't send packet from char device: " - "got bogus packet type (expected: BAT_ICMP)\n"); - len = -EINVAL; - goto free_skb; - } - - if (icmp_packet->msg_type != ECHO_REQUEST) { - bat_dbg(DBG_BATMAN, bat_priv, - "Error - can't send packet from char device: " - "got bogus message type (expected: ECHO_REQUEST)\n"); - len = -EINVAL; - goto free_skb; - } - - icmp_packet->uid = socket_client->index; - - if (icmp_packet->version != COMPAT_VERSION) { - icmp_packet->msg_type = PARAMETER_PROBLEM; - icmp_packet->ttl = COMPAT_VERSION; - bat_socket_add_packet(socket_client, icmp_packet, packet_len); - goto free_skb; - } - - if (atomic_read(&bat_priv->mesh_state) != MESH_ACTIVE) - goto dst_unreach; - - spin_lock_bh(&bat_priv->orig_hash_lock); - orig_node = ((struct orig_node *)hash_find(bat_priv->orig_hash, - compare_orig, choose_orig, - icmp_packet->dst)); - - if (!orig_node) - goto unlock; - - if (!orig_node->router) - goto unlock; - - batman_if = orig_node->router->if_incoming; - memcpy(dstaddr, orig_node->router->addr, ETH_ALEN); - - spin_unlock_bh(&bat_priv->orig_hash_lock); - - if (!batman_if) - goto dst_unreach; - - if (batman_if->if_status != IF_ACTIVE) - goto dst_unreach; - - memcpy(icmp_packet->orig, - bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN); - - if (packet_len == sizeof(struct icmp_packet_rr)) - memcpy(icmp_packet->rr, batman_if->net_dev->dev_addr, ETH_ALEN); - - - send_skb_packet(skb, batman_if, dstaddr); - - goto out; - -unlock: - spin_unlock_bh(&bat_priv->orig_hash_lock); -dst_unreach: - icmp_packet->msg_type = DESTINATION_UNREACHABLE; - bat_socket_add_packet(socket_client, icmp_packet, packet_len); -free_skb: - kfree_skb(skb); -out: - return len; -} - -static unsigned int bat_socket_poll(struct file *file, poll_table *wait) -{ - struct socket_client *socket_client = file->private_data; - - poll_wait(file, &socket_client->queue_wait, wait); - - if (socket_client->queue_len > 0) - return POLLIN | POLLRDNORM; - - return 0; -} - -static const struct file_operations fops = { - .owner = THIS_MODULE, - .open = bat_socket_open, - .release = bat_socket_release, - .read = bat_socket_read, - .write = bat_socket_write, - .poll = bat_socket_poll, - .llseek = no_llseek, -}; - -int bat_socket_setup(struct bat_priv *bat_priv) -{ - struct dentry *d; - - if (!bat_priv->debug_dir) - goto err; - - d = debugfs_create_file(ICMP_SOCKET, S_IFREG | S_IWUSR | S_IRUSR, - bat_priv->debug_dir, bat_priv, &fops); - if (d) - goto err; - - return 0; - -err: - return 1; -} - -static void bat_socket_add_packet(struct socket_client *socket_client, - struct icmp_packet_rr *icmp_packet, - size_t icmp_len) -{ - struct socket_packet *socket_packet; - - socket_packet = kmalloc(sizeof(struct socket_packet), GFP_ATOMIC); - - if (!socket_packet) - return; - - INIT_LIST_HEAD(&socket_packet->list); - memcpy(&socket_packet->icmp_packet, icmp_packet, icmp_len); - socket_packet->icmp_len = icmp_len; - - spin_lock_bh(&socket_client->lock); - - /* while waiting for the lock the socket_client could have been - * deleted */ - if (!socket_client_hash[icmp_packet->uid]) { - spin_unlock_bh(&socket_client->lock); - kfree(socket_packet); - return; - } - - list_add_tail(&socket_packet->list, &socket_client->queue_list); - socket_client->queue_len++; - - if (socket_client->queue_len > 100) { - socket_packet = list_first_entry(&socket_client->queue_list, - struct socket_packet, list); - - list_del(&socket_packet->list); - kfree(socket_packet); - socket_client->queue_len--; - } - - spin_unlock_bh(&socket_client->lock); - - wake_up(&socket_client->queue_wait); -} - -void bat_socket_receive_packet(struct icmp_packet_rr *icmp_packet, - size_t icmp_len) -{ - struct socket_client *hash = socket_client_hash[icmp_packet->uid]; - - if (hash) - bat_socket_add_packet(hash, icmp_packet, icmp_len); -} diff --git a/drivers/staging/batman-adv/icmp_socket.h b/drivers/staging/batman-adv/icmp_socket.h deleted file mode 100644 index bf9b348cde27..000000000000 --- a/drivers/staging/batman-adv/icmp_socket.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: - * - * Marek Lindner - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License 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. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA - * - */ - -#ifndef _NET_BATMAN_ADV_ICMP_SOCKET_H_ -#define _NET_BATMAN_ADV_ICMP_SOCKET_H_ - -#include "types.h" - -#define ICMP_SOCKET "socket" - -void bat_socket_init(void); -int bat_socket_setup(struct bat_priv *bat_priv); -void bat_socket_receive_packet(struct icmp_packet_rr *icmp_packet, - size_t icmp_len); - -#endif /* _NET_BATMAN_ADV_ICMP_SOCKET_H_ */ diff --git a/drivers/staging/batman-adv/main.c b/drivers/staging/batman-adv/main.c deleted file mode 100644 index b827f6a158cb..000000000000 --- a/drivers/staging/batman-adv/main.c +++ /dev/null @@ -1,187 +0,0 @@ -/* - * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: - * - * Marek Lindner, Simon Wunderlich - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License 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. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA - * - */ - -#include "main.h" -#include "bat_sysfs.h" -#include "bat_debugfs.h" -#include "routing.h" -#include "send.h" -#include "originator.h" -#include "soft-interface.h" -#include "icmp_socket.h" -#include "translation-table.h" -#include "hard-interface.h" -#include "gateway_client.h" -#include "types.h" -#include "vis.h" -#include "hash.h" - -struct list_head if_list; - -unsigned char broadcast_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; - -struct workqueue_struct *bat_event_workqueue; - -static int __init batman_init(void) -{ - INIT_LIST_HEAD(&if_list); - - /* the name should not be longer than 10 chars - see - * http://lwn.net/Articles/23634/ */ - bat_event_workqueue = create_singlethread_workqueue("bat_events"); - - if (!bat_event_workqueue) - return -ENOMEM; - - bat_socket_init(); - debugfs_init(); - - register_netdevice_notifier(&hard_if_notifier); - - pr_info("B.A.T.M.A.N. advanced %s%s (compatibility version %i) " - "loaded\n", SOURCE_VERSION, REVISION_VERSION_STR, - COMPAT_VERSION); - - return 0; -} - -static void __exit batman_exit(void) -{ - debugfs_destroy(); - unregister_netdevice_notifier(&hard_if_notifier); - hardif_remove_interfaces(); - - flush_workqueue(bat_event_workqueue); - destroy_workqueue(bat_event_workqueue); - bat_event_workqueue = NULL; - - rcu_barrier(); -} - -int mesh_init(struct net_device *soft_iface) -{ - struct bat_priv *bat_priv = netdev_priv(soft_iface); - - spin_lock_init(&bat_priv->orig_hash_lock); - spin_lock_init(&bat_priv->forw_bat_list_lock); - spin_lock_init(&bat_priv->forw_bcast_list_lock); - spin_lock_init(&bat_priv->hna_lhash_lock); - spin_lock_init(&bat_priv->hna_ghash_lock); - spin_lock_init(&bat_priv->gw_list_lock); - spin_lock_init(&bat_priv->vis_hash_lock); - spin_lock_init(&bat_priv->vis_list_lock); - spin_lock_init(&bat_priv->softif_neigh_lock); - - INIT_HLIST_HEAD(&bat_priv->forw_bat_list); - INIT_HLIST_HEAD(&bat_priv->forw_bcast_list); - INIT_HLIST_HEAD(&bat_priv->gw_list); - INIT_HLIST_HEAD(&bat_priv->softif_neigh_list); - - if (originator_init(bat_priv) < 1) - goto err; - - if (hna_local_init(bat_priv) < 1) - goto err; - - if (hna_global_init(bat_priv) < 1) - goto err; - - hna_local_add(soft_iface, soft_iface->dev_addr); - - if (vis_init(bat_priv) < 1) - goto err; - - atomic_set(&bat_priv->mesh_state, MESH_ACTIVE); - goto end; - -err: - pr_err("Unable to allocate memory for mesh information structures: " - "out of mem ?\n"); - mesh_free(soft_iface); - return -1; - -end: - return 0; -} - -void mesh_free(struct net_device *soft_iface) -{ - struct bat_priv *bat_priv = netdev_priv(soft_iface); - - atomic_set(&bat_priv->mesh_state, MESH_DEACTIVATING); - - purge_outstanding_packets(bat_priv, NULL); - - vis_quit(bat_priv); - - gw_node_purge(bat_priv); - originator_free(bat_priv); - - hna_local_free(bat_priv); - hna_global_free(bat_priv); - - softif_neigh_purge(bat_priv); - - atomic_set(&bat_priv->mesh_state, MESH_INACTIVE); -} - -void inc_module_count(void) -{ - try_module_get(THIS_MODULE); -} - -void dec_module_count(void) -{ - module_put(THIS_MODULE); -} - -int is_my_mac(uint8_t *addr) -{ - struct batman_if *batman_if; - - rcu_read_lock(); - list_for_each_entry_rcu(batman_if, &if_list, list) { - if (batman_if->if_status != IF_ACTIVE) - continue; - - if (compare_orig(batman_if->net_dev->dev_addr, addr)) { - rcu_read_unlock(); - return 1; - } - } - rcu_read_unlock(); - return 0; - -} - -module_init(batman_init); -module_exit(batman_exit); - -MODULE_LICENSE("GPL"); - -MODULE_AUTHOR(DRIVER_AUTHOR); -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_SUPPORTED_DEVICE(DRIVER_DEVICE); -#ifdef REVISION_VERSION -MODULE_VERSION(SOURCE_VERSION "-" REVISION_VERSION); -#else -MODULE_VERSION(SOURCE_VERSION); -#endif diff --git a/drivers/staging/batman-adv/main.h b/drivers/staging/batman-adv/main.h deleted file mode 100644 index 6b60c33a8b77..000000000000 --- a/drivers/staging/batman-adv/main.h +++ /dev/null @@ -1,180 +0,0 @@ -/* - * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: - * - * Marek Lindner, Simon Wunderlich - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License 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. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA - * - */ - -#ifndef _NET_BATMAN_ADV_MAIN_H_ -#define _NET_BATMAN_ADV_MAIN_H_ - -/* Kernel Programming */ -#define LINUX - -#define DRIVER_AUTHOR "Marek Lindner , " \ - "Simon Wunderlich " -#define DRIVER_DESC "B.A.T.M.A.N. advanced" -#define DRIVER_DEVICE "batman-adv" - -#define SOURCE_VERSION "next" - - -/* B.A.T.M.A.N. parameters */ - -#define TQ_MAX_VALUE 255 -#define JITTER 20 -#define TTL 50 /* Time To Live of broadcast messages */ - -#define PURGE_TIMEOUT 200 /* purge originators after time in seconds if no - * valid packet comes in -> TODO: check - * influence on TQ_LOCAL_WINDOW_SIZE */ -#define LOCAL_HNA_TIMEOUT 3600 /* in seconds */ - -#define TQ_LOCAL_WINDOW_SIZE 64 /* sliding packet range of received originator - * messages in squence numbers (should be a - * multiple of our word size) */ -#define TQ_GLOBAL_WINDOW_SIZE 5 -#define TQ_LOCAL_BIDRECT_SEND_MINIMUM 1 -#define TQ_LOCAL_BIDRECT_RECV_MINIMUM 1 -#define TQ_TOTAL_BIDRECT_LIMIT 1 - -#define NUM_WORDS (TQ_LOCAL_WINDOW_SIZE / WORD_BIT_SIZE) - -#define PACKBUFF_SIZE 2000 -#define LOG_BUF_LEN 8192 /* has to be a power of 2 */ - -#define VIS_INTERVAL 5000 /* 5 seconds */ - -/* how much worse secondary interfaces may be to - * to be considered as bonding candidates */ - -#define BONDING_TQ_THRESHOLD 50 - -#define MAX_AGGREGATION_BYTES 512 /* should not be bigger than 512 bytes or - * change the size of - * forw_packet->direct_link_flags */ -#define MAX_AGGREGATION_MS 100 - -#define SOFTIF_NEIGH_TIMEOUT 180000 /* 3 minutes */ - -#define RESET_PROTECTION_MS 30000 -#define EXPECTED_SEQNO_RANGE 65536 -/* don't reset again within 30 seconds */ - -#define MESH_INACTIVE 0 -#define MESH_ACTIVE 1 -#define MESH_DEACTIVATING 2 - -#define BCAST_QUEUE_LEN 256 -#define BATMAN_QUEUE_LEN 256 - -/* - * Debug Messages - */ -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt /* Append 'batman-adv: ' before - * kernel messages */ - -#define DBG_BATMAN 1 /* all messages related to routing / flooding / - * broadcasting / etc */ -#define DBG_ROUTES 2 /* route or hna added / changed / deleted */ -#define DBG_ALL 3 - -#define LOG_BUF_LEN 8192 /* has to be a power of 2 */ - - -/* - * Vis - */ - -/* #define VIS_SUBCLUSTERS_DISABLED */ - -/* - * Kernel headers - */ - -#include /* mutex */ -#include /* needed by all modules */ -#include /* netdevice */ -#include /* ethernet address classifaction */ -#include /* ethernet header */ -#include /* poll_table */ -#include /* kernel threads */ -#include /* schedule types */ -#include /* workqueue */ -#include -#include /* struct sock */ -#include -#include -#include "types.h" - -#ifndef REVISION_VERSION -#define REVISION_VERSION_STR "" -#else -#define REVISION_VERSION_STR " "REVISION_VERSION -#endif - -extern struct list_head if_list; - -extern unsigned char broadcast_addr[]; -extern struct workqueue_struct *bat_event_workqueue; - -int mesh_init(struct net_device *soft_iface); -void mesh_free(struct net_device *soft_iface); -void inc_module_count(void); -void dec_module_count(void); -int is_my_mac(uint8_t *addr); - -#ifdef CONFIG_BATMAN_ADV_DEBUG -int debug_log(struct bat_priv *bat_priv, char *fmt, ...); - -#define bat_dbg(type, bat_priv, fmt, arg...) \ - do { \ - if (atomic_read(&bat_priv->log_level) & type) \ - debug_log(bat_priv, fmt, ## arg); \ - } \ - while (0) -#else /* !CONFIG_BATMAN_ADV_DEBUG */ -static inline void bat_dbg(char type __attribute__((unused)), - struct bat_priv *bat_priv __attribute__((unused)), - char *fmt __attribute__((unused)), ...) -{ -} -#endif - -#define bat_warning(net_dev, fmt, arg...) \ - do { \ - struct net_device *_netdev = (net_dev); \ - struct bat_priv *_batpriv = netdev_priv(_netdev); \ - bat_dbg(DBG_ALL, _batpriv, fmt, ## arg); \ - pr_warning("%s: " fmt, _netdev->name, ## arg); \ - } while (0) -#define bat_info(net_dev, fmt, arg...) \ - do { \ - struct net_device *_netdev = (net_dev); \ - struct bat_priv *_batpriv = netdev_priv(_netdev); \ - bat_dbg(DBG_ALL, _batpriv, fmt, ## arg); \ - pr_info("%s: " fmt, _netdev->name, ## arg); \ - } while (0) -#define bat_err(net_dev, fmt, arg...) \ - do { \ - struct net_device *_netdev = (net_dev); \ - struct bat_priv *_batpriv = netdev_priv(_netdev); \ - bat_dbg(DBG_ALL, _batpriv, fmt, ## arg); \ - pr_err("%s: " fmt, _netdev->name, ## arg); \ - } while (0) - -#endif /* _NET_BATMAN_ADV_MAIN_H_ */ diff --git a/drivers/staging/batman-adv/originator.c b/drivers/staging/batman-adv/originator.c deleted file mode 100644 index 89ec02100a3b..000000000000 --- a/drivers/staging/batman-adv/originator.c +++ /dev/null @@ -1,546 +0,0 @@ -/* - * Copyright (C) 2009-2010 B.A.T.M.A.N. contributors: - * - * Marek Lindner, Simon Wunderlich - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License 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. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA - * - */ - -/* increase the reference counter for this originator */ - -#include "main.h" -#include "originator.h" -#include "hash.h" -#include "translation-table.h" -#include "routing.h" -#include "gateway_client.h" -#include "hard-interface.h" -#include "unicast.h" -#include "soft-interface.h" - -static void purge_orig(struct work_struct *work); - -static void start_purge_timer(struct bat_priv *bat_priv) -{ - INIT_DELAYED_WORK(&bat_priv->orig_work, purge_orig); - queue_delayed_work(bat_event_workqueue, &bat_priv->orig_work, 1 * HZ); -} - -int originator_init(struct bat_priv *bat_priv) -{ - if (bat_priv->orig_hash) - return 1; - - spin_lock_bh(&bat_priv->orig_hash_lock); - bat_priv->orig_hash = hash_new(128); - - if (!bat_priv->orig_hash) - goto err; - - spin_unlock_bh(&bat_priv->orig_hash_lock); - start_purge_timer(bat_priv); - return 1; - -err: - spin_unlock_bh(&bat_priv->orig_hash_lock); - return 0; -} - -struct neigh_node * -create_neighbor(struct orig_node *orig_node, struct orig_node *orig_neigh_node, - uint8_t *neigh, struct batman_if *if_incoming) -{ - struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface); - struct neigh_node *neigh_node; - - bat_dbg(DBG_BATMAN, bat_priv, - "Creating new last-hop neighbor of originator\n"); - - neigh_node = kzalloc(sizeof(struct neigh_node), GFP_ATOMIC); - if (!neigh_node) - return NULL; - - INIT_LIST_HEAD(&neigh_node->list); - - memcpy(neigh_node->addr, neigh, ETH_ALEN); - neigh_node->orig_node = orig_neigh_node; - neigh_node->if_incoming = if_incoming; - - list_add_tail(&neigh_node->list, &orig_node->neigh_list); - return neigh_node; -} - -static void free_orig_node(void *data, void *arg) -{ - struct list_head *list_pos, *list_pos_tmp; - struct neigh_node *neigh_node; - struct orig_node *orig_node = (struct orig_node *)data; - struct bat_priv *bat_priv = (struct bat_priv *)arg; - - /* for all neighbors towards this originator ... */ - list_for_each_safe(list_pos, list_pos_tmp, &orig_node->neigh_list) { - neigh_node = list_entry(list_pos, struct neigh_node, list); - - list_del(list_pos); - kfree(neigh_node); - } - - frag_list_free(&orig_node->frag_list); - hna_global_del_orig(bat_priv, orig_node, "originator timed out"); - - kfree(orig_node->bcast_own); - kfree(orig_node->bcast_own_sum); - kfree(orig_node); -} - -void originator_free(struct bat_priv *bat_priv) -{ - if (!bat_priv->orig_hash) - return; - - cancel_delayed_work_sync(&bat_priv->orig_work); - - spin_lock_bh(&bat_priv->orig_hash_lock); - hash_delete(bat_priv->orig_hash, free_orig_node, bat_priv); - bat_priv->orig_hash = NULL; - spin_unlock_bh(&bat_priv->orig_hash_lock); -} - -/* this function finds or creates an originator entry for the given - * address if it does not exits */ -struct orig_node *get_orig_node(struct bat_priv *bat_priv, uint8_t *addr) -{ - struct orig_node *orig_node; - struct hashtable_t *swaphash; - int size; - int hash_added; - - orig_node = ((struct orig_node *)hash_find(bat_priv->orig_hash, - compare_orig, choose_orig, - addr)); - - if (orig_node) - return orig_node; - - bat_dbg(DBG_BATMAN, bat_priv, - "Creating new originator: %pM\n", addr); - - orig_node = kzalloc(sizeof(struct orig_node), GFP_ATOMIC); - if (!orig_node) - return NULL; - - INIT_LIST_HEAD(&orig_node->neigh_list); - - memcpy(orig_node->orig, addr, ETH_ALEN); - orig_node->router = NULL; - orig_node->hna_buff = NULL; - orig_node->bcast_seqno_reset = jiffies - 1 - - msecs_to_jiffies(RESET_PROTECTION_MS); - orig_node->batman_seqno_reset = jiffies - 1 - - msecs_to_jiffies(RESET_PROTECTION_MS); - - size = bat_priv->num_ifaces * sizeof(TYPE_OF_WORD) * NUM_WORDS; - - orig_node->bcast_own = kzalloc(size, GFP_ATOMIC); - if (!orig_node->bcast_own) - goto free_orig_node; - - size = bat_priv->num_ifaces * sizeof(uint8_t); - orig_node->bcast_own_sum = kzalloc(size, GFP_ATOMIC); - - INIT_LIST_HEAD(&orig_node->frag_list); - orig_node->last_frag_packet = 0; - - if (!orig_node->bcast_own_sum) - goto free_bcast_own; - - hash_added = hash_add(bat_priv->orig_hash, compare_orig, choose_orig, - orig_node); - if (hash_added < 0) - goto free_bcast_own_sum; - - if (bat_priv->orig_hash->elements * 4 > bat_priv->orig_hash->size) { - swaphash = hash_resize(bat_priv->orig_hash, choose_orig, - bat_priv->orig_hash->size * 2); - - if (!swaphash) - bat_dbg(DBG_BATMAN, bat_priv, - "Couldn't resize orig hash table\n"); - else - bat_priv->orig_hash = swaphash; - } - - return orig_node; -free_bcast_own_sum: - kfree(orig_node->bcast_own_sum); -free_bcast_own: - kfree(orig_node->bcast_own); -free_orig_node: - kfree(orig_node); - return NULL; -} - -static bool purge_orig_neighbors(struct bat_priv *bat_priv, - struct orig_node *orig_node, - struct neigh_node **best_neigh_node) -{ - struct list_head *list_pos, *list_pos_tmp; - struct neigh_node *neigh_node; - bool neigh_purged = false; - - *best_neigh_node = NULL; - - /* for all neighbors towards this originator ... */ - list_for_each_safe(list_pos, list_pos_tmp, &orig_node->neigh_list) { - neigh_node = list_entry(list_pos, struct neigh_node, list); - - if ((time_after(jiffies, - neigh_node->last_valid + PURGE_TIMEOUT * HZ)) || - (neigh_node->if_incoming->if_status == IF_INACTIVE) || - (neigh_node->if_incoming->if_status == IF_TO_BE_REMOVED)) { - - if (neigh_node->if_incoming->if_status == - IF_TO_BE_REMOVED) - bat_dbg(DBG_BATMAN, bat_priv, - "neighbor purge: originator %pM, " - "neighbor: %pM, iface: %s\n", - orig_node->orig, neigh_node->addr, - neigh_node->if_incoming->net_dev->name); - else - bat_dbg(DBG_BATMAN, bat_priv, - "neighbor timeout: originator %pM, " - "neighbor: %pM, last_valid: %lu\n", - orig_node->orig, neigh_node->addr, - (neigh_node->last_valid / HZ)); - - neigh_purged = true; - list_del(list_pos); - kfree(neigh_node); - } else { - if ((*best_neigh_node == NULL) || - (neigh_node->tq_avg > (*best_neigh_node)->tq_avg)) - *best_neigh_node = neigh_node; - } - } - return neigh_purged; -} - -static bool purge_orig_node(struct bat_priv *bat_priv, - struct orig_node *orig_node) -{ - struct neigh_node *best_neigh_node; - - if (time_after(jiffies, - orig_node->last_valid + 2 * PURGE_TIMEOUT * HZ)) { - - bat_dbg(DBG_BATMAN, bat_priv, - "Originator timeout: originator %pM, last_valid %lu\n", - orig_node->orig, (orig_node->last_valid / HZ)); - return true; - } else { - if (purge_orig_neighbors(bat_priv, orig_node, - &best_neigh_node)) { - update_routes(bat_priv, orig_node, - best_neigh_node, - orig_node->hna_buff, - orig_node->hna_buff_len); - /* update bonding candidates, we could have lost - * some candidates. */ - update_bonding_candidates(bat_priv, orig_node); - } - } - - return false; -} - -static void _purge_orig(struct bat_priv *bat_priv) -{ - HASHIT(hashit); - struct element_t *bucket; - struct orig_node *orig_node; - - spin_lock_bh(&bat_priv->orig_hash_lock); - - /* for all origins... */ - while (hash_iterate(bat_priv->orig_hash, &hashit)) { - bucket = hlist_entry(hashit.walk, struct element_t, hlist); - orig_node = bucket->data; - - if (purge_orig_node(bat_priv, orig_node)) { - if (orig_node->gw_flags) - gw_node_delete(bat_priv, orig_node); - hash_remove_bucket(bat_priv->orig_hash, &hashit); - free_orig_node(orig_node, bat_priv); - } - - if (time_after(jiffies, (orig_node->last_frag_packet + - msecs_to_jiffies(FRAG_TIMEOUT)))) - frag_list_free(&orig_node->frag_list); - } - - spin_unlock_bh(&bat_priv->orig_hash_lock); - - gw_node_purge(bat_priv); - gw_election(bat_priv); - - softif_neigh_purge(bat_priv); -} - -static void purge_orig(struct work_struct *work) -{ - struct delayed_work *delayed_work = - container_of(work, struct delayed_work, work); - struct bat_priv *bat_priv = - container_of(delayed_work, struct bat_priv, orig_work); - - _purge_orig(bat_priv); - start_purge_timer(bat_priv); -} - -void purge_orig_ref(struct bat_priv *bat_priv) -{ - _purge_orig(bat_priv); -} - -int orig_seq_print_text(struct seq_file *seq, void *offset) -{ - HASHIT(hashit); - struct element_t *bucket; - struct net_device *net_dev = (struct net_device *)seq->private; - struct bat_priv *bat_priv = netdev_priv(net_dev); - struct orig_node *orig_node; - struct neigh_node *neigh_node; - int batman_count = 0; - int last_seen_secs; - int last_seen_msecs; - - if ((!bat_priv->primary_if) || - (bat_priv->primary_if->if_status != IF_ACTIVE)) { - if (!bat_priv->primary_if) - return seq_printf(seq, "BATMAN mesh %s disabled - " - "please specify interfaces to enable it\n", - net_dev->name); - - return seq_printf(seq, "BATMAN mesh %s " - "disabled - primary interface not active\n", - net_dev->name); - } - - seq_printf(seq, "[B.A.T.M.A.N. adv %s%s, MainIF/MAC: %s/%pM (%s)]\n", - SOURCE_VERSION, REVISION_VERSION_STR, - bat_priv->primary_if->net_dev->name, - bat_priv->primary_if->net_dev->dev_addr, net_dev->name); - seq_printf(seq, " %-15s %s (%s/%i) %17s [%10s]: %20s ...\n", - "Originator", "last-seen", "#", TQ_MAX_VALUE, "Nexthop", - "outgoingIF", "Potential nexthops"); - - spin_lock_bh(&bat_priv->orig_hash_lock); - - while (hash_iterate(bat_priv->orig_hash, &hashit)) { - bucket = hlist_entry(hashit.walk, struct element_t, hlist); - orig_node = bucket->data; - - if (!orig_node->router) - continue; - - if (orig_node->router->tq_avg == 0) - continue; - - last_seen_secs = jiffies_to_msecs(jiffies - - orig_node->last_valid) / 1000; - last_seen_msecs = jiffies_to_msecs(jiffies - - orig_node->last_valid) % 1000; - - seq_printf(seq, "%pM %4i.%03is (%3i) %pM [%10s]:", - orig_node->orig, last_seen_secs, last_seen_msecs, - orig_node->router->tq_avg, orig_node->router->addr, - orig_node->router->if_incoming->net_dev->name); - - list_for_each_entry(neigh_node, &orig_node->neigh_list, list) { - seq_printf(seq, " %pM (%3i)", neigh_node->addr, - neigh_node->tq_avg); - } - - seq_printf(seq, "\n"); - batman_count++; - } - - spin_unlock_bh(&bat_priv->orig_hash_lock); - - if ((batman_count == 0)) - seq_printf(seq, "No batman nodes in range ...\n"); - - return 0; -} - -static int orig_node_add_if(struct orig_node *orig_node, int max_if_num) -{ - void *data_ptr; - - data_ptr = kmalloc(max_if_num * sizeof(TYPE_OF_WORD) * NUM_WORDS, - GFP_ATOMIC); - if (!data_ptr) { - pr_err("Can't resize orig: out of memory\n"); - return -1; - } - - memcpy(data_ptr, orig_node->bcast_own, - (max_if_num - 1) * sizeof(TYPE_OF_WORD) * NUM_WORDS); - kfree(orig_node->bcast_own); - orig_node->bcast_own = data_ptr; - - data_ptr = kmalloc(max_if_num * sizeof(uint8_t), GFP_ATOMIC); - if (!data_ptr) { - pr_err("Can't resize orig: out of memory\n"); - return -1; - } - - memcpy(data_ptr, orig_node->bcast_own_sum, - (max_if_num - 1) * sizeof(uint8_t)); - kfree(orig_node->bcast_own_sum); - orig_node->bcast_own_sum = data_ptr; - - return 0; -} - -int orig_hash_add_if(struct batman_if *batman_if, int max_if_num) -{ - struct bat_priv *bat_priv = netdev_priv(batman_if->soft_iface); - struct orig_node *orig_node; - HASHIT(hashit); - struct element_t *bucket; - - /* resize all orig nodes because orig_node->bcast_own(_sum) depend on - * if_num */ - spin_lock_bh(&bat_priv->orig_hash_lock); - - while (hash_iterate(bat_priv->orig_hash, &hashit)) { - bucket = hlist_entry(hashit.walk, struct element_t, hlist); - orig_node = bucket->data; - - if (orig_node_add_if(orig_node, max_if_num) == -1) - goto err; - } - - spin_unlock_bh(&bat_priv->orig_hash_lock); - return 0; - -err: - spin_unlock_bh(&bat_priv->orig_hash_lock); - return -ENOMEM; -} - -static int orig_node_del_if(struct orig_node *orig_node, - int max_if_num, int del_if_num) -{ - void *data_ptr = NULL; - int chunk_size; - - /* last interface was removed */ - if (max_if_num == 0) - goto free_bcast_own; - - chunk_size = sizeof(TYPE_OF_WORD) * NUM_WORDS; - data_ptr = kmalloc(max_if_num * chunk_size, GFP_ATOMIC); - if (!data_ptr) { - pr_err("Can't resize orig: out of memory\n"); - return -1; - } - - /* copy first part */ - memcpy(data_ptr, orig_node->bcast_own, del_if_num * chunk_size); - - /* copy second part */ - memcpy(data_ptr + del_if_num * chunk_size, - orig_node->bcast_own + ((del_if_num + 1) * chunk_size), - (max_if_num - del_if_num) * chunk_size); - -free_bcast_own: - kfree(orig_node->bcast_own); - orig_node->bcast_own = data_ptr; - - if (max_if_num == 0) - goto free_own_sum; - - data_ptr = kmalloc(max_if_num * sizeof(uint8_t), GFP_ATOMIC); - if (!data_ptr) { - pr_err("Can't resize orig: out of memory\n"); - return -1; - } - - memcpy(data_ptr, orig_node->bcast_own_sum, - del_if_num * sizeof(uint8_t)); - - memcpy(data_ptr + del_if_num * sizeof(uint8_t), - orig_node->bcast_own_sum + ((del_if_num + 1) * sizeof(uint8_t)), - (max_if_num - del_if_num) * sizeof(uint8_t)); - -free_own_sum: - kfree(orig_node->bcast_own_sum); - orig_node->bcast_own_sum = data_ptr; - - return 0; -} - -int orig_hash_del_if(struct batman_if *batman_if, int max_if_num) -{ - struct bat_priv *bat_priv = netdev_priv(batman_if->soft_iface); - struct batman_if *batman_if_tmp; - struct orig_node *orig_node; - HASHIT(hashit); - struct element_t *bucket; - int ret; - - /* resize all orig nodes because orig_node->bcast_own(_sum) depend on - * if_num */ - spin_lock_bh(&bat_priv->orig_hash_lock); - - while (hash_iterate(bat_priv->orig_hash, &hashit)) { - bucket = hlist_entry(hashit.walk, struct element_t, hlist); - orig_node = bucket->data; - - ret = orig_node_del_if(orig_node, max_if_num, - batman_if->if_num); - - if (ret == -1) - goto err; - } - - /* renumber remaining batman interfaces _inside_ of orig_hash_lock */ - rcu_read_lock(); - list_for_each_entry_rcu(batman_if_tmp, &if_list, list) { - if (batman_if_tmp->if_status == IF_NOT_IN_USE) - continue; - - if (batman_if == batman_if_tmp) - continue; - - if (batman_if->soft_iface != batman_if_tmp->soft_iface) - continue; - - if (batman_if_tmp->if_num > batman_if->if_num) - batman_if_tmp->if_num--; - } - rcu_read_unlock(); - - batman_if->if_num = -1; - spin_unlock_bh(&bat_priv->orig_hash_lock); - return 0; - -err: - spin_unlock_bh(&bat_priv->orig_hash_lock); - return -ENOMEM; -} diff --git a/drivers/staging/batman-adv/originator.h b/drivers/staging/batman-adv/originator.h deleted file mode 100644 index d474ceb2a4eb..000000000000 --- a/drivers/staging/batman-adv/originator.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: - * - * Marek Lindner, Simon Wunderlich - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License 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. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA - * - */ - -#ifndef _NET_BATMAN_ADV_ORIGINATOR_H_ -#define _NET_BATMAN_ADV_ORIGINATOR_H_ - -int originator_init(struct bat_priv *bat_priv); -void originator_free(struct bat_priv *bat_priv); -void purge_orig_ref(struct bat_priv *bat_priv); -struct orig_node *get_orig_node(struct bat_priv *bat_priv, uint8_t *addr); -struct neigh_node * -create_neighbor(struct orig_node *orig_node, struct orig_node *orig_neigh_node, - uint8_t *neigh, struct batman_if *if_incoming); -int orig_seq_print_text(struct seq_file *seq, void *offset); -int orig_hash_add_if(struct batman_if *batman_if, int max_if_num); -int orig_hash_del_if(struct batman_if *batman_if, int max_if_num); - - -/* returns 1 if they are the same originator */ -static inline int compare_orig(void *data1, void *data2) -{ - return (memcmp(data1, data2, ETH_ALEN) == 0 ? 1 : 0); -} - -/* hashfunction to choose an entry in a hash table of given size */ -/* hash algorithm from http://en.wikipedia.org/wiki/Hash_table */ -static inline int choose_orig(void *data, int32_t size) -{ - unsigned char *key = data; - uint32_t hash = 0; - size_t i; - - for (i = 0; i < 6; i++) { - hash += key[i]; - hash += (hash << 10); - hash ^= (hash >> 6); - } - - hash += (hash << 3); - hash ^= (hash >> 11); - hash += (hash << 15); - - return hash % size; -} - -#endif /* _NET_BATMAN_ADV_ORIGINATOR_H_ */ diff --git a/drivers/staging/batman-adv/packet.h b/drivers/staging/batman-adv/packet.h deleted file mode 100644 index b49fdf70a6d5..000000000000 --- a/drivers/staging/batman-adv/packet.h +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: - * - * Marek Lindner, Simon Wunderlich - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License 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. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA - * - */ - -#ifndef _NET_BATMAN_ADV_PACKET_H_ -#define _NET_BATMAN_ADV_PACKET_H_ - -#define ETH_P_BATMAN 0x4305 /* unofficial/not registered Ethertype */ - -#define BAT_PACKET 0x01 -#define BAT_ICMP 0x02 -#define BAT_UNICAST 0x03 -#define BAT_BCAST 0x04 -#define BAT_VIS 0x05 -#define BAT_UNICAST_FRAG 0x06 - -/* this file is included by batctl which needs these defines */ -#define COMPAT_VERSION 12 -#define DIRECTLINK 0x40 -#define VIS_SERVER 0x20 -#define PRIMARIES_FIRST_HOP 0x10 - -/* ICMP message types */ -#define ECHO_REPLY 0 -#define DESTINATION_UNREACHABLE 3 -#define ECHO_REQUEST 8 -#define TTL_EXCEEDED 11 -#define PARAMETER_PROBLEM 12 - -/* vis defines */ -#define VIS_TYPE_SERVER_SYNC 0 -#define VIS_TYPE_CLIENT_UPDATE 1 - -/* fragmentation defines */ -#define UNI_FRAG_HEAD 0x01 - -struct batman_packet { - uint8_t packet_type; - uint8_t version; /* batman version field */ - uint8_t flags; /* 0x40: DIRECTLINK flag, 0x20 VIS_SERVER flag... */ - uint8_t tq; - uint32_t seqno; - uint8_t orig[6]; - uint8_t prev_sender[6]; - uint8_t ttl; - uint8_t num_hna; - uint8_t gw_flags; /* flags related to gateway class */ - uint8_t align; -} __attribute__((packed)); - -#define BAT_PACKET_LEN sizeof(struct batman_packet) - -struct icmp_packet { - uint8_t packet_type; - uint8_t version; /* batman version field */ - uint8_t msg_type; /* see ICMP message types above */ - uint8_t ttl; - uint8_t dst[6]; - uint8_t orig[6]; - uint16_t seqno; - uint8_t uid; -} __attribute__((packed)); - -#define BAT_RR_LEN 16 - -/* icmp_packet_rr must start with all fields from imcp_packet - * as this is assumed by code that handles ICMP packets */ -struct icmp_packet_rr { - uint8_t packet_type; - uint8_t version; /* batman version field */ - uint8_t msg_type; /* see ICMP message types above */ - uint8_t ttl; - uint8_t dst[6]; - uint8_t orig[6]; - uint16_t seqno; - uint8_t uid; - uint8_t rr_cur; - uint8_t rr[BAT_RR_LEN][ETH_ALEN]; -} __attribute__((packed)); - -struct unicast_packet { - uint8_t packet_type; - uint8_t version; /* batman version field */ - uint8_t dest[6]; - uint8_t ttl; -} __attribute__((packed)); - -struct unicast_frag_packet { - uint8_t packet_type; - uint8_t version; /* batman version field */ - uint8_t dest[6]; - uint8_t ttl; - uint8_t flags; - uint8_t orig[6]; - uint16_t seqno; -} __attribute__((packed)); - -struct bcast_packet { - uint8_t packet_type; - uint8_t version; /* batman version field */ - uint8_t orig[6]; - uint8_t ttl; - uint32_t seqno; -} __attribute__((packed)); - -struct vis_packet { - uint8_t packet_type; - uint8_t version; /* batman version field */ - uint8_t vis_type; /* which type of vis-participant sent this? */ - uint8_t entries; /* number of entries behind this struct */ - uint32_t seqno; /* sequence number */ - uint8_t ttl; /* TTL */ - uint8_t vis_orig[6]; /* originator that informs about its - * neighbors */ - uint8_t target_orig[6]; /* who should receive this packet */ - uint8_t sender_orig[6]; /* who sent or rebroadcasted this packet */ -} __attribute__((packed)); - -#endif /* _NET_BATMAN_ADV_PACKET_H_ */ diff --git a/drivers/staging/batman-adv/ring_buffer.c b/drivers/staging/batman-adv/ring_buffer.c deleted file mode 100644 index defd37c9be1f..000000000000 --- a/drivers/staging/batman-adv/ring_buffer.c +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: - * - * Marek Lindner - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License 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. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA - * - */ - -#include "main.h" -#include "ring_buffer.h" - -void ring_buffer_set(uint8_t lq_recv[], uint8_t *lq_index, uint8_t value) -{ - lq_recv[*lq_index] = value; - *lq_index = (*lq_index + 1) % TQ_GLOBAL_WINDOW_SIZE; -} - -uint8_t ring_buffer_avg(uint8_t lq_recv[]) -{ - uint8_t *ptr; - uint16_t count = 0, i = 0, sum = 0; - - ptr = lq_recv; - - while (i < TQ_GLOBAL_WINDOW_SIZE) { - if (*ptr != 0) { - count++; - sum += *ptr; - } - - i++; - ptr++; - } - - if (count == 0) - return 0; - - return (uint8_t)(sum / count); -} diff --git a/drivers/staging/batman-adv/ring_buffer.h b/drivers/staging/batman-adv/ring_buffer.h deleted file mode 100644 index 6b0cb9aaeba5..000000000000 --- a/drivers/staging/batman-adv/ring_buffer.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: - * - * Marek Lindner - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License 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. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA - * - */ - -#ifndef _NET_BATMAN_ADV_RING_BUFFER_H_ -#define _NET_BATMAN_ADV_RING_BUFFER_H_ - -void ring_buffer_set(uint8_t lq_recv[], uint8_t *lq_index, uint8_t value); -uint8_t ring_buffer_avg(uint8_t lq_recv[]); - -#endif /* _NET_BATMAN_ADV_RING_BUFFER_H_ */ diff --git a/drivers/staging/batman-adv/routing.c b/drivers/staging/batman-adv/routing.c deleted file mode 100644 index d8b0c5a6d5df..000000000000 --- a/drivers/staging/batman-adv/routing.c +++ /dev/null @@ -1,1393 +0,0 @@ -/* - * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: - * - * Marek Lindner, Simon Wunderlich - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License 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. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA - * - */ - -#include "main.h" -#include "routing.h" -#include "send.h" -#include "hash.h" -#include "soft-interface.h" -#include "hard-interface.h" -#include "icmp_socket.h" -#include "translation-table.h" -#include "originator.h" -#include "types.h" -#include "ring_buffer.h" -#include "vis.h" -#include "aggregation.h" -#include "gateway_common.h" -#include "gateway_client.h" -#include "unicast.h" - -void slide_own_bcast_window(struct batman_if *batman_if) -{ - struct bat_priv *bat_priv = netdev_priv(batman_if->soft_iface); - HASHIT(hashit); - struct element_t *bucket; - struct orig_node *orig_node; - TYPE_OF_WORD *word; - - spin_lock_bh(&bat_priv->orig_hash_lock); - - while (hash_iterate(bat_priv->orig_hash, &hashit)) { - bucket = hlist_entry(hashit.walk, struct element_t, hlist); - orig_node = bucket->data; - word = &(orig_node->bcast_own[batman_if->if_num * NUM_WORDS]); - - bit_get_packet(bat_priv, word, 1, 0); - orig_node->bcast_own_sum[batman_if->if_num] = - bit_packet_count(word); - } - - spin_unlock_bh(&bat_priv->orig_hash_lock); -} - -static void update_HNA(struct bat_priv *bat_priv, struct orig_node *orig_node, - unsigned char *hna_buff, int hna_buff_len) -{ - if ((hna_buff_len != orig_node->hna_buff_len) || - ((hna_buff_len > 0) && - (orig_node->hna_buff_len > 0) && - (memcmp(orig_node->hna_buff, hna_buff, hna_buff_len) != 0))) { - - if (orig_node->hna_buff_len > 0) - hna_global_del_orig(bat_priv, orig_node, - "originator changed hna"); - - if ((hna_buff_len > 0) && (hna_buff != NULL)) - hna_global_add_orig(bat_priv, orig_node, - hna_buff, hna_buff_len); - } -} - -static void update_route(struct bat_priv *bat_priv, - struct orig_node *orig_node, - struct neigh_node *neigh_node, - unsigned char *hna_buff, int hna_buff_len) -{ - /* route deleted */ - if ((orig_node->router != NULL) && (neigh_node == NULL)) { - - bat_dbg(DBG_ROUTES, bat_priv, "Deleting route towards: %pM\n", - orig_node->orig); - hna_global_del_orig(bat_priv, orig_node, - "originator timed out"); - - /* route added */ - } else if ((orig_node->router == NULL) && (neigh_node != NULL)) { - - bat_dbg(DBG_ROUTES, bat_priv, - "Adding route towards: %pM (via %pM)\n", - orig_node->orig, neigh_node->addr); - hna_global_add_orig(bat_priv, orig_node, - hna_buff, hna_buff_len); - - /* route changed */ - } else { - bat_dbg(DBG_ROUTES, bat_priv, - "Changing route towards: %pM " - "(now via %pM - was via %pM)\n", - orig_node->orig, neigh_node->addr, - orig_node->router->addr); - } - - orig_node->router = neigh_node; -} - - -void update_routes(struct bat_priv *bat_priv, struct orig_node *orig_node, - struct neigh_node *neigh_node, unsigned char *hna_buff, - int hna_buff_len) -{ - - if (orig_node == NULL) - return; - - if (orig_node->router != neigh_node) - update_route(bat_priv, orig_node, neigh_node, - hna_buff, hna_buff_len); - /* may be just HNA changed */ - else - update_HNA(bat_priv, orig_node, hna_buff, hna_buff_len); -} - -static int is_bidirectional_neigh(struct orig_node *orig_node, - struct orig_node *orig_neigh_node, - struct batman_packet *batman_packet, - struct batman_if *if_incoming) -{ - struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface); - struct neigh_node *neigh_node = NULL, *tmp_neigh_node = NULL; - unsigned char total_count; - - if (orig_node == orig_neigh_node) { - list_for_each_entry(tmp_neigh_node, - &orig_node->neigh_list, - list) { - - if (compare_orig(tmp_neigh_node->addr, - orig_neigh_node->orig) && - (tmp_neigh_node->if_incoming == if_incoming)) - neigh_node = tmp_neigh_node; - } - - if (!neigh_node) - neigh_node = create_neighbor(orig_node, - orig_neigh_node, - orig_neigh_node->orig, - if_incoming); - /* create_neighbor failed, return 0 */ - if (!neigh_node) - return 0; - - neigh_node->last_valid = jiffies; - } else { - /* find packet count of corresponding one hop neighbor */ - list_for_each_entry(tmp_neigh_node, - &orig_neigh_node->neigh_list, list) { - - if (compare_orig(tmp_neigh_node->addr, - orig_neigh_node->orig) && - (tmp_neigh_node->if_incoming == if_incoming)) - neigh_node = tmp_neigh_node; - } - - if (!neigh_node) - neigh_node = create_neighbor(orig_neigh_node, - orig_neigh_node, - orig_neigh_node->orig, - if_incoming); - /* create_neighbor failed, return 0 */ - if (!neigh_node) - return 0; - } - - orig_node->last_valid = jiffies; - - /* pay attention to not get a value bigger than 100 % */ - total_count = (orig_neigh_node->bcast_own_sum[if_incoming->if_num] > - neigh_node->real_packet_count ? - neigh_node->real_packet_count : - orig_neigh_node->bcast_own_sum[if_incoming->if_num]); - - /* if we have too few packets (too less data) we set tq_own to zero */ - /* if we receive too few packets it is not considered bidirectional */ - if ((total_count < TQ_LOCAL_BIDRECT_SEND_MINIMUM) || - (neigh_node->real_packet_count < TQ_LOCAL_BIDRECT_RECV_MINIMUM)) - orig_neigh_node->tq_own = 0; - else - /* neigh_node->real_packet_count is never zero as we - * only purge old information when getting new - * information */ - orig_neigh_node->tq_own = (TQ_MAX_VALUE * total_count) / - neigh_node->real_packet_count; - - /* - * 1 - ((1-x) ** 3), normalized to TQ_MAX_VALUE this does - * affect the nearly-symmetric links only a little, but - * punishes asymmetric links more. This will give a value - * between 0 and TQ_MAX_VALUE - */ - orig_neigh_node->tq_asym_penalty = - TQ_MAX_VALUE - - (TQ_MAX_VALUE * - (TQ_LOCAL_WINDOW_SIZE - neigh_node->real_packet_count) * - (TQ_LOCAL_WINDOW_SIZE - neigh_node->real_packet_count) * - (TQ_LOCAL_WINDOW_SIZE - neigh_node->real_packet_count)) / - (TQ_LOCAL_WINDOW_SIZE * - TQ_LOCAL_WINDOW_SIZE * - TQ_LOCAL_WINDOW_SIZE); - - batman_packet->tq = ((batman_packet->tq * - orig_neigh_node->tq_own * - orig_neigh_node->tq_asym_penalty) / - (TQ_MAX_VALUE * TQ_MAX_VALUE)); - - bat_dbg(DBG_BATMAN, bat_priv, - "bidirectional: " - "orig = %-15pM neigh = %-15pM => own_bcast = %2i, " - "real recv = %2i, local tq: %3i, asym_penalty: %3i, " - "total tq: %3i\n", - orig_node->orig, orig_neigh_node->orig, total_count, - neigh_node->real_packet_count, orig_neigh_node->tq_own, - orig_neigh_node->tq_asym_penalty, batman_packet->tq); - - /* if link has the minimum required transmission quality - * consider it bidirectional */ - if (batman_packet->tq >= TQ_TOTAL_BIDRECT_LIMIT) - return 1; - - return 0; -} - -static void update_orig(struct bat_priv *bat_priv, - struct orig_node *orig_node, - struct ethhdr *ethhdr, - struct batman_packet *batman_packet, - struct batman_if *if_incoming, - unsigned char *hna_buff, int hna_buff_len, - char is_duplicate) -{ - struct neigh_node *neigh_node = NULL, *tmp_neigh_node = NULL; - int tmp_hna_buff_len; - - bat_dbg(DBG_BATMAN, bat_priv, "update_originator(): " - "Searching and updating originator entry of received packet\n"); - - list_for_each_entry(tmp_neigh_node, &orig_node->neigh_list, list) { - if (compare_orig(tmp_neigh_node->addr, ethhdr->h_source) && - (tmp_neigh_node->if_incoming == if_incoming)) { - neigh_node = tmp_neigh_node; - continue; - } - - if (is_duplicate) - continue; - - ring_buffer_set(tmp_neigh_node->tq_recv, - &tmp_neigh_node->tq_index, 0); - tmp_neigh_node->tq_avg = - ring_buffer_avg(tmp_neigh_node->tq_recv); - } - - if (!neigh_node) { - struct orig_node *orig_tmp; - - orig_tmp = get_orig_node(bat_priv, ethhdr->h_source); - if (!orig_tmp) - return; - - neigh_node = create_neighbor(orig_node, orig_tmp, - ethhdr->h_source, if_incoming); - if (!neigh_node) - return; - } else - bat_dbg(DBG_BATMAN, bat_priv, - "Updating existing last-hop neighbor of originator\n"); - - orig_node->flags = batman_packet->flags; - neigh_node->last_valid = jiffies; - - ring_buffer_set(neigh_node->tq_recv, - &neigh_node->tq_index, - batman_packet->tq); - neigh_node->tq_avg = ring_buffer_avg(neigh_node->tq_recv); - - if (!is_duplicate) { - orig_node->last_ttl = batman_packet->ttl; - neigh_node->last_ttl = batman_packet->ttl; - } - - tmp_hna_buff_len = (hna_buff_len > batman_packet->num_hna * ETH_ALEN ? - batman_packet->num_hna * ETH_ALEN : hna_buff_len); - - /* if this neighbor already is our next hop there is nothing - * to change */ - if (orig_node->router == neigh_node) - goto update_hna; - - /* if this neighbor does not offer a better TQ we won't consider it */ - if ((orig_node->router) && - (orig_node->router->tq_avg > neigh_node->tq_avg)) - goto update_hna; - - /* if the TQ is the same and the link not more symetric we - * won't consider it either */ - if ((orig_node->router) && - ((neigh_node->tq_avg == orig_node->router->tq_avg) && - (orig_node->router->orig_node->bcast_own_sum[if_incoming->if_num] - >= neigh_node->orig_node->bcast_own_sum[if_incoming->if_num]))) - goto update_hna; - - update_routes(bat_priv, orig_node, neigh_node, - hna_buff, tmp_hna_buff_len); - goto update_gw; - -update_hna: - update_routes(bat_priv, orig_node, orig_node->router, - hna_buff, tmp_hna_buff_len); - -update_gw: - if (orig_node->gw_flags != batman_packet->gw_flags) - gw_node_update(bat_priv, orig_node, batman_packet->gw_flags); - - orig_node->gw_flags = batman_packet->gw_flags; - - /* restart gateway selection if fast or late switching was enabled */ - if ((orig_node->gw_flags) && - (atomic_read(&bat_priv->gw_mode) == GW_MODE_CLIENT) && - (atomic_read(&bat_priv->gw_sel_class) > 2)) - gw_check_election(bat_priv, orig_node); -} - -/* checks whether the host restarted and is in the protection time. - * returns: - * 0 if the packet is to be accepted - * 1 if the packet is to be ignored. - */ -static int window_protected(struct bat_priv *bat_priv, - int32_t seq_num_diff, - unsigned long *last_reset) -{ - if ((seq_num_diff <= -TQ_LOCAL_WINDOW_SIZE) - || (seq_num_diff >= EXPECTED_SEQNO_RANGE)) { - if (time_after(jiffies, *last_reset + - msecs_to_jiffies(RESET_PROTECTION_MS))) { - - *last_reset = jiffies; - bat_dbg(DBG_BATMAN, bat_priv, - "old packet received, start protection\n"); - - return 0; - } else - return 1; - } - return 0; -} - -/* processes a batman packet for all interfaces, adjusts the sequence number and - * finds out whether it is a duplicate. - * returns: - * 1 the packet is a duplicate - * 0 the packet has not yet been received - * -1 the packet is old and has been received while the seqno window - * was protected. Caller should drop it. - */ -static char count_real_packets(struct ethhdr *ethhdr, - struct batman_packet *batman_packet, - struct batman_if *if_incoming) -{ - struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface); - struct orig_node *orig_node; - struct neigh_node *tmp_neigh_node; - char is_duplicate = 0; - int32_t seq_diff; - int need_update = 0; - int set_mark; - - orig_node = get_orig_node(bat_priv, batman_packet->orig); - if (orig_node == NULL) - return 0; - - seq_diff = batman_packet->seqno - orig_node->last_real_seqno; - - /* signalize caller that the packet is to be dropped. */ - if (window_protected(bat_priv, seq_diff, - &orig_node->batman_seqno_reset)) - return -1; - - list_for_each_entry(tmp_neigh_node, &orig_node->neigh_list, list) { - - is_duplicate |= get_bit_status(tmp_neigh_node->real_bits, - orig_node->last_real_seqno, - batman_packet->seqno); - - if (compare_orig(tmp_neigh_node->addr, ethhdr->h_source) && - (tmp_neigh_node->if_incoming == if_incoming)) - set_mark = 1; - else - set_mark = 0; - - /* if the window moved, set the update flag. */ - need_update |= bit_get_packet(bat_priv, - tmp_neigh_node->real_bits, - seq_diff, set_mark); - - tmp_neigh_node->real_packet_count = - bit_packet_count(tmp_neigh_node->real_bits); - } - - if (need_update) { - bat_dbg(DBG_BATMAN, bat_priv, - "updating last_seqno: old %d, new %d\n", - orig_node->last_real_seqno, batman_packet->seqno); - orig_node->last_real_seqno = batman_packet->seqno; - } - - return is_duplicate; -} - -/* copy primary address for bonding */ -static void mark_bonding_address(struct bat_priv *bat_priv, - struct orig_node *orig_node, - struct orig_node *orig_neigh_node, - struct batman_packet *batman_packet) - -{ - if (batman_packet->flags & PRIMARIES_FIRST_HOP) - memcpy(orig_neigh_node->primary_addr, - orig_node->orig, ETH_ALEN); - - return; -} - -/* mark possible bond.candidates in the neighbor list */ -void update_bonding_candidates(struct bat_priv *bat_priv, - struct orig_node *orig_node) -{ - int candidates; - int interference_candidate; - int best_tq; - struct neigh_node *tmp_neigh_node, *tmp_neigh_node2; - struct neigh_node *first_candidate, *last_candidate; - - /* update the candidates for this originator */ - if (!orig_node->router) { - orig_node->bond.candidates = 0; - return; - } - - best_tq = orig_node->router->tq_avg; - - /* update bond.candidates */ - - candidates = 0; - - /* mark other nodes which also received "PRIMARIES FIRST HOP" packets - * as "bonding partner" */ - - /* first, zero the list */ - list_for_each_entry(tmp_neigh_node, &orig_node->neigh_list, list) { - tmp_neigh_node->next_bond_candidate = NULL; - } - - first_candidate = NULL; - last_candidate = NULL; - list_for_each_entry(tmp_neigh_node, &orig_node->neigh_list, list) { - - /* only consider if it has the same primary address ... */ - if (memcmp(orig_node->orig, - tmp_neigh_node->orig_node->primary_addr, - ETH_ALEN) != 0) - continue; - - /* ... and is good enough to be considered */ - if (tmp_neigh_node->tq_avg < best_tq - BONDING_TQ_THRESHOLD) - continue; - - /* check if we have another candidate with the same - * mac address or interface. If we do, we won't - * select this candidate because of possible interference. */ - - interference_candidate = 0; - list_for_each_entry(tmp_neigh_node2, - &orig_node->neigh_list, list) { - - if (tmp_neigh_node2 == tmp_neigh_node) - continue; - - /* we only care if the other candidate is even - * considered as candidate. */ - if (tmp_neigh_node2->next_bond_candidate == NULL) - continue; - - - if ((tmp_neigh_node->if_incoming == - tmp_neigh_node2->if_incoming) - || (memcmp(tmp_neigh_node->addr, - tmp_neigh_node2->addr, ETH_ALEN) == 0)) { - - interference_candidate = 1; - break; - } - } - /* don't care further if it is an interference candidate */ - if (interference_candidate) - continue; - - if (first_candidate == NULL) { - first_candidate = tmp_neigh_node; - tmp_neigh_node->next_bond_candidate = first_candidate; - } else - tmp_neigh_node->next_bond_candidate = last_candidate; - - last_candidate = tmp_neigh_node; - - candidates++; - } - - if (candidates > 0) { - first_candidate->next_bond_candidate = last_candidate; - orig_node->bond.selected = first_candidate; - } - - orig_node->bond.candidates = candidates; -} - -void receive_bat_packet(struct ethhdr *ethhdr, - struct batman_packet *batman_packet, - unsigned char *hna_buff, int hna_buff_len, - struct batman_if *if_incoming) -{ - struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface); - struct batman_if *batman_if; - struct orig_node *orig_neigh_node, *orig_node; - char has_directlink_flag; - char is_my_addr = 0, is_my_orig = 0, is_my_oldorig = 0; - char is_broadcast = 0, is_bidirectional, is_single_hop_neigh; - char is_duplicate; - uint32_t if_incoming_seqno; - - /* Silently drop when the batman packet is actually not a - * correct packet. - * - * This might happen if a packet is padded (e.g. Ethernet has a - * minimum frame length of 64 byte) and the aggregation interprets - * it as an additional length. - * - * TODO: A more sane solution would be to have a bit in the - * batman_packet to detect whether the packet is the last - * packet in an aggregation. Here we expect that the padding - * is always zero (or not 0x01) - */ - if (batman_packet->packet_type != BAT_PACKET) - return; - - /* could be changed by schedule_own_packet() */ - if_incoming_seqno = atomic_read(&if_incoming->seqno); - - has_directlink_flag = (batman_packet->flags & DIRECTLINK ? 1 : 0); - - is_single_hop_neigh = (compare_orig(ethhdr->h_source, - batman_packet->orig) ? 1 : 0); - - bat_dbg(DBG_BATMAN, bat_priv, - "Received BATMAN packet via NB: %pM, IF: %s [%pM] " - "(from OG: %pM, via prev OG: %pM, seqno %d, tq %d, " - "TTL %d, V %d, IDF %d)\n", - ethhdr->h_source, if_incoming->net_dev->name, - if_incoming->net_dev->dev_addr, batman_packet->orig, - batman_packet->prev_sender, batman_packet->seqno, - batman_packet->tq, batman_packet->ttl, batman_packet->version, - has_directlink_flag); - - rcu_read_lock(); - list_for_each_entry_rcu(batman_if, &if_list, list) { - if (batman_if->if_status != IF_ACTIVE) - continue; - - if (batman_if->soft_iface != if_incoming->soft_iface) - continue; - - if (compare_orig(ethhdr->h_source, - batman_if->net_dev->dev_addr)) - is_my_addr = 1; - - if (compare_orig(batman_packet->orig, - batman_if->net_dev->dev_addr)) - is_my_orig = 1; - - if (compare_orig(batman_packet->prev_sender, - batman_if->net_dev->dev_addr)) - is_my_oldorig = 1; - - if (compare_orig(ethhdr->h_source, broadcast_addr)) - is_broadcast = 1; - } - rcu_read_unlock(); - - if (batman_packet->version != COMPAT_VERSION) { - bat_dbg(DBG_BATMAN, bat_priv, - "Drop packet: incompatible batman version (%i)\n", - batman_packet->version); - return; - } - - if (is_my_addr) { - bat_dbg(DBG_BATMAN, bat_priv, - "Drop packet: received my own broadcast (sender: %pM" - ")\n", - ethhdr->h_source); - return; - } - - if (is_broadcast) { - bat_dbg(DBG_BATMAN, bat_priv, "Drop packet: " - "ignoring all packets with broadcast source addr (sender: %pM" - ")\n", ethhdr->h_source); - return; - } - - if (is_my_orig) { - TYPE_OF_WORD *word; - int offset; - - orig_neigh_node = get_orig_node(bat_priv, ethhdr->h_source); - - if (!orig_neigh_node) - return; - - /* neighbor has to indicate direct link and it has to - * come via the corresponding interface */ - /* if received seqno equals last send seqno save new - * seqno for bidirectional check */ - if (has_directlink_flag && - compare_orig(if_incoming->net_dev->dev_addr, - batman_packet->orig) && - (batman_packet->seqno - if_incoming_seqno + 2 == 0)) { - offset = if_incoming->if_num * NUM_WORDS; - word = &(orig_neigh_node->bcast_own[offset]); - bit_mark(word, 0); - orig_neigh_node->bcast_own_sum[if_incoming->if_num] = - bit_packet_count(word); - } - - bat_dbg(DBG_BATMAN, bat_priv, "Drop packet: " - "originator packet from myself (via neighbor)\n"); - return; - } - - if (is_my_oldorig) { - bat_dbg(DBG_BATMAN, bat_priv, - "Drop packet: ignoring all rebroadcast echos (sender: " - "%pM)\n", ethhdr->h_source); - return; - } - - orig_node = get_orig_node(bat_priv, batman_packet->orig); - if (orig_node == NULL) - return; - - is_duplicate = count_real_packets(ethhdr, batman_packet, if_incoming); - - if (is_duplicate == -1) { - bat_dbg(DBG_BATMAN, bat_priv, - "Drop packet: packet within seqno protection time " - "(sender: %pM)\n", ethhdr->h_source); - return; - } - - if (batman_packet->tq == 0) { - bat_dbg(DBG_BATMAN, bat_priv, - "Drop packet: originator packet with tq equal 0\n"); - return; - } - - /* avoid temporary routing loops */ - if ((orig_node->router) && - (orig_node->router->orig_node->router) && - (compare_orig(orig_node->router->addr, - batman_packet->prev_sender)) && - !(compare_orig(batman_packet->orig, batman_packet->prev_sender)) && - (compare_orig(orig_node->router->addr, - orig_node->router->orig_node->router->addr))) { - bat_dbg(DBG_BATMAN, bat_priv, - "Drop packet: ignoring all rebroadcast packets that " - "may make me loop (sender: %pM)\n", ethhdr->h_source); - return; - } - - /* if sender is a direct neighbor the sender mac equals - * originator mac */ - orig_neigh_node = (is_single_hop_neigh ? - orig_node : - get_orig_node(bat_priv, ethhdr->h_source)); - if (orig_neigh_node == NULL) - return; - - /* drop packet if sender is not a direct neighbor and if we - * don't route towards it */ - if (!is_single_hop_neigh && - (orig_neigh_node->router == NULL)) { - bat_dbg(DBG_BATMAN, bat_priv, - "Drop packet: OGM via unknown neighbor!\n"); - return; - } - - is_bidirectional = is_bidirectional_neigh(orig_node, orig_neigh_node, - batman_packet, if_incoming); - - /* update ranking if it is not a duplicate or has the same - * seqno and similar ttl as the non-duplicate */ - if (is_bidirectional && - (!is_duplicate || - ((orig_node->last_real_seqno == batman_packet->seqno) && - (orig_node->last_ttl - 3 <= batman_packet->ttl)))) - update_orig(bat_priv, orig_node, ethhdr, batman_packet, - if_incoming, hna_buff, hna_buff_len, is_duplicate); - - mark_bonding_address(bat_priv, orig_node, - orig_neigh_node, batman_packet); - update_bonding_candidates(bat_priv, orig_node); - - /* is single hop (direct) neighbor */ - if (is_single_hop_neigh) { - - /* mark direct link on incoming interface */ - schedule_forward_packet(orig_node, ethhdr, batman_packet, - 1, hna_buff_len, if_incoming); - - bat_dbg(DBG_BATMAN, bat_priv, "Forwarding packet: " - "rebroadcast neighbor packet with direct link flag\n"); - return; - } - - /* multihop originator */ - if (!is_bidirectional) { - bat_dbg(DBG_BATMAN, bat_priv, - "Drop packet: not received via bidirectional link\n"); - return; - } - - if (is_duplicate) { - bat_dbg(DBG_BATMAN, bat_priv, - "Drop packet: duplicate packet received\n"); - return; - } - - bat_dbg(DBG_BATMAN, bat_priv, - "Forwarding packet: rebroadcast originator packet\n"); - schedule_forward_packet(orig_node, ethhdr, batman_packet, - 0, hna_buff_len, if_incoming); -} - -int recv_bat_packet(struct sk_buff *skb, struct batman_if *batman_if) -{ - struct bat_priv *bat_priv = netdev_priv(batman_if->soft_iface); - struct ethhdr *ethhdr; - - /* drop packet if it has not necessary minimum size */ - if (unlikely(!pskb_may_pull(skb, sizeof(struct batman_packet)))) - return NET_RX_DROP; - - ethhdr = (struct ethhdr *)skb_mac_header(skb); - - /* packet with broadcast indication but unicast recipient */ - if (!is_broadcast_ether_addr(ethhdr->h_dest)) - return NET_RX_DROP; - - /* packet with broadcast sender address */ - if (is_broadcast_ether_addr(ethhdr->h_source)) - return NET_RX_DROP; - - /* create a copy of the skb, if needed, to modify it. */ - if (skb_cow(skb, 0) < 0) - return NET_RX_DROP; - - /* keep skb linear */ - if (skb_linearize(skb) < 0) - return NET_RX_DROP; - - ethhdr = (struct ethhdr *)skb_mac_header(skb); - - spin_lock_bh(&bat_priv->orig_hash_lock); - receive_aggr_bat_packet(ethhdr, - skb->data, - skb_headlen(skb), - batman_if); - spin_unlock_bh(&bat_priv->orig_hash_lock); - - kfree_skb(skb); - return NET_RX_SUCCESS; -} - -static int recv_my_icmp_packet(struct bat_priv *bat_priv, - struct sk_buff *skb, size_t icmp_len) -{ - struct orig_node *orig_node; - struct icmp_packet_rr *icmp_packet; - struct ethhdr *ethhdr; - struct batman_if *batman_if; - int ret; - uint8_t dstaddr[ETH_ALEN]; - - icmp_packet = (struct icmp_packet_rr *)skb->data; - ethhdr = (struct ethhdr *)skb_mac_header(skb); - - /* add data to device queue */ - if (icmp_packet->msg_type != ECHO_REQUEST) { - bat_socket_receive_packet(icmp_packet, icmp_len); - return NET_RX_DROP; - } - - if (!bat_priv->primary_if) - return NET_RX_DROP; - - /* answer echo request (ping) */ - /* get routing information */ - spin_lock_bh(&bat_priv->orig_hash_lock); - orig_node = ((struct orig_node *)hash_find(bat_priv->orig_hash, - compare_orig, choose_orig, - icmp_packet->orig)); - ret = NET_RX_DROP; - - if ((orig_node != NULL) && - (orig_node->router != NULL)) { - - /* don't lock while sending the packets ... we therefore - * copy the required data before sending */ - batman_if = orig_node->router->if_incoming; - memcpy(dstaddr, orig_node->router->addr, ETH_ALEN); - spin_unlock_bh(&bat_priv->orig_hash_lock); - - /* create a copy of the skb, if needed, to modify it. */ - if (skb_cow(skb, sizeof(struct ethhdr)) < 0) - return NET_RX_DROP; - - icmp_packet = (struct icmp_packet_rr *)skb->data; - ethhdr = (struct ethhdr *)skb_mac_header(skb); - - memcpy(icmp_packet->dst, icmp_packet->orig, ETH_ALEN); - memcpy(icmp_packet->orig, - bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN); - icmp_packet->msg_type = ECHO_REPLY; - icmp_packet->ttl = TTL; - - send_skb_packet(skb, batman_if, dstaddr); - ret = NET_RX_SUCCESS; - - } else - spin_unlock_bh(&bat_priv->orig_hash_lock); - - return ret; -} - -static int recv_icmp_ttl_exceeded(struct bat_priv *bat_priv, - struct sk_buff *skb, size_t icmp_len) -{ - struct orig_node *orig_node; - struct icmp_packet *icmp_packet; - struct ethhdr *ethhdr; - struct batman_if *batman_if; - int ret; - uint8_t dstaddr[ETH_ALEN]; - - icmp_packet = (struct icmp_packet *)skb->data; - ethhdr = (struct ethhdr *)skb_mac_header(skb); - - /* send TTL exceeded if packet is an echo request (traceroute) */ - if (icmp_packet->msg_type != ECHO_REQUEST) { - pr_debug("Warning - can't forward icmp packet from %pM to " - "%pM: ttl exceeded\n", icmp_packet->orig, - icmp_packet->dst); - return NET_RX_DROP; - } - - if (!bat_priv->primary_if) - return NET_RX_DROP; - - /* get routing information */ - spin_lock_bh(&bat_priv->orig_hash_lock); - orig_node = ((struct orig_node *) - hash_find(bat_priv->orig_hash, compare_orig, choose_orig, - icmp_packet->orig)); - ret = NET_RX_DROP; - - if ((orig_node != NULL) && - (orig_node->router != NULL)) { - - /* don't lock while sending the packets ... we therefore - * copy the required data before sending */ - batman_if = orig_node->router->if_incoming; - memcpy(dstaddr, orig_node->router->addr, ETH_ALEN); - spin_unlock_bh(&bat_priv->orig_hash_lock); - - /* create a copy of the skb, if needed, to modify it. */ - if (skb_cow(skb, sizeof(struct ethhdr)) < 0) - return NET_RX_DROP; - - icmp_packet = (struct icmp_packet *) skb->data; - ethhdr = (struct ethhdr *)skb_mac_header(skb); - - memcpy(icmp_packet->dst, icmp_packet->orig, ETH_ALEN); - memcpy(icmp_packet->orig, - bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN); - icmp_packet->msg_type = TTL_EXCEEDED; - icmp_packet->ttl = TTL; - - send_skb_packet(skb, batman_if, dstaddr); - ret = NET_RX_SUCCESS; - - } else - spin_unlock_bh(&bat_priv->orig_hash_lock); - - return ret; -} - - -int recv_icmp_packet(struct sk_buff *skb, struct batman_if *recv_if) -{ - struct bat_priv *bat_priv = netdev_priv(recv_if->soft_iface); - struct icmp_packet_rr *icmp_packet; - struct ethhdr *ethhdr; - struct orig_node *orig_node; - struct batman_if *batman_if; - int hdr_size = sizeof(struct icmp_packet); - int ret; - uint8_t dstaddr[ETH_ALEN]; - - /** - * we truncate all incoming icmp packets if they don't match our size - */ - if (skb->len >= sizeof(struct icmp_packet_rr)) - hdr_size = sizeof(struct icmp_packet_rr); - - /* drop packet if it has not necessary minimum size */ - if (unlikely(!pskb_may_pull(skb, hdr_size))) - return NET_RX_DROP; - - ethhdr = (struct ethhdr *)skb_mac_header(skb); - - /* packet with unicast indication but broadcast recipient */ - if (is_broadcast_ether_addr(ethhdr->h_dest)) - return NET_RX_DROP; - - /* packet with broadcast sender address */ - if (is_broadcast_ether_addr(ethhdr->h_source)) - return NET_RX_DROP; - - /* not for me */ - if (!is_my_mac(ethhdr->h_dest)) - return NET_RX_DROP; - - icmp_packet = (struct icmp_packet_rr *)skb->data; - - /* add record route information if not full */ - if ((hdr_size == sizeof(struct icmp_packet_rr)) && - (icmp_packet->rr_cur < BAT_RR_LEN)) { - memcpy(&(icmp_packet->rr[icmp_packet->rr_cur]), - ethhdr->h_dest, ETH_ALEN); - icmp_packet->rr_cur++; - } - - /* packet for me */ - if (is_my_mac(icmp_packet->dst)) - return recv_my_icmp_packet(bat_priv, skb, hdr_size); - - /* TTL exceeded */ - if (icmp_packet->ttl < 2) - return recv_icmp_ttl_exceeded(bat_priv, skb, hdr_size); - - ret = NET_RX_DROP; - - /* get routing information */ - spin_lock_bh(&bat_priv->orig_hash_lock); - orig_node = ((struct orig_node *) - hash_find(bat_priv->orig_hash, compare_orig, choose_orig, - icmp_packet->dst)); - - if ((orig_node != NULL) && - (orig_node->router != NULL)) { - - /* don't lock while sending the packets ... we therefore - * copy the required data before sending */ - batman_if = orig_node->router->if_incoming; - memcpy(dstaddr, orig_node->router->addr, ETH_ALEN); - spin_unlock_bh(&bat_priv->orig_hash_lock); - - /* create a copy of the skb, if needed, to modify it. */ - if (skb_cow(skb, sizeof(struct ethhdr)) < 0) - return NET_RX_DROP; - - icmp_packet = (struct icmp_packet_rr *)skb->data; - ethhdr = (struct ethhdr *)skb_mac_header(skb); - - /* decrement ttl */ - icmp_packet->ttl--; - - /* route it */ - send_skb_packet(skb, batman_if, dstaddr); - ret = NET_RX_SUCCESS; - - } else - spin_unlock_bh(&bat_priv->orig_hash_lock); - - return ret; -} - -/* find a suitable router for this originator, and use - * bonding if possible. */ -struct neigh_node *find_router(struct bat_priv *bat_priv, - struct orig_node *orig_node, - struct batman_if *recv_if) -{ - struct orig_node *primary_orig_node; - struct orig_node *router_orig; - struct neigh_node *router, *first_candidate, *best_router; - static uint8_t zero_mac[ETH_ALEN] = {0, 0, 0, 0, 0, 0}; - int bonding_enabled; - - if (!orig_node) - return NULL; - - if (!orig_node->router) - return NULL; - - /* without bonding, the first node should - * always choose the default router. */ - - bonding_enabled = atomic_read(&bat_priv->bonding); - - if ((!recv_if) && (!bonding_enabled)) - return orig_node->router; - - router_orig = orig_node->router->orig_node; - - /* if we have something in the primary_addr, we can search - * for a potential bonding candidate. */ - if (memcmp(router_orig->primary_addr, zero_mac, ETH_ALEN) == 0) - return orig_node->router; - - /* find the orig_node which has the primary interface. might - * even be the same as our router_orig in many cases */ - - if (memcmp(router_orig->primary_addr, - router_orig->orig, ETH_ALEN) == 0) { - primary_orig_node = router_orig; - } else { - primary_orig_node = hash_find(bat_priv->orig_hash, compare_orig, - choose_orig, - router_orig->primary_addr); - - if (!primary_orig_node) - return orig_node->router; - } - - /* with less than 2 candidates, we can't do any - * bonding and prefer the original router. */ - - if (primary_orig_node->bond.candidates < 2) - return orig_node->router; - - - /* all nodes between should choose a candidate which - * is is not on the interface where the packet came - * in. */ - first_candidate = primary_orig_node->bond.selected; - router = first_candidate; - - if (bonding_enabled) { - /* in the bonding case, send the packets in a round - * robin fashion over the remaining interfaces. */ - do { - /* recv_if == NULL on the first node. */ - if (router->if_incoming != recv_if) - break; - - router = router->next_bond_candidate; - } while (router != first_candidate); - - primary_orig_node->bond.selected = router->next_bond_candidate; - - } else { - /* if bonding is disabled, use the best of the - * remaining candidates which are not using - * this interface. */ - best_router = first_candidate; - - do { - /* recv_if == NULL on the first node. */ - if ((router->if_incoming != recv_if) && - (router->tq_avg > best_router->tq_avg)) - best_router = router; - - router = router->next_bond_candidate; - } while (router != first_candidate); - - router = best_router; - } - - return router; -} - -static int check_unicast_packet(struct sk_buff *skb, int hdr_size) -{ - struct ethhdr *ethhdr; - - /* drop packet if it has not necessary minimum size */ - if (unlikely(!pskb_may_pull(skb, hdr_size))) - return -1; - - ethhdr = (struct ethhdr *)skb_mac_header(skb); - - /* packet with unicast indication but broadcast recipient */ - if (is_broadcast_ether_addr(ethhdr->h_dest)) - return -1; - - /* packet with broadcast sender address */ - if (is_broadcast_ether_addr(ethhdr->h_source)) - return -1; - - /* not for me */ - if (!is_my_mac(ethhdr->h_dest)) - return -1; - - return 0; -} - -int route_unicast_packet(struct sk_buff *skb, struct batman_if *recv_if, - int hdr_size) -{ - struct bat_priv *bat_priv = netdev_priv(recv_if->soft_iface); - struct orig_node *orig_node; - struct neigh_node *router; - struct batman_if *batman_if; - uint8_t dstaddr[ETH_ALEN]; - struct unicast_packet *unicast_packet; - struct ethhdr *ethhdr = (struct ethhdr *)skb_mac_header(skb); - int ret; - struct sk_buff *new_skb; - - unicast_packet = (struct unicast_packet *)skb->data; - - /* TTL exceeded */ - if (unicast_packet->ttl < 2) { - pr_debug("Warning - can't forward unicast packet from %pM to " - "%pM: ttl exceeded\n", ethhdr->h_source, - unicast_packet->dest); - return NET_RX_DROP; - } - - /* get routing information */ - spin_lock_bh(&bat_priv->orig_hash_lock); - orig_node = ((struct orig_node *) - hash_find(bat_priv->orig_hash, compare_orig, choose_orig, - unicast_packet->dest)); - - router = find_router(bat_priv, orig_node, recv_if); - - if (!router) { - spin_unlock_bh(&bat_priv->orig_hash_lock); - return NET_RX_DROP; - } - - /* don't lock while sending the packets ... we therefore - * copy the required data before sending */ - - batman_if = router->if_incoming; - memcpy(dstaddr, router->addr, ETH_ALEN); - - spin_unlock_bh(&bat_priv->orig_hash_lock); - - /* create a copy of the skb, if needed, to modify it. */ - if (skb_cow(skb, sizeof(struct ethhdr)) < 0) - return NET_RX_DROP; - - unicast_packet = (struct unicast_packet *)skb->data; - - if (unicast_packet->packet_type == BAT_UNICAST && - atomic_read(&bat_priv->fragmentation) && - skb->len > batman_if->net_dev->mtu) - return frag_send_skb(skb, bat_priv, batman_if, - dstaddr); - - if (unicast_packet->packet_type == BAT_UNICAST_FRAG && - 2 * skb->len - hdr_size <= batman_if->net_dev->mtu) { - - ret = frag_reassemble_skb(skb, bat_priv, &new_skb); - - if (ret == NET_RX_DROP) - return NET_RX_DROP; - - /* packet was buffered for late merge */ - if (!new_skb) - return NET_RX_SUCCESS; - - skb = new_skb; - unicast_packet = (struct unicast_packet *)skb->data; - } - - /* decrement ttl */ - unicast_packet->ttl--; - - /* route it */ - send_skb_packet(skb, batman_if, dstaddr); - - return NET_RX_SUCCESS; -} - -int recv_unicast_packet(struct sk_buff *skb, struct batman_if *recv_if) -{ - struct unicast_packet *unicast_packet; - int hdr_size = sizeof(struct unicast_packet); - - if (check_unicast_packet(skb, hdr_size) < 0) - return NET_RX_DROP; - - unicast_packet = (struct unicast_packet *)skb->data; - - /* packet for me */ - if (is_my_mac(unicast_packet->dest)) { - interface_rx(recv_if->soft_iface, skb, recv_if, hdr_size); - return NET_RX_SUCCESS; - } - - return route_unicast_packet(skb, recv_if, hdr_size); -} - -int recv_ucast_frag_packet(struct sk_buff *skb, struct batman_if *recv_if) -{ - struct bat_priv *bat_priv = netdev_priv(recv_if->soft_iface); - struct unicast_frag_packet *unicast_packet; - int hdr_size = sizeof(struct unicast_frag_packet); - struct sk_buff *new_skb = NULL; - int ret; - - if (check_unicast_packet(skb, hdr_size) < 0) - return NET_RX_DROP; - - unicast_packet = (struct unicast_frag_packet *)skb->data; - - /* packet for me */ - if (is_my_mac(unicast_packet->dest)) { - - ret = frag_reassemble_skb(skb, bat_priv, &new_skb); - - if (ret == NET_RX_DROP) - return NET_RX_DROP; - - /* packet was buffered for late merge */ - if (!new_skb) - return NET_RX_SUCCESS; - - interface_rx(recv_if->soft_iface, new_skb, recv_if, - sizeof(struct unicast_packet)); - return NET_RX_SUCCESS; - } - - return route_unicast_packet(skb, recv_if, hdr_size); -} - - -int recv_bcast_packet(struct sk_buff *skb, struct batman_if *recv_if) -{ - struct bat_priv *bat_priv = netdev_priv(recv_if->soft_iface); - struct orig_node *orig_node; - struct bcast_packet *bcast_packet; - struct ethhdr *ethhdr; - int hdr_size = sizeof(struct bcast_packet); - int32_t seq_diff; - - /* drop packet if it has not necessary minimum size */ - if (unlikely(!pskb_may_pull(skb, hdr_size))) - return NET_RX_DROP; - - ethhdr = (struct ethhdr *)skb_mac_header(skb); - - /* packet with broadcast indication but unicast recipient */ - if (!is_broadcast_ether_addr(ethhdr->h_dest)) - return NET_RX_DROP; - - /* packet with broadcast sender address */ - if (is_broadcast_ether_addr(ethhdr->h_source)) - return NET_RX_DROP; - - /* ignore broadcasts sent by myself */ - if (is_my_mac(ethhdr->h_source)) - return NET_RX_DROP; - - bcast_packet = (struct bcast_packet *)skb->data; - - /* ignore broadcasts originated by myself */ - if (is_my_mac(bcast_packet->orig)) - return NET_RX_DROP; - - if (bcast_packet->ttl < 2) - return NET_RX_DROP; - - spin_lock_bh(&bat_priv->orig_hash_lock); - orig_node = ((struct orig_node *) - hash_find(bat_priv->orig_hash, compare_orig, choose_orig, - bcast_packet->orig)); - - if (orig_node == NULL) { - spin_unlock_bh(&bat_priv->orig_hash_lock); - return NET_RX_DROP; - } - - /* check whether the packet is a duplicate */ - if (get_bit_status(orig_node->bcast_bits, - orig_node->last_bcast_seqno, - ntohl(bcast_packet->seqno))) { - spin_unlock_bh(&bat_priv->orig_hash_lock); - return NET_RX_DROP; - } - - seq_diff = ntohl(bcast_packet->seqno) - orig_node->last_bcast_seqno; - - /* check whether the packet is old and the host just restarted. */ - if (window_protected(bat_priv, seq_diff, - &orig_node->bcast_seqno_reset)) { - spin_unlock_bh(&bat_priv->orig_hash_lock); - return NET_RX_DROP; - } - - /* mark broadcast in flood history, update window position - * if required. */ - if (bit_get_packet(bat_priv, orig_node->bcast_bits, seq_diff, 1)) - orig_node->last_bcast_seqno = ntohl(bcast_packet->seqno); - - spin_unlock_bh(&bat_priv->orig_hash_lock); - /* rebroadcast packet */ - add_bcast_packet_to_list(bat_priv, skb); - - /* broadcast for me */ - interface_rx(recv_if->soft_iface, skb, recv_if, hdr_size); - - return NET_RX_SUCCESS; -} - -int recv_vis_packet(struct sk_buff *skb, struct batman_if *recv_if) -{ - struct vis_packet *vis_packet; - struct ethhdr *ethhdr; - struct bat_priv *bat_priv = netdev_priv(recv_if->soft_iface); - int hdr_size = sizeof(struct vis_packet); - - /* keep skb linear */ - if (skb_linearize(skb) < 0) - return NET_RX_DROP; - - if (unlikely(!pskb_may_pull(skb, hdr_size))) - return NET_RX_DROP; - - vis_packet = (struct vis_packet *)skb->data; - ethhdr = (struct ethhdr *)skb_mac_header(skb); - - /* not for me */ - if (!is_my_mac(ethhdr->h_dest)) - return NET_RX_DROP; - - /* ignore own packets */ - if (is_my_mac(vis_packet->vis_orig)) - return NET_RX_DROP; - - if (is_my_mac(vis_packet->sender_orig)) - return NET_RX_DROP; - - switch (vis_packet->vis_type) { - case VIS_TYPE_SERVER_SYNC: - receive_server_sync_packet(bat_priv, vis_packet, - skb_headlen(skb)); - break; - - case VIS_TYPE_CLIENT_UPDATE: - receive_client_update_packet(bat_priv, vis_packet, - skb_headlen(skb)); - break; - - default: /* ignore unknown packet */ - break; - } - - /* We take a copy of the data in the packet, so we should - always free the skbuf. */ - return NET_RX_DROP; -} diff --git a/drivers/staging/batman-adv/routing.h b/drivers/staging/batman-adv/routing.h deleted file mode 100644 index f108f230bfdb..000000000000 --- a/drivers/staging/batman-adv/routing.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: - * - * Marek Lindner, Simon Wunderlich - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License 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. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA - * - */ - -#ifndef _NET_BATMAN_ADV_ROUTING_H_ -#define _NET_BATMAN_ADV_ROUTING_H_ - -#include "types.h" - -void slide_own_bcast_window(struct batman_if *batman_if); -void receive_bat_packet(struct ethhdr *ethhdr, - struct batman_packet *batman_packet, - unsigned char *hna_buff, int hna_buff_len, - struct batman_if *if_incoming); -void update_routes(struct bat_priv *bat_priv, struct orig_node *orig_node, - struct neigh_node *neigh_node, unsigned char *hna_buff, - int hna_buff_len); -int route_unicast_packet(struct sk_buff *skb, struct batman_if *recv_if, - int hdr_size); -int recv_icmp_packet(struct sk_buff *skb, struct batman_if *recv_if); -int recv_unicast_packet(struct sk_buff *skb, struct batman_if *recv_if); -int recv_ucast_frag_packet(struct sk_buff *skb, struct batman_if *recv_if); -int recv_bcast_packet(struct sk_buff *skb, struct batman_if *recv_if); -int recv_vis_packet(struct sk_buff *skb, struct batman_if *recv_if); -int recv_bat_packet(struct sk_buff *skb, struct batman_if *recv_if); -struct neigh_node *find_router(struct bat_priv *bat_priv, - struct orig_node *orig_node, struct batman_if *recv_if); -void update_bonding_candidates(struct bat_priv *bat_priv, - struct orig_node *orig_node); - -#endif /* _NET_BATMAN_ADV_ROUTING_H_ */ diff --git a/drivers/staging/batman-adv/send.c b/drivers/staging/batman-adv/send.c deleted file mode 100644 index 36945dc5a44b..000000000000 --- a/drivers/staging/batman-adv/send.c +++ /dev/null @@ -1,586 +0,0 @@ -/* - * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: - * - * Marek Lindner, Simon Wunderlich - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License 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. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA - * - */ - -#include "main.h" -#include "send.h" -#include "routing.h" -#include "translation-table.h" -#include "soft-interface.h" -#include "hard-interface.h" -#include "types.h" -#include "vis.h" -#include "aggregation.h" -#include "gateway_common.h" -#include "originator.h" - - -static void send_outstanding_bcast_packet(struct work_struct *work); - -/* apply hop penalty for a normal link */ -static uint8_t hop_penalty(const uint8_t tq, struct bat_priv *bat_priv) -{ - int hop_penalty = atomic_read(&bat_priv->hop_penalty); - return (tq * (TQ_MAX_VALUE - hop_penalty)) / (TQ_MAX_VALUE); -} - -/* when do we schedule our own packet to be sent */ -static unsigned long own_send_time(struct bat_priv *bat_priv) -{ - return jiffies + msecs_to_jiffies( - atomic_read(&bat_priv->orig_interval) - - JITTER + (random32() % 2*JITTER)); -} - -/* when do we schedule a forwarded packet to be sent */ -static unsigned long forward_send_time(struct bat_priv *bat_priv) -{ - return jiffies + msecs_to_jiffies(random32() % (JITTER/2)); -} - -/* send out an already prepared packet to the given address via the - * specified batman interface */ -int send_skb_packet(struct sk_buff *skb, - struct batman_if *batman_if, - uint8_t *dst_addr) -{ - struct ethhdr *ethhdr; - - if (batman_if->if_status != IF_ACTIVE) - goto send_skb_err; - - if (unlikely(!batman_if->net_dev)) - goto send_skb_err; - - if (!(batman_if->net_dev->flags & IFF_UP)) { - pr_warning("Interface %s is not up - can't send packet via " - "that interface!\n", batman_if->net_dev->name); - goto send_skb_err; - } - - /* push to the ethernet header. */ - if (my_skb_head_push(skb, sizeof(struct ethhdr)) < 0) - goto send_skb_err; - - skb_reset_mac_header(skb); - - ethhdr = (struct ethhdr *) skb_mac_header(skb); - memcpy(ethhdr->h_source, batman_if->net_dev->dev_addr, ETH_ALEN); - memcpy(ethhdr->h_dest, dst_addr, ETH_ALEN); - ethhdr->h_proto = __constant_htons(ETH_P_BATMAN); - - skb_set_network_header(skb, ETH_HLEN); - skb->priority = TC_PRIO_CONTROL; - skb->protocol = __constant_htons(ETH_P_BATMAN); - - skb->dev = batman_if->net_dev; - - /* dev_queue_xmit() returns a negative result on error. However on - * congestion and traffic shaping, it drops and returns NET_XMIT_DROP - * (which is > 0). This will not be treated as an error. */ - - return dev_queue_xmit(skb); -send_skb_err: - kfree_skb(skb); - return NET_XMIT_DROP; -} - -/* Send a packet to a given interface */ -static void send_packet_to_if(struct forw_packet *forw_packet, - struct batman_if *batman_if) -{ - struct bat_priv *bat_priv = netdev_priv(batman_if->soft_iface); - char *fwd_str; - uint8_t packet_num; - int16_t buff_pos; - struct batman_packet *batman_packet; - struct sk_buff *skb; - - if (batman_if->if_status != IF_ACTIVE) - return; - - packet_num = 0; - buff_pos = 0; - batman_packet = (struct batman_packet *)forw_packet->skb->data; - - /* adjust all flags and log packets */ - while (aggregated_packet(buff_pos, - forw_packet->packet_len, - batman_packet->num_hna)) { - - /* we might have aggregated direct link packets with an - * ordinary base packet */ - if ((forw_packet->direct_link_flags & (1 << packet_num)) && - (forw_packet->if_incoming == batman_if)) - batman_packet->flags |= DIRECTLINK; - else - batman_packet->flags &= ~DIRECTLINK; - - fwd_str = (packet_num > 0 ? "Forwarding" : (forw_packet->own ? - "Sending own" : - "Forwarding")); - bat_dbg(DBG_BATMAN, bat_priv, - "%s %spacket (originator %pM, seqno %d, TQ %d, TTL %d," - " IDF %s) on interface %s [%pM]\n", - fwd_str, (packet_num > 0 ? "aggregated " : ""), - batman_packet->orig, ntohl(batman_packet->seqno), - batman_packet->tq, batman_packet->ttl, - (batman_packet->flags & DIRECTLINK ? - "on" : "off"), - batman_if->net_dev->name, batman_if->net_dev->dev_addr); - - buff_pos += sizeof(struct batman_packet) + - (batman_packet->num_hna * ETH_ALEN); - packet_num++; - batman_packet = (struct batman_packet *) - (forw_packet->skb->data + buff_pos); - } - - /* create clone because function is called more than once */ - skb = skb_clone(forw_packet->skb, GFP_ATOMIC); - if (skb) - send_skb_packet(skb, batman_if, broadcast_addr); -} - -/* send a batman packet */ -static void send_packet(struct forw_packet *forw_packet) -{ - struct batman_if *batman_if; - struct net_device *soft_iface; - struct bat_priv *bat_priv; - struct batman_packet *batman_packet = - (struct batman_packet *)(forw_packet->skb->data); - unsigned char directlink = (batman_packet->flags & DIRECTLINK ? 1 : 0); - - if (!forw_packet->if_incoming) { - pr_err("Error - can't forward packet: incoming iface not " - "specified\n"); - return; - } - - soft_iface = forw_packet->if_incoming->soft_iface; - bat_priv = netdev_priv(soft_iface); - - if (forw_packet->if_incoming->if_status != IF_ACTIVE) - return; - - /* multihomed peer assumed */ - /* non-primary OGMs are only broadcasted on their interface */ - if ((directlink && (batman_packet->ttl == 1)) || - (forw_packet->own && (forw_packet->if_incoming->if_num > 0))) { - - /* FIXME: what about aggregated packets ? */ - bat_dbg(DBG_BATMAN, bat_priv, - "%s packet (originator %pM, seqno %d, TTL %d) " - "on interface %s [%pM]\n", - (forw_packet->own ? "Sending own" : "Forwarding"), - batman_packet->orig, ntohl(batman_packet->seqno), - batman_packet->ttl, - forw_packet->if_incoming->net_dev->name, - forw_packet->if_incoming->net_dev->dev_addr); - - /* skb is only used once and than forw_packet is free'd */ - send_skb_packet(forw_packet->skb, forw_packet->if_incoming, - broadcast_addr); - forw_packet->skb = NULL; - - return; - } - - /* broadcast on every interface */ - rcu_read_lock(); - list_for_each_entry_rcu(batman_if, &if_list, list) { - if (batman_if->soft_iface != soft_iface) - continue; - - send_packet_to_if(forw_packet, batman_if); - } - rcu_read_unlock(); -} - -static void rebuild_batman_packet(struct bat_priv *bat_priv, - struct batman_if *batman_if) -{ - int new_len; - unsigned char *new_buff; - struct batman_packet *batman_packet; - - new_len = sizeof(struct batman_packet) + - (bat_priv->num_local_hna * ETH_ALEN); - new_buff = kmalloc(new_len, GFP_ATOMIC); - - /* keep old buffer if kmalloc should fail */ - if (new_buff) { - memcpy(new_buff, batman_if->packet_buff, - sizeof(struct batman_packet)); - batman_packet = (struct batman_packet *)new_buff; - - batman_packet->num_hna = hna_local_fill_buffer(bat_priv, - new_buff + sizeof(struct batman_packet), - new_len - sizeof(struct batman_packet)); - - kfree(batman_if->packet_buff); - batman_if->packet_buff = new_buff; - batman_if->packet_len = new_len; - } -} - -void schedule_own_packet(struct batman_if *batman_if) -{ - struct bat_priv *bat_priv = netdev_priv(batman_if->soft_iface); - unsigned long send_time; - struct batman_packet *batman_packet; - int vis_server; - - if ((batman_if->if_status == IF_NOT_IN_USE) || - (batman_if->if_status == IF_TO_BE_REMOVED)) - return; - - vis_server = atomic_read(&bat_priv->vis_mode); - - /** - * the interface gets activated here to avoid race conditions between - * the moment of activating the interface in - * hardif_activate_interface() where the originator mac is set and - * outdated packets (especially uninitialized mac addresses) in the - * packet queue - */ - if (batman_if->if_status == IF_TO_BE_ACTIVATED) - batman_if->if_status = IF_ACTIVE; - - /* if local hna has changed and interface is a primary interface */ - if ((atomic_read(&bat_priv->hna_local_changed)) && - (batman_if == bat_priv->primary_if)) - rebuild_batman_packet(bat_priv, batman_if); - - /** - * NOTE: packet_buff might just have been re-allocated in - * rebuild_batman_packet() - */ - batman_packet = (struct batman_packet *)batman_if->packet_buff; - - /* change sequence number to network order */ - batman_packet->seqno = - htonl((uint32_t)atomic_read(&batman_if->seqno)); - - if (vis_server == VIS_TYPE_SERVER_SYNC) - batman_packet->flags |= VIS_SERVER; - else - batman_packet->flags &= ~VIS_SERVER; - - if ((batman_if == bat_priv->primary_if) && - (atomic_read(&bat_priv->gw_mode) == GW_MODE_SERVER)) - batman_packet->gw_flags = - (uint8_t)atomic_read(&bat_priv->gw_bandwidth); - else - batman_packet->gw_flags = 0; - - atomic_inc(&batman_if->seqno); - - slide_own_bcast_window(batman_if); - send_time = own_send_time(bat_priv); - add_bat_packet_to_list(bat_priv, - batman_if->packet_buff, - batman_if->packet_len, - batman_if, 1, send_time); -} - -void schedule_forward_packet(struct orig_node *orig_node, - struct ethhdr *ethhdr, - struct batman_packet *batman_packet, - uint8_t directlink, int hna_buff_len, - struct batman_if *if_incoming) -{ - struct bat_priv *bat_priv = netdev_priv(if_incoming->soft_iface); - unsigned char in_tq, in_ttl, tq_avg = 0; - unsigned long send_time; - - if (batman_packet->ttl <= 1) { - bat_dbg(DBG_BATMAN, bat_priv, "ttl exceeded\n"); - return; - } - - in_tq = batman_packet->tq; - in_ttl = batman_packet->ttl; - - batman_packet->ttl--; - memcpy(batman_packet->prev_sender, ethhdr->h_source, ETH_ALEN); - - /* rebroadcast tq of our best ranking neighbor to ensure the rebroadcast - * of our best tq value */ - if ((orig_node->router) && (orig_node->router->tq_avg != 0)) { - - /* rebroadcast ogm of best ranking neighbor as is */ - if (!compare_orig(orig_node->router->addr, ethhdr->h_source)) { - batman_packet->tq = orig_node->router->tq_avg; - - if (orig_node->router->last_ttl) - batman_packet->ttl = orig_node->router->last_ttl - - 1; - } - - tq_avg = orig_node->router->tq_avg; - } - - /* apply hop penalty */ - batman_packet->tq = hop_penalty(batman_packet->tq, bat_priv); - - bat_dbg(DBG_BATMAN, bat_priv, - "Forwarding packet: tq_orig: %i, tq_avg: %i, " - "tq_forw: %i, ttl_orig: %i, ttl_forw: %i\n", - in_tq, tq_avg, batman_packet->tq, in_ttl - 1, - batman_packet->ttl); - - batman_packet->seqno = htonl(batman_packet->seqno); - - /* switch of primaries first hop flag when forwarding */ - batman_packet->flags &= ~PRIMARIES_FIRST_HOP; - if (directlink) - batman_packet->flags |= DIRECTLINK; - else - batman_packet->flags &= ~DIRECTLINK; - - send_time = forward_send_time(bat_priv); - add_bat_packet_to_list(bat_priv, - (unsigned char *)batman_packet, - sizeof(struct batman_packet) + hna_buff_len, - if_incoming, 0, send_time); -} - -static void forw_packet_free(struct forw_packet *forw_packet) -{ - if (forw_packet->skb) - kfree_skb(forw_packet->skb); - kfree(forw_packet); -} - -static void _add_bcast_packet_to_list(struct bat_priv *bat_priv, - struct forw_packet *forw_packet, - unsigned long send_time) -{ - INIT_HLIST_NODE(&forw_packet->list); - - /* add new packet to packet list */ - spin_lock_bh(&bat_priv->forw_bcast_list_lock); - hlist_add_head(&forw_packet->list, &bat_priv->forw_bcast_list); - spin_unlock_bh(&bat_priv->forw_bcast_list_lock); - - /* start timer for this packet */ - INIT_DELAYED_WORK(&forw_packet->delayed_work, - send_outstanding_bcast_packet); - queue_delayed_work(bat_event_workqueue, &forw_packet->delayed_work, - send_time); -} - -#define atomic_dec_not_zero(v) atomic_add_unless((v), -1, 0) -/* add a broadcast packet to the queue and setup timers. broadcast packets - * are sent multiple times to increase probability for beeing received. - * - * This function returns NETDEV_TX_OK on success and NETDEV_TX_BUSY on - * errors. - * - * The skb is not consumed, so the caller should make sure that the - * skb is freed. */ -int add_bcast_packet_to_list(struct bat_priv *bat_priv, struct sk_buff *skb) -{ - struct forw_packet *forw_packet; - struct bcast_packet *bcast_packet; - - if (!atomic_dec_not_zero(&bat_priv->bcast_queue_left)) { - bat_dbg(DBG_BATMAN, bat_priv, "bcast packet queue full\n"); - goto out; - } - - if (!bat_priv->primary_if) - goto out; - - forw_packet = kmalloc(sizeof(struct forw_packet), GFP_ATOMIC); - - if (!forw_packet) - goto out_and_inc; - - skb = skb_copy(skb, GFP_ATOMIC); - if (!skb) - goto packet_free; - - /* as we have a copy now, it is safe to decrease the TTL */ - bcast_packet = (struct bcast_packet *)skb->data; - bcast_packet->ttl--; - - skb_reset_mac_header(skb); - - forw_packet->skb = skb; - forw_packet->if_incoming = bat_priv->primary_if; - - /* how often did we send the bcast packet ? */ - forw_packet->num_packets = 0; - - _add_bcast_packet_to_list(bat_priv, forw_packet, 1); - return NETDEV_TX_OK; - -packet_free: - kfree(forw_packet); -out_and_inc: - atomic_inc(&bat_priv->bcast_queue_left); -out: - return NETDEV_TX_BUSY; -} - -static void send_outstanding_bcast_packet(struct work_struct *work) -{ - struct batman_if *batman_if; - struct delayed_work *delayed_work = - container_of(work, struct delayed_work, work); - struct forw_packet *forw_packet = - container_of(delayed_work, struct forw_packet, delayed_work); - struct sk_buff *skb1; - struct net_device *soft_iface = forw_packet->if_incoming->soft_iface; - struct bat_priv *bat_priv = netdev_priv(soft_iface); - - spin_lock_bh(&bat_priv->forw_bcast_list_lock); - hlist_del(&forw_packet->list); - spin_unlock_bh(&bat_priv->forw_bcast_list_lock); - - if (atomic_read(&bat_priv->mesh_state) == MESH_DEACTIVATING) - goto out; - - /* rebroadcast packet */ - rcu_read_lock(); - list_for_each_entry_rcu(batman_if, &if_list, list) { - if (batman_if->soft_iface != soft_iface) - continue; - - /* send a copy of the saved skb */ - skb1 = skb_clone(forw_packet->skb, GFP_ATOMIC); - if (skb1) - send_skb_packet(skb1, batman_if, broadcast_addr); - } - rcu_read_unlock(); - - forw_packet->num_packets++; - - /* if we still have some more bcasts to send */ - if (forw_packet->num_packets < 3) { - _add_bcast_packet_to_list(bat_priv, forw_packet, - ((5 * HZ) / 1000)); - return; - } - -out: - forw_packet_free(forw_packet); - atomic_inc(&bat_priv->bcast_queue_left); -} - -void send_outstanding_bat_packet(struct work_struct *work) -{ - struct delayed_work *delayed_work = - container_of(work, struct delayed_work, work); - struct forw_packet *forw_packet = - container_of(delayed_work, struct forw_packet, delayed_work); - struct bat_priv *bat_priv; - - bat_priv = netdev_priv(forw_packet->if_incoming->soft_iface); - spin_lock_bh(&bat_priv->forw_bat_list_lock); - hlist_del(&forw_packet->list); - spin_unlock_bh(&bat_priv->forw_bat_list_lock); - - if (atomic_read(&bat_priv->mesh_state) == MESH_DEACTIVATING) - goto out; - - send_packet(forw_packet); - - /** - * we have to have at least one packet in the queue - * to determine the queues wake up time unless we are - * shutting down - */ - if (forw_packet->own) - schedule_own_packet(forw_packet->if_incoming); - -out: - /* don't count own packet */ - if (!forw_packet->own) - atomic_inc(&bat_priv->batman_queue_left); - - forw_packet_free(forw_packet); -} - -void purge_outstanding_packets(struct bat_priv *bat_priv, - struct batman_if *batman_if) -{ - struct forw_packet *forw_packet; - struct hlist_node *tmp_node, *safe_tmp_node; - - if (batman_if) - bat_dbg(DBG_BATMAN, bat_priv, - "purge_outstanding_packets(): %s\n", - batman_if->net_dev->name); - else - bat_dbg(DBG_BATMAN, bat_priv, - "purge_outstanding_packets()\n"); - - /* free bcast list */ - spin_lock_bh(&bat_priv->forw_bcast_list_lock); - hlist_for_each_entry_safe(forw_packet, tmp_node, safe_tmp_node, - &bat_priv->forw_bcast_list, list) { - - /** - * if purge_outstanding_packets() was called with an argmument - * we delete only packets belonging to the given interface - */ - if ((batman_if) && - (forw_packet->if_incoming != batman_if)) - continue; - - spin_unlock_bh(&bat_priv->forw_bcast_list_lock); - - /** - * send_outstanding_bcast_packet() will lock the list to - * delete the item from the list - */ - cancel_delayed_work_sync(&forw_packet->delayed_work); - spin_lock_bh(&bat_priv->forw_bcast_list_lock); - } - spin_unlock_bh(&bat_priv->forw_bcast_list_lock); - - /* free batman packet list */ - spin_lock_bh(&bat_priv->forw_bat_list_lock); - hlist_for_each_entry_safe(forw_packet, tmp_node, safe_tmp_node, - &bat_priv->forw_bat_list, list) { - - /** - * if purge_outstanding_packets() was called with an argmument - * we delete only packets belonging to the given interface - */ - if ((batman_if) && - (forw_packet->if_incoming != batman_if)) - continue; - - spin_unlock_bh(&bat_priv->forw_bat_list_lock); - - /** - * send_outstanding_bat_packet() will lock the list to - * delete the item from the list - */ - cancel_delayed_work_sync(&forw_packet->delayed_work); - spin_lock_bh(&bat_priv->forw_bat_list_lock); - } - spin_unlock_bh(&bat_priv->forw_bat_list_lock); -} diff --git a/drivers/staging/batman-adv/send.h b/drivers/staging/batman-adv/send.h deleted file mode 100644 index c4cefa8e4f85..000000000000 --- a/drivers/staging/batman-adv/send.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: - * - * Marek Lindner, Simon Wunderlich - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License 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. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA - * - */ - -#ifndef _NET_BATMAN_ADV_SEND_H_ -#define _NET_BATMAN_ADV_SEND_H_ - -#include "types.h" - -int send_skb_packet(struct sk_buff *skb, - struct batman_if *batman_if, - uint8_t *dst_addr); -void schedule_own_packet(struct batman_if *batman_if); -void schedule_forward_packet(struct orig_node *orig_node, - struct ethhdr *ethhdr, - struct batman_packet *batman_packet, - uint8_t directlink, int hna_buff_len, - struct batman_if *if_outgoing); -int add_bcast_packet_to_list(struct bat_priv *bat_priv, struct sk_buff *skb); -void send_outstanding_bat_packet(struct work_struct *work); -void purge_outstanding_packets(struct bat_priv *bat_priv, - struct batman_if *batman_if); - -#endif /* _NET_BATMAN_ADV_SEND_H_ */ diff --git a/drivers/staging/batman-adv/soft-interface.c b/drivers/staging/batman-adv/soft-interface.c deleted file mode 100644 index e89ede192ed0..000000000000 --- a/drivers/staging/batman-adv/soft-interface.c +++ /dev/null @@ -1,697 +0,0 @@ -/* - * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: - * - * Marek Lindner, Simon Wunderlich - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License 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. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA - * - */ - -#include "main.h" -#include "soft-interface.h" -#include "hard-interface.h" -#include "routing.h" -#include "send.h" -#include "bat_debugfs.h" -#include "translation-table.h" -#include "types.h" -#include "hash.h" -#include "gateway_common.h" -#include "gateway_client.h" -#include "send.h" -#include "bat_sysfs.h" -#include -#include -#include -#include -#include "unicast.h" -#include "routing.h" - - -static int bat_get_settings(struct net_device *dev, struct ethtool_cmd *cmd); -static void bat_get_drvinfo(struct net_device *dev, - struct ethtool_drvinfo *info); -static u32 bat_get_msglevel(struct net_device *dev); -static void bat_set_msglevel(struct net_device *dev, u32 value); -static u32 bat_get_link(struct net_device *dev); -static u32 bat_get_rx_csum(struct net_device *dev); -static int bat_set_rx_csum(struct net_device *dev, u32 data); - -static const struct ethtool_ops bat_ethtool_ops = { - .get_settings = bat_get_settings, - .get_drvinfo = bat_get_drvinfo, - .get_msglevel = bat_get_msglevel, - .set_msglevel = bat_set_msglevel, - .get_link = bat_get_link, - .get_rx_csum = bat_get_rx_csum, - .set_rx_csum = bat_set_rx_csum -}; - -int my_skb_head_push(struct sk_buff *skb, unsigned int len) -{ - int result; - - /** - * TODO: We must check if we can release all references to non-payload - * data using skb_header_release in our skbs to allow skb_cow_header to - * work optimally. This means that those skbs are not allowed to read - * or write any data which is before the current position of skb->data - * after that call and thus allow other skbs with the same data buffer - * to write freely in that area. - */ - result = skb_cow_head(skb, len); - if (result < 0) - return result; - - skb_push(skb, len); - return 0; -} - -static void softif_neigh_free_ref(struct kref *refcount) -{ - struct softif_neigh *softif_neigh; - - softif_neigh = container_of(refcount, struct softif_neigh, refcount); - kfree(softif_neigh); -} - -static void softif_neigh_free_rcu(struct rcu_head *rcu) -{ - struct softif_neigh *softif_neigh; - - softif_neigh = container_of(rcu, struct softif_neigh, rcu); - kref_put(&softif_neigh->refcount, softif_neigh_free_ref); -} - -void softif_neigh_purge(struct bat_priv *bat_priv) -{ - struct softif_neigh *softif_neigh, *softif_neigh_tmp; - struct hlist_node *node, *node_tmp; - - spin_lock_bh(&bat_priv->softif_neigh_lock); - - hlist_for_each_entry_safe(softif_neigh, node, node_tmp, - &bat_priv->softif_neigh_list, list) { - - if ((!time_after(jiffies, softif_neigh->last_seen + - msecs_to_jiffies(SOFTIF_NEIGH_TIMEOUT))) && - (atomic_read(&bat_priv->mesh_state) == MESH_ACTIVE)) - continue; - - hlist_del_rcu(&softif_neigh->list); - - if (bat_priv->softif_neigh == softif_neigh) { - bat_dbg(DBG_ROUTES, bat_priv, - "Current mesh exit point '%pM' vanished " - "(vid: %d).\n", - softif_neigh->addr, softif_neigh->vid); - softif_neigh_tmp = bat_priv->softif_neigh; - bat_priv->softif_neigh = NULL; - kref_put(&softif_neigh_tmp->refcount, - softif_neigh_free_ref); - } - - call_rcu(&softif_neigh->rcu, softif_neigh_free_rcu); - } - - spin_unlock_bh(&bat_priv->softif_neigh_lock); -} - -static struct softif_neigh *softif_neigh_get(struct bat_priv *bat_priv, - uint8_t *addr, short vid) -{ - struct softif_neigh *softif_neigh; - struct hlist_node *node; - - rcu_read_lock(); - hlist_for_each_entry_rcu(softif_neigh, node, - &bat_priv->softif_neigh_list, list) { - if (memcmp(softif_neigh->addr, addr, ETH_ALEN) != 0) - continue; - - if (softif_neigh->vid != vid) - continue; - - softif_neigh->last_seen = jiffies; - goto found; - } - - softif_neigh = kzalloc(sizeof(struct softif_neigh), GFP_ATOMIC); - if (!softif_neigh) - goto out; - - memcpy(softif_neigh->addr, addr, ETH_ALEN); - softif_neigh->vid = vid; - softif_neigh->last_seen = jiffies; - kref_init(&softif_neigh->refcount); - - INIT_HLIST_NODE(&softif_neigh->list); - spin_lock_bh(&bat_priv->softif_neigh_lock); - hlist_add_head_rcu(&softif_neigh->list, &bat_priv->softif_neigh_list); - spin_unlock_bh(&bat_priv->softif_neigh_lock); - -found: - kref_get(&softif_neigh->refcount); -out: - rcu_read_unlock(); - return softif_neigh; -} - -int softif_neigh_seq_print_text(struct seq_file *seq, void *offset) -{ - struct net_device *net_dev = (struct net_device *)seq->private; - struct bat_priv *bat_priv = netdev_priv(net_dev); - struct softif_neigh *softif_neigh; - struct hlist_node *node; - size_t buf_size, pos; - char *buff; - - if (!bat_priv->primary_if) { - return seq_printf(seq, "BATMAN mesh %s disabled - " - "please specify interfaces to enable it\n", - net_dev->name); - } - - seq_printf(seq, "Softif neighbor list (%s)\n", net_dev->name); - - buf_size = 1; - /* Estimate length for: " xx:xx:xx:xx:xx:xx\n" */ - rcu_read_lock(); - hlist_for_each_entry_rcu(softif_neigh, node, - &bat_priv->softif_neigh_list, list) - buf_size += 30; - rcu_read_unlock(); - - buff = kmalloc(buf_size, GFP_ATOMIC); - if (!buff) - return -ENOMEM; - - buff[0] = '\0'; - pos = 0; - - rcu_read_lock(); - hlist_for_each_entry_rcu(softif_neigh, node, - &bat_priv->softif_neigh_list, list) { - pos += snprintf(buff + pos, 31, "%s %pM (vid: %d)\n", - bat_priv->softif_neigh == softif_neigh - ? "=>" : " ", softif_neigh->addr, - softif_neigh->vid); - } - rcu_read_unlock(); - - seq_printf(seq, "%s", buff); - kfree(buff); - return 0; -} - -static void softif_batman_recv(struct sk_buff *skb, struct net_device *dev, - short vid) -{ - struct bat_priv *bat_priv = netdev_priv(dev); - struct ethhdr *ethhdr = (struct ethhdr *)skb->data; - struct batman_packet *batman_packet; - struct softif_neigh *softif_neigh, *softif_neigh_tmp; - - if (ntohs(ethhdr->h_proto) == ETH_P_8021Q) - batman_packet = (struct batman_packet *) - (skb->data + ETH_HLEN + VLAN_HLEN); - else - batman_packet = (struct batman_packet *)(skb->data + ETH_HLEN); - - if (batman_packet->version != COMPAT_VERSION) - goto err; - - if (batman_packet->packet_type != BAT_PACKET) - goto err; - - if (!(batman_packet->flags & PRIMARIES_FIRST_HOP)) - goto err; - - if (is_my_mac(batman_packet->orig)) - goto err; - - softif_neigh = softif_neigh_get(bat_priv, batman_packet->orig, vid); - - if (!softif_neigh) - goto err; - - if (bat_priv->softif_neigh == softif_neigh) - goto out; - - /* we got a neighbor but its mac is 'bigger' than ours */ - if (memcmp(bat_priv->primary_if->net_dev->dev_addr, - softif_neigh->addr, ETH_ALEN) < 0) - goto out; - - /* switch to new 'smallest neighbor' */ - if ((bat_priv->softif_neigh) && - (memcmp(softif_neigh->addr, bat_priv->softif_neigh->addr, - ETH_ALEN) < 0)) { - bat_dbg(DBG_ROUTES, bat_priv, - "Changing mesh exit point from %pM (vid: %d) " - "to %pM (vid: %d).\n", - bat_priv->softif_neigh->addr, - bat_priv->softif_neigh->vid, - softif_neigh->addr, softif_neigh->vid); - softif_neigh_tmp = bat_priv->softif_neigh; - bat_priv->softif_neigh = softif_neigh; - kref_put(&softif_neigh_tmp->refcount, softif_neigh_free_ref); - /* we need to hold the additional reference */ - goto err; - } - - /* close own batX device and use softif_neigh as exit node */ - if ((!bat_priv->softif_neigh) && - (memcmp(softif_neigh->addr, - bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN) < 0)) { - bat_dbg(DBG_ROUTES, bat_priv, - "Setting mesh exit point to %pM (vid: %d).\n", - softif_neigh->addr, softif_neigh->vid); - bat_priv->softif_neigh = softif_neigh; - /* we need to hold the additional reference */ - goto err; - } - -out: - kref_put(&softif_neigh->refcount, softif_neigh_free_ref); -err: - kfree_skb(skb); - return; -} - -static int interface_open(struct net_device *dev) -{ - netif_start_queue(dev); - return 0; -} - -static int interface_release(struct net_device *dev) -{ - netif_stop_queue(dev); - return 0; -} - -static struct net_device_stats *interface_stats(struct net_device *dev) -{ - struct bat_priv *bat_priv = netdev_priv(dev); - return &bat_priv->stats; -} - -static int interface_set_mac_addr(struct net_device *dev, void *p) -{ - struct bat_priv *bat_priv = netdev_priv(dev); - struct sockaddr *addr = p; - - if (!is_valid_ether_addr(addr->sa_data)) - return -EADDRNOTAVAIL; - - /* only modify hna-table if it has been initialised before */ - if (atomic_read(&bat_priv->mesh_state) == MESH_ACTIVE) { - hna_local_remove(bat_priv, dev->dev_addr, - "mac address changed"); - hna_local_add(dev, addr->sa_data); - } - - memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN); - return 0; -} - -static int interface_change_mtu(struct net_device *dev, int new_mtu) -{ - /* check ranges */ - if ((new_mtu < 68) || (new_mtu > hardif_min_mtu(dev))) - return -EINVAL; - - dev->mtu = new_mtu; - - return 0; -} - -int interface_tx(struct sk_buff *skb, struct net_device *soft_iface) -{ - struct ethhdr *ethhdr = (struct ethhdr *)skb->data; - struct bat_priv *bat_priv = netdev_priv(soft_iface); - struct bcast_packet *bcast_packet; - struct vlan_ethhdr *vhdr; - int data_len = skb->len, ret; - short vid = -1; - bool do_bcast = false; - - if (atomic_read(&bat_priv->mesh_state) != MESH_ACTIVE) - goto dropped; - - soft_iface->trans_start = jiffies; - - switch (ntohs(ethhdr->h_proto)) { - case ETH_P_8021Q: - vhdr = (struct vlan_ethhdr *)skb->data; - vid = ntohs(vhdr->h_vlan_TCI) & VLAN_VID_MASK; - - if (ntohs(vhdr->h_vlan_encapsulated_proto) != ETH_P_BATMAN) - break; - - /* fall through */ - case ETH_P_BATMAN: - softif_batman_recv(skb, soft_iface, vid); - goto end; - } - - /** - * if we have a another chosen mesh exit node in range - * it will transport the packets to the mesh - */ - if ((bat_priv->softif_neigh) && (bat_priv->softif_neigh->vid == vid)) - goto dropped; - - /* TODO: check this for locks */ - hna_local_add(soft_iface, ethhdr->h_source); - - if (is_multicast_ether_addr(ethhdr->h_dest)) { - ret = gw_is_target(bat_priv, skb); - - if (ret < 0) - goto dropped; - - if (ret == 0) - do_bcast = true; - } - - /* ethernet packet should be broadcasted */ - if (do_bcast) { - if (!bat_priv->primary_if) - goto dropped; - - if (my_skb_head_push(skb, sizeof(struct bcast_packet)) < 0) - goto dropped; - - bcast_packet = (struct bcast_packet *)skb->data; - bcast_packet->version = COMPAT_VERSION; - bcast_packet->ttl = TTL; - - /* batman packet type: broadcast */ - bcast_packet->packet_type = BAT_BCAST; - - /* hw address of first interface is the orig mac because only - * this mac is known throughout the mesh */ - memcpy(bcast_packet->orig, - bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN); - - /* set broadcast sequence number */ - bcast_packet->seqno = - htonl(atomic_inc_return(&bat_priv->bcast_seqno)); - - add_bcast_packet_to_list(bat_priv, skb); - - /* a copy is stored in the bcast list, therefore removing - * the original skb. */ - kfree_skb(skb); - - /* unicast packet */ - } else { - ret = unicast_send_skb(skb, bat_priv); - if (ret != 0) - goto dropped_freed; - } - - bat_priv->stats.tx_packets++; - bat_priv->stats.tx_bytes += data_len; - goto end; - -dropped: - kfree_skb(skb); -dropped_freed: - bat_priv->stats.tx_dropped++; -end: - return NETDEV_TX_OK; -} - -void interface_rx(struct net_device *soft_iface, - struct sk_buff *skb, struct batman_if *recv_if, - int hdr_size) -{ - struct bat_priv *bat_priv = netdev_priv(soft_iface); - struct unicast_packet *unicast_packet; - struct ethhdr *ethhdr; - struct vlan_ethhdr *vhdr; - short vid = -1; - int ret; - - /* check if enough space is available for pulling, and pull */ - if (!pskb_may_pull(skb, hdr_size)) - goto dropped; - - skb_pull_rcsum(skb, hdr_size); - skb_reset_mac_header(skb); - - ethhdr = (struct ethhdr *)skb_mac_header(skb); - - switch (ntohs(ethhdr->h_proto)) { - case ETH_P_8021Q: - vhdr = (struct vlan_ethhdr *)skb->data; - vid = ntohs(vhdr->h_vlan_TCI) & VLAN_VID_MASK; - - if (ntohs(vhdr->h_vlan_encapsulated_proto) != ETH_P_BATMAN) - break; - - /* fall through */ - case ETH_P_BATMAN: - goto dropped; - } - - /** - * if we have a another chosen mesh exit node in range - * it will transport the packets to the non-mesh network - */ - if ((bat_priv->softif_neigh) && (bat_priv->softif_neigh->vid == vid)) { - skb_push(skb, hdr_size); - unicast_packet = (struct unicast_packet *)skb->data; - - if ((unicast_packet->packet_type != BAT_UNICAST) && - (unicast_packet->packet_type != BAT_UNICAST_FRAG)) - goto dropped; - - skb_reset_mac_header(skb); - - memcpy(unicast_packet->dest, - bat_priv->softif_neigh->addr, ETH_ALEN); - ret = route_unicast_packet(skb, recv_if, hdr_size); - if (ret == NET_RX_DROP) - goto dropped; - - goto out; - } - - /* skb->dev & skb->pkt_type are set here */ - if (unlikely(!pskb_may_pull(skb, ETH_HLEN))) - goto dropped; - skb->protocol = eth_type_trans(skb, soft_iface); - - /* should not be neccesary anymore as we use skb_pull_rcsum() - * TODO: please verify this and remove this TODO - * -- Dec 21st 2009, Simon Wunderlich */ - -/* skb->ip_summed = CHECKSUM_UNNECESSARY;*/ - - bat_priv->stats.rx_packets++; - bat_priv->stats.rx_bytes += skb->len + sizeof(struct ethhdr); - - soft_iface->last_rx = jiffies; - - netif_rx(skb); - return; - -dropped: - kfree_skb(skb); -out: - return; -} - -#ifdef HAVE_NET_DEVICE_OPS -static const struct net_device_ops bat_netdev_ops = { - .ndo_open = interface_open, - .ndo_stop = interface_release, - .ndo_get_stats = interface_stats, - .ndo_set_mac_address = interface_set_mac_addr, - .ndo_change_mtu = interface_change_mtu, - .ndo_start_xmit = interface_tx, - .ndo_validate_addr = eth_validate_addr -}; -#endif - -static void interface_setup(struct net_device *dev) -{ - struct bat_priv *priv = netdev_priv(dev); - char dev_addr[ETH_ALEN]; - - ether_setup(dev); - -#ifdef HAVE_NET_DEVICE_OPS - dev->netdev_ops = &bat_netdev_ops; -#else - dev->open = interface_open; - dev->stop = interface_release; - dev->get_stats = interface_stats; - dev->set_mac_address = interface_set_mac_addr; - dev->change_mtu = interface_change_mtu; - dev->hard_start_xmit = interface_tx; -#endif - dev->destructor = free_netdev; - - /** - * can't call min_mtu, because the needed variables - * have not been initialized yet - */ - dev->mtu = ETH_DATA_LEN; - dev->hard_header_len = BAT_HEADER_LEN; /* reserve more space in the - * skbuff for our header */ - - /* generate random address */ - random_ether_addr(dev_addr); - memcpy(dev->dev_addr, dev_addr, ETH_ALEN); - - SET_ETHTOOL_OPS(dev, &bat_ethtool_ops); - - memset(priv, 0, sizeof(struct bat_priv)); -} - -struct net_device *softif_create(char *name) -{ - struct net_device *soft_iface; - struct bat_priv *bat_priv; - int ret; - - soft_iface = alloc_netdev(sizeof(struct bat_priv) , name, - interface_setup); - - if (!soft_iface) { - pr_err("Unable to allocate the batman interface: %s\n", name); - goto out; - } - - ret = register_netdev(soft_iface); - if (ret < 0) { - pr_err("Unable to register the batman interface '%s': %i\n", - name, ret); - goto free_soft_iface; - } - - bat_priv = netdev_priv(soft_iface); - - atomic_set(&bat_priv->aggregated_ogms, 1); - atomic_set(&bat_priv->bonding, 0); - atomic_set(&bat_priv->vis_mode, VIS_TYPE_CLIENT_UPDATE); - atomic_set(&bat_priv->gw_mode, GW_MODE_OFF); - atomic_set(&bat_priv->gw_sel_class, 20); - atomic_set(&bat_priv->gw_bandwidth, 41); - atomic_set(&bat_priv->orig_interval, 1000); - atomic_set(&bat_priv->hop_penalty, 10); - atomic_set(&bat_priv->log_level, 0); - atomic_set(&bat_priv->fragmentation, 1); - atomic_set(&bat_priv->bcast_queue_left, BCAST_QUEUE_LEN); - atomic_set(&bat_priv->batman_queue_left, BATMAN_QUEUE_LEN); - - atomic_set(&bat_priv->mesh_state, MESH_INACTIVE); - atomic_set(&bat_priv->bcast_seqno, 1); - atomic_set(&bat_priv->hna_local_changed, 0); - - bat_priv->primary_if = NULL; - bat_priv->num_ifaces = 0; - bat_priv->softif_neigh = NULL; - - ret = sysfs_add_meshif(soft_iface); - if (ret < 0) - goto unreg_soft_iface; - - ret = debugfs_add_meshif(soft_iface); - if (ret < 0) - goto unreg_sysfs; - - ret = mesh_init(soft_iface); - if (ret < 0) - goto unreg_debugfs; - - return soft_iface; - -unreg_debugfs: - debugfs_del_meshif(soft_iface); -unreg_sysfs: - sysfs_del_meshif(soft_iface); -unreg_soft_iface: - unregister_netdev(soft_iface); - return NULL; - -free_soft_iface: - free_netdev(soft_iface); -out: - return NULL; -} - -void softif_destroy(struct net_device *soft_iface) -{ - debugfs_del_meshif(soft_iface); - sysfs_del_meshif(soft_iface); - mesh_free(soft_iface); - unregister_netdevice(soft_iface); -} - -/* ethtool */ -static int bat_get_settings(struct net_device *dev, struct ethtool_cmd *cmd) -{ - cmd->supported = 0; - cmd->advertising = 0; - cmd->speed = SPEED_10; - cmd->duplex = DUPLEX_FULL; - cmd->port = PORT_TP; - cmd->phy_address = 0; - cmd->transceiver = XCVR_INTERNAL; - cmd->autoneg = AUTONEG_DISABLE; - cmd->maxtxpkt = 0; - cmd->maxrxpkt = 0; - - return 0; -} - -static void bat_get_drvinfo(struct net_device *dev, - struct ethtool_drvinfo *info) -{ - strcpy(info->driver, "B.A.T.M.A.N. advanced"); - strcpy(info->version, SOURCE_VERSION); - strcpy(info->fw_version, "N/A"); - strcpy(info->bus_info, "batman"); -} - -static u32 bat_get_msglevel(struct net_device *dev) -{ - return -EOPNOTSUPP; -} - -static void bat_set_msglevel(struct net_device *dev, u32 value) -{ -} - -static u32 bat_get_link(struct net_device *dev) -{ - return 1; -} - -static u32 bat_get_rx_csum(struct net_device *dev) -{ - return 0; -} - -static int bat_set_rx_csum(struct net_device *dev, u32 data) -{ - return -EOPNOTSUPP; -} diff --git a/drivers/staging/batman-adv/soft-interface.h b/drivers/staging/batman-adv/soft-interface.h deleted file mode 100644 index 02b77334d10d..000000000000 --- a/drivers/staging/batman-adv/soft-interface.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: - * - * Marek Lindner - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License 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. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA - * - */ - -#ifndef _NET_BATMAN_ADV_SOFT_INTERFACE_H_ -#define _NET_BATMAN_ADV_SOFT_INTERFACE_H_ - -int my_skb_head_push(struct sk_buff *skb, unsigned int len); -int softif_neigh_seq_print_text(struct seq_file *seq, void *offset); -void softif_neigh_purge(struct bat_priv *bat_priv); -int interface_tx(struct sk_buff *skb, struct net_device *soft_iface); -void interface_rx(struct net_device *soft_iface, - struct sk_buff *skb, struct batman_if *recv_if, - int hdr_size); -struct net_device *softif_create(char *name); -void softif_destroy(struct net_device *soft_iface); - -#endif /* _NET_BATMAN_ADV_SOFT_INTERFACE_H_ */ diff --git a/drivers/staging/batman-adv/sysfs-class-net-batman-adv b/drivers/staging/batman-adv/sysfs-class-net-batman-adv deleted file mode 100644 index 38dd762def4b..000000000000 --- a/drivers/staging/batman-adv/sysfs-class-net-batman-adv +++ /dev/null @@ -1,14 +0,0 @@ - -What: /sys/class/net//batman-adv/mesh_iface -Date: May 2010 -Contact: Marek Lindner -Description: - The /sys/class/net//batman-adv/mesh_iface file - displays the batman mesh interface this - currently is associated with. - -What: /sys/class/net//batman-adv/iface_status -Date: May 2010 -Contact: Marek Lindner -Description: - Indicates the status of as it is seen by batman. diff --git a/drivers/staging/batman-adv/sysfs-class-net-mesh b/drivers/staging/batman-adv/sysfs-class-net-mesh deleted file mode 100644 index 748fe1701d25..000000000000 --- a/drivers/staging/batman-adv/sysfs-class-net-mesh +++ /dev/null @@ -1,69 +0,0 @@ - -What: /sys/class/net//mesh/aggregated_ogms -Date: May 2010 -Contact: Marek Lindner -Description: - Indicates whether the batman protocol messages of the - mesh shall be aggregated or not. - -What: /sys/class/net//mesh/bonding -Date: June 2010 -Contact: Simon Wunderlich -Description: - Indicates whether the data traffic going through the - mesh will be sent using multiple interfaces at the - same time (if available). - -What: /sys/class/net//mesh/fragmentation -Date: October 2010 -Contact: Andreas Langer -Description: - Indicates whether the data traffic going through the - mesh will be fragmented or silently discarded if the - packet size exceeds the outgoing interface MTU. - -What: /sys/class/net//mesh/gw_bandwidth -Date: October 2010 -Contact: Marek Lindner -Description: - Defines the bandwidth which is propagated by this - node if gw_mode was set to 'server'. - -What: /sys/class/net//mesh/gw_mode -Date: October 2010 -Contact: Marek Lindner -Description: - Defines the state of the gateway features. Can be - either 'off', 'client' or 'server'. - -What: /sys/class/net//mesh/gw_sel_class -Date: October 2010 -Contact: Marek Lindner -Description: - Defines the selection criteria this node will use - to choose a gateway if gw_mode was set to 'client'. - -What: /sys/class/net//mesh/orig_interval -Date: May 2010 -Contact: Marek Lindner -Description: - Defines the interval in milliseconds in which batman - sends its protocol messages. - -What: /sys/class/net//mesh/hop_penalty -Date: Oct 2010 -Contact: Linus Lüssing -Description: - Defines the penalty which will be applied to an - originator message's tq-field on every hop. - -What: /sys/class/net//mesh/vis_mode -Date: May 2010 -Contact: Marek Lindner -Description: - Each batman node only maintains information about its - own local neighborhood, therefore generating graphs - showing the topology of the entire mesh is not easily - feasible without having a central instance to collect - the local topologies from all nodes. This file allows - to activate the collecting (server) mode. diff --git a/drivers/staging/batman-adv/translation-table.c b/drivers/staging/batman-adv/translation-table.c deleted file mode 100644 index 4b0a1079347b..000000000000 --- a/drivers/staging/batman-adv/translation-table.c +++ /dev/null @@ -1,528 +0,0 @@ -/* - * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: - * - * Marek Lindner, Simon Wunderlich - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License 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. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA - * - */ - -#include "main.h" -#include "translation-table.h" -#include "soft-interface.h" -#include "types.h" -#include "hash.h" -#include "originator.h" - -static void hna_local_purge(struct work_struct *work); -static void _hna_global_del_orig(struct bat_priv *bat_priv, - struct hna_global_entry *hna_global_entry, - char *message); - -static void hna_local_start_timer(struct bat_priv *bat_priv) -{ - INIT_DELAYED_WORK(&bat_priv->hna_work, hna_local_purge); - queue_delayed_work(bat_event_workqueue, &bat_priv->hna_work, 10 * HZ); -} - -int hna_local_init(struct bat_priv *bat_priv) -{ - if (bat_priv->hna_local_hash) - return 1; - - bat_priv->hna_local_hash = hash_new(128); - - if (!bat_priv->hna_local_hash) - return 0; - - atomic_set(&bat_priv->hna_local_changed, 0); - hna_local_start_timer(bat_priv); - - return 1; -} - -void hna_local_add(struct net_device *soft_iface, uint8_t *addr) -{ - struct bat_priv *bat_priv = netdev_priv(soft_iface); - struct hna_local_entry *hna_local_entry; - struct hna_global_entry *hna_global_entry; - struct hashtable_t *swaphash; - int required_bytes; - - spin_lock_bh(&bat_priv->hna_lhash_lock); - hna_local_entry = - ((struct hna_local_entry *)hash_find(bat_priv->hna_local_hash, - compare_orig, choose_orig, - addr)); - spin_unlock_bh(&bat_priv->hna_lhash_lock); - - if (hna_local_entry) { - hna_local_entry->last_seen = jiffies; - return; - } - - /* only announce as many hosts as possible in the batman-packet and - space in batman_packet->num_hna That also should give a limit to - MAC-flooding. */ - required_bytes = (bat_priv->num_local_hna + 1) * ETH_ALEN; - required_bytes += BAT_PACKET_LEN; - - if ((required_bytes > ETH_DATA_LEN) || - (atomic_read(&bat_priv->aggregated_ogms) && - required_bytes > MAX_AGGREGATION_BYTES) || - (bat_priv->num_local_hna + 1 > 255)) { - bat_dbg(DBG_ROUTES, bat_priv, - "Can't add new local hna entry (%pM): " - "number of local hna entries exceeds packet size\n", - addr); - return; - } - - bat_dbg(DBG_ROUTES, bat_priv, - "Creating new local hna entry: %pM\n", addr); - - hna_local_entry = kmalloc(sizeof(struct hna_local_entry), GFP_ATOMIC); - if (!hna_local_entry) - return; - - memcpy(hna_local_entry->addr, addr, ETH_ALEN); - hna_local_entry->last_seen = jiffies; - - /* the batman interface mac address should never be purged */ - if (compare_orig(addr, soft_iface->dev_addr)) - hna_local_entry->never_purge = 1; - else - hna_local_entry->never_purge = 0; - - spin_lock_bh(&bat_priv->hna_lhash_lock); - - hash_add(bat_priv->hna_local_hash, compare_orig, choose_orig, - hna_local_entry); - bat_priv->num_local_hna++; - atomic_set(&bat_priv->hna_local_changed, 1); - - if (bat_priv->hna_local_hash->elements * 4 > - bat_priv->hna_local_hash->size) { - swaphash = hash_resize(bat_priv->hna_local_hash, choose_orig, - bat_priv->hna_local_hash->size * 2); - - if (!swaphash) - pr_err("Couldn't resize local hna hash table\n"); - else - bat_priv->hna_local_hash = swaphash; - } - - spin_unlock_bh(&bat_priv->hna_lhash_lock); - - /* remove address from global hash if present */ - spin_lock_bh(&bat_priv->hna_ghash_lock); - - hna_global_entry = ((struct hna_global_entry *) - hash_find(bat_priv->hna_global_hash, - compare_orig, choose_orig, addr)); - - if (hna_global_entry) - _hna_global_del_orig(bat_priv, hna_global_entry, - "local hna received"); - - spin_unlock_bh(&bat_priv->hna_ghash_lock); -} - -int hna_local_fill_buffer(struct bat_priv *bat_priv, - unsigned char *buff, int buff_len) -{ - struct hna_local_entry *hna_local_entry; - struct element_t *bucket; - HASHIT(hashit); - int i = 0; - - spin_lock_bh(&bat_priv->hna_lhash_lock); - - while (hash_iterate(bat_priv->hna_local_hash, &hashit)) { - - if (buff_len < (i + 1) * ETH_ALEN) - break; - - bucket = hlist_entry(hashit.walk, struct element_t, hlist); - hna_local_entry = bucket->data; - memcpy(buff + (i * ETH_ALEN), hna_local_entry->addr, ETH_ALEN); - - i++; - } - - /* if we did not get all new local hnas see you next time ;-) */ - if (i == bat_priv->num_local_hna) - atomic_set(&bat_priv->hna_local_changed, 0); - - spin_unlock_bh(&bat_priv->hna_lhash_lock); - return i; -} - -int hna_local_seq_print_text(struct seq_file *seq, void *offset) -{ - struct net_device *net_dev = (struct net_device *)seq->private; - struct bat_priv *bat_priv = netdev_priv(net_dev); - struct hna_local_entry *hna_local_entry; - HASHIT(hashit); - HASHIT(hashit_count); - struct element_t *bucket; - size_t buf_size, pos; - char *buff; - - if (!bat_priv->primary_if) { - return seq_printf(seq, "BATMAN mesh %s disabled - " - "please specify interfaces to enable it\n", - net_dev->name); - } - - seq_printf(seq, "Locally retrieved addresses (from %s) " - "announced via HNA:\n", - net_dev->name); - - spin_lock_bh(&bat_priv->hna_lhash_lock); - - buf_size = 1; - /* Estimate length for: " * xx:xx:xx:xx:xx:xx\n" */ - while (hash_iterate(bat_priv->hna_local_hash, &hashit_count)) - buf_size += 21; - - buff = kmalloc(buf_size, GFP_ATOMIC); - if (!buff) { - spin_unlock_bh(&bat_priv->hna_lhash_lock); - return -ENOMEM; - } - buff[0] = '\0'; - pos = 0; - - while (hash_iterate(bat_priv->hna_local_hash, &hashit)) { - bucket = hlist_entry(hashit.walk, struct element_t, hlist); - hna_local_entry = bucket->data; - - pos += snprintf(buff + pos, 22, " * %pM\n", - hna_local_entry->addr); - } - - spin_unlock_bh(&bat_priv->hna_lhash_lock); - - seq_printf(seq, "%s", buff); - kfree(buff); - return 0; -} - -static void _hna_local_del(void *data, void *arg) -{ - struct bat_priv *bat_priv = (struct bat_priv *)arg; - - kfree(data); - bat_priv->num_local_hna--; - atomic_set(&bat_priv->hna_local_changed, 1); -} - -static void hna_local_del(struct bat_priv *bat_priv, - struct hna_local_entry *hna_local_entry, - char *message) -{ - bat_dbg(DBG_ROUTES, bat_priv, "Deleting local hna entry (%pM): %s\n", - hna_local_entry->addr, message); - - hash_remove(bat_priv->hna_local_hash, compare_orig, choose_orig, - hna_local_entry->addr); - _hna_local_del(hna_local_entry, bat_priv); -} - -void hna_local_remove(struct bat_priv *bat_priv, - uint8_t *addr, char *message) -{ - struct hna_local_entry *hna_local_entry; - - spin_lock_bh(&bat_priv->hna_lhash_lock); - - hna_local_entry = (struct hna_local_entry *) - hash_find(bat_priv->hna_local_hash, compare_orig, choose_orig, - addr); - if (hna_local_entry) - hna_local_del(bat_priv, hna_local_entry, message); - - spin_unlock_bh(&bat_priv->hna_lhash_lock); -} - -static void hna_local_purge(struct work_struct *work) -{ - struct delayed_work *delayed_work = - container_of(work, struct delayed_work, work); - struct bat_priv *bat_priv = - container_of(delayed_work, struct bat_priv, hna_work); - struct hna_local_entry *hna_local_entry; - HASHIT(hashit); - struct element_t *bucket; - unsigned long timeout; - - spin_lock_bh(&bat_priv->hna_lhash_lock); - - while (hash_iterate(bat_priv->hna_local_hash, &hashit)) { - bucket = hlist_entry(hashit.walk, struct element_t, hlist); - hna_local_entry = bucket->data; - - timeout = hna_local_entry->last_seen + LOCAL_HNA_TIMEOUT * HZ; - - if ((!hna_local_entry->never_purge) && - time_after(jiffies, timeout)) - hna_local_del(bat_priv, hna_local_entry, - "address timed out"); - } - - spin_unlock_bh(&bat_priv->hna_lhash_lock); - hna_local_start_timer(bat_priv); -} - -void hna_local_free(struct bat_priv *bat_priv) -{ - if (!bat_priv->hna_local_hash) - return; - - cancel_delayed_work_sync(&bat_priv->hna_work); - hash_delete(bat_priv->hna_local_hash, _hna_local_del, bat_priv); - bat_priv->hna_local_hash = NULL; -} - -int hna_global_init(struct bat_priv *bat_priv) -{ - if (bat_priv->hna_global_hash) - return 1; - - bat_priv->hna_global_hash = hash_new(128); - - if (!bat_priv->hna_global_hash) - return 0; - - return 1; -} - -void hna_global_add_orig(struct bat_priv *bat_priv, - struct orig_node *orig_node, - unsigned char *hna_buff, int hna_buff_len) -{ - struct hna_global_entry *hna_global_entry; - struct hna_local_entry *hna_local_entry; - struct hashtable_t *swaphash; - int hna_buff_count = 0; - unsigned char *hna_ptr; - - while ((hna_buff_count + 1) * ETH_ALEN <= hna_buff_len) { - spin_lock_bh(&bat_priv->hna_ghash_lock); - - hna_ptr = hna_buff + (hna_buff_count * ETH_ALEN); - hna_global_entry = (struct hna_global_entry *) - hash_find(bat_priv->hna_global_hash, compare_orig, - choose_orig, hna_ptr); - - if (!hna_global_entry) { - spin_unlock_bh(&bat_priv->hna_ghash_lock); - - hna_global_entry = - kmalloc(sizeof(struct hna_global_entry), - GFP_ATOMIC); - - if (!hna_global_entry) - break; - - memcpy(hna_global_entry->addr, hna_ptr, ETH_ALEN); - - bat_dbg(DBG_ROUTES, bat_priv, - "Creating new global hna entry: " - "%pM (via %pM)\n", - hna_global_entry->addr, orig_node->orig); - - spin_lock_bh(&bat_priv->hna_ghash_lock); - hash_add(bat_priv->hna_global_hash, compare_orig, - choose_orig, hna_global_entry); - - } - - hna_global_entry->orig_node = orig_node; - spin_unlock_bh(&bat_priv->hna_ghash_lock); - - /* remove address from local hash if present */ - spin_lock_bh(&bat_priv->hna_lhash_lock); - - hna_ptr = hna_buff + (hna_buff_count * ETH_ALEN); - hna_local_entry = (struct hna_local_entry *) - hash_find(bat_priv->hna_local_hash, compare_orig, - choose_orig, hna_ptr); - - if (hna_local_entry) - hna_local_del(bat_priv, hna_local_entry, - "global hna received"); - - spin_unlock_bh(&bat_priv->hna_lhash_lock); - - hna_buff_count++; - } - - /* initialize, and overwrite if malloc succeeds */ - orig_node->hna_buff = NULL; - orig_node->hna_buff_len = 0; - - if (hna_buff_len > 0) { - orig_node->hna_buff = kmalloc(hna_buff_len, GFP_ATOMIC); - if (orig_node->hna_buff) { - memcpy(orig_node->hna_buff, hna_buff, hna_buff_len); - orig_node->hna_buff_len = hna_buff_len; - } - } - - spin_lock_bh(&bat_priv->hna_ghash_lock); - - if (bat_priv->hna_global_hash->elements * 4 > - bat_priv->hna_global_hash->size) { - swaphash = hash_resize(bat_priv->hna_global_hash, choose_orig, - bat_priv->hna_global_hash->size * 2); - - if (!swaphash) - pr_err("Couldn't resize global hna hash table\n"); - else - bat_priv->hna_global_hash = swaphash; - } - - spin_unlock_bh(&bat_priv->hna_ghash_lock); -} - -int hna_global_seq_print_text(struct seq_file *seq, void *offset) -{ - struct net_device *net_dev = (struct net_device *)seq->private; - struct bat_priv *bat_priv = netdev_priv(net_dev); - struct hna_global_entry *hna_global_entry; - HASHIT(hashit); - HASHIT(hashit_count); - struct element_t *bucket; - size_t buf_size, pos; - char *buff; - - if (!bat_priv->primary_if) { - return seq_printf(seq, "BATMAN mesh %s disabled - " - "please specify interfaces to enable it\n", - net_dev->name); - } - - seq_printf(seq, "Globally announced HNAs received via the mesh %s\n", - net_dev->name); - - spin_lock_bh(&bat_priv->hna_ghash_lock); - - buf_size = 1; - /* Estimate length for: " * xx:xx:xx:xx:xx:xx via xx:xx:xx:xx:xx:xx\n"*/ - while (hash_iterate(bat_priv->hna_global_hash, &hashit_count)) - buf_size += 43; - - buff = kmalloc(buf_size, GFP_ATOMIC); - if (!buff) { - spin_unlock_bh(&bat_priv->hna_ghash_lock); - return -ENOMEM; - } - buff[0] = '\0'; - pos = 0; - - while (hash_iterate(bat_priv->hna_global_hash, &hashit)) { - bucket = hlist_entry(hashit.walk, struct element_t, hlist); - hna_global_entry = bucket->data; - - pos += snprintf(buff + pos, 44, - " * %pM via %pM\n", hna_global_entry->addr, - hna_global_entry->orig_node->orig); - } - - spin_unlock_bh(&bat_priv->hna_ghash_lock); - - seq_printf(seq, "%s", buff); - kfree(buff); - return 0; -} - -static void _hna_global_del_orig(struct bat_priv *bat_priv, - struct hna_global_entry *hna_global_entry, - char *message) -{ - bat_dbg(DBG_ROUTES, bat_priv, - "Deleting global hna entry %pM (via %pM): %s\n", - hna_global_entry->addr, hna_global_entry->orig_node->orig, - message); - - hash_remove(bat_priv->hna_global_hash, compare_orig, choose_orig, - hna_global_entry->addr); - kfree(hna_global_entry); -} - -void hna_global_del_orig(struct bat_priv *bat_priv, - struct orig_node *orig_node, char *message) -{ - struct hna_global_entry *hna_global_entry; - int hna_buff_count = 0; - unsigned char *hna_ptr; - - if (orig_node->hna_buff_len == 0) - return; - - spin_lock_bh(&bat_priv->hna_ghash_lock); - - while ((hna_buff_count + 1) * ETH_ALEN <= orig_node->hna_buff_len) { - hna_ptr = orig_node->hna_buff + (hna_buff_count * ETH_ALEN); - hna_global_entry = (struct hna_global_entry *) - hash_find(bat_priv->hna_global_hash, compare_orig, - choose_orig, hna_ptr); - - if ((hna_global_entry) && - (hna_global_entry->orig_node == orig_node)) - _hna_global_del_orig(bat_priv, hna_global_entry, - message); - - hna_buff_count++; - } - - spin_unlock_bh(&bat_priv->hna_ghash_lock); - - orig_node->hna_buff_len = 0; - kfree(orig_node->hna_buff); - orig_node->hna_buff = NULL; -} - -static void hna_global_del(void *data, void *arg) -{ - kfree(data); -} - -void hna_global_free(struct bat_priv *bat_priv) -{ - if (!bat_priv->hna_global_hash) - return; - - hash_delete(bat_priv->hna_global_hash, hna_global_del, NULL); - bat_priv->hna_global_hash = NULL; -} - -struct orig_node *transtable_search(struct bat_priv *bat_priv, uint8_t *addr) -{ - struct hna_global_entry *hna_global_entry; - - spin_lock_bh(&bat_priv->hna_ghash_lock); - hna_global_entry = (struct hna_global_entry *) - hash_find(bat_priv->hna_global_hash, - compare_orig, choose_orig, addr); - spin_unlock_bh(&bat_priv->hna_ghash_lock); - - if (!hna_global_entry) - return NULL; - - return hna_global_entry->orig_node; -} diff --git a/drivers/staging/batman-adv/translation-table.h b/drivers/staging/batman-adv/translation-table.h deleted file mode 100644 index 10c4c5c319b6..000000000000 --- a/drivers/staging/batman-adv/translation-table.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: - * - * Marek Lindner, Simon Wunderlich - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License 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. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA - * - */ - -#ifndef _NET_BATMAN_ADV_TRANSLATION_TABLE_H_ -#define _NET_BATMAN_ADV_TRANSLATION_TABLE_H_ - -#include "types.h" - -int hna_local_init(struct bat_priv *bat_priv); -void hna_local_add(struct net_device *soft_iface, uint8_t *addr); -void hna_local_remove(struct bat_priv *bat_priv, - uint8_t *addr, char *message); -int hna_local_fill_buffer(struct bat_priv *bat_priv, - unsigned char *buff, int buff_len); -int hna_local_seq_print_text(struct seq_file *seq, void *offset); -void hna_local_free(struct bat_priv *bat_priv); -int hna_global_init(struct bat_priv *bat_priv); -void hna_global_add_orig(struct bat_priv *bat_priv, - struct orig_node *orig_node, - unsigned char *hna_buff, int hna_buff_len); -int hna_global_seq_print_text(struct seq_file *seq, void *offset); -void hna_global_del_orig(struct bat_priv *bat_priv, - struct orig_node *orig_node, char *message); -void hna_global_free(struct bat_priv *bat_priv); -struct orig_node *transtable_search(struct bat_priv *bat_priv, uint8_t *addr); - -#endif /* _NET_BATMAN_ADV_TRANSLATION_TABLE_H_ */ diff --git a/drivers/staging/batman-adv/types.h b/drivers/staging/batman-adv/types.h deleted file mode 100644 index 1d0084995c7c..000000000000 --- a/drivers/staging/batman-adv/types.h +++ /dev/null @@ -1,271 +0,0 @@ -/* - * Copyright (C) 2007-2010 B.A.T.M.A.N. contributors: - * - * Marek Lindner, Simon Wunderlich - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License 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. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA - * - */ - - - -#ifndef _NET_BATMAN_ADV_TYPES_H_ -#define _NET_BATMAN_ADV_TYPES_H_ - -#include "packet.h" -#include "bitarray.h" - -#define BAT_HEADER_LEN (sizeof(struct ethhdr) + \ - ((sizeof(struct unicast_packet) > sizeof(struct bcast_packet) ? \ - sizeof(struct unicast_packet) : \ - sizeof(struct bcast_packet)))) - - -struct batman_if { - struct list_head list; - int16_t if_num; - char if_status; - struct net_device *net_dev; - atomic_t seqno; - atomic_t frag_seqno; - unsigned char *packet_buff; - int packet_len; - struct kobject *hardif_obj; - struct kref refcount; - struct packet_type batman_adv_ptype; - struct net_device *soft_iface; - struct rcu_head rcu; -}; - -/** - * orig_node - structure for orig_list maintaining nodes of mesh - * @primary_addr: hosts primary interface address - * @last_valid: when last packet from this node was received - * @bcast_seqno_reset: time when the broadcast seqno window was reset - * @batman_seqno_reset: time when the batman seqno window was reset - * @gw_flags: flags related to gateway class - * @flags: for now only VIS_SERVER flag - * @last_real_seqno: last and best known squence number - * @last_ttl: ttl of last received packet - * @last_bcast_seqno: last broadcast sequence number received by this host - * - * @candidates: how many candidates are available - * @selected: next bonding candidate - */ -struct orig_node { - uint8_t orig[ETH_ALEN]; - uint8_t primary_addr[ETH_ALEN]; - struct neigh_node *router; - TYPE_OF_WORD *bcast_own; - uint8_t *bcast_own_sum; - uint8_t tq_own; - int tq_asym_penalty; - unsigned long last_valid; - unsigned long bcast_seqno_reset; - unsigned long batman_seqno_reset; - uint8_t gw_flags; - uint8_t flags; - unsigned char *hna_buff; - int16_t hna_buff_len; - uint32_t last_real_seqno; - uint8_t last_ttl; - TYPE_OF_WORD bcast_bits[NUM_WORDS]; - uint32_t last_bcast_seqno; - struct list_head neigh_list; - struct list_head frag_list; - unsigned long last_frag_packet; - struct { - uint8_t candidates; - struct neigh_node *selected; - } bond; -}; - -struct gw_node { - struct hlist_node list; - struct orig_node *orig_node; - unsigned long deleted; - struct kref refcount; - struct rcu_head rcu; -}; - -/** - * neigh_node - * @last_valid: when last packet via this neighbor was received - */ -struct neigh_node { - struct list_head list; - uint8_t addr[ETH_ALEN]; - uint8_t real_packet_count; - uint8_t tq_recv[TQ_GLOBAL_WINDOW_SIZE]; - uint8_t tq_index; - uint8_t tq_avg; - uint8_t last_ttl; - struct neigh_node *next_bond_candidate; - unsigned long last_valid; - TYPE_OF_WORD real_bits[NUM_WORDS]; - struct orig_node *orig_node; - struct batman_if *if_incoming; -}; - - -struct bat_priv { - atomic_t mesh_state; - struct net_device_stats stats; - atomic_t aggregated_ogms; /* boolean */ - atomic_t bonding; /* boolean */ - atomic_t fragmentation; /* boolean */ - atomic_t vis_mode; /* VIS_TYPE_* */ - atomic_t gw_mode; /* GW_MODE_* */ - atomic_t gw_sel_class; /* uint */ - atomic_t gw_bandwidth; /* gw bandwidth */ - atomic_t orig_interval; /* uint */ - atomic_t hop_penalty; /* uint */ - atomic_t log_level; /* uint */ - atomic_t bcast_seqno; - atomic_t bcast_queue_left; - atomic_t batman_queue_left; - char num_ifaces; - struct hlist_head softif_neigh_list; - struct softif_neigh *softif_neigh; - struct debug_log *debug_log; - struct batman_if *primary_if; - struct kobject *mesh_obj; - struct dentry *debug_dir; - struct hlist_head forw_bat_list; - struct hlist_head forw_bcast_list; - struct hlist_head gw_list; - struct list_head vis_send_list; - struct hashtable_t *orig_hash; - struct hashtable_t *hna_local_hash; - struct hashtable_t *hna_global_hash; - struct hashtable_t *vis_hash; - spinlock_t orig_hash_lock; /* protects orig_hash */ - spinlock_t forw_bat_list_lock; /* protects forw_bat_list */ - spinlock_t forw_bcast_list_lock; /* protects */ - spinlock_t hna_lhash_lock; /* protects hna_local_hash */ - spinlock_t hna_ghash_lock; /* protects hna_global_hash */ - spinlock_t gw_list_lock; /* protects gw_list */ - spinlock_t vis_hash_lock; /* protects vis_hash */ - spinlock_t vis_list_lock; /* protects vis_info::recv_list */ - spinlock_t softif_neigh_lock; /* protects soft-interface neigh list */ - int16_t num_local_hna; - atomic_t hna_local_changed; - struct delayed_work hna_work; - struct delayed_work orig_work; - struct delayed_work vis_work; - struct gw_node *curr_gw; - struct vis_info *my_vis_info; -}; - -struct socket_client { - struct list_head queue_list; - unsigned int queue_len; - unsigned char index; - spinlock_t lock; /* protects queue_list, queue_len, index */ - wait_queue_head_t queue_wait; - struct bat_priv *bat_priv; -}; - -struct socket_packet { - struct list_head list; - size_t icmp_len; - struct icmp_packet_rr icmp_packet; -}; - -struct hna_local_entry { - uint8_t addr[ETH_ALEN]; - unsigned long last_seen; - char never_purge; -}; - -struct hna_global_entry { - uint8_t addr[ETH_ALEN]; - struct orig_node *orig_node; -}; - -/** - * forw_packet - structure for forw_list maintaining packets to be - * send/forwarded - */ -struct forw_packet { - struct hlist_node list; - unsigned long send_time; - uint8_t own; - struct sk_buff *skb; - uint16_t packet_len; - uint32_t direct_link_flags; - uint8_t num_packets; - struct delayed_work delayed_work; - struct batman_if *if_incoming; -}; - -/* While scanning for vis-entries of a particular vis-originator - * this list collects its interfaces to create a subgraph/cluster - * out of them later - */ -struct if_list_entry { - uint8_t addr[ETH_ALEN]; - bool primary; - struct hlist_node list; -}; - -struct debug_log { - char log_buff[LOG_BUF_LEN]; - unsigned long log_start; - unsigned long log_end; - spinlock_t lock; /* protects log_buff, log_start and log_end */ - wait_queue_head_t queue_wait; -}; - -struct frag_packet_list_entry { - struct list_head list; - uint16_t seqno; - struct sk_buff *skb; -}; - -struct vis_info { - unsigned long first_seen; - struct list_head recv_list; - /* list of server-neighbors we received a vis-packet - * from. we should not reply to them. */ - struct list_head send_list; - struct kref refcount; - struct bat_priv *bat_priv; - /* this packet might be part of the vis send queue. */ - struct sk_buff *skb_packet; - /* vis_info may follow here*/ -} __attribute__((packed)); - -struct vis_info_entry { - uint8_t src[ETH_ALEN]; - uint8_t dest[ETH_ALEN]; - uint8_t quality; /* quality = 0 means HNA */ -} __attribute__((packed)); - -struct recvlist_node { - struct list_head list; - uint8_t mac[ETH_ALEN]; -}; - -struct softif_neigh { - struct hlist_node list; - uint8_t addr[ETH_ALEN]; - unsigned long last_seen; - short vid; - struct kref refcount; - struct rcu_head rcu; -}; - -#endif /* _NET_BATMAN_ADV_TYPES_H_ */ diff --git a/drivers/staging/batman-adv/unicast.c b/drivers/staging/batman-adv/unicast.c deleted file mode 100644 index dc2e28bed844..000000000000 --- a/drivers/staging/batman-adv/unicast.c +++ /dev/null @@ -1,343 +0,0 @@ -/* - * Copyright (C) 2010 B.A.T.M.A.N. contributors: - * - * Andreas Langer - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License 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. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA - * - */ - -#include "main.h" -#include "unicast.h" -#include "send.h" -#include "soft-interface.h" -#include "gateway_client.h" -#include "originator.h" -#include "hash.h" -#include "translation-table.h" -#include "routing.h" -#include "hard-interface.h" - - -static struct sk_buff *frag_merge_packet(struct list_head *head, - struct frag_packet_list_entry *tfp, - struct sk_buff *skb) -{ - struct unicast_frag_packet *up = - (struct unicast_frag_packet *)skb->data; - struct sk_buff *tmp_skb; - struct unicast_packet *unicast_packet; - int hdr_len = sizeof(struct unicast_packet), - uni_diff = sizeof(struct unicast_frag_packet) - hdr_len; - - /* set skb to the first part and tmp_skb to the second part */ - if (up->flags & UNI_FRAG_HEAD) { - tmp_skb = tfp->skb; - } else { - tmp_skb = skb; - skb = tfp->skb; - } - - skb_pull(tmp_skb, sizeof(struct unicast_frag_packet)); - if (pskb_expand_head(skb, 0, tmp_skb->len, GFP_ATOMIC) < 0) { - /* free buffered skb, skb will be freed later */ - kfree_skb(tfp->skb); - return NULL; - } - - /* move free entry to end */ - tfp->skb = NULL; - tfp->seqno = 0; - list_move_tail(&tfp->list, head); - - memcpy(skb_put(skb, tmp_skb->len), tmp_skb->data, tmp_skb->len); - kfree_skb(tmp_skb); - - memmove(skb->data + uni_diff, skb->data, hdr_len); - unicast_packet = (struct unicast_packet *) skb_pull(skb, uni_diff); - unicast_packet->packet_type = BAT_UNICAST; - - return skb; -} - -static void frag_create_entry(struct list_head *head, struct sk_buff *skb) -{ - struct frag_packet_list_entry *tfp; - struct unicast_frag_packet *up = - (struct unicast_frag_packet *)skb->data; - - /* free and oldest packets stand at the end */ - tfp = list_entry((head)->prev, typeof(*tfp), list); - kfree_skb(tfp->skb); - - tfp->seqno = ntohs(up->seqno); - tfp->skb = skb; - list_move(&tfp->list, head); - return; -} - -static int frag_create_buffer(struct list_head *head) -{ - int i; - struct frag_packet_list_entry *tfp; - - for (i = 0; i < FRAG_BUFFER_SIZE; i++) { - tfp = kmalloc(sizeof(struct frag_packet_list_entry), - GFP_ATOMIC); - if (!tfp) { - frag_list_free(head); - return -ENOMEM; - } - tfp->skb = NULL; - tfp->seqno = 0; - INIT_LIST_HEAD(&tfp->list); - list_add(&tfp->list, head); - } - - return 0; -} - -static struct frag_packet_list_entry *frag_search_packet(struct list_head *head, - struct unicast_frag_packet *up) -{ - struct frag_packet_list_entry *tfp; - struct unicast_frag_packet *tmp_up = NULL; - uint16_t search_seqno; - - if (up->flags & UNI_FRAG_HEAD) - search_seqno = ntohs(up->seqno)+1; - else - search_seqno = ntohs(up->seqno)-1; - - list_for_each_entry(tfp, head, list) { - - if (!tfp->skb) - continue; - - if (tfp->seqno == ntohs(up->seqno)) - goto mov_tail; - - tmp_up = (struct unicast_frag_packet *)tfp->skb->data; - - if (tfp->seqno == search_seqno) { - - if ((tmp_up->flags & UNI_FRAG_HEAD) != - (up->flags & UNI_FRAG_HEAD)) - return tfp; - else - goto mov_tail; - } - } - return NULL; - -mov_tail: - list_move_tail(&tfp->list, head); - return NULL; -} - -void frag_list_free(struct list_head *head) -{ - struct frag_packet_list_entry *pf, *tmp_pf; - - if (!list_empty(head)) { - - list_for_each_entry_safe(pf, tmp_pf, head, list) { - kfree_skb(pf->skb); - list_del(&pf->list); - kfree(pf); - } - } - return; -} - -/* frag_reassemble_skb(): - * returns NET_RX_DROP if the operation failed - skb is left intact - * returns NET_RX_SUCCESS if the fragment was buffered (skb_new will be NULL) - * or the skb could be reassembled (skb_new will point to the new packet and - * skb was freed) - */ -int frag_reassemble_skb(struct sk_buff *skb, struct bat_priv *bat_priv, - struct sk_buff **new_skb) -{ - struct orig_node *orig_node; - struct frag_packet_list_entry *tmp_frag_entry; - int ret = NET_RX_DROP; - struct unicast_frag_packet *unicast_packet = - (struct unicast_frag_packet *)skb->data; - - *new_skb = NULL; - spin_lock_bh(&bat_priv->orig_hash_lock); - orig_node = ((struct orig_node *) - hash_find(bat_priv->orig_hash, compare_orig, choose_orig, - unicast_packet->orig)); - - if (!orig_node) { - pr_debug("couldn't find originator in orig_hash\n"); - goto out; - } - - orig_node->last_frag_packet = jiffies; - - if (list_empty(&orig_node->frag_list) && - frag_create_buffer(&orig_node->frag_list)) { - pr_debug("couldn't create frag buffer\n"); - goto out; - } - - tmp_frag_entry = frag_search_packet(&orig_node->frag_list, - unicast_packet); - - if (!tmp_frag_entry) { - frag_create_entry(&orig_node->frag_list, skb); - ret = NET_RX_SUCCESS; - goto out; - } - - *new_skb = frag_merge_packet(&orig_node->frag_list, tmp_frag_entry, - skb); - /* if not, merge failed */ - if (*new_skb) - ret = NET_RX_SUCCESS; -out: - spin_unlock_bh(&bat_priv->orig_hash_lock); - - return ret; -} - -int frag_send_skb(struct sk_buff *skb, struct bat_priv *bat_priv, - struct batman_if *batman_if, uint8_t dstaddr[]) -{ - struct unicast_packet tmp_uc, *unicast_packet; - struct sk_buff *frag_skb; - struct unicast_frag_packet *frag1, *frag2; - int uc_hdr_len = sizeof(struct unicast_packet); - int ucf_hdr_len = sizeof(struct unicast_frag_packet); - int data_len = skb->len; - - if (!bat_priv->primary_if) - goto dropped; - - unicast_packet = (struct unicast_packet *) skb->data; - - memcpy(&tmp_uc, unicast_packet, uc_hdr_len); - frag_skb = dev_alloc_skb(data_len - (data_len / 2) + ucf_hdr_len); - skb_split(skb, frag_skb, data_len / 2); - - if (my_skb_head_push(skb, ucf_hdr_len - uc_hdr_len) < 0 || - my_skb_head_push(frag_skb, ucf_hdr_len) < 0) - goto drop_frag; - - frag1 = (struct unicast_frag_packet *)skb->data; - frag2 = (struct unicast_frag_packet *)frag_skb->data; - - memcpy(frag1, &tmp_uc, sizeof(struct unicast_packet)); - - frag1->ttl--; - frag1->version = COMPAT_VERSION; - frag1->packet_type = BAT_UNICAST_FRAG; - - memcpy(frag1->orig, bat_priv->primary_if->net_dev->dev_addr, ETH_ALEN); - memcpy(frag2, frag1, sizeof(struct unicast_frag_packet)); - - frag1->flags |= UNI_FRAG_HEAD; - frag2->flags &= ~UNI_FRAG_HEAD; - - frag1->seqno = htons((uint16_t)atomic_inc_return( - &batman_if->frag_seqno)); - frag2->seqno = htons((uint16_t)atomic_inc_return( - &batman_if->frag_seqno)); - - send_skb_packet(skb, batman_if, dstaddr); - send_skb_packet(frag_skb, batman_if, dstaddr); - return NET_RX_SUCCESS; - -drop_frag: - kfree_skb(frag_skb); -dropped: - kfree_skb(skb); - return NET_RX_DROP; -} - -int unicast_send_skb(struct sk_buff *skb, struct bat_priv *bat_priv) -{ - struct ethhdr *ethhdr = (struct ethhdr *)skb->data; - struct unicast_packet *unicast_packet; - struct orig_node *orig_node; - struct batman_if *batman_if; - struct neigh_node *router; - int data_len = skb->len; - uint8_t dstaddr[6]; - - spin_lock_bh(&bat_priv->orig_hash_lock); - - /* get routing information */ - if (is_multicast_ether_addr(ethhdr->h_dest)) - orig_node = (struct orig_node *)gw_get_selected(bat_priv); - else - orig_node = ((struct orig_node *)hash_find(bat_priv->orig_hash, - compare_orig, - choose_orig, - ethhdr->h_dest)); - - /* check for hna host */ - if (!orig_node) - orig_node = transtable_search(bat_priv, ethhdr->h_dest); - - router = find_router(bat_priv, orig_node, NULL); - - if (!router) - goto unlock; - - /* don't lock while sending the packets ... we therefore - * copy the required data before sending */ - - batman_if = router->if_incoming; - memcpy(dstaddr, router->addr, ETH_ALEN); - - spin_unlock_bh(&bat_priv->orig_hash_lock); - - if (batman_if->if_status != IF_ACTIVE) - goto dropped; - - if (my_skb_head_push(skb, sizeof(struct unicast_packet)) < 0) - goto dropped; - - unicast_packet = (struct unicast_packet *)skb->data; - - unicast_packet->version = COMPAT_VERSION; - /* batman packet type: unicast */ - unicast_packet->packet_type = BAT_UNICAST; - /* set unicast ttl */ - unicast_packet->ttl = TTL; - /* copy the destination for faster routing */ - memcpy(unicast_packet->dest, orig_node->orig, ETH_ALEN); - - if (atomic_read(&bat_priv->fragmentation) && - data_len + sizeof(struct unicast_packet) > - batman_if->net_dev->mtu) { - /* send frag skb decreases ttl */ - unicast_packet->ttl++; - return frag_send_skb(skb, bat_priv, batman_if, - dstaddr); - } - send_skb_packet(skb, batman_if, dstaddr); - return 0; - -unlock: - spin_unlock_bh(&bat_priv->orig_hash_lock); -dropped: - kfree_skb(skb); - return 1; -} diff --git a/drivers/staging/batman-adv/unicast.h b/drivers/staging/batman-adv/unicast.h deleted file mode 100644 index e32b7867a9a4..000000000000 --- a/drivers/staging/batman-adv/unicast.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (C) 2010 B.A.T.M.A.N. contributors: - * - * Andreas Langer - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License 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. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA - * - */ - -#ifndef _NET_BATMAN_ADV_UNICAST_H_ -#define _NET_BATMAN_ADV_UNICAST_H_ - -#define FRAG_TIMEOUT 10000 /* purge frag list entrys after time in ms */ -#define FRAG_BUFFER_SIZE 6 /* number of list elements in buffer */ - -int frag_reassemble_skb(struct sk_buff *skb, struct bat_priv *bat_priv, - struct sk_buff **new_skb); -void frag_list_free(struct list_head *head); -int unicast_send_skb(struct sk_buff *skb, struct bat_priv *bat_priv); -int frag_send_skb(struct sk_buff *skb, struct bat_priv *bat_priv, - struct batman_if *batman_if, uint8_t dstaddr[]); - -#endif /* _NET_BATMAN_ADV_UNICAST_H_ */ diff --git a/drivers/staging/batman-adv/vis.c b/drivers/staging/batman-adv/vis.c deleted file mode 100644 index 957a08624ff8..000000000000 --- a/drivers/staging/batman-adv/vis.c +++ /dev/null @@ -1,903 +0,0 @@ -/* - * Copyright (C) 2008-2010 B.A.T.M.A.N. contributors: - * - * Simon Wunderlich - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License 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. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA - * - */ - -#include "main.h" -#include "send.h" -#include "translation-table.h" -#include "vis.h" -#include "soft-interface.h" -#include "hard-interface.h" -#include "hash.h" -#include "originator.h" - -#define MAX_VIS_PACKET_SIZE 1000 - -/* Returns the smallest signed integer in two's complement with the sizeof x */ -#define smallest_signed_int(x) (1u << (7u + 8u * (sizeof(x) - 1u))) - -/* Checks if a sequence number x is a predecessor/successor of y. - * they handle overflows/underflows and can correctly check for a - * predecessor/successor unless the variable sequence number has grown by - * more then 2**(bitwidth(x)-1)-1. - * This means that for a uint8_t with the maximum value 255, it would think: - * - when adding nothing - it is neither a predecessor nor a successor - * - before adding more than 127 to the starting value - it is a predecessor, - * - when adding 128 - it is neither a predecessor nor a successor, - * - after adding more than 127 to the starting value - it is a successor */ -#define seq_before(x, y) ({typeof(x) _dummy = (x - y); \ - _dummy > smallest_signed_int(_dummy); }) -#define seq_after(x, y) seq_before(y, x) - -static void start_vis_timer(struct bat_priv *bat_priv); - -/* free the info */ -static void free_info(struct kref *ref) -{ - struct vis_info *info = container_of(ref, struct vis_info, refcount); - struct bat_priv *bat_priv = info->bat_priv; - struct recvlist_node *entry, *tmp; - - list_del_init(&info->send_list); - spin_lock_bh(&bat_priv->vis_list_lock); - list_for_each_entry_safe(entry, tmp, &info->recv_list, list) { - list_del(&entry->list); - kfree(entry); - } - - spin_unlock_bh(&bat_priv->vis_list_lock); - kfree_skb(info->skb_packet); -} - -/* Compare two vis packets, used by the hashing algorithm */ -static int vis_info_cmp(void *data1, void *data2) -{ - struct vis_info *d1, *d2; - struct vis_packet *p1, *p2; - d1 = data1; - d2 = data2; - p1 = (struct vis_packet *)d1->skb_packet->data; - p2 = (struct vis_packet *)d2->skb_packet->data; - return compare_orig(p1->vis_orig, p2->vis_orig); -} - -/* hash function to choose an entry in a hash table of given size */ -/* hash algorithm from http://en.wikipedia.org/wiki/Hash_table */ -static int vis_info_choose(void *data, int size) -{ - struct vis_info *vis_info = data; - struct vis_packet *packet; - unsigned char *key; - uint32_t hash = 0; - size_t i; - - packet = (struct vis_packet *)vis_info->skb_packet->data; - key = packet->vis_orig; - for (i = 0; i < ETH_ALEN; i++) { - hash += key[i]; - hash += (hash << 10); - hash ^= (hash >> 6); - } - - hash += (hash << 3); - hash ^= (hash >> 11); - hash += (hash << 15); - - return hash % size; -} - -/* insert interface to the list of interfaces of one originator, if it - * does not already exist in the list */ -static void vis_data_insert_interface(const uint8_t *interface, - struct hlist_head *if_list, - bool primary) -{ - struct if_list_entry *entry; - struct hlist_node *pos; - - hlist_for_each_entry(entry, pos, if_list, list) { - if (compare_orig(entry->addr, (void *)interface)) - return; - } - - /* its a new address, add it to the list */ - entry = kmalloc(sizeof(*entry), GFP_ATOMIC); - if (!entry) - return; - memcpy(entry->addr, interface, ETH_ALEN); - entry->primary = primary; - hlist_add_head(&entry->list, if_list); -} - -static ssize_t vis_data_read_prim_sec(char *buff, struct hlist_head *if_list) -{ - struct if_list_entry *entry; - struct hlist_node *pos; - size_t len = 0; - - hlist_for_each_entry(entry, pos, if_list, list) { - if (entry->primary) - len += sprintf(buff + len, "PRIMARY, "); - else - len += sprintf(buff + len, "SEC %pM, ", entry->addr); - } - - return len; -} - -static size_t vis_data_count_prim_sec(struct hlist_head *if_list) -{ - struct if_list_entry *entry; - struct hlist_node *pos; - size_t count = 0; - - hlist_for_each_entry(entry, pos, if_list, list) { - if (entry->primary) - count += 9; - else - count += 23; - } - - return count; -} - -/* read an entry */ -static ssize_t vis_data_read_entry(char *buff, struct vis_info_entry *entry, - uint8_t *src, bool primary) -{ - /* maximal length: max(4+17+2, 3+17+1+3+2) == 26 */ - if (primary && entry->quality == 0) - return sprintf(buff, "HNA %pM, ", entry->dest); - else if (compare_orig(entry->src, src)) - return sprintf(buff, "TQ %pM %d, ", entry->dest, - entry->quality); - - return 0; -} - -int vis_seq_print_text(struct seq_file *seq, void *offset) -{ - HASHIT(hashit); - HASHIT(hashit_count); - struct element_t *bucket; - struct vis_info *info; - struct vis_packet *packet; - struct vis_info_entry *entries; - struct net_device *net_dev = (struct net_device *)seq->private; - struct bat_priv *bat_priv = netdev_priv(net_dev); - HLIST_HEAD(vis_if_list); - struct if_list_entry *entry; - struct hlist_node *pos, *n; - int i; - int vis_server = atomic_read(&bat_priv->vis_mode); - size_t buff_pos, buf_size; - char *buff; - - if ((!bat_priv->primary_if) || - (vis_server == VIS_TYPE_CLIENT_UPDATE)) - return 0; - - buf_size = 1; - /* Estimate length */ - spin_lock_bh(&bat_priv->vis_hash_lock); - while (hash_iterate(bat_priv->vis_hash, &hashit_count)) { - bucket = hlist_entry(hashit_count.walk, struct element_t, - hlist); - info = bucket->data; - packet = (struct vis_packet *)info->skb_packet->data; - entries = (struct vis_info_entry *) - ((char *)packet + sizeof(struct vis_packet)); - - for (i = 0; i < packet->entries; i++) { - if (entries[i].quality == 0) - continue; - vis_data_insert_interface(entries[i].src, &vis_if_list, - compare_orig(entries[i].src, packet->vis_orig)); - } - - hlist_for_each_entry(entry, pos, &vis_if_list, list) { - buf_size += 18 + 26 * packet->entries; - - /* add primary/secondary records */ - if (compare_orig(entry->addr, packet->vis_orig)) - buf_size += - vis_data_count_prim_sec(&vis_if_list); - - buf_size += 1; - } - - hlist_for_each_entry_safe(entry, pos, n, &vis_if_list, list) { - hlist_del(&entry->list); - kfree(entry); - } - } - - buff = kmalloc(buf_size, GFP_ATOMIC); - if (!buff) { - spin_unlock_bh(&bat_priv->vis_hash_lock); - return -ENOMEM; - } - buff[0] = '\0'; - buff_pos = 0; - - while (hash_iterate(bat_priv->vis_hash, &hashit)) { - bucket = hlist_entry(hashit.walk, struct element_t, hlist); - info = bucket->data; - packet = (struct vis_packet *)info->skb_packet->data; - entries = (struct vis_info_entry *) - ((char *)packet + sizeof(struct vis_packet)); - - for (i = 0; i < packet->entries; i++) { - if (entries[i].quality == 0) - continue; - vis_data_insert_interface(entries[i].src, &vis_if_list, - compare_orig(entries[i].src, packet->vis_orig)); - } - - hlist_for_each_entry(entry, pos, &vis_if_list, list) { - buff_pos += sprintf(buff + buff_pos, "%pM,", - entry->addr); - - for (i = 0; i < packet->entries; i++) - buff_pos += vis_data_read_entry(buff + buff_pos, - &entries[i], - entry->addr, - entry->primary); - - /* add primary/secondary records */ - if (compare_orig(entry->addr, packet->vis_orig)) - buff_pos += - vis_data_read_prim_sec(buff + buff_pos, - &vis_if_list); - - buff_pos += sprintf(buff + buff_pos, "\n"); - } - - hlist_for_each_entry_safe(entry, pos, n, &vis_if_list, list) { - hlist_del(&entry->list); - kfree(entry); - } - } - - spin_unlock_bh(&bat_priv->vis_hash_lock); - - seq_printf(seq, "%s", buff); - kfree(buff); - - return 0; -} - -/* add the info packet to the send list, if it was not - * already linked in. */ -static void send_list_add(struct bat_priv *bat_priv, struct vis_info *info) -{ - if (list_empty(&info->send_list)) { - kref_get(&info->refcount); - list_add_tail(&info->send_list, &bat_priv->vis_send_list); - } -} - -/* delete the info packet from the send list, if it was - * linked in. */ -static void send_list_del(struct vis_info *info) -{ - if (!list_empty(&info->send_list)) { - list_del_init(&info->send_list); - kref_put(&info->refcount, free_info); - } -} - -/* tries to add one entry to the receive list. */ -static void recv_list_add(struct bat_priv *bat_priv, - struct list_head *recv_list, char *mac) -{ - struct recvlist_node *entry; - - entry = kmalloc(sizeof(struct recvlist_node), GFP_ATOMIC); - if (!entry) - return; - - memcpy(entry->mac, mac, ETH_ALEN); - spin_lock_bh(&bat_priv->vis_list_lock); - list_add_tail(&entry->list, recv_list); - spin_unlock_bh(&bat_priv->vis_list_lock); -} - -/* returns 1 if this mac is in the recv_list */ -static int recv_list_is_in(struct bat_priv *bat_priv, - struct list_head *recv_list, char *mac) -{ - struct recvlist_node *entry; - - spin_lock_bh(&bat_priv->vis_list_lock); - list_for_each_entry(entry, recv_list, list) { - if (memcmp(entry->mac, mac, ETH_ALEN) == 0) { - spin_unlock_bh(&bat_priv->vis_list_lock); - return 1; - } - } - spin_unlock_bh(&bat_priv->vis_list_lock); - return 0; -} - -/* try to add the packet to the vis_hash. return NULL if invalid (e.g. too old, - * broken.. ). vis hash must be locked outside. is_new is set when the packet - * is newer than old entries in the hash. */ -static struct vis_info *add_packet(struct bat_priv *bat_priv, - struct vis_packet *vis_packet, - int vis_info_len, int *is_new, - int make_broadcast) -{ - struct vis_info *info, *old_info; - struct vis_packet *search_packet, *old_packet; - struct vis_info search_elem; - struct vis_packet *packet; - int hash_added; - - *is_new = 0; - /* sanity check */ - if (!bat_priv->vis_hash) - return NULL; - - /* see if the packet is already in vis_hash */ - search_elem.skb_packet = dev_alloc_skb(sizeof(struct vis_packet)); - if (!search_elem.skb_packet) - return NULL; - search_packet = (struct vis_packet *)skb_put(search_elem.skb_packet, - sizeof(struct vis_packet)); - - memcpy(search_packet->vis_orig, vis_packet->vis_orig, ETH_ALEN); - old_info = hash_find(bat_priv->vis_hash, vis_info_cmp, vis_info_choose, - &search_elem); - kfree_skb(search_elem.skb_packet); - - if (old_info != NULL) { - old_packet = (struct vis_packet *)old_info->skb_packet->data; - if (!seq_after(ntohl(vis_packet->seqno), - ntohl(old_packet->seqno))) { - if (old_packet->seqno == vis_packet->seqno) { - recv_list_add(bat_priv, &old_info->recv_list, - vis_packet->sender_orig); - return old_info; - } else { - /* newer packet is already in hash. */ - return NULL; - } - } - /* remove old entry */ - hash_remove(bat_priv->vis_hash, vis_info_cmp, vis_info_choose, - old_info); - send_list_del(old_info); - kref_put(&old_info->refcount, free_info); - } - - info = kmalloc(sizeof(struct vis_info), GFP_ATOMIC); - if (!info) - return NULL; - - info->skb_packet = dev_alloc_skb(sizeof(struct vis_packet) + - vis_info_len + sizeof(struct ethhdr)); - if (!info->skb_packet) { - kfree(info); - return NULL; - } - skb_reserve(info->skb_packet, sizeof(struct ethhdr)); - packet = (struct vis_packet *)skb_put(info->skb_packet, - sizeof(struct vis_packet) + - vis_info_len); - - kref_init(&info->refcount); - INIT_LIST_HEAD(&info->send_list); - INIT_LIST_HEAD(&info->recv_list); - info->first_seen = jiffies; - info->bat_priv = bat_priv; - memcpy(packet, vis_packet, sizeof(struct vis_packet) + vis_info_len); - - /* initialize and add new packet. */ - *is_new = 1; - - /* Make it a broadcast packet, if required */ - if (make_broadcast) - memcpy(packet->target_orig, broadcast_addr, ETH_ALEN); - - /* repair if entries is longer than packet. */ - if (packet->entries * sizeof(struct vis_info_entry) > vis_info_len) - packet->entries = vis_info_len / sizeof(struct vis_info_entry); - - recv_list_add(bat_priv, &info->recv_list, packet->sender_orig); - - /* try to add it */ - hash_added = hash_add(bat_priv->vis_hash, vis_info_cmp, vis_info_choose, - info); - if (hash_added < 0) { - /* did not work (for some reason) */ - kref_put(&old_info->refcount, free_info); - info = NULL; - } - - return info; -} - -/* handle the server sync packet, forward if needed. */ -void receive_server_sync_packet(struct bat_priv *bat_priv, - struct vis_packet *vis_packet, - int vis_info_len) -{ - struct vis_info *info; - int is_new, make_broadcast; - int vis_server = atomic_read(&bat_priv->vis_mode); - - make_broadcast = (vis_server == VIS_TYPE_SERVER_SYNC); - - spin_lock_bh(&bat_priv->vis_hash_lock); - info = add_packet(bat_priv, vis_packet, vis_info_len, - &is_new, make_broadcast); - if (!info) - goto end; - - /* only if we are server ourselves and packet is newer than the one in - * hash.*/ - if (vis_server == VIS_TYPE_SERVER_SYNC && is_new) - send_list_add(bat_priv, info); -end: - spin_unlock_bh(&bat_priv->vis_hash_lock); -} - -/* handle an incoming client update packet and schedule forward if needed. */ -void receive_client_update_packet(struct bat_priv *bat_priv, - struct vis_packet *vis_packet, - int vis_info_len) -{ - struct vis_info *info; - struct vis_packet *packet; - int is_new; - int vis_server = atomic_read(&bat_priv->vis_mode); - int are_target = 0; - - /* clients shall not broadcast. */ - if (is_broadcast_ether_addr(vis_packet->target_orig)) - return; - - /* Are we the target for this VIS packet? */ - if (vis_server == VIS_TYPE_SERVER_SYNC && - is_my_mac(vis_packet->target_orig)) - are_target = 1; - - spin_lock_bh(&bat_priv->vis_hash_lock); - info = add_packet(bat_priv, vis_packet, vis_info_len, - &is_new, are_target); - - if (!info) - goto end; - /* note that outdated packets will be dropped at this point. */ - - packet = (struct vis_packet *)info->skb_packet->data; - - /* send only if we're the target server or ... */ - if (are_target && is_new) { - packet->vis_type = VIS_TYPE_SERVER_SYNC; /* upgrade! */ - send_list_add(bat_priv, info); - - /* ... we're not the recipient (and thus need to forward). */ - } else if (!is_my_mac(packet->target_orig)) { - send_list_add(bat_priv, info); - } - -end: - spin_unlock_bh(&bat_priv->vis_hash_lock); -} - -/* Walk the originators and find the VIS server with the best tq. Set the packet - * address to its address and return the best_tq. - * - * Must be called with the originator hash locked */ -static int find_best_vis_server(struct bat_priv *bat_priv, - struct vis_info *info) -{ - HASHIT(hashit); - struct element_t *bucket; - struct orig_node *orig_node; - struct vis_packet *packet; - int best_tq = -1; - - packet = (struct vis_packet *)info->skb_packet->data; - - while (hash_iterate(bat_priv->orig_hash, &hashit)) { - bucket = hlist_entry(hashit.walk, struct element_t, hlist); - orig_node = bucket->data; - if ((orig_node) && (orig_node->router) && - (orig_node->flags & VIS_SERVER) && - (orig_node->router->tq_avg > best_tq)) { - best_tq = orig_node->router->tq_avg; - memcpy(packet->target_orig, orig_node->orig, ETH_ALEN); - } - } - return best_tq; -} - -/* Return true if the vis packet is full. */ -static bool vis_packet_full(struct vis_info *info) -{ - struct vis_packet *packet; - packet = (struct vis_packet *)info->skb_packet->data; - - if (MAX_VIS_PACKET_SIZE / sizeof(struct vis_info_entry) - < packet->entries + 1) - return true; - return false; -} - -/* generates a packet of own vis data, - * returns 0 on success, -1 if no packet could be generated */ -static int generate_vis_packet(struct bat_priv *bat_priv) -{ - HASHIT(hashit_local); - HASHIT(hashit_global); - struct element_t *bucket; - struct orig_node *orig_node; - struct vis_info *info = (struct vis_info *)bat_priv->my_vis_info; - struct vis_packet *packet = (struct vis_packet *)info->skb_packet->data; - struct vis_info_entry *entry; - struct hna_local_entry *hna_local_entry; - int best_tq = -1; - - info->first_seen = jiffies; - packet->vis_type = atomic_read(&bat_priv->vis_mode); - - spin_lock_bh(&bat_priv->orig_hash_lock); - memcpy(packet->target_orig, broadcast_addr, ETH_ALEN); - packet->ttl = TTL; - packet->seqno = htonl(ntohl(packet->seqno) + 1); - packet->entries = 0; - skb_trim(info->skb_packet, sizeof(struct vis_packet)); - - if (packet->vis_type == VIS_TYPE_CLIENT_UPDATE) { - best_tq = find_best_vis_server(bat_priv, info); - - if (best_tq < 0) { - spin_unlock_bh(&bat_priv->orig_hash_lock); - return -1; - } - } - - while (hash_iterate(bat_priv->orig_hash, &hashit_global)) { - bucket = hlist_entry(hashit_global.walk, struct element_t, - hlist); - orig_node = bucket->data; - - if (!orig_node->router) - continue; - - if (!compare_orig(orig_node->router->addr, orig_node->orig)) - continue; - - if (orig_node->router->if_incoming->if_status != IF_ACTIVE) - continue; - - if (orig_node->router->tq_avg < 1) - continue; - - /* fill one entry into buffer. */ - entry = (struct vis_info_entry *) - skb_put(info->skb_packet, sizeof(*entry)); - memcpy(entry->src, - orig_node->router->if_incoming->net_dev->dev_addr, - ETH_ALEN); - memcpy(entry->dest, orig_node->orig, ETH_ALEN); - entry->quality = orig_node->router->tq_avg; - packet->entries++; - - if (vis_packet_full(info)) { - spin_unlock_bh(&bat_priv->orig_hash_lock); - return 0; - } - } - - spin_unlock_bh(&bat_priv->orig_hash_lock); - - spin_lock_bh(&bat_priv->hna_lhash_lock); - while (hash_iterate(bat_priv->hna_local_hash, &hashit_local)) { - bucket = hlist_entry(hashit_local.walk, struct element_t, - hlist); - hna_local_entry = bucket->data; - entry = (struct vis_info_entry *)skb_put(info->skb_packet, - sizeof(*entry)); - memset(entry->src, 0, ETH_ALEN); - memcpy(entry->dest, hna_local_entry->addr, ETH_ALEN); - entry->quality = 0; /* 0 means HNA */ - packet->entries++; - - if (vis_packet_full(info)) { - spin_unlock_bh(&bat_priv->hna_lhash_lock); - return 0; - } - } - - spin_unlock_bh(&bat_priv->hna_lhash_lock); - return 0; -} - -/* free old vis packets. Must be called with this vis_hash_lock - * held */ -static void purge_vis_packets(struct bat_priv *bat_priv) -{ - HASHIT(hashit); - struct element_t *bucket; - struct vis_info *info; - - while (hash_iterate(bat_priv->vis_hash, &hashit)) { - bucket = hlist_entry(hashit.walk, struct element_t, hlist); - info = bucket->data; - - /* never purge own data. */ - if (info == bat_priv->my_vis_info) - continue; - - if (time_after(jiffies, - info->first_seen + VIS_TIMEOUT * HZ)) { - hash_remove_bucket(bat_priv->vis_hash, &hashit); - send_list_del(info); - kref_put(&info->refcount, free_info); - } - } -} - -static void broadcast_vis_packet(struct bat_priv *bat_priv, - struct vis_info *info) -{ - HASHIT(hashit); - struct element_t *bucket; - struct orig_node *orig_node; - struct vis_packet *packet; - struct sk_buff *skb; - struct batman_if *batman_if; - uint8_t dstaddr[ETH_ALEN]; - - - spin_lock_bh(&bat_priv->orig_hash_lock); - packet = (struct vis_packet *)info->skb_packet->data; - - /* send to all routers in range. */ - while (hash_iterate(bat_priv->orig_hash, &hashit)) { - bucket = hlist_entry(hashit.walk, struct element_t, hlist); - orig_node = bucket->data; - - /* if it's a vis server and reachable, send it. */ - if ((!orig_node) || (!orig_node->router)) - continue; - if (!(orig_node->flags & VIS_SERVER)) - continue; - /* don't send it if we already received the packet from - * this node. */ - if (recv_list_is_in(bat_priv, &info->recv_list, - orig_node->orig)) - continue; - - memcpy(packet->target_orig, orig_node->orig, ETH_ALEN); - batman_if = orig_node->router->if_incoming; - memcpy(dstaddr, orig_node->router->addr, ETH_ALEN); - spin_unlock_bh(&bat_priv->orig_hash_lock); - - skb = skb_clone(info->skb_packet, GFP_ATOMIC); - if (skb) - send_skb_packet(skb, batman_if, dstaddr); - - spin_lock_bh(&bat_priv->orig_hash_lock); - - } - - spin_unlock_bh(&bat_priv->orig_hash_lock); -} - -static void unicast_vis_packet(struct bat_priv *bat_priv, - struct vis_info *info) -{ - struct orig_node *orig_node; - struct sk_buff *skb; - struct vis_packet *packet; - struct batman_if *batman_if; - uint8_t dstaddr[ETH_ALEN]; - - spin_lock_bh(&bat_priv->orig_hash_lock); - packet = (struct vis_packet *)info->skb_packet->data; - orig_node = ((struct orig_node *)hash_find(bat_priv->orig_hash, - compare_orig, choose_orig, - packet->target_orig)); - - if ((!orig_node) || (!orig_node->router)) - goto out; - - /* don't lock while sending the packets ... we therefore - * copy the required data before sending */ - batman_if = orig_node->router->if_incoming; - memcpy(dstaddr, orig_node->router->addr, ETH_ALEN); - spin_unlock_bh(&bat_priv->orig_hash_lock); - - skb = skb_clone(info->skb_packet, GFP_ATOMIC); - if (skb) - send_skb_packet(skb, batman_if, dstaddr); - - return; - -out: - spin_unlock_bh(&bat_priv->orig_hash_lock); -} - -/* only send one vis packet. called from send_vis_packets() */ -static void send_vis_packet(struct bat_priv *bat_priv, struct vis_info *info) -{ - struct vis_packet *packet; - - packet = (struct vis_packet *)info->skb_packet->data; - if (packet->ttl < 2) { - pr_debug("Error - can't send vis packet: ttl exceeded\n"); - return; - } - - memcpy(packet->sender_orig, bat_priv->primary_if->net_dev->dev_addr, - ETH_ALEN); - packet->ttl--; - - if (is_broadcast_ether_addr(packet->target_orig)) - broadcast_vis_packet(bat_priv, info); - else - unicast_vis_packet(bat_priv, info); - packet->ttl++; /* restore TTL */ -} - -/* called from timer; send (and maybe generate) vis packet. */ -static void send_vis_packets(struct work_struct *work) -{ - struct delayed_work *delayed_work = - container_of(work, struct delayed_work, work); - struct bat_priv *bat_priv = - container_of(delayed_work, struct bat_priv, vis_work); - struct vis_info *info, *temp; - - spin_lock_bh(&bat_priv->vis_hash_lock); - purge_vis_packets(bat_priv); - - if (generate_vis_packet(bat_priv) == 0) { - /* schedule if generation was successful */ - send_list_add(bat_priv, bat_priv->my_vis_info); - } - - list_for_each_entry_safe(info, temp, &bat_priv->vis_send_list, - send_list) { - - kref_get(&info->refcount); - spin_unlock_bh(&bat_priv->vis_hash_lock); - - if (bat_priv->primary_if) - send_vis_packet(bat_priv, info); - - spin_lock_bh(&bat_priv->vis_hash_lock); - send_list_del(info); - kref_put(&info->refcount, free_info); - } - spin_unlock_bh(&bat_priv->vis_hash_lock); - start_vis_timer(bat_priv); -} - -/* init the vis server. this may only be called when if_list is already - * initialized (e.g. bat0 is initialized, interfaces have been added) */ -int vis_init(struct bat_priv *bat_priv) -{ - struct vis_packet *packet; - int hash_added; - - if (bat_priv->vis_hash) - return 1; - - spin_lock_bh(&bat_priv->vis_hash_lock); - - bat_priv->vis_hash = hash_new(256); - if (!bat_priv->vis_hash) { - pr_err("Can't initialize vis_hash\n"); - goto err; - } - - bat_priv->my_vis_info = kmalloc(MAX_VIS_PACKET_SIZE, GFP_ATOMIC); - if (!bat_priv->my_vis_info) { - pr_err("Can't initialize vis packet\n"); - goto err; - } - - bat_priv->my_vis_info->skb_packet = dev_alloc_skb( - sizeof(struct vis_packet) + - MAX_VIS_PACKET_SIZE + - sizeof(struct ethhdr)); - if (!bat_priv->my_vis_info->skb_packet) - goto free_info; - - skb_reserve(bat_priv->my_vis_info->skb_packet, sizeof(struct ethhdr)); - packet = (struct vis_packet *)skb_put( - bat_priv->my_vis_info->skb_packet, - sizeof(struct vis_packet)); - - /* prefill the vis info */ - bat_priv->my_vis_info->first_seen = jiffies - - msecs_to_jiffies(VIS_INTERVAL); - INIT_LIST_HEAD(&bat_priv->my_vis_info->recv_list); - INIT_LIST_HEAD(&bat_priv->my_vis_info->send_list); - kref_init(&bat_priv->my_vis_info->refcount); - bat_priv->my_vis_info->bat_priv = bat_priv; - packet->version = COMPAT_VERSION; - packet->packet_type = BAT_VIS; - packet->ttl = TTL; - packet->seqno = 0; - packet->entries = 0; - - INIT_LIST_HEAD(&bat_priv->vis_send_list); - - hash_added = hash_add(bat_priv->vis_hash, vis_info_cmp, vis_info_choose, - bat_priv->my_vis_info); - if (hash_added < 0) { - pr_err("Can't add own vis packet into hash\n"); - /* not in hash, need to remove it manually. */ - kref_put(&bat_priv->my_vis_info->refcount, free_info); - goto err; - } - - spin_unlock_bh(&bat_priv->vis_hash_lock); - start_vis_timer(bat_priv); - return 1; - -free_info: - kfree(bat_priv->my_vis_info); - bat_priv->my_vis_info = NULL; -err: - spin_unlock_bh(&bat_priv->vis_hash_lock); - vis_quit(bat_priv); - return 0; -} - -/* Decrease the reference count on a hash item info */ -static void free_info_ref(void *data, void *arg) -{ - struct vis_info *info = data; - - send_list_del(info); - kref_put(&info->refcount, free_info); -} - -/* shutdown vis-server */ -void vis_quit(struct bat_priv *bat_priv) -{ - if (!bat_priv->vis_hash) - return; - - cancel_delayed_work_sync(&bat_priv->vis_work); - - spin_lock_bh(&bat_priv->vis_hash_lock); - /* properly remove, kill timers ... */ - hash_delete(bat_priv->vis_hash, free_info_ref, NULL); - bat_priv->vis_hash = NULL; - bat_priv->my_vis_info = NULL; - spin_unlock_bh(&bat_priv->vis_hash_lock); -} - -/* schedule packets for (re)transmission */ -static void start_vis_timer(struct bat_priv *bat_priv) -{ - INIT_DELAYED_WORK(&bat_priv->vis_work, send_vis_packets); - queue_delayed_work(bat_event_workqueue, &bat_priv->vis_work, - msecs_to_jiffies(VIS_INTERVAL)); -} diff --git a/drivers/staging/batman-adv/vis.h b/drivers/staging/batman-adv/vis.h deleted file mode 100644 index 2c3b33089a9b..000000000000 --- a/drivers/staging/batman-adv/vis.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (C) 2008-2010 B.A.T.M.A.N. contributors: - * - * Simon Wunderlich, Marek Lindner - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of version 2 of the GNU General Public - * License 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. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - * 02110-1301, USA - * - */ - -#ifndef _NET_BATMAN_ADV_VIS_H_ -#define _NET_BATMAN_ADV_VIS_H_ - -#define VIS_TIMEOUT 200 /* timeout of vis packets in seconds */ - -int vis_seq_print_text(struct seq_file *seq, void *offset); -void receive_server_sync_packet(struct bat_priv *bat_priv, - struct vis_packet *vis_packet, - int vis_info_len); -void receive_client_update_packet(struct bat_priv *bat_priv, - struct vis_packet *vis_packet, - int vis_info_len); -int vis_init(struct bat_priv *bat_priv); -void vis_quit(struct bat_priv *bat_priv); - -#endif /* _NET_BATMAN_ADV_VIS_H_ */ -- cgit v1.2.3 From a8adbe378b56acd5945df70753c7e8f6fe223304 Mon Sep 17 00:00:00 2001 From: MichaÅ‚ MirosÅ‚aw Date: Fri, 17 Dec 2010 08:56:44 +0100 Subject: fs/splice: Pull buf->ops->confirm() from splice_from_pipe actors MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch pulls calls to buf->ops->confirm() from all actors passed (also indirectly) to splice_from_pipe_feed(). Is avoiding the call to buf->ops->confirm() while splice()ing to /dev/null is an intentional optimization? No other user does that and this will remove this special case. Against current linux.git 6313e3c21743cc88bb5bd8aa72948ee1e83937b6. Signed-off-by: MichaÅ‚ MirosÅ‚aw Signed-off-by: Jens Axboe --- drivers/block/loop.c | 4 ---- fs/nfsd/vfs.c | 4 ---- fs/splice.c | 43 ++++++++++++++----------------------------- 3 files changed, 14 insertions(+), 37 deletions(-) diff --git a/drivers/block/loop.c b/drivers/block/loop.c index 7ea0bea2f7e3..c87b0840d2cb 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -397,10 +397,6 @@ lo_splice_actor(struct pipe_inode_info *pipe, struct pipe_buffer *buf, sector_t IV; int size, ret; - ret = buf->ops->confirm(pipe, buf); - if (unlikely(ret)) - return ret; - IV = ((sector_t) page->index << (PAGE_CACHE_SHIFT - 9)) + (buf->offset >> 9); size = sd->len; diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index 184938fcff04..c6e08661adee 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c @@ -847,10 +847,6 @@ nfsd_splice_actor(struct pipe_inode_info *pipe, struct pipe_buffer *buf, size_t size; int ret; - ret = buf->ops->confirm(pipe, buf); - if (unlikely(ret)) - return ret; - size = sd->len; if (rqstp->rq_res.page_len == 0) { diff --git a/fs/splice.c b/fs/splice.c index 8f1dfaecc8f0..d2026382ac3e 100644 --- a/fs/splice.c +++ b/fs/splice.c @@ -682,19 +682,14 @@ static int pipe_to_sendpage(struct pipe_inode_info *pipe, { struct file *file = sd->u.file; loff_t pos = sd->pos; - int ret, more; - - ret = buf->ops->confirm(pipe, buf); - if (!ret) { - more = (sd->flags & SPLICE_F_MORE) || sd->len < sd->total_len; - if (file->f_op && file->f_op->sendpage) - ret = file->f_op->sendpage(file, buf->page, buf->offset, - sd->len, &pos, more); - else - ret = -EINVAL; - } + int more; - return ret; + if (!likely(file->f_op && file->f_op->sendpage)) + return -EINVAL; + + more = (sd->flags & SPLICE_F_MORE) || sd->len < sd->total_len; + return file->f_op->sendpage(file, buf->page, buf->offset, + sd->len, &pos, more); } /* @@ -727,13 +722,6 @@ int pipe_to_file(struct pipe_inode_info *pipe, struct pipe_buffer *buf, void *fsdata; int ret; - /* - * make sure the data in this buffer is uptodate - */ - ret = buf->ops->confirm(pipe, buf); - if (unlikely(ret)) - return ret; - offset = sd->pos & ~PAGE_CACHE_MASK; this_len = sd->len; @@ -805,12 +793,17 @@ int splice_from_pipe_feed(struct pipe_inode_info *pipe, struct splice_desc *sd, if (sd->len > sd->total_len) sd->len = sd->total_len; - ret = actor(pipe, buf, sd); - if (ret <= 0) { + ret = buf->ops->confirm(pipe, buf); + if (unlikely(ret)) { if (ret == -ENODATA) ret = 0; return ret; } + + ret = actor(pipe, buf, sd); + if (ret <= 0) + return ret; + buf->offset += ret; buf->len -= ret; @@ -1044,10 +1037,6 @@ static int write_pipe_buf(struct pipe_inode_info *pipe, struct pipe_buffer *buf, int ret; void *data; - ret = buf->ops->confirm(pipe, buf); - if (ret) - return ret; - data = buf->ops->map(pipe, buf, 0); ret = kernel_write(sd->u.file, data + buf->offset, sd->len, sd->pos); buf->ops->unmap(pipe, buf, data); @@ -1507,10 +1496,6 @@ static int pipe_to_user(struct pipe_inode_info *pipe, struct pipe_buffer *buf, char *src; int ret; - ret = buf->ops->confirm(pipe, buf); - if (unlikely(ret)) - return ret; - /* * See if we can use the atomic maps, by prefaulting in the * pages and doing an atomic copy -- cgit v1.2.3 From 7278c9c19bd85cf33213a2e0b538a18d3ac8ad00 Mon Sep 17 00:00:00 2001 From: Gui Jianfeng Date: Fri, 17 Dec 2010 08:57:14 +0100 Subject: cfq-iosched: don't check cfqg in choose_service_tree() When cfq_choose_cfqg() is called in select_queue(), there must be at least one backlogged CFQ queue waiting for dispatching, hence there must be at least one backlogged CFQ group on service tree. So we never call choose_service_tree() with cfqg == NULL. Signed-off-by: Gui Jianfeng Reviewed-by: Jeff Moyer Acked-by: Vivek Goyal Signed-off-by: Jens Axboe --- block/cfq-iosched.c | 6 ------ 1 file changed, 6 deletions(-) diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c index 9b186fd6bf47..c19d015ac5a5 100644 --- a/block/cfq-iosched.c +++ b/block/cfq-iosched.c @@ -2103,12 +2103,6 @@ static void choose_service_tree(struct cfq_data *cfqd, struct cfq_group *cfqg) unsigned group_slice; enum wl_prio_t original_prio = cfqd->serving_prio; - if (!cfqg) { - cfqd->serving_prio = IDLE_WORKLOAD; - cfqd->workload_expires = jiffies + 1; - return; - } - /* Choose next priority. RT > BE > IDLE */ if (cfq_group_busy_queues_wl(RT_WORKLOAD, cfqd, cfqg)) cfqd->serving_prio = RT_WORKLOAD; -- cgit v1.2.3 From b9f985b6e05ebd7af2aaef0eb3ae369390ef191f Mon Sep 17 00:00:00 2001 From: Yang Zhang Date: Fri, 17 Dec 2010 08:58:36 +0100 Subject: block: convert !IS_ERR(p) && p to !IS_ERR_NOR_NULL(p) Signed-off-by: Yang Zhang Signed-off-by: Jens Axboe --- block/genhd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/block/genhd.c b/block/genhd.c index 5fa2b44a72ff..79b9e327f3cb 100644 --- a/block/genhd.c +++ b/block/genhd.c @@ -735,7 +735,7 @@ static void *show_partition_start(struct seq_file *seqf, loff_t *pos) static void *p; p = disk_seqf_start(seqf, pos); - if (!IS_ERR(p) && p && !*pos) + if (!IS_ERR_OR_NULL(p) && !*pos) seq_puts(seqf, "major minor #blocks name\n\n"); return p; } -- cgit v1.2.3 From e61eb2e93fe86931d46831752a82dab25a5335ca Mon Sep 17 00:00:00 2001 From: Yang Zhang Date: Fri, 17 Dec 2010 09:00:18 +0100 Subject: fs/block: type signature of major_to_index(int) to major_to_index(unsigned) The major/minor device numbers are always defined and used as `unsigned'. Signed-off-by: Yang Zhang Signed-off-by: Jens Axboe --- block/genhd.c | 2 +- fs/char_dev.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/block/genhd.c b/block/genhd.c index 79b9e327f3cb..16ccc0d2d5d3 100644 --- a/block/genhd.c +++ b/block/genhd.c @@ -239,7 +239,7 @@ static struct blk_major_name { } *major_names[BLKDEV_MAJOR_HASH_SIZE]; /* index in the above - for now: assume no multimajor ranges */ -static inline int major_to_index(int major) +static inline int major_to_index(unsigned major) { return major % BLKDEV_MAJOR_HASH_SIZE; } diff --git a/fs/char_dev.c b/fs/char_dev.c index e5b9df993b93..143f0207c7eb 100644 --- a/fs/char_dev.c +++ b/fs/char_dev.c @@ -59,7 +59,7 @@ static struct char_device_struct { } *chrdevs[CHRDEV_MAJOR_HASH_SIZE]; /* index in the above */ -static inline int major_to_index(int major) +static inline int major_to_index(unsigned major) { return major % CHRDEV_MAJOR_HASH_SIZE; } -- cgit v1.2.3 From 9c3d2f7ffac34c62fea0b73e607707168a6f09b1 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Fri, 17 Dec 2010 10:54:26 +0000 Subject: drm/i915: Enable EI mode for RCx decision making on Sandybridge And no I have no idea what the difference is either, just that is the recommendation. Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/intel_display.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index fe6538297872..c79bee4b4d56 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -6141,6 +6141,7 @@ static void gen6_enable_rc6(struct drm_i915_private *dev_priv) I915_WRITE(GEN6_RC_CONTROL, GEN6_RC_CTL_RC6p_ENABLE | GEN6_RC_CTL_RC6_ENABLE | + GEN6_RC_CTL_EI_MODE(1) | GEN6_RC_CTL_HW_ENABLE); I915_WRITE(GEN6_RC_NORMAL_FREQ, -- cgit v1.2.3 From 97404f2e0386ac147cec00fc5d89ea475b04bd78 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 14 Dec 2010 16:13:57 +0000 Subject: ASoC: Do DAPM control updates in the middle of DAPM sequences Attempt to minimise audible effects from mixer and mux updates by implementing the actual register changes between powering down widgets that have become unused and powering up widgets that are newly used. This means that we're making the change with the minimum set of widgets powered, that the input path is connected when we're powering up widgets (so things like DC offset correction can run with their signal active) and that we bring things down to cold before switching away. Since hardware tends to be designed for the power on/off case more than for dynamic reconfiguration this should minimise pops and clicks during reconfiguration while active. Signed-off-by: Mark Brown Acked-by: Peter Ujfalusi Tested-by: Peter Ujfalusi Acked-by: Liam Girdwood --- include/sound/soc-dapm.h | 10 ++++ sound/soc/soc-dapm.c | 130 ++++++++++++++++++++++++++--------------------- 2 files changed, 82 insertions(+), 58 deletions(-) diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h index 98783510d2f1..540872fc1390 100644 --- a/include/sound/soc-dapm.h +++ b/include/sound/soc-dapm.h @@ -460,6 +460,14 @@ struct snd_soc_dapm_widget { struct list_head power_list; }; +struct snd_soc_dapm_update { + struct snd_soc_dapm_widget *widget; + struct snd_kcontrol *kcontrol; + int reg; + int mask; + int val; +}; + /* DAPM context */ struct snd_soc_dapm_context { int n_widgets; /* number of widgets in this context */ @@ -468,6 +476,8 @@ struct snd_soc_dapm_context { struct delayed_work delayed_work; unsigned int idle_bias_off:1; /* Use BIAS_OFF instead of STANDBY */ + struct snd_soc_dapm_update *update; + struct device *dev; /* from parent - for debug */ struct snd_soc_codec *codec; /* parent codec */ struct snd_soc_card *card; /* parent card */ diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index f362d1de78f3..1debc3b05665 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -920,6 +920,41 @@ static void dapm_seq_run(struct snd_soc_dapm_context *dapm, dapm_seq_run_coalesced(dapm, &pending); } +static void dapm_widget_update(struct snd_soc_dapm_context *dapm) +{ + struct snd_soc_dapm_update *update = dapm->update; + struct snd_soc_dapm_widget *w; + int ret; + + if (!update) + return; + + w = update->widget; + + if (w->event && + (w->event_flags & SND_SOC_DAPM_PRE_REG)) { + ret = w->event(w, update->kcontrol, SND_SOC_DAPM_PRE_REG); + if (ret != 0) + pr_err("%s DAPM pre-event failed: %d\n", + w->name, ret); + } + + ret = snd_soc_update_bits(w->codec, update->reg, update->mask, + update->val); + if (ret < 0) + pr_err("%s DAPM update failed: %d\n", w->name, ret); + + if (w->event && + (w->event_flags & SND_SOC_DAPM_POST_REG)) { + ret = w->event(w, update->kcontrol, SND_SOC_DAPM_POST_REG); + if (ret != 0) + pr_err("%s DAPM post-event failed: %d\n", + w->name, ret); + } +} + + + /* * Scan each dapm widget for complete audio path. * A complete path is a route that has valid endpoints i.e.:- @@ -1037,6 +1072,8 @@ static int dapm_power_widgets(struct snd_soc_dapm_context *dapm, int event) /* Power down widgets first; try to avoid amplifying pops. */ dapm_seq_run(dapm, &down_list, event, dapm_down_seq); + dapm_widget_update(dapm); + /* Now power up. */ dapm_seq_run(dapm, &up_list, event, dapm_up_seq); @@ -1683,13 +1720,12 @@ int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol, (struct soc_mixer_control *)kcontrol->private_value; unsigned int reg = mc->reg; unsigned int shift = mc->shift; - unsigned int rshift = mc->rshift; int max = mc->max; unsigned int mask = (1 << fls(max)) - 1; unsigned int invert = mc->invert; - unsigned int val, val2, val_mask; - int connect; - int ret; + unsigned int val, val_mask; + int connect, change; + struct snd_soc_dapm_update update; val = (ucontrol->value.integer.value[0] & mask); @@ -1697,18 +1733,12 @@ int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol, val = max - val; val_mask = mask << shift; val = val << shift; - if (shift != rshift) { - val2 = (ucontrol->value.integer.value[1] & mask); - if (invert) - val2 = max - val2; - val_mask |= mask << rshift; - val |= val2 << rshift; - } mutex_lock(&widget->codec->mutex); widget->value = val; - if (snd_soc_test_bits(widget->codec, reg, val_mask, val)) { + change = snd_soc_test_bits(widget->codec, reg, val_mask, val); + if (change) { if (val) /* new connection */ connect = invert ? 0:1; @@ -1716,28 +1746,20 @@ int snd_soc_dapm_put_volsw(struct snd_kcontrol *kcontrol, /* old connection must be powered down */ connect = invert ? 1:0; + update.kcontrol = kcontrol; + update.widget = widget; + update.reg = reg; + update.mask = mask; + update.val = val; + widget->dapm->update = &update; + dapm_mixer_update_power(widget, kcontrol, connect); + + widget->dapm->update = NULL; } - if (widget->event) { - if (widget->event_flags & SND_SOC_DAPM_PRE_REG) { - ret = widget->event(widget, kcontrol, - SND_SOC_DAPM_PRE_REG); - if (ret < 0) { - ret = 1; - goto out; - } - } - ret = snd_soc_update_bits(widget->codec, reg, val_mask, val); - if (widget->event_flags & SND_SOC_DAPM_POST_REG) - ret = widget->event(widget, kcontrol, - SND_SOC_DAPM_POST_REG); - } else - ret = snd_soc_update_bits(widget->codec, reg, val_mask, val); - -out: mutex_unlock(&widget->codec->mutex); - return ret; + return 0; } EXPORT_SYMBOL_GPL(snd_soc_dapm_put_volsw); @@ -1785,7 +1807,7 @@ int snd_soc_dapm_put_enum_double(struct snd_kcontrol *kcontrol, struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; unsigned int val, mux, change; unsigned int mask, bitmask; - int ret = 0; + struct snd_soc_dapm_update update; for (bitmask = 1; bitmask < e->max; bitmask <<= 1) ; @@ -1804,24 +1826,20 @@ int snd_soc_dapm_put_enum_double(struct snd_kcontrol *kcontrol, mutex_lock(&widget->codec->mutex); widget->value = val; change = snd_soc_test_bits(widget->codec, e->reg, mask, val); - dapm_mux_update_power(widget, kcontrol, change, mux, e); - if (widget->event_flags & SND_SOC_DAPM_PRE_REG) { - ret = widget->event(widget, - kcontrol, SND_SOC_DAPM_PRE_REG); - if (ret < 0) - goto out; - } + update.kcontrol = kcontrol; + update.widget = widget; + update.reg = e->reg; + update.mask = mask; + update.val = val; + widget->dapm->update = &update; - ret = snd_soc_update_bits(widget->codec, e->reg, mask, val); + dapm_mux_update_power(widget, kcontrol, change, mux, e); - if (widget->event_flags & SND_SOC_DAPM_POST_REG) - ret = widget->event(widget, - kcontrol, SND_SOC_DAPM_POST_REG); + widget->dapm->update = NULL; -out: mutex_unlock(&widget->codec->mutex); - return ret; + return change; } EXPORT_SYMBOL_GPL(snd_soc_dapm_put_enum_double); @@ -1933,7 +1951,7 @@ int snd_soc_dapm_put_value_enum_double(struct snd_kcontrol *kcontrol, struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; unsigned int val, mux, change; unsigned int mask; - int ret = 0; + struct snd_soc_dapm_update update; if (ucontrol->value.enumerated.item[0] > e->max - 1) return -EINVAL; @@ -1950,24 +1968,20 @@ int snd_soc_dapm_put_value_enum_double(struct snd_kcontrol *kcontrol, mutex_lock(&widget->codec->mutex); widget->value = val; change = snd_soc_test_bits(widget->codec, e->reg, mask, val); - dapm_mux_update_power(widget, kcontrol, change, mux, e); - if (widget->event_flags & SND_SOC_DAPM_PRE_REG) { - ret = widget->event(widget, - kcontrol, SND_SOC_DAPM_PRE_REG); - if (ret < 0) - goto out; - } + update.kcontrol = kcontrol; + update.widget = widget; + update.reg = e->reg; + update.mask = mask; + update.val = val; + widget->dapm->update = &update; - ret = snd_soc_update_bits(widget->codec, e->reg, mask, val); + dapm_mux_update_power(widget, kcontrol, change, mux, e); - if (widget->event_flags & SND_SOC_DAPM_POST_REG) - ret = widget->event(widget, - kcontrol, SND_SOC_DAPM_POST_REG); + widget->dapm->update = NULL; -out: mutex_unlock(&widget->codec->mutex); - return ret; + return change; } EXPORT_SYMBOL_GPL(snd_soc_dapm_put_value_enum_double); -- cgit v1.2.3 From 9e261bbcba087b98b9d60a78e60845d5df488aa3 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Fri, 17 Dec 2010 12:52:56 +0900 Subject: ASoC: sh: fsi: move fsi_irq_enable function to fsi_dai_trigger Signed-off-by: Kuninori Morimoto Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/sh/fsi.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c index 97c5394aa7d7..9ab85936e65d 100644 --- a/sound/soc/sh/fsi.c +++ b/sound/soc/sh/fsi.c @@ -684,9 +684,6 @@ static int fsi_fifo_data_ctrl(struct fsi_priv *fsi, int startup, int stream) fsi_reg_write(fsi, DOFF_ST, 0) : fsi_reg_write(fsi, DIFF_ST, 0); - /* re-enable irq */ - fsi_irq_enable(fsi, is_play); - if (over_period) snd_pcm_period_elapsed(substream); @@ -859,6 +856,7 @@ static int fsi_dai_trigger(struct snd_pcm_substream *substream, int cmd, frames_to_bytes(runtime, runtime->buffer_size), frames_to_bytes(runtime, runtime->period_size)); ret = is_play ? fsi_data_push(fsi, 1) : fsi_data_pop(fsi, 1); + fsi_irq_enable(fsi, is_play); break; case SNDRV_PCM_TRIGGER_STOP: fsi_irq_disable(fsi, is_play); -- cgit v1.2.3 From 1ec9bc35a6a01555836fa1e4d0f00a3501835b0b Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Fri, 17 Dec 2010 12:55:22 +0900 Subject: ASoC: sh: fsi: Add over/under run counter Current FSI driver had printed under/over run error if status register have its error bit. But runtime print cause the next error because print out is slow. This patch add error counter and print error when sound stop Signed-off-by: Kuninori Morimoto Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/sh/fsi.c | 76 +++++++++++++++++++++++++++++++++++------------------- 1 file changed, 49 insertions(+), 27 deletions(-) diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c index 9ab85936e65d..2b06402801ef 100644 --- a/sound/soc/sh/fsi.c +++ b/sound/soc/sh/fsi.c @@ -134,6 +134,9 @@ struct fsi_stream { int buff_len; int period_len; int period_num; + + int uerr_num; + int oerr_num; }; struct fsi_priv { @@ -326,17 +329,29 @@ static void fsi_stream_push(struct fsi_priv *fsi, io->buff_offset = 0; io->period_len = period_len; io->period_num = 0; + io->oerr_num = -1; /* ignore 1st err */ + io->uerr_num = -1; /* ignore 1st err */ } static void fsi_stream_pop(struct fsi_priv *fsi, int is_play) { struct fsi_stream *io = fsi_get_stream(fsi, is_play); + struct snd_soc_dai *dai = fsi_get_dai(io->substream); + + + if (io->oerr_num > 0) + dev_err(dai->dev, "over_run = %d\n", io->oerr_num); + + if (io->uerr_num > 0) + dev_err(dai->dev, "under_run = %d\n", io->uerr_num); io->substream = NULL; io->buff_len = 0; io->buff_offset = 0; io->period_len = 0; io->period_num = 0; + io->oerr_num = 0; + io->uerr_num = 0; } static int fsi_get_fifo_data_num(struct fsi_priv *fsi, int is_play) @@ -375,6 +390,27 @@ static int fsi_get_frame_width(struct fsi_priv *fsi, int is_play) return frames_to_bytes(runtime, 1) / io->chan_num; } +static void fsi_count_fifo_err(struct fsi_priv *fsi) +{ + u32 ostatus = fsi_reg_read(fsi, DOFF_ST); + u32 istatus = fsi_reg_read(fsi, DIFF_ST); + + if (ostatus & ERR_OVER) + fsi->playback.oerr_num++; + + if (ostatus & ERR_UNDER) + fsi->playback.uerr_num++; + + if (istatus & ERR_OVER) + fsi->capture.oerr_num++; + + if (istatus & ERR_UNDER) + fsi->capture.uerr_num++; + + fsi_reg_write(fsi, DOFF_ST, 0); + fsi_reg_write(fsi, DIFF_ST, 0); +} + /* * dma function */ @@ -574,7 +610,7 @@ static void fsi_soft_all_reset(struct fsi_master *master) mdelay(10); } -static int fsi_fifo_data_ctrl(struct fsi_priv *fsi, int startup, int stream) +static int fsi_fifo_data_ctrl(struct fsi_priv *fsi, int stream) { struct snd_pcm_runtime *runtime; struct snd_pcm_substream *substream = NULL; @@ -667,37 +703,20 @@ static int fsi_fifo_data_ctrl(struct fsi_priv *fsi, int startup, int stream) /* update buff_offset */ io->buff_offset += fsi_num2offset(data_num, ch_width); - /* check fifo status */ - if (!startup) { - struct snd_soc_dai *dai = fsi_get_dai(substream); - u32 status = is_play ? - fsi_reg_read(fsi, DOFF_ST) : - fsi_reg_read(fsi, DIFF_ST); - - if (status & ERR_OVER) - dev_err(dai->dev, "over run\n"); - if (status & ERR_UNDER) - dev_err(dai->dev, "under run\n"); - } - - is_play ? - fsi_reg_write(fsi, DOFF_ST, 0) : - fsi_reg_write(fsi, DIFF_ST, 0); - if (over_period) snd_pcm_period_elapsed(substream); return 0; } -static int fsi_data_pop(struct fsi_priv *fsi, int startup) +static int fsi_data_pop(struct fsi_priv *fsi) { - return fsi_fifo_data_ctrl(fsi, startup, SNDRV_PCM_STREAM_CAPTURE); + return fsi_fifo_data_ctrl(fsi, SNDRV_PCM_STREAM_CAPTURE); } -static int fsi_data_push(struct fsi_priv *fsi, int startup) +static int fsi_data_push(struct fsi_priv *fsi) { - return fsi_fifo_data_ctrl(fsi, startup, SNDRV_PCM_STREAM_PLAYBACK); + return fsi_fifo_data_ctrl(fsi, SNDRV_PCM_STREAM_PLAYBACK); } static irqreturn_t fsi_interrupt(int irq, void *data) @@ -710,13 +729,16 @@ static irqreturn_t fsi_interrupt(int irq, void *data) fsi_master_mask_set(master, SOFT_RST, IR, IR); if (int_st & AB_IO(1, AO_SHIFT)) - fsi_data_push(&master->fsia, 0); + fsi_data_push(&master->fsia); if (int_st & AB_IO(1, BO_SHIFT)) - fsi_data_push(&master->fsib, 0); + fsi_data_push(&master->fsib); if (int_st & AB_IO(1, AI_SHIFT)) - fsi_data_pop(&master->fsia, 0); + fsi_data_pop(&master->fsia); if (int_st & AB_IO(1, BI_SHIFT)) - fsi_data_pop(&master->fsib, 0); + fsi_data_pop(&master->fsib); + + fsi_count_fifo_err(&master->fsia); + fsi_count_fifo_err(&master->fsib); fsi_irq_clear_status(&master->fsia); fsi_irq_clear_status(&master->fsib); @@ -855,7 +877,7 @@ static int fsi_dai_trigger(struct snd_pcm_substream *substream, int cmd, fsi_stream_push(fsi, is_play, substream, frames_to_bytes(runtime, runtime->buffer_size), frames_to_bytes(runtime, runtime->period_size)); - ret = is_play ? fsi_data_push(fsi, 1) : fsi_data_pop(fsi, 1); + ret = is_play ? fsi_data_push(fsi) : fsi_data_pop(fsi); fsi_irq_enable(fsi, is_play); break; case SNDRV_PCM_TRIGGER_STOP: -- cgit v1.2.3 From a8901d34872dafcafa23efa0865dcecfd4fddf8c Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Fri, 17 Dec 2010 10:40:47 -0500 Subject: ext4: Use pr_warning_ratelimited() instead of printk_ratelimit() printk_ratelimit() is deprecated since it is a global instead of a per-printk ratelimit. Signed-off-by: "Theodore Ts'o" --- fs/ext4/inode.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index db3cc913ee8f..c0fe426d444a 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -40,6 +40,7 @@ #include #include #include +#include #include "ext4_jbd2.h" #include "xattr.h" @@ -3729,8 +3730,7 @@ static int ext4_set_bh_endio(struct buffer_head *bh, struct inode *inode) retry: io_end = ext4_init_io_end(inode, GFP_ATOMIC); if (!io_end) { - if (printk_ratelimit()) - printk(KERN_WARNING "%s: allocation fail\n", __func__); + pr_warning_ratelimited("%s: allocation fail\n", __func__); schedule(); goto retry; } -- cgit v1.2.3 From 670be5a78ac7c80f0d6009d648c84c65a03f373a Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Fri, 17 Dec 2010 10:44:16 -0500 Subject: jbd2: Use pr_notice_ratelimited() in journal_alloc_journal_head() We had an open-coded version of printk_ratelimited(); use the provided abstraction to make the code cleaner and easier to understand. Based on a similar patch for fs/jbd from Namhyung Kim Signed-off-by: "Theodore Ts'o" --- fs/jbd2/journal.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c index f837ba953529..06dfd778cae5 100644 --- a/fs/jbd2/journal.c +++ b/fs/jbd2/journal.c @@ -43,6 +43,7 @@ #include #include #include +#include #define CREATE_TRACE_POINTS #include @@ -1982,7 +1983,6 @@ static void jbd2_journal_destroy_jbd2_journal_head_cache(void) static struct journal_head *journal_alloc_journal_head(void) { struct journal_head *ret; - static unsigned long last_warning; #ifdef CONFIG_JBD2_DEBUG atomic_inc(&nr_journal_heads); @@ -1990,11 +1990,7 @@ static struct journal_head *journal_alloc_journal_head(void) ret = kmem_cache_alloc(jbd2_journal_head_cache, GFP_NOFS); if (!ret) { jbd_debug(1, "out of memory for journal_head\n"); - if (time_after(jiffies, last_warning + 5*HZ)) { - printk(KERN_NOTICE "ENOMEM in %s, retrying.\n", - __func__); - last_warning = jiffies; - } + pr_notice_ratelimited("ENOMEM in %s, retrying.\n", __func__); while (!ret) { yield(); ret = kmem_cache_alloc(jbd2_journal_head_cache, GFP_NOFS); -- cgit v1.2.3 From 24ff33ac696802e478714480f505c00a50a89c75 Mon Sep 17 00:00:00 2001 From: Dimitris Papastamos Date: Thu, 16 Dec 2010 15:53:39 +0000 Subject: ASoC: soc-dapm: Introduce the new snd_soc_dapm_virt_mux type This new type is a virtual version of snd_soc_dapm_mux. It is used when a backing register value is not necessary for deciding which input path to connect. A simple virtual enumeration control e.g. SOC_DAPM_ENUM_VIRT() can be exposed to userspace which will be used to choose which path to connect. The snd_soc_dapm_virt_mux type ensures that during the initial path setup, the first (which is also the default) input path will be connected. Signed-off-by: Dimitris Papastamos Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- include/sound/soc-dapm.h | 9 +++++++++ sound/soc/soc-dapm.c | 19 +++++++++++++++++++ 2 files changed, 28 insertions(+) diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h index 540872fc1390..8031769ac485 100644 --- a/include/sound/soc-dapm.h +++ b/include/sound/soc-dapm.h @@ -93,6 +93,9 @@ #define SND_SOC_DAPM_MUX(wname, wreg, wshift, winvert, wcontrols) \ { .id = snd_soc_dapm_mux, .name = wname, .reg = wreg, .shift = wshift, \ .invert = winvert, .kcontrols = wcontrols, .num_kcontrols = 1} +#define SND_SOC_DAPM_VIRT_MUX(wname, wreg, wshift, winvert, wcontrols) \ +{ .id = snd_soc_dapm_virt_mux, .name = wname, .reg = wreg, .shift = wshift, \ + .invert = winvert, .kcontrols = wcontrols, .num_kcontrols = 1} #define SND_SOC_DAPM_VALUE_MUX(wname, wreg, wshift, winvert, wcontrols) \ { .id = snd_soc_dapm_value_mux, .name = wname, .reg = wreg, \ .shift = wshift, .invert = winvert, .kcontrols = wcontrols, \ @@ -148,6 +151,11 @@ { .id = snd_soc_dapm_mux, .name = wname, .reg = wreg, .shift = wshift, \ .invert = winvert, .kcontrols = wcontrols, .num_kcontrols = 1, \ .event = wevent, .event_flags = wflags} +#define SND_SOC_DAPM_VIRT_MUX_E(wname, wreg, wshift, winvert, wcontrols, \ + wevent, wflags) \ +{ .id = snd_soc_dapm_virt_mux, .name = wname, .reg = wreg, .shift = wshift, \ + .invert = winvert, .kcontrols = wcontrols, .num_kcontrols = 1, \ + .event = wevent, .event_flags = wflags} /* Simplified versions of above macros, assuming wncontrols = ARRAY_SIZE(wcontrols) */ #define SOC_PGA_E_ARRAY(wname, wreg, wshift, winvert, wcontrols, \ @@ -357,6 +365,7 @@ enum snd_soc_dapm_type { snd_soc_dapm_input = 0, /* input pin */ snd_soc_dapm_output, /* output pin */ snd_soc_dapm_mux, /* selects 1 analog signal from many inputs */ + snd_soc_dapm_virt_mux, /* virtual version of snd_soc_dapm_mux */ snd_soc_dapm_value_mux, /* selects 1 analog signal from many inputs */ snd_soc_dapm_mixer, /* mixes several analog signals together */ snd_soc_dapm_mixer_named_ctl, /* mixer with named controls */ diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c index 1debc3b05665..50f5c785cb61 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -56,6 +56,7 @@ static int dapm_up_seq[] = { [snd_soc_dapm_aif_out] = 3, [snd_soc_dapm_mic] = 4, [snd_soc_dapm_mux] = 5, + [snd_soc_dapm_virt_mux] = 5, [snd_soc_dapm_value_mux] = 5, [snd_soc_dapm_dac] = 6, [snd_soc_dapm_mixer] = 7, @@ -81,6 +82,7 @@ static int dapm_down_seq[] = { [snd_soc_dapm_mic] = 7, [snd_soc_dapm_micbias] = 8, [snd_soc_dapm_mux] = 9, + [snd_soc_dapm_virt_mux] = 9, [snd_soc_dapm_value_mux] = 9, [snd_soc_dapm_aif_in] = 10, [snd_soc_dapm_aif_out] = 10, @@ -216,6 +218,20 @@ static void dapm_set_path_status(struct snd_soc_dapm_widget *w, } } break; + case snd_soc_dapm_virt_mux: { + struct soc_enum *e = (struct soc_enum *)w->kcontrols[i].private_value; + + p->connect = 0; + /* since a virtual mux has no backing registers to + * decide which path to connect, it will try to match + * with the first enumeration. This is to ensure + * that the default mux choice (the first) will be + * correctly powered up during initialization. + */ + if (!strcmp(p->name, e->texts[0])) + p->connect = 1; + } + break; case snd_soc_dapm_value_mux: { struct soc_enum *e = (struct soc_enum *) w->kcontrols[i].private_value; @@ -1228,6 +1244,7 @@ static int dapm_mux_update_power(struct snd_soc_dapm_widget *widget, int found = 0; if (widget->id != snd_soc_dapm_mux && + widget->id != snd_soc_dapm_virt_mux && widget->id != snd_soc_dapm_value_mux) return -ENODEV; @@ -1534,6 +1551,7 @@ static int snd_soc_dapm_add_route(struct snd_soc_dapm_context *dapm, path->connect = 1; return 0; case snd_soc_dapm_mux: + case snd_soc_dapm_virt_mux: case snd_soc_dapm_value_mux: ret = dapm_connect_mux(dapm, wsource, wsink, path, control, &wsink->kcontrols[0]); @@ -1623,6 +1641,7 @@ int snd_soc_dapm_new_widgets(struct snd_soc_dapm_context *dapm) dapm_new_mixer(dapm, w); break; case snd_soc_dapm_mux: + case snd_soc_dapm_virt_mux: case snd_soc_dapm_value_mux: w->power_check = dapm_generic_check_power; dapm_new_mux(dapm, w); -- cgit v1.2.3 From 6e5f15c93dc745d46c2bb9e4597b44463203844b Mon Sep 17 00:00:00 2001 From: "J. Bruce Fields" Date: Wed, 24 Nov 2010 17:17:34 -0500 Subject: nfsd4: replace unintuitive match_clientid_establishment Reviewed-by: Benny Halevy Signed-off-by: J. Bruce Fields --- fs/nfsd/nfs4state.c | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 4d542cfd6960..0c61cc1eadca 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -1135,19 +1135,13 @@ find_unconfirmed_client(clientid_t *clid) } /* - * Return 1 iff clp's clientid establishment method matches the use_exchange_id - * parameter. Matching is based on the fact the at least one of the - * EXCHGID4_FLAG_USE_{NON_PNFS,PNFS_MDS,PNFS_DS} flags must be set for v4.1 - * * FIXME: we need to unify the clientid namespaces for nfsv4.x * and correctly deal with client upgrade/downgrade in EXCHANGE_ID * and SET_CLIENTID{,_CONFIRM} */ -static inline int -match_clientid_establishment(struct nfs4_client *clp, bool use_exchange_id) +static bool clp_used_exchangeid(struct nfs4_client *clp) { - bool has_exchange_flags = (clp->cl_exchange_flags != 0); - return use_exchange_id == has_exchange_flags; + return clp->cl_exchange_flags != 0; } static struct nfs4_client * @@ -1158,7 +1152,7 @@ find_confirmed_client_by_str(const char *dname, unsigned int hashval, list_for_each_entry(clp, &conf_str_hashtbl[hashval], cl_strhash) { if (same_name(clp->cl_recdir, dname) && - match_clientid_establishment(clp, use_exchange_id)) + clp_used_exchangeid(clp) == use_exchange_id) return clp; } return NULL; @@ -1172,7 +1166,7 @@ find_unconfirmed_client_by_str(const char *dname, unsigned int hashval, list_for_each_entry(clp, &unconf_str_hashtbl[hashval], cl_strhash) { if (same_name(clp->cl_recdir, dname) && - match_clientid_establishment(clp, use_exchange_id)) + clp_used_exchangeid(clp) == use_exchange_id) return clp; } return NULL; -- cgit v1.2.3 From e203d506bd221bfa5b3acbb7336ae7b7646636a4 Mon Sep 17 00:00:00 2001 From: "J. Bruce Fields" Date: Wed, 24 Nov 2010 17:30:54 -0500 Subject: nfsd4: fix mixed 4.0/4.1 handling, 4.1 reboot Instead of failing to find client entries which don't match the minorversion, we should be finding them, then either erroring out or expiring them as appropriate. This also fixes a problem which would cause the 4.1 server to fail to recognize clients after a second reboot. Reported-by: Casey Bodley Reviewed-by: Benny Halevy Signed-off-by: J. Bruce Fields --- fs/nfsd/nfs4recover.c | 1 - fs/nfsd/nfs4state.c | 37 +++++++++++++++++-------------------- 2 files changed, 17 insertions(+), 21 deletions(-) diff --git a/fs/nfsd/nfs4recover.c b/fs/nfsd/nfs4recover.c index 7e26caab2a26..ffb59ef6f82f 100644 --- a/fs/nfsd/nfs4recover.c +++ b/fs/nfsd/nfs4recover.c @@ -302,7 +302,6 @@ purge_old(struct dentry *parent, struct dentry *child) { int status; - /* note: we currently use this path only for minorversion 0 */ if (nfs4_has_reclaimed_state(child->d_name.name, false)) return 0; diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 0c61cc1eadca..73adcfb2dc17 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c @@ -1134,39 +1134,30 @@ find_unconfirmed_client(clientid_t *clid) return NULL; } -/* - * FIXME: we need to unify the clientid namespaces for nfsv4.x - * and correctly deal with client upgrade/downgrade in EXCHANGE_ID - * and SET_CLIENTID{,_CONFIRM} - */ static bool clp_used_exchangeid(struct nfs4_client *clp) { return clp->cl_exchange_flags != 0; -} +} static struct nfs4_client * -find_confirmed_client_by_str(const char *dname, unsigned int hashval, - bool use_exchange_id) +find_confirmed_client_by_str(const char *dname, unsigned int hashval) { struct nfs4_client *clp; list_for_each_entry(clp, &conf_str_hashtbl[hashval], cl_strhash) { - if (same_name(clp->cl_recdir, dname) && - clp_used_exchangeid(clp) == use_exchange_id) + if (same_name(clp->cl_recdir, dname)) return clp; } return NULL; } static struct nfs4_client * -find_unconfirmed_client_by_str(const char *dname, unsigned int hashval, - bool use_exchange_id) +find_unconfirmed_client_by_str(const char *dname, unsigned int hashval) { struct nfs4_client *clp; list_for_each_entry(clp, &unconf_str_hashtbl[hashval], cl_strhash) { - if (same_name(clp->cl_recdir, dname) && - clp_used_exchangeid(clp) == use_exchange_id) + if (same_name(clp->cl_recdir, dname)) return clp; } return NULL; @@ -1357,8 +1348,12 @@ nfsd4_exchange_id(struct svc_rqst *rqstp, nfs4_lock_state(); status = nfs_ok; - conf = find_confirmed_client_by_str(dname, strhashval, true); + conf = find_confirmed_client_by_str(dname, strhashval); if (conf) { + if (!clp_used_exchangeid(conf)) { + status = nfserr_clid_inuse; /* XXX: ? */ + goto out; + } if (!same_verf(&verf, &conf->cl_verifier)) { /* 18.35.4 case 8 */ if (exid->flags & EXCHGID4_FLAG_UPD_CONFIRMED_REC_A) { @@ -1399,7 +1394,7 @@ nfsd4_exchange_id(struct svc_rqst *rqstp, goto out; } - unconf = find_unconfirmed_client_by_str(dname, strhashval, true); + unconf = find_unconfirmed_client_by_str(dname, strhashval); if (unconf) { /* * Possible retry or client restart. Per 18.35.4 case 4, @@ -1799,10 +1794,12 @@ nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, strhashval = clientstr_hashval(dname); nfs4_lock_state(); - conf = find_confirmed_client_by_str(dname, strhashval, false); + conf = find_confirmed_client_by_str(dname, strhashval); if (conf) { /* RFC 3530 14.2.33 CASE 0: */ status = nfserr_clid_inuse; + if (clp_used_exchangeid(conf)) + goto out; if (!same_creds(&conf->cl_cred, &rqstp->rq_cred)) { char addr_str[INET6_ADDRSTRLEN]; rpc_ntop((struct sockaddr *) &conf->cl_addr, addr_str, @@ -1817,7 +1814,7 @@ nfsd4_setclientid(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, * has a description of SETCLIENTID request processing consisting * of 5 bullet points, labeled as CASE0 - CASE4 below. */ - unconf = find_unconfirmed_client_by_str(dname, strhashval, false); + unconf = find_unconfirmed_client_by_str(dname, strhashval); status = nfserr_resource; if (!conf) { /* @@ -1962,7 +1959,7 @@ nfsd4_setclientid_confirm(struct svc_rqst *rqstp, unsigned int hash = clientstr_hashval(unconf->cl_recdir); conf = find_confirmed_client_by_str(unconf->cl_recdir, - hash, false); + hash); if (conf) { nfsd4_remove_clid_dir(conf); expire_client(conf); @@ -4106,7 +4103,7 @@ nfs4_has_reclaimed_state(const char *name, bool use_exchange_id) unsigned int strhashval = clientstr_hashval(name); struct nfs4_client *clp; - clp = find_confirmed_client_by_str(name, strhashval, use_exchange_id); + clp = find_confirmed_client_by_str(name, strhashval); return clp ? 1 : 0; } -- cgit v1.2.3 From 18b631f83810e95eeb2e1839889b27142bd8d6d8 Mon Sep 17 00:00:00 2001 From: "J. Bruce Fields" Date: Mon, 29 Nov 2010 15:28:10 -0500 Subject: nfsd: fix offset printk's in nfsd3 read/write Thanks to dysbr01@ca.com for noticing that the debugging printk in the v3 write procedure can print >2GB offsets as negative numbers: https://bugzilla.kernel.org/show_bug.cgi?id=23342 Signed-off-by: J. Bruce Fields --- fs/nfsd/nfs3proc.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/fs/nfsd/nfs3proc.c b/fs/nfsd/nfs3proc.c index 5b7e3021e06b..2247fc91d5e9 100644 --- a/fs/nfsd/nfs3proc.c +++ b/fs/nfsd/nfs3proc.c @@ -151,10 +151,10 @@ nfsd3_proc_read(struct svc_rqst *rqstp, struct nfsd3_readargs *argp, __be32 nfserr; u32 max_blocksize = svc_max_payload(rqstp); - dprintk("nfsd: READ(3) %s %lu bytes at %lu\n", + dprintk("nfsd: READ(3) %s %lu bytes at %Lu\n", SVCFH_fmt(&argp->fh), (unsigned long) argp->count, - (unsigned long) argp->offset); + (unsigned long long) argp->offset); /* Obtain buffer pointer for payload. * 1 (status) + 22 (post_op_attr) + 1 (count) + 1 (eof) @@ -191,10 +191,10 @@ nfsd3_proc_write(struct svc_rqst *rqstp, struct nfsd3_writeargs *argp, __be32 nfserr; unsigned long cnt = argp->len; - dprintk("nfsd: WRITE(3) %s %d bytes at %ld%s\n", + dprintk("nfsd: WRITE(3) %s %d bytes at %Lu%s\n", SVCFH_fmt(&argp->fh), argp->len, - (unsigned long) argp->offset, + (unsigned long long) argp->offset, argp->stable? " stable" : ""); fh_copy(&resp->fh, &argp->fh); -- cgit v1.2.3 From 7c96aef75949a56ec427fc6a2522dace2af33605 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Mon, 15 Nov 2010 11:27:01 +1100 Subject: sunrpc: remove xpt_pool The xpt_pool field is only used for reporting BUGs. And it isn't used correctly. In particular, when it is cleared in svc_xprt_received before XPT_BUSY is cleared, there is no guarantee that either the compiler or the CPU might not re-order to two assignments, just setting xpt_pool to NULL after XPT_BUSY is cleared. If a different cpu were running svc_xprt_enqueue at this moment, it might see XPT_BUSY clear and then xpt_pool non-NULL, and so BUG. This could be fixed by calling smp_mb__before_clear_bit() before the clear_bit. However as xpt_pool isn't really used, it seems safest to simply remove xpt_pool. Another alternate would be to change the clear_bit to clear_bit_unlock, and the test_and_set_bit to test_and_set_bit_lock. Signed-off-by: NeilBrown Signed-off-by: J. Bruce Fields --- include/linux/sunrpc/svc_xprt.h | 1 - net/sunrpc/svc_xprt.c | 5 ----- 2 files changed, 6 deletions(-) diff --git a/include/linux/sunrpc/svc_xprt.h b/include/linux/sunrpc/svc_xprt.h index aea0d438e3c7..c8f81da15c7e 100644 --- a/include/linux/sunrpc/svc_xprt.h +++ b/include/linux/sunrpc/svc_xprt.h @@ -63,7 +63,6 @@ struct svc_xprt { #define XPT_LISTENER 11 /* listening endpoint */ #define XPT_CACHE_AUTH 12 /* cache auth info */ - struct svc_pool *xpt_pool; /* current pool iff queued */ struct svc_serv *xpt_server; /* service for transport */ atomic_t xpt_reserved; /* space on outq that is rsvd */ struct mutex xpt_mutex; /* to serialize sending data */ diff --git a/net/sunrpc/svc_xprt.c b/net/sunrpc/svc_xprt.c index 5a75d23645c8..5eae53b1e306 100644 --- a/net/sunrpc/svc_xprt.c +++ b/net/sunrpc/svc_xprt.c @@ -351,8 +351,6 @@ void svc_xprt_enqueue(struct svc_xprt *xprt) dprintk("svc: transport %p busy, not enqueued\n", xprt); goto out_unlock; } - BUG_ON(xprt->xpt_pool != NULL); - xprt->xpt_pool = pool; if (!list_empty(&pool->sp_threads)) { rqstp = list_entry(pool->sp_threads.next, @@ -370,13 +368,11 @@ void svc_xprt_enqueue(struct svc_xprt *xprt) rqstp->rq_reserved = serv->sv_max_mesg; atomic_add(rqstp->rq_reserved, &xprt->xpt_reserved); pool->sp_stats.threads_woken++; - BUG_ON(xprt->xpt_pool != pool); wake_up(&rqstp->rq_wait); } else { dprintk("svc: transport %p put into queue\n", xprt); list_add_tail(&xprt->xpt_ready, &pool->sp_sockets); pool->sp_stats.sockets_queued++; - BUG_ON(xprt->xpt_pool != pool); } out_unlock: @@ -415,7 +411,6 @@ static struct svc_xprt *svc_xprt_dequeue(struct svc_pool *pool) void svc_xprt_received(struct svc_xprt *xprt) { BUG_ON(!test_bit(XPT_BUSY, &xprt->xpt_flags)); - xprt->xpt_pool = NULL; /* As soon as we clear busy, the xprt could be closed and * 'put', so we need a reference to call svc_xprt_enqueue with: */ -- cgit v1.2.3 From 3942302ea9e1dffa933021b20bf1642046e7641b Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Mon, 15 Nov 2010 11:27:01 +1100 Subject: sunrpc: svc_sock_names should hold ref to socket being closed. Currently svc_sock_names calls svc_close_xprt on a svc_sock to which it does not own a reference. As soon as svc_close_xprt sets XPT_CLOSE, the socket could be freed by a separate thread (though this is a very unlikely race). It is safer to hold a reference while calling svc_close_xprt. Signed-off-by: NeilBrown Signed-off-by: J. Bruce Fields --- net/sunrpc/svcsock.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c index 07919e16be3e..52bd1130e83a 100644 --- a/net/sunrpc/svcsock.c +++ b/net/sunrpc/svcsock.c @@ -324,19 +324,21 @@ int svc_sock_names(struct svc_serv *serv, char *buf, const size_t buflen, len = onelen; break; } - if (toclose && strcmp(toclose, buf + len) == 0) + if (toclose && strcmp(toclose, buf + len) == 0) { closesk = svsk; - else + svc_xprt_get(&closesk->sk_xprt); + } else len += onelen; } spin_unlock_bh(&serv->sv_lock); - if (closesk) + if (closesk) { /* Should unregister with portmap, but you cannot * unregister just one protocol... */ svc_close_xprt(&closesk->sk_xprt); - else if (toclose) + svc_xprt_put(&closesk->sk_xprt); + } else if (toclose) return -ENOENT; return len; } -- cgit v1.2.3 From 5b6a599f0da3722dea9ecc01d97f54061662ce49 Mon Sep 17 00:00:00 2001 From: "bookjovi@gmail.com" Date: Sat, 11 Dec 2010 00:21:17 -0500 Subject: nfs: add missed CONFIG_NFSD_DEPRECATED these pieces of code only make sense when CONFIG_NFSD_DEPRECATED enabled Signed-off-by: Jovi Zhang fs/nfsd/nfsctl.c | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) Signed-off-by: J. Bruce Fields --- fs/nfsd/nfsctl.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c index 4514ebbee4d6..6840ec3ceecf 100644 --- a/fs/nfsd/nfsctl.c +++ b/fs/nfsd/nfsctl.c @@ -127,6 +127,7 @@ static ssize_t nfsctl_transaction_write(struct file *file, const char __user *bu static ssize_t nfsctl_transaction_read(struct file *file, char __user *buf, size_t size, loff_t *pos) { +#ifdef CONFIG_NFSD_DEPRECATED static int warned; if (file->f_dentry->d_name.name[0] == '.' && !warned) { printk(KERN_INFO @@ -135,6 +136,7 @@ static ssize_t nfsctl_transaction_read(struct file *file, char __user *buf, size current->comm, file->f_dentry->d_name.name); warned = 1; } +#endif if (! file->private_data) { /* An attempt to read a transaction file without writing * causes a 0-byte write so that the file can return -- cgit v1.2.3 From 66c941f4aa8aef397a757001af61073db23b39e5 Mon Sep 17 00:00:00 2001 From: Shan Wei Date: Wed, 15 Dec 2010 14:47:20 +0800 Subject: net: sunrpc: kill unused macros These macros never be used for several years. Signed-off-by: Shan Wei Signed-off-by: J. Bruce Fields --- net/sunrpc/auth_gss/svcauth_gss.c | 2 -- net/sunrpc/svcauth.c | 1 - net/sunrpc/svcauth_unix.c | 2 -- 3 files changed, 5 deletions(-) diff --git a/net/sunrpc/auth_gss/svcauth_gss.c b/net/sunrpc/auth_gss/svcauth_gss.c index dec2a6fc7c12..bcdae78fdfc6 100644 --- a/net/sunrpc/auth_gss/svcauth_gss.c +++ b/net/sunrpc/auth_gss/svcauth_gss.c @@ -67,7 +67,6 @@ static int netobj_equal(struct xdr_netobj *a, struct xdr_netobj *b) #define RSI_HASHBITS 6 #define RSI_HASHMAX (1< Date: Sun, 14 Nov 2010 18:08:11 -0800 Subject: net/sunrpc/auth_gss/gss_krb5_crypto.c: Use normal negative error value return And remove unnecessary double semicolon too. No effect to code, as test is != 0. Signed-off-by: Joe Perches Signed-off-by: J. Bruce Fields --- net/sunrpc/auth_gss/gss_krb5_crypto.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/sunrpc/auth_gss/gss_krb5_crypto.c b/net/sunrpc/auth_gss/gss_krb5_crypto.c index 75ee993ea057..9576f35ab701 100644 --- a/net/sunrpc/auth_gss/gss_krb5_crypto.c +++ b/net/sunrpc/auth_gss/gss_krb5_crypto.c @@ -137,7 +137,7 @@ arcfour_hmac_md5_usage_to_salt(unsigned int usage, u8 salt[4]) ms_usage = 13; break; default: - return EINVAL;; + return -EINVAL; } salt[0] = (ms_usage >> 0) & 0xff; salt[1] = (ms_usage >> 8) & 0xff; -- cgit v1.2.3 From 56560b9ae0c2d07bb5bbcec16f799d7bf756d3de Mon Sep 17 00:00:00 2001 From: "J. Bruce Fields" Date: Thu, 16 Dec 2010 09:57:15 -0500 Subject: nfsd4: 4.1 SECINFO should consume filehandle See the referenced spec language; an attempt by a 4.1 client to use the current filehandle after a secinfo call should result in a NOFILEHANDLE error. Signed-off-by: J. Bruce Fields --- fs/nfsd/nfs4proc.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index 0cdfd022bb7b..bad4bf8e4bbc 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c @@ -769,6 +769,9 @@ nfsd4_secinfo(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, } else secinfo->si_exp = exp; dput(dentry); + if (cstate->minorversion) + /* See rfc 5661 section 2.6.3.1.1.8 */ + fh_put(&cstate->current_fh); return err; } -- cgit v1.2.3 From 0ff7ab46719a9c1e264b8d8e85416d59737ff13c Mon Sep 17 00:00:00 2001 From: "J. Bruce Fields" Date: Thu, 16 Dec 2010 10:06:27 -0500 Subject: nfsd4: move guts of nfsd4_lookupp into helper We'll reuse this code in secinfo_no_name. Signed-off-by: J. Bruce Fields --- fs/nfsd/nfs4proc.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index bad4bf8e4bbc..095431a35722 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c @@ -604,9 +604,7 @@ nfsd4_link(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, return status; } -static __be32 -nfsd4_lookupp(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, - void *arg) +static __be32 nfsd4_do_lookupp(struct svc_rqst *rqstp, struct svc_fh *fh) { struct svc_fh tmp_fh; __be32 ret; @@ -615,13 +613,19 @@ nfsd4_lookupp(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, ret = exp_pseudoroot(rqstp, &tmp_fh); if (ret) return ret; - if (tmp_fh.fh_dentry == cstate->current_fh.fh_dentry) { + if (tmp_fh.fh_dentry == fh->fh_dentry) { fh_put(&tmp_fh); return nfserr_noent; } fh_put(&tmp_fh); - return nfsd_lookup(rqstp, &cstate->current_fh, - "..", 2, &cstate->current_fh); + return nfsd_lookup(rqstp, fh, "..", 2, fh); +} + +static __be32 +nfsd4_lookupp(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, + void *arg) +{ + return nfsd4_do_lookupp(rqstp, &cstate->current_fh); } static __be32 -- cgit v1.2.3 From 04f4ad16b231abbfde34c762697ad035a3af0b5f Mon Sep 17 00:00:00 2001 From: "J. Bruce Fields" Date: Thu, 16 Dec 2010 09:51:13 -0500 Subject: nfsd4: implement secinfo_no_name Implementation of this operation is mandatory for NFSv4.1. Signed-off-by: J. Bruce Fields --- fs/nfsd/nfs4proc.c | 27 +++++++++++++++++++++++++++ fs/nfsd/nfs4xdr.c | 15 +++++++++++++-- fs/nfsd/xdr4.h | 5 +++++ include/linux/nfs4.h | 3 +++ 4 files changed, 48 insertions(+), 2 deletions(-) diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index 095431a35722..f80c3997d24c 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c @@ -779,6 +779,29 @@ nfsd4_secinfo(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, return err; } +static __be32 +nfsd4_secinfo_no_name(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, + struct nfsd4_secinfo_no_name *sin) +{ + __be32 err; + + switch (sin->sin_style) { + case NFS4_SECINFO_STYLE4_CURRENT_FH: + break; + case NFS4_SECINFO_STYLE4_PARENT: + err = nfsd4_do_lookupp(rqstp, &cstate->current_fh); + if (err) + return err; + break; + default: + return nfserr_inval; + } + exp_get(cstate->current_fh.fh_export); + sin->sin_exp = cstate->current_fh.fh_export; + fh_put(&cstate->current_fh); + return nfs_ok; +} + static __be32 nfsd4_setattr(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, struct nfsd4_setattr *setattr) @@ -1327,6 +1350,10 @@ static struct nfsd4_operation nfsd4_ops[] = { .op_flags = ALLOWED_WITHOUT_FH, .op_name = "OP_RECLAIM_COMPLETE", }, + [OP_SECINFO_NO_NAME] = { + .op_func = (nfsd4op_func)nfsd4_secinfo_no_name, + .op_name = "OP_SECINFO_NO_NAME", + }, }; static const char *nfsd4_op_name(unsigned opnum) diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index 71d7d339e44a..b543b2410b54 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -846,6 +846,17 @@ nfsd4_decode_secinfo(struct nfsd4_compoundargs *argp, DECODE_TAIL; } +static __be32 +nfsd4_decode_secinfo_no_name(struct nfsd4_compoundargs *argp, + struct nfsd4_secinfo_no_name *sin) +{ + DECODE_HEAD; + + READ_BUF(4); + READ32(sin->sin_style); + DECODE_TAIL; +} + static __be32 nfsd4_decode_setattr(struct nfsd4_compoundargs *argp, struct nfsd4_setattr *setattr) { @@ -1358,7 +1369,7 @@ static nfsd4_dec nfsd41_dec_ops[] = { [OP_LAYOUTCOMMIT] = (nfsd4_dec)nfsd4_decode_notsupp, [OP_LAYOUTGET] = (nfsd4_dec)nfsd4_decode_notsupp, [OP_LAYOUTRETURN] = (nfsd4_dec)nfsd4_decode_notsupp, - [OP_SECINFO_NO_NAME] = (nfsd4_dec)nfsd4_decode_notsupp, + [OP_SECINFO_NO_NAME] = (nfsd4_dec)nfsd4_decode_secinfo_no_name, [OP_SEQUENCE] = (nfsd4_dec)nfsd4_decode_sequence, [OP_SET_SSV] = (nfsd4_dec)nfsd4_decode_notsupp, [OP_TEST_STATEID] = (nfsd4_dec)nfsd4_decode_notsupp, @@ -3162,7 +3173,7 @@ static nfsd4_enc nfsd4_enc_ops[] = { [OP_LAYOUTCOMMIT] = (nfsd4_enc)nfsd4_encode_noop, [OP_LAYOUTGET] = (nfsd4_enc)nfsd4_encode_noop, [OP_LAYOUTRETURN] = (nfsd4_enc)nfsd4_encode_noop, - [OP_SECINFO_NO_NAME] = (nfsd4_enc)nfsd4_encode_noop, + [OP_SECINFO_NO_NAME] = (nfsd4_enc)nfsd4_encode_secinfo, [OP_SEQUENCE] = (nfsd4_enc)nfsd4_encode_sequence, [OP_SET_SSV] = (nfsd4_enc)nfsd4_encode_noop, [OP_TEST_STATEID] = (nfsd4_enc)nfsd4_encode_noop, diff --git a/fs/nfsd/xdr4.h b/fs/nfsd/xdr4.h index 60fce3dc5cb5..799c30c3b495 100644 --- a/fs/nfsd/xdr4.h +++ b/fs/nfsd/xdr4.h @@ -311,6 +311,11 @@ struct nfsd4_secinfo { struct svc_export *si_exp; /* response */ }; +struct nfsd4_secinfo_no_name { + u32 sin_style; /* request */ + struct svc_export *sin_exp; /* response */ +}; + struct nfsd4_setattr { stateid_t sa_stateid; /* request */ u32 sa_bmval[3]; /* request */ diff --git a/include/linux/nfs4.h b/include/linux/nfs4.h index 4925b22219d2..26afa3021ed6 100644 --- a/include/linux/nfs4.h +++ b/include/linux/nfs4.h @@ -136,6 +136,9 @@ #define SEQ4_STATUS_CB_PATH_DOWN_SESSION 0x00000200 #define SEQ4_STATUS_BACKCHANNEL_FAULT 0x00000400 +#define NFS4_SECINFO_STYLE4_CURRENT_FH 0 +#define NFS4_SECINFO_STYLE4_PARENT 1 + #define NFS4_MAX_UINT64 (~(u64)0) /* An NFS4 sessions server must support at least NFS4_MAX_OPS operations. -- cgit v1.2.3 From 3b8d8d91d51c7d15cda51052624169edf7b6dbc6 Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Fri, 17 Dec 2010 14:19:02 -0800 Subject: drm/i915: dynamic render p-state support for Sandy Bridge Add an interrupt handler for switching graphics frequencies and handling PM interrupts. This should allow for increased performance when busy and lower power consumption when idle. Signed-off-by: Jesse Barnes Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_debugfs.c | 54 ++++++++++++++++++++++++++++++------ drivers/gpu/drm/i915/i915_drv.h | 1 + drivers/gpu/drm/i915/i915_irq.c | 47 +++++++++++++++++++++++++++++-- drivers/gpu/drm/i915/i915_reg.h | 8 +++++- drivers/gpu/drm/i915/i915_suspend.c | 9 ++++-- drivers/gpu/drm/i915/intel_display.c | 36 ++++++++++++++++++++---- drivers/gpu/drm/i915/intel_drv.h | 2 ++ 7 files changed, 137 insertions(+), 20 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 864e75d762e6..92f75782c332 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c @@ -797,15 +797,51 @@ static int i915_cur_delayinfo(struct seq_file *m, void *unused) struct drm_info_node *node = (struct drm_info_node *) m->private; struct drm_device *dev = node->minor->dev; drm_i915_private_t *dev_priv = dev->dev_private; - u16 rgvswctl = I915_READ16(MEMSWCTL); - u16 rgvstat = I915_READ16(MEMSTAT_ILK); - - seq_printf(m, "Requested P-state: %d\n", (rgvswctl >> 8) & 0xf); - seq_printf(m, "Requested VID: %d\n", rgvswctl & 0x3f); - seq_printf(m, "Current VID: %d\n", (rgvstat & MEMSTAT_VID_MASK) >> - MEMSTAT_VID_SHIFT); - seq_printf(m, "Current P-state: %d\n", - (rgvstat & MEMSTAT_PSTATE_MASK) >> MEMSTAT_PSTATE_SHIFT); + + if (IS_GEN5(dev)) { + u16 rgvswctl = I915_READ16(MEMSWCTL); + u16 rgvstat = I915_READ16(MEMSTAT_ILK); + + seq_printf(m, "Requested P-state: %d\n", (rgvswctl >> 8) & 0xf); + seq_printf(m, "Requested VID: %d\n", rgvswctl & 0x3f); + seq_printf(m, "Current VID: %d\n", (rgvstat & MEMSTAT_VID_MASK) >> + MEMSTAT_VID_SHIFT); + seq_printf(m, "Current P-state: %d\n", + (rgvstat & MEMSTAT_PSTATE_MASK) >> MEMSTAT_PSTATE_SHIFT); + } else if (IS_GEN6(dev)) { + u32 gt_perf_status = I915_READ(GEN6_GT_PERF_STATUS); + u32 rp_state_limits = I915_READ(GEN6_RP_STATE_LIMITS); + u32 rp_state_cap = I915_READ(GEN6_RP_STATE_CAP); + int max_freq; + + /* RPSTAT1 is in the GT power well */ + __gen6_force_wake_get(dev_priv); + + seq_printf(m, "GT_PERF_STATUS: 0x%08x\n", gt_perf_status); + seq_printf(m, "RPSTAT1: 0x%08x\n", I915_READ(GEN6_RPSTAT1)); + seq_printf(m, "Render p-state ratio: %d\n", + (gt_perf_status & 0xff00) >> 8); + seq_printf(m, "Render p-state VID: %d\n", + gt_perf_status & 0xff); + seq_printf(m, "Render p-state limit: %d\n", + rp_state_limits & 0xff); + + max_freq = (rp_state_cap & 0xff0000) >> 16; + seq_printf(m, "Lowest (RPN) frequency: %dMHz\n", + max_freq * 100); + + max_freq = (rp_state_cap & 0xff00) >> 8; + seq_printf(m, "Nominal (RP1) frequency: %dMHz\n", + max_freq * 100); + + max_freq = rp_state_cap & 0xff; + seq_printf(m, "Max non-overclocked (RP0) frequency: %dMHz\n", + max_freq * 100); + + __gen6_force_wake_put(dev_priv); + } else { + seq_printf(m, "no P-state info available\n"); + } return 0; } diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 53dfc8398a96..2a653cc80395 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -1264,6 +1264,7 @@ extern void intel_disable_fbc(struct drm_device *dev); extern void intel_enable_fbc(struct drm_crtc *crtc, unsigned long interval); extern bool intel_fbc_enabled(struct drm_device *dev); extern bool ironlake_set_drps(struct drm_device *dev, u8 val); +extern void gen6_set_rps(struct drm_device *dev, u8 val); extern void intel_detect_pch (struct drm_device *dev); extern int intel_trans_dp_port_sel (struct drm_crtc *crtc); diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index adf983f01dda..0dadc025b77b 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -397,11 +397,49 @@ static void notify_ring(struct drm_device *dev, jiffies + msecs_to_jiffies(DRM_I915_HANGCHECK_PERIOD)); } +static void gen6_pm_irq_handler(struct drm_device *dev) +{ + drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; + u8 new_delay = dev_priv->cur_delay; + u32 pm_iir; + + pm_iir = I915_READ(GEN6_PMIIR); + if (!pm_iir) + return; + + if (pm_iir & GEN6_PM_RP_UP_THRESHOLD) { + if (dev_priv->cur_delay != dev_priv->max_delay) + new_delay = dev_priv->cur_delay + 1; + if (new_delay > dev_priv->max_delay) + new_delay = dev_priv->max_delay; + } else if (pm_iir & (GEN6_PM_RP_DOWN_THRESHOLD | GEN6_PM_RP_DOWN_TIMEOUT)) { + if (dev_priv->cur_delay != dev_priv->min_delay) + new_delay = dev_priv->cur_delay - 1; + if (new_delay < dev_priv->min_delay) { + new_delay = dev_priv->min_delay; + I915_WRITE(GEN6_RP_INTERRUPT_LIMITS, + I915_READ(GEN6_RP_INTERRUPT_LIMITS) | + ((new_delay << 16) & 0x3f0000)); + } else { + /* Make sure we continue to get down interrupts + * until we hit the minimum frequency */ + I915_WRITE(GEN6_RP_INTERRUPT_LIMITS, + I915_READ(GEN6_RP_INTERRUPT_LIMITS) & ~0x3f0000); + } + + } + + gen6_set_rps(dev, new_delay); + dev_priv->cur_delay = new_delay; + + I915_WRITE(GEN6_PMIIR, pm_iir); +} + static irqreturn_t ironlake_irq_handler(struct drm_device *dev) { drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; int ret = IRQ_NONE; - u32 de_iir, gt_iir, de_ier, pch_iir; + u32 de_iir, gt_iir, de_ier, pch_iir, pm_iir; u32 hotplug_mask; struct drm_i915_master_private *master_priv; u32 bsd_usr_interrupt = GT_BSD_USER_INTERRUPT; @@ -417,8 +455,10 @@ static irqreturn_t ironlake_irq_handler(struct drm_device *dev) de_iir = I915_READ(DEIIR); gt_iir = I915_READ(GTIIR); pch_iir = I915_READ(SDEIIR); + pm_iir = I915_READ(GEN6_PMIIR); - if (de_iir == 0 && gt_iir == 0 && pch_iir == 0) + if (de_iir == 0 && gt_iir == 0 && pch_iir == 0 && + (!IS_GEN6(dev) || pm_iir == 0)) goto done; if (HAS_PCH_CPT(dev)) @@ -470,6 +510,9 @@ static irqreturn_t ironlake_irq_handler(struct drm_device *dev) i915_handle_rps_change(dev); } + if (IS_GEN6(dev)) + gen6_pm_irq_handler(dev); + /* should clear PCH hotplug event before clear CPU irq */ I915_WRITE(SDEIIR, pch_iir); I915_WRITE(GTIIR, gt_iir); diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index c2231f7d2d97..d60860ec8cf4 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -1188,6 +1188,10 @@ #define DDRMPLL1 0X12c20 #define PEG_BAND_GAP_DATA 0x14d68 +#define GEN6_GT_PERF_STATUS 0x145948 +#define GEN6_RP_STATE_LIMITS 0x145994 +#define GEN6_RP_STATE_CAP 0x145998 + /* * Logical Context regs */ @@ -3169,7 +3173,7 @@ #define FORCEWAKE 0xA18C #define FORCEWAKE_ACK 0x130090 -#define GEN6_RC_NORMAL_FREQ 0xA008 +#define GEN6_RPNSWREQ 0xA008 #define GEN6_TURBO_DISABLE (1<<31) #define GEN6_FREQUENCY(x) ((x)<<25) #define GEN6_OFFSET(x) ((x)<<19) @@ -3185,6 +3189,7 @@ #define GEN6_RC_CTL_HW_ENABLE (1<<31) #define GEN6_RP_DOWN_TIMEOUT 0xA010 #define GEN6_RP_INTERRUPT_LIMITS 0xA014 +#define GEN6_RPSTAT1 0xA01C #define GEN6_RP_CONTROL 0xA024 #define GEN6_RP_MEDIA_TURBO (1<<11) #define GEN6_RP_USE_NORMAL_FREQ (1<<9) @@ -3208,6 +3213,7 @@ #define GEN6_RC6_THRESHOLD 0xA0B8 #define GEN6_RC6p_THRESHOLD 0xA0BC #define GEN6_RC6pp_THRESHOLD 0xA0C0 +#define GEN6_PMINTRMSK 0xA168 #define GEN6_PMISR 0x44020 #define GEN6_PMIMR 0x44024 diff --git a/drivers/gpu/drm/i915/i915_suspend.c b/drivers/gpu/drm/i915/i915_suspend.c index a311809f3c80..f623efdb1151 100644 --- a/drivers/gpu/drm/i915/i915_suspend.c +++ b/drivers/gpu/drm/i915/i915_suspend.c @@ -817,8 +817,10 @@ int i915_save_state(struct drm_device *dev) dev_priv->saveIMR = I915_READ(IMR); } - if (HAS_PCH_SPLIT(dev)) + if (IS_IRONLAKE_M(dev)) ironlake_disable_drps(dev); + if (IS_GEN6(dev)) + gen6_disable_rps(dev); intel_disable_clock_gating(dev); @@ -867,11 +869,14 @@ int i915_restore_state(struct drm_device *dev) /* Clock gating state */ intel_enable_clock_gating(dev); - if (HAS_PCH_SPLIT(dev)) { + if (IS_IRONLAKE_M(dev)) { ironlake_enable_drps(dev); intel_init_emon(dev); } + if (IS_GEN6(dev)) + gen6_enable_rps(dev_priv); + /* Cache mode state */ I915_WRITE (CACHE_MODE_0, dev_priv->saveCACHE_MODE_0 | 0xffff0000); diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index c79bee4b4d56..880659680d0a 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -6021,6 +6021,25 @@ void ironlake_disable_drps(struct drm_device *dev) } +void gen6_set_rps(struct drm_device *dev, u8 val) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + u32 swreq; + + swreq = (val & 0x3ff) << 25; + I915_WRITE(GEN6_RPNSWREQ, swreq); +} + +void gen6_disable_rps(struct drm_device *dev) +{ + struct drm_i915_private *dev_priv = dev->dev_private; + + I915_WRITE(GEN6_RPNSWREQ, 1 << 31); + I915_WRITE(GEN6_PMINTRMSK, 0xffffffff); + I915_WRITE(GEN6_PMIER, 0); + I915_WRITE(GEN6_PMIIR, I915_READ(GEN6_PMIIR)); +} + static unsigned long intel_pxfreq(u32 vidfreq) { unsigned long freq; @@ -6107,7 +6126,7 @@ void intel_init_emon(struct drm_device *dev) dev_priv->corr = (lcfuse & LCFUSE_HIV_MASK); } -static void gen6_enable_rc6(struct drm_i915_private *dev_priv) +void gen6_enable_rps(struct drm_i915_private *dev_priv) { int i; @@ -6120,7 +6139,7 @@ static void gen6_enable_rc6(struct drm_i915_private *dev_priv) I915_WRITE(GEN6_RC_STATE, 0); __gen6_force_wake_get(dev_priv); - /* disable the counters and set determistic thresholds */ + /* disable the counters and set deterministic thresholds */ I915_WRITE(GEN6_RC_CONTROL, 0); I915_WRITE(GEN6_RC1_WAKE_RATE_LIMIT, 1000 << 16); @@ -6144,7 +6163,7 @@ static void gen6_enable_rc6(struct drm_i915_private *dev_priv) GEN6_RC_CTL_EI_MODE(1) | GEN6_RC_CTL_HW_ENABLE); - I915_WRITE(GEN6_RC_NORMAL_FREQ, + I915_WRITE(GEN6_RPNSWREQ, GEN6_FREQUENCY(10) | GEN6_OFFSET(0) | GEN6_AGGRESSIVE_TURBO); @@ -6189,6 +6208,9 @@ static void gen6_enable_rc6(struct drm_i915_private *dev_priv) GEN6_PM_RP_DOWN_THRESHOLD | GEN6_PM_RP_UP_EI_EXPIRED | GEN6_PM_RP_DOWN_EI_EXPIRED); + I915_WRITE(GEN6_PMIMR, 0); + /* enable all PM interrupts */ + I915_WRITE(GEN6_PMINTRMSK, 0); __gen6_force_wake_put(dev_priv); } @@ -6381,9 +6403,6 @@ void intel_enable_clock_gating(struct drm_device *dev) I915_READ(MCHBAR_RENDER_STANDBY) & ~RCX_SW_EXIT); } } - - if (IS_GEN6(dev)) - gen6_enable_rc6(dev_priv); } void intel_disable_clock_gating(struct drm_device *dev) @@ -6657,6 +6676,9 @@ void intel_modeset_init(struct drm_device *dev) intel_init_emon(dev); } + if (IS_GEN6(dev)) + gen6_enable_rps(dev_priv); + INIT_WORK(&dev_priv->idle_work, intel_idle_update); setup_timer(&dev_priv->idle_timer, intel_gpu_idle_timer, (unsigned long)dev); @@ -6690,6 +6712,8 @@ void intel_modeset_cleanup(struct drm_device *dev) if (IS_IRONLAKE_M(dev)) ironlake_disable_drps(dev); + if (IS_GEN6(dev)) + gen6_disable_rps(dev); intel_disable_clock_gating(dev); diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index acdea6549ec4..d782ad9fd6db 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -298,6 +298,8 @@ extern void intel_enable_clock_gating(struct drm_device *dev); extern void intel_disable_clock_gating(struct drm_device *dev); extern void ironlake_enable_drps(struct drm_device *dev); extern void ironlake_disable_drps(struct drm_device *dev); +extern void gen6_enable_rps(struct drm_i915_private *dev_priv); +extern void gen6_disable_rps(struct drm_device *dev); extern void intel_init_emon(struct drm_device *dev); extern int intel_pin_and_fence_fb_obj(struct drm_device *dev, -- cgit v1.2.3 From cfef2c6a559b1e37cbc7e7c1b51f82d26abf24ec Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Sat, 18 Dec 2010 13:07:34 -0500 Subject: jbd2: Fix a debug message in do_get_write_access() 'buffer_head' should be 'journal_head' This is a port of a patch which Namhyung Kim made to fs/jbd to jbd2. Signed-off-by: "Theodore Ts'o" --- fs/jbd2/transaction.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c index 6bf0a242613e..10b5e3b1ca8b 100644 --- a/fs/jbd2/transaction.c +++ b/fs/jbd2/transaction.c @@ -589,7 +589,7 @@ do_get_write_access(handle_t *handle, struct journal_head *jh, transaction = handle->h_transaction; journal = transaction->t_journal; - jbd_debug(5, "buffer_head %p, force_copy %d\n", jh, force_copy); + jbd_debug(5, "journal_head %p, force_copy %d\n", jh, force_copy); JBUFFER_TRACE(jh, "entry"); repeat: -- cgit v1.2.3 From a1dd53318409ed6a27a8ce4fecf52e1326a100c0 Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Sat, 18 Dec 2010 13:13:40 -0500 Subject: jbd2: use offset_in_page() instead of manual calculation This is a port to jbd2 of a patch which Namhyung Kim originally made to fs/jbd. Signed-off-by: "Theodore Ts'o" --- fs/jbd2/transaction.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c index 10b5e3b1ca8b..80f9b2a3880b 100644 --- a/fs/jbd2/transaction.c +++ b/fs/jbd2/transaction.c @@ -774,7 +774,7 @@ done: J_EXPECT_JH(jh, buffer_uptodate(jh2bh(jh)), "Possible IO failure.\n"); page = jh2bh(jh)->b_page; - offset = ((unsigned long) jh2bh(jh)->b_data) & ~PAGE_MASK; + offset = offset_in_page(jh2bh(jh)->b_data); source = kmap_atomic(page, KM_USER0); /* Fire data frozen trigger just before we copy the data */ jbd2_buffer_frozen_trigger(jh, source + offset, -- cgit v1.2.3 From ae00b267f3827ba88309fb74bdf7527396f0acf9 Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Sat, 18 Dec 2010 13:34:20 -0500 Subject: jbd2: remove unnecessary goto statement This is a port to jbd2 of a patch which Namhyung Kim originally made to fs/jbd. Signed-off-by: "Theodore Ts'o" --- fs/jbd2/transaction.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/fs/jbd2/transaction.c b/fs/jbd2/transaction.c index 80f9b2a3880b..394893242ae3 100644 --- a/fs/jbd2/transaction.c +++ b/fs/jbd2/transaction.c @@ -340,9 +340,7 @@ handle_t *jbd2__journal_start(journal_t *journal, int nblocks, int gfp_mask) jbd2_free_handle(handle); current->journal_info = NULL; handle = ERR_PTR(err); - goto out; } -out: return handle; } EXPORT_SYMBOL(jbd2__journal_start); -- cgit v1.2.3 From 9a4f6271b68b9693290963b97b320d2e6e6f3446 Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Sat, 18 Dec 2010 13:36:33 -0500 Subject: jbd2: move debug message into debug #ifdef This is a port to jbd2 of a patch which Namhyung Kim originally made to fs/jbd. Signed-off-by: "Theodore Ts'o" --- fs/jbd2/recovery.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/jbd2/recovery.c b/fs/jbd2/recovery.c index 2bc4d5f116f1..1cad869494f0 100644 --- a/fs/jbd2/recovery.c +++ b/fs/jbd2/recovery.c @@ -299,10 +299,10 @@ int jbd2_journal_skip_recovery(journal_t *journal) #ifdef CONFIG_JBD2_DEBUG int dropped = info.end_transaction - be32_to_cpu(journal->j_superblock->s_sequence); -#endif jbd_debug(1, "JBD: ignoring %d transaction%s from the journal.\n", dropped, (dropped == 1) ? "" : "s"); +#endif journal->j_transaction_sequence = ++info.end_transaction; } -- cgit v1.2.3 From b7271b0a39947f757d7969f6150dcb16c1976b91 Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Sat, 18 Dec 2010 13:39:38 -0500 Subject: jbd2: simplify return path of journal_init_common Signed-off-by: "Theodore Ts'o" --- fs/jbd2/journal.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c index 06dfd778cae5..2447bd86f801 100644 --- a/fs/jbd2/journal.c +++ b/fs/jbd2/journal.c @@ -828,7 +828,7 @@ static journal_t * journal_init_common (void) journal = kzalloc(sizeof(*journal), GFP_KERNEL); if (!journal) - goto fail; + return NULL; init_waitqueue_head(&journal->j_wait_transaction_locked); init_waitqueue_head(&journal->j_wait_logspace); @@ -853,14 +853,12 @@ static journal_t * journal_init_common (void) err = jbd2_journal_init_revoke(journal, JOURNAL_REVOKE_DEFAULT_HASH); if (err) { kfree(journal); - goto fail; + return NULL; } spin_lock_init(&journal->j_history_lock); return journal; -fail: - return NULL; } /* jbd2_journal_init_dev and jbd2_journal_init_inode: -- cgit v1.2.3 From 18bb36f9fab5980efeff063755c037a622f0231c Mon Sep 17 00:00:00 2001 From: Maxim Levitsky Date: Wed, 8 Dec 2010 04:22:57 +0200 Subject: firewire: net: add carrier detection To make userland, e.g. NetworkManager work with firewire, we need to detect whether cable is plugged or not. Simple and correct way of doing that is just counting number of peers. No peers - no link and vice versa. Signed-off-by: Stefan Richter --- drivers/firewire/net.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/drivers/firewire/net.c b/drivers/firewire/net.c index ea31e3084d67..7fd51c9e243d 100644 --- a/drivers/firewire/net.c +++ b/drivers/firewire/net.c @@ -178,6 +178,7 @@ struct fwnet_device { /* Number of tx datagrams that have been queued but not yet acked */ int queued_datagrams; + int peer_count; struct list_head peer_list; struct fw_card *card; @@ -1405,6 +1406,10 @@ static int fwnet_change_mtu(struct net_device *net, int new_mtu) return 0; } +static const struct ethtool_ops fwnet_ethtool_ops = { + .get_link = ethtool_op_get_link, +}; + static const struct net_device_ops fwnet_netdev_ops = { .ndo_open = fwnet_open, .ndo_stop = fwnet_stop, @@ -1423,6 +1428,8 @@ static void fwnet_init_dev(struct net_device *net) net->hard_header_len = FWNET_HLEN; net->type = ARPHRD_IEEE1394; net->tx_queue_len = FWNET_TX_QUEUE_LEN; + net->ethtool_ops = &fwnet_ethtool_ops; + } /* caller must hold fwnet_device_mutex */ @@ -1463,6 +1470,7 @@ static int fwnet_add_peer(struct fwnet_device *dev, spin_lock_irq(&dev->lock); list_add_tail(&peer->peer_link, &dev->peer_list); + dev->peer_count++; spin_unlock_irq(&dev->lock); return 0; @@ -1534,6 +1542,9 @@ static int fwnet_probe(struct device *_dev) unregister_netdev(net); list_del(&dev->dev_link); } + + if (dev->peer_count > 1) + netif_carrier_on(net); out: if (ret && allocated_netdev) free_netdev(net); @@ -1549,6 +1560,7 @@ static void fwnet_remove_peer(struct fwnet_peer *peer) spin_lock_irq(&peer->dev->lock); list_del(&peer->peer_link); + peer->dev->peer_count--; spin_unlock_irq(&peer->dev->lock); list_for_each_entry_safe(pd, pd_next, &peer->pd_list, pd_link) @@ -1568,6 +1580,11 @@ static int fwnet_remove(struct device *_dev) fwnet_remove_peer(peer); + /* If we serve just one node, that means we lost link + with outer world */ + if (dev->peer_count == 1) + netif_carrier_off(dev->netdev); + if (list_empty(&dev->peer_list)) { net = dev->netdev; unregister_netdev(net); -- cgit v1.2.3 From c16714704bb35165e5b85d927873dcc643772648 Mon Sep 17 00:00:00 2001 From: Stefan Richter Date: Fri, 17 Dec 2010 22:22:33 +0100 Subject: firewire: net: set carrier state at ifup At ifup, carrier status would be shown on even if it actually was off. Also add an include for ethtool_ops rather than to rely on the one from netdevice.h. Note, we can alas not use fwnet_device_mutex to serialize access to dev->peer_count (as I originally wanted). This would cause a lock inversion: - fwnet_probe | takes fwnet_device_mutex + register_netdev | takes rtnl_mutex - devinet_ioctl | takes rtnl_mutex + fwnet_open | ...must not take fwnet_device_mutex Hence use the dev->lock spinlock for serialization. Signed-off-by: Stefan Richter --- drivers/firewire/net.c | 36 +++++++++++++++++++++--------------- 1 file changed, 21 insertions(+), 15 deletions(-) diff --git a/drivers/firewire/net.c b/drivers/firewire/net.c index 7fd51c9e243d..c2e194c58667 100644 --- a/drivers/firewire/net.c +++ b/drivers/firewire/net.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -178,8 +179,8 @@ struct fwnet_device { /* Number of tx datagrams that have been queued but not yet acked */ int queued_datagrams; - int peer_count; + int peer_count; struct list_head peer_list; struct fw_card *card; struct net_device *netdev; @@ -1222,6 +1223,14 @@ static int fwnet_broadcast_start(struct fwnet_device *dev) return retval; } +static void set_carrier_state(struct fwnet_device *dev) +{ + if (dev->peer_count > 1) + netif_carrier_on(dev->netdev); + else + netif_carrier_off(dev->netdev); +} + /* ifup */ static int fwnet_open(struct net_device *net) { @@ -1235,6 +1244,10 @@ static int fwnet_open(struct net_device *net) } netif_start_queue(net); + spin_lock_irq(&dev->lock); + set_carrier_state(dev); + spin_unlock_irq(&dev->lock); + return 0; } @@ -1429,7 +1442,6 @@ static void fwnet_init_dev(struct net_device *net) net->type = ARPHRD_IEEE1394; net->tx_queue_len = FWNET_TX_QUEUE_LEN; net->ethtool_ops = &fwnet_ethtool_ops; - } /* caller must hold fwnet_device_mutex */ @@ -1471,6 +1483,7 @@ static int fwnet_add_peer(struct fwnet_device *dev, spin_lock_irq(&dev->lock); list_add_tail(&peer->peer_link, &dev->peer_list); dev->peer_count++; + set_carrier_state(dev); spin_unlock_irq(&dev->lock); return 0; @@ -1542,9 +1555,6 @@ static int fwnet_probe(struct device *_dev) unregister_netdev(net); list_del(&dev->dev_link); } - - if (dev->peer_count > 1) - netif_carrier_on(net); out: if (ret && allocated_netdev) free_netdev(net); @@ -1554,14 +1564,15 @@ static int fwnet_probe(struct device *_dev) return ret; } -static void fwnet_remove_peer(struct fwnet_peer *peer) +static void fwnet_remove_peer(struct fwnet_peer *peer, struct fwnet_device *dev) { struct fwnet_partial_datagram *pd, *pd_next; - spin_lock_irq(&peer->dev->lock); + spin_lock_irq(&dev->lock); list_del(&peer->peer_link); - peer->dev->peer_count--; - spin_unlock_irq(&peer->dev->lock); + dev->peer_count--; + set_carrier_state(dev); + spin_unlock_irq(&dev->lock); list_for_each_entry_safe(pd, pd_next, &peer->pd_list, pd_link) fwnet_pd_delete(pd); @@ -1578,12 +1589,7 @@ static int fwnet_remove(struct device *_dev) mutex_lock(&fwnet_device_mutex); - fwnet_remove_peer(peer); - - /* If we serve just one node, that means we lost link - with outer world */ - if (dev->peer_count == 1) - netif_carrier_off(dev->netdev); + fwnet_remove_peer(peer, dev); if (list_empty(&dev->peer_list)) { net = dev->netdev; -- cgit v1.2.3 From 6ca7b13dea385484e2fcc89790b8030697c5014a Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Sun, 19 Dec 2010 21:38:46 -0500 Subject: ext4: Remove redundant unlikely() IS_ERR() already implies unlikely(), so it can be omitted here. Signed-off-by: Tobias Klauser Signed-off-by: "Theodore Ts'o" --- fs/ext4/namei.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c index dc40e75cba88..203086498caa 100644 --- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c @@ -1036,7 +1036,7 @@ static struct dentry *ext4_lookup(struct inode *dir, struct dentry *dentry, stru return ERR_PTR(-EIO); } inode = ext4_iget(dir->i_sb, ino); - if (unlikely(IS_ERR(inode))) { + if (IS_ERR(inode)) { if (PTR_ERR(inode) == -ESTALE) { EXT4_ERROR_INODE(dir, "deleted inode referenced: %u", -- cgit v1.2.3 From b17b35ec13adfeb0346d4b329110b14adc509327 Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Sun, 19 Dec 2010 21:41:55 -0500 Subject: ext4: use kmem_cache_zalloc() in ext4_init_io_end() Use advantage of kmem_cache_zalloc() to remove a memset() call in ext4_init_io_end() and save a few bytes. Before: [jj@dragon linux-2.6]$ size fs/ext4/page-io.o text data bss dec hex filename 3016 0 624 3640 e38 fs/ext4/page-io.o After: [jj@dragon linux-2.6]$ size fs/ext4/page-io.o text data bss dec hex filename 3000 0 624 3624 e28 fs/ext4/page-io.o Signed-off-by: Jesper Juhl Signed-off-by: "Theodore Ts'o" --- fs/ext4/page-io.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/fs/ext4/page-io.c b/fs/ext4/page-io.c index beacce11ac50..0f5dfe0e83e7 100644 --- a/fs/ext4/page-io.c +++ b/fs/ext4/page-io.c @@ -158,11 +158,8 @@ static void ext4_end_io_work(struct work_struct *work) ext4_io_end_t *ext4_init_io_end(struct inode *inode, gfp_t flags) { - ext4_io_end_t *io = NULL; - - io = kmem_cache_alloc(io_end_cachep, flags); + ext4_io_end_t *io = kmem_cache_zalloc(io_end_cachep, flags); if (io) { - memset(io, 0, sizeof(*io)); atomic_inc(&EXT4_I(inode)->i_ioend_count); io->inode = inode; INIT_WORK(&io->work, ext4_end_io_work); -- cgit v1.2.3 From cad3f00763dcf9dfc62cbddf4bd714ab5a71a0eb Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Sun, 19 Dec 2010 22:07:02 -0500 Subject: ext4: optimize ext4_check_dir_entry() with unlikely() annotations This function gets called a lot for large directories, and the answer is almost always "no, no, there's no problem". This means using unlikely() is a good thing. Signed-off-by: "Theodore Ts'o" --- fs/ext4/dir.c | 40 +++++++++++++++++++++++----------------- fs/ext4/ext4.h | 3 ++- fs/ext4/namei.c | 14 +++++++------- 3 files changed, 32 insertions(+), 25 deletions(-) diff --git a/fs/ext4/dir.c b/fs/ext4/dir.c index ece76fb6a40c..bd5d74d06399 100644 --- a/fs/ext4/dir.c +++ b/fs/ext4/dir.c @@ -60,7 +60,11 @@ static unsigned char get_dtype(struct super_block *sb, int filetype) return (ext4_filetype_table[filetype]); } - +/* + * Return 0 if the directory entry is OK, and 1 if there is a problem + * + * Note: this is the opposite of what ext2 and ext3 historically returned... + */ int __ext4_check_dir_entry(const char *function, unsigned int line, struct inode *dir, struct ext4_dir_entry_2 *de, @@ -71,26 +75,28 @@ int __ext4_check_dir_entry(const char *function, unsigned int line, const int rlen = ext4_rec_len_from_disk(de->rec_len, dir->i_sb->s_blocksize); - if (rlen < EXT4_DIR_REC_LEN(1)) + if (unlikely(rlen < EXT4_DIR_REC_LEN(1))) error_msg = "rec_len is smaller than minimal"; - else if (rlen % 4 != 0) + else if (unlikely(rlen % 4 != 0)) error_msg = "rec_len % 4 != 0"; - else if (rlen < EXT4_DIR_REC_LEN(de->name_len)) + else if (unlikely(rlen < EXT4_DIR_REC_LEN(de->name_len))) error_msg = "rec_len is too small for name_len"; - else if (((char *) de - bh->b_data) + rlen > dir->i_sb->s_blocksize) + else if (unlikely(((char *) de - bh->b_data) + rlen > + dir->i_sb->s_blocksize)) error_msg = "directory entry across blocks"; - else if (le32_to_cpu(de->inode) > - le32_to_cpu(EXT4_SB(dir->i_sb)->s_es->s_inodes_count)) + else if (unlikely(le32_to_cpu(de->inode) > + le32_to_cpu(EXT4_SB(dir->i_sb)->s_es->s_inodes_count))) error_msg = "inode out of bounds"; + else + return 0; - if (error_msg != NULL) - ext4_error_inode(dir, function, line, bh->b_blocknr, - "bad entry in directory: %s - " - "offset=%u(%u), inode=%u, rec_len=%d, name_len=%d", - error_msg, (unsigned) (offset%bh->b_size), offset, - le32_to_cpu(de->inode), - rlen, de->name_len); - return error_msg == NULL ? 1 : 0; + ext4_error_inode(dir, function, line, bh->b_blocknr, + "bad entry in directory: %s - " + "offset=%u(%u), inode=%u, rec_len=%d, name_len=%d", + error_msg, (unsigned) (offset%bh->b_size), offset, + le32_to_cpu(de->inode), + rlen, de->name_len); + return 1; } static int ext4_readdir(struct file *filp, @@ -194,8 +200,8 @@ revalidate: while (!error && filp->f_pos < inode->i_size && offset < sb->s_blocksize) { de = (struct ext4_dir_entry_2 *) (bh->b_data + offset); - if (!ext4_check_dir_entry(inode, de, - bh, offset)) { + if (ext4_check_dir_entry(inode, de, + bh, offset)) { /* * On error, skip the f_pos to the next block */ diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index 17baecbf8cda..49f1ceaac57d 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h @@ -1639,7 +1639,8 @@ extern int __ext4_check_dir_entry(const char *, unsigned int, struct inode *, struct ext4_dir_entry_2 *, struct buffer_head *, unsigned int); #define ext4_check_dir_entry(dir, de, bh, offset) \ - __ext4_check_dir_entry(__func__, __LINE__, (dir), (de), (bh), (offset)) + unlikely(__ext4_check_dir_entry(__func__, __LINE__, (dir), (de), \ + (bh), (offset))) extern int ext4_htree_store_dirent(struct file *dir_file, __u32 hash, __u32 minor_hash, struct ext4_dir_entry_2 *dirent); diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c index 203086498caa..e275464f7754 100644 --- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c @@ -581,9 +581,9 @@ static int htree_dirblock_to_tree(struct file *dir_file, dir->i_sb->s_blocksize - EXT4_DIR_REC_LEN(0)); for (; de < top; de = ext4_next_entry(de, dir->i_sb->s_blocksize)) { - if (!ext4_check_dir_entry(dir, de, bh, - (block<i_sb)) - +((char *)de - bh->b_data))) { + if (ext4_check_dir_entry(dir, de, bh, + (block<i_sb)) + + ((char *)de - bh->b_data))) { /* On error, skip the f_pos to the next block. */ dir_file->f_pos = (dir_file->f_pos | (dir->i_sb->s_blocksize - 1)) + 1; @@ -820,7 +820,7 @@ static inline int search_dirblock(struct buffer_head *bh, if ((char *) de + namelen <= dlimit && ext4_match (namelen, name, de)) { /* found a match - just to be sure, do a full check */ - if (!ext4_check_dir_entry(dir, de, bh, offset)) + if (ext4_check_dir_entry(dir, de, bh, offset)) return -1; *res_dir = de; return 1; @@ -1269,7 +1269,7 @@ static int add_dirent_to_buf(handle_t *handle, struct dentry *dentry, de = (struct ext4_dir_entry_2 *)bh->b_data; top = bh->b_data + blocksize - reclen; while ((char *) de <= top) { - if (!ext4_check_dir_entry(dir, de, bh, offset)) + if (ext4_check_dir_entry(dir, de, bh, offset)) return -EIO; if (ext4_match(namelen, name, de)) return -EEXIST; @@ -1636,7 +1636,7 @@ static int ext4_delete_entry(handle_t *handle, pde = NULL; de = (struct ext4_dir_entry_2 *) bh->b_data; while (i < bh->b_size) { - if (!ext4_check_dir_entry(dir, de, bh, i)) + if (ext4_check_dir_entry(dir, de, bh, i)) return -EIO; if (de == de_del) { BUFFER_TRACE(bh, "get_write_access"); @@ -1919,7 +1919,7 @@ static int empty_dir(struct inode *inode) } de = (struct ext4_dir_entry_2 *) bh->b_data; } - if (!ext4_check_dir_entry(inode, de, bh, offset)) { + if (ext4_check_dir_entry(inode, de, bh, offset)) { de = (struct ext4_dir_entry_2 *)(bh->b_data + sb->s_blocksize); offset = (offset | (sb->s_blocksize - 1)) + 1; -- cgit v1.2.3 From af0b44a1970fed1cda31d2969c99c46ffc515160 Mon Sep 17 00:00:00 2001 From: Eric Sandeen Date: Sun, 19 Dec 2010 22:10:31 -0500 Subject: ext4: zero out nanosecond timestamps for small inodes When nanosecond timestamp resolution isn't supported on an ext4 partition (inode size = 128), stat() appears to be returning uninitialized garbage in the nanosecond component of timestamps. EXT4_INODE_GET_XTIME should zero out tv_nsec when EXT4_FITS_IN_INODE evaluates to false. Reported-by: Jordan Russell Signed-off-by: Eric Sandeen Signed-off-by: "Theodore Ts'o" --- fs/ext4/ext4.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index 49f1ceaac57d..8104ab7eb7d4 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h @@ -693,6 +693,8 @@ do { \ if (EXT4_FITS_IN_INODE(raw_inode, EXT4_I(inode), xtime ## _extra)) \ ext4_decode_extra_time(&(inode)->xtime, \ raw_inode->xtime ## _extra); \ + else \ + (inode)->xtime.tv_nsec = 0; \ } while (0) #define EXT4_EINODE_GET_XTIME(xtime, einode, raw_inode) \ @@ -703,6 +705,8 @@ do { \ if (EXT4_FITS_IN_INODE(raw_inode, einode, xtime ## _extra)) \ ext4_decode_extra_time(&(einode)->xtime, \ raw_inode->xtime ## _extra); \ + else \ + (einode)->xtime.tv_nsec = 0; \ } while (0) #define i_disk_version osd1.linux1.l_i_version -- cgit v1.2.3 From 94de56ab2062be59d80e2efb7c0dc60ecf616075 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Sun, 19 Dec 2010 22:21:02 -0500 Subject: ext4: Use vzalloc in ext4_fill_flex_info() Signed-off-by: Joe Perches Signed-off-by: "Theodore Ts'o" --- fs/ext4/super.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 072ff973ff2b..10290f8f5922 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -1930,14 +1930,13 @@ static int ext4_fill_flex_info(struct super_block *sb) size = flex_group_count * sizeof(struct flex_groups); sbi->s_flex_groups = kzalloc(size, GFP_KERNEL); if (sbi->s_flex_groups == NULL) { - sbi->s_flex_groups = vmalloc(size); - if (sbi->s_flex_groups) - memset(sbi->s_flex_groups, 0, size); - } - if (sbi->s_flex_groups == NULL) { - ext4_msg(sb, KERN_ERR, "not enough memory for " - "%u flex groups", flex_group_count); - goto failed; + sbi->s_flex_groups = vzalloc(size); + if (sbi->s_flex_groups == NULL) { + ext4_msg(sb, KERN_ERR, + "not enough memory for %u flex groups", + flex_group_count); + goto failed; + } } for (i = 0; i < sbi->s_groups_count; i++) { -- cgit v1.2.3 From 0ff2ea7d84e31176a046a1eabea59d6e4eecd998 Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Sun, 19 Dec 2010 22:43:19 -0500 Subject: ext4: Use printf extension %pV Using %pV reduces the number of printk calls and eliminates any possible message interleaving from other printk calls. In function __ext4_grp_locked_error also added KERN_CONT to some printks. Signed-off-by: Joe Perches Signed-off-by: "Theodore Ts'o" --- fs/ext4/super.c | 40 +++++++++++++++++++++++----------------- 1 file changed, 23 insertions(+), 17 deletions(-) diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 10290f8f5922..c228da112de0 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c @@ -388,13 +388,14 @@ static void ext4_handle_error(struct super_block *sb) void __ext4_error(struct super_block *sb, const char *function, unsigned int line, const char *fmt, ...) { + struct va_format vaf; va_list args; va_start(args, fmt); - printk(KERN_CRIT "EXT4-fs error (device %s): %s:%d: comm %s: ", - sb->s_id, function, line, current->comm); - vprintk(fmt, args); - printk("\n"); + vaf.fmt = fmt; + vaf.va = &args; + printk(KERN_CRIT "EXT4-fs error (device %s): %s:%d: comm %s: %pV\n", + sb->s_id, function, line, current->comm, &vaf); va_end(args); ext4_handle_error(sb); @@ -543,28 +544,29 @@ void __ext4_abort(struct super_block *sb, const char *function, panic("EXT4-fs panic from previous error\n"); } -void ext4_msg (struct super_block * sb, const char *prefix, - const char *fmt, ...) +void ext4_msg(struct super_block *sb, const char *prefix, const char *fmt, ...) { + struct va_format vaf; va_list args; va_start(args, fmt); - printk("%sEXT4-fs (%s): ", prefix, sb->s_id); - vprintk(fmt, args); - printk("\n"); + vaf.fmt = fmt; + vaf.va = &args; + printk("%sEXT4-fs (%s): %pV\n", prefix, sb->s_id, &vaf); va_end(args); } void __ext4_warning(struct super_block *sb, const char *function, unsigned int line, const char *fmt, ...) { + struct va_format vaf; va_list args; va_start(args, fmt); - printk(KERN_WARNING "EXT4-fs warning (device %s): %s:%d: ", - sb->s_id, function, line); - vprintk(fmt, args); - printk("\n"); + vaf.fmt = fmt; + vaf.va = &args; + printk(KERN_WARNING "EXT4-fs warning (device %s): %s:%d: %pV\n", + sb->s_id, function, line, &vaf); va_end(args); } @@ -575,21 +577,25 @@ void __ext4_grp_locked_error(const char *function, unsigned int line, __releases(bitlock) __acquires(bitlock) { + struct va_format vaf; va_list args; struct ext4_super_block *es = EXT4_SB(sb)->s_es; es->s_last_error_ino = cpu_to_le32(ino); es->s_last_error_block = cpu_to_le64(block); __save_error_info(sb, function, line); + va_start(args, fmt); + + vaf.fmt = fmt; + vaf.va = &args; printk(KERN_CRIT "EXT4-fs error (device %s): %s:%d: group %u", sb->s_id, function, line, grp); if (ino) - printk("inode %lu: ", ino); + printk(KERN_CONT "inode %lu: ", ino); if (block) - printk("block %llu:", (unsigned long long) block); - vprintk(fmt, args); - printk("\n"); + printk(KERN_CONT "block %llu:", (unsigned long long) block); + printk(KERN_CONT "%pV\n", &vaf); va_end(args); if (test_opt(sb, ERRORS_CONT)) { -- cgit v1.2.3 From 3603b8eaccc8e41d3f355b3cadd662a3dd6699fd Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Mon, 20 Dec 2010 09:15:19 +0100 Subject: Fix compile warnings due to missing removal of a 'ret' variable Commit a8adbe3 forgot to remove the return variable, kill it. drivers/block/loop.c: In function 'lo_splice_actor': drivers/block/loop.c:398: warning: unused variable 'ret' [...] fs/nfsd/vfs.c: In function 'nfsd_splice_actor': fs/nfsd/vfs.c:848: warning: unused variable 'ret' Reported-by: Stephen Rothwell Signed-off-by: Jens Axboe --- drivers/block/loop.c | 2 +- fs/nfsd/vfs.c | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/block/loop.c b/drivers/block/loop.c index c87b0840d2cb..44e18c073c44 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -395,7 +395,7 @@ lo_splice_actor(struct pipe_inode_info *pipe, struct pipe_buffer *buf, struct loop_device *lo = p->lo; struct page *page = buf->page; sector_t IV; - int size, ret; + int size; IV = ((sector_t) page->index << (PAGE_CACHE_SHIFT - 9)) + (buf->offset >> 9); diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index c6e08661adee..106ed482f119 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c @@ -845,7 +845,6 @@ nfsd_splice_actor(struct pipe_inode_info *pipe, struct pipe_buffer *buf, struct page **pp = rqstp->rq_respages + rqstp->rq_resused; struct page *page = buf->page; size_t size; - int ret; size = sd->len; -- cgit v1.2.3 From 72bfa19c8deb4d1db5ad068c34fd580cb295cbe8 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Sun, 19 Dec 2010 11:42:05 +0000 Subject: drm/i915: Allow the application to choose the constant addressing mode The relative-to-general state default is useless as it means having to rewrite the streaming kernels for each batch. Relative-to-surface is more useful, as that stream usually needs to be rewritten for each batch. And absolute addressing mode, vital if you start streaming state, is also only available by adjusting the register... Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_dma.c | 3 +++ drivers/gpu/drm/i915/i915_drv.h | 1 + drivers/gpu/drm/i915/i915_gem.c | 2 ++ drivers/gpu/drm/i915/i915_gem_execbuffer.c | 35 +++++++++++++++++++++++++++++- include/drm/i915_drm.h | 12 ++++++++++ 5 files changed, 52 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 3f7b20392e26..18746e6cb129 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -778,6 +778,9 @@ static int i915_getparam(struct drm_device *dev, void *data, case I915_PARAM_HAS_COHERENT_RINGS: value = 1; break; + case I915_PARAM_HAS_EXEC_CONSTANTS: + value = INTEL_INFO(dev)->gen >= 4; + break; default: DRM_DEBUG_DRIVER("Unknown parameter %d\n", param->param); diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 2a653cc80395..aac1bf332f75 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -258,6 +258,7 @@ typedef struct drm_i915_private { const struct intel_device_info *info; int has_gem; + int relative_constants_mode; void __iomem *regs; diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 5a0fbe59dd5b..c79c0b62ef60 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -3735,6 +3735,8 @@ i915_gem_load(struct drm_device *dev) } } + dev_priv->relative_constants_mode = I915_EXEC_CONSTANTS_REL_GENERAL; + /* Old X drivers will take 0-2 for front, back, depth buffers */ if (!drm_core_check_feature(dev, DRIVER_MODESET)) dev_priv->fence_reg_start = 3; diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index fda0dc858a1f..61129e6759eb 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c @@ -957,7 +957,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, struct intel_ring_buffer *ring; u32 exec_start, exec_len; u32 seqno; - int ret, i; + int ret, mode, i; if (!i915_gem_check_execbuffer(args)) { DRM_ERROR("execbuf with invalid offset/length\n"); @@ -997,6 +997,39 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, return -EINVAL; } + mode = args->flags & I915_EXEC_CONSTANTS_MASK; + switch (mode) { + case I915_EXEC_CONSTANTS_REL_GENERAL: + case I915_EXEC_CONSTANTS_ABSOLUTE: + case I915_EXEC_CONSTANTS_REL_SURFACE: + if (ring == &dev_priv->ring[RCS] && + mode != dev_priv->relative_constants_mode) { + if (INTEL_INFO(dev)->gen < 4) + return -EINVAL; + + if (INTEL_INFO(dev)->gen > 5 && + mode == I915_EXEC_CONSTANTS_REL_SURFACE) + return -EINVAL; + + ret = intel_ring_begin(ring, 4); + if (ret) + return ret; + + intel_ring_emit(ring, MI_NOOP); + intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(1)); + intel_ring_emit(ring, INSTPM); + intel_ring_emit(ring, + I915_EXEC_CONSTANTS_MASK << 16 | mode); + intel_ring_advance(ring); + + dev_priv->relative_constants_mode = mode; + } + break; + default: + DRM_ERROR("execbuf with unknown constants: %d\n", mode); + return -EINVAL; + } + if (args->buffer_count < 1) { DRM_ERROR("execbuf with %d buffers\n", args->buffer_count); return -EINVAL; diff --git a/include/drm/i915_drm.h b/include/drm/i915_drm.h index a2776e2807a4..0039f1f97ad8 100644 --- a/include/drm/i915_drm.h +++ b/include/drm/i915_drm.h @@ -289,6 +289,7 @@ typedef struct drm_i915_irq_wait { #define I915_PARAM_HAS_BLT 11 #define I915_PARAM_HAS_RELAXED_FENCING 12 #define I915_PARAM_HAS_COHERENT_RINGS 13 +#define I915_PARAM_HAS_EXEC_CONSTANTS 14 typedef struct drm_i915_getparam { int param; @@ -635,6 +636,17 @@ struct drm_i915_gem_execbuffer2 { #define I915_EXEC_RENDER (1<<0) #define I915_EXEC_BSD (2<<0) #define I915_EXEC_BLT (3<<0) + +/* Used for switching the constants addressing mode on gen4+ RENDER ring. + * Gen6+ only supports relative addressing to dynamic state (default) and + * absolute addressing. + * + * These flags are ignored for the BSD and BLT rings. + */ +#define I915_EXEC_CONSTANTS_MASK (3<<6) +#define I915_EXEC_CONSTANTS_REL_GENERAL (0<<6) /* default */ +#define I915_EXEC_CONSTANTS_ABSOLUTE (1<<6) +#define I915_EXEC_CONSTANTS_REL_SURFACE (2<<6) /* gen4/5 only */ __u64 flags; __u64 rsvd1; __u64 rsvd2; -- cgit v1.2.3 From 5909a77ac62cc042f94bd262016cf468a2f96022 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Mon, 20 Dec 2010 09:45:15 +0000 Subject: drm/i915: Undo "Uncouple render/power ctx before suspending" Manaul revert of 0cdab21f9a1fca50dd27e488839f5a6578e333b2, just to remove the call to disable the clock gatings and powerctx before suspend. Peter Clifton bisected a suspend failure on his gme45 and found this to be the culprit. As this was intended to be a fix for a similar suspend failure for Ironlake (it didn't work), undoing this patch should have no other side-effects. Reported-and-tested-by: Peter Clifton Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_suspend.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/gpu/drm/i915/i915_suspend.c b/drivers/gpu/drm/i915/i915_suspend.c index f623efdb1151..410772466fa7 100644 --- a/drivers/gpu/drm/i915/i915_suspend.c +++ b/drivers/gpu/drm/i915/i915_suspend.c @@ -822,7 +822,9 @@ int i915_save_state(struct drm_device *dev) if (IS_GEN6(dev)) gen6_disable_rps(dev); + /* XXX disabling the clock gating breaks suspend on gm45 intel_disable_clock_gating(dev); + */ /* Cache mode state */ dev_priv->saveCACHE_MODE_0 = I915_READ(CACHE_MODE_0); -- cgit v1.2.3 From b72143ab3ed566a12560fa4411a1f02c276dcc39 Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Mon, 20 Dec 2010 07:26:59 -0500 Subject: ext4: Add error checking to kmem_cache_alloc() call in ext4_free_blocks() Signed-off-by: "Theodore Ts'o" --- fs/ext4/mballoc.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index 731b6f738a03..46d5414f59c1 100644 --- a/fs/ext4/mballoc.c +++ b/fs/ext4/mballoc.c @@ -4626,7 +4626,11 @@ do_more: * blocks being freed are metadata. these blocks shouldn't * be used until this transaction is committed */ - new_entry = kmem_cache_alloc(ext4_free_ext_cachep, GFP_NOFS); + new_entry = kmem_cache_alloc(ext4_free_ext_cachep, GFP_NOFS); + if (!new_entry) { + err = -ENOMEM; + goto error_return; + } new_entry->start_blk = bit; new_entry->group = block_group; new_entry->count = count; -- cgit v1.2.3 From 6ce534aac29ca177749000d76e4ecc8a326c852d Mon Sep 17 00:00:00 2001 From: Jassi Brar Date: Mon, 20 Dec 2010 11:05:46 +0900 Subject: ASoC: Samsung: Set default rclk source rate Since the rclk_srcrate is cleared upon startup, it should be initialized upon second and later 'open' calls to the device with same root-clock source. The bug is otherwise visible in Codec-Slave mode. Signed-off-by: Jassi Brar Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/samsung/i2s.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c index d6de3f0eeff8..26b4bdf42c5b 100644 --- a/sound/soc/samsung/i2s.c +++ b/sound/soc/samsung/i2s.c @@ -525,6 +525,8 @@ static int i2s_set_sysclk(struct snd_soc_dai *dai, clk_disable(i2s->op_clk); clk_put(i2s->op_clk); } else { + i2s->rclk_srcrate = + clk_get_rate(i2s->op_clk); return 0; } } -- cgit v1.2.3 From 775bc97131c3dcf62d29cdb33e00db8f827eac35 Mon Sep 17 00:00:00 2001 From: Jassi Brar Date: Mon, 20 Dec 2010 11:05:47 +0900 Subject: ASoC: Samsung: I2S: Flush FIFO after stop Flush the FIFO while stopping the channel rather than starting. This saves time during stream start and keeps the FIFOs clean when the channel is idling. Signed-off-by: Jassi Brar Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/samsung/i2s.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/sound/soc/samsung/i2s.c b/sound/soc/samsung/i2s.c index 26b4bdf42c5b..d00ac3a7102c 100644 --- a/sound/soc/samsung/i2s.c +++ b/sound/soc/samsung/i2s.c @@ -843,11 +843,6 @@ static int i2s_trigger(struct snd_pcm_substream *substream, case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: local_irq_save(flags); - if (capture) - i2s_fifo(i2s, FIC_RXFLUSH); - else - i2s_fifo(i2s, FIC_TXFLUSH); - if (config_setup(i2s)) { local_irq_restore(flags); return -EINVAL; @@ -870,6 +865,11 @@ static int i2s_trigger(struct snd_pcm_substream *substream, else i2s_txctrl(i2s, 0); + if (capture) + i2s_fifo(i2s, FIC_RXFLUSH); + else + i2s_fifo(i2s, FIC_TXFLUSH); + local_irq_restore(flags); break; } -- cgit v1.2.3 From 72685f27b1aed0d104e9356e30343506a4e09c30 Mon Sep 17 00:00:00 2001 From: Jassi Brar Date: Mon, 20 Dec 2010 11:05:48 +0900 Subject: ASoC: SMDK_WM8580: Make I2S0 as default dai Since most newer SMDKs have I2S0 routed to the WM8580's Primary DAI, future changes can be minimized if the default CPU DAIs are set to 0, rather than 2. Signed-off-by: Jassi Brar Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/samsung/smdk_wm8580.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/sound/soc/samsung/smdk_wm8580.c b/sound/soc/samsung/smdk_wm8580.c index e2d56b9bac5a..e4f3bc8c1248 100644 --- a/sound/soc/samsung/smdk_wm8580.c +++ b/sound/soc/samsung/smdk_wm8580.c @@ -212,7 +212,7 @@ static struct snd_soc_dai_link smdk_dai[] = { [PRI_PLAYBACK] = { /* Primary Playback i/f */ .name = "WM8580 PAIF RX", .stream_name = "Playback", - .cpu_dai_name = "samsung-i2s.2", + .cpu_dai_name = "samsung-i2s.0", .codec_dai_name = "wm8580-hifi-playback", .platform_name = "samsung-audio", .codec_name = "wm8580-codec.0-001b", @@ -222,7 +222,7 @@ static struct snd_soc_dai_link smdk_dai[] = { [PRI_CAPTURE] = { /* Primary Capture i/f */ .name = "WM8580 PAIF TX", .stream_name = "Capture", - .cpu_dai_name = "samsung-i2s.2", + .cpu_dai_name = "samsung-i2s.0", .codec_dai_name = "wm8580-hifi-capture", .platform_name = "samsung-audio", .codec_name = "wm8580-codec.0-001b", @@ -256,14 +256,14 @@ static int __init smdk_audio_init(void) if (machine_is_smdkc100()) { smdk.num_links = 3; - /* S5PC100 has I2S0 as v5 */ - str = (char *)smdk_dai[PRI_PLAYBACK].cpu_dai_name; - str[strlen(str) - 1] = '0'; - str = (char *)smdk_dai[PRI_CAPTURE].cpu_dai_name; - str[strlen(str) - 1] = '0'; /* Secondary is at offset SAMSUNG_I2S_SECOFF from Primary */ str = (char *)smdk_dai[SEC_PLAYBACK].cpu_dai_name; str[strlen(str) - 1] = '0' + SAMSUNG_I2S_SECOFF; + } else if (machine_is_smdk6410()) { + str = (char *)smdk_dai[PRI_PLAYBACK].cpu_dai_name; + str[strlen(str) - 1] = '2'; + str = (char *)smdk_dai[PRI_CAPTURE].cpu_dai_name; + str[strlen(str) - 1] = '2'; } smdk_snd_device = platform_device_alloc("soc-audio", -1); -- cgit v1.2.3 From c6ccc596cafd99b46ba1db8b7c81c7fb0ead90d6 Mon Sep 17 00:00:00 2001 From: Jassi Brar Date: Mon, 20 Dec 2010 11:05:50 +0900 Subject: ASoC: SMDK6440: Enable I2S device Signed-off-by: Jassi Brar Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/samsung/Kconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/samsung/Kconfig b/sound/soc/samsung/Kconfig index 67cdad4ee535..be09a2290603 100644 --- a/sound/soc/samsung/Kconfig +++ b/sound/soc/samsung/Kconfig @@ -1,6 +1,6 @@ config ASOC_SAMSUNG tristate "ASoC support for Samsung" - depends on ARCH_S3C2410 || ARCH_S3C64XX || ARCH_S5PC100 || ARCH_S5PV210 + depends on ARCH_S3C2410 || ARCH_S3C64XX || ARCH_S5PC100 || ARCH_S5PV210 || ARCH_S5P64X0 select S3C64XX_DMA if ARCH_S3C64XX select S3C2410_DMA if ARCH_S3C2410 help @@ -62,7 +62,7 @@ config ASOC_SAMSUNG_JIVE_WM8750 config ASOC_SAMSUNG_SMDK_WM8580 tristate "SoC I2S Audio support for WM8580 on SMDK" - depends on ASOC_SAMSUNG && (MACH_SMDK6410 || MACH_SMDKC100) + depends on ASOC_SAMSUNG && (MACH_SMDK6410 || MACH_SMDKC100 || MACH_SMDK6440) select SND_SOC_WM8580 select SND_SAMSUNG_I2S help -- cgit v1.2.3 From de4987ab104da973deeb651166960d4aae19812d Mon Sep 17 00:00:00 2001 From: Jassi Brar Date: Mon, 20 Dec 2010 11:05:51 +0900 Subject: ASoC: SMDK6450: Enable I2S device Signed-off-by: Jassi Brar Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/samsung/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/samsung/Kconfig b/sound/soc/samsung/Kconfig index be09a2290603..c8aa73eb39c3 100644 --- a/sound/soc/samsung/Kconfig +++ b/sound/soc/samsung/Kconfig @@ -62,7 +62,7 @@ config ASOC_SAMSUNG_JIVE_WM8750 config ASOC_SAMSUNG_SMDK_WM8580 tristate "SoC I2S Audio support for WM8580 on SMDK" - depends on ASOC_SAMSUNG && (MACH_SMDK6410 || MACH_SMDKC100 || MACH_SMDK6440) + depends on ASOC_SAMSUNG && (MACH_SMDK6410 || MACH_SMDKC100 || MACH_SMDK6440 || MACH_SMDK6450) select SND_SOC_WM8580 select SND_SAMSUNG_I2S help -- cgit v1.2.3 From dc6ee063937f7d2e79cd1ae1596a6fe896ffa3f9 Mon Sep 17 00:00:00 2001 From: Jassi Brar Date: Mon, 20 Dec 2010 11:05:52 +0900 Subject: ASoC: SMDK6442: Enable I2S device Signed-off-by: Jassi Brar Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/samsung/Kconfig | 4 ++-- sound/soc/samsung/smdk_wm8580.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/soc/samsung/Kconfig b/sound/soc/samsung/Kconfig index c8aa73eb39c3..1e73f7079567 100644 --- a/sound/soc/samsung/Kconfig +++ b/sound/soc/samsung/Kconfig @@ -1,6 +1,6 @@ config ASOC_SAMSUNG tristate "ASoC support for Samsung" - depends on ARCH_S3C2410 || ARCH_S3C64XX || ARCH_S5PC100 || ARCH_S5PV210 || ARCH_S5P64X0 + depends on ARCH_S3C2410 || ARCH_S3C64XX || ARCH_S5PC100 || ARCH_S5PV210 || ARCH_S5P64X0 || ARCH_S5P6442 select S3C64XX_DMA if ARCH_S3C64XX select S3C2410_DMA if ARCH_S3C2410 help @@ -62,7 +62,7 @@ config ASOC_SAMSUNG_JIVE_WM8750 config ASOC_SAMSUNG_SMDK_WM8580 tristate "SoC I2S Audio support for WM8580 on SMDK" - depends on ASOC_SAMSUNG && (MACH_SMDK6410 || MACH_SMDKC100 || MACH_SMDK6440 || MACH_SMDK6450) + depends on ASOC_SAMSUNG && (MACH_SMDK6410 || MACH_SMDKC100 || MACH_SMDK6440 || MACH_SMDK6450 || MACH_SMDK6442) select SND_SOC_WM8580 select SND_SAMSUNG_I2S help diff --git a/sound/soc/samsung/smdk_wm8580.c b/sound/soc/samsung/smdk_wm8580.c index e4f3bc8c1248..c149f73adac8 100644 --- a/sound/soc/samsung/smdk_wm8580.c +++ b/sound/soc/samsung/smdk_wm8580.c @@ -254,7 +254,7 @@ static int __init smdk_audio_init(void) int ret; char *str; - if (machine_is_smdkc100()) { + if (machine_is_smdkc100() || machine_is_smdk6442()) { smdk.num_links = 3; /* Secondary is at offset SAMSUNG_I2S_SECOFF from Primary */ str = (char *)smdk_dai[SEC_PLAYBACK].cpu_dai_name; -- cgit v1.2.3 From e3bd3e182d0b936923445e03aa259b1d50d83a20 Mon Sep 17 00:00:00 2001 From: Jassi Brar Date: Mon, 20 Dec 2010 11:05:53 +0900 Subject: ASoC: SMDKV210: Enable I2S device Signed-off-by: Jassi Brar Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/samsung/Kconfig | 2 +- sound/soc/samsung/smdk_wm8580.c | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/sound/soc/samsung/Kconfig b/sound/soc/samsung/Kconfig index 1e73f7079567..e718ec1966f1 100644 --- a/sound/soc/samsung/Kconfig +++ b/sound/soc/samsung/Kconfig @@ -62,7 +62,7 @@ config ASOC_SAMSUNG_JIVE_WM8750 config ASOC_SAMSUNG_SMDK_WM8580 tristate "SoC I2S Audio support for WM8580 on SMDK" - depends on ASOC_SAMSUNG && (MACH_SMDK6410 || MACH_SMDKC100 || MACH_SMDK6440 || MACH_SMDK6450 || MACH_SMDK6442) + depends on ASOC_SAMSUNG && (MACH_SMDK6410 || MACH_SMDKC100 || MACH_SMDK6440 || MACH_SMDK6450 || MACH_SMDK6442 || MACH_SMDKV210) select SND_SOC_WM8580 select SND_SAMSUNG_I2S help diff --git a/sound/soc/samsung/smdk_wm8580.c b/sound/soc/samsung/smdk_wm8580.c index c149f73adac8..f37b9da69690 100644 --- a/sound/soc/samsung/smdk_wm8580.c +++ b/sound/soc/samsung/smdk_wm8580.c @@ -254,7 +254,8 @@ static int __init smdk_audio_init(void) int ret; char *str; - if (machine_is_smdkc100() || machine_is_smdk6442()) { + if (machine_is_smdkc100() || machine_is_smdk6442() + || machine_is_smdkv210()) { smdk.num_links = 3; /* Secondary is at offset SAMSUNG_I2S_SECOFF from Primary */ str = (char *)smdk_dai[SEC_PLAYBACK].cpu_dai_name; -- cgit v1.2.3 From 40d2482993d39f3b99973b6e94b358fa1e1f0679 Mon Sep 17 00:00:00 2001 From: Jassi Brar Date: Mon, 20 Dec 2010 11:05:55 +0900 Subject: ASoC: SMDKC110: Enable I2S device Signed-off-by: Jassi Brar Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/samsung/Kconfig | 2 +- sound/soc/samsung/smdk_wm8580.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/samsung/Kconfig b/sound/soc/samsung/Kconfig index e718ec1966f1..472951da79f8 100644 --- a/sound/soc/samsung/Kconfig +++ b/sound/soc/samsung/Kconfig @@ -62,7 +62,7 @@ config ASOC_SAMSUNG_JIVE_WM8750 config ASOC_SAMSUNG_SMDK_WM8580 tristate "SoC I2S Audio support for WM8580 on SMDK" - depends on ASOC_SAMSUNG && (MACH_SMDK6410 || MACH_SMDKC100 || MACH_SMDK6440 || MACH_SMDK6450 || MACH_SMDK6442 || MACH_SMDKV210) + depends on ASOC_SAMSUNG && (MACH_SMDK6410 || MACH_SMDKC100 || MACH_SMDK6440 || MACH_SMDK6450 || MACH_SMDK6442 || MACH_SMDKV210 || MACH_SMDKC110) select SND_SOC_WM8580 select SND_SAMSUNG_I2S help diff --git a/sound/soc/samsung/smdk_wm8580.c b/sound/soc/samsung/smdk_wm8580.c index f37b9da69690..b2cff1a44aed 100644 --- a/sound/soc/samsung/smdk_wm8580.c +++ b/sound/soc/samsung/smdk_wm8580.c @@ -255,7 +255,7 @@ static int __init smdk_audio_init(void) char *str; if (machine_is_smdkc100() || machine_is_smdk6442() - || machine_is_smdkv210()) { + || machine_is_smdkv210() || machine_is_smdkc110()) { smdk.num_links = 3; /* Secondary is at offset SAMSUNG_I2S_SECOFF from Primary */ str = (char *)smdk_dai[SEC_PLAYBACK].cpu_dai_name; -- cgit v1.2.3 From 4d81acff4099ae5eccd113f10e8038b65b1fc638 Mon Sep 17 00:00:00 2001 From: Jassi Brar Date: Mon, 20 Dec 2010 11:05:56 +0900 Subject: ASoC: SMDKV310: Enable AC97 device Enable AC97 audio device on SMDKV310/C210. Signed-off-by: Jassi Brar Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/samsung/Kconfig | 4 ++-- sound/soc/samsung/smdk_wm9713.c | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/sound/soc/samsung/Kconfig b/sound/soc/samsung/Kconfig index 472951da79f8..9cedf345933c 100644 --- a/sound/soc/samsung/Kconfig +++ b/sound/soc/samsung/Kconfig @@ -1,6 +1,6 @@ config ASOC_SAMSUNG tristate "ASoC support for Samsung" - depends on ARCH_S3C2410 || ARCH_S3C64XX || ARCH_S5PC100 || ARCH_S5PV210 || ARCH_S5P64X0 || ARCH_S5P6442 + depends on ARCH_S3C2410 || ARCH_S3C64XX || ARCH_S5PC100 || ARCH_S5PV210 || ARCH_S5P64X0 || ARCH_S5P6442 || ARCH_S5PV310 select S3C64XX_DMA if ARCH_S3C64XX select S3C2410_DMA if ARCH_S3C2410 help @@ -134,7 +134,7 @@ config ASOC_SAMSUNG_RX1950_UDA1380 config ASOC_SAMSUNG_SMDK_WM9713 tristate "SoC AC97 Audio support for SMDK with WM9713" - depends on ASOC_SAMSUNG && (MACH_SMDK6410 || MACH_SMDKC100 || MACH_SMDKV210 || MACH_SMDKC110) + depends on ASOC_SAMSUNG && (MACH_SMDK6410 || MACH_SMDKC100 || MACH_SMDKV210 || MACH_SMDKC110 || MACH_SMDKV310 || MACH_SMDKC210) select SND_SOC_WM9713 select SND_SAMSUNG_AC97 help diff --git a/sound/soc/samsung/smdk_wm9713.c b/sound/soc/samsung/smdk_wm9713.c index 238cb3a38c5d..ae5fed6f772f 100644 --- a/sound/soc/samsung/smdk_wm9713.c +++ b/sound/soc/samsung/smdk_wm9713.c @@ -27,6 +27,7 @@ static struct snd_soc_card smdk; * SMDKC100: Set CFG6 1-3 On, CFG7 1 On * SMDKC110: Set CFGB10 1-2 Off, CFGB12 1-3 On * SMDKV210: Set CFGB10 1-2 Off, CFGB12 1-3 On + * SMDKV310: Set CFG2 1-2 Off, CFG4 All On, CFG7 All Off, CFG8 1-On */ /* -- cgit v1.2.3 From 96657d33b9ba4e7bd3728ee319ed96ed3f09c40b Mon Sep 17 00:00:00 2001 From: Jassi Brar Date: Mon, 20 Dec 2010 11:05:57 +0900 Subject: ASoC: SMDKV310: Add I2S support Add ASoC machine driver for SMDKV310/C210 boards that have a WM8994 attached to I2S-0. Signed-off-by: Jassi Brar Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/samsung/Kconfig | 8 ++ sound/soc/samsung/Makefile | 2 + sound/soc/samsung/smdk_wm8994.c | 176 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 186 insertions(+) create mode 100644 sound/soc/samsung/smdk_wm8994.c diff --git a/sound/soc/samsung/Kconfig b/sound/soc/samsung/Kconfig index 9cedf345933c..11ff4adf9901 100644 --- a/sound/soc/samsung/Kconfig +++ b/sound/soc/samsung/Kconfig @@ -68,6 +68,14 @@ config ASOC_SAMSUNG_SMDK_WM8580 help Say Y if you want to add support for SoC audio on the SMDKs. +config ASOC_SAMSUNG_SMDK_WM8994 + tristate "SoC I2S Audio support for WM8994 on SMDK" + depends on ASOC_SAMSUNG && (MACH_SMDKV310 || MACH_SMDKC210) + select SND_SOC_WM8994 + select SND_SAMSUNG_I2S + help + Say Y if you want to add support for SoC audio on the SMDKs. + config ASOC_SAMSUNG_SMDK2443_WM9710 tristate "SoC AC97 Audio support for SMDK2443 - WM9710" depends on ASOC_SAMSUNG && MACH_SMDK2443 diff --git a/sound/soc/samsung/Makefile b/sound/soc/samsung/Makefile index 622e76eb9775..fe694cc5c3a3 100644 --- a/sound/soc/samsung/Makefile +++ b/sound/soc/samsung/Makefile @@ -30,6 +30,7 @@ snd-soc-s3c24xx-simtec-tlv320aic23-objs := s3c24xx_simtec_tlv320aic23.o snd-soc-h1940-uda1380-objs := h1940_uda1380.o snd-soc-rx1950-uda1380-objs := rx1950_uda1380.o snd-soc-smdk-wm8580-objs := smdk_wm8580.o +snd-soc-smdk-wm8994-objs := smdk_wm8994.o snd-soc-smdk-wm9713-objs := smdk_wm9713.o snd-soc-s3c64xx-smartq-wm8987-objs := smartq_wm8987.o snd-soc-goni-wm8994-objs := goni_wm8994.o @@ -47,6 +48,7 @@ obj-$(CONFIG_ASOC_SAMSUNG_SIMTEC_TLV320AIC23) += snd-soc-s3c24xx-simtec-tlv320ai obj-$(CONFIG_ASOC_SAMSUNG_H1940_UDA1380) += snd-soc-h1940-uda1380.o obj-$(CONFIG_ASOC_SAMSUNG_RX1950_UDA1380) += snd-soc-rx1950-uda1380.o obj-$(CONFIG_ASOC_SAMSUNG_SMDK_WM8580) += snd-soc-smdk-wm8580.o +obj-$(CONFIG_ASOC_SAMSUNG_SMDK_WM8994) += snd-soc-smdk-wm8994.o obj-$(CONFIG_ASOC_SAMSUNG_SMDK_WM9713) += snd-soc-smdk-wm9713.o obj-$(CONFIG_ASOC_SMARTQ) += snd-soc-s3c64xx-smartq-wm8987.o obj-$(CONFIG_ASOC_SAMSUNG_SMDK_SPDIF) += snd-soc-smdk-spdif.o diff --git a/sound/soc/samsung/smdk_wm8994.c b/sound/soc/samsung/smdk_wm8994.c new file mode 100644 index 000000000000..e7c1009a1e1d --- /dev/null +++ b/sound/soc/samsung/smdk_wm8994.c @@ -0,0 +1,176 @@ +/* + * smdk_wm8994.c + * + * 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. + */ + +#include "../codecs/wm8994.h" + + /* + * Default CFG switch settings to use this driver: + * SMDKV310: CFG5-1000, CFG7-111111 + */ + + /* + * Configure audio route as :- + * $ amixer sset 'DAC1' on,on + * $ amixer sset 'Right Headphone Mux' 'DAC' + * $ amixer sset 'Left Headphone Mux' 'DAC' + * $ amixer sset 'DAC1R Mixer AIF1.1' on + * $ amixer sset 'DAC1L Mixer AIF1.1' on + * $ amixer sset 'IN2L' on + * $ amixer sset 'IN2L PGA IN2LN' on + * $ amixer sset 'MIXINL IN2L' on + * $ amixer sset 'AIF1ADC1L Mixer ADC/DMIC' on + * $ amixer sset 'IN2R' on + * $ amixer sset 'IN2R PGA IN2RN' on + * $ amixer sset 'MIXINR IN2R' on + * $ amixer sset 'AIF1ADC1R Mixer ADC/DMIC' on + */ + +/* SMDK has a 16.934MHZ crystal attached to WM8994 */ +#define SMDK_WM8994_FREQ 16934000 + +static int smdk_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + struct snd_soc_dai *codec_dai = rtd->codec_dai; + unsigned int pll_out; + int ret; + + /* AIF1CLK should be >=3MHz for optimal performance */ + if (params_rate(params) == 8000 || params_rate(params) == 11025) + pll_out = params_rate(params) * 512; + else + pll_out = params_rate(params) * 256; + + ret = snd_soc_dai_set_fmt(codec_dai, SND_SOC_DAIFMT_I2S + | SND_SOC_DAIFMT_NB_NF + | SND_SOC_DAIFMT_CBM_CFM); + if (ret < 0) + return ret; + + ret = snd_soc_dai_set_fmt(cpu_dai, SND_SOC_DAIFMT_I2S + | SND_SOC_DAIFMT_NB_NF + | SND_SOC_DAIFMT_CBM_CFM); + if (ret < 0) + return ret; + + ret = snd_soc_dai_set_pll(codec_dai, WM8994_FLL1, WM8994_FLL_SRC_MCLK1, + SMDK_WM8994_FREQ, pll_out); + if (ret < 0) + return ret; + + ret = snd_soc_dai_set_sysclk(codec_dai, WM8994_SYSCLK_FLL1, + pll_out, SND_SOC_CLOCK_IN); + if (ret < 0) + return ret; + + return 0; +} + +/* + * SMDK WM8994 DAI operations. + */ +static struct snd_soc_ops smdk_ops = { + .hw_params = smdk_hw_params, +}; + +static int smdk_wm8994_init_paiftx(struct snd_soc_pcm_runtime *rtd) +{ + struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_dapm_context *dapm = &codec->dapm; + + /* HeadPhone */ + snd_soc_dapm_enable_pin(dapm, "HPOUT1R"); + snd_soc_dapm_enable_pin(dapm, "HPOUT1L"); + + /* MicIn */ + snd_soc_dapm_enable_pin(dapm, "IN1LN"); + snd_soc_dapm_enable_pin(dapm, "IN1RN"); + + /* LineIn */ + snd_soc_dapm_enable_pin(dapm, "IN2LN"); + snd_soc_dapm_enable_pin(dapm, "IN2RN"); + + /* Other pins NC */ + snd_soc_dapm_nc_pin(dapm, "HPOUT2P"); + snd_soc_dapm_nc_pin(dapm, "HPOUT2N"); + snd_soc_dapm_nc_pin(dapm, "SPKOUTLN"); + snd_soc_dapm_nc_pin(dapm, "SPKOUTLP"); + snd_soc_dapm_nc_pin(dapm, "SPKOUTRP"); + snd_soc_dapm_nc_pin(dapm, "SPKOUTRN"); + snd_soc_dapm_nc_pin(dapm, "LINEOUT1N"); + snd_soc_dapm_nc_pin(dapm, "LINEOUT1P"); + snd_soc_dapm_nc_pin(dapm, "LINEOUT2N"); + snd_soc_dapm_nc_pin(dapm, "LINEOUT2P"); + snd_soc_dapm_nc_pin(dapm, "IN1LP"); + snd_soc_dapm_nc_pin(dapm, "IN2LP:VXRN"); + snd_soc_dapm_nc_pin(dapm, "IN1RP"); + snd_soc_dapm_nc_pin(dapm, "IN2RP:VXRP"); + + snd_soc_dapm_sync(dapm); + + return 0; +} + +static struct snd_soc_dai_link smdk_dai[] = { + { /* Primary DAI i/f */ + .name = "WM8994 AIF1", + .stream_name = "Pri_Dai", + .cpu_dai_name = "samsung-i2s.0", + .codec_dai_name = "wm8994-aif1", + .platform_name = "samsung-audio", + .codec_name = "wm8994-codec", + .init = smdk_wm8994_init_paiftx, + .ops = &smdk_ops, + }, { /* Sec_Fifo Playback i/f */ + .name = "Sec_FIFO TX", + .stream_name = "Sec_Dai", + .cpu_dai_name = "samsung-i2s.4", + .codec_dai_name = "wm8994-aif1", + .platform_name = "samsung-audio", + .codec_name = "wm8994-codec", + .ops = &smdk_ops, + }, +}; + +static struct snd_soc_card smdk = { + .name = "SMDK-I2S", + .dai_link = smdk_dai, + .num_links = ARRAY_SIZE(smdk_dai), +}; + +static struct platform_device *smdk_snd_device; + +static int __init smdk_audio_init(void) +{ + int ret; + + smdk_snd_device = platform_device_alloc("soc-audio", -1); + if (!smdk_snd_device) + return -ENOMEM; + + platform_set_drvdata(smdk_snd_device, &smdk); + + ret = platform_device_add(smdk_snd_device); + if (ret) + platform_device_put(smdk_snd_device); + + return ret; +} +module_init(smdk_audio_init); + +static void __exit smdk_audio_exit(void) +{ + platform_device_unregister(smdk_snd_device); +} +module_exit(smdk_audio_exit); + +MODULE_DESCRIPTION("ALSA SoC SMDK WM8994"); +MODULE_LICENSE("GPL"); -- cgit v1.2.3 From 28c4edb71d21623f1e47422194d865d2b6712fd4 Mon Sep 17 00:00:00 2001 From: David Henningsson Date: Mon, 20 Dec 2010 14:24:29 +0100 Subject: ALSA: HDA: Rename "Int Mic" to "Internal Mic" "Int Mic" and "Internal Mic" both mean the same thing, so rename the former to the latter in order to clean up the namespace a little. Signed-off-by: David Henningsson Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_conexant.c | 36 ++++++++++----------- sound/pci/hda/patch_realtek.c | 72 +++++++++++++++++++++--------------------- 2 files changed, 54 insertions(+), 54 deletions(-) diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index e584b3dd7aa8..62acf10cf493 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c @@ -869,14 +869,14 @@ static void cxt5045_hp_unsol_event(struct hda_codec *codec, } static struct snd_kcontrol_new cxt5045_mixers[] = { - HDA_CODEC_VOLUME("Int Mic Capture Volume", 0x1a, 0x01, HDA_INPUT), - HDA_CODEC_MUTE("Int Mic Capture Switch", 0x1a, 0x01, HDA_INPUT), + HDA_CODEC_VOLUME("Internal Mic Capture Volume", 0x1a, 0x01, HDA_INPUT), + HDA_CODEC_MUTE("Internal Mic Capture Switch", 0x1a, 0x01, HDA_INPUT), HDA_CODEC_VOLUME("Ext Mic Capture Volume", 0x1a, 0x02, HDA_INPUT), HDA_CODEC_MUTE("Ext Mic Capture Switch", 0x1a, 0x02, HDA_INPUT), HDA_CODEC_VOLUME("PCM Playback Volume", 0x17, 0x0, HDA_INPUT), HDA_CODEC_MUTE("PCM Playback Switch", 0x17, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x17, 0x1, HDA_INPUT), - HDA_CODEC_MUTE("Int Mic Playback Switch", 0x17, 0x1, HDA_INPUT), + HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x17, 0x1, HDA_INPUT), + HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x17, 0x1, HDA_INPUT), HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x17, 0x2, HDA_INPUT), HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x17, 0x2, HDA_INPUT), HDA_BIND_VOL("Master Playback Volume", &cxt5045_hp_bind_master_vol), @@ -910,14 +910,14 @@ static struct snd_kcontrol_new cxt5045_benq_mixers[] = { }; static struct snd_kcontrol_new cxt5045_mixers_hp530[] = { - HDA_CODEC_VOLUME("Int Mic Capture Volume", 0x1a, 0x02, HDA_INPUT), - HDA_CODEC_MUTE("Int Mic Capture Switch", 0x1a, 0x02, HDA_INPUT), + HDA_CODEC_VOLUME("Internal Mic Capture Volume", 0x1a, 0x02, HDA_INPUT), + HDA_CODEC_MUTE("Internal Mic Capture Switch", 0x1a, 0x02, HDA_INPUT), HDA_CODEC_VOLUME("Ext Mic Capture Volume", 0x1a, 0x01, HDA_INPUT), HDA_CODEC_MUTE("Ext Mic Capture Switch", 0x1a, 0x01, HDA_INPUT), HDA_CODEC_VOLUME("PCM Playback Volume", 0x17, 0x0, HDA_INPUT), HDA_CODEC_MUTE("PCM Playback Switch", 0x17, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x17, 0x2, HDA_INPUT), - HDA_CODEC_MUTE("Int Mic Playback Switch", 0x17, 0x2, HDA_INPUT), + HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x17, 0x2, HDA_INPUT), + HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x17, 0x2, HDA_INPUT), HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x17, 0x1, HDA_INPUT), HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x17, 0x1, HDA_INPUT), HDA_BIND_VOL("Master Playback Volume", &cxt5045_hp_bind_master_vol), @@ -947,7 +947,7 @@ static struct hda_verb cxt5045_init_verbs[] = { {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, - /* Record selector: Int mic */ + /* Record selector: Internal mic */ {0x1a, AC_VERB_SET_CONNECT_SEL,0x1}, {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AC_AMP_SET_INPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x17}, @@ -960,7 +960,7 @@ static struct hda_verb cxt5045_init_verbs[] = { }; static struct hda_verb cxt5045_benq_init_verbs[] = { - /* Int Mic, Mic */ + /* Internal Mic, Mic */ {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_80 }, {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_80 }, /* Line In,HP, Amp */ @@ -973,7 +973,7 @@ static struct hda_verb cxt5045_benq_init_verbs[] = { {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, - /* Record selector: Int mic */ + /* Record selector: Internal mic */ {0x1a, AC_VERB_SET_CONNECT_SEL, 0x1}, {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AC_AMP_SET_INPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x17}, @@ -1847,7 +1847,7 @@ static struct hda_verb cxt5051_init_verbs[] = { {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */ {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, - /* Record selector: Int mic */ + /* Record selector: Internal mic */ {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x44}, {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1) | 0x44}, {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x44}, @@ -1874,7 +1874,7 @@ static struct hda_verb cxt5051_hp_dv6736_init_verbs[] = { {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */ {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, - /* Record selector: Int mic */ + /* Record selector: Internal mic */ {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1) | 0x44}, {0x14, AC_VERB_SET_CONNECT_SEL, 0x1}, /* SPDIF route: PCM */ @@ -1904,7 +1904,7 @@ static struct hda_verb cxt5051_lenovo_x200_init_verbs[] = { {0x19, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */ {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, - /* Record selector: Int mic */ + /* Record selector: Internal mic */ {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x44}, {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1) | 0x44}, {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x44}, @@ -1932,7 +1932,7 @@ static struct hda_verb cxt5051_f700_init_verbs[] = { {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */ {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, - /* Record selector: Int mic */ + /* Record selector: Internal mic */ {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1) | 0x44}, {0x14, AC_VERB_SET_CONNECT_SEL, 0x1}, /* SPDIF route: PCM */ @@ -2729,7 +2729,7 @@ static struct snd_kcontrol_new cxt5066_mixers[] = { static struct snd_kcontrol_new cxt5066_vostro_mixers[] = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Int Mic Boost Capture Enum", + .name = "Internal Mic Boost Capture Enum", .info = cxt5066_mic_boost_mux_enum_info, .get = cxt5066_mic_boost_mux_enum_get, .put = cxt5066_mic_boost_mux_enum_put, @@ -2955,7 +2955,7 @@ static struct hda_verb cxt5066_init_verbs_ideapad[] = { {0x22, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* internal microphone */ - {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* enable int mic */ + {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* enable internal mic */ /* EAPD */ {0x1d, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */ @@ -3010,7 +3010,7 @@ static struct hda_verb cxt5066_init_verbs_thinkpad[] = { {0x22, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* internal microphone */ - {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* enable int mic */ + {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* enable internal mic */ /* EAPD */ {0x1d, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */ diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 5baaf12111ba..e976a4ddb0c3 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -2169,7 +2169,7 @@ static struct hda_input_mux alc888_acer_aspire_6530_sources[2] = { { "Line In", 0x2 }, { "CD", 0x4 }, { "Input Mix", 0xa }, - { "Int Mic", 0xb }, + { "Internal Mic", 0xb }, }, }, { @@ -2843,8 +2843,8 @@ static struct snd_kcontrol_new alc880_fujitsu_mixer[] = { HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), - HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), + HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), + HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), { } /* end */ }; @@ -7451,7 +7451,7 @@ static struct hda_input_mux alc883_lenovo_nb0763_capture_source = { .num_items = 4, .items = { { "Mic", 0x0 }, - { "Int Mic", 0x1 }, + { "Internal Mic", 0x1 }, { "Line", 0x2 }, { "CD", 0x4 }, }, @@ -7461,7 +7461,7 @@ static struct hda_input_mux alc883_fujitsu_pi2515_capture_source = { .num_items = 2, .items = { { "Mic", 0x0 }, - { "Int Mic", 0x1 }, + { "Internal Mic", 0x1 }, }, }; @@ -8824,9 +8824,9 @@ static struct snd_kcontrol_new alc883_clevo_m720_mixer[] = { HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), - HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT), - HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), + HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), + HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT), + HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), { } /* end */ }; @@ -8838,9 +8838,9 @@ static struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = { HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), - HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT), - HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), + HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), + HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT), + HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), { } /* end */ }; @@ -8986,18 +8986,18 @@ static struct snd_kcontrol_new alc883_targa_2ch_mixer[] = { HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), - HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT), - HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), + HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), + HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT), + HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), { } /* end */ }; static struct snd_kcontrol_new alc883_targa_8ch_mixer[] = { HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT), HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), - HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), - HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT), - HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), + HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), + HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT), + HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), { } /* end */ }; @@ -9021,8 +9021,8 @@ static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = { HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), - HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), + HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), + HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), { } /* end */ }; @@ -11676,7 +11676,7 @@ static struct hda_input_mux alc262_fujitsu_capture_source = { .num_items = 3, .items = { { "Mic", 0x0 }, - { "Int Mic", 0x1 }, + { "Internal Mic", 0x1 }, { "CD", 0x4 }, }, }; @@ -11831,9 +11831,9 @@ static struct snd_kcontrol_new alc262_fujitsu_mixer[] = { HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT), - HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), - HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), + HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), + HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), { } /* end */ }; @@ -11867,9 +11867,9 @@ static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = { HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT), - HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), - HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), + HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), + HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), { } /* end */ }; @@ -13248,7 +13248,7 @@ static struct snd_kcontrol_new alc267_quanta_il1_mixer[] = { HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT), HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT), HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT), - HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT), { } }; @@ -16381,7 +16381,7 @@ static struct hda_input_mux alc861vd_dallas_capture_source = { .num_items = 2, .items = { { "Ext Mic", 0x0 }, - { "Int Mic", 0x1 }, + { "Internal Mic", 0x1 }, }, }; @@ -16522,7 +16522,7 @@ static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = { }; /* Pin assignment: Speaker=0x14, HP = 0x15, - * Ext Mic=0x18, Int Mic = 0x19, CD = 0x1c, PC Beep = 0x1d + * Ext Mic=0x18, Internal Mic = 0x19, CD = 0x1c, PC Beep = 0x1d */ static struct snd_kcontrol_new alc861vd_dallas_mixer[] = { HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), @@ -16532,9 +16532,9 @@ static struct snd_kcontrol_new alc861vd_dallas_mixer[] = { HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT), HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT), - HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), - HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), + HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), + HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), { } /* end */ }; @@ -18551,9 +18551,9 @@ static struct snd_kcontrol_new alc272_nc10_mixer[] = { HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT), - HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), - HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), - HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), + HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), + HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT), { } /* end */ }; @@ -19596,7 +19596,7 @@ static struct snd_kcontrol_new alc680_base_mixer[] = { HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("Headphone Playback Volume", 0x4, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Headphone Playback Switch", 0x16, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("Int Mic Boost", 0x12, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Internal Mic Boost", 0x12, 0, HDA_INPUT), HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), HDA_CODEC_VOLUME("Line In Boost", 0x19, 0, HDA_INPUT), { } -- cgit v1.2.3 From 8607f7c4245bc1737989d908e9c5adbfe4f5d06d Mon Sep 17 00:00:00 2001 From: David Henningsson Date: Mon, 20 Dec 2010 14:43:54 +0100 Subject: ALSA: HDA: Rename "Ext Mic" and "External Mic" to "Mic" Usually external microphones are just labelled "Mic", so rename "Ext Mic" and "External Mic" to "Mic" to clear up the namespace. Signed-off-by: David Henningsson Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_conexant.c | 28 ++++++++++++++-------------- sound/pci/hda/patch_realtek.c | 26 +++++++++++++------------- 2 files changed, 27 insertions(+), 27 deletions(-) diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index 62acf10cf493..74291f744c68 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c @@ -871,14 +871,14 @@ static void cxt5045_hp_unsol_event(struct hda_codec *codec, static struct snd_kcontrol_new cxt5045_mixers[] = { HDA_CODEC_VOLUME("Internal Mic Capture Volume", 0x1a, 0x01, HDA_INPUT), HDA_CODEC_MUTE("Internal Mic Capture Switch", 0x1a, 0x01, HDA_INPUT), - HDA_CODEC_VOLUME("Ext Mic Capture Volume", 0x1a, 0x02, HDA_INPUT), - HDA_CODEC_MUTE("Ext Mic Capture Switch", 0x1a, 0x02, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Capture Volume", 0x1a, 0x02, HDA_INPUT), + HDA_CODEC_MUTE("Mic Capture Switch", 0x1a, 0x02, HDA_INPUT), HDA_CODEC_VOLUME("PCM Playback Volume", 0x17, 0x0, HDA_INPUT), HDA_CODEC_MUTE("PCM Playback Switch", 0x17, 0x0, HDA_INPUT), HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x17, 0x1, HDA_INPUT), HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x17, 0x1, HDA_INPUT), - HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x17, 0x2, HDA_INPUT), - HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x17, 0x2, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Playback Volume", 0x17, 0x2, HDA_INPUT), + HDA_CODEC_MUTE("Mic Playback Switch", 0x17, 0x2, HDA_INPUT), HDA_BIND_VOL("Master Playback Volume", &cxt5045_hp_bind_master_vol), { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, @@ -912,14 +912,14 @@ static struct snd_kcontrol_new cxt5045_benq_mixers[] = { static struct snd_kcontrol_new cxt5045_mixers_hp530[] = { HDA_CODEC_VOLUME("Internal Mic Capture Volume", 0x1a, 0x02, HDA_INPUT), HDA_CODEC_MUTE("Internal Mic Capture Switch", 0x1a, 0x02, HDA_INPUT), - HDA_CODEC_VOLUME("Ext Mic Capture Volume", 0x1a, 0x01, HDA_INPUT), - HDA_CODEC_MUTE("Ext Mic Capture Switch", 0x1a, 0x01, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Capture Volume", 0x1a, 0x01, HDA_INPUT), + HDA_CODEC_MUTE("Mic Capture Switch", 0x1a, 0x01, HDA_INPUT), HDA_CODEC_VOLUME("PCM Playback Volume", 0x17, 0x0, HDA_INPUT), HDA_CODEC_MUTE("PCM Playback Switch", 0x17, 0x0, HDA_INPUT), HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x17, 0x2, HDA_INPUT), HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x17, 0x2, HDA_INPUT), - HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x17, 0x1, HDA_INPUT), - HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x17, 0x1, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Playback Volume", 0x17, 0x1, HDA_INPUT), + HDA_CODEC_MUTE("Mic Playback Switch", 0x17, 0x1, HDA_INPUT), HDA_BIND_VOL("Master Playback Volume", &cxt5045_hp_bind_master_vol), { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, @@ -1796,8 +1796,8 @@ static struct snd_kcontrol_new cxt5051_playback_mixers[] = { static struct snd_kcontrol_new cxt5051_capture_mixers[] = { HDA_CODEC_VOLUME("Internal Mic Volume", 0x14, 0x00, HDA_INPUT), HDA_CODEC_MUTE("Internal Mic Switch", 0x14, 0x00, HDA_INPUT), - HDA_CODEC_VOLUME("External Mic Volume", 0x14, 0x01, HDA_INPUT), - HDA_CODEC_MUTE("External Mic Switch", 0x14, 0x01, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Volume", 0x14, 0x01, HDA_INPUT), + HDA_CODEC_MUTE("Mic Switch", 0x14, 0x01, HDA_INPUT), HDA_CODEC_VOLUME("Docking Mic Volume", 0x15, 0x00, HDA_INPUT), HDA_CODEC_MUTE("Docking Mic Switch", 0x15, 0x00, HDA_INPUT), {} @@ -1806,8 +1806,8 @@ static struct snd_kcontrol_new cxt5051_capture_mixers[] = { static struct snd_kcontrol_new cxt5051_hp_mixers[] = { HDA_CODEC_VOLUME("Internal Mic Volume", 0x14, 0x00, HDA_INPUT), HDA_CODEC_MUTE("Internal Mic Switch", 0x14, 0x00, HDA_INPUT), - HDA_CODEC_VOLUME("External Mic Volume", 0x15, 0x00, HDA_INPUT), - HDA_CODEC_MUTE("External Mic Switch", 0x15, 0x00, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Volume", 0x15, 0x00, HDA_INPUT), + HDA_CODEC_MUTE("Mic Switch", 0x15, 0x00, HDA_INPUT), {} }; @@ -1826,8 +1826,8 @@ static struct snd_kcontrol_new cxt5051_f700_mixers[] = { static struct snd_kcontrol_new cxt5051_toshiba_mixers[] = { HDA_CODEC_VOLUME("Internal Mic Volume", 0x14, 0x00, HDA_INPUT), HDA_CODEC_MUTE("Internal Mic Switch", 0x14, 0x00, HDA_INPUT), - HDA_CODEC_VOLUME("External Mic Volume", 0x14, 0x01, HDA_INPUT), - HDA_CODEC_MUTE("External Mic Switch", 0x14, 0x01, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Volume", 0x14, 0x01, HDA_INPUT), + HDA_CODEC_MUTE("Mic Switch", 0x14, 0x01, HDA_INPUT), {} }; diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index e976a4ddb0c3..fceb1e60b352 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -2165,7 +2165,7 @@ static struct hda_input_mux alc888_acer_aspire_6530_sources[2] = { { .num_items = 5, .items = { - { "Ext Mic", 0x0 }, + { "Mic", 0x0 }, { "Line In", 0x2 }, { "CD", 0x4 }, { "Input Mix", 0xa }, @@ -2175,7 +2175,7 @@ static struct hda_input_mux alc888_acer_aspire_6530_sources[2] = { { .num_items = 4, .items = { - { "Ext Mic", 0x0 }, + { "Mic", 0x0 }, { "Line In", 0x2 }, { "CD", 0x4 }, { "Input Mix", 0xa }, @@ -2841,8 +2841,8 @@ static struct snd_kcontrol_new alc880_fujitsu_mixer[] = { HDA_BIND_MUTE("Speaker Playback Switch", 0x0d, 2, HDA_INPUT), HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), - HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), + HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), { } /* end */ @@ -13247,7 +13247,7 @@ static struct snd_kcontrol_new alc267_quanta_il1_mixer[] = { HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("Mic Capture Volume", 0x23, 0x0, HDA_OUTPUT), HDA_BIND_MUTE("Mic Capture Switch", 0x23, 2, HDA_OUTPUT), - HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT), { } }; @@ -16380,7 +16380,7 @@ static struct hda_input_mux alc861vd_capture_source = { static struct hda_input_mux alc861vd_dallas_capture_source = { .num_items = 2, .items = { - { "Ext Mic", 0x0 }, + { "Mic", 0x0 }, { "Internal Mic", 0x1 }, }, }; @@ -16522,16 +16522,16 @@ static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = { }; /* Pin assignment: Speaker=0x14, HP = 0x15, - * Ext Mic=0x18, Internal Mic = 0x19, CD = 0x1c, PC Beep = 0x1d + * Mic=0x18, Internal Mic = 0x19, CD = 0x1c, PC Beep = 0x1d */ static struct snd_kcontrol_new alc861vd_dallas_mixer[] = { HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT), HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), HDA_BIND_MUTE("Headphone Playback Switch", 0x0d, 2, HDA_INPUT), - HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT), - HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), + HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT), HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), @@ -18547,9 +18547,9 @@ static struct snd_kcontrol_new alc272_nc10_mixer[] = { HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("Ext Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_MUTE("Ext Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Ext Mic Boost", 0x18, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), + HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), -- cgit v1.2.3 From 10528020d7323778b60c2de04754a2615a88d002 Mon Sep 17 00:00:00 2001 From: David Henningsson Date: Mon, 20 Dec 2010 14:50:59 +0100 Subject: ALSA: HDA: Rename "e-Mic" and "i-Mic" to "Mic" and "Internal Mic" Change non-standard mic control names to standard control names to clean up the namespace. Signed-off-by: David Henningsson Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index fceb1e60b352..cad88f476acc 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -17534,13 +17534,13 @@ static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = { HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT), ALC262_HIPPO_MASTER_SWITCH, - HDA_CODEC_VOLUME("e-Mic Boost", 0x18, 0, HDA_INPUT), - HDA_CODEC_VOLUME("e-Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_MUTE("e-Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), + HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT), - HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), - HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), + HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), + HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), { } /* end */ }; @@ -17684,8 +17684,8 @@ static struct snd_kcontrol_new alc663_g71v_mixer[] = { HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), - HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), + HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), + HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), { } /* end */ }; @@ -17696,8 +17696,8 @@ static struct snd_kcontrol_new alc663_g50v_mixer[] = { HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), - HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), + HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), + HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), { } /* end */ @@ -18530,13 +18530,13 @@ static struct snd_kcontrol_new alc662_ecs_mixer[] = { HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT), ALC262_HIPPO_MASTER_SWITCH, - HDA_CODEC_VOLUME("e-Mic/LineIn Boost", 0x18, 0, HDA_INPUT), - HDA_CODEC_VOLUME("e-Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_MUTE("e-Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT), + HDA_CODEC_VOLUME("Mic/LineIn Boost", 0x18, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT), + HDA_CODEC_MUTE("Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT), - HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), - HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), + HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), + HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), { } /* end */ }; -- cgit v1.2.3 From 6e5f6856427abe5418f535cb46c454ae8ea7f8e7 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 25 Aug 2010 12:22:40 +0200 Subject: checksyscalls: Fix stand-alone usage The usage help in the comments - refers to the wrong script name, - doesn't mention that $srctree must be set. Hence correct the script name, and derive the source tree path from the script path, so we no longer need to rely on $srctree being set by the caller. Signed-off-by: Geert Uytterhoeven Acked-by: Sam Ravnborg Signed-off-by: Michal Marek --- scripts/checksyscalls.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/checksyscalls.sh b/scripts/checksyscalls.sh index 6bb42e72e0e5..3ab316e52313 100755 --- a/scripts/checksyscalls.sh +++ b/scripts/checksyscalls.sh @@ -6,7 +6,7 @@ # and listed below so they are ignored. # # Usage: -# syscallchk gcc gcc-options +# checksyscalls.sh gcc gcc-options # ignore_list() { @@ -204,5 +204,5 @@ sed -n -e '/^\#define/ s/[^_]*__NR_\([^[:space:]]*\).*/\ \#endif/p' $1 } -(ignore_list && syscall_list ${srctree}/arch/x86/include/asm/unistd_32.h) | \ +(ignore_list && syscall_list $(dirname $0)/../arch/x86/include/asm/unistd_32.h) | \ $* -E -x c - > /dev/null -- cgit v1.2.3 From 55f88eccf9c288eed2f93f9ca7d7fe4dd2da762e Mon Sep 17 00:00:00 2001 From: Asbjoern Sloth Toennesen Date: Sun, 12 Dec 2010 17:39:40 +0000 Subject: kbuild, deb-pkg: support overriding userland architecture Usefull if building for sparc64 userland, because the sparc and sparc64 userlands use the same 64-bit kernel, making it impossible to always select the correct userland architecture for the resulting debian package. Might also be usefull, if you want a i386 userland with a amd64 kernel. Example usage: make KBUILD_DEBARCH=i386 deb-pkg LKML-reference: Signed-off-by: Asbjoern Sloth Toennesen Reviewed-by: WANG Cong Acked-by: maximilian attems Signed-off-by: Michal Marek --- Documentation/kbuild/kbuild.txt | 8 ++++++++ scripts/package/builddeb | 3 +++ 2 files changed, 11 insertions(+) diff --git a/Documentation/kbuild/kbuild.txt b/Documentation/kbuild/kbuild.txt index 634c625da8ce..b146eb86e498 100644 --- a/Documentation/kbuild/kbuild.txt +++ b/Documentation/kbuild/kbuild.txt @@ -51,6 +51,14 @@ Specify the output directory when building the kernel. The output directory can also be specificed using "O=...". Setting "O=..." takes precedence over KBUILD_OUTPUT. +KBUILD_DEBARCH +-------------------------------------------------- +For the deb-pkg target, allows overriding the normal heuristics deployed by +deb-pkg. Normally deb-pkg attempts to guess the right architecture based on +the UTS_MACHINE variable, and on some architectures also the kernel config. +The value of KBUILD_DEBARCH is assumed (not checked) to be a valid Debian +architecture. + ARCH -------------------------------------------------- Set ARCH to the architecture to be built. diff --git a/scripts/package/builddeb b/scripts/package/builddeb index 5d6be3f5e7f7..ffe24194b763 100644 --- a/scripts/package/builddeb +++ b/scripts/package/builddeb @@ -54,6 +54,9 @@ create_package() { echo "Please add support for $UTS_MACHINE to ${0} ..." >&2 echo "" >&2 esac + if [ -n "$KBUILD_DEBARCH" ] ; then + debarch="$KBUILD_DEBARCH" + fi if [ -n "$debarch" ] ; then forcearch="-DArchitecture=$debarch" fi -- cgit v1.2.3 From d095e23206e6291cbde4b2937d1316a42d9e6440 Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Mon, 20 Dec 2010 12:26:26 +0300 Subject: drm/nouveau: sizeof() vs ARRAY_SIZE() ARRAY_SIZE() was intended here, sizeof() is too large. Signed-off-by: Dan Carpenter Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nv50_vram.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/nouveau/nv50_vram.c b/drivers/gpu/drm/nouveau/nv50_vram.c index 47489ed0a5a8..58e98ad36347 100644 --- a/drivers/gpu/drm/nouveau/nv50_vram.c +++ b/drivers/gpu/drm/nouveau/nv50_vram.c @@ -42,7 +42,7 @@ nv50_vram_flags_valid(struct drm_device *dev, u32 tile_flags) { int type = (tile_flags & NOUVEAU_GEM_TILE_LAYOUT_MASK) >> 8; - if (likely(type < sizeof(types) && types[type])) + if (likely(type < ARRAY_SIZE(types) && types[type])) return true; return false; } -- cgit v1.2.3 From 910d1b3a8cec4fef20f11eb39e9ec6ac6e964b0e Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 21 Dec 2010 11:15:44 +1000 Subject: drm/nv50: fix smatch warning in nv50_vram.c Reported-by: Dan Carpenter Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nv50_vm.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/nouveau/nv50_vm.c b/drivers/gpu/drm/nouveau/nv50_vm.c index eebab95f59b2..7939387f7f80 100644 --- a/drivers/gpu/drm/nouveau/nv50_vm.c +++ b/drivers/gpu/drm/nouveau/nv50_vm.c @@ -91,7 +91,8 @@ void nv50_vm_map(struct nouveau_vma *vma, struct nouveau_gpuobj *pgt, struct nouveau_vram *mem, u32 pte, u32 cnt, u64 phys) { - u32 block, i; + u32 block; + int i; phys = nv50_vm_addr(vma, pgt, phys, mem->memtype, 0); pte <<= 3; -- cgit v1.2.3 From 147dc38e976f4dd6d888d585649e724a3e82a9b2 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Thu, 16 Dec 2010 13:32:36 +1000 Subject: drm/nv50: add missing license header to nv50_fbcon.c Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nv50_fbcon.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/drivers/gpu/drm/nouveau/nv50_fbcon.c b/drivers/gpu/drm/nouveau/nv50_fbcon.c index 6d38cb1488ae..791ded1c5c6d 100644 --- a/drivers/gpu/drm/nouveau/nv50_fbcon.c +++ b/drivers/gpu/drm/nouveau/nv50_fbcon.c @@ -1,3 +1,27 @@ +/* + * Copyright 2010 Red Hat Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: Ben Skeggs + */ + #include "drmP.h" #include "nouveau_drv.h" #include "nouveau_dma.h" -- cgit v1.2.3 From 6a5b3beff916a19e7672f8c0330b4f82ed367be2 Mon Sep 17 00:00:00 2001 From: Daniel De Graaf Date: Mon, 20 Dec 2010 14:56:09 -0800 Subject: xenbus: Fix memory leak on release Pending responses were leaked on close. Signed-off-by: Daniel De Graaf Signed-off-by: Jan Beulich Signed-off-by: Jeremy Fitzhardinge --- drivers/xen/xenfs/xenbus.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/xen/xenfs/xenbus.c b/drivers/xen/xenfs/xenbus.c index 55791dd1105f..8f6c7d4b3e4d 100644 --- a/drivers/xen/xenfs/xenbus.c +++ b/drivers/xen/xenfs/xenbus.c @@ -543,6 +543,7 @@ static int xenbus_file_release(struct inode *inode, struct file *filp) struct xenbus_file_priv *u = filp->private_data; struct xenbus_transaction_holder *trans, *tmp; struct watch_adapter *watch, *tmp_watch; + struct read_buffer *rb, *tmp_rb; /* * No need for locking here because there are no other users, @@ -561,6 +562,10 @@ static int xenbus_file_release(struct inode *inode, struct file *filp) free_watch_adapter(watch); } + list_for_each_entry_safe(rb, tmp_rb, &u->read_buffers, list) { + list_del(&rb->list); + kfree(rb); + } kfree(u); return 0; -- cgit v1.2.3 From 7c63dedcc52c8c1253b1deec387102ef788ed0b4 Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Mon, 20 Dec 2010 15:00:17 -0800 Subject: msm: qsd8x50: Platform data isn't init data Remove the SMC91x platform and resource data from initdata. These will continue to be accessed after init, and must remain available. Signed-off-by: Stephen Boyd Signed-off-by: David Brown --- arch/arm/mach-msm/board-qsd8x50.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-msm/board-qsd8x50.c b/arch/arm/mach-msm/board-qsd8x50.c index ed2af4ad97ed..39925c1a819d 100644 --- a/arch/arm/mach-msm/board-qsd8x50.c +++ b/arch/arm/mach-msm/board-qsd8x50.c @@ -42,7 +42,7 @@ static const unsigned qsd8x50_surf_smc91x_gpio __initdata = 156; * at run-time: they vary from board to board, and the true * configuration won't be known until boot. */ -static struct resource smc91x_resources[] __initdata = { +static struct resource smc91x_resources[] = { [0] = { .flags = IORESOURCE_MEM, }, @@ -51,7 +51,7 @@ static struct resource smc91x_resources[] __initdata = { }, }; -static struct platform_device smc91x_device __initdata = { +static struct platform_device smc91x_device = { .name = "smc91x", .id = 0, .num_resources = ARRAY_SIZE(smc91x_resources), -- cgit v1.2.3 From 3f16b9850743b702380f098ab5e0308cd6af1792 Mon Sep 17 00:00:00 2001 From: Dave Chinner Date: Tue, 21 Dec 2010 12:29:01 +1100 Subject: xfs: introduce new locks for the log grant ticket wait queues The log grant ticket wait queues are currently protected by the log grant lock. However, the queues are functionally independent from each other, and operations on them only require serialisation against other queue operations now that all of the other log variables they use are atomic values. Hence, we can make them independent of the grant lock by introducing new locks just to protect the lists operations. because the lists are independent, we can use a lock per list and ensure that reserve and write head queuing do not contend. To ensure forced shutdowns work correctly in conjunction with the new fast paths, ensure that we check whether the log has been shut down in the grant functions once we hold the relevant spin locks but before we go to sleep. This is needed to co-ordinate correctly with the wakeups that are issued on the ticket queues so we don't leave any processes sleeping on the queues during a shutdown. Signed-off-by: Dave Chinner Reviewed-by: Christoph Hellwig --- fs/xfs/linux-2.6/xfs_trace.h | 2 + fs/xfs/xfs_log.c | 139 ++++++++++++++++++++++++++----------------- fs/xfs/xfs_log_priv.h | 16 +++-- 3 files changed, 97 insertions(+), 60 deletions(-) diff --git a/fs/xfs/linux-2.6/xfs_trace.h b/fs/xfs/linux-2.6/xfs_trace.h index b180e1bf8257..647af2a2e7aa 100644 --- a/fs/xfs/linux-2.6/xfs_trace.h +++ b/fs/xfs/linux-2.6/xfs_trace.h @@ -837,6 +837,7 @@ DEFINE_LOGGRANT_EVENT(xfs_log_grant_sleep1); DEFINE_LOGGRANT_EVENT(xfs_log_grant_wake1); DEFINE_LOGGRANT_EVENT(xfs_log_grant_sleep2); DEFINE_LOGGRANT_EVENT(xfs_log_grant_wake2); +DEFINE_LOGGRANT_EVENT(xfs_log_grant_wake_up); DEFINE_LOGGRANT_EVENT(xfs_log_regrant_write_enter); DEFINE_LOGGRANT_EVENT(xfs_log_regrant_write_exit); DEFINE_LOGGRANT_EVENT(xfs_log_regrant_write_error); @@ -844,6 +845,7 @@ DEFINE_LOGGRANT_EVENT(xfs_log_regrant_write_sleep1); DEFINE_LOGGRANT_EVENT(xfs_log_regrant_write_wake1); DEFINE_LOGGRANT_EVENT(xfs_log_regrant_write_sleep2); DEFINE_LOGGRANT_EVENT(xfs_log_regrant_write_wake2); +DEFINE_LOGGRANT_EVENT(xfs_log_regrant_write_wake_up); DEFINE_LOGGRANT_EVENT(xfs_log_regrant_reserve_enter); DEFINE_LOGGRANT_EVENT(xfs_log_regrant_reserve_exit); DEFINE_LOGGRANT_EVENT(xfs_log_regrant_reserve_sub); diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c index a1d7d12fc51f..6fcc9d0af524 100644 --- a/fs/xfs/xfs_log.c +++ b/fs/xfs/xfs_log.c @@ -682,12 +682,12 @@ xfs_log_move_tail(xfs_mount_t *mp, if (tail_lsn != 1) atomic64_set(&log->l_tail_lsn, tail_lsn); - spin_lock(&log->l_grant_lock); - if (!list_empty(&log->l_writeq)) { + if (!list_empty_careful(&log->l_writeq)) { #ifdef DEBUG if (log->l_flags & XLOG_ACTIVE_RECOVERY) panic("Recovery problem"); #endif + spin_lock(&log->l_grant_write_lock); free_bytes = xlog_space_left(log, &log->l_grant_write_head); list_for_each_entry(tic, &log->l_writeq, t_queue) { ASSERT(tic->t_flags & XLOG_TIC_PERM_RESERV); @@ -696,15 +696,18 @@ xfs_log_move_tail(xfs_mount_t *mp, break; tail_lsn = 0; free_bytes -= tic->t_unit_res; + trace_xfs_log_regrant_write_wake_up(log, tic); wake_up(&tic->t_wait); } + spin_unlock(&log->l_grant_write_lock); } - if (!list_empty(&log->l_reserveq)) { + if (!list_empty_careful(&log->l_reserveq)) { #ifdef DEBUG if (log->l_flags & XLOG_ACTIVE_RECOVERY) panic("Recovery problem"); #endif + spin_lock(&log->l_grant_reserve_lock); free_bytes = xlog_space_left(log, &log->l_grant_reserve_head); list_for_each_entry(tic, &log->l_reserveq, t_queue) { if (tic->t_flags & XLOG_TIC_PERM_RESERV) @@ -715,11 +718,12 @@ xfs_log_move_tail(xfs_mount_t *mp, break; tail_lsn = 0; free_bytes -= need_bytes; + trace_xfs_log_grant_wake_up(log, tic); wake_up(&tic->t_wait); } + spin_unlock(&log->l_grant_reserve_lock); } - spin_unlock(&log->l_grant_lock); -} /* xfs_log_move_tail */ +} /* * Determine if we have a transaction that has gone to disk @@ -1010,6 +1014,8 @@ xlog_alloc_log(xfs_mount_t *mp, xlog_assign_grant_head(&log->l_grant_write_head, 1, 0); INIT_LIST_HEAD(&log->l_reserveq); INIT_LIST_HEAD(&log->l_writeq); + spin_lock_init(&log->l_grant_reserve_lock); + spin_lock_init(&log->l_grant_write_lock); error = EFSCORRUPTED; if (xfs_sb_version_hassector(&mp->m_sb)) { @@ -2477,6 +2483,18 @@ restart: * * Once a ticket gets put onto the reserveq, it will only return after * the needed reservation is satisfied. + * + * This function is structured so that it has a lock free fast path. This is + * necessary because every new transaction reservation will come through this + * path. Hence any lock will be globally hot if we take it unconditionally on + * every pass. + * + * As tickets are only ever moved on and off the reserveq under the + * l_grant_reserve_lock, we only need to take that lock if we are going + * to add the ticket to the queue and sleep. We can avoid taking the lock if the + * ticket was never added to the reserveq because the t_queue list head will be + * empty and we hold the only reference to it so it can safely be checked + * unlocked. */ STATIC int xlog_grant_log_space(xlog_t *log, @@ -2490,13 +2508,20 @@ xlog_grant_log_space(xlog_t *log, panic("grant Recovery problem"); #endif - /* Is there space or do we need to sleep? */ - spin_lock(&log->l_grant_lock); - trace_xfs_log_grant_enter(log, tic); + need_bytes = tic->t_unit_res; + if (tic->t_flags & XFS_LOG_PERM_RESERV) + need_bytes *= tic->t_ocnt; + /* something is already sleeping; insert new transaction at end */ - if (!list_empty(&log->l_reserveq)) { + if (!list_empty_careful(&log->l_reserveq)) { + spin_lock(&log->l_grant_reserve_lock); + /* recheck the queue now we are locked */ + if (list_empty(&log->l_reserveq)) { + spin_unlock(&log->l_grant_reserve_lock); + goto redo; + } list_add_tail(&tic->t_queue, &log->l_reserveq); trace_xfs_log_grant_sleep1(log, tic); @@ -2509,48 +2534,47 @@ xlog_grant_log_space(xlog_t *log, goto error_return; XFS_STATS_INC(xs_sleep_logspace); - xlog_wait(&tic->t_wait, &log->l_grant_lock); + xlog_wait(&tic->t_wait, &log->l_grant_reserve_lock); /* * If we got an error, and the filesystem is shutting down, * we'll catch it down below. So just continue... */ trace_xfs_log_grant_wake1(log, tic); - spin_lock(&log->l_grant_lock); } - if (tic->t_flags & XFS_LOG_PERM_RESERV) - need_bytes = tic->t_unit_res*tic->t_ocnt; - else - need_bytes = tic->t_unit_res; redo: if (XLOG_FORCED_SHUTDOWN(log)) - goto error_return; + goto error_return_unlocked; free_bytes = xlog_space_left(log, &log->l_grant_reserve_head); if (free_bytes < need_bytes) { + spin_lock(&log->l_grant_reserve_lock); if (list_empty(&tic->t_queue)) list_add_tail(&tic->t_queue, &log->l_reserveq); trace_xfs_log_grant_sleep2(log, tic); + if (XLOG_FORCED_SHUTDOWN(log)) + goto error_return; + xlog_grant_push_ail(log, need_bytes); XFS_STATS_INC(xs_sleep_logspace); - xlog_wait(&tic->t_wait, &log->l_grant_lock); - - spin_lock(&log->l_grant_lock); - if (XLOG_FORCED_SHUTDOWN(log)) - goto error_return; + xlog_wait(&tic->t_wait, &log->l_grant_reserve_lock); trace_xfs_log_grant_wake2(log, tic); - goto redo; } - list_del_init(&tic->t_queue); + if (!list_empty(&tic->t_queue)) { + spin_lock(&log->l_grant_reserve_lock); + list_del_init(&tic->t_queue); + spin_unlock(&log->l_grant_reserve_lock); + } /* we've got enough space */ + spin_lock(&log->l_grant_lock); xlog_grant_add_space(log, &log->l_grant_reserve_head, need_bytes); xlog_grant_add_space(log, &log->l_grant_write_head, need_bytes); trace_xfs_log_grant_exit(log, tic); @@ -2559,8 +2583,11 @@ redo: spin_unlock(&log->l_grant_lock); return 0; - error_return: +error_return_unlocked: + spin_lock(&log->l_grant_reserve_lock); +error_return: list_del_init(&tic->t_queue); + spin_unlock(&log->l_grant_reserve_lock); trace_xfs_log_grant_error(log, tic); /* @@ -2570,7 +2597,6 @@ redo: */ tic->t_curr_res = 0; tic->t_cnt = 0; /* ungrant will give back unit_res * t_cnt. */ - spin_unlock(&log->l_grant_lock); return XFS_ERROR(EIO); } /* xlog_grant_log_space */ @@ -2578,7 +2604,8 @@ redo: /* * Replenish the byte reservation required by moving the grant write head. * - * + * Similar to xlog_grant_log_space, the function is structured to have a lock + * free fast path. */ STATIC int xlog_regrant_write_log_space(xlog_t *log, @@ -2597,12 +2624,9 @@ xlog_regrant_write_log_space(xlog_t *log, panic("regrant Recovery problem"); #endif - spin_lock(&log->l_grant_lock); - trace_xfs_log_regrant_write_enter(log, tic); - if (XLOG_FORCED_SHUTDOWN(log)) - goto error_return; + goto error_return_unlocked; /* If there are other waiters on the queue then give them a * chance at logspace before us. Wake up the first waiters, @@ -2611,8 +2635,10 @@ xlog_regrant_write_log_space(xlog_t *log, * this transaction. */ need_bytes = tic->t_unit_res; - if (!list_empty(&log->l_writeq)) { + if (!list_empty_careful(&log->l_writeq)) { struct xlog_ticket *ntic; + + spin_lock(&log->l_grant_write_lock); free_bytes = xlog_space_left(log, &log->l_grant_write_head); list_for_each_entry(ntic, &log->l_writeq, t_queue) { ASSERT(ntic->t_flags & XLOG_TIC_PERM_RESERV); @@ -2627,50 +2653,48 @@ xlog_regrant_write_log_space(xlog_t *log, struct xlog_ticket, t_queue)) { if (list_empty(&tic->t_queue)) list_add_tail(&tic->t_queue, &log->l_writeq); - trace_xfs_log_regrant_write_sleep1(log, tic); xlog_grant_push_ail(log, need_bytes); XFS_STATS_INC(xs_sleep_logspace); - xlog_wait(&tic->t_wait, &log->l_grant_lock); - - /* If we're shutting down, this tic is already - * off the queue */ - spin_lock(&log->l_grant_lock); - if (XLOG_FORCED_SHUTDOWN(log)) - goto error_return; - + xlog_wait(&tic->t_wait, &log->l_grant_write_lock); trace_xfs_log_regrant_write_wake1(log, tic); - } + } else + spin_unlock(&log->l_grant_write_lock); } redo: if (XLOG_FORCED_SHUTDOWN(log)) - goto error_return; + goto error_return_unlocked; free_bytes = xlog_space_left(log, &log->l_grant_write_head); if (free_bytes < need_bytes) { + spin_lock(&log->l_grant_write_lock); if (list_empty(&tic->t_queue)) list_add_tail(&tic->t_queue, &log->l_writeq); + + if (XLOG_FORCED_SHUTDOWN(log)) + goto error_return; + xlog_grant_push_ail(log, need_bytes); XFS_STATS_INC(xs_sleep_logspace); trace_xfs_log_regrant_write_sleep2(log, tic); - xlog_wait(&tic->t_wait, &log->l_grant_lock); - - /* If we're shutting down, this tic is already off the queue */ - spin_lock(&log->l_grant_lock); - if (XLOG_FORCED_SHUTDOWN(log)) - goto error_return; + xlog_wait(&tic->t_wait, &log->l_grant_write_lock); trace_xfs_log_regrant_write_wake2(log, tic); goto redo; } - list_del_init(&tic->t_queue); + if (!list_empty(&tic->t_queue)) { + spin_lock(&log->l_grant_write_lock); + list_del_init(&tic->t_queue); + spin_unlock(&log->l_grant_write_lock); + } /* we've got enough space */ + spin_lock(&log->l_grant_lock); xlog_grant_add_space(log, &log->l_grant_write_head, need_bytes); trace_xfs_log_regrant_write_exit(log, tic); xlog_verify_grant_head(log, 1); @@ -2679,8 +2703,11 @@ redo: return 0; + error_return_unlocked: + spin_lock(&log->l_grant_write_lock); error_return: list_del_init(&tic->t_queue); + spin_unlock(&log->l_grant_write_lock); trace_xfs_log_regrant_write_error(log, tic); /* @@ -2690,7 +2717,6 @@ redo: */ tic->t_curr_res = 0; tic->t_cnt = 0; /* ungrant will give back unit_res * t_cnt. */ - spin_unlock(&log->l_grant_lock); return XFS_ERROR(EIO); } /* xlog_regrant_write_log_space */ @@ -3664,12 +3690,10 @@ xfs_log_force_umount( xlog_cil_force(log); /* - * We must hold both the GRANT lock and the LOG lock, - * before we mark the filesystem SHUTDOWN and wake - * everybody up to tell the bad news. + * mark the filesystem and the as in a shutdown state and wake + * everybody up to tell them the bad news. */ spin_lock(&log->l_icloglock); - spin_lock(&log->l_grant_lock); mp->m_flags |= XFS_MOUNT_FS_SHUTDOWN; if (mp->m_sb_bp) XFS_BUF_DONE(mp->m_sb_bp); @@ -3694,14 +3718,17 @@ xfs_log_force_umount( * means we have to wake up everybody queued up on reserveq as well as * writeq. In addition, we make sure in xlog_{re}grant_log_space that * we don't enqueue anything once the SHUTDOWN flag is set, and this - * action is protected by the GRANTLOCK. + * action is protected by the grant locks. */ + spin_lock(&log->l_grant_reserve_lock); list_for_each_entry(tic, &log->l_reserveq, t_queue) wake_up(&tic->t_wait); + spin_unlock(&log->l_grant_reserve_lock); + spin_lock(&log->l_grant_write_lock); list_for_each_entry(tic, &log->l_writeq, t_queue) wake_up(&tic->t_wait); - spin_unlock(&log->l_grant_lock); + spin_unlock(&log->l_grant_write_lock); if (!(log->l_iclog->ic_state & XLOG_STATE_IOERROR)) { ASSERT(!logerror); diff --git a/fs/xfs/xfs_log_priv.h b/fs/xfs/xfs_log_priv.h index 7619d6a02388..befb2fc5b027 100644 --- a/fs/xfs/xfs_log_priv.h +++ b/fs/xfs/xfs_log_priv.h @@ -512,10 +512,6 @@ typedef struct log { /* The following block of fields are changed while holding grant_lock */ spinlock_t l_grant_lock ____cacheline_aligned_in_smp; - struct list_head l_reserveq; - struct list_head l_writeq; - atomic64_t l_grant_reserve_head; - atomic64_t l_grant_write_head; /* * l_last_sync_lsn and l_tail_lsn are atomics so they can be set and @@ -528,6 +524,18 @@ typedef struct log { /* lsn of 1st LR with unflushed * buffers */ atomic64_t l_tail_lsn ____cacheline_aligned_in_smp; + /* + * ticket grant locks, queues and accounting have their own cachlines + * as these are quite hot and can be operated on concurrently. + */ + spinlock_t l_grant_reserve_lock ____cacheline_aligned_in_smp; + struct list_head l_reserveq; + atomic64_t l_grant_reserve_head; + + spinlock_t l_grant_write_lock ____cacheline_aligned_in_smp; + struct list_head l_writeq; + atomic64_t l_grant_write_head; + /* The following field are used for debugging; need to hold icloglock */ #ifdef DEBUG char *l_iclog_bak[XLOG_MAX_ICLOGS]; -- cgit v1.2.3 From d0eb2f38b250b7d6c993adf81b0e4ded0565497e Mon Sep 17 00:00:00 2001 From: Dave Chinner Date: Tue, 21 Dec 2010 12:29:14 +1100 Subject: xfs: convert grant head manipulations to lockless algorithm The only thing that the grant lock remains to protect is the grant head manipulations when adding or removing space from the log. These calculations are already based on atomic variables, so we can already update them safely without locks. However, the grant head manpulations require atomic multi-step calculations to be executed, which the algorithms currently don't allow. To make these multi-step calculations atomic, convert the algorithms to compare-and-exchange loops on the atomic variables. That is, we sample the old value, perform the calculation and use atomic64_cmpxchg() to attempt to update the head with the new value. If the head has not changed since we sampled it, it will succeed and we are done. Otherwise, we rerun the calculation again from a new sample of the head. This allows us to remove the grant lock from around all the grant head space manipulations, and that effectively removes the grant lock from the log completely. Hence we can remove the grant lock completely from the log at this point. Signed-off-by: Dave Chinner Reviewed-by: Christoph Hellwig --- fs/xfs/xfs_log.c | 103 +++++++++++++++++--------------------------------- fs/xfs/xfs_log_priv.h | 23 +++++++---- 2 files changed, 49 insertions(+), 77 deletions(-) diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c index 6fcc9d0af524..0bf24b11d0c4 100644 --- a/fs/xfs/xfs_log.c +++ b/fs/xfs/xfs_log.c @@ -81,7 +81,6 @@ STATIC void xlog_ungrant_log_space(xlog_t *log, #if defined(DEBUG) STATIC void xlog_verify_dest_ptr(xlog_t *log, char *ptr); -STATIC void xlog_verify_grant_head(xlog_t *log, int equals); STATIC void xlog_verify_grant_tail(struct log *log); STATIC void xlog_verify_iclog(xlog_t *log, xlog_in_core_t *iclog, int count, boolean_t syncing); @@ -89,7 +88,6 @@ STATIC void xlog_verify_tail_lsn(xlog_t *log, xlog_in_core_t *iclog, xfs_lsn_t tail_lsn); #else #define xlog_verify_dest_ptr(a,b) -#define xlog_verify_grant_head(a,b) #define xlog_verify_grant_tail(a) #define xlog_verify_iclog(a,b,c,d) #define xlog_verify_tail_lsn(a,b,c) @@ -103,17 +101,24 @@ xlog_grant_sub_space( atomic64_t *head, int bytes) { - int cycle, space; + int64_t head_val = atomic64_read(head); + int64_t new, old; - xlog_crack_grant_head(head, &cycle, &space); + do { + int cycle, space; - space -= bytes; - if (space < 0) { - space += log->l_logsize; - cycle--; - } + xlog_crack_grant_head_val(head_val, &cycle, &space); - xlog_assign_grant_head(head, cycle, space); + space -= bytes; + if (space < 0) { + space += log->l_logsize; + cycle--; + } + + old = head_val; + new = xlog_assign_grant_head_val(cycle, space); + head_val = atomic64_cmpxchg(head, old, new); + } while (head_val != old); } static void @@ -122,20 +127,27 @@ xlog_grant_add_space( atomic64_t *head, int bytes) { - int tmp; - int cycle, space; + int64_t head_val = atomic64_read(head); + int64_t new, old; - xlog_crack_grant_head(head, &cycle, &space); + do { + int tmp; + int cycle, space; - tmp = log->l_logsize - space; - if (tmp > bytes) - space += bytes; - else { - space = bytes - tmp; - cycle++; - } + xlog_crack_grant_head_val(head_val, &cycle, &space); - xlog_assign_grant_head(head, cycle, space); + tmp = log->l_logsize - space; + if (tmp > bytes) + space += bytes; + else { + space = bytes - tmp; + cycle++; + } + + old = head_val; + new = xlog_assign_grant_head_val(cycle, space); + head_val = atomic64_cmpxchg(head, old, new); + } while (head_val != old); } static void @@ -318,9 +330,7 @@ xfs_log_reserve( trace_xfs_log_reserve(log, internal_ticket); - spin_lock(&log->l_grant_lock); xlog_grant_push_ail(log, internal_ticket->t_unit_res); - spin_unlock(&log->l_grant_lock); retval = xlog_regrant_write_log_space(log, internal_ticket); } else { /* may sleep if need to allocate more tickets */ @@ -334,11 +344,9 @@ xfs_log_reserve( trace_xfs_log_reserve(log, internal_ticket); - spin_lock(&log->l_grant_lock); xlog_grant_push_ail(log, (internal_ticket->t_unit_res * internal_ticket->t_cnt)); - spin_unlock(&log->l_grant_lock); retval = xlog_grant_log_space(log, internal_ticket); } @@ -1057,7 +1065,6 @@ xlog_alloc_log(xfs_mount_t *mp, log->l_xbuf = bp; spin_lock_init(&log->l_icloglock); - spin_lock_init(&log->l_grant_lock); init_waitqueue_head(&log->l_flush_wait); /* log record size must be multiple of BBSIZE; see xlog_rec_header_t */ @@ -1135,7 +1142,6 @@ out_free_iclog: kmem_free(iclog); } spinlock_destroy(&log->l_icloglock); - spinlock_destroy(&log->l_grant_lock); xfs_buf_free(log->l_xbuf); out_free_log: kmem_free(log); @@ -1331,10 +1337,8 @@ xlog_sync(xlog_t *log, roundoff < BBTOB(1))); /* move grant heads by roundoff in sync */ - spin_lock(&log->l_grant_lock); xlog_grant_add_space(log, &log->l_grant_reserve_head, roundoff); xlog_grant_add_space(log, &log->l_grant_write_head, roundoff); - spin_unlock(&log->l_grant_lock); /* put cycle number in every block */ xlog_pack_data(log, iclog, roundoff); @@ -1455,7 +1459,6 @@ xlog_dealloc_log(xlog_t *log) iclog = next_iclog; } spinlock_destroy(&log->l_icloglock); - spinlock_destroy(&log->l_grant_lock); xfs_buf_free(log->l_xbuf); log->l_mp->m_log = NULL; @@ -2574,13 +2577,10 @@ redo: } /* we've got enough space */ - spin_lock(&log->l_grant_lock); xlog_grant_add_space(log, &log->l_grant_reserve_head, need_bytes); xlog_grant_add_space(log, &log->l_grant_write_head, need_bytes); trace_xfs_log_grant_exit(log, tic); - xlog_verify_grant_head(log, 1); xlog_verify_grant_tail(log); - spin_unlock(&log->l_grant_lock); return 0; error_return_unlocked: @@ -2694,12 +2694,9 @@ redo: } /* we've got enough space */ - spin_lock(&log->l_grant_lock); xlog_grant_add_space(log, &log->l_grant_write_head, need_bytes); trace_xfs_log_regrant_write_exit(log, tic); - xlog_verify_grant_head(log, 1); xlog_verify_grant_tail(log); - spin_unlock(&log->l_grant_lock); return 0; @@ -2737,7 +2734,6 @@ xlog_regrant_reserve_log_space(xlog_t *log, if (ticket->t_cnt > 0) ticket->t_cnt--; - spin_lock(&log->l_grant_lock); xlog_grant_sub_space(log, &log->l_grant_reserve_head, ticket->t_curr_res); xlog_grant_sub_space(log, &log->l_grant_write_head, @@ -2747,21 +2743,15 @@ xlog_regrant_reserve_log_space(xlog_t *log, trace_xfs_log_regrant_reserve_sub(log, ticket); - xlog_verify_grant_head(log, 1); - /* just return if we still have some of the pre-reserved space */ - if (ticket->t_cnt > 0) { - spin_unlock(&log->l_grant_lock); + if (ticket->t_cnt > 0) return; - } xlog_grant_add_space(log, &log->l_grant_reserve_head, ticket->t_unit_res); trace_xfs_log_regrant_reserve_exit(log, ticket); - xlog_verify_grant_head(log, 0); - spin_unlock(&log->l_grant_lock); ticket->t_curr_res = ticket->t_unit_res; xlog_tic_reset_res(ticket); } /* xlog_regrant_reserve_log_space */ @@ -2790,7 +2780,6 @@ xlog_ungrant_log_space(xlog_t *log, if (ticket->t_cnt > 0) ticket->t_cnt--; - spin_lock(&log->l_grant_lock); trace_xfs_log_ungrant_enter(log, ticket); trace_xfs_log_ungrant_sub(log, ticket); @@ -2809,8 +2798,6 @@ xlog_ungrant_log_space(xlog_t *log, trace_xfs_log_ungrant_exit(log, ticket); - xlog_verify_grant_head(log, 1); - spin_unlock(&log->l_grant_lock); xfs_log_move_tail(log->l_mp, 1); } /* xlog_ungrant_log_space */ @@ -3428,28 +3415,6 @@ xlog_verify_dest_ptr( xlog_panic("xlog_verify_dest_ptr: invalid ptr"); } -STATIC void -xlog_verify_grant_head(xlog_t *log, int equals) -{ - int reserve_cycle, reserve_space; - int write_cycle, write_space; - - xlog_crack_grant_head(&log->l_grant_reserve_head, - &reserve_cycle, &reserve_space); - xlog_crack_grant_head(&log->l_grant_write_head, - &write_cycle, &write_space); - - if (reserve_cycle == write_cycle) { - if (equals) - ASSERT(reserve_space >= write_space); - else - ASSERT(reserve_space > write_space); - } else { - ASSERT(reserve_cycle - 1 == write_cycle); - ASSERT(write_space >= reserve_space); - } -} - STATIC void xlog_verify_grant_tail( struct log *log) diff --git a/fs/xfs/xfs_log_priv.h b/fs/xfs/xfs_log_priv.h index befb2fc5b027..d5f8be8f4bf6 100644 --- a/fs/xfs/xfs_log_priv.h +++ b/fs/xfs/xfs_log_priv.h @@ -510,9 +510,6 @@ typedef struct log { int l_curr_block; /* current logical log block */ int l_prev_block; /* previous logical log block */ - /* The following block of fields are changed while holding grant_lock */ - spinlock_t l_grant_lock ____cacheline_aligned_in_smp; - /* * l_last_sync_lsn and l_tail_lsn are atomics so they can be set and * read without needing to hold specific locks. To avoid operations @@ -599,23 +596,33 @@ xlog_assign_atomic_lsn(atomic64_t *lsn, uint cycle, uint block) } /* - * When we crack the grrant head, we sample it first so that the value will not + * When we crack the grant head, we sample it first so that the value will not * change while we are cracking it into the component values. This means we * will always get consistent component values to work from. */ static inline void -xlog_crack_grant_head(atomic64_t *head, int *cycle, int *space) +xlog_crack_grant_head_val(int64_t val, int *cycle, int *space) { - int64_t val = atomic64_read(head); - *cycle = val >> 32; *space = val & 0xffffffff; } +static inline void +xlog_crack_grant_head(atomic64_t *head, int *cycle, int *space) +{ + xlog_crack_grant_head_val(atomic64_read(head), cycle, space); +} + +static inline int64_t +xlog_assign_grant_head_val(int cycle, int space) +{ + return ((int64_t)cycle << 32) | space; +} + static inline void xlog_assign_grant_head(atomic64_t *head, int cycle, int space) { - atomic64_set(head, ((int64_t)cycle << 32) | space); + atomic64_set(head, xlog_assign_grant_head_val(cycle, space)); } /* -- cgit v1.2.3 From 57084d05379fe5c081d024006129b0565a11855f Mon Sep 17 00:00:00 2001 From: James Simmons Date: Mon, 20 Dec 2010 19:10:39 +0000 Subject: drm/fb: Don't expose mmio for fbdev emulation layer For the fbdev api if the struct fb_var_screeninfo accel_flags field is set to FB_ACCELF_TEXT then userland applications can not mmap the mmio region. Since it is a bad idea for DRM drivers to expose the mmio region via the fbdev layer we always set the accel_flags to prevent this. Please apply. Signed-off-by: James Simmons Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_fb_helper.c | 3 +++ drivers/gpu/drm/i915/intel_fb.c | 6 +----- drivers/gpu/drm/nouveau/nouveau_fbcon.c | 4 ---- drivers/gpu/drm/radeon/radeon_fb.c | 2 -- drivers/gpu/drm/vmwgfx/vmwgfx_fb.c | 3 --- 5 files changed, 4 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index d2849e4ea4d0..aa377115483b 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -985,6 +985,8 @@ void drm_fb_helper_fill_fix(struct fb_info *info, uint32_t pitch, info->fix.type = FB_TYPE_PACKED_PIXELS; info->fix.visual = depth == 8 ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR; + info->fix.mmio_start = 0; + info->fix.mmio_len = 0; info->fix.type_aux = 0; info->fix.xpanstep = 1; /* doing it in hw */ info->fix.ypanstep = 1; /* doing it in hw */ @@ -1005,6 +1007,7 @@ void drm_fb_helper_fill_var(struct fb_info *info, struct drm_fb_helper *fb_helpe info->var.xres_virtual = fb->width; info->var.yres_virtual = fb->height; info->var.bits_per_pixel = fb->bits_per_pixel; + info->var.accel_flags = FB_ACCELF_TEXT; info->var.xoffset = 0; info->var.yoffset = 0; info->var.activate = FB_ACTIVATE_NOW; diff --git a/drivers/gpu/drm/i915/intel_fb.c b/drivers/gpu/drm/i915/intel_fb.c index af2a1dddc28e..ced3eef8da07 100644 --- a/drivers/gpu/drm/i915/intel_fb.c +++ b/drivers/gpu/drm/i915/intel_fb.c @@ -68,7 +68,7 @@ static int intelfb_create(struct intel_fbdev *ifbdev, struct drm_gem_object *fbo = NULL; struct drm_i915_gem_object *obj_priv; struct device *device = &dev->pdev->dev; - int size, ret, mmio_bar = IS_GEN2(dev) ? 1 : 0; + int size, ret; /* we don't do packed 24bpp */ if (sizes->surface_bpp == 24) @@ -156,10 +156,6 @@ static int intelfb_create(struct intel_fbdev *ifbdev, drm_fb_helper_fill_fix(info, fb->pitch, fb->depth); drm_fb_helper_fill_var(info, &ifbdev->helper, sizes->fb_width, sizes->fb_height); - /* FIXME: we really shouldn't expose mmio space at all */ - info->fix.mmio_start = pci_resource_start(dev->pdev, mmio_bar); - info->fix.mmio_len = pci_resource_len(dev->pdev, mmio_bar); - info->pixmap.size = 64*1024; info->pixmap.buf_align = 8; info->pixmap.access_align = 32; diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/drivers/gpu/drm/nouveau/nouveau_fbcon.c index ea861c915149..9dbe1eff2ae5 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fbcon.c +++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c @@ -348,10 +348,6 @@ nouveau_fbcon_create(struct nouveau_fbdev *nfbdev, drm_fb_helper_fill_fix(info, fb->pitch, fb->depth); drm_fb_helper_fill_var(info, &nfbdev->helper, sizes->fb_width, sizes->fb_height); - /* FIXME: we really shouldn't expose mmio space at all */ - info->fix.mmio_start = pci_resource_start(pdev, 1); - info->fix.mmio_len = pci_resource_len(pdev, 1); - /* Set aperture base/size for vesafb takeover */ info->apertures = dev_priv->apertures; if (!info->apertures) { diff --git a/drivers/gpu/drm/radeon/radeon_fb.c b/drivers/gpu/drm/radeon/radeon_fb.c index efa211898fe6..f7b4762fa6b6 100644 --- a/drivers/gpu/drm/radeon/radeon_fb.c +++ b/drivers/gpu/drm/radeon/radeon_fb.c @@ -247,8 +247,6 @@ static int radeonfb_create(struct radeon_fbdev *rfbdev, info->apertures->ranges[0].base = rdev->ddev->mode_config.fb_base; info->apertures->ranges[0].size = rdev->mc.real_vram_size; - info->fix.mmio_start = 0; - info->fix.mmio_len = 0; info->pixmap.size = 64*1024; info->pixmap.buf_align = 8; info->pixmap.access_align = 32; diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c b/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c index 41d9a5b73c03..dd596f2bd6e8 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c @@ -480,9 +480,6 @@ int vmw_fb_init(struct vmw_private *vmw_priv) info->fix.smem_start = 0; info->fix.smem_len = fb_size; - info->fix.mmio_start = 0; - info->fix.mmio_len = 0; - info->pseudo_palette = par->pseudo_palette; info->screen_base = par->vmalloc; info->screen_size = fb_size; -- cgit v1.2.3 From 21719b398b0e49d21c0b9083cffd552ba28ed4af Mon Sep 17 00:00:00 2001 From: Tijl Coosemans Date: Tue, 21 Dec 2010 12:54:52 +1000 Subject: drm/radeon: Definition of R_0003C2_GENMO_WT seems wrong In drivers/gpu/drm/radeon/r100d.h R_0003C2_GENMO_WT is defined as 0x3C0. I think this should be 0x3C2. Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/r100d.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/radeon/r100d.h b/drivers/gpu/drm/radeon/r100d.h index b121b6c678d4..eab91760fae0 100644 --- a/drivers/gpu/drm/radeon/r100d.h +++ b/drivers/gpu/drm/radeon/r100d.h @@ -551,7 +551,7 @@ #define S_000360_CUR2_LOCK(x) (((x) & 0x1) << 31) #define G_000360_CUR2_LOCK(x) (((x) >> 31) & 0x1) #define C_000360_CUR2_LOCK 0x7FFFFFFF -#define R_0003C2_GENMO_WT 0x0003C0 +#define R_0003C2_GENMO_WT 0x0003C2 #define S_0003C2_GENMO_MONO_ADDRESS_B(x) (((x) & 0x1) << 0) #define G_0003C2_GENMO_MONO_ADDRESS_B(x) (((x) >> 0) & 0x1) #define C_0003C2_GENMO_MONO_ADDRESS_B 0xFE -- cgit v1.2.3 From 48c36c8f9a3e881953bb72deb55623a53795a684 Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Sat, 18 Dec 2010 11:41:49 +0100 Subject: drm/radeon/kms: allow r500 US_FORMAT regs in the CS checker MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit add to the 2.8 bump for pageflip The purpose of these regs is to work around a TX hw bug in R520. Signed-off-by: Marek Olšák Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/radeon_drv.c | 2 +- drivers/gpu/drm/radeon/reg_srcs/rv515 | 16 ++++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index a92d2a5cea90..6fb1218f9d76 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c @@ -48,7 +48,7 @@ * - 2.5.0 - add get accel 2 to work around ddx breakage for evergreen * - 2.6.0 - add tiling config query (r6xx+), add initial HiZ support (r300->r500) * 2.7.0 - fixups for r600 2D tiling support. (no external ABI change), add eg dyn gpr regs - * 2.8.0 - pageflip support + * 2.8.0 - pageflip support, r500 US_FORMAT regs. */ #define KMS_DRIVER_MAJOR 2 #define KMS_DRIVER_MINOR 8 diff --git a/drivers/gpu/drm/radeon/reg_srcs/rv515 b/drivers/gpu/drm/radeon/reg_srcs/rv515 index b3f9f1d92005..ef422bbacfc1 100644 --- a/drivers/gpu/drm/radeon/reg_srcs/rv515 +++ b/drivers/gpu/drm/radeon/reg_srcs/rv515 @@ -304,6 +304,22 @@ rv515 0x6d40 0x4630 US_CODE_ADDR 0x4634 US_CODE_RANGE 0x4638 US_CODE_OFFSET +0x4640 US_FORMAT0_0 +0x4644 US_FORMAT0_1 +0x4648 US_FORMAT0_2 +0x464C US_FORMAT0_3 +0x4650 US_FORMAT0_4 +0x4654 US_FORMAT0_5 +0x4658 US_FORMAT0_6 +0x465C US_FORMAT0_7 +0x4660 US_FORMAT0_8 +0x4664 US_FORMAT0_9 +0x4668 US_FORMAT0_10 +0x466C US_FORMAT0_11 +0x4670 US_FORMAT0_12 +0x4674 US_FORMAT0_13 +0x4678 US_FORMAT0_14 +0x467C US_FORMAT0_15 0x46A4 US_OUT_FMT_0 0x46A8 US_OUT_FMT_1 0x46AC US_OUT_FMT_2 -- cgit v1.2.3 From b61c99de8e7905916d1508ba7c9a9c08656e169d Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Thu, 16 Dec 2010 18:40:29 -0500 Subject: drm/radeon/kms: fix DCE4.1 dig routing (v2) Works more like DCE4.0 despite what the docs say. This fixes blank screen issues when changing crtc routing due to incorrect crtc to dig mapping. v2: only two DIGx blocks, routing is hardcoded based on link. Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/radeon_encoders.c | 54 +++++++++++++++----------------- 1 file changed, 25 insertions(+), 29 deletions(-) diff --git a/drivers/gpu/drm/radeon/radeon_encoders.c b/drivers/gpu/drm/radeon/radeon_encoders.c index e4e64a80b58d..55b84b8e6b29 100644 --- a/drivers/gpu/drm/radeon/radeon_encoders.c +++ b/drivers/gpu/drm/radeon/radeon_encoders.c @@ -910,15 +910,9 @@ atombios_dig_transmitter_setup(struct drm_encoder *encoder, int action, uint8_t else args.v3.ucLaneNum = 4; - if (ASIC_IS_DCE41(rdev)) { - args.v3.acConfig.ucEncoderSel = dig->dig_encoder; - if (dig->linkb) - args.v3.acConfig.ucLinkSel = 1; - } else { - if (dig->linkb) { - args.v3.acConfig.ucLinkSel = 1; - args.v3.acConfig.ucEncoderSel = 1; - } + if (dig->linkb) { + args.v3.acConfig.ucLinkSel = 1; + args.v3.acConfig.ucEncoderSel = 1; } /* Select the PLL for the PHY @@ -1535,32 +1529,34 @@ static int radeon_atom_pick_dig_encoder(struct drm_encoder *encoder) struct radeon_encoder_atom_dig *dig; uint32_t dig_enc_in_use = 0; - /* on DCE41 and encoder can driver any phy so just crtc id */ - if (ASIC_IS_DCE41(rdev)) { - return radeon_crtc->crtc_id; - } - if (ASIC_IS_DCE4(rdev)) { dig = radeon_encoder->enc_priv; - switch (radeon_encoder->encoder_id) { - case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: + if (ASIC_IS_DCE41(rdev)) { if (dig->linkb) return 1; else return 0; - break; - case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: - if (dig->linkb) - return 3; - else - return 2; - break; - case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: - if (dig->linkb) - return 5; - else - return 4; - break; + } else { + switch (radeon_encoder->encoder_id) { + case ENCODER_OBJECT_ID_INTERNAL_UNIPHY: + if (dig->linkb) + return 1; + else + return 0; + break; + case ENCODER_OBJECT_ID_INTERNAL_UNIPHY1: + if (dig->linkb) + return 3; + else + return 2; + break; + case ENCODER_OBJECT_ID_INTERNAL_UNIPHY2: + if (dig->linkb) + return 5; + else + return 4; + break; + } } } -- cgit v1.2.3 From 7d6aa80c35bb1f706e2894100dcc51e19a83f913 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Mon, 20 Dec 2010 11:21:43 -0500 Subject: drm/radeon/kms/atom: clean up op_mask handler Readability cleanup and fix debugging output, no functional change. Reported-by: Frank Huang Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/atom.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/radeon/atom.c b/drivers/gpu/drm/radeon/atom.c index 8e421f644a54..9b0773b75e86 100644 --- a/drivers/gpu/drm/radeon/atom.c +++ b/drivers/gpu/drm/radeon/atom.c @@ -733,16 +733,16 @@ static void atom_op_jump(atom_exec_context *ctx, int *ptr, int arg) static void atom_op_mask(atom_exec_context *ctx, int *ptr, int arg) { uint8_t attr = U8((*ptr)++); - uint32_t dst, src1, src2, saved; + uint32_t dst, mask, src, saved; int dptr = *ptr; SDEBUG(" dst: "); dst = atom_get_dst(ctx, arg, attr, ptr, &saved, 1); - SDEBUG(" src1: "); - src1 = atom_get_src_direct(ctx, ((attr >> 3) & 7), ptr); - SDEBUG(" src2: "); - src2 = atom_get_src(ctx, attr, ptr); - dst &= src1; - dst |= src2; + mask = atom_get_src_direct(ctx, ((attr >> 3) & 7), ptr); + SDEBUG(" mask: 0x%08x", mask); + SDEBUG(" src: "); + src = atom_get_src(ctx, attr, ptr); + dst &= mask; + dst |= src; SDEBUG(" dst: "); atom_put_dst(ctx, arg, attr, &dptr, dst, saved); } -- cgit v1.2.3 From 3ce05168907c9b1358492a73badb0ff1603fb81d Mon Sep 17 00:00:00 2001 From: David Fries Date: Sun, 12 Dec 2010 12:39:22 -0600 Subject: drm/kms: load fbcon from drm_kms_helper Kconfig says fbcon is required by drm_kms_helper. If radeon, fbcon, and drm_kms_helper are all modules, radeon is auto loaded (by PCI id?), drm_kms_helper is loaded because of the module dependency, but fbcon isn't loaded leaving the console unusable. Since fbcon is required and there isn't an explicit module dependency, request the module to be loaded from drm_kms_helper. Signed-off-by: David Fries Cc: David Airlie Cc: dri-devel@lists.freedesktop.org Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_fb_helper.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index aa377115483b..5c4f9b9ecdc0 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c @@ -1533,3 +1533,24 @@ bool drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper) } EXPORT_SYMBOL(drm_fb_helper_hotplug_event); +/* The Kconfig DRM_KMS_HELPER selects FRAMEBUFFER_CONSOLE (if !EMBEDDED) + * but the module doesn't depend on any fb console symbols. At least + * attempt to load fbcon to avoid leaving the system without a usable console. + */ +#if defined(CONFIG_FRAMEBUFFER_CONSOLE_MODULE) && !defined(CONFIG_EMBEDDED) +static int __init drm_fb_helper_modinit(void) +{ + const char *name = "fbcon"; + struct module *fbcon; + + mutex_lock(&module_mutex); + fbcon = find_module(name); + mutex_unlock(&module_mutex); + + if (!fbcon) + request_module_nowait(name); + return 0; +} + +module_init(drm_fb_helper_modinit); +#endif -- cgit v1.2.3 From 000fa7cf46479238f7b9f2d7763e41af5268b16a Mon Sep 17 00:00:00 2001 From: Mario Kleiner Date: Fri, 10 Dec 2010 16:00:19 +0100 Subject: drm-vblank: Always return true vblank count of scheduled vblank event. This patch tries to make sure that the vbl.reply.sequence vblank count for a queued or emitted vblank event always corresponds to the true vblank count of queueing/emission, so the ddx can rely on the returned target_msc for consistency checks and implementation of swap_intervals in glXSwapBuffers(). Without this there is a small race-condition between the userspace ddx queueing a vblank event and the vblank counter incrementing before the event gets queued in the kernel. Signed-off-by: Mario Kleiner Acked-by: Jesse Barnes Signed-off-by: Dave Airlie --- drivers/gpu/drm/drm_irq.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c index 4e82d0d3c378..55160d7c38b6 100644 --- a/drivers/gpu/drm/drm_irq.c +++ b/drivers/gpu/drm/drm_irq.c @@ -1086,15 +1086,18 @@ static int drm_queue_vblank_event(struct drm_device *dev, int pipe, e->event.sequence = vblwait->request.sequence; if ((seq - vblwait->request.sequence) <= (1 << 23)) { + e->event.sequence = seq; e->event.tv_sec = now.tv_sec; e->event.tv_usec = now.tv_usec; drm_vblank_put(dev, e->pipe); list_add_tail(&e->base.link, &e->base.file_priv->event_list); wake_up_interruptible(&e->base.file_priv->event_wait); + vblwait->reply.sequence = seq; trace_drm_vblank_event_delivered(current->pid, pipe, vblwait->request.sequence); } else { list_add_tail(&e->base.link, &dev->vblank_event_list); + vblwait->reply.sequence = vblwait->request.sequence; } spin_unlock_irqrestore(&dev->event_lock, flags); -- cgit v1.2.3 From 7a868e18a4907dc8f1f05d99bcb9fd3fa8881ee4 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Wed, 8 Dec 2010 22:13:05 -0500 Subject: drm/radeon/kms: use LCD physical size from vbios tables if available Some systems have the LCD width and height in mm available in the LCD info table. Use this info if there is no EDID to provide it. Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/radeon_atombios.c | 3 +++ drivers/gpu/drm/radeon/radeon_connectors.c | 3 +++ 2 files changed, 6 insertions(+) diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c index ac882639b3ed..35c5ff09040d 100644 --- a/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/drivers/gpu/drm/radeon/radeon_atombios.c @@ -1500,6 +1500,9 @@ struct radeon_encoder_atom_dig *radeon_atombios_get_lvds_info(struct if (misc & ATOM_DOUBLE_CLOCK_MODE) lvds->native_mode.flags |= DRM_MODE_FLAG_DBLSCAN; + lvds->native_mode.width_mm = lvds_info->info.sLCDTiming.usImageHSize; + lvds->native_mode.height_mm = lvds_info->info.sLCDTiming.usImageVSize; + /* set crtc values */ drm_mode_set_crtcinfo(&lvds->native_mode, CRTC_INTERLACE_HALVE_V); diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index 3bef9f6d66fd..f3ba066ded20 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c @@ -472,6 +472,9 @@ static int radeon_lvds_get_modes(struct drm_connector *connector) if (mode) { ret = 1; drm_mode_probed_add(connector, mode); + /* add the width/height from vbios tables if available */ + connector->display_info.width_mm = mode->width_mm; + connector->display_info.height_mm = mode->height_mm; /* add scaled modes */ radeon_add_common_modes(encoder, connector); } -- cgit v1.2.3 From c324acd5032f516b8188da99d2ce05cf8d1294d6 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Wed, 8 Dec 2010 22:13:06 -0500 Subject: drm/radeon/kms: parse the extended LCD info block This block may contain various additional LCD info such as physical size and a stored EDID. Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/radeon_atombios.c | 53 ++++++++++++++++++++++++++++++++ drivers/gpu/drm/radeon/radeon_combios.c | 3 +- drivers/gpu/drm/radeon/radeon_display.c | 14 +++++++-- drivers/gpu/drm/radeon/radeon_mode.h | 2 +- 4 files changed, 67 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c index 35c5ff09040d..d6c611eee204 100644 --- a/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/drivers/gpu/drm/radeon/radeon_atombios.c @@ -1515,6 +1515,59 @@ struct radeon_encoder_atom_dig *radeon_atombios_get_lvds_info(struct else lvds->linkb = false; + /* parse the lcd record table */ + if (lvds_info->info.usModePatchTableOffset) { + ATOM_FAKE_EDID_PATCH_RECORD *fake_edid_record; + ATOM_PANEL_RESOLUTION_PATCH_RECORD *panel_res_record; + bool bad_record = false; + u8 *record = (u8 *)(mode_info->atom_context->bios + + data_offset + + lvds_info->info.usModePatchTableOffset); + while (*record != ATOM_RECORD_END_TYPE) { + switch (*record) { + case LCD_MODE_PATCH_RECORD_MODE_TYPE: + record += sizeof(ATOM_PATCH_RECORD_MODE); + break; + case LCD_RTS_RECORD_TYPE: + record += sizeof(ATOM_LCD_RTS_RECORD); + break; + case LCD_CAP_RECORD_TYPE: + record += sizeof(ATOM_LCD_MODE_CONTROL_CAP); + break; + case LCD_FAKE_EDID_PATCH_RECORD_TYPE: + fake_edid_record = (ATOM_FAKE_EDID_PATCH_RECORD *)record; + if (fake_edid_record->ucFakeEDIDLength) { + struct edid *edid; + int edid_size = + max((int)EDID_LENGTH, (int)fake_edid_record->ucFakeEDIDLength); + edid = kmalloc(edid_size, GFP_KERNEL); + if (edid) { + memcpy((u8 *)edid, (u8 *)&fake_edid_record->ucFakeEDIDString[0], + fake_edid_record->ucFakeEDIDLength); + + if (drm_edid_is_valid(edid)) + rdev->mode_info.bios_hardcoded_edid = edid; + else + kfree(edid); + } + } + record += sizeof(ATOM_FAKE_EDID_PATCH_RECORD); + break; + case LCD_PANEL_RESOLUTION_RECORD_TYPE: + panel_res_record = (ATOM_PANEL_RESOLUTION_PATCH_RECORD *)record; + lvds->native_mode.width_mm = panel_res_record->usHSize; + lvds->native_mode.height_mm = panel_res_record->usVSize; + record += sizeof(ATOM_PANEL_RESOLUTION_PATCH_RECORD); + break; + default: + DRM_ERROR("Bad LCD record %d\n", *record); + bad_record = true; + break; + } + if (bad_record) + break; + } + } } return lvds; } diff --git a/drivers/gpu/drm/radeon/radeon_combios.c b/drivers/gpu/drm/radeon/radeon_combios.c index 3bddea5b5295..111a844c1ecb 100644 --- a/drivers/gpu/drm/radeon/radeon_combios.c +++ b/drivers/gpu/drm/radeon/radeon_combios.c @@ -471,8 +471,9 @@ bool radeon_combios_check_hardcoded_edid(struct radeon_device *rdev) return true; } +/* this is used for atom LCDs as well */ struct edid * -radeon_combios_get_hardcoded_edid(struct radeon_device *rdev) +radeon_bios_get_hardcoded_edid(struct radeon_device *rdev) { if (rdev->mode_info.bios_hardcoded_edid) return rdev->mode_info.bios_hardcoded_edid; diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c index 7b17e639ab32..acebbc76c2f9 100644 --- a/drivers/gpu/drm/radeon/radeon_display.c +++ b/drivers/gpu/drm/radeon/radeon_display.c @@ -679,9 +679,17 @@ int radeon_ddc_get_modes(struct radeon_connector *radeon_connector) if (!radeon_connector->edid) { radeon_connector->edid = drm_get_edid(&radeon_connector->base, &radeon_connector->ddc_bus->adapter); } - /* some servers provide a hardcoded edid in rom for KVMs */ - if (!radeon_connector->edid) - radeon_connector->edid = radeon_combios_get_hardcoded_edid(rdev); + + if (!radeon_connector->edid) { + if (rdev->is_atom_bios) { + /* some laptops provide a hardcoded edid in rom for LCDs */ + if (((radeon_connector->base.connector_type == DRM_MODE_CONNECTOR_LVDS) || + (radeon_connector->base.connector_type == DRM_MODE_CONNECTOR_eDP))) + radeon_connector->edid = radeon_bios_get_hardcoded_edid(rdev); + } else + /* some servers provide a hardcoded edid in rom for KVMs */ + radeon_connector->edid = radeon_bios_get_hardcoded_edid(rdev); + } if (radeon_connector->edid) { drm_mode_connector_update_edid_property(&radeon_connector->base, radeon_connector->edid); ret = drm_add_edid_modes(&radeon_connector->base, radeon_connector->edid); diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h index f406f02bf14e..fd185f783a31 100644 --- a/drivers/gpu/drm/radeon/radeon_mode.h +++ b/drivers/gpu/drm/radeon/radeon_mode.h @@ -566,7 +566,7 @@ extern int radeon_get_crtc_scanoutpos(struct drm_device *dev, int crtc, extern bool radeon_combios_check_hardcoded_edid(struct radeon_device *rdev); extern struct edid * -radeon_combios_get_hardcoded_edid(struct radeon_device *rdev); +radeon_bios_get_hardcoded_edid(struct radeon_device *rdev); extern bool radeon_atom_get_clock_info(struct drm_device *dev); extern bool radeon_combios_get_clock_info(struct drm_device *dev); extern struct radeon_encoder_atom_dig * -- cgit v1.2.3 From 3ee0128140eed7d32b785a335099a2ec38258283 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 15 Dec 2010 11:04:39 +1000 Subject: drm/nouveau: modify vm to accomodate dual page tables for nvc0 Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_vm.c | 59 ++++++++++++++++------------------ drivers/gpu/drm/nouveau/nouveau_vm.h | 16 ++++----- drivers/gpu/drm/nouveau/nv50_instmem.c | 16 ++++----- drivers/gpu/drm/nouveau/nv50_vm.c | 49 ++++++++++++++-------------- 4 files changed, 65 insertions(+), 75 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_vm.c b/drivers/gpu/drm/nouveau/nouveau_vm.c index 07ab1749cf7d..b023a64c27d8 100644 --- a/drivers/gpu/drm/nouveau/nouveau_vm.c +++ b/drivers/gpu/drm/nouveau/nouveau_vm.c @@ -32,6 +32,7 @@ nouveau_vm_map_at(struct nouveau_vma *vma, u64 delta, struct nouveau_vram *vram) { struct nouveau_vm *vm = vma->vm; struct nouveau_mm_node *r; + int big = vma->node->type != vm->spg_shift; u32 offset = vma->node->offset + (delta >> 12); u32 bits = vma->node->type - 12; u32 pde = (offset >> vm->pgt_bits) - vm->fpde; @@ -44,7 +45,7 @@ nouveau_vm_map_at(struct nouveau_vma *vma, u64 delta, struct nouveau_vram *vram) u32 num = r->length >> bits; while (num) { - struct nouveau_gpuobj *pgt = vm->pgt[pde].obj; + struct nouveau_gpuobj *pgt = vm->pgt[pde].obj[big]; end = (pte + num); if (unlikely(end >= max)) @@ -76,6 +77,7 @@ nouveau_vm_map_sg(struct nouveau_vma *vma, u64 delta, u64 length, dma_addr_t *list) { struct nouveau_vm *vm = vma->vm; + int big = vma->node->type != vm->spg_shift; u32 offset = vma->node->offset + (delta >> 12); u32 bits = vma->node->type - 12; u32 num = length >> vma->node->type; @@ -85,7 +87,7 @@ nouveau_vm_map_sg(struct nouveau_vma *vma, u64 delta, u64 length, u32 end, len; while (num) { - struct nouveau_gpuobj *pgt = vm->pgt[pde].obj; + struct nouveau_gpuobj *pgt = vm->pgt[pde].obj[big]; end = (pte + num); if (unlikely(end >= max)) @@ -110,6 +112,7 @@ void nouveau_vm_unmap_at(struct nouveau_vma *vma, u64 delta, u64 length) { struct nouveau_vm *vm = vma->vm; + int big = vma->node->type != vm->spg_shift; u32 offset = vma->node->offset + (delta >> 12); u32 bits = vma->node->type - 12; u32 num = length >> vma->node->type; @@ -119,7 +122,7 @@ nouveau_vm_unmap_at(struct nouveau_vma *vma, u64 delta, u64 length) u32 end, len; while (num) { - struct nouveau_gpuobj *pgt = vm->pgt[pde].obj; + struct nouveau_gpuobj *pgt = vm->pgt[pde].obj[big]; end = (pte + num); if (unlikely(end >= max)) @@ -146,7 +149,7 @@ nouveau_vm_unmap(struct nouveau_vma *vma) } static void -nouveau_vm_unmap_pgt(struct nouveau_vm *vm, u32 fpde, u32 lpde) +nouveau_vm_unmap_pgt(struct nouveau_vm *vm, int big, u32 fpde, u32 lpde) { struct nouveau_vm_pgd *vpgd; struct nouveau_vm_pgt *vpgt; @@ -155,16 +158,16 @@ nouveau_vm_unmap_pgt(struct nouveau_vm *vm, u32 fpde, u32 lpde) for (pde = fpde; pde <= lpde; pde++) { vpgt = &vm->pgt[pde - vm->fpde]; - if (--vpgt->refcount) + if (--vpgt->refcount[big]) continue; + pgt = vpgt->obj[big]; + vpgt->obj[big] = NULL; + list_for_each_entry(vpgd, &vm->pgd_list, head) { - vm->unmap_pgt(vpgd->obj, pde); + vm->map_pgt(vpgd->obj, pde, vpgt->obj); } - pgt = vpgt->obj; - vpgt->obj = NULL; - mutex_unlock(&vm->mm->mutex); nouveau_gpuobj_ref(NULL, &pgt); mutex_lock(&vm->mm->mutex); @@ -177,6 +180,7 @@ nouveau_vm_map_pgt(struct nouveau_vm *vm, u32 pde, u32 type) struct nouveau_vm_pgt *vpgt = &vm->pgt[pde - vm->fpde]; struct nouveau_vm_pgd *vpgd; struct nouveau_gpuobj *pgt; + int big = (type != vm->spg_shift); u32 pgt_size; int ret; @@ -191,19 +195,18 @@ nouveau_vm_map_pgt(struct nouveau_vm *vm, u32 pde, u32 type) return ret; /* someone beat us to filling the PDE while we didn't have the lock */ - if (unlikely(vpgt->refcount++)) { + if (unlikely(vpgt->refcount[big]++)) { mutex_unlock(&vm->mm->mutex); nouveau_gpuobj_ref(NULL, &pgt); mutex_lock(&vm->mm->mutex); return 0; } + vpgt->obj[big] = pgt; list_for_each_entry(vpgd, &vm->pgd_list, head) { - vm->map_pgt(vpgd->obj, type, pde, pgt); + vm->map_pgt(vpgd->obj, pde, vpgt->obj); } - vpgt->page_shift = type; - vpgt->obj = pgt; return 0; } @@ -227,16 +230,17 @@ nouveau_vm_get(struct nouveau_vm *vm, u64 size, u32 page_shift, lpde = (vma->node->offset + vma->node->length - 1) >> vm->pgt_bits; for (pde = fpde; pde <= lpde; pde++) { struct nouveau_vm_pgt *vpgt = &vm->pgt[pde - vm->fpde]; + int big = (vma->node->type != vm->spg_shift); - if (likely(vpgt->refcount)) { - vpgt->refcount++; + if (likely(vpgt->refcount[big])) { + vpgt->refcount[big]++; continue; } ret = nouveau_vm_map_pgt(vm, pde, vma->node->type); if (ret) { if (pde != fpde) - nouveau_vm_unmap_pgt(vm, fpde, pde - 1); + nouveau_vm_unmap_pgt(vm, big, fpde, pde - 1); nouveau_mm_put(vm->mm, vma->node); mutex_unlock(&vm->mm->mutex); vma->node = NULL; @@ -263,21 +267,20 @@ nouveau_vm_put(struct nouveau_vma *vma) lpde = (vma->node->offset + vma->node->length - 1) >> vm->pgt_bits; mutex_lock(&vm->mm->mutex); + nouveau_vm_unmap_pgt(vm, vma->node->type != vm->spg_shift, fpde, lpde); nouveau_mm_put(vm->mm, vma->node); vma->node = NULL; - nouveau_vm_unmap_pgt(vm, fpde, lpde); mutex_unlock(&vm->mm->mutex); } int nouveau_vm_new(struct drm_device *dev, u64 offset, u64 length, u64 mm_offset, - u8 pgt_bits, u8 spg_shift, u8 lpg_shift, struct nouveau_vm **pvm) { struct drm_nouveau_private *dev_priv = dev->dev_private; struct nouveau_vm *vm; u64 mm_length = (offset + length) - mm_offset; - u32 block; + u32 block, pgt_bits; int ret; vm = kzalloc(sizeof(*vm), GFP_KERNEL); @@ -286,11 +289,13 @@ nouveau_vm_new(struct drm_device *dev, u64 offset, u64 length, u64 mm_offset, if (dev_priv->card_type == NV_50) { vm->map_pgt = nv50_vm_map_pgt; - vm->unmap_pgt = nv50_vm_unmap_pgt; vm->map = nv50_vm_map; vm->map_sg = nv50_vm_map_sg; vm->unmap = nv50_vm_unmap; vm->flush = nv50_vm_flush; + vm->spg_shift = 12; + vm->lpg_shift = 16; + pgt_bits = 29; } else { kfree(vm); return -ENOSYS; @@ -308,8 +313,6 @@ nouveau_vm_new(struct drm_device *dev, u64 offset, u64 length, u64 mm_offset, vm->dev = dev; vm->refcount = 1; vm->pgt_bits = pgt_bits - 12; - vm->spg_shift = spg_shift; - vm->lpg_shift = lpg_shift; block = (1 << pgt_bits); if (length < block) @@ -342,16 +345,8 @@ nouveau_vm_link(struct nouveau_vm *vm, struct nouveau_gpuobj *pgd) nouveau_gpuobj_ref(pgd, &vpgd->obj); mutex_lock(&vm->mm->mutex); - for (i = vm->fpde; i <= vm->lpde; i++) { - struct nouveau_vm_pgt *vpgt = &vm->pgt[i - vm->fpde]; - - if (!vpgt->obj) { - vm->unmap_pgt(pgd, i); - continue; - } - - vm->map_pgt(pgd, vpgt->page_shift, i, vpgt->obj); - } + for (i = vm->fpde; i <= vm->lpde; i++) + vm->map_pgt(pgd, i, vm->pgt[i - vm->fpde].obj); list_add(&vpgd->head, &vm->pgd_list); mutex_unlock(&vm->mm->mutex); return 0; diff --git a/drivers/gpu/drm/nouveau/nouveau_vm.h b/drivers/gpu/drm/nouveau/nouveau_vm.h index b6755cfa7b71..105b6f65f19d 100644 --- a/drivers/gpu/drm/nouveau/nouveau_vm.h +++ b/drivers/gpu/drm/nouveau/nouveau_vm.h @@ -31,9 +31,8 @@ #include "nouveau_mm.h" struct nouveau_vm_pgt { - struct nouveau_gpuobj *obj; - u32 page_shift; - u32 refcount; + struct nouveau_gpuobj *obj[2]; + u32 refcount[2]; }; struct nouveau_vm_pgd { @@ -65,9 +64,8 @@ struct nouveau_vm { u8 spg_shift; u8 lpg_shift; - void (*map_pgt)(struct nouveau_gpuobj *pgd, u32 type, u32 pde, - struct nouveau_gpuobj *pgt); - void (*unmap_pgt)(struct nouveau_gpuobj *pgd, u32 pde); + void (*map_pgt)(struct nouveau_gpuobj *pgd, u32 pde, + struct nouveau_gpuobj *pgt[2]); void (*map)(struct nouveau_vma *, struct nouveau_gpuobj *, struct nouveau_vram *, u32 pte, u32 cnt, u64 phys); void (*map_sg)(struct nouveau_vma *, struct nouveau_gpuobj *, @@ -78,7 +76,6 @@ struct nouveau_vm { /* nouveau_vm.c */ int nouveau_vm_new(struct drm_device *, u64 offset, u64 length, u64 mm_offset, - u8 pgt_bits, u8 spg_shift, u8 lpg_shift, struct nouveau_vm **); int nouveau_vm_ref(struct nouveau_vm *, struct nouveau_vm **, struct nouveau_gpuobj *pgd); @@ -93,9 +90,8 @@ void nouveau_vm_map_sg(struct nouveau_vma *, u64 offset, u64 length, dma_addr_t *); /* nv50_vm.c */ -void nv50_vm_map_pgt(struct nouveau_gpuobj *pgd, u32 type, u32 pde, - struct nouveau_gpuobj *pgt); -void nv50_vm_unmap_pgt(struct nouveau_gpuobj *pgd, u32 pde); +void nv50_vm_map_pgt(struct nouveau_gpuobj *pgd, u32 pde, + struct nouveau_gpuobj *pgt[2]); void nv50_vm_map(struct nouveau_vma *, struct nouveau_gpuobj *, struct nouveau_vram *, u32 pte, u32 cnt, u64 phys); void nv50_vm_map_sg(struct nouveau_vma *, struct nouveau_gpuobj *, diff --git a/drivers/gpu/drm/nouveau/nv50_instmem.c b/drivers/gpu/drm/nouveau/nv50_instmem.c index adac4da98f7e..2e1b1cd19a4b 100644 --- a/drivers/gpu/drm/nouveau/nv50_instmem.c +++ b/drivers/gpu/drm/nouveau/nv50_instmem.c @@ -151,20 +151,19 @@ nv50_instmem_init(struct drm_device *dev) /* BAR3 */ ret = nouveau_vm_new(dev, BAR3_VM_BASE, BAR3_VM_SIZE, BAR3_VM_BASE, - 29, 12, 16, &dev_priv->bar3_vm); + &dev_priv->bar3_vm); if (ret) goto error; ret = nouveau_gpuobj_new(dev, NULL, (BAR3_VM_SIZE >> 12) * 8, 0x1000, NVOBJ_FLAG_DONT_MAP | NVOBJ_FLAG_ZERO_ALLOC, - &dev_priv->bar3_vm->pgt[0].obj); + &dev_priv->bar3_vm->pgt[0].obj[0]); if (ret) goto error; - dev_priv->bar3_vm->pgt[0].page_shift = 12; - dev_priv->bar3_vm->pgt[0].refcount = 1; + dev_priv->bar3_vm->pgt[0].refcount[0] = 1; - nv50_instmem_map(dev_priv->bar3_vm->pgt[0].obj); + nv50_instmem_map(dev_priv->bar3_vm->pgt[0].obj[0]); ret = nv50_channel_new(dev, 128 * 1024, dev_priv->bar3_vm, &chan); if (ret) @@ -195,8 +194,7 @@ nv50_instmem_init(struct drm_device *dev) nv_wo32(chan->ramin, 0, tmp); /* BAR1 */ - ret = nouveau_vm_new(dev, BAR1_VM_BASE, BAR1_VM_SIZE, BAR1_VM_BASE, - 29, 12, 16, &vm); + ret = nouveau_vm_new(dev, BAR1_VM_BASE, BAR1_VM_SIZE, BAR1_VM_BASE, &vm); if (ret) goto error; @@ -220,7 +218,7 @@ nv50_instmem_init(struct drm_device *dev) * to catch "NULL pointer" references */ ret = nouveau_vm_new(dev, 0, (1ULL << 40), 0x0020000000ULL, - 29, 12, 16, &dev_priv->chan_vm); + &dev_priv->chan_vm); if (ret) return ret; @@ -258,7 +256,7 @@ nv50_instmem_takedown(struct drm_device *dev) dev_priv->channels.ptr[127] = 0; nv50_channel_del(&dev_priv->channels.ptr[0]); - nouveau_gpuobj_ref(NULL, &dev_priv->bar3_vm->pgt[0].obj); + nouveau_gpuobj_ref(NULL, &dev_priv->bar3_vm->pgt[0].obj[0]); nouveau_vm_ref(NULL, &dev_priv->bar3_vm, NULL); if (dev_priv->ramin_heap.free_stack.next) diff --git a/drivers/gpu/drm/nouveau/nv50_vm.c b/drivers/gpu/drm/nouveau/nv50_vm.c index 7939387f7f80..38e523e10995 100644 --- a/drivers/gpu/drm/nouveau/nv50_vm.c +++ b/drivers/gpu/drm/nouveau/nv50_vm.c @@ -28,39 +28,40 @@ #include "nouveau_vm.h" void -nv50_vm_map_pgt(struct nouveau_gpuobj *pgd, u32 type, u32 pde, - struct nouveau_gpuobj *pgt) +nv50_vm_map_pgt(struct nouveau_gpuobj *pgd, u32 pde, + struct nouveau_gpuobj *pgt[2]) { struct drm_nouveau_private *dev_priv = pgd->dev->dev_private; - u32 coverage = (pgt->size >> 3) << type; - u64 phys; - - phys = pgt->vinst; - phys |= 0x01; /* present */ - phys |= (type == 12) ? 0x02 : 0x00; /* 4KiB pages */ - if (dev_priv->vram_sys_base) { - phys += dev_priv->vram_sys_base; - phys |= 0x30; + u64 phys = 0xdeadcafe00000000ULL; + u32 coverage = 0; + + if (pgt[0]) { + phys = 0x00000003 | pgt[0]->vinst; /* present, 4KiB pages */ + coverage = (pgt[0]->size >> 3) << 12; + } else + if (pgt[1]) { + phys = 0x00000001 | pgt[1]->vinst; /* present */ + coverage = (pgt[1]->size >> 3) << 16; } - if (coverage <= 32 * 1024 * 1024) - phys |= 0x60; - else if (coverage <= 64 * 1024 * 1024) - phys |= 0x40; - else if (coverage < 128 * 1024 * 1024) - phys |= 0x20; + if (phys & 1) { + if (dev_priv->vram_sys_base) { + phys += dev_priv->vram_sys_base; + phys |= 0x30; + } + + if (coverage <= 32 * 1024 * 1024) + phys |= 0x60; + else if (coverage <= 64 * 1024 * 1024) + phys |= 0x40; + else if (coverage < 128 * 1024 * 1024) + phys |= 0x20; + } nv_wo32(pgd, (pde * 8) + 0, lower_32_bits(phys)); nv_wo32(pgd, (pde * 8) + 4, upper_32_bits(phys)); } -void -nv50_vm_unmap_pgt(struct nouveau_gpuobj *pgd, u32 pde) -{ - nv_wo32(pgd, (pde * 8) + 0, 0x00000000); - nv_wo32(pgd, (pde * 8) + 4, 0xdeadcafe); -} - static inline u64 nv50_vm_addr(struct nouveau_vma *vma, struct nouveau_gpuobj *pgt, u64 phys, u32 memtype, u32 target) -- cgit v1.2.3 From 4c74eb7ff276813ee73943a3756b295675fb2865 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 10 Nov 2010 14:10:04 +1000 Subject: drm/nvc0: import initial vm backend Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/Makefile | 2 +- drivers/gpu/drm/nouveau/nouveau_bo.c | 5 +- drivers/gpu/drm/nouveau/nouveau_drv.h | 1 + drivers/gpu/drm/nouveau/nouveau_mem.c | 4 ++ drivers/gpu/drm/nouveau/nouveau_vm.c | 31 +++++++-- drivers/gpu/drm/nouveau/nouveau_vm.h | 10 +++ drivers/gpu/drm/nouveau/nvc0_vm.c | 123 ++++++++++++++++++++++++++++++++++ 7 files changed, 169 insertions(+), 7 deletions(-) create mode 100644 drivers/gpu/drm/nouveau/nvc0_vm.c diff --git a/drivers/gpu/drm/nouveau/Makefile b/drivers/gpu/drm/nouveau/Makefile index b1d8941e04d8..e89d89593af1 100644 --- a/drivers/gpu/drm/nouveau/Makefile +++ b/drivers/gpu/drm/nouveau/Makefile @@ -28,7 +28,7 @@ nouveau-y := nouveau_drv.o nouveau_state.o nouveau_channel.o nouveau_mem.o \ nv10_gpio.o nv50_gpio.o \ nv50_calc.o \ nv04_pm.o nv50_pm.o nva3_pm.o \ - nv50_vram.o nv50_vm.o + nv50_vram.o nv50_vm.o nvc0_vm.o nouveau-$(CONFIG_DRM_NOUVEAU_DEBUG) += nouveau_debugfs.o nouveau-$(CONFIG_COMPAT) += nouveau_ioc32.o diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index 42d1ad62b381..d17ffea3c617 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c @@ -909,8 +909,9 @@ nouveau_ttm_io_mem_reserve(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem) break; } - ret = nouveau_vm_get(dev_priv->bar1_vm, mem->bus.size, 12, - NV_MEM_ACCESS_RW, &vram->bar_vma); + ret = nouveau_vm_get(dev_priv->bar1_vm, mem->bus.size, + vram->page_shift, NV_MEM_ACCESS_RW, + &vram->bar_vma); if (ret) return ret; diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index 8f13906185b2..57da219fb18b 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -69,6 +69,7 @@ struct nouveau_vram { struct drm_device *dev; struct nouveau_vma bar_vma; + u8 page_shift; struct list_head regions; u32 memtype; diff --git a/drivers/gpu/drm/nouveau/nouveau_mem.c b/drivers/gpu/drm/nouveau/nouveau_mem.c index 224181193a1f..07be1dd04530 100644 --- a/drivers/gpu/drm/nouveau/nouveau_mem.c +++ b/drivers/gpu/drm/nouveau/nouveau_mem.c @@ -731,6 +731,10 @@ nouveau_vram_manager_new(struct ttm_mem_type_manager *man, if (ret) return ret; + node->page_shift = 12; + if (nvbo->vma.node) + node->page_shift = nvbo->vma.node->type; + mem->mm_node = node; mem->start = node->offset >> PAGE_SHIFT; return 0; diff --git a/drivers/gpu/drm/nouveau/nouveau_vm.c b/drivers/gpu/drm/nouveau/nouveau_vm.c index b023a64c27d8..97d82aedf86b 100644 --- a/drivers/gpu/drm/nouveau/nouveau_vm.c +++ b/drivers/gpu/drm/nouveau/nouveau_vm.c @@ -295,7 +295,34 @@ nouveau_vm_new(struct drm_device *dev, u64 offset, u64 length, u64 mm_offset, vm->flush = nv50_vm_flush; vm->spg_shift = 12; vm->lpg_shift = 16; + pgt_bits = 29; + block = (1 << pgt_bits); + if (length < block) + block = length; + + } else + if (dev_priv->card_type == NV_C0) { + vm->map_pgt = nvc0_vm_map_pgt; + vm->map = nvc0_vm_map; + vm->map_sg = nvc0_vm_map_sg; + vm->unmap = nvc0_vm_unmap; + vm->flush = nvc0_vm_flush; + vm->spg_shift = 12; + vm->lpg_shift = 17; + pgt_bits = 27; + + /* Should be 4096 everywhere, this is a hack that's + * currently necessary to avoid an elusive bug that + * causes corruption when mixing small/large pages + */ + if (length < (1ULL << 40)) + block = 4096; + else { + block = (1 << pgt_bits); + if (length < block) + block = length; + } } else { kfree(vm); return -ENOSYS; @@ -314,10 +341,6 @@ nouveau_vm_new(struct drm_device *dev, u64 offset, u64 length, u64 mm_offset, vm->refcount = 1; vm->pgt_bits = pgt_bits - 12; - block = (1 << pgt_bits); - if (length < block) - block = length; - ret = nouveau_mm_init(&vm->mm, mm_offset >> 12, mm_length >> 12, block >> 12); if (ret) { diff --git a/drivers/gpu/drm/nouveau/nouveau_vm.h b/drivers/gpu/drm/nouveau/nouveau_vm.h index 105b6f65f19d..e1193515771b 100644 --- a/drivers/gpu/drm/nouveau/nouveau_vm.h +++ b/drivers/gpu/drm/nouveau/nouveau_vm.h @@ -100,4 +100,14 @@ void nv50_vm_unmap(struct nouveau_gpuobj *, u32 pte, u32 cnt); void nv50_vm_flush(struct nouveau_vm *); void nv50_vm_flush_engine(struct drm_device *, int engine); +/* nvc0_vm.c */ +void nvc0_vm_map_pgt(struct nouveau_gpuobj *pgd, u32 pde, + struct nouveau_gpuobj *pgt[2]); +void nvc0_vm_map(struct nouveau_vma *, struct nouveau_gpuobj *, + struct nouveau_vram *, u32 pte, u32 cnt, u64 phys); +void nvc0_vm_map_sg(struct nouveau_vma *, struct nouveau_gpuobj *, + u32 pte, dma_addr_t *, u32 cnt); +void nvc0_vm_unmap(struct nouveau_gpuobj *, u32 pte, u32 cnt); +void nvc0_vm_flush(struct nouveau_vm *); + #endif diff --git a/drivers/gpu/drm/nouveau/nvc0_vm.c b/drivers/gpu/drm/nouveau/nvc0_vm.c new file mode 100644 index 000000000000..4b9251bb0ff4 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvc0_vm.c @@ -0,0 +1,123 @@ +/* + * Copyright 2010 Red Hat Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: Ben Skeggs + */ + +#include "drmP.h" + +#include "nouveau_drv.h" +#include "nouveau_vm.h" + +void +nvc0_vm_map_pgt(struct nouveau_gpuobj *pgd, u32 index, + struct nouveau_gpuobj *pgt[2]) +{ + u32 pde[2] = { 0, 0 }; + + if (pgt[0]) + pde[1] = 0x00000001 | (pgt[0]->vinst >> 8); + if (pgt[1]) + pde[0] = 0x00000001 | (pgt[1]->vinst >> 8); + + nv_wo32(pgd, (index * 8) + 0, pde[0]); + nv_wo32(pgd, (index * 8) + 4, pde[1]); +} + +static inline u64 +nvc0_vm_addr(struct nouveau_vma *vma, u64 phys, u32 memtype, u32 target) +{ + phys >>= 8; + + phys |= 0x00000001; /* present */ +// if (vma->access & NV_MEM_ACCESS_SYS) +// phys |= 0x00000002; + + phys |= ((u64)target << 32); + phys |= ((u64)memtype << 36); + + return phys; +} + +void +nvc0_vm_map(struct nouveau_vma *vma, struct nouveau_gpuobj *pgt, + struct nouveau_vram *mem, u32 pte, u32 cnt, u64 phys) +{ + u32 next = 1 << (vma->node->type - 8); + + phys = nvc0_vm_addr(vma, phys, mem->memtype, 0); + pte <<= 3; + while (cnt--) { + nv_wo32(pgt, pte + 0, lower_32_bits(phys)); + nv_wo32(pgt, pte + 4, upper_32_bits(phys)); + phys += next; + pte += 8; + } +} + +void +nvc0_vm_map_sg(struct nouveau_vma *vma, struct nouveau_gpuobj *pgt, + u32 pte, dma_addr_t *list, u32 cnt) +{ + pte <<= 3; + while (cnt--) { + u64 phys = nvc0_vm_addr(vma, *list++, 0, 5); + nv_wo32(pgt, pte + 0, lower_32_bits(phys)); + nv_wo32(pgt, pte + 4, upper_32_bits(phys)); + pte += 8; + } +} + +void +nvc0_vm_unmap(struct nouveau_gpuobj *pgt, u32 pte, u32 cnt) +{ + pte <<= 3; + while (cnt--) { + nv_wo32(pgt, pte + 0, 0x00000000); + nv_wo32(pgt, pte + 4, 0x00000000); + pte += 8; + } +} + +void +nvc0_vm_flush(struct nouveau_vm *vm) +{ + struct drm_nouveau_private *dev_priv = vm->dev->dev_private; + struct nouveau_instmem_engine *pinstmem = &dev_priv->engine.instmem; + struct drm_device *dev = vm->dev; + struct nouveau_vm_pgd *vpgd; + u32 r100c80, engine; + + pinstmem->flush(vm->dev); + + if (vm == dev_priv->chan_vm) + engine = 1; + else + engine = 5; + + list_for_each_entry(vpgd, &vm->pgd_list, head) { + r100c80 = nv_rd32(dev, 0x100c80); + nv_wr32(dev, 0x100cb8, vpgd->obj->vinst >> 8); + nv_wr32(dev, 0x100cbc, 0x80000000 | engine); + if (!nv_wait(dev, 0x100c80, 0xffffffff, r100c80)) + NV_ERROR(dev, "vm flush timeout eng %d\n", engine); + } +} -- cgit v1.2.3 From 8984e046153eb1d6b0b24626169f9c6e58232e1b Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 15 Nov 2010 11:48:33 +1000 Subject: drm/nvc0: initial vm implementation, use for bar1/bar3 management Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/Makefile | 3 +- drivers/gpu/drm/nouveau/nouveau_bo.c | 18 +- drivers/gpu/drm/nouveau/nouveau_drv.h | 8 +- drivers/gpu/drm/nouveau/nouveau_mem.c | 3 - drivers/gpu/drm/nouveau/nouveau_mm.h | 5 + drivers/gpu/drm/nouveau/nouveau_state.c | 16 +- drivers/gpu/drm/nouveau/nvc0_instmem.c | 326 ++++++++++++++------------------ drivers/gpu/drm/nouveau/nvc0_vram.c | 91 +++++++++ 8 files changed, 266 insertions(+), 204 deletions(-) create mode 100644 drivers/gpu/drm/nouveau/nvc0_vram.c diff --git a/drivers/gpu/drm/nouveau/Makefile b/drivers/gpu/drm/nouveau/Makefile index e89d89593af1..d9d22ffff81e 100644 --- a/drivers/gpu/drm/nouveau/Makefile +++ b/drivers/gpu/drm/nouveau/Makefile @@ -28,7 +28,8 @@ nouveau-y := nouveau_drv.o nouveau_state.o nouveau_channel.o nouveau_mem.o \ nv10_gpio.o nv50_gpio.o \ nv50_calc.o \ nv04_pm.o nv50_pm.o nva3_pm.o \ - nv50_vram.o nv50_vm.o nvc0_vm.o + nv50_vram.o nvc0_vram.o \ + nv50_vm.o nvc0_vm.o nouveau-$(CONFIG_DRM_NOUVEAU_DEBUG) += nouveau_debugfs.o nouveau-$(CONFIG_COMPAT) += nouveau_ioc32.o diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index d17ffea3c617..6f3096a50297 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c @@ -120,6 +120,9 @@ nouveau_bo_new(struct drm_device *dev, struct nouveau_channel *chan, align >>= PAGE_SHIFT; if (!nvbo->no_vm && dev_priv->chan_vm) { + if (dev_priv->card_type == NV_C0) + page_shift = 12; + ret = nouveau_vm_get(dev_priv->chan_vm, size, page_shift, NV_MEM_ACCESS_RW, &nvbo->vma); if (ret) { @@ -413,7 +416,7 @@ nouveau_bo_init_mem_type(struct ttm_bo_device *bdev, uint32_t type, man->default_caching = TTM_PL_FLAG_CACHED; break; case TTM_PL_VRAM: - if (dev_priv->card_type == NV_50) { + if (dev_priv->card_type >= NV_50) { man->func = &nouveau_vram_manager; man->io_reserve_fastpath = false; man->use_io_reserve_lru = true; @@ -901,6 +904,7 @@ nouveau_ttm_io_mem_reserve(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem) case TTM_PL_VRAM: { struct nouveau_vram *vram = mem->mm_node; + u8 page_shift; if (!dev_priv->bar1_vm) { mem->bus.offset = mem->start << PAGE_SHIFT; @@ -909,8 +913,13 @@ nouveau_ttm_io_mem_reserve(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem) break; } + if (dev_priv->card_type == NV_C0) + page_shift = vram->page_shift; + else + page_shift = 12; + ret = nouveau_vm_get(dev_priv->bar1_vm, mem->bus.size, - vram->page_shift, NV_MEM_ACCESS_RW, + page_shift, NV_MEM_ACCESS_RW, &vram->bar_vma); if (ret) return ret; @@ -921,8 +930,9 @@ nouveau_ttm_io_mem_reserve(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem) return ret; } - mem->bus.offset = vram->bar_vma.offset; - mem->bus.offset -= 0x0020000000ULL; + mem->bus.offset = vram->bar_vma.offset; + if (dev_priv->card_type == NV_50) /*XXX*/ + mem->bus.offset -= 0x0020000000ULL; mem->bus.base = pci_resource_start(dev->pdev, 1); mem->bus.is_iomem = true; } diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index 57da219fb18b..c1e85c4c7ac2 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -842,6 +842,9 @@ extern void nv10_mem_put_tile_region(struct drm_device *dev, struct nouveau_fence *fence); extern const struct ttm_mem_type_manager_func nouveau_vram_manager; +/* nvc0_vram.c */ +extern const struct ttm_mem_type_manager_func nvc0_vram_manager; + /* nouveau_notifier.c */ extern int nouveau_notifier_init_channel(struct nouveau_channel *); extern void nouveau_notifier_takedown_channel(struct nouveau_channel *); @@ -1229,11 +1232,6 @@ extern int nvc0_instmem_init(struct drm_device *); extern void nvc0_instmem_takedown(struct drm_device *); extern int nvc0_instmem_suspend(struct drm_device *); extern void nvc0_instmem_resume(struct drm_device *); -extern int nvc0_instmem_get(struct nouveau_gpuobj *, u32 size, u32 align); -extern void nvc0_instmem_put(struct nouveau_gpuobj *); -extern int nvc0_instmem_map(struct nouveau_gpuobj *); -extern void nvc0_instmem_unmap(struct nouveau_gpuobj *); -extern void nvc0_instmem_flush(struct drm_device *); /* nv04_mc.c */ extern int nv04_mc_init(struct drm_device *); diff --git a/drivers/gpu/drm/nouveau/nouveau_mem.c b/drivers/gpu/drm/nouveau/nouveau_mem.c index 07be1dd04530..69044eb104bb 100644 --- a/drivers/gpu/drm/nouveau/nouveau_mem.c +++ b/drivers/gpu/drm/nouveau/nouveau_mem.c @@ -255,9 +255,6 @@ nouveau_mem_detect(struct drm_device *dev) if (dev_priv->card_type < NV_50) { dev_priv->vram_size = nv_rd32(dev, NV04_PFB_FIFO_DATA); dev_priv->vram_size &= NV10_PFB_FIFO_DATA_RAM_AMOUNT_MB_MASK; - } else { - dev_priv->vram_size = nv_rd32(dev, 0x10f20c) << 20; - dev_priv->vram_size *= nv_rd32(dev, 0x121c74); } if (dev_priv->vram_size) diff --git a/drivers/gpu/drm/nouveau/nouveau_mm.h b/drivers/gpu/drm/nouveau/nouveau_mm.h index 250e642de0a7..af3844933036 100644 --- a/drivers/gpu/drm/nouveau/nouveau_mm.h +++ b/drivers/gpu/drm/nouveau/nouveau_mm.h @@ -59,4 +59,9 @@ int nv50_vram_new(struct drm_device *, u64 size, u32 align, u32 size_nc, void nv50_vram_del(struct drm_device *, struct nouveau_vram **); bool nv50_vram_flags_valid(struct drm_device *, u32 tile_flags); +int nvc0_vram_init(struct drm_device *); +int nvc0_vram_new(struct drm_device *, u64 size, u32 align, u32 ncmin, + u32 memtype, struct nouveau_vram **); +bool nvc0_vram_flags_valid(struct drm_device *, u32 tile_flags); + #endif diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c index 8eac943e8fd2..813790f4c7c7 100644 --- a/drivers/gpu/drm/nouveau/nouveau_state.c +++ b/drivers/gpu/drm/nouveau/nouveau_state.c @@ -464,11 +464,11 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->instmem.takedown = nvc0_instmem_takedown; engine->instmem.suspend = nvc0_instmem_suspend; engine->instmem.resume = nvc0_instmem_resume; - engine->instmem.get = nvc0_instmem_get; - engine->instmem.put = nvc0_instmem_put; - engine->instmem.map = nvc0_instmem_map; - engine->instmem.unmap = nvc0_instmem_unmap; - engine->instmem.flush = nvc0_instmem_flush; + engine->instmem.get = nv50_instmem_get; + engine->instmem.put = nv50_instmem_put; + engine->instmem.map = nv50_instmem_map; + engine->instmem.unmap = nv50_instmem_unmap; + engine->instmem.flush = nv84_instmem_flush; engine->mc.init = nv50_mc_init; engine->mc.takedown = nv50_mc_takedown; engine->timer.init = nv04_timer_init; @@ -509,8 +509,10 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) engine->gpio.irq_enable = nv50_gpio_irq_enable; engine->crypt.init = nouveau_stub_init; engine->crypt.takedown = nouveau_stub_takedown; - engine->vram.init = nouveau_mem_detect; - engine->vram.flags_valid = nouveau_mem_flags_valid; + engine->vram.init = nvc0_vram_init; + engine->vram.get = nvc0_vram_new; + engine->vram.put = nv50_vram_del; + engine->vram.flags_valid = nvc0_vram_flags_valid; break; default: NV_ERROR(dev, "NV%02x unsupported\n", dev_priv->chipset); diff --git a/drivers/gpu/drm/nouveau/nvc0_instmem.c b/drivers/gpu/drm/nouveau/nvc0_instmem.c index 39232085193d..211099736553 100644 --- a/drivers/gpu/drm/nouveau/nvc0_instmem.c +++ b/drivers/gpu/drm/nouveau/nvc0_instmem.c @@ -25,233 +25,191 @@ #include "drmP.h" #include "nouveau_drv.h" +#include "nouveau_vm.h" -struct nvc0_gpuobj_node { - struct nouveau_bo *vram; - struct drm_mm_node *ramin; - u32 align; +struct nvc0_instmem_priv { + struct nouveau_gpuobj *bar1_pgd; + struct nouveau_channel *bar1; + struct nouveau_gpuobj *bar3_pgd; + struct nouveau_channel *bar3; }; int -nvc0_instmem_get(struct nouveau_gpuobj *gpuobj, u32 size, u32 align) +nvc0_instmem_suspend(struct drm_device *dev) { - struct drm_device *dev = gpuobj->dev; - struct nvc0_gpuobj_node *node = NULL; - int ret; - - node = kzalloc(sizeof(*node), GFP_KERNEL); - if (!node) - return -ENOMEM; - node->align = align; - - ret = nouveau_bo_new(dev, NULL, size, align, TTM_PL_FLAG_VRAM, - 0, 0x0000, true, false, &node->vram); - if (ret) { - NV_ERROR(dev, "error getting PRAMIN backing pages: %d\n", ret); - return ret; - } - - ret = nouveau_bo_pin(node->vram, TTM_PL_FLAG_VRAM); - if (ret) { - NV_ERROR(dev, "error pinning PRAMIN backing VRAM: %d\n", ret); - nouveau_bo_ref(NULL, &node->vram); - return ret; - } + struct drm_nouveau_private *dev_priv = dev->dev_private; - gpuobj->vinst = node->vram->bo.mem.start << PAGE_SHIFT; - gpuobj->size = node->vram->bo.mem.num_pages << PAGE_SHIFT; - gpuobj->node = node; + dev_priv->ramin_available = false; return 0; } void -nvc0_instmem_put(struct nouveau_gpuobj *gpuobj) +nvc0_instmem_resume(struct drm_device *dev) { - struct nvc0_gpuobj_node *node; - - node = gpuobj->node; - gpuobj->node = NULL; + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nvc0_instmem_priv *priv = dev_priv->engine.instmem.priv; - nouveau_bo_unpin(node->vram); - nouveau_bo_ref(NULL, &node->vram); - kfree(node); + nv_mask(dev, 0x100c80, 0x00000001, 0x00000000); + nv_wr32(dev, 0x001704, 0x80000000 | priv->bar1->ramin->vinst >> 12); + nv_wr32(dev, 0x001714, 0xc0000000 | priv->bar3->ramin->vinst >> 12); + dev_priv->ramin_available = true; } -int -nvc0_instmem_map(struct nouveau_gpuobj *gpuobj) +static void +nvc0_channel_del(struct nouveau_channel **pchan) { - struct drm_nouveau_private *dev_priv = gpuobj->dev->dev_private; - struct nvc0_gpuobj_node *node = gpuobj->node; - struct drm_device *dev = gpuobj->dev; - struct drm_mm_node *ramin = NULL; - u32 pte, pte_end; - u64 vram; - - do { - if (drm_mm_pre_get(&dev_priv->ramin_heap)) - return -ENOMEM; - - spin_lock(&dev_priv->ramin_lock); - ramin = drm_mm_search_free(&dev_priv->ramin_heap, gpuobj->size, - node->align, 0); - if (ramin == NULL) { - spin_unlock(&dev_priv->ramin_lock); - return -ENOMEM; - } - - ramin = drm_mm_get_block_atomic(ramin, gpuobj->size, node->align); - spin_unlock(&dev_priv->ramin_lock); - } while (ramin == NULL); - - pte = (ramin->start >> 12) << 1; - pte_end = ((ramin->size >> 12) << 1) + pte; - vram = gpuobj->vinst; - - NV_DEBUG(dev, "pramin=0x%lx, pte=%d, pte_end=%d\n", - ramin->start, pte, pte_end); - NV_DEBUG(dev, "first vram page: 0x%010llx\n", gpuobj->vinst); - - while (pte < pte_end) { - nv_wr32(dev, 0x702000 + (pte * 8), (vram >> 8) | 1); - nv_wr32(dev, 0x702004 + (pte * 8), 0); - vram += 4096; - pte++; - } - dev_priv->engine.instmem.flush(dev); + struct nouveau_channel *chan; - if (1) { - u32 chan = nv_rd32(dev, 0x1700) << 16; - nv_wr32(dev, 0x100cb8, (chan + 0x1000) >> 8); - nv_wr32(dev, 0x100cbc, 0x80000005); - } + chan = *pchan; + *pchan = NULL; + if (!chan) + return; - node->ramin = ramin; - gpuobj->pinst = ramin->start; - return 0; + nouveau_vm_ref(NULL, &chan->vm, NULL); + if (chan->ramin_heap.free_stack.next) + drm_mm_takedown(&chan->ramin_heap); + nouveau_gpuobj_ref(NULL, &chan->ramin); + kfree(chan); } -void -nvc0_instmem_unmap(struct nouveau_gpuobj *gpuobj) +static int +nvc0_channel_new(struct drm_device *dev, u32 size, struct nouveau_vm *vm, + struct nouveau_channel **pchan, + struct nouveau_gpuobj *pgd, u64 vm_size) { - struct drm_nouveau_private *dev_priv = gpuobj->dev->dev_private; - struct nvc0_gpuobj_node *node = gpuobj->node; - u32 pte, pte_end; + struct nouveau_channel *chan; + int ret; - if (!node->ramin || !dev_priv->ramin_available) - return; + chan = kzalloc(sizeof(*chan), GFP_KERNEL); + if (!chan) + return -ENOMEM; + chan->dev = dev; - pte = (node->ramin->start >> 12) << 1; - pte_end = ((node->ramin->size >> 12) << 1) + pte; + ret = nouveau_gpuobj_new(dev, NULL, size, 0x1000, 0, &chan->ramin); + if (ret) { + nvc0_channel_del(&chan); + return ret; + } - while (pte < pte_end) { - nv_wr32(gpuobj->dev, 0x702000 + (pte * 8), 0); - nv_wr32(gpuobj->dev, 0x702004 + (pte * 8), 0); - pte++; + ret = drm_mm_init(&chan->ramin_heap, 0x1000, size - 0x1000); + if (ret) { + nvc0_channel_del(&chan); + return ret; } - dev_priv->engine.instmem.flush(gpuobj->dev); - spin_lock(&dev_priv->ramin_lock); - drm_mm_put_block(node->ramin); - node->ramin = NULL; - spin_unlock(&dev_priv->ramin_lock); -} + ret = nouveau_vm_ref(vm, &chan->vm, NULL); + if (ret) { + nvc0_channel_del(&chan); + return ret; + } -void -nvc0_instmem_flush(struct drm_device *dev) -{ - nv_wr32(dev, 0x070000, 1); - if (!nv_wait(dev, 0x070000, 0x00000002, 0x00000000)) - NV_ERROR(dev, "PRAMIN flush timeout\n"); + nv_wo32(chan->ramin, 0x0200, lower_32_bits(pgd->vinst)); + nv_wo32(chan->ramin, 0x0204, upper_32_bits(pgd->vinst)); + nv_wo32(chan->ramin, 0x0208, lower_32_bits(vm_size - 1)); + nv_wo32(chan->ramin, 0x020c, upper_32_bits(vm_size - 1)); + + *pchan = chan; + return 0; } int -nvc0_instmem_suspend(struct drm_device *dev) +nvc0_instmem_init(struct drm_device *dev) { struct drm_nouveau_private *dev_priv = dev->dev_private; - u32 *buf; - int i; + struct nouveau_instmem_engine *pinstmem = &dev_priv->engine.instmem; + struct pci_dev *pdev = dev->pdev; + struct nvc0_instmem_priv *priv; + struct nouveau_vm *vm = NULL; + int ret; - dev_priv->susres.ramin_copy = vmalloc(65536); - if (!dev_priv->susres.ramin_copy) + priv = kzalloc(sizeof(*priv), GFP_KERNEL); + if (!priv) return -ENOMEM; - buf = dev_priv->susres.ramin_copy; - - for (i = 0; i < 65536; i += 4) - buf[i/4] = nv_rd32(dev, NV04_PRAMIN + i); + pinstmem->priv = priv; + + /* BAR3 VM */ + ret = nouveau_vm_new(dev, 0, pci_resource_len(pdev, 3), 0, + &dev_priv->bar3_vm); + if (ret) + goto error; + + ret = nouveau_gpuobj_new(dev, NULL, + (pci_resource_len(pdev, 3) >> 12) * 8, 0, + NVOBJ_FLAG_DONT_MAP | + NVOBJ_FLAG_ZERO_ALLOC, + &dev_priv->bar3_vm->pgt[0].obj[0]); + if (ret) + goto error; + dev_priv->bar3_vm->pgt[0].refcount[0] = 1; + + nv50_instmem_map(dev_priv->bar3_vm->pgt[0].obj[0]); + + ret = nouveau_gpuobj_new(dev, NULL, 0x8000, 4096, + NVOBJ_FLAG_ZERO_ALLOC, &priv->bar3_pgd); + if (ret) + goto error; + + ret = nouveau_vm_ref(dev_priv->bar3_vm, &vm, priv->bar3_pgd); + if (ret) + goto error; + nouveau_vm_ref(NULL, &vm, NULL); + + ret = nvc0_channel_new(dev, 8192, dev_priv->bar3_vm, &priv->bar3, + priv->bar3_pgd, pci_resource_len(dev->pdev, 3)); + if (ret) + goto error; + + /* BAR1 VM */ + ret = nouveau_vm_new(dev, 0, pci_resource_len(pdev, 1), 0, &vm); + if (ret) + goto error; + + ret = nouveau_gpuobj_new(dev, NULL, 0x8000, 4096, + NVOBJ_FLAG_ZERO_ALLOC, &priv->bar1_pgd); + if (ret) + goto error; + + ret = nouveau_vm_ref(vm, &dev_priv->bar1_vm, priv->bar1_pgd); + if (ret) + goto error; + nouveau_vm_ref(NULL, &vm, NULL); + + ret = nvc0_channel_new(dev, 8192, dev_priv->bar1_vm, &priv->bar1, + priv->bar1_pgd, pci_resource_len(dev->pdev, 1)); + if (ret) + goto error; + + nvc0_instmem_resume(dev); return 0; +error: + nvc0_instmem_takedown(dev); + return ret; } void -nvc0_instmem_resume(struct drm_device *dev) -{ - struct drm_nouveau_private *dev_priv = dev->dev_private; - u32 *buf = dev_priv->susres.ramin_copy; - u64 chan; - int i; - - chan = dev_priv->vram_size - dev_priv->ramin_rsvd_vram; - nv_wr32(dev, 0x001700, chan >> 16); - - for (i = 0; i < 65536; i += 4) - nv_wr32(dev, NV04_PRAMIN + i, buf[i/4]); - vfree(dev_priv->susres.ramin_copy); - dev_priv->susres.ramin_copy = NULL; - - nv_wr32(dev, 0x001714, 0xc0000000 | (chan >> 12)); -} - -int -nvc0_instmem_init(struct drm_device *dev) +nvc0_instmem_takedown(struct drm_device *dev) { struct drm_nouveau_private *dev_priv = dev->dev_private; - u64 chan, pgt3, imem, lim3 = dev_priv->ramin_size - 1; - int ret, i; - - dev_priv->ramin_rsvd_vram = 1 * 1024 * 1024; - chan = dev_priv->vram_size - dev_priv->ramin_rsvd_vram; - imem = 4096 + 4096 + 32768; - - nv_wr32(dev, 0x001700, chan >> 16); - - /* channel setup */ - nv_wr32(dev, 0x700200, lower_32_bits(chan + 0x1000)); - nv_wr32(dev, 0x700204, upper_32_bits(chan + 0x1000)); - nv_wr32(dev, 0x700208, lower_32_bits(lim3)); - nv_wr32(dev, 0x70020c, upper_32_bits(lim3)); - - /* point pgd -> pgt */ - nv_wr32(dev, 0x701000, 0); - nv_wr32(dev, 0x701004, ((chan + 0x2000) >> 8) | 1); - - /* point pgt -> physical vram for channel */ - pgt3 = 0x2000; - for (i = 0; i < dev_priv->ramin_rsvd_vram; i += 4096, pgt3 += 8) { - nv_wr32(dev, 0x700000 + pgt3, ((chan + i) >> 8) | 1); - nv_wr32(dev, 0x700004 + pgt3, 0); - } + struct nvc0_instmem_priv *priv = dev_priv->engine.instmem.priv; + struct nouveau_vm *vm = NULL; - /* clear rest of pgt */ - for (; i < dev_priv->ramin_size; i += 4096, pgt3 += 8) { - nv_wr32(dev, 0x700000 + pgt3, 0); - nv_wr32(dev, 0x700004 + pgt3, 0); - } + nvc0_instmem_suspend(dev); - /* point bar3 at the channel */ - nv_wr32(dev, 0x001714, 0xc0000000 | (chan >> 12)); + nv_wr32(dev, 0x1704, 0x00000000); + nv_wr32(dev, 0x1714, 0x00000000); - /* Global PRAMIN heap */ - ret = drm_mm_init(&dev_priv->ramin_heap, imem, - dev_priv->ramin_size - imem); - if (ret) { - NV_ERROR(dev, "Failed to init RAMIN heap\n"); - return -ENOMEM; - } + nvc0_channel_del(&priv->bar1); + nouveau_vm_ref(NULL, &dev_priv->bar1_vm, priv->bar1_pgd); + nouveau_gpuobj_ref(NULL, &priv->bar1_pgd); - return 0; -} + nvc0_channel_del(&priv->bar3); + nouveau_vm_ref(dev_priv->bar3_vm, &vm, NULL); + nouveau_vm_ref(NULL, &vm, priv->bar3_pgd); + nouveau_gpuobj_ref(NULL, &priv->bar3_pgd); + nouveau_gpuobj_ref(NULL, &dev_priv->bar3_vm->pgt[0].obj[0]); + nouveau_vm_ref(NULL, &dev_priv->bar3_vm, NULL); -void -nvc0_instmem_takedown(struct drm_device *dev) -{ + dev_priv->engine.instmem.priv = NULL; + kfree(priv); } diff --git a/drivers/gpu/drm/nouveau/nvc0_vram.c b/drivers/gpu/drm/nouveau/nvc0_vram.c new file mode 100644 index 000000000000..41fcae5ffba4 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvc0_vram.c @@ -0,0 +1,91 @@ +/* + * Copyright 2010 Red Hat Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: Ben Skeggs + */ + +#include "drmP.h" +#include "nouveau_drv.h" +#include "nouveau_mm.h" + +bool +nvc0_vram_flags_valid(struct drm_device *dev, u32 tile_flags) +{ + if (likely(!(tile_flags & NOUVEAU_GEM_TILE_LAYOUT_MASK))) + return true; + return false; +} + +int +nvc0_vram_new(struct drm_device *dev, u64 size, u32 align, u32 ncmin, + u32 type, struct nouveau_vram **pvram) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct ttm_bo_device *bdev = &dev_priv->ttm.bdev; + struct ttm_mem_type_manager *man = &bdev->man[TTM_PL_VRAM]; + struct nouveau_mm *mm = man->priv; + struct nouveau_mm_node *r; + struct nouveau_vram *vram; + int ret; + + size >>= 12; + align >>= 12; + ncmin >>= 12; + + vram = kzalloc(sizeof(*vram), GFP_KERNEL); + if (!vram) + return -ENOMEM; + + INIT_LIST_HEAD(&vram->regions); + vram->dev = dev_priv->dev; + vram->memtype = type; + vram->size = size; + + mutex_lock(&mm->mutex); + do { + ret = nouveau_mm_get(mm, 1, size, ncmin, align, &r); + if (ret) { + mutex_unlock(&mm->mutex); + nv50_vram_del(dev, &vram); + return ret; + } + + list_add_tail(&r->rl_entry, &vram->regions); + size -= r->length; + } while (size); + mutex_unlock(&mm->mutex); + + r = list_first_entry(&vram->regions, struct nouveau_mm_node, rl_entry); + vram->offset = (u64)r->offset << 12; + *pvram = vram; + return 0; +} + +int +nvc0_vram_init(struct drm_device *dev) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + + dev_priv->vram_size = nv_rd32(dev, 0x10f20c) << 20; + dev_priv->vram_size *= nv_rd32(dev, 0x121c74); + dev_priv->vram_rblock_size = 4096; + return 0; +} -- cgit v1.2.3 From 99805566d93d69b7daf2373aba9fae52a62396f4 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Tue, 16 Nov 2010 14:58:42 +1000 Subject: drm/nvc0: create shared channel vm Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvc0_instmem.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/drivers/gpu/drm/nouveau/nvc0_instmem.c b/drivers/gpu/drm/nouveau/nvc0_instmem.c index 211099736553..c09091749054 100644 --- a/drivers/gpu/drm/nouveau/nvc0_instmem.c +++ b/drivers/gpu/drm/nouveau/nvc0_instmem.c @@ -32,6 +32,7 @@ struct nvc0_instmem_priv { struct nouveau_channel *bar1; struct nouveau_gpuobj *bar3_pgd; struct nouveau_channel *bar3; + struct nouveau_gpuobj *chan_pgd; }; int @@ -179,6 +180,18 @@ nvc0_instmem_init(struct drm_device *dev) if (ret) goto error; + /* channel vm */ + ret = nouveau_vm_new(dev, 0, (1ULL << 40), 0x0008000000ULL, &vm); + if (ret) + goto error; + + ret = nouveau_gpuobj_new(dev, NULL, 0x8000, 4096, 0, &priv->chan_pgd); + if (ret) + goto error; + + nouveau_vm_ref(vm, &dev_priv->chan_vm, priv->chan_pgd); + nouveau_vm_ref(NULL, &vm, NULL); + nvc0_instmem_resume(dev); return 0; error: @@ -198,6 +211,9 @@ nvc0_instmem_takedown(struct drm_device *dev) nv_wr32(dev, 0x1704, 0x00000000); nv_wr32(dev, 0x1714, 0x00000000); + nouveau_vm_ref(NULL, &dev_priv->chan_vm, priv->chan_pgd); + nouveau_gpuobj_ref(NULL, &priv->chan_pgd); + nvc0_channel_del(&priv->bar1); nouveau_vm_ref(NULL, &dev_priv->bar1_vm, priv->bar1_pgd); nouveau_gpuobj_ref(NULL, &priv->bar1_pgd); -- cgit v1.2.3 From 587107b690f567690982fb504047e7b0a6590344 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 24 Nov 2010 10:07:21 +1000 Subject: drm/nvc0: reject the notifier_alloc ioctl Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_notifier.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/gpu/drm/nouveau/nouveau_notifier.c b/drivers/gpu/drm/nouveau/nouveau_notifier.c index a050b7b69782..fe29d604b820 100644 --- a/drivers/gpu/drm/nouveau/nouveau_notifier.c +++ b/drivers/gpu/drm/nouveau/nouveau_notifier.c @@ -164,10 +164,15 @@ int nouveau_ioctl_notifier_alloc(struct drm_device *dev, void *data, struct drm_file *file_priv) { + struct drm_nouveau_private *dev_priv = dev->dev_private; struct drm_nouveau_notifierobj_alloc *na = data; struct nouveau_channel *chan; int ret; + /* completely unnecessary for these chipsets... */ + if (unlikely(dev_priv->card_type >= NV_C0)) + return -EINVAL; + chan = nouveau_channel_get(dev, file_priv, na->channel); if (IS_ERR(chan)) return PTR_ERR(chan); -- cgit v1.2.3 From 7460d70355eb568817296d6d3364f72d72eeba70 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 24 Nov 2010 10:10:23 +1000 Subject: drm/nvc0: gpuobj_new need only check validity and init the relevant engine Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_object.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_object.c b/drivers/gpu/drm/nouveau/nouveau_object.c index 55c9fdcfa67f..c64fd971b867 100644 --- a/drivers/gpu/drm/nouveau/nouveau_object.c +++ b/drivers/gpu/drm/nouveau/nouveau_object.c @@ -643,10 +643,13 @@ nouveau_gpuobj_gr_new(struct nouveau_channel *chan, u32 handle, int class) found: switch (oc->engine) { case NVOBJ_ENGINE_SW: - ret = nouveau_gpuobj_sw_new(chan, class, &gpuobj); - if (ret) - return ret; - goto insert; + if (dev_priv->card_type < NV_C0) { + ret = nouveau_gpuobj_sw_new(chan, class, &gpuobj); + if (ret) + return ret; + goto insert; + } + break; case NVOBJ_ENGINE_GR: if (dev_priv->card_type >= NV_50 && !chan->ramin_grctx) { struct nouveau_pgraph_engine *pgraph = @@ -669,6 +672,10 @@ found: break; } + /* we're done if this is fermi */ + if (dev_priv->card_type >= NV_C0) + return 0; + ret = nouveau_gpuobj_new(dev, chan, nouveau_gpuobj_class_instmem_size(dev, class), 16, -- cgit v1.2.3 From effd6e066f406277254ad7603cf2c7465c4f114b Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 24 Nov 2010 10:15:05 +1000 Subject: drm/nvc0: implement channel structure initialisation Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_object.c | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_object.c b/drivers/gpu/drm/nouveau/nouveau_object.c index c64fd971b867..d77b1fcd19d4 100644 --- a/drivers/gpu/drm/nouveau/nouveau_object.c +++ b/drivers/gpu/drm/nouveau/nouveau_object.c @@ -779,6 +779,25 @@ nouveau_gpuobj_channel_init(struct nouveau_channel *chan, NV_DEBUG(dev, "ch%d vram=0x%08x tt=0x%08x\n", chan->id, vram_h, tt_h); + if (dev_priv->card_type == NV_C0) { + struct nouveau_vm *vm = dev_priv->chan_vm; + struct nouveau_vm_pgd *vpgd; + + ret = nouveau_gpuobj_new(dev, NULL, 4096, 0x1000, 0, + &chan->ramin); + if (ret) + return ret; + + nouveau_vm_ref(vm, &chan->vm, NULL); + + vpgd = list_first_entry(&vm->pgd_list, struct nouveau_vm_pgd, head); + nv_wo32(chan->ramin, 0x0200, lower_32_bits(vpgd->obj->vinst)); + nv_wo32(chan->ramin, 0x0204, upper_32_bits(vpgd->obj->vinst)); + nv_wo32(chan->ramin, 0x0208, 0xffffffff); + nv_wo32(chan->ramin, 0x020c, 0x000000ff); + return 0; + } + /* Allocate a chunk of memory for per-channel object storage */ ret = nouveau_gpuobj_channel_init_pramin(chan); if (ret) { @@ -786,7 +805,7 @@ nouveau_gpuobj_channel_init(struct nouveau_channel *chan, return ret; } - /* NV50/NVC0 VM + /* NV50 VM * - Allocate per-channel page-directory * - Link with shared channel VM */ @@ -884,9 +903,6 @@ nouveau_gpuobj_channel_takedown(struct nouveau_channel *chan) NV_DEBUG(dev, "ch%d\n", chan->id); - if (!chan->ramht) - return; - nouveau_ramht_ref(NULL, &chan->ramht, chan); nouveau_vm_ref(NULL, &chan->vm, chan->vm_pd); -- cgit v1.2.3 From 5216782bf8c195de3befe0742a877c987dd3c4fd Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 24 Nov 2010 10:18:28 +1000 Subject: drm/nvc0: skip dma object creation for drm channel Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_state.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c index 813790f4c7c7..d5b17b6ccd3a 100644 --- a/drivers/gpu/drm/nouveau/nouveau_state.c +++ b/drivers/gpu/drm/nouveau/nouveau_state.c @@ -552,6 +552,10 @@ nouveau_card_init_channel(struct drm_device *dev) if (ret) return ret; + /* no dma objects on fermi... */ + if (dev_priv->card_type >= NV_C0) + goto out_done; + ret = nouveau_gpuobj_dma_new(dev_priv->channel, NV_CLASS_DMA_IN_MEMORY, 0, dev_priv->vram_size, NV_MEM_ACCESS_RW, NV_MEM_TARGET_VRAM, @@ -576,6 +580,7 @@ nouveau_card_init_channel(struct drm_device *dev) if (ret) goto out_err; +out_done: mutex_unlock(&dev_priv->channel->mutex); return 0; -- cgit v1.2.3 From 96545299d7405d4c0f44b727718e263653fc11aa Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 24 Nov 2010 10:26:24 +1000 Subject: drm/nvc0: fix channel dma init paths Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_channel.c | 20 ++++++++++++++++---- drivers/gpu/drm/nouveau/nouveau_dma.c | 22 ++++++++++++++++------ drivers/gpu/drm/nouveau/nouveau_dma.h | 6 ++++++ 3 files changed, 38 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_channel.c b/drivers/gpu/drm/nouveau/nouveau_channel.c index 6f37995aee2d..e37977d02463 100644 --- a/drivers/gpu/drm/nouveau/nouveau_channel.c +++ b/drivers/gpu/drm/nouveau/nouveau_channel.c @@ -38,9 +38,14 @@ nouveau_channel_pushbuf_ctxdma_init(struct nouveau_channel *chan) int ret; if (dev_priv->card_type >= NV_50) { - ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY, 0, - (1ULL << 40), NV_MEM_ACCESS_RO, - NV_MEM_TARGET_VM, &pushbuf); + if (dev_priv->card_type < NV_C0) { + ret = nouveau_gpuobj_dma_new(chan, + NV_CLASS_DMA_IN_MEMORY, 0, + (1ULL << 40), + NV_MEM_ACCESS_RO, + NV_MEM_TARGET_VM, + &pushbuf); + } chan->pushbuf_base = pb->bo.offset; } else if (pb->bo.mem.mem_type == TTM_PL_TT) { @@ -71,7 +76,7 @@ nouveau_channel_pushbuf_ctxdma_init(struct nouveau_channel *chan) nouveau_gpuobj_ref(pushbuf, &chan->pushbuf); nouveau_gpuobj_ref(NULL, &pushbuf); - return 0; + return ret; } static struct nouveau_bo * @@ -99,6 +104,13 @@ nouveau_channel_user_pushbuf_alloc(struct drm_device *dev) return NULL; } + ret = nouveau_bo_map(pushbuf); + if (ret) { + nouveau_bo_unpin(pushbuf); + nouveau_bo_ref(NULL, &pushbuf); + return NULL; + } + return pushbuf; } diff --git a/drivers/gpu/drm/nouveau/nouveau_dma.c b/drivers/gpu/drm/nouveau/nouveau_dma.c index 6ff77cedc008..65699bfaaaea 100644 --- a/drivers/gpu/drm/nouveau/nouveau_dma.c +++ b/drivers/gpu/drm/nouveau/nouveau_dma.c @@ -36,7 +36,7 @@ nouveau_dma_pre_init(struct nouveau_channel *chan) struct drm_nouveau_private *dev_priv = chan->dev->dev_private; struct nouveau_bo *pushbuf = chan->pushbuf_bo; - if (dev_priv->card_type == NV_50) { + if (dev_priv->card_type >= NV_50) { const int ib_size = pushbuf->bo.mem.size / 2; chan->dma.ib_base = (pushbuf->bo.mem.size - ib_size) >> 2; @@ -61,6 +61,21 @@ nouveau_dma_init(struct nouveau_channel *chan) struct drm_nouveau_private *dev_priv = dev->dev_private; int ret, i; + if (dev_priv->card_type >= NV_C0) { + ret = nouveau_gpuobj_gr_new(chan, 0x9039, 0x9039); + if (ret) + return ret; + + ret = RING_SPACE(chan, 2); + if (ret) + return ret; + + BEGIN_NVC0(chan, 2, NvSubM2MF, 0x0000, 1); + OUT_RING (chan, 0x00009039); + FIRE_RING (chan); + return 0; + } + /* Create NV_MEMORY_TO_MEMORY_FORMAT for buffer moves */ ret = nouveau_gpuobj_gr_new(chan, NvM2MF, dev_priv->card_type < NV_50 ? 0x0039 : 0x5039); @@ -72,11 +87,6 @@ nouveau_dma_init(struct nouveau_channel *chan) if (ret) return ret; - /* Map push buffer */ - ret = nouveau_bo_map(chan->pushbuf_bo); - if (ret) - return ret; - /* Insert NOPS for NOUVEAU_DMA_SKIPS */ ret = RING_SPACE(chan, NOUVEAU_DMA_SKIPS); if (ret) diff --git a/drivers/gpu/drm/nouveau/nouveau_dma.h b/drivers/gpu/drm/nouveau/nouveau_dma.h index d578c21d3c8d..c118a331b5bc 100644 --- a/drivers/gpu/drm/nouveau/nouveau_dma.h +++ b/drivers/gpu/drm/nouveau/nouveau_dma.h @@ -124,6 +124,12 @@ OUT_RING(struct nouveau_channel *chan, int data) extern void OUT_RINGp(struct nouveau_channel *chan, const void *data, unsigned nr_dwords); +static inline void +BEGIN_NVC0(struct nouveau_channel *chan, int op, int subc, int mthd, int size) +{ + OUT_RING(chan, (op << 28) | (size << 16) | (subc << 13) | (mthd >> 2)); +} + static inline void BEGIN_RING(struct nouveau_channel *chan, int subc, int mthd, int size) { -- cgit v1.2.3 From 529c4959129c7c425aaf3d5b6acc63edf76827ad Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 24 Nov 2010 10:30:22 +1000 Subject: drm/nvc0: implement fencing Just simple REF_CNT fencing for the moment. Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_fence.c | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_fence.c b/drivers/gpu/drm/nouveau/nouveau_fence.c index 374a9793b85f..88b2f29ca3e4 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fence.c +++ b/drivers/gpu/drm/nouveau/nouveau_fence.c @@ -32,7 +32,8 @@ #include "nouveau_dma.h" #define USE_REFCNT(dev) (nouveau_private(dev)->chipset >= 0x10) -#define USE_SEMA(dev) (nouveau_private(dev)->chipset >= 0x17) +#define USE_SEMA(dev) (nouveau_private(dev)->chipset >= 0x17 && \ + nouveau_private(dev)->card_type < NV_C0) struct nouveau_fence { struct nouveau_channel *channel; @@ -139,6 +140,7 @@ nouveau_fence_emit(struct nouveau_fence *fence) { struct nouveau_channel *chan = fence->channel; struct drm_device *dev = chan->dev; + struct drm_nouveau_private *dev_priv = dev->dev_private; int ret; ret = RING_SPACE(chan, 2); @@ -159,8 +161,15 @@ nouveau_fence_emit(struct nouveau_fence *fence) list_add_tail(&fence->entry, &chan->fence.pending); spin_unlock(&chan->fence.lock); - BEGIN_RING(chan, NvSubSw, USE_REFCNT(dev) ? 0x0050 : 0x0150, 1); - OUT_RING(chan, fence->sequence); + if (USE_REFCNT(dev)) { + if (dev_priv->card_type < NV_C0) + BEGIN_RING(chan, NvSubSw, 0x0050, 1); + else + BEGIN_NVC0(chan, 2, NvSubSw, 0x0050, 1); + } else { + BEGIN_RING(chan, NvSubSw, 0x0150, 1); + } + OUT_RING (chan, fence->sequence); FIRE_RING(chan); return 0; @@ -445,11 +454,14 @@ nouveau_fence_channel_init(struct nouveau_channel *chan) if (ret) return ret; - ret = RING_SPACE(chan, 2); - if (ret) - return ret; - BEGIN_RING(chan, NvSubSw, 0, 1); - OUT_RING(chan, NvSw); + /* we leave subchannel empty for nvc0 */ + if (dev_priv->card_type < NV_C0) { + ret = RING_SPACE(chan, 2); + if (ret) + return ret; + BEGIN_RING(chan, NvSubSw, 0, 1); + OUT_RING(chan, NvSw); + } /* Create a DMA object for the shared cross-channel sync area. */ if (USE_SEMA(dev)) { -- cgit v1.2.3 From b2b099388fa76f0be25431794d369d251a4002dd Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 24 Nov 2010 10:47:15 +1000 Subject: drm/nvc0: implement pfifo engine hooks Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_drv.h | 2 + drivers/gpu/drm/nouveau/nvc0_fifo.c | 359 ++++++++++++++++++++++++++++++++++ 2 files changed, 361 insertions(+) diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index c1e85c4c7ac2..6a2b3359f368 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -240,6 +240,7 @@ struct nouveau_channel { /* PFIFO context */ struct nouveau_gpuobj *ramfc; struct nouveau_gpuobj *cache; + void *fifo_priv; /* PGRAPH context */ /* XXX may be merge 2 pointers as private data ??? */ @@ -337,6 +338,7 @@ struct nouveau_fb_engine { }; struct nouveau_fifo_engine { + void *priv; int channels; struct nouveau_gpuobj *playlist[2]; diff --git a/drivers/gpu/drm/nouveau/nvc0_fifo.c b/drivers/gpu/drm/nouveau/nvc0_fifo.c index 890c2b95fbc1..82a4ded5dae8 100644 --- a/drivers/gpu/drm/nouveau/nvc0_fifo.c +++ b/drivers/gpu/drm/nouveau/nvc0_fifo.c @@ -25,6 +25,48 @@ #include "drmP.h" #include "nouveau_drv.h" +#include "nouveau_mm.h" + +static void nvc0_fifo_isr(struct drm_device *); + +struct nvc0_fifo_priv { + struct nouveau_gpuobj *playlist[2]; + int cur_playlist; + struct nouveau_vma user_vma; +}; + +struct nvc0_fifo_chan { + struct nouveau_bo *user; + struct nouveau_gpuobj *ramfc; +}; + +static void +nvc0_fifo_playlist_update(struct drm_device *dev) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_instmem_engine *pinstmem = &dev_priv->engine.instmem; + struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo; + struct nvc0_fifo_priv *priv = pfifo->priv; + struct nouveau_gpuobj *cur; + int i, p; + + cur = priv->playlist[priv->cur_playlist]; + priv->cur_playlist = !priv->cur_playlist; + + for (i = 0, p = 0; i < 128; i++) { + if (!(nv_rd32(dev, 0x3004 + (i * 8)) & 1)) + continue; + nv_wo32(cur, p + 0, i); + nv_wo32(cur, p + 4, 0x00000004); + p += 8; + } + pinstmem->flush(dev); + + nv_wr32(dev, 0x002270, cur->vinst >> 12); + nv_wr32(dev, 0x002274, 0x01f00000 | (p >> 3)); + if (!nv_wait(dev, 0x00227c, 0x00100000, 0x00000000)) + NV_ERROR(dev, "PFIFO - playlist update failed\n"); +} void nvc0_fifo_disable(struct drm_device *dev) @@ -57,12 +99,135 @@ nvc0_fifo_channel_id(struct drm_device *dev) int nvc0_fifo_create_context(struct nouveau_channel *chan) { + struct drm_device *dev = chan->dev; + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_instmem_engine *pinstmem = &dev_priv->engine.instmem; + struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo; + struct nvc0_fifo_priv *priv = pfifo->priv; + struct nvc0_fifo_chan *fifoch; + u64 ib_virt, user_vinst; + int ret; + + chan->fifo_priv = kzalloc(sizeof(*fifoch), GFP_KERNEL); + if (!chan->fifo_priv) + return -ENOMEM; + fifoch = chan->fifo_priv; + + /* allocate vram for control regs, map into polling area */ + ret = nouveau_bo_new(dev, NULL, 0x1000, 0, TTM_PL_FLAG_VRAM, + 0, 0, true, true, &fifoch->user); + if (ret) + goto error; + + ret = nouveau_bo_pin(fifoch->user, TTM_PL_FLAG_VRAM); + if (ret) { + nouveau_bo_ref(NULL, &fifoch->user); + goto error; + } + + user_vinst = fifoch->user->bo.mem.start << PAGE_SHIFT; + + ret = nouveau_bo_map(fifoch->user); + if (ret) { + nouveau_bo_unpin(fifoch->user); + nouveau_bo_ref(NULL, &fifoch->user); + goto error; + } + + nouveau_vm_map_at(&priv->user_vma, chan->id * 0x1000, + fifoch->user->bo.mem.mm_node); + + chan->user = ioremap_wc(pci_resource_start(dev->pdev, 1) + + priv->user_vma.offset + (chan->id * 0x1000), + PAGE_SIZE); + if (!chan->user) { + ret = -ENOMEM; + goto error; + } + + ib_virt = chan->pushbuf_base + chan->dma.ib_base * 4; + + /* zero channel regs */ + nouveau_bo_wr32(fifoch->user, 0x0040/4, 0); + nouveau_bo_wr32(fifoch->user, 0x0044/4, 0); + nouveau_bo_wr32(fifoch->user, 0x0048/4, 0); + nouveau_bo_wr32(fifoch->user, 0x004c/4, 0); + nouveau_bo_wr32(fifoch->user, 0x0050/4, 0); + nouveau_bo_wr32(fifoch->user, 0x0058/4, 0); + nouveau_bo_wr32(fifoch->user, 0x005c/4, 0); + nouveau_bo_wr32(fifoch->user, 0x0060/4, 0); + nouveau_bo_wr32(fifoch->user, 0x0088/4, 0); + nouveau_bo_wr32(fifoch->user, 0x008c/4, 0); + + /* ramfc */ + ret = nouveau_gpuobj_new_fake(dev, chan->ramin->pinst, + chan->ramin->vinst, 0x100, + NVOBJ_FLAG_ZERO_ALLOC, &fifoch->ramfc); + if (ret) + goto error; + + nv_wo32(fifoch->ramfc, 0x08, lower_32_bits(user_vinst)); + nv_wo32(fifoch->ramfc, 0x0c, upper_32_bits(user_vinst)); + nv_wo32(fifoch->ramfc, 0x10, 0x0000face); + nv_wo32(fifoch->ramfc, 0x30, 0xfffff902); + nv_wo32(fifoch->ramfc, 0x48, lower_32_bits(ib_virt)); + nv_wo32(fifoch->ramfc, 0x4c, drm_order(chan->dma.ib_max + 1) << 16 | + upper_32_bits(ib_virt)); + nv_wo32(fifoch->ramfc, 0x54, 0x00000002); + nv_wo32(fifoch->ramfc, 0x84, 0x20400000); + nv_wo32(fifoch->ramfc, 0x94, 0x30000001); + nv_wo32(fifoch->ramfc, 0x9c, 0x00000100); + nv_wo32(fifoch->ramfc, 0xa4, 0x1f1f1f1f); + nv_wo32(fifoch->ramfc, 0xa8, 0x1f1f1f1f); + nv_wo32(fifoch->ramfc, 0xac, 0x0000001f); + nv_wo32(fifoch->ramfc, 0xb8, 0xf8000000); + nv_wo32(fifoch->ramfc, 0xf8, 0x10003080); /* 0x002310 */ + nv_wo32(fifoch->ramfc, 0xfc, 0x10000010); /* 0x002350 */ + pinstmem->flush(dev); + + nv_wr32(dev, 0x003000 + (chan->id * 8), 0xc0000000 | + (chan->ramin->vinst >> 12)); + nv_wr32(dev, 0x003004 + (chan->id * 8), 0x001f0001); + nvc0_fifo_playlist_update(dev); return 0; + +error: + pfifo->destroy_context(chan); + return ret; } void nvc0_fifo_destroy_context(struct nouveau_channel *chan) { + struct drm_device *dev = chan->dev; + struct nvc0_fifo_chan *fifoch; + + nv_mask(dev, 0x003004 + (chan->id * 8), 0x00000001, 0x00000000); + nv_wr32(dev, 0x002634, chan->id); + if (!nv_wait(dev, 0x0002634, 0xffffffff, chan->id)) + NV_WARN(dev, "0x2634 != chid: 0x%08x\n", nv_rd32(dev, 0x2634)); + + nvc0_fifo_playlist_update(dev); + + nv_wr32(dev, 0x003000 + (chan->id * 8), 0x00000000); + + if (chan->user) { + iounmap(chan->user); + chan->user = NULL; + } + + fifoch = chan->fifo_priv; + chan->fifo_priv = NULL; + if (!fifoch) + return; + + nouveau_gpuobj_ref(NULL, &fifoch->ramfc); + if (fifoch->user) { + nouveau_bo_unmap(fifoch->user); + nouveau_bo_unpin(fifoch->user); + nouveau_bo_ref(NULL, &fifoch->user); + } + kfree(fifoch); } int @@ -77,14 +242,208 @@ nvc0_fifo_unload_context(struct drm_device *dev) return 0; } +static void +nvc0_fifo_destroy(struct drm_device *dev) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo; + struct nvc0_fifo_priv *priv; + + priv = pfifo->priv; + if (!priv) + return; + + nouveau_vm_put(&priv->user_vma); + nouveau_gpuobj_ref(NULL, &priv->playlist[1]); + nouveau_gpuobj_ref(NULL, &priv->playlist[0]); + kfree(priv); +} + void nvc0_fifo_takedown(struct drm_device *dev) { + nv_wr32(dev, 0x002140, 0x00000000); + nvc0_fifo_destroy(dev); +} + +static int +nvc0_fifo_create(struct drm_device *dev) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo; + struct nvc0_fifo_priv *priv; + int ret; + + priv = kzalloc(sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + pfifo->priv = priv; + + ret = nouveau_gpuobj_new(dev, NULL, 0x1000, 0x1000, 0, + &priv->playlist[0]); + if (ret) + goto error; + + ret = nouveau_gpuobj_new(dev, NULL, 0x1000, 0x1000, 0, + &priv->playlist[1]); + if (ret) + goto error; + + ret = nouveau_vm_get(dev_priv->bar1_vm, pfifo->channels * 0x1000, + 12, NV_MEM_ACCESS_RW, &priv->user_vma); + if (ret) + goto error; + + nouveau_irq_register(dev, 8, nvc0_fifo_isr); + NVOBJ_CLASS(dev, 0x506e, SW); /* nvsw */ + return 0; + +error: + nvc0_fifo_destroy(dev); + return ret; } int nvc0_fifo_init(struct drm_device *dev) { + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_fifo_engine *pfifo = &dev_priv->engine.fifo; + struct nvc0_fifo_priv *priv; + int ret, i; + + if (!pfifo->priv) { + ret = nvc0_fifo_create(dev); + if (ret) + return ret; + } + priv = pfifo->priv; + + /* reset PFIFO, enable all available PSUBFIFO areas */ + nv_mask(dev, 0x000200, 0x00000100, 0x00000000); + nv_mask(dev, 0x000200, 0x00000100, 0x00000100); + nv_wr32(dev, 0x000204, 0xffffffff); + nv_wr32(dev, 0x002204, 0xffffffff); + + /* assign engines to subfifos */ + nv_wr32(dev, 0x002208, ~(1 << 0)); /* PGRAPH */ + nv_wr32(dev, 0x00220c, ~(1 << 1)); /* PVP */ + nv_wr32(dev, 0x002210, ~(1 << 1)); /* PPP */ + nv_wr32(dev, 0x002214, ~(1 << 1)); /* PBSP */ + nv_wr32(dev, 0x002218, ~(1 << 2)); /* PCE0 */ + nv_wr32(dev, 0x00221c, ~(1 << 1)); /* PCE1 */ + + /* PSUBFIFO[n] */ + for (i = 0; i < 3; i++) { + nv_mask(dev, 0x04013c + (i * 0x2000), 0x10000100, 0x00000000); + nv_wr32(dev, 0x040108 + (i * 0x2000), 0xffffffff); /* INTR */ + nv_wr32(dev, 0x04010c + (i * 0x2000), 0xfffffeff); /* INTR_EN */ + } + + nv_mask(dev, 0x002200, 0x00000001, 0x00000001); + nv_wr32(dev, 0x002254, 0x10000000 | priv->user_vma.offset >> 12); + + nv_wr32(dev, 0x002a00, 0xffffffff); /* clears PFIFO.INTR bit 30 */ + nv_wr32(dev, 0x002100, 0xffffffff); + nv_wr32(dev, 0x002140, 0xbfffffff); return 0; } +struct nouveau_enum nvc0_fifo_fault_unit[] = { + { 0, "PGRAPH" }, + { 3, "PEEPHOLE" }, + { 4, "BAR1" }, + { 5, "BAR3" }, + { 7, "PFIFO" }, + {} +}; + +struct nouveau_enum nvc0_fifo_fault_reason[] = { + { 0, "PT_NOT_PRESENT" }, + { 1, "PT_TOO_SHORT" }, + { 2, "PAGE_NOT_PRESENT" }, + { 3, "VM_LIMIT_EXCEEDED" }, + {} +}; + +struct nouveau_bitfield nvc0_fifo_subfifo_intr[] = { +/* { 0x00008000, "" } seen with null ib push */ + { 0x00200000, "ILLEGAL_MTHD" }, + { 0x00800000, "EMPTY_SUBC" }, + {} +}; + +static void +nvc0_fifo_isr_vm_fault(struct drm_device *dev, int unit) +{ + u32 inst = nv_rd32(dev, 0x2800 + (unit * 0x10)); + u32 valo = nv_rd32(dev, 0x2804 + (unit * 0x10)); + u32 vahi = nv_rd32(dev, 0x2808 + (unit * 0x10)); + u32 stat = nv_rd32(dev, 0x280c + (unit * 0x10)); + + NV_INFO(dev, "PFIFO: %s fault at 0x%010llx [", + (stat & 0x00000080) ? "write" : "read", (u64)vahi << 32 | valo); + nouveau_enum_print(nvc0_fifo_fault_reason, stat & 0x0000000f); + printk("] from "); + nouveau_enum_print(nvc0_fifo_fault_unit, unit); + printk(" on channel 0x%010llx\n", (u64)inst << 12); +} + +static void +nvc0_fifo_isr_subfifo_intr(struct drm_device *dev, int unit) +{ + u32 stat = nv_rd32(dev, 0x040108 + (unit * 0x2000)); + u32 addr = nv_rd32(dev, 0x0400c0 + (unit * 0x2000)); + u32 data = nv_rd32(dev, 0x0400c4 + (unit * 0x2000)); + u32 chid = nv_rd32(dev, 0x040120 + (unit * 0x2000)) & 0x7f; + u32 subc = (addr & 0x00070000); + u32 mthd = (addr & 0x00003ffc); + + NV_INFO(dev, "PSUBFIFO %d:", unit); + nouveau_bitfield_print(nvc0_fifo_subfifo_intr, stat); + NV_INFO(dev, "PSUBFIFO %d: ch %d subc %d mthd 0x%04x data 0x%08x\n", + unit, chid, subc, mthd, data); + + nv_wr32(dev, 0x0400c0 + (unit * 0x2000), 0x80600008); + nv_wr32(dev, 0x040108 + (unit * 0x2000), stat); +} + +static void +nvc0_fifo_isr(struct drm_device *dev) +{ + u32 stat = nv_rd32(dev, 0x002100); + + if (stat & 0x10000000) { + u32 units = nv_rd32(dev, 0x00259c); + u32 u = units; + + while (u) { + int i = ffs(u) - 1; + nvc0_fifo_isr_vm_fault(dev, i); + u &= ~(1 << i); + } + + nv_wr32(dev, 0x00259c, units); + stat &= ~0x10000000; + } + + if (stat & 0x20000000) { + u32 units = nv_rd32(dev, 0x0025a0); + u32 u = units; + + while (u) { + int i = ffs(u) - 1; + nvc0_fifo_isr_subfifo_intr(dev, i); + u &= ~(1 << i); + } + + nv_wr32(dev, 0x0025a0, units); + stat &= ~0x20000000; + } + + if (stat) { + NV_INFO(dev, "PFIFO: unhandled status 0x%08x\n", stat); + nv_wr32(dev, 0x002100, stat); + } + + nv_wr32(dev, 0x2140, 0); +} -- cgit v1.2.3 From 966a5b7daa15e152bc2e1f0407939cc721fb5995 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 24 Nov 2010 10:49:02 +1000 Subject: drm/nvc0: implement pgraph engine hooks Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/Makefile | 2 +- drivers/gpu/drm/nouveau/nouveau_bo.c | 2 +- drivers/gpu/drm/nouveau/nouveau_drv.h | 1 + drivers/gpu/drm/nouveau/nvc0_graph.c | 709 +++++++- drivers/gpu/drm/nouveau/nvc0_graph.h | 66 + drivers/gpu/drm/nouveau/nvc0_grctx.c | 2854 +++++++++++++++++++++++++++++++++ 6 files changed, 3631 insertions(+), 3 deletions(-) create mode 100644 drivers/gpu/drm/nouveau/nvc0_graph.h create mode 100644 drivers/gpu/drm/nouveau/nvc0_grctx.c diff --git a/drivers/gpu/drm/nouveau/Makefile b/drivers/gpu/drm/nouveau/Makefile index d9d22ffff81e..141771beb8e6 100644 --- a/drivers/gpu/drm/nouveau/Makefile +++ b/drivers/gpu/drm/nouveau/Makefile @@ -18,7 +18,7 @@ nouveau-y := nouveau_drv.o nouveau_state.o nouveau_channel.o nouveau_mem.o \ nv04_fifo.o nv10_fifo.o nv40_fifo.o nv50_fifo.o nvc0_fifo.o \ nv04_graph.o nv10_graph.o nv20_graph.o \ nv40_graph.o nv50_graph.o nvc0_graph.o \ - nv40_grctx.o nv50_grctx.o \ + nv40_grctx.o nv50_grctx.o nvc0_grctx.o \ nv84_crypt.o \ nv04_instmem.o nv50_instmem.o nvc0_instmem.o \ nv50_evo.o nv50_crtc.o nv50_dac.o nv50_sor.o \ diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index 6f3096a50297..5dc639e0c969 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c @@ -839,7 +839,7 @@ nouveau_bo_move(struct ttm_buffer_object *bo, bool evict, bool intr, } /* Software copy if the card isn't up and running yet. */ - if (!dev_priv->channel) { + if (!dev_priv->channel || dev_priv->card_type == NV_C0) { ret = ttm_bo_move_memcpy(bo, evict, no_wait_reserve, no_wait_gpu, new_mem); goto out; } diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index 6a2b3359f368..e81575687354 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h @@ -365,6 +365,7 @@ struct nouveau_pgraph_engine { bool accel_blocked; bool registered; int grctx_size; + void *priv; /* NV2x/NV3x context table (0x400780) */ struct nouveau_gpuobj *ctx_table; diff --git a/drivers/gpu/drm/nouveau/nvc0_graph.c b/drivers/gpu/drm/nouveau/nvc0_graph.c index 717a5177a8d8..cf2f6aa920b4 100644 --- a/drivers/gpu/drm/nouveau/nvc0_graph.c +++ b/drivers/gpu/drm/nouveau/nvc0_graph.c @@ -22,9 +22,16 @@ * Authors: Ben Skeggs */ +#include + #include "drmP.h" #include "nouveau_drv.h" +#include "nouveau_mm.h" +#include "nvc0_graph.h" + +static void nvc0_graph_isr(struct drm_device *); +static int nvc0_graph_unload_context_to(struct drm_device *dev, u64 chan); void nvc0_graph_fifo_access(struct drm_device *dev, bool enabled) @@ -37,39 +44,739 @@ nvc0_graph_channel(struct drm_device *dev) return NULL; } +static int +nvc0_graph_construct_context(struct nouveau_channel *chan) +{ + struct drm_nouveau_private *dev_priv = chan->dev->dev_private; + struct nvc0_graph_priv *priv = dev_priv->engine.graph.priv; + struct nvc0_graph_chan *grch = chan->pgraph_ctx; + struct drm_device *dev = chan->dev; + int ret, i; + u32 *ctx; + + ctx = kmalloc(priv->grctx_size, GFP_KERNEL); + if (!ctx) + return -ENOMEM; + + nvc0_graph_load_context(chan); + + nv_wo32(grch->grctx, 0x1c, 1); + nv_wo32(grch->grctx, 0x20, 0); + nv_wo32(grch->grctx, 0x28, 0); + nv_wo32(grch->grctx, 0x2c, 0); + dev_priv->engine.instmem.flush(dev); + + ret = nvc0_grctx_generate(chan); + if (ret) { + kfree(ctx); + return ret; + } + + ret = nvc0_graph_unload_context_to(dev, chan->ramin->vinst); + if (ret) { + kfree(ctx); + return ret; + } + + for (i = 0; i < priv->grctx_size; i += 4) + ctx[i / 4] = nv_ro32(grch->grctx, i); + + priv->grctx_vals = ctx; + return 0; +} + +static int +nvc0_graph_create_context_mmio_list(struct nouveau_channel *chan) +{ + struct drm_nouveau_private *dev_priv = chan->dev->dev_private; + struct nvc0_graph_priv *priv = dev_priv->engine.graph.priv; + struct nvc0_graph_chan *grch = chan->pgraph_ctx; + struct drm_device *dev = chan->dev; + int i = 0, gpc, tp, ret; + u32 magic; + + ret = nouveau_gpuobj_new(dev, NULL, 0x2000, 256, NVOBJ_FLAG_VM, + &grch->unk408004); + if (ret) + return ret; + + ret = nouveau_gpuobj_new(dev, NULL, 0x8000, 256, NVOBJ_FLAG_VM, + &grch->unk40800c); + if (ret) + return ret; + + ret = nouveau_gpuobj_new(dev, NULL, 384 * 1024, 4096, NVOBJ_FLAG_VM, + &grch->unk418810); + if (ret) + return ret; + + ret = nouveau_gpuobj_new(dev, NULL, 0x1000, 0, NVOBJ_FLAG_VM, + &grch->mmio); + if (ret) + return ret; + + + nv_wo32(grch->mmio, i++ * 4, 0x00408004); + nv_wo32(grch->mmio, i++ * 4, grch->unk408004->vinst >> 8); + nv_wo32(grch->mmio, i++ * 4, 0x00408008); + nv_wo32(grch->mmio, i++ * 4, 0x80000018); + + nv_wo32(grch->mmio, i++ * 4, 0x0040800c); + nv_wo32(grch->mmio, i++ * 4, grch->unk40800c->vinst >> 8); + nv_wo32(grch->mmio, i++ * 4, 0x00408010); + nv_wo32(grch->mmio, i++ * 4, 0x80000000); + + nv_wo32(grch->mmio, i++ * 4, 0x00418810); + nv_wo32(grch->mmio, i++ * 4, 0x80000000 | grch->unk418810->vinst >> 12); + nv_wo32(grch->mmio, i++ * 4, 0x00419848); + nv_wo32(grch->mmio, i++ * 4, 0x10000000 | grch->unk418810->vinst >> 12); + + nv_wo32(grch->mmio, i++ * 4, 0x00419004); + nv_wo32(grch->mmio, i++ * 4, grch->unk40800c->vinst >> 8); + nv_wo32(grch->mmio, i++ * 4, 0x00419008); + nv_wo32(grch->mmio, i++ * 4, 0x00000000); + + nv_wo32(grch->mmio, i++ * 4, 0x00418808); + nv_wo32(grch->mmio, i++ * 4, grch->unk408004->vinst >> 8); + nv_wo32(grch->mmio, i++ * 4, 0x0041880c); + nv_wo32(grch->mmio, i++ * 4, 0x80000018); + + magic = 0x02180000; + nv_wo32(grch->mmio, i++ * 4, 0x00405830); + nv_wo32(grch->mmio, i++ * 4, magic); + for (gpc = 0; gpc < priv->gpc_nr; gpc++) { + for (tp = 0; tp < priv->tp_nr[gpc]; tp++, magic += 0x02fc) { + u32 reg = 0x504520 + (gpc * 0x8000) + (tp * 0x0800); + nv_wo32(grch->mmio, i++ * 4, reg); + nv_wo32(grch->mmio, i++ * 4, magic); + } + } + + grch->mmio_nr = i / 2; + return 0; +} + int nvc0_graph_create_context(struct nouveau_channel *chan) { + struct drm_nouveau_private *dev_priv = chan->dev->dev_private; + struct nouveau_instmem_engine *pinstmem = &dev_priv->engine.instmem; + struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; + struct nvc0_graph_priv *priv = pgraph->priv; + struct nvc0_graph_chan *grch; + struct drm_device *dev = chan->dev; + struct nouveau_gpuobj *grctx; + int ret, i; + + chan->pgraph_ctx = kzalloc(sizeof(*grch), GFP_KERNEL); + if (!chan->pgraph_ctx) + return -ENOMEM; + grch = chan->pgraph_ctx; + + ret = nouveau_gpuobj_new(dev, NULL, priv->grctx_size, 256, + NVOBJ_FLAG_VM | NVOBJ_FLAG_ZERO_ALLOC, + &grch->grctx); + if (ret) + goto error; + chan->ramin_grctx = grch->grctx; + grctx = grch->grctx; + + ret = nvc0_graph_create_context_mmio_list(chan); + if (ret) + goto error; + + nv_wo32(chan->ramin, 0x0210, lower_32_bits(grctx->vinst) | 4); + nv_wo32(chan->ramin, 0x0214, upper_32_bits(grctx->vinst)); + pinstmem->flush(dev); + + if (!priv->grctx_vals) { + ret = nvc0_graph_construct_context(chan); + if (ret) + goto error; + } + + for (i = 0; i < priv->grctx_size; i += 4) + nv_wo32(grctx, i, priv->grctx_vals[i / 4]); + + nv_wo32(grctx, 0xf4, 0); + nv_wo32(grctx, 0xf8, 0); + nv_wo32(grctx, 0x10, grch->mmio_nr); + nv_wo32(grctx, 0x14, lower_32_bits(grch->mmio->vinst)); + nv_wo32(grctx, 0x18, upper_32_bits(grch->mmio->vinst)); + nv_wo32(grctx, 0x1c, 1); + nv_wo32(grctx, 0x20, 0); + nv_wo32(grctx, 0x28, 0); + nv_wo32(grctx, 0x2c, 0); + pinstmem->flush(dev); return 0; + +error: + pgraph->destroy_context(chan); + return ret; } void nvc0_graph_destroy_context(struct nouveau_channel *chan) { + struct nvc0_graph_chan *grch; + + grch = chan->pgraph_ctx; + chan->pgraph_ctx = NULL; + if (!grch) + return; + + nouveau_gpuobj_ref(NULL, &grch->mmio); + nouveau_gpuobj_ref(NULL, &grch->unk418810); + nouveau_gpuobj_ref(NULL, &grch->unk40800c); + nouveau_gpuobj_ref(NULL, &grch->unk408004); + nouveau_gpuobj_ref(NULL, &grch->grctx); + chan->ramin_grctx = NULL; } int nvc0_graph_load_context(struct nouveau_channel *chan) { + struct drm_device *dev = chan->dev; + + nv_wr32(dev, 0x409840, 0x00000030); + nv_wr32(dev, 0x409500, 0x80000000 | chan->ramin->vinst >> 12); + nv_wr32(dev, 0x409504, 0x00000003); + if (!nv_wait(dev, 0x409800, 0x00000010, 0x00000010)) + NV_ERROR(dev, "PGRAPH: load_ctx timeout\n"); + + printk(KERN_ERR "load_ctx 0x%08x\n", nv_rd32(dev, 0x409b00)); + return 0; +} + +static int +nvc0_graph_unload_context_to(struct drm_device *dev, u64 chan) +{ + nv_wr32(dev, 0x409840, 0x00000003); + nv_wr32(dev, 0x409500, 0x80000000 | chan >> 12); + nv_wr32(dev, 0x409504, 0x00000009); + if (!nv_wait(dev, 0x409800, 0x00000001, 0x00000000)) { + NV_ERROR(dev, "PGRAPH: unload_ctx timeout\n"); + return -EBUSY; + } + return 0; } int nvc0_graph_unload_context(struct drm_device *dev) { - return 0; + u64 inst = (u64)(nv_rd32(dev, 0x409b00) & 0x0fffffff) << 12; + return nvc0_graph_unload_context_to(dev, inst); +} + +static void +nvc0_graph_destroy(struct drm_device *dev) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; + struct nvc0_graph_priv *priv; + + priv = pgraph->priv; + if (!priv) + return; + + nouveau_irq_unregister(dev, 12); + + nouveau_gpuobj_ref(NULL, &priv->unk4188b8); + nouveau_gpuobj_ref(NULL, &priv->unk4188b4); + + if (priv->grctx_vals) + kfree(priv->grctx_vals); + kfree(priv); } void nvc0_graph_takedown(struct drm_device *dev) { + nvc0_graph_destroy(dev); +} + +static int +nvc0_graph_create(struct drm_device *dev) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; + struct nvc0_graph_priv *priv; + int ret, gpc, i; + + priv = kzalloc(sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + pgraph->priv = priv; + + ret = nouveau_gpuobj_new(dev, NULL, 0x1000, 256, 0, &priv->unk4188b4); + if (ret) + goto error; + + ret = nouveau_gpuobj_new(dev, NULL, 0x1000, 256, 0, &priv->unk4188b8); + if (ret) + goto error; + + for (i = 0; i < 0x1000; i += 4) { + nv_wo32(priv->unk4188b4, i, 0x00000010); + nv_wo32(priv->unk4188b8, i, 0x00000010); + } + + priv->gpc_nr = nv_rd32(dev, 0x409604) & 0x0000001f; + priv->rop_nr = (nv_rd32(dev, 0x409604) & 0x001f0000) >> 16; + for (gpc = 0; gpc < priv->gpc_nr; gpc++) { + priv->tp_nr[gpc] = nv_rd32(dev, GPC_UNIT(gpc, 0x2608)); + priv->tp_total += priv->tp_nr[gpc]; + } + + /*XXX: these need figuring out... */ + switch (dev_priv->chipset) { + case 0xc0: + if (priv->tp_total == 11) { /* 465, 3/4/4/0, 4 */ + priv->magic_not_rop_nr = 0x07; + priv->magic419bd0 = 0x0a360000; + priv->magic419be4 = 0x04c33a54; + /* filled values up to tp_total, the rest 0 */ + priv->magicgpc980[0] = 0x22111000; + priv->magicgpc980[1] = 0x00000233; + priv->magicgpc980[2] = 0x00000000; + priv->magicgpc980[3] = 0x00000000; + priv->magicgpc918 = 0x000ba2e9; + } else + if (priv->tp_total == 14) { /* 470, 3/3/4/4, 5 */ + priv->magic_not_rop_nr = 0x05; + priv->magic419bd0 = 0x043c0000; + priv->magic419be4 = 0x09041208; + priv->magicgpc980[0] = 0x11110000; + priv->magicgpc980[1] = 0x00233222; + priv->magicgpc980[2] = 0x00000000; + priv->magicgpc980[3] = 0x00000000; + priv->magicgpc918 = 0x00092493; + } else + if (priv->tp_total == 15) { /* 480, 3/4/4/4, 6 */ + priv->magic_not_rop_nr = 0x06; + priv->magic419bd0 = 0x023e0000; + priv->magic419be4 = 0x10414104; + priv->magicgpc980[0] = 0x11110000; + priv->magicgpc980[1] = 0x03332222; + priv->magicgpc980[2] = 0x00000000; + priv->magicgpc980[3] = 0x00000000; + priv->magicgpc918 = 0x00088889; + } + break; + case 0xc3: /* 450, 4/0/0/0, 2 */ + priv->magic_not_rop_nr = 0x03; + priv->magic419bd0 = 0x00500000; + priv->magic419be4 = 0x00000000; + priv->magicgpc980[0] = 0x00003210; + priv->magicgpc980[1] = 0x00000000; + priv->magicgpc980[2] = 0x00000000; + priv->magicgpc980[3] = 0x00000000; + priv->magicgpc918 = 0x00200000; + break; + case 0xc4: /* 460, 3/4/0/0, 4 */ + priv->magic_not_rop_nr = 0x01; + priv->magic419bd0 = 0x045c0000; + priv->magic419be4 = 0x09041208; + priv->magicgpc980[0] = 0x02321100; + priv->magicgpc980[1] = 0x00000000; + priv->magicgpc980[2] = 0x00000000; + priv->magicgpc980[3] = 0x00000000; + priv->magicgpc918 = 0x00124925; + break; + } + + if (!priv->magic419bd0) { + NV_ERROR(dev, "PGRAPH: unknown config: %d/%d/%d/%d, %d\n", + priv->tp_nr[0], priv->tp_nr[1], priv->tp_nr[2], + priv->tp_nr[3], priv->rop_nr); + /* use 0xc3's values... */ + priv->magic_not_rop_nr = 0x03; + priv->magic419bd0 = 0x00500000; + priv->magic419be4 = 0x00000000; + priv->magicgpc980[0] = 0x00003210; + priv->magicgpc980[1] = 0x00000000; + priv->magicgpc980[2] = 0x00000000; + priv->magicgpc980[3] = 0x00000000; + priv->magicgpc918 = 0x00200000; + } + + nouveau_irq_register(dev, 12, nvc0_graph_isr); + NVOBJ_CLASS(dev, 0x902d, GR); /* 2D */ + NVOBJ_CLASS(dev, 0x9039, GR); /* M2MF */ + NVOBJ_CLASS(dev, 0x9097, GR); /* 3D */ + NVOBJ_CLASS(dev, 0x90c0, GR); /* COMPUTE */ + return 0; + +error: + nvc0_graph_destroy(dev); + return ret; +} + +static void +nvc0_graph_init_obj418880(struct drm_device *dev) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; + struct nvc0_graph_priv *priv = pgraph->priv; + int i; + + nv_wr32(dev, GPC_BCAST(0x0880), 0x00000000); + nv_wr32(dev, GPC_BCAST(0x08a4), 0x00000000); + for (i = 0; i < 4; i++) + nv_wr32(dev, GPC_BCAST(0x0888) + (i * 4), 0x00000000); + nv_wr32(dev, GPC_BCAST(0x08b4), priv->unk4188b4->vinst >> 8); + nv_wr32(dev, GPC_BCAST(0x08b8), priv->unk4188b8->vinst >> 8); +} + +static void +nvc0_graph_init_regs(struct drm_device *dev) +{ + nv_wr32(dev, 0x400080, 0x003083c2); + nv_wr32(dev, 0x400088, 0x00006fe7); + nv_wr32(dev, 0x40008c, 0x00000000); + nv_wr32(dev, 0x400090, 0x00000030); + nv_wr32(dev, 0x40013c, 0x013901f7); + nv_wr32(dev, 0x400140, 0x00000100); + nv_wr32(dev, 0x400144, 0x00000000); + nv_wr32(dev, 0x400148, 0x00000110); + nv_wr32(dev, 0x400138, 0x00000000); + nv_wr32(dev, 0x400130, 0x00000000); + nv_wr32(dev, 0x400134, 0x00000000); + nv_wr32(dev, 0x400124, 0x00000002); +} + +static void +nvc0_graph_init_gpc_0(struct drm_device *dev) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nvc0_graph_priv *priv = dev_priv->engine.graph.priv; + int gpc; + + // TP ROP UNKVAL(magic_not_rop_nr) + // 450: 4/0/0/0 2 3 + // 460: 3/4/0/0 4 1 + // 465: 3/4/4/0 4 7 + // 470: 3/3/4/4 5 5 + // 480: 3/4/4/4 6 6 + + // magicgpc918 + // 450: 00200000 00000000001000000000000000000000 + // 460: 00124925 00000000000100100100100100100101 + // 465: 000ba2e9 00000000000010111010001011101001 + // 470: 00092493 00000000000010010010010010010011 + // 480: 00088889 00000000000010001000100010001001 + + /* filled values up to tp_total, remainder 0 */ + // 450: 00003210 00000000 00000000 00000000 + // 460: 02321100 00000000 00000000 00000000 + // 465: 22111000 00000233 00000000 00000000 + // 470: 11110000 00233222 00000000 00000000 + // 480: 11110000 03332222 00000000 00000000 + + nv_wr32(dev, GPC_BCAST(0x0980), priv->magicgpc980[0]); + nv_wr32(dev, GPC_BCAST(0x0984), priv->magicgpc980[1]); + nv_wr32(dev, GPC_BCAST(0x0988), priv->magicgpc980[2]); + nv_wr32(dev, GPC_BCAST(0x098c), priv->magicgpc980[3]); + + for (gpc = 0; gpc < priv->gpc_nr; gpc++) { + nv_wr32(dev, GPC_UNIT(gpc, 0x0914), priv->magic_not_rop_nr << 8 | + priv->tp_nr[gpc]); + nv_wr32(dev, GPC_UNIT(gpc, 0x0910), 0x00040000 | priv->tp_total); + nv_wr32(dev, GPC_UNIT(gpc, 0x0918), priv->magicgpc918); + } + + nv_wr32(dev, GPC_BCAST(0x1bd4), priv->magicgpc918); + nv_wr32(dev, GPC_BCAST(0x08ac), priv->rop_nr); +} + +static void +nvc0_graph_init_units(struct drm_device *dev) +{ + nv_wr32(dev, 0x409c24, 0x000f0000); + nv_wr32(dev, 0x404000, 0xc0000000); /* DISPATCH */ + nv_wr32(dev, 0x404600, 0xc0000000); /* M2MF */ + nv_wr32(dev, 0x408030, 0xc0000000); + nv_wr32(dev, 0x40601c, 0xc0000000); + nv_wr32(dev, 0x404490, 0xc0000000); /* MACRO */ + nv_wr32(dev, 0x406018, 0xc0000000); + nv_wr32(dev, 0x405840, 0xc0000000); + nv_wr32(dev, 0x405844, 0x00ffffff); + nv_mask(dev, 0x419cc0, 0x00000008, 0x00000008); + nv_mask(dev, 0x419eb4, 0x00001000, 0x00001000); +} + +static void +nvc0_graph_init_gpc_1(struct drm_device *dev) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nvc0_graph_priv *priv = dev_priv->engine.graph.priv; + int gpc, tp; + + for (gpc = 0; gpc < priv->gpc_nr; gpc++) { + nv_wr32(dev, GPC_UNIT(gpc, 0x0420), 0xc0000000); + nv_wr32(dev, GPC_UNIT(gpc, 0x0900), 0xc0000000); + nv_wr32(dev, GPC_UNIT(gpc, 0x1028), 0xc0000000); + nv_wr32(dev, GPC_UNIT(gpc, 0x0824), 0xc0000000); + for (tp = 0; tp < priv->tp_nr[gpc]; tp++) { + nv_wr32(dev, TP_UNIT(gpc, tp, 0x508), 0xffffffff); + nv_wr32(dev, TP_UNIT(gpc, tp, 0x50c), 0xffffffff); + nv_wr32(dev, TP_UNIT(gpc, tp, 0x224), 0xc0000000); + nv_wr32(dev, TP_UNIT(gpc, tp, 0x48c), 0xc0000000); + nv_wr32(dev, TP_UNIT(gpc, tp, 0x084), 0xc0000000); + nv_wr32(dev, TP_UNIT(gpc, tp, 0xe44), 0x001ffffe); + nv_wr32(dev, TP_UNIT(gpc, tp, 0xe4c), 0x0000000f); + } + nv_wr32(dev, GPC_UNIT(gpc, 0x2c90), 0xffffffff); + nv_wr32(dev, GPC_UNIT(gpc, 0x2c94), 0xffffffff); + } +} + +static void +nvc0_graph_init_rop(struct drm_device *dev) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nvc0_graph_priv *priv = dev_priv->engine.graph.priv; + int rop; + + for (rop = 0; rop < priv->rop_nr; rop++) { + nv_wr32(dev, ROP_UNIT(rop, 0x144), 0xc0000000); + nv_wr32(dev, ROP_UNIT(rop, 0x070), 0xc0000000); + nv_wr32(dev, ROP_UNIT(rop, 0x204), 0xffffffff); + nv_wr32(dev, ROP_UNIT(rop, 0x208), 0xffffffff); + } +} + +static int +nvc0_fuc_load_fw(struct drm_device *dev, u32 fuc_base, + const char *code_fw, const char *data_fw) +{ + const struct firmware *fw; + char name[32]; + int ret, i; + + snprintf(name, sizeof(name), "nouveau/%s", data_fw); + ret = request_firmware(&fw, name, &dev->pdev->dev); + if (ret) { + NV_ERROR(dev, "failed to load %s\n", data_fw); + return ret; + } + + nv_wr32(dev, fuc_base + 0x01c0, 0x01000000); + for (i = 0; i < fw->size / 4; i++) + nv_wr32(dev, fuc_base + 0x01c4, ((u32 *)fw->data)[i]); + release_firmware(fw); + + snprintf(name, sizeof(name), "nouveau/%s", code_fw); + ret = request_firmware(&fw, name, &dev->pdev->dev); + if (ret) { + NV_ERROR(dev, "failed to load %s\n", code_fw); + return ret; + } + + nv_wr32(dev, fuc_base + 0x0180, 0x01000000); + for (i = 0; i < fw->size / 4; i++) { + if ((i & 0x3f) == 0) + nv_wr32(dev, fuc_base + 0x0188, i >> 6); + nv_wr32(dev, fuc_base + 0x0184, ((u32 *)fw->data)[i]); + } + release_firmware(fw); + + return 0; +} + +static int +nvc0_graph_init_ctxctl(struct drm_device *dev) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nvc0_graph_priv *priv = dev_priv->engine.graph.priv; + u32 r000260; + int ret; + + /* load fuc microcode */ + r000260 = nv_mask(dev, 0x000260, 0x00000001, 0x00000000); + ret = nvc0_fuc_load_fw(dev, 0x409000, "fuc409c", "fuc409d"); + if (ret == 0) + nvc0_fuc_load_fw(dev, 0x41a000, "fuc41ac", "fuc41ad"); + nv_wr32(dev, 0x000260, r000260); + + if (ret) + return ret; + + /* start both of them running */ + nv_wr32(dev, 0x409840, 0xffffffff); + nv_wr32(dev, 0x41a10c, 0x00000000); + nv_wr32(dev, 0x40910c, 0x00000000); + nv_wr32(dev, 0x41a100, 0x00000002); + nv_wr32(dev, 0x409100, 0x00000002); + if (!nv_wait(dev, 0x409800, 0x00000001, 0x00000001)) + NV_INFO(dev, "0x409800 wait failed\n"); + + nv_wr32(dev, 0x409840, 0xffffffff); + nv_wr32(dev, 0x409500, 0x7fffffff); + nv_wr32(dev, 0x409504, 0x00000021); + + nv_wr32(dev, 0x409840, 0xffffffff); + nv_wr32(dev, 0x409500, 0x00000000); + nv_wr32(dev, 0x409504, 0x00000010); + if (!nv_wait_ne(dev, 0x409800, 0xffffffff, 0x00000000)) { + NV_ERROR(dev, "fuc09 req 0x10 timeout\n"); + return -EBUSY; + } + priv->grctx_size = nv_rd32(dev, 0x409800); + + nv_wr32(dev, 0x409840, 0xffffffff); + nv_wr32(dev, 0x409500, 0x00000000); + nv_wr32(dev, 0x409504, 0x00000016); + if (!nv_wait_ne(dev, 0x409800, 0xffffffff, 0x00000000)) { + NV_ERROR(dev, "fuc09 req 0x16 timeout\n"); + return -EBUSY; + } + + nv_wr32(dev, 0x409840, 0xffffffff); + nv_wr32(dev, 0x409500, 0x00000000); + nv_wr32(dev, 0x409504, 0x00000025); + if (!nv_wait_ne(dev, 0x409800, 0xffffffff, 0x00000000)) { + NV_ERROR(dev, "fuc09 req 0x25 timeout\n"); + return -EBUSY; + } + + return 0; } int nvc0_graph_init(struct drm_device *dev) { struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; + struct nvc0_graph_priv *priv; + int ret; + dev_priv->engine.graph.accel_blocked = true; + + switch (dev_priv->chipset) { + case 0xc0: + case 0xc3: + case 0xc4: + break; + default: + NV_ERROR(dev, "PGRAPH: unsupported chipset, please report!\n"); + if (nouveau_noaccel != 0) + return 0; + break; + } + + nv_mask(dev, 0x000200, 0x18001000, 0x00000000); + nv_mask(dev, 0x000200, 0x18001000, 0x18001000); + + if (!pgraph->priv) { + ret = nvc0_graph_create(dev); + if (ret) + return ret; + } + priv = pgraph->priv; + + nvc0_graph_init_obj418880(dev); + nvc0_graph_init_regs(dev); + //nvc0_graph_init_unitplemented_magics(dev); + nvc0_graph_init_gpc_0(dev); + //nvc0_graph_init_unitplemented_c242(dev); + + nv_wr32(dev, 0x400500, 0x00010001); + nv_wr32(dev, 0x400100, 0xffffffff); + nv_wr32(dev, 0x40013c, 0xffffffff); + + nvc0_graph_init_units(dev); + nvc0_graph_init_gpc_1(dev); + nvc0_graph_init_rop(dev); + + nv_wr32(dev, 0x400108, 0xffffffff); + nv_wr32(dev, 0x400138, 0xffffffff); + nv_wr32(dev, 0x400118, 0xffffffff); + nv_wr32(dev, 0x400130, 0xffffffff); + nv_wr32(dev, 0x40011c, 0xffffffff); + nv_wr32(dev, 0x400134, 0xffffffff); + nv_wr32(dev, 0x400054, 0x34ce3464); + + ret = nvc0_graph_init_ctxctl(dev); + if (ret) + return ret; + + dev_priv->engine.graph.accel_blocked = false; return 0; } +static struct nouveau_enum nvc0_graph_data_error[] = { + { 5, "INVALID_ENUM" }, + {} +}; + +static int +nvc0_graph_isr_chid(struct drm_device *dev, u64 inst) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_channel *chan; + unsigned long flags; + int i; + + spin_lock_irqsave(&dev_priv->channels.lock, flags); + for (i = 0; i < dev_priv->engine.fifo.channels; i++) { + chan = dev_priv->channels.ptr[i]; + if (!chan || !chan->ramin) + continue; + + if (inst == chan->ramin->vinst) + break; + } + spin_unlock_irqrestore(&dev_priv->channels.lock, flags); + return i; +} + +static void +nvc0_graph_isr(struct drm_device *dev) +{ + u64 inst = (u64)(nv_rd32(dev, 0x409b00) & 0x0fffffff) << 12; + u32 chid = nvc0_graph_isr_chid(dev, inst); + u32 stat = nv_rd32(dev, 0x400100); + u32 addr = nv_rd32(dev, 0x400704); + u32 mthd = (addr & 0x00003ffc); + u32 subc = (addr & 0x00070000) >> 16; + u32 data = nv_rd32(dev, 0x400708); + u32 code = nv_rd32(dev, 0x400110); + u32 class = nv_rd32(dev, 0x404200 + (subc * 4)); + + if (stat & 0x00000010) { + NV_INFO(dev, "PGRAPH: ILLEGAL_MTHD ch %d [0x%010llx] subc %d " + "class 0x%04x mthd 0x%04x data 0x%08x\n", + chid, inst, subc, class, mthd, data); + nv_wr32(dev, 0x400100, 0x00000010); + stat &= ~0x00000010; + } + + if (stat & 0x00100000) { + NV_INFO(dev, "PGRAPH: DATA_ERROR ["); + nouveau_enum_print(nvc0_graph_data_error, code); + printk("] ch %d [0x%010llx] subc %d class 0x%04x " + "mthd 0x%04x data 0x%08x\n", + chid, inst, subc, class, mthd, data); + nv_wr32(dev, 0x400100, 0x00100000); + stat &= ~0x00100000; + } + + if (stat & 0x00080000) { + u32 ustat = nv_rd32(dev, 0x409c18); + + NV_INFO(dev, "PGRAPH: CTXCTRL ustat 0x%08x\n", ustat); + + nv_wr32(dev, 0x409c20, ustat); + nv_wr32(dev, 0x400100, 0x00080000); + stat &= ~0x00080000; + } + + if (stat) { + NV_INFO(dev, "PGRAPH: unknown stat 0x%08x\n", stat); + nv_wr32(dev, 0x400100, stat); + } + + nv_wr32(dev, 0x400500, 0x00010001); +} diff --git a/drivers/gpu/drm/nouveau/nvc0_graph.h b/drivers/gpu/drm/nouveau/nvc0_graph.h new file mode 100644 index 000000000000..1e1f24f3fd34 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvc0_graph.h @@ -0,0 +1,66 @@ +/* + * Copyright 2010 Red Hat Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: Ben Skeggs + */ + +#ifndef __NVC0_GRAPH_H__ +#define __NVC0_GRAPH_H__ + +#define GPC_MAX 4 +#define TP_MAX 32 + +#define ROP_BCAST(r) (0x408800 + (r)) +#define ROP_UNIT(u,r) (0x410000 + (u) * 0x400 + (r)) +#define GPC_BCAST(r) (0x418000 + (r)) +#define GPC_UNIT(t,r) (0x500000 + (t) * 0x8000 + (r)) +#define TP_UNIT(t,m,r) (0x504000 + (t) * 0x8000 + (m) * 0x800 + (r)) + +struct nvc0_graph_priv { + u8 gpc_nr; + u8 rop_nr; + u8 tp_nr[GPC_MAX]; + u8 tp_total; + + u32 grctx_size; + u32 *grctx_vals; + struct nouveau_gpuobj *unk4188b4; + struct nouveau_gpuobj *unk4188b8; + + u8 magic_not_rop_nr; + u32 magic419bd0; + u32 magic419be4; + u32 magicgpc980[4]; + u32 magicgpc918; +}; + +struct nvc0_graph_chan { + struct nouveau_gpuobj *grctx; + struct nouveau_gpuobj *unk408004; // 0x418810 too + struct nouveau_gpuobj *unk40800c; // 0x419004 too + struct nouveau_gpuobj *unk418810; // 0x419848 too + struct nouveau_gpuobj *mmio; + int mmio_nr; +}; + +int nvc0_grctx_generate(struct nouveau_channel *); + +#endif diff --git a/drivers/gpu/drm/nouveau/nvc0_grctx.c b/drivers/gpu/drm/nouveau/nvc0_grctx.c new file mode 100644 index 000000000000..88fa6211ac19 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvc0_grctx.c @@ -0,0 +1,2854 @@ +/* + * Copyright 2010 Red Hat Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: Ben Skeggs + */ + +#include "drmP.h" +#include "nouveau_drv.h" +#include "nouveau_mm.h" +#include "nvc0_graph.h" + +static void +nv_icmd(struct drm_device *dev, u32 icmd, u32 data) +{ + nv_wr32(dev, 0x400204, data); + nv_wr32(dev, 0x400200, icmd); + while (nv_rd32(dev, 0x400700) & 2) {} +} + +static void +nv_mthd(struct drm_device *dev, u32 class, u32 mthd, u32 data) +{ + nv_wr32(dev, 0x40448c, data); + nv_wr32(dev, 0x404488, 0x80000000 | (mthd << 14) | class); +} + +static void +nvc0_grctx_generate_9097(struct drm_device *dev) +{ + nv_mthd(dev, 0x9097, 0x0800, 0x00000000); + nv_mthd(dev, 0x9097, 0x0840, 0x00000000); + nv_mthd(dev, 0x9097, 0x0880, 0x00000000); + nv_mthd(dev, 0x9097, 0x08c0, 0x00000000); + nv_mthd(dev, 0x9097, 0x0900, 0x00000000); + nv_mthd(dev, 0x9097, 0x0940, 0x00000000); + nv_mthd(dev, 0x9097, 0x0980, 0x00000000); + nv_mthd(dev, 0x9097, 0x09c0, 0x00000000); + nv_mthd(dev, 0x9097, 0x0804, 0x00000000); + nv_mthd(dev, 0x9097, 0x0844, 0x00000000); + nv_mthd(dev, 0x9097, 0x0884, 0x00000000); + nv_mthd(dev, 0x9097, 0x08c4, 0x00000000); + nv_mthd(dev, 0x9097, 0x0904, 0x00000000); + nv_mthd(dev, 0x9097, 0x0944, 0x00000000); + nv_mthd(dev, 0x9097, 0x0984, 0x00000000); + nv_mthd(dev, 0x9097, 0x09c4, 0x00000000); + nv_mthd(dev, 0x9097, 0x0808, 0x00000400); + nv_mthd(dev, 0x9097, 0x0848, 0x00000400); + nv_mthd(dev, 0x9097, 0x0888, 0x00000400); + nv_mthd(dev, 0x9097, 0x08c8, 0x00000400); + nv_mthd(dev, 0x9097, 0x0908, 0x00000400); + nv_mthd(dev, 0x9097, 0x0948, 0x00000400); + nv_mthd(dev, 0x9097, 0x0988, 0x00000400); + nv_mthd(dev, 0x9097, 0x09c8, 0x00000400); + nv_mthd(dev, 0x9097, 0x080c, 0x00000300); + nv_mthd(dev, 0x9097, 0x084c, 0x00000300); + nv_mthd(dev, 0x9097, 0x088c, 0x00000300); + nv_mthd(dev, 0x9097, 0x08cc, 0x00000300); + nv_mthd(dev, 0x9097, 0x090c, 0x00000300); + nv_mthd(dev, 0x9097, 0x094c, 0x00000300); + nv_mthd(dev, 0x9097, 0x098c, 0x00000300); + nv_mthd(dev, 0x9097, 0x09cc, 0x00000300); + nv_mthd(dev, 0x9097, 0x0810, 0x000000cf); + nv_mthd(dev, 0x9097, 0x0850, 0x00000000); + nv_mthd(dev, 0x9097, 0x0890, 0x00000000); + nv_mthd(dev, 0x9097, 0x08d0, 0x00000000); + nv_mthd(dev, 0x9097, 0x0910, 0x00000000); + nv_mthd(dev, 0x9097, 0x0950, 0x00000000); + nv_mthd(dev, 0x9097, 0x0990, 0x00000000); + nv_mthd(dev, 0x9097, 0x09d0, 0x00000000); + nv_mthd(dev, 0x9097, 0x0814, 0x00000040); + nv_mthd(dev, 0x9097, 0x0854, 0x00000040); + nv_mthd(dev, 0x9097, 0x0894, 0x00000040); + nv_mthd(dev, 0x9097, 0x08d4, 0x00000040); + nv_mthd(dev, 0x9097, 0x0914, 0x00000040); + nv_mthd(dev, 0x9097, 0x0954, 0x00000040); + nv_mthd(dev, 0x9097, 0x0994, 0x00000040); + nv_mthd(dev, 0x9097, 0x09d4, 0x00000040); + nv_mthd(dev, 0x9097, 0x0818, 0x00000001); + nv_mthd(dev, 0x9097, 0x0858, 0x00000001); + nv_mthd(dev, 0x9097, 0x0898, 0x00000001); + nv_mthd(dev, 0x9097, 0x08d8, 0x00000001); + nv_mthd(dev, 0x9097, 0x0918, 0x00000001); + nv_mthd(dev, 0x9097, 0x0958, 0x00000001); + nv_mthd(dev, 0x9097, 0x0998, 0x00000001); + nv_mthd(dev, 0x9097, 0x09d8, 0x00000001); + nv_mthd(dev, 0x9097, 0x081c, 0x00000000); + nv_mthd(dev, 0x9097, 0x085c, 0x00000000); + nv_mthd(dev, 0x9097, 0x089c, 0x00000000); + nv_mthd(dev, 0x9097, 0x08dc, 0x00000000); + nv_mthd(dev, 0x9097, 0x091c, 0x00000000); + nv_mthd(dev, 0x9097, 0x095c, 0x00000000); + nv_mthd(dev, 0x9097, 0x099c, 0x00000000); + nv_mthd(dev, 0x9097, 0x09dc, 0x00000000); + nv_mthd(dev, 0x9097, 0x0820, 0x00000000); + nv_mthd(dev, 0x9097, 0x0860, 0x00000000); + nv_mthd(dev, 0x9097, 0x08a0, 0x00000000); + nv_mthd(dev, 0x9097, 0x08e0, 0x00000000); + nv_mthd(dev, 0x9097, 0x0920, 0x00000000); + nv_mthd(dev, 0x9097, 0x0960, 0x00000000); + nv_mthd(dev, 0x9097, 0x09a0, 0x00000000); + nv_mthd(dev, 0x9097, 0x09e0, 0x00000000); + nv_mthd(dev, 0x9097, 0x2700, 0x00000000); + nv_mthd(dev, 0x9097, 0x2720, 0x00000000); + nv_mthd(dev, 0x9097, 0x2740, 0x00000000); + nv_mthd(dev, 0x9097, 0x2760, 0x00000000); + nv_mthd(dev, 0x9097, 0x2780, 0x00000000); + nv_mthd(dev, 0x9097, 0x27a0, 0x00000000); + nv_mthd(dev, 0x9097, 0x27c0, 0x00000000); + nv_mthd(dev, 0x9097, 0x27e0, 0x00000000); + nv_mthd(dev, 0x9097, 0x2704, 0x00000000); + nv_mthd(dev, 0x9097, 0x2724, 0x00000000); + nv_mthd(dev, 0x9097, 0x2744, 0x00000000); + nv_mthd(dev, 0x9097, 0x2764, 0x00000000); + nv_mthd(dev, 0x9097, 0x2784, 0x00000000); + nv_mthd(dev, 0x9097, 0x27a4, 0x00000000); + nv_mthd(dev, 0x9097, 0x27c4, 0x00000000); + nv_mthd(dev, 0x9097, 0x27e4, 0x00000000); + nv_mthd(dev, 0x9097, 0x2708, 0x00000000); + nv_mthd(dev, 0x9097, 0x2728, 0x00000000); + nv_mthd(dev, 0x9097, 0x2748, 0x00000000); + nv_mthd(dev, 0x9097, 0x2768, 0x00000000); + nv_mthd(dev, 0x9097, 0x2788, 0x00000000); + nv_mthd(dev, 0x9097, 0x27a8, 0x00000000); + nv_mthd(dev, 0x9097, 0x27c8, 0x00000000); + nv_mthd(dev, 0x9097, 0x27e8, 0x00000000); + nv_mthd(dev, 0x9097, 0x270c, 0x00000000); + nv_mthd(dev, 0x9097, 0x272c, 0x00000000); + nv_mthd(dev, 0x9097, 0x274c, 0x00000000); + nv_mthd(dev, 0x9097, 0x276c, 0x00000000); + nv_mthd(dev, 0x9097, 0x278c, 0x00000000); + nv_mthd(dev, 0x9097, 0x27ac, 0x00000000); + nv_mthd(dev, 0x9097, 0x27cc, 0x00000000); + nv_mthd(dev, 0x9097, 0x27ec, 0x00000000); + nv_mthd(dev, 0x9097, 0x2710, 0x00014000); + nv_mthd(dev, 0x9097, 0x2730, 0x00014000); + nv_mthd(dev, 0x9097, 0x2750, 0x00014000); + nv_mthd(dev, 0x9097, 0x2770, 0x00014000); + nv_mthd(dev, 0x9097, 0x2790, 0x00014000); + nv_mthd(dev, 0x9097, 0x27b0, 0x00014000); + nv_mthd(dev, 0x9097, 0x27d0, 0x00014000); + nv_mthd(dev, 0x9097, 0x27f0, 0x00014000); + nv_mthd(dev, 0x9097, 0x2714, 0x00000040); + nv_mthd(dev, 0x9097, 0x2734, 0x00000040); + nv_mthd(dev, 0x9097, 0x2754, 0x00000040); + nv_mthd(dev, 0x9097, 0x2774, 0x00000040); + nv_mthd(dev, 0x9097, 0x2794, 0x00000040); + nv_mthd(dev, 0x9097, 0x27b4, 0x00000040); + nv_mthd(dev, 0x9097, 0x27d4, 0x00000040); + nv_mthd(dev, 0x9097, 0x27f4, 0x00000040); + nv_mthd(dev, 0x9097, 0x1c00, 0x00000000); + nv_mthd(dev, 0x9097, 0x1c10, 0x00000000); + nv_mthd(dev, 0x9097, 0x1c20, 0x00000000); + nv_mthd(dev, 0x9097, 0x1c30, 0x00000000); + nv_mthd(dev, 0x9097, 0x1c40, 0x00000000); + nv_mthd(dev, 0x9097, 0x1c50, 0x00000000); + nv_mthd(dev, 0x9097, 0x1c60, 0x00000000); + nv_mthd(dev, 0x9097, 0x1c70, 0x00000000); + nv_mthd(dev, 0x9097, 0x1c80, 0x00000000); + nv_mthd(dev, 0x9097, 0x1c90, 0x00000000); + nv_mthd(dev, 0x9097, 0x1ca0, 0x00000000); + nv_mthd(dev, 0x9097, 0x1cb0, 0x00000000); + nv_mthd(dev, 0x9097, 0x1cc0, 0x00000000); + nv_mthd(dev, 0x9097, 0x1cd0, 0x00000000); + nv_mthd(dev, 0x9097, 0x1ce0, 0x00000000); + nv_mthd(dev, 0x9097, 0x1cf0, 0x00000000); + nv_mthd(dev, 0x9097, 0x1c04, 0x00000000); + nv_mthd(dev, 0x9097, 0x1c14, 0x00000000); + nv_mthd(dev, 0x9097, 0x1c24, 0x00000000); + nv_mthd(dev, 0x9097, 0x1c34, 0x00000000); + nv_mthd(dev, 0x9097, 0x1c44, 0x00000000); + nv_mthd(dev, 0x9097, 0x1c54, 0x00000000); + nv_mthd(dev, 0x9097, 0x1c64, 0x00000000); + nv_mthd(dev, 0x9097, 0x1c74, 0x00000000); + nv_mthd(dev, 0x9097, 0x1c84, 0x00000000); + nv_mthd(dev, 0x9097, 0x1c94, 0x00000000); + nv_mthd(dev, 0x9097, 0x1ca4, 0x00000000); + nv_mthd(dev, 0x9097, 0x1cb4, 0x00000000); + nv_mthd(dev, 0x9097, 0x1cc4, 0x00000000); + nv_mthd(dev, 0x9097, 0x1cd4, 0x00000000); + nv_mthd(dev, 0x9097, 0x1ce4, 0x00000000); + nv_mthd(dev, 0x9097, 0x1cf4, 0x00000000); + nv_mthd(dev, 0x9097, 0x1c08, 0x00000000); + nv_mthd(dev, 0x9097, 0x1c18, 0x00000000); + nv_mthd(dev, 0x9097, 0x1c28, 0x00000000); + nv_mthd(dev, 0x9097, 0x1c38, 0x00000000); + nv_mthd(dev, 0x9097, 0x1c48, 0x00000000); + nv_mthd(dev, 0x9097, 0x1c58, 0x00000000); + nv_mthd(dev, 0x9097, 0x1c68, 0x00000000); + nv_mthd(dev, 0x9097, 0x1c78, 0x00000000); + nv_mthd(dev, 0x9097, 0x1c88, 0x00000000); + nv_mthd(dev, 0x9097, 0x1c98, 0x00000000); + nv_mthd(dev, 0x9097, 0x1ca8, 0x00000000); + nv_mthd(dev, 0x9097, 0x1cb8, 0x00000000); + nv_mthd(dev, 0x9097, 0x1cc8, 0x00000000); + nv_mthd(dev, 0x9097, 0x1cd8, 0x00000000); + nv_mthd(dev, 0x9097, 0x1ce8, 0x00000000); + nv_mthd(dev, 0x9097, 0x1cf8, 0x00000000); + nv_mthd(dev, 0x9097, 0x1c0c, 0x00000000); + nv_mthd(dev, 0x9097, 0x1c1c, 0x00000000); + nv_mthd(dev, 0x9097, 0x1c2c, 0x00000000); + nv_mthd(dev, 0x9097, 0x1c3c, 0x00000000); + nv_mthd(dev, 0x9097, 0x1c4c, 0x00000000); + nv_mthd(dev, 0x9097, 0x1c5c, 0x00000000); + nv_mthd(dev, 0x9097, 0x1c6c, 0x00000000); + nv_mthd(dev, 0x9097, 0x1c7c, 0x00000000); + nv_mthd(dev, 0x9097, 0x1c8c, 0x00000000); + nv_mthd(dev, 0x9097, 0x1c9c, 0x00000000); + nv_mthd(dev, 0x9097, 0x1cac, 0x00000000); + nv_mthd(dev, 0x9097, 0x1cbc, 0x00000000); + nv_mthd(dev, 0x9097, 0x1ccc, 0x00000000); + nv_mthd(dev, 0x9097, 0x1cdc, 0x00000000); + nv_mthd(dev, 0x9097, 0x1cec, 0x00000000); + nv_mthd(dev, 0x9097, 0x1cfc, 0x00000000); + nv_mthd(dev, 0x9097, 0x1d00, 0x00000000); + nv_mthd(dev, 0x9097, 0x1d10, 0x00000000); + nv_mthd(dev, 0x9097, 0x1d20, 0x00000000); + nv_mthd(dev, 0x9097, 0x1d30, 0x00000000); + nv_mthd(dev, 0x9097, 0x1d40, 0x00000000); + nv_mthd(dev, 0x9097, 0x1d50, 0x00000000); + nv_mthd(dev, 0x9097, 0x1d60, 0x00000000); + nv_mthd(dev, 0x9097, 0x1d70, 0x00000000); + nv_mthd(dev, 0x9097, 0x1d80, 0x00000000); + nv_mthd(dev, 0x9097, 0x1d90, 0x00000000); + nv_mthd(dev, 0x9097, 0x1da0, 0x00000000); + nv_mthd(dev, 0x9097, 0x1db0, 0x00000000); + nv_mthd(dev, 0x9097, 0x1dc0, 0x00000000); + nv_mthd(dev, 0x9097, 0x1dd0, 0x00000000); + nv_mthd(dev, 0x9097, 0x1de0, 0x00000000); + nv_mthd(dev, 0x9097, 0x1df0, 0x00000000); + nv_mthd(dev, 0x9097, 0x1d04, 0x00000000); + nv_mthd(dev, 0x9097, 0x1d14, 0x00000000); + nv_mthd(dev, 0x9097, 0x1d24, 0x00000000); + nv_mthd(dev, 0x9097, 0x1d34, 0x00000000); + nv_mthd(dev, 0x9097, 0x1d44, 0x00000000); + nv_mthd(dev, 0x9097, 0x1d54, 0x00000000); + nv_mthd(dev, 0x9097, 0x1d64, 0x00000000); + nv_mthd(dev, 0x9097, 0x1d74, 0x00000000); + nv_mthd(dev, 0x9097, 0x1d84, 0x00000000); + nv_mthd(dev, 0x9097, 0x1d94, 0x00000000); + nv_mthd(dev, 0x9097, 0x1da4, 0x00000000); + nv_mthd(dev, 0x9097, 0x1db4, 0x00000000); + nv_mthd(dev, 0x9097, 0x1dc4, 0x00000000); + nv_mthd(dev, 0x9097, 0x1dd4, 0x00000000); + nv_mthd(dev, 0x9097, 0x1de4, 0x00000000); + nv_mthd(dev, 0x9097, 0x1df4, 0x00000000); + nv_mthd(dev, 0x9097, 0x1d08, 0x00000000); + nv_mthd(dev, 0x9097, 0x1d18, 0x00000000); + nv_mthd(dev, 0x9097, 0x1d28, 0x00000000); + nv_mthd(dev, 0x9097, 0x1d38, 0x00000000); + nv_mthd(dev, 0x9097, 0x1d48, 0x00000000); + nv_mthd(dev, 0x9097, 0x1d58, 0x00000000); + nv_mthd(dev, 0x9097, 0x1d68, 0x00000000); + nv_mthd(dev, 0x9097, 0x1d78, 0x00000000); + nv_mthd(dev, 0x9097, 0x1d88, 0x00000000); + nv_mthd(dev, 0x9097, 0x1d98, 0x00000000); + nv_mthd(dev, 0x9097, 0x1da8, 0x00000000); + nv_mthd(dev, 0x9097, 0x1db8, 0x00000000); + nv_mthd(dev, 0x9097, 0x1dc8, 0x00000000); + nv_mthd(dev, 0x9097, 0x1dd8, 0x00000000); + nv_mthd(dev, 0x9097, 0x1de8, 0x00000000); + nv_mthd(dev, 0x9097, 0x1df8, 0x00000000); + nv_mthd(dev, 0x9097, 0x1d0c, 0x00000000); + nv_mthd(dev, 0x9097, 0x1d1c, 0x00000000); + nv_mthd(dev, 0x9097, 0x1d2c, 0x00000000); + nv_mthd(dev, 0x9097, 0x1d3c, 0x00000000); + nv_mthd(dev, 0x9097, 0x1d4c, 0x00000000); + nv_mthd(dev, 0x9097, 0x1d5c, 0x00000000); + nv_mthd(dev, 0x9097, 0x1d6c, 0x00000000); + nv_mthd(dev, 0x9097, 0x1d7c, 0x00000000); + nv_mthd(dev, 0x9097, 0x1d8c, 0x00000000); + nv_mthd(dev, 0x9097, 0x1d9c, 0x00000000); + nv_mthd(dev, 0x9097, 0x1dac, 0x00000000); + nv_mthd(dev, 0x9097, 0x1dbc, 0x00000000); + nv_mthd(dev, 0x9097, 0x1dcc, 0x00000000); + nv_mthd(dev, 0x9097, 0x1ddc, 0x00000000); + nv_mthd(dev, 0x9097, 0x1dec, 0x00000000); + nv_mthd(dev, 0x9097, 0x1dfc, 0x00000000); + nv_mthd(dev, 0x9097, 0x1f00, 0x00000000); + nv_mthd(dev, 0x9097, 0x1f08, 0x00000000); + nv_mthd(dev, 0x9097, 0x1f10, 0x00000000); + nv_mthd(dev, 0x9097, 0x1f18, 0x00000000); + nv_mthd(dev, 0x9097, 0x1f20, 0x00000000); + nv_mthd(dev, 0x9097, 0x1f28, 0x00000000); + nv_mthd(dev, 0x9097, 0x1f30, 0x00000000); + nv_mthd(dev, 0x9097, 0x1f38, 0x00000000); + nv_mthd(dev, 0x9097, 0x1f40, 0x00000000); + nv_mthd(dev, 0x9097, 0x1f48, 0x00000000); + nv_mthd(dev, 0x9097, 0x1f50, 0x00000000); + nv_mthd(dev, 0x9097, 0x1f58, 0x00000000); + nv_mthd(dev, 0x9097, 0x1f60, 0x00000000); + nv_mthd(dev, 0x9097, 0x1f68, 0x00000000); + nv_mthd(dev, 0x9097, 0x1f70, 0x00000000); + nv_mthd(dev, 0x9097, 0x1f78, 0x00000000); + nv_mthd(dev, 0x9097, 0x1f04, 0x00000000); + nv_mthd(dev, 0x9097, 0x1f0c, 0x00000000); + nv_mthd(dev, 0x9097, 0x1f14, 0x00000000); + nv_mthd(dev, 0x9097, 0x1f1c, 0x00000000); + nv_mthd(dev, 0x9097, 0x1f24, 0x00000000); + nv_mthd(dev, 0x9097, 0x1f2c, 0x00000000); + nv_mthd(dev, 0x9097, 0x1f34, 0x00000000); + nv_mthd(dev, 0x9097, 0x1f3c, 0x00000000); + nv_mthd(dev, 0x9097, 0x1f44, 0x00000000); + nv_mthd(dev, 0x9097, 0x1f4c, 0x00000000); + nv_mthd(dev, 0x9097, 0x1f54, 0x00000000); + nv_mthd(dev, 0x9097, 0x1f5c, 0x00000000); + nv_mthd(dev, 0x9097, 0x1f64, 0x00000000); + nv_mthd(dev, 0x9097, 0x1f6c, 0x00000000); + nv_mthd(dev, 0x9097, 0x1f74, 0x00000000); + nv_mthd(dev, 0x9097, 0x1f7c, 0x00000000); + nv_mthd(dev, 0x9097, 0x1f80, 0x00000000); + nv_mthd(dev, 0x9097, 0x1f88, 0x00000000); + nv_mthd(dev, 0x9097, 0x1f90, 0x00000000); + nv_mthd(dev, 0x9097, 0x1f98, 0x00000000); + nv_mthd(dev, 0x9097, 0x1fa0, 0x00000000); + nv_mthd(dev, 0x9097, 0x1fa8, 0x00000000); + nv_mthd(dev, 0x9097, 0x1fb0, 0x00000000); + nv_mthd(dev, 0x9097, 0x1fb8, 0x00000000); + nv_mthd(dev, 0x9097, 0x1fc0, 0x00000000); + nv_mthd(dev, 0x9097, 0x1fc8, 0x00000000); + nv_mthd(dev, 0x9097, 0x1fd0, 0x00000000); + nv_mthd(dev, 0x9097, 0x1fd8, 0x00000000); + nv_mthd(dev, 0x9097, 0x1fe0, 0x00000000); + nv_mthd(dev, 0x9097, 0x1fe8, 0x00000000); + nv_mthd(dev, 0x9097, 0x1ff0, 0x00000000); + nv_mthd(dev, 0x9097, 0x1ff8, 0x00000000); + nv_mthd(dev, 0x9097, 0x1f84, 0x00000000); + nv_mthd(dev, 0x9097, 0x1f8c, 0x00000000); + nv_mthd(dev, 0x9097, 0x1f94, 0x00000000); + nv_mthd(dev, 0x9097, 0x1f9c, 0x00000000); + nv_mthd(dev, 0x9097, 0x1fa4, 0x00000000); + nv_mthd(dev, 0x9097, 0x1fac, 0x00000000); + nv_mthd(dev, 0x9097, 0x1fb4, 0x00000000); + nv_mthd(dev, 0x9097, 0x1fbc, 0x00000000); + nv_mthd(dev, 0x9097, 0x1fc4, 0x00000000); + nv_mthd(dev, 0x9097, 0x1fcc, 0x00000000); + nv_mthd(dev, 0x9097, 0x1fd4, 0x00000000); + nv_mthd(dev, 0x9097, 0x1fdc, 0x00000000); + nv_mthd(dev, 0x9097, 0x1fe4, 0x00000000); + nv_mthd(dev, 0x9097, 0x1fec, 0x00000000); + nv_mthd(dev, 0x9097, 0x1ff4, 0x00000000); + nv_mthd(dev, 0x9097, 0x1ffc, 0x00000000); + nv_mthd(dev, 0x9097, 0x2200, 0x00000022); + nv_mthd(dev, 0x9097, 0x2210, 0x00000022); + nv_mthd(dev, 0x9097, 0x2220, 0x00000022); + nv_mthd(dev, 0x9097, 0x2230, 0x00000022); + nv_mthd(dev, 0x9097, 0x2240, 0x00000022); + nv_mthd(dev, 0x9097, 0x2000, 0x00000000); + nv_mthd(dev, 0x9097, 0x2040, 0x00000011); + nv_mthd(dev, 0x9097, 0x2080, 0x00000020); + nv_mthd(dev, 0x9097, 0x20c0, 0x00000030); + nv_mthd(dev, 0x9097, 0x2100, 0x00000040); + nv_mthd(dev, 0x9097, 0x2140, 0x00000051); + nv_mthd(dev, 0x9097, 0x200c, 0x00000001); + nv_mthd(dev, 0x9097, 0x204c, 0x00000001); + nv_mthd(dev, 0x9097, 0x208c, 0x00000001); + nv_mthd(dev, 0x9097, 0x20cc, 0x00000001); + nv_mthd(dev, 0x9097, 0x210c, 0x00000001); + nv_mthd(dev, 0x9097, 0x214c, 0x00000001); + nv_mthd(dev, 0x9097, 0x2010, 0x00000000); + nv_mthd(dev, 0x9097, 0x2050, 0x00000000); + nv_mthd(dev, 0x9097, 0x2090, 0x00000001); + nv_mthd(dev, 0x9097, 0x20d0, 0x00000002); + nv_mthd(dev, 0x9097, 0x2110, 0x00000003); + nv_mthd(dev, 0x9097, 0x2150, 0x00000004); + nv_mthd(dev, 0x9097, 0x0380, 0x00000000); + nv_mthd(dev, 0x9097, 0x03a0, 0x00000000); + nv_mthd(dev, 0x9097, 0x03c0, 0x00000000); + nv_mthd(dev, 0x9097, 0x03e0, 0x00000000); + nv_mthd(dev, 0x9097, 0x0384, 0x00000000); + nv_mthd(dev, 0x9097, 0x03a4, 0x00000000); + nv_mthd(dev, 0x9097, 0x03c4, 0x00000000); + nv_mthd(dev, 0x9097, 0x03e4, 0x00000000); + nv_mthd(dev, 0x9097, 0x0388, 0x00000000); + nv_mthd(dev, 0x9097, 0x03a8, 0x00000000); + nv_mthd(dev, 0x9097, 0x03c8, 0x00000000); + nv_mthd(dev, 0x9097, 0x03e8, 0x00000000); + nv_mthd(dev, 0x9097, 0x038c, 0x00000000); + nv_mthd(dev, 0x9097, 0x03ac, 0x00000000); + nv_mthd(dev, 0x9097, 0x03cc, 0x00000000); + nv_mthd(dev, 0x9097, 0x03ec, 0x00000000); + nv_mthd(dev, 0x9097, 0x0700, 0x00000000); + nv_mthd(dev, 0x9097, 0x0710, 0x00000000); + nv_mthd(dev, 0x9097, 0x0720, 0x00000000); + nv_mthd(dev, 0x9097, 0x0730, 0x00000000); + nv_mthd(dev, 0x9097, 0x0704, 0x00000000); + nv_mthd(dev, 0x9097, 0x0714, 0x00000000); + nv_mthd(dev, 0x9097, 0x0724, 0x00000000); + nv_mthd(dev, 0x9097, 0x0734, 0x00000000); + nv_mthd(dev, 0x9097, 0x0708, 0x00000000); + nv_mthd(dev, 0x9097, 0x0718, 0x00000000); + nv_mthd(dev, 0x9097, 0x0728, 0x00000000); + nv_mthd(dev, 0x9097, 0x0738, 0x00000000); + nv_mthd(dev, 0x9097, 0x2800, 0x00000000); + nv_mthd(dev, 0x9097, 0x2804, 0x00000000); + nv_mthd(dev, 0x9097, 0x2808, 0x00000000); + nv_mthd(dev, 0x9097, 0x280c, 0x00000000); + nv_mthd(dev, 0x9097, 0x2810, 0x00000000); + nv_mthd(dev, 0x9097, 0x2814, 0x00000000); + nv_mthd(dev, 0x9097, 0x2818, 0x00000000); + nv_mthd(dev, 0x9097, 0x281c, 0x00000000); + nv_mthd(dev, 0x9097, 0x2820, 0x00000000); + nv_mthd(dev, 0x9097, 0x2824, 0x00000000); + nv_mthd(dev, 0x9097, 0x2828, 0x00000000); + nv_mthd(dev, 0x9097, 0x282c, 0x00000000); + nv_mthd(dev, 0x9097, 0x2830, 0x00000000); + nv_mthd(dev, 0x9097, 0x2834, 0x00000000); + nv_mthd(dev, 0x9097, 0x2838, 0x00000000); + nv_mthd(dev, 0x9097, 0x283c, 0x00000000); + nv_mthd(dev, 0x9097, 0x2840, 0x00000000); + nv_mthd(dev, 0x9097, 0x2844, 0x00000000); + nv_mthd(dev, 0x9097, 0x2848, 0x00000000); + nv_mthd(dev, 0x9097, 0x284c, 0x00000000); + nv_mthd(dev, 0x9097, 0x2850, 0x00000000); + nv_mthd(dev, 0x9097, 0x2854, 0x00000000); + nv_mthd(dev, 0x9097, 0x2858, 0x00000000); + nv_mthd(dev, 0x9097, 0x285c, 0x00000000); + nv_mthd(dev, 0x9097, 0x2860, 0x00000000); + nv_mthd(dev, 0x9097, 0x2864, 0x00000000); + nv_mthd(dev, 0x9097, 0x2868, 0x00000000); + nv_mthd(dev, 0x9097, 0x286c, 0x00000000); + nv_mthd(dev, 0x9097, 0x2870, 0x00000000); + nv_mthd(dev, 0x9097, 0x2874, 0x00000000); + nv_mthd(dev, 0x9097, 0x2878, 0x00000000); + nv_mthd(dev, 0x9097, 0x287c, 0x00000000); + nv_mthd(dev, 0x9097, 0x2880, 0x00000000); + nv_mthd(dev, 0x9097, 0x2884, 0x00000000); + nv_mthd(dev, 0x9097, 0x2888, 0x00000000); + nv_mthd(dev, 0x9097, 0x288c, 0x00000000); + nv_mthd(dev, 0x9097, 0x2890, 0x00000000); + nv_mthd(dev, 0x9097, 0x2894, 0x00000000); + nv_mthd(dev, 0x9097, 0x2898, 0x00000000); + nv_mthd(dev, 0x9097, 0x289c, 0x00000000); + nv_mthd(dev, 0x9097, 0x28a0, 0x00000000); + nv_mthd(dev, 0x9097, 0x28a4, 0x00000000); + nv_mthd(dev, 0x9097, 0x28a8, 0x00000000); + nv_mthd(dev, 0x9097, 0x28ac, 0x00000000); + nv_mthd(dev, 0x9097, 0x28b0, 0x00000000); + nv_mthd(dev, 0x9097, 0x28b4, 0x00000000); + nv_mthd(dev, 0x9097, 0x28b8, 0x00000000); + nv_mthd(dev, 0x9097, 0x28bc, 0x00000000); + nv_mthd(dev, 0x9097, 0x28c0, 0x00000000); + nv_mthd(dev, 0x9097, 0x28c4, 0x00000000); + nv_mthd(dev, 0x9097, 0x28c8, 0x00000000); + nv_mthd(dev, 0x9097, 0x28cc, 0x00000000); + nv_mthd(dev, 0x9097, 0x28d0, 0x00000000); + nv_mthd(dev, 0x9097, 0x28d4, 0x00000000); + nv_mthd(dev, 0x9097, 0x28d8, 0x00000000); + nv_mthd(dev, 0x9097, 0x28dc, 0x00000000); + nv_mthd(dev, 0x9097, 0x28e0, 0x00000000); + nv_mthd(dev, 0x9097, 0x28e4, 0x00000000); + nv_mthd(dev, 0x9097, 0x28e8, 0x00000000); + nv_mthd(dev, 0x9097, 0x28ec, 0x00000000); + nv_mthd(dev, 0x9097, 0x28f0, 0x00000000); + nv_mthd(dev, 0x9097, 0x28f4, 0x00000000); + nv_mthd(dev, 0x9097, 0x28f8, 0x00000000); + nv_mthd(dev, 0x9097, 0x28fc, 0x00000000); + nv_mthd(dev, 0x9097, 0x2900, 0x00000000); + nv_mthd(dev, 0x9097, 0x2904, 0x00000000); + nv_mthd(dev, 0x9097, 0x2908, 0x00000000); + nv_mthd(dev, 0x9097, 0x290c, 0x00000000); + nv_mthd(dev, 0x9097, 0x2910, 0x00000000); + nv_mthd(dev, 0x9097, 0x2914, 0x00000000); + nv_mthd(dev, 0x9097, 0x2918, 0x00000000); + nv_mthd(dev, 0x9097, 0x291c, 0x00000000); + nv_mthd(dev, 0x9097, 0x2920, 0x00000000); + nv_mthd(dev, 0x9097, 0x2924, 0x00000000); + nv_mthd(dev, 0x9097, 0x2928, 0x00000000); + nv_mthd(dev, 0x9097, 0x292c, 0x00000000); + nv_mthd(dev, 0x9097, 0x2930, 0x00000000); + nv_mthd(dev, 0x9097, 0x2934, 0x00000000); + nv_mthd(dev, 0x9097, 0x2938, 0x00000000); + nv_mthd(dev, 0x9097, 0x293c, 0x00000000); + nv_mthd(dev, 0x9097, 0x2940, 0x00000000); + nv_mthd(dev, 0x9097, 0x2944, 0x00000000); + nv_mthd(dev, 0x9097, 0x2948, 0x00000000); + nv_mthd(dev, 0x9097, 0x294c, 0x00000000); + nv_mthd(dev, 0x9097, 0x2950, 0x00000000); + nv_mthd(dev, 0x9097, 0x2954, 0x00000000); + nv_mthd(dev, 0x9097, 0x2958, 0x00000000); + nv_mthd(dev, 0x9097, 0x295c, 0x00000000); + nv_mthd(dev, 0x9097, 0x2960, 0x00000000); + nv_mthd(dev, 0x9097, 0x2964, 0x00000000); + nv_mthd(dev, 0x9097, 0x2968, 0x00000000); + nv_mthd(dev, 0x9097, 0x296c, 0x00000000); + nv_mthd(dev, 0x9097, 0x2970, 0x00000000); + nv_mthd(dev, 0x9097, 0x2974, 0x00000000); + nv_mthd(dev, 0x9097, 0x2978, 0x00000000); + nv_mthd(dev, 0x9097, 0x297c, 0x00000000); + nv_mthd(dev, 0x9097, 0x2980, 0x00000000); + nv_mthd(dev, 0x9097, 0x2984, 0x00000000); + nv_mthd(dev, 0x9097, 0x2988, 0x00000000); + nv_mthd(dev, 0x9097, 0x298c, 0x00000000); + nv_mthd(dev, 0x9097, 0x2990, 0x00000000); + nv_mthd(dev, 0x9097, 0x2994, 0x00000000); + nv_mthd(dev, 0x9097, 0x2998, 0x00000000); + nv_mthd(dev, 0x9097, 0x299c, 0x00000000); + nv_mthd(dev, 0x9097, 0x29a0, 0x00000000); + nv_mthd(dev, 0x9097, 0x29a4, 0x00000000); + nv_mthd(dev, 0x9097, 0x29a8, 0x00000000); + nv_mthd(dev, 0x9097, 0x29ac, 0x00000000); + nv_mthd(dev, 0x9097, 0x29b0, 0x00000000); + nv_mthd(dev, 0x9097, 0x29b4, 0x00000000); + nv_mthd(dev, 0x9097, 0x29b8, 0x00000000); + nv_mthd(dev, 0x9097, 0x29bc, 0x00000000); + nv_mthd(dev, 0x9097, 0x29c0, 0x00000000); + nv_mthd(dev, 0x9097, 0x29c4, 0x00000000); + nv_mthd(dev, 0x9097, 0x29c8, 0x00000000); + nv_mthd(dev, 0x9097, 0x29cc, 0x00000000); + nv_mthd(dev, 0x9097, 0x29d0, 0x00000000); + nv_mthd(dev, 0x9097, 0x29d4, 0x00000000); + nv_mthd(dev, 0x9097, 0x29d8, 0x00000000); + nv_mthd(dev, 0x9097, 0x29dc, 0x00000000); + nv_mthd(dev, 0x9097, 0x29e0, 0x00000000); + nv_mthd(dev, 0x9097, 0x29e4, 0x00000000); + nv_mthd(dev, 0x9097, 0x29e8, 0x00000000); + nv_mthd(dev, 0x9097, 0x29ec, 0x00000000); + nv_mthd(dev, 0x9097, 0x29f0, 0x00000000); + nv_mthd(dev, 0x9097, 0x29f4, 0x00000000); + nv_mthd(dev, 0x9097, 0x29f8, 0x00000000); + nv_mthd(dev, 0x9097, 0x29fc, 0x00000000); + nv_mthd(dev, 0x9097, 0x0a00, 0x00000000); + nv_mthd(dev, 0x9097, 0x0a20, 0x00000000); + nv_mthd(dev, 0x9097, 0x0a40, 0x00000000); + nv_mthd(dev, 0x9097, 0x0a60, 0x00000000); + nv_mthd(dev, 0x9097, 0x0a80, 0x00000000); + nv_mthd(dev, 0x9097, 0x0aa0, 0x00000000); + nv_mthd(dev, 0x9097, 0x0ac0, 0x00000000); + nv_mthd(dev, 0x9097, 0x0ae0, 0x00000000); + nv_mthd(dev, 0x9097, 0x0b00, 0x00000000); + nv_mthd(dev, 0x9097, 0x0b20, 0x00000000); + nv_mthd(dev, 0x9097, 0x0b40, 0x00000000); + nv_mthd(dev, 0x9097, 0x0b60, 0x00000000); + nv_mthd(dev, 0x9097, 0x0b80, 0x00000000); + nv_mthd(dev, 0x9097, 0x0ba0, 0x00000000); + nv_mthd(dev, 0x9097, 0x0bc0, 0x00000000); + nv_mthd(dev, 0x9097, 0x0be0, 0x00000000); + nv_mthd(dev, 0x9097, 0x0a04, 0x00000000); + nv_mthd(dev, 0x9097, 0x0a24, 0x00000000); + nv_mthd(dev, 0x9097, 0x0a44, 0x00000000); + nv_mthd(dev, 0x9097, 0x0a64, 0x00000000); + nv_mthd(dev, 0x9097, 0x0a84, 0x00000000); + nv_mthd(dev, 0x9097, 0x0aa4, 0x00000000); + nv_mthd(dev, 0x9097, 0x0ac4, 0x00000000); + nv_mthd(dev, 0x9097, 0x0ae4, 0x00000000); + nv_mthd(dev, 0x9097, 0x0b04, 0x00000000); + nv_mthd(dev, 0x9097, 0x0b24, 0x00000000); + nv_mthd(dev, 0x9097, 0x0b44, 0x00000000); + nv_mthd(dev, 0x9097, 0x0b64, 0x00000000); + nv_mthd(dev, 0x9097, 0x0b84, 0x00000000); + nv_mthd(dev, 0x9097, 0x0ba4, 0x00000000); + nv_mthd(dev, 0x9097, 0x0bc4, 0x00000000); + nv_mthd(dev, 0x9097, 0x0be4, 0x00000000); + nv_mthd(dev, 0x9097, 0x0a08, 0x00000000); + nv_mthd(dev, 0x9097, 0x0a28, 0x00000000); + nv_mthd(dev, 0x9097, 0x0a48, 0x00000000); + nv_mthd(dev, 0x9097, 0x0a68, 0x00000000); + nv_mthd(dev, 0x9097, 0x0a88, 0x00000000); + nv_mthd(dev, 0x9097, 0x0aa8, 0x00000000); + nv_mthd(dev, 0x9097, 0x0ac8, 0x00000000); + nv_mthd(dev, 0x9097, 0x0ae8, 0x00000000); + nv_mthd(dev, 0x9097, 0x0b08, 0x00000000); + nv_mthd(dev, 0x9097, 0x0b28, 0x00000000); + nv_mthd(dev, 0x9097, 0x0b48, 0x00000000); + nv_mthd(dev, 0x9097, 0x0b68, 0x00000000); + nv_mthd(dev, 0x9097, 0x0b88, 0x00000000); + nv_mthd(dev, 0x9097, 0x0ba8, 0x00000000); + nv_mthd(dev, 0x9097, 0x0bc8, 0x00000000); + nv_mthd(dev, 0x9097, 0x0be8, 0x00000000); + nv_mthd(dev, 0x9097, 0x0a0c, 0x00000000); + nv_mthd(dev, 0x9097, 0x0a2c, 0x00000000); + nv_mthd(dev, 0x9097, 0x0a4c, 0x00000000); + nv_mthd(dev, 0x9097, 0x0a6c, 0x00000000); + nv_mthd(dev, 0x9097, 0x0a8c, 0x00000000); + nv_mthd(dev, 0x9097, 0x0aac, 0x00000000); + nv_mthd(dev, 0x9097, 0x0acc, 0x00000000); + nv_mthd(dev, 0x9097, 0x0aec, 0x00000000); + nv_mthd(dev, 0x9097, 0x0b0c, 0x00000000); + nv_mthd(dev, 0x9097, 0x0b2c, 0x00000000); + nv_mthd(dev, 0x9097, 0x0b4c, 0x00000000); + nv_mthd(dev, 0x9097, 0x0b6c, 0x00000000); + nv_mthd(dev, 0x9097, 0x0b8c, 0x00000000); + nv_mthd(dev, 0x9097, 0x0bac, 0x00000000); + nv_mthd(dev, 0x9097, 0x0bcc, 0x00000000); + nv_mthd(dev, 0x9097, 0x0bec, 0x00000000); + nv_mthd(dev, 0x9097, 0x0a10, 0x00000000); + nv_mthd(dev, 0x9097, 0x0a30, 0x00000000); + nv_mthd(dev, 0x9097, 0x0a50, 0x00000000); + nv_mthd(dev, 0x9097, 0x0a70, 0x00000000); + nv_mthd(dev, 0x9097, 0x0a90, 0x00000000); + nv_mthd(dev, 0x9097, 0x0ab0, 0x00000000); + nv_mthd(dev, 0x9097, 0x0ad0, 0x00000000); + nv_mthd(dev, 0x9097, 0x0af0, 0x00000000); + nv_mthd(dev, 0x9097, 0x0b10, 0x00000000); + nv_mthd(dev, 0x9097, 0x0b30, 0x00000000); + nv_mthd(dev, 0x9097, 0x0b50, 0x00000000); + nv_mthd(dev, 0x9097, 0x0b70, 0x00000000); + nv_mthd(dev, 0x9097, 0x0b90, 0x00000000); + nv_mthd(dev, 0x9097, 0x0bb0, 0x00000000); + nv_mthd(dev, 0x9097, 0x0bd0, 0x00000000); + nv_mthd(dev, 0x9097, 0x0bf0, 0x00000000); + nv_mthd(dev, 0x9097, 0x0a14, 0x00000000); + nv_mthd(dev, 0x9097, 0x0a34, 0x00000000); + nv_mthd(dev, 0x9097, 0x0a54, 0x00000000); + nv_mthd(dev, 0x9097, 0x0a74, 0x00000000); + nv_mthd(dev, 0x9097, 0x0a94, 0x00000000); + nv_mthd(dev, 0x9097, 0x0ab4, 0x00000000); + nv_mthd(dev, 0x9097, 0x0ad4, 0x00000000); + nv_mthd(dev, 0x9097, 0x0af4, 0x00000000); + nv_mthd(dev, 0x9097, 0x0b14, 0x00000000); + nv_mthd(dev, 0x9097, 0x0b34, 0x00000000); + nv_mthd(dev, 0x9097, 0x0b54, 0x00000000); + nv_mthd(dev, 0x9097, 0x0b74, 0x00000000); + nv_mthd(dev, 0x9097, 0x0b94, 0x00000000); + nv_mthd(dev, 0x9097, 0x0bb4, 0x00000000); + nv_mthd(dev, 0x9097, 0x0bd4, 0x00000000); + nv_mthd(dev, 0x9097, 0x0bf4, 0x00000000); + nv_mthd(dev, 0x9097, 0x0c00, 0x00000000); + nv_mthd(dev, 0x9097, 0x0c10, 0x00000000); + nv_mthd(dev, 0x9097, 0x0c20, 0x00000000); + nv_mthd(dev, 0x9097, 0x0c30, 0x00000000); + nv_mthd(dev, 0x9097, 0x0c40, 0x00000000); + nv_mthd(dev, 0x9097, 0x0c50, 0x00000000); + nv_mthd(dev, 0x9097, 0x0c60, 0x00000000); + nv_mthd(dev, 0x9097, 0x0c70, 0x00000000); + nv_mthd(dev, 0x9097, 0x0c80, 0x00000000); + nv_mthd(dev, 0x9097, 0x0c90, 0x00000000); + nv_mthd(dev, 0x9097, 0x0ca0, 0x00000000); + nv_mthd(dev, 0x9097, 0x0cb0, 0x00000000); + nv_mthd(dev, 0x9097, 0x0cc0, 0x00000000); + nv_mthd(dev, 0x9097, 0x0cd0, 0x00000000); + nv_mthd(dev, 0x9097, 0x0ce0, 0x00000000); + nv_mthd(dev, 0x9097, 0x0cf0, 0x00000000); + nv_mthd(dev, 0x9097, 0x0c04, 0x00000000); + nv_mthd(dev, 0x9097, 0x0c14, 0x00000000); + nv_mthd(dev, 0x9097, 0x0c24, 0x00000000); + nv_mthd(dev, 0x9097, 0x0c34, 0x00000000); + nv_mthd(dev, 0x9097, 0x0c44, 0x00000000); + nv_mthd(dev, 0x9097, 0x0c54, 0x00000000); + nv_mthd(dev, 0x9097, 0x0c64, 0x00000000); + nv_mthd(dev, 0x9097, 0x0c74, 0x00000000); + nv_mthd(dev, 0x9097, 0x0c84, 0x00000000); + nv_mthd(dev, 0x9097, 0x0c94, 0x00000000); + nv_mthd(dev, 0x9097, 0x0ca4, 0x00000000); + nv_mthd(dev, 0x9097, 0x0cb4, 0x00000000); + nv_mthd(dev, 0x9097, 0x0cc4, 0x00000000); + nv_mthd(dev, 0x9097, 0x0cd4, 0x00000000); + nv_mthd(dev, 0x9097, 0x0ce4, 0x00000000); + nv_mthd(dev, 0x9097, 0x0cf4, 0x00000000); + nv_mthd(dev, 0x9097, 0x0c08, 0x00000000); + nv_mthd(dev, 0x9097, 0x0c18, 0x00000000); + nv_mthd(dev, 0x9097, 0x0c28, 0x00000000); + nv_mthd(dev, 0x9097, 0x0c38, 0x00000000); + nv_mthd(dev, 0x9097, 0x0c48, 0x00000000); + nv_mthd(dev, 0x9097, 0x0c58, 0x00000000); + nv_mthd(dev, 0x9097, 0x0c68, 0x00000000); + nv_mthd(dev, 0x9097, 0x0c78, 0x00000000); + nv_mthd(dev, 0x9097, 0x0c88, 0x00000000); + nv_mthd(dev, 0x9097, 0x0c98, 0x00000000); + nv_mthd(dev, 0x9097, 0x0ca8, 0x00000000); + nv_mthd(dev, 0x9097, 0x0cb8, 0x00000000); + nv_mthd(dev, 0x9097, 0x0cc8, 0x00000000); + nv_mthd(dev, 0x9097, 0x0cd8, 0x00000000); + nv_mthd(dev, 0x9097, 0x0ce8, 0x00000000); + nv_mthd(dev, 0x9097, 0x0cf8, 0x00000000); + nv_mthd(dev, 0x9097, 0x0c0c, 0x3f800000); + nv_mthd(dev, 0x9097, 0x0c1c, 0x3f800000); + nv_mthd(dev, 0x9097, 0x0c2c, 0x3f800000); + nv_mthd(dev, 0x9097, 0x0c3c, 0x3f800000); + nv_mthd(dev, 0x9097, 0x0c4c, 0x3f800000); + nv_mthd(dev, 0x9097, 0x0c5c, 0x3f800000); + nv_mthd(dev, 0x9097, 0x0c6c, 0x3f800000); + nv_mthd(dev, 0x9097, 0x0c7c, 0x3f800000); + nv_mthd(dev, 0x9097, 0x0c8c, 0x3f800000); + nv_mthd(dev, 0x9097, 0x0c9c, 0x3f800000); + nv_mthd(dev, 0x9097, 0x0cac, 0x3f800000); + nv_mthd(dev, 0x9097, 0x0cbc, 0x3f800000); + nv_mthd(dev, 0x9097, 0x0ccc, 0x3f800000); + nv_mthd(dev, 0x9097, 0x0cdc, 0x3f800000); + nv_mthd(dev, 0x9097, 0x0cec, 0x3f800000); + nv_mthd(dev, 0x9097, 0x0cfc, 0x3f800000); + nv_mthd(dev, 0x9097, 0x0d00, 0xffff0000); + nv_mthd(dev, 0x9097, 0x0d08, 0xffff0000); + nv_mthd(dev, 0x9097, 0x0d10, 0xffff0000); + nv_mthd(dev, 0x9097, 0x0d18, 0xffff0000); + nv_mthd(dev, 0x9097, 0x0d20, 0xffff0000); + nv_mthd(dev, 0x9097, 0x0d28, 0xffff0000); + nv_mthd(dev, 0x9097, 0x0d30, 0xffff0000); + nv_mthd(dev, 0x9097, 0x0d38, 0xffff0000); + nv_mthd(dev, 0x9097, 0x0d04, 0xffff0000); + nv_mthd(dev, 0x9097, 0x0d0c, 0xffff0000); + nv_mthd(dev, 0x9097, 0x0d14, 0xffff0000); + nv_mthd(dev, 0x9097, 0x0d1c, 0xffff0000); + nv_mthd(dev, 0x9097, 0x0d24, 0xffff0000); + nv_mthd(dev, 0x9097, 0x0d2c, 0xffff0000); + nv_mthd(dev, 0x9097, 0x0d34, 0xffff0000); + nv_mthd(dev, 0x9097, 0x0d3c, 0xffff0000); + nv_mthd(dev, 0x9097, 0x0e00, 0x00000000); + nv_mthd(dev, 0x9097, 0x0e10, 0x00000000); + nv_mthd(dev, 0x9097, 0x0e20, 0x00000000); + nv_mthd(dev, 0x9097, 0x0e30, 0x00000000); + nv_mthd(dev, 0x9097, 0x0e40, 0x00000000); + nv_mthd(dev, 0x9097, 0x0e50, 0x00000000); + nv_mthd(dev, 0x9097, 0x0e60, 0x00000000); + nv_mthd(dev, 0x9097, 0x0e70, 0x00000000); + nv_mthd(dev, 0x9097, 0x0e80, 0x00000000); + nv_mthd(dev, 0x9097, 0x0e90, 0x00000000); + nv_mthd(dev, 0x9097, 0x0ea0, 0x00000000); + nv_mthd(dev, 0x9097, 0x0eb0, 0x00000000); + nv_mthd(dev, 0x9097, 0x0ec0, 0x00000000); + nv_mthd(dev, 0x9097, 0x0ed0, 0x00000000); + nv_mthd(dev, 0x9097, 0x0ee0, 0x00000000); + nv_mthd(dev, 0x9097, 0x0ef0, 0x00000000); + nv_mthd(dev, 0x9097, 0x0e04, 0xffff0000); + nv_mthd(dev, 0x9097, 0x0e14, 0xffff0000); + nv_mthd(dev, 0x9097, 0x0e24, 0xffff0000); + nv_mthd(dev, 0x9097, 0x0e34, 0xffff0000); + nv_mthd(dev, 0x9097, 0x0e44, 0xffff0000); + nv_mthd(dev, 0x9097, 0x0e54, 0xffff0000); + nv_mthd(dev, 0x9097, 0x0e64, 0xffff0000); + nv_mthd(dev, 0x9097, 0x0e74, 0xffff0000); + nv_mthd(dev, 0x9097, 0x0e84, 0xffff0000); + nv_mthd(dev, 0x9097, 0x0e94, 0xffff0000); + nv_mthd(dev, 0x9097, 0x0ea4, 0xffff0000); + nv_mthd(dev, 0x9097, 0x0eb4, 0xffff0000); + nv_mthd(dev, 0x9097, 0x0ec4, 0xffff0000); + nv_mthd(dev, 0x9097, 0x0ed4, 0xffff0000); + nv_mthd(dev, 0x9097, 0x0ee4, 0xffff0000); + nv_mthd(dev, 0x9097, 0x0ef4, 0xffff0000); + nv_mthd(dev, 0x9097, 0x0e08, 0xffff0000); + nv_mthd(dev, 0x9097, 0x0e18, 0xffff0000); + nv_mthd(dev, 0x9097, 0x0e28, 0xffff0000); + nv_mthd(dev, 0x9097, 0x0e38, 0xffff0000); + nv_mthd(dev, 0x9097, 0x0e48, 0xffff0000); + nv_mthd(dev, 0x9097, 0x0e58, 0xffff0000); + nv_mthd(dev, 0x9097, 0x0e68, 0xffff0000); + nv_mthd(dev, 0x9097, 0x0e78, 0xffff0000); + nv_mthd(dev, 0x9097, 0x0e88, 0xffff0000); + nv_mthd(dev, 0x9097, 0x0e98, 0xffff0000); + nv_mthd(dev, 0x9097, 0x0ea8, 0xffff0000); + nv_mthd(dev, 0x9097, 0x0eb8, 0xffff0000); + nv_mthd(dev, 0x9097, 0x0ec8, 0xffff0000); + nv_mthd(dev, 0x9097, 0x0ed8, 0xffff0000); + nv_mthd(dev, 0x9097, 0x0ee8, 0xffff0000); + nv_mthd(dev, 0x9097, 0x0ef8, 0xffff0000); + nv_mthd(dev, 0x9097, 0x0d40, 0x00000000); + nv_mthd(dev, 0x9097, 0x0d48, 0x00000000); + nv_mthd(dev, 0x9097, 0x0d50, 0x00000000); + nv_mthd(dev, 0x9097, 0x0d58, 0x00000000); + nv_mthd(dev, 0x9097, 0x0d44, 0x00000000); + nv_mthd(dev, 0x9097, 0x0d4c, 0x00000000); + nv_mthd(dev, 0x9097, 0x0d54, 0x00000000); + nv_mthd(dev, 0x9097, 0x0d5c, 0x00000000); + nv_mthd(dev, 0x9097, 0x1e00, 0x00000001); + nv_mthd(dev, 0x9097, 0x1e20, 0x00000001); + nv_mthd(dev, 0x9097, 0x1e40, 0x00000001); + nv_mthd(dev, 0x9097, 0x1e60, 0x00000001); + nv_mthd(dev, 0x9097, 0x1e80, 0x00000001); + nv_mthd(dev, 0x9097, 0x1ea0, 0x00000001); + nv_mthd(dev, 0x9097, 0x1ec0, 0x00000001); + nv_mthd(dev, 0x9097, 0x1ee0, 0x00000001); + nv_mthd(dev, 0x9097, 0x1e04, 0x00000001); + nv_mthd(dev, 0x9097, 0x1e24, 0x00000001); + nv_mthd(dev, 0x9097, 0x1e44, 0x00000001); + nv_mthd(dev, 0x9097, 0x1e64, 0x00000001); + nv_mthd(dev, 0x9097, 0x1e84, 0x00000001); + nv_mthd(dev, 0x9097, 0x1ea4, 0x00000001); + nv_mthd(dev, 0x9097, 0x1ec4, 0x00000001); + nv_mthd(dev, 0x9097, 0x1ee4, 0x00000001); + nv_mthd(dev, 0x9097, 0x1e08, 0x00000002); + nv_mthd(dev, 0x9097, 0x1e28, 0x00000002); + nv_mthd(dev, 0x9097, 0x1e48, 0x00000002); + nv_mthd(dev, 0x9097, 0x1e68, 0x00000002); + nv_mthd(dev, 0x9097, 0x1e88, 0x00000002); + nv_mthd(dev, 0x9097, 0x1ea8, 0x00000002); + nv_mthd(dev, 0x9097, 0x1ec8, 0x00000002); + nv_mthd(dev, 0x9097, 0x1ee8, 0x00000002); + nv_mthd(dev, 0x9097, 0x1e0c, 0x00000001); + nv_mthd(dev, 0x9097, 0x1e2c, 0x00000001); + nv_mthd(dev, 0x9097, 0x1e4c, 0x00000001); + nv_mthd(dev, 0x9097, 0x1e6c, 0x00000001); + nv_mthd(dev, 0x9097, 0x1e8c, 0x00000001); + nv_mthd(dev, 0x9097, 0x1eac, 0x00000001); + nv_mthd(dev, 0x9097, 0x1ecc, 0x00000001); + nv_mthd(dev, 0x9097, 0x1eec, 0x00000001); + nv_mthd(dev, 0x9097, 0x1e10, 0x00000001); + nv_mthd(dev, 0x9097, 0x1e30, 0x00000001); + nv_mthd(dev, 0x9097, 0x1e50, 0x00000001); + nv_mthd(dev, 0x9097, 0x1e70, 0x00000001); + nv_mthd(dev, 0x9097, 0x1e90, 0x00000001); + nv_mthd(dev, 0x9097, 0x1eb0, 0x00000001); + nv_mthd(dev, 0x9097, 0x1ed0, 0x00000001); + nv_mthd(dev, 0x9097, 0x1ef0, 0x00000001); + nv_mthd(dev, 0x9097, 0x1e14, 0x00000002); + nv_mthd(dev, 0x9097, 0x1e34, 0x00000002); + nv_mthd(dev, 0x9097, 0x1e54, 0x00000002); + nv_mthd(dev, 0x9097, 0x1e74, 0x00000002); + nv_mthd(dev, 0x9097, 0x1e94, 0x00000002); + nv_mthd(dev, 0x9097, 0x1eb4, 0x00000002); + nv_mthd(dev, 0x9097, 0x1ed4, 0x00000002); + nv_mthd(dev, 0x9097, 0x1ef4, 0x00000002); + nv_mthd(dev, 0x9097, 0x1e18, 0x00000001); + nv_mthd(dev, 0x9097, 0x1e38, 0x00000001); + nv_mthd(dev, 0x9097, 0x1e58, 0x00000001); + nv_mthd(dev, 0x9097, 0x1e78, 0x00000001); + nv_mthd(dev, 0x9097, 0x1e98, 0x00000001); + nv_mthd(dev, 0x9097, 0x1eb8, 0x00000001); + nv_mthd(dev, 0x9097, 0x1ed8, 0x00000001); + nv_mthd(dev, 0x9097, 0x1ef8, 0x00000001); + nv_mthd(dev, 0x9097, 0x3400, 0x00000000); + nv_mthd(dev, 0x9097, 0x3404, 0x00000000); + nv_mthd(dev, 0x9097, 0x3408, 0x00000000); + nv_mthd(dev, 0x9097, 0x340c, 0x00000000); + nv_mthd(dev, 0x9097, 0x3410, 0x00000000); + nv_mthd(dev, 0x9097, 0x3414, 0x00000000); + nv_mthd(dev, 0x9097, 0x3418, 0x00000000); + nv_mthd(dev, 0x9097, 0x341c, 0x00000000); + nv_mthd(dev, 0x9097, 0x3420, 0x00000000); + nv_mthd(dev, 0x9097, 0x3424, 0x00000000); + nv_mthd(dev, 0x9097, 0x3428, 0x00000000); + nv_mthd(dev, 0x9097, 0x342c, 0x00000000); + nv_mthd(dev, 0x9097, 0x3430, 0x00000000); + nv_mthd(dev, 0x9097, 0x3434, 0x00000000); + nv_mthd(dev, 0x9097, 0x3438, 0x00000000); + nv_mthd(dev, 0x9097, 0x343c, 0x00000000); + nv_mthd(dev, 0x9097, 0x3440, 0x00000000); + nv_mthd(dev, 0x9097, 0x3444, 0x00000000); + nv_mthd(dev, 0x9097, 0x3448, 0x00000000); + nv_mthd(dev, 0x9097, 0x344c, 0x00000000); + nv_mthd(dev, 0x9097, 0x3450, 0x00000000); + nv_mthd(dev, 0x9097, 0x3454, 0x00000000); + nv_mthd(dev, 0x9097, 0x3458, 0x00000000); + nv_mthd(dev, 0x9097, 0x345c, 0x00000000); + nv_mthd(dev, 0x9097, 0x3460, 0x00000000); + nv_mthd(dev, 0x9097, 0x3464, 0x00000000); + nv_mthd(dev, 0x9097, 0x3468, 0x00000000); + nv_mthd(dev, 0x9097, 0x346c, 0x00000000); + nv_mthd(dev, 0x9097, 0x3470, 0x00000000); + nv_mthd(dev, 0x9097, 0x3474, 0x00000000); + nv_mthd(dev, 0x9097, 0x3478, 0x00000000); + nv_mthd(dev, 0x9097, 0x347c, 0x00000000); + nv_mthd(dev, 0x9097, 0x3480, 0x00000000); + nv_mthd(dev, 0x9097, 0x3484, 0x00000000); + nv_mthd(dev, 0x9097, 0x3488, 0x00000000); + nv_mthd(dev, 0x9097, 0x348c, 0x00000000); + nv_mthd(dev, 0x9097, 0x3490, 0x00000000); + nv_mthd(dev, 0x9097, 0x3494, 0x00000000); + nv_mthd(dev, 0x9097, 0x3498, 0x00000000); + nv_mthd(dev, 0x9097, 0x349c, 0x00000000); + nv_mthd(dev, 0x9097, 0x34a0, 0x00000000); + nv_mthd(dev, 0x9097, 0x34a4, 0x00000000); + nv_mthd(dev, 0x9097, 0x34a8, 0x00000000); + nv_mthd(dev, 0x9097, 0x34ac, 0x00000000); + nv_mthd(dev, 0x9097, 0x34b0, 0x00000000); + nv_mthd(dev, 0x9097, 0x34b4, 0x00000000); + nv_mthd(dev, 0x9097, 0x34b8, 0x00000000); + nv_mthd(dev, 0x9097, 0x34bc, 0x00000000); + nv_mthd(dev, 0x9097, 0x34c0, 0x00000000); + nv_mthd(dev, 0x9097, 0x34c4, 0x00000000); + nv_mthd(dev, 0x9097, 0x34c8, 0x00000000); + nv_mthd(dev, 0x9097, 0x34cc, 0x00000000); + nv_mthd(dev, 0x9097, 0x34d0, 0x00000000); + nv_mthd(dev, 0x9097, 0x34d4, 0x00000000); + nv_mthd(dev, 0x9097, 0x34d8, 0x00000000); + nv_mthd(dev, 0x9097, 0x34dc, 0x00000000); + nv_mthd(dev, 0x9097, 0x34e0, 0x00000000); + nv_mthd(dev, 0x9097, 0x34e4, 0x00000000); + nv_mthd(dev, 0x9097, 0x34e8, 0x00000000); + nv_mthd(dev, 0x9097, 0x34ec, 0x00000000); + nv_mthd(dev, 0x9097, 0x34f0, 0x00000000); + nv_mthd(dev, 0x9097, 0x34f4, 0x00000000); + nv_mthd(dev, 0x9097, 0x34f8, 0x00000000); + nv_mthd(dev, 0x9097, 0x34fc, 0x00000000); + nv_mthd(dev, 0x9097, 0x3500, 0x00000000); + nv_mthd(dev, 0x9097, 0x3504, 0x00000000); + nv_mthd(dev, 0x9097, 0x3508, 0x00000000); + nv_mthd(dev, 0x9097, 0x350c, 0x00000000); + nv_mthd(dev, 0x9097, 0x3510, 0x00000000); + nv_mthd(dev, 0x9097, 0x3514, 0x00000000); + nv_mthd(dev, 0x9097, 0x3518, 0x00000000); + nv_mthd(dev, 0x9097, 0x351c, 0x00000000); + nv_mthd(dev, 0x9097, 0x3520, 0x00000000); + nv_mthd(dev, 0x9097, 0x3524, 0x00000000); + nv_mthd(dev, 0x9097, 0x3528, 0x00000000); + nv_mthd(dev, 0x9097, 0x352c, 0x00000000); + nv_mthd(dev, 0x9097, 0x3530, 0x00000000); + nv_mthd(dev, 0x9097, 0x3534, 0x00000000); + nv_mthd(dev, 0x9097, 0x3538, 0x00000000); + nv_mthd(dev, 0x9097, 0x353c, 0x00000000); + nv_mthd(dev, 0x9097, 0x3540, 0x00000000); + nv_mthd(dev, 0x9097, 0x3544, 0x00000000); + nv_mthd(dev, 0x9097, 0x3548, 0x00000000); + nv_mthd(dev, 0x9097, 0x354c, 0x00000000); + nv_mthd(dev, 0x9097, 0x3550, 0x00000000); + nv_mthd(dev, 0x9097, 0x3554, 0x00000000); + nv_mthd(dev, 0x9097, 0x3558, 0x00000000); + nv_mthd(dev, 0x9097, 0x355c, 0x00000000); + nv_mthd(dev, 0x9097, 0x3560, 0x00000000); + nv_mthd(dev, 0x9097, 0x3564, 0x00000000); + nv_mthd(dev, 0x9097, 0x3568, 0x00000000); + nv_mthd(dev, 0x9097, 0x356c, 0x00000000); + nv_mthd(dev, 0x9097, 0x3570, 0x00000000); + nv_mthd(dev, 0x9097, 0x3574, 0x00000000); + nv_mthd(dev, 0x9097, 0x3578, 0x00000000); + nv_mthd(dev, 0x9097, 0x357c, 0x00000000); + nv_mthd(dev, 0x9097, 0x3580, 0x00000000); + nv_mthd(dev, 0x9097, 0x3584, 0x00000000); + nv_mthd(dev, 0x9097, 0x3588, 0x00000000); + nv_mthd(dev, 0x9097, 0x358c, 0x00000000); + nv_mthd(dev, 0x9097, 0x3590, 0x00000000); + nv_mthd(dev, 0x9097, 0x3594, 0x00000000); + nv_mthd(dev, 0x9097, 0x3598, 0x00000000); + nv_mthd(dev, 0x9097, 0x359c, 0x00000000); + nv_mthd(dev, 0x9097, 0x35a0, 0x00000000); + nv_mthd(dev, 0x9097, 0x35a4, 0x00000000); + nv_mthd(dev, 0x9097, 0x35a8, 0x00000000); + nv_mthd(dev, 0x9097, 0x35ac, 0x00000000); + nv_mthd(dev, 0x9097, 0x35b0, 0x00000000); + nv_mthd(dev, 0x9097, 0x35b4, 0x00000000); + nv_mthd(dev, 0x9097, 0x35b8, 0x00000000); + nv_mthd(dev, 0x9097, 0x35bc, 0x00000000); + nv_mthd(dev, 0x9097, 0x35c0, 0x00000000); + nv_mthd(dev, 0x9097, 0x35c4, 0x00000000); + nv_mthd(dev, 0x9097, 0x35c8, 0x00000000); + nv_mthd(dev, 0x9097, 0x35cc, 0x00000000); + nv_mthd(dev, 0x9097, 0x35d0, 0x00000000); + nv_mthd(dev, 0x9097, 0x35d4, 0x00000000); + nv_mthd(dev, 0x9097, 0x35d8, 0x00000000); + nv_mthd(dev, 0x9097, 0x35dc, 0x00000000); + nv_mthd(dev, 0x9097, 0x35e0, 0x00000000); + nv_mthd(dev, 0x9097, 0x35e4, 0x00000000); + nv_mthd(dev, 0x9097, 0x35e8, 0x00000000); + nv_mthd(dev, 0x9097, 0x35ec, 0x00000000); + nv_mthd(dev, 0x9097, 0x35f0, 0x00000000); + nv_mthd(dev, 0x9097, 0x35f4, 0x00000000); + nv_mthd(dev, 0x9097, 0x35f8, 0x00000000); + nv_mthd(dev, 0x9097, 0x35fc, 0x00000000); + nv_mthd(dev, 0x9097, 0x030c, 0x00000001); + nv_mthd(dev, 0x9097, 0x1944, 0x00000000); + nv_mthd(dev, 0x9097, 0x1514, 0x00000000); + nv_mthd(dev, 0x9097, 0x0d68, 0x0000ffff); + nv_mthd(dev, 0x9097, 0x121c, 0x0fac6881); + nv_mthd(dev, 0x9097, 0x0fac, 0x00000001); + nv_mthd(dev, 0x9097, 0x1538, 0x00000001); + nv_mthd(dev, 0x9097, 0x0fe0, 0x00000000); + nv_mthd(dev, 0x9097, 0x0fe4, 0x00000000); + nv_mthd(dev, 0x9097, 0x0fe8, 0x00000014); + nv_mthd(dev, 0x9097, 0x0fec, 0x00000040); + nv_mthd(dev, 0x9097, 0x0ff0, 0x00000000); + nv_mthd(dev, 0x9097, 0x179c, 0x00000000); + nv_mthd(dev, 0x9097, 0x1228, 0x00000400); + nv_mthd(dev, 0x9097, 0x122c, 0x00000300); + nv_mthd(dev, 0x9097, 0x1230, 0x00010001); + nv_mthd(dev, 0x9097, 0x07f8, 0x00000000); + nv_mthd(dev, 0x9097, 0x15b4, 0x00000001); + nv_mthd(dev, 0x9097, 0x15cc, 0x00000000); + nv_mthd(dev, 0x9097, 0x1534, 0x00000000); + nv_mthd(dev, 0x9097, 0x0fb0, 0x00000000); + nv_mthd(dev, 0x9097, 0x15d0, 0x00000000); + nv_mthd(dev, 0x9097, 0x153c, 0x00000000); + nv_mthd(dev, 0x9097, 0x16b4, 0x00000003); + nv_mthd(dev, 0x9097, 0x0fbc, 0x0000ffff); + nv_mthd(dev, 0x9097, 0x0fc0, 0x0000ffff); + nv_mthd(dev, 0x9097, 0x0fc4, 0x0000ffff); + nv_mthd(dev, 0x9097, 0x0fc8, 0x0000ffff); + nv_mthd(dev, 0x9097, 0x0df8, 0x00000000); + nv_mthd(dev, 0x9097, 0x0dfc, 0x00000000); + nv_mthd(dev, 0x9097, 0x1948, 0x00000000); + nv_mthd(dev, 0x9097, 0x1970, 0x00000001); + nv_mthd(dev, 0x9097, 0x161c, 0x000009f0); + nv_mthd(dev, 0x9097, 0x0dcc, 0x00000010); + nv_mthd(dev, 0x9097, 0x163c, 0x00000000); + nv_mthd(dev, 0x9097, 0x15e4, 0x00000000); + nv_mthd(dev, 0x9097, 0x1160, 0x25e00040); + nv_mthd(dev, 0x9097, 0x1164, 0x25e00040); + nv_mthd(dev, 0x9097, 0x1168, 0x25e00040); + nv_mthd(dev, 0x9097, 0x116c, 0x25e00040); + nv_mthd(dev, 0x9097, 0x1170, 0x25e00040); + nv_mthd(dev, 0x9097, 0x1174, 0x25e00040); + nv_mthd(dev, 0x9097, 0x1178, 0x25e00040); + nv_mthd(dev, 0x9097, 0x117c, 0x25e00040); + nv_mthd(dev, 0x9097, 0x1180, 0x25e00040); + nv_mthd(dev, 0x9097, 0x1184, 0x25e00040); + nv_mthd(dev, 0x9097, 0x1188, 0x25e00040); + nv_mthd(dev, 0x9097, 0x118c, 0x25e00040); + nv_mthd(dev, 0x9097, 0x1190, 0x25e00040); + nv_mthd(dev, 0x9097, 0x1194, 0x25e00040); + nv_mthd(dev, 0x9097, 0x1198, 0x25e00040); + nv_mthd(dev, 0x9097, 0x119c, 0x25e00040); + nv_mthd(dev, 0x9097, 0x11a0, 0x25e00040); + nv_mthd(dev, 0x9097, 0x11a4, 0x25e00040); + nv_mthd(dev, 0x9097, 0x11a8, 0x25e00040); + nv_mthd(dev, 0x9097, 0x11ac, 0x25e00040); + nv_mthd(dev, 0x9097, 0x11b0, 0x25e00040); + nv_mthd(dev, 0x9097, 0x11b4, 0x25e00040); + nv_mthd(dev, 0x9097, 0x11b8, 0x25e00040); + nv_mthd(dev, 0x9097, 0x11bc, 0x25e00040); + nv_mthd(dev, 0x9097, 0x11c0, 0x25e00040); + nv_mthd(dev, 0x9097, 0x11c4, 0x25e00040); + nv_mthd(dev, 0x9097, 0x11c8, 0x25e00040); + nv_mthd(dev, 0x9097, 0x11cc, 0x25e00040); + nv_mthd(dev, 0x9097, 0x11d0, 0x25e00040); + nv_mthd(dev, 0x9097, 0x11d4, 0x25e00040); + nv_mthd(dev, 0x9097, 0x11d8, 0x25e00040); + nv_mthd(dev, 0x9097, 0x11dc, 0x25e00040); + nv_mthd(dev, 0x9097, 0x1880, 0x00000000); + nv_mthd(dev, 0x9097, 0x1884, 0x00000000); + nv_mthd(dev, 0x9097, 0x1888, 0x00000000); + nv_mthd(dev, 0x9097, 0x188c, 0x00000000); + nv_mthd(dev, 0x9097, 0x1890, 0x00000000); + nv_mthd(dev, 0x9097, 0x1894, 0x00000000); + nv_mthd(dev, 0x9097, 0x1898, 0x00000000); + nv_mthd(dev, 0x9097, 0x189c, 0x00000000); + nv_mthd(dev, 0x9097, 0x18a0, 0x00000000); + nv_mthd(dev, 0x9097, 0x18a4, 0x00000000); + nv_mthd(dev, 0x9097, 0x18a8, 0x00000000); + nv_mthd(dev, 0x9097, 0x18ac, 0x00000000); + nv_mthd(dev, 0x9097, 0x18b0, 0x00000000); + nv_mthd(dev, 0x9097, 0x18b4, 0x00000000); + nv_mthd(dev, 0x9097, 0x18b8, 0x00000000); + nv_mthd(dev, 0x9097, 0x18bc, 0x00000000); + nv_mthd(dev, 0x9097, 0x18c0, 0x00000000); + nv_mthd(dev, 0x9097, 0x18c4, 0x00000000); + nv_mthd(dev, 0x9097, 0x18c8, 0x00000000); + nv_mthd(dev, 0x9097, 0x18cc, 0x00000000); + nv_mthd(dev, 0x9097, 0x18d0, 0x00000000); + nv_mthd(dev, 0x9097, 0x18d4, 0x00000000); + nv_mthd(dev, 0x9097, 0x18d8, 0x00000000); + nv_mthd(dev, 0x9097, 0x18dc, 0x00000000); + nv_mthd(dev, 0x9097, 0x18e0, 0x00000000); + nv_mthd(dev, 0x9097, 0x18e4, 0x00000000); + nv_mthd(dev, 0x9097, 0x18e8, 0x00000000); + nv_mthd(dev, 0x9097, 0x18ec, 0x00000000); + nv_mthd(dev, 0x9097, 0x18f0, 0x00000000); + nv_mthd(dev, 0x9097, 0x18f4, 0x00000000); + nv_mthd(dev, 0x9097, 0x18f8, 0x00000000); + nv_mthd(dev, 0x9097, 0x18fc, 0x00000000); + nv_mthd(dev, 0x9097, 0x0f84, 0x00000000); + nv_mthd(dev, 0x9097, 0x0f88, 0x00000000); + nv_mthd(dev, 0x9097, 0x17c8, 0x00000000); + nv_mthd(dev, 0x9097, 0x17cc, 0x00000000); + nv_mthd(dev, 0x9097, 0x17d0, 0x000000ff); + nv_mthd(dev, 0x9097, 0x17d4, 0xffffffff); + nv_mthd(dev, 0x9097, 0x17d8, 0x00000002); + nv_mthd(dev, 0x9097, 0x17dc, 0x00000000); + nv_mthd(dev, 0x9097, 0x15f4, 0x00000000); + nv_mthd(dev, 0x9097, 0x15f8, 0x00000000); + nv_mthd(dev, 0x9097, 0x1434, 0x00000000); + nv_mthd(dev, 0x9097, 0x1438, 0x00000000); + nv_mthd(dev, 0x9097, 0x0d74, 0x00000000); + nv_mthd(dev, 0x9097, 0x0dec, 0x00000001); + nv_mthd(dev, 0x9097, 0x13a4, 0x00000000); + nv_mthd(dev, 0x9097, 0x1318, 0x00000001); + nv_mthd(dev, 0x9097, 0x1644, 0x00000000); + nv_mthd(dev, 0x9097, 0x0748, 0x00000000); + nv_mthd(dev, 0x9097, 0x0de8, 0x00000000); + nv_mthd(dev, 0x9097, 0x1648, 0x00000000); + nv_mthd(dev, 0x9097, 0x12a4, 0x00000000); + nv_mthd(dev, 0x9097, 0x1120, 0x00000000); + nv_mthd(dev, 0x9097, 0x1124, 0x00000000); + nv_mthd(dev, 0x9097, 0x1128, 0x00000000); + nv_mthd(dev, 0x9097, 0x112c, 0x00000000); + nv_mthd(dev, 0x9097, 0x1118, 0x00000000); + nv_mthd(dev, 0x9097, 0x164c, 0x00000000); + nv_mthd(dev, 0x9097, 0x1658, 0x00000000); + nv_mthd(dev, 0x9097, 0x1910, 0x00000290); + nv_mthd(dev, 0x9097, 0x1518, 0x00000000); + nv_mthd(dev, 0x9097, 0x165c, 0x00000001); + nv_mthd(dev, 0x9097, 0x1520, 0x00000000); + nv_mthd(dev, 0x9097, 0x1604, 0x00000000); + nv_mthd(dev, 0x9097, 0x1570, 0x00000000); + nv_mthd(dev, 0x9097, 0x13b0, 0x3f800000); + nv_mthd(dev, 0x9097, 0x13b4, 0x3f800000); + nv_mthd(dev, 0x9097, 0x020c, 0x00000000); + nv_mthd(dev, 0x9097, 0x1670, 0x30201000); + nv_mthd(dev, 0x9097, 0x1674, 0x70605040); + nv_mthd(dev, 0x9097, 0x1678, 0xb8a89888); + nv_mthd(dev, 0x9097, 0x167c, 0xf8e8d8c8); + nv_mthd(dev, 0x9097, 0x166c, 0x00000000); + nv_mthd(dev, 0x9097, 0x1680, 0x00ffff00); + nv_mthd(dev, 0x9097, 0x12d0, 0x00000003); + nv_mthd(dev, 0x9097, 0x12d4, 0x00000002); + nv_mthd(dev, 0x9097, 0x1684, 0x00000000); + nv_mthd(dev, 0x9097, 0x1688, 0x00000000); + nv_mthd(dev, 0x9097, 0x0dac, 0x00001b02); + nv_mthd(dev, 0x9097, 0x0db0, 0x00001b02); + nv_mthd(dev, 0x9097, 0x0db4, 0x00000000); + nv_mthd(dev, 0x9097, 0x168c, 0x00000000); + nv_mthd(dev, 0x9097, 0x15bc, 0x00000000); + nv_mthd(dev, 0x9097, 0x156c, 0x00000000); + nv_mthd(dev, 0x9097, 0x187c, 0x00000000); + nv_mthd(dev, 0x9097, 0x1110, 0x00000001); + nv_mthd(dev, 0x9097, 0x0dc0, 0x00000000); + nv_mthd(dev, 0x9097, 0x0dc4, 0x00000000); + nv_mthd(dev, 0x9097, 0x0dc8, 0x00000000); + nv_mthd(dev, 0x9097, 0x1234, 0x00000000); + nv_mthd(dev, 0x9097, 0x1690, 0x00000000); + nv_mthd(dev, 0x9097, 0x12ac, 0x00000001); + nv_mthd(dev, 0x9097, 0x02c4, 0x00000000); + nv_mthd(dev, 0x9097, 0x0790, 0x00000000); + nv_mthd(dev, 0x9097, 0x0794, 0x00000000); + nv_mthd(dev, 0x9097, 0x0798, 0x00000000); + nv_mthd(dev, 0x9097, 0x079c, 0x00000000); + nv_mthd(dev, 0x9097, 0x07a0, 0x00000000); + nv_mthd(dev, 0x9097, 0x077c, 0x00000000); + nv_mthd(dev, 0x9097, 0x1000, 0x00000010); + nv_mthd(dev, 0x9097, 0x10fc, 0x00000000); + nv_mthd(dev, 0x9097, 0x1290, 0x00000000); + nv_mthd(dev, 0x9097, 0x0218, 0x00000010); + nv_mthd(dev, 0x9097, 0x12d8, 0x00000000); + nv_mthd(dev, 0x9097, 0x12dc, 0x00000010); + nv_mthd(dev, 0x9097, 0x0d94, 0x00000001); + nv_mthd(dev, 0x9097, 0x155c, 0x00000000); + nv_mthd(dev, 0x9097, 0x1560, 0x00000000); + nv_mthd(dev, 0x9097, 0x1564, 0x00001fff); + nv_mthd(dev, 0x9097, 0x1574, 0x00000000); + nv_mthd(dev, 0x9097, 0x1578, 0x00000000); + nv_mthd(dev, 0x9097, 0x157c, 0x003fffff); + nv_mthd(dev, 0x9097, 0x1354, 0x00000000); + nv_mthd(dev, 0x9097, 0x1664, 0x00000000); + nv_mthd(dev, 0x9097, 0x1610, 0x00000012); + nv_mthd(dev, 0x9097, 0x1608, 0x00000000); + nv_mthd(dev, 0x9097, 0x160c, 0x00000000); + nv_mthd(dev, 0x9097, 0x162c, 0x00000003); + nv_mthd(dev, 0x9097, 0x0210, 0x00000000); + nv_mthd(dev, 0x9097, 0x0320, 0x00000000); + nv_mthd(dev, 0x9097, 0x0324, 0x3f800000); + nv_mthd(dev, 0x9097, 0x0328, 0x3f800000); + nv_mthd(dev, 0x9097, 0x032c, 0x3f800000); + nv_mthd(dev, 0x9097, 0x0330, 0x3f800000); + nv_mthd(dev, 0x9097, 0x0334, 0x3f800000); + nv_mthd(dev, 0x9097, 0x0338, 0x3f800000); + nv_mthd(dev, 0x9097, 0x0750, 0x00000000); + nv_mthd(dev, 0x9097, 0x0760, 0x39291909); + nv_mthd(dev, 0x9097, 0x0764, 0x79695949); + nv_mthd(dev, 0x9097, 0x0768, 0xb9a99989); + nv_mthd(dev, 0x9097, 0x076c, 0xf9e9d9c9); + nv_mthd(dev, 0x9097, 0x0770, 0x30201000); + nv_mthd(dev, 0x9097, 0x0774, 0x70605040); + nv_mthd(dev, 0x9097, 0x0778, 0x00009080); + nv_mthd(dev, 0x9097, 0x0780, 0x39291909); + nv_mthd(dev, 0x9097, 0x0784, 0x79695949); + nv_mthd(dev, 0x9097, 0x0788, 0xb9a99989); + nv_mthd(dev, 0x9097, 0x078c, 0xf9e9d9c9); + nv_mthd(dev, 0x9097, 0x07d0, 0x30201000); + nv_mthd(dev, 0x9097, 0x07d4, 0x70605040); + nv_mthd(dev, 0x9097, 0x07d8, 0x00009080); + nv_mthd(dev, 0x9097, 0x037c, 0x00000001); + nv_mthd(dev, 0x9097, 0x0740, 0x00000000); + nv_mthd(dev, 0x9097, 0x0744, 0x00000000); + nv_mthd(dev, 0x9097, 0x2600, 0x00000000); + nv_mthd(dev, 0x9097, 0x1918, 0x00000000); + nv_mthd(dev, 0x9097, 0x191c, 0x00000900); + nv_mthd(dev, 0x9097, 0x1920, 0x00000405); + nv_mthd(dev, 0x9097, 0x1308, 0x00000001); + nv_mthd(dev, 0x9097, 0x1924, 0x00000000); + nv_mthd(dev, 0x9097, 0x13ac, 0x00000000); + nv_mthd(dev, 0x9097, 0x192c, 0x00000001); + nv_mthd(dev, 0x9097, 0x193c, 0x00002c1c); + nv_mthd(dev, 0x9097, 0x0d7c, 0x00000000); + nv_mthd(dev, 0x9097, 0x0f8c, 0x00000000); + nv_mthd(dev, 0x9097, 0x02c0, 0x00000001); + nv_mthd(dev, 0x9097, 0x1510, 0x00000000); + nv_mthd(dev, 0x9097, 0x1940, 0x00000000); + nv_mthd(dev, 0x9097, 0x0ff4, 0x00000000); + nv_mthd(dev, 0x9097, 0x0ff8, 0x00000000); + nv_mthd(dev, 0x9097, 0x194c, 0x00000000); + nv_mthd(dev, 0x9097, 0x1950, 0x00000000); + nv_mthd(dev, 0x9097, 0x1968, 0x00000000); + nv_mthd(dev, 0x9097, 0x1590, 0x0000003f); + nv_mthd(dev, 0x9097, 0x07e8, 0x00000000); + nv_mthd(dev, 0x9097, 0x07ec, 0x00000000); + nv_mthd(dev, 0x9097, 0x07f0, 0x00000000); + nv_mthd(dev, 0x9097, 0x07f4, 0x00000000); + nv_mthd(dev, 0x9097, 0x196c, 0x00000011); + nv_mthd(dev, 0x9097, 0x197c, 0x00000000); + nv_mthd(dev, 0x9097, 0x0fcc, 0x00000000); + nv_mthd(dev, 0x9097, 0x0fd0, 0x00000000); + nv_mthd(dev, 0x9097, 0x02d8, 0x00000040); + nv_mthd(dev, 0x9097, 0x1980, 0x00000080); + nv_mthd(dev, 0x9097, 0x1504, 0x00000080); + nv_mthd(dev, 0x9097, 0x1984, 0x00000000); + nv_mthd(dev, 0x9097, 0x0300, 0x00000001); + nv_mthd(dev, 0x9097, 0x13a8, 0x00000000); + nv_mthd(dev, 0x9097, 0x12ec, 0x00000000); + nv_mthd(dev, 0x9097, 0x1310, 0x00000000); + nv_mthd(dev, 0x9097, 0x1314, 0x00000001); + nv_mthd(dev, 0x9097, 0x1380, 0x00000000); + nv_mthd(dev, 0x9097, 0x1384, 0x00000001); + nv_mthd(dev, 0x9097, 0x1388, 0x00000001); + nv_mthd(dev, 0x9097, 0x138c, 0x00000001); + nv_mthd(dev, 0x9097, 0x1390, 0x00000001); + nv_mthd(dev, 0x9097, 0x1394, 0x00000000); + nv_mthd(dev, 0x9097, 0x139c, 0x00000000); + nv_mthd(dev, 0x9097, 0x1398, 0x00000000); + nv_mthd(dev, 0x9097, 0x1594, 0x00000000); + nv_mthd(dev, 0x9097, 0x1598, 0x00000001); + nv_mthd(dev, 0x9097, 0x159c, 0x00000001); + nv_mthd(dev, 0x9097, 0x15a0, 0x00000001); + nv_mthd(dev, 0x9097, 0x15a4, 0x00000001); + nv_mthd(dev, 0x9097, 0x0f54, 0x00000000); + nv_mthd(dev, 0x9097, 0x0f58, 0x00000000); + nv_mthd(dev, 0x9097, 0x0f5c, 0x00000000); + nv_mthd(dev, 0x9097, 0x19bc, 0x00000000); + nv_mthd(dev, 0x9097, 0x0f9c, 0x00000000); + nv_mthd(dev, 0x9097, 0x0fa0, 0x00000000); + nv_mthd(dev, 0x9097, 0x12cc, 0x00000000); + nv_mthd(dev, 0x9097, 0x12e8, 0x00000000); + nv_mthd(dev, 0x9097, 0x130c, 0x00000001); + nv_mthd(dev, 0x9097, 0x1360, 0x00000000); + nv_mthd(dev, 0x9097, 0x1364, 0x00000000); + nv_mthd(dev, 0x9097, 0x1368, 0x00000000); + nv_mthd(dev, 0x9097, 0x136c, 0x00000000); + nv_mthd(dev, 0x9097, 0x1370, 0x00000000); + nv_mthd(dev, 0x9097, 0x1374, 0x00000000); + nv_mthd(dev, 0x9097, 0x1378, 0x00000000); + nv_mthd(dev, 0x9097, 0x137c, 0x00000000); + nv_mthd(dev, 0x9097, 0x133c, 0x00000001); + nv_mthd(dev, 0x9097, 0x1340, 0x00000001); + nv_mthd(dev, 0x9097, 0x1344, 0x00000002); + nv_mthd(dev, 0x9097, 0x1348, 0x00000001); + nv_mthd(dev, 0x9097, 0x134c, 0x00000001); + nv_mthd(dev, 0x9097, 0x1350, 0x00000002); + nv_mthd(dev, 0x9097, 0x1358, 0x00000001); + nv_mthd(dev, 0x9097, 0x12e4, 0x00000000); + nv_mthd(dev, 0x9097, 0x131c, 0x00000000); + nv_mthd(dev, 0x9097, 0x1320, 0x00000000); + nv_mthd(dev, 0x9097, 0x1324, 0x00000000); + nv_mthd(dev, 0x9097, 0x1328, 0x00000000); + nv_mthd(dev, 0x9097, 0x19c0, 0x00000000); + nv_mthd(dev, 0x9097, 0x1140, 0x00000000); + nv_mthd(dev, 0x9097, 0x19c4, 0x00000000); + nv_mthd(dev, 0x9097, 0x19c8, 0x00001500); + nv_mthd(dev, 0x9097, 0x135c, 0x00000000); + nv_mthd(dev, 0x9097, 0x0f90, 0x00000000); + nv_mthd(dev, 0x9097, 0x19e0, 0x00000001); + nv_mthd(dev, 0x9097, 0x19e4, 0x00000001); + nv_mthd(dev, 0x9097, 0x19e8, 0x00000001); + nv_mthd(dev, 0x9097, 0x19ec, 0x00000001); + nv_mthd(dev, 0x9097, 0x19f0, 0x00000001); + nv_mthd(dev, 0x9097, 0x19f4, 0x00000001); + nv_mthd(dev, 0x9097, 0x19f8, 0x00000001); + nv_mthd(dev, 0x9097, 0x19fc, 0x00000001); + nv_mthd(dev, 0x9097, 0x19cc, 0x00000001); + nv_mthd(dev, 0x9097, 0x15b8, 0x00000000); + nv_mthd(dev, 0x9097, 0x1a00, 0x00001111); + nv_mthd(dev, 0x9097, 0x1a04, 0x00000000); + nv_mthd(dev, 0x9097, 0x1a08, 0x00000000); + nv_mthd(dev, 0x9097, 0x1a0c, 0x00000000); + nv_mthd(dev, 0x9097, 0x1a10, 0x00000000); + nv_mthd(dev, 0x9097, 0x1a14, 0x00000000); + nv_mthd(dev, 0x9097, 0x1a18, 0x00000000); + nv_mthd(dev, 0x9097, 0x1a1c, 0x00000000); + nv_mthd(dev, 0x9097, 0x0d6c, 0xffff0000); + nv_mthd(dev, 0x9097, 0x0d70, 0xffff0000); + nv_mthd(dev, 0x9097, 0x10f8, 0x00001010); + nv_mthd(dev, 0x9097, 0x0d80, 0x00000000); + nv_mthd(dev, 0x9097, 0x0d84, 0x00000000); + nv_mthd(dev, 0x9097, 0x0d88, 0x00000000); + nv_mthd(dev, 0x9097, 0x0d8c, 0x00000000); + nv_mthd(dev, 0x9097, 0x0d90, 0x00000000); + nv_mthd(dev, 0x9097, 0x0da0, 0x00000000); + nv_mthd(dev, 0x9097, 0x1508, 0x80000000); + nv_mthd(dev, 0x9097, 0x150c, 0x40000000); + nv_mthd(dev, 0x9097, 0x1668, 0x00000000); + nv_mthd(dev, 0x9097, 0x0318, 0x00000008); + nv_mthd(dev, 0x9097, 0x031c, 0x00000008); + nv_mthd(dev, 0x9097, 0x0d9c, 0x00000001); + nv_mthd(dev, 0x9097, 0x07dc, 0x00000000); + nv_mthd(dev, 0x9097, 0x074c, 0x00000055); + nv_mthd(dev, 0x9097, 0x1420, 0x00000003); + nv_mthd(dev, 0x9097, 0x17bc, 0x00000000); + nv_mthd(dev, 0x9097, 0x17c0, 0x00000000); + nv_mthd(dev, 0x9097, 0x17c4, 0x00000001); + nv_mthd(dev, 0x9097, 0x1008, 0x00000008); + nv_mthd(dev, 0x9097, 0x100c, 0x00000040); + nv_mthd(dev, 0x9097, 0x1010, 0x0000012c); + nv_mthd(dev, 0x9097, 0x0d60, 0x00000040); + nv_mthd(dev, 0x9097, 0x075c, 0x00000003); + nv_mthd(dev, 0x9097, 0x1018, 0x00000020); + nv_mthd(dev, 0x9097, 0x101c, 0x00000001); + nv_mthd(dev, 0x9097, 0x1020, 0x00000020); + nv_mthd(dev, 0x9097, 0x1024, 0x00000001); + nv_mthd(dev, 0x9097, 0x1444, 0x00000000); + nv_mthd(dev, 0x9097, 0x1448, 0x00000000); + nv_mthd(dev, 0x9097, 0x144c, 0x00000000); + nv_mthd(dev, 0x9097, 0x0360, 0x20164010); + nv_mthd(dev, 0x9097, 0x0364, 0x00000020); + nv_mthd(dev, 0x9097, 0x0368, 0x00000000); + nv_mthd(dev, 0x9097, 0x0de4, 0x00000000); + nv_mthd(dev, 0x9097, 0x0204, 0x00000006); + nv_mthd(dev, 0x9097, 0x0208, 0x00000000); + nv_mthd(dev, 0x9097, 0x02cc, 0x003fffff); + nv_mthd(dev, 0x9097, 0x02d0, 0x00000c48); + nv_mthd(dev, 0x9097, 0x1220, 0x00000005); + nv_mthd(dev, 0x9097, 0x0fdc, 0x00000000); + nv_mthd(dev, 0x9097, 0x0f98, 0x00300008); + nv_mthd(dev, 0x9097, 0x1284, 0x04000080); + nv_mthd(dev, 0x9097, 0x1450, 0x00300008); + nv_mthd(dev, 0x9097, 0x1454, 0x04000080); + nv_mthd(dev, 0x9097, 0x0214, 0x00000000); + /* in trace, right after 0x90c0, not here */ + nv_mthd(dev, 0x9097, 0x3410, 0x80002006); +} + +static void +nvc0_grctx_generate_902d(struct drm_device *dev) +{ + nv_mthd(dev, 0x902d, 0x0200, 0x000000cf); + nv_mthd(dev, 0x902d, 0x0204, 0x00000001); + nv_mthd(dev, 0x902d, 0x0208, 0x00000020); + nv_mthd(dev, 0x902d, 0x020c, 0x00000001); + nv_mthd(dev, 0x902d, 0x0210, 0x00000000); + nv_mthd(dev, 0x902d, 0x0214, 0x00000080); + nv_mthd(dev, 0x902d, 0x0218, 0x00000100); + nv_mthd(dev, 0x902d, 0x021c, 0x00000100); + nv_mthd(dev, 0x902d, 0x0220, 0x00000000); + nv_mthd(dev, 0x902d, 0x0224, 0x00000000); + nv_mthd(dev, 0x902d, 0x0230, 0x000000cf); + nv_mthd(dev, 0x902d, 0x0234, 0x00000001); + nv_mthd(dev, 0x902d, 0x0238, 0x00000020); + nv_mthd(dev, 0x902d, 0x023c, 0x00000001); + nv_mthd(dev, 0x902d, 0x0244, 0x00000080); + nv_mthd(dev, 0x902d, 0x0248, 0x00000100); + nv_mthd(dev, 0x902d, 0x024c, 0x00000100); +} + +static void +nvc0_grctx_generate_9039(struct drm_device *dev) +{ + nv_mthd(dev, 0x9039, 0x030c, 0x00000000); + nv_mthd(dev, 0x9039, 0x0310, 0x00000000); + nv_mthd(dev, 0x9039, 0x0314, 0x00000000); + nv_mthd(dev, 0x9039, 0x0320, 0x00000000); + nv_mthd(dev, 0x9039, 0x0238, 0x00000000); + nv_mthd(dev, 0x9039, 0x023c, 0x00000000); + nv_mthd(dev, 0x9039, 0x0318, 0x00000000); + nv_mthd(dev, 0x9039, 0x031c, 0x00000000); +} + +static void +nvc0_grctx_generate_90c0(struct drm_device *dev) +{ + nv_mthd(dev, 0x90c0, 0x270c, 0x00000000); + nv_mthd(dev, 0x90c0, 0x272c, 0x00000000); + nv_mthd(dev, 0x90c0, 0x274c, 0x00000000); + nv_mthd(dev, 0x90c0, 0x276c, 0x00000000); + nv_mthd(dev, 0x90c0, 0x278c, 0x00000000); + nv_mthd(dev, 0x90c0, 0x27ac, 0x00000000); + nv_mthd(dev, 0x90c0, 0x27cc, 0x00000000); + nv_mthd(dev, 0x90c0, 0x27ec, 0x00000000); + nv_mthd(dev, 0x90c0, 0x030c, 0x00000001); + nv_mthd(dev, 0x90c0, 0x1944, 0x00000000); + nv_mthd(dev, 0x90c0, 0x0758, 0x00000100); + nv_mthd(dev, 0x90c0, 0x02c4, 0x00000000); + nv_mthd(dev, 0x90c0, 0x0790, 0x00000000); + nv_mthd(dev, 0x90c0, 0x0794, 0x00000000); + nv_mthd(dev, 0x90c0, 0x0798, 0x00000000); + nv_mthd(dev, 0x90c0, 0x079c, 0x00000000); + nv_mthd(dev, 0x90c0, 0x07a0, 0x00000000); + nv_mthd(dev, 0x90c0, 0x077c, 0x00000000); + nv_mthd(dev, 0x90c0, 0x0204, 0x00000000); + nv_mthd(dev, 0x90c0, 0x0208, 0x00000000); + nv_mthd(dev, 0x90c0, 0x020c, 0x00000000); + nv_mthd(dev, 0x90c0, 0x0214, 0x00000000); + nv_mthd(dev, 0x90c0, 0x024c, 0x00000000); + nv_mthd(dev, 0x90c0, 0x0d94, 0x00000001); + nv_mthd(dev, 0x90c0, 0x1608, 0x00000000); + nv_mthd(dev, 0x90c0, 0x160c, 0x00000000); + nv_mthd(dev, 0x90c0, 0x1664, 0x00000000); +} + +static void +nvc0_grctx_generate_dispatch(struct drm_device *dev) +{ + int i; + + nv_wr32(dev, 0x404004, 0x00000000); + nv_wr32(dev, 0x404008, 0x00000000); + nv_wr32(dev, 0x40400c, 0x00000000); + nv_wr32(dev, 0x404010, 0x00000000); + nv_wr32(dev, 0x404014, 0x00000000); + nv_wr32(dev, 0x404018, 0x00000000); + nv_wr32(dev, 0x40401c, 0x00000000); + nv_wr32(dev, 0x404020, 0x00000000); + nv_wr32(dev, 0x404024, 0x00000000); + nv_wr32(dev, 0x404028, 0x00000000); + nv_wr32(dev, 0x40402c, 0x00000000); + nv_wr32(dev, 0x404044, 0x00000000); + nv_wr32(dev, 0x404094, 0x00000000); + nv_wr32(dev, 0x404098, 0x00000000); + nv_wr32(dev, 0x40409c, 0x00000000); + nv_wr32(dev, 0x4040a0, 0x00000000); + nv_wr32(dev, 0x4040a4, 0x00000000); + nv_wr32(dev, 0x4040a8, 0x00000000); + nv_wr32(dev, 0x4040ac, 0x00000000); + nv_wr32(dev, 0x4040b0, 0x00000000); + nv_wr32(dev, 0x4040b4, 0x00000000); + nv_wr32(dev, 0x4040b8, 0x00000000); + nv_wr32(dev, 0x4040bc, 0x00000000); + nv_wr32(dev, 0x4040c0, 0x00000000); + nv_wr32(dev, 0x4040c4, 0x00000000); + nv_wr32(dev, 0x4040c8, 0xf0000087); + nv_wr32(dev, 0x4040d4, 0x00000000); + nv_wr32(dev, 0x4040d8, 0x00000000); + nv_wr32(dev, 0x4040dc, 0x00000000); + nv_wr32(dev, 0x4040e0, 0x00000000); + nv_wr32(dev, 0x4040e4, 0x00000000); + nv_wr32(dev, 0x4040e8, 0x00001000); + nv_wr32(dev, 0x4040f8, 0x00000000); + nv_wr32(dev, 0x404130, 0x00000000); + nv_wr32(dev, 0x404134, 0x00000000); + nv_wr32(dev, 0x404138, 0x20000040); + nv_wr32(dev, 0x404150, 0x0000002e); + nv_wr32(dev, 0x404154, 0x00000400); + nv_wr32(dev, 0x404158, 0x00000200); + nv_wr32(dev, 0x404164, 0x00000055); + nv_wr32(dev, 0x404168, 0x00000000); + nv_wr32(dev, 0x404174, 0x00000000); + nv_wr32(dev, 0x404178, 0x00000000); + nv_wr32(dev, 0x40417c, 0x00000000); + for (i = 0; i < 8; i++) + nv_wr32(dev, 0x404200 + (i * 4), 0x00000000); /* subc */ +} + +static void +nvc0_grctx_generate_macro(struct drm_device *dev) +{ + nv_wr32(dev, 0x404404, 0x00000000); + nv_wr32(dev, 0x404408, 0x00000000); + nv_wr32(dev, 0x40440c, 0x00000000); + nv_wr32(dev, 0x404410, 0x00000000); + nv_wr32(dev, 0x404414, 0x00000000); + nv_wr32(dev, 0x404418, 0x00000000); + nv_wr32(dev, 0x40441c, 0x00000000); + nv_wr32(dev, 0x404420, 0x00000000); + nv_wr32(dev, 0x404424, 0x00000000); + nv_wr32(dev, 0x404428, 0x00000000); + nv_wr32(dev, 0x40442c, 0x00000000); + nv_wr32(dev, 0x404430, 0x00000000); + nv_wr32(dev, 0x404434, 0x00000000); + nv_wr32(dev, 0x404438, 0x00000000); + nv_wr32(dev, 0x404460, 0x00000000); + nv_wr32(dev, 0x404464, 0x00000000); + nv_wr32(dev, 0x404468, 0x00ffffff); + nv_wr32(dev, 0x40446c, 0x00000000); + nv_wr32(dev, 0x404480, 0x00000001); + nv_wr32(dev, 0x404498, 0x00000001); +} + +static void +nvc0_grctx_generate_m2mf(struct drm_device *dev) +{ + nv_wr32(dev, 0x404604, 0x00000015); + nv_wr32(dev, 0x404608, 0x00000000); + nv_wr32(dev, 0x40460c, 0x00002e00); + nv_wr32(dev, 0x404610, 0x00000100); + nv_wr32(dev, 0x404618, 0x00000000); + nv_wr32(dev, 0x40461c, 0x00000000); + nv_wr32(dev, 0x404620, 0x00000000); + nv_wr32(dev, 0x404624, 0x00000000); + nv_wr32(dev, 0x404628, 0x00000000); + nv_wr32(dev, 0x40462c, 0x00000000); + nv_wr32(dev, 0x404630, 0x00000000); + nv_wr32(dev, 0x404634, 0x00000000); + nv_wr32(dev, 0x404638, 0x00000004); + nv_wr32(dev, 0x40463c, 0x00000000); + nv_wr32(dev, 0x404640, 0x00000000); + nv_wr32(dev, 0x404644, 0x00000000); + nv_wr32(dev, 0x404648, 0x00000000); + nv_wr32(dev, 0x40464c, 0x00000000); + nv_wr32(dev, 0x404650, 0x00000000); + nv_wr32(dev, 0x404654, 0x00000000); + nv_wr32(dev, 0x404658, 0x00000000); + nv_wr32(dev, 0x40465c, 0x007f0100); + nv_wr32(dev, 0x404660, 0x00000000); + nv_wr32(dev, 0x404664, 0x00000000); + nv_wr32(dev, 0x404668, 0x00000000); + nv_wr32(dev, 0x40466c, 0x00000000); + nv_wr32(dev, 0x404670, 0x00000000); + nv_wr32(dev, 0x404674, 0x00000000); + nv_wr32(dev, 0x404678, 0x00000000); + nv_wr32(dev, 0x40467c, 0x00000002); + nv_wr32(dev, 0x404680, 0x00000000); + nv_wr32(dev, 0x404684, 0x00000000); + nv_wr32(dev, 0x404688, 0x00000000); + nv_wr32(dev, 0x40468c, 0x00000000); + nv_wr32(dev, 0x404690, 0x00000000); + nv_wr32(dev, 0x404694, 0x00000000); + nv_wr32(dev, 0x404698, 0x00000000); + nv_wr32(dev, 0x40469c, 0x00000000); + nv_wr32(dev, 0x4046a0, 0x007f0080); + nv_wr32(dev, 0x4046a4, 0x00000000); + nv_wr32(dev, 0x4046a8, 0x00000000); + nv_wr32(dev, 0x4046ac, 0x00000000); + nv_wr32(dev, 0x4046b0, 0x00000000); + nv_wr32(dev, 0x4046b4, 0x00000000); + nv_wr32(dev, 0x4046b8, 0x00000000); + nv_wr32(dev, 0x4046bc, 0x00000000); + nv_wr32(dev, 0x4046c0, 0x00000000); + nv_wr32(dev, 0x4046c4, 0x00000000); + nv_wr32(dev, 0x4046c8, 0x00000000); + nv_wr32(dev, 0x4046cc, 0x00000000); + nv_wr32(dev, 0x4046d0, 0x00000000); + nv_wr32(dev, 0x4046d4, 0x00000000); + nv_wr32(dev, 0x4046d8, 0x00000000); + nv_wr32(dev, 0x4046dc, 0x00000000); + nv_wr32(dev, 0x4046e0, 0x00000000); + nv_wr32(dev, 0x4046e4, 0x00000000); + nv_wr32(dev, 0x4046e8, 0x00000000); + nv_wr32(dev, 0x4046f0, 0x00000000); + nv_wr32(dev, 0x4046f4, 0x00000000); +} + +static void +nvc0_grctx_generate_unk47xx(struct drm_device *dev) +{ + nv_wr32(dev, 0x404700, 0x00000000); + nv_wr32(dev, 0x404704, 0x00000000); + nv_wr32(dev, 0x404708, 0x00000000); + nv_wr32(dev, 0x40470c, 0x00000000); + nv_wr32(dev, 0x404710, 0x00000000); + nv_wr32(dev, 0x404714, 0x00000000); + nv_wr32(dev, 0x404718, 0x00000000); + nv_wr32(dev, 0x40471c, 0x00000000); + nv_wr32(dev, 0x404720, 0x00000000); + nv_wr32(dev, 0x404724, 0x00000000); + nv_wr32(dev, 0x404728, 0x00000000); + nv_wr32(dev, 0x40472c, 0x00000000); + nv_wr32(dev, 0x404730, 0x00000000); + nv_wr32(dev, 0x404734, 0x00000100); + nv_wr32(dev, 0x404738, 0x00000000); + nv_wr32(dev, 0x40473c, 0x00000000); + nv_wr32(dev, 0x404740, 0x00000000); + nv_wr32(dev, 0x404744, 0x00000000); + nv_wr32(dev, 0x404748, 0x00000000); + nv_wr32(dev, 0x40474c, 0x00000000); + nv_wr32(dev, 0x404750, 0x00000000); + nv_wr32(dev, 0x404754, 0x00000000); +} + +static void +nvc0_grctx_generate_unk58xx(struct drm_device *dev) +{ + nv_wr32(dev, 0x405800, 0x078000bf); + nv_wr32(dev, 0x405830, 0x02180000); + nv_wr32(dev, 0x405834, 0x00000000); + nv_wr32(dev, 0x405838, 0x00000000); + nv_wr32(dev, 0x405854, 0x00000000); + nv_wr32(dev, 0x405870, 0x00000001); + nv_wr32(dev, 0x405874, 0x00000001); + nv_wr32(dev, 0x405878, 0x00000001); + nv_wr32(dev, 0x40587c, 0x00000001); + nv_wr32(dev, 0x405a00, 0x00000000); + nv_wr32(dev, 0x405a04, 0x00000000); + nv_wr32(dev, 0x405a18, 0x00000000); +} + +static void +nvc0_grctx_generate_unk60xx(struct drm_device *dev) +{ + nv_wr32(dev, 0x406020, 0x000103c1); + nv_wr32(dev, 0x406028, 0x00000001); + nv_wr32(dev, 0x40602c, 0x00000001); + nv_wr32(dev, 0x406030, 0x00000001); + nv_wr32(dev, 0x406034, 0x00000001); +} + +static void +nvc0_grctx_generate_unk64xx(struct drm_device *dev) +{ + nv_wr32(dev, 0x4064a8, 0x00000000); + nv_wr32(dev, 0x4064ac, 0x00003fff); + nv_wr32(dev, 0x4064b4, 0x00000000); + nv_wr32(dev, 0x4064b8, 0x00000000); +} + +static void +nvc0_grctx_generate_unk78xx(struct drm_device *dev) +{ + nv_wr32(dev, 0x407804, 0x00000023); + nv_wr32(dev, 0x40780c, 0x0a418820); + nv_wr32(dev, 0x407810, 0x062080e6); + nv_wr32(dev, 0x407814, 0x020398a4); + nv_wr32(dev, 0x407818, 0x0e629062); + nv_wr32(dev, 0x40781c, 0x0a418820); + nv_wr32(dev, 0x407820, 0x000000e6); + nv_wr32(dev, 0x4078bc, 0x00000103); +} + +static void +nvc0_grctx_generate_unk80xx(struct drm_device *dev) +{ + nv_wr32(dev, 0x408000, 0x00000000); + nv_wr32(dev, 0x408004, 0x00000000); + nv_wr32(dev, 0x408008, 0x00000018); + nv_wr32(dev, 0x40800c, 0x00000000); + nv_wr32(dev, 0x408010, 0x00000000); + nv_wr32(dev, 0x408014, 0x00000069); + nv_wr32(dev, 0x408018, 0xe100e100); + nv_wr32(dev, 0x408064, 0x00000000); +} + +static void +nvc0_grctx_generate_rop(struct drm_device *dev) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + + // ROPC_BROADCAST + nv_wr32(dev, 0x408800, 0x02802a3c); + nv_wr32(dev, 0x408804, 0x00000040); + nv_wr32(dev, 0x408808, 0x0003e00d); + switch (dev_priv->chipset) { + case 0xc0: + nv_wr32(dev, 0x408900, 0x0080b801); + break; + case 0xc3: + case 0xc4: + nv_wr32(dev, 0x408900, 0x3080b801); + break; + } + nv_wr32(dev, 0x408904, 0x02000001); + nv_wr32(dev, 0x408908, 0x00c80929); + nv_wr32(dev, 0x40890c, 0x00000000); + nv_wr32(dev, 0x408980, 0x0000011d); +} + +static void +nvc0_grctx_generate_gpc(struct drm_device *dev) +{ + int i; + + // GPC_BROADCAST + nv_wr32(dev, 0x418380, 0x00000016); + nv_wr32(dev, 0x418400, 0x38004e00); + nv_wr32(dev, 0x418404, 0x71e0ffff); + nv_wr32(dev, 0x418408, 0x00000000); + nv_wr32(dev, 0x41840c, 0x00001008); + nv_wr32(dev, 0x418410, 0x0fff0fff); + nv_wr32(dev, 0x418414, 0x00200fff); + nv_wr32(dev, 0x418450, 0x00000000); + nv_wr32(dev, 0x418454, 0x00000000); + nv_wr32(dev, 0x418458, 0x00000000); + nv_wr32(dev, 0x41845c, 0x00000000); + nv_wr32(dev, 0x418460, 0x00000000); + nv_wr32(dev, 0x418464, 0x00000000); + nv_wr32(dev, 0x418468, 0x00000001); + nv_wr32(dev, 0x41846c, 0x00000000); + nv_wr32(dev, 0x418470, 0x00000000); + nv_wr32(dev, 0x418600, 0x0000001f); + nv_wr32(dev, 0x418684, 0x0000000f); + nv_wr32(dev, 0x418700, 0x00000002); + nv_wr32(dev, 0x418704, 0x00000080); + nv_wr32(dev, 0x418708, 0x00000000); + nv_wr32(dev, 0x41870c, 0x07c80000); + nv_wr32(dev, 0x418710, 0x00000000); + nv_wr32(dev, 0x418800, 0x0006860a); + nv_wr32(dev, 0x418808, 0x00000000); + nv_wr32(dev, 0x41880c, 0x00000000); + nv_wr32(dev, 0x418810, 0x00000000); + nv_wr32(dev, 0x418828, 0x00008442); + nv_wr32(dev, 0x418830, 0x00000001); + nv_wr32(dev, 0x4188d8, 0x00000008); + nv_wr32(dev, 0x4188e0, 0x01000000); + nv_wr32(dev, 0x4188e8, 0x00000000); + nv_wr32(dev, 0x4188ec, 0x00000000); + nv_wr32(dev, 0x4188f0, 0x00000000); + nv_wr32(dev, 0x4188f4, 0x00000000); + nv_wr32(dev, 0x4188f8, 0x00000000); + nv_wr32(dev, 0x4188fc, 0x00100000); + nv_wr32(dev, 0x41891c, 0x00ff00ff); + nv_wr32(dev, 0x418924, 0x00000000); + nv_wr32(dev, 0x418928, 0x00ffff00); + nv_wr32(dev, 0x41892c, 0x0000ff00); + for (i = 0; i < 8; i++) { + nv_wr32(dev, 0x418a00 + (i * 0x20), 0x00000000); + nv_wr32(dev, 0x418a04 + (i * 0x20), 0x00000000); + nv_wr32(dev, 0x418a08 + (i * 0x20), 0x00000000); + nv_wr32(dev, 0x418a0c + (i * 0x20), 0x00010000); + nv_wr32(dev, 0x418a10 + (i * 0x20), 0x00000000); + nv_wr32(dev, 0x418a14 + (i * 0x20), 0x00000000); + nv_wr32(dev, 0x418a18 + (i * 0x20), 0x00000000); + } + nv_wr32(dev, 0x418b00, 0x00000000); + nv_wr32(dev, 0x418b08, 0x0a418820); + nv_wr32(dev, 0x418b0c, 0x062080e6); + nv_wr32(dev, 0x418b10, 0x020398a4); + nv_wr32(dev, 0x418b14, 0x0e629062); + nv_wr32(dev, 0x418b18, 0x0a418820); + nv_wr32(dev, 0x418b1c, 0x000000e6); + nv_wr32(dev, 0x418bb8, 0x00000103); + nv_wr32(dev, 0x418c08, 0x00000001); + nv_wr32(dev, 0x418c10, 0x00000000); + nv_wr32(dev, 0x418c14, 0x00000000); + nv_wr32(dev, 0x418c18, 0x00000000); + nv_wr32(dev, 0x418c1c, 0x00000000); + nv_wr32(dev, 0x418c20, 0x00000000); + nv_wr32(dev, 0x418c24, 0x00000000); + nv_wr32(dev, 0x418c28, 0x00000000); + nv_wr32(dev, 0x418c2c, 0x00000000); + nv_wr32(dev, 0x418c80, 0x20200004); + nv_wr32(dev, 0x418c8c, 0x00000001); + nv_wr32(dev, 0x419000, 0x00000780); + nv_wr32(dev, 0x419004, 0x00000000); + nv_wr32(dev, 0x419008, 0x00000000); + nv_wr32(dev, 0x419014, 0x00000004); +} + +static void +nvc0_grctx_generate_tp(struct drm_device *dev) +{ + struct drm_nouveau_private *dev_priv = dev->dev_private; + + // GPC_BROADCAST.TP_BROADCAST + nv_wr32(dev, 0x419848, 0x00000000); + nv_wr32(dev, 0x419864, 0x0000012a); + nv_wr32(dev, 0x419888, 0x00000000); + nv_wr32(dev, 0x419a00, 0x000001f0); + nv_wr32(dev, 0x419a04, 0x00000001); + nv_wr32(dev, 0x419a08, 0x00000023); + nv_wr32(dev, 0x419a0c, 0x00020000); + nv_wr32(dev, 0x419a10, 0x00000000); + nv_wr32(dev, 0x419a14, 0x00000200); + nv_wr32(dev, 0x419a1c, 0x00000000); + nv_wr32(dev, 0x419a20, 0x00000800); + if (dev_priv->chipset != 0xc0) + nv_wr32(dev, 0x00419ac4, 0x0007f440); // 0xc3 + nv_wr32(dev, 0x419b00, 0x0a418820); + nv_wr32(dev, 0x419b04, 0x062080e6); + nv_wr32(dev, 0x419b08, 0x020398a4); + nv_wr32(dev, 0x419b0c, 0x0e629062); + nv_wr32(dev, 0x419b10, 0x0a418820); + nv_wr32(dev, 0x419b14, 0x000000e6); + nv_wr32(dev, 0x419bd0, 0x00900103); + nv_wr32(dev, 0x419be0, 0x00000001); + nv_wr32(dev, 0x419be4, 0x00000000); + nv_wr32(dev, 0x419c00, 0x00000002); + nv_wr32(dev, 0x419c04, 0x00000006); + nv_wr32(dev, 0x419c08, 0x00000002); + nv_wr32(dev, 0x419c20, 0x00000000); + nv_wr32(dev, 0x419cbc, 0x28137606); + nv_wr32(dev, 0x419ce8, 0x00000000); + nv_wr32(dev, 0x419cf4, 0x00000183); + nv_wr32(dev, 0x419d20, 0x02180000); + nv_wr32(dev, 0x419d24, 0x00001fff); + nv_wr32(dev, 0x419e04, 0x00000000); + nv_wr32(dev, 0x419e08, 0x00000000); + nv_wr32(dev, 0x419e0c, 0x00000000); + nv_wr32(dev, 0x419e10, 0x00000002); + nv_wr32(dev, 0x419e44, 0x001beff2); + nv_wr32(dev, 0x419e48, 0x00000000); + nv_wr32(dev, 0x419e4c, 0x0000000f); + nv_wr32(dev, 0x419e50, 0x00000000); + nv_wr32(dev, 0x419e54, 0x00000000); + nv_wr32(dev, 0x419e58, 0x00000000); + nv_wr32(dev, 0x419e5c, 0x00000000); + nv_wr32(dev, 0x419e60, 0x00000000); + nv_wr32(dev, 0x419e64, 0x00000000); + nv_wr32(dev, 0x419e68, 0x00000000); + nv_wr32(dev, 0x419e6c, 0x00000000); + nv_wr32(dev, 0x419e70, 0x00000000); + nv_wr32(dev, 0x419e74, 0x00000000); + nv_wr32(dev, 0x419e78, 0x00000000); + nv_wr32(dev, 0x419e7c, 0x00000000); + nv_wr32(dev, 0x419e80, 0x00000000); + nv_wr32(dev, 0x419e84, 0x00000000); + nv_wr32(dev, 0x419e88, 0x00000000); + nv_wr32(dev, 0x419e8c, 0x00000000); + nv_wr32(dev, 0x419e90, 0x00000000); + nv_wr32(dev, 0x419e98, 0x00000000); + if (dev_priv->chipset != 0xc0) + nv_wr32(dev, 0x419ee0, 0x00011110); + nv_wr32(dev, 0x419f50, 0x00000000); + nv_wr32(dev, 0x419f54, 0x00000000); + if (dev_priv->chipset != 0xc0) + nv_wr32(dev, 0x419f58, 0x00000000); +} + +int +nvc0_grctx_generate(struct nouveau_channel *chan) +{ + struct drm_nouveau_private *dev_priv = chan->dev->dev_private; + struct nvc0_graph_priv *priv = dev_priv->engine.graph.priv; + struct nvc0_graph_chan *grch = chan->pgraph_ctx; + struct drm_device *dev = chan->dev; + int i, gpc, tp, id; + u32 r000260; + + r000260 = nv_rd32(dev, 0x000260); + nv_wr32(dev, 0x000260, r000260 & ~1); + nv_wr32(dev, 0x400208, 0x00000000); + + nvc0_grctx_generate_dispatch(dev); + nvc0_grctx_generate_macro(dev); + nvc0_grctx_generate_m2mf(dev); + nvc0_grctx_generate_unk47xx(dev); + nvc0_grctx_generate_unk58xx(dev); + nvc0_grctx_generate_unk60xx(dev); + nvc0_grctx_generate_unk64xx(dev); + nvc0_grctx_generate_unk78xx(dev); + nvc0_grctx_generate_unk80xx(dev); + nvc0_grctx_generate_rop(dev); + nvc0_grctx_generate_gpc(dev); + nvc0_grctx_generate_tp(dev); + + nv_wr32(dev, 0x404154, 0x00000000); + + /* fuc "mmio list" writes */ + for (i = 0; i < grch->mmio_nr * 8; i += 8) { + u32 reg = nv_ro32(grch->mmio, i + 0); + nv_wr32(dev, reg, nv_ro32(grch->mmio, i + 4)); + } + + for (tp = 0, id = 0; tp < 4; tp++) { + for (gpc = 0; gpc < priv->gpc_nr; gpc++) { + if (tp <= priv->tp_nr[gpc]) { + nv_wr32(dev, TP_UNIT(gpc, tp, 0x698), id); + nv_wr32(dev, TP_UNIT(gpc, tp, 0x4e8), id); + nv_wr32(dev, GPC_UNIT(gpc, 0x0c10 + tp * 4), id); + nv_wr32(dev, TP_UNIT(gpc, tp, 0x088), id); + id++; + } + + nv_wr32(dev, GPC_UNIT(gpc, 0x0c08), priv->tp_nr[gpc]); + nv_wr32(dev, GPC_UNIT(gpc, 0x0c8c), priv->tp_nr[gpc]); + } + } + + nv_wr32(dev, 0x406028, 0x00000443); + nv_wr32(dev, 0x405870, 0x00000443); + nv_wr32(dev, 0x40602c, 0x00000000); + nv_wr32(dev, 0x405874, 0x00000000); + nv_wr32(dev, 0x406030, 0x00000000); + nv_wr32(dev, 0x405878, 0x00000000); + nv_wr32(dev, 0x406034, 0x00000000); + nv_wr32(dev, 0x40587c, 0x00000000); + + if (1) { + const u8 chipset_tp_max[] = { 16, 0, 0, 4, 8 }; + u8 max = chipset_tp_max[dev_priv->chipset & 0x0f]; + u8 tpnr[GPC_MAX]; + u8 data[32]; + + memcpy(tpnr, priv->tp_nr, sizeof(priv->tp_nr)); + memset(data, 0x1f, sizeof(data)); + + gpc = -1; + for (tp = 0; tp < priv->tp_total; tp++) { + do { + gpc = (gpc + 1) % priv->gpc_nr; + } while (!tpnr[gpc]); + tpnr[gpc]--; + data[tp] = gpc; + } + + for (i = 0; i < max / 4; i++) + nv_wr32(dev, 0x4060a8 + (i * 4), ((u32 *)data)[i]); + } + + if (1) { + u32 data[6] = {}; + u8 tpnr[GPC_MAX]; + + memcpy(tpnr, priv->tp_nr, sizeof(priv->tp_nr)); + + for (tp = 0; tp < priv->tp_total; tp++) { + do { + gpc = (gpc + 1) % priv->gpc_nr; + } while (!tpnr[gpc]); + tpnr[gpc]--; + + data[tp / 6] |= gpc << ((tp % 6) * 5); + } + + for (; tp < 32; tp++) + data[tp / 6] |= 7 << ((tp % 6) * 5); + + // GPC_BROADCAST + nv_wr32(dev, 0x418bb8, (priv->tp_total << 8) | + priv->magic_not_rop_nr); + for (i = 0; i < 6; i++) + nv_wr32(dev, 0x418b08 + (i * 4), data[i]); + + // GPC_BROADCAST.TP_BROADCAST + nv_wr32(dev, 0x419bd0, (priv->tp_total << 8) | + priv->magic_not_rop_nr | + priv->magic419bd0); + nv_wr32(dev, 0x419be4, priv->magic419be4); + for (i = 0; i < 6; i++) + nv_wr32(dev, 0x419b00 + (i * 4), data[i]); + + // UNK78xx + nv_wr32(dev, 0x4078bc, (priv->tp_total << 8) | + priv->magic_not_rop_nr); + for (i = 0; i < 6; i++) + nv_wr32(dev, 0x40780c + (i * 4), data[i]); + } + + if (1) { + u32 tp_mask = 0, tp_set = 0; + u8 tpnr[GPC_MAX]; + + memcpy(tpnr, priv->tp_nr, sizeof(priv->tp_nr)); + for (gpc = 0; gpc < priv->gpc_nr; gpc++) + tp_mask |= ((1 << priv->tp_nr[gpc]) - 1) << (gpc * 8); + + gpc = -1; + for (i = 0, gpc = -1; i < 32; i++) { + int ltp = i * (priv->tp_total - 1) / 32; + + do { + gpc = (gpc + 1) % priv->gpc_nr; + } while (!tpnr[gpc]); + tp = priv->tp_nr[gpc] - tpnr[gpc]--; + + tp_set |= 1 << ((gpc * 8) + tp); + + do { + nv_wr32(dev, 0x406800 + (i * 0x20), tp_set); + tp_set ^= tp_mask; + nv_wr32(dev, 0x406c00 + (i * 0x20), tp_set); + tp_set ^= tp_mask; + } while (ltp == (++i * (priv->tp_total - 1) / 32)); + i--; + } + } + + nv_wr32(dev, 0x400208, 0x80000000); + + nv_icmd(dev, 0x00001000, 0x00000004); + nv_icmd(dev, 0x000000a9, 0x0000ffff); + nv_icmd(dev, 0x00000038, 0x0fac6881); + nv_icmd(dev, 0x0000003d, 0x00000001); + nv_icmd(dev, 0x000000e8, 0x00000400); + nv_icmd(dev, 0x000000e9, 0x00000400); + nv_icmd(dev, 0x000000ea, 0x00000400); + nv_icmd(dev, 0x000000eb, 0x00000400); + nv_icmd(dev, 0x000000ec, 0x00000400); + nv_icmd(dev, 0x000000ed, 0x00000400); + nv_icmd(dev, 0x000000ee, 0x00000400); + nv_icmd(dev, 0x000000ef, 0x00000400); + nv_icmd(dev, 0x00000078, 0x00000300); + nv_icmd(dev, 0x00000079, 0x00000300); + nv_icmd(dev, 0x0000007a, 0x00000300); + nv_icmd(dev, 0x0000007b, 0x00000300); + nv_icmd(dev, 0x0000007c, 0x00000300); + nv_icmd(dev, 0x0000007d, 0x00000300); + nv_icmd(dev, 0x0000007e, 0x00000300); + nv_icmd(dev, 0x0000007f, 0x00000300); + nv_icmd(dev, 0x00000050, 0x00000011); + nv_icmd(dev, 0x00000058, 0x00000008); + nv_icmd(dev, 0x00000059, 0x00000008); + nv_icmd(dev, 0x0000005a, 0x00000008); + nv_icmd(dev, 0x0000005b, 0x00000008); + nv_icmd(dev, 0x0000005c, 0x00000008); + nv_icmd(dev, 0x0000005d, 0x00000008); + nv_icmd(dev, 0x0000005e, 0x00000008); + nv_icmd(dev, 0x0000005f, 0x00000008); + nv_icmd(dev, 0x00000208, 0x00000001); + nv_icmd(dev, 0x00000209, 0x00000001); + nv_icmd(dev, 0x0000020a, 0x00000001); + nv_icmd(dev, 0x0000020b, 0x00000001); + nv_icmd(dev, 0x0000020c, 0x00000001); + nv_icmd(dev, 0x0000020d, 0x00000001); + nv_icmd(dev, 0x0000020e, 0x00000001); + nv_icmd(dev, 0x0000020f, 0x00000001); + nv_icmd(dev, 0x00000081, 0x00000001); + nv_icmd(dev, 0x00000085, 0x00000004); + nv_icmd(dev, 0x00000088, 0x00000400); + nv_icmd(dev, 0x00000090, 0x00000300); + nv_icmd(dev, 0x00000098, 0x00001001); + nv_icmd(dev, 0x000000e3, 0x00000001); + nv_icmd(dev, 0x000000da, 0x00000001); + nv_icmd(dev, 0x000000f8, 0x00000003); + nv_icmd(dev, 0x000000fa, 0x00000001); + nv_icmd(dev, 0x0000009f, 0x0000ffff); + nv_icmd(dev, 0x000000a0, 0x0000ffff); + nv_icmd(dev, 0x000000a1, 0x0000ffff); + nv_icmd(dev, 0x000000a2, 0x0000ffff); + nv_icmd(dev, 0x000000b1, 0x00000001); + nv_icmd(dev, 0x000000b2, 0x00000000); + nv_icmd(dev, 0x000000b3, 0x00000000); + nv_icmd(dev, 0x000000b4, 0x00000000); + nv_icmd(dev, 0x000000b5, 0x00000000); + nv_icmd(dev, 0x000000b6, 0x00000000); + nv_icmd(dev, 0x000000b7, 0x00000000); + nv_icmd(dev, 0x000000b8, 0x00000000); + nv_icmd(dev, 0x000000b9, 0x00000000); + nv_icmd(dev, 0x000000ba, 0x00000000); + nv_icmd(dev, 0x000000bb, 0x00000000); + nv_icmd(dev, 0x000000bc, 0x00000000); + nv_icmd(dev, 0x000000bd, 0x00000000); + nv_icmd(dev, 0x000000be, 0x00000000); + nv_icmd(dev, 0x000000bf, 0x00000000); + nv_icmd(dev, 0x000000c0, 0x00000000); + nv_icmd(dev, 0x000000c1, 0x00000000); + nv_icmd(dev, 0x000000c2, 0x00000000); + nv_icmd(dev, 0x000000c3, 0x00000000); + nv_icmd(dev, 0x000000c4, 0x00000000); + nv_icmd(dev, 0x000000c5, 0x00000000); + nv_icmd(dev, 0x000000c6, 0x00000000); + nv_icmd(dev, 0x000000c7, 0x00000000); + nv_icmd(dev, 0x000000c8, 0x00000000); + nv_icmd(dev, 0x000000c9, 0x00000000); + nv_icmd(dev, 0x000000ca, 0x00000000); + nv_icmd(dev, 0x000000cb, 0x00000000); + nv_icmd(dev, 0x000000cc, 0x00000000); + nv_icmd(dev, 0x000000cd, 0x00000000); + nv_icmd(dev, 0x000000ce, 0x00000000); + nv_icmd(dev, 0x000000cf, 0x00000000); + nv_icmd(dev, 0x000000d0, 0x00000000); + nv_icmd(dev, 0x000000d1, 0x00000000); + nv_icmd(dev, 0x000000d2, 0x00000000); + nv_icmd(dev, 0x000000d3, 0x00000000); + nv_icmd(dev, 0x000000d4, 0x00000000); + nv_icmd(dev, 0x000000d5, 0x00000000); + nv_icmd(dev, 0x000000d6, 0x00000000); + nv_icmd(dev, 0x000000d7, 0x00000000); + nv_icmd(dev, 0x000000d8, 0x00000000); + nv_icmd(dev, 0x000000d9, 0x00000000); + nv_icmd(dev, 0x00000210, 0x00000040); + nv_icmd(dev, 0x00000211, 0x00000040); + nv_icmd(dev, 0x00000212, 0x00000040); + nv_icmd(dev, 0x00000213, 0x00000040); + nv_icmd(dev, 0x00000214, 0x00000040); + nv_icmd(dev, 0x00000215, 0x00000040); + nv_icmd(dev, 0x00000216, 0x00000040); + nv_icmd(dev, 0x00000217, 0x00000040); + nv_icmd(dev, 0x00000218, 0x0000c080); + nv_icmd(dev, 0x00000219, 0x0000c080); + nv_icmd(dev, 0x0000021a, 0x0000c080); + nv_icmd(dev, 0x0000021b, 0x0000c080); + nv_icmd(dev, 0x0000021c, 0x0000c080); + nv_icmd(dev, 0x0000021d, 0x0000c080); + nv_icmd(dev, 0x0000021e, 0x0000c080); + nv_icmd(dev, 0x0000021f, 0x0000c080); + nv_icmd(dev, 0x000000ad, 0x0000013e); + nv_icmd(dev, 0x000000e1, 0x00000010); + nv_icmd(dev, 0x00000290, 0x00000000); + nv_icmd(dev, 0x00000291, 0x00000000); + nv_icmd(dev, 0x00000292, 0x00000000); + nv_icmd(dev, 0x00000293, 0x00000000); + nv_icmd(dev, 0x00000294, 0x00000000); + nv_icmd(dev, 0x00000295, 0x00000000); + nv_icmd(dev, 0x00000296, 0x00000000); + nv_icmd(dev, 0x00000297, 0x00000000); + nv_icmd(dev, 0x00000298, 0x00000000); + nv_icmd(dev, 0x00000299, 0x00000000); + nv_icmd(dev, 0x0000029a, 0x00000000); + nv_icmd(dev, 0x0000029b, 0x00000000); + nv_icmd(dev, 0x0000029c, 0x00000000); + nv_icmd(dev, 0x0000029d, 0x00000000); + nv_icmd(dev, 0x0000029e, 0x00000000); + nv_icmd(dev, 0x0000029f, 0x00000000); + nv_icmd(dev, 0x000003b0, 0x00000000); + nv_icmd(dev, 0x000003b1, 0x00000000); + nv_icmd(dev, 0x000003b2, 0x00000000); + nv_icmd(dev, 0x000003b3, 0x00000000); + nv_icmd(dev, 0x000003b4, 0x00000000); + nv_icmd(dev, 0x000003b5, 0x00000000); + nv_icmd(dev, 0x000003b6, 0x00000000); + nv_icmd(dev, 0x000003b7, 0x00000000); + nv_icmd(dev, 0x000003b8, 0x00000000); + nv_icmd(dev, 0x000003b9, 0x00000000); + nv_icmd(dev, 0x000003ba, 0x00000000); + nv_icmd(dev, 0x000003bb, 0x00000000); + nv_icmd(dev, 0x000003bc, 0x00000000); + nv_icmd(dev, 0x000003bd, 0x00000000); + nv_icmd(dev, 0x000003be, 0x00000000); + nv_icmd(dev, 0x000003bf, 0x00000000); + nv_icmd(dev, 0x000002a0, 0x00000000); + nv_icmd(dev, 0x000002a1, 0x00000000); + nv_icmd(dev, 0x000002a2, 0x00000000); + nv_icmd(dev, 0x000002a3, 0x00000000); + nv_icmd(dev, 0x000002a4, 0x00000000); + nv_icmd(dev, 0x000002a5, 0x00000000); + nv_icmd(dev, 0x000002a6, 0x00000000); + nv_icmd(dev, 0x000002a7, 0x00000000); + nv_icmd(dev, 0x000002a8, 0x00000000); + nv_icmd(dev, 0x000002a9, 0x00000000); + nv_icmd(dev, 0x000002aa, 0x00000000); + nv_icmd(dev, 0x000002ab, 0x00000000); + nv_icmd(dev, 0x000002ac, 0x00000000); + nv_icmd(dev, 0x000002ad, 0x00000000); + nv_icmd(dev, 0x000002ae, 0x00000000); + nv_icmd(dev, 0x000002af, 0x00000000); + nv_icmd(dev, 0x00000420, 0x00000000); + nv_icmd(dev, 0x00000421, 0x00000000); + nv_icmd(dev, 0x00000422, 0x00000000); + nv_icmd(dev, 0x00000423, 0x00000000); + nv_icmd(dev, 0x00000424, 0x00000000); + nv_icmd(dev, 0x00000425, 0x00000000); + nv_icmd(dev, 0x00000426, 0x00000000); + nv_icmd(dev, 0x00000427, 0x00000000); + nv_icmd(dev, 0x00000428, 0x00000000); + nv_icmd(dev, 0x00000429, 0x00000000); + nv_icmd(dev, 0x0000042a, 0x00000000); + nv_icmd(dev, 0x0000042b, 0x00000000); + nv_icmd(dev, 0x0000042c, 0x00000000); + nv_icmd(dev, 0x0000042d, 0x00000000); + nv_icmd(dev, 0x0000042e, 0x00000000); + nv_icmd(dev, 0x0000042f, 0x00000000); + nv_icmd(dev, 0x000002b0, 0x00000000); + nv_icmd(dev, 0x000002b1, 0x00000000); + nv_icmd(dev, 0x000002b2, 0x00000000); + nv_icmd(dev, 0x000002b3, 0x00000000); + nv_icmd(dev, 0x000002b4, 0x00000000); + nv_icmd(dev, 0x000002b5, 0x00000000); + nv_icmd(dev, 0x000002b6, 0x00000000); + nv_icmd(dev, 0x000002b7, 0x00000000); + nv_icmd(dev, 0x000002b8, 0x00000000); + nv_icmd(dev, 0x000002b9, 0x00000000); + nv_icmd(dev, 0x000002ba, 0x00000000); + nv_icmd(dev, 0x000002bb, 0x00000000); + nv_icmd(dev, 0x000002bc, 0x00000000); + nv_icmd(dev, 0x000002bd, 0x00000000); + nv_icmd(dev, 0x000002be, 0x00000000); + nv_icmd(dev, 0x000002bf, 0x00000000); + nv_icmd(dev, 0x00000430, 0x00000000); + nv_icmd(dev, 0x00000431, 0x00000000); + nv_icmd(dev, 0x00000432, 0x00000000); + nv_icmd(dev, 0x00000433, 0x00000000); + nv_icmd(dev, 0x00000434, 0x00000000); + nv_icmd(dev, 0x00000435, 0x00000000); + nv_icmd(dev, 0x00000436, 0x00000000); + nv_icmd(dev, 0x00000437, 0x00000000); + nv_icmd(dev, 0x00000438, 0x00000000); + nv_icmd(dev, 0x00000439, 0x00000000); + nv_icmd(dev, 0x0000043a, 0x00000000); + nv_icmd(dev, 0x0000043b, 0x00000000); + nv_icmd(dev, 0x0000043c, 0x00000000); + nv_icmd(dev, 0x0000043d, 0x00000000); + nv_icmd(dev, 0x0000043e, 0x00000000); + nv_icmd(dev, 0x0000043f, 0x00000000); + nv_icmd(dev, 0x000002c0, 0x00000000); + nv_icmd(dev, 0x000002c1, 0x00000000); + nv_icmd(dev, 0x000002c2, 0x00000000); + nv_icmd(dev, 0x000002c3, 0x00000000); + nv_icmd(dev, 0x000002c4, 0x00000000); + nv_icmd(dev, 0x000002c5, 0x00000000); + nv_icmd(dev, 0x000002c6, 0x00000000); + nv_icmd(dev, 0x000002c7, 0x00000000); + nv_icmd(dev, 0x000002c8, 0x00000000); + nv_icmd(dev, 0x000002c9, 0x00000000); + nv_icmd(dev, 0x000002ca, 0x00000000); + nv_icmd(dev, 0x000002cb, 0x00000000); + nv_icmd(dev, 0x000002cc, 0x00000000); + nv_icmd(dev, 0x000002cd, 0x00000000); + nv_icmd(dev, 0x000002ce, 0x00000000); + nv_icmd(dev, 0x000002cf, 0x00000000); + nv_icmd(dev, 0x000004d0, 0x00000000); + nv_icmd(dev, 0x000004d1, 0x00000000); + nv_icmd(dev, 0x000004d2, 0x00000000); + nv_icmd(dev, 0x000004d3, 0x00000000); + nv_icmd(dev, 0x000004d4, 0x00000000); + nv_icmd(dev, 0x000004d5, 0x00000000); + nv_icmd(dev, 0x000004d6, 0x00000000); + nv_icmd(dev, 0x000004d7, 0x00000000); + nv_icmd(dev, 0x000004d8, 0x00000000); + nv_icmd(dev, 0x000004d9, 0x00000000); + nv_icmd(dev, 0x000004da, 0x00000000); + nv_icmd(dev, 0x000004db, 0x00000000); + nv_icmd(dev, 0x000004dc, 0x00000000); + nv_icmd(dev, 0x000004dd, 0x00000000); + nv_icmd(dev, 0x000004de, 0x00000000); + nv_icmd(dev, 0x000004df, 0x00000000); + nv_icmd(dev, 0x00000720, 0x00000000); + nv_icmd(dev, 0x00000721, 0x00000000); + nv_icmd(dev, 0x00000722, 0x00000000); + nv_icmd(dev, 0x00000723, 0x00000000); + nv_icmd(dev, 0x00000724, 0x00000000); + nv_icmd(dev, 0x00000725, 0x00000000); + nv_icmd(dev, 0x00000726, 0x00000000); + nv_icmd(dev, 0x00000727, 0x00000000); + nv_icmd(dev, 0x00000728, 0x00000000); + nv_icmd(dev, 0x00000729, 0x00000000); + nv_icmd(dev, 0x0000072a, 0x00000000); + nv_icmd(dev, 0x0000072b, 0x00000000); + nv_icmd(dev, 0x0000072c, 0x00000000); + nv_icmd(dev, 0x0000072d, 0x00000000); + nv_icmd(dev, 0x0000072e, 0x00000000); + nv_icmd(dev, 0x0000072f, 0x00000000); + nv_icmd(dev, 0x000008c0, 0x00000000); + nv_icmd(dev, 0x000008c1, 0x00000000); + nv_icmd(dev, 0x000008c2, 0x00000000); + nv_icmd(dev, 0x000008c3, 0x00000000); + nv_icmd(dev, 0x000008c4, 0x00000000); + nv_icmd(dev, 0x000008c5, 0x00000000); + nv_icmd(dev, 0x000008c6, 0x00000000); + nv_icmd(dev, 0x000008c7, 0x00000000); + nv_icmd(dev, 0x000008c8, 0x00000000); + nv_icmd(dev, 0x000008c9, 0x00000000); + nv_icmd(dev, 0x000008ca, 0x00000000); + nv_icmd(dev, 0x000008cb, 0x00000000); + nv_icmd(dev, 0x000008cc, 0x00000000); + nv_icmd(dev, 0x000008cd, 0x00000000); + nv_icmd(dev, 0x000008ce, 0x00000000); + nv_icmd(dev, 0x000008cf, 0x00000000); + nv_icmd(dev, 0x00000890, 0x00000000); + nv_icmd(dev, 0x00000891, 0x00000000); + nv_icmd(dev, 0x00000892, 0x00000000); + nv_icmd(dev, 0x00000893, 0x00000000); + nv_icmd(dev, 0x00000894, 0x00000000); + nv_icmd(dev, 0x00000895, 0x00000000); + nv_icmd(dev, 0x00000896, 0x00000000); + nv_icmd(dev, 0x00000897, 0x00000000); + nv_icmd(dev, 0x00000898, 0x00000000); + nv_icmd(dev, 0x00000899, 0x00000000); + nv_icmd(dev, 0x0000089a, 0x00000000); + nv_icmd(dev, 0x0000089b, 0x00000000); + nv_icmd(dev, 0x0000089c, 0x00000000); + nv_icmd(dev, 0x0000089d, 0x00000000); + nv_icmd(dev, 0x0000089e, 0x00000000); + nv_icmd(dev, 0x0000089f, 0x00000000); + nv_icmd(dev, 0x000008e0, 0x00000000); + nv_icmd(dev, 0x000008e1, 0x00000000); + nv_icmd(dev, 0x000008e2, 0x00000000); + nv_icmd(dev, 0x000008e3, 0x00000000); + nv_icmd(dev, 0x000008e4, 0x00000000); + nv_icmd(dev, 0x000008e5, 0x00000000); + nv_icmd(dev, 0x000008e6, 0x00000000); + nv_icmd(dev, 0x000008e7, 0x00000000); + nv_icmd(dev, 0x000008e8, 0x00000000); + nv_icmd(dev, 0x000008e9, 0x00000000); + nv_icmd(dev, 0x000008ea, 0x00000000); + nv_icmd(dev, 0x000008eb, 0x00000000); + nv_icmd(dev, 0x000008ec, 0x00000000); + nv_icmd(dev, 0x000008ed, 0x00000000); + nv_icmd(dev, 0x000008ee, 0x00000000); + nv_icmd(dev, 0x000008ef, 0x00000000); + nv_icmd(dev, 0x000008a0, 0x00000000); + nv_icmd(dev, 0x000008a1, 0x00000000); + nv_icmd(dev, 0x000008a2, 0x00000000); + nv_icmd(dev, 0x000008a3, 0x00000000); + nv_icmd(dev, 0x000008a4, 0x00000000); + nv_icmd(dev, 0x000008a5, 0x00000000); + nv_icmd(dev, 0x000008a6, 0x00000000); + nv_icmd(dev, 0x000008a7, 0x00000000); + nv_icmd(dev, 0x000008a8, 0x00000000); + nv_icmd(dev, 0x000008a9, 0x00000000); + nv_icmd(dev, 0x000008aa, 0x00000000); + nv_icmd(dev, 0x000008ab, 0x00000000); + nv_icmd(dev, 0x000008ac, 0x00000000); + nv_icmd(dev, 0x000008ad, 0x00000000); + nv_icmd(dev, 0x000008ae, 0x00000000); + nv_icmd(dev, 0x000008af, 0x00000000); + nv_icmd(dev, 0x000008f0, 0x00000000); + nv_icmd(dev, 0x000008f1, 0x00000000); + nv_icmd(dev, 0x000008f2, 0x00000000); + nv_icmd(dev, 0x000008f3, 0x00000000); + nv_icmd(dev, 0x000008f4, 0x00000000); + nv_icmd(dev, 0x000008f5, 0x00000000); + nv_icmd(dev, 0x000008f6, 0x00000000); + nv_icmd(dev, 0x000008f7, 0x00000000); + nv_icmd(dev, 0x000008f8, 0x00000000); + nv_icmd(dev, 0x000008f9, 0x00000000); + nv_icmd(dev, 0x000008fa, 0x00000000); + nv_icmd(dev, 0x000008fb, 0x00000000); + nv_icmd(dev, 0x000008fc, 0x00000000); + nv_icmd(dev, 0x000008fd, 0x00000000); + nv_icmd(dev, 0x000008fe, 0x00000000); + nv_icmd(dev, 0x000008ff, 0x00000000); + nv_icmd(dev, 0x0000094c, 0x000000ff); + nv_icmd(dev, 0x0000094d, 0xffffffff); + nv_icmd(dev, 0x0000094e, 0x00000002); + nv_icmd(dev, 0x000002ec, 0x00000001); + nv_icmd(dev, 0x00000303, 0x00000001); + nv_icmd(dev, 0x000002e6, 0x00000001); + nv_icmd(dev, 0x00000466, 0x00000052); + nv_icmd(dev, 0x00000301, 0x3f800000); + nv_icmd(dev, 0x00000304, 0x30201000); + nv_icmd(dev, 0x00000305, 0x70605040); + nv_icmd(dev, 0x00000306, 0xb8a89888); + nv_icmd(dev, 0x00000307, 0xf8e8d8c8); + nv_icmd(dev, 0x0000030a, 0x00ffff00); + nv_icmd(dev, 0x0000030b, 0x0000001a); + nv_icmd(dev, 0x0000030c, 0x00000001); + nv_icmd(dev, 0x00000318, 0x00000001); + nv_icmd(dev, 0x00000340, 0x00000000); + nv_icmd(dev, 0x00000375, 0x00000001); + nv_icmd(dev, 0x00000351, 0x00000100); + nv_icmd(dev, 0x0000037d, 0x00000006); + nv_icmd(dev, 0x000003a0, 0x00000002); + nv_icmd(dev, 0x000003aa, 0x00000001); + nv_icmd(dev, 0x000003a9, 0x00000001); + nv_icmd(dev, 0x00000380, 0x00000001); + nv_icmd(dev, 0x00000360, 0x00000040); + nv_icmd(dev, 0x00000366, 0x00000000); + nv_icmd(dev, 0x00000367, 0x00000000); + nv_icmd(dev, 0x00000368, 0x00001fff); + nv_icmd(dev, 0x00000370, 0x00000000); + nv_icmd(dev, 0x00000371, 0x00000000); + nv_icmd(dev, 0x00000372, 0x003fffff); + nv_icmd(dev, 0x0000037a, 0x00000012); + nv_icmd(dev, 0x000005e0, 0x00000022); + nv_icmd(dev, 0x000005e1, 0x00000022); + nv_icmd(dev, 0x000005e2, 0x00000022); + nv_icmd(dev, 0x000005e3, 0x00000022); + nv_icmd(dev, 0x000005e4, 0x00000022); + nv_icmd(dev, 0x00000619, 0x00000003); + nv_icmd(dev, 0x00000811, 0x00000003); + nv_icmd(dev, 0x00000812, 0x00000004); + nv_icmd(dev, 0x00000813, 0x00000006); + nv_icmd(dev, 0x00000814, 0x00000008); + nv_icmd(dev, 0x00000815, 0x0000000b); + nv_icmd(dev, 0x00000800, 0x00000001); + nv_icmd(dev, 0x00000801, 0x00000001); + nv_icmd(dev, 0x00000802, 0x00000001); + nv_icmd(dev, 0x00000803, 0x00000001); + nv_icmd(dev, 0x00000804, 0x00000001); + nv_icmd(dev, 0x00000805, 0x00000001); + nv_icmd(dev, 0x00000632, 0x00000001); + nv_icmd(dev, 0x00000633, 0x00000002); + nv_icmd(dev, 0x00000634, 0x00000003); + nv_icmd(dev, 0x00000635, 0x00000004); + nv_icmd(dev, 0x00000654, 0x3f800000); + nv_icmd(dev, 0x00000657, 0x3f800000); + nv_icmd(dev, 0x00000655, 0x3f800000); + nv_icmd(dev, 0x00000656, 0x3f800000); + nv_icmd(dev, 0x000006cd, 0x3f800000); + nv_icmd(dev, 0x000007f5, 0x3f800000); + nv_icmd(dev, 0x000007dc, 0x39291909); + nv_icmd(dev, 0x000007dd, 0x79695949); + nv_icmd(dev, 0x000007de, 0xb9a99989); + nv_icmd(dev, 0x000007df, 0xf9e9d9c9); + nv_icmd(dev, 0x000007e8, 0x00003210); + nv_icmd(dev, 0x000007e9, 0x00007654); + nv_icmd(dev, 0x000007ea, 0x00000098); + nv_icmd(dev, 0x000007ec, 0x39291909); + nv_icmd(dev, 0x000007ed, 0x79695949); + nv_icmd(dev, 0x000007ee, 0xb9a99989); + nv_icmd(dev, 0x000007ef, 0xf9e9d9c9); + nv_icmd(dev, 0x000007f0, 0x00003210); + nv_icmd(dev, 0x000007f1, 0x00007654); + nv_icmd(dev, 0x000007f2, 0x00000098); + nv_icmd(dev, 0x000005a5, 0x00000001); + nv_icmd(dev, 0x00000980, 0x00000000); + nv_icmd(dev, 0x00000981, 0x00000000); + nv_icmd(dev, 0x00000982, 0x00000000); + nv_icmd(dev, 0x00000983, 0x00000000); + nv_icmd(dev, 0x00000984, 0x00000000); + nv_icmd(dev, 0x00000985, 0x00000000); + nv_icmd(dev, 0x00000986, 0x00000000); + nv_icmd(dev, 0x00000987, 0x00000000); + nv_icmd(dev, 0x00000988, 0x00000000); + nv_icmd(dev, 0x00000989, 0x00000000); + nv_icmd(dev, 0x0000098a, 0x00000000); + nv_icmd(dev, 0x0000098b, 0x00000000); + nv_icmd(dev, 0x0000098c, 0x00000000); + nv_icmd(dev, 0x0000098d, 0x00000000); + nv_icmd(dev, 0x0000098e, 0x00000000); + nv_icmd(dev, 0x0000098f, 0x00000000); + nv_icmd(dev, 0x00000990, 0x00000000); + nv_icmd(dev, 0x00000991, 0x00000000); + nv_icmd(dev, 0x00000992, 0x00000000); + nv_icmd(dev, 0x00000993, 0x00000000); + nv_icmd(dev, 0x00000994, 0x00000000); + nv_icmd(dev, 0x00000995, 0x00000000); + nv_icmd(dev, 0x00000996, 0x00000000); + nv_icmd(dev, 0x00000997, 0x00000000); + nv_icmd(dev, 0x00000998, 0x00000000); + nv_icmd(dev, 0x00000999, 0x00000000); + nv_icmd(dev, 0x0000099a, 0x00000000); + nv_icmd(dev, 0x0000099b, 0x00000000); + nv_icmd(dev, 0x0000099c, 0x00000000); + nv_icmd(dev, 0x0000099d, 0x00000000); + nv_icmd(dev, 0x0000099e, 0x00000000); + nv_icmd(dev, 0x0000099f, 0x00000000); + nv_icmd(dev, 0x000009a0, 0x00000000); + nv_icmd(dev, 0x000009a1, 0x00000000); + nv_icmd(dev, 0x000009a2, 0x00000000); + nv_icmd(dev, 0x000009a3, 0x00000000); + nv_icmd(dev, 0x000009a4, 0x00000000); + nv_icmd(dev, 0x000009a5, 0x00000000); + nv_icmd(dev, 0x000009a6, 0x00000000); + nv_icmd(dev, 0x000009a7, 0x00000000); + nv_icmd(dev, 0x000009a8, 0x00000000); + nv_icmd(dev, 0x000009a9, 0x00000000); + nv_icmd(dev, 0x000009aa, 0x00000000); + nv_icmd(dev, 0x000009ab, 0x00000000); + nv_icmd(dev, 0x000009ac, 0x00000000); + nv_icmd(dev, 0x000009ad, 0x00000000); + nv_icmd(dev, 0x000009ae, 0x00000000); + nv_icmd(dev, 0x000009af, 0x00000000); + nv_icmd(dev, 0x000009b0, 0x00000000); + nv_icmd(dev, 0x000009b1, 0x00000000); + nv_icmd(dev, 0x000009b2, 0x00000000); + nv_icmd(dev, 0x000009b3, 0x00000000); + nv_icmd(dev, 0x000009b4, 0x00000000); + nv_icmd(dev, 0x000009b5, 0x00000000); + nv_icmd(dev, 0x000009b6, 0x00000000); + nv_icmd(dev, 0x000009b7, 0x00000000); + nv_icmd(dev, 0x000009b8, 0x00000000); + nv_icmd(dev, 0x000009b9, 0x00000000); + nv_icmd(dev, 0x000009ba, 0x00000000); + nv_icmd(dev, 0x000009bb, 0x00000000); + nv_icmd(dev, 0x000009bc, 0x00000000); + nv_icmd(dev, 0x000009bd, 0x00000000); + nv_icmd(dev, 0x000009be, 0x00000000); + nv_icmd(dev, 0x000009bf, 0x00000000); + nv_icmd(dev, 0x000009c0, 0x00000000); + nv_icmd(dev, 0x000009c1, 0x00000000); + nv_icmd(dev, 0x000009c2, 0x00000000); + nv_icmd(dev, 0x000009c3, 0x00000000); + nv_icmd(dev, 0x000009c4, 0x00000000); + nv_icmd(dev, 0x000009c5, 0x00000000); + nv_icmd(dev, 0x000009c6, 0x00000000); + nv_icmd(dev, 0x000009c7, 0x00000000); + nv_icmd(dev, 0x000009c8, 0x00000000); + nv_icmd(dev, 0x000009c9, 0x00000000); + nv_icmd(dev, 0x000009ca, 0x00000000); + nv_icmd(dev, 0x000009cb, 0x00000000); + nv_icmd(dev, 0x000009cc, 0x00000000); + nv_icmd(dev, 0x000009cd, 0x00000000); + nv_icmd(dev, 0x000009ce, 0x00000000); + nv_icmd(dev, 0x000009cf, 0x00000000); + nv_icmd(dev, 0x000009d0, 0x00000000); + nv_icmd(dev, 0x000009d1, 0x00000000); + nv_icmd(dev, 0x000009d2, 0x00000000); + nv_icmd(dev, 0x000009d3, 0x00000000); + nv_icmd(dev, 0x000009d4, 0x00000000); + nv_icmd(dev, 0x000009d5, 0x00000000); + nv_icmd(dev, 0x000009d6, 0x00000000); + nv_icmd(dev, 0x000009d7, 0x00000000); + nv_icmd(dev, 0x000009d8, 0x00000000); + nv_icmd(dev, 0x000009d9, 0x00000000); + nv_icmd(dev, 0x000009da, 0x00000000); + nv_icmd(dev, 0x000009db, 0x00000000); + nv_icmd(dev, 0x000009dc, 0x00000000); + nv_icmd(dev, 0x000009dd, 0x00000000); + nv_icmd(dev, 0x000009de, 0x00000000); + nv_icmd(dev, 0x000009df, 0x00000000); + nv_icmd(dev, 0x000009e0, 0x00000000); + nv_icmd(dev, 0x000009e1, 0x00000000); + nv_icmd(dev, 0x000009e2, 0x00000000); + nv_icmd(dev, 0x000009e3, 0x00000000); + nv_icmd(dev, 0x000009e4, 0x00000000); + nv_icmd(dev, 0x000009e5, 0x00000000); + nv_icmd(dev, 0x000009e6, 0x00000000); + nv_icmd(dev, 0x000009e7, 0x00000000); + nv_icmd(dev, 0x000009e8, 0x00000000); + nv_icmd(dev, 0x000009e9, 0x00000000); + nv_icmd(dev, 0x000009ea, 0x00000000); + nv_icmd(dev, 0x000009eb, 0x00000000); + nv_icmd(dev, 0x000009ec, 0x00000000); + nv_icmd(dev, 0x000009ed, 0x00000000); + nv_icmd(dev, 0x000009ee, 0x00000000); + nv_icmd(dev, 0x000009ef, 0x00000000); + nv_icmd(dev, 0x000009f0, 0x00000000); + nv_icmd(dev, 0x000009f1, 0x00000000); + nv_icmd(dev, 0x000009f2, 0x00000000); + nv_icmd(dev, 0x000009f3, 0x00000000); + nv_icmd(dev, 0x000009f4, 0x00000000); + nv_icmd(dev, 0x000009f5, 0x00000000); + nv_icmd(dev, 0x000009f6, 0x00000000); + nv_icmd(dev, 0x000009f7, 0x00000000); + nv_icmd(dev, 0x000009f8, 0x00000000); + nv_icmd(dev, 0x000009f9, 0x00000000); + nv_icmd(dev, 0x000009fa, 0x00000000); + nv_icmd(dev, 0x000009fb, 0x00000000); + nv_icmd(dev, 0x000009fc, 0x00000000); + nv_icmd(dev, 0x000009fd, 0x00000000); + nv_icmd(dev, 0x000009fe, 0x00000000); + nv_icmd(dev, 0x000009ff, 0x00000000); + nv_icmd(dev, 0x00000468, 0x00000004); + nv_icmd(dev, 0x0000046c, 0x00000001); + nv_icmd(dev, 0x00000470, 0x00000000); + nv_icmd(dev, 0x00000471, 0x00000000); + nv_icmd(dev, 0x00000472, 0x00000000); + nv_icmd(dev, 0x00000473, 0x00000000); + nv_icmd(dev, 0x00000474, 0x00000000); + nv_icmd(dev, 0x00000475, 0x00000000); + nv_icmd(dev, 0x00000476, 0x00000000); + nv_icmd(dev, 0x00000477, 0x00000000); + nv_icmd(dev, 0x00000478, 0x00000000); + nv_icmd(dev, 0x00000479, 0x00000000); + nv_icmd(dev, 0x0000047a, 0x00000000); + nv_icmd(dev, 0x0000047b, 0x00000000); + nv_icmd(dev, 0x0000047c, 0x00000000); + nv_icmd(dev, 0x0000047d, 0x00000000); + nv_icmd(dev, 0x0000047e, 0x00000000); + nv_icmd(dev, 0x0000047f, 0x00000000); + nv_icmd(dev, 0x00000480, 0x00000000); + nv_icmd(dev, 0x00000481, 0x00000000); + nv_icmd(dev, 0x00000482, 0x00000000); + nv_icmd(dev, 0x00000483, 0x00000000); + nv_icmd(dev, 0x00000484, 0x00000000); + nv_icmd(dev, 0x00000485, 0x00000000); + nv_icmd(dev, 0x00000486, 0x00000000); + nv_icmd(dev, 0x00000487, 0x00000000); + nv_icmd(dev, 0x00000488, 0x00000000); + nv_icmd(dev, 0x00000489, 0x00000000); + nv_icmd(dev, 0x0000048a, 0x00000000); + nv_icmd(dev, 0x0000048b, 0x00000000); + nv_icmd(dev, 0x0000048c, 0x00000000); + nv_icmd(dev, 0x0000048d, 0x00000000); + nv_icmd(dev, 0x0000048e, 0x00000000); + nv_icmd(dev, 0x0000048f, 0x00000000); + nv_icmd(dev, 0x00000490, 0x00000000); + nv_icmd(dev, 0x00000491, 0x00000000); + nv_icmd(dev, 0x00000492, 0x00000000); + nv_icmd(dev, 0x00000493, 0x00000000); + nv_icmd(dev, 0x00000494, 0x00000000); + nv_icmd(dev, 0x00000495, 0x00000000); + nv_icmd(dev, 0x00000496, 0x00000000); + nv_icmd(dev, 0x00000497, 0x00000000); + nv_icmd(dev, 0x00000498, 0x00000000); + nv_icmd(dev, 0x00000499, 0x00000000); + nv_icmd(dev, 0x0000049a, 0x00000000); + nv_icmd(dev, 0x0000049b, 0x00000000); + nv_icmd(dev, 0x0000049c, 0x00000000); + nv_icmd(dev, 0x0000049d, 0x00000000); + nv_icmd(dev, 0x0000049e, 0x00000000); + nv_icmd(dev, 0x0000049f, 0x00000000); + nv_icmd(dev, 0x000004a0, 0x00000000); + nv_icmd(dev, 0x000004a1, 0x00000000); + nv_icmd(dev, 0x000004a2, 0x00000000); + nv_icmd(dev, 0x000004a3, 0x00000000); + nv_icmd(dev, 0x000004a4, 0x00000000); + nv_icmd(dev, 0x000004a5, 0x00000000); + nv_icmd(dev, 0x000004a6, 0x00000000); + nv_icmd(dev, 0x000004a7, 0x00000000); + nv_icmd(dev, 0x000004a8, 0x00000000); + nv_icmd(dev, 0x000004a9, 0x00000000); + nv_icmd(dev, 0x000004aa, 0x00000000); + nv_icmd(dev, 0x000004ab, 0x00000000); + nv_icmd(dev, 0x000004ac, 0x00000000); + nv_icmd(dev, 0x000004ad, 0x00000000); + nv_icmd(dev, 0x000004ae, 0x00000000); + nv_icmd(dev, 0x000004af, 0x00000000); + nv_icmd(dev, 0x000004b0, 0x00000000); + nv_icmd(dev, 0x000004b1, 0x00000000); + nv_icmd(dev, 0x000004b2, 0x00000000); + nv_icmd(dev, 0x000004b3, 0x00000000); + nv_icmd(dev, 0x000004b4, 0x00000000); + nv_icmd(dev, 0x000004b5, 0x00000000); + nv_icmd(dev, 0x000004b6, 0x00000000); + nv_icmd(dev, 0x000004b7, 0x00000000); + nv_icmd(dev, 0x000004b8, 0x00000000); + nv_icmd(dev, 0x000004b9, 0x00000000); + nv_icmd(dev, 0x000004ba, 0x00000000); + nv_icmd(dev, 0x000004bb, 0x00000000); + nv_icmd(dev, 0x000004bc, 0x00000000); + nv_icmd(dev, 0x000004bd, 0x00000000); + nv_icmd(dev, 0x000004be, 0x00000000); + nv_icmd(dev, 0x000004bf, 0x00000000); + nv_icmd(dev, 0x000004c0, 0x00000000); + nv_icmd(dev, 0x000004c1, 0x00000000); + nv_icmd(dev, 0x000004c2, 0x00000000); + nv_icmd(dev, 0x000004c3, 0x00000000); + nv_icmd(dev, 0x000004c4, 0x00000000); + nv_icmd(dev, 0x000004c5, 0x00000000); + nv_icmd(dev, 0x000004c6, 0x00000000); + nv_icmd(dev, 0x000004c7, 0x00000000); + nv_icmd(dev, 0x000004c8, 0x00000000); + nv_icmd(dev, 0x000004c9, 0x00000000); + nv_icmd(dev, 0x000004ca, 0x00000000); + nv_icmd(dev, 0x000004cb, 0x00000000); + nv_icmd(dev, 0x000004cc, 0x00000000); + nv_icmd(dev, 0x000004cd, 0x00000000); + nv_icmd(dev, 0x000004ce, 0x00000000); + nv_icmd(dev, 0x000004cf, 0x00000000); + nv_icmd(dev, 0x00000510, 0x3f800000); + nv_icmd(dev, 0x00000511, 0x3f800000); + nv_icmd(dev, 0x00000512, 0x3f800000); + nv_icmd(dev, 0x00000513, 0x3f800000); + nv_icmd(dev, 0x00000514, 0x3f800000); + nv_icmd(dev, 0x00000515, 0x3f800000); + nv_icmd(dev, 0x00000516, 0x3f800000); + nv_icmd(dev, 0x00000517, 0x3f800000); + nv_icmd(dev, 0x00000518, 0x3f800000); + nv_icmd(dev, 0x00000519, 0x3f800000); + nv_icmd(dev, 0x0000051a, 0x3f800000); + nv_icmd(dev, 0x0000051b, 0x3f800000); + nv_icmd(dev, 0x0000051c, 0x3f800000); + nv_icmd(dev, 0x0000051d, 0x3f800000); + nv_icmd(dev, 0x0000051e, 0x3f800000); + nv_icmd(dev, 0x0000051f, 0x3f800000); + nv_icmd(dev, 0x00000520, 0x000002b6); + nv_icmd(dev, 0x00000529, 0x00000001); + nv_icmd(dev, 0x00000530, 0xffff0000); + nv_icmd(dev, 0x00000531, 0xffff0000); + nv_icmd(dev, 0x00000532, 0xffff0000); + nv_icmd(dev, 0x00000533, 0xffff0000); + nv_icmd(dev, 0x00000534, 0xffff0000); + nv_icmd(dev, 0x00000535, 0xffff0000); + nv_icmd(dev, 0x00000536, 0xffff0000); + nv_icmd(dev, 0x00000537, 0xffff0000); + nv_icmd(dev, 0x00000538, 0xffff0000); + nv_icmd(dev, 0x00000539, 0xffff0000); + nv_icmd(dev, 0x0000053a, 0xffff0000); + nv_icmd(dev, 0x0000053b, 0xffff0000); + nv_icmd(dev, 0x0000053c, 0xffff0000); + nv_icmd(dev, 0x0000053d, 0xffff0000); + nv_icmd(dev, 0x0000053e, 0xffff0000); + nv_icmd(dev, 0x0000053f, 0xffff0000); + nv_icmd(dev, 0x00000585, 0x0000003f); + nv_icmd(dev, 0x00000576, 0x00000003); + nv_icmd(dev, 0x00000586, 0x00000040); + nv_icmd(dev, 0x00000582, 0x00000080); + nv_icmd(dev, 0x00000583, 0x00000080); + nv_icmd(dev, 0x000005c2, 0x00000001); + nv_icmd(dev, 0x00000638, 0x00000001); + nv_icmd(dev, 0x00000639, 0x00000001); + nv_icmd(dev, 0x0000063a, 0x00000002); + nv_icmd(dev, 0x0000063b, 0x00000001); + nv_icmd(dev, 0x0000063c, 0x00000001); + nv_icmd(dev, 0x0000063d, 0x00000002); + nv_icmd(dev, 0x0000063e, 0x00000001); + nv_icmd(dev, 0x000008b8, 0x00000001); + nv_icmd(dev, 0x000008b9, 0x00000001); + nv_icmd(dev, 0x000008ba, 0x00000001); + nv_icmd(dev, 0x000008bb, 0x00000001); + nv_icmd(dev, 0x000008bc, 0x00000001); + nv_icmd(dev, 0x000008bd, 0x00000001); + nv_icmd(dev, 0x000008be, 0x00000001); + nv_icmd(dev, 0x000008bf, 0x00000001); + nv_icmd(dev, 0x00000900, 0x00000001); + nv_icmd(dev, 0x00000901, 0x00000001); + nv_icmd(dev, 0x00000902, 0x00000001); + nv_icmd(dev, 0x00000903, 0x00000001); + nv_icmd(dev, 0x00000904, 0x00000001); + nv_icmd(dev, 0x00000905, 0x00000001); + nv_icmd(dev, 0x00000906, 0x00000001); + nv_icmd(dev, 0x00000907, 0x00000001); + nv_icmd(dev, 0x00000908, 0x00000002); + nv_icmd(dev, 0x00000909, 0x00000002); + nv_icmd(dev, 0x0000090a, 0x00000002); + nv_icmd(dev, 0x0000090b, 0x00000002); + nv_icmd(dev, 0x0000090c, 0x00000002); + nv_icmd(dev, 0x0000090d, 0x00000002); + nv_icmd(dev, 0x0000090e, 0x00000002); + nv_icmd(dev, 0x0000090f, 0x00000002); + nv_icmd(dev, 0x00000910, 0x00000001); + nv_icmd(dev, 0x00000911, 0x00000001); + nv_icmd(dev, 0x00000912, 0x00000001); + nv_icmd(dev, 0x00000913, 0x00000001); + nv_icmd(dev, 0x00000914, 0x00000001); + nv_icmd(dev, 0x00000915, 0x00000001); + nv_icmd(dev, 0x00000916, 0x00000001); + nv_icmd(dev, 0x00000917, 0x00000001); + nv_icmd(dev, 0x00000918, 0x00000001); + nv_icmd(dev, 0x00000919, 0x00000001); + nv_icmd(dev, 0x0000091a, 0x00000001); + nv_icmd(dev, 0x0000091b, 0x00000001); + nv_icmd(dev, 0x0000091c, 0x00000001); + nv_icmd(dev, 0x0000091d, 0x00000001); + nv_icmd(dev, 0x0000091e, 0x00000001); + nv_icmd(dev, 0x0000091f, 0x00000001); + nv_icmd(dev, 0x00000920, 0x00000002); + nv_icmd(dev, 0x00000921, 0x00000002); + nv_icmd(dev, 0x00000922, 0x00000002); + nv_icmd(dev, 0x00000923, 0x00000002); + nv_icmd(dev, 0x00000924, 0x00000002); + nv_icmd(dev, 0x00000925, 0x00000002); + nv_icmd(dev, 0x00000926, 0x00000002); + nv_icmd(dev, 0x00000927, 0x00000002); + nv_icmd(dev, 0x00000928, 0x00000001); + nv_icmd(dev, 0x00000929, 0x00000001); + nv_icmd(dev, 0x0000092a, 0x00000001); + nv_icmd(dev, 0x0000092b, 0x00000001); + nv_icmd(dev, 0x0000092c, 0x00000001); + nv_icmd(dev, 0x0000092d, 0x00000001); + nv_icmd(dev, 0x0000092e, 0x00000001); + nv_icmd(dev, 0x0000092f, 0x00000001); + nv_icmd(dev, 0x00000648, 0x00000001); + nv_icmd(dev, 0x00000649, 0x00000001); + nv_icmd(dev, 0x0000064a, 0x00000001); + nv_icmd(dev, 0x0000064b, 0x00000001); + nv_icmd(dev, 0x0000064c, 0x00000001); + nv_icmd(dev, 0x0000064d, 0x00000001); + nv_icmd(dev, 0x0000064e, 0x00000001); + nv_icmd(dev, 0x0000064f, 0x00000001); + nv_icmd(dev, 0x00000650, 0x00000001); + nv_icmd(dev, 0x00000658, 0x0000000f); + nv_icmd(dev, 0x000007ff, 0x0000000a); + nv_icmd(dev, 0x0000066a, 0x40000000); + nv_icmd(dev, 0x0000066b, 0x10000000); + nv_icmd(dev, 0x0000066c, 0xffff0000); + nv_icmd(dev, 0x0000066d, 0xffff0000); + nv_icmd(dev, 0x000007af, 0x00000008); + nv_icmd(dev, 0x000007b0, 0x00000008); + nv_icmd(dev, 0x000007f6, 0x00000001); + nv_icmd(dev, 0x000006b2, 0x00000055); + nv_icmd(dev, 0x000007ad, 0x00000003); + nv_icmd(dev, 0x00000937, 0x00000001); + nv_icmd(dev, 0x00000971, 0x00000008); + nv_icmd(dev, 0x00000972, 0x00000040); + nv_icmd(dev, 0x00000973, 0x0000012c); + nv_icmd(dev, 0x0000097c, 0x00000040); + nv_icmd(dev, 0x00000979, 0x00000003); + nv_icmd(dev, 0x00000975, 0x00000020); + nv_icmd(dev, 0x00000976, 0x00000001); + nv_icmd(dev, 0x00000977, 0x00000020); + nv_icmd(dev, 0x00000978, 0x00000001); + nv_icmd(dev, 0x00000957, 0x00000003); + nv_icmd(dev, 0x0000095e, 0x20164010); + nv_icmd(dev, 0x0000095f, 0x00000020); + nv_icmd(dev, 0x00000683, 0x00000006); + nv_icmd(dev, 0x00000685, 0x003fffff); + nv_icmd(dev, 0x00000687, 0x00000c48); + nv_icmd(dev, 0x000006a0, 0x00000005); + nv_icmd(dev, 0x00000840, 0x00300008); + nv_icmd(dev, 0x00000841, 0x04000080); + nv_icmd(dev, 0x00000842, 0x00300008); + nv_icmd(dev, 0x00000843, 0x04000080); + nv_icmd(dev, 0x00000818, 0x00000000); + nv_icmd(dev, 0x00000819, 0x00000000); + nv_icmd(dev, 0x0000081a, 0x00000000); + nv_icmd(dev, 0x0000081b, 0x00000000); + nv_icmd(dev, 0x0000081c, 0x00000000); + nv_icmd(dev, 0x0000081d, 0x00000000); + nv_icmd(dev, 0x0000081e, 0x00000000); + nv_icmd(dev, 0x0000081f, 0x00000000); + nv_icmd(dev, 0x00000848, 0x00000000); + nv_icmd(dev, 0x00000849, 0x00000000); + nv_icmd(dev, 0x0000084a, 0x00000000); + nv_icmd(dev, 0x0000084b, 0x00000000); + nv_icmd(dev, 0x0000084c, 0x00000000); + nv_icmd(dev, 0x0000084d, 0x00000000); + nv_icmd(dev, 0x0000084e, 0x00000000); + nv_icmd(dev, 0x0000084f, 0x00000000); + nv_icmd(dev, 0x00000850, 0x00000000); + nv_icmd(dev, 0x00000851, 0x00000000); + nv_icmd(dev, 0x00000852, 0x00000000); + nv_icmd(dev, 0x00000853, 0x00000000); + nv_icmd(dev, 0x00000854, 0x00000000); + nv_icmd(dev, 0x00000855, 0x00000000); + nv_icmd(dev, 0x00000856, 0x00000000); + nv_icmd(dev, 0x00000857, 0x00000000); + nv_icmd(dev, 0x00000738, 0x00000000); + nv_icmd(dev, 0x000006aa, 0x00000001); + nv_icmd(dev, 0x000006ab, 0x00000002); + nv_icmd(dev, 0x000006ac, 0x00000080); + nv_icmd(dev, 0x000006ad, 0x00000100); + nv_icmd(dev, 0x000006ae, 0x00000100); + nv_icmd(dev, 0x000006b1, 0x00000011); + nv_icmd(dev, 0x000006bb, 0x000000cf); + nv_icmd(dev, 0x000006ce, 0x2a712488); + nv_icmd(dev, 0x00000739, 0x4085c000); + nv_icmd(dev, 0x0000073a, 0x00000080); + nv_icmd(dev, 0x00000786, 0x80000100); + nv_icmd(dev, 0x0000073c, 0x00010100); + nv_icmd(dev, 0x0000073d, 0x02800000); + nv_icmd(dev, 0x00000787, 0x000000cf); + nv_icmd(dev, 0x0000078c, 0x00000008); + nv_icmd(dev, 0x00000792, 0x00000001); + nv_icmd(dev, 0x00000794, 0x00000001); + nv_icmd(dev, 0x00000795, 0x00000001); + nv_icmd(dev, 0x00000796, 0x00000001); + nv_icmd(dev, 0x00000797, 0x000000cf); + nv_icmd(dev, 0x00000836, 0x00000001); + nv_icmd(dev, 0x0000079a, 0x00000002); + nv_icmd(dev, 0x00000833, 0x04444480); + nv_icmd(dev, 0x000007a1, 0x00000001); + nv_icmd(dev, 0x000007a3, 0x00000001); + nv_icmd(dev, 0x000007a4, 0x00000001); + nv_icmd(dev, 0x000007a5, 0x00000001); + nv_icmd(dev, 0x00000831, 0x00000004); + nv_icmd(dev, 0x0000080c, 0x00000002); + nv_icmd(dev, 0x0000080d, 0x00000100); + nv_icmd(dev, 0x0000080e, 0x00000100); + nv_icmd(dev, 0x0000080f, 0x00000001); + nv_icmd(dev, 0x00000823, 0x00000002); + nv_icmd(dev, 0x00000824, 0x00000100); + nv_icmd(dev, 0x00000825, 0x00000100); + nv_icmd(dev, 0x00000826, 0x00000001); + nv_icmd(dev, 0x0000095d, 0x00000001); + nv_icmd(dev, 0x0000082b, 0x00000004); + nv_icmd(dev, 0x00000942, 0x00010001); + nv_icmd(dev, 0x00000943, 0x00000001); + nv_icmd(dev, 0x00000944, 0x00000022); + nv_icmd(dev, 0x000007c5, 0x00010001); + nv_icmd(dev, 0x00000834, 0x00000001); + nv_icmd(dev, 0x000007c7, 0x00000001); + nv_icmd(dev, 0x0000c1b0, 0x0000000f); + nv_icmd(dev, 0x0000c1b1, 0x0000000f); + nv_icmd(dev, 0x0000c1b2, 0x0000000f); + nv_icmd(dev, 0x0000c1b3, 0x0000000f); + nv_icmd(dev, 0x0000c1b4, 0x0000000f); + nv_icmd(dev, 0x0000c1b5, 0x0000000f); + nv_icmd(dev, 0x0000c1b6, 0x0000000f); + nv_icmd(dev, 0x0000c1b7, 0x0000000f); + nv_icmd(dev, 0x0000c1b8, 0x0fac6881); + nv_icmd(dev, 0x0000c1b9, 0x00fac688); + nv_icmd(dev, 0x0001e100, 0x00000001); + nv_icmd(dev, 0x00001000, 0x00000002); + nv_icmd(dev, 0x000006aa, 0x00000001); + nv_icmd(dev, 0x000006ad, 0x00000100); + nv_icmd(dev, 0x000006ae, 0x00000100); + nv_icmd(dev, 0x000006b1, 0x00000011); + nv_icmd(dev, 0x0000078c, 0x00000008); + nv_icmd(dev, 0x00000792, 0x00000001); + nv_icmd(dev, 0x00000794, 0x00000001); + nv_icmd(dev, 0x00000795, 0x00000001); + nv_icmd(dev, 0x00000796, 0x00000001); + nv_icmd(dev, 0x00000797, 0x000000cf); + nv_icmd(dev, 0x0000079a, 0x00000002); + nv_icmd(dev, 0x00000833, 0x04444480); + nv_icmd(dev, 0x000007a1, 0x00000001); + nv_icmd(dev, 0x000007a3, 0x00000001); + nv_icmd(dev, 0x000007a4, 0x00000001); + nv_icmd(dev, 0x000007a5, 0x00000001); + nv_icmd(dev, 0x00000831, 0x00000004); + nv_icmd(dev, 0x0001e100, 0x00000001); + nv_icmd(dev, 0x00001000, 0x00000014); + nv_icmd(dev, 0x00000351, 0x00000100); + nv_icmd(dev, 0x00000957, 0x00000003); + nv_icmd(dev, 0x0000095d, 0x00000001); + nv_icmd(dev, 0x0000082b, 0x00000004); + nv_icmd(dev, 0x00000942, 0x00010001); + nv_icmd(dev, 0x00000943, 0x00000001); + nv_icmd(dev, 0x000007c5, 0x00010001); + nv_icmd(dev, 0x00000834, 0x00000001); + nv_icmd(dev, 0x000007c7, 0x00000001); + nv_icmd(dev, 0x0001e100, 0x00000001); + nv_icmd(dev, 0x00001000, 0x00000001); + nv_icmd(dev, 0x0000080c, 0x00000002); + nv_icmd(dev, 0x0000080d, 0x00000100); + nv_icmd(dev, 0x0000080e, 0x00000100); + nv_icmd(dev, 0x0000080f, 0x00000001); + nv_icmd(dev, 0x00000823, 0x00000002); + nv_icmd(dev, 0x00000824, 0x00000100); + nv_icmd(dev, 0x00000825, 0x00000100); + nv_icmd(dev, 0x00000826, 0x00000001); + nv_icmd(dev, 0x0001e100, 0x00000001); + nv_wr32(dev, 0x400208, 0x00000000); + nv_wr32(dev, 0x404154, 0x00000400); + + nvc0_grctx_generate_9097(dev); + nvc0_grctx_generate_902d(dev); + nvc0_grctx_generate_9039(dev); + nvc0_grctx_generate_90c0(dev); + + nv_wr32(dev, 0x000260, r000260); + return 0; +} -- cgit v1.2.3 From ddbaf79a8b047dcccf766d0518626cdc0f43d58e Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 24 Nov 2010 10:52:43 +1000 Subject: drm/nvc0: implement fbcon acceleration Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/Makefile | 5 +- drivers/gpu/drm/nouveau/nouveau_fbcon.c | 24 ++- drivers/gpu/drm/nouveau/nouveau_fbcon.h | 6 + drivers/gpu/drm/nouveau/nvc0_fbcon.c | 271 ++++++++++++++++++++++++++++++++ 4 files changed, 300 insertions(+), 6 deletions(-) create mode 100644 drivers/gpu/drm/nouveau/nvc0_fbcon.c diff --git a/drivers/gpu/drm/nouveau/Makefile b/drivers/gpu/drm/nouveau/Makefile index 141771beb8e6..e12c97fd8db8 100644 --- a/drivers/gpu/drm/nouveau/Makefile +++ b/drivers/gpu/drm/nouveau/Makefile @@ -22,9 +22,10 @@ nouveau-y := nouveau_drv.o nouveau_state.o nouveau_channel.o nouveau_mem.o \ nv84_crypt.o \ nv04_instmem.o nv50_instmem.o nvc0_instmem.o \ nv50_evo.o nv50_crtc.o nv50_dac.o nv50_sor.o \ - nv50_cursor.o nv50_display.o nv50_fbcon.o \ + nv50_cursor.o nv50_display.o \ nv04_dac.o nv04_dfp.o nv04_tv.o nv17_tv.o nv17_tv_modes.o \ - nv04_crtc.o nv04_display.o nv04_cursor.o nv04_fbcon.o \ + nv04_crtc.o nv04_display.o nv04_cursor.o \ + nv04_fbcon.o nv50_fbcon.o nvc0_fbcon.o \ nv10_gpio.o nv50_gpio.o \ nv50_calc.o \ nv04_pm.o nv50_pm.o nva3_pm.o \ diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/drivers/gpu/drm/nouveau/nouveau_fbcon.c index ea861c915149..326eeda6ad7f 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fbcon.c +++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c @@ -68,6 +68,8 @@ nouveau_fbcon_fillrect(struct fb_info *info, const struct fb_fillrect *rect) else if (dev_priv->card_type < NV_C0) ret = nv50_fbcon_fillrect(info, rect); + else + ret = nvc0_fbcon_fillrect(info, rect); mutex_unlock(&dev_priv->channel->mutex); } @@ -98,6 +100,8 @@ nouveau_fbcon_copyarea(struct fb_info *info, const struct fb_copyarea *image) else if (dev_priv->card_type < NV_C0) ret = nv50_fbcon_copyarea(info, image); + else + ret = nvc0_fbcon_copyarea(info, image); mutex_unlock(&dev_priv->channel->mutex); } @@ -128,6 +132,8 @@ nouveau_fbcon_imageblit(struct fb_info *info, const struct fb_image *image) else if (dev_priv->card_type < NV_C0) ret = nv50_fbcon_imageblit(info, image); + else + ret = nvc0_fbcon_imageblit(info, image); mutex_unlock(&dev_priv->channel->mutex); } @@ -163,10 +169,18 @@ nouveau_fbcon_sync(struct fb_info *info) return 0; } - BEGIN_RING(chan, 0, 0x0104, 1); - OUT_RING(chan, 0); - BEGIN_RING(chan, 0, 0x0100, 1); - OUT_RING(chan, 0); + if (dev_priv->card_type >= NV_C0) { + BEGIN_NVC0(chan, 2, NvSub2D, 0x010c, 1); + OUT_RING (chan, 0); + BEGIN_NVC0(chan, 2, NvSub2D, 0x0100, 1); + OUT_RING (chan, 0); + } else { + BEGIN_RING(chan, 0, 0x0104, 1); + OUT_RING (chan, 0); + BEGIN_RING(chan, 0, 0x0100, 1); + OUT_RING (chan, 0); + } + nouveau_bo_wr32(chan->notifier_bo, chan->m2mf_ntfy + 3, 0xffffffff); FIRE_RING(chan); mutex_unlock(&chan->mutex); @@ -374,6 +388,8 @@ nouveau_fbcon_create(struct nouveau_fbdev *nfbdev, else if (dev_priv->card_type < NV_C0) ret = nv50_fbcon_accel_init(info); + else + ret = nvc0_fbcon_accel_init(info); if (ret == 0) info->fbops = &nouveau_fbcon_ops; diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.h b/drivers/gpu/drm/nouveau/nouveau_fbcon.h index 6b933f2c3a5b..b73c29f87fc3 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fbcon.h +++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.h @@ -44,11 +44,17 @@ int nv04_fbcon_copyarea(struct fb_info *info, const struct fb_copyarea *region); int nv04_fbcon_fillrect(struct fb_info *info, const struct fb_fillrect *rect); int nv04_fbcon_imageblit(struct fb_info *info, const struct fb_image *image); int nv04_fbcon_accel_init(struct fb_info *info); + int nv50_fbcon_fillrect(struct fb_info *info, const struct fb_fillrect *rect); int nv50_fbcon_copyarea(struct fb_info *info, const struct fb_copyarea *region); int nv50_fbcon_imageblit(struct fb_info *info, const struct fb_image *image); int nv50_fbcon_accel_init(struct fb_info *info); +int nvc0_fbcon_fillrect(struct fb_info *info, const struct fb_fillrect *rect); +int nvc0_fbcon_copyarea(struct fb_info *info, const struct fb_copyarea *region); +int nvc0_fbcon_imageblit(struct fb_info *info, const struct fb_image *image); +int nvc0_fbcon_accel_init(struct fb_info *info); + void nouveau_fbcon_gpu_lockup(struct fb_info *info); int nouveau_fbcon_init(struct drm_device *dev); diff --git a/drivers/gpu/drm/nouveau/nvc0_fbcon.c b/drivers/gpu/drm/nouveau/nvc0_fbcon.c new file mode 100644 index 000000000000..cbb4a1ae20b1 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvc0_fbcon.c @@ -0,0 +1,271 @@ +/* + * Copyright 2010 Red Hat Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: Ben Skeggs + */ + +#include "drmP.h" +#include "nouveau_drv.h" +#include "nouveau_dma.h" +#include "nouveau_ramht.h" +#include "nouveau_fbcon.h" +#include "nouveau_mm.h" + +int +nvc0_fbcon_fillrect(struct fb_info *info, const struct fb_fillrect *rect) +{ + struct nouveau_fbdev *nfbdev = info->par; + struct drm_device *dev = nfbdev->dev; + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_channel *chan = dev_priv->channel; + int ret; + + ret = RING_SPACE(chan, rect->rop == ROP_COPY ? 7 : 11); + if (ret) + return ret; + + if (rect->rop != ROP_COPY) { + BEGIN_NVC0(chan, 2, NvSub2D, 0x02ac, 1); + OUT_RING (chan, 1); + } + BEGIN_NVC0(chan, 2, NvSub2D, 0x0588, 1); + if (info->fix.visual == FB_VISUAL_TRUECOLOR || + info->fix.visual == FB_VISUAL_DIRECTCOLOR) + OUT_RING (chan, ((uint32_t *)info->pseudo_palette)[rect->color]); + else + OUT_RING (chan, rect->color); + BEGIN_NVC0(chan, 2, NvSub2D, 0x0600, 4); + OUT_RING (chan, rect->dx); + OUT_RING (chan, rect->dy); + OUT_RING (chan, rect->dx + rect->width); + OUT_RING (chan, rect->dy + rect->height); + if (rect->rop != ROP_COPY) { + BEGIN_NVC0(chan, 2, NvSub2D, 0x02ac, 1); + OUT_RING (chan, 3); + } + FIRE_RING(chan); + return 0; +} + +int +nvc0_fbcon_copyarea(struct fb_info *info, const struct fb_copyarea *region) +{ + struct nouveau_fbdev *nfbdev = info->par; + struct drm_device *dev = nfbdev->dev; + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_channel *chan = dev_priv->channel; + int ret; + + ret = RING_SPACE(chan, 12); + if (ret) + return ret; + + BEGIN_NVC0(chan, 2, NvSub2D, 0x0110, 1); + OUT_RING (chan, 0); + BEGIN_NVC0(chan, 2, NvSub2D, 0x08b0, 4); + OUT_RING (chan, region->dx); + OUT_RING (chan, region->dy); + OUT_RING (chan, region->width); + OUT_RING (chan, region->height); + BEGIN_NVC0(chan, 2, NvSub2D, 0x08d0, 4); + OUT_RING (chan, 0); + OUT_RING (chan, region->sx); + OUT_RING (chan, 0); + OUT_RING (chan, region->sy); + FIRE_RING(chan); + return 0; +} + +int +nvc0_fbcon_imageblit(struct fb_info *info, const struct fb_image *image) +{ + struct nouveau_fbdev *nfbdev = info->par; + struct drm_device *dev = nfbdev->dev; + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_channel *chan = dev_priv->channel; + uint32_t width, dwords, *data = (uint32_t *)image->data; + uint32_t mask = ~(~0 >> (32 - info->var.bits_per_pixel)); + uint32_t *palette = info->pseudo_palette; + int ret; + + if (image->depth != 1) + return -ENODEV; + + ret = RING_SPACE(chan, 11); + if (ret) + return ret; + + width = ALIGN(image->width, 32); + dwords = (width * image->height) >> 5; + + BEGIN_NVC0(chan, 2, NvSub2D, 0x0814, 2); + if (info->fix.visual == FB_VISUAL_TRUECOLOR || + info->fix.visual == FB_VISUAL_DIRECTCOLOR) { + OUT_RING (chan, palette[image->bg_color] | mask); + OUT_RING (chan, palette[image->fg_color] | mask); + } else { + OUT_RING (chan, image->bg_color); + OUT_RING (chan, image->fg_color); + } + BEGIN_NVC0(chan, 2, NvSub2D, 0x0838, 2); + OUT_RING (chan, image->width); + OUT_RING (chan, image->height); + BEGIN_NVC0(chan, 2, NvSub2D, 0x0850, 4); + OUT_RING (chan, 0); + OUT_RING (chan, image->dx); + OUT_RING (chan, 0); + OUT_RING (chan, image->dy); + + while (dwords) { + int push = dwords > 2047 ? 2047 : dwords; + + ret = RING_SPACE(chan, push + 1); + if (ret) + return ret; + + dwords -= push; + + BEGIN_NVC0(chan, 6, NvSub2D, 0x0860, push); + OUT_RINGp(chan, data, push); + data += push; + } + + FIRE_RING(chan); + return 0; +} + +int +nvc0_fbcon_accel_init(struct fb_info *info) +{ + struct nouveau_fbdev *nfbdev = info->par; + struct drm_device *dev = nfbdev->dev; + struct drm_nouveau_private *dev_priv = dev->dev_private; + struct nouveau_channel *chan = dev_priv->channel; + struct nouveau_bo *nvbo = nfbdev->nouveau_fb.nvbo; + int ret, format; + + ret = nouveau_gpuobj_gr_new(chan, 0x902d, 0x902d); + if (ret) + return ret; + + switch (info->var.bits_per_pixel) { + case 8: + format = 0xf3; + break; + case 15: + format = 0xf8; + break; + case 16: + format = 0xe8; + break; + case 32: + switch (info->var.transp.length) { + case 0: /* depth 24 */ + case 8: /* depth 32, just use 24.. */ + format = 0xe6; + break; + case 2: /* depth 30 */ + format = 0xd1; + break; + default: + return -EINVAL; + } + break; + default: + return -EINVAL; + } + + ret = RING_SPACE(chan, 60); + if (ret) { + WARN_ON(1); + nouveau_fbcon_gpu_lockup(info); + return ret; + } + + printk(KERN_ERR "fb vma 0x%010llx\n", nvbo->vma.offset); + + BEGIN_NVC0(chan, 2, NvSub2D, 0x0000, 1); + OUT_RING (chan, 0x0000902d); + BEGIN_NVC0(chan, 2, NvSub2D, 0x0104, 2); + OUT_RING (chan, upper_32_bits(chan->notifier_bo->bo.offset)); + OUT_RING (chan, lower_32_bits(chan->notifier_bo->bo.offset)); + BEGIN_NVC0(chan, 2, NvSub2D, 0x0290, 1); + OUT_RING (chan, 0); + BEGIN_NVC0(chan, 2, NvSub2D, 0x0888, 1); + OUT_RING (chan, 1); + BEGIN_NVC0(chan, 2, NvSub2D, 0x02ac, 1); + OUT_RING (chan, 3); + BEGIN_NVC0(chan, 2, NvSub2D, 0x02a0, 1); + OUT_RING (chan, 0x55); + BEGIN_NVC0(chan, 2, NvSub2D, 0x08c0, 4); + OUT_RING (chan, 0); + OUT_RING (chan, 1); + OUT_RING (chan, 0); + OUT_RING (chan, 1); + BEGIN_NVC0(chan, 2, NvSub2D, 0x0580, 2); + OUT_RING (chan, 4); + OUT_RING (chan, format); + BEGIN_NVC0(chan, 2, NvSub2D, 0x02e8, 2); + OUT_RING (chan, 2); + OUT_RING (chan, 1); + + BEGIN_NVC0(chan, 2, NvSub2D, 0x0804, 1); + OUT_RING (chan, format); + BEGIN_NVC0(chan, 2, NvSub2D, 0x0800, 1); + OUT_RING (chan, 1); + BEGIN_NVC0(chan, 2, NvSub2D, 0x0808, 3); + OUT_RING (chan, 0); + OUT_RING (chan, 0); + OUT_RING (chan, 1); + BEGIN_NVC0(chan, 2, NvSub2D, 0x081c, 1); + OUT_RING (chan, 1); + BEGIN_NVC0(chan, 2, NvSub2D, 0x0840, 4); + OUT_RING (chan, 0); + OUT_RING (chan, 1); + OUT_RING (chan, 0); + OUT_RING (chan, 1); + BEGIN_NVC0(chan, 2, NvSub2D, 0x0200, 10); + OUT_RING (chan, format); + OUT_RING (chan, 1); + OUT_RING (chan, 0); + OUT_RING (chan, 1); + OUT_RING (chan, 0); + OUT_RING (chan, info->fix.line_length); + OUT_RING (chan, info->var.xres_virtual); + OUT_RING (chan, info->var.yres_virtual); + OUT_RING (chan, upper_32_bits(nvbo->vma.offset)); + OUT_RING (chan, lower_32_bits(nvbo->vma.offset)); + BEGIN_NVC0(chan, 2, NvSub2D, 0x0230, 10); + OUT_RING (chan, format); + OUT_RING (chan, 1); + OUT_RING (chan, 0); + OUT_RING (chan, 1); + OUT_RING (chan, 0); + OUT_RING (chan, info->fix.line_length); + OUT_RING (chan, info->var.xres_virtual); + OUT_RING (chan, info->var.yres_virtual); + OUT_RING (chan, upper_32_bits(nvbo->vma.offset)); + OUT_RING (chan, lower_32_bits(nvbo->vma.offset)); + FIRE_RING (chan); + + return 0; +} + -- cgit v1.2.3 From 6d86951a45013ac5b060c5e6307b11b7c685c76f Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 8 Dec 2010 11:19:30 +1000 Subject: drm/nvc0: initial support for tiled buffer objects Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_bo.c | 3 -- drivers/gpu/drm/nouveau/nouveau_dma.h | 3 +- drivers/gpu/drm/nouveau/nv50_crtc.c | 18 +++++++----- drivers/gpu/drm/nouveau/nv50_evo.c | 53 ++++++++++++++++++++++++++--------- drivers/gpu/drm/nouveau/nvc0_vram.c | 10 ++++++- 5 files changed, 62 insertions(+), 25 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index 5dc639e0c969..74d0ef41118d 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c @@ -120,9 +120,6 @@ nouveau_bo_new(struct drm_device *dev, struct nouveau_channel *chan, align >>= PAGE_SHIFT; if (!nvbo->no_vm && dev_priv->chan_vm) { - if (dev_priv->card_type == NV_C0) - page_shift = 12; - ret = nouveau_vm_get(dev_priv->chan_vm, size, page_shift, NV_MEM_ACCESS_RW, &nvbo->vma); if (ret) { diff --git a/drivers/gpu/drm/nouveau/nouveau_dma.h b/drivers/gpu/drm/nouveau/nouveau_dma.h index c118a331b5bc..c36f1763feaa 100644 --- a/drivers/gpu/drm/nouveau/nouveau_dma.h +++ b/drivers/gpu/drm/nouveau/nouveau_dma.h @@ -77,7 +77,8 @@ enum { /* G80+ display objects */ NvEvoVRAM = 0x01000000, NvEvoFB16 = 0x01000001, - NvEvoFB32 = 0x01000002 + NvEvoFB32 = 0x01000002, + NvEvoVRAM_LP = 0x01000003 }; #define NV_MEMORY_TO_MEMORY_FORMAT 0x00000039 diff --git a/drivers/gpu/drm/nouveau/nv50_crtc.c b/drivers/gpu/drm/nouveau/nv50_crtc.c index 2c346f797285..9023c4dbb449 100644 --- a/drivers/gpu/drm/nouveau/nv50_crtc.c +++ b/drivers/gpu/drm/nouveau/nv50_crtc.c @@ -115,15 +115,16 @@ nv50_crtc_blank(struct nouveau_crtc *nv_crtc, bool blanked) OUT_RING(evo, 0); BEGIN_RING(evo, 0, NV50_EVO_CRTC(index, FB_DMA), 1); if (dev_priv->chipset != 0x50) - if (nv_crtc->fb.tile_flags == 0x7a00) + if (nv_crtc->fb.tile_flags == 0x7a00 || + nv_crtc->fb.tile_flags == 0xfe00) OUT_RING(evo, NvEvoFB32); else if (nv_crtc->fb.tile_flags == 0x7000) OUT_RING(evo, NvEvoFB16); else - OUT_RING(evo, NvEvoVRAM); + OUT_RING(evo, NvEvoVRAM_LP); else - OUT_RING(evo, NvEvoVRAM); + OUT_RING(evo, NvEvoVRAM_LP); } nv_crtc->fb.blanked = blanked; @@ -555,13 +556,14 @@ nv50_crtc_do_mode_set_base(struct drm_crtc *crtc, return ret; BEGIN_RING(evo, 0, NV50_EVO_CRTC(nv_crtc->index, FB_DMA), 1); - if (nv_crtc->fb.tile_flags == 0x7a00) + if (nv_crtc->fb.tile_flags == 0x7a00 || + nv_crtc->fb.tile_flags == 0xfe00) OUT_RING(evo, NvEvoFB32); else if (nv_crtc->fb.tile_flags == 0x7000) OUT_RING(evo, NvEvoFB16); else - OUT_RING(evo, NvEvoVRAM); + OUT_RING(evo, NvEvoVRAM_LP); } ret = RING_SPACE(evo, 12); @@ -575,8 +577,10 @@ nv50_crtc_do_mode_set_base(struct drm_crtc *crtc, if (!nv_crtc->fb.tile_flags) { OUT_RING(evo, drm_fb->pitch | (1 << 20)); } else { - OUT_RING(evo, ((drm_fb->pitch / 4) << 4) | - fb->nvbo->tile_mode); + u32 tile_mode = fb->nvbo->tile_mode; + if (dev_priv->card_type >= NV_C0) + tile_mode >>= 4; + OUT_RING(evo, ((drm_fb->pitch / 4) << 4) | tile_mode); } if (dev_priv->chipset == 0x50) OUT_RING(evo, (nv_crtc->fb.tile_flags << 8) | format); diff --git a/drivers/gpu/drm/nouveau/nv50_evo.c b/drivers/gpu/drm/nouveau/nv50_evo.c index 887b2a97e2a2..14e24e906ee8 100644 --- a/drivers/gpu/drm/nouveau/nv50_evo.c +++ b/drivers/gpu/drm/nouveau/nv50_evo.c @@ -53,7 +53,8 @@ nv50_evo_channel_del(struct nouveau_channel **pevo) int nv50_evo_dmaobj_new(struct nouveau_channel *evo, u32 class, u32 name, - u32 tile_flags, u32 magic_flags, u32 offset, u32 limit) + u32 tile_flags, u32 magic_flags, u32 offset, u32 limit, + u32 flags5) { struct drm_nouveau_private *dev_priv = evo->dev->dev_private; struct drm_device *dev = evo->dev; @@ -70,10 +71,7 @@ nv50_evo_dmaobj_new(struct nouveau_channel *evo, u32 class, u32 name, nv_wo32(obj, 8, offset); nv_wo32(obj, 12, 0x00000000); nv_wo32(obj, 16, 0x00000000); - if (dev_priv->card_type < NV_C0) - nv_wo32(obj, 20, 0x00010000); - else - nv_wo32(obj, 20, 0x00020000); + nv_wo32(obj, 20, flags5); dev_priv->engine.instmem.flush(dev); ret = nouveau_ramht_insert(evo, name, obj); @@ -264,9 +262,31 @@ nv50_evo_create(struct drm_device *dev) } /* create some default objects for the scanout memtypes we support */ + if (dev_priv->card_type >= NV_C0) { + ret = nv50_evo_dmaobj_new(evo, 0x3d, NvEvoFB32, 0xfe, 0x19, + 0, 0xffffffff, 0x00000000); + if (ret) { + nv50_evo_channel_del(&dev_priv->evo); + return ret; + } + + ret = nv50_evo_dmaobj_new(evo, 0x3d, NvEvoVRAM, 0, 0x19, + 0, dev_priv->vram_size, 0x00020000); + if (ret) { + nv50_evo_channel_del(&dev_priv->evo); + return ret; + } + + ret = nv50_evo_dmaobj_new(evo, 0x3d, NvEvoVRAM_LP, 0, 0x19, + 0, dev_priv->vram_size, 0x00000000); + if (ret) { + nv50_evo_channel_del(&dev_priv->evo); + return ret; + } + } else if (dev_priv->chipset != 0x50) { ret = nv50_evo_dmaobj_new(evo, 0x3d, NvEvoFB16, 0x70, 0x19, - 0, 0xffffffff); + 0, 0xffffffff, 0x00010000); if (ret) { nv50_evo_channel_del(&dev_priv->evo); return ret; @@ -274,18 +294,25 @@ nv50_evo_create(struct drm_device *dev) ret = nv50_evo_dmaobj_new(evo, 0x3d, NvEvoFB32, 0x7a, 0x19, - 0, 0xffffffff); + 0, 0xffffffff, 0x00010000); if (ret) { nv50_evo_channel_del(&dev_priv->evo); return ret; } - } - ret = nv50_evo_dmaobj_new(evo, 0x3d, NvEvoVRAM, 0, 0x19, - 0, dev_priv->vram_size); - if (ret) { - nv50_evo_channel_del(&dev_priv->evo); - return ret; + ret = nv50_evo_dmaobj_new(evo, 0x3d, NvEvoVRAM, 0, 0x19, + 0, dev_priv->vram_size, 0x00010000); + if (ret) { + nv50_evo_channel_del(&dev_priv->evo); + return ret; + } + + ret = nv50_evo_dmaobj_new(evo, 0x3d, NvEvoVRAM_LP, 0, 0x19, + 0, dev_priv->vram_size, 0x00010000); + if (ret) { + nv50_evo_channel_del(&dev_priv->evo); + return ret; + } } return 0; diff --git a/drivers/gpu/drm/nouveau/nvc0_vram.c b/drivers/gpu/drm/nouveau/nvc0_vram.c index 41fcae5ffba4..858eda5dedd1 100644 --- a/drivers/gpu/drm/nouveau/nvc0_vram.c +++ b/drivers/gpu/drm/nouveau/nvc0_vram.c @@ -29,8 +29,16 @@ bool nvc0_vram_flags_valid(struct drm_device *dev, u32 tile_flags) { - if (likely(!(tile_flags & NOUVEAU_GEM_TILE_LAYOUT_MASK))) + switch (tile_flags & NOUVEAU_GEM_TILE_LAYOUT_MASK) { + case 0x0000: + case 0xfe00: + case 0xdb00: + case 0x1100: return true; + default: + break; + } + return false; } -- cgit v1.2.3 From 183720b8af5301e2eab7f3163f03133c5a6ad6da Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Thu, 9 Dec 2010 15:17:10 +1000 Subject: drm/nvc0: accelerate ttm buffer moves Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_bo.c | 57 +++++++++++++++++++++++++++++++++++- 1 file changed, 56 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index 74d0ef41118d..a7fae26f4654 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c @@ -514,6 +514,58 @@ nouveau_bo_mem_ctxdma(struct ttm_buffer_object *bo, return chan->vram_handle; } +static int +nvc0_bo_move_m2mf(struct nouveau_channel *chan, struct ttm_buffer_object *bo, + struct ttm_mem_reg *old_mem, struct ttm_mem_reg *new_mem) +{ + struct drm_nouveau_private *dev_priv = nouveau_bdev(bo->bdev); + struct nouveau_bo *nvbo = nouveau_bo(bo); + u64 src_offset = old_mem->start << PAGE_SHIFT; + u64 dst_offset = new_mem->start << PAGE_SHIFT; + u32 page_count = new_mem->num_pages; + int ret; + + if (!nvbo->no_vm) { + if (old_mem->mem_type == TTM_PL_VRAM) + src_offset = nvbo->vma.offset; + else + src_offset += dev_priv->gart_info.aper_base; + + if (new_mem->mem_type == TTM_PL_VRAM) + dst_offset = nvbo->vma.offset; + else + dst_offset += dev_priv->gart_info.aper_base; + } + + page_count = new_mem->num_pages; + while (page_count) { + int line_count = (page_count > 2047) ? 2047 : page_count; + + ret = RING_SPACE(chan, 12); + if (ret) + return ret; + + BEGIN_NVC0(chan, 2, NvSubM2MF, 0x0238, 2); + OUT_RING (chan, upper_32_bits(dst_offset)); + OUT_RING (chan, lower_32_bits(dst_offset)); + BEGIN_NVC0(chan, 2, NvSubM2MF, 0x030c, 6); + OUT_RING (chan, upper_32_bits(src_offset)); + OUT_RING (chan, lower_32_bits(src_offset)); + OUT_RING (chan, PAGE_SIZE); /* src_pitch */ + OUT_RING (chan, PAGE_SIZE); /* dst_pitch */ + OUT_RING (chan, PAGE_SIZE); /* line_length */ + OUT_RING (chan, line_count); + BEGIN_NVC0(chan, 2, NvSubM2MF, 0x0300, 1); + OUT_RING (chan, 0x00100110); + + page_count -= line_count; + src_offset += (PAGE_SIZE * line_count); + dst_offset += (PAGE_SIZE * line_count); + } + + return 0; +} + static int nv50_bo_move_m2mf(struct nouveau_channel *chan, struct ttm_buffer_object *bo, struct ttm_mem_reg *old_mem, struct ttm_mem_reg *new_mem) @@ -690,7 +742,10 @@ nouveau_bo_move_m2mf(struct ttm_buffer_object *bo, int evict, bool intr, if (dev_priv->card_type < NV_50) ret = nv04_bo_move_m2mf(chan, bo, &bo->mem, new_mem); else + if (dev_priv->card_type < NV_C0) ret = nv50_bo_move_m2mf(chan, bo, &bo->mem, new_mem); + else + ret = nvc0_bo_move_m2mf(chan, bo, &bo->mem, new_mem); if (ret == 0) { ret = nouveau_bo_move_accel_cleanup(chan, nvbo, evict, no_wait_reserve, @@ -836,7 +891,7 @@ nouveau_bo_move(struct ttm_buffer_object *bo, bool evict, bool intr, } /* Software copy if the card isn't up and running yet. */ - if (!dev_priv->channel || dev_priv->card_type == NV_C0) { + if (!dev_priv->channel) { ret = ttm_bo_move_memcpy(bo, evict, no_wait_reserve, no_wait_gpu, new_mem); goto out; } -- cgit v1.2.3 From 0686952458780e8a29d5a75dea03472fe2302c5a Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Tue, 21 Dec 2010 22:22:40 +1100 Subject: crypto: af_alg - fix af_alg memory_allocated data type Change data type to fix warning: crypto/af_alg.c:35: warning: initialization from incompatible pointer type Signed-off-by: Randy Dunlap Signed-off-by: Herbert Xu --- crypto/af_alg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crypto/af_alg.c b/crypto/af_alg.c index bd9e53c78026..940d70cb5c25 100644 --- a/crypto/af_alg.c +++ b/crypto/af_alg.c @@ -27,7 +27,7 @@ struct alg_type_list { struct list_head list; }; -static atomic_t alg_memory_allocated; +static atomic_long_t alg_memory_allocated; static struct proto alg_proto = { .name = "ALG", -- cgit v1.2.3 From 0bb140f8d94dd683fab248a3216dd5d0e792d41f Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Mon, 20 Dec 2010 20:53:25 +0000 Subject: ASoC: Remove some unused defines from WM8903 These would have been used if we'd done manual clock divider setup, but we didn't. Signed-off-by: Mark Brown Acked-by: Liam Girdwood --- sound/soc/codecs/wm8903.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/sound/soc/codecs/wm8903.h b/sound/soc/codecs/wm8903.h index 996435e681e5..e47b8c8be921 100644 --- a/sound/soc/codecs/wm8903.h +++ b/sound/soc/codecs/wm8903.h @@ -19,10 +19,6 @@ extern int wm8903_mic_detect(struct snd_soc_codec *codec, struct snd_soc_jack *jack, int det, int shrt); -#define WM8903_MCLK_DIV_2 1 -#define WM8903_CLK_SYS 2 -#define WM8903_BCLK 3 -#define WM8903_LRCLK 4 /* * Register values. -- cgit v1.2.3 From 458350b31f4f7a4d1db0c268cf1cced5afeeb8a5 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Mon, 20 Dec 2010 14:35:09 +0000 Subject: ASoC: Fix WM8994/58 3D stereo control definitions Cut'n'paste in the register names. Signed-off-by: Mark Brown Acked-by: Liam Girdwood --- sound/soc/codecs/wm8994.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index af104acd75f8..e1a775bd83fa 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c @@ -869,15 +869,15 @@ SOC_SINGLE_TLV("SPKR DAC1 Volume", WM8994_SPKMIXR_ATTENUATION, SOC_SINGLE_TLV("AIF1DAC1 3D Stereo Volume", WM8994_AIF1_DAC1_FILTERS_2, 10, 15, 0, wm8994_3d_tlv), -SOC_SINGLE("AIF1DAC1 3D Stereo Switch", WM8994_AIF1_DAC2_FILTERS_2, +SOC_SINGLE("AIF1DAC1 3D Stereo Switch", WM8994_AIF1_DAC1_FILTERS_2, 8, 1, 0), SOC_SINGLE_TLV("AIF1DAC2 3D Stereo Volume", WM8994_AIF1_DAC2_FILTERS_2, 10, 15, 0, wm8994_3d_tlv), SOC_SINGLE("AIF1DAC2 3D Stereo Switch", WM8994_AIF1_DAC2_FILTERS_2, 8, 1, 0), -SOC_SINGLE_TLV("AIF2DAC 3D Stereo Volume", WM8994_AIF1_DAC1_FILTERS_2, +SOC_SINGLE_TLV("AIF2DAC 3D Stereo Volume", WM8994_AIF2_DAC_FILTERS_2, 10, 15, 0, wm8994_3d_tlv), -SOC_SINGLE("AIF2DAC 3D Stereo Switch", WM8994_AIF1_DAC2_FILTERS_2, +SOC_SINGLE("AIF2DAC 3D Stereo Switch", WM8994_AIF2_DAC_FILTERS_2, 8, 1, 0), }; -- cgit v1.2.3 From 27667c996f6a0bed4ad1e10ac0a0dbb6037968db Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Tue, 21 Dec 2010 15:07:45 +0100 Subject: block: Clean up exit_io_context() source code. This patch fixes a spelling error in a source code comment and removes superfluous braces in the function exit_io_context(). Signed-off-by: Bart Van Assche Cc: Jens Axboe Signed-off-by: Jens Axboe --- block/blk-ioc.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/block/blk-ioc.c b/block/blk-ioc.c index 3c7a339fe381..b791022beef3 100644 --- a/block/blk-ioc.c +++ b/block/blk-ioc.c @@ -64,7 +64,7 @@ static void cfq_exit(struct io_context *ioc) rcu_read_unlock(); } -/* Called by the exitting task */ +/* Called by the exiting task */ void exit_io_context(struct task_struct *task) { struct io_context *ioc; @@ -74,10 +74,9 @@ void exit_io_context(struct task_struct *task) task->io_context = NULL; task_unlock(task); - if (atomic_dec_and_test(&ioc->nr_tasks)) { + if (atomic_dec_and_test(&ioc->nr_tasks)) cfq_exit(ioc); - } put_io_context(ioc); } -- cgit v1.2.3 From c8b031ebc1246d42463c5c69df8f610ca9f48e77 Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Thu, 9 Dec 2010 15:53:28 +0100 Subject: NFS: Remove redundant unlikely() IS_ERR() already implies unlikely(), so it can be omitted here. Signed-off-by: Tobias Klauser Signed-off-by: Trond Myklebust --- fs/nfs/mount_clnt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/nfs/mount_clnt.c b/fs/nfs/mount_clnt.c index 697e07235f30..d4c2d6b7507e 100644 --- a/fs/nfs/mount_clnt.c +++ b/fs/nfs/mount_clnt.c @@ -246,7 +246,7 @@ void nfs_umount(const struct nfs_mount_request *info) args.flags |= RPC_CLNT_CREATE_NONPRIVPORT; clnt = rpc_create(&args); - if (unlikely(IS_ERR(clnt))) + if (IS_ERR(clnt)) goto out_clnt_err; dprintk("NFS: sending UMNT request for %s:%s\n", -- cgit v1.2.3 From 72895b1ac7baeda76835cddb3edb019a90d32bcb Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Thu, 9 Dec 2010 23:17:15 +0100 Subject: nfs: Take advantage of kmem_cache_zalloc() in nfs_page_alloc() Take advantage of kmem_cache_zalloc() in nfs_page_alloc(). Save a call to memset() and a few bytes. Before: [jj@dragon linux-2.6]$ size fs/nfs/pagelist.o text data bss dec hex filename 1765 0 8 1773 6ed fs/nfs/pagelist.o After: [jj@dragon linux-2.6]$ size fs/nfs/pagelist.o text data bss dec hex filename 1749 0 8 1757 6dd fs/nfs/pagelist.o Signed-off-by: Jesper Juhl Signed-off-by: Trond Myklebust --- fs/nfs/pagelist.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/fs/nfs/pagelist.c b/fs/nfs/pagelist.c index b68536cc9046..e1164e3f9e69 100644 --- a/fs/nfs/pagelist.c +++ b/fs/nfs/pagelist.c @@ -26,12 +26,9 @@ static struct kmem_cache *nfs_page_cachep; static inline struct nfs_page * nfs_page_alloc(void) { - struct nfs_page *p; - p = kmem_cache_alloc(nfs_page_cachep, GFP_KERNEL); - if (p) { - memset(p, 0, sizeof(*p)); + struct nfs_page *p = kmem_cache_zalloc(nfs_page_cachep, GFP_KERNEL); + if (p) INIT_LIST_HEAD(&p->wb_list); - } return p; } -- cgit v1.2.3 From 611c96c8f728c4bcdbadaa2387942d3c0641cadf Mon Sep 17 00:00:00 2001 From: "J. Bruce Fields" Date: Mon, 13 Dec 2010 19:05:46 -0500 Subject: nfs4: fix units bug causing hang on recovery Note that cl_lease_time is in jiffies. This can cause a very long wait in the NFS4ERR_CLID_INUSE case. Signed-off-by: J. Bruce Fields Signed-off-by: Trond Myklebust --- fs/nfs/nfs4proc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 4435e5e1f904..494c68739ff4 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -3517,7 +3517,7 @@ int nfs4_proc_setclientid(struct nfs_client *clp, u32 program, if (signalled()) break; if (loop++ & 1) - ssleep(clp->cl_lease_time + 1); + ssleep(clp->cl_lease_time / HZ + 1); else if (++clp->cl_id_uniquifier == 0) break; -- cgit v1.2.3 From aa69947399a119d7f1b35bbcd62c849839b35449 Mon Sep 17 00:00:00 2001 From: Stanislav Kinsbursky Date: Wed, 8 Dec 2010 12:40:13 +0300 Subject: NFS: suppressing showing of default mount port value in /proc fixed Update: added check for zero value as it was before (note: can't simply check mountd_port for positive value because it's typeof unsigned short) Default value for mount server port is set to NFS_UNSPEC_PORT (-1) and will not be changed during parsing mount options for mound data version 6. This default value will be showed for mountport in /proc/mounts always since current default check is for zero value. This small mistake leads to big problem, because during umount.nfs execution from old user-space utils (at least nfs-utils 1.0.9) this value will be used as the server port to connect to. This request will be rejected (since port is 65535) and thus nfs mount point can't be unmounted. Note from Chuck Lever (chuck.lever@oracle.com): this is only possible if /etc/mtab is a link to /proc/mounts. Not all systems have this configuration. Signed-off-by: Stanislav Kinsbursky Signed-off-by: Trond Myklebust --- fs/nfs/super.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/fs/nfs/super.c b/fs/nfs/super.c index 4100630c9a5b..dd56eec16eac 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c @@ -598,7 +598,9 @@ static void nfs_show_mountd_options(struct seq_file *m, struct nfs_server *nfss, if (nfss->mountd_version || showdefaults) seq_printf(m, ",mountvers=%u", nfss->mountd_version); - if (nfss->mountd_port || showdefaults) + if ((nfss->mountd_port && + nfss->mountd_port != (unsigned short)NFS_UNSPEC_PORT) || + showdefaults) seq_printf(m, ",mountport=%u", nfss->mountd_port); nfs_show_mountd_netid(m, nfss, showdefaults); -- cgit v1.2.3 From b3bcedadf23264c3b7afcbfbfe1965a17ef1352c Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Tue, 21 Dec 2010 10:52:24 -0500 Subject: net/sunrpc/clnt.c: Convert sprintf_symbol to %ps Signed-off-by: Joe Perches Signed-off-by: Trond Myklebust --- net/sunrpc/clnt.c | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/net/sunrpc/clnt.c b/net/sunrpc/clnt.c index 4e8210dcda72..57d344cf2256 100644 --- a/net/sunrpc/clnt.c +++ b/net/sunrpc/clnt.c @@ -1829,23 +1829,15 @@ static void rpc_show_task(const struct rpc_clnt *clnt, const struct rpc_task *task) { const char *rpc_waitq = "none"; - char *p, action[KSYM_SYMBOL_LEN]; if (RPC_IS_QUEUED(task)) rpc_waitq = rpc_qname(task->tk_waitqueue); - /* map tk_action pointer to a function name; then trim off - * the "+0x0 [sunrpc]" */ - sprint_symbol(action, (unsigned long)task->tk_action); - p = strchr(action, '+'); - if (p) - *p = '\0'; - - printk(KERN_INFO "%5u %04x %6d %8p %8p %8ld %8p %sv%u %s a:%s q:%s\n", + printk(KERN_INFO "%5u %04x %6d %8p %8p %8ld %8p %sv%u %s a:%ps q:%s\n", task->tk_pid, task->tk_flags, task->tk_status, clnt, task->tk_rqstp, task->tk_timeout, task->tk_ops, clnt->cl_protname, clnt->cl_vers, rpc_proc_name(task), - action, rpc_waitq); + task->tk_action, rpc_waitq); } void rpc_show_tasks(void) -- cgit v1.2.3 From 1174dd1f890b7f8be8ec6a7071657fe8f59e18b7 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Tue, 21 Dec 2010 10:52:24 -0500 Subject: NFSv4: Convert a few commas into semicolons... Signed-off-by: Trond Myklebust --- fs/nfs/nfs4proc.c | 16 ++++++++-------- fs/nfs/unlink.c | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 494c68739ff4..78b08993a38b 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -1984,8 +1984,8 @@ int nfs4_do_close(struct path *path, struct nfs4_state *state, gfp_t gfp_mask, i path_get(path); calldata->path = *path; - msg.rpc_argp = &calldata->arg, - msg.rpc_resp = &calldata->res, + msg.rpc_argp = &calldata->arg; + msg.rpc_resp = &calldata->res; task_setup_data.callback_data = calldata; task = rpc_run_task(&task_setup_data); if (IS_ERR(task)) @@ -3663,8 +3663,8 @@ static int _nfs4_proc_delegreturn(struct inode *inode, struct rpc_cred *cred, co data->rpc_status = 0; task_setup_data.callback_data = data; - msg.rpc_argp = &data->args, - msg.rpc_resp = &data->res, + msg.rpc_argp = &data->args; + msg.rpc_resp = &data->res; task = rpc_run_task(&task_setup_data); if (IS_ERR(task)) return PTR_ERR(task); @@ -3908,8 +3908,8 @@ static struct rpc_task *nfs4_do_unlck(struct file_lock *fl, return ERR_PTR(-ENOMEM); } - msg.rpc_argp = &data->arg, - msg.rpc_resp = &data->res, + msg.rpc_argp = &data->arg; + msg.rpc_resp = &data->res; task_setup_data.callback_data = data; return rpc_run_task(&task_setup_data); } @@ -4145,8 +4145,8 @@ static int _nfs4_do_setlk(struct nfs4_state *state, int cmd, struct file_lock *f data->arg.reclaim = NFS_LOCK_RECLAIM; task_setup_data.callback_ops = &nfs4_recover_lock_ops; } - msg.rpc_argp = &data->arg, - msg.rpc_resp = &data->res, + msg.rpc_argp = &data->arg; + msg.rpc_resp = &data->res; task_setup_data.callback_data = data; task = rpc_run_task(&task_setup_data); if (IS_ERR(task)) diff --git a/fs/nfs/unlink.c b/fs/nfs/unlink.c index 7bdec8531400..3bf1e53c4a3f 100644 --- a/fs/nfs/unlink.c +++ b/fs/nfs/unlink.c @@ -429,7 +429,7 @@ nfs_async_rename(struct inode *old_dir, struct inode *new_dir, data = kzalloc(sizeof(*data), GFP_KERNEL); if (data == NULL) return ERR_PTR(-ENOMEM); - task_setup_data.callback_data = data, + task_setup_data.callback_data = data; data->cred = rpc_lookup_cred(); if (IS_ERR(data->cred)) { -- cgit v1.2.3 From 1137c56b7420c801147e0863845c03b07554721a Mon Sep 17 00:00:00 2001 From: Arnaud Lacombe Date: Sun, 26 Sep 2010 16:24:08 -0400 Subject: kconfig: simplify select-with-unmet-direct-dependency warning This is an attempt to simplify the expressing printed by kconfig when a symbol is selected but still has direct unmet dependency. First, the symbol reverse dependency is split in sub-expression. Then, each sub-expression is checked to ensure that it does not contains the unmet dependency. This removes the false-positive symbols and fixed symbol which already have the correct dependency. Finally, only the symbol responsible of the "select" is printed, instead of its full dependency tree. CC: Catalin Marinas Signed-off-by: Arnaud Lacombe Signed-off-by: Michal Marek --- scripts/kconfig/expr.c | 42 ++++++++++++++++++++++++++++++++++++++++++ scripts/kconfig/symbol.c | 6 +++++- 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/scripts/kconfig/expr.c b/scripts/kconfig/expr.c index 330e7c0048a8..65531a7f28a8 100644 --- a/scripts/kconfig/expr.c +++ b/scripts/kconfig/expr.c @@ -1013,6 +1013,48 @@ int expr_compare_type(enum expr_type t1, enum expr_type t2) #endif } +static inline struct expr * +expr_get_leftmost_symbol(const struct expr *e) +{ + + if (e == NULL) + return NULL; + + while (e->type != E_SYMBOL) + e = e->left.expr; + + return expr_copy(e); +} + +/* + * Given expression `e1' and `e2', returns the leaf of the longest + * sub-expression of `e1' not containing 'e2. + */ +struct expr *expr_simplify_unmet_dep(struct expr *e1, struct expr *e2) +{ + struct expr *ret; + + switch (e1->type) { + case E_OR: + return expr_alloc_and( + expr_simplify_unmet_dep(e1->left.expr, e2), + expr_simplify_unmet_dep(e1->right.expr, e2)); + case E_AND: { + struct expr *e; + e = expr_alloc_and(expr_copy(e1), expr_copy(e2)); + e = expr_eliminate_dups(e); + ret = (!expr_eq(e, e1)) ? e1 : NULL; + expr_free(e); + break; + } + default: + ret = e1; + break; + } + + return expr_get_leftmost_symbol(ret); +} + void expr_print(struct expr *e, void (*fn)(void *, struct symbol *, const char *), void *data, int prevtoken) { if (!e) { diff --git a/scripts/kconfig/symbol.c b/scripts/kconfig/symbol.c index 60830ce4a0a9..fa52e6f44ac4 100644 --- a/scripts/kconfig/symbol.c +++ b/scripts/kconfig/symbol.c @@ -351,12 +351,16 @@ void sym_calc_value(struct symbol *sym) } calc_newval: if (sym->dir_dep.tri == no && sym->rev_dep.tri != no) { + struct expr *e; + e = expr_simplify_unmet_dep(sym->rev_dep.expr, + sym->dir_dep.expr); fprintf(stderr, "warning: ("); - expr_fprint(sym->rev_dep.expr, stderr); + expr_fprint(e, stderr); fprintf(stderr, ") selects %s which has unmet direct dependencies (", sym->name); expr_fprint(sym->dir_dep.expr, stderr); fprintf(stderr, ")\n"); + expr_free(e); } newval.tri = EXPR_OR(newval.tri, sym->rev_dep.tri); } -- cgit v1.2.3 From 17742dc743716eebbf5892add0e0bf91f541fc39 Mon Sep 17 00:00:00 2001 From: Michal Marek Date: Mon, 20 Dec 2010 16:06:44 +0100 Subject: kconfig: Make expr_copy() take a const argument MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes scripts/kconfig/expr.c: In function ‘expr_get_leftmost_symbol’: scripts/kconfig/expr.c:1026:2: warning: passing argument 1 of ‘expr_copy’ discards qualifiers from pointer target type scripts/kconfig/expr.c:67:14: note: expected ‘struct expr *’ but argument is of type ‘const struct expr *’ Signed-off-by: Michal Marek --- scripts/kconfig/expr.c | 2 +- scripts/kconfig/expr.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/kconfig/expr.c b/scripts/kconfig/expr.c index 65531a7f28a8..001003452f68 100644 --- a/scripts/kconfig/expr.c +++ b/scripts/kconfig/expr.c @@ -64,7 +64,7 @@ struct expr *expr_alloc_or(struct expr *e1, struct expr *e2) return e2 ? expr_alloc_two(E_OR, e1, e2) : e1; } -struct expr *expr_copy(struct expr *org) +struct expr *expr_copy(const struct expr *org) { struct expr *e; diff --git a/scripts/kconfig/expr.h b/scripts/kconfig/expr.h index 184eb6a0b505..218991b26d92 100644 --- a/scripts/kconfig/expr.h +++ b/scripts/kconfig/expr.h @@ -191,7 +191,7 @@ struct expr *expr_alloc_two(enum expr_type type, struct expr *e1, struct expr *e struct expr *expr_alloc_comp(enum expr_type type, struct symbol *s1, struct symbol *s2); struct expr *expr_alloc_and(struct expr *e1, struct expr *e2); struct expr *expr_alloc_or(struct expr *e1, struct expr *e2); -struct expr *expr_copy(struct expr *org); +struct expr *expr_copy(const struct expr *org); void expr_free(struct expr *e); int expr_eq(struct expr *e1, struct expr *e2); void expr_eliminate_eq(struct expr **ep1, struct expr **ep2); -- cgit v1.2.3 From 0719e1d23aab3b445c823404fd1b8b027757bb0a Mon Sep 17 00:00:00 2001 From: "Yann E. MORIN" Date: Thu, 16 Dec 2010 00:19:00 +0100 Subject: Documentation/kbuild: add info that 'choice' can have a symbol name Changeset 5a1aa8a1 added the possibility to name a choice, and to have the same choice be defined multiple times. But the documentation was forgotten, so this updates it accordingly. Thanks to Arnaud Lacombe for pointing it to me in the first place: http://www.spinics.net/lists/linux-kbuild/msg03940.html Signed-off-by: "Yann E. MORIN" Cc: Roman Zippel Cc: Arnaud Lacombe Signed-off-by: Michal Marek --- Documentation/kbuild/kconfig-language.txt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Documentation/kbuild/kconfig-language.txt b/Documentation/kbuild/kconfig-language.txt index 2fe93ca7c77c..a4bbaaf34981 100644 --- a/Documentation/kbuild/kconfig-language.txt +++ b/Documentation/kbuild/kconfig-language.txt @@ -268,7 +268,7 @@ separate list of options. choices: - "choice" + "choice" [symbol] "endchoice" @@ -282,6 +282,10 @@ single driver can be compiled/loaded into the kernel, but all drivers can be compiled as modules. A choice accepts another option "optional", which allows to set the choice to 'n' and no entry needs to be selected. +If no [symbol] is associated with a choice, then you can not have multiple +definitions of that choice. If a [symbol] is associated to the choice, +then you may define the same choice (ie. with the same entries) in another +place. comment: -- cgit v1.2.3 From be4fcddd17f01ede0ff46cf86c5ab8c5adb37175 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 21 Dec 2010 17:09:48 +0000 Subject: ASoC: If we can't find a cache compression type default to flat This makes it easier to make cache types build time configurable as we don't have a hard dependency on a given cache being built in. Signed-off-by: Mark Brown Acked-by: Liam Girdwood --- sound/soc/soc-cache.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/sound/soc/soc-cache.c b/sound/soc/soc-cache.c index 0e17b4050425..fc80be7dfd6a 100644 --- a/sound/soc/soc-cache.c +++ b/sound/soc/soc-cache.c @@ -1531,6 +1531,7 @@ static int snd_soc_flat_cache_init(struct snd_soc_codec *codec) /* an array of all supported compression types */ static const struct snd_soc_cache_ops cache_types[] = { + /* Flat *must* be the first entry for fallback */ { .id = SND_SOC_FLAT_COMPRESSION, .name = "flat", @@ -1567,10 +1568,12 @@ int snd_soc_cache_init(struct snd_soc_codec *codec) for (i = 0; i < ARRAY_SIZE(cache_types); ++i) if (cache_types[i].id == codec->compress_type) break; + + /* Fall back to flat compression */ if (i == ARRAY_SIZE(cache_types)) { - dev_err(codec->dev, "Could not match compress type: %d\n", - codec->compress_type); - return -EINVAL; + dev_warn(codec->dev, "Could not match compress type: %d\n", + codec->compress_type); + i = 0; } mutex_init(&codec->cache_rw_mutex); -- cgit v1.2.3 From 68d44ee0bc70be30ea1ee936e6e21082193386cf Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 21 Dec 2010 17:19:56 +0000 Subject: ASoC: Make LZO cache compression optional Make LZO cache compression optional as it pulls in the kernel wide LZO implementation and rbtree compression is generally more efficient for typical register maps, especially in terms of CPU performance. Signed-off-by: Mark Brown Acked-by: Liam Girdwood --- sound/soc/Kconfig | 17 +++++++++++++++-- sound/soc/soc-cache.c | 4 ++++ 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/sound/soc/Kconfig b/sound/soc/Kconfig index 21a5465ceb65..a3efc52a34da 100644 --- a/sound/soc/Kconfig +++ b/sound/soc/Kconfig @@ -4,8 +4,6 @@ menuconfig SND_SOC tristate "ALSA for SoC audio support" - select LZO_COMPRESS - select LZO_DECOMPRESS select SND_PCM select AC97_BUS if SND_SOC_AC97_BUS select SND_JACK if INPUT=y || INPUT=SND @@ -22,6 +20,21 @@ menuconfig SND_SOC if SND_SOC +config SND_SOC_CACHE_LZO + bool "Support LZO compression for register caches" + select LZO_COMPRESS + select LZO_DECOMPRESS + ---help--- + Select this to enable LZO compression for register caches. + This will allow machine or CODEC drivers to compress register + caches in memory, reducing the memory consumption at the + expense of performance. If this is not present and is used + the system will fall back to uncompressed caches. + + Usually it is safe to disable this option, where cache + compression in used the rbtree option will typically perform + better. + config SND_SOC_AC97_BUS bool diff --git a/sound/soc/soc-cache.c b/sound/soc/soc-cache.c index fc80be7dfd6a..a9ebc078bea8 100644 --- a/sound/soc/soc-cache.c +++ b/sound/soc/soc-cache.c @@ -988,6 +988,7 @@ static int snd_soc_rbtree_cache_init(struct snd_soc_codec *codec) return 0; } +#ifdef CONFIG_SND_SOC_CACHE_LZO struct snd_soc_lzo_ctx { void *wmem; void *dst; @@ -1399,6 +1400,7 @@ err_tofree: } return ret; } +#endif static int snd_soc_flat_cache_sync(struct snd_soc_codec *codec) { @@ -1541,6 +1543,7 @@ static const struct snd_soc_cache_ops cache_types[] = { .write = snd_soc_flat_cache_write, .sync = snd_soc_flat_cache_sync }, +#ifdef CONFIG_SND_SOC_CACHE_LZO { .id = SND_SOC_LZO_COMPRESSION, .name = "LZO", @@ -1550,6 +1553,7 @@ static const struct snd_soc_cache_ops cache_types[] = { .write = snd_soc_lzo_cache_write, .sync = snd_soc_lzo_cache_sync }, +#endif { .id = SND_SOC_RBTREE_COMPRESSION, .name = "rbtree", -- cgit v1.2.3 From 722bc28384accb67c0bfbbe1914fd82d4d0c996a Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Mon, 20 Dec 2010 10:03:13 +0900 Subject: ASoC: sh: fsi: modify improper dependent FSI-AK4642 and FSI-DA7210 are depend on I2C, not I2C_SH_MOBILE Signed-off-by: Kuninori Morimoto Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/sh/Kconfig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/sh/Kconfig b/sound/soc/sh/Kconfig index 7f0a496e07ce..d8e06a607a22 100644 --- a/sound/soc/sh/Kconfig +++ b/sound/soc/sh/Kconfig @@ -48,7 +48,7 @@ config SND_SH7760_AC97 config SND_FSI_AK4642 tristate "FSI-AK4642 sound support" - depends on SND_SOC_SH4_FSI && I2C_SH_MOBILE + depends on SND_SOC_SH4_FSI && I2C select SND_SOC_AK4642 help This option enables generic sound support for the @@ -56,7 +56,7 @@ config SND_FSI_AK4642 config SND_FSI_DA7210 tristate "FSI-DA7210 sound support" - depends on SND_SOC_SH4_FSI && I2C_SH_MOBILE + depends on SND_SOC_SH4_FSI && I2C select SND_SOC_DA7210 help This option enables generic sound support for the -- cgit v1.2.3 From 2e9ff5f5e4c6b034554f3539f29529265279102c Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Thu, 18 Nov 2010 23:08:37 +0100 Subject: gpio-charger: Check result of kzalloc Since kzalloc can return NULL we have to check its result. Signed-off-by: Lars-Peter Clausen Signed-off-by: Vasiliy Kulikov Signed-off-by: Dan Carpenter Signed-off-by: Anton Vorontsov --- drivers/power/gpio-charger.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/power/gpio-charger.c b/drivers/power/gpio-charger.c index fccbe99b619c..8458cafcd2b2 100644 --- a/drivers/power/gpio-charger.c +++ b/drivers/power/gpio-charger.c @@ -87,6 +87,10 @@ static int __devinit gpio_charger_probe(struct platform_device *pdev) } gpio_charger = kzalloc(sizeof(*gpio_charger), GFP_KERNEL); + if (!gpio_charger) { + dev_err(&pdev->dev, "Failed to alloc driver structure\n"); + return -ENOMEM; + } charger = &gpio_charger->charger; -- cgit v1.2.3 From 80577b8a478f3386d106464f2a2241b2d43571ce Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Thu, 18 Nov 2010 23:08:39 +0100 Subject: gpio-charger: Provide default name for the power_supply This patch sets a default name for the power_supply in case there was no name supplied through the platform_data. Signed-off-by: Lars-Peter Clausen Signed-off-by: Anton Vorontsov --- drivers/power/gpio-charger.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/power/gpio-charger.c b/drivers/power/gpio-charger.c index 8458cafcd2b2..43078e34428a 100644 --- a/drivers/power/gpio-charger.c +++ b/drivers/power/gpio-charger.c @@ -94,7 +94,7 @@ static int __devinit gpio_charger_probe(struct platform_device *pdev) charger = &gpio_charger->charger; - charger->name = pdata->name; + charger->name = pdata->name ? pdata->name : "gpio-charger"; charger->type = pdata->type; charger->properties = gpio_charger_properties; charger->num_properties = ARRAY_SIZE(gpio_charger_properties); -- cgit v1.2.3 From 26eb387265872b59566ddeed5e9bf142a6b9ff5b Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Thu, 18 Nov 2010 23:08:38 +0100 Subject: gpio-charger: Fix potential race between irq handler and probe/remove This patch fixes a potential race between the irq handler and the probe and remove functions. The irq should not be requested before the chargers power_supply has been registered and has to be freed before the power_supply is unregistered, otherwise it is possible that the irq fires while the power_supply is not initialized yet or has already been freed. While we are at it replace request_irq with request_any_context_irq. Signed-off-by: Lars-Peter Clausen Signed-off-by: Anton Vorontsov --- drivers/power/gpio-charger.c | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/drivers/power/gpio-charger.c b/drivers/power/gpio-charger.c index 43078e34428a..25b88ac1d44c 100644 --- a/drivers/power/gpio-charger.c +++ b/drivers/power/gpio-charger.c @@ -98,7 +98,7 @@ static int __devinit gpio_charger_probe(struct platform_device *pdev) charger->type = pdata->type; charger->properties = gpio_charger_properties; charger->num_properties = ARRAY_SIZE(gpio_charger_properties); - charger->get_property = gpio_charger_get_property; + charger->get_property = gpio_charger_get_property; charger->supplied_to = pdata->supplied_to; charger->num_supplicants = pdata->num_supplicants; @@ -113,9 +113,18 @@ static int __devinit gpio_charger_probe(struct platform_device *pdev) goto err_gpio_free; } + gpio_charger->pdata = pdata; + + ret = power_supply_register(&pdev->dev, charger); + if (ret < 0) { + dev_err(&pdev->dev, "Failed to register power supply: %d\n", + ret); + goto err_gpio_free; + } + irq = gpio_to_irq(pdata->gpio); if (irq > 0) { - ret = request_irq(irq, gpio_charger_irq, + ret = request_any_context_irq(irq, gpio_charger_irq, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, dev_name(&pdev->dev), charger); if (ret) @@ -124,21 +133,10 @@ static int __devinit gpio_charger_probe(struct platform_device *pdev) gpio_charger->irq = irq; } - gpio_charger->pdata = pdata; - - ret = power_supply_register(&pdev->dev, charger); - if (ret < 0) { - dev_err(&pdev->dev, "Failed to register power supply: %d\n", ret); - goto err_irq_free; - } - platform_set_drvdata(pdev, gpio_charger); return 0; -err_irq_free: - if (gpio_charger->irq) - free_irq(gpio_charger->irq, charger); err_gpio_free: gpio_free(pdata->gpio); err_free: @@ -150,10 +148,11 @@ static int __devexit gpio_charger_remove(struct platform_device *pdev) { struct gpio_charger *gpio_charger = platform_get_drvdata(pdev); - power_supply_unregister(&gpio_charger->charger); - if (gpio_charger->irq) free_irq(gpio_charger->irq, &gpio_charger->charger); + + power_supply_unregister(&gpio_charger->charger); + gpio_free(gpio_charger->pdata->gpio); platform_set_drvdata(pdev, NULL); -- cgit v1.2.3 From 3a2dbd611b38cf9a026c0099a85701ad183d1949 Mon Sep 17 00:00:00 2001 From: Vasiliy Kulikov Date: Fri, 19 Nov 2010 21:41:58 +0300 Subject: power_supply: Fix use after free and memory leak device_unregister() might free its argument. This leads to freed memory use in kfree(). Also use put_device() instead of kfree() as dev may be already used in another layer after call to device_add(). Signed-off-by: Vasiliy Kulikov Signed-off-by: Anton Vorontsov --- drivers/power/power_supply_core.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/power/power_supply_core.c b/drivers/power/power_supply_core.c index 91606bb55318..f06bad047d76 100644 --- a/drivers/power/power_supply_core.c +++ b/drivers/power/power_supply_core.c @@ -190,10 +190,10 @@ int power_supply_register(struct device *parent, struct power_supply *psy) goto success; create_triggers_failed: - device_unregister(psy->dev); + device_del(dev); kobject_set_name_failed: device_add_failed: - kfree(dev); + put_device(dev); success: return rc; } -- cgit v1.2.3 From bc51e7ff521f28a7f14dc2f25307ad9101d1305a Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sat, 11 Dec 2010 17:51:45 +0100 Subject: power_supply: Don't use flush_scheduled_work() flush_scheduled_work() is deprecated and scheduled to be removed. In battery drivers, the work can be canceled on probe failure and removal and should be flushed on suspend. Replace flush_scheduled_work() usages with direct cancels and flushes. Signed-off-by: Tejun Heo Signed-off-by: Anton Vorontsov --- drivers/power/collie_battery.c | 13 ++++++------- drivers/power/intel_mid_battery.c | 2 +- drivers/power/power_supply_core.c | 2 +- drivers/power/tosa_battery.c | 13 ++++++------- drivers/power/wm97xx_battery.c | 4 ++-- drivers/power/z2_battery.c | 6 ++++-- 6 files changed, 20 insertions(+), 20 deletions(-) diff --git a/drivers/power/collie_battery.c b/drivers/power/collie_battery.c index 039f41ae217d..548d263b1ad0 100644 --- a/drivers/power/collie_battery.c +++ b/drivers/power/collie_battery.c @@ -295,7 +295,7 @@ static struct { static int collie_bat_suspend(struct ucb1x00_dev *dev, pm_message_t state) { /* flush all pending status updates */ - flush_scheduled_work(); + flush_work_sync(&bat_work); return 0; } @@ -362,7 +362,7 @@ err_psy_reg_bu: err_psy_reg_main: /* see comment in collie_bat_remove */ - flush_scheduled_work(); + cancel_work_sync(&bat_work); i--; err_gpio: @@ -382,12 +382,11 @@ static void __devexit collie_bat_remove(struct ucb1x00_dev *dev) power_supply_unregister(&collie_bat_main.psy); /* - * now flush all pending work. - * we won't get any more schedules, since all - * sources (isr and external_power_changed) - * are unregistered now. + * Now cancel the bat_work. We won't get any more schedules, + * since all sources (isr and external_power_changed) are + * unregistered now. */ - flush_scheduled_work(); + cancel_work_sync(&bat_work); for (i = ARRAY_SIZE(gpios) - 1; i >= 0; i--) gpio_free(gpios[i].gpio); diff --git a/drivers/power/intel_mid_battery.c b/drivers/power/intel_mid_battery.c index 2a10cd361181..236147c3a5c6 100644 --- a/drivers/power/intel_mid_battery.c +++ b/drivers/power/intel_mid_battery.c @@ -767,7 +767,7 @@ static int __devexit platform_pmic_battery_remove(struct platform_device *pdev) power_supply_unregister(&pbi->usb); power_supply_unregister(&pbi->batt); - flush_scheduled_work(); + cancel_work_sync(&pbi->handler); kfree(pbi); return 0; } diff --git a/drivers/power/power_supply_core.c b/drivers/power/power_supply_core.c index f06bad047d76..970f7335d3a7 100644 --- a/drivers/power/power_supply_core.c +++ b/drivers/power/power_supply_core.c @@ -201,7 +201,7 @@ EXPORT_SYMBOL_GPL(power_supply_register); void power_supply_unregister(struct power_supply *psy) { - flush_scheduled_work(); + cancel_work_sync(&psy->changed_work); power_supply_remove_triggers(psy); device_unregister(psy->dev); } diff --git a/drivers/power/tosa_battery.c b/drivers/power/tosa_battery.c index ee04936b2db5..53f0d3524fcd 100644 --- a/drivers/power/tosa_battery.c +++ b/drivers/power/tosa_battery.c @@ -332,7 +332,7 @@ static struct { static int tosa_bat_suspend(struct platform_device *dev, pm_message_t state) { /* flush all pending status updates */ - flush_scheduled_work(); + flush_work_sync(&bat_work); return 0; } @@ -422,7 +422,7 @@ err_psy_reg_jacket: err_psy_reg_main: /* see comment in tosa_bat_remove */ - flush_scheduled_work(); + cancel_work_sync(&bat_work); i--; err_gpio: @@ -445,12 +445,11 @@ static int __devexit tosa_bat_remove(struct platform_device *dev) power_supply_unregister(&tosa_bat_main.psy); /* - * now flush all pending work. - * we won't get any more schedules, since all - * sources (isr and external_power_changed) - * are unregistered now. + * Now cancel the bat_work. We won't get any more schedules, + * since all sources (isr and external_power_changed) are + * unregistered now. */ - flush_scheduled_work(); + cancel_work_sync(&bat_work); for (i = ARRAY_SIZE(gpios) - 1; i >= 0; i--) gpio_free(gpios[i].gpio); diff --git a/drivers/power/wm97xx_battery.c b/drivers/power/wm97xx_battery.c index 5071d85ec12d..156559e56fa5 100644 --- a/drivers/power/wm97xx_battery.c +++ b/drivers/power/wm97xx_battery.c @@ -147,7 +147,7 @@ static irqreturn_t wm97xx_chrg_irq(int irq, void *data) #ifdef CONFIG_PM static int wm97xx_bat_suspend(struct device *dev) { - flush_scheduled_work(); + flush_work_sync(&bat_work); return 0; } @@ -273,7 +273,7 @@ static int __devexit wm97xx_bat_remove(struct platform_device *dev) free_irq(gpio_to_irq(pdata->charge_gpio), dev); gpio_free(pdata->charge_gpio); } - flush_scheduled_work(); + cancel_work_sync(&bat_work); power_supply_unregister(&bat_ps); kfree(prop); return 0; diff --git a/drivers/power/z2_battery.c b/drivers/power/z2_battery.c index 85064a9f649e..e5ed52d71937 100644 --- a/drivers/power/z2_battery.c +++ b/drivers/power/z2_battery.c @@ -254,7 +254,7 @@ static int __devexit z2_batt_remove(struct i2c_client *client) struct z2_charger *charger = i2c_get_clientdata(client); struct z2_battery_info *info = charger->info; - flush_scheduled_work(); + cancel_work_sync(&charger->bat_work); power_supply_unregister(&charger->batt_ps); kfree(charger->batt_ps.properties); @@ -271,7 +271,9 @@ static int __devexit z2_batt_remove(struct i2c_client *client) #ifdef CONFIG_PM static int z2_batt_suspend(struct i2c_client *client, pm_message_t state) { - flush_scheduled_work(); + struct z2_charger *charger = i2c_get_clientdata(client); + + flush_work_sync(&charger->bat_work); return 0; } -- cgit v1.2.3 From c66ae9bb4dcaac78cc5e30d0ce7ff2bf3dcb48d9 Mon Sep 17 00:00:00 2001 From: Vasily Khoruzhick Date: Mon, 13 Dec 2010 12:26:21 +0200 Subject: s3c_adc_battery: Add gpio_inverted field to pdata Add support for inverted gpio_charge_finished values. This change is necessary for H1940 support. Signed-off-by: Vasily Khoruzhick Signed-off-by: Anton Vorontsov --- drivers/power/s3c_adc_battery.c | 12 +++++++++--- include/linux/s3c_adc_battery.h | 1 + 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/drivers/power/s3c_adc_battery.c b/drivers/power/s3c_adc_battery.c index fe16b482e912..7bc5bfe55ce9 100644 --- a/drivers/power/s3c_adc_battery.c +++ b/drivers/power/s3c_adc_battery.c @@ -112,6 +112,13 @@ static int calc_full_volt(int volt_val, int cur_val, int impedance) return volt_val + cur_val * impedance / 1000; } +static int charge_finished(struct s3c_adc_bat *bat) +{ + return bat->pdata->gpio_inverted ? + !gpio_get_value(bat->pdata->gpio_charge_finished) : + gpio_get_value(bat->pdata->gpio_charge_finished); +} + static int s3c_adc_bat_get_property(struct power_supply *psy, enum power_supply_property psp, union power_supply_propval *val) @@ -140,7 +147,7 @@ static int s3c_adc_bat_get_property(struct power_supply *psy, if (bat->cable_plugged && ((bat->pdata->gpio_charge_finished < 0) || - !gpio_get_value(bat->pdata->gpio_charge_finished))) { + !charge_finished(bat))) { lut = bat->pdata->lut_acin; lut_size = bat->pdata->lut_acin_cnt; } @@ -236,8 +243,7 @@ static void s3c_adc_bat_work(struct work_struct *work) } } else { if ((bat->pdata->gpio_charge_finished >= 0) && is_plugged) { - is_charged = gpio_get_value( - main_bat.pdata->gpio_charge_finished); + is_charged = charge_finished(&main_bat); if (is_charged) { if (bat->pdata->disable_charger) bat->pdata->disable_charger(); diff --git a/include/linux/s3c_adc_battery.h b/include/linux/s3c_adc_battery.h index dbce22faa660..fbe58b7e63eb 100644 --- a/include/linux/s3c_adc_battery.h +++ b/include/linux/s3c_adc_battery.h @@ -14,6 +14,7 @@ struct s3c_adc_bat_pdata { void (*disable_charger)(void); int gpio_charge_finished; + int gpio_inverted; const struct s3c_adc_bat_thresh *lut_noac; unsigned int lut_noac_cnt; -- cgit v1.2.3 From 880981e49b90568ebb53428e231b43b8c1049ef9 Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Tue, 21 Dec 2010 16:16:13 -0500 Subject: drm/radeon/kms: disable bo moves using the blitter Blitting from vram to gart is problematic at the moment. Use the CPU for now to avoid buffer corruption. Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/evergreen.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index f7d7477daffb..499122c8ccc9 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c @@ -2782,6 +2782,11 @@ static int evergreen_startup(struct radeon_device *rdev) rdev->asic->copy = NULL; dev_warn(rdev->dev, "failed blitter (%d) falling back to memcpy\n", r); } + /* XXX: ontario has problems blitting to gart at the moment */ + if (rdev->family == CHIP_PALM) { + rdev->asic->copy = NULL; + rdev->mc.active_vram_size = rdev->mc.visible_vram_size; + } /* allocate wb buffer */ r = radeon_wb_init(rdev); -- cgit v1.2.3 From f3dcab70e192b0489ac05cc554e0b1cedae46d1a Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Wed, 22 Dec 2010 02:44:49 +0300 Subject: jz4740-battery: Should include linux/io.h MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit During test-build (with disabled 'depends on') I found that jz4740-battery driver lacks linux/io.h, which makes build break like this (on x86): CC [M] drivers/power/isp1704_charger.o jz4740-battery.c: In function 'jz_battery_read_voltage': jz4740-battery.c:84: error: implicit declaration of function 'readw’ jz4740-battery.c: In function 'jz_battery_probe': jz4740-battery.c:284: error: implicit declaration of function 'ioremap_nocache’ jz4740-battery.c:285: warning: assignment makes pointer from integer without a cast jz4740-battery.c:372: error: implicit declaration of function 'iounmap' make[2]: *** [drivers/power/jz4740-battery.o] Error 1 This patch fixes the issues, and thus makes it easier to build-test the driver for me. Signed-off-by: Anton Vorontsov --- drivers/power/jz4740-battery.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/power/jz4740-battery.c b/drivers/power/jz4740-battery.c index 5b4821593201..02414db6a94c 100644 --- a/drivers/power/jz4740-battery.c +++ b/drivers/power/jz4740-battery.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include -- cgit v1.2.3 From 204663c48711ddceee09df46269cd34d49d1f7be Mon Sep 17 00:00:00 2001 From: Marek Olšák Date: Tue, 21 Dec 2010 21:27:34 +0100 Subject: drm/radeon/kms: add ARGB2101010 colorbuffer support for r500 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This should be part of DRM 2.8.0. Signed-off-by: Marek Olšák Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/r300.c | 7 +++++++ drivers/gpu/drm/radeon/radeon_drv.c | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/radeon/r300.c b/drivers/gpu/drm/radeon/r300.c index cde1d3480d93..36b4f7b48d6a 100644 --- a/drivers/gpu/drm/radeon/r300.c +++ b/drivers/gpu/drm/radeon/r300.c @@ -787,6 +787,13 @@ static int r300_packet0_check(struct radeon_cs_parser *p, case 15: track->cb[i].cpp = 2; break; + case 5: + if (p->rdev->family < CHIP_RV515) { + DRM_ERROR("Invalid color buffer format (%d)!\n", + ((idx_value >> 21) & 0xF)); + return -EINVAL; + } + /* Pass through. */ case 6: track->cb[i].cpp = 4; break; diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index 6fb1218f9d76..520b776b09f4 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c @@ -48,7 +48,7 @@ * - 2.5.0 - add get accel 2 to work around ddx breakage for evergreen * - 2.6.0 - add tiling config query (r6xx+), add initial HiZ support (r300->r500) * 2.7.0 - fixups for r600 2D tiling support. (no external ABI change), add eg dyn gpr regs - * 2.8.0 - pageflip support, r500 US_FORMAT regs. + * 2.8.0 - pageflip support, r500 US_FORMAT regs. r500 ARGB2101010 colorbuf */ #define KMS_DRIVER_MAJOR 2 #define KMS_DRIVER_MINOR 8 -- cgit v1.2.3 From fcc57045d53edc35bcce456e60ac4aa802712934 Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Wed, 22 Dec 2010 09:48:49 +0100 Subject: Revert "sd: implement sd_check_events()" This reverts commit c8d2e937355d02db3055c2fc203e5f017297ee1f. We run into merging problems with the SCSI tree, revert this one so it can be handled by a postmerge tree there. Signed-off-by: Jens Axboe --- drivers/scsi/sd.c | 87 +++++++++++++++++++++++++------------------------------ drivers/scsi/sd.h | 1 + 2 files changed, 41 insertions(+), 47 deletions(-) diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index b179b0e39a3b..8d488a9fef00 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -991,50 +991,30 @@ out: static void set_media_not_present(struct scsi_disk *sdkp) { - if (sdkp->media_present) - sdkp->device->changed = 1; sdkp->media_present = 0; sdkp->capacity = 0; -} - -static int media_not_present(struct scsi_disk *sdkp, - struct scsi_sense_hdr *sshdr) -{ - if (!scsi_sense_valid(sshdr)) - return 0; - - /* not invoked for commands that could return deferred errors */ - switch (sshdr->sense_key) { - case UNIT_ATTENTION: - sdkp->device->changed = 1; - /* fall through */ - case NOT_READY: - /* medium not present */ - if (sshdr->asc == 0x3A) { - set_media_not_present(sdkp); - return 1; - } - } - return 0; + sdkp->device->changed = 1; } /** - * sd_check_events - check media events - * @disk: kernel device descriptor - * @clearing: disk events currently being cleared + * sd_media_changed - check if our medium changed + * @disk: kernel device descriptor * - * Returns mask of DISK_EVENT_*. + * Returns 0 if not applicable or no change; 1 if change * * Note: this function is invoked from the block subsystem. **/ -static unsigned int sd_check_events(struct gendisk *disk, unsigned int clearing) +static int sd_media_changed(struct gendisk *disk) { struct scsi_disk *sdkp = scsi_disk(disk); struct scsi_device *sdp = sdkp->device; struct scsi_sense_hdr *sshdr = NULL; int retval; - SCSI_LOG_HLQUEUE(3, sd_printk(KERN_INFO, sdkp, "sd_check_events\n")); + SCSI_LOG_HLQUEUE(3, sd_printk(KERN_INFO, sdkp, "sd_media_changed\n")); + + if (!sdp->removable) + return 0; /* * If the device is offline, don't send any commands - just pretend as @@ -1044,6 +1024,7 @@ static unsigned int sd_check_events(struct gendisk *disk, unsigned int clearing) */ if (!scsi_device_online(sdp)) { set_media_not_present(sdkp); + retval = 1; goto out; } @@ -1064,30 +1045,26 @@ static unsigned int sd_check_events(struct gendisk *disk, unsigned int clearing) sshdr); } - /* failed to execute TUR, assume media not present */ - if (host_byte(retval)) { + if (retval) { set_media_not_present(sdkp); + retval = 1; goto out; } - if (media_not_present(sdkp, sshdr)) - goto out; - /* * For removable scsi disk we have to recognise the presence - * of a disk in the drive. + * of a disk in the drive. This is kept in the struct scsi_disk + * struct and tested at open ! Daniel Roche (dan@lectra.fr) */ - if (!sdkp->media_present) - sdp->changed = 1; sdkp->media_present = 1; + + retval = sdp->changed; + sdp->changed = 0; out: - /* for backward compatibility */ - if (sdp->changed) + if (retval != sdkp->previous_state) sdev_evt_send_simple(sdp, SDEV_EVT_MEDIA_CHANGE, GFP_KERNEL); + sdkp->previous_state = retval; kfree(sshdr); - - retval = sdp->changed ? DISK_EVENT_MEDIA_CHANGE : 0; - sdp->changed = 0; return retval; } @@ -1180,7 +1157,7 @@ static const struct block_device_operations sd_fops = { #ifdef CONFIG_COMPAT .compat_ioctl = sd_compat_ioctl, #endif - .check_events = sd_check_events, + .media_changed = sd_media_changed, .revalidate_disk = sd_revalidate_disk, .unlock_native_capacity = sd_unlock_native_capacity, }; @@ -1316,6 +1293,23 @@ static int sd_done(struct scsi_cmnd *SCpnt) return good_bytes; } +static int media_not_present(struct scsi_disk *sdkp, + struct scsi_sense_hdr *sshdr) +{ + + if (!scsi_sense_valid(sshdr)) + return 0; + /* not invoked for commands that could return deferred errors */ + if (sshdr->sense_key != NOT_READY && + sshdr->sense_key != UNIT_ATTENTION) + return 0; + if (sshdr->asc != 0x3A) /* medium not present */ + return 0; + + set_media_not_present(sdkp); + return 1; +} + /* * spinup disk - called only in sd_revalidate_disk() */ @@ -1490,7 +1484,7 @@ static void read_capacity_error(struct scsi_disk *sdkp, struct scsi_device *sdp, */ if (sdp->removable && sense_valid && sshdr->sense_key == NOT_READY) - set_media_not_present(sdkp); + sdp->changed = 1; /* * We used to set media_present to 0 here to indicate no media @@ -2345,10 +2339,8 @@ static void sd_probe_async(void *data, async_cookie_t cookie) gd->driverfs_dev = &sdp->sdev_gendev; gd->flags = GENHD_FL_EXT_DEVT; - if (sdp->removable) { + if (sdp->removable) gd->flags |= GENHD_FL_REMOVABLE; - gd->events |= DISK_EVENT_MEDIA_CHANGE; - } add_disk(gd); sd_dif_config_host(sdkp); @@ -2430,6 +2422,7 @@ static int sd_probe(struct device *dev) sdkp->disk = gd; sdkp->index = index; atomic_set(&sdkp->openers, 0); + sdkp->previous_state = 1; if (!sdp->request_queue->rq_timeout) { if (sdp->type != TYPE_MOD) diff --git a/drivers/scsi/sd.h b/drivers/scsi/sd.h index c9d8f6ca49e2..55488faf0815 100644 --- a/drivers/scsi/sd.h +++ b/drivers/scsi/sd.h @@ -55,6 +55,7 @@ struct scsi_disk { u8 media_present; u8 write_prot; u8 protection_type;/* Data Integrity Field */ + unsigned previous_state : 1; unsigned ATO : 1; /* state of disk ATO bit */ unsigned WCE : 1; /* state of disk WCE bit */ unsigned RCD : 1; /* state of disk RCD bit, unused */ -- cgit v1.2.3 From 6d3c26bcb7a129a11a54d78644e264ec872547e1 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Sun, 5 Dec 2010 12:41:52 +0000 Subject: ASoC: Use delayed work to debounce WM8350 jack IRQs This avoids blocking the IRQ thread and allows further bounces to extend the debounce time. Signed-off-by: Mark Brown Acked-by: Liam Girdwood --- sound/soc/codecs/wm8350.c | 62 ++++++++++++++++++++++++++++++++--------------- 1 file changed, 43 insertions(+), 19 deletions(-) diff --git a/sound/soc/codecs/wm8350.c b/sound/soc/codecs/wm8350.c index 07ba7e3f6a8c..3e0362e62f8f 100644 --- a/sound/soc/codecs/wm8350.c +++ b/sound/soc/codecs/wm8350.c @@ -53,6 +53,7 @@ struct wm8350_output { struct wm8350_jack_data { struct snd_soc_jack *jack; + struct delayed_work work; int report; int short_report; }; @@ -1335,45 +1336,63 @@ static int wm8350_resume(struct snd_soc_codec *codec) return 0; } -static irqreturn_t wm8350_hp_jack_handler(int irq, void *data) +static void wm8350_hp_work(struct wm8350_data *priv, + struct wm8350_jack_data *jack, + u16 mask) { - struct wm8350_data *priv = data; struct wm8350 *wm8350 = priv->codec.control_data; u16 reg; int report; - int mask; + + reg = wm8350_reg_read(wm8350, WM8350_JACK_PIN_STATUS); + if (reg & mask) + report = jack->report; + else + report = 0; + + snd_soc_jack_report(jack->jack, report, jack->report); + +} + +static void wm8350_hpl_work(struct work_struct *work) +{ + struct wm8350_data *priv = + container_of(work, struct wm8350_data, hpl.work.work); + + wm8350_hp_work(priv, &priv->hpl, WM8350_JACK_L_LVL); +} + +static void wm8350_hpr_work(struct work_struct *work) +{ + struct wm8350_data *priv = + container_of(work, struct wm8350_data, hpr.work.work); + + wm8350_hp_work(priv, &priv->hpr, WM8350_JACK_R_LVL); +} + +static irqreturn_t wm8350_hp_jack_handler(int irq, void *data) +{ + struct wm8350_data *priv = data; + struct wm8350 *wm8350 = priv->codec.control_data; struct wm8350_jack_data *jack = NULL; switch (irq - wm8350->irq_base) { case WM8350_IRQ_CODEC_JCK_DET_L: jack = &priv->hpl; - mask = WM8350_JACK_L_LVL; break; case WM8350_IRQ_CODEC_JCK_DET_R: jack = &priv->hpr; - mask = WM8350_JACK_R_LVL; break; default: BUG(); } - if (!jack->jack) { - dev_warn(wm8350->dev, "Jack interrupt called with no jack\n"); - return IRQ_NONE; - } + if (device_may_wakeup(wm8350->dev)) + pm_wakeup_event(wm8350->dev, 250); - /* Debounce */ - msleep(200); - - reg = wm8350_reg_read(wm8350, WM8350_JACK_PIN_STATUS); - if (reg & mask) - report = jack->report; - else - report = 0; - - snd_soc_jack_report(jack->jack, report, jack->report); + schedule_delayed_work(&jack->work, 200); return IRQ_HANDLED; } @@ -1552,6 +1571,8 @@ static int wm8350_codec_probe(struct snd_soc_codec *codec) wm8350_clear_bits(wm8350, WM8350_POWER_MGMT_5, WM8350_CODEC_ENA); INIT_DELAYED_WORK(&codec->dapm.delayed_work, wm8350_pga_work); + INIT_DELAYED_WORK(&priv->hpl.work, wm8350_hpl_work); + INIT_DELAYED_WORK(&priv->hpr.work, wm8350_hpr_work); /* Enable the codec */ wm8350_set_bits(wm8350, WM8350_POWER_MGMT_5, WM8350_CODEC_ENA); @@ -1641,6 +1662,9 @@ static int wm8350_codec_remove(struct snd_soc_codec *codec) priv->hpr.jack = NULL; priv->mic.jack = NULL; + cancel_delayed_work_sync(&priv->hpl.work); + cancel_delayed_work_sync(&priv->hpr.work); + /* if there was any work waiting then we run it now and * wait for its completion */ flush_delayed_work_sync(&codec->dapm.delayed_work); -- cgit v1.2.3 From 2bbb5d667958f20ef8e7f7b37f9acced6dac0b98 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Sun, 5 Dec 2010 12:50:12 +0000 Subject: ASoC: Trace Wolfson jack detection IRQs Add jack detection interrupt trace to Wolfson CODEC drivers. Signed-off-by: Mark Brown Acked-by: Liam Girdwood --- sound/soc/codecs/wm8350.c | 5 +++++ sound/soc/codecs/wm8903.c | 4 ++++ sound/soc/codecs/wm8962.c | 3 +++ sound/soc/codecs/wm8994.c | 5 +++++ 4 files changed, 17 insertions(+) diff --git a/sound/soc/codecs/wm8350.c b/sound/soc/codecs/wm8350.c index 3e0362e62f8f..82d877df3fb0 100644 --- a/sound/soc/codecs/wm8350.c +++ b/sound/soc/codecs/wm8350.c @@ -26,6 +26,7 @@ #include #include #include +#include #include "wm8350.h" @@ -1378,10 +1379,12 @@ static irqreturn_t wm8350_hp_jack_handler(int irq, void *data) switch (irq - wm8350->irq_base) { case WM8350_IRQ_CODEC_JCK_DET_L: + trace_snd_soc_jack_irq("WM8350 HPL"); jack = &priv->hpl; break; case WM8350_IRQ_CODEC_JCK_DET_R: + trace_snd_soc_jack_irq("WM8350 HPR"); jack = &priv->hpr; break; @@ -1456,6 +1459,8 @@ static irqreturn_t wm8350_mic_handler(int irq, void *data) u16 reg; int report = 0; + trace_snd_soc_jack_irq("WM8350 mic"); + reg = wm8350_reg_read(wm8350, WM8350_JACK_PIN_STATUS); if (reg & WM8350_JACK_MICSCD_LVL) report |= priv->mic.short_report; diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c index d015745a886b..b32699bc1927 100644 --- a/sound/soc/codecs/wm8903.c +++ b/sound/soc/codecs/wm8903.c @@ -31,6 +31,7 @@ #include #include #include +#include #include "wm8903.h" @@ -1533,6 +1534,9 @@ static irqreturn_t wm8903_irq(int irq, void *data) mic_report = wm8903->mic_last_report; int_pol = snd_soc_read(codec, WM8903_INTERRUPT_POLARITY_1); + if (int_val & (WM8903_MICSHRT_EINT | WM8903_MICDET_EINT)) + trace_snd_soc_jack_irq(dev_name(codec->dev)); + if (int_val & WM8903_MICSHRT_EINT) { dev_dbg(codec->dev, "Microphone short (pol=%x)\n", int_pol); diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c index f0c9d2691842..a24f83d604c9 100644 --- a/sound/soc/codecs/wm8962.c +++ b/sound/soc/codecs/wm8962.c @@ -32,6 +32,7 @@ #include #include #include +#include #include "wm8962.h" @@ -3353,6 +3354,8 @@ static irqreturn_t wm8962_irq(int irq, void *data) if (active & (WM8962_MICSCD_EINT | WM8962_MICD_EINT)) { dev_dbg(codec->dev, "Microphone event detected\n"); + trace_snd_soc_jack_irq(dev_name(codec->dev)); + pm_wakeup_event(codec->dev, 300); schedule_delayed_work(&wm8962->mic_work, diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index e1a775bd83fa..067a532bed15 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include @@ -2755,6 +2756,8 @@ static irqreturn_t wm8994_mic_irq(int irq, void *data) int reg; int report; + trace_snd_soc_jack_irq(dev_name(codec->dev)); + reg = snd_soc_read(codec, WM8994_INTERRUPT_RAW_STATUS_2); if (reg < 0) { dev_err(codec->dev, "Failed to read microphone status: %d\n", @@ -2901,6 +2904,8 @@ static irqreturn_t wm8958_mic_irq(int irq, void *data) goto out; } + trace_snd_soc_jack_irq(dev_name(codec->dev)); + if (wm8994->jack_cb) wm8994->jack_cb(reg, wm8994->jack_cb_data); else -- cgit v1.2.3 From 1c9e9795b5e2348df619fd6010d7583dc9b8c811 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Sun, 5 Dec 2010 12:53:08 +0000 Subject: ASoC: Add jack IRQ trace to 88pm860x driver Signed-off-by: Mark Brown Acked-by: Liam Girdwood --- sound/soc/codecs/88pm860x-codec.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/sound/soc/codecs/88pm860x-codec.c b/sound/soc/codecs/88pm860x-codec.c index 08e15dee9182..a34fb924e77b 100644 --- a/sound/soc/codecs/88pm860x-codec.c +++ b/sound/soc/codecs/88pm860x-codec.c @@ -22,6 +22,7 @@ #include #include #include +#include #include "88pm860x-codec.h" @@ -1262,6 +1263,10 @@ static irqreturn_t pm860x_codec_handler(int irq, void *data) mask = pm860x->det.hs_shrt | pm860x->det.hook_det | pm860x->det.lo_shrt | pm860x->det.hp_det; + if (status & (HEADSET_STATUS | MIC_STATUS | SHORT_HS1 | SHORT_HS2 | + SHORT_LO1 | SHORT_LO2)) + trace_snd_soc_jack_irq(dev_name(pm860x->codec->dev)); + if ((pm860x->det.hp_det & SND_JACK_HEADPHONE) && (status & HEADSET_STATUS)) report |= SND_JACK_HEADPHONE; -- cgit v1.2.3 From f49be89bb4e235776af08cdcef91a37a0d12aa62 Mon Sep 17 00:00:00 2001 From: Seungwhan Youn Date: Wed, 22 Dec 2010 18:46:24 +0900 Subject: ASoC: SAMSUNG: Debug wrong parameter snd_soc_jack_new()'s first parameter was changed from snd_soc_card to snd_soc_codec after Multi-Component support patches. So, this patch fixes parameter that we missed. Signed-off-by: Seungwhan Youn Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/samsung/goni_wm8994.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/samsung/goni_wm8994.c b/sound/soc/samsung/goni_wm8994.c index cc8528c0a49a..34dd9ef1b9c0 100644 --- a/sound/soc/samsung/goni_wm8994.c +++ b/sound/soc/samsung/goni_wm8994.c @@ -131,7 +131,7 @@ static int goni_wm8994_init(struct snd_soc_pcm_runtime *rtd) snd_soc_dapm_sync(dapm); /* Headset jack detection */ - ret = snd_soc_jack_new(&goni, "Headset Jack", + ret = snd_soc_jack_new(codec, "Headset Jack", SND_JACK_HEADSET | SND_JACK_MECHANICAL | SND_JACK_AVOUT, &jack); if (ret) -- cgit v1.2.3 From 9d01df063e70260d6c0aabd58dd5507db151aa51 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 22 Dec 2010 14:08:40 +0100 Subject: ASoC: don't pass the string as the format arguemtn for dev_info() Signed-off-by: Takashi Iwai --- 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 50f5c785cb61..499730ab5638 100644 --- a/sound/soc/soc-dapm.c +++ b/sound/soc/soc-dapm.c @@ -110,7 +110,7 @@ static void pop_dbg(struct device *dev, u32 pop_time, const char *fmt, ...) va_start(args, fmt); vsnprintf(buf, PAGE_SIZE, fmt, args); - dev_info(dev, buf); + dev_info(dev, "%s", buf); va_end(args); kfree(buf); -- cgit v1.2.3 From 6a504a751124889e0bdbb25963a7edf7aeedb7bd Mon Sep 17 00:00:00 2001 From: Dimitris Papastamos Date: Wed, 22 Dec 2010 11:33:11 +0000 Subject: ASoC: Add initial WM8995 driver The WM8995 is a digital audio hub CODEC designed for smartphones. The current driver supports most of the basic functionality of the WM8995. Signed-off-by: Dimitris Papastamos Acked-by: Liam Girdwood Signed-off-by: Mark Brown --- sound/soc/codecs/Kconfig | 4 + sound/soc/codecs/Makefile | 2 + sound/soc/codecs/wm8995.c | 1818 ++++++++++ sound/soc/codecs/wm8995.h | 8749 +++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 10573 insertions(+) create mode 100644 sound/soc/codecs/wm8995.c create mode 100644 sound/soc/codecs/wm8995.h diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index 0f33db2be25a..054191ed08ef 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -78,6 +78,7 @@ config SND_SOC_ALL_CODECS select SND_SOC_WM8990 if I2C select SND_SOC_WM8993 if I2C select SND_SOC_WM8994 if MFD_WM8994 + select SND_SOC_WM8995 if SND_SOC_I2C_AND_SPI select SND_SOC_WM9081 if I2C select SND_SOC_WM9090 if I2C select SND_SOC_WM9705 if SND_SOC_AC97_BUS @@ -306,6 +307,9 @@ config SND_SOC_WM8993 config SND_SOC_WM8994 tristate +config SND_SOC_WM8995 + tristate + config SND_SOC_WM9081 tristate diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index 10e5e099334a..6a1e17bbbf83 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile @@ -62,6 +62,7 @@ snd-soc-wm8988-objs := wm8988.o snd-soc-wm8990-objs := wm8990.o snd-soc-wm8993-objs := wm8993.o snd-soc-wm8994-objs := wm8994.o wm8994-tables.o +snd-soc-wm8995-objs := wm8995.o snd-soc-wm9081-objs := wm9081.o snd-soc-wm9705-objs := wm9705.o snd-soc-wm9712-objs := wm9712.o @@ -140,6 +141,7 @@ obj-$(CONFIG_SND_SOC_WM8988) += snd-soc-wm8988.o obj-$(CONFIG_SND_SOC_WM8990) += snd-soc-wm8990.o obj-$(CONFIG_SND_SOC_WM8993) += snd-soc-wm8993.o obj-$(CONFIG_SND_SOC_WM8994) += snd-soc-wm8994.o +obj-$(CONFIG_SND_SOC_WM8995) += snd-soc-wm8995.o obj-$(CONFIG_SND_SOC_WM9081) += snd-soc-wm9081.o obj-$(CONFIG_SND_SOC_WM9705) += snd-soc-wm9705.o obj-$(CONFIG_SND_SOC_WM9712) += snd-soc-wm9712.o diff --git a/sound/soc/codecs/wm8995.c b/sound/soc/codecs/wm8995.c new file mode 100644 index 000000000000..3d2110c1d81f --- /dev/null +++ b/sound/soc/codecs/wm8995.c @@ -0,0 +1,1818 @@ +/* + * wm8995.c -- WM8995 ALSA SoC Audio driver + * + * Copyright 2010 Wolfson Microelectronics plc + * + * Author: Dimitris Papastamos + * + * Based on wm8994.c and wm_hubs.c by Mark Brown + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "wm8995.h" + +static const u16 wm8995_reg_defs[WM8995_MAX_REGISTER + 1] __devinitconst = { + [0] = 0x8995, [5] = 0x0100, [16] = 0x000b, [17] = 0x000b, + [24] = 0x02c0, [25] = 0x02c0, [26] = 0x02c0, [27] = 0x02c0, + [28] = 0x000f, [32] = 0x0005, [33] = 0x0005, [40] = 0x0003, + [41] = 0x0013, [48] = 0x0004, [56] = 0x09f8, [64] = 0x1f25, + [69] = 0x0004, [82] = 0xaaaa, [84] = 0x2a2a, [146] = 0x0060, + [256] = 0x0002, [257] = 0x8004, [520] = 0x0010, [528] = 0x0083, + [529] = 0x0083, [548] = 0x0c80, [580] = 0x0c80, [768] = 0x4050, + [769] = 0x4000, [771] = 0x0040, [772] = 0x0040, [773] = 0x0040, + [774] = 0x0004, [775] = 0x0100, [784] = 0x4050, [785] = 0x4000, + [787] = 0x0040, [788] = 0x0040, [789] = 0x0040, [1024] = 0x00c0, + [1025] = 0x00c0, [1026] = 0x00c0, [1027] = 0x00c0, [1028] = 0x00c0, + [1029] = 0x00c0, [1030] = 0x00c0, [1031] = 0x00c0, [1056] = 0x0200, + [1057] = 0x0010, [1058] = 0x0200, [1059] = 0x0010, [1088] = 0x0098, + [1089] = 0x0845, [1104] = 0x0098, [1105] = 0x0845, [1152] = 0x6318, + [1153] = 0x6300, [1154] = 0x0fca, [1155] = 0x0400, [1156] = 0x00d8, + [1157] = 0x1eb5, [1158] = 0xf145, [1159] = 0x0b75, [1160] = 0x01c5, + [1161] = 0x1c58, [1162] = 0xf373, [1163] = 0x0a54, [1164] = 0x0558, + [1165] = 0x168e, [1166] = 0xf829, [1167] = 0x07ad, [1168] = 0x1103, + [1169] = 0x0564, [1170] = 0x0559, [1171] = 0x4000, [1184] = 0x6318, + [1185] = 0x6300, [1186] = 0x0fca, [1187] = 0x0400, [1188] = 0x00d8, + [1189] = 0x1eb5, [1190] = 0xf145, [1191] = 0x0b75, [1192] = 0x01c5, + [1193] = 0x1c58, [1194] = 0xf373, [1195] = 0x0a54, [1196] = 0x0558, + [1197] = 0x168e, [1198] = 0xf829, [1199] = 0x07ad, [1200] = 0x1103, + [1201] = 0x0564, [1202] = 0x0559, [1203] = 0x4000, [1280] = 0x00c0, + [1281] = 0x00c0, [1282] = 0x00c0, [1283] = 0x00c0, [1312] = 0x0200, + [1313] = 0x0010, [1344] = 0x0098, [1345] = 0x0845, [1408] = 0x6318, + [1409] = 0x6300, [1410] = 0x0fca, [1411] = 0x0400, [1412] = 0x00d8, + [1413] = 0x1eb5, [1414] = 0xf145, [1415] = 0x0b75, [1416] = 0x01c5, + [1417] = 0x1c58, [1418] = 0xf373, [1419] = 0x0a54, [1420] = 0x0558, + [1421] = 0x168e, [1422] = 0xf829, [1423] = 0x07ad, [1424] = 0x1103, + [1425] = 0x0564, [1426] = 0x0559, [1427] = 0x4000, [1568] = 0x0002, + [1792] = 0xa100, [1793] = 0xa101, [1794] = 0xa101, [1795] = 0xa101, + [1796] = 0xa101, [1797] = 0xa101, [1798] = 0xa101, [1799] = 0xa101, + [1800] = 0xa101, [1801] = 0xa101, [1802] = 0xa101, [1803] = 0xa101, + [1804] = 0xa101, [1805] = 0xa101, [1825] = 0x0055, [1848] = 0x3fff, + [1849] = 0x1fff, [2049] = 0x0001, [2050] = 0x0069, [2056] = 0x0002, + [2057] = 0x0003, [2058] = 0x0069, [12288] = 0x0001, [12289] = 0x0001, + [12291] = 0x0006, [12292] = 0x0040, [12293] = 0x0001, [12294] = 0x000f, + [12295] = 0x0006, [12296] = 0x0001, [12297] = 0x0003, [12298] = 0x0104, + [12300] = 0x0060, [12301] = 0x0011, [12302] = 0x0401, [12304] = 0x0050, + [12305] = 0x0003, [12306] = 0x0100, [12308] = 0x0051, [12309] = 0x0003, + [12310] = 0x0104, [12311] = 0x000a, [12312] = 0x0060, [12313] = 0x003b, + [12314] = 0x0502, [12315] = 0x0100, [12316] = 0x2fff, [12320] = 0x2fff, + [12324] = 0x2fff, [12328] = 0x2fff, [12332] = 0x2fff, [12336] = 0x2fff, + [12340] = 0x2fff, [12344] = 0x2fff, [12348] = 0x2fff, [12352] = 0x0001, + [12353] = 0x0001, [12355] = 0x0006, [12356] = 0x0040, [12357] = 0x0001, + [12358] = 0x000f, [12359] = 0x0006, [12360] = 0x0001, [12361] = 0x0003, + [12362] = 0x0104, [12364] = 0x0060, [12365] = 0x0011, [12366] = 0x0401, + [12368] = 0x0050, [12369] = 0x0003, [12370] = 0x0100, [12372] = 0x0060, + [12373] = 0x003b, [12374] = 0x0502, [12375] = 0x0100, [12376] = 0x2fff, + [12380] = 0x2fff, [12384] = 0x2fff, [12388] = 0x2fff, [12392] = 0x2fff, + [12396] = 0x2fff, [12400] = 0x2fff, [12404] = 0x2fff, [12408] = 0x2fff, + [12412] = 0x2fff, [12416] = 0x0001, [12417] = 0x0001, [12419] = 0x0006, + [12420] = 0x0040, [12421] = 0x0001, [12422] = 0x000f, [12423] = 0x0006, + [12424] = 0x0001, [12425] = 0x0003, [12426] = 0x0106, [12428] = 0x0061, + [12429] = 0x0011, [12430] = 0x0401, [12432] = 0x0050, [12433] = 0x0003, + [12434] = 0x0102, [12436] = 0x0051, [12437] = 0x0003, [12438] = 0x0106, + [12439] = 0x000a, [12440] = 0x0061, [12441] = 0x003b, [12442] = 0x0502, + [12443] = 0x0100, [12444] = 0x2fff, [12448] = 0x2fff, [12452] = 0x2fff, + [12456] = 0x2fff, [12460] = 0x2fff, [12464] = 0x2fff, [12468] = 0x2fff, + [12472] = 0x2fff, [12476] = 0x2fff, [12480] = 0x0001, [12481] = 0x0001, + [12483] = 0x0006, [12484] = 0x0040, [12485] = 0x0001, [12486] = 0x000f, + [12487] = 0x0006, [12488] = 0x0001, [12489] = 0x0003, [12490] = 0x0106, + [12492] = 0x0061, [12493] = 0x0011, [12494] = 0x0401, [12496] = 0x0050, + [12497] = 0x0003, [12498] = 0x0102, [12500] = 0x0061, [12501] = 0x003b, + [12502] = 0x0502, [12503] = 0x0100, [12504] = 0x2fff, [12508] = 0x2fff, + [12512] = 0x2fff, [12516] = 0x2fff, [12520] = 0x2fff, [12524] = 0x2fff, + [12528] = 0x2fff, [12532] = 0x2fff, [12536] = 0x2fff, [12540] = 0x2fff, + [12544] = 0x0060, [12546] = 0x0601, [12548] = 0x0050, [12550] = 0x0100, + [12552] = 0x0001, [12554] = 0x0104, [12555] = 0x0100, [12556] = 0x2fff, + [12560] = 0x2fff, [12564] = 0x2fff, [12568] = 0x2fff, [12572] = 0x2fff, + [12576] = 0x2fff, [12580] = 0x2fff, [12584] = 0x2fff, [12588] = 0x2fff, + [12592] = 0x2fff, [12596] = 0x2fff, [12600] = 0x2fff, [12604] = 0x2fff, + [12608] = 0x0061, [12610] = 0x0601, [12612] = 0x0050, [12614] = 0x0102, + [12616] = 0x0001, [12618] = 0x0106, [12619] = 0x0100, [12620] = 0x2fff, + [12624] = 0x2fff, [12628] = 0x2fff, [12632] = 0x2fff, [12636] = 0x2fff, + [12640] = 0x2fff, [12644] = 0x2fff, [12648] = 0x2fff, [12652] = 0x2fff, + [12656] = 0x2fff, [12660] = 0x2fff, [12664] = 0x2fff, [12668] = 0x2fff, + [12672] = 0x0060, [12674] = 0x0601, [12676] = 0x0061, [12678] = 0x0601, + [12680] = 0x0050, [12682] = 0x0300, [12684] = 0x0001, [12686] = 0x0304, + [12688] = 0x0040, [12690] = 0x000f, [12692] = 0x0001, [12695] = 0x0100 +}; + +struct fll_config { + int src; + int in; + int out; +}; + +struct wm8995_priv { + enum snd_soc_control_type control_type; + int sysclk[2]; + int mclk[2]; + int aifclk[2]; + struct fll_config fll[2], fll_suspend[2]; +}; + +static const DECLARE_TLV_DB_SCALE(digital_tlv, -7200, 75, 1); +static const DECLARE_TLV_DB_SCALE(in1lr_pga_tlv, -1650, 150, 0); +static const DECLARE_TLV_DB_SCALE(in1l_boost_tlv, 0, 600, 0); +static const DECLARE_TLV_DB_SCALE(sidetone_tlv, -3600, 150, 0); + +static const char *in1l_text[] = { + "Differential", "Single-ended IN1LN", "Single-ended IN1LP" +}; + +static const SOC_ENUM_SINGLE_DECL(in1l_enum, WM8995_LEFT_LINE_INPUT_CONTROL, + 2, in1l_text); + +static const char *in1r_text[] = { + "Differential", "Single-ended IN1RN", "Single-ended IN1RP" +}; + +static const SOC_ENUM_SINGLE_DECL(in1r_enum, WM8995_LEFT_LINE_INPUT_CONTROL, + 0, in1r_text); + +static const char *dmic_src_text[] = { + "DMICDAT1", "DMICDAT2", "DMICDAT3" +}; + +static const SOC_ENUM_SINGLE_DECL(dmic_src1_enum, WM8995_POWER_MANAGEMENT_5, + 8, dmic_src_text); +static const SOC_ENUM_SINGLE_DECL(dmic_src2_enum, WM8995_POWER_MANAGEMENT_5, + 6, dmic_src_text); + +static const struct snd_kcontrol_new wm8995_snd_controls[] = { + SOC_DOUBLE_R_TLV("DAC1 Volume", WM8995_DAC1_LEFT_VOLUME, + WM8995_DAC1_RIGHT_VOLUME, 0, 96, 0, digital_tlv), + SOC_DOUBLE_R("DAC1 Switch", WM8995_DAC1_LEFT_VOLUME, + WM8995_DAC1_RIGHT_VOLUME, 9, 1, 1), + + SOC_DOUBLE_R_TLV("DAC2 Volume", WM8995_DAC2_LEFT_VOLUME, + WM8995_DAC2_RIGHT_VOLUME, 0, 96, 0, digital_tlv), + SOC_DOUBLE_R("DAC2 Switch", WM8995_DAC2_LEFT_VOLUME, + WM8995_DAC2_RIGHT_VOLUME, 9, 1, 1), + + SOC_DOUBLE_R_TLV("AIF1DAC1 Volume", WM8995_AIF1_DAC1_LEFT_VOLUME, + WM8995_AIF1_DAC1_RIGHT_VOLUME, 0, 96, 0, digital_tlv), + SOC_DOUBLE_R_TLV("AIF1DAC2 Volume", WM8995_AIF1_DAC2_LEFT_VOLUME, + WM8995_AIF1_DAC2_RIGHT_VOLUME, 0, 96, 0, digital_tlv), + SOC_DOUBLE_R_TLV("AIF2DAC Volume", WM8995_AIF2_DAC_LEFT_VOLUME, + WM8995_AIF2_DAC_RIGHT_VOLUME, 0, 96, 0, digital_tlv), + + SOC_DOUBLE_R_TLV("IN1LR Volume", WM8995_LEFT_LINE_INPUT_1_VOLUME, + WM8995_RIGHT_LINE_INPUT_1_VOLUME, 0, 31, 0, in1lr_pga_tlv), + + SOC_SINGLE_TLV("IN1L Boost", WM8995_LEFT_LINE_INPUT_CONTROL, + 4, 3, 0, in1l_boost_tlv), + + SOC_ENUM("IN1L Mode", in1l_enum), + SOC_ENUM("IN1R Mode", in1r_enum), + + SOC_ENUM("DMIC1 SRC", dmic_src1_enum), + SOC_ENUM("DMIC2 SRC", dmic_src2_enum), + + SOC_DOUBLE_TLV("DAC1 Sidetone Volume", WM8995_DAC1_MIXER_VOLUMES, 0, 5, + 24, 0, sidetone_tlv), + SOC_DOUBLE_TLV("DAC2 Sidetone Volume", WM8995_DAC2_MIXER_VOLUMES, 0, 5, + 24, 0, sidetone_tlv), + + SOC_DOUBLE_R_TLV("AIF1ADC1 Volume", WM8995_AIF1_ADC1_LEFT_VOLUME, + WM8995_AIF1_ADC1_RIGHT_VOLUME, 0, 96, 0, digital_tlv), + SOC_DOUBLE_R_TLV("AIF1ADC2 Volume", WM8995_AIF1_ADC2_LEFT_VOLUME, + WM8995_AIF1_ADC2_RIGHT_VOLUME, 0, 96, 0, digital_tlv), + SOC_DOUBLE_R_TLV("AIF2ADC Volume", WM8995_AIF2_ADC_LEFT_VOLUME, + WM8995_AIF2_ADC_RIGHT_VOLUME, 0, 96, 0, digital_tlv) +}; + +static void wm8995_update_class_w(struct snd_soc_codec *codec) +{ + int enable = 1; + int source = 0; /* GCC flow analysis can't track enable */ + int reg, reg_r; + + /* We also need the same setting for L/R and only one path */ + reg = snd_soc_read(codec, WM8995_DAC1_LEFT_MIXER_ROUTING); + switch (reg) { + case WM8995_AIF2DACL_TO_DAC1L: + dev_dbg(codec->dev, "Class W source AIF2DAC\n"); + source = 2 << WM8995_CP_DYN_SRC_SEL_SHIFT; + break; + case WM8995_AIF1DAC2L_TO_DAC1L: + dev_dbg(codec->dev, "Class W source AIF1DAC2\n"); + source = 1 << WM8995_CP_DYN_SRC_SEL_SHIFT; + break; + case WM8995_AIF1DAC1L_TO_DAC1L: + dev_dbg(codec->dev, "Class W source AIF1DAC1\n"); + source = 0 << WM8995_CP_DYN_SRC_SEL_SHIFT; + break; + default: + dev_dbg(codec->dev, "DAC mixer setting: %x\n", reg); + enable = 0; + break; + } + + reg_r = snd_soc_read(codec, WM8995_DAC1_RIGHT_MIXER_ROUTING); + if (reg_r != reg) { + dev_dbg(codec->dev, "Left and right DAC mixers different\n"); + enable = 0; + } + + if (enable) { + dev_dbg(codec->dev, "Class W enabled\n"); + snd_soc_update_bits(codec, WM8995_CLASS_W_1, + WM8995_CP_DYN_PWR_MASK | + WM8995_CP_DYN_SRC_SEL_MASK, + source | WM8995_CP_DYN_PWR); + } else { + dev_dbg(codec->dev, "Class W disabled\n"); + snd_soc_update_bits(codec, WM8995_CLASS_W_1, + WM8995_CP_DYN_PWR_MASK, 0); + } +} + +static int check_clk_sys(struct snd_soc_dapm_widget *source, + struct snd_soc_dapm_widget *sink) +{ + unsigned int reg; + const char *clk; + + reg = snd_soc_read(source->codec, WM8995_CLOCKING_1); + /* Check what we're currently using for CLK_SYS */ + if (reg & WM8995_SYSCLK_SRC) + clk = "AIF2CLK"; + else + clk = "AIF1CLK"; + return !strcmp(source->name, clk); +} + +static int wm8995_put_class_w(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_soc_dapm_widget *w; + struct snd_soc_codec *codec; + int ret; + + w = snd_kcontrol_chip(kcontrol); + codec = w->codec; + ret = snd_soc_dapm_put_volsw(kcontrol, ucontrol); + wm8995_update_class_w(codec); + return ret; +} + +static int hp_supply_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec; + struct wm8995_priv *wm8995; + + codec = w->codec; + wm8995 = snd_soc_codec_get_drvdata(codec); + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + /* Enable the headphone amp */ + snd_soc_update_bits(codec, WM8995_POWER_MANAGEMENT_1, + WM8995_HPOUT1L_ENA_MASK | + WM8995_HPOUT1R_ENA_MASK, + WM8995_HPOUT1L_ENA | + WM8995_HPOUT1R_ENA); + + /* Enable the second stage */ + snd_soc_update_bits(codec, WM8995_ANALOGUE_HP_1, + WM8995_HPOUT1L_DLY_MASK | + WM8995_HPOUT1R_DLY_MASK, + WM8995_HPOUT1L_DLY | + WM8995_HPOUT1R_DLY); + break; + case SND_SOC_DAPM_PRE_PMD: + snd_soc_update_bits(codec, WM8995_CHARGE_PUMP_1, + WM8995_CP_ENA_MASK, 0); + break; + } + + return 0; +} + +static void dc_servo_cmd(struct snd_soc_codec *codec, + unsigned int reg, unsigned int val, unsigned int mask) +{ + int timeout = 10; + + dev_dbg(codec->dev, "%s: reg = %#x, val = %#x, mask = %#x\n", + __func__, reg, val, mask); + + snd_soc_write(codec, reg, val); + while (timeout--) { + msleep(10); + val = snd_soc_read(codec, WM8995_DC_SERVO_READBACK_0); + if ((val & mask) == mask) + return; + } + + dev_err(codec->dev, "Timed out waiting for DC Servo\n"); +} + +static int hp_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec; + unsigned int reg; + + codec = w->codec; + reg = snd_soc_read(codec, WM8995_ANALOGUE_HP_1); + + switch (event) { + case SND_SOC_DAPM_POST_PMU: + snd_soc_update_bits(codec, WM8995_CHARGE_PUMP_1, + WM8995_CP_ENA_MASK, WM8995_CP_ENA); + + msleep(5); + + snd_soc_update_bits(codec, WM8995_POWER_MANAGEMENT_1, + WM8995_HPOUT1L_ENA_MASK | + WM8995_HPOUT1R_ENA_MASK, + WM8995_HPOUT1L_ENA | WM8995_HPOUT1R_ENA); + + udelay(20); + + reg |= WM8995_HPOUT1L_DLY | WM8995_HPOUT1R_DLY; + snd_soc_write(codec, WM8995_ANALOGUE_HP_1, reg); + + snd_soc_write(codec, WM8995_DC_SERVO_1, WM8995_DCS_ENA_CHAN_0 | + WM8995_DCS_ENA_CHAN_1); + + dc_servo_cmd(codec, WM8995_DC_SERVO_2, + WM8995_DCS_TRIG_STARTUP_0 | + WM8995_DCS_TRIG_STARTUP_1, + WM8995_DCS_TRIG_DAC_WR_0 | + WM8995_DCS_TRIG_DAC_WR_1); + + reg |= WM8995_HPOUT1R_OUTP | WM8995_HPOUT1R_RMV_SHORT | + WM8995_HPOUT1L_OUTP | WM8995_HPOUT1L_RMV_SHORT; + snd_soc_write(codec, WM8995_ANALOGUE_HP_1, reg); + + break; + case SND_SOC_DAPM_PRE_PMD: + snd_soc_update_bits(codec, WM8995_ANALOGUE_HP_1, + WM8995_HPOUT1L_OUTP_MASK | + WM8995_HPOUT1R_OUTP_MASK | + WM8995_HPOUT1L_RMV_SHORT_MASK | + WM8995_HPOUT1R_RMV_SHORT_MASK, 0); + + snd_soc_update_bits(codec, WM8995_ANALOGUE_HP_1, + WM8995_HPOUT1L_DLY_MASK | + WM8995_HPOUT1R_DLY_MASK, 0); + + snd_soc_write(codec, WM8995_DC_SERVO_1, 0); + + snd_soc_update_bits(codec, WM8995_POWER_MANAGEMENT_1, + WM8995_HPOUT1L_ENA_MASK | + WM8995_HPOUT1R_ENA_MASK, + 0); + break; + } + + return 0; +} + +static int configure_aif_clock(struct snd_soc_codec *codec, int aif) +{ + struct wm8995_priv *wm8995; + int rate; + int reg1 = 0; + int offset; + + wm8995 = snd_soc_codec_get_drvdata(codec); + + if (aif) + offset = 4; + else + offset = 0; + + switch (wm8995->sysclk[aif]) { + case WM8995_SYSCLK_MCLK1: + rate = wm8995->mclk[0]; + break; + case WM8995_SYSCLK_MCLK2: + reg1 |= 0x8; + rate = wm8995->mclk[1]; + break; + case WM8995_SYSCLK_FLL1: + reg1 |= 0x10; + rate = wm8995->fll[0].out; + break; + case WM8995_SYSCLK_FLL2: + reg1 |= 0x18; + rate = wm8995->fll[1].out; + break; + default: + return -EINVAL; + } + + if (rate >= 13500000) { + rate /= 2; + reg1 |= WM8995_AIF1CLK_DIV; + + dev_dbg(codec->dev, "Dividing AIF%d clock to %dHz\n", + aif + 1, rate); + } + + wm8995->aifclk[aif] = rate; + + snd_soc_update_bits(codec, WM8995_AIF1_CLOCKING_1 + offset, + WM8995_AIF1CLK_SRC_MASK | WM8995_AIF1CLK_DIV_MASK, + reg1); + return 0; +} + +static int configure_clock(struct snd_soc_codec *codec) +{ + struct wm8995_priv *wm8995; + int old, new; + + wm8995 = snd_soc_codec_get_drvdata(codec); + + /* Bring up the AIF clocks first */ + configure_aif_clock(codec, 0); + configure_aif_clock(codec, 1); + + /* + * Then switch CLK_SYS over to the higher of them; a change + * can only happen as a result of a clocking change which can + * only be made outside of DAPM so we can safely redo the + * clocking. + */ + + /* If they're equal it doesn't matter which is used */ + if (wm8995->aifclk[0] == wm8995->aifclk[1]) + return 0; + + if (wm8995->aifclk[0] < wm8995->aifclk[1]) + new = WM8995_SYSCLK_SRC; + else + new = 0; + + old = snd_soc_read(codec, WM8995_CLOCKING_1) & WM8995_SYSCLK_SRC; + + /* If there's no change then we're done. */ + if (old == new) + return 0; + + snd_soc_update_bits(codec, WM8995_CLOCKING_1, + WM8995_SYSCLK_SRC_MASK, new); + + snd_soc_dapm_sync(&codec->dapm); + + return 0; +} + +static int clk_sys_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *kcontrol, int event) +{ + struct snd_soc_codec *codec; + + codec = w->codec; + + switch (event) { + case SND_SOC_DAPM_PRE_PMU: + return configure_clock(codec); + + case SND_SOC_DAPM_POST_PMD: + configure_clock(codec); + break; + } + + return 0; +} + +static const char *sidetone_text[] = { + "ADC/DMIC1", "DMIC2", +}; + +static const struct soc_enum sidetone1_enum = + SOC_ENUM_SINGLE(WM8995_SIDETONE, 0, 2, sidetone_text); + +static const struct snd_kcontrol_new sidetone1_mux = + SOC_DAPM_ENUM("Left Sidetone Mux", sidetone1_enum); + +static const struct soc_enum sidetone2_enum = + SOC_ENUM_SINGLE(WM8995_SIDETONE, 1, 2, sidetone_text); + +static const struct snd_kcontrol_new sidetone2_mux = + SOC_DAPM_ENUM("Right Sidetone Mux", sidetone2_enum); + +static const struct snd_kcontrol_new aif1adc1l_mix[] = { + SOC_DAPM_SINGLE("ADC/DMIC Switch", WM8995_AIF1_ADC1_LEFT_MIXER_ROUTING, + 1, 1, 0), + SOC_DAPM_SINGLE("AIF2 Switch", WM8995_AIF1_ADC1_LEFT_MIXER_ROUTING, + 0, 1, 0), +}; + +static const struct snd_kcontrol_new aif1adc1r_mix[] = { + SOC_DAPM_SINGLE("ADC/DMIC Switch", WM8995_AIF1_ADC1_RIGHT_MIXER_ROUTING, + 1, 1, 0), + SOC_DAPM_SINGLE("AIF2 Switch", WM8995_AIF1_ADC1_RIGHT_MIXER_ROUTING, + 0, 1, 0), +}; + +static const struct snd_kcontrol_new aif1adc2l_mix[] = { + SOC_DAPM_SINGLE("DMIC Switch", WM8995_AIF1_ADC2_LEFT_MIXER_ROUTING, + 1, 1, 0), + SOC_DAPM_SINGLE("AIF2 Switch", WM8995_AIF1_ADC2_LEFT_MIXER_ROUTING, + 0, 1, 0), +}; + +static const struct snd_kcontrol_new aif1adc2r_mix[] = { + SOC_DAPM_SINGLE("DMIC Switch", WM8995_AIF1_ADC2_RIGHT_MIXER_ROUTING, + 1, 1, 0), + SOC_DAPM_SINGLE("AIF2 Switch", WM8995_AIF1_ADC2_RIGHT_MIXER_ROUTING, + 0, 1, 0), +}; + +static const struct snd_kcontrol_new dac1l_mix[] = { + WM8995_CLASS_W_SWITCH("Right Sidetone Switch", WM8995_DAC1_LEFT_MIXER_ROUTING, + 5, 1, 0), + WM8995_CLASS_W_SWITCH("Left Sidetone Switch", WM8995_DAC1_LEFT_MIXER_ROUTING, + 4, 1, 0), + WM8995_CLASS_W_SWITCH("AIF2 Switch", WM8995_DAC1_LEFT_MIXER_ROUTING, + 2, 1, 0), + WM8995_CLASS_W_SWITCH("AIF1.2 Switch", WM8995_DAC1_LEFT_MIXER_ROUTING, + 1, 1, 0), + WM8995_CLASS_W_SWITCH("AIF1.1 Switch", WM8995_DAC1_LEFT_MIXER_ROUTING, + 0, 1, 0), +}; + +static const struct snd_kcontrol_new dac1r_mix[] = { + WM8995_CLASS_W_SWITCH("Right Sidetone Switch", WM8995_DAC1_RIGHT_MIXER_ROUTING, + 5, 1, 0), + WM8995_CLASS_W_SWITCH("Left Sidetone Switch", WM8995_DAC1_RIGHT_MIXER_ROUTING, + 4, 1, 0), + WM8995_CLASS_W_SWITCH("AIF2 Switch", WM8995_DAC1_RIGHT_MIXER_ROUTING, + 2, 1, 0), + WM8995_CLASS_W_SWITCH("AIF1.2 Switch", WM8995_DAC1_RIGHT_MIXER_ROUTING, + 1, 1, 0), + WM8995_CLASS_W_SWITCH("AIF1.1 Switch", WM8995_DAC1_RIGHT_MIXER_ROUTING, + 0, 1, 0), +}; + +static const struct snd_kcontrol_new aif2dac2l_mix[] = { + SOC_DAPM_SINGLE("Right Sidetone Switch", WM8995_DAC2_LEFT_MIXER_ROUTING, + 5, 1, 0), + SOC_DAPM_SINGLE("Left Sidetone Switch", WM8995_DAC2_LEFT_MIXER_ROUTING, + 4, 1, 0), + SOC_DAPM_SINGLE("AIF2 Switch", WM8995_DAC2_LEFT_MIXER_ROUTING, + 2, 1, 0), + SOC_DAPM_SINGLE("AIF1.2 Switch", WM8995_DAC2_LEFT_MIXER_ROUTING, + 1, 1, 0), + SOC_DAPM_SINGLE("AIF1.1 Switch", WM8995_DAC2_LEFT_MIXER_ROUTING, + 0, 1, 0), +}; + +static const struct snd_kcontrol_new aif2dac2r_mix[] = { + SOC_DAPM_SINGLE("Right Sidetone Switch", WM8995_DAC2_RIGHT_MIXER_ROUTING, + 5, 1, 0), + SOC_DAPM_SINGLE("Left Sidetone Switch", WM8995_DAC2_RIGHT_MIXER_ROUTING, + 4, 1, 0), + SOC_DAPM_SINGLE("AIF2 Switch", WM8995_DAC2_RIGHT_MIXER_ROUTING, + 2, 1, 0), + SOC_DAPM_SINGLE("AIF1.2 Switch", WM8995_DAC2_RIGHT_MIXER_ROUTING, + 1, 1, 0), + SOC_DAPM_SINGLE("AIF1.1 Switch", WM8995_DAC2_RIGHT_MIXER_ROUTING, + 0, 1, 0), +}; + +static const struct snd_kcontrol_new in1l_pga = + SOC_DAPM_SINGLE("IN1L Switch", WM8995_POWER_MANAGEMENT_2, 5, 1, 0); + +static const struct snd_kcontrol_new in1r_pga = + SOC_DAPM_SINGLE("IN1R Switch", WM8995_POWER_MANAGEMENT_2, 4, 1, 0); + +static const char *adc_mux_text[] = { + "ADC", + "DMIC", +}; + +static const struct soc_enum adc_enum = + SOC_ENUM_SINGLE(0, 0, 2, adc_mux_text); + +static const struct snd_kcontrol_new adcl_mux = + SOC_DAPM_ENUM_VIRT("ADCL Mux", adc_enum); + +static const struct snd_kcontrol_new adcr_mux = + SOC_DAPM_ENUM_VIRT("ADCR Mux", adc_enum); + +static const char *spk_src_text[] = { + "DAC1L", "DAC1R", "DAC2L", "DAC2R" +}; + +static const SOC_ENUM_SINGLE_DECL(spk1l_src_enum, WM8995_LEFT_PDM_SPEAKER_1, + 0, spk_src_text); +static const SOC_ENUM_SINGLE_DECL(spk1r_src_enum, WM8995_RIGHT_PDM_SPEAKER_1, + 0, spk_src_text); +static const SOC_ENUM_SINGLE_DECL(spk2l_src_enum, WM8995_LEFT_PDM_SPEAKER_2, + 0, spk_src_text); +static const SOC_ENUM_SINGLE_DECL(spk2r_src_enum, WM8995_RIGHT_PDM_SPEAKER_2, + 0, spk_src_text); + +static const struct snd_kcontrol_new spk1l_mux = + SOC_DAPM_ENUM("SPK1L SRC", spk1l_src_enum); +static const struct snd_kcontrol_new spk1r_mux = + SOC_DAPM_ENUM("SPK1R SRC", spk1r_src_enum); +static const struct snd_kcontrol_new spk2l_mux = + SOC_DAPM_ENUM("SPK2L SRC", spk2l_src_enum); +static const struct snd_kcontrol_new spk2r_mux = + SOC_DAPM_ENUM("SPK2R SRC", spk2r_src_enum); + +static const struct snd_soc_dapm_widget wm8995_dapm_widgets[] = { + SND_SOC_DAPM_INPUT("DMIC1DAT"), + SND_SOC_DAPM_INPUT("DMIC2DAT"), + + SND_SOC_DAPM_INPUT("IN1L"), + SND_SOC_DAPM_INPUT("IN1R"), + + SND_SOC_DAPM_MIXER("IN1L PGA", SND_SOC_NOPM, 0, 0, + &in1l_pga, 1), + SND_SOC_DAPM_MIXER("IN1R PGA", SND_SOC_NOPM, 0, 0, + &in1r_pga, 1), + + SND_SOC_DAPM_MICBIAS("MICBIAS1", WM8995_POWER_MANAGEMENT_1, 8, 0), + SND_SOC_DAPM_MICBIAS("MICBIAS2", WM8995_POWER_MANAGEMENT_1, 9, 0), + + SND_SOC_DAPM_SUPPLY("AIF1CLK", WM8995_AIF1_CLOCKING_1, 0, 0, NULL, 0), + SND_SOC_DAPM_SUPPLY("AIF2CLK", WM8995_AIF2_CLOCKING_1, 0, 0, NULL, 0), + SND_SOC_DAPM_SUPPLY("DSP1CLK", WM8995_CLOCKING_1, 3, 0, NULL, 0), + SND_SOC_DAPM_SUPPLY("DSP2CLK", WM8995_CLOCKING_1, 2, 0, NULL, 0), + SND_SOC_DAPM_SUPPLY("SYSDSPCLK", WM8995_CLOCKING_1, 1, 0, NULL, 0), + SND_SOC_DAPM_SUPPLY("CLK_SYS", SND_SOC_NOPM, 0, 0, clk_sys_event, + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), + + SND_SOC_DAPM_AIF_OUT("AIF1ADC1L", "AIF1 Capture", 0, + WM8995_POWER_MANAGEMENT_3, 9, 0), + SND_SOC_DAPM_AIF_OUT("AIF1ADC1R", "AIF1 Capture", 0, + WM8995_POWER_MANAGEMENT_3, 8, 0), + SND_SOC_DAPM_AIF_OUT("AIF1ADCDAT", "AIF1 Capture", 0, + SND_SOC_NOPM, 0, 0), + SND_SOC_DAPM_AIF_OUT("AIF1ADC2L", "AIF1 Capture", + 0, WM8995_POWER_MANAGEMENT_3, 11, 0), + 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_ADC("DMIC2L", NULL, WM8995_POWER_MANAGEMENT_3, 5, 0), + SND_SOC_DAPM_ADC("DMIC2R", NULL, WM8995_POWER_MANAGEMENT_3, 4, 0), + SND_SOC_DAPM_ADC("DMIC1L", NULL, WM8995_POWER_MANAGEMENT_3, 3, 0), + SND_SOC_DAPM_ADC("DMIC1R", NULL, WM8995_POWER_MANAGEMENT_3, 2, 0), + + SND_SOC_DAPM_ADC("ADCL", NULL, WM8995_POWER_MANAGEMENT_3, 1, 0), + SND_SOC_DAPM_ADC("ADCR", NULL, WM8995_POWER_MANAGEMENT_3, 0, 0), + + SND_SOC_DAPM_MIXER("AIF1ADC1L Mixer", SND_SOC_NOPM, 0, 0, + aif1adc1l_mix, ARRAY_SIZE(aif1adc1l_mix)), + SND_SOC_DAPM_MIXER("AIF1ADC1R Mixer", SND_SOC_NOPM, 0, 0, + aif1adc1r_mix, ARRAY_SIZE(aif1adc1r_mix)), + SND_SOC_DAPM_MIXER("AIF1ADC2L Mixer", SND_SOC_NOPM, 0, 0, + aif1adc2l_mix, ARRAY_SIZE(aif1adc2l_mix)), + SND_SOC_DAPM_MIXER("AIF1ADC2R Mixer", SND_SOC_NOPM, 0, 0, + aif1adc2r_mix, ARRAY_SIZE(aif1adc2r_mix)), + + SND_SOC_DAPM_AIF_IN("AIF1DAC1L", NULL, 0, WM8995_POWER_MANAGEMENT_4, + 9, 0), + SND_SOC_DAPM_AIF_IN("AIF1DAC1R", NULL, 0, WM8995_POWER_MANAGEMENT_4, + 8, 0), + SND_SOC_DAPM_AIF_IN("AIF1DACDAT", "AIF1 Playback", 0, SND_SOC_NOPM, + 0, 0), + + SND_SOC_DAPM_AIF_IN("AIF1DAC2L", NULL, 0, WM8995_POWER_MANAGEMENT_4, + 11, 0), + SND_SOC_DAPM_AIF_IN("AIF1DAC2R", NULL, 0, WM8995_POWER_MANAGEMENT_4, + 10, 0), + + SND_SOC_DAPM_MIXER("AIF2DAC2L Mixer", SND_SOC_NOPM, 0, 0, + aif2dac2l_mix, ARRAY_SIZE(aif2dac2l_mix)), + SND_SOC_DAPM_MIXER("AIF2DAC2R Mixer", SND_SOC_NOPM, 0, 0, + aif2dac2r_mix, ARRAY_SIZE(aif2dac2r_mix)), + + SND_SOC_DAPM_DAC("DAC2L", NULL, WM8995_POWER_MANAGEMENT_4, 3, 0), + SND_SOC_DAPM_DAC("DAC2R", NULL, WM8995_POWER_MANAGEMENT_4, 2, 0), + SND_SOC_DAPM_DAC("DAC1L", NULL, WM8995_POWER_MANAGEMENT_4, 1, 0), + SND_SOC_DAPM_DAC("DAC1R", NULL, WM8995_POWER_MANAGEMENT_4, 0, 0), + + SND_SOC_DAPM_MIXER("DAC1L Mixer", SND_SOC_NOPM, 0, 0, dac1l_mix, + ARRAY_SIZE(dac1l_mix)), + SND_SOC_DAPM_MIXER("DAC1R Mixer", SND_SOC_NOPM, 0, 0, dac1r_mix, + ARRAY_SIZE(dac1r_mix)), + + SND_SOC_DAPM_MUX("Left Sidetone", SND_SOC_NOPM, 0, 0, &sidetone1_mux), + SND_SOC_DAPM_MUX("Right Sidetone", SND_SOC_NOPM, 0, 0, &sidetone2_mux), + + SND_SOC_DAPM_PGA_E("Headphone PGA", SND_SOC_NOPM, 0, 0, NULL, 0, + hp_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), + + SND_SOC_DAPM_SUPPLY("Headphone Supply", SND_SOC_NOPM, 0, 0, + hp_supply_event, SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_PRE_PMD), + + SND_SOC_DAPM_MUX("SPK1L Driver", WM8995_LEFT_PDM_SPEAKER_1, + 4, 0, &spk1l_mux), + SND_SOC_DAPM_MUX("SPK1R Driver", WM8995_RIGHT_PDM_SPEAKER_1, + 4, 0, &spk1r_mux), + SND_SOC_DAPM_MUX("SPK2L Driver", WM8995_LEFT_PDM_SPEAKER_2, + 4, 0, &spk2l_mux), + SND_SOC_DAPM_MUX("SPK2R Driver", WM8995_RIGHT_PDM_SPEAKER_2, + 4, 0, &spk2r_mux), + + SND_SOC_DAPM_SUPPLY("LDO2", WM8995_POWER_MANAGEMENT_2, 1, 0, NULL, 0), + + SND_SOC_DAPM_OUTPUT("HP1L"), + SND_SOC_DAPM_OUTPUT("HP1R"), + SND_SOC_DAPM_OUTPUT("SPK1L"), + SND_SOC_DAPM_OUTPUT("SPK1R"), + SND_SOC_DAPM_OUTPUT("SPK2L"), + SND_SOC_DAPM_OUTPUT("SPK2R") +}; + +static const struct snd_soc_dapm_route wm8995_intercon[] = { + { "CLK_SYS", NULL, "AIF1CLK", check_clk_sys }, + { "CLK_SYS", NULL, "AIF2CLK", check_clk_sys }, + + { "DSP1CLK", NULL, "CLK_SYS" }, + { "DSP2CLK", NULL, "CLK_SYS" }, + { "SYSDSPCLK", NULL, "CLK_SYS" }, + + { "AIF1ADC1L", NULL, "AIF1CLK" }, + { "AIF1ADC1L", NULL, "DSP1CLK" }, + { "AIF1ADC1R", NULL, "AIF1CLK" }, + { "AIF1ADC1R", NULL, "DSP1CLK" }, + { "AIF1ADC1R", NULL, "SYSDSPCLK" }, + + { "AIF1ADC2L", NULL, "AIF1CLK" }, + { "AIF1ADC2L", NULL, "DSP1CLK" }, + { "AIF1ADC2R", NULL, "AIF1CLK" }, + { "AIF1ADC2R", NULL, "DSP1CLK" }, + { "AIF1ADC2R", NULL, "SYSDSPCLK" }, + + { "DMIC1L", NULL, "DMIC1DAT" }, + { "DMIC1L", NULL, "CLK_SYS" }, + { "DMIC1R", NULL, "DMIC1DAT" }, + { "DMIC1R", NULL, "CLK_SYS" }, + { "DMIC2L", NULL, "DMIC2DAT" }, + { "DMIC2L", NULL, "CLK_SYS" }, + { "DMIC2R", NULL, "DMIC2DAT" }, + { "DMIC2R", NULL, "CLK_SYS" }, + + { "ADCL", NULL, "AIF1CLK" }, + { "ADCL", NULL, "DSP1CLK" }, + { "ADCL", NULL, "SYSDSPCLK" }, + + { "ADCR", NULL, "AIF1CLK" }, + { "ADCR", NULL, "DSP1CLK" }, + { "ADCR", NULL, "SYSDSPCLK" }, + + { "IN1L PGA", "IN1L Switch", "IN1L" }, + { "IN1R PGA", "IN1R Switch", "IN1R" }, + { "IN1L PGA", NULL, "LDO2" }, + { "IN1R PGA", NULL, "LDO2" }, + + { "ADCL", NULL, "IN1L PGA" }, + { "ADCR", NULL, "IN1R PGA" }, + + { "ADCL Mux", "ADC", "ADCL" }, + { "ADCL Mux", "DMIC", "DMIC1L" }, + { "ADCR Mux", "ADC", "ADCR" }, + { "ADCR Mux", "DMIC", "DMIC1R" }, + + /* AIF1 outputs */ + { "AIF1ADC1L", NULL, "AIF1ADC1L Mixer" }, + { "AIF1ADC1L Mixer", "ADC/DMIC Switch", "ADCL Mux" }, + + { "AIF1ADC1R", NULL, "AIF1ADC1R Mixer" }, + { "AIF1ADC1R Mixer", "ADC/DMIC Switch", "ADCR Mux" }, + + { "AIF1ADC2L", NULL, "AIF1ADC2L Mixer" }, + { "AIF1ADC2L Mixer", "DMIC Switch", "DMIC2L" }, + + { "AIF1ADC2R", NULL, "AIF1ADC2R Mixer" }, + { "AIF1ADC2R Mixer", "DMIC Switch", "DMIC2R" }, + + /* Sidetone */ + { "Left Sidetone", "ADC/DMIC1", "AIF1ADC1L" }, + { "Left Sidetone", "DMIC2", "AIF1ADC2L" }, + { "Right Sidetone", "ADC/DMIC1", "AIF1ADC1R" }, + { "Right Sidetone", "DMIC2", "AIF1ADC2R" }, + + { "AIF1DAC1L", NULL, "AIF1CLK" }, + { "AIF1DAC1L", NULL, "DSP1CLK" }, + { "AIF1DAC1R", NULL, "AIF1CLK" }, + { "AIF1DAC1R", NULL, "DSP1CLK" }, + { "AIF1DAC1R", NULL, "SYSDSPCLK" }, + + { "AIF1DAC2L", NULL, "AIF1CLK" }, + { "AIF1DAC2L", NULL, "DSP1CLK" }, + { "AIF1DAC2R", NULL, "AIF1CLK" }, + { "AIF1DAC2R", NULL, "DSP1CLK" }, + { "AIF1DAC2R", NULL, "SYSDSPCLK" }, + + { "DAC1L", NULL, "AIF1CLK" }, + { "DAC1L", NULL, "DSP1CLK" }, + { "DAC1L", NULL, "SYSDSPCLK" }, + + { "DAC1R", NULL, "AIF1CLK" }, + { "DAC1R", NULL, "DSP1CLK" }, + { "DAC1R", NULL, "SYSDSPCLK" }, + + { "AIF1DAC1L", NULL, "AIF1DACDAT" }, + { "AIF1DAC1R", NULL, "AIF1DACDAT" }, + { "AIF1DAC2L", NULL, "AIF1DACDAT" }, + { "AIF1DAC2R", NULL, "AIF1DACDAT" }, + + /* DAC1 inputs */ + { "DAC1L", NULL, "DAC1L Mixer" }, + { "DAC1L Mixer", "AIF1.1 Switch", "AIF1DAC1L" }, + { "DAC1L Mixer", "AIF1.2 Switch", "AIF1DAC2L" }, + { "DAC1L Mixer", "Left Sidetone Switch", "Left Sidetone" }, + { "DAC1L Mixer", "Right Sidetone Switch", "Right Sidetone" }, + + { "DAC1R", NULL, "DAC1R Mixer" }, + { "DAC1R Mixer", "AIF1.1 Switch", "AIF1DAC1R" }, + { "DAC1R Mixer", "AIF1.2 Switch", "AIF1DAC2R" }, + { "DAC1R Mixer", "Left Sidetone Switch", "Left Sidetone" }, + { "DAC1R Mixer", "Right Sidetone Switch", "Right Sidetone" }, + + /* DAC2/AIF2 outputs */ + { "DAC2L", NULL, "AIF2DAC2L Mixer" }, + { "AIF2DAC2L Mixer", "AIF1.2 Switch", "AIF1DAC2L" }, + { "AIF2DAC2L Mixer", "AIF1.1 Switch", "AIF1DAC1L" }, + + { "DAC2R", NULL, "AIF2DAC2R Mixer" }, + { "AIF2DAC2R Mixer", "AIF1.2 Switch", "AIF1DAC2R" }, + { "AIF2DAC2R Mixer", "AIF1.1 Switch", "AIF1DAC1R" }, + + /* Output stages */ + { "Headphone PGA", NULL, "DAC1L" }, + { "Headphone PGA", NULL, "DAC1R" }, + + { "Headphone PGA", NULL, "DAC2L" }, + { "Headphone PGA", NULL, "DAC2R" }, + + { "Headphone PGA", NULL, "Headphone Supply" }, + { "Headphone PGA", NULL, "CLK_SYS" }, + { "Headphone PGA", NULL, "LDO2" }, + + { "HP1L", NULL, "Headphone PGA" }, + { "HP1R", NULL, "Headphone PGA" }, + + { "SPK1L Driver", "DAC1L", "DAC1L" }, + { "SPK1L Driver", "DAC1R", "DAC1R" }, + { "SPK1L Driver", "DAC2L", "DAC2L" }, + { "SPK1L Driver", "DAC2R", "DAC2R" }, + { "SPK1L Driver", NULL, "CLK_SYS" }, + + { "SPK1R Driver", "DAC1L", "DAC1L" }, + { "SPK1R Driver", "DAC1R", "DAC1R" }, + { "SPK1R Driver", "DAC2L", "DAC2L" }, + { "SPK1R Driver", "DAC2R", "DAC2R" }, + { "SPK1R Driver", NULL, "CLK_SYS" }, + + { "SPK2L Driver", "DAC1L", "DAC1L" }, + { "SPK2L Driver", "DAC1R", "DAC1R" }, + { "SPK2L Driver", "DAC2L", "DAC2L" }, + { "SPK2L Driver", "DAC2R", "DAC2R" }, + { "SPK2L Driver", NULL, "CLK_SYS" }, + + { "SPK2R Driver", "DAC1L", "DAC1L" }, + { "SPK2R Driver", "DAC1R", "DAC1R" }, + { "SPK2R Driver", "DAC2L", "DAC2L" }, + { "SPK2R Driver", "DAC2R", "DAC2R" }, + { "SPK2R Driver", NULL, "CLK_SYS" }, + + { "SPK1L", NULL, "SPK1L Driver" }, + { "SPK1R", NULL, "SPK1R Driver" }, + { "SPK2L", NULL, "SPK2L Driver" }, + { "SPK2R", NULL, "SPK2R Driver" } +}; + +static int wm8995_volatile(unsigned int reg) +{ + /* out of bounds registers are generally considered + * volatile to support register banks that are partially + * owned by something else for e.g. a DSP + */ + if (reg > WM8995_MAX_CACHED_REGISTER) + return 1; + + switch (reg) { + case WM8995_SOFTWARE_RESET: + case WM8995_DC_SERVO_READBACK_0: + case WM8995_INTERRUPT_STATUS_1: + case WM8995_INTERRUPT_STATUS_2: + case WM8995_INTERRUPT_STATUS_1_MASK: + case WM8995_INTERRUPT_STATUS_2_MASK: + case WM8995_INTERRUPT_CONTROL: + case WM8995_ACCESSORY_DETECT_MODE1: + case WM8995_ACCESSORY_DETECT_MODE2: + case WM8995_HEADPHONE_DETECT1: + case WM8995_HEADPHONE_DETECT2: + return 1; + } + + return 0; +} + +static int wm8995_aif_mute(struct snd_soc_dai *dai, int mute) +{ + struct snd_soc_codec *codec = dai->codec; + int mute_reg; + + switch (dai->id) { + case 0: + mute_reg = WM8995_AIF1_DAC1_FILTERS_1; + break; + case 1: + mute_reg = WM8995_AIF2_DAC_FILTERS_1; + break; + default: + return -EINVAL; + } + + snd_soc_update_bits(codec, mute_reg, WM8995_AIF1DAC1_MUTE_MASK, + !!mute << WM8995_AIF1DAC1_MUTE_SHIFT); + return 0; +} + +static int wm8995_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt) +{ + struct snd_soc_codec *codec; + int master; + int aif; + + codec = dai->codec; + + master = 0; + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { + case SND_SOC_DAIFMT_CBS_CFS: + break; + case SND_SOC_DAIFMT_CBM_CFM: + master = WM8995_AIF1_MSTR; + break; + default: + dev_err(dai->dev, "Unknown master/slave configuration\n"); + return -EINVAL; + } + + aif = 0; + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { + case SND_SOC_DAIFMT_DSP_B: + aif |= WM8995_AIF1_LRCLK_INV; + case SND_SOC_DAIFMT_DSP_A: + aif |= (0x3 << WM8995_AIF1_FMT_SHIFT); + break; + case SND_SOC_DAIFMT_I2S: + aif |= (0x2 << WM8995_AIF1_FMT_SHIFT); + break; + case SND_SOC_DAIFMT_RIGHT_J: + break; + case SND_SOC_DAIFMT_LEFT_J: + aif |= (0x1 << WM8995_AIF1_FMT_SHIFT); + break; + default: + dev_err(dai->dev, "Unknown dai format\n"); + return -EINVAL; + } + + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { + case SND_SOC_DAIFMT_DSP_A: + case SND_SOC_DAIFMT_DSP_B: + /* frame inversion not valid for DSP modes */ + switch (fmt & SND_SOC_DAIFMT_INV_MASK) { + case SND_SOC_DAIFMT_NB_NF: + break; + case SND_SOC_DAIFMT_IB_NF: + aif |= WM8995_AIF1_BCLK_INV; + break; + default: + return -EINVAL; + } + break; + + case SND_SOC_DAIFMT_I2S: + case SND_SOC_DAIFMT_RIGHT_J: + case SND_SOC_DAIFMT_LEFT_J: + switch (fmt & SND_SOC_DAIFMT_INV_MASK) { + case SND_SOC_DAIFMT_NB_NF: + break; + case SND_SOC_DAIFMT_IB_IF: + aif |= WM8995_AIF1_BCLK_INV | WM8995_AIF1_LRCLK_INV; + break; + case SND_SOC_DAIFMT_IB_NF: + aif |= WM8995_AIF1_BCLK_INV; + break; + case SND_SOC_DAIFMT_NB_IF: + aif |= WM8995_AIF1_LRCLK_INV; + break; + default: + return -EINVAL; + } + break; + default: + return -EINVAL; + } + + snd_soc_update_bits(codec, WM8995_AIF1_CONTROL_1, + WM8995_AIF1_BCLK_INV_MASK | + WM8995_AIF1_LRCLK_INV_MASK | + WM8995_AIF1_FMT_MASK, aif); + snd_soc_update_bits(codec, WM8995_AIF1_MASTER_SLAVE, + WM8995_AIF1_MSTR_MASK, master); + return 0; +} + +static const int srs[] = { + 8000, 11025, 12000, 16000, 22050, 24000, 32000, 44100, + 48000, 88200, 96000 +}; + +static const int fs_ratios[] = { + -1 /* reserved */, + 128, 192, 256, 384, 512, 768, 1024, 1408, 1536 +}; + +static const int bclk_divs[] = { + 10, 15, 20, 30, 40, 55, 60, 80, 110, 120, 160, 220, 240, 320, 440, 480 +}; + +static int wm8995_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct snd_soc_codec *codec; + struct wm8995_priv *wm8995; + int aif1_reg; + int bclk_reg; + int lrclk_reg; + int rate_reg; + int bclk_rate; + int aif1; + int lrclk, bclk; + int i, rate_val, best, best_val, cur_val; + + codec = dai->codec; + wm8995 = snd_soc_codec_get_drvdata(codec); + + switch (dai->id) { + case 0: + aif1_reg = WM8995_AIF1_CONTROL_1; + bclk_reg = WM8995_AIF1_BCLK; + rate_reg = WM8995_AIF1_RATE; + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK /* || + wm8995->lrclk_shared[0] */) { + lrclk_reg = WM8995_AIF1DAC_LRCLK; + } else { + lrclk_reg = WM8995_AIF1ADC_LRCLK; + dev_dbg(codec->dev, "AIF1 using split LRCLK\n"); + } + break; + case 1: + aif1_reg = WM8995_AIF2_CONTROL_1; + bclk_reg = WM8995_AIF2_BCLK; + rate_reg = WM8995_AIF2_RATE; + if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK /* || + wm8995->lrclk_shared[1] */) { + lrclk_reg = WM8995_AIF2DAC_LRCLK; + } else { + lrclk_reg = WM8995_AIF2ADC_LRCLK; + dev_dbg(codec->dev, "AIF2 using split LRCLK\n"); + } + break; + default: + return -EINVAL; + } + + bclk_rate = snd_soc_params_to_bclk(params); + if (bclk_rate < 0) + return bclk_rate; + + aif1 = 0; + switch (params_format(params)) { + case SNDRV_PCM_FORMAT_S16_LE: + break; + case SNDRV_PCM_FORMAT_S20_3LE: + aif1 |= (0x1 << WM8995_AIF1_WL_SHIFT); + break; + case SNDRV_PCM_FORMAT_S24_LE: + aif1 |= (0x2 << WM8995_AIF1_WL_SHIFT); + break; + case SNDRV_PCM_FORMAT_S32_LE: + aif1 |= (0x3 << WM8995_AIF1_WL_SHIFT); + break; + default: + dev_err(dai->dev, "Unsupported word length %u\n", + params_format(params)); + return -EINVAL; + } + + /* try to find a suitable sample rate */ + for (i = 0; i < ARRAY_SIZE(srs); ++i) + if (srs[i] == params_rate(params)) + break; + if (i == ARRAY_SIZE(srs)) { + dev_err(dai->dev, "Sample rate %d is not supported\n", + params_rate(params)); + return -EINVAL; + } + rate_val = i << WM8995_AIF1_SR_SHIFT; + + dev_dbg(dai->dev, "Sample rate is %dHz\n", srs[i]); + dev_dbg(dai->dev, "AIF%dCLK is %dHz, target BCLK %dHz\n", + dai->id + 1, wm8995->aifclk[dai->id], bclk_rate); + + /* AIFCLK/fs ratio; look for a close match in either direction */ + best = 1; + best_val = abs((fs_ratios[1] * params_rate(params)) + - wm8995->aifclk[dai->id]); + for (i = 2; i < ARRAY_SIZE(fs_ratios); i++) { + cur_val = abs((fs_ratios[i] * params_rate(params)) + - wm8995->aifclk[dai->id]); + if (cur_val >= best_val) + continue; + best = i; + best_val = cur_val; + } + rate_val |= best; + + dev_dbg(dai->dev, "Selected AIF%dCLK/fs = %d\n", + dai->id + 1, fs_ratios[best]); + + /* + * We may not get quite the right frequency if using + * approximate clocks so look for the closest match that is + * higher than the target (we need to ensure that there enough + * BCLKs to clock out the samples). + */ + best = 0; + bclk = 0; + for (i = 0; i < ARRAY_SIZE(bclk_divs); i++) { + cur_val = (wm8995->aifclk[dai->id] * 10 / bclk_divs[i]) - bclk_rate; + if (cur_val < 0) /* BCLK table is sorted */ + break; + best = i; + } + bclk |= best << WM8995_AIF1_BCLK_DIV_SHIFT; + + bclk_rate = wm8995->aifclk[dai->id] * 10 / bclk_divs[best]; + dev_dbg(dai->dev, "Using BCLK_DIV %d for actual BCLK %dHz\n", + bclk_divs[best], bclk_rate); + + lrclk = bclk_rate / params_rate(params); + dev_dbg(dai->dev, "Using LRCLK rate %d for actual LRCLK %dHz\n", + lrclk, bclk_rate / lrclk); + + snd_soc_update_bits(codec, aif1_reg, + WM8995_AIF1_WL_MASK, aif1); + snd_soc_update_bits(codec, bclk_reg, + WM8995_AIF1_BCLK_DIV_MASK, bclk); + snd_soc_update_bits(codec, lrclk_reg, + WM8995_AIF1DAC_RATE_MASK, lrclk); + snd_soc_update_bits(codec, rate_reg, + WM8995_AIF1_SR_MASK | + WM8995_AIF1CLK_RATE_MASK, rate_val); + return 0; +} + +static int wm8995_set_tristate(struct snd_soc_dai *codec_dai, int tristate) +{ + struct snd_soc_codec *codec = codec_dai->codec; + int reg, val, mask; + + switch (codec_dai->id) { + case 0: + reg = WM8995_AIF1_MASTER_SLAVE; + mask = WM8995_AIF1_TRI; + break; + case 1: + reg = WM8995_AIF2_MASTER_SLAVE; + mask = WM8995_AIF2_TRI; + break; + case 2: + reg = WM8995_POWER_MANAGEMENT_5; + mask = WM8995_AIF3_TRI; + break; + default: + return -EINVAL; + } + + if (tristate) + val = mask; + else + val = 0; + + return snd_soc_update_bits(codec, reg, mask, reg); +} + +/* The size in bits of the FLL divide multiplied by 10 + * to allow rounding later */ +#define FIXED_FLL_SIZE ((1 << 16) * 10) + +struct fll_div { + u16 outdiv; + u16 n; + u16 k; + u16 clk_ref_div; + u16 fll_fratio; +}; + +static int wm8995_get_fll_config(struct fll_div *fll, + int freq_in, int freq_out) +{ + u64 Kpart; + unsigned int K, Ndiv, Nmod; + + pr_debug("FLL input=%dHz, output=%dHz\n", freq_in, freq_out); + + /* Scale the input frequency down to <= 13.5MHz */ + fll->clk_ref_div = 0; + while (freq_in > 13500000) { + fll->clk_ref_div++; + freq_in /= 2; + + if (fll->clk_ref_div > 3) + return -EINVAL; + } + pr_debug("CLK_REF_DIV=%d, Fref=%dHz\n", fll->clk_ref_div, freq_in); + + /* Scale the output to give 90MHz<=Fvco<=100MHz */ + fll->outdiv = 3; + while (freq_out * (fll->outdiv + 1) < 90000000) { + fll->outdiv++; + if (fll->outdiv > 63) + return -EINVAL; + } + freq_out *= fll->outdiv + 1; + pr_debug("OUTDIV=%d, Fvco=%dHz\n", fll->outdiv, freq_out); + + if (freq_in > 1000000) { + fll->fll_fratio = 0; + } else if (freq_in > 256000) { + fll->fll_fratio = 1; + freq_in *= 2; + } else if (freq_in > 128000) { + fll->fll_fratio = 2; + freq_in *= 4; + } else if (freq_in > 64000) { + fll->fll_fratio = 3; + freq_in *= 8; + } else { + fll->fll_fratio = 4; + freq_in *= 16; + } + pr_debug("FLL_FRATIO=%d, Fref=%dHz\n", fll->fll_fratio, freq_in); + + /* Now, calculate N.K */ + Ndiv = freq_out / freq_in; + + fll->n = Ndiv; + Nmod = freq_out % freq_in; + pr_debug("Nmod=%d\n", Nmod); + + /* Calculate fractional part - scale up so we can round. */ + Kpart = FIXED_FLL_SIZE * (long long)Nmod; + + do_div(Kpart, freq_in); + + K = Kpart & 0xFFFFFFFF; + + if ((K % 10) >= 5) + K += 5; + + /* Move down to proper range now rounding is done */ + fll->k = K / 10; + + pr_debug("N=%x K=%x\n", fll->n, fll->k); + + return 0; +} + +static int wm8995_set_fll(struct snd_soc_dai *dai, int id, + int src, unsigned int freq_in, + unsigned int freq_out) +{ + struct snd_soc_codec *codec; + struct wm8995_priv *wm8995; + int reg_offset, ret; + struct fll_div fll; + u16 reg, aif1, aif2; + + codec = dai->codec; + wm8995 = snd_soc_codec_get_drvdata(codec); + + aif1 = snd_soc_read(codec, WM8995_AIF1_CLOCKING_1) + & WM8995_AIF1CLK_ENA; + + aif2 = snd_soc_read(codec, WM8995_AIF2_CLOCKING_1) + & WM8995_AIF2CLK_ENA; + + switch (id) { + case WM8995_FLL1: + reg_offset = 0; + id = 0; + break; + case WM8995_FLL2: + reg_offset = 0x20; + id = 1; + break; + default: + return -EINVAL; + } + + switch (src) { + case 0: + /* Allow no source specification when stopping */ + if (freq_out) + return -EINVAL; + break; + case WM8995_FLL_SRC_MCLK1: + case WM8995_FLL_SRC_MCLK2: + case WM8995_FLL_SRC_LRCLK: + case WM8995_FLL_SRC_BCLK: + break; + default: + return -EINVAL; + } + + /* Are we changing anything? */ + if (wm8995->fll[id].src == src && + wm8995->fll[id].in == freq_in && wm8995->fll[id].out == freq_out) + return 0; + + /* If we're stopping the FLL redo the old config - no + * registers will actually be written but we avoid GCC flow + * analysis bugs spewing warnings. + */ + if (freq_out) + ret = wm8995_get_fll_config(&fll, freq_in, freq_out); + else + ret = wm8995_get_fll_config(&fll, wm8995->fll[id].in, + wm8995->fll[id].out); + if (ret < 0) + return ret; + + /* Gate the AIF clocks while we reclock */ + snd_soc_update_bits(codec, WM8995_AIF1_CLOCKING_1, + WM8995_AIF1CLK_ENA_MASK, 0); + snd_soc_update_bits(codec, WM8995_AIF2_CLOCKING_1, + WM8995_AIF2CLK_ENA_MASK, 0); + + /* We always need to disable the FLL while reconfiguring */ + snd_soc_update_bits(codec, WM8995_FLL1_CONTROL_1 + reg_offset, + WM8995_FLL1_ENA_MASK, 0); + + reg = (fll.outdiv << WM8995_FLL1_OUTDIV_SHIFT) | + (fll.fll_fratio << WM8995_FLL1_FRATIO_SHIFT); + snd_soc_update_bits(codec, WM8995_FLL1_CONTROL_2 + reg_offset, + WM8995_FLL1_OUTDIV_MASK | + WM8995_FLL1_FRATIO_MASK, reg); + + snd_soc_write(codec, WM8995_FLL1_CONTROL_3 + reg_offset, fll.k); + + snd_soc_update_bits(codec, WM8995_FLL1_CONTROL_4 + reg_offset, + WM8995_FLL1_N_MASK, + fll.n << WM8995_FLL1_N_SHIFT); + + snd_soc_update_bits(codec, WM8995_FLL1_CONTROL_5 + reg_offset, + WM8995_FLL1_REFCLK_DIV_MASK | + WM8995_FLL1_REFCLK_SRC_MASK, + (fll.clk_ref_div << WM8995_FLL1_REFCLK_DIV_SHIFT) | + (src - 1)); + + if (freq_out) + snd_soc_update_bits(codec, WM8995_FLL1_CONTROL_1 + reg_offset, + WM8995_FLL1_ENA_MASK, WM8995_FLL1_ENA); + + wm8995->fll[id].in = freq_in; + wm8995->fll[id].out = freq_out; + wm8995->fll[id].src = src; + + /* Enable any gated AIF clocks */ + snd_soc_update_bits(codec, WM8995_AIF1_CLOCKING_1, + WM8995_AIF1CLK_ENA_MASK, aif1); + snd_soc_update_bits(codec, WM8995_AIF2_CLOCKING_1, + WM8995_AIF2CLK_ENA_MASK, aif2); + + configure_clock(codec); + + return 0; +} + +static int wm8995_set_dai_sysclk(struct snd_soc_dai *dai, + int clk_id, unsigned int freq, int dir) +{ + struct snd_soc_codec *codec; + struct wm8995_priv *wm8995; + + codec = dai->codec; + wm8995 = snd_soc_codec_get_drvdata(codec); + + switch (dai->id) { + case 0: + case 1: + break; + default: + /* AIF3 shares clocking with AIF1/2 */ + return -EINVAL; + } + + switch (clk_id) { + case WM8995_SYSCLK_MCLK1: + wm8995->sysclk[dai->id] = WM8995_SYSCLK_MCLK1; + wm8995->mclk[0] = freq; + dev_dbg(dai->dev, "AIF%d using MCLK1 at %uHz\n", + dai->id + 1, freq); + break; + case WM8995_SYSCLK_MCLK2: + wm8995->sysclk[dai->id] = WM8995_SYSCLK_MCLK1; + wm8995->mclk[1] = freq; + dev_dbg(dai->dev, "AIF%d using MCLK2 at %uHz\n", + dai->id + 1, freq); + break; + case WM8995_SYSCLK_FLL1: + wm8995->sysclk[dai->id] = WM8995_SYSCLK_FLL1; + dev_dbg(dai->dev, "AIF%d using FLL1\n", dai->id + 1); + break; + case WM8995_SYSCLK_FLL2: + wm8995->sysclk[dai->id] = WM8995_SYSCLK_FLL2; + dev_dbg(dai->dev, "AIF%d using FLL2\n", dai->id + 1); + break; + case WM8995_SYSCLK_OPCLK: + default: + dev_err(dai->dev, "Unknown clock source %d\n", clk_id); + return -EINVAL; + } + + configure_clock(codec); + + return 0; +} + +static int wm8995_set_bias_level(struct snd_soc_codec *codec, + enum snd_soc_bias_level level) +{ + struct wm8995_priv *wm8995; + int ret; + + wm8995 = snd_soc_codec_get_drvdata(codec); + switch (level) { + case SND_SOC_BIAS_ON: + case SND_SOC_BIAS_PREPARE: + break; + case SND_SOC_BIAS_STANDBY: + if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) { + ret = snd_soc_cache_sync(codec); + if (ret) { + dev_err(codec->dev, + "Failed to sync cache: %d\n", ret); + return ret; + } + + snd_soc_update_bits(codec, WM8995_POWER_MANAGEMENT_1, + WM8995_BG_ENA_MASK, WM8995_BG_ENA); + + } + break; + case SND_SOC_BIAS_OFF: + snd_soc_update_bits(codec, WM8995_POWER_MANAGEMENT_1, + WM8995_BG_ENA_MASK, 0); + break; + } + + codec->dapm.bias_level = level; + return 0; +} + +#ifdef CONFIG_PM +static int wm8995_suspend(struct snd_soc_codec *codec, pm_message_t state) +{ + wm8995_set_bias_level(codec, SND_SOC_BIAS_OFF); + return 0; +} + +static int wm8995_resume(struct snd_soc_codec *codec) +{ + wm8995_set_bias_level(codec, SND_SOC_BIAS_STANDBY); + return 0; +} +#else +#define wm8995_suspend NULL +#define wm8995_resume NULL +#endif + +static int wm8995_remove(struct snd_soc_codec *codec) +{ + struct wm8995_priv *wm8995; + struct i2c_client *i2c; + + i2c = container_of(codec->dev, struct i2c_client, dev); + wm8995 = snd_soc_codec_get_drvdata(codec); + wm8995_set_bias_level(codec, SND_SOC_BIAS_OFF); + return 0; +} + +static int wm8995_probe(struct snd_soc_codec *codec) +{ + struct wm8995_priv *wm8995; + int ret; + + codec->dapm.idle_bias_off = 1; + wm8995 = snd_soc_codec_get_drvdata(codec); + + ret = snd_soc_codec_set_cache_io(codec, 16, 16, wm8995->control_type); + if (ret < 0) { + dev_err(codec->dev, "Failed to set cache i/o: %d\n", ret); + return ret; + } + + ret = snd_soc_read(codec, WM8995_SOFTWARE_RESET); + if (ret < 0) { + dev_err(codec->dev, "Failed to read device ID: %d\n", ret); + return ret; + } + + if (ret != 0x8995) { + dev_err(codec->dev, "Invalid device ID: %#x\n", ret); + return -EINVAL; + } + + ret = snd_soc_write(codec, WM8995_SOFTWARE_RESET, 0); + if (ret < 0) { + dev_err(codec->dev, "Failed to issue reset: %d\n", ret); + return ret; + } + + wm8995_set_bias_level(codec, SND_SOC_BIAS_STANDBY); + + /* Latch volume updates (right only; we always do left then right). */ + snd_soc_update_bits(codec, WM8995_AIF1_DAC1_RIGHT_VOLUME, + WM8995_AIF1DAC1_VU_MASK, WM8995_AIF1DAC1_VU); + snd_soc_update_bits(codec, WM8995_AIF1_DAC2_RIGHT_VOLUME, + WM8995_AIF1DAC2_VU_MASK, WM8995_AIF1DAC2_VU); + snd_soc_update_bits(codec, WM8995_AIF2_DAC_RIGHT_VOLUME, + WM8995_AIF2DAC_VU_MASK, WM8995_AIF2DAC_VU); + snd_soc_update_bits(codec, WM8995_AIF1_ADC1_RIGHT_VOLUME, + WM8995_AIF1ADC1_VU_MASK, WM8995_AIF1ADC1_VU); + snd_soc_update_bits(codec, WM8995_AIF1_ADC2_RIGHT_VOLUME, + WM8995_AIF1ADC2_VU_MASK, WM8995_AIF1ADC2_VU); + snd_soc_update_bits(codec, WM8995_AIF2_ADC_RIGHT_VOLUME, + WM8995_AIF2ADC_VU_MASK, WM8995_AIF1ADC2_VU); + snd_soc_update_bits(codec, WM8995_DAC1_RIGHT_VOLUME, + WM8995_DAC1_VU_MASK, WM8995_DAC1_VU); + snd_soc_update_bits(codec, WM8995_DAC2_RIGHT_VOLUME, + WM8995_DAC2_VU_MASK, WM8995_DAC2_VU); + snd_soc_update_bits(codec, WM8995_RIGHT_LINE_INPUT_1_VOLUME, + WM8995_IN1_VU_MASK, WM8995_IN1_VU); + + wm8995_update_class_w(codec); + + snd_soc_add_controls(codec, wm8995_snd_controls, + ARRAY_SIZE(wm8995_snd_controls)); + snd_soc_dapm_new_controls(&codec->dapm, wm8995_dapm_widgets, + ARRAY_SIZE(wm8995_dapm_widgets)); + snd_soc_dapm_add_routes(&codec->dapm, wm8995_intercon, + ARRAY_SIZE(wm8995_intercon)); + + return 0; +} + +#define WM8995_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\ + SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE) + +static struct snd_soc_dai_ops wm8995_aif1_dai_ops = { + .set_sysclk = wm8995_set_dai_sysclk, + .set_fmt = wm8995_set_dai_fmt, + .hw_params = wm8995_hw_params, + .digital_mute = wm8995_aif_mute, + .set_pll = wm8995_set_fll, + .set_tristate = wm8995_set_tristate, +}; + +static struct snd_soc_dai_ops wm8995_aif2_dai_ops = { + .set_sysclk = wm8995_set_dai_sysclk, + .set_fmt = wm8995_set_dai_fmt, + .hw_params = wm8995_hw_params, + .digital_mute = wm8995_aif_mute, + .set_pll = wm8995_set_fll, + .set_tristate = wm8995_set_tristate, +}; + +static struct snd_soc_dai_ops wm8995_aif3_dai_ops = { + .set_tristate = wm8995_set_tristate, +}; + +static struct snd_soc_dai_driver wm8995_dai[] = { + { + .name = "wm8995-aif1", + .playback = { + .stream_name = "AIF1 Playback", + .channels_min = 2, + .channels_max = 2, + .rates = SNDRV_PCM_RATE_8000_96000, + .formats = WM8995_FORMATS + }, + .capture = { + .stream_name = "AIF1 Capture", + .channels_min = 2, + .channels_max = 2, + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = WM8995_FORMATS + }, + .ops = &wm8995_aif1_dai_ops + }, + { + .name = "wm8995-aif2", + .playback = { + .stream_name = "AIF2 Playback", + .channels_min = 2, + .channels_max = 2, + .rates = SNDRV_PCM_RATE_8000_96000, + .formats = WM8995_FORMATS + }, + .capture = { + .stream_name = "AIF2 Capture", + .channels_min = 2, + .channels_max = 2, + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = WM8995_FORMATS + }, + .ops = &wm8995_aif2_dai_ops + }, + { + .name = "wm8995-aif3", + .playback = { + .stream_name = "AIF3 Playback", + .channels_min = 2, + .channels_max = 2, + .rates = SNDRV_PCM_RATE_8000_96000, + .formats = WM8995_FORMATS + }, + .capture = { + .stream_name = "AIF3 Capture", + .channels_min = 2, + .channels_max = 2, + .rates = SNDRV_PCM_RATE_8000_48000, + .formats = WM8995_FORMATS + }, + .ops = &wm8995_aif3_dai_ops + } +}; + +static struct snd_soc_codec_driver soc_codec_dev_wm8995 = { + .probe = wm8995_probe, + .remove = wm8995_remove, + .suspend = wm8995_suspend, + .resume = wm8995_resume, + .set_bias_level = wm8995_set_bias_level, + .reg_cache_size = ARRAY_SIZE(wm8995_reg_defs), + .reg_word_size = sizeof(u16), + .reg_cache_default = wm8995_reg_defs, + .volatile_register = wm8995_volatile, + .compress_type = SND_SOC_RBTREE_COMPRESSION +}; + +#if defined(CONFIG_SPI_MASTER) +static int __devinit wm8995_spi_probe(struct spi_device *spi) +{ + struct wm8995_priv *wm8995; + int ret; + + wm8995 = kzalloc(sizeof *wm8995, GFP_KERNEL); + if (!wm8995) + return -ENOMEM; + + wm8995->control_type = SND_SOC_SPI; + spi_set_drvdata(spi, wm8995); + + ret = snd_soc_register_codec(&spi->dev, + &soc_codec_dev_wm8995, wm8995_dai, + ARRAY_SIZE(wm8995_dai)); + if (ret < 0) + kfree(wm8995); + return ret; +} + +static int __devexit wm8995_spi_remove(struct spi_device *spi) +{ + snd_soc_unregister_codec(&spi->dev); + kfree(spi_get_drvdata(spi)); + return 0; +} + +static struct spi_driver wm8995_spi_driver = { + .driver = { + .name = "wm8995", + .owner = THIS_MODULE, + }, + .probe = wm8995_spi_probe, + .remove = __devexit_p(wm8995_spi_remove) +}; +#endif + +#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) +static __devinit int wm8995_i2c_probe(struct i2c_client *i2c, + const struct i2c_device_id *id) +{ + struct wm8995_priv *wm8995; + int ret; + + wm8995 = kzalloc(sizeof *wm8995, GFP_KERNEL); + if (!wm8995) + return -ENOMEM; + + wm8995->control_type = SND_SOC_I2C; + i2c_set_clientdata(i2c, wm8995); + + ret = snd_soc_register_codec(&i2c->dev, + &soc_codec_dev_wm8995, wm8995_dai, + ARRAY_SIZE(wm8995_dai)); + if (ret < 0) + kfree(wm8995); + return ret; +} + +static __devexit int wm8995_i2c_remove(struct i2c_client *client) +{ + snd_soc_unregister_codec(&client->dev); + kfree(i2c_get_clientdata(client)); + return 0; +} + +static const struct i2c_device_id wm8995_i2c_id[] = { + {"wm8995", 0}, + {} +}; + +MODULE_DEVICE_TABLE(i2c, wm8995_i2c_id); + +static struct i2c_driver wm8995_i2c_driver = { + .driver = { + .name = "wm8995", + .owner = THIS_MODULE, + }, + .probe = wm8995_i2c_probe, + .remove = __devexit_p(wm8995_i2c_remove), + .id_table = wm8995_i2c_id +}; +#endif + +static int __init wm8995_modinit(void) +{ + int ret = 0; + +#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) + ret = i2c_add_driver(&wm8995_i2c_driver); + if (ret) { + printk(KERN_ERR "Failed to register wm8995 I2C driver: %d\n", + ret); + } +#endif +#if defined(CONFIG_SPI_MASTER) + ret = spi_register_driver(&wm8995_spi_driver); + if (ret) { + printk(KERN_ERR "Failed to register wm8995 SPI driver: %d\n", + ret); + } +#endif + return ret; +} + +module_init(wm8995_modinit); + +static void __exit wm8995_exit(void) +{ +#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) + i2c_del_driver(&wm8995_i2c_driver); +#endif +#if defined(CONFIG_SPI_MASTER) + spi_unregister_driver(&wm8995_spi_driver); +#endif +} + +module_exit(wm8995_exit); + +MODULE_DESCRIPTION("ASoC WM8995 driver"); +MODULE_AUTHOR("Dimitris Papastamos "); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/codecs/wm8995.h b/sound/soc/codecs/wm8995.h new file mode 100644 index 000000000000..6409e5a6b574 --- /dev/null +++ b/sound/soc/codecs/wm8995.h @@ -0,0 +1,8749 @@ +/* + * wm8995.h -- WM8995 ALSA SoC Audio driver + * + * Copyright 2010 Wolfson Microelectronics plc + * + * Author: Dimitris Papastamos + * + * 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. + */ + +#ifndef _WM8995_H +#define _WM8995_H + +#include + +/* + * Register values. + */ +#define WM8995_SOFTWARE_RESET 0x00 +#define WM8995_POWER_MANAGEMENT_1 0x01 +#define WM8995_POWER_MANAGEMENT_2 0x02 +#define WM8995_POWER_MANAGEMENT_3 0x03 +#define WM8995_POWER_MANAGEMENT_4 0x04 +#define WM8995_POWER_MANAGEMENT_5 0x05 +#define WM8995_LEFT_LINE_INPUT_1_VOLUME 0x10 +#define WM8995_RIGHT_LINE_INPUT_1_VOLUME 0x11 +#define WM8995_LEFT_LINE_INPUT_CONTROL 0x12 +#define WM8995_DAC1_LEFT_VOLUME 0x18 +#define WM8995_DAC1_RIGHT_VOLUME 0x19 +#define WM8995_DAC2_LEFT_VOLUME 0x1A +#define WM8995_DAC2_RIGHT_VOLUME 0x1B +#define WM8995_OUTPUT_VOLUME_ZC_1 0x1C +#define WM8995_MICBIAS_1 0x20 +#define WM8995_MICBIAS_2 0x21 +#define WM8995_LDO_1 0x28 +#define WM8995_LDO_2 0x29 +#define WM8995_ACCESSORY_DETECT_MODE1 0x30 +#define WM8995_ACCESSORY_DETECT_MODE2 0x31 +#define WM8995_HEADPHONE_DETECT1 0x34 +#define WM8995_HEADPHONE_DETECT2 0x35 +#define WM8995_MIC_DETECT_1 0x38 +#define WM8995_MIC_DETECT_2 0x39 +#define WM8995_CHARGE_PUMP_1 0x40 +#define WM8995_CLASS_W_1 0x45 +#define WM8995_DC_SERVO_1 0x50 +#define WM8995_DC_SERVO_2 0x51 +#define WM8995_DC_SERVO_3 0x52 +#define WM8995_DC_SERVO_5 0x54 +#define WM8995_DC_SERVO_6 0x55 +#define WM8995_DC_SERVO_7 0x56 +#define WM8995_DC_SERVO_READBACK_0 0x57 +#define WM8995_ANALOGUE_HP_1 0x60 +#define WM8995_ANALOGUE_HP_2 0x61 +#define WM8995_CHIP_REVISION 0x100 +#define WM8995_CONTROL_INTERFACE_1 0x101 +#define WM8995_CONTROL_INTERFACE_2 0x102 +#define WM8995_WRITE_SEQUENCER_CTRL_1 0x110 +#define WM8995_WRITE_SEQUENCER_CTRL_2 0x111 +#define WM8995_AIF1_CLOCKING_1 0x200 +#define WM8995_AIF1_CLOCKING_2 0x201 +#define WM8995_AIF2_CLOCKING_1 0x204 +#define WM8995_AIF2_CLOCKING_2 0x205 +#define WM8995_CLOCKING_1 0x208 +#define WM8995_CLOCKING_2 0x209 +#define WM8995_AIF1_RATE 0x210 +#define WM8995_AIF2_RATE 0x211 +#define WM8995_RATE_STATUS 0x212 +#define WM8995_FLL1_CONTROL_1 0x220 +#define WM8995_FLL1_CONTROL_2 0x221 +#define WM8995_FLL1_CONTROL_3 0x222 +#define WM8995_FLL1_CONTROL_4 0x223 +#define WM8995_FLL1_CONTROL_5 0x224 +#define WM8995_FLL2_CONTROL_1 0x240 +#define WM8995_FLL2_CONTROL_2 0x241 +#define WM8995_FLL2_CONTROL_3 0x242 +#define WM8995_FLL2_CONTROL_4 0x243 +#define WM8995_FLL2_CONTROL_5 0x244 +#define WM8995_AIF1_CONTROL_1 0x300 +#define WM8995_AIF1_CONTROL_2 0x301 +#define WM8995_AIF1_MASTER_SLAVE 0x302 +#define WM8995_AIF1_BCLK 0x303 +#define WM8995_AIF1ADC_LRCLK 0x304 +#define WM8995_AIF1DAC_LRCLK 0x305 +#define WM8995_AIF1DAC_DATA 0x306 +#define WM8995_AIF1ADC_DATA 0x307 +#define WM8995_AIF2_CONTROL_1 0x310 +#define WM8995_AIF2_CONTROL_2 0x311 +#define WM8995_AIF2_MASTER_SLAVE 0x312 +#define WM8995_AIF2_BCLK 0x313 +#define WM8995_AIF2ADC_LRCLK 0x314 +#define WM8995_AIF2DAC_LRCLK 0x315 +#define WM8995_AIF2DAC_DATA 0x316 +#define WM8995_AIF2ADC_DATA 0x317 +#define WM8995_AIF1_ADC1_LEFT_VOLUME 0x400 +#define WM8995_AIF1_ADC1_RIGHT_VOLUME 0x401 +#define WM8995_AIF1_DAC1_LEFT_VOLUME 0x402 +#define WM8995_AIF1_DAC1_RIGHT_VOLUME 0x403 +#define WM8995_AIF1_ADC2_LEFT_VOLUME 0x404 +#define WM8995_AIF1_ADC2_RIGHT_VOLUME 0x405 +#define WM8995_AIF1_DAC2_LEFT_VOLUME 0x406 +#define WM8995_AIF1_DAC2_RIGHT_VOLUME 0x407 +#define WM8995_AIF1_ADC1_FILTERS 0x410 +#define WM8995_AIF1_ADC2_FILTERS 0x411 +#define WM8995_AIF1_DAC1_FILTERS_1 0x420 +#define WM8995_AIF1_DAC1_FILTERS_2 0x421 +#define WM8995_AIF1_DAC2_FILTERS_1 0x422 +#define WM8995_AIF1_DAC2_FILTERS_2 0x423 +#define WM8995_AIF1_DRC1_1 0x440 +#define WM8995_AIF1_DRC1_2 0x441 +#define WM8995_AIF1_DRC1_3 0x442 +#define WM8995_AIF1_DRC1_4 0x443 +#define WM8995_AIF1_DRC1_5 0x444 +#define WM8995_AIF1_DRC2_1 0x450 +#define WM8995_AIF1_DRC2_2 0x451 +#define WM8995_AIF1_DRC2_3 0x452 +#define WM8995_AIF1_DRC2_4 0x453 +#define WM8995_AIF1_DRC2_5 0x454 +#define WM8995_AIF1_DAC1_EQ_GAINS_1 0x480 +#define WM8995_AIF1_DAC1_EQ_GAINS_2 0x481 +#define WM8995_AIF1_DAC1_EQ_BAND_1_A 0x482 +#define WM8995_AIF1_DAC1_EQ_BAND_1_B 0x483 +#define WM8995_AIF1_DAC1_EQ_BAND_1_PG 0x484 +#define WM8995_AIF1_DAC1_EQ_BAND_2_A 0x485 +#define WM8995_AIF1_DAC1_EQ_BAND_2_B 0x486 +#define WM8995_AIF1_DAC1_EQ_BAND_2_C 0x487 +#define WM8995_AIF1_DAC1_EQ_BAND_2_PG 0x488 +#define WM8995_AIF1_DAC1_EQ_BAND_3_A 0x489 +#define WM8995_AIF1_DAC1_EQ_BAND_3_B 0x48A +#define WM8995_AIF1_DAC1_EQ_BAND_3_C 0x48B +#define WM8995_AIF1_DAC1_EQ_BAND_3_PG 0x48C +#define WM8995_AIF1_DAC1_EQ_BAND_4_A 0x48D +#define WM8995_AIF1_DAC1_EQ_BAND_4_B 0x48E +#define WM8995_AIF1_DAC1_EQ_BAND_4_C 0x48F +#define WM8995_AIF1_DAC1_EQ_BAND_4_PG 0x490 +#define WM8995_AIF1_DAC1_EQ_BAND_5_A 0x491 +#define WM8995_AIF1_DAC1_EQ_BAND_5_B 0x492 +#define WM8995_AIF1_DAC1_EQ_BAND_5_PG 0x493 +#define WM8995_AIF1_DAC2_EQ_GAINS_1 0x4A0 +#define WM8995_AIF1_DAC2_EQ_GAINS_2 0x4A1 +#define WM8995_AIF1_DAC2_EQ_BAND_1_A 0x4A2 +#define WM8995_AIF1_DAC2_EQ_BAND_1_B 0x4A3 +#define WM8995_AIF1_DAC2_EQ_BAND_1_PG 0x4A4 +#define WM8995_AIF1_DAC2_EQ_BAND_2_A 0x4A5 +#define WM8995_AIF1_DAC2_EQ_BAND_2_B 0x4A6 +#define WM8995_AIF1_DAC2_EQ_BAND_2_C 0x4A7 +#define WM8995_AIF1_DAC2_EQ_BAND_2_PG 0x4A8 +#define WM8995_AIF1_DAC2_EQ_BAND_3_A 0x4A9 +#define WM8995_AIF1_DAC2_EQ_BAND_3_B 0x4AA +#define WM8995_AIF1_DAC2_EQ_BAND_3_C 0x4AB +#define WM8995_AIF1_DAC2_EQ_BAND_3_PG 0x4AC +#define WM8995_AIF1_DAC2_EQ_BAND_4_A 0x4AD +#define WM8995_AIF1_DAC2_EQ_BAND_4_B 0x4AE +#define WM8995_AIF1_DAC2_EQ_BAND_4_C 0x4AF +#define WM8995_AIF1_DAC2_EQ_BAND_4_PG 0x4B0 +#define WM8995_AIF1_DAC2_EQ_BAND_5_A 0x4B1 +#define WM8995_AIF1_DAC2_EQ_BAND_5_B 0x4B2 +#define WM8995_AIF1_DAC2_EQ_BAND_5_PG 0x4B3 +#define WM8995_AIF2_ADC_LEFT_VOLUME 0x500 +#define WM8995_AIF2_ADC_RIGHT_VOLUME 0x501 +#define WM8995_AIF2_DAC_LEFT_VOLUME 0x502 +#define WM8995_AIF2_DAC_RIGHT_VOLUME 0x503 +#define WM8995_AIF2_ADC_FILTERS 0x510 +#define WM8995_AIF2_DAC_FILTERS_1 0x520 +#define WM8995_AIF2_DAC_FILTERS_2 0x521 +#define WM8995_AIF2_DRC_1 0x540 +#define WM8995_AIF2_DRC_2 0x541 +#define WM8995_AIF2_DRC_3 0x542 +#define WM8995_AIF2_DRC_4 0x543 +#define WM8995_AIF2_DRC_5 0x544 +#define WM8995_AIF2_EQ_GAINS_1 0x580 +#define WM8995_AIF2_EQ_GAINS_2 0x581 +#define WM8995_AIF2_EQ_BAND_1_A 0x582 +#define WM8995_AIF2_EQ_BAND_1_B 0x583 +#define WM8995_AIF2_EQ_BAND_1_PG 0x584 +#define WM8995_AIF2_EQ_BAND_2_A 0x585 +#define WM8995_AIF2_EQ_BAND_2_B 0x586 +#define WM8995_AIF2_EQ_BAND_2_C 0x587 +#define WM8995_AIF2_EQ_BAND_2_PG 0x588 +#define WM8995_AIF2_EQ_BAND_3_A 0x589 +#define WM8995_AIF2_EQ_BAND_3_B 0x58A +#define WM8995_AIF2_EQ_BAND_3_C 0x58B +#define WM8995_AIF2_EQ_BAND_3_PG 0x58C +#define WM8995_AIF2_EQ_BAND_4_A 0x58D +#define WM8995_AIF2_EQ_BAND_4_B 0x58E +#define WM8995_AIF2_EQ_BAND_4_C 0x58F +#define WM8995_AIF2_EQ_BAND_4_PG 0x590 +#define WM8995_AIF2_EQ_BAND_5_A 0x591 +#define WM8995_AIF2_EQ_BAND_5_B 0x592 +#define WM8995_AIF2_EQ_BAND_5_PG 0x593 +#define WM8995_DAC1_MIXER_VOLUMES 0x600 +#define WM8995_DAC1_LEFT_MIXER_ROUTING 0x601 +#define WM8995_DAC1_RIGHT_MIXER_ROUTING 0x602 +#define WM8995_DAC2_MIXER_VOLUMES 0x603 +#define WM8995_DAC2_LEFT_MIXER_ROUTING 0x604 +#define WM8995_DAC2_RIGHT_MIXER_ROUTING 0x605 +#define WM8995_AIF1_ADC1_LEFT_MIXER_ROUTING 0x606 +#define WM8995_AIF1_ADC1_RIGHT_MIXER_ROUTING 0x607 +#define WM8995_AIF1_ADC2_LEFT_MIXER_ROUTING 0x608 +#define WM8995_AIF1_ADC2_RIGHT_MIXER_ROUTING 0x609 +#define WM8995_DAC_SOFTMUTE 0x610 +#define WM8995_OVERSAMPLING 0x620 +#define WM8995_SIDETONE 0x621 +#define WM8995_GPIO_1 0x700 +#define WM8995_GPIO_2 0x701 +#define WM8995_GPIO_3 0x702 +#define WM8995_GPIO_4 0x703 +#define WM8995_GPIO_5 0x704 +#define WM8995_GPIO_6 0x705 +#define WM8995_GPIO_7 0x706 +#define WM8995_GPIO_8 0x707 +#define WM8995_GPIO_9 0x708 +#define WM8995_GPIO_10 0x709 +#define WM8995_GPIO_11 0x70A +#define WM8995_GPIO_12 0x70B +#define WM8995_GPIO_13 0x70C +#define WM8995_GPIO_14 0x70D +#define WM8995_PULL_CONTROL_1 0x720 +#define WM8995_PULL_CONTROL_2 0x721 +#define WM8995_INTERRUPT_STATUS_1 0x730 +#define WM8995_INTERRUPT_STATUS_2 0x731 +#define WM8995_INTERRUPT_RAW_STATUS_2 0x732 +#define WM8995_INTERRUPT_STATUS_1_MASK 0x738 +#define WM8995_INTERRUPT_STATUS_2_MASK 0x739 +#define WM8995_INTERRUPT_CONTROL 0x740 +#define WM8995_LEFT_PDM_SPEAKER_1 0x800 +#define WM8995_RIGHT_PDM_SPEAKER_1 0x801 +#define WM8995_PDM_SPEAKER_1_MUTE_SEQUENCE 0x802 +#define WM8995_LEFT_PDM_SPEAKER_2 0x808 +#define WM8995_RIGHT_PDM_SPEAKER_2 0x809 +#define WM8995_PDM_SPEAKER_2_MUTE_SEQUENCE 0x80A +#define WM8995_WRITE_SEQUENCER_0 0x3000 +#define WM8995_WRITE_SEQUENCER_1 0x3001 +#define WM8995_WRITE_SEQUENCER_2 0x3002 +#define WM8995_WRITE_SEQUENCER_3 0x3003 +#define WM8995_WRITE_SEQUENCER_4 0x3004 +#define WM8995_WRITE_SEQUENCER_5 0x3005 +#define WM8995_WRITE_SEQUENCER_6 0x3006 +#define WM8995_WRITE_SEQUENCER_7 0x3007 +#define WM8995_WRITE_SEQUENCER_8 0x3008 +#define WM8995_WRITE_SEQUENCER_9 0x3009 +#define WM8995_WRITE_SEQUENCER_10 0x300A +#define WM8995_WRITE_SEQUENCER_11 0x300B +#define WM8995_WRITE_SEQUENCER_12 0x300C +#define WM8995_WRITE_SEQUENCER_13 0x300D +#define WM8995_WRITE_SEQUENCER_14 0x300E +#define WM8995_WRITE_SEQUENCER_15 0x300F +#define WM8995_WRITE_SEQUENCER_16 0x3010 +#define WM8995_WRITE_SEQUENCER_17 0x3011 +#define WM8995_WRITE_SEQUENCER_18 0x3012 +#define WM8995_WRITE_SEQUENCER_19 0x3013 +#define WM8995_WRITE_SEQUENCER_20 0x3014 +#define WM8995_WRITE_SEQUENCER_21 0x3015 +#define WM8995_WRITE_SEQUENCER_22 0x3016 +#define WM8995_WRITE_SEQUENCER_23 0x3017 +#define WM8995_WRITE_SEQUENCER_24 0x3018 +#define WM8995_WRITE_SEQUENCER_25 0x3019 +#define WM8995_WRITE_SEQUENCER_26 0x301A +#define WM8995_WRITE_SEQUENCER_27 0x301B +#define WM8995_WRITE_SEQUENCER_28 0x301C +#define WM8995_WRITE_SEQUENCER_29 0x301D +#define WM8995_WRITE_SEQUENCER_30 0x301E +#define WM8995_WRITE_SEQUENCER_31 0x301F +#define WM8995_WRITE_SEQUENCER_32 0x3020 +#define WM8995_WRITE_SEQUENCER_33 0x3021 +#define WM8995_WRITE_SEQUENCER_34 0x3022 +#define WM8995_WRITE_SEQUENCER_35 0x3023 +#define WM8995_WRITE_SEQUENCER_36 0x3024 +#define WM8995_WRITE_SEQUENCER_37 0x3025 +#define WM8995_WRITE_SEQUENCER_38 0x3026 +#define WM8995_WRITE_SEQUENCER_39 0x3027 +#define WM8995_WRITE_SEQUENCER_40 0x3028 +#define WM8995_WRITE_SEQUENCER_41 0x3029 +#define WM8995_WRITE_SEQUENCER_42 0x302A +#define WM8995_WRITE_SEQUENCER_43 0x302B +#define WM8995_WRITE_SEQUENCER_44 0x302C +#define WM8995_WRITE_SEQUENCER_45 0x302D +#define WM8995_WRITE_SEQUENCER_46 0x302E +#define WM8995_WRITE_SEQUENCER_47 0x302F +#define WM8995_WRITE_SEQUENCER_48 0x3030 +#define WM8995_WRITE_SEQUENCER_49 0x3031 +#define WM8995_WRITE_SEQUENCER_50 0x3032 +#define WM8995_WRITE_SEQUENCER_51 0x3033 +#define WM8995_WRITE_SEQUENCER_52 0x3034 +#define WM8995_WRITE_SEQUENCER_53 0x3035 +#define WM8995_WRITE_SEQUENCER_54 0x3036 +#define WM8995_WRITE_SEQUENCER_55 0x3037 +#define WM8995_WRITE_SEQUENCER_56 0x3038 +#define WM8995_WRITE_SEQUENCER_57 0x3039 +#define WM8995_WRITE_SEQUENCER_58 0x303A +#define WM8995_WRITE_SEQUENCER_59 0x303B +#define WM8995_WRITE_SEQUENCER_60 0x303C +#define WM8995_WRITE_SEQUENCER_61 0x303D +#define WM8995_WRITE_SEQUENCER_62 0x303E +#define WM8995_WRITE_SEQUENCER_63 0x303F +#define WM8995_WRITE_SEQUENCER_64 0x3040 +#define WM8995_WRITE_SEQUENCER_65 0x3041 +#define WM8995_WRITE_SEQUENCER_66 0x3042 +#define WM8995_WRITE_SEQUENCER_67 0x3043 +#define WM8995_WRITE_SEQUENCER_68 0x3044 +#define WM8995_WRITE_SEQUENCER_69 0x3045 +#define WM8995_WRITE_SEQUENCER_70 0x3046 +#define WM8995_WRITE_SEQUENCER_71 0x3047 +#define WM8995_WRITE_SEQUENCER_72 0x3048 +#define WM8995_WRITE_SEQUENCER_73 0x3049 +#define WM8995_WRITE_SEQUENCER_74 0x304A +#define WM8995_WRITE_SEQUENCER_75 0x304B +#define WM8995_WRITE_SEQUENCER_76 0x304C +#define WM8995_WRITE_SEQUENCER_77 0x304D +#define WM8995_WRITE_SEQUENCER_78 0x304E +#define WM8995_WRITE_SEQUENCER_79 0x304F +#define WM8995_WRITE_SEQUENCER_80 0x3050 +#define WM8995_WRITE_SEQUENCER_81 0x3051 +#define WM8995_WRITE_SEQUENCER_82 0x3052 +#define WM8995_WRITE_SEQUENCER_83 0x3053 +#define WM8995_WRITE_SEQUENCER_84 0x3054 +#define WM8995_WRITE_SEQUENCER_85 0x3055 +#define WM8995_WRITE_SEQUENCER_86 0x3056 +#define WM8995_WRITE_SEQUENCER_87 0x3057 +#define WM8995_WRITE_SEQUENCER_88 0x3058 +#define WM8995_WRITE_SEQUENCER_89 0x3059 +#define WM8995_WRITE_SEQUENCER_90 0x305A +#define WM8995_WRITE_SEQUENCER_91 0x305B +#define WM8995_WRITE_SEQUENCER_92 0x305C +#define WM8995_WRITE_SEQUENCER_93 0x305D +#define WM8995_WRITE_SEQUENCER_94 0x305E +#define WM8995_WRITE_SEQUENCER_95 0x305F +#define WM8995_WRITE_SEQUENCER_96 0x3060 +#define WM8995_WRITE_SEQUENCER_97 0x3061 +#define WM8995_WRITE_SEQUENCER_98 0x3062 +#define WM8995_WRITE_SEQUENCER_99 0x3063 +#define WM8995_WRITE_SEQUENCER_100 0x3064 +#define WM8995_WRITE_SEQUENCER_101 0x3065 +#define WM8995_WRITE_SEQUENCER_102 0x3066 +#define WM8995_WRITE_SEQUENCER_103 0x3067 +#define WM8995_WRITE_SEQUENCER_104 0x3068 +#define WM8995_WRITE_SEQUENCER_105 0x3069 +#define WM8995_WRITE_SEQUENCER_106 0x306A +#define WM8995_WRITE_SEQUENCER_107 0x306B +#define WM8995_WRITE_SEQUENCER_108 0x306C +#define WM8995_WRITE_SEQUENCER_109 0x306D +#define WM8995_WRITE_SEQUENCER_110 0x306E +#define WM8995_WRITE_SEQUENCER_111 0x306F +#define WM8995_WRITE_SEQUENCER_112 0x3070 +#define WM8995_WRITE_SEQUENCER_113 0x3071 +#define WM8995_WRITE_SEQUENCER_114 0x3072 +#define WM8995_WRITE_SEQUENCER_115 0x3073 +#define WM8995_WRITE_SEQUENCER_116 0x3074 +#define WM8995_WRITE_SEQUENCER_117 0x3075 +#define WM8995_WRITE_SEQUENCER_118 0x3076 +#define WM8995_WRITE_SEQUENCER_119 0x3077 +#define WM8995_WRITE_SEQUENCER_120 0x3078 +#define WM8995_WRITE_SEQUENCER_121 0x3079 +#define WM8995_WRITE_SEQUENCER_122 0x307A +#define WM8995_WRITE_SEQUENCER_123 0x307B +#define WM8995_WRITE_SEQUENCER_124 0x307C +#define WM8995_WRITE_SEQUENCER_125 0x307D +#define WM8995_WRITE_SEQUENCER_126 0x307E +#define WM8995_WRITE_SEQUENCER_127 0x307F +#define WM8995_WRITE_SEQUENCER_128 0x3080 +#define WM8995_WRITE_SEQUENCER_129 0x3081 +#define WM8995_WRITE_SEQUENCER_130 0x3082 +#define WM8995_WRITE_SEQUENCER_131 0x3083 +#define WM8995_WRITE_SEQUENCER_132 0x3084 +#define WM8995_WRITE_SEQUENCER_133 0x3085 +#define WM8995_WRITE_SEQUENCER_134 0x3086 +#define WM8995_WRITE_SEQUENCER_135 0x3087 +#define WM8995_WRITE_SEQUENCER_136 0x3088 +#define WM8995_WRITE_SEQUENCER_137 0x3089 +#define WM8995_WRITE_SEQUENCER_138 0x308A +#define WM8995_WRITE_SEQUENCER_139 0x308B +#define WM8995_WRITE_SEQUENCER_140 0x308C +#define WM8995_WRITE_SEQUENCER_141 0x308D +#define WM8995_WRITE_SEQUENCER_142 0x308E +#define WM8995_WRITE_SEQUENCER_143 0x308F +#define WM8995_WRITE_SEQUENCER_144 0x3090 +#define WM8995_WRITE_SEQUENCER_145 0x3091 +#define WM8995_WRITE_SEQUENCER_146 0x3092 +#define WM8995_WRITE_SEQUENCER_147 0x3093 +#define WM8995_WRITE_SEQUENCER_148 0x3094 +#define WM8995_WRITE_SEQUENCER_149 0x3095 +#define WM8995_WRITE_SEQUENCER_150 0x3096 +#define WM8995_WRITE_SEQUENCER_151 0x3097 +#define WM8995_WRITE_SEQUENCER_152 0x3098 +#define WM8995_WRITE_SEQUENCER_153 0x3099 +#define WM8995_WRITE_SEQUENCER_154 0x309A +#define WM8995_WRITE_SEQUENCER_155 0x309B +#define WM8995_WRITE_SEQUENCER_156 0x309C +#define WM8995_WRITE_SEQUENCER_157 0x309D +#define WM8995_WRITE_SEQUENCER_158 0x309E +#define WM8995_WRITE_SEQUENCER_159 0x309F +#define WM8995_WRITE_SEQUENCER_160 0x30A0 +#define WM8995_WRITE_SEQUENCER_161 0x30A1 +#define WM8995_WRITE_SEQUENCER_162 0x30A2 +#define WM8995_WRITE_SEQUENCER_163 0x30A3 +#define WM8995_WRITE_SEQUENCER_164 0x30A4 +#define WM8995_WRITE_SEQUENCER_165 0x30A5 +#define WM8995_WRITE_SEQUENCER_166 0x30A6 +#define WM8995_WRITE_SEQUENCER_167 0x30A7 +#define WM8995_WRITE_SEQUENCER_168 0x30A8 +#define WM8995_WRITE_SEQUENCER_169 0x30A9 +#define WM8995_WRITE_SEQUENCER_170 0x30AA +#define WM8995_WRITE_SEQUENCER_171 0x30AB +#define WM8995_WRITE_SEQUENCER_172 0x30AC +#define WM8995_WRITE_SEQUENCER_173 0x30AD +#define WM8995_WRITE_SEQUENCER_174 0x30AE +#define WM8995_WRITE_SEQUENCER_175 0x30AF +#define WM8995_WRITE_SEQUENCER_176 0x30B0 +#define WM8995_WRITE_SEQUENCER_177 0x30B1 +#define WM8995_WRITE_SEQUENCER_178 0x30B2 +#define WM8995_WRITE_SEQUENCER_179 0x30B3 +#define WM8995_WRITE_SEQUENCER_180 0x30B4 +#define WM8995_WRITE_SEQUENCER_181 0x30B5 +#define WM8995_WRITE_SEQUENCER_182 0x30B6 +#define WM8995_WRITE_SEQUENCER_183 0x30B7 +#define WM8995_WRITE_SEQUENCER_184 0x30B8 +#define WM8995_WRITE_SEQUENCER_185 0x30B9 +#define WM8995_WRITE_SEQUENCER_186 0x30BA +#define WM8995_WRITE_SEQUENCER_187 0x30BB +#define WM8995_WRITE_SEQUENCER_188 0x30BC +#define WM8995_WRITE_SEQUENCER_189 0x30BD +#define WM8995_WRITE_SEQUENCER_190 0x30BE +#define WM8995_WRITE_SEQUENCER_191 0x30BF +#define WM8995_WRITE_SEQUENCER_192 0x30C0 +#define WM8995_WRITE_SEQUENCER_193 0x30C1 +#define WM8995_WRITE_SEQUENCER_194 0x30C2 +#define WM8995_WRITE_SEQUENCER_195 0x30C3 +#define WM8995_WRITE_SEQUENCER_196 0x30C4 +#define WM8995_WRITE_SEQUENCER_197 0x30C5 +#define WM8995_WRITE_SEQUENCER_198 0x30C6 +#define WM8995_WRITE_SEQUENCER_199 0x30C7 +#define WM8995_WRITE_SEQUENCER_200 0x30C8 +#define WM8995_WRITE_SEQUENCER_201 0x30C9 +#define WM8995_WRITE_SEQUENCER_202 0x30CA +#define WM8995_WRITE_SEQUENCER_203 0x30CB +#define WM8995_WRITE_SEQUENCER_204 0x30CC +#define WM8995_WRITE_SEQUENCER_205 0x30CD +#define WM8995_WRITE_SEQUENCER_206 0x30CE +#define WM8995_WRITE_SEQUENCER_207 0x30CF +#define WM8995_WRITE_SEQUENCER_208 0x30D0 +#define WM8995_WRITE_SEQUENCER_209 0x30D1 +#define WM8995_WRITE_SEQUENCER_210 0x30D2 +#define WM8995_WRITE_SEQUENCER_211 0x30D3 +#define WM8995_WRITE_SEQUENCER_212 0x30D4 +#define WM8995_WRITE_SEQUENCER_213 0x30D5 +#define WM8995_WRITE_SEQUENCER_214 0x30D6 +#define WM8995_WRITE_SEQUENCER_215 0x30D7 +#define WM8995_WRITE_SEQUENCER_216 0x30D8 +#define WM8995_WRITE_SEQUENCER_217 0x30D9 +#define WM8995_WRITE_SEQUENCER_218 0x30DA +#define WM8995_WRITE_SEQUENCER_219 0x30DB +#define WM8995_WRITE_SEQUENCER_220 0x30DC +#define WM8995_WRITE_SEQUENCER_221 0x30DD +#define WM8995_WRITE_SEQUENCER_222 0x30DE +#define WM8995_WRITE_SEQUENCER_223 0x30DF +#define WM8995_WRITE_SEQUENCER_224 0x30E0 +#define WM8995_WRITE_SEQUENCER_225 0x30E1 +#define WM8995_WRITE_SEQUENCER_226 0x30E2 +#define WM8995_WRITE_SEQUENCER_227 0x30E3 +#define WM8995_WRITE_SEQUENCER_228 0x30E4 +#define WM8995_WRITE_SEQUENCER_229 0x30E5 +#define WM8995_WRITE_SEQUENCER_230 0x30E6 +#define WM8995_WRITE_SEQUENCER_231 0x30E7 +#define WM8995_WRITE_SEQUENCER_232 0x30E8 +#define WM8995_WRITE_SEQUENCER_233 0x30E9 +#define WM8995_WRITE_SEQUENCER_234 0x30EA +#define WM8995_WRITE_SEQUENCER_235 0x30EB +#define WM8995_WRITE_SEQUENCER_236 0x30EC +#define WM8995_WRITE_SEQUENCER_237 0x30ED +#define WM8995_WRITE_SEQUENCER_238 0x30EE +#define WM8995_WRITE_SEQUENCER_239 0x30EF +#define WM8995_WRITE_SEQUENCER_240 0x30F0 +#define WM8995_WRITE_SEQUENCER_241 0x30F1 +#define WM8995_WRITE_SEQUENCER_242 0x30F2 +#define WM8995_WRITE_SEQUENCER_243 0x30F3 +#define WM8995_WRITE_SEQUENCER_244 0x30F4 +#define WM8995_WRITE_SEQUENCER_245 0x30F5 +#define WM8995_WRITE_SEQUENCER_246 0x30F6 +#define WM8995_WRITE_SEQUENCER_247 0x30F7 +#define WM8995_WRITE_SEQUENCER_248 0x30F8 +#define WM8995_WRITE_SEQUENCER_249 0x30F9 +#define WM8995_WRITE_SEQUENCER_250 0x30FA +#define WM8995_WRITE_SEQUENCER_251 0x30FB +#define WM8995_WRITE_SEQUENCER_252 0x30FC +#define WM8995_WRITE_SEQUENCER_253 0x30FD +#define WM8995_WRITE_SEQUENCER_254 0x30FE +#define WM8995_WRITE_SEQUENCER_255 0x30FF +#define WM8995_WRITE_SEQUENCER_256 0x3100 +#define WM8995_WRITE_SEQUENCER_257 0x3101 +#define WM8995_WRITE_SEQUENCER_258 0x3102 +#define WM8995_WRITE_SEQUENCER_259 0x3103 +#define WM8995_WRITE_SEQUENCER_260 0x3104 +#define WM8995_WRITE_SEQUENCER_261 0x3105 +#define WM8995_WRITE_SEQUENCER_262 0x3106 +#define WM8995_WRITE_SEQUENCER_263 0x3107 +#define WM8995_WRITE_SEQUENCER_264 0x3108 +#define WM8995_WRITE_SEQUENCER_265 0x3109 +#define WM8995_WRITE_SEQUENCER_266 0x310A +#define WM8995_WRITE_SEQUENCER_267 0x310B +#define WM8995_WRITE_SEQUENCER_268 0x310C +#define WM8995_WRITE_SEQUENCER_269 0x310D +#define WM8995_WRITE_SEQUENCER_270 0x310E +#define WM8995_WRITE_SEQUENCER_271 0x310F +#define WM8995_WRITE_SEQUENCER_272 0x3110 +#define WM8995_WRITE_SEQUENCER_273 0x3111 +#define WM8995_WRITE_SEQUENCER_274 0x3112 +#define WM8995_WRITE_SEQUENCER_275 0x3113 +#define WM8995_WRITE_SEQUENCER_276 0x3114 +#define WM8995_WRITE_SEQUENCER_277 0x3115 +#define WM8995_WRITE_SEQUENCER_278 0x3116 +#define WM8995_WRITE_SEQUENCER_279 0x3117 +#define WM8995_WRITE_SEQUENCER_280 0x3118 +#define WM8995_WRITE_SEQUENCER_281 0x3119 +#define WM8995_WRITE_SEQUENCER_282 0x311A +#define WM8995_WRITE_SEQUENCER_283 0x311B +#define WM8995_WRITE_SEQUENCER_284 0x311C +#define WM8995_WRITE_SEQUENCER_285 0x311D +#define WM8995_WRITE_SEQUENCER_286 0x311E +#define WM8995_WRITE_SEQUENCER_287 0x311F +#define WM8995_WRITE_SEQUENCER_288 0x3120 +#define WM8995_WRITE_SEQUENCER_289 0x3121 +#define WM8995_WRITE_SEQUENCER_290 0x3122 +#define WM8995_WRITE_SEQUENCER_291 0x3123 +#define WM8995_WRITE_SEQUENCER_292 0x3124 +#define WM8995_WRITE_SEQUENCER_293 0x3125 +#define WM8995_WRITE_SEQUENCER_294 0x3126 +#define WM8995_WRITE_SEQUENCER_295 0x3127 +#define WM8995_WRITE_SEQUENCER_296 0x3128 +#define WM8995_WRITE_SEQUENCER_297 0x3129 +#define WM8995_WRITE_SEQUENCER_298 0x312A +#define WM8995_WRITE_SEQUENCER_299 0x312B +#define WM8995_WRITE_SEQUENCER_300 0x312C +#define WM8995_WRITE_SEQUENCER_301 0x312D +#define WM8995_WRITE_SEQUENCER_302 0x312E +#define WM8995_WRITE_SEQUENCER_303 0x312F +#define WM8995_WRITE_SEQUENCER_304 0x3130 +#define WM8995_WRITE_SEQUENCER_305 0x3131 +#define WM8995_WRITE_SEQUENCER_306 0x3132 +#define WM8995_WRITE_SEQUENCER_307 0x3133 +#define WM8995_WRITE_SEQUENCER_308 0x3134 +#define WM8995_WRITE_SEQUENCER_309 0x3135 +#define WM8995_WRITE_SEQUENCER_310 0x3136 +#define WM8995_WRITE_SEQUENCER_311 0x3137 +#define WM8995_WRITE_SEQUENCER_312 0x3138 +#define WM8995_WRITE_SEQUENCER_313 0x3139 +#define WM8995_WRITE_SEQUENCER_314 0x313A +#define WM8995_WRITE_SEQUENCER_315 0x313B +#define WM8995_WRITE_SEQUENCER_316 0x313C +#define WM8995_WRITE_SEQUENCER_317 0x313D +#define WM8995_WRITE_SEQUENCER_318 0x313E +#define WM8995_WRITE_SEQUENCER_319 0x313F +#define WM8995_WRITE_SEQUENCER_320 0x3140 +#define WM8995_WRITE_SEQUENCER_321 0x3141 +#define WM8995_WRITE_SEQUENCER_322 0x3142 +#define WM8995_WRITE_SEQUENCER_323 0x3143 +#define WM8995_WRITE_SEQUENCER_324 0x3144 +#define WM8995_WRITE_SEQUENCER_325 0x3145 +#define WM8995_WRITE_SEQUENCER_326 0x3146 +#define WM8995_WRITE_SEQUENCER_327 0x3147 +#define WM8995_WRITE_SEQUENCER_328 0x3148 +#define WM8995_WRITE_SEQUENCER_329 0x3149 +#define WM8995_WRITE_SEQUENCER_330 0x314A +#define WM8995_WRITE_SEQUENCER_331 0x314B +#define WM8995_WRITE_SEQUENCER_332 0x314C +#define WM8995_WRITE_SEQUENCER_333 0x314D +#define WM8995_WRITE_SEQUENCER_334 0x314E +#define WM8995_WRITE_SEQUENCER_335 0x314F +#define WM8995_WRITE_SEQUENCER_336 0x3150 +#define WM8995_WRITE_SEQUENCER_337 0x3151 +#define WM8995_WRITE_SEQUENCER_338 0x3152 +#define WM8995_WRITE_SEQUENCER_339 0x3153 +#define WM8995_WRITE_SEQUENCER_340 0x3154 +#define WM8995_WRITE_SEQUENCER_341 0x3155 +#define WM8995_WRITE_SEQUENCER_342 0x3156 +#define WM8995_WRITE_SEQUENCER_343 0x3157 +#define WM8995_WRITE_SEQUENCER_344 0x3158 +#define WM8995_WRITE_SEQUENCER_345 0x3159 +#define WM8995_WRITE_SEQUENCER_346 0x315A +#define WM8995_WRITE_SEQUENCER_347 0x315B +#define WM8995_WRITE_SEQUENCER_348 0x315C +#define WM8995_WRITE_SEQUENCER_349 0x315D +#define WM8995_WRITE_SEQUENCER_350 0x315E +#define WM8995_WRITE_SEQUENCER_351 0x315F +#define WM8995_WRITE_SEQUENCER_352 0x3160 +#define WM8995_WRITE_SEQUENCER_353 0x3161 +#define WM8995_WRITE_SEQUENCER_354 0x3162 +#define WM8995_WRITE_SEQUENCER_355 0x3163 +#define WM8995_WRITE_SEQUENCER_356 0x3164 +#define WM8995_WRITE_SEQUENCER_357 0x3165 +#define WM8995_WRITE_SEQUENCER_358 0x3166 +#define WM8995_WRITE_SEQUENCER_359 0x3167 +#define WM8995_WRITE_SEQUENCER_360 0x3168 +#define WM8995_WRITE_SEQUENCER_361 0x3169 +#define WM8995_WRITE_SEQUENCER_362 0x316A +#define WM8995_WRITE_SEQUENCER_363 0x316B +#define WM8995_WRITE_SEQUENCER_364 0x316C +#define WM8995_WRITE_SEQUENCER_365 0x316D +#define WM8995_WRITE_SEQUENCER_366 0x316E +#define WM8995_WRITE_SEQUENCER_367 0x316F +#define WM8995_WRITE_SEQUENCER_368 0x3170 +#define WM8995_WRITE_SEQUENCER_369 0x3171 +#define WM8995_WRITE_SEQUENCER_370 0x3172 +#define WM8995_WRITE_SEQUENCER_371 0x3173 +#define WM8995_WRITE_SEQUENCER_372 0x3174 +#define WM8995_WRITE_SEQUENCER_373 0x3175 +#define WM8995_WRITE_SEQUENCER_374 0x3176 +#define WM8995_WRITE_SEQUENCER_375 0x3177 +#define WM8995_WRITE_SEQUENCER_376 0x3178 +#define WM8995_WRITE_SEQUENCER_377 0x3179 +#define WM8995_WRITE_SEQUENCER_378 0x317A +#define WM8995_WRITE_SEQUENCER_379 0x317B +#define WM8995_WRITE_SEQUENCER_380 0x317C +#define WM8995_WRITE_SEQUENCER_381 0x317D +#define WM8995_WRITE_SEQUENCER_382 0x317E +#define WM8995_WRITE_SEQUENCER_383 0x317F +#define WM8995_WRITE_SEQUENCER_384 0x3180 +#define WM8995_WRITE_SEQUENCER_385 0x3181 +#define WM8995_WRITE_SEQUENCER_386 0x3182 +#define WM8995_WRITE_SEQUENCER_387 0x3183 +#define WM8995_WRITE_SEQUENCER_388 0x3184 +#define WM8995_WRITE_SEQUENCER_389 0x3185 +#define WM8995_WRITE_SEQUENCER_390 0x3186 +#define WM8995_WRITE_SEQUENCER_391 0x3187 +#define WM8995_WRITE_SEQUENCER_392 0x3188 +#define WM8995_WRITE_SEQUENCER_393 0x3189 +#define WM8995_WRITE_SEQUENCER_394 0x318A +#define WM8995_WRITE_SEQUENCER_395 0x318B +#define WM8995_WRITE_SEQUENCER_396 0x318C +#define WM8995_WRITE_SEQUENCER_397 0x318D +#define WM8995_WRITE_SEQUENCER_398 0x318E +#define WM8995_WRITE_SEQUENCER_399 0x318F +#define WM8995_WRITE_SEQUENCER_400 0x3190 +#define WM8995_WRITE_SEQUENCER_401 0x3191 +#define WM8995_WRITE_SEQUENCER_402 0x3192 +#define WM8995_WRITE_SEQUENCER_403 0x3193 +#define WM8995_WRITE_SEQUENCER_404 0x3194 +#define WM8995_WRITE_SEQUENCER_405 0x3195 +#define WM8995_WRITE_SEQUENCER_406 0x3196 +#define WM8995_WRITE_SEQUENCER_407 0x3197 +#define WM8995_WRITE_SEQUENCER_408 0x3198 +#define WM8995_WRITE_SEQUENCER_409 0x3199 +#define WM8995_WRITE_SEQUENCER_410 0x319A +#define WM8995_WRITE_SEQUENCER_411 0x319B +#define WM8995_WRITE_SEQUENCER_412 0x319C +#define WM8995_WRITE_SEQUENCER_413 0x319D +#define WM8995_WRITE_SEQUENCER_414 0x319E +#define WM8995_WRITE_SEQUENCER_415 0x319F +#define WM8995_WRITE_SEQUENCER_416 0x31A0 +#define WM8995_WRITE_SEQUENCER_417 0x31A1 +#define WM8995_WRITE_SEQUENCER_418 0x31A2 +#define WM8995_WRITE_SEQUENCER_419 0x31A3 +#define WM8995_WRITE_SEQUENCER_420 0x31A4 +#define WM8995_WRITE_SEQUENCER_421 0x31A5 +#define WM8995_WRITE_SEQUENCER_422 0x31A6 +#define WM8995_WRITE_SEQUENCER_423 0x31A7 +#define WM8995_WRITE_SEQUENCER_424 0x31A8 +#define WM8995_WRITE_SEQUENCER_425 0x31A9 +#define WM8995_WRITE_SEQUENCER_426 0x31AA +#define WM8995_WRITE_SEQUENCER_427 0x31AB +#define WM8995_WRITE_SEQUENCER_428 0x31AC +#define WM8995_WRITE_SEQUENCER_429 0x31AD +#define WM8995_WRITE_SEQUENCER_430 0x31AE +#define WM8995_WRITE_SEQUENCER_431 0x31AF +#define WM8995_WRITE_SEQUENCER_432 0x31B0 +#define WM8995_WRITE_SEQUENCER_433 0x31B1 +#define WM8995_WRITE_SEQUENCER_434 0x31B2 +#define WM8995_WRITE_SEQUENCER_435 0x31B3 +#define WM8995_WRITE_SEQUENCER_436 0x31B4 +#define WM8995_WRITE_SEQUENCER_437 0x31B5 +#define WM8995_WRITE_SEQUENCER_438 0x31B6 +#define WM8995_WRITE_SEQUENCER_439 0x31B7 +#define WM8995_WRITE_SEQUENCER_440 0x31B8 +#define WM8995_WRITE_SEQUENCER_441 0x31B9 +#define WM8995_WRITE_SEQUENCER_442 0x31BA +#define WM8995_WRITE_SEQUENCER_443 0x31BB +#define WM8995_WRITE_SEQUENCER_444 0x31BC +#define WM8995_WRITE_SEQUENCER_445 0x31BD +#define WM8995_WRITE_SEQUENCER_446 0x31BE +#define WM8995_WRITE_SEQUENCER_447 0x31BF +#define WM8995_WRITE_SEQUENCER_448 0x31C0 +#define WM8995_WRITE_SEQUENCER_449 0x31C1 +#define WM8995_WRITE_SEQUENCER_450 0x31C2 +#define WM8995_WRITE_SEQUENCER_451 0x31C3 +#define WM8995_WRITE_SEQUENCER_452 0x31C4 +#define WM8995_WRITE_SEQUENCER_453 0x31C5 +#define WM8995_WRITE_SEQUENCER_454 0x31C6 +#define WM8995_WRITE_SEQUENCER_455 0x31C7 +#define WM8995_WRITE_SEQUENCER_456 0x31C8 +#define WM8995_WRITE_SEQUENCER_457 0x31C9 +#define WM8995_WRITE_SEQUENCER_458 0x31CA +#define WM8995_WRITE_SEQUENCER_459 0x31CB +#define WM8995_WRITE_SEQUENCER_460 0x31CC +#define WM8995_WRITE_SEQUENCER_461 0x31CD +#define WM8995_WRITE_SEQUENCER_462 0x31CE +#define WM8995_WRITE_SEQUENCER_463 0x31CF +#define WM8995_WRITE_SEQUENCER_464 0x31D0 +#define WM8995_WRITE_SEQUENCER_465 0x31D1 +#define WM8995_WRITE_SEQUENCER_466 0x31D2 +#define WM8995_WRITE_SEQUENCER_467 0x31D3 +#define WM8995_WRITE_SEQUENCER_468 0x31D4 +#define WM8995_WRITE_SEQUENCER_469 0x31D5 +#define WM8995_WRITE_SEQUENCER_470 0x31D6 +#define WM8995_WRITE_SEQUENCER_471 0x31D7 +#define WM8995_WRITE_SEQUENCER_472 0x31D8 +#define WM8995_WRITE_SEQUENCER_473 0x31D9 +#define WM8995_WRITE_SEQUENCER_474 0x31DA +#define WM8995_WRITE_SEQUENCER_475 0x31DB +#define WM8995_WRITE_SEQUENCER_476 0x31DC +#define WM8995_WRITE_SEQUENCER_477 0x31DD +#define WM8995_WRITE_SEQUENCER_478 0x31DE +#define WM8995_WRITE_SEQUENCER_479 0x31DF +#define WM8995_WRITE_SEQUENCER_480 0x31E0 +#define WM8995_WRITE_SEQUENCER_481 0x31E1 +#define WM8995_WRITE_SEQUENCER_482 0x31E2 +#define WM8995_WRITE_SEQUENCER_483 0x31E3 +#define WM8995_WRITE_SEQUENCER_484 0x31E4 +#define WM8995_WRITE_SEQUENCER_485 0x31E5 +#define WM8995_WRITE_SEQUENCER_486 0x31E6 +#define WM8995_WRITE_SEQUENCER_487 0x31E7 +#define WM8995_WRITE_SEQUENCER_488 0x31E8 +#define WM8995_WRITE_SEQUENCER_489 0x31E9 +#define WM8995_WRITE_SEQUENCER_490 0x31EA +#define WM8995_WRITE_SEQUENCER_491 0x31EB +#define WM8995_WRITE_SEQUENCER_492 0x31EC +#define WM8995_WRITE_SEQUENCER_493 0x31ED +#define WM8995_WRITE_SEQUENCER_494 0x31EE +#define WM8995_WRITE_SEQUENCER_495 0x31EF +#define WM8995_WRITE_SEQUENCER_496 0x31F0 +#define WM8995_WRITE_SEQUENCER_497 0x31F1 +#define WM8995_WRITE_SEQUENCER_498 0x31F2 +#define WM8995_WRITE_SEQUENCER_499 0x31F3 +#define WM8995_WRITE_SEQUENCER_500 0x31F4 +#define WM8995_WRITE_SEQUENCER_501 0x31F5 +#define WM8995_WRITE_SEQUENCER_502 0x31F6 +#define WM8995_WRITE_SEQUENCER_503 0x31F7 +#define WM8995_WRITE_SEQUENCER_504 0x31F8 +#define WM8995_WRITE_SEQUENCER_505 0x31F9 +#define WM8995_WRITE_SEQUENCER_506 0x31FA +#define WM8995_WRITE_SEQUENCER_507 0x31FB +#define WM8995_WRITE_SEQUENCER_508 0x31FC +#define WM8995_WRITE_SEQUENCER_509 0x31FD +#define WM8995_WRITE_SEQUENCER_510 0x31FE +#define WM8995_WRITE_SEQUENCER_511 0x31FF + +#define WM8995_REGISTER_COUNT 725 +#define WM8995_MAX_REGISTER 0x31FF + +#define WM8995_MAX_CACHED_REGISTER WM8995_MAX_REGISTER + +/* + * Field Definitions. + */ + +/* + * R0 (0x00) - Software Reset + */ +#define WM8995_SW_RESET_MASK 0xFFFF /* SW_RESET - [15:0] */ +#define WM8995_SW_RESET_SHIFT 0 /* SW_RESET - [15:0] */ +#define WM8995_SW_RESET_WIDTH 16 /* SW_RESET - [15:0] */ + +/* + * R1 (0x01) - Power Management (1) + */ +#define WM8995_MICB2_ENA 0x0200 /* MICB2_ENA */ +#define WM8995_MICB2_ENA_MASK 0x0200 /* MICB2_ENA */ +#define WM8995_MICB2_ENA_SHIFT 9 /* MICB2_ENA */ +#define WM8995_MICB2_ENA_WIDTH 1 /* MICB2_ENA */ +#define WM8995_MICB1_ENA 0x0100 /* MICB1_ENA */ +#define WM8995_MICB1_ENA_MASK 0x0100 /* MICB1_ENA */ +#define WM8995_MICB1_ENA_SHIFT 8 /* MICB1_ENA */ +#define WM8995_MICB1_ENA_WIDTH 1 /* MICB1_ENA */ +#define WM8995_HPOUT2L_ENA 0x0080 /* HPOUT2L_ENA */ +#define WM8995_HPOUT2L_ENA_MASK 0x0080 /* HPOUT2L_ENA */ +#define WM8995_HPOUT2L_ENA_SHIFT 7 /* HPOUT2L_ENA */ +#define WM8995_HPOUT2L_ENA_WIDTH 1 /* HPOUT2L_ENA */ +#define WM8995_HPOUT2R_ENA 0x0040 /* HPOUT2R_ENA */ +#define WM8995_HPOUT2R_ENA_MASK 0x0040 /* HPOUT2R_ENA */ +#define WM8995_HPOUT2R_ENA_SHIFT 6 /* HPOUT2R_ENA */ +#define WM8995_HPOUT2R_ENA_WIDTH 1 /* HPOUT2R_ENA */ +#define WM8995_HPOUT1L_ENA 0x0020 /* HPOUT1L_ENA */ +#define WM8995_HPOUT1L_ENA_MASK 0x0020 /* HPOUT1L_ENA */ +#define WM8995_HPOUT1L_ENA_SHIFT 5 /* HPOUT1L_ENA */ +#define WM8995_HPOUT1L_ENA_WIDTH 1 /* HPOUT1L_ENA */ +#define WM8995_HPOUT1R_ENA 0x0010 /* HPOUT1R_ENA */ +#define WM8995_HPOUT1R_ENA_MASK 0x0010 /* HPOUT1R_ENA */ +#define WM8995_HPOUT1R_ENA_SHIFT 4 /* HPOUT1R_ENA */ +#define WM8995_HPOUT1R_ENA_WIDTH 1 /* HPOUT1R_ENA */ +#define WM8995_BG_ENA 0x0001 /* BG_ENA */ +#define WM8995_BG_ENA_MASK 0x0001 /* BG_ENA */ +#define WM8995_BG_ENA_SHIFT 0 /* BG_ENA */ +#define WM8995_BG_ENA_WIDTH 1 /* BG_ENA */ + +/* + * R2 (0x02) - Power Management (2) + */ +#define WM8995_OPCLK_ENA 0x0800 /* OPCLK_ENA */ +#define WM8995_OPCLK_ENA_MASK 0x0800 /* OPCLK_ENA */ +#define WM8995_OPCLK_ENA_SHIFT 11 /* OPCLK_ENA */ +#define WM8995_OPCLK_ENA_WIDTH 1 /* OPCLK_ENA */ +#define WM8995_IN1L_ENA 0x0020 /* IN1L_ENA */ +#define WM8995_IN1L_ENA_MASK 0x0020 /* IN1L_ENA */ +#define WM8995_IN1L_ENA_SHIFT 5 /* IN1L_ENA */ +#define WM8995_IN1L_ENA_WIDTH 1 /* IN1L_ENA */ +#define WM8995_IN1R_ENA 0x0010 /* IN1R_ENA */ +#define WM8995_IN1R_ENA_MASK 0x0010 /* IN1R_ENA */ +#define WM8995_IN1R_ENA_SHIFT 4 /* IN1R_ENA */ +#define WM8995_IN1R_ENA_WIDTH 1 /* IN1R_ENA */ +#define WM8995_LDO2_ENA 0x0002 /* LDO2_ENA */ +#define WM8995_LDO2_ENA_MASK 0x0002 /* LDO2_ENA */ +#define WM8995_LDO2_ENA_SHIFT 1 /* LDO2_ENA */ +#define WM8995_LDO2_ENA_WIDTH 1 /* LDO2_ENA */ + +/* + * R3 (0x03) - Power Management (3) + */ +#define WM8995_AIF2ADCL_ENA 0x2000 /* AIF2ADCL_ENA */ +#define WM8995_AIF2ADCL_ENA_MASK 0x2000 /* AIF2ADCL_ENA */ +#define WM8995_AIF2ADCL_ENA_SHIFT 13 /* AIF2ADCL_ENA */ +#define WM8995_AIF2ADCL_ENA_WIDTH 1 /* AIF2ADCL_ENA */ +#define WM8995_AIF2ADCR_ENA 0x1000 /* AIF2ADCR_ENA */ +#define WM8995_AIF2ADCR_ENA_MASK 0x1000 /* AIF2ADCR_ENA */ +#define WM8995_AIF2ADCR_ENA_SHIFT 12 /* AIF2ADCR_ENA */ +#define WM8995_AIF2ADCR_ENA_WIDTH 1 /* AIF2ADCR_ENA */ +#define WM8995_AIF1ADC2L_ENA 0x0800 /* AIF1ADC2L_ENA */ +#define WM8995_AIF1ADC2L_ENA_MASK 0x0800 /* AIF1ADC2L_ENA */ +#define WM8995_AIF1ADC2L_ENA_SHIFT 11 /* AIF1ADC2L_ENA */ +#define WM8995_AIF1ADC2L_ENA_WIDTH 1 /* AIF1ADC2L_ENA */ +#define WM8995_AIF1ADC2R_ENA 0x0400 /* AIF1ADC2R_ENA */ +#define WM8995_AIF1ADC2R_ENA_MASK 0x0400 /* AIF1ADC2R_ENA */ +#define WM8995_AIF1ADC2R_ENA_SHIFT 10 /* AIF1ADC2R_ENA */ +#define WM8995_AIF1ADC2R_ENA_WIDTH 1 /* AIF1ADC2R_ENA */ +#define WM8995_AIF1ADC1L_ENA 0x0200 /* AIF1ADC1L_ENA */ +#define WM8995_AIF1ADC1L_ENA_MASK 0x0200 /* AIF1ADC1L_ENA */ +#define WM8995_AIF1ADC1L_ENA_SHIFT 9 /* AIF1ADC1L_ENA */ +#define WM8995_AIF1ADC1L_ENA_WIDTH 1 /* AIF1ADC1L_ENA */ +#define WM8995_AIF1ADC1R_ENA 0x0100 /* AIF1ADC1R_ENA */ +#define WM8995_AIF1ADC1R_ENA_MASK 0x0100 /* AIF1ADC1R_ENA */ +#define WM8995_AIF1ADC1R_ENA_SHIFT 8 /* AIF1ADC1R_ENA */ +#define WM8995_AIF1ADC1R_ENA_WIDTH 1 /* AIF1ADC1R_ENA */ +#define WM8995_DMIC3L_ENA 0x0080 /* DMIC3L_ENA */ +#define WM8995_DMIC3L_ENA_MASK 0x0080 /* DMIC3L_ENA */ +#define WM8995_DMIC3L_ENA_SHIFT 7 /* DMIC3L_ENA */ +#define WM8995_DMIC3L_ENA_WIDTH 1 /* DMIC3L_ENA */ +#define WM8995_DMIC3R_ENA 0x0040 /* DMIC3R_ENA */ +#define WM8995_DMIC3R_ENA_MASK 0x0040 /* DMIC3R_ENA */ +#define WM8995_DMIC3R_ENA_SHIFT 6 /* DMIC3R_ENA */ +#define WM8995_DMIC3R_ENA_WIDTH 1 /* DMIC3R_ENA */ +#define WM8995_DMIC2L_ENA 0x0020 /* DMIC2L_ENA */ +#define WM8995_DMIC2L_ENA_MASK 0x0020 /* DMIC2L_ENA */ +#define WM8995_DMIC2L_ENA_SHIFT 5 /* DMIC2L_ENA */ +#define WM8995_DMIC2L_ENA_WIDTH 1 /* DMIC2L_ENA */ +#define WM8995_DMIC2R_ENA 0x0010 /* DMIC2R_ENA */ +#define WM8995_DMIC2R_ENA_MASK 0x0010 /* DMIC2R_ENA */ +#define WM8995_DMIC2R_ENA_SHIFT 4 /* DMIC2R_ENA */ +#define WM8995_DMIC2R_ENA_WIDTH 1 /* DMIC2R_ENA */ +#define WM8995_DMIC1L_ENA 0x0008 /* DMIC1L_ENA */ +#define WM8995_DMIC1L_ENA_MASK 0x0008 /* DMIC1L_ENA */ +#define WM8995_DMIC1L_ENA_SHIFT 3 /* DMIC1L_ENA */ +#define WM8995_DMIC1L_ENA_WIDTH 1 /* DMIC1L_ENA */ +#define WM8995_DMIC1R_ENA 0x0004 /* DMIC1R_ENA */ +#define WM8995_DMIC1R_ENA_MASK 0x0004 /* DMIC1R_ENA */ +#define WM8995_DMIC1R_ENA_SHIFT 2 /* DMIC1R_ENA */ +#define WM8995_DMIC1R_ENA_WIDTH 1 /* DMIC1R_ENA */ +#define WM8995_ADCL_ENA 0x0002 /* ADCL_ENA */ +#define WM8995_ADCL_ENA_MASK 0x0002 /* ADCL_ENA */ +#define WM8995_ADCL_ENA_SHIFT 1 /* ADCL_ENA */ +#define WM8995_ADCL_ENA_WIDTH 1 /* ADCL_ENA */ +#define WM8995_ADCR_ENA 0x0001 /* ADCR_ENA */ +#define WM8995_ADCR_ENA_MASK 0x0001 /* ADCR_ENA */ +#define WM8995_ADCR_ENA_SHIFT 0 /* ADCR_ENA */ +#define WM8995_ADCR_ENA_WIDTH 1 /* ADCR_ENA */ + +/* + * R4 (0x04) - Power Management (4) + */ +#define WM8995_AIF2DACL_ENA 0x2000 /* AIF2DACL_ENA */ +#define WM8995_AIF2DACL_ENA_MASK 0x2000 /* AIF2DACL_ENA */ +#define WM8995_AIF2DACL_ENA_SHIFT 13 /* AIF2DACL_ENA */ +#define WM8995_AIF2DACL_ENA_WIDTH 1 /* AIF2DACL_ENA */ +#define WM8995_AIF2DACR_ENA 0x1000 /* AIF2DACR_ENA */ +#define WM8995_AIF2DACR_ENA_MASK 0x1000 /* AIF2DACR_ENA */ +#define WM8995_AIF2DACR_ENA_SHIFT 12 /* AIF2DACR_ENA */ +#define WM8995_AIF2DACR_ENA_WIDTH 1 /* AIF2DACR_ENA */ +#define WM8995_AIF1DAC2L_ENA 0x0800 /* AIF1DAC2L_ENA */ +#define WM8995_AIF1DAC2L_ENA_MASK 0x0800 /* AIF1DAC2L_ENA */ +#define WM8995_AIF1DAC2L_ENA_SHIFT 11 /* AIF1DAC2L_ENA */ +#define WM8995_AIF1DAC2L_ENA_WIDTH 1 /* AIF1DAC2L_ENA */ +#define WM8995_AIF1DAC2R_ENA 0x0400 /* AIF1DAC2R_ENA */ +#define WM8995_AIF1DAC2R_ENA_MASK 0x0400 /* AIF1DAC2R_ENA */ +#define WM8995_AIF1DAC2R_ENA_SHIFT 10 /* AIF1DAC2R_ENA */ +#define WM8995_AIF1DAC2R_ENA_WIDTH 1 /* AIF1DAC2R_ENA */ +#define WM8995_AIF1DAC1L_ENA 0x0200 /* AIF1DAC1L_ENA */ +#define WM8995_AIF1DAC1L_ENA_MASK 0x0200 /* AIF1DAC1L_ENA */ +#define WM8995_AIF1DAC1L_ENA_SHIFT 9 /* AIF1DAC1L_ENA */ +#define WM8995_AIF1DAC1L_ENA_WIDTH 1 /* AIF1DAC1L_ENA */ +#define WM8995_AIF1DAC1R_ENA 0x0100 /* AIF1DAC1R_ENA */ +#define WM8995_AIF1DAC1R_ENA_MASK 0x0100 /* AIF1DAC1R_ENA */ +#define WM8995_AIF1DAC1R_ENA_SHIFT 8 /* AIF1DAC1R_ENA */ +#define WM8995_AIF1DAC1R_ENA_WIDTH 1 /* AIF1DAC1R_ENA */ +#define WM8995_DAC2L_ENA 0x0008 /* DAC2L_ENA */ +#define WM8995_DAC2L_ENA_MASK 0x0008 /* DAC2L_ENA */ +#define WM8995_DAC2L_ENA_SHIFT 3 /* DAC2L_ENA */ +#define WM8995_DAC2L_ENA_WIDTH 1 /* DAC2L_ENA */ +#define WM8995_DAC2R_ENA 0x0004 /* DAC2R_ENA */ +#define WM8995_DAC2R_ENA_MASK 0x0004 /* DAC2R_ENA */ +#define WM8995_DAC2R_ENA_SHIFT 2 /* DAC2R_ENA */ +#define WM8995_DAC2R_ENA_WIDTH 1 /* DAC2R_ENA */ +#define WM8995_DAC1L_ENA 0x0002 /* DAC1L_ENA */ +#define WM8995_DAC1L_ENA_MASK 0x0002 /* DAC1L_ENA */ +#define WM8995_DAC1L_ENA_SHIFT 1 /* DAC1L_ENA */ +#define WM8995_DAC1L_ENA_WIDTH 1 /* DAC1L_ENA */ +#define WM8995_DAC1R_ENA 0x0001 /* DAC1R_ENA */ +#define WM8995_DAC1R_ENA_MASK 0x0001 /* DAC1R_ENA */ +#define WM8995_DAC1R_ENA_SHIFT 0 /* DAC1R_ENA */ +#define WM8995_DAC1R_ENA_WIDTH 1 /* DAC1R_ENA */ + +/* + * R5 (0x05) - Power Management (5) + */ +#define WM8995_DMIC_SRC2_MASK 0x0300 /* DMIC_SRC2 - [9:8] */ +#define WM8995_DMIC_SRC2_SHIFT 8 /* DMIC_SRC2 - [9:8] */ +#define WM8995_DMIC_SRC2_WIDTH 2 /* DMIC_SRC2 - [9:8] */ +#define WM8995_DMIC_SRC1_MASK 0x00C0 /* DMIC_SRC1 - [7:6] */ +#define WM8995_DMIC_SRC1_SHIFT 6 /* DMIC_SRC1 - [7:6] */ +#define WM8995_DMIC_SRC1_WIDTH 2 /* DMIC_SRC1 - [7:6] */ +#define WM8995_AIF3_TRI 0x0020 /* AIF3_TRI */ +#define WM8995_AIF3_TRI_MASK 0x0020 /* AIF3_TRI */ +#define WM8995_AIF3_TRI_SHIFT 5 /* AIF3_TRI */ +#define WM8995_AIF3_TRI_WIDTH 1 /* AIF3_TRI */ +#define WM8995_AIF3_ADCDAT_SRC_MASK 0x0018 /* AIF3_ADCDAT_SRC - [4:3] */ +#define WM8995_AIF3_ADCDAT_SRC_SHIFT 3 /* AIF3_ADCDAT_SRC - [4:3] */ +#define WM8995_AIF3_ADCDAT_SRC_WIDTH 2 /* AIF3_ADCDAT_SRC - [4:3] */ +#define WM8995_AIF2_ADCDAT_SRC 0x0004 /* AIF2_ADCDAT_SRC */ +#define WM8995_AIF2_ADCDAT_SRC_MASK 0x0004 /* AIF2_ADCDAT_SRC */ +#define WM8995_AIF2_ADCDAT_SRC_SHIFT 2 /* AIF2_ADCDAT_SRC */ +#define WM8995_AIF2_ADCDAT_SRC_WIDTH 1 /* AIF2_ADCDAT_SRC */ +#define WM8995_AIF2_DACDAT_SRC 0x0002 /* AIF2_DACDAT_SRC */ +#define WM8995_AIF2_DACDAT_SRC_MASK 0x0002 /* AIF2_DACDAT_SRC */ +#define WM8995_AIF2_DACDAT_SRC_SHIFT 1 /* AIF2_DACDAT_SRC */ +#define WM8995_AIF2_DACDAT_SRC_WIDTH 1 /* AIF2_DACDAT_SRC */ +#define WM8995_AIF1_DACDAT_SRC 0x0001 /* AIF1_DACDAT_SRC */ +#define WM8995_AIF1_DACDAT_SRC_MASK 0x0001 /* AIF1_DACDAT_SRC */ +#define WM8995_AIF1_DACDAT_SRC_SHIFT 0 /* AIF1_DACDAT_SRC */ +#define WM8995_AIF1_DACDAT_SRC_WIDTH 1 /* AIF1_DACDAT_SRC */ + +/* + * R16 (0x10) - Left Line Input 1 Volume + */ +#define WM8995_IN1_VU 0x0080 /* IN1_VU */ +#define WM8995_IN1_VU_MASK 0x0080 /* IN1_VU */ +#define WM8995_IN1_VU_SHIFT 7 /* IN1_VU */ +#define WM8995_IN1_VU_WIDTH 1 /* IN1_VU */ +#define WM8995_IN1L_ZC 0x0020 /* IN1L_ZC */ +#define WM8995_IN1L_ZC_MASK 0x0020 /* IN1L_ZC */ +#define WM8995_IN1L_ZC_SHIFT 5 /* IN1L_ZC */ +#define WM8995_IN1L_ZC_WIDTH 1 /* IN1L_ZC */ +#define WM8995_IN1L_VOL_MASK 0x001F /* IN1L_VOL - [4:0] */ +#define WM8995_IN1L_VOL_SHIFT 0 /* IN1L_VOL - [4:0] */ +#define WM8995_IN1L_VOL_WIDTH 5 /* IN1L_VOL - [4:0] */ + +/* + * R17 (0x11) - Right Line Input 1 Volume + */ +#define WM8995_IN1_VU 0x0080 /* IN1_VU */ +#define WM8995_IN1_VU_MASK 0x0080 /* IN1_VU */ +#define WM8995_IN1_VU_SHIFT 7 /* IN1_VU */ +#define WM8995_IN1_VU_WIDTH 1 /* IN1_VU */ +#define WM8995_IN1R_ZC 0x0020 /* IN1R_ZC */ +#define WM8995_IN1R_ZC_MASK 0x0020 /* IN1R_ZC */ +#define WM8995_IN1R_ZC_SHIFT 5 /* IN1R_ZC */ +#define WM8995_IN1R_ZC_WIDTH 1 /* IN1R_ZC */ +#define WM8995_IN1R_VOL_MASK 0x001F /* IN1R_VOL - [4:0] */ +#define WM8995_IN1R_VOL_SHIFT 0 /* IN1R_VOL - [4:0] */ +#define WM8995_IN1R_VOL_WIDTH 5 /* IN1R_VOL - [4:0] */ + +/* + * R18 (0x12) - Left Line Input Control + */ +#define WM8995_IN1L_BOOST_MASK 0x0030 /* IN1L_BOOST - [5:4] */ +#define WM8995_IN1L_BOOST_SHIFT 4 /* IN1L_BOOST - [5:4] */ +#define WM8995_IN1L_BOOST_WIDTH 2 /* IN1L_BOOST - [5:4] */ +#define WM8995_IN1L_MODE_MASK 0x000C /* IN1L_MODE - [3:2] */ +#define WM8995_IN1L_MODE_SHIFT 2 /* IN1L_MODE - [3:2] */ +#define WM8995_IN1L_MODE_WIDTH 2 /* IN1L_MODE - [3:2] */ +#define WM8995_IN1R_MODE_MASK 0x0003 /* IN1R_MODE - [1:0] */ +#define WM8995_IN1R_MODE_SHIFT 0 /* IN1R_MODE - [1:0] */ +#define WM8995_IN1R_MODE_WIDTH 2 /* IN1R_MODE - [1:0] */ + +/* + * R24 (0x18) - DAC1 Left Volume + */ +#define WM8995_DAC1L_MUTE 0x0200 /* DAC1L_MUTE */ +#define WM8995_DAC1L_MUTE_MASK 0x0200 /* DAC1L_MUTE */ +#define WM8995_DAC1L_MUTE_SHIFT 9 /* DAC1L_MUTE */ +#define WM8995_DAC1L_MUTE_WIDTH 1 /* DAC1L_MUTE */ +#define WM8995_DAC1_VU 0x0100 /* DAC1_VU */ +#define WM8995_DAC1_VU_MASK 0x0100 /* DAC1_VU */ +#define WM8995_DAC1_VU_SHIFT 8 /* DAC1_VU */ +#define WM8995_DAC1_VU_WIDTH 1 /* DAC1_VU */ +#define WM8995_DAC1L_VOL_MASK 0x00FF /* DAC1L_VOL - [7:0] */ +#define WM8995_DAC1L_VOL_SHIFT 0 /* DAC1L_VOL - [7:0] */ +#define WM8995_DAC1L_VOL_WIDTH 8 /* DAC1L_VOL - [7:0] */ + +/* + * R25 (0x19) - DAC1 Right Volume + */ +#define WM8995_DAC1R_MUTE 0x0200 /* DAC1R_MUTE */ +#define WM8995_DAC1R_MUTE_MASK 0x0200 /* DAC1R_MUTE */ +#define WM8995_DAC1R_MUTE_SHIFT 9 /* DAC1R_MUTE */ +#define WM8995_DAC1R_MUTE_WIDTH 1 /* DAC1R_MUTE */ +#define WM8995_DAC1_VU 0x0100 /* DAC1_VU */ +#define WM8995_DAC1_VU_MASK 0x0100 /* DAC1_VU */ +#define WM8995_DAC1_VU_SHIFT 8 /* DAC1_VU */ +#define WM8995_DAC1_VU_WIDTH 1 /* DAC1_VU */ +#define WM8995_DAC1R_VOL_MASK 0x00FF /* DAC1R_VOL - [7:0] */ +#define WM8995_DAC1R_VOL_SHIFT 0 /* DAC1R_VOL - [7:0] */ +#define WM8995_DAC1R_VOL_WIDTH 8 /* DAC1R_VOL - [7:0] */ + +/* + * R26 (0x1A) - DAC2 Left Volume + */ +#define WM8995_DAC2L_MUTE 0x0200 /* DAC2L_MUTE */ +#define WM8995_DAC2L_MUTE_MASK 0x0200 /* DAC2L_MUTE */ +#define WM8995_DAC2L_MUTE_SHIFT 9 /* DAC2L_MUTE */ +#define WM8995_DAC2L_MUTE_WIDTH 1 /* DAC2L_MUTE */ +#define WM8995_DAC2_VU 0x0100 /* DAC2_VU */ +#define WM8995_DAC2_VU_MASK 0x0100 /* DAC2_VU */ +#define WM8995_DAC2_VU_SHIFT 8 /* DAC2_VU */ +#define WM8995_DAC2_VU_WIDTH 1 /* DAC2_VU */ +#define WM8995_DAC2L_VOL_MASK 0x00FF /* DAC2L_VOL - [7:0] */ +#define WM8995_DAC2L_VOL_SHIFT 0 /* DAC2L_VOL - [7:0] */ +#define WM8995_DAC2L_VOL_WIDTH 8 /* DAC2L_VOL - [7:0] */ + +/* + * R27 (0x1B) - DAC2 Right Volume + */ +#define WM8995_DAC2R_MUTE 0x0200 /* DAC2R_MUTE */ +#define WM8995_DAC2R_MUTE_MASK 0x0200 /* DAC2R_MUTE */ +#define WM8995_DAC2R_MUTE_SHIFT 9 /* DAC2R_MUTE */ +#define WM8995_DAC2R_MUTE_WIDTH 1 /* DAC2R_MUTE */ +#define WM8995_DAC2_VU 0x0100 /* DAC2_VU */ +#define WM8995_DAC2_VU_MASK 0x0100 /* DAC2_VU */ +#define WM8995_DAC2_VU_SHIFT 8 /* DAC2_VU */ +#define WM8995_DAC2_VU_WIDTH 1 /* DAC2_VU */ +#define WM8995_DAC2R_VOL_MASK 0x00FF /* DAC2R_VOL - [7:0] */ +#define WM8995_DAC2R_VOL_SHIFT 0 /* DAC2R_VOL - [7:0] */ +#define WM8995_DAC2R_VOL_WIDTH 8 /* DAC2R_VOL - [7:0] */ + +/* + * R28 (0x1C) - Output Volume ZC (1) + */ +#define WM8995_HPOUT2L_ZC 0x0008 /* HPOUT2L_ZC */ +#define WM8995_HPOUT2L_ZC_MASK 0x0008 /* HPOUT2L_ZC */ +#define WM8995_HPOUT2L_ZC_SHIFT 3 /* HPOUT2L_ZC */ +#define WM8995_HPOUT2L_ZC_WIDTH 1 /* HPOUT2L_ZC */ +#define WM8995_HPOUT2R_ZC 0x0004 /* HPOUT2R_ZC */ +#define WM8995_HPOUT2R_ZC_MASK 0x0004 /* HPOUT2R_ZC */ +#define WM8995_HPOUT2R_ZC_SHIFT 2 /* HPOUT2R_ZC */ +#define WM8995_HPOUT2R_ZC_WIDTH 1 /* HPOUT2R_ZC */ +#define WM8995_HPOUT1L_ZC 0x0002 /* HPOUT1L_ZC */ +#define WM8995_HPOUT1L_ZC_MASK 0x0002 /* HPOUT1L_ZC */ +#define WM8995_HPOUT1L_ZC_SHIFT 1 /* HPOUT1L_ZC */ +#define WM8995_HPOUT1L_ZC_WIDTH 1 /* HPOUT1L_ZC */ +#define WM8995_HPOUT1R_ZC 0x0001 /* HPOUT1R_ZC */ +#define WM8995_HPOUT1R_ZC_MASK 0x0001 /* HPOUT1R_ZC */ +#define WM8995_HPOUT1R_ZC_SHIFT 0 /* HPOUT1R_ZC */ +#define WM8995_HPOUT1R_ZC_WIDTH 1 /* HPOUT1R_ZC */ + +/* + * R32 (0x20) - MICBIAS (1) + */ +#define WM8995_MICB1_MODE 0x0008 /* MICB1_MODE */ +#define WM8995_MICB1_MODE_MASK 0x0008 /* MICB1_MODE */ +#define WM8995_MICB1_MODE_SHIFT 3 /* MICB1_MODE */ +#define WM8995_MICB1_MODE_WIDTH 1 /* MICB1_MODE */ +#define WM8995_MICB1_LVL_MASK 0x0006 /* MICB1_LVL - [2:1] */ +#define WM8995_MICB1_LVL_SHIFT 1 /* MICB1_LVL - [2:1] */ +#define WM8995_MICB1_LVL_WIDTH 2 /* MICB1_LVL - [2:1] */ +#define WM8995_MICB1_DISCH 0x0001 /* MICB1_DISCH */ +#define WM8995_MICB1_DISCH_MASK 0x0001 /* MICB1_DISCH */ +#define WM8995_MICB1_DISCH_SHIFT 0 /* MICB1_DISCH */ +#define WM8995_MICB1_DISCH_WIDTH 1 /* MICB1_DISCH */ + +/* + * R33 (0x21) - MICBIAS (2) + */ +#define WM8995_MICB2_MODE 0x0008 /* MICB2_MODE */ +#define WM8995_MICB2_MODE_MASK 0x0008 /* MICB2_MODE */ +#define WM8995_MICB2_MODE_SHIFT 3 /* MICB2_MODE */ +#define WM8995_MICB2_MODE_WIDTH 1 /* MICB2_MODE */ +#define WM8995_MICB2_LVL_MASK 0x0006 /* MICB2_LVL - [2:1] */ +#define WM8995_MICB2_LVL_SHIFT 1 /* MICB2_LVL - [2:1] */ +#define WM8995_MICB2_LVL_WIDTH 2 /* MICB2_LVL - [2:1] */ +#define WM8995_MICB2_DISCH 0x0001 /* MICB2_DISCH */ +#define WM8995_MICB2_DISCH_MASK 0x0001 /* MICB2_DISCH */ +#define WM8995_MICB2_DISCH_SHIFT 0 /* MICB2_DISCH */ +#define WM8995_MICB2_DISCH_WIDTH 1 /* MICB2_DISCH */ + +/* + * R40 (0x28) - LDO 1 + */ +#define WM8995_LDO1_MODE 0x0020 /* LDO1_MODE */ +#define WM8995_LDO1_MODE_MASK 0x0020 /* LDO1_MODE */ +#define WM8995_LDO1_MODE_SHIFT 5 /* LDO1_MODE */ +#define WM8995_LDO1_MODE_WIDTH 1 /* LDO1_MODE */ +#define WM8995_LDO1_VSEL_MASK 0x0006 /* LDO1_VSEL - [2:1] */ +#define WM8995_LDO1_VSEL_SHIFT 1 /* LDO1_VSEL - [2:1] */ +#define WM8995_LDO1_VSEL_WIDTH 2 /* LDO1_VSEL - [2:1] */ +#define WM8995_LDO1_DISCH 0x0001 /* LDO1_DISCH */ +#define WM8995_LDO1_DISCH_MASK 0x0001 /* LDO1_DISCH */ +#define WM8995_LDO1_DISCH_SHIFT 0 /* LDO1_DISCH */ +#define WM8995_LDO1_DISCH_WIDTH 1 /* LDO1_DISCH */ + +/* + * R41 (0x29) - LDO 2 + */ +#define WM8995_LDO2_MODE 0x0020 /* LDO2_MODE */ +#define WM8995_LDO2_MODE_MASK 0x0020 /* LDO2_MODE */ +#define WM8995_LDO2_MODE_SHIFT 5 /* LDO2_MODE */ +#define WM8995_LDO2_MODE_WIDTH 1 /* LDO2_MODE */ +#define WM8995_LDO2_VSEL_MASK 0x001E /* LDO2_VSEL - [4:1] */ +#define WM8995_LDO2_VSEL_SHIFT 1 /* LDO2_VSEL - [4:1] */ +#define WM8995_LDO2_VSEL_WIDTH 4 /* LDO2_VSEL - [4:1] */ +#define WM8995_LDO2_DISCH 0x0001 /* LDO2_DISCH */ +#define WM8995_LDO2_DISCH_MASK 0x0001 /* LDO2_DISCH */ +#define WM8995_LDO2_DISCH_SHIFT 0 /* LDO2_DISCH */ +#define WM8995_LDO2_DISCH_WIDTH 1 /* LDO2_DISCH */ + +/* + * R48 (0x30) - Accessory Detect Mode1 + */ +#define WM8995_JD_MODE_MASK 0x0003 /* JD_MODE - [1:0] */ +#define WM8995_JD_MODE_SHIFT 0 /* JD_MODE - [1:0] */ +#define WM8995_JD_MODE_WIDTH 2 /* JD_MODE - [1:0] */ + +/* + * R49 (0x31) - Accessory Detect Mode2 + */ +#define WM8995_VID_ENA 0x0001 /* VID_ENA */ +#define WM8995_VID_ENA_MASK 0x0001 /* VID_ENA */ +#define WM8995_VID_ENA_SHIFT 0 /* VID_ENA */ +#define WM8995_VID_ENA_WIDTH 1 /* VID_ENA */ + +/* + * R52 (0x34) - Headphone Detect1 + */ +#define WM8995_HP_RAMPRATE 0x0002 /* HP_RAMPRATE */ +#define WM8995_HP_RAMPRATE_MASK 0x0002 /* HP_RAMPRATE */ +#define WM8995_HP_RAMPRATE_SHIFT 1 /* HP_RAMPRATE */ +#define WM8995_HP_RAMPRATE_WIDTH 1 /* HP_RAMPRATE */ +#define WM8995_HP_POLL 0x0001 /* HP_POLL */ +#define WM8995_HP_POLL_MASK 0x0001 /* HP_POLL */ +#define WM8995_HP_POLL_SHIFT 0 /* HP_POLL */ +#define WM8995_HP_POLL_WIDTH 1 /* HP_POLL */ + +/* + * R53 (0x35) - Headphone Detect2 + */ +#define WM8995_HP_DONE 0x0080 /* HP_DONE */ +#define WM8995_HP_DONE_MASK 0x0080 /* HP_DONE */ +#define WM8995_HP_DONE_SHIFT 7 /* HP_DONE */ +#define WM8995_HP_DONE_WIDTH 1 /* HP_DONE */ +#define WM8995_HP_LVL_MASK 0x007F /* HP_LVL - [6:0] */ +#define WM8995_HP_LVL_SHIFT 0 /* HP_LVL - [6:0] */ +#define WM8995_HP_LVL_WIDTH 7 /* HP_LVL - [6:0] */ + +/* + * R56 (0x38) - Mic Detect (1) + */ +#define WM8995_MICD_RATE_MASK 0x7800 /* MICD_RATE - [14:11] */ +#define WM8995_MICD_RATE_SHIFT 11 /* MICD_RATE - [14:11] */ +#define WM8995_MICD_RATE_WIDTH 4 /* MICD_RATE - [14:11] */ +#define WM8995_MICD_LVL_SEL_MASK 0x01F8 /* MICD_LVL_SEL - [8:3] */ +#define WM8995_MICD_LVL_SEL_SHIFT 3 /* MICD_LVL_SEL - [8:3] */ +#define WM8995_MICD_LVL_SEL_WIDTH 6 /* MICD_LVL_SEL - [8:3] */ +#define WM8995_MICD_DBTIME 0x0002 /* MICD_DBTIME */ +#define WM8995_MICD_DBTIME_MASK 0x0002 /* MICD_DBTIME */ +#define WM8995_MICD_DBTIME_SHIFT 1 /* MICD_DBTIME */ +#define WM8995_MICD_DBTIME_WIDTH 1 /* MICD_DBTIME */ +#define WM8995_MICD_ENA 0x0001 /* MICD_ENA */ +#define WM8995_MICD_ENA_MASK 0x0001 /* MICD_ENA */ +#define WM8995_MICD_ENA_SHIFT 0 /* MICD_ENA */ +#define WM8995_MICD_ENA_WIDTH 1 /* MICD_ENA */ + +/* + * R57 (0x39) - Mic Detect (2) + */ +#define WM8995_MICD_LVL_MASK 0x01FC /* MICD_LVL - [8:2] */ +#define WM8995_MICD_LVL_SHIFT 2 /* MICD_LVL - [8:2] */ +#define WM8995_MICD_LVL_WIDTH 7 /* MICD_LVL - [8:2] */ +#define WM8995_MICD_VALID 0x0002 /* MICD_VALID */ +#define WM8995_MICD_VALID_MASK 0x0002 /* MICD_VALID */ +#define WM8995_MICD_VALID_SHIFT 1 /* MICD_VALID */ +#define WM8995_MICD_VALID_WIDTH 1 /* MICD_VALID */ +#define WM8995_MICD_STS 0x0001 /* MICD_STS */ +#define WM8995_MICD_STS_MASK 0x0001 /* MICD_STS */ +#define WM8995_MICD_STS_SHIFT 0 /* MICD_STS */ +#define WM8995_MICD_STS_WIDTH 1 /* MICD_STS */ + +/* + * R64 (0x40) - Charge Pump (1) + */ +#define WM8995_CP_ENA 0x8000 /* CP_ENA */ +#define WM8995_CP_ENA_MASK 0x8000 /* CP_ENA */ +#define WM8995_CP_ENA_SHIFT 15 /* CP_ENA */ +#define WM8995_CP_ENA_WIDTH 1 /* CP_ENA */ + +/* + * R69 (0x45) - Class W (1) + */ +#define WM8995_CP_DYN_SRC_SEL_MASK 0x0300 /* CP_DYN_SRC_SEL - [9:8] */ +#define WM8995_CP_DYN_SRC_SEL_SHIFT 8 /* CP_DYN_SRC_SEL - [9:8] */ +#define WM8995_CP_DYN_SRC_SEL_WIDTH 2 /* CP_DYN_SRC_SEL - [9:8] */ +#define WM8995_CP_DYN_PWR 0x0001 /* CP_DYN_PWR */ +#define WM8995_CP_DYN_PWR_MASK 0x0001 /* CP_DYN_PWR */ +#define WM8995_CP_DYN_PWR_SHIFT 0 /* CP_DYN_PWR */ +#define WM8995_CP_DYN_PWR_WIDTH 1 /* CP_DYN_PWR */ + +/* + * R80 (0x50) - DC Servo (1) + */ +#define WM8995_DCS_ENA_CHAN_3 0x0008 /* DCS_ENA_CHAN_3 */ +#define WM8995_DCS_ENA_CHAN_3_MASK 0x0008 /* DCS_ENA_CHAN_3 */ +#define WM8995_DCS_ENA_CHAN_3_SHIFT 3 /* DCS_ENA_CHAN_3 */ +#define WM8995_DCS_ENA_CHAN_3_WIDTH 1 /* DCS_ENA_CHAN_3 */ +#define WM8995_DCS_ENA_CHAN_2 0x0004 /* DCS_ENA_CHAN_2 */ +#define WM8995_DCS_ENA_CHAN_2_MASK 0x0004 /* DCS_ENA_CHAN_2 */ +#define WM8995_DCS_ENA_CHAN_2_SHIFT 2 /* DCS_ENA_CHAN_2 */ +#define WM8995_DCS_ENA_CHAN_2_WIDTH 1 /* DCS_ENA_CHAN_2 */ +#define WM8995_DCS_ENA_CHAN_1 0x0002 /* DCS_ENA_CHAN_1 */ +#define WM8995_DCS_ENA_CHAN_1_MASK 0x0002 /* DCS_ENA_CHAN_1 */ +#define WM8995_DCS_ENA_CHAN_1_SHIFT 1 /* DCS_ENA_CHAN_1 */ +#define WM8995_DCS_ENA_CHAN_1_WIDTH 1 /* DCS_ENA_CHAN_1 */ +#define WM8995_DCS_ENA_CHAN_0 0x0001 /* DCS_ENA_CHAN_0 */ +#define WM8995_DCS_ENA_CHAN_0_MASK 0x0001 /* DCS_ENA_CHAN_0 */ +#define WM8995_DCS_ENA_CHAN_0_SHIFT 0 /* DCS_ENA_CHAN_0 */ +#define WM8995_DCS_ENA_CHAN_0_WIDTH 1 /* DCS_ENA_CHAN_0 */ + +/* + * R81 (0x51) - DC Servo (2) + */ +#define WM8995_DCS_TRIG_SINGLE_3 0x8000 /* DCS_TRIG_SINGLE_3 */ +#define WM8995_DCS_TRIG_SINGLE_3_MASK 0x8000 /* DCS_TRIG_SINGLE_3 */ +#define WM8995_DCS_TRIG_SINGLE_3_SHIFT 15 /* DCS_TRIG_SINGLE_3 */ +#define WM8995_DCS_TRIG_SINGLE_3_WIDTH 1 /* DCS_TRIG_SINGLE_3 */ +#define WM8995_DCS_TRIG_SINGLE_2 0x4000 /* DCS_TRIG_SINGLE_2 */ +#define WM8995_DCS_TRIG_SINGLE_2_MASK 0x4000 /* DCS_TRIG_SINGLE_2 */ +#define WM8995_DCS_TRIG_SINGLE_2_SHIFT 14 /* DCS_TRIG_SINGLE_2 */ +#define WM8995_DCS_TRIG_SINGLE_2_WIDTH 1 /* DCS_TRIG_SINGLE_2 */ +#define WM8995_DCS_TRIG_SINGLE_1 0x2000 /* DCS_TRIG_SINGLE_1 */ +#define WM8995_DCS_TRIG_SINGLE_1_MASK 0x2000 /* DCS_TRIG_SINGLE_1 */ +#define WM8995_DCS_TRIG_SINGLE_1_SHIFT 13 /* DCS_TRIG_SINGLE_1 */ +#define WM8995_DCS_TRIG_SINGLE_1_WIDTH 1 /* DCS_TRIG_SINGLE_1 */ +#define WM8995_DCS_TRIG_SINGLE_0 0x1000 /* DCS_TRIG_SINGLE_0 */ +#define WM8995_DCS_TRIG_SINGLE_0_MASK 0x1000 /* DCS_TRIG_SINGLE_0 */ +#define WM8995_DCS_TRIG_SINGLE_0_SHIFT 12 /* DCS_TRIG_SINGLE_0 */ +#define WM8995_DCS_TRIG_SINGLE_0_WIDTH 1 /* DCS_TRIG_SINGLE_0 */ +#define WM8995_DCS_TRIG_SERIES_3 0x0800 /* DCS_TRIG_SERIES_3 */ +#define WM8995_DCS_TRIG_SERIES_3_MASK 0x0800 /* DCS_TRIG_SERIES_3 */ +#define WM8995_DCS_TRIG_SERIES_3_SHIFT 11 /* DCS_TRIG_SERIES_3 */ +#define WM8995_DCS_TRIG_SERIES_3_WIDTH 1 /* DCS_TRIG_SERIES_3 */ +#define WM8995_DCS_TRIG_SERIES_2 0x0400 /* DCS_TRIG_SERIES_2 */ +#define WM8995_DCS_TRIG_SERIES_2_MASK 0x0400 /* DCS_TRIG_SERIES_2 */ +#define WM8995_DCS_TRIG_SERIES_2_SHIFT 10 /* DCS_TRIG_SERIES_2 */ +#define WM8995_DCS_TRIG_SERIES_2_WIDTH 1 /* DCS_TRIG_SERIES_2 */ +#define WM8995_DCS_TRIG_SERIES_1 0x0200 /* DCS_TRIG_SERIES_1 */ +#define WM8995_DCS_TRIG_SERIES_1_MASK 0x0200 /* DCS_TRIG_SERIES_1 */ +#define WM8995_DCS_TRIG_SERIES_1_SHIFT 9 /* DCS_TRIG_SERIES_1 */ +#define WM8995_DCS_TRIG_SERIES_1_WIDTH 1 /* DCS_TRIG_SERIES_1 */ +#define WM8995_DCS_TRIG_SERIES_0 0x0100 /* DCS_TRIG_SERIES_0 */ +#define WM8995_DCS_TRIG_SERIES_0_MASK 0x0100 /* DCS_TRIG_SERIES_0 */ +#define WM8995_DCS_TRIG_SERIES_0_SHIFT 8 /* DCS_TRIG_SERIES_0 */ +#define WM8995_DCS_TRIG_SERIES_0_WIDTH 1 /* DCS_TRIG_SERIES_0 */ +#define WM8995_DCS_TRIG_STARTUP_3 0x0080 /* DCS_TRIG_STARTUP_3 */ +#define WM8995_DCS_TRIG_STARTUP_3_MASK 0x0080 /* DCS_TRIG_STARTUP_3 */ +#define WM8995_DCS_TRIG_STARTUP_3_SHIFT 7 /* DCS_TRIG_STARTUP_3 */ +#define WM8995_DCS_TRIG_STARTUP_3_WIDTH 1 /* DCS_TRIG_STARTUP_3 */ +#define WM8995_DCS_TRIG_STARTUP_2 0x0040 /* DCS_TRIG_STARTUP_2 */ +#define WM8995_DCS_TRIG_STARTUP_2_MASK 0x0040 /* DCS_TRIG_STARTUP_2 */ +#define WM8995_DCS_TRIG_STARTUP_2_SHIFT 6 /* DCS_TRIG_STARTUP_2 */ +#define WM8995_DCS_TRIG_STARTUP_2_WIDTH 1 /* DCS_TRIG_STARTUP_2 */ +#define WM8995_DCS_TRIG_STARTUP_1 0x0020 /* DCS_TRIG_STARTUP_1 */ +#define WM8995_DCS_TRIG_STARTUP_1_MASK 0x0020 /* DCS_TRIG_STARTUP_1 */ +#define WM8995_DCS_TRIG_STARTUP_1_SHIFT 5 /* DCS_TRIG_STARTUP_1 */ +#define WM8995_DCS_TRIG_STARTUP_1_WIDTH 1 /* DCS_TRIG_STARTUP_1 */ +#define WM8995_DCS_TRIG_STARTUP_0 0x0010 /* DCS_TRIG_STARTUP_0 */ +#define WM8995_DCS_TRIG_STARTUP_0_MASK 0x0010 /* DCS_TRIG_STARTUP_0 */ +#define WM8995_DCS_TRIG_STARTUP_0_SHIFT 4 /* DCS_TRIG_STARTUP_0 */ +#define WM8995_DCS_TRIG_STARTUP_0_WIDTH 1 /* DCS_TRIG_STARTUP_0 */ +#define WM8995_DCS_TRIG_DAC_WR_3 0x0008 /* DCS_TRIG_DAC_WR_3 */ +#define WM8995_DCS_TRIG_DAC_WR_3_MASK 0x0008 /* DCS_TRIG_DAC_WR_3 */ +#define WM8995_DCS_TRIG_DAC_WR_3_SHIFT 3 /* DCS_TRIG_DAC_WR_3 */ +#define WM8995_DCS_TRIG_DAC_WR_3_WIDTH 1 /* DCS_TRIG_DAC_WR_3 */ +#define WM8995_DCS_TRIG_DAC_WR_2 0x0004 /* DCS_TRIG_DAC_WR_2 */ +#define WM8995_DCS_TRIG_DAC_WR_2_MASK 0x0004 /* DCS_TRIG_DAC_WR_2 */ +#define WM8995_DCS_TRIG_DAC_WR_2_SHIFT 2 /* DCS_TRIG_DAC_WR_2 */ +#define WM8995_DCS_TRIG_DAC_WR_2_WIDTH 1 /* DCS_TRIG_DAC_WR_2 */ +#define WM8995_DCS_TRIG_DAC_WR_1 0x0002 /* DCS_TRIG_DAC_WR_1 */ +#define WM8995_DCS_TRIG_DAC_WR_1_MASK 0x0002 /* DCS_TRIG_DAC_WR_1 */ +#define WM8995_DCS_TRIG_DAC_WR_1_SHIFT 1 /* DCS_TRIG_DAC_WR_1 */ +#define WM8995_DCS_TRIG_DAC_WR_1_WIDTH 1 /* DCS_TRIG_DAC_WR_1 */ +#define WM8995_DCS_TRIG_DAC_WR_0 0x0001 /* DCS_TRIG_DAC_WR_0 */ +#define WM8995_DCS_TRIG_DAC_WR_0_MASK 0x0001 /* DCS_TRIG_DAC_WR_0 */ +#define WM8995_DCS_TRIG_DAC_WR_0_SHIFT 0 /* DCS_TRIG_DAC_WR_0 */ +#define WM8995_DCS_TRIG_DAC_WR_0_WIDTH 1 /* DCS_TRIG_DAC_WR_0 */ + +/* + * R82 (0x52) - DC Servo (3) + */ +#define WM8995_DCS_TIMER_PERIOD_23_MASK 0x0F00 /* DCS_TIMER_PERIOD_23 - [11:8] */ +#define WM8995_DCS_TIMER_PERIOD_23_SHIFT 8 /* DCS_TIMER_PERIOD_23 - [11:8] */ +#define WM8995_DCS_TIMER_PERIOD_23_WIDTH 4 /* DCS_TIMER_PERIOD_23 - [11:8] */ +#define WM8995_DCS_TIMER_PERIOD_01_MASK 0x000F /* DCS_TIMER_PERIOD_01 - [3:0] */ +#define WM8995_DCS_TIMER_PERIOD_01_SHIFT 0 /* DCS_TIMER_PERIOD_01 - [3:0] */ +#define WM8995_DCS_TIMER_PERIOD_01_WIDTH 4 /* DCS_TIMER_PERIOD_01 - [3:0] */ + +/* + * R84 (0x54) - DC Servo (5) + */ +#define WM8995_DCS_SERIES_NO_23_MASK 0x7F00 /* DCS_SERIES_NO_23 - [14:8] */ +#define WM8995_DCS_SERIES_NO_23_SHIFT 8 /* DCS_SERIES_NO_23 - [14:8] */ +#define WM8995_DCS_SERIES_NO_23_WIDTH 7 /* DCS_SERIES_NO_23 - [14:8] */ +#define WM8995_DCS_SERIES_NO_01_MASK 0x007F /* DCS_SERIES_NO_01 - [6:0] */ +#define WM8995_DCS_SERIES_NO_01_SHIFT 0 /* DCS_SERIES_NO_01 - [6:0] */ +#define WM8995_DCS_SERIES_NO_01_WIDTH 7 /* DCS_SERIES_NO_01 - [6:0] */ + +/* + * R85 (0x55) - DC Servo (6) + */ +#define WM8995_DCS_DAC_WR_VAL_3_MASK 0xFF00 /* DCS_DAC_WR_VAL_3 - [15:8] */ +#define WM8995_DCS_DAC_WR_VAL_3_SHIFT 8 /* DCS_DAC_WR_VAL_3 - [15:8] */ +#define WM8995_DCS_DAC_WR_VAL_3_WIDTH 8 /* DCS_DAC_WR_VAL_3 - [15:8] */ +#define WM8995_DCS_DAC_WR_VAL_2_MASK 0x00FF /* DCS_DAC_WR_VAL_2 - [7:0] */ +#define WM8995_DCS_DAC_WR_VAL_2_SHIFT 0 /* DCS_DAC_WR_VAL_2 - [7:0] */ +#define WM8995_DCS_DAC_WR_VAL_2_WIDTH 8 /* DCS_DAC_WR_VAL_2 - [7:0] */ + +/* + * R86 (0x56) - DC Servo (7) + */ +#define WM8995_DCS_DAC_WR_VAL_1_MASK 0xFF00 /* DCS_DAC_WR_VAL_1 - [15:8] */ +#define WM8995_DCS_DAC_WR_VAL_1_SHIFT 8 /* DCS_DAC_WR_VAL_1 - [15:8] */ +#define WM8995_DCS_DAC_WR_VAL_1_WIDTH 8 /* DCS_DAC_WR_VAL_1 - [15:8] */ +#define WM8995_DCS_DAC_WR_VAL_0_MASK 0x00FF /* DCS_DAC_WR_VAL_0 - [7:0] */ +#define WM8995_DCS_DAC_WR_VAL_0_SHIFT 0 /* DCS_DAC_WR_VAL_0 - [7:0] */ +#define WM8995_DCS_DAC_WR_VAL_0_WIDTH 8 /* DCS_DAC_WR_VAL_0 - [7:0] */ + +/* + * R87 (0x57) - DC Servo Readback 0 + */ +#define WM8995_DCS_CAL_COMPLETE_MASK 0x0F00 /* DCS_CAL_COMPLETE - [11:8] */ +#define WM8995_DCS_CAL_COMPLETE_SHIFT 8 /* DCS_CAL_COMPLETE - [11:8] */ +#define WM8995_DCS_CAL_COMPLETE_WIDTH 4 /* DCS_CAL_COMPLETE - [11:8] */ +#define WM8995_DCS_DAC_WR_COMPLETE_MASK 0x00F0 /* DCS_DAC_WR_COMPLETE - [7:4] */ +#define WM8995_DCS_DAC_WR_COMPLETE_SHIFT 4 /* DCS_DAC_WR_COMPLETE - [7:4] */ +#define WM8995_DCS_DAC_WR_COMPLETE_WIDTH 4 /* DCS_DAC_WR_COMPLETE - [7:4] */ +#define WM8995_DCS_STARTUP_COMPLETE_MASK 0x000F /* DCS_STARTUP_COMPLETE - [3:0] */ +#define WM8995_DCS_STARTUP_COMPLETE_SHIFT 0 /* DCS_STARTUP_COMPLETE - [3:0] */ +#define WM8995_DCS_STARTUP_COMPLETE_WIDTH 4 /* DCS_STARTUP_COMPLETE - [3:0] */ + +/* + * R96 (0x60) - Analogue HP (1) + */ +#define WM8995_HPOUT1L_RMV_SHORT 0x0080 /* HPOUT1L_RMV_SHORT */ +#define WM8995_HPOUT1L_RMV_SHORT_MASK 0x0080 /* HPOUT1L_RMV_SHORT */ +#define WM8995_HPOUT1L_RMV_SHORT_SHIFT 7 /* HPOUT1L_RMV_SHORT */ +#define WM8995_HPOUT1L_RMV_SHORT_WIDTH 1 /* HPOUT1L_RMV_SHORT */ +#define WM8995_HPOUT1L_OUTP 0x0040 /* HPOUT1L_OUTP */ +#define WM8995_HPOUT1L_OUTP_MASK 0x0040 /* HPOUT1L_OUTP */ +#define WM8995_HPOUT1L_OUTP_SHIFT 6 /* HPOUT1L_OUTP */ +#define WM8995_HPOUT1L_OUTP_WIDTH 1 /* HPOUT1L_OUTP */ +#define WM8995_HPOUT1L_DLY 0x0020 /* HPOUT1L_DLY */ +#define WM8995_HPOUT1L_DLY_MASK 0x0020 /* HPOUT1L_DLY */ +#define WM8995_HPOUT1L_DLY_SHIFT 5 /* HPOUT1L_DLY */ +#define WM8995_HPOUT1L_DLY_WIDTH 1 /* HPOUT1L_DLY */ +#define WM8995_HPOUT1R_RMV_SHORT 0x0008 /* HPOUT1R_RMV_SHORT */ +#define WM8995_HPOUT1R_RMV_SHORT_MASK 0x0008 /* HPOUT1R_RMV_SHORT */ +#define WM8995_HPOUT1R_RMV_SHORT_SHIFT 3 /* HPOUT1R_RMV_SHORT */ +#define WM8995_HPOUT1R_RMV_SHORT_WIDTH 1 /* HPOUT1R_RMV_SHORT */ +#define WM8995_HPOUT1R_OUTP 0x0004 /* HPOUT1R_OUTP */ +#define WM8995_HPOUT1R_OUTP_MASK 0x0004 /* HPOUT1R_OUTP */ +#define WM8995_HPOUT1R_OUTP_SHIFT 2 /* HPOUT1R_OUTP */ +#define WM8995_HPOUT1R_OUTP_WIDTH 1 /* HPOUT1R_OUTP */ +#define WM8995_HPOUT1R_DLY 0x0002 /* HPOUT1R_DLY */ +#define WM8995_HPOUT1R_DLY_MASK 0x0002 /* HPOUT1R_DLY */ +#define WM8995_HPOUT1R_DLY_SHIFT 1 /* HPOUT1R_DLY */ +#define WM8995_HPOUT1R_DLY_WIDTH 1 /* HPOUT1R_DLY */ + +/* + * R97 (0x61) - Analogue HP (2) + */ +#define WM8995_HPOUT2L_RMV_SHORT 0x0080 /* HPOUT2L_RMV_SHORT */ +#define WM8995_HPOUT2L_RMV_SHORT_MASK 0x0080 /* HPOUT2L_RMV_SHORT */ +#define WM8995_HPOUT2L_RMV_SHORT_SHIFT 7 /* HPOUT2L_RMV_SHORT */ +#define WM8995_HPOUT2L_RMV_SHORT_WIDTH 1 /* HPOUT2L_RMV_SHORT */ +#define WM8995_HPOUT2L_OUTP 0x0040 /* HPOUT2L_OUTP */ +#define WM8995_HPOUT2L_OUTP_MASK 0x0040 /* HPOUT2L_OUTP */ +#define WM8995_HPOUT2L_OUTP_SHIFT 6 /* HPOUT2L_OUTP */ +#define WM8995_HPOUT2L_OUTP_WIDTH 1 /* HPOUT2L_OUTP */ +#define WM8995_HPOUT2L_DLY 0x0020 /* HPOUT2L_DLY */ +#define WM8995_HPOUT2L_DLY_MASK 0x0020 /* HPOUT2L_DLY */ +#define WM8995_HPOUT2L_DLY_SHIFT 5 /* HPOUT2L_DLY */ +#define WM8995_HPOUT2L_DLY_WIDTH 1 /* HPOUT2L_DLY */ +#define WM8995_HPOUT2R_RMV_SHORT 0x0008 /* HPOUT2R_RMV_SHORT */ +#define WM8995_HPOUT2R_RMV_SHORT_MASK 0x0008 /* HPOUT2R_RMV_SHORT */ +#define WM8995_HPOUT2R_RMV_SHORT_SHIFT 3 /* HPOUT2R_RMV_SHORT */ +#define WM8995_HPOUT2R_RMV_SHORT_WIDTH 1 /* HPOUT2R_RMV_SHORT */ +#define WM8995_HPOUT2R_OUTP 0x0004 /* HPOUT2R_OUTP */ +#define WM8995_HPOUT2R_OUTP_MASK 0x0004 /* HPOUT2R_OUTP */ +#define WM8995_HPOUT2R_OUTP_SHIFT 2 /* HPOUT2R_OUTP */ +#define WM8995_HPOUT2R_OUTP_WIDTH 1 /* HPOUT2R_OUTP */ +#define WM8995_HPOUT2R_DLY 0x0002 /* HPOUT2R_DLY */ +#define WM8995_HPOUT2R_DLY_MASK 0x0002 /* HPOUT2R_DLY */ +#define WM8995_HPOUT2R_DLY_SHIFT 1 /* HPOUT2R_DLY */ +#define WM8995_HPOUT2R_DLY_WIDTH 1 /* HPOUT2R_DLY */ + +/* + * R256 (0x100) - Chip Revision + */ +#define WM8995_CHIP_REV_MASK 0x000F /* CHIP_REV - [3:0] */ +#define WM8995_CHIP_REV_SHIFT 0 /* CHIP_REV - [3:0] */ +#define WM8995_CHIP_REV_WIDTH 4 /* CHIP_REV - [3:0] */ + +/* + * R257 (0x101) - Control Interface (1) + */ +#define WM8995_REG_SYNC 0x8000 /* REG_SYNC */ +#define WM8995_REG_SYNC_MASK 0x8000 /* REG_SYNC */ +#define WM8995_REG_SYNC_SHIFT 15 /* REG_SYNC */ +#define WM8995_REG_SYNC_WIDTH 1 /* REG_SYNC */ +#define WM8995_SPI_CONTRD 0x0040 /* SPI_CONTRD */ +#define WM8995_SPI_CONTRD_MASK 0x0040 /* SPI_CONTRD */ +#define WM8995_SPI_CONTRD_SHIFT 6 /* SPI_CONTRD */ +#define WM8995_SPI_CONTRD_WIDTH 1 /* SPI_CONTRD */ +#define WM8995_SPI_4WIRE 0x0020 /* SPI_4WIRE */ +#define WM8995_SPI_4WIRE_MASK 0x0020 /* SPI_4WIRE */ +#define WM8995_SPI_4WIRE_SHIFT 5 /* SPI_4WIRE */ +#define WM8995_SPI_4WIRE_WIDTH 1 /* SPI_4WIRE */ +#define WM8995_SPI_CFG 0x0010 /* SPI_CFG */ +#define WM8995_SPI_CFG_MASK 0x0010 /* SPI_CFG */ +#define WM8995_SPI_CFG_SHIFT 4 /* SPI_CFG */ +#define WM8995_SPI_CFG_WIDTH 1 /* SPI_CFG */ +#define WM8995_AUTO_INC 0x0004 /* AUTO_INC */ +#define WM8995_AUTO_INC_MASK 0x0004 /* AUTO_INC */ +#define WM8995_AUTO_INC_SHIFT 2 /* AUTO_INC */ +#define WM8995_AUTO_INC_WIDTH 1 /* AUTO_INC */ + +/* + * R258 (0x102) - Control Interface (2) + */ +#define WM8995_CTRL_IF_SRC 0x0001 /* CTRL_IF_SRC */ +#define WM8995_CTRL_IF_SRC_MASK 0x0001 /* CTRL_IF_SRC */ +#define WM8995_CTRL_IF_SRC_SHIFT 0 /* CTRL_IF_SRC */ +#define WM8995_CTRL_IF_SRC_WIDTH 1 /* CTRL_IF_SRC */ + +/* + * R272 (0x110) - Write Sequencer Ctrl (1) + */ +#define WM8995_WSEQ_ENA 0x8000 /* WSEQ_ENA */ +#define WM8995_WSEQ_ENA_MASK 0x8000 /* WSEQ_ENA */ +#define WM8995_WSEQ_ENA_SHIFT 15 /* WSEQ_ENA */ +#define WM8995_WSEQ_ENA_WIDTH 1 /* WSEQ_ENA */ +#define WM8995_WSEQ_ABORT 0x0200 /* WSEQ_ABORT */ +#define WM8995_WSEQ_ABORT_MASK 0x0200 /* WSEQ_ABORT */ +#define WM8995_WSEQ_ABORT_SHIFT 9 /* WSEQ_ABORT */ +#define WM8995_WSEQ_ABORT_WIDTH 1 /* WSEQ_ABORT */ +#define WM8995_WSEQ_START 0x0100 /* WSEQ_START */ +#define WM8995_WSEQ_START_MASK 0x0100 /* WSEQ_START */ +#define WM8995_WSEQ_START_SHIFT 8 /* WSEQ_START */ +#define WM8995_WSEQ_START_WIDTH 1 /* WSEQ_START */ +#define WM8995_WSEQ_START_INDEX_MASK 0x007F /* WSEQ_START_INDEX - [6:0] */ +#define WM8995_WSEQ_START_INDEX_SHIFT 0 /* WSEQ_START_INDEX - [6:0] */ +#define WM8995_WSEQ_START_INDEX_WIDTH 7 /* WSEQ_START_INDEX - [6:0] */ + +/* + * R273 (0x111) - Write Sequencer Ctrl (2) + */ +#define WM8995_WSEQ_BUSY 0x0100 /* WSEQ_BUSY */ +#define WM8995_WSEQ_BUSY_MASK 0x0100 /* WSEQ_BUSY */ +#define WM8995_WSEQ_BUSY_SHIFT 8 /* WSEQ_BUSY */ +#define WM8995_WSEQ_BUSY_WIDTH 1 /* WSEQ_BUSY */ +#define WM8995_WSEQ_CURRENT_INDEX_MASK 0x007F /* WSEQ_CURRENT_INDEX - [6:0] */ +#define WM8995_WSEQ_CURRENT_INDEX_SHIFT 0 /* WSEQ_CURRENT_INDEX - [6:0] */ +#define WM8995_WSEQ_CURRENT_INDEX_WIDTH 7 /* WSEQ_CURRENT_INDEX - [6:0] */ + +/* + * R512 (0x200) - AIF1 Clocking (1) + */ +#define WM8995_AIF1CLK_SRC_MASK 0x0018 /* AIF1CLK_SRC - [4:3] */ +#define WM8995_AIF1CLK_SRC_SHIFT 3 /* AIF1CLK_SRC - [4:3] */ +#define WM8995_AIF1CLK_SRC_WIDTH 2 /* AIF1CLK_SRC - [4:3] */ +#define WM8995_AIF1CLK_INV 0x0004 /* AIF1CLK_INV */ +#define WM8995_AIF1CLK_INV_MASK 0x0004 /* AIF1CLK_INV */ +#define WM8995_AIF1CLK_INV_SHIFT 2 /* AIF1CLK_INV */ +#define WM8995_AIF1CLK_INV_WIDTH 1 /* AIF1CLK_INV */ +#define WM8995_AIF1CLK_DIV 0x0002 /* AIF1CLK_DIV */ +#define WM8995_AIF1CLK_DIV_MASK 0x0002 /* AIF1CLK_DIV */ +#define WM8995_AIF1CLK_DIV_SHIFT 1 /* AIF1CLK_DIV */ +#define WM8995_AIF1CLK_DIV_WIDTH 1 /* AIF1CLK_DIV */ +#define WM8995_AIF1CLK_ENA 0x0001 /* AIF1CLK_ENA */ +#define WM8995_AIF1CLK_ENA_MASK 0x0001 /* AIF1CLK_ENA */ +#define WM8995_AIF1CLK_ENA_SHIFT 0 /* AIF1CLK_ENA */ +#define WM8995_AIF1CLK_ENA_WIDTH 1 /* AIF1CLK_ENA */ + +/* + * R513 (0x201) - AIF1 Clocking (2) + */ +#define WM8995_AIF1DAC_DIV_MASK 0x0038 /* AIF1DAC_DIV - [5:3] */ +#define WM8995_AIF1DAC_DIV_SHIFT 3 /* AIF1DAC_DIV - [5:3] */ +#define WM8995_AIF1DAC_DIV_WIDTH 3 /* AIF1DAC_DIV - [5:3] */ +#define WM8995_AIF1ADC_DIV_MASK 0x0007 /* AIF1ADC_DIV - [2:0] */ +#define WM8995_AIF1ADC_DIV_SHIFT 0 /* AIF1ADC_DIV - [2:0] */ +#define WM8995_AIF1ADC_DIV_WIDTH 3 /* AIF1ADC_DIV - [2:0] */ + +/* + * R516 (0x204) - AIF2 Clocking (1) + */ +#define WM8995_AIF2CLK_SRC_MASK 0x0018 /* AIF2CLK_SRC - [4:3] */ +#define WM8995_AIF2CLK_SRC_SHIFT 3 /* AIF2CLK_SRC - [4:3] */ +#define WM8995_AIF2CLK_SRC_WIDTH 2 /* AIF2CLK_SRC - [4:3] */ +#define WM8995_AIF2CLK_INV 0x0004 /* AIF2CLK_INV */ +#define WM8995_AIF2CLK_INV_MASK 0x0004 /* AIF2CLK_INV */ +#define WM8995_AIF2CLK_INV_SHIFT 2 /* AIF2CLK_INV */ +#define WM8995_AIF2CLK_INV_WIDTH 1 /* AIF2CLK_INV */ +#define WM8995_AIF2CLK_DIV 0x0002 /* AIF2CLK_DIV */ +#define WM8995_AIF2CLK_DIV_MASK 0x0002 /* AIF2CLK_DIV */ +#define WM8995_AIF2CLK_DIV_SHIFT 1 /* AIF2CLK_DIV */ +#define WM8995_AIF2CLK_DIV_WIDTH 1 /* AIF2CLK_DIV */ +#define WM8995_AIF2CLK_ENA 0x0001 /* AIF2CLK_ENA */ +#define WM8995_AIF2CLK_ENA_MASK 0x0001 /* AIF2CLK_ENA */ +#define WM8995_AIF2CLK_ENA_SHIFT 0 /* AIF2CLK_ENA */ +#define WM8995_AIF2CLK_ENA_WIDTH 1 /* AIF2CLK_ENA */ + +/* + * R517 (0x205) - AIF2 Clocking (2) + */ +#define WM8995_AIF2DAC_DIV_MASK 0x0038 /* AIF2DAC_DIV - [5:3] */ +#define WM8995_AIF2DAC_DIV_SHIFT 3 /* AIF2DAC_DIV - [5:3] */ +#define WM8995_AIF2DAC_DIV_WIDTH 3 /* AIF2DAC_DIV - [5:3] */ +#define WM8995_AIF2ADC_DIV_MASK 0x0007 /* AIF2ADC_DIV - [2:0] */ +#define WM8995_AIF2ADC_DIV_SHIFT 0 /* AIF2ADC_DIV - [2:0] */ +#define WM8995_AIF2ADC_DIV_WIDTH 3 /* AIF2ADC_DIV - [2:0] */ + +/* + * R520 (0x208) - Clocking (1) + */ +#define WM8995_LFCLK_ENA 0x0020 /* LFCLK_ENA */ +#define WM8995_LFCLK_ENA_MASK 0x0020 /* LFCLK_ENA */ +#define WM8995_LFCLK_ENA_SHIFT 5 /* LFCLK_ENA */ +#define WM8995_LFCLK_ENA_WIDTH 1 /* LFCLK_ENA */ +#define WM8995_TOCLK_ENA 0x0010 /* TOCLK_ENA */ +#define WM8995_TOCLK_ENA_MASK 0x0010 /* TOCLK_ENA */ +#define WM8995_TOCLK_ENA_SHIFT 4 /* TOCLK_ENA */ +#define WM8995_TOCLK_ENA_WIDTH 1 /* TOCLK_ENA */ +#define WM8995_AIF1DSPCLK_ENA 0x0008 /* AIF1DSPCLK_ENA */ +#define WM8995_AIF1DSPCLK_ENA_MASK 0x0008 /* AIF1DSPCLK_ENA */ +#define WM8995_AIF1DSPCLK_ENA_SHIFT 3 /* AIF1DSPCLK_ENA */ +#define WM8995_AIF1DSPCLK_ENA_WIDTH 1 /* AIF1DSPCLK_ENA */ +#define WM8995_AIF2DSPCLK_ENA 0x0004 /* AIF2DSPCLK_ENA */ +#define WM8995_AIF2DSPCLK_ENA_MASK 0x0004 /* AIF2DSPCLK_ENA */ +#define WM8995_AIF2DSPCLK_ENA_SHIFT 2 /* AIF2DSPCLK_ENA */ +#define WM8995_AIF2DSPCLK_ENA_WIDTH 1 /* AIF2DSPCLK_ENA */ +#define WM8995_SYSDSPCLK_ENA 0x0002 /* SYSDSPCLK_ENA */ +#define WM8995_SYSDSPCLK_ENA_MASK 0x0002 /* SYSDSPCLK_ENA */ +#define WM8995_SYSDSPCLK_ENA_SHIFT 1 /* SYSDSPCLK_ENA */ +#define WM8995_SYSDSPCLK_ENA_WIDTH 1 /* SYSDSPCLK_ENA */ +#define WM8995_SYSCLK_SRC 0x0001 /* SYSCLK_SRC */ +#define WM8995_SYSCLK_SRC_MASK 0x0001 /* SYSCLK_SRC */ +#define WM8995_SYSCLK_SRC_SHIFT 0 /* SYSCLK_SRC */ +#define WM8995_SYSCLK_SRC_WIDTH 1 /* SYSCLK_SRC */ + +/* + * R521 (0x209) - Clocking (2) + */ +#define WM8995_TOCLK_DIV_MASK 0x0700 /* TOCLK_DIV - [10:8] */ +#define WM8995_TOCLK_DIV_SHIFT 8 /* TOCLK_DIV - [10:8] */ +#define WM8995_TOCLK_DIV_WIDTH 3 /* TOCLK_DIV - [10:8] */ +#define WM8995_DBCLK_DIV_MASK 0x00F0 /* DBCLK_DIV - [7:4] */ +#define WM8995_DBCLK_DIV_SHIFT 4 /* DBCLK_DIV - [7:4] */ +#define WM8995_DBCLK_DIV_WIDTH 4 /* DBCLK_DIV - [7:4] */ +#define WM8995_OPCLK_DIV_MASK 0x0007 /* OPCLK_DIV - [2:0] */ +#define WM8995_OPCLK_DIV_SHIFT 0 /* OPCLK_DIV - [2:0] */ +#define WM8995_OPCLK_DIV_WIDTH 3 /* OPCLK_DIV - [2:0] */ + +/* + * R528 (0x210) - AIF1 Rate + */ +#define WM8995_AIF1_SR_MASK 0x00F0 /* AIF1_SR - [7:4] */ +#define WM8995_AIF1_SR_SHIFT 4 /* AIF1_SR - [7:4] */ +#define WM8995_AIF1_SR_WIDTH 4 /* AIF1_SR - [7:4] */ +#define WM8995_AIF1CLK_RATE_MASK 0x000F /* AIF1CLK_RATE - [3:0] */ +#define WM8995_AIF1CLK_RATE_SHIFT 0 /* AIF1CLK_RATE - [3:0] */ +#define WM8995_AIF1CLK_RATE_WIDTH 4 /* AIF1CLK_RATE - [3:0] */ + +/* + * R529 (0x211) - AIF2 Rate + */ +#define WM8995_AIF2_SR_MASK 0x00F0 /* AIF2_SR - [7:4] */ +#define WM8995_AIF2_SR_SHIFT 4 /* AIF2_SR - [7:4] */ +#define WM8995_AIF2_SR_WIDTH 4 /* AIF2_SR - [7:4] */ +#define WM8995_AIF2CLK_RATE_MASK 0x000F /* AIF2CLK_RATE - [3:0] */ +#define WM8995_AIF2CLK_RATE_SHIFT 0 /* AIF2CLK_RATE - [3:0] */ +#define WM8995_AIF2CLK_RATE_WIDTH 4 /* AIF2CLK_RATE - [3:0] */ + +/* + * R530 (0x212) - Rate Status + */ +#define WM8995_SR_ERROR_MASK 0x000F /* SR_ERROR - [3:0] */ +#define WM8995_SR_ERROR_SHIFT 0 /* SR_ERROR - [3:0] */ +#define WM8995_SR_ERROR_WIDTH 4 /* SR_ERROR - [3:0] */ + +/* + * R544 (0x220) - FLL1 Control (1) + */ +#define WM8995_FLL1_OSC_ENA 0x0002 /* FLL1_OSC_ENA */ +#define WM8995_FLL1_OSC_ENA_MASK 0x0002 /* FLL1_OSC_ENA */ +#define WM8995_FLL1_OSC_ENA_SHIFT 1 /* FLL1_OSC_ENA */ +#define WM8995_FLL1_OSC_ENA_WIDTH 1 /* FLL1_OSC_ENA */ +#define WM8995_FLL1_ENA 0x0001 /* FLL1_ENA */ +#define WM8995_FLL1_ENA_MASK 0x0001 /* FLL1_ENA */ +#define WM8995_FLL1_ENA_SHIFT 0 /* FLL1_ENA */ +#define WM8995_FLL1_ENA_WIDTH 1 /* FLL1_ENA */ + +/* + * R545 (0x221) - FLL1 Control (2) + */ +#define WM8995_FLL1_OUTDIV_MASK 0x3F00 /* FLL1_OUTDIV - [13:8] */ +#define WM8995_FLL1_OUTDIV_SHIFT 8 /* FLL1_OUTDIV - [13:8] */ +#define WM8995_FLL1_OUTDIV_WIDTH 6 /* FLL1_OUTDIV - [13:8] */ +#define WM8995_FLL1_CTRL_RATE_MASK 0x0070 /* FLL1_CTRL_RATE - [6:4] */ +#define WM8995_FLL1_CTRL_RATE_SHIFT 4 /* FLL1_CTRL_RATE - [6:4] */ +#define WM8995_FLL1_CTRL_RATE_WIDTH 3 /* FLL1_CTRL_RATE - [6:4] */ +#define WM8995_FLL1_FRATIO_MASK 0x0007 /* FLL1_FRATIO - [2:0] */ +#define WM8995_FLL1_FRATIO_SHIFT 0 /* FLL1_FRATIO - [2:0] */ +#define WM8995_FLL1_FRATIO_WIDTH 3 /* FLL1_FRATIO - [2:0] */ + +/* + * R546 (0x222) - FLL1 Control (3) + */ +#define WM8995_FLL1_K_MASK 0xFFFF /* FLL1_K - [15:0] */ +#define WM8995_FLL1_K_SHIFT 0 /* FLL1_K - [15:0] */ +#define WM8995_FLL1_K_WIDTH 16 /* FLL1_K - [15:0] */ + +/* + * R547 (0x223) - FLL1 Control (4) + */ +#define WM8995_FLL1_N_MASK 0x7FE0 /* FLL1_N - [14:5] */ +#define WM8995_FLL1_N_SHIFT 5 /* FLL1_N - [14:5] */ +#define WM8995_FLL1_N_WIDTH 10 /* FLL1_N - [14:5] */ +#define WM8995_FLL1_LOOP_GAIN_MASK 0x000F /* FLL1_LOOP_GAIN - [3:0] */ +#define WM8995_FLL1_LOOP_GAIN_SHIFT 0 /* FLL1_LOOP_GAIN - [3:0] */ +#define WM8995_FLL1_LOOP_GAIN_WIDTH 4 /* FLL1_LOOP_GAIN - [3:0] */ + +/* + * R548 (0x224) - FLL1 Control (5) + */ +#define WM8995_FLL1_FRC_NCO_VAL_MASK 0x1F80 /* FLL1_FRC_NCO_VAL - [12:7] */ +#define WM8995_FLL1_FRC_NCO_VAL_SHIFT 7 /* FLL1_FRC_NCO_VAL - [12:7] */ +#define WM8995_FLL1_FRC_NCO_VAL_WIDTH 6 /* FLL1_FRC_NCO_VAL - [12:7] */ +#define WM8995_FLL1_FRC_NCO 0x0040 /* FLL1_FRC_NCO */ +#define WM8995_FLL1_FRC_NCO_MASK 0x0040 /* FLL1_FRC_NCO */ +#define WM8995_FLL1_FRC_NCO_SHIFT 6 /* FLL1_FRC_NCO */ +#define WM8995_FLL1_FRC_NCO_WIDTH 1 /* FLL1_FRC_NCO */ +#define WM8995_FLL1_REFCLK_DIV_MASK 0x0018 /* FLL1_REFCLK_DIV - [4:3] */ +#define WM8995_FLL1_REFCLK_DIV_SHIFT 3 /* FLL1_REFCLK_DIV - [4:3] */ +#define WM8995_FLL1_REFCLK_DIV_WIDTH 2 /* FLL1_REFCLK_DIV - [4:3] */ +#define WM8995_FLL1_REFCLK_SRC_MASK 0x0003 /* FLL1_REFCLK_SRC - [1:0] */ +#define WM8995_FLL1_REFCLK_SRC_SHIFT 0 /* FLL1_REFCLK_SRC - [1:0] */ +#define WM8995_FLL1_REFCLK_SRC_WIDTH 2 /* FLL1_REFCLK_SRC - [1:0] */ + +/* + * R576 (0x240) - FLL2 Control (1) + */ +#define WM8995_FLL2_OSC_ENA 0x0002 /* FLL2_OSC_ENA */ +#define WM8995_FLL2_OSC_ENA_MASK 0x0002 /* FLL2_OSC_ENA */ +#define WM8995_FLL2_OSC_ENA_SHIFT 1 /* FLL2_OSC_ENA */ +#define WM8995_FLL2_OSC_ENA_WIDTH 1 /* FLL2_OSC_ENA */ +#define WM8995_FLL2_ENA 0x0001 /* FLL2_ENA */ +#define WM8995_FLL2_ENA_MASK 0x0001 /* FLL2_ENA */ +#define WM8995_FLL2_ENA_SHIFT 0 /* FLL2_ENA */ +#define WM8995_FLL2_ENA_WIDTH 1 /* FLL2_ENA */ + +/* + * R577 (0x241) - FLL2 Control (2) + */ +#define WM8995_FLL2_OUTDIV_MASK 0x3F00 /* FLL2_OUTDIV - [13:8] */ +#define WM8995_FLL2_OUTDIV_SHIFT 8 /* FLL2_OUTDIV - [13:8] */ +#define WM8995_FLL2_OUTDIV_WIDTH 6 /* FLL2_OUTDIV - [13:8] */ +#define WM8995_FLL2_CTRL_RATE_MASK 0x0070 /* FLL2_CTRL_RATE - [6:4] */ +#define WM8995_FLL2_CTRL_RATE_SHIFT 4 /* FLL2_CTRL_RATE - [6:4] */ +#define WM8995_FLL2_CTRL_RATE_WIDTH 3 /* FLL2_CTRL_RATE - [6:4] */ +#define WM8995_FLL2_FRATIO_MASK 0x0007 /* FLL2_FRATIO - [2:0] */ +#define WM8995_FLL2_FRATIO_SHIFT 0 /* FLL2_FRATIO - [2:0] */ +#define WM8995_FLL2_FRATIO_WIDTH 3 /* FLL2_FRATIO - [2:0] */ + +/* + * R578 (0x242) - FLL2 Control (3) + */ +#define WM8995_FLL2_K_MASK 0xFFFF /* FLL2_K - [15:0] */ +#define WM8995_FLL2_K_SHIFT 0 /* FLL2_K - [15:0] */ +#define WM8995_FLL2_K_WIDTH 16 /* FLL2_K - [15:0] */ + +/* + * R579 (0x243) - FLL2 Control (4) + */ +#define WM8995_FLL2_N_MASK 0x7FE0 /* FLL2_N - [14:5] */ +#define WM8995_FLL2_N_SHIFT 5 /* FLL2_N - [14:5] */ +#define WM8995_FLL2_N_WIDTH 10 /* FLL2_N - [14:5] */ +#define WM8995_FLL2_LOOP_GAIN_MASK 0x000F /* FLL2_LOOP_GAIN - [3:0] */ +#define WM8995_FLL2_LOOP_GAIN_SHIFT 0 /* FLL2_LOOP_GAIN - [3:0] */ +#define WM8995_FLL2_LOOP_GAIN_WIDTH 4 /* FLL2_LOOP_GAIN - [3:0] */ + +/* + * R580 (0x244) - FLL2 Control (5) + */ +#define WM8995_FLL2_FRC_NCO_VAL_MASK 0x1F80 /* FLL2_FRC_NCO_VAL - [12:7] */ +#define WM8995_FLL2_FRC_NCO_VAL_SHIFT 7 /* FLL2_FRC_NCO_VAL - [12:7] */ +#define WM8995_FLL2_FRC_NCO_VAL_WIDTH 6 /* FLL2_FRC_NCO_VAL - [12:7] */ +#define WM8995_FLL2_FRC_NCO 0x0040 /* FLL2_FRC_NCO */ +#define WM8995_FLL2_FRC_NCO_MASK 0x0040 /* FLL2_FRC_NCO */ +#define WM8995_FLL2_FRC_NCO_SHIFT 6 /* FLL2_FRC_NCO */ +#define WM8995_FLL2_FRC_NCO_WIDTH 1 /* FLL2_FRC_NCO */ +#define WM8995_FLL2_REFCLK_DIV_MASK 0x0018 /* FLL2_REFCLK_DIV - [4:3] */ +#define WM8995_FLL2_REFCLK_DIV_SHIFT 3 /* FLL2_REFCLK_DIV - [4:3] */ +#define WM8995_FLL2_REFCLK_DIV_WIDTH 2 /* FLL2_REFCLK_DIV - [4:3] */ +#define WM8995_FLL2_REFCLK_SRC_MASK 0x0003 /* FLL2_REFCLK_SRC - [1:0] */ +#define WM8995_FLL2_REFCLK_SRC_SHIFT 0 /* FLL2_REFCLK_SRC - [1:0] */ +#define WM8995_FLL2_REFCLK_SRC_WIDTH 2 /* FLL2_REFCLK_SRC - [1:0] */ + +/* + * R768 (0x300) - AIF1 Control (1) + */ +#define WM8995_AIF1ADCL_SRC 0x8000 /* AIF1ADCL_SRC */ +#define WM8995_AIF1ADCL_SRC_MASK 0x8000 /* AIF1ADCL_SRC */ +#define WM8995_AIF1ADCL_SRC_SHIFT 15 /* AIF1ADCL_SRC */ +#define WM8995_AIF1ADCL_SRC_WIDTH 1 /* AIF1ADCL_SRC */ +#define WM8995_AIF1ADCR_SRC 0x4000 /* AIF1ADCR_SRC */ +#define WM8995_AIF1ADCR_SRC_MASK 0x4000 /* AIF1ADCR_SRC */ +#define WM8995_AIF1ADCR_SRC_SHIFT 14 /* AIF1ADCR_SRC */ +#define WM8995_AIF1ADCR_SRC_WIDTH 1 /* AIF1ADCR_SRC */ +#define WM8995_AIF1ADC_TDM 0x2000 /* AIF1ADC_TDM */ +#define WM8995_AIF1ADC_TDM_MASK 0x2000 /* AIF1ADC_TDM */ +#define WM8995_AIF1ADC_TDM_SHIFT 13 /* AIF1ADC_TDM */ +#define WM8995_AIF1ADC_TDM_WIDTH 1 /* AIF1ADC_TDM */ +#define WM8995_AIF1_BCLK_INV 0x0100 /* AIF1_BCLK_INV */ +#define WM8995_AIF1_BCLK_INV_MASK 0x0100 /* AIF1_BCLK_INV */ +#define WM8995_AIF1_BCLK_INV_SHIFT 8 /* AIF1_BCLK_INV */ +#define WM8995_AIF1_BCLK_INV_WIDTH 1 /* AIF1_BCLK_INV */ +#define WM8995_AIF1_LRCLK_INV 0x0080 /* AIF1_LRCLK_INV */ +#define WM8995_AIF1_LRCLK_INV_MASK 0x0080 /* AIF1_LRCLK_INV */ +#define WM8995_AIF1_LRCLK_INV_SHIFT 7 /* AIF1_LRCLK_INV */ +#define WM8995_AIF1_LRCLK_INV_WIDTH 1 /* AIF1_LRCLK_INV */ +#define WM8995_AIF1_WL_MASK 0x0060 /* AIF1_WL - [6:5] */ +#define WM8995_AIF1_WL_SHIFT 5 /* AIF1_WL - [6:5] */ +#define WM8995_AIF1_WL_WIDTH 2 /* AIF1_WL - [6:5] */ +#define WM8995_AIF1_FMT_MASK 0x0018 /* AIF1_FMT - [4:3] */ +#define WM8995_AIF1_FMT_SHIFT 3 /* AIF1_FMT - [4:3] */ +#define WM8995_AIF1_FMT_WIDTH 2 /* AIF1_FMT - [4:3] */ + +/* + * R769 (0x301) - AIF1 Control (2) + */ +#define WM8995_AIF1DACL_SRC 0x8000 /* AIF1DACL_SRC */ +#define WM8995_AIF1DACL_SRC_MASK 0x8000 /* AIF1DACL_SRC */ +#define WM8995_AIF1DACL_SRC_SHIFT 15 /* AIF1DACL_SRC */ +#define WM8995_AIF1DACL_SRC_WIDTH 1 /* AIF1DACL_SRC */ +#define WM8995_AIF1DACR_SRC 0x4000 /* AIF1DACR_SRC */ +#define WM8995_AIF1DACR_SRC_MASK 0x4000 /* AIF1DACR_SRC */ +#define WM8995_AIF1DACR_SRC_SHIFT 14 /* AIF1DACR_SRC */ +#define WM8995_AIF1DACR_SRC_WIDTH 1 /* AIF1DACR_SRC */ +#define WM8995_AIF1DAC_BOOST_MASK 0x0C00 /* AIF1DAC_BOOST - [11:10] */ +#define WM8995_AIF1DAC_BOOST_SHIFT 10 /* AIF1DAC_BOOST - [11:10] */ +#define WM8995_AIF1DAC_BOOST_WIDTH 2 /* AIF1DAC_BOOST - [11:10] */ +#define WM8995_AIF1DAC_COMP 0x0010 /* AIF1DAC_COMP */ +#define WM8995_AIF1DAC_COMP_MASK 0x0010 /* AIF1DAC_COMP */ +#define WM8995_AIF1DAC_COMP_SHIFT 4 /* AIF1DAC_COMP */ +#define WM8995_AIF1DAC_COMP_WIDTH 1 /* AIF1DAC_COMP */ +#define WM8995_AIF1DAC_COMPMODE 0x0008 /* AIF1DAC_COMPMODE */ +#define WM8995_AIF1DAC_COMPMODE_MASK 0x0008 /* AIF1DAC_COMPMODE */ +#define WM8995_AIF1DAC_COMPMODE_SHIFT 3 /* AIF1DAC_COMPMODE */ +#define WM8995_AIF1DAC_COMPMODE_WIDTH 1 /* AIF1DAC_COMPMODE */ +#define WM8995_AIF1ADC_COMP 0x0004 /* AIF1ADC_COMP */ +#define WM8995_AIF1ADC_COMP_MASK 0x0004 /* AIF1ADC_COMP */ +#define WM8995_AIF1ADC_COMP_SHIFT 2 /* AIF1ADC_COMP */ +#define WM8995_AIF1ADC_COMP_WIDTH 1 /* AIF1ADC_COMP */ +#define WM8995_AIF1ADC_COMPMODE 0x0002 /* AIF1ADC_COMPMODE */ +#define WM8995_AIF1ADC_COMPMODE_MASK 0x0002 /* AIF1ADC_COMPMODE */ +#define WM8995_AIF1ADC_COMPMODE_SHIFT 1 /* AIF1ADC_COMPMODE */ +#define WM8995_AIF1ADC_COMPMODE_WIDTH 1 /* AIF1ADC_COMPMODE */ +#define WM8995_AIF1_LOOPBACK 0x0001 /* AIF1_LOOPBACK */ +#define WM8995_AIF1_LOOPBACK_MASK 0x0001 /* AIF1_LOOPBACK */ +#define WM8995_AIF1_LOOPBACK_SHIFT 0 /* AIF1_LOOPBACK */ +#define WM8995_AIF1_LOOPBACK_WIDTH 1 /* AIF1_LOOPBACK */ + +/* + * R770 (0x302) - AIF1 Master/Slave + */ +#define WM8995_AIF1_TRI 0x8000 /* AIF1_TRI */ +#define WM8995_AIF1_TRI_MASK 0x8000 /* AIF1_TRI */ +#define WM8995_AIF1_TRI_SHIFT 15 /* AIF1_TRI */ +#define WM8995_AIF1_TRI_WIDTH 1 /* AIF1_TRI */ +#define WM8995_AIF1_MSTR 0x4000 /* AIF1_MSTR */ +#define WM8995_AIF1_MSTR_MASK 0x4000 /* AIF1_MSTR */ +#define WM8995_AIF1_MSTR_SHIFT 14 /* AIF1_MSTR */ +#define WM8995_AIF1_MSTR_WIDTH 1 /* AIF1_MSTR */ +#define WM8995_AIF1_CLK_FRC 0x2000 /* AIF1_CLK_FRC */ +#define WM8995_AIF1_CLK_FRC_MASK 0x2000 /* AIF1_CLK_FRC */ +#define WM8995_AIF1_CLK_FRC_SHIFT 13 /* AIF1_CLK_FRC */ +#define WM8995_AIF1_CLK_FRC_WIDTH 1 /* AIF1_CLK_FRC */ +#define WM8995_AIF1_LRCLK_FRC 0x1000 /* AIF1_LRCLK_FRC */ +#define WM8995_AIF1_LRCLK_FRC_MASK 0x1000 /* AIF1_LRCLK_FRC */ +#define WM8995_AIF1_LRCLK_FRC_SHIFT 12 /* AIF1_LRCLK_FRC */ +#define WM8995_AIF1_LRCLK_FRC_WIDTH 1 /* AIF1_LRCLK_FRC */ + +/* + * R771 (0x303) - AIF1 BCLK + */ +#define WM8995_AIF1_BCLK_DIV_MASK 0x00F0 /* AIF1_BCLK_DIV - [7:4] */ +#define WM8995_AIF1_BCLK_DIV_SHIFT 4 /* AIF1_BCLK_DIV - [7:4] */ +#define WM8995_AIF1_BCLK_DIV_WIDTH 4 /* AIF1_BCLK_DIV - [7:4] */ + +/* + * R772 (0x304) - AIF1ADC LRCLK + */ +#define WM8995_AIF1ADC_LRCLK_DIR 0x0800 /* AIF1ADC_LRCLK_DIR */ +#define WM8995_AIF1ADC_LRCLK_DIR_MASK 0x0800 /* AIF1ADC_LRCLK_DIR */ +#define WM8995_AIF1ADC_LRCLK_DIR_SHIFT 11 /* AIF1ADC_LRCLK_DIR */ +#define WM8995_AIF1ADC_LRCLK_DIR_WIDTH 1 /* AIF1ADC_LRCLK_DIR */ +#define WM8995_AIF1ADC_RATE_MASK 0x07FF /* AIF1ADC_RATE - [10:0] */ +#define WM8995_AIF1ADC_RATE_SHIFT 0 /* AIF1ADC_RATE - [10:0] */ +#define WM8995_AIF1ADC_RATE_WIDTH 11 /* AIF1ADC_RATE - [10:0] */ + +/* + * R773 (0x305) - AIF1DAC LRCLK + */ +#define WM8995_AIF1DAC_LRCLK_DIR 0x0800 /* AIF1DAC_LRCLK_DIR */ +#define WM8995_AIF1DAC_LRCLK_DIR_MASK 0x0800 /* AIF1DAC_LRCLK_DIR */ +#define WM8995_AIF1DAC_LRCLK_DIR_SHIFT 11 /* AIF1DAC_LRCLK_DIR */ +#define WM8995_AIF1DAC_LRCLK_DIR_WIDTH 1 /* AIF1DAC_LRCLK_DIR */ +#define WM8995_AIF1DAC_RATE_MASK 0x07FF /* AIF1DAC_RATE - [10:0] */ +#define WM8995_AIF1DAC_RATE_SHIFT 0 /* AIF1DAC_RATE - [10:0] */ +#define WM8995_AIF1DAC_RATE_WIDTH 11 /* AIF1DAC_RATE - [10:0] */ + +/* + * R774 (0x306) - AIF1DAC Data + */ +#define WM8995_AIF1DACL_DAT_INV 0x0002 /* AIF1DACL_DAT_INV */ +#define WM8995_AIF1DACL_DAT_INV_MASK 0x0002 /* AIF1DACL_DAT_INV */ +#define WM8995_AIF1DACL_DAT_INV_SHIFT 1 /* AIF1DACL_DAT_INV */ +#define WM8995_AIF1DACL_DAT_INV_WIDTH 1 /* AIF1DACL_DAT_INV */ +#define WM8995_AIF1DACR_DAT_INV 0x0001 /* AIF1DACR_DAT_INV */ +#define WM8995_AIF1DACR_DAT_INV_MASK 0x0001 /* AIF1DACR_DAT_INV */ +#define WM8995_AIF1DACR_DAT_INV_SHIFT 0 /* AIF1DACR_DAT_INV */ +#define WM8995_AIF1DACR_DAT_INV_WIDTH 1 /* AIF1DACR_DAT_INV */ + +/* + * R775 (0x307) - AIF1ADC Data + */ +#define WM8995_AIF1ADCL_DAT_INV 0x0002 /* AIF1ADCL_DAT_INV */ +#define WM8995_AIF1ADCL_DAT_INV_MASK 0x0002 /* AIF1ADCL_DAT_INV */ +#define WM8995_AIF1ADCL_DAT_INV_SHIFT 1 /* AIF1ADCL_DAT_INV */ +#define WM8995_AIF1ADCL_DAT_INV_WIDTH 1 /* AIF1ADCL_DAT_INV */ +#define WM8995_AIF1ADCR_DAT_INV 0x0001 /* AIF1ADCR_DAT_INV */ +#define WM8995_AIF1ADCR_DAT_INV_MASK 0x0001 /* AIF1ADCR_DAT_INV */ +#define WM8995_AIF1ADCR_DAT_INV_SHIFT 0 /* AIF1ADCR_DAT_INV */ +#define WM8995_AIF1ADCR_DAT_INV_WIDTH 1 /* AIF1ADCR_DAT_INV */ + +/* + * R784 (0x310) - AIF2 Control (1) + */ +#define WM8995_AIF2ADCL_SRC 0x8000 /* AIF2ADCL_SRC */ +#define WM8995_AIF2ADCL_SRC_MASK 0x8000 /* AIF2ADCL_SRC */ +#define WM8995_AIF2ADCL_SRC_SHIFT 15 /* AIF2ADCL_SRC */ +#define WM8995_AIF2ADCL_SRC_WIDTH 1 /* AIF2ADCL_SRC */ +#define WM8995_AIF2ADCR_SRC 0x4000 /* AIF2ADCR_SRC */ +#define WM8995_AIF2ADCR_SRC_MASK 0x4000 /* AIF2ADCR_SRC */ +#define WM8995_AIF2ADCR_SRC_SHIFT 14 /* AIF2ADCR_SRC */ +#define WM8995_AIF2ADCR_SRC_WIDTH 1 /* AIF2ADCR_SRC */ +#define WM8995_AIF2ADC_TDM 0x2000 /* AIF2ADC_TDM */ +#define WM8995_AIF2ADC_TDM_MASK 0x2000 /* AIF2ADC_TDM */ +#define WM8995_AIF2ADC_TDM_SHIFT 13 /* AIF2ADC_TDM */ +#define WM8995_AIF2ADC_TDM_WIDTH 1 /* AIF2ADC_TDM */ +#define WM8995_AIF2ADC_TDM_CHAN 0x1000 /* AIF2ADC_TDM_CHAN */ +#define WM8995_AIF2ADC_TDM_CHAN_MASK 0x1000 /* AIF2ADC_TDM_CHAN */ +#define WM8995_AIF2ADC_TDM_CHAN_SHIFT 12 /* AIF2ADC_TDM_CHAN */ +#define WM8995_AIF2ADC_TDM_CHAN_WIDTH 1 /* AIF2ADC_TDM_CHAN */ +#define WM8995_AIF2_BCLK_INV 0x0100 /* AIF2_BCLK_INV */ +#define WM8995_AIF2_BCLK_INV_MASK 0x0100 /* AIF2_BCLK_INV */ +#define WM8995_AIF2_BCLK_INV_SHIFT 8 /* AIF2_BCLK_INV */ +#define WM8995_AIF2_BCLK_INV_WIDTH 1 /* AIF2_BCLK_INV */ +#define WM8995_AIF2_LRCLK_INV 0x0080 /* AIF2_LRCLK_INV */ +#define WM8995_AIF2_LRCLK_INV_MASK 0x0080 /* AIF2_LRCLK_INV */ +#define WM8995_AIF2_LRCLK_INV_SHIFT 7 /* AIF2_LRCLK_INV */ +#define WM8995_AIF2_LRCLK_INV_WIDTH 1 /* AIF2_LRCLK_INV */ +#define WM8995_AIF2_WL_MASK 0x0060 /* AIF2_WL - [6:5] */ +#define WM8995_AIF2_WL_SHIFT 5 /* AIF2_WL - [6:5] */ +#define WM8995_AIF2_WL_WIDTH 2 /* AIF2_WL - [6:5] */ +#define WM8995_AIF2_FMT_MASK 0x0018 /* AIF2_FMT - [4:3] */ +#define WM8995_AIF2_FMT_SHIFT 3 /* AIF2_FMT - [4:3] */ +#define WM8995_AIF2_FMT_WIDTH 2 /* AIF2_FMT - [4:3] */ + +/* + * R785 (0x311) - AIF2 Control (2) + */ +#define WM8995_AIF2DACL_SRC 0x8000 /* AIF2DACL_SRC */ +#define WM8995_AIF2DACL_SRC_MASK 0x8000 /* AIF2DACL_SRC */ +#define WM8995_AIF2DACL_SRC_SHIFT 15 /* AIF2DACL_SRC */ +#define WM8995_AIF2DACL_SRC_WIDTH 1 /* AIF2DACL_SRC */ +#define WM8995_AIF2DACR_SRC 0x4000 /* AIF2DACR_SRC */ +#define WM8995_AIF2DACR_SRC_MASK 0x4000 /* AIF2DACR_SRC */ +#define WM8995_AIF2DACR_SRC_SHIFT 14 /* AIF2DACR_SRC */ +#define WM8995_AIF2DACR_SRC_WIDTH 1 /* AIF2DACR_SRC */ +#define WM8995_AIF2DAC_TDM 0x2000 /* AIF2DAC_TDM */ +#define WM8995_AIF2DAC_TDM_MASK 0x2000 /* AIF2DAC_TDM */ +#define WM8995_AIF2DAC_TDM_SHIFT 13 /* AIF2DAC_TDM */ +#define WM8995_AIF2DAC_TDM_WIDTH 1 /* AIF2DAC_TDM */ +#define WM8995_AIF2DAC_TDM_CHAN 0x1000 /* AIF2DAC_TDM_CHAN */ +#define WM8995_AIF2DAC_TDM_CHAN_MASK 0x1000 /* AIF2DAC_TDM_CHAN */ +#define WM8995_AIF2DAC_TDM_CHAN_SHIFT 12 /* AIF2DAC_TDM_CHAN */ +#define WM8995_AIF2DAC_TDM_CHAN_WIDTH 1 /* AIF2DAC_TDM_CHAN */ +#define WM8995_AIF2DAC_BOOST_MASK 0x0C00 /* AIF2DAC_BOOST - [11:10] */ +#define WM8995_AIF2DAC_BOOST_SHIFT 10 /* AIF2DAC_BOOST - [11:10] */ +#define WM8995_AIF2DAC_BOOST_WIDTH 2 /* AIF2DAC_BOOST - [11:10] */ +#define WM8995_AIF2DAC_COMP 0x0010 /* AIF2DAC_COMP */ +#define WM8995_AIF2DAC_COMP_MASK 0x0010 /* AIF2DAC_COMP */ +#define WM8995_AIF2DAC_COMP_SHIFT 4 /* AIF2DAC_COMP */ +#define WM8995_AIF2DAC_COMP_WIDTH 1 /* AIF2DAC_COMP */ +#define WM8995_AIF2DAC_COMPMODE 0x0008 /* AIF2DAC_COMPMODE */ +#define WM8995_AIF2DAC_COMPMODE_MASK 0x0008 /* AIF2DAC_COMPMODE */ +#define WM8995_AIF2DAC_COMPMODE_SHIFT 3 /* AIF2DAC_COMPMODE */ +#define WM8995_AIF2DAC_COMPMODE_WIDTH 1 /* AIF2DAC_COMPMODE */ +#define WM8995_AIF2ADC_COMP 0x0004 /* AIF2ADC_COMP */ +#define WM8995_AIF2ADC_COMP_MASK 0x0004 /* AIF2ADC_COMP */ +#define WM8995_AIF2ADC_COMP_SHIFT 2 /* AIF2ADC_COMP */ +#define WM8995_AIF2ADC_COMP_WIDTH 1 /* AIF2ADC_COMP */ +#define WM8995_AIF2ADC_COMPMODE 0x0002 /* AIF2ADC_COMPMODE */ +#define WM8995_AIF2ADC_COMPMODE_MASK 0x0002 /* AIF2ADC_COMPMODE */ +#define WM8995_AIF2ADC_COMPMODE_SHIFT 1 /* AIF2ADC_COMPMODE */ +#define WM8995_AIF2ADC_COMPMODE_WIDTH 1 /* AIF2ADC_COMPMODE */ +#define WM8995_AIF2_LOOPBACK 0x0001 /* AIF2_LOOPBACK */ +#define WM8995_AIF2_LOOPBACK_MASK 0x0001 /* AIF2_LOOPBACK */ +#define WM8995_AIF2_LOOPBACK_SHIFT 0 /* AIF2_LOOPBACK */ +#define WM8995_AIF2_LOOPBACK_WIDTH 1 /* AIF2_LOOPBACK */ + +/* + * R786 (0x312) - AIF2 Master/Slave + */ +#define WM8995_AIF2_TRI 0x8000 /* AIF2_TRI */ +#define WM8995_AIF2_TRI_MASK 0x8000 /* AIF2_TRI */ +#define WM8995_AIF2_TRI_SHIFT 15 /* AIF2_TRI */ +#define WM8995_AIF2_TRI_WIDTH 1 /* AIF2_TRI */ +#define WM8995_AIF2_MSTR 0x4000 /* AIF2_MSTR */ +#define WM8995_AIF2_MSTR_MASK 0x4000 /* AIF2_MSTR */ +#define WM8995_AIF2_MSTR_SHIFT 14 /* AIF2_MSTR */ +#define WM8995_AIF2_MSTR_WIDTH 1 /* AIF2_MSTR */ +#define WM8995_AIF2_CLK_FRC 0x2000 /* AIF2_CLK_FRC */ +#define WM8995_AIF2_CLK_FRC_MASK 0x2000 /* AIF2_CLK_FRC */ +#define WM8995_AIF2_CLK_FRC_SHIFT 13 /* AIF2_CLK_FRC */ +#define WM8995_AIF2_CLK_FRC_WIDTH 1 /* AIF2_CLK_FRC */ +#define WM8995_AIF2_LRCLK_FRC 0x1000 /* AIF2_LRCLK_FRC */ +#define WM8995_AIF2_LRCLK_FRC_MASK 0x1000 /* AIF2_LRCLK_FRC */ +#define WM8995_AIF2_LRCLK_FRC_SHIFT 12 /* AIF2_LRCLK_FRC */ +#define WM8995_AIF2_LRCLK_FRC_WIDTH 1 /* AIF2_LRCLK_FRC */ + +/* + * R787 (0x313) - AIF2 BCLK + */ +#define WM8995_AIF2_BCLK_DIV_MASK 0x00F0 /* AIF2_BCLK_DIV - [7:4] */ +#define WM8995_AIF2_BCLK_DIV_SHIFT 4 /* AIF2_BCLK_DIV - [7:4] */ +#define WM8995_AIF2_BCLK_DIV_WIDTH 4 /* AIF2_BCLK_DIV - [7:4] */ + +/* + * R788 (0x314) - AIF2ADC LRCLK + */ +#define WM8995_AIF2ADC_LRCLK_DIR 0x0800 /* AIF2ADC_LRCLK_DIR */ +#define WM8995_AIF2ADC_LRCLK_DIR_MASK 0x0800 /* AIF2ADC_LRCLK_DIR */ +#define WM8995_AIF2ADC_LRCLK_DIR_SHIFT 11 /* AIF2ADC_LRCLK_DIR */ +#define WM8995_AIF2ADC_LRCLK_DIR_WIDTH 1 /* AIF2ADC_LRCLK_DIR */ +#define WM8995_AIF2ADC_RATE_MASK 0x07FF /* AIF2ADC_RATE - [10:0] */ +#define WM8995_AIF2ADC_RATE_SHIFT 0 /* AIF2ADC_RATE - [10:0] */ +#define WM8995_AIF2ADC_RATE_WIDTH 11 /* AIF2ADC_RATE - [10:0] */ + +/* + * R789 (0x315) - AIF2DAC LRCLK + */ +#define WM8995_AIF2DAC_LRCLK_DIR 0x0800 /* AIF2DAC_LRCLK_DIR */ +#define WM8995_AIF2DAC_LRCLK_DIR_MASK 0x0800 /* AIF2DAC_LRCLK_DIR */ +#define WM8995_AIF2DAC_LRCLK_DIR_SHIFT 11 /* AIF2DAC_LRCLK_DIR */ +#define WM8995_AIF2DAC_LRCLK_DIR_WIDTH 1 /* AIF2DAC_LRCLK_DIR */ +#define WM8995_AIF2DAC_RATE_MASK 0x07FF /* AIF2DAC_RATE - [10:0] */ +#define WM8995_AIF2DAC_RATE_SHIFT 0 /* AIF2DAC_RATE - [10:0] */ +#define WM8995_AIF2DAC_RATE_WIDTH 11 /* AIF2DAC_RATE - [10:0] */ + +/* + * R790 (0x316) - AIF2DAC Data + */ +#define WM8995_AIF2DACL_DAT_INV 0x0002 /* AIF2DACL_DAT_INV */ +#define WM8995_AIF2DACL_DAT_INV_MASK 0x0002 /* AIF2DACL_DAT_INV */ +#define WM8995_AIF2DACL_DAT_INV_SHIFT 1 /* AIF2DACL_DAT_INV */ +#define WM8995_AIF2DACL_DAT_INV_WIDTH 1 /* AIF2DACL_DAT_INV */ +#define WM8995_AIF2DACR_DAT_INV 0x0001 /* AIF2DACR_DAT_INV */ +#define WM8995_AIF2DACR_DAT_INV_MASK 0x0001 /* AIF2DACR_DAT_INV */ +#define WM8995_AIF2DACR_DAT_INV_SHIFT 0 /* AIF2DACR_DAT_INV */ +#define WM8995_AIF2DACR_DAT_INV_WIDTH 1 /* AIF2DACR_DAT_INV */ + +/* + * R791 (0x317) - AIF2ADC Data + */ +#define WM8995_AIF2ADCL_DAT_INV 0x0002 /* AIF2ADCL_DAT_INV */ +#define WM8995_AIF2ADCL_DAT_INV_MASK 0x0002 /* AIF2ADCL_DAT_INV */ +#define WM8995_AIF2ADCL_DAT_INV_SHIFT 1 /* AIF2ADCL_DAT_INV */ +#define WM8995_AIF2ADCL_DAT_INV_WIDTH 1 /* AIF2ADCL_DAT_INV */ +#define WM8995_AIF2ADCR_DAT_INV 0x0001 /* AIF2ADCR_DAT_INV */ +#define WM8995_AIF2ADCR_DAT_INV_MASK 0x0001 /* AIF2ADCR_DAT_INV */ +#define WM8995_AIF2ADCR_DAT_INV_SHIFT 0 /* AIF2ADCR_DAT_INV */ +#define WM8995_AIF2ADCR_DAT_INV_WIDTH 1 /* AIF2ADCR_DAT_INV */ + +/* + * R1024 (0x400) - AIF1 ADC1 Left Volume + */ +#define WM8995_AIF1ADC1_VU 0x0100 /* AIF1ADC1_VU */ +#define WM8995_AIF1ADC1_VU_MASK 0x0100 /* AIF1ADC1_VU */ +#define WM8995_AIF1ADC1_VU_SHIFT 8 /* AIF1ADC1_VU */ +#define WM8995_AIF1ADC1_VU_WIDTH 1 /* AIF1ADC1_VU */ +#define WM8995_AIF1ADC1L_VOL_MASK 0x00FF /* AIF1ADC1L_VOL - [7:0] */ +#define WM8995_AIF1ADC1L_VOL_SHIFT 0 /* AIF1ADC1L_VOL - [7:0] */ +#define WM8995_AIF1ADC1L_VOL_WIDTH 8 /* AIF1ADC1L_VOL - [7:0] */ + +/* + * R1025 (0x401) - AIF1 ADC1 Right Volume + */ +#define WM8995_AIF1ADC1_VU 0x0100 /* AIF1ADC1_VU */ +#define WM8995_AIF1ADC1_VU_MASK 0x0100 /* AIF1ADC1_VU */ +#define WM8995_AIF1ADC1_VU_SHIFT 8 /* AIF1ADC1_VU */ +#define WM8995_AIF1ADC1_VU_WIDTH 1 /* AIF1ADC1_VU */ +#define WM8995_AIF1ADC1R_VOL_MASK 0x00FF /* AIF1ADC1R_VOL - [7:0] */ +#define WM8995_AIF1ADC1R_VOL_SHIFT 0 /* AIF1ADC1R_VOL - [7:0] */ +#define WM8995_AIF1ADC1R_VOL_WIDTH 8 /* AIF1ADC1R_VOL - [7:0] */ + +/* + * R1026 (0x402) - AIF1 DAC1 Left Volume + */ +#define WM8995_AIF1DAC1_VU 0x0100 /* AIF1DAC1_VU */ +#define WM8995_AIF1DAC1_VU_MASK 0x0100 /* AIF1DAC1_VU */ +#define WM8995_AIF1DAC1_VU_SHIFT 8 /* AIF1DAC1_VU */ +#define WM8995_AIF1DAC1_VU_WIDTH 1 /* AIF1DAC1_VU */ +#define WM8995_AIF1DAC1L_VOL_MASK 0x00FF /* AIF1DAC1L_VOL - [7:0] */ +#define WM8995_AIF1DAC1L_VOL_SHIFT 0 /* AIF1DAC1L_VOL - [7:0] */ +#define WM8995_AIF1DAC1L_VOL_WIDTH 8 /* AIF1DAC1L_VOL - [7:0] */ + +/* + * R1027 (0x403) - AIF1 DAC1 Right Volume + */ +#define WM8995_AIF1DAC1_VU 0x0100 /* AIF1DAC1_VU */ +#define WM8995_AIF1DAC1_VU_MASK 0x0100 /* AIF1DAC1_VU */ +#define WM8995_AIF1DAC1_VU_SHIFT 8 /* AIF1DAC1_VU */ +#define WM8995_AIF1DAC1_VU_WIDTH 1 /* AIF1DAC1_VU */ +#define WM8995_AIF1DAC1R_VOL_MASK 0x00FF /* AIF1DAC1R_VOL - [7:0] */ +#define WM8995_AIF1DAC1R_VOL_SHIFT 0 /* AIF1DAC1R_VOL - [7:0] */ +#define WM8995_AIF1DAC1R_VOL_WIDTH 8 /* AIF1DAC1R_VOL - [7:0] */ + +/* + * R1028 (0x404) - AIF1 ADC2 Left Volume + */ +#define WM8995_AIF1ADC2_VU 0x0100 /* AIF1ADC2_VU */ +#define WM8995_AIF1ADC2_VU_MASK 0x0100 /* AIF1ADC2_VU */ +#define WM8995_AIF1ADC2_VU_SHIFT 8 /* AIF1ADC2_VU */ +#define WM8995_AIF1ADC2_VU_WIDTH 1 /* AIF1ADC2_VU */ +#define WM8995_AIF1ADC2L_VOL_MASK 0x00FF /* AIF1ADC2L_VOL - [7:0] */ +#define WM8995_AIF1ADC2L_VOL_SHIFT 0 /* AIF1ADC2L_VOL - [7:0] */ +#define WM8995_AIF1ADC2L_VOL_WIDTH 8 /* AIF1ADC2L_VOL - [7:0] */ + +/* + * R1029 (0x405) - AIF1 ADC2 Right Volume + */ +#define WM8995_AIF1ADC2_VU 0x0100 /* AIF1ADC2_VU */ +#define WM8995_AIF1ADC2_VU_MASK 0x0100 /* AIF1ADC2_VU */ +#define WM8995_AIF1ADC2_VU_SHIFT 8 /* AIF1ADC2_VU */ +#define WM8995_AIF1ADC2_VU_WIDTH 1 /* AIF1ADC2_VU */ +#define WM8995_AIF1ADC2R_VOL_MASK 0x00FF /* AIF1ADC2R_VOL - [7:0] */ +#define WM8995_AIF1ADC2R_VOL_SHIFT 0 /* AIF1ADC2R_VOL - [7:0] */ +#define WM8995_AIF1ADC2R_VOL_WIDTH 8 /* AIF1ADC2R_VOL - [7:0] */ + +/* + * R1030 (0x406) - AIF1 DAC2 Left Volume + */ +#define WM8995_AIF1DAC2_VU 0x0100 /* AIF1DAC2_VU */ +#define WM8995_AIF1DAC2_VU_MASK 0x0100 /* AIF1DAC2_VU */ +#define WM8995_AIF1DAC2_VU_SHIFT 8 /* AIF1DAC2_VU */ +#define WM8995_AIF1DAC2_VU_WIDTH 1 /* AIF1DAC2_VU */ +#define WM8995_AIF1DAC2L_VOL_MASK 0x00FF /* AIF1DAC2L_VOL - [7:0] */ +#define WM8995_AIF1DAC2L_VOL_SHIFT 0 /* AIF1DAC2L_VOL - [7:0] */ +#define WM8995_AIF1DAC2L_VOL_WIDTH 8 /* AIF1DAC2L_VOL - [7:0] */ + +/* + * R1031 (0x407) - AIF1 DAC2 Right Volume + */ +#define WM8995_AIF1DAC2_VU 0x0100 /* AIF1DAC2_VU */ +#define WM8995_AIF1DAC2_VU_MASK 0x0100 /* AIF1DAC2_VU */ +#define WM8995_AIF1DAC2_VU_SHIFT 8 /* AIF1DAC2_VU */ +#define WM8995_AIF1DAC2_VU_WIDTH 1 /* AIF1DAC2_VU */ +#define WM8995_AIF1DAC2R_VOL_MASK 0x00FF /* AIF1DAC2R_VOL - [7:0] */ +#define WM8995_AIF1DAC2R_VOL_SHIFT 0 /* AIF1DAC2R_VOL - [7:0] */ +#define WM8995_AIF1DAC2R_VOL_WIDTH 8 /* AIF1DAC2R_VOL - [7:0] */ + +/* + * R1040 (0x410) - AIF1 ADC1 Filters + */ +#define WM8995_AIF1ADC_4FS 0x8000 /* AIF1ADC_4FS */ +#define WM8995_AIF1ADC_4FS_MASK 0x8000 /* AIF1ADC_4FS */ +#define WM8995_AIF1ADC_4FS_SHIFT 15 /* AIF1ADC_4FS */ +#define WM8995_AIF1ADC_4FS_WIDTH 1 /* AIF1ADC_4FS */ +#define WM8995_AIF1ADC1L_HPF 0x1000 /* AIF1ADC1L_HPF */ +#define WM8995_AIF1ADC1L_HPF_MASK 0x1000 /* AIF1ADC1L_HPF */ +#define WM8995_AIF1ADC1L_HPF_SHIFT 12 /* AIF1ADC1L_HPF */ +#define WM8995_AIF1ADC1L_HPF_WIDTH 1 /* AIF1ADC1L_HPF */ +#define WM8995_AIF1ADC1R_HPF 0x0800 /* AIF1ADC1R_HPF */ +#define WM8995_AIF1ADC1R_HPF_MASK 0x0800 /* AIF1ADC1R_HPF */ +#define WM8995_AIF1ADC1R_HPF_SHIFT 11 /* AIF1ADC1R_HPF */ +#define WM8995_AIF1ADC1R_HPF_WIDTH 1 /* AIF1ADC1R_HPF */ +#define WM8995_AIF1ADC1_HPF_MODE 0x0008 /* AIF1ADC1_HPF_MODE */ +#define WM8995_AIF1ADC1_HPF_MODE_MASK 0x0008 /* AIF1ADC1_HPF_MODE */ +#define WM8995_AIF1ADC1_HPF_MODE_SHIFT 3 /* AIF1ADC1_HPF_MODE */ +#define WM8995_AIF1ADC1_HPF_MODE_WIDTH 1 /* AIF1ADC1_HPF_MODE */ +#define WM8995_AIF1ADC1_HPF_CUT_MASK 0x0007 /* AIF1ADC1_HPF_CUT - [2:0] */ +#define WM8995_AIF1ADC1_HPF_CUT_SHIFT 0 /* AIF1ADC1_HPF_CUT - [2:0] */ +#define WM8995_AIF1ADC1_HPF_CUT_WIDTH 3 /* AIF1ADC1_HPF_CUT - [2:0] */ + +/* + * R1041 (0x411) - AIF1 ADC2 Filters + */ +#define WM8995_AIF1ADC2L_HPF 0x1000 /* AIF1ADC2L_HPF */ +#define WM8995_AIF1ADC2L_HPF_MASK 0x1000 /* AIF1ADC2L_HPF */ +#define WM8995_AIF1ADC2L_HPF_SHIFT 12 /* AIF1ADC2L_HPF */ +#define WM8995_AIF1ADC2L_HPF_WIDTH 1 /* AIF1ADC2L_HPF */ +#define WM8995_AIF1ADC2R_HPF 0x0800 /* AIF1ADC2R_HPF */ +#define WM8995_AIF1ADC2R_HPF_MASK 0x0800 /* AIF1ADC2R_HPF */ +#define WM8995_AIF1ADC2R_HPF_SHIFT 11 /* AIF1ADC2R_HPF */ +#define WM8995_AIF1ADC2R_HPF_WIDTH 1 /* AIF1ADC2R_HPF */ +#define WM8995_AIF1ADC2_HPF_MODE 0x0008 /* AIF1ADC2_HPF_MODE */ +#define WM8995_AIF1ADC2_HPF_MODE_MASK 0x0008 /* AIF1ADC2_HPF_MODE */ +#define WM8995_AIF1ADC2_HPF_MODE_SHIFT 3 /* AIF1ADC2_HPF_MODE */ +#define WM8995_AIF1ADC2_HPF_MODE_WIDTH 1 /* AIF1ADC2_HPF_MODE */ +#define WM8995_AIF1ADC2_HPF_CUT_MASK 0x0007 /* AIF1ADC2_HPF_CUT - [2:0] */ +#define WM8995_AIF1ADC2_HPF_CUT_SHIFT 0 /* AIF1ADC2_HPF_CUT - [2:0] */ +#define WM8995_AIF1ADC2_HPF_CUT_WIDTH 3 /* AIF1ADC2_HPF_CUT - [2:0] */ + +/* + * R1056 (0x420) - AIF1 DAC1 Filters (1) + */ +#define WM8995_AIF1DAC1_MUTE 0x0200 /* AIF1DAC1_MUTE */ +#define WM8995_AIF1DAC1_MUTE_MASK 0x0200 /* AIF1DAC1_MUTE */ +#define WM8995_AIF1DAC1_MUTE_SHIFT 9 /* AIF1DAC1_MUTE */ +#define WM8995_AIF1DAC1_MUTE_WIDTH 1 /* AIF1DAC1_MUTE */ +#define WM8995_AIF1DAC1_MONO 0x0080 /* AIF1DAC1_MONO */ +#define WM8995_AIF1DAC1_MONO_MASK 0x0080 /* AIF1DAC1_MONO */ +#define WM8995_AIF1DAC1_MONO_SHIFT 7 /* AIF1DAC1_MONO */ +#define WM8995_AIF1DAC1_MONO_WIDTH 1 /* AIF1DAC1_MONO */ +#define WM8995_AIF1DAC1_MUTERATE 0x0020 /* AIF1DAC1_MUTERATE */ +#define WM8995_AIF1DAC1_MUTERATE_MASK 0x0020 /* AIF1DAC1_MUTERATE */ +#define WM8995_AIF1DAC1_MUTERATE_SHIFT 5 /* AIF1DAC1_MUTERATE */ +#define WM8995_AIF1DAC1_MUTERATE_WIDTH 1 /* AIF1DAC1_MUTERATE */ +#define WM8995_AIF1DAC1_UNMUTE_RAMP 0x0010 /* AIF1DAC1_UNMUTE_RAMP */ +#define WM8995_AIF1DAC1_UNMUTE_RAMP_MASK 0x0010 /* AIF1DAC1_UNMUTE_RAMP */ +#define WM8995_AIF1DAC1_UNMUTE_RAMP_SHIFT 4 /* AIF1DAC1_UNMUTE_RAMP */ +#define WM8995_AIF1DAC1_UNMUTE_RAMP_WIDTH 1 /* AIF1DAC1_UNMUTE_RAMP */ +#define WM8995_AIF1DAC1_DEEMP_MASK 0x0006 /* AIF1DAC1_DEEMP - [2:1] */ +#define WM8995_AIF1DAC1_DEEMP_SHIFT 1 /* AIF1DAC1_DEEMP - [2:1] */ +#define WM8995_AIF1DAC1_DEEMP_WIDTH 2 /* AIF1DAC1_DEEMP - [2:1] */ + +/* + * R1057 (0x421) - AIF1 DAC1 Filters (2) + */ +#define WM8995_AIF1DAC1_3D_GAIN_MASK 0x3E00 /* AIF1DAC1_3D_GAIN - [13:9] */ +#define WM8995_AIF1DAC1_3D_GAIN_SHIFT 9 /* AIF1DAC1_3D_GAIN - [13:9] */ +#define WM8995_AIF1DAC1_3D_GAIN_WIDTH 5 /* AIF1DAC1_3D_GAIN - [13:9] */ +#define WM8995_AIF1DAC1_3D_ENA 0x0100 /* AIF1DAC1_3D_ENA */ +#define WM8995_AIF1DAC1_3D_ENA_MASK 0x0100 /* AIF1DAC1_3D_ENA */ +#define WM8995_AIF1DAC1_3D_ENA_SHIFT 8 /* AIF1DAC1_3D_ENA */ +#define WM8995_AIF1DAC1_3D_ENA_WIDTH 1 /* AIF1DAC1_3D_ENA */ + +/* + * R1058 (0x422) - AIF1 DAC2 Filters (1) + */ +#define WM8995_AIF1DAC2_MUTE 0x0200 /* AIF1DAC2_MUTE */ +#define WM8995_AIF1DAC2_MUTE_MASK 0x0200 /* AIF1DAC2_MUTE */ +#define WM8995_AIF1DAC2_MUTE_SHIFT 9 /* AIF1DAC2_MUTE */ +#define WM8995_AIF1DAC2_MUTE_WIDTH 1 /* AIF1DAC2_MUTE */ +#define WM8995_AIF1DAC2_MONO 0x0080 /* AIF1DAC2_MONO */ +#define WM8995_AIF1DAC2_MONO_MASK 0x0080 /* AIF1DAC2_MONO */ +#define WM8995_AIF1DAC2_MONO_SHIFT 7 /* AIF1DAC2_MONO */ +#define WM8995_AIF1DAC2_MONO_WIDTH 1 /* AIF1DAC2_MONO */ +#define WM8995_AIF1DAC2_MUTERATE 0x0020 /* AIF1DAC2_MUTERATE */ +#define WM8995_AIF1DAC2_MUTERATE_MASK 0x0020 /* AIF1DAC2_MUTERATE */ +#define WM8995_AIF1DAC2_MUTERATE_SHIFT 5 /* AIF1DAC2_MUTERATE */ +#define WM8995_AIF1DAC2_MUTERATE_WIDTH 1 /* AIF1DAC2_MUTERATE */ +#define WM8995_AIF1DAC2_UNMUTE_RAMP 0x0010 /* AIF1DAC2_UNMUTE_RAMP */ +#define WM8995_AIF1DAC2_UNMUTE_RAMP_MASK 0x0010 /* AIF1DAC2_UNMUTE_RAMP */ +#define WM8995_AIF1DAC2_UNMUTE_RAMP_SHIFT 4 /* AIF1DAC2_UNMUTE_RAMP */ +#define WM8995_AIF1DAC2_UNMUTE_RAMP_WIDTH 1 /* AIF1DAC2_UNMUTE_RAMP */ +#define WM8995_AIF1DAC2_DEEMP_MASK 0x0006 /* AIF1DAC2_DEEMP - [2:1] */ +#define WM8995_AIF1DAC2_DEEMP_SHIFT 1 /* AIF1DAC2_DEEMP - [2:1] */ +#define WM8995_AIF1DAC2_DEEMP_WIDTH 2 /* AIF1DAC2_DEEMP - [2:1] */ + +/* + * R1059 (0x423) - AIF1 DAC2 Filters (2) + */ +#define WM8995_AIF1DAC2_3D_GAIN_MASK 0x3E00 /* AIF1DAC2_3D_GAIN - [13:9] */ +#define WM8995_AIF1DAC2_3D_GAIN_SHIFT 9 /* AIF1DAC2_3D_GAIN - [13:9] */ +#define WM8995_AIF1DAC2_3D_GAIN_WIDTH 5 /* AIF1DAC2_3D_GAIN - [13:9] */ +#define WM8995_AIF1DAC2_3D_ENA 0x0100 /* AIF1DAC2_3D_ENA */ +#define WM8995_AIF1DAC2_3D_ENA_MASK 0x0100 /* AIF1DAC2_3D_ENA */ +#define WM8995_AIF1DAC2_3D_ENA_SHIFT 8 /* AIF1DAC2_3D_ENA */ +#define WM8995_AIF1DAC2_3D_ENA_WIDTH 1 /* AIF1DAC2_3D_ENA */ + +/* + * R1088 (0x440) - AIF1 DRC1 (1) + */ +#define WM8995_AIF1DRC1_SIG_DET_RMS_MASK 0xF800 /* AIF1DRC1_SIG_DET_RMS - [15:11] */ +#define WM8995_AIF1DRC1_SIG_DET_RMS_SHIFT 11 /* AIF1DRC1_SIG_DET_RMS - [15:11] */ +#define WM8995_AIF1DRC1_SIG_DET_RMS_WIDTH 5 /* AIF1DRC1_SIG_DET_RMS - [15:11] */ +#define WM8995_AIF1DRC1_SIG_DET_PK_MASK 0x0600 /* AIF1DRC1_SIG_DET_PK - [10:9] */ +#define WM8995_AIF1DRC1_SIG_DET_PK_SHIFT 9 /* AIF1DRC1_SIG_DET_PK - [10:9] */ +#define WM8995_AIF1DRC1_SIG_DET_PK_WIDTH 2 /* AIF1DRC1_SIG_DET_PK - [10:9] */ +#define WM8995_AIF1DRC1_NG_ENA 0x0100 /* AIF1DRC1_NG_ENA */ +#define WM8995_AIF1DRC1_NG_ENA_MASK 0x0100 /* AIF1DRC1_NG_ENA */ +#define WM8995_AIF1DRC1_NG_ENA_SHIFT 8 /* AIF1DRC1_NG_ENA */ +#define WM8995_AIF1DRC1_NG_ENA_WIDTH 1 /* AIF1DRC1_NG_ENA */ +#define WM8995_AIF1DRC1_SIG_DET_MODE 0x0080 /* AIF1DRC1_SIG_DET_MODE */ +#define WM8995_AIF1DRC1_SIG_DET_MODE_MASK 0x0080 /* AIF1DRC1_SIG_DET_MODE */ +#define WM8995_AIF1DRC1_SIG_DET_MODE_SHIFT 7 /* AIF1DRC1_SIG_DET_MODE */ +#define WM8995_AIF1DRC1_SIG_DET_MODE_WIDTH 1 /* AIF1DRC1_SIG_DET_MODE */ +#define WM8995_AIF1DRC1_SIG_DET 0x0040 /* AIF1DRC1_SIG_DET */ +#define WM8995_AIF1DRC1_SIG_DET_MASK 0x0040 /* AIF1DRC1_SIG_DET */ +#define WM8995_AIF1DRC1_SIG_DET_SHIFT 6 /* AIF1DRC1_SIG_DET */ +#define WM8995_AIF1DRC1_SIG_DET_WIDTH 1 /* AIF1DRC1_SIG_DET */ +#define WM8995_AIF1DRC1_KNEE2_OP_ENA 0x0020 /* AIF1DRC1_KNEE2_OP_ENA */ +#define WM8995_AIF1DRC1_KNEE2_OP_ENA_MASK 0x0020 /* AIF1DRC1_KNEE2_OP_ENA */ +#define WM8995_AIF1DRC1_KNEE2_OP_ENA_SHIFT 5 /* AIF1DRC1_KNEE2_OP_ENA */ +#define WM8995_AIF1DRC1_KNEE2_OP_ENA_WIDTH 1 /* AIF1DRC1_KNEE2_OP_ENA */ +#define WM8995_AIF1DRC1_QR 0x0010 /* AIF1DRC1_QR */ +#define WM8995_AIF1DRC1_QR_MASK 0x0010 /* AIF1DRC1_QR */ +#define WM8995_AIF1DRC1_QR_SHIFT 4 /* AIF1DRC1_QR */ +#define WM8995_AIF1DRC1_QR_WIDTH 1 /* AIF1DRC1_QR */ +#define WM8995_AIF1DRC1_ANTICLIP 0x0008 /* AIF1DRC1_ANTICLIP */ +#define WM8995_AIF1DRC1_ANTICLIP_MASK 0x0008 /* AIF1DRC1_ANTICLIP */ +#define WM8995_AIF1DRC1_ANTICLIP_SHIFT 3 /* AIF1DRC1_ANTICLIP */ +#define WM8995_AIF1DRC1_ANTICLIP_WIDTH 1 /* AIF1DRC1_ANTICLIP */ +#define WM8995_AIF1DAC1_DRC_ENA 0x0004 /* AIF1DAC1_DRC_ENA */ +#define WM8995_AIF1DAC1_DRC_ENA_MASK 0x0004 /* AIF1DAC1_DRC_ENA */ +#define WM8995_AIF1DAC1_DRC_ENA_SHIFT 2 /* AIF1DAC1_DRC_ENA */ +#define WM8995_AIF1DAC1_DRC_ENA_WIDTH 1 /* AIF1DAC1_DRC_ENA */ +#define WM8995_AIF1ADC1L_DRC_ENA 0x0002 /* AIF1ADC1L_DRC_ENA */ +#define WM8995_AIF1ADC1L_DRC_ENA_MASK 0x0002 /* AIF1ADC1L_DRC_ENA */ +#define WM8995_AIF1ADC1L_DRC_ENA_SHIFT 1 /* AIF1ADC1L_DRC_ENA */ +#define WM8995_AIF1ADC1L_DRC_ENA_WIDTH 1 /* AIF1ADC1L_DRC_ENA */ +#define WM8995_AIF1ADC1R_DRC_ENA 0x0001 /* AIF1ADC1R_DRC_ENA */ +#define WM8995_AIF1ADC1R_DRC_ENA_MASK 0x0001 /* AIF1ADC1R_DRC_ENA */ +#define WM8995_AIF1ADC1R_DRC_ENA_SHIFT 0 /* AIF1ADC1R_DRC_ENA */ +#define WM8995_AIF1ADC1R_DRC_ENA_WIDTH 1 /* AIF1ADC1R_DRC_ENA */ + +/* + * R1089 (0x441) - AIF1 DRC1 (2) + */ +#define WM8995_AIF1DRC1_ATK_MASK 0x1E00 /* AIF1DRC1_ATK - [12:9] */ +#define WM8995_AIF1DRC1_ATK_SHIFT 9 /* AIF1DRC1_ATK - [12:9] */ +#define WM8995_AIF1DRC1_ATK_WIDTH 4 /* AIF1DRC1_ATK - [12:9] */ +#define WM8995_AIF1DRC1_DCY_MASK 0x01E0 /* AIF1DRC1_DCY - [8:5] */ +#define WM8995_AIF1DRC1_DCY_SHIFT 5 /* AIF1DRC1_DCY - [8:5] */ +#define WM8995_AIF1DRC1_DCY_WIDTH 4 /* AIF1DRC1_DCY - [8:5] */ +#define WM8995_AIF1DRC1_MINGAIN_MASK 0x001C /* AIF1DRC1_MINGAIN - [4:2] */ +#define WM8995_AIF1DRC1_MINGAIN_SHIFT 2 /* AIF1DRC1_MINGAIN - [4:2] */ +#define WM8995_AIF1DRC1_MINGAIN_WIDTH 3 /* AIF1DRC1_MINGAIN - [4:2] */ +#define WM8995_AIF1DRC1_MAXGAIN_MASK 0x0003 /* AIF1DRC1_MAXGAIN - [1:0] */ +#define WM8995_AIF1DRC1_MAXGAIN_SHIFT 0 /* AIF1DRC1_MAXGAIN - [1:0] */ +#define WM8995_AIF1DRC1_MAXGAIN_WIDTH 2 /* AIF1DRC1_MAXGAIN - [1:0] */ + +/* + * R1090 (0x442) - AIF1 DRC1 (3) + */ +#define WM8995_AIF1DRC1_NG_MINGAIN_MASK 0xF000 /* AIF1DRC1_NG_MINGAIN - [15:12] */ +#define WM8995_AIF1DRC1_NG_MINGAIN_SHIFT 12 /* AIF1DRC1_NG_MINGAIN - [15:12] */ +#define WM8995_AIF1DRC1_NG_MINGAIN_WIDTH 4 /* AIF1DRC1_NG_MINGAIN - [15:12] */ +#define WM8995_AIF1DRC1_NG_EXP_MASK 0x0C00 /* AIF1DRC1_NG_EXP - [11:10] */ +#define WM8995_AIF1DRC1_NG_EXP_SHIFT 10 /* AIF1DRC1_NG_EXP - [11:10] */ +#define WM8995_AIF1DRC1_NG_EXP_WIDTH 2 /* AIF1DRC1_NG_EXP - [11:10] */ +#define WM8995_AIF1DRC1_QR_THR_MASK 0x0300 /* AIF1DRC1_QR_THR - [9:8] */ +#define WM8995_AIF1DRC1_QR_THR_SHIFT 8 /* AIF1DRC1_QR_THR - [9:8] */ +#define WM8995_AIF1DRC1_QR_THR_WIDTH 2 /* AIF1DRC1_QR_THR - [9:8] */ +#define WM8995_AIF1DRC1_QR_DCY_MASK 0x00C0 /* AIF1DRC1_QR_DCY - [7:6] */ +#define WM8995_AIF1DRC1_QR_DCY_SHIFT 6 /* AIF1DRC1_QR_DCY - [7:6] */ +#define WM8995_AIF1DRC1_QR_DCY_WIDTH 2 /* AIF1DRC1_QR_DCY - [7:6] */ +#define WM8995_AIF1DRC1_HI_COMP_MASK 0x0038 /* AIF1DRC1_HI_COMP - [5:3] */ +#define WM8995_AIF1DRC1_HI_COMP_SHIFT 3 /* AIF1DRC1_HI_COMP - [5:3] */ +#define WM8995_AIF1DRC1_HI_COMP_WIDTH 3 /* AIF1DRC1_HI_COMP - [5:3] */ +#define WM8995_AIF1DRC1_LO_COMP_MASK 0x0007 /* AIF1DRC1_LO_COMP - [2:0] */ +#define WM8995_AIF1DRC1_LO_COMP_SHIFT 0 /* AIF1DRC1_LO_COMP - [2:0] */ +#define WM8995_AIF1DRC1_LO_COMP_WIDTH 3 /* AIF1DRC1_LO_COMP - [2:0] */ + +/* + * R1091 (0x443) - AIF1 DRC1 (4) + */ +#define WM8995_AIF1DRC1_KNEE_IP_MASK 0x07E0 /* AIF1DRC1_KNEE_IP - [10:5] */ +#define WM8995_AIF1DRC1_KNEE_IP_SHIFT 5 /* AIF1DRC1_KNEE_IP - [10:5] */ +#define WM8995_AIF1DRC1_KNEE_IP_WIDTH 6 /* AIF1DRC1_KNEE_IP - [10:5] */ +#define WM8995_AIF1DRC1_KNEE_OP_MASK 0x001F /* AIF1DRC1_KNEE_OP - [4:0] */ +#define WM8995_AIF1DRC1_KNEE_OP_SHIFT 0 /* AIF1DRC1_KNEE_OP - [4:0] */ +#define WM8995_AIF1DRC1_KNEE_OP_WIDTH 5 /* AIF1DRC1_KNEE_OP - [4:0] */ + +/* + * R1092 (0x444) - AIF1 DRC1 (5) + */ +#define WM8995_AIF1DRC1_KNEE2_IP_MASK 0x03E0 /* AIF1DRC1_KNEE2_IP - [9:5] */ +#define WM8995_AIF1DRC1_KNEE2_IP_SHIFT 5 /* AIF1DRC1_KNEE2_IP - [9:5] */ +#define WM8995_AIF1DRC1_KNEE2_IP_WIDTH 5 /* AIF1DRC1_KNEE2_IP - [9:5] */ +#define WM8995_AIF1DRC1_KNEE2_OP_MASK 0x001F /* AIF1DRC1_KNEE2_OP - [4:0] */ +#define WM8995_AIF1DRC1_KNEE2_OP_SHIFT 0 /* AIF1DRC1_KNEE2_OP - [4:0] */ +#define WM8995_AIF1DRC1_KNEE2_OP_WIDTH 5 /* AIF1DRC1_KNEE2_OP - [4:0] */ + +/* + * R1104 (0x450) - AIF1 DRC2 (1) + */ +#define WM8995_AIF1DRC2_SIG_DET_RMS_MASK 0xF800 /* AIF1DRC2_SIG_DET_RMS - [15:11] */ +#define WM8995_AIF1DRC2_SIG_DET_RMS_SHIFT 11 /* AIF1DRC2_SIG_DET_RMS - [15:11] */ +#define WM8995_AIF1DRC2_SIG_DET_RMS_WIDTH 5 /* AIF1DRC2_SIG_DET_RMS - [15:11] */ +#define WM8995_AIF1DRC2_SIG_DET_PK_MASK 0x0600 /* AIF1DRC2_SIG_DET_PK - [10:9] */ +#define WM8995_AIF1DRC2_SIG_DET_PK_SHIFT 9 /* AIF1DRC2_SIG_DET_PK - [10:9] */ +#define WM8995_AIF1DRC2_SIG_DET_PK_WIDTH 2 /* AIF1DRC2_SIG_DET_PK - [10:9] */ +#define WM8995_AIF1DRC2_NG_ENA 0x0100 /* AIF1DRC2_NG_ENA */ +#define WM8995_AIF1DRC2_NG_ENA_MASK 0x0100 /* AIF1DRC2_NG_ENA */ +#define WM8995_AIF1DRC2_NG_ENA_SHIFT 8 /* AIF1DRC2_NG_ENA */ +#define WM8995_AIF1DRC2_NG_ENA_WIDTH 1 /* AIF1DRC2_NG_ENA */ +#define WM8995_AIF1DRC2_SIG_DET_MODE 0x0080 /* AIF1DRC2_SIG_DET_MODE */ +#define WM8995_AIF1DRC2_SIG_DET_MODE_MASK 0x0080 /* AIF1DRC2_SIG_DET_MODE */ +#define WM8995_AIF1DRC2_SIG_DET_MODE_SHIFT 7 /* AIF1DRC2_SIG_DET_MODE */ +#define WM8995_AIF1DRC2_SIG_DET_MODE_WIDTH 1 /* AIF1DRC2_SIG_DET_MODE */ +#define WM8995_AIF1DRC2_SIG_DET 0x0040 /* AIF1DRC2_SIG_DET */ +#define WM8995_AIF1DRC2_SIG_DET_MASK 0x0040 /* AIF1DRC2_SIG_DET */ +#define WM8995_AIF1DRC2_SIG_DET_SHIFT 6 /* AIF1DRC2_SIG_DET */ +#define WM8995_AIF1DRC2_SIG_DET_WIDTH 1 /* AIF1DRC2_SIG_DET */ +#define WM8995_AIF1DRC2_KNEE2_OP_ENA 0x0020 /* AIF1DRC2_KNEE2_OP_ENA */ +#define WM8995_AIF1DRC2_KNEE2_OP_ENA_MASK 0x0020 /* AIF1DRC2_KNEE2_OP_ENA */ +#define WM8995_AIF1DRC2_KNEE2_OP_ENA_SHIFT 5 /* AIF1DRC2_KNEE2_OP_ENA */ +#define WM8995_AIF1DRC2_KNEE2_OP_ENA_WIDTH 1 /* AIF1DRC2_KNEE2_OP_ENA */ +#define WM8995_AIF1DRC2_QR 0x0010 /* AIF1DRC2_QR */ +#define WM8995_AIF1DRC2_QR_MASK 0x0010 /* AIF1DRC2_QR */ +#define WM8995_AIF1DRC2_QR_SHIFT 4 /* AIF1DRC2_QR */ +#define WM8995_AIF1DRC2_QR_WIDTH 1 /* AIF1DRC2_QR */ +#define WM8995_AIF1DRC2_ANTICLIP 0x0008 /* AIF1DRC2_ANTICLIP */ +#define WM8995_AIF1DRC2_ANTICLIP_MASK 0x0008 /* AIF1DRC2_ANTICLIP */ +#define WM8995_AIF1DRC2_ANTICLIP_SHIFT 3 /* AIF1DRC2_ANTICLIP */ +#define WM8995_AIF1DRC2_ANTICLIP_WIDTH 1 /* AIF1DRC2_ANTICLIP */ +#define WM8995_AIF1DAC2_DRC_ENA 0x0004 /* AIF1DAC2_DRC_ENA */ +#define WM8995_AIF1DAC2_DRC_ENA_MASK 0x0004 /* AIF1DAC2_DRC_ENA */ +#define WM8995_AIF1DAC2_DRC_ENA_SHIFT 2 /* AIF1DAC2_DRC_ENA */ +#define WM8995_AIF1DAC2_DRC_ENA_WIDTH 1 /* AIF1DAC2_DRC_ENA */ +#define WM8995_AIF1ADC2L_DRC_ENA 0x0002 /* AIF1ADC2L_DRC_ENA */ +#define WM8995_AIF1ADC2L_DRC_ENA_MASK 0x0002 /* AIF1ADC2L_DRC_ENA */ +#define WM8995_AIF1ADC2L_DRC_ENA_SHIFT 1 /* AIF1ADC2L_DRC_ENA */ +#define WM8995_AIF1ADC2L_DRC_ENA_WIDTH 1 /* AIF1ADC2L_DRC_ENA */ +#define WM8995_AIF1ADC2R_DRC_ENA 0x0001 /* AIF1ADC2R_DRC_ENA */ +#define WM8995_AIF1ADC2R_DRC_ENA_MASK 0x0001 /* AIF1ADC2R_DRC_ENA */ +#define WM8995_AIF1ADC2R_DRC_ENA_SHIFT 0 /* AIF1ADC2R_DRC_ENA */ +#define WM8995_AIF1ADC2R_DRC_ENA_WIDTH 1 /* AIF1ADC2R_DRC_ENA */ + +/* + * R1105 (0x451) - AIF1 DRC2 (2) + */ +#define WM8995_AIF1DRC2_ATK_MASK 0x1E00 /* AIF1DRC2_ATK - [12:9] */ +#define WM8995_AIF1DRC2_ATK_SHIFT 9 /* AIF1DRC2_ATK - [12:9] */ +#define WM8995_AIF1DRC2_ATK_WIDTH 4 /* AIF1DRC2_ATK - [12:9] */ +#define WM8995_AIF1DRC2_DCY_MASK 0x01E0 /* AIF1DRC2_DCY - [8:5] */ +#define WM8995_AIF1DRC2_DCY_SHIFT 5 /* AIF1DRC2_DCY - [8:5] */ +#define WM8995_AIF1DRC2_DCY_WIDTH 4 /* AIF1DRC2_DCY - [8:5] */ +#define WM8995_AIF1DRC2_MINGAIN_MASK 0x001C /* AIF1DRC2_MINGAIN - [4:2] */ +#define WM8995_AIF1DRC2_MINGAIN_SHIFT 2 /* AIF1DRC2_MINGAIN - [4:2] */ +#define WM8995_AIF1DRC2_MINGAIN_WIDTH 3 /* AIF1DRC2_MINGAIN - [4:2] */ +#define WM8995_AIF1DRC2_MAXGAIN_MASK 0x0003 /* AIF1DRC2_MAXGAIN - [1:0] */ +#define WM8995_AIF1DRC2_MAXGAIN_SHIFT 0 /* AIF1DRC2_MAXGAIN - [1:0] */ +#define WM8995_AIF1DRC2_MAXGAIN_WIDTH 2 /* AIF1DRC2_MAXGAIN - [1:0] */ + +/* + * R1106 (0x452) - AIF1 DRC2 (3) + */ +#define WM8995_AIF1DRC2_NG_MINGAIN_MASK 0xF000 /* AIF1DRC2_NG_MINGAIN - [15:12] */ +#define WM8995_AIF1DRC2_NG_MINGAIN_SHIFT 12 /* AIF1DRC2_NG_MINGAIN - [15:12] */ +#define WM8995_AIF1DRC2_NG_MINGAIN_WIDTH 4 /* AIF1DRC2_NG_MINGAIN - [15:12] */ +#define WM8995_AIF1DRC2_NG_EXP_MASK 0x0C00 /* AIF1DRC2_NG_EXP - [11:10] */ +#define WM8995_AIF1DRC2_NG_EXP_SHIFT 10 /* AIF1DRC2_NG_EXP - [11:10] */ +#define WM8995_AIF1DRC2_NG_EXP_WIDTH 2 /* AIF1DRC2_NG_EXP - [11:10] */ +#define WM8995_AIF1DRC2_QR_THR_MASK 0x0300 /* AIF1DRC2_QR_THR - [9:8] */ +#define WM8995_AIF1DRC2_QR_THR_SHIFT 8 /* AIF1DRC2_QR_THR - [9:8] */ +#define WM8995_AIF1DRC2_QR_THR_WIDTH 2 /* AIF1DRC2_QR_THR - [9:8] */ +#define WM8995_AIF1DRC2_QR_DCY_MASK 0x00C0 /* AIF1DRC2_QR_DCY - [7:6] */ +#define WM8995_AIF1DRC2_QR_DCY_SHIFT 6 /* AIF1DRC2_QR_DCY - [7:6] */ +#define WM8995_AIF1DRC2_QR_DCY_WIDTH 2 /* AIF1DRC2_QR_DCY - [7:6] */ +#define WM8995_AIF1DRC2_HI_COMP_MASK 0x0038 /* AIF1DRC2_HI_COMP - [5:3] */ +#define WM8995_AIF1DRC2_HI_COMP_SHIFT 3 /* AIF1DRC2_HI_COMP - [5:3] */ +#define WM8995_AIF1DRC2_HI_COMP_WIDTH 3 /* AIF1DRC2_HI_COMP - [5:3] */ +#define WM8995_AIF1DRC2_LO_COMP_MASK 0x0007 /* AIF1DRC2_LO_COMP - [2:0] */ +#define WM8995_AIF1DRC2_LO_COMP_SHIFT 0 /* AIF1DRC2_LO_COMP - [2:0] */ +#define WM8995_AIF1DRC2_LO_COMP_WIDTH 3 /* AIF1DRC2_LO_COMP - [2:0] */ + +/* + * R1107 (0x453) - AIF1 DRC2 (4) + */ +#define WM8995_AIF1DRC2_KNEE_IP_MASK 0x07E0 /* AIF1DRC2_KNEE_IP - [10:5] */ +#define WM8995_AIF1DRC2_KNEE_IP_SHIFT 5 /* AIF1DRC2_KNEE_IP - [10:5] */ +#define WM8995_AIF1DRC2_KNEE_IP_WIDTH 6 /* AIF1DRC2_KNEE_IP - [10:5] */ +#define WM8995_AIF1DRC2_KNEE_OP_MASK 0x001F /* AIF1DRC2_KNEE_OP - [4:0] */ +#define WM8995_AIF1DRC2_KNEE_OP_SHIFT 0 /* AIF1DRC2_KNEE_OP - [4:0] */ +#define WM8995_AIF1DRC2_KNEE_OP_WIDTH 5 /* AIF1DRC2_KNEE_OP - [4:0] */ + +/* + * R1108 (0x454) - AIF1 DRC2 (5) + */ +#define WM8995_AIF1DRC2_KNEE2_IP_MASK 0x03E0 /* AIF1DRC2_KNEE2_IP - [9:5] */ +#define WM8995_AIF1DRC2_KNEE2_IP_SHIFT 5 /* AIF1DRC2_KNEE2_IP - [9:5] */ +#define WM8995_AIF1DRC2_KNEE2_IP_WIDTH 5 /* AIF1DRC2_KNEE2_IP - [9:5] */ +#define WM8995_AIF1DRC2_KNEE2_OP_MASK 0x001F /* AIF1DRC2_KNEE2_OP - [4:0] */ +#define WM8995_AIF1DRC2_KNEE2_OP_SHIFT 0 /* AIF1DRC2_KNEE2_OP - [4:0] */ +#define WM8995_AIF1DRC2_KNEE2_OP_WIDTH 5 /* AIF1DRC2_KNEE2_OP - [4:0] */ + +/* + * R1152 (0x480) - AIF1 DAC1 EQ Gains (1) + */ +#define WM8995_AIF1DAC1_EQ_B1_GAIN_MASK 0xF800 /* AIF1DAC1_EQ_B1_GAIN - [15:11] */ +#define WM8995_AIF1DAC1_EQ_B1_GAIN_SHIFT 11 /* AIF1DAC1_EQ_B1_GAIN - [15:11] */ +#define WM8995_AIF1DAC1_EQ_B1_GAIN_WIDTH 5 /* AIF1DAC1_EQ_B1_GAIN - [15:11] */ +#define WM8995_AIF1DAC1_EQ_B2_GAIN_MASK 0x07C0 /* AIF1DAC1_EQ_B2_GAIN - [10:6] */ +#define WM8995_AIF1DAC1_EQ_B2_GAIN_SHIFT 6 /* AIF1DAC1_EQ_B2_GAIN - [10:6] */ +#define WM8995_AIF1DAC1_EQ_B2_GAIN_WIDTH 5 /* AIF1DAC1_EQ_B2_GAIN - [10:6] */ +#define WM8995_AIF1DAC1_EQ_B3_GAIN_MASK 0x003E /* AIF1DAC1_EQ_B3_GAIN - [5:1] */ +#define WM8995_AIF1DAC1_EQ_B3_GAIN_SHIFT 1 /* AIF1DAC1_EQ_B3_GAIN - [5:1] */ +#define WM8995_AIF1DAC1_EQ_B3_GAIN_WIDTH 5 /* AIF1DAC1_EQ_B3_GAIN - [5:1] */ +#define WM8995_AIF1DAC1_EQ_ENA 0x0001 /* AIF1DAC1_EQ_ENA */ +#define WM8995_AIF1DAC1_EQ_ENA_MASK 0x0001 /* AIF1DAC1_EQ_ENA */ +#define WM8995_AIF1DAC1_EQ_ENA_SHIFT 0 /* AIF1DAC1_EQ_ENA */ +#define WM8995_AIF1DAC1_EQ_ENA_WIDTH 1 /* AIF1DAC1_EQ_ENA */ + +/* + * R1153 (0x481) - AIF1 DAC1 EQ Gains (2) + */ +#define WM8995_AIF1DAC1_EQ_B4_GAIN_MASK 0xF800 /* AIF1DAC1_EQ_B4_GAIN - [15:11] */ +#define WM8995_AIF1DAC1_EQ_B4_GAIN_SHIFT 11 /* AIF1DAC1_EQ_B4_GAIN - [15:11] */ +#define WM8995_AIF1DAC1_EQ_B4_GAIN_WIDTH 5 /* AIF1DAC1_EQ_B4_GAIN - [15:11] */ +#define WM8995_AIF1DAC1_EQ_B5_GAIN_MASK 0x07C0 /* AIF1DAC1_EQ_B5_GAIN - [10:6] */ +#define WM8995_AIF1DAC1_EQ_B5_GAIN_SHIFT 6 /* AIF1DAC1_EQ_B5_GAIN - [10:6] */ +#define WM8995_AIF1DAC1_EQ_B5_GAIN_WIDTH 5 /* AIF1DAC1_EQ_B5_GAIN - [10:6] */ + +/* + * R1154 (0x482) - AIF1 DAC1 EQ Band 1 A + */ +#define WM8995_AIF1DAC1_EQ_B1_A_MASK 0xFFFF /* AIF1DAC1_EQ_B1_A - [15:0] */ +#define WM8995_AIF1DAC1_EQ_B1_A_SHIFT 0 /* AIF1DAC1_EQ_B1_A - [15:0] */ +#define WM8995_AIF1DAC1_EQ_B1_A_WIDTH 16 /* AIF1DAC1_EQ_B1_A - [15:0] */ + +/* + * R1155 (0x483) - AIF1 DAC1 EQ Band 1 B + */ +#define WM8995_AIF1DAC1_EQ_B1_B_MASK 0xFFFF /* AIF1DAC1_EQ_B1_B - [15:0] */ +#define WM8995_AIF1DAC1_EQ_B1_B_SHIFT 0 /* AIF1DAC1_EQ_B1_B - [15:0] */ +#define WM8995_AIF1DAC1_EQ_B1_B_WIDTH 16 /* AIF1DAC1_EQ_B1_B - [15:0] */ + +/* + * R1156 (0x484) - AIF1 DAC1 EQ Band 1 PG + */ +#define WM8995_AIF1DAC1_EQ_B1_PG_MASK 0xFFFF /* AIF1DAC1_EQ_B1_PG - [15:0] */ +#define WM8995_AIF1DAC1_EQ_B1_PG_SHIFT 0 /* AIF1DAC1_EQ_B1_PG - [15:0] */ +#define WM8995_AIF1DAC1_EQ_B1_PG_WIDTH 16 /* AIF1DAC1_EQ_B1_PG - [15:0] */ + +/* + * R1157 (0x485) - AIF1 DAC1 EQ Band 2 A + */ +#define WM8995_AIF1DAC1_EQ_B2_A_MASK 0xFFFF /* AIF1DAC1_EQ_B2_A - [15:0] */ +#define WM8995_AIF1DAC1_EQ_B2_A_SHIFT 0 /* AIF1DAC1_EQ_B2_A - [15:0] */ +#define WM8995_AIF1DAC1_EQ_B2_A_WIDTH 16 /* AIF1DAC1_EQ_B2_A - [15:0] */ + +/* + * R1158 (0x486) - AIF1 DAC1 EQ Band 2 B + */ +#define WM8995_AIF1DAC1_EQ_B2_B_MASK 0xFFFF /* AIF1DAC1_EQ_B2_B - [15:0] */ +#define WM8995_AIF1DAC1_EQ_B2_B_SHIFT 0 /* AIF1DAC1_EQ_B2_B - [15:0] */ +#define WM8995_AIF1DAC1_EQ_B2_B_WIDTH 16 /* AIF1DAC1_EQ_B2_B - [15:0] */ + +/* + * R1159 (0x487) - AIF1 DAC1 EQ Band 2 C + */ +#define WM8995_AIF1DAC1_EQ_B2_C_MASK 0xFFFF /* AIF1DAC1_EQ_B2_C - [15:0] */ +#define WM8995_AIF1DAC1_EQ_B2_C_SHIFT 0 /* AIF1DAC1_EQ_B2_C - [15:0] */ +#define WM8995_AIF1DAC1_EQ_B2_C_WIDTH 16 /* AIF1DAC1_EQ_B2_C - [15:0] */ + +/* + * R1160 (0x488) - AIF1 DAC1 EQ Band 2 PG + */ +#define WM8995_AIF1DAC1_EQ_B2_PG_MASK 0xFFFF /* AIF1DAC1_EQ_B2_PG - [15:0] */ +#define WM8995_AIF1DAC1_EQ_B2_PG_SHIFT 0 /* AIF1DAC1_EQ_B2_PG - [15:0] */ +#define WM8995_AIF1DAC1_EQ_B2_PG_WIDTH 16 /* AIF1DAC1_EQ_B2_PG - [15:0] */ + +/* + * R1161 (0x489) - AIF1 DAC1 EQ Band 3 A + */ +#define WM8995_AIF1DAC1_EQ_B3_A_MASK 0xFFFF /* AIF1DAC1_EQ_B3_A - [15:0] */ +#define WM8995_AIF1DAC1_EQ_B3_A_SHIFT 0 /* AIF1DAC1_EQ_B3_A - [15:0] */ +#define WM8995_AIF1DAC1_EQ_B3_A_WIDTH 16 /* AIF1DAC1_EQ_B3_A - [15:0] */ + +/* + * R1162 (0x48A) - AIF1 DAC1 EQ Band 3 B + */ +#define WM8995_AIF1DAC1_EQ_B3_B_MASK 0xFFFF /* AIF1DAC1_EQ_B3_B - [15:0] */ +#define WM8995_AIF1DAC1_EQ_B3_B_SHIFT 0 /* AIF1DAC1_EQ_B3_B - [15:0] */ +#define WM8995_AIF1DAC1_EQ_B3_B_WIDTH 16 /* AIF1DAC1_EQ_B3_B - [15:0] */ + +/* + * R1163 (0x48B) - AIF1 DAC1 EQ Band 3 C + */ +#define WM8995_AIF1DAC1_EQ_B3_C_MASK 0xFFFF /* AIF1DAC1_EQ_B3_C - [15:0] */ +#define WM8995_AIF1DAC1_EQ_B3_C_SHIFT 0 /* AIF1DAC1_EQ_B3_C - [15:0] */ +#define WM8995_AIF1DAC1_EQ_B3_C_WIDTH 16 /* AIF1DAC1_EQ_B3_C - [15:0] */ + +/* + * R1164 (0x48C) - AIF1 DAC1 EQ Band 3 PG + */ +#define WM8995_AIF1DAC1_EQ_B3_PG_MASK 0xFFFF /* AIF1DAC1_EQ_B3_PG - [15:0] */ +#define WM8995_AIF1DAC1_EQ_B3_PG_SHIFT 0 /* AIF1DAC1_EQ_B3_PG - [15:0] */ +#define WM8995_AIF1DAC1_EQ_B3_PG_WIDTH 16 /* AIF1DAC1_EQ_B3_PG - [15:0] */ + +/* + * R1165 (0x48D) - AIF1 DAC1 EQ Band 4 A + */ +#define WM8995_AIF1DAC1_EQ_B4_A_MASK 0xFFFF /* AIF1DAC1_EQ_B4_A - [15:0] */ +#define WM8995_AIF1DAC1_EQ_B4_A_SHIFT 0 /* AIF1DAC1_EQ_B4_A - [15:0] */ +#define WM8995_AIF1DAC1_EQ_B4_A_WIDTH 16 /* AIF1DAC1_EQ_B4_A - [15:0] */ + +/* + * R1166 (0x48E) - AIF1 DAC1 EQ Band 4 B + */ +#define WM8995_AIF1DAC1_EQ_B4_B_MASK 0xFFFF /* AIF1DAC1_EQ_B4_B - [15:0] */ +#define WM8995_AIF1DAC1_EQ_B4_B_SHIFT 0 /* AIF1DAC1_EQ_B4_B - [15:0] */ +#define WM8995_AIF1DAC1_EQ_B4_B_WIDTH 16 /* AIF1DAC1_EQ_B4_B - [15:0] */ + +/* + * R1167 (0x48F) - AIF1 DAC1 EQ Band 4 C + */ +#define WM8995_AIF1DAC1_EQ_B4_C_MASK 0xFFFF /* AIF1DAC1_EQ_B4_C - [15:0] */ +#define WM8995_AIF1DAC1_EQ_B4_C_SHIFT 0 /* AIF1DAC1_EQ_B4_C - [15:0] */ +#define WM8995_AIF1DAC1_EQ_B4_C_WIDTH 16 /* AIF1DAC1_EQ_B4_C - [15:0] */ + +/* + * R1168 (0x490) - AIF1 DAC1 EQ Band 4 PG + */ +#define WM8995_AIF1DAC1_EQ_B4_PG_MASK 0xFFFF /* AIF1DAC1_EQ_B4_PG - [15:0] */ +#define WM8995_AIF1DAC1_EQ_B4_PG_SHIFT 0 /* AIF1DAC1_EQ_B4_PG - [15:0] */ +#define WM8995_AIF1DAC1_EQ_B4_PG_WIDTH 16 /* AIF1DAC1_EQ_B4_PG - [15:0] */ + +/* + * R1169 (0x491) - AIF1 DAC1 EQ Band 5 A + */ +#define WM8995_AIF1DAC1_EQ_B5_A_MASK 0xFFFF /* AIF1DAC1_EQ_B5_A - [15:0] */ +#define WM8995_AIF1DAC1_EQ_B5_A_SHIFT 0 /* AIF1DAC1_EQ_B5_A - [15:0] */ +#define WM8995_AIF1DAC1_EQ_B5_A_WIDTH 16 /* AIF1DAC1_EQ_B5_A - [15:0] */ + +/* + * R1170 (0x492) - AIF1 DAC1 EQ Band 5 B + */ +#define WM8995_AIF1DAC1_EQ_B5_B_MASK 0xFFFF /* AIF1DAC1_EQ_B5_B - [15:0] */ +#define WM8995_AIF1DAC1_EQ_B5_B_SHIFT 0 /* AIF1DAC1_EQ_B5_B - [15:0] */ +#define WM8995_AIF1DAC1_EQ_B5_B_WIDTH 16 /* AIF1DAC1_EQ_B5_B - [15:0] */ + +/* + * R1171 (0x493) - AIF1 DAC1 EQ Band 5 PG + */ +#define WM8995_AIF1DAC1_EQ_B5_PG_MASK 0xFFFF /* AIF1DAC1_EQ_B5_PG - [15:0] */ +#define WM8995_AIF1DAC1_EQ_B5_PG_SHIFT 0 /* AIF1DAC1_EQ_B5_PG - [15:0] */ +#define WM8995_AIF1DAC1_EQ_B5_PG_WIDTH 16 /* AIF1DAC1_EQ_B5_PG - [15:0] */ + +/* + * R1184 (0x4A0) - AIF1 DAC2 EQ Gains (1) + */ +#define WM8995_AIF1DAC2_EQ_B1_GAIN_MASK 0xF800 /* AIF1DAC2_EQ_B1_GAIN - [15:11] */ +#define WM8995_AIF1DAC2_EQ_B1_GAIN_SHIFT 11 /* AIF1DAC2_EQ_B1_GAIN - [15:11] */ +#define WM8995_AIF1DAC2_EQ_B1_GAIN_WIDTH 5 /* AIF1DAC2_EQ_B1_GAIN - [15:11] */ +#define WM8995_AIF1DAC2_EQ_B2_GAIN_MASK 0x07C0 /* AIF1DAC2_EQ_B2_GAIN - [10:6] */ +#define WM8995_AIF1DAC2_EQ_B2_GAIN_SHIFT 6 /* AIF1DAC2_EQ_B2_GAIN - [10:6] */ +#define WM8995_AIF1DAC2_EQ_B2_GAIN_WIDTH 5 /* AIF1DAC2_EQ_B2_GAIN - [10:6] */ +#define WM8995_AIF1DAC2_EQ_B3_GAIN_MASK 0x003E /* AIF1DAC2_EQ_B3_GAIN - [5:1] */ +#define WM8995_AIF1DAC2_EQ_B3_GAIN_SHIFT 1 /* AIF1DAC2_EQ_B3_GAIN - [5:1] */ +#define WM8995_AIF1DAC2_EQ_B3_GAIN_WIDTH 5 /* AIF1DAC2_EQ_B3_GAIN - [5:1] */ +#define WM8995_AIF1DAC2_EQ_ENA 0x0001 /* AIF1DAC2_EQ_ENA */ +#define WM8995_AIF1DAC2_EQ_ENA_MASK 0x0001 /* AIF1DAC2_EQ_ENA */ +#define WM8995_AIF1DAC2_EQ_ENA_SHIFT 0 /* AIF1DAC2_EQ_ENA */ +#define WM8995_AIF1DAC2_EQ_ENA_WIDTH 1 /* AIF1DAC2_EQ_ENA */ + +/* + * R1185 (0x4A1) - AIF1 DAC2 EQ Gains (2) + */ +#define WM8995_AIF1DAC2_EQ_B4_GAIN_MASK 0xF800 /* AIF1DAC2_EQ_B4_GAIN - [15:11] */ +#define WM8995_AIF1DAC2_EQ_B4_GAIN_SHIFT 11 /* AIF1DAC2_EQ_B4_GAIN - [15:11] */ +#define WM8995_AIF1DAC2_EQ_B4_GAIN_WIDTH 5 /* AIF1DAC2_EQ_B4_GAIN - [15:11] */ +#define WM8995_AIF1DAC2_EQ_B5_GAIN_MASK 0x07C0 /* AIF1DAC2_EQ_B5_GAIN - [10:6] */ +#define WM8995_AIF1DAC2_EQ_B5_GAIN_SHIFT 6 /* AIF1DAC2_EQ_B5_GAIN - [10:6] */ +#define WM8995_AIF1DAC2_EQ_B5_GAIN_WIDTH 5 /* AIF1DAC2_EQ_B5_GAIN - [10:6] */ + +/* + * R1186 (0x4A2) - AIF1 DAC2 EQ Band 1 A + */ +#define WM8995_AIF1DAC2_EQ_B1_A_MASK 0xFFFF /* AIF1DAC2_EQ_B1_A - [15:0] */ +#define WM8995_AIF1DAC2_EQ_B1_A_SHIFT 0 /* AIF1DAC2_EQ_B1_A - [15:0] */ +#define WM8995_AIF1DAC2_EQ_B1_A_WIDTH 16 /* AIF1DAC2_EQ_B1_A - [15:0] */ + +/* + * R1187 (0x4A3) - AIF1 DAC2 EQ Band 1 B + */ +#define WM8995_AIF1DAC2_EQ_B1_B_MASK 0xFFFF /* AIF1DAC2_EQ_B1_B - [15:0] */ +#define WM8995_AIF1DAC2_EQ_B1_B_SHIFT 0 /* AIF1DAC2_EQ_B1_B - [15:0] */ +#define WM8995_AIF1DAC2_EQ_B1_B_WIDTH 16 /* AIF1DAC2_EQ_B1_B - [15:0] */ + +/* + * R1188 (0x4A4) - AIF1 DAC2 EQ Band 1 PG + */ +#define WM8995_AIF1DAC2_EQ_B1_PG_MASK 0xFFFF /* AIF1DAC2_EQ_B1_PG - [15:0] */ +#define WM8995_AIF1DAC2_EQ_B1_PG_SHIFT 0 /* AIF1DAC2_EQ_B1_PG - [15:0] */ +#define WM8995_AIF1DAC2_EQ_B1_PG_WIDTH 16 /* AIF1DAC2_EQ_B1_PG - [15:0] */ + +/* + * R1189 (0x4A5) - AIF1 DAC2 EQ Band 2 A + */ +#define WM8995_AIF1DAC2_EQ_B2_A_MASK 0xFFFF /* AIF1DAC2_EQ_B2_A - [15:0] */ +#define WM8995_AIF1DAC2_EQ_B2_A_SHIFT 0 /* AIF1DAC2_EQ_B2_A - [15:0] */ +#define WM8995_AIF1DAC2_EQ_B2_A_WIDTH 16 /* AIF1DAC2_EQ_B2_A - [15:0] */ + +/* + * R1190 (0x4A6) - AIF1 DAC2 EQ Band 2 B + */ +#define WM8995_AIF1DAC2_EQ_B2_B_MASK 0xFFFF /* AIF1DAC2_EQ_B2_B - [15:0] */ +#define WM8995_AIF1DAC2_EQ_B2_B_SHIFT 0 /* AIF1DAC2_EQ_B2_B - [15:0] */ +#define WM8995_AIF1DAC2_EQ_B2_B_WIDTH 16 /* AIF1DAC2_EQ_B2_B - [15:0] */ + +/* + * R1191 (0x4A7) - AIF1 DAC2 EQ Band 2 C + */ +#define WM8995_AIF1DAC2_EQ_B2_C_MASK 0xFFFF /* AIF1DAC2_EQ_B2_C - [15:0] */ +#define WM8995_AIF1DAC2_EQ_B2_C_SHIFT 0 /* AIF1DAC2_EQ_B2_C - [15:0] */ +#define WM8995_AIF1DAC2_EQ_B2_C_WIDTH 16 /* AIF1DAC2_EQ_B2_C - [15:0] */ + +/* + * R1192 (0x4A8) - AIF1 DAC2 EQ Band 2 PG + */ +#define WM8995_AIF1DAC2_EQ_B2_PG_MASK 0xFFFF /* AIF1DAC2_EQ_B2_PG - [15:0] */ +#define WM8995_AIF1DAC2_EQ_B2_PG_SHIFT 0 /* AIF1DAC2_EQ_B2_PG - [15:0] */ +#define WM8995_AIF1DAC2_EQ_B2_PG_WIDTH 16 /* AIF1DAC2_EQ_B2_PG - [15:0] */ + +/* + * R1193 (0x4A9) - AIF1 DAC2 EQ Band 3 A + */ +#define WM8995_AIF1DAC2_EQ_B3_A_MASK 0xFFFF /* AIF1DAC2_EQ_B3_A - [15:0] */ +#define WM8995_AIF1DAC2_EQ_B3_A_SHIFT 0 /* AIF1DAC2_EQ_B3_A - [15:0] */ +#define WM8995_AIF1DAC2_EQ_B3_A_WIDTH 16 /* AIF1DAC2_EQ_B3_A - [15:0] */ + +/* + * R1194 (0x4AA) - AIF1 DAC2 EQ Band 3 B + */ +#define WM8995_AIF1DAC2_EQ_B3_B_MASK 0xFFFF /* AIF1DAC2_EQ_B3_B - [15:0] */ +#define WM8995_AIF1DAC2_EQ_B3_B_SHIFT 0 /* AIF1DAC2_EQ_B3_B - [15:0] */ +#define WM8995_AIF1DAC2_EQ_B3_B_WIDTH 16 /* AIF1DAC2_EQ_B3_B - [15:0] */ + +/* + * R1195 (0x4AB) - AIF1 DAC2 EQ Band 3 C + */ +#define WM8995_AIF1DAC2_EQ_B3_C_MASK 0xFFFF /* AIF1DAC2_EQ_B3_C - [15:0] */ +#define WM8995_AIF1DAC2_EQ_B3_C_SHIFT 0 /* AIF1DAC2_EQ_B3_C - [15:0] */ +#define WM8995_AIF1DAC2_EQ_B3_C_WIDTH 16 /* AIF1DAC2_EQ_B3_C - [15:0] */ + +/* + * R1196 (0x4AC) - AIF1 DAC2 EQ Band 3 PG + */ +#define WM8995_AIF1DAC2_EQ_B3_PG_MASK 0xFFFF /* AIF1DAC2_EQ_B3_PG - [15:0] */ +#define WM8995_AIF1DAC2_EQ_B3_PG_SHIFT 0 /* AIF1DAC2_EQ_B3_PG - [15:0] */ +#define WM8995_AIF1DAC2_EQ_B3_PG_WIDTH 16 /* AIF1DAC2_EQ_B3_PG - [15:0] */ + +/* + * R1197 (0x4AD) - AIF1 DAC2 EQ Band 4 A + */ +#define WM8995_AIF1DAC2_EQ_B4_A_MASK 0xFFFF /* AIF1DAC2_EQ_B4_A - [15:0] */ +#define WM8995_AIF1DAC2_EQ_B4_A_SHIFT 0 /* AIF1DAC2_EQ_B4_A - [15:0] */ +#define WM8995_AIF1DAC2_EQ_B4_A_WIDTH 16 /* AIF1DAC2_EQ_B4_A - [15:0] */ + +/* + * R1198 (0x4AE) - AIF1 DAC2 EQ Band 4 B + */ +#define WM8995_AIF1DAC2_EQ_B4_B_MASK 0xFFFF /* AIF1DAC2_EQ_B4_B - [15:0] */ +#define WM8995_AIF1DAC2_EQ_B4_B_SHIFT 0 /* AIF1DAC2_EQ_B4_B - [15:0] */ +#define WM8995_AIF1DAC2_EQ_B4_B_WIDTH 16 /* AIF1DAC2_EQ_B4_B - [15:0] */ + +/* + * R1199 (0x4AF) - AIF1 DAC2 EQ Band 4 C + */ +#define WM8995_AIF1DAC2_EQ_B4_C_MASK 0xFFFF /* AIF1DAC2_EQ_B4_C - [15:0] */ +#define WM8995_AIF1DAC2_EQ_B4_C_SHIFT 0 /* AIF1DAC2_EQ_B4_C - [15:0] */ +#define WM8995_AIF1DAC2_EQ_B4_C_WIDTH 16 /* AIF1DAC2_EQ_B4_C - [15:0] */ + +/* + * R1200 (0x4B0) - AIF1 DAC2 EQ Band 4 PG + */ +#define WM8995_AIF1DAC2_EQ_B4_PG_MASK 0xFFFF /* AIF1DAC2_EQ_B4_PG - [15:0] */ +#define WM8995_AIF1DAC2_EQ_B4_PG_SHIFT 0 /* AIF1DAC2_EQ_B4_PG - [15:0] */ +#define WM8995_AIF1DAC2_EQ_B4_PG_WIDTH 16 /* AIF1DAC2_EQ_B4_PG - [15:0] */ + +/* + * R1201 (0x4B1) - AIF1 DAC2 EQ Band 5 A + */ +#define WM8995_AIF1DAC2_EQ_B5_A_MASK 0xFFFF /* AIF1DAC2_EQ_B5_A - [15:0] */ +#define WM8995_AIF1DAC2_EQ_B5_A_SHIFT 0 /* AIF1DAC2_EQ_B5_A - [15:0] */ +#define WM8995_AIF1DAC2_EQ_B5_A_WIDTH 16 /* AIF1DAC2_EQ_B5_A - [15:0] */ + +/* + * R1202 (0x4B2) - AIF1 DAC2 EQ Band 5 B + */ +#define WM8995_AIF1DAC2_EQ_B5_B_MASK 0xFFFF /* AIF1DAC2_EQ_B5_B - [15:0] */ +#define WM8995_AIF1DAC2_EQ_B5_B_SHIFT 0 /* AIF1DAC2_EQ_B5_B - [15:0] */ +#define WM8995_AIF1DAC2_EQ_B5_B_WIDTH 16 /* AIF1DAC2_EQ_B5_B - [15:0] */ + +/* + * R1203 (0x4B3) - AIF1 DAC2 EQ Band 5 PG + */ +#define WM8995_AIF1DAC2_EQ_B5_PG_MASK 0xFFFF /* AIF1DAC2_EQ_B5_PG - [15:0] */ +#define WM8995_AIF1DAC2_EQ_B5_PG_SHIFT 0 /* AIF1DAC2_EQ_B5_PG - [15:0] */ +#define WM8995_AIF1DAC2_EQ_B5_PG_WIDTH 16 /* AIF1DAC2_EQ_B5_PG - [15:0] */ + +/* + * R1280 (0x500) - AIF2 ADC Left Volume + */ +#define WM8995_AIF2ADC_VU 0x0100 /* AIF2ADC_VU */ +#define WM8995_AIF2ADC_VU_MASK 0x0100 /* AIF2ADC_VU */ +#define WM8995_AIF2ADC_VU_SHIFT 8 /* AIF2ADC_VU */ +#define WM8995_AIF2ADC_VU_WIDTH 1 /* AIF2ADC_VU */ +#define WM8995_AIF2ADCL_VOL_MASK 0x00FF /* AIF2ADCL_VOL - [7:0] */ +#define WM8995_AIF2ADCL_VOL_SHIFT 0 /* AIF2ADCL_VOL - [7:0] */ +#define WM8995_AIF2ADCL_VOL_WIDTH 8 /* AIF2ADCL_VOL - [7:0] */ + +/* + * R1281 (0x501) - AIF2 ADC Right Volume + */ +#define WM8995_AIF2ADC_VU 0x0100 /* AIF2ADC_VU */ +#define WM8995_AIF2ADC_VU_MASK 0x0100 /* AIF2ADC_VU */ +#define WM8995_AIF2ADC_VU_SHIFT 8 /* AIF2ADC_VU */ +#define WM8995_AIF2ADC_VU_WIDTH 1 /* AIF2ADC_VU */ +#define WM8995_AIF2ADCR_VOL_MASK 0x00FF /* AIF2ADCR_VOL - [7:0] */ +#define WM8995_AIF2ADCR_VOL_SHIFT 0 /* AIF2ADCR_VOL - [7:0] */ +#define WM8995_AIF2ADCR_VOL_WIDTH 8 /* AIF2ADCR_VOL - [7:0] */ + +/* + * R1282 (0x502) - AIF2 DAC Left Volume + */ +#define WM8995_AIF2DAC_VU 0x0100 /* AIF2DAC_VU */ +#define WM8995_AIF2DAC_VU_MASK 0x0100 /* AIF2DAC_VU */ +#define WM8995_AIF2DAC_VU_SHIFT 8 /* AIF2DAC_VU */ +#define WM8995_AIF2DAC_VU_WIDTH 1 /* AIF2DAC_VU */ +#define WM8995_AIF2DACL_VOL_MASK 0x00FF /* AIF2DACL_VOL - [7:0] */ +#define WM8995_AIF2DACL_VOL_SHIFT 0 /* AIF2DACL_VOL - [7:0] */ +#define WM8995_AIF2DACL_VOL_WIDTH 8 /* AIF2DACL_VOL - [7:0] */ + +/* + * R1283 (0x503) - AIF2 DAC Right Volume + */ +#define WM8995_AIF2DAC_VU 0x0100 /* AIF2DAC_VU */ +#define WM8995_AIF2DAC_VU_MASK 0x0100 /* AIF2DAC_VU */ +#define WM8995_AIF2DAC_VU_SHIFT 8 /* AIF2DAC_VU */ +#define WM8995_AIF2DAC_VU_WIDTH 1 /* AIF2DAC_VU */ +#define WM8995_AIF2DACR_VOL_MASK 0x00FF /* AIF2DACR_VOL - [7:0] */ +#define WM8995_AIF2DACR_VOL_SHIFT 0 /* AIF2DACR_VOL - [7:0] */ +#define WM8995_AIF2DACR_VOL_WIDTH 8 /* AIF2DACR_VOL - [7:0] */ + +/* + * R1296 (0x510) - AIF2 ADC Filters + */ +#define WM8995_AIF2ADC_4FS 0x8000 /* AIF2ADC_4FS */ +#define WM8995_AIF2ADC_4FS_MASK 0x8000 /* AIF2ADC_4FS */ +#define WM8995_AIF2ADC_4FS_SHIFT 15 /* AIF2ADC_4FS */ +#define WM8995_AIF2ADC_4FS_WIDTH 1 /* AIF2ADC_4FS */ +#define WM8995_AIF2ADCL_HPF 0x1000 /* AIF2ADCL_HPF */ +#define WM8995_AIF2ADCL_HPF_MASK 0x1000 /* AIF2ADCL_HPF */ +#define WM8995_AIF2ADCL_HPF_SHIFT 12 /* AIF2ADCL_HPF */ +#define WM8995_AIF2ADCL_HPF_WIDTH 1 /* AIF2ADCL_HPF */ +#define WM8995_AIF2ADCR_HPF 0x0800 /* AIF2ADCR_HPF */ +#define WM8995_AIF2ADCR_HPF_MASK 0x0800 /* AIF2ADCR_HPF */ +#define WM8995_AIF2ADCR_HPF_SHIFT 11 /* AIF2ADCR_HPF */ +#define WM8995_AIF2ADCR_HPF_WIDTH 1 /* AIF2ADCR_HPF */ +#define WM8995_AIF2ADC_HPF_MODE 0x0008 /* AIF2ADC_HPF_MODE */ +#define WM8995_AIF2ADC_HPF_MODE_MASK 0x0008 /* AIF2ADC_HPF_MODE */ +#define WM8995_AIF2ADC_HPF_MODE_SHIFT 3 /* AIF2ADC_HPF_MODE */ +#define WM8995_AIF2ADC_HPF_MODE_WIDTH 1 /* AIF2ADC_HPF_MODE */ +#define WM8995_AIF2ADC_HPF_CUT_MASK 0x0007 /* AIF2ADC_HPF_CUT - [2:0] */ +#define WM8995_AIF2ADC_HPF_CUT_SHIFT 0 /* AIF2ADC_HPF_CUT - [2:0] */ +#define WM8995_AIF2ADC_HPF_CUT_WIDTH 3 /* AIF2ADC_HPF_CUT - [2:0] */ + +/* + * R1312 (0x520) - AIF2 DAC Filters (1) + */ +#define WM8995_AIF2DAC_MUTE 0x0200 /* AIF2DAC_MUTE */ +#define WM8995_AIF2DAC_MUTE_MASK 0x0200 /* AIF2DAC_MUTE */ +#define WM8995_AIF2DAC_MUTE_SHIFT 9 /* AIF2DAC_MUTE */ +#define WM8995_AIF2DAC_MUTE_WIDTH 1 /* AIF2DAC_MUTE */ +#define WM8995_AIF2DAC_MONO 0x0080 /* AIF2DAC_MONO */ +#define WM8995_AIF2DAC_MONO_MASK 0x0080 /* AIF2DAC_MONO */ +#define WM8995_AIF2DAC_MONO_SHIFT 7 /* AIF2DAC_MONO */ +#define WM8995_AIF2DAC_MONO_WIDTH 1 /* AIF2DAC_MONO */ +#define WM8995_AIF2DAC_MUTERATE 0x0020 /* AIF2DAC_MUTERATE */ +#define WM8995_AIF2DAC_MUTERATE_MASK 0x0020 /* AIF2DAC_MUTERATE */ +#define WM8995_AIF2DAC_MUTERATE_SHIFT 5 /* AIF2DAC_MUTERATE */ +#define WM8995_AIF2DAC_MUTERATE_WIDTH 1 /* AIF2DAC_MUTERATE */ +#define WM8995_AIF2DAC_UNMUTE_RAMP 0x0010 /* AIF2DAC_UNMUTE_RAMP */ +#define WM8995_AIF2DAC_UNMUTE_RAMP_MASK 0x0010 /* AIF2DAC_UNMUTE_RAMP */ +#define WM8995_AIF2DAC_UNMUTE_RAMP_SHIFT 4 /* AIF2DAC_UNMUTE_RAMP */ +#define WM8995_AIF2DAC_UNMUTE_RAMP_WIDTH 1 /* AIF2DAC_UNMUTE_RAMP */ +#define WM8995_AIF2DAC_DEEMP_MASK 0x0006 /* AIF2DAC_DEEMP - [2:1] */ +#define WM8995_AIF2DAC_DEEMP_SHIFT 1 /* AIF2DAC_DEEMP - [2:1] */ +#define WM8995_AIF2DAC_DEEMP_WIDTH 2 /* AIF2DAC_DEEMP - [2:1] */ + +/* + * R1313 (0x521) - AIF2 DAC Filters (2) + */ +#define WM8995_AIF2DAC_3D_GAIN_MASK 0x3E00 /* AIF2DAC_3D_GAIN - [13:9] */ +#define WM8995_AIF2DAC_3D_GAIN_SHIFT 9 /* AIF2DAC_3D_GAIN - [13:9] */ +#define WM8995_AIF2DAC_3D_GAIN_WIDTH 5 /* AIF2DAC_3D_GAIN - [13:9] */ +#define WM8995_AIF2DAC_3D_ENA 0x0100 /* AIF2DAC_3D_ENA */ +#define WM8995_AIF2DAC_3D_ENA_MASK 0x0100 /* AIF2DAC_3D_ENA */ +#define WM8995_AIF2DAC_3D_ENA_SHIFT 8 /* AIF2DAC_3D_ENA */ +#define WM8995_AIF2DAC_3D_ENA_WIDTH 1 /* AIF2DAC_3D_ENA */ + +/* + * R1344 (0x540) - AIF2 DRC (1) + */ +#define WM8995_AIF2DRC_SIG_DET_RMS_MASK 0xF800 /* AIF2DRC_SIG_DET_RMS - [15:11] */ +#define WM8995_AIF2DRC_SIG_DET_RMS_SHIFT 11 /* AIF2DRC_SIG_DET_RMS - [15:11] */ +#define WM8995_AIF2DRC_SIG_DET_RMS_WIDTH 5 /* AIF2DRC_SIG_DET_RMS - [15:11] */ +#define WM8995_AIF2DRC_SIG_DET_PK_MASK 0x0600 /* AIF2DRC_SIG_DET_PK - [10:9] */ +#define WM8995_AIF2DRC_SIG_DET_PK_SHIFT 9 /* AIF2DRC_SIG_DET_PK - [10:9] */ +#define WM8995_AIF2DRC_SIG_DET_PK_WIDTH 2 /* AIF2DRC_SIG_DET_PK - [10:9] */ +#define WM8995_AIF2DRC_NG_ENA 0x0100 /* AIF2DRC_NG_ENA */ +#define WM8995_AIF2DRC_NG_ENA_MASK 0x0100 /* AIF2DRC_NG_ENA */ +#define WM8995_AIF2DRC_NG_ENA_SHIFT 8 /* AIF2DRC_NG_ENA */ +#define WM8995_AIF2DRC_NG_ENA_WIDTH 1 /* AIF2DRC_NG_ENA */ +#define WM8995_AIF2DRC_SIG_DET_MODE 0x0080 /* AIF2DRC_SIG_DET_MODE */ +#define WM8995_AIF2DRC_SIG_DET_MODE_MASK 0x0080 /* AIF2DRC_SIG_DET_MODE */ +#define WM8995_AIF2DRC_SIG_DET_MODE_SHIFT 7 /* AIF2DRC_SIG_DET_MODE */ +#define WM8995_AIF2DRC_SIG_DET_MODE_WIDTH 1 /* AIF2DRC_SIG_DET_MODE */ +#define WM8995_AIF2DRC_SIG_DET 0x0040 /* AIF2DRC_SIG_DET */ +#define WM8995_AIF2DRC_SIG_DET_MASK 0x0040 /* AIF2DRC_SIG_DET */ +#define WM8995_AIF2DRC_SIG_DET_SHIFT 6 /* AIF2DRC_SIG_DET */ +#define WM8995_AIF2DRC_SIG_DET_WIDTH 1 /* AIF2DRC_SIG_DET */ +#define WM8995_AIF2DRC_KNEE2_OP_ENA 0x0020 /* AIF2DRC_KNEE2_OP_ENA */ +#define WM8995_AIF2DRC_KNEE2_OP_ENA_MASK 0x0020 /* AIF2DRC_KNEE2_OP_ENA */ +#define WM8995_AIF2DRC_KNEE2_OP_ENA_SHIFT 5 /* AIF2DRC_KNEE2_OP_ENA */ +#define WM8995_AIF2DRC_KNEE2_OP_ENA_WIDTH 1 /* AIF2DRC_KNEE2_OP_ENA */ +#define WM8995_AIF2DRC_QR 0x0010 /* AIF2DRC_QR */ +#define WM8995_AIF2DRC_QR_MASK 0x0010 /* AIF2DRC_QR */ +#define WM8995_AIF2DRC_QR_SHIFT 4 /* AIF2DRC_QR */ +#define WM8995_AIF2DRC_QR_WIDTH 1 /* AIF2DRC_QR */ +#define WM8995_AIF2DRC_ANTICLIP 0x0008 /* AIF2DRC_ANTICLIP */ +#define WM8995_AIF2DRC_ANTICLIP_MASK 0x0008 /* AIF2DRC_ANTICLIP */ +#define WM8995_AIF2DRC_ANTICLIP_SHIFT 3 /* AIF2DRC_ANTICLIP */ +#define WM8995_AIF2DRC_ANTICLIP_WIDTH 1 /* AIF2DRC_ANTICLIP */ +#define WM8995_AIF2DAC_DRC_ENA 0x0004 /* AIF2DAC_DRC_ENA */ +#define WM8995_AIF2DAC_DRC_ENA_MASK 0x0004 /* AIF2DAC_DRC_ENA */ +#define WM8995_AIF2DAC_DRC_ENA_SHIFT 2 /* AIF2DAC_DRC_ENA */ +#define WM8995_AIF2DAC_DRC_ENA_WIDTH 1 /* AIF2DAC_DRC_ENA */ +#define WM8995_AIF2ADCL_DRC_ENA 0x0002 /* AIF2ADCL_DRC_ENA */ +#define WM8995_AIF2ADCL_DRC_ENA_MASK 0x0002 /* AIF2ADCL_DRC_ENA */ +#define WM8995_AIF2ADCL_DRC_ENA_SHIFT 1 /* AIF2ADCL_DRC_ENA */ +#define WM8995_AIF2ADCL_DRC_ENA_WIDTH 1 /* AIF2ADCL_DRC_ENA */ +#define WM8995_AIF2ADCR_DRC_ENA 0x0001 /* AIF2ADCR_DRC_ENA */ +#define WM8995_AIF2ADCR_DRC_ENA_MASK 0x0001 /* AIF2ADCR_DRC_ENA */ +#define WM8995_AIF2ADCR_DRC_ENA_SHIFT 0 /* AIF2ADCR_DRC_ENA */ +#define WM8995_AIF2ADCR_DRC_ENA_WIDTH 1 /* AIF2ADCR_DRC_ENA */ + +/* + * R1345 (0x541) - AIF2 DRC (2) + */ +#define WM8995_AIF2DRC_ATK_MASK 0x1E00 /* AIF2DRC_ATK - [12:9] */ +#define WM8995_AIF2DRC_ATK_SHIFT 9 /* AIF2DRC_ATK - [12:9] */ +#define WM8995_AIF2DRC_ATK_WIDTH 4 /* AIF2DRC_ATK - [12:9] */ +#define WM8995_AIF2DRC_DCY_MASK 0x01E0 /* AIF2DRC_DCY - [8:5] */ +#define WM8995_AIF2DRC_DCY_SHIFT 5 /* AIF2DRC_DCY - [8:5] */ +#define WM8995_AIF2DRC_DCY_WIDTH 4 /* AIF2DRC_DCY - [8:5] */ +#define WM8995_AIF2DRC_MINGAIN_MASK 0x001C /* AIF2DRC_MINGAIN - [4:2] */ +#define WM8995_AIF2DRC_MINGAIN_SHIFT 2 /* AIF2DRC_MINGAIN - [4:2] */ +#define WM8995_AIF2DRC_MINGAIN_WIDTH 3 /* AIF2DRC_MINGAIN - [4:2] */ +#define WM8995_AIF2DRC_MAXGAIN_MASK 0x0003 /* AIF2DRC_MAXGAIN - [1:0] */ +#define WM8995_AIF2DRC_MAXGAIN_SHIFT 0 /* AIF2DRC_MAXGAIN - [1:0] */ +#define WM8995_AIF2DRC_MAXGAIN_WIDTH 2 /* AIF2DRC_MAXGAIN - [1:0] */ + +/* + * R1346 (0x542) - AIF2 DRC (3) + */ +#define WM8995_AIF2DRC_NG_MINGAIN_MASK 0xF000 /* AIF2DRC_NG_MINGAIN - [15:12] */ +#define WM8995_AIF2DRC_NG_MINGAIN_SHIFT 12 /* AIF2DRC_NG_MINGAIN - [15:12] */ +#define WM8995_AIF2DRC_NG_MINGAIN_WIDTH 4 /* AIF2DRC_NG_MINGAIN - [15:12] */ +#define WM8995_AIF2DRC_NG_EXP_MASK 0x0C00 /* AIF2DRC_NG_EXP - [11:10] */ +#define WM8995_AIF2DRC_NG_EXP_SHIFT 10 /* AIF2DRC_NG_EXP - [11:10] */ +#define WM8995_AIF2DRC_NG_EXP_WIDTH 2 /* AIF2DRC_NG_EXP - [11:10] */ +#define WM8995_AIF2DRC_QR_THR_MASK 0x0300 /* AIF2DRC_QR_THR - [9:8] */ +#define WM8995_AIF2DRC_QR_THR_SHIFT 8 /* AIF2DRC_QR_THR - [9:8] */ +#define WM8995_AIF2DRC_QR_THR_WIDTH 2 /* AIF2DRC_QR_THR - [9:8] */ +#define WM8995_AIF2DRC_QR_DCY_MASK 0x00C0 /* AIF2DRC_QR_DCY - [7:6] */ +#define WM8995_AIF2DRC_QR_DCY_SHIFT 6 /* AIF2DRC_QR_DCY - [7:6] */ +#define WM8995_AIF2DRC_QR_DCY_WIDTH 2 /* AIF2DRC_QR_DCY - [7:6] */ +#define WM8995_AIF2DRC_HI_COMP_MASK 0x0038 /* AIF2DRC_HI_COMP - [5:3] */ +#define WM8995_AIF2DRC_HI_COMP_SHIFT 3 /* AIF2DRC_HI_COMP - [5:3] */ +#define WM8995_AIF2DRC_HI_COMP_WIDTH 3 /* AIF2DRC_HI_COMP - [5:3] */ +#define WM8995_AIF2DRC_LO_COMP_MASK 0x0007 /* AIF2DRC_LO_COMP - [2:0] */ +#define WM8995_AIF2DRC_LO_COMP_SHIFT 0 /* AIF2DRC_LO_COMP - [2:0] */ +#define WM8995_AIF2DRC_LO_COMP_WIDTH 3 /* AIF2DRC_LO_COMP - [2:0] */ + +/* + * R1347 (0x543) - AIF2 DRC (4) + */ +#define WM8995_AIF2DRC_KNEE_IP_MASK 0x07E0 /* AIF2DRC_KNEE_IP - [10:5] */ +#define WM8995_AIF2DRC_KNEE_IP_SHIFT 5 /* AIF2DRC_KNEE_IP - [10:5] */ +#define WM8995_AIF2DRC_KNEE_IP_WIDTH 6 /* AIF2DRC_KNEE_IP - [10:5] */ +#define WM8995_AIF2DRC_KNEE_OP_MASK 0x001F /* AIF2DRC_KNEE_OP - [4:0] */ +#define WM8995_AIF2DRC_KNEE_OP_SHIFT 0 /* AIF2DRC_KNEE_OP - [4:0] */ +#define WM8995_AIF2DRC_KNEE_OP_WIDTH 5 /* AIF2DRC_KNEE_OP - [4:0] */ + +/* + * R1348 (0x544) - AIF2 DRC (5) + */ +#define WM8995_AIF2DRC_KNEE2_IP_MASK 0x03E0 /* AIF2DRC_KNEE2_IP - [9:5] */ +#define WM8995_AIF2DRC_KNEE2_IP_SHIFT 5 /* AIF2DRC_KNEE2_IP - [9:5] */ +#define WM8995_AIF2DRC_KNEE2_IP_WIDTH 5 /* AIF2DRC_KNEE2_IP - [9:5] */ +#define WM8995_AIF2DRC_KNEE2_OP_MASK 0x001F /* AIF2DRC_KNEE2_OP - [4:0] */ +#define WM8995_AIF2DRC_KNEE2_OP_SHIFT 0 /* AIF2DRC_KNEE2_OP - [4:0] */ +#define WM8995_AIF2DRC_KNEE2_OP_WIDTH 5 /* AIF2DRC_KNEE2_OP - [4:0] */ + +/* + * R1408 (0x580) - AIF2 EQ Gains (1) + */ +#define WM8995_AIF2DAC_EQ_B1_GAIN_MASK 0xF800 /* AIF2DAC_EQ_B1_GAIN - [15:11] */ +#define WM8995_AIF2DAC_EQ_B1_GAIN_SHIFT 11 /* AIF2DAC_EQ_B1_GAIN - [15:11] */ +#define WM8995_AIF2DAC_EQ_B1_GAIN_WIDTH 5 /* AIF2DAC_EQ_B1_GAIN - [15:11] */ +#define WM8995_AIF2DAC_EQ_B2_GAIN_MASK 0x07C0 /* AIF2DAC_EQ_B2_GAIN - [10:6] */ +#define WM8995_AIF2DAC_EQ_B2_GAIN_SHIFT 6 /* AIF2DAC_EQ_B2_GAIN - [10:6] */ +#define WM8995_AIF2DAC_EQ_B2_GAIN_WIDTH 5 /* AIF2DAC_EQ_B2_GAIN - [10:6] */ +#define WM8995_AIF2DAC_EQ_B3_GAIN_MASK 0x003E /* AIF2DAC_EQ_B3_GAIN - [5:1] */ +#define WM8995_AIF2DAC_EQ_B3_GAIN_SHIFT 1 /* AIF2DAC_EQ_B3_GAIN - [5:1] */ +#define WM8995_AIF2DAC_EQ_B3_GAIN_WIDTH 5 /* AIF2DAC_EQ_B3_GAIN - [5:1] */ +#define WM8995_AIF2DAC_EQ_ENA 0x0001 /* AIF2DAC_EQ_ENA */ +#define WM8995_AIF2DAC_EQ_ENA_MASK 0x0001 /* AIF2DAC_EQ_ENA */ +#define WM8995_AIF2DAC_EQ_ENA_SHIFT 0 /* AIF2DAC_EQ_ENA */ +#define WM8995_AIF2DAC_EQ_ENA_WIDTH 1 /* AIF2DAC_EQ_ENA */ + +/* + * R1409 (0x581) - AIF2 EQ Gains (2) + */ +#define WM8995_AIF2DAC_EQ_B4_GAIN_MASK 0xF800 /* AIF2DAC_EQ_B4_GAIN - [15:11] */ +#define WM8995_AIF2DAC_EQ_B4_GAIN_SHIFT 11 /* AIF2DAC_EQ_B4_GAIN - [15:11] */ +#define WM8995_AIF2DAC_EQ_B4_GAIN_WIDTH 5 /* AIF2DAC_EQ_B4_GAIN - [15:11] */ +#define WM8995_AIF2DAC_EQ_B5_GAIN_MASK 0x07C0 /* AIF2DAC_EQ_B5_GAIN - [10:6] */ +#define WM8995_AIF2DAC_EQ_B5_GAIN_SHIFT 6 /* AIF2DAC_EQ_B5_GAIN - [10:6] */ +#define WM8995_AIF2DAC_EQ_B5_GAIN_WIDTH 5 /* AIF2DAC_EQ_B5_GAIN - [10:6] */ + +/* + * R1410 (0x582) - AIF2 EQ Band 1 A + */ +#define WM8995_AIF2DAC_EQ_B1_A_MASK 0xFFFF /* AIF2DAC_EQ_B1_A - [15:0] */ +#define WM8995_AIF2DAC_EQ_B1_A_SHIFT 0 /* AIF2DAC_EQ_B1_A - [15:0] */ +#define WM8995_AIF2DAC_EQ_B1_A_WIDTH 16 /* AIF2DAC_EQ_B1_A - [15:0] */ + +/* + * R1411 (0x583) - AIF2 EQ Band 1 B + */ +#define WM8995_AIF2DAC_EQ_B1_B_MASK 0xFFFF /* AIF2DAC_EQ_B1_B - [15:0] */ +#define WM8995_AIF2DAC_EQ_B1_B_SHIFT 0 /* AIF2DAC_EQ_B1_B - [15:0] */ +#define WM8995_AIF2DAC_EQ_B1_B_WIDTH 16 /* AIF2DAC_EQ_B1_B - [15:0] */ + +/* + * R1412 (0x584) - AIF2 EQ Band 1 PG + */ +#define WM8995_AIF2DAC_EQ_B1_PG_MASK 0xFFFF /* AIF2DAC_EQ_B1_PG - [15:0] */ +#define WM8995_AIF2DAC_EQ_B1_PG_SHIFT 0 /* AIF2DAC_EQ_B1_PG - [15:0] */ +#define WM8995_AIF2DAC_EQ_B1_PG_WIDTH 16 /* AIF2DAC_EQ_B1_PG - [15:0] */ + +/* + * R1413 (0x585) - AIF2 EQ Band 2 A + */ +#define WM8995_AIF2DAC_EQ_B2_A_MASK 0xFFFF /* AIF2DAC_EQ_B2_A - [15:0] */ +#define WM8995_AIF2DAC_EQ_B2_A_SHIFT 0 /* AIF2DAC_EQ_B2_A - [15:0] */ +#define WM8995_AIF2DAC_EQ_B2_A_WIDTH 16 /* AIF2DAC_EQ_B2_A - [15:0] */ + +/* + * R1414 (0x586) - AIF2 EQ Band 2 B + */ +#define WM8995_AIF2DAC_EQ_B2_B_MASK 0xFFFF /* AIF2DAC_EQ_B2_B - [15:0] */ +#define WM8995_AIF2DAC_EQ_B2_B_SHIFT 0 /* AIF2DAC_EQ_B2_B - [15:0] */ +#define WM8995_AIF2DAC_EQ_B2_B_WIDTH 16 /* AIF2DAC_EQ_B2_B - [15:0] */ + +/* + * R1415 (0x587) - AIF2 EQ Band 2 C + */ +#define WM8995_AIF2DAC_EQ_B2_C_MASK 0xFFFF /* AIF2DAC_EQ_B2_C - [15:0] */ +#define WM8995_AIF2DAC_EQ_B2_C_SHIFT 0 /* AIF2DAC_EQ_B2_C - [15:0] */ +#define WM8995_AIF2DAC_EQ_B2_C_WIDTH 16 /* AIF2DAC_EQ_B2_C - [15:0] */ + +/* + * R1416 (0x588) - AIF2 EQ Band 2 PG + */ +#define WM8995_AIF2DAC_EQ_B2_PG_MASK 0xFFFF /* AIF2DAC_EQ_B2_PG - [15:0] */ +#define WM8995_AIF2DAC_EQ_B2_PG_SHIFT 0 /* AIF2DAC_EQ_B2_PG - [15:0] */ +#define WM8995_AIF2DAC_EQ_B2_PG_WIDTH 16 /* AIF2DAC_EQ_B2_PG - [15:0] */ + +/* + * R1417 (0x589) - AIF2 EQ Band 3 A + */ +#define WM8995_AIF2DAC_EQ_B3_A_MASK 0xFFFF /* AIF2DAC_EQ_B3_A - [15:0] */ +#define WM8995_AIF2DAC_EQ_B3_A_SHIFT 0 /* AIF2DAC_EQ_B3_A - [15:0] */ +#define WM8995_AIF2DAC_EQ_B3_A_WIDTH 16 /* AIF2DAC_EQ_B3_A - [15:0] */ + +/* + * R1418 (0x58A) - AIF2 EQ Band 3 B + */ +#define WM8995_AIF2DAC_EQ_B3_B_MASK 0xFFFF /* AIF2DAC_EQ_B3_B - [15:0] */ +#define WM8995_AIF2DAC_EQ_B3_B_SHIFT 0 /* AIF2DAC_EQ_B3_B - [15:0] */ +#define WM8995_AIF2DAC_EQ_B3_B_WIDTH 16 /* AIF2DAC_EQ_B3_B - [15:0] */ + +/* + * R1419 (0x58B) - AIF2 EQ Band 3 C + */ +#define WM8995_AIF2DAC_EQ_B3_C_MASK 0xFFFF /* AIF2DAC_EQ_B3_C - [15:0] */ +#define WM8995_AIF2DAC_EQ_B3_C_SHIFT 0 /* AIF2DAC_EQ_B3_C - [15:0] */ +#define WM8995_AIF2DAC_EQ_B3_C_WIDTH 16 /* AIF2DAC_EQ_B3_C - [15:0] */ + +/* + * R1420 (0x58C) - AIF2 EQ Band 3 PG + */ +#define WM8995_AIF2DAC_EQ_B3_PG_MASK 0xFFFF /* AIF2DAC_EQ_B3_PG - [15:0] */ +#define WM8995_AIF2DAC_EQ_B3_PG_SHIFT 0 /* AIF2DAC_EQ_B3_PG - [15:0] */ +#define WM8995_AIF2DAC_EQ_B3_PG_WIDTH 16 /* AIF2DAC_EQ_B3_PG - [15:0] */ + +/* + * R1421 (0x58D) - AIF2 EQ Band 4 A + */ +#define WM8995_AIF2DAC_EQ_B4_A_MASK 0xFFFF /* AIF2DAC_EQ_B4_A - [15:0] */ +#define WM8995_AIF2DAC_EQ_B4_A_SHIFT 0 /* AIF2DAC_EQ_B4_A - [15:0] */ +#define WM8995_AIF2DAC_EQ_B4_A_WIDTH 16 /* AIF2DAC_EQ_B4_A - [15:0] */ + +/* + * R1422 (0x58E) - AIF2 EQ Band 4 B + */ +#define WM8995_AIF2DAC_EQ_B4_B_MASK 0xFFFF /* AIF2DAC_EQ_B4_B - [15:0] */ +#define WM8995_AIF2DAC_EQ_B4_B_SHIFT 0 /* AIF2DAC_EQ_B4_B - [15:0] */ +#define WM8995_AIF2DAC_EQ_B4_B_WIDTH 16 /* AIF2DAC_EQ_B4_B - [15:0] */ + +/* + * R1423 (0x58F) - AIF2 EQ Band 4 C + */ +#define WM8995_AIF2DAC_EQ_B4_C_MASK 0xFFFF /* AIF2DAC_EQ_B4_C - [15:0] */ +#define WM8995_AIF2DAC_EQ_B4_C_SHIFT 0 /* AIF2DAC_EQ_B4_C - [15:0] */ +#define WM8995_AIF2DAC_EQ_B4_C_WIDTH 16 /* AIF2DAC_EQ_B4_C - [15:0] */ + +/* + * R1424 (0x590) - AIF2 EQ Band 4 PG + */ +#define WM8995_AIF2DAC_EQ_B4_PG_MASK 0xFFFF /* AIF2DAC_EQ_B4_PG - [15:0] */ +#define WM8995_AIF2DAC_EQ_B4_PG_SHIFT 0 /* AIF2DAC_EQ_B4_PG - [15:0] */ +#define WM8995_AIF2DAC_EQ_B4_PG_WIDTH 16 /* AIF2DAC_EQ_B4_PG - [15:0] */ + +/* + * R1425 (0x591) - AIF2 EQ Band 5 A + */ +#define WM8995_AIF2DAC_EQ_B5_A_MASK 0xFFFF /* AIF2DAC_EQ_B5_A - [15:0] */ +#define WM8995_AIF2DAC_EQ_B5_A_SHIFT 0 /* AIF2DAC_EQ_B5_A - [15:0] */ +#define WM8995_AIF2DAC_EQ_B5_A_WIDTH 16 /* AIF2DAC_EQ_B5_A - [15:0] */ + +/* + * R1426 (0x592) - AIF2 EQ Band 5 B + */ +#define WM8995_AIF2DAC_EQ_B5_B_MASK 0xFFFF /* AIF2DAC_EQ_B5_B - [15:0] */ +#define WM8995_AIF2DAC_EQ_B5_B_SHIFT 0 /* AIF2DAC_EQ_B5_B - [15:0] */ +#define WM8995_AIF2DAC_EQ_B5_B_WIDTH 16 /* AIF2DAC_EQ_B5_B - [15:0] */ + +/* + * R1427 (0x593) - AIF2 EQ Band 5 PG + */ +#define WM8995_AIF2DAC_EQ_B5_PG_MASK 0xFFFF /* AIF2DAC_EQ_B5_PG - [15:0] */ +#define WM8995_AIF2DAC_EQ_B5_PG_SHIFT 0 /* AIF2DAC_EQ_B5_PG - [15:0] */ +#define WM8995_AIF2DAC_EQ_B5_PG_WIDTH 16 /* AIF2DAC_EQ_B5_PG - [15:0] */ + +/* + * R1536 (0x600) - DAC1 Mixer Volumes + */ +#define WM8995_ADCR_DAC1_VOL_MASK 0x03E0 /* ADCR_DAC1_VOL - [9:5] */ +#define WM8995_ADCR_DAC1_VOL_SHIFT 5 /* ADCR_DAC1_VOL - [9:5] */ +#define WM8995_ADCR_DAC1_VOL_WIDTH 5 /* ADCR_DAC1_VOL - [9:5] */ +#define WM8995_ADCL_DAC1_VOL_MASK 0x001F /* ADCL_DAC1_VOL - [4:0] */ +#define WM8995_ADCL_DAC1_VOL_SHIFT 0 /* ADCL_DAC1_VOL - [4:0] */ +#define WM8995_ADCL_DAC1_VOL_WIDTH 5 /* ADCL_DAC1_VOL - [4:0] */ + +/* + * R1537 (0x601) - DAC1 Left Mixer Routing + */ +#define WM8995_ADCR_TO_DAC1L 0x0020 /* ADCR_TO_DAC1L */ +#define WM8995_ADCR_TO_DAC1L_MASK 0x0020 /* ADCR_TO_DAC1L */ +#define WM8995_ADCR_TO_DAC1L_SHIFT 5 /* ADCR_TO_DAC1L */ +#define WM8995_ADCR_TO_DAC1L_WIDTH 1 /* ADCR_TO_DAC1L */ +#define WM8995_ADCL_TO_DAC1L 0x0010 /* ADCL_TO_DAC1L */ +#define WM8995_ADCL_TO_DAC1L_MASK 0x0010 /* ADCL_TO_DAC1L */ +#define WM8995_ADCL_TO_DAC1L_SHIFT 4 /* ADCL_TO_DAC1L */ +#define WM8995_ADCL_TO_DAC1L_WIDTH 1 /* ADCL_TO_DAC1L */ +#define WM8995_AIF2DACL_TO_DAC1L 0x0004 /* AIF2DACL_TO_DAC1L */ +#define WM8995_AIF2DACL_TO_DAC1L_MASK 0x0004 /* AIF2DACL_TO_DAC1L */ +#define WM8995_AIF2DACL_TO_DAC1L_SHIFT 2 /* AIF2DACL_TO_DAC1L */ +#define WM8995_AIF2DACL_TO_DAC1L_WIDTH 1 /* AIF2DACL_TO_DAC1L */ +#define WM8995_AIF1DAC2L_TO_DAC1L 0x0002 /* AIF1DAC2L_TO_DAC1L */ +#define WM8995_AIF1DAC2L_TO_DAC1L_MASK 0x0002 /* AIF1DAC2L_TO_DAC1L */ +#define WM8995_AIF1DAC2L_TO_DAC1L_SHIFT 1 /* AIF1DAC2L_TO_DAC1L */ +#define WM8995_AIF1DAC2L_TO_DAC1L_WIDTH 1 /* AIF1DAC2L_TO_DAC1L */ +#define WM8995_AIF1DAC1L_TO_DAC1L 0x0001 /* AIF1DAC1L_TO_DAC1L */ +#define WM8995_AIF1DAC1L_TO_DAC1L_MASK 0x0001 /* AIF1DAC1L_TO_DAC1L */ +#define WM8995_AIF1DAC1L_TO_DAC1L_SHIFT 0 /* AIF1DAC1L_TO_DAC1L */ +#define WM8995_AIF1DAC1L_TO_DAC1L_WIDTH 1 /* AIF1DAC1L_TO_DAC1L */ + +/* + * R1538 (0x602) - DAC1 Right Mixer Routing + */ +#define WM8995_ADCR_TO_DAC1R 0x0020 /* ADCR_TO_DAC1R */ +#define WM8995_ADCR_TO_DAC1R_MASK 0x0020 /* ADCR_TO_DAC1R */ +#define WM8995_ADCR_TO_DAC1R_SHIFT 5 /* ADCR_TO_DAC1R */ +#define WM8995_ADCR_TO_DAC1R_WIDTH 1 /* ADCR_TO_DAC1R */ +#define WM8995_ADCL_TO_DAC1R 0x0010 /* ADCL_TO_DAC1R */ +#define WM8995_ADCL_TO_DAC1R_MASK 0x0010 /* ADCL_TO_DAC1R */ +#define WM8995_ADCL_TO_DAC1R_SHIFT 4 /* ADCL_TO_DAC1R */ +#define WM8995_ADCL_TO_DAC1R_WIDTH 1 /* ADCL_TO_DAC1R */ +#define WM8995_AIF2DACR_TO_DAC1R 0x0004 /* AIF2DACR_TO_DAC1R */ +#define WM8995_AIF2DACR_TO_DAC1R_MASK 0x0004 /* AIF2DACR_TO_DAC1R */ +#define WM8995_AIF2DACR_TO_DAC1R_SHIFT 2 /* AIF2DACR_TO_DAC1R */ +#define WM8995_AIF2DACR_TO_DAC1R_WIDTH 1 /* AIF2DACR_TO_DAC1R */ +#define WM8995_AIF1DAC2R_TO_DAC1R 0x0002 /* AIF1DAC2R_TO_DAC1R */ +#define WM8995_AIF1DAC2R_TO_DAC1R_MASK 0x0002 /* AIF1DAC2R_TO_DAC1R */ +#define WM8995_AIF1DAC2R_TO_DAC1R_SHIFT 1 /* AIF1DAC2R_TO_DAC1R */ +#define WM8995_AIF1DAC2R_TO_DAC1R_WIDTH 1 /* AIF1DAC2R_TO_DAC1R */ +#define WM8995_AIF1DAC1R_TO_DAC1R 0x0001 /* AIF1DAC1R_TO_DAC1R */ +#define WM8995_AIF1DAC1R_TO_DAC1R_MASK 0x0001 /* AIF1DAC1R_TO_DAC1R */ +#define WM8995_AIF1DAC1R_TO_DAC1R_SHIFT 0 /* AIF1DAC1R_TO_DAC1R */ +#define WM8995_AIF1DAC1R_TO_DAC1R_WIDTH 1 /* AIF1DAC1R_TO_DAC1R */ + +/* + * R1539 (0x603) - DAC2 Mixer Volumes + */ +#define WM8995_ADCR_DAC2_VOL_MASK 0x03E0 /* ADCR_DAC2_VOL - [9:5] */ +#define WM8995_ADCR_DAC2_VOL_SHIFT 5 /* ADCR_DAC2_VOL - [9:5] */ +#define WM8995_ADCR_DAC2_VOL_WIDTH 5 /* ADCR_DAC2_VOL - [9:5] */ +#define WM8995_ADCL_DAC2_VOL_MASK 0x001F /* ADCL_DAC2_VOL - [4:0] */ +#define WM8995_ADCL_DAC2_VOL_SHIFT 0 /* ADCL_DAC2_VOL - [4:0] */ +#define WM8995_ADCL_DAC2_VOL_WIDTH 5 /* ADCL_DAC2_VOL - [4:0] */ + +/* + * R1540 (0x604) - DAC2 Left Mixer Routing + */ +#define WM8995_ADCR_TO_DAC2L 0x0020 /* ADCR_TO_DAC2L */ +#define WM8995_ADCR_TO_DAC2L_MASK 0x0020 /* ADCR_TO_DAC2L */ +#define WM8995_ADCR_TO_DAC2L_SHIFT 5 /* ADCR_TO_DAC2L */ +#define WM8995_ADCR_TO_DAC2L_WIDTH 1 /* ADCR_TO_DAC2L */ +#define WM8995_ADCL_TO_DAC2L 0x0010 /* ADCL_TO_DAC2L */ +#define WM8995_ADCL_TO_DAC2L_MASK 0x0010 /* ADCL_TO_DAC2L */ +#define WM8995_ADCL_TO_DAC2L_SHIFT 4 /* ADCL_TO_DAC2L */ +#define WM8995_ADCL_TO_DAC2L_WIDTH 1 /* ADCL_TO_DAC2L */ +#define WM8995_AIF2DACL_TO_DAC2L 0x0004 /* AIF2DACL_TO_DAC2L */ +#define WM8995_AIF2DACL_TO_DAC2L_MASK 0x0004 /* AIF2DACL_TO_DAC2L */ +#define WM8995_AIF2DACL_TO_DAC2L_SHIFT 2 /* AIF2DACL_TO_DAC2L */ +#define WM8995_AIF2DACL_TO_DAC2L_WIDTH 1 /* AIF2DACL_TO_DAC2L */ +#define WM8995_AIF1DAC2L_TO_DAC2L 0x0002 /* AIF1DAC2L_TO_DAC2L */ +#define WM8995_AIF1DAC2L_TO_DAC2L_MASK 0x0002 /* AIF1DAC2L_TO_DAC2L */ +#define WM8995_AIF1DAC2L_TO_DAC2L_SHIFT 1 /* AIF1DAC2L_TO_DAC2L */ +#define WM8995_AIF1DAC2L_TO_DAC2L_WIDTH 1 /* AIF1DAC2L_TO_DAC2L */ +#define WM8995_AIF1DAC1L_TO_DAC2L 0x0001 /* AIF1DAC1L_TO_DAC2L */ +#define WM8995_AIF1DAC1L_TO_DAC2L_MASK 0x0001 /* AIF1DAC1L_TO_DAC2L */ +#define WM8995_AIF1DAC1L_TO_DAC2L_SHIFT 0 /* AIF1DAC1L_TO_DAC2L */ +#define WM8995_AIF1DAC1L_TO_DAC2L_WIDTH 1 /* AIF1DAC1L_TO_DAC2L */ + +/* + * R1541 (0x605) - DAC2 Right Mixer Routing + */ +#define WM8995_ADCR_TO_DAC2R 0x0020 /* ADCR_TO_DAC2R */ +#define WM8995_ADCR_TO_DAC2R_MASK 0x0020 /* ADCR_TO_DAC2R */ +#define WM8995_ADCR_TO_DAC2R_SHIFT 5 /* ADCR_TO_DAC2R */ +#define WM8995_ADCR_TO_DAC2R_WIDTH 1 /* ADCR_TO_DAC2R */ +#define WM8995_ADCL_TO_DAC2R 0x0010 /* ADCL_TO_DAC2R */ +#define WM8995_ADCL_TO_DAC2R_MASK 0x0010 /* ADCL_TO_DAC2R */ +#define WM8995_ADCL_TO_DAC2R_SHIFT 4 /* ADCL_TO_DAC2R */ +#define WM8995_ADCL_TO_DAC2R_WIDTH 1 /* ADCL_TO_DAC2R */ +#define WM8995_AIF2DACR_TO_DAC2R 0x0004 /* AIF2DACR_TO_DAC2R */ +#define WM8995_AIF2DACR_TO_DAC2R_MASK 0x0004 /* AIF2DACR_TO_DAC2R */ +#define WM8995_AIF2DACR_TO_DAC2R_SHIFT 2 /* AIF2DACR_TO_DAC2R */ +#define WM8995_AIF2DACR_TO_DAC2R_WIDTH 1 /* AIF2DACR_TO_DAC2R */ +#define WM8995_AIF1DAC2R_TO_DAC2R 0x0002 /* AIF1DAC2R_TO_DAC2R */ +#define WM8995_AIF1DAC2R_TO_DAC2R_MASK 0x0002 /* AIF1DAC2R_TO_DAC2R */ +#define WM8995_AIF1DAC2R_TO_DAC2R_SHIFT 1 /* AIF1DAC2R_TO_DAC2R */ +#define WM8995_AIF1DAC2R_TO_DAC2R_WIDTH 1 /* AIF1DAC2R_TO_DAC2R */ +#define WM8995_AIF1DAC1R_TO_DAC2R 0x0001 /* AIF1DAC1R_TO_DAC2R */ +#define WM8995_AIF1DAC1R_TO_DAC2R_MASK 0x0001 /* AIF1DAC1R_TO_DAC2R */ +#define WM8995_AIF1DAC1R_TO_DAC2R_SHIFT 0 /* AIF1DAC1R_TO_DAC2R */ +#define WM8995_AIF1DAC1R_TO_DAC2R_WIDTH 1 /* AIF1DAC1R_TO_DAC2R */ + +/* + * R1542 (0x606) - AIF1 ADC1 Left Mixer Routing + */ +#define WM8995_ADC1L_TO_AIF1ADC1L 0x0002 /* ADC1L_TO_AIF1ADC1L */ +#define WM8995_ADC1L_TO_AIF1ADC1L_MASK 0x0002 /* ADC1L_TO_AIF1ADC1L */ +#define WM8995_ADC1L_TO_AIF1ADC1L_SHIFT 1 /* ADC1L_TO_AIF1ADC1L */ +#define WM8995_ADC1L_TO_AIF1ADC1L_WIDTH 1 /* ADC1L_TO_AIF1ADC1L */ +#define WM8995_AIF2DACL_TO_AIF1ADC1L 0x0001 /* AIF2DACL_TO_AIF1ADC1L */ +#define WM8995_AIF2DACL_TO_AIF1ADC1L_MASK 0x0001 /* AIF2DACL_TO_AIF1ADC1L */ +#define WM8995_AIF2DACL_TO_AIF1ADC1L_SHIFT 0 /* AIF2DACL_TO_AIF1ADC1L */ +#define WM8995_AIF2DACL_TO_AIF1ADC1L_WIDTH 1 /* AIF2DACL_TO_AIF1ADC1L */ + +/* + * R1543 (0x607) - AIF1 ADC1 Right Mixer Routing + */ +#define WM8995_ADC1R_TO_AIF1ADC1R 0x0002 /* ADC1R_TO_AIF1ADC1R */ +#define WM8995_ADC1R_TO_AIF1ADC1R_MASK 0x0002 /* ADC1R_TO_AIF1ADC1R */ +#define WM8995_ADC1R_TO_AIF1ADC1R_SHIFT 1 /* ADC1R_TO_AIF1ADC1R */ +#define WM8995_ADC1R_TO_AIF1ADC1R_WIDTH 1 /* ADC1R_TO_AIF1ADC1R */ +#define WM8995_AIF2DACR_TO_AIF1ADC1R 0x0001 /* AIF2DACR_TO_AIF1ADC1R */ +#define WM8995_AIF2DACR_TO_AIF1ADC1R_MASK 0x0001 /* AIF2DACR_TO_AIF1ADC1R */ +#define WM8995_AIF2DACR_TO_AIF1ADC1R_SHIFT 0 /* AIF2DACR_TO_AIF1ADC1R */ +#define WM8995_AIF2DACR_TO_AIF1ADC1R_WIDTH 1 /* AIF2DACR_TO_AIF1ADC1R */ + +/* + * R1544 (0x608) - AIF1 ADC2 Left Mixer Routing + */ +#define WM8995_ADC2L_TO_AIF1ADC2L 0x0002 /* ADC2L_TO_AIF1ADC2L */ +#define WM8995_ADC2L_TO_AIF1ADC2L_MASK 0x0002 /* ADC2L_TO_AIF1ADC2L */ +#define WM8995_ADC2L_TO_AIF1ADC2L_SHIFT 1 /* ADC2L_TO_AIF1ADC2L */ +#define WM8995_ADC2L_TO_AIF1ADC2L_WIDTH 1 /* ADC2L_TO_AIF1ADC2L */ +#define WM8995_AIF2DACL_TO_AIF1ADC2L 0x0001 /* AIF2DACL_TO_AIF1ADC2L */ +#define WM8995_AIF2DACL_TO_AIF1ADC2L_MASK 0x0001 /* AIF2DACL_TO_AIF1ADC2L */ +#define WM8995_AIF2DACL_TO_AIF1ADC2L_SHIFT 0 /* AIF2DACL_TO_AIF1ADC2L */ +#define WM8995_AIF2DACL_TO_AIF1ADC2L_WIDTH 1 /* AIF2DACL_TO_AIF1ADC2L */ + +/* + * R1545 (0x609) - AIF1 ADC2 Right mixer Routing + */ +#define WM8995_ADC2R_TO_AIF1ADC2R 0x0002 /* ADC2R_TO_AIF1ADC2R */ +#define WM8995_ADC2R_TO_AIF1ADC2R_MASK 0x0002 /* ADC2R_TO_AIF1ADC2R */ +#define WM8995_ADC2R_TO_AIF1ADC2R_SHIFT 1 /* ADC2R_TO_AIF1ADC2R */ +#define WM8995_ADC2R_TO_AIF1ADC2R_WIDTH 1 /* ADC2R_TO_AIF1ADC2R */ +#define WM8995_AIF2DACR_TO_AIF1ADC2R 0x0001 /* AIF2DACR_TO_AIF1ADC2R */ +#define WM8995_AIF2DACR_TO_AIF1ADC2R_MASK 0x0001 /* AIF2DACR_TO_AIF1ADC2R */ +#define WM8995_AIF2DACR_TO_AIF1ADC2R_SHIFT 0 /* AIF2DACR_TO_AIF1ADC2R */ +#define WM8995_AIF2DACR_TO_AIF1ADC2R_WIDTH 1 /* AIF2DACR_TO_AIF1ADC2R */ + +/* + * R1552 (0x610) - DAC Softmute + */ +#define WM8995_DAC_SOFTMUTEMODE 0x0002 /* DAC_SOFTMUTEMODE */ +#define WM8995_DAC_SOFTMUTEMODE_MASK 0x0002 /* DAC_SOFTMUTEMODE */ +#define WM8995_DAC_SOFTMUTEMODE_SHIFT 1 /* DAC_SOFTMUTEMODE */ +#define WM8995_DAC_SOFTMUTEMODE_WIDTH 1 /* DAC_SOFTMUTEMODE */ +#define WM8995_DAC_MUTERATE 0x0001 /* DAC_MUTERATE */ +#define WM8995_DAC_MUTERATE_MASK 0x0001 /* DAC_MUTERATE */ +#define WM8995_DAC_MUTERATE_SHIFT 0 /* DAC_MUTERATE */ +#define WM8995_DAC_MUTERATE_WIDTH 1 /* DAC_MUTERATE */ + +/* + * R1568 (0x620) - Oversampling + */ +#define WM8995_ADC_OSR128 0x0002 /* ADC_OSR128 */ +#define WM8995_ADC_OSR128_MASK 0x0002 /* ADC_OSR128 */ +#define WM8995_ADC_OSR128_SHIFT 1 /* ADC_OSR128 */ +#define WM8995_ADC_OSR128_WIDTH 1 /* ADC_OSR128 */ +#define WM8995_DAC_OSR128 0x0001 /* DAC_OSR128 */ +#define WM8995_DAC_OSR128_MASK 0x0001 /* DAC_OSR128 */ +#define WM8995_DAC_OSR128_SHIFT 0 /* DAC_OSR128 */ +#define WM8995_DAC_OSR128_WIDTH 1 /* DAC_OSR128 */ + +/* + * R1569 (0x621) - Sidetone + */ +#define WM8995_ST_LPF 0x1000 /* ST_LPF */ +#define WM8995_ST_LPF_MASK 0x1000 /* ST_LPF */ +#define WM8995_ST_LPF_SHIFT 12 /* ST_LPF */ +#define WM8995_ST_LPF_WIDTH 1 /* ST_LPF */ +#define WM8995_ST_HPF_CUT_MASK 0x0380 /* ST_HPF_CUT - [9:7] */ +#define WM8995_ST_HPF_CUT_SHIFT 7 /* ST_HPF_CUT - [9:7] */ +#define WM8995_ST_HPF_CUT_WIDTH 3 /* ST_HPF_CUT - [9:7] */ +#define WM8995_ST_HPF 0x0040 /* ST_HPF */ +#define WM8995_ST_HPF_MASK 0x0040 /* ST_HPF */ +#define WM8995_ST_HPF_SHIFT 6 /* ST_HPF */ +#define WM8995_ST_HPF_WIDTH 1 /* ST_HPF */ +#define WM8995_STR_SEL 0x0002 /* STR_SEL */ +#define WM8995_STR_SEL_MASK 0x0002 /* STR_SEL */ +#define WM8995_STR_SEL_SHIFT 1 /* STR_SEL */ +#define WM8995_STR_SEL_WIDTH 1 /* STR_SEL */ +#define WM8995_STL_SEL 0x0001 /* STL_SEL */ +#define WM8995_STL_SEL_MASK 0x0001 /* STL_SEL */ +#define WM8995_STL_SEL_SHIFT 0 /* STL_SEL */ +#define WM8995_STL_SEL_WIDTH 1 /* STL_SEL */ + +/* + * R1792 (0x700) - GPIO 1 + */ +#define WM8995_GP1_DIR 0x8000 /* GP1_DIR */ +#define WM8995_GP1_DIR_MASK 0x8000 /* GP1_DIR */ +#define WM8995_GP1_DIR_SHIFT 15 /* GP1_DIR */ +#define WM8995_GP1_DIR_WIDTH 1 /* GP1_DIR */ +#define WM8995_GP1_PU 0x4000 /* GP1_PU */ +#define WM8995_GP1_PU_MASK 0x4000 /* GP1_PU */ +#define WM8995_GP1_PU_SHIFT 14 /* GP1_PU */ +#define WM8995_GP1_PU_WIDTH 1 /* GP1_PU */ +#define WM8995_GP1_PD 0x2000 /* GP1_PD */ +#define WM8995_GP1_PD_MASK 0x2000 /* GP1_PD */ +#define WM8995_GP1_PD_SHIFT 13 /* GP1_PD */ +#define WM8995_GP1_PD_WIDTH 1 /* GP1_PD */ +#define WM8995_GP1_POL 0x0400 /* GP1_POL */ +#define WM8995_GP1_POL_MASK 0x0400 /* GP1_POL */ +#define WM8995_GP1_POL_SHIFT 10 /* GP1_POL */ +#define WM8995_GP1_POL_WIDTH 1 /* GP1_POL */ +#define WM8995_GP1_OP_CFG 0x0200 /* GP1_OP_CFG */ +#define WM8995_GP1_OP_CFG_MASK 0x0200 /* GP1_OP_CFG */ +#define WM8995_GP1_OP_CFG_SHIFT 9 /* GP1_OP_CFG */ +#define WM8995_GP1_OP_CFG_WIDTH 1 /* GP1_OP_CFG */ +#define WM8995_GP1_DB 0x0100 /* GP1_DB */ +#define WM8995_GP1_DB_MASK 0x0100 /* GP1_DB */ +#define WM8995_GP1_DB_SHIFT 8 /* GP1_DB */ +#define WM8995_GP1_DB_WIDTH 1 /* GP1_DB */ +#define WM8995_GP1_LVL 0x0040 /* GP1_LVL */ +#define WM8995_GP1_LVL_MASK 0x0040 /* GP1_LVL */ +#define WM8995_GP1_LVL_SHIFT 6 /* GP1_LVL */ +#define WM8995_GP1_LVL_WIDTH 1 /* GP1_LVL */ +#define WM8995_GP1_FN_MASK 0x001F /* GP1_FN - [4:0] */ +#define WM8995_GP1_FN_SHIFT 0 /* GP1_FN - [4:0] */ +#define WM8995_GP1_FN_WIDTH 5 /* GP1_FN - [4:0] */ + +/* + * R1793 (0x701) - GPIO 2 + */ +#define WM8995_GP2_DIR 0x8000 /* GP2_DIR */ +#define WM8995_GP2_DIR_MASK 0x8000 /* GP2_DIR */ +#define WM8995_GP2_DIR_SHIFT 15 /* GP2_DIR */ +#define WM8995_GP2_DIR_WIDTH 1 /* GP2_DIR */ +#define WM8995_GP2_PU 0x4000 /* GP2_PU */ +#define WM8995_GP2_PU_MASK 0x4000 /* GP2_PU */ +#define WM8995_GP2_PU_SHIFT 14 /* GP2_PU */ +#define WM8995_GP2_PU_WIDTH 1 /* GP2_PU */ +#define WM8995_GP2_PD 0x2000 /* GP2_PD */ +#define WM8995_GP2_PD_MASK 0x2000 /* GP2_PD */ +#define WM8995_GP2_PD_SHIFT 13 /* GP2_PD */ +#define WM8995_GP2_PD_WIDTH 1 /* GP2_PD */ +#define WM8995_GP2_POL 0x0400 /* GP2_POL */ +#define WM8995_GP2_POL_MASK 0x0400 /* GP2_POL */ +#define WM8995_GP2_POL_SHIFT 10 /* GP2_POL */ +#define WM8995_GP2_POL_WIDTH 1 /* GP2_POL */ +#define WM8995_GP2_OP_CFG 0x0200 /* GP2_OP_CFG */ +#define WM8995_GP2_OP_CFG_MASK 0x0200 /* GP2_OP_CFG */ +#define WM8995_GP2_OP_CFG_SHIFT 9 /* GP2_OP_CFG */ +#define WM8995_GP2_OP_CFG_WIDTH 1 /* GP2_OP_CFG */ +#define WM8995_GP2_DB 0x0100 /* GP2_DB */ +#define WM8995_GP2_DB_MASK 0x0100 /* GP2_DB */ +#define WM8995_GP2_DB_SHIFT 8 /* GP2_DB */ +#define WM8995_GP2_DB_WIDTH 1 /* GP2_DB */ +#define WM8995_GP2_LVL 0x0040 /* GP2_LVL */ +#define WM8995_GP2_LVL_MASK 0x0040 /* GP2_LVL */ +#define WM8995_GP2_LVL_SHIFT 6 /* GP2_LVL */ +#define WM8995_GP2_LVL_WIDTH 1 /* GP2_LVL */ +#define WM8995_GP2_FN_MASK 0x001F /* GP2_FN - [4:0] */ +#define WM8995_GP2_FN_SHIFT 0 /* GP2_FN - [4:0] */ +#define WM8995_GP2_FN_WIDTH 5 /* GP2_FN - [4:0] */ + +/* + * R1794 (0x702) - GPIO 3 + */ +#define WM8995_GP3_DIR 0x8000 /* GP3_DIR */ +#define WM8995_GP3_DIR_MASK 0x8000 /* GP3_DIR */ +#define WM8995_GP3_DIR_SHIFT 15 /* GP3_DIR */ +#define WM8995_GP3_DIR_WIDTH 1 /* GP3_DIR */ +#define WM8995_GP3_PU 0x4000 /* GP3_PU */ +#define WM8995_GP3_PU_MASK 0x4000 /* GP3_PU */ +#define WM8995_GP3_PU_SHIFT 14 /* GP3_PU */ +#define WM8995_GP3_PU_WIDTH 1 /* GP3_PU */ +#define WM8995_GP3_PD 0x2000 /* GP3_PD */ +#define WM8995_GP3_PD_MASK 0x2000 /* GP3_PD */ +#define WM8995_GP3_PD_SHIFT 13 /* GP3_PD */ +#define WM8995_GP3_PD_WIDTH 1 /* GP3_PD */ +#define WM8995_GP3_POL 0x0400 /* GP3_POL */ +#define WM8995_GP3_POL_MASK 0x0400 /* GP3_POL */ +#define WM8995_GP3_POL_SHIFT 10 /* GP3_POL */ +#define WM8995_GP3_POL_WIDTH 1 /* GP3_POL */ +#define WM8995_GP3_OP_CFG 0x0200 /* GP3_OP_CFG */ +#define WM8995_GP3_OP_CFG_MASK 0x0200 /* GP3_OP_CFG */ +#define WM8995_GP3_OP_CFG_SHIFT 9 /* GP3_OP_CFG */ +#define WM8995_GP3_OP_CFG_WIDTH 1 /* GP3_OP_CFG */ +#define WM8995_GP3_DB 0x0100 /* GP3_DB */ +#define WM8995_GP3_DB_MASK 0x0100 /* GP3_DB */ +#define WM8995_GP3_DB_SHIFT 8 /* GP3_DB */ +#define WM8995_GP3_DB_WIDTH 1 /* GP3_DB */ +#define WM8995_GP3_LVL 0x0040 /* GP3_LVL */ +#define WM8995_GP3_LVL_MASK 0x0040 /* GP3_LVL */ +#define WM8995_GP3_LVL_SHIFT 6 /* GP3_LVL */ +#define WM8995_GP3_LVL_WIDTH 1 /* GP3_LVL */ +#define WM8995_GP3_FN_MASK 0x001F /* GP3_FN - [4:0] */ +#define WM8995_GP3_FN_SHIFT 0 /* GP3_FN - [4:0] */ +#define WM8995_GP3_FN_WIDTH 5 /* GP3_FN - [4:0] */ + +/* + * R1795 (0x703) - GPIO 4 + */ +#define WM8995_GP4_DIR 0x8000 /* GP4_DIR */ +#define WM8995_GP4_DIR_MASK 0x8000 /* GP4_DIR */ +#define WM8995_GP4_DIR_SHIFT 15 /* GP4_DIR */ +#define WM8995_GP4_DIR_WIDTH 1 /* GP4_DIR */ +#define WM8995_GP4_PU 0x4000 /* GP4_PU */ +#define WM8995_GP4_PU_MASK 0x4000 /* GP4_PU */ +#define WM8995_GP4_PU_SHIFT 14 /* GP4_PU */ +#define WM8995_GP4_PU_WIDTH 1 /* GP4_PU */ +#define WM8995_GP4_PD 0x2000 /* GP4_PD */ +#define WM8995_GP4_PD_MASK 0x2000 /* GP4_PD */ +#define WM8995_GP4_PD_SHIFT 13 /* GP4_PD */ +#define WM8995_GP4_PD_WIDTH 1 /* GP4_PD */ +#define WM8995_GP4_POL 0x0400 /* GP4_POL */ +#define WM8995_GP4_POL_MASK 0x0400 /* GP4_POL */ +#define WM8995_GP4_POL_SHIFT 10 /* GP4_POL */ +#define WM8995_GP4_POL_WIDTH 1 /* GP4_POL */ +#define WM8995_GP4_OP_CFG 0x0200 /* GP4_OP_CFG */ +#define WM8995_GP4_OP_CFG_MASK 0x0200 /* GP4_OP_CFG */ +#define WM8995_GP4_OP_CFG_SHIFT 9 /* GP4_OP_CFG */ +#define WM8995_GP4_OP_CFG_WIDTH 1 /* GP4_OP_CFG */ +#define WM8995_GP4_DB 0x0100 /* GP4_DB */ +#define WM8995_GP4_DB_MASK 0x0100 /* GP4_DB */ +#define WM8995_GP4_DB_SHIFT 8 /* GP4_DB */ +#define WM8995_GP4_DB_WIDTH 1 /* GP4_DB */ +#define WM8995_GP4_LVL 0x0040 /* GP4_LVL */ +#define WM8995_GP4_LVL_MASK 0x0040 /* GP4_LVL */ +#define WM8995_GP4_LVL_SHIFT 6 /* GP4_LVL */ +#define WM8995_GP4_LVL_WIDTH 1 /* GP4_LVL */ +#define WM8995_GP4_FN_MASK 0x001F /* GP4_FN - [4:0] */ +#define WM8995_GP4_FN_SHIFT 0 /* GP4_FN - [4:0] */ +#define WM8995_GP4_FN_WIDTH 5 /* GP4_FN - [4:0] */ + +/* + * R1796 (0x704) - GPIO 5 + */ +#define WM8995_GP5_DIR 0x8000 /* GP5_DIR */ +#define WM8995_GP5_DIR_MASK 0x8000 /* GP5_DIR */ +#define WM8995_GP5_DIR_SHIFT 15 /* GP5_DIR */ +#define WM8995_GP5_DIR_WIDTH 1 /* GP5_DIR */ +#define WM8995_GP5_PU 0x4000 /* GP5_PU */ +#define WM8995_GP5_PU_MASK 0x4000 /* GP5_PU */ +#define WM8995_GP5_PU_SHIFT 14 /* GP5_PU */ +#define WM8995_GP5_PU_WIDTH 1 /* GP5_PU */ +#define WM8995_GP5_PD 0x2000 /* GP5_PD */ +#define WM8995_GP5_PD_MASK 0x2000 /* GP5_PD */ +#define WM8995_GP5_PD_SHIFT 13 /* GP5_PD */ +#define WM8995_GP5_PD_WIDTH 1 /* GP5_PD */ +#define WM8995_GP5_POL 0x0400 /* GP5_POL */ +#define WM8995_GP5_POL_MASK 0x0400 /* GP5_POL */ +#define WM8995_GP5_POL_SHIFT 10 /* GP5_POL */ +#define WM8995_GP5_POL_WIDTH 1 /* GP5_POL */ +#define WM8995_GP5_OP_CFG 0x0200 /* GP5_OP_CFG */ +#define WM8995_GP5_OP_CFG_MASK 0x0200 /* GP5_OP_CFG */ +#define WM8995_GP5_OP_CFG_SHIFT 9 /* GP5_OP_CFG */ +#define WM8995_GP5_OP_CFG_WIDTH 1 /* GP5_OP_CFG */ +#define WM8995_GP5_DB 0x0100 /* GP5_DB */ +#define WM8995_GP5_DB_MASK 0x0100 /* GP5_DB */ +#define WM8995_GP5_DB_SHIFT 8 /* GP5_DB */ +#define WM8995_GP5_DB_WIDTH 1 /* GP5_DB */ +#define WM8995_GP5_LVL 0x0040 /* GP5_LVL */ +#define WM8995_GP5_LVL_MASK 0x0040 /* GP5_LVL */ +#define WM8995_GP5_LVL_SHIFT 6 /* GP5_LVL */ +#define WM8995_GP5_LVL_WIDTH 1 /* GP5_LVL */ +#define WM8995_GP5_FN_MASK 0x001F /* GP5_FN - [4:0] */ +#define WM8995_GP5_FN_SHIFT 0 /* GP5_FN - [4:0] */ +#define WM8995_GP5_FN_WIDTH 5 /* GP5_FN - [4:0] */ + +/* + * R1797 (0x705) - GPIO 6 + */ +#define WM8995_GP6_DIR 0x8000 /* GP6_DIR */ +#define WM8995_GP6_DIR_MASK 0x8000 /* GP6_DIR */ +#define WM8995_GP6_DIR_SHIFT 15 /* GP6_DIR */ +#define WM8995_GP6_DIR_WIDTH 1 /* GP6_DIR */ +#define WM8995_GP6_PU 0x4000 /* GP6_PU */ +#define WM8995_GP6_PU_MASK 0x4000 /* GP6_PU */ +#define WM8995_GP6_PU_SHIFT 14 /* GP6_PU */ +#define WM8995_GP6_PU_WIDTH 1 /* GP6_PU */ +#define WM8995_GP6_PD 0x2000 /* GP6_PD */ +#define WM8995_GP6_PD_MASK 0x2000 /* GP6_PD */ +#define WM8995_GP6_PD_SHIFT 13 /* GP6_PD */ +#define WM8995_GP6_PD_WIDTH 1 /* GP6_PD */ +#define WM8995_GP6_POL 0x0400 /* GP6_POL */ +#define WM8995_GP6_POL_MASK 0x0400 /* GP6_POL */ +#define WM8995_GP6_POL_SHIFT 10 /* GP6_POL */ +#define WM8995_GP6_POL_WIDTH 1 /* GP6_POL */ +#define WM8995_GP6_OP_CFG 0x0200 /* GP6_OP_CFG */ +#define WM8995_GP6_OP_CFG_MASK 0x0200 /* GP6_OP_CFG */ +#define WM8995_GP6_OP_CFG_SHIFT 9 /* GP6_OP_CFG */ +#define WM8995_GP6_OP_CFG_WIDTH 1 /* GP6_OP_CFG */ +#define WM8995_GP6_DB 0x0100 /* GP6_DB */ +#define WM8995_GP6_DB_MASK 0x0100 /* GP6_DB */ +#define WM8995_GP6_DB_SHIFT 8 /* GP6_DB */ +#define WM8995_GP6_DB_WIDTH 1 /* GP6_DB */ +#define WM8995_GP6_LVL 0x0040 /* GP6_LVL */ +#define WM8995_GP6_LVL_MASK 0x0040 /* GP6_LVL */ +#define WM8995_GP6_LVL_SHIFT 6 /* GP6_LVL */ +#define WM8995_GP6_LVL_WIDTH 1 /* GP6_LVL */ +#define WM8995_GP6_FN_MASK 0x001F /* GP6_FN - [4:0] */ +#define WM8995_GP6_FN_SHIFT 0 /* GP6_FN - [4:0] */ +#define WM8995_GP6_FN_WIDTH 5 /* GP6_FN - [4:0] */ + +/* + * R1798 (0x706) - GPIO 7 + */ +#define WM8995_GP7_DIR 0x8000 /* GP7_DIR */ +#define WM8995_GP7_DIR_MASK 0x8000 /* GP7_DIR */ +#define WM8995_GP7_DIR_SHIFT 15 /* GP7_DIR */ +#define WM8995_GP7_DIR_WIDTH 1 /* GP7_DIR */ +#define WM8995_GP7_PU 0x4000 /* GP7_PU */ +#define WM8995_GP7_PU_MASK 0x4000 /* GP7_PU */ +#define WM8995_GP7_PU_SHIFT 14 /* GP7_PU */ +#define WM8995_GP7_PU_WIDTH 1 /* GP7_PU */ +#define WM8995_GP7_PD 0x2000 /* GP7_PD */ +#define WM8995_GP7_PD_MASK 0x2000 /* GP7_PD */ +#define WM8995_GP7_PD_SHIFT 13 /* GP7_PD */ +#define WM8995_GP7_PD_WIDTH 1 /* GP7_PD */ +#define WM8995_GP7_POL 0x0400 /* GP7_POL */ +#define WM8995_GP7_POL_MASK 0x0400 /* GP7_POL */ +#define WM8995_GP7_POL_SHIFT 10 /* GP7_POL */ +#define WM8995_GP7_POL_WIDTH 1 /* GP7_POL */ +#define WM8995_GP7_OP_CFG 0x0200 /* GP7_OP_CFG */ +#define WM8995_GP7_OP_CFG_MASK 0x0200 /* GP7_OP_CFG */ +#define WM8995_GP7_OP_CFG_SHIFT 9 /* GP7_OP_CFG */ +#define WM8995_GP7_OP_CFG_WIDTH 1 /* GP7_OP_CFG */ +#define WM8995_GP7_DB 0x0100 /* GP7_DB */ +#define WM8995_GP7_DB_MASK 0x0100 /* GP7_DB */ +#define WM8995_GP7_DB_SHIFT 8 /* GP7_DB */ +#define WM8995_GP7_DB_WIDTH 1 /* GP7_DB */ +#define WM8995_GP7_LVL 0x0040 /* GP7_LVL */ +#define WM8995_GP7_LVL_MASK 0x0040 /* GP7_LVL */ +#define WM8995_GP7_LVL_SHIFT 6 /* GP7_LVL */ +#define WM8995_GP7_LVL_WIDTH 1 /* GP7_LVL */ +#define WM8995_GP7_FN_MASK 0x001F /* GP7_FN - [4:0] */ +#define WM8995_GP7_FN_SHIFT 0 /* GP7_FN - [4:0] */ +#define WM8995_GP7_FN_WIDTH 5 /* GP7_FN - [4:0] */ + +/* + * R1799 (0x707) - GPIO 8 + */ +#define WM8995_GP8_DIR 0x8000 /* GP8_DIR */ +#define WM8995_GP8_DIR_MASK 0x8000 /* GP8_DIR */ +#define WM8995_GP8_DIR_SHIFT 15 /* GP8_DIR */ +#define WM8995_GP8_DIR_WIDTH 1 /* GP8_DIR */ +#define WM8995_GP8_PU 0x4000 /* GP8_PU */ +#define WM8995_GP8_PU_MASK 0x4000 /* GP8_PU */ +#define WM8995_GP8_PU_SHIFT 14 /* GP8_PU */ +#define WM8995_GP8_PU_WIDTH 1 /* GP8_PU */ +#define WM8995_GP8_PD 0x2000 /* GP8_PD */ +#define WM8995_GP8_PD_MASK 0x2000 /* GP8_PD */ +#define WM8995_GP8_PD_SHIFT 13 /* GP8_PD */ +#define WM8995_GP8_PD_WIDTH 1 /* GP8_PD */ +#define WM8995_GP8_POL 0x0400 /* GP8_POL */ +#define WM8995_GP8_POL_MASK 0x0400 /* GP8_POL */ +#define WM8995_GP8_POL_SHIFT 10 /* GP8_POL */ +#define WM8995_GP8_POL_WIDTH 1 /* GP8_POL */ +#define WM8995_GP8_OP_CFG 0x0200 /* GP8_OP_CFG */ +#define WM8995_GP8_OP_CFG_MASK 0x0200 /* GP8_OP_CFG */ +#define WM8995_GP8_OP_CFG_SHIFT 9 /* GP8_OP_CFG */ +#define WM8995_GP8_OP_CFG_WIDTH 1 /* GP8_OP_CFG */ +#define WM8995_GP8_DB 0x0100 /* GP8_DB */ +#define WM8995_GP8_DB_MASK 0x0100 /* GP8_DB */ +#define WM8995_GP8_DB_SHIFT 8 /* GP8_DB */ +#define WM8995_GP8_DB_WIDTH 1 /* GP8_DB */ +#define WM8995_GP8_LVL 0x0040 /* GP8_LVL */ +#define WM8995_GP8_LVL_MASK 0x0040 /* GP8_LVL */ +#define WM8995_GP8_LVL_SHIFT 6 /* GP8_LVL */ +#define WM8995_GP8_LVL_WIDTH 1 /* GP8_LVL */ +#define WM8995_GP8_FN_MASK 0x001F /* GP8_FN - [4:0] */ +#define WM8995_GP8_FN_SHIFT 0 /* GP8_FN - [4:0] */ +#define WM8995_GP8_FN_WIDTH 5 /* GP8_FN - [4:0] */ + +/* + * R1800 (0x708) - GPIO 9 + */ +#define WM8995_GP9_DIR 0x8000 /* GP9_DIR */ +#define WM8995_GP9_DIR_MASK 0x8000 /* GP9_DIR */ +#define WM8995_GP9_DIR_SHIFT 15 /* GP9_DIR */ +#define WM8995_GP9_DIR_WIDTH 1 /* GP9_DIR */ +#define WM8995_GP9_PU 0x4000 /* GP9_PU */ +#define WM8995_GP9_PU_MASK 0x4000 /* GP9_PU */ +#define WM8995_GP9_PU_SHIFT 14 /* GP9_PU */ +#define WM8995_GP9_PU_WIDTH 1 /* GP9_PU */ +#define WM8995_GP9_PD 0x2000 /* GP9_PD */ +#define WM8995_GP9_PD_MASK 0x2000 /* GP9_PD */ +#define WM8995_GP9_PD_SHIFT 13 /* GP9_PD */ +#define WM8995_GP9_PD_WIDTH 1 /* GP9_PD */ +#define WM8995_GP9_POL 0x0400 /* GP9_POL */ +#define WM8995_GP9_POL_MASK 0x0400 /* GP9_POL */ +#define WM8995_GP9_POL_SHIFT 10 /* GP9_POL */ +#define WM8995_GP9_POL_WIDTH 1 /* GP9_POL */ +#define WM8995_GP9_OP_CFG 0x0200 /* GP9_OP_CFG */ +#define WM8995_GP9_OP_CFG_MASK 0x0200 /* GP9_OP_CFG */ +#define WM8995_GP9_OP_CFG_SHIFT 9 /* GP9_OP_CFG */ +#define WM8995_GP9_OP_CFG_WIDTH 1 /* GP9_OP_CFG */ +#define WM8995_GP9_DB 0x0100 /* GP9_DB */ +#define WM8995_GP9_DB_MASK 0x0100 /* GP9_DB */ +#define WM8995_GP9_DB_SHIFT 8 /* GP9_DB */ +#define WM8995_GP9_DB_WIDTH 1 /* GP9_DB */ +#define WM8995_GP9_LVL 0x0040 /* GP9_LVL */ +#define WM8995_GP9_LVL_MASK 0x0040 /* GP9_LVL */ +#define WM8995_GP9_LVL_SHIFT 6 /* GP9_LVL */ +#define WM8995_GP9_LVL_WIDTH 1 /* GP9_LVL */ +#define WM8995_GP9_FN_MASK 0x001F /* GP9_FN - [4:0] */ +#define WM8995_GP9_FN_SHIFT 0 /* GP9_FN - [4:0] */ +#define WM8995_GP9_FN_WIDTH 5 /* GP9_FN - [4:0] */ + +/* + * R1801 (0x709) - GPIO 10 + */ +#define WM8995_GP10_DIR 0x8000 /* GP10_DIR */ +#define WM8995_GP10_DIR_MASK 0x8000 /* GP10_DIR */ +#define WM8995_GP10_DIR_SHIFT 15 /* GP10_DIR */ +#define WM8995_GP10_DIR_WIDTH 1 /* GP10_DIR */ +#define WM8995_GP10_PU 0x4000 /* GP10_PU */ +#define WM8995_GP10_PU_MASK 0x4000 /* GP10_PU */ +#define WM8995_GP10_PU_SHIFT 14 /* GP10_PU */ +#define WM8995_GP10_PU_WIDTH 1 /* GP10_PU */ +#define WM8995_GP10_PD 0x2000 /* GP10_PD */ +#define WM8995_GP10_PD_MASK 0x2000 /* GP10_PD */ +#define WM8995_GP10_PD_SHIFT 13 /* GP10_PD */ +#define WM8995_GP10_PD_WIDTH 1 /* GP10_PD */ +#define WM8995_GP10_POL 0x0400 /* GP10_POL */ +#define WM8995_GP10_POL_MASK 0x0400 /* GP10_POL */ +#define WM8995_GP10_POL_SHIFT 10 /* GP10_POL */ +#define WM8995_GP10_POL_WIDTH 1 /* GP10_POL */ +#define WM8995_GP10_OP_CFG 0x0200 /* GP10_OP_CFG */ +#define WM8995_GP10_OP_CFG_MASK 0x0200 /* GP10_OP_CFG */ +#define WM8995_GP10_OP_CFG_SHIFT 9 /* GP10_OP_CFG */ +#define WM8995_GP10_OP_CFG_WIDTH 1 /* GP10_OP_CFG */ +#define WM8995_GP10_DB 0x0100 /* GP10_DB */ +#define WM8995_GP10_DB_MASK 0x0100 /* GP10_DB */ +#define WM8995_GP10_DB_SHIFT 8 /* GP10_DB */ +#define WM8995_GP10_DB_WIDTH 1 /* GP10_DB */ +#define WM8995_GP10_LVL 0x0040 /* GP10_LVL */ +#define WM8995_GP10_LVL_MASK 0x0040 /* GP10_LVL */ +#define WM8995_GP10_LVL_SHIFT 6 /* GP10_LVL */ +#define WM8995_GP10_LVL_WIDTH 1 /* GP10_LVL */ +#define WM8995_GP10_FN_MASK 0x001F /* GP10_FN - [4:0] */ +#define WM8995_GP10_FN_SHIFT 0 /* GP10_FN - [4:0] */ +#define WM8995_GP10_FN_WIDTH 5 /* GP10_FN - [4:0] */ + +/* + * R1802 (0x70A) - GPIO 11 + */ +#define WM8995_GP11_DIR 0x8000 /* GP11_DIR */ +#define WM8995_GP11_DIR_MASK 0x8000 /* GP11_DIR */ +#define WM8995_GP11_DIR_SHIFT 15 /* GP11_DIR */ +#define WM8995_GP11_DIR_WIDTH 1 /* GP11_DIR */ +#define WM8995_GP11_PU 0x4000 /* GP11_PU */ +#define WM8995_GP11_PU_MASK 0x4000 /* GP11_PU */ +#define WM8995_GP11_PU_SHIFT 14 /* GP11_PU */ +#define WM8995_GP11_PU_WIDTH 1 /* GP11_PU */ +#define WM8995_GP11_PD 0x2000 /* GP11_PD */ +#define WM8995_GP11_PD_MASK 0x2000 /* GP11_PD */ +#define WM8995_GP11_PD_SHIFT 13 /* GP11_PD */ +#define WM8995_GP11_PD_WIDTH 1 /* GP11_PD */ +#define WM8995_GP11_POL 0x0400 /* GP11_POL */ +#define WM8995_GP11_POL_MASK 0x0400 /* GP11_POL */ +#define WM8995_GP11_POL_SHIFT 10 /* GP11_POL */ +#define WM8995_GP11_POL_WIDTH 1 /* GP11_POL */ +#define WM8995_GP11_OP_CFG 0x0200 /* GP11_OP_CFG */ +#define WM8995_GP11_OP_CFG_MASK 0x0200 /* GP11_OP_CFG */ +#define WM8995_GP11_OP_CFG_SHIFT 9 /* GP11_OP_CFG */ +#define WM8995_GP11_OP_CFG_WIDTH 1 /* GP11_OP_CFG */ +#define WM8995_GP11_DB 0x0100 /* GP11_DB */ +#define WM8995_GP11_DB_MASK 0x0100 /* GP11_DB */ +#define WM8995_GP11_DB_SHIFT 8 /* GP11_DB */ +#define WM8995_GP11_DB_WIDTH 1 /* GP11_DB */ +#define WM8995_GP11_LVL 0x0040 /* GP11_LVL */ +#define WM8995_GP11_LVL_MASK 0x0040 /* GP11_LVL */ +#define WM8995_GP11_LVL_SHIFT 6 /* GP11_LVL */ +#define WM8995_GP11_LVL_WIDTH 1 /* GP11_LVL */ +#define WM8995_GP11_FN_MASK 0x001F /* GP11_FN - [4:0] */ +#define WM8995_GP11_FN_SHIFT 0 /* GP11_FN - [4:0] */ +#define WM8995_GP11_FN_WIDTH 5 /* GP11_FN - [4:0] */ + +/* + * R1803 (0x70B) - GPIO 12 + */ +#define WM8995_GP12_DIR 0x8000 /* GP12_DIR */ +#define WM8995_GP12_DIR_MASK 0x8000 /* GP12_DIR */ +#define WM8995_GP12_DIR_SHIFT 15 /* GP12_DIR */ +#define WM8995_GP12_DIR_WIDTH 1 /* GP12_DIR */ +#define WM8995_GP12_PU 0x4000 /* GP12_PU */ +#define WM8995_GP12_PU_MASK 0x4000 /* GP12_PU */ +#define WM8995_GP12_PU_SHIFT 14 /* GP12_PU */ +#define WM8995_GP12_PU_WIDTH 1 /* GP12_PU */ +#define WM8995_GP12_PD 0x2000 /* GP12_PD */ +#define WM8995_GP12_PD_MASK 0x2000 /* GP12_PD */ +#define WM8995_GP12_PD_SHIFT 13 /* GP12_PD */ +#define WM8995_GP12_PD_WIDTH 1 /* GP12_PD */ +#define WM8995_GP12_POL 0x0400 /* GP12_POL */ +#define WM8995_GP12_POL_MASK 0x0400 /* GP12_POL */ +#define WM8995_GP12_POL_SHIFT 10 /* GP12_POL */ +#define WM8995_GP12_POL_WIDTH 1 /* GP12_POL */ +#define WM8995_GP12_OP_CFG 0x0200 /* GP12_OP_CFG */ +#define WM8995_GP12_OP_CFG_MASK 0x0200 /* GP12_OP_CFG */ +#define WM8995_GP12_OP_CFG_SHIFT 9 /* GP12_OP_CFG */ +#define WM8995_GP12_OP_CFG_WIDTH 1 /* GP12_OP_CFG */ +#define WM8995_GP12_DB 0x0100 /* GP12_DB */ +#define WM8995_GP12_DB_MASK 0x0100 /* GP12_DB */ +#define WM8995_GP12_DB_SHIFT 8 /* GP12_DB */ +#define WM8995_GP12_DB_WIDTH 1 /* GP12_DB */ +#define WM8995_GP12_LVL 0x0040 /* GP12_LVL */ +#define WM8995_GP12_LVL_MASK 0x0040 /* GP12_LVL */ +#define WM8995_GP12_LVL_SHIFT 6 /* GP12_LVL */ +#define WM8995_GP12_LVL_WIDTH 1 /* GP12_LVL */ +#define WM8995_GP12_FN_MASK 0x001F /* GP12_FN - [4:0] */ +#define WM8995_GP12_FN_SHIFT 0 /* GP12_FN - [4:0] */ +#define WM8995_GP12_FN_WIDTH 5 /* GP12_FN - [4:0] */ + +/* + * R1804 (0x70C) - GPIO 13 + */ +#define WM8995_GP13_DIR 0x8000 /* GP13_DIR */ +#define WM8995_GP13_DIR_MASK 0x8000 /* GP13_DIR */ +#define WM8995_GP13_DIR_SHIFT 15 /* GP13_DIR */ +#define WM8995_GP13_DIR_WIDTH 1 /* GP13_DIR */ +#define WM8995_GP13_PU 0x4000 /* GP13_PU */ +#define WM8995_GP13_PU_MASK 0x4000 /* GP13_PU */ +#define WM8995_GP13_PU_SHIFT 14 /* GP13_PU */ +#define WM8995_GP13_PU_WIDTH 1 /* GP13_PU */ +#define WM8995_GP13_PD 0x2000 /* GP13_PD */ +#define WM8995_GP13_PD_MASK 0x2000 /* GP13_PD */ +#define WM8995_GP13_PD_SHIFT 13 /* GP13_PD */ +#define WM8995_GP13_PD_WIDTH 1 /* GP13_PD */ +#define WM8995_GP13_POL 0x0400 /* GP13_POL */ +#define WM8995_GP13_POL_MASK 0x0400 /* GP13_POL */ +#define WM8995_GP13_POL_SHIFT 10 /* GP13_POL */ +#define WM8995_GP13_POL_WIDTH 1 /* GP13_POL */ +#define WM8995_GP13_OP_CFG 0x0200 /* GP13_OP_CFG */ +#define WM8995_GP13_OP_CFG_MASK 0x0200 /* GP13_OP_CFG */ +#define WM8995_GP13_OP_CFG_SHIFT 9 /* GP13_OP_CFG */ +#define WM8995_GP13_OP_CFG_WIDTH 1 /* GP13_OP_CFG */ +#define WM8995_GP13_DB 0x0100 /* GP13_DB */ +#define WM8995_GP13_DB_MASK 0x0100 /* GP13_DB */ +#define WM8995_GP13_DB_SHIFT 8 /* GP13_DB */ +#define WM8995_GP13_DB_WIDTH 1 /* GP13_DB */ +#define WM8995_GP13_LVL 0x0040 /* GP13_LVL */ +#define WM8995_GP13_LVL_MASK 0x0040 /* GP13_LVL */ +#define WM8995_GP13_LVL_SHIFT 6 /* GP13_LVL */ +#define WM8995_GP13_LVL_WIDTH 1 /* GP13_LVL */ +#define WM8995_GP13_FN_MASK 0x001F /* GP13_FN - [4:0] */ +#define WM8995_GP13_FN_SHIFT 0 /* GP13_FN - [4:0] */ +#define WM8995_GP13_FN_WIDTH 5 /* GP13_FN - [4:0] */ + +/* + * R1805 (0x70D) - GPIO 14 + */ +#define WM8995_GP14_DIR 0x8000 /* GP14_DIR */ +#define WM8995_GP14_DIR_MASK 0x8000 /* GP14_DIR */ +#define WM8995_GP14_DIR_SHIFT 15 /* GP14_DIR */ +#define WM8995_GP14_DIR_WIDTH 1 /* GP14_DIR */ +#define WM8995_GP14_PU 0x4000 /* GP14_PU */ +#define WM8995_GP14_PU_MASK 0x4000 /* GP14_PU */ +#define WM8995_GP14_PU_SHIFT 14 /* GP14_PU */ +#define WM8995_GP14_PU_WIDTH 1 /* GP14_PU */ +#define WM8995_GP14_PD 0x2000 /* GP14_PD */ +#define WM8995_GP14_PD_MASK 0x2000 /* GP14_PD */ +#define WM8995_GP14_PD_SHIFT 13 /* GP14_PD */ +#define WM8995_GP14_PD_WIDTH 1 /* GP14_PD */ +#define WM8995_GP14_POL 0x0400 /* GP14_POL */ +#define WM8995_GP14_POL_MASK 0x0400 /* GP14_POL */ +#define WM8995_GP14_POL_SHIFT 10 /* GP14_POL */ +#define WM8995_GP14_POL_WIDTH 1 /* GP14_POL */ +#define WM8995_GP14_OP_CFG 0x0200 /* GP14_OP_CFG */ +#define WM8995_GP14_OP_CFG_MASK 0x0200 /* GP14_OP_CFG */ +#define WM8995_GP14_OP_CFG_SHIFT 9 /* GP14_OP_CFG */ +#define WM8995_GP14_OP_CFG_WIDTH 1 /* GP14_OP_CFG */ +#define WM8995_GP14_DB 0x0100 /* GP14_DB */ +#define WM8995_GP14_DB_MASK 0x0100 /* GP14_DB */ +#define WM8995_GP14_DB_SHIFT 8 /* GP14_DB */ +#define WM8995_GP14_DB_WIDTH 1 /* GP14_DB */ +#define WM8995_GP14_LVL 0x0040 /* GP14_LVL */ +#define WM8995_GP14_LVL_MASK 0x0040 /* GP14_LVL */ +#define WM8995_GP14_LVL_SHIFT 6 /* GP14_LVL */ +#define WM8995_GP14_LVL_WIDTH 1 /* GP14_LVL */ +#define WM8995_GP14_FN_MASK 0x001F /* GP14_FN - [4:0] */ +#define WM8995_GP14_FN_SHIFT 0 /* GP14_FN - [4:0] */ +#define WM8995_GP14_FN_WIDTH 5 /* GP14_FN - [4:0] */ + +/* + * R1824 (0x720) - Pull Control (1) + */ +#define WM8995_DMICDAT3_PD 0x4000 /* DMICDAT3_PD */ +#define WM8995_DMICDAT3_PD_MASK 0x4000 /* DMICDAT3_PD */ +#define WM8995_DMICDAT3_PD_SHIFT 14 /* DMICDAT3_PD */ +#define WM8995_DMICDAT3_PD_WIDTH 1 /* DMICDAT3_PD */ +#define WM8995_DMICDAT2_PD 0x1000 /* DMICDAT2_PD */ +#define WM8995_DMICDAT2_PD_MASK 0x1000 /* DMICDAT2_PD */ +#define WM8995_DMICDAT2_PD_SHIFT 12 /* DMICDAT2_PD */ +#define WM8995_DMICDAT2_PD_WIDTH 1 /* DMICDAT2_PD */ +#define WM8995_DMICDAT1_PD 0x0400 /* DMICDAT1_PD */ +#define WM8995_DMICDAT1_PD_MASK 0x0400 /* DMICDAT1_PD */ +#define WM8995_DMICDAT1_PD_SHIFT 10 /* DMICDAT1_PD */ +#define WM8995_DMICDAT1_PD_WIDTH 1 /* DMICDAT1_PD */ +#define WM8995_MCLK2_PU 0x0200 /* MCLK2_PU */ +#define WM8995_MCLK2_PU_MASK 0x0200 /* MCLK2_PU */ +#define WM8995_MCLK2_PU_SHIFT 9 /* MCLK2_PU */ +#define WM8995_MCLK2_PU_WIDTH 1 /* MCLK2_PU */ +#define WM8995_MCLK2_PD 0x0100 /* MCLK2_PD */ +#define WM8995_MCLK2_PD_MASK 0x0100 /* MCLK2_PD */ +#define WM8995_MCLK2_PD_SHIFT 8 /* MCLK2_PD */ +#define WM8995_MCLK2_PD_WIDTH 1 /* MCLK2_PD */ +#define WM8995_MCLK1_PU 0x0080 /* MCLK1_PU */ +#define WM8995_MCLK1_PU_MASK 0x0080 /* MCLK1_PU */ +#define WM8995_MCLK1_PU_SHIFT 7 /* MCLK1_PU */ +#define WM8995_MCLK1_PU_WIDTH 1 /* MCLK1_PU */ +#define WM8995_MCLK1_PD 0x0040 /* MCLK1_PD */ +#define WM8995_MCLK1_PD_MASK 0x0040 /* MCLK1_PD */ +#define WM8995_MCLK1_PD_SHIFT 6 /* MCLK1_PD */ +#define WM8995_MCLK1_PD_WIDTH 1 /* MCLK1_PD */ +#define WM8995_DACDAT1_PU 0x0020 /* DACDAT1_PU */ +#define WM8995_DACDAT1_PU_MASK 0x0020 /* DACDAT1_PU */ +#define WM8995_DACDAT1_PU_SHIFT 5 /* DACDAT1_PU */ +#define WM8995_DACDAT1_PU_WIDTH 1 /* DACDAT1_PU */ +#define WM8995_DACDAT1_PD 0x0010 /* DACDAT1_PD */ +#define WM8995_DACDAT1_PD_MASK 0x0010 /* DACDAT1_PD */ +#define WM8995_DACDAT1_PD_SHIFT 4 /* DACDAT1_PD */ +#define WM8995_DACDAT1_PD_WIDTH 1 /* DACDAT1_PD */ +#define WM8995_DACLRCLK1_PU 0x0008 /* DACLRCLK1_PU */ +#define WM8995_DACLRCLK1_PU_MASK 0x0008 /* DACLRCLK1_PU */ +#define WM8995_DACLRCLK1_PU_SHIFT 3 /* DACLRCLK1_PU */ +#define WM8995_DACLRCLK1_PU_WIDTH 1 /* DACLRCLK1_PU */ +#define WM8995_DACLRCLK1_PD 0x0004 /* DACLRCLK1_PD */ +#define WM8995_DACLRCLK1_PD_MASK 0x0004 /* DACLRCLK1_PD */ +#define WM8995_DACLRCLK1_PD_SHIFT 2 /* DACLRCLK1_PD */ +#define WM8995_DACLRCLK1_PD_WIDTH 1 /* DACLRCLK1_PD */ +#define WM8995_BCLK1_PU 0x0002 /* BCLK1_PU */ +#define WM8995_BCLK1_PU_MASK 0x0002 /* BCLK1_PU */ +#define WM8995_BCLK1_PU_SHIFT 1 /* BCLK1_PU */ +#define WM8995_BCLK1_PU_WIDTH 1 /* BCLK1_PU */ +#define WM8995_BCLK1_PD 0x0001 /* BCLK1_PD */ +#define WM8995_BCLK1_PD_MASK 0x0001 /* BCLK1_PD */ +#define WM8995_BCLK1_PD_SHIFT 0 /* BCLK1_PD */ +#define WM8995_BCLK1_PD_WIDTH 1 /* BCLK1_PD */ + +/* + * R1825 (0x721) - Pull Control (2) + */ +#define WM8995_LDO1ENA_PD 0x0010 /* LDO1ENA_PD */ +#define WM8995_LDO1ENA_PD_MASK 0x0010 /* LDO1ENA_PD */ +#define WM8995_LDO1ENA_PD_SHIFT 4 /* LDO1ENA_PD */ +#define WM8995_LDO1ENA_PD_WIDTH 1 /* LDO1ENA_PD */ +#define WM8995_MODE_PD 0x0004 /* MODE_PD */ +#define WM8995_MODE_PD_MASK 0x0004 /* MODE_PD */ +#define WM8995_MODE_PD_SHIFT 2 /* MODE_PD */ +#define WM8995_MODE_PD_WIDTH 1 /* MODE_PD */ +#define WM8995_CSNADDR_PD 0x0001 /* CSNADDR_PD */ +#define WM8995_CSNADDR_PD_MASK 0x0001 /* CSNADDR_PD */ +#define WM8995_CSNADDR_PD_SHIFT 0 /* CSNADDR_PD */ +#define WM8995_CSNADDR_PD_WIDTH 1 /* CSNADDR_PD */ + +/* + * R1840 (0x730) - Interrupt Status 1 + */ +#define WM8995_GP14_EINT 0x2000 /* GP14_EINT */ +#define WM8995_GP14_EINT_MASK 0x2000 /* GP14_EINT */ +#define WM8995_GP14_EINT_SHIFT 13 /* GP14_EINT */ +#define WM8995_GP14_EINT_WIDTH 1 /* GP14_EINT */ +#define WM8995_GP13_EINT 0x1000 /* GP13_EINT */ +#define WM8995_GP13_EINT_MASK 0x1000 /* GP13_EINT */ +#define WM8995_GP13_EINT_SHIFT 12 /* GP13_EINT */ +#define WM8995_GP13_EINT_WIDTH 1 /* GP13_EINT */ +#define WM8995_GP12_EINT 0x0800 /* GP12_EINT */ +#define WM8995_GP12_EINT_MASK 0x0800 /* GP12_EINT */ +#define WM8995_GP12_EINT_SHIFT 11 /* GP12_EINT */ +#define WM8995_GP12_EINT_WIDTH 1 /* GP12_EINT */ +#define WM8995_GP11_EINT 0x0400 /* GP11_EINT */ +#define WM8995_GP11_EINT_MASK 0x0400 /* GP11_EINT */ +#define WM8995_GP11_EINT_SHIFT 10 /* GP11_EINT */ +#define WM8995_GP11_EINT_WIDTH 1 /* GP11_EINT */ +#define WM8995_GP10_EINT 0x0200 /* GP10_EINT */ +#define WM8995_GP10_EINT_MASK 0x0200 /* GP10_EINT */ +#define WM8995_GP10_EINT_SHIFT 9 /* GP10_EINT */ +#define WM8995_GP10_EINT_WIDTH 1 /* GP10_EINT */ +#define WM8995_GP9_EINT 0x0100 /* GP9_EINT */ +#define WM8995_GP9_EINT_MASK 0x0100 /* GP9_EINT */ +#define WM8995_GP9_EINT_SHIFT 8 /* GP9_EINT */ +#define WM8995_GP9_EINT_WIDTH 1 /* GP9_EINT */ +#define WM8995_GP8_EINT 0x0080 /* GP8_EINT */ +#define WM8995_GP8_EINT_MASK 0x0080 /* GP8_EINT */ +#define WM8995_GP8_EINT_SHIFT 7 /* GP8_EINT */ +#define WM8995_GP8_EINT_WIDTH 1 /* GP8_EINT */ +#define WM8995_GP7_EINT 0x0040 /* GP7_EINT */ +#define WM8995_GP7_EINT_MASK 0x0040 /* GP7_EINT */ +#define WM8995_GP7_EINT_SHIFT 6 /* GP7_EINT */ +#define WM8995_GP7_EINT_WIDTH 1 /* GP7_EINT */ +#define WM8995_GP6_EINT 0x0020 /* GP6_EINT */ +#define WM8995_GP6_EINT_MASK 0x0020 /* GP6_EINT */ +#define WM8995_GP6_EINT_SHIFT 5 /* GP6_EINT */ +#define WM8995_GP6_EINT_WIDTH 1 /* GP6_EINT */ +#define WM8995_GP5_EINT 0x0010 /* GP5_EINT */ +#define WM8995_GP5_EINT_MASK 0x0010 /* GP5_EINT */ +#define WM8995_GP5_EINT_SHIFT 4 /* GP5_EINT */ +#define WM8995_GP5_EINT_WIDTH 1 /* GP5_EINT */ +#define WM8995_GP4_EINT 0x0008 /* GP4_EINT */ +#define WM8995_GP4_EINT_MASK 0x0008 /* GP4_EINT */ +#define WM8995_GP4_EINT_SHIFT 3 /* GP4_EINT */ +#define WM8995_GP4_EINT_WIDTH 1 /* GP4_EINT */ +#define WM8995_GP3_EINT 0x0004 /* GP3_EINT */ +#define WM8995_GP3_EINT_MASK 0x0004 /* GP3_EINT */ +#define WM8995_GP3_EINT_SHIFT 2 /* GP3_EINT */ +#define WM8995_GP3_EINT_WIDTH 1 /* GP3_EINT */ +#define WM8995_GP2_EINT 0x0002 /* GP2_EINT */ +#define WM8995_GP2_EINT_MASK 0x0002 /* GP2_EINT */ +#define WM8995_GP2_EINT_SHIFT 1 /* GP2_EINT */ +#define WM8995_GP2_EINT_WIDTH 1 /* GP2_EINT */ +#define WM8995_GP1_EINT 0x0001 /* GP1_EINT */ +#define WM8995_GP1_EINT_MASK 0x0001 /* GP1_EINT */ +#define WM8995_GP1_EINT_SHIFT 0 /* GP1_EINT */ +#define WM8995_GP1_EINT_WIDTH 1 /* GP1_EINT */ + +/* + * R1841 (0x731) - Interrupt Status 2 + */ +#define WM8995_DCS_DONE_23_EINT 0x1000 /* DCS_DONE_23_EINT */ +#define WM8995_DCS_DONE_23_EINT_MASK 0x1000 /* DCS_DONE_23_EINT */ +#define WM8995_DCS_DONE_23_EINT_SHIFT 12 /* DCS_DONE_23_EINT */ +#define WM8995_DCS_DONE_23_EINT_WIDTH 1 /* DCS_DONE_23_EINT */ +#define WM8995_DCS_DONE_01_EINT 0x0800 /* DCS_DONE_01_EINT */ +#define WM8995_DCS_DONE_01_EINT_MASK 0x0800 /* DCS_DONE_01_EINT */ +#define WM8995_DCS_DONE_01_EINT_SHIFT 11 /* DCS_DONE_01_EINT */ +#define WM8995_DCS_DONE_01_EINT_WIDTH 1 /* DCS_DONE_01_EINT */ +#define WM8995_WSEQ_DONE_EINT 0x0400 /* WSEQ_DONE_EINT */ +#define WM8995_WSEQ_DONE_EINT_MASK 0x0400 /* WSEQ_DONE_EINT */ +#define WM8995_WSEQ_DONE_EINT_SHIFT 10 /* WSEQ_DONE_EINT */ +#define WM8995_WSEQ_DONE_EINT_WIDTH 1 /* WSEQ_DONE_EINT */ +#define WM8995_FIFOS_ERR_EINT 0x0200 /* FIFOS_ERR_EINT */ +#define WM8995_FIFOS_ERR_EINT_MASK 0x0200 /* FIFOS_ERR_EINT */ +#define WM8995_FIFOS_ERR_EINT_SHIFT 9 /* FIFOS_ERR_EINT */ +#define WM8995_FIFOS_ERR_EINT_WIDTH 1 /* FIFOS_ERR_EINT */ +#define WM8995_AIF2DRC_SIG_DET_EINT 0x0100 /* AIF2DRC_SIG_DET_EINT */ +#define WM8995_AIF2DRC_SIG_DET_EINT_MASK 0x0100 /* AIF2DRC_SIG_DET_EINT */ +#define WM8995_AIF2DRC_SIG_DET_EINT_SHIFT 8 /* AIF2DRC_SIG_DET_EINT */ +#define WM8995_AIF2DRC_SIG_DET_EINT_WIDTH 1 /* AIF2DRC_SIG_DET_EINT */ +#define WM8995_AIF1DRC2_SIG_DET_EINT 0x0080 /* AIF1DRC2_SIG_DET_EINT */ +#define WM8995_AIF1DRC2_SIG_DET_EINT_MASK 0x0080 /* AIF1DRC2_SIG_DET_EINT */ +#define WM8995_AIF1DRC2_SIG_DET_EINT_SHIFT 7 /* AIF1DRC2_SIG_DET_EINT */ +#define WM8995_AIF1DRC2_SIG_DET_EINT_WIDTH 1 /* AIF1DRC2_SIG_DET_EINT */ +#define WM8995_AIF1DRC1_SIG_DET_EINT 0x0040 /* AIF1DRC1_SIG_DET_EINT */ +#define WM8995_AIF1DRC1_SIG_DET_EINT_MASK 0x0040 /* AIF1DRC1_SIG_DET_EINT */ +#define WM8995_AIF1DRC1_SIG_DET_EINT_SHIFT 6 /* AIF1DRC1_SIG_DET_EINT */ +#define WM8995_AIF1DRC1_SIG_DET_EINT_WIDTH 1 /* AIF1DRC1_SIG_DET_EINT */ +#define WM8995_SRC2_LOCK_EINT 0x0020 /* SRC2_LOCK_EINT */ +#define WM8995_SRC2_LOCK_EINT_MASK 0x0020 /* SRC2_LOCK_EINT */ +#define WM8995_SRC2_LOCK_EINT_SHIFT 5 /* SRC2_LOCK_EINT */ +#define WM8995_SRC2_LOCK_EINT_WIDTH 1 /* SRC2_LOCK_EINT */ +#define WM8995_SRC1_LOCK_EINT 0x0010 /* SRC1_LOCK_EINT */ +#define WM8995_SRC1_LOCK_EINT_MASK 0x0010 /* SRC1_LOCK_EINT */ +#define WM8995_SRC1_LOCK_EINT_SHIFT 4 /* SRC1_LOCK_EINT */ +#define WM8995_SRC1_LOCK_EINT_WIDTH 1 /* SRC1_LOCK_EINT */ +#define WM8995_FLL2_LOCK_EINT 0x0008 /* FLL2_LOCK_EINT */ +#define WM8995_FLL2_LOCK_EINT_MASK 0x0008 /* FLL2_LOCK_EINT */ +#define WM8995_FLL2_LOCK_EINT_SHIFT 3 /* FLL2_LOCK_EINT */ +#define WM8995_FLL2_LOCK_EINT_WIDTH 1 /* FLL2_LOCK_EINT */ +#define WM8995_FLL1_LOCK_EINT 0x0004 /* FLL1_LOCK_EINT */ +#define WM8995_FLL1_LOCK_EINT_MASK 0x0004 /* FLL1_LOCK_EINT */ +#define WM8995_FLL1_LOCK_EINT_SHIFT 2 /* FLL1_LOCK_EINT */ +#define WM8995_FLL1_LOCK_EINT_WIDTH 1 /* FLL1_LOCK_EINT */ +#define WM8995_HP_DONE_EINT 0x0002 /* HP_DONE_EINT */ +#define WM8995_HP_DONE_EINT_MASK 0x0002 /* HP_DONE_EINT */ +#define WM8995_HP_DONE_EINT_SHIFT 1 /* HP_DONE_EINT */ +#define WM8995_HP_DONE_EINT_WIDTH 1 /* HP_DONE_EINT */ +#define WM8995_MICD_EINT 0x0001 /* MICD_EINT */ +#define WM8995_MICD_EINT_MASK 0x0001 /* MICD_EINT */ +#define WM8995_MICD_EINT_SHIFT 0 /* MICD_EINT */ +#define WM8995_MICD_EINT_WIDTH 1 /* MICD_EINT */ + +/* + * R1842 (0x732) - Interrupt Raw Status 2 + */ +#define WM8995_DCS_DONE_23_STS 0x1000 /* DCS_DONE_23_STS */ +#define WM8995_DCS_DONE_23_STS_MASK 0x1000 /* DCS_DONE_23_STS */ +#define WM8995_DCS_DONE_23_STS_SHIFT 12 /* DCS_DONE_23_STS */ +#define WM8995_DCS_DONE_23_STS_WIDTH 1 /* DCS_DONE_23_STS */ +#define WM8995_DCS_DONE_01_STS 0x0800 /* DCS_DONE_01_STS */ +#define WM8995_DCS_DONE_01_STS_MASK 0x0800 /* DCS_DONE_01_STS */ +#define WM8995_DCS_DONE_01_STS_SHIFT 11 /* DCS_DONE_01_STS */ +#define WM8995_DCS_DONE_01_STS_WIDTH 1 /* DCS_DONE_01_STS */ +#define WM8995_WSEQ_DONE_STS 0x0400 /* WSEQ_DONE_STS */ +#define WM8995_WSEQ_DONE_STS_MASK 0x0400 /* WSEQ_DONE_STS */ +#define WM8995_WSEQ_DONE_STS_SHIFT 10 /* WSEQ_DONE_STS */ +#define WM8995_WSEQ_DONE_STS_WIDTH 1 /* WSEQ_DONE_STS */ +#define WM8995_FIFOS_ERR_STS 0x0200 /* FIFOS_ERR_STS */ +#define WM8995_FIFOS_ERR_STS_MASK 0x0200 /* FIFOS_ERR_STS */ +#define WM8995_FIFOS_ERR_STS_SHIFT 9 /* FIFOS_ERR_STS */ +#define WM8995_FIFOS_ERR_STS_WIDTH 1 /* FIFOS_ERR_STS */ +#define WM8995_AIF2DRC_SIG_DET_STS 0x0100 /* AIF2DRC_SIG_DET_STS */ +#define WM8995_AIF2DRC_SIG_DET_STS_MASK 0x0100 /* AIF2DRC_SIG_DET_STS */ +#define WM8995_AIF2DRC_SIG_DET_STS_SHIFT 8 /* AIF2DRC_SIG_DET_STS */ +#define WM8995_AIF2DRC_SIG_DET_STS_WIDTH 1 /* AIF2DRC_SIG_DET_STS */ +#define WM8995_AIF1DRC2_SIG_DET_STS 0x0080 /* AIF1DRC2_SIG_DET_STS */ +#define WM8995_AIF1DRC2_SIG_DET_STS_MASK 0x0080 /* AIF1DRC2_SIG_DET_STS */ +#define WM8995_AIF1DRC2_SIG_DET_STS_SHIFT 7 /* AIF1DRC2_SIG_DET_STS */ +#define WM8995_AIF1DRC2_SIG_DET_STS_WIDTH 1 /* AIF1DRC2_SIG_DET_STS */ +#define WM8995_AIF1DRC1_SIG_DET_STS 0x0040 /* AIF1DRC1_SIG_DET_STS */ +#define WM8995_AIF1DRC1_SIG_DET_STS_MASK 0x0040 /* AIF1DRC1_SIG_DET_STS */ +#define WM8995_AIF1DRC1_SIG_DET_STS_SHIFT 6 /* AIF1DRC1_SIG_DET_STS */ +#define WM8995_AIF1DRC1_SIG_DET_STS_WIDTH 1 /* AIF1DRC1_SIG_DET_STS */ +#define WM8995_SRC2_LOCK_STS 0x0020 /* SRC2_LOCK_STS */ +#define WM8995_SRC2_LOCK_STS_MASK 0x0020 /* SRC2_LOCK_STS */ +#define WM8995_SRC2_LOCK_STS_SHIFT 5 /* SRC2_LOCK_STS */ +#define WM8995_SRC2_LOCK_STS_WIDTH 1 /* SRC2_LOCK_STS */ +#define WM8995_SRC1_LOCK_STS 0x0010 /* SRC1_LOCK_STS */ +#define WM8995_SRC1_LOCK_STS_MASK 0x0010 /* SRC1_LOCK_STS */ +#define WM8995_SRC1_LOCK_STS_SHIFT 4 /* SRC1_LOCK_STS */ +#define WM8995_SRC1_LOCK_STS_WIDTH 1 /* SRC1_LOCK_STS */ +#define WM8995_FLL2_LOCK_STS 0x0008 /* FLL2_LOCK_STS */ +#define WM8995_FLL2_LOCK_STS_MASK 0x0008 /* FLL2_LOCK_STS */ +#define WM8995_FLL2_LOCK_STS_SHIFT 3 /* FLL2_LOCK_STS */ +#define WM8995_FLL2_LOCK_STS_WIDTH 1 /* FLL2_LOCK_STS */ +#define WM8995_FLL1_LOCK_STS 0x0004 /* FLL1_LOCK_STS */ +#define WM8995_FLL1_LOCK_STS_MASK 0x0004 /* FLL1_LOCK_STS */ +#define WM8995_FLL1_LOCK_STS_SHIFT 2 /* FLL1_LOCK_STS */ +#define WM8995_FLL1_LOCK_STS_WIDTH 1 /* FLL1_LOCK_STS */ + +/* + * R1848 (0x738) - Interrupt Status 1 Mask + */ +#define WM8995_IM_GP14_EINT 0x2000 /* IM_GP14_EINT */ +#define WM8995_IM_GP14_EINT_MASK 0x2000 /* IM_GP14_EINT */ +#define WM8995_IM_GP14_EINT_SHIFT 13 /* IM_GP14_EINT */ +#define WM8995_IM_GP14_EINT_WIDTH 1 /* IM_GP14_EINT */ +#define WM8995_IM_GP13_EINT 0x1000 /* IM_GP13_EINT */ +#define WM8995_IM_GP13_EINT_MASK 0x1000 /* IM_GP13_EINT */ +#define WM8995_IM_GP13_EINT_SHIFT 12 /* IM_GP13_EINT */ +#define WM8995_IM_GP13_EINT_WIDTH 1 /* IM_GP13_EINT */ +#define WM8995_IM_GP12_EINT 0x0800 /* IM_GP12_EINT */ +#define WM8995_IM_GP12_EINT_MASK 0x0800 /* IM_GP12_EINT */ +#define WM8995_IM_GP12_EINT_SHIFT 11 /* IM_GP12_EINT */ +#define WM8995_IM_GP12_EINT_WIDTH 1 /* IM_GP12_EINT */ +#define WM8995_IM_GP11_EINT 0x0400 /* IM_GP11_EINT */ +#define WM8995_IM_GP11_EINT_MASK 0x0400 /* IM_GP11_EINT */ +#define WM8995_IM_GP11_EINT_SHIFT 10 /* IM_GP11_EINT */ +#define WM8995_IM_GP11_EINT_WIDTH 1 /* IM_GP11_EINT */ +#define WM8995_IM_GP10_EINT 0x0200 /* IM_GP10_EINT */ +#define WM8995_IM_GP10_EINT_MASK 0x0200 /* IM_GP10_EINT */ +#define WM8995_IM_GP10_EINT_SHIFT 9 /* IM_GP10_EINT */ +#define WM8995_IM_GP10_EINT_WIDTH 1 /* IM_GP10_EINT */ +#define WM8995_IM_GP9_EINT 0x0100 /* IM_GP9_EINT */ +#define WM8995_IM_GP9_EINT_MASK 0x0100 /* IM_GP9_EINT */ +#define WM8995_IM_GP9_EINT_SHIFT 8 /* IM_GP9_EINT */ +#define WM8995_IM_GP9_EINT_WIDTH 1 /* IM_GP9_EINT */ +#define WM8995_IM_GP8_EINT 0x0080 /* IM_GP8_EINT */ +#define WM8995_IM_GP8_EINT_MASK 0x0080 /* IM_GP8_EINT */ +#define WM8995_IM_GP8_EINT_SHIFT 7 /* IM_GP8_EINT */ +#define WM8995_IM_GP8_EINT_WIDTH 1 /* IM_GP8_EINT */ +#define WM8995_IM_GP7_EINT 0x0040 /* IM_GP7_EINT */ +#define WM8995_IM_GP7_EINT_MASK 0x0040 /* IM_GP7_EINT */ +#define WM8995_IM_GP7_EINT_SHIFT 6 /* IM_GP7_EINT */ +#define WM8995_IM_GP7_EINT_WIDTH 1 /* IM_GP7_EINT */ +#define WM8995_IM_GP6_EINT 0x0020 /* IM_GP6_EINT */ +#define WM8995_IM_GP6_EINT_MASK 0x0020 /* IM_GP6_EINT */ +#define WM8995_IM_GP6_EINT_SHIFT 5 /* IM_GP6_EINT */ +#define WM8995_IM_GP6_EINT_WIDTH 1 /* IM_GP6_EINT */ +#define WM8995_IM_GP5_EINT 0x0010 /* IM_GP5_EINT */ +#define WM8995_IM_GP5_EINT_MASK 0x0010 /* IM_GP5_EINT */ +#define WM8995_IM_GP5_EINT_SHIFT 4 /* IM_GP5_EINT */ +#define WM8995_IM_GP5_EINT_WIDTH 1 /* IM_GP5_EINT */ +#define WM8995_IM_GP4_EINT 0x0008 /* IM_GP4_EINT */ +#define WM8995_IM_GP4_EINT_MASK 0x0008 /* IM_GP4_EINT */ +#define WM8995_IM_GP4_EINT_SHIFT 3 /* IM_GP4_EINT */ +#define WM8995_IM_GP4_EINT_WIDTH 1 /* IM_GP4_EINT */ +#define WM8995_IM_GP3_EINT 0x0004 /* IM_GP3_EINT */ +#define WM8995_IM_GP3_EINT_MASK 0x0004 /* IM_GP3_EINT */ +#define WM8995_IM_GP3_EINT_SHIFT 2 /* IM_GP3_EINT */ +#define WM8995_IM_GP3_EINT_WIDTH 1 /* IM_GP3_EINT */ +#define WM8995_IM_GP2_EINT 0x0002 /* IM_GP2_EINT */ +#define WM8995_IM_GP2_EINT_MASK 0x0002 /* IM_GP2_EINT */ +#define WM8995_IM_GP2_EINT_SHIFT 1 /* IM_GP2_EINT */ +#define WM8995_IM_GP2_EINT_WIDTH 1 /* IM_GP2_EINT */ +#define WM8995_IM_GP1_EINT 0x0001 /* IM_GP1_EINT */ +#define WM8995_IM_GP1_EINT_MASK 0x0001 /* IM_GP1_EINT */ +#define WM8995_IM_GP1_EINT_SHIFT 0 /* IM_GP1_EINT */ +#define WM8995_IM_GP1_EINT_WIDTH 1 /* IM_GP1_EINT */ + +/* + * R1849 (0x739) - Interrupt Status 2 Mask + */ +#define WM8995_IM_DCS_DONE_23_EINT 0x1000 /* IM_DCS_DONE_23_EINT */ +#define WM8995_IM_DCS_DONE_23_EINT_MASK 0x1000 /* IM_DCS_DONE_23_EINT */ +#define WM8995_IM_DCS_DONE_23_EINT_SHIFT 12 /* IM_DCS_DONE_23_EINT */ +#define WM8995_IM_DCS_DONE_23_EINT_WIDTH 1 /* IM_DCS_DONE_23_EINT */ +#define WM8995_IM_DCS_DONE_01_EINT 0x0800 /* IM_DCS_DONE_01_EINT */ +#define WM8995_IM_DCS_DONE_01_EINT_MASK 0x0800 /* IM_DCS_DONE_01_EINT */ +#define WM8995_IM_DCS_DONE_01_EINT_SHIFT 11 /* IM_DCS_DONE_01_EINT */ +#define WM8995_IM_DCS_DONE_01_EINT_WIDTH 1 /* IM_DCS_DONE_01_EINT */ +#define WM8995_IM_WSEQ_DONE_EINT 0x0400 /* IM_WSEQ_DONE_EINT */ +#define WM8995_IM_WSEQ_DONE_EINT_MASK 0x0400 /* IM_WSEQ_DONE_EINT */ +#define WM8995_IM_WSEQ_DONE_EINT_SHIFT 10 /* IM_WSEQ_DONE_EINT */ +#define WM8995_IM_WSEQ_DONE_EINT_WIDTH 1 /* IM_WSEQ_DONE_EINT */ +#define WM8995_IM_FIFOS_ERR_EINT 0x0200 /* IM_FIFOS_ERR_EINT */ +#define WM8995_IM_FIFOS_ERR_EINT_MASK 0x0200 /* IM_FIFOS_ERR_EINT */ +#define WM8995_IM_FIFOS_ERR_EINT_SHIFT 9 /* IM_FIFOS_ERR_EINT */ +#define WM8995_IM_FIFOS_ERR_EINT_WIDTH 1 /* IM_FIFOS_ERR_EINT */ +#define WM8995_IM_AIF2DRC_SIG_DET_EINT 0x0100 /* IM_AIF2DRC_SIG_DET_EINT */ +#define WM8995_IM_AIF2DRC_SIG_DET_EINT_MASK 0x0100 /* IM_AIF2DRC_SIG_DET_EINT */ +#define WM8995_IM_AIF2DRC_SIG_DET_EINT_SHIFT 8 /* IM_AIF2DRC_SIG_DET_EINT */ +#define WM8995_IM_AIF2DRC_SIG_DET_EINT_WIDTH 1 /* IM_AIF2DRC_SIG_DET_EINT */ +#define WM8995_IM_AIF1DRC2_SIG_DET_EINT 0x0080 /* IM_AIF1DRC2_SIG_DET_EINT */ +#define WM8995_IM_AIF1DRC2_SIG_DET_EINT_MASK 0x0080 /* IM_AIF1DRC2_SIG_DET_EINT */ +#define WM8995_IM_AIF1DRC2_SIG_DET_EINT_SHIFT 7 /* IM_AIF1DRC2_SIG_DET_EINT */ +#define WM8995_IM_AIF1DRC2_SIG_DET_EINT_WIDTH 1 /* IM_AIF1DRC2_SIG_DET_EINT */ +#define WM8995_IM_AIF1DRC1_SIG_DET_EINT 0x0040 /* IM_AIF1DRC1_SIG_DET_EINT */ +#define WM8995_IM_AIF1DRC1_SIG_DET_EINT_MASK 0x0040 /* IM_AIF1DRC1_SIG_DET_EINT */ +#define WM8995_IM_AIF1DRC1_SIG_DET_EINT_SHIFT 6 /* IM_AIF1DRC1_SIG_DET_EINT */ +#define WM8995_IM_AIF1DRC1_SIG_DET_EINT_WIDTH 1 /* IM_AIF1DRC1_SIG_DET_EINT */ +#define WM8995_IM_SRC2_LOCK_EINT 0x0020 /* IM_SRC2_LOCK_EINT */ +#define WM8995_IM_SRC2_LOCK_EINT_MASK 0x0020 /* IM_SRC2_LOCK_EINT */ +#define WM8995_IM_SRC2_LOCK_EINT_SHIFT 5 /* IM_SRC2_LOCK_EINT */ +#define WM8995_IM_SRC2_LOCK_EINT_WIDTH 1 /* IM_SRC2_LOCK_EINT */ +#define WM8995_IM_SRC1_LOCK_EINT 0x0010 /* IM_SRC1_LOCK_EINT */ +#define WM8995_IM_SRC1_LOCK_EINT_MASK 0x0010 /* IM_SRC1_LOCK_EINT */ +#define WM8995_IM_SRC1_LOCK_EINT_SHIFT 4 /* IM_SRC1_LOCK_EINT */ +#define WM8995_IM_SRC1_LOCK_EINT_WIDTH 1 /* IM_SRC1_LOCK_EINT */ +#define WM8995_IM_FLL2_LOCK_EINT 0x0008 /* IM_FLL2_LOCK_EINT */ +#define WM8995_IM_FLL2_LOCK_EINT_MASK 0x0008 /* IM_FLL2_LOCK_EINT */ +#define WM8995_IM_FLL2_LOCK_EINT_SHIFT 3 /* IM_FLL2_LOCK_EINT */ +#define WM8995_IM_FLL2_LOCK_EINT_WIDTH 1 /* IM_FLL2_LOCK_EINT */ +#define WM8995_IM_FLL1_LOCK_EINT 0x0004 /* IM_FLL1_LOCK_EINT */ +#define WM8995_IM_FLL1_LOCK_EINT_MASK 0x0004 /* IM_FLL1_LOCK_EINT */ +#define WM8995_IM_FLL1_LOCK_EINT_SHIFT 2 /* IM_FLL1_LOCK_EINT */ +#define WM8995_IM_FLL1_LOCK_EINT_WIDTH 1 /* IM_FLL1_LOCK_EINT */ +#define WM8995_IM_HP_DONE_EINT 0x0002 /* IM_HP_DONE_EINT */ +#define WM8995_IM_HP_DONE_EINT_MASK 0x0002 /* IM_HP_DONE_EINT */ +#define WM8995_IM_HP_DONE_EINT_SHIFT 1 /* IM_HP_DONE_EINT */ +#define WM8995_IM_HP_DONE_EINT_WIDTH 1 /* IM_HP_DONE_EINT */ +#define WM8995_IM_MICD_EINT 0x0001 /* IM_MICD_EINT */ +#define WM8995_IM_MICD_EINT_MASK 0x0001 /* IM_MICD_EINT */ +#define WM8995_IM_MICD_EINT_SHIFT 0 /* IM_MICD_EINT */ +#define WM8995_IM_MICD_EINT_WIDTH 1 /* IM_MICD_EINT */ + +/* + * R1856 (0x740) - Interrupt Control + */ +#define WM8995_IM_IRQ 0x0001 /* IM_IRQ */ +#define WM8995_IM_IRQ_MASK 0x0001 /* IM_IRQ */ +#define WM8995_IM_IRQ_SHIFT 0 /* IM_IRQ */ +#define WM8995_IM_IRQ_WIDTH 1 /* IM_IRQ */ + +/* + * R2048 (0x800) - Left PDM Speaker 1 + */ +#define WM8995_SPK1L_ENA 0x0010 /* SPK1L_ENA */ +#define WM8995_SPK1L_ENA_MASK 0x0010 /* SPK1L_ENA */ +#define WM8995_SPK1L_ENA_SHIFT 4 /* SPK1L_ENA */ +#define WM8995_SPK1L_ENA_WIDTH 1 /* SPK1L_ENA */ +#define WM8995_SPK1L_MUTE 0x0008 /* SPK1L_MUTE */ +#define WM8995_SPK1L_MUTE_MASK 0x0008 /* SPK1L_MUTE */ +#define WM8995_SPK1L_MUTE_SHIFT 3 /* SPK1L_MUTE */ +#define WM8995_SPK1L_MUTE_WIDTH 1 /* SPK1L_MUTE */ +#define WM8995_SPK1L_MUTE_ZC 0x0004 /* SPK1L_MUTE_ZC */ +#define WM8995_SPK1L_MUTE_ZC_MASK 0x0004 /* SPK1L_MUTE_ZC */ +#define WM8995_SPK1L_MUTE_ZC_SHIFT 2 /* SPK1L_MUTE_ZC */ +#define WM8995_SPK1L_MUTE_ZC_WIDTH 1 /* SPK1L_MUTE_ZC */ +#define WM8995_SPK1L_SRC_MASK 0x0003 /* SPK1L_SRC - [1:0] */ +#define WM8995_SPK1L_SRC_SHIFT 0 /* SPK1L_SRC - [1:0] */ +#define WM8995_SPK1L_SRC_WIDTH 2 /* SPK1L_SRC - [1:0] */ + +/* + * R2049 (0x801) - Right PDM Speaker 1 + */ +#define WM8995_SPK1R_ENA 0x0010 /* SPK1R_ENA */ +#define WM8995_SPK1R_ENA_MASK 0x0010 /* SPK1R_ENA */ +#define WM8995_SPK1R_ENA_SHIFT 4 /* SPK1R_ENA */ +#define WM8995_SPK1R_ENA_WIDTH 1 /* SPK1R_ENA */ +#define WM8995_SPK1R_MUTE 0x0008 /* SPK1R_MUTE */ +#define WM8995_SPK1R_MUTE_MASK 0x0008 /* SPK1R_MUTE */ +#define WM8995_SPK1R_MUTE_SHIFT 3 /* SPK1R_MUTE */ +#define WM8995_SPK1R_MUTE_WIDTH 1 /* SPK1R_MUTE */ +#define WM8995_SPK1R_MUTE_ZC 0x0004 /* SPK1R_MUTE_ZC */ +#define WM8995_SPK1R_MUTE_ZC_MASK 0x0004 /* SPK1R_MUTE_ZC */ +#define WM8995_SPK1R_MUTE_ZC_SHIFT 2 /* SPK1R_MUTE_ZC */ +#define WM8995_SPK1R_MUTE_ZC_WIDTH 1 /* SPK1R_MUTE_ZC */ +#define WM8995_SPK1R_SRC_MASK 0x0003 /* SPK1R_SRC - [1:0] */ +#define WM8995_SPK1R_SRC_SHIFT 0 /* SPK1R_SRC - [1:0] */ +#define WM8995_SPK1R_SRC_WIDTH 2 /* SPK1R_SRC - [1:0] */ + +/* + * R2050 (0x802) - PDM Speaker 1 Mute Sequence + */ +#define WM8995_SPK1_MUTE_SEQ1_MASK 0x00FF /* SPK1_MUTE_SEQ1 - [7:0] */ +#define WM8995_SPK1_MUTE_SEQ1_SHIFT 0 /* SPK1_MUTE_SEQ1 - [7:0] */ +#define WM8995_SPK1_MUTE_SEQ1_WIDTH 8 /* SPK1_MUTE_SEQ1 - [7:0] */ + +/* + * R2056 (0x808) - Left PDM Speaker 2 + */ +#define WM8995_SPK2L_ENA 0x0010 /* SPK2L_ENA */ +#define WM8995_SPK2L_ENA_MASK 0x0010 /* SPK2L_ENA */ +#define WM8995_SPK2L_ENA_SHIFT 4 /* SPK2L_ENA */ +#define WM8995_SPK2L_ENA_WIDTH 1 /* SPK2L_ENA */ +#define WM8995_SPK2L_MUTE 0x0008 /* SPK2L_MUTE */ +#define WM8995_SPK2L_MUTE_MASK 0x0008 /* SPK2L_MUTE */ +#define WM8995_SPK2L_MUTE_SHIFT 3 /* SPK2L_MUTE */ +#define WM8995_SPK2L_MUTE_WIDTH 1 /* SPK2L_MUTE */ +#define WM8995_SPK2L_MUTE_ZC 0x0004 /* SPK2L_MUTE_ZC */ +#define WM8995_SPK2L_MUTE_ZC_MASK 0x0004 /* SPK2L_MUTE_ZC */ +#define WM8995_SPK2L_MUTE_ZC_SHIFT 2 /* SPK2L_MUTE_ZC */ +#define WM8995_SPK2L_MUTE_ZC_WIDTH 1 /* SPK2L_MUTE_ZC */ +#define WM8995_SPK2L_SRC_MASK 0x0003 /* SPK2L_SRC - [1:0] */ +#define WM8995_SPK2L_SRC_SHIFT 0 /* SPK2L_SRC - [1:0] */ +#define WM8995_SPK2L_SRC_WIDTH 2 /* SPK2L_SRC - [1:0] */ + +/* + * R2057 (0x809) - Right PDM Speaker 2 + */ +#define WM8995_SPK2R_ENA 0x0010 /* SPK2R_ENA */ +#define WM8995_SPK2R_ENA_MASK 0x0010 /* SPK2R_ENA */ +#define WM8995_SPK2R_ENA_SHIFT 4 /* SPK2R_ENA */ +#define WM8995_SPK2R_ENA_WIDTH 1 /* SPK2R_ENA */ +#define WM8995_SPK2R_MUTE 0x0008 /* SPK2R_MUTE */ +#define WM8995_SPK2R_MUTE_MASK 0x0008 /* SPK2R_MUTE */ +#define WM8995_SPK2R_MUTE_SHIFT 3 /* SPK2R_MUTE */ +#define WM8995_SPK2R_MUTE_WIDTH 1 /* SPK2R_MUTE */ +#define WM8995_SPK2R_MUTE_ZC 0x0004 /* SPK2R_MUTE_ZC */ +#define WM8995_SPK2R_MUTE_ZC_MASK 0x0004 /* SPK2R_MUTE_ZC */ +#define WM8995_SPK2R_MUTE_ZC_SHIFT 2 /* SPK2R_MUTE_ZC */ +#define WM8995_SPK2R_MUTE_ZC_WIDTH 1 /* SPK2R_MUTE_ZC */ +#define WM8995_SPK2R_SRC_MASK 0x0003 /* SPK2R_SRC - [1:0] */ +#define WM8995_SPK2R_SRC_SHIFT 0 /* SPK2R_SRC - [1:0] */ +#define WM8995_SPK2R_SRC_WIDTH 2 /* SPK2R_SRC - [1:0] */ + +/* + * R2058 (0x80A) - PDM Speaker 2 Mute Sequence + */ +#define WM8995_SPK2_MUTE_SEQ1_MASK 0x00FF /* SPK2_MUTE_SEQ1 - [7:0] */ +#define WM8995_SPK2_MUTE_SEQ1_SHIFT 0 /* SPK2_MUTE_SEQ1 - [7:0] */ +#define WM8995_SPK2_MUTE_SEQ1_WIDTH 8 /* SPK2_MUTE_SEQ1 - [7:0] */ + +/* + * R12288 (0x3000) - Write Sequencer 0 + */ +#define WM8995_WSEQ_ADDR0_MASK 0x3FFF /* WSEQ_ADDR0 - [13:0] */ +#define WM8995_WSEQ_ADDR0_SHIFT 0 /* WSEQ_ADDR0 - [13:0] */ +#define WM8995_WSEQ_ADDR0_WIDTH 14 /* WSEQ_ADDR0 - [13:0] */ + +/* + * R12289 (0x3001) - Write Sequencer 1 + */ +#define WM8995_WSEQ_DATA0_MASK 0x00FF /* WSEQ_DATA0 - [7:0] */ +#define WM8995_WSEQ_DATA0_SHIFT 0 /* WSEQ_DATA0 - [7:0] */ +#define WM8995_WSEQ_DATA0_WIDTH 8 /* WSEQ_DATA0 - [7:0] */ + +/* + * R12290 (0x3002) - Write Sequencer 2 + */ +#define WM8995_WSEQ_DATA_WIDTH0_MASK 0x0700 /* WSEQ_DATA_WIDTH0 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH0_SHIFT 8 /* WSEQ_DATA_WIDTH0 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH0_WIDTH 3 /* WSEQ_DATA_WIDTH0 - [10:8] */ +#define WM8995_WSEQ_DATA_START0_MASK 0x000F /* WSEQ_DATA_START0 - [3:0] */ +#define WM8995_WSEQ_DATA_START0_SHIFT 0 /* WSEQ_DATA_START0 - [3:0] */ +#define WM8995_WSEQ_DATA_START0_WIDTH 4 /* WSEQ_DATA_START0 - [3:0] */ + +/* + * R12291 (0x3003) - Write Sequencer 3 + */ +#define WM8995_WSEQ_EOS0 0x0100 /* WSEQ_EOS0 */ +#define WM8995_WSEQ_EOS0_MASK 0x0100 /* WSEQ_EOS0 */ +#define WM8995_WSEQ_EOS0_SHIFT 8 /* WSEQ_EOS0 */ +#define WM8995_WSEQ_EOS0_WIDTH 1 /* WSEQ_EOS0 */ +#define WM8995_WSEQ_DELAY0_MASK 0x000F /* WSEQ_DELAY0 - [3:0] */ +#define WM8995_WSEQ_DELAY0_SHIFT 0 /* WSEQ_DELAY0 - [3:0] */ +#define WM8995_WSEQ_DELAY0_WIDTH 4 /* WSEQ_DELAY0 - [3:0] */ + +/* + * R12292 (0x3004) - Write Sequencer 4 + */ +#define WM8995_WSEQ_ADDR1_MASK 0x3FFF /* WSEQ_ADDR1 - [13:0] */ +#define WM8995_WSEQ_ADDR1_SHIFT 0 /* WSEQ_ADDR1 - [13:0] */ +#define WM8995_WSEQ_ADDR1_WIDTH 14 /* WSEQ_ADDR1 - [13:0] */ + +/* + * R12293 (0x3005) - Write Sequencer 5 + */ +#define WM8995_WSEQ_DATA1_MASK 0x00FF /* WSEQ_DATA1 - [7:0] */ +#define WM8995_WSEQ_DATA1_SHIFT 0 /* WSEQ_DATA1 - [7:0] */ +#define WM8995_WSEQ_DATA1_WIDTH 8 /* WSEQ_DATA1 - [7:0] */ + +/* + * R12294 (0x3006) - Write Sequencer 6 + */ +#define WM8995_WSEQ_DATA_WIDTH1_MASK 0x0700 /* WSEQ_DATA_WIDTH1 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH1_SHIFT 8 /* WSEQ_DATA_WIDTH1 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH1_WIDTH 3 /* WSEQ_DATA_WIDTH1 - [10:8] */ +#define WM8995_WSEQ_DATA_START1_MASK 0x000F /* WSEQ_DATA_START1 - [3:0] */ +#define WM8995_WSEQ_DATA_START1_SHIFT 0 /* WSEQ_DATA_START1 - [3:0] */ +#define WM8995_WSEQ_DATA_START1_WIDTH 4 /* WSEQ_DATA_START1 - [3:0] */ + +/* + * R12295 (0x3007) - Write Sequencer 7 + */ +#define WM8995_WSEQ_EOS1 0x0100 /* WSEQ_EOS1 */ +#define WM8995_WSEQ_EOS1_MASK 0x0100 /* WSEQ_EOS1 */ +#define WM8995_WSEQ_EOS1_SHIFT 8 /* WSEQ_EOS1 */ +#define WM8995_WSEQ_EOS1_WIDTH 1 /* WSEQ_EOS1 */ +#define WM8995_WSEQ_DELAY1_MASK 0x000F /* WSEQ_DELAY1 - [3:0] */ +#define WM8995_WSEQ_DELAY1_SHIFT 0 /* WSEQ_DELAY1 - [3:0] */ +#define WM8995_WSEQ_DELAY1_WIDTH 4 /* WSEQ_DELAY1 - [3:0] */ + +/* + * R12296 (0x3008) - Write Sequencer 8 + */ +#define WM8995_WSEQ_ADDR2_MASK 0x3FFF /* WSEQ_ADDR2 - [13:0] */ +#define WM8995_WSEQ_ADDR2_SHIFT 0 /* WSEQ_ADDR2 - [13:0] */ +#define WM8995_WSEQ_ADDR2_WIDTH 14 /* WSEQ_ADDR2 - [13:0] */ + +/* + * R12297 (0x3009) - Write Sequencer 9 + */ +#define WM8995_WSEQ_DATA2_MASK 0x00FF /* WSEQ_DATA2 - [7:0] */ +#define WM8995_WSEQ_DATA2_SHIFT 0 /* WSEQ_DATA2 - [7:0] */ +#define WM8995_WSEQ_DATA2_WIDTH 8 /* WSEQ_DATA2 - [7:0] */ + +/* + * R12298 (0x300A) - Write Sequencer 10 + */ +#define WM8995_WSEQ_DATA_WIDTH2_MASK 0x0700 /* WSEQ_DATA_WIDTH2 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH2_SHIFT 8 /* WSEQ_DATA_WIDTH2 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH2_WIDTH 3 /* WSEQ_DATA_WIDTH2 - [10:8] */ +#define WM8995_WSEQ_DATA_START2_MASK 0x000F /* WSEQ_DATA_START2 - [3:0] */ +#define WM8995_WSEQ_DATA_START2_SHIFT 0 /* WSEQ_DATA_START2 - [3:0] */ +#define WM8995_WSEQ_DATA_START2_WIDTH 4 /* WSEQ_DATA_START2 - [3:0] */ + +/* + * R12299 (0x300B) - Write Sequencer 11 + */ +#define WM8995_WSEQ_EOS2 0x0100 /* WSEQ_EOS2 */ +#define WM8995_WSEQ_EOS2_MASK 0x0100 /* WSEQ_EOS2 */ +#define WM8995_WSEQ_EOS2_SHIFT 8 /* WSEQ_EOS2 */ +#define WM8995_WSEQ_EOS2_WIDTH 1 /* WSEQ_EOS2 */ +#define WM8995_WSEQ_DELAY2_MASK 0x000F /* WSEQ_DELAY2 - [3:0] */ +#define WM8995_WSEQ_DELAY2_SHIFT 0 /* WSEQ_DELAY2 - [3:0] */ +#define WM8995_WSEQ_DELAY2_WIDTH 4 /* WSEQ_DELAY2 - [3:0] */ + +/* + * R12300 (0x300C) - Write Sequencer 12 + */ +#define WM8995_WSEQ_ADDR3_MASK 0x3FFF /* WSEQ_ADDR3 - [13:0] */ +#define WM8995_WSEQ_ADDR3_SHIFT 0 /* WSEQ_ADDR3 - [13:0] */ +#define WM8995_WSEQ_ADDR3_WIDTH 14 /* WSEQ_ADDR3 - [13:0] */ + +/* + * R12301 (0x300D) - Write Sequencer 13 + */ +#define WM8995_WSEQ_DATA3_MASK 0x00FF /* WSEQ_DATA3 - [7:0] */ +#define WM8995_WSEQ_DATA3_SHIFT 0 /* WSEQ_DATA3 - [7:0] */ +#define WM8995_WSEQ_DATA3_WIDTH 8 /* WSEQ_DATA3 - [7:0] */ + +/* + * R12302 (0x300E) - Write Sequencer 14 + */ +#define WM8995_WSEQ_DATA_WIDTH3_MASK 0x0700 /* WSEQ_DATA_WIDTH3 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH3_SHIFT 8 /* WSEQ_DATA_WIDTH3 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH3_WIDTH 3 /* WSEQ_DATA_WIDTH3 - [10:8] */ +#define WM8995_WSEQ_DATA_START3_MASK 0x000F /* WSEQ_DATA_START3 - [3:0] */ +#define WM8995_WSEQ_DATA_START3_SHIFT 0 /* WSEQ_DATA_START3 - [3:0] */ +#define WM8995_WSEQ_DATA_START3_WIDTH 4 /* WSEQ_DATA_START3 - [3:0] */ + +/* + * R12303 (0x300F) - Write Sequencer 15 + */ +#define WM8995_WSEQ_EOS3 0x0100 /* WSEQ_EOS3 */ +#define WM8995_WSEQ_EOS3_MASK 0x0100 /* WSEQ_EOS3 */ +#define WM8995_WSEQ_EOS3_SHIFT 8 /* WSEQ_EOS3 */ +#define WM8995_WSEQ_EOS3_WIDTH 1 /* WSEQ_EOS3 */ +#define WM8995_WSEQ_DELAY3_MASK 0x000F /* WSEQ_DELAY3 - [3:0] */ +#define WM8995_WSEQ_DELAY3_SHIFT 0 /* WSEQ_DELAY3 - [3:0] */ +#define WM8995_WSEQ_DELAY3_WIDTH 4 /* WSEQ_DELAY3 - [3:0] */ + +/* + * R12304 (0x3010) - Write Sequencer 16 + */ +#define WM8995_WSEQ_ADDR4_MASK 0x3FFF /* WSEQ_ADDR4 - [13:0] */ +#define WM8995_WSEQ_ADDR4_SHIFT 0 /* WSEQ_ADDR4 - [13:0] */ +#define WM8995_WSEQ_ADDR4_WIDTH 14 /* WSEQ_ADDR4 - [13:0] */ + +/* + * R12305 (0x3011) - Write Sequencer 17 + */ +#define WM8995_WSEQ_DATA4_MASK 0x00FF /* WSEQ_DATA4 - [7:0] */ +#define WM8995_WSEQ_DATA4_SHIFT 0 /* WSEQ_DATA4 - [7:0] */ +#define WM8995_WSEQ_DATA4_WIDTH 8 /* WSEQ_DATA4 - [7:0] */ + +/* + * R12306 (0x3012) - Write Sequencer 18 + */ +#define WM8995_WSEQ_DATA_WIDTH4_MASK 0x0700 /* WSEQ_DATA_WIDTH4 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH4_SHIFT 8 /* WSEQ_DATA_WIDTH4 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH4_WIDTH 3 /* WSEQ_DATA_WIDTH4 - [10:8] */ +#define WM8995_WSEQ_DATA_START4_MASK 0x000F /* WSEQ_DATA_START4 - [3:0] */ +#define WM8995_WSEQ_DATA_START4_SHIFT 0 /* WSEQ_DATA_START4 - [3:0] */ +#define WM8995_WSEQ_DATA_START4_WIDTH 4 /* WSEQ_DATA_START4 - [3:0] */ + +/* + * R12307 (0x3013) - Write Sequencer 19 + */ +#define WM8995_WSEQ_EOS4 0x0100 /* WSEQ_EOS4 */ +#define WM8995_WSEQ_EOS4_MASK 0x0100 /* WSEQ_EOS4 */ +#define WM8995_WSEQ_EOS4_SHIFT 8 /* WSEQ_EOS4 */ +#define WM8995_WSEQ_EOS4_WIDTH 1 /* WSEQ_EOS4 */ +#define WM8995_WSEQ_DELAY4_MASK 0x000F /* WSEQ_DELAY4 - [3:0] */ +#define WM8995_WSEQ_DELAY4_SHIFT 0 /* WSEQ_DELAY4 - [3:0] */ +#define WM8995_WSEQ_DELAY4_WIDTH 4 /* WSEQ_DELAY4 - [3:0] */ + +/* + * R12308 (0x3014) - Write Sequencer 20 + */ +#define WM8995_WSEQ_ADDR5_MASK 0x3FFF /* WSEQ_ADDR5 - [13:0] */ +#define WM8995_WSEQ_ADDR5_SHIFT 0 /* WSEQ_ADDR5 - [13:0] */ +#define WM8995_WSEQ_ADDR5_WIDTH 14 /* WSEQ_ADDR5 - [13:0] */ + +/* + * R12309 (0x3015) - Write Sequencer 21 + */ +#define WM8995_WSEQ_DATA5_MASK 0x00FF /* WSEQ_DATA5 - [7:0] */ +#define WM8995_WSEQ_DATA5_SHIFT 0 /* WSEQ_DATA5 - [7:0] */ +#define WM8995_WSEQ_DATA5_WIDTH 8 /* WSEQ_DATA5 - [7:0] */ + +/* + * R12310 (0x3016) - Write Sequencer 22 + */ +#define WM8995_WSEQ_DATA_WIDTH5_MASK 0x0700 /* WSEQ_DATA_WIDTH5 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH5_SHIFT 8 /* WSEQ_DATA_WIDTH5 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH5_WIDTH 3 /* WSEQ_DATA_WIDTH5 - [10:8] */ +#define WM8995_WSEQ_DATA_START5_MASK 0x000F /* WSEQ_DATA_START5 - [3:0] */ +#define WM8995_WSEQ_DATA_START5_SHIFT 0 /* WSEQ_DATA_START5 - [3:0] */ +#define WM8995_WSEQ_DATA_START5_WIDTH 4 /* WSEQ_DATA_START5 - [3:0] */ + +/* + * R12311 (0x3017) - Write Sequencer 23 + */ +#define WM8995_WSEQ_EOS5 0x0100 /* WSEQ_EOS5 */ +#define WM8995_WSEQ_EOS5_MASK 0x0100 /* WSEQ_EOS5 */ +#define WM8995_WSEQ_EOS5_SHIFT 8 /* WSEQ_EOS5 */ +#define WM8995_WSEQ_EOS5_WIDTH 1 /* WSEQ_EOS5 */ +#define WM8995_WSEQ_DELAY5_MASK 0x000F /* WSEQ_DELAY5 - [3:0] */ +#define WM8995_WSEQ_DELAY5_SHIFT 0 /* WSEQ_DELAY5 - [3:0] */ +#define WM8995_WSEQ_DELAY5_WIDTH 4 /* WSEQ_DELAY5 - [3:0] */ + +/* + * R12312 (0x3018) - Write Sequencer 24 + */ +#define WM8995_WSEQ_ADDR6_MASK 0x3FFF /* WSEQ_ADDR6 - [13:0] */ +#define WM8995_WSEQ_ADDR6_SHIFT 0 /* WSEQ_ADDR6 - [13:0] */ +#define WM8995_WSEQ_ADDR6_WIDTH 14 /* WSEQ_ADDR6 - [13:0] */ + +/* + * R12313 (0x3019) - Write Sequencer 25 + */ +#define WM8995_WSEQ_DATA6_MASK 0x00FF /* WSEQ_DATA6 - [7:0] */ +#define WM8995_WSEQ_DATA6_SHIFT 0 /* WSEQ_DATA6 - [7:0] */ +#define WM8995_WSEQ_DATA6_WIDTH 8 /* WSEQ_DATA6 - [7:0] */ + +/* + * R12314 (0x301A) - Write Sequencer 26 + */ +#define WM8995_WSEQ_DATA_WIDTH6_MASK 0x0700 /* WSEQ_DATA_WIDTH6 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH6_SHIFT 8 /* WSEQ_DATA_WIDTH6 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH6_WIDTH 3 /* WSEQ_DATA_WIDTH6 - [10:8] */ +#define WM8995_WSEQ_DATA_START6_MASK 0x000F /* WSEQ_DATA_START6 - [3:0] */ +#define WM8995_WSEQ_DATA_START6_SHIFT 0 /* WSEQ_DATA_START6 - [3:0] */ +#define WM8995_WSEQ_DATA_START6_WIDTH 4 /* WSEQ_DATA_START6 - [3:0] */ + +/* + * R12315 (0x301B) - Write Sequencer 27 + */ +#define WM8995_WSEQ_EOS6 0x0100 /* WSEQ_EOS6 */ +#define WM8995_WSEQ_EOS6_MASK 0x0100 /* WSEQ_EOS6 */ +#define WM8995_WSEQ_EOS6_SHIFT 8 /* WSEQ_EOS6 */ +#define WM8995_WSEQ_EOS6_WIDTH 1 /* WSEQ_EOS6 */ +#define WM8995_WSEQ_DELAY6_MASK 0x000F /* WSEQ_DELAY6 - [3:0] */ +#define WM8995_WSEQ_DELAY6_SHIFT 0 /* WSEQ_DELAY6 - [3:0] */ +#define WM8995_WSEQ_DELAY6_WIDTH 4 /* WSEQ_DELAY6 - [3:0] */ + +/* + * R12316 (0x301C) - Write Sequencer 28 + */ +#define WM8995_WSEQ_ADDR7_MASK 0x3FFF /* WSEQ_ADDR7 - [13:0] */ +#define WM8995_WSEQ_ADDR7_SHIFT 0 /* WSEQ_ADDR7 - [13:0] */ +#define WM8995_WSEQ_ADDR7_WIDTH 14 /* WSEQ_ADDR7 - [13:0] */ + +/* + * R12317 (0x301D) - Write Sequencer 29 + */ +#define WM8995_WSEQ_DATA7_MASK 0x00FF /* WSEQ_DATA7 - [7:0] */ +#define WM8995_WSEQ_DATA7_SHIFT 0 /* WSEQ_DATA7 - [7:0] */ +#define WM8995_WSEQ_DATA7_WIDTH 8 /* WSEQ_DATA7 - [7:0] */ + +/* + * R12318 (0x301E) - Write Sequencer 30 + */ +#define WM8995_WSEQ_DATA_WIDTH7_MASK 0x0700 /* WSEQ_DATA_WIDTH7 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH7_SHIFT 8 /* WSEQ_DATA_WIDTH7 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH7_WIDTH 3 /* WSEQ_DATA_WIDTH7 - [10:8] */ +#define WM8995_WSEQ_DATA_START7_MASK 0x000F /* WSEQ_DATA_START7 - [3:0] */ +#define WM8995_WSEQ_DATA_START7_SHIFT 0 /* WSEQ_DATA_START7 - [3:0] */ +#define WM8995_WSEQ_DATA_START7_WIDTH 4 /* WSEQ_DATA_START7 - [3:0] */ + +/* + * R12319 (0x301F) - Write Sequencer 31 + */ +#define WM8995_WSEQ_EOS7 0x0100 /* WSEQ_EOS7 */ +#define WM8995_WSEQ_EOS7_MASK 0x0100 /* WSEQ_EOS7 */ +#define WM8995_WSEQ_EOS7_SHIFT 8 /* WSEQ_EOS7 */ +#define WM8995_WSEQ_EOS7_WIDTH 1 /* WSEQ_EOS7 */ +#define WM8995_WSEQ_DELAY7_MASK 0x000F /* WSEQ_DELAY7 - [3:0] */ +#define WM8995_WSEQ_DELAY7_SHIFT 0 /* WSEQ_DELAY7 - [3:0] */ +#define WM8995_WSEQ_DELAY7_WIDTH 4 /* WSEQ_DELAY7 - [3:0] */ + +/* + * R12320 (0x3020) - Write Sequencer 32 + */ +#define WM8995_WSEQ_ADDR8_MASK 0x3FFF /* WSEQ_ADDR8 - [13:0] */ +#define WM8995_WSEQ_ADDR8_SHIFT 0 /* WSEQ_ADDR8 - [13:0] */ +#define WM8995_WSEQ_ADDR8_WIDTH 14 /* WSEQ_ADDR8 - [13:0] */ + +/* + * R12321 (0x3021) - Write Sequencer 33 + */ +#define WM8995_WSEQ_DATA8_MASK 0x00FF /* WSEQ_DATA8 - [7:0] */ +#define WM8995_WSEQ_DATA8_SHIFT 0 /* WSEQ_DATA8 - [7:0] */ +#define WM8995_WSEQ_DATA8_WIDTH 8 /* WSEQ_DATA8 - [7:0] */ + +/* + * R12322 (0x3022) - Write Sequencer 34 + */ +#define WM8995_WSEQ_DATA_WIDTH8_MASK 0x0700 /* WSEQ_DATA_WIDTH8 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH8_SHIFT 8 /* WSEQ_DATA_WIDTH8 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH8_WIDTH 3 /* WSEQ_DATA_WIDTH8 - [10:8] */ +#define WM8995_WSEQ_DATA_START8_MASK 0x000F /* WSEQ_DATA_START8 - [3:0] */ +#define WM8995_WSEQ_DATA_START8_SHIFT 0 /* WSEQ_DATA_START8 - [3:0] */ +#define WM8995_WSEQ_DATA_START8_WIDTH 4 /* WSEQ_DATA_START8 - [3:0] */ + +/* + * R12323 (0x3023) - Write Sequencer 35 + */ +#define WM8995_WSEQ_EOS8 0x0100 /* WSEQ_EOS8 */ +#define WM8995_WSEQ_EOS8_MASK 0x0100 /* WSEQ_EOS8 */ +#define WM8995_WSEQ_EOS8_SHIFT 8 /* WSEQ_EOS8 */ +#define WM8995_WSEQ_EOS8_WIDTH 1 /* WSEQ_EOS8 */ +#define WM8995_WSEQ_DELAY8_MASK 0x000F /* WSEQ_DELAY8 - [3:0] */ +#define WM8995_WSEQ_DELAY8_SHIFT 0 /* WSEQ_DELAY8 - [3:0] */ +#define WM8995_WSEQ_DELAY8_WIDTH 4 /* WSEQ_DELAY8 - [3:0] */ + +/* + * R12324 (0x3024) - Write Sequencer 36 + */ +#define WM8995_WSEQ_ADDR9_MASK 0x3FFF /* WSEQ_ADDR9 - [13:0] */ +#define WM8995_WSEQ_ADDR9_SHIFT 0 /* WSEQ_ADDR9 - [13:0] */ +#define WM8995_WSEQ_ADDR9_WIDTH 14 /* WSEQ_ADDR9 - [13:0] */ + +/* + * R12325 (0x3025) - Write Sequencer 37 + */ +#define WM8995_WSEQ_DATA9_MASK 0x00FF /* WSEQ_DATA9 - [7:0] */ +#define WM8995_WSEQ_DATA9_SHIFT 0 /* WSEQ_DATA9 - [7:0] */ +#define WM8995_WSEQ_DATA9_WIDTH 8 /* WSEQ_DATA9 - [7:0] */ + +/* + * R12326 (0x3026) - Write Sequencer 38 + */ +#define WM8995_WSEQ_DATA_WIDTH9_MASK 0x0700 /* WSEQ_DATA_WIDTH9 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH9_SHIFT 8 /* WSEQ_DATA_WIDTH9 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH9_WIDTH 3 /* WSEQ_DATA_WIDTH9 - [10:8] */ +#define WM8995_WSEQ_DATA_START9_MASK 0x000F /* WSEQ_DATA_START9 - [3:0] */ +#define WM8995_WSEQ_DATA_START9_SHIFT 0 /* WSEQ_DATA_START9 - [3:0] */ +#define WM8995_WSEQ_DATA_START9_WIDTH 4 /* WSEQ_DATA_START9 - [3:0] */ + +/* + * R12327 (0x3027) - Write Sequencer 39 + */ +#define WM8995_WSEQ_EOS9 0x0100 /* WSEQ_EOS9 */ +#define WM8995_WSEQ_EOS9_MASK 0x0100 /* WSEQ_EOS9 */ +#define WM8995_WSEQ_EOS9_SHIFT 8 /* WSEQ_EOS9 */ +#define WM8995_WSEQ_EOS9_WIDTH 1 /* WSEQ_EOS9 */ +#define WM8995_WSEQ_DELAY9_MASK 0x000F /* WSEQ_DELAY9 - [3:0] */ +#define WM8995_WSEQ_DELAY9_SHIFT 0 /* WSEQ_DELAY9 - [3:0] */ +#define WM8995_WSEQ_DELAY9_WIDTH 4 /* WSEQ_DELAY9 - [3:0] */ + +/* + * R12328 (0x3028) - Write Sequencer 40 + */ +#define WM8995_WSEQ_ADDR10_MASK 0x3FFF /* WSEQ_ADDR10 - [13:0] */ +#define WM8995_WSEQ_ADDR10_SHIFT 0 /* WSEQ_ADDR10 - [13:0] */ +#define WM8995_WSEQ_ADDR10_WIDTH 14 /* WSEQ_ADDR10 - [13:0] */ + +/* + * R12329 (0x3029) - Write Sequencer 41 + */ +#define WM8995_WSEQ_DATA10_MASK 0x00FF /* WSEQ_DATA10 - [7:0] */ +#define WM8995_WSEQ_DATA10_SHIFT 0 /* WSEQ_DATA10 - [7:0] */ +#define WM8995_WSEQ_DATA10_WIDTH 8 /* WSEQ_DATA10 - [7:0] */ + +/* + * R12330 (0x302A) - Write Sequencer 42 + */ +#define WM8995_WSEQ_DATA_WIDTH10_MASK 0x0700 /* WSEQ_DATA_WIDTH10 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH10_SHIFT 8 /* WSEQ_DATA_WIDTH10 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH10_WIDTH 3 /* WSEQ_DATA_WIDTH10 - [10:8] */ +#define WM8995_WSEQ_DATA_START10_MASK 0x000F /* WSEQ_DATA_START10 - [3:0] */ +#define WM8995_WSEQ_DATA_START10_SHIFT 0 /* WSEQ_DATA_START10 - [3:0] */ +#define WM8995_WSEQ_DATA_START10_WIDTH 4 /* WSEQ_DATA_START10 - [3:0] */ + +/* + * R12331 (0x302B) - Write Sequencer 43 + */ +#define WM8995_WSEQ_EOS10 0x0100 /* WSEQ_EOS10 */ +#define WM8995_WSEQ_EOS10_MASK 0x0100 /* WSEQ_EOS10 */ +#define WM8995_WSEQ_EOS10_SHIFT 8 /* WSEQ_EOS10 */ +#define WM8995_WSEQ_EOS10_WIDTH 1 /* WSEQ_EOS10 */ +#define WM8995_WSEQ_DELAY10_MASK 0x000F /* WSEQ_DELAY10 - [3:0] */ +#define WM8995_WSEQ_DELAY10_SHIFT 0 /* WSEQ_DELAY10 - [3:0] */ +#define WM8995_WSEQ_DELAY10_WIDTH 4 /* WSEQ_DELAY10 - [3:0] */ + +/* + * R12332 (0x302C) - Write Sequencer 44 + */ +#define WM8995_WSEQ_ADDR11_MASK 0x3FFF /* WSEQ_ADDR11 - [13:0] */ +#define WM8995_WSEQ_ADDR11_SHIFT 0 /* WSEQ_ADDR11 - [13:0] */ +#define WM8995_WSEQ_ADDR11_WIDTH 14 /* WSEQ_ADDR11 - [13:0] */ + +/* + * R12333 (0x302D) - Write Sequencer 45 + */ +#define WM8995_WSEQ_DATA11_MASK 0x00FF /* WSEQ_DATA11 - [7:0] */ +#define WM8995_WSEQ_DATA11_SHIFT 0 /* WSEQ_DATA11 - [7:0] */ +#define WM8995_WSEQ_DATA11_WIDTH 8 /* WSEQ_DATA11 - [7:0] */ + +/* + * R12334 (0x302E) - Write Sequencer 46 + */ +#define WM8995_WSEQ_DATA_WIDTH11_MASK 0x0700 /* WSEQ_DATA_WIDTH11 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH11_SHIFT 8 /* WSEQ_DATA_WIDTH11 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH11_WIDTH 3 /* WSEQ_DATA_WIDTH11 - [10:8] */ +#define WM8995_WSEQ_DATA_START11_MASK 0x000F /* WSEQ_DATA_START11 - [3:0] */ +#define WM8995_WSEQ_DATA_START11_SHIFT 0 /* WSEQ_DATA_START11 - [3:0] */ +#define WM8995_WSEQ_DATA_START11_WIDTH 4 /* WSEQ_DATA_START11 - [3:0] */ + +/* + * R12335 (0x302F) - Write Sequencer 47 + */ +#define WM8995_WSEQ_EOS11 0x0100 /* WSEQ_EOS11 */ +#define WM8995_WSEQ_EOS11_MASK 0x0100 /* WSEQ_EOS11 */ +#define WM8995_WSEQ_EOS11_SHIFT 8 /* WSEQ_EOS11 */ +#define WM8995_WSEQ_EOS11_WIDTH 1 /* WSEQ_EOS11 */ +#define WM8995_WSEQ_DELAY11_MASK 0x000F /* WSEQ_DELAY11 - [3:0] */ +#define WM8995_WSEQ_DELAY11_SHIFT 0 /* WSEQ_DELAY11 - [3:0] */ +#define WM8995_WSEQ_DELAY11_WIDTH 4 /* WSEQ_DELAY11 - [3:0] */ + +/* + * R12336 (0x3030) - Write Sequencer 48 + */ +#define WM8995_WSEQ_ADDR12_MASK 0x3FFF /* WSEQ_ADDR12 - [13:0] */ +#define WM8995_WSEQ_ADDR12_SHIFT 0 /* WSEQ_ADDR12 - [13:0] */ +#define WM8995_WSEQ_ADDR12_WIDTH 14 /* WSEQ_ADDR12 - [13:0] */ + +/* + * R12337 (0x3031) - Write Sequencer 49 + */ +#define WM8995_WSEQ_DATA12_MASK 0x00FF /* WSEQ_DATA12 - [7:0] */ +#define WM8995_WSEQ_DATA12_SHIFT 0 /* WSEQ_DATA12 - [7:0] */ +#define WM8995_WSEQ_DATA12_WIDTH 8 /* WSEQ_DATA12 - [7:0] */ + +/* + * R12338 (0x3032) - Write Sequencer 50 + */ +#define WM8995_WSEQ_DATA_WIDTH12_MASK 0x0700 /* WSEQ_DATA_WIDTH12 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH12_SHIFT 8 /* WSEQ_DATA_WIDTH12 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH12_WIDTH 3 /* WSEQ_DATA_WIDTH12 - [10:8] */ +#define WM8995_WSEQ_DATA_START12_MASK 0x000F /* WSEQ_DATA_START12 - [3:0] */ +#define WM8995_WSEQ_DATA_START12_SHIFT 0 /* WSEQ_DATA_START12 - [3:0] */ +#define WM8995_WSEQ_DATA_START12_WIDTH 4 /* WSEQ_DATA_START12 - [3:0] */ + +/* + * R12339 (0x3033) - Write Sequencer 51 + */ +#define WM8995_WSEQ_EOS12 0x0100 /* WSEQ_EOS12 */ +#define WM8995_WSEQ_EOS12_MASK 0x0100 /* WSEQ_EOS12 */ +#define WM8995_WSEQ_EOS12_SHIFT 8 /* WSEQ_EOS12 */ +#define WM8995_WSEQ_EOS12_WIDTH 1 /* WSEQ_EOS12 */ +#define WM8995_WSEQ_DELAY12_MASK 0x000F /* WSEQ_DELAY12 - [3:0] */ +#define WM8995_WSEQ_DELAY12_SHIFT 0 /* WSEQ_DELAY12 - [3:0] */ +#define WM8995_WSEQ_DELAY12_WIDTH 4 /* WSEQ_DELAY12 - [3:0] */ + +/* + * R12340 (0x3034) - Write Sequencer 52 + */ +#define WM8995_WSEQ_ADDR13_MASK 0x3FFF /* WSEQ_ADDR13 - [13:0] */ +#define WM8995_WSEQ_ADDR13_SHIFT 0 /* WSEQ_ADDR13 - [13:0] */ +#define WM8995_WSEQ_ADDR13_WIDTH 14 /* WSEQ_ADDR13 - [13:0] */ + +/* + * R12341 (0x3035) - Write Sequencer 53 + */ +#define WM8995_WSEQ_DATA13_MASK 0x00FF /* WSEQ_DATA13 - [7:0] */ +#define WM8995_WSEQ_DATA13_SHIFT 0 /* WSEQ_DATA13 - [7:0] */ +#define WM8995_WSEQ_DATA13_WIDTH 8 /* WSEQ_DATA13 - [7:0] */ + +/* + * R12342 (0x3036) - Write Sequencer 54 + */ +#define WM8995_WSEQ_DATA_WIDTH13_MASK 0x0700 /* WSEQ_DATA_WIDTH13 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH13_SHIFT 8 /* WSEQ_DATA_WIDTH13 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH13_WIDTH 3 /* WSEQ_DATA_WIDTH13 - [10:8] */ +#define WM8995_WSEQ_DATA_START13_MASK 0x000F /* WSEQ_DATA_START13 - [3:0] */ +#define WM8995_WSEQ_DATA_START13_SHIFT 0 /* WSEQ_DATA_START13 - [3:0] */ +#define WM8995_WSEQ_DATA_START13_WIDTH 4 /* WSEQ_DATA_START13 - [3:0] */ + +/* + * R12343 (0x3037) - Write Sequencer 55 + */ +#define WM8995_WSEQ_EOS13 0x0100 /* WSEQ_EOS13 */ +#define WM8995_WSEQ_EOS13_MASK 0x0100 /* WSEQ_EOS13 */ +#define WM8995_WSEQ_EOS13_SHIFT 8 /* WSEQ_EOS13 */ +#define WM8995_WSEQ_EOS13_WIDTH 1 /* WSEQ_EOS13 */ +#define WM8995_WSEQ_DELAY13_MASK 0x000F /* WSEQ_DELAY13 - [3:0] */ +#define WM8995_WSEQ_DELAY13_SHIFT 0 /* WSEQ_DELAY13 - [3:0] */ +#define WM8995_WSEQ_DELAY13_WIDTH 4 /* WSEQ_DELAY13 - [3:0] */ + +/* + * R12344 (0x3038) - Write Sequencer 56 + */ +#define WM8995_WSEQ_ADDR14_MASK 0x3FFF /* WSEQ_ADDR14 - [13:0] */ +#define WM8995_WSEQ_ADDR14_SHIFT 0 /* WSEQ_ADDR14 - [13:0] */ +#define WM8995_WSEQ_ADDR14_WIDTH 14 /* WSEQ_ADDR14 - [13:0] */ + +/* + * R12345 (0x3039) - Write Sequencer 57 + */ +#define WM8995_WSEQ_DATA14_MASK 0x00FF /* WSEQ_DATA14 - [7:0] */ +#define WM8995_WSEQ_DATA14_SHIFT 0 /* WSEQ_DATA14 - [7:0] */ +#define WM8995_WSEQ_DATA14_WIDTH 8 /* WSEQ_DATA14 - [7:0] */ + +/* + * R12346 (0x303A) - Write Sequencer 58 + */ +#define WM8995_WSEQ_DATA_WIDTH14_MASK 0x0700 /* WSEQ_DATA_WIDTH14 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH14_SHIFT 8 /* WSEQ_DATA_WIDTH14 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH14_WIDTH 3 /* WSEQ_DATA_WIDTH14 - [10:8] */ +#define WM8995_WSEQ_DATA_START14_MASK 0x000F /* WSEQ_DATA_START14 - [3:0] */ +#define WM8995_WSEQ_DATA_START14_SHIFT 0 /* WSEQ_DATA_START14 - [3:0] */ +#define WM8995_WSEQ_DATA_START14_WIDTH 4 /* WSEQ_DATA_START14 - [3:0] */ + +/* + * R12347 (0x303B) - Write Sequencer 59 + */ +#define WM8995_WSEQ_EOS14 0x0100 /* WSEQ_EOS14 */ +#define WM8995_WSEQ_EOS14_MASK 0x0100 /* WSEQ_EOS14 */ +#define WM8995_WSEQ_EOS14_SHIFT 8 /* WSEQ_EOS14 */ +#define WM8995_WSEQ_EOS14_WIDTH 1 /* WSEQ_EOS14 */ +#define WM8995_WSEQ_DELAY14_MASK 0x000F /* WSEQ_DELAY14 - [3:0] */ +#define WM8995_WSEQ_DELAY14_SHIFT 0 /* WSEQ_DELAY14 - [3:0] */ +#define WM8995_WSEQ_DELAY14_WIDTH 4 /* WSEQ_DELAY14 - [3:0] */ + +/* + * R12348 (0x303C) - Write Sequencer 60 + */ +#define WM8995_WSEQ_ADDR15_MASK 0x3FFF /* WSEQ_ADDR15 - [13:0] */ +#define WM8995_WSEQ_ADDR15_SHIFT 0 /* WSEQ_ADDR15 - [13:0] */ +#define WM8995_WSEQ_ADDR15_WIDTH 14 /* WSEQ_ADDR15 - [13:0] */ + +/* + * R12349 (0x303D) - Write Sequencer 61 + */ +#define WM8995_WSEQ_DATA15_MASK 0x00FF /* WSEQ_DATA15 - [7:0] */ +#define WM8995_WSEQ_DATA15_SHIFT 0 /* WSEQ_DATA15 - [7:0] */ +#define WM8995_WSEQ_DATA15_WIDTH 8 /* WSEQ_DATA15 - [7:0] */ + +/* + * R12350 (0x303E) - Write Sequencer 62 + */ +#define WM8995_WSEQ_DATA_WIDTH15_MASK 0x0700 /* WSEQ_DATA_WIDTH15 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH15_SHIFT 8 /* WSEQ_DATA_WIDTH15 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH15_WIDTH 3 /* WSEQ_DATA_WIDTH15 - [10:8] */ +#define WM8995_WSEQ_DATA_START15_MASK 0x000F /* WSEQ_DATA_START15 - [3:0] */ +#define WM8995_WSEQ_DATA_START15_SHIFT 0 /* WSEQ_DATA_START15 - [3:0] */ +#define WM8995_WSEQ_DATA_START15_WIDTH 4 /* WSEQ_DATA_START15 - [3:0] */ + +/* + * R12351 (0x303F) - Write Sequencer 63 + */ +#define WM8995_WSEQ_EOS15 0x0100 /* WSEQ_EOS15 */ +#define WM8995_WSEQ_EOS15_MASK 0x0100 /* WSEQ_EOS15 */ +#define WM8995_WSEQ_EOS15_SHIFT 8 /* WSEQ_EOS15 */ +#define WM8995_WSEQ_EOS15_WIDTH 1 /* WSEQ_EOS15 */ +#define WM8995_WSEQ_DELAY15_MASK 0x000F /* WSEQ_DELAY15 - [3:0] */ +#define WM8995_WSEQ_DELAY15_SHIFT 0 /* WSEQ_DELAY15 - [3:0] */ +#define WM8995_WSEQ_DELAY15_WIDTH 4 /* WSEQ_DELAY15 - [3:0] */ + +/* + * R12352 (0x3040) - Write Sequencer 64 + */ +#define WM8995_WSEQ_ADDR16_MASK 0x3FFF /* WSEQ_ADDR16 - [13:0] */ +#define WM8995_WSEQ_ADDR16_SHIFT 0 /* WSEQ_ADDR16 - [13:0] */ +#define WM8995_WSEQ_ADDR16_WIDTH 14 /* WSEQ_ADDR16 - [13:0] */ + +/* + * R12353 (0x3041) - Write Sequencer 65 + */ +#define WM8995_WSEQ_DATA16_MASK 0x00FF /* WSEQ_DATA16 - [7:0] */ +#define WM8995_WSEQ_DATA16_SHIFT 0 /* WSEQ_DATA16 - [7:0] */ +#define WM8995_WSEQ_DATA16_WIDTH 8 /* WSEQ_DATA16 - [7:0] */ + +/* + * R12354 (0x3042) - Write Sequencer 66 + */ +#define WM8995_WSEQ_DATA_WIDTH16_MASK 0x0700 /* WSEQ_DATA_WIDTH16 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH16_SHIFT 8 /* WSEQ_DATA_WIDTH16 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH16_WIDTH 3 /* WSEQ_DATA_WIDTH16 - [10:8] */ +#define WM8995_WSEQ_DATA_START16_MASK 0x000F /* WSEQ_DATA_START16 - [3:0] */ +#define WM8995_WSEQ_DATA_START16_SHIFT 0 /* WSEQ_DATA_START16 - [3:0] */ +#define WM8995_WSEQ_DATA_START16_WIDTH 4 /* WSEQ_DATA_START16 - [3:0] */ + +/* + * R12355 (0x3043) - Write Sequencer 67 + */ +#define WM8995_WSEQ_EOS16 0x0100 /* WSEQ_EOS16 */ +#define WM8995_WSEQ_EOS16_MASK 0x0100 /* WSEQ_EOS16 */ +#define WM8995_WSEQ_EOS16_SHIFT 8 /* WSEQ_EOS16 */ +#define WM8995_WSEQ_EOS16_WIDTH 1 /* WSEQ_EOS16 */ +#define WM8995_WSEQ_DELAY16_MASK 0x000F /* WSEQ_DELAY16 - [3:0] */ +#define WM8995_WSEQ_DELAY16_SHIFT 0 /* WSEQ_DELAY16 - [3:0] */ +#define WM8995_WSEQ_DELAY16_WIDTH 4 /* WSEQ_DELAY16 - [3:0] */ + +/* + * R12356 (0x3044) - Write Sequencer 68 + */ +#define WM8995_WSEQ_ADDR17_MASK 0x3FFF /* WSEQ_ADDR17 - [13:0] */ +#define WM8995_WSEQ_ADDR17_SHIFT 0 /* WSEQ_ADDR17 - [13:0] */ +#define WM8995_WSEQ_ADDR17_WIDTH 14 /* WSEQ_ADDR17 - [13:0] */ + +/* + * R12357 (0x3045) - Write Sequencer 69 + */ +#define WM8995_WSEQ_DATA17_MASK 0x00FF /* WSEQ_DATA17 - [7:0] */ +#define WM8995_WSEQ_DATA17_SHIFT 0 /* WSEQ_DATA17 - [7:0] */ +#define WM8995_WSEQ_DATA17_WIDTH 8 /* WSEQ_DATA17 - [7:0] */ + +/* + * R12358 (0x3046) - Write Sequencer 70 + */ +#define WM8995_WSEQ_DATA_WIDTH17_MASK 0x0700 /* WSEQ_DATA_WIDTH17 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH17_SHIFT 8 /* WSEQ_DATA_WIDTH17 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH17_WIDTH 3 /* WSEQ_DATA_WIDTH17 - [10:8] */ +#define WM8995_WSEQ_DATA_START17_MASK 0x000F /* WSEQ_DATA_START17 - [3:0] */ +#define WM8995_WSEQ_DATA_START17_SHIFT 0 /* WSEQ_DATA_START17 - [3:0] */ +#define WM8995_WSEQ_DATA_START17_WIDTH 4 /* WSEQ_DATA_START17 - [3:0] */ + +/* + * R12359 (0x3047) - Write Sequencer 71 + */ +#define WM8995_WSEQ_EOS17 0x0100 /* WSEQ_EOS17 */ +#define WM8995_WSEQ_EOS17_MASK 0x0100 /* WSEQ_EOS17 */ +#define WM8995_WSEQ_EOS17_SHIFT 8 /* WSEQ_EOS17 */ +#define WM8995_WSEQ_EOS17_WIDTH 1 /* WSEQ_EOS17 */ +#define WM8995_WSEQ_DELAY17_MASK 0x000F /* WSEQ_DELAY17 - [3:0] */ +#define WM8995_WSEQ_DELAY17_SHIFT 0 /* WSEQ_DELAY17 - [3:0] */ +#define WM8995_WSEQ_DELAY17_WIDTH 4 /* WSEQ_DELAY17 - [3:0] */ + +/* + * R12360 (0x3048) - Write Sequencer 72 + */ +#define WM8995_WSEQ_ADDR18_MASK 0x3FFF /* WSEQ_ADDR18 - [13:0] */ +#define WM8995_WSEQ_ADDR18_SHIFT 0 /* WSEQ_ADDR18 - [13:0] */ +#define WM8995_WSEQ_ADDR18_WIDTH 14 /* WSEQ_ADDR18 - [13:0] */ + +/* + * R12361 (0x3049) - Write Sequencer 73 + */ +#define WM8995_WSEQ_DATA18_MASK 0x00FF /* WSEQ_DATA18 - [7:0] */ +#define WM8995_WSEQ_DATA18_SHIFT 0 /* WSEQ_DATA18 - [7:0] */ +#define WM8995_WSEQ_DATA18_WIDTH 8 /* WSEQ_DATA18 - [7:0] */ + +/* + * R12362 (0x304A) - Write Sequencer 74 + */ +#define WM8995_WSEQ_DATA_WIDTH18_MASK 0x0700 /* WSEQ_DATA_WIDTH18 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH18_SHIFT 8 /* WSEQ_DATA_WIDTH18 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH18_WIDTH 3 /* WSEQ_DATA_WIDTH18 - [10:8] */ +#define WM8995_WSEQ_DATA_START18_MASK 0x000F /* WSEQ_DATA_START18 - [3:0] */ +#define WM8995_WSEQ_DATA_START18_SHIFT 0 /* WSEQ_DATA_START18 - [3:0] */ +#define WM8995_WSEQ_DATA_START18_WIDTH 4 /* WSEQ_DATA_START18 - [3:0] */ + +/* + * R12363 (0x304B) - Write Sequencer 75 + */ +#define WM8995_WSEQ_EOS18 0x0100 /* WSEQ_EOS18 */ +#define WM8995_WSEQ_EOS18_MASK 0x0100 /* WSEQ_EOS18 */ +#define WM8995_WSEQ_EOS18_SHIFT 8 /* WSEQ_EOS18 */ +#define WM8995_WSEQ_EOS18_WIDTH 1 /* WSEQ_EOS18 */ +#define WM8995_WSEQ_DELAY18_MASK 0x000F /* WSEQ_DELAY18 - [3:0] */ +#define WM8995_WSEQ_DELAY18_SHIFT 0 /* WSEQ_DELAY18 - [3:0] */ +#define WM8995_WSEQ_DELAY18_WIDTH 4 /* WSEQ_DELAY18 - [3:0] */ + +/* + * R12364 (0x304C) - Write Sequencer 76 + */ +#define WM8995_WSEQ_ADDR19_MASK 0x3FFF /* WSEQ_ADDR19 - [13:0] */ +#define WM8995_WSEQ_ADDR19_SHIFT 0 /* WSEQ_ADDR19 - [13:0] */ +#define WM8995_WSEQ_ADDR19_WIDTH 14 /* WSEQ_ADDR19 - [13:0] */ + +/* + * R12365 (0x304D) - Write Sequencer 77 + */ +#define WM8995_WSEQ_DATA19_MASK 0x00FF /* WSEQ_DATA19 - [7:0] */ +#define WM8995_WSEQ_DATA19_SHIFT 0 /* WSEQ_DATA19 - [7:0] */ +#define WM8995_WSEQ_DATA19_WIDTH 8 /* WSEQ_DATA19 - [7:0] */ + +/* + * R12366 (0x304E) - Write Sequencer 78 + */ +#define WM8995_WSEQ_DATA_WIDTH19_MASK 0x0700 /* WSEQ_DATA_WIDTH19 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH19_SHIFT 8 /* WSEQ_DATA_WIDTH19 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH19_WIDTH 3 /* WSEQ_DATA_WIDTH19 - [10:8] */ +#define WM8995_WSEQ_DATA_START19_MASK 0x000F /* WSEQ_DATA_START19 - [3:0] */ +#define WM8995_WSEQ_DATA_START19_SHIFT 0 /* WSEQ_DATA_START19 - [3:0] */ +#define WM8995_WSEQ_DATA_START19_WIDTH 4 /* WSEQ_DATA_START19 - [3:0] */ + +/* + * R12367 (0x304F) - Write Sequencer 79 + */ +#define WM8995_WSEQ_EOS19 0x0100 /* WSEQ_EOS19 */ +#define WM8995_WSEQ_EOS19_MASK 0x0100 /* WSEQ_EOS19 */ +#define WM8995_WSEQ_EOS19_SHIFT 8 /* WSEQ_EOS19 */ +#define WM8995_WSEQ_EOS19_WIDTH 1 /* WSEQ_EOS19 */ +#define WM8995_WSEQ_DELAY19_MASK 0x000F /* WSEQ_DELAY19 - [3:0] */ +#define WM8995_WSEQ_DELAY19_SHIFT 0 /* WSEQ_DELAY19 - [3:0] */ +#define WM8995_WSEQ_DELAY19_WIDTH 4 /* WSEQ_DELAY19 - [3:0] */ + +/* + * R12368 (0x3050) - Write Sequencer 80 + */ +#define WM8995_WSEQ_ADDR20_MASK 0x3FFF /* WSEQ_ADDR20 - [13:0] */ +#define WM8995_WSEQ_ADDR20_SHIFT 0 /* WSEQ_ADDR20 - [13:0] */ +#define WM8995_WSEQ_ADDR20_WIDTH 14 /* WSEQ_ADDR20 - [13:0] */ + +/* + * R12369 (0x3051) - Write Sequencer 81 + */ +#define WM8995_WSEQ_DATA20_MASK 0x00FF /* WSEQ_DATA20 - [7:0] */ +#define WM8995_WSEQ_DATA20_SHIFT 0 /* WSEQ_DATA20 - [7:0] */ +#define WM8995_WSEQ_DATA20_WIDTH 8 /* WSEQ_DATA20 - [7:0] */ + +/* + * R12370 (0x3052) - Write Sequencer 82 + */ +#define WM8995_WSEQ_DATA_WIDTH20_MASK 0x0700 /* WSEQ_DATA_WIDTH20 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH20_SHIFT 8 /* WSEQ_DATA_WIDTH20 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH20_WIDTH 3 /* WSEQ_DATA_WIDTH20 - [10:8] */ +#define WM8995_WSEQ_DATA_START20_MASK 0x000F /* WSEQ_DATA_START20 - [3:0] */ +#define WM8995_WSEQ_DATA_START20_SHIFT 0 /* WSEQ_DATA_START20 - [3:0] */ +#define WM8995_WSEQ_DATA_START20_WIDTH 4 /* WSEQ_DATA_START20 - [3:0] */ + +/* + * R12371 (0x3053) - Write Sequencer 83 + */ +#define WM8995_WSEQ_EOS20 0x0100 /* WSEQ_EOS20 */ +#define WM8995_WSEQ_EOS20_MASK 0x0100 /* WSEQ_EOS20 */ +#define WM8995_WSEQ_EOS20_SHIFT 8 /* WSEQ_EOS20 */ +#define WM8995_WSEQ_EOS20_WIDTH 1 /* WSEQ_EOS20 */ +#define WM8995_WSEQ_DELAY20_MASK 0x000F /* WSEQ_DELAY20 - [3:0] */ +#define WM8995_WSEQ_DELAY20_SHIFT 0 /* WSEQ_DELAY20 - [3:0] */ +#define WM8995_WSEQ_DELAY20_WIDTH 4 /* WSEQ_DELAY20 - [3:0] */ + +/* + * R12372 (0x3054) - Write Sequencer 84 + */ +#define WM8995_WSEQ_ADDR21_MASK 0x3FFF /* WSEQ_ADDR21 - [13:0] */ +#define WM8995_WSEQ_ADDR21_SHIFT 0 /* WSEQ_ADDR21 - [13:0] */ +#define WM8995_WSEQ_ADDR21_WIDTH 14 /* WSEQ_ADDR21 - [13:0] */ + +/* + * R12373 (0x3055) - Write Sequencer 85 + */ +#define WM8995_WSEQ_DATA21_MASK 0x00FF /* WSEQ_DATA21 - [7:0] */ +#define WM8995_WSEQ_DATA21_SHIFT 0 /* WSEQ_DATA21 - [7:0] */ +#define WM8995_WSEQ_DATA21_WIDTH 8 /* WSEQ_DATA21 - [7:0] */ + +/* + * R12374 (0x3056) - Write Sequencer 86 + */ +#define WM8995_WSEQ_DATA_WIDTH21_MASK 0x0700 /* WSEQ_DATA_WIDTH21 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH21_SHIFT 8 /* WSEQ_DATA_WIDTH21 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH21_WIDTH 3 /* WSEQ_DATA_WIDTH21 - [10:8] */ +#define WM8995_WSEQ_DATA_START21_MASK 0x000F /* WSEQ_DATA_START21 - [3:0] */ +#define WM8995_WSEQ_DATA_START21_SHIFT 0 /* WSEQ_DATA_START21 - [3:0] */ +#define WM8995_WSEQ_DATA_START21_WIDTH 4 /* WSEQ_DATA_START21 - [3:0] */ + +/* + * R12375 (0x3057) - Write Sequencer 87 + */ +#define WM8995_WSEQ_EOS21 0x0100 /* WSEQ_EOS21 */ +#define WM8995_WSEQ_EOS21_MASK 0x0100 /* WSEQ_EOS21 */ +#define WM8995_WSEQ_EOS21_SHIFT 8 /* WSEQ_EOS21 */ +#define WM8995_WSEQ_EOS21_WIDTH 1 /* WSEQ_EOS21 */ +#define WM8995_WSEQ_DELAY21_MASK 0x000F /* WSEQ_DELAY21 - [3:0] */ +#define WM8995_WSEQ_DELAY21_SHIFT 0 /* WSEQ_DELAY21 - [3:0] */ +#define WM8995_WSEQ_DELAY21_WIDTH 4 /* WSEQ_DELAY21 - [3:0] */ + +/* + * R12376 (0x3058) - Write Sequencer 88 + */ +#define WM8995_WSEQ_ADDR22_MASK 0x3FFF /* WSEQ_ADDR22 - [13:0] */ +#define WM8995_WSEQ_ADDR22_SHIFT 0 /* WSEQ_ADDR22 - [13:0] */ +#define WM8995_WSEQ_ADDR22_WIDTH 14 /* WSEQ_ADDR22 - [13:0] */ + +/* + * R12377 (0x3059) - Write Sequencer 89 + */ +#define WM8995_WSEQ_DATA22_MASK 0x00FF /* WSEQ_DATA22 - [7:0] */ +#define WM8995_WSEQ_DATA22_SHIFT 0 /* WSEQ_DATA22 - [7:0] */ +#define WM8995_WSEQ_DATA22_WIDTH 8 /* WSEQ_DATA22 - [7:0] */ + +/* + * R12378 (0x305A) - Write Sequencer 90 + */ +#define WM8995_WSEQ_DATA_WIDTH22_MASK 0x0700 /* WSEQ_DATA_WIDTH22 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH22_SHIFT 8 /* WSEQ_DATA_WIDTH22 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH22_WIDTH 3 /* WSEQ_DATA_WIDTH22 - [10:8] */ +#define WM8995_WSEQ_DATA_START22_MASK 0x000F /* WSEQ_DATA_START22 - [3:0] */ +#define WM8995_WSEQ_DATA_START22_SHIFT 0 /* WSEQ_DATA_START22 - [3:0] */ +#define WM8995_WSEQ_DATA_START22_WIDTH 4 /* WSEQ_DATA_START22 - [3:0] */ + +/* + * R12379 (0x305B) - Write Sequencer 91 + */ +#define WM8995_WSEQ_EOS22 0x0100 /* WSEQ_EOS22 */ +#define WM8995_WSEQ_EOS22_MASK 0x0100 /* WSEQ_EOS22 */ +#define WM8995_WSEQ_EOS22_SHIFT 8 /* WSEQ_EOS22 */ +#define WM8995_WSEQ_EOS22_WIDTH 1 /* WSEQ_EOS22 */ +#define WM8995_WSEQ_DELAY22_MASK 0x000F /* WSEQ_DELAY22 - [3:0] */ +#define WM8995_WSEQ_DELAY22_SHIFT 0 /* WSEQ_DELAY22 - [3:0] */ +#define WM8995_WSEQ_DELAY22_WIDTH 4 /* WSEQ_DELAY22 - [3:0] */ + +/* + * R12380 (0x305C) - Write Sequencer 92 + */ +#define WM8995_WSEQ_ADDR23_MASK 0x3FFF /* WSEQ_ADDR23 - [13:0] */ +#define WM8995_WSEQ_ADDR23_SHIFT 0 /* WSEQ_ADDR23 - [13:0] */ +#define WM8995_WSEQ_ADDR23_WIDTH 14 /* WSEQ_ADDR23 - [13:0] */ + +/* + * R12381 (0x305D) - Write Sequencer 93 + */ +#define WM8995_WSEQ_DATA23_MASK 0x00FF /* WSEQ_DATA23 - [7:0] */ +#define WM8995_WSEQ_DATA23_SHIFT 0 /* WSEQ_DATA23 - [7:0] */ +#define WM8995_WSEQ_DATA23_WIDTH 8 /* WSEQ_DATA23 - [7:0] */ + +/* + * R12382 (0x305E) - Write Sequencer 94 + */ +#define WM8995_WSEQ_DATA_WIDTH23_MASK 0x0700 /* WSEQ_DATA_WIDTH23 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH23_SHIFT 8 /* WSEQ_DATA_WIDTH23 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH23_WIDTH 3 /* WSEQ_DATA_WIDTH23 - [10:8] */ +#define WM8995_WSEQ_DATA_START23_MASK 0x000F /* WSEQ_DATA_START23 - [3:0] */ +#define WM8995_WSEQ_DATA_START23_SHIFT 0 /* WSEQ_DATA_START23 - [3:0] */ +#define WM8995_WSEQ_DATA_START23_WIDTH 4 /* WSEQ_DATA_START23 - [3:0] */ + +/* + * R12383 (0x305F) - Write Sequencer 95 + */ +#define WM8995_WSEQ_EOS23 0x0100 /* WSEQ_EOS23 */ +#define WM8995_WSEQ_EOS23_MASK 0x0100 /* WSEQ_EOS23 */ +#define WM8995_WSEQ_EOS23_SHIFT 8 /* WSEQ_EOS23 */ +#define WM8995_WSEQ_EOS23_WIDTH 1 /* WSEQ_EOS23 */ +#define WM8995_WSEQ_DELAY23_MASK 0x000F /* WSEQ_DELAY23 - [3:0] */ +#define WM8995_WSEQ_DELAY23_SHIFT 0 /* WSEQ_DELAY23 - [3:0] */ +#define WM8995_WSEQ_DELAY23_WIDTH 4 /* WSEQ_DELAY23 - [3:0] */ + +/* + * R12384 (0x3060) - Write Sequencer 96 + */ +#define WM8995_WSEQ_ADDR24_MASK 0x3FFF /* WSEQ_ADDR24 - [13:0] */ +#define WM8995_WSEQ_ADDR24_SHIFT 0 /* WSEQ_ADDR24 - [13:0] */ +#define WM8995_WSEQ_ADDR24_WIDTH 14 /* WSEQ_ADDR24 - [13:0] */ + +/* + * R12385 (0x3061) - Write Sequencer 97 + */ +#define WM8995_WSEQ_DATA24_MASK 0x00FF /* WSEQ_DATA24 - [7:0] */ +#define WM8995_WSEQ_DATA24_SHIFT 0 /* WSEQ_DATA24 - [7:0] */ +#define WM8995_WSEQ_DATA24_WIDTH 8 /* WSEQ_DATA24 - [7:0] */ + +/* + * R12386 (0x3062) - Write Sequencer 98 + */ +#define WM8995_WSEQ_DATA_WIDTH24_MASK 0x0700 /* WSEQ_DATA_WIDTH24 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH24_SHIFT 8 /* WSEQ_DATA_WIDTH24 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH24_WIDTH 3 /* WSEQ_DATA_WIDTH24 - [10:8] */ +#define WM8995_WSEQ_DATA_START24_MASK 0x000F /* WSEQ_DATA_START24 - [3:0] */ +#define WM8995_WSEQ_DATA_START24_SHIFT 0 /* WSEQ_DATA_START24 - [3:0] */ +#define WM8995_WSEQ_DATA_START24_WIDTH 4 /* WSEQ_DATA_START24 - [3:0] */ + +/* + * R12387 (0x3063) - Write Sequencer 99 + */ +#define WM8995_WSEQ_EOS24 0x0100 /* WSEQ_EOS24 */ +#define WM8995_WSEQ_EOS24_MASK 0x0100 /* WSEQ_EOS24 */ +#define WM8995_WSEQ_EOS24_SHIFT 8 /* WSEQ_EOS24 */ +#define WM8995_WSEQ_EOS24_WIDTH 1 /* WSEQ_EOS24 */ +#define WM8995_WSEQ_DELAY24_MASK 0x000F /* WSEQ_DELAY24 - [3:0] */ +#define WM8995_WSEQ_DELAY24_SHIFT 0 /* WSEQ_DELAY24 - [3:0] */ +#define WM8995_WSEQ_DELAY24_WIDTH 4 /* WSEQ_DELAY24 - [3:0] */ + +/* + * R12388 (0x3064) - Write Sequencer 100 + */ +#define WM8995_WSEQ_ADDR25_MASK 0x3FFF /* WSEQ_ADDR25 - [13:0] */ +#define WM8995_WSEQ_ADDR25_SHIFT 0 /* WSEQ_ADDR25 - [13:0] */ +#define WM8995_WSEQ_ADDR25_WIDTH 14 /* WSEQ_ADDR25 - [13:0] */ + +/* + * R12389 (0x3065) - Write Sequencer 101 + */ +#define WM8995_WSEQ_DATA25_MASK 0x00FF /* WSEQ_DATA25 - [7:0] */ +#define WM8995_WSEQ_DATA25_SHIFT 0 /* WSEQ_DATA25 - [7:0] */ +#define WM8995_WSEQ_DATA25_WIDTH 8 /* WSEQ_DATA25 - [7:0] */ + +/* + * R12390 (0x3066) - Write Sequencer 102 + */ +#define WM8995_WSEQ_DATA_WIDTH25_MASK 0x0700 /* WSEQ_DATA_WIDTH25 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH25_SHIFT 8 /* WSEQ_DATA_WIDTH25 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH25_WIDTH 3 /* WSEQ_DATA_WIDTH25 - [10:8] */ +#define WM8995_WSEQ_DATA_START25_MASK 0x000F /* WSEQ_DATA_START25 - [3:0] */ +#define WM8995_WSEQ_DATA_START25_SHIFT 0 /* WSEQ_DATA_START25 - [3:0] */ +#define WM8995_WSEQ_DATA_START25_WIDTH 4 /* WSEQ_DATA_START25 - [3:0] */ + +/* + * R12391 (0x3067) - Write Sequencer 103 + */ +#define WM8995_WSEQ_EOS25 0x0100 /* WSEQ_EOS25 */ +#define WM8995_WSEQ_EOS25_MASK 0x0100 /* WSEQ_EOS25 */ +#define WM8995_WSEQ_EOS25_SHIFT 8 /* WSEQ_EOS25 */ +#define WM8995_WSEQ_EOS25_WIDTH 1 /* WSEQ_EOS25 */ +#define WM8995_WSEQ_DELAY25_MASK 0x000F /* WSEQ_DELAY25 - [3:0] */ +#define WM8995_WSEQ_DELAY25_SHIFT 0 /* WSEQ_DELAY25 - [3:0] */ +#define WM8995_WSEQ_DELAY25_WIDTH 4 /* WSEQ_DELAY25 - [3:0] */ + +/* + * R12392 (0x3068) - Write Sequencer 104 + */ +#define WM8995_WSEQ_ADDR26_MASK 0x3FFF /* WSEQ_ADDR26 - [13:0] */ +#define WM8995_WSEQ_ADDR26_SHIFT 0 /* WSEQ_ADDR26 - [13:0] */ +#define WM8995_WSEQ_ADDR26_WIDTH 14 /* WSEQ_ADDR26 - [13:0] */ + +/* + * R12393 (0x3069) - Write Sequencer 105 + */ +#define WM8995_WSEQ_DATA26_MASK 0x00FF /* WSEQ_DATA26 - [7:0] */ +#define WM8995_WSEQ_DATA26_SHIFT 0 /* WSEQ_DATA26 - [7:0] */ +#define WM8995_WSEQ_DATA26_WIDTH 8 /* WSEQ_DATA26 - [7:0] */ + +/* + * R12394 (0x306A) - Write Sequencer 106 + */ +#define WM8995_WSEQ_DATA_WIDTH26_MASK 0x0700 /* WSEQ_DATA_WIDTH26 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH26_SHIFT 8 /* WSEQ_DATA_WIDTH26 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH26_WIDTH 3 /* WSEQ_DATA_WIDTH26 - [10:8] */ +#define WM8995_WSEQ_DATA_START26_MASK 0x000F /* WSEQ_DATA_START26 - [3:0] */ +#define WM8995_WSEQ_DATA_START26_SHIFT 0 /* WSEQ_DATA_START26 - [3:0] */ +#define WM8995_WSEQ_DATA_START26_WIDTH 4 /* WSEQ_DATA_START26 - [3:0] */ + +/* + * R12395 (0x306B) - Write Sequencer 107 + */ +#define WM8995_WSEQ_EOS26 0x0100 /* WSEQ_EOS26 */ +#define WM8995_WSEQ_EOS26_MASK 0x0100 /* WSEQ_EOS26 */ +#define WM8995_WSEQ_EOS26_SHIFT 8 /* WSEQ_EOS26 */ +#define WM8995_WSEQ_EOS26_WIDTH 1 /* WSEQ_EOS26 */ +#define WM8995_WSEQ_DELAY26_MASK 0x000F /* WSEQ_DELAY26 - [3:0] */ +#define WM8995_WSEQ_DELAY26_SHIFT 0 /* WSEQ_DELAY26 - [3:0] */ +#define WM8995_WSEQ_DELAY26_WIDTH 4 /* WSEQ_DELAY26 - [3:0] */ + +/* + * R12396 (0x306C) - Write Sequencer 108 + */ +#define WM8995_WSEQ_ADDR27_MASK 0x3FFF /* WSEQ_ADDR27 - [13:0] */ +#define WM8995_WSEQ_ADDR27_SHIFT 0 /* WSEQ_ADDR27 - [13:0] */ +#define WM8995_WSEQ_ADDR27_WIDTH 14 /* WSEQ_ADDR27 - [13:0] */ + +/* + * R12397 (0x306D) - Write Sequencer 109 + */ +#define WM8995_WSEQ_DATA27_MASK 0x00FF /* WSEQ_DATA27 - [7:0] */ +#define WM8995_WSEQ_DATA27_SHIFT 0 /* WSEQ_DATA27 - [7:0] */ +#define WM8995_WSEQ_DATA27_WIDTH 8 /* WSEQ_DATA27 - [7:0] */ + +/* + * R12398 (0x306E) - Write Sequencer 110 + */ +#define WM8995_WSEQ_DATA_WIDTH27_MASK 0x0700 /* WSEQ_DATA_WIDTH27 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH27_SHIFT 8 /* WSEQ_DATA_WIDTH27 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH27_WIDTH 3 /* WSEQ_DATA_WIDTH27 - [10:8] */ +#define WM8995_WSEQ_DATA_START27_MASK 0x000F /* WSEQ_DATA_START27 - [3:0] */ +#define WM8995_WSEQ_DATA_START27_SHIFT 0 /* WSEQ_DATA_START27 - [3:0] */ +#define WM8995_WSEQ_DATA_START27_WIDTH 4 /* WSEQ_DATA_START27 - [3:0] */ + +/* + * R12399 (0x306F) - Write Sequencer 111 + */ +#define WM8995_WSEQ_EOS27 0x0100 /* WSEQ_EOS27 */ +#define WM8995_WSEQ_EOS27_MASK 0x0100 /* WSEQ_EOS27 */ +#define WM8995_WSEQ_EOS27_SHIFT 8 /* WSEQ_EOS27 */ +#define WM8995_WSEQ_EOS27_WIDTH 1 /* WSEQ_EOS27 */ +#define WM8995_WSEQ_DELAY27_MASK 0x000F /* WSEQ_DELAY27 - [3:0] */ +#define WM8995_WSEQ_DELAY27_SHIFT 0 /* WSEQ_DELAY27 - [3:0] */ +#define WM8995_WSEQ_DELAY27_WIDTH 4 /* WSEQ_DELAY27 - [3:0] */ + +/* + * R12400 (0x3070) - Write Sequencer 112 + */ +#define WM8995_WSEQ_ADDR28_MASK 0x3FFF /* WSEQ_ADDR28 - [13:0] */ +#define WM8995_WSEQ_ADDR28_SHIFT 0 /* WSEQ_ADDR28 - [13:0] */ +#define WM8995_WSEQ_ADDR28_WIDTH 14 /* WSEQ_ADDR28 - [13:0] */ + +/* + * R12401 (0x3071) - Write Sequencer 113 + */ +#define WM8995_WSEQ_DATA28_MASK 0x00FF /* WSEQ_DATA28 - [7:0] */ +#define WM8995_WSEQ_DATA28_SHIFT 0 /* WSEQ_DATA28 - [7:0] */ +#define WM8995_WSEQ_DATA28_WIDTH 8 /* WSEQ_DATA28 - [7:0] */ + +/* + * R12402 (0x3072) - Write Sequencer 114 + */ +#define WM8995_WSEQ_DATA_WIDTH28_MASK 0x0700 /* WSEQ_DATA_WIDTH28 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH28_SHIFT 8 /* WSEQ_DATA_WIDTH28 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH28_WIDTH 3 /* WSEQ_DATA_WIDTH28 - [10:8] */ +#define WM8995_WSEQ_DATA_START28_MASK 0x000F /* WSEQ_DATA_START28 - [3:0] */ +#define WM8995_WSEQ_DATA_START28_SHIFT 0 /* WSEQ_DATA_START28 - [3:0] */ +#define WM8995_WSEQ_DATA_START28_WIDTH 4 /* WSEQ_DATA_START28 - [3:0] */ + +/* + * R12403 (0x3073) - Write Sequencer 115 + */ +#define WM8995_WSEQ_EOS28 0x0100 /* WSEQ_EOS28 */ +#define WM8995_WSEQ_EOS28_MASK 0x0100 /* WSEQ_EOS28 */ +#define WM8995_WSEQ_EOS28_SHIFT 8 /* WSEQ_EOS28 */ +#define WM8995_WSEQ_EOS28_WIDTH 1 /* WSEQ_EOS28 */ +#define WM8995_WSEQ_DELAY28_MASK 0x000F /* WSEQ_DELAY28 - [3:0] */ +#define WM8995_WSEQ_DELAY28_SHIFT 0 /* WSEQ_DELAY28 - [3:0] */ +#define WM8995_WSEQ_DELAY28_WIDTH 4 /* WSEQ_DELAY28 - [3:0] */ + +/* + * R12404 (0x3074) - Write Sequencer 116 + */ +#define WM8995_WSEQ_ADDR29_MASK 0x3FFF /* WSEQ_ADDR29 - [13:0] */ +#define WM8995_WSEQ_ADDR29_SHIFT 0 /* WSEQ_ADDR29 - [13:0] */ +#define WM8995_WSEQ_ADDR29_WIDTH 14 /* WSEQ_ADDR29 - [13:0] */ + +/* + * R12405 (0x3075) - Write Sequencer 117 + */ +#define WM8995_WSEQ_DATA29_MASK 0x00FF /* WSEQ_DATA29 - [7:0] */ +#define WM8995_WSEQ_DATA29_SHIFT 0 /* WSEQ_DATA29 - [7:0] */ +#define WM8995_WSEQ_DATA29_WIDTH 8 /* WSEQ_DATA29 - [7:0] */ + +/* + * R12406 (0x3076) - Write Sequencer 118 + */ +#define WM8995_WSEQ_DATA_WIDTH29_MASK 0x0700 /* WSEQ_DATA_WIDTH29 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH29_SHIFT 8 /* WSEQ_DATA_WIDTH29 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH29_WIDTH 3 /* WSEQ_DATA_WIDTH29 - [10:8] */ +#define WM8995_WSEQ_DATA_START29_MASK 0x000F /* WSEQ_DATA_START29 - [3:0] */ +#define WM8995_WSEQ_DATA_START29_SHIFT 0 /* WSEQ_DATA_START29 - [3:0] */ +#define WM8995_WSEQ_DATA_START29_WIDTH 4 /* WSEQ_DATA_START29 - [3:0] */ + +/* + * R12407 (0x3077) - Write Sequencer 119 + */ +#define WM8995_WSEQ_EOS29 0x0100 /* WSEQ_EOS29 */ +#define WM8995_WSEQ_EOS29_MASK 0x0100 /* WSEQ_EOS29 */ +#define WM8995_WSEQ_EOS29_SHIFT 8 /* WSEQ_EOS29 */ +#define WM8995_WSEQ_EOS29_WIDTH 1 /* WSEQ_EOS29 */ +#define WM8995_WSEQ_DELAY29_MASK 0x000F /* WSEQ_DELAY29 - [3:0] */ +#define WM8995_WSEQ_DELAY29_SHIFT 0 /* WSEQ_DELAY29 - [3:0] */ +#define WM8995_WSEQ_DELAY29_WIDTH 4 /* WSEQ_DELAY29 - [3:0] */ + +/* + * R12408 (0x3078) - Write Sequencer 120 + */ +#define WM8995_WSEQ_ADDR30_MASK 0x3FFF /* WSEQ_ADDR30 - [13:0] */ +#define WM8995_WSEQ_ADDR30_SHIFT 0 /* WSEQ_ADDR30 - [13:0] */ +#define WM8995_WSEQ_ADDR30_WIDTH 14 /* WSEQ_ADDR30 - [13:0] */ + +/* + * R12409 (0x3079) - Write Sequencer 121 + */ +#define WM8995_WSEQ_DATA30_MASK 0x00FF /* WSEQ_DATA30 - [7:0] */ +#define WM8995_WSEQ_DATA30_SHIFT 0 /* WSEQ_DATA30 - [7:0] */ +#define WM8995_WSEQ_DATA30_WIDTH 8 /* WSEQ_DATA30 - [7:0] */ + +/* + * R12410 (0x307A) - Write Sequencer 122 + */ +#define WM8995_WSEQ_DATA_WIDTH30_MASK 0x0700 /* WSEQ_DATA_WIDTH30 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH30_SHIFT 8 /* WSEQ_DATA_WIDTH30 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH30_WIDTH 3 /* WSEQ_DATA_WIDTH30 - [10:8] */ +#define WM8995_WSEQ_DATA_START30_MASK 0x000F /* WSEQ_DATA_START30 - [3:0] */ +#define WM8995_WSEQ_DATA_START30_SHIFT 0 /* WSEQ_DATA_START30 - [3:0] */ +#define WM8995_WSEQ_DATA_START30_WIDTH 4 /* WSEQ_DATA_START30 - [3:0] */ + +/* + * R12411 (0x307B) - Write Sequencer 123 + */ +#define WM8995_WSEQ_EOS30 0x0100 /* WSEQ_EOS30 */ +#define WM8995_WSEQ_EOS30_MASK 0x0100 /* WSEQ_EOS30 */ +#define WM8995_WSEQ_EOS30_SHIFT 8 /* WSEQ_EOS30 */ +#define WM8995_WSEQ_EOS30_WIDTH 1 /* WSEQ_EOS30 */ +#define WM8995_WSEQ_DELAY30_MASK 0x000F /* WSEQ_DELAY30 - [3:0] */ +#define WM8995_WSEQ_DELAY30_SHIFT 0 /* WSEQ_DELAY30 - [3:0] */ +#define WM8995_WSEQ_DELAY30_WIDTH 4 /* WSEQ_DELAY30 - [3:0] */ + +/* + * R12412 (0x307C) - Write Sequencer 124 + */ +#define WM8995_WSEQ_ADDR31_MASK 0x3FFF /* WSEQ_ADDR31 - [13:0] */ +#define WM8995_WSEQ_ADDR31_SHIFT 0 /* WSEQ_ADDR31 - [13:0] */ +#define WM8995_WSEQ_ADDR31_WIDTH 14 /* WSEQ_ADDR31 - [13:0] */ + +/* + * R12413 (0x307D) - Write Sequencer 125 + */ +#define WM8995_WSEQ_DATA31_MASK 0x00FF /* WSEQ_DATA31 - [7:0] */ +#define WM8995_WSEQ_DATA31_SHIFT 0 /* WSEQ_DATA31 - [7:0] */ +#define WM8995_WSEQ_DATA31_WIDTH 8 /* WSEQ_DATA31 - [7:0] */ + +/* + * R12414 (0x307E) - Write Sequencer 126 + */ +#define WM8995_WSEQ_DATA_WIDTH31_MASK 0x0700 /* WSEQ_DATA_WIDTH31 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH31_SHIFT 8 /* WSEQ_DATA_WIDTH31 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH31_WIDTH 3 /* WSEQ_DATA_WIDTH31 - [10:8] */ +#define WM8995_WSEQ_DATA_START31_MASK 0x000F /* WSEQ_DATA_START31 - [3:0] */ +#define WM8995_WSEQ_DATA_START31_SHIFT 0 /* WSEQ_DATA_START31 - [3:0] */ +#define WM8995_WSEQ_DATA_START31_WIDTH 4 /* WSEQ_DATA_START31 - [3:0] */ + +/* + * R12415 (0x307F) - Write Sequencer 127 + */ +#define WM8995_WSEQ_EOS31 0x0100 /* WSEQ_EOS31 */ +#define WM8995_WSEQ_EOS31_MASK 0x0100 /* WSEQ_EOS31 */ +#define WM8995_WSEQ_EOS31_SHIFT 8 /* WSEQ_EOS31 */ +#define WM8995_WSEQ_EOS31_WIDTH 1 /* WSEQ_EOS31 */ +#define WM8995_WSEQ_DELAY31_MASK 0x000F /* WSEQ_DELAY31 - [3:0] */ +#define WM8995_WSEQ_DELAY31_SHIFT 0 /* WSEQ_DELAY31 - [3:0] */ +#define WM8995_WSEQ_DELAY31_WIDTH 4 /* WSEQ_DELAY31 - [3:0] */ + +/* + * R12416 (0x3080) - Write Sequencer 128 + */ +#define WM8995_WSEQ_ADDR32_MASK 0x3FFF /* WSEQ_ADDR32 - [13:0] */ +#define WM8995_WSEQ_ADDR32_SHIFT 0 /* WSEQ_ADDR32 - [13:0] */ +#define WM8995_WSEQ_ADDR32_WIDTH 14 /* WSEQ_ADDR32 - [13:0] */ + +/* + * R12417 (0x3081) - Write Sequencer 129 + */ +#define WM8995_WSEQ_DATA32_MASK 0x00FF /* WSEQ_DATA32 - [7:0] */ +#define WM8995_WSEQ_DATA32_SHIFT 0 /* WSEQ_DATA32 - [7:0] */ +#define WM8995_WSEQ_DATA32_WIDTH 8 /* WSEQ_DATA32 - [7:0] */ + +/* + * R12418 (0x3082) - Write Sequencer 130 + */ +#define WM8995_WSEQ_DATA_WIDTH32_MASK 0x0700 /* WSEQ_DATA_WIDTH32 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH32_SHIFT 8 /* WSEQ_DATA_WIDTH32 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH32_WIDTH 3 /* WSEQ_DATA_WIDTH32 - [10:8] */ +#define WM8995_WSEQ_DATA_START32_MASK 0x000F /* WSEQ_DATA_START32 - [3:0] */ +#define WM8995_WSEQ_DATA_START32_SHIFT 0 /* WSEQ_DATA_START32 - [3:0] */ +#define WM8995_WSEQ_DATA_START32_WIDTH 4 /* WSEQ_DATA_START32 - [3:0] */ + +/* + * R12419 (0x3083) - Write Sequencer 131 + */ +#define WM8995_WSEQ_EOS32 0x0100 /* WSEQ_EOS32 */ +#define WM8995_WSEQ_EOS32_MASK 0x0100 /* WSEQ_EOS32 */ +#define WM8995_WSEQ_EOS32_SHIFT 8 /* WSEQ_EOS32 */ +#define WM8995_WSEQ_EOS32_WIDTH 1 /* WSEQ_EOS32 */ +#define WM8995_WSEQ_DELAY32_MASK 0x000F /* WSEQ_DELAY32 - [3:0] */ +#define WM8995_WSEQ_DELAY32_SHIFT 0 /* WSEQ_DELAY32 - [3:0] */ +#define WM8995_WSEQ_DELAY32_WIDTH 4 /* WSEQ_DELAY32 - [3:0] */ + +/* + * R12420 (0x3084) - Write Sequencer 132 + */ +#define WM8995_WSEQ_ADDR33_MASK 0x3FFF /* WSEQ_ADDR33 - [13:0] */ +#define WM8995_WSEQ_ADDR33_SHIFT 0 /* WSEQ_ADDR33 - [13:0] */ +#define WM8995_WSEQ_ADDR33_WIDTH 14 /* WSEQ_ADDR33 - [13:0] */ + +/* + * R12421 (0x3085) - Write Sequencer 133 + */ +#define WM8995_WSEQ_DATA33_MASK 0x00FF /* WSEQ_DATA33 - [7:0] */ +#define WM8995_WSEQ_DATA33_SHIFT 0 /* WSEQ_DATA33 - [7:0] */ +#define WM8995_WSEQ_DATA33_WIDTH 8 /* WSEQ_DATA33 - [7:0] */ + +/* + * R12422 (0x3086) - Write Sequencer 134 + */ +#define WM8995_WSEQ_DATA_WIDTH33_MASK 0x0700 /* WSEQ_DATA_WIDTH33 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH33_SHIFT 8 /* WSEQ_DATA_WIDTH33 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH33_WIDTH 3 /* WSEQ_DATA_WIDTH33 - [10:8] */ +#define WM8995_WSEQ_DATA_START33_MASK 0x000F /* WSEQ_DATA_START33 - [3:0] */ +#define WM8995_WSEQ_DATA_START33_SHIFT 0 /* WSEQ_DATA_START33 - [3:0] */ +#define WM8995_WSEQ_DATA_START33_WIDTH 4 /* WSEQ_DATA_START33 - [3:0] */ + +/* + * R12423 (0x3087) - Write Sequencer 135 + */ +#define WM8995_WSEQ_EOS33 0x0100 /* WSEQ_EOS33 */ +#define WM8995_WSEQ_EOS33_MASK 0x0100 /* WSEQ_EOS33 */ +#define WM8995_WSEQ_EOS33_SHIFT 8 /* WSEQ_EOS33 */ +#define WM8995_WSEQ_EOS33_WIDTH 1 /* WSEQ_EOS33 */ +#define WM8995_WSEQ_DELAY33_MASK 0x000F /* WSEQ_DELAY33 - [3:0] */ +#define WM8995_WSEQ_DELAY33_SHIFT 0 /* WSEQ_DELAY33 - [3:0] */ +#define WM8995_WSEQ_DELAY33_WIDTH 4 /* WSEQ_DELAY33 - [3:0] */ + +/* + * R12424 (0x3088) - Write Sequencer 136 + */ +#define WM8995_WSEQ_ADDR34_MASK 0x3FFF /* WSEQ_ADDR34 - [13:0] */ +#define WM8995_WSEQ_ADDR34_SHIFT 0 /* WSEQ_ADDR34 - [13:0] */ +#define WM8995_WSEQ_ADDR34_WIDTH 14 /* WSEQ_ADDR34 - [13:0] */ + +/* + * R12425 (0x3089) - Write Sequencer 137 + */ +#define WM8995_WSEQ_DATA34_MASK 0x00FF /* WSEQ_DATA34 - [7:0] */ +#define WM8995_WSEQ_DATA34_SHIFT 0 /* WSEQ_DATA34 - [7:0] */ +#define WM8995_WSEQ_DATA34_WIDTH 8 /* WSEQ_DATA34 - [7:0] */ + +/* + * R12426 (0x308A) - Write Sequencer 138 + */ +#define WM8995_WSEQ_DATA_WIDTH34_MASK 0x0700 /* WSEQ_DATA_WIDTH34 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH34_SHIFT 8 /* WSEQ_DATA_WIDTH34 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH34_WIDTH 3 /* WSEQ_DATA_WIDTH34 - [10:8] */ +#define WM8995_WSEQ_DATA_START34_MASK 0x000F /* WSEQ_DATA_START34 - [3:0] */ +#define WM8995_WSEQ_DATA_START34_SHIFT 0 /* WSEQ_DATA_START34 - [3:0] */ +#define WM8995_WSEQ_DATA_START34_WIDTH 4 /* WSEQ_DATA_START34 - [3:0] */ + +/* + * R12427 (0x308B) - Write Sequencer 139 + */ +#define WM8995_WSEQ_EOS34 0x0100 /* WSEQ_EOS34 */ +#define WM8995_WSEQ_EOS34_MASK 0x0100 /* WSEQ_EOS34 */ +#define WM8995_WSEQ_EOS34_SHIFT 8 /* WSEQ_EOS34 */ +#define WM8995_WSEQ_EOS34_WIDTH 1 /* WSEQ_EOS34 */ +#define WM8995_WSEQ_DELAY34_MASK 0x000F /* WSEQ_DELAY34 - [3:0] */ +#define WM8995_WSEQ_DELAY34_SHIFT 0 /* WSEQ_DELAY34 - [3:0] */ +#define WM8995_WSEQ_DELAY34_WIDTH 4 /* WSEQ_DELAY34 - [3:0] */ + +/* + * R12428 (0x308C) - Write Sequencer 140 + */ +#define WM8995_WSEQ_ADDR35_MASK 0x3FFF /* WSEQ_ADDR35 - [13:0] */ +#define WM8995_WSEQ_ADDR35_SHIFT 0 /* WSEQ_ADDR35 - [13:0] */ +#define WM8995_WSEQ_ADDR35_WIDTH 14 /* WSEQ_ADDR35 - [13:0] */ + +/* + * R12429 (0x308D) - Write Sequencer 141 + */ +#define WM8995_WSEQ_DATA35_MASK 0x00FF /* WSEQ_DATA35 - [7:0] */ +#define WM8995_WSEQ_DATA35_SHIFT 0 /* WSEQ_DATA35 - [7:0] */ +#define WM8995_WSEQ_DATA35_WIDTH 8 /* WSEQ_DATA35 - [7:0] */ + +/* + * R12430 (0x308E) - Write Sequencer 142 + */ +#define WM8995_WSEQ_DATA_WIDTH35_MASK 0x0700 /* WSEQ_DATA_WIDTH35 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH35_SHIFT 8 /* WSEQ_DATA_WIDTH35 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH35_WIDTH 3 /* WSEQ_DATA_WIDTH35 - [10:8] */ +#define WM8995_WSEQ_DATA_START35_MASK 0x000F /* WSEQ_DATA_START35 - [3:0] */ +#define WM8995_WSEQ_DATA_START35_SHIFT 0 /* WSEQ_DATA_START35 - [3:0] */ +#define WM8995_WSEQ_DATA_START35_WIDTH 4 /* WSEQ_DATA_START35 - [3:0] */ + +/* + * R12431 (0x308F) - Write Sequencer 143 + */ +#define WM8995_WSEQ_EOS35 0x0100 /* WSEQ_EOS35 */ +#define WM8995_WSEQ_EOS35_MASK 0x0100 /* WSEQ_EOS35 */ +#define WM8995_WSEQ_EOS35_SHIFT 8 /* WSEQ_EOS35 */ +#define WM8995_WSEQ_EOS35_WIDTH 1 /* WSEQ_EOS35 */ +#define WM8995_WSEQ_DELAY35_MASK 0x000F /* WSEQ_DELAY35 - [3:0] */ +#define WM8995_WSEQ_DELAY35_SHIFT 0 /* WSEQ_DELAY35 - [3:0] */ +#define WM8995_WSEQ_DELAY35_WIDTH 4 /* WSEQ_DELAY35 - [3:0] */ + +/* + * R12432 (0x3090) - Write Sequencer 144 + */ +#define WM8995_WSEQ_ADDR36_MASK 0x3FFF /* WSEQ_ADDR36 - [13:0] */ +#define WM8995_WSEQ_ADDR36_SHIFT 0 /* WSEQ_ADDR36 - [13:0] */ +#define WM8995_WSEQ_ADDR36_WIDTH 14 /* WSEQ_ADDR36 - [13:0] */ + +/* + * R12433 (0x3091) - Write Sequencer 145 + */ +#define WM8995_WSEQ_DATA36_MASK 0x00FF /* WSEQ_DATA36 - [7:0] */ +#define WM8995_WSEQ_DATA36_SHIFT 0 /* WSEQ_DATA36 - [7:0] */ +#define WM8995_WSEQ_DATA36_WIDTH 8 /* WSEQ_DATA36 - [7:0] */ + +/* + * R12434 (0x3092) - Write Sequencer 146 + */ +#define WM8995_WSEQ_DATA_WIDTH36_MASK 0x0700 /* WSEQ_DATA_WIDTH36 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH36_SHIFT 8 /* WSEQ_DATA_WIDTH36 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH36_WIDTH 3 /* WSEQ_DATA_WIDTH36 - [10:8] */ +#define WM8995_WSEQ_DATA_START36_MASK 0x000F /* WSEQ_DATA_START36 - [3:0] */ +#define WM8995_WSEQ_DATA_START36_SHIFT 0 /* WSEQ_DATA_START36 - [3:0] */ +#define WM8995_WSEQ_DATA_START36_WIDTH 4 /* WSEQ_DATA_START36 - [3:0] */ + +/* + * R12435 (0x3093) - Write Sequencer 147 + */ +#define WM8995_WSEQ_EOS36 0x0100 /* WSEQ_EOS36 */ +#define WM8995_WSEQ_EOS36_MASK 0x0100 /* WSEQ_EOS36 */ +#define WM8995_WSEQ_EOS36_SHIFT 8 /* WSEQ_EOS36 */ +#define WM8995_WSEQ_EOS36_WIDTH 1 /* WSEQ_EOS36 */ +#define WM8995_WSEQ_DELAY36_MASK 0x000F /* WSEQ_DELAY36 - [3:0] */ +#define WM8995_WSEQ_DELAY36_SHIFT 0 /* WSEQ_DELAY36 - [3:0] */ +#define WM8995_WSEQ_DELAY36_WIDTH 4 /* WSEQ_DELAY36 - [3:0] */ + +/* + * R12436 (0x3094) - Write Sequencer 148 + */ +#define WM8995_WSEQ_ADDR37_MASK 0x3FFF /* WSEQ_ADDR37 - [13:0] */ +#define WM8995_WSEQ_ADDR37_SHIFT 0 /* WSEQ_ADDR37 - [13:0] */ +#define WM8995_WSEQ_ADDR37_WIDTH 14 /* WSEQ_ADDR37 - [13:0] */ + +/* + * R12437 (0x3095) - Write Sequencer 149 + */ +#define WM8995_WSEQ_DATA37_MASK 0x00FF /* WSEQ_DATA37 - [7:0] */ +#define WM8995_WSEQ_DATA37_SHIFT 0 /* WSEQ_DATA37 - [7:0] */ +#define WM8995_WSEQ_DATA37_WIDTH 8 /* WSEQ_DATA37 - [7:0] */ + +/* + * R12438 (0x3096) - Write Sequencer 150 + */ +#define WM8995_WSEQ_DATA_WIDTH37_MASK 0x0700 /* WSEQ_DATA_WIDTH37 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH37_SHIFT 8 /* WSEQ_DATA_WIDTH37 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH37_WIDTH 3 /* WSEQ_DATA_WIDTH37 - [10:8] */ +#define WM8995_WSEQ_DATA_START37_MASK 0x000F /* WSEQ_DATA_START37 - [3:0] */ +#define WM8995_WSEQ_DATA_START37_SHIFT 0 /* WSEQ_DATA_START37 - [3:0] */ +#define WM8995_WSEQ_DATA_START37_WIDTH 4 /* WSEQ_DATA_START37 - [3:0] */ + +/* + * R12439 (0x3097) - Write Sequencer 151 + */ +#define WM8995_WSEQ_EOS37 0x0100 /* WSEQ_EOS37 */ +#define WM8995_WSEQ_EOS37_MASK 0x0100 /* WSEQ_EOS37 */ +#define WM8995_WSEQ_EOS37_SHIFT 8 /* WSEQ_EOS37 */ +#define WM8995_WSEQ_EOS37_WIDTH 1 /* WSEQ_EOS37 */ +#define WM8995_WSEQ_DELAY37_MASK 0x000F /* WSEQ_DELAY37 - [3:0] */ +#define WM8995_WSEQ_DELAY37_SHIFT 0 /* WSEQ_DELAY37 - [3:0] */ +#define WM8995_WSEQ_DELAY37_WIDTH 4 /* WSEQ_DELAY37 - [3:0] */ + +/* + * R12440 (0x3098) - Write Sequencer 152 + */ +#define WM8995_WSEQ_ADDR38_MASK 0x3FFF /* WSEQ_ADDR38 - [13:0] */ +#define WM8995_WSEQ_ADDR38_SHIFT 0 /* WSEQ_ADDR38 - [13:0] */ +#define WM8995_WSEQ_ADDR38_WIDTH 14 /* WSEQ_ADDR38 - [13:0] */ + +/* + * R12441 (0x3099) - Write Sequencer 153 + */ +#define WM8995_WSEQ_DATA38_MASK 0x00FF /* WSEQ_DATA38 - [7:0] */ +#define WM8995_WSEQ_DATA38_SHIFT 0 /* WSEQ_DATA38 - [7:0] */ +#define WM8995_WSEQ_DATA38_WIDTH 8 /* WSEQ_DATA38 - [7:0] */ + +/* + * R12442 (0x309A) - Write Sequencer 154 + */ +#define WM8995_WSEQ_DATA_WIDTH38_MASK 0x0700 /* WSEQ_DATA_WIDTH38 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH38_SHIFT 8 /* WSEQ_DATA_WIDTH38 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH38_WIDTH 3 /* WSEQ_DATA_WIDTH38 - [10:8] */ +#define WM8995_WSEQ_DATA_START38_MASK 0x000F /* WSEQ_DATA_START38 - [3:0] */ +#define WM8995_WSEQ_DATA_START38_SHIFT 0 /* WSEQ_DATA_START38 - [3:0] */ +#define WM8995_WSEQ_DATA_START38_WIDTH 4 /* WSEQ_DATA_START38 - [3:0] */ + +/* + * R12443 (0x309B) - Write Sequencer 155 + */ +#define WM8995_WSEQ_EOS38 0x0100 /* WSEQ_EOS38 */ +#define WM8995_WSEQ_EOS38_MASK 0x0100 /* WSEQ_EOS38 */ +#define WM8995_WSEQ_EOS38_SHIFT 8 /* WSEQ_EOS38 */ +#define WM8995_WSEQ_EOS38_WIDTH 1 /* WSEQ_EOS38 */ +#define WM8995_WSEQ_DELAY38_MASK 0x000F /* WSEQ_DELAY38 - [3:0] */ +#define WM8995_WSEQ_DELAY38_SHIFT 0 /* WSEQ_DELAY38 - [3:0] */ +#define WM8995_WSEQ_DELAY38_WIDTH 4 /* WSEQ_DELAY38 - [3:0] */ + +/* + * R12444 (0x309C) - Write Sequencer 156 + */ +#define WM8995_WSEQ_ADDR39_MASK 0x3FFF /* WSEQ_ADDR39 - [13:0] */ +#define WM8995_WSEQ_ADDR39_SHIFT 0 /* WSEQ_ADDR39 - [13:0] */ +#define WM8995_WSEQ_ADDR39_WIDTH 14 /* WSEQ_ADDR39 - [13:0] */ + +/* + * R12445 (0x309D) - Write Sequencer 157 + */ +#define WM8995_WSEQ_DATA39_MASK 0x00FF /* WSEQ_DATA39 - [7:0] */ +#define WM8995_WSEQ_DATA39_SHIFT 0 /* WSEQ_DATA39 - [7:0] */ +#define WM8995_WSEQ_DATA39_WIDTH 8 /* WSEQ_DATA39 - [7:0] */ + +/* + * R12446 (0x309E) - Write Sequencer 158 + */ +#define WM8995_WSEQ_DATA_WIDTH39_MASK 0x0700 /* WSEQ_DATA_WIDTH39 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH39_SHIFT 8 /* WSEQ_DATA_WIDTH39 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH39_WIDTH 3 /* WSEQ_DATA_WIDTH39 - [10:8] */ +#define WM8995_WSEQ_DATA_START39_MASK 0x000F /* WSEQ_DATA_START39 - [3:0] */ +#define WM8995_WSEQ_DATA_START39_SHIFT 0 /* WSEQ_DATA_START39 - [3:0] */ +#define WM8995_WSEQ_DATA_START39_WIDTH 4 /* WSEQ_DATA_START39 - [3:0] */ + +/* + * R12447 (0x309F) - Write Sequencer 159 + */ +#define WM8995_WSEQ_EOS39 0x0100 /* WSEQ_EOS39 */ +#define WM8995_WSEQ_EOS39_MASK 0x0100 /* WSEQ_EOS39 */ +#define WM8995_WSEQ_EOS39_SHIFT 8 /* WSEQ_EOS39 */ +#define WM8995_WSEQ_EOS39_WIDTH 1 /* WSEQ_EOS39 */ +#define WM8995_WSEQ_DELAY39_MASK 0x000F /* WSEQ_DELAY39 - [3:0] */ +#define WM8995_WSEQ_DELAY39_SHIFT 0 /* WSEQ_DELAY39 - [3:0] */ +#define WM8995_WSEQ_DELAY39_WIDTH 4 /* WSEQ_DELAY39 - [3:0] */ + +/* + * R12448 (0x30A0) - Write Sequencer 160 + */ +#define WM8995_WSEQ_ADDR40_MASK 0x3FFF /* WSEQ_ADDR40 - [13:0] */ +#define WM8995_WSEQ_ADDR40_SHIFT 0 /* WSEQ_ADDR40 - [13:0] */ +#define WM8995_WSEQ_ADDR40_WIDTH 14 /* WSEQ_ADDR40 - [13:0] */ + +/* + * R12449 (0x30A1) - Write Sequencer 161 + */ +#define WM8995_WSEQ_DATA40_MASK 0x00FF /* WSEQ_DATA40 - [7:0] */ +#define WM8995_WSEQ_DATA40_SHIFT 0 /* WSEQ_DATA40 - [7:0] */ +#define WM8995_WSEQ_DATA40_WIDTH 8 /* WSEQ_DATA40 - [7:0] */ + +/* + * R12450 (0x30A2) - Write Sequencer 162 + */ +#define WM8995_WSEQ_DATA_WIDTH40_MASK 0x0700 /* WSEQ_DATA_WIDTH40 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH40_SHIFT 8 /* WSEQ_DATA_WIDTH40 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH40_WIDTH 3 /* WSEQ_DATA_WIDTH40 - [10:8] */ +#define WM8995_WSEQ_DATA_START40_MASK 0x000F /* WSEQ_DATA_START40 - [3:0] */ +#define WM8995_WSEQ_DATA_START40_SHIFT 0 /* WSEQ_DATA_START40 - [3:0] */ +#define WM8995_WSEQ_DATA_START40_WIDTH 4 /* WSEQ_DATA_START40 - [3:0] */ + +/* + * R12451 (0x30A3) - Write Sequencer 163 + */ +#define WM8995_WSEQ_EOS40 0x0100 /* WSEQ_EOS40 */ +#define WM8995_WSEQ_EOS40_MASK 0x0100 /* WSEQ_EOS40 */ +#define WM8995_WSEQ_EOS40_SHIFT 8 /* WSEQ_EOS40 */ +#define WM8995_WSEQ_EOS40_WIDTH 1 /* WSEQ_EOS40 */ +#define WM8995_WSEQ_DELAY40_MASK 0x000F /* WSEQ_DELAY40 - [3:0] */ +#define WM8995_WSEQ_DELAY40_SHIFT 0 /* WSEQ_DELAY40 - [3:0] */ +#define WM8995_WSEQ_DELAY40_WIDTH 4 /* WSEQ_DELAY40 - [3:0] */ + +/* + * R12452 (0x30A4) - Write Sequencer 164 + */ +#define WM8995_WSEQ_ADDR41_MASK 0x3FFF /* WSEQ_ADDR41 - [13:0] */ +#define WM8995_WSEQ_ADDR41_SHIFT 0 /* WSEQ_ADDR41 - [13:0] */ +#define WM8995_WSEQ_ADDR41_WIDTH 14 /* WSEQ_ADDR41 - [13:0] */ + +/* + * R12453 (0x30A5) - Write Sequencer 165 + */ +#define WM8995_WSEQ_DATA41_MASK 0x00FF /* WSEQ_DATA41 - [7:0] */ +#define WM8995_WSEQ_DATA41_SHIFT 0 /* WSEQ_DATA41 - [7:0] */ +#define WM8995_WSEQ_DATA41_WIDTH 8 /* WSEQ_DATA41 - [7:0] */ + +/* + * R12454 (0x30A6) - Write Sequencer 166 + */ +#define WM8995_WSEQ_DATA_WIDTH41_MASK 0x0700 /* WSEQ_DATA_WIDTH41 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH41_SHIFT 8 /* WSEQ_DATA_WIDTH41 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH41_WIDTH 3 /* WSEQ_DATA_WIDTH41 - [10:8] */ +#define WM8995_WSEQ_DATA_START41_MASK 0x000F /* WSEQ_DATA_START41 - [3:0] */ +#define WM8995_WSEQ_DATA_START41_SHIFT 0 /* WSEQ_DATA_START41 - [3:0] */ +#define WM8995_WSEQ_DATA_START41_WIDTH 4 /* WSEQ_DATA_START41 - [3:0] */ + +/* + * R12455 (0x30A7) - Write Sequencer 167 + */ +#define WM8995_WSEQ_EOS41 0x0100 /* WSEQ_EOS41 */ +#define WM8995_WSEQ_EOS41_MASK 0x0100 /* WSEQ_EOS41 */ +#define WM8995_WSEQ_EOS41_SHIFT 8 /* WSEQ_EOS41 */ +#define WM8995_WSEQ_EOS41_WIDTH 1 /* WSEQ_EOS41 */ +#define WM8995_WSEQ_DELAY41_MASK 0x000F /* WSEQ_DELAY41 - [3:0] */ +#define WM8995_WSEQ_DELAY41_SHIFT 0 /* WSEQ_DELAY41 - [3:0] */ +#define WM8995_WSEQ_DELAY41_WIDTH 4 /* WSEQ_DELAY41 - [3:0] */ + +/* + * R12456 (0x30A8) - Write Sequencer 168 + */ +#define WM8995_WSEQ_ADDR42_MASK 0x3FFF /* WSEQ_ADDR42 - [13:0] */ +#define WM8995_WSEQ_ADDR42_SHIFT 0 /* WSEQ_ADDR42 - [13:0] */ +#define WM8995_WSEQ_ADDR42_WIDTH 14 /* WSEQ_ADDR42 - [13:0] */ + +/* + * R12457 (0x30A9) - Write Sequencer 169 + */ +#define WM8995_WSEQ_DATA42_MASK 0x00FF /* WSEQ_DATA42 - [7:0] */ +#define WM8995_WSEQ_DATA42_SHIFT 0 /* WSEQ_DATA42 - [7:0] */ +#define WM8995_WSEQ_DATA42_WIDTH 8 /* WSEQ_DATA42 - [7:0] */ + +/* + * R12458 (0x30AA) - Write Sequencer 170 + */ +#define WM8995_WSEQ_DATA_WIDTH42_MASK 0x0700 /* WSEQ_DATA_WIDTH42 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH42_SHIFT 8 /* WSEQ_DATA_WIDTH42 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH42_WIDTH 3 /* WSEQ_DATA_WIDTH42 - [10:8] */ +#define WM8995_WSEQ_DATA_START42_MASK 0x000F /* WSEQ_DATA_START42 - [3:0] */ +#define WM8995_WSEQ_DATA_START42_SHIFT 0 /* WSEQ_DATA_START42 - [3:0] */ +#define WM8995_WSEQ_DATA_START42_WIDTH 4 /* WSEQ_DATA_START42 - [3:0] */ + +/* + * R12459 (0x30AB) - Write Sequencer 171 + */ +#define WM8995_WSEQ_EOS42 0x0100 /* WSEQ_EOS42 */ +#define WM8995_WSEQ_EOS42_MASK 0x0100 /* WSEQ_EOS42 */ +#define WM8995_WSEQ_EOS42_SHIFT 8 /* WSEQ_EOS42 */ +#define WM8995_WSEQ_EOS42_WIDTH 1 /* WSEQ_EOS42 */ +#define WM8995_WSEQ_DELAY42_MASK 0x000F /* WSEQ_DELAY42 - [3:0] */ +#define WM8995_WSEQ_DELAY42_SHIFT 0 /* WSEQ_DELAY42 - [3:0] */ +#define WM8995_WSEQ_DELAY42_WIDTH 4 /* WSEQ_DELAY42 - [3:0] */ + +/* + * R12460 (0x30AC) - Write Sequencer 172 + */ +#define WM8995_WSEQ_ADDR43_MASK 0x3FFF /* WSEQ_ADDR43 - [13:0] */ +#define WM8995_WSEQ_ADDR43_SHIFT 0 /* WSEQ_ADDR43 - [13:0] */ +#define WM8995_WSEQ_ADDR43_WIDTH 14 /* WSEQ_ADDR43 - [13:0] */ + +/* + * R12461 (0x30AD) - Write Sequencer 173 + */ +#define WM8995_WSEQ_DATA43_MASK 0x00FF /* WSEQ_DATA43 - [7:0] */ +#define WM8995_WSEQ_DATA43_SHIFT 0 /* WSEQ_DATA43 - [7:0] */ +#define WM8995_WSEQ_DATA43_WIDTH 8 /* WSEQ_DATA43 - [7:0] */ + +/* + * R12462 (0x30AE) - Write Sequencer 174 + */ +#define WM8995_WSEQ_DATA_WIDTH43_MASK 0x0700 /* WSEQ_DATA_WIDTH43 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH43_SHIFT 8 /* WSEQ_DATA_WIDTH43 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH43_WIDTH 3 /* WSEQ_DATA_WIDTH43 - [10:8] */ +#define WM8995_WSEQ_DATA_START43_MASK 0x000F /* WSEQ_DATA_START43 - [3:0] */ +#define WM8995_WSEQ_DATA_START43_SHIFT 0 /* WSEQ_DATA_START43 - [3:0] */ +#define WM8995_WSEQ_DATA_START43_WIDTH 4 /* WSEQ_DATA_START43 - [3:0] */ + +/* + * R12463 (0x30AF) - Write Sequencer 175 + */ +#define WM8995_WSEQ_EOS43 0x0100 /* WSEQ_EOS43 */ +#define WM8995_WSEQ_EOS43_MASK 0x0100 /* WSEQ_EOS43 */ +#define WM8995_WSEQ_EOS43_SHIFT 8 /* WSEQ_EOS43 */ +#define WM8995_WSEQ_EOS43_WIDTH 1 /* WSEQ_EOS43 */ +#define WM8995_WSEQ_DELAY43_MASK 0x000F /* WSEQ_DELAY43 - [3:0] */ +#define WM8995_WSEQ_DELAY43_SHIFT 0 /* WSEQ_DELAY43 - [3:0] */ +#define WM8995_WSEQ_DELAY43_WIDTH 4 /* WSEQ_DELAY43 - [3:0] */ + +/* + * R12464 (0x30B0) - Write Sequencer 176 + */ +#define WM8995_WSEQ_ADDR44_MASK 0x3FFF /* WSEQ_ADDR44 - [13:0] */ +#define WM8995_WSEQ_ADDR44_SHIFT 0 /* WSEQ_ADDR44 - [13:0] */ +#define WM8995_WSEQ_ADDR44_WIDTH 14 /* WSEQ_ADDR44 - [13:0] */ + +/* + * R12465 (0x30B1) - Write Sequencer 177 + */ +#define WM8995_WSEQ_DATA44_MASK 0x00FF /* WSEQ_DATA44 - [7:0] */ +#define WM8995_WSEQ_DATA44_SHIFT 0 /* WSEQ_DATA44 - [7:0] */ +#define WM8995_WSEQ_DATA44_WIDTH 8 /* WSEQ_DATA44 - [7:0] */ + +/* + * R12466 (0x30B2) - Write Sequencer 178 + */ +#define WM8995_WSEQ_DATA_WIDTH44_MASK 0x0700 /* WSEQ_DATA_WIDTH44 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH44_SHIFT 8 /* WSEQ_DATA_WIDTH44 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH44_WIDTH 3 /* WSEQ_DATA_WIDTH44 - [10:8] */ +#define WM8995_WSEQ_DATA_START44_MASK 0x000F /* WSEQ_DATA_START44 - [3:0] */ +#define WM8995_WSEQ_DATA_START44_SHIFT 0 /* WSEQ_DATA_START44 - [3:0] */ +#define WM8995_WSEQ_DATA_START44_WIDTH 4 /* WSEQ_DATA_START44 - [3:0] */ + +/* + * R12467 (0x30B3) - Write Sequencer 179 + */ +#define WM8995_WSEQ_EOS44 0x0100 /* WSEQ_EOS44 */ +#define WM8995_WSEQ_EOS44_MASK 0x0100 /* WSEQ_EOS44 */ +#define WM8995_WSEQ_EOS44_SHIFT 8 /* WSEQ_EOS44 */ +#define WM8995_WSEQ_EOS44_WIDTH 1 /* WSEQ_EOS44 */ +#define WM8995_WSEQ_DELAY44_MASK 0x000F /* WSEQ_DELAY44 - [3:0] */ +#define WM8995_WSEQ_DELAY44_SHIFT 0 /* WSEQ_DELAY44 - [3:0] */ +#define WM8995_WSEQ_DELAY44_WIDTH 4 /* WSEQ_DELAY44 - [3:0] */ + +/* + * R12468 (0x30B4) - Write Sequencer 180 + */ +#define WM8995_WSEQ_ADDR45_MASK 0x3FFF /* WSEQ_ADDR45 - [13:0] */ +#define WM8995_WSEQ_ADDR45_SHIFT 0 /* WSEQ_ADDR45 - [13:0] */ +#define WM8995_WSEQ_ADDR45_WIDTH 14 /* WSEQ_ADDR45 - [13:0] */ + +/* + * R12469 (0x30B5) - Write Sequencer 181 + */ +#define WM8995_WSEQ_DATA45_MASK 0x00FF /* WSEQ_DATA45 - [7:0] */ +#define WM8995_WSEQ_DATA45_SHIFT 0 /* WSEQ_DATA45 - [7:0] */ +#define WM8995_WSEQ_DATA45_WIDTH 8 /* WSEQ_DATA45 - [7:0] */ + +/* + * R12470 (0x30B6) - Write Sequencer 182 + */ +#define WM8995_WSEQ_DATA_WIDTH45_MASK 0x0700 /* WSEQ_DATA_WIDTH45 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH45_SHIFT 8 /* WSEQ_DATA_WIDTH45 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH45_WIDTH 3 /* WSEQ_DATA_WIDTH45 - [10:8] */ +#define WM8995_WSEQ_DATA_START45_MASK 0x000F /* WSEQ_DATA_START45 - [3:0] */ +#define WM8995_WSEQ_DATA_START45_SHIFT 0 /* WSEQ_DATA_START45 - [3:0] */ +#define WM8995_WSEQ_DATA_START45_WIDTH 4 /* WSEQ_DATA_START45 - [3:0] */ + +/* + * R12471 (0x30B7) - Write Sequencer 183 + */ +#define WM8995_WSEQ_EOS45 0x0100 /* WSEQ_EOS45 */ +#define WM8995_WSEQ_EOS45_MASK 0x0100 /* WSEQ_EOS45 */ +#define WM8995_WSEQ_EOS45_SHIFT 8 /* WSEQ_EOS45 */ +#define WM8995_WSEQ_EOS45_WIDTH 1 /* WSEQ_EOS45 */ +#define WM8995_WSEQ_DELAY45_MASK 0x000F /* WSEQ_DELAY45 - [3:0] */ +#define WM8995_WSEQ_DELAY45_SHIFT 0 /* WSEQ_DELAY45 - [3:0] */ +#define WM8995_WSEQ_DELAY45_WIDTH 4 /* WSEQ_DELAY45 - [3:0] */ + +/* + * R12472 (0x30B8) - Write Sequencer 184 + */ +#define WM8995_WSEQ_ADDR46_MASK 0x3FFF /* WSEQ_ADDR46 - [13:0] */ +#define WM8995_WSEQ_ADDR46_SHIFT 0 /* WSEQ_ADDR46 - [13:0] */ +#define WM8995_WSEQ_ADDR46_WIDTH 14 /* WSEQ_ADDR46 - [13:0] */ + +/* + * R12473 (0x30B9) - Write Sequencer 185 + */ +#define WM8995_WSEQ_DATA46_MASK 0x00FF /* WSEQ_DATA46 - [7:0] */ +#define WM8995_WSEQ_DATA46_SHIFT 0 /* WSEQ_DATA46 - [7:0] */ +#define WM8995_WSEQ_DATA46_WIDTH 8 /* WSEQ_DATA46 - [7:0] */ + +/* + * R12474 (0x30BA) - Write Sequencer 186 + */ +#define WM8995_WSEQ_DATA_WIDTH46_MASK 0x0700 /* WSEQ_DATA_WIDTH46 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH46_SHIFT 8 /* WSEQ_DATA_WIDTH46 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH46_WIDTH 3 /* WSEQ_DATA_WIDTH46 - [10:8] */ +#define WM8995_WSEQ_DATA_START46_MASK 0x000F /* WSEQ_DATA_START46 - [3:0] */ +#define WM8995_WSEQ_DATA_START46_SHIFT 0 /* WSEQ_DATA_START46 - [3:0] */ +#define WM8995_WSEQ_DATA_START46_WIDTH 4 /* WSEQ_DATA_START46 - [3:0] */ + +/* + * R12475 (0x30BB) - Write Sequencer 187 + */ +#define WM8995_WSEQ_EOS46 0x0100 /* WSEQ_EOS46 */ +#define WM8995_WSEQ_EOS46_MASK 0x0100 /* WSEQ_EOS46 */ +#define WM8995_WSEQ_EOS46_SHIFT 8 /* WSEQ_EOS46 */ +#define WM8995_WSEQ_EOS46_WIDTH 1 /* WSEQ_EOS46 */ +#define WM8995_WSEQ_DELAY46_MASK 0x000F /* WSEQ_DELAY46 - [3:0] */ +#define WM8995_WSEQ_DELAY46_SHIFT 0 /* WSEQ_DELAY46 - [3:0] */ +#define WM8995_WSEQ_DELAY46_WIDTH 4 /* WSEQ_DELAY46 - [3:0] */ + +/* + * R12476 (0x30BC) - Write Sequencer 188 + */ +#define WM8995_WSEQ_ADDR47_MASK 0x3FFF /* WSEQ_ADDR47 - [13:0] */ +#define WM8995_WSEQ_ADDR47_SHIFT 0 /* WSEQ_ADDR47 - [13:0] */ +#define WM8995_WSEQ_ADDR47_WIDTH 14 /* WSEQ_ADDR47 - [13:0] */ + +/* + * R12477 (0x30BD) - Write Sequencer 189 + */ +#define WM8995_WSEQ_DATA47_MASK 0x00FF /* WSEQ_DATA47 - [7:0] */ +#define WM8995_WSEQ_DATA47_SHIFT 0 /* WSEQ_DATA47 - [7:0] */ +#define WM8995_WSEQ_DATA47_WIDTH 8 /* WSEQ_DATA47 - [7:0] */ + +/* + * R12478 (0x30BE) - Write Sequencer 190 + */ +#define WM8995_WSEQ_DATA_WIDTH47_MASK 0x0700 /* WSEQ_DATA_WIDTH47 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH47_SHIFT 8 /* WSEQ_DATA_WIDTH47 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH47_WIDTH 3 /* WSEQ_DATA_WIDTH47 - [10:8] */ +#define WM8995_WSEQ_DATA_START47_MASK 0x000F /* WSEQ_DATA_START47 - [3:0] */ +#define WM8995_WSEQ_DATA_START47_SHIFT 0 /* WSEQ_DATA_START47 - [3:0] */ +#define WM8995_WSEQ_DATA_START47_WIDTH 4 /* WSEQ_DATA_START47 - [3:0] */ + +/* + * R12479 (0x30BF) - Write Sequencer 191 + */ +#define WM8995_WSEQ_EOS47 0x0100 /* WSEQ_EOS47 */ +#define WM8995_WSEQ_EOS47_MASK 0x0100 /* WSEQ_EOS47 */ +#define WM8995_WSEQ_EOS47_SHIFT 8 /* WSEQ_EOS47 */ +#define WM8995_WSEQ_EOS47_WIDTH 1 /* WSEQ_EOS47 */ +#define WM8995_WSEQ_DELAY47_MASK 0x000F /* WSEQ_DELAY47 - [3:0] */ +#define WM8995_WSEQ_DELAY47_SHIFT 0 /* WSEQ_DELAY47 - [3:0] */ +#define WM8995_WSEQ_DELAY47_WIDTH 4 /* WSEQ_DELAY47 - [3:0] */ + +/* + * R12480 (0x30C0) - Write Sequencer 192 + */ +#define WM8995_WSEQ_ADDR48_MASK 0x3FFF /* WSEQ_ADDR48 - [13:0] */ +#define WM8995_WSEQ_ADDR48_SHIFT 0 /* WSEQ_ADDR48 - [13:0] */ +#define WM8995_WSEQ_ADDR48_WIDTH 14 /* WSEQ_ADDR48 - [13:0] */ + +/* + * R12481 (0x30C1) - Write Sequencer 193 + */ +#define WM8995_WSEQ_DATA48_MASK 0x00FF /* WSEQ_DATA48 - [7:0] */ +#define WM8995_WSEQ_DATA48_SHIFT 0 /* WSEQ_DATA48 - [7:0] */ +#define WM8995_WSEQ_DATA48_WIDTH 8 /* WSEQ_DATA48 - [7:0] */ + +/* + * R12482 (0x30C2) - Write Sequencer 194 + */ +#define WM8995_WSEQ_DATA_WIDTH48_MASK 0x0700 /* WSEQ_DATA_WIDTH48 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH48_SHIFT 8 /* WSEQ_DATA_WIDTH48 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH48_WIDTH 3 /* WSEQ_DATA_WIDTH48 - [10:8] */ +#define WM8995_WSEQ_DATA_START48_MASK 0x000F /* WSEQ_DATA_START48 - [3:0] */ +#define WM8995_WSEQ_DATA_START48_SHIFT 0 /* WSEQ_DATA_START48 - [3:0] */ +#define WM8995_WSEQ_DATA_START48_WIDTH 4 /* WSEQ_DATA_START48 - [3:0] */ + +/* + * R12483 (0x30C3) - Write Sequencer 195 + */ +#define WM8995_WSEQ_EOS48 0x0100 /* WSEQ_EOS48 */ +#define WM8995_WSEQ_EOS48_MASK 0x0100 /* WSEQ_EOS48 */ +#define WM8995_WSEQ_EOS48_SHIFT 8 /* WSEQ_EOS48 */ +#define WM8995_WSEQ_EOS48_WIDTH 1 /* WSEQ_EOS48 */ +#define WM8995_WSEQ_DELAY48_MASK 0x000F /* WSEQ_DELAY48 - [3:0] */ +#define WM8995_WSEQ_DELAY48_SHIFT 0 /* WSEQ_DELAY48 - [3:0] */ +#define WM8995_WSEQ_DELAY48_WIDTH 4 /* WSEQ_DELAY48 - [3:0] */ + +/* + * R12484 (0x30C4) - Write Sequencer 196 + */ +#define WM8995_WSEQ_ADDR49_MASK 0x3FFF /* WSEQ_ADDR49 - [13:0] */ +#define WM8995_WSEQ_ADDR49_SHIFT 0 /* WSEQ_ADDR49 - [13:0] */ +#define WM8995_WSEQ_ADDR49_WIDTH 14 /* WSEQ_ADDR49 - [13:0] */ + +/* + * R12485 (0x30C5) - Write Sequencer 197 + */ +#define WM8995_WSEQ_DATA49_MASK 0x00FF /* WSEQ_DATA49 - [7:0] */ +#define WM8995_WSEQ_DATA49_SHIFT 0 /* WSEQ_DATA49 - [7:0] */ +#define WM8995_WSEQ_DATA49_WIDTH 8 /* WSEQ_DATA49 - [7:0] */ + +/* + * R12486 (0x30C6) - Write Sequencer 198 + */ +#define WM8995_WSEQ_DATA_WIDTH49_MASK 0x0700 /* WSEQ_DATA_WIDTH49 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH49_SHIFT 8 /* WSEQ_DATA_WIDTH49 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH49_WIDTH 3 /* WSEQ_DATA_WIDTH49 - [10:8] */ +#define WM8995_WSEQ_DATA_START49_MASK 0x000F /* WSEQ_DATA_START49 - [3:0] */ +#define WM8995_WSEQ_DATA_START49_SHIFT 0 /* WSEQ_DATA_START49 - [3:0] */ +#define WM8995_WSEQ_DATA_START49_WIDTH 4 /* WSEQ_DATA_START49 - [3:0] */ + +/* + * R12487 (0x30C7) - Write Sequencer 199 + */ +#define WM8995_WSEQ_EOS49 0x0100 /* WSEQ_EOS49 */ +#define WM8995_WSEQ_EOS49_MASK 0x0100 /* WSEQ_EOS49 */ +#define WM8995_WSEQ_EOS49_SHIFT 8 /* WSEQ_EOS49 */ +#define WM8995_WSEQ_EOS49_WIDTH 1 /* WSEQ_EOS49 */ +#define WM8995_WSEQ_DELAY49_MASK 0x000F /* WSEQ_DELAY49 - [3:0] */ +#define WM8995_WSEQ_DELAY49_SHIFT 0 /* WSEQ_DELAY49 - [3:0] */ +#define WM8995_WSEQ_DELAY49_WIDTH 4 /* WSEQ_DELAY49 - [3:0] */ + +/* + * R12488 (0x30C8) - Write Sequencer 200 + */ +#define WM8995_WSEQ_ADDR50_MASK 0x3FFF /* WSEQ_ADDR50 - [13:0] */ +#define WM8995_WSEQ_ADDR50_SHIFT 0 /* WSEQ_ADDR50 - [13:0] */ +#define WM8995_WSEQ_ADDR50_WIDTH 14 /* WSEQ_ADDR50 - [13:0] */ + +/* + * R12489 (0x30C9) - Write Sequencer 201 + */ +#define WM8995_WSEQ_DATA50_MASK 0x00FF /* WSEQ_DATA50 - [7:0] */ +#define WM8995_WSEQ_DATA50_SHIFT 0 /* WSEQ_DATA50 - [7:0] */ +#define WM8995_WSEQ_DATA50_WIDTH 8 /* WSEQ_DATA50 - [7:0] */ + +/* + * R12490 (0x30CA) - Write Sequencer 202 + */ +#define WM8995_WSEQ_DATA_WIDTH50_MASK 0x0700 /* WSEQ_DATA_WIDTH50 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH50_SHIFT 8 /* WSEQ_DATA_WIDTH50 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH50_WIDTH 3 /* WSEQ_DATA_WIDTH50 - [10:8] */ +#define WM8995_WSEQ_DATA_START50_MASK 0x000F /* WSEQ_DATA_START50 - [3:0] */ +#define WM8995_WSEQ_DATA_START50_SHIFT 0 /* WSEQ_DATA_START50 - [3:0] */ +#define WM8995_WSEQ_DATA_START50_WIDTH 4 /* WSEQ_DATA_START50 - [3:0] */ + +/* + * R12491 (0x30CB) - Write Sequencer 203 + */ +#define WM8995_WSEQ_EOS50 0x0100 /* WSEQ_EOS50 */ +#define WM8995_WSEQ_EOS50_MASK 0x0100 /* WSEQ_EOS50 */ +#define WM8995_WSEQ_EOS50_SHIFT 8 /* WSEQ_EOS50 */ +#define WM8995_WSEQ_EOS50_WIDTH 1 /* WSEQ_EOS50 */ +#define WM8995_WSEQ_DELAY50_MASK 0x000F /* WSEQ_DELAY50 - [3:0] */ +#define WM8995_WSEQ_DELAY50_SHIFT 0 /* WSEQ_DELAY50 - [3:0] */ +#define WM8995_WSEQ_DELAY50_WIDTH 4 /* WSEQ_DELAY50 - [3:0] */ + +/* + * R12492 (0x30CC) - Write Sequencer 204 + */ +#define WM8995_WSEQ_ADDR51_MASK 0x3FFF /* WSEQ_ADDR51 - [13:0] */ +#define WM8995_WSEQ_ADDR51_SHIFT 0 /* WSEQ_ADDR51 - [13:0] */ +#define WM8995_WSEQ_ADDR51_WIDTH 14 /* WSEQ_ADDR51 - [13:0] */ + +/* + * R12493 (0x30CD) - Write Sequencer 205 + */ +#define WM8995_WSEQ_DATA51_MASK 0x00FF /* WSEQ_DATA51 - [7:0] */ +#define WM8995_WSEQ_DATA51_SHIFT 0 /* WSEQ_DATA51 - [7:0] */ +#define WM8995_WSEQ_DATA51_WIDTH 8 /* WSEQ_DATA51 - [7:0] */ + +/* + * R12494 (0x30CE) - Write Sequencer 206 + */ +#define WM8995_WSEQ_DATA_WIDTH51_MASK 0x0700 /* WSEQ_DATA_WIDTH51 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH51_SHIFT 8 /* WSEQ_DATA_WIDTH51 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH51_WIDTH 3 /* WSEQ_DATA_WIDTH51 - [10:8] */ +#define WM8995_WSEQ_DATA_START51_MASK 0x000F /* WSEQ_DATA_START51 - [3:0] */ +#define WM8995_WSEQ_DATA_START51_SHIFT 0 /* WSEQ_DATA_START51 - [3:0] */ +#define WM8995_WSEQ_DATA_START51_WIDTH 4 /* WSEQ_DATA_START51 - [3:0] */ + +/* + * R12495 (0x30CF) - Write Sequencer 207 + */ +#define WM8995_WSEQ_EOS51 0x0100 /* WSEQ_EOS51 */ +#define WM8995_WSEQ_EOS51_MASK 0x0100 /* WSEQ_EOS51 */ +#define WM8995_WSEQ_EOS51_SHIFT 8 /* WSEQ_EOS51 */ +#define WM8995_WSEQ_EOS51_WIDTH 1 /* WSEQ_EOS51 */ +#define WM8995_WSEQ_DELAY51_MASK 0x000F /* WSEQ_DELAY51 - [3:0] */ +#define WM8995_WSEQ_DELAY51_SHIFT 0 /* WSEQ_DELAY51 - [3:0] */ +#define WM8995_WSEQ_DELAY51_WIDTH 4 /* WSEQ_DELAY51 - [3:0] */ + +/* + * R12496 (0x30D0) - Write Sequencer 208 + */ +#define WM8995_WSEQ_ADDR52_MASK 0x3FFF /* WSEQ_ADDR52 - [13:0] */ +#define WM8995_WSEQ_ADDR52_SHIFT 0 /* WSEQ_ADDR52 - [13:0] */ +#define WM8995_WSEQ_ADDR52_WIDTH 14 /* WSEQ_ADDR52 - [13:0] */ + +/* + * R12497 (0x30D1) - Write Sequencer 209 + */ +#define WM8995_WSEQ_DATA52_MASK 0x00FF /* WSEQ_DATA52 - [7:0] */ +#define WM8995_WSEQ_DATA52_SHIFT 0 /* WSEQ_DATA52 - [7:0] */ +#define WM8995_WSEQ_DATA52_WIDTH 8 /* WSEQ_DATA52 - [7:0] */ + +/* + * R12498 (0x30D2) - Write Sequencer 210 + */ +#define WM8995_WSEQ_DATA_WIDTH52_MASK 0x0700 /* WSEQ_DATA_WIDTH52 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH52_SHIFT 8 /* WSEQ_DATA_WIDTH52 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH52_WIDTH 3 /* WSEQ_DATA_WIDTH52 - [10:8] */ +#define WM8995_WSEQ_DATA_START52_MASK 0x000F /* WSEQ_DATA_START52 - [3:0] */ +#define WM8995_WSEQ_DATA_START52_SHIFT 0 /* WSEQ_DATA_START52 - [3:0] */ +#define WM8995_WSEQ_DATA_START52_WIDTH 4 /* WSEQ_DATA_START52 - [3:0] */ + +/* + * R12499 (0x30D3) - Write Sequencer 211 + */ +#define WM8995_WSEQ_EOS52 0x0100 /* WSEQ_EOS52 */ +#define WM8995_WSEQ_EOS52_MASK 0x0100 /* WSEQ_EOS52 */ +#define WM8995_WSEQ_EOS52_SHIFT 8 /* WSEQ_EOS52 */ +#define WM8995_WSEQ_EOS52_WIDTH 1 /* WSEQ_EOS52 */ +#define WM8995_WSEQ_DELAY52_MASK 0x000F /* WSEQ_DELAY52 - [3:0] */ +#define WM8995_WSEQ_DELAY52_SHIFT 0 /* WSEQ_DELAY52 - [3:0] */ +#define WM8995_WSEQ_DELAY52_WIDTH 4 /* WSEQ_DELAY52 - [3:0] */ + +/* + * R12500 (0x30D4) - Write Sequencer 212 + */ +#define WM8995_WSEQ_ADDR53_MASK 0x3FFF /* WSEQ_ADDR53 - [13:0] */ +#define WM8995_WSEQ_ADDR53_SHIFT 0 /* WSEQ_ADDR53 - [13:0] */ +#define WM8995_WSEQ_ADDR53_WIDTH 14 /* WSEQ_ADDR53 - [13:0] */ + +/* + * R12501 (0x30D5) - Write Sequencer 213 + */ +#define WM8995_WSEQ_DATA53_MASK 0x00FF /* WSEQ_DATA53 - [7:0] */ +#define WM8995_WSEQ_DATA53_SHIFT 0 /* WSEQ_DATA53 - [7:0] */ +#define WM8995_WSEQ_DATA53_WIDTH 8 /* WSEQ_DATA53 - [7:0] */ + +/* + * R12502 (0x30D6) - Write Sequencer 214 + */ +#define WM8995_WSEQ_DATA_WIDTH53_MASK 0x0700 /* WSEQ_DATA_WIDTH53 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH53_SHIFT 8 /* WSEQ_DATA_WIDTH53 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH53_WIDTH 3 /* WSEQ_DATA_WIDTH53 - [10:8] */ +#define WM8995_WSEQ_DATA_START53_MASK 0x000F /* WSEQ_DATA_START53 - [3:0] */ +#define WM8995_WSEQ_DATA_START53_SHIFT 0 /* WSEQ_DATA_START53 - [3:0] */ +#define WM8995_WSEQ_DATA_START53_WIDTH 4 /* WSEQ_DATA_START53 - [3:0] */ + +/* + * R12503 (0x30D7) - Write Sequencer 215 + */ +#define WM8995_WSEQ_EOS53 0x0100 /* WSEQ_EOS53 */ +#define WM8995_WSEQ_EOS53_MASK 0x0100 /* WSEQ_EOS53 */ +#define WM8995_WSEQ_EOS53_SHIFT 8 /* WSEQ_EOS53 */ +#define WM8995_WSEQ_EOS53_WIDTH 1 /* WSEQ_EOS53 */ +#define WM8995_WSEQ_DELAY53_MASK 0x000F /* WSEQ_DELAY53 - [3:0] */ +#define WM8995_WSEQ_DELAY53_SHIFT 0 /* WSEQ_DELAY53 - [3:0] */ +#define WM8995_WSEQ_DELAY53_WIDTH 4 /* WSEQ_DELAY53 - [3:0] */ + +/* + * R12504 (0x30D8) - Write Sequencer 216 + */ +#define WM8995_WSEQ_ADDR54_MASK 0x3FFF /* WSEQ_ADDR54 - [13:0] */ +#define WM8995_WSEQ_ADDR54_SHIFT 0 /* WSEQ_ADDR54 - [13:0] */ +#define WM8995_WSEQ_ADDR54_WIDTH 14 /* WSEQ_ADDR54 - [13:0] */ + +/* + * R12505 (0x30D9) - Write Sequencer 217 + */ +#define WM8995_WSEQ_DATA54_MASK 0x00FF /* WSEQ_DATA54 - [7:0] */ +#define WM8995_WSEQ_DATA54_SHIFT 0 /* WSEQ_DATA54 - [7:0] */ +#define WM8995_WSEQ_DATA54_WIDTH 8 /* WSEQ_DATA54 - [7:0] */ + +/* + * R12506 (0x30DA) - Write Sequencer 218 + */ +#define WM8995_WSEQ_DATA_WIDTH54_MASK 0x0700 /* WSEQ_DATA_WIDTH54 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH54_SHIFT 8 /* WSEQ_DATA_WIDTH54 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH54_WIDTH 3 /* WSEQ_DATA_WIDTH54 - [10:8] */ +#define WM8995_WSEQ_DATA_START54_MASK 0x000F /* WSEQ_DATA_START54 - [3:0] */ +#define WM8995_WSEQ_DATA_START54_SHIFT 0 /* WSEQ_DATA_START54 - [3:0] */ +#define WM8995_WSEQ_DATA_START54_WIDTH 4 /* WSEQ_DATA_START54 - [3:0] */ + +/* + * R12507 (0x30DB) - Write Sequencer 219 + */ +#define WM8995_WSEQ_EOS54 0x0100 /* WSEQ_EOS54 */ +#define WM8995_WSEQ_EOS54_MASK 0x0100 /* WSEQ_EOS54 */ +#define WM8995_WSEQ_EOS54_SHIFT 8 /* WSEQ_EOS54 */ +#define WM8995_WSEQ_EOS54_WIDTH 1 /* WSEQ_EOS54 */ +#define WM8995_WSEQ_DELAY54_MASK 0x000F /* WSEQ_DELAY54 - [3:0] */ +#define WM8995_WSEQ_DELAY54_SHIFT 0 /* WSEQ_DELAY54 - [3:0] */ +#define WM8995_WSEQ_DELAY54_WIDTH 4 /* WSEQ_DELAY54 - [3:0] */ + +/* + * R12508 (0x30DC) - Write Sequencer 220 + */ +#define WM8995_WSEQ_ADDR55_MASK 0x3FFF /* WSEQ_ADDR55 - [13:0] */ +#define WM8995_WSEQ_ADDR55_SHIFT 0 /* WSEQ_ADDR55 - [13:0] */ +#define WM8995_WSEQ_ADDR55_WIDTH 14 /* WSEQ_ADDR55 - [13:0] */ + +/* + * R12509 (0x30DD) - Write Sequencer 221 + */ +#define WM8995_WSEQ_DATA55_MASK 0x00FF /* WSEQ_DATA55 - [7:0] */ +#define WM8995_WSEQ_DATA55_SHIFT 0 /* WSEQ_DATA55 - [7:0] */ +#define WM8995_WSEQ_DATA55_WIDTH 8 /* WSEQ_DATA55 - [7:0] */ + +/* + * R12510 (0x30DE) - Write Sequencer 222 + */ +#define WM8995_WSEQ_DATA_WIDTH55_MASK 0x0700 /* WSEQ_DATA_WIDTH55 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH55_SHIFT 8 /* WSEQ_DATA_WIDTH55 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH55_WIDTH 3 /* WSEQ_DATA_WIDTH55 - [10:8] */ +#define WM8995_WSEQ_DATA_START55_MASK 0x000F /* WSEQ_DATA_START55 - [3:0] */ +#define WM8995_WSEQ_DATA_START55_SHIFT 0 /* WSEQ_DATA_START55 - [3:0] */ +#define WM8995_WSEQ_DATA_START55_WIDTH 4 /* WSEQ_DATA_START55 - [3:0] */ + +/* + * R12511 (0x30DF) - Write Sequencer 223 + */ +#define WM8995_WSEQ_EOS55 0x0100 /* WSEQ_EOS55 */ +#define WM8995_WSEQ_EOS55_MASK 0x0100 /* WSEQ_EOS55 */ +#define WM8995_WSEQ_EOS55_SHIFT 8 /* WSEQ_EOS55 */ +#define WM8995_WSEQ_EOS55_WIDTH 1 /* WSEQ_EOS55 */ +#define WM8995_WSEQ_DELAY55_MASK 0x000F /* WSEQ_DELAY55 - [3:0] */ +#define WM8995_WSEQ_DELAY55_SHIFT 0 /* WSEQ_DELAY55 - [3:0] */ +#define WM8995_WSEQ_DELAY55_WIDTH 4 /* WSEQ_DELAY55 - [3:0] */ + +/* + * R12512 (0x30E0) - Write Sequencer 224 + */ +#define WM8995_WSEQ_ADDR56_MASK 0x3FFF /* WSEQ_ADDR56 - [13:0] */ +#define WM8995_WSEQ_ADDR56_SHIFT 0 /* WSEQ_ADDR56 - [13:0] */ +#define WM8995_WSEQ_ADDR56_WIDTH 14 /* WSEQ_ADDR56 - [13:0] */ + +/* + * R12513 (0x30E1) - Write Sequencer 225 + */ +#define WM8995_WSEQ_DATA56_MASK 0x00FF /* WSEQ_DATA56 - [7:0] */ +#define WM8995_WSEQ_DATA56_SHIFT 0 /* WSEQ_DATA56 - [7:0] */ +#define WM8995_WSEQ_DATA56_WIDTH 8 /* WSEQ_DATA56 - [7:0] */ + +/* + * R12514 (0x30E2) - Write Sequencer 226 + */ +#define WM8995_WSEQ_DATA_WIDTH56_MASK 0x0700 /* WSEQ_DATA_WIDTH56 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH56_SHIFT 8 /* WSEQ_DATA_WIDTH56 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH56_WIDTH 3 /* WSEQ_DATA_WIDTH56 - [10:8] */ +#define WM8995_WSEQ_DATA_START56_MASK 0x000F /* WSEQ_DATA_START56 - [3:0] */ +#define WM8995_WSEQ_DATA_START56_SHIFT 0 /* WSEQ_DATA_START56 - [3:0] */ +#define WM8995_WSEQ_DATA_START56_WIDTH 4 /* WSEQ_DATA_START56 - [3:0] */ + +/* + * R12515 (0x30E3) - Write Sequencer 227 + */ +#define WM8995_WSEQ_EOS56 0x0100 /* WSEQ_EOS56 */ +#define WM8995_WSEQ_EOS56_MASK 0x0100 /* WSEQ_EOS56 */ +#define WM8995_WSEQ_EOS56_SHIFT 8 /* WSEQ_EOS56 */ +#define WM8995_WSEQ_EOS56_WIDTH 1 /* WSEQ_EOS56 */ +#define WM8995_WSEQ_DELAY56_MASK 0x000F /* WSEQ_DELAY56 - [3:0] */ +#define WM8995_WSEQ_DELAY56_SHIFT 0 /* WSEQ_DELAY56 - [3:0] */ +#define WM8995_WSEQ_DELAY56_WIDTH 4 /* WSEQ_DELAY56 - [3:0] */ + +/* + * R12516 (0x30E4) - Write Sequencer 228 + */ +#define WM8995_WSEQ_ADDR57_MASK 0x3FFF /* WSEQ_ADDR57 - [13:0] */ +#define WM8995_WSEQ_ADDR57_SHIFT 0 /* WSEQ_ADDR57 - [13:0] */ +#define WM8995_WSEQ_ADDR57_WIDTH 14 /* WSEQ_ADDR57 - [13:0] */ + +/* + * R12517 (0x30E5) - Write Sequencer 229 + */ +#define WM8995_WSEQ_DATA57_MASK 0x00FF /* WSEQ_DATA57 - [7:0] */ +#define WM8995_WSEQ_DATA57_SHIFT 0 /* WSEQ_DATA57 - [7:0] */ +#define WM8995_WSEQ_DATA57_WIDTH 8 /* WSEQ_DATA57 - [7:0] */ + +/* + * R12518 (0x30E6) - Write Sequencer 230 + */ +#define WM8995_WSEQ_DATA_WIDTH57_MASK 0x0700 /* WSEQ_DATA_WIDTH57 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH57_SHIFT 8 /* WSEQ_DATA_WIDTH57 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH57_WIDTH 3 /* WSEQ_DATA_WIDTH57 - [10:8] */ +#define WM8995_WSEQ_DATA_START57_MASK 0x000F /* WSEQ_DATA_START57 - [3:0] */ +#define WM8995_WSEQ_DATA_START57_SHIFT 0 /* WSEQ_DATA_START57 - [3:0] */ +#define WM8995_WSEQ_DATA_START57_WIDTH 4 /* WSEQ_DATA_START57 - [3:0] */ + +/* + * R12519 (0x30E7) - Write Sequencer 231 + */ +#define WM8995_WSEQ_EOS57 0x0100 /* WSEQ_EOS57 */ +#define WM8995_WSEQ_EOS57_MASK 0x0100 /* WSEQ_EOS57 */ +#define WM8995_WSEQ_EOS57_SHIFT 8 /* WSEQ_EOS57 */ +#define WM8995_WSEQ_EOS57_WIDTH 1 /* WSEQ_EOS57 */ +#define WM8995_WSEQ_DELAY57_MASK 0x000F /* WSEQ_DELAY57 - [3:0] */ +#define WM8995_WSEQ_DELAY57_SHIFT 0 /* WSEQ_DELAY57 - [3:0] */ +#define WM8995_WSEQ_DELAY57_WIDTH 4 /* WSEQ_DELAY57 - [3:0] */ + +/* + * R12520 (0x30E8) - Write Sequencer 232 + */ +#define WM8995_WSEQ_ADDR58_MASK 0x3FFF /* WSEQ_ADDR58 - [13:0] */ +#define WM8995_WSEQ_ADDR58_SHIFT 0 /* WSEQ_ADDR58 - [13:0] */ +#define WM8995_WSEQ_ADDR58_WIDTH 14 /* WSEQ_ADDR58 - [13:0] */ + +/* + * R12521 (0x30E9) - Write Sequencer 233 + */ +#define WM8995_WSEQ_DATA58_MASK 0x00FF /* WSEQ_DATA58 - [7:0] */ +#define WM8995_WSEQ_DATA58_SHIFT 0 /* WSEQ_DATA58 - [7:0] */ +#define WM8995_WSEQ_DATA58_WIDTH 8 /* WSEQ_DATA58 - [7:0] */ + +/* + * R12522 (0x30EA) - Write Sequencer 234 + */ +#define WM8995_WSEQ_DATA_WIDTH58_MASK 0x0700 /* WSEQ_DATA_WIDTH58 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH58_SHIFT 8 /* WSEQ_DATA_WIDTH58 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH58_WIDTH 3 /* WSEQ_DATA_WIDTH58 - [10:8] */ +#define WM8995_WSEQ_DATA_START58_MASK 0x000F /* WSEQ_DATA_START58 - [3:0] */ +#define WM8995_WSEQ_DATA_START58_SHIFT 0 /* WSEQ_DATA_START58 - [3:0] */ +#define WM8995_WSEQ_DATA_START58_WIDTH 4 /* WSEQ_DATA_START58 - [3:0] */ + +/* + * R12523 (0x30EB) - Write Sequencer 235 + */ +#define WM8995_WSEQ_EOS58 0x0100 /* WSEQ_EOS58 */ +#define WM8995_WSEQ_EOS58_MASK 0x0100 /* WSEQ_EOS58 */ +#define WM8995_WSEQ_EOS58_SHIFT 8 /* WSEQ_EOS58 */ +#define WM8995_WSEQ_EOS58_WIDTH 1 /* WSEQ_EOS58 */ +#define WM8995_WSEQ_DELAY58_MASK 0x000F /* WSEQ_DELAY58 - [3:0] */ +#define WM8995_WSEQ_DELAY58_SHIFT 0 /* WSEQ_DELAY58 - [3:0] */ +#define WM8995_WSEQ_DELAY58_WIDTH 4 /* WSEQ_DELAY58 - [3:0] */ + +/* + * R12524 (0x30EC) - Write Sequencer 236 + */ +#define WM8995_WSEQ_ADDR59_MASK 0x3FFF /* WSEQ_ADDR59 - [13:0] */ +#define WM8995_WSEQ_ADDR59_SHIFT 0 /* WSEQ_ADDR59 - [13:0] */ +#define WM8995_WSEQ_ADDR59_WIDTH 14 /* WSEQ_ADDR59 - [13:0] */ + +/* + * R12525 (0x30ED) - Write Sequencer 237 + */ +#define WM8995_WSEQ_DATA59_MASK 0x00FF /* WSEQ_DATA59 - [7:0] */ +#define WM8995_WSEQ_DATA59_SHIFT 0 /* WSEQ_DATA59 - [7:0] */ +#define WM8995_WSEQ_DATA59_WIDTH 8 /* WSEQ_DATA59 - [7:0] */ + +/* + * R12526 (0x30EE) - Write Sequencer 238 + */ +#define WM8995_WSEQ_DATA_WIDTH59_MASK 0x0700 /* WSEQ_DATA_WIDTH59 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH59_SHIFT 8 /* WSEQ_DATA_WIDTH59 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH59_WIDTH 3 /* WSEQ_DATA_WIDTH59 - [10:8] */ +#define WM8995_WSEQ_DATA_START59_MASK 0x000F /* WSEQ_DATA_START59 - [3:0] */ +#define WM8995_WSEQ_DATA_START59_SHIFT 0 /* WSEQ_DATA_START59 - [3:0] */ +#define WM8995_WSEQ_DATA_START59_WIDTH 4 /* WSEQ_DATA_START59 - [3:0] */ + +/* + * R12527 (0x30EF) - Write Sequencer 239 + */ +#define WM8995_WSEQ_EOS59 0x0100 /* WSEQ_EOS59 */ +#define WM8995_WSEQ_EOS59_MASK 0x0100 /* WSEQ_EOS59 */ +#define WM8995_WSEQ_EOS59_SHIFT 8 /* WSEQ_EOS59 */ +#define WM8995_WSEQ_EOS59_WIDTH 1 /* WSEQ_EOS59 */ +#define WM8995_WSEQ_DELAY59_MASK 0x000F /* WSEQ_DELAY59 - [3:0] */ +#define WM8995_WSEQ_DELAY59_SHIFT 0 /* WSEQ_DELAY59 - [3:0] */ +#define WM8995_WSEQ_DELAY59_WIDTH 4 /* WSEQ_DELAY59 - [3:0] */ + +/* + * R12528 (0x30F0) - Write Sequencer 240 + */ +#define WM8995_WSEQ_ADDR60_MASK 0x3FFF /* WSEQ_ADDR60 - [13:0] */ +#define WM8995_WSEQ_ADDR60_SHIFT 0 /* WSEQ_ADDR60 - [13:0] */ +#define WM8995_WSEQ_ADDR60_WIDTH 14 /* WSEQ_ADDR60 - [13:0] */ + +/* + * R12529 (0x30F1) - Write Sequencer 241 + */ +#define WM8995_WSEQ_DATA60_MASK 0x00FF /* WSEQ_DATA60 - [7:0] */ +#define WM8995_WSEQ_DATA60_SHIFT 0 /* WSEQ_DATA60 - [7:0] */ +#define WM8995_WSEQ_DATA60_WIDTH 8 /* WSEQ_DATA60 - [7:0] */ + +/* + * R12530 (0x30F2) - Write Sequencer 242 + */ +#define WM8995_WSEQ_DATA_WIDTH60_MASK 0x0700 /* WSEQ_DATA_WIDTH60 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH60_SHIFT 8 /* WSEQ_DATA_WIDTH60 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH60_WIDTH 3 /* WSEQ_DATA_WIDTH60 - [10:8] */ +#define WM8995_WSEQ_DATA_START60_MASK 0x000F /* WSEQ_DATA_START60 - [3:0] */ +#define WM8995_WSEQ_DATA_START60_SHIFT 0 /* WSEQ_DATA_START60 - [3:0] */ +#define WM8995_WSEQ_DATA_START60_WIDTH 4 /* WSEQ_DATA_START60 - [3:0] */ + +/* + * R12531 (0x30F3) - Write Sequencer 243 + */ +#define WM8995_WSEQ_EOS60 0x0100 /* WSEQ_EOS60 */ +#define WM8995_WSEQ_EOS60_MASK 0x0100 /* WSEQ_EOS60 */ +#define WM8995_WSEQ_EOS60_SHIFT 8 /* WSEQ_EOS60 */ +#define WM8995_WSEQ_EOS60_WIDTH 1 /* WSEQ_EOS60 */ +#define WM8995_WSEQ_DELAY60_MASK 0x000F /* WSEQ_DELAY60 - [3:0] */ +#define WM8995_WSEQ_DELAY60_SHIFT 0 /* WSEQ_DELAY60 - [3:0] */ +#define WM8995_WSEQ_DELAY60_WIDTH 4 /* WSEQ_DELAY60 - [3:0] */ + +/* + * R12532 (0x30F4) - Write Sequencer 244 + */ +#define WM8995_WSEQ_ADDR61_MASK 0x3FFF /* WSEQ_ADDR61 - [13:0] */ +#define WM8995_WSEQ_ADDR61_SHIFT 0 /* WSEQ_ADDR61 - [13:0] */ +#define WM8995_WSEQ_ADDR61_WIDTH 14 /* WSEQ_ADDR61 - [13:0] */ + +/* + * R12533 (0x30F5) - Write Sequencer 245 + */ +#define WM8995_WSEQ_DATA61_MASK 0x00FF /* WSEQ_DATA61 - [7:0] */ +#define WM8995_WSEQ_DATA61_SHIFT 0 /* WSEQ_DATA61 - [7:0] */ +#define WM8995_WSEQ_DATA61_WIDTH 8 /* WSEQ_DATA61 - [7:0] */ + +/* + * R12534 (0x30F6) - Write Sequencer 246 + */ +#define WM8995_WSEQ_DATA_WIDTH61_MASK 0x0700 /* WSEQ_DATA_WIDTH61 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH61_SHIFT 8 /* WSEQ_DATA_WIDTH61 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH61_WIDTH 3 /* WSEQ_DATA_WIDTH61 - [10:8] */ +#define WM8995_WSEQ_DATA_START61_MASK 0x000F /* WSEQ_DATA_START61 - [3:0] */ +#define WM8995_WSEQ_DATA_START61_SHIFT 0 /* WSEQ_DATA_START61 - [3:0] */ +#define WM8995_WSEQ_DATA_START61_WIDTH 4 /* WSEQ_DATA_START61 - [3:0] */ + +/* + * R12535 (0x30F7) - Write Sequencer 247 + */ +#define WM8995_WSEQ_EOS61 0x0100 /* WSEQ_EOS61 */ +#define WM8995_WSEQ_EOS61_MASK 0x0100 /* WSEQ_EOS61 */ +#define WM8995_WSEQ_EOS61_SHIFT 8 /* WSEQ_EOS61 */ +#define WM8995_WSEQ_EOS61_WIDTH 1 /* WSEQ_EOS61 */ +#define WM8995_WSEQ_DELAY61_MASK 0x000F /* WSEQ_DELAY61 - [3:0] */ +#define WM8995_WSEQ_DELAY61_SHIFT 0 /* WSEQ_DELAY61 - [3:0] */ +#define WM8995_WSEQ_DELAY61_WIDTH 4 /* WSEQ_DELAY61 - [3:0] */ + +/* + * R12536 (0x30F8) - Write Sequencer 248 + */ +#define WM8995_WSEQ_ADDR62_MASK 0x3FFF /* WSEQ_ADDR62 - [13:0] */ +#define WM8995_WSEQ_ADDR62_SHIFT 0 /* WSEQ_ADDR62 - [13:0] */ +#define WM8995_WSEQ_ADDR62_WIDTH 14 /* WSEQ_ADDR62 - [13:0] */ + +/* + * R12537 (0x30F9) - Write Sequencer 249 + */ +#define WM8995_WSEQ_DATA62_MASK 0x00FF /* WSEQ_DATA62 - [7:0] */ +#define WM8995_WSEQ_DATA62_SHIFT 0 /* WSEQ_DATA62 - [7:0] */ +#define WM8995_WSEQ_DATA62_WIDTH 8 /* WSEQ_DATA62 - [7:0] */ + +/* + * R12538 (0x30FA) - Write Sequencer 250 + */ +#define WM8995_WSEQ_DATA_WIDTH62_MASK 0x0700 /* WSEQ_DATA_WIDTH62 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH62_SHIFT 8 /* WSEQ_DATA_WIDTH62 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH62_WIDTH 3 /* WSEQ_DATA_WIDTH62 - [10:8] */ +#define WM8995_WSEQ_DATA_START62_MASK 0x000F /* WSEQ_DATA_START62 - [3:0] */ +#define WM8995_WSEQ_DATA_START62_SHIFT 0 /* WSEQ_DATA_START62 - [3:0] */ +#define WM8995_WSEQ_DATA_START62_WIDTH 4 /* WSEQ_DATA_START62 - [3:0] */ + +/* + * R12539 (0x30FB) - Write Sequencer 251 + */ +#define WM8995_WSEQ_EOS62 0x0100 /* WSEQ_EOS62 */ +#define WM8995_WSEQ_EOS62_MASK 0x0100 /* WSEQ_EOS62 */ +#define WM8995_WSEQ_EOS62_SHIFT 8 /* WSEQ_EOS62 */ +#define WM8995_WSEQ_EOS62_WIDTH 1 /* WSEQ_EOS62 */ +#define WM8995_WSEQ_DELAY62_MASK 0x000F /* WSEQ_DELAY62 - [3:0] */ +#define WM8995_WSEQ_DELAY62_SHIFT 0 /* WSEQ_DELAY62 - [3:0] */ +#define WM8995_WSEQ_DELAY62_WIDTH 4 /* WSEQ_DELAY62 - [3:0] */ + +/* + * R12540 (0x30FC) - Write Sequencer 252 + */ +#define WM8995_WSEQ_ADDR63_MASK 0x3FFF /* WSEQ_ADDR63 - [13:0] */ +#define WM8995_WSEQ_ADDR63_SHIFT 0 /* WSEQ_ADDR63 - [13:0] */ +#define WM8995_WSEQ_ADDR63_WIDTH 14 /* WSEQ_ADDR63 - [13:0] */ + +/* + * R12541 (0x30FD) - Write Sequencer 253 + */ +#define WM8995_WSEQ_DATA63_MASK 0x00FF /* WSEQ_DATA63 - [7:0] */ +#define WM8995_WSEQ_DATA63_SHIFT 0 /* WSEQ_DATA63 - [7:0] */ +#define WM8995_WSEQ_DATA63_WIDTH 8 /* WSEQ_DATA63 - [7:0] */ + +/* + * R12542 (0x30FE) - Write Sequencer 254 + */ +#define WM8995_WSEQ_DATA_WIDTH63_MASK 0x0700 /* WSEQ_DATA_WIDTH63 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH63_SHIFT 8 /* WSEQ_DATA_WIDTH63 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH63_WIDTH 3 /* WSEQ_DATA_WIDTH63 - [10:8] */ +#define WM8995_WSEQ_DATA_START63_MASK 0x000F /* WSEQ_DATA_START63 - [3:0] */ +#define WM8995_WSEQ_DATA_START63_SHIFT 0 /* WSEQ_DATA_START63 - [3:0] */ +#define WM8995_WSEQ_DATA_START63_WIDTH 4 /* WSEQ_DATA_START63 - [3:0] */ + +/* + * R12543 (0x30FF) - Write Sequencer 255 + */ +#define WM8995_WSEQ_EOS63 0x0100 /* WSEQ_EOS63 */ +#define WM8995_WSEQ_EOS63_MASK 0x0100 /* WSEQ_EOS63 */ +#define WM8995_WSEQ_EOS63_SHIFT 8 /* WSEQ_EOS63 */ +#define WM8995_WSEQ_EOS63_WIDTH 1 /* WSEQ_EOS63 */ +#define WM8995_WSEQ_DELAY63_MASK 0x000F /* WSEQ_DELAY63 - [3:0] */ +#define WM8995_WSEQ_DELAY63_SHIFT 0 /* WSEQ_DELAY63 - [3:0] */ +#define WM8995_WSEQ_DELAY63_WIDTH 4 /* WSEQ_DELAY63 - [3:0] */ + +/* + * R12544 (0x3100) - Write Sequencer 256 + */ +#define WM8995_WSEQ_ADDR64_MASK 0x3FFF /* WSEQ_ADDR64 - [13:0] */ +#define WM8995_WSEQ_ADDR64_SHIFT 0 /* WSEQ_ADDR64 - [13:0] */ +#define WM8995_WSEQ_ADDR64_WIDTH 14 /* WSEQ_ADDR64 - [13:0] */ + +/* + * R12545 (0x3101) - Write Sequencer 257 + */ +#define WM8995_WSEQ_DATA64_MASK 0x00FF /* WSEQ_DATA64 - [7:0] */ +#define WM8995_WSEQ_DATA64_SHIFT 0 /* WSEQ_DATA64 - [7:0] */ +#define WM8995_WSEQ_DATA64_WIDTH 8 /* WSEQ_DATA64 - [7:0] */ + +/* + * R12546 (0x3102) - Write Sequencer 258 + */ +#define WM8995_WSEQ_DATA_WIDTH64_MASK 0x0700 /* WSEQ_DATA_WIDTH64 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH64_SHIFT 8 /* WSEQ_DATA_WIDTH64 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH64_WIDTH 3 /* WSEQ_DATA_WIDTH64 - [10:8] */ +#define WM8995_WSEQ_DATA_START64_MASK 0x000F /* WSEQ_DATA_START64 - [3:0] */ +#define WM8995_WSEQ_DATA_START64_SHIFT 0 /* WSEQ_DATA_START64 - [3:0] */ +#define WM8995_WSEQ_DATA_START64_WIDTH 4 /* WSEQ_DATA_START64 - [3:0] */ + +/* + * R12547 (0x3103) - Write Sequencer 259 + */ +#define WM8995_WSEQ_EOS64 0x0100 /* WSEQ_EOS64 */ +#define WM8995_WSEQ_EOS64_MASK 0x0100 /* WSEQ_EOS64 */ +#define WM8995_WSEQ_EOS64_SHIFT 8 /* WSEQ_EOS64 */ +#define WM8995_WSEQ_EOS64_WIDTH 1 /* WSEQ_EOS64 */ +#define WM8995_WSEQ_DELAY64_MASK 0x000F /* WSEQ_DELAY64 - [3:0] */ +#define WM8995_WSEQ_DELAY64_SHIFT 0 /* WSEQ_DELAY64 - [3:0] */ +#define WM8995_WSEQ_DELAY64_WIDTH 4 /* WSEQ_DELAY64 - [3:0] */ + +/* + * R12548 (0x3104) - Write Sequencer 260 + */ +#define WM8995_WSEQ_ADDR65_MASK 0x3FFF /* WSEQ_ADDR65 - [13:0] */ +#define WM8995_WSEQ_ADDR65_SHIFT 0 /* WSEQ_ADDR65 - [13:0] */ +#define WM8995_WSEQ_ADDR65_WIDTH 14 /* WSEQ_ADDR65 - [13:0] */ + +/* + * R12549 (0x3105) - Write Sequencer 261 + */ +#define WM8995_WSEQ_DATA65_MASK 0x00FF /* WSEQ_DATA65 - [7:0] */ +#define WM8995_WSEQ_DATA65_SHIFT 0 /* WSEQ_DATA65 - [7:0] */ +#define WM8995_WSEQ_DATA65_WIDTH 8 /* WSEQ_DATA65 - [7:0] */ + +/* + * R12550 (0x3106) - Write Sequencer 262 + */ +#define WM8995_WSEQ_DATA_WIDTH65_MASK 0x0700 /* WSEQ_DATA_WIDTH65 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH65_SHIFT 8 /* WSEQ_DATA_WIDTH65 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH65_WIDTH 3 /* WSEQ_DATA_WIDTH65 - [10:8] */ +#define WM8995_WSEQ_DATA_START65_MASK 0x000F /* WSEQ_DATA_START65 - [3:0] */ +#define WM8995_WSEQ_DATA_START65_SHIFT 0 /* WSEQ_DATA_START65 - [3:0] */ +#define WM8995_WSEQ_DATA_START65_WIDTH 4 /* WSEQ_DATA_START65 - [3:0] */ + +/* + * R12551 (0x3107) - Write Sequencer 263 + */ +#define WM8995_WSEQ_EOS65 0x0100 /* WSEQ_EOS65 */ +#define WM8995_WSEQ_EOS65_MASK 0x0100 /* WSEQ_EOS65 */ +#define WM8995_WSEQ_EOS65_SHIFT 8 /* WSEQ_EOS65 */ +#define WM8995_WSEQ_EOS65_WIDTH 1 /* WSEQ_EOS65 */ +#define WM8995_WSEQ_DELAY65_MASK 0x000F /* WSEQ_DELAY65 - [3:0] */ +#define WM8995_WSEQ_DELAY65_SHIFT 0 /* WSEQ_DELAY65 - [3:0] */ +#define WM8995_WSEQ_DELAY65_WIDTH 4 /* WSEQ_DELAY65 - [3:0] */ + +/* + * R12552 (0x3108) - Write Sequencer 264 + */ +#define WM8995_WSEQ_ADDR66_MASK 0x3FFF /* WSEQ_ADDR66 - [13:0] */ +#define WM8995_WSEQ_ADDR66_SHIFT 0 /* WSEQ_ADDR66 - [13:0] */ +#define WM8995_WSEQ_ADDR66_WIDTH 14 /* WSEQ_ADDR66 - [13:0] */ + +/* + * R12553 (0x3109) - Write Sequencer 265 + */ +#define WM8995_WSEQ_DATA66_MASK 0x00FF /* WSEQ_DATA66 - [7:0] */ +#define WM8995_WSEQ_DATA66_SHIFT 0 /* WSEQ_DATA66 - [7:0] */ +#define WM8995_WSEQ_DATA66_WIDTH 8 /* WSEQ_DATA66 - [7:0] */ + +/* + * R12554 (0x310A) - Write Sequencer 266 + */ +#define WM8995_WSEQ_DATA_WIDTH66_MASK 0x0700 /* WSEQ_DATA_WIDTH66 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH66_SHIFT 8 /* WSEQ_DATA_WIDTH66 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH66_WIDTH 3 /* WSEQ_DATA_WIDTH66 - [10:8] */ +#define WM8995_WSEQ_DATA_START66_MASK 0x000F /* WSEQ_DATA_START66 - [3:0] */ +#define WM8995_WSEQ_DATA_START66_SHIFT 0 /* WSEQ_DATA_START66 - [3:0] */ +#define WM8995_WSEQ_DATA_START66_WIDTH 4 /* WSEQ_DATA_START66 - [3:0] */ + +/* + * R12555 (0x310B) - Write Sequencer 267 + */ +#define WM8995_WSEQ_EOS66 0x0100 /* WSEQ_EOS66 */ +#define WM8995_WSEQ_EOS66_MASK 0x0100 /* WSEQ_EOS66 */ +#define WM8995_WSEQ_EOS66_SHIFT 8 /* WSEQ_EOS66 */ +#define WM8995_WSEQ_EOS66_WIDTH 1 /* WSEQ_EOS66 */ +#define WM8995_WSEQ_DELAY66_MASK 0x000F /* WSEQ_DELAY66 - [3:0] */ +#define WM8995_WSEQ_DELAY66_SHIFT 0 /* WSEQ_DELAY66 - [3:0] */ +#define WM8995_WSEQ_DELAY66_WIDTH 4 /* WSEQ_DELAY66 - [3:0] */ + +/* + * R12556 (0x310C) - Write Sequencer 268 + */ +#define WM8995_WSEQ_ADDR67_MASK 0x3FFF /* WSEQ_ADDR67 - [13:0] */ +#define WM8995_WSEQ_ADDR67_SHIFT 0 /* WSEQ_ADDR67 - [13:0] */ +#define WM8995_WSEQ_ADDR67_WIDTH 14 /* WSEQ_ADDR67 - [13:0] */ + +/* + * R12557 (0x310D) - Write Sequencer 269 + */ +#define WM8995_WSEQ_DATA67_MASK 0x00FF /* WSEQ_DATA67 - [7:0] */ +#define WM8995_WSEQ_DATA67_SHIFT 0 /* WSEQ_DATA67 - [7:0] */ +#define WM8995_WSEQ_DATA67_WIDTH 8 /* WSEQ_DATA67 - [7:0] */ + +/* + * R12558 (0x310E) - Write Sequencer 270 + */ +#define WM8995_WSEQ_DATA_WIDTH67_MASK 0x0700 /* WSEQ_DATA_WIDTH67 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH67_SHIFT 8 /* WSEQ_DATA_WIDTH67 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH67_WIDTH 3 /* WSEQ_DATA_WIDTH67 - [10:8] */ +#define WM8995_WSEQ_DATA_START67_MASK 0x000F /* WSEQ_DATA_START67 - [3:0] */ +#define WM8995_WSEQ_DATA_START67_SHIFT 0 /* WSEQ_DATA_START67 - [3:0] */ +#define WM8995_WSEQ_DATA_START67_WIDTH 4 /* WSEQ_DATA_START67 - [3:0] */ + +/* + * R12559 (0x310F) - Write Sequencer 271 + */ +#define WM8995_WSEQ_EOS67 0x0100 /* WSEQ_EOS67 */ +#define WM8995_WSEQ_EOS67_MASK 0x0100 /* WSEQ_EOS67 */ +#define WM8995_WSEQ_EOS67_SHIFT 8 /* WSEQ_EOS67 */ +#define WM8995_WSEQ_EOS67_WIDTH 1 /* WSEQ_EOS67 */ +#define WM8995_WSEQ_DELAY67_MASK 0x000F /* WSEQ_DELAY67 - [3:0] */ +#define WM8995_WSEQ_DELAY67_SHIFT 0 /* WSEQ_DELAY67 - [3:0] */ +#define WM8995_WSEQ_DELAY67_WIDTH 4 /* WSEQ_DELAY67 - [3:0] */ + +/* + * R12560 (0x3110) - Write Sequencer 272 + */ +#define WM8995_WSEQ_ADDR68_MASK 0x3FFF /* WSEQ_ADDR68 - [13:0] */ +#define WM8995_WSEQ_ADDR68_SHIFT 0 /* WSEQ_ADDR68 - [13:0] */ +#define WM8995_WSEQ_ADDR68_WIDTH 14 /* WSEQ_ADDR68 - [13:0] */ + +/* + * R12561 (0x3111) - Write Sequencer 273 + */ +#define WM8995_WSEQ_DATA68_MASK 0x00FF /* WSEQ_DATA68 - [7:0] */ +#define WM8995_WSEQ_DATA68_SHIFT 0 /* WSEQ_DATA68 - [7:0] */ +#define WM8995_WSEQ_DATA68_WIDTH 8 /* WSEQ_DATA68 - [7:0] */ + +/* + * R12562 (0x3112) - Write Sequencer 274 + */ +#define WM8995_WSEQ_DATA_WIDTH68_MASK 0x0700 /* WSEQ_DATA_WIDTH68 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH68_SHIFT 8 /* WSEQ_DATA_WIDTH68 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH68_WIDTH 3 /* WSEQ_DATA_WIDTH68 - [10:8] */ +#define WM8995_WSEQ_DATA_START68_MASK 0x000F /* WSEQ_DATA_START68 - [3:0] */ +#define WM8995_WSEQ_DATA_START68_SHIFT 0 /* WSEQ_DATA_START68 - [3:0] */ +#define WM8995_WSEQ_DATA_START68_WIDTH 4 /* WSEQ_DATA_START68 - [3:0] */ + +/* + * R12563 (0x3113) - Write Sequencer 275 + */ +#define WM8995_WSEQ_EOS68 0x0100 /* WSEQ_EOS68 */ +#define WM8995_WSEQ_EOS68_MASK 0x0100 /* WSEQ_EOS68 */ +#define WM8995_WSEQ_EOS68_SHIFT 8 /* WSEQ_EOS68 */ +#define WM8995_WSEQ_EOS68_WIDTH 1 /* WSEQ_EOS68 */ +#define WM8995_WSEQ_DELAY68_MASK 0x000F /* WSEQ_DELAY68 - [3:0] */ +#define WM8995_WSEQ_DELAY68_SHIFT 0 /* WSEQ_DELAY68 - [3:0] */ +#define WM8995_WSEQ_DELAY68_WIDTH 4 /* WSEQ_DELAY68 - [3:0] */ + +/* + * R12564 (0x3114) - Write Sequencer 276 + */ +#define WM8995_WSEQ_ADDR69_MASK 0x3FFF /* WSEQ_ADDR69 - [13:0] */ +#define WM8995_WSEQ_ADDR69_SHIFT 0 /* WSEQ_ADDR69 - [13:0] */ +#define WM8995_WSEQ_ADDR69_WIDTH 14 /* WSEQ_ADDR69 - [13:0] */ + +/* + * R12565 (0x3115) - Write Sequencer 277 + */ +#define WM8995_WSEQ_DATA69_MASK 0x00FF /* WSEQ_DATA69 - [7:0] */ +#define WM8995_WSEQ_DATA69_SHIFT 0 /* WSEQ_DATA69 - [7:0] */ +#define WM8995_WSEQ_DATA69_WIDTH 8 /* WSEQ_DATA69 - [7:0] */ + +/* + * R12566 (0x3116) - Write Sequencer 278 + */ +#define WM8995_WSEQ_DATA_WIDTH69_MASK 0x0700 /* WSEQ_DATA_WIDTH69 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH69_SHIFT 8 /* WSEQ_DATA_WIDTH69 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH69_WIDTH 3 /* WSEQ_DATA_WIDTH69 - [10:8] */ +#define WM8995_WSEQ_DATA_START69_MASK 0x000F /* WSEQ_DATA_START69 - [3:0] */ +#define WM8995_WSEQ_DATA_START69_SHIFT 0 /* WSEQ_DATA_START69 - [3:0] */ +#define WM8995_WSEQ_DATA_START69_WIDTH 4 /* WSEQ_DATA_START69 - [3:0] */ + +/* + * R12567 (0x3117) - Write Sequencer 279 + */ +#define WM8995_WSEQ_EOS69 0x0100 /* WSEQ_EOS69 */ +#define WM8995_WSEQ_EOS69_MASK 0x0100 /* WSEQ_EOS69 */ +#define WM8995_WSEQ_EOS69_SHIFT 8 /* WSEQ_EOS69 */ +#define WM8995_WSEQ_EOS69_WIDTH 1 /* WSEQ_EOS69 */ +#define WM8995_WSEQ_DELAY69_MASK 0x000F /* WSEQ_DELAY69 - [3:0] */ +#define WM8995_WSEQ_DELAY69_SHIFT 0 /* WSEQ_DELAY69 - [3:0] */ +#define WM8995_WSEQ_DELAY69_WIDTH 4 /* WSEQ_DELAY69 - [3:0] */ + +/* + * R12568 (0x3118) - Write Sequencer 280 + */ +#define WM8995_WSEQ_ADDR70_MASK 0x3FFF /* WSEQ_ADDR70 - [13:0] */ +#define WM8995_WSEQ_ADDR70_SHIFT 0 /* WSEQ_ADDR70 - [13:0] */ +#define WM8995_WSEQ_ADDR70_WIDTH 14 /* WSEQ_ADDR70 - [13:0] */ + +/* + * R12569 (0x3119) - Write Sequencer 281 + */ +#define WM8995_WSEQ_DATA70_MASK 0x00FF /* WSEQ_DATA70 - [7:0] */ +#define WM8995_WSEQ_DATA70_SHIFT 0 /* WSEQ_DATA70 - [7:0] */ +#define WM8995_WSEQ_DATA70_WIDTH 8 /* WSEQ_DATA70 - [7:0] */ + +/* + * R12570 (0x311A) - Write Sequencer 282 + */ +#define WM8995_WSEQ_DATA_WIDTH70_MASK 0x0700 /* WSEQ_DATA_WIDTH70 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH70_SHIFT 8 /* WSEQ_DATA_WIDTH70 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH70_WIDTH 3 /* WSEQ_DATA_WIDTH70 - [10:8] */ +#define WM8995_WSEQ_DATA_START70_MASK 0x000F /* WSEQ_DATA_START70 - [3:0] */ +#define WM8995_WSEQ_DATA_START70_SHIFT 0 /* WSEQ_DATA_START70 - [3:0] */ +#define WM8995_WSEQ_DATA_START70_WIDTH 4 /* WSEQ_DATA_START70 - [3:0] */ + +/* + * R12571 (0x311B) - Write Sequencer 283 + */ +#define WM8995_WSEQ_EOS70 0x0100 /* WSEQ_EOS70 */ +#define WM8995_WSEQ_EOS70_MASK 0x0100 /* WSEQ_EOS70 */ +#define WM8995_WSEQ_EOS70_SHIFT 8 /* WSEQ_EOS70 */ +#define WM8995_WSEQ_EOS70_WIDTH 1 /* WSEQ_EOS70 */ +#define WM8995_WSEQ_DELAY70_MASK 0x000F /* WSEQ_DELAY70 - [3:0] */ +#define WM8995_WSEQ_DELAY70_SHIFT 0 /* WSEQ_DELAY70 - [3:0] */ +#define WM8995_WSEQ_DELAY70_WIDTH 4 /* WSEQ_DELAY70 - [3:0] */ + +/* + * R12572 (0x311C) - Write Sequencer 284 + */ +#define WM8995_WSEQ_ADDR71_MASK 0x3FFF /* WSEQ_ADDR71 - [13:0] */ +#define WM8995_WSEQ_ADDR71_SHIFT 0 /* WSEQ_ADDR71 - [13:0] */ +#define WM8995_WSEQ_ADDR71_WIDTH 14 /* WSEQ_ADDR71 - [13:0] */ + +/* + * R12573 (0x311D) - Write Sequencer 285 + */ +#define WM8995_WSEQ_DATA71_MASK 0x00FF /* WSEQ_DATA71 - [7:0] */ +#define WM8995_WSEQ_DATA71_SHIFT 0 /* WSEQ_DATA71 - [7:0] */ +#define WM8995_WSEQ_DATA71_WIDTH 8 /* WSEQ_DATA71 - [7:0] */ + +/* + * R12574 (0x311E) - Write Sequencer 286 + */ +#define WM8995_WSEQ_DATA_WIDTH71_MASK 0x0700 /* WSEQ_DATA_WIDTH71 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH71_SHIFT 8 /* WSEQ_DATA_WIDTH71 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH71_WIDTH 3 /* WSEQ_DATA_WIDTH71 - [10:8] */ +#define WM8995_WSEQ_DATA_START71_MASK 0x000F /* WSEQ_DATA_START71 - [3:0] */ +#define WM8995_WSEQ_DATA_START71_SHIFT 0 /* WSEQ_DATA_START71 - [3:0] */ +#define WM8995_WSEQ_DATA_START71_WIDTH 4 /* WSEQ_DATA_START71 - [3:0] */ + +/* + * R12575 (0x311F) - Write Sequencer 287 + */ +#define WM8995_WSEQ_EOS71 0x0100 /* WSEQ_EOS71 */ +#define WM8995_WSEQ_EOS71_MASK 0x0100 /* WSEQ_EOS71 */ +#define WM8995_WSEQ_EOS71_SHIFT 8 /* WSEQ_EOS71 */ +#define WM8995_WSEQ_EOS71_WIDTH 1 /* WSEQ_EOS71 */ +#define WM8995_WSEQ_DELAY71_MASK 0x000F /* WSEQ_DELAY71 - [3:0] */ +#define WM8995_WSEQ_DELAY71_SHIFT 0 /* WSEQ_DELAY71 - [3:0] */ +#define WM8995_WSEQ_DELAY71_WIDTH 4 /* WSEQ_DELAY71 - [3:0] */ + +/* + * R12576 (0x3120) - Write Sequencer 288 + */ +#define WM8995_WSEQ_ADDR72_MASK 0x3FFF /* WSEQ_ADDR72 - [13:0] */ +#define WM8995_WSEQ_ADDR72_SHIFT 0 /* WSEQ_ADDR72 - [13:0] */ +#define WM8995_WSEQ_ADDR72_WIDTH 14 /* WSEQ_ADDR72 - [13:0] */ + +/* + * R12577 (0x3121) - Write Sequencer 289 + */ +#define WM8995_WSEQ_DATA72_MASK 0x00FF /* WSEQ_DATA72 - [7:0] */ +#define WM8995_WSEQ_DATA72_SHIFT 0 /* WSEQ_DATA72 - [7:0] */ +#define WM8995_WSEQ_DATA72_WIDTH 8 /* WSEQ_DATA72 - [7:0] */ + +/* + * R12578 (0x3122) - Write Sequencer 290 + */ +#define WM8995_WSEQ_DATA_WIDTH72_MASK 0x0700 /* WSEQ_DATA_WIDTH72 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH72_SHIFT 8 /* WSEQ_DATA_WIDTH72 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH72_WIDTH 3 /* WSEQ_DATA_WIDTH72 - [10:8] */ +#define WM8995_WSEQ_DATA_START72_MASK 0x000F /* WSEQ_DATA_START72 - [3:0] */ +#define WM8995_WSEQ_DATA_START72_SHIFT 0 /* WSEQ_DATA_START72 - [3:0] */ +#define WM8995_WSEQ_DATA_START72_WIDTH 4 /* WSEQ_DATA_START72 - [3:0] */ + +/* + * R12579 (0x3123) - Write Sequencer 291 + */ +#define WM8995_WSEQ_EOS72 0x0100 /* WSEQ_EOS72 */ +#define WM8995_WSEQ_EOS72_MASK 0x0100 /* WSEQ_EOS72 */ +#define WM8995_WSEQ_EOS72_SHIFT 8 /* WSEQ_EOS72 */ +#define WM8995_WSEQ_EOS72_WIDTH 1 /* WSEQ_EOS72 */ +#define WM8995_WSEQ_DELAY72_MASK 0x000F /* WSEQ_DELAY72 - [3:0] */ +#define WM8995_WSEQ_DELAY72_SHIFT 0 /* WSEQ_DELAY72 - [3:0] */ +#define WM8995_WSEQ_DELAY72_WIDTH 4 /* WSEQ_DELAY72 - [3:0] */ + +/* + * R12580 (0x3124) - Write Sequencer 292 + */ +#define WM8995_WSEQ_ADDR73_MASK 0x3FFF /* WSEQ_ADDR73 - [13:0] */ +#define WM8995_WSEQ_ADDR73_SHIFT 0 /* WSEQ_ADDR73 - [13:0] */ +#define WM8995_WSEQ_ADDR73_WIDTH 14 /* WSEQ_ADDR73 - [13:0] */ + +/* + * R12581 (0x3125) - Write Sequencer 293 + */ +#define WM8995_WSEQ_DATA73_MASK 0x00FF /* WSEQ_DATA73 - [7:0] */ +#define WM8995_WSEQ_DATA73_SHIFT 0 /* WSEQ_DATA73 - [7:0] */ +#define WM8995_WSEQ_DATA73_WIDTH 8 /* WSEQ_DATA73 - [7:0] */ + +/* + * R12582 (0x3126) - Write Sequencer 294 + */ +#define WM8995_WSEQ_DATA_WIDTH73_MASK 0x0700 /* WSEQ_DATA_WIDTH73 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH73_SHIFT 8 /* WSEQ_DATA_WIDTH73 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH73_WIDTH 3 /* WSEQ_DATA_WIDTH73 - [10:8] */ +#define WM8995_WSEQ_DATA_START73_MASK 0x000F /* WSEQ_DATA_START73 - [3:0] */ +#define WM8995_WSEQ_DATA_START73_SHIFT 0 /* WSEQ_DATA_START73 - [3:0] */ +#define WM8995_WSEQ_DATA_START73_WIDTH 4 /* WSEQ_DATA_START73 - [3:0] */ + +/* + * R12583 (0x3127) - Write Sequencer 295 + */ +#define WM8995_WSEQ_EOS73 0x0100 /* WSEQ_EOS73 */ +#define WM8995_WSEQ_EOS73_MASK 0x0100 /* WSEQ_EOS73 */ +#define WM8995_WSEQ_EOS73_SHIFT 8 /* WSEQ_EOS73 */ +#define WM8995_WSEQ_EOS73_WIDTH 1 /* WSEQ_EOS73 */ +#define WM8995_WSEQ_DELAY73_MASK 0x000F /* WSEQ_DELAY73 - [3:0] */ +#define WM8995_WSEQ_DELAY73_SHIFT 0 /* WSEQ_DELAY73 - [3:0] */ +#define WM8995_WSEQ_DELAY73_WIDTH 4 /* WSEQ_DELAY73 - [3:0] */ + +/* + * R12584 (0x3128) - Write Sequencer 296 + */ +#define WM8995_WSEQ_ADDR74_MASK 0x3FFF /* WSEQ_ADDR74 - [13:0] */ +#define WM8995_WSEQ_ADDR74_SHIFT 0 /* WSEQ_ADDR74 - [13:0] */ +#define WM8995_WSEQ_ADDR74_WIDTH 14 /* WSEQ_ADDR74 - [13:0] */ + +/* + * R12585 (0x3129) - Write Sequencer 297 + */ +#define WM8995_WSEQ_DATA74_MASK 0x00FF /* WSEQ_DATA74 - [7:0] */ +#define WM8995_WSEQ_DATA74_SHIFT 0 /* WSEQ_DATA74 - [7:0] */ +#define WM8995_WSEQ_DATA74_WIDTH 8 /* WSEQ_DATA74 - [7:0] */ + +/* + * R12586 (0x312A) - Write Sequencer 298 + */ +#define WM8995_WSEQ_DATA_WIDTH74_MASK 0x0700 /* WSEQ_DATA_WIDTH74 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH74_SHIFT 8 /* WSEQ_DATA_WIDTH74 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH74_WIDTH 3 /* WSEQ_DATA_WIDTH74 - [10:8] */ +#define WM8995_WSEQ_DATA_START74_MASK 0x000F /* WSEQ_DATA_START74 - [3:0] */ +#define WM8995_WSEQ_DATA_START74_SHIFT 0 /* WSEQ_DATA_START74 - [3:0] */ +#define WM8995_WSEQ_DATA_START74_WIDTH 4 /* WSEQ_DATA_START74 - [3:0] */ + +/* + * R12587 (0x312B) - Write Sequencer 299 + */ +#define WM8995_WSEQ_EOS74 0x0100 /* WSEQ_EOS74 */ +#define WM8995_WSEQ_EOS74_MASK 0x0100 /* WSEQ_EOS74 */ +#define WM8995_WSEQ_EOS74_SHIFT 8 /* WSEQ_EOS74 */ +#define WM8995_WSEQ_EOS74_WIDTH 1 /* WSEQ_EOS74 */ +#define WM8995_WSEQ_DELAY74_MASK 0x000F /* WSEQ_DELAY74 - [3:0] */ +#define WM8995_WSEQ_DELAY74_SHIFT 0 /* WSEQ_DELAY74 - [3:0] */ +#define WM8995_WSEQ_DELAY74_WIDTH 4 /* WSEQ_DELAY74 - [3:0] */ + +/* + * R12588 (0x312C) - Write Sequencer 300 + */ +#define WM8995_WSEQ_ADDR75_MASK 0x3FFF /* WSEQ_ADDR75 - [13:0] */ +#define WM8995_WSEQ_ADDR75_SHIFT 0 /* WSEQ_ADDR75 - [13:0] */ +#define WM8995_WSEQ_ADDR75_WIDTH 14 /* WSEQ_ADDR75 - [13:0] */ + +/* + * R12589 (0x312D) - Write Sequencer 301 + */ +#define WM8995_WSEQ_DATA75_MASK 0x00FF /* WSEQ_DATA75 - [7:0] */ +#define WM8995_WSEQ_DATA75_SHIFT 0 /* WSEQ_DATA75 - [7:0] */ +#define WM8995_WSEQ_DATA75_WIDTH 8 /* WSEQ_DATA75 - [7:0] */ + +/* + * R12590 (0x312E) - Write Sequencer 302 + */ +#define WM8995_WSEQ_DATA_WIDTH75_MASK 0x0700 /* WSEQ_DATA_WIDTH75 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH75_SHIFT 8 /* WSEQ_DATA_WIDTH75 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH75_WIDTH 3 /* WSEQ_DATA_WIDTH75 - [10:8] */ +#define WM8995_WSEQ_DATA_START75_MASK 0x000F /* WSEQ_DATA_START75 - [3:0] */ +#define WM8995_WSEQ_DATA_START75_SHIFT 0 /* WSEQ_DATA_START75 - [3:0] */ +#define WM8995_WSEQ_DATA_START75_WIDTH 4 /* WSEQ_DATA_START75 - [3:0] */ + +/* + * R12591 (0x312F) - Write Sequencer 303 + */ +#define WM8995_WSEQ_EOS75 0x0100 /* WSEQ_EOS75 */ +#define WM8995_WSEQ_EOS75_MASK 0x0100 /* WSEQ_EOS75 */ +#define WM8995_WSEQ_EOS75_SHIFT 8 /* WSEQ_EOS75 */ +#define WM8995_WSEQ_EOS75_WIDTH 1 /* WSEQ_EOS75 */ +#define WM8995_WSEQ_DELAY75_MASK 0x000F /* WSEQ_DELAY75 - [3:0] */ +#define WM8995_WSEQ_DELAY75_SHIFT 0 /* WSEQ_DELAY75 - [3:0] */ +#define WM8995_WSEQ_DELAY75_WIDTH 4 /* WSEQ_DELAY75 - [3:0] */ + +/* + * R12592 (0x3130) - Write Sequencer 304 + */ +#define WM8995_WSEQ_ADDR76_MASK 0x3FFF /* WSEQ_ADDR76 - [13:0] */ +#define WM8995_WSEQ_ADDR76_SHIFT 0 /* WSEQ_ADDR76 - [13:0] */ +#define WM8995_WSEQ_ADDR76_WIDTH 14 /* WSEQ_ADDR76 - [13:0] */ + +/* + * R12593 (0x3131) - Write Sequencer 305 + */ +#define WM8995_WSEQ_DATA76_MASK 0x00FF /* WSEQ_DATA76 - [7:0] */ +#define WM8995_WSEQ_DATA76_SHIFT 0 /* WSEQ_DATA76 - [7:0] */ +#define WM8995_WSEQ_DATA76_WIDTH 8 /* WSEQ_DATA76 - [7:0] */ + +/* + * R12594 (0x3132) - Write Sequencer 306 + */ +#define WM8995_WSEQ_DATA_WIDTH76_MASK 0x0700 /* WSEQ_DATA_WIDTH76 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH76_SHIFT 8 /* WSEQ_DATA_WIDTH76 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH76_WIDTH 3 /* WSEQ_DATA_WIDTH76 - [10:8] */ +#define WM8995_WSEQ_DATA_START76_MASK 0x000F /* WSEQ_DATA_START76 - [3:0] */ +#define WM8995_WSEQ_DATA_START76_SHIFT 0 /* WSEQ_DATA_START76 - [3:0] */ +#define WM8995_WSEQ_DATA_START76_WIDTH 4 /* WSEQ_DATA_START76 - [3:0] */ + +/* + * R12595 (0x3133) - Write Sequencer 307 + */ +#define WM8995_WSEQ_EOS76 0x0100 /* WSEQ_EOS76 */ +#define WM8995_WSEQ_EOS76_MASK 0x0100 /* WSEQ_EOS76 */ +#define WM8995_WSEQ_EOS76_SHIFT 8 /* WSEQ_EOS76 */ +#define WM8995_WSEQ_EOS76_WIDTH 1 /* WSEQ_EOS76 */ +#define WM8995_WSEQ_DELAY76_MASK 0x000F /* WSEQ_DELAY76 - [3:0] */ +#define WM8995_WSEQ_DELAY76_SHIFT 0 /* WSEQ_DELAY76 - [3:0] */ +#define WM8995_WSEQ_DELAY76_WIDTH 4 /* WSEQ_DELAY76 - [3:0] */ + +/* + * R12596 (0x3134) - Write Sequencer 308 + */ +#define WM8995_WSEQ_ADDR77_MASK 0x3FFF /* WSEQ_ADDR77 - [13:0] */ +#define WM8995_WSEQ_ADDR77_SHIFT 0 /* WSEQ_ADDR77 - [13:0] */ +#define WM8995_WSEQ_ADDR77_WIDTH 14 /* WSEQ_ADDR77 - [13:0] */ + +/* + * R12597 (0x3135) - Write Sequencer 309 + */ +#define WM8995_WSEQ_DATA77_MASK 0x00FF /* WSEQ_DATA77 - [7:0] */ +#define WM8995_WSEQ_DATA77_SHIFT 0 /* WSEQ_DATA77 - [7:0] */ +#define WM8995_WSEQ_DATA77_WIDTH 8 /* WSEQ_DATA77 - [7:0] */ + +/* + * R12598 (0x3136) - Write Sequencer 310 + */ +#define WM8995_WSEQ_DATA_WIDTH77_MASK 0x0700 /* WSEQ_DATA_WIDTH77 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH77_SHIFT 8 /* WSEQ_DATA_WIDTH77 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH77_WIDTH 3 /* WSEQ_DATA_WIDTH77 - [10:8] */ +#define WM8995_WSEQ_DATA_START77_MASK 0x000F /* WSEQ_DATA_START77 - [3:0] */ +#define WM8995_WSEQ_DATA_START77_SHIFT 0 /* WSEQ_DATA_START77 - [3:0] */ +#define WM8995_WSEQ_DATA_START77_WIDTH 4 /* WSEQ_DATA_START77 - [3:0] */ + +/* + * R12599 (0x3137) - Write Sequencer 311 + */ +#define WM8995_WSEQ_EOS77 0x0100 /* WSEQ_EOS77 */ +#define WM8995_WSEQ_EOS77_MASK 0x0100 /* WSEQ_EOS77 */ +#define WM8995_WSEQ_EOS77_SHIFT 8 /* WSEQ_EOS77 */ +#define WM8995_WSEQ_EOS77_WIDTH 1 /* WSEQ_EOS77 */ +#define WM8995_WSEQ_DELAY77_MASK 0x000F /* WSEQ_DELAY77 - [3:0] */ +#define WM8995_WSEQ_DELAY77_SHIFT 0 /* WSEQ_DELAY77 - [3:0] */ +#define WM8995_WSEQ_DELAY77_WIDTH 4 /* WSEQ_DELAY77 - [3:0] */ + +/* + * R12600 (0x3138) - Write Sequencer 312 + */ +#define WM8995_WSEQ_ADDR78_MASK 0x3FFF /* WSEQ_ADDR78 - [13:0] */ +#define WM8995_WSEQ_ADDR78_SHIFT 0 /* WSEQ_ADDR78 - [13:0] */ +#define WM8995_WSEQ_ADDR78_WIDTH 14 /* WSEQ_ADDR78 - [13:0] */ + +/* + * R12601 (0x3139) - Write Sequencer 313 + */ +#define WM8995_WSEQ_DATA78_MASK 0x00FF /* WSEQ_DATA78 - [7:0] */ +#define WM8995_WSEQ_DATA78_SHIFT 0 /* WSEQ_DATA78 - [7:0] */ +#define WM8995_WSEQ_DATA78_WIDTH 8 /* WSEQ_DATA78 - [7:0] */ + +/* + * R12602 (0x313A) - Write Sequencer 314 + */ +#define WM8995_WSEQ_DATA_WIDTH78_MASK 0x0700 /* WSEQ_DATA_WIDTH78 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH78_SHIFT 8 /* WSEQ_DATA_WIDTH78 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH78_WIDTH 3 /* WSEQ_DATA_WIDTH78 - [10:8] */ +#define WM8995_WSEQ_DATA_START78_MASK 0x000F /* WSEQ_DATA_START78 - [3:0] */ +#define WM8995_WSEQ_DATA_START78_SHIFT 0 /* WSEQ_DATA_START78 - [3:0] */ +#define WM8995_WSEQ_DATA_START78_WIDTH 4 /* WSEQ_DATA_START78 - [3:0] */ + +/* + * R12603 (0x313B) - Write Sequencer 315 + */ +#define WM8995_WSEQ_EOS78 0x0100 /* WSEQ_EOS78 */ +#define WM8995_WSEQ_EOS78_MASK 0x0100 /* WSEQ_EOS78 */ +#define WM8995_WSEQ_EOS78_SHIFT 8 /* WSEQ_EOS78 */ +#define WM8995_WSEQ_EOS78_WIDTH 1 /* WSEQ_EOS78 */ +#define WM8995_WSEQ_DELAY78_MASK 0x000F /* WSEQ_DELAY78 - [3:0] */ +#define WM8995_WSEQ_DELAY78_SHIFT 0 /* WSEQ_DELAY78 - [3:0] */ +#define WM8995_WSEQ_DELAY78_WIDTH 4 /* WSEQ_DELAY78 - [3:0] */ + +/* + * R12604 (0x313C) - Write Sequencer 316 + */ +#define WM8995_WSEQ_ADDR79_MASK 0x3FFF /* WSEQ_ADDR79 - [13:0] */ +#define WM8995_WSEQ_ADDR79_SHIFT 0 /* WSEQ_ADDR79 - [13:0] */ +#define WM8995_WSEQ_ADDR79_WIDTH 14 /* WSEQ_ADDR79 - [13:0] */ + +/* + * R12605 (0x313D) - Write Sequencer 317 + */ +#define WM8995_WSEQ_DATA79_MASK 0x00FF /* WSEQ_DATA79 - [7:0] */ +#define WM8995_WSEQ_DATA79_SHIFT 0 /* WSEQ_DATA79 - [7:0] */ +#define WM8995_WSEQ_DATA79_WIDTH 8 /* WSEQ_DATA79 - [7:0] */ + +/* + * R12606 (0x313E) - Write Sequencer 318 + */ +#define WM8995_WSEQ_DATA_WIDTH79_MASK 0x0700 /* WSEQ_DATA_WIDTH79 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH79_SHIFT 8 /* WSEQ_DATA_WIDTH79 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH79_WIDTH 3 /* WSEQ_DATA_WIDTH79 - [10:8] */ +#define WM8995_WSEQ_DATA_START79_MASK 0x000F /* WSEQ_DATA_START79 - [3:0] */ +#define WM8995_WSEQ_DATA_START79_SHIFT 0 /* WSEQ_DATA_START79 - [3:0] */ +#define WM8995_WSEQ_DATA_START79_WIDTH 4 /* WSEQ_DATA_START79 - [3:0] */ + +/* + * R12607 (0x313F) - Write Sequencer 319 + */ +#define WM8995_WSEQ_EOS79 0x0100 /* WSEQ_EOS79 */ +#define WM8995_WSEQ_EOS79_MASK 0x0100 /* WSEQ_EOS79 */ +#define WM8995_WSEQ_EOS79_SHIFT 8 /* WSEQ_EOS79 */ +#define WM8995_WSEQ_EOS79_WIDTH 1 /* WSEQ_EOS79 */ +#define WM8995_WSEQ_DELAY79_MASK 0x000F /* WSEQ_DELAY79 - [3:0] */ +#define WM8995_WSEQ_DELAY79_SHIFT 0 /* WSEQ_DELAY79 - [3:0] */ +#define WM8995_WSEQ_DELAY79_WIDTH 4 /* WSEQ_DELAY79 - [3:0] */ + +/* + * R12608 (0x3140) - Write Sequencer 320 + */ +#define WM8995_WSEQ_ADDR80_MASK 0x3FFF /* WSEQ_ADDR80 - [13:0] */ +#define WM8995_WSEQ_ADDR80_SHIFT 0 /* WSEQ_ADDR80 - [13:0] */ +#define WM8995_WSEQ_ADDR80_WIDTH 14 /* WSEQ_ADDR80 - [13:0] */ + +/* + * R12609 (0x3141) - Write Sequencer 321 + */ +#define WM8995_WSEQ_DATA80_MASK 0x00FF /* WSEQ_DATA80 - [7:0] */ +#define WM8995_WSEQ_DATA80_SHIFT 0 /* WSEQ_DATA80 - [7:0] */ +#define WM8995_WSEQ_DATA80_WIDTH 8 /* WSEQ_DATA80 - [7:0] */ + +/* + * R12610 (0x3142) - Write Sequencer 322 + */ +#define WM8995_WSEQ_DATA_WIDTH80_MASK 0x0700 /* WSEQ_DATA_WIDTH80 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH80_SHIFT 8 /* WSEQ_DATA_WIDTH80 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH80_WIDTH 3 /* WSEQ_DATA_WIDTH80 - [10:8] */ +#define WM8995_WSEQ_DATA_START80_MASK 0x000F /* WSEQ_DATA_START80 - [3:0] */ +#define WM8995_WSEQ_DATA_START80_SHIFT 0 /* WSEQ_DATA_START80 - [3:0] */ +#define WM8995_WSEQ_DATA_START80_WIDTH 4 /* WSEQ_DATA_START80 - [3:0] */ + +/* + * R12611 (0x3143) - Write Sequencer 323 + */ +#define WM8995_WSEQ_EOS80 0x0100 /* WSEQ_EOS80 */ +#define WM8995_WSEQ_EOS80_MASK 0x0100 /* WSEQ_EOS80 */ +#define WM8995_WSEQ_EOS80_SHIFT 8 /* WSEQ_EOS80 */ +#define WM8995_WSEQ_EOS80_WIDTH 1 /* WSEQ_EOS80 */ +#define WM8995_WSEQ_DELAY80_MASK 0x000F /* WSEQ_DELAY80 - [3:0] */ +#define WM8995_WSEQ_DELAY80_SHIFT 0 /* WSEQ_DELAY80 - [3:0] */ +#define WM8995_WSEQ_DELAY80_WIDTH 4 /* WSEQ_DELAY80 - [3:0] */ + +/* + * R12612 (0x3144) - Write Sequencer 324 + */ +#define WM8995_WSEQ_ADDR81_MASK 0x3FFF /* WSEQ_ADDR81 - [13:0] */ +#define WM8995_WSEQ_ADDR81_SHIFT 0 /* WSEQ_ADDR81 - [13:0] */ +#define WM8995_WSEQ_ADDR81_WIDTH 14 /* WSEQ_ADDR81 - [13:0] */ + +/* + * R12613 (0x3145) - Write Sequencer 325 + */ +#define WM8995_WSEQ_DATA81_MASK 0x00FF /* WSEQ_DATA81 - [7:0] */ +#define WM8995_WSEQ_DATA81_SHIFT 0 /* WSEQ_DATA81 - [7:0] */ +#define WM8995_WSEQ_DATA81_WIDTH 8 /* WSEQ_DATA81 - [7:0] */ + +/* + * R12614 (0x3146) - Write Sequencer 326 + */ +#define WM8995_WSEQ_DATA_WIDTH81_MASK 0x0700 /* WSEQ_DATA_WIDTH81 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH81_SHIFT 8 /* WSEQ_DATA_WIDTH81 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH81_WIDTH 3 /* WSEQ_DATA_WIDTH81 - [10:8] */ +#define WM8995_WSEQ_DATA_START81_MASK 0x000F /* WSEQ_DATA_START81 - [3:0] */ +#define WM8995_WSEQ_DATA_START81_SHIFT 0 /* WSEQ_DATA_START81 - [3:0] */ +#define WM8995_WSEQ_DATA_START81_WIDTH 4 /* WSEQ_DATA_START81 - [3:0] */ + +/* + * R12615 (0x3147) - Write Sequencer 327 + */ +#define WM8995_WSEQ_EOS81 0x0100 /* WSEQ_EOS81 */ +#define WM8995_WSEQ_EOS81_MASK 0x0100 /* WSEQ_EOS81 */ +#define WM8995_WSEQ_EOS81_SHIFT 8 /* WSEQ_EOS81 */ +#define WM8995_WSEQ_EOS81_WIDTH 1 /* WSEQ_EOS81 */ +#define WM8995_WSEQ_DELAY81_MASK 0x000F /* WSEQ_DELAY81 - [3:0] */ +#define WM8995_WSEQ_DELAY81_SHIFT 0 /* WSEQ_DELAY81 - [3:0] */ +#define WM8995_WSEQ_DELAY81_WIDTH 4 /* WSEQ_DELAY81 - [3:0] */ + +/* + * R12616 (0x3148) - Write Sequencer 328 + */ +#define WM8995_WSEQ_ADDR82_MASK 0x3FFF /* WSEQ_ADDR82 - [13:0] */ +#define WM8995_WSEQ_ADDR82_SHIFT 0 /* WSEQ_ADDR82 - [13:0] */ +#define WM8995_WSEQ_ADDR82_WIDTH 14 /* WSEQ_ADDR82 - [13:0] */ + +/* + * R12617 (0x3149) - Write Sequencer 329 + */ +#define WM8995_WSEQ_DATA82_MASK 0x00FF /* WSEQ_DATA82 - [7:0] */ +#define WM8995_WSEQ_DATA82_SHIFT 0 /* WSEQ_DATA82 - [7:0] */ +#define WM8995_WSEQ_DATA82_WIDTH 8 /* WSEQ_DATA82 - [7:0] */ + +/* + * R12618 (0x314A) - Write Sequencer 330 + */ +#define WM8995_WSEQ_DATA_WIDTH82_MASK 0x0700 /* WSEQ_DATA_WIDTH82 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH82_SHIFT 8 /* WSEQ_DATA_WIDTH82 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH82_WIDTH 3 /* WSEQ_DATA_WIDTH82 - [10:8] */ +#define WM8995_WSEQ_DATA_START82_MASK 0x000F /* WSEQ_DATA_START82 - [3:0] */ +#define WM8995_WSEQ_DATA_START82_SHIFT 0 /* WSEQ_DATA_START82 - [3:0] */ +#define WM8995_WSEQ_DATA_START82_WIDTH 4 /* WSEQ_DATA_START82 - [3:0] */ + +/* + * R12619 (0x314B) - Write Sequencer 331 + */ +#define WM8995_WSEQ_EOS82 0x0100 /* WSEQ_EOS82 */ +#define WM8995_WSEQ_EOS82_MASK 0x0100 /* WSEQ_EOS82 */ +#define WM8995_WSEQ_EOS82_SHIFT 8 /* WSEQ_EOS82 */ +#define WM8995_WSEQ_EOS82_WIDTH 1 /* WSEQ_EOS82 */ +#define WM8995_WSEQ_DELAY82_MASK 0x000F /* WSEQ_DELAY82 - [3:0] */ +#define WM8995_WSEQ_DELAY82_SHIFT 0 /* WSEQ_DELAY82 - [3:0] */ +#define WM8995_WSEQ_DELAY82_WIDTH 4 /* WSEQ_DELAY82 - [3:0] */ + +/* + * R12620 (0x314C) - Write Sequencer 332 + */ +#define WM8995_WSEQ_ADDR83_MASK 0x3FFF /* WSEQ_ADDR83 - [13:0] */ +#define WM8995_WSEQ_ADDR83_SHIFT 0 /* WSEQ_ADDR83 - [13:0] */ +#define WM8995_WSEQ_ADDR83_WIDTH 14 /* WSEQ_ADDR83 - [13:0] */ + +/* + * R12621 (0x314D) - Write Sequencer 333 + */ +#define WM8995_WSEQ_DATA83_MASK 0x00FF /* WSEQ_DATA83 - [7:0] */ +#define WM8995_WSEQ_DATA83_SHIFT 0 /* WSEQ_DATA83 - [7:0] */ +#define WM8995_WSEQ_DATA83_WIDTH 8 /* WSEQ_DATA83 - [7:0] */ + +/* + * R12622 (0x314E) - Write Sequencer 334 + */ +#define WM8995_WSEQ_DATA_WIDTH83_MASK 0x0700 /* WSEQ_DATA_WIDTH83 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH83_SHIFT 8 /* WSEQ_DATA_WIDTH83 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH83_WIDTH 3 /* WSEQ_DATA_WIDTH83 - [10:8] */ +#define WM8995_WSEQ_DATA_START83_MASK 0x000F /* WSEQ_DATA_START83 - [3:0] */ +#define WM8995_WSEQ_DATA_START83_SHIFT 0 /* WSEQ_DATA_START83 - [3:0] */ +#define WM8995_WSEQ_DATA_START83_WIDTH 4 /* WSEQ_DATA_START83 - [3:0] */ + +/* + * R12623 (0x314F) - Write Sequencer 335 + */ +#define WM8995_WSEQ_EOS83 0x0100 /* WSEQ_EOS83 */ +#define WM8995_WSEQ_EOS83_MASK 0x0100 /* WSEQ_EOS83 */ +#define WM8995_WSEQ_EOS83_SHIFT 8 /* WSEQ_EOS83 */ +#define WM8995_WSEQ_EOS83_WIDTH 1 /* WSEQ_EOS83 */ +#define WM8995_WSEQ_DELAY83_MASK 0x000F /* WSEQ_DELAY83 - [3:0] */ +#define WM8995_WSEQ_DELAY83_SHIFT 0 /* WSEQ_DELAY83 - [3:0] */ +#define WM8995_WSEQ_DELAY83_WIDTH 4 /* WSEQ_DELAY83 - [3:0] */ + +/* + * R12624 (0x3150) - Write Sequencer 336 + */ +#define WM8995_WSEQ_ADDR84_MASK 0x3FFF /* WSEQ_ADDR84 - [13:0] */ +#define WM8995_WSEQ_ADDR84_SHIFT 0 /* WSEQ_ADDR84 - [13:0] */ +#define WM8995_WSEQ_ADDR84_WIDTH 14 /* WSEQ_ADDR84 - [13:0] */ + +/* + * R12625 (0x3151) - Write Sequencer 337 + */ +#define WM8995_WSEQ_DATA84_MASK 0x00FF /* WSEQ_DATA84 - [7:0] */ +#define WM8995_WSEQ_DATA84_SHIFT 0 /* WSEQ_DATA84 - [7:0] */ +#define WM8995_WSEQ_DATA84_WIDTH 8 /* WSEQ_DATA84 - [7:0] */ + +/* + * R12626 (0x3152) - Write Sequencer 338 + */ +#define WM8995_WSEQ_DATA_WIDTH84_MASK 0x0700 /* WSEQ_DATA_WIDTH84 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH84_SHIFT 8 /* WSEQ_DATA_WIDTH84 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH84_WIDTH 3 /* WSEQ_DATA_WIDTH84 - [10:8] */ +#define WM8995_WSEQ_DATA_START84_MASK 0x000F /* WSEQ_DATA_START84 - [3:0] */ +#define WM8995_WSEQ_DATA_START84_SHIFT 0 /* WSEQ_DATA_START84 - [3:0] */ +#define WM8995_WSEQ_DATA_START84_WIDTH 4 /* WSEQ_DATA_START84 - [3:0] */ + +/* + * R12627 (0x3153) - Write Sequencer 339 + */ +#define WM8995_WSEQ_EOS84 0x0100 /* WSEQ_EOS84 */ +#define WM8995_WSEQ_EOS84_MASK 0x0100 /* WSEQ_EOS84 */ +#define WM8995_WSEQ_EOS84_SHIFT 8 /* WSEQ_EOS84 */ +#define WM8995_WSEQ_EOS84_WIDTH 1 /* WSEQ_EOS84 */ +#define WM8995_WSEQ_DELAY84_MASK 0x000F /* WSEQ_DELAY84 - [3:0] */ +#define WM8995_WSEQ_DELAY84_SHIFT 0 /* WSEQ_DELAY84 - [3:0] */ +#define WM8995_WSEQ_DELAY84_WIDTH 4 /* WSEQ_DELAY84 - [3:0] */ + +/* + * R12628 (0x3154) - Write Sequencer 340 + */ +#define WM8995_WSEQ_ADDR85_MASK 0x3FFF /* WSEQ_ADDR85 - [13:0] */ +#define WM8995_WSEQ_ADDR85_SHIFT 0 /* WSEQ_ADDR85 - [13:0] */ +#define WM8995_WSEQ_ADDR85_WIDTH 14 /* WSEQ_ADDR85 - [13:0] */ + +/* + * R12629 (0x3155) - Write Sequencer 341 + */ +#define WM8995_WSEQ_DATA85_MASK 0x00FF /* WSEQ_DATA85 - [7:0] */ +#define WM8995_WSEQ_DATA85_SHIFT 0 /* WSEQ_DATA85 - [7:0] */ +#define WM8995_WSEQ_DATA85_WIDTH 8 /* WSEQ_DATA85 - [7:0] */ + +/* + * R12630 (0x3156) - Write Sequencer 342 + */ +#define WM8995_WSEQ_DATA_WIDTH85_MASK 0x0700 /* WSEQ_DATA_WIDTH85 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH85_SHIFT 8 /* WSEQ_DATA_WIDTH85 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH85_WIDTH 3 /* WSEQ_DATA_WIDTH85 - [10:8] */ +#define WM8995_WSEQ_DATA_START85_MASK 0x000F /* WSEQ_DATA_START85 - [3:0] */ +#define WM8995_WSEQ_DATA_START85_SHIFT 0 /* WSEQ_DATA_START85 - [3:0] */ +#define WM8995_WSEQ_DATA_START85_WIDTH 4 /* WSEQ_DATA_START85 - [3:0] */ + +/* + * R12631 (0x3157) - Write Sequencer 343 + */ +#define WM8995_WSEQ_EOS85 0x0100 /* WSEQ_EOS85 */ +#define WM8995_WSEQ_EOS85_MASK 0x0100 /* WSEQ_EOS85 */ +#define WM8995_WSEQ_EOS85_SHIFT 8 /* WSEQ_EOS85 */ +#define WM8995_WSEQ_EOS85_WIDTH 1 /* WSEQ_EOS85 */ +#define WM8995_WSEQ_DELAY85_MASK 0x000F /* WSEQ_DELAY85 - [3:0] */ +#define WM8995_WSEQ_DELAY85_SHIFT 0 /* WSEQ_DELAY85 - [3:0] */ +#define WM8995_WSEQ_DELAY85_WIDTH 4 /* WSEQ_DELAY85 - [3:0] */ + +/* + * R12632 (0x3158) - Write Sequencer 344 + */ +#define WM8995_WSEQ_ADDR86_MASK 0x3FFF /* WSEQ_ADDR86 - [13:0] */ +#define WM8995_WSEQ_ADDR86_SHIFT 0 /* WSEQ_ADDR86 - [13:0] */ +#define WM8995_WSEQ_ADDR86_WIDTH 14 /* WSEQ_ADDR86 - [13:0] */ + +/* + * R12633 (0x3159) - Write Sequencer 345 + */ +#define WM8995_WSEQ_DATA86_MASK 0x00FF /* WSEQ_DATA86 - [7:0] */ +#define WM8995_WSEQ_DATA86_SHIFT 0 /* WSEQ_DATA86 - [7:0] */ +#define WM8995_WSEQ_DATA86_WIDTH 8 /* WSEQ_DATA86 - [7:0] */ + +/* + * R12634 (0x315A) - Write Sequencer 346 + */ +#define WM8995_WSEQ_DATA_WIDTH86_MASK 0x0700 /* WSEQ_DATA_WIDTH86 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH86_SHIFT 8 /* WSEQ_DATA_WIDTH86 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH86_WIDTH 3 /* WSEQ_DATA_WIDTH86 - [10:8] */ +#define WM8995_WSEQ_DATA_START86_MASK 0x000F /* WSEQ_DATA_START86 - [3:0] */ +#define WM8995_WSEQ_DATA_START86_SHIFT 0 /* WSEQ_DATA_START86 - [3:0] */ +#define WM8995_WSEQ_DATA_START86_WIDTH 4 /* WSEQ_DATA_START86 - [3:0] */ + +/* + * R12635 (0x315B) - Write Sequencer 347 + */ +#define WM8995_WSEQ_EOS86 0x0100 /* WSEQ_EOS86 */ +#define WM8995_WSEQ_EOS86_MASK 0x0100 /* WSEQ_EOS86 */ +#define WM8995_WSEQ_EOS86_SHIFT 8 /* WSEQ_EOS86 */ +#define WM8995_WSEQ_EOS86_WIDTH 1 /* WSEQ_EOS86 */ +#define WM8995_WSEQ_DELAY86_MASK 0x000F /* WSEQ_DELAY86 - [3:0] */ +#define WM8995_WSEQ_DELAY86_SHIFT 0 /* WSEQ_DELAY86 - [3:0] */ +#define WM8995_WSEQ_DELAY86_WIDTH 4 /* WSEQ_DELAY86 - [3:0] */ + +/* + * R12636 (0x315C) - Write Sequencer 348 + */ +#define WM8995_WSEQ_ADDR87_MASK 0x3FFF /* WSEQ_ADDR87 - [13:0] */ +#define WM8995_WSEQ_ADDR87_SHIFT 0 /* WSEQ_ADDR87 - [13:0] */ +#define WM8995_WSEQ_ADDR87_WIDTH 14 /* WSEQ_ADDR87 - [13:0] */ + +/* + * R12637 (0x315D) - Write Sequencer 349 + */ +#define WM8995_WSEQ_DATA87_MASK 0x00FF /* WSEQ_DATA87 - [7:0] */ +#define WM8995_WSEQ_DATA87_SHIFT 0 /* WSEQ_DATA87 - [7:0] */ +#define WM8995_WSEQ_DATA87_WIDTH 8 /* WSEQ_DATA87 - [7:0] */ + +/* + * R12638 (0x315E) - Write Sequencer 350 + */ +#define WM8995_WSEQ_DATA_WIDTH87_MASK 0x0700 /* WSEQ_DATA_WIDTH87 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH87_SHIFT 8 /* WSEQ_DATA_WIDTH87 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH87_WIDTH 3 /* WSEQ_DATA_WIDTH87 - [10:8] */ +#define WM8995_WSEQ_DATA_START87_MASK 0x000F /* WSEQ_DATA_START87 - [3:0] */ +#define WM8995_WSEQ_DATA_START87_SHIFT 0 /* WSEQ_DATA_START87 - [3:0] */ +#define WM8995_WSEQ_DATA_START87_WIDTH 4 /* WSEQ_DATA_START87 - [3:0] */ + +/* + * R12639 (0x315F) - Write Sequencer 351 + */ +#define WM8995_WSEQ_EOS87 0x0100 /* WSEQ_EOS87 */ +#define WM8995_WSEQ_EOS87_MASK 0x0100 /* WSEQ_EOS87 */ +#define WM8995_WSEQ_EOS87_SHIFT 8 /* WSEQ_EOS87 */ +#define WM8995_WSEQ_EOS87_WIDTH 1 /* WSEQ_EOS87 */ +#define WM8995_WSEQ_DELAY87_MASK 0x000F /* WSEQ_DELAY87 - [3:0] */ +#define WM8995_WSEQ_DELAY87_SHIFT 0 /* WSEQ_DELAY87 - [3:0] */ +#define WM8995_WSEQ_DELAY87_WIDTH 4 /* WSEQ_DELAY87 - [3:0] */ + +/* + * R12640 (0x3160) - Write Sequencer 352 + */ +#define WM8995_WSEQ_ADDR88_MASK 0x3FFF /* WSEQ_ADDR88 - [13:0] */ +#define WM8995_WSEQ_ADDR88_SHIFT 0 /* WSEQ_ADDR88 - [13:0] */ +#define WM8995_WSEQ_ADDR88_WIDTH 14 /* WSEQ_ADDR88 - [13:0] */ + +/* + * R12641 (0x3161) - Write Sequencer 353 + */ +#define WM8995_WSEQ_DATA88_MASK 0x00FF /* WSEQ_DATA88 - [7:0] */ +#define WM8995_WSEQ_DATA88_SHIFT 0 /* WSEQ_DATA88 - [7:0] */ +#define WM8995_WSEQ_DATA88_WIDTH 8 /* WSEQ_DATA88 - [7:0] */ + +/* + * R12642 (0x3162) - Write Sequencer 354 + */ +#define WM8995_WSEQ_DATA_WIDTH88_MASK 0x0700 /* WSEQ_DATA_WIDTH88 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH88_SHIFT 8 /* WSEQ_DATA_WIDTH88 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH88_WIDTH 3 /* WSEQ_DATA_WIDTH88 - [10:8] */ +#define WM8995_WSEQ_DATA_START88_MASK 0x000F /* WSEQ_DATA_START88 - [3:0] */ +#define WM8995_WSEQ_DATA_START88_SHIFT 0 /* WSEQ_DATA_START88 - [3:0] */ +#define WM8995_WSEQ_DATA_START88_WIDTH 4 /* WSEQ_DATA_START88 - [3:0] */ + +/* + * R12643 (0x3163) - Write Sequencer 355 + */ +#define WM8995_WSEQ_EOS88 0x0100 /* WSEQ_EOS88 */ +#define WM8995_WSEQ_EOS88_MASK 0x0100 /* WSEQ_EOS88 */ +#define WM8995_WSEQ_EOS88_SHIFT 8 /* WSEQ_EOS88 */ +#define WM8995_WSEQ_EOS88_WIDTH 1 /* WSEQ_EOS88 */ +#define WM8995_WSEQ_DELAY88_MASK 0x000F /* WSEQ_DELAY88 - [3:0] */ +#define WM8995_WSEQ_DELAY88_SHIFT 0 /* WSEQ_DELAY88 - [3:0] */ +#define WM8995_WSEQ_DELAY88_WIDTH 4 /* WSEQ_DELAY88 - [3:0] */ + +/* + * R12644 (0x3164) - Write Sequencer 356 + */ +#define WM8995_WSEQ_ADDR89_MASK 0x3FFF /* WSEQ_ADDR89 - [13:0] */ +#define WM8995_WSEQ_ADDR89_SHIFT 0 /* WSEQ_ADDR89 - [13:0] */ +#define WM8995_WSEQ_ADDR89_WIDTH 14 /* WSEQ_ADDR89 - [13:0] */ + +/* + * R12645 (0x3165) - Write Sequencer 357 + */ +#define WM8995_WSEQ_DATA89_MASK 0x00FF /* WSEQ_DATA89 - [7:0] */ +#define WM8995_WSEQ_DATA89_SHIFT 0 /* WSEQ_DATA89 - [7:0] */ +#define WM8995_WSEQ_DATA89_WIDTH 8 /* WSEQ_DATA89 - [7:0] */ + +/* + * R12646 (0x3166) - Write Sequencer 358 + */ +#define WM8995_WSEQ_DATA_WIDTH89_MASK 0x0700 /* WSEQ_DATA_WIDTH89 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH89_SHIFT 8 /* WSEQ_DATA_WIDTH89 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH89_WIDTH 3 /* WSEQ_DATA_WIDTH89 - [10:8] */ +#define WM8995_WSEQ_DATA_START89_MASK 0x000F /* WSEQ_DATA_START89 - [3:0] */ +#define WM8995_WSEQ_DATA_START89_SHIFT 0 /* WSEQ_DATA_START89 - [3:0] */ +#define WM8995_WSEQ_DATA_START89_WIDTH 4 /* WSEQ_DATA_START89 - [3:0] */ + +/* + * R12647 (0x3167) - Write Sequencer 359 + */ +#define WM8995_WSEQ_EOS89 0x0100 /* WSEQ_EOS89 */ +#define WM8995_WSEQ_EOS89_MASK 0x0100 /* WSEQ_EOS89 */ +#define WM8995_WSEQ_EOS89_SHIFT 8 /* WSEQ_EOS89 */ +#define WM8995_WSEQ_EOS89_WIDTH 1 /* WSEQ_EOS89 */ +#define WM8995_WSEQ_DELAY89_MASK 0x000F /* WSEQ_DELAY89 - [3:0] */ +#define WM8995_WSEQ_DELAY89_SHIFT 0 /* WSEQ_DELAY89 - [3:0] */ +#define WM8995_WSEQ_DELAY89_WIDTH 4 /* WSEQ_DELAY89 - [3:0] */ + +/* + * R12648 (0x3168) - Write Sequencer 360 + */ +#define WM8995_WSEQ_ADDR90_MASK 0x3FFF /* WSEQ_ADDR90 - [13:0] */ +#define WM8995_WSEQ_ADDR90_SHIFT 0 /* WSEQ_ADDR90 - [13:0] */ +#define WM8995_WSEQ_ADDR90_WIDTH 14 /* WSEQ_ADDR90 - [13:0] */ + +/* + * R12649 (0x3169) - Write Sequencer 361 + */ +#define WM8995_WSEQ_DATA90_MASK 0x00FF /* WSEQ_DATA90 - [7:0] */ +#define WM8995_WSEQ_DATA90_SHIFT 0 /* WSEQ_DATA90 - [7:0] */ +#define WM8995_WSEQ_DATA90_WIDTH 8 /* WSEQ_DATA90 - [7:0] */ + +/* + * R12650 (0x316A) - Write Sequencer 362 + */ +#define WM8995_WSEQ_DATA_WIDTH90_MASK 0x0700 /* WSEQ_DATA_WIDTH90 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH90_SHIFT 8 /* WSEQ_DATA_WIDTH90 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH90_WIDTH 3 /* WSEQ_DATA_WIDTH90 - [10:8] */ +#define WM8995_WSEQ_DATA_START90_MASK 0x000F /* WSEQ_DATA_START90 - [3:0] */ +#define WM8995_WSEQ_DATA_START90_SHIFT 0 /* WSEQ_DATA_START90 - [3:0] */ +#define WM8995_WSEQ_DATA_START90_WIDTH 4 /* WSEQ_DATA_START90 - [3:0] */ + +/* + * R12651 (0x316B) - Write Sequencer 363 + */ +#define WM8995_WSEQ_EOS90 0x0100 /* WSEQ_EOS90 */ +#define WM8995_WSEQ_EOS90_MASK 0x0100 /* WSEQ_EOS90 */ +#define WM8995_WSEQ_EOS90_SHIFT 8 /* WSEQ_EOS90 */ +#define WM8995_WSEQ_EOS90_WIDTH 1 /* WSEQ_EOS90 */ +#define WM8995_WSEQ_DELAY90_MASK 0x000F /* WSEQ_DELAY90 - [3:0] */ +#define WM8995_WSEQ_DELAY90_SHIFT 0 /* WSEQ_DELAY90 - [3:0] */ +#define WM8995_WSEQ_DELAY90_WIDTH 4 /* WSEQ_DELAY90 - [3:0] */ + +/* + * R12652 (0x316C) - Write Sequencer 364 + */ +#define WM8995_WSEQ_ADDR91_MASK 0x3FFF /* WSEQ_ADDR91 - [13:0] */ +#define WM8995_WSEQ_ADDR91_SHIFT 0 /* WSEQ_ADDR91 - [13:0] */ +#define WM8995_WSEQ_ADDR91_WIDTH 14 /* WSEQ_ADDR91 - [13:0] */ + +/* + * R12653 (0x316D) - Write Sequencer 365 + */ +#define WM8995_WSEQ_DATA91_MASK 0x00FF /* WSEQ_DATA91 - [7:0] */ +#define WM8995_WSEQ_DATA91_SHIFT 0 /* WSEQ_DATA91 - [7:0] */ +#define WM8995_WSEQ_DATA91_WIDTH 8 /* WSEQ_DATA91 - [7:0] */ + +/* + * R12654 (0x316E) - Write Sequencer 366 + */ +#define WM8995_WSEQ_DATA_WIDTH91_MASK 0x0700 /* WSEQ_DATA_WIDTH91 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH91_SHIFT 8 /* WSEQ_DATA_WIDTH91 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH91_WIDTH 3 /* WSEQ_DATA_WIDTH91 - [10:8] */ +#define WM8995_WSEQ_DATA_START91_MASK 0x000F /* WSEQ_DATA_START91 - [3:0] */ +#define WM8995_WSEQ_DATA_START91_SHIFT 0 /* WSEQ_DATA_START91 - [3:0] */ +#define WM8995_WSEQ_DATA_START91_WIDTH 4 /* WSEQ_DATA_START91 - [3:0] */ + +/* + * R12655 (0x316F) - Write Sequencer 367 + */ +#define WM8995_WSEQ_EOS91 0x0100 /* WSEQ_EOS91 */ +#define WM8995_WSEQ_EOS91_MASK 0x0100 /* WSEQ_EOS91 */ +#define WM8995_WSEQ_EOS91_SHIFT 8 /* WSEQ_EOS91 */ +#define WM8995_WSEQ_EOS91_WIDTH 1 /* WSEQ_EOS91 */ +#define WM8995_WSEQ_DELAY91_MASK 0x000F /* WSEQ_DELAY91 - [3:0] */ +#define WM8995_WSEQ_DELAY91_SHIFT 0 /* WSEQ_DELAY91 - [3:0] */ +#define WM8995_WSEQ_DELAY91_WIDTH 4 /* WSEQ_DELAY91 - [3:0] */ + +/* + * R12656 (0x3170) - Write Sequencer 368 + */ +#define WM8995_WSEQ_ADDR92_MASK 0x3FFF /* WSEQ_ADDR92 - [13:0] */ +#define WM8995_WSEQ_ADDR92_SHIFT 0 /* WSEQ_ADDR92 - [13:0] */ +#define WM8995_WSEQ_ADDR92_WIDTH 14 /* WSEQ_ADDR92 - [13:0] */ + +/* + * R12657 (0x3171) - Write Sequencer 369 + */ +#define WM8995_WSEQ_DATA92_MASK 0x00FF /* WSEQ_DATA92 - [7:0] */ +#define WM8995_WSEQ_DATA92_SHIFT 0 /* WSEQ_DATA92 - [7:0] */ +#define WM8995_WSEQ_DATA92_WIDTH 8 /* WSEQ_DATA92 - [7:0] */ + +/* + * R12658 (0x3172) - Write Sequencer 370 + */ +#define WM8995_WSEQ_DATA_WIDTH92_MASK 0x0700 /* WSEQ_DATA_WIDTH92 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH92_SHIFT 8 /* WSEQ_DATA_WIDTH92 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH92_WIDTH 3 /* WSEQ_DATA_WIDTH92 - [10:8] */ +#define WM8995_WSEQ_DATA_START92_MASK 0x000F /* WSEQ_DATA_START92 - [3:0] */ +#define WM8995_WSEQ_DATA_START92_SHIFT 0 /* WSEQ_DATA_START92 - [3:0] */ +#define WM8995_WSEQ_DATA_START92_WIDTH 4 /* WSEQ_DATA_START92 - [3:0] */ + +/* + * R12659 (0x3173) - Write Sequencer 371 + */ +#define WM8995_WSEQ_EOS92 0x0100 /* WSEQ_EOS92 */ +#define WM8995_WSEQ_EOS92_MASK 0x0100 /* WSEQ_EOS92 */ +#define WM8995_WSEQ_EOS92_SHIFT 8 /* WSEQ_EOS92 */ +#define WM8995_WSEQ_EOS92_WIDTH 1 /* WSEQ_EOS92 */ +#define WM8995_WSEQ_DELAY92_MASK 0x000F /* WSEQ_DELAY92 - [3:0] */ +#define WM8995_WSEQ_DELAY92_SHIFT 0 /* WSEQ_DELAY92 - [3:0] */ +#define WM8995_WSEQ_DELAY92_WIDTH 4 /* WSEQ_DELAY92 - [3:0] */ + +/* + * R12660 (0x3174) - Write Sequencer 372 + */ +#define WM8995_WSEQ_ADDR93_MASK 0x3FFF /* WSEQ_ADDR93 - [13:0] */ +#define WM8995_WSEQ_ADDR93_SHIFT 0 /* WSEQ_ADDR93 - [13:0] */ +#define WM8995_WSEQ_ADDR93_WIDTH 14 /* WSEQ_ADDR93 - [13:0] */ + +/* + * R12661 (0x3175) - Write Sequencer 373 + */ +#define WM8995_WSEQ_DATA93_MASK 0x00FF /* WSEQ_DATA93 - [7:0] */ +#define WM8995_WSEQ_DATA93_SHIFT 0 /* WSEQ_DATA93 - [7:0] */ +#define WM8995_WSEQ_DATA93_WIDTH 8 /* WSEQ_DATA93 - [7:0] */ + +/* + * R12662 (0x3176) - Write Sequencer 374 + */ +#define WM8995_WSEQ_DATA_WIDTH93_MASK 0x0700 /* WSEQ_DATA_WIDTH93 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH93_SHIFT 8 /* WSEQ_DATA_WIDTH93 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH93_WIDTH 3 /* WSEQ_DATA_WIDTH93 - [10:8] */ +#define WM8995_WSEQ_DATA_START93_MASK 0x000F /* WSEQ_DATA_START93 - [3:0] */ +#define WM8995_WSEQ_DATA_START93_SHIFT 0 /* WSEQ_DATA_START93 - [3:0] */ +#define WM8995_WSEQ_DATA_START93_WIDTH 4 /* WSEQ_DATA_START93 - [3:0] */ + +/* + * R12663 (0x3177) - Write Sequencer 375 + */ +#define WM8995_WSEQ_EOS93 0x0100 /* WSEQ_EOS93 */ +#define WM8995_WSEQ_EOS93_MASK 0x0100 /* WSEQ_EOS93 */ +#define WM8995_WSEQ_EOS93_SHIFT 8 /* WSEQ_EOS93 */ +#define WM8995_WSEQ_EOS93_WIDTH 1 /* WSEQ_EOS93 */ +#define WM8995_WSEQ_DELAY93_MASK 0x000F /* WSEQ_DELAY93 - [3:0] */ +#define WM8995_WSEQ_DELAY93_SHIFT 0 /* WSEQ_DELAY93 - [3:0] */ +#define WM8995_WSEQ_DELAY93_WIDTH 4 /* WSEQ_DELAY93 - [3:0] */ + +/* + * R12664 (0x3178) - Write Sequencer 376 + */ +#define WM8995_WSEQ_ADDR94_MASK 0x3FFF /* WSEQ_ADDR94 - [13:0] */ +#define WM8995_WSEQ_ADDR94_SHIFT 0 /* WSEQ_ADDR94 - [13:0] */ +#define WM8995_WSEQ_ADDR94_WIDTH 14 /* WSEQ_ADDR94 - [13:0] */ + +/* + * R12665 (0x3179) - Write Sequencer 377 + */ +#define WM8995_WSEQ_DATA94_MASK 0x00FF /* WSEQ_DATA94 - [7:0] */ +#define WM8995_WSEQ_DATA94_SHIFT 0 /* WSEQ_DATA94 - [7:0] */ +#define WM8995_WSEQ_DATA94_WIDTH 8 /* WSEQ_DATA94 - [7:0] */ + +/* + * R12666 (0x317A) - Write Sequencer 378 + */ +#define WM8995_WSEQ_DATA_WIDTH94_MASK 0x0700 /* WSEQ_DATA_WIDTH94 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH94_SHIFT 8 /* WSEQ_DATA_WIDTH94 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH94_WIDTH 3 /* WSEQ_DATA_WIDTH94 - [10:8] */ +#define WM8995_WSEQ_DATA_START94_MASK 0x000F /* WSEQ_DATA_START94 - [3:0] */ +#define WM8995_WSEQ_DATA_START94_SHIFT 0 /* WSEQ_DATA_START94 - [3:0] */ +#define WM8995_WSEQ_DATA_START94_WIDTH 4 /* WSEQ_DATA_START94 - [3:0] */ + +/* + * R12667 (0x317B) - Write Sequencer 379 + */ +#define WM8995_WSEQ_EOS94 0x0100 /* WSEQ_EOS94 */ +#define WM8995_WSEQ_EOS94_MASK 0x0100 /* WSEQ_EOS94 */ +#define WM8995_WSEQ_EOS94_SHIFT 8 /* WSEQ_EOS94 */ +#define WM8995_WSEQ_EOS94_WIDTH 1 /* WSEQ_EOS94 */ +#define WM8995_WSEQ_DELAY94_MASK 0x000F /* WSEQ_DELAY94 - [3:0] */ +#define WM8995_WSEQ_DELAY94_SHIFT 0 /* WSEQ_DELAY94 - [3:0] */ +#define WM8995_WSEQ_DELAY94_WIDTH 4 /* WSEQ_DELAY94 - [3:0] */ + +/* + * R12668 (0x317C) - Write Sequencer 380 + */ +#define WM8995_WSEQ_ADDR95_MASK 0x3FFF /* WSEQ_ADDR95 - [13:0] */ +#define WM8995_WSEQ_ADDR95_SHIFT 0 /* WSEQ_ADDR95 - [13:0] */ +#define WM8995_WSEQ_ADDR95_WIDTH 14 /* WSEQ_ADDR95 - [13:0] */ + +/* + * R12669 (0x317D) - Write Sequencer 381 + */ +#define WM8995_WSEQ_DATA95_MASK 0x00FF /* WSEQ_DATA95 - [7:0] */ +#define WM8995_WSEQ_DATA95_SHIFT 0 /* WSEQ_DATA95 - [7:0] */ +#define WM8995_WSEQ_DATA95_WIDTH 8 /* WSEQ_DATA95 - [7:0] */ + +/* + * R12670 (0x317E) - Write Sequencer 382 + */ +#define WM8995_WSEQ_DATA_WIDTH95_MASK 0x0700 /* WSEQ_DATA_WIDTH95 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH95_SHIFT 8 /* WSEQ_DATA_WIDTH95 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH95_WIDTH 3 /* WSEQ_DATA_WIDTH95 - [10:8] */ +#define WM8995_WSEQ_DATA_START95_MASK 0x000F /* WSEQ_DATA_START95 - [3:0] */ +#define WM8995_WSEQ_DATA_START95_SHIFT 0 /* WSEQ_DATA_START95 - [3:0] */ +#define WM8995_WSEQ_DATA_START95_WIDTH 4 /* WSEQ_DATA_START95 - [3:0] */ + +/* + * R12671 (0x317F) - Write Sequencer 383 + */ +#define WM8995_WSEQ_EOS95 0x0100 /* WSEQ_EOS95 */ +#define WM8995_WSEQ_EOS95_MASK 0x0100 /* WSEQ_EOS95 */ +#define WM8995_WSEQ_EOS95_SHIFT 8 /* WSEQ_EOS95 */ +#define WM8995_WSEQ_EOS95_WIDTH 1 /* WSEQ_EOS95 */ +#define WM8995_WSEQ_DELAY95_MASK 0x000F /* WSEQ_DELAY95 - [3:0] */ +#define WM8995_WSEQ_DELAY95_SHIFT 0 /* WSEQ_DELAY95 - [3:0] */ +#define WM8995_WSEQ_DELAY95_WIDTH 4 /* WSEQ_DELAY95 - [3:0] */ + +/* + * R12672 (0x3180) - Write Sequencer 384 + */ +#define WM8995_WSEQ_ADDR96_MASK 0x3FFF /* WSEQ_ADDR96 - [13:0] */ +#define WM8995_WSEQ_ADDR96_SHIFT 0 /* WSEQ_ADDR96 - [13:0] */ +#define WM8995_WSEQ_ADDR96_WIDTH 14 /* WSEQ_ADDR96 - [13:0] */ + +/* + * R12673 (0x3181) - Write Sequencer 385 + */ +#define WM8995_WSEQ_DATA96_MASK 0x00FF /* WSEQ_DATA96 - [7:0] */ +#define WM8995_WSEQ_DATA96_SHIFT 0 /* WSEQ_DATA96 - [7:0] */ +#define WM8995_WSEQ_DATA96_WIDTH 8 /* WSEQ_DATA96 - [7:0] */ + +/* + * R12674 (0x3182) - Write Sequencer 386 + */ +#define WM8995_WSEQ_DATA_WIDTH96_MASK 0x0700 /* WSEQ_DATA_WIDTH96 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH96_SHIFT 8 /* WSEQ_DATA_WIDTH96 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH96_WIDTH 3 /* WSEQ_DATA_WIDTH96 - [10:8] */ +#define WM8995_WSEQ_DATA_START96_MASK 0x000F /* WSEQ_DATA_START96 - [3:0] */ +#define WM8995_WSEQ_DATA_START96_SHIFT 0 /* WSEQ_DATA_START96 - [3:0] */ +#define WM8995_WSEQ_DATA_START96_WIDTH 4 /* WSEQ_DATA_START96 - [3:0] */ + +/* + * R12675 (0x3183) - Write Sequencer 387 + */ +#define WM8995_WSEQ_EOS96 0x0100 /* WSEQ_EOS96 */ +#define WM8995_WSEQ_EOS96_MASK 0x0100 /* WSEQ_EOS96 */ +#define WM8995_WSEQ_EOS96_SHIFT 8 /* WSEQ_EOS96 */ +#define WM8995_WSEQ_EOS96_WIDTH 1 /* WSEQ_EOS96 */ +#define WM8995_WSEQ_DELAY96_MASK 0x000F /* WSEQ_DELAY96 - [3:0] */ +#define WM8995_WSEQ_DELAY96_SHIFT 0 /* WSEQ_DELAY96 - [3:0] */ +#define WM8995_WSEQ_DELAY96_WIDTH 4 /* WSEQ_DELAY96 - [3:0] */ + +/* + * R12676 (0x3184) - Write Sequencer 388 + */ +#define WM8995_WSEQ_ADDR97_MASK 0x3FFF /* WSEQ_ADDR97 - [13:0] */ +#define WM8995_WSEQ_ADDR97_SHIFT 0 /* WSEQ_ADDR97 - [13:0] */ +#define WM8995_WSEQ_ADDR97_WIDTH 14 /* WSEQ_ADDR97 - [13:0] */ + +/* + * R12677 (0x3185) - Write Sequencer 389 + */ +#define WM8995_WSEQ_DATA97_MASK 0x00FF /* WSEQ_DATA97 - [7:0] */ +#define WM8995_WSEQ_DATA97_SHIFT 0 /* WSEQ_DATA97 - [7:0] */ +#define WM8995_WSEQ_DATA97_WIDTH 8 /* WSEQ_DATA97 - [7:0] */ + +/* + * R12678 (0x3186) - Write Sequencer 390 + */ +#define WM8995_WSEQ_DATA_WIDTH97_MASK 0x0700 /* WSEQ_DATA_WIDTH97 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH97_SHIFT 8 /* WSEQ_DATA_WIDTH97 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH97_WIDTH 3 /* WSEQ_DATA_WIDTH97 - [10:8] */ +#define WM8995_WSEQ_DATA_START97_MASK 0x000F /* WSEQ_DATA_START97 - [3:0] */ +#define WM8995_WSEQ_DATA_START97_SHIFT 0 /* WSEQ_DATA_START97 - [3:0] */ +#define WM8995_WSEQ_DATA_START97_WIDTH 4 /* WSEQ_DATA_START97 - [3:0] */ + +/* + * R12679 (0x3187) - Write Sequencer 391 + */ +#define WM8995_WSEQ_EOS97 0x0100 /* WSEQ_EOS97 */ +#define WM8995_WSEQ_EOS97_MASK 0x0100 /* WSEQ_EOS97 */ +#define WM8995_WSEQ_EOS97_SHIFT 8 /* WSEQ_EOS97 */ +#define WM8995_WSEQ_EOS97_WIDTH 1 /* WSEQ_EOS97 */ +#define WM8995_WSEQ_DELAY97_MASK 0x000F /* WSEQ_DELAY97 - [3:0] */ +#define WM8995_WSEQ_DELAY97_SHIFT 0 /* WSEQ_DELAY97 - [3:0] */ +#define WM8995_WSEQ_DELAY97_WIDTH 4 /* WSEQ_DELAY97 - [3:0] */ + +/* + * R12680 (0x3188) - Write Sequencer 392 + */ +#define WM8995_WSEQ_ADDR98_MASK 0x3FFF /* WSEQ_ADDR98 - [13:0] */ +#define WM8995_WSEQ_ADDR98_SHIFT 0 /* WSEQ_ADDR98 - [13:0] */ +#define WM8995_WSEQ_ADDR98_WIDTH 14 /* WSEQ_ADDR98 - [13:0] */ + +/* + * R12681 (0x3189) - Write Sequencer 393 + */ +#define WM8995_WSEQ_DATA98_MASK 0x00FF /* WSEQ_DATA98 - [7:0] */ +#define WM8995_WSEQ_DATA98_SHIFT 0 /* WSEQ_DATA98 - [7:0] */ +#define WM8995_WSEQ_DATA98_WIDTH 8 /* WSEQ_DATA98 - [7:0] */ + +/* + * R12682 (0x318A) - Write Sequencer 394 + */ +#define WM8995_WSEQ_DATA_WIDTH98_MASK 0x0700 /* WSEQ_DATA_WIDTH98 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH98_SHIFT 8 /* WSEQ_DATA_WIDTH98 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH98_WIDTH 3 /* WSEQ_DATA_WIDTH98 - [10:8] */ +#define WM8995_WSEQ_DATA_START98_MASK 0x000F /* WSEQ_DATA_START98 - [3:0] */ +#define WM8995_WSEQ_DATA_START98_SHIFT 0 /* WSEQ_DATA_START98 - [3:0] */ +#define WM8995_WSEQ_DATA_START98_WIDTH 4 /* WSEQ_DATA_START98 - [3:0] */ + +/* + * R12683 (0x318B) - Write Sequencer 395 + */ +#define WM8995_WSEQ_EOS98 0x0100 /* WSEQ_EOS98 */ +#define WM8995_WSEQ_EOS98_MASK 0x0100 /* WSEQ_EOS98 */ +#define WM8995_WSEQ_EOS98_SHIFT 8 /* WSEQ_EOS98 */ +#define WM8995_WSEQ_EOS98_WIDTH 1 /* WSEQ_EOS98 */ +#define WM8995_WSEQ_DELAY98_MASK 0x000F /* WSEQ_DELAY98 - [3:0] */ +#define WM8995_WSEQ_DELAY98_SHIFT 0 /* WSEQ_DELAY98 - [3:0] */ +#define WM8995_WSEQ_DELAY98_WIDTH 4 /* WSEQ_DELAY98 - [3:0] */ + +/* + * R12684 (0x318C) - Write Sequencer 396 + */ +#define WM8995_WSEQ_ADDR99_MASK 0x3FFF /* WSEQ_ADDR99 - [13:0] */ +#define WM8995_WSEQ_ADDR99_SHIFT 0 /* WSEQ_ADDR99 - [13:0] */ +#define WM8995_WSEQ_ADDR99_WIDTH 14 /* WSEQ_ADDR99 - [13:0] */ + +/* + * R12685 (0x318D) - Write Sequencer 397 + */ +#define WM8995_WSEQ_DATA99_MASK 0x00FF /* WSEQ_DATA99 - [7:0] */ +#define WM8995_WSEQ_DATA99_SHIFT 0 /* WSEQ_DATA99 - [7:0] */ +#define WM8995_WSEQ_DATA99_WIDTH 8 /* WSEQ_DATA99 - [7:0] */ + +/* + * R12686 (0x318E) - Write Sequencer 398 + */ +#define WM8995_WSEQ_DATA_WIDTH99_MASK 0x0700 /* WSEQ_DATA_WIDTH99 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH99_SHIFT 8 /* WSEQ_DATA_WIDTH99 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH99_WIDTH 3 /* WSEQ_DATA_WIDTH99 - [10:8] */ +#define WM8995_WSEQ_DATA_START99_MASK 0x000F /* WSEQ_DATA_START99 - [3:0] */ +#define WM8995_WSEQ_DATA_START99_SHIFT 0 /* WSEQ_DATA_START99 - [3:0] */ +#define WM8995_WSEQ_DATA_START99_WIDTH 4 /* WSEQ_DATA_START99 - [3:0] */ + +/* + * R12687 (0x318F) - Write Sequencer 399 + */ +#define WM8995_WSEQ_EOS99 0x0100 /* WSEQ_EOS99 */ +#define WM8995_WSEQ_EOS99_MASK 0x0100 /* WSEQ_EOS99 */ +#define WM8995_WSEQ_EOS99_SHIFT 8 /* WSEQ_EOS99 */ +#define WM8995_WSEQ_EOS99_WIDTH 1 /* WSEQ_EOS99 */ +#define WM8995_WSEQ_DELAY99_MASK 0x000F /* WSEQ_DELAY99 - [3:0] */ +#define WM8995_WSEQ_DELAY99_SHIFT 0 /* WSEQ_DELAY99 - [3:0] */ +#define WM8995_WSEQ_DELAY99_WIDTH 4 /* WSEQ_DELAY99 - [3:0] */ + +/* + * R12688 (0x3190) - Write Sequencer 400 + */ +#define WM8995_WSEQ_ADDR100_MASK 0x3FFF /* WSEQ_ADDR100 - [13:0] */ +#define WM8995_WSEQ_ADDR100_SHIFT 0 /* WSEQ_ADDR100 - [13:0] */ +#define WM8995_WSEQ_ADDR100_WIDTH 14 /* WSEQ_ADDR100 - [13:0] */ + +/* + * R12689 (0x3191) - Write Sequencer 401 + */ +#define WM8995_WSEQ_DATA100_MASK 0x00FF /* WSEQ_DATA100 - [7:0] */ +#define WM8995_WSEQ_DATA100_SHIFT 0 /* WSEQ_DATA100 - [7:0] */ +#define WM8995_WSEQ_DATA100_WIDTH 8 /* WSEQ_DATA100 - [7:0] */ + +/* + * R12690 (0x3192) - Write Sequencer 402 + */ +#define WM8995_WSEQ_DATA_WIDTH100_MASK 0x0700 /* WSEQ_DATA_WIDTH100 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH100_SHIFT 8 /* WSEQ_DATA_WIDTH100 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH100_WIDTH 3 /* WSEQ_DATA_WIDTH100 - [10:8] */ +#define WM8995_WSEQ_DATA_START100_MASK 0x000F /* WSEQ_DATA_START100 - [3:0] */ +#define WM8995_WSEQ_DATA_START100_SHIFT 0 /* WSEQ_DATA_START100 - [3:0] */ +#define WM8995_WSEQ_DATA_START100_WIDTH 4 /* WSEQ_DATA_START100 - [3:0] */ + +/* + * R12691 (0x3193) - Write Sequencer 403 + */ +#define WM8995_WSEQ_EOS100 0x0100 /* WSEQ_EOS100 */ +#define WM8995_WSEQ_EOS100_MASK 0x0100 /* WSEQ_EOS100 */ +#define WM8995_WSEQ_EOS100_SHIFT 8 /* WSEQ_EOS100 */ +#define WM8995_WSEQ_EOS100_WIDTH 1 /* WSEQ_EOS100 */ +#define WM8995_WSEQ_DELAY100_MASK 0x000F /* WSEQ_DELAY100 - [3:0] */ +#define WM8995_WSEQ_DELAY100_SHIFT 0 /* WSEQ_DELAY100 - [3:0] */ +#define WM8995_WSEQ_DELAY100_WIDTH 4 /* WSEQ_DELAY100 - [3:0] */ + +/* + * R12692 (0x3194) - Write Sequencer 404 + */ +#define WM8995_WSEQ_ADDR101_MASK 0x3FFF /* WSEQ_ADDR101 - [13:0] */ +#define WM8995_WSEQ_ADDR101_SHIFT 0 /* WSEQ_ADDR101 - [13:0] */ +#define WM8995_WSEQ_ADDR101_WIDTH 14 /* WSEQ_ADDR101 - [13:0] */ + +/* + * R12693 (0x3195) - Write Sequencer 405 + */ +#define WM8995_WSEQ_DATA101_MASK 0x00FF /* WSEQ_DATA101 - [7:0] */ +#define WM8995_WSEQ_DATA101_SHIFT 0 /* WSEQ_DATA101 - [7:0] */ +#define WM8995_WSEQ_DATA101_WIDTH 8 /* WSEQ_DATA101 - [7:0] */ + +/* + * R12694 (0x3196) - Write Sequencer 406 + */ +#define WM8995_WSEQ_DATA_WIDTH101_MASK 0x0700 /* WSEQ_DATA_WIDTH101 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH101_SHIFT 8 /* WSEQ_DATA_WIDTH101 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH101_WIDTH 3 /* WSEQ_DATA_WIDTH101 - [10:8] */ +#define WM8995_WSEQ_DATA_START101_MASK 0x000F /* WSEQ_DATA_START101 - [3:0] */ +#define WM8995_WSEQ_DATA_START101_SHIFT 0 /* WSEQ_DATA_START101 - [3:0] */ +#define WM8995_WSEQ_DATA_START101_WIDTH 4 /* WSEQ_DATA_START101 - [3:0] */ + +/* + * R12695 (0x3197) - Write Sequencer 407 + */ +#define WM8995_WSEQ_EOS101 0x0100 /* WSEQ_EOS101 */ +#define WM8995_WSEQ_EOS101_MASK 0x0100 /* WSEQ_EOS101 */ +#define WM8995_WSEQ_EOS101_SHIFT 8 /* WSEQ_EOS101 */ +#define WM8995_WSEQ_EOS101_WIDTH 1 /* WSEQ_EOS101 */ +#define WM8995_WSEQ_DELAY101_MASK 0x000F /* WSEQ_DELAY101 - [3:0] */ +#define WM8995_WSEQ_DELAY101_SHIFT 0 /* WSEQ_DELAY101 - [3:0] */ +#define WM8995_WSEQ_DELAY101_WIDTH 4 /* WSEQ_DELAY101 - [3:0] */ + +/* + * R12696 (0x3198) - Write Sequencer 408 + */ +#define WM8995_WSEQ_ADDR102_MASK 0x3FFF /* WSEQ_ADDR102 - [13:0] */ +#define WM8995_WSEQ_ADDR102_SHIFT 0 /* WSEQ_ADDR102 - [13:0] */ +#define WM8995_WSEQ_ADDR102_WIDTH 14 /* WSEQ_ADDR102 - [13:0] */ + +/* + * R12697 (0x3199) - Write Sequencer 409 + */ +#define WM8995_WSEQ_DATA102_MASK 0x00FF /* WSEQ_DATA102 - [7:0] */ +#define WM8995_WSEQ_DATA102_SHIFT 0 /* WSEQ_DATA102 - [7:0] */ +#define WM8995_WSEQ_DATA102_WIDTH 8 /* WSEQ_DATA102 - [7:0] */ + +/* + * R12698 (0x319A) - Write Sequencer 410 + */ +#define WM8995_WSEQ_DATA_WIDTH102_MASK 0x0700 /* WSEQ_DATA_WIDTH102 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH102_SHIFT 8 /* WSEQ_DATA_WIDTH102 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH102_WIDTH 3 /* WSEQ_DATA_WIDTH102 - [10:8] */ +#define WM8995_WSEQ_DATA_START102_MASK 0x000F /* WSEQ_DATA_START102 - [3:0] */ +#define WM8995_WSEQ_DATA_START102_SHIFT 0 /* WSEQ_DATA_START102 - [3:0] */ +#define WM8995_WSEQ_DATA_START102_WIDTH 4 /* WSEQ_DATA_START102 - [3:0] */ + +/* + * R12699 (0x319B) - Write Sequencer 411 + */ +#define WM8995_WSEQ_EOS102 0x0100 /* WSEQ_EOS102 */ +#define WM8995_WSEQ_EOS102_MASK 0x0100 /* WSEQ_EOS102 */ +#define WM8995_WSEQ_EOS102_SHIFT 8 /* WSEQ_EOS102 */ +#define WM8995_WSEQ_EOS102_WIDTH 1 /* WSEQ_EOS102 */ +#define WM8995_WSEQ_DELAY102_MASK 0x000F /* WSEQ_DELAY102 - [3:0] */ +#define WM8995_WSEQ_DELAY102_SHIFT 0 /* WSEQ_DELAY102 - [3:0] */ +#define WM8995_WSEQ_DELAY102_WIDTH 4 /* WSEQ_DELAY102 - [3:0] */ + +/* + * R12700 (0x319C) - Write Sequencer 412 + */ +#define WM8995_WSEQ_ADDR103_MASK 0x3FFF /* WSEQ_ADDR103 - [13:0] */ +#define WM8995_WSEQ_ADDR103_SHIFT 0 /* WSEQ_ADDR103 - [13:0] */ +#define WM8995_WSEQ_ADDR103_WIDTH 14 /* WSEQ_ADDR103 - [13:0] */ + +/* + * R12701 (0x319D) - Write Sequencer 413 + */ +#define WM8995_WSEQ_DATA103_MASK 0x00FF /* WSEQ_DATA103 - [7:0] */ +#define WM8995_WSEQ_DATA103_SHIFT 0 /* WSEQ_DATA103 - [7:0] */ +#define WM8995_WSEQ_DATA103_WIDTH 8 /* WSEQ_DATA103 - [7:0] */ + +/* + * R12702 (0x319E) - Write Sequencer 414 + */ +#define WM8995_WSEQ_DATA_WIDTH103_MASK 0x0700 /* WSEQ_DATA_WIDTH103 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH103_SHIFT 8 /* WSEQ_DATA_WIDTH103 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH103_WIDTH 3 /* WSEQ_DATA_WIDTH103 - [10:8] */ +#define WM8995_WSEQ_DATA_START103_MASK 0x000F /* WSEQ_DATA_START103 - [3:0] */ +#define WM8995_WSEQ_DATA_START103_SHIFT 0 /* WSEQ_DATA_START103 - [3:0] */ +#define WM8995_WSEQ_DATA_START103_WIDTH 4 /* WSEQ_DATA_START103 - [3:0] */ + +/* + * R12703 (0x319F) - Write Sequencer 415 + */ +#define WM8995_WSEQ_EOS103 0x0100 /* WSEQ_EOS103 */ +#define WM8995_WSEQ_EOS103_MASK 0x0100 /* WSEQ_EOS103 */ +#define WM8995_WSEQ_EOS103_SHIFT 8 /* WSEQ_EOS103 */ +#define WM8995_WSEQ_EOS103_WIDTH 1 /* WSEQ_EOS103 */ +#define WM8995_WSEQ_DELAY103_MASK 0x000F /* WSEQ_DELAY103 - [3:0] */ +#define WM8995_WSEQ_DELAY103_SHIFT 0 /* WSEQ_DELAY103 - [3:0] */ +#define WM8995_WSEQ_DELAY103_WIDTH 4 /* WSEQ_DELAY103 - [3:0] */ + +/* + * R12704 (0x31A0) - Write Sequencer 416 + */ +#define WM8995_WSEQ_ADDR104_MASK 0x3FFF /* WSEQ_ADDR104 - [13:0] */ +#define WM8995_WSEQ_ADDR104_SHIFT 0 /* WSEQ_ADDR104 - [13:0] */ +#define WM8995_WSEQ_ADDR104_WIDTH 14 /* WSEQ_ADDR104 - [13:0] */ + +/* + * R12705 (0x31A1) - Write Sequencer 417 + */ +#define WM8995_WSEQ_DATA104_MASK 0x00FF /* WSEQ_DATA104 - [7:0] */ +#define WM8995_WSEQ_DATA104_SHIFT 0 /* WSEQ_DATA104 - [7:0] */ +#define WM8995_WSEQ_DATA104_WIDTH 8 /* WSEQ_DATA104 - [7:0] */ + +/* + * R12706 (0x31A2) - Write Sequencer 418 + */ +#define WM8995_WSEQ_DATA_WIDTH104_MASK 0x0700 /* WSEQ_DATA_WIDTH104 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH104_SHIFT 8 /* WSEQ_DATA_WIDTH104 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH104_WIDTH 3 /* WSEQ_DATA_WIDTH104 - [10:8] */ +#define WM8995_WSEQ_DATA_START104_MASK 0x000F /* WSEQ_DATA_START104 - [3:0] */ +#define WM8995_WSEQ_DATA_START104_SHIFT 0 /* WSEQ_DATA_START104 - [3:0] */ +#define WM8995_WSEQ_DATA_START104_WIDTH 4 /* WSEQ_DATA_START104 - [3:0] */ + +/* + * R12707 (0x31A3) - Write Sequencer 419 + */ +#define WM8995_WSEQ_EOS104 0x0100 /* WSEQ_EOS104 */ +#define WM8995_WSEQ_EOS104_MASK 0x0100 /* WSEQ_EOS104 */ +#define WM8995_WSEQ_EOS104_SHIFT 8 /* WSEQ_EOS104 */ +#define WM8995_WSEQ_EOS104_WIDTH 1 /* WSEQ_EOS104 */ +#define WM8995_WSEQ_DELAY104_MASK 0x000F /* WSEQ_DELAY104 - [3:0] */ +#define WM8995_WSEQ_DELAY104_SHIFT 0 /* WSEQ_DELAY104 - [3:0] */ +#define WM8995_WSEQ_DELAY104_WIDTH 4 /* WSEQ_DELAY104 - [3:0] */ + +/* + * R12708 (0x31A4) - Write Sequencer 420 + */ +#define WM8995_WSEQ_ADDR105_MASK 0x3FFF /* WSEQ_ADDR105 - [13:0] */ +#define WM8995_WSEQ_ADDR105_SHIFT 0 /* WSEQ_ADDR105 - [13:0] */ +#define WM8995_WSEQ_ADDR105_WIDTH 14 /* WSEQ_ADDR105 - [13:0] */ + +/* + * R12709 (0x31A5) - Write Sequencer 421 + */ +#define WM8995_WSEQ_DATA105_MASK 0x00FF /* WSEQ_DATA105 - [7:0] */ +#define WM8995_WSEQ_DATA105_SHIFT 0 /* WSEQ_DATA105 - [7:0] */ +#define WM8995_WSEQ_DATA105_WIDTH 8 /* WSEQ_DATA105 - [7:0] */ + +/* + * R12710 (0x31A6) - Write Sequencer 422 + */ +#define WM8995_WSEQ_DATA_WIDTH105_MASK 0x0700 /* WSEQ_DATA_WIDTH105 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH105_SHIFT 8 /* WSEQ_DATA_WIDTH105 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH105_WIDTH 3 /* WSEQ_DATA_WIDTH105 - [10:8] */ +#define WM8995_WSEQ_DATA_START105_MASK 0x000F /* WSEQ_DATA_START105 - [3:0] */ +#define WM8995_WSEQ_DATA_START105_SHIFT 0 /* WSEQ_DATA_START105 - [3:0] */ +#define WM8995_WSEQ_DATA_START105_WIDTH 4 /* WSEQ_DATA_START105 - [3:0] */ + +/* + * R12711 (0x31A7) - Write Sequencer 423 + */ +#define WM8995_WSEQ_EOS105 0x0100 /* WSEQ_EOS105 */ +#define WM8995_WSEQ_EOS105_MASK 0x0100 /* WSEQ_EOS105 */ +#define WM8995_WSEQ_EOS105_SHIFT 8 /* WSEQ_EOS105 */ +#define WM8995_WSEQ_EOS105_WIDTH 1 /* WSEQ_EOS105 */ +#define WM8995_WSEQ_DELAY105_MASK 0x000F /* WSEQ_DELAY105 - [3:0] */ +#define WM8995_WSEQ_DELAY105_SHIFT 0 /* WSEQ_DELAY105 - [3:0] */ +#define WM8995_WSEQ_DELAY105_WIDTH 4 /* WSEQ_DELAY105 - [3:0] */ + +/* + * R12712 (0x31A8) - Write Sequencer 424 + */ +#define WM8995_WSEQ_ADDR106_MASK 0x3FFF /* WSEQ_ADDR106 - [13:0] */ +#define WM8995_WSEQ_ADDR106_SHIFT 0 /* WSEQ_ADDR106 - [13:0] */ +#define WM8995_WSEQ_ADDR106_WIDTH 14 /* WSEQ_ADDR106 - [13:0] */ + +/* + * R12713 (0x31A9) - Write Sequencer 425 + */ +#define WM8995_WSEQ_DATA106_MASK 0x00FF /* WSEQ_DATA106 - [7:0] */ +#define WM8995_WSEQ_DATA106_SHIFT 0 /* WSEQ_DATA106 - [7:0] */ +#define WM8995_WSEQ_DATA106_WIDTH 8 /* WSEQ_DATA106 - [7:0] */ + +/* + * R12714 (0x31AA) - Write Sequencer 426 + */ +#define WM8995_WSEQ_DATA_WIDTH106_MASK 0x0700 /* WSEQ_DATA_WIDTH106 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH106_SHIFT 8 /* WSEQ_DATA_WIDTH106 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH106_WIDTH 3 /* WSEQ_DATA_WIDTH106 - [10:8] */ +#define WM8995_WSEQ_DATA_START106_MASK 0x000F /* WSEQ_DATA_START106 - [3:0] */ +#define WM8995_WSEQ_DATA_START106_SHIFT 0 /* WSEQ_DATA_START106 - [3:0] */ +#define WM8995_WSEQ_DATA_START106_WIDTH 4 /* WSEQ_DATA_START106 - [3:0] */ + +/* + * R12715 (0x31AB) - Write Sequencer 427 + */ +#define WM8995_WSEQ_EOS106 0x0100 /* WSEQ_EOS106 */ +#define WM8995_WSEQ_EOS106_MASK 0x0100 /* WSEQ_EOS106 */ +#define WM8995_WSEQ_EOS106_SHIFT 8 /* WSEQ_EOS106 */ +#define WM8995_WSEQ_EOS106_WIDTH 1 /* WSEQ_EOS106 */ +#define WM8995_WSEQ_DELAY106_MASK 0x000F /* WSEQ_DELAY106 - [3:0] */ +#define WM8995_WSEQ_DELAY106_SHIFT 0 /* WSEQ_DELAY106 - [3:0] */ +#define WM8995_WSEQ_DELAY106_WIDTH 4 /* WSEQ_DELAY106 - [3:0] */ + +/* + * R12716 (0x31AC) - Write Sequencer 428 + */ +#define WM8995_WSEQ_ADDR107_MASK 0x3FFF /* WSEQ_ADDR107 - [13:0] */ +#define WM8995_WSEQ_ADDR107_SHIFT 0 /* WSEQ_ADDR107 - [13:0] */ +#define WM8995_WSEQ_ADDR107_WIDTH 14 /* WSEQ_ADDR107 - [13:0] */ + +/* + * R12717 (0x31AD) - Write Sequencer 429 + */ +#define WM8995_WSEQ_DATA107_MASK 0x00FF /* WSEQ_DATA107 - [7:0] */ +#define WM8995_WSEQ_DATA107_SHIFT 0 /* WSEQ_DATA107 - [7:0] */ +#define WM8995_WSEQ_DATA107_WIDTH 8 /* WSEQ_DATA107 - [7:0] */ + +/* + * R12718 (0x31AE) - Write Sequencer 430 + */ +#define WM8995_WSEQ_DATA_WIDTH107_MASK 0x0700 /* WSEQ_DATA_WIDTH107 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH107_SHIFT 8 /* WSEQ_DATA_WIDTH107 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH107_WIDTH 3 /* WSEQ_DATA_WIDTH107 - [10:8] */ +#define WM8995_WSEQ_DATA_START107_MASK 0x000F /* WSEQ_DATA_START107 - [3:0] */ +#define WM8995_WSEQ_DATA_START107_SHIFT 0 /* WSEQ_DATA_START107 - [3:0] */ +#define WM8995_WSEQ_DATA_START107_WIDTH 4 /* WSEQ_DATA_START107 - [3:0] */ + +/* + * R12719 (0x31AF) - Write Sequencer 431 + */ +#define WM8995_WSEQ_EOS107 0x0100 /* WSEQ_EOS107 */ +#define WM8995_WSEQ_EOS107_MASK 0x0100 /* WSEQ_EOS107 */ +#define WM8995_WSEQ_EOS107_SHIFT 8 /* WSEQ_EOS107 */ +#define WM8995_WSEQ_EOS107_WIDTH 1 /* WSEQ_EOS107 */ +#define WM8995_WSEQ_DELAY107_MASK 0x000F /* WSEQ_DELAY107 - [3:0] */ +#define WM8995_WSEQ_DELAY107_SHIFT 0 /* WSEQ_DELAY107 - [3:0] */ +#define WM8995_WSEQ_DELAY107_WIDTH 4 /* WSEQ_DELAY107 - [3:0] */ + +/* + * R12720 (0x31B0) - Write Sequencer 432 + */ +#define WM8995_WSEQ_ADDR108_MASK 0x3FFF /* WSEQ_ADDR108 - [13:0] */ +#define WM8995_WSEQ_ADDR108_SHIFT 0 /* WSEQ_ADDR108 - [13:0] */ +#define WM8995_WSEQ_ADDR108_WIDTH 14 /* WSEQ_ADDR108 - [13:0] */ + +/* + * R12721 (0x31B1) - Write Sequencer 433 + */ +#define WM8995_WSEQ_DATA108_MASK 0x00FF /* WSEQ_DATA108 - [7:0] */ +#define WM8995_WSEQ_DATA108_SHIFT 0 /* WSEQ_DATA108 - [7:0] */ +#define WM8995_WSEQ_DATA108_WIDTH 8 /* WSEQ_DATA108 - [7:0] */ + +/* + * R12722 (0x31B2) - Write Sequencer 434 + */ +#define WM8995_WSEQ_DATA_WIDTH108_MASK 0x0700 /* WSEQ_DATA_WIDTH108 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH108_SHIFT 8 /* WSEQ_DATA_WIDTH108 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH108_WIDTH 3 /* WSEQ_DATA_WIDTH108 - [10:8] */ +#define WM8995_WSEQ_DATA_START108_MASK 0x000F /* WSEQ_DATA_START108 - [3:0] */ +#define WM8995_WSEQ_DATA_START108_SHIFT 0 /* WSEQ_DATA_START108 - [3:0] */ +#define WM8995_WSEQ_DATA_START108_WIDTH 4 /* WSEQ_DATA_START108 - [3:0] */ + +/* + * R12723 (0x31B3) - Write Sequencer 435 + */ +#define WM8995_WSEQ_EOS108 0x0100 /* WSEQ_EOS108 */ +#define WM8995_WSEQ_EOS108_MASK 0x0100 /* WSEQ_EOS108 */ +#define WM8995_WSEQ_EOS108_SHIFT 8 /* WSEQ_EOS108 */ +#define WM8995_WSEQ_EOS108_WIDTH 1 /* WSEQ_EOS108 */ +#define WM8995_WSEQ_DELAY108_MASK 0x000F /* WSEQ_DELAY108 - [3:0] */ +#define WM8995_WSEQ_DELAY108_SHIFT 0 /* WSEQ_DELAY108 - [3:0] */ +#define WM8995_WSEQ_DELAY108_WIDTH 4 /* WSEQ_DELAY108 - [3:0] */ + +/* + * R12724 (0x31B4) - Write Sequencer 436 + */ +#define WM8995_WSEQ_ADDR109_MASK 0x3FFF /* WSEQ_ADDR109 - [13:0] */ +#define WM8995_WSEQ_ADDR109_SHIFT 0 /* WSEQ_ADDR109 - [13:0] */ +#define WM8995_WSEQ_ADDR109_WIDTH 14 /* WSEQ_ADDR109 - [13:0] */ + +/* + * R12725 (0x31B5) - Write Sequencer 437 + */ +#define WM8995_WSEQ_DATA109_MASK 0x00FF /* WSEQ_DATA109 - [7:0] */ +#define WM8995_WSEQ_DATA109_SHIFT 0 /* WSEQ_DATA109 - [7:0] */ +#define WM8995_WSEQ_DATA109_WIDTH 8 /* WSEQ_DATA109 - [7:0] */ + +/* + * R12726 (0x31B6) - Write Sequencer 438 + */ +#define WM8995_WSEQ_DATA_WIDTH109_MASK 0x0700 /* WSEQ_DATA_WIDTH109 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH109_SHIFT 8 /* WSEQ_DATA_WIDTH109 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH109_WIDTH 3 /* WSEQ_DATA_WIDTH109 - [10:8] */ +#define WM8995_WSEQ_DATA_START109_MASK 0x000F /* WSEQ_DATA_START109 - [3:0] */ +#define WM8995_WSEQ_DATA_START109_SHIFT 0 /* WSEQ_DATA_START109 - [3:0] */ +#define WM8995_WSEQ_DATA_START109_WIDTH 4 /* WSEQ_DATA_START109 - [3:0] */ + +/* + * R12727 (0x31B7) - Write Sequencer 439 + */ +#define WM8995_WSEQ_EOS109 0x0100 /* WSEQ_EOS109 */ +#define WM8995_WSEQ_EOS109_MASK 0x0100 /* WSEQ_EOS109 */ +#define WM8995_WSEQ_EOS109_SHIFT 8 /* WSEQ_EOS109 */ +#define WM8995_WSEQ_EOS109_WIDTH 1 /* WSEQ_EOS109 */ +#define WM8995_WSEQ_DELAY109_MASK 0x000F /* WSEQ_DELAY109 - [3:0] */ +#define WM8995_WSEQ_DELAY109_SHIFT 0 /* WSEQ_DELAY109 - [3:0] */ +#define WM8995_WSEQ_DELAY109_WIDTH 4 /* WSEQ_DELAY109 - [3:0] */ + +/* + * R12728 (0x31B8) - Write Sequencer 440 + */ +#define WM8995_WSEQ_ADDR110_MASK 0x3FFF /* WSEQ_ADDR110 - [13:0] */ +#define WM8995_WSEQ_ADDR110_SHIFT 0 /* WSEQ_ADDR110 - [13:0] */ +#define WM8995_WSEQ_ADDR110_WIDTH 14 /* WSEQ_ADDR110 - [13:0] */ + +/* + * R12729 (0x31B9) - Write Sequencer 441 + */ +#define WM8995_WSEQ_DATA110_MASK 0x00FF /* WSEQ_DATA110 - [7:0] */ +#define WM8995_WSEQ_DATA110_SHIFT 0 /* WSEQ_DATA110 - [7:0] */ +#define WM8995_WSEQ_DATA110_WIDTH 8 /* WSEQ_DATA110 - [7:0] */ + +/* + * R12730 (0x31BA) - Write Sequencer 442 + */ +#define WM8995_WSEQ_DATA_WIDTH110_MASK 0x0700 /* WSEQ_DATA_WIDTH110 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH110_SHIFT 8 /* WSEQ_DATA_WIDTH110 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH110_WIDTH 3 /* WSEQ_DATA_WIDTH110 - [10:8] */ +#define WM8995_WSEQ_DATA_START110_MASK 0x000F /* WSEQ_DATA_START110 - [3:0] */ +#define WM8995_WSEQ_DATA_START110_SHIFT 0 /* WSEQ_DATA_START110 - [3:0] */ +#define WM8995_WSEQ_DATA_START110_WIDTH 4 /* WSEQ_DATA_START110 - [3:0] */ + +/* + * R12731 (0x31BB) - Write Sequencer 443 + */ +#define WM8995_WSEQ_EOS110 0x0100 /* WSEQ_EOS110 */ +#define WM8995_WSEQ_EOS110_MASK 0x0100 /* WSEQ_EOS110 */ +#define WM8995_WSEQ_EOS110_SHIFT 8 /* WSEQ_EOS110 */ +#define WM8995_WSEQ_EOS110_WIDTH 1 /* WSEQ_EOS110 */ +#define WM8995_WSEQ_DELAY110_MASK 0x000F /* WSEQ_DELAY110 - [3:0] */ +#define WM8995_WSEQ_DELAY110_SHIFT 0 /* WSEQ_DELAY110 - [3:0] */ +#define WM8995_WSEQ_DELAY110_WIDTH 4 /* WSEQ_DELAY110 - [3:0] */ + +/* + * R12732 (0x31BC) - Write Sequencer 444 + */ +#define WM8995_WSEQ_ADDR111_MASK 0x3FFF /* WSEQ_ADDR111 - [13:0] */ +#define WM8995_WSEQ_ADDR111_SHIFT 0 /* WSEQ_ADDR111 - [13:0] */ +#define WM8995_WSEQ_ADDR111_WIDTH 14 /* WSEQ_ADDR111 - [13:0] */ + +/* + * R12733 (0x31BD) - Write Sequencer 445 + */ +#define WM8995_WSEQ_DATA111_MASK 0x00FF /* WSEQ_DATA111 - [7:0] */ +#define WM8995_WSEQ_DATA111_SHIFT 0 /* WSEQ_DATA111 - [7:0] */ +#define WM8995_WSEQ_DATA111_WIDTH 8 /* WSEQ_DATA111 - [7:0] */ + +/* + * R12734 (0x31BE) - Write Sequencer 446 + */ +#define WM8995_WSEQ_DATA_WIDTH111_MASK 0x0700 /* WSEQ_DATA_WIDTH111 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH111_SHIFT 8 /* WSEQ_DATA_WIDTH111 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH111_WIDTH 3 /* WSEQ_DATA_WIDTH111 - [10:8] */ +#define WM8995_WSEQ_DATA_START111_MASK 0x000F /* WSEQ_DATA_START111 - [3:0] */ +#define WM8995_WSEQ_DATA_START111_SHIFT 0 /* WSEQ_DATA_START111 - [3:0] */ +#define WM8995_WSEQ_DATA_START111_WIDTH 4 /* WSEQ_DATA_START111 - [3:0] */ + +/* + * R12735 (0x31BF) - Write Sequencer 447 + */ +#define WM8995_WSEQ_EOS111 0x0100 /* WSEQ_EOS111 */ +#define WM8995_WSEQ_EOS111_MASK 0x0100 /* WSEQ_EOS111 */ +#define WM8995_WSEQ_EOS111_SHIFT 8 /* WSEQ_EOS111 */ +#define WM8995_WSEQ_EOS111_WIDTH 1 /* WSEQ_EOS111 */ +#define WM8995_WSEQ_DELAY111_MASK 0x000F /* WSEQ_DELAY111 - [3:0] */ +#define WM8995_WSEQ_DELAY111_SHIFT 0 /* WSEQ_DELAY111 - [3:0] */ +#define WM8995_WSEQ_DELAY111_WIDTH 4 /* WSEQ_DELAY111 - [3:0] */ + +/* + * R12736 (0x31C0) - Write Sequencer 448 + */ +#define WM8995_WSEQ_ADDR112_MASK 0x3FFF /* WSEQ_ADDR112 - [13:0] */ +#define WM8995_WSEQ_ADDR112_SHIFT 0 /* WSEQ_ADDR112 - [13:0] */ +#define WM8995_WSEQ_ADDR112_WIDTH 14 /* WSEQ_ADDR112 - [13:0] */ + +/* + * R12737 (0x31C1) - Write Sequencer 449 + */ +#define WM8995_WSEQ_DATA112_MASK 0x00FF /* WSEQ_DATA112 - [7:0] */ +#define WM8995_WSEQ_DATA112_SHIFT 0 /* WSEQ_DATA112 - [7:0] */ +#define WM8995_WSEQ_DATA112_WIDTH 8 /* WSEQ_DATA112 - [7:0] */ + +/* + * R12738 (0x31C2) - Write Sequencer 450 + */ +#define WM8995_WSEQ_DATA_WIDTH112_MASK 0x0700 /* WSEQ_DATA_WIDTH112 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH112_SHIFT 8 /* WSEQ_DATA_WIDTH112 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH112_WIDTH 3 /* WSEQ_DATA_WIDTH112 - [10:8] */ +#define WM8995_WSEQ_DATA_START112_MASK 0x000F /* WSEQ_DATA_START112 - [3:0] */ +#define WM8995_WSEQ_DATA_START112_SHIFT 0 /* WSEQ_DATA_START112 - [3:0] */ +#define WM8995_WSEQ_DATA_START112_WIDTH 4 /* WSEQ_DATA_START112 - [3:0] */ + +/* + * R12739 (0x31C3) - Write Sequencer 451 + */ +#define WM8995_WSEQ_EOS112 0x0100 /* WSEQ_EOS112 */ +#define WM8995_WSEQ_EOS112_MASK 0x0100 /* WSEQ_EOS112 */ +#define WM8995_WSEQ_EOS112_SHIFT 8 /* WSEQ_EOS112 */ +#define WM8995_WSEQ_EOS112_WIDTH 1 /* WSEQ_EOS112 */ +#define WM8995_WSEQ_DELAY112_MASK 0x000F /* WSEQ_DELAY112 - [3:0] */ +#define WM8995_WSEQ_DELAY112_SHIFT 0 /* WSEQ_DELAY112 - [3:0] */ +#define WM8995_WSEQ_DELAY112_WIDTH 4 /* WSEQ_DELAY112 - [3:0] */ + +/* + * R12740 (0x31C4) - Write Sequencer 452 + */ +#define WM8995_WSEQ_ADDR113_MASK 0x3FFF /* WSEQ_ADDR113 - [13:0] */ +#define WM8995_WSEQ_ADDR113_SHIFT 0 /* WSEQ_ADDR113 - [13:0] */ +#define WM8995_WSEQ_ADDR113_WIDTH 14 /* WSEQ_ADDR113 - [13:0] */ + +/* + * R12741 (0x31C5) - Write Sequencer 453 + */ +#define WM8995_WSEQ_DATA113_MASK 0x00FF /* WSEQ_DATA113 - [7:0] */ +#define WM8995_WSEQ_DATA113_SHIFT 0 /* WSEQ_DATA113 - [7:0] */ +#define WM8995_WSEQ_DATA113_WIDTH 8 /* WSEQ_DATA113 - [7:0] */ + +/* + * R12742 (0x31C6) - Write Sequencer 454 + */ +#define WM8995_WSEQ_DATA_WIDTH113_MASK 0x0700 /* WSEQ_DATA_WIDTH113 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH113_SHIFT 8 /* WSEQ_DATA_WIDTH113 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH113_WIDTH 3 /* WSEQ_DATA_WIDTH113 - [10:8] */ +#define WM8995_WSEQ_DATA_START113_MASK 0x000F /* WSEQ_DATA_START113 - [3:0] */ +#define WM8995_WSEQ_DATA_START113_SHIFT 0 /* WSEQ_DATA_START113 - [3:0] */ +#define WM8995_WSEQ_DATA_START113_WIDTH 4 /* WSEQ_DATA_START113 - [3:0] */ + +/* + * R12743 (0x31C7) - Write Sequencer 455 + */ +#define WM8995_WSEQ_EOS113 0x0100 /* WSEQ_EOS113 */ +#define WM8995_WSEQ_EOS113_MASK 0x0100 /* WSEQ_EOS113 */ +#define WM8995_WSEQ_EOS113_SHIFT 8 /* WSEQ_EOS113 */ +#define WM8995_WSEQ_EOS113_WIDTH 1 /* WSEQ_EOS113 */ +#define WM8995_WSEQ_DELAY113_MASK 0x000F /* WSEQ_DELAY113 - [3:0] */ +#define WM8995_WSEQ_DELAY113_SHIFT 0 /* WSEQ_DELAY113 - [3:0] */ +#define WM8995_WSEQ_DELAY113_WIDTH 4 /* WSEQ_DELAY113 - [3:0] */ + +/* + * R12744 (0x31C8) - Write Sequencer 456 + */ +#define WM8995_WSEQ_ADDR114_MASK 0x3FFF /* WSEQ_ADDR114 - [13:0] */ +#define WM8995_WSEQ_ADDR114_SHIFT 0 /* WSEQ_ADDR114 - [13:0] */ +#define WM8995_WSEQ_ADDR114_WIDTH 14 /* WSEQ_ADDR114 - [13:0] */ + +/* + * R12745 (0x31C9) - Write Sequencer 457 + */ +#define WM8995_WSEQ_DATA114_MASK 0x00FF /* WSEQ_DATA114 - [7:0] */ +#define WM8995_WSEQ_DATA114_SHIFT 0 /* WSEQ_DATA114 - [7:0] */ +#define WM8995_WSEQ_DATA114_WIDTH 8 /* WSEQ_DATA114 - [7:0] */ + +/* + * R12746 (0x31CA) - Write Sequencer 458 + */ +#define WM8995_WSEQ_DATA_WIDTH114_MASK 0x0700 /* WSEQ_DATA_WIDTH114 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH114_SHIFT 8 /* WSEQ_DATA_WIDTH114 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH114_WIDTH 3 /* WSEQ_DATA_WIDTH114 - [10:8] */ +#define WM8995_WSEQ_DATA_START114_MASK 0x000F /* WSEQ_DATA_START114 - [3:0] */ +#define WM8995_WSEQ_DATA_START114_SHIFT 0 /* WSEQ_DATA_START114 - [3:0] */ +#define WM8995_WSEQ_DATA_START114_WIDTH 4 /* WSEQ_DATA_START114 - [3:0] */ + +/* + * R12747 (0x31CB) - Write Sequencer 459 + */ +#define WM8995_WSEQ_EOS114 0x0100 /* WSEQ_EOS114 */ +#define WM8995_WSEQ_EOS114_MASK 0x0100 /* WSEQ_EOS114 */ +#define WM8995_WSEQ_EOS114_SHIFT 8 /* WSEQ_EOS114 */ +#define WM8995_WSEQ_EOS114_WIDTH 1 /* WSEQ_EOS114 */ +#define WM8995_WSEQ_DELAY114_MASK 0x000F /* WSEQ_DELAY114 - [3:0] */ +#define WM8995_WSEQ_DELAY114_SHIFT 0 /* WSEQ_DELAY114 - [3:0] */ +#define WM8995_WSEQ_DELAY114_WIDTH 4 /* WSEQ_DELAY114 - [3:0] */ + +/* + * R12748 (0x31CC) - Write Sequencer 460 + */ +#define WM8995_WSEQ_ADDR115_MASK 0x3FFF /* WSEQ_ADDR115 - [13:0] */ +#define WM8995_WSEQ_ADDR115_SHIFT 0 /* WSEQ_ADDR115 - [13:0] */ +#define WM8995_WSEQ_ADDR115_WIDTH 14 /* WSEQ_ADDR115 - [13:0] */ + +/* + * R12749 (0x31CD) - Write Sequencer 461 + */ +#define WM8995_WSEQ_DATA115_MASK 0x00FF /* WSEQ_DATA115 - [7:0] */ +#define WM8995_WSEQ_DATA115_SHIFT 0 /* WSEQ_DATA115 - [7:0] */ +#define WM8995_WSEQ_DATA115_WIDTH 8 /* WSEQ_DATA115 - [7:0] */ + +/* + * R12750 (0x31CE) - Write Sequencer 462 + */ +#define WM8995_WSEQ_DATA_WIDTH115_MASK 0x0700 /* WSEQ_DATA_WIDTH115 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH115_SHIFT 8 /* WSEQ_DATA_WIDTH115 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH115_WIDTH 3 /* WSEQ_DATA_WIDTH115 - [10:8] */ +#define WM8995_WSEQ_DATA_START115_MASK 0x000F /* WSEQ_DATA_START115 - [3:0] */ +#define WM8995_WSEQ_DATA_START115_SHIFT 0 /* WSEQ_DATA_START115 - [3:0] */ +#define WM8995_WSEQ_DATA_START115_WIDTH 4 /* WSEQ_DATA_START115 - [3:0] */ + +/* + * R12751 (0x31CF) - Write Sequencer 463 + */ +#define WM8995_WSEQ_EOS115 0x0100 /* WSEQ_EOS115 */ +#define WM8995_WSEQ_EOS115_MASK 0x0100 /* WSEQ_EOS115 */ +#define WM8995_WSEQ_EOS115_SHIFT 8 /* WSEQ_EOS115 */ +#define WM8995_WSEQ_EOS115_WIDTH 1 /* WSEQ_EOS115 */ +#define WM8995_WSEQ_DELAY115_MASK 0x000F /* WSEQ_DELAY115 - [3:0] */ +#define WM8995_WSEQ_DELAY115_SHIFT 0 /* WSEQ_DELAY115 - [3:0] */ +#define WM8995_WSEQ_DELAY115_WIDTH 4 /* WSEQ_DELAY115 - [3:0] */ + +/* + * R12752 (0x31D0) - Write Sequencer 464 + */ +#define WM8995_WSEQ_ADDR116_MASK 0x3FFF /* WSEQ_ADDR116 - [13:0] */ +#define WM8995_WSEQ_ADDR116_SHIFT 0 /* WSEQ_ADDR116 - [13:0] */ +#define WM8995_WSEQ_ADDR116_WIDTH 14 /* WSEQ_ADDR116 - [13:0] */ + +/* + * R12753 (0x31D1) - Write Sequencer 465 + */ +#define WM8995_WSEQ_DATA116_MASK 0x00FF /* WSEQ_DATA116 - [7:0] */ +#define WM8995_WSEQ_DATA116_SHIFT 0 /* WSEQ_DATA116 - [7:0] */ +#define WM8995_WSEQ_DATA116_WIDTH 8 /* WSEQ_DATA116 - [7:0] */ + +/* + * R12754 (0x31D2) - Write Sequencer 466 + */ +#define WM8995_WSEQ_DATA_WIDTH116_MASK 0x0700 /* WSEQ_DATA_WIDTH116 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH116_SHIFT 8 /* WSEQ_DATA_WIDTH116 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH116_WIDTH 3 /* WSEQ_DATA_WIDTH116 - [10:8] */ +#define WM8995_WSEQ_DATA_START116_MASK 0x000F /* WSEQ_DATA_START116 - [3:0] */ +#define WM8995_WSEQ_DATA_START116_SHIFT 0 /* WSEQ_DATA_START116 - [3:0] */ +#define WM8995_WSEQ_DATA_START116_WIDTH 4 /* WSEQ_DATA_START116 - [3:0] */ + +/* + * R12755 (0x31D3) - Write Sequencer 467 + */ +#define WM8995_WSEQ_EOS116 0x0100 /* WSEQ_EOS116 */ +#define WM8995_WSEQ_EOS116_MASK 0x0100 /* WSEQ_EOS116 */ +#define WM8995_WSEQ_EOS116_SHIFT 8 /* WSEQ_EOS116 */ +#define WM8995_WSEQ_EOS116_WIDTH 1 /* WSEQ_EOS116 */ +#define WM8995_WSEQ_DELAY116_MASK 0x000F /* WSEQ_DELAY116 - [3:0] */ +#define WM8995_WSEQ_DELAY116_SHIFT 0 /* WSEQ_DELAY116 - [3:0] */ +#define WM8995_WSEQ_DELAY116_WIDTH 4 /* WSEQ_DELAY116 - [3:0] */ + +/* + * R12756 (0x31D4) - Write Sequencer 468 + */ +#define WM8995_WSEQ_ADDR117_MASK 0x3FFF /* WSEQ_ADDR117 - [13:0] */ +#define WM8995_WSEQ_ADDR117_SHIFT 0 /* WSEQ_ADDR117 - [13:0] */ +#define WM8995_WSEQ_ADDR117_WIDTH 14 /* WSEQ_ADDR117 - [13:0] */ + +/* + * R12757 (0x31D5) - Write Sequencer 469 + */ +#define WM8995_WSEQ_DATA117_MASK 0x00FF /* WSEQ_DATA117 - [7:0] */ +#define WM8995_WSEQ_DATA117_SHIFT 0 /* WSEQ_DATA117 - [7:0] */ +#define WM8995_WSEQ_DATA117_WIDTH 8 /* WSEQ_DATA117 - [7:0] */ + +/* + * R12758 (0x31D6) - Write Sequencer 470 + */ +#define WM8995_WSEQ_DATA_WIDTH117_MASK 0x0700 /* WSEQ_DATA_WIDTH117 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH117_SHIFT 8 /* WSEQ_DATA_WIDTH117 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH117_WIDTH 3 /* WSEQ_DATA_WIDTH117 - [10:8] */ +#define WM8995_WSEQ_DATA_START117_MASK 0x000F /* WSEQ_DATA_START117 - [3:0] */ +#define WM8995_WSEQ_DATA_START117_SHIFT 0 /* WSEQ_DATA_START117 - [3:0] */ +#define WM8995_WSEQ_DATA_START117_WIDTH 4 /* WSEQ_DATA_START117 - [3:0] */ + +/* + * R12759 (0x31D7) - Write Sequencer 471 + */ +#define WM8995_WSEQ_EOS117 0x0100 /* WSEQ_EOS117 */ +#define WM8995_WSEQ_EOS117_MASK 0x0100 /* WSEQ_EOS117 */ +#define WM8995_WSEQ_EOS117_SHIFT 8 /* WSEQ_EOS117 */ +#define WM8995_WSEQ_EOS117_WIDTH 1 /* WSEQ_EOS117 */ +#define WM8995_WSEQ_DELAY117_MASK 0x000F /* WSEQ_DELAY117 - [3:0] */ +#define WM8995_WSEQ_DELAY117_SHIFT 0 /* WSEQ_DELAY117 - [3:0] */ +#define WM8995_WSEQ_DELAY117_WIDTH 4 /* WSEQ_DELAY117 - [3:0] */ + +/* + * R12760 (0x31D8) - Write Sequencer 472 + */ +#define WM8995_WSEQ_ADDR118_MASK 0x3FFF /* WSEQ_ADDR118 - [13:0] */ +#define WM8995_WSEQ_ADDR118_SHIFT 0 /* WSEQ_ADDR118 - [13:0] */ +#define WM8995_WSEQ_ADDR118_WIDTH 14 /* WSEQ_ADDR118 - [13:0] */ + +/* + * R12761 (0x31D9) - Write Sequencer 473 + */ +#define WM8995_WSEQ_DATA118_MASK 0x00FF /* WSEQ_DATA118 - [7:0] */ +#define WM8995_WSEQ_DATA118_SHIFT 0 /* WSEQ_DATA118 - [7:0] */ +#define WM8995_WSEQ_DATA118_WIDTH 8 /* WSEQ_DATA118 - [7:0] */ + +/* + * R12762 (0x31DA) - Write Sequencer 474 + */ +#define WM8995_WSEQ_DATA_WIDTH118_MASK 0x0700 /* WSEQ_DATA_WIDTH118 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH118_SHIFT 8 /* WSEQ_DATA_WIDTH118 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH118_WIDTH 3 /* WSEQ_DATA_WIDTH118 - [10:8] */ +#define WM8995_WSEQ_DATA_START118_MASK 0x000F /* WSEQ_DATA_START118 - [3:0] */ +#define WM8995_WSEQ_DATA_START118_SHIFT 0 /* WSEQ_DATA_START118 - [3:0] */ +#define WM8995_WSEQ_DATA_START118_WIDTH 4 /* WSEQ_DATA_START118 - [3:0] */ + +/* + * R12763 (0x31DB) - Write Sequencer 475 + */ +#define WM8995_WSEQ_EOS118 0x0100 /* WSEQ_EOS118 */ +#define WM8995_WSEQ_EOS118_MASK 0x0100 /* WSEQ_EOS118 */ +#define WM8995_WSEQ_EOS118_SHIFT 8 /* WSEQ_EOS118 */ +#define WM8995_WSEQ_EOS118_WIDTH 1 /* WSEQ_EOS118 */ +#define WM8995_WSEQ_DELAY118_MASK 0x000F /* WSEQ_DELAY118 - [3:0] */ +#define WM8995_WSEQ_DELAY118_SHIFT 0 /* WSEQ_DELAY118 - [3:0] */ +#define WM8995_WSEQ_DELAY118_WIDTH 4 /* WSEQ_DELAY118 - [3:0] */ + +/* + * R12764 (0x31DC) - Write Sequencer 476 + */ +#define WM8995_WSEQ_ADDR119_MASK 0x3FFF /* WSEQ_ADDR119 - [13:0] */ +#define WM8995_WSEQ_ADDR119_SHIFT 0 /* WSEQ_ADDR119 - [13:0] */ +#define WM8995_WSEQ_ADDR119_WIDTH 14 /* WSEQ_ADDR119 - [13:0] */ + +/* + * R12765 (0x31DD) - Write Sequencer 477 + */ +#define WM8995_WSEQ_DATA119_MASK 0x00FF /* WSEQ_DATA119 - [7:0] */ +#define WM8995_WSEQ_DATA119_SHIFT 0 /* WSEQ_DATA119 - [7:0] */ +#define WM8995_WSEQ_DATA119_WIDTH 8 /* WSEQ_DATA119 - [7:0] */ + +/* + * R12766 (0x31DE) - Write Sequencer 478 + */ +#define WM8995_WSEQ_DATA_WIDTH119_MASK 0x0700 /* WSEQ_DATA_WIDTH119 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH119_SHIFT 8 /* WSEQ_DATA_WIDTH119 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH119_WIDTH 3 /* WSEQ_DATA_WIDTH119 - [10:8] */ +#define WM8995_WSEQ_DATA_START119_MASK 0x000F /* WSEQ_DATA_START119 - [3:0] */ +#define WM8995_WSEQ_DATA_START119_SHIFT 0 /* WSEQ_DATA_START119 - [3:0] */ +#define WM8995_WSEQ_DATA_START119_WIDTH 4 /* WSEQ_DATA_START119 - [3:0] */ + +/* + * R12767 (0x31DF) - Write Sequencer 479 + */ +#define WM8995_WSEQ_EOS119 0x0100 /* WSEQ_EOS119 */ +#define WM8995_WSEQ_EOS119_MASK 0x0100 /* WSEQ_EOS119 */ +#define WM8995_WSEQ_EOS119_SHIFT 8 /* WSEQ_EOS119 */ +#define WM8995_WSEQ_EOS119_WIDTH 1 /* WSEQ_EOS119 */ +#define WM8995_WSEQ_DELAY119_MASK 0x000F /* WSEQ_DELAY119 - [3:0] */ +#define WM8995_WSEQ_DELAY119_SHIFT 0 /* WSEQ_DELAY119 - [3:0] */ +#define WM8995_WSEQ_DELAY119_WIDTH 4 /* WSEQ_DELAY119 - [3:0] */ + +/* + * R12768 (0x31E0) - Write Sequencer 480 + */ +#define WM8995_WSEQ_ADDR120_MASK 0x3FFF /* WSEQ_ADDR120 - [13:0] */ +#define WM8995_WSEQ_ADDR120_SHIFT 0 /* WSEQ_ADDR120 - [13:0] */ +#define WM8995_WSEQ_ADDR120_WIDTH 14 /* WSEQ_ADDR120 - [13:0] */ + +/* + * R12769 (0x31E1) - Write Sequencer 481 + */ +#define WM8995_WSEQ_DATA120_MASK 0x00FF /* WSEQ_DATA120 - [7:0] */ +#define WM8995_WSEQ_DATA120_SHIFT 0 /* WSEQ_DATA120 - [7:0] */ +#define WM8995_WSEQ_DATA120_WIDTH 8 /* WSEQ_DATA120 - [7:0] */ + +/* + * R12770 (0x31E2) - Write Sequencer 482 + */ +#define WM8995_WSEQ_DATA_WIDTH120_MASK 0x0700 /* WSEQ_DATA_WIDTH120 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH120_SHIFT 8 /* WSEQ_DATA_WIDTH120 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH120_WIDTH 3 /* WSEQ_DATA_WIDTH120 - [10:8] */ +#define WM8995_WSEQ_DATA_START120_MASK 0x000F /* WSEQ_DATA_START120 - [3:0] */ +#define WM8995_WSEQ_DATA_START120_SHIFT 0 /* WSEQ_DATA_START120 - [3:0] */ +#define WM8995_WSEQ_DATA_START120_WIDTH 4 /* WSEQ_DATA_START120 - [3:0] */ + +/* + * R12771 (0x31E3) - Write Sequencer 483 + */ +#define WM8995_WSEQ_EOS120 0x0100 /* WSEQ_EOS120 */ +#define WM8995_WSEQ_EOS120_MASK 0x0100 /* WSEQ_EOS120 */ +#define WM8995_WSEQ_EOS120_SHIFT 8 /* WSEQ_EOS120 */ +#define WM8995_WSEQ_EOS120_WIDTH 1 /* WSEQ_EOS120 */ +#define WM8995_WSEQ_DELAY120_MASK 0x000F /* WSEQ_DELAY120 - [3:0] */ +#define WM8995_WSEQ_DELAY120_SHIFT 0 /* WSEQ_DELAY120 - [3:0] */ +#define WM8995_WSEQ_DELAY120_WIDTH 4 /* WSEQ_DELAY120 - [3:0] */ + +/* + * R12772 (0x31E4) - Write Sequencer 484 + */ +#define WM8995_WSEQ_ADDR121_MASK 0x3FFF /* WSEQ_ADDR121 - [13:0] */ +#define WM8995_WSEQ_ADDR121_SHIFT 0 /* WSEQ_ADDR121 - [13:0] */ +#define WM8995_WSEQ_ADDR121_WIDTH 14 /* WSEQ_ADDR121 - [13:0] */ + +/* + * R12773 (0x31E5) - Write Sequencer 485 + */ +#define WM8995_WSEQ_DATA121_MASK 0x00FF /* WSEQ_DATA121 - [7:0] */ +#define WM8995_WSEQ_DATA121_SHIFT 0 /* WSEQ_DATA121 - [7:0] */ +#define WM8995_WSEQ_DATA121_WIDTH 8 /* WSEQ_DATA121 - [7:0] */ + +/* + * R12774 (0x31E6) - Write Sequencer 486 + */ +#define WM8995_WSEQ_DATA_WIDTH121_MASK 0x0700 /* WSEQ_DATA_WIDTH121 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH121_SHIFT 8 /* WSEQ_DATA_WIDTH121 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH121_WIDTH 3 /* WSEQ_DATA_WIDTH121 - [10:8] */ +#define WM8995_WSEQ_DATA_START121_MASK 0x000F /* WSEQ_DATA_START121 - [3:0] */ +#define WM8995_WSEQ_DATA_START121_SHIFT 0 /* WSEQ_DATA_START121 - [3:0] */ +#define WM8995_WSEQ_DATA_START121_WIDTH 4 /* WSEQ_DATA_START121 - [3:0] */ + +/* + * R12775 (0x31E7) - Write Sequencer 487 + */ +#define WM8995_WSEQ_EOS121 0x0100 /* WSEQ_EOS121 */ +#define WM8995_WSEQ_EOS121_MASK 0x0100 /* WSEQ_EOS121 */ +#define WM8995_WSEQ_EOS121_SHIFT 8 /* WSEQ_EOS121 */ +#define WM8995_WSEQ_EOS121_WIDTH 1 /* WSEQ_EOS121 */ +#define WM8995_WSEQ_DELAY121_MASK 0x000F /* WSEQ_DELAY121 - [3:0] */ +#define WM8995_WSEQ_DELAY121_SHIFT 0 /* WSEQ_DELAY121 - [3:0] */ +#define WM8995_WSEQ_DELAY121_WIDTH 4 /* WSEQ_DELAY121 - [3:0] */ + +/* + * R12776 (0x31E8) - Write Sequencer 488 + */ +#define WM8995_WSEQ_ADDR122_MASK 0x3FFF /* WSEQ_ADDR122 - [13:0] */ +#define WM8995_WSEQ_ADDR122_SHIFT 0 /* WSEQ_ADDR122 - [13:0] */ +#define WM8995_WSEQ_ADDR122_WIDTH 14 /* WSEQ_ADDR122 - [13:0] */ + +/* + * R12777 (0x31E9) - Write Sequencer 489 + */ +#define WM8995_WSEQ_DATA122_MASK 0x00FF /* WSEQ_DATA122 - [7:0] */ +#define WM8995_WSEQ_DATA122_SHIFT 0 /* WSEQ_DATA122 - [7:0] */ +#define WM8995_WSEQ_DATA122_WIDTH 8 /* WSEQ_DATA122 - [7:0] */ + +/* + * R12778 (0x31EA) - Write Sequencer 490 + */ +#define WM8995_WSEQ_DATA_WIDTH122_MASK 0x0700 /* WSEQ_DATA_WIDTH122 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH122_SHIFT 8 /* WSEQ_DATA_WIDTH122 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH122_WIDTH 3 /* WSEQ_DATA_WIDTH122 - [10:8] */ +#define WM8995_WSEQ_DATA_START122_MASK 0x000F /* WSEQ_DATA_START122 - [3:0] */ +#define WM8995_WSEQ_DATA_START122_SHIFT 0 /* WSEQ_DATA_START122 - [3:0] */ +#define WM8995_WSEQ_DATA_START122_WIDTH 4 /* WSEQ_DATA_START122 - [3:0] */ + +/* + * R12779 (0x31EB) - Write Sequencer 491 + */ +#define WM8995_WSEQ_EOS122 0x0100 /* WSEQ_EOS122 */ +#define WM8995_WSEQ_EOS122_MASK 0x0100 /* WSEQ_EOS122 */ +#define WM8995_WSEQ_EOS122_SHIFT 8 /* WSEQ_EOS122 */ +#define WM8995_WSEQ_EOS122_WIDTH 1 /* WSEQ_EOS122 */ +#define WM8995_WSEQ_DELAY122_MASK 0x000F /* WSEQ_DELAY122 - [3:0] */ +#define WM8995_WSEQ_DELAY122_SHIFT 0 /* WSEQ_DELAY122 - [3:0] */ +#define WM8995_WSEQ_DELAY122_WIDTH 4 /* WSEQ_DELAY122 - [3:0] */ + +/* + * R12780 (0x31EC) - Write Sequencer 492 + */ +#define WM8995_WSEQ_ADDR123_MASK 0x3FFF /* WSEQ_ADDR123 - [13:0] */ +#define WM8995_WSEQ_ADDR123_SHIFT 0 /* WSEQ_ADDR123 - [13:0] */ +#define WM8995_WSEQ_ADDR123_WIDTH 14 /* WSEQ_ADDR123 - [13:0] */ + +/* + * R12781 (0x31ED) - Write Sequencer 493 + */ +#define WM8995_WSEQ_DATA123_MASK 0x00FF /* WSEQ_DATA123 - [7:0] */ +#define WM8995_WSEQ_DATA123_SHIFT 0 /* WSEQ_DATA123 - [7:0] */ +#define WM8995_WSEQ_DATA123_WIDTH 8 /* WSEQ_DATA123 - [7:0] */ + +/* + * R12782 (0x31EE) - Write Sequencer 494 + */ +#define WM8995_WSEQ_DATA_WIDTH123_MASK 0x0700 /* WSEQ_DATA_WIDTH123 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH123_SHIFT 8 /* WSEQ_DATA_WIDTH123 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH123_WIDTH 3 /* WSEQ_DATA_WIDTH123 - [10:8] */ +#define WM8995_WSEQ_DATA_START123_MASK 0x000F /* WSEQ_DATA_START123 - [3:0] */ +#define WM8995_WSEQ_DATA_START123_SHIFT 0 /* WSEQ_DATA_START123 - [3:0] */ +#define WM8995_WSEQ_DATA_START123_WIDTH 4 /* WSEQ_DATA_START123 - [3:0] */ + +/* + * R12783 (0x31EF) - Write Sequencer 495 + */ +#define WM8995_WSEQ_EOS123 0x0100 /* WSEQ_EOS123 */ +#define WM8995_WSEQ_EOS123_MASK 0x0100 /* WSEQ_EOS123 */ +#define WM8995_WSEQ_EOS123_SHIFT 8 /* WSEQ_EOS123 */ +#define WM8995_WSEQ_EOS123_WIDTH 1 /* WSEQ_EOS123 */ +#define WM8995_WSEQ_DELAY123_MASK 0x000F /* WSEQ_DELAY123 - [3:0] */ +#define WM8995_WSEQ_DELAY123_SHIFT 0 /* WSEQ_DELAY123 - [3:0] */ +#define WM8995_WSEQ_DELAY123_WIDTH 4 /* WSEQ_DELAY123 - [3:0] */ + +/* + * R12784 (0x31F0) - Write Sequencer 496 + */ +#define WM8995_WSEQ_ADDR124_MASK 0x3FFF /* WSEQ_ADDR124 - [13:0] */ +#define WM8995_WSEQ_ADDR124_SHIFT 0 /* WSEQ_ADDR124 - [13:0] */ +#define WM8995_WSEQ_ADDR124_WIDTH 14 /* WSEQ_ADDR124 - [13:0] */ + +/* + * R12785 (0x31F1) - Write Sequencer 497 + */ +#define WM8995_WSEQ_DATA124_MASK 0x00FF /* WSEQ_DATA124 - [7:0] */ +#define WM8995_WSEQ_DATA124_SHIFT 0 /* WSEQ_DATA124 - [7:0] */ +#define WM8995_WSEQ_DATA124_WIDTH 8 /* WSEQ_DATA124 - [7:0] */ + +/* + * R12786 (0x31F2) - Write Sequencer 498 + */ +#define WM8995_WSEQ_DATA_WIDTH124_MASK 0x0700 /* WSEQ_DATA_WIDTH124 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH124_SHIFT 8 /* WSEQ_DATA_WIDTH124 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH124_WIDTH 3 /* WSEQ_DATA_WIDTH124 - [10:8] */ +#define WM8995_WSEQ_DATA_START124_MASK 0x000F /* WSEQ_DATA_START124 - [3:0] */ +#define WM8995_WSEQ_DATA_START124_SHIFT 0 /* WSEQ_DATA_START124 - [3:0] */ +#define WM8995_WSEQ_DATA_START124_WIDTH 4 /* WSEQ_DATA_START124 - [3:0] */ + +/* + * R12787 (0x31F3) - Write Sequencer 499 + */ +#define WM8995_WSEQ_EOS124 0x0100 /* WSEQ_EOS124 */ +#define WM8995_WSEQ_EOS124_MASK 0x0100 /* WSEQ_EOS124 */ +#define WM8995_WSEQ_EOS124_SHIFT 8 /* WSEQ_EOS124 */ +#define WM8995_WSEQ_EOS124_WIDTH 1 /* WSEQ_EOS124 */ +#define WM8995_WSEQ_DELAY124_MASK 0x000F /* WSEQ_DELAY124 - [3:0] */ +#define WM8995_WSEQ_DELAY124_SHIFT 0 /* WSEQ_DELAY124 - [3:0] */ +#define WM8995_WSEQ_DELAY124_WIDTH 4 /* WSEQ_DELAY124 - [3:0] */ + +/* + * R12788 (0x31F4) - Write Sequencer 500 + */ +#define WM8995_WSEQ_ADDR125_MASK 0x3FFF /* WSEQ_ADDR125 - [13:0] */ +#define WM8995_WSEQ_ADDR125_SHIFT 0 /* WSEQ_ADDR125 - [13:0] */ +#define WM8995_WSEQ_ADDR125_WIDTH 14 /* WSEQ_ADDR125 - [13:0] */ + +/* + * R12789 (0x31F5) - Write Sequencer 501 + */ +#define WM8995_WSEQ_DATA125_MASK 0x00FF /* WSEQ_DATA125 - [7:0] */ +#define WM8995_WSEQ_DATA125_SHIFT 0 /* WSEQ_DATA125 - [7:0] */ +#define WM8995_WSEQ_DATA125_WIDTH 8 /* WSEQ_DATA125 - [7:0] */ + +/* + * R12790 (0x31F6) - Write Sequencer 502 + */ +#define WM8995_WSEQ_DATA_WIDTH125_MASK 0x0700 /* WSEQ_DATA_WIDTH125 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH125_SHIFT 8 /* WSEQ_DATA_WIDTH125 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH125_WIDTH 3 /* WSEQ_DATA_WIDTH125 - [10:8] */ +#define WM8995_WSEQ_DATA_START125_MASK 0x000F /* WSEQ_DATA_START125 - [3:0] */ +#define WM8995_WSEQ_DATA_START125_SHIFT 0 /* WSEQ_DATA_START125 - [3:0] */ +#define WM8995_WSEQ_DATA_START125_WIDTH 4 /* WSEQ_DATA_START125 - [3:0] */ + +/* + * R12791 (0x31F7) - Write Sequencer 503 + */ +#define WM8995_WSEQ_EOS125 0x0100 /* WSEQ_EOS125 */ +#define WM8995_WSEQ_EOS125_MASK 0x0100 /* WSEQ_EOS125 */ +#define WM8995_WSEQ_EOS125_SHIFT 8 /* WSEQ_EOS125 */ +#define WM8995_WSEQ_EOS125_WIDTH 1 /* WSEQ_EOS125 */ +#define WM8995_WSEQ_DELAY125_MASK 0x000F /* WSEQ_DELAY125 - [3:0] */ +#define WM8995_WSEQ_DELAY125_SHIFT 0 /* WSEQ_DELAY125 - [3:0] */ +#define WM8995_WSEQ_DELAY125_WIDTH 4 /* WSEQ_DELAY125 - [3:0] */ + +/* + * R12792 (0x31F8) - Write Sequencer 504 + */ +#define WM8995_WSEQ_ADDR126_MASK 0x3FFF /* WSEQ_ADDR126 - [13:0] */ +#define WM8995_WSEQ_ADDR126_SHIFT 0 /* WSEQ_ADDR126 - [13:0] */ +#define WM8995_WSEQ_ADDR126_WIDTH 14 /* WSEQ_ADDR126 - [13:0] */ + +/* + * R12793 (0x31F9) - Write Sequencer 505 + */ +#define WM8995_WSEQ_DATA126_MASK 0x00FF /* WSEQ_DATA126 - [7:0] */ +#define WM8995_WSEQ_DATA126_SHIFT 0 /* WSEQ_DATA126 - [7:0] */ +#define WM8995_WSEQ_DATA126_WIDTH 8 /* WSEQ_DATA126 - [7:0] */ + +/* + * R12794 (0x31FA) - Write Sequencer 506 + */ +#define WM8995_WSEQ_DATA_WIDTH126_MASK 0x0700 /* WSEQ_DATA_WIDTH126 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH126_SHIFT 8 /* WSEQ_DATA_WIDTH126 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH126_WIDTH 3 /* WSEQ_DATA_WIDTH126 - [10:8] */ +#define WM8995_WSEQ_DATA_START126_MASK 0x000F /* WSEQ_DATA_START126 - [3:0] */ +#define WM8995_WSEQ_DATA_START126_SHIFT 0 /* WSEQ_DATA_START126 - [3:0] */ +#define WM8995_WSEQ_DATA_START126_WIDTH 4 /* WSEQ_DATA_START126 - [3:0] */ + +/* + * R12795 (0x31FB) - Write Sequencer 507 + */ +#define WM8995_WSEQ_EOS126 0x0100 /* WSEQ_EOS126 */ +#define WM8995_WSEQ_EOS126_MASK 0x0100 /* WSEQ_EOS126 */ +#define WM8995_WSEQ_EOS126_SHIFT 8 /* WSEQ_EOS126 */ +#define WM8995_WSEQ_EOS126_WIDTH 1 /* WSEQ_EOS126 */ +#define WM8995_WSEQ_DELAY126_MASK 0x000F /* WSEQ_DELAY126 - [3:0] */ +#define WM8995_WSEQ_DELAY126_SHIFT 0 /* WSEQ_DELAY126 - [3:0] */ +#define WM8995_WSEQ_DELAY126_WIDTH 4 /* WSEQ_DELAY126 - [3:0] */ + +/* + * R12796 (0x31FC) - Write Sequencer 508 + */ +#define WM8995_WSEQ_ADDR127_MASK 0x3FFF /* WSEQ_ADDR127 - [13:0] */ +#define WM8995_WSEQ_ADDR127_SHIFT 0 /* WSEQ_ADDR127 - [13:0] */ +#define WM8995_WSEQ_ADDR127_WIDTH 14 /* WSEQ_ADDR127 - [13:0] */ + +/* + * R12797 (0x31FD) - Write Sequencer 509 + */ +#define WM8995_WSEQ_DATA127_MASK 0x00FF /* WSEQ_DATA127 - [7:0] */ +#define WM8995_WSEQ_DATA127_SHIFT 0 /* WSEQ_DATA127 - [7:0] */ +#define WM8995_WSEQ_DATA127_WIDTH 8 /* WSEQ_DATA127 - [7:0] */ + +/* + * R12798 (0x31FE) - Write Sequencer 510 + */ +#define WM8995_WSEQ_DATA_WIDTH127_MASK 0x0700 /* WSEQ_DATA_WIDTH127 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH127_SHIFT 8 /* WSEQ_DATA_WIDTH127 - [10:8] */ +#define WM8995_WSEQ_DATA_WIDTH127_WIDTH 3 /* WSEQ_DATA_WIDTH127 - [10:8] */ +#define WM8995_WSEQ_DATA_START127_MASK 0x000F /* WSEQ_DATA_START127 - [3:0] */ +#define WM8995_WSEQ_DATA_START127_SHIFT 0 /* WSEQ_DATA_START127 - [3:0] */ +#define WM8995_WSEQ_DATA_START127_WIDTH 4 /* WSEQ_DATA_START127 - [3:0] */ + +/* + * R12799 (0x31FF) - Write Sequencer 511 + */ +#define WM8995_WSEQ_EOS127 0x0100 /* WSEQ_EOS127 */ +#define WM8995_WSEQ_EOS127_MASK 0x0100 /* WSEQ_EOS127 */ +#define WM8995_WSEQ_EOS127_SHIFT 8 /* WSEQ_EOS127 */ +#define WM8995_WSEQ_EOS127_WIDTH 1 /* WSEQ_EOS127 */ +#define WM8995_WSEQ_DELAY127_MASK 0x000F /* WSEQ_DELAY127 - [3:0] */ +#define WM8995_WSEQ_DELAY127_SHIFT 0 /* WSEQ_DELAY127 - [3:0] */ +#define WM8995_WSEQ_DELAY127_WIDTH 4 /* WSEQ_DELAY127 - [3:0] */ + +#define WM8995_CLASS_W_SWITCH(xname, reg, shift, max, invert) \ +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ + .info = snd_soc_info_volsw, \ + .get = snd_soc_dapm_get_volsw, .put = wm8995_put_class_w, \ + .private_value = SOC_SINGLE_VALUE(reg, shift, max, invert) \ +} + +struct wm8995_reg_access { + u16 read; + u16 write; + u16 vol; +}; + +/* Sources for AIF1/2 SYSCLK - use with set_dai_sysclk() */ +enum clk_src { + WM8995_SYSCLK_MCLK1 = 1, + WM8995_SYSCLK_MCLK2, + WM8995_SYSCLK_FLL1, + WM8995_SYSCLK_FLL2, + WM8995_SYSCLK_OPCLK +}; + +#define WM8995_FLL1 1 +#define WM8995_FLL2 2 + +#define WM8995_FLL_SRC_MCLK1 1 +#define WM8995_FLL_SRC_MCLK2 2 +#define WM8995_FLL_SRC_LRCLK 3 +#define WM8995_FLL_SRC_BCLK 4 + +#endif /* _WM8995_H */ -- cgit v1.2.3 From 8844355df7f4e091b03cc131e1549631238b397b Mon Sep 17 00:00:00 2001 From: Li Zefan Date: Mon, 25 Oct 2010 15:11:43 +0800 Subject: btrfs: Fix bugs in zlib workspace - Fix a race that can result in alloc_workspace > cpus. - Fix to check num_workspace after wakeup. Signed-off-by: Li Zefan --- fs/btrfs/zlib.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/fs/btrfs/zlib.c b/fs/btrfs/zlib.c index b9cd5445f71c..e5b8b22e07d6 100644 --- a/fs/btrfs/zlib.c +++ b/fs/btrfs/zlib.c @@ -75,16 +75,19 @@ again: return workspace; } - spin_unlock(&workspace_lock); if (atomic_read(&alloc_workspace) > cpus) { DEFINE_WAIT(wait); + + spin_unlock(&workspace_lock); prepare_to_wait(&workspace_wait, &wait, TASK_UNINTERRUPTIBLE); - if (atomic_read(&alloc_workspace) > cpus) + if (atomic_read(&alloc_workspace) > cpus && !num_workspace) schedule(); finish_wait(&workspace_wait, &wait); goto again; } atomic_inc(&alloc_workspace); + spin_unlock(&workspace_lock); + workspace = kzalloc(sizeof(*workspace), GFP_NOFS); if (!workspace) { ret = -ENOMEM; -- cgit v1.2.3 From 4b72029dc3fd6ba7dc45ccd1cf0aa0ebfa209bd3 Mon Sep 17 00:00:00 2001 From: Li Zefan Date: Tue, 9 Nov 2010 08:27:27 +0800 Subject: btrfs: Fix error handling in zlib Return failure if alloc_page() fails to allocate memory, and the upper code will just give up compression. Signed-off-by: Li Zefan --- fs/btrfs/zlib.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/fs/btrfs/zlib.c b/fs/btrfs/zlib.c index e5b8b22e07d6..b01558661e3b 100644 --- a/fs/btrfs/zlib.c +++ b/fs/btrfs/zlib.c @@ -225,6 +225,10 @@ int btrfs_zlib_compress_pages(struct address_space *mapping, data_in = kmap(in_page); out_page = alloc_page(GFP_NOFS | __GFP_HIGHMEM); + if (out_page == NULL) { + ret = -1; + goto out; + } cpage_out = kmap(out_page); pages[0] = out_page; nr_pages = 1; @@ -263,6 +267,10 @@ int btrfs_zlib_compress_pages(struct address_space *mapping, goto out; } out_page = alloc_page(GFP_NOFS | __GFP_HIGHMEM); + if (out_page == NULL) { + ret = -1; + goto out; + } cpage_out = kmap(out_page); pages[nr_pages] = out_page; nr_pages++; -- cgit v1.2.3 From 261507a02ccba9afda919852263b6bc1581ce1ef Mon Sep 17 00:00:00 2001 From: Li Zefan Date: Fri, 17 Dec 2010 14:21:50 +0800 Subject: btrfs: Allow to add new compression algorithm Make the code aware of compression type, instead of always assuming zlib compression. Also make the zlib workspace function as common code for all compression types. Signed-off-by: Li Zefan --- fs/btrfs/btrfs_inode.h | 2 +- fs/btrfs/compression.c | 236 +++++++++++++++++++++++++++++++++++++++++++- fs/btrfs/compression.h | 66 +++++++++---- fs/btrfs/ctree.h | 10 +- fs/btrfs/extent_io.c | 5 +- fs/btrfs/extent_io.h | 17 +++- fs/btrfs/extent_map.c | 2 + fs/btrfs/extent_map.h | 3 +- fs/btrfs/file.c | 2 + fs/btrfs/inode.c | 82 ++++++++++------ fs/btrfs/ioctl.c | 4 +- fs/btrfs/ordered-data.c | 18 +++- fs/btrfs/ordered-data.h | 8 +- fs/btrfs/super.c | 47 ++++++--- fs/btrfs/zlib.c | 253 ++++++++++-------------------------------------- 15 files changed, 473 insertions(+), 282 deletions(-) diff --git a/fs/btrfs/btrfs_inode.h b/fs/btrfs/btrfs_inode.h index 6ad63f17eca0..ccc991c542df 100644 --- a/fs/btrfs/btrfs_inode.h +++ b/fs/btrfs/btrfs_inode.h @@ -157,7 +157,7 @@ struct btrfs_inode { /* * always compress this one file */ - unsigned force_compress:1; + unsigned force_compress:4; struct inode vfs_inode; }; diff --git a/fs/btrfs/compression.c b/fs/btrfs/compression.c index b50bc4bd5c56..6638c9877720 100644 --- a/fs/btrfs/compression.c +++ b/fs/btrfs/compression.c @@ -62,6 +62,9 @@ struct compressed_bio { /* number of bytes on disk */ unsigned long compressed_len; + /* the compression algorithm for this bio */ + int compress_type; + /* number of compressed pages in the array */ unsigned long nr_pages; @@ -173,11 +176,12 @@ static void end_compressed_bio_read(struct bio *bio, int err) /* ok, we're the last bio for this extent, lets start * the decompression. */ - ret = btrfs_zlib_decompress_biovec(cb->compressed_pages, - cb->start, - cb->orig_bio->bi_io_vec, - cb->orig_bio->bi_vcnt, - cb->compressed_len); + ret = btrfs_decompress_biovec(cb->compress_type, + cb->compressed_pages, + cb->start, + cb->orig_bio->bi_io_vec, + cb->orig_bio->bi_vcnt, + cb->compressed_len); csum_failed: if (ret) cb->errors = 1; @@ -588,6 +592,7 @@ int btrfs_submit_compressed_read(struct inode *inode, struct bio *bio, cb->len = uncompressed_len; cb->compressed_len = compressed_len; + cb->compress_type = extent_compress_type(bio_flags); cb->orig_bio = bio; nr_pages = (compressed_len + PAGE_CACHE_SIZE - 1) / @@ -677,3 +682,224 @@ int btrfs_submit_compressed_read(struct inode *inode, struct bio *bio, bio_put(comp_bio); return 0; } + +static struct list_head comp_idle_workspace[BTRFS_COMPRESS_TYPES]; +static spinlock_t comp_workspace_lock[BTRFS_COMPRESS_TYPES]; +static int comp_num_workspace[BTRFS_COMPRESS_TYPES]; +static atomic_t comp_alloc_workspace[BTRFS_COMPRESS_TYPES]; +static wait_queue_head_t comp_workspace_wait[BTRFS_COMPRESS_TYPES]; + +struct btrfs_compress_op *btrfs_compress_op[] = { + &btrfs_zlib_compress, +}; + +int __init btrfs_init_compress(void) +{ + int i; + + for (i = 0; i < BTRFS_COMPRESS_TYPES; i++) { + INIT_LIST_HEAD(&comp_idle_workspace[i]); + spin_lock_init(&comp_workspace_lock[i]); + atomic_set(&comp_alloc_workspace[i], 0); + init_waitqueue_head(&comp_workspace_wait[i]); + } + return 0; +} + +/* + * this finds an available workspace or allocates a new one + * ERR_PTR is returned if things go bad. + */ +static struct list_head *find_workspace(int type) +{ + struct list_head *workspace; + int cpus = num_online_cpus(); + int idx = type - 1; + + struct list_head *idle_workspace = &comp_idle_workspace[idx]; + spinlock_t *workspace_lock = &comp_workspace_lock[idx]; + atomic_t *alloc_workspace = &comp_alloc_workspace[idx]; + wait_queue_head_t *workspace_wait = &comp_workspace_wait[idx]; + int *num_workspace = &comp_num_workspace[idx]; +again: + spin_lock(workspace_lock); + if (!list_empty(idle_workspace)) { + workspace = idle_workspace->next; + list_del(workspace); + (*num_workspace)--; + spin_unlock(workspace_lock); + return workspace; + + } + if (atomic_read(alloc_workspace) > cpus) { + DEFINE_WAIT(wait); + + spin_unlock(workspace_lock); + prepare_to_wait(workspace_wait, &wait, TASK_UNINTERRUPTIBLE); + if (atomic_read(alloc_workspace) > cpus && !*num_workspace) + schedule(); + finish_wait(workspace_wait, &wait); + goto again; + } + atomic_inc(alloc_workspace); + spin_unlock(workspace_lock); + + workspace = btrfs_compress_op[idx]->alloc_workspace(); + if (IS_ERR(workspace)) { + atomic_dec(alloc_workspace); + wake_up(workspace_wait); + } + return workspace; +} + +/* + * put a workspace struct back on the list or free it if we have enough + * idle ones sitting around + */ +static void free_workspace(int type, struct list_head *workspace) +{ + int idx = type - 1; + struct list_head *idle_workspace = &comp_idle_workspace[idx]; + spinlock_t *workspace_lock = &comp_workspace_lock[idx]; + atomic_t *alloc_workspace = &comp_alloc_workspace[idx]; + wait_queue_head_t *workspace_wait = &comp_workspace_wait[idx]; + int *num_workspace = &comp_num_workspace[idx]; + + spin_lock(workspace_lock); + if (*num_workspace < num_online_cpus()) { + list_add_tail(workspace, idle_workspace); + (*num_workspace)++; + spin_unlock(workspace_lock); + goto wake; + } + spin_unlock(workspace_lock); + + btrfs_compress_op[idx]->free_workspace(workspace); + atomic_dec(alloc_workspace); +wake: + if (waitqueue_active(workspace_wait)) + wake_up(workspace_wait); +} + +/* + * cleanup function for module exit + */ +static void free_workspaces(void) +{ + struct list_head *workspace; + int i; + + for (i = 0; i < BTRFS_COMPRESS_TYPES; i++) { + while (!list_empty(&comp_idle_workspace[i])) { + workspace = comp_idle_workspace[i].next; + list_del(workspace); + btrfs_compress_op[i]->free_workspace(workspace); + atomic_dec(&comp_alloc_workspace[i]); + } + } +} + +/* + * given an address space and start/len, compress the bytes. + * + * pages are allocated to hold the compressed result and stored + * in 'pages' + * + * out_pages is used to return the number of pages allocated. There + * may be pages allocated even if we return an error + * + * total_in is used to return the number of bytes actually read. It + * may be smaller then len if we had to exit early because we + * ran out of room in the pages array or because we cross the + * max_out threshold. + * + * total_out is used to return the total number of compressed bytes + * + * max_out tells us the max number of bytes that we're allowed to + * stuff into pages + */ +int btrfs_compress_pages(int type, struct address_space *mapping, + u64 start, unsigned long len, + struct page **pages, + unsigned long nr_dest_pages, + unsigned long *out_pages, + unsigned long *total_in, + unsigned long *total_out, + unsigned long max_out) +{ + struct list_head *workspace; + int ret; + + workspace = find_workspace(type); + if (IS_ERR(workspace)) + return -1; + + ret = btrfs_compress_op[type-1]->compress_pages(workspace, mapping, + start, len, pages, + nr_dest_pages, out_pages, + total_in, total_out, + max_out); + free_workspace(type, workspace); + return ret; +} + +/* + * pages_in is an array of pages with compressed data. + * + * disk_start is the starting logical offset of this array in the file + * + * bvec is a bio_vec of pages from the file that we want to decompress into + * + * vcnt is the count of pages in the biovec + * + * srclen is the number of bytes in pages_in + * + * The basic idea is that we have a bio that was created by readpages. + * The pages in the bio are for the uncompressed data, and they may not + * be contiguous. They all correspond to the range of bytes covered by + * the compressed extent. + */ +int btrfs_decompress_biovec(int type, struct page **pages_in, u64 disk_start, + struct bio_vec *bvec, int vcnt, size_t srclen) +{ + struct list_head *workspace; + int ret; + + workspace = find_workspace(type); + if (IS_ERR(workspace)) + return -ENOMEM; + + ret = btrfs_compress_op[type-1]->decompress_biovec(workspace, pages_in, + disk_start, + bvec, vcnt, srclen); + free_workspace(type, workspace); + return ret; +} + +/* + * a less complex decompression routine. Our compressed data fits in a + * single page, and we want to read a single page out of it. + * start_byte tells us the offset into the compressed data we're interested in + */ +int btrfs_decompress(int type, unsigned char *data_in, struct page *dest_page, + unsigned long start_byte, size_t srclen, size_t destlen) +{ + struct list_head *workspace; + int ret; + + workspace = find_workspace(type); + if (IS_ERR(workspace)) + return -ENOMEM; + + ret = btrfs_compress_op[type-1]->decompress(workspace, data_in, + dest_page, start_byte, + srclen, destlen); + + free_workspace(type, workspace); + return ret; +} + +void __exit btrfs_exit_compress(void) +{ + free_workspaces(); +} diff --git a/fs/btrfs/compression.h b/fs/btrfs/compression.h index 421f5b4aa715..9b5f2f365b79 100644 --- a/fs/btrfs/compression.h +++ b/fs/btrfs/compression.h @@ -19,24 +19,22 @@ #ifndef __BTRFS_COMPRESSION_ #define __BTRFS_COMPRESSION_ -int btrfs_zlib_decompress(unsigned char *data_in, - struct page *dest_page, - unsigned long start_byte, - size_t srclen, size_t destlen); -int btrfs_zlib_compress_pages(struct address_space *mapping, - u64 start, unsigned long len, - struct page **pages, - unsigned long nr_dest_pages, - unsigned long *out_pages, - unsigned long *total_in, - unsigned long *total_out, - unsigned long max_out); -int btrfs_zlib_decompress_biovec(struct page **pages_in, - u64 disk_start, - struct bio_vec *bvec, - int vcnt, - size_t srclen); -void btrfs_zlib_exit(void); +int btrfs_init_compress(void); +void btrfs_exit_compress(void); + +int btrfs_compress_pages(int type, struct address_space *mapping, + u64 start, unsigned long len, + struct page **pages, + unsigned long nr_dest_pages, + unsigned long *out_pages, + unsigned long *total_in, + unsigned long *total_out, + unsigned long max_out); +int btrfs_decompress_biovec(int type, struct page **pages_in, u64 disk_start, + struct bio_vec *bvec, int vcnt, size_t srclen); +int btrfs_decompress(int type, unsigned char *data_in, struct page *dest_page, + unsigned long start_byte, size_t srclen, size_t destlen); + int btrfs_submit_compressed_write(struct inode *inode, u64 start, unsigned long len, u64 disk_start, unsigned long compressed_len, @@ -44,4 +42,36 @@ int btrfs_submit_compressed_write(struct inode *inode, u64 start, unsigned long nr_pages); int btrfs_submit_compressed_read(struct inode *inode, struct bio *bio, int mirror_num, unsigned long bio_flags); + +struct btrfs_compress_op { + struct list_head *(*alloc_workspace)(void); + + void (*free_workspace)(struct list_head *workspace); + + int (*compress_pages)(struct list_head *workspace, + struct address_space *mapping, + u64 start, unsigned long len, + struct page **pages, + unsigned long nr_dest_pages, + unsigned long *out_pages, + unsigned long *total_in, + unsigned long *total_out, + unsigned long max_out); + + int (*decompress_biovec)(struct list_head *workspace, + struct page **pages_in, + u64 disk_start, + struct bio_vec *bvec, + int vcnt, + size_t srclen); + + int (*decompress)(struct list_head *workspace, + unsigned char *data_in, + struct page *dest_page, + unsigned long start_byte, + size_t srclen, size_t destlen); +}; + +extern struct btrfs_compress_op btrfs_zlib_compress; + #endif diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index af52f6d7a4d8..e06534438592 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h @@ -551,9 +551,10 @@ struct btrfs_timespec { } __attribute__ ((__packed__)); enum btrfs_compression_type { - BTRFS_COMPRESS_NONE = 0, - BTRFS_COMPRESS_ZLIB = 1, - BTRFS_COMPRESS_LAST = 2, + BTRFS_COMPRESS_NONE = 0, + BTRFS_COMPRESS_ZLIB = 1, + BTRFS_COMPRESS_TYPES = 1, + BTRFS_COMPRESS_LAST = 2, }; struct btrfs_inode_item { @@ -895,7 +896,8 @@ struct btrfs_fs_info { */ u64 last_trans_log_full_commit; u64 open_ioctl_trans; - unsigned long mount_opt; + unsigned long mount_opt:20; + unsigned long compress_type:4; u64 max_inline; u64 alloc_start; struct btrfs_transaction *running_transaction; diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c index 5e7a94d7da89..f1d198128959 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c @@ -2028,8 +2028,11 @@ static int __extent_read_full_page(struct extent_io_tree *tree, BUG_ON(extent_map_end(em) <= cur); BUG_ON(end < cur); - if (test_bit(EXTENT_FLAG_COMPRESSED, &em->flags)) + if (test_bit(EXTENT_FLAG_COMPRESSED, &em->flags)) { this_bio_flag = EXTENT_BIO_COMPRESSED; + extent_set_compress_type(&this_bio_flag, + em->compress_type); + } iosize = min(extent_map_end(em) - cur, end - cur + 1); cur_end = min(extent_map_end(em) - 1, end); diff --git a/fs/btrfs/extent_io.h b/fs/btrfs/extent_io.h index 4183c8178f01..7083cfafd061 100644 --- a/fs/btrfs/extent_io.h +++ b/fs/btrfs/extent_io.h @@ -20,8 +20,12 @@ #define EXTENT_IOBITS (EXTENT_LOCKED | EXTENT_WRITEBACK) #define EXTENT_CTLBITS (EXTENT_DO_ACCOUNTING | EXTENT_FIRST_DELALLOC) -/* flags for bio submission */ +/* + * flags for bio submission. The high bits indicate the compression + * type for this bio + */ #define EXTENT_BIO_COMPRESSED 1 +#define EXTENT_BIO_FLAG_SHIFT 16 /* these are bit numbers for test/set bit */ #define EXTENT_BUFFER_UPTODATE 0 @@ -135,6 +139,17 @@ struct extent_buffer { wait_queue_head_t lock_wq; }; +static inline void extent_set_compress_type(unsigned long *bio_flags, + int compress_type) +{ + *bio_flags |= compress_type << EXTENT_BIO_FLAG_SHIFT; +} + +static inline int extent_compress_type(unsigned long bio_flags) +{ + return bio_flags >> EXTENT_BIO_FLAG_SHIFT; +} + struct extent_map_tree; static inline struct extent_state *extent_state_next(struct extent_state *state) diff --git a/fs/btrfs/extent_map.c b/fs/btrfs/extent_map.c index 23cb8da3ff66..b0e1fce12530 100644 --- a/fs/btrfs/extent_map.c +++ b/fs/btrfs/extent_map.c @@ -3,6 +3,7 @@ #include #include #include +#include "ctree.h" #include "extent_map.h" @@ -54,6 +55,7 @@ struct extent_map *alloc_extent_map(gfp_t mask) return em; em->in_tree = 0; em->flags = 0; + em->compress_type = BTRFS_COMPRESS_NONE; atomic_set(&em->refs, 1); return em; } diff --git a/fs/btrfs/extent_map.h b/fs/btrfs/extent_map.h index ab6d74b6e647..28b44dbd1e35 100644 --- a/fs/btrfs/extent_map.h +++ b/fs/btrfs/extent_map.h @@ -26,7 +26,8 @@ struct extent_map { unsigned long flags; struct block_device *bdev; atomic_t refs; - int in_tree; + unsigned int in_tree:1; + unsigned int compress_type:4; }; struct extent_map_tree { diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index 66836d85763b..05df688c96f4 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c @@ -224,6 +224,7 @@ int btrfs_drop_extent_cache(struct inode *inode, u64 start, u64 end, split->bdev = em->bdev; split->flags = flags; + split->compress_type = em->compress_type; ret = add_extent_mapping(em_tree, split); BUG_ON(ret); free_extent_map(split); @@ -238,6 +239,7 @@ int btrfs_drop_extent_cache(struct inode *inode, u64 start, u64 end, split->len = em->start + em->len - (start + len); split->bdev = em->bdev; split->flags = flags; + split->compress_type = em->compress_type; if (compressed) { split->block_len = em->block_len; diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 5f9194438f7c..ba563b2a5d6c 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -122,10 +122,10 @@ static noinline int insert_inline_extent(struct btrfs_trans_handle *trans, size_t cur_size = size; size_t datasize; unsigned long offset; - int use_compress = 0; + int compress_type = BTRFS_COMPRESS_NONE; if (compressed_size && compressed_pages) { - use_compress = 1; + compress_type = root->fs_info->compress_type; cur_size = compressed_size; } @@ -159,7 +159,7 @@ static noinline int insert_inline_extent(struct btrfs_trans_handle *trans, btrfs_set_file_extent_ram_bytes(leaf, ei, size); ptr = btrfs_file_extent_inline_start(ei); - if (use_compress) { + if (compress_type != BTRFS_COMPRESS_NONE) { struct page *cpage; int i = 0; while (compressed_size > 0) { @@ -176,7 +176,7 @@ static noinline int insert_inline_extent(struct btrfs_trans_handle *trans, compressed_size -= cur_size; } btrfs_set_file_extent_compression(leaf, ei, - BTRFS_COMPRESS_ZLIB); + compress_type); } else { page = find_get_page(inode->i_mapping, start >> PAGE_CACHE_SHIFT); @@ -263,6 +263,7 @@ struct async_extent { u64 compressed_size; struct page **pages; unsigned long nr_pages; + int compress_type; struct list_head list; }; @@ -280,7 +281,8 @@ static noinline int add_async_extent(struct async_cow *cow, u64 start, u64 ram_size, u64 compressed_size, struct page **pages, - unsigned long nr_pages) + unsigned long nr_pages, + int compress_type) { struct async_extent *async_extent; @@ -290,6 +292,7 @@ static noinline int add_async_extent(struct async_cow *cow, async_extent->compressed_size = compressed_size; async_extent->pages = pages; async_extent->nr_pages = nr_pages; + async_extent->compress_type = compress_type; list_add_tail(&async_extent->list, &cow->extents); return 0; } @@ -332,6 +335,7 @@ static noinline int compress_file_range(struct inode *inode, unsigned long max_uncompressed = 128 * 1024; int i; int will_compress; + int compress_type = root->fs_info->compress_type; actual_end = min_t(u64, isize, end + 1); again: @@ -381,12 +385,16 @@ again: WARN_ON(pages); pages = kzalloc(sizeof(struct page *) * nr_pages, GFP_NOFS); - ret = btrfs_zlib_compress_pages(inode->i_mapping, start, - total_compressed, pages, - nr_pages, &nr_pages_ret, - &total_in, - &total_compressed, - max_compressed); + if (BTRFS_I(inode)->force_compress) + compress_type = BTRFS_I(inode)->force_compress; + + ret = btrfs_compress_pages(compress_type, + inode->i_mapping, start, + total_compressed, pages, + nr_pages, &nr_pages_ret, + &total_in, + &total_compressed, + max_compressed); if (!ret) { unsigned long offset = total_compressed & @@ -493,7 +501,8 @@ again: * and will submit them to the elevator. */ add_async_extent(async_cow, start, num_bytes, - total_compressed, pages, nr_pages_ret); + total_compressed, pages, nr_pages_ret, + compress_type); if (start + num_bytes < end) { start += num_bytes; @@ -515,7 +524,8 @@ cleanup_and_bail_uncompressed: __set_page_dirty_nobuffers(locked_page); /* unlocked later on in the async handlers */ } - add_async_extent(async_cow, start, end - start + 1, 0, NULL, 0); + add_async_extent(async_cow, start, end - start + 1, + 0, NULL, 0, BTRFS_COMPRESS_NONE); *num_added += 1; } @@ -640,6 +650,7 @@ retry: em->block_start = ins.objectid; em->block_len = ins.offset; em->bdev = root->fs_info->fs_devices->latest_bdev; + em->compress_type = async_extent->compress_type; set_bit(EXTENT_FLAG_PINNED, &em->flags); set_bit(EXTENT_FLAG_COMPRESSED, &em->flags); @@ -656,11 +667,13 @@ retry: async_extent->ram_size - 1, 0); } - ret = btrfs_add_ordered_extent(inode, async_extent->start, - ins.objectid, - async_extent->ram_size, - ins.offset, - BTRFS_ORDERED_COMPRESSED); + ret = btrfs_add_ordered_extent_compress(inode, + async_extent->start, + ins.objectid, + async_extent->ram_size, + ins.offset, + BTRFS_ORDERED_COMPRESSED, + async_extent->compress_type); BUG_ON(ret); /* @@ -1670,7 +1683,7 @@ static int btrfs_finish_ordered_io(struct inode *inode, u64 start, u64 end) struct btrfs_ordered_extent *ordered_extent = NULL; struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree; struct extent_state *cached_state = NULL; - int compressed = 0; + int compress_type = 0; int ret; bool nolock = false; @@ -1711,9 +1724,9 @@ static int btrfs_finish_ordered_io(struct inode *inode, u64 start, u64 end) trans->block_rsv = &root->fs_info->delalloc_block_rsv; if (test_bit(BTRFS_ORDERED_COMPRESSED, &ordered_extent->flags)) - compressed = 1; + compress_type = ordered_extent->compress_type; if (test_bit(BTRFS_ORDERED_PREALLOC, &ordered_extent->flags)) { - BUG_ON(compressed); + BUG_ON(compress_type); ret = btrfs_mark_extent_written(trans, inode, ordered_extent->file_offset, ordered_extent->file_offset + @@ -1727,7 +1740,7 @@ static int btrfs_finish_ordered_io(struct inode *inode, u64 start, u64 end) ordered_extent->disk_len, ordered_extent->len, ordered_extent->len, - compressed, 0, 0, + compress_type, 0, 0, BTRFS_FILE_EXTENT_REG); unpin_extent_cache(&BTRFS_I(inode)->extent_tree, ordered_extent->file_offset, @@ -1829,6 +1842,8 @@ static int btrfs_io_failed_hook(struct bio *failed_bio, if (test_bit(EXTENT_FLAG_COMPRESSED, &em->flags)) { logical = em->block_start; failrec->bio_flags = EXTENT_BIO_COMPRESSED; + extent_set_compress_type(&failrec->bio_flags, + em->compress_type); } failrec->logical = logical; free_extent_map(em); @@ -4930,8 +4945,10 @@ static noinline int uncompress_inline(struct btrfs_path *path, size_t max_size; unsigned long inline_size; unsigned long ptr; + int compress_type; WARN_ON(pg_offset != 0); + compress_type = btrfs_file_extent_compression(leaf, item); max_size = btrfs_file_extent_ram_bytes(leaf, item); inline_size = btrfs_file_extent_inline_item_len(leaf, btrfs_item_nr(leaf, path->slots[0])); @@ -4941,8 +4958,8 @@ static noinline int uncompress_inline(struct btrfs_path *path, read_extent_buffer(leaf, tmp, ptr, inline_size); max_size = min_t(unsigned long, PAGE_CACHE_SIZE, max_size); - ret = btrfs_zlib_decompress(tmp, page, extent_offset, - inline_size, max_size); + ret = btrfs_decompress(compress_type, tmp, page, + extent_offset, inline_size, max_size); if (ret) { char *kaddr = kmap_atomic(page, KM_USER0); unsigned long copy_size = min_t(u64, @@ -4984,7 +5001,7 @@ struct extent_map *btrfs_get_extent(struct inode *inode, struct page *page, struct extent_map_tree *em_tree = &BTRFS_I(inode)->extent_tree; struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree; struct btrfs_trans_handle *trans = NULL; - int compressed; + int compress_type; again: read_lock(&em_tree->lock); @@ -5043,7 +5060,7 @@ again: found_type = btrfs_file_extent_type(leaf, item); extent_start = found_key.offset; - compressed = btrfs_file_extent_compression(leaf, item); + compress_type = btrfs_file_extent_compression(leaf, item); if (found_type == BTRFS_FILE_EXTENT_REG || found_type == BTRFS_FILE_EXTENT_PREALLOC) { extent_end = extent_start + @@ -5089,8 +5106,9 @@ again: em->block_start = EXTENT_MAP_HOLE; goto insert; } - if (compressed) { + if (compress_type != BTRFS_COMPRESS_NONE) { set_bit(EXTENT_FLAG_COMPRESSED, &em->flags); + em->compress_type = compress_type; em->block_start = bytenr; em->block_len = btrfs_file_extent_disk_num_bytes(leaf, item); @@ -5124,12 +5142,14 @@ again: em->len = (copy_size + root->sectorsize - 1) & ~((u64)root->sectorsize - 1); em->orig_start = EXTENT_MAP_INLINE; - if (compressed) + if (compress_type) { set_bit(EXTENT_FLAG_COMPRESSED, &em->flags); + em->compress_type = compress_type; + } ptr = btrfs_file_extent_inline_start(item) + extent_offset; if (create == 0 && !PageUptodate(page)) { - if (btrfs_file_extent_compression(leaf, item) == - BTRFS_COMPRESS_ZLIB) { + if (btrfs_file_extent_compression(leaf, item) != + BTRFS_COMPRESS_NONE) { ret = uncompress_inline(path, inode, page, pg_offset, extent_offset, item); @@ -6479,7 +6499,7 @@ struct inode *btrfs_alloc_inode(struct super_block *sb) ei->ordered_data_close = 0; ei->orphan_meta_reserved = 0; ei->dummy_inode = 0; - ei->force_compress = 0; + ei->force_compress = BTRFS_COMPRESS_NONE; inode = &ei->vfs_inode; extent_map_tree_init(&ei->extent_tree, GFP_NOFS); diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index f87552a1d7ea..8cb86d4d763c 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c @@ -683,7 +683,7 @@ static int btrfs_defrag_file(struct file *file, total_read++; mutex_lock(&inode->i_mutex); if (range->flags & BTRFS_DEFRAG_RANGE_COMPRESS) - BTRFS_I(inode)->force_compress = 1; + BTRFS_I(inode)->force_compress = BTRFS_COMPRESS_ZLIB; ret = btrfs_delalloc_reserve_space(inode, PAGE_CACHE_SIZE); if (ret) @@ -781,7 +781,7 @@ loop_unlock: atomic_dec(&root->fs_info->async_submit_draining); mutex_lock(&inode->i_mutex); - BTRFS_I(inode)->force_compress = 0; + BTRFS_I(inode)->force_compress = BTRFS_COMPRESS_NONE; mutex_unlock(&inode->i_mutex); } diff --git a/fs/btrfs/ordered-data.c b/fs/btrfs/ordered-data.c index ae7737e352c9..2b61e1ddcd99 100644 --- a/fs/btrfs/ordered-data.c +++ b/fs/btrfs/ordered-data.c @@ -172,7 +172,7 @@ static inline struct rb_node *tree_search(struct btrfs_ordered_inode_tree *tree, */ static int __btrfs_add_ordered_extent(struct inode *inode, u64 file_offset, u64 start, u64 len, u64 disk_len, - int type, int dio) + int type, int dio, int compress_type) { struct btrfs_ordered_inode_tree *tree; struct rb_node *node; @@ -189,6 +189,7 @@ static int __btrfs_add_ordered_extent(struct inode *inode, u64 file_offset, entry->disk_len = disk_len; entry->bytes_left = len; entry->inode = inode; + entry->compress_type = compress_type; if (type != BTRFS_ORDERED_IO_DONE && type != BTRFS_ORDERED_COMPLETE) set_bit(type, &entry->flags); @@ -220,14 +221,25 @@ int btrfs_add_ordered_extent(struct inode *inode, u64 file_offset, u64 start, u64 len, u64 disk_len, int type) { return __btrfs_add_ordered_extent(inode, file_offset, start, len, - disk_len, type, 0); + disk_len, type, 0, + BTRFS_COMPRESS_NONE); } int btrfs_add_ordered_extent_dio(struct inode *inode, u64 file_offset, u64 start, u64 len, u64 disk_len, int type) { return __btrfs_add_ordered_extent(inode, file_offset, start, len, - disk_len, type, 1); + disk_len, type, 1, + BTRFS_COMPRESS_NONE); +} + +int btrfs_add_ordered_extent_compress(struct inode *inode, u64 file_offset, + u64 start, u64 len, u64 disk_len, + int type, int compress_type) +{ + return __btrfs_add_ordered_extent(inode, file_offset, start, len, + disk_len, type, 0, + compress_type); } /* diff --git a/fs/btrfs/ordered-data.h b/fs/btrfs/ordered-data.h index 61dca83119dd..ff1f69aa1883 100644 --- a/fs/btrfs/ordered-data.h +++ b/fs/btrfs/ordered-data.h @@ -68,7 +68,7 @@ struct btrfs_ordered_sum { #define BTRFS_ORDERED_NOCOW 2 /* set when we want to write in place */ -#define BTRFS_ORDERED_COMPRESSED 3 /* writing a compressed extent */ +#define BTRFS_ORDERED_COMPRESSED 3 /* writing a zlib compressed extent */ #define BTRFS_ORDERED_PREALLOC 4 /* set when writing to prealloced extent */ @@ -93,6 +93,9 @@ struct btrfs_ordered_extent { /* flags (described above) */ unsigned long flags; + /* compression algorithm */ + int compress_type; + /* reference count */ atomic_t refs; @@ -148,6 +151,9 @@ int btrfs_add_ordered_extent(struct inode *inode, u64 file_offset, u64 start, u64 len, u64 disk_len, int type); int btrfs_add_ordered_extent_dio(struct inode *inode, u64 file_offset, u64 start, u64 len, u64 disk_len, int type); +int btrfs_add_ordered_extent_compress(struct inode *inode, u64 file_offset, + u64 start, u64 len, u64 disk_len, + int type, int compress_type); int btrfs_add_ordered_sum(struct inode *inode, struct btrfs_ordered_extent *entry, struct btrfs_ordered_sum *sum); diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index 61bd79abb805..f348f2b93164 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c @@ -69,9 +69,9 @@ enum { Opt_degraded, Opt_subvol, Opt_subvolid, Opt_device, Opt_nodatasum, Opt_nodatacow, Opt_max_inline, Opt_alloc_start, Opt_nobarrier, Opt_ssd, Opt_nossd, Opt_ssd_spread, Opt_thread_pool, Opt_noacl, Opt_compress, - Opt_compress_force, Opt_notreelog, Opt_ratio, Opt_flushoncommit, - Opt_discard, Opt_space_cache, Opt_clear_cache, Opt_err, - Opt_user_subvol_rm_allowed, + Opt_compress_type, Opt_compress_force, Opt_compress_force_type, + Opt_notreelog, Opt_ratio, Opt_flushoncommit, Opt_discard, + Opt_space_cache, Opt_clear_cache, Opt_user_subvol_rm_allowed, Opt_err, }; static match_table_t tokens = { @@ -86,7 +86,9 @@ static match_table_t tokens = { {Opt_alloc_start, "alloc_start=%s"}, {Opt_thread_pool, "thread_pool=%d"}, {Opt_compress, "compress"}, + {Opt_compress_type, "compress=%s"}, {Opt_compress_force, "compress-force"}, + {Opt_compress_force_type, "compress-force=%s"}, {Opt_ssd, "ssd"}, {Opt_ssd_spread, "ssd_spread"}, {Opt_nossd, "nossd"}, @@ -112,6 +114,8 @@ int btrfs_parse_options(struct btrfs_root *root, char *options) char *p, *num, *orig; int intarg; int ret = 0; + char *compress_type; + bool compress_force = false; if (!options) return 0; @@ -154,14 +158,29 @@ int btrfs_parse_options(struct btrfs_root *root, char *options) btrfs_set_opt(info->mount_opt, NODATACOW); btrfs_set_opt(info->mount_opt, NODATASUM); break; - case Opt_compress: - printk(KERN_INFO "btrfs: use compression\n"); - btrfs_set_opt(info->mount_opt, COMPRESS); - break; case Opt_compress_force: - printk(KERN_INFO "btrfs: forcing compression\n"); - btrfs_set_opt(info->mount_opt, FORCE_COMPRESS); + case Opt_compress_force_type: + compress_force = true; + case Opt_compress: + case Opt_compress_type: + if (token == Opt_compress || + token == Opt_compress_force || + strcmp(args[0].from, "zlib") == 0) { + compress_type = "zlib"; + info->compress_type = BTRFS_COMPRESS_ZLIB; + } else { + ret = -EINVAL; + goto out; + } + btrfs_set_opt(info->mount_opt, COMPRESS); + if (compress_force) { + btrfs_set_opt(info->mount_opt, FORCE_COMPRESS); + pr_info("btrfs: force %s compression\n", + compress_type); + } else + pr_info("btrfs: use %s compression\n", + compress_type); break; case Opt_ssd: printk(KERN_INFO "btrfs: use ssd allocation scheme\n"); @@ -898,10 +917,14 @@ static int __init init_btrfs_fs(void) if (err) return err; - err = btrfs_init_cachep(); + err = btrfs_init_compress(); if (err) goto free_sysfs; + err = btrfs_init_cachep(); + if (err) + goto free_compress; + err = extent_io_init(); if (err) goto free_cachep; @@ -929,6 +952,8 @@ free_extent_io: extent_io_exit(); free_cachep: btrfs_destroy_cachep(); +free_compress: + btrfs_exit_compress(); free_sysfs: btrfs_exit_sysfs(); return err; @@ -943,7 +968,7 @@ static void __exit exit_btrfs_fs(void) unregister_filesystem(&btrfs_fs_type); btrfs_exit_sysfs(); btrfs_cleanup_fs_uuids(); - btrfs_zlib_exit(); + btrfs_exit_compress(); } module_init(init_btrfs_fs) diff --git a/fs/btrfs/zlib.c b/fs/btrfs/zlib.c index b01558661e3b..9a3e693917f2 100644 --- a/fs/btrfs/zlib.c +++ b/fs/btrfs/zlib.c @@ -32,15 +32,6 @@ #include #include "compression.h" -/* Plan: call deflate() with avail_in == *sourcelen, - avail_out = *dstlen - 12 and flush == Z_FINISH. - If it doesn't manage to finish, call it again with - avail_in == 0 and avail_out set to the remaining 12 - bytes for it to clean up. - Q: Is 12 bytes sufficient? -*/ -#define STREAM_END_SPACE 12 - struct workspace { z_stream inf_strm; z_stream def_strm; @@ -48,155 +39,51 @@ struct workspace { struct list_head list; }; -static LIST_HEAD(idle_workspace); -static DEFINE_SPINLOCK(workspace_lock); -static unsigned long num_workspace; -static atomic_t alloc_workspace = ATOMIC_INIT(0); -static DECLARE_WAIT_QUEUE_HEAD(workspace_wait); +static void zlib_free_workspace(struct list_head *ws) +{ + struct workspace *workspace = list_entry(ws, struct workspace, list); -/* - * this finds an available zlib workspace or allocates a new one - * NULL or an ERR_PTR is returned if things go bad. - */ -static struct workspace *find_zlib_workspace(void) + vfree(workspace->def_strm.workspace); + vfree(workspace->inf_strm.workspace); + kfree(workspace->buf); + kfree(workspace); +} + +static struct list_head *zlib_alloc_workspace(void) { struct workspace *workspace; - int ret; - int cpus = num_online_cpus(); - -again: - spin_lock(&workspace_lock); - if (!list_empty(&idle_workspace)) { - workspace = list_entry(idle_workspace.next, struct workspace, - list); - list_del(&workspace->list); - num_workspace--; - spin_unlock(&workspace_lock); - return workspace; - - } - if (atomic_read(&alloc_workspace) > cpus) { - DEFINE_WAIT(wait); - - spin_unlock(&workspace_lock); - prepare_to_wait(&workspace_wait, &wait, TASK_UNINTERRUPTIBLE); - if (atomic_read(&alloc_workspace) > cpus && !num_workspace) - schedule(); - finish_wait(&workspace_wait, &wait); - goto again; - } - atomic_inc(&alloc_workspace); - spin_unlock(&workspace_lock); workspace = kzalloc(sizeof(*workspace), GFP_NOFS); - if (!workspace) { - ret = -ENOMEM; - goto fail; - } + if (!workspace) + return ERR_PTR(-ENOMEM); workspace->def_strm.workspace = vmalloc(zlib_deflate_workspacesize()); - if (!workspace->def_strm.workspace) { - ret = -ENOMEM; - goto fail; - } workspace->inf_strm.workspace = vmalloc(zlib_inflate_workspacesize()); - if (!workspace->inf_strm.workspace) { - ret = -ENOMEM; - goto fail_inflate; - } workspace->buf = kmalloc(PAGE_CACHE_SIZE, GFP_NOFS); - if (!workspace->buf) { - ret = -ENOMEM; - goto fail_kmalloc; - } - return workspace; - -fail_kmalloc: - vfree(workspace->inf_strm.workspace); -fail_inflate: - vfree(workspace->def_strm.workspace); -fail: - kfree(workspace); - atomic_dec(&alloc_workspace); - wake_up(&workspace_wait); - return ERR_PTR(ret); -} - -/* - * put a workspace struct back on the list or free it if we have enough - * idle ones sitting around - */ -static int free_workspace(struct workspace *workspace) -{ - spin_lock(&workspace_lock); - if (num_workspace < num_online_cpus()) { - list_add_tail(&workspace->list, &idle_workspace); - num_workspace++; - spin_unlock(&workspace_lock); - if (waitqueue_active(&workspace_wait)) - wake_up(&workspace_wait); - return 0; - } - spin_unlock(&workspace_lock); - vfree(workspace->def_strm.workspace); - vfree(workspace->inf_strm.workspace); - kfree(workspace->buf); - kfree(workspace); + if (!workspace->def_strm.workspace || + !workspace->inf_strm.workspace || !workspace->buf) + goto fail; - atomic_dec(&alloc_workspace); - if (waitqueue_active(&workspace_wait)) - wake_up(&workspace_wait); - return 0; -} + INIT_LIST_HEAD(&workspace->list); -/* - * cleanup function for module exit - */ -static void free_workspaces(void) -{ - struct workspace *workspace; - while (!list_empty(&idle_workspace)) { - workspace = list_entry(idle_workspace.next, struct workspace, - list); - list_del(&workspace->list); - vfree(workspace->def_strm.workspace); - vfree(workspace->inf_strm.workspace); - kfree(workspace->buf); - kfree(workspace); - atomic_dec(&alloc_workspace); - } + return &workspace->list; +fail: + zlib_free_workspace(&workspace->list); + return ERR_PTR(-ENOMEM); } -/* - * given an address space and start/len, compress the bytes. - * - * pages are allocated to hold the compressed result and stored - * in 'pages' - * - * out_pages is used to return the number of pages allocated. There - * may be pages allocated even if we return an error - * - * total_in is used to return the number of bytes actually read. It - * may be smaller then len if we had to exit early because we - * ran out of room in the pages array or because we cross the - * max_out threshold. - * - * total_out is used to return the total number of compressed bytes - * - * max_out tells us the max number of bytes that we're allowed to - * stuff into pages - */ -int btrfs_zlib_compress_pages(struct address_space *mapping, - u64 start, unsigned long len, - struct page **pages, - unsigned long nr_dest_pages, - unsigned long *out_pages, - unsigned long *total_in, - unsigned long *total_out, - unsigned long max_out) +static int zlib_compress_pages(struct list_head *ws, + struct address_space *mapping, + u64 start, unsigned long len, + struct page **pages, + unsigned long nr_dest_pages, + unsigned long *out_pages, + unsigned long *total_in, + unsigned long *total_out, + unsigned long max_out) { + struct workspace *workspace = list_entry(ws, struct workspace, list); int ret; - struct workspace *workspace; char *data_in; char *cpage_out; int nr_pages = 0; @@ -208,10 +95,6 @@ int btrfs_zlib_compress_pages(struct address_space *mapping, *total_out = 0; *total_in = 0; - workspace = find_zlib_workspace(); - if (IS_ERR(workspace)) - return -1; - if (Z_OK != zlib_deflateInit(&workspace->def_strm, 3)) { printk(KERN_WARNING "deflateInit failed\n"); ret = -1; @@ -325,35 +208,18 @@ out: kunmap(in_page); page_cache_release(in_page); } - free_workspace(workspace); return ret; } -/* - * pages_in is an array of pages with compressed data. - * - * disk_start is the starting logical offset of this array in the file - * - * bvec is a bio_vec of pages from the file that we want to decompress into - * - * vcnt is the count of pages in the biovec - * - * srclen is the number of bytes in pages_in - * - * The basic idea is that we have a bio that was created by readpages. - * The pages in the bio are for the uncompressed data, and they may not - * be contiguous. They all correspond to the range of bytes covered by - * the compressed extent. - */ -int btrfs_zlib_decompress_biovec(struct page **pages_in, - u64 disk_start, - struct bio_vec *bvec, - int vcnt, - size_t srclen) +static int zlib_decompress_biovec(struct list_head *ws, struct page **pages_in, + u64 disk_start, + struct bio_vec *bvec, + int vcnt, + size_t srclen) { + struct workspace *workspace = list_entry(ws, struct workspace, list); int ret = 0; int wbits = MAX_WBITS; - struct workspace *workspace; char *data_in; size_t total_out = 0; unsigned long page_bytes_left; @@ -371,10 +237,6 @@ int btrfs_zlib_decompress_biovec(struct page **pages_in, unsigned long current_buf_start; char *kaddr; - workspace = find_zlib_workspace(); - if (IS_ERR(workspace)) - return -ENOMEM; - data_in = kmap(pages_in[page_in_index]); workspace->inf_strm.next_in = data_in; workspace->inf_strm.avail_in = min_t(size_t, srclen, PAGE_CACHE_SIZE); @@ -400,8 +262,7 @@ int btrfs_zlib_decompress_biovec(struct page **pages_in, if (Z_OK != zlib_inflateInit2(&workspace->inf_strm, wbits)) { printk(KERN_WARNING "inflateInit failed\n"); - ret = -1; - goto out; + return -1; } while (workspace->inf_strm.total_in < srclen) { ret = zlib_inflate(&workspace->inf_strm, Z_NO_FLUSH); @@ -527,35 +388,21 @@ done: zlib_inflateEnd(&workspace->inf_strm); if (data_in) kunmap(pages_in[page_in_index]); -out: - free_workspace(workspace); return ret; } -/* - * a less complex decompression routine. Our compressed data fits in a - * single page, and we want to read a single page out of it. - * start_byte tells us the offset into the compressed data we're interested in - */ -int btrfs_zlib_decompress(unsigned char *data_in, - struct page *dest_page, - unsigned long start_byte, - size_t srclen, size_t destlen) +static int zlib_decompress(struct list_head *ws, unsigned char *data_in, + struct page *dest_page, + unsigned long start_byte, + size_t srclen, size_t destlen) { + struct workspace *workspace = list_entry(ws, struct workspace, list); int ret = 0; int wbits = MAX_WBITS; - struct workspace *workspace; unsigned long bytes_left = destlen; unsigned long total_out = 0; char *kaddr; - if (destlen > PAGE_CACHE_SIZE) - return -ENOMEM; - - workspace = find_zlib_workspace(); - if (IS_ERR(workspace)) - return -ENOMEM; - workspace->inf_strm.next_in = data_in; workspace->inf_strm.avail_in = srclen; workspace->inf_strm.total_in = 0; @@ -576,8 +423,7 @@ int btrfs_zlib_decompress(unsigned char *data_in, if (Z_OK != zlib_inflateInit2(&workspace->inf_strm, wbits)) { printk(KERN_WARNING "inflateInit failed\n"); - ret = -1; - goto out; + return -1; } while (bytes_left > 0) { @@ -627,12 +473,13 @@ next: ret = 0; zlib_inflateEnd(&workspace->inf_strm); -out: - free_workspace(workspace); return ret; } -void btrfs_zlib_exit(void) -{ - free_workspaces(); -} +struct btrfs_compress_op btrfs_zlib_compress = { + .alloc_workspace = zlib_alloc_workspace, + .free_workspace = zlib_free_workspace, + .compress_pages = zlib_compress_pages, + .decompress_biovec = zlib_decompress_biovec, + .decompress = zlib_decompress, +}; -- cgit v1.2.3 From a6fa6fae40ec336c7df6155255ae64ebef43a8bc Mon Sep 17 00:00:00 2001 From: Li Zefan Date: Mon, 25 Oct 2010 15:12:26 +0800 Subject: btrfs: Add lzo compression support Lzo is a much faster compression algorithm than gzib, so would allow more users to enable transparent compression, and some users can choose from compression ratio and speed for different applications Usage: # mount -t btrfs -o compress[=] dev /mnt or # mount -t btrfs -o compress-force[=] dev /mnt "-o compress" without argument is still allowed for compatability. Compatibility: If we mount a filesystem with lzo compression, it will not be able be mounted in old kernels. One reason is, otherwise btrfs will directly dump compressed data, which sits in inline extent, to user. Performance: The test copied a linux source tarball (~400M) from an ext4 partition to the btrfs partition, and then extracted it. (time in second) lzo zlib nocompress copy: 10.6 21.7 14.9 extract: 70.1 94.4 66.6 (data size in MB) lzo zlib nocompress copy: 185.87 108.69 394.49 extract: 193.80 132.36 381.21 Changelog: v1 -> v2: - Select LZO_COMPRESS and LZO_DECOMPRESS in btrfs Kconfig. - Add incompability flag. - Fix error handling in compress code. Signed-off-by: Li Zefan --- fs/btrfs/Kconfig | 2 + fs/btrfs/Makefile | 2 +- fs/btrfs/compression.c | 1 + fs/btrfs/compression.h | 1 + fs/btrfs/ctree.h | 9 +- fs/btrfs/disk-io.c | 8 +- fs/btrfs/lzo.c | 509 +++++++++++++++++++++++++++++++++++++++++++++++++ fs/btrfs/super.c | 3 + 8 files changed, 527 insertions(+), 8 deletions(-) create mode 100644 fs/btrfs/lzo.c diff --git a/fs/btrfs/Kconfig b/fs/btrfs/Kconfig index 7bb3c020e570..ecb9fd3be143 100644 --- a/fs/btrfs/Kconfig +++ b/fs/btrfs/Kconfig @@ -4,6 +4,8 @@ config BTRFS_FS select LIBCRC32C select ZLIB_INFLATE select ZLIB_DEFLATE + select LZO_COMPRESS + select LZO_DECOMPRESS help Btrfs is a new filesystem with extents, writable snapshotting, support for multiple devices and many more features. diff --git a/fs/btrfs/Makefile b/fs/btrfs/Makefile index a35eb36b32fd..31610ea73aec 100644 --- a/fs/btrfs/Makefile +++ b/fs/btrfs/Makefile @@ -6,5 +6,5 @@ btrfs-y += super.o ctree.o extent-tree.o print-tree.o root-tree.o dir-item.o \ transaction.o inode.o file.o tree-defrag.o \ extent_map.o sysfs.o struct-funcs.o xattr.o ordered-data.o \ extent_io.o volumes.o async-thread.o ioctl.o locking.o orphan.o \ - export.o tree-log.o acl.o free-space-cache.o zlib.o \ + export.o tree-log.o acl.o free-space-cache.o zlib.o lzo.o \ compression.o delayed-ref.o relocation.o diff --git a/fs/btrfs/compression.c b/fs/btrfs/compression.c index 6638c9877720..8faa2df9e719 100644 --- a/fs/btrfs/compression.c +++ b/fs/btrfs/compression.c @@ -691,6 +691,7 @@ static wait_queue_head_t comp_workspace_wait[BTRFS_COMPRESS_TYPES]; struct btrfs_compress_op *btrfs_compress_op[] = { &btrfs_zlib_compress, + &btrfs_lzo_compress, }; int __init btrfs_init_compress(void) diff --git a/fs/btrfs/compression.h b/fs/btrfs/compression.h index 9b5f2f365b79..f7ce217113fa 100644 --- a/fs/btrfs/compression.h +++ b/fs/btrfs/compression.h @@ -73,5 +73,6 @@ struct btrfs_compress_op { }; extern struct btrfs_compress_op btrfs_zlib_compress; +extern struct btrfs_compress_op btrfs_lzo_compress; #endif diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index e06534438592..53b984623983 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h @@ -398,13 +398,15 @@ struct btrfs_super_block { #define BTRFS_FEATURE_INCOMPAT_MIXED_BACKREF (1ULL << 0) #define BTRFS_FEATURE_INCOMPAT_DEFAULT_SUBVOL (1ULL << 1) #define BTRFS_FEATURE_INCOMPAT_MIXED_GROUPS (1ULL << 2) +#define BTRFS_FEATURE_INCOMPAT_COMPRESS_LZO (1ULL << 3) #define BTRFS_FEATURE_COMPAT_SUPP 0ULL #define BTRFS_FEATURE_COMPAT_RO_SUPP 0ULL #define BTRFS_FEATURE_INCOMPAT_SUPP \ (BTRFS_FEATURE_INCOMPAT_MIXED_BACKREF | \ BTRFS_FEATURE_INCOMPAT_DEFAULT_SUBVOL | \ - BTRFS_FEATURE_INCOMPAT_MIXED_GROUPS) + BTRFS_FEATURE_INCOMPAT_MIXED_GROUPS | \ + BTRFS_FEATURE_INCOMPAT_COMPRESS_LZO) /* * A leaf is full of items. offset and size tell us where to find @@ -553,8 +555,9 @@ struct btrfs_timespec { enum btrfs_compression_type { BTRFS_COMPRESS_NONE = 0, BTRFS_COMPRESS_ZLIB = 1, - BTRFS_COMPRESS_TYPES = 1, - BTRFS_COMPRESS_LAST = 2, + BTRFS_COMPRESS_LZO = 2, + BTRFS_COMPRESS_TYPES = 2, + BTRFS_COMPRESS_LAST = 3, }; struct btrfs_inode_item { diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index a5d2249e6da5..f88eb2ce7919 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c @@ -1744,10 +1744,10 @@ struct btrfs_root *open_ctree(struct super_block *sb, } features = btrfs_super_incompat_flags(disk_super); - if (!(features & BTRFS_FEATURE_INCOMPAT_MIXED_BACKREF)) { - features |= BTRFS_FEATURE_INCOMPAT_MIXED_BACKREF; - btrfs_set_super_incompat_flags(disk_super, features); - } + features |= BTRFS_FEATURE_INCOMPAT_MIXED_BACKREF; + if (tree_root->fs_info->compress_type & BTRFS_COMPRESS_LZO) + features |= BTRFS_FEATURE_INCOMPAT_COMPRESS_LZO; + btrfs_set_super_incompat_flags(disk_super, features); features = btrfs_super_compat_ro_flags(disk_super) & ~BTRFS_FEATURE_COMPAT_RO_SUPP; diff --git a/fs/btrfs/lzo.c b/fs/btrfs/lzo.c new file mode 100644 index 000000000000..523b144e2aec --- /dev/null +++ b/fs/btrfs/lzo.c @@ -0,0 +1,509 @@ +/* + * Copyright (C) 2008 Oracle. All rights reserved. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License v2 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. + * + * You should have received a copy of the GNU General Public + * License along with this program; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 021110-1307, USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "compression.h" + +#define LZO_LEN 4 + +struct workspace { + void *mem; + void *buf; /* where compressed data goes */ + void *cbuf; /* where decompressed data goes */ + struct list_head list; +}; + +static void lzo_free_workspace(struct list_head *ws) +{ + struct workspace *workspace = list_entry(ws, struct workspace, list); + + vfree(workspace->buf); + vfree(workspace->cbuf); + vfree(workspace->mem); + kfree(workspace); +} + +static struct list_head *lzo_alloc_workspace(void) +{ + struct workspace *workspace; + + workspace = kzalloc(sizeof(*workspace), GFP_NOFS); + if (!workspace) + return ERR_PTR(-ENOMEM); + + workspace->mem = vmalloc(LZO1X_MEM_COMPRESS); + workspace->buf = vmalloc(lzo1x_worst_compress(PAGE_CACHE_SIZE)); + workspace->cbuf = vmalloc(lzo1x_worst_compress(PAGE_CACHE_SIZE)); + if (!workspace->mem || !workspace->buf || !workspace->cbuf) + goto fail; + + INIT_LIST_HEAD(&workspace->list); + + return &workspace->list; +fail: + lzo_free_workspace(&workspace->list); + return ERR_PTR(-ENOMEM); +} + +static inline void write_compress_length(char *buf, size_t len) +{ + __le32 dlen; + + dlen = cpu_to_le32(len); + memcpy(buf, &dlen, LZO_LEN); +} + +static inline size_t read_compress_length(char *buf) +{ + __le32 dlen; + + memcpy(&dlen, buf, LZO_LEN); + return le32_to_cpu(dlen); +} + +static int lzo_compress_pages(struct list_head *ws, + struct address_space *mapping, + u64 start, unsigned long len, + struct page **pages, + unsigned long nr_dest_pages, + unsigned long *out_pages, + unsigned long *total_in, + unsigned long *total_out, + unsigned long max_out) +{ + struct workspace *workspace = list_entry(ws, struct workspace, list); + int ret = 0; + char *data_in; + char *cpage_out; + int nr_pages = 0; + struct page *in_page = NULL; + struct page *out_page = NULL; + unsigned long bytes_left; + + size_t in_len; + size_t out_len; + char *buf; + unsigned long tot_in = 0; + unsigned long tot_out = 0; + unsigned long pg_bytes_left; + unsigned long out_offset; + unsigned long bytes; + + *out_pages = 0; + *total_out = 0; + *total_in = 0; + + in_page = find_get_page(mapping, start >> PAGE_CACHE_SHIFT); + data_in = kmap(in_page); + + /* + * store the size of all chunks of compressed data in + * the first 4 bytes + */ + out_page = alloc_page(GFP_NOFS | __GFP_HIGHMEM); + if (out_page == NULL) { + ret = -ENOMEM; + goto out; + } + cpage_out = kmap(out_page); + out_offset = LZO_LEN; + tot_out = LZO_LEN; + pages[0] = out_page; + nr_pages = 1; + pg_bytes_left = PAGE_CACHE_SIZE - LZO_LEN; + + /* compress at most one page of data each time */ + in_len = min(len, PAGE_CACHE_SIZE); + while (tot_in < len) { + ret = lzo1x_1_compress(data_in, in_len, workspace->cbuf, + &out_len, workspace->mem); + if (ret != LZO_E_OK) { + printk(KERN_DEBUG "btrfs deflate in loop returned %d\n", + ret); + ret = -1; + goto out; + } + + /* store the size of this chunk of compressed data */ + write_compress_length(cpage_out + out_offset, out_len); + tot_out += LZO_LEN; + out_offset += LZO_LEN; + pg_bytes_left -= LZO_LEN; + + tot_in += in_len; + tot_out += out_len; + + /* copy bytes from the working buffer into the pages */ + buf = workspace->cbuf; + while (out_len) { + bytes = min_t(unsigned long, pg_bytes_left, out_len); + + memcpy(cpage_out + out_offset, buf, bytes); + + out_len -= bytes; + pg_bytes_left -= bytes; + buf += bytes; + out_offset += bytes; + + /* + * we need another page for writing out. + * + * Note if there's less than 4 bytes left, we just + * skip to a new page. + */ + if ((out_len == 0 && pg_bytes_left < LZO_LEN) || + pg_bytes_left == 0) { + if (pg_bytes_left) { + memset(cpage_out + out_offset, 0, + pg_bytes_left); + tot_out += pg_bytes_left; + } + + /* we're done, don't allocate new page */ + if (out_len == 0 && tot_in >= len) + break; + + kunmap(out_page); + if (nr_pages == nr_dest_pages) { + out_page = NULL; + ret = -1; + goto out; + } + + out_page = alloc_page(GFP_NOFS | __GFP_HIGHMEM); + if (out_page == NULL) { + ret = -ENOMEM; + goto out; + } + cpage_out = kmap(out_page); + pages[nr_pages++] = out_page; + + pg_bytes_left = PAGE_CACHE_SIZE; + out_offset = 0; + } + } + + /* we're making it bigger, give up */ + if (tot_in > 8192 && tot_in < tot_out) + goto out; + + /* we're all done */ + if (tot_in >= len) + break; + + if (tot_out > max_out) + break; + + bytes_left = len - tot_in; + kunmap(in_page); + page_cache_release(in_page); + + start += PAGE_CACHE_SIZE; + in_page = find_get_page(mapping, start >> PAGE_CACHE_SHIFT); + data_in = kmap(in_page); + in_len = min(bytes_left, PAGE_CACHE_SIZE); + } + + if (tot_out > tot_in) + goto out; + + /* store the size of all chunks of compressed data */ + cpage_out = kmap(pages[0]); + write_compress_length(cpage_out, tot_out); + + kunmap(pages[0]); + + ret = 0; + *total_out = tot_out; + *total_in = tot_in; +out: + *out_pages = nr_pages; + if (out_page) + kunmap(out_page); + + if (in_page) { + kunmap(in_page); + page_cache_release(in_page); + } + + return ret; +} + +static int lzo_decompress_biovec(struct list_head *ws, + struct page **pages_in, + u64 disk_start, + struct bio_vec *bvec, + int vcnt, + size_t srclen) +{ + struct workspace *workspace = list_entry(ws, struct workspace, list); + int ret = 0; + char *data_in; + unsigned long page_bytes_left; + unsigned long page_in_index = 0; + unsigned long page_out_index = 0; + struct page *page_out; + unsigned long total_pages_in = (srclen + PAGE_CACHE_SIZE - 1) / + PAGE_CACHE_SIZE; + unsigned long buf_start; + unsigned long buf_offset = 0; + unsigned long bytes; + unsigned long working_bytes; + unsigned long pg_offset; + unsigned long start_byte; + unsigned long current_buf_start; + char *kaddr; + + size_t in_len; + size_t out_len; + unsigned long in_offset; + unsigned long in_page_bytes_left; + unsigned long tot_in; + unsigned long tot_out; + unsigned long tot_len; + char *buf; + + data_in = kmap(pages_in[0]); + tot_len = read_compress_length(data_in); + + tot_in = LZO_LEN; + in_offset = LZO_LEN; + tot_len = min_t(size_t, srclen, tot_len); + in_page_bytes_left = PAGE_CACHE_SIZE - LZO_LEN; + + tot_out = 0; + page_out = bvec[0].bv_page; + page_bytes_left = PAGE_CACHE_SIZE; + pg_offset = 0; + + while (tot_in < tot_len) { + in_len = read_compress_length(data_in + in_offset); + in_page_bytes_left -= LZO_LEN; + in_offset += LZO_LEN; + tot_in += LZO_LEN; + + tot_in += in_len; + working_bytes = in_len; + + /* fast path: avoid using the working buffer */ + if (in_page_bytes_left >= in_len) { + buf = data_in + in_offset; + bytes = in_len; + goto cont; + } + + /* copy bytes from the pages into the working buffer */ + buf = workspace->cbuf; + buf_offset = 0; + while (working_bytes) { + bytes = min(working_bytes, in_page_bytes_left); + + memcpy(buf + buf_offset, data_in + in_offset, bytes); + buf_offset += bytes; +cont: + working_bytes -= bytes; + in_page_bytes_left -= bytes; + in_offset += bytes; + + /* check if we need to pick another page */ + if ((working_bytes == 0 && in_page_bytes_left < LZO_LEN) + || in_page_bytes_left == 0) { + tot_in += in_page_bytes_left; + + if (working_bytes == 0 && tot_in >= tot_len) + break; + + kunmap(pages_in[page_in_index]); + page_in_index++; + if (page_in_index >= total_pages_in) { + ret = -1; + data_in = NULL; + goto done; + } + data_in = kmap(pages_in[page_in_index]); + + in_page_bytes_left = PAGE_CACHE_SIZE; + in_offset = 0; + } + } + + out_len = lzo1x_worst_compress(PAGE_CACHE_SIZE); + ret = lzo1x_decompress_safe(buf, in_len, workspace->buf, + &out_len); + if (ret != LZO_E_OK) { + printk(KERN_WARNING "btrfs decompress failed\n"); + ret = -1; + break; + } + + /* + * buf start is the byte offset we're of the start of + * our workspace buffer + */ + buf_start = tot_out; + + /* tot_out is the last byte of the workspace buffer */ + tot_out += out_len; + + working_bytes = tot_out - buf_start; + + /* + * start_byte is the first byte of the page we're currently + * copying into relative to the start of the compressed data. + */ + start_byte = page_offset(page_out) - disk_start; + + if (working_bytes == 0) { + /* we didn't make progress in this inflate + * call, we're done + */ + break; + } + + /* we haven't yet hit data corresponding to this page */ + if (tot_out <= start_byte) + continue; + + /* + * the start of the data we care about is offset into + * the middle of our working buffer + */ + if (tot_out > start_byte && buf_start < start_byte) { + buf_offset = start_byte - buf_start; + working_bytes -= buf_offset; + } else { + buf_offset = 0; + } + current_buf_start = buf_start; + + /* copy bytes from the working buffer into the pages */ + while (working_bytes > 0) { + bytes = min(PAGE_CACHE_SIZE - pg_offset, + PAGE_CACHE_SIZE - buf_offset); + bytes = min(bytes, working_bytes); + kaddr = kmap_atomic(page_out, KM_USER0); + memcpy(kaddr + pg_offset, workspace->buf + buf_offset, + bytes); + kunmap_atomic(kaddr, KM_USER0); + flush_dcache_page(page_out); + + pg_offset += bytes; + page_bytes_left -= bytes; + buf_offset += bytes; + working_bytes -= bytes; + current_buf_start += bytes; + + /* check if we need to pick another page */ + if (page_bytes_left == 0) { + page_out_index++; + if (page_out_index >= vcnt) { + ret = 0; + goto done; + } + + page_out = bvec[page_out_index].bv_page; + pg_offset = 0; + page_bytes_left = PAGE_CACHE_SIZE; + start_byte = page_offset(page_out) - disk_start; + + /* + * make sure our new page is covered by this + * working buffer + */ + if (tot_out <= start_byte) + break; + + /* the next page in the biovec might not + * be adjacent to the last page, but it + * might still be found inside this working + * buffer. bump our offset pointer + */ + if (tot_out > start_byte && + current_buf_start < start_byte) { + buf_offset = start_byte - buf_start; + working_bytes = tot_out - start_byte; + current_buf_start = buf_start + + buf_offset; + } + } + } + } +done: + if (data_in) + kunmap(pages_in[page_in_index]); + return ret; +} + +static int lzo_decompress(struct list_head *ws, unsigned char *data_in, + struct page *dest_page, + unsigned long start_byte, + size_t srclen, size_t destlen) +{ + struct workspace *workspace = list_entry(ws, struct workspace, list); + size_t in_len; + size_t out_len; + size_t tot_len; + int ret = 0; + char *kaddr; + unsigned long bytes; + + BUG_ON(srclen < LZO_LEN); + + tot_len = read_compress_length(data_in); + data_in += LZO_LEN; + + in_len = read_compress_length(data_in); + data_in += LZO_LEN; + + out_len = PAGE_CACHE_SIZE; + ret = lzo1x_decompress_safe(data_in, in_len, workspace->buf, &out_len); + if (ret != LZO_E_OK) { + printk(KERN_WARNING "btrfs decompress failed!\n"); + ret = -1; + goto out; + } + + if (out_len < start_byte) { + ret = -1; + goto out; + } + + bytes = min_t(unsigned long, destlen, out_len - start_byte); + + kaddr = kmap_atomic(dest_page, KM_USER0); + memcpy(kaddr, workspace->buf + start_byte, bytes); + kunmap_atomic(kaddr, KM_USER0); +out: + return ret; +} + +struct btrfs_compress_op btrfs_lzo_compress = { + .alloc_workspace = lzo_alloc_workspace, + .free_workspace = lzo_free_workspace, + .compress_pages = lzo_compress_pages, + .decompress_biovec = lzo_decompress_biovec, + .decompress = lzo_decompress, +}; diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index f348f2b93164..a1a76b2a61f9 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c @@ -168,6 +168,9 @@ int btrfs_parse_options(struct btrfs_root *root, char *options) strcmp(args[0].from, "zlib") == 0) { compress_type = "zlib"; info->compress_type = BTRFS_COMPRESS_ZLIB; + } else if (strcmp(args[0].from, "lzo") == 0) { + compress_type = "lzo"; + info->compress_type = BTRFS_COMPRESS_LZO; } else { ret = -EINVAL; goto out; -- cgit v1.2.3 From 1a419d85a76853d7d04e9b6280a80e96770bf3e3 Mon Sep 17 00:00:00 2001 From: Li Zefan Date: Mon, 25 Oct 2010 15:12:50 +0800 Subject: btrfs: Allow to specify compress method when defrag Update defrag ioctl, so one can choose lzo or zlib when turning on compression in defrag operation. Changelog: v1 -> v2 - Add incompability flag. - Fix to check invalid compress type. Signed-off-by: Li Zefan --- fs/btrfs/ioctl.c | 19 ++++++++++++++++++- fs/btrfs/ioctl.h | 9 ++++++++- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 8cb86d4d763c..b6985d33eede 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c @@ -638,9 +638,11 @@ static int btrfs_defrag_file(struct file *file, struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree; struct btrfs_ordered_extent *ordered; struct page *page; + struct btrfs_super_block *disk_super; unsigned long last_index; unsigned long ra_pages = root->fs_info->bdi.ra_pages; unsigned long total_read = 0; + u64 features; u64 page_start; u64 page_end; u64 last_len = 0; @@ -648,6 +650,14 @@ static int btrfs_defrag_file(struct file *file, u64 defrag_end = 0; unsigned long i; int ret; + int compress_type = BTRFS_COMPRESS_ZLIB; + + if (range->flags & BTRFS_DEFRAG_RANGE_COMPRESS) { + if (range->compress_type > BTRFS_COMPRESS_TYPES) + return -EINVAL; + if (range->compress_type) + compress_type = range->compress_type; + } if (inode->i_size == 0) return 0; @@ -683,7 +693,7 @@ static int btrfs_defrag_file(struct file *file, total_read++; mutex_lock(&inode->i_mutex); if (range->flags & BTRFS_DEFRAG_RANGE_COMPRESS) - BTRFS_I(inode)->force_compress = BTRFS_COMPRESS_ZLIB; + BTRFS_I(inode)->force_compress = compress_type; ret = btrfs_delalloc_reserve_space(inode, PAGE_CACHE_SIZE); if (ret) @@ -785,6 +795,13 @@ loop_unlock: mutex_unlock(&inode->i_mutex); } + disk_super = &root->fs_info->super_copy; + features = btrfs_super_incompat_flags(disk_super); + if (range->compress_type == BTRFS_COMPRESS_LZO) { + features |= BTRFS_FEATURE_INCOMPAT_COMPRESS_LZO; + btrfs_set_super_incompat_flags(disk_super, features); + } + return 0; err_reservations: diff --git a/fs/btrfs/ioctl.h b/fs/btrfs/ioctl.h index c344d12c646b..24d0f4628240 100644 --- a/fs/btrfs/ioctl.h +++ b/fs/btrfs/ioctl.h @@ -133,8 +133,15 @@ struct btrfs_ioctl_defrag_range_args { */ __u32 extent_thresh; + /* + * which compression method to use if turning on compression + * for this defrag operation. If unspecified, zlib will + * be used + */ + __u32 compress_type; + /* spare for later */ - __u32 unused[5]; + __u32 unused[4]; }; struct btrfs_ioctl_space_info { -- cgit v1.2.3 From 3a39c18d63fec35f49df577d4b2a4e29c2212f22 Mon Sep 17 00:00:00 2001 From: Li Zefan Date: Mon, 8 Nov 2010 15:22:19 +0800 Subject: btrfs: Extract duplicate decompress code Add a common function to copy decompressed data from working buffer to bio pages. Signed-off-by: Li Zefan --- fs/btrfs/compression.c | 92 ++++++++++++++++++++++++++++++++++++++++ fs/btrfs/compression.h | 5 +++ fs/btrfs/lzo.c | 101 +++----------------------------------------- fs/btrfs/zlib.c | 111 ++++++------------------------------------------- 4 files changed, 115 insertions(+), 194 deletions(-) diff --git a/fs/btrfs/compression.c b/fs/btrfs/compression.c index 8faa2df9e719..f745287fbf2e 100644 --- a/fs/btrfs/compression.c +++ b/fs/btrfs/compression.c @@ -904,3 +904,95 @@ void __exit btrfs_exit_compress(void) { free_workspaces(); } + +/* + * Copy uncompressed data from working buffer to pages. + * + * buf_start is the byte offset we're of the start of our workspace buffer. + * + * total_out is the last byte of the buffer + */ +int btrfs_decompress_buf2page(char *buf, unsigned long buf_start, + unsigned long total_out, u64 disk_start, + struct bio_vec *bvec, int vcnt, + unsigned long *page_index, + unsigned long *pg_offset) +{ + unsigned long buf_offset; + unsigned long current_buf_start; + unsigned long start_byte; + unsigned long working_bytes = total_out - buf_start; + unsigned long bytes; + char *kaddr; + struct page *page_out = bvec[*page_index].bv_page; + + /* + * start byte is the first byte of the page we're currently + * copying into relative to the start of the compressed data. + */ + start_byte = page_offset(page_out) - disk_start; + + /* we haven't yet hit data corresponding to this page */ + if (total_out <= start_byte) + return 1; + + /* + * the start of the data we care about is offset into + * the middle of our working buffer + */ + if (total_out > start_byte && buf_start < start_byte) { + buf_offset = start_byte - buf_start; + working_bytes -= buf_offset; + } else { + buf_offset = 0; + } + current_buf_start = buf_start; + + /* copy bytes from the working buffer into the pages */ + while (working_bytes > 0) { + bytes = min(PAGE_CACHE_SIZE - *pg_offset, + PAGE_CACHE_SIZE - buf_offset); + bytes = min(bytes, working_bytes); + kaddr = kmap_atomic(page_out, KM_USER0); + memcpy(kaddr + *pg_offset, buf + buf_offset, bytes); + kunmap_atomic(kaddr, KM_USER0); + flush_dcache_page(page_out); + + *pg_offset += bytes; + buf_offset += bytes; + working_bytes -= bytes; + current_buf_start += bytes; + + /* check if we need to pick another page */ + if (*pg_offset == PAGE_CACHE_SIZE) { + (*page_index)++; + if (*page_index >= vcnt) + return 0; + + page_out = bvec[*page_index].bv_page; + *pg_offset = 0; + start_byte = page_offset(page_out) - disk_start; + + /* + * make sure our new page is covered by this + * working buffer + */ + if (total_out <= start_byte) + return 1; + + /* + * the next page in the biovec might not be adjacent + * to the last page, but it might still be found + * inside this working buffer. bump our offset pointer + */ + if (total_out > start_byte && + current_buf_start < start_byte) { + buf_offset = start_byte - buf_start; + working_bytes = total_out - start_byte; + current_buf_start = buf_start + buf_offset; + } + } + } + + return 1; +} diff --git a/fs/btrfs/compression.h b/fs/btrfs/compression.h index f7ce217113fa..51000174b9d7 100644 --- a/fs/btrfs/compression.h +++ b/fs/btrfs/compression.h @@ -34,6 +34,11 @@ int btrfs_decompress_biovec(int type, struct page **pages_in, u64 disk_start, struct bio_vec *bvec, int vcnt, size_t srclen); int btrfs_decompress(int type, unsigned char *data_in, struct page *dest_page, unsigned long start_byte, size_t srclen, size_t destlen); +int btrfs_decompress_buf2page(char *buf, unsigned long buf_start, + unsigned long total_out, u64 disk_start, + struct bio_vec *bvec, int vcnt, + unsigned long *page_index, + unsigned long *pg_offset); int btrfs_submit_compressed_write(struct inode *inode, u64 start, unsigned long len, u64 disk_start, diff --git a/fs/btrfs/lzo.c b/fs/btrfs/lzo.c index 523b144e2aec..cc9b450399df 100644 --- a/fs/btrfs/lzo.c +++ b/fs/btrfs/lzo.c @@ -260,12 +260,10 @@ static int lzo_decompress_biovec(struct list_head *ws, size_t srclen) { struct workspace *workspace = list_entry(ws, struct workspace, list); - int ret = 0; + int ret = 0, ret2; char *data_in; - unsigned long page_bytes_left; unsigned long page_in_index = 0; unsigned long page_out_index = 0; - struct page *page_out; unsigned long total_pages_in = (srclen + PAGE_CACHE_SIZE - 1) / PAGE_CACHE_SIZE; unsigned long buf_start; @@ -273,9 +271,6 @@ static int lzo_decompress_biovec(struct list_head *ws, unsigned long bytes; unsigned long working_bytes; unsigned long pg_offset; - unsigned long start_byte; - unsigned long current_buf_start; - char *kaddr; size_t in_len; size_t out_len; @@ -295,8 +290,6 @@ static int lzo_decompress_biovec(struct list_head *ws, in_page_bytes_left = PAGE_CACHE_SIZE - LZO_LEN; tot_out = 0; - page_out = bvec[0].bv_page; - page_bytes_left = PAGE_CACHE_SIZE; pg_offset = 0; while (tot_in < tot_len) { @@ -359,97 +352,15 @@ cont: break; } - /* - * buf start is the byte offset we're of the start of - * our workspace buffer - */ buf_start = tot_out; - - /* tot_out is the last byte of the workspace buffer */ tot_out += out_len; - working_bytes = tot_out - buf_start; - - /* - * start_byte is the first byte of the page we're currently - * copying into relative to the start of the compressed data. - */ - start_byte = page_offset(page_out) - disk_start; - - if (working_bytes == 0) { - /* we didn't make progress in this inflate - * call, we're done - */ + ret2 = btrfs_decompress_buf2page(workspace->buf, buf_start, + tot_out, disk_start, + bvec, vcnt, + &page_out_index, &pg_offset); + if (ret2 == 0) break; - } - - /* we haven't yet hit data corresponding to this page */ - if (tot_out <= start_byte) - continue; - - /* - * the start of the data we care about is offset into - * the middle of our working buffer - */ - if (tot_out > start_byte && buf_start < start_byte) { - buf_offset = start_byte - buf_start; - working_bytes -= buf_offset; - } else { - buf_offset = 0; - } - current_buf_start = buf_start; - - /* copy bytes from the working buffer into the pages */ - while (working_bytes > 0) { - bytes = min(PAGE_CACHE_SIZE - pg_offset, - PAGE_CACHE_SIZE - buf_offset); - bytes = min(bytes, working_bytes); - kaddr = kmap_atomic(page_out, KM_USER0); - memcpy(kaddr + pg_offset, workspace->buf + buf_offset, - bytes); - kunmap_atomic(kaddr, KM_USER0); - flush_dcache_page(page_out); - - pg_offset += bytes; - page_bytes_left -= bytes; - buf_offset += bytes; - working_bytes -= bytes; - current_buf_start += bytes; - - /* check if we need to pick another page */ - if (page_bytes_left == 0) { - page_out_index++; - if (page_out_index >= vcnt) { - ret = 0; - goto done; - } - - page_out = bvec[page_out_index].bv_page; - pg_offset = 0; - page_bytes_left = PAGE_CACHE_SIZE; - start_byte = page_offset(page_out) - disk_start; - - /* - * make sure our new page is covered by this - * working buffer - */ - if (tot_out <= start_byte) - break; - - /* the next page in the biovec might not - * be adjacent to the last page, but it - * might still be found inside this working - * buffer. bump our offset pointer - */ - if (tot_out > start_byte && - current_buf_start < start_byte) { - buf_offset = start_byte - buf_start; - working_bytes = tot_out - start_byte; - current_buf_start = buf_start + - buf_offset; - } - } - } } done: if (data_in) diff --git a/fs/btrfs/zlib.c b/fs/btrfs/zlib.c index 9a3e693917f2..f5ec2d44150d 100644 --- a/fs/btrfs/zlib.c +++ b/fs/btrfs/zlib.c @@ -218,24 +218,16 @@ static int zlib_decompress_biovec(struct list_head *ws, struct page **pages_in, size_t srclen) { struct workspace *workspace = list_entry(ws, struct workspace, list); - int ret = 0; + int ret = 0, ret2; int wbits = MAX_WBITS; char *data_in; size_t total_out = 0; - unsigned long page_bytes_left; unsigned long page_in_index = 0; unsigned long page_out_index = 0; - struct page *page_out; unsigned long total_pages_in = (srclen + PAGE_CACHE_SIZE - 1) / PAGE_CACHE_SIZE; unsigned long buf_start; - unsigned long buf_offset; - unsigned long bytes; - unsigned long working_bytes; unsigned long pg_offset; - unsigned long start_byte; - unsigned long current_buf_start; - char *kaddr; data_in = kmap(pages_in[page_in_index]); workspace->inf_strm.next_in = data_in; @@ -245,8 +237,6 @@ static int zlib_decompress_biovec(struct list_head *ws, struct page **pages_in, workspace->inf_strm.total_out = 0; workspace->inf_strm.next_out = workspace->buf; workspace->inf_strm.avail_out = PAGE_CACHE_SIZE; - page_out = bvec[page_out_index].bv_page; - page_bytes_left = PAGE_CACHE_SIZE; pg_offset = 0; /* If it's deflate, and it's got no preset dictionary, then @@ -268,100 +258,23 @@ static int zlib_decompress_biovec(struct list_head *ws, struct page **pages_in, ret = zlib_inflate(&workspace->inf_strm, Z_NO_FLUSH); if (ret != Z_OK && ret != Z_STREAM_END) break; - /* - * buf start is the byte offset we're of the start of - * our workspace buffer - */ - buf_start = total_out; - /* total_out is the last byte of the workspace buffer */ + buf_start = total_out; total_out = workspace->inf_strm.total_out; - working_bytes = total_out - buf_start; - - /* - * start byte is the first byte of the page we're currently - * copying into relative to the start of the compressed data. - */ - start_byte = page_offset(page_out) - disk_start; - - if (working_bytes == 0) { - /* we didn't make progress in this inflate - * call, we're done - */ - if (ret != Z_STREAM_END) - ret = -1; + /* we didn't make progress in this inflate call, we're done */ + if (buf_start == total_out) break; - } - /* we haven't yet hit data corresponding to this page */ - if (total_out <= start_byte) - goto next; - - /* - * the start of the data we care about is offset into - * the middle of our working buffer - */ - if (total_out > start_byte && buf_start < start_byte) { - buf_offset = start_byte - buf_start; - working_bytes -= buf_offset; - } else { - buf_offset = 0; - } - current_buf_start = buf_start; - - /* copy bytes from the working buffer into the pages */ - while (working_bytes > 0) { - bytes = min(PAGE_CACHE_SIZE - pg_offset, - PAGE_CACHE_SIZE - buf_offset); - bytes = min(bytes, working_bytes); - kaddr = kmap_atomic(page_out, KM_USER0); - memcpy(kaddr + pg_offset, workspace->buf + buf_offset, - bytes); - kunmap_atomic(kaddr, KM_USER0); - flush_dcache_page(page_out); - - pg_offset += bytes; - page_bytes_left -= bytes; - buf_offset += bytes; - working_bytes -= bytes; - current_buf_start += bytes; - - /* check if we need to pick another page */ - if (page_bytes_left == 0) { - page_out_index++; - if (page_out_index >= vcnt) { - ret = 0; - goto done; - } - - page_out = bvec[page_out_index].bv_page; - pg_offset = 0; - page_bytes_left = PAGE_CACHE_SIZE; - start_byte = page_offset(page_out) - disk_start; - - /* - * make sure our new page is covered by this - * working buffer - */ - if (total_out <= start_byte) - goto next; - - /* the next page in the biovec might not - * be adjacent to the last page, but it - * might still be found inside this working - * buffer. bump our offset pointer - */ - if (total_out > start_byte && - current_buf_start < start_byte) { - buf_offset = start_byte - buf_start; - working_bytes = total_out - start_byte; - current_buf_start = buf_start + - buf_offset; - } - } + ret2 = btrfs_decompress_buf2page(workspace->buf, buf_start, + total_out, disk_start, + bvec, vcnt, + &page_out_index, &pg_offset); + if (ret2 == 0) { + ret = 0; + goto done; } -next: + workspace->inf_strm.next_out = workspace->buf; workspace->inf_strm.avail_out = PAGE_CACHE_SIZE; -- cgit v1.2.3 From 43d547f9ce039e5a9d2401c8f2fbfa29932b6b4f Mon Sep 17 00:00:00 2001 From: Jim Cromie Date: Fri, 17 Dec 2010 14:32:36 -0700 Subject: init/Kconfig: fix typo MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by:  Jim Cromie Signed-off-by: Jiri Kosina --- init/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/init/Kconfig b/init/Kconfig index c9728992a776..dd43d8e22980 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -620,7 +620,7 @@ config CGROUP_MEM_RES_CTLR_SWAP_ENABLED help Memory Resource Controller Swap Extension comes with its price in a bigger memory consumption. General purpose distribution kernels - which want to enable the feautre but keep it disabled by default + which want to enable the feature but keep it disabled by default and let the user enable it by swapaccount boot command line parameter should have this option unselected. For those who want to have the feature enabled by default should -- cgit v1.2.3 From 43b210139a3cb09d49a18f0dc9bed3674c55f235 Mon Sep 17 00:00:00 2001 From: Namhyung Kim Date: Wed, 22 Dec 2010 19:01:47 +0100 Subject: hrtimer: fix a typo in comment Signed-off-by: Namhyung Kim Signed-off-by: Jiri Kosina --- kernel/hrtimer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/hrtimer.c b/kernel/hrtimer.c index 72206cf5c6cf..66163dfe810b 100644 --- a/kernel/hrtimer.c +++ b/kernel/hrtimer.c @@ -1774,7 +1774,7 @@ schedule_hrtimeout_range_clock(ktime_t *expires, unsigned long delta, } /* - * A NULL parameter means "inifinte" + * A NULL parameter means "infinite" */ if (!expires) { schedule(); -- cgit v1.2.3 From 68229689b6dc950bea4b81dd60563884f4a7e1c5 Mon Sep 17 00:00:00 2001 From: Oliver Neukum Date: Wed, 22 Dec 2010 15:33:40 +0100 Subject: HID: usbhid: base runtime PM on modern API This patch doesn't alter functionality, but removes a dedicated kernel thread. Signed-off-by: Oliver Neukum Tested-by: Maulik Mankad Signed-off-by: Jiri Kosina --- drivers/hid/usbhid/hid-core.c | 57 +++++++++++++++---------------------------- drivers/hid/usbhid/usbhid.h | 1 - 2 files changed, 19 insertions(+), 39 deletions(-) diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c index 276758f53ab5..b336dd84036f 100644 --- a/drivers/hid/usbhid/hid-core.c +++ b/drivers/hid/usbhid/hid-core.c @@ -67,7 +67,6 @@ MODULE_PARM_DESC(quirks, "Add/modify USB HID quirks by specifying " * Input submission and I/O error handler. */ static DEFINE_MUTEX(hid_open_mut); -static struct workqueue_struct *resumption_waker; static void hid_io_error(struct hid_device *hid); static int hid_submit_out(struct hid_device *hid); @@ -300,10 +299,19 @@ static int hid_submit_out(struct hid_device *hid) struct hid_report *report; char *raw_report; struct usbhid_device *usbhid = hid->driver_data; + int r; report = usbhid->out[usbhid->outtail].report; raw_report = usbhid->out[usbhid->outtail].raw_report; + r = usb_autopm_get_interface_async(usbhid->intf); + if (r < 0) + return -1; + + /* + * if the device hasn't been woken, we leave the output + * to resume() + */ if (!test_bit(HID_REPORTED_IDLE, &usbhid->iofl)) { usbhid->urbout->transfer_buffer_length = ((report->size - 1) >> 3) + 1 + (report->id > 0); usbhid->urbout->dev = hid_to_usb_dev(hid); @@ -314,16 +322,10 @@ static int hid_submit_out(struct hid_device *hid) if (usb_submit_urb(usbhid->urbout, GFP_ATOMIC)) { hid_err(hid, "usb_submit_urb(out) failed\n"); + usb_autopm_put_interface_async(usbhid->intf); return -1; } usbhid->last_out = jiffies; - } else { - /* - * queue work to wake up the device. - * as the work queue is freezeable, this is safe - * with respect to STD and STR - */ - queue_work(resumption_waker, &usbhid->restart_work); } return 0; @@ -334,13 +336,16 @@ static int hid_submit_ctrl(struct hid_device *hid) struct hid_report *report; unsigned char dir; char *raw_report; - int len; + int len, r; struct usbhid_device *usbhid = hid->driver_data; report = usbhid->ctrl[usbhid->ctrltail].report; raw_report = usbhid->ctrl[usbhid->ctrltail].raw_report; dir = usbhid->ctrl[usbhid->ctrltail].dir; + r = usb_autopm_get_interface_async(usbhid->intf); + if (r < 0) + return -1; if (!test_bit(HID_REPORTED_IDLE, &usbhid->iofl)) { len = ((report->size - 1) >> 3) + 1 + (report->id > 0); if (dir == USB_DIR_OUT) { @@ -375,17 +380,11 @@ static int hid_submit_ctrl(struct hid_device *hid) usbhid->cr->wValue, usbhid->cr->wIndex, usbhid->cr->wLength); if (usb_submit_urb(usbhid->urbctrl, GFP_ATOMIC)) { + usb_autopm_put_interface_async(usbhid->intf); hid_err(hid, "usb_submit_urb(ctrl) failed\n"); return -1; } usbhid->last_ctrl = jiffies; - } else { - /* - * queue work to wake up the device. - * as the work queue is freezeable, this is safe - * with respect to STD and STR - */ - queue_work(resumption_waker, &usbhid->restart_work); } return 0; @@ -435,6 +434,7 @@ static void hid_irq_out(struct urb *urb) clear_bit(HID_OUT_RUNNING, &usbhid->iofl); spin_unlock_irqrestore(&usbhid->lock, flags); + usb_autopm_put_interface_async(usbhid->intf); wake_up(&usbhid->wait); } @@ -480,11 +480,13 @@ static void hid_ctrl(struct urb *urb) wake_up(&usbhid->wait); } spin_unlock(&usbhid->lock); + usb_autopm_put_interface_async(usbhid->intf); return; } clear_bit(HID_CTRL_RUNNING, &usbhid->iofl); spin_unlock(&usbhid->lock); + usb_autopm_put_interface_async(usbhid->intf); wake_up(&usbhid->wait); } @@ -655,7 +657,7 @@ int usbhid_open(struct hid_device *hid) mutex_lock(&hid_open_mut); if (!hid->open++) { res = usb_autopm_get_interface(usbhid->intf); - /* the device must be awake to reliable request remote wakeup */ + /* the device must be awake to reliably request remote wakeup */ if (res < 0) { hid->open--; mutex_unlock(&hid_open_mut); @@ -856,18 +858,6 @@ static void usbhid_restart_queues(struct usbhid_device *usbhid) usbhid_restart_ctrl_queue(usbhid); } -static void __usbhid_restart_queues(struct work_struct *work) -{ - struct usbhid_device *usbhid = - container_of(work, struct usbhid_device, restart_work); - int r; - - r = usb_autopm_get_interface(usbhid->intf); - if (r < 0) - return; - usb_autopm_put_interface(usbhid->intf); -} - static void hid_free_buffers(struct usb_device *dev, struct hid_device *hid) { struct usbhid_device *usbhid = hid->driver_data; @@ -1204,7 +1194,6 @@ static int usbhid_probe(struct usb_interface *intf, const struct usb_device_id * init_waitqueue_head(&usbhid->wait); INIT_WORK(&usbhid->reset_work, hid_reset); - INIT_WORK(&usbhid->restart_work, __usbhid_restart_queues); setup_timer(&usbhid->io_retry, hid_retry_timeout, (unsigned long) hid); spin_lock_init(&usbhid->lock); @@ -1239,7 +1228,6 @@ static void usbhid_disconnect(struct usb_interface *intf) static void hid_cancel_delayed_stuff(struct usbhid_device *usbhid) { del_timer_sync(&usbhid->io_retry); - cancel_work_sync(&usbhid->restart_work); cancel_work_sync(&usbhid->reset_work); } @@ -1260,7 +1248,6 @@ static int hid_pre_reset(struct usb_interface *intf) spin_lock_irq(&usbhid->lock); set_bit(HID_RESET_PENDING, &usbhid->iofl); spin_unlock_irq(&usbhid->lock); - cancel_work_sync(&usbhid->restart_work); hid_cease_io(usbhid); return 0; @@ -1459,9 +1446,6 @@ static int __init hid_init(void) { int retval = -ENOMEM; - resumption_waker = create_freezeable_workqueue("usbhid_resumer"); - if (!resumption_waker) - goto no_queue; retval = hid_register_driver(&hid_usb_driver); if (retval) goto hid_register_fail; @@ -1479,8 +1463,6 @@ usb_register_fail: usbhid_quirks_init_fail: hid_unregister_driver(&hid_usb_driver); hid_register_fail: - destroy_workqueue(resumption_waker); -no_queue: return retval; } @@ -1489,7 +1471,6 @@ static void __exit hid_exit(void) usb_deregister(&hid_driver); usbhid_quirks_exit(); hid_unregister_driver(&hid_usb_driver); - destroy_workqueue(resumption_waker); } module_init(hid_init); diff --git a/drivers/hid/usbhid/usbhid.h b/drivers/hid/usbhid/usbhid.h index 89d2e847dcc6..1673cac93d77 100644 --- a/drivers/hid/usbhid/usbhid.h +++ b/drivers/hid/usbhid/usbhid.h @@ -95,7 +95,6 @@ struct usbhid_device { unsigned long stop_retry; /* Time to give up, in jiffies */ unsigned int retry_delay; /* Delay length in ms */ struct work_struct reset_work; /* Task context for resets */ - struct work_struct restart_work; /* waking up for output to be done in a task */ wait_queue_head_t wait; /* For sleeping */ int ledcount; /* counting the number of active leds */ }; -- cgit v1.2.3 From a3ba81131aca243bfecfa78c42edec0cd69f72d6 Mon Sep 17 00:00:00 2001 From: Ben Gamari Date: Wed, 22 Dec 2010 13:30:14 -0500 Subject: Make fixdep error handling more explicit Also add missing error handling to fstat call Signed-off-by: Ben Gamari Signed-off-by: Michal Marek --- scripts/basic/fixdep.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/scripts/basic/fixdep.c b/scripts/basic/fixdep.c index ed0584623690..c9a16abacab4 100644 --- a/scripts/basic/fixdep.c +++ b/scripts/basic/fixdep.c @@ -286,7 +286,7 @@ static void do_config_file(const char *filename) fd = open(filename, O_RDONLY); if (fd < 0) { - fprintf(stderr, "fixdep: "); + fprintf(stderr, "fixdep: error opening config file: "); perror(filename); exit(2); } @@ -357,11 +357,15 @@ static void print_deps(void) fd = open(depfile, O_RDONLY); if (fd < 0) { - fprintf(stderr, "fixdep: "); + fprintf(stderr, "fixdep: error opening depfile: "); perror(depfile); exit(2); } - fstat(fd, &st); + if (fstat(fd, &st) < 0) { + fprintf(stderr, "fixdep: error fstat'ing depfile: "); + perror(depfile); + exit(2); + } if (st.st_size == 0) { fprintf(stderr,"fixdep: %s is empty\n",depfile); close(fd); -- cgit v1.2.3 From fa0d2b9bd717340e0bc4850a80ac0eb344e9a7fb Mon Sep 17 00:00:00 2001 From: Li Zefan Date: Mon, 20 Dec 2010 15:53:28 +0800 Subject: Btrfs: Refactor btrfs_ioctl_snap_create() Split it into two functions for two different ioctls, since they share no common code. Signed-off-by: Li Zefan --- fs/btrfs/ioctl.c | 84 +++++++++++++++++++++++++++----------------------------- 1 file changed, 40 insertions(+), 44 deletions(-) diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index f87552a1d7ea..02554e19d974 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c @@ -946,58 +946,54 @@ out: } static noinline int btrfs_ioctl_snap_create(struct file *file, - void __user *arg, int subvol, - int v2) + void __user *arg, int subvol) { - struct btrfs_ioctl_vol_args *vol_args = NULL; - struct btrfs_ioctl_vol_args_v2 *vol_args_v2 = NULL; - char *name; - u64 fd; + struct btrfs_ioctl_vol_args *vol_args; int ret; - if (v2) { - u64 transid = 0; - u64 *ptr = NULL; + vol_args = memdup_user(arg, sizeof(*vol_args)); + if (IS_ERR(vol_args)) + return PTR_ERR(vol_args); + vol_args->name[BTRFS_PATH_NAME_MAX] = '\0'; - vol_args_v2 = memdup_user(arg, sizeof(*vol_args_v2)); - if (IS_ERR(vol_args_v2)) - return PTR_ERR(vol_args_v2); + ret = btrfs_ioctl_snap_create_transid(file, vol_args->name, + vol_args->fd, subvol, NULL); - if (vol_args_v2->flags & ~BTRFS_SUBVOL_CREATE_ASYNC) { - ret = -EINVAL; - goto out; - } - - name = vol_args_v2->name; - fd = vol_args_v2->fd; - vol_args_v2->name[BTRFS_SUBVOL_NAME_MAX] = '\0'; + kfree(vol_args); + return ret; +} - if (vol_args_v2->flags & BTRFS_SUBVOL_CREATE_ASYNC) - ptr = &transid; +static noinline int btrfs_ioctl_snap_create_v2(struct file *file, + void __user *arg, int subvol) +{ + struct btrfs_ioctl_vol_args_v2 *vol_args; + int ret; + u64 transid = 0; + u64 *ptr = NULL; - ret = btrfs_ioctl_snap_create_transid(file, name, fd, - subvol, ptr); + vol_args = memdup_user(arg, sizeof(*vol_args)); + if (IS_ERR(vol_args)) + return PTR_ERR(vol_args); + vol_args->name[BTRFS_SUBVOL_NAME_MAX] = '\0'; - if (ret == 0 && ptr && - copy_to_user(arg + - offsetof(struct btrfs_ioctl_vol_args_v2, - transid), ptr, sizeof(*ptr))) - ret = -EFAULT; - } else { - vol_args = memdup_user(arg, sizeof(*vol_args)); - if (IS_ERR(vol_args)) - return PTR_ERR(vol_args); - name = vol_args->name; - fd = vol_args->fd; - vol_args->name[BTRFS_PATH_NAME_MAX] = '\0'; - - ret = btrfs_ioctl_snap_create_transid(file, name, fd, - subvol, NULL); + if (vol_args->flags & ~BTRFS_SUBVOL_CREATE_ASYNC) { + ret = -EINVAL; + goto out; } + + if (vol_args->flags & BTRFS_SUBVOL_CREATE_ASYNC) + ptr = &transid; + + ret = btrfs_ioctl_snap_create_transid(file, vol_args->name, + vol_args->fd, subvol, ptr); + + if (ret == 0 && ptr && + copy_to_user(arg + + offsetof(struct btrfs_ioctl_vol_args_v2, + transid), ptr, sizeof(*ptr))) + ret = -EFAULT; out: kfree(vol_args); - kfree(vol_args_v2); - return ret; } @@ -2257,11 +2253,11 @@ long btrfs_ioctl(struct file *file, unsigned int case FS_IOC_GETVERSION: return btrfs_ioctl_getversion(file, argp); case BTRFS_IOC_SNAP_CREATE: - return btrfs_ioctl_snap_create(file, argp, 0, 0); + return btrfs_ioctl_snap_create(file, argp, 0); case BTRFS_IOC_SNAP_CREATE_V2: - return btrfs_ioctl_snap_create(file, argp, 0, 1); + return btrfs_ioctl_snap_create_v2(file, argp, 0); case BTRFS_IOC_SUBVOL_CREATE: - return btrfs_ioctl_snap_create(file, argp, 1, 0); + return btrfs_ioctl_snap_create(file, argp, 1); case BTRFS_IOC_SNAP_DESTROY: return btrfs_ioctl_snap_destroy(file, argp); case BTRFS_IOC_DEFAULT_SUBVOL: -- cgit v1.2.3 From b83cc9693f39689490970c19f6c5b866f6719a70 Mon Sep 17 00:00:00 2001 From: Li Zefan Date: Mon, 20 Dec 2010 16:04:08 +0800 Subject: Btrfs: Add readonly snapshots support Usage: Set BTRFS_SUBVOL_RDONLY of btrfs_ioctl_vol_arg_v2->flags, and call ioctl(BTRFS_I0CTL_SNAP_CREATE_V2). Implementation: - Set readonly bit of btrfs_root_item->flags. - Add readonly checks in btrfs_permission (inode_permission), btrfs_setattr, btrfs_set/remove_xattr and some ioctls. Changelog for v3: - Eliminate btrfs_root->readonly, but check btrfs_root->root_item.flags. - Rename BTRFS_ROOT_SNAP_RDONLY to BTRFS_ROOT_SUBVOL_RDONLY. Signed-off-by: Li Zefan --- fs/btrfs/ctree.h | 7 +++++++ fs/btrfs/inode.c | 8 ++++++++ fs/btrfs/ioctl.c | 42 ++++++++++++++++++++++++++++++++---------- fs/btrfs/ioctl.h | 1 + fs/btrfs/transaction.c | 8 ++++++++ fs/btrfs/transaction.h | 1 + fs/btrfs/xattr.c | 18 ++++++++++++++++++ 7 files changed, 75 insertions(+), 10 deletions(-) diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index af52f6d7a4d8..4403e5643d43 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h @@ -597,6 +597,8 @@ struct btrfs_dir_item { u8 type; } __attribute__ ((__packed__)); +#define BTRFS_ROOT_SUBVOL_RDONLY (1ULL << 0) + struct btrfs_root_item { struct btrfs_inode_item inode; __le64 generation; @@ -1893,6 +1895,11 @@ BTRFS_SETGET_STACK_FUNCS(root_limit, struct btrfs_root_item, byte_limit, 64); BTRFS_SETGET_STACK_FUNCS(root_last_snapshot, struct btrfs_root_item, last_snapshot, 64); +static inline bool btrfs_root_readonly(struct btrfs_root *root) +{ + return root->root_item.flags & BTRFS_ROOT_SUBVOL_RDONLY; +} + /* struct btrfs_super_block */ BTRFS_SETGET_STACK_FUNCS(super_bytenr, struct btrfs_super_block, bytenr, 64); diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 5f9194438f7c..956f1eb913b1 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c @@ -3671,8 +3671,12 @@ static int btrfs_setattr_size(struct inode *inode, struct iattr *attr) static int btrfs_setattr(struct dentry *dentry, struct iattr *attr) { struct inode *inode = dentry->d_inode; + struct btrfs_root *root = BTRFS_I(inode)->root; int err; + if (btrfs_root_readonly(root)) + return -EROFS; + err = inode_change_ok(inode, attr); if (err) return err; @@ -7206,6 +7210,10 @@ static int btrfs_set_page_dirty(struct page *page) static int btrfs_permission(struct inode *inode, int mask) { + struct btrfs_root *root = BTRFS_I(inode)->root; + + if (btrfs_root_readonly(root) && (mask & MAY_WRITE)) + return -EROFS; if ((BTRFS_I(inode)->flags & BTRFS_INODE_READONLY) && (mask & MAY_WRITE)) return -EACCES; return generic_permission(inode, mask, btrfs_check_acl); diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 02554e19d974..f066ccb5dddf 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c @@ -147,6 +147,9 @@ static int btrfs_ioctl_setflags(struct file *file, void __user *arg) unsigned int flags, oldflags; int ret; + if (btrfs_root_readonly(root)) + return -EROFS; + if (copy_from_user(&flags, arg, sizeof(flags))) return -EFAULT; @@ -360,7 +363,8 @@ fail: } static int create_snapshot(struct btrfs_root *root, struct dentry *dentry, - char *name, int namelen, u64 *async_transid) + char *name, int namelen, u64 *async_transid, + bool readonly) { struct inode *inode; struct dentry *parent; @@ -378,6 +382,7 @@ static int create_snapshot(struct btrfs_root *root, struct dentry *dentry, btrfs_init_block_rsv(&pending_snapshot->block_rsv); pending_snapshot->dentry = dentry; pending_snapshot->root = root; + pending_snapshot->readonly = readonly; trans = btrfs_start_transaction(root->fs_info->extent_root, 5); if (IS_ERR(trans)) { @@ -509,7 +514,7 @@ static inline int btrfs_may_create(struct inode *dir, struct dentry *child) static noinline int btrfs_mksubvol(struct path *parent, char *name, int namelen, struct btrfs_root *snap_src, - u64 *async_transid) + u64 *async_transid, bool readonly) { struct inode *dir = parent->dentry->d_inode; struct dentry *dentry; @@ -541,7 +546,7 @@ static noinline int btrfs_mksubvol(struct path *parent, if (snap_src) { error = create_snapshot(snap_src, dentry, - name, namelen, async_transid); + name, namelen, async_transid, readonly); } else { error = create_subvol(BTRFS_I(dir)->root, dentry, name, namelen, async_transid); @@ -901,7 +906,8 @@ static noinline int btrfs_ioctl_snap_create_transid(struct file *file, char *name, unsigned long fd, int subvol, - u64 *transid) + u64 *transid, + bool readonly) { struct btrfs_root *root = BTRFS_I(fdentry(file)->d_inode)->root; struct file *src_file; @@ -919,7 +925,7 @@ static noinline int btrfs_ioctl_snap_create_transid(struct file *file, if (subvol) { ret = btrfs_mksubvol(&file->f_path, name, namelen, - NULL, transid); + NULL, transid, readonly); } else { struct inode *src_inode; src_file = fget(fd); @@ -938,7 +944,7 @@ static noinline int btrfs_ioctl_snap_create_transid(struct file *file, } ret = btrfs_mksubvol(&file->f_path, name, namelen, BTRFS_I(src_inode)->root, - transid); + transid, readonly); fput(src_file); } out: @@ -957,7 +963,8 @@ static noinline int btrfs_ioctl_snap_create(struct file *file, vol_args->name[BTRFS_PATH_NAME_MAX] = '\0'; ret = btrfs_ioctl_snap_create_transid(file, vol_args->name, - vol_args->fd, subvol, NULL); + vol_args->fd, subvol, + NULL, false); kfree(vol_args); return ret; @@ -970,22 +977,27 @@ static noinline int btrfs_ioctl_snap_create_v2(struct file *file, int ret; u64 transid = 0; u64 *ptr = NULL; + bool readonly = false; vol_args = memdup_user(arg, sizeof(*vol_args)); if (IS_ERR(vol_args)) return PTR_ERR(vol_args); vol_args->name[BTRFS_SUBVOL_NAME_MAX] = '\0'; - if (vol_args->flags & ~BTRFS_SUBVOL_CREATE_ASYNC) { - ret = -EINVAL; + if (vol_args->flags & + ~(BTRFS_SUBVOL_CREATE_ASYNC | BTRFS_SUBVOL_RDONLY)) { + ret = -EOPNOTSUPP; goto out; } if (vol_args->flags & BTRFS_SUBVOL_CREATE_ASYNC) ptr = &transid; + if (vol_args->flags & BTRFS_SUBVOL_RDONLY) + readonly = true; ret = btrfs_ioctl_snap_create_transid(file, vol_args->name, - vol_args->fd, subvol, ptr); + vol_args->fd, subvol, + ptr, readonly); if (ret == 0 && ptr && copy_to_user(arg + @@ -1505,6 +1517,9 @@ static int btrfs_ioctl_defrag(struct file *file, void __user *argp) struct btrfs_ioctl_defrag_range_args *range; int ret; + if (btrfs_root_readonly(root)) + return -EROFS; + ret = mnt_want_write(file->f_path.mnt); if (ret) return ret; @@ -1633,6 +1648,9 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd, if (!(file->f_mode & FMODE_WRITE) || (file->f_flags & O_APPEND)) return -EINVAL; + if (btrfs_root_readonly(root)) + return -EROFS; + ret = mnt_want_write(file->f_path.mnt); if (ret) return ret; @@ -1954,6 +1972,10 @@ static long btrfs_ioctl_trans_start(struct file *file) if (file->private_data) goto out; + ret = -EROFS; + if (btrfs_root_readonly(root)) + goto out; + ret = mnt_want_write(file->f_path.mnt); if (ret) goto out; diff --git a/fs/btrfs/ioctl.h b/fs/btrfs/ioctl.h index c344d12c646b..52ae489974be 100644 --- a/fs/btrfs/ioctl.h +++ b/fs/btrfs/ioctl.h @@ -31,6 +31,7 @@ struct btrfs_ioctl_vol_args { }; #define BTRFS_SUBVOL_CREATE_ASYNC (1ULL << 0) +#define BTRFS_SUBVOL_RDONLY (1ULL << 1) #define BTRFS_SUBVOL_NAME_MAX 4039 struct btrfs_ioctl_vol_args_v2 { diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index f50e931fc217..29e30d832ec9 100644 --- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c @@ -910,6 +910,7 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans, u64 to_reserve = 0; u64 index = 0; u64 objectid; + u64 root_flags; new_root_item = kmalloc(sizeof(*new_root_item), GFP_NOFS); if (!new_root_item) { @@ -967,6 +968,13 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans, btrfs_set_root_last_snapshot(&root->root_item, trans->transid); memcpy(new_root_item, &root->root_item, sizeof(*new_root_item)); + root_flags = btrfs_root_flags(new_root_item); + if (pending->readonly) + root_flags |= BTRFS_ROOT_SUBVOL_RDONLY; + else + root_flags &= ~BTRFS_ROOT_SUBVOL_RDONLY; + btrfs_set_root_flags(new_root_item, root_flags); + old = btrfs_lock_root_node(root); btrfs_cow_block(trans, root, old, NULL, 0, &old); btrfs_set_lock_blocking(old); diff --git a/fs/btrfs/transaction.h b/fs/btrfs/transaction.h index f104b57ad4ef..229a594cacd5 100644 --- a/fs/btrfs/transaction.h +++ b/fs/btrfs/transaction.h @@ -62,6 +62,7 @@ struct btrfs_pending_snapshot { struct btrfs_block_rsv block_rsv; /* extra metadata reseration for relocation */ int error; + bool readonly; struct list_head list; }; diff --git a/fs/btrfs/xattr.c b/fs/btrfs/xattr.c index 698fdd2c739c..a5776531dc2b 100644 --- a/fs/btrfs/xattr.c +++ b/fs/btrfs/xattr.c @@ -316,6 +316,15 @@ ssize_t btrfs_getxattr(struct dentry *dentry, const char *name, int btrfs_setxattr(struct dentry *dentry, const char *name, const void *value, size_t size, int flags) { + struct btrfs_root *root = BTRFS_I(dentry->d_inode)->root; + + /* + * The permission on security.* and system.* is not checked + * in permission(). + */ + if (btrfs_root_readonly(root)) + return -EROFS; + /* * If this is a request for a synthetic attribute in the system.* * namespace use the generic infrastructure to resolve a handler @@ -336,6 +345,15 @@ int btrfs_setxattr(struct dentry *dentry, const char *name, const void *value, int btrfs_removexattr(struct dentry *dentry, const char *name) { + struct btrfs_root *root = BTRFS_I(dentry->d_inode)->root; + + /* + * The permission on security.* and system.* is not checked + * in permission(). + */ + if (btrfs_root_readonly(root)) + return -EROFS; + /* * If this is a request for a synthetic attribute in the system.* * namespace use the generic infrastructure to resolve a handler -- cgit v1.2.3 From 0caa102da82799efaba88e234484786a9591c797 Mon Sep 17 00:00:00 2001 From: Li Zefan Date: Mon, 20 Dec 2010 16:30:25 +0800 Subject: Btrfs: Add BTRFS_IOC_SUBVOL_GETFLAGS/SETFLAGS ioctls This allows us to set a snapshot or a subvolume readonly or writable on the fly. Usage: Set BTRFS_SUBVOL_RDONLY of btrfs_ioctl_vol_arg_v2->flags, and then call ioctl(BTRFS_IOCTL_SUBVOL_SETFLAGS); Changelog for v3: - Change to pass __u64 as ioctl parameter. Changelog for v2: - Add _GETFLAGS ioctl. - Check if the passed fd is the root of a subvolume. - Change the name from _SNAP_SETFLAGS to _SUBVOL_SETFLAGS. Signed-off-by: Li Zefan --- fs/btrfs/ioctl.c | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ fs/btrfs/ioctl.h | 2 ++ 2 files changed, 85 insertions(+) diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index f066ccb5dddf..ad1983524f97 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c @@ -1009,6 +1009,85 @@ out: return ret; } +static noinline int btrfs_ioctl_subvol_getflags(struct file *file, + void __user *arg) +{ + struct inode *inode = fdentry(file)->d_inode; + struct btrfs_root *root = BTRFS_I(inode)->root; + int ret = 0; + u64 flags = 0; + + if (inode->i_ino != BTRFS_FIRST_FREE_OBJECTID) + return -EINVAL; + + down_read(&root->fs_info->subvol_sem); + if (btrfs_root_readonly(root)) + flags |= BTRFS_SUBVOL_RDONLY; + up_read(&root->fs_info->subvol_sem); + + if (copy_to_user(arg, &flags, sizeof(flags))) + ret = -EFAULT; + + return ret; +} + +static noinline int btrfs_ioctl_subvol_setflags(struct file *file, + void __user *arg) +{ + struct inode *inode = fdentry(file)->d_inode; + struct btrfs_root *root = BTRFS_I(inode)->root; + struct btrfs_trans_handle *trans; + u64 root_flags; + u64 flags; + int ret = 0; + + if (root->fs_info->sb->s_flags & MS_RDONLY) + return -EROFS; + + if (inode->i_ino != BTRFS_FIRST_FREE_OBJECTID) + return -EINVAL; + + if (copy_from_user(&flags, arg, sizeof(flags))) + return -EFAULT; + + if (flags & ~BTRFS_SUBVOL_CREATE_ASYNC) + return -EINVAL; + + if (flags & ~BTRFS_SUBVOL_RDONLY) + return -EOPNOTSUPP; + + down_write(&root->fs_info->subvol_sem); + + /* nothing to do */ + if (!!(flags & BTRFS_SUBVOL_RDONLY) == btrfs_root_readonly(root)) + goto out; + + root_flags = btrfs_root_flags(&root->root_item); + if (flags & BTRFS_SUBVOL_RDONLY) + btrfs_set_root_flags(&root->root_item, + root_flags | BTRFS_ROOT_SUBVOL_RDONLY); + else + btrfs_set_root_flags(&root->root_item, + root_flags & ~BTRFS_ROOT_SUBVOL_RDONLY); + + trans = btrfs_start_transaction(root, 1); + if (IS_ERR(trans)) { + ret = PTR_ERR(trans); + goto out_reset; + } + + ret = btrfs_update_root(trans, root, + &root->root_key, &root->root_item); + + btrfs_commit_transaction(trans, root); +out_reset: + if (ret) + btrfs_set_root_flags(&root->root_item, root_flags); +out: + up_write(&root->fs_info->subvol_sem); + return ret; +} + /* * helper to check if the subvolume references other subvolumes */ @@ -2282,6 +2361,10 @@ long btrfs_ioctl(struct file *file, unsigned int return btrfs_ioctl_snap_create(file, argp, 1); case BTRFS_IOC_SNAP_DESTROY: return btrfs_ioctl_snap_destroy(file, argp); + case BTRFS_IOC_SUBVOL_GETFLAGS: + return btrfs_ioctl_subvol_getflags(file, argp); + case BTRFS_IOC_SUBVOL_SETFLAGS: + return btrfs_ioctl_subvol_setflags(file, argp); case BTRFS_IOC_DEFAULT_SUBVOL: return btrfs_ioctl_default_subvol(file, argp); case BTRFS_IOC_DEFRAG: diff --git a/fs/btrfs/ioctl.h b/fs/btrfs/ioctl.h index 52ae489974be..1223223351fa 100644 --- a/fs/btrfs/ioctl.h +++ b/fs/btrfs/ioctl.h @@ -194,4 +194,6 @@ struct btrfs_ioctl_space_args { #define BTRFS_IOC_WAIT_SYNC _IOW(BTRFS_IOCTL_MAGIC, 22, __u64) #define BTRFS_IOC_SNAP_CREATE_V2 _IOW(BTRFS_IOCTL_MAGIC, 23, \ struct btrfs_ioctl_vol_args_v2) +#define BTRFS_IOC_SUBVOL_GETFLAGS _IOW(BTRFS_IOCTL_MAGIC, 25, __u64) +#define BTRFS_IOC_SUBVOL_SETFLAGS _IOW(BTRFS_IOCTL_MAGIC, 26, __u64) #endif -- cgit v1.2.3 From 1435b9402fe0fb27ac4ec5bb271112de2c4806c0 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 23 Dec 2010 01:56:20 +0000 Subject: ASoC: ifdef out trace points from modules for x86 No idea why this works on ARM but not x86. Signed-off-by: Mark Brown --- sound/soc/codecs/88pm860x-codec.c | 2 ++ sound/soc/codecs/wm8350.c | 4 ++++ sound/soc/codecs/wm8903.c | 2 ++ sound/soc/codecs/wm8962.c | 2 ++ 4 files changed, 10 insertions(+) diff --git a/sound/soc/codecs/88pm860x-codec.c b/sound/soc/codecs/88pm860x-codec.c index a34fb924e77b..3e798a12ee3d 100644 --- a/sound/soc/codecs/88pm860x-codec.c +++ b/sound/soc/codecs/88pm860x-codec.c @@ -1263,9 +1263,11 @@ static irqreturn_t pm860x_codec_handler(int irq, void *data) mask = pm860x->det.hs_shrt | pm860x->det.hook_det | pm860x->det.lo_shrt | pm860x->det.hp_det; +#ifndef CONFIG_SND_SOC_88PM860X if (status & (HEADSET_STATUS | MIC_STATUS | SHORT_HS1 | SHORT_HS2 | SHORT_LO1 | SHORT_LO2)) trace_snd_soc_jack_irq(dev_name(pm860x->codec->dev)); +#endif if ((pm860x->det.hp_det & SND_JACK_HEADPHONE) && (status & HEADSET_STATUS)) diff --git a/sound/soc/codecs/wm8350.c b/sound/soc/codecs/wm8350.c index 82d877df3fb0..db07137bf3b9 100644 --- a/sound/soc/codecs/wm8350.c +++ b/sound/soc/codecs/wm8350.c @@ -1379,12 +1379,16 @@ static irqreturn_t wm8350_hp_jack_handler(int irq, void *data) switch (irq - wm8350->irq_base) { case WM8350_IRQ_CODEC_JCK_DET_L: +#ifndef CONFIG_SND_SOC_WM8350_MODULE trace_snd_soc_jack_irq("WM8350 HPL"); +#endif jack = &priv->hpl; break; case WM8350_IRQ_CODEC_JCK_DET_R: +#ifndef CONFIG_SND_SOC_WM8350_MODULE trace_snd_soc_jack_irq("WM8350 HPR"); +#endif jack = &priv->hpr; break; diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c index b32699bc1927..02de5ae42d63 100644 --- a/sound/soc/codecs/wm8903.c +++ b/sound/soc/codecs/wm8903.c @@ -1534,8 +1534,10 @@ static irqreturn_t wm8903_irq(int irq, void *data) mic_report = wm8903->mic_last_report; int_pol = snd_soc_read(codec, WM8903_INTERRUPT_POLARITY_1); +#ifndef CONFIG_SND_SOC_WM8903_MODULE if (int_val & (WM8903_MICSHRT_EINT | WM8903_MICDET_EINT)) trace_snd_soc_jack_irq(dev_name(codec->dev)); +#endif if (int_val & WM8903_MICSHRT_EINT) { dev_dbg(codec->dev, "Microphone short (pol=%x)\n", int_pol); diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c index a24f83d604c9..b311b465c4d8 100644 --- a/sound/soc/codecs/wm8962.c +++ b/sound/soc/codecs/wm8962.c @@ -3354,7 +3354,9 @@ static irqreturn_t wm8962_irq(int irq, void *data) if (active & (WM8962_MICSCD_EINT | WM8962_MICD_EINT)) { dev_dbg(codec->dev, "Microphone event detected\n"); +#ifndef CONFIG_SOUND_SOC_WM862_MODULE trace_snd_soc_jack_irq(dev_name(codec->dev)); +#endif pm_wakeup_event(codec->dev, 300); -- cgit v1.2.3 From 1e6d9153df27923649976554d034a69ac7b28f95 Mon Sep 17 00:00:00 2001 From: Tao Ma Date: Mon, 20 Dec 2010 16:21:11 +0800 Subject: ocfs2: Release buffer_head in case of error in ocfs2_double_lock. In ocfs2_double_lock, when ocfs2_inode_lock for inode1 fails, we just unlock inode2 and return without releasing buffer we get from inode_lock(inode2). The good thing is that it is freed by the only caller ocfs2_rename when it exits. But I don't think this is a right way for error handling. We should free the buffer_head we get in ocfs2_double_lock before exit so that the caller doesn't need to take care of it. Signed-off-by: Tao Ma Signed-off-by: Joel Becker --- fs/ocfs2/namei.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c index ff5744e1e36f..ca35f81a13bb 100644 --- a/fs/ocfs2/namei.c +++ b/fs/ocfs2/namei.c @@ -1017,8 +1017,11 @@ static int ocfs2_double_lock(struct ocfs2_super *osb, * An error return must mean that no cluster locks * were held on function exit. */ - if (oi1->ip_blkno != oi2->ip_blkno) + if (oi1->ip_blkno != oi2->ip_blkno) { ocfs2_inode_unlock(inode2, 1); + brelse(*bh2); + *bh2 = NULL; + } if (status != -ENOENT) mlog_errno(status); -- cgit v1.2.3 From 02bd9c394ef64a16a313eb4d968a94b7000c5d00 Mon Sep 17 00:00:00 2001 From: Sunil Mushran Date: Mon, 20 Dec 2010 16:34:59 -0800 Subject: ocfs2/dlm: Cleanup dlmdebug.c Remove struct debug_buffer in dlmdebug.c/h. Signed-off-by: Sunil Mushran Signed-off-by: Joel Becker --- fs/ocfs2/dlm/dlmdebug.c | 178 ++++++++++++++++++------------------------------ fs/ocfs2/dlm/dlmdebug.h | 5 -- 2 files changed, 66 insertions(+), 117 deletions(-) diff --git a/fs/ocfs2/dlm/dlmdebug.c b/fs/ocfs2/dlm/dlmdebug.c index 272ec8631a51..77199ca4409a 100644 --- a/fs/ocfs2/dlm/dlmdebug.c +++ b/fs/ocfs2/dlm/dlmdebug.c @@ -370,92 +370,46 @@ static void dlm_debug_get(struct dlm_debug_ctxt *dc) kref_get(&dc->debug_refcnt); } -static struct debug_buffer *debug_buffer_allocate(void) +static int debug_release(struct inode *inode, struct file *file) { - struct debug_buffer *db = NULL; - - db = kzalloc(sizeof(struct debug_buffer), GFP_KERNEL); - if (!db) - goto bail; - - db->len = PAGE_SIZE; - db->buf = kmalloc(db->len, GFP_KERNEL); - if (!db->buf) - goto bail; - - return db; -bail: - kfree(db); - return NULL; -} - -static ssize_t debug_buffer_read(struct file *file, char __user *buf, - size_t nbytes, loff_t *ppos) -{ - struct debug_buffer *db = file->private_data; - - return simple_read_from_buffer(buf, nbytes, ppos, db->buf, db->len); -} - -static loff_t debug_buffer_llseek(struct file *file, loff_t off, int whence) -{ - struct debug_buffer *db = file->private_data; - loff_t new = -1; - - switch (whence) { - case 0: - new = off; - break; - case 1: - new = file->f_pos + off; - break; - } - - if (new < 0 || new > db->len) - return -EINVAL; - - return (file->f_pos = new); + free_page((unsigned long)file->private_data); + return 0; } -static int debug_buffer_release(struct inode *inode, struct file *file) +static ssize_t debug_read(struct file *file, char __user *buf, + size_t nbytes, loff_t *ppos) { - struct debug_buffer *db = file->private_data; - - if (db) - kfree(db->buf); - kfree(db); - - return 0; + return simple_read_from_buffer(buf, nbytes, ppos, file->private_data, + i_size_read(file->f_mapping->host)); } /* end - util funcs */ /* begin - purge list funcs */ -static int debug_purgelist_print(struct dlm_ctxt *dlm, struct debug_buffer *db) +static int debug_purgelist_print(struct dlm_ctxt *dlm, char *buf, int len) { struct dlm_lock_resource *res; int out = 0; unsigned long total = 0; - out += snprintf(db->buf + out, db->len - out, + out += snprintf(buf + out, len - out, "Dumping Purgelist for Domain: %s\n", dlm->name); spin_lock(&dlm->spinlock); list_for_each_entry(res, &dlm->purge_list, purge) { ++total; - if (db->len - out < 100) + if (len - out < 100) continue; spin_lock(&res->spinlock); out += stringify_lockname(res->lockname.name, res->lockname.len, - db->buf + out, db->len - out); - out += snprintf(db->buf + out, db->len - out, "\t%ld\n", + buf + out, len - out); + out += snprintf(buf + out, len - out, "\t%ld\n", (jiffies - res->last_used)/HZ); spin_unlock(&res->spinlock); } spin_unlock(&dlm->spinlock); - out += snprintf(db->buf + out, db->len - out, - "Total on list: %ld\n", total); + out += snprintf(buf + out, len - out, "Total on list: %ld\n", total); return out; } @@ -463,15 +417,15 @@ static int debug_purgelist_print(struct dlm_ctxt *dlm, struct debug_buffer *db) static int debug_purgelist_open(struct inode *inode, struct file *file) { struct dlm_ctxt *dlm = inode->i_private; - struct debug_buffer *db; + char *buf = NULL; - db = debug_buffer_allocate(); - if (!db) + buf = (char *) get_zeroed_page(GFP_NOFS); + if (!buf) goto bail; - db->len = debug_purgelist_print(dlm, db); + i_size_write(inode, debug_purgelist_print(dlm, buf, PAGE_SIZE - 1)); - file->private_data = db; + file->private_data = buf; return 0; bail: @@ -480,14 +434,14 @@ bail: static const struct file_operations debug_purgelist_fops = { .open = debug_purgelist_open, - .release = debug_buffer_release, - .read = debug_buffer_read, - .llseek = debug_buffer_llseek, + .release = debug_release, + .read = debug_read, + .llseek = generic_file_llseek, }; /* end - purge list funcs */ /* begin - debug mle funcs */ -static int debug_mle_print(struct dlm_ctxt *dlm, struct debug_buffer *db) +static int debug_mle_print(struct dlm_ctxt *dlm, char *buf, int len) { struct dlm_master_list_entry *mle; struct hlist_head *bucket; @@ -495,7 +449,7 @@ static int debug_mle_print(struct dlm_ctxt *dlm, struct debug_buffer *db) int i, out = 0; unsigned long total = 0, longest = 0, bucket_count = 0; - out += snprintf(db->buf + out, db->len - out, + out += snprintf(buf + out, len - out, "Dumping MLEs for Domain: %s\n", dlm->name); spin_lock(&dlm->master_lock); @@ -506,16 +460,16 @@ static int debug_mle_print(struct dlm_ctxt *dlm, struct debug_buffer *db) master_hash_node); ++total; ++bucket_count; - if (db->len - out < 200) + if (len - out < 200) continue; - out += dump_mle(mle, db->buf + out, db->len - out); + out += dump_mle(mle, buf + out, len - out); } longest = max(longest, bucket_count); bucket_count = 0; } spin_unlock(&dlm->master_lock); - out += snprintf(db->buf + out, db->len - out, + out += snprintf(buf + out, len - out, "Total: %ld, Longest: %ld\n", total, longest); return out; } @@ -523,15 +477,15 @@ static int debug_mle_print(struct dlm_ctxt *dlm, struct debug_buffer *db) static int debug_mle_open(struct inode *inode, struct file *file) { struct dlm_ctxt *dlm = inode->i_private; - struct debug_buffer *db; + char *buf = NULL; - db = debug_buffer_allocate(); - if (!db) + buf = (char *) get_zeroed_page(GFP_NOFS); + if (!buf) goto bail; - db->len = debug_mle_print(dlm, db); + i_size_write(inode, debug_mle_print(dlm, buf, PAGE_SIZE - 1)); - file->private_data = db; + file->private_data = buf; return 0; bail: @@ -540,9 +494,9 @@ bail: static const struct file_operations debug_mle_fops = { .open = debug_mle_open, - .release = debug_buffer_release, - .read = debug_buffer_read, - .llseek = debug_buffer_llseek, + .release = debug_release, + .read = debug_read, + .llseek = generic_file_llseek, }; /* end - debug mle funcs */ @@ -757,7 +711,7 @@ static const struct file_operations debug_lockres_fops = { /* end - debug lockres funcs */ /* begin - debug state funcs */ -static int debug_state_print(struct dlm_ctxt *dlm, struct debug_buffer *db) +static int debug_state_print(struct dlm_ctxt *dlm, char *buf, int len) { int out = 0; struct dlm_reco_node_data *node; @@ -781,35 +735,35 @@ static int debug_state_print(struct dlm_ctxt *dlm, struct debug_buffer *db) } /* Domain: xxxxxxxxxx Key: 0xdfbac769 */ - out += snprintf(db->buf + out, db->len - out, + out += snprintf(buf + out, len - out, "Domain: %s Key: 0x%08x Protocol: %d.%d\n", dlm->name, dlm->key, dlm->dlm_locking_proto.pv_major, dlm->dlm_locking_proto.pv_minor); /* Thread Pid: xxx Node: xxx State: xxxxx */ - out += snprintf(db->buf + out, db->len - out, + out += snprintf(buf + out, len - out, "Thread Pid: %d Node: %d State: %s\n", dlm->dlm_thread_task->pid, dlm->node_num, state); /* Number of Joins: xxx Joining Node: xxx */ - out += snprintf(db->buf + out, db->len - out, + out += snprintf(buf + out, len - out, "Number of Joins: %d Joining Node: %d\n", dlm->num_joins, dlm->joining_node); /* Domain Map: xx xx xx */ - out += snprintf(db->buf + out, db->len - out, "Domain Map: "); + out += snprintf(buf + out, len - out, "Domain Map: "); out += stringify_nodemap(dlm->domain_map, O2NM_MAX_NODES, - db->buf + out, db->len - out); - out += snprintf(db->buf + out, db->len - out, "\n"); + buf + out, len - out); + out += snprintf(buf + out, len - out, "\n"); /* Live Map: xx xx xx */ - out += snprintf(db->buf + out, db->len - out, "Live Map: "); + out += snprintf(buf + out, len - out, "Live Map: "); out += stringify_nodemap(dlm->live_nodes_map, O2NM_MAX_NODES, - db->buf + out, db->len - out); - out += snprintf(db->buf + out, db->len - out, "\n"); + buf + out, len - out); + out += snprintf(buf + out, len - out, "\n"); /* Lock Resources: xxx (xxx) */ - out += snprintf(db->buf + out, db->len - out, + out += snprintf(buf + out, len - out, "Lock Resources: %d (%d)\n", atomic_read(&dlm->res_cur_count), atomic_read(&dlm->res_tot_count)); @@ -821,29 +775,29 @@ static int debug_state_print(struct dlm_ctxt *dlm, struct debug_buffer *db) cur_mles += atomic_read(&dlm->mle_cur_count[i]); /* MLEs: xxx (xxx) */ - out += snprintf(db->buf + out, db->len - out, + out += snprintf(buf + out, len - out, "MLEs: %d (%d)\n", cur_mles, tot_mles); /* Blocking: xxx (xxx) */ - out += snprintf(db->buf + out, db->len - out, + out += snprintf(buf + out, len - out, " Blocking: %d (%d)\n", atomic_read(&dlm->mle_cur_count[DLM_MLE_BLOCK]), atomic_read(&dlm->mle_tot_count[DLM_MLE_BLOCK])); /* Mastery: xxx (xxx) */ - out += snprintf(db->buf + out, db->len - out, + out += snprintf(buf + out, len - out, " Mastery: %d (%d)\n", atomic_read(&dlm->mle_cur_count[DLM_MLE_MASTER]), atomic_read(&dlm->mle_tot_count[DLM_MLE_MASTER])); /* Migration: xxx (xxx) */ - out += snprintf(db->buf + out, db->len - out, + out += snprintf(buf + out, len - out, " Migration: %d (%d)\n", atomic_read(&dlm->mle_cur_count[DLM_MLE_MIGRATION]), atomic_read(&dlm->mle_tot_count[DLM_MLE_MIGRATION])); /* Lists: Dirty=Empty Purge=InUse PendingASTs=Empty ... */ - out += snprintf(db->buf + out, db->len - out, + out += snprintf(buf + out, len - out, "Lists: Dirty=%s Purge=%s PendingASTs=%s " "PendingBASTs=%s\n", (list_empty(&dlm->dirty_list) ? "Empty" : "InUse"), @@ -852,12 +806,12 @@ static int debug_state_print(struct dlm_ctxt *dlm, struct debug_buffer *db) (list_empty(&dlm->pending_basts) ? "Empty" : "InUse")); /* Purge Count: xxx Refs: xxx */ - out += snprintf(db->buf + out, db->len - out, + out += snprintf(buf + out, len - out, "Purge Count: %d Refs: %d\n", dlm->purge_count, atomic_read(&dlm->dlm_refs.refcount)); /* Dead Node: xxx */ - out += snprintf(db->buf + out, db->len - out, + out += snprintf(buf + out, len - out, "Dead Node: %d\n", dlm->reco.dead_node); /* What about DLM_RECO_STATE_FINALIZE? */ @@ -867,19 +821,19 @@ static int debug_state_print(struct dlm_ctxt *dlm, struct debug_buffer *db) state = "INACTIVE"; /* Recovery Pid: xxxx Master: xxx State: xxxx */ - out += snprintf(db->buf + out, db->len - out, + out += snprintf(buf + out, len - out, "Recovery Pid: %d Master: %d State: %s\n", dlm->dlm_reco_thread_task->pid, dlm->reco.new_master, state); /* Recovery Map: xx xx */ - out += snprintf(db->buf + out, db->len - out, "Recovery Map: "); + out += snprintf(buf + out, len - out, "Recovery Map: "); out += stringify_nodemap(dlm->recovery_map, O2NM_MAX_NODES, - db->buf + out, db->len - out); - out += snprintf(db->buf + out, db->len - out, "\n"); + buf + out, len - out); + out += snprintf(buf + out, len - out, "\n"); /* Recovery Node State: */ - out += snprintf(db->buf + out, db->len - out, "Recovery Node State:\n"); + out += snprintf(buf + out, len - out, "Recovery Node State:\n"); list_for_each_entry(node, &dlm->reco.node_data, list) { switch (node->state) { case DLM_RECO_NODE_DATA_INIT: @@ -907,7 +861,7 @@ static int debug_state_print(struct dlm_ctxt *dlm, struct debug_buffer *db) state = "BAD"; break; } - out += snprintf(db->buf + out, db->len - out, "\t%u - %s\n", + out += snprintf(buf + out, len - out, "\t%u - %s\n", node->node_num, state); } @@ -919,15 +873,15 @@ static int debug_state_print(struct dlm_ctxt *dlm, struct debug_buffer *db) static int debug_state_open(struct inode *inode, struct file *file) { struct dlm_ctxt *dlm = inode->i_private; - struct debug_buffer *db = NULL; + char *buf = NULL; - db = debug_buffer_allocate(); - if (!db) + buf = (char *) get_zeroed_page(GFP_NOFS); + if (!buf) goto bail; - db->len = debug_state_print(dlm, db); + i_size_write(inode, debug_state_print(dlm, buf, PAGE_SIZE - 1)); - file->private_data = db; + file->private_data = buf; return 0; bail: @@ -936,9 +890,9 @@ bail: static const struct file_operations debug_state_fops = { .open = debug_state_open, - .release = debug_buffer_release, - .read = debug_buffer_read, - .llseek = debug_buffer_llseek, + .release = debug_release, + .read = debug_read, + .llseek = generic_file_llseek, }; /* end - debug state funcs */ diff --git a/fs/ocfs2/dlm/dlmdebug.h b/fs/ocfs2/dlm/dlmdebug.h index 8c686d22f9c7..1f27c4812d1a 100644 --- a/fs/ocfs2/dlm/dlmdebug.h +++ b/fs/ocfs2/dlm/dlmdebug.h @@ -37,11 +37,6 @@ struct dlm_debug_ctxt { struct dentry *debug_purgelist_dentry; }; -struct debug_buffer { - int len; - char *buf; -}; - struct debug_lockres { int dl_len; char *dl_buf; -- cgit v1.2.3 From 37096a7927decb0b1d3c2514b8adb4583a834112 Mon Sep 17 00:00:00 2001 From: Sunil Mushran Date: Mon, 20 Dec 2010 16:35:00 -0800 Subject: ocfs2/dlm: Minor cleanup Patch makes use of task_pid_nr(). Also removes the null check before calling debugfs_remove(). Signed-off-by: Sunil Mushran Signed-off-by: Joel Becker --- fs/ocfs2/cluster/netdebug.c | 20 +++++++------------- fs/ocfs2/dlm/dlmdebug.c | 22 ++++++++-------------- 2 files changed, 15 insertions(+), 27 deletions(-) diff --git a/fs/ocfs2/cluster/netdebug.c b/fs/ocfs2/cluster/netdebug.c index a3f150e52b02..0edf836b42d5 100644 --- a/fs/ocfs2/cluster/netdebug.c +++ b/fs/ocfs2/cluster/netdebug.c @@ -141,7 +141,7 @@ static int nst_seq_show(struct seq_file *seq, void *v) " sock acquiry: %lu.%ld\n" " send start: %lu.%ld\n" " wait start: %lu.%ld\n", - nst, (unsigned long)nst->st_task->pid, + nst, (unsigned long)task_pid_nr(nst->st_task), (unsigned long)nst->st_task->tgid, nst->st_task->comm, nst->st_node, nst->st_sc, nst->st_id, nst->st_msg_type, @@ -421,23 +421,17 @@ int o2net_debugfs_init(void) return 0; bail: - if (sc_dentry) - debugfs_remove(sc_dentry); - if (nst_dentry) - debugfs_remove(nst_dentry); - if (o2net_dentry) - debugfs_remove(o2net_dentry); + debugfs_remove(sc_dentry); + debugfs_remove(nst_dentry); + debugfs_remove(o2net_dentry); return -ENOMEM; } void o2net_debugfs_exit(void) { - if (sc_dentry) - debugfs_remove(sc_dentry); - if (nst_dentry) - debugfs_remove(nst_dentry); - if (o2net_dentry) - debugfs_remove(o2net_dentry); + debugfs_remove(sc_dentry); + debugfs_remove(nst_dentry); + debugfs_remove(o2net_dentry); } #endif /* CONFIG_DEBUG_FS */ diff --git a/fs/ocfs2/dlm/dlmdebug.c b/fs/ocfs2/dlm/dlmdebug.c index 77199ca4409a..04a32be0aeb9 100644 --- a/fs/ocfs2/dlm/dlmdebug.c +++ b/fs/ocfs2/dlm/dlmdebug.c @@ -743,7 +743,7 @@ static int debug_state_print(struct dlm_ctxt *dlm, char *buf, int len) /* Thread Pid: xxx Node: xxx State: xxxxx */ out += snprintf(buf + out, len - out, "Thread Pid: %d Node: %d State: %s\n", - dlm->dlm_thread_task->pid, dlm->node_num, state); + task_pid_nr(dlm->dlm_thread_task), dlm->node_num, state); /* Number of Joins: xxx Joining Node: xxx */ out += snprintf(buf + out, len - out, @@ -823,7 +823,7 @@ static int debug_state_print(struct dlm_ctxt *dlm, char *buf, int len) /* Recovery Pid: xxxx Master: xxx State: xxxx */ out += snprintf(buf + out, len - out, "Recovery Pid: %d Master: %d State: %s\n", - dlm->dlm_reco_thread_task->pid, + task_pid_nr(dlm->dlm_reco_thread_task), dlm->reco.new_master, state); /* Recovery Map: xx xx */ @@ -956,14 +956,10 @@ void dlm_debug_shutdown(struct dlm_ctxt *dlm) struct dlm_debug_ctxt *dc = dlm->dlm_debug_ctxt; if (dc) { - if (dc->debug_purgelist_dentry) - debugfs_remove(dc->debug_purgelist_dentry); - if (dc->debug_mle_dentry) - debugfs_remove(dc->debug_mle_dentry); - if (dc->debug_lockres_dentry) - debugfs_remove(dc->debug_lockres_dentry); - if (dc->debug_state_dentry) - debugfs_remove(dc->debug_state_dentry); + debugfs_remove(dc->debug_purgelist_dentry); + debugfs_remove(dc->debug_mle_dentry); + debugfs_remove(dc->debug_lockres_dentry); + debugfs_remove(dc->debug_state_dentry); dlm_debug_put(dc); } } @@ -994,8 +990,7 @@ bail: void dlm_destroy_debugfs_subroot(struct dlm_ctxt *dlm) { - if (dlm->dlm_debugfs_subroot) - debugfs_remove(dlm->dlm_debugfs_subroot); + debugfs_remove(dlm->dlm_debugfs_subroot); } /* debugfs root */ @@ -1011,7 +1006,6 @@ int dlm_create_debugfs_root(void) void dlm_destroy_debugfs_root(void) { - if (dlm_debugfs_root) - debugfs_remove(dlm_debugfs_root); + debugfs_remove(dlm_debugfs_root); } #endif /* CONFIG_DEBUG_FS */ -- cgit v1.2.3 From 079ffb743c622fe2189b75614427c56e8391498b Mon Sep 17 00:00:00 2001 From: Sunil Mushran Date: Mon, 20 Dec 2010 16:35:01 -0800 Subject: ocfs2/dlm: Hard code the values for enums In o2dlm, the enumerated message values are part of the protocol. The patch hard codes each value so as to reduce the chance of an editing error causing a protocol mismatch. Signed-off-by: Sunil Mushran Signed-off-by: Joel Becker --- fs/ocfs2/dlm/dlmcommon.h | 86 ++++++++++++++++++++++++------------------------ 1 file changed, 43 insertions(+), 43 deletions(-) diff --git a/fs/ocfs2/dlm/dlmcommon.h b/fs/ocfs2/dlm/dlmcommon.h index b36d0bf77a5a..4bdf7baee344 100644 --- a/fs/ocfs2/dlm/dlmcommon.h +++ b/fs/ocfs2/dlm/dlmcommon.h @@ -50,10 +50,10 @@ #define dlm_lockid_hash(_n, _l) full_name_hash(_n, _l) enum dlm_mle_type { - DLM_MLE_BLOCK, - DLM_MLE_MASTER, - DLM_MLE_MIGRATION, - DLM_MLE_NUM_TYPES + DLM_MLE_BLOCK = 0, + DLM_MLE_MASTER = 1, + DLM_MLE_MIGRATION = 2, + DLM_MLE_NUM_TYPES = 3, }; struct dlm_master_list_entry { @@ -82,8 +82,8 @@ struct dlm_master_list_entry { enum dlm_ast_type { DLM_AST = 0, - DLM_BAST, - DLM_ASTUNLOCK + DLM_BAST = 1, + DLM_ASTUNLOCK = 2, }; @@ -119,9 +119,9 @@ struct dlm_recovery_ctxt enum dlm_ctxt_state { DLM_CTXT_NEW = 0, - DLM_CTXT_JOINED, - DLM_CTXT_IN_SHUTDOWN, - DLM_CTXT_LEAVING, + DLM_CTXT_JOINED = 1, + DLM_CTXT_IN_SHUTDOWN = 2, + DLM_CTXT_LEAVING = 3, }; struct dlm_ctxt @@ -388,8 +388,8 @@ struct dlm_lock enum dlm_lockres_list { DLM_GRANTED_LIST = 0, - DLM_CONVERTING_LIST, - DLM_BLOCKED_LIST + DLM_CONVERTING_LIST = 1, + DLM_BLOCKED_LIST = 2, }; static inline int dlm_lvb_is_empty(char *lvb) @@ -427,27 +427,27 @@ struct dlm_node_iter enum { - DLM_MASTER_REQUEST_MSG = 500, - DLM_UNUSED_MSG1, /* 501 */ - DLM_ASSERT_MASTER_MSG, /* 502 */ - DLM_CREATE_LOCK_MSG, /* 503 */ - DLM_CONVERT_LOCK_MSG, /* 504 */ - DLM_PROXY_AST_MSG, /* 505 */ - DLM_UNLOCK_LOCK_MSG, /* 506 */ - DLM_DEREF_LOCKRES_MSG, /* 507 */ - DLM_MIGRATE_REQUEST_MSG, /* 508 */ - DLM_MIG_LOCKRES_MSG, /* 509 */ - DLM_QUERY_JOIN_MSG, /* 510 */ - DLM_ASSERT_JOINED_MSG, /* 511 */ - DLM_CANCEL_JOIN_MSG, /* 512 */ - DLM_EXIT_DOMAIN_MSG, /* 513 */ - DLM_MASTER_REQUERY_MSG, /* 514 */ - DLM_LOCK_REQUEST_MSG, /* 515 */ - DLM_RECO_DATA_DONE_MSG, /* 516 */ - DLM_BEGIN_RECO_MSG, /* 517 */ - DLM_FINALIZE_RECO_MSG, /* 518 */ - DLM_QUERY_REGION, /* 519 */ - DLM_QUERY_NODEINFO, /* 520 */ + DLM_MASTER_REQUEST_MSG = 500, + DLM_UNUSED_MSG1 = 501, + DLM_ASSERT_MASTER_MSG = 502, + DLM_CREATE_LOCK_MSG = 503, + DLM_CONVERT_LOCK_MSG = 504, + DLM_PROXY_AST_MSG = 505, + DLM_UNLOCK_LOCK_MSG = 506, + DLM_DEREF_LOCKRES_MSG = 507, + DLM_MIGRATE_REQUEST_MSG = 508, + DLM_MIG_LOCKRES_MSG = 509, + DLM_QUERY_JOIN_MSG = 510, + DLM_ASSERT_JOINED_MSG = 511, + DLM_CANCEL_JOIN_MSG = 512, + DLM_EXIT_DOMAIN_MSG = 513, + DLM_MASTER_REQUERY_MSG = 514, + DLM_LOCK_REQUEST_MSG = 515, + DLM_RECO_DATA_DONE_MSG = 516, + DLM_BEGIN_RECO_MSG = 517, + DLM_FINALIZE_RECO_MSG = 518, + DLM_QUERY_REGION = 519, + DLM_QUERY_NODEINFO = 520, }; struct dlm_reco_node_data @@ -460,19 +460,19 @@ struct dlm_reco_node_data enum { DLM_RECO_NODE_DATA_DEAD = -1, DLM_RECO_NODE_DATA_INIT = 0, - DLM_RECO_NODE_DATA_REQUESTING, - DLM_RECO_NODE_DATA_REQUESTED, - DLM_RECO_NODE_DATA_RECEIVING, - DLM_RECO_NODE_DATA_DONE, - DLM_RECO_NODE_DATA_FINALIZE_SENT, + DLM_RECO_NODE_DATA_REQUESTING = 1, + DLM_RECO_NODE_DATA_REQUESTED = 2, + DLM_RECO_NODE_DATA_RECEIVING = 3, + DLM_RECO_NODE_DATA_DONE = 4, + DLM_RECO_NODE_DATA_FINALIZE_SENT = 5, }; enum { DLM_MASTER_RESP_NO = 0, - DLM_MASTER_RESP_YES, - DLM_MASTER_RESP_MAYBE, - DLM_MASTER_RESP_ERROR + DLM_MASTER_RESP_YES = 1, + DLM_MASTER_RESP_MAYBE = 2, + DLM_MASTER_RESP_ERROR = 3, }; @@ -649,9 +649,9 @@ struct dlm_proxy_ast #define DLM_MOD_KEY (0x666c6172) enum dlm_query_join_response_code { JOIN_DISALLOW = 0, - JOIN_OK, - JOIN_OK_NO_MAP, - JOIN_PROTOCOL_MISMATCH, + JOIN_OK = 1, + JOIN_OK_NO_MAP = 2, + JOIN_PROTOCOL_MISMATCH = 3, }; struct dlm_query_join_packet { -- cgit v1.2.3 From 8757241e32a295a2aa836e8f8b32912204d11fda Mon Sep 17 00:00:00 2001 From: Sunil Mushran Date: Wed, 22 Dec 2010 12:39:37 -0800 Subject: ocfs2: Add DEBUG_FS dependency Make OCFS2_FS_STATS depend on DEBUG_FS. Signed-off-by: Sunil Mushran Signed-off-by: Joel Becker --- fs/ocfs2/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/ocfs2/Kconfig b/fs/ocfs2/Kconfig index 0d840669698e..ab152c00cd3a 100644 --- a/fs/ocfs2/Kconfig +++ b/fs/ocfs2/Kconfig @@ -51,7 +51,7 @@ config OCFS2_FS_USERSPACE_CLUSTER config OCFS2_FS_STATS bool "OCFS2 statistics" - depends on OCFS2_FS + depends on OCFS2_FS && DEBUG_FS default y help This option allows some fs statistics to be captured. Enabling -- cgit v1.2.3 From 3f9c14fab0a2e90af9995f261a123f59e0b41141 Mon Sep 17 00:00:00 2001 From: Sunil Mushran Date: Wed, 22 Dec 2010 12:39:38 -0800 Subject: ocfs2/cluster: Replace timeval with ktime in struct o2net_send_tracking Replace time trackers in struct o2net_send_tracking from struct timeval to union ktime. Signed-off-by: Sunil Mushran Signed-off-by: Joel Becker --- fs/ocfs2/cluster/netdebug.c | 22 +++++++++++++--------- fs/ocfs2/cluster/tcp.c | 6 +++--- fs/ocfs2/cluster/tcp_internal.h | 6 +++--- 3 files changed, 19 insertions(+), 15 deletions(-) diff --git a/fs/ocfs2/cluster/netdebug.c b/fs/ocfs2/cluster/netdebug.c index 0edf836b42d5..2b986aa82299 100644 --- a/fs/ocfs2/cluster/netdebug.c +++ b/fs/ocfs2/cluster/netdebug.c @@ -123,10 +123,17 @@ static void *nst_seq_next(struct seq_file *seq, void *v, loff_t *pos) static int nst_seq_show(struct seq_file *seq, void *v) { struct o2net_send_tracking *nst, *dummy_nst = seq->private; + ktime_t now; + s64 sock, send, status; spin_lock(&o2net_debug_lock); nst = next_nst(dummy_nst); + now = ktime_get(); + sock = ktime_to_us(ktime_sub(now, nst->st_sock_time)); + send = ktime_to_us(ktime_sub(now, nst->st_send_time)); + status = ktime_to_us(ktime_sub(now, nst->st_status_time)); + if (nst != NULL) { /* get_task_comm isn't exported. oh well. */ seq_printf(seq, "%p:\n" @@ -138,20 +145,17 @@ static int nst_seq_show(struct seq_file *seq, void *v) " message id: %d\n" " message type: %u\n" " message key: 0x%08x\n" - " sock acquiry: %lu.%ld\n" - " send start: %lu.%ld\n" - " wait start: %lu.%ld\n", + " sock acquiry: %lld usecs ago\n" + " send start: %lld usecs ago\n" + " wait start: %lld usecs ago\n", nst, (unsigned long)task_pid_nr(nst->st_task), (unsigned long)nst->st_task->tgid, nst->st_task->comm, nst->st_node, nst->st_sc, nst->st_id, nst->st_msg_type, nst->st_msg_key, - nst->st_sock_time.tv_sec, - (long)nst->st_sock_time.tv_usec, - nst->st_send_time.tv_sec, - (long)nst->st_send_time.tv_usec, - nst->st_status_time.tv_sec, - (long)nst->st_status_time.tv_usec); + (long long)sock, + (long long)send, + (long long)status); } spin_unlock(&o2net_debug_lock); diff --git a/fs/ocfs2/cluster/tcp.c b/fs/ocfs2/cluster/tcp.c index 92de96cd247d..49c1a95e352e 100644 --- a/fs/ocfs2/cluster/tcp.c +++ b/fs/ocfs2/cluster/tcp.c @@ -155,17 +155,17 @@ static void o2net_init_nst(struct o2net_send_tracking *nst, u32 msgtype, static void o2net_set_nst_sock_time(struct o2net_send_tracking *nst) { - do_gettimeofday(&nst->st_sock_time); + nst->st_sock_time = ktime_get(); } static void o2net_set_nst_send_time(struct o2net_send_tracking *nst) { - do_gettimeofday(&nst->st_send_time); + nst->st_send_time = ktime_get(); } static void o2net_set_nst_status_time(struct o2net_send_tracking *nst) { - do_gettimeofday(&nst->st_status_time); + nst->st_status_time = ktime_get(); } static void o2net_set_nst_sock_container(struct o2net_send_tracking *nst, diff --git a/fs/ocfs2/cluster/tcp_internal.h b/fs/ocfs2/cluster/tcp_internal.h index 15fdbdf9eb4b..b613aaaf3e5c 100644 --- a/fs/ocfs2/cluster/tcp_internal.h +++ b/fs/ocfs2/cluster/tcp_internal.h @@ -220,9 +220,9 @@ struct o2net_send_tracking { u32 st_msg_type; u32 st_msg_key; u8 st_node; - struct timeval st_sock_time; - struct timeval st_send_time; - struct timeval st_status_time; + ktime_t st_sock_time; + ktime_t st_send_time; + ktime_t st_status_time; }; #else struct o2net_send_tracking { -- cgit v1.2.3 From ff1becbf85bf4d4d4652915b7ab27db949585f6b Mon Sep 17 00:00:00 2001 From: Sunil Mushran Date: Wed, 22 Dec 2010 12:39:39 -0800 Subject: ocfs2/cluster: Use ktime instead of timeval in struct o2net_sock_container Replace time trackers in struct o2net_sock_container from struct timeval to union ktime. Signed-off-by: Sunil Mushran Signed-off-by: Joel Becker --- fs/ocfs2/cluster/netdebug.c | 28 ++++++------- fs/ocfs2/cluster/tcp.c | 91 ++++++++++++++++++++++++----------------- fs/ocfs2/cluster/tcp_internal.h | 19 +++++---- 3 files changed, 76 insertions(+), 62 deletions(-) diff --git a/fs/ocfs2/cluster/netdebug.c b/fs/ocfs2/cluster/netdebug.c index 2b986aa82299..536a93d13a06 100644 --- a/fs/ocfs2/cluster/netdebug.c +++ b/fs/ocfs2/cluster/netdebug.c @@ -280,8 +280,6 @@ static void *sc_seq_next(struct seq_file *seq, void *v, loff_t *pos) return sc; /* unused, just needs to be null when done */ } -#define TV_SEC_USEC(TV) TV.tv_sec, (long)TV.tv_usec - static int sc_seq_show(struct seq_file *seq, void *v) { struct o2net_sock_container *sc, *dummy_sc = seq->private; @@ -313,13 +311,13 @@ static int sc_seq_show(struct seq_file *seq, void *v) " remote node: %s\n" " page off: %zu\n" " handshake ok: %u\n" - " timer: %lu.%ld\n" - " data ready: %lu.%ld\n" - " advance start: %lu.%ld\n" - " advance stop: %lu.%ld\n" - " func start: %lu.%ld\n" - " func stop: %lu.%ld\n" - " func key: %u\n" + " timer: %lld usecs\n" + " data ready: %lld usecs\n" + " advance start: %lld usecs\n" + " advance stop: %lld usecs\n" + " func start: %lld usecs\n" + " func stop: %lld usecs\n" + " func key: 0x%08x\n" " func type: %u\n", sc, atomic_read(&sc->sc_kref.refcount), @@ -328,12 +326,12 @@ static int sc_seq_show(struct seq_file *seq, void *v) sc->sc_node->nd_name, sc->sc_page_off, sc->sc_handshake_ok, - TV_SEC_USEC(sc->sc_tv_timer), - TV_SEC_USEC(sc->sc_tv_data_ready), - TV_SEC_USEC(sc->sc_tv_advance_start), - TV_SEC_USEC(sc->sc_tv_advance_stop), - TV_SEC_USEC(sc->sc_tv_func_start), - TV_SEC_USEC(sc->sc_tv_func_stop), + (long long)ktime_to_us(sc->sc_tv_timer), + (long long)ktime_to_us(sc->sc_tv_data_ready), + (long long)ktime_to_us(sc->sc_tv_advance_start), + (long long)ktime_to_us(sc->sc_tv_advance_stop), + (long long)ktime_to_us(sc->sc_tv_func_start), + (long long)ktime_to_us(sc->sc_tv_func_stop), sc->sc_msg_key, sc->sc_msg_type); } diff --git a/fs/ocfs2/cluster/tcp.c b/fs/ocfs2/cluster/tcp.c index 49c1a95e352e..efd848334052 100644 --- a/fs/ocfs2/cluster/tcp.c +++ b/fs/ocfs2/cluster/tcp.c @@ -153,61 +153,75 @@ static void o2net_init_nst(struct o2net_send_tracking *nst, u32 msgtype, nst->st_node = node; } -static void o2net_set_nst_sock_time(struct o2net_send_tracking *nst) +static inline void o2net_set_nst_sock_time(struct o2net_send_tracking *nst) { nst->st_sock_time = ktime_get(); } -static void o2net_set_nst_send_time(struct o2net_send_tracking *nst) +static inline void o2net_set_nst_send_time(struct o2net_send_tracking *nst) { nst->st_send_time = ktime_get(); } -static void o2net_set_nst_status_time(struct o2net_send_tracking *nst) +static inline void o2net_set_nst_status_time(struct o2net_send_tracking *nst) { nst->st_status_time = ktime_get(); } -static void o2net_set_nst_sock_container(struct o2net_send_tracking *nst, - struct o2net_sock_container *sc) +static inline void o2net_set_nst_sock_container(struct o2net_send_tracking *nst, + struct o2net_sock_container *sc) { nst->st_sc = sc; } -static void o2net_set_nst_msg_id(struct o2net_send_tracking *nst, u32 msg_id) +static inline void o2net_set_nst_msg_id(struct o2net_send_tracking *nst, + u32 msg_id) { nst->st_id = msg_id; } -#else /* CONFIG_DEBUG_FS */ - -static inline void o2net_init_nst(struct o2net_send_tracking *nst, u32 msgtype, - u32 msgkey, struct task_struct *task, u8 node) +static inline void o2net_set_sock_timer(struct o2net_sock_container *sc) { + sc->sc_tv_timer = ktime_get(); } -static inline void o2net_set_nst_sock_time(struct o2net_send_tracking *nst) +static inline void o2net_set_data_ready_time(struct o2net_sock_container *sc) { + sc->sc_tv_data_ready = ktime_get(); } -static inline void o2net_set_nst_send_time(struct o2net_send_tracking *nst) +static inline void o2net_set_advance_start_time(struct o2net_sock_container *sc) { + sc->sc_tv_advance_start = ktime_get(); } -static inline void o2net_set_nst_status_time(struct o2net_send_tracking *nst) +static inline void o2net_set_advance_stop_time(struct o2net_sock_container *sc) { + sc->sc_tv_advance_stop = ktime_get(); } -static inline void o2net_set_nst_sock_container(struct o2net_send_tracking *nst, - struct o2net_sock_container *sc) +static inline void o2net_set_func_start_time(struct o2net_sock_container *sc) { + sc->sc_tv_func_start = ktime_get(); } -static inline void o2net_set_nst_msg_id(struct o2net_send_tracking *nst, - u32 msg_id) +static inline void o2net_set_func_stop_time(struct o2net_sock_container *sc) { + sc->sc_tv_func_stop = ktime_get(); } - +#else /* CONFIG_DEBUG_FS */ +# define o2net_init_nst(a, b, c, d, e) +# define o2net_set_nst_sock_time(a) +# define o2net_set_nst_send_time(a) +# define o2net_set_nst_status_time(a) +# define o2net_set_nst_sock_container(a, b) +# define o2net_set_nst_msg_id(a, b) +# define o2net_set_sock_timer(a) +# define o2net_set_data_ready_time(a) +# define o2net_set_advance_start_time(a) +# define o2net_set_advance_stop_time(a) +# define o2net_set_func_start_time(a) +# define o2net_set_func_stop_time(a) #endif /* CONFIG_DEBUG_FS */ static inline int o2net_reconnect_delay(void) @@ -555,7 +569,7 @@ static void o2net_data_ready(struct sock *sk, int bytes) if (sk->sk_user_data) { struct o2net_sock_container *sc = sk->sk_user_data; sclog(sc, "data_ready hit\n"); - do_gettimeofday(&sc->sc_tv_data_ready); + o2net_set_data_ready_time(sc); o2net_sc_queue_work(sc, &sc->sc_rx_work); ready = sc->sc_data_ready; } else { @@ -1192,13 +1206,13 @@ static int o2net_process_message(struct o2net_sock_container *sc, if (syserr != O2NET_ERR_NONE) goto out_respond; - do_gettimeofday(&sc->sc_tv_func_start); + o2net_set_func_start_time(sc); sc->sc_msg_key = be32_to_cpu(hdr->key); sc->sc_msg_type = be16_to_cpu(hdr->msg_type); handler_status = (nmh->nh_func)(hdr, sizeof(struct o2net_msg) + be16_to_cpu(hdr->data_len), nmh->nh_func_data, &ret_data); - do_gettimeofday(&sc->sc_tv_func_stop); + o2net_set_func_stop_time(sc); out_respond: /* this destroys the hdr, so don't use it after this */ @@ -1309,7 +1323,7 @@ static int o2net_advance_rx(struct o2net_sock_container *sc) size_t datalen; sclog(sc, "receiving\n"); - do_gettimeofday(&sc->sc_tv_advance_start); + o2net_set_advance_start_time(sc); if (unlikely(sc->sc_handshake_ok == 0)) { if(sc->sc_page_off < sizeof(struct o2net_handshake)) { @@ -1384,7 +1398,7 @@ static int o2net_advance_rx(struct o2net_sock_container *sc) out: sclog(sc, "ret = %d\n", ret); - do_gettimeofday(&sc->sc_tv_advance_stop); + o2net_set_advance_stop_time(sc); return ret; } @@ -1484,27 +1498,28 @@ static void o2net_idle_timer(unsigned long data) { struct o2net_sock_container *sc = (struct o2net_sock_container *)data; struct o2net_node *nn = o2net_nn_from_num(sc->sc_node->nd_num); - struct timeval now; - do_gettimeofday(&now); +#ifdef CONFIG_DEBUG_FS + ktime_t now = ktime_get(); +#endif printk(KERN_NOTICE "o2net: connection to " SC_NODEF_FMT " has been idle for %u.%u " "seconds, shutting it down.\n", SC_NODEF_ARGS(sc), o2net_idle_timeout() / 1000, o2net_idle_timeout() % 1000); - mlog(ML_NOTICE, "here are some times that might help debug the " - "situation: (tmr %ld.%ld now %ld.%ld dr %ld.%ld adv " - "%ld.%ld:%ld.%ld func (%08x:%u) %ld.%ld:%ld.%ld)\n", - sc->sc_tv_timer.tv_sec, (long) sc->sc_tv_timer.tv_usec, - now.tv_sec, (long) now.tv_usec, - sc->sc_tv_data_ready.tv_sec, (long) sc->sc_tv_data_ready.tv_usec, - sc->sc_tv_advance_start.tv_sec, - (long) sc->sc_tv_advance_start.tv_usec, - sc->sc_tv_advance_stop.tv_sec, - (long) sc->sc_tv_advance_stop.tv_usec, + +#ifdef CONFIG_DEBUG_FS + mlog(ML_NOTICE, "Here are some times that might help debug the " + "situation: (Timer: %lld, Now %lld, DataReady %lld, Advance %lld-%lld, " + "Key 0x%08x, Func %u, FuncTime %lld-%lld)\n", + (long long)ktime_to_us(sc->sc_tv_timer), (long long)ktime_to_us(now), + (long long)ktime_to_us(sc->sc_tv_data_ready), + (long long)ktime_to_us(sc->sc_tv_advance_start), + (long long)ktime_to_us(sc->sc_tv_advance_stop), sc->sc_msg_key, sc->sc_msg_type, - sc->sc_tv_func_start.tv_sec, (long) sc->sc_tv_func_start.tv_usec, - sc->sc_tv_func_stop.tv_sec, (long) sc->sc_tv_func_stop.tv_usec); + (long long)ktime_to_us(sc->sc_tv_func_start), + (long long)ktime_to_us(sc->sc_tv_func_stop)); +#endif /* * Initialize the nn_timeout so that the next connection attempt @@ -1520,7 +1535,7 @@ static void o2net_sc_reset_idle_timer(struct o2net_sock_container *sc) o2net_sc_cancel_delayed_work(sc, &sc->sc_keepalive_work); o2net_sc_queue_delayed_work(sc, &sc->sc_keepalive_work, msecs_to_jiffies(o2net_keepalive_delay())); - do_gettimeofday(&sc->sc_tv_timer); + o2net_set_sock_timer(sc); mod_timer(&sc->sc_idle_timeout, jiffies + msecs_to_jiffies(o2net_idle_timeout())); } diff --git a/fs/ocfs2/cluster/tcp_internal.h b/fs/ocfs2/cluster/tcp_internal.h index b613aaaf3e5c..f81576333911 100644 --- a/fs/ocfs2/cluster/tcp_internal.h +++ b/fs/ocfs2/cluster/tcp_internal.h @@ -166,18 +166,19 @@ struct o2net_sock_container { /* original handlers for the sockets */ void (*sc_state_change)(struct sock *sk); void (*sc_data_ready)(struct sock *sk, int bytes); -#ifdef CONFIG_DEBUG_FS - struct list_head sc_net_debug_item; -#endif - struct timeval sc_tv_timer; - struct timeval sc_tv_data_ready; - struct timeval sc_tv_advance_start; - struct timeval sc_tv_advance_stop; - struct timeval sc_tv_func_start; - struct timeval sc_tv_func_stop; + u32 sc_msg_key; u16 sc_msg_type; +#ifdef CONFIG_DEBUG_FS + struct list_head sc_net_debug_item; + ktime_t sc_tv_timer; + ktime_t sc_tv_data_ready; + ktime_t sc_tv_advance_start; + ktime_t sc_tv_advance_stop; + ktime_t sc_tv_func_start; + ktime_t sc_tv_func_stop; +#endif struct mutex sc_send_lock; }; -- cgit v1.2.3 From 3c193b3807e933cf2a16d55a38debbe549195847 Mon Sep 17 00:00:00 2001 From: Sunil Mushran Date: Wed, 22 Dec 2010 12:39:40 -0800 Subject: ocfs2/cluster: Track send message timing stats for each socket Tracks total send and status times for all messages sent on a socket. Signed-off-by: Sunil Mushran Signed-off-by: Joel Becker --- fs/ocfs2/cluster/tcp.c | 24 ++++++++++++++++++++++++ fs/ocfs2/cluster/tcp_internal.h | 6 ++++++ 2 files changed, 30 insertions(+) diff --git a/fs/ocfs2/cluster/tcp.c b/fs/ocfs2/cluster/tcp.c index efd848334052..4d61e19d6146 100644 --- a/fs/ocfs2/cluster/tcp.c +++ b/fs/ocfs2/cluster/tcp.c @@ -224,6 +224,28 @@ static inline void o2net_set_func_stop_time(struct o2net_sock_container *sc) # define o2net_set_func_stop_time(a) #endif /* CONFIG_DEBUG_FS */ +#ifdef CONFIG_OCFS2_FS_STATS +static void o2net_update_send_stats(struct o2net_send_tracking *nst, + struct o2net_sock_container *sc) +{ + sc->sc_tv_status_total = ktime_add(sc->sc_tv_status_total, + ktime_sub(ktime_get(), + nst->st_status_time)); + sc->sc_tv_send_total = ktime_add(sc->sc_tv_send_total, + ktime_sub(nst->st_status_time, + nst->st_send_time)); + sc->sc_tv_acquiry_total = ktime_add(sc->sc_tv_acquiry_total, + ktime_sub(nst->st_send_time, + nst->st_sock_time)); + sc->sc_send_count++; +} + +#else + +# define o2net_update_send_stats(a, b) + +#endif /* CONFIG_OCFS2_FS_STATS */ + static inline int o2net_reconnect_delay(void) { return o2nm_single_cluster->cl_reconnect_delay_ms; @@ -1093,6 +1115,8 @@ int o2net_send_message_vec(u32 msg_type, u32 key, struct kvec *caller_vec, o2net_set_nst_status_time(&nst); wait_event(nsw.ns_wq, o2net_nsw_completed(nn, &nsw)); + o2net_update_send_stats(&nst, sc); + /* Note that we avoid overwriting the callers status return * variable if a system error was reported on the other * side. Callers beware. */ diff --git a/fs/ocfs2/cluster/tcp_internal.h b/fs/ocfs2/cluster/tcp_internal.h index f81576333911..640c6fcef720 100644 --- a/fs/ocfs2/cluster/tcp_internal.h +++ b/fs/ocfs2/cluster/tcp_internal.h @@ -178,6 +178,12 @@ struct o2net_sock_container { ktime_t sc_tv_advance_stop; ktime_t sc_tv_func_start; ktime_t sc_tv_func_stop; +#endif +#ifdef CONFIG_OCFS2_FS_STATS + ktime_t sc_tv_acquiry_total; + ktime_t sc_tv_send_total; + ktime_t sc_tv_status_total; + u32 sc_send_count; #endif struct mutex sc_send_lock; }; -- cgit v1.2.3 From e453039f8bf44abf82f3ecfb34177e0cb04bce12 Mon Sep 17 00:00:00 2001 From: Sunil Mushran Date: Wed, 22 Dec 2010 12:39:41 -0800 Subject: ocfs2/cluster: Track process message timing stats for each socket Tracks total time taken to process messages received on a socket. Signed-off-by: Sunil Mushran Signed-off-by: Joel Becker --- fs/ocfs2/cluster/tcp.c | 15 +++++++++++++++ fs/ocfs2/cluster/tcp_internal.h | 2 ++ 2 files changed, 17 insertions(+) diff --git a/fs/ocfs2/cluster/tcp.c b/fs/ocfs2/cluster/tcp.c index 4d61e19d6146..bc2309554d0b 100644 --- a/fs/ocfs2/cluster/tcp.c +++ b/fs/ocfs2/cluster/tcp.c @@ -209,6 +209,11 @@ static inline void o2net_set_func_stop_time(struct o2net_sock_container *sc) { sc->sc_tv_func_stop = ktime_get(); } + +static ktime_t o2net_get_func_run_time(struct o2net_sock_container *sc) +{ + return ktime_sub(sc->sc_tv_func_stop, sc->sc_tv_func_start); +} #else /* CONFIG_DEBUG_FS */ # define o2net_init_nst(a, b, c, d, e) # define o2net_set_nst_sock_time(a) @@ -222,6 +227,7 @@ static inline void o2net_set_func_stop_time(struct o2net_sock_container *sc) # define o2net_set_advance_stop_time(a) # define o2net_set_func_start_time(a) # define o2net_set_func_stop_time(a) +# define o2net_get_func_run_time(a) (ktime_t)0 #endif /* CONFIG_DEBUG_FS */ #ifdef CONFIG_OCFS2_FS_STATS @@ -240,6 +246,13 @@ static void o2net_update_send_stats(struct o2net_send_tracking *nst, sc->sc_send_count++; } +static void o2net_update_recv_stats(struct o2net_sock_container *sc) +{ + sc->sc_tv_process_total = ktime_add(sc->sc_tv_process_total, + o2net_get_func_run_time(sc)); + sc->sc_recv_count++; +} + #else # define o2net_update_send_stats(a, b) @@ -1238,6 +1251,8 @@ static int o2net_process_message(struct o2net_sock_container *sc, nmh->nh_func_data, &ret_data); o2net_set_func_stop_time(sc); + o2net_update_recv_stats(sc); + out_respond: /* this destroys the hdr, so don't use it after this */ mutex_lock(&sc->sc_send_lock); diff --git a/fs/ocfs2/cluster/tcp_internal.h b/fs/ocfs2/cluster/tcp_internal.h index 640c6fcef720..4cbcb65784a3 100644 --- a/fs/ocfs2/cluster/tcp_internal.h +++ b/fs/ocfs2/cluster/tcp_internal.h @@ -184,6 +184,8 @@ struct o2net_sock_container { ktime_t sc_tv_send_total; ktime_t sc_tv_status_total; u32 sc_send_count; + u32 sc_recv_count; + ktime_t sc_tv_process_total; #endif struct mutex sc_send_lock; }; -- cgit v1.2.3 From db02754c8a1205b24beac70562c45ca5d671151f Mon Sep 17 00:00:00 2001 From: Sunil Mushran Date: Wed, 22 Dec 2010 12:39:42 -0800 Subject: ocfs2/cluster: Show o2net timing statistics Adds debugfs dentry o2net/stats to show the o2net timing statistics. Signed-off-by: Sunil Mushran Signed-off-by: Joel Becker --- fs/ocfs2/cluster/netdebug.c | 211 ++++++++++++++++++++++++++++++++------------ 1 file changed, 157 insertions(+), 54 deletions(-) diff --git a/fs/ocfs2/cluster/netdebug.c b/fs/ocfs2/cluster/netdebug.c index 536a93d13a06..61df89cedded 100644 --- a/fs/ocfs2/cluster/netdebug.c +++ b/fs/ocfs2/cluster/netdebug.c @@ -46,10 +46,15 @@ #define O2NET_DEBUG_DIR "o2net" #define SC_DEBUG_NAME "sock_containers" #define NST_DEBUG_NAME "send_tracking" +#define STATS_DEBUG_NAME "stats" + +#define SHOW_SOCK_CONTAINERS 0 +#define SHOW_SOCK_STATS 1 static struct dentry *o2net_dentry; static struct dentry *sc_dentry; static struct dentry *nst_dentry; +static struct dentry *stats_dentry; static DEFINE_SPINLOCK(o2net_debug_lock); @@ -232,6 +237,11 @@ void o2net_debug_del_sc(struct o2net_sock_container *sc) spin_unlock(&o2net_debug_lock); } +struct o2net_sock_debug { + int dbg_ctxt; + struct o2net_sock_container *dbg_sock; +}; + static struct o2net_sock_container *next_sc(struct o2net_sock_container *sc_start) { @@ -257,7 +267,8 @@ static struct o2net_sock_container static void *sc_seq_start(struct seq_file *seq, loff_t *pos) { - struct o2net_sock_container *sc, *dummy_sc = seq->private; + struct o2net_sock_debug *sd = seq->private; + struct o2net_sock_container *sc, *dummy_sc = sd->dbg_sock; spin_lock(&o2net_debug_lock); sc = next_sc(dummy_sc); @@ -268,7 +279,8 @@ static void *sc_seq_start(struct seq_file *seq, loff_t *pos) static void *sc_seq_next(struct seq_file *seq, void *v, loff_t *pos) { - struct o2net_sock_container *sc, *dummy_sc = seq->private; + struct o2net_sock_debug *sd = seq->private; + struct o2net_sock_container *sc, *dummy_sc = sd->dbg_sock; spin_lock(&o2net_debug_lock); sc = next_sc(dummy_sc); @@ -280,63 +292,107 @@ static void *sc_seq_next(struct seq_file *seq, void *v, loff_t *pos) return sc; /* unused, just needs to be null when done */ } -static int sc_seq_show(struct seq_file *seq, void *v) +#ifdef CONFIG_OCFS2_FS_STATS +# define sc_send_count(_s) ((_s)->sc_send_count) +# define sc_recv_count(_s) ((_s)->sc_recv_count) +# define sc_tv_acquiry_total_ns(_s) (ktime_to_ns((_s)->sc_tv_acquiry_total)) +# define sc_tv_send_total_ns(_s) (ktime_to_ns((_s)->sc_tv_send_total)) +# define sc_tv_status_total_ns(_s) (ktime_to_ns((_s)->sc_tv_status_total)) +# define sc_tv_process_total_ns(_s) (ktime_to_ns((_s)->sc_tv_process_total)) +#else +# define sc_send_count(_s) (0U) +# define sc_recv_count(_s) (0U) +# define sc_tv_acquiry_total_ns(_s) (0LL) +# define sc_tv_send_total_ns(_s) (0LL) +# define sc_tv_status_total_ns(_s) (0LL) +# define sc_tv_process_total_ns(_s) (0LL) +#endif + +/* So that debugfs.ocfs2 can determine which format is being used */ +#define O2NET_STATS_STR_VERSION 1 +static void sc_show_sock_stats(struct seq_file *seq, + struct o2net_sock_container *sc) { - struct o2net_sock_container *sc, *dummy_sc = seq->private; + if (!sc) + return; + + seq_printf(seq, "%d,%u,%lu,%lld,%lld,%lld,%lu,%lld\n", O2NET_STATS_STR_VERSION, + sc->sc_node->nd_num, (unsigned long)sc_send_count(sc), + (long long)sc_tv_acquiry_total_ns(sc), + (long long)sc_tv_send_total_ns(sc), + (long long)sc_tv_status_total_ns(sc), + (unsigned long)sc_recv_count(sc), + (long long)sc_tv_process_total_ns(sc)); +} - spin_lock(&o2net_debug_lock); - sc = next_sc(dummy_sc); +static void sc_show_sock_container(struct seq_file *seq, + struct o2net_sock_container *sc) +{ + struct inet_sock *inet = NULL; + __be32 saddr = 0, daddr = 0; + __be16 sport = 0, dport = 0; + + if (!sc) + return; + + if (sc->sc_sock) { + inet = inet_sk(sc->sc_sock->sk); + /* the stack's structs aren't sparse endian clean */ + saddr = (__force __be32)inet->inet_saddr; + daddr = (__force __be32)inet->inet_daddr; + sport = (__force __be16)inet->inet_sport; + dport = (__force __be16)inet->inet_dport; + } - if (sc != NULL) { - struct inet_sock *inet = NULL; + /* XXX sigh, inet-> doesn't have sparse annotation so any + * use of it here generates a warning with -Wbitwise */ + seq_printf(seq, "%p:\n" + " krefs: %d\n" + " sock: %pI4:%u -> " + "%pI4:%u\n" + " remote node: %s\n" + " page off: %zu\n" + " handshake ok: %u\n" + " timer: %lld usecs\n" + " data ready: %lld usecs\n" + " advance start: %lld usecs\n" + " advance stop: %lld usecs\n" + " func start: %lld usecs\n" + " func stop: %lld usecs\n" + " func key: 0x%08x\n" + " func type: %u\n", + sc, + atomic_read(&sc->sc_kref.refcount), + &saddr, inet ? ntohs(sport) : 0, + &daddr, inet ? ntohs(dport) : 0, + sc->sc_node->nd_name, + sc->sc_page_off, + sc->sc_handshake_ok, + (long long)ktime_to_us(sc->sc_tv_timer), + (long long)ktime_to_us(sc->sc_tv_data_ready), + (long long)ktime_to_us(sc->sc_tv_advance_start), + (long long)ktime_to_us(sc->sc_tv_advance_stop), + (long long)ktime_to_us(sc->sc_tv_func_start), + (long long)ktime_to_us(sc->sc_tv_func_stop), + sc->sc_msg_key, + sc->sc_msg_type); +} - __be32 saddr = 0, daddr = 0; - __be16 sport = 0, dport = 0; +static int sc_seq_show(struct seq_file *seq, void *v) +{ + struct o2net_sock_debug *sd = seq->private; + struct o2net_sock_container *sc, *dummy_sc = sd->dbg_sock; - if (sc->sc_sock) { - inet = inet_sk(sc->sc_sock->sk); - /* the stack's structs aren't sparse endian clean */ - saddr = (__force __be32)inet->inet_saddr; - daddr = (__force __be32)inet->inet_daddr; - sport = (__force __be16)inet->inet_sport; - dport = (__force __be16)inet->inet_dport; - } + spin_lock(&o2net_debug_lock); + sc = next_sc(dummy_sc); - /* XXX sigh, inet-> doesn't have sparse annotation so any - * use of it here generates a warning with -Wbitwise */ - seq_printf(seq, "%p:\n" - " krefs: %d\n" - " sock: %pI4:%u -> " - "%pI4:%u\n" - " remote node: %s\n" - " page off: %zu\n" - " handshake ok: %u\n" - " timer: %lld usecs\n" - " data ready: %lld usecs\n" - " advance start: %lld usecs\n" - " advance stop: %lld usecs\n" - " func start: %lld usecs\n" - " func stop: %lld usecs\n" - " func key: 0x%08x\n" - " func type: %u\n", - sc, - atomic_read(&sc->sc_kref.refcount), - &saddr, inet ? ntohs(sport) : 0, - &daddr, inet ? ntohs(dport) : 0, - sc->sc_node->nd_name, - sc->sc_page_off, - sc->sc_handshake_ok, - (long long)ktime_to_us(sc->sc_tv_timer), - (long long)ktime_to_us(sc->sc_tv_data_ready), - (long long)ktime_to_us(sc->sc_tv_advance_start), - (long long)ktime_to_us(sc->sc_tv_advance_stop), - (long long)ktime_to_us(sc->sc_tv_func_start), - (long long)ktime_to_us(sc->sc_tv_func_stop), - sc->sc_msg_key, - sc->sc_msg_type); + if (sc) { + if (sd->dbg_ctxt == SHOW_SOCK_CONTAINERS) + sc_show_sock_container(seq, sc); + else + sc_show_sock_stats(seq, sc); } - spin_unlock(&o2net_debug_lock); return 0; @@ -353,7 +409,7 @@ static const struct seq_operations sc_seq_ops = { .show = sc_seq_show, }; -static int sc_fop_open(struct inode *inode, struct file *file) +static int sc_common_open(struct file *file, struct o2net_sock_debug *sd) { struct o2net_sock_container *dummy_sc; struct seq_file *seq; @@ -371,7 +427,8 @@ static int sc_fop_open(struct inode *inode, struct file *file) goto out; seq = file->private_data; - seq->private = dummy_sc; + seq->private = sd; + sd->dbg_sock = dummy_sc; o2net_debug_add_sc(dummy_sc); dummy_sc = NULL; @@ -384,12 +441,48 @@ out: static int sc_fop_release(struct inode *inode, struct file *file) { struct seq_file *seq = file->private_data; - struct o2net_sock_container *dummy_sc = seq->private; + struct o2net_sock_debug *sd = seq->private; + struct o2net_sock_container *dummy_sc = sd->dbg_sock; o2net_debug_del_sc(dummy_sc); return seq_release_private(inode, file); } +static int stats_fop_open(struct inode *inode, struct file *file) +{ + struct o2net_sock_debug *sd; + + sd = kmalloc(sizeof(struct o2net_sock_debug), GFP_KERNEL); + if (sd == NULL) + return -ENOMEM; + + sd->dbg_ctxt = SHOW_SOCK_STATS; + sd->dbg_sock = NULL; + + return sc_common_open(file, sd); +} + +static const struct file_operations stats_seq_fops = { + .open = stats_fop_open, + .read = seq_read, + .llseek = seq_lseek, + .release = sc_fop_release, +}; + +static int sc_fop_open(struct inode *inode, struct file *file) +{ + struct o2net_sock_debug *sd; + + sd = kmalloc(sizeof(struct o2net_sock_debug), GFP_KERNEL); + if (sd == NULL) + return -ENOMEM; + + sd->dbg_ctxt = SHOW_SOCK_CONTAINERS; + sd->dbg_sock = NULL; + + return sc_common_open(file, sd); +} + static const struct file_operations sc_seq_fops = { .open = sc_fop_open, .read = seq_read, @@ -421,8 +514,17 @@ int o2net_debugfs_init(void) goto bail; } + stats_dentry = debugfs_create_file(STATS_DEBUG_NAME, S_IFREG|S_IRUSR, + o2net_dentry, NULL, + &stats_seq_fops); + if (!stats_dentry) { + mlog_errno(-ENOMEM); + goto bail; + } + return 0; bail: + debugfs_remove(stats_dentry); debugfs_remove(sc_dentry); debugfs_remove(nst_dentry); debugfs_remove(o2net_dentry); @@ -431,6 +533,7 @@ bail: void o2net_debugfs_exit(void) { + debugfs_remove(stats_dentry); debugfs_remove(sc_dentry); debugfs_remove(nst_dentry); debugfs_remove(o2net_dentry); -- cgit v1.2.3 From 7af36b9787e19b4cbde9ee984e431d64b586784e Mon Sep 17 00:00:00 2001 From: Sunyoung Kang Date: Sat, 18 Sep 2010 10:59:31 +0900 Subject: ARM: S5PV310: Update CMU registers for CPUFREQ This patch adds CMU(Clock Management Unit) registers for S5PV310/S5PC210 CPUFREQ driver and modifies some register names according to datasheet. Signed-off-by: Sunyoung Kang Signed-off-by: Kukjin Kim --- arch/arm/mach-s5pv310/clock.c | 12 ++-- arch/arm/mach-s5pv310/include/mach/regs-clock.h | 77 ++++++++++++++++++++++++- 2 files changed, 81 insertions(+), 8 deletions(-) diff --git a/arch/arm/mach-s5pv310/clock.c b/arch/arm/mach-s5pv310/clock.c index 58c9d33f36fe..fdce2b48efc6 100644 --- a/arch/arm/mach-s5pv310/clock.c +++ b/arch/arm/mach-s5pv310/clock.c @@ -244,7 +244,7 @@ static struct clksrc_clk clk_mout_corebus = { .id = -1, }, .sources = &clkset_mout_corebus, - .reg_src = { .reg = S5P_CLKSRC_CORE, .shift = 4, .size = 1 }, + .reg_src = { .reg = S5P_CLKSRC_DMC, .shift = 4, .size = 1 }, }; static struct clksrc_clk clk_sclk_dmc = { @@ -253,7 +253,7 @@ static struct clksrc_clk clk_sclk_dmc = { .id = -1, .parent = &clk_mout_corebus.clk, }, - .reg_div = { .reg = S5P_CLKDIV_CORE0, .shift = 12, .size = 3 }, + .reg_div = { .reg = S5P_CLKDIV_DMC0, .shift = 12, .size = 3 }, }; static struct clksrc_clk clk_aclk_cored = { @@ -262,7 +262,7 @@ static struct clksrc_clk clk_aclk_cored = { .id = -1, .parent = &clk_sclk_dmc.clk, }, - .reg_div = { .reg = S5P_CLKDIV_CORE0, .shift = 16, .size = 3 }, + .reg_div = { .reg = S5P_CLKDIV_DMC0, .shift = 16, .size = 3 }, }; static struct clksrc_clk clk_aclk_corep = { @@ -271,7 +271,7 @@ static struct clksrc_clk clk_aclk_corep = { .id = -1, .parent = &clk_aclk_cored.clk, }, - .reg_div = { .reg = S5P_CLKDIV_CORE0, .shift = 20, .size = 3 }, + .reg_div = { .reg = S5P_CLKDIV_DMC0, .shift = 20, .size = 3 }, }; static struct clksrc_clk clk_aclk_acp = { @@ -280,7 +280,7 @@ static struct clksrc_clk clk_aclk_acp = { .id = -1, .parent = &clk_mout_corebus.clk, }, - .reg_div = { .reg = S5P_CLKDIV_CORE0, .shift = 0, .size = 3 }, + .reg_div = { .reg = S5P_CLKDIV_DMC0, .shift = 0, .size = 3 }, }; static struct clksrc_clk clk_pclk_acp = { @@ -289,7 +289,7 @@ static struct clksrc_clk clk_pclk_acp = { .id = -1, .parent = &clk_aclk_acp.clk, }, - .reg_div = { .reg = S5P_CLKDIV_CORE0, .shift = 4, .size = 3 }, + .reg_div = { .reg = S5P_CLKDIV_DMC0, .shift = 4, .size = 3 }, }; /* Core list of CMU_TOP side */ diff --git a/arch/arm/mach-s5pv310/include/mach/regs-clock.h b/arch/arm/mach-s5pv310/include/mach/regs-clock.h index f1028cad9788..9e9e44c3290e 100644 --- a/arch/arm/mach-s5pv310/include/mach/regs-clock.h +++ b/arch/arm/mach-s5pv310/include/mach/regs-clock.h @@ -19,6 +19,12 @@ #define S5P_INFORM0 S5P_CLKREG(0x800) +#define S5P_CLKDIV_LEFTBUS S5P_CLKREG(0x04500) +#define S5P_CLKDIV_STAT_LEFTBUS S5P_CLKREG(0x04600) + +#define S5P_CLKDIV_RIGHTBUS S5P_CLKREG(0x08500) +#define S5P_CLKDIV_STAT_RIGHTBUS S5P_CLKREG(0x08600) + #define S5P_EPLL_CON0 S5P_CLKREG(0x0C110) #define S5P_EPLL_CON1 S5P_CLKREG(0x0C114) #define S5P_VPLL_CON0 S5P_CLKREG(0x0C120) @@ -58,6 +64,8 @@ #define S5P_CLKSRC_MASK_PERIL0 S5P_CLKREG(0x0C350) #define S5P_CLKSRC_MASK_PERIL1 S5P_CLKREG(0x0C354) +#define S5P_CLKDIV_STAT_TOP S5P_CLKREG(0x0C610) + #define S5P_CLKGATE_IP_CAM S5P_CLKREG(0x0C920) #define S5P_CLKGATE_IP_IMAGE S5P_CLKREG(0x0C930) #define S5P_CLKGATE_IP_LCD0 S5P_CLKREG(0x0C934) @@ -66,8 +74,9 @@ #define S5P_CLKGATE_IP_PERIL S5P_CLKREG(0x0C950) #define S5P_CLKGATE_IP_PERIR S5P_CLKREG(0x0C960) -#define S5P_CLKSRC_CORE S5P_CLKREG(0x10200) -#define S5P_CLKDIV_CORE0 S5P_CLKREG(0x10500) +#define S5P_CLKSRC_DMC S5P_CLKREG(0x10200) +#define S5P_CLKDIV_DMC0 S5P_CLKREG(0x10500) +#define S5P_CLKDIV_STAT_DMC0 S5P_CLKREG(0x10600) #define S5P_APLL_LOCK S5P_CLKREG(0x14000) #define S5P_MPLL_LOCK S5P_CLKREG(0x14004) @@ -84,6 +93,70 @@ #define S5P_CLKGATE_SCLKCPU S5P_CLKREG(0x14800) +/* APLL_LOCK */ +#define S5P_APLL_LOCKTIME (0x1C20) /* 300us */ + +/* APLL_CON0 */ +#define S5P_APLLCON0_ENABLE_SHIFT (31) +#define S5P_APLLCON0_LOCKED_SHIFT (29) +#define S5P_APLL_VAL_1000 ((250 << 16) | (6 << 8) | 1) + +/* CLK_SRC_CPU */ +#define S5P_CLKSRC_CPU_MUXCORE_SHIFT (16) +#define S5P_CLKMUX_STATCPU_MUXCORE_MASK (0x7 << S5P_CLKSRC_CPU_MUXCORE_SHIFT) + +/* CLKDIV_CPU0 */ +#define S5P_CLKDIV_CPU0_CORE_SHIFT (0) +#define S5P_CLKDIV_CPU0_CORE_MASK (0x7 << S5P_CLKDIV_CPU0_CORE_SHIFT) +#define S5P_CLKDIV_CPU0_COREM0_SHIFT (4) +#define S5P_CLKDIV_CPU0_COREM0_MASK (0x7 << S5P_CLKDIV_CPU0_COREM0_SHIFT) +#define S5P_CLKDIV_CPU0_COREM1_SHIFT (8) +#define S5P_CLKDIV_CPU0_COREM1_MASK (0x7 << S5P_CLKDIV_CPU0_COREM1_SHIFT) +#define S5P_CLKDIV_CPU0_PERIPH_SHIFT (12) +#define S5P_CLKDIV_CPU0_PERIPH_MASK (0x7 << S5P_CLKDIV_CPU0_PERIPH_SHIFT) +#define S5P_CLKDIV_CPU0_ATB_SHIFT (16) +#define S5P_CLKDIV_CPU0_ATB_MASK (0x7 << S5P_CLKDIV_CPU0_ATB_SHIFT) +#define S5P_CLKDIV_CPU0_PCLKDBG_SHIFT (20) +#define S5P_CLKDIV_CPU0_PCLKDBG_MASK (0x7 << S5P_CLKDIV_CPU0_PCLKDBG_SHIFT) +#define S5P_CLKDIV_CPU0_APLL_SHIFT (24) +#define S5P_CLKDIV_CPU0_APLL_MASK (0x7 << S5P_CLKDIV_CPU0_APLL_SHIFT) + +/* CLKDIV_DMC0 */ +#define S5P_CLKDIV_DMC0_ACP_SHIFT (0) +#define S5P_CLKDIV_DMC0_ACP_MASK (0x7 << S5P_CLKDIV_DMC0_ACP_SHIFT) +#define S5P_CLKDIV_DMC0_ACPPCLK_SHIFT (4) +#define S5P_CLKDIV_DMC0_ACPPCLK_MASK (0x7 << S5P_CLKDIV_DMC0_ACPPCLK_SHIFT) +#define S5P_CLKDIV_DMC0_DPHY_SHIFT (8) +#define S5P_CLKDIV_DMC0_DPHY_MASK (0x7 << S5P_CLKDIV_DMC0_DPHY_SHIFT) +#define S5P_CLKDIV_DMC0_DMC_SHIFT (12) +#define S5P_CLKDIV_DMC0_DMC_MASK (0x7 << S5P_CLKDIV_DMC0_DMC_SHIFT) +#define S5P_CLKDIV_DMC0_DMCD_SHIFT (16) +#define S5P_CLKDIV_DMC0_DMCD_MASK (0x7 << S5P_CLKDIV_DMC0_DMCD_SHIFT) +#define S5P_CLKDIV_DMC0_DMCP_SHIFT (20) +#define S5P_CLKDIV_DMC0_DMCP_MASK (0x7 << S5P_CLKDIV_DMC0_DMCP_SHIFT) +#define S5P_CLKDIV_DMC0_COPY2_SHIFT (24) +#define S5P_CLKDIV_DMC0_COPY2_MASK (0x7 << S5P_CLKDIV_DMC0_COPY2_SHIFT) +#define S5P_CLKDIV_DMC0_CORETI_SHIFT (28) +#define S5P_CLKDIV_DMC0_CORETI_MASK (0x7 << S5P_CLKDIV_DMC0_CORETI_SHIFT) + +/* CLKDIV_TOP */ +#define S5P_CLKDIV_TOP_ACLK200_SHIFT (0) +#define S5P_CLKDIV_TOP_ACLK200_MASK (0x7 << S5P_CLKDIV_TOP_ACLK200_SHIFT) +#define S5P_CLKDIV_TOP_ACLK100_SHIFT (4) +#define S5P_CLKDIV_TOP_ACLK100_MASK (0xf << S5P_CLKDIV_TOP_ACLK100_SHIFT) +#define S5P_CLKDIV_TOP_ACLK160_SHIFT (8) +#define S5P_CLKDIV_TOP_ACLK160_MASK (0x7 << S5P_CLKDIV_TOP_ACLK160_SHIFT) +#define S5P_CLKDIV_TOP_ACLK133_SHIFT (12) +#define S5P_CLKDIV_TOP_ACLK133_MASK (0x7 << S5P_CLKDIV_TOP_ACLK133_SHIFT) +#define S5P_CLKDIV_TOP_ONENAND_SHIFT (16) +#define S5P_CLKDIV_TOP_ONENAND_MASK (0x7 << S5P_CLKDIV_TOP_ONENAND_SHIFT) + +/* CLKDIV_LEFTBUS / CLKDIV_RIGHTBUS*/ +#define S5P_CLKDIV_BUS_GDLR_SHIFT (0) +#define S5P_CLKDIV_BUS_GDLR_MASK (0x7 << S5P_CLKDIV_BUS_GDLR_SHIFT) +#define S5P_CLKDIV_BUS_GPLR_SHIFT (4) +#define S5P_CLKDIV_BUS_GPLR_MASK (0x7 << S5P_CLKDIV_BUS_GPLR_SHIFT) + /* Compatibility defines */ #define S5P_EPLL_CON S5P_EPLL_CON0 -- cgit v1.2.3 From 09dc781e94b881d23e3c5da8c72d6832ae542938 Mon Sep 17 00:00:00 2001 From: Sangwook Ju Date: Wed, 22 Dec 2010 07:26:40 +0900 Subject: ARM: S5PV310: Define missing CMU register for CPUFREQ This patch adds missing CMU(Clock Management Unit) registers for updated S5PV310 CPUFREQ driver. Signed-off-by: Sangwook Ju Signed-off-by: Sangbeom Kim Signed-off-by: Kukjin Kim --- arch/arm/mach-s5pv310/include/mach/regs-clock.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/arm/mach-s5pv310/include/mach/regs-clock.h b/arch/arm/mach-s5pv310/include/mach/regs-clock.h index 9e9e44c3290e..b5c4ada1cff5 100644 --- a/arch/arm/mach-s5pv310/include/mach/regs-clock.h +++ b/arch/arm/mach-s5pv310/include/mach/regs-clock.h @@ -89,7 +89,9 @@ #define S5P_CLKMUX_STATCPU S5P_CLKREG(0x14400) #define S5P_CLKDIV_CPU S5P_CLKREG(0x14500) +#define S5P_CLKDIV_CPU1 S5P_CLKREG(0x14504) #define S5P_CLKDIV_STATCPU S5P_CLKREG(0x14600) +#define S5P_CLKDIV_STATCPU1 S5P_CLKREG(0x14604) #define S5P_CLKGATE_SCLKCPU S5P_CLKREG(0x14800) @@ -100,6 +102,7 @@ #define S5P_APLLCON0_ENABLE_SHIFT (31) #define S5P_APLLCON0_LOCKED_SHIFT (29) #define S5P_APLL_VAL_1000 ((250 << 16) | (6 << 8) | 1) +#define S5P_APLL_VAL_800 ((200 << 16) | (6 << 8) | 1) /* CLK_SRC_CPU */ #define S5P_CLKSRC_CPU_MUXCORE_SHIFT (16) -- cgit v1.2.3 From dd0b7e20da906b40d55f24bb2dc21abd58ed3f55 Mon Sep 17 00:00:00 2001 From: Sunyoung Kang Date: Wed, 22 Dec 2010 07:21:17 +0900 Subject: ARM: S5PV310: Add DMC registers and map_desc This patch adds DMC io mapping for access it and adds registers. This is used in checking DRAM memory type. Signed-off-by: Sunyoung Kang Signed-off-by: Kukjin Kim --- arch/arm/mach-s5pv310/cpu.c | 5 +++++ arch/arm/mach-s5pv310/include/mach/map.h | 2 ++ arch/arm/mach-s5pv310/include/mach/regs-mem.h | 23 +++++++++++++++++++++++ 3 files changed, 30 insertions(+) create mode 100644 arch/arm/mach-s5pv310/include/mach/regs-mem.h diff --git a/arch/arm/mach-s5pv310/cpu.c b/arch/arm/mach-s5pv310/cpu.c index 82ce4aa6d61a..283dd75effe7 100644 --- a/arch/arm/mach-s5pv310/cpu.c +++ b/arch/arm/mach-s5pv310/cpu.c @@ -72,6 +72,11 @@ static struct map_desc s5pv310_iodesc[] __initdata = { .pfn = __phys_to_pfn(S5PV310_PA_GPIO3), .length = SZ_256, .type = MT_DEVICE, + }, { + .virtual = (unsigned long)S5P_VA_DMC0, + .pfn = __phys_to_pfn(S5PV310_PA_DMC0), + .length = SZ_4K, + .type = MT_DEVICE, }, { .virtual = (unsigned long)S3C_VA_UART, .pfn = __phys_to_pfn(S3C_PA_UART), diff --git a/arch/arm/mach-s5pv310/include/mach/map.h b/arch/arm/mach-s5pv310/include/mach/map.h index 7acf4e77e92e..37294f13ca0c 100644 --- a/arch/arm/mach-s5pv310/include/mach/map.h +++ b/arch/arm/mach-s5pv310/include/mach/map.h @@ -44,6 +44,8 @@ #define S5PV310_PA_WATCHDOG (0x10060000) #define S5PV310_PA_RTC (0x10070000) +#define S5PV310_PA_DMC0 (0x10400000) + #define S5PV310_PA_COMBINER (0x10448000) #define S5PV310_PA_COREPERI (0x10500000) diff --git a/arch/arm/mach-s5pv310/include/mach/regs-mem.h b/arch/arm/mach-s5pv310/include/mach/regs-mem.h new file mode 100644 index 000000000000..834227140eaa --- /dev/null +++ b/arch/arm/mach-s5pv310/include/mach/regs-mem.h @@ -0,0 +1,23 @@ +/* linux/arch/arm/mach-s5pv310/include/mach/regs-mem.h + * + * Copyright (c) 2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * S5PV310 - SROMC and DMC register definitions + * + * 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. +*/ + +#ifndef __ASM_ARCH_REGS_MEM_H +#define __ASM_ARCH_REGS_MEM_H __FILE__ + +#include + +#define S5P_DMC0_MEMCON_OFFSET 0x04 + +#define S5P_DMC0_MEMTYPE_SHIFT 8 +#define S5P_DMC0_MEMTYPE_MASK 0xF + +#endif /* __ASM_ARCH_REGS_MEM_H */ -- cgit v1.2.3 From f40f91fefcf3a9049bcfa31ac53bc0e775444dab Mon Sep 17 00:00:00 2001 From: Sunyoung Kang Date: Thu, 16 Sep 2010 17:59:21 +0900 Subject: ARM: S5PV310: Add support CPUFREQ This patch adds support CPUFREQ driver for S5PV310 and S5PC210. This can support DVFS(Dynamic Voltage and Frequency Scaling). The voltage scaling depends on existence of regulator. Sigend-off-by: Sunyoung Kang Signed-off-by: Kukjin Kim --- arch/arm/mach-s5pv310/cpufreq.c | 561 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 561 insertions(+) create mode 100644 arch/arm/mach-s5pv310/cpufreq.c diff --git a/arch/arm/mach-s5pv310/cpufreq.c b/arch/arm/mach-s5pv310/cpufreq.c new file mode 100644 index 000000000000..bcd4ebf93e56 --- /dev/null +++ b/arch/arm/mach-s5pv310/cpufreq.c @@ -0,0 +1,561 @@ +/* linux/arch/arm/mach-s5pv310/cpufreq.c + * + * Copyright (c) 2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * S5PV310 - CPU frequency scaling support + * + * 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 +#include +#include +#include +#include + +#include +#include +#include + +#include + +static struct clk *cpu_clk; +static struct clk *moutcore; +static struct clk *mout_mpll; +static struct clk *mout_apll; + +#ifdef CONFIG_REGULATOR +static struct regulator *arm_regulator; +static struct regulator *int_regulator; +#endif + +static struct cpufreq_freqs freqs; +static unsigned int armclk_use_apll; +static unsigned int memtype; + +enum s5pv310_memory_type { + DDR2 = 4, + LPDDR2, + DDR3, +}; + +enum cpufreq_level_index { + L0, L1, L2, L3, L4, CPUFREQ_LEVEL_END, +}; + +static struct cpufreq_frequency_table s5pv310_freq_table[] = { + {L0, 1000*1000}, + {L1, 800*1000}, + {L2, 400*1000}, + {L3, 200*1000}, + {L4, 100*1000}, + {0, CPUFREQ_TABLE_END}, +}; + +static unsigned int clkdiv_cpu0[CPUFREQ_LEVEL_END + 1][7] = { + /* + * Clock divider value for following + * { DIVCORE, DIVCOREM0, DIVCOREM1, DIVPERIPH, + * DIVATB, DIVPCLK_DBG, DIVAPLL } + */ + + /* ARM L0: 1000MHz */ + { 0, 3, 7, 3, 3, 0, 0 }, + + /* ARM L1: 800MHz */ + { 0, 3, 7, 3, 3, 0, 0 }, + + /* ARM L2: 400MHz */ + { 1, 1, 3, 1, 1, 0, 0 }, + + /* ARM L3: 200MHz */ + { 3, 0, 1, 0, 0, 0, 0 }, + + /* ARM L4A: 100MHz, for DDR2/3 */ + { 7, 0, 1, 0, 0, 0, 0 }, + + /* ARM L4B: 100MHz, for LPDDR2 (SMDKV310 has LPDDR2) */ + { 7, 0, 1, 0, 0, 0, 0 }, +}; + +static unsigned int clkdiv_dmc0[CPUFREQ_LEVEL_END + 1][8] = { + /* + * Clock divider value for following + * { DIVACP, DIVACP_PCLK, DIVDPHY, DIVDMC, DIVDMCD + * DIVDMCP, DIVCOPY2, DIVCORE_TIMERS } + */ + + /* DMC L0: 400MHz */ + { 3, 1, 1, 1, 1, 1, 3, 1 }, + + /* DMC L1: 400MHz */ + { 3, 1, 1, 1, 1, 1, 3, 1 }, + + /* DMC L2: 400MHz */ + { 3, 1, 1, 1, 1, 1, 3, 1 }, + + /* DMC L3: 400MHz */ + { 3, 1, 1, 1, 1, 1, 3, 1 }, + + /* DMC L4A: 400MHz, for DDR2/3 */ + { 7, 1, 1, 1, 1, 1, 3, 1 }, + + /* DMC L4B: 200MHz, for LPDDR2 */ + { 7, 1, 1, 3, 1, 1, 3, 1 }, +}; + +static unsigned int clkdiv_top[CPUFREQ_LEVEL_END + 1][5] = { + /* + * Clock divider value for following + * { DIVACLK200, DIVACLK100, DIVACLK160, DIVACLK133, DIVONENAND } + */ + + /* ACLK200 L0: 200MHz */ + { 3, 7, 4, 5, 1 }, + + /* ACLK200 L1: 200MHz */ + { 3, 7, 4, 5, 1 }, + + /* ACLK200 L2: 200MHz */ + { 3, 7, 4, 5, 1 }, + + /* ACLK200 L3: 200MHz */ + { 3, 7, 4, 5, 1 }, + + /* ACLK200 L4A: 100MHz */ + { 7, 7, 7, 7, 1 }, + + /* ACLK200 L4B: 100MHz */ + { 7, 7, 7, 7, 1 }, +}; + +static unsigned int clkdiv_lr_bus[CPUFREQ_LEVEL_END + 1][2] = { + /* + * Clock divider value for following + * { DIVGDL/R, DIVGPL/R } + */ + + /* ACLK_GDL/R L0: 200MHz */ + { 3, 1 }, + + /* ACLK_GDL/R L1: 200MHz */ + { 3, 1 }, + + /* ACLK_GDL/R L2: 200MHz */ + { 3, 1 }, + + /* ACLK_GDL/R L3: 200MHz */ + { 3, 1 }, + + /* ACLK_GDL/R L4A: 100MHz */ + { 7, 1 }, + + /* ACLK_GDL/R L4B: 100MHz */ + { 7, 1 }, +}; + +struct cpufreq_voltage_table { + unsigned int index; /* any */ + unsigned int arm_volt; /* uV */ + unsigned int int_volt; +}; + +static struct cpufreq_voltage_table s5pv310_volt_table[] = { + { + .index = L0, + .arm_volt = 1200000, + .int_volt = 1100000, + }, { + .index = L1, + .arm_volt = 1100000, + .int_volt = 1100000, + }, { + .index = L2, + .arm_volt = 1050000, + .int_volt = 1100000, + }, { + .index = L3, + .arm_volt = 1050000, + .int_volt = 1100000, + }, { + .index = L4, + .arm_volt = 1000000, + .int_volt = 1000000, + }, +}; + +int s5pv310_verify_speed(struct cpufreq_policy *policy) +{ + return cpufreq_frequency_table_verify(policy, s5pv310_freq_table); +} + +unsigned int s5pv310_getspeed(unsigned int cpu) +{ + return clk_get_rate(cpu_clk) / 1000; +} + +void s5pv310_set_clkdiv(unsigned int div_index) +{ + unsigned int tmp; + + /* Change Divider - CPU0 */ + + tmp = __raw_readl(S5P_CLKDIV_CPU); + + tmp &= ~(S5P_CLKDIV_CPU0_CORE_MASK | S5P_CLKDIV_CPU0_COREM0_MASK | + S5P_CLKDIV_CPU0_COREM1_MASK | S5P_CLKDIV_CPU0_PERIPH_MASK | + S5P_CLKDIV_CPU0_ATB_MASK | S5P_CLKDIV_CPU0_PCLKDBG_MASK | + S5P_CLKDIV_CPU0_APLL_MASK); + + tmp |= ((clkdiv_cpu0[div_index][0] << S5P_CLKDIV_CPU0_CORE_SHIFT) | + (clkdiv_cpu0[div_index][1] << S5P_CLKDIV_CPU0_COREM0_SHIFT) | + (clkdiv_cpu0[div_index][2] << S5P_CLKDIV_CPU0_COREM1_SHIFT) | + (clkdiv_cpu0[div_index][3] << S5P_CLKDIV_CPU0_PERIPH_SHIFT) | + (clkdiv_cpu0[div_index][4] << S5P_CLKDIV_CPU0_ATB_SHIFT) | + (clkdiv_cpu0[div_index][5] << S5P_CLKDIV_CPU0_PCLKDBG_SHIFT) | + (clkdiv_cpu0[div_index][6] << S5P_CLKDIV_CPU0_APLL_SHIFT)); + + __raw_writel(tmp, S5P_CLKDIV_CPU); + + do { + tmp = __raw_readl(S5P_CLKDIV_STATCPU); + } while (tmp & 0x1111111); + + /* Change Divider - DMC0 */ + + tmp = __raw_readl(S5P_CLKDIV_DMC0); + + tmp &= ~(S5P_CLKDIV_DMC0_ACP_MASK | S5P_CLKDIV_DMC0_ACPPCLK_MASK | + S5P_CLKDIV_DMC0_DPHY_MASK | S5P_CLKDIV_DMC0_DMC_MASK | + S5P_CLKDIV_DMC0_DMCD_MASK | S5P_CLKDIV_DMC0_DMCP_MASK | + S5P_CLKDIV_DMC0_COPY2_MASK | S5P_CLKDIV_DMC0_CORETI_MASK); + + tmp |= ((clkdiv_dmc0[div_index][0] << S5P_CLKDIV_DMC0_ACP_SHIFT) | + (clkdiv_dmc0[div_index][1] << S5P_CLKDIV_DMC0_ACPPCLK_SHIFT) | + (clkdiv_dmc0[div_index][2] << S5P_CLKDIV_DMC0_DPHY_SHIFT) | + (clkdiv_dmc0[div_index][3] << S5P_CLKDIV_DMC0_DMC_SHIFT) | + (clkdiv_dmc0[div_index][4] << S5P_CLKDIV_DMC0_DMCD_SHIFT) | + (clkdiv_dmc0[div_index][5] << S5P_CLKDIV_DMC0_DMCP_SHIFT) | + (clkdiv_dmc0[div_index][6] << S5P_CLKDIV_DMC0_COPY2_SHIFT) | + (clkdiv_dmc0[div_index][7] << S5P_CLKDIV_DMC0_CORETI_SHIFT)); + + __raw_writel(tmp, S5P_CLKDIV_DMC0); + + do { + tmp = __raw_readl(S5P_CLKDIV_STAT_DMC0); + } while (tmp & 0x11111111); + + /* Change Divider - TOP */ + + tmp = __raw_readl(S5P_CLKDIV_TOP); + + tmp &= ~(S5P_CLKDIV_TOP_ACLK200_MASK | S5P_CLKDIV_TOP_ACLK100_MASK | + S5P_CLKDIV_TOP_ACLK160_MASK | S5P_CLKDIV_TOP_ACLK133_MASK | + S5P_CLKDIV_TOP_ONENAND_MASK); + + tmp |= ((clkdiv_top[div_index][0] << S5P_CLKDIV_TOP_ACLK200_SHIFT) | + (clkdiv_top[div_index][1] << S5P_CLKDIV_TOP_ACLK100_SHIFT) | + (clkdiv_top[div_index][2] << S5P_CLKDIV_TOP_ACLK160_SHIFT) | + (clkdiv_top[div_index][3] << S5P_CLKDIV_TOP_ACLK133_SHIFT) | + (clkdiv_top[div_index][4] << S5P_CLKDIV_TOP_ONENAND_SHIFT)); + + __raw_writel(tmp, S5P_CLKDIV_TOP); + + do { + tmp = __raw_readl(S5P_CLKDIV_STAT_TOP); + } while (tmp & 0x11111); + + /* Change Divider - LEFTBUS */ + + tmp = __raw_readl(S5P_CLKDIV_LEFTBUS); + + tmp &= ~(S5P_CLKDIV_BUS_GDLR_MASK | S5P_CLKDIV_BUS_GPLR_MASK); + + tmp |= ((clkdiv_lr_bus[div_index][0] << S5P_CLKDIV_BUS_GDLR_SHIFT) | + (clkdiv_lr_bus[div_index][1] << S5P_CLKDIV_BUS_GPLR_SHIFT)); + + __raw_writel(tmp, S5P_CLKDIV_LEFTBUS); + + do { + tmp = __raw_readl(S5P_CLKDIV_STAT_LEFTBUS); + } while (tmp & 0x11); + + /* Change Divider - RIGHTBUS */ + + tmp = __raw_readl(S5P_CLKDIV_RIGHTBUS); + + tmp &= ~(S5P_CLKDIV_BUS_GDLR_MASK | S5P_CLKDIV_BUS_GPLR_MASK); + + tmp |= ((clkdiv_lr_bus[div_index][0] << S5P_CLKDIV_BUS_GDLR_SHIFT) | + (clkdiv_lr_bus[div_index][1] << S5P_CLKDIV_BUS_GPLR_SHIFT)); + + __raw_writel(tmp, S5P_CLKDIV_RIGHTBUS); + + do { + tmp = __raw_readl(S5P_CLKDIV_STAT_RIGHTBUS); + } while (tmp & 0x11); +} + +static int s5pv310_target(struct cpufreq_policy *policy, + unsigned int target_freq, + unsigned int relation) +{ + unsigned int index, div_index, tmp; + unsigned int arm_volt, int_volt; + unsigned int need_apll = 0; + + freqs.old = s5pv310_getspeed(policy->cpu); + + if (cpufreq_frequency_table_target(policy, s5pv310_freq_table, + target_freq, relation, &index)) + return -EINVAL; + + freqs.new = s5pv310_freq_table[index].frequency; + freqs.cpu = policy->cpu; + + if (freqs.new == freqs.old) + return 0; + + /* + * If freqs.new is higher than 800MHz + * cpufreq driver should turn on apll + */ + if (index < L1) + need_apll = 1; + + /* If the memory type is LPDDR2, use L4-B instead of L4-A */ + if ((index == L4) && (memtype == LPDDR2)) + div_index = index + 1; + else + div_index = index; + + /* get the voltage value */ + arm_volt = s5pv310_volt_table[index].arm_volt; + int_volt = s5pv310_volt_table[index].int_volt; + + cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); + + /* control regulator */ + if (freqs.new > freqs.old) { + /* Voltage up */ +#ifdef CONFIG_REGULATOR + regulator_set_voltage(arm_regulator, arm_volt, arm_volt); + regulator_set_voltage(int_regulator, int_volt, int_volt); +#endif + } + + /* Clock Configuration Procedure */ + + /* 1. Change the system clock divider values */ + s5pv310_set_clkdiv(div_index); + + /* 2. Change the divider values for special clocks in CMU_TOP */ + /* currently nothing */ + + /* 3. Change the XPLL values or Select the parent XPLL */ + if (need_apll) { + if (!armclk_use_apll) { + /* + * If the parent clock of armclk isn't apll + * here need to set apll (include m,p,s value) + */ + + /* a. MUX_CORE_SEL = MPLL, + * ARMCLK uses MPLL for lock time */ + clk_set_parent(moutcore, mout_mpll); + + do { + tmp = (__raw_readl(S5P_CLKMUX_STATCPU) + >> S5P_CLKSRC_CPU_MUXCORE_SHIFT); + tmp &= 0x7; + } while (tmp != 0x2); + + /* b. Set APLL Lock time */ + __raw_writel(S5P_APLL_LOCKTIME, S5P_APLL_LOCK); + + /* c. Change PLL PMS values */ + __raw_writel(S5P_APLL_VAL_1000, S5P_APLL_CON0); + + /* d. Turn on a PLL */ + tmp = __raw_readl(S5P_APLL_CON0); + tmp |= (0x1 << S5P_APLLCON0_ENABLE_SHIFT); + __raw_writel(tmp, S5P_APLL_CON0); + + /* e. wait_lock_time */ + do { + tmp = __raw_readl(S5P_APLL_CON0); + } while (!(tmp & (0x1 << S5P_APLLCON0_LOCKED_SHIFT))); + + armclk_use_apll = 1; + + } + + /* MUX_CORE_SEL = APLL */ + clk_set_parent(moutcore, mout_apll); + + do { + tmp = __raw_readl(S5P_CLKMUX_STATCPU); + tmp &= S5P_CLKMUX_STATCPU_MUXCORE_MASK; + } while (tmp != (0x1 << S5P_CLKSRC_CPU_MUXCORE_SHIFT)); + + } else { + if (clk_get_parent(moutcore) != mout_mpll) { + clk_set_parent(moutcore, mout_mpll); + + do { + tmp = __raw_readl(S5P_CLKMUX_STATCPU); + tmp &= S5P_CLKMUX_STATCPU_MUXCORE_MASK; + } while (tmp != (0x2 << S5P_CLKSRC_CPU_MUXCORE_SHIFT)); + } + } + + /* control regulator */ + if (freqs.new < freqs.old) { + /* Voltage down */ +#ifdef CONFIG_REGULATOR + regulator_set_voltage(arm_regulator, arm_volt, arm_volt); + regulator_set_voltage(int_regulator, int_volt, int_volt); +#endif + } + + cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); + + return 0; +} + +#ifdef CONFIG_PM +static int s5pv310_cpufreq_suspend(struct cpufreq_policy *policy, + pm_message_t pmsg) +{ + return 0; +} + +static int s5pv310_cpufreq_resume(struct cpufreq_policy *policy) +{ + return 0; +} +#endif + +static int s5pv310_cpufreq_cpu_init(struct cpufreq_policy *policy) +{ + policy->cur = policy->min = policy->max = s5pv310_getspeed(policy->cpu); + + cpufreq_frequency_table_get_attr(s5pv310_freq_table, policy->cpu); + + /* set the transition latency value */ + policy->cpuinfo.transition_latency = 100000; + + /* + * S5PV310 multi-core processors has 2 cores + * that the frequency cannot be set independently. + * Each cpu is bound to the same speed. + * So the affected cpu is all of the cpus. + */ + cpumask_setall(policy->cpus); + + return cpufreq_frequency_table_cpuinfo(policy, s5pv310_freq_table); +} + +static struct cpufreq_driver s5pv310_driver = { + .flags = CPUFREQ_STICKY, + .verify = s5pv310_verify_speed, + .target = s5pv310_target, + .get = s5pv310_getspeed, + .init = s5pv310_cpufreq_cpu_init, + .name = "s5pv310_cpufreq", +#ifdef CONFIG_PM + .suspend = s5pv310_cpufreq_suspend, + .resume = s5pv310_cpufreq_resume, +#endif +}; + +static int __init s5pv310_cpufreq_init(void) +{ + unsigned int tmp; + + cpu_clk = clk_get(NULL, "armclk"); + if (IS_ERR(cpu_clk)) + return PTR_ERR(cpu_clk); + + moutcore = clk_get(NULL, "moutcore"); + if (IS_ERR(moutcore)) + goto out; + + mout_mpll = clk_get(NULL, "mout_mpll"); + if (IS_ERR(mout_mpll)) + goto out; + + mout_apll = clk_get(NULL, "mout_apll"); + if (IS_ERR(mout_apll)) + goto out; + +#ifdef CONFIG_REGULATOR + arm_regulator = regulator_get(NULL, "vdd_arm"); + if (IS_ERR(arm_regulator)) { + printk(KERN_ERR "failed to get resource %s\n", "vdd_arm"); + goto out; + } + + int_regulator = regulator_get(NULL, "vdd_int"); + if (IS_ERR(int_regulator)) { + printk(KERN_ERR "failed to get resource %s\n", "vdd_int"); + goto out; + } +#endif + + /* check parent clock of armclk */ + tmp = __raw_readl(S5P_CLKSRC_CPU); + if (tmp & S5P_CLKSRC_CPU_MUXCORE_SHIFT) + armclk_use_apll = 0; + else + armclk_use_apll = 1; + + /* + * Check DRAM type. + * Because DVFS level is different according to DRAM type. + */ + memtype = __raw_readl(S5P_VA_DMC0 + S5P_DMC0_MEMCON_OFFSET); + memtype = (memtype >> S5P_DMC0_MEMTYPE_SHIFT); + memtype &= S5P_DMC0_MEMTYPE_MASK; + + if ((memtype < DDR2) && (memtype > DDR3)) { + printk(KERN_ERR "%s: wrong memtype= 0x%x\n", __func__, memtype); + goto out; + } else { + printk(KERN_DEBUG "%s: memtype= 0x%x\n", __func__, memtype); + } + + return cpufreq_register_driver(&s5pv310_driver); + +out: + if (!IS_ERR(cpu_clk)) + clk_put(cpu_clk); + + if (!IS_ERR(moutcore)) + clk_put(moutcore); + + if (!IS_ERR(mout_mpll)) + clk_put(mout_mpll); + + if (!IS_ERR(mout_apll)) + clk_put(mout_apll); + +#ifdef CONFIG_REGULATOR + if (!IS_ERR(arm_regulator)) + regulator_put(arm_regulator); + + if (!IS_ERR(int_regulator)) + regulator_put(int_regulator); +#endif + + printk(KERN_ERR "%s: failed initialization\n", __func__); + + return -EINVAL; +} +late_initcall(s5pv310_cpufreq_init); -- cgit v1.2.3 From bf5ce054f5ffdb9a2f5556edab07e86acec916ed Mon Sep 17 00:00:00 2001 From: Sangwook Ju Date: Wed, 22 Dec 2010 16:49:32 +0900 Subject: ARM: S5PV310: Update CPUFREQ This patch updates following of CPUFREQ. - Updated DVFS table and divider value - Added common function - Added some function for changing APLL and setting Signed-off-by: Sangwook Ju Reviewed-by: Jaecheol Lee Signed-off-by: Sangbeom Kim Signed-off-by: Kukjin Kim --- arch/arm/mach-s5pv310/cpufreq.c | 301 +++++++++++++++++++++------------------- 1 file changed, 160 insertions(+), 141 deletions(-) diff --git a/arch/arm/mach-s5pv310/cpufreq.c b/arch/arm/mach-s5pv310/cpufreq.c index bcd4ebf93e56..b04cbc731128 100644 --- a/arch/arm/mach-s5pv310/cpufreq.c +++ b/arch/arm/mach-s5pv310/cpufreq.c @@ -24,6 +24,7 @@ #include #include +#include static struct clk *cpu_clk; static struct clk *moutcore; @@ -36,7 +37,6 @@ static struct regulator *int_regulator; #endif static struct cpufreq_freqs freqs; -static unsigned int armclk_use_apll; static unsigned int memtype; enum s5pv310_memory_type { @@ -46,19 +46,18 @@ enum s5pv310_memory_type { }; enum cpufreq_level_index { - L0, L1, L2, L3, L4, CPUFREQ_LEVEL_END, + L0, L1, L2, L3, CPUFREQ_LEVEL_END, }; static struct cpufreq_frequency_table s5pv310_freq_table[] = { {L0, 1000*1000}, {L1, 800*1000}, {L2, 400*1000}, - {L3, 200*1000}, - {L4, 100*1000}, + {L3, 100*1000}, {0, CPUFREQ_TABLE_END}, }; -static unsigned int clkdiv_cpu0[CPUFREQ_LEVEL_END + 1][7] = { +static unsigned int clkdiv_cpu0[CPUFREQ_LEVEL_END][7] = { /* * Clock divider value for following * { DIVCORE, DIVCOREM0, DIVCOREM1, DIVPERIPH, @@ -66,25 +65,38 @@ static unsigned int clkdiv_cpu0[CPUFREQ_LEVEL_END + 1][7] = { */ /* ARM L0: 1000MHz */ - { 0, 3, 7, 3, 3, 0, 0 }, + { 0, 3, 7, 3, 3, 0, 1 }, /* ARM L1: 800MHz */ - { 0, 3, 7, 3, 3, 0, 0 }, + { 0, 3, 7, 3, 3, 0, 1 }, /* ARM L2: 400MHz */ - { 1, 1, 3, 1, 1, 0, 0 }, + { 0, 1, 3, 1, 3, 0, 1 }, - /* ARM L3: 200MHz */ - { 3, 0, 1, 0, 0, 0, 0 }, + /* ARM L3: 100MHz */ + { 0, 0, 1, 0, 3, 1, 1 }, +}; - /* ARM L4A: 100MHz, for DDR2/3 */ - { 7, 0, 1, 0, 0, 0, 0 }, +static unsigned int clkdiv_cpu1[CPUFREQ_LEVEL_END][2] = { + /* + * Clock divider value for following + * { DIVCOPY, DIVHPM } + */ + + /* ARM L0: 1000MHz */ + { 3, 0 }, + + /* ARM L1: 800MHz */ + { 3, 0 }, - /* ARM L4B: 100MHz, for LPDDR2 (SMDKV310 has LPDDR2) */ - { 7, 0, 1, 0, 0, 0, 0 }, + /* ARM L2: 400MHz */ + { 3, 0 }, + + /* ARM L3: 100MHz */ + { 3, 0 }, }; -static unsigned int clkdiv_dmc0[CPUFREQ_LEVEL_END + 1][8] = { +static unsigned int clkdiv_dmc0[CPUFREQ_LEVEL_END][8] = { /* * Clock divider value for following * { DIVACP, DIVACP_PCLK, DIVDPHY, DIVDMC, DIVDMCD @@ -97,20 +109,14 @@ static unsigned int clkdiv_dmc0[CPUFREQ_LEVEL_END + 1][8] = { /* DMC L1: 400MHz */ { 3, 1, 1, 1, 1, 1, 3, 1 }, - /* DMC L2: 400MHz */ - { 3, 1, 1, 1, 1, 1, 3, 1 }, - - /* DMC L3: 400MHz */ - { 3, 1, 1, 1, 1, 1, 3, 1 }, - - /* DMC L4A: 400MHz, for DDR2/3 */ - { 7, 1, 1, 1, 1, 1, 3, 1 }, + /* DMC L2: 266.7MHz */ + { 7, 1, 1, 2, 1, 1, 3, 1 }, - /* DMC L4B: 200MHz, for LPDDR2 */ + /* DMC L3: 200MHz */ { 7, 1, 1, 3, 1, 1, 3, 1 }, }; -static unsigned int clkdiv_top[CPUFREQ_LEVEL_END + 1][5] = { +static unsigned int clkdiv_top[CPUFREQ_LEVEL_END][5] = { /* * Clock divider value for following * { DIVACLK200, DIVACLK100, DIVACLK160, DIVACLK133, DIVONENAND } @@ -122,20 +128,14 @@ static unsigned int clkdiv_top[CPUFREQ_LEVEL_END + 1][5] = { /* ACLK200 L1: 200MHz */ { 3, 7, 4, 5, 1 }, - /* ACLK200 L2: 200MHz */ - { 3, 7, 4, 5, 1 }, - - /* ACLK200 L3: 200MHz */ - { 3, 7, 4, 5, 1 }, - - /* ACLK200 L4A: 100MHz */ - { 7, 7, 7, 7, 1 }, + /* ACLK200 L2: 160MHz */ + { 4, 7, 5, 7, 1 }, - /* ACLK200 L4B: 100MHz */ - { 7, 7, 7, 7, 1 }, + /* ACLK200 L3: 133.3MHz */ + { 5, 7, 7, 7, 1 }, }; -static unsigned int clkdiv_lr_bus[CPUFREQ_LEVEL_END + 1][2] = { +static unsigned int clkdiv_lr_bus[CPUFREQ_LEVEL_END][2] = { /* * Clock divider value for following * { DIVGDL/R, DIVGPL/R } @@ -147,17 +147,11 @@ static unsigned int clkdiv_lr_bus[CPUFREQ_LEVEL_END + 1][2] = { /* ACLK_GDL/R L1: 200MHz */ { 3, 1 }, - /* ACLK_GDL/R L2: 200MHz */ - { 3, 1 }, - - /* ACLK_GDL/R L3: 200MHz */ - { 3, 1 }, + /* ACLK_GDL/R L2: 160MHz */ + { 4, 1 }, - /* ACLK_GDL/R L4A: 100MHz */ - { 7, 1 }, - - /* ACLK_GDL/R L4B: 100MHz */ - { 7, 1 }, + /* ACLK_GDL/R L3: 133.3MHz */ + { 5, 1 }, }; struct cpufreq_voltage_table { @@ -166,7 +160,7 @@ struct cpufreq_voltage_table { unsigned int int_volt; }; -static struct cpufreq_voltage_table s5pv310_volt_table[] = { +static struct cpufreq_voltage_table s5pv310_volt_table[CPUFREQ_LEVEL_END] = { { .index = L0, .arm_volt = 1200000, @@ -177,19 +171,29 @@ static struct cpufreq_voltage_table s5pv310_volt_table[] = { .int_volt = 1100000, }, { .index = L2, - .arm_volt = 1050000, - .int_volt = 1100000, + .arm_volt = 1000000, + .int_volt = 1000000, }, { .index = L3, - .arm_volt = 1050000, - .int_volt = 1100000, - }, { - .index = L4, - .arm_volt = 1000000, + .arm_volt = 900000, .int_volt = 1000000, }, }; +static unsigned int s5pv310_apll_pms_table[CPUFREQ_LEVEL_END] = { + /* APLL FOUT L0: 1000MHz */ + ((250 << 16) | (6 << 8) | 1), + + /* APLL FOUT L1: 800MHz */ + ((200 << 16) | (6 << 8) | 1), + + /* APLL FOUT L2 : 400MHz */ + ((200 << 16) | (6 << 8) | 2), + + /* APLL FOUT L3: 100MHz */ + ((200 << 16) | (6 << 8) | 4), +}; + int s5pv310_verify_speed(struct cpufreq_policy *policy) { return cpufreq_frequency_table_verify(policy, s5pv310_freq_table); @@ -227,6 +231,21 @@ void s5pv310_set_clkdiv(unsigned int div_index) tmp = __raw_readl(S5P_CLKDIV_STATCPU); } while (tmp & 0x1111111); + /* Change Divider - CPU1 */ + + tmp = __raw_readl(S5P_CLKDIV_CPU1); + + tmp &= ~((0x7 << 4) | 0x7); + + tmp |= ((clkdiv_cpu1[div_index][0] << 4) | + (clkdiv_cpu1[div_index][1] << 0)); + + __raw_writel(tmp, S5P_CLKDIV_CPU1); + + do { + tmp = __raw_readl(S5P_CLKDIV_STATCPU1); + } while (tmp & 0x11); + /* Change Divider - DMC0 */ tmp = __raw_readl(S5P_CLKDIV_DMC0); @@ -302,16 +321,100 @@ void s5pv310_set_clkdiv(unsigned int div_index) } while (tmp & 0x11); } +static void s5pv310_set_apll(unsigned int index) +{ + unsigned int tmp; + + /* 1. MUX_CORE_SEL = MPLL, ARMCLK uses MPLL for lock time */ + clk_set_parent(moutcore, mout_mpll); + + do { + tmp = (__raw_readl(S5P_CLKMUX_STATCPU) + >> S5P_CLKSRC_CPU_MUXCORE_SHIFT); + tmp &= 0x7; + } while (tmp != 0x2); + + /* 2. Set APLL Lock time */ + __raw_writel(S5P_APLL_LOCKTIME, S5P_APLL_LOCK); + + /* 3. Change PLL PMS values */ + tmp = __raw_readl(S5P_APLL_CON0); + tmp &= ~((0x3ff << 16) | (0x3f << 8) | (0x7 << 0)); + tmp |= s5pv310_apll_pms_table[index]; + __raw_writel(tmp, S5P_APLL_CON0); + + /* 4. wait_lock_time */ + do { + tmp = __raw_readl(S5P_APLL_CON0); + } while (!(tmp & (0x1 << S5P_APLLCON0_LOCKED_SHIFT))); + + /* 5. MUX_CORE_SEL = APLL */ + clk_set_parent(moutcore, mout_apll); + + do { + tmp = __raw_readl(S5P_CLKMUX_STATCPU); + tmp &= S5P_CLKMUX_STATCPU_MUXCORE_MASK; + } while (tmp != (0x1 << S5P_CLKSRC_CPU_MUXCORE_SHIFT)); +} + +static void s5pv310_set_frequency(unsigned int old_index, unsigned int new_index) +{ + unsigned int tmp; + + if (old_index > new_index) { + /* The frequency changing to L0 needs to change apll */ + if (freqs.new == s5pv310_freq_table[L0].frequency) { + /* 1. Change the system clock divider values */ + s5pv310_set_clkdiv(new_index); + + /* 2. Change the apll m,p,s value */ + s5pv310_set_apll(new_index); + } else { + /* 1. Change the system clock divider values */ + s5pv310_set_clkdiv(new_index); + + /* 2. Change just s value in apll m,p,s value */ + tmp = __raw_readl(S5P_APLL_CON0); + tmp &= ~(0x7 << 0); + tmp |= (s5pv310_apll_pms_table[new_index] & 0x7); + __raw_writel(tmp, S5P_APLL_CON0); + } + } + + else if (old_index < new_index) { + /* The frequency changing from L0 needs to change apll */ + if (freqs.old == s5pv310_freq_table[L0].frequency) { + /* 1. Change the apll m,p,s value */ + s5pv310_set_apll(new_index); + + /* 2. Change the system clock divider values */ + s5pv310_set_clkdiv(new_index); + } else { + /* 1. Change just s value in apll m,p,s value */ + tmp = __raw_readl(S5P_APLL_CON0); + tmp &= ~(0x7 << 0); + tmp |= (s5pv310_apll_pms_table[new_index] & 0x7); + __raw_writel(tmp, S5P_APLL_CON0); + + /* 2. Change the system clock divider values */ + s5pv310_set_clkdiv(new_index); + } + } +} + static int s5pv310_target(struct cpufreq_policy *policy, unsigned int target_freq, unsigned int relation) { - unsigned int index, div_index, tmp; + unsigned int index, old_index; unsigned int arm_volt, int_volt; - unsigned int need_apll = 0; freqs.old = s5pv310_getspeed(policy->cpu); + if (cpufreq_frequency_table_target(policy, s5pv310_freq_table, + freqs.old, relation, &old_index)) + return -EINVAL; + if (cpufreq_frequency_table_target(policy, s5pv310_freq_table, target_freq, relation, &index)) return -EINVAL; @@ -322,19 +425,6 @@ static int s5pv310_target(struct cpufreq_policy *policy, if (freqs.new == freqs.old) return 0; - /* - * If freqs.new is higher than 800MHz - * cpufreq driver should turn on apll - */ - if (index < L1) - need_apll = 1; - - /* If the memory type is LPDDR2, use L4-B instead of L4-A */ - if ((index == L4) && (memtype == LPDDR2)) - div_index = index + 1; - else - div_index = index; - /* get the voltage value */ arm_volt = s5pv310_volt_table[index].arm_volt; int_volt = s5pv310_volt_table[index].int_volt; @@ -351,69 +441,7 @@ static int s5pv310_target(struct cpufreq_policy *policy, } /* Clock Configuration Procedure */ - - /* 1. Change the system clock divider values */ - s5pv310_set_clkdiv(div_index); - - /* 2. Change the divider values for special clocks in CMU_TOP */ - /* currently nothing */ - - /* 3. Change the XPLL values or Select the parent XPLL */ - if (need_apll) { - if (!armclk_use_apll) { - /* - * If the parent clock of armclk isn't apll - * here need to set apll (include m,p,s value) - */ - - /* a. MUX_CORE_SEL = MPLL, - * ARMCLK uses MPLL for lock time */ - clk_set_parent(moutcore, mout_mpll); - - do { - tmp = (__raw_readl(S5P_CLKMUX_STATCPU) - >> S5P_CLKSRC_CPU_MUXCORE_SHIFT); - tmp &= 0x7; - } while (tmp != 0x2); - - /* b. Set APLL Lock time */ - __raw_writel(S5P_APLL_LOCKTIME, S5P_APLL_LOCK); - - /* c. Change PLL PMS values */ - __raw_writel(S5P_APLL_VAL_1000, S5P_APLL_CON0); - - /* d. Turn on a PLL */ - tmp = __raw_readl(S5P_APLL_CON0); - tmp |= (0x1 << S5P_APLLCON0_ENABLE_SHIFT); - __raw_writel(tmp, S5P_APLL_CON0); - - /* e. wait_lock_time */ - do { - tmp = __raw_readl(S5P_APLL_CON0); - } while (!(tmp & (0x1 << S5P_APLLCON0_LOCKED_SHIFT))); - - armclk_use_apll = 1; - - } - - /* MUX_CORE_SEL = APLL */ - clk_set_parent(moutcore, mout_apll); - - do { - tmp = __raw_readl(S5P_CLKMUX_STATCPU); - tmp &= S5P_CLKMUX_STATCPU_MUXCORE_MASK; - } while (tmp != (0x1 << S5P_CLKSRC_CPU_MUXCORE_SHIFT)); - - } else { - if (clk_get_parent(moutcore) != mout_mpll) { - clk_set_parent(moutcore, mout_mpll); - - do { - tmp = __raw_readl(S5P_CLKMUX_STATCPU); - tmp &= S5P_CLKMUX_STATCPU_MUXCORE_MASK; - } while (tmp != (0x2 << S5P_CLKSRC_CPU_MUXCORE_SHIFT)); - } - } + s5pv310_set_frequency(old_index, index); /* control regulator */ if (freqs.new < freqs.old) { @@ -477,8 +505,6 @@ static struct cpufreq_driver s5pv310_driver = { static int __init s5pv310_cpufreq_init(void) { - unsigned int tmp; - cpu_clk = clk_get(NULL, "armclk"); if (IS_ERR(cpu_clk)) return PTR_ERR(cpu_clk); @@ -509,13 +535,6 @@ static int __init s5pv310_cpufreq_init(void) } #endif - /* check parent clock of armclk */ - tmp = __raw_readl(S5P_CLKSRC_CPU); - if (tmp & S5P_CLKSRC_CPU_MUXCORE_SHIFT) - armclk_use_apll = 0; - else - armclk_use_apll = 1; - /* * Check DRAM type. * Because DVFS level is different according to DRAM type. -- cgit v1.2.3 From 877d1b571d7763dbf57e38de2827177ad5369e64 Mon Sep 17 00:00:00 2001 From: Jaecheol Lee Date: Thu, 23 Dec 2010 14:25:31 +0900 Subject: ARM: S5PV310: Add FOUT APLL get rate function FOUT APLL clock is used as a source of ARM core clock. So we need that the clock source can be changed dynamically by using CPUFREQ driver. This patch can give correct frequency when calling clk_get_rate() function. Signed-off-by: Jaecheol Lee Signed-off-by: Sangwook Ju Signed-off-by: Kukjin Kim --- arch/arm/mach-s5pv310/clock.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-s5pv310/clock.c b/arch/arm/mach-s5pv310/clock.c index fdce2b48efc6..752a07ed7c19 100644 --- a/arch/arm/mach-s5pv310/clock.c +++ b/arch/arm/mach-s5pv310/clock.c @@ -990,6 +990,17 @@ static struct clksrc_clk *sysclks[] = { &clk_dout_mmc4, }; +static int xtal_rate; + +static unsigned long s5pv310_fout_apll_get_rate(struct clk *clk) +{ + return s5p_get_pll45xx(xtal_rate, __raw_readl(S5P_APLL_CON0), pll_4508); +} + +static struct clk_ops s5pv310_fout_apll_ops = { + .get_rate = s5pv310_fout_apll_get_rate, +}; + void __init_or_cpufreq s5pv310_setup_clocks(void) { struct clk *xtal_clk; @@ -1013,6 +1024,9 @@ void __init_or_cpufreq s5pv310_setup_clocks(void) BUG_ON(IS_ERR(xtal_clk)); xtal = clk_get_rate(xtal_clk); + + xtal_rate = xtal; + clk_put(xtal_clk); printk(KERN_DEBUG "%s: xtal is %ld\n", __func__, xtal); @@ -1026,7 +1040,7 @@ void __init_or_cpufreq s5pv310_setup_clocks(void) vpll = s5p_get_pll46xx(vpllsrc, __raw_readl(S5P_VPLL_CON0), __raw_readl(S5P_VPLL_CON1), pll_4650); - clk_fout_apll.rate = apll; + clk_fout_apll.ops = &s5pv310_fout_apll_ops; clk_fout_mpll.rate = mpll; clk_fout_epll.rate = epll; clk_fout_vpll.rate = vpll; -- cgit v1.2.3 From b333fb16dcc50541df1930addea3eac03c838a4c Mon Sep 17 00:00:00 2001 From: Sunyoung Kang Date: Thu, 16 Sep 2010 11:11:45 +0900 Subject: ARM: S5PV310: Update Kconfig and Makefile for supporting CPUFREQ This patch adds ARCH_HAS_CPUFREQ in Kconfig of ARCH_S5PV310 and updates Makefile for supporting build S5PV310 CPUFREQ driver. Signed-off-by: Sunyoung Kang Signed-off-by: Kukjin Kim --- arch/arm/Kconfig | 1 + arch/arm/mach-s5pv310/Makefile | 1 + 2 files changed, 2 insertions(+) diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index d56d21c0573b..5ecaec63a47b 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -738,6 +738,7 @@ config ARCH_S5PV310 select ARCH_SPARSEMEM_ENABLE select GENERIC_GPIO select HAVE_CLK + select ARCH_HAS_CPUFREQ select GENERIC_CLOCKEVENTS select HAVE_S3C_RTC if RTC_CLASS select HAVE_S3C2410_I2C if I2C diff --git a/arch/arm/mach-s5pv310/Makefile b/arch/arm/mach-s5pv310/Makefile index 84afc64e7c01..6a8a1ef00c3a 100644 --- a/arch/arm/mach-s5pv310/Makefile +++ b/arch/arm/mach-s5pv310/Makefile @@ -14,6 +14,7 @@ obj- := obj-$(CONFIG_CPU_S5PV310) += cpu.o init.o clock.o irq-combiner.o obj-$(CONFIG_CPU_S5PV310) += setup-i2c0.o time.o gpiolib.o irq-eint.o +obj-$(CONFIG_CPU_FREQ) += cpufreq.o obj-$(CONFIG_SMP) += platsmp.o headsmp.o obj-$(CONFIG_LOCAL_TIMERS) += localtimer.o -- cgit v1.2.3 From d4686c654bb1d7ea226578d5725ca34911d6e34c Mon Sep 17 00:00:00 2001 From: Jorge Eduardo Candelaria Date: Mon, 20 Dec 2010 11:32:47 -0600 Subject: ASoC: mcbsp: Add McBSP support for OMAP4 This patch adds McBSP support for the OMAP4 CPU Signed-off-by: Jorge Eduardo Candelaria Signed-off-by: Margarita Olaya Cabrera Acked-by: Mark Brown Acked-by: Peter Ujfalusi Acked-by: Jarkko Nikula Signed-off-by: Liam Girdwood --- sound/soc/omap/omap-mcbsp.c | 35 ++++++++++++++++++++++++++++++++--- sound/soc/omap/omap-mcbsp.h | 4 ++++ 2 files changed, 36 insertions(+), 3 deletions(-) diff --git a/sound/soc/omap/omap-mcbsp.c b/sound/soc/omap/omap-mcbsp.c index 7e84f24b9a88..d203f4da18a0 100644 --- a/sound/soc/omap/omap-mcbsp.c +++ b/sound/soc/omap/omap-mcbsp.c @@ -102,6 +102,17 @@ static const int omap24xx_dma_reqs[][2] = { static const int omap24xx_dma_reqs[][2] = {}; #endif +#if defined(CONFIG_ARCH_OMAP4) +static const int omap44xx_dma_reqs[][2] = { + { OMAP44XX_DMA_MCBSP1_TX, OMAP44XX_DMA_MCBSP1_RX }, + { OMAP44XX_DMA_MCBSP2_TX, OMAP44XX_DMA_MCBSP2_RX }, + { OMAP44XX_DMA_MCBSP3_TX, OMAP44XX_DMA_MCBSP3_RX }, + { OMAP44XX_DMA_MCBSP4_TX, OMAP44XX_DMA_MCBSP4_RX }, +}; +#else +static const int omap44xx_dma_reqs[][2] = {}; +#endif + #if defined(CONFIG_ARCH_OMAP2420) static const unsigned long omap2420_mcbsp_port[][2] = { { OMAP24XX_MCBSP1_BASE + OMAP_MCBSP_REG_DXR1, @@ -147,6 +158,21 @@ static const unsigned long omap34xx_mcbsp_port[][2] = { static const unsigned long omap34xx_mcbsp_port[][2] = {}; #endif +#if defined(CONFIG_ARCH_OMAP4) +static const unsigned long omap44xx_mcbsp_port[][2] = { + { OMAP44XX_MCBSP1_BASE + OMAP_MCBSP_REG_DXR, + OMAP44XX_MCBSP1_BASE + OMAP_MCBSP_REG_DRR }, + { OMAP44XX_MCBSP2_BASE + OMAP_MCBSP_REG_DXR, + OMAP44XX_MCBSP2_BASE + OMAP_MCBSP_REG_DRR }, + { OMAP44XX_MCBSP3_BASE + OMAP_MCBSP_REG_DXR, + OMAP44XX_MCBSP3_BASE + OMAP_MCBSP_REG_DRR }, + { OMAP44XX_MCBSP4_BASE + OMAP_MCBSP_REG_DXR, + OMAP44XX_MCBSP4_BASE + OMAP_MCBSP_REG_DRR }, +}; +#else +static const unsigned long omap44xx_mcbsp_port[][2] = {}; +#endif + static void omap_mcbsp_set_threshold(struct snd_pcm_substream *substream) { struct snd_soc_pcm_runtime *rtd = substream->private_data; @@ -224,7 +250,7 @@ static int omap_mcbsp_dai_startup(struct snd_pcm_substream *substream, * 2 channels (stereo): size is 128 / 2 = 64 frames (2 * 64 words) * 4 channels: size is 128 / 4 = 32 frames (4 * 32 words) */ - if (cpu_is_omap343x()) { + if (cpu_is_omap343x() || cpu_is_omap44xx()) { /* * Rule for the buffer size. We should not allow * smaller buffer than the FIFO size to avoid underruns @@ -332,6 +358,9 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream, } else if (cpu_is_omap343x()) { dma = omap24xx_dma_reqs[bus_id][substream->stream]; port = omap34xx_mcbsp_port[bus_id][substream->stream]; + } else if (cpu_is_omap44xx()) { + dma = omap44xx_dma_reqs[bus_id][substream->stream]; + port = omap44xx_mcbsp_port[bus_id][substream->stream]; } else { return -ENODEV; } @@ -498,11 +527,11 @@ static int omap_mcbsp_dai_set_dai_fmt(struct snd_soc_dai *cpu_dai, regs->spcr2 |= XINTM(3) | FREE; regs->spcr1 |= RINTM(3); /* RFIG and XFIG are not defined in 34xx */ - if (!cpu_is_omap34xx()) { + if (!cpu_is_omap34xx() && !cpu_is_omap44xx()) { regs->rcr2 |= RFIG; regs->xcr2 |= XFIG; } - if (cpu_is_omap2430() || cpu_is_omap34xx()) { + if (cpu_is_omap2430() || cpu_is_omap34xx() || cpu_is_omap44xx()) { regs->xccr = DXENDLY(1) | XDMAEN | XDISABLE; regs->rccr = RFULL_CYCLE | RDMAEN | RDISABLE; } diff --git a/sound/soc/omap/omap-mcbsp.h b/sound/soc/omap/omap-mcbsp.h index ffdcc5abb7b9..110c106611d3 100644 --- a/sound/soc/omap/omap-mcbsp.h +++ b/sound/soc/omap/omap-mcbsp.h @@ -50,6 +50,10 @@ enum omap_mcbsp_div { #undef NUM_LINKS #define NUM_LINKS 3 #endif +#if defined(CONFIG_ARCH_OMAP4) +#undef NUM_LINKS +#define NUM_LINKS 4 +#endif #if defined(CONFIG_ARCH_OMAP2430) || defined(CONFIG_ARCH_OMAP3) #undef NUM_LINKS #define NUM_LINKS 5 -- cgit v1.2.3 From f769bdf2a7ee97c8e762fc133ff00aabe935867b Mon Sep 17 00:00:00 2001 From: "Olaya, Margarita" Date: Mon, 20 Dec 2010 10:39:20 -0600 Subject: ASoC: twl6040: Convert HF and HS drivers to use DAPM OUT_DRV widget Make the phoenix HS and HF drivers use the new DAPM driver widget in order to guarantee power ON/OFF order sequence. Signed-off-by: Margarita Olaya Cabrera Acked-by: Mark Brown Signed-off-by: Liam Girdwood --- sound/soc/codecs/twl6040.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sound/soc/codecs/twl6040.c b/sound/soc/codecs/twl6040.c index 2f68f5949a63..4bbf1b15a493 100644 --- a/sound/soc/codecs/twl6040.c +++ b/sound/soc/codecs/twl6040.c @@ -1138,19 +1138,19 @@ static const struct snd_soc_dapm_widget twl6040_dapm_widgets[] = { SND_SOC_NOPM, 0, 0, &hsr_mux_controls), /* Analog playback drivers */ - SND_SOC_DAPM_PGA_E("Handsfree Left Driver", + SND_SOC_DAPM_OUT_DRV_E("Handsfree Left Driver", TWL6040_REG_HFLCTL, 4, 0, NULL, 0, pga_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), - SND_SOC_DAPM_PGA_E("Handsfree Right Driver", + SND_SOC_DAPM_OUT_DRV_E("Handsfree Right Driver", TWL6040_REG_HFRCTL, 4, 0, NULL, 0, pga_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), - SND_SOC_DAPM_PGA_E("Headset Left Driver", + SND_SOC_DAPM_OUT_DRV_E("Headset Left Driver", TWL6040_REG_HSLCTL, 2, 0, NULL, 0, pga_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), - SND_SOC_DAPM_PGA_E("Headset Right Driver", + SND_SOC_DAPM_OUT_DRV_E("Headset Right Driver", TWL6040_REG_HSRCTL, 2, 0, NULL, 0, pga_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD), -- cgit v1.2.3 From 3591f4cd53a3835e6d59dd509337503c2c61173e Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Wed, 22 Dec 2010 10:45:16 +0200 Subject: ASoC: tlv320dac33: Remove manual FIFO configuration The manual FIFO configuration was the first version to enable the use of the FIFO in the codec. It had served it's purpose as debugging aid, but the automatic FIFO configuration is much safer to use. The removal of the manual controls, and configuration makes it easier to add new features for the codec later, since the manual mode neded different ways to calculate, and protect against misconfiguration. Signed-off-by: Peter Ujfalusi Acked-by: Mark Brown Signed-off-by: Liam Girdwood --- sound/soc/codecs/tlv320dac33.c | 157 ++++++----------------------------------- 1 file changed, 20 insertions(+), 137 deletions(-) diff --git a/sound/soc/codecs/tlv320dac33.c b/sound/soc/codecs/tlv320dac33.c index 776ac80cc1a8..c574ae238973 100644 --- a/sound/soc/codecs/tlv320dac33.c +++ b/sound/soc/codecs/tlv320dac33.c @@ -46,8 +46,6 @@ * 6144 stereo */ #define DAC33_BUFFER_SIZE_SAMPLES 6144 -#define NSAMPLE_MAX 5700 - #define MODE7_LTHR 10 #define MODE7_UTHR (DAC33_BUFFER_SIZE_SAMPLES - 10) @@ -99,16 +97,10 @@ struct tlv320dac33_priv { unsigned int refclk; unsigned int alarm_threshold; /* set to be half of LATENCY_TIME_MS */ - unsigned int nsample_min; /* nsample should not be lower than - * this */ - unsigned int nsample_max; /* nsample should not be higher than - * this */ enum dac33_fifo_modes fifo_mode;/* FIFO mode selection */ unsigned int nsample; /* burst read amount from host */ int mode1_latency; /* latency caused by the i2c writes in * us */ - int auto_fifo_config; /* Configure the FIFO based on the - * period size */ u8 burst_bclkdiv; /* BCLK divider value in burst mode */ unsigned int burst_rate; /* Interface speed in Burst modes */ @@ -436,73 +428,6 @@ static int dac33_playback_event(struct snd_soc_dapm_widget *w, return 0; } -static int dac33_get_nsample(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec); - - ucontrol->value.integer.value[0] = dac33->nsample; - - return 0; -} - -static int dac33_set_nsample(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec); - int ret = 0; - - if (dac33->nsample == ucontrol->value.integer.value[0]) - return 0; - - if (ucontrol->value.integer.value[0] < dac33->nsample_min || - ucontrol->value.integer.value[0] > dac33->nsample_max) { - ret = -EINVAL; - } else { - dac33->nsample = ucontrol->value.integer.value[0]; - /* Re calculate the burst time */ - dac33->mode1_us_burst = SAMPLES_TO_US(dac33->burst_rate, - dac33->nsample); - } - - return ret; -} - -static int dac33_get_uthr(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec); - - ucontrol->value.integer.value[0] = dac33->uthr; - - return 0; -} - -static int dac33_set_uthr(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec); - int ret = 0; - - if (dac33->substream) - return -EBUSY; - - if (dac33->uthr == ucontrol->value.integer.value[0]) - return 0; - - if (ucontrol->value.integer.value[0] < (MODE7_LTHR + 10) || - ucontrol->value.integer.value[0] > MODE7_UTHR) - ret = -EINVAL; - else - dac33->uthr = ucontrol->value.integer.value[0]; - - return ret; -} - static int dac33_get_fifo_mode(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -587,13 +512,6 @@ static const struct snd_kcontrol_new dac33_mode_snd_controls[] = { dac33_get_fifo_mode, dac33_set_fifo_mode), }; -static const struct snd_kcontrol_new dac33_fifo_snd_controls[] = { - SOC_SINGLE_EXT("nSample", 0, 0, 5900, 0, - dac33_get_nsample, dac33_set_nsample), - SOC_SINGLE_EXT("UTHR", 0, 0, MODE7_UTHR, 0, - dac33_get_uthr, dac33_set_uthr), -}; - /* Analog bypass */ static const struct snd_kcontrol_new dac33_dapm_abypassl_control = SOC_DAPM_SINGLE("Switch", DAC33_LINEL_TO_LLO_VOL, 7, 1, 1); @@ -853,10 +771,6 @@ static void dac33_shutdown(struct snd_pcm_substream *substream, struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec); dac33->substream = NULL; - - /* Reset the nSample restrictions */ - dac33->nsample_min = 0; - dac33->nsample_max = NSAMPLE_MAX; } static int dac33_hw_params(struct snd_pcm_substream *substream, @@ -1112,39 +1026,19 @@ static void dac33_calculate_times(struct snd_pcm_substream *substream) nsample_limit = DAC33_BUFFER_SIZE_SAMPLES - dac33->alarm_threshold; - if (dac33->auto_fifo_config) { - if (period_size <= dac33->alarm_threshold) - /* - * Configure nSamaple to number of periods, - * which covers the latency requironment. - */ - dac33->nsample = period_size * - ((dac33->alarm_threshold / period_size) + - (dac33->alarm_threshold % period_size ? - 1 : 0)); - else if (period_size > nsample_limit) - dac33->nsample = nsample_limit; - else - dac33->nsample = period_size; - } else { - /* nSample time shall not be shorter than i2c latency */ - dac33->nsample_min = dac33->alarm_threshold; + if (period_size <= dac33->alarm_threshold) /* - * nSample should not be bigger than alsa buffer minus - * size of one period to avoid overruns + * Configure nSamaple to number of periods, + * which covers the latency requironment. */ - dac33->nsample_max = substream->runtime->buffer_size - - period_size; - - if (dac33->nsample_max > nsample_limit) - dac33->nsample_max = nsample_limit; - - /* Correct the nSample if it is outside of the ranges */ - if (dac33->nsample < dac33->nsample_min) - dac33->nsample = dac33->nsample_min; - if (dac33->nsample > dac33->nsample_max) - dac33->nsample = dac33->nsample_max; - } + dac33->nsample = period_size * + ((dac33->alarm_threshold / period_size) + + (dac33->alarm_threshold % period_size ? + 1 : 0)); + else if (period_size > nsample_limit) + dac33->nsample = nsample_limit; + else + dac33->nsample = period_size; dac33->mode1_us_burst = SAMPLES_TO_US(dac33->burst_rate, dac33->nsample); @@ -1152,16 +1046,13 @@ static void dac33_calculate_times(struct snd_pcm_substream *substream) dac33->t_stamp2 = 0; break; case DAC33_FIFO_MODE7: - if (dac33->auto_fifo_config) { - dac33->uthr = UTHR_FROM_PERIOD_SIZE( - period_size, - rate, - dac33->burst_rate) + 9; - if (dac33->uthr > MODE7_UTHR) - dac33->uthr = MODE7_UTHR; - if (dac33->uthr < (MODE7_LTHR + 10)) - dac33->uthr = (MODE7_LTHR + 10); - } + dac33->uthr = UTHR_FROM_PERIOD_SIZE(period_size, rate, + dac33->burst_rate) + 9; + if (dac33->uthr > MODE7_UTHR) + dac33->uthr = MODE7_UTHR; + if (dac33->uthr < (MODE7_LTHR + 10)) + dac33->uthr = (MODE7_LTHR + 10); + dac33->mode7_us_to_lthr = SAMPLES_TO_US(substream->runtime->rate, dac33->uthr - MODE7_LTHR + 1); @@ -1486,14 +1377,10 @@ static int dac33_soc_probe(struct snd_soc_codec *codec) snd_soc_add_controls(codec, dac33_snd_controls, ARRAY_SIZE(dac33_snd_controls)); /* Only add the FIFO controls, if we have valid IRQ number */ - if (dac33->irq >= 0) { + if (dac33->irq >= 0) snd_soc_add_controls(codec, dac33_mode_snd_controls, ARRAY_SIZE(dac33_mode_snd_controls)); - /* FIFO usage controls only, if autoio config is not selected */ - if (!dac33->auto_fifo_config) - snd_soc_add_controls(codec, dac33_fifo_snd_controls, - ARRAY_SIZE(dac33_fifo_snd_controls)); - } + dac33_add_widgets(codec); err_power: @@ -1593,14 +1480,10 @@ static int __devinit dac33_i2c_probe(struct i2c_client *client, /* Pre calculate the burst rate */ dac33->burst_rate = BURST_BASEFREQ_HZ / dac33->burst_bclkdiv / 32; dac33->keep_bclk = pdata->keep_bclk; - dac33->auto_fifo_config = pdata->auto_fifo_config; dac33->mode1_latency = pdata->mode1_latency; if (!dac33->mode1_latency) dac33->mode1_latency = 10000; /* 10ms */ dac33->irq = client->irq; - dac33->nsample = NSAMPLE_MAX; - dac33->nsample_max = NSAMPLE_MAX; - dac33->uthr = MODE7_UTHR; /* Disable FIFO use by default */ dac33->fifo_mode = DAC33_FIFO_BYPASS; -- cgit v1.2.3 From 549675ed658761b9a84cb579795c9ec1da227fea Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Wed, 22 Dec 2010 10:45:17 +0200 Subject: ASoC: tlv320dac33: Some cleanup for 32/24 bit support Change the structure of FIFO handling in order to pave the way for adding 32/24 bit audio support. Signed-off-by: Peter Ujfalusi Acked-by: Mark Brown Signed-off-by: Liam Girdwood --- sound/soc/codecs/tlv320dac33.c | 47 ++++++++++++++++++++++++------------------ 1 file changed, 27 insertions(+), 20 deletions(-) diff --git a/sound/soc/codecs/tlv320dac33.c b/sound/soc/codecs/tlv320dac33.c index c574ae238973..05a4e9fade47 100644 --- a/sound/soc/codecs/tlv320dac33.c +++ b/sound/soc/codecs/tlv320dac33.c @@ -42,12 +42,15 @@ #include #include "tlv320dac33.h" -#define DAC33_BUFFER_SIZE_BYTES 24576 /* bytes, 12288 16 bit words, - * 6144 stereo */ -#define DAC33_BUFFER_SIZE_SAMPLES 6144 - -#define MODE7_LTHR 10 -#define MODE7_UTHR (DAC33_BUFFER_SIZE_SAMPLES - 10) +/* + * The internal FIFO is 24576 bytes long + * It can be configured to hold 16bit or 24bit samples + * In 16bit configuration the FIFO can hold 6144 stereo samples + * In 24bit configuration the FIFO can hold 4096 stereo samples + */ +#define DAC33_FIFO_SIZE_16BIT 6144 +#define DAC33_FIFO_SIZE_24BIT 4096 +#define DAC33_MODE7_MARGIN 10 /* Safety margin for FIFO in Mode7 */ #define BURST_BASEFREQ_HZ 49152000 @@ -98,6 +101,7 @@ struct tlv320dac33_priv { unsigned int alarm_threshold; /* set to be half of LATENCY_TIME_MS */ enum dac33_fifo_modes fifo_mode;/* FIFO mode selection */ + unsigned int fifo_size; /* Size of the FIFO in samples */ unsigned int nsample; /* burst read amount from host */ int mode1_latency; /* latency caused by the i2c writes in * us */ @@ -650,7 +654,7 @@ static inline void dac33_prefill_handler(struct tlv320dac33_priv *dac33) spin_unlock_irq(&dac33->lock); dac33_write16(codec, DAC33_PREFILL_MSB, - DAC33_THRREG(MODE7_LTHR)); + DAC33_THRREG(DAC33_MODE7_MARGIN)); /* Enable Upper Threshold IRQ */ dac33_write(codec, DAC33_FIFO_IRQ_MASK, DAC33_MUT); @@ -773,12 +777,15 @@ static void dac33_shutdown(struct snd_pcm_substream *substream, dac33->substream = NULL; } +#define CALC_BURST_RATE(bclkdiv, bclk_per_sample) \ + (BURST_BASEFREQ_HZ / bclkdiv / bclk_per_sample) static int dac33_hw_params(struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params, struct snd_soc_dai *dai) { struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_codec *codec = rtd->codec; + struct tlv320dac33_priv *dac33 = snd_soc_codec_get_drvdata(codec); /* Check parameters for validity */ switch (params_rate(params)) { @@ -793,6 +800,8 @@ static int dac33_hw_params(struct snd_pcm_substream *substream, switch (params_format(params)) { case SNDRV_PCM_FORMAT_S16_LE: + dac33->fifo_size = DAC33_FIFO_SIZE_16BIT; + dac33->burst_rate = CALC_BURST_RATE(dac33->burst_bclkdiv, 32); break; default: dev_err(codec->dev, "unsupported format %d\n", @@ -994,7 +1003,8 @@ static int dac33_prepare_chip(struct snd_pcm_substream *substream) * at the bottom, and also at the top of the FIFO */ dac33_write16(codec, DAC33_UTHR_MSB, DAC33_THRREG(dac33->uthr)); - dac33_write16(codec, DAC33_LTHR_MSB, DAC33_THRREG(MODE7_LTHR)); + dac33_write16(codec, DAC33_LTHR_MSB, + DAC33_THRREG(DAC33_MODE7_MARGIN)); break; default: break; @@ -1023,8 +1033,7 @@ static void dac33_calculate_times(struct snd_pcm_substream *substream) /* Number of samples under i2c latency */ dac33->alarm_threshold = US_TO_SAMPLES(rate, dac33->mode1_latency); - nsample_limit = DAC33_BUFFER_SIZE_SAMPLES - - dac33->alarm_threshold; + nsample_limit = dac33->fifo_size - dac33->alarm_threshold; if (period_size <= dac33->alarm_threshold) /* @@ -1048,14 +1057,14 @@ static void dac33_calculate_times(struct snd_pcm_substream *substream) case DAC33_FIFO_MODE7: dac33->uthr = UTHR_FROM_PERIOD_SIZE(period_size, rate, dac33->burst_rate) + 9; - if (dac33->uthr > MODE7_UTHR) - dac33->uthr = MODE7_UTHR; - if (dac33->uthr < (MODE7_LTHR + 10)) - dac33->uthr = (MODE7_LTHR + 10); + if (dac33->uthr > (dac33->fifo_size - DAC33_MODE7_MARGIN)) + dac33->uthr = dac33->fifo_size - DAC33_MODE7_MARGIN; + if (dac33->uthr < (DAC33_MODE7_MARGIN + 10)) + dac33->uthr = (DAC33_MODE7_MARGIN + 10); dac33->mode7_us_to_lthr = SAMPLES_TO_US(substream->runtime->rate, - dac33->uthr - MODE7_LTHR + 1); + dac33->uthr - DAC33_MODE7_MARGIN + 1); dac33->t_stamp1 = 0; break; default: @@ -1173,8 +1182,8 @@ static snd_pcm_sframes_t dac33_dai_delay( samples += (samples_in - samples_out); if (likely(samples > 0)) - delay = samples > DAC33_BUFFER_SIZE_SAMPLES ? - DAC33_BUFFER_SIZE_SAMPLES : samples; + delay = samples > dac33->fifo_size ? + dac33->fifo_size : samples; else delay = 0; } @@ -1226,7 +1235,7 @@ static snd_pcm_sframes_t dac33_dai_delay( samples_in = US_TO_SAMPLES( dac33->burst_rate, time_delta); - delay = MODE7_LTHR + samples_in - samples_out; + delay = DAC33_MODE7_MARGIN + samples_in - samples_out; if (unlikely(delay > uthr)) delay = uthr; @@ -1477,8 +1486,6 @@ static int __devinit dac33_i2c_probe(struct i2c_client *client, dac33->power_gpio = pdata->power_gpio; dac33->burst_bclkdiv = pdata->burst_bclkdiv; - /* Pre calculate the burst rate */ - dac33->burst_rate = BURST_BASEFREQ_HZ / dac33->burst_bclkdiv / 32; dac33->keep_bclk = pdata->keep_bclk; dac33->mode1_latency = pdata->mode1_latency; if (!dac33->mode1_latency) -- cgit v1.2.3 From 0d99d2b036974ed1160f9d10457b6054646fb7d6 Mon Sep 17 00:00:00 2001 From: Peter Ujfalusi Date: Wed, 22 Dec 2010 10:45:18 +0200 Subject: ASoC: tlv320dac33: Add 32/24 bit audio support Add support for 24 bit audio (with S32_LE msbits 24). The reason to limit the msbits to 24, is that the FIFO can be configured for 16 or 24 bit layout. It is unknown how the codec would downsample from 32 to 24 bit, if the interface is configured to receive 32 bit data. Signed-off-by: Peter Ujfalusi Acked-by: Mark Brown Signed-off-by: Liam Girdwood --- sound/soc/codecs/tlv320dac33.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/sound/soc/codecs/tlv320dac33.c b/sound/soc/codecs/tlv320dac33.c index 05a4e9fade47..13d521cfe393 100644 --- a/sound/soc/codecs/tlv320dac33.c +++ b/sound/soc/codecs/tlv320dac33.c @@ -764,6 +764,8 @@ static int dac33_startup(struct snd_pcm_substream *substream, /* Stream started, save the substream pointer */ dac33->substream = substream; + snd_pcm_hw_constraint_msbits(substream->runtime, 0, 32, 24); + return 0; } @@ -803,6 +805,10 @@ static int dac33_hw_params(struct snd_pcm_substream *substream, dac33->fifo_size = DAC33_FIFO_SIZE_16BIT; dac33->burst_rate = CALC_BURST_RATE(dac33->burst_bclkdiv, 32); break; + case SNDRV_PCM_FORMAT_S32_LE: + dac33->fifo_size = DAC33_FIFO_SIZE_24BIT; + dac33->burst_rate = CALC_BURST_RATE(dac33->burst_bclkdiv, 64); + break; default: dev_err(codec->dev, "unsupported format %d\n", params_format(params)); @@ -856,6 +862,9 @@ static int dac33_prepare_chip(struct snd_pcm_substream *substream) aictrl_a |= (DAC33_NCYCL_16 | DAC33_WLEN_16); fifoctrl_a |= DAC33_WIDTH; break; + case SNDRV_PCM_FORMAT_S32_LE: + aictrl_a |= (DAC33_NCYCL_32 | DAC33_WLEN_24); + break; default: dev_err(codec->dev, "unsupported format %d\n", substream->runtime->format); @@ -990,7 +999,10 @@ static int dac33_prepare_chip(struct snd_pcm_substream *substream) dac33_write(codec, DAC33_SER_AUDIOIF_CTRL_C, dac33->burst_bclkdiv); else - dac33_write(codec, DAC33_SER_AUDIOIF_CTRL_C, 32); + if (substream->runtime->format == SNDRV_PCM_FORMAT_S16_LE) + dac33_write(codec, DAC33_SER_AUDIOIF_CTRL_C, 32); + else + dac33_write(codec, DAC33_SER_AUDIOIF_CTRL_C, 16); switch (dac33->fifo_mode) { case DAC33_FIFO_MODE1: @@ -1438,7 +1450,7 @@ static struct snd_soc_codec_driver soc_codec_dev_tlv320dac33 = { #define DAC33_RATES (SNDRV_PCM_RATE_44100 | \ SNDRV_PCM_RATE_48000) -#define DAC33_FORMATS SNDRV_PCM_FMTBIT_S16_LE +#define DAC33_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE) static struct snd_soc_dai_ops dac33_dai_ops = { .startup = dac33_startup, -- cgit v1.2.3 From 00aaaef9a51a1a25c5d6d52ce510772f149a0eb0 Mon Sep 17 00:00:00 2001 From: Sheng Yang Date: Thu, 11 Nov 2010 15:46:54 +0800 Subject: PCI: MSI: Move MSI-X entry definition to pci_regs.h Then it can be used by others. Reviewed-by: Hidetoshi Seto Reviewed-by: Matthew Wilcox Signed-off-by: Sheng Yang Signed-off-by: Jesse Barnes --- drivers/pci/msi.h | 6 ------ include/linux/pci_regs.h | 7 +++++++ 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/drivers/pci/msi.h b/drivers/pci/msi.h index feff3bee6fe5..65c42f80f23e 100644 --- a/drivers/pci/msi.h +++ b/drivers/pci/msi.h @@ -6,12 +6,6 @@ #ifndef MSI_H #define MSI_H -#define PCI_MSIX_ENTRY_SIZE 16 -#define PCI_MSIX_ENTRY_LOWER_ADDR 0 -#define PCI_MSIX_ENTRY_UPPER_ADDR 4 -#define PCI_MSIX_ENTRY_DATA 8 -#define PCI_MSIX_ENTRY_VECTOR_CTRL 12 - #define msi_control_reg(base) (base + PCI_MSI_FLAGS) #define msi_lower_address_reg(base) (base + PCI_MSI_ADDRESS_LO) #define msi_upper_address_reg(base) (base + PCI_MSI_ADDRESS_HI) diff --git a/include/linux/pci_regs.h b/include/linux/pci_regs.h index af83076c31a6..b21d33e4bc2a 100644 --- a/include/linux/pci_regs.h +++ b/include/linux/pci_regs.h @@ -309,6 +309,13 @@ #define PCI_MSIX_PBA 8 #define PCI_MSIX_FLAGS_BIRMASK (7 << 0) +/* MSI-X entry's format */ +#define PCI_MSIX_ENTRY_SIZE 16 +#define PCI_MSIX_ENTRY_LOWER_ADDR 0 +#define PCI_MSIX_ENTRY_UPPER_ADDR 4 +#define PCI_MSIX_ENTRY_DATA 8 +#define PCI_MSIX_ENTRY_VECTOR_CTRL 12 + /* CompactPCI Hotswap Register */ #define PCI_CHSWP_CSR 2 /* Control and Status Register */ -- cgit v1.2.3 From 8d805286968811223cca002134ba3d81244d5313 Mon Sep 17 00:00:00 2001 From: Sheng Yang Date: Thu, 11 Nov 2010 15:46:55 +0800 Subject: PCI: Add mask bit definition for MSI-X table Then we can use it instead of magic number 1. Reviewed-by: Hidetoshi Seto Cc: Matthew Wilcox Signed-off-by: Sheng Yang Signed-off-by: Jesse Barnes --- drivers/pci/msi.c | 5 +++-- include/linux/pci_regs.h | 1 + 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index 7c24dcef2989..44b0aeee83e5 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c @@ -168,8 +168,9 @@ static u32 __msix_mask_irq(struct msi_desc *desc, u32 flag) u32 mask_bits = desc->masked; unsigned offset = desc->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE + PCI_MSIX_ENTRY_VECTOR_CTRL; - mask_bits &= ~1; - mask_bits |= flag; + mask_bits &= ~PCI_MSIX_ENTRY_CTRL_MASKBIT; + if (flag) + mask_bits |= PCI_MSIX_ENTRY_CTRL_MASKBIT; writel(mask_bits, desc->mask_base + offset); return mask_bits; diff --git a/include/linux/pci_regs.h b/include/linux/pci_regs.h index b21d33e4bc2a..d4f2c80a6c3e 100644 --- a/include/linux/pci_regs.h +++ b/include/linux/pci_regs.h @@ -315,6 +315,7 @@ #define PCI_MSIX_ENTRY_UPPER_ADDR 4 #define PCI_MSIX_ENTRY_DATA 8 #define PCI_MSIX_ENTRY_VECTOR_CTRL 12 +#define PCI_MSIX_ENTRY_CTRL_MASKBIT 1 /* CompactPCI Hotswap Register */ -- cgit v1.2.3 From 2f671e2dbff6eb5ef4e2600adbec550c13b8fe72 Mon Sep 17 00:00:00 2001 From: Matthew Garrett Date: Mon, 6 Dec 2010 14:00:56 -0500 Subject: PCI: Disable ASPM if BIOS asks us to We currently refuse to touch the ASPM registers if the BIOS tells us that ASPM isn't supported. This can cause problems if the BIOS has (for any reason) enabled ASPM on some devices anyway. Change the code such that we explicitly clear ASPM if the FADT indicates that ASPM isn't supported, and make sure we tidy up appropriately on device removal in order to deal with the hotplug case. If ASPM is disabled because the BIOS doesn't hand over control then we won't touch the registers. Signed-off-by: Matthew Garrett Signed-off-by: Jesse Barnes --- drivers/pci/pci-acpi.c | 1 + drivers/pci/pcie/aspm.c | 21 +++++++++++++++++---- include/linux/pci-aspm.h | 5 ++++- 3 files changed, 22 insertions(+), 5 deletions(-) diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c index 24e19c594e57..d7ea699b8ddc 100644 --- a/drivers/pci/pci-acpi.c +++ b/drivers/pci/pci-acpi.c @@ -399,6 +399,7 @@ static int __init acpi_pci_init(void) if (acpi_gbl_FADT.boot_flags & ACPI_FADT_NO_ASPM) { printk(KERN_INFO"ACPI FADT declares the system doesn't support PCIe ASPM, so disable it\n"); + pcie_clear_aspm(); pcie_no_aspm(); } diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c index 71222814c1ec..3188cd96b338 100644 --- a/drivers/pci/pcie/aspm.c +++ b/drivers/pci/pcie/aspm.c @@ -68,7 +68,7 @@ struct pcie_link_state { struct aspm_latency acceptable[8]; }; -static int aspm_disabled, aspm_force; +static int aspm_disabled, aspm_force, aspm_clear_state; static DEFINE_MUTEX(aspm_lock); static LIST_HEAD(link_list); @@ -139,7 +139,7 @@ static void pcie_set_clkpm(struct pcie_link_state *link, int enable) { /* Don't enable Clock PM if the link is not Clock PM capable */ if (!link->clkpm_capable && enable) - return; + enable = 0; /* Need nothing if the specified equals to current state */ if (link->clkpm_enabled == enable) return; @@ -498,6 +498,10 @@ static int pcie_aspm_sanity_check(struct pci_dev *pdev) struct pci_dev *child; int pos; u32 reg32; + + if (aspm_clear_state) + return -EINVAL; + /* * Some functions in a slot might not all be PCIe functions, * very strange. Disable ASPM for the whole slot @@ -563,12 +567,15 @@ void pcie_aspm_init_link_state(struct pci_dev *pdev) struct pcie_link_state *link; int blacklist = !!pcie_aspm_sanity_check(pdev); - if (aspm_disabled || !pci_is_pcie(pdev) || pdev->link_state) + if (!pci_is_pcie(pdev) || pdev->link_state) return; if (pdev->pcie_type != PCI_EXP_TYPE_ROOT_PORT && pdev->pcie_type != PCI_EXP_TYPE_DOWNSTREAM) return; + if (aspm_disabled && !aspm_clear_state) + return; + /* VIA has a strange chipset, root port is under a bridge */ if (pdev->pcie_type == PCI_EXP_TYPE_ROOT_PORT && pdev->bus->self) @@ -641,7 +648,7 @@ void pcie_aspm_exit_link_state(struct pci_dev *pdev) struct pci_dev *parent = pdev->bus->self; struct pcie_link_state *link, *root, *parent_link; - if (aspm_disabled || !pci_is_pcie(pdev) || + if ((aspm_disabled && !aspm_clear_state) || !pci_is_pcie(pdev) || !parent || !parent->link_state) return; if ((parent->pcie_type != PCI_EXP_TYPE_ROOT_PORT) && @@ -899,6 +906,12 @@ static int __init pcie_aspm_disable(char *str) __setup("pcie_aspm=", pcie_aspm_disable); +void pcie_clear_aspm(void) +{ + if (!aspm_force) + aspm_clear_state = 1; +} + void pcie_no_aspm(void) { if (!aspm_force) diff --git a/include/linux/pci-aspm.h b/include/linux/pci-aspm.h index 91ba0b338b47..ce6810512c66 100644 --- a/include/linux/pci-aspm.h +++ b/include/linux/pci-aspm.h @@ -27,6 +27,7 @@ extern void pcie_aspm_init_link_state(struct pci_dev *pdev); extern void pcie_aspm_exit_link_state(struct pci_dev *pdev); extern void pcie_aspm_pm_state_change(struct pci_dev *pdev); extern void pci_disable_link_state(struct pci_dev *pdev, int state); +extern void pcie_clear_aspm(void); extern void pcie_no_aspm(void); #else static inline void pcie_aspm_init_link_state(struct pci_dev *pdev) @@ -41,7 +42,9 @@ static inline void pcie_aspm_pm_state_change(struct pci_dev *pdev) static inline void pci_disable_link_state(struct pci_dev *pdev, int state) { } - +static inline void pcie_clear_aspm(void) +{ +} static inline void pcie_no_aspm(void) { } -- cgit v1.2.3 From 1d3c16a818e992c199844954d95c17fd7ce6cbba Mon Sep 17 00:00:00 2001 From: Jon Mason Date: Tue, 30 Nov 2010 17:43:26 -0600 Subject: PCI: make pci_restore_state return void pci_restore_state only ever returns 0, thus there is no benefit in having it return any value. Also, a large majority of the callers do not check the return code of pci_restore_state. Make the pci_restore_state a void return and avoid the overhead. Acked-by: Mauro Carvalho Chehab Signed-off-by: Jon Mason Signed-off-by: Jesse Barnes --- drivers/media/video/cafe_ccic.c | 4 +--- drivers/net/myri10ge/myri10ge.c | 4 +--- drivers/net/sfc/falcon.c | 25 +++++-------------------- drivers/net/skge.c | 4 +--- drivers/net/sky2.c | 5 +---- drivers/net/wireless/rt2x00/rt2x00pci.c | 4 ++-- drivers/pci/pci-driver.c | 3 ++- drivers/pci/pci.c | 7 ++----- drivers/scsi/ipr.c | 8 +------- drivers/scsi/pmcraid.c | 7 +------ drivers/staging/sm7xx/smtcfb.c | 2 +- include/linux/pci.h | 8 +++----- sound/pci/cs5535audio/cs5535audio_pm.c | 7 +------ 13 files changed, 22 insertions(+), 66 deletions(-) diff --git a/drivers/media/video/cafe_ccic.c b/drivers/media/video/cafe_ccic.c index 0dfff50891e4..737bb877e962 100644 --- a/drivers/media/video/cafe_ccic.c +++ b/drivers/media/video/cafe_ccic.c @@ -2186,9 +2186,7 @@ static int cafe_pci_resume(struct pci_dev *pdev) struct cafe_camera *cam = to_cam(v4l2_dev); int ret = 0; - ret = pci_restore_state(pdev); - if (ret) - return ret; + pci_restore_state(pdev); ret = pci_enable_device(pdev); if (ret) { diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c index 8524cc40ec57..d3c4a374a92e 100644 --- a/drivers/net/myri10ge/myri10ge.c +++ b/drivers/net/myri10ge/myri10ge.c @@ -3403,9 +3403,7 @@ static int myri10ge_resume(struct pci_dev *pdev) return -EIO; } - status = pci_restore_state(pdev); - if (status) - return status; + pci_restore_state(pdev); status = pci_enable_device(pdev); if (status) { diff --git a/drivers/net/sfc/falcon.c b/drivers/net/sfc/falcon.c index 267019bb2b15..1763b9a7fd8e 100644 --- a/drivers/net/sfc/falcon.c +++ b/drivers/net/sfc/falcon.c @@ -1066,22 +1066,9 @@ static int falcon_reset_hw(struct efx_nic *efx, enum reset_type method) /* Restore PCI configuration if needed */ if (method == RESET_TYPE_WORLD) { - if (efx_nic_is_dual_func(efx)) { - rc = pci_restore_state(nic_data->pci_dev2); - if (rc) { - netif_err(efx, drv, efx->net_dev, - "failed to restore PCI config for " - "the secondary function\n"); - goto fail3; - } - } - rc = pci_restore_state(efx->pci_dev); - if (rc) { - netif_err(efx, drv, efx->net_dev, - "failed to restore PCI config for the " - "primary function\n"); - goto fail4; - } + if (efx_nic_is_dual_func(efx)) + pci_restore_state(nic_data->pci_dev2); + pci_restore_state(efx->pci_dev); netif_dbg(efx, drv, efx->net_dev, "successfully restored PCI config\n"); } @@ -1092,7 +1079,7 @@ static int falcon_reset_hw(struct efx_nic *efx, enum reset_type method) rc = -ETIMEDOUT; netif_err(efx, hw, efx->net_dev, "timed out waiting for hardware reset\n"); - goto fail5; + goto fail3; } netif_dbg(efx, hw, efx->net_dev, "hardware reset complete\n"); @@ -1100,11 +1087,9 @@ static int falcon_reset_hw(struct efx_nic *efx, enum reset_type method) /* pci_save_state() and pci_restore_state() MUST be called in pairs */ fail2: -fail3: pci_restore_state(efx->pci_dev); fail1: -fail4: -fail5: +fail3: return rc; } diff --git a/drivers/net/skge.c b/drivers/net/skge.c index 220e0398f1d5..61553af38e65 100644 --- a/drivers/net/skge.c +++ b/drivers/net/skge.c @@ -4087,9 +4087,7 @@ static int skge_resume(struct pci_dev *pdev) if (err) goto out; - err = pci_restore_state(pdev); - if (err) - goto out; + pci_restore_state(pdev); err = skge_reset(hw); if (err) diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index d6577084ce70..be3aee782760 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c @@ -4969,10 +4969,7 @@ static int sky2_resume(struct pci_dev *pdev) if (err) goto out; - err = pci_restore_state(pdev); - if (err) - goto out; - + pci_restore_state(pdev); pci_enable_wake(pdev, PCI_D0, 0); /* Re-enable all clocks */ diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c index 2449d785cf8d..4fd4c33de6ae 100644 --- a/drivers/net/wireless/rt2x00/rt2x00pci.c +++ b/drivers/net/wireless/rt2x00/rt2x00pci.c @@ -356,12 +356,12 @@ int rt2x00pci_resume(struct pci_dev *pci_dev) struct rt2x00_dev *rt2x00dev = hw->priv; if (pci_set_power_state(pci_dev, PCI_D0) || - pci_enable_device(pci_dev) || - pci_restore_state(pci_dev)) { + pci_enable_device(pci_dev)) { ERROR(rt2x00dev, "Failed to resume device.\n"); return -EIO; } + pci_restore_state(pci_dev); return rt2x00lib_resume(rt2x00dev); } EXPORT_SYMBOL_GPL(rt2x00pci_resume); diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index 8a6f797de8e5..80e551ee640b 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c @@ -449,7 +449,8 @@ static int pci_restore_standard_config(struct pci_dev *pci_dev) return error; } - return pci_restore_state(pci_dev); + pci_restore_state(pci_dev); + return 0; } static void pci_pm_default_resume_early(struct pci_dev *pci_dev) diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 710c8a29be0d..6762dcae90ab 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -937,14 +937,13 @@ pci_save_state(struct pci_dev *dev) * pci_restore_state - Restore the saved state of a PCI device * @dev: - PCI device that we're dealing with */ -int -pci_restore_state(struct pci_dev *dev) +void pci_restore_state(struct pci_dev *dev) { int i; u32 val; if (!dev->state_saved) - return 0; + return; /* PCI Express register must be restored first */ pci_restore_pcie_state(dev); @@ -968,8 +967,6 @@ pci_restore_state(struct pci_dev *dev) pci_restore_iov_state(dev); dev->state_saved = false; - - return 0; } static int do_pci_enable_device(struct pci_dev *dev, int bars) diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c index 5bbaee597e88..524d586c3147 100644 --- a/drivers/scsi/ipr.c +++ b/drivers/scsi/ipr.c @@ -7487,16 +7487,10 @@ static int ipr_reset_restore_cfg_space(struct ipr_cmnd *ipr_cmd) { struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; volatile u32 int_reg; - int rc; ENTER; ioa_cfg->pdev->state_saved = true; - rc = pci_restore_state(ioa_cfg->pdev); - - if (rc != PCIBIOS_SUCCESSFUL) { - ipr_cmd->s.ioasa.hdr.ioasc = cpu_to_be32(IPR_IOASC_PCI_ACCESS_ERROR); - return IPR_RC_JOB_CONTINUE; - } + pci_restore_state(ioa_cfg->pdev); if (ipr_set_pcix_cmd_reg(ioa_cfg)) { ipr_cmd->s.ioasa.hdr.ioasc = cpu_to_be32(IPR_IOASC_PCI_ACCESS_ERROR); diff --git a/drivers/scsi/pmcraid.c b/drivers/scsi/pmcraid.c index 300d59f389da..321cf3ae8630 100644 --- a/drivers/scsi/pmcraid.c +++ b/drivers/scsi/pmcraid.c @@ -2228,12 +2228,7 @@ static void pmcraid_ioa_reset(struct pmcraid_cmd *cmd) /* Once either bist or pci reset is done, restore PCI config * space. If this fails, proceed with hard reset again */ - if (pci_restore_state(pinstance->pdev)) { - pmcraid_info("config-space error resetting again\n"); - pinstance->ioa_state = IOA_STATE_IN_RESET_ALERT; - pmcraid_reset_alert(cmd); - break; - } + pci_restore_state(pinstance->pdev); /* fail all pending commands */ pmcraid_fail_outstanding_cmds(pinstance); diff --git a/drivers/staging/sm7xx/smtcfb.c b/drivers/staging/sm7xx/smtcfb.c index 24f47d6388f4..7162dee3b0d8 100644 --- a/drivers/staging/sm7xx/smtcfb.c +++ b/drivers/staging/sm7xx/smtcfb.c @@ -1071,7 +1071,7 @@ static int __maybe_unused smtcfb_resume(struct pci_dev *pdev) /* when resuming, restore pci data and fb cursor */ if (pdev->dev.power.power_state.event != PM_EVENT_FREEZE) { retv = pci_set_power_state(pdev, PCI_D0); - retv = pci_restore_state(pdev); + pci_restore_state(pdev); if (pci_enable_device(pdev)) return -1; pci_set_master(pdev); diff --git a/include/linux/pci.h b/include/linux/pci.h index 7454408c41b6..63cbadce337e 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -806,7 +806,7 @@ size_t pci_get_rom_size(struct pci_dev *pdev, void __iomem *rom, size_t size); /* Power management related routines */ int pci_save_state(struct pci_dev *dev); -int pci_restore_state(struct pci_dev *dev); +void pci_restore_state(struct pci_dev *dev); int __pci_complete_power_transition(struct pci_dev *dev, pci_power_t state); int pci_set_power_state(struct pci_dev *dev, pci_power_t state); pci_power_t pci_choose_state(struct pci_dev *dev, pm_message_t state); @@ -1168,10 +1168,8 @@ static inline int pci_save_state(struct pci_dev *dev) return 0; } -static inline int pci_restore_state(struct pci_dev *dev) -{ - return 0; -} +static inline void pci_restore_state(struct pci_dev *dev) +{ } static inline int pci_set_power_state(struct pci_dev *dev, pci_power_t state) { diff --git a/sound/pci/cs5535audio/cs5535audio_pm.c b/sound/pci/cs5535audio/cs5535audio_pm.c index a3301cc4ab82..185b00088320 100644 --- a/sound/pci/cs5535audio/cs5535audio_pm.c +++ b/sound/pci/cs5535audio/cs5535audio_pm.c @@ -90,12 +90,7 @@ int snd_cs5535audio_resume(struct pci_dev *pci) int i; pci_set_power_state(pci, PCI_D0); - if (pci_restore_state(pci) < 0) { - printk(KERN_ERR "cs5535audio: pci_restore_state failed, " - "disabling device\n"); - snd_card_disconnect(card); - return -EIO; - } + pci_restore_state(pci); if (pci_enable_device(pci) < 0) { printk(KERN_ERR "cs5535audio: pci_enable_device failed, " "disabling device\n"); -- cgit v1.2.3 From 23ea3793fd368fd6a1ea20659699e280e2996658 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Thu, 18 Nov 2010 15:02:31 -0800 Subject: PCI: fix __pci_device_probe kernel-doc warning Fix kernel-doc warning for __pci_device_probe(): Warning(drivers/pci/pci-driver.c:341): missing initial short description on line: * __pci_device_probe() Signed-off-by: Randy Dunlap Signed-off-by: Jesse Barnes --- drivers/pci/pci-driver.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index 80e551ee640b..88246dd46452 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c @@ -338,7 +338,7 @@ static int pci_call_probe(struct pci_driver *drv, struct pci_dev *dev, } /** - * __pci_device_probe() + * __pci_device_probe - check if a driver wants to claim a specific PCI device * @drv: driver to call to check if it wants the PCI device * @pci_dev: PCI device being probed * -- cgit v1.2.3 From ee8abf783dd36f65440fd782ad16f9768631d998 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Wed, 17 Nov 2010 12:10:40 -0800 Subject: PCI: Skip id checking if no id is passed Will get warning when pci stub driver is built-in kenel like: pci-stub: invalid id string "" So stop early if no id is passed. Signed-off-by: Yinghai Lu Signed-off-by: Jesse Barnes --- drivers/pci/pci-stub.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/drivers/pci/pci-stub.c b/drivers/pci/pci-stub.c index f7b68ca6cc98..4c0336b31caf 100644 --- a/drivers/pci/pci-stub.c +++ b/drivers/pci/pci-stub.c @@ -47,6 +47,10 @@ static int __init pci_stub_init(void) if (rc) return rc; + /* no ids passed actually */ + if (ids[0] == '\0') + return 0; + /* add ids specified in the module parameter */ p = ids; while ((id = strsep(&p, ","))) { -- cgit v1.2.3 From 9b444b36fee16d2aaae9cc91ce594ecb15d922a9 Mon Sep 17 00:00:00 2001 From: Seth Heasley Date: Wed, 17 Nov 2010 12:12:08 -0700 Subject: x86/PCI: irq and pci_ids patch for Intel Patsburg This patch adds an additional LPC Controller DeviceID for the Intel Patsburg PCH. Signed-off-by: Seth Heasley Signed-off-by: Jesse Barnes --- arch/x86/pci/irq.c | 3 ++- include/linux/pci_ids.h | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/arch/x86/pci/irq.c b/arch/x86/pci/irq.c index 9f9bfb705cf9..87e6c8323117 100644 --- a/arch/x86/pci/irq.c +++ b/arch/x86/pci/irq.c @@ -589,7 +589,8 @@ static __init int intel_router_probe(struct irq_router *r, struct pci_dev *route case PCI_DEVICE_ID_INTEL_ICH10_1: case PCI_DEVICE_ID_INTEL_ICH10_2: case PCI_DEVICE_ID_INTEL_ICH10_3: - case PCI_DEVICE_ID_INTEL_PATSBURG_LPC: + case PCI_DEVICE_ID_INTEL_PATSBURG_LPC_0: + case PCI_DEVICE_ID_INTEL_PATSBURG_LPC_1: r->name = "PIIX/ICH"; r->get = pirq_piix_get; r->set = pirq_piix_set; diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index cb845c16ad7d..d830106827fd 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -2468,7 +2468,8 @@ #define PCI_DEVICE_ID_INTEL_COUGARPOINT_LPC_MIN 0x1c41 #define PCI_DEVICE_ID_INTEL_COUGARPOINT_LPC_MAX 0x1c5f #define PCI_DEVICE_ID_INTEL_PATSBURG_SMBUS 0x1d22 -#define PCI_DEVICE_ID_INTEL_PATSBURG_LPC 0x1d40 +#define PCI_DEVICE_ID_INTEL_PATSBURG_LPC_0 0x1d40 +#define PCI_DEVICE_ID_INTEL_PATSBURG_LPC_1 0x1d41 #define PCI_DEVICE_ID_INTEL_82801AA_0 0x2410 #define PCI_DEVICE_ID_INTEL_82801AA_1 0x2411 #define PCI_DEVICE_ID_INTEL_82801AA_3 0x2413 -- cgit v1.2.3 From 99a0fadf561e1f553c08f0a29f8b2578f55dd5f0 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Wed, 22 Dec 2010 10:06:36 +0100 Subject: PCI: pci-stub: ignore zero-length id parameters pci-stub uses strsep() to separate list of ids and generates a warning message when it fails to parse an id. However, not specifying the parameter results in ids set to an empty string. strsep() happily returns the empty string as the first token and thus triggers the warning message spuriously. Make the tokner ignore zero length ids. Reported-by: Chris Wright Reported-by: Prasad Joshi Cc: stable@kernel.org Signed-off-by: Jesse Barnes --- drivers/pci/pci-stub.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/pci/pci-stub.c b/drivers/pci/pci-stub.c index 4c0336b31caf..775e933c2225 100644 --- a/drivers/pci/pci-stub.c +++ b/drivers/pci/pci-stub.c @@ -58,6 +58,9 @@ static int __init pci_stub_init(void) subdevice = PCI_ANY_ID, class=0, class_mask=0; int fields; + if (!strlen(id)) + continue; + fields = sscanf(id, "%x:%x:%x:%x:%x:%x", &vendor, &device, &subvendor, &subdevice, &class, &class_mask); -- cgit v1.2.3 From fe31e69740eddc7316071ed5165fed6703c8cd12 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Sun, 19 Dec 2010 15:57:16 +0100 Subject: PCI/PCIe: Clear Root PME Status bits early during system resume I noticed that PCI Express PMEs don't work on my Toshiba Portege R500 after the system has been woken up from a sleep state by a PME (through Wake-on-LAN). After some investigation it turned out that the BIOS didn't clear the Root PME Status bit in the root port that received the wakeup PME and since the Requester ID was also set in the port's Root Status register, any subsequent PMEs didn't trigger interrupts. This problem can be avoided by clearing the Root PME Status bits in all PCI Express root ports during early resume. For this purpose, add an early resume routine to the PCIe port driver and make this driver be always registered, even if pci_ports_disable is set (in which case the driver's only function is to provide the early resume callback). Signed-off-by: Rafael J. Wysocki Signed-off-by: Jesse Barnes --- drivers/pci/pcie/pme.c | 27 ++++----------------------- drivers/pci/pcie/portdrv.h | 2 ++ drivers/pci/pcie/portdrv_core.c | 25 ++++++++++++++----------- drivers/pci/pcie/portdrv_pci.c | 37 +++++++++++++++++++++++++++++++++---- include/linux/pci_regs.h | 2 ++ 5 files changed, 55 insertions(+), 38 deletions(-) diff --git a/drivers/pci/pcie/pme.c b/drivers/pci/pcie/pme.c index 2f3c90407227..073f0308c6b2 100644 --- a/drivers/pci/pcie/pme.c +++ b/drivers/pci/pcie/pme.c @@ -26,9 +26,6 @@ #include "../pci.h" #include "portdrv.h" -#define PCI_EXP_RTSTA_PME 0x10000 /* PME status */ -#define PCI_EXP_RTSTA_PENDING 0x20000 /* PME pending */ - /* * If this switch is set, MSI will not be used for PCIe PME signaling. This * causes the PCIe port driver to use INTx interrupts only, but it turns out @@ -73,22 +70,6 @@ void pcie_pme_interrupt_enable(struct pci_dev *dev, bool enable) pci_write_config_word(dev, rtctl_pos, rtctl); } -/** - * pcie_pme_clear_status - Clear root port PME interrupt status. - * @dev: PCIe root port or event collector. - */ -static void pcie_pme_clear_status(struct pci_dev *dev) -{ - int rtsta_pos; - u32 rtsta; - - rtsta_pos = pci_pcie_cap(dev) + PCI_EXP_RTSTA; - - pci_read_config_dword(dev, rtsta_pos, &rtsta); - rtsta |= PCI_EXP_RTSTA_PME; - pci_write_config_dword(dev, rtsta_pos, rtsta); -} - /** * pcie_pme_walk_bus - Scan a PCI bus for devices asserting PME#. * @bus: PCI bus to scan. @@ -253,7 +234,7 @@ static void pcie_pme_work_fn(struct work_struct *work) * Clear PME status of the port. If there are other * pending PMEs, the status will be set again. */ - pcie_pme_clear_status(port); + pcie_clear_root_pme_status(port); spin_unlock_irq(&data->lock); pcie_pme_handle_request(port, rtsta & 0xffff); @@ -378,7 +359,7 @@ static int pcie_pme_probe(struct pcie_device *srv) port = srv->port; pcie_pme_interrupt_enable(port, false); - pcie_pme_clear_status(port); + pcie_clear_root_pme_status(port); ret = request_irq(srv->irq, pcie_pme_irq, IRQF_SHARED, "PCIe PME", srv); if (ret) { @@ -402,7 +383,7 @@ static int pcie_pme_suspend(struct pcie_device *srv) spin_lock_irq(&data->lock); pcie_pme_interrupt_enable(port, false); - pcie_pme_clear_status(port); + pcie_clear_root_pme_status(port); data->noirq = true; spin_unlock_irq(&data->lock); @@ -422,7 +403,7 @@ static int pcie_pme_resume(struct pcie_device *srv) spin_lock_irq(&data->lock); data->noirq = false; - pcie_pme_clear_status(port); + pcie_clear_root_pme_status(port); pcie_pme_interrupt_enable(port, true); spin_unlock_irq(&data->lock); diff --git a/drivers/pci/pcie/portdrv.h b/drivers/pci/pcie/portdrv.h index 7b5aba0a3291..8fcc03598b29 100644 --- a/drivers/pci/pcie/portdrv.h +++ b/drivers/pci/pcie/portdrv.h @@ -35,6 +35,8 @@ extern void pcie_port_bus_unregister(void); struct pci_dev; +extern void pcie_clear_root_pme_status(struct pci_dev *dev); + #ifdef CONFIG_PCIE_PME extern bool pcie_pme_msi_disabled; diff --git a/drivers/pci/pcie/portdrv_core.c b/drivers/pci/pcie/portdrv_core.c index a9c222d79ebc..5130d0d22390 100644 --- a/drivers/pci/pcie/portdrv_core.c +++ b/drivers/pci/pcie/portdrv_core.c @@ -241,17 +241,17 @@ static int get_port_device_capability(struct pci_dev *dev) int cap_mask; int err; + if (pcie_ports_disabled) + return 0; + err = pcie_port_platform_notify(dev, &cap_mask); - if (pcie_ports_auto) { - if (err) { - pcie_no_aspm(); - return 0; - } - } else { + if (!pcie_ports_auto) { cap_mask = PCIE_PORT_SERVICE_PME | PCIE_PORT_SERVICE_HP | PCIE_PORT_SERVICE_VC; if (pci_aer_available()) cap_mask |= PCIE_PORT_SERVICE_AER; + } else if (err) { + return 0; } pos = pci_pcie_cap(dev); @@ -349,15 +349,18 @@ int pcie_port_device_register(struct pci_dev *dev) int status, capabilities, i, nr_service; int irqs[PCIE_PORT_DEVICE_MAXSERVICES]; - /* Get and check PCI Express port services */ - capabilities = get_port_device_capability(dev); - if (!capabilities) - return -ENODEV; - /* Enable PCI Express port device */ status = pci_enable_device(dev); if (status) return status; + + /* Get and check PCI Express port services */ + capabilities = get_port_device_capability(dev); + if (!capabilities) { + pcie_no_aspm(); + return 0; + } + pci_set_master(dev); /* * Initialize service irqs. Don't use service devices that diff --git a/drivers/pci/pcie/portdrv_pci.c b/drivers/pci/pcie/portdrv_pci.c index f9033e190fb6..e0610bda1dea 100644 --- a/drivers/pci/pcie/portdrv_pci.c +++ b/drivers/pci/pcie/portdrv_pci.c @@ -57,6 +57,22 @@ __setup("pcie_ports=", pcie_port_setup); /* global data */ +/** + * pcie_clear_root_pme_status - Clear root port PME interrupt status. + * @dev: PCIe root port or event collector. + */ +void pcie_clear_root_pme_status(struct pci_dev *dev) +{ + int rtsta_pos; + u32 rtsta; + + rtsta_pos = pci_pcie_cap(dev) + PCI_EXP_RTSTA; + + pci_read_config_dword(dev, rtsta_pos, &rtsta); + rtsta |= PCI_EXP_RTSTA_PME; + pci_write_config_dword(dev, rtsta_pos, rtsta); +} + static int pcie_portdrv_restore_config(struct pci_dev *dev) { int retval; @@ -69,6 +85,20 @@ static int pcie_portdrv_restore_config(struct pci_dev *dev) } #ifdef CONFIG_PM +static int pcie_port_resume_noirq(struct device *dev) +{ + struct pci_dev *pdev = to_pci_dev(dev); + + /* + * Some BIOSes forget to clear Root PME Status bits after system wakeup + * which breaks ACPI-based runtime wakeup on PCI Express, so clear those + * bits now just in case (shouldn't hurt). + */ + if(pdev->pcie_type == PCI_EXP_TYPE_ROOT_PORT) + pcie_clear_root_pme_status(pdev); + return 0; +} + static const struct dev_pm_ops pcie_portdrv_pm_ops = { .suspend = pcie_port_device_suspend, .resume = pcie_port_device_resume, @@ -76,6 +106,7 @@ static const struct dev_pm_ops pcie_portdrv_pm_ops = { .thaw = pcie_port_device_resume, .poweroff = pcie_port_device_suspend, .restore = pcie_port_device_resume, + .resume_noirq = pcie_port_resume_noirq, }; #define PCIE_PORTDRV_PM_OPS (&pcie_portdrv_pm_ops) @@ -327,10 +358,8 @@ static int __init pcie_portdrv_init(void) { int retval; - if (pcie_ports_disabled) { - pcie_no_aspm(); - return -EACCES; - } + if (pcie_ports_disabled) + return pci_register_driver(&pcie_portdriver); dmi_check_system(pcie_portdrv_dmi_table); diff --git a/include/linux/pci_regs.h b/include/linux/pci_regs.h index d4f2c80a6c3e..5b7e6b1ba54f 100644 --- a/include/linux/pci_regs.h +++ b/include/linux/pci_regs.h @@ -504,6 +504,8 @@ #define PCI_EXP_RTCTL_CRSSVE 0x10 /* CRS Software Visibility Enable */ #define PCI_EXP_RTCAP 30 /* Root Capabilities */ #define PCI_EXP_RTSTA 32 /* Root Status */ +#define PCI_EXP_RTSTA_PME 0x10000 /* PME status */ +#define PCI_EXP_RTSTA_PENDING 0x20000 /* PME pending */ #define PCI_EXP_DEVCAP2 36 /* Device Capabilities 2 */ #define PCI_EXP_DEVCAP2_ARI 0x20 /* Alternative Routing-ID */ #define PCI_EXP_DEVCTL2 40 /* Device Control 2 */ -- cgit v1.2.3 From aab94339cd85d726abeae78fc02351fc1910e6a4 Mon Sep 17 00:00:00 2001 From: Dirk Brandewie Date: Wed, 22 Dec 2010 11:57:26 -0800 Subject: of: Add support for linking device tree blobs into vmlinux This patch adds support for linking device tree blob(s) into vmlinux. Modifies asm-generic/vmlinux.lds.h to add linking .dtb sections into vmlinux. To maintain compatiblity with the of/fdt driver code platforms MUST copy the blob to a non-init memory location before the kernel frees the .init.* sections in the image. Modifies scripts/Makefile.lib to add a kbuild command to compile DTS files to device tree blobs and a rule to create objects to wrap the blobs for linking. STRUCT_ALIGNMENT is defined in vmlinux.lds.h for use in the rule to create wrapper objects for the dtb in Makefile.lib. The STRUCT_ALIGN() macro in vmlinux.lds.h is modified to use the STRUCT_ALIGNMENT definition. The DTB's are placed on 32 byte boundries to allow parsing the blob with driver/of/fdt.c during early boot without having to copy the blob to get the structure alignment GCC expects. A DTB is linked in by adding the DTB object to the list of objects to be linked into vmlinux in the archtecture specific Makefile using obj-y += foo.dtb.o Signed-off-by: Dirk Brandewie Acked-by: Michal Marek [grant.likely@secretlab.ca: cleaned up whitespace inconsistencies] Signed-off-by: Grant Likely --- Documentation/kbuild/makefiles.txt | 15 +++++++++++++++ include/asm-generic/vmlinux.lds.h | 13 +++++++++++-- scripts/Makefile.lib | 23 +++++++++++++++++++++++ 3 files changed, 49 insertions(+), 2 deletions(-) diff --git a/Documentation/kbuild/makefiles.txt b/Documentation/kbuild/makefiles.txt index 0ef00bd6e54d..86e3cd0d26a0 100644 --- a/Documentation/kbuild/makefiles.txt +++ b/Documentation/kbuild/makefiles.txt @@ -1136,6 +1136,21 @@ When kbuild executes, the following steps are followed (roughly): resulting in the target file being recompiled for no obvious reason. + dtc + Create flattend device tree blob object suitable for linking + into vmlinux. Device tree blobs linked into vmlinux are placed + in an init section in the image. Platform code *must* copy the + blob to non-init memory prior to calling unflatten_device_tree(). + + Example: + #arch/x86/platform/ce4100/Makefile + clean-files := *dtb.S + + DTC_FLAGS := -p 1024 + obj-y += foo.dtb.o + + $(obj)/%.dtb: $(src)/%.dts + $(call cmd,dtc) --- 6.7 Custom kbuild commands diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h index bd69d79208de..05cbad03c5ab 100644 --- a/include/asm-generic/vmlinux.lds.h +++ b/include/asm-generic/vmlinux.lds.h @@ -67,7 +67,8 @@ * Align to a 32 byte boundary equal to the * alignment gcc 4.5 uses for a struct */ -#define STRUCT_ALIGN() . = ALIGN(32) +#define STRUCT_ALIGNMENT 32 +#define STRUCT_ALIGN() . = ALIGN(STRUCT_ALIGNMENT) /* The actual configuration determine if the init/exit sections * are handled as text/data or they can be discarded (which @@ -146,6 +147,13 @@ #define TRACE_SYSCALLS() #endif + +#define KERNEL_DTB() \ + STRUCT_ALIGN(); \ + VMLINUX_SYMBOL(__dtb_start) = .; \ + *(.dtb.init.rodata) \ + VMLINUX_SYMBOL(__dtb_end) = .; + /* .data section */ #define DATA_DATA \ *(.data) \ @@ -468,7 +476,8 @@ MCOUNT_REC() \ DEV_DISCARD(init.rodata) \ CPU_DISCARD(init.rodata) \ - MEM_DISCARD(init.rodata) + MEM_DISCARD(init.rodata) \ + KERNEL_DTB() #define INIT_TEXT \ *(.init.text) \ diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index 4c72c1189479..396da16aabf8 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -200,6 +200,29 @@ quiet_cmd_gzip = GZIP $@ cmd_gzip = (cat $(filter-out FORCE,$^) | gzip -f -9 > $@) || \ (rm -f $@ ; false) +# DTC +# --------------------------------------------------------------------------- + +# Generate an assembly file to wrap the output of the device tree compiler +quiet_cmd_dt_S_dtb= DTB $@ +cmd_dt_S_dtb= \ +( \ + echo '\#include '; \ + echo '.section .dtb.init.rodata,"a"'; \ + echo '.balign STRUCT_ALIGNMENT'; \ + echo '.global __dtb_$(*F)_begin'; \ + echo '__dtb_$(*F)_begin:'; \ + echo '.incbin "$<" '; \ + echo '__dtb_$(*F)_end:'; \ + echo '.global __dtb_$(*F)_end'; \ + echo '.balign STRUCT_ALIGNMENT'; \ +) > $@ + +$(obj)/%.dtb.S: $(obj)/%.dtb + $(call cmd,dt_S_dtb) + +quiet_cmd_dtc = DTC $@ +cmd_dtc = $(objtree)/scripts/dtc/dtc -O dtb -o $@ -b 0 $(DTC_FLAGS) $< # Bzip2 # --------------------------------------------------------------------------- -- cgit v1.2.3 From 63849340621f7f5f963e4a9b9ba76add3ad54612 Mon Sep 17 00:00:00 2001 From: Dirk Brandewie Date: Wed, 22 Dec 2010 11:57:28 -0800 Subject: of/powerpc: Use generic rule to build dtb's Modify arch/powerpc/boot/Makefile to use dtc command in scripts/Makefile.lib Signed-off-by: Dirk Brandewie Signed-off-by: Grant Likely --- arch/powerpc/boot/Makefile | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile index fae8192c8fcc..96deec63bcf3 100644 --- a/arch/powerpc/boot/Makefile +++ b/arch/powerpc/boot/Makefile @@ -35,7 +35,7 @@ endif BOOTCFLAGS += -I$(obj) -I$(srctree)/$(obj) -DTS_FLAGS ?= -p 1024 +DTC_FLAGS ?= -p 1024 $(obj)/4xx.o: BOOTCFLAGS += -mcpu=405 $(obj)/ebony.o: BOOTCFLAGS += -mcpu=405 @@ -332,10 +332,8 @@ $(obj)/treeImage.%: vmlinux $(obj)/%.dtb $(wrapperbits) $(call if_changed,wrap,treeboot-$*,,$(obj)/$*.dtb) # Rule to build device tree blobs -DTC = $(objtree)/scripts/dtc/dtc - -$(obj)/%.dtb: $(dtstree)/%.dts - $(DTC) -O dtb -o $(obj)/$*.dtb -b 0 $(DTS_FLAGS) $(dtstree)/$*.dts +$(obj)/%.dtb: $(src)/dts/%.dts + $(call cmd,dtc) # If there isn't a platform selected then just strip the vmlinux. ifeq (,$(image-y)) -- cgit v1.2.3 From 710fc04da1abe48a33d54afb1ba33dbeceafb6e1 Mon Sep 17 00:00:00 2001 From: Dirk Brandewie Date: Wed, 22 Dec 2010 11:57:29 -0800 Subject: microblaze/of: Use generic rule to build dtb's Modify arch/powerpc/boot/Makefile to use dtc command in scripts/Makefile.lib Signed-off-by: Dirk Brandewie Signed-off-by: Grant Likely --- arch/microblaze/boot/Makefile | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/arch/microblaze/boot/Makefile b/arch/microblaze/boot/Makefile index be01d78750d9..4c4e58ef0cb6 100644 --- a/arch/microblaze/boot/Makefile +++ b/arch/microblaze/boot/Makefile @@ -10,9 +10,6 @@ targets := linux.bin linux.bin.gz simpleImage.% OBJCOPYFLAGS := -O binary -# Where the DTS files live -dtstree := $(srctree)/$(src)/dts - # Ensure system.dtb exists $(obj)/linked_dtb.o: $(obj)/system.dtb @@ -51,14 +48,11 @@ $(obj)/simpleImage.%: vmlinux FORCE $(call if_changed,strip) @echo 'Kernel: $@ is ready' ' (#'`cat .version`')' -# Rule to build device tree blobs -DTC = $(objtree)/scripts/dtc/dtc # Rule to build device tree blobs -quiet_cmd_dtc = DTC $@ - cmd_dtc = $(DTC) -O dtb -o $(obj)/$*.dtb -b 0 -p 1024 $(dtstree)/$*.dts +DTC_FLAGS := -p 1024 -$(obj)/%.dtb: $(dtstree)/%.dts FORCE - $(call if_changed,dtc) +$(obj)/%.dtb: $(src)/dts/%.dts FORCE + $(call cmd,dtc) clean-files += *.dtb simpleImage.*.unstrip linux.bin.ub -- cgit v1.2.3 From 0131d8973c8b9bd9d40fee8fae24eab24821efdb Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Wed, 1 Dec 2010 10:54:46 +0100 Subject: of/address: use proper endianess in get_flags This patch changes u32 to __be32 for all "ranges", "prop" and "addr" and such. Those variables are pointing to the device tree which contains integers in big endian format. Most functions are doing it right because of_read_number() is doing the right thing for them. of_bus_isa_get_flags(), of_bus_pci_get_flags() and of_bus_isa_map() were accessing the data directly and were doing it wrong. Signed-off-by: Sebastian Andrzej Siewior Acked-by: Benjamin Herrenschmidt Signed-off-by: Grant Likely --- arch/powerpc/include/asm/prom.h | 2 +- drivers/of/address.c | 54 +++++++++++++++++++++-------------------- include/linux/of_address.h | 6 ++--- 3 files changed, 32 insertions(+), 30 deletions(-) diff --git a/arch/powerpc/include/asm/prom.h b/arch/powerpc/include/asm/prom.h index 98264bf0a433..d72757585595 100644 --- a/arch/powerpc/include/asm/prom.h +++ b/arch/powerpc/include/asm/prom.h @@ -42,7 +42,7 @@ extern void pci_create_OF_bus_map(void); /* Translate a DMA address from device space to CPU space */ extern u64 of_translate_dma_address(struct device_node *dev, - const u32 *in_addr); + const __be32 *in_addr); #ifdef CONFIG_PCI extern unsigned long pci_address_to_pio(phys_addr_t address); diff --git a/drivers/of/address.c b/drivers/of/address.c index 3a1c7e70b192..b4559c58c095 100644 --- a/drivers/of/address.c +++ b/drivers/of/address.c @@ -12,13 +12,13 @@ (ns) > 0) static struct of_bus *of_match_bus(struct device_node *np); -static int __of_address_to_resource(struct device_node *dev, const u32 *addrp, - u64 size, unsigned int flags, +static int __of_address_to_resource(struct device_node *dev, + const __be32 *addrp, u64 size, unsigned int flags, struct resource *r); /* Debug utility */ #ifdef DEBUG -static void of_dump_addr(const char *s, const u32 *addr, int na) +static void of_dump_addr(const char *s, const __be32 *addr, int na) { printk(KERN_DEBUG "%s", s); while (na--) @@ -26,7 +26,7 @@ static void of_dump_addr(const char *s, const u32 *addr, int na) printk("\n"); } #else -static void of_dump_addr(const char *s, const u32 *addr, int na) { } +static void of_dump_addr(const char *s, const __be32 *addr, int na) { } #endif /* Callbacks for bus specific translators */ @@ -36,10 +36,10 @@ struct of_bus { int (*match)(struct device_node *parent); void (*count_cells)(struct device_node *child, int *addrc, int *sizec); - u64 (*map)(u32 *addr, const u32 *range, + u64 (*map)(u32 *addr, const __be32 *range, int na, int ns, int pna); int (*translate)(u32 *addr, u64 offset, int na); - unsigned int (*get_flags)(const u32 *addr); + unsigned int (*get_flags)(const __be32 *addr); }; /* @@ -55,7 +55,7 @@ static void of_bus_default_count_cells(struct device_node *dev, *sizec = of_n_size_cells(dev); } -static u64 of_bus_default_map(u32 *addr, const u32 *range, +static u64 of_bus_default_map(u32 *addr, const __be32 *range, int na, int ns, int pna) { u64 cp, s, da; @@ -85,7 +85,7 @@ static int of_bus_default_translate(u32 *addr, u64 offset, int na) return 0; } -static unsigned int of_bus_default_get_flags(const u32 *addr) +static unsigned int of_bus_default_get_flags(const __be32 *addr) { return IORESOURCE_MEM; } @@ -110,10 +110,10 @@ static void of_bus_pci_count_cells(struct device_node *np, *sizec = 2; } -static unsigned int of_bus_pci_get_flags(const u32 *addr) +static unsigned int of_bus_pci_get_flags(const __be32 *addr) { unsigned int flags = 0; - u32 w = addr[0]; + u32 w = be32_to_cpup(addr); switch((w >> 24) & 0x03) { case 0x01: @@ -129,7 +129,8 @@ static unsigned int of_bus_pci_get_flags(const u32 *addr) return flags; } -static u64 of_bus_pci_map(u32 *addr, const u32 *range, int na, int ns, int pna) +static u64 of_bus_pci_map(u32 *addr, const __be32 *range, int na, int ns, + int pna) { u64 cp, s, da; unsigned int af, rf; @@ -160,7 +161,7 @@ static int of_bus_pci_translate(u32 *addr, u64 offset, int na) return of_bus_default_translate(addr + 1, offset, na - 1); } -const u32 *of_get_pci_address(struct device_node *dev, int bar_no, u64 *size, +const __be32 *of_get_pci_address(struct device_node *dev, int bar_no, u64 *size, unsigned int *flags) { const __be32 *prop; @@ -207,7 +208,7 @@ EXPORT_SYMBOL(of_get_pci_address); int of_pci_address_to_resource(struct device_node *dev, int bar, struct resource *r) { - const u32 *addrp; + const __be32 *addrp; u64 size; unsigned int flags; @@ -237,12 +238,13 @@ static void of_bus_isa_count_cells(struct device_node *child, *sizec = 1; } -static u64 of_bus_isa_map(u32 *addr, const u32 *range, int na, int ns, int pna) +static u64 of_bus_isa_map(u32 *addr, const __be32 *range, int na, int ns, + int pna) { u64 cp, s, da; /* Check address type match */ - if ((addr[0] ^ range[0]) & 0x00000001) + if ((addr[0] ^ range[0]) & cpu_to_be32(1)) return OF_BAD_ADDR; /* Read address values, skipping high cell */ @@ -264,10 +266,10 @@ static int of_bus_isa_translate(u32 *addr, u64 offset, int na) return of_bus_default_translate(addr + 1, offset, na - 1); } -static unsigned int of_bus_isa_get_flags(const u32 *addr) +static unsigned int of_bus_isa_get_flags(const __be32 *addr) { unsigned int flags = 0; - u32 w = addr[0]; + u32 w = be32_to_cpup(addr); if (w & 1) flags |= IORESOURCE_IO; @@ -330,7 +332,7 @@ static int of_translate_one(struct device_node *parent, struct of_bus *bus, struct of_bus *pbus, u32 *addr, int na, int ns, int pna, const char *rprop) { - const u32 *ranges; + const __be32 *ranges; unsigned int rlen; int rone; u64 offset = OF_BAD_ADDR; @@ -398,7 +400,7 @@ static int of_translate_one(struct device_node *parent, struct of_bus *bus, * that can be mapped to a cpu physical address). This is not really specified * that way, but this is traditionally the way IBM at least do things */ -u64 __of_translate_address(struct device_node *dev, const u32 *in_addr, +u64 __of_translate_address(struct device_node *dev, const __be32 *in_addr, const char *rprop) { struct device_node *parent = NULL; @@ -475,22 +477,22 @@ u64 __of_translate_address(struct device_node *dev, const u32 *in_addr, return result; } -u64 of_translate_address(struct device_node *dev, const u32 *in_addr) +u64 of_translate_address(struct device_node *dev, const __be32 *in_addr) { return __of_translate_address(dev, in_addr, "ranges"); } EXPORT_SYMBOL(of_translate_address); -u64 of_translate_dma_address(struct device_node *dev, const u32 *in_addr) +u64 of_translate_dma_address(struct device_node *dev, const __be32 *in_addr) { return __of_translate_address(dev, in_addr, "dma-ranges"); } EXPORT_SYMBOL(of_translate_dma_address); -const u32 *of_get_address(struct device_node *dev, int index, u64 *size, +const __be32 *of_get_address(struct device_node *dev, int index, u64 *size, unsigned int *flags) { - const u32 *prop; + const __be32 *prop; unsigned int psize; struct device_node *parent; struct of_bus *bus; @@ -525,8 +527,8 @@ const u32 *of_get_address(struct device_node *dev, int index, u64 *size, } EXPORT_SYMBOL(of_get_address); -static int __of_address_to_resource(struct device_node *dev, const u32 *addrp, - u64 size, unsigned int flags, +static int __of_address_to_resource(struct device_node *dev, + const __be32 *addrp, u64 size, unsigned int flags, struct resource *r) { u64 taddr; @@ -564,7 +566,7 @@ static int __of_address_to_resource(struct device_node *dev, const u32 *addrp, int of_address_to_resource(struct device_node *dev, int index, struct resource *r) { - const u32 *addrp; + const __be32 *addrp; u64 size; unsigned int flags; diff --git a/include/linux/of_address.h b/include/linux/of_address.h index 8aea06f0564c..2feda6ee6140 100644 --- a/include/linux/of_address.h +++ b/include/linux/of_address.h @@ -3,7 +3,7 @@ #include #include -extern u64 of_translate_address(struct device_node *np, const u32 *addr); +extern u64 of_translate_address(struct device_node *np, const __be32 *addr); extern int of_address_to_resource(struct device_node *dev, int index, struct resource *r); extern void __iomem *of_iomap(struct device_node *device, int index); @@ -21,7 +21,7 @@ static inline unsigned long pci_address_to_pio(phys_addr_t addr) { return -1; } #endif #ifdef CONFIG_PCI -extern const u32 *of_get_pci_address(struct device_node *dev, int bar_no, +extern const __be32 *of_get_pci_address(struct device_node *dev, int bar_no, u64 *size, unsigned int *flags); extern int of_pci_address_to_resource(struct device_node *dev, int bar, struct resource *r); @@ -32,7 +32,7 @@ static inline int of_pci_address_to_resource(struct device_node *dev, int bar, return -ENOSYS; } -static inline const u32 *of_get_pci_address(struct device_node *dev, +static inline const __be32 *of_get_pci_address(struct device_node *dev, int bar_no, u64 *size, unsigned int *flags) { return NULL; -- cgit v1.2.3 From 34dc9e74968ef4b582c3815b0124d88a68dfabef Mon Sep 17 00:00:00 2001 From: David Rientjes Date: Wed, 22 Dec 2010 17:23:40 -0800 Subject: x86, numa: Reduce minimum fake node size to 32M This patch changes the minimum fake node size from 64MB to 32MB so it is possible to test NUMA code at a greater scale on smaller machines (64 nodes on a 2G machine, 1024 nodes on 32G machine with CONFIG_NODES_SHIFT=10). Signed-off-by: David Rientjes LKML-Reference: Signed-off-by: H. Peter Anvin --- arch/x86/include/asm/numa_64.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/x86/include/asm/numa_64.h b/arch/x86/include/asm/numa_64.h index 823e070e7c26..5ae87285a502 100644 --- a/arch/x86/include/asm/numa_64.h +++ b/arch/x86/include/asm/numa_64.h @@ -38,7 +38,7 @@ extern void __cpuinit numa_add_cpu(int cpu); extern void __cpuinit numa_remove_cpu(int cpu); #ifdef CONFIG_NUMA_EMU -#define FAKE_NODE_MIN_SIZE ((u64)64 << 20) +#define FAKE_NODE_MIN_SIZE ((u64)32 << 20) #define FAKE_NODE_MIN_HASH_MASK (~(FAKE_NODE_MIN_SIZE - 1UL)) #endif /* CONFIG_NUMA_EMU */ #else -- cgit v1.2.3 From 4e76f4e67a106ed827ca721b4c8b622047cd2f6d Mon Sep 17 00:00:00 2001 From: David Rientjes Date: Wed, 22 Dec 2010 17:23:47 -0800 Subject: x86, numa: Avoid compiling NUMA emulation functions without CONFIG_NUMA_EMU Both acpi_get_nodes() and amd_get_nodes() are only necessary when CONFIG_NUMA_EMU is enabled, so avoid compiling them when the option is disabled. Signed-off-by: David Rientjes LKML-Reference: Signed-off-by: H. Peter Anvin --- arch/x86/include/asm/acpi.h | 5 ++++- arch/x86/include/asm/amd_nb.h | 5 ++++- arch/x86/mm/amdtopology_64.c | 2 ++ arch/x86/mm/srat_64.c | 2 ++ 4 files changed, 12 insertions(+), 2 deletions(-) diff --git a/arch/x86/include/asm/acpi.h b/arch/x86/include/asm/acpi.h index 55d106b5e31b..b326fa99db57 100644 --- a/arch/x86/include/asm/acpi.h +++ b/arch/x86/include/asm/acpi.h @@ -188,14 +188,17 @@ extern int acpi_numa; extern int acpi_get_nodes(struct bootnode *physnodes); extern int acpi_scan_nodes(unsigned long start, unsigned long end); #define NR_NODE_MEMBLKS (MAX_NUMNODES*2) + +#ifdef CONFIG_NUMA_EMU extern void acpi_fake_nodes(const struct bootnode *fake_nodes, int num_nodes); +#endif #else static inline void acpi_fake_nodes(const struct bootnode *fake_nodes, int num_nodes) { } -#endif +#endif /* CONFIG_ACPI_NUMA */ #define acpi_unlazy_tlb(x) leave_mm(x) diff --git a/arch/x86/include/asm/amd_nb.h b/arch/x86/include/asm/amd_nb.h index 6aee50d655d1..9c16cde63f04 100644 --- a/arch/x86/include/asm/amd_nb.h +++ b/arch/x86/include/asm/amd_nb.h @@ -9,10 +9,13 @@ struct bootnode; extern int early_is_amd_nb(u32 value); extern int amd_cache_northbridges(void); extern void amd_flush_garts(void); -extern int amd_get_nodes(struct bootnode *nodes); extern int amd_numa_init(unsigned long start_pfn, unsigned long end_pfn); extern int amd_scan_nodes(void); +#ifdef CONFIG_NUMA_EMU +extern int amd_get_nodes(struct bootnode *nodes); +#endif + struct amd_northbridge { struct pci_dev *misc; }; diff --git a/arch/x86/mm/amdtopology_64.c b/arch/x86/mm/amdtopology_64.c index 51fae9cfdecb..fe050af614e2 100644 --- a/arch/x86/mm/amdtopology_64.c +++ b/arch/x86/mm/amdtopology_64.c @@ -69,6 +69,7 @@ static __init void early_get_boot_cpu_id(void) early_init_lapic_mapping(); } +#ifdef CONFIG_NUMA_EMU int __init amd_get_nodes(struct bootnode *physnodes) { int i; @@ -81,6 +82,7 @@ int __init amd_get_nodes(struct bootnode *physnodes) } return ret; } +#endif /* CONFIG_NUMA_EMU */ int __init amd_numa_init(unsigned long start_pfn, unsigned long end_pfn) { diff --git a/arch/x86/mm/srat_64.c b/arch/x86/mm/srat_64.c index a35cb9d8b060..8241bf0f6eb2 100644 --- a/arch/x86/mm/srat_64.c +++ b/arch/x86/mm/srat_64.c @@ -339,6 +339,7 @@ static int __init nodes_cover_memory(const struct bootnode *nodes) void __init acpi_numa_arch_fixup(void) {} +#ifdef CONFIG_NUMA_EMU int __init acpi_get_nodes(struct bootnode *physnodes) { int i; @@ -351,6 +352,7 @@ int __init acpi_get_nodes(struct bootnode *physnodes) } return ret; } +#endif /* CONFIG_NUMA_EMU */ /* Use the information discovered above to actually set up the nodes. */ int __init acpi_scan_nodes(unsigned long start, unsigned long end) -- cgit v1.2.3 From f51bf3073a145a5b3263fd882c52d6ec04b687da Mon Sep 17 00:00:00 2001 From: David Rientjes Date: Wed, 22 Dec 2010 17:23:51 -0800 Subject: x86, numa: Fake apicid and pxm mappings for NUMA emulation This patch adds the equivalent of acpi_fake_nodes() for AMD Northbridge platforms. The goal is to fake the apicid-to-node mappings for NUMA emulation so the physical topology of the machine is correctly maintained within the kernel. This change also fakes proximity domains for both ACPI and k8 code so the physical distance between emulated nodes is maintained via node_distance(). This exports the correct distances via /sys/devices/system/node/.../distance based on the underlying topology. A new helper function, fake_physnodes(), is introduced to correctly invoke the correct NUMA code to fake these two mappings based on the system type. If there is no underlying NUMA configuration, all cpus are mapped to node 0 for local distance. Since acpi_fake_nodes() is no longer called with CONFIG_ACPI_NUMA, it's prototype can be removed from the header file for such a configuration. Signed-off-by: David Rientjes LKML-Reference: Signed-off-by: H. Peter Anvin --- arch/x86/include/asm/acpi.h | 5 --- arch/x86/include/asm/amd_nb.h | 1 + arch/x86/mm/amdtopology_64.c | 91 +++++++++++++++++++++++++++++++++++-------- arch/x86/mm/numa_64.c | 20 +++++++++- arch/x86/mm/srat_64.c | 2 - 5 files changed, 95 insertions(+), 24 deletions(-) diff --git a/arch/x86/include/asm/acpi.h b/arch/x86/include/asm/acpi.h index b326fa99db57..8288daf72dc9 100644 --- a/arch/x86/include/asm/acpi.h +++ b/arch/x86/include/asm/acpi.h @@ -193,11 +193,6 @@ extern int acpi_scan_nodes(unsigned long start, unsigned long end); extern void acpi_fake_nodes(const struct bootnode *fake_nodes, int num_nodes); #endif -#else -static inline void acpi_fake_nodes(const struct bootnode *fake_nodes, - int num_nodes) -{ -} #endif /* CONFIG_ACPI_NUMA */ #define acpi_unlazy_tlb(x) leave_mm(x) diff --git a/arch/x86/include/asm/amd_nb.h b/arch/x86/include/asm/amd_nb.h index 9c16cde63f04..8f6192c1592c 100644 --- a/arch/x86/include/asm/amd_nb.h +++ b/arch/x86/include/asm/amd_nb.h @@ -13,6 +13,7 @@ extern int amd_numa_init(unsigned long start_pfn, unsigned long end_pfn); extern int amd_scan_nodes(void); #ifdef CONFIG_NUMA_EMU +extern void amd_fake_nodes(const struct bootnode *nodes, int nr_nodes); extern int amd_get_nodes(struct bootnode *nodes); #endif diff --git a/arch/x86/mm/amdtopology_64.c b/arch/x86/mm/amdtopology_64.c index fe050af614e2..eb5cbb97b68d 100644 --- a/arch/x86/mm/amdtopology_64.c +++ b/arch/x86/mm/amdtopology_64.c @@ -27,6 +27,7 @@ #include static struct bootnode __initdata nodes[8]; +static unsigned char __initdata nodeids[8]; static nodemask_t __initdata nodes_parsed = NODE_MASK_NONE; static __init int find_northbridge(void) @@ -69,21 +70,6 @@ static __init void early_get_boot_cpu_id(void) early_init_lapic_mapping(); } -#ifdef CONFIG_NUMA_EMU -int __init amd_get_nodes(struct bootnode *physnodes) -{ - int i; - int ret = 0; - - for_each_node_mask(i, nodes_parsed) { - physnodes[ret].start = nodes[i].start; - physnodes[ret].end = nodes[i].end; - ret++; - } - return ret; -} -#endif /* CONFIG_NUMA_EMU */ - int __init amd_numa_init(unsigned long start_pfn, unsigned long end_pfn) { unsigned long start = PFN_PHYS(start_pfn); @@ -116,7 +102,7 @@ int __init amd_numa_init(unsigned long start_pfn, unsigned long end_pfn) base = read_pci_config(0, nb, 1, 0x40 + i*8); limit = read_pci_config(0, nb, 1, 0x44 + i*8); - nodeid = limit & 7; + nodeids[i] = nodeid = limit & 7; if ((base & 3) == 0) { if (i < numnodes) pr_info("Skipping disabled node %d\n", i); @@ -196,6 +182,79 @@ int __init amd_numa_init(unsigned long start_pfn, unsigned long end_pfn) return 0; } +#ifdef CONFIG_NUMA_EMU +static s16 fake_apicid_to_node[MAX_LOCAL_APIC] __initdata = { + [0 ... MAX_LOCAL_APIC-1] = NUMA_NO_NODE +}; + +int __init amd_get_nodes(struct bootnode *physnodes) +{ + int i; + int ret = 0; + + for_each_node_mask(i, nodes_parsed) { + physnodes[ret].start = nodes[i].start; + physnodes[ret].end = nodes[i].end; + ret++; + } + return ret; +} + +static int __init find_node_by_addr(unsigned long addr) +{ + int ret = NUMA_NO_NODE; + int i; + + for (i = 0; i < 8; i++) + if (addr >= nodes[i].start && addr < nodes[i].end) { + ret = i; + break; + } + return ret; +} + +/* + * For NUMA emulation, fake proximity domain (_PXM) to node id mappings must be + * setup to represent the physical topology but reflect the emulated + * environment. For each emulated node, the real node which it appears on is + * found and a fake pxm to nid mapping is created which mirrors the actual + * locality. node_distance() then represents the correct distances between + * emulated nodes by using the fake acpi mappings to pxms. + */ +void __init amd_fake_nodes(const struct bootnode *nodes, int nr_nodes) +{ + unsigned int bits; + unsigned int cores; + unsigned int apicid_base = 0; + int i; + + bits = boot_cpu_data.x86_coreid_bits; + cores = 1 << bits; + early_get_boot_cpu_id(); + if (boot_cpu_physical_apicid > 0) + apicid_base = boot_cpu_physical_apicid; + + for (i = 0; i < nr_nodes; i++) { + int index; + int nid; + int j; + + nid = find_node_by_addr(nodes[i].start); + if (nid == NUMA_NO_NODE) + continue; + + index = nodeids[nid] << bits; + if (fake_apicid_to_node[index + apicid_base] == NUMA_NO_NODE) + for (j = apicid_base; j < cores + apicid_base; j++) + fake_apicid_to_node[index + j] = i; +#ifdef CONFIG_ACPI_NUMA + __acpi_map_pxm_to_node(nid, i); +#endif + } + memcpy(apicid_to_node, fake_apicid_to_node, sizeof(apicid_to_node)); +} +#endif /* CONFIG_NUMA_EMU */ + int __init amd_scan_nodes(void) { unsigned int bits; diff --git a/arch/x86/mm/numa_64.c b/arch/x86/mm/numa_64.c index 7762a517d69d..cc390f3a1bde 100644 --- a/arch/x86/mm/numa_64.c +++ b/arch/x86/mm/numa_64.c @@ -324,6 +324,24 @@ static int __init setup_physnodes(unsigned long start, unsigned long end, return ret; } +static void __init fake_physnodes(int acpi, int amd, int nr_nodes) +{ + int i; + + BUG_ON(acpi && amd); +#ifdef CONFIG_ACPI_NUMA + if (acpi) + acpi_fake_nodes(nodes, nr_nodes); +#endif +#ifdef CONFIG_AMD_NUMA + if (amd) + amd_fake_nodes(nodes, nr_nodes); +#endif + if (!acpi && !amd) + for (i = 0; i < nr_cpu_ids; i++) + numa_set_node(i, 0); +} + /* * Setups up nid to range from addr to addr + size. If the end * boundary is greater than max_addr, then max_addr is used instead. @@ -595,7 +613,7 @@ static int __init numa_emulation(unsigned long start_pfn, nodes[i].end >> PAGE_SHIFT); setup_node_bootmem(i, nodes[i].start, nodes[i].end); } - acpi_fake_nodes(nodes, num_nodes); + fake_physnodes(acpi, amd, num_nodes); numa_init_array(); return 0; } diff --git a/arch/x86/mm/srat_64.c b/arch/x86/mm/srat_64.c index 8241bf0f6eb2..c48b443706c5 100644 --- a/arch/x86/mm/srat_64.c +++ b/arch/x86/mm/srat_64.c @@ -497,8 +497,6 @@ void __init acpi_fake_nodes(const struct bootnode *fake_nodes, int num_nodes) { int i, j; - printk(KERN_INFO "Faking PXM affinity for fake nodes on real " - "topology.\n"); for (i = 0; i < num_nodes; i++) { int nid, pxm; -- cgit v1.2.3 From c1c3443c9c5e9be92641029ed229a41563e44506 Mon Sep 17 00:00:00 2001 From: David Rientjes Date: Wed, 22 Dec 2010 17:23:54 -0800 Subject: x86, numa: Fake node-to-cpumask for NUMA emulation It's necessary to fake the node-to-cpumask mapping so that an emulated node ID returns a cpumask that includes all cpus that have affinity to the memory it represents. This is a little intrusive because it requires knowledge of the physical topology of the system. setup_physnodes() gives us that information, but since NUMA emulation ends up altering the physnodes array, it's necessary to reset it before cpus are brought online. Accordingly, the physnodes array is moved out of init.data and into cpuinit.data since it will be needed on cpuup callbacks. This works regardless of whether numa=fake is used on the command line, or the setup of the fake node succeeds or fails. The physnodes array always contains the physical topology of the machine if CONFIG_NUMA_EMU is enabled and can be used to setup the correct node-to-cpumask mappings in all cases since setup_physnodes() is called whenever the array needs to be repopulated with the correct data. To fake the actual mappings, numa_add_cpu() and numa_remove_cpu() are rewritten for CONFIG_NUMA_EMU so that we first find the physical node to which each cpu has local affinity, then iterate through all online nodes to find the emulated nodes that have local affinity to that physical node, and then finally map the cpu to each of those emulated nodes. Signed-off-by: David Rientjes LKML-Reference: Signed-off-by: H. Peter Anvin --- arch/x86/mm/numa_64.c | 99 ++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 79 insertions(+), 20 deletions(-) diff --git a/arch/x86/mm/numa_64.c b/arch/x86/mm/numa_64.c index cc390f3a1bde..dd300c491f1f 100644 --- a/arch/x86/mm/numa_64.c +++ b/arch/x86/mm/numa_64.c @@ -260,7 +260,7 @@ void __init numa_init_array(void) #ifdef CONFIG_NUMA_EMU /* Numa emulation */ static struct bootnode nodes[MAX_NUMNODES] __initdata; -static struct bootnode physnodes[MAX_NUMNODES] __initdata; +static struct bootnode physnodes[MAX_NUMNODES] __cpuinitdata; static char *cmdline __initdata; static int __init setup_physnodes(unsigned long start, unsigned long end, @@ -270,6 +270,7 @@ static int __init setup_physnodes(unsigned long start, unsigned long end, int ret = 0; int i; + memset(physnodes, 0, sizeof(physnodes)); #ifdef CONFIG_ACPI_NUMA if (acpi) nr_nodes = acpi_get_nodes(physnodes); @@ -370,8 +371,7 @@ static int __init setup_node_range(int nid, u64 *addr, u64 size, u64 max_addr) * Sets up nr_nodes fake nodes interleaved over physical nodes ranging from addr * to max_addr. The return value is the number of nodes allocated. */ -static int __init split_nodes_interleave(u64 addr, u64 max_addr, - int nr_phys_nodes, int nr_nodes) +static int __init split_nodes_interleave(u64 addr, u64 max_addr, int nr_nodes) { nodemask_t physnode_mask = NODE_MASK_NONE; u64 size; @@ -402,7 +402,7 @@ static int __init split_nodes_interleave(u64 addr, u64 max_addr, return -1; } - for (i = 0; i < nr_phys_nodes; i++) + for (i = 0; i < MAX_NUMNODES; i++) if (physnodes[i].start != physnodes[i].end) node_set(i, physnode_mask); @@ -571,11 +571,9 @@ static int __init numa_emulation(unsigned long start_pfn, { u64 addr = start_pfn << PAGE_SHIFT; u64 max_addr = last_pfn << PAGE_SHIFT; - int num_phys_nodes; int num_nodes; int i; - num_phys_nodes = setup_physnodes(addr, max_addr, acpi, amd); /* * If the numa=fake command-line contains a 'M' or 'G', it represents * the fixed node size. Otherwise, if it is just a single number N, @@ -590,7 +588,7 @@ static int __init numa_emulation(unsigned long start_pfn, unsigned long n; n = simple_strtoul(cmdline, NULL, 0); - num_nodes = split_nodes_interleave(addr, max_addr, num_phys_nodes, n); + num_nodes = split_nodes_interleave(addr, max_addr, n); } if (num_nodes < 0) @@ -613,6 +611,7 @@ static int __init numa_emulation(unsigned long start_pfn, nodes[i].end >> PAGE_SHIFT); setup_node_bootmem(i, nodes[i].start, nodes[i].end); } + setup_physnodes(addr, max_addr, acpi, amd); fake_physnodes(acpi, amd, num_nodes); numa_init_array(); return 0; @@ -628,8 +627,12 @@ void __init initmem_init(unsigned long start_pfn, unsigned long last_pfn, nodes_clear(node_online_map); #ifdef CONFIG_NUMA_EMU + setup_physnodes(start_pfn << PAGE_SHIFT, last_pfn << PAGE_SHIFT, + acpi, amd); if (cmdline && !numa_emulation(start_pfn, last_pfn, acpi, amd)) return; + setup_physnodes(start_pfn << PAGE_SHIFT, last_pfn << PAGE_SHIFT, + acpi, amd); nodes_clear(node_possible_map); nodes_clear(node_online_map); #endif @@ -785,6 +788,7 @@ void __cpuinit numa_clear_node(int cpu) #ifndef CONFIG_DEBUG_PER_CPU_MAPS +#ifndef CONFIG_NUMA_EMU void __cpuinit numa_add_cpu(int cpu) { cpumask_set_cpu(cpu, node_to_cpumask_map[early_cpu_to_node(cpu)]); @@ -794,6 +798,51 @@ void __cpuinit numa_remove_cpu(int cpu) { cpumask_clear_cpu(cpu, node_to_cpumask_map[early_cpu_to_node(cpu)]); } +#else +void __cpuinit numa_add_cpu(int cpu) +{ + unsigned long addr; + u16 apicid; + int physnid; + int nid = NUMA_NO_NODE; + + apicid = early_per_cpu(x86_cpu_to_apicid, cpu); + if (apicid != BAD_APICID) + nid = apicid_to_node[apicid]; + if (nid == NUMA_NO_NODE) + nid = early_cpu_to_node(cpu); + BUG_ON(nid == NUMA_NO_NODE || !node_online(nid)); + + /* + * Use the starting address of the emulated node to find which physical + * node it is allocated on. + */ + addr = node_start_pfn(nid) << PAGE_SHIFT; + for (physnid = 0; physnid < MAX_NUMNODES; physnid++) + if (addr >= physnodes[physnid].start && + addr < physnodes[physnid].end) + break; + + /* + * Map the cpu to each emulated node that is allocated on the physical + * node of the cpu's apic id. + */ + for_each_online_node(nid) { + addr = node_start_pfn(nid) << PAGE_SHIFT; + if (addr >= physnodes[physnid].start && + addr < physnodes[physnid].end) + cpumask_set_cpu(cpu, node_to_cpumask_map[nid]); + } +} + +void __cpuinit numa_remove_cpu(int cpu) +{ + int i; + + for_each_online_node(i) + cpumask_clear_cpu(cpu, node_to_cpumask_map[i]); +} +#endif /* !CONFIG_NUMA_EMU */ #else /* CONFIG_DEBUG_PER_CPU_MAPS */ @@ -805,22 +854,32 @@ static void __cpuinit numa_set_cpumask(int cpu, int enable) int node = early_cpu_to_node(cpu); struct cpumask *mask; char buf[64]; + int i; - mask = node_to_cpumask_map[node]; - if (mask == NULL) { - printk(KERN_ERR "node_to_cpumask_map[%i] NULL\n", node); - dump_stack(); - return; - } + for_each_online_node(i) { + unsigned long addr; - if (enable) - cpumask_set_cpu(cpu, mask); - else - cpumask_clear_cpu(cpu, mask); + addr = node_start_pfn(i) << PAGE_SHIFT; + if (addr < physnodes[node].start || + addr >= physnodes[node].end) + continue; + mask = node_to_cpumask_map[node]; + if (mask == NULL) { + pr_err("node_to_cpumask_map[%i] NULL\n", i); + dump_stack(); + return; + } + + if (enable) + cpumask_set_cpu(cpu, mask); + else + cpumask_clear_cpu(cpu, mask); - cpulist_scnprintf(buf, sizeof(buf), mask); - printk(KERN_DEBUG "%s cpu %d node %d: mask now %s\n", - enable ? "numa_add_cpu" : "numa_remove_cpu", cpu, node, buf); + cpulist_scnprintf(buf, sizeof(buf), mask); + printk(KERN_DEBUG "%s cpu %d node %d: mask now %s\n", + enable ? "numa_add_cpu" : "numa_remove_cpu", + cpu, node, buf); + } } void __cpuinit numa_add_cpu(int cpu) -- cgit v1.2.3 From a387e95a49743cf9835c5299ca549232618d8249 Mon Sep 17 00:00:00 2001 From: David Rientjes Date: Wed, 22 Dec 2010 17:23:56 -0800 Subject: x86, numa: Fix cpu to node mapping for sparse node ids NUMA boot code assumes that physical node ids start at 0, but the DIMMs that the apic id represents may not be reachable. If this is the case, node 0 is never online and cpus never end up getting appropriately assigned to a node. This causes the cpumask of all online nodes to be empty and machines crash with kernel code assuming online nodes have valid cpus. The fix is to appropriately map all the address ranges for physical nodes and ensure the cpu to node mapping function checks all possible nodes (up to MAX_NUMNODES) instead of simply checking nodes 0-N, where N is the number of physical nodes, for valid address ranges. This requires no longer "compressing" the address ranges of nodes in the physical node map from 0-N, but rather leave indices in physnodes[] to represent the actual node id of the physical node. Accordingly, the topology exported by both amd_get_nodes() and acpi_get_nodes() no longer must return the number of nodes to iterate through; all such iterations will now be to MAX_NUMNODES. This change also passes the end address of system RAM (which may be different from normal operation if mem= is specified on the command line) before the physnodes[] array is populated. ACPI parsed nodes are truncated to fit within the address range that respect the mem= boundaries and even some physical nodes may become unreachable in such cases. When NUMA emulation does succeed, any apicid to node mapping that exists for unreachable nodes are given default values so that proximity domains can still be assigned. This is important for node_distance() to function as desired. Signed-off-by: David Rientjes LKML-Reference: Signed-off-by: H. Peter Anvin --- arch/x86/include/asm/acpi.h | 3 ++- arch/x86/include/asm/amd_nb.h | 2 +- arch/x86/mm/amdtopology_64.c | 9 +++------ arch/x86/mm/numa_64.c | 18 +++--------------- arch/x86/mm/srat_64.c | 22 ++++++++++++++++------ 5 files changed, 25 insertions(+), 29 deletions(-) diff --git a/arch/x86/include/asm/acpi.h b/arch/x86/include/asm/acpi.h index 8288daf72dc9..211ca3f7fd16 100644 --- a/arch/x86/include/asm/acpi.h +++ b/arch/x86/include/asm/acpi.h @@ -185,7 +185,8 @@ struct bootnode; #ifdef CONFIG_ACPI_NUMA extern int acpi_numa; -extern int acpi_get_nodes(struct bootnode *physnodes); +extern void acpi_get_nodes(struct bootnode *physnodes, unsigned long start, + unsigned long end); extern int acpi_scan_nodes(unsigned long start, unsigned long end); #define NR_NODE_MEMBLKS (MAX_NUMNODES*2) diff --git a/arch/x86/include/asm/amd_nb.h b/arch/x86/include/asm/amd_nb.h index 8f6192c1592c..980f22567631 100644 --- a/arch/x86/include/asm/amd_nb.h +++ b/arch/x86/include/asm/amd_nb.h @@ -14,7 +14,7 @@ extern int amd_scan_nodes(void); #ifdef CONFIG_NUMA_EMU extern void amd_fake_nodes(const struct bootnode *nodes, int nr_nodes); -extern int amd_get_nodes(struct bootnode *nodes); +extern void amd_get_nodes(struct bootnode *nodes); #endif struct amd_northbridge { diff --git a/arch/x86/mm/amdtopology_64.c b/arch/x86/mm/amdtopology_64.c index eb5cbb97b68d..0df2623d1039 100644 --- a/arch/x86/mm/amdtopology_64.c +++ b/arch/x86/mm/amdtopology_64.c @@ -187,17 +187,14 @@ static s16 fake_apicid_to_node[MAX_LOCAL_APIC] __initdata = { [0 ... MAX_LOCAL_APIC-1] = NUMA_NO_NODE }; -int __init amd_get_nodes(struct bootnode *physnodes) +void __init amd_get_nodes(struct bootnode *physnodes) { int i; - int ret = 0; for_each_node_mask(i, nodes_parsed) { - physnodes[ret].start = nodes[i].start; - physnodes[ret].end = nodes[i].end; - ret++; + physnodes[i].start = nodes[i].start; + physnodes[i].end = nodes[i].end; } - return ret; } static int __init find_node_by_addr(unsigned long addr) diff --git a/arch/x86/mm/numa_64.c b/arch/x86/mm/numa_64.c index dd300c491f1f..3d73201ba347 100644 --- a/arch/x86/mm/numa_64.c +++ b/arch/x86/mm/numa_64.c @@ -266,25 +266,24 @@ static char *cmdline __initdata; static int __init setup_physnodes(unsigned long start, unsigned long end, int acpi, int amd) { - int nr_nodes = 0; int ret = 0; int i; memset(physnodes, 0, sizeof(physnodes)); #ifdef CONFIG_ACPI_NUMA if (acpi) - nr_nodes = acpi_get_nodes(physnodes); + acpi_get_nodes(physnodes, start, end); #endif #ifdef CONFIG_AMD_NUMA if (amd) - nr_nodes = amd_get_nodes(physnodes); + amd_get_nodes(physnodes); #endif /* * Basic sanity checking on the physical node map: there may be errors * if the SRAT or AMD code incorrectly reported the topology or the mem= * kernel parameter is used. */ - for (i = 0; i < nr_nodes; i++) { + for (i = 0; i < MAX_NUMNODES; i++) { if (physnodes[i].start == physnodes[i].end) continue; if (physnodes[i].start > end) { @@ -299,17 +298,6 @@ static int __init setup_physnodes(unsigned long start, unsigned long end, physnodes[i].start = start; if (physnodes[i].end > end) physnodes[i].end = end; - } - - /* - * Remove all nodes that have no memory or were truncated because of the - * limited address range. - */ - for (i = 0; i < nr_nodes; i++) { - if (physnodes[i].start == physnodes[i].end) - continue; - physnodes[ret].start = physnodes[i].start; - physnodes[ret].end = physnodes[i].end; ret++; } diff --git a/arch/x86/mm/srat_64.c b/arch/x86/mm/srat_64.c index c48b443706c5..a756bcf3fa48 100644 --- a/arch/x86/mm/srat_64.c +++ b/arch/x86/mm/srat_64.c @@ -340,17 +340,16 @@ static int __init nodes_cover_memory(const struct bootnode *nodes) void __init acpi_numa_arch_fixup(void) {} #ifdef CONFIG_NUMA_EMU -int __init acpi_get_nodes(struct bootnode *physnodes) +void __init acpi_get_nodes(struct bootnode *physnodes, unsigned long start, + unsigned long end) { int i; - int ret = 0; for_each_node_mask(i, nodes_parsed) { - physnodes[ret].start = nodes[i].start; - physnodes[ret].end = nodes[i].end; - ret++; + cutoff_node(i, start, end); + physnodes[i].start = nodes[i].start; + physnodes[i].end = nodes[i].end; } - return ret; } #endif /* CONFIG_NUMA_EMU */ @@ -516,6 +515,17 @@ void __init acpi_fake_nodes(const struct bootnode *fake_nodes, int num_nodes) fake_apicid_to_node[j] == NUMA_NO_NODE) fake_apicid_to_node[j] = i; } + + /* + * If there are apicid-to-node mappings for physical nodes that do not + * have a corresponding emulated node, it should default to a guaranteed + * value. + */ + for (i = 0; i < MAX_LOCAL_APIC; i++) + if (apicid_to_node[i] != NUMA_NO_NODE && + fake_apicid_to_node[i] == NUMA_NO_NODE) + fake_apicid_to_node[i] = 0; + for (i = 0; i < num_nodes; i++) __acpi_map_pxm_to_node(fake_node_to_pxm_map[i], i); memcpy(apicid_to_node, fake_apicid_to_node, sizeof(apicid_to_node)); -- cgit v1.2.3 From 194588604765ac803f98fb9d19a36f6b835f4620 Mon Sep 17 00:00:00 2001 From: David Daney Date: Wed, 27 Oct 2010 18:03:47 -0700 Subject: of/mdio: Fix some endianness problems. In of_mdiobus_register(), the __be32 *addr variable is dereferenced. This will not work on little-endian targets. Also since it is unsigned, checking for less than zero is redundant. Fix these two issues. Signed-off-by: David Daney [grant.likely@secretlab.ca: removed goto] Signed-off-by: Grant Likely --- drivers/of/of_mdio.c | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/drivers/of/of_mdio.c b/drivers/of/of_mdio.c index 1fce00eb421b..dcd7857784f2 100644 --- a/drivers/of/of_mdio.c +++ b/drivers/of/of_mdio.c @@ -52,27 +52,35 @@ int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np) /* Loop over the child nodes and register a phy_device for each one */ for_each_child_of_node(np, child) { - const __be32 *addr; + const __be32 *paddr; + u32 addr; int len; /* A PHY must have a reg property in the range [0-31] */ - addr = of_get_property(child, "reg", &len); - if (!addr || len < sizeof(*addr) || *addr >= 32 || *addr < 0) { + paddr = of_get_property(child, "reg", &len); + if (!paddr || len < sizeof(*paddr)) { dev_err(&mdio->dev, "%s has invalid PHY address\n", child->full_name); continue; } + addr = be32_to_cpup(paddr); + if (addr >= 32) { + dev_err(&mdio->dev, "%s PHY address %i is too large\n", + child->full_name, addr); + continue; + } + if (mdio->irq) { - mdio->irq[*addr] = irq_of_parse_and_map(child, 0); - if (!mdio->irq[*addr]) - mdio->irq[*addr] = PHY_POLL; + mdio->irq[addr] = irq_of_parse_and_map(child, 0); + if (!mdio->irq[addr]) + mdio->irq[addr] = PHY_POLL; } - phy = get_phy_device(mdio, be32_to_cpup(addr)); + phy = get_phy_device(mdio, addr); if (!phy || IS_ERR(phy)) { dev_err(&mdio->dev, "error probing PHY at address %i\n", - *addr); + addr); continue; } phy_scan_fixups(phy); @@ -91,7 +99,7 @@ int of_mdiobus_register(struct mii_bus *mdio, struct device_node *np) } dev_dbg(&mdio->dev, "registered phy %s at address %i\n", - child->name, *addr); + child->name, addr); } return 0; -- cgit v1.2.3 From 9ed030d728f3bd03b6e869357da02725afda19a7 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Wed, 17 Nov 2010 13:00:48 +0100 Subject: misc/at24: parse device tree data Information about the pagesize and read-only-status may also come from the devicetree. Parse this data, too, and act accordingly. While we are here, change the initialization printout a bit. write_max is useful to know to detect performance bottlenecks, the rest is superfluous. Signed-off-by: Wolfram Sang Signed-off-by: Grant Likely --- Documentation/powerpc/dts-bindings/eeprom.txt | 28 +++++++++++++++++++++++ drivers/misc/eeprom/at24.c | 33 ++++++++++++++++++++++----- 2 files changed, 55 insertions(+), 6 deletions(-) create mode 100644 Documentation/powerpc/dts-bindings/eeprom.txt diff --git a/Documentation/powerpc/dts-bindings/eeprom.txt b/Documentation/powerpc/dts-bindings/eeprom.txt new file mode 100644 index 000000000000..4342c10de1bf --- /dev/null +++ b/Documentation/powerpc/dts-bindings/eeprom.txt @@ -0,0 +1,28 @@ +EEPROMs (I2C) + +Required properties: + + - compatible : should be "," + If there is no specific driver for , a generic + driver based on is selected. Possible types are: + 24c00, 24c01, 24c02, 24c04, 24c08, 24c16, 24c32, 24c64, + 24c128, 24c256, 24c512, 24c1024, spd + + - reg : the I2C address of the EEPROM + +Optional properties: + + - pagesize : the length of the pagesize for writing. Please consult the + manual of your device, that value varies a lot. A wrong value + may result in data loss! If not specified, a safety value of + '1' is used which will be very slow. + + - read-only: this parameterless property disables writes to the eeprom + +Example: + +eeprom@52 { + compatible = "atmel,24c32"; + reg = <0x52>; + pagesize = <32>; +}; diff --git a/drivers/misc/eeprom/at24.c b/drivers/misc/eeprom/at24.c index 559b0b3c16c3..3a53efc28821 100644 --- a/drivers/misc/eeprom/at24.c +++ b/drivers/misc/eeprom/at24.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -457,6 +458,27 @@ static ssize_t at24_macc_write(struct memory_accessor *macc, const char *buf, /*-------------------------------------------------------------------------*/ +#ifdef CONFIG_OF +static void at24_get_ofdata(struct i2c_client *client, + struct at24_platform_data *chip) +{ + const __be32 *val; + struct device_node *node = client->dev.of_node; + + if (node) { + if (of_get_property(node, "read-only", NULL)) + chip->flags |= AT24_FLAG_READONLY; + val = of_get_property(node, "pagesize", NULL); + if (val) + chip->page_size = be32_to_cpup(val); + } +} +#else +static void at24_get_ofdata(struct i2c_client *client, + struct at24_platform_data *chip) +{ } +#endif /* CONFIG_OF */ + static int at24_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct at24_platform_data chip; @@ -485,6 +507,9 @@ static int at24_probe(struct i2c_client *client, const struct i2c_device_id *id) */ chip.page_size = 1; + /* update chipdata if OF is present */ + at24_get_ofdata(client, &chip); + chip.setup = NULL; chip.context = NULL; } @@ -597,19 +622,15 @@ static int at24_probe(struct i2c_client *client, const struct i2c_device_id *id) i2c_set_clientdata(client, at24); - dev_info(&client->dev, "%zu byte %s EEPROM %s\n", + dev_info(&client->dev, "%zu byte %s EEPROM, %s, %u bytes/write\n", at24->bin.size, client->name, - writable ? "(writable)" : "(read-only)"); + writable ? "writable" : "read-only", at24->write_max); if (use_smbus == I2C_SMBUS_WORD_DATA || use_smbus == I2C_SMBUS_BYTE_DATA) { dev_notice(&client->dev, "Falling back to %s reads, " "performance will suffer\n", use_smbus == I2C_SMBUS_WORD_DATA ? "word" : "byte"); } - dev_dbg(&client->dev, - "page_size %d, num_addresses %d, write_max %d, use_smbus %d\n", - chip.page_size, num_addresses, - at24->write_max, use_smbus); /* export data to kernel code */ if (chip.setup) -- cgit v1.2.3 From 45efe847971e6274a04eea75a0745d8015b54d37 Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Wed, 17 Nov 2010 13:00:49 +0100 Subject: misc/at24: add more sanity checks for parameters Side-effects happen when passing 0 to either io_limit or page_size. Give an error in case of this misconfiguration. Signed-off-by: Wolfram Sang Signed-off-by: Grant Likely --- drivers/misc/eeprom/at24.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/misc/eeprom/at24.c b/drivers/misc/eeprom/at24.c index 3a53efc28821..ab1ad41786d1 100644 --- a/drivers/misc/eeprom/at24.c +++ b/drivers/misc/eeprom/at24.c @@ -517,6 +517,11 @@ static int at24_probe(struct i2c_client *client, const struct i2c_device_id *id) if (!is_power_of_2(chip.byte_len)) dev_warn(&client->dev, "byte_len looks suspicious (no power of 2)!\n"); + if (!chip.page_size) { + dev_err(&client->dev, "page_size must not be 0!\n"); + err = -EINVAL; + goto err_out; + } if (!is_power_of_2(chip.page_size)) dev_warn(&client->dev, "page_size looks suspicious (no power of 2)!\n"); @@ -681,6 +686,11 @@ static struct i2c_driver at24_driver = { static int __init at24_init(void) { + if (!io_limit) { + pr_err("at24: io_limit must not be 0!\n"); + return -EINVAL; + } + io_limit = rounddown_pow_of_two(io_limit); return i2c_add_driver(&at24_driver); } -- cgit v1.2.3 From 55271024a735d0c3234e6ca7e0914b05aab7fbac Mon Sep 17 00:00:00 2001 From: Wolfram Sang Date: Wed, 17 Nov 2010 13:00:50 +0100 Subject: powerpc/pcm{030,032}: add pagesize to dts Signed-off-by: Wolfram Sang Signed-off-by: Grant Likely --- arch/powerpc/boot/dts/pcm030.dts | 1 + arch/powerpc/boot/dts/pcm032.dts | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/arch/powerpc/boot/dts/pcm030.dts b/arch/powerpc/boot/dts/pcm030.dts index 8a4ec30b21ae..e7c36bc88fa0 100644 --- a/arch/powerpc/boot/dts/pcm030.dts +++ b/arch/powerpc/boot/dts/pcm030.dts @@ -259,6 +259,7 @@ eeprom@52 { compatible = "catalyst,24c32"; reg = <0x52>; + pagesize = <32>; }; }; diff --git a/arch/powerpc/boot/dts/pcm032.dts b/arch/powerpc/boot/dts/pcm032.dts index 85d857a5d46e..e175e2c601b5 100644 --- a/arch/powerpc/boot/dts/pcm032.dts +++ b/arch/powerpc/boot/dts/pcm032.dts @@ -257,8 +257,9 @@ reg = <0x51>; }; eeprom@52 { - compatible = "at24,24c32"; + compatible = "catalyst,24c32"; reg = <0x52>; + pagesize = <32>; }; }; -- cgit v1.2.3 From 524d7692bcdbec9027bfdc001a8aeb6eb6837117 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 23 Dec 2010 11:17:24 +0000 Subject: ASoC: Remove incorrect WM8903 erratum workaround Due to a typographical error in the erratum workaround it was never functional so just remove it. Signed-off-by: Mark Brown Acked-by: Liam Girdwood --- sound/soc/codecs/wm8903.c | 20 ++++++-------------- sound/soc/codecs/wm8903.h | 19 ------------------- 2 files changed, 6 insertions(+), 33 deletions(-) diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c index 02de5ae42d63..b9843f72c455 100644 --- a/sound/soc/codecs/wm8903.c +++ b/sound/soc/codecs/wm8903.c @@ -1014,7 +1014,7 @@ static int wm8903_add_widgets(struct snd_soc_codec *codec) static int wm8903_set_bias_level(struct snd_soc_codec *codec, enum snd_soc_bias_level level) { - u16 reg, reg2; + u16 reg; switch (level) { case SND_SOC_BIAS_ON: @@ -1038,23 +1038,15 @@ static int wm8903_set_bias_level(struct snd_soc_codec *codec, wm8903_run_sequence(codec, 0); wm8903_sync_reg_cache(codec, codec->reg_cache); - /* Enable low impedence charge pump output */ - reg = snd_soc_read(codec, - WM8903_CONTROL_INTERFACE_TEST_1); - snd_soc_write(codec, WM8903_CONTROL_INTERFACE_TEST_1, - reg | WM8903_TEST_KEY); - reg2 = snd_soc_read(codec, WM8903_CHARGE_PUMP_TEST_1); - snd_soc_write(codec, WM8903_CHARGE_PUMP_TEST_1, - reg2 | WM8903_CP_SW_KELVIN_MODE_MASK); - snd_soc_write(codec, WM8903_CONTROL_INTERFACE_TEST_1, - reg); - /* By default no bypass paths are enabled so * enable Class W support. */ dev_dbg(codec->dev, "Enabling Class W\n"); - snd_soc_write(codec, WM8903_CLASS_W_0, reg | - WM8903_CP_DYN_FREQ | WM8903_CP_DYN_V); + snd_soc_update_bits(codec, WM8903_CLASS_W_0, + WM8903_CP_DYN_FREQ | + WM8903_CP_DYN_V, + WM8903_CP_DYN_FREQ | + WM8903_CP_DYN_V); } reg = snd_soc_read(codec, WM8903_VMID_CONTROL_0); diff --git a/sound/soc/codecs/wm8903.h b/sound/soc/codecs/wm8903.h index e47b8c8be921..5f23d3ca45f8 100644 --- a/sound/soc/codecs/wm8903.h +++ b/sound/soc/codecs/wm8903.h @@ -94,8 +94,6 @@ extern int wm8903_mic_detect(struct snd_soc_codec *codec, #define WM8903_INTERRUPT_STATUS_1_MASK 0x7A #define WM8903_INTERRUPT_POLARITY_1 0x7B #define WM8903_INTERRUPT_CONTROL 0x7E -#define WM8903_CONTROL_INTERFACE_TEST_1 0x81 -#define WM8903_CHARGE_PUMP_TEST_1 0x95 #define WM8903_CLOCK_RATE_TEST_4 0xA4 #define WM8903_ANALOGUE_OUTPUT_BIAS_0 0xAC @@ -1202,23 +1200,6 @@ extern int wm8903_mic_detect(struct snd_soc_codec *codec, #define WM8903_IRQ_POL_WIDTH 1 /* IRQ_POL */ /* - * R129 (0x81) - Control Interface Test 1 - */ -#define WM8903_USER_KEY 0x0002 /* USER_KEY */ -#define WM8903_USER_KEY_MASK 0x0002 /* USER_KEY */ -#define WM8903_USER_KEY_SHIFT 1 /* USER_KEY */ -#define WM8903_USER_KEY_WIDTH 1 /* USER_KEY */ -#define WM8903_TEST_KEY 0x0001 /* TEST_KEY */ -#define WM8903_TEST_KEY_MASK 0x0001 /* TEST_KEY */ -#define WM8903_TEST_KEY_SHIFT 0 /* TEST_KEY */ -#define WM8903_TEST_KEY_WIDTH 1 /* TEST_KEY */ - -/* - * R149 (0x95) - Charge Pump Test 1 - */ -#define WM8903_CP_SW_KELVIN_MODE_MASK 0x0006 /* CP_SW_KELVIN_MODE - [2:1] */ -#define WM8903_CP_SW_KELVIN_MODE_SHIFT 1 /* CP_SW_KELVIN_MODE - [2:1] */ -#define WM8903_CP_SW_KELVIN_MODE_WIDTH 2 /* CP_SW_KELVIN_MODE - [2:1] */ /* * R164 (0xA4) - Clock Rate Test 4 -- cgit v1.2.3 From 617eecdb3d51624afca3be546b72fe80d8708370 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 23 Dec 2010 12:03:07 +0000 Subject: ASoC: Remove WM8995 write sequencer bitfield definitions They're very verbose and extremely repetitive so bulk up the kernel more than is ideal. If required we can readd with WRITE_SEQUENCER_n type definitions that cover the entire register bank in a few defines. Signed-off-by: Mark Brown Acked-by: Liam Girdwood --- sound/soc/codecs/wm8995.h | 4480 --------------------------------------------- 1 file changed, 4480 deletions(-) diff --git a/sound/soc/codecs/wm8995.h b/sound/soc/codecs/wm8995.h index 6409e5a6b574..5642121c4977 100644 --- a/sound/soc/codecs/wm8995.h +++ b/sound/soc/codecs/wm8995.h @@ -4236,4486 +4236,6 @@ #define WM8995_SPK2_MUTE_SEQ1_SHIFT 0 /* SPK2_MUTE_SEQ1 - [7:0] */ #define WM8995_SPK2_MUTE_SEQ1_WIDTH 8 /* SPK2_MUTE_SEQ1 - [7:0] */ -/* - * R12288 (0x3000) - Write Sequencer 0 - */ -#define WM8995_WSEQ_ADDR0_MASK 0x3FFF /* WSEQ_ADDR0 - [13:0] */ -#define WM8995_WSEQ_ADDR0_SHIFT 0 /* WSEQ_ADDR0 - [13:0] */ -#define WM8995_WSEQ_ADDR0_WIDTH 14 /* WSEQ_ADDR0 - [13:0] */ - -/* - * R12289 (0x3001) - Write Sequencer 1 - */ -#define WM8995_WSEQ_DATA0_MASK 0x00FF /* WSEQ_DATA0 - [7:0] */ -#define WM8995_WSEQ_DATA0_SHIFT 0 /* WSEQ_DATA0 - [7:0] */ -#define WM8995_WSEQ_DATA0_WIDTH 8 /* WSEQ_DATA0 - [7:0] */ - -/* - * R12290 (0x3002) - Write Sequencer 2 - */ -#define WM8995_WSEQ_DATA_WIDTH0_MASK 0x0700 /* WSEQ_DATA_WIDTH0 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH0_SHIFT 8 /* WSEQ_DATA_WIDTH0 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH0_WIDTH 3 /* WSEQ_DATA_WIDTH0 - [10:8] */ -#define WM8995_WSEQ_DATA_START0_MASK 0x000F /* WSEQ_DATA_START0 - [3:0] */ -#define WM8995_WSEQ_DATA_START0_SHIFT 0 /* WSEQ_DATA_START0 - [3:0] */ -#define WM8995_WSEQ_DATA_START0_WIDTH 4 /* WSEQ_DATA_START0 - [3:0] */ - -/* - * R12291 (0x3003) - Write Sequencer 3 - */ -#define WM8995_WSEQ_EOS0 0x0100 /* WSEQ_EOS0 */ -#define WM8995_WSEQ_EOS0_MASK 0x0100 /* WSEQ_EOS0 */ -#define WM8995_WSEQ_EOS0_SHIFT 8 /* WSEQ_EOS0 */ -#define WM8995_WSEQ_EOS0_WIDTH 1 /* WSEQ_EOS0 */ -#define WM8995_WSEQ_DELAY0_MASK 0x000F /* WSEQ_DELAY0 - [3:0] */ -#define WM8995_WSEQ_DELAY0_SHIFT 0 /* WSEQ_DELAY0 - [3:0] */ -#define WM8995_WSEQ_DELAY0_WIDTH 4 /* WSEQ_DELAY0 - [3:0] */ - -/* - * R12292 (0x3004) - Write Sequencer 4 - */ -#define WM8995_WSEQ_ADDR1_MASK 0x3FFF /* WSEQ_ADDR1 - [13:0] */ -#define WM8995_WSEQ_ADDR1_SHIFT 0 /* WSEQ_ADDR1 - [13:0] */ -#define WM8995_WSEQ_ADDR1_WIDTH 14 /* WSEQ_ADDR1 - [13:0] */ - -/* - * R12293 (0x3005) - Write Sequencer 5 - */ -#define WM8995_WSEQ_DATA1_MASK 0x00FF /* WSEQ_DATA1 - [7:0] */ -#define WM8995_WSEQ_DATA1_SHIFT 0 /* WSEQ_DATA1 - [7:0] */ -#define WM8995_WSEQ_DATA1_WIDTH 8 /* WSEQ_DATA1 - [7:0] */ - -/* - * R12294 (0x3006) - Write Sequencer 6 - */ -#define WM8995_WSEQ_DATA_WIDTH1_MASK 0x0700 /* WSEQ_DATA_WIDTH1 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH1_SHIFT 8 /* WSEQ_DATA_WIDTH1 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH1_WIDTH 3 /* WSEQ_DATA_WIDTH1 - [10:8] */ -#define WM8995_WSEQ_DATA_START1_MASK 0x000F /* WSEQ_DATA_START1 - [3:0] */ -#define WM8995_WSEQ_DATA_START1_SHIFT 0 /* WSEQ_DATA_START1 - [3:0] */ -#define WM8995_WSEQ_DATA_START1_WIDTH 4 /* WSEQ_DATA_START1 - [3:0] */ - -/* - * R12295 (0x3007) - Write Sequencer 7 - */ -#define WM8995_WSEQ_EOS1 0x0100 /* WSEQ_EOS1 */ -#define WM8995_WSEQ_EOS1_MASK 0x0100 /* WSEQ_EOS1 */ -#define WM8995_WSEQ_EOS1_SHIFT 8 /* WSEQ_EOS1 */ -#define WM8995_WSEQ_EOS1_WIDTH 1 /* WSEQ_EOS1 */ -#define WM8995_WSEQ_DELAY1_MASK 0x000F /* WSEQ_DELAY1 - [3:0] */ -#define WM8995_WSEQ_DELAY1_SHIFT 0 /* WSEQ_DELAY1 - [3:0] */ -#define WM8995_WSEQ_DELAY1_WIDTH 4 /* WSEQ_DELAY1 - [3:0] */ - -/* - * R12296 (0x3008) - Write Sequencer 8 - */ -#define WM8995_WSEQ_ADDR2_MASK 0x3FFF /* WSEQ_ADDR2 - [13:0] */ -#define WM8995_WSEQ_ADDR2_SHIFT 0 /* WSEQ_ADDR2 - [13:0] */ -#define WM8995_WSEQ_ADDR2_WIDTH 14 /* WSEQ_ADDR2 - [13:0] */ - -/* - * R12297 (0x3009) - Write Sequencer 9 - */ -#define WM8995_WSEQ_DATA2_MASK 0x00FF /* WSEQ_DATA2 - [7:0] */ -#define WM8995_WSEQ_DATA2_SHIFT 0 /* WSEQ_DATA2 - [7:0] */ -#define WM8995_WSEQ_DATA2_WIDTH 8 /* WSEQ_DATA2 - [7:0] */ - -/* - * R12298 (0x300A) - Write Sequencer 10 - */ -#define WM8995_WSEQ_DATA_WIDTH2_MASK 0x0700 /* WSEQ_DATA_WIDTH2 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH2_SHIFT 8 /* WSEQ_DATA_WIDTH2 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH2_WIDTH 3 /* WSEQ_DATA_WIDTH2 - [10:8] */ -#define WM8995_WSEQ_DATA_START2_MASK 0x000F /* WSEQ_DATA_START2 - [3:0] */ -#define WM8995_WSEQ_DATA_START2_SHIFT 0 /* WSEQ_DATA_START2 - [3:0] */ -#define WM8995_WSEQ_DATA_START2_WIDTH 4 /* WSEQ_DATA_START2 - [3:0] */ - -/* - * R12299 (0x300B) - Write Sequencer 11 - */ -#define WM8995_WSEQ_EOS2 0x0100 /* WSEQ_EOS2 */ -#define WM8995_WSEQ_EOS2_MASK 0x0100 /* WSEQ_EOS2 */ -#define WM8995_WSEQ_EOS2_SHIFT 8 /* WSEQ_EOS2 */ -#define WM8995_WSEQ_EOS2_WIDTH 1 /* WSEQ_EOS2 */ -#define WM8995_WSEQ_DELAY2_MASK 0x000F /* WSEQ_DELAY2 - [3:0] */ -#define WM8995_WSEQ_DELAY2_SHIFT 0 /* WSEQ_DELAY2 - [3:0] */ -#define WM8995_WSEQ_DELAY2_WIDTH 4 /* WSEQ_DELAY2 - [3:0] */ - -/* - * R12300 (0x300C) - Write Sequencer 12 - */ -#define WM8995_WSEQ_ADDR3_MASK 0x3FFF /* WSEQ_ADDR3 - [13:0] */ -#define WM8995_WSEQ_ADDR3_SHIFT 0 /* WSEQ_ADDR3 - [13:0] */ -#define WM8995_WSEQ_ADDR3_WIDTH 14 /* WSEQ_ADDR3 - [13:0] */ - -/* - * R12301 (0x300D) - Write Sequencer 13 - */ -#define WM8995_WSEQ_DATA3_MASK 0x00FF /* WSEQ_DATA3 - [7:0] */ -#define WM8995_WSEQ_DATA3_SHIFT 0 /* WSEQ_DATA3 - [7:0] */ -#define WM8995_WSEQ_DATA3_WIDTH 8 /* WSEQ_DATA3 - [7:0] */ - -/* - * R12302 (0x300E) - Write Sequencer 14 - */ -#define WM8995_WSEQ_DATA_WIDTH3_MASK 0x0700 /* WSEQ_DATA_WIDTH3 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH3_SHIFT 8 /* WSEQ_DATA_WIDTH3 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH3_WIDTH 3 /* WSEQ_DATA_WIDTH3 - [10:8] */ -#define WM8995_WSEQ_DATA_START3_MASK 0x000F /* WSEQ_DATA_START3 - [3:0] */ -#define WM8995_WSEQ_DATA_START3_SHIFT 0 /* WSEQ_DATA_START3 - [3:0] */ -#define WM8995_WSEQ_DATA_START3_WIDTH 4 /* WSEQ_DATA_START3 - [3:0] */ - -/* - * R12303 (0x300F) - Write Sequencer 15 - */ -#define WM8995_WSEQ_EOS3 0x0100 /* WSEQ_EOS3 */ -#define WM8995_WSEQ_EOS3_MASK 0x0100 /* WSEQ_EOS3 */ -#define WM8995_WSEQ_EOS3_SHIFT 8 /* WSEQ_EOS3 */ -#define WM8995_WSEQ_EOS3_WIDTH 1 /* WSEQ_EOS3 */ -#define WM8995_WSEQ_DELAY3_MASK 0x000F /* WSEQ_DELAY3 - [3:0] */ -#define WM8995_WSEQ_DELAY3_SHIFT 0 /* WSEQ_DELAY3 - [3:0] */ -#define WM8995_WSEQ_DELAY3_WIDTH 4 /* WSEQ_DELAY3 - [3:0] */ - -/* - * R12304 (0x3010) - Write Sequencer 16 - */ -#define WM8995_WSEQ_ADDR4_MASK 0x3FFF /* WSEQ_ADDR4 - [13:0] */ -#define WM8995_WSEQ_ADDR4_SHIFT 0 /* WSEQ_ADDR4 - [13:0] */ -#define WM8995_WSEQ_ADDR4_WIDTH 14 /* WSEQ_ADDR4 - [13:0] */ - -/* - * R12305 (0x3011) - Write Sequencer 17 - */ -#define WM8995_WSEQ_DATA4_MASK 0x00FF /* WSEQ_DATA4 - [7:0] */ -#define WM8995_WSEQ_DATA4_SHIFT 0 /* WSEQ_DATA4 - [7:0] */ -#define WM8995_WSEQ_DATA4_WIDTH 8 /* WSEQ_DATA4 - [7:0] */ - -/* - * R12306 (0x3012) - Write Sequencer 18 - */ -#define WM8995_WSEQ_DATA_WIDTH4_MASK 0x0700 /* WSEQ_DATA_WIDTH4 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH4_SHIFT 8 /* WSEQ_DATA_WIDTH4 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH4_WIDTH 3 /* WSEQ_DATA_WIDTH4 - [10:8] */ -#define WM8995_WSEQ_DATA_START4_MASK 0x000F /* WSEQ_DATA_START4 - [3:0] */ -#define WM8995_WSEQ_DATA_START4_SHIFT 0 /* WSEQ_DATA_START4 - [3:0] */ -#define WM8995_WSEQ_DATA_START4_WIDTH 4 /* WSEQ_DATA_START4 - [3:0] */ - -/* - * R12307 (0x3013) - Write Sequencer 19 - */ -#define WM8995_WSEQ_EOS4 0x0100 /* WSEQ_EOS4 */ -#define WM8995_WSEQ_EOS4_MASK 0x0100 /* WSEQ_EOS4 */ -#define WM8995_WSEQ_EOS4_SHIFT 8 /* WSEQ_EOS4 */ -#define WM8995_WSEQ_EOS4_WIDTH 1 /* WSEQ_EOS4 */ -#define WM8995_WSEQ_DELAY4_MASK 0x000F /* WSEQ_DELAY4 - [3:0] */ -#define WM8995_WSEQ_DELAY4_SHIFT 0 /* WSEQ_DELAY4 - [3:0] */ -#define WM8995_WSEQ_DELAY4_WIDTH 4 /* WSEQ_DELAY4 - [3:0] */ - -/* - * R12308 (0x3014) - Write Sequencer 20 - */ -#define WM8995_WSEQ_ADDR5_MASK 0x3FFF /* WSEQ_ADDR5 - [13:0] */ -#define WM8995_WSEQ_ADDR5_SHIFT 0 /* WSEQ_ADDR5 - [13:0] */ -#define WM8995_WSEQ_ADDR5_WIDTH 14 /* WSEQ_ADDR5 - [13:0] */ - -/* - * R12309 (0x3015) - Write Sequencer 21 - */ -#define WM8995_WSEQ_DATA5_MASK 0x00FF /* WSEQ_DATA5 - [7:0] */ -#define WM8995_WSEQ_DATA5_SHIFT 0 /* WSEQ_DATA5 - [7:0] */ -#define WM8995_WSEQ_DATA5_WIDTH 8 /* WSEQ_DATA5 - [7:0] */ - -/* - * R12310 (0x3016) - Write Sequencer 22 - */ -#define WM8995_WSEQ_DATA_WIDTH5_MASK 0x0700 /* WSEQ_DATA_WIDTH5 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH5_SHIFT 8 /* WSEQ_DATA_WIDTH5 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH5_WIDTH 3 /* WSEQ_DATA_WIDTH5 - [10:8] */ -#define WM8995_WSEQ_DATA_START5_MASK 0x000F /* WSEQ_DATA_START5 - [3:0] */ -#define WM8995_WSEQ_DATA_START5_SHIFT 0 /* WSEQ_DATA_START5 - [3:0] */ -#define WM8995_WSEQ_DATA_START5_WIDTH 4 /* WSEQ_DATA_START5 - [3:0] */ - -/* - * R12311 (0x3017) - Write Sequencer 23 - */ -#define WM8995_WSEQ_EOS5 0x0100 /* WSEQ_EOS5 */ -#define WM8995_WSEQ_EOS5_MASK 0x0100 /* WSEQ_EOS5 */ -#define WM8995_WSEQ_EOS5_SHIFT 8 /* WSEQ_EOS5 */ -#define WM8995_WSEQ_EOS5_WIDTH 1 /* WSEQ_EOS5 */ -#define WM8995_WSEQ_DELAY5_MASK 0x000F /* WSEQ_DELAY5 - [3:0] */ -#define WM8995_WSEQ_DELAY5_SHIFT 0 /* WSEQ_DELAY5 - [3:0] */ -#define WM8995_WSEQ_DELAY5_WIDTH 4 /* WSEQ_DELAY5 - [3:0] */ - -/* - * R12312 (0x3018) - Write Sequencer 24 - */ -#define WM8995_WSEQ_ADDR6_MASK 0x3FFF /* WSEQ_ADDR6 - [13:0] */ -#define WM8995_WSEQ_ADDR6_SHIFT 0 /* WSEQ_ADDR6 - [13:0] */ -#define WM8995_WSEQ_ADDR6_WIDTH 14 /* WSEQ_ADDR6 - [13:0] */ - -/* - * R12313 (0x3019) - Write Sequencer 25 - */ -#define WM8995_WSEQ_DATA6_MASK 0x00FF /* WSEQ_DATA6 - [7:0] */ -#define WM8995_WSEQ_DATA6_SHIFT 0 /* WSEQ_DATA6 - [7:0] */ -#define WM8995_WSEQ_DATA6_WIDTH 8 /* WSEQ_DATA6 - [7:0] */ - -/* - * R12314 (0x301A) - Write Sequencer 26 - */ -#define WM8995_WSEQ_DATA_WIDTH6_MASK 0x0700 /* WSEQ_DATA_WIDTH6 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH6_SHIFT 8 /* WSEQ_DATA_WIDTH6 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH6_WIDTH 3 /* WSEQ_DATA_WIDTH6 - [10:8] */ -#define WM8995_WSEQ_DATA_START6_MASK 0x000F /* WSEQ_DATA_START6 - [3:0] */ -#define WM8995_WSEQ_DATA_START6_SHIFT 0 /* WSEQ_DATA_START6 - [3:0] */ -#define WM8995_WSEQ_DATA_START6_WIDTH 4 /* WSEQ_DATA_START6 - [3:0] */ - -/* - * R12315 (0x301B) - Write Sequencer 27 - */ -#define WM8995_WSEQ_EOS6 0x0100 /* WSEQ_EOS6 */ -#define WM8995_WSEQ_EOS6_MASK 0x0100 /* WSEQ_EOS6 */ -#define WM8995_WSEQ_EOS6_SHIFT 8 /* WSEQ_EOS6 */ -#define WM8995_WSEQ_EOS6_WIDTH 1 /* WSEQ_EOS6 */ -#define WM8995_WSEQ_DELAY6_MASK 0x000F /* WSEQ_DELAY6 - [3:0] */ -#define WM8995_WSEQ_DELAY6_SHIFT 0 /* WSEQ_DELAY6 - [3:0] */ -#define WM8995_WSEQ_DELAY6_WIDTH 4 /* WSEQ_DELAY6 - [3:0] */ - -/* - * R12316 (0x301C) - Write Sequencer 28 - */ -#define WM8995_WSEQ_ADDR7_MASK 0x3FFF /* WSEQ_ADDR7 - [13:0] */ -#define WM8995_WSEQ_ADDR7_SHIFT 0 /* WSEQ_ADDR7 - [13:0] */ -#define WM8995_WSEQ_ADDR7_WIDTH 14 /* WSEQ_ADDR7 - [13:0] */ - -/* - * R12317 (0x301D) - Write Sequencer 29 - */ -#define WM8995_WSEQ_DATA7_MASK 0x00FF /* WSEQ_DATA7 - [7:0] */ -#define WM8995_WSEQ_DATA7_SHIFT 0 /* WSEQ_DATA7 - [7:0] */ -#define WM8995_WSEQ_DATA7_WIDTH 8 /* WSEQ_DATA7 - [7:0] */ - -/* - * R12318 (0x301E) - Write Sequencer 30 - */ -#define WM8995_WSEQ_DATA_WIDTH7_MASK 0x0700 /* WSEQ_DATA_WIDTH7 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH7_SHIFT 8 /* WSEQ_DATA_WIDTH7 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH7_WIDTH 3 /* WSEQ_DATA_WIDTH7 - [10:8] */ -#define WM8995_WSEQ_DATA_START7_MASK 0x000F /* WSEQ_DATA_START7 - [3:0] */ -#define WM8995_WSEQ_DATA_START7_SHIFT 0 /* WSEQ_DATA_START7 - [3:0] */ -#define WM8995_WSEQ_DATA_START7_WIDTH 4 /* WSEQ_DATA_START7 - [3:0] */ - -/* - * R12319 (0x301F) - Write Sequencer 31 - */ -#define WM8995_WSEQ_EOS7 0x0100 /* WSEQ_EOS7 */ -#define WM8995_WSEQ_EOS7_MASK 0x0100 /* WSEQ_EOS7 */ -#define WM8995_WSEQ_EOS7_SHIFT 8 /* WSEQ_EOS7 */ -#define WM8995_WSEQ_EOS7_WIDTH 1 /* WSEQ_EOS7 */ -#define WM8995_WSEQ_DELAY7_MASK 0x000F /* WSEQ_DELAY7 - [3:0] */ -#define WM8995_WSEQ_DELAY7_SHIFT 0 /* WSEQ_DELAY7 - [3:0] */ -#define WM8995_WSEQ_DELAY7_WIDTH 4 /* WSEQ_DELAY7 - [3:0] */ - -/* - * R12320 (0x3020) - Write Sequencer 32 - */ -#define WM8995_WSEQ_ADDR8_MASK 0x3FFF /* WSEQ_ADDR8 - [13:0] */ -#define WM8995_WSEQ_ADDR8_SHIFT 0 /* WSEQ_ADDR8 - [13:0] */ -#define WM8995_WSEQ_ADDR8_WIDTH 14 /* WSEQ_ADDR8 - [13:0] */ - -/* - * R12321 (0x3021) - Write Sequencer 33 - */ -#define WM8995_WSEQ_DATA8_MASK 0x00FF /* WSEQ_DATA8 - [7:0] */ -#define WM8995_WSEQ_DATA8_SHIFT 0 /* WSEQ_DATA8 - [7:0] */ -#define WM8995_WSEQ_DATA8_WIDTH 8 /* WSEQ_DATA8 - [7:0] */ - -/* - * R12322 (0x3022) - Write Sequencer 34 - */ -#define WM8995_WSEQ_DATA_WIDTH8_MASK 0x0700 /* WSEQ_DATA_WIDTH8 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH8_SHIFT 8 /* WSEQ_DATA_WIDTH8 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH8_WIDTH 3 /* WSEQ_DATA_WIDTH8 - [10:8] */ -#define WM8995_WSEQ_DATA_START8_MASK 0x000F /* WSEQ_DATA_START8 - [3:0] */ -#define WM8995_WSEQ_DATA_START8_SHIFT 0 /* WSEQ_DATA_START8 - [3:0] */ -#define WM8995_WSEQ_DATA_START8_WIDTH 4 /* WSEQ_DATA_START8 - [3:0] */ - -/* - * R12323 (0x3023) - Write Sequencer 35 - */ -#define WM8995_WSEQ_EOS8 0x0100 /* WSEQ_EOS8 */ -#define WM8995_WSEQ_EOS8_MASK 0x0100 /* WSEQ_EOS8 */ -#define WM8995_WSEQ_EOS8_SHIFT 8 /* WSEQ_EOS8 */ -#define WM8995_WSEQ_EOS8_WIDTH 1 /* WSEQ_EOS8 */ -#define WM8995_WSEQ_DELAY8_MASK 0x000F /* WSEQ_DELAY8 - [3:0] */ -#define WM8995_WSEQ_DELAY8_SHIFT 0 /* WSEQ_DELAY8 - [3:0] */ -#define WM8995_WSEQ_DELAY8_WIDTH 4 /* WSEQ_DELAY8 - [3:0] */ - -/* - * R12324 (0x3024) - Write Sequencer 36 - */ -#define WM8995_WSEQ_ADDR9_MASK 0x3FFF /* WSEQ_ADDR9 - [13:0] */ -#define WM8995_WSEQ_ADDR9_SHIFT 0 /* WSEQ_ADDR9 - [13:0] */ -#define WM8995_WSEQ_ADDR9_WIDTH 14 /* WSEQ_ADDR9 - [13:0] */ - -/* - * R12325 (0x3025) - Write Sequencer 37 - */ -#define WM8995_WSEQ_DATA9_MASK 0x00FF /* WSEQ_DATA9 - [7:0] */ -#define WM8995_WSEQ_DATA9_SHIFT 0 /* WSEQ_DATA9 - [7:0] */ -#define WM8995_WSEQ_DATA9_WIDTH 8 /* WSEQ_DATA9 - [7:0] */ - -/* - * R12326 (0x3026) - Write Sequencer 38 - */ -#define WM8995_WSEQ_DATA_WIDTH9_MASK 0x0700 /* WSEQ_DATA_WIDTH9 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH9_SHIFT 8 /* WSEQ_DATA_WIDTH9 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH9_WIDTH 3 /* WSEQ_DATA_WIDTH9 - [10:8] */ -#define WM8995_WSEQ_DATA_START9_MASK 0x000F /* WSEQ_DATA_START9 - [3:0] */ -#define WM8995_WSEQ_DATA_START9_SHIFT 0 /* WSEQ_DATA_START9 - [3:0] */ -#define WM8995_WSEQ_DATA_START9_WIDTH 4 /* WSEQ_DATA_START9 - [3:0] */ - -/* - * R12327 (0x3027) - Write Sequencer 39 - */ -#define WM8995_WSEQ_EOS9 0x0100 /* WSEQ_EOS9 */ -#define WM8995_WSEQ_EOS9_MASK 0x0100 /* WSEQ_EOS9 */ -#define WM8995_WSEQ_EOS9_SHIFT 8 /* WSEQ_EOS9 */ -#define WM8995_WSEQ_EOS9_WIDTH 1 /* WSEQ_EOS9 */ -#define WM8995_WSEQ_DELAY9_MASK 0x000F /* WSEQ_DELAY9 - [3:0] */ -#define WM8995_WSEQ_DELAY9_SHIFT 0 /* WSEQ_DELAY9 - [3:0] */ -#define WM8995_WSEQ_DELAY9_WIDTH 4 /* WSEQ_DELAY9 - [3:0] */ - -/* - * R12328 (0x3028) - Write Sequencer 40 - */ -#define WM8995_WSEQ_ADDR10_MASK 0x3FFF /* WSEQ_ADDR10 - [13:0] */ -#define WM8995_WSEQ_ADDR10_SHIFT 0 /* WSEQ_ADDR10 - [13:0] */ -#define WM8995_WSEQ_ADDR10_WIDTH 14 /* WSEQ_ADDR10 - [13:0] */ - -/* - * R12329 (0x3029) - Write Sequencer 41 - */ -#define WM8995_WSEQ_DATA10_MASK 0x00FF /* WSEQ_DATA10 - [7:0] */ -#define WM8995_WSEQ_DATA10_SHIFT 0 /* WSEQ_DATA10 - [7:0] */ -#define WM8995_WSEQ_DATA10_WIDTH 8 /* WSEQ_DATA10 - [7:0] */ - -/* - * R12330 (0x302A) - Write Sequencer 42 - */ -#define WM8995_WSEQ_DATA_WIDTH10_MASK 0x0700 /* WSEQ_DATA_WIDTH10 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH10_SHIFT 8 /* WSEQ_DATA_WIDTH10 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH10_WIDTH 3 /* WSEQ_DATA_WIDTH10 - [10:8] */ -#define WM8995_WSEQ_DATA_START10_MASK 0x000F /* WSEQ_DATA_START10 - [3:0] */ -#define WM8995_WSEQ_DATA_START10_SHIFT 0 /* WSEQ_DATA_START10 - [3:0] */ -#define WM8995_WSEQ_DATA_START10_WIDTH 4 /* WSEQ_DATA_START10 - [3:0] */ - -/* - * R12331 (0x302B) - Write Sequencer 43 - */ -#define WM8995_WSEQ_EOS10 0x0100 /* WSEQ_EOS10 */ -#define WM8995_WSEQ_EOS10_MASK 0x0100 /* WSEQ_EOS10 */ -#define WM8995_WSEQ_EOS10_SHIFT 8 /* WSEQ_EOS10 */ -#define WM8995_WSEQ_EOS10_WIDTH 1 /* WSEQ_EOS10 */ -#define WM8995_WSEQ_DELAY10_MASK 0x000F /* WSEQ_DELAY10 - [3:0] */ -#define WM8995_WSEQ_DELAY10_SHIFT 0 /* WSEQ_DELAY10 - [3:0] */ -#define WM8995_WSEQ_DELAY10_WIDTH 4 /* WSEQ_DELAY10 - [3:0] */ - -/* - * R12332 (0x302C) - Write Sequencer 44 - */ -#define WM8995_WSEQ_ADDR11_MASK 0x3FFF /* WSEQ_ADDR11 - [13:0] */ -#define WM8995_WSEQ_ADDR11_SHIFT 0 /* WSEQ_ADDR11 - [13:0] */ -#define WM8995_WSEQ_ADDR11_WIDTH 14 /* WSEQ_ADDR11 - [13:0] */ - -/* - * R12333 (0x302D) - Write Sequencer 45 - */ -#define WM8995_WSEQ_DATA11_MASK 0x00FF /* WSEQ_DATA11 - [7:0] */ -#define WM8995_WSEQ_DATA11_SHIFT 0 /* WSEQ_DATA11 - [7:0] */ -#define WM8995_WSEQ_DATA11_WIDTH 8 /* WSEQ_DATA11 - [7:0] */ - -/* - * R12334 (0x302E) - Write Sequencer 46 - */ -#define WM8995_WSEQ_DATA_WIDTH11_MASK 0x0700 /* WSEQ_DATA_WIDTH11 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH11_SHIFT 8 /* WSEQ_DATA_WIDTH11 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH11_WIDTH 3 /* WSEQ_DATA_WIDTH11 - [10:8] */ -#define WM8995_WSEQ_DATA_START11_MASK 0x000F /* WSEQ_DATA_START11 - [3:0] */ -#define WM8995_WSEQ_DATA_START11_SHIFT 0 /* WSEQ_DATA_START11 - [3:0] */ -#define WM8995_WSEQ_DATA_START11_WIDTH 4 /* WSEQ_DATA_START11 - [3:0] */ - -/* - * R12335 (0x302F) - Write Sequencer 47 - */ -#define WM8995_WSEQ_EOS11 0x0100 /* WSEQ_EOS11 */ -#define WM8995_WSEQ_EOS11_MASK 0x0100 /* WSEQ_EOS11 */ -#define WM8995_WSEQ_EOS11_SHIFT 8 /* WSEQ_EOS11 */ -#define WM8995_WSEQ_EOS11_WIDTH 1 /* WSEQ_EOS11 */ -#define WM8995_WSEQ_DELAY11_MASK 0x000F /* WSEQ_DELAY11 - [3:0] */ -#define WM8995_WSEQ_DELAY11_SHIFT 0 /* WSEQ_DELAY11 - [3:0] */ -#define WM8995_WSEQ_DELAY11_WIDTH 4 /* WSEQ_DELAY11 - [3:0] */ - -/* - * R12336 (0x3030) - Write Sequencer 48 - */ -#define WM8995_WSEQ_ADDR12_MASK 0x3FFF /* WSEQ_ADDR12 - [13:0] */ -#define WM8995_WSEQ_ADDR12_SHIFT 0 /* WSEQ_ADDR12 - [13:0] */ -#define WM8995_WSEQ_ADDR12_WIDTH 14 /* WSEQ_ADDR12 - [13:0] */ - -/* - * R12337 (0x3031) - Write Sequencer 49 - */ -#define WM8995_WSEQ_DATA12_MASK 0x00FF /* WSEQ_DATA12 - [7:0] */ -#define WM8995_WSEQ_DATA12_SHIFT 0 /* WSEQ_DATA12 - [7:0] */ -#define WM8995_WSEQ_DATA12_WIDTH 8 /* WSEQ_DATA12 - [7:0] */ - -/* - * R12338 (0x3032) - Write Sequencer 50 - */ -#define WM8995_WSEQ_DATA_WIDTH12_MASK 0x0700 /* WSEQ_DATA_WIDTH12 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH12_SHIFT 8 /* WSEQ_DATA_WIDTH12 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH12_WIDTH 3 /* WSEQ_DATA_WIDTH12 - [10:8] */ -#define WM8995_WSEQ_DATA_START12_MASK 0x000F /* WSEQ_DATA_START12 - [3:0] */ -#define WM8995_WSEQ_DATA_START12_SHIFT 0 /* WSEQ_DATA_START12 - [3:0] */ -#define WM8995_WSEQ_DATA_START12_WIDTH 4 /* WSEQ_DATA_START12 - [3:0] */ - -/* - * R12339 (0x3033) - Write Sequencer 51 - */ -#define WM8995_WSEQ_EOS12 0x0100 /* WSEQ_EOS12 */ -#define WM8995_WSEQ_EOS12_MASK 0x0100 /* WSEQ_EOS12 */ -#define WM8995_WSEQ_EOS12_SHIFT 8 /* WSEQ_EOS12 */ -#define WM8995_WSEQ_EOS12_WIDTH 1 /* WSEQ_EOS12 */ -#define WM8995_WSEQ_DELAY12_MASK 0x000F /* WSEQ_DELAY12 - [3:0] */ -#define WM8995_WSEQ_DELAY12_SHIFT 0 /* WSEQ_DELAY12 - [3:0] */ -#define WM8995_WSEQ_DELAY12_WIDTH 4 /* WSEQ_DELAY12 - [3:0] */ - -/* - * R12340 (0x3034) - Write Sequencer 52 - */ -#define WM8995_WSEQ_ADDR13_MASK 0x3FFF /* WSEQ_ADDR13 - [13:0] */ -#define WM8995_WSEQ_ADDR13_SHIFT 0 /* WSEQ_ADDR13 - [13:0] */ -#define WM8995_WSEQ_ADDR13_WIDTH 14 /* WSEQ_ADDR13 - [13:0] */ - -/* - * R12341 (0x3035) - Write Sequencer 53 - */ -#define WM8995_WSEQ_DATA13_MASK 0x00FF /* WSEQ_DATA13 - [7:0] */ -#define WM8995_WSEQ_DATA13_SHIFT 0 /* WSEQ_DATA13 - [7:0] */ -#define WM8995_WSEQ_DATA13_WIDTH 8 /* WSEQ_DATA13 - [7:0] */ - -/* - * R12342 (0x3036) - Write Sequencer 54 - */ -#define WM8995_WSEQ_DATA_WIDTH13_MASK 0x0700 /* WSEQ_DATA_WIDTH13 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH13_SHIFT 8 /* WSEQ_DATA_WIDTH13 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH13_WIDTH 3 /* WSEQ_DATA_WIDTH13 - [10:8] */ -#define WM8995_WSEQ_DATA_START13_MASK 0x000F /* WSEQ_DATA_START13 - [3:0] */ -#define WM8995_WSEQ_DATA_START13_SHIFT 0 /* WSEQ_DATA_START13 - [3:0] */ -#define WM8995_WSEQ_DATA_START13_WIDTH 4 /* WSEQ_DATA_START13 - [3:0] */ - -/* - * R12343 (0x3037) - Write Sequencer 55 - */ -#define WM8995_WSEQ_EOS13 0x0100 /* WSEQ_EOS13 */ -#define WM8995_WSEQ_EOS13_MASK 0x0100 /* WSEQ_EOS13 */ -#define WM8995_WSEQ_EOS13_SHIFT 8 /* WSEQ_EOS13 */ -#define WM8995_WSEQ_EOS13_WIDTH 1 /* WSEQ_EOS13 */ -#define WM8995_WSEQ_DELAY13_MASK 0x000F /* WSEQ_DELAY13 - [3:0] */ -#define WM8995_WSEQ_DELAY13_SHIFT 0 /* WSEQ_DELAY13 - [3:0] */ -#define WM8995_WSEQ_DELAY13_WIDTH 4 /* WSEQ_DELAY13 - [3:0] */ - -/* - * R12344 (0x3038) - Write Sequencer 56 - */ -#define WM8995_WSEQ_ADDR14_MASK 0x3FFF /* WSEQ_ADDR14 - [13:0] */ -#define WM8995_WSEQ_ADDR14_SHIFT 0 /* WSEQ_ADDR14 - [13:0] */ -#define WM8995_WSEQ_ADDR14_WIDTH 14 /* WSEQ_ADDR14 - [13:0] */ - -/* - * R12345 (0x3039) - Write Sequencer 57 - */ -#define WM8995_WSEQ_DATA14_MASK 0x00FF /* WSEQ_DATA14 - [7:0] */ -#define WM8995_WSEQ_DATA14_SHIFT 0 /* WSEQ_DATA14 - [7:0] */ -#define WM8995_WSEQ_DATA14_WIDTH 8 /* WSEQ_DATA14 - [7:0] */ - -/* - * R12346 (0x303A) - Write Sequencer 58 - */ -#define WM8995_WSEQ_DATA_WIDTH14_MASK 0x0700 /* WSEQ_DATA_WIDTH14 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH14_SHIFT 8 /* WSEQ_DATA_WIDTH14 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH14_WIDTH 3 /* WSEQ_DATA_WIDTH14 - [10:8] */ -#define WM8995_WSEQ_DATA_START14_MASK 0x000F /* WSEQ_DATA_START14 - [3:0] */ -#define WM8995_WSEQ_DATA_START14_SHIFT 0 /* WSEQ_DATA_START14 - [3:0] */ -#define WM8995_WSEQ_DATA_START14_WIDTH 4 /* WSEQ_DATA_START14 - [3:0] */ - -/* - * R12347 (0x303B) - Write Sequencer 59 - */ -#define WM8995_WSEQ_EOS14 0x0100 /* WSEQ_EOS14 */ -#define WM8995_WSEQ_EOS14_MASK 0x0100 /* WSEQ_EOS14 */ -#define WM8995_WSEQ_EOS14_SHIFT 8 /* WSEQ_EOS14 */ -#define WM8995_WSEQ_EOS14_WIDTH 1 /* WSEQ_EOS14 */ -#define WM8995_WSEQ_DELAY14_MASK 0x000F /* WSEQ_DELAY14 - [3:0] */ -#define WM8995_WSEQ_DELAY14_SHIFT 0 /* WSEQ_DELAY14 - [3:0] */ -#define WM8995_WSEQ_DELAY14_WIDTH 4 /* WSEQ_DELAY14 - [3:0] */ - -/* - * R12348 (0x303C) - Write Sequencer 60 - */ -#define WM8995_WSEQ_ADDR15_MASK 0x3FFF /* WSEQ_ADDR15 - [13:0] */ -#define WM8995_WSEQ_ADDR15_SHIFT 0 /* WSEQ_ADDR15 - [13:0] */ -#define WM8995_WSEQ_ADDR15_WIDTH 14 /* WSEQ_ADDR15 - [13:0] */ - -/* - * R12349 (0x303D) - Write Sequencer 61 - */ -#define WM8995_WSEQ_DATA15_MASK 0x00FF /* WSEQ_DATA15 - [7:0] */ -#define WM8995_WSEQ_DATA15_SHIFT 0 /* WSEQ_DATA15 - [7:0] */ -#define WM8995_WSEQ_DATA15_WIDTH 8 /* WSEQ_DATA15 - [7:0] */ - -/* - * R12350 (0x303E) - Write Sequencer 62 - */ -#define WM8995_WSEQ_DATA_WIDTH15_MASK 0x0700 /* WSEQ_DATA_WIDTH15 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH15_SHIFT 8 /* WSEQ_DATA_WIDTH15 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH15_WIDTH 3 /* WSEQ_DATA_WIDTH15 - [10:8] */ -#define WM8995_WSEQ_DATA_START15_MASK 0x000F /* WSEQ_DATA_START15 - [3:0] */ -#define WM8995_WSEQ_DATA_START15_SHIFT 0 /* WSEQ_DATA_START15 - [3:0] */ -#define WM8995_WSEQ_DATA_START15_WIDTH 4 /* WSEQ_DATA_START15 - [3:0] */ - -/* - * R12351 (0x303F) - Write Sequencer 63 - */ -#define WM8995_WSEQ_EOS15 0x0100 /* WSEQ_EOS15 */ -#define WM8995_WSEQ_EOS15_MASK 0x0100 /* WSEQ_EOS15 */ -#define WM8995_WSEQ_EOS15_SHIFT 8 /* WSEQ_EOS15 */ -#define WM8995_WSEQ_EOS15_WIDTH 1 /* WSEQ_EOS15 */ -#define WM8995_WSEQ_DELAY15_MASK 0x000F /* WSEQ_DELAY15 - [3:0] */ -#define WM8995_WSEQ_DELAY15_SHIFT 0 /* WSEQ_DELAY15 - [3:0] */ -#define WM8995_WSEQ_DELAY15_WIDTH 4 /* WSEQ_DELAY15 - [3:0] */ - -/* - * R12352 (0x3040) - Write Sequencer 64 - */ -#define WM8995_WSEQ_ADDR16_MASK 0x3FFF /* WSEQ_ADDR16 - [13:0] */ -#define WM8995_WSEQ_ADDR16_SHIFT 0 /* WSEQ_ADDR16 - [13:0] */ -#define WM8995_WSEQ_ADDR16_WIDTH 14 /* WSEQ_ADDR16 - [13:0] */ - -/* - * R12353 (0x3041) - Write Sequencer 65 - */ -#define WM8995_WSEQ_DATA16_MASK 0x00FF /* WSEQ_DATA16 - [7:0] */ -#define WM8995_WSEQ_DATA16_SHIFT 0 /* WSEQ_DATA16 - [7:0] */ -#define WM8995_WSEQ_DATA16_WIDTH 8 /* WSEQ_DATA16 - [7:0] */ - -/* - * R12354 (0x3042) - Write Sequencer 66 - */ -#define WM8995_WSEQ_DATA_WIDTH16_MASK 0x0700 /* WSEQ_DATA_WIDTH16 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH16_SHIFT 8 /* WSEQ_DATA_WIDTH16 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH16_WIDTH 3 /* WSEQ_DATA_WIDTH16 - [10:8] */ -#define WM8995_WSEQ_DATA_START16_MASK 0x000F /* WSEQ_DATA_START16 - [3:0] */ -#define WM8995_WSEQ_DATA_START16_SHIFT 0 /* WSEQ_DATA_START16 - [3:0] */ -#define WM8995_WSEQ_DATA_START16_WIDTH 4 /* WSEQ_DATA_START16 - [3:0] */ - -/* - * R12355 (0x3043) - Write Sequencer 67 - */ -#define WM8995_WSEQ_EOS16 0x0100 /* WSEQ_EOS16 */ -#define WM8995_WSEQ_EOS16_MASK 0x0100 /* WSEQ_EOS16 */ -#define WM8995_WSEQ_EOS16_SHIFT 8 /* WSEQ_EOS16 */ -#define WM8995_WSEQ_EOS16_WIDTH 1 /* WSEQ_EOS16 */ -#define WM8995_WSEQ_DELAY16_MASK 0x000F /* WSEQ_DELAY16 - [3:0] */ -#define WM8995_WSEQ_DELAY16_SHIFT 0 /* WSEQ_DELAY16 - [3:0] */ -#define WM8995_WSEQ_DELAY16_WIDTH 4 /* WSEQ_DELAY16 - [3:0] */ - -/* - * R12356 (0x3044) - Write Sequencer 68 - */ -#define WM8995_WSEQ_ADDR17_MASK 0x3FFF /* WSEQ_ADDR17 - [13:0] */ -#define WM8995_WSEQ_ADDR17_SHIFT 0 /* WSEQ_ADDR17 - [13:0] */ -#define WM8995_WSEQ_ADDR17_WIDTH 14 /* WSEQ_ADDR17 - [13:0] */ - -/* - * R12357 (0x3045) - Write Sequencer 69 - */ -#define WM8995_WSEQ_DATA17_MASK 0x00FF /* WSEQ_DATA17 - [7:0] */ -#define WM8995_WSEQ_DATA17_SHIFT 0 /* WSEQ_DATA17 - [7:0] */ -#define WM8995_WSEQ_DATA17_WIDTH 8 /* WSEQ_DATA17 - [7:0] */ - -/* - * R12358 (0x3046) - Write Sequencer 70 - */ -#define WM8995_WSEQ_DATA_WIDTH17_MASK 0x0700 /* WSEQ_DATA_WIDTH17 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH17_SHIFT 8 /* WSEQ_DATA_WIDTH17 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH17_WIDTH 3 /* WSEQ_DATA_WIDTH17 - [10:8] */ -#define WM8995_WSEQ_DATA_START17_MASK 0x000F /* WSEQ_DATA_START17 - [3:0] */ -#define WM8995_WSEQ_DATA_START17_SHIFT 0 /* WSEQ_DATA_START17 - [3:0] */ -#define WM8995_WSEQ_DATA_START17_WIDTH 4 /* WSEQ_DATA_START17 - [3:0] */ - -/* - * R12359 (0x3047) - Write Sequencer 71 - */ -#define WM8995_WSEQ_EOS17 0x0100 /* WSEQ_EOS17 */ -#define WM8995_WSEQ_EOS17_MASK 0x0100 /* WSEQ_EOS17 */ -#define WM8995_WSEQ_EOS17_SHIFT 8 /* WSEQ_EOS17 */ -#define WM8995_WSEQ_EOS17_WIDTH 1 /* WSEQ_EOS17 */ -#define WM8995_WSEQ_DELAY17_MASK 0x000F /* WSEQ_DELAY17 - [3:0] */ -#define WM8995_WSEQ_DELAY17_SHIFT 0 /* WSEQ_DELAY17 - [3:0] */ -#define WM8995_WSEQ_DELAY17_WIDTH 4 /* WSEQ_DELAY17 - [3:0] */ - -/* - * R12360 (0x3048) - Write Sequencer 72 - */ -#define WM8995_WSEQ_ADDR18_MASK 0x3FFF /* WSEQ_ADDR18 - [13:0] */ -#define WM8995_WSEQ_ADDR18_SHIFT 0 /* WSEQ_ADDR18 - [13:0] */ -#define WM8995_WSEQ_ADDR18_WIDTH 14 /* WSEQ_ADDR18 - [13:0] */ - -/* - * R12361 (0x3049) - Write Sequencer 73 - */ -#define WM8995_WSEQ_DATA18_MASK 0x00FF /* WSEQ_DATA18 - [7:0] */ -#define WM8995_WSEQ_DATA18_SHIFT 0 /* WSEQ_DATA18 - [7:0] */ -#define WM8995_WSEQ_DATA18_WIDTH 8 /* WSEQ_DATA18 - [7:0] */ - -/* - * R12362 (0x304A) - Write Sequencer 74 - */ -#define WM8995_WSEQ_DATA_WIDTH18_MASK 0x0700 /* WSEQ_DATA_WIDTH18 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH18_SHIFT 8 /* WSEQ_DATA_WIDTH18 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH18_WIDTH 3 /* WSEQ_DATA_WIDTH18 - [10:8] */ -#define WM8995_WSEQ_DATA_START18_MASK 0x000F /* WSEQ_DATA_START18 - [3:0] */ -#define WM8995_WSEQ_DATA_START18_SHIFT 0 /* WSEQ_DATA_START18 - [3:0] */ -#define WM8995_WSEQ_DATA_START18_WIDTH 4 /* WSEQ_DATA_START18 - [3:0] */ - -/* - * R12363 (0x304B) - Write Sequencer 75 - */ -#define WM8995_WSEQ_EOS18 0x0100 /* WSEQ_EOS18 */ -#define WM8995_WSEQ_EOS18_MASK 0x0100 /* WSEQ_EOS18 */ -#define WM8995_WSEQ_EOS18_SHIFT 8 /* WSEQ_EOS18 */ -#define WM8995_WSEQ_EOS18_WIDTH 1 /* WSEQ_EOS18 */ -#define WM8995_WSEQ_DELAY18_MASK 0x000F /* WSEQ_DELAY18 - [3:0] */ -#define WM8995_WSEQ_DELAY18_SHIFT 0 /* WSEQ_DELAY18 - [3:0] */ -#define WM8995_WSEQ_DELAY18_WIDTH 4 /* WSEQ_DELAY18 - [3:0] */ - -/* - * R12364 (0x304C) - Write Sequencer 76 - */ -#define WM8995_WSEQ_ADDR19_MASK 0x3FFF /* WSEQ_ADDR19 - [13:0] */ -#define WM8995_WSEQ_ADDR19_SHIFT 0 /* WSEQ_ADDR19 - [13:0] */ -#define WM8995_WSEQ_ADDR19_WIDTH 14 /* WSEQ_ADDR19 - [13:0] */ - -/* - * R12365 (0x304D) - Write Sequencer 77 - */ -#define WM8995_WSEQ_DATA19_MASK 0x00FF /* WSEQ_DATA19 - [7:0] */ -#define WM8995_WSEQ_DATA19_SHIFT 0 /* WSEQ_DATA19 - [7:0] */ -#define WM8995_WSEQ_DATA19_WIDTH 8 /* WSEQ_DATA19 - [7:0] */ - -/* - * R12366 (0x304E) - Write Sequencer 78 - */ -#define WM8995_WSEQ_DATA_WIDTH19_MASK 0x0700 /* WSEQ_DATA_WIDTH19 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH19_SHIFT 8 /* WSEQ_DATA_WIDTH19 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH19_WIDTH 3 /* WSEQ_DATA_WIDTH19 - [10:8] */ -#define WM8995_WSEQ_DATA_START19_MASK 0x000F /* WSEQ_DATA_START19 - [3:0] */ -#define WM8995_WSEQ_DATA_START19_SHIFT 0 /* WSEQ_DATA_START19 - [3:0] */ -#define WM8995_WSEQ_DATA_START19_WIDTH 4 /* WSEQ_DATA_START19 - [3:0] */ - -/* - * R12367 (0x304F) - Write Sequencer 79 - */ -#define WM8995_WSEQ_EOS19 0x0100 /* WSEQ_EOS19 */ -#define WM8995_WSEQ_EOS19_MASK 0x0100 /* WSEQ_EOS19 */ -#define WM8995_WSEQ_EOS19_SHIFT 8 /* WSEQ_EOS19 */ -#define WM8995_WSEQ_EOS19_WIDTH 1 /* WSEQ_EOS19 */ -#define WM8995_WSEQ_DELAY19_MASK 0x000F /* WSEQ_DELAY19 - [3:0] */ -#define WM8995_WSEQ_DELAY19_SHIFT 0 /* WSEQ_DELAY19 - [3:0] */ -#define WM8995_WSEQ_DELAY19_WIDTH 4 /* WSEQ_DELAY19 - [3:0] */ - -/* - * R12368 (0x3050) - Write Sequencer 80 - */ -#define WM8995_WSEQ_ADDR20_MASK 0x3FFF /* WSEQ_ADDR20 - [13:0] */ -#define WM8995_WSEQ_ADDR20_SHIFT 0 /* WSEQ_ADDR20 - [13:0] */ -#define WM8995_WSEQ_ADDR20_WIDTH 14 /* WSEQ_ADDR20 - [13:0] */ - -/* - * R12369 (0x3051) - Write Sequencer 81 - */ -#define WM8995_WSEQ_DATA20_MASK 0x00FF /* WSEQ_DATA20 - [7:0] */ -#define WM8995_WSEQ_DATA20_SHIFT 0 /* WSEQ_DATA20 - [7:0] */ -#define WM8995_WSEQ_DATA20_WIDTH 8 /* WSEQ_DATA20 - [7:0] */ - -/* - * R12370 (0x3052) - Write Sequencer 82 - */ -#define WM8995_WSEQ_DATA_WIDTH20_MASK 0x0700 /* WSEQ_DATA_WIDTH20 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH20_SHIFT 8 /* WSEQ_DATA_WIDTH20 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH20_WIDTH 3 /* WSEQ_DATA_WIDTH20 - [10:8] */ -#define WM8995_WSEQ_DATA_START20_MASK 0x000F /* WSEQ_DATA_START20 - [3:0] */ -#define WM8995_WSEQ_DATA_START20_SHIFT 0 /* WSEQ_DATA_START20 - [3:0] */ -#define WM8995_WSEQ_DATA_START20_WIDTH 4 /* WSEQ_DATA_START20 - [3:0] */ - -/* - * R12371 (0x3053) - Write Sequencer 83 - */ -#define WM8995_WSEQ_EOS20 0x0100 /* WSEQ_EOS20 */ -#define WM8995_WSEQ_EOS20_MASK 0x0100 /* WSEQ_EOS20 */ -#define WM8995_WSEQ_EOS20_SHIFT 8 /* WSEQ_EOS20 */ -#define WM8995_WSEQ_EOS20_WIDTH 1 /* WSEQ_EOS20 */ -#define WM8995_WSEQ_DELAY20_MASK 0x000F /* WSEQ_DELAY20 - [3:0] */ -#define WM8995_WSEQ_DELAY20_SHIFT 0 /* WSEQ_DELAY20 - [3:0] */ -#define WM8995_WSEQ_DELAY20_WIDTH 4 /* WSEQ_DELAY20 - [3:0] */ - -/* - * R12372 (0x3054) - Write Sequencer 84 - */ -#define WM8995_WSEQ_ADDR21_MASK 0x3FFF /* WSEQ_ADDR21 - [13:0] */ -#define WM8995_WSEQ_ADDR21_SHIFT 0 /* WSEQ_ADDR21 - [13:0] */ -#define WM8995_WSEQ_ADDR21_WIDTH 14 /* WSEQ_ADDR21 - [13:0] */ - -/* - * R12373 (0x3055) - Write Sequencer 85 - */ -#define WM8995_WSEQ_DATA21_MASK 0x00FF /* WSEQ_DATA21 - [7:0] */ -#define WM8995_WSEQ_DATA21_SHIFT 0 /* WSEQ_DATA21 - [7:0] */ -#define WM8995_WSEQ_DATA21_WIDTH 8 /* WSEQ_DATA21 - [7:0] */ - -/* - * R12374 (0x3056) - Write Sequencer 86 - */ -#define WM8995_WSEQ_DATA_WIDTH21_MASK 0x0700 /* WSEQ_DATA_WIDTH21 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH21_SHIFT 8 /* WSEQ_DATA_WIDTH21 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH21_WIDTH 3 /* WSEQ_DATA_WIDTH21 - [10:8] */ -#define WM8995_WSEQ_DATA_START21_MASK 0x000F /* WSEQ_DATA_START21 - [3:0] */ -#define WM8995_WSEQ_DATA_START21_SHIFT 0 /* WSEQ_DATA_START21 - [3:0] */ -#define WM8995_WSEQ_DATA_START21_WIDTH 4 /* WSEQ_DATA_START21 - [3:0] */ - -/* - * R12375 (0x3057) - Write Sequencer 87 - */ -#define WM8995_WSEQ_EOS21 0x0100 /* WSEQ_EOS21 */ -#define WM8995_WSEQ_EOS21_MASK 0x0100 /* WSEQ_EOS21 */ -#define WM8995_WSEQ_EOS21_SHIFT 8 /* WSEQ_EOS21 */ -#define WM8995_WSEQ_EOS21_WIDTH 1 /* WSEQ_EOS21 */ -#define WM8995_WSEQ_DELAY21_MASK 0x000F /* WSEQ_DELAY21 - [3:0] */ -#define WM8995_WSEQ_DELAY21_SHIFT 0 /* WSEQ_DELAY21 - [3:0] */ -#define WM8995_WSEQ_DELAY21_WIDTH 4 /* WSEQ_DELAY21 - [3:0] */ - -/* - * R12376 (0x3058) - Write Sequencer 88 - */ -#define WM8995_WSEQ_ADDR22_MASK 0x3FFF /* WSEQ_ADDR22 - [13:0] */ -#define WM8995_WSEQ_ADDR22_SHIFT 0 /* WSEQ_ADDR22 - [13:0] */ -#define WM8995_WSEQ_ADDR22_WIDTH 14 /* WSEQ_ADDR22 - [13:0] */ - -/* - * R12377 (0x3059) - Write Sequencer 89 - */ -#define WM8995_WSEQ_DATA22_MASK 0x00FF /* WSEQ_DATA22 - [7:0] */ -#define WM8995_WSEQ_DATA22_SHIFT 0 /* WSEQ_DATA22 - [7:0] */ -#define WM8995_WSEQ_DATA22_WIDTH 8 /* WSEQ_DATA22 - [7:0] */ - -/* - * R12378 (0x305A) - Write Sequencer 90 - */ -#define WM8995_WSEQ_DATA_WIDTH22_MASK 0x0700 /* WSEQ_DATA_WIDTH22 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH22_SHIFT 8 /* WSEQ_DATA_WIDTH22 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH22_WIDTH 3 /* WSEQ_DATA_WIDTH22 - [10:8] */ -#define WM8995_WSEQ_DATA_START22_MASK 0x000F /* WSEQ_DATA_START22 - [3:0] */ -#define WM8995_WSEQ_DATA_START22_SHIFT 0 /* WSEQ_DATA_START22 - [3:0] */ -#define WM8995_WSEQ_DATA_START22_WIDTH 4 /* WSEQ_DATA_START22 - [3:0] */ - -/* - * R12379 (0x305B) - Write Sequencer 91 - */ -#define WM8995_WSEQ_EOS22 0x0100 /* WSEQ_EOS22 */ -#define WM8995_WSEQ_EOS22_MASK 0x0100 /* WSEQ_EOS22 */ -#define WM8995_WSEQ_EOS22_SHIFT 8 /* WSEQ_EOS22 */ -#define WM8995_WSEQ_EOS22_WIDTH 1 /* WSEQ_EOS22 */ -#define WM8995_WSEQ_DELAY22_MASK 0x000F /* WSEQ_DELAY22 - [3:0] */ -#define WM8995_WSEQ_DELAY22_SHIFT 0 /* WSEQ_DELAY22 - [3:0] */ -#define WM8995_WSEQ_DELAY22_WIDTH 4 /* WSEQ_DELAY22 - [3:0] */ - -/* - * R12380 (0x305C) - Write Sequencer 92 - */ -#define WM8995_WSEQ_ADDR23_MASK 0x3FFF /* WSEQ_ADDR23 - [13:0] */ -#define WM8995_WSEQ_ADDR23_SHIFT 0 /* WSEQ_ADDR23 - [13:0] */ -#define WM8995_WSEQ_ADDR23_WIDTH 14 /* WSEQ_ADDR23 - [13:0] */ - -/* - * R12381 (0x305D) - Write Sequencer 93 - */ -#define WM8995_WSEQ_DATA23_MASK 0x00FF /* WSEQ_DATA23 - [7:0] */ -#define WM8995_WSEQ_DATA23_SHIFT 0 /* WSEQ_DATA23 - [7:0] */ -#define WM8995_WSEQ_DATA23_WIDTH 8 /* WSEQ_DATA23 - [7:0] */ - -/* - * R12382 (0x305E) - Write Sequencer 94 - */ -#define WM8995_WSEQ_DATA_WIDTH23_MASK 0x0700 /* WSEQ_DATA_WIDTH23 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH23_SHIFT 8 /* WSEQ_DATA_WIDTH23 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH23_WIDTH 3 /* WSEQ_DATA_WIDTH23 - [10:8] */ -#define WM8995_WSEQ_DATA_START23_MASK 0x000F /* WSEQ_DATA_START23 - [3:0] */ -#define WM8995_WSEQ_DATA_START23_SHIFT 0 /* WSEQ_DATA_START23 - [3:0] */ -#define WM8995_WSEQ_DATA_START23_WIDTH 4 /* WSEQ_DATA_START23 - [3:0] */ - -/* - * R12383 (0x305F) - Write Sequencer 95 - */ -#define WM8995_WSEQ_EOS23 0x0100 /* WSEQ_EOS23 */ -#define WM8995_WSEQ_EOS23_MASK 0x0100 /* WSEQ_EOS23 */ -#define WM8995_WSEQ_EOS23_SHIFT 8 /* WSEQ_EOS23 */ -#define WM8995_WSEQ_EOS23_WIDTH 1 /* WSEQ_EOS23 */ -#define WM8995_WSEQ_DELAY23_MASK 0x000F /* WSEQ_DELAY23 - [3:0] */ -#define WM8995_WSEQ_DELAY23_SHIFT 0 /* WSEQ_DELAY23 - [3:0] */ -#define WM8995_WSEQ_DELAY23_WIDTH 4 /* WSEQ_DELAY23 - [3:0] */ - -/* - * R12384 (0x3060) - Write Sequencer 96 - */ -#define WM8995_WSEQ_ADDR24_MASK 0x3FFF /* WSEQ_ADDR24 - [13:0] */ -#define WM8995_WSEQ_ADDR24_SHIFT 0 /* WSEQ_ADDR24 - [13:0] */ -#define WM8995_WSEQ_ADDR24_WIDTH 14 /* WSEQ_ADDR24 - [13:0] */ - -/* - * R12385 (0x3061) - Write Sequencer 97 - */ -#define WM8995_WSEQ_DATA24_MASK 0x00FF /* WSEQ_DATA24 - [7:0] */ -#define WM8995_WSEQ_DATA24_SHIFT 0 /* WSEQ_DATA24 - [7:0] */ -#define WM8995_WSEQ_DATA24_WIDTH 8 /* WSEQ_DATA24 - [7:0] */ - -/* - * R12386 (0x3062) - Write Sequencer 98 - */ -#define WM8995_WSEQ_DATA_WIDTH24_MASK 0x0700 /* WSEQ_DATA_WIDTH24 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH24_SHIFT 8 /* WSEQ_DATA_WIDTH24 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH24_WIDTH 3 /* WSEQ_DATA_WIDTH24 - [10:8] */ -#define WM8995_WSEQ_DATA_START24_MASK 0x000F /* WSEQ_DATA_START24 - [3:0] */ -#define WM8995_WSEQ_DATA_START24_SHIFT 0 /* WSEQ_DATA_START24 - [3:0] */ -#define WM8995_WSEQ_DATA_START24_WIDTH 4 /* WSEQ_DATA_START24 - [3:0] */ - -/* - * R12387 (0x3063) - Write Sequencer 99 - */ -#define WM8995_WSEQ_EOS24 0x0100 /* WSEQ_EOS24 */ -#define WM8995_WSEQ_EOS24_MASK 0x0100 /* WSEQ_EOS24 */ -#define WM8995_WSEQ_EOS24_SHIFT 8 /* WSEQ_EOS24 */ -#define WM8995_WSEQ_EOS24_WIDTH 1 /* WSEQ_EOS24 */ -#define WM8995_WSEQ_DELAY24_MASK 0x000F /* WSEQ_DELAY24 - [3:0] */ -#define WM8995_WSEQ_DELAY24_SHIFT 0 /* WSEQ_DELAY24 - [3:0] */ -#define WM8995_WSEQ_DELAY24_WIDTH 4 /* WSEQ_DELAY24 - [3:0] */ - -/* - * R12388 (0x3064) - Write Sequencer 100 - */ -#define WM8995_WSEQ_ADDR25_MASK 0x3FFF /* WSEQ_ADDR25 - [13:0] */ -#define WM8995_WSEQ_ADDR25_SHIFT 0 /* WSEQ_ADDR25 - [13:0] */ -#define WM8995_WSEQ_ADDR25_WIDTH 14 /* WSEQ_ADDR25 - [13:0] */ - -/* - * R12389 (0x3065) - Write Sequencer 101 - */ -#define WM8995_WSEQ_DATA25_MASK 0x00FF /* WSEQ_DATA25 - [7:0] */ -#define WM8995_WSEQ_DATA25_SHIFT 0 /* WSEQ_DATA25 - [7:0] */ -#define WM8995_WSEQ_DATA25_WIDTH 8 /* WSEQ_DATA25 - [7:0] */ - -/* - * R12390 (0x3066) - Write Sequencer 102 - */ -#define WM8995_WSEQ_DATA_WIDTH25_MASK 0x0700 /* WSEQ_DATA_WIDTH25 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH25_SHIFT 8 /* WSEQ_DATA_WIDTH25 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH25_WIDTH 3 /* WSEQ_DATA_WIDTH25 - [10:8] */ -#define WM8995_WSEQ_DATA_START25_MASK 0x000F /* WSEQ_DATA_START25 - [3:0] */ -#define WM8995_WSEQ_DATA_START25_SHIFT 0 /* WSEQ_DATA_START25 - [3:0] */ -#define WM8995_WSEQ_DATA_START25_WIDTH 4 /* WSEQ_DATA_START25 - [3:0] */ - -/* - * R12391 (0x3067) - Write Sequencer 103 - */ -#define WM8995_WSEQ_EOS25 0x0100 /* WSEQ_EOS25 */ -#define WM8995_WSEQ_EOS25_MASK 0x0100 /* WSEQ_EOS25 */ -#define WM8995_WSEQ_EOS25_SHIFT 8 /* WSEQ_EOS25 */ -#define WM8995_WSEQ_EOS25_WIDTH 1 /* WSEQ_EOS25 */ -#define WM8995_WSEQ_DELAY25_MASK 0x000F /* WSEQ_DELAY25 - [3:0] */ -#define WM8995_WSEQ_DELAY25_SHIFT 0 /* WSEQ_DELAY25 - [3:0] */ -#define WM8995_WSEQ_DELAY25_WIDTH 4 /* WSEQ_DELAY25 - [3:0] */ - -/* - * R12392 (0x3068) - Write Sequencer 104 - */ -#define WM8995_WSEQ_ADDR26_MASK 0x3FFF /* WSEQ_ADDR26 - [13:0] */ -#define WM8995_WSEQ_ADDR26_SHIFT 0 /* WSEQ_ADDR26 - [13:0] */ -#define WM8995_WSEQ_ADDR26_WIDTH 14 /* WSEQ_ADDR26 - [13:0] */ - -/* - * R12393 (0x3069) - Write Sequencer 105 - */ -#define WM8995_WSEQ_DATA26_MASK 0x00FF /* WSEQ_DATA26 - [7:0] */ -#define WM8995_WSEQ_DATA26_SHIFT 0 /* WSEQ_DATA26 - [7:0] */ -#define WM8995_WSEQ_DATA26_WIDTH 8 /* WSEQ_DATA26 - [7:0] */ - -/* - * R12394 (0x306A) - Write Sequencer 106 - */ -#define WM8995_WSEQ_DATA_WIDTH26_MASK 0x0700 /* WSEQ_DATA_WIDTH26 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH26_SHIFT 8 /* WSEQ_DATA_WIDTH26 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH26_WIDTH 3 /* WSEQ_DATA_WIDTH26 - [10:8] */ -#define WM8995_WSEQ_DATA_START26_MASK 0x000F /* WSEQ_DATA_START26 - [3:0] */ -#define WM8995_WSEQ_DATA_START26_SHIFT 0 /* WSEQ_DATA_START26 - [3:0] */ -#define WM8995_WSEQ_DATA_START26_WIDTH 4 /* WSEQ_DATA_START26 - [3:0] */ - -/* - * R12395 (0x306B) - Write Sequencer 107 - */ -#define WM8995_WSEQ_EOS26 0x0100 /* WSEQ_EOS26 */ -#define WM8995_WSEQ_EOS26_MASK 0x0100 /* WSEQ_EOS26 */ -#define WM8995_WSEQ_EOS26_SHIFT 8 /* WSEQ_EOS26 */ -#define WM8995_WSEQ_EOS26_WIDTH 1 /* WSEQ_EOS26 */ -#define WM8995_WSEQ_DELAY26_MASK 0x000F /* WSEQ_DELAY26 - [3:0] */ -#define WM8995_WSEQ_DELAY26_SHIFT 0 /* WSEQ_DELAY26 - [3:0] */ -#define WM8995_WSEQ_DELAY26_WIDTH 4 /* WSEQ_DELAY26 - [3:0] */ - -/* - * R12396 (0x306C) - Write Sequencer 108 - */ -#define WM8995_WSEQ_ADDR27_MASK 0x3FFF /* WSEQ_ADDR27 - [13:0] */ -#define WM8995_WSEQ_ADDR27_SHIFT 0 /* WSEQ_ADDR27 - [13:0] */ -#define WM8995_WSEQ_ADDR27_WIDTH 14 /* WSEQ_ADDR27 - [13:0] */ - -/* - * R12397 (0x306D) - Write Sequencer 109 - */ -#define WM8995_WSEQ_DATA27_MASK 0x00FF /* WSEQ_DATA27 - [7:0] */ -#define WM8995_WSEQ_DATA27_SHIFT 0 /* WSEQ_DATA27 - [7:0] */ -#define WM8995_WSEQ_DATA27_WIDTH 8 /* WSEQ_DATA27 - [7:0] */ - -/* - * R12398 (0x306E) - Write Sequencer 110 - */ -#define WM8995_WSEQ_DATA_WIDTH27_MASK 0x0700 /* WSEQ_DATA_WIDTH27 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH27_SHIFT 8 /* WSEQ_DATA_WIDTH27 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH27_WIDTH 3 /* WSEQ_DATA_WIDTH27 - [10:8] */ -#define WM8995_WSEQ_DATA_START27_MASK 0x000F /* WSEQ_DATA_START27 - [3:0] */ -#define WM8995_WSEQ_DATA_START27_SHIFT 0 /* WSEQ_DATA_START27 - [3:0] */ -#define WM8995_WSEQ_DATA_START27_WIDTH 4 /* WSEQ_DATA_START27 - [3:0] */ - -/* - * R12399 (0x306F) - Write Sequencer 111 - */ -#define WM8995_WSEQ_EOS27 0x0100 /* WSEQ_EOS27 */ -#define WM8995_WSEQ_EOS27_MASK 0x0100 /* WSEQ_EOS27 */ -#define WM8995_WSEQ_EOS27_SHIFT 8 /* WSEQ_EOS27 */ -#define WM8995_WSEQ_EOS27_WIDTH 1 /* WSEQ_EOS27 */ -#define WM8995_WSEQ_DELAY27_MASK 0x000F /* WSEQ_DELAY27 - [3:0] */ -#define WM8995_WSEQ_DELAY27_SHIFT 0 /* WSEQ_DELAY27 - [3:0] */ -#define WM8995_WSEQ_DELAY27_WIDTH 4 /* WSEQ_DELAY27 - [3:0] */ - -/* - * R12400 (0x3070) - Write Sequencer 112 - */ -#define WM8995_WSEQ_ADDR28_MASK 0x3FFF /* WSEQ_ADDR28 - [13:0] */ -#define WM8995_WSEQ_ADDR28_SHIFT 0 /* WSEQ_ADDR28 - [13:0] */ -#define WM8995_WSEQ_ADDR28_WIDTH 14 /* WSEQ_ADDR28 - [13:0] */ - -/* - * R12401 (0x3071) - Write Sequencer 113 - */ -#define WM8995_WSEQ_DATA28_MASK 0x00FF /* WSEQ_DATA28 - [7:0] */ -#define WM8995_WSEQ_DATA28_SHIFT 0 /* WSEQ_DATA28 - [7:0] */ -#define WM8995_WSEQ_DATA28_WIDTH 8 /* WSEQ_DATA28 - [7:0] */ - -/* - * R12402 (0x3072) - Write Sequencer 114 - */ -#define WM8995_WSEQ_DATA_WIDTH28_MASK 0x0700 /* WSEQ_DATA_WIDTH28 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH28_SHIFT 8 /* WSEQ_DATA_WIDTH28 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH28_WIDTH 3 /* WSEQ_DATA_WIDTH28 - [10:8] */ -#define WM8995_WSEQ_DATA_START28_MASK 0x000F /* WSEQ_DATA_START28 - [3:0] */ -#define WM8995_WSEQ_DATA_START28_SHIFT 0 /* WSEQ_DATA_START28 - [3:0] */ -#define WM8995_WSEQ_DATA_START28_WIDTH 4 /* WSEQ_DATA_START28 - [3:0] */ - -/* - * R12403 (0x3073) - Write Sequencer 115 - */ -#define WM8995_WSEQ_EOS28 0x0100 /* WSEQ_EOS28 */ -#define WM8995_WSEQ_EOS28_MASK 0x0100 /* WSEQ_EOS28 */ -#define WM8995_WSEQ_EOS28_SHIFT 8 /* WSEQ_EOS28 */ -#define WM8995_WSEQ_EOS28_WIDTH 1 /* WSEQ_EOS28 */ -#define WM8995_WSEQ_DELAY28_MASK 0x000F /* WSEQ_DELAY28 - [3:0] */ -#define WM8995_WSEQ_DELAY28_SHIFT 0 /* WSEQ_DELAY28 - [3:0] */ -#define WM8995_WSEQ_DELAY28_WIDTH 4 /* WSEQ_DELAY28 - [3:0] */ - -/* - * R12404 (0x3074) - Write Sequencer 116 - */ -#define WM8995_WSEQ_ADDR29_MASK 0x3FFF /* WSEQ_ADDR29 - [13:0] */ -#define WM8995_WSEQ_ADDR29_SHIFT 0 /* WSEQ_ADDR29 - [13:0] */ -#define WM8995_WSEQ_ADDR29_WIDTH 14 /* WSEQ_ADDR29 - [13:0] */ - -/* - * R12405 (0x3075) - Write Sequencer 117 - */ -#define WM8995_WSEQ_DATA29_MASK 0x00FF /* WSEQ_DATA29 - [7:0] */ -#define WM8995_WSEQ_DATA29_SHIFT 0 /* WSEQ_DATA29 - [7:0] */ -#define WM8995_WSEQ_DATA29_WIDTH 8 /* WSEQ_DATA29 - [7:0] */ - -/* - * R12406 (0x3076) - Write Sequencer 118 - */ -#define WM8995_WSEQ_DATA_WIDTH29_MASK 0x0700 /* WSEQ_DATA_WIDTH29 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH29_SHIFT 8 /* WSEQ_DATA_WIDTH29 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH29_WIDTH 3 /* WSEQ_DATA_WIDTH29 - [10:8] */ -#define WM8995_WSEQ_DATA_START29_MASK 0x000F /* WSEQ_DATA_START29 - [3:0] */ -#define WM8995_WSEQ_DATA_START29_SHIFT 0 /* WSEQ_DATA_START29 - [3:0] */ -#define WM8995_WSEQ_DATA_START29_WIDTH 4 /* WSEQ_DATA_START29 - [3:0] */ - -/* - * R12407 (0x3077) - Write Sequencer 119 - */ -#define WM8995_WSEQ_EOS29 0x0100 /* WSEQ_EOS29 */ -#define WM8995_WSEQ_EOS29_MASK 0x0100 /* WSEQ_EOS29 */ -#define WM8995_WSEQ_EOS29_SHIFT 8 /* WSEQ_EOS29 */ -#define WM8995_WSEQ_EOS29_WIDTH 1 /* WSEQ_EOS29 */ -#define WM8995_WSEQ_DELAY29_MASK 0x000F /* WSEQ_DELAY29 - [3:0] */ -#define WM8995_WSEQ_DELAY29_SHIFT 0 /* WSEQ_DELAY29 - [3:0] */ -#define WM8995_WSEQ_DELAY29_WIDTH 4 /* WSEQ_DELAY29 - [3:0] */ - -/* - * R12408 (0x3078) - Write Sequencer 120 - */ -#define WM8995_WSEQ_ADDR30_MASK 0x3FFF /* WSEQ_ADDR30 - [13:0] */ -#define WM8995_WSEQ_ADDR30_SHIFT 0 /* WSEQ_ADDR30 - [13:0] */ -#define WM8995_WSEQ_ADDR30_WIDTH 14 /* WSEQ_ADDR30 - [13:0] */ - -/* - * R12409 (0x3079) - Write Sequencer 121 - */ -#define WM8995_WSEQ_DATA30_MASK 0x00FF /* WSEQ_DATA30 - [7:0] */ -#define WM8995_WSEQ_DATA30_SHIFT 0 /* WSEQ_DATA30 - [7:0] */ -#define WM8995_WSEQ_DATA30_WIDTH 8 /* WSEQ_DATA30 - [7:0] */ - -/* - * R12410 (0x307A) - Write Sequencer 122 - */ -#define WM8995_WSEQ_DATA_WIDTH30_MASK 0x0700 /* WSEQ_DATA_WIDTH30 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH30_SHIFT 8 /* WSEQ_DATA_WIDTH30 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH30_WIDTH 3 /* WSEQ_DATA_WIDTH30 - [10:8] */ -#define WM8995_WSEQ_DATA_START30_MASK 0x000F /* WSEQ_DATA_START30 - [3:0] */ -#define WM8995_WSEQ_DATA_START30_SHIFT 0 /* WSEQ_DATA_START30 - [3:0] */ -#define WM8995_WSEQ_DATA_START30_WIDTH 4 /* WSEQ_DATA_START30 - [3:0] */ - -/* - * R12411 (0x307B) - Write Sequencer 123 - */ -#define WM8995_WSEQ_EOS30 0x0100 /* WSEQ_EOS30 */ -#define WM8995_WSEQ_EOS30_MASK 0x0100 /* WSEQ_EOS30 */ -#define WM8995_WSEQ_EOS30_SHIFT 8 /* WSEQ_EOS30 */ -#define WM8995_WSEQ_EOS30_WIDTH 1 /* WSEQ_EOS30 */ -#define WM8995_WSEQ_DELAY30_MASK 0x000F /* WSEQ_DELAY30 - [3:0] */ -#define WM8995_WSEQ_DELAY30_SHIFT 0 /* WSEQ_DELAY30 - [3:0] */ -#define WM8995_WSEQ_DELAY30_WIDTH 4 /* WSEQ_DELAY30 - [3:0] */ - -/* - * R12412 (0x307C) - Write Sequencer 124 - */ -#define WM8995_WSEQ_ADDR31_MASK 0x3FFF /* WSEQ_ADDR31 - [13:0] */ -#define WM8995_WSEQ_ADDR31_SHIFT 0 /* WSEQ_ADDR31 - [13:0] */ -#define WM8995_WSEQ_ADDR31_WIDTH 14 /* WSEQ_ADDR31 - [13:0] */ - -/* - * R12413 (0x307D) - Write Sequencer 125 - */ -#define WM8995_WSEQ_DATA31_MASK 0x00FF /* WSEQ_DATA31 - [7:0] */ -#define WM8995_WSEQ_DATA31_SHIFT 0 /* WSEQ_DATA31 - [7:0] */ -#define WM8995_WSEQ_DATA31_WIDTH 8 /* WSEQ_DATA31 - [7:0] */ - -/* - * R12414 (0x307E) - Write Sequencer 126 - */ -#define WM8995_WSEQ_DATA_WIDTH31_MASK 0x0700 /* WSEQ_DATA_WIDTH31 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH31_SHIFT 8 /* WSEQ_DATA_WIDTH31 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH31_WIDTH 3 /* WSEQ_DATA_WIDTH31 - [10:8] */ -#define WM8995_WSEQ_DATA_START31_MASK 0x000F /* WSEQ_DATA_START31 - [3:0] */ -#define WM8995_WSEQ_DATA_START31_SHIFT 0 /* WSEQ_DATA_START31 - [3:0] */ -#define WM8995_WSEQ_DATA_START31_WIDTH 4 /* WSEQ_DATA_START31 - [3:0] */ - -/* - * R12415 (0x307F) - Write Sequencer 127 - */ -#define WM8995_WSEQ_EOS31 0x0100 /* WSEQ_EOS31 */ -#define WM8995_WSEQ_EOS31_MASK 0x0100 /* WSEQ_EOS31 */ -#define WM8995_WSEQ_EOS31_SHIFT 8 /* WSEQ_EOS31 */ -#define WM8995_WSEQ_EOS31_WIDTH 1 /* WSEQ_EOS31 */ -#define WM8995_WSEQ_DELAY31_MASK 0x000F /* WSEQ_DELAY31 - [3:0] */ -#define WM8995_WSEQ_DELAY31_SHIFT 0 /* WSEQ_DELAY31 - [3:0] */ -#define WM8995_WSEQ_DELAY31_WIDTH 4 /* WSEQ_DELAY31 - [3:0] */ - -/* - * R12416 (0x3080) - Write Sequencer 128 - */ -#define WM8995_WSEQ_ADDR32_MASK 0x3FFF /* WSEQ_ADDR32 - [13:0] */ -#define WM8995_WSEQ_ADDR32_SHIFT 0 /* WSEQ_ADDR32 - [13:0] */ -#define WM8995_WSEQ_ADDR32_WIDTH 14 /* WSEQ_ADDR32 - [13:0] */ - -/* - * R12417 (0x3081) - Write Sequencer 129 - */ -#define WM8995_WSEQ_DATA32_MASK 0x00FF /* WSEQ_DATA32 - [7:0] */ -#define WM8995_WSEQ_DATA32_SHIFT 0 /* WSEQ_DATA32 - [7:0] */ -#define WM8995_WSEQ_DATA32_WIDTH 8 /* WSEQ_DATA32 - [7:0] */ - -/* - * R12418 (0x3082) - Write Sequencer 130 - */ -#define WM8995_WSEQ_DATA_WIDTH32_MASK 0x0700 /* WSEQ_DATA_WIDTH32 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH32_SHIFT 8 /* WSEQ_DATA_WIDTH32 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH32_WIDTH 3 /* WSEQ_DATA_WIDTH32 - [10:8] */ -#define WM8995_WSEQ_DATA_START32_MASK 0x000F /* WSEQ_DATA_START32 - [3:0] */ -#define WM8995_WSEQ_DATA_START32_SHIFT 0 /* WSEQ_DATA_START32 - [3:0] */ -#define WM8995_WSEQ_DATA_START32_WIDTH 4 /* WSEQ_DATA_START32 - [3:0] */ - -/* - * R12419 (0x3083) - Write Sequencer 131 - */ -#define WM8995_WSEQ_EOS32 0x0100 /* WSEQ_EOS32 */ -#define WM8995_WSEQ_EOS32_MASK 0x0100 /* WSEQ_EOS32 */ -#define WM8995_WSEQ_EOS32_SHIFT 8 /* WSEQ_EOS32 */ -#define WM8995_WSEQ_EOS32_WIDTH 1 /* WSEQ_EOS32 */ -#define WM8995_WSEQ_DELAY32_MASK 0x000F /* WSEQ_DELAY32 - [3:0] */ -#define WM8995_WSEQ_DELAY32_SHIFT 0 /* WSEQ_DELAY32 - [3:0] */ -#define WM8995_WSEQ_DELAY32_WIDTH 4 /* WSEQ_DELAY32 - [3:0] */ - -/* - * R12420 (0x3084) - Write Sequencer 132 - */ -#define WM8995_WSEQ_ADDR33_MASK 0x3FFF /* WSEQ_ADDR33 - [13:0] */ -#define WM8995_WSEQ_ADDR33_SHIFT 0 /* WSEQ_ADDR33 - [13:0] */ -#define WM8995_WSEQ_ADDR33_WIDTH 14 /* WSEQ_ADDR33 - [13:0] */ - -/* - * R12421 (0x3085) - Write Sequencer 133 - */ -#define WM8995_WSEQ_DATA33_MASK 0x00FF /* WSEQ_DATA33 - [7:0] */ -#define WM8995_WSEQ_DATA33_SHIFT 0 /* WSEQ_DATA33 - [7:0] */ -#define WM8995_WSEQ_DATA33_WIDTH 8 /* WSEQ_DATA33 - [7:0] */ - -/* - * R12422 (0x3086) - Write Sequencer 134 - */ -#define WM8995_WSEQ_DATA_WIDTH33_MASK 0x0700 /* WSEQ_DATA_WIDTH33 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH33_SHIFT 8 /* WSEQ_DATA_WIDTH33 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH33_WIDTH 3 /* WSEQ_DATA_WIDTH33 - [10:8] */ -#define WM8995_WSEQ_DATA_START33_MASK 0x000F /* WSEQ_DATA_START33 - [3:0] */ -#define WM8995_WSEQ_DATA_START33_SHIFT 0 /* WSEQ_DATA_START33 - [3:0] */ -#define WM8995_WSEQ_DATA_START33_WIDTH 4 /* WSEQ_DATA_START33 - [3:0] */ - -/* - * R12423 (0x3087) - Write Sequencer 135 - */ -#define WM8995_WSEQ_EOS33 0x0100 /* WSEQ_EOS33 */ -#define WM8995_WSEQ_EOS33_MASK 0x0100 /* WSEQ_EOS33 */ -#define WM8995_WSEQ_EOS33_SHIFT 8 /* WSEQ_EOS33 */ -#define WM8995_WSEQ_EOS33_WIDTH 1 /* WSEQ_EOS33 */ -#define WM8995_WSEQ_DELAY33_MASK 0x000F /* WSEQ_DELAY33 - [3:0] */ -#define WM8995_WSEQ_DELAY33_SHIFT 0 /* WSEQ_DELAY33 - [3:0] */ -#define WM8995_WSEQ_DELAY33_WIDTH 4 /* WSEQ_DELAY33 - [3:0] */ - -/* - * R12424 (0x3088) - Write Sequencer 136 - */ -#define WM8995_WSEQ_ADDR34_MASK 0x3FFF /* WSEQ_ADDR34 - [13:0] */ -#define WM8995_WSEQ_ADDR34_SHIFT 0 /* WSEQ_ADDR34 - [13:0] */ -#define WM8995_WSEQ_ADDR34_WIDTH 14 /* WSEQ_ADDR34 - [13:0] */ - -/* - * R12425 (0x3089) - Write Sequencer 137 - */ -#define WM8995_WSEQ_DATA34_MASK 0x00FF /* WSEQ_DATA34 - [7:0] */ -#define WM8995_WSEQ_DATA34_SHIFT 0 /* WSEQ_DATA34 - [7:0] */ -#define WM8995_WSEQ_DATA34_WIDTH 8 /* WSEQ_DATA34 - [7:0] */ - -/* - * R12426 (0x308A) - Write Sequencer 138 - */ -#define WM8995_WSEQ_DATA_WIDTH34_MASK 0x0700 /* WSEQ_DATA_WIDTH34 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH34_SHIFT 8 /* WSEQ_DATA_WIDTH34 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH34_WIDTH 3 /* WSEQ_DATA_WIDTH34 - [10:8] */ -#define WM8995_WSEQ_DATA_START34_MASK 0x000F /* WSEQ_DATA_START34 - [3:0] */ -#define WM8995_WSEQ_DATA_START34_SHIFT 0 /* WSEQ_DATA_START34 - [3:0] */ -#define WM8995_WSEQ_DATA_START34_WIDTH 4 /* WSEQ_DATA_START34 - [3:0] */ - -/* - * R12427 (0x308B) - Write Sequencer 139 - */ -#define WM8995_WSEQ_EOS34 0x0100 /* WSEQ_EOS34 */ -#define WM8995_WSEQ_EOS34_MASK 0x0100 /* WSEQ_EOS34 */ -#define WM8995_WSEQ_EOS34_SHIFT 8 /* WSEQ_EOS34 */ -#define WM8995_WSEQ_EOS34_WIDTH 1 /* WSEQ_EOS34 */ -#define WM8995_WSEQ_DELAY34_MASK 0x000F /* WSEQ_DELAY34 - [3:0] */ -#define WM8995_WSEQ_DELAY34_SHIFT 0 /* WSEQ_DELAY34 - [3:0] */ -#define WM8995_WSEQ_DELAY34_WIDTH 4 /* WSEQ_DELAY34 - [3:0] */ - -/* - * R12428 (0x308C) - Write Sequencer 140 - */ -#define WM8995_WSEQ_ADDR35_MASK 0x3FFF /* WSEQ_ADDR35 - [13:0] */ -#define WM8995_WSEQ_ADDR35_SHIFT 0 /* WSEQ_ADDR35 - [13:0] */ -#define WM8995_WSEQ_ADDR35_WIDTH 14 /* WSEQ_ADDR35 - [13:0] */ - -/* - * R12429 (0x308D) - Write Sequencer 141 - */ -#define WM8995_WSEQ_DATA35_MASK 0x00FF /* WSEQ_DATA35 - [7:0] */ -#define WM8995_WSEQ_DATA35_SHIFT 0 /* WSEQ_DATA35 - [7:0] */ -#define WM8995_WSEQ_DATA35_WIDTH 8 /* WSEQ_DATA35 - [7:0] */ - -/* - * R12430 (0x308E) - Write Sequencer 142 - */ -#define WM8995_WSEQ_DATA_WIDTH35_MASK 0x0700 /* WSEQ_DATA_WIDTH35 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH35_SHIFT 8 /* WSEQ_DATA_WIDTH35 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH35_WIDTH 3 /* WSEQ_DATA_WIDTH35 - [10:8] */ -#define WM8995_WSEQ_DATA_START35_MASK 0x000F /* WSEQ_DATA_START35 - [3:0] */ -#define WM8995_WSEQ_DATA_START35_SHIFT 0 /* WSEQ_DATA_START35 - [3:0] */ -#define WM8995_WSEQ_DATA_START35_WIDTH 4 /* WSEQ_DATA_START35 - [3:0] */ - -/* - * R12431 (0x308F) - Write Sequencer 143 - */ -#define WM8995_WSEQ_EOS35 0x0100 /* WSEQ_EOS35 */ -#define WM8995_WSEQ_EOS35_MASK 0x0100 /* WSEQ_EOS35 */ -#define WM8995_WSEQ_EOS35_SHIFT 8 /* WSEQ_EOS35 */ -#define WM8995_WSEQ_EOS35_WIDTH 1 /* WSEQ_EOS35 */ -#define WM8995_WSEQ_DELAY35_MASK 0x000F /* WSEQ_DELAY35 - [3:0] */ -#define WM8995_WSEQ_DELAY35_SHIFT 0 /* WSEQ_DELAY35 - [3:0] */ -#define WM8995_WSEQ_DELAY35_WIDTH 4 /* WSEQ_DELAY35 - [3:0] */ - -/* - * R12432 (0x3090) - Write Sequencer 144 - */ -#define WM8995_WSEQ_ADDR36_MASK 0x3FFF /* WSEQ_ADDR36 - [13:0] */ -#define WM8995_WSEQ_ADDR36_SHIFT 0 /* WSEQ_ADDR36 - [13:0] */ -#define WM8995_WSEQ_ADDR36_WIDTH 14 /* WSEQ_ADDR36 - [13:0] */ - -/* - * R12433 (0x3091) - Write Sequencer 145 - */ -#define WM8995_WSEQ_DATA36_MASK 0x00FF /* WSEQ_DATA36 - [7:0] */ -#define WM8995_WSEQ_DATA36_SHIFT 0 /* WSEQ_DATA36 - [7:0] */ -#define WM8995_WSEQ_DATA36_WIDTH 8 /* WSEQ_DATA36 - [7:0] */ - -/* - * R12434 (0x3092) - Write Sequencer 146 - */ -#define WM8995_WSEQ_DATA_WIDTH36_MASK 0x0700 /* WSEQ_DATA_WIDTH36 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH36_SHIFT 8 /* WSEQ_DATA_WIDTH36 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH36_WIDTH 3 /* WSEQ_DATA_WIDTH36 - [10:8] */ -#define WM8995_WSEQ_DATA_START36_MASK 0x000F /* WSEQ_DATA_START36 - [3:0] */ -#define WM8995_WSEQ_DATA_START36_SHIFT 0 /* WSEQ_DATA_START36 - [3:0] */ -#define WM8995_WSEQ_DATA_START36_WIDTH 4 /* WSEQ_DATA_START36 - [3:0] */ - -/* - * R12435 (0x3093) - Write Sequencer 147 - */ -#define WM8995_WSEQ_EOS36 0x0100 /* WSEQ_EOS36 */ -#define WM8995_WSEQ_EOS36_MASK 0x0100 /* WSEQ_EOS36 */ -#define WM8995_WSEQ_EOS36_SHIFT 8 /* WSEQ_EOS36 */ -#define WM8995_WSEQ_EOS36_WIDTH 1 /* WSEQ_EOS36 */ -#define WM8995_WSEQ_DELAY36_MASK 0x000F /* WSEQ_DELAY36 - [3:0] */ -#define WM8995_WSEQ_DELAY36_SHIFT 0 /* WSEQ_DELAY36 - [3:0] */ -#define WM8995_WSEQ_DELAY36_WIDTH 4 /* WSEQ_DELAY36 - [3:0] */ - -/* - * R12436 (0x3094) - Write Sequencer 148 - */ -#define WM8995_WSEQ_ADDR37_MASK 0x3FFF /* WSEQ_ADDR37 - [13:0] */ -#define WM8995_WSEQ_ADDR37_SHIFT 0 /* WSEQ_ADDR37 - [13:0] */ -#define WM8995_WSEQ_ADDR37_WIDTH 14 /* WSEQ_ADDR37 - [13:0] */ - -/* - * R12437 (0x3095) - Write Sequencer 149 - */ -#define WM8995_WSEQ_DATA37_MASK 0x00FF /* WSEQ_DATA37 - [7:0] */ -#define WM8995_WSEQ_DATA37_SHIFT 0 /* WSEQ_DATA37 - [7:0] */ -#define WM8995_WSEQ_DATA37_WIDTH 8 /* WSEQ_DATA37 - [7:0] */ - -/* - * R12438 (0x3096) - Write Sequencer 150 - */ -#define WM8995_WSEQ_DATA_WIDTH37_MASK 0x0700 /* WSEQ_DATA_WIDTH37 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH37_SHIFT 8 /* WSEQ_DATA_WIDTH37 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH37_WIDTH 3 /* WSEQ_DATA_WIDTH37 - [10:8] */ -#define WM8995_WSEQ_DATA_START37_MASK 0x000F /* WSEQ_DATA_START37 - [3:0] */ -#define WM8995_WSEQ_DATA_START37_SHIFT 0 /* WSEQ_DATA_START37 - [3:0] */ -#define WM8995_WSEQ_DATA_START37_WIDTH 4 /* WSEQ_DATA_START37 - [3:0] */ - -/* - * R12439 (0x3097) - Write Sequencer 151 - */ -#define WM8995_WSEQ_EOS37 0x0100 /* WSEQ_EOS37 */ -#define WM8995_WSEQ_EOS37_MASK 0x0100 /* WSEQ_EOS37 */ -#define WM8995_WSEQ_EOS37_SHIFT 8 /* WSEQ_EOS37 */ -#define WM8995_WSEQ_EOS37_WIDTH 1 /* WSEQ_EOS37 */ -#define WM8995_WSEQ_DELAY37_MASK 0x000F /* WSEQ_DELAY37 - [3:0] */ -#define WM8995_WSEQ_DELAY37_SHIFT 0 /* WSEQ_DELAY37 - [3:0] */ -#define WM8995_WSEQ_DELAY37_WIDTH 4 /* WSEQ_DELAY37 - [3:0] */ - -/* - * R12440 (0x3098) - Write Sequencer 152 - */ -#define WM8995_WSEQ_ADDR38_MASK 0x3FFF /* WSEQ_ADDR38 - [13:0] */ -#define WM8995_WSEQ_ADDR38_SHIFT 0 /* WSEQ_ADDR38 - [13:0] */ -#define WM8995_WSEQ_ADDR38_WIDTH 14 /* WSEQ_ADDR38 - [13:0] */ - -/* - * R12441 (0x3099) - Write Sequencer 153 - */ -#define WM8995_WSEQ_DATA38_MASK 0x00FF /* WSEQ_DATA38 - [7:0] */ -#define WM8995_WSEQ_DATA38_SHIFT 0 /* WSEQ_DATA38 - [7:0] */ -#define WM8995_WSEQ_DATA38_WIDTH 8 /* WSEQ_DATA38 - [7:0] */ - -/* - * R12442 (0x309A) - Write Sequencer 154 - */ -#define WM8995_WSEQ_DATA_WIDTH38_MASK 0x0700 /* WSEQ_DATA_WIDTH38 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH38_SHIFT 8 /* WSEQ_DATA_WIDTH38 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH38_WIDTH 3 /* WSEQ_DATA_WIDTH38 - [10:8] */ -#define WM8995_WSEQ_DATA_START38_MASK 0x000F /* WSEQ_DATA_START38 - [3:0] */ -#define WM8995_WSEQ_DATA_START38_SHIFT 0 /* WSEQ_DATA_START38 - [3:0] */ -#define WM8995_WSEQ_DATA_START38_WIDTH 4 /* WSEQ_DATA_START38 - [3:0] */ - -/* - * R12443 (0x309B) - Write Sequencer 155 - */ -#define WM8995_WSEQ_EOS38 0x0100 /* WSEQ_EOS38 */ -#define WM8995_WSEQ_EOS38_MASK 0x0100 /* WSEQ_EOS38 */ -#define WM8995_WSEQ_EOS38_SHIFT 8 /* WSEQ_EOS38 */ -#define WM8995_WSEQ_EOS38_WIDTH 1 /* WSEQ_EOS38 */ -#define WM8995_WSEQ_DELAY38_MASK 0x000F /* WSEQ_DELAY38 - [3:0] */ -#define WM8995_WSEQ_DELAY38_SHIFT 0 /* WSEQ_DELAY38 - [3:0] */ -#define WM8995_WSEQ_DELAY38_WIDTH 4 /* WSEQ_DELAY38 - [3:0] */ - -/* - * R12444 (0x309C) - Write Sequencer 156 - */ -#define WM8995_WSEQ_ADDR39_MASK 0x3FFF /* WSEQ_ADDR39 - [13:0] */ -#define WM8995_WSEQ_ADDR39_SHIFT 0 /* WSEQ_ADDR39 - [13:0] */ -#define WM8995_WSEQ_ADDR39_WIDTH 14 /* WSEQ_ADDR39 - [13:0] */ - -/* - * R12445 (0x309D) - Write Sequencer 157 - */ -#define WM8995_WSEQ_DATA39_MASK 0x00FF /* WSEQ_DATA39 - [7:0] */ -#define WM8995_WSEQ_DATA39_SHIFT 0 /* WSEQ_DATA39 - [7:0] */ -#define WM8995_WSEQ_DATA39_WIDTH 8 /* WSEQ_DATA39 - [7:0] */ - -/* - * R12446 (0x309E) - Write Sequencer 158 - */ -#define WM8995_WSEQ_DATA_WIDTH39_MASK 0x0700 /* WSEQ_DATA_WIDTH39 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH39_SHIFT 8 /* WSEQ_DATA_WIDTH39 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH39_WIDTH 3 /* WSEQ_DATA_WIDTH39 - [10:8] */ -#define WM8995_WSEQ_DATA_START39_MASK 0x000F /* WSEQ_DATA_START39 - [3:0] */ -#define WM8995_WSEQ_DATA_START39_SHIFT 0 /* WSEQ_DATA_START39 - [3:0] */ -#define WM8995_WSEQ_DATA_START39_WIDTH 4 /* WSEQ_DATA_START39 - [3:0] */ - -/* - * R12447 (0x309F) - Write Sequencer 159 - */ -#define WM8995_WSEQ_EOS39 0x0100 /* WSEQ_EOS39 */ -#define WM8995_WSEQ_EOS39_MASK 0x0100 /* WSEQ_EOS39 */ -#define WM8995_WSEQ_EOS39_SHIFT 8 /* WSEQ_EOS39 */ -#define WM8995_WSEQ_EOS39_WIDTH 1 /* WSEQ_EOS39 */ -#define WM8995_WSEQ_DELAY39_MASK 0x000F /* WSEQ_DELAY39 - [3:0] */ -#define WM8995_WSEQ_DELAY39_SHIFT 0 /* WSEQ_DELAY39 - [3:0] */ -#define WM8995_WSEQ_DELAY39_WIDTH 4 /* WSEQ_DELAY39 - [3:0] */ - -/* - * R12448 (0x30A0) - Write Sequencer 160 - */ -#define WM8995_WSEQ_ADDR40_MASK 0x3FFF /* WSEQ_ADDR40 - [13:0] */ -#define WM8995_WSEQ_ADDR40_SHIFT 0 /* WSEQ_ADDR40 - [13:0] */ -#define WM8995_WSEQ_ADDR40_WIDTH 14 /* WSEQ_ADDR40 - [13:0] */ - -/* - * R12449 (0x30A1) - Write Sequencer 161 - */ -#define WM8995_WSEQ_DATA40_MASK 0x00FF /* WSEQ_DATA40 - [7:0] */ -#define WM8995_WSEQ_DATA40_SHIFT 0 /* WSEQ_DATA40 - [7:0] */ -#define WM8995_WSEQ_DATA40_WIDTH 8 /* WSEQ_DATA40 - [7:0] */ - -/* - * R12450 (0x30A2) - Write Sequencer 162 - */ -#define WM8995_WSEQ_DATA_WIDTH40_MASK 0x0700 /* WSEQ_DATA_WIDTH40 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH40_SHIFT 8 /* WSEQ_DATA_WIDTH40 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH40_WIDTH 3 /* WSEQ_DATA_WIDTH40 - [10:8] */ -#define WM8995_WSEQ_DATA_START40_MASK 0x000F /* WSEQ_DATA_START40 - [3:0] */ -#define WM8995_WSEQ_DATA_START40_SHIFT 0 /* WSEQ_DATA_START40 - [3:0] */ -#define WM8995_WSEQ_DATA_START40_WIDTH 4 /* WSEQ_DATA_START40 - [3:0] */ - -/* - * R12451 (0x30A3) - Write Sequencer 163 - */ -#define WM8995_WSEQ_EOS40 0x0100 /* WSEQ_EOS40 */ -#define WM8995_WSEQ_EOS40_MASK 0x0100 /* WSEQ_EOS40 */ -#define WM8995_WSEQ_EOS40_SHIFT 8 /* WSEQ_EOS40 */ -#define WM8995_WSEQ_EOS40_WIDTH 1 /* WSEQ_EOS40 */ -#define WM8995_WSEQ_DELAY40_MASK 0x000F /* WSEQ_DELAY40 - [3:0] */ -#define WM8995_WSEQ_DELAY40_SHIFT 0 /* WSEQ_DELAY40 - [3:0] */ -#define WM8995_WSEQ_DELAY40_WIDTH 4 /* WSEQ_DELAY40 - [3:0] */ - -/* - * R12452 (0x30A4) - Write Sequencer 164 - */ -#define WM8995_WSEQ_ADDR41_MASK 0x3FFF /* WSEQ_ADDR41 - [13:0] */ -#define WM8995_WSEQ_ADDR41_SHIFT 0 /* WSEQ_ADDR41 - [13:0] */ -#define WM8995_WSEQ_ADDR41_WIDTH 14 /* WSEQ_ADDR41 - [13:0] */ - -/* - * R12453 (0x30A5) - Write Sequencer 165 - */ -#define WM8995_WSEQ_DATA41_MASK 0x00FF /* WSEQ_DATA41 - [7:0] */ -#define WM8995_WSEQ_DATA41_SHIFT 0 /* WSEQ_DATA41 - [7:0] */ -#define WM8995_WSEQ_DATA41_WIDTH 8 /* WSEQ_DATA41 - [7:0] */ - -/* - * R12454 (0x30A6) - Write Sequencer 166 - */ -#define WM8995_WSEQ_DATA_WIDTH41_MASK 0x0700 /* WSEQ_DATA_WIDTH41 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH41_SHIFT 8 /* WSEQ_DATA_WIDTH41 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH41_WIDTH 3 /* WSEQ_DATA_WIDTH41 - [10:8] */ -#define WM8995_WSEQ_DATA_START41_MASK 0x000F /* WSEQ_DATA_START41 - [3:0] */ -#define WM8995_WSEQ_DATA_START41_SHIFT 0 /* WSEQ_DATA_START41 - [3:0] */ -#define WM8995_WSEQ_DATA_START41_WIDTH 4 /* WSEQ_DATA_START41 - [3:0] */ - -/* - * R12455 (0x30A7) - Write Sequencer 167 - */ -#define WM8995_WSEQ_EOS41 0x0100 /* WSEQ_EOS41 */ -#define WM8995_WSEQ_EOS41_MASK 0x0100 /* WSEQ_EOS41 */ -#define WM8995_WSEQ_EOS41_SHIFT 8 /* WSEQ_EOS41 */ -#define WM8995_WSEQ_EOS41_WIDTH 1 /* WSEQ_EOS41 */ -#define WM8995_WSEQ_DELAY41_MASK 0x000F /* WSEQ_DELAY41 - [3:0] */ -#define WM8995_WSEQ_DELAY41_SHIFT 0 /* WSEQ_DELAY41 - [3:0] */ -#define WM8995_WSEQ_DELAY41_WIDTH 4 /* WSEQ_DELAY41 - [3:0] */ - -/* - * R12456 (0x30A8) - Write Sequencer 168 - */ -#define WM8995_WSEQ_ADDR42_MASK 0x3FFF /* WSEQ_ADDR42 - [13:0] */ -#define WM8995_WSEQ_ADDR42_SHIFT 0 /* WSEQ_ADDR42 - [13:0] */ -#define WM8995_WSEQ_ADDR42_WIDTH 14 /* WSEQ_ADDR42 - [13:0] */ - -/* - * R12457 (0x30A9) - Write Sequencer 169 - */ -#define WM8995_WSEQ_DATA42_MASK 0x00FF /* WSEQ_DATA42 - [7:0] */ -#define WM8995_WSEQ_DATA42_SHIFT 0 /* WSEQ_DATA42 - [7:0] */ -#define WM8995_WSEQ_DATA42_WIDTH 8 /* WSEQ_DATA42 - [7:0] */ - -/* - * R12458 (0x30AA) - Write Sequencer 170 - */ -#define WM8995_WSEQ_DATA_WIDTH42_MASK 0x0700 /* WSEQ_DATA_WIDTH42 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH42_SHIFT 8 /* WSEQ_DATA_WIDTH42 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH42_WIDTH 3 /* WSEQ_DATA_WIDTH42 - [10:8] */ -#define WM8995_WSEQ_DATA_START42_MASK 0x000F /* WSEQ_DATA_START42 - [3:0] */ -#define WM8995_WSEQ_DATA_START42_SHIFT 0 /* WSEQ_DATA_START42 - [3:0] */ -#define WM8995_WSEQ_DATA_START42_WIDTH 4 /* WSEQ_DATA_START42 - [3:0] */ - -/* - * R12459 (0x30AB) - Write Sequencer 171 - */ -#define WM8995_WSEQ_EOS42 0x0100 /* WSEQ_EOS42 */ -#define WM8995_WSEQ_EOS42_MASK 0x0100 /* WSEQ_EOS42 */ -#define WM8995_WSEQ_EOS42_SHIFT 8 /* WSEQ_EOS42 */ -#define WM8995_WSEQ_EOS42_WIDTH 1 /* WSEQ_EOS42 */ -#define WM8995_WSEQ_DELAY42_MASK 0x000F /* WSEQ_DELAY42 - [3:0] */ -#define WM8995_WSEQ_DELAY42_SHIFT 0 /* WSEQ_DELAY42 - [3:0] */ -#define WM8995_WSEQ_DELAY42_WIDTH 4 /* WSEQ_DELAY42 - [3:0] */ - -/* - * R12460 (0x30AC) - Write Sequencer 172 - */ -#define WM8995_WSEQ_ADDR43_MASK 0x3FFF /* WSEQ_ADDR43 - [13:0] */ -#define WM8995_WSEQ_ADDR43_SHIFT 0 /* WSEQ_ADDR43 - [13:0] */ -#define WM8995_WSEQ_ADDR43_WIDTH 14 /* WSEQ_ADDR43 - [13:0] */ - -/* - * R12461 (0x30AD) - Write Sequencer 173 - */ -#define WM8995_WSEQ_DATA43_MASK 0x00FF /* WSEQ_DATA43 - [7:0] */ -#define WM8995_WSEQ_DATA43_SHIFT 0 /* WSEQ_DATA43 - [7:0] */ -#define WM8995_WSEQ_DATA43_WIDTH 8 /* WSEQ_DATA43 - [7:0] */ - -/* - * R12462 (0x30AE) - Write Sequencer 174 - */ -#define WM8995_WSEQ_DATA_WIDTH43_MASK 0x0700 /* WSEQ_DATA_WIDTH43 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH43_SHIFT 8 /* WSEQ_DATA_WIDTH43 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH43_WIDTH 3 /* WSEQ_DATA_WIDTH43 - [10:8] */ -#define WM8995_WSEQ_DATA_START43_MASK 0x000F /* WSEQ_DATA_START43 - [3:0] */ -#define WM8995_WSEQ_DATA_START43_SHIFT 0 /* WSEQ_DATA_START43 - [3:0] */ -#define WM8995_WSEQ_DATA_START43_WIDTH 4 /* WSEQ_DATA_START43 - [3:0] */ - -/* - * R12463 (0x30AF) - Write Sequencer 175 - */ -#define WM8995_WSEQ_EOS43 0x0100 /* WSEQ_EOS43 */ -#define WM8995_WSEQ_EOS43_MASK 0x0100 /* WSEQ_EOS43 */ -#define WM8995_WSEQ_EOS43_SHIFT 8 /* WSEQ_EOS43 */ -#define WM8995_WSEQ_EOS43_WIDTH 1 /* WSEQ_EOS43 */ -#define WM8995_WSEQ_DELAY43_MASK 0x000F /* WSEQ_DELAY43 - [3:0] */ -#define WM8995_WSEQ_DELAY43_SHIFT 0 /* WSEQ_DELAY43 - [3:0] */ -#define WM8995_WSEQ_DELAY43_WIDTH 4 /* WSEQ_DELAY43 - [3:0] */ - -/* - * R12464 (0x30B0) - Write Sequencer 176 - */ -#define WM8995_WSEQ_ADDR44_MASK 0x3FFF /* WSEQ_ADDR44 - [13:0] */ -#define WM8995_WSEQ_ADDR44_SHIFT 0 /* WSEQ_ADDR44 - [13:0] */ -#define WM8995_WSEQ_ADDR44_WIDTH 14 /* WSEQ_ADDR44 - [13:0] */ - -/* - * R12465 (0x30B1) - Write Sequencer 177 - */ -#define WM8995_WSEQ_DATA44_MASK 0x00FF /* WSEQ_DATA44 - [7:0] */ -#define WM8995_WSEQ_DATA44_SHIFT 0 /* WSEQ_DATA44 - [7:0] */ -#define WM8995_WSEQ_DATA44_WIDTH 8 /* WSEQ_DATA44 - [7:0] */ - -/* - * R12466 (0x30B2) - Write Sequencer 178 - */ -#define WM8995_WSEQ_DATA_WIDTH44_MASK 0x0700 /* WSEQ_DATA_WIDTH44 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH44_SHIFT 8 /* WSEQ_DATA_WIDTH44 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH44_WIDTH 3 /* WSEQ_DATA_WIDTH44 - [10:8] */ -#define WM8995_WSEQ_DATA_START44_MASK 0x000F /* WSEQ_DATA_START44 - [3:0] */ -#define WM8995_WSEQ_DATA_START44_SHIFT 0 /* WSEQ_DATA_START44 - [3:0] */ -#define WM8995_WSEQ_DATA_START44_WIDTH 4 /* WSEQ_DATA_START44 - [3:0] */ - -/* - * R12467 (0x30B3) - Write Sequencer 179 - */ -#define WM8995_WSEQ_EOS44 0x0100 /* WSEQ_EOS44 */ -#define WM8995_WSEQ_EOS44_MASK 0x0100 /* WSEQ_EOS44 */ -#define WM8995_WSEQ_EOS44_SHIFT 8 /* WSEQ_EOS44 */ -#define WM8995_WSEQ_EOS44_WIDTH 1 /* WSEQ_EOS44 */ -#define WM8995_WSEQ_DELAY44_MASK 0x000F /* WSEQ_DELAY44 - [3:0] */ -#define WM8995_WSEQ_DELAY44_SHIFT 0 /* WSEQ_DELAY44 - [3:0] */ -#define WM8995_WSEQ_DELAY44_WIDTH 4 /* WSEQ_DELAY44 - [3:0] */ - -/* - * R12468 (0x30B4) - Write Sequencer 180 - */ -#define WM8995_WSEQ_ADDR45_MASK 0x3FFF /* WSEQ_ADDR45 - [13:0] */ -#define WM8995_WSEQ_ADDR45_SHIFT 0 /* WSEQ_ADDR45 - [13:0] */ -#define WM8995_WSEQ_ADDR45_WIDTH 14 /* WSEQ_ADDR45 - [13:0] */ - -/* - * R12469 (0x30B5) - Write Sequencer 181 - */ -#define WM8995_WSEQ_DATA45_MASK 0x00FF /* WSEQ_DATA45 - [7:0] */ -#define WM8995_WSEQ_DATA45_SHIFT 0 /* WSEQ_DATA45 - [7:0] */ -#define WM8995_WSEQ_DATA45_WIDTH 8 /* WSEQ_DATA45 - [7:0] */ - -/* - * R12470 (0x30B6) - Write Sequencer 182 - */ -#define WM8995_WSEQ_DATA_WIDTH45_MASK 0x0700 /* WSEQ_DATA_WIDTH45 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH45_SHIFT 8 /* WSEQ_DATA_WIDTH45 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH45_WIDTH 3 /* WSEQ_DATA_WIDTH45 - [10:8] */ -#define WM8995_WSEQ_DATA_START45_MASK 0x000F /* WSEQ_DATA_START45 - [3:0] */ -#define WM8995_WSEQ_DATA_START45_SHIFT 0 /* WSEQ_DATA_START45 - [3:0] */ -#define WM8995_WSEQ_DATA_START45_WIDTH 4 /* WSEQ_DATA_START45 - [3:0] */ - -/* - * R12471 (0x30B7) - Write Sequencer 183 - */ -#define WM8995_WSEQ_EOS45 0x0100 /* WSEQ_EOS45 */ -#define WM8995_WSEQ_EOS45_MASK 0x0100 /* WSEQ_EOS45 */ -#define WM8995_WSEQ_EOS45_SHIFT 8 /* WSEQ_EOS45 */ -#define WM8995_WSEQ_EOS45_WIDTH 1 /* WSEQ_EOS45 */ -#define WM8995_WSEQ_DELAY45_MASK 0x000F /* WSEQ_DELAY45 - [3:0] */ -#define WM8995_WSEQ_DELAY45_SHIFT 0 /* WSEQ_DELAY45 - [3:0] */ -#define WM8995_WSEQ_DELAY45_WIDTH 4 /* WSEQ_DELAY45 - [3:0] */ - -/* - * R12472 (0x30B8) - Write Sequencer 184 - */ -#define WM8995_WSEQ_ADDR46_MASK 0x3FFF /* WSEQ_ADDR46 - [13:0] */ -#define WM8995_WSEQ_ADDR46_SHIFT 0 /* WSEQ_ADDR46 - [13:0] */ -#define WM8995_WSEQ_ADDR46_WIDTH 14 /* WSEQ_ADDR46 - [13:0] */ - -/* - * R12473 (0x30B9) - Write Sequencer 185 - */ -#define WM8995_WSEQ_DATA46_MASK 0x00FF /* WSEQ_DATA46 - [7:0] */ -#define WM8995_WSEQ_DATA46_SHIFT 0 /* WSEQ_DATA46 - [7:0] */ -#define WM8995_WSEQ_DATA46_WIDTH 8 /* WSEQ_DATA46 - [7:0] */ - -/* - * R12474 (0x30BA) - Write Sequencer 186 - */ -#define WM8995_WSEQ_DATA_WIDTH46_MASK 0x0700 /* WSEQ_DATA_WIDTH46 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH46_SHIFT 8 /* WSEQ_DATA_WIDTH46 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH46_WIDTH 3 /* WSEQ_DATA_WIDTH46 - [10:8] */ -#define WM8995_WSEQ_DATA_START46_MASK 0x000F /* WSEQ_DATA_START46 - [3:0] */ -#define WM8995_WSEQ_DATA_START46_SHIFT 0 /* WSEQ_DATA_START46 - [3:0] */ -#define WM8995_WSEQ_DATA_START46_WIDTH 4 /* WSEQ_DATA_START46 - [3:0] */ - -/* - * R12475 (0x30BB) - Write Sequencer 187 - */ -#define WM8995_WSEQ_EOS46 0x0100 /* WSEQ_EOS46 */ -#define WM8995_WSEQ_EOS46_MASK 0x0100 /* WSEQ_EOS46 */ -#define WM8995_WSEQ_EOS46_SHIFT 8 /* WSEQ_EOS46 */ -#define WM8995_WSEQ_EOS46_WIDTH 1 /* WSEQ_EOS46 */ -#define WM8995_WSEQ_DELAY46_MASK 0x000F /* WSEQ_DELAY46 - [3:0] */ -#define WM8995_WSEQ_DELAY46_SHIFT 0 /* WSEQ_DELAY46 - [3:0] */ -#define WM8995_WSEQ_DELAY46_WIDTH 4 /* WSEQ_DELAY46 - [3:0] */ - -/* - * R12476 (0x30BC) - Write Sequencer 188 - */ -#define WM8995_WSEQ_ADDR47_MASK 0x3FFF /* WSEQ_ADDR47 - [13:0] */ -#define WM8995_WSEQ_ADDR47_SHIFT 0 /* WSEQ_ADDR47 - [13:0] */ -#define WM8995_WSEQ_ADDR47_WIDTH 14 /* WSEQ_ADDR47 - [13:0] */ - -/* - * R12477 (0x30BD) - Write Sequencer 189 - */ -#define WM8995_WSEQ_DATA47_MASK 0x00FF /* WSEQ_DATA47 - [7:0] */ -#define WM8995_WSEQ_DATA47_SHIFT 0 /* WSEQ_DATA47 - [7:0] */ -#define WM8995_WSEQ_DATA47_WIDTH 8 /* WSEQ_DATA47 - [7:0] */ - -/* - * R12478 (0x30BE) - Write Sequencer 190 - */ -#define WM8995_WSEQ_DATA_WIDTH47_MASK 0x0700 /* WSEQ_DATA_WIDTH47 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH47_SHIFT 8 /* WSEQ_DATA_WIDTH47 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH47_WIDTH 3 /* WSEQ_DATA_WIDTH47 - [10:8] */ -#define WM8995_WSEQ_DATA_START47_MASK 0x000F /* WSEQ_DATA_START47 - [3:0] */ -#define WM8995_WSEQ_DATA_START47_SHIFT 0 /* WSEQ_DATA_START47 - [3:0] */ -#define WM8995_WSEQ_DATA_START47_WIDTH 4 /* WSEQ_DATA_START47 - [3:0] */ - -/* - * R12479 (0x30BF) - Write Sequencer 191 - */ -#define WM8995_WSEQ_EOS47 0x0100 /* WSEQ_EOS47 */ -#define WM8995_WSEQ_EOS47_MASK 0x0100 /* WSEQ_EOS47 */ -#define WM8995_WSEQ_EOS47_SHIFT 8 /* WSEQ_EOS47 */ -#define WM8995_WSEQ_EOS47_WIDTH 1 /* WSEQ_EOS47 */ -#define WM8995_WSEQ_DELAY47_MASK 0x000F /* WSEQ_DELAY47 - [3:0] */ -#define WM8995_WSEQ_DELAY47_SHIFT 0 /* WSEQ_DELAY47 - [3:0] */ -#define WM8995_WSEQ_DELAY47_WIDTH 4 /* WSEQ_DELAY47 - [3:0] */ - -/* - * R12480 (0x30C0) - Write Sequencer 192 - */ -#define WM8995_WSEQ_ADDR48_MASK 0x3FFF /* WSEQ_ADDR48 - [13:0] */ -#define WM8995_WSEQ_ADDR48_SHIFT 0 /* WSEQ_ADDR48 - [13:0] */ -#define WM8995_WSEQ_ADDR48_WIDTH 14 /* WSEQ_ADDR48 - [13:0] */ - -/* - * R12481 (0x30C1) - Write Sequencer 193 - */ -#define WM8995_WSEQ_DATA48_MASK 0x00FF /* WSEQ_DATA48 - [7:0] */ -#define WM8995_WSEQ_DATA48_SHIFT 0 /* WSEQ_DATA48 - [7:0] */ -#define WM8995_WSEQ_DATA48_WIDTH 8 /* WSEQ_DATA48 - [7:0] */ - -/* - * R12482 (0x30C2) - Write Sequencer 194 - */ -#define WM8995_WSEQ_DATA_WIDTH48_MASK 0x0700 /* WSEQ_DATA_WIDTH48 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH48_SHIFT 8 /* WSEQ_DATA_WIDTH48 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH48_WIDTH 3 /* WSEQ_DATA_WIDTH48 - [10:8] */ -#define WM8995_WSEQ_DATA_START48_MASK 0x000F /* WSEQ_DATA_START48 - [3:0] */ -#define WM8995_WSEQ_DATA_START48_SHIFT 0 /* WSEQ_DATA_START48 - [3:0] */ -#define WM8995_WSEQ_DATA_START48_WIDTH 4 /* WSEQ_DATA_START48 - [3:0] */ - -/* - * R12483 (0x30C3) - Write Sequencer 195 - */ -#define WM8995_WSEQ_EOS48 0x0100 /* WSEQ_EOS48 */ -#define WM8995_WSEQ_EOS48_MASK 0x0100 /* WSEQ_EOS48 */ -#define WM8995_WSEQ_EOS48_SHIFT 8 /* WSEQ_EOS48 */ -#define WM8995_WSEQ_EOS48_WIDTH 1 /* WSEQ_EOS48 */ -#define WM8995_WSEQ_DELAY48_MASK 0x000F /* WSEQ_DELAY48 - [3:0] */ -#define WM8995_WSEQ_DELAY48_SHIFT 0 /* WSEQ_DELAY48 - [3:0] */ -#define WM8995_WSEQ_DELAY48_WIDTH 4 /* WSEQ_DELAY48 - [3:0] */ - -/* - * R12484 (0x30C4) - Write Sequencer 196 - */ -#define WM8995_WSEQ_ADDR49_MASK 0x3FFF /* WSEQ_ADDR49 - [13:0] */ -#define WM8995_WSEQ_ADDR49_SHIFT 0 /* WSEQ_ADDR49 - [13:0] */ -#define WM8995_WSEQ_ADDR49_WIDTH 14 /* WSEQ_ADDR49 - [13:0] */ - -/* - * R12485 (0x30C5) - Write Sequencer 197 - */ -#define WM8995_WSEQ_DATA49_MASK 0x00FF /* WSEQ_DATA49 - [7:0] */ -#define WM8995_WSEQ_DATA49_SHIFT 0 /* WSEQ_DATA49 - [7:0] */ -#define WM8995_WSEQ_DATA49_WIDTH 8 /* WSEQ_DATA49 - [7:0] */ - -/* - * R12486 (0x30C6) - Write Sequencer 198 - */ -#define WM8995_WSEQ_DATA_WIDTH49_MASK 0x0700 /* WSEQ_DATA_WIDTH49 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH49_SHIFT 8 /* WSEQ_DATA_WIDTH49 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH49_WIDTH 3 /* WSEQ_DATA_WIDTH49 - [10:8] */ -#define WM8995_WSEQ_DATA_START49_MASK 0x000F /* WSEQ_DATA_START49 - [3:0] */ -#define WM8995_WSEQ_DATA_START49_SHIFT 0 /* WSEQ_DATA_START49 - [3:0] */ -#define WM8995_WSEQ_DATA_START49_WIDTH 4 /* WSEQ_DATA_START49 - [3:0] */ - -/* - * R12487 (0x30C7) - Write Sequencer 199 - */ -#define WM8995_WSEQ_EOS49 0x0100 /* WSEQ_EOS49 */ -#define WM8995_WSEQ_EOS49_MASK 0x0100 /* WSEQ_EOS49 */ -#define WM8995_WSEQ_EOS49_SHIFT 8 /* WSEQ_EOS49 */ -#define WM8995_WSEQ_EOS49_WIDTH 1 /* WSEQ_EOS49 */ -#define WM8995_WSEQ_DELAY49_MASK 0x000F /* WSEQ_DELAY49 - [3:0] */ -#define WM8995_WSEQ_DELAY49_SHIFT 0 /* WSEQ_DELAY49 - [3:0] */ -#define WM8995_WSEQ_DELAY49_WIDTH 4 /* WSEQ_DELAY49 - [3:0] */ - -/* - * R12488 (0x30C8) - Write Sequencer 200 - */ -#define WM8995_WSEQ_ADDR50_MASK 0x3FFF /* WSEQ_ADDR50 - [13:0] */ -#define WM8995_WSEQ_ADDR50_SHIFT 0 /* WSEQ_ADDR50 - [13:0] */ -#define WM8995_WSEQ_ADDR50_WIDTH 14 /* WSEQ_ADDR50 - [13:0] */ - -/* - * R12489 (0x30C9) - Write Sequencer 201 - */ -#define WM8995_WSEQ_DATA50_MASK 0x00FF /* WSEQ_DATA50 - [7:0] */ -#define WM8995_WSEQ_DATA50_SHIFT 0 /* WSEQ_DATA50 - [7:0] */ -#define WM8995_WSEQ_DATA50_WIDTH 8 /* WSEQ_DATA50 - [7:0] */ - -/* - * R12490 (0x30CA) - Write Sequencer 202 - */ -#define WM8995_WSEQ_DATA_WIDTH50_MASK 0x0700 /* WSEQ_DATA_WIDTH50 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH50_SHIFT 8 /* WSEQ_DATA_WIDTH50 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH50_WIDTH 3 /* WSEQ_DATA_WIDTH50 - [10:8] */ -#define WM8995_WSEQ_DATA_START50_MASK 0x000F /* WSEQ_DATA_START50 - [3:0] */ -#define WM8995_WSEQ_DATA_START50_SHIFT 0 /* WSEQ_DATA_START50 - [3:0] */ -#define WM8995_WSEQ_DATA_START50_WIDTH 4 /* WSEQ_DATA_START50 - [3:0] */ - -/* - * R12491 (0x30CB) - Write Sequencer 203 - */ -#define WM8995_WSEQ_EOS50 0x0100 /* WSEQ_EOS50 */ -#define WM8995_WSEQ_EOS50_MASK 0x0100 /* WSEQ_EOS50 */ -#define WM8995_WSEQ_EOS50_SHIFT 8 /* WSEQ_EOS50 */ -#define WM8995_WSEQ_EOS50_WIDTH 1 /* WSEQ_EOS50 */ -#define WM8995_WSEQ_DELAY50_MASK 0x000F /* WSEQ_DELAY50 - [3:0] */ -#define WM8995_WSEQ_DELAY50_SHIFT 0 /* WSEQ_DELAY50 - [3:0] */ -#define WM8995_WSEQ_DELAY50_WIDTH 4 /* WSEQ_DELAY50 - [3:0] */ - -/* - * R12492 (0x30CC) - Write Sequencer 204 - */ -#define WM8995_WSEQ_ADDR51_MASK 0x3FFF /* WSEQ_ADDR51 - [13:0] */ -#define WM8995_WSEQ_ADDR51_SHIFT 0 /* WSEQ_ADDR51 - [13:0] */ -#define WM8995_WSEQ_ADDR51_WIDTH 14 /* WSEQ_ADDR51 - [13:0] */ - -/* - * R12493 (0x30CD) - Write Sequencer 205 - */ -#define WM8995_WSEQ_DATA51_MASK 0x00FF /* WSEQ_DATA51 - [7:0] */ -#define WM8995_WSEQ_DATA51_SHIFT 0 /* WSEQ_DATA51 - [7:0] */ -#define WM8995_WSEQ_DATA51_WIDTH 8 /* WSEQ_DATA51 - [7:0] */ - -/* - * R12494 (0x30CE) - Write Sequencer 206 - */ -#define WM8995_WSEQ_DATA_WIDTH51_MASK 0x0700 /* WSEQ_DATA_WIDTH51 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH51_SHIFT 8 /* WSEQ_DATA_WIDTH51 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH51_WIDTH 3 /* WSEQ_DATA_WIDTH51 - [10:8] */ -#define WM8995_WSEQ_DATA_START51_MASK 0x000F /* WSEQ_DATA_START51 - [3:0] */ -#define WM8995_WSEQ_DATA_START51_SHIFT 0 /* WSEQ_DATA_START51 - [3:0] */ -#define WM8995_WSEQ_DATA_START51_WIDTH 4 /* WSEQ_DATA_START51 - [3:0] */ - -/* - * R12495 (0x30CF) - Write Sequencer 207 - */ -#define WM8995_WSEQ_EOS51 0x0100 /* WSEQ_EOS51 */ -#define WM8995_WSEQ_EOS51_MASK 0x0100 /* WSEQ_EOS51 */ -#define WM8995_WSEQ_EOS51_SHIFT 8 /* WSEQ_EOS51 */ -#define WM8995_WSEQ_EOS51_WIDTH 1 /* WSEQ_EOS51 */ -#define WM8995_WSEQ_DELAY51_MASK 0x000F /* WSEQ_DELAY51 - [3:0] */ -#define WM8995_WSEQ_DELAY51_SHIFT 0 /* WSEQ_DELAY51 - [3:0] */ -#define WM8995_WSEQ_DELAY51_WIDTH 4 /* WSEQ_DELAY51 - [3:0] */ - -/* - * R12496 (0x30D0) - Write Sequencer 208 - */ -#define WM8995_WSEQ_ADDR52_MASK 0x3FFF /* WSEQ_ADDR52 - [13:0] */ -#define WM8995_WSEQ_ADDR52_SHIFT 0 /* WSEQ_ADDR52 - [13:0] */ -#define WM8995_WSEQ_ADDR52_WIDTH 14 /* WSEQ_ADDR52 - [13:0] */ - -/* - * R12497 (0x30D1) - Write Sequencer 209 - */ -#define WM8995_WSEQ_DATA52_MASK 0x00FF /* WSEQ_DATA52 - [7:0] */ -#define WM8995_WSEQ_DATA52_SHIFT 0 /* WSEQ_DATA52 - [7:0] */ -#define WM8995_WSEQ_DATA52_WIDTH 8 /* WSEQ_DATA52 - [7:0] */ - -/* - * R12498 (0x30D2) - Write Sequencer 210 - */ -#define WM8995_WSEQ_DATA_WIDTH52_MASK 0x0700 /* WSEQ_DATA_WIDTH52 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH52_SHIFT 8 /* WSEQ_DATA_WIDTH52 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH52_WIDTH 3 /* WSEQ_DATA_WIDTH52 - [10:8] */ -#define WM8995_WSEQ_DATA_START52_MASK 0x000F /* WSEQ_DATA_START52 - [3:0] */ -#define WM8995_WSEQ_DATA_START52_SHIFT 0 /* WSEQ_DATA_START52 - [3:0] */ -#define WM8995_WSEQ_DATA_START52_WIDTH 4 /* WSEQ_DATA_START52 - [3:0] */ - -/* - * R12499 (0x30D3) - Write Sequencer 211 - */ -#define WM8995_WSEQ_EOS52 0x0100 /* WSEQ_EOS52 */ -#define WM8995_WSEQ_EOS52_MASK 0x0100 /* WSEQ_EOS52 */ -#define WM8995_WSEQ_EOS52_SHIFT 8 /* WSEQ_EOS52 */ -#define WM8995_WSEQ_EOS52_WIDTH 1 /* WSEQ_EOS52 */ -#define WM8995_WSEQ_DELAY52_MASK 0x000F /* WSEQ_DELAY52 - [3:0] */ -#define WM8995_WSEQ_DELAY52_SHIFT 0 /* WSEQ_DELAY52 - [3:0] */ -#define WM8995_WSEQ_DELAY52_WIDTH 4 /* WSEQ_DELAY52 - [3:0] */ - -/* - * R12500 (0x30D4) - Write Sequencer 212 - */ -#define WM8995_WSEQ_ADDR53_MASK 0x3FFF /* WSEQ_ADDR53 - [13:0] */ -#define WM8995_WSEQ_ADDR53_SHIFT 0 /* WSEQ_ADDR53 - [13:0] */ -#define WM8995_WSEQ_ADDR53_WIDTH 14 /* WSEQ_ADDR53 - [13:0] */ - -/* - * R12501 (0x30D5) - Write Sequencer 213 - */ -#define WM8995_WSEQ_DATA53_MASK 0x00FF /* WSEQ_DATA53 - [7:0] */ -#define WM8995_WSEQ_DATA53_SHIFT 0 /* WSEQ_DATA53 - [7:0] */ -#define WM8995_WSEQ_DATA53_WIDTH 8 /* WSEQ_DATA53 - [7:0] */ - -/* - * R12502 (0x30D6) - Write Sequencer 214 - */ -#define WM8995_WSEQ_DATA_WIDTH53_MASK 0x0700 /* WSEQ_DATA_WIDTH53 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH53_SHIFT 8 /* WSEQ_DATA_WIDTH53 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH53_WIDTH 3 /* WSEQ_DATA_WIDTH53 - [10:8] */ -#define WM8995_WSEQ_DATA_START53_MASK 0x000F /* WSEQ_DATA_START53 - [3:0] */ -#define WM8995_WSEQ_DATA_START53_SHIFT 0 /* WSEQ_DATA_START53 - [3:0] */ -#define WM8995_WSEQ_DATA_START53_WIDTH 4 /* WSEQ_DATA_START53 - [3:0] */ - -/* - * R12503 (0x30D7) - Write Sequencer 215 - */ -#define WM8995_WSEQ_EOS53 0x0100 /* WSEQ_EOS53 */ -#define WM8995_WSEQ_EOS53_MASK 0x0100 /* WSEQ_EOS53 */ -#define WM8995_WSEQ_EOS53_SHIFT 8 /* WSEQ_EOS53 */ -#define WM8995_WSEQ_EOS53_WIDTH 1 /* WSEQ_EOS53 */ -#define WM8995_WSEQ_DELAY53_MASK 0x000F /* WSEQ_DELAY53 - [3:0] */ -#define WM8995_WSEQ_DELAY53_SHIFT 0 /* WSEQ_DELAY53 - [3:0] */ -#define WM8995_WSEQ_DELAY53_WIDTH 4 /* WSEQ_DELAY53 - [3:0] */ - -/* - * R12504 (0x30D8) - Write Sequencer 216 - */ -#define WM8995_WSEQ_ADDR54_MASK 0x3FFF /* WSEQ_ADDR54 - [13:0] */ -#define WM8995_WSEQ_ADDR54_SHIFT 0 /* WSEQ_ADDR54 - [13:0] */ -#define WM8995_WSEQ_ADDR54_WIDTH 14 /* WSEQ_ADDR54 - [13:0] */ - -/* - * R12505 (0x30D9) - Write Sequencer 217 - */ -#define WM8995_WSEQ_DATA54_MASK 0x00FF /* WSEQ_DATA54 - [7:0] */ -#define WM8995_WSEQ_DATA54_SHIFT 0 /* WSEQ_DATA54 - [7:0] */ -#define WM8995_WSEQ_DATA54_WIDTH 8 /* WSEQ_DATA54 - [7:0] */ - -/* - * R12506 (0x30DA) - Write Sequencer 218 - */ -#define WM8995_WSEQ_DATA_WIDTH54_MASK 0x0700 /* WSEQ_DATA_WIDTH54 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH54_SHIFT 8 /* WSEQ_DATA_WIDTH54 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH54_WIDTH 3 /* WSEQ_DATA_WIDTH54 - [10:8] */ -#define WM8995_WSEQ_DATA_START54_MASK 0x000F /* WSEQ_DATA_START54 - [3:0] */ -#define WM8995_WSEQ_DATA_START54_SHIFT 0 /* WSEQ_DATA_START54 - [3:0] */ -#define WM8995_WSEQ_DATA_START54_WIDTH 4 /* WSEQ_DATA_START54 - [3:0] */ - -/* - * R12507 (0x30DB) - Write Sequencer 219 - */ -#define WM8995_WSEQ_EOS54 0x0100 /* WSEQ_EOS54 */ -#define WM8995_WSEQ_EOS54_MASK 0x0100 /* WSEQ_EOS54 */ -#define WM8995_WSEQ_EOS54_SHIFT 8 /* WSEQ_EOS54 */ -#define WM8995_WSEQ_EOS54_WIDTH 1 /* WSEQ_EOS54 */ -#define WM8995_WSEQ_DELAY54_MASK 0x000F /* WSEQ_DELAY54 - [3:0] */ -#define WM8995_WSEQ_DELAY54_SHIFT 0 /* WSEQ_DELAY54 - [3:0] */ -#define WM8995_WSEQ_DELAY54_WIDTH 4 /* WSEQ_DELAY54 - [3:0] */ - -/* - * R12508 (0x30DC) - Write Sequencer 220 - */ -#define WM8995_WSEQ_ADDR55_MASK 0x3FFF /* WSEQ_ADDR55 - [13:0] */ -#define WM8995_WSEQ_ADDR55_SHIFT 0 /* WSEQ_ADDR55 - [13:0] */ -#define WM8995_WSEQ_ADDR55_WIDTH 14 /* WSEQ_ADDR55 - [13:0] */ - -/* - * R12509 (0x30DD) - Write Sequencer 221 - */ -#define WM8995_WSEQ_DATA55_MASK 0x00FF /* WSEQ_DATA55 - [7:0] */ -#define WM8995_WSEQ_DATA55_SHIFT 0 /* WSEQ_DATA55 - [7:0] */ -#define WM8995_WSEQ_DATA55_WIDTH 8 /* WSEQ_DATA55 - [7:0] */ - -/* - * R12510 (0x30DE) - Write Sequencer 222 - */ -#define WM8995_WSEQ_DATA_WIDTH55_MASK 0x0700 /* WSEQ_DATA_WIDTH55 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH55_SHIFT 8 /* WSEQ_DATA_WIDTH55 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH55_WIDTH 3 /* WSEQ_DATA_WIDTH55 - [10:8] */ -#define WM8995_WSEQ_DATA_START55_MASK 0x000F /* WSEQ_DATA_START55 - [3:0] */ -#define WM8995_WSEQ_DATA_START55_SHIFT 0 /* WSEQ_DATA_START55 - [3:0] */ -#define WM8995_WSEQ_DATA_START55_WIDTH 4 /* WSEQ_DATA_START55 - [3:0] */ - -/* - * R12511 (0x30DF) - Write Sequencer 223 - */ -#define WM8995_WSEQ_EOS55 0x0100 /* WSEQ_EOS55 */ -#define WM8995_WSEQ_EOS55_MASK 0x0100 /* WSEQ_EOS55 */ -#define WM8995_WSEQ_EOS55_SHIFT 8 /* WSEQ_EOS55 */ -#define WM8995_WSEQ_EOS55_WIDTH 1 /* WSEQ_EOS55 */ -#define WM8995_WSEQ_DELAY55_MASK 0x000F /* WSEQ_DELAY55 - [3:0] */ -#define WM8995_WSEQ_DELAY55_SHIFT 0 /* WSEQ_DELAY55 - [3:0] */ -#define WM8995_WSEQ_DELAY55_WIDTH 4 /* WSEQ_DELAY55 - [3:0] */ - -/* - * R12512 (0x30E0) - Write Sequencer 224 - */ -#define WM8995_WSEQ_ADDR56_MASK 0x3FFF /* WSEQ_ADDR56 - [13:0] */ -#define WM8995_WSEQ_ADDR56_SHIFT 0 /* WSEQ_ADDR56 - [13:0] */ -#define WM8995_WSEQ_ADDR56_WIDTH 14 /* WSEQ_ADDR56 - [13:0] */ - -/* - * R12513 (0x30E1) - Write Sequencer 225 - */ -#define WM8995_WSEQ_DATA56_MASK 0x00FF /* WSEQ_DATA56 - [7:0] */ -#define WM8995_WSEQ_DATA56_SHIFT 0 /* WSEQ_DATA56 - [7:0] */ -#define WM8995_WSEQ_DATA56_WIDTH 8 /* WSEQ_DATA56 - [7:0] */ - -/* - * R12514 (0x30E2) - Write Sequencer 226 - */ -#define WM8995_WSEQ_DATA_WIDTH56_MASK 0x0700 /* WSEQ_DATA_WIDTH56 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH56_SHIFT 8 /* WSEQ_DATA_WIDTH56 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH56_WIDTH 3 /* WSEQ_DATA_WIDTH56 - [10:8] */ -#define WM8995_WSEQ_DATA_START56_MASK 0x000F /* WSEQ_DATA_START56 - [3:0] */ -#define WM8995_WSEQ_DATA_START56_SHIFT 0 /* WSEQ_DATA_START56 - [3:0] */ -#define WM8995_WSEQ_DATA_START56_WIDTH 4 /* WSEQ_DATA_START56 - [3:0] */ - -/* - * R12515 (0x30E3) - Write Sequencer 227 - */ -#define WM8995_WSEQ_EOS56 0x0100 /* WSEQ_EOS56 */ -#define WM8995_WSEQ_EOS56_MASK 0x0100 /* WSEQ_EOS56 */ -#define WM8995_WSEQ_EOS56_SHIFT 8 /* WSEQ_EOS56 */ -#define WM8995_WSEQ_EOS56_WIDTH 1 /* WSEQ_EOS56 */ -#define WM8995_WSEQ_DELAY56_MASK 0x000F /* WSEQ_DELAY56 - [3:0] */ -#define WM8995_WSEQ_DELAY56_SHIFT 0 /* WSEQ_DELAY56 - [3:0] */ -#define WM8995_WSEQ_DELAY56_WIDTH 4 /* WSEQ_DELAY56 - [3:0] */ - -/* - * R12516 (0x30E4) - Write Sequencer 228 - */ -#define WM8995_WSEQ_ADDR57_MASK 0x3FFF /* WSEQ_ADDR57 - [13:0] */ -#define WM8995_WSEQ_ADDR57_SHIFT 0 /* WSEQ_ADDR57 - [13:0] */ -#define WM8995_WSEQ_ADDR57_WIDTH 14 /* WSEQ_ADDR57 - [13:0] */ - -/* - * R12517 (0x30E5) - Write Sequencer 229 - */ -#define WM8995_WSEQ_DATA57_MASK 0x00FF /* WSEQ_DATA57 - [7:0] */ -#define WM8995_WSEQ_DATA57_SHIFT 0 /* WSEQ_DATA57 - [7:0] */ -#define WM8995_WSEQ_DATA57_WIDTH 8 /* WSEQ_DATA57 - [7:0] */ - -/* - * R12518 (0x30E6) - Write Sequencer 230 - */ -#define WM8995_WSEQ_DATA_WIDTH57_MASK 0x0700 /* WSEQ_DATA_WIDTH57 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH57_SHIFT 8 /* WSEQ_DATA_WIDTH57 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH57_WIDTH 3 /* WSEQ_DATA_WIDTH57 - [10:8] */ -#define WM8995_WSEQ_DATA_START57_MASK 0x000F /* WSEQ_DATA_START57 - [3:0] */ -#define WM8995_WSEQ_DATA_START57_SHIFT 0 /* WSEQ_DATA_START57 - [3:0] */ -#define WM8995_WSEQ_DATA_START57_WIDTH 4 /* WSEQ_DATA_START57 - [3:0] */ - -/* - * R12519 (0x30E7) - Write Sequencer 231 - */ -#define WM8995_WSEQ_EOS57 0x0100 /* WSEQ_EOS57 */ -#define WM8995_WSEQ_EOS57_MASK 0x0100 /* WSEQ_EOS57 */ -#define WM8995_WSEQ_EOS57_SHIFT 8 /* WSEQ_EOS57 */ -#define WM8995_WSEQ_EOS57_WIDTH 1 /* WSEQ_EOS57 */ -#define WM8995_WSEQ_DELAY57_MASK 0x000F /* WSEQ_DELAY57 - [3:0] */ -#define WM8995_WSEQ_DELAY57_SHIFT 0 /* WSEQ_DELAY57 - [3:0] */ -#define WM8995_WSEQ_DELAY57_WIDTH 4 /* WSEQ_DELAY57 - [3:0] */ - -/* - * R12520 (0x30E8) - Write Sequencer 232 - */ -#define WM8995_WSEQ_ADDR58_MASK 0x3FFF /* WSEQ_ADDR58 - [13:0] */ -#define WM8995_WSEQ_ADDR58_SHIFT 0 /* WSEQ_ADDR58 - [13:0] */ -#define WM8995_WSEQ_ADDR58_WIDTH 14 /* WSEQ_ADDR58 - [13:0] */ - -/* - * R12521 (0x30E9) - Write Sequencer 233 - */ -#define WM8995_WSEQ_DATA58_MASK 0x00FF /* WSEQ_DATA58 - [7:0] */ -#define WM8995_WSEQ_DATA58_SHIFT 0 /* WSEQ_DATA58 - [7:0] */ -#define WM8995_WSEQ_DATA58_WIDTH 8 /* WSEQ_DATA58 - [7:0] */ - -/* - * R12522 (0x30EA) - Write Sequencer 234 - */ -#define WM8995_WSEQ_DATA_WIDTH58_MASK 0x0700 /* WSEQ_DATA_WIDTH58 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH58_SHIFT 8 /* WSEQ_DATA_WIDTH58 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH58_WIDTH 3 /* WSEQ_DATA_WIDTH58 - [10:8] */ -#define WM8995_WSEQ_DATA_START58_MASK 0x000F /* WSEQ_DATA_START58 - [3:0] */ -#define WM8995_WSEQ_DATA_START58_SHIFT 0 /* WSEQ_DATA_START58 - [3:0] */ -#define WM8995_WSEQ_DATA_START58_WIDTH 4 /* WSEQ_DATA_START58 - [3:0] */ - -/* - * R12523 (0x30EB) - Write Sequencer 235 - */ -#define WM8995_WSEQ_EOS58 0x0100 /* WSEQ_EOS58 */ -#define WM8995_WSEQ_EOS58_MASK 0x0100 /* WSEQ_EOS58 */ -#define WM8995_WSEQ_EOS58_SHIFT 8 /* WSEQ_EOS58 */ -#define WM8995_WSEQ_EOS58_WIDTH 1 /* WSEQ_EOS58 */ -#define WM8995_WSEQ_DELAY58_MASK 0x000F /* WSEQ_DELAY58 - [3:0] */ -#define WM8995_WSEQ_DELAY58_SHIFT 0 /* WSEQ_DELAY58 - [3:0] */ -#define WM8995_WSEQ_DELAY58_WIDTH 4 /* WSEQ_DELAY58 - [3:0] */ - -/* - * R12524 (0x30EC) - Write Sequencer 236 - */ -#define WM8995_WSEQ_ADDR59_MASK 0x3FFF /* WSEQ_ADDR59 - [13:0] */ -#define WM8995_WSEQ_ADDR59_SHIFT 0 /* WSEQ_ADDR59 - [13:0] */ -#define WM8995_WSEQ_ADDR59_WIDTH 14 /* WSEQ_ADDR59 - [13:0] */ - -/* - * R12525 (0x30ED) - Write Sequencer 237 - */ -#define WM8995_WSEQ_DATA59_MASK 0x00FF /* WSEQ_DATA59 - [7:0] */ -#define WM8995_WSEQ_DATA59_SHIFT 0 /* WSEQ_DATA59 - [7:0] */ -#define WM8995_WSEQ_DATA59_WIDTH 8 /* WSEQ_DATA59 - [7:0] */ - -/* - * R12526 (0x30EE) - Write Sequencer 238 - */ -#define WM8995_WSEQ_DATA_WIDTH59_MASK 0x0700 /* WSEQ_DATA_WIDTH59 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH59_SHIFT 8 /* WSEQ_DATA_WIDTH59 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH59_WIDTH 3 /* WSEQ_DATA_WIDTH59 - [10:8] */ -#define WM8995_WSEQ_DATA_START59_MASK 0x000F /* WSEQ_DATA_START59 - [3:0] */ -#define WM8995_WSEQ_DATA_START59_SHIFT 0 /* WSEQ_DATA_START59 - [3:0] */ -#define WM8995_WSEQ_DATA_START59_WIDTH 4 /* WSEQ_DATA_START59 - [3:0] */ - -/* - * R12527 (0x30EF) - Write Sequencer 239 - */ -#define WM8995_WSEQ_EOS59 0x0100 /* WSEQ_EOS59 */ -#define WM8995_WSEQ_EOS59_MASK 0x0100 /* WSEQ_EOS59 */ -#define WM8995_WSEQ_EOS59_SHIFT 8 /* WSEQ_EOS59 */ -#define WM8995_WSEQ_EOS59_WIDTH 1 /* WSEQ_EOS59 */ -#define WM8995_WSEQ_DELAY59_MASK 0x000F /* WSEQ_DELAY59 - [3:0] */ -#define WM8995_WSEQ_DELAY59_SHIFT 0 /* WSEQ_DELAY59 - [3:0] */ -#define WM8995_WSEQ_DELAY59_WIDTH 4 /* WSEQ_DELAY59 - [3:0] */ - -/* - * R12528 (0x30F0) - Write Sequencer 240 - */ -#define WM8995_WSEQ_ADDR60_MASK 0x3FFF /* WSEQ_ADDR60 - [13:0] */ -#define WM8995_WSEQ_ADDR60_SHIFT 0 /* WSEQ_ADDR60 - [13:0] */ -#define WM8995_WSEQ_ADDR60_WIDTH 14 /* WSEQ_ADDR60 - [13:0] */ - -/* - * R12529 (0x30F1) - Write Sequencer 241 - */ -#define WM8995_WSEQ_DATA60_MASK 0x00FF /* WSEQ_DATA60 - [7:0] */ -#define WM8995_WSEQ_DATA60_SHIFT 0 /* WSEQ_DATA60 - [7:0] */ -#define WM8995_WSEQ_DATA60_WIDTH 8 /* WSEQ_DATA60 - [7:0] */ - -/* - * R12530 (0x30F2) - Write Sequencer 242 - */ -#define WM8995_WSEQ_DATA_WIDTH60_MASK 0x0700 /* WSEQ_DATA_WIDTH60 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH60_SHIFT 8 /* WSEQ_DATA_WIDTH60 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH60_WIDTH 3 /* WSEQ_DATA_WIDTH60 - [10:8] */ -#define WM8995_WSEQ_DATA_START60_MASK 0x000F /* WSEQ_DATA_START60 - [3:0] */ -#define WM8995_WSEQ_DATA_START60_SHIFT 0 /* WSEQ_DATA_START60 - [3:0] */ -#define WM8995_WSEQ_DATA_START60_WIDTH 4 /* WSEQ_DATA_START60 - [3:0] */ - -/* - * R12531 (0x30F3) - Write Sequencer 243 - */ -#define WM8995_WSEQ_EOS60 0x0100 /* WSEQ_EOS60 */ -#define WM8995_WSEQ_EOS60_MASK 0x0100 /* WSEQ_EOS60 */ -#define WM8995_WSEQ_EOS60_SHIFT 8 /* WSEQ_EOS60 */ -#define WM8995_WSEQ_EOS60_WIDTH 1 /* WSEQ_EOS60 */ -#define WM8995_WSEQ_DELAY60_MASK 0x000F /* WSEQ_DELAY60 - [3:0] */ -#define WM8995_WSEQ_DELAY60_SHIFT 0 /* WSEQ_DELAY60 - [3:0] */ -#define WM8995_WSEQ_DELAY60_WIDTH 4 /* WSEQ_DELAY60 - [3:0] */ - -/* - * R12532 (0x30F4) - Write Sequencer 244 - */ -#define WM8995_WSEQ_ADDR61_MASK 0x3FFF /* WSEQ_ADDR61 - [13:0] */ -#define WM8995_WSEQ_ADDR61_SHIFT 0 /* WSEQ_ADDR61 - [13:0] */ -#define WM8995_WSEQ_ADDR61_WIDTH 14 /* WSEQ_ADDR61 - [13:0] */ - -/* - * R12533 (0x30F5) - Write Sequencer 245 - */ -#define WM8995_WSEQ_DATA61_MASK 0x00FF /* WSEQ_DATA61 - [7:0] */ -#define WM8995_WSEQ_DATA61_SHIFT 0 /* WSEQ_DATA61 - [7:0] */ -#define WM8995_WSEQ_DATA61_WIDTH 8 /* WSEQ_DATA61 - [7:0] */ - -/* - * R12534 (0x30F6) - Write Sequencer 246 - */ -#define WM8995_WSEQ_DATA_WIDTH61_MASK 0x0700 /* WSEQ_DATA_WIDTH61 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH61_SHIFT 8 /* WSEQ_DATA_WIDTH61 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH61_WIDTH 3 /* WSEQ_DATA_WIDTH61 - [10:8] */ -#define WM8995_WSEQ_DATA_START61_MASK 0x000F /* WSEQ_DATA_START61 - [3:0] */ -#define WM8995_WSEQ_DATA_START61_SHIFT 0 /* WSEQ_DATA_START61 - [3:0] */ -#define WM8995_WSEQ_DATA_START61_WIDTH 4 /* WSEQ_DATA_START61 - [3:0] */ - -/* - * R12535 (0x30F7) - Write Sequencer 247 - */ -#define WM8995_WSEQ_EOS61 0x0100 /* WSEQ_EOS61 */ -#define WM8995_WSEQ_EOS61_MASK 0x0100 /* WSEQ_EOS61 */ -#define WM8995_WSEQ_EOS61_SHIFT 8 /* WSEQ_EOS61 */ -#define WM8995_WSEQ_EOS61_WIDTH 1 /* WSEQ_EOS61 */ -#define WM8995_WSEQ_DELAY61_MASK 0x000F /* WSEQ_DELAY61 - [3:0] */ -#define WM8995_WSEQ_DELAY61_SHIFT 0 /* WSEQ_DELAY61 - [3:0] */ -#define WM8995_WSEQ_DELAY61_WIDTH 4 /* WSEQ_DELAY61 - [3:0] */ - -/* - * R12536 (0x30F8) - Write Sequencer 248 - */ -#define WM8995_WSEQ_ADDR62_MASK 0x3FFF /* WSEQ_ADDR62 - [13:0] */ -#define WM8995_WSEQ_ADDR62_SHIFT 0 /* WSEQ_ADDR62 - [13:0] */ -#define WM8995_WSEQ_ADDR62_WIDTH 14 /* WSEQ_ADDR62 - [13:0] */ - -/* - * R12537 (0x30F9) - Write Sequencer 249 - */ -#define WM8995_WSEQ_DATA62_MASK 0x00FF /* WSEQ_DATA62 - [7:0] */ -#define WM8995_WSEQ_DATA62_SHIFT 0 /* WSEQ_DATA62 - [7:0] */ -#define WM8995_WSEQ_DATA62_WIDTH 8 /* WSEQ_DATA62 - [7:0] */ - -/* - * R12538 (0x30FA) - Write Sequencer 250 - */ -#define WM8995_WSEQ_DATA_WIDTH62_MASK 0x0700 /* WSEQ_DATA_WIDTH62 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH62_SHIFT 8 /* WSEQ_DATA_WIDTH62 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH62_WIDTH 3 /* WSEQ_DATA_WIDTH62 - [10:8] */ -#define WM8995_WSEQ_DATA_START62_MASK 0x000F /* WSEQ_DATA_START62 - [3:0] */ -#define WM8995_WSEQ_DATA_START62_SHIFT 0 /* WSEQ_DATA_START62 - [3:0] */ -#define WM8995_WSEQ_DATA_START62_WIDTH 4 /* WSEQ_DATA_START62 - [3:0] */ - -/* - * R12539 (0x30FB) - Write Sequencer 251 - */ -#define WM8995_WSEQ_EOS62 0x0100 /* WSEQ_EOS62 */ -#define WM8995_WSEQ_EOS62_MASK 0x0100 /* WSEQ_EOS62 */ -#define WM8995_WSEQ_EOS62_SHIFT 8 /* WSEQ_EOS62 */ -#define WM8995_WSEQ_EOS62_WIDTH 1 /* WSEQ_EOS62 */ -#define WM8995_WSEQ_DELAY62_MASK 0x000F /* WSEQ_DELAY62 - [3:0] */ -#define WM8995_WSEQ_DELAY62_SHIFT 0 /* WSEQ_DELAY62 - [3:0] */ -#define WM8995_WSEQ_DELAY62_WIDTH 4 /* WSEQ_DELAY62 - [3:0] */ - -/* - * R12540 (0x30FC) - Write Sequencer 252 - */ -#define WM8995_WSEQ_ADDR63_MASK 0x3FFF /* WSEQ_ADDR63 - [13:0] */ -#define WM8995_WSEQ_ADDR63_SHIFT 0 /* WSEQ_ADDR63 - [13:0] */ -#define WM8995_WSEQ_ADDR63_WIDTH 14 /* WSEQ_ADDR63 - [13:0] */ - -/* - * R12541 (0x30FD) - Write Sequencer 253 - */ -#define WM8995_WSEQ_DATA63_MASK 0x00FF /* WSEQ_DATA63 - [7:0] */ -#define WM8995_WSEQ_DATA63_SHIFT 0 /* WSEQ_DATA63 - [7:0] */ -#define WM8995_WSEQ_DATA63_WIDTH 8 /* WSEQ_DATA63 - [7:0] */ - -/* - * R12542 (0x30FE) - Write Sequencer 254 - */ -#define WM8995_WSEQ_DATA_WIDTH63_MASK 0x0700 /* WSEQ_DATA_WIDTH63 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH63_SHIFT 8 /* WSEQ_DATA_WIDTH63 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH63_WIDTH 3 /* WSEQ_DATA_WIDTH63 - [10:8] */ -#define WM8995_WSEQ_DATA_START63_MASK 0x000F /* WSEQ_DATA_START63 - [3:0] */ -#define WM8995_WSEQ_DATA_START63_SHIFT 0 /* WSEQ_DATA_START63 - [3:0] */ -#define WM8995_WSEQ_DATA_START63_WIDTH 4 /* WSEQ_DATA_START63 - [3:0] */ - -/* - * R12543 (0x30FF) - Write Sequencer 255 - */ -#define WM8995_WSEQ_EOS63 0x0100 /* WSEQ_EOS63 */ -#define WM8995_WSEQ_EOS63_MASK 0x0100 /* WSEQ_EOS63 */ -#define WM8995_WSEQ_EOS63_SHIFT 8 /* WSEQ_EOS63 */ -#define WM8995_WSEQ_EOS63_WIDTH 1 /* WSEQ_EOS63 */ -#define WM8995_WSEQ_DELAY63_MASK 0x000F /* WSEQ_DELAY63 - [3:0] */ -#define WM8995_WSEQ_DELAY63_SHIFT 0 /* WSEQ_DELAY63 - [3:0] */ -#define WM8995_WSEQ_DELAY63_WIDTH 4 /* WSEQ_DELAY63 - [3:0] */ - -/* - * R12544 (0x3100) - Write Sequencer 256 - */ -#define WM8995_WSEQ_ADDR64_MASK 0x3FFF /* WSEQ_ADDR64 - [13:0] */ -#define WM8995_WSEQ_ADDR64_SHIFT 0 /* WSEQ_ADDR64 - [13:0] */ -#define WM8995_WSEQ_ADDR64_WIDTH 14 /* WSEQ_ADDR64 - [13:0] */ - -/* - * R12545 (0x3101) - Write Sequencer 257 - */ -#define WM8995_WSEQ_DATA64_MASK 0x00FF /* WSEQ_DATA64 - [7:0] */ -#define WM8995_WSEQ_DATA64_SHIFT 0 /* WSEQ_DATA64 - [7:0] */ -#define WM8995_WSEQ_DATA64_WIDTH 8 /* WSEQ_DATA64 - [7:0] */ - -/* - * R12546 (0x3102) - Write Sequencer 258 - */ -#define WM8995_WSEQ_DATA_WIDTH64_MASK 0x0700 /* WSEQ_DATA_WIDTH64 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH64_SHIFT 8 /* WSEQ_DATA_WIDTH64 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH64_WIDTH 3 /* WSEQ_DATA_WIDTH64 - [10:8] */ -#define WM8995_WSEQ_DATA_START64_MASK 0x000F /* WSEQ_DATA_START64 - [3:0] */ -#define WM8995_WSEQ_DATA_START64_SHIFT 0 /* WSEQ_DATA_START64 - [3:0] */ -#define WM8995_WSEQ_DATA_START64_WIDTH 4 /* WSEQ_DATA_START64 - [3:0] */ - -/* - * R12547 (0x3103) - Write Sequencer 259 - */ -#define WM8995_WSEQ_EOS64 0x0100 /* WSEQ_EOS64 */ -#define WM8995_WSEQ_EOS64_MASK 0x0100 /* WSEQ_EOS64 */ -#define WM8995_WSEQ_EOS64_SHIFT 8 /* WSEQ_EOS64 */ -#define WM8995_WSEQ_EOS64_WIDTH 1 /* WSEQ_EOS64 */ -#define WM8995_WSEQ_DELAY64_MASK 0x000F /* WSEQ_DELAY64 - [3:0] */ -#define WM8995_WSEQ_DELAY64_SHIFT 0 /* WSEQ_DELAY64 - [3:0] */ -#define WM8995_WSEQ_DELAY64_WIDTH 4 /* WSEQ_DELAY64 - [3:0] */ - -/* - * R12548 (0x3104) - Write Sequencer 260 - */ -#define WM8995_WSEQ_ADDR65_MASK 0x3FFF /* WSEQ_ADDR65 - [13:0] */ -#define WM8995_WSEQ_ADDR65_SHIFT 0 /* WSEQ_ADDR65 - [13:0] */ -#define WM8995_WSEQ_ADDR65_WIDTH 14 /* WSEQ_ADDR65 - [13:0] */ - -/* - * R12549 (0x3105) - Write Sequencer 261 - */ -#define WM8995_WSEQ_DATA65_MASK 0x00FF /* WSEQ_DATA65 - [7:0] */ -#define WM8995_WSEQ_DATA65_SHIFT 0 /* WSEQ_DATA65 - [7:0] */ -#define WM8995_WSEQ_DATA65_WIDTH 8 /* WSEQ_DATA65 - [7:0] */ - -/* - * R12550 (0x3106) - Write Sequencer 262 - */ -#define WM8995_WSEQ_DATA_WIDTH65_MASK 0x0700 /* WSEQ_DATA_WIDTH65 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH65_SHIFT 8 /* WSEQ_DATA_WIDTH65 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH65_WIDTH 3 /* WSEQ_DATA_WIDTH65 - [10:8] */ -#define WM8995_WSEQ_DATA_START65_MASK 0x000F /* WSEQ_DATA_START65 - [3:0] */ -#define WM8995_WSEQ_DATA_START65_SHIFT 0 /* WSEQ_DATA_START65 - [3:0] */ -#define WM8995_WSEQ_DATA_START65_WIDTH 4 /* WSEQ_DATA_START65 - [3:0] */ - -/* - * R12551 (0x3107) - Write Sequencer 263 - */ -#define WM8995_WSEQ_EOS65 0x0100 /* WSEQ_EOS65 */ -#define WM8995_WSEQ_EOS65_MASK 0x0100 /* WSEQ_EOS65 */ -#define WM8995_WSEQ_EOS65_SHIFT 8 /* WSEQ_EOS65 */ -#define WM8995_WSEQ_EOS65_WIDTH 1 /* WSEQ_EOS65 */ -#define WM8995_WSEQ_DELAY65_MASK 0x000F /* WSEQ_DELAY65 - [3:0] */ -#define WM8995_WSEQ_DELAY65_SHIFT 0 /* WSEQ_DELAY65 - [3:0] */ -#define WM8995_WSEQ_DELAY65_WIDTH 4 /* WSEQ_DELAY65 - [3:0] */ - -/* - * R12552 (0x3108) - Write Sequencer 264 - */ -#define WM8995_WSEQ_ADDR66_MASK 0x3FFF /* WSEQ_ADDR66 - [13:0] */ -#define WM8995_WSEQ_ADDR66_SHIFT 0 /* WSEQ_ADDR66 - [13:0] */ -#define WM8995_WSEQ_ADDR66_WIDTH 14 /* WSEQ_ADDR66 - [13:0] */ - -/* - * R12553 (0x3109) - Write Sequencer 265 - */ -#define WM8995_WSEQ_DATA66_MASK 0x00FF /* WSEQ_DATA66 - [7:0] */ -#define WM8995_WSEQ_DATA66_SHIFT 0 /* WSEQ_DATA66 - [7:0] */ -#define WM8995_WSEQ_DATA66_WIDTH 8 /* WSEQ_DATA66 - [7:0] */ - -/* - * R12554 (0x310A) - Write Sequencer 266 - */ -#define WM8995_WSEQ_DATA_WIDTH66_MASK 0x0700 /* WSEQ_DATA_WIDTH66 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH66_SHIFT 8 /* WSEQ_DATA_WIDTH66 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH66_WIDTH 3 /* WSEQ_DATA_WIDTH66 - [10:8] */ -#define WM8995_WSEQ_DATA_START66_MASK 0x000F /* WSEQ_DATA_START66 - [3:0] */ -#define WM8995_WSEQ_DATA_START66_SHIFT 0 /* WSEQ_DATA_START66 - [3:0] */ -#define WM8995_WSEQ_DATA_START66_WIDTH 4 /* WSEQ_DATA_START66 - [3:0] */ - -/* - * R12555 (0x310B) - Write Sequencer 267 - */ -#define WM8995_WSEQ_EOS66 0x0100 /* WSEQ_EOS66 */ -#define WM8995_WSEQ_EOS66_MASK 0x0100 /* WSEQ_EOS66 */ -#define WM8995_WSEQ_EOS66_SHIFT 8 /* WSEQ_EOS66 */ -#define WM8995_WSEQ_EOS66_WIDTH 1 /* WSEQ_EOS66 */ -#define WM8995_WSEQ_DELAY66_MASK 0x000F /* WSEQ_DELAY66 - [3:0] */ -#define WM8995_WSEQ_DELAY66_SHIFT 0 /* WSEQ_DELAY66 - [3:0] */ -#define WM8995_WSEQ_DELAY66_WIDTH 4 /* WSEQ_DELAY66 - [3:0] */ - -/* - * R12556 (0x310C) - Write Sequencer 268 - */ -#define WM8995_WSEQ_ADDR67_MASK 0x3FFF /* WSEQ_ADDR67 - [13:0] */ -#define WM8995_WSEQ_ADDR67_SHIFT 0 /* WSEQ_ADDR67 - [13:0] */ -#define WM8995_WSEQ_ADDR67_WIDTH 14 /* WSEQ_ADDR67 - [13:0] */ - -/* - * R12557 (0x310D) - Write Sequencer 269 - */ -#define WM8995_WSEQ_DATA67_MASK 0x00FF /* WSEQ_DATA67 - [7:0] */ -#define WM8995_WSEQ_DATA67_SHIFT 0 /* WSEQ_DATA67 - [7:0] */ -#define WM8995_WSEQ_DATA67_WIDTH 8 /* WSEQ_DATA67 - [7:0] */ - -/* - * R12558 (0x310E) - Write Sequencer 270 - */ -#define WM8995_WSEQ_DATA_WIDTH67_MASK 0x0700 /* WSEQ_DATA_WIDTH67 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH67_SHIFT 8 /* WSEQ_DATA_WIDTH67 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH67_WIDTH 3 /* WSEQ_DATA_WIDTH67 - [10:8] */ -#define WM8995_WSEQ_DATA_START67_MASK 0x000F /* WSEQ_DATA_START67 - [3:0] */ -#define WM8995_WSEQ_DATA_START67_SHIFT 0 /* WSEQ_DATA_START67 - [3:0] */ -#define WM8995_WSEQ_DATA_START67_WIDTH 4 /* WSEQ_DATA_START67 - [3:0] */ - -/* - * R12559 (0x310F) - Write Sequencer 271 - */ -#define WM8995_WSEQ_EOS67 0x0100 /* WSEQ_EOS67 */ -#define WM8995_WSEQ_EOS67_MASK 0x0100 /* WSEQ_EOS67 */ -#define WM8995_WSEQ_EOS67_SHIFT 8 /* WSEQ_EOS67 */ -#define WM8995_WSEQ_EOS67_WIDTH 1 /* WSEQ_EOS67 */ -#define WM8995_WSEQ_DELAY67_MASK 0x000F /* WSEQ_DELAY67 - [3:0] */ -#define WM8995_WSEQ_DELAY67_SHIFT 0 /* WSEQ_DELAY67 - [3:0] */ -#define WM8995_WSEQ_DELAY67_WIDTH 4 /* WSEQ_DELAY67 - [3:0] */ - -/* - * R12560 (0x3110) - Write Sequencer 272 - */ -#define WM8995_WSEQ_ADDR68_MASK 0x3FFF /* WSEQ_ADDR68 - [13:0] */ -#define WM8995_WSEQ_ADDR68_SHIFT 0 /* WSEQ_ADDR68 - [13:0] */ -#define WM8995_WSEQ_ADDR68_WIDTH 14 /* WSEQ_ADDR68 - [13:0] */ - -/* - * R12561 (0x3111) - Write Sequencer 273 - */ -#define WM8995_WSEQ_DATA68_MASK 0x00FF /* WSEQ_DATA68 - [7:0] */ -#define WM8995_WSEQ_DATA68_SHIFT 0 /* WSEQ_DATA68 - [7:0] */ -#define WM8995_WSEQ_DATA68_WIDTH 8 /* WSEQ_DATA68 - [7:0] */ - -/* - * R12562 (0x3112) - Write Sequencer 274 - */ -#define WM8995_WSEQ_DATA_WIDTH68_MASK 0x0700 /* WSEQ_DATA_WIDTH68 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH68_SHIFT 8 /* WSEQ_DATA_WIDTH68 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH68_WIDTH 3 /* WSEQ_DATA_WIDTH68 - [10:8] */ -#define WM8995_WSEQ_DATA_START68_MASK 0x000F /* WSEQ_DATA_START68 - [3:0] */ -#define WM8995_WSEQ_DATA_START68_SHIFT 0 /* WSEQ_DATA_START68 - [3:0] */ -#define WM8995_WSEQ_DATA_START68_WIDTH 4 /* WSEQ_DATA_START68 - [3:0] */ - -/* - * R12563 (0x3113) - Write Sequencer 275 - */ -#define WM8995_WSEQ_EOS68 0x0100 /* WSEQ_EOS68 */ -#define WM8995_WSEQ_EOS68_MASK 0x0100 /* WSEQ_EOS68 */ -#define WM8995_WSEQ_EOS68_SHIFT 8 /* WSEQ_EOS68 */ -#define WM8995_WSEQ_EOS68_WIDTH 1 /* WSEQ_EOS68 */ -#define WM8995_WSEQ_DELAY68_MASK 0x000F /* WSEQ_DELAY68 - [3:0] */ -#define WM8995_WSEQ_DELAY68_SHIFT 0 /* WSEQ_DELAY68 - [3:0] */ -#define WM8995_WSEQ_DELAY68_WIDTH 4 /* WSEQ_DELAY68 - [3:0] */ - -/* - * R12564 (0x3114) - Write Sequencer 276 - */ -#define WM8995_WSEQ_ADDR69_MASK 0x3FFF /* WSEQ_ADDR69 - [13:0] */ -#define WM8995_WSEQ_ADDR69_SHIFT 0 /* WSEQ_ADDR69 - [13:0] */ -#define WM8995_WSEQ_ADDR69_WIDTH 14 /* WSEQ_ADDR69 - [13:0] */ - -/* - * R12565 (0x3115) - Write Sequencer 277 - */ -#define WM8995_WSEQ_DATA69_MASK 0x00FF /* WSEQ_DATA69 - [7:0] */ -#define WM8995_WSEQ_DATA69_SHIFT 0 /* WSEQ_DATA69 - [7:0] */ -#define WM8995_WSEQ_DATA69_WIDTH 8 /* WSEQ_DATA69 - [7:0] */ - -/* - * R12566 (0x3116) - Write Sequencer 278 - */ -#define WM8995_WSEQ_DATA_WIDTH69_MASK 0x0700 /* WSEQ_DATA_WIDTH69 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH69_SHIFT 8 /* WSEQ_DATA_WIDTH69 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH69_WIDTH 3 /* WSEQ_DATA_WIDTH69 - [10:8] */ -#define WM8995_WSEQ_DATA_START69_MASK 0x000F /* WSEQ_DATA_START69 - [3:0] */ -#define WM8995_WSEQ_DATA_START69_SHIFT 0 /* WSEQ_DATA_START69 - [3:0] */ -#define WM8995_WSEQ_DATA_START69_WIDTH 4 /* WSEQ_DATA_START69 - [3:0] */ - -/* - * R12567 (0x3117) - Write Sequencer 279 - */ -#define WM8995_WSEQ_EOS69 0x0100 /* WSEQ_EOS69 */ -#define WM8995_WSEQ_EOS69_MASK 0x0100 /* WSEQ_EOS69 */ -#define WM8995_WSEQ_EOS69_SHIFT 8 /* WSEQ_EOS69 */ -#define WM8995_WSEQ_EOS69_WIDTH 1 /* WSEQ_EOS69 */ -#define WM8995_WSEQ_DELAY69_MASK 0x000F /* WSEQ_DELAY69 - [3:0] */ -#define WM8995_WSEQ_DELAY69_SHIFT 0 /* WSEQ_DELAY69 - [3:0] */ -#define WM8995_WSEQ_DELAY69_WIDTH 4 /* WSEQ_DELAY69 - [3:0] */ - -/* - * R12568 (0x3118) - Write Sequencer 280 - */ -#define WM8995_WSEQ_ADDR70_MASK 0x3FFF /* WSEQ_ADDR70 - [13:0] */ -#define WM8995_WSEQ_ADDR70_SHIFT 0 /* WSEQ_ADDR70 - [13:0] */ -#define WM8995_WSEQ_ADDR70_WIDTH 14 /* WSEQ_ADDR70 - [13:0] */ - -/* - * R12569 (0x3119) - Write Sequencer 281 - */ -#define WM8995_WSEQ_DATA70_MASK 0x00FF /* WSEQ_DATA70 - [7:0] */ -#define WM8995_WSEQ_DATA70_SHIFT 0 /* WSEQ_DATA70 - [7:0] */ -#define WM8995_WSEQ_DATA70_WIDTH 8 /* WSEQ_DATA70 - [7:0] */ - -/* - * R12570 (0x311A) - Write Sequencer 282 - */ -#define WM8995_WSEQ_DATA_WIDTH70_MASK 0x0700 /* WSEQ_DATA_WIDTH70 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH70_SHIFT 8 /* WSEQ_DATA_WIDTH70 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH70_WIDTH 3 /* WSEQ_DATA_WIDTH70 - [10:8] */ -#define WM8995_WSEQ_DATA_START70_MASK 0x000F /* WSEQ_DATA_START70 - [3:0] */ -#define WM8995_WSEQ_DATA_START70_SHIFT 0 /* WSEQ_DATA_START70 - [3:0] */ -#define WM8995_WSEQ_DATA_START70_WIDTH 4 /* WSEQ_DATA_START70 - [3:0] */ - -/* - * R12571 (0x311B) - Write Sequencer 283 - */ -#define WM8995_WSEQ_EOS70 0x0100 /* WSEQ_EOS70 */ -#define WM8995_WSEQ_EOS70_MASK 0x0100 /* WSEQ_EOS70 */ -#define WM8995_WSEQ_EOS70_SHIFT 8 /* WSEQ_EOS70 */ -#define WM8995_WSEQ_EOS70_WIDTH 1 /* WSEQ_EOS70 */ -#define WM8995_WSEQ_DELAY70_MASK 0x000F /* WSEQ_DELAY70 - [3:0] */ -#define WM8995_WSEQ_DELAY70_SHIFT 0 /* WSEQ_DELAY70 - [3:0] */ -#define WM8995_WSEQ_DELAY70_WIDTH 4 /* WSEQ_DELAY70 - [3:0] */ - -/* - * R12572 (0x311C) - Write Sequencer 284 - */ -#define WM8995_WSEQ_ADDR71_MASK 0x3FFF /* WSEQ_ADDR71 - [13:0] */ -#define WM8995_WSEQ_ADDR71_SHIFT 0 /* WSEQ_ADDR71 - [13:0] */ -#define WM8995_WSEQ_ADDR71_WIDTH 14 /* WSEQ_ADDR71 - [13:0] */ - -/* - * R12573 (0x311D) - Write Sequencer 285 - */ -#define WM8995_WSEQ_DATA71_MASK 0x00FF /* WSEQ_DATA71 - [7:0] */ -#define WM8995_WSEQ_DATA71_SHIFT 0 /* WSEQ_DATA71 - [7:0] */ -#define WM8995_WSEQ_DATA71_WIDTH 8 /* WSEQ_DATA71 - [7:0] */ - -/* - * R12574 (0x311E) - Write Sequencer 286 - */ -#define WM8995_WSEQ_DATA_WIDTH71_MASK 0x0700 /* WSEQ_DATA_WIDTH71 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH71_SHIFT 8 /* WSEQ_DATA_WIDTH71 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH71_WIDTH 3 /* WSEQ_DATA_WIDTH71 - [10:8] */ -#define WM8995_WSEQ_DATA_START71_MASK 0x000F /* WSEQ_DATA_START71 - [3:0] */ -#define WM8995_WSEQ_DATA_START71_SHIFT 0 /* WSEQ_DATA_START71 - [3:0] */ -#define WM8995_WSEQ_DATA_START71_WIDTH 4 /* WSEQ_DATA_START71 - [3:0] */ - -/* - * R12575 (0x311F) - Write Sequencer 287 - */ -#define WM8995_WSEQ_EOS71 0x0100 /* WSEQ_EOS71 */ -#define WM8995_WSEQ_EOS71_MASK 0x0100 /* WSEQ_EOS71 */ -#define WM8995_WSEQ_EOS71_SHIFT 8 /* WSEQ_EOS71 */ -#define WM8995_WSEQ_EOS71_WIDTH 1 /* WSEQ_EOS71 */ -#define WM8995_WSEQ_DELAY71_MASK 0x000F /* WSEQ_DELAY71 - [3:0] */ -#define WM8995_WSEQ_DELAY71_SHIFT 0 /* WSEQ_DELAY71 - [3:0] */ -#define WM8995_WSEQ_DELAY71_WIDTH 4 /* WSEQ_DELAY71 - [3:0] */ - -/* - * R12576 (0x3120) - Write Sequencer 288 - */ -#define WM8995_WSEQ_ADDR72_MASK 0x3FFF /* WSEQ_ADDR72 - [13:0] */ -#define WM8995_WSEQ_ADDR72_SHIFT 0 /* WSEQ_ADDR72 - [13:0] */ -#define WM8995_WSEQ_ADDR72_WIDTH 14 /* WSEQ_ADDR72 - [13:0] */ - -/* - * R12577 (0x3121) - Write Sequencer 289 - */ -#define WM8995_WSEQ_DATA72_MASK 0x00FF /* WSEQ_DATA72 - [7:0] */ -#define WM8995_WSEQ_DATA72_SHIFT 0 /* WSEQ_DATA72 - [7:0] */ -#define WM8995_WSEQ_DATA72_WIDTH 8 /* WSEQ_DATA72 - [7:0] */ - -/* - * R12578 (0x3122) - Write Sequencer 290 - */ -#define WM8995_WSEQ_DATA_WIDTH72_MASK 0x0700 /* WSEQ_DATA_WIDTH72 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH72_SHIFT 8 /* WSEQ_DATA_WIDTH72 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH72_WIDTH 3 /* WSEQ_DATA_WIDTH72 - [10:8] */ -#define WM8995_WSEQ_DATA_START72_MASK 0x000F /* WSEQ_DATA_START72 - [3:0] */ -#define WM8995_WSEQ_DATA_START72_SHIFT 0 /* WSEQ_DATA_START72 - [3:0] */ -#define WM8995_WSEQ_DATA_START72_WIDTH 4 /* WSEQ_DATA_START72 - [3:0] */ - -/* - * R12579 (0x3123) - Write Sequencer 291 - */ -#define WM8995_WSEQ_EOS72 0x0100 /* WSEQ_EOS72 */ -#define WM8995_WSEQ_EOS72_MASK 0x0100 /* WSEQ_EOS72 */ -#define WM8995_WSEQ_EOS72_SHIFT 8 /* WSEQ_EOS72 */ -#define WM8995_WSEQ_EOS72_WIDTH 1 /* WSEQ_EOS72 */ -#define WM8995_WSEQ_DELAY72_MASK 0x000F /* WSEQ_DELAY72 - [3:0] */ -#define WM8995_WSEQ_DELAY72_SHIFT 0 /* WSEQ_DELAY72 - [3:0] */ -#define WM8995_WSEQ_DELAY72_WIDTH 4 /* WSEQ_DELAY72 - [3:0] */ - -/* - * R12580 (0x3124) - Write Sequencer 292 - */ -#define WM8995_WSEQ_ADDR73_MASK 0x3FFF /* WSEQ_ADDR73 - [13:0] */ -#define WM8995_WSEQ_ADDR73_SHIFT 0 /* WSEQ_ADDR73 - [13:0] */ -#define WM8995_WSEQ_ADDR73_WIDTH 14 /* WSEQ_ADDR73 - [13:0] */ - -/* - * R12581 (0x3125) - Write Sequencer 293 - */ -#define WM8995_WSEQ_DATA73_MASK 0x00FF /* WSEQ_DATA73 - [7:0] */ -#define WM8995_WSEQ_DATA73_SHIFT 0 /* WSEQ_DATA73 - [7:0] */ -#define WM8995_WSEQ_DATA73_WIDTH 8 /* WSEQ_DATA73 - [7:0] */ - -/* - * R12582 (0x3126) - Write Sequencer 294 - */ -#define WM8995_WSEQ_DATA_WIDTH73_MASK 0x0700 /* WSEQ_DATA_WIDTH73 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH73_SHIFT 8 /* WSEQ_DATA_WIDTH73 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH73_WIDTH 3 /* WSEQ_DATA_WIDTH73 - [10:8] */ -#define WM8995_WSEQ_DATA_START73_MASK 0x000F /* WSEQ_DATA_START73 - [3:0] */ -#define WM8995_WSEQ_DATA_START73_SHIFT 0 /* WSEQ_DATA_START73 - [3:0] */ -#define WM8995_WSEQ_DATA_START73_WIDTH 4 /* WSEQ_DATA_START73 - [3:0] */ - -/* - * R12583 (0x3127) - Write Sequencer 295 - */ -#define WM8995_WSEQ_EOS73 0x0100 /* WSEQ_EOS73 */ -#define WM8995_WSEQ_EOS73_MASK 0x0100 /* WSEQ_EOS73 */ -#define WM8995_WSEQ_EOS73_SHIFT 8 /* WSEQ_EOS73 */ -#define WM8995_WSEQ_EOS73_WIDTH 1 /* WSEQ_EOS73 */ -#define WM8995_WSEQ_DELAY73_MASK 0x000F /* WSEQ_DELAY73 - [3:0] */ -#define WM8995_WSEQ_DELAY73_SHIFT 0 /* WSEQ_DELAY73 - [3:0] */ -#define WM8995_WSEQ_DELAY73_WIDTH 4 /* WSEQ_DELAY73 - [3:0] */ - -/* - * R12584 (0x3128) - Write Sequencer 296 - */ -#define WM8995_WSEQ_ADDR74_MASK 0x3FFF /* WSEQ_ADDR74 - [13:0] */ -#define WM8995_WSEQ_ADDR74_SHIFT 0 /* WSEQ_ADDR74 - [13:0] */ -#define WM8995_WSEQ_ADDR74_WIDTH 14 /* WSEQ_ADDR74 - [13:0] */ - -/* - * R12585 (0x3129) - Write Sequencer 297 - */ -#define WM8995_WSEQ_DATA74_MASK 0x00FF /* WSEQ_DATA74 - [7:0] */ -#define WM8995_WSEQ_DATA74_SHIFT 0 /* WSEQ_DATA74 - [7:0] */ -#define WM8995_WSEQ_DATA74_WIDTH 8 /* WSEQ_DATA74 - [7:0] */ - -/* - * R12586 (0x312A) - Write Sequencer 298 - */ -#define WM8995_WSEQ_DATA_WIDTH74_MASK 0x0700 /* WSEQ_DATA_WIDTH74 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH74_SHIFT 8 /* WSEQ_DATA_WIDTH74 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH74_WIDTH 3 /* WSEQ_DATA_WIDTH74 - [10:8] */ -#define WM8995_WSEQ_DATA_START74_MASK 0x000F /* WSEQ_DATA_START74 - [3:0] */ -#define WM8995_WSEQ_DATA_START74_SHIFT 0 /* WSEQ_DATA_START74 - [3:0] */ -#define WM8995_WSEQ_DATA_START74_WIDTH 4 /* WSEQ_DATA_START74 - [3:0] */ - -/* - * R12587 (0x312B) - Write Sequencer 299 - */ -#define WM8995_WSEQ_EOS74 0x0100 /* WSEQ_EOS74 */ -#define WM8995_WSEQ_EOS74_MASK 0x0100 /* WSEQ_EOS74 */ -#define WM8995_WSEQ_EOS74_SHIFT 8 /* WSEQ_EOS74 */ -#define WM8995_WSEQ_EOS74_WIDTH 1 /* WSEQ_EOS74 */ -#define WM8995_WSEQ_DELAY74_MASK 0x000F /* WSEQ_DELAY74 - [3:0] */ -#define WM8995_WSEQ_DELAY74_SHIFT 0 /* WSEQ_DELAY74 - [3:0] */ -#define WM8995_WSEQ_DELAY74_WIDTH 4 /* WSEQ_DELAY74 - [3:0] */ - -/* - * R12588 (0x312C) - Write Sequencer 300 - */ -#define WM8995_WSEQ_ADDR75_MASK 0x3FFF /* WSEQ_ADDR75 - [13:0] */ -#define WM8995_WSEQ_ADDR75_SHIFT 0 /* WSEQ_ADDR75 - [13:0] */ -#define WM8995_WSEQ_ADDR75_WIDTH 14 /* WSEQ_ADDR75 - [13:0] */ - -/* - * R12589 (0x312D) - Write Sequencer 301 - */ -#define WM8995_WSEQ_DATA75_MASK 0x00FF /* WSEQ_DATA75 - [7:0] */ -#define WM8995_WSEQ_DATA75_SHIFT 0 /* WSEQ_DATA75 - [7:0] */ -#define WM8995_WSEQ_DATA75_WIDTH 8 /* WSEQ_DATA75 - [7:0] */ - -/* - * R12590 (0x312E) - Write Sequencer 302 - */ -#define WM8995_WSEQ_DATA_WIDTH75_MASK 0x0700 /* WSEQ_DATA_WIDTH75 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH75_SHIFT 8 /* WSEQ_DATA_WIDTH75 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH75_WIDTH 3 /* WSEQ_DATA_WIDTH75 - [10:8] */ -#define WM8995_WSEQ_DATA_START75_MASK 0x000F /* WSEQ_DATA_START75 - [3:0] */ -#define WM8995_WSEQ_DATA_START75_SHIFT 0 /* WSEQ_DATA_START75 - [3:0] */ -#define WM8995_WSEQ_DATA_START75_WIDTH 4 /* WSEQ_DATA_START75 - [3:0] */ - -/* - * R12591 (0x312F) - Write Sequencer 303 - */ -#define WM8995_WSEQ_EOS75 0x0100 /* WSEQ_EOS75 */ -#define WM8995_WSEQ_EOS75_MASK 0x0100 /* WSEQ_EOS75 */ -#define WM8995_WSEQ_EOS75_SHIFT 8 /* WSEQ_EOS75 */ -#define WM8995_WSEQ_EOS75_WIDTH 1 /* WSEQ_EOS75 */ -#define WM8995_WSEQ_DELAY75_MASK 0x000F /* WSEQ_DELAY75 - [3:0] */ -#define WM8995_WSEQ_DELAY75_SHIFT 0 /* WSEQ_DELAY75 - [3:0] */ -#define WM8995_WSEQ_DELAY75_WIDTH 4 /* WSEQ_DELAY75 - [3:0] */ - -/* - * R12592 (0x3130) - Write Sequencer 304 - */ -#define WM8995_WSEQ_ADDR76_MASK 0x3FFF /* WSEQ_ADDR76 - [13:0] */ -#define WM8995_WSEQ_ADDR76_SHIFT 0 /* WSEQ_ADDR76 - [13:0] */ -#define WM8995_WSEQ_ADDR76_WIDTH 14 /* WSEQ_ADDR76 - [13:0] */ - -/* - * R12593 (0x3131) - Write Sequencer 305 - */ -#define WM8995_WSEQ_DATA76_MASK 0x00FF /* WSEQ_DATA76 - [7:0] */ -#define WM8995_WSEQ_DATA76_SHIFT 0 /* WSEQ_DATA76 - [7:0] */ -#define WM8995_WSEQ_DATA76_WIDTH 8 /* WSEQ_DATA76 - [7:0] */ - -/* - * R12594 (0x3132) - Write Sequencer 306 - */ -#define WM8995_WSEQ_DATA_WIDTH76_MASK 0x0700 /* WSEQ_DATA_WIDTH76 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH76_SHIFT 8 /* WSEQ_DATA_WIDTH76 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH76_WIDTH 3 /* WSEQ_DATA_WIDTH76 - [10:8] */ -#define WM8995_WSEQ_DATA_START76_MASK 0x000F /* WSEQ_DATA_START76 - [3:0] */ -#define WM8995_WSEQ_DATA_START76_SHIFT 0 /* WSEQ_DATA_START76 - [3:0] */ -#define WM8995_WSEQ_DATA_START76_WIDTH 4 /* WSEQ_DATA_START76 - [3:0] */ - -/* - * R12595 (0x3133) - Write Sequencer 307 - */ -#define WM8995_WSEQ_EOS76 0x0100 /* WSEQ_EOS76 */ -#define WM8995_WSEQ_EOS76_MASK 0x0100 /* WSEQ_EOS76 */ -#define WM8995_WSEQ_EOS76_SHIFT 8 /* WSEQ_EOS76 */ -#define WM8995_WSEQ_EOS76_WIDTH 1 /* WSEQ_EOS76 */ -#define WM8995_WSEQ_DELAY76_MASK 0x000F /* WSEQ_DELAY76 - [3:0] */ -#define WM8995_WSEQ_DELAY76_SHIFT 0 /* WSEQ_DELAY76 - [3:0] */ -#define WM8995_WSEQ_DELAY76_WIDTH 4 /* WSEQ_DELAY76 - [3:0] */ - -/* - * R12596 (0x3134) - Write Sequencer 308 - */ -#define WM8995_WSEQ_ADDR77_MASK 0x3FFF /* WSEQ_ADDR77 - [13:0] */ -#define WM8995_WSEQ_ADDR77_SHIFT 0 /* WSEQ_ADDR77 - [13:0] */ -#define WM8995_WSEQ_ADDR77_WIDTH 14 /* WSEQ_ADDR77 - [13:0] */ - -/* - * R12597 (0x3135) - Write Sequencer 309 - */ -#define WM8995_WSEQ_DATA77_MASK 0x00FF /* WSEQ_DATA77 - [7:0] */ -#define WM8995_WSEQ_DATA77_SHIFT 0 /* WSEQ_DATA77 - [7:0] */ -#define WM8995_WSEQ_DATA77_WIDTH 8 /* WSEQ_DATA77 - [7:0] */ - -/* - * R12598 (0x3136) - Write Sequencer 310 - */ -#define WM8995_WSEQ_DATA_WIDTH77_MASK 0x0700 /* WSEQ_DATA_WIDTH77 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH77_SHIFT 8 /* WSEQ_DATA_WIDTH77 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH77_WIDTH 3 /* WSEQ_DATA_WIDTH77 - [10:8] */ -#define WM8995_WSEQ_DATA_START77_MASK 0x000F /* WSEQ_DATA_START77 - [3:0] */ -#define WM8995_WSEQ_DATA_START77_SHIFT 0 /* WSEQ_DATA_START77 - [3:0] */ -#define WM8995_WSEQ_DATA_START77_WIDTH 4 /* WSEQ_DATA_START77 - [3:0] */ - -/* - * R12599 (0x3137) - Write Sequencer 311 - */ -#define WM8995_WSEQ_EOS77 0x0100 /* WSEQ_EOS77 */ -#define WM8995_WSEQ_EOS77_MASK 0x0100 /* WSEQ_EOS77 */ -#define WM8995_WSEQ_EOS77_SHIFT 8 /* WSEQ_EOS77 */ -#define WM8995_WSEQ_EOS77_WIDTH 1 /* WSEQ_EOS77 */ -#define WM8995_WSEQ_DELAY77_MASK 0x000F /* WSEQ_DELAY77 - [3:0] */ -#define WM8995_WSEQ_DELAY77_SHIFT 0 /* WSEQ_DELAY77 - [3:0] */ -#define WM8995_WSEQ_DELAY77_WIDTH 4 /* WSEQ_DELAY77 - [3:0] */ - -/* - * R12600 (0x3138) - Write Sequencer 312 - */ -#define WM8995_WSEQ_ADDR78_MASK 0x3FFF /* WSEQ_ADDR78 - [13:0] */ -#define WM8995_WSEQ_ADDR78_SHIFT 0 /* WSEQ_ADDR78 - [13:0] */ -#define WM8995_WSEQ_ADDR78_WIDTH 14 /* WSEQ_ADDR78 - [13:0] */ - -/* - * R12601 (0x3139) - Write Sequencer 313 - */ -#define WM8995_WSEQ_DATA78_MASK 0x00FF /* WSEQ_DATA78 - [7:0] */ -#define WM8995_WSEQ_DATA78_SHIFT 0 /* WSEQ_DATA78 - [7:0] */ -#define WM8995_WSEQ_DATA78_WIDTH 8 /* WSEQ_DATA78 - [7:0] */ - -/* - * R12602 (0x313A) - Write Sequencer 314 - */ -#define WM8995_WSEQ_DATA_WIDTH78_MASK 0x0700 /* WSEQ_DATA_WIDTH78 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH78_SHIFT 8 /* WSEQ_DATA_WIDTH78 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH78_WIDTH 3 /* WSEQ_DATA_WIDTH78 - [10:8] */ -#define WM8995_WSEQ_DATA_START78_MASK 0x000F /* WSEQ_DATA_START78 - [3:0] */ -#define WM8995_WSEQ_DATA_START78_SHIFT 0 /* WSEQ_DATA_START78 - [3:0] */ -#define WM8995_WSEQ_DATA_START78_WIDTH 4 /* WSEQ_DATA_START78 - [3:0] */ - -/* - * R12603 (0x313B) - Write Sequencer 315 - */ -#define WM8995_WSEQ_EOS78 0x0100 /* WSEQ_EOS78 */ -#define WM8995_WSEQ_EOS78_MASK 0x0100 /* WSEQ_EOS78 */ -#define WM8995_WSEQ_EOS78_SHIFT 8 /* WSEQ_EOS78 */ -#define WM8995_WSEQ_EOS78_WIDTH 1 /* WSEQ_EOS78 */ -#define WM8995_WSEQ_DELAY78_MASK 0x000F /* WSEQ_DELAY78 - [3:0] */ -#define WM8995_WSEQ_DELAY78_SHIFT 0 /* WSEQ_DELAY78 - [3:0] */ -#define WM8995_WSEQ_DELAY78_WIDTH 4 /* WSEQ_DELAY78 - [3:0] */ - -/* - * R12604 (0x313C) - Write Sequencer 316 - */ -#define WM8995_WSEQ_ADDR79_MASK 0x3FFF /* WSEQ_ADDR79 - [13:0] */ -#define WM8995_WSEQ_ADDR79_SHIFT 0 /* WSEQ_ADDR79 - [13:0] */ -#define WM8995_WSEQ_ADDR79_WIDTH 14 /* WSEQ_ADDR79 - [13:0] */ - -/* - * R12605 (0x313D) - Write Sequencer 317 - */ -#define WM8995_WSEQ_DATA79_MASK 0x00FF /* WSEQ_DATA79 - [7:0] */ -#define WM8995_WSEQ_DATA79_SHIFT 0 /* WSEQ_DATA79 - [7:0] */ -#define WM8995_WSEQ_DATA79_WIDTH 8 /* WSEQ_DATA79 - [7:0] */ - -/* - * R12606 (0x313E) - Write Sequencer 318 - */ -#define WM8995_WSEQ_DATA_WIDTH79_MASK 0x0700 /* WSEQ_DATA_WIDTH79 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH79_SHIFT 8 /* WSEQ_DATA_WIDTH79 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH79_WIDTH 3 /* WSEQ_DATA_WIDTH79 - [10:8] */ -#define WM8995_WSEQ_DATA_START79_MASK 0x000F /* WSEQ_DATA_START79 - [3:0] */ -#define WM8995_WSEQ_DATA_START79_SHIFT 0 /* WSEQ_DATA_START79 - [3:0] */ -#define WM8995_WSEQ_DATA_START79_WIDTH 4 /* WSEQ_DATA_START79 - [3:0] */ - -/* - * R12607 (0x313F) - Write Sequencer 319 - */ -#define WM8995_WSEQ_EOS79 0x0100 /* WSEQ_EOS79 */ -#define WM8995_WSEQ_EOS79_MASK 0x0100 /* WSEQ_EOS79 */ -#define WM8995_WSEQ_EOS79_SHIFT 8 /* WSEQ_EOS79 */ -#define WM8995_WSEQ_EOS79_WIDTH 1 /* WSEQ_EOS79 */ -#define WM8995_WSEQ_DELAY79_MASK 0x000F /* WSEQ_DELAY79 - [3:0] */ -#define WM8995_WSEQ_DELAY79_SHIFT 0 /* WSEQ_DELAY79 - [3:0] */ -#define WM8995_WSEQ_DELAY79_WIDTH 4 /* WSEQ_DELAY79 - [3:0] */ - -/* - * R12608 (0x3140) - Write Sequencer 320 - */ -#define WM8995_WSEQ_ADDR80_MASK 0x3FFF /* WSEQ_ADDR80 - [13:0] */ -#define WM8995_WSEQ_ADDR80_SHIFT 0 /* WSEQ_ADDR80 - [13:0] */ -#define WM8995_WSEQ_ADDR80_WIDTH 14 /* WSEQ_ADDR80 - [13:0] */ - -/* - * R12609 (0x3141) - Write Sequencer 321 - */ -#define WM8995_WSEQ_DATA80_MASK 0x00FF /* WSEQ_DATA80 - [7:0] */ -#define WM8995_WSEQ_DATA80_SHIFT 0 /* WSEQ_DATA80 - [7:0] */ -#define WM8995_WSEQ_DATA80_WIDTH 8 /* WSEQ_DATA80 - [7:0] */ - -/* - * R12610 (0x3142) - Write Sequencer 322 - */ -#define WM8995_WSEQ_DATA_WIDTH80_MASK 0x0700 /* WSEQ_DATA_WIDTH80 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH80_SHIFT 8 /* WSEQ_DATA_WIDTH80 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH80_WIDTH 3 /* WSEQ_DATA_WIDTH80 - [10:8] */ -#define WM8995_WSEQ_DATA_START80_MASK 0x000F /* WSEQ_DATA_START80 - [3:0] */ -#define WM8995_WSEQ_DATA_START80_SHIFT 0 /* WSEQ_DATA_START80 - [3:0] */ -#define WM8995_WSEQ_DATA_START80_WIDTH 4 /* WSEQ_DATA_START80 - [3:0] */ - -/* - * R12611 (0x3143) - Write Sequencer 323 - */ -#define WM8995_WSEQ_EOS80 0x0100 /* WSEQ_EOS80 */ -#define WM8995_WSEQ_EOS80_MASK 0x0100 /* WSEQ_EOS80 */ -#define WM8995_WSEQ_EOS80_SHIFT 8 /* WSEQ_EOS80 */ -#define WM8995_WSEQ_EOS80_WIDTH 1 /* WSEQ_EOS80 */ -#define WM8995_WSEQ_DELAY80_MASK 0x000F /* WSEQ_DELAY80 - [3:0] */ -#define WM8995_WSEQ_DELAY80_SHIFT 0 /* WSEQ_DELAY80 - [3:0] */ -#define WM8995_WSEQ_DELAY80_WIDTH 4 /* WSEQ_DELAY80 - [3:0] */ - -/* - * R12612 (0x3144) - Write Sequencer 324 - */ -#define WM8995_WSEQ_ADDR81_MASK 0x3FFF /* WSEQ_ADDR81 - [13:0] */ -#define WM8995_WSEQ_ADDR81_SHIFT 0 /* WSEQ_ADDR81 - [13:0] */ -#define WM8995_WSEQ_ADDR81_WIDTH 14 /* WSEQ_ADDR81 - [13:0] */ - -/* - * R12613 (0x3145) - Write Sequencer 325 - */ -#define WM8995_WSEQ_DATA81_MASK 0x00FF /* WSEQ_DATA81 - [7:0] */ -#define WM8995_WSEQ_DATA81_SHIFT 0 /* WSEQ_DATA81 - [7:0] */ -#define WM8995_WSEQ_DATA81_WIDTH 8 /* WSEQ_DATA81 - [7:0] */ - -/* - * R12614 (0x3146) - Write Sequencer 326 - */ -#define WM8995_WSEQ_DATA_WIDTH81_MASK 0x0700 /* WSEQ_DATA_WIDTH81 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH81_SHIFT 8 /* WSEQ_DATA_WIDTH81 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH81_WIDTH 3 /* WSEQ_DATA_WIDTH81 - [10:8] */ -#define WM8995_WSEQ_DATA_START81_MASK 0x000F /* WSEQ_DATA_START81 - [3:0] */ -#define WM8995_WSEQ_DATA_START81_SHIFT 0 /* WSEQ_DATA_START81 - [3:0] */ -#define WM8995_WSEQ_DATA_START81_WIDTH 4 /* WSEQ_DATA_START81 - [3:0] */ - -/* - * R12615 (0x3147) - Write Sequencer 327 - */ -#define WM8995_WSEQ_EOS81 0x0100 /* WSEQ_EOS81 */ -#define WM8995_WSEQ_EOS81_MASK 0x0100 /* WSEQ_EOS81 */ -#define WM8995_WSEQ_EOS81_SHIFT 8 /* WSEQ_EOS81 */ -#define WM8995_WSEQ_EOS81_WIDTH 1 /* WSEQ_EOS81 */ -#define WM8995_WSEQ_DELAY81_MASK 0x000F /* WSEQ_DELAY81 - [3:0] */ -#define WM8995_WSEQ_DELAY81_SHIFT 0 /* WSEQ_DELAY81 - [3:0] */ -#define WM8995_WSEQ_DELAY81_WIDTH 4 /* WSEQ_DELAY81 - [3:0] */ - -/* - * R12616 (0x3148) - Write Sequencer 328 - */ -#define WM8995_WSEQ_ADDR82_MASK 0x3FFF /* WSEQ_ADDR82 - [13:0] */ -#define WM8995_WSEQ_ADDR82_SHIFT 0 /* WSEQ_ADDR82 - [13:0] */ -#define WM8995_WSEQ_ADDR82_WIDTH 14 /* WSEQ_ADDR82 - [13:0] */ - -/* - * R12617 (0x3149) - Write Sequencer 329 - */ -#define WM8995_WSEQ_DATA82_MASK 0x00FF /* WSEQ_DATA82 - [7:0] */ -#define WM8995_WSEQ_DATA82_SHIFT 0 /* WSEQ_DATA82 - [7:0] */ -#define WM8995_WSEQ_DATA82_WIDTH 8 /* WSEQ_DATA82 - [7:0] */ - -/* - * R12618 (0x314A) - Write Sequencer 330 - */ -#define WM8995_WSEQ_DATA_WIDTH82_MASK 0x0700 /* WSEQ_DATA_WIDTH82 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH82_SHIFT 8 /* WSEQ_DATA_WIDTH82 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH82_WIDTH 3 /* WSEQ_DATA_WIDTH82 - [10:8] */ -#define WM8995_WSEQ_DATA_START82_MASK 0x000F /* WSEQ_DATA_START82 - [3:0] */ -#define WM8995_WSEQ_DATA_START82_SHIFT 0 /* WSEQ_DATA_START82 - [3:0] */ -#define WM8995_WSEQ_DATA_START82_WIDTH 4 /* WSEQ_DATA_START82 - [3:0] */ - -/* - * R12619 (0x314B) - Write Sequencer 331 - */ -#define WM8995_WSEQ_EOS82 0x0100 /* WSEQ_EOS82 */ -#define WM8995_WSEQ_EOS82_MASK 0x0100 /* WSEQ_EOS82 */ -#define WM8995_WSEQ_EOS82_SHIFT 8 /* WSEQ_EOS82 */ -#define WM8995_WSEQ_EOS82_WIDTH 1 /* WSEQ_EOS82 */ -#define WM8995_WSEQ_DELAY82_MASK 0x000F /* WSEQ_DELAY82 - [3:0] */ -#define WM8995_WSEQ_DELAY82_SHIFT 0 /* WSEQ_DELAY82 - [3:0] */ -#define WM8995_WSEQ_DELAY82_WIDTH 4 /* WSEQ_DELAY82 - [3:0] */ - -/* - * R12620 (0x314C) - Write Sequencer 332 - */ -#define WM8995_WSEQ_ADDR83_MASK 0x3FFF /* WSEQ_ADDR83 - [13:0] */ -#define WM8995_WSEQ_ADDR83_SHIFT 0 /* WSEQ_ADDR83 - [13:0] */ -#define WM8995_WSEQ_ADDR83_WIDTH 14 /* WSEQ_ADDR83 - [13:0] */ - -/* - * R12621 (0x314D) - Write Sequencer 333 - */ -#define WM8995_WSEQ_DATA83_MASK 0x00FF /* WSEQ_DATA83 - [7:0] */ -#define WM8995_WSEQ_DATA83_SHIFT 0 /* WSEQ_DATA83 - [7:0] */ -#define WM8995_WSEQ_DATA83_WIDTH 8 /* WSEQ_DATA83 - [7:0] */ - -/* - * R12622 (0x314E) - Write Sequencer 334 - */ -#define WM8995_WSEQ_DATA_WIDTH83_MASK 0x0700 /* WSEQ_DATA_WIDTH83 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH83_SHIFT 8 /* WSEQ_DATA_WIDTH83 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH83_WIDTH 3 /* WSEQ_DATA_WIDTH83 - [10:8] */ -#define WM8995_WSEQ_DATA_START83_MASK 0x000F /* WSEQ_DATA_START83 - [3:0] */ -#define WM8995_WSEQ_DATA_START83_SHIFT 0 /* WSEQ_DATA_START83 - [3:0] */ -#define WM8995_WSEQ_DATA_START83_WIDTH 4 /* WSEQ_DATA_START83 - [3:0] */ - -/* - * R12623 (0x314F) - Write Sequencer 335 - */ -#define WM8995_WSEQ_EOS83 0x0100 /* WSEQ_EOS83 */ -#define WM8995_WSEQ_EOS83_MASK 0x0100 /* WSEQ_EOS83 */ -#define WM8995_WSEQ_EOS83_SHIFT 8 /* WSEQ_EOS83 */ -#define WM8995_WSEQ_EOS83_WIDTH 1 /* WSEQ_EOS83 */ -#define WM8995_WSEQ_DELAY83_MASK 0x000F /* WSEQ_DELAY83 - [3:0] */ -#define WM8995_WSEQ_DELAY83_SHIFT 0 /* WSEQ_DELAY83 - [3:0] */ -#define WM8995_WSEQ_DELAY83_WIDTH 4 /* WSEQ_DELAY83 - [3:0] */ - -/* - * R12624 (0x3150) - Write Sequencer 336 - */ -#define WM8995_WSEQ_ADDR84_MASK 0x3FFF /* WSEQ_ADDR84 - [13:0] */ -#define WM8995_WSEQ_ADDR84_SHIFT 0 /* WSEQ_ADDR84 - [13:0] */ -#define WM8995_WSEQ_ADDR84_WIDTH 14 /* WSEQ_ADDR84 - [13:0] */ - -/* - * R12625 (0x3151) - Write Sequencer 337 - */ -#define WM8995_WSEQ_DATA84_MASK 0x00FF /* WSEQ_DATA84 - [7:0] */ -#define WM8995_WSEQ_DATA84_SHIFT 0 /* WSEQ_DATA84 - [7:0] */ -#define WM8995_WSEQ_DATA84_WIDTH 8 /* WSEQ_DATA84 - [7:0] */ - -/* - * R12626 (0x3152) - Write Sequencer 338 - */ -#define WM8995_WSEQ_DATA_WIDTH84_MASK 0x0700 /* WSEQ_DATA_WIDTH84 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH84_SHIFT 8 /* WSEQ_DATA_WIDTH84 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH84_WIDTH 3 /* WSEQ_DATA_WIDTH84 - [10:8] */ -#define WM8995_WSEQ_DATA_START84_MASK 0x000F /* WSEQ_DATA_START84 - [3:0] */ -#define WM8995_WSEQ_DATA_START84_SHIFT 0 /* WSEQ_DATA_START84 - [3:0] */ -#define WM8995_WSEQ_DATA_START84_WIDTH 4 /* WSEQ_DATA_START84 - [3:0] */ - -/* - * R12627 (0x3153) - Write Sequencer 339 - */ -#define WM8995_WSEQ_EOS84 0x0100 /* WSEQ_EOS84 */ -#define WM8995_WSEQ_EOS84_MASK 0x0100 /* WSEQ_EOS84 */ -#define WM8995_WSEQ_EOS84_SHIFT 8 /* WSEQ_EOS84 */ -#define WM8995_WSEQ_EOS84_WIDTH 1 /* WSEQ_EOS84 */ -#define WM8995_WSEQ_DELAY84_MASK 0x000F /* WSEQ_DELAY84 - [3:0] */ -#define WM8995_WSEQ_DELAY84_SHIFT 0 /* WSEQ_DELAY84 - [3:0] */ -#define WM8995_WSEQ_DELAY84_WIDTH 4 /* WSEQ_DELAY84 - [3:0] */ - -/* - * R12628 (0x3154) - Write Sequencer 340 - */ -#define WM8995_WSEQ_ADDR85_MASK 0x3FFF /* WSEQ_ADDR85 - [13:0] */ -#define WM8995_WSEQ_ADDR85_SHIFT 0 /* WSEQ_ADDR85 - [13:0] */ -#define WM8995_WSEQ_ADDR85_WIDTH 14 /* WSEQ_ADDR85 - [13:0] */ - -/* - * R12629 (0x3155) - Write Sequencer 341 - */ -#define WM8995_WSEQ_DATA85_MASK 0x00FF /* WSEQ_DATA85 - [7:0] */ -#define WM8995_WSEQ_DATA85_SHIFT 0 /* WSEQ_DATA85 - [7:0] */ -#define WM8995_WSEQ_DATA85_WIDTH 8 /* WSEQ_DATA85 - [7:0] */ - -/* - * R12630 (0x3156) - Write Sequencer 342 - */ -#define WM8995_WSEQ_DATA_WIDTH85_MASK 0x0700 /* WSEQ_DATA_WIDTH85 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH85_SHIFT 8 /* WSEQ_DATA_WIDTH85 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH85_WIDTH 3 /* WSEQ_DATA_WIDTH85 - [10:8] */ -#define WM8995_WSEQ_DATA_START85_MASK 0x000F /* WSEQ_DATA_START85 - [3:0] */ -#define WM8995_WSEQ_DATA_START85_SHIFT 0 /* WSEQ_DATA_START85 - [3:0] */ -#define WM8995_WSEQ_DATA_START85_WIDTH 4 /* WSEQ_DATA_START85 - [3:0] */ - -/* - * R12631 (0x3157) - Write Sequencer 343 - */ -#define WM8995_WSEQ_EOS85 0x0100 /* WSEQ_EOS85 */ -#define WM8995_WSEQ_EOS85_MASK 0x0100 /* WSEQ_EOS85 */ -#define WM8995_WSEQ_EOS85_SHIFT 8 /* WSEQ_EOS85 */ -#define WM8995_WSEQ_EOS85_WIDTH 1 /* WSEQ_EOS85 */ -#define WM8995_WSEQ_DELAY85_MASK 0x000F /* WSEQ_DELAY85 - [3:0] */ -#define WM8995_WSEQ_DELAY85_SHIFT 0 /* WSEQ_DELAY85 - [3:0] */ -#define WM8995_WSEQ_DELAY85_WIDTH 4 /* WSEQ_DELAY85 - [3:0] */ - -/* - * R12632 (0x3158) - Write Sequencer 344 - */ -#define WM8995_WSEQ_ADDR86_MASK 0x3FFF /* WSEQ_ADDR86 - [13:0] */ -#define WM8995_WSEQ_ADDR86_SHIFT 0 /* WSEQ_ADDR86 - [13:0] */ -#define WM8995_WSEQ_ADDR86_WIDTH 14 /* WSEQ_ADDR86 - [13:0] */ - -/* - * R12633 (0x3159) - Write Sequencer 345 - */ -#define WM8995_WSEQ_DATA86_MASK 0x00FF /* WSEQ_DATA86 - [7:0] */ -#define WM8995_WSEQ_DATA86_SHIFT 0 /* WSEQ_DATA86 - [7:0] */ -#define WM8995_WSEQ_DATA86_WIDTH 8 /* WSEQ_DATA86 - [7:0] */ - -/* - * R12634 (0x315A) - Write Sequencer 346 - */ -#define WM8995_WSEQ_DATA_WIDTH86_MASK 0x0700 /* WSEQ_DATA_WIDTH86 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH86_SHIFT 8 /* WSEQ_DATA_WIDTH86 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH86_WIDTH 3 /* WSEQ_DATA_WIDTH86 - [10:8] */ -#define WM8995_WSEQ_DATA_START86_MASK 0x000F /* WSEQ_DATA_START86 - [3:0] */ -#define WM8995_WSEQ_DATA_START86_SHIFT 0 /* WSEQ_DATA_START86 - [3:0] */ -#define WM8995_WSEQ_DATA_START86_WIDTH 4 /* WSEQ_DATA_START86 - [3:0] */ - -/* - * R12635 (0x315B) - Write Sequencer 347 - */ -#define WM8995_WSEQ_EOS86 0x0100 /* WSEQ_EOS86 */ -#define WM8995_WSEQ_EOS86_MASK 0x0100 /* WSEQ_EOS86 */ -#define WM8995_WSEQ_EOS86_SHIFT 8 /* WSEQ_EOS86 */ -#define WM8995_WSEQ_EOS86_WIDTH 1 /* WSEQ_EOS86 */ -#define WM8995_WSEQ_DELAY86_MASK 0x000F /* WSEQ_DELAY86 - [3:0] */ -#define WM8995_WSEQ_DELAY86_SHIFT 0 /* WSEQ_DELAY86 - [3:0] */ -#define WM8995_WSEQ_DELAY86_WIDTH 4 /* WSEQ_DELAY86 - [3:0] */ - -/* - * R12636 (0x315C) - Write Sequencer 348 - */ -#define WM8995_WSEQ_ADDR87_MASK 0x3FFF /* WSEQ_ADDR87 - [13:0] */ -#define WM8995_WSEQ_ADDR87_SHIFT 0 /* WSEQ_ADDR87 - [13:0] */ -#define WM8995_WSEQ_ADDR87_WIDTH 14 /* WSEQ_ADDR87 - [13:0] */ - -/* - * R12637 (0x315D) - Write Sequencer 349 - */ -#define WM8995_WSEQ_DATA87_MASK 0x00FF /* WSEQ_DATA87 - [7:0] */ -#define WM8995_WSEQ_DATA87_SHIFT 0 /* WSEQ_DATA87 - [7:0] */ -#define WM8995_WSEQ_DATA87_WIDTH 8 /* WSEQ_DATA87 - [7:0] */ - -/* - * R12638 (0x315E) - Write Sequencer 350 - */ -#define WM8995_WSEQ_DATA_WIDTH87_MASK 0x0700 /* WSEQ_DATA_WIDTH87 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH87_SHIFT 8 /* WSEQ_DATA_WIDTH87 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH87_WIDTH 3 /* WSEQ_DATA_WIDTH87 - [10:8] */ -#define WM8995_WSEQ_DATA_START87_MASK 0x000F /* WSEQ_DATA_START87 - [3:0] */ -#define WM8995_WSEQ_DATA_START87_SHIFT 0 /* WSEQ_DATA_START87 - [3:0] */ -#define WM8995_WSEQ_DATA_START87_WIDTH 4 /* WSEQ_DATA_START87 - [3:0] */ - -/* - * R12639 (0x315F) - Write Sequencer 351 - */ -#define WM8995_WSEQ_EOS87 0x0100 /* WSEQ_EOS87 */ -#define WM8995_WSEQ_EOS87_MASK 0x0100 /* WSEQ_EOS87 */ -#define WM8995_WSEQ_EOS87_SHIFT 8 /* WSEQ_EOS87 */ -#define WM8995_WSEQ_EOS87_WIDTH 1 /* WSEQ_EOS87 */ -#define WM8995_WSEQ_DELAY87_MASK 0x000F /* WSEQ_DELAY87 - [3:0] */ -#define WM8995_WSEQ_DELAY87_SHIFT 0 /* WSEQ_DELAY87 - [3:0] */ -#define WM8995_WSEQ_DELAY87_WIDTH 4 /* WSEQ_DELAY87 - [3:0] */ - -/* - * R12640 (0x3160) - Write Sequencer 352 - */ -#define WM8995_WSEQ_ADDR88_MASK 0x3FFF /* WSEQ_ADDR88 - [13:0] */ -#define WM8995_WSEQ_ADDR88_SHIFT 0 /* WSEQ_ADDR88 - [13:0] */ -#define WM8995_WSEQ_ADDR88_WIDTH 14 /* WSEQ_ADDR88 - [13:0] */ - -/* - * R12641 (0x3161) - Write Sequencer 353 - */ -#define WM8995_WSEQ_DATA88_MASK 0x00FF /* WSEQ_DATA88 - [7:0] */ -#define WM8995_WSEQ_DATA88_SHIFT 0 /* WSEQ_DATA88 - [7:0] */ -#define WM8995_WSEQ_DATA88_WIDTH 8 /* WSEQ_DATA88 - [7:0] */ - -/* - * R12642 (0x3162) - Write Sequencer 354 - */ -#define WM8995_WSEQ_DATA_WIDTH88_MASK 0x0700 /* WSEQ_DATA_WIDTH88 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH88_SHIFT 8 /* WSEQ_DATA_WIDTH88 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH88_WIDTH 3 /* WSEQ_DATA_WIDTH88 - [10:8] */ -#define WM8995_WSEQ_DATA_START88_MASK 0x000F /* WSEQ_DATA_START88 - [3:0] */ -#define WM8995_WSEQ_DATA_START88_SHIFT 0 /* WSEQ_DATA_START88 - [3:0] */ -#define WM8995_WSEQ_DATA_START88_WIDTH 4 /* WSEQ_DATA_START88 - [3:0] */ - -/* - * R12643 (0x3163) - Write Sequencer 355 - */ -#define WM8995_WSEQ_EOS88 0x0100 /* WSEQ_EOS88 */ -#define WM8995_WSEQ_EOS88_MASK 0x0100 /* WSEQ_EOS88 */ -#define WM8995_WSEQ_EOS88_SHIFT 8 /* WSEQ_EOS88 */ -#define WM8995_WSEQ_EOS88_WIDTH 1 /* WSEQ_EOS88 */ -#define WM8995_WSEQ_DELAY88_MASK 0x000F /* WSEQ_DELAY88 - [3:0] */ -#define WM8995_WSEQ_DELAY88_SHIFT 0 /* WSEQ_DELAY88 - [3:0] */ -#define WM8995_WSEQ_DELAY88_WIDTH 4 /* WSEQ_DELAY88 - [3:0] */ - -/* - * R12644 (0x3164) - Write Sequencer 356 - */ -#define WM8995_WSEQ_ADDR89_MASK 0x3FFF /* WSEQ_ADDR89 - [13:0] */ -#define WM8995_WSEQ_ADDR89_SHIFT 0 /* WSEQ_ADDR89 - [13:0] */ -#define WM8995_WSEQ_ADDR89_WIDTH 14 /* WSEQ_ADDR89 - [13:0] */ - -/* - * R12645 (0x3165) - Write Sequencer 357 - */ -#define WM8995_WSEQ_DATA89_MASK 0x00FF /* WSEQ_DATA89 - [7:0] */ -#define WM8995_WSEQ_DATA89_SHIFT 0 /* WSEQ_DATA89 - [7:0] */ -#define WM8995_WSEQ_DATA89_WIDTH 8 /* WSEQ_DATA89 - [7:0] */ - -/* - * R12646 (0x3166) - Write Sequencer 358 - */ -#define WM8995_WSEQ_DATA_WIDTH89_MASK 0x0700 /* WSEQ_DATA_WIDTH89 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH89_SHIFT 8 /* WSEQ_DATA_WIDTH89 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH89_WIDTH 3 /* WSEQ_DATA_WIDTH89 - [10:8] */ -#define WM8995_WSEQ_DATA_START89_MASK 0x000F /* WSEQ_DATA_START89 - [3:0] */ -#define WM8995_WSEQ_DATA_START89_SHIFT 0 /* WSEQ_DATA_START89 - [3:0] */ -#define WM8995_WSEQ_DATA_START89_WIDTH 4 /* WSEQ_DATA_START89 - [3:0] */ - -/* - * R12647 (0x3167) - Write Sequencer 359 - */ -#define WM8995_WSEQ_EOS89 0x0100 /* WSEQ_EOS89 */ -#define WM8995_WSEQ_EOS89_MASK 0x0100 /* WSEQ_EOS89 */ -#define WM8995_WSEQ_EOS89_SHIFT 8 /* WSEQ_EOS89 */ -#define WM8995_WSEQ_EOS89_WIDTH 1 /* WSEQ_EOS89 */ -#define WM8995_WSEQ_DELAY89_MASK 0x000F /* WSEQ_DELAY89 - [3:0] */ -#define WM8995_WSEQ_DELAY89_SHIFT 0 /* WSEQ_DELAY89 - [3:0] */ -#define WM8995_WSEQ_DELAY89_WIDTH 4 /* WSEQ_DELAY89 - [3:0] */ - -/* - * R12648 (0x3168) - Write Sequencer 360 - */ -#define WM8995_WSEQ_ADDR90_MASK 0x3FFF /* WSEQ_ADDR90 - [13:0] */ -#define WM8995_WSEQ_ADDR90_SHIFT 0 /* WSEQ_ADDR90 - [13:0] */ -#define WM8995_WSEQ_ADDR90_WIDTH 14 /* WSEQ_ADDR90 - [13:0] */ - -/* - * R12649 (0x3169) - Write Sequencer 361 - */ -#define WM8995_WSEQ_DATA90_MASK 0x00FF /* WSEQ_DATA90 - [7:0] */ -#define WM8995_WSEQ_DATA90_SHIFT 0 /* WSEQ_DATA90 - [7:0] */ -#define WM8995_WSEQ_DATA90_WIDTH 8 /* WSEQ_DATA90 - [7:0] */ - -/* - * R12650 (0x316A) - Write Sequencer 362 - */ -#define WM8995_WSEQ_DATA_WIDTH90_MASK 0x0700 /* WSEQ_DATA_WIDTH90 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH90_SHIFT 8 /* WSEQ_DATA_WIDTH90 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH90_WIDTH 3 /* WSEQ_DATA_WIDTH90 - [10:8] */ -#define WM8995_WSEQ_DATA_START90_MASK 0x000F /* WSEQ_DATA_START90 - [3:0] */ -#define WM8995_WSEQ_DATA_START90_SHIFT 0 /* WSEQ_DATA_START90 - [3:0] */ -#define WM8995_WSEQ_DATA_START90_WIDTH 4 /* WSEQ_DATA_START90 - [3:0] */ - -/* - * R12651 (0x316B) - Write Sequencer 363 - */ -#define WM8995_WSEQ_EOS90 0x0100 /* WSEQ_EOS90 */ -#define WM8995_WSEQ_EOS90_MASK 0x0100 /* WSEQ_EOS90 */ -#define WM8995_WSEQ_EOS90_SHIFT 8 /* WSEQ_EOS90 */ -#define WM8995_WSEQ_EOS90_WIDTH 1 /* WSEQ_EOS90 */ -#define WM8995_WSEQ_DELAY90_MASK 0x000F /* WSEQ_DELAY90 - [3:0] */ -#define WM8995_WSEQ_DELAY90_SHIFT 0 /* WSEQ_DELAY90 - [3:0] */ -#define WM8995_WSEQ_DELAY90_WIDTH 4 /* WSEQ_DELAY90 - [3:0] */ - -/* - * R12652 (0x316C) - Write Sequencer 364 - */ -#define WM8995_WSEQ_ADDR91_MASK 0x3FFF /* WSEQ_ADDR91 - [13:0] */ -#define WM8995_WSEQ_ADDR91_SHIFT 0 /* WSEQ_ADDR91 - [13:0] */ -#define WM8995_WSEQ_ADDR91_WIDTH 14 /* WSEQ_ADDR91 - [13:0] */ - -/* - * R12653 (0x316D) - Write Sequencer 365 - */ -#define WM8995_WSEQ_DATA91_MASK 0x00FF /* WSEQ_DATA91 - [7:0] */ -#define WM8995_WSEQ_DATA91_SHIFT 0 /* WSEQ_DATA91 - [7:0] */ -#define WM8995_WSEQ_DATA91_WIDTH 8 /* WSEQ_DATA91 - [7:0] */ - -/* - * R12654 (0x316E) - Write Sequencer 366 - */ -#define WM8995_WSEQ_DATA_WIDTH91_MASK 0x0700 /* WSEQ_DATA_WIDTH91 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH91_SHIFT 8 /* WSEQ_DATA_WIDTH91 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH91_WIDTH 3 /* WSEQ_DATA_WIDTH91 - [10:8] */ -#define WM8995_WSEQ_DATA_START91_MASK 0x000F /* WSEQ_DATA_START91 - [3:0] */ -#define WM8995_WSEQ_DATA_START91_SHIFT 0 /* WSEQ_DATA_START91 - [3:0] */ -#define WM8995_WSEQ_DATA_START91_WIDTH 4 /* WSEQ_DATA_START91 - [3:0] */ - -/* - * R12655 (0x316F) - Write Sequencer 367 - */ -#define WM8995_WSEQ_EOS91 0x0100 /* WSEQ_EOS91 */ -#define WM8995_WSEQ_EOS91_MASK 0x0100 /* WSEQ_EOS91 */ -#define WM8995_WSEQ_EOS91_SHIFT 8 /* WSEQ_EOS91 */ -#define WM8995_WSEQ_EOS91_WIDTH 1 /* WSEQ_EOS91 */ -#define WM8995_WSEQ_DELAY91_MASK 0x000F /* WSEQ_DELAY91 - [3:0] */ -#define WM8995_WSEQ_DELAY91_SHIFT 0 /* WSEQ_DELAY91 - [3:0] */ -#define WM8995_WSEQ_DELAY91_WIDTH 4 /* WSEQ_DELAY91 - [3:0] */ - -/* - * R12656 (0x3170) - Write Sequencer 368 - */ -#define WM8995_WSEQ_ADDR92_MASK 0x3FFF /* WSEQ_ADDR92 - [13:0] */ -#define WM8995_WSEQ_ADDR92_SHIFT 0 /* WSEQ_ADDR92 - [13:0] */ -#define WM8995_WSEQ_ADDR92_WIDTH 14 /* WSEQ_ADDR92 - [13:0] */ - -/* - * R12657 (0x3171) - Write Sequencer 369 - */ -#define WM8995_WSEQ_DATA92_MASK 0x00FF /* WSEQ_DATA92 - [7:0] */ -#define WM8995_WSEQ_DATA92_SHIFT 0 /* WSEQ_DATA92 - [7:0] */ -#define WM8995_WSEQ_DATA92_WIDTH 8 /* WSEQ_DATA92 - [7:0] */ - -/* - * R12658 (0x3172) - Write Sequencer 370 - */ -#define WM8995_WSEQ_DATA_WIDTH92_MASK 0x0700 /* WSEQ_DATA_WIDTH92 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH92_SHIFT 8 /* WSEQ_DATA_WIDTH92 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH92_WIDTH 3 /* WSEQ_DATA_WIDTH92 - [10:8] */ -#define WM8995_WSEQ_DATA_START92_MASK 0x000F /* WSEQ_DATA_START92 - [3:0] */ -#define WM8995_WSEQ_DATA_START92_SHIFT 0 /* WSEQ_DATA_START92 - [3:0] */ -#define WM8995_WSEQ_DATA_START92_WIDTH 4 /* WSEQ_DATA_START92 - [3:0] */ - -/* - * R12659 (0x3173) - Write Sequencer 371 - */ -#define WM8995_WSEQ_EOS92 0x0100 /* WSEQ_EOS92 */ -#define WM8995_WSEQ_EOS92_MASK 0x0100 /* WSEQ_EOS92 */ -#define WM8995_WSEQ_EOS92_SHIFT 8 /* WSEQ_EOS92 */ -#define WM8995_WSEQ_EOS92_WIDTH 1 /* WSEQ_EOS92 */ -#define WM8995_WSEQ_DELAY92_MASK 0x000F /* WSEQ_DELAY92 - [3:0] */ -#define WM8995_WSEQ_DELAY92_SHIFT 0 /* WSEQ_DELAY92 - [3:0] */ -#define WM8995_WSEQ_DELAY92_WIDTH 4 /* WSEQ_DELAY92 - [3:0] */ - -/* - * R12660 (0x3174) - Write Sequencer 372 - */ -#define WM8995_WSEQ_ADDR93_MASK 0x3FFF /* WSEQ_ADDR93 - [13:0] */ -#define WM8995_WSEQ_ADDR93_SHIFT 0 /* WSEQ_ADDR93 - [13:0] */ -#define WM8995_WSEQ_ADDR93_WIDTH 14 /* WSEQ_ADDR93 - [13:0] */ - -/* - * R12661 (0x3175) - Write Sequencer 373 - */ -#define WM8995_WSEQ_DATA93_MASK 0x00FF /* WSEQ_DATA93 - [7:0] */ -#define WM8995_WSEQ_DATA93_SHIFT 0 /* WSEQ_DATA93 - [7:0] */ -#define WM8995_WSEQ_DATA93_WIDTH 8 /* WSEQ_DATA93 - [7:0] */ - -/* - * R12662 (0x3176) - Write Sequencer 374 - */ -#define WM8995_WSEQ_DATA_WIDTH93_MASK 0x0700 /* WSEQ_DATA_WIDTH93 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH93_SHIFT 8 /* WSEQ_DATA_WIDTH93 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH93_WIDTH 3 /* WSEQ_DATA_WIDTH93 - [10:8] */ -#define WM8995_WSEQ_DATA_START93_MASK 0x000F /* WSEQ_DATA_START93 - [3:0] */ -#define WM8995_WSEQ_DATA_START93_SHIFT 0 /* WSEQ_DATA_START93 - [3:0] */ -#define WM8995_WSEQ_DATA_START93_WIDTH 4 /* WSEQ_DATA_START93 - [3:0] */ - -/* - * R12663 (0x3177) - Write Sequencer 375 - */ -#define WM8995_WSEQ_EOS93 0x0100 /* WSEQ_EOS93 */ -#define WM8995_WSEQ_EOS93_MASK 0x0100 /* WSEQ_EOS93 */ -#define WM8995_WSEQ_EOS93_SHIFT 8 /* WSEQ_EOS93 */ -#define WM8995_WSEQ_EOS93_WIDTH 1 /* WSEQ_EOS93 */ -#define WM8995_WSEQ_DELAY93_MASK 0x000F /* WSEQ_DELAY93 - [3:0] */ -#define WM8995_WSEQ_DELAY93_SHIFT 0 /* WSEQ_DELAY93 - [3:0] */ -#define WM8995_WSEQ_DELAY93_WIDTH 4 /* WSEQ_DELAY93 - [3:0] */ - -/* - * R12664 (0x3178) - Write Sequencer 376 - */ -#define WM8995_WSEQ_ADDR94_MASK 0x3FFF /* WSEQ_ADDR94 - [13:0] */ -#define WM8995_WSEQ_ADDR94_SHIFT 0 /* WSEQ_ADDR94 - [13:0] */ -#define WM8995_WSEQ_ADDR94_WIDTH 14 /* WSEQ_ADDR94 - [13:0] */ - -/* - * R12665 (0x3179) - Write Sequencer 377 - */ -#define WM8995_WSEQ_DATA94_MASK 0x00FF /* WSEQ_DATA94 - [7:0] */ -#define WM8995_WSEQ_DATA94_SHIFT 0 /* WSEQ_DATA94 - [7:0] */ -#define WM8995_WSEQ_DATA94_WIDTH 8 /* WSEQ_DATA94 - [7:0] */ - -/* - * R12666 (0x317A) - Write Sequencer 378 - */ -#define WM8995_WSEQ_DATA_WIDTH94_MASK 0x0700 /* WSEQ_DATA_WIDTH94 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH94_SHIFT 8 /* WSEQ_DATA_WIDTH94 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH94_WIDTH 3 /* WSEQ_DATA_WIDTH94 - [10:8] */ -#define WM8995_WSEQ_DATA_START94_MASK 0x000F /* WSEQ_DATA_START94 - [3:0] */ -#define WM8995_WSEQ_DATA_START94_SHIFT 0 /* WSEQ_DATA_START94 - [3:0] */ -#define WM8995_WSEQ_DATA_START94_WIDTH 4 /* WSEQ_DATA_START94 - [3:0] */ - -/* - * R12667 (0x317B) - Write Sequencer 379 - */ -#define WM8995_WSEQ_EOS94 0x0100 /* WSEQ_EOS94 */ -#define WM8995_WSEQ_EOS94_MASK 0x0100 /* WSEQ_EOS94 */ -#define WM8995_WSEQ_EOS94_SHIFT 8 /* WSEQ_EOS94 */ -#define WM8995_WSEQ_EOS94_WIDTH 1 /* WSEQ_EOS94 */ -#define WM8995_WSEQ_DELAY94_MASK 0x000F /* WSEQ_DELAY94 - [3:0] */ -#define WM8995_WSEQ_DELAY94_SHIFT 0 /* WSEQ_DELAY94 - [3:0] */ -#define WM8995_WSEQ_DELAY94_WIDTH 4 /* WSEQ_DELAY94 - [3:0] */ - -/* - * R12668 (0x317C) - Write Sequencer 380 - */ -#define WM8995_WSEQ_ADDR95_MASK 0x3FFF /* WSEQ_ADDR95 - [13:0] */ -#define WM8995_WSEQ_ADDR95_SHIFT 0 /* WSEQ_ADDR95 - [13:0] */ -#define WM8995_WSEQ_ADDR95_WIDTH 14 /* WSEQ_ADDR95 - [13:0] */ - -/* - * R12669 (0x317D) - Write Sequencer 381 - */ -#define WM8995_WSEQ_DATA95_MASK 0x00FF /* WSEQ_DATA95 - [7:0] */ -#define WM8995_WSEQ_DATA95_SHIFT 0 /* WSEQ_DATA95 - [7:0] */ -#define WM8995_WSEQ_DATA95_WIDTH 8 /* WSEQ_DATA95 - [7:0] */ - -/* - * R12670 (0x317E) - Write Sequencer 382 - */ -#define WM8995_WSEQ_DATA_WIDTH95_MASK 0x0700 /* WSEQ_DATA_WIDTH95 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH95_SHIFT 8 /* WSEQ_DATA_WIDTH95 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH95_WIDTH 3 /* WSEQ_DATA_WIDTH95 - [10:8] */ -#define WM8995_WSEQ_DATA_START95_MASK 0x000F /* WSEQ_DATA_START95 - [3:0] */ -#define WM8995_WSEQ_DATA_START95_SHIFT 0 /* WSEQ_DATA_START95 - [3:0] */ -#define WM8995_WSEQ_DATA_START95_WIDTH 4 /* WSEQ_DATA_START95 - [3:0] */ - -/* - * R12671 (0x317F) - Write Sequencer 383 - */ -#define WM8995_WSEQ_EOS95 0x0100 /* WSEQ_EOS95 */ -#define WM8995_WSEQ_EOS95_MASK 0x0100 /* WSEQ_EOS95 */ -#define WM8995_WSEQ_EOS95_SHIFT 8 /* WSEQ_EOS95 */ -#define WM8995_WSEQ_EOS95_WIDTH 1 /* WSEQ_EOS95 */ -#define WM8995_WSEQ_DELAY95_MASK 0x000F /* WSEQ_DELAY95 - [3:0] */ -#define WM8995_WSEQ_DELAY95_SHIFT 0 /* WSEQ_DELAY95 - [3:0] */ -#define WM8995_WSEQ_DELAY95_WIDTH 4 /* WSEQ_DELAY95 - [3:0] */ - -/* - * R12672 (0x3180) - Write Sequencer 384 - */ -#define WM8995_WSEQ_ADDR96_MASK 0x3FFF /* WSEQ_ADDR96 - [13:0] */ -#define WM8995_WSEQ_ADDR96_SHIFT 0 /* WSEQ_ADDR96 - [13:0] */ -#define WM8995_WSEQ_ADDR96_WIDTH 14 /* WSEQ_ADDR96 - [13:0] */ - -/* - * R12673 (0x3181) - Write Sequencer 385 - */ -#define WM8995_WSEQ_DATA96_MASK 0x00FF /* WSEQ_DATA96 - [7:0] */ -#define WM8995_WSEQ_DATA96_SHIFT 0 /* WSEQ_DATA96 - [7:0] */ -#define WM8995_WSEQ_DATA96_WIDTH 8 /* WSEQ_DATA96 - [7:0] */ - -/* - * R12674 (0x3182) - Write Sequencer 386 - */ -#define WM8995_WSEQ_DATA_WIDTH96_MASK 0x0700 /* WSEQ_DATA_WIDTH96 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH96_SHIFT 8 /* WSEQ_DATA_WIDTH96 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH96_WIDTH 3 /* WSEQ_DATA_WIDTH96 - [10:8] */ -#define WM8995_WSEQ_DATA_START96_MASK 0x000F /* WSEQ_DATA_START96 - [3:0] */ -#define WM8995_WSEQ_DATA_START96_SHIFT 0 /* WSEQ_DATA_START96 - [3:0] */ -#define WM8995_WSEQ_DATA_START96_WIDTH 4 /* WSEQ_DATA_START96 - [3:0] */ - -/* - * R12675 (0x3183) - Write Sequencer 387 - */ -#define WM8995_WSEQ_EOS96 0x0100 /* WSEQ_EOS96 */ -#define WM8995_WSEQ_EOS96_MASK 0x0100 /* WSEQ_EOS96 */ -#define WM8995_WSEQ_EOS96_SHIFT 8 /* WSEQ_EOS96 */ -#define WM8995_WSEQ_EOS96_WIDTH 1 /* WSEQ_EOS96 */ -#define WM8995_WSEQ_DELAY96_MASK 0x000F /* WSEQ_DELAY96 - [3:0] */ -#define WM8995_WSEQ_DELAY96_SHIFT 0 /* WSEQ_DELAY96 - [3:0] */ -#define WM8995_WSEQ_DELAY96_WIDTH 4 /* WSEQ_DELAY96 - [3:0] */ - -/* - * R12676 (0x3184) - Write Sequencer 388 - */ -#define WM8995_WSEQ_ADDR97_MASK 0x3FFF /* WSEQ_ADDR97 - [13:0] */ -#define WM8995_WSEQ_ADDR97_SHIFT 0 /* WSEQ_ADDR97 - [13:0] */ -#define WM8995_WSEQ_ADDR97_WIDTH 14 /* WSEQ_ADDR97 - [13:0] */ - -/* - * R12677 (0x3185) - Write Sequencer 389 - */ -#define WM8995_WSEQ_DATA97_MASK 0x00FF /* WSEQ_DATA97 - [7:0] */ -#define WM8995_WSEQ_DATA97_SHIFT 0 /* WSEQ_DATA97 - [7:0] */ -#define WM8995_WSEQ_DATA97_WIDTH 8 /* WSEQ_DATA97 - [7:0] */ - -/* - * R12678 (0x3186) - Write Sequencer 390 - */ -#define WM8995_WSEQ_DATA_WIDTH97_MASK 0x0700 /* WSEQ_DATA_WIDTH97 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH97_SHIFT 8 /* WSEQ_DATA_WIDTH97 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH97_WIDTH 3 /* WSEQ_DATA_WIDTH97 - [10:8] */ -#define WM8995_WSEQ_DATA_START97_MASK 0x000F /* WSEQ_DATA_START97 - [3:0] */ -#define WM8995_WSEQ_DATA_START97_SHIFT 0 /* WSEQ_DATA_START97 - [3:0] */ -#define WM8995_WSEQ_DATA_START97_WIDTH 4 /* WSEQ_DATA_START97 - [3:0] */ - -/* - * R12679 (0x3187) - Write Sequencer 391 - */ -#define WM8995_WSEQ_EOS97 0x0100 /* WSEQ_EOS97 */ -#define WM8995_WSEQ_EOS97_MASK 0x0100 /* WSEQ_EOS97 */ -#define WM8995_WSEQ_EOS97_SHIFT 8 /* WSEQ_EOS97 */ -#define WM8995_WSEQ_EOS97_WIDTH 1 /* WSEQ_EOS97 */ -#define WM8995_WSEQ_DELAY97_MASK 0x000F /* WSEQ_DELAY97 - [3:0] */ -#define WM8995_WSEQ_DELAY97_SHIFT 0 /* WSEQ_DELAY97 - [3:0] */ -#define WM8995_WSEQ_DELAY97_WIDTH 4 /* WSEQ_DELAY97 - [3:0] */ - -/* - * R12680 (0x3188) - Write Sequencer 392 - */ -#define WM8995_WSEQ_ADDR98_MASK 0x3FFF /* WSEQ_ADDR98 - [13:0] */ -#define WM8995_WSEQ_ADDR98_SHIFT 0 /* WSEQ_ADDR98 - [13:0] */ -#define WM8995_WSEQ_ADDR98_WIDTH 14 /* WSEQ_ADDR98 - [13:0] */ - -/* - * R12681 (0x3189) - Write Sequencer 393 - */ -#define WM8995_WSEQ_DATA98_MASK 0x00FF /* WSEQ_DATA98 - [7:0] */ -#define WM8995_WSEQ_DATA98_SHIFT 0 /* WSEQ_DATA98 - [7:0] */ -#define WM8995_WSEQ_DATA98_WIDTH 8 /* WSEQ_DATA98 - [7:0] */ - -/* - * R12682 (0x318A) - Write Sequencer 394 - */ -#define WM8995_WSEQ_DATA_WIDTH98_MASK 0x0700 /* WSEQ_DATA_WIDTH98 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH98_SHIFT 8 /* WSEQ_DATA_WIDTH98 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH98_WIDTH 3 /* WSEQ_DATA_WIDTH98 - [10:8] */ -#define WM8995_WSEQ_DATA_START98_MASK 0x000F /* WSEQ_DATA_START98 - [3:0] */ -#define WM8995_WSEQ_DATA_START98_SHIFT 0 /* WSEQ_DATA_START98 - [3:0] */ -#define WM8995_WSEQ_DATA_START98_WIDTH 4 /* WSEQ_DATA_START98 - [3:0] */ - -/* - * R12683 (0x318B) - Write Sequencer 395 - */ -#define WM8995_WSEQ_EOS98 0x0100 /* WSEQ_EOS98 */ -#define WM8995_WSEQ_EOS98_MASK 0x0100 /* WSEQ_EOS98 */ -#define WM8995_WSEQ_EOS98_SHIFT 8 /* WSEQ_EOS98 */ -#define WM8995_WSEQ_EOS98_WIDTH 1 /* WSEQ_EOS98 */ -#define WM8995_WSEQ_DELAY98_MASK 0x000F /* WSEQ_DELAY98 - [3:0] */ -#define WM8995_WSEQ_DELAY98_SHIFT 0 /* WSEQ_DELAY98 - [3:0] */ -#define WM8995_WSEQ_DELAY98_WIDTH 4 /* WSEQ_DELAY98 - [3:0] */ - -/* - * R12684 (0x318C) - Write Sequencer 396 - */ -#define WM8995_WSEQ_ADDR99_MASK 0x3FFF /* WSEQ_ADDR99 - [13:0] */ -#define WM8995_WSEQ_ADDR99_SHIFT 0 /* WSEQ_ADDR99 - [13:0] */ -#define WM8995_WSEQ_ADDR99_WIDTH 14 /* WSEQ_ADDR99 - [13:0] */ - -/* - * R12685 (0x318D) - Write Sequencer 397 - */ -#define WM8995_WSEQ_DATA99_MASK 0x00FF /* WSEQ_DATA99 - [7:0] */ -#define WM8995_WSEQ_DATA99_SHIFT 0 /* WSEQ_DATA99 - [7:0] */ -#define WM8995_WSEQ_DATA99_WIDTH 8 /* WSEQ_DATA99 - [7:0] */ - -/* - * R12686 (0x318E) - Write Sequencer 398 - */ -#define WM8995_WSEQ_DATA_WIDTH99_MASK 0x0700 /* WSEQ_DATA_WIDTH99 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH99_SHIFT 8 /* WSEQ_DATA_WIDTH99 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH99_WIDTH 3 /* WSEQ_DATA_WIDTH99 - [10:8] */ -#define WM8995_WSEQ_DATA_START99_MASK 0x000F /* WSEQ_DATA_START99 - [3:0] */ -#define WM8995_WSEQ_DATA_START99_SHIFT 0 /* WSEQ_DATA_START99 - [3:0] */ -#define WM8995_WSEQ_DATA_START99_WIDTH 4 /* WSEQ_DATA_START99 - [3:0] */ - -/* - * R12687 (0x318F) - Write Sequencer 399 - */ -#define WM8995_WSEQ_EOS99 0x0100 /* WSEQ_EOS99 */ -#define WM8995_WSEQ_EOS99_MASK 0x0100 /* WSEQ_EOS99 */ -#define WM8995_WSEQ_EOS99_SHIFT 8 /* WSEQ_EOS99 */ -#define WM8995_WSEQ_EOS99_WIDTH 1 /* WSEQ_EOS99 */ -#define WM8995_WSEQ_DELAY99_MASK 0x000F /* WSEQ_DELAY99 - [3:0] */ -#define WM8995_WSEQ_DELAY99_SHIFT 0 /* WSEQ_DELAY99 - [3:0] */ -#define WM8995_WSEQ_DELAY99_WIDTH 4 /* WSEQ_DELAY99 - [3:0] */ - -/* - * R12688 (0x3190) - Write Sequencer 400 - */ -#define WM8995_WSEQ_ADDR100_MASK 0x3FFF /* WSEQ_ADDR100 - [13:0] */ -#define WM8995_WSEQ_ADDR100_SHIFT 0 /* WSEQ_ADDR100 - [13:0] */ -#define WM8995_WSEQ_ADDR100_WIDTH 14 /* WSEQ_ADDR100 - [13:0] */ - -/* - * R12689 (0x3191) - Write Sequencer 401 - */ -#define WM8995_WSEQ_DATA100_MASK 0x00FF /* WSEQ_DATA100 - [7:0] */ -#define WM8995_WSEQ_DATA100_SHIFT 0 /* WSEQ_DATA100 - [7:0] */ -#define WM8995_WSEQ_DATA100_WIDTH 8 /* WSEQ_DATA100 - [7:0] */ - -/* - * R12690 (0x3192) - Write Sequencer 402 - */ -#define WM8995_WSEQ_DATA_WIDTH100_MASK 0x0700 /* WSEQ_DATA_WIDTH100 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH100_SHIFT 8 /* WSEQ_DATA_WIDTH100 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH100_WIDTH 3 /* WSEQ_DATA_WIDTH100 - [10:8] */ -#define WM8995_WSEQ_DATA_START100_MASK 0x000F /* WSEQ_DATA_START100 - [3:0] */ -#define WM8995_WSEQ_DATA_START100_SHIFT 0 /* WSEQ_DATA_START100 - [3:0] */ -#define WM8995_WSEQ_DATA_START100_WIDTH 4 /* WSEQ_DATA_START100 - [3:0] */ - -/* - * R12691 (0x3193) - Write Sequencer 403 - */ -#define WM8995_WSEQ_EOS100 0x0100 /* WSEQ_EOS100 */ -#define WM8995_WSEQ_EOS100_MASK 0x0100 /* WSEQ_EOS100 */ -#define WM8995_WSEQ_EOS100_SHIFT 8 /* WSEQ_EOS100 */ -#define WM8995_WSEQ_EOS100_WIDTH 1 /* WSEQ_EOS100 */ -#define WM8995_WSEQ_DELAY100_MASK 0x000F /* WSEQ_DELAY100 - [3:0] */ -#define WM8995_WSEQ_DELAY100_SHIFT 0 /* WSEQ_DELAY100 - [3:0] */ -#define WM8995_WSEQ_DELAY100_WIDTH 4 /* WSEQ_DELAY100 - [3:0] */ - -/* - * R12692 (0x3194) - Write Sequencer 404 - */ -#define WM8995_WSEQ_ADDR101_MASK 0x3FFF /* WSEQ_ADDR101 - [13:0] */ -#define WM8995_WSEQ_ADDR101_SHIFT 0 /* WSEQ_ADDR101 - [13:0] */ -#define WM8995_WSEQ_ADDR101_WIDTH 14 /* WSEQ_ADDR101 - [13:0] */ - -/* - * R12693 (0x3195) - Write Sequencer 405 - */ -#define WM8995_WSEQ_DATA101_MASK 0x00FF /* WSEQ_DATA101 - [7:0] */ -#define WM8995_WSEQ_DATA101_SHIFT 0 /* WSEQ_DATA101 - [7:0] */ -#define WM8995_WSEQ_DATA101_WIDTH 8 /* WSEQ_DATA101 - [7:0] */ - -/* - * R12694 (0x3196) - Write Sequencer 406 - */ -#define WM8995_WSEQ_DATA_WIDTH101_MASK 0x0700 /* WSEQ_DATA_WIDTH101 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH101_SHIFT 8 /* WSEQ_DATA_WIDTH101 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH101_WIDTH 3 /* WSEQ_DATA_WIDTH101 - [10:8] */ -#define WM8995_WSEQ_DATA_START101_MASK 0x000F /* WSEQ_DATA_START101 - [3:0] */ -#define WM8995_WSEQ_DATA_START101_SHIFT 0 /* WSEQ_DATA_START101 - [3:0] */ -#define WM8995_WSEQ_DATA_START101_WIDTH 4 /* WSEQ_DATA_START101 - [3:0] */ - -/* - * R12695 (0x3197) - Write Sequencer 407 - */ -#define WM8995_WSEQ_EOS101 0x0100 /* WSEQ_EOS101 */ -#define WM8995_WSEQ_EOS101_MASK 0x0100 /* WSEQ_EOS101 */ -#define WM8995_WSEQ_EOS101_SHIFT 8 /* WSEQ_EOS101 */ -#define WM8995_WSEQ_EOS101_WIDTH 1 /* WSEQ_EOS101 */ -#define WM8995_WSEQ_DELAY101_MASK 0x000F /* WSEQ_DELAY101 - [3:0] */ -#define WM8995_WSEQ_DELAY101_SHIFT 0 /* WSEQ_DELAY101 - [3:0] */ -#define WM8995_WSEQ_DELAY101_WIDTH 4 /* WSEQ_DELAY101 - [3:0] */ - -/* - * R12696 (0x3198) - Write Sequencer 408 - */ -#define WM8995_WSEQ_ADDR102_MASK 0x3FFF /* WSEQ_ADDR102 - [13:0] */ -#define WM8995_WSEQ_ADDR102_SHIFT 0 /* WSEQ_ADDR102 - [13:0] */ -#define WM8995_WSEQ_ADDR102_WIDTH 14 /* WSEQ_ADDR102 - [13:0] */ - -/* - * R12697 (0x3199) - Write Sequencer 409 - */ -#define WM8995_WSEQ_DATA102_MASK 0x00FF /* WSEQ_DATA102 - [7:0] */ -#define WM8995_WSEQ_DATA102_SHIFT 0 /* WSEQ_DATA102 - [7:0] */ -#define WM8995_WSEQ_DATA102_WIDTH 8 /* WSEQ_DATA102 - [7:0] */ - -/* - * R12698 (0x319A) - Write Sequencer 410 - */ -#define WM8995_WSEQ_DATA_WIDTH102_MASK 0x0700 /* WSEQ_DATA_WIDTH102 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH102_SHIFT 8 /* WSEQ_DATA_WIDTH102 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH102_WIDTH 3 /* WSEQ_DATA_WIDTH102 - [10:8] */ -#define WM8995_WSEQ_DATA_START102_MASK 0x000F /* WSEQ_DATA_START102 - [3:0] */ -#define WM8995_WSEQ_DATA_START102_SHIFT 0 /* WSEQ_DATA_START102 - [3:0] */ -#define WM8995_WSEQ_DATA_START102_WIDTH 4 /* WSEQ_DATA_START102 - [3:0] */ - -/* - * R12699 (0x319B) - Write Sequencer 411 - */ -#define WM8995_WSEQ_EOS102 0x0100 /* WSEQ_EOS102 */ -#define WM8995_WSEQ_EOS102_MASK 0x0100 /* WSEQ_EOS102 */ -#define WM8995_WSEQ_EOS102_SHIFT 8 /* WSEQ_EOS102 */ -#define WM8995_WSEQ_EOS102_WIDTH 1 /* WSEQ_EOS102 */ -#define WM8995_WSEQ_DELAY102_MASK 0x000F /* WSEQ_DELAY102 - [3:0] */ -#define WM8995_WSEQ_DELAY102_SHIFT 0 /* WSEQ_DELAY102 - [3:0] */ -#define WM8995_WSEQ_DELAY102_WIDTH 4 /* WSEQ_DELAY102 - [3:0] */ - -/* - * R12700 (0x319C) - Write Sequencer 412 - */ -#define WM8995_WSEQ_ADDR103_MASK 0x3FFF /* WSEQ_ADDR103 - [13:0] */ -#define WM8995_WSEQ_ADDR103_SHIFT 0 /* WSEQ_ADDR103 - [13:0] */ -#define WM8995_WSEQ_ADDR103_WIDTH 14 /* WSEQ_ADDR103 - [13:0] */ - -/* - * R12701 (0x319D) - Write Sequencer 413 - */ -#define WM8995_WSEQ_DATA103_MASK 0x00FF /* WSEQ_DATA103 - [7:0] */ -#define WM8995_WSEQ_DATA103_SHIFT 0 /* WSEQ_DATA103 - [7:0] */ -#define WM8995_WSEQ_DATA103_WIDTH 8 /* WSEQ_DATA103 - [7:0] */ - -/* - * R12702 (0x319E) - Write Sequencer 414 - */ -#define WM8995_WSEQ_DATA_WIDTH103_MASK 0x0700 /* WSEQ_DATA_WIDTH103 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH103_SHIFT 8 /* WSEQ_DATA_WIDTH103 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH103_WIDTH 3 /* WSEQ_DATA_WIDTH103 - [10:8] */ -#define WM8995_WSEQ_DATA_START103_MASK 0x000F /* WSEQ_DATA_START103 - [3:0] */ -#define WM8995_WSEQ_DATA_START103_SHIFT 0 /* WSEQ_DATA_START103 - [3:0] */ -#define WM8995_WSEQ_DATA_START103_WIDTH 4 /* WSEQ_DATA_START103 - [3:0] */ - -/* - * R12703 (0x319F) - Write Sequencer 415 - */ -#define WM8995_WSEQ_EOS103 0x0100 /* WSEQ_EOS103 */ -#define WM8995_WSEQ_EOS103_MASK 0x0100 /* WSEQ_EOS103 */ -#define WM8995_WSEQ_EOS103_SHIFT 8 /* WSEQ_EOS103 */ -#define WM8995_WSEQ_EOS103_WIDTH 1 /* WSEQ_EOS103 */ -#define WM8995_WSEQ_DELAY103_MASK 0x000F /* WSEQ_DELAY103 - [3:0] */ -#define WM8995_WSEQ_DELAY103_SHIFT 0 /* WSEQ_DELAY103 - [3:0] */ -#define WM8995_WSEQ_DELAY103_WIDTH 4 /* WSEQ_DELAY103 - [3:0] */ - -/* - * R12704 (0x31A0) - Write Sequencer 416 - */ -#define WM8995_WSEQ_ADDR104_MASK 0x3FFF /* WSEQ_ADDR104 - [13:0] */ -#define WM8995_WSEQ_ADDR104_SHIFT 0 /* WSEQ_ADDR104 - [13:0] */ -#define WM8995_WSEQ_ADDR104_WIDTH 14 /* WSEQ_ADDR104 - [13:0] */ - -/* - * R12705 (0x31A1) - Write Sequencer 417 - */ -#define WM8995_WSEQ_DATA104_MASK 0x00FF /* WSEQ_DATA104 - [7:0] */ -#define WM8995_WSEQ_DATA104_SHIFT 0 /* WSEQ_DATA104 - [7:0] */ -#define WM8995_WSEQ_DATA104_WIDTH 8 /* WSEQ_DATA104 - [7:0] */ - -/* - * R12706 (0x31A2) - Write Sequencer 418 - */ -#define WM8995_WSEQ_DATA_WIDTH104_MASK 0x0700 /* WSEQ_DATA_WIDTH104 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH104_SHIFT 8 /* WSEQ_DATA_WIDTH104 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH104_WIDTH 3 /* WSEQ_DATA_WIDTH104 - [10:8] */ -#define WM8995_WSEQ_DATA_START104_MASK 0x000F /* WSEQ_DATA_START104 - [3:0] */ -#define WM8995_WSEQ_DATA_START104_SHIFT 0 /* WSEQ_DATA_START104 - [3:0] */ -#define WM8995_WSEQ_DATA_START104_WIDTH 4 /* WSEQ_DATA_START104 - [3:0] */ - -/* - * R12707 (0x31A3) - Write Sequencer 419 - */ -#define WM8995_WSEQ_EOS104 0x0100 /* WSEQ_EOS104 */ -#define WM8995_WSEQ_EOS104_MASK 0x0100 /* WSEQ_EOS104 */ -#define WM8995_WSEQ_EOS104_SHIFT 8 /* WSEQ_EOS104 */ -#define WM8995_WSEQ_EOS104_WIDTH 1 /* WSEQ_EOS104 */ -#define WM8995_WSEQ_DELAY104_MASK 0x000F /* WSEQ_DELAY104 - [3:0] */ -#define WM8995_WSEQ_DELAY104_SHIFT 0 /* WSEQ_DELAY104 - [3:0] */ -#define WM8995_WSEQ_DELAY104_WIDTH 4 /* WSEQ_DELAY104 - [3:0] */ - -/* - * R12708 (0x31A4) - Write Sequencer 420 - */ -#define WM8995_WSEQ_ADDR105_MASK 0x3FFF /* WSEQ_ADDR105 - [13:0] */ -#define WM8995_WSEQ_ADDR105_SHIFT 0 /* WSEQ_ADDR105 - [13:0] */ -#define WM8995_WSEQ_ADDR105_WIDTH 14 /* WSEQ_ADDR105 - [13:0] */ - -/* - * R12709 (0x31A5) - Write Sequencer 421 - */ -#define WM8995_WSEQ_DATA105_MASK 0x00FF /* WSEQ_DATA105 - [7:0] */ -#define WM8995_WSEQ_DATA105_SHIFT 0 /* WSEQ_DATA105 - [7:0] */ -#define WM8995_WSEQ_DATA105_WIDTH 8 /* WSEQ_DATA105 - [7:0] */ - -/* - * R12710 (0x31A6) - Write Sequencer 422 - */ -#define WM8995_WSEQ_DATA_WIDTH105_MASK 0x0700 /* WSEQ_DATA_WIDTH105 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH105_SHIFT 8 /* WSEQ_DATA_WIDTH105 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH105_WIDTH 3 /* WSEQ_DATA_WIDTH105 - [10:8] */ -#define WM8995_WSEQ_DATA_START105_MASK 0x000F /* WSEQ_DATA_START105 - [3:0] */ -#define WM8995_WSEQ_DATA_START105_SHIFT 0 /* WSEQ_DATA_START105 - [3:0] */ -#define WM8995_WSEQ_DATA_START105_WIDTH 4 /* WSEQ_DATA_START105 - [3:0] */ - -/* - * R12711 (0x31A7) - Write Sequencer 423 - */ -#define WM8995_WSEQ_EOS105 0x0100 /* WSEQ_EOS105 */ -#define WM8995_WSEQ_EOS105_MASK 0x0100 /* WSEQ_EOS105 */ -#define WM8995_WSEQ_EOS105_SHIFT 8 /* WSEQ_EOS105 */ -#define WM8995_WSEQ_EOS105_WIDTH 1 /* WSEQ_EOS105 */ -#define WM8995_WSEQ_DELAY105_MASK 0x000F /* WSEQ_DELAY105 - [3:0] */ -#define WM8995_WSEQ_DELAY105_SHIFT 0 /* WSEQ_DELAY105 - [3:0] */ -#define WM8995_WSEQ_DELAY105_WIDTH 4 /* WSEQ_DELAY105 - [3:0] */ - -/* - * R12712 (0x31A8) - Write Sequencer 424 - */ -#define WM8995_WSEQ_ADDR106_MASK 0x3FFF /* WSEQ_ADDR106 - [13:0] */ -#define WM8995_WSEQ_ADDR106_SHIFT 0 /* WSEQ_ADDR106 - [13:0] */ -#define WM8995_WSEQ_ADDR106_WIDTH 14 /* WSEQ_ADDR106 - [13:0] */ - -/* - * R12713 (0x31A9) - Write Sequencer 425 - */ -#define WM8995_WSEQ_DATA106_MASK 0x00FF /* WSEQ_DATA106 - [7:0] */ -#define WM8995_WSEQ_DATA106_SHIFT 0 /* WSEQ_DATA106 - [7:0] */ -#define WM8995_WSEQ_DATA106_WIDTH 8 /* WSEQ_DATA106 - [7:0] */ - -/* - * R12714 (0x31AA) - Write Sequencer 426 - */ -#define WM8995_WSEQ_DATA_WIDTH106_MASK 0x0700 /* WSEQ_DATA_WIDTH106 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH106_SHIFT 8 /* WSEQ_DATA_WIDTH106 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH106_WIDTH 3 /* WSEQ_DATA_WIDTH106 - [10:8] */ -#define WM8995_WSEQ_DATA_START106_MASK 0x000F /* WSEQ_DATA_START106 - [3:0] */ -#define WM8995_WSEQ_DATA_START106_SHIFT 0 /* WSEQ_DATA_START106 - [3:0] */ -#define WM8995_WSEQ_DATA_START106_WIDTH 4 /* WSEQ_DATA_START106 - [3:0] */ - -/* - * R12715 (0x31AB) - Write Sequencer 427 - */ -#define WM8995_WSEQ_EOS106 0x0100 /* WSEQ_EOS106 */ -#define WM8995_WSEQ_EOS106_MASK 0x0100 /* WSEQ_EOS106 */ -#define WM8995_WSEQ_EOS106_SHIFT 8 /* WSEQ_EOS106 */ -#define WM8995_WSEQ_EOS106_WIDTH 1 /* WSEQ_EOS106 */ -#define WM8995_WSEQ_DELAY106_MASK 0x000F /* WSEQ_DELAY106 - [3:0] */ -#define WM8995_WSEQ_DELAY106_SHIFT 0 /* WSEQ_DELAY106 - [3:0] */ -#define WM8995_WSEQ_DELAY106_WIDTH 4 /* WSEQ_DELAY106 - [3:0] */ - -/* - * R12716 (0x31AC) - Write Sequencer 428 - */ -#define WM8995_WSEQ_ADDR107_MASK 0x3FFF /* WSEQ_ADDR107 - [13:0] */ -#define WM8995_WSEQ_ADDR107_SHIFT 0 /* WSEQ_ADDR107 - [13:0] */ -#define WM8995_WSEQ_ADDR107_WIDTH 14 /* WSEQ_ADDR107 - [13:0] */ - -/* - * R12717 (0x31AD) - Write Sequencer 429 - */ -#define WM8995_WSEQ_DATA107_MASK 0x00FF /* WSEQ_DATA107 - [7:0] */ -#define WM8995_WSEQ_DATA107_SHIFT 0 /* WSEQ_DATA107 - [7:0] */ -#define WM8995_WSEQ_DATA107_WIDTH 8 /* WSEQ_DATA107 - [7:0] */ - -/* - * R12718 (0x31AE) - Write Sequencer 430 - */ -#define WM8995_WSEQ_DATA_WIDTH107_MASK 0x0700 /* WSEQ_DATA_WIDTH107 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH107_SHIFT 8 /* WSEQ_DATA_WIDTH107 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH107_WIDTH 3 /* WSEQ_DATA_WIDTH107 - [10:8] */ -#define WM8995_WSEQ_DATA_START107_MASK 0x000F /* WSEQ_DATA_START107 - [3:0] */ -#define WM8995_WSEQ_DATA_START107_SHIFT 0 /* WSEQ_DATA_START107 - [3:0] */ -#define WM8995_WSEQ_DATA_START107_WIDTH 4 /* WSEQ_DATA_START107 - [3:0] */ - -/* - * R12719 (0x31AF) - Write Sequencer 431 - */ -#define WM8995_WSEQ_EOS107 0x0100 /* WSEQ_EOS107 */ -#define WM8995_WSEQ_EOS107_MASK 0x0100 /* WSEQ_EOS107 */ -#define WM8995_WSEQ_EOS107_SHIFT 8 /* WSEQ_EOS107 */ -#define WM8995_WSEQ_EOS107_WIDTH 1 /* WSEQ_EOS107 */ -#define WM8995_WSEQ_DELAY107_MASK 0x000F /* WSEQ_DELAY107 - [3:0] */ -#define WM8995_WSEQ_DELAY107_SHIFT 0 /* WSEQ_DELAY107 - [3:0] */ -#define WM8995_WSEQ_DELAY107_WIDTH 4 /* WSEQ_DELAY107 - [3:0] */ - -/* - * R12720 (0x31B0) - Write Sequencer 432 - */ -#define WM8995_WSEQ_ADDR108_MASK 0x3FFF /* WSEQ_ADDR108 - [13:0] */ -#define WM8995_WSEQ_ADDR108_SHIFT 0 /* WSEQ_ADDR108 - [13:0] */ -#define WM8995_WSEQ_ADDR108_WIDTH 14 /* WSEQ_ADDR108 - [13:0] */ - -/* - * R12721 (0x31B1) - Write Sequencer 433 - */ -#define WM8995_WSEQ_DATA108_MASK 0x00FF /* WSEQ_DATA108 - [7:0] */ -#define WM8995_WSEQ_DATA108_SHIFT 0 /* WSEQ_DATA108 - [7:0] */ -#define WM8995_WSEQ_DATA108_WIDTH 8 /* WSEQ_DATA108 - [7:0] */ - -/* - * R12722 (0x31B2) - Write Sequencer 434 - */ -#define WM8995_WSEQ_DATA_WIDTH108_MASK 0x0700 /* WSEQ_DATA_WIDTH108 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH108_SHIFT 8 /* WSEQ_DATA_WIDTH108 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH108_WIDTH 3 /* WSEQ_DATA_WIDTH108 - [10:8] */ -#define WM8995_WSEQ_DATA_START108_MASK 0x000F /* WSEQ_DATA_START108 - [3:0] */ -#define WM8995_WSEQ_DATA_START108_SHIFT 0 /* WSEQ_DATA_START108 - [3:0] */ -#define WM8995_WSEQ_DATA_START108_WIDTH 4 /* WSEQ_DATA_START108 - [3:0] */ - -/* - * R12723 (0x31B3) - Write Sequencer 435 - */ -#define WM8995_WSEQ_EOS108 0x0100 /* WSEQ_EOS108 */ -#define WM8995_WSEQ_EOS108_MASK 0x0100 /* WSEQ_EOS108 */ -#define WM8995_WSEQ_EOS108_SHIFT 8 /* WSEQ_EOS108 */ -#define WM8995_WSEQ_EOS108_WIDTH 1 /* WSEQ_EOS108 */ -#define WM8995_WSEQ_DELAY108_MASK 0x000F /* WSEQ_DELAY108 - [3:0] */ -#define WM8995_WSEQ_DELAY108_SHIFT 0 /* WSEQ_DELAY108 - [3:0] */ -#define WM8995_WSEQ_DELAY108_WIDTH 4 /* WSEQ_DELAY108 - [3:0] */ - -/* - * R12724 (0x31B4) - Write Sequencer 436 - */ -#define WM8995_WSEQ_ADDR109_MASK 0x3FFF /* WSEQ_ADDR109 - [13:0] */ -#define WM8995_WSEQ_ADDR109_SHIFT 0 /* WSEQ_ADDR109 - [13:0] */ -#define WM8995_WSEQ_ADDR109_WIDTH 14 /* WSEQ_ADDR109 - [13:0] */ - -/* - * R12725 (0x31B5) - Write Sequencer 437 - */ -#define WM8995_WSEQ_DATA109_MASK 0x00FF /* WSEQ_DATA109 - [7:0] */ -#define WM8995_WSEQ_DATA109_SHIFT 0 /* WSEQ_DATA109 - [7:0] */ -#define WM8995_WSEQ_DATA109_WIDTH 8 /* WSEQ_DATA109 - [7:0] */ - -/* - * R12726 (0x31B6) - Write Sequencer 438 - */ -#define WM8995_WSEQ_DATA_WIDTH109_MASK 0x0700 /* WSEQ_DATA_WIDTH109 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH109_SHIFT 8 /* WSEQ_DATA_WIDTH109 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH109_WIDTH 3 /* WSEQ_DATA_WIDTH109 - [10:8] */ -#define WM8995_WSEQ_DATA_START109_MASK 0x000F /* WSEQ_DATA_START109 - [3:0] */ -#define WM8995_WSEQ_DATA_START109_SHIFT 0 /* WSEQ_DATA_START109 - [3:0] */ -#define WM8995_WSEQ_DATA_START109_WIDTH 4 /* WSEQ_DATA_START109 - [3:0] */ - -/* - * R12727 (0x31B7) - Write Sequencer 439 - */ -#define WM8995_WSEQ_EOS109 0x0100 /* WSEQ_EOS109 */ -#define WM8995_WSEQ_EOS109_MASK 0x0100 /* WSEQ_EOS109 */ -#define WM8995_WSEQ_EOS109_SHIFT 8 /* WSEQ_EOS109 */ -#define WM8995_WSEQ_EOS109_WIDTH 1 /* WSEQ_EOS109 */ -#define WM8995_WSEQ_DELAY109_MASK 0x000F /* WSEQ_DELAY109 - [3:0] */ -#define WM8995_WSEQ_DELAY109_SHIFT 0 /* WSEQ_DELAY109 - [3:0] */ -#define WM8995_WSEQ_DELAY109_WIDTH 4 /* WSEQ_DELAY109 - [3:0] */ - -/* - * R12728 (0x31B8) - Write Sequencer 440 - */ -#define WM8995_WSEQ_ADDR110_MASK 0x3FFF /* WSEQ_ADDR110 - [13:0] */ -#define WM8995_WSEQ_ADDR110_SHIFT 0 /* WSEQ_ADDR110 - [13:0] */ -#define WM8995_WSEQ_ADDR110_WIDTH 14 /* WSEQ_ADDR110 - [13:0] */ - -/* - * R12729 (0x31B9) - Write Sequencer 441 - */ -#define WM8995_WSEQ_DATA110_MASK 0x00FF /* WSEQ_DATA110 - [7:0] */ -#define WM8995_WSEQ_DATA110_SHIFT 0 /* WSEQ_DATA110 - [7:0] */ -#define WM8995_WSEQ_DATA110_WIDTH 8 /* WSEQ_DATA110 - [7:0] */ - -/* - * R12730 (0x31BA) - Write Sequencer 442 - */ -#define WM8995_WSEQ_DATA_WIDTH110_MASK 0x0700 /* WSEQ_DATA_WIDTH110 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH110_SHIFT 8 /* WSEQ_DATA_WIDTH110 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH110_WIDTH 3 /* WSEQ_DATA_WIDTH110 - [10:8] */ -#define WM8995_WSEQ_DATA_START110_MASK 0x000F /* WSEQ_DATA_START110 - [3:0] */ -#define WM8995_WSEQ_DATA_START110_SHIFT 0 /* WSEQ_DATA_START110 - [3:0] */ -#define WM8995_WSEQ_DATA_START110_WIDTH 4 /* WSEQ_DATA_START110 - [3:0] */ - -/* - * R12731 (0x31BB) - Write Sequencer 443 - */ -#define WM8995_WSEQ_EOS110 0x0100 /* WSEQ_EOS110 */ -#define WM8995_WSEQ_EOS110_MASK 0x0100 /* WSEQ_EOS110 */ -#define WM8995_WSEQ_EOS110_SHIFT 8 /* WSEQ_EOS110 */ -#define WM8995_WSEQ_EOS110_WIDTH 1 /* WSEQ_EOS110 */ -#define WM8995_WSEQ_DELAY110_MASK 0x000F /* WSEQ_DELAY110 - [3:0] */ -#define WM8995_WSEQ_DELAY110_SHIFT 0 /* WSEQ_DELAY110 - [3:0] */ -#define WM8995_WSEQ_DELAY110_WIDTH 4 /* WSEQ_DELAY110 - [3:0] */ - -/* - * R12732 (0x31BC) - Write Sequencer 444 - */ -#define WM8995_WSEQ_ADDR111_MASK 0x3FFF /* WSEQ_ADDR111 - [13:0] */ -#define WM8995_WSEQ_ADDR111_SHIFT 0 /* WSEQ_ADDR111 - [13:0] */ -#define WM8995_WSEQ_ADDR111_WIDTH 14 /* WSEQ_ADDR111 - [13:0] */ - -/* - * R12733 (0x31BD) - Write Sequencer 445 - */ -#define WM8995_WSEQ_DATA111_MASK 0x00FF /* WSEQ_DATA111 - [7:0] */ -#define WM8995_WSEQ_DATA111_SHIFT 0 /* WSEQ_DATA111 - [7:0] */ -#define WM8995_WSEQ_DATA111_WIDTH 8 /* WSEQ_DATA111 - [7:0] */ - -/* - * R12734 (0x31BE) - Write Sequencer 446 - */ -#define WM8995_WSEQ_DATA_WIDTH111_MASK 0x0700 /* WSEQ_DATA_WIDTH111 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH111_SHIFT 8 /* WSEQ_DATA_WIDTH111 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH111_WIDTH 3 /* WSEQ_DATA_WIDTH111 - [10:8] */ -#define WM8995_WSEQ_DATA_START111_MASK 0x000F /* WSEQ_DATA_START111 - [3:0] */ -#define WM8995_WSEQ_DATA_START111_SHIFT 0 /* WSEQ_DATA_START111 - [3:0] */ -#define WM8995_WSEQ_DATA_START111_WIDTH 4 /* WSEQ_DATA_START111 - [3:0] */ - -/* - * R12735 (0x31BF) - Write Sequencer 447 - */ -#define WM8995_WSEQ_EOS111 0x0100 /* WSEQ_EOS111 */ -#define WM8995_WSEQ_EOS111_MASK 0x0100 /* WSEQ_EOS111 */ -#define WM8995_WSEQ_EOS111_SHIFT 8 /* WSEQ_EOS111 */ -#define WM8995_WSEQ_EOS111_WIDTH 1 /* WSEQ_EOS111 */ -#define WM8995_WSEQ_DELAY111_MASK 0x000F /* WSEQ_DELAY111 - [3:0] */ -#define WM8995_WSEQ_DELAY111_SHIFT 0 /* WSEQ_DELAY111 - [3:0] */ -#define WM8995_WSEQ_DELAY111_WIDTH 4 /* WSEQ_DELAY111 - [3:0] */ - -/* - * R12736 (0x31C0) - Write Sequencer 448 - */ -#define WM8995_WSEQ_ADDR112_MASK 0x3FFF /* WSEQ_ADDR112 - [13:0] */ -#define WM8995_WSEQ_ADDR112_SHIFT 0 /* WSEQ_ADDR112 - [13:0] */ -#define WM8995_WSEQ_ADDR112_WIDTH 14 /* WSEQ_ADDR112 - [13:0] */ - -/* - * R12737 (0x31C1) - Write Sequencer 449 - */ -#define WM8995_WSEQ_DATA112_MASK 0x00FF /* WSEQ_DATA112 - [7:0] */ -#define WM8995_WSEQ_DATA112_SHIFT 0 /* WSEQ_DATA112 - [7:0] */ -#define WM8995_WSEQ_DATA112_WIDTH 8 /* WSEQ_DATA112 - [7:0] */ - -/* - * R12738 (0x31C2) - Write Sequencer 450 - */ -#define WM8995_WSEQ_DATA_WIDTH112_MASK 0x0700 /* WSEQ_DATA_WIDTH112 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH112_SHIFT 8 /* WSEQ_DATA_WIDTH112 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH112_WIDTH 3 /* WSEQ_DATA_WIDTH112 - [10:8] */ -#define WM8995_WSEQ_DATA_START112_MASK 0x000F /* WSEQ_DATA_START112 - [3:0] */ -#define WM8995_WSEQ_DATA_START112_SHIFT 0 /* WSEQ_DATA_START112 - [3:0] */ -#define WM8995_WSEQ_DATA_START112_WIDTH 4 /* WSEQ_DATA_START112 - [3:0] */ - -/* - * R12739 (0x31C3) - Write Sequencer 451 - */ -#define WM8995_WSEQ_EOS112 0x0100 /* WSEQ_EOS112 */ -#define WM8995_WSEQ_EOS112_MASK 0x0100 /* WSEQ_EOS112 */ -#define WM8995_WSEQ_EOS112_SHIFT 8 /* WSEQ_EOS112 */ -#define WM8995_WSEQ_EOS112_WIDTH 1 /* WSEQ_EOS112 */ -#define WM8995_WSEQ_DELAY112_MASK 0x000F /* WSEQ_DELAY112 - [3:0] */ -#define WM8995_WSEQ_DELAY112_SHIFT 0 /* WSEQ_DELAY112 - [3:0] */ -#define WM8995_WSEQ_DELAY112_WIDTH 4 /* WSEQ_DELAY112 - [3:0] */ - -/* - * R12740 (0x31C4) - Write Sequencer 452 - */ -#define WM8995_WSEQ_ADDR113_MASK 0x3FFF /* WSEQ_ADDR113 - [13:0] */ -#define WM8995_WSEQ_ADDR113_SHIFT 0 /* WSEQ_ADDR113 - [13:0] */ -#define WM8995_WSEQ_ADDR113_WIDTH 14 /* WSEQ_ADDR113 - [13:0] */ - -/* - * R12741 (0x31C5) - Write Sequencer 453 - */ -#define WM8995_WSEQ_DATA113_MASK 0x00FF /* WSEQ_DATA113 - [7:0] */ -#define WM8995_WSEQ_DATA113_SHIFT 0 /* WSEQ_DATA113 - [7:0] */ -#define WM8995_WSEQ_DATA113_WIDTH 8 /* WSEQ_DATA113 - [7:0] */ - -/* - * R12742 (0x31C6) - Write Sequencer 454 - */ -#define WM8995_WSEQ_DATA_WIDTH113_MASK 0x0700 /* WSEQ_DATA_WIDTH113 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH113_SHIFT 8 /* WSEQ_DATA_WIDTH113 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH113_WIDTH 3 /* WSEQ_DATA_WIDTH113 - [10:8] */ -#define WM8995_WSEQ_DATA_START113_MASK 0x000F /* WSEQ_DATA_START113 - [3:0] */ -#define WM8995_WSEQ_DATA_START113_SHIFT 0 /* WSEQ_DATA_START113 - [3:0] */ -#define WM8995_WSEQ_DATA_START113_WIDTH 4 /* WSEQ_DATA_START113 - [3:0] */ - -/* - * R12743 (0x31C7) - Write Sequencer 455 - */ -#define WM8995_WSEQ_EOS113 0x0100 /* WSEQ_EOS113 */ -#define WM8995_WSEQ_EOS113_MASK 0x0100 /* WSEQ_EOS113 */ -#define WM8995_WSEQ_EOS113_SHIFT 8 /* WSEQ_EOS113 */ -#define WM8995_WSEQ_EOS113_WIDTH 1 /* WSEQ_EOS113 */ -#define WM8995_WSEQ_DELAY113_MASK 0x000F /* WSEQ_DELAY113 - [3:0] */ -#define WM8995_WSEQ_DELAY113_SHIFT 0 /* WSEQ_DELAY113 - [3:0] */ -#define WM8995_WSEQ_DELAY113_WIDTH 4 /* WSEQ_DELAY113 - [3:0] */ - -/* - * R12744 (0x31C8) - Write Sequencer 456 - */ -#define WM8995_WSEQ_ADDR114_MASK 0x3FFF /* WSEQ_ADDR114 - [13:0] */ -#define WM8995_WSEQ_ADDR114_SHIFT 0 /* WSEQ_ADDR114 - [13:0] */ -#define WM8995_WSEQ_ADDR114_WIDTH 14 /* WSEQ_ADDR114 - [13:0] */ - -/* - * R12745 (0x31C9) - Write Sequencer 457 - */ -#define WM8995_WSEQ_DATA114_MASK 0x00FF /* WSEQ_DATA114 - [7:0] */ -#define WM8995_WSEQ_DATA114_SHIFT 0 /* WSEQ_DATA114 - [7:0] */ -#define WM8995_WSEQ_DATA114_WIDTH 8 /* WSEQ_DATA114 - [7:0] */ - -/* - * R12746 (0x31CA) - Write Sequencer 458 - */ -#define WM8995_WSEQ_DATA_WIDTH114_MASK 0x0700 /* WSEQ_DATA_WIDTH114 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH114_SHIFT 8 /* WSEQ_DATA_WIDTH114 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH114_WIDTH 3 /* WSEQ_DATA_WIDTH114 - [10:8] */ -#define WM8995_WSEQ_DATA_START114_MASK 0x000F /* WSEQ_DATA_START114 - [3:0] */ -#define WM8995_WSEQ_DATA_START114_SHIFT 0 /* WSEQ_DATA_START114 - [3:0] */ -#define WM8995_WSEQ_DATA_START114_WIDTH 4 /* WSEQ_DATA_START114 - [3:0] */ - -/* - * R12747 (0x31CB) - Write Sequencer 459 - */ -#define WM8995_WSEQ_EOS114 0x0100 /* WSEQ_EOS114 */ -#define WM8995_WSEQ_EOS114_MASK 0x0100 /* WSEQ_EOS114 */ -#define WM8995_WSEQ_EOS114_SHIFT 8 /* WSEQ_EOS114 */ -#define WM8995_WSEQ_EOS114_WIDTH 1 /* WSEQ_EOS114 */ -#define WM8995_WSEQ_DELAY114_MASK 0x000F /* WSEQ_DELAY114 - [3:0] */ -#define WM8995_WSEQ_DELAY114_SHIFT 0 /* WSEQ_DELAY114 - [3:0] */ -#define WM8995_WSEQ_DELAY114_WIDTH 4 /* WSEQ_DELAY114 - [3:0] */ - -/* - * R12748 (0x31CC) - Write Sequencer 460 - */ -#define WM8995_WSEQ_ADDR115_MASK 0x3FFF /* WSEQ_ADDR115 - [13:0] */ -#define WM8995_WSEQ_ADDR115_SHIFT 0 /* WSEQ_ADDR115 - [13:0] */ -#define WM8995_WSEQ_ADDR115_WIDTH 14 /* WSEQ_ADDR115 - [13:0] */ - -/* - * R12749 (0x31CD) - Write Sequencer 461 - */ -#define WM8995_WSEQ_DATA115_MASK 0x00FF /* WSEQ_DATA115 - [7:0] */ -#define WM8995_WSEQ_DATA115_SHIFT 0 /* WSEQ_DATA115 - [7:0] */ -#define WM8995_WSEQ_DATA115_WIDTH 8 /* WSEQ_DATA115 - [7:0] */ - -/* - * R12750 (0x31CE) - Write Sequencer 462 - */ -#define WM8995_WSEQ_DATA_WIDTH115_MASK 0x0700 /* WSEQ_DATA_WIDTH115 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH115_SHIFT 8 /* WSEQ_DATA_WIDTH115 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH115_WIDTH 3 /* WSEQ_DATA_WIDTH115 - [10:8] */ -#define WM8995_WSEQ_DATA_START115_MASK 0x000F /* WSEQ_DATA_START115 - [3:0] */ -#define WM8995_WSEQ_DATA_START115_SHIFT 0 /* WSEQ_DATA_START115 - [3:0] */ -#define WM8995_WSEQ_DATA_START115_WIDTH 4 /* WSEQ_DATA_START115 - [3:0] */ - -/* - * R12751 (0x31CF) - Write Sequencer 463 - */ -#define WM8995_WSEQ_EOS115 0x0100 /* WSEQ_EOS115 */ -#define WM8995_WSEQ_EOS115_MASK 0x0100 /* WSEQ_EOS115 */ -#define WM8995_WSEQ_EOS115_SHIFT 8 /* WSEQ_EOS115 */ -#define WM8995_WSEQ_EOS115_WIDTH 1 /* WSEQ_EOS115 */ -#define WM8995_WSEQ_DELAY115_MASK 0x000F /* WSEQ_DELAY115 - [3:0] */ -#define WM8995_WSEQ_DELAY115_SHIFT 0 /* WSEQ_DELAY115 - [3:0] */ -#define WM8995_WSEQ_DELAY115_WIDTH 4 /* WSEQ_DELAY115 - [3:0] */ - -/* - * R12752 (0x31D0) - Write Sequencer 464 - */ -#define WM8995_WSEQ_ADDR116_MASK 0x3FFF /* WSEQ_ADDR116 - [13:0] */ -#define WM8995_WSEQ_ADDR116_SHIFT 0 /* WSEQ_ADDR116 - [13:0] */ -#define WM8995_WSEQ_ADDR116_WIDTH 14 /* WSEQ_ADDR116 - [13:0] */ - -/* - * R12753 (0x31D1) - Write Sequencer 465 - */ -#define WM8995_WSEQ_DATA116_MASK 0x00FF /* WSEQ_DATA116 - [7:0] */ -#define WM8995_WSEQ_DATA116_SHIFT 0 /* WSEQ_DATA116 - [7:0] */ -#define WM8995_WSEQ_DATA116_WIDTH 8 /* WSEQ_DATA116 - [7:0] */ - -/* - * R12754 (0x31D2) - Write Sequencer 466 - */ -#define WM8995_WSEQ_DATA_WIDTH116_MASK 0x0700 /* WSEQ_DATA_WIDTH116 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH116_SHIFT 8 /* WSEQ_DATA_WIDTH116 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH116_WIDTH 3 /* WSEQ_DATA_WIDTH116 - [10:8] */ -#define WM8995_WSEQ_DATA_START116_MASK 0x000F /* WSEQ_DATA_START116 - [3:0] */ -#define WM8995_WSEQ_DATA_START116_SHIFT 0 /* WSEQ_DATA_START116 - [3:0] */ -#define WM8995_WSEQ_DATA_START116_WIDTH 4 /* WSEQ_DATA_START116 - [3:0] */ - -/* - * R12755 (0x31D3) - Write Sequencer 467 - */ -#define WM8995_WSEQ_EOS116 0x0100 /* WSEQ_EOS116 */ -#define WM8995_WSEQ_EOS116_MASK 0x0100 /* WSEQ_EOS116 */ -#define WM8995_WSEQ_EOS116_SHIFT 8 /* WSEQ_EOS116 */ -#define WM8995_WSEQ_EOS116_WIDTH 1 /* WSEQ_EOS116 */ -#define WM8995_WSEQ_DELAY116_MASK 0x000F /* WSEQ_DELAY116 - [3:0] */ -#define WM8995_WSEQ_DELAY116_SHIFT 0 /* WSEQ_DELAY116 - [3:0] */ -#define WM8995_WSEQ_DELAY116_WIDTH 4 /* WSEQ_DELAY116 - [3:0] */ - -/* - * R12756 (0x31D4) - Write Sequencer 468 - */ -#define WM8995_WSEQ_ADDR117_MASK 0x3FFF /* WSEQ_ADDR117 - [13:0] */ -#define WM8995_WSEQ_ADDR117_SHIFT 0 /* WSEQ_ADDR117 - [13:0] */ -#define WM8995_WSEQ_ADDR117_WIDTH 14 /* WSEQ_ADDR117 - [13:0] */ - -/* - * R12757 (0x31D5) - Write Sequencer 469 - */ -#define WM8995_WSEQ_DATA117_MASK 0x00FF /* WSEQ_DATA117 - [7:0] */ -#define WM8995_WSEQ_DATA117_SHIFT 0 /* WSEQ_DATA117 - [7:0] */ -#define WM8995_WSEQ_DATA117_WIDTH 8 /* WSEQ_DATA117 - [7:0] */ - -/* - * R12758 (0x31D6) - Write Sequencer 470 - */ -#define WM8995_WSEQ_DATA_WIDTH117_MASK 0x0700 /* WSEQ_DATA_WIDTH117 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH117_SHIFT 8 /* WSEQ_DATA_WIDTH117 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH117_WIDTH 3 /* WSEQ_DATA_WIDTH117 - [10:8] */ -#define WM8995_WSEQ_DATA_START117_MASK 0x000F /* WSEQ_DATA_START117 - [3:0] */ -#define WM8995_WSEQ_DATA_START117_SHIFT 0 /* WSEQ_DATA_START117 - [3:0] */ -#define WM8995_WSEQ_DATA_START117_WIDTH 4 /* WSEQ_DATA_START117 - [3:0] */ - -/* - * R12759 (0x31D7) - Write Sequencer 471 - */ -#define WM8995_WSEQ_EOS117 0x0100 /* WSEQ_EOS117 */ -#define WM8995_WSEQ_EOS117_MASK 0x0100 /* WSEQ_EOS117 */ -#define WM8995_WSEQ_EOS117_SHIFT 8 /* WSEQ_EOS117 */ -#define WM8995_WSEQ_EOS117_WIDTH 1 /* WSEQ_EOS117 */ -#define WM8995_WSEQ_DELAY117_MASK 0x000F /* WSEQ_DELAY117 - [3:0] */ -#define WM8995_WSEQ_DELAY117_SHIFT 0 /* WSEQ_DELAY117 - [3:0] */ -#define WM8995_WSEQ_DELAY117_WIDTH 4 /* WSEQ_DELAY117 - [3:0] */ - -/* - * R12760 (0x31D8) - Write Sequencer 472 - */ -#define WM8995_WSEQ_ADDR118_MASK 0x3FFF /* WSEQ_ADDR118 - [13:0] */ -#define WM8995_WSEQ_ADDR118_SHIFT 0 /* WSEQ_ADDR118 - [13:0] */ -#define WM8995_WSEQ_ADDR118_WIDTH 14 /* WSEQ_ADDR118 - [13:0] */ - -/* - * R12761 (0x31D9) - Write Sequencer 473 - */ -#define WM8995_WSEQ_DATA118_MASK 0x00FF /* WSEQ_DATA118 - [7:0] */ -#define WM8995_WSEQ_DATA118_SHIFT 0 /* WSEQ_DATA118 - [7:0] */ -#define WM8995_WSEQ_DATA118_WIDTH 8 /* WSEQ_DATA118 - [7:0] */ - -/* - * R12762 (0x31DA) - Write Sequencer 474 - */ -#define WM8995_WSEQ_DATA_WIDTH118_MASK 0x0700 /* WSEQ_DATA_WIDTH118 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH118_SHIFT 8 /* WSEQ_DATA_WIDTH118 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH118_WIDTH 3 /* WSEQ_DATA_WIDTH118 - [10:8] */ -#define WM8995_WSEQ_DATA_START118_MASK 0x000F /* WSEQ_DATA_START118 - [3:0] */ -#define WM8995_WSEQ_DATA_START118_SHIFT 0 /* WSEQ_DATA_START118 - [3:0] */ -#define WM8995_WSEQ_DATA_START118_WIDTH 4 /* WSEQ_DATA_START118 - [3:0] */ - -/* - * R12763 (0x31DB) - Write Sequencer 475 - */ -#define WM8995_WSEQ_EOS118 0x0100 /* WSEQ_EOS118 */ -#define WM8995_WSEQ_EOS118_MASK 0x0100 /* WSEQ_EOS118 */ -#define WM8995_WSEQ_EOS118_SHIFT 8 /* WSEQ_EOS118 */ -#define WM8995_WSEQ_EOS118_WIDTH 1 /* WSEQ_EOS118 */ -#define WM8995_WSEQ_DELAY118_MASK 0x000F /* WSEQ_DELAY118 - [3:0] */ -#define WM8995_WSEQ_DELAY118_SHIFT 0 /* WSEQ_DELAY118 - [3:0] */ -#define WM8995_WSEQ_DELAY118_WIDTH 4 /* WSEQ_DELAY118 - [3:0] */ - -/* - * R12764 (0x31DC) - Write Sequencer 476 - */ -#define WM8995_WSEQ_ADDR119_MASK 0x3FFF /* WSEQ_ADDR119 - [13:0] */ -#define WM8995_WSEQ_ADDR119_SHIFT 0 /* WSEQ_ADDR119 - [13:0] */ -#define WM8995_WSEQ_ADDR119_WIDTH 14 /* WSEQ_ADDR119 - [13:0] */ - -/* - * R12765 (0x31DD) - Write Sequencer 477 - */ -#define WM8995_WSEQ_DATA119_MASK 0x00FF /* WSEQ_DATA119 - [7:0] */ -#define WM8995_WSEQ_DATA119_SHIFT 0 /* WSEQ_DATA119 - [7:0] */ -#define WM8995_WSEQ_DATA119_WIDTH 8 /* WSEQ_DATA119 - [7:0] */ - -/* - * R12766 (0x31DE) - Write Sequencer 478 - */ -#define WM8995_WSEQ_DATA_WIDTH119_MASK 0x0700 /* WSEQ_DATA_WIDTH119 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH119_SHIFT 8 /* WSEQ_DATA_WIDTH119 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH119_WIDTH 3 /* WSEQ_DATA_WIDTH119 - [10:8] */ -#define WM8995_WSEQ_DATA_START119_MASK 0x000F /* WSEQ_DATA_START119 - [3:0] */ -#define WM8995_WSEQ_DATA_START119_SHIFT 0 /* WSEQ_DATA_START119 - [3:0] */ -#define WM8995_WSEQ_DATA_START119_WIDTH 4 /* WSEQ_DATA_START119 - [3:0] */ - -/* - * R12767 (0x31DF) - Write Sequencer 479 - */ -#define WM8995_WSEQ_EOS119 0x0100 /* WSEQ_EOS119 */ -#define WM8995_WSEQ_EOS119_MASK 0x0100 /* WSEQ_EOS119 */ -#define WM8995_WSEQ_EOS119_SHIFT 8 /* WSEQ_EOS119 */ -#define WM8995_WSEQ_EOS119_WIDTH 1 /* WSEQ_EOS119 */ -#define WM8995_WSEQ_DELAY119_MASK 0x000F /* WSEQ_DELAY119 - [3:0] */ -#define WM8995_WSEQ_DELAY119_SHIFT 0 /* WSEQ_DELAY119 - [3:0] */ -#define WM8995_WSEQ_DELAY119_WIDTH 4 /* WSEQ_DELAY119 - [3:0] */ - -/* - * R12768 (0x31E0) - Write Sequencer 480 - */ -#define WM8995_WSEQ_ADDR120_MASK 0x3FFF /* WSEQ_ADDR120 - [13:0] */ -#define WM8995_WSEQ_ADDR120_SHIFT 0 /* WSEQ_ADDR120 - [13:0] */ -#define WM8995_WSEQ_ADDR120_WIDTH 14 /* WSEQ_ADDR120 - [13:0] */ - -/* - * R12769 (0x31E1) - Write Sequencer 481 - */ -#define WM8995_WSEQ_DATA120_MASK 0x00FF /* WSEQ_DATA120 - [7:0] */ -#define WM8995_WSEQ_DATA120_SHIFT 0 /* WSEQ_DATA120 - [7:0] */ -#define WM8995_WSEQ_DATA120_WIDTH 8 /* WSEQ_DATA120 - [7:0] */ - -/* - * R12770 (0x31E2) - Write Sequencer 482 - */ -#define WM8995_WSEQ_DATA_WIDTH120_MASK 0x0700 /* WSEQ_DATA_WIDTH120 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH120_SHIFT 8 /* WSEQ_DATA_WIDTH120 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH120_WIDTH 3 /* WSEQ_DATA_WIDTH120 - [10:8] */ -#define WM8995_WSEQ_DATA_START120_MASK 0x000F /* WSEQ_DATA_START120 - [3:0] */ -#define WM8995_WSEQ_DATA_START120_SHIFT 0 /* WSEQ_DATA_START120 - [3:0] */ -#define WM8995_WSEQ_DATA_START120_WIDTH 4 /* WSEQ_DATA_START120 - [3:0] */ - -/* - * R12771 (0x31E3) - Write Sequencer 483 - */ -#define WM8995_WSEQ_EOS120 0x0100 /* WSEQ_EOS120 */ -#define WM8995_WSEQ_EOS120_MASK 0x0100 /* WSEQ_EOS120 */ -#define WM8995_WSEQ_EOS120_SHIFT 8 /* WSEQ_EOS120 */ -#define WM8995_WSEQ_EOS120_WIDTH 1 /* WSEQ_EOS120 */ -#define WM8995_WSEQ_DELAY120_MASK 0x000F /* WSEQ_DELAY120 - [3:0] */ -#define WM8995_WSEQ_DELAY120_SHIFT 0 /* WSEQ_DELAY120 - [3:0] */ -#define WM8995_WSEQ_DELAY120_WIDTH 4 /* WSEQ_DELAY120 - [3:0] */ - -/* - * R12772 (0x31E4) - Write Sequencer 484 - */ -#define WM8995_WSEQ_ADDR121_MASK 0x3FFF /* WSEQ_ADDR121 - [13:0] */ -#define WM8995_WSEQ_ADDR121_SHIFT 0 /* WSEQ_ADDR121 - [13:0] */ -#define WM8995_WSEQ_ADDR121_WIDTH 14 /* WSEQ_ADDR121 - [13:0] */ - -/* - * R12773 (0x31E5) - Write Sequencer 485 - */ -#define WM8995_WSEQ_DATA121_MASK 0x00FF /* WSEQ_DATA121 - [7:0] */ -#define WM8995_WSEQ_DATA121_SHIFT 0 /* WSEQ_DATA121 - [7:0] */ -#define WM8995_WSEQ_DATA121_WIDTH 8 /* WSEQ_DATA121 - [7:0] */ - -/* - * R12774 (0x31E6) - Write Sequencer 486 - */ -#define WM8995_WSEQ_DATA_WIDTH121_MASK 0x0700 /* WSEQ_DATA_WIDTH121 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH121_SHIFT 8 /* WSEQ_DATA_WIDTH121 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH121_WIDTH 3 /* WSEQ_DATA_WIDTH121 - [10:8] */ -#define WM8995_WSEQ_DATA_START121_MASK 0x000F /* WSEQ_DATA_START121 - [3:0] */ -#define WM8995_WSEQ_DATA_START121_SHIFT 0 /* WSEQ_DATA_START121 - [3:0] */ -#define WM8995_WSEQ_DATA_START121_WIDTH 4 /* WSEQ_DATA_START121 - [3:0] */ - -/* - * R12775 (0x31E7) - Write Sequencer 487 - */ -#define WM8995_WSEQ_EOS121 0x0100 /* WSEQ_EOS121 */ -#define WM8995_WSEQ_EOS121_MASK 0x0100 /* WSEQ_EOS121 */ -#define WM8995_WSEQ_EOS121_SHIFT 8 /* WSEQ_EOS121 */ -#define WM8995_WSEQ_EOS121_WIDTH 1 /* WSEQ_EOS121 */ -#define WM8995_WSEQ_DELAY121_MASK 0x000F /* WSEQ_DELAY121 - [3:0] */ -#define WM8995_WSEQ_DELAY121_SHIFT 0 /* WSEQ_DELAY121 - [3:0] */ -#define WM8995_WSEQ_DELAY121_WIDTH 4 /* WSEQ_DELAY121 - [3:0] */ - -/* - * R12776 (0x31E8) - Write Sequencer 488 - */ -#define WM8995_WSEQ_ADDR122_MASK 0x3FFF /* WSEQ_ADDR122 - [13:0] */ -#define WM8995_WSEQ_ADDR122_SHIFT 0 /* WSEQ_ADDR122 - [13:0] */ -#define WM8995_WSEQ_ADDR122_WIDTH 14 /* WSEQ_ADDR122 - [13:0] */ - -/* - * R12777 (0x31E9) - Write Sequencer 489 - */ -#define WM8995_WSEQ_DATA122_MASK 0x00FF /* WSEQ_DATA122 - [7:0] */ -#define WM8995_WSEQ_DATA122_SHIFT 0 /* WSEQ_DATA122 - [7:0] */ -#define WM8995_WSEQ_DATA122_WIDTH 8 /* WSEQ_DATA122 - [7:0] */ - -/* - * R12778 (0x31EA) - Write Sequencer 490 - */ -#define WM8995_WSEQ_DATA_WIDTH122_MASK 0x0700 /* WSEQ_DATA_WIDTH122 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH122_SHIFT 8 /* WSEQ_DATA_WIDTH122 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH122_WIDTH 3 /* WSEQ_DATA_WIDTH122 - [10:8] */ -#define WM8995_WSEQ_DATA_START122_MASK 0x000F /* WSEQ_DATA_START122 - [3:0] */ -#define WM8995_WSEQ_DATA_START122_SHIFT 0 /* WSEQ_DATA_START122 - [3:0] */ -#define WM8995_WSEQ_DATA_START122_WIDTH 4 /* WSEQ_DATA_START122 - [3:0] */ - -/* - * R12779 (0x31EB) - Write Sequencer 491 - */ -#define WM8995_WSEQ_EOS122 0x0100 /* WSEQ_EOS122 */ -#define WM8995_WSEQ_EOS122_MASK 0x0100 /* WSEQ_EOS122 */ -#define WM8995_WSEQ_EOS122_SHIFT 8 /* WSEQ_EOS122 */ -#define WM8995_WSEQ_EOS122_WIDTH 1 /* WSEQ_EOS122 */ -#define WM8995_WSEQ_DELAY122_MASK 0x000F /* WSEQ_DELAY122 - [3:0] */ -#define WM8995_WSEQ_DELAY122_SHIFT 0 /* WSEQ_DELAY122 - [3:0] */ -#define WM8995_WSEQ_DELAY122_WIDTH 4 /* WSEQ_DELAY122 - [3:0] */ - -/* - * R12780 (0x31EC) - Write Sequencer 492 - */ -#define WM8995_WSEQ_ADDR123_MASK 0x3FFF /* WSEQ_ADDR123 - [13:0] */ -#define WM8995_WSEQ_ADDR123_SHIFT 0 /* WSEQ_ADDR123 - [13:0] */ -#define WM8995_WSEQ_ADDR123_WIDTH 14 /* WSEQ_ADDR123 - [13:0] */ - -/* - * R12781 (0x31ED) - Write Sequencer 493 - */ -#define WM8995_WSEQ_DATA123_MASK 0x00FF /* WSEQ_DATA123 - [7:0] */ -#define WM8995_WSEQ_DATA123_SHIFT 0 /* WSEQ_DATA123 - [7:0] */ -#define WM8995_WSEQ_DATA123_WIDTH 8 /* WSEQ_DATA123 - [7:0] */ - -/* - * R12782 (0x31EE) - Write Sequencer 494 - */ -#define WM8995_WSEQ_DATA_WIDTH123_MASK 0x0700 /* WSEQ_DATA_WIDTH123 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH123_SHIFT 8 /* WSEQ_DATA_WIDTH123 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH123_WIDTH 3 /* WSEQ_DATA_WIDTH123 - [10:8] */ -#define WM8995_WSEQ_DATA_START123_MASK 0x000F /* WSEQ_DATA_START123 - [3:0] */ -#define WM8995_WSEQ_DATA_START123_SHIFT 0 /* WSEQ_DATA_START123 - [3:0] */ -#define WM8995_WSEQ_DATA_START123_WIDTH 4 /* WSEQ_DATA_START123 - [3:0] */ - -/* - * R12783 (0x31EF) - Write Sequencer 495 - */ -#define WM8995_WSEQ_EOS123 0x0100 /* WSEQ_EOS123 */ -#define WM8995_WSEQ_EOS123_MASK 0x0100 /* WSEQ_EOS123 */ -#define WM8995_WSEQ_EOS123_SHIFT 8 /* WSEQ_EOS123 */ -#define WM8995_WSEQ_EOS123_WIDTH 1 /* WSEQ_EOS123 */ -#define WM8995_WSEQ_DELAY123_MASK 0x000F /* WSEQ_DELAY123 - [3:0] */ -#define WM8995_WSEQ_DELAY123_SHIFT 0 /* WSEQ_DELAY123 - [3:0] */ -#define WM8995_WSEQ_DELAY123_WIDTH 4 /* WSEQ_DELAY123 - [3:0] */ - -/* - * R12784 (0x31F0) - Write Sequencer 496 - */ -#define WM8995_WSEQ_ADDR124_MASK 0x3FFF /* WSEQ_ADDR124 - [13:0] */ -#define WM8995_WSEQ_ADDR124_SHIFT 0 /* WSEQ_ADDR124 - [13:0] */ -#define WM8995_WSEQ_ADDR124_WIDTH 14 /* WSEQ_ADDR124 - [13:0] */ - -/* - * R12785 (0x31F1) - Write Sequencer 497 - */ -#define WM8995_WSEQ_DATA124_MASK 0x00FF /* WSEQ_DATA124 - [7:0] */ -#define WM8995_WSEQ_DATA124_SHIFT 0 /* WSEQ_DATA124 - [7:0] */ -#define WM8995_WSEQ_DATA124_WIDTH 8 /* WSEQ_DATA124 - [7:0] */ - -/* - * R12786 (0x31F2) - Write Sequencer 498 - */ -#define WM8995_WSEQ_DATA_WIDTH124_MASK 0x0700 /* WSEQ_DATA_WIDTH124 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH124_SHIFT 8 /* WSEQ_DATA_WIDTH124 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH124_WIDTH 3 /* WSEQ_DATA_WIDTH124 - [10:8] */ -#define WM8995_WSEQ_DATA_START124_MASK 0x000F /* WSEQ_DATA_START124 - [3:0] */ -#define WM8995_WSEQ_DATA_START124_SHIFT 0 /* WSEQ_DATA_START124 - [3:0] */ -#define WM8995_WSEQ_DATA_START124_WIDTH 4 /* WSEQ_DATA_START124 - [3:0] */ - -/* - * R12787 (0x31F3) - Write Sequencer 499 - */ -#define WM8995_WSEQ_EOS124 0x0100 /* WSEQ_EOS124 */ -#define WM8995_WSEQ_EOS124_MASK 0x0100 /* WSEQ_EOS124 */ -#define WM8995_WSEQ_EOS124_SHIFT 8 /* WSEQ_EOS124 */ -#define WM8995_WSEQ_EOS124_WIDTH 1 /* WSEQ_EOS124 */ -#define WM8995_WSEQ_DELAY124_MASK 0x000F /* WSEQ_DELAY124 - [3:0] */ -#define WM8995_WSEQ_DELAY124_SHIFT 0 /* WSEQ_DELAY124 - [3:0] */ -#define WM8995_WSEQ_DELAY124_WIDTH 4 /* WSEQ_DELAY124 - [3:0] */ - -/* - * R12788 (0x31F4) - Write Sequencer 500 - */ -#define WM8995_WSEQ_ADDR125_MASK 0x3FFF /* WSEQ_ADDR125 - [13:0] */ -#define WM8995_WSEQ_ADDR125_SHIFT 0 /* WSEQ_ADDR125 - [13:0] */ -#define WM8995_WSEQ_ADDR125_WIDTH 14 /* WSEQ_ADDR125 - [13:0] */ - -/* - * R12789 (0x31F5) - Write Sequencer 501 - */ -#define WM8995_WSEQ_DATA125_MASK 0x00FF /* WSEQ_DATA125 - [7:0] */ -#define WM8995_WSEQ_DATA125_SHIFT 0 /* WSEQ_DATA125 - [7:0] */ -#define WM8995_WSEQ_DATA125_WIDTH 8 /* WSEQ_DATA125 - [7:0] */ - -/* - * R12790 (0x31F6) - Write Sequencer 502 - */ -#define WM8995_WSEQ_DATA_WIDTH125_MASK 0x0700 /* WSEQ_DATA_WIDTH125 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH125_SHIFT 8 /* WSEQ_DATA_WIDTH125 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH125_WIDTH 3 /* WSEQ_DATA_WIDTH125 - [10:8] */ -#define WM8995_WSEQ_DATA_START125_MASK 0x000F /* WSEQ_DATA_START125 - [3:0] */ -#define WM8995_WSEQ_DATA_START125_SHIFT 0 /* WSEQ_DATA_START125 - [3:0] */ -#define WM8995_WSEQ_DATA_START125_WIDTH 4 /* WSEQ_DATA_START125 - [3:0] */ - -/* - * R12791 (0x31F7) - Write Sequencer 503 - */ -#define WM8995_WSEQ_EOS125 0x0100 /* WSEQ_EOS125 */ -#define WM8995_WSEQ_EOS125_MASK 0x0100 /* WSEQ_EOS125 */ -#define WM8995_WSEQ_EOS125_SHIFT 8 /* WSEQ_EOS125 */ -#define WM8995_WSEQ_EOS125_WIDTH 1 /* WSEQ_EOS125 */ -#define WM8995_WSEQ_DELAY125_MASK 0x000F /* WSEQ_DELAY125 - [3:0] */ -#define WM8995_WSEQ_DELAY125_SHIFT 0 /* WSEQ_DELAY125 - [3:0] */ -#define WM8995_WSEQ_DELAY125_WIDTH 4 /* WSEQ_DELAY125 - [3:0] */ - -/* - * R12792 (0x31F8) - Write Sequencer 504 - */ -#define WM8995_WSEQ_ADDR126_MASK 0x3FFF /* WSEQ_ADDR126 - [13:0] */ -#define WM8995_WSEQ_ADDR126_SHIFT 0 /* WSEQ_ADDR126 - [13:0] */ -#define WM8995_WSEQ_ADDR126_WIDTH 14 /* WSEQ_ADDR126 - [13:0] */ - -/* - * R12793 (0x31F9) - Write Sequencer 505 - */ -#define WM8995_WSEQ_DATA126_MASK 0x00FF /* WSEQ_DATA126 - [7:0] */ -#define WM8995_WSEQ_DATA126_SHIFT 0 /* WSEQ_DATA126 - [7:0] */ -#define WM8995_WSEQ_DATA126_WIDTH 8 /* WSEQ_DATA126 - [7:0] */ - -/* - * R12794 (0x31FA) - Write Sequencer 506 - */ -#define WM8995_WSEQ_DATA_WIDTH126_MASK 0x0700 /* WSEQ_DATA_WIDTH126 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH126_SHIFT 8 /* WSEQ_DATA_WIDTH126 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH126_WIDTH 3 /* WSEQ_DATA_WIDTH126 - [10:8] */ -#define WM8995_WSEQ_DATA_START126_MASK 0x000F /* WSEQ_DATA_START126 - [3:0] */ -#define WM8995_WSEQ_DATA_START126_SHIFT 0 /* WSEQ_DATA_START126 - [3:0] */ -#define WM8995_WSEQ_DATA_START126_WIDTH 4 /* WSEQ_DATA_START126 - [3:0] */ - -/* - * R12795 (0x31FB) - Write Sequencer 507 - */ -#define WM8995_WSEQ_EOS126 0x0100 /* WSEQ_EOS126 */ -#define WM8995_WSEQ_EOS126_MASK 0x0100 /* WSEQ_EOS126 */ -#define WM8995_WSEQ_EOS126_SHIFT 8 /* WSEQ_EOS126 */ -#define WM8995_WSEQ_EOS126_WIDTH 1 /* WSEQ_EOS126 */ -#define WM8995_WSEQ_DELAY126_MASK 0x000F /* WSEQ_DELAY126 - [3:0] */ -#define WM8995_WSEQ_DELAY126_SHIFT 0 /* WSEQ_DELAY126 - [3:0] */ -#define WM8995_WSEQ_DELAY126_WIDTH 4 /* WSEQ_DELAY126 - [3:0] */ - -/* - * R12796 (0x31FC) - Write Sequencer 508 - */ -#define WM8995_WSEQ_ADDR127_MASK 0x3FFF /* WSEQ_ADDR127 - [13:0] */ -#define WM8995_WSEQ_ADDR127_SHIFT 0 /* WSEQ_ADDR127 - [13:0] */ -#define WM8995_WSEQ_ADDR127_WIDTH 14 /* WSEQ_ADDR127 - [13:0] */ - -/* - * R12797 (0x31FD) - Write Sequencer 509 - */ -#define WM8995_WSEQ_DATA127_MASK 0x00FF /* WSEQ_DATA127 - [7:0] */ -#define WM8995_WSEQ_DATA127_SHIFT 0 /* WSEQ_DATA127 - [7:0] */ -#define WM8995_WSEQ_DATA127_WIDTH 8 /* WSEQ_DATA127 - [7:0] */ - -/* - * R12798 (0x31FE) - Write Sequencer 510 - */ -#define WM8995_WSEQ_DATA_WIDTH127_MASK 0x0700 /* WSEQ_DATA_WIDTH127 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH127_SHIFT 8 /* WSEQ_DATA_WIDTH127 - [10:8] */ -#define WM8995_WSEQ_DATA_WIDTH127_WIDTH 3 /* WSEQ_DATA_WIDTH127 - [10:8] */ -#define WM8995_WSEQ_DATA_START127_MASK 0x000F /* WSEQ_DATA_START127 - [3:0] */ -#define WM8995_WSEQ_DATA_START127_SHIFT 0 /* WSEQ_DATA_START127 - [3:0] */ -#define WM8995_WSEQ_DATA_START127_WIDTH 4 /* WSEQ_DATA_START127 - [3:0] */ - -/* - * R12799 (0x31FF) - Write Sequencer 511 - */ -#define WM8995_WSEQ_EOS127 0x0100 /* WSEQ_EOS127 */ -#define WM8995_WSEQ_EOS127_MASK 0x0100 /* WSEQ_EOS127 */ -#define WM8995_WSEQ_EOS127_SHIFT 8 /* WSEQ_EOS127 */ -#define WM8995_WSEQ_EOS127_WIDTH 1 /* WSEQ_EOS127 */ -#define WM8995_WSEQ_DELAY127_MASK 0x000F /* WSEQ_DELAY127 - [3:0] */ -#define WM8995_WSEQ_DELAY127_SHIFT 0 /* WSEQ_DELAY127 - [3:0] */ -#define WM8995_WSEQ_DELAY127_WIDTH 4 /* WSEQ_DELAY127 - [3:0] */ - #define WM8995_CLASS_W_SWITCH(xname, reg, shift, max, invert) \ { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ .info = snd_soc_info_volsw, \ -- cgit v1.2.3 From 6675bc056790b403d198a173498d377187754142 Mon Sep 17 00:00:00 2001 From: Aaro Koskinen Date: Thu, 25 Nov 2010 23:41:19 +0100 Subject: PM / Runtime: Fix comments to match runtime callback code Commit 05aa55dddb9ee4045c320661068bea78dad6a6e5 changed routines to succeed if the driver handler is not defined. Comments were not updated. Signed-off-by: Aaro Koskinen Signed-off-by: Rafael J. Wysocki --- drivers/base/power/generic_ops.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/base/power/generic_ops.c b/drivers/base/power/generic_ops.c index 81f2c84697f4..3d2c3500069a 100644 --- a/drivers/base/power/generic_ops.c +++ b/drivers/base/power/generic_ops.c @@ -39,7 +39,7 @@ EXPORT_SYMBOL_GPL(pm_generic_runtime_idle); * * If PM operations are defined for the @dev's driver and they include * ->runtime_suspend(), execute it and return its error code. Otherwise, - * return -EINVAL. + * return 0. */ int pm_generic_runtime_suspend(struct device *dev) { @@ -58,7 +58,7 @@ EXPORT_SYMBOL_GPL(pm_generic_runtime_suspend); * * If PM operations are defined for the @dev's driver and they include * ->runtime_resume(), execute it and return its error code. Otherwise, - * return -EINVAL. + * return 0. */ int pm_generic_runtime_resume(struct device *dev) { -- cgit v1.2.3 From 133f1128b2bf178a1976b17c54bd14ce6feb90bf Mon Sep 17 00:00:00 2001 From: Tracey Dent Date: Thu, 25 Nov 2010 23:41:29 +0100 Subject: PM: Use proper ccflag flag in kernel/power/Makefile Use the ccflags-$ flag instead of EXTRA_CFLAGS because EXTRA_CFLAGS is deprecated and should now be switched. According to (documentation/kbuild/makefiles.txt). Signed-off-by: Tracey Dent Signed-off-by: Rafael J. Wysocki --- kernel/power/Makefile | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/kernel/power/Makefile b/kernel/power/Makefile index f9063c6b185d..b75597235d85 100644 --- a/kernel/power/Makefile +++ b/kernel/power/Makefile @@ -1,7 +1,4 @@ - -ifeq ($(CONFIG_PM_DEBUG),y) -EXTRA_CFLAGS += -DDEBUG -endif +ccflags-$(CONFIG_PM_DEBUG) := -DDEBUG obj-$(CONFIG_PM) += main.o obj-$(CONFIG_PM_SLEEP) += console.o -- cgit v1.2.3 From 8cfe400ca54fd1ed96f962bea5f7e20b09b6d69f Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Fri, 26 Nov 2010 23:07:27 +0100 Subject: Freezer: Fix a race during freezing of TASK_STOPPED tasks After calling freeze_task(), try_to_freeze_tasks() see whether the task is stopped or traced and if so, considers it to be frozen; however, nothing guarantees that either the task being frozen sees TIF_FREEZE or the freezer sees TASK_STOPPED -> TASK_RUNNING transition. The task being frozen may wake up and not see TIF_FREEZE while the freezer fails to notice the transition and believes the task is still stopped. This patch fixes the race by making freeze_task() always go through fake_signal_wake_up() for applicable tasks. The function goes through the target task's scheduler lock and thus guarantees that either the target sees TIF_FREEZE or try_to_freeze_task() sees TASK_RUNNING. Signed-off-by: Tejun Heo Signed-off-by: Rafael J. Wysocki --- kernel/freezer.c | 9 +++++++-- kernel/power/process.c | 6 ++++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/kernel/freezer.c b/kernel/freezer.c index bd1d42b17cb2..66ecd2ead215 100644 --- a/kernel/freezer.c +++ b/kernel/freezer.c @@ -104,8 +104,13 @@ bool freeze_task(struct task_struct *p, bool sig_only) } if (should_send_signal(p)) { - if (!signal_pending(p)) - fake_signal_wake_up(p); + fake_signal_wake_up(p); + /* + * fake_signal_wake_up() goes through p's scheduler + * lock and guarantees that TASK_STOPPED/TRACED -> + * TASK_RUNNING transition can't race with task state + * testing in try_to_freeze_tasks(). + */ } else if (sig_only) { return false; } else { diff --git a/kernel/power/process.c b/kernel/power/process.c index e50b4c1b2a0f..eb2c88a9e562 100644 --- a/kernel/power/process.c +++ b/kernel/power/process.c @@ -64,6 +64,12 @@ static int try_to_freeze_tasks(bool sig_only) * perturb a task in TASK_STOPPED or TASK_TRACED. * It is "frozen enough". If the task does wake * up, it will immediately call try_to_freeze. + * + * Because freeze_task() goes through p's + * scheduler lock after setting TIF_FREEZE, it's + * guaranteed that either we see TASK_RUNNING or + * try_to_stop() after schedule() in ptrace/signal + * stop sees TIF_FREEZE. */ if (!task_is_stopped_or_traced(p) && !freezer_should_skip(p)) -- cgit v1.2.3 From 5729c63a51f0f8a351e0f1dc7b3250ebac12c309 Mon Sep 17 00:00:00 2001 From: MyungJoo Ham Date: Fri, 26 Nov 2010 23:07:48 +0100 Subject: PM / Hibernate: hibernation_ops->leave should be checked too Because hibernate calls hibernation_ops->leave() without checking whether hibernation_ops->leave is NULL or not, hiberantion_set_ops should WARN_ON if hibernation_ops->leave is NULL. This patch added one more condition to check hibernation_ops->leave. Signed-off-by: MyungJoo Ham Signed-off-by: Kyungmin Park Acked-by: Pavel Machek Signed-off-by: Rafael J. Wysocki --- kernel/power/hibernate.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c index 048d0b514831..ab2836c25038 100644 --- a/kernel/power/hibernate.c +++ b/kernel/power/hibernate.c @@ -62,7 +62,7 @@ void hibernation_set_ops(struct platform_hibernation_ops *ops) { if (ops && !(ops->begin && ops->end && ops->pre_snapshot && ops->prepare && ops->finish && ops->enter && ops->pre_restore - && ops->restore_cleanup)) { + && ops->restore_cleanup && ops->leave)) { WARN_ON(1); return; } -- cgit v1.2.3 From 5262a47502adcfc3a64403120768f528418a3b79 Mon Sep 17 00:00:00 2001 From: MyungJoo Ham Date: Fri, 26 Nov 2010 23:07:56 +0100 Subject: PM / Hibernate: When failed, in_suspend should be reset When hibernation failed due to an error in swsusp_write() called by hibernate(), it skips calling "power_down()" and returns. When hibernate() is called again (probably after fixing up so that swsusp_write() wouldn't fail again), before "in_suspend = 1" of create_image is called, in_suspend should be 0. However, because hibernate() did not reset "in_suspend" after a failure, it's already 1. This patch fixes such inconsistency of "in_suspend" value. Signed-off-by: MyungJoo Ham Signed-off-by: Kyungmin Park Signed-off-by: Rafael J. Wysocki --- kernel/power/hibernate.c | 1 + 1 file changed, 1 insertion(+) diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c index ab2836c25038..c9a98beffee4 100644 --- a/kernel/power/hibernate.c +++ b/kernel/power/hibernate.c @@ -647,6 +647,7 @@ int hibernate(void) swsusp_free(); if (!error) power_down(); + in_suspend = 0; pm_restore_gfp_mask(); } else { pr_debug("PM: Image restored successfully.\n"); -- cgit v1.2.3 From c7b61de5b7b17f0df34dc7d2f8b9576f8bd36fce Mon Sep 17 00:00:00 2001 From: Alan Stern Date: Wed, 1 Dec 2010 00:14:42 +0100 Subject: PM / Runtime: Add synchronous runtime interface for interrupt handlers (v3) This patch (as1431c) makes the synchronous runtime-PM interface suitable for use in interrupt handlers. Subsystems can call the new pm_runtime_irq_safe() function to tell the PM core that a device's runtime_suspend and runtime_resume callbacks should be invoked with interrupts disabled and the spinlock held. This permits the pm_runtime_get_sync() and the new pm_runtime_put_sync_suspend() routines to be called from within interrupt handlers. When a device is declared irq-safe in this way, the PM core increments the parent's usage count, so the parent will never be runtime suspended. This prevents difficult situations in which an irq-safe device can't resume because it is forced to wait for its non-irq-safe parent. Signed-off-by: Alan Stern Signed-off-by: Rafael J. Wysocki --- Documentation/power/runtime_pm.txt | 31 +++++++++++++++++++++++++ drivers/base/power/runtime.c | 47 ++++++++++++++++++++++++++++++-------- include/linux/pm.h | 1 + include/linux/pm_runtime.h | 7 ++++++ 4 files changed, 77 insertions(+), 9 deletions(-) diff --git a/Documentation/power/runtime_pm.txt b/Documentation/power/runtime_pm.txt index 41cc7b30d7dd..ffe55ffa540a 100644 --- a/Documentation/power/runtime_pm.txt +++ b/Documentation/power/runtime_pm.txt @@ -50,6 +50,15 @@ type's callbacks are not defined) of given device. The bus type, device type and device class callbacks are referred to as subsystem-level callbacks in what follows. +By default, the callbacks are always invoked in process context with interrupts +enabled. However, subsystems can use the pm_runtime_irq_safe() helper function +to tell the PM core that a device's ->runtime_suspend() and ->runtime_resume() +callbacks should be invoked in atomic context with interrupts disabled +(->runtime_idle() is still invoked the default way). This implies that these +callback routines must not block or sleep, but it also means that the +synchronous helper functions listed at the end of Section 4 can be used within +an interrupt handler or in an atomic context. + The subsystem-level suspend callback is _entirely_ _responsible_ for handling the suspend of the device as appropriate, which may, but need not include executing the device driver's own ->runtime_suspend() callback (from the @@ -237,6 +246,10 @@ defined in include/linux/pm.h: Section 8); it may be modified only by the pm_runtime_no_callbacks() helper function + unsigned int irq_safe; + - indicates that the ->runtime_suspend() and ->runtime_resume() callbacks + will be invoked with the spinlock held and interrupts disabled + unsigned int use_autosuspend; - indicates that the device's driver supports delayed autosuspend (see Section 9); it may be modified only by the @@ -344,6 +357,10 @@ drivers/base/power/runtime.c and include/linux/pm_runtime.h: - decrement the device's usage counter; if the result is 0 then run pm_runtime_idle(dev) and return its result + int pm_runtime_put_sync_suspend(struct device *dev); + - decrement the device's usage counter; if the result is 0 then run + pm_runtime_suspend(dev) and return its result + int pm_runtime_put_sync_autosuspend(struct device *dev); - decrement the device's usage counter; if the result is 0 then run pm_runtime_autosuspend(dev) and return its result @@ -397,6 +414,11 @@ drivers/base/power/runtime.c and include/linux/pm_runtime.h: PM attributes from /sys/devices/.../power (or prevent them from being added when the device is registered) + void pm_runtime_irq_safe(struct device *dev); + - set the power.irq_safe flag for the device, causing the runtime-PM + suspend and resume callbacks (but not the idle callback) to be invoked + with interrupts disabled + void pm_runtime_mark_last_busy(struct device *dev); - set the power.last_busy field to the current time @@ -438,6 +460,15 @@ pm_runtime_suspended() pm_runtime_mark_last_busy() pm_runtime_autosuspend_expiration() +If pm_runtime_irq_safe() has been called for a device then the following helper +functions may also be used in interrupt context: + +pm_runtime_suspend() +pm_runtime_autosuspend() +pm_runtime_resume() +pm_runtime_get_sync() +pm_runtime_put_sync_suspend() + 5. Run-time PM Initialization, Device Probing and Removal Initially, the run-time PM is disabled for all devices, which means that the diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c index 02c652be83e7..656493a5e073 100644 --- a/drivers/base/power/runtime.c +++ b/drivers/base/power/runtime.c @@ -250,13 +250,16 @@ static int rpm_callback(int (*cb)(struct device *), struct device *dev) if (!cb) return -ENOSYS; - spin_unlock_irq(&dev->power.lock); + if (dev->power.irq_safe) { + retval = cb(dev); + } else { + spin_unlock_irq(&dev->power.lock); - retval = cb(dev); + retval = cb(dev); - spin_lock_irq(&dev->power.lock); + spin_lock_irq(&dev->power.lock); + } dev->power.runtime_error = retval; - return retval; } @@ -404,7 +407,7 @@ static int rpm_suspend(struct device *dev, int rpmflags) goto out; } - if (parent && !parent->power.ignore_children) { + if (parent && !parent->power.ignore_children && !dev->power.irq_safe) { spin_unlock_irq(&dev->power.lock); pm_request_idle(parent); @@ -527,10 +530,13 @@ static int rpm_resume(struct device *dev, int rpmflags) if (!parent && dev->parent) { /* - * Increment the parent's resume counter and resume it if - * necessary. + * Increment the parent's usage counter and resume it if + * necessary. Not needed if dev is irq-safe; then the + * parent is permanently resumed. */ parent = dev->parent; + if (dev->power.irq_safe) + goto skip_parent; spin_unlock(&dev->power.lock); pm_runtime_get_noresume(parent); @@ -553,6 +559,7 @@ static int rpm_resume(struct device *dev, int rpmflags) goto out; goto repeat; } + skip_parent: if (dev->power.no_callbacks) goto no_callback; /* Assume success. */ @@ -584,7 +591,7 @@ static int rpm_resume(struct device *dev, int rpmflags) rpm_idle(dev, RPM_ASYNC); out: - if (parent) { + if (parent && !dev->power.irq_safe) { spin_unlock_irq(&dev->power.lock); pm_runtime_put(parent); @@ -1065,7 +1072,6 @@ EXPORT_SYMBOL_GPL(pm_runtime_allow); * Set the power.no_callbacks flag, which tells the PM core that this * device is power-managed through its parent and has no run-time PM * callbacks of its own. The run-time sysfs attributes will be removed. - * */ void pm_runtime_no_callbacks(struct device *dev) { @@ -1077,6 +1083,27 @@ void pm_runtime_no_callbacks(struct device *dev) } EXPORT_SYMBOL_GPL(pm_runtime_no_callbacks); +/** + * pm_runtime_irq_safe - Leave interrupts disabled during callbacks. + * @dev: Device to handle + * + * Set the power.irq_safe flag, which tells the PM core that the + * ->runtime_suspend() and ->runtime_resume() callbacks for this device should + * always be invoked with the spinlock held and interrupts disabled. It also + * causes the parent's usage counter to be permanently incremented, preventing + * the parent from runtime suspending -- otherwise an irq-safe child might have + * to wait for a non-irq-safe parent. + */ +void pm_runtime_irq_safe(struct device *dev) +{ + if (dev->parent) + pm_runtime_get_sync(dev->parent); + spin_lock_irq(&dev->power.lock); + dev->power.irq_safe = 1; + spin_unlock_irq(&dev->power.lock); +} +EXPORT_SYMBOL_GPL(pm_runtime_irq_safe); + /** * update_autosuspend - Handle a change to a device's autosuspend settings. * @dev: Device to handle. @@ -1199,4 +1226,6 @@ void pm_runtime_remove(struct device *dev) /* Change the status back to 'suspended' to match the initial status. */ if (dev->power.runtime_status == RPM_ACTIVE) pm_runtime_set_suspended(dev); + if (dev->power.irq_safe && dev->parent) + pm_runtime_put_sync(dev->parent); } diff --git a/include/linux/pm.h b/include/linux/pm.h index 40f3f45702ba..61f2066e6852 100644 --- a/include/linux/pm.h +++ b/include/linux/pm.h @@ -486,6 +486,7 @@ struct dev_pm_info { unsigned int run_wake:1; unsigned int runtime_auto:1; unsigned int no_callbacks:1; + unsigned int irq_safe:1; unsigned int use_autosuspend:1; unsigned int timer_autosuspends:1; enum rpm_request request; diff --git a/include/linux/pm_runtime.h b/include/linux/pm_runtime.h index d19f1cca7f74..e9cc049ccb62 100644 --- a/include/linux/pm_runtime.h +++ b/include/linux/pm_runtime.h @@ -40,6 +40,7 @@ extern int pm_generic_runtime_idle(struct device *dev); extern int pm_generic_runtime_suspend(struct device *dev); extern int pm_generic_runtime_resume(struct device *dev); extern void pm_runtime_no_callbacks(struct device *dev); +extern void pm_runtime_irq_safe(struct device *dev); extern void __pm_runtime_use_autosuspend(struct device *dev, bool use); extern void pm_runtime_set_autosuspend_delay(struct device *dev, int delay); extern unsigned long pm_runtime_autosuspend_expiration(struct device *dev); @@ -124,6 +125,7 @@ static inline int pm_generic_runtime_idle(struct device *dev) { return 0; } static inline int pm_generic_runtime_suspend(struct device *dev) { return 0; } static inline int pm_generic_runtime_resume(struct device *dev) { return 0; } static inline void pm_runtime_no_callbacks(struct device *dev) {} +static inline void pm_runtime_irq_safe(struct device *dev) {} static inline void pm_runtime_mark_last_busy(struct device *dev) {} static inline void __pm_runtime_use_autosuspend(struct device *dev, @@ -196,6 +198,11 @@ static inline int pm_runtime_put_sync(struct device *dev) return __pm_runtime_idle(dev, RPM_GET_PUT); } +static inline int pm_runtime_put_sync_suspend(struct device *dev) +{ + return __pm_runtime_suspend(dev, RPM_GET_PUT); +} + static inline int pm_runtime_put_sync_autosuspend(struct device *dev) { return __pm_runtime_suspend(dev, RPM_GET_PUT | RPM_AUTO); -- cgit v1.2.3 From 7ac4dcabdb482d4e74c9d36782d00bc6c4c01619 Mon Sep 17 00:00:00 2001 From: Jon Mason Date: Wed, 1 Dec 2010 00:14:55 +0100 Subject: PM: Fix references to basic-pm-debugging.txt in drivers-testing.txt basic-pm-debugging.txt is located in Documentation/power/ not Documents/power/. Change the references in Documentation/power/drivers-testing.txt to reflect the location. Signed-off-by: Jon Mason Signed-off-by: Rafael J. Wysocki --- Documentation/power/drivers-testing.txt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Documentation/power/drivers-testing.txt b/Documentation/power/drivers-testing.txt index 7f7a737f7f9f..638afdf4d6b8 100644 --- a/Documentation/power/drivers-testing.txt +++ b/Documentation/power/drivers-testing.txt @@ -23,10 +23,10 @@ Once you have resolved the suspend/resume-related problems with your test system without the new driver, you are ready to test it: a) Build the driver as a module, load it and try the test modes of hibernation - (see: Documents/power/basic-pm-debugging.txt, 1). + (see: Documentation/power/basic-pm-debugging.txt, 1). b) Load the driver and attempt to hibernate in the "reboot", "shutdown" and - "platform" modes (see: Documents/power/basic-pm-debugging.txt, 1). + "platform" modes (see: Documentation/power/basic-pm-debugging.txt, 1). c) Compile the driver directly into the kernel and try the test modes of hibernation. @@ -34,12 +34,12 @@ c) Compile the driver directly into the kernel and try the test modes of d) Attempt to hibernate with the driver compiled directly into the kernel in the "reboot", "shutdown" and "platform" modes. -e) Try the test modes of suspend (see: Documents/power/basic-pm-debugging.txt, +e) Try the test modes of suspend (see: Documentation/power/basic-pm-debugging.txt, 2). [As far as the STR tests are concerned, it should not matter whether or not the driver is built as a module.] f) Attempt to suspend to RAM using the s2ram tool with the driver loaded - (see: Documents/power/basic-pm-debugging.txt, 2). + (see: Documentation/power/basic-pm-debugging.txt, 2). Each of the above tests should be repeated several times and the STD tests should be mixed with the STR tests. If any of them fails, the driver cannot be -- cgit v1.2.3 From 1e75227ef0571031cd18536ab768ee35667ec5b9 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Fri, 3 Dec 2010 22:58:05 +0100 Subject: PM: Prevent dpm_prepare() from returning errors unnecessarily Currently dpm_prepare() returns error code if it finds that a device being suspended has a pending runtime resume request. However, it should not do that if the checking for wakeup events is not enabled. On the other hand, if the checking for wakeup events is enabled, it can return error when a wakeup event is detected, regardless of its source. Signed-off-by: Rafael J. Wysocki --- drivers/base/power/main.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c index ead3e79d6fcf..4747a1e8b44a 100644 --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c @@ -26,6 +26,7 @@ #include #include #include +#include #include "../base.h" #include "power.h" @@ -1052,8 +1053,10 @@ static int dpm_prepare(pm_message_t state) mutex_unlock(&dpm_list_mtx); pm_runtime_get_noresume(dev); - if (pm_runtime_barrier(dev) && device_may_wakeup(dev)) { - /* Wake-up requested during system sleep transition. */ + if (pm_runtime_barrier(dev) && device_may_wakeup(dev)) + pm_wakeup_event(dev, 0); + + if (!pm_check_wakeup_events()) { pm_runtime_put_sync(dev); error = -EBUSY; } else { @@ -1068,8 +1071,8 @@ static int dpm_prepare(pm_message_t state) error = 0; continue; } - printk(KERN_ERR "PM: Failed to prepare device %s " - "for power transition: error %d\n", + printk(KERN_INFO "PM: Device %s not prepared " + "for power transition: code %d\n", kobject_name(&dev->kobj), error); put_device(dev); break; -- cgit v1.2.3 From a2867e08c8e3bdbc00caf56bc3bdde19ccc058e3 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Fri, 3 Dec 2010 22:58:31 +0100 Subject: PM / Wakeup: Replace pm_check_wakeup_events() with pm_wakeup_pending() To avoid confusion with the meaning and return value of pm_check_wakeup_events() replace it with pm_wakeup_pending() that will work the other way around (ie. return true when system-wide power transition should be aborted). Signed-off-by: Rafael J. Wysocki --- drivers/base/power/main.c | 2 +- drivers/base/power/wakeup.c | 20 ++++++++++---------- include/linux/suspend.h | 4 ++-- kernel/power/hibernate.c | 4 ++-- kernel/power/process.c | 2 +- kernel/power/suspend.c | 2 +- 6 files changed, 17 insertions(+), 17 deletions(-) diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c index 4747a1e8b44a..8a5258339ca2 100644 --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c @@ -1056,7 +1056,7 @@ static int dpm_prepare(pm_message_t state) if (pm_runtime_barrier(dev) && device_may_wakeup(dev)) pm_wakeup_event(dev, 0); - if (!pm_check_wakeup_events()) { + if (pm_wakeup_pending()) { pm_runtime_put_sync(dev); error = -EBUSY; } else { diff --git a/drivers/base/power/wakeup.c b/drivers/base/power/wakeup.c index 71c5528e1c35..8ec406d8f548 100644 --- a/drivers/base/power/wakeup.c +++ b/drivers/base/power/wakeup.c @@ -542,26 +542,26 @@ static void pm_wakeup_update_hit_counts(void) } /** - * pm_check_wakeup_events - Check for new wakeup events. + * pm_wakeup_pending - Check if power transition in progress should be aborted. * * Compare the current number of registered wakeup events with its preserved - * value from the past to check if new wakeup events have been registered since - * the old value was stored. Check if the current number of wakeup events being - * processed is zero. + * value from the past and return true if new wakeup events have been registered + * since the old value was stored. Also return true if the current number of + * wakeup events being processed is different from zero. */ -bool pm_check_wakeup_events(void) +bool pm_wakeup_pending(void) { unsigned long flags; - bool ret = true; + bool ret = false; spin_lock_irqsave(&events_lock, flags); if (events_check_enabled) { - ret = ((unsigned int)atomic_read(&event_count) == saved_count) - && !atomic_read(&events_in_progress); - events_check_enabled = ret; + ret = ((unsigned int)atomic_read(&event_count) != saved_count) + || atomic_read(&events_in_progress); + events_check_enabled = !ret; } spin_unlock_irqrestore(&events_lock, flags); - if (!ret) + if (ret) pm_wakeup_update_hit_counts(); return ret; } diff --git a/include/linux/suspend.h b/include/linux/suspend.h index 26697514c5ec..144b34be5c32 100644 --- a/include/linux/suspend.h +++ b/include/linux/suspend.h @@ -292,7 +292,7 @@ extern int unregister_pm_notifier(struct notifier_block *nb); /* drivers/base/power/wakeup.c */ extern bool events_check_enabled; -extern bool pm_check_wakeup_events(void); +extern bool pm_wakeup_pending(void); extern bool pm_get_wakeup_count(unsigned int *count); extern bool pm_save_wakeup_count(unsigned int count); #else /* !CONFIG_PM_SLEEP */ @@ -309,7 +309,7 @@ static inline int unregister_pm_notifier(struct notifier_block *nb) #define pm_notifier(fn, pri) do { (void)(fn); } while (0) -static inline bool pm_check_wakeup_events(void) { return true; } +static inline bool pm_wakeup_pending(void) { return false; } #endif /* !CONFIG_PM_SLEEP */ extern struct mutex pm_mutex; diff --git a/kernel/power/hibernate.c b/kernel/power/hibernate.c index c9a98beffee4..870f72bc72ae 100644 --- a/kernel/power/hibernate.c +++ b/kernel/power/hibernate.c @@ -278,7 +278,7 @@ static int create_image(int platform_mode) goto Enable_irqs; } - if (hibernation_test(TEST_CORE) || !pm_check_wakeup_events()) + if (hibernation_test(TEST_CORE) || pm_wakeup_pending()) goto Power_up; in_suspend = 1; @@ -516,7 +516,7 @@ int hibernation_platform_enter(void) local_irq_disable(); sysdev_suspend(PMSG_HIBERNATE); - if (!pm_check_wakeup_events()) { + if (pm_wakeup_pending()) { error = -EAGAIN; goto Power_up; } diff --git a/kernel/power/process.c b/kernel/power/process.c index eb2c88a9e562..d6d2a10320e0 100644 --- a/kernel/power/process.c +++ b/kernel/power/process.c @@ -85,7 +85,7 @@ static int try_to_freeze_tasks(bool sig_only) if (!todo || time_after(jiffies, end_time)) break; - if (!pm_check_wakeup_events()) { + if (pm_wakeup_pending()) { wakeup = true; break; } diff --git a/kernel/power/suspend.c b/kernel/power/suspend.c index ecf770509d0d..5e644e3a6bf3 100644 --- a/kernel/power/suspend.c +++ b/kernel/power/suspend.c @@ -163,7 +163,7 @@ static int suspend_enter(suspend_state_t state) error = sysdev_suspend(PMSG_SUSPEND); if (!error) { - if (!suspend_test(TEST_CORE) && pm_check_wakeup_events()) { + if (!(suspend_test(TEST_CORE) || pm_wakeup_pending())) { error = suspend_ops->enter(state); events_check_enabled = false; } -- cgit v1.2.3 From d83f905e126f8cbc5e4addc5d1a64aea785b732e Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Fri, 3 Dec 2010 23:14:26 +0100 Subject: PM: Use pm_wakeup_pending() in __device_suspend() Before starting to suspend a device in __device_suspend() check if there's a request to abort the power transition and return -EBUSY in that case. Signed-off-by: Rafael J. Wysocki --- drivers/base/power/main.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c index 8a5258339ca2..fb4ca2870081 100644 --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c @@ -877,6 +877,11 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async) if (async_error) goto End; + if (pm_wakeup_pending()) { + async_error = -EBUSY; + goto End; + } + if (dev->class) { if (dev->class->pm) { pm_dev_dbg(dev, state, "class "); -- cgit v1.2.3 From 2cbb3ce1ad19e66858a4284dd6c4bb958162c483 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Wed, 15 Dec 2010 00:17:29 +0100 Subject: PM: Avoid compiler warning in pm_noirq_op() The compiler complains that calltime may be uninitialized in pm_noirq_op(), so add extra initialization for that variable to avoid the warning. Signed-off-by: Rafael J. Wysocki --- drivers/base/power/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c index fb4ca2870081..e6d628012654 100644 --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c @@ -304,7 +304,7 @@ static int pm_noirq_op(struct device *dev, pm_message_t state) { int error = 0; - ktime_t calltime, delta, rettime; + ktime_t calltime = ktime_set(0, 0), delta, rettime; if (initcall_debug) { pr_info("calling %s+ @ %i, parent: %s\n", -- cgit v1.2.3 From 8a43a9ab7b329aa8590f8a064df9bf8c80987507 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Thu, 16 Dec 2010 00:50:30 +0100 Subject: PM: Use a different list of devices for each stage of device suspend Instead of keeping all devices in the same list during system suspend and resume, regardless of what suspend-resume callbacks have been executed for them already, use separate lists of devices that have had their ->prepare(), ->suspend() and ->suspend_noirq() callbacks executed. This will allow us to simplify the core device suspend and resume routines. Signed-off-by: Rafael J. Wysocki --- drivers/base/power/main.c | 53 +++++++++++++++++------------------------------ 1 file changed, 19 insertions(+), 34 deletions(-) diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c index e6d628012654..b711867fa58e 100644 --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c @@ -42,6 +42,9 @@ */ LIST_HEAD(dpm_list); +LIST_HEAD(dpm_prepared_list); +LIST_HEAD(dpm_suspended_list); +LIST_HEAD(dpm_noirq_list); static DEFINE_MUTEX(dpm_list_mtx); static pm_message_t pm_transition; @@ -476,14 +479,12 @@ End: */ void dpm_resume_noirq(pm_message_t state) { - struct list_head list; ktime_t starttime = ktime_get(); - INIT_LIST_HEAD(&list); mutex_lock(&dpm_list_mtx); transition_started = false; - while (!list_empty(&dpm_list)) { - struct device *dev = to_device(dpm_list.next); + while (!list_empty(&dpm_noirq_list)) { + struct device *dev = to_device(dpm_noirq_list.next); get_device(dev); if (dev->power.status > DPM_OFF) { @@ -499,10 +500,9 @@ void dpm_resume_noirq(pm_message_t state) pm_dev_err(dev, state, " early", error); } if (!list_empty(&dev->power.entry)) - list_move_tail(&dev->power.entry, &list); + list_move_tail(&dev->power.entry, &dpm_suspended_list); put_device(dev); } - list_splice(&list, &dpm_list); mutex_unlock(&dpm_list_mtx); dpm_show_time(starttime, state, "early"); resume_device_irqs(); @@ -611,16 +611,14 @@ static bool is_async(struct device *dev) */ static void dpm_resume(pm_message_t state) { - struct list_head list; struct device *dev; ktime_t starttime = ktime_get(); - INIT_LIST_HEAD(&list); mutex_lock(&dpm_list_mtx); pm_transition = state; async_error = 0; - list_for_each_entry(dev, &dpm_list, power.entry) { + list_for_each_entry(dev, &dpm_suspended_list, power.entry) { if (dev->power.status < DPM_OFF) continue; @@ -631,8 +629,8 @@ static void dpm_resume(pm_message_t state) } } - while (!list_empty(&dpm_list)) { - dev = to_device(dpm_list.next); + while (!list_empty(&dpm_suspended_list)) { + dev = to_device(dpm_suspended_list.next); get_device(dev); if (dev->power.status >= DPM_OFF && !is_async(dev)) { int error; @@ -644,15 +642,11 @@ static void dpm_resume(pm_message_t state) mutex_lock(&dpm_list_mtx); if (error) pm_dev_err(dev, state, "", error); - } else if (dev->power.status == DPM_SUSPENDING) { - /* Allow new children of the device to be registered */ - dev->power.status = DPM_RESUMING; } if (!list_empty(&dev->power.entry)) - list_move_tail(&dev->power.entry, &list); + list_move_tail(&dev->power.entry, &dpm_prepared_list); put_device(dev); } - list_splice(&list, &dpm_list); mutex_unlock(&dpm_list_mtx); async_synchronize_full(); dpm_show_time(starttime, state, NULL); @@ -699,8 +693,8 @@ static void dpm_complete(pm_message_t state) INIT_LIST_HEAD(&list); mutex_lock(&dpm_list_mtx); transition_started = false; - while (!list_empty(&dpm_list)) { - struct device *dev = to_device(dpm_list.prev); + while (!list_empty(&dpm_prepared_list)) { + struct device *dev = to_device(dpm_prepared_list.prev); get_device(dev); if (dev->power.status > DPM_ON) { @@ -803,15 +797,13 @@ End: */ int dpm_suspend_noirq(pm_message_t state) { - struct list_head list; ktime_t starttime = ktime_get(); int error = 0; - INIT_LIST_HEAD(&list); suspend_device_irqs(); mutex_lock(&dpm_list_mtx); - while (!list_empty(&dpm_list)) { - struct device *dev = to_device(dpm_list.prev); + while (!list_empty(&dpm_suspended_list)) { + struct device *dev = to_device(dpm_suspended_list.prev); get_device(dev); mutex_unlock(&dpm_list_mtx); @@ -826,10 +818,9 @@ int dpm_suspend_noirq(pm_message_t state) } dev->power.status = DPM_OFF_IRQ; if (!list_empty(&dev->power.entry)) - list_move(&dev->power.entry, &list); + list_move(&dev->power.entry, &dpm_noirq_list); put_device(dev); } - list_splice_tail(&list, &dpm_list); mutex_unlock(&dpm_list_mtx); if (error) dpm_resume_noirq(resume_event(state)); @@ -957,16 +948,14 @@ static int device_suspend(struct device *dev) */ static int dpm_suspend(pm_message_t state) { - struct list_head list; ktime_t starttime = ktime_get(); int error = 0; - INIT_LIST_HEAD(&list); mutex_lock(&dpm_list_mtx); pm_transition = state; async_error = 0; - while (!list_empty(&dpm_list)) { - struct device *dev = to_device(dpm_list.prev); + while (!list_empty(&dpm_prepared_list)) { + struct device *dev = to_device(dpm_prepared_list.prev); get_device(dev); mutex_unlock(&dpm_list_mtx); @@ -980,12 +969,11 @@ static int dpm_suspend(pm_message_t state) break; } if (!list_empty(&dev->power.entry)) - list_move(&dev->power.entry, &list); + list_move(&dev->power.entry, &dpm_suspended_list); put_device(dev); if (async_error) break; } - list_splice(&list, dpm_list.prev); mutex_unlock(&dpm_list_mtx); async_synchronize_full(); if (!error) @@ -1044,10 +1032,8 @@ static int device_prepare(struct device *dev, pm_message_t state) */ static int dpm_prepare(pm_message_t state) { - struct list_head list; int error = 0; - INIT_LIST_HEAD(&list); mutex_lock(&dpm_list_mtx); transition_started = true; while (!list_empty(&dpm_list)) { @@ -1084,10 +1070,9 @@ static int dpm_prepare(pm_message_t state) } dev->power.status = DPM_SUSPENDING; if (!list_empty(&dev->power.entry)) - list_move_tail(&dev->power.entry, &list); + list_move_tail(&dev->power.entry, &dpm_prepared_list); put_device(dev); } - list_splice(&list, &dpm_list); mutex_unlock(&dpm_list_mtx); return error; } -- cgit v1.2.3 From 5b219a51fdceaf76e0e18da57c7efb9e5586e567 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Thu, 16 Dec 2010 00:51:08 +0100 Subject: PM: Remove redundant checks from core device resume routines Since a separate list of devices is used to link devices that have completed each stage of suspend (or resume), it is not necessary to check dev->power.status in the core device resume routines any more. Signed-off-by: Rafael J. Wysocki --- drivers/base/power/main.c | 44 +++++++++++++++++--------------------------- 1 file changed, 17 insertions(+), 27 deletions(-) diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c index b711867fa58e..bb5c8cb64174 100644 --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c @@ -485,22 +485,18 @@ void dpm_resume_noirq(pm_message_t state) transition_started = false; while (!list_empty(&dpm_noirq_list)) { struct device *dev = to_device(dpm_noirq_list.next); + int error; get_device(dev); - if (dev->power.status > DPM_OFF) { - int error; - - dev->power.status = DPM_OFF; - mutex_unlock(&dpm_list_mtx); + dev->power.status = DPM_OFF; + list_move_tail(&dev->power.entry, &dpm_suspended_list); + mutex_unlock(&dpm_list_mtx); - error = device_resume_noirq(dev, state); + error = device_resume_noirq(dev, state); + if (error) + pm_dev_err(dev, state, " early", error); - mutex_lock(&dpm_list_mtx); - if (error) - pm_dev_err(dev, state, " early", error); - } - if (!list_empty(&dev->power.entry)) - list_move_tail(&dev->power.entry, &dpm_suspended_list); + mutex_lock(&dpm_list_mtx); put_device(dev); } mutex_unlock(&dpm_list_mtx); @@ -619,9 +615,6 @@ static void dpm_resume(pm_message_t state) async_error = 0; list_for_each_entry(dev, &dpm_suspended_list, power.entry) { - if (dev->power.status < DPM_OFF) - continue; - INIT_COMPLETION(dev->power.completion); if (is_async(dev)) { get_device(dev); @@ -632,16 +625,16 @@ static void dpm_resume(pm_message_t state) while (!list_empty(&dpm_suspended_list)) { dev = to_device(dpm_suspended_list.next); get_device(dev); - if (dev->power.status >= DPM_OFF && !is_async(dev)) { + if (!is_async(dev)) { int error; mutex_unlock(&dpm_list_mtx); error = device_resume(dev, state, false); - - mutex_lock(&dpm_list_mtx); if (error) pm_dev_err(dev, state, "", error); + + mutex_lock(&dpm_list_mtx); } if (!list_empty(&dev->power.entry)) list_move_tail(&dev->power.entry, &dpm_prepared_list); @@ -697,17 +690,14 @@ static void dpm_complete(pm_message_t state) struct device *dev = to_device(dpm_prepared_list.prev); get_device(dev); - if (dev->power.status > DPM_ON) { - dev->power.status = DPM_ON; - mutex_unlock(&dpm_list_mtx); + dev->power.status = DPM_ON; + list_move(&dev->power.entry, &list); + mutex_unlock(&dpm_list_mtx); - device_complete(dev, state); - pm_runtime_put_sync(dev); + device_complete(dev, state); + pm_runtime_put_sync(dev); - mutex_lock(&dpm_list_mtx); - } - if (!list_empty(&dev->power.entry)) - list_move(&dev->power.entry, &list); + mutex_lock(&dpm_list_mtx); put_device(dev); } list_splice(&list, &dpm_list); -- cgit v1.2.3 From b8c76f6aed0ab7df73a6410f3f82de2c831bb144 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Thu, 16 Dec 2010 00:51:21 +0100 Subject: PM: Replace the device power.status field with a bit field The device power.status field is too complicated for its purpose (storing the information about whether or not the device is in the "active" state from the PM core's point of view), so replace it with a bit field and modify all of its users accordingly. Signed-off-by: Rafael J. Wysocki --- drivers/base/power/main.c | 17 +++++------------ drivers/usb/core/driver.c | 7 +++---- include/linux/device.h | 4 ++-- include/linux/pm.h | 43 ++----------------------------------------- 4 files changed, 12 insertions(+), 59 deletions(-) diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c index bb5c8cb64174..a90480baa850 100644 --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c @@ -63,7 +63,7 @@ static int async_error; */ void device_pm_init(struct device *dev) { - dev->power.status = DPM_ON; + dev->power.in_suspend = false; init_completion(&dev->power.completion); complete_all(&dev->power.completion); dev->power.wakeup = NULL; @@ -98,7 +98,7 @@ void device_pm_add(struct device *dev) kobject_name(&dev->kobj)); mutex_lock(&dpm_list_mtx); if (dev->parent) { - if (dev->parent->power.status >= DPM_SUSPENDING) + if (dev->parent->power.in_suspend) dev_warn(dev, "parent %s should not be sleeping\n", dev_name(dev->parent)); } else if (transition_started) { @@ -488,7 +488,6 @@ void dpm_resume_noirq(pm_message_t state) int error; get_device(dev); - dev->power.status = DPM_OFF; list_move_tail(&dev->power.entry, &dpm_suspended_list); mutex_unlock(&dpm_list_mtx); @@ -541,7 +540,7 @@ static int device_resume(struct device *dev, pm_message_t state, bool async) dpm_wait(dev->parent, async); device_lock(dev); - dev->power.status = DPM_RESUMING; + dev->power.in_suspend = false; if (dev->bus) { if (dev->bus->pm) { @@ -690,7 +689,7 @@ static void dpm_complete(pm_message_t state) struct device *dev = to_device(dpm_prepared_list.prev); get_device(dev); - dev->power.status = DPM_ON; + dev->power.in_suspend = false; list_move(&dev->power.entry, &list); mutex_unlock(&dpm_list_mtx); @@ -806,7 +805,6 @@ int dpm_suspend_noirq(pm_message_t state) put_device(dev); break; } - dev->power.status = DPM_OFF_IRQ; if (!list_empty(&dev->power.entry)) list_move(&dev->power.entry, &dpm_noirq_list); put_device(dev); @@ -894,9 +892,6 @@ static int __device_suspend(struct device *dev, pm_message_t state, bool async) } } - if (!error) - dev->power.status = DPM_OFF; - End: device_unlock(dev); complete_all(&dev->power.completion); @@ -1030,7 +1025,6 @@ static int dpm_prepare(pm_message_t state) struct device *dev = to_device(dpm_list.next); get_device(dev); - dev->power.status = DPM_PREPARING; mutex_unlock(&dpm_list_mtx); pm_runtime_get_noresume(dev); @@ -1046,7 +1040,6 @@ static int dpm_prepare(pm_message_t state) mutex_lock(&dpm_list_mtx); if (error) { - dev->power.status = DPM_ON; if (error == -EAGAIN) { put_device(dev); error = 0; @@ -1058,7 +1051,7 @@ static int dpm_prepare(pm_message_t state) put_device(dev); break; } - dev->power.status = DPM_SUSPENDING; + dev->power.in_suspend = true; if (!list_empty(&dev->power.entry)) list_move_tail(&dev->power.entry, &dpm_prepared_list); put_device(dev); diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c index c0e60fbcb048..4ec50224ee86 100644 --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c @@ -376,7 +376,7 @@ static int usb_unbind_interface(struct device *dev) * Just re-enable it without affecting the endpoint toggles. */ usb_enable_interface(udev, intf, false); - } else if (!error && intf->dev.power.status == DPM_ON) { + } else if (!error && !intf->dev.power.in_suspend) { r = usb_set_interface(udev, intf->altsetting[0]. desc.bInterfaceNumber, 0); if (r < 0) @@ -961,7 +961,7 @@ void usb_rebind_intf(struct usb_interface *intf) } /* Try to rebind the interface */ - if (intf->dev.power.status == DPM_ON) { + if (!intf->dev.power.in_suspend) { intf->needs_binding = 0; rc = device_attach(&intf->dev); if (rc < 0) @@ -1108,8 +1108,7 @@ static int usb_resume_interface(struct usb_device *udev, if (intf->condition == USB_INTERFACE_UNBOUND) { /* Carry out a deferred switch to altsetting 0 */ - if (intf->needs_altsetting0 && - intf->dev.power.status == DPM_ON) { + if (intf->needs_altsetting0 && !intf->dev.power.in_suspend) { usb_set_interface(udev, intf->altsetting[0]. desc.bInterfaceNumber, 0); intf->needs_altsetting0 = 0; diff --git a/include/linux/device.h b/include/linux/device.h index dd4895313468..45bc8c1669d2 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -508,13 +508,13 @@ static inline int device_is_registered(struct device *dev) static inline void device_enable_async_suspend(struct device *dev) { - if (dev->power.status == DPM_ON) + if (!dev->power.in_suspend) dev->power.async_suspend = true; } static inline void device_disable_async_suspend(struct device *dev) { - if (dev->power.status == DPM_ON) + if (!dev->power.in_suspend) dev->power.async_suspend = false; } diff --git a/include/linux/pm.h b/include/linux/pm.h index 61f2066e6852..c1756dfeb8c5 100644 --- a/include/linux/pm.h +++ b/include/linux/pm.h @@ -366,45 +366,6 @@ extern struct dev_pm_ops generic_subsys_pm_ops; #define PMSG_AUTO_RESUME ((struct pm_message) \ { .event = PM_EVENT_AUTO_RESUME, }) -/** - * Device power management states - * - * These state labels are used internally by the PM core to indicate the current - * status of a device with respect to the PM core operations. - * - * DPM_ON Device is regarded as operational. Set this way - * initially and when ->complete() is about to be called. - * Also set when ->prepare() fails. - * - * DPM_PREPARING Device is going to be prepared for a PM transition. Set - * when ->prepare() is about to be called. - * - * DPM_RESUMING Device is going to be resumed. Set when ->resume(), - * ->thaw(), or ->restore() is about to be called. - * - * DPM_SUSPENDING Device has been prepared for a power transition. Set - * when ->prepare() has just succeeded. - * - * DPM_OFF Device is regarded as inactive. Set immediately after - * ->suspend(), ->freeze(), or ->poweroff() has succeeded. - * Also set when ->resume()_noirq, ->thaw_noirq(), or - * ->restore_noirq() is about to be called. - * - * DPM_OFF_IRQ Device is in a "deep sleep". Set immediately after - * ->suspend_noirq(), ->freeze_noirq(), or - * ->poweroff_noirq() has just succeeded. - */ - -enum dpm_state { - DPM_INVALID, - DPM_ON, - DPM_PREPARING, - DPM_RESUMING, - DPM_SUSPENDING, - DPM_OFF, - DPM_OFF_IRQ, -}; - /** * Device run-time power management status. * @@ -463,8 +424,8 @@ struct wakeup_source; struct dev_pm_info { pm_message_t power_state; unsigned int can_wakeup:1; - unsigned async_suspend:1; - enum dpm_state status; /* Owned by the PM core */ + unsigned int async_suspend:1; + unsigned int in_suspend:1; /* Owned by the PM core */ spinlock_t lock; #ifdef CONFIG_PM_SLEEP struct list_head entry; -- cgit v1.2.3 From b64959e6158d6dcb640fc22d7f43b94ad1c91135 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Thu, 16 Dec 2010 17:11:45 +0100 Subject: PM: Permit registration of parentless devices during system suspend The registration of a new parentless device during system suspend will not lead to any complications affecting the PM core (the device will be effectively seen after the subsequent resume has completed), so remove the code used for detection of such events. Signed-off-by: Rafael J. Wysocki --- drivers/base/power/main.c | 25 +++---------------------- 1 file changed, 3 insertions(+), 22 deletions(-) diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c index a90480baa850..11fe6ed75278 100644 --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c @@ -49,12 +49,6 @@ LIST_HEAD(dpm_noirq_list); static DEFINE_MUTEX(dpm_list_mtx); static pm_message_t pm_transition; -/* - * Set once the preparation of devices for a PM transition has started, reset - * before starting to resume devices. Protected by dpm_list_mtx. - */ -static bool transition_started; - static int async_error; /** @@ -97,19 +91,9 @@ void device_pm_add(struct device *dev) dev->bus ? dev->bus->name : "No Bus", kobject_name(&dev->kobj)); mutex_lock(&dpm_list_mtx); - if (dev->parent) { - if (dev->parent->power.in_suspend) - dev_warn(dev, "parent %s should not be sleeping\n", - dev_name(dev->parent)); - } else if (transition_started) { - /* - * We refuse to register parentless devices while a PM - * transition is in progress in order to avoid leaving them - * unhandled down the road - */ - dev_WARN(dev, "Parentless device registered during a PM transaction\n"); - } - + if (dev->parent && dev->parent->power.in_suspend) + dev_warn(dev, "parent %s should not be sleeping\n", + dev_name(dev->parent)); list_add_tail(&dev->power.entry, &dpm_list); mutex_unlock(&dpm_list_mtx); } @@ -482,7 +466,6 @@ void dpm_resume_noirq(pm_message_t state) ktime_t starttime = ktime_get(); mutex_lock(&dpm_list_mtx); - transition_started = false; while (!list_empty(&dpm_noirq_list)) { struct device *dev = to_device(dpm_noirq_list.next); int error; @@ -684,7 +667,6 @@ static void dpm_complete(pm_message_t state) INIT_LIST_HEAD(&list); mutex_lock(&dpm_list_mtx); - transition_started = false; while (!list_empty(&dpm_prepared_list)) { struct device *dev = to_device(dpm_prepared_list.prev); @@ -1020,7 +1002,6 @@ static int dpm_prepare(pm_message_t state) int error = 0; mutex_lock(&dpm_list_mtx); - transition_started = true; while (!list_empty(&dpm_list)) { struct device *dev = to_device(dpm_list.next); -- cgit v1.2.3 From 5c1a07ab3e78ef68fc9ccf419c969e8ed88d7cb6 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Fri, 24 Dec 2010 15:03:34 +0100 Subject: PM: Use dev_name() in core device suspend and resume routines Use dev_name() wherever applicable in drivers/base/power/main.c. Signed-off-by: Rafael J. Wysocki --- drivers/base/power/main.c | 25 +++++++++---------------- 1 file changed, 9 insertions(+), 16 deletions(-) diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c index 11fe6ed75278..2a52270aeb30 100644 --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c @@ -88,8 +88,7 @@ void device_pm_unlock(void) void device_pm_add(struct device *dev) { pr_debug("PM: Adding info for %s:%s\n", - dev->bus ? dev->bus->name : "No Bus", - kobject_name(&dev->kobj)); + dev->bus ? dev->bus->name : "No Bus", dev_name(dev)); mutex_lock(&dpm_list_mtx); if (dev->parent && dev->parent->power.in_suspend) dev_warn(dev, "parent %s should not be sleeping\n", @@ -105,8 +104,7 @@ void device_pm_add(struct device *dev) void device_pm_remove(struct device *dev) { pr_debug("PM: Removing info for %s:%s\n", - dev->bus ? dev->bus->name : "No Bus", - kobject_name(&dev->kobj)); + dev->bus ? dev->bus->name : "No Bus", dev_name(dev)); complete_all(&dev->power.completion); mutex_lock(&dpm_list_mtx); list_del_init(&dev->power.entry); @@ -123,10 +121,8 @@ void device_pm_remove(struct device *dev) void device_pm_move_before(struct device *deva, struct device *devb) { pr_debug("PM: Moving %s:%s before %s:%s\n", - deva->bus ? deva->bus->name : "No Bus", - kobject_name(&deva->kobj), - devb->bus ? devb->bus->name : "No Bus", - kobject_name(&devb->kobj)); + deva->bus ? deva->bus->name : "No Bus", dev_name(deva), + devb->bus ? devb->bus->name : "No Bus", dev_name(devb)); /* Delete deva from dpm_list and reinsert before devb. */ list_move_tail(&deva->power.entry, &devb->power.entry); } @@ -139,10 +135,8 @@ void device_pm_move_before(struct device *deva, struct device *devb) void device_pm_move_after(struct device *deva, struct device *devb) { pr_debug("PM: Moving %s:%s after %s:%s\n", - deva->bus ? deva->bus->name : "No Bus", - kobject_name(&deva->kobj), - devb->bus ? devb->bus->name : "No Bus", - kobject_name(&devb->kobj)); + deva->bus ? deva->bus->name : "No Bus", dev_name(deva), + devb->bus ? devb->bus->name : "No Bus", dev_name(devb)); /* Delete deva from dpm_list and reinsert after devb. */ list_move(&deva->power.entry, &devb->power.entry); } @@ -154,8 +148,7 @@ void device_pm_move_after(struct device *deva, struct device *devb) void device_pm_move_last(struct device *dev) { pr_debug("PM: Moving %s:%s to end of list\n", - dev->bus ? dev->bus->name : "No Bus", - kobject_name(&dev->kobj)); + dev->bus ? dev->bus->name : "No Bus", dev_name(dev)); list_move_tail(&dev->power.entry, &dpm_list); } @@ -393,7 +386,7 @@ static void pm_dev_err(struct device *dev, pm_message_t state, char *info, int error) { printk(KERN_ERR "PM: Device %s failed to %s%s: error %d\n", - kobject_name(&dev->kobj), pm_verb(state.event), info, error); + dev_name(dev), pm_verb(state.event), info, error); } static void dpm_show_time(ktime_t starttime, pm_message_t state, char *info) @@ -1028,7 +1021,7 @@ static int dpm_prepare(pm_message_t state) } printk(KERN_INFO "PM: Device %s not prepared " "for power transition: code %d\n", - kobject_name(&dev->kobj), error); + dev_name(dev), error); put_device(dev); break; } -- cgit v1.2.3 From 4b31db8a16fa0d4d6a0fa42d044e7a4f4dad3641 Mon Sep 17 00:00:00 2001 From: "Rafael J. Wysocki" Date: Fri, 24 Dec 2010 15:04:06 +0100 Subject: PM / Runtime: Generic resume shouldn't set RPM_ACTIVE unconditionally The __pm_generic_resume() function changes the given device's runtime PM status to RPM_ACTIVE if its driver's callback returns 0, but it only should do that if the rumtime PM is enabled for the device. Signed-off-by: Rafael J. Wysocki --- drivers/base/power/generic_ops.c | 2 +- include/linux/pm_runtime.h | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/drivers/base/power/generic_ops.c b/drivers/base/power/generic_ops.c index 3d2c3500069a..42f97f925629 100644 --- a/drivers/base/power/generic_ops.c +++ b/drivers/base/power/generic_ops.c @@ -185,7 +185,7 @@ static int __pm_generic_resume(struct device *dev, int event) return 0; ret = callback(dev); - if (!ret) { + if (!ret && pm_runtime_enabled(dev)) { pm_runtime_disable(dev); pm_runtime_set_active(dev); pm_runtime_enable(dev); diff --git a/include/linux/pm_runtime.h b/include/linux/pm_runtime.h index e9cc049ccb62..d34f067e2a7f 100644 --- a/include/linux/pm_runtime.h +++ b/include/linux/pm_runtime.h @@ -82,6 +82,11 @@ static inline bool pm_runtime_suspended(struct device *dev) && !dev->power.disable_depth; } +static inline bool pm_runtime_enabled(struct device *dev) +{ + return !dev->power.disable_depth; +} + static inline void pm_runtime_mark_last_busy(struct device *dev) { ACCESS_ONCE(dev->power.last_busy) = jiffies; @@ -120,6 +125,7 @@ static inline void pm_runtime_put_noidle(struct device *dev) {} static inline bool device_run_wake(struct device *dev) { return false; } static inline void device_set_run_wake(struct device *dev, bool enable) {} static inline bool pm_runtime_suspended(struct device *dev) { return false; } +static inline bool pm_runtime_enabled(struct device *dev) { return false; } static inline int pm_generic_runtime_idle(struct device *dev) { return 0; } static inline int pm_generic_runtime_suspend(struct device *dev) { return 0; } -- cgit v1.2.3 From 62bcb91573425975d6ad2389d7ab1d8feca88ab4 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 24 Dec 2010 15:04:41 +0100 Subject: PM: Prototype the pm_generic_ operations The pm_generic_ operations are all exported but are not prototyped in any header file for direct use. Do so. [rjw: Added extern.] Signed-off-by: Mark Brown Signed-off-by: Rafael J. Wysocki --- include/linux/pm.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/include/linux/pm.h b/include/linux/pm.h index c1756dfeb8c5..dd9c7ab38270 100644 --- a/include/linux/pm.h +++ b/include/linux/pm.h @@ -572,4 +572,11 @@ extern unsigned int pm_flags; #define PM_APM 1 #define PM_ACPI 2 +extern int pm_generic_suspend(struct device *dev); +extern int pm_generic_resume(struct device *dev); +extern int pm_generic_freeze(struct device *dev); +extern int pm_generic_thaw(struct device *dev); +extern int pm_generic_restore(struct device *dev); +extern int pm_generic_poweroff(struct device *dev); + #endif /* _LINUX_PM_H */ -- cgit v1.2.3 From 3ae22e8c8ac39daf88ae32f047fb23825be7c646 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Sat, 25 Dec 2010 15:32:27 +0100 Subject: spi / PM: Support dev_pm_ops Allow SPI drivers to use runtime PM and other dev_pm_ops features by implementing dev_pm_ops for the bus. The existing bus specific suspend and resume functions will be called if a driver does not provide dev_pm_ops allowing for transition to the new model. Signed-off-by: Mark Brown Acked-by: Grant Likely Signed-off-by: Rafael J. Wysocki --- drivers/spi/spi.c | 92 ++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 84 insertions(+), 8 deletions(-) diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index b02d0cbce890..34bb17f03019 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c @@ -28,6 +28,7 @@ #include #include #include +#include static void spidev_release(struct device *dev) { @@ -100,9 +101,8 @@ static int spi_uevent(struct device *dev, struct kobj_uevent_env *env) return 0; } -#ifdef CONFIG_PM - -static int spi_suspend(struct device *dev, pm_message_t message) +#ifdef CONFIG_PM_SLEEP +static int spi_legacy_suspend(struct device *dev, pm_message_t message) { int value = 0; struct spi_driver *drv = to_spi_driver(dev->driver); @@ -117,7 +117,7 @@ static int spi_suspend(struct device *dev, pm_message_t message) return value; } -static int spi_resume(struct device *dev) +static int spi_legacy_resume(struct device *dev) { int value = 0; struct spi_driver *drv = to_spi_driver(dev->driver); @@ -132,18 +132,94 @@ static int spi_resume(struct device *dev) return value; } +static int spi_pm_suspend(struct device *dev) +{ + const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; + + if (pm) + return pm_generic_suspend(dev); + else + return spi_legacy_suspend(dev, PMSG_SUSPEND); +} + +static int spi_pm_resume(struct device *dev) +{ + const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; + + if (pm) + return pm_generic_resume(dev); + else + return spi_legacy_resume(dev); +} + +static int spi_pm_freeze(struct device *dev) +{ + const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; + + if (pm) + return pm_generic_freeze(dev); + else + return spi_legacy_suspend(dev, PMSG_FREEZE); +} + +static int spi_pm_thaw(struct device *dev) +{ + const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; + + if (pm) + return pm_generic_thaw(dev); + else + return spi_legacy_resume(dev); +} + +static int spi_pm_poweroff(struct device *dev) +{ + const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; + + if (pm) + return pm_generic_poweroff(dev); + else + return spi_legacy_suspend(dev, PMSG_HIBERNATE); +} + +static int spi_pm_restore(struct device *dev) +{ + const struct dev_pm_ops *pm = dev->driver ? dev->driver->pm : NULL; + + if (pm) + return pm_generic_restore(dev); + else + return spi_legacy_resume(dev); +} #else -#define spi_suspend NULL -#define spi_resume NULL +#define spi_pm_suspend NULL +#define spi_pm_resume NULL +#define spi_pm_freeze NULL +#define spi_pm_thaw NULL +#define spi_pm_poweroff NULL +#define spi_pm_restore NULL #endif +static const struct dev_pm_ops spi_pm = { + .suspend = spi_pm_suspend, + .resume = spi_pm_resume, + .freeze = spi_pm_freeze, + .thaw = spi_pm_thaw, + .poweroff = spi_pm_poweroff, + .restore = spi_pm_restore, + SET_RUNTIME_PM_OPS( + pm_generic_runtime_suspend, + pm_generic_runtime_resume, + pm_generic_runtime_idle + ) +}; + struct bus_type spi_bus_type = { .name = "spi", .dev_attrs = spi_dev_attrs, .match = spi_match_device, .uevent = spi_uevent, - .suspend = spi_suspend, - .resume = spi_resume, + .pm = &spi_pm, }; EXPORT_SYMBOL_GPL(spi_bus_type); -- cgit v1.2.3 From c42988012ad9c1807b7c7a5ff855cd630094989b Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Sat, 25 Dec 2010 16:17:32 +0000 Subject: drm/nouveau: Only select ACPI_VIDEO if its dependencies are met CONFIG_ACPI_VIDEO depends on more than just CONFIG_ACPI, so add those dependencies to the Kconfig select condition. The case where some dependencies fail to be satisfied should be handled correctly, because in that case the ACPI_VIDEO symbols we use are converted into static-inline stubs. Signed-off-by: Ben Hutchings Signed-off-by: Francisco Jerez Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/nouveau/Kconfig b/drivers/gpu/drm/nouveau/Kconfig index 72730e9ca06c..21d6c29c2d21 100644 --- a/drivers/gpu/drm/nouveau/Kconfig +++ b/drivers/gpu/drm/nouveau/Kconfig @@ -10,7 +10,7 @@ config DRM_NOUVEAU select FB select FRAMEBUFFER_CONSOLE if !EMBEDDED select FB_BACKLIGHT if DRM_NOUVEAU_BACKLIGHT - select ACPI_VIDEO if ACPI + select ACPI_VIDEO if ACPI && X86 && BACKLIGHT_CLASS_DEVICE && VIDEO_OUTPUT_CONTROL && INPUT help Choose this option for open-source nVidia support. -- cgit v1.2.3 From 8e91182bbdb8591be4835907d825a5b9a80495a9 Mon Sep 17 00:00:00 2001 From: Michel Hermier Date: Sat, 25 Dec 2010 16:58:56 +0100 Subject: drm/nouveau: Validate channel indices passed from userspace. When hacking the libdrm for improvements, I triggered a kernel crash related to the fact that the NOUVEAU_NOTIFIEROBJ_ALLOC ioctl calls nouveau_channel_get with an unchecked channel index. The patch ensures that the channel index is an unsigned and validates its value in nouveau_channel_get. Signed-off-by: Michel Hermier Signed-off-by: Francisco Jerez Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nouveau_channel.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/gpu/drm/nouveau/nouveau_channel.c b/drivers/gpu/drm/nouveau/nouveau_channel.c index e37977d02463..4d2f19420922 100644 --- a/drivers/gpu/drm/nouveau/nouveau_channel.c +++ b/drivers/gpu/drm/nouveau/nouveau_channel.c @@ -253,6 +253,9 @@ nouveau_channel_get(struct drm_device *dev, struct drm_file *file_priv, int id) struct nouveau_channel *chan; unsigned long flags; + if (unlikely(id < 0 || id >= NOUVEAU_MAX_CHANNEL_NR)) + return ERR_PTR(-EINVAL); + spin_lock_irqsave(&dev_priv->channels.lock, flags); chan = nouveau_channel_get_unlocked(dev_priv->channels.ptr[id]); spin_unlock_irqrestore(&dev_priv->channels.lock, flags); -- cgit v1.2.3 From c521dde6a690721a1db17924ef5683864ff58fdb Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Mon, 27 Dec 2010 15:09:53 +0100 Subject: sound, ca0106: Fix assignment to 'channel'. The assignment to the local variable 'channel' in snd_ca0106_pcm_pointer_capture() is a little crazy. Order of assignment is undefined. This fixes it. Signed-off-by: Jesper Juhl Signed-off-by: Jiri Kosina --- sound/pci/ca0106/ca0106_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/pci/ca0106/ca0106_main.c b/sound/pci/ca0106/ca0106_main.c index d2d12c08f937..01b49388fafd 100644 --- a/sound/pci/ca0106/ca0106_main.c +++ b/sound/pci/ca0106/ca0106_main.c @@ -1082,7 +1082,7 @@ snd_ca0106_pcm_pointer_capture(struct snd_pcm_substream *substream) struct snd_pcm_runtime *runtime = substream->runtime; struct snd_ca0106_pcm *epcm = runtime->private_data; snd_pcm_uframes_t ptr, ptr1, ptr2 = 0; - int channel = channel=epcm->channel_id; + int channel = epcm->channel_id; if (!epcm->running) return 0; -- cgit v1.2.3 From 23a0790af27b08daddf1334388c48d0d4ccf2374 Mon Sep 17 00:00:00 2001 From: "Figo.zhang" Date: Mon, 27 Dec 2010 15:14:06 +0100 Subject: mm/rmap.c: fix comment clean up comment. Signed-off-by: Figo.zhang Acked-by: Rik van Riel Signed-off-by: Jiri Kosina --- mm/rmap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mm/rmap.c b/mm/rmap.c index 1a8bf76bfd03..c95d2ba27a0b 100644 --- a/mm/rmap.c +++ b/mm/rmap.c @@ -94,7 +94,7 @@ static void anon_vma_chain_free(struct anon_vma_chain *anon_vma_chain) * anonymous pages mapped into it with that anon_vma. * * The common case will be that we already have one, but if - * if not we either need to find an adjacent mapping that we + * not we either need to find an adjacent mapping that we * can re-use the anon_vma from (very common when the only * reason for splitting a vma has been mprotect()), or we * allocate a new one. -- cgit v1.2.3 From 3f1c63261b7ff81bffd7d4ac6b933c9d0e4c4f94 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Mon, 27 Dec 2010 15:30:45 +0000 Subject: ASoC: Fix typo in x86 workaround Signed-off-by: Mark Brown --- sound/soc/codecs/wm8962.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c index b311b465c4d8..e2177144b714 100644 --- a/sound/soc/codecs/wm8962.c +++ b/sound/soc/codecs/wm8962.c @@ -3354,7 +3354,7 @@ static irqreturn_t wm8962_irq(int irq, void *data) if (active & (WM8962_MICSCD_EINT | WM8962_MICD_EINT)) { dev_dbg(codec->dev, "Microphone event detected\n"); -#ifndef CONFIG_SOUND_SOC_WM862_MODULE +#ifndef CONFIG_SOUND_SOC_WM8962_MODULE trace_snd_soc_jack_irq(dev_name(codec->dev)); #endif -- cgit v1.2.3 From 8b08c0fe95060bba87e98ae6308b90441698a878 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 24 Dec 2010 16:59:36 +0000 Subject: ASoC: Fix double comment start Signed-off-by: Mark Brown --- sound/soc/codecs/wm8903.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/sound/soc/codecs/wm8903.h b/sound/soc/codecs/wm8903.h index 5f23d3ca45f8..e8490f3edd03 100644 --- a/sound/soc/codecs/wm8903.h +++ b/sound/soc/codecs/wm8903.h @@ -1199,8 +1199,6 @@ extern int wm8903_mic_detect(struct snd_soc_codec *codec, #define WM8903_IRQ_POL_SHIFT 0 /* IRQ_POL */ #define WM8903_IRQ_POL_WIDTH 1 /* IRQ_POL */ -/* - /* * R164 (0xA4) - Clock Rate Test 4 */ -- cgit v1.2.3 From 86280a208825d55ba988420b6b0ed2d6b9ec80f8 Mon Sep 17 00:00:00 2001 From: David Sterba Date: Mon, 27 Dec 2010 16:27:43 +0100 Subject: HID: picolcd: fix misuse of logical operation in place of bitop MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CC: Bruno Prémont CC: Jiri Kosina Signed-off-by: David Sterba Signed-off-by: Jiri Kosina --- drivers/hid/hid-picolcd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/hid/hid-picolcd.c b/drivers/hid/hid-picolcd.c index bc2e07740628..0aff3cdddd83 100644 --- a/drivers/hid/hid-picolcd.c +++ b/drivers/hid/hid-picolcd.c @@ -1544,7 +1544,7 @@ static ssize_t picolcd_debug_eeprom_read(struct file *f, char __user *u, /* prepare buffer with info about what we want to read (addr & len) */ raw_data[0] = *off & 0xff; - raw_data[1] = (*off >> 8) && 0xff; + raw_data[1] = (*off >> 8) & 0xff; raw_data[2] = s < 20 ? s : 20; if (*off + raw_data[2] > 0xff) raw_data[2] = 0x100 - *off; @@ -1583,7 +1583,7 @@ static ssize_t picolcd_debug_eeprom_write(struct file *f, const char __user *u, memset(raw_data, 0, sizeof(raw_data)); raw_data[0] = *off & 0xff; - raw_data[1] = (*off >> 8) && 0xff; + raw_data[1] = (*off >> 8) & 0xff; raw_data[2] = s < 20 ? s : 20; if (*off + raw_data[2] > 0xff) raw_data[2] = 0x100 - *off; -- cgit v1.2.3 From 0597fcd08b858df83b9f20afd6035311d92c48f8 Mon Sep 17 00:00:00 2001 From: Arnaud Lacombe Date: Thu, 23 Dec 2010 03:25:16 -0500 Subject: kconfig: fix warning In file included from scripts/kconfig/zconf.tab.c:2502: scripts/kconfig/expr.c:1033: warning: no previous prototype for 'expr_simplify_unmet_dep' Reported-by: Stephen Rothwell Signed-off-by: Arnaud Lacombe Signed-off-by: Michal Marek --- scripts/kconfig/expr.h | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/kconfig/expr.h b/scripts/kconfig/expr.h index 218991b26d92..79ab6e746f53 100644 --- a/scripts/kconfig/expr.h +++ b/scripts/kconfig/expr.h @@ -206,6 +206,7 @@ struct expr *expr_extract_eq_and(struct expr **ep1, struct expr **ep2); struct expr *expr_extract_eq_or(struct expr **ep1, struct expr **ep2); void expr_extract_eq(enum expr_type type, struct expr **ep, struct expr **ep1, struct expr **ep2); struct expr *expr_trans_compare(struct expr *e, enum expr_type type, struct symbol *sym); +struct expr *expr_simplify_unmet_dep(struct expr *e1, struct expr *e2); void expr_fprint(struct expr *e, FILE *out); struct gstr; /* forward */ -- cgit v1.2.3 From 731ece41fb1047816303295a0cdfed90a528137e Mon Sep 17 00:00:00 2001 From: Olof Johansson Date: Fri, 10 Dec 2010 02:09:23 -0600 Subject: modpost: Fix address calculation in reloc_location() This patch fixes a segfault in modpost that is observed when the gold linker is used to link the input objects. The problem is that reloc_location (modpost.c) is computing the address of the relocation target incorrectly. Here, elf->hdr points to the beginning of the ELF file in memory, sechdr points to the relocation section header, section is the index of the section being relocated, and sechdrs[section].sh_offset would be the offset of that section, relative to the beginning of the ELF file. Adding elf->hdr + sechdrs[section].sh_offset gives you the address of the beginning of the section, and adding r->r_offset to that gives you the address of the location to be relocated. You do not need to subtract sechdrs[section].sh_addr from that -- the result of this is an address outside the file, and causes the segfault when addend_386_rel tries to dereference it. This bug is not observed when GNU ld is used to link the inputs. The object file ubuntu/omnibook/omnibook.o is the result of an ld -r of several other files. When GNU ld does an ld -r, it sets the vaddr field for each section to 0, but gold lays out the section addresses sequentially instead: Section Headers: [Nr] Name Type Addr Off Size ES Flg Lk Inf Al [ 0] NULL 00000000 000000 000000 00 0 0 0 [ 1] .text PROGBITS 00000000 000034 004794 00 AX 0 0 4 [ 2] .data PROGBITS 0000b9d0 0047c8 0009c0 00 WA 0 0 4 [ 3] .bss NOBITS 000162f8 005188 00013c 00 WA 0 0 4 [ 4] .rodata.str1.1 PROGBITS 00004f2d 0052c4 001b1a 01 AMS 0 0 1 [ 5] .init.text PROGBITS 00004794 006dde 0005fa 00 AX 0 0 1 [ 6] .exit.text PROGBITS 00004d8e 0073d8 00018a 00 AX 0 0 1 ... So the bug in the tool remained undiscovered because the section's vaddr always happened to be 0. Signed-off-by: Raymes Khoury Signed-off-by: Olof Johansson Signed-off-by: Michal Marek --- scripts/mod/modpost.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 194e2c453609..97d2259ae999 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -1442,7 +1442,7 @@ static unsigned int *reloc_location(struct elf_info *elf, int section = shndx2secindex(sechdr->sh_info); return (void *)elf->hdr + sechdrs[section].sh_offset + - r->r_offset - sechdrs[section].sh_addr; + r->r_offset; } static int addend_386_rel(struct elf_info *elf, Elf_Shdr *sechdr, Elf_Rela *r) -- cgit v1.2.3 From e7bf068aa3208d73e9dea817f6d975071ddd4336 Mon Sep 17 00:00:00 2001 From: David Sterba Date: Mon, 27 Dec 2010 16:51:15 +0100 Subject: i7core_edac: fix typos in comments Signed-off-by: Jiri Kosina --- drivers/edac/i7core_edac.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/edac/i7core_edac.c b/drivers/edac/i7core_edac.c index 362861c15779..81154ab296b6 100644 --- a/drivers/edac/i7core_edac.c +++ b/drivers/edac/i7core_edac.c @@ -1,6 +1,6 @@ /* Intel i7 core/Nehalem Memory Controller kernel module * - * This driver supports yhe memory controllers found on the Intel + * This driver supports the memory controllers found on the Intel * processor families i7core, i7core 7xx/8xx, i5core, Xeon 35xx, * Xeon 55xx and Xeon 56xx also known as Nehalem, Nehalem-EP, Lynnfield * and Westmere-EP. @@ -1271,7 +1271,7 @@ static void __init i7core_xeon_pci_fixup(const struct pci_id_table *table) int i; /* - * On Xeon 55xx, the Intel Quckpath Arch Generic Non-core pci buses + * On Xeon 55xx, the Intel Quick Path Arch Generic Non-core pci buses * aren't announced by acpi. So, we need to use a legacy scan probing * to detect them */ @@ -1864,7 +1864,7 @@ static int i7core_mce_check_error(void *priv, struct mce *mce) if (mce->mcgstatus & 1) i7core_check_error(mci); - /* Advice mcelog that the error were handled */ + /* Advise mcelog that the errors were handled */ return 1; } -- cgit v1.2.3 From 6dc47e97a064c4fc0e324fc4accc90415c1509b2 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 28 Dec 2010 02:14:25 +0000 Subject: ASoC: One more x86 typo fix Signed-off-by: Mark Brown --- sound/soc/codecs/wm8962.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c index e2177144b714..aa1192f6aa9c 100644 --- a/sound/soc/codecs/wm8962.c +++ b/sound/soc/codecs/wm8962.c @@ -3354,7 +3354,7 @@ static irqreturn_t wm8962_irq(int irq, void *data) if (active & (WM8962_MICSCD_EINT | WM8962_MICD_EINT)) { dev_dbg(codec->dev, "Microphone event detected\n"); -#ifndef CONFIG_SOUND_SOC_WM8962_MODULE +#ifndef CONFIG_SND_SOC_WM8962_MODULE trace_snd_soc_jack_irq(dev_name(codec->dev)); #endif -- cgit v1.2.3 From 8ad225e8e4f530f500c12ec77fd5a51caf6a2f66 Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Tue, 28 Dec 2010 22:56:26 +1100 Subject: crypto: gf128mul - Remove experimental tag MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This feature no longer needs the experimental tag. Reported-by: Toralf Förster Signed-off-by: Herbert Xu --- crypto/Kconfig | 1 - 1 file changed, 1 deletion(-) diff --git a/crypto/Kconfig b/crypto/Kconfig index 96b0e5542121..4b7cb0e691cd 100644 --- a/crypto/Kconfig +++ b/crypto/Kconfig @@ -110,7 +110,6 @@ config CRYPTO_MANAGER_DISABLE_TESTS config CRYPTO_GF128MUL tristate "GF(2^128) multiplication functions (EXPERIMENTAL)" - depends on EXPERIMENTAL help Efficient table driven implementation of multiplications in the field GF(2^128). This is needed by some cypher modes. This -- cgit v1.2.3 From bb9fb42029abcc90c265dbc40cab106421dd9348 Mon Sep 17 00:00:00 2001 From: Jiri Kosina Date: Tue, 28 Dec 2010 14:16:15 +0100 Subject: Revert conflicting V4L changes This is a partial revert of b595076a180a56d1bb1 ("tree-wide: fix comment/printk typos"), as it changes the code that no longer exists in linux-next. Reported-by: Stephen Rothwell Signed-off-by: Jiri Kosina --- drivers/media/video/zoran/zoran.h | 2 +- drivers/staging/stradis/stradis.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/media/video/zoran/zoran.h b/drivers/media/video/zoran/zoran.h index b336259ce20c..27f05551183f 100644 --- a/drivers/media/video/zoran/zoran.h +++ b/drivers/media/video/zoran/zoran.h @@ -95,7 +95,7 @@ struct zoran_params { int quality; /* Measure for quality of compressed images. * Scales linearly with the size of the compressed images. - * Must be between 0 and 100, 100 is a compression + * Must be beetween 0 and 100, 100 is a compression * ratio of 1:4 */ int odd_even; /* Which field should come first ??? */ diff --git a/drivers/staging/stradis/stradis.c b/drivers/staging/stradis/stradis.c index 2e74355d1ea1..807dd7eb748f 100644 --- a/drivers/staging/stradis/stradis.c +++ b/drivers/staging/stradis/stradis.c @@ -745,7 +745,7 @@ static void set_out_format(struct saa7146 *saa, int mode) } } -/* Initialize bitmangler to map from a byte value to the mangled word that +/* Intialize bitmangler to map from a byte value to the mangled word that * must be output to program the Xilinx part through the DEBI port. * Xilinx Data Bit->DEBI Bit: 0->15 1->7 2->6 3->12 4->11 5->2 6->1 7->0 * transfer FPGA code, init IBM chip, transfer IBM microcode -- cgit v1.2.3 From eface65c336eff420d70beb0fb6787a732e05ffb Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Sat, 18 Dec 2010 18:42:23 +0100 Subject: [SCSI] sd: implement sd_check_events() Replace sd_media_change() with sd_check_events(). * Move media removed logic into set_media_not_present() and media_not_present() and set sdev->changed iff an existing media is removed or the device indicates UNIT_ATTENTION. * Make sd_check_events() sets sdev->changed if previously missing media becomes present. * Event is reported only if sdev->changed is set. This makes media presence event reported if scsi_disk->media_present actually changed or the device indicated UNIT_ATTENTION. For backward compatibility, SDEV_EVT_MEDIA_CHANGE is generated each time sd_check_events() detects media change event. [jejb: fix boot failure] Signed-off-by: Tejun Heo Acked-by: Jens Axboe Signed-off-by: James Bottomley --- drivers/scsi/sd.c | 104 ++++++++++++++++++++++++++++-------------------------- drivers/scsi/sd.h | 1 - 2 files changed, 53 insertions(+), 52 deletions(-) diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index b65e65aa07eb..7d257465bd98 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -990,30 +990,51 @@ out: static void set_media_not_present(struct scsi_disk *sdkp) { - sdkp->media_present = 0; - sdkp->capacity = 0; - sdkp->device->changed = 1; + if (sdkp->media_present) + sdkp->device->changed = 1; + + if (sdkp->device->removable) { + sdkp->media_present = 0; + sdkp->capacity = 0; + } +} + +static int media_not_present(struct scsi_disk *sdkp, + struct scsi_sense_hdr *sshdr) +{ + if (!scsi_sense_valid(sshdr)) + return 0; + + /* not invoked for commands that could return deferred errors */ + switch (sshdr->sense_key) { + case UNIT_ATTENTION: + case NOT_READY: + /* medium not present */ + if (sshdr->asc == 0x3A) { + set_media_not_present(sdkp); + return 1; + } + } + return 0; } /** - * sd_media_changed - check if our medium changed - * @disk: kernel device descriptor + * sd_check_events - check media events + * @disk: kernel device descriptor + * @clearing: disk events currently being cleared * - * Returns 0 if not applicable or no change; 1 if change + * Returns mask of DISK_EVENT_*. * * Note: this function is invoked from the block subsystem. **/ -static int sd_media_changed(struct gendisk *disk) +static unsigned int sd_check_events(struct gendisk *disk, unsigned int clearing) { struct scsi_disk *sdkp = scsi_disk(disk); struct scsi_device *sdp = sdkp->device; struct scsi_sense_hdr *sshdr = NULL; int retval; - SCSI_LOG_HLQUEUE(3, sd_printk(KERN_INFO, sdkp, "sd_media_changed\n")); - - if (!sdp->removable) - return 0; + SCSI_LOG_HLQUEUE(3, sd_printk(KERN_INFO, sdkp, "sd_check_events\n")); /* * If the device is offline, don't send any commands - just pretend as @@ -1043,40 +1064,37 @@ static int sd_media_changed(struct gendisk *disk) sshdr); } - if (retval) { + /* failed to execute TUR, assume media not present */ + if (host_byte(retval)) { set_media_not_present(sdkp); goto out; } + if (media_not_present(sdkp, sshdr)) + goto out; + /* * For removable scsi disk we have to recognise the presence - * of a disk in the drive. This is kept in the struct scsi_disk - * struct and tested at open ! Daniel Roche (dan@lectra.fr) + * of a disk in the drive. */ + if (!sdkp->media_present) + sdp->changed = 1; sdkp->media_present = 1; - out: /* - * Report a media change under the following conditions: + * sdp->changed is set under the following conditions: * - * Medium is present now and wasn't present before. - * Medium wasn't present before and is present now. - * Medium was present at all times, but it changed while - * we weren't looking (sdp->changed is set). + * Medium present state has changed in either direction. + * Device has indicated UNIT_ATTENTION. * - * If there was no medium before and there is no medium now then - * don't report a change, even if a medium was inserted and removed - * while we weren't looking. + * Report SDEV_EVT_MEDIA_CHANGE too for backward compatibility. */ - retval = (sdkp->media_present != sdkp->previous_state || - (sdkp->media_present && sdp->changed)); - if (retval) + if (sdp->changed) sdev_evt_send_simple(sdp, SDEV_EVT_MEDIA_CHANGE, GFP_KERNEL); - sdkp->previous_state = sdkp->media_present; - - /* sdp->changed indicates medium was changed or is not present */ - sdp->changed = !sdkp->media_present; kfree(sshdr); + + retval = sdp->changed ? DISK_EVENT_MEDIA_CHANGE : 0; + sdp->changed = 0; return retval; } @@ -1169,7 +1187,7 @@ static const struct block_device_operations sd_fops = { #ifdef CONFIG_COMPAT .compat_ioctl = sd_compat_ioctl, #endif - .media_changed = sd_media_changed, + .check_events = sd_check_events, .revalidate_disk = sd_revalidate_disk, .unlock_native_capacity = sd_unlock_native_capacity, }; @@ -1312,23 +1330,6 @@ static int sd_done(struct scsi_cmnd *SCpnt) return good_bytes; } -static int media_not_present(struct scsi_disk *sdkp, - struct scsi_sense_hdr *sshdr) -{ - - if (!scsi_sense_valid(sshdr)) - return 0; - /* not invoked for commands that could return deferred errors */ - if (sshdr->sense_key != NOT_READY && - sshdr->sense_key != UNIT_ATTENTION) - return 0; - if (sshdr->asc != 0x3A) /* medium not present */ - return 0; - - set_media_not_present(sdkp); - return 1; -} - /* * spinup disk - called only in sd_revalidate_disk() */ @@ -1503,7 +1504,7 @@ static void read_capacity_error(struct scsi_disk *sdkp, struct scsi_device *sdp, */ if (sdp->removable && sense_valid && sshdr->sense_key == NOT_READY) - sdp->changed = 1; + set_media_not_present(sdkp); /* * We used to set media_present to 0 here to indicate no media @@ -2389,8 +2390,10 @@ static void sd_probe_async(void *data, async_cookie_t cookie) gd->driverfs_dev = &sdp->sdev_gendev; gd->flags = GENHD_FL_EXT_DEVT; - if (sdp->removable) + if (sdp->removable) { gd->flags |= GENHD_FL_REMOVABLE; + gd->events |= DISK_EVENT_MEDIA_CHANGE; + } add_disk(gd); sd_dif_config_host(sdkp); @@ -2472,7 +2475,6 @@ static int sd_probe(struct device *dev) sdkp->disk = gd; sdkp->index = index; atomic_set(&sdkp->openers, 0); - sdkp->previous_state = 1; if (!sdp->request_queue->rq_timeout) { if (sdp->type != TYPE_MOD) diff --git a/drivers/scsi/sd.h b/drivers/scsi/sd.h index 55488faf0815..c9d8f6ca49e2 100644 --- a/drivers/scsi/sd.h +++ b/drivers/scsi/sd.h @@ -55,7 +55,6 @@ struct scsi_disk { u8 media_present; u8 write_prot; u8 protection_type;/* Data Integrity Field */ - unsigned previous_state : 1; unsigned ATO : 1; /* state of disk ATO bit */ unsigned WCE : 1; /* state of disk WCE bit */ unsigned RCD : 1; /* state of disk RCD bit, unused */ -- cgit v1.2.3 From 75c1c91cb92806f960fcd6e53d2a0c21f343081c Mon Sep 17 00:00:00 2001 From: Dimitri Sivanich Date: Tue, 28 Dec 2010 13:34:42 -0600 Subject: [IA64] eliminate race condition in smp_flush_tlb_mm A race condition exists within smp_call_function_many() when called from smp_flush_tlb_mm(). On rare occasions the cpu_vm_mask can be cleared while smp_call_function_many is executing, occasionally resulting in a hung process. Make a copy of the mask prior to calling smp_call_function_many(). Signed-off-by: Dimitri Sivanich Signed-off-by: Tony Luck --- arch/ia64/kernel/smp.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/arch/ia64/kernel/smp.c b/arch/ia64/kernel/smp.c index dabeefe21134..be450a3e9871 100644 --- a/arch/ia64/kernel/smp.c +++ b/arch/ia64/kernel/smp.c @@ -293,6 +293,7 @@ smp_flush_tlb_all (void) void smp_flush_tlb_mm (struct mm_struct *mm) { + cpumask_var_t cpus; preempt_disable(); /* this happens for the common case of a single-threaded fork(): */ if (likely(mm == current->active_mm && atomic_read(&mm->mm_users) == 1)) @@ -301,9 +302,15 @@ smp_flush_tlb_mm (struct mm_struct *mm) preempt_enable(); return; } - - smp_call_function_many(mm_cpumask(mm), - (void (*)(void *))local_finish_flush_tlb_mm, mm, 1); + if (!alloc_cpumask_var(&cpus, GFP_ATOMIC)) { + smp_call_function((void (*)(void *))local_finish_flush_tlb_mm, + mm, 1); + } else { + cpumask_copy(cpus, mm_cpumask(mm)); + smp_call_function_many(cpus, + (void (*)(void *))local_finish_flush_tlb_mm, mm, 1); + free_cpumask_var(cpus); + } local_irq_disable(); local_finish_flush_tlb_mm(mm); local_irq_enable(); -- cgit v1.2.3 From e21763dbce76d3a07ead438f8811b3e4bce0825b Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Sat, 30 Oct 2010 21:35:58 +0200 Subject: [IA64] perfmon: Change vmalloc to vzalloc and drop memset. vzalloc() nicely zeroes memory for us, so we don't have to do a vmalloc() and then manually memset() the returned memory when all we want is for it to be zero. Patch changes this for pfm_rvmalloc(). Signed-off-by: Jesper Juhl Signed-off-by: Tony Luck --- arch/ia64/kernel/perfmon.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/arch/ia64/kernel/perfmon.c b/arch/ia64/kernel/perfmon.c index 39e534f5a3b0..3aee09d2c2de 100644 --- a/arch/ia64/kernel/perfmon.c +++ b/arch/ia64/kernel/perfmon.c @@ -829,10 +829,9 @@ pfm_rvmalloc(unsigned long size) unsigned long addr; size = PAGE_ALIGN(size); - mem = vmalloc(size); + mem = vzalloc(size); if (mem) { //printk("perfmon: CPU%d pfm_rvmalloc(%ld)=%p\n", smp_processor_id(), size, mem); - memset(mem, 0, size); addr = (unsigned long)mem; while (size > 0) { pfm_reserve_page(addr); -- cgit v1.2.3 From 409e590572d980c314e989e94176bcb060130fae Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Mon, 22 Nov 2010 10:41:19 +0100 Subject: [IA64] irq_ia64, use set_irq_chip Don't access desc->chip directly, because them chip member will disappear some time later. Signed-off-by: Jiri Slaby Cc: Thomas Gleixner Signed-off-by: Tony Luck --- arch/ia64/kernel/irq_ia64.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/ia64/kernel/irq_ia64.c b/arch/ia64/kernel/irq_ia64.c index 9a26015c3e50..38c07b866901 100644 --- a/arch/ia64/kernel/irq_ia64.c +++ b/arch/ia64/kernel/irq_ia64.c @@ -633,7 +633,7 @@ ia64_native_register_percpu_irq (ia64_vector vec, struct irqaction *action) BUG_ON(bind_irq_vector(irq, vec, CPU_MASK_ALL)); desc = irq_desc + irq; desc->status |= IRQ_PER_CPU; - desc->chip = &irq_type_ia64_lsapic; + set_irq_chip(irq, &irq_type_ia64_lsapic); if (action) setup_irq(irq, action); set_irq_handler(irq, handle_percpu_irq); -- cgit v1.2.3 From e7d282535c94cddc208c03b7cd0815f70d676a0e Mon Sep 17 00:00:00 2001 From: Joe Perches Date: Thu, 9 Dec 2010 23:16:55 -0800 Subject: [IA64] Remove unlikely from cpu_is_offline cpu_is_offline already uses unlikely internally. Signed-off-by: Joe Perches Signed-off-by: Tony Luck --- arch/ia64/kernel/time.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/ia64/kernel/time.c b/arch/ia64/kernel/time.c index ed6f22eb5b12..9702fa92489e 100644 --- a/arch/ia64/kernel/time.c +++ b/arch/ia64/kernel/time.c @@ -168,7 +168,7 @@ timer_interrupt (int irq, void *dev_id) { unsigned long new_itm; - if (unlikely(cpu_is_offline(smp_processor_id()))) { + if (cpu_is_offline(smp_processor_id())) { return IRQ_HANDLED; } -- cgit v1.2.3 From 839d271c509b6ce5c1da8a8e89fad73a1af0ddda Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Tue, 28 Dec 2010 21:37:55 +0100 Subject: ASoC: codecs: Remove unused reg_cache fields from device structs The multi-component patch(commit f0fba2ad1) moved the allocation of the register cache from the driver to the ASoC core. Most drivers where adjusted to this, but there are quite a few drivers left which now have an unused reg_cache field in their private device struct. This patch removes these unused fields. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown --- sound/soc/codecs/88pm860x-codec.c | 1 - sound/soc/codecs/ad193x.c | 1 - sound/soc/codecs/ak4671.c | 1 - sound/soc/codecs/cs4270.c | 1 - sound/soc/codecs/cs42l51.c | 1 - sound/soc/codecs/cx20442.c | 1 - sound/soc/codecs/tlv320aic26.c | 4 +--- sound/soc/codecs/uda1380.c | 1 - sound/soc/codecs/wm8580.c | 1 - sound/soc/codecs/wm8711.c | 1 - sound/soc/codecs/wm8731.c | 1 - sound/soc/codecs/wm8750.c | 1 - sound/soc/codecs/wm8900.c | 1 - sound/soc/codecs/wm8903.c | 2 -- sound/soc/codecs/wm8940.c | 1 - sound/soc/codecs/wm8960.c | 1 - sound/soc/codecs/wm8961.c | 1 - sound/soc/codecs/wm8974.c | 1 - sound/soc/codecs/wm8978.c | 1 - sound/soc/codecs/wm8988.c | 1 - sound/soc/codecs/wm8993.c | 1 - sound/soc/codecs/wm9081.c | 1 - 22 files changed, 1 insertion(+), 25 deletions(-) diff --git a/sound/soc/codecs/88pm860x-codec.c b/sound/soc/codecs/88pm860x-codec.c index 3e798a12ee3d..5da8207a6961 100644 --- a/sound/soc/codecs/88pm860x-codec.c +++ b/sound/soc/codecs/88pm860x-codec.c @@ -146,7 +146,6 @@ struct pm860x_priv { int irq[4]; unsigned char name[4][MAX_NAME_LEN]; - unsigned char reg_cache[REG_CACHE_SIZE]; }; /* -9450dB to 0dB in 150dB steps ( mute instead of -9450dB) */ diff --git a/sound/soc/codecs/ad193x.c b/sound/soc/codecs/ad193x.c index a007bd7326fd..da46479bfcfa 100644 --- a/sound/soc/codecs/ad193x.c +++ b/sound/soc/codecs/ad193x.c @@ -23,7 +23,6 @@ /* codec private data */ struct ad193x_priv { - u8 reg_cache[AD193X_NUM_REGS]; enum snd_soc_control_type bus_type; void *control_data; int sysclk; diff --git a/sound/soc/codecs/ak4671.c b/sound/soc/codecs/ak4671.c index 4faf10553a30..2ec75abfa3e9 100644 --- a/sound/soc/codecs/ak4671.c +++ b/sound/soc/codecs/ak4671.c @@ -27,7 +27,6 @@ struct ak4671_priv { enum snd_soc_control_type control_type; void *control_data; - u8 reg_cache[AK4671_CACHEREGNUM]; }; /* ak4671 register cache & default register settings */ diff --git a/sound/soc/codecs/cs4270.c b/sound/soc/codecs/cs4270.c index 6d4bdc609ac8..3a582caa6ef9 100644 --- a/sound/soc/codecs/cs4270.c +++ b/sound/soc/codecs/cs4270.c @@ -114,7 +114,6 @@ static const char *supply_names[] = { struct cs4270_private { enum snd_soc_control_type control_type; void *control_data; - u8 reg_cache[CS4270_NUMREGS]; unsigned int mclk; /* Input frequency of the MCLK pin */ unsigned int mode; /* The mode (I2S or left-justified) */ unsigned int slave_mode; diff --git a/sound/soc/codecs/cs42l51.c b/sound/soc/codecs/cs42l51.c index d4e60dc45bf6..8fb7070108dd 100644 --- a/sound/soc/codecs/cs42l51.c +++ b/sound/soc/codecs/cs42l51.c @@ -46,7 +46,6 @@ struct cs42l51_private { unsigned int mclk; unsigned int audio_mode; /* The mode (I2S or left-justified) */ enum master_slave_mode func; - u8 reg_cache[CS42L51_NUMREGS]; }; #define CS42L51_FORMATS ( \ diff --git a/sound/soc/codecs/cx20442.c b/sound/soc/codecs/cx20442.c index a9521acad99c..03d1e860d229 100644 --- a/sound/soc/codecs/cx20442.c +++ b/sound/soc/codecs/cx20442.c @@ -26,7 +26,6 @@ struct cx20442_priv { enum snd_soc_control_type control_type; void *control_data; - u8 reg_cache[1]; }; #define CX20442_PM 0x0 diff --git a/sound/soc/codecs/tlv320aic26.c b/sound/soc/codecs/tlv320aic26.c index 68f0ae47f608..e2a7608d3944 100644 --- a/sound/soc/codecs/tlv320aic26.c +++ b/sound/soc/codecs/tlv320aic26.c @@ -30,7 +30,6 @@ MODULE_LICENSE("GPL"); struct aic26 { struct spi_device *spi; struct snd_soc_codec codec; - u16 reg_cache[AIC26_NUM_REGS]; /* shadow registers */ int master; int datfm; int mclk; @@ -354,7 +353,6 @@ static DEVICE_ATTR(keyclick, 0644, aic26_keyclick_show, aic26_keyclick_set); */ static int aic26_probe(struct snd_soc_codec *codec) { - struct aic26 *aic26 = snd_soc_codec_get_drvdata(codec); int ret, err, i, reg; dev_info(codec->dev, "Probing AIC26 SoC CODEC driver\n"); @@ -372,7 +370,7 @@ static int aic26_probe(struct snd_soc_codec *codec) aic26_reg_write(codec, AIC26_REG_AUDIO_CTRL3, reg); /* Fill register cache */ - for (i = 0; i < ARRAY_SIZE(aic26->reg_cache); i++) + for (i = 0; i < codec->driver->reg_cache_size; i++) aic26_reg_read(codec, i); /* Register the sysfs files for debugging */ diff --git a/sound/soc/codecs/uda1380.c b/sound/soc/codecs/uda1380.c index 800980e2e9ab..c5ca8cfea60f 100644 --- a/sound/soc/codecs/uda1380.c +++ b/sound/soc/codecs/uda1380.c @@ -35,7 +35,6 @@ /* codec private data */ struct uda1380_priv { struct snd_soc_codec *codec; - u16 reg_cache[UDA1380_CACHEREGNUM]; unsigned int dac_clk; struct work_struct work; void *control_data; diff --git a/sound/soc/codecs/wm8580.c b/sound/soc/codecs/wm8580.c index 0ebdecfd27a9..8f6b5ee6645b 100644 --- a/sound/soc/codecs/wm8580.c +++ b/sound/soc/codecs/wm8580.c @@ -190,7 +190,6 @@ static const char *wm8580_supply_names[WM8580_NUM_SUPPLIES] = { struct wm8580_priv { enum snd_soc_control_type control_type; struct regulator_bulk_data supplies[WM8580_NUM_SUPPLIES]; - u16 reg_cache[WM8580_MAX_REGISTER + 1]; struct pll_state a; struct pll_state b; int sysclk[2]; diff --git a/sound/soc/codecs/wm8711.c b/sound/soc/codecs/wm8711.c index fec37ebfdb34..97c30382d3ff 100644 --- a/sound/soc/codecs/wm8711.c +++ b/sound/soc/codecs/wm8711.c @@ -33,7 +33,6 @@ /* codec private data */ struct wm8711_priv { enum snd_soc_control_type bus_type; - u16 reg_cache[WM8711_CACHEREGNUM]; unsigned int sysclk; }; diff --git a/sound/soc/codecs/wm8731.c b/sound/soc/codecs/wm8731.c index 71122dc36826..0a67c31b2663 100644 --- a/sound/soc/codecs/wm8731.c +++ b/sound/soc/codecs/wm8731.c @@ -43,7 +43,6 @@ static const char *wm8731_supply_names[WM8731_NUM_SUPPLIES] = { struct wm8731_priv { enum snd_soc_control_type control_type; struct regulator_bulk_data supplies[WM8731_NUM_SUPPLIES]; - u16 reg_cache[WM8731_CACHEREGNUM]; unsigned int sysclk; int sysclk_type; int playback_fs; diff --git a/sound/soc/codecs/wm8750.c b/sound/soc/codecs/wm8750.c index 51280e96d721..38f38fddd190 100644 --- a/sound/soc/codecs/wm8750.c +++ b/sound/soc/codecs/wm8750.c @@ -52,7 +52,6 @@ static const u16 wm8750_reg[] = { struct wm8750_priv { unsigned int sysclk; enum snd_soc_control_type control_type; - u16 reg_cache[ARRAY_SIZE(wm8750_reg)]; }; #define wm8750_reset(c) snd_soc_write(c, WM8750_RESET, 0) diff --git a/sound/soc/codecs/wm8900.c b/sound/soc/codecs/wm8900.c index cfbaac1a0ead..cd0959926d12 100644 --- a/sound/soc/codecs/wm8900.c +++ b/sound/soc/codecs/wm8900.c @@ -139,7 +139,6 @@ struct wm8900_priv { enum snd_soc_control_type control_type; - u16 reg_cache[WM8900_MAXREG]; u32 fll_in; /* FLL input frequency */ u32 fll_out; /* FLL output frequency */ diff --git a/sound/soc/codecs/wm8903.c b/sound/soc/codecs/wm8903.c index b9843f72c455..987476a5895f 100644 --- a/sound/soc/codecs/wm8903.c +++ b/sound/soc/codecs/wm8903.c @@ -214,8 +214,6 @@ static u16 wm8903_reg_defaults[] = { struct wm8903_priv { - u16 reg_cache[ARRAY_SIZE(wm8903_reg_defaults)]; - int sysclk; int irq; diff --git a/sound/soc/codecs/wm8940.c b/sound/soc/codecs/wm8940.c index 381934fff4ec..fc7761fa8bd3 100644 --- a/sound/soc/codecs/wm8940.c +++ b/sound/soc/codecs/wm8940.c @@ -42,7 +42,6 @@ struct wm8940_priv { unsigned int sysclk; - u16 reg_cache[WM8940_CACHEREGNUM]; enum snd_soc_control_type control_type; void *control_data; }; diff --git a/sound/soc/codecs/wm8960.c b/sound/soc/codecs/wm8960.c index 054f5737319c..2bb856156eda 100644 --- a/sound/soc/codecs/wm8960.c +++ b/sound/soc/codecs/wm8960.c @@ -71,7 +71,6 @@ static const u16 wm8960_reg[WM8960_CACHEREGNUM] = { }; struct wm8960_priv { - u16 reg_cache[WM8960_CACHEREGNUM]; enum snd_soc_control_type control_type; void *control_data; int (*set_bias_level)(struct snd_soc_codec *, diff --git a/sound/soc/codecs/wm8961.c b/sound/soc/codecs/wm8961.c index 6b22ef200e20..55252e7d02c9 100644 --- a/sound/soc/codecs/wm8961.c +++ b/sound/soc/codecs/wm8961.c @@ -289,7 +289,6 @@ static u16 wm8961_reg_defaults[] = { struct wm8961_priv { enum snd_soc_control_type control_type; int sysclk; - u16 reg_cache[WM8961_MAX_REGISTER]; }; static int wm8961_volatile_register(unsigned int reg) diff --git a/sound/soc/codecs/wm8974.c b/sound/soc/codecs/wm8974.c index 5d286427532a..ca646a822444 100644 --- a/sound/soc/codecs/wm8974.c +++ b/sound/soc/codecs/wm8974.c @@ -51,7 +51,6 @@ static const u16 wm8974_reg[WM8974_CACHEREGNUM] = { struct wm8974_priv { enum snd_soc_control_type control_type; - u16 reg_cache[WM8974_CACHEREGNUM]; }; #define wm8974_reset(c) snd_soc_write(c, WM8974_RESET, 0) diff --git a/sound/soc/codecs/wm8978.c b/sound/soc/codecs/wm8978.c index a195af92b425..4bbc3442703f 100644 --- a/sound/soc/codecs/wm8978.c +++ b/sound/soc/codecs/wm8978.c @@ -59,7 +59,6 @@ struct wm8978_priv { unsigned int f_opclk; int mclk_idx; enum wm8978_sysclk_src sysclk; - u16 reg_cache[WM8978_CACHEREGNUM]; }; static const char *wm8978_companding[] = {"Off", "NC", "u-law", "A-law"}; diff --git a/sound/soc/codecs/wm8988.c b/sound/soc/codecs/wm8988.c index 65807b15a2cc..d7170f1381aa 100644 --- a/sound/soc/codecs/wm8988.c +++ b/sound/soc/codecs/wm8988.c @@ -53,7 +53,6 @@ struct wm8988_priv { unsigned int sysclk; enum snd_soc_control_type control_type; struct snd_pcm_hw_constraint_list *sysclk_constraints; - u16 reg_cache[WM8988_NUM_REG]; }; diff --git a/sound/soc/codecs/wm8993.c b/sound/soc/codecs/wm8993.c index 15f34a26debf..18c0d9ce7c32 100644 --- a/sound/soc/codecs/wm8993.c +++ b/sound/soc/codecs/wm8993.c @@ -225,7 +225,6 @@ static struct { struct wm8993_priv { struct wm_hubs_data hubs_data; - u16 reg_cache[WM8993_REGISTER_COUNT]; struct regulator_bulk_data supplies[WM8993_NUM_SUPPLIES]; struct wm8993_platform_data pdata; enum snd_soc_control_type control_type; diff --git a/sound/soc/codecs/wm9081.c b/sound/soc/codecs/wm9081.c index e5055b28c638..702db6937d4f 100644 --- a/sound/soc/codecs/wm9081.c +++ b/sound/soc/codecs/wm9081.c @@ -157,7 +157,6 @@ static struct { struct wm9081_priv { enum snd_soc_control_type control_type; void *control_data; - u16 reg_cache[WM9081_MAX_REGISTER + 1]; int sysclk_source; int mclk_rate; int sysclk_rate; -- cgit v1.2.3 From b1cd916ab96e5fcd16e2009410af2e8edfae2962 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Fri, 24 Dec 2010 09:33:33 +1000 Subject: drm/nvc0: kill off a couple more magics Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvc0_graph.c | 14 +------------- drivers/gpu/drm/nouveau/nvc0_graph.h | 2 -- drivers/gpu/drm/nouveau/nvc0_grctx.c | 24 ++++++++++++++++++++---- 3 files changed, 21 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nvc0_graph.c b/drivers/gpu/drm/nouveau/nvc0_graph.c index cf2f6aa920b4..f03c17a10ab9 100644 --- a/drivers/gpu/drm/nouveau/nvc0_graph.c +++ b/drivers/gpu/drm/nouveau/nvc0_graph.c @@ -334,8 +334,6 @@ nvc0_graph_create(struct drm_device *dev) case 0xc0: if (priv->tp_total == 11) { /* 465, 3/4/4/0, 4 */ priv->magic_not_rop_nr = 0x07; - priv->magic419bd0 = 0x0a360000; - priv->magic419be4 = 0x04c33a54; /* filled values up to tp_total, the rest 0 */ priv->magicgpc980[0] = 0x22111000; priv->magicgpc980[1] = 0x00000233; @@ -345,8 +343,6 @@ nvc0_graph_create(struct drm_device *dev) } else if (priv->tp_total == 14) { /* 470, 3/3/4/4, 5 */ priv->magic_not_rop_nr = 0x05; - priv->magic419bd0 = 0x043c0000; - priv->magic419be4 = 0x09041208; priv->magicgpc980[0] = 0x11110000; priv->magicgpc980[1] = 0x00233222; priv->magicgpc980[2] = 0x00000000; @@ -355,8 +351,6 @@ nvc0_graph_create(struct drm_device *dev) } else if (priv->tp_total == 15) { /* 480, 3/4/4/4, 6 */ priv->magic_not_rop_nr = 0x06; - priv->magic419bd0 = 0x023e0000; - priv->magic419be4 = 0x10414104; priv->magicgpc980[0] = 0x11110000; priv->magicgpc980[1] = 0x03332222; priv->magicgpc980[2] = 0x00000000; @@ -366,8 +360,6 @@ nvc0_graph_create(struct drm_device *dev) break; case 0xc3: /* 450, 4/0/0/0, 2 */ priv->magic_not_rop_nr = 0x03; - priv->magic419bd0 = 0x00500000; - priv->magic419be4 = 0x00000000; priv->magicgpc980[0] = 0x00003210; priv->magicgpc980[1] = 0x00000000; priv->magicgpc980[2] = 0x00000000; @@ -376,8 +368,6 @@ nvc0_graph_create(struct drm_device *dev) break; case 0xc4: /* 460, 3/4/0/0, 4 */ priv->magic_not_rop_nr = 0x01; - priv->magic419bd0 = 0x045c0000; - priv->magic419be4 = 0x09041208; priv->magicgpc980[0] = 0x02321100; priv->magicgpc980[1] = 0x00000000; priv->magicgpc980[2] = 0x00000000; @@ -386,14 +376,12 @@ nvc0_graph_create(struct drm_device *dev) break; } - if (!priv->magic419bd0) { + if (!priv->magic_not_rop_nr) { NV_ERROR(dev, "PGRAPH: unknown config: %d/%d/%d/%d, %d\n", priv->tp_nr[0], priv->tp_nr[1], priv->tp_nr[2], priv->tp_nr[3], priv->rop_nr); /* use 0xc3's values... */ priv->magic_not_rop_nr = 0x03; - priv->magic419bd0 = 0x00500000; - priv->magic419be4 = 0x00000000; priv->magicgpc980[0] = 0x00003210; priv->magicgpc980[1] = 0x00000000; priv->magicgpc980[2] = 0x00000000; diff --git a/drivers/gpu/drm/nouveau/nvc0_graph.h b/drivers/gpu/drm/nouveau/nvc0_graph.h index 1e1f24f3fd34..40e26f9c56c4 100644 --- a/drivers/gpu/drm/nouveau/nvc0_graph.h +++ b/drivers/gpu/drm/nouveau/nvc0_graph.h @@ -46,8 +46,6 @@ struct nvc0_graph_priv { struct nouveau_gpuobj *unk4188b8; u8 magic_not_rop_nr; - u32 magic419bd0; - u32 magic419be4; u32 magicgpc980[4]; u32 magicgpc918; }; diff --git a/drivers/gpu/drm/nouveau/nvc0_grctx.c b/drivers/gpu/drm/nouveau/nvc0_grctx.c index 88fa6211ac19..fddfab73a58d 100644 --- a/drivers/gpu/drm/nouveau/nvc0_grctx.c +++ b/drivers/gpu/drm/nouveau/nvc0_grctx.c @@ -1875,9 +1875,11 @@ nvc0_grctx_generate(struct nouveau_channel *chan) } if (1) { - u32 data[6] = {}; + u32 data[6] = {}, data2[2] = {}; u8 tpnr[GPC_MAX]; + u8 shift, ntpcv; + /* calculate first set of magics */ memcpy(tpnr, priv->tp_nr, sizeof(priv->tp_nr)); for (tp = 0; tp < priv->tp_total; tp++) { @@ -1892,6 +1894,20 @@ nvc0_grctx_generate(struct nouveau_channel *chan) for (; tp < 32; tp++) data[tp / 6] |= 7 << ((tp % 6) * 5); + /* and the second... */ + shift = 0; + ntpcv = priv->tp_total; + while (!(ntpcv & (1 << 4))) { + ntpcv <<= 1; + shift++; + } + + data2[0] = (ntpcv << 16); + data2[0] |= (shift << 21); + data2[0] |= (((1 << (0 + 5)) % ntpcv) << 24); + for (i = 1; i < 7; i++) + data2[1] |= ((1 << (i + 5)) % ntpcv) << ((i - 1) * 5); + // GPC_BROADCAST nv_wr32(dev, 0x418bb8, (priv->tp_total << 8) | priv->magic_not_rop_nr); @@ -1900,9 +1916,9 @@ nvc0_grctx_generate(struct nouveau_channel *chan) // GPC_BROADCAST.TP_BROADCAST nv_wr32(dev, 0x419bd0, (priv->tp_total << 8) | - priv->magic_not_rop_nr | - priv->magic419bd0); - nv_wr32(dev, 0x419be4, priv->magic419be4); + priv->magic_not_rop_nr | + data2[0]); + nv_wr32(dev, 0x419be4, data2[1]); for (i = 0; i < 6; i++) nv_wr32(dev, 0x419b00 + (i * 4), data[i]); -- cgit v1.2.3 From 93d0cd7b9e4855c12b3bb5c9367872476c78fef9 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 29 Dec 2010 10:41:20 +1000 Subject: drm/nvc0: nuke left-over debug messages Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/nvc0_fbcon.c | 2 -- drivers/gpu/drm/nouveau/nvc0_graph.c | 1 - 2 files changed, 3 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nvc0_fbcon.c b/drivers/gpu/drm/nouveau/nvc0_fbcon.c index cbb4a1ae20b1..fa5d4c234383 100644 --- a/drivers/gpu/drm/nouveau/nvc0_fbcon.c +++ b/drivers/gpu/drm/nouveau/nvc0_fbcon.c @@ -200,8 +200,6 @@ nvc0_fbcon_accel_init(struct fb_info *info) return ret; } - printk(KERN_ERR "fb vma 0x%010llx\n", nvbo->vma.offset); - BEGIN_NVC0(chan, 2, NvSub2D, 0x0000, 1); OUT_RING (chan, 0x0000902d); BEGIN_NVC0(chan, 2, NvSub2D, 0x0104, 2); diff --git a/drivers/gpu/drm/nouveau/nvc0_graph.c b/drivers/gpu/drm/nouveau/nvc0_graph.c index f03c17a10ab9..c28bc7b04d27 100644 --- a/drivers/gpu/drm/nouveau/nvc0_graph.c +++ b/drivers/gpu/drm/nouveau/nvc0_graph.c @@ -244,7 +244,6 @@ nvc0_graph_load_context(struct nouveau_channel *chan) if (!nv_wait(dev, 0x409800, 0x00000010, 0x00000010)) NV_ERROR(dev, "PGRAPH: load_ctx timeout\n"); - printk(KERN_ERR "load_ctx 0x%08x\n", nv_rd32(dev, 0x409b00)); return 0; } -- cgit v1.2.3 From 6c39d116ba308ccf9007773a090ca6d20eb68459 Mon Sep 17 00:00:00 2001 From: Dmitry Kasatkin Date: Wed, 29 Dec 2010 21:52:04 +1100 Subject: crypto: omap-sham - backlog handling fix Previous commit "removed redundant locking" introduced a bug in handling backlog. In certain cases, when async request complete callback will call complete() on -EINPROGRESS code, it will cause uncompleted requests. It does not happen in implementation similar to crypto test manager, but it will happen in implementation similar to dm-crypt. Backlog needs to be checked before dequeuing next request. Signed-off-by: Dmitry Kasatkin Signed-off-by: Herbert Xu --- drivers/crypto/omap-sham.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/drivers/crypto/omap-sham.c b/drivers/crypto/omap-sham.c index eb988e7a2fd9..2e71123516e0 100644 --- a/drivers/crypto/omap-sham.c +++ b/drivers/crypto/omap-sham.c @@ -664,7 +664,7 @@ static void omap_sham_finish_req(struct ahash_request *req, int err) static int omap_sham_handle_queue(struct omap_sham_dev *dd, struct ahash_request *req) { - struct crypto_async_request *async_req, *backlog = 0; + struct crypto_async_request *async_req, *backlog; struct omap_sham_reqctx *ctx; struct ahash_request *prev_req; unsigned long flags; @@ -677,11 +677,10 @@ static int omap_sham_handle_queue(struct omap_sham_dev *dd, spin_unlock_irqrestore(&dd->lock, flags); return ret; } + backlog = crypto_get_backlog(&dd->queue); async_req = crypto_dequeue_request(&dd->queue); - if (async_req) { + if (async_req) dd->flags |= FLAGS_BUSY; - backlog = crypto_get_backlog(&dd->queue); - } spin_unlock_irqrestore(&dd->lock, flags); if (!async_req) -- cgit v1.2.3 From cd8d60a20a4516016c117ac0f1ac7b06ff606f7e Mon Sep 17 00:00:00 2001 From: Theodore Ts'o Date: Fri, 24 Dec 2010 09:42:10 -0500 Subject: kbuild: create linux-headers package in deb-pkg Create a linux-headers-$KVER.deb package which can be used to build external modules without having the source tree around. Signed-off-by: "Theodore Ts'o" Signed-off-by: Michal Marek --- scripts/package/builddeb | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/scripts/package/builddeb b/scripts/package/builddeb index ffe24194b763..5fc1e6f71838 100644 --- a/scripts/package/builddeb +++ b/scripts/package/builddeb @@ -76,15 +76,17 @@ else fi tmpdir="$objtree/debian/tmp" fwdir="$objtree/debian/fwtmp" +hdrdir="$objtree/debian/hdrtmp" packagename=linux-image-$version fwpackagename=linux-firmware-image +hdrpackagename=linux-headers-$version if [ "$ARCH" = "um" ] ; then packagename=user-mode-linux-$version fi # Setup the directory structure -rm -rf "$tmpdir" "$fwdir" +rm -rf "$tmpdir" "$fwdir" "$hdrdir" mkdir -m 755 -p "$tmpdir/DEBIAN" mkdir -p "$tmpdir/lib" "$tmpdir/boot" "$tmpdir/usr/share/doc/$packagename" mkdir -m 755 -p "$fwdir/DEBIAN" @@ -226,6 +228,30 @@ EOF fi +# Build header package +find . -name Makefile -o -name Kconfig\* -o -name \*.pl > /tmp/files$$ +find arch/x86/include include scripts -type f >> /tmp/files$$ +(cd $objtree; find .config Module.symvers include scripts -type f >> /tmp/objfiles$$) +destdir=$hdrdir/usr/src/linux-headers-$version +mkdir -p "$destdir" "$hdrdir/DEBIAN" "$hdrdir/usr/share/doc/$hdrpackagename" +tar -c -f - -T /tmp/files$$ | (cd $destdir; tar -xf -) +(cd $objtree; tar -c -f - -T /tmp/objfiles$$) | (cd $destdir; tar -xf -) +rm -f /tmp/files$$ /tmp/objfiles$$ +arch=$(dpkg --print-architecture) + +cat <> debian/control + +Package: $hdrpackagename +Provides: linux-headers, linux-headers-2.6 +Architecture: $arch +Description: Linux kernel headers for $KERNELRELEASE on $arch + This package provides kernel header files for $KERNELRELEASE on $arch + . + This is useful for people who need to build external modules +EOF + +create_package "$hdrpackagename" "$hdrdir" + # Do we have firmware? Move it out of the way and build it into a package. if [ -e "$tmpdir/lib/firmware" ]; then mv "$tmpdir/lib/firmware" "$fwdir/lib/" -- cgit v1.2.3 From 7116f452c8e3e38f99ab3231a758eb366dacfe4a Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Wed, 29 Dec 2010 13:05:21 +0000 Subject: ASoC: Yet more x86 tracepoint workarounds Signed-off-by: Mark Brown --- sound/soc/codecs/88pm860x-codec.c | 2 +- sound/soc/codecs/wm8350.c | 2 ++ sound/soc/codecs/wm8994.c | 4 ++++ 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/sound/soc/codecs/88pm860x-codec.c b/sound/soc/codecs/88pm860x-codec.c index 5da8207a6961..06b6981b8d6d 100644 --- a/sound/soc/codecs/88pm860x-codec.c +++ b/sound/soc/codecs/88pm860x-codec.c @@ -1262,7 +1262,7 @@ static irqreturn_t pm860x_codec_handler(int irq, void *data) mask = pm860x->det.hs_shrt | pm860x->det.hook_det | pm860x->det.lo_shrt | pm860x->det.hp_det; -#ifndef CONFIG_SND_SOC_88PM860X +#ifndef CONFIG_SND_SOC_88PM860X_MODULE if (status & (HEADSET_STATUS | MIC_STATUS | SHORT_HS1 | SHORT_HS2 | SHORT_LO1 | SHORT_LO2)) trace_snd_soc_jack_irq(dev_name(pm860x->codec->dev)); diff --git a/sound/soc/codecs/wm8350.c b/sound/soc/codecs/wm8350.c index db07137bf3b9..6d6dc9efe914 100644 --- a/sound/soc/codecs/wm8350.c +++ b/sound/soc/codecs/wm8350.c @@ -1463,7 +1463,9 @@ static irqreturn_t wm8350_mic_handler(int irq, void *data) u16 reg; int report = 0; +#ifndef CONFIG_SND_SOC_WM8350_MODULE trace_snd_soc_jack_irq("WM8350 mic"); +#endif reg = wm8350_reg_read(wm8350, WM8350_JACK_PIN_STATUS); if (reg & WM8350_JACK_MICSCD_LVL) diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index 067a532bed15..247a6a99feb8 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c @@ -2756,7 +2756,9 @@ static irqreturn_t wm8994_mic_irq(int irq, void *data) int reg; int report; +#ifndef CONFIG_SND_SOC_WM8994_MODULE trace_snd_soc_jack_irq(dev_name(codec->dev)); +#endif reg = snd_soc_read(codec, WM8994_INTERRUPT_RAW_STATUS_2); if (reg < 0) { @@ -2904,7 +2906,9 @@ static irqreturn_t wm8958_mic_irq(int irq, void *data) goto out; } +#ifndef CONFIG_SND_SOC_WM8994_MODULE trace_snd_soc_jack_irq(dev_name(codec->dev)); +#endif if (wm8994->jack_cb) wm8994->jack_cb(reg, wm8994->jack_cb_data); -- cgit v1.2.3 From 644a98453d5764f467b73f2e02df0d2688da1873 Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Mon, 27 Dec 2010 13:42:20 +0900 Subject: fbdev: sh_mobile_hdmi: fixup compile error Signed-off-by: Kuninori Morimoto Signed-off-by: Mark Brown --- drivers/video/sh_mobile_hdmi.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/video/sh_mobile_hdmi.c b/drivers/video/sh_mobile_hdmi.c index d7df10315d8d..b19941d37ed4 100644 --- a/drivers/video/sh_mobile_hdmi.c +++ b/drivers/video/sh_mobile_hdmi.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include -- cgit v1.2.3 From 96aebafa63418f447ddc823e40da341cc40553dd Mon Sep 17 00:00:00 2001 From: Jesper Juhl Date: Fri, 24 Dec 2010 21:28:56 +0100 Subject: gen_init_cpio: Avoid race between call to stat() and call to open() In usr/gen_init_cpio.c::cpio_mkfile() a call to stat() is made based on pathname, subsequently the file is open()'ed and then the value of the initial stat() call is used to allocate a buffer. This is not safe since the file may change between the call to stat() and the call to open(). Safer to just open() the file and then do fstat() using the filedescriptor returned by open. Signed-off-by: Jesper Juhl Acked-by: Jeff Garzik Signed-off-by: Michal Marek --- usr/gen_init_cpio.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/usr/gen_init_cpio.c b/usr/gen_init_cpio.c index 59df70d9d1dc..f463cafdccb2 100644 --- a/usr/gen_init_cpio.c +++ b/usr/gen_init_cpio.c @@ -309,18 +309,18 @@ static int cpio_mkfile(const char *name, const char *location, mode |= S_IFREG; - retval = stat (location, &buf); - if (retval) { - fprintf (stderr, "File %s could not be located\n", location); - goto error; - } - file = open (location, O_RDONLY); if (file < 0) { fprintf (stderr, "File %s could not be opened for reading\n", location); goto error; } + retval = fstat (file, &buf); + if (retval) { + fprintf (stderr, "File %s could not be stat()'ed\n", location); + goto error; + } + filebuf = malloc(buf.st_size); if (!filebuf) { fprintf (stderr, "out of memory\n"); -- cgit v1.2.3 From 22b6dee842c6341b49bc09cc5728eb2f8f2b3766 Mon Sep 17 00:00:00 2001 From: Mi Jinlong Date: Mon, 27 Dec 2010 14:29:57 +0800 Subject: nfsd4: fix oops on secinfo_no_name result encoding The secinfo_no_name code oopses on encoding with BUG: unable to handle kernel NULL pointer dereference at 00000044 IP: [] nfsd4_encode_secinfo+0x1c/0x1c1 [nfsd] We should implement a nfsd4_encode_secinfo_no_name() instead using nfsd4_encode_secinfo(). Signed-off-by: Mi Jinlong Signed-off-by: J. Bruce Fields --- fs/nfsd/nfs4xdr.c | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index b543b2410b54..437b4623cb02 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -2845,11 +2845,10 @@ nfsd4_encode_rename(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_ } static __be32 -nfsd4_encode_secinfo(struct nfsd4_compoundres *resp, __be32 nfserr, - struct nfsd4_secinfo *secinfo) +nfsd4_do_encode_secinfo(struct nfsd4_compoundres *resp, + __be32 nfserr,struct svc_export *exp) { int i = 0; - struct svc_export *exp = secinfo->si_exp; u32 nflavs; struct exp_flavor_info *flavs; struct exp_flavor_info def_flavs[2]; @@ -2911,6 +2910,20 @@ out: return nfserr; } +static __be32 +nfsd4_encode_secinfo(struct nfsd4_compoundres *resp, __be32 nfserr, + struct nfsd4_secinfo *secinfo) +{ + return nfsd4_do_encode_secinfo(resp, nfserr, secinfo->si_exp); +} + +static __be32 +nfsd4_encode_secinfo_no_name(struct nfsd4_compoundres *resp, __be32 nfserr, + struct nfsd4_secinfo_no_name *secinfo) +{ + return nfsd4_do_encode_secinfo(resp, nfserr, secinfo->sin_exp); +} + /* * The SETATTR encode routine is special -- it always encodes a bitmap, * regardless of the error status. @@ -3173,7 +3186,7 @@ static nfsd4_enc nfsd4_enc_ops[] = { [OP_LAYOUTCOMMIT] = (nfsd4_enc)nfsd4_encode_noop, [OP_LAYOUTGET] = (nfsd4_enc)nfsd4_encode_noop, [OP_LAYOUTRETURN] = (nfsd4_enc)nfsd4_encode_noop, - [OP_SECINFO_NO_NAME] = (nfsd4_enc)nfsd4_encode_secinfo, + [OP_SECINFO_NO_NAME] = (nfsd4_enc)nfsd4_encode_secinfo_no_name, [OP_SEQUENCE] = (nfsd4_enc)nfsd4_encode_sequence, [OP_SET_SSV] = (nfsd4_enc)nfsd4_encode_noop, [OP_TEST_STATEID] = (nfsd4_enc)nfsd4_encode_noop, -- cgit v1.2.3 From e6ce1324e4f08b0d984340201a125806dae0e9a6 Mon Sep 17 00:00:00 2001 From: Stephen Neuendorffer Date: Thu, 18 Nov 2010 15:54:56 -0800 Subject: of/flattree: Add Kconfig for EARLY_FLATTREE The device tree code is now in two pieces: some which can be used generically on any platform which selects CONFIG_OF_FLATTREE, and some early which is used at boot time on only a few architectures. This patch segregates the early code so that only those architectures which care about it need compile it. This also means that some of the requirements in the early code (such as a cmd_line variable) that most architectures (e.g. X86) don't provide can be ignored. Signed-off-by: Stephen Neuendorffer [grant.likely@secretlab.ca: remove extra blank line addition] [grant.likely@secretlab.ca: fixed incorrect #ifdef CONFIG_EARLY_FLATTREE check] [grant.likely@secretlab.ca: Made OF_EARLY_FLATTREE select instead of depend on OF_FLATTREE] Signed-off-by: Grant Likely --- arch/microblaze/Kconfig | 2 +- arch/mips/Kconfig | 2 +- arch/powerpc/Kconfig | 2 +- drivers/of/Kconfig | 4 ++++ drivers/of/fdt.c | 4 ++++ 5 files changed, 11 insertions(+), 3 deletions(-) diff --git a/arch/microblaze/Kconfig b/arch/microblaze/Kconfig index 387d5ffdfd3a..5f5018a71a3d 100644 --- a/arch/microblaze/Kconfig +++ b/arch/microblaze/Kconfig @@ -14,7 +14,7 @@ config MICROBLAZE select HAVE_DMA_API_DEBUG select TRACING_SUPPORT select OF - select OF_FLATTREE + select OF_EARLY_FLATTREE config SWAP def_bool n diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index 0a9b5b8b2a19..f489ec30e071 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig @@ -2218,7 +2218,7 @@ config SECCOMP config USE_OF bool "Flattened Device Tree support" select OF - select OF_FLATTREE + select OF_EARLY_FLATTREE help Include support for flattened device tree machine descriptions. diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index e625e9e034ae..48fb4790bfec 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -116,7 +116,7 @@ config PPC bool default y select OF - select OF_FLATTREE + select OF_EARLY_FLATTREE select HAVE_FTRACE_MCOUNT_RECORD select HAVE_DYNAMIC_FTRACE select HAVE_FUNCTION_TRACER diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig index e4b93a0a15d2..3c6e100a3ad0 100644 --- a/drivers/of/Kconfig +++ b/drivers/of/Kconfig @@ -19,6 +19,10 @@ config OF_FLATTREE bool select DTC +config OF_EARLY_FLATTREE + bool + select OF_FLATTREE + config OF_PROMTREE bool diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c index c1360e02f921..2ebacf14e7de 100644 --- a/drivers/of/fdt.c +++ b/drivers/of/fdt.c @@ -27,6 +27,8 @@ int __initdata dt_root_size_cells; struct boot_param_header *initial_boot_params; +#ifdef CONFIG_OF_EARLY_FLATTREE + char *find_flat_dt_string(u32 offset) { return ((char *)initial_boot_params) + @@ -604,3 +606,5 @@ void __init unflatten_device_tree(void) pr_debug(" <- unflatten_device_tree()\n"); } + +#endif /* CONFIG_OF_EARLY_FLATTREE */ -- cgit v1.2.3 From 85e0dbf94eb369882d5ad768e3687a4af6f36dbe Mon Sep 17 00:00:00 2001 From: Jassi Brar Date: Tue, 21 Dec 2010 09:44:28 +0900 Subject: ARM: S5P6442: Implement i2c-gpio config Signed-off-by: Jassi Brar Acked-by: Mark Brown Signed-off-by: Kukjin Kim --- arch/arm/mach-s5p6442/setup-i2c0.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-s5p6442/setup-i2c0.c b/arch/arm/mach-s5p6442/setup-i2c0.c index 662695dd7761..aad85656b0cc 100644 --- a/arch/arm/mach-s5p6442/setup-i2c0.c +++ b/arch/arm/mach-s5p6442/setup-i2c0.c @@ -14,12 +14,15 @@ #include #include +#include struct platform_device; /* don't need the contents */ +#include #include void s3c_i2c0_cfg_gpio(struct platform_device *dev) { - /* Will be populated later */ + s3c_gpio_cfgall_range(S5P6442_GPD1(0), 2, + S3C_GPIO_SFN(2), S3C_GPIO_PULL_UP); } -- cgit v1.2.3 From c204fb151781dedef364ded77324b5c77a5b83a9 Mon Sep 17 00:00:00 2001 From: Jassi Brar Date: Tue, 21 Dec 2010 09:44:30 +0900 Subject: ARM: S5P6442: Enable I2C0 device on SMDK6442 This patch enables I2C0 device for WM8580 on SMDK6442. Signed-off-by: Jassi Brar Acked-by: Mark Brown [kgene.kim@samsung.com: minor changed title and description] Signed-off-by: Kukjin Kim --- arch/arm/mach-s5p6442/mach-smdk6442.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/arch/arm/mach-s5p6442/mach-smdk6442.c b/arch/arm/mach-s5p6442/mach-smdk6442.c index 819fd80d00af..e69f137b0a39 100644 --- a/arch/arm/mach-s5p6442/mach-smdk6442.c +++ b/arch/arm/mach-s5p6442/mach-smdk6442.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include @@ -25,6 +26,7 @@ #include #include #include +#include /* Following are default values for UCON, ULCON and UFCON UART registers */ #define SMDK6442_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \ @@ -65,10 +67,15 @@ static struct s3c2410_uartcfg smdk6442_uartcfgs[] __initdata = { }; static struct platform_device *smdk6442_devices[] __initdata = { + &s3c_device_i2c0, &s5p6442_device_iis0, &s3c_device_wdt, }; +static struct i2c_board_info smdk6442_i2c_devs0[] __initdata = { + { I2C_BOARD_INFO("wm8580", 0x1b), }, +}; + static void __init smdk6442_map_io(void) { s5p_init_io(NULL, 0, S5P_VA_CHIPID); @@ -78,6 +85,9 @@ static void __init smdk6442_map_io(void) static void __init smdk6442_machine_init(void) { + s3c_i2c0_set_platdata(NULL); + i2c_register_board_info(0, smdk6442_i2c_devs0, + ARRAY_SIZE(smdk6442_i2c_devs0)); platform_add_devices(smdk6442_devices, ARRAY_SIZE(smdk6442_devices)); } -- cgit v1.2.3 From 6cb26da8205a47cab75118af8849766a10d098db Mon Sep 17 00:00:00 2001 From: Jassi Brar Date: Tue, 21 Dec 2010 09:44:36 +0900 Subject: ARM: S5P6450: Define clocks for I2S Define missing controller clocks for the I2S-0,1 blocks. Signed-off-by: Jassi Brar Acked-by: Mark Brown Signed-off-by: Kukjin Kim --- arch/arm/mach-s5p64x0/clock-s5p6450.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/arch/arm/mach-s5p64x0/clock-s5p6450.c b/arch/arm/mach-s5p64x0/clock-s5p6450.c index 7fc6abd35914..d8b20ee8cc8c 100644 --- a/arch/arm/mach-s5p64x0/clock-s5p6450.c +++ b/arch/arm/mach-s5p64x0/clock-s5p6450.c @@ -260,6 +260,18 @@ static struct clk init_clocks_disable[] = { .parent = &clk_pclk_low.clk, .enable = s5p64x0_pclk_ctrl, .ctrlbit = (1 << 26), + }, { + .name = "iis", + .id = 1, + .parent = &clk_pclk_low.clk, + .enable = s5p64x0_pclk_ctrl, + .ctrlbit = (1 << 15), + }, { + .name = "iis", + .id = 2, + .parent = &clk_pclk_low.clk, + .enable = s5p64x0_pclk_ctrl, + .ctrlbit = (1 << 16), }, { .name = "i2c", .id = 1, -- cgit v1.2.3 From cf57b1a7f288829547b03385bf22124a96c82a4e Mon Sep 17 00:00:00 2001 From: Jassi Brar Date: Tue, 21 Dec 2010 09:44:39 +0900 Subject: ARM: S5P6450: Define base addresses for I2S Define the base address of I2S-1 and 2 for S5P6450. Signed-off-by: Jassi Brar Acked-by: Mark Brown [kgene.kim@samsung.com: Added description] Signed-off-by: Kukjin Kim --- arch/arm/mach-s5p64x0/include/mach/map.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/arch/arm/mach-s5p64x0/include/mach/map.h b/arch/arm/mach-s5p64x0/include/mach/map.h index 31e534156e06..4d3d332152d0 100644 --- a/arch/arm/mach-s5p64x0/include/mach/map.h +++ b/arch/arm/mach-s5p64x0/include/mach/map.h @@ -63,6 +63,8 @@ #define S5P64X0_PA_HSMMC(x) (0xED800000 + ((x) * 0x100000)) #define S5P64X0_PA_I2S (0xF2000000) +#define S5P6450_PA_I2S1 0xF2800000 +#define S5P6450_PA_I2S2 0xF2900000 #define S5P64X0_PA_PCM (0xF2100000) -- cgit v1.2.3 From e0b9c88b12dd190591eb5903cd0572a97d2a6bf1 Mon Sep 17 00:00:00 2001 From: Rajeshwari Shinde Date: Tue, 21 Dec 2010 09:44:42 +0900 Subject: ARM: S5P64X0: Segregate audio devices Segregate I2S devices for S5P6440 and S5P6450. Signed-off-by: Rajeshwari Shinde Signed-off-by: Jassi Brar Acked-by: Mark Brown Signed-off-by: Kukjin Kim --- arch/arm/mach-s5p64x0/dev-audio.c | 123 ++++++++++++++++++++++++++---- arch/arm/plat-samsung/include/plat/devs.h | 2 + 2 files changed, 112 insertions(+), 13 deletions(-) diff --git a/arch/arm/mach-s5p64x0/dev-audio.c b/arch/arm/mach-s5p64x0/dev-audio.c index 14f89e73b8de..35f1f226dabb 100644 --- a/arch/arm/mach-s5p64x0/dev-audio.c +++ b/arch/arm/mach-s5p64x0/dev-audio.c @@ -24,13 +24,13 @@ static const char *rclksrc[] = { [1] = "sclk_audio2", }; -static int s5p64x0_cfg_i2s(struct platform_device *pdev) +static int s5p6440_cfg_i2s(struct platform_device *pdev) { - /* configure GPIO for i2s port */ switch (pdev->id) { case 0: - s3c_gpio_cfgpin_range(S5P6440_GPR(4), 5, S3C_GPIO_SFN(5)); - s3c_gpio_cfgpin_range(S5P6440_GPR(13), 2, S3C_GPIO_SFN(5)); + s3c_gpio_cfgpin_range(S5P6440_GPC(4), 2, S3C_GPIO_SFN(5)); + s3c_gpio_cfgpin(S5P6440_GPC(7), S3C_GPIO_SFN(5)); + s3c_gpio_cfgpin_range(S5P6440_GPH(6), 4, S3C_GPIO_SFN(5)); break; default: printk(KERN_ERR "Invalid Device %d\n", pdev->id); @@ -40,8 +40,8 @@ static int s5p64x0_cfg_i2s(struct platform_device *pdev) return 0; } -static struct s3c_audio_pdata s5p64x0_i2s_pdata = { - .cfg_gpio = s5p64x0_cfg_i2s, +static struct s3c_audio_pdata s5p6440_i2s_pdata = { + .cfg_gpio = s5p6440_cfg_i2s, .type = { .i2s = { .quirks = QUIRK_PRI_6CHAN, @@ -50,7 +50,7 @@ static struct s3c_audio_pdata s5p64x0_i2s_pdata = { }, }; -static struct resource s5p64x0_iis0_resource[] = { +static struct resource s5p64x0_i2s0_resource[] = { [0] = { .start = S5P64X0_PA_I2S, .end = S5P64X0_PA_I2S + 0x100 - 1, @@ -71,20 +71,117 @@ static struct resource s5p64x0_iis0_resource[] = { struct platform_device s5p6440_device_iis = { .name = "samsung-i2s", .id = 0, - .num_resources = ARRAY_SIZE(s5p64x0_iis0_resource), - .resource = s5p64x0_iis0_resource, + .num_resources = ARRAY_SIZE(s5p64x0_i2s0_resource), + .resource = s5p64x0_i2s0_resource, .dev = { - .platform_data = &s5p64x0_i2s_pdata, + .platform_data = &s5p6440_i2s_pdata, + }, +}; + +static int s5p6450_cfg_i2s(struct platform_device *pdev) +{ + switch (pdev->id) { + case 0: + s3c_gpio_cfgpin_range(S5P6450_GPR(4), 5, S3C_GPIO_SFN(5)); + s3c_gpio_cfgpin_range(S5P6450_GPR(13), 2, S3C_GPIO_SFN(5)); + break; + case 1: + s3c_gpio_cfgpin(S5P6440_GPB(4), S3C_GPIO_SFN(5)); + s3c_gpio_cfgpin_range(S5P6450_GPC(0), 4, S3C_GPIO_SFN(5)); + break; + case 2: + s3c_gpio_cfgpin_range(S5P6450_GPK(0), 5, S3C_GPIO_SFN(5)); + break; + default: + printk(KERN_ERR "Invalid Device %d\n", pdev->id); + return -EINVAL; + } + + return 0; +} + +static struct s3c_audio_pdata s5p6450_i2s0_pdata = { + .cfg_gpio = s5p6450_cfg_i2s, + .type = { + .i2s = { + .quirks = QUIRK_PRI_6CHAN, + .src_clk = rclksrc, + }, }, }; struct platform_device s5p6450_device_iis0 = { .name = "samsung-i2s", .id = 0, - .num_resources = ARRAY_SIZE(s5p64x0_iis0_resource), - .resource = s5p64x0_iis0_resource, + .num_resources = ARRAY_SIZE(s5p64x0_i2s0_resource), + .resource = s5p64x0_i2s0_resource, + .dev = { + .platform_data = &s5p6450_i2s0_pdata, + }, +}; + +static struct s3c_audio_pdata s5p6450_i2s_pdata = { + .cfg_gpio = s5p6450_cfg_i2s, + .type = { + .i2s = { + .src_clk = rclksrc, + }, + }, +}; + +static struct resource s5p6450_i2s1_resource[] = { + [0] = { + .start = S5P6450_PA_I2S1, + .end = S5P6450_PA_I2S1 + 0x100 - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = DMACH_I2S1_TX, + .end = DMACH_I2S1_TX, + .flags = IORESOURCE_DMA, + }, + [2] = { + .start = DMACH_I2S1_RX, + .end = DMACH_I2S1_RX, + .flags = IORESOURCE_DMA, + }, +}; + +struct platform_device s5p6450_device_iis1 = { + .name = "samsung-i2s", + .id = 1, + .num_resources = ARRAY_SIZE(s5p6450_i2s1_resource), + .resource = s5p6450_i2s1_resource, + .dev = { + .platform_data = &s5p6450_i2s_pdata, + }, +}; + +static struct resource s5p6450_i2s2_resource[] = { + [0] = { + .start = S5P6450_PA_I2S2, + .end = S5P6450_PA_I2S2 + 0x100 - 1, + .flags = IORESOURCE_MEM, + }, + [1] = { + .start = DMACH_I2S2_TX, + .end = DMACH_I2S2_TX, + .flags = IORESOURCE_DMA, + }, + [2] = { + .start = DMACH_I2S2_RX, + .end = DMACH_I2S2_RX, + .flags = IORESOURCE_DMA, + }, +}; + +struct platform_device s5p6450_device_iis2 = { + .name = "samsung-i2s", + .id = 2, + .num_resources = ARRAY_SIZE(s5p6450_i2s2_resource), + .resource = s5p6450_i2s2_resource, .dev = { - .platform_data = &s5p64x0_i2s_pdata, + .platform_data = &s5p6450_i2s_pdata, }, }; diff --git a/arch/arm/plat-samsung/include/plat/devs.h b/arch/arm/plat-samsung/include/plat/devs.h index dec0ded6a5ee..126196e9983b 100644 --- a/arch/arm/plat-samsung/include/plat/devs.h +++ b/arch/arm/plat-samsung/include/plat/devs.h @@ -115,6 +115,8 @@ extern struct platform_device s5p6440_device_pcm; extern struct platform_device s5p6440_device_iis; extern struct platform_device s5p6450_device_iis0; +extern struct platform_device s5p6450_device_iis1; +extern struct platform_device s5p6450_device_iis2; extern struct platform_device s5p6450_device_pcm0; extern struct platform_device s5pc100_device_ac97; -- cgit v1.2.3 From 149bb5bcc3b1c5f4044e0ad088afdc8a12b51c64 Mon Sep 17 00:00:00 2001 From: Jassi Brar Date: Tue, 21 Dec 2010 09:46:29 +0900 Subject: ARM: S5P6440: Enable I2S device to work on SMDK6440 Add missing virtual ASoC DMA device and WM8580 as I2C slave, so that the I2S can work on SMDK6440. [kgene.kim@samsung.com: removed virtual ASoC DMA device to avoid build error and it will be added next time] Signed-off-by: Jassi Brar Acked-by: Mark Brown [kgene.kim@samsung.com: minor changed title] Signed-off-by: Kukjin Kim --- arch/arm/mach-s5p64x0/mach-smdk6440.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/mach-s5p64x0/mach-smdk6440.c b/arch/arm/mach-s5p64x0/mach-smdk6440.c index 87c3f03c618c..e9802755daeb 100644 --- a/arch/arm/mach-s5p64x0/mach-smdk6440.c +++ b/arch/arm/mach-s5p64x0/mach-smdk6440.c @@ -117,6 +117,7 @@ static struct s3c2410_platform_i2c s5p6440_i2c1_data __initdata = { static struct i2c_board_info smdk6440_i2c_devs0[] __initdata = { { I2C_BOARD_INFO("24c08", 0x50), }, + { I2C_BOARD_INFO("wm8580", 0x1b), }, }; static struct i2c_board_info smdk6440_i2c_devs1[] __initdata = { -- cgit v1.2.3 From fcf8897d038b819267cae2c661438331785c2979 Mon Sep 17 00:00:00 2001 From: Jassi Brar Date: Tue, 21 Dec 2010 09:48:32 +0900 Subject: ARM: S5P6450: Enable I2S device to work on SMDK6450 Add missing virtual ASoC DMA device and WM8580 as I2C slave, so that the I2S can work on SMDK6450. [kgene.kim@samsung.com: removed virtual ASoC DMA device to avoid build error and it will be added next time] Signed-off-by: Jassi Brar Acked-by: Mark Brown [kgene.kim@samsung.com: minor changed title] Signed-off-by: Kukjin Kim --- arch/arm/mach-s5p64x0/mach-smdk6450.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/mach-s5p64x0/mach-smdk6450.c b/arch/arm/mach-s5p64x0/mach-smdk6450.c index d609f5af2b98..b78f56292780 100644 --- a/arch/arm/mach-s5p64x0/mach-smdk6450.c +++ b/arch/arm/mach-s5p64x0/mach-smdk6450.c @@ -135,6 +135,7 @@ static struct s3c2410_platform_i2c s5p6450_i2c1_data __initdata = { }; static struct i2c_board_info smdk6450_i2c_devs0[] __initdata = { + { I2C_BOARD_INFO("wm8580", 0x1b), }, { I2C_BOARD_INFO("24c08", 0x50), }, /* Samsung KS24C080C EEPROM */ }; -- cgit v1.2.3 From 0031e9d91e45d1ddf17702c1f105096b8740d456 Mon Sep 17 00:00:00 2001 From: Jassi Brar Date: Tue, 21 Dec 2010 09:48:35 +0900 Subject: ARM: S5PV210: Enable I2S device to work on SMDKC110 Add missing virtual ASoC DMA device and WM8580 as I2C slave, so that the I2S can work on SMDKC110. [kgene.kim@samsung.com: removed virtual ASoC DMA device to avoid build error and it will be added next time] Signed-off-by: Jassi Brar Acked-by: Mark Brown [kgene.kim@samsung.com: minor changed title] Signed-off-by: Kukjin Kim --- arch/arm/mach-s5pv210/mach-smdkc110.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/mach-s5pv210/mach-smdkc110.c b/arch/arm/mach-s5pv210/mach-smdkc110.c index 5dd1681c069e..bb20a14da100 100644 --- a/arch/arm/mach-s5pv210/mach-smdkc110.c +++ b/arch/arm/mach-s5pv210/mach-smdkc110.c @@ -94,6 +94,7 @@ static struct platform_device *smdkc110_devices[] __initdata = { static struct i2c_board_info smdkc110_i2c_devs0[] __initdata = { { I2C_BOARD_INFO("24c08", 0x50), }, /* Samsung S524AD0XD1 */ + { I2C_BOARD_INFO("wm8580", 0x1b), }, }; static struct i2c_board_info smdkc110_i2c_devs1[] __initdata = { -- cgit v1.2.3 From d8710bc8de918059efaadd126320c2b34c514548 Mon Sep 17 00:00:00 2001 From: Jassi Brar Date: Tue, 21 Dec 2010 09:48:37 +0900 Subject: ARM: S5PV210: Enable I2S device to work on SMDKV210 Add missing virtual ASoC DMA device and WM8580 as I2C slave, so that the I2S can work on SMDKV210. [kgene.kim@samsung.com: removed virtual ASoC DMA device to avoid build error and it will be added next time] Signed-off-by: Jassi Brar Acked-by: Mark Brown Signed-off-by: Kukjin Kim --- arch/arm/mach-s5pv210/mach-smdkv210.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/arm/mach-s5pv210/mach-smdkv210.c b/arch/arm/mach-s5pv210/mach-smdkv210.c index 1fbc45b2a432..82e635625073 100644 --- a/arch/arm/mach-s5pv210/mach-smdkv210.c +++ b/arch/arm/mach-s5pv210/mach-smdkv210.c @@ -123,6 +123,7 @@ static struct platform_device *smdkv210_devices[] __initdata = { static struct i2c_board_info smdkv210_i2c_devs0[] __initdata = { { I2C_BOARD_INFO("24c08", 0x50), }, /* Samsung S524AD0XD1 */ + { I2C_BOARD_INFO("wm8580", 0x1b), }, }; static struct i2c_board_info smdkv210_i2c_devs1[] __initdata = { -- cgit v1.2.3 From f5cc4354907dccd6bb343cca18074c751a94f913 Mon Sep 17 00:00:00 2001 From: Jassi Brar Date: Tue, 21 Dec 2010 09:52:14 +0900 Subject: ARM: S5PV310: Enable I2C1 device Enable the I2C1 device on SMDKV310 and SMDKC210. Signed-off-by: Jassi Brar Acked-by: Mark Brown [kgene.kim@samsung.com: minor changed title] Signed-off-by: Kukjin Kim --- arch/arm/mach-s5pv310/Kconfig | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/arch/arm/mach-s5pv310/Kconfig b/arch/arm/mach-s5pv310/Kconfig index d64efe0d4c97..3e1fe9d6b1fa 100644 --- a/arch/arm/mach-s5pv310/Kconfig +++ b/arch/arm/mach-s5pv310/Kconfig @@ -70,10 +70,12 @@ config MACH_SMDKC210 select CPU_S5PV310 select S3C_DEV_RTC select S3C_DEV_WDT + select S3C_DEV_I2C1 select S3C_DEV_HSMMC select S3C_DEV_HSMMC1 select S3C_DEV_HSMMC2 select S3C_DEV_HSMMC3 + select S5PV310_SETUP_I2C1 select S5PV310_SETUP_SDHCI help Machine support for Samsung SMDKC210 @@ -98,10 +100,12 @@ config MACH_SMDKV310 select CPU_S5PV310 select S3C_DEV_RTC select S3C_DEV_WDT + select S3C_DEV_I2C1 select S3C_DEV_HSMMC select S3C_DEV_HSMMC1 select S3C_DEV_HSMMC2 select S3C_DEV_HSMMC3 + select S5PV310_SETUP_I2C1 select S5PV310_SETUP_SDHCI help Machine support for Samsung SMDKV310 -- cgit v1.2.3 From 3055c6dad620af9e2c5432feb5ec7d5ac46d54b0 Mon Sep 17 00:00:00 2001 From: Jassi Brar Date: Tue, 21 Dec 2010 09:54:35 +0900 Subject: ARM: S5PV310: Add PDMA clocks Define PDMA clocks for the controller 0 and 1. Signed-off-by: Jassi Brar Acked-by: Mark Brown Signed-off-by: Kukjin Kim --- arch/arm/mach-s5pv310/clock.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/arch/arm/mach-s5pv310/clock.c b/arch/arm/mach-s5pv310/clock.c index 58c9d33f36fe..ace8f52aa04f 100644 --- a/arch/arm/mach-s5pv310/clock.c +++ b/arch/arm/mach-s5pv310/clock.c @@ -466,6 +466,16 @@ static struct clk init_clocks_disable[] = { .id = -1, .enable = s5pv310_clk_ip_fsys_ctrl, .ctrlbit = (1 << 10), + }, { + .name = "pdma", + .id = 0, + .enable = s5pv310_clk_ip_fsys_ctrl, + .ctrlbit = (1 << 0), + }, { + .name = "pdma", + .id = 1, + .enable = s5pv310_clk_ip_fsys_ctrl, + .ctrlbit = (1 << 1), }, { .name = "adc", .id = -1, -- cgit v1.2.3 From aa227557dde1d8de2eba19655320d4af360054fd Mon Sep 17 00:00:00 2001 From: Jassi Brar Date: Tue, 21 Dec 2010 09:54:57 +0900 Subject: ARM: S5PV310: Add AC97 clock Define clock for the AC97 controller. Signed-off-by: Jassi Brar Acked-by: Mark Brown Signed-off-by: Kukjin Kim --- arch/arm/mach-s5pv310/clock.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/arch/arm/mach-s5pv310/clock.c b/arch/arm/mach-s5pv310/clock.c index ace8f52aa04f..189198a8fd6f 100644 --- a/arch/arm/mach-s5pv310/clock.c +++ b/arch/arm/mach-s5pv310/clock.c @@ -516,6 +516,11 @@ static struct clk init_clocks_disable[] = { .id = 2, .enable = s5pv310_clk_ip_peril_ctrl, .ctrlbit = (1 << 18), + }, { + .name = "ac97", + .id = -1, + .enable = s5pv310_clk_ip_peril_ctrl, + .ctrlbit = (1 << 27), }, { .name = "fimg2d", .id = -1, -- cgit v1.2.3 From 2d27043f7b7692252cc76aa13a95b4ff88558977 Mon Sep 17 00:00:00 2001 From: Jassi Brar Date: Tue, 21 Dec 2010 09:57:03 +0900 Subject: ARM: S5PV310: Define I2S clocks Define missing controller clocks for the I2S-0, 1 and 2 blocks. Signed-off-by: Jassi Brar Acked-by: Mark Brown [kgene.kim@samsung.com: Added description] Signed-off-by: Kukjin Kim --- arch/arm/mach-s5pv310/clock.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/arch/arm/mach-s5pv310/clock.c b/arch/arm/mach-s5pv310/clock.c index 189198a8fd6f..6d22c43c6ee8 100644 --- a/arch/arm/mach-s5pv310/clock.c +++ b/arch/arm/mach-s5pv310/clock.c @@ -516,6 +516,21 @@ static struct clk init_clocks_disable[] = { .id = 2, .enable = s5pv310_clk_ip_peril_ctrl, .ctrlbit = (1 << 18), + }, { + .name = "iis", + .id = 0, + .enable = s5pv310_clk_ip_peril_ctrl, + .ctrlbit = (1 << 19), + }, { + .name = "iis", + .id = 1, + .enable = s5pv310_clk_ip_peril_ctrl, + .ctrlbit = (1 << 20), + }, { + .name = "iis", + .id = 2, + .enable = s5pv310_clk_ip_peril_ctrl, + .ctrlbit = (1 << 21), }, { .name = "ac97", .id = -1, -- cgit v1.2.3 From 906b9826b81d07701b96621a14d7cf255c6e1712 Mon Sep 17 00:00:00 2001 From: Jassi Brar Date: Tue, 21 Dec 2010 09:57:46 +0900 Subject: ARM: S5PV310: Add AC97 support for SMDK Enable AC97 audio device on SMDKV310 and SMDKC210. Signed-off-by: Jassi Brar Acked-by: Mark Brown Signed-off-by: Kukjin Kim --- arch/arm/mach-s5pv310/mach-smdkc210.c | 1 + arch/arm/mach-s5pv310/mach-smdkv310.c | 1 + 2 files changed, 2 insertions(+) diff --git a/arch/arm/mach-s5pv310/mach-smdkc210.c b/arch/arm/mach-s5pv310/mach-smdkc210.c index 2b8d4fc52d7c..5621f0dd1685 100644 --- a/arch/arm/mach-s5pv310/mach-smdkc210.c +++ b/arch/arm/mach-s5pv310/mach-smdkc210.c @@ -147,6 +147,7 @@ static struct platform_device *smdkc210_devices[] __initdata = { &s3c_device_rtc, &s3c_device_wdt, &smdkc210_smsc911x, + &s5pv310_device_ac97, }; static void __init smdkc210_smsc911x_init(void) diff --git a/arch/arm/mach-s5pv310/mach-smdkv310.c b/arch/arm/mach-s5pv310/mach-smdkv310.c index 35826d66632c..524b5f33b857 100644 --- a/arch/arm/mach-s5pv310/mach-smdkv310.c +++ b/arch/arm/mach-s5pv310/mach-smdkv310.c @@ -147,6 +147,7 @@ static struct platform_device *smdkv310_devices[] __initdata = { &s3c_device_rtc, &s3c_device_wdt, &smdkv310_smsc911x, + &s5pv310_device_ac97, }; static void __init smdkv310_smsc911x_init(void) -- cgit v1.2.3 From 6f5c11c5a5ec9aef67b433906c712608ef7b9b97 Mon Sep 17 00:00:00 2001 From: Jassi Brar Date: Tue, 21 Dec 2010 09:59:05 +0900 Subject: ARM: S5PV310: Enable I2S device on SMDKV310 Enable I2S_0 device on the SMDKV310. Also, add the dependency I2C_1 device. Signed-off-by: Jassi Brar Acked-by: Mark Brown [kgene.kim@samsung.com: minor changed title] Signed-off-by: Kukjin Kim --- arch/arm/mach-s5pv310/mach-smdkv310.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/arch/arm/mach-s5pv310/mach-smdkv310.c b/arch/arm/mach-s5pv310/mach-smdkv310.c index 524b5f33b857..d5eb607763f7 100644 --- a/arch/arm/mach-s5pv310/mach-smdkv310.c +++ b/arch/arm/mach-s5pv310/mach-smdkv310.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -23,6 +24,7 @@ #include #include #include +#include #include #include @@ -139,7 +141,12 @@ static struct platform_device smdkv310_smsc911x = { }, }; +static struct i2c_board_info i2c_devs1[] __initdata = { + {I2C_BOARD_INFO("wm8994", 0x1a),}, +}; + static struct platform_device *smdkv310_devices[] __initdata = { + &s3c_device_i2c1, &s3c_device_hsmmc0, &s3c_device_hsmmc1, &s3c_device_hsmmc2, @@ -148,6 +155,7 @@ static struct platform_device *smdkv310_devices[] __initdata = { &s3c_device_wdt, &smdkv310_smsc911x, &s5pv310_device_ac97, + &s5pv310_device_i2s0, }; static void __init smdkv310_smsc911x_init(void) @@ -183,6 +191,9 @@ static void __init smdkv310_map_io(void) static void __init smdkv310_machine_init(void) { + s3c_i2c1_set_platdata(NULL); + i2c_register_board_info(1, i2c_devs1, ARRAY_SIZE(i2c_devs1)); + smdkv310_smsc911x_init(); s3c_sdhci0_set_platdata(&smdkv310_hsmmc0_pdata); -- cgit v1.2.3 From d8a2d39d9e1d023b7eb4ea559d2baa668d3eb6c7 Mon Sep 17 00:00:00 2001 From: Jassi Brar Date: Tue, 21 Dec 2010 09:59:57 +0900 Subject: ARM: S5PV310: Enable I2S device on SMDKC210 Enable I2S_0 device on the SMDKC210. Also, add the dependency I2C_1 device. Signed-off-by: Jassi Brar Acked-by: Mark Brown [kgene.kim@samsung.com: minor changed title] Signed-off-by: Kukjin Kim --- arch/arm/mach-s5pv310/mach-smdkc210.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/arch/arm/mach-s5pv310/mach-smdkc210.c b/arch/arm/mach-s5pv310/mach-smdkc210.c index 5621f0dd1685..62c4d6204d2a 100644 --- a/arch/arm/mach-s5pv310/mach-smdkc210.c +++ b/arch/arm/mach-s5pv310/mach-smdkc210.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -23,6 +24,7 @@ #include #include #include +#include #include #include @@ -139,7 +141,12 @@ static struct platform_device smdkc210_smsc911x = { }, }; +static struct i2c_board_info i2c_devs1[] __initdata = { + {I2C_BOARD_INFO("wm8994", 0x1a),}, +}; + static struct platform_device *smdkc210_devices[] __initdata = { + &s3c_device_i2c1, &s3c_device_hsmmc0, &s3c_device_hsmmc1, &s3c_device_hsmmc2, @@ -148,6 +155,7 @@ static struct platform_device *smdkc210_devices[] __initdata = { &s3c_device_wdt, &smdkc210_smsc911x, &s5pv310_device_ac97, + &s5pv310_device_i2s0, }; static void __init smdkc210_smsc911x_init(void) @@ -183,6 +191,9 @@ static void __init smdkc210_map_io(void) static void __init smdkc210_machine_init(void) { + s3c_i2c1_set_platdata(NULL); + i2c_register_board_info(1, i2c_devs1, ARRAY_SIZE(i2c_devs1)); + smdkc210_smsc911x_init(); s3c_sdhci0_set_platdata(&smdkc210_hsmmc0_pdata); -- cgit v1.2.3 From 9706a36e35c4ce04f28a62cfe1205b4e3b0dd13c Mon Sep 17 00:00:00 2001 From: Stephen Neuendorffer Date: Thu, 18 Nov 2010 15:54:59 -0800 Subject: of/flattree: Add non-boottime device tree functions In preparation for providing run-time handling of device trees, factor out some of the basic functions so that they take an arbitrary blob, rather than relying on the single boot-time tree. V2: - functions have of_fdt_* names - removed find_flat_dt_string - blob argument is first Signed-off-by: Stephen Neuendorffer Signed-off-by: Grant Likely --- drivers/of/fdt.c | 133 +++++++++++++++++++++++++++++-------------------- include/linux/of_fdt.h | 11 ++++ 2 files changed, 90 insertions(+), 54 deletions(-) diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c index 2ebacf14e7de..10eab21076ea 100644 --- a/drivers/of/fdt.c +++ b/drivers/of/fdt.c @@ -22,6 +22,82 @@ #include +char *of_fdt_get_string(struct boot_param_header *blob, u32 offset) +{ + return ((char *)blob) + + be32_to_cpu(blob->off_dt_strings) + offset; +} + +/** + * of_fdt_get_property - Given a node in the given flat blob, return + * the property ptr + */ +void *of_fdt_get_property(struct boot_param_header *blob, + unsigned long node, const char *name, + unsigned long *size) +{ + unsigned long p = node; + + do { + u32 tag = be32_to_cpup((__be32 *)p); + u32 sz, noff; + const char *nstr; + + p += 4; + if (tag == OF_DT_NOP) + continue; + if (tag != OF_DT_PROP) + return NULL; + + sz = be32_to_cpup((__be32 *)p); + noff = be32_to_cpup((__be32 *)(p + 4)); + p += 8; + if (be32_to_cpu(blob->version) < 0x10) + p = ALIGN(p, sz >= 8 ? 8 : 4); + + nstr = of_fdt_get_string(blob, noff); + if (nstr == NULL) { + pr_warning("Can't find property index name !\n"); + return NULL; + } + if (strcmp(name, nstr) == 0) { + if (size) + *size = sz; + return (void *)p; + } + p += sz; + p = ALIGN(p, 4); + } while (1); +} + +/** + * of_fdt_is_compatible - Return true if given node from the given blob has + * compat in its compatible list + * @blob: A device tree blob + * @node: node to test + * @compat: compatible string to compare with compatible list. + */ +int of_fdt_is_compatible(struct boot_param_header *blob, + unsigned long node, const char *compat) +{ + const char *cp; + unsigned long cplen, l; + + cp = of_fdt_get_property(blob, node, "compatible", &cplen); + if (cp == NULL) + return 0; + while (cplen > 0) { + if (of_compat_cmp(cp, compat, strlen(compat)) == 0) + return 1; + l = strlen(cp) + 1; + cp += l; + cplen -= l; + } + + return 0; +} + +/* Everything below here references initial_boot_params directly. */ int __initdata dt_root_addr_cells; int __initdata dt_root_size_cells; @@ -29,12 +105,6 @@ struct boot_param_header *initial_boot_params; #ifdef CONFIG_OF_EARLY_FLATTREE -char *find_flat_dt_string(u32 offset) -{ - return ((char *)initial_boot_params) + - be32_to_cpu(initial_boot_params->off_dt_strings) + offset; -} - /** * of_scan_flat_dt - scan flattened tree blob and call callback on each. * @it: callback function @@ -123,38 +193,7 @@ unsigned long __init of_get_flat_dt_root(void) void *__init of_get_flat_dt_prop(unsigned long node, const char *name, unsigned long *size) { - unsigned long p = node; - - do { - u32 tag = be32_to_cpup((__be32 *)p); - u32 sz, noff; - const char *nstr; - - p += 4; - if (tag == OF_DT_NOP) - continue; - if (tag != OF_DT_PROP) - return NULL; - - sz = be32_to_cpup((__be32 *)p); - noff = be32_to_cpup((__be32 *)(p + 4)); - p += 8; - if (be32_to_cpu(initial_boot_params->version) < 0x10) - p = ALIGN(p, sz >= 8 ? 8 : 4); - - nstr = find_flat_dt_string(noff); - if (nstr == NULL) { - pr_warning("Can't find property index name !\n"); - return NULL; - } - if (strcmp(name, nstr) == 0) { - if (size) - *size = sz; - return (void *)p; - } - p += sz; - p = ALIGN(p, 4); - } while (1); + return of_fdt_get_property(initial_boot_params, node, name, size); } /** @@ -164,21 +203,7 @@ void *__init of_get_flat_dt_prop(unsigned long node, const char *name, */ int __init of_flat_dt_is_compatible(unsigned long node, const char *compat) { - const char *cp; - unsigned long cplen, l; - - cp = of_get_flat_dt_prop(node, "compatible", &cplen); - if (cp == NULL) - return 0; - while (cplen > 0) { - if (of_compat_cmp(cp, compat, strlen(compat)) == 0) - return 1; - l = strlen(cp) + 1; - cp += l; - cplen -= l; - } - - return 0; + return of_fdt_is_compatible(initial_boot_params, node, compat); } static void *__init unflatten_dt_alloc(unsigned long *mem, unsigned long size, @@ -303,7 +328,7 @@ unsigned long __init unflatten_dt_node(unsigned long mem, if (be32_to_cpu(initial_boot_params->version) < 0x10) *p = ALIGN(*p, sz >= 8 ? 8 : 4); - pname = find_flat_dt_string(noff); + pname = of_fdt_get_string(initial_boot_params, noff); if (pname == NULL) { pr_info("Can't find property name in list !\n"); break; diff --git a/include/linux/of_fdt.h b/include/linux/of_fdt.h index 7bbf5b328438..70c5b736f0a3 100644 --- a/include/linux/of_fdt.h +++ b/include/linux/of_fdt.h @@ -58,6 +58,17 @@ struct boot_param_header { }; #if defined(CONFIG_OF_FLATTREE) + +/* For scanning an arbitrary device-tree at any time */ +extern char *of_fdt_get_string(struct boot_param_header *blob, u32 offset); +extern void *of_fdt_get_property(struct boot_param_header *blob, + unsigned long node, + const char *name, + unsigned long *size); +extern int of_fdt_is_compatible(struct boot_param_header *blob, + unsigned long node, + const char *compat); + /* TBD: Temporary export of fdt globals - remove when code fully merged */ extern int __initdata dt_root_addr_cells; extern int __initdata dt_root_size_cells; -- cgit v1.2.3 From a40d6c4cf12d87980c10b230df435d0f56adc40b Mon Sep 17 00:00:00 2001 From: Stephen Neuendorffer Date: Thu, 18 Nov 2010 15:55:00 -0800 Subject: of/flattree: Refactor unflatten_dt_node unflatten_dt_node is a helper function that does most of the work to convert a device tree blob into tree of device nodes. This code now uses a passed-in blob instead of using the single boot-time blob, allowing it to be called in more contexts. Signed-off-by: Stephen Neuendorffer Signed-off-by: Grant Likely --- drivers/of/fdt.c | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c index 10eab21076ea..cf74e546faf2 100644 --- a/drivers/of/fdt.c +++ b/drivers/of/fdt.c @@ -206,7 +206,7 @@ int __init of_flat_dt_is_compatible(unsigned long node, const char *compat) return of_fdt_is_compatible(initial_boot_params, node, compat); } -static void *__init unflatten_dt_alloc(unsigned long *mem, unsigned long size, +static void *unflatten_dt_alloc(unsigned long *mem, unsigned long size, unsigned long align) { void *res; @@ -220,16 +220,18 @@ static void *__init unflatten_dt_alloc(unsigned long *mem, unsigned long size, /** * unflatten_dt_node - Alloc and populate a device_node from the flat tree + * @blob: The parent device tree blob * @p: pointer to node in flat tree * @dad: Parent struct device_node * @allnextpp: pointer to ->allnext from last allocated device_node * @fpsize: Size of the node path up at the current depth. */ -unsigned long __init unflatten_dt_node(unsigned long mem, - unsigned long *p, - struct device_node *dad, - struct device_node ***allnextpp, - unsigned long fpsize) +unsigned long unflatten_dt_node(struct boot_param_header *blob, + unsigned long mem, + unsigned long *p, + struct device_node *dad, + struct device_node ***allnextpp, + unsigned long fpsize) { struct device_node *np; struct property *pp, **prev_pp = NULL; @@ -325,10 +327,10 @@ unsigned long __init unflatten_dt_node(unsigned long mem, sz = be32_to_cpup((__be32 *)(*p)); noff = be32_to_cpup((__be32 *)((*p) + 4)); *p += 8; - if (be32_to_cpu(initial_boot_params->version) < 0x10) + if (be32_to_cpu(blob->version) < 0x10) *p = ALIGN(*p, sz >= 8 ? 8 : 4); - pname = of_fdt_get_string(initial_boot_params, noff); + pname = of_fdt_get_string(blob, noff); if (pname == NULL) { pr_info("Can't find property name in list !\n"); break; @@ -407,7 +409,8 @@ unsigned long __init unflatten_dt_node(unsigned long mem, if (tag == OF_DT_NOP) *p += 4; else - mem = unflatten_dt_node(mem, p, np, allnextpp, fpsize); + mem = unflatten_dt_node(blob, mem, p, np, allnextpp, + fpsize); tag = be32_to_cpup((__be32 *)(*p)); } if (tag != OF_DT_END_NODE) { @@ -599,7 +602,8 @@ void __init unflatten_device_tree(void) /* First pass, scan for size */ start = ((unsigned long)initial_boot_params) + be32_to_cpu(initial_boot_params->off_dt_struct); - size = unflatten_dt_node(0, &start, NULL, NULL, 0); + size = unflatten_dt_node(initial_boot_params, 0, &start, + NULL, NULL, 0); size = (size | 3) + 1; pr_debug(" size is %lx, allocating...\n", size); @@ -616,7 +620,8 @@ void __init unflatten_device_tree(void) /* Second pass, do actual unflattening */ start = ((unsigned long)initial_boot_params) + be32_to_cpu(initial_boot_params->off_dt_struct); - unflatten_dt_node(mem, &start, NULL, &allnextp, 0); + unflatten_dt_node(initial_boot_params, mem, &start, + NULL, &allnextp, 0); if (be32_to_cpup((__be32 *)start) != OF_DT_END) pr_warning("Weird tag at end of tree: %08x\n", *((u32 *)start)); if (be32_to_cpu(((__be32 *)mem)[size / 4]) != 0xdeadbeef) -- cgit v1.2.3 From 57d00ecf90cc9854973da2960012b734acc26e51 Mon Sep 17 00:00:00 2001 From: Stephen Neuendorffer Date: Thu, 18 Nov 2010 15:55:01 -0800 Subject: of/flattree: Reorder unflatten_dt_node Move unflatten_dt_node to be grouped with non-__init functions. Signed-off-by: Stephen Neuendorffer Signed-off-by: Grant Likely --- drivers/of/fdt.c | 218 +++++++++++++++++++++++++++---------------------------- 1 file changed, 109 insertions(+), 109 deletions(-) diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c index cf74e546faf2..71edc9cecd62 100644 --- a/drivers/of/fdt.c +++ b/drivers/of/fdt.c @@ -97,115 +97,6 @@ int of_fdt_is_compatible(struct boot_param_header *blob, return 0; } -/* Everything below here references initial_boot_params directly. */ -int __initdata dt_root_addr_cells; -int __initdata dt_root_size_cells; - -struct boot_param_header *initial_boot_params; - -#ifdef CONFIG_OF_EARLY_FLATTREE - -/** - * of_scan_flat_dt - scan flattened tree blob and call callback on each. - * @it: callback function - * @data: context data pointer - * - * This function is used to scan the flattened device-tree, it is - * used to extract the memory information at boot before we can - * unflatten the tree - */ -int __init of_scan_flat_dt(int (*it)(unsigned long node, - const char *uname, int depth, - void *data), - void *data) -{ - unsigned long p = ((unsigned long)initial_boot_params) + - be32_to_cpu(initial_boot_params->off_dt_struct); - int rc = 0; - int depth = -1; - - do { - u32 tag = be32_to_cpup((__be32 *)p); - char *pathp; - - p += 4; - if (tag == OF_DT_END_NODE) { - depth--; - continue; - } - if (tag == OF_DT_NOP) - continue; - if (tag == OF_DT_END) - break; - if (tag == OF_DT_PROP) { - u32 sz = be32_to_cpup((__be32 *)p); - p += 8; - if (be32_to_cpu(initial_boot_params->version) < 0x10) - p = ALIGN(p, sz >= 8 ? 8 : 4); - p += sz; - p = ALIGN(p, 4); - continue; - } - if (tag != OF_DT_BEGIN_NODE) { - pr_err("Invalid tag %x in flat device tree!\n", tag); - return -EINVAL; - } - depth++; - pathp = (char *)p; - p = ALIGN(p + strlen(pathp) + 1, 4); - if ((*pathp) == '/') { - char *lp, *np; - for (lp = NULL, np = pathp; *np; np++) - if ((*np) == '/') - lp = np+1; - if (lp != NULL) - pathp = lp; - } - rc = it(p, pathp, depth, data); - if (rc != 0) - break; - } while (1); - - return rc; -} - -/** - * of_get_flat_dt_root - find the root node in the flat blob - */ -unsigned long __init of_get_flat_dt_root(void) -{ - unsigned long p = ((unsigned long)initial_boot_params) + - be32_to_cpu(initial_boot_params->off_dt_struct); - - while (be32_to_cpup((__be32 *)p) == OF_DT_NOP) - p += 4; - BUG_ON(be32_to_cpup((__be32 *)p) != OF_DT_BEGIN_NODE); - p += 4; - return ALIGN(p + strlen((char *)p) + 1, 4); -} - -/** - * of_get_flat_dt_prop - Given a node in the flat blob, return the property ptr - * - * This function can be used within scan_flattened_dt callback to get - * access to properties - */ -void *__init of_get_flat_dt_prop(unsigned long node, const char *name, - unsigned long *size) -{ - return of_fdt_get_property(initial_boot_params, node, name, size); -} - -/** - * of_flat_dt_is_compatible - Return true if given node has compat in compatible list - * @node: node to test - * @compat: compatible string to compare with compatible list. - */ -int __init of_flat_dt_is_compatible(unsigned long node, const char *compat) -{ - return of_fdt_is_compatible(initial_boot_params, node, compat); -} - static void *unflatten_dt_alloc(unsigned long *mem, unsigned long size, unsigned long align) { @@ -421,6 +312,115 @@ unsigned long unflatten_dt_node(struct boot_param_header *blob, return mem; } +/* Everything below here references initial_boot_params directly. */ +int __initdata dt_root_addr_cells; +int __initdata dt_root_size_cells; + +struct boot_param_header *initial_boot_params; + +#ifdef CONFIG_OF_EARLY_FLATTREE + +/** + * of_scan_flat_dt - scan flattened tree blob and call callback on each. + * @it: callback function + * @data: context data pointer + * + * This function is used to scan the flattened device-tree, it is + * used to extract the memory information at boot before we can + * unflatten the tree + */ +int __init of_scan_flat_dt(int (*it)(unsigned long node, + const char *uname, int depth, + void *data), + void *data) +{ + unsigned long p = ((unsigned long)initial_boot_params) + + be32_to_cpu(initial_boot_params->off_dt_struct); + int rc = 0; + int depth = -1; + + do { + u32 tag = be32_to_cpup((__be32 *)p); + char *pathp; + + p += 4; + if (tag == OF_DT_END_NODE) { + depth--; + continue; + } + if (tag == OF_DT_NOP) + continue; + if (tag == OF_DT_END) + break; + if (tag == OF_DT_PROP) { + u32 sz = be32_to_cpup((__be32 *)p); + p += 8; + if (be32_to_cpu(initial_boot_params->version) < 0x10) + p = ALIGN(p, sz >= 8 ? 8 : 4); + p += sz; + p = ALIGN(p, 4); + continue; + } + if (tag != OF_DT_BEGIN_NODE) { + pr_err("Invalid tag %x in flat device tree!\n", tag); + return -EINVAL; + } + depth++; + pathp = (char *)p; + p = ALIGN(p + strlen(pathp) + 1, 4); + if ((*pathp) == '/') { + char *lp, *np; + for (lp = NULL, np = pathp; *np; np++) + if ((*np) == '/') + lp = np+1; + if (lp != NULL) + pathp = lp; + } + rc = it(p, pathp, depth, data); + if (rc != 0) + break; + } while (1); + + return rc; +} + +/** + * of_get_flat_dt_root - find the root node in the flat blob + */ +unsigned long __init of_get_flat_dt_root(void) +{ + unsigned long p = ((unsigned long)initial_boot_params) + + be32_to_cpu(initial_boot_params->off_dt_struct); + + while (be32_to_cpup((__be32 *)p) == OF_DT_NOP) + p += 4; + BUG_ON(be32_to_cpup((__be32 *)p) != OF_DT_BEGIN_NODE); + p += 4; + return ALIGN(p + strlen((char *)p) + 1, 4); +} + +/** + * of_get_flat_dt_prop - Given a node in the flat blob, return the property ptr + * + * This function can be used within scan_flattened_dt callback to get + * access to properties + */ +void *__init of_get_flat_dt_prop(unsigned long node, const char *name, + unsigned long *size) +{ + return of_fdt_get_property(initial_boot_params, node, name, size); +} + +/** + * of_flat_dt_is_compatible - Return true if given node has compat in compatible list + * @node: node to test + * @compat: compatible string to compare with compatible list. + */ +int __init of_flat_dt_is_compatible(unsigned long node, const char *compat) +{ + return of_fdt_is_compatible(initial_boot_params, node, compat); +} + #ifdef CONFIG_BLK_DEV_INITRD /** * early_init_dt_check_for_initrd - Decode initrd location from flat tree -- cgit v1.2.3 From fe14042358fac0673d4b6362a73796fd64379938 Mon Sep 17 00:00:00 2001 From: Stephen Neuendorffer Date: Thu, 18 Nov 2010 15:55:02 -0800 Subject: of/flattree: Refactor unflatten_device_tree and add fdt_unflatten_tree unflatten_device_tree has two dependencies on things that happen during boot time. Firstly, it references the initial device tree directly. Secondly, it allocates memory using the early boot allocator. This patch factors out these dependencies and uses the new __unflatten_device_tree function to implement a driver-visible fdt_unflatten_tree function, which can be used to unflatten a blob after boot time. V2: - remove extra __va() call - make dt_alloc functions return void *. This doesn't fix the general strangeness in this code that constantly casts back and forth between unsigned long and __be32 * Signed-off-by: Stephen Neuendorffer Signed-off-by: Grant Likely --- drivers/of/fdt.c | 149 ++++++++++++++++++++++++++++++++----------------- include/linux/of_fdt.h | 2 + 2 files changed, 100 insertions(+), 51 deletions(-) diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c index 71edc9cecd62..8a90ee42071a 100644 --- a/drivers/of/fdt.c +++ b/drivers/of/fdt.c @@ -11,10 +11,12 @@ #include #include +#include #include #include #include #include +#include #ifdef CONFIG_PPC #include @@ -312,6 +314,94 @@ unsigned long unflatten_dt_node(struct boot_param_header *blob, return mem; } +/** + * __unflatten_device_tree - create tree of device_nodes from flat blob + * + * unflattens a device-tree, creating the + * tree of struct device_node. It also fills the "name" and "type" + * pointers of the nodes so the normal device-tree walking functions + * can be used. + * @blob: The blob to expand + * @mynodes: The device_node tree created by the call + * @dt_alloc: An allocator that provides a virtual address to memory + * for the resulting tree + */ +void __unflatten_device_tree(struct boot_param_header *blob, + struct device_node **mynodes, + void * (*dt_alloc)(u64 size, u64 align)) +{ + unsigned long start, mem, size; + struct device_node **allnextp = mynodes; + + pr_debug(" -> unflatten_device_tree()\n"); + + if (!blob) { + pr_debug("No device tree pointer\n"); + return; + } + + pr_debug("Unflattening device tree:\n"); + pr_debug("magic: %08x\n", be32_to_cpu(blob->magic)); + pr_debug("size: %08x\n", be32_to_cpu(blob->totalsize)); + pr_debug("version: %08x\n", be32_to_cpu(blob->version)); + + if (be32_to_cpu(blob->magic) != OF_DT_HEADER) { + pr_err("Invalid device tree blob header\n"); + return; + } + + /* First pass, scan for size */ + start = ((unsigned long)blob) + + be32_to_cpu(blob->off_dt_struct); + size = unflatten_dt_node(blob, 0, &start, NULL, NULL, 0); + size = (size | 3) + 1; + + pr_debug(" size is %lx, allocating...\n", size); + + /* Allocate memory for the expanded device tree */ + mem = (unsigned long) + dt_alloc(size + 4, __alignof__(struct device_node)); + + ((__be32 *)mem)[size / 4] = cpu_to_be32(0xdeadbeef); + + pr_debug(" unflattening %lx...\n", mem); + + /* Second pass, do actual unflattening */ + start = ((unsigned long)blob) + + be32_to_cpu(blob->off_dt_struct); + unflatten_dt_node(blob, mem, &start, NULL, &allnextp, 0); + if (be32_to_cpup((__be32 *)start) != OF_DT_END) + pr_warning("Weird tag at end of tree: %08x\n", *((u32 *)start)); + if (be32_to_cpu(((__be32 *)mem)[size / 4]) != 0xdeadbeef) + pr_warning("End of tree marker overwritten: %08x\n", + be32_to_cpu(((__be32 *)mem)[size / 4])); + *allnextp = NULL; + + pr_debug(" <- unflatten_device_tree()\n"); +} + +static void *kernel_tree_alloc(u64 size, u64 align) +{ + return kzalloc(size, GFP_KERNEL); +} + +/** + * of_fdt_unflatten_tree - create tree of device_nodes from flat blob + * + * unflattens the device-tree passed by the firmware, creating the + * tree of struct device_node. It also fills the "name" and "type" + * pointers of the nodes so the normal device-tree walking functions + * can be used. + */ +void of_fdt_unflatten_tree(unsigned long *blob, + struct device_node **mynodes) +{ + struct boot_param_header *device_tree = + (struct boot_param_header *)blob; + __unflatten_device_tree(device_tree, mynodes, &kernel_tree_alloc); +} +EXPORT_SYMBOL_GPL(of_fdt_unflatten_tree); + /* Everything below here references initial_boot_params directly. */ int __initdata dt_root_addr_cells; int __initdata dt_root_size_cells; @@ -569,6 +659,12 @@ int __init early_init_dt_scan_chosen(unsigned long node, const char *uname, return 1; } +static void *__init early_device_tree_alloc(u64 size, u64 align) +{ + unsigned long mem = early_init_dt_alloc_memory_arch(size, align); + return __va(mem); +} + /** * unflatten_device_tree - create tree of device_nodes from flat blob * @@ -579,62 +675,13 @@ int __init early_init_dt_scan_chosen(unsigned long node, const char *uname, */ void __init unflatten_device_tree(void) { - unsigned long start, mem, size; - struct device_node **allnextp = &allnodes; - - pr_debug(" -> unflatten_device_tree()\n"); - - if (!initial_boot_params) { - pr_debug("No device tree pointer\n"); - return; - } - - pr_debug("Unflattening device tree:\n"); - pr_debug("magic: %08x\n", be32_to_cpu(initial_boot_params->magic)); - pr_debug("size: %08x\n", be32_to_cpu(initial_boot_params->totalsize)); - pr_debug("version: %08x\n", be32_to_cpu(initial_boot_params->version)); - - if (be32_to_cpu(initial_boot_params->magic) != OF_DT_HEADER) { - pr_err("Invalid device tree blob header\n"); - return; - } - - /* First pass, scan for size */ - start = ((unsigned long)initial_boot_params) + - be32_to_cpu(initial_boot_params->off_dt_struct); - size = unflatten_dt_node(initial_boot_params, 0, &start, - NULL, NULL, 0); - size = (size | 3) + 1; - - pr_debug(" size is %lx, allocating...\n", size); - - /* Allocate memory for the expanded device tree */ - mem = early_init_dt_alloc_memory_arch(size + 4, - __alignof__(struct device_node)); - mem = (unsigned long) __va(mem); - - ((__be32 *)mem)[size / 4] = cpu_to_be32(0xdeadbeef); - - pr_debug(" unflattening %lx...\n", mem); - - /* Second pass, do actual unflattening */ - start = ((unsigned long)initial_boot_params) + - be32_to_cpu(initial_boot_params->off_dt_struct); - unflatten_dt_node(initial_boot_params, mem, &start, - NULL, &allnextp, 0); - if (be32_to_cpup((__be32 *)start) != OF_DT_END) - pr_warning("Weird tag at end of tree: %08x\n", *((u32 *)start)); - if (be32_to_cpu(((__be32 *)mem)[size / 4]) != 0xdeadbeef) - pr_warning("End of tree marker overwritten: %08x\n", - be32_to_cpu(((__be32 *)mem)[size / 4])); - *allnextp = NULL; + __unflatten_device_tree(initial_boot_params, &allnodes, + early_device_tree_alloc); /* Get pointer to OF "/chosen" node for use everywhere */ of_chosen = of_find_node_by_path("/chosen"); if (of_chosen == NULL) of_chosen = of_find_node_by_path("/chosen@0"); - - pr_debug(" <- unflatten_device_tree()\n"); } #endif /* CONFIG_OF_EARLY_FLATTREE */ diff --git a/include/linux/of_fdt.h b/include/linux/of_fdt.h index 70c5b736f0a3..9ce5dfd2186a 100644 --- a/include/linux/of_fdt.h +++ b/include/linux/of_fdt.h @@ -68,6 +68,8 @@ extern void *of_fdt_get_property(struct boot_param_header *blob, extern int of_fdt_is_compatible(struct boot_param_header *blob, unsigned long node, const char *compat); +extern void of_fdt_unflatten_tree(unsigned long *blob, + struct device_node **mynodes); /* TBD: Temporary export of fdt globals - remove when code fully merged */ extern int __initdata dt_root_addr_cells; -- cgit v1.2.3 From f5aeffb784f35f82b048969a4d7bcca42c783c84 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 2 Dec 2010 14:35:38 +0900 Subject: ARM: SAMSUNG: Convert s3c_irqext_wake() to new irq_ interrupt methods Kernel 2.6.37 adds new interrupt methods which take a struct irq_data rather than an irq number. Begin converting Samsung platforms over to these methods by converting s3c_irqext_wake() with a simple textual substitution. Signed-off-by: Mark Brown Cc: Ben Dooks Signed-off-by: Kukjin Kim --- arch/arm/mach-s3c64xx/irq-eint.c | 2 +- arch/arm/mach-s5pv310/irq-eint.c | 2 +- arch/arm/plat-s3c24xx/irq.c | 2 +- arch/arm/plat-s5p/irq-eint.c | 4 ++-- arch/arm/plat-samsung/include/plat/pm.h | 4 +++- arch/arm/plat-samsung/pm.c | 6 +++--- 6 files changed, 11 insertions(+), 9 deletions(-) diff --git a/arch/arm/mach-s3c64xx/irq-eint.c b/arch/arm/mach-s3c64xx/irq-eint.c index 5682d6a7f4af..1a1aa5da431d 100644 --- a/arch/arm/mach-s3c64xx/irq-eint.c +++ b/arch/arm/mach-s3c64xx/irq-eint.c @@ -145,7 +145,7 @@ static struct irq_chip s3c_irq_eint = { .mask_ack = s3c_irq_eint_maskack, .ack = s3c_irq_eint_ack, .set_type = s3c_irq_eint_set_type, - .set_wake = s3c_irqext_wake, + .irq_set_wake = s3c_irqext_wake, }; /* s3c_irq_demux_eint diff --git a/arch/arm/mach-s5pv310/irq-eint.c b/arch/arm/mach-s5pv310/irq-eint.c index 5877503e92c3..f5a415edc0b6 100644 --- a/arch/arm/mach-s5pv310/irq-eint.c +++ b/arch/arm/mach-s5pv310/irq-eint.c @@ -152,7 +152,7 @@ static struct irq_chip s5pv310_irq_eint = { .ack = s5pv310_irq_eint_ack, .set_type = s5pv310_irq_eint_set_type, #ifdef CONFIG_PM - .set_wake = s3c_irqext_wake, + .irq_set_wake = s3c_irqext_wake, #endif }; diff --git a/arch/arm/plat-s3c24xx/irq.c b/arch/arm/plat-s3c24xx/irq.c index ad0d44ef1f93..91ce38393ba6 100644 --- a/arch/arm/plat-s3c24xx/irq.c +++ b/arch/arm/plat-s3c24xx/irq.c @@ -238,7 +238,7 @@ static struct irq_chip s3c_irqext_chip = { .unmask = s3c_irqext_unmask, .ack = s3c_irqext_ack, .set_type = s3c_irqext_type, - .set_wake = s3c_irqext_wake + .irq_set_wake = s3c_irqext_wake }; static struct irq_chip s3c_irq_eint0t4 = { diff --git a/arch/arm/plat-s5p/irq-eint.c b/arch/arm/plat-s5p/irq-eint.c index 752f1a645f9d..f2f2e1ccd0e6 100644 --- a/arch/arm/plat-s5p/irq-eint.c +++ b/arch/arm/plat-s5p/irq-eint.c @@ -125,7 +125,7 @@ static struct irq_chip s5p_irq_eint = { .ack = s5p_irq_eint_ack, .set_type = s5p_irq_eint_set_type, #ifdef CONFIG_PM - .set_wake = s3c_irqext_wake, + .irq_set_wake = s3c_irqext_wake, #endif }; @@ -194,7 +194,7 @@ static struct irq_chip s5p_irq_vic_eint = { .ack = s5p_irq_vic_eint_ack, .set_type = s5p_irq_eint_set_type, #ifdef CONFIG_PM - .set_wake = s3c_irqext_wake, + .irq_set_wake = s3c_irqext_wake, #endif }; diff --git a/arch/arm/plat-samsung/include/plat/pm.h b/arch/arm/plat-samsung/include/plat/pm.h index 245836d91931..d9025e377675 100644 --- a/arch/arm/plat-samsung/include/plat/pm.h +++ b/arch/arm/plat-samsung/include/plat/pm.h @@ -15,6 +15,8 @@ * management */ +#include + #ifdef CONFIG_PM extern __init int s3c_pm_init(void); @@ -100,7 +102,7 @@ extern void s3c_pm_do_restore(struct sleep_save *ptr, int count); extern void s3c_pm_do_restore_core(struct sleep_save *ptr, int count); #ifdef CONFIG_PM -extern int s3c_irqext_wake(unsigned int irqno, unsigned int state); +extern int s3c_irqext_wake(struct irq_data *data, unsigned int state); extern int s3c24xx_irq_suspend(struct sys_device *dev, pm_message_t state); extern int s3c24xx_irq_resume(struct sys_device *dev); #else diff --git a/arch/arm/plat-samsung/pm.c b/arch/arm/plat-samsung/pm.c index 27cfca597699..eaa57dc969ae 100644 --- a/arch/arm/plat-samsung/pm.c +++ b/arch/arm/plat-samsung/pm.c @@ -136,15 +136,15 @@ static void s3c_pm_restore_uarts(void) { } unsigned long s3c_irqwake_intmask = 0xffffffffL; unsigned long s3c_irqwake_eintmask = 0xffffffffL; -int s3c_irqext_wake(unsigned int irqno, unsigned int state) +int s3c_irqext_wake(struct irq_data *data, unsigned int state) { - unsigned long bit = 1L << IRQ_EINT_BIT(irqno); + unsigned long bit = 1L << IRQ_EINT_BIT(data->irq); if (!(s3c_irqwake_eintallow & bit)) return -ENOENT; printk(KERN_INFO "wake %s for irq %d\n", - state ? "enabled" : "disabled", irqno); + state ? "enabled" : "disabled", data->irq); if (!state) s3c_irqwake_eintmask |= bit; -- cgit v1.2.3 From c35cd6ec36a619dfd72d95d719ac926511d3f0e4 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 2 Dec 2010 14:35:38 +0900 Subject: ARM: S3C64XX: Convert S3C64xx irq-eint to use new irq_ methods Kernel 2.6.37 adds new interrupt methods which take a struct irq_data rather than an irq number. Conver S3C64xx irq-eint to use this with a simple textual substitution. Signed-off-by: Mark Brown Cc: Ben Dooks Signed-off-by: Kukjin Kim --- arch/arm/mach-s3c64xx/irq-eint.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/arch/arm/mach-s3c64xx/irq-eint.c b/arch/arm/mach-s3c64xx/irq-eint.c index 1a1aa5da431d..169ee29d37d7 100644 --- a/arch/arm/mach-s3c64xx/irq-eint.c +++ b/arch/arm/mach-s3c64xx/irq-eint.c @@ -32,39 +32,39 @@ #define eint_offset(irq) ((irq) - IRQ_EINT(0)) #define eint_irq_to_bit(irq) (1 << eint_offset(irq)) -static inline void s3c_irq_eint_mask(unsigned int irq) +static inline void s3c_irq_eint_mask(struct irq_data *data) { u32 mask; mask = __raw_readl(S3C64XX_EINT0MASK); - mask |= eint_irq_to_bit(irq); + mask |= eint_irq_to_bit(data->irq); __raw_writel(mask, S3C64XX_EINT0MASK); } -static void s3c_irq_eint_unmask(unsigned int irq) +static void s3c_irq_eint_unmask(struct irq_data *data) { u32 mask; mask = __raw_readl(S3C64XX_EINT0MASK); - mask &= ~eint_irq_to_bit(irq); + mask &= ~eint_irq_to_bit(data->irq); __raw_writel(mask, S3C64XX_EINT0MASK); } -static inline void s3c_irq_eint_ack(unsigned int irq) +static inline void s3c_irq_eint_ack(struct irq_data *data) { - __raw_writel(eint_irq_to_bit(irq), S3C64XX_EINT0PEND); + __raw_writel(eint_irq_to_bit(data->irq), S3C64XX_EINT0PEND); } -static void s3c_irq_eint_maskack(unsigned int irq) +static void s3c_irq_eint_maskack(struct irq_data *data) { /* compiler should in-line these */ - s3c_irq_eint_mask(irq); - s3c_irq_eint_ack(irq); + s3c_irq_eint_mask(data); + s3c_irq_eint_ack(data); } -static int s3c_irq_eint_set_type(unsigned int irq, unsigned int type) +static int s3c_irq_eint_set_type(struct irq_data *data, unsigned int type) { - int offs = eint_offset(irq); + int offs = eint_offset(data->irq); int pin, pin_val; int shift; u32 ctrl, mask; @@ -140,11 +140,11 @@ static int s3c_irq_eint_set_type(unsigned int irq, unsigned int type) static struct irq_chip s3c_irq_eint = { .name = "s3c-eint", - .mask = s3c_irq_eint_mask, - .unmask = s3c_irq_eint_unmask, - .mask_ack = s3c_irq_eint_maskack, - .ack = s3c_irq_eint_ack, - .set_type = s3c_irq_eint_set_type, + .irq_mask = s3c_irq_eint_mask, + .irq_unmask = s3c_irq_eint_unmask, + .irq_mask_ack = s3c_irq_eint_maskack, + .irq_ack = s3c_irq_eint_ack, + .irq_set_type = s3c_irq_eint_set_type, .irq_set_wake = s3c_irqext_wake, }; -- cgit v1.2.3 From 3c9169753b42c34c9c5ed96a0e55f417a2f65d77 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 2 Dec 2010 14:35:38 +0900 Subject: ARM: S3C64XX: Use chip_data to store the shift for EINTs This makes all the functions that use the shift slightly smaller, one instruction in most cases but more for ack() and maskack(). Signed-off-by: Mark Brown Cc: Ben Dooks Signed-off-by: Kukjin Kim --- arch/arm/mach-s3c64xx/irq-eint.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/arch/arm/mach-s3c64xx/irq-eint.c b/arch/arm/mach-s3c64xx/irq-eint.c index 169ee29d37d7..2ead8189da74 100644 --- a/arch/arm/mach-s3c64xx/irq-eint.c +++ b/arch/arm/mach-s3c64xx/irq-eint.c @@ -30,14 +30,14 @@ #include #define eint_offset(irq) ((irq) - IRQ_EINT(0)) -#define eint_irq_to_bit(irq) (1 << eint_offset(irq)) +#define eint_irq_to_bit(irq) ((u32)(1 << eint_offset(irq))) static inline void s3c_irq_eint_mask(struct irq_data *data) { u32 mask; mask = __raw_readl(S3C64XX_EINT0MASK); - mask |= eint_irq_to_bit(data->irq); + mask |= (u32)data->chip_data; __raw_writel(mask, S3C64XX_EINT0MASK); } @@ -46,13 +46,13 @@ static void s3c_irq_eint_unmask(struct irq_data *data) u32 mask; mask = __raw_readl(S3C64XX_EINT0MASK); - mask &= ~eint_irq_to_bit(data->irq); + mask &= ~((u32)data->chip_data); __raw_writel(mask, S3C64XX_EINT0MASK); } static inline void s3c_irq_eint_ack(struct irq_data *data) { - __raw_writel(eint_irq_to_bit(data->irq), S3C64XX_EINT0PEND); + __raw_writel((u32)data->chip_data, S3C64XX_EINT0PEND); } static void s3c_irq_eint_maskack(struct irq_data *data) @@ -198,6 +198,7 @@ static int __init s3c64xx_init_irq_eint(void) for (irq = IRQ_EINT(0); irq <= IRQ_EINT(27); irq++) { set_irq_chip(irq, &s3c_irq_eint); + set_irq_chip_data(irq, (void *)eint_irq_to_bit(irq)); set_irq_handler(irq, handle_level_irq); set_irq_flags(irq, IRQF_VALID); } -- cgit v1.2.3 From 27b31e56239b44608cad176c36c384c0265f8da5 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 3 Dec 2010 20:28:21 +0900 Subject: ARM: SAMSUNG: Convert irq-uart to use new irq_ functions Convert to the new irq_ versions of the IRQ operations. As well as the textual substituion of irq_data for the raw IRQ number we also convert the register base lookup to in s3c_irq_uart_base() to pick the irq_data up directly. Signed-off-by: Mark Brown Signed-off-by: Kukjin Kim --- arch/arm/plat-samsung/irq-uart.c | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/arch/arm/plat-samsung/irq-uart.c b/arch/arm/plat-samsung/irq-uart.c index 4f8c102674ae..da31d785cbd1 100644 --- a/arch/arm/plat-samsung/irq-uart.c +++ b/arch/arm/plat-samsung/irq-uart.c @@ -28,9 +28,9 @@ * are consecutive when looking up the interrupt in the demux routines. */ -static inline void __iomem *s3c_irq_uart_base(unsigned int irq) +static inline void __iomem *s3c_irq_uart_base(struct irq_data *data) { - struct s3c_uart_irq *uirq = get_irq_chip_data(irq); + struct s3c_uart_irq *uirq = data->chip_data; return uirq->regs; } @@ -39,10 +39,10 @@ static inline unsigned int s3c_irq_uart_bit(unsigned int irq) return irq & 3; } -static void s3c_irq_uart_mask(unsigned int irq) +static void s3c_irq_uart_mask(struct irq_data *data) { - void __iomem *regs = s3c_irq_uart_base(irq); - unsigned int bit = s3c_irq_uart_bit(irq); + void __iomem *regs = s3c_irq_uart_base(data); + unsigned int bit = s3c_irq_uart_bit(data->irq); u32 reg; reg = __raw_readl(regs + S3C64XX_UINTM); @@ -50,10 +50,10 @@ static void s3c_irq_uart_mask(unsigned int irq) __raw_writel(reg, regs + S3C64XX_UINTM); } -static void s3c_irq_uart_maskack(unsigned int irq) +static void s3c_irq_uart_maskack(struct irq_data *data) { - void __iomem *regs = s3c_irq_uart_base(irq); - unsigned int bit = s3c_irq_uart_bit(irq); + void __iomem *regs = s3c_irq_uart_base(data); + unsigned int bit = s3c_irq_uart_bit(data->irq); u32 reg; reg = __raw_readl(regs + S3C64XX_UINTM); @@ -62,10 +62,10 @@ static void s3c_irq_uart_maskack(unsigned int irq) __raw_writel(1 << bit, regs + S3C64XX_UINTP); } -static void s3c_irq_uart_unmask(unsigned int irq) +static void s3c_irq_uart_unmask(struct irq_data *data) { - void __iomem *regs = s3c_irq_uart_base(irq); - unsigned int bit = s3c_irq_uart_bit(irq); + void __iomem *regs = s3c_irq_uart_base(data); + unsigned int bit = s3c_irq_uart_bit(data->irq); u32 reg; reg = __raw_readl(regs + S3C64XX_UINTM); @@ -73,10 +73,10 @@ static void s3c_irq_uart_unmask(unsigned int irq) __raw_writel(reg, regs + S3C64XX_UINTM); } -static void s3c_irq_uart_ack(unsigned int irq) +static void s3c_irq_uart_ack(struct irq_data *data) { - void __iomem *regs = s3c_irq_uart_base(irq); - unsigned int bit = s3c_irq_uart_bit(irq); + void __iomem *regs = s3c_irq_uart_base(data); + unsigned int bit = s3c_irq_uart_bit(data->irq); __raw_writel(1 << bit, regs + S3C64XX_UINTP); } @@ -99,10 +99,10 @@ static void s3c_irq_demux_uart(unsigned int irq, struct irq_desc *desc) static struct irq_chip s3c_irq_uart = { .name = "s3c-uart", - .mask = s3c_irq_uart_mask, - .unmask = s3c_irq_uart_unmask, - .mask_ack = s3c_irq_uart_maskack, - .ack = s3c_irq_uart_ack, + .irq_mask = s3c_irq_uart_mask, + .irq_unmask = s3c_irq_uart_unmask, + .irq_mask_ack = s3c_irq_uart_maskack, + .irq_ack = s3c_irq_uart_ack, }; static void __init s3c_init_uart_irq(struct s3c_uart_irq *uirq) -- cgit v1.2.3 From df3d02962bc39155c8b4214ce6f0e84750c7921f Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 3 Dec 2010 20:28:21 +0900 Subject: ARM: SAMSUNG: Convert irq-vic-timer to irq_ functions Conver the VIC timer interrupts to use the irq_ versions of the IRQ operatiosn introduced in 2.6.37, storing the mask for the timer interrupt in the chip_data of the irq_data in order to save having to do a substraction and a shift on every operation. Signed-off-by: Mark Brown Signed-off-by: Kukjin Kim --- arch/arm/plat-samsung/irq-vic-timer.c | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/arch/arm/plat-samsung/irq-vic-timer.c b/arch/arm/plat-samsung/irq-vic-timer.c index 0270519fcabc..7ce77ddb729d 100644 --- a/arch/arm/plat-samsung/irq-vic-timer.c +++ b/arch/arm/plat-samsung/irq-vic-timer.c @@ -29,38 +29,41 @@ static void s3c_irq_demux_vic_timer(unsigned int irq, struct irq_desc *desc) /* We assume the IRQ_TIMER0..IRQ_TIMER4 range is continuous. */ -static void s3c_irq_timer_mask(unsigned int irq) +static void s3c_irq_timer_mask(struct irq_data *data) { u32 reg = __raw_readl(S3C64XX_TINT_CSTAT); + u32 mask = (u32)data->chip_data; reg &= 0x1f; /* mask out pending interrupts */ - reg &= ~(1 << (irq - IRQ_TIMER0)); + reg &= ~mask; __raw_writel(reg, S3C64XX_TINT_CSTAT); } -static void s3c_irq_timer_unmask(unsigned int irq) +static void s3c_irq_timer_unmask(struct irq_data *data) { u32 reg = __raw_readl(S3C64XX_TINT_CSTAT); + u32 mask = (u32)data->chip_data; reg &= 0x1f; /* mask out pending interrupts */ - reg |= 1 << (irq - IRQ_TIMER0); + reg |= mask; __raw_writel(reg, S3C64XX_TINT_CSTAT); } -static void s3c_irq_timer_ack(unsigned int irq) +static void s3c_irq_timer_ack(struct irq_data *data) { u32 reg = __raw_readl(S3C64XX_TINT_CSTAT); + u32 mask = (u32)data->chip_data; reg &= 0x1f; - reg |= (1 << 5) << (irq - IRQ_TIMER0); + reg |= mask << 5; __raw_writel(reg, S3C64XX_TINT_CSTAT); } static struct irq_chip s3c_irq_timer = { .name = "s3c-timer", - .mask = s3c_irq_timer_mask, - .unmask = s3c_irq_timer_unmask, - .ack = s3c_irq_timer_ack, + .irq_mask = s3c_irq_timer_mask, + .irq_unmask = s3c_irq_timer_unmask, + .irq_ack = s3c_irq_timer_ack, }; /** @@ -79,6 +82,7 @@ void __init s3c_init_vic_timer_irq(unsigned int parent_irq, set_irq_chained_handler(parent_irq, s3c_irq_demux_vic_timer); set_irq_chip(timer_irq, &s3c_irq_timer); + set_irq_chip_data(timer_irq, (void *)(1 << (timer_irq - IRQ_TIMER0))); set_irq_handler(timer_irq, handle_level_irq); set_irq_flags(timer_irq, IRQF_VALID); -- cgit v1.2.3 From d930596a3c093bf3f4fbf24f10ad0d8372d6ac21 Mon Sep 17 00:00:00 2001 From: Changhwan Youn Date: Fri, 3 Dec 2010 17:14:57 +0900 Subject: ARM: SAMSUNG: Add support for Power Domain control This patch implements Power Domain control based on Runtime PM framework. Each Power Domain is represented by a Power Domain device and the devices belong to these Power Domains should be set as a child device of the Power Domain devices. The corresponding drivers of the devices should implement Runtime PM to control the Power Domains. Signed-off-by: Changhwan Youn Signed-off-by: Kukjin Kim --- arch/arm/plat-samsung/Kconfig | 8 +++ arch/arm/plat-samsung/Makefile | 4 ++ arch/arm/plat-samsung/include/plat/pd.h | 30 +++++++++++ arch/arm/plat-samsung/pd.c | 95 +++++++++++++++++++++++++++++++++ 4 files changed, 137 insertions(+) create mode 100644 arch/arm/plat-samsung/include/plat/pd.h create mode 100644 arch/arm/plat-samsung/pd.c diff --git a/arch/arm/plat-samsung/Kconfig b/arch/arm/plat-samsung/Kconfig index dcd6eff4ee53..2ebf4157d93a 100644 --- a/arch/arm/plat-samsung/Kconfig +++ b/arch/arm/plat-samsung/Kconfig @@ -333,4 +333,12 @@ config SAMSUNG_WAKEMASK and above. This code allows a set of interrupt to wakeup-mask mappings. See +comment "Power Domain" + +config SAMSUNG_PD + bool "Samsung Power Domain" + depends on PM_RUNTIME + help + Say Y here if you want to control Power Domain by Runtime PM. + endif diff --git a/arch/arm/plat-samsung/Makefile b/arch/arm/plat-samsung/Makefile index afcce474af8e..09dbd78b56f5 100644 --- a/arch/arm/plat-samsung/Makefile +++ b/arch/arm/plat-samsung/Makefile @@ -73,6 +73,10 @@ obj-$(CONFIG_SAMSUNG_PM_CHECK) += pm-check.o obj-$(CONFIG_SAMSUNG_WAKEMASK) += wakeup-mask.o +# PD support + +obj-$(CONFIG_SAMSUNG_PD) += pd.o + # PWM support obj-$(CONFIG_HAVE_PWM) += pwm.o diff --git a/arch/arm/plat-samsung/include/plat/pd.h b/arch/arm/plat-samsung/include/plat/pd.h new file mode 100644 index 000000000000..5f0ad85783db --- /dev/null +++ b/arch/arm/plat-samsung/include/plat/pd.h @@ -0,0 +1,30 @@ +/* linux/arch/arm/plat-samsung/include/plat/pd.h + * + * Copyright (c) 2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * 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. +*/ + +#ifndef __ASM_PLAT_SAMSUNG_PD_H +#define __ASM_PLAT_SAMSUNG_PD_H __FILE__ + +struct samsung_pd_info { + int (*enable)(struct device *dev); + int (*disable)(struct device *dev); + void __iomem *base; +}; + +enum s5pv310_pd_block { + PD_MFC, + PD_G3D, + PD_LCD0, + PD_LCD1, + PD_TV, + PD_CAM, + PD_GPS +}; + +#endif /* __ASM_PLAT_SAMSUNG_PD_H */ diff --git a/arch/arm/plat-samsung/pd.c b/arch/arm/plat-samsung/pd.c new file mode 100644 index 000000000000..efe1d564473e --- /dev/null +++ b/arch/arm/plat-samsung/pd.c @@ -0,0 +1,95 @@ +/* linux/arch/arm/plat-samsung/pd.c + * + * Copyright (c) 2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * Samsung Power domain support + * + * 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 +#include + +#include + +static int samsung_pd_probe(struct platform_device *pdev) +{ + struct samsung_pd_info *pdata = pdev->dev.platform_data; + struct device *dev = &pdev->dev; + + if (!pdata) { + dev_err(dev, "no device data specified\n"); + return -ENOENT; + } + + pm_runtime_set_active(dev); + pm_runtime_enable(dev); + + dev_info(dev, "power domain registered\n"); + return 0; +} + +static int __devexit samsung_pd_remove(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + + pm_runtime_disable(dev); + return 0; +} + +static int samsung_pd_runtime_suspend(struct device *dev) +{ + struct samsung_pd_info *pdata = dev->platform_data; + int ret = 0; + + if (pdata->disable) + ret = pdata->disable(dev); + + dev_dbg(dev, "suspended\n"); + return ret; +} + +static int samsung_pd_runtime_resume(struct device *dev) +{ + struct samsung_pd_info *pdata = dev->platform_data; + int ret = 0; + + if (pdata->enable) + ret = pdata->enable(dev); + + dev_dbg(dev, "resumed\n"); + return ret; +} + +static const struct dev_pm_ops samsung_pd_pm_ops = { + .runtime_suspend = samsung_pd_runtime_suspend, + .runtime_resume = samsung_pd_runtime_resume, +}; + +static struct platform_driver samsung_pd_driver = { + .driver = { + .name = "samsung-pd", + .owner = THIS_MODULE, + .pm = &samsung_pd_pm_ops, + }, + .probe = samsung_pd_probe, + .remove = __devexit_p(samsung_pd_remove), +}; + +static int __init samsung_pd_init(void) +{ + int ret; + + ret = platform_driver_register(&samsung_pd_driver); + if (ret) + printk(KERN_ERR "%s: failed to add PD driver\n", __func__); + + return ret; +} +arch_initcall(samsung_pd_init); -- cgit v1.2.3 From a50eb1c7680973f5441ca20ac4da0af2055d0d87 Mon Sep 17 00:00:00 2001 From: Changhwan Youn Date: Fri, 26 Nov 2010 13:21:53 +0900 Subject: ARM: S5PV310: Set bit 22 in the PL310 (cache controller) AuxCtlr register This patch is applied according to the commit 1a8e41cd672f894bbd74874eac601e6cedf838fb (ARM: 6395/1: VExpress: Set bit 22 in the PL310 (cache controller) AuxCtlr register). Actually, S5PV310 has same cache controller(PL310). Following is from Catalin Marinas' commit. Clearing bit 22 in the PL310 Auxiliary Control register (shared attribute override enable) has the side effect of transforming Normal Shared Non-cacheable reads into Cacheable no-allocate reads. Coherent DMA buffers in Linux always have a Cacheable alias via the kernel linear mapping and the processor can speculatively load cache lines into the PL310 controller. With bit 22 cleared, Non-cacheable reads would unexpectedly hit such cache lines leading to buffer corruption. Signed-off-by: Changhwan Youn Cc: Cc: Catalin Marinas Cc: Russell King Signed-off-by: Kukjin Kim --- arch/arm/mach-s5pv310/cpu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-s5pv310/cpu.c b/arch/arm/mach-s5pv310/cpu.c index 82ce4aa6d61a..b2a37d0f9d7a 100644 --- a/arch/arm/mach-s5pv310/cpu.c +++ b/arch/arm/mach-s5pv310/cpu.c @@ -168,7 +168,7 @@ static int __init s5pv310_l2x0_cache_init(void) __raw_writel(L2X0_DYNAMIC_CLK_GATING_EN | L2X0_STNDBY_MODE_EN, S5P_VA_L2CC + L2X0_POWER_CTRL); - l2x0_init(S5P_VA_L2CC, 0x7C070001, 0xC200ffff); + l2x0_init(S5P_VA_L2CC, 0x7C470001, 0xC200ffff); return 0; } -- cgit v1.2.3 From d6d8b481999507a20012b7ee924bdaf5bfb52a05 Mon Sep 17 00:00:00 2001 From: Changhwan Youn Date: Fri, 3 Dec 2010 17:15:40 +0900 Subject: ARM: S5PV310: Add support Power Domain This patch adds support Power Domain for S5PV310 and S5PC210. Signed-off-by: Changhwan Youn Signed-off-by: Kukjin Kim --- arch/arm/mach-s5pv310/Kconfig | 7 ++ arch/arm/mach-s5pv310/Makefile | 3 + arch/arm/mach-s5pv310/cpu.c | 5 + arch/arm/mach-s5pv310/dev-pd.c | 139 ++++++++++++++++++++++++++ arch/arm/mach-s5pv310/include/mach/map.h | 2 + arch/arm/mach-s5pv310/include/mach/regs-pmu.h | 30 ++++++ arch/arm/mach-s5pv310/mach-smdkc210.c | 8 ++ arch/arm/mach-s5pv310/mach-smdkv310.c | 8 ++ arch/arm/plat-s5p/include/plat/map-s5p.h | 1 + arch/arm/plat-samsung/include/plat/devs.h | 2 + 10 files changed, 205 insertions(+) create mode 100644 arch/arm/mach-s5pv310/dev-pd.c create mode 100644 arch/arm/mach-s5pv310/include/mach/regs-pmu.h diff --git a/arch/arm/mach-s5pv310/Kconfig b/arch/arm/mach-s5pv310/Kconfig index 1150b360f38c..3bf72a60bf53 100644 --- a/arch/arm/mach-s5pv310/Kconfig +++ b/arch/arm/mach-s5pv310/Kconfig @@ -14,6 +14,11 @@ config CPU_S5PV310 help Enable S5PV310 CPU support +config S5PV310_DEV_PD + bool + help + Compile in platform device definitions for Power Domain + config S5PV310_SETUP_I2C1 bool help @@ -73,6 +78,7 @@ config MACH_SMDKC210 select S3C_DEV_HSMMC1 select S3C_DEV_HSMMC2 select S3C_DEV_HSMMC3 + select S5PV310_DEV_PD select S5PV310_SETUP_SDHCI help Machine support for Samsung SMDKC210 @@ -101,6 +107,7 @@ config MACH_SMDKV310 select S3C_DEV_HSMMC1 select S3C_DEV_HSMMC2 select S3C_DEV_HSMMC3 + select S5PV310_DEV_PD select S5PV310_SETUP_SDHCI help Machine support for Samsung SMDKV310 diff --git a/arch/arm/mach-s5pv310/Makefile b/arch/arm/mach-s5pv310/Makefile index 84afc64e7c01..e310609d6268 100644 --- a/arch/arm/mach-s5pv310/Makefile +++ b/arch/arm/mach-s5pv310/Makefile @@ -27,6 +27,9 @@ obj-$(CONFIG_MACH_UNIVERSAL_C210) += mach-universal_c210.o # device support +obj-y += dev-audio.o +obj-$(CONFIG_S5PV310_DEV_PD) += dev-pd.o + obj-$(CONFIG_S5PV310_SETUP_I2C1) += setup-i2c1.o obj-$(CONFIG_S5PV310_SETUP_I2C2) += setup-i2c2.o obj-$(CONFIG_S5PV310_SETUP_I2C3) += setup-i2c3.o diff --git a/arch/arm/mach-s5pv310/cpu.c b/arch/arm/mach-s5pv310/cpu.c index b2a37d0f9d7a..7b6e066e2271 100644 --- a/arch/arm/mach-s5pv310/cpu.c +++ b/arch/arm/mach-s5pv310/cpu.c @@ -42,6 +42,11 @@ static struct map_desc s5pv310_iodesc[] __initdata = { .pfn = __phys_to_pfn(S5PV310_PA_CMU), .length = SZ_128K, .type = MT_DEVICE, + }, { + .virtual = (unsigned long)S5P_VA_PMU, + .pfn = __phys_to_pfn(S5PV310_PA_PMU), + .length = SZ_64K, + .type = MT_DEVICE, }, { .virtual = (unsigned long)S5P_VA_COMBINER_BASE, .pfn = __phys_to_pfn(S5PV310_PA_COMBINER), diff --git a/arch/arm/mach-s5pv310/dev-pd.c b/arch/arm/mach-s5pv310/dev-pd.c new file mode 100644 index 000000000000..58a50c2d0b67 --- /dev/null +++ b/arch/arm/mach-s5pv310/dev-pd.c @@ -0,0 +1,139 @@ +/* linux/arch/arm/mach-s5pv310/dev-pd.c + * + * Copyright (c) 2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * S5PV310 - Power Domain support + * + * 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 + +#include + +#include + +static int s5pv310_pd_enable(struct device *dev) +{ + struct samsung_pd_info *pdata = dev->platform_data; + u32 timeout; + + __raw_writel(S5P_INT_LOCAL_PWR_EN, pdata->base); + + /* Wait max 1ms */ + timeout = 10; + while ((__raw_readl(pdata->base + 0x4) & S5P_INT_LOCAL_PWR_EN) + != S5P_INT_LOCAL_PWR_EN) { + if (timeout == 0) { + printk(KERN_ERR "Power domain %s enable failed.\n", + dev_name(dev)); + return -ETIMEDOUT; + } + timeout--; + udelay(100); + } + + return 0; +} + +static int s5pv310_pd_disable(struct device *dev) +{ + struct samsung_pd_info *pdata = dev->platform_data; + u32 timeout; + + __raw_writel(0, pdata->base); + + /* Wait max 1ms */ + timeout = 10; + while (__raw_readl(pdata->base + 0x4) & S5P_INT_LOCAL_PWR_EN) { + if (timeout == 0) { + printk(KERN_ERR "Power domain %s disable failed.\n", + dev_name(dev)); + return -ETIMEDOUT; + } + timeout--; + udelay(100); + } + + return 0; +} + +struct platform_device s5pv310_device_pd[] = { + { + .name = "samsung-pd", + .id = 0, + .dev = { + .platform_data = &(struct samsung_pd_info) { + .enable = s5pv310_pd_enable, + .disable = s5pv310_pd_disable, + .base = S5P_PMU_MFC_CONF, + }, + }, + }, { + .name = "samsung-pd", + .id = 1, + .dev = { + .platform_data = &(struct samsung_pd_info) { + .enable = s5pv310_pd_enable, + .disable = s5pv310_pd_disable, + .base = S5P_PMU_G3D_CONF, + }, + }, + }, { + .name = "samsung-pd", + .id = 2, + .dev = { + .platform_data = &(struct samsung_pd_info) { + .enable = s5pv310_pd_enable, + .disable = s5pv310_pd_disable, + .base = S5P_PMU_LCD0_CONF, + }, + }, + }, { + .name = "samsung-pd", + .id = 3, + .dev = { + .platform_data = &(struct samsung_pd_info) { + .enable = s5pv310_pd_enable, + .disable = s5pv310_pd_disable, + .base = S5P_PMU_LCD1_CONF, + }, + }, + }, { + .name = "samsung-pd", + .id = 4, + .dev = { + .platform_data = &(struct samsung_pd_info) { + .enable = s5pv310_pd_enable, + .disable = s5pv310_pd_disable, + .base = S5P_PMU_TV_CONF, + }, + }, + }, { + .name = "samsung-pd", + .id = 5, + .dev = { + .platform_data = &(struct samsung_pd_info) { + .enable = s5pv310_pd_enable, + .disable = s5pv310_pd_disable, + .base = S5P_PMU_CAM_CONF, + }, + }, + }, { + .name = "samsung-pd", + .id = 6, + .dev = { + .platform_data = &(struct samsung_pd_info) { + .enable = s5pv310_pd_enable, + .disable = s5pv310_pd_disable, + .base = S5P_PMU_GPS_CONF, + }, + }, + }, +}; diff --git a/arch/arm/mach-s5pv310/include/mach/map.h b/arch/arm/mach-s5pv310/include/mach/map.h index 7acf4e77e92e..a16d0c9c27bc 100644 --- a/arch/arm/mach-s5pv310/include/mach/map.h +++ b/arch/arm/mach-s5pv310/include/mach/map.h @@ -39,6 +39,8 @@ #define S5PV310_PA_SYSCON (0x10010000) #define S5P_PA_SYSCON S5PV310_PA_SYSCON +#define S5PV310_PA_PMU (0x10020000) + #define S5PV310_PA_CMU (0x10030000) #define S5PV310_PA_WATCHDOG (0x10060000) diff --git a/arch/arm/mach-s5pv310/include/mach/regs-pmu.h b/arch/arm/mach-s5pv310/include/mach/regs-pmu.h new file mode 100644 index 000000000000..fb333d0f6073 --- /dev/null +++ b/arch/arm/mach-s5pv310/include/mach/regs-pmu.h @@ -0,0 +1,30 @@ +/* linux/arch/arm/mach-s5pv310/include/mach/regs-pmu.h + * + * Copyright (c) 2010 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * S5PV310 - Power management unit definition + * + * 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. +*/ + +#ifndef __ASM_ARCH_REGS_PMU_H +#define __ASM_ARCH_REGS_PMU_H __FILE__ + +#include + +#define S5P_PMUREG(x) (S5P_VA_PMU + (x)) + +#define S5P_PMU_CAM_CONF S5P_PMUREG(0x3C00) +#define S5P_PMU_TV_CONF S5P_PMUREG(0x3C20) +#define S5P_PMU_MFC_CONF S5P_PMUREG(0x3C40) +#define S5P_PMU_G3D_CONF S5P_PMUREG(0x3C60) +#define S5P_PMU_LCD0_CONF S5P_PMUREG(0x3C80) +#define S5P_PMU_LCD1_CONF S5P_PMUREG(0x3CA0) +#define S5P_PMU_GPS_CONF S5P_PMUREG(0x3CE0) + +#define S5P_INT_LOCAL_PWR_EN 0x7 + +#endif /* __ASM_ARCH_REGS_PMU_H */ diff --git a/arch/arm/mach-s5pv310/mach-smdkc210.c b/arch/arm/mach-s5pv310/mach-smdkc210.c index 2b8d4fc52d7c..f65e668ceae9 100644 --- a/arch/arm/mach-s5pv310/mach-smdkc210.c +++ b/arch/arm/mach-s5pv310/mach-smdkc210.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -147,6 +148,13 @@ static struct platform_device *smdkc210_devices[] __initdata = { &s3c_device_rtc, &s3c_device_wdt, &smdkc210_smsc911x, + &s5pv310_device_pd[PD_MFC], + &s5pv310_device_pd[PD_G3D], + &s5pv310_device_pd[PD_LCD0], + &s5pv310_device_pd[PD_LCD1], + &s5pv310_device_pd[PD_CAM], + &s5pv310_device_pd[PD_TV], + &s5pv310_device_pd[PD_GPS], }; static void __init smdkc210_smsc911x_init(void) diff --git a/arch/arm/mach-s5pv310/mach-smdkv310.c b/arch/arm/mach-s5pv310/mach-smdkv310.c index 35826d66632c..19aa3e3c011d 100644 --- a/arch/arm/mach-s5pv310/mach-smdkv310.c +++ b/arch/arm/mach-s5pv310/mach-smdkv310.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -147,6 +148,13 @@ static struct platform_device *smdkv310_devices[] __initdata = { &s3c_device_rtc, &s3c_device_wdt, &smdkv310_smsc911x, + &s5pv310_device_pd[PD_MFC], + &s5pv310_device_pd[PD_G3D], + &s5pv310_device_pd[PD_LCD0], + &s5pv310_device_pd[PD_LCD1], + &s5pv310_device_pd[PD_CAM], + &s5pv310_device_pd[PD_TV], + &s5pv310_device_pd[PD_GPS], }; static void __init smdkv310_smsc911x_init(void) diff --git a/arch/arm/plat-s5p/include/plat/map-s5p.h b/arch/arm/plat-s5p/include/plat/map-s5p.h index fef353d44513..d973d39666a3 100644 --- a/arch/arm/plat-s5p/include/plat/map-s5p.h +++ b/arch/arm/plat-s5p/include/plat/map-s5p.h @@ -15,6 +15,7 @@ #define S5P_VA_CHIPID S3C_ADDR(0x02000000) #define S5P_VA_CMU S3C_ADDR(0x02100000) +#define S5P_VA_PMU S3C_ADDR(0x02180000) #define S5P_VA_GPIO S3C_ADDR(0x02200000) #define S5P_VA_GPIO1 S5P_VA_GPIO #define S5P_VA_GPIO2 S3C_ADDR(0x02240000) diff --git a/arch/arm/plat-samsung/include/plat/devs.h b/arch/arm/plat-samsung/include/plat/devs.h index 2d82a6cb1444..4dad6e24e970 100644 --- a/arch/arm/plat-samsung/include/plat/devs.h +++ b/arch/arm/plat-samsung/include/plat/devs.h @@ -122,6 +122,8 @@ extern struct platform_device s5p_device_fimc0; extern struct platform_device s5p_device_fimc1; extern struct platform_device s5p_device_fimc2; +extern struct platform_device s5pv310_device_pd[]; + /* s3c2440 specific devices */ #ifdef CONFIG_CPU_S3C2440 -- cgit v1.2.3 From a8928ce7e09eed34b59525779cb833f8438d0733 Mon Sep 17 00:00:00 2001 From: Kyungmin Park Date: Wed, 22 Dec 2010 13:34:23 +0900 Subject: ARM: S5PV310: Universal SDHCI devices support Universal (C210) board has 3 SDHCI devices. Signed-off-by: Kyungmin Park [kgene.kim@samsung.com: minor edit of title] Signed-off-by: Kukjin Kim --- arch/arm/mach-s5pv310/Kconfig | 4 ++ arch/arm/mach-s5pv310/mach-universal_c210.c | 80 +++++++++++++++++++++++++++++ 2 files changed, 84 insertions(+) diff --git a/arch/arm/mach-s5pv310/Kconfig b/arch/arm/mach-s5pv310/Kconfig index 3bf72a60bf53..e0cef3fd165e 100644 --- a/arch/arm/mach-s5pv310/Kconfig +++ b/arch/arm/mach-s5pv310/Kconfig @@ -88,6 +88,10 @@ config MACH_UNIVERSAL_C210 bool "Mobile UNIVERSAL_C210 Board" select CPU_S5PV310 select S5P_DEV_ONENAND + select S3C_DEV_HSMMC + select S3C_DEV_HSMMC2 + select S3C_DEV_HSMMC3 + select S5PV310_SETUP_SDHCI select S3C_DEV_I2C1 select S5PV310_SETUP_I2C1 help diff --git a/arch/arm/mach-s5pv310/mach-universal_c210.c b/arch/arm/mach-s5pv310/mach-universal_c210.c index 16d8fc00cafd..36bc3cf825e3 100644 --- a/arch/arm/mach-s5pv310/mach-universal_c210.c +++ b/arch/arm/mach-s5pv310/mach-universal_c210.c @@ -13,6 +13,9 @@ #include #include #include +#include +#include +#include #include #include @@ -21,6 +24,7 @@ #include #include #include +#include #include @@ -116,6 +120,73 @@ static struct platform_device universal_gpio_keys = { }, }; +/* eMMC */ +static struct s3c_sdhci_platdata universal_hsmmc0_data __initdata = { + .max_width = 8, + .host_caps = (MMC_CAP_8_BIT_DATA | MMC_CAP_4_BIT_DATA | + MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED | + MMC_CAP_DISABLE), + .cd_type = S3C_SDHCI_CD_PERMANENT, + .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL, +}; + +static struct regulator_consumer_supply mmc0_supplies[] = { + REGULATOR_SUPPLY("vmmc", "s3c-sdhci.0"), +}; + +static struct regulator_init_data mmc0_fixed_voltage_init_data = { + .constraints = { + .name = "VMEM_VDD_2.8V", + .valid_ops_mask = REGULATOR_CHANGE_STATUS, + }, + .num_consumer_supplies = ARRAY_SIZE(mmc0_supplies), + .consumer_supplies = mmc0_supplies, +}; + +static struct fixed_voltage_config mmc0_fixed_voltage_config = { + .supply_name = "MASSMEMORY_EN", + .microvolts = 2800000, + .gpio = S5PV310_GPE1(3), + .enable_high = true, + .init_data = &mmc0_fixed_voltage_init_data, +}; + +static struct platform_device mmc0_fixed_voltage = { + .name = "reg-fixed-voltage", + .id = 0, + .dev = { + .platform_data = &mmc0_fixed_voltage_config, + }, +}; + +/* SD */ +static struct s3c_sdhci_platdata universal_hsmmc2_data __initdata = { + .max_width = 4, + .host_caps = MMC_CAP_4_BIT_DATA | + MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED | + MMC_CAP_DISABLE, + .ext_cd_gpio = S5PV310_GPX3(4), /* XEINT_28 */ + .ext_cd_gpio_invert = 1, + .cd_type = S3C_SDHCI_CD_GPIO, + .clk_type = S3C_SDHCI_CLK_DIV_EXTERNAL, +}; + +/* WiFi */ +static struct s3c_sdhci_platdata universal_hsmmc3_data __initdata = { + .max_width = 4, + .host_caps = MMC_CAP_4_BIT_DATA | + MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED | + MMC_CAP_DISABLE, + .cd_type = S3C_SDHCI_CD_EXTERNAL, +}; + +static void __init universal_sdhci_init(void) +{ + s3c_sdhci0_set_platdata(&universal_hsmmc0_data); + s3c_sdhci2_set_platdata(&universal_hsmmc2_data); + s3c_sdhci3_set_platdata(&universal_hsmmc3_data); +} + /* I2C0 */ static struct i2c_board_info i2c0_devs[] __initdata = { /* Camera, To be updated */ @@ -127,6 +198,13 @@ static struct i2c_board_info i2c1_devs[] __initdata = { }; static struct platform_device *universal_devices[] __initdata = { + /* Samsung Platform Devices */ + &mmc0_fixed_voltage, + &s3c_device_hsmmc0, + &s3c_device_hsmmc2, + &s3c_device_hsmmc3, + + /* Universal Devices */ &universal_gpio_keys, &s5p_device_onenand, }; @@ -140,6 +218,8 @@ static void __init universal_map_io(void) static void __init universal_machine_init(void) { + universal_sdhci_init(); + i2c_register_board_info(0, i2c0_devs, ARRAY_SIZE(i2c0_devs)); i2c_register_board_info(1, i2c1_devs, ARRAY_SIZE(i2c1_devs)); -- cgit v1.2.3 From 8f49720d5afb42dc7c0ced2cd94d561fbe9560d9 Mon Sep 17 00:00:00 2001 From: Thomas Abraham Date: Fri, 26 Nov 2010 13:19:49 +0900 Subject: ARM: S5PV210: Add frame buffer display support for SMDKV210 Enable frame buffer display support for SMDKV210 board. Signed-off-by: Thomas Abraham Reviewed-by: Jonghun Han Signed-off-by: Kukjin Kim --- arch/arm/mach-s5pv210/Kconfig | 2 + arch/arm/mach-s5pv210/mach-smdkv210.c | 74 +++++++++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+) diff --git a/arch/arm/mach-s5pv210/Kconfig b/arch/arm/mach-s5pv210/Kconfig index 862f239a0fdb..53aabef1e9ce 100644 --- a/arch/arm/mach-s5pv210/Kconfig +++ b/arch/arm/mach-s5pv210/Kconfig @@ -118,6 +118,7 @@ menu "S5PV210 Machines" config MACH_SMDKV210 bool "SMDKV210" select CPU_S5PV210 + select S3C_DEV_FB select S3C_DEV_HSMMC select S3C_DEV_HSMMC1 select S3C_DEV_HSMMC2 @@ -130,6 +131,7 @@ config MACH_SMDKV210 select SAMSUNG_DEV_IDE select SAMSUNG_DEV_KEYPAD select SAMSUNG_DEV_TS + select S5PV210_SETUP_FB_24BPP select S5PV210_SETUP_I2C1 select S5PV210_SETUP_I2C2 select S5PV210_SETUP_IDE diff --git a/arch/arm/mach-s5pv210/mach-smdkv210.c b/arch/arm/mach-s5pv210/mach-smdkv210.c index 1fbc45b2a432..2196c231cfd2 100644 --- a/arch/arm/mach-s5pv210/mach-smdkv210.c +++ b/arch/arm/mach-s5pv210/mach-smdkv210.c @@ -14,14 +14,20 @@ #include #include #include +#include +#include +#include #include #include #include #include +#include
+ RDS datastructures struct <structname>v4l2_rds_data</structname> @@ -129,10 +130,11 @@ as follows:
Block defines - + - + + V4L2_RDS_BLOCK_MSK -- cgit v1.2.3 From bda50bcd0cc21d9d6dd8c82628f763ab108260a6 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Sun, 16 Jan 2011 17:44:17 -0300 Subject: [media] DocBook/v4l: update V4L2 revision and update copyright years Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- Documentation/DocBook/dvb/dvbapi.xml | 2 +- Documentation/DocBook/media.tmpl | 4 ++-- Documentation/DocBook/v4l/v4l2.xml | 3 ++- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/Documentation/DocBook/dvb/dvbapi.xml b/Documentation/DocBook/dvb/dvbapi.xml index e3a97fdd62a6..ad8678d48916 100644 --- a/Documentation/DocBook/dvb/dvbapi.xml +++ b/Documentation/DocBook/dvb/dvbapi.xml @@ -28,7 +28,7 @@ Convergence GmbH - 2009-2010 + 2009-2011 Mauro Carvalho Chehab diff --git a/Documentation/DocBook/media.tmpl b/Documentation/DocBook/media.tmpl index f11048d4053f..a99088aae1aa 100644 --- a/Documentation/DocBook/media.tmpl +++ b/Documentation/DocBook/media.tmpl @@ -28,7 +28,7 @@ LINUX MEDIA INFRASTRUCTURE API - 2009-2010 + 2009-2011 LinuxTV Developers @@ -86,7 +86,7 @@ Foundation. A copy of the license is included in the chapter entitled - 2009-2010 + 2009-2011 Mauro Carvalho Chehab diff --git a/Documentation/DocBook/v4l/v4l2.xml b/Documentation/DocBook/v4l/v4l2.xml index 839e93e875ae..9288af96de34 100644 --- a/Documentation/DocBook/v4l/v4l2.xml +++ b/Documentation/DocBook/v4l/v4l2.xml @@ -100,6 +100,7 @@ Remote Controller chapter. 2008 2009 2010 + 2011 Bill Dirks, Michael H. Schimek, Hans Verkuil, Martin Rubli, Andy Walls, Muralidharan Karicheri, Mauro Carvalho Chehab @@ -381,7 +382,7 @@ and discussions on the V4L mailing list. Video for Linux Two API Specification - Revision 2.6.33 + Revision 2.6.38 &sub-common; -- cgit v1.2.3 From 01c40c048b0f3f377e6d27b35fd99f04efcc21dd Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Fri, 19 Nov 2010 11:20:06 -0300 Subject: [media] v4l: Include linux/videodev2.h in media/v4l2-ctrls.h The later makes extensive use of structures defined in the former. Signed-off-by: Laurent Pinchart Signed-off-by: Mauro Carvalho Chehab --- include/media/v4l2-ctrls.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/media/v4l2-ctrls.h b/include/media/v4l2-ctrls.h index fcc9a0cf8ff1..97d063837b61 100644 --- a/include/media/v4l2-ctrls.h +++ b/include/media/v4l2-ctrls.h @@ -23,6 +23,7 @@ #include #include +#include /* forward references */ struct v4l2_ctrl_handler; -- cgit v1.2.3 From eac9aa005a2e0676d07f1906f9933fd055eb1f0b Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Tue, 7 Dec 2010 08:57:25 -0300 Subject: [media] v4l: Fix a use-before-set in the control framework v4l2_queryctrl sets the step value based on the control type. That would be fine if it used the control type stored in the V4L2 kernel control object, not the one stored in the userspace ioctl structure that has just been memset to 0. Fix this. Signed-off-by: Laurent Pinchart Acked-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/v4l2-ctrls.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/video/v4l2-ctrls.c b/drivers/media/video/v4l2-ctrls.c index 01251431fd2a..ef66d2af0c57 100644 --- a/drivers/media/video/v4l2-ctrls.c +++ b/drivers/media/video/v4l2-ctrls.c @@ -1352,7 +1352,7 @@ int v4l2_queryctrl(struct v4l2_ctrl_handler *hdl, struct v4l2_queryctrl *qc) qc->minimum = ctrl->minimum; qc->maximum = ctrl->maximum; qc->default_value = ctrl->default_value; - if (qc->type == V4L2_CTRL_TYPE_MENU) + if (ctrl->type == V4L2_CTRL_TYPE_MENU) qc->step = 1; else qc->step = ctrl->step; -- cgit v1.2.3 From bd5ba3ba2ead7248124723dac2481d0992e75e91 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 31 Dec 2010 11:27:38 -0300 Subject: [media] w9966: zero device state after a detach After a detach zero the whole device state to ensure a clean slate on the next attach. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/w9966.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/media/video/w9966.c b/drivers/media/video/w9966.c index 019ee206cbee..fa35639d0c15 100644 --- a/drivers/media/video/w9966.c +++ b/drivers/media/video/w9966.c @@ -937,6 +937,7 @@ static void w9966_term(struct w9966 *cam) parport_unregister_device(cam->pdev); w9966_set_state(cam, W9966_STATE_PDEV, 0); } + memset(cam, 0, sizeof(*cam)); } -- cgit v1.2.3 From 6ce3ced4f73e3f0c345f47dc99fd21f2248724a8 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 31 Dec 2010 11:28:51 -0300 Subject: [media] zoran: use video_device_alloc instead of kmalloc Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/zoran/zoran_card.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/media/video/zoran/zoran_card.c b/drivers/media/video/zoran/zoran_card.c index 9cdc3bb15b15..9f2bac519647 100644 --- a/drivers/media/video/zoran/zoran_card.c +++ b/drivers/media/video/zoran/zoran_card.c @@ -1041,7 +1041,7 @@ zr36057_init (struct zoran *zr) /* allocate memory *before* doing anything to the hardware * in case allocation fails */ zr->stat_com = kzalloc(BUZ_NUM_STAT_COM * 4, GFP_KERNEL); - zr->video_dev = kmalloc(sizeof(struct video_device), GFP_KERNEL); + zr->video_dev = video_device_alloc(); if (!zr->stat_com || !zr->video_dev) { dprintk(1, KERN_ERR -- cgit v1.2.3 From 46b633779b299c7fb3d78f153a5034055f99cd45 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Fri, 31 Dec 2010 11:47:23 -0300 Subject: [media] v4l2-dev: don't memset video_device.dev Zeroing video_device.dev causes a memory leak if video_set_drvdata was called before video_register_device was called. video_set_drvdata calls dev_set_drvdata which allocates video_device.dev.p. memsetting this will prevent freeing of that memory. Signed-off-by: Hans Verkuil Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/v4l2-dev.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/media/video/v4l2-dev.c b/drivers/media/video/v4l2-dev.c index 359e23290a7e..341764a3a990 100644 --- a/drivers/media/video/v4l2-dev.c +++ b/drivers/media/video/v4l2-dev.c @@ -419,6 +419,10 @@ static int get_index(struct video_device *vdev) * The registration code assigns minor numbers and device node numbers * based on the requested type and registers the new device node with * the kernel. + * + * This function assumes that struct video_device was zeroed when it + * was allocated and does not contain any stale date. + * * An error is returned if no free minor or device node number could be * found, or if the registration of the device node failed. * @@ -440,7 +444,6 @@ static int __video_register_device(struct video_device *vdev, int type, int nr, int minor_offset = 0; int minor_cnt = VIDEO_NUM_DEVICES; const char *name_base; - void *priv = vdev->dev.p; /* A minor value of -1 marks this video device as never having been registered */ @@ -559,10 +562,6 @@ static int __video_register_device(struct video_device *vdev, int type, int nr, } /* Part 4: register the device with sysfs */ - memset(&vdev->dev, 0, sizeof(vdev->dev)); - /* The memset above cleared the device's device_private, so - put back the copy we made earlier. */ - vdev->dev.p = priv; vdev->dev.class = &video_class; vdev->dev.devt = MKDEV(VIDEO_MAJOR, vdev->minor); if (vdev->parent) -- cgit v1.2.3 From 672dcd54774ea1b03da8f2baa1cdbf827927fc85 Mon Sep 17 00:00:00 2001 From: Hans Verkuil Date: Tue, 11 Jan 2011 17:48:21 -0300 Subject: [media] v4l2-device: fix 'use-after-freed' oops Fix a bug in v4l2_device_unregister where the sd pointer can be dereferenced after it was freed. Normally the i2c adapter is removed before this function is called. Removing the adapter will also unregister all subdevs on that adapter, so generally v4l2_device_unregister has nothing to do. However, in the case of a platform i2c bus that bus is generally not freed. In that case, after freeing the i2c subdevice the code will fall into the second block when it tests if the subdev is a SPI device. But by that time the subdev is already freed and the kernel oopses. The fix is trivial: continue with the loop after freeing the i2c or spi subdevice. Signed-off-by: Hans Verkuil Reported-by: Daniel Drake Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/v4l2-device.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/media/video/v4l2-device.c b/drivers/media/video/v4l2-device.c index b24f002ffa67..ce64fe16bc60 100644 --- a/drivers/media/video/v4l2-device.c +++ b/drivers/media/video/v4l2-device.c @@ -100,6 +100,7 @@ void v4l2_device_unregister(struct v4l2_device *v4l2_dev) is a platform bus, then it is never deleted. */ if (client) i2c_unregister_device(client); + continue; } #endif #if defined(CONFIG_SPI) @@ -108,6 +109,7 @@ void v4l2_device_unregister(struct v4l2_device *v4l2_dev) if (spi) spi_unregister_device(spi); + continue; } #endif } -- cgit v1.2.3 From a28287925555c93984115d37a1a25315ea369764 Mon Sep 17 00:00:00 2001 From: Dimitris Papastamos Date: Wed, 19 Jan 2011 12:55:28 +0000 Subject: ASoC: WM8995: Fix incorrect use of snd_soc_update_bits() In the wm8995_set_tristate() function when updating the register bits use the value and not the register index as the value argument. Signed-off-by: Dimitris Papastamos Acked-by: Liam Girdwood Signed-off-by: Mark Brown Cc: stable@kernel.org --- sound/soc/codecs/wm8995.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/codecs/wm8995.c b/sound/soc/codecs/wm8995.c index 6045cbde492b..608c84c5aa8e 100644 --- a/sound/soc/codecs/wm8995.c +++ b/sound/soc/codecs/wm8995.c @@ -1223,7 +1223,7 @@ static int wm8995_set_tristate(struct snd_soc_dai *codec_dai, int tristate) else val = 0; - return snd_soc_update_bits(codec, reg, mask, reg); + return snd_soc_update_bits(codec, reg, mask, val); } /* The size in bits of the FLL divide multiplied by 10 -- cgit v1.2.3 From 78b3fb46753872fc79bffecc8d50355a8622b39b Mon Sep 17 00:00:00 2001 From: Qiao Zhou Date: Wed, 19 Jan 2011 19:10:47 +0800 Subject: ASoC: WM8994: fix wrong value in tristate function fix wrong value in wm8994_set_tristate func. when updating reg bits, it should use "value", not "reg". Signed-off-by: Qiao Zhou Acked-by: Liam Girdwood Signed-off-by: Mark Brown Cc: stable@kernel.org --- sound/soc/codecs/wm8994.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index 247a6a99feb8..3351f77607b3 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c @@ -2386,7 +2386,7 @@ static int wm8994_set_tristate(struct snd_soc_dai *codec_dai, int tristate) else val = 0; - return snd_soc_update_bits(codec, reg, mask, reg); + return snd_soc_update_bits(codec, reg, mask, val); } #define WM8994_RATES SNDRV_PCM_RATE_8000_96000 -- cgit v1.2.3 From 706c57d802394e2fe720ebc929234a678f94e716 Mon Sep 17 00:00:00 2001 From: Jarod Wilson Date: Thu, 6 Jan 2011 13:23:13 -0300 Subject: [media] rc/mceusb: timeout should be in ns, not us Fixes an egregious bug in mceusb driver, where the receiver was being put into idle mode far sooner than it should have, thanks to storing a timeout value that in us where it should be ns. Basically, the receiver kept going into idle mode before a trailing space had been fully received, which was causing problems for some protocols, most notably manifesting as lirc userspace never receiving a trailing space for any rc5 signals. Signed-off-by: Jarod Wilson Signed-off-by: Mauro Carvalho Chehab --- drivers/media/rc/mceusb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/media/rc/mceusb.c b/drivers/media/rc/mceusb.c index 2d9113493cf0..079353e5d558 100644 --- a/drivers/media/rc/mceusb.c +++ b/drivers/media/rc/mceusb.c @@ -816,7 +816,7 @@ static void mceusb_handle_command(struct mceusb_dev *ir, int index) switch (ir->buf_in[index]) { /* 2-byte return value commands */ case MCE_CMD_S_TIMEOUT: - ir->rc->timeout = MS_TO_US((hi << 8 | lo) / 2); + ir->rc->timeout = MS_TO_NS((hi << 8 | lo) / 2); break; /* 1-byte return value commands */ @@ -1060,7 +1060,7 @@ static struct rc_dev *mceusb_init_rc_dev(struct mceusb_dev *ir) rc->priv = ir; rc->driver_type = RC_DRIVER_IR_RAW; rc->allowed_protos = RC_TYPE_ALL; - rc->timeout = MS_TO_US(1000); + rc->timeout = MS_TO_NS(1000); if (!ir->flags.no_tx) { rc->s_tx_mask = mceusb_set_tx_mask; rc->s_tx_carrier = mceusb_set_tx_carrier; -- cgit v1.2.3 From 324b04ba5da7918a2409f8113e46843bfbd89e67 Mon Sep 17 00:00:00 2001 From: Jarod Wilson Date: Fri, 14 Jan 2011 16:25:21 -0300 Subject: [media] hdpvr: enable IR part A number of things going on here, but the end result is that the IR part on the hdpvr gets enabled, and can be used with ir-kbd-i2c and/or lirc_zilog. First up, there are some conditional build fixes that come into play whether i2c is built-in or modular. Second, we're swapping out i2c_new_probed_device() for i2c_new_device(), as in my testing, probing always fails, but we *know* that all hdpvr devices have a z8 chip at 0x70 and 0x71. Third, we're poking at an i2c address directly without a client, and writing some magic bits to actually turn on this IR part (this could use some improvement in the future). Fourth, some of the i2c_adapter storage has been reworked, as the existing implementation used to lead to an oops following i2c changes c. 2.6.31. Earlier editions of this patch have been floating around the 'net for a while, including being patched into Fedora kernels, and they *do* work. This specific version isn't yet tested, beyond loading ir-kbd-i2c and confirming that it does bind to the RX address of the hdpvr. [mchehab@redhat.com: I2C_CLASS_TV_ANALOG is not defined. Fix compilation bug] Signed-off-by: Jarod Wilson Acked-by: Andy Walls Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/hdpvr/Makefile | 4 +- drivers/media/video/hdpvr/hdpvr-core.c | 10 ++- drivers/media/video/hdpvr/hdpvr-i2c.c | 119 +++++++++++++++----------------- drivers/media/video/hdpvr/hdpvr-video.c | 7 +- drivers/media/video/hdpvr/hdpvr.h | 2 +- 5 files changed, 65 insertions(+), 77 deletions(-) diff --git a/drivers/media/video/hdpvr/Makefile b/drivers/media/video/hdpvr/Makefile index e0230fcb2e36..3baa9f613ca3 100644 --- a/drivers/media/video/hdpvr/Makefile +++ b/drivers/media/video/hdpvr/Makefile @@ -1,6 +1,4 @@ -hdpvr-objs := hdpvr-control.o hdpvr-core.o hdpvr-video.o - -hdpvr-$(CONFIG_I2C) += hdpvr-i2c.o +hdpvr-objs := hdpvr-control.o hdpvr-core.o hdpvr-video.o hdpvr-i2c.o obj-$(CONFIG_VIDEO_HDPVR) += hdpvr.o diff --git a/drivers/media/video/hdpvr/hdpvr-core.c b/drivers/media/video/hdpvr/hdpvr-core.c index f7d1ee55185a..a6572e5ae369 100644 --- a/drivers/media/video/hdpvr/hdpvr-core.c +++ b/drivers/media/video/hdpvr/hdpvr-core.c @@ -378,19 +378,17 @@ static int hdpvr_probe(struct usb_interface *interface, goto error; } -#ifdef CONFIG_I2C - /* until i2c is working properly */ - retval = 0; /* hdpvr_register_i2c_adapter(dev); */ +#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) + retval = hdpvr_register_i2c_adapter(dev); if (retval < 0) { v4l2_err(&dev->v4l2_dev, "registering i2c adapter failed\n"); goto error; } - /* until i2c is working properly */ - retval = 0; /* hdpvr_register_i2c_ir(dev); */ + retval = hdpvr_register_i2c_ir(dev); if (retval < 0) v4l2_err(&dev->v4l2_dev, "registering i2c IR devices failed\n"); -#endif /* CONFIG_I2C */ +#endif /* let the user know what node this device is now attached to */ v4l2_info(&dev->v4l2_dev, "device now attached to %s\n", diff --git a/drivers/media/video/hdpvr/hdpvr-i2c.c b/drivers/media/video/hdpvr/hdpvr-i2c.c index 24966aa02a70..45b88cf60d68 100644 --- a/drivers/media/video/hdpvr/hdpvr-i2c.c +++ b/drivers/media/video/hdpvr/hdpvr-i2c.c @@ -13,6 +13,8 @@ * */ +#if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) + #include #include @@ -28,55 +30,31 @@ #define Z8F0811_IR_TX_I2C_ADDR 0x70 #define Z8F0811_IR_RX_I2C_ADDR 0x71 -static const u8 ir_i2c_addrs[] = { - Z8F0811_IR_TX_I2C_ADDR, - Z8F0811_IR_RX_I2C_ADDR, -}; -static const char * const ir_devicenames[] = { - "ir_tx_z8f0811_hdpvr", - "ir_rx_z8f0811_hdpvr", +static struct i2c_board_info hdpvr_i2c_board_info = { + I2C_BOARD_INFO("ir_tx_z8f0811_hdpvr", Z8F0811_IR_TX_I2C_ADDR), + I2C_BOARD_INFO("ir_rx_z8f0811_hdpvr", Z8F0811_IR_RX_I2C_ADDR), }; -static int hdpvr_new_i2c_ir(struct hdpvr_device *dev, struct i2c_adapter *adap, - const char *type, u8 addr) +int hdpvr_register_i2c_ir(struct hdpvr_device *dev) { - struct i2c_board_info info; + struct i2c_client *c; struct IR_i2c_init_data *init_data = &dev->ir_i2c_init_data; - unsigned short addr_list[2] = { addr, I2C_CLIENT_END }; - - memset(&info, 0, sizeof(struct i2c_board_info)); - strlcpy(info.type, type, I2C_NAME_SIZE); /* Our default information for ir-kbd-i2c.c to use */ - switch (addr) { - case Z8F0811_IR_RX_I2C_ADDR: - init_data->ir_codes = RC_MAP_HAUPPAUGE_NEW; - init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR; - init_data->type = RC_TYPE_RC5; - init_data->name = "HD PVR"; - info.platform_data = init_data; - break; - } - - return i2c_new_probed_device(adap, &info, addr_list, NULL) == NULL ? - -1 : 0; -} + init_data->ir_codes = RC_MAP_HAUPPAUGE_NEW; + init_data->internal_get_key_func = IR_KBD_GET_KEY_HAUP_XVR; + init_data->type = RC_TYPE_RC5; + init_data->name = "HD PVR"; + hdpvr_i2c_board_info.platform_data = init_data; -int hdpvr_register_i2c_ir(struct hdpvr_device *dev) -{ - int i; - int ret = 0; + c = i2c_new_device(&dev->i2c_adapter, &hdpvr_i2c_board_info); - for (i = 0; i < ARRAY_SIZE(ir_i2c_addrs); i++) - ret += hdpvr_new_i2c_ir(dev, dev->i2c_adapter, - ir_devicenames[i], ir_i2c_addrs[i]); - - return ret; + return (c == NULL) ? -ENODEV : 0; } -static int hdpvr_i2c_read(struct hdpvr_device *dev, unsigned char addr, - char *data, int len) +static int hdpvr_i2c_read(struct hdpvr_device *dev, int bus, + unsigned char addr, char *data, int len) { int ret; char *buf = kmalloc(len, GFP_KERNEL); @@ -86,7 +64,7 @@ static int hdpvr_i2c_read(struct hdpvr_device *dev, unsigned char addr, ret = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0), REQTYPE_I2C_READ, CTRL_READ_REQUEST, - 0x100|addr, 0, buf, len, 1000); + (bus << 8) | addr, 0, buf, len, 1000); if (ret == len) { memcpy(data, buf, len); @@ -99,8 +77,8 @@ static int hdpvr_i2c_read(struct hdpvr_device *dev, unsigned char addr, return ret; } -static int hdpvr_i2c_write(struct hdpvr_device *dev, unsigned char addr, - char *data, int len) +static int hdpvr_i2c_write(struct hdpvr_device *dev, int bus, + unsigned char addr, char *data, int len) { int ret; char *buf = kmalloc(len, GFP_KERNEL); @@ -111,7 +89,7 @@ static int hdpvr_i2c_write(struct hdpvr_device *dev, unsigned char addr, ret = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0), REQTYPE_I2C_WRITE, CTRL_WRITE_REQUEST, - 0x100|addr, 0, buf, len, 1000); + (bus << 8) | addr, 0, buf, len, 1000); if (ret < 0) goto error; @@ -121,7 +99,7 @@ static int hdpvr_i2c_write(struct hdpvr_device *dev, unsigned char addr, REQTYPE_I2C_WRITE_STATT, CTRL_READ_REQUEST, 0, 0, buf, 2, 1000); - if (ret == 2) + if ((ret == 2) && (buf[1] == (len - 1))) ret = 0; else if (ret >= 0) ret = -EIO; @@ -146,10 +124,10 @@ static int hdpvr_transfer(struct i2c_adapter *i2c_adapter, struct i2c_msg *msgs, addr = msgs[i].addr << 1; if (msgs[i].flags & I2C_M_RD) - retval = hdpvr_i2c_read(dev, addr, msgs[i].buf, + retval = hdpvr_i2c_read(dev, 1, addr, msgs[i].buf, msgs[i].len); else - retval = hdpvr_i2c_write(dev, addr, msgs[i].buf, + retval = hdpvr_i2c_write(dev, 1, addr, msgs[i].buf, msgs[i].len); } @@ -168,30 +146,47 @@ static struct i2c_algorithm hdpvr_algo = { .functionality = hdpvr_functionality, }; +static struct i2c_adapter hdpvr_i2c_adapter_template = { + .name = "Hauppage HD PVR I2C", + .owner = THIS_MODULE, + .algo = &hdpvr_algo, +}; + +static int hdpvr_activate_ir(struct hdpvr_device *dev) +{ + char buffer[8]; + + mutex_lock(&dev->i2c_mutex); + + hdpvr_i2c_read(dev, 0, 0x54, buffer, 1); + + buffer[0] = 0; + buffer[1] = 0x8; + hdpvr_i2c_write(dev, 1, 0x54, buffer, 2); + + buffer[1] = 0x18; + hdpvr_i2c_write(dev, 1, 0x54, buffer, 2); + + mutex_unlock(&dev->i2c_mutex); + + return 0; +} + int hdpvr_register_i2c_adapter(struct hdpvr_device *dev) { - struct i2c_adapter *i2c_adap; int retval = -ENOMEM; - i2c_adap = kzalloc(sizeof(struct i2c_adapter), GFP_KERNEL); - if (i2c_adap == NULL) - goto error; + hdpvr_activate_ir(dev); - strlcpy(i2c_adap->name, "Hauppauge HD PVR I2C", - sizeof(i2c_adap->name)); - i2c_adap->algo = &hdpvr_algo; - i2c_adap->owner = THIS_MODULE; - i2c_adap->dev.parent = &dev->udev->dev; + memcpy(&dev->i2c_adapter, &hdpvr_i2c_adapter_template, + sizeof(struct i2c_adapter)); + dev->i2c_adapter.dev.parent = &dev->udev->dev; - i2c_set_adapdata(i2c_adap, dev); + i2c_set_adapdata(&dev->i2c_adapter, dev); - retval = i2c_add_adapter(i2c_adap); + retval = i2c_add_adapter(&dev->i2c_adapter); - if (!retval) - dev->i2c_adapter = i2c_adap; - else - kfree(i2c_adap); - -error: return retval; } + +#endif diff --git a/drivers/media/video/hdpvr/hdpvr-video.c b/drivers/media/video/hdpvr/hdpvr-video.c index d38fe1043e47..514aea76eaa5 100644 --- a/drivers/media/video/hdpvr/hdpvr-video.c +++ b/drivers/media/video/hdpvr/hdpvr-video.c @@ -1220,12 +1220,9 @@ static void hdpvr_device_release(struct video_device *vdev) v4l2_device_unregister(&dev->v4l2_dev); /* deregister I2C adapter */ -#ifdef CONFIG_I2C +#if defined(CONFIG_I2C) || (CONFIG_I2C_MODULE) mutex_lock(&dev->i2c_mutex); - if (dev->i2c_adapter) - i2c_del_adapter(dev->i2c_adapter); - kfree(dev->i2c_adapter); - dev->i2c_adapter = NULL; + i2c_del_adapter(&dev->i2c_adapter); mutex_unlock(&dev->i2c_mutex); #endif /* CONFIG_I2C */ diff --git a/drivers/media/video/hdpvr/hdpvr.h b/drivers/media/video/hdpvr/hdpvr.h index 37f1e4c7675d..29f74269400c 100644 --- a/drivers/media/video/hdpvr/hdpvr.h +++ b/drivers/media/video/hdpvr/hdpvr.h @@ -106,7 +106,7 @@ struct hdpvr_device { struct work_struct worker; /* I2C adapter */ - struct i2c_adapter *i2c_adapter; + struct i2c_adapter i2c_adapter; /* I2C lock */ struct mutex i2c_mutex; -- cgit v1.2.3 From 559d162e1ebcdb61e89f154f2c2db376af072b0e Mon Sep 17 00:00:00 2001 From: Jarod Wilson Date: Fri, 14 Jan 2011 16:40:32 -0300 Subject: [media] hdpvr: reduce latency of i2c read/write w/recycled buffer The current hdpvr code kmalloc's a new buffer for every i2c read and write. Rather than do that, lets allocate a buffer in the driver's device struct and just use that every time. The size I've chosen for the buffer is the maximum size I could ascertain might be used by either ir-kbd-i2c or lirc_zilog, plus a bit of padding (lirc_zilog may use up to 100 bytes on tx, rounded that up to 128). Note that this might also remedy user reports of very sluggish behavior of IR receive with hdpvr hardware. v2: make sure (len <= (dev->i2c_buf)) [Jean Delvare] Reported-by: Jean Delvare Acked-by: Jean Delvare Signed-off-by: Jarod Wilson Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/hdpvr/hdpvr-i2c.c | 30 +++++++++++++----------------- drivers/media/video/hdpvr/hdpvr.h | 3 +++ 2 files changed, 16 insertions(+), 17 deletions(-) diff --git a/drivers/media/video/hdpvr/hdpvr-i2c.c b/drivers/media/video/hdpvr/hdpvr-i2c.c index 45b88cf60d68..89b71faeaac2 100644 --- a/drivers/media/video/hdpvr/hdpvr-i2c.c +++ b/drivers/media/video/hdpvr/hdpvr-i2c.c @@ -57,23 +57,21 @@ static int hdpvr_i2c_read(struct hdpvr_device *dev, int bus, unsigned char addr, char *data, int len) { int ret; - char *buf = kmalloc(len, GFP_KERNEL); - if (!buf) - return -ENOMEM; + + if (len > sizeof(dev->i2c_buf)) + return -EINVAL; ret = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0), REQTYPE_I2C_READ, CTRL_READ_REQUEST, - (bus << 8) | addr, 0, buf, len, 1000); + (bus << 8) | addr, 0, &dev->i2c_buf, len, 1000); if (ret == len) { - memcpy(data, buf, len); + memcpy(data, &dev->i2c_buf, len); ret = 0; } else if (ret >= 0) ret = -EIO; - kfree(buf); - return ret; } @@ -81,31 +79,29 @@ static int hdpvr_i2c_write(struct hdpvr_device *dev, int bus, unsigned char addr, char *data, int len) { int ret; - char *buf = kmalloc(len, GFP_KERNEL); - if (!buf) - return -ENOMEM; - memcpy(buf, data, len); + if (len > sizeof(dev->i2c_buf)) + return -EINVAL; + + memcpy(&dev->i2c_buf, data, len); ret = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0), REQTYPE_I2C_WRITE, CTRL_WRITE_REQUEST, - (bus << 8) | addr, 0, buf, len, 1000); + (bus << 8) | addr, 0, &dev->i2c_buf, len, 1000); if (ret < 0) - goto error; + return ret; ret = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, 0), REQTYPE_I2C_WRITE_STATT, CTRL_READ_REQUEST, - 0, 0, buf, 2, 1000); + 0, 0, &dev->i2c_buf, 2, 1000); - if ((ret == 2) && (buf[1] == (len - 1))) + if ((ret == 2) && (dev->i2c_buf[1] == (len - 1))) ret = 0; else if (ret >= 0) ret = -EIO; -error: - kfree(buf); return ret; } diff --git a/drivers/media/video/hdpvr/hdpvr.h b/drivers/media/video/hdpvr/hdpvr.h index 29f74269400c..ee74e3be9a6a 100644 --- a/drivers/media/video/hdpvr/hdpvr.h +++ b/drivers/media/video/hdpvr/hdpvr.h @@ -25,6 +25,7 @@ KERNEL_VERSION(HDPVR_MAJOR_VERSION, HDPVR_MINOR_VERSION, HDPVR_RELEASE) #define HDPVR_MAX 8 +#define HDPVR_I2C_MAX_SIZE 128 /* Define these values to match your devices */ #define HD_PVR_VENDOR_ID 0x2040 @@ -109,6 +110,8 @@ struct hdpvr_device { struct i2c_adapter i2c_adapter; /* I2C lock */ struct mutex i2c_mutex; + /* I2C message buffer space */ + char i2c_buf[HDPVR_I2C_MAX_SIZE]; /* For passing data to ir-kbd-i2c */ struct IR_i2c_init_data ir_i2c_init_data; -- cgit v1.2.3 From 88914bdf8c677ebd7e797adac05e47303fd6ac77 Mon Sep 17 00:00:00 2001 From: Jarod Wilson Date: Mon, 17 Jan 2011 16:02:00 -0300 Subject: [media] staging/lirc: fix mem leaks and ptr err usage When the lirc drivers were converted over to using memdup_user, I mistakenly also removed corresponding calls to kfree. Add those back. I also screwed up on the allocation error check in lirc_serial, using if (PTR_ERR()) instead of if (IS_ERR()), which broke transmit. Reported-by: Jiri Fojtasek Signed-off-by: Jarod Wilson Signed-off-by: Mauro Carvalho Chehab --- drivers/staging/lirc/lirc_imon.c | 1 + drivers/staging/lirc/lirc_it87.c | 1 + drivers/staging/lirc/lirc_parallel.c | 19 ++++++++++++++----- drivers/staging/lirc/lirc_sasem.c | 1 + drivers/staging/lirc/lirc_serial.c | 3 ++- drivers/staging/lirc/lirc_sir.c | 1 + 6 files changed, 20 insertions(+), 6 deletions(-) diff --git a/drivers/staging/lirc/lirc_imon.c b/drivers/staging/lirc/lirc_imon.c index 0da6b9518af9..235cab0eb087 100644 --- a/drivers/staging/lirc/lirc_imon.c +++ b/drivers/staging/lirc/lirc_imon.c @@ -447,6 +447,7 @@ static ssize_t vfd_write(struct file *file, const char *buf, exit: mutex_unlock(&context->ctx_lock); + kfree(data_buf); return (!retval) ? n_bytes : retval; } diff --git a/drivers/staging/lirc/lirc_it87.c b/drivers/staging/lirc/lirc_it87.c index 929ae5795467..5938616f3e8f 100644 --- a/drivers/staging/lirc/lirc_it87.c +++ b/drivers/staging/lirc/lirc_it87.c @@ -232,6 +232,7 @@ static ssize_t lirc_write(struct file *file, const char *buf, i++; } terminate_send(tx_buf[i - 1]); + kfree(tx_buf); return n; } diff --git a/drivers/staging/lirc/lirc_parallel.c b/drivers/staging/lirc/lirc_parallel.c index dfd2c447e67d..3a9c09881b2b 100644 --- a/drivers/staging/lirc/lirc_parallel.c +++ b/drivers/staging/lirc/lirc_parallel.c @@ -376,6 +376,7 @@ static ssize_t lirc_write(struct file *filep, const char *buf, size_t n, unsigned long flags; int counttimer; int *wbuf; + ssize_t ret; if (!is_claimed) return -EBUSY; @@ -393,8 +394,10 @@ static ssize_t lirc_write(struct file *filep, const char *buf, size_t n, if (timer == 0) { /* try again if device is ready */ timer = init_lirc_timer(); - if (timer == 0) - return -EIO; + if (timer == 0) { + ret = -EIO; + goto out; + } } /* adjust values from usecs */ @@ -420,7 +423,8 @@ static ssize_t lirc_write(struct file *filep, const char *buf, size_t n, if (check_pselecd && (in(1) & LP_PSELECD)) { lirc_off(); local_irq_restore(flags); - return -EIO; + ret = -EIO; + goto out; } } while (counttimer < wbuf[i]); i++; @@ -436,7 +440,8 @@ static ssize_t lirc_write(struct file *filep, const char *buf, size_t n, level = newlevel; if (check_pselecd && (in(1) & LP_PSELECD)) { local_irq_restore(flags); - return -EIO; + ret = -EIO; + goto out; } } while (counttimer < wbuf[i]); i++; @@ -445,7 +450,11 @@ static ssize_t lirc_write(struct file *filep, const char *buf, size_t n, #else /* place code that handles write without external timer here */ #endif - return n; + ret = n; +out: + kfree(wbuf); + + return ret; } static unsigned int lirc_poll(struct file *file, poll_table *wait) diff --git a/drivers/staging/lirc/lirc_sasem.c b/drivers/staging/lirc/lirc_sasem.c index 998485ebdbce..925eabe14854 100644 --- a/drivers/staging/lirc/lirc_sasem.c +++ b/drivers/staging/lirc/lirc_sasem.c @@ -448,6 +448,7 @@ static ssize_t vfd_write(struct file *file, const char *buf, exit: mutex_unlock(&context->ctx_lock); + kfree(data_buf); return (!retval) ? n_bytes : retval; } diff --git a/drivers/staging/lirc/lirc_serial.c b/drivers/staging/lirc/lirc_serial.c index 9bcf149c4260..1c3099b388e0 100644 --- a/drivers/staging/lirc/lirc_serial.c +++ b/drivers/staging/lirc/lirc_serial.c @@ -966,7 +966,7 @@ static ssize_t lirc_write(struct file *file, const char *buf, if (n % sizeof(int) || count % 2 == 0) return -EINVAL; wbuf = memdup_user(buf, n); - if (PTR_ERR(wbuf)) + if (IS_ERR(wbuf)) return PTR_ERR(wbuf); spin_lock_irqsave(&hardware[type].lock, flags); if (type == LIRC_IRDEO) { @@ -981,6 +981,7 @@ static ssize_t lirc_write(struct file *file, const char *buf, } off(); spin_unlock_irqrestore(&hardware[type].lock, flags); + kfree(wbuf); return n; } diff --git a/drivers/staging/lirc/lirc_sir.c b/drivers/staging/lirc/lirc_sir.c index c553ab626238..76be7b8c6209 100644 --- a/drivers/staging/lirc/lirc_sir.c +++ b/drivers/staging/lirc/lirc_sir.c @@ -330,6 +330,7 @@ static ssize_t lirc_write(struct file *file, const char *buf, size_t n, /* enable receiver */ Ser2UTCR3 = UTCR3_RXE|UTCR3_RIE; #endif + kfree(tx_buf); return count; } -- cgit v1.2.3 From 490da40d82b31c0562d3f5edb37810f492ca1c34 Mon Sep 17 00:00:00 2001 From: Tao Ma Date: Wed, 19 Jan 2011 10:51:44 +0800 Subject: blktrace: Don't output messages if NOTIFY isn't set. Now if we enable blktrace, cfq has too many messages output to the trace buffer. It is fine if we don't specify any action mask. But if I do like this: blktrace /dev/sdb -a issue -a complete -o - | blkparse -i - I only want to see 'D' and 'C', while with the following command dd if=/mnt/ocfs2/test of=/dev/null bs=4k count=1 iflag=direct I will get(with a 2.6.37 vanilla kernel): 8,16 0 0 0.000000000 0 m N cfq3805 alloced 8,16 0 0 0.000004126 0 m N cfq3805 insert_request 8,16 0 0 0.000004884 0 m N cfq3805 add_to_rr 8,16 0 0 0.000008417 0 m N cfq workload slice:300 8,16 0 0 0.000009557 0 m N cfq3805 set_active wl_prio:0 wl_type:2 8,16 0 0 0.000010640 0 m N cfq3805 fifo= (null) 8,16 0 0 0.000011193 0 m N cfq3805 dispatch_insert 8,16 0 0 0.000012221 0 m N cfq3805 dispatched a request 8,16 0 0 0.000012802 0 m N cfq3805 activate rq, drv=1 8,16 0 1 0.000013181 3805 D R 114759 + 8 [dd] 8,16 0 2 0.000164244 0 C R 114759 + 8 [0] 8,16 0 0 0.000167997 0 m N cfq3805 complete rqnoidle 0 8,16 0 0 0.000168782 0 m N cfq3805 set_slice=100 8,16 0 0 0.000169874 0 m N cfq3805 arm_idle: 8 group_idle: 0 8,16 0 0 0.000170189 0 m N cfq schedule dispatch 8,16 0 0 0.000397938 0 m N cfq3805 slice expired t=0 8,16 0 0 0.000399763 0 m N cfq3805 sl_used=1 disp=1 charge=1 iops=0 sect=8 8,16 0 0 0.000400227 0 m N cfq3805 del_from_rr 8,16 0 0 0.000400882 0 m N cfq3805 put_queue See, there are 19 lines while I only need 2. I don't think it is appropriate for a user. So this patch will disable any messages if the BLK_TC_NOTIFY isn't set. Now the output for the same command will look like: 8,16 0 1 0.000000000 4908 D R 114759 + 8 [dd] 8,16 0 2 0.000146827 0 C R 114759 + 8 [0] Yes, it is what I want to see. Cc: Steven Rostedt Cc: Jeff Moyer Signed-off-by: Tao Ma Signed-off-by: Jens Axboe --- kernel/trace/blktrace.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/kernel/trace/blktrace.c b/kernel/trace/blktrace.c index 153562d0b93c..d95721f33702 100644 --- a/kernel/trace/blktrace.c +++ b/kernel/trace/blktrace.c @@ -138,6 +138,13 @@ void __trace_note_message(struct blk_trace *bt, const char *fmt, ...) !blk_tracer_enabled)) return; + /* + * If the BLK_TC_NOTIFY action mask isn't set, don't send any note + * message to the trace. + */ + if (!(bt->act_mask & BLK_TC_NOTIFY)) + return; + local_irq_save(flags); buf = per_cpu_ptr(bt->msg_data, smp_processor_id()); va_start(args, fmt); -- cgit v1.2.3 From 04de96c9c6981c5957aa5db39bbdc4d958d07efa Mon Sep 17 00:00:00 2001 From: Tracey Dent Date: Wed, 19 Jan 2011 08:25:02 -0700 Subject: drivers/block/Makefile: replace the use of -objs with -y Change Makefile to use -y instead of -objs because -objs is deprecated and should now be switched. According to (documentation/kbuild/makefiles.txt). Signed-off-by: Tracey Dent Signed-off-by: Andrew Morton Signed-off-by: Jens Axboe --- drivers/block/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/block/Makefile b/drivers/block/Makefile index d7f463d6312d..40528ba56d1b 100644 --- a/drivers/block/Makefile +++ b/drivers/block/Makefile @@ -39,4 +39,4 @@ obj-$(CONFIG_XEN_BLKDEV_FRONTEND) += xen-blkfront.o obj-$(CONFIG_BLK_DEV_DRBD) += drbd/ obj-$(CONFIG_BLK_DEV_RBD) += rbd.o -swim_mod-objs := swim.o swim_asm.o +swim_mod-y := swim.o swim_asm.o -- cgit v1.2.3 From ee71a968672a9951aee6014c55511007596425bc Mon Sep 17 00:00:00 2001 From: Sergey Senozhatsky Date: Wed, 19 Jan 2011 08:25:02 -0700 Subject: loop: queue_lock NULL pointer derefence in blk_throtl_exit Performing $ sudo mount -o loop -o umask=0 /dev/sdb1 /mnt/ mount: wrong fs type, bad option, bad superblock on /dev/loop0, missing codepage or helper program, or other error In some cases useful info is found in syslog - try dmesg | tail or so $ sudo modprobe -r loop results in oops: BUG: unable to handle kernel NULL pointer dereference at 0000000000000004 IP: [] do_raw_spin_lock+0x14/0x122 Process modprobe (pid: 6189, threadinfo ffff88009a898000, task ffff880154a88000) Call Trace: [] _raw_spin_lock_irq+0x4a/0x51 [] ? blk_throtl_exit+0x3b/0xa0 [] ? cancel_delayed_work_sync+0xd/0xf [] blk_throtl_exit+0x3b/0xa0 [] blk_release_queue+0x21/0x65 [] kobject_release+0x51/0x66 [] ? kobject_release+0x0/0x66 [] kref_put+0x43/0x4d [] kobject_put+0x47/0x4b [] blk_cleanup_queue+0x56/0x5b [] loop_exit+0x68/0x844 [loop] [] sys_delete_module+0x1e8/0x25b [] ? trace_hardirqs_on_thunk+0x3a/0x3f [] system_call_fastpath+0x16/0x1b because of an attempt to acquire NULL queue_lock. I added the same lines as in blk_queue_make_request - index 44e18c0..49e6a54 100644`fall back to embedded per-queue lock'. Signed-off-by: Sergey Senozhatsky Signed-off-by: Andrew Morton Signed-off-by: Jens Axboe --- drivers/block/loop.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/block/loop.c b/drivers/block/loop.c index 44e18c073c44..49e6a545eb63 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -1641,6 +1641,9 @@ out: static void loop_free(struct loop_device *lo) { + if (!lo->lo_queue->queue_lock) + lo->lo_queue->queue_lock = &lo->lo_queue->__queue_lock; + blk_cleanup_queue(lo->lo_queue); put_disk(lo->lo_disk); list_del(&lo->lo_list); -- cgit v1.2.3 From a0700bdd0b0150ea445159b1dee587f1507c272f Mon Sep 17 00:00:00 2001 From: Tracey Dent Date: Wed, 19 Jan 2011 08:25:02 -0700 Subject: drivers/block/aoe/Makefile: replace the use of -objs with -y Change Makefile to use -y instead of -objs because -objs is deprecated and should now be switched. According to (documentation/kbuild/makefiles.txt). Signed-off-by: Tracey Dent Cc: "Ed L. Cashin" Signed-off-by: Andrew Morton Signed-off-by: Jens Axboe --- drivers/block/aoe/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/block/aoe/Makefile b/drivers/block/aoe/Makefile index e76d997183c6..06ea82cdf27d 100644 --- a/drivers/block/aoe/Makefile +++ b/drivers/block/aoe/Makefile @@ -3,4 +3,4 @@ # obj-$(CONFIG_ATA_OVER_ETH) += aoe.o -aoe-objs := aoeblk.o aoechr.o aoecmd.o aoedev.o aoemain.o aoenet.o +aoe-y := aoeblk.o aoechr.o aoecmd.o aoedev.o aoemain.o aoenet.o -- cgit v1.2.3 From 68264e9d6781f7163e92c517769bb470fa43f6cd Mon Sep 17 00:00:00 2001 From: "Stephen M. Cameron" Date: Wed, 19 Jan 2011 08:25:02 -0700 Subject: cciss: make cciss_revalidate not loop through CISS_MAX_LUNS volumes unnecessarily. Signed-off-by: Stephen M. Cameron Signed-off-by: Andrew Morton Signed-off-by: Jens Axboe --- drivers/block/cciss.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c index 516d5bbec2b6..9279272b3732 100644 --- a/drivers/block/cciss.c +++ b/drivers/block/cciss.c @@ -2833,7 +2833,7 @@ static int cciss_revalidate(struct gendisk *disk) sector_t total_size; InquiryData_struct *inq_buff = NULL; - for (logvol = 0; logvol < CISS_MAX_LUN; logvol++) { + for (logvol = 0; logvol <= h->highest_lun; logvol++) { if (!h->drv[logvol]) continue; if (memcmp(h->drv[logvol]->LunID, drv->LunID, -- cgit v1.2.3 From ba5bd520f679c450fb6efa439618703bd0956daa Mon Sep 17 00:00:00 2001 From: Vivek Goyal Date: Wed, 19 Jan 2011 08:25:02 -0700 Subject: cfq: rename a function to give it more appropriate name o Rename a function to give it more approprate name. We are calculating cfq queue slice and function name gives the impression as if cfq group slice length is being calculated. Signed-off-by: Vivek Goyal Signed-off-by: Jens Axboe --- block/cfq-iosched.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c index 501ffdf0399c..ace168657136 100644 --- a/block/cfq-iosched.c +++ b/block/cfq-iosched.c @@ -599,7 +599,7 @@ cfq_group_slice(struct cfq_data *cfqd, struct cfq_group *cfqg) } static inline unsigned -cfq_scaled_group_slice(struct cfq_data *cfqd, struct cfq_queue *cfqq) +cfq_scaled_cfqq_slice(struct cfq_data *cfqd, struct cfq_queue *cfqq) { unsigned slice = cfq_prio_to_slice(cfqd, cfqq); if (cfqd->cfq_latency) { @@ -631,7 +631,7 @@ cfq_scaled_group_slice(struct cfq_data *cfqd, struct cfq_queue *cfqq) static inline void cfq_set_prio_slice(struct cfq_data *cfqd, struct cfq_queue *cfqq) { - unsigned slice = cfq_scaled_group_slice(cfqd, cfqq); + unsigned slice = cfq_scaled_cfqq_slice(cfqd, cfqq); cfqq->slice_start = jiffies; cfqq->slice_end = jiffies + slice; @@ -1671,7 +1671,7 @@ __cfq_slice_expired(struct cfq_data *cfqd, struct cfq_queue *cfqq, */ if (timed_out) { if (cfq_cfqq_slice_new(cfqq)) - cfqq->slice_resid = cfq_scaled_group_slice(cfqd, cfqq); + cfqq->slice_resid = cfq_scaled_cfqq_slice(cfqd, cfqq); else cfqq->slice_resid = cfqq->slice_end - jiffies; cfq_log_cfqq(cfqd, cfqq, "resid=%ld", cfqq->slice_resid); -- cgit v1.2.3 From be2c6b1990904dbd43f3d9b90fa2c530504375cd Mon Sep 17 00:00:00 2001 From: Vivek Goyal Date: Wed, 19 Jan 2011 08:25:02 -0700 Subject: blkio-throttle: Avoid calling blkiocg_lookup_group() for root group o Jeff Moyer was doing some testing on a RAM backed disk and blkiocg_lookup_group() showed up high overhead after memcpy(). Similarly somebody else reported that blkiocg_lookup_group() is eating 6% extra cpu. Though looking at the code I can't think why the overhead of this function is so high. One thing is that it is called with very high frequency (once for every IO). o For lot of folks blkio controller will be compiled in but they might not have actually created cgroups. Hence optimize the case of root cgroup where we can avoid calling blkiocg_lookup_group() if IO is happening in root group (common case). Reported-by: Jeff Moyer Signed-off-by: Vivek Goyal Acked-by: Jeff Moyer Signed-off-by: Jens Axboe --- block/blk-throttle.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/block/blk-throttle.c b/block/blk-throttle.c index 381b09bb562b..a89043a3caa4 100644 --- a/block/blk-throttle.c +++ b/block/blk-throttle.c @@ -168,7 +168,15 @@ static struct throtl_grp * throtl_find_alloc_tg(struct throtl_data *td, * tree of blkg (instead of traversing through hash list all * the time. */ - tg = tg_of_blkg(blkiocg_lookup_group(blkcg, key)); + + /* + * This is the common case when there are no blkio cgroups. + * Avoid lookup in this case + */ + if (blkcg == &blkio_root_cgroup) + tg = &td->root_tg; + else + tg = tg_of_blkg(blkiocg_lookup_group(blkcg, key)); /* Fill in device details for root group */ if (tg && !tg->blkg.dev && bdi->dev && dev_name(bdi->dev)) { -- cgit v1.2.3 From 5734a07cbb8d4600a74a374c839620ddc62b2cf2 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 19 Jan 2011 17:07:12 +0100 Subject: ALSA: hda - Add quirk for HP Z-series workstation It seems working well with model=hp-bpc. Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 4f006eedd7ef..7874023db0f3 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -12629,6 +12629,8 @@ static struct snd_pci_quirk alc262_cfg_tbl[] = { ALC262_HP_BPC), SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1300, "HP xw series", ALC262_HP_BPC), + SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1500, "HP z series", + ALC262_HP_BPC), SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1700, "HP xw series", ALC262_HP_BPC), SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL), -- cgit v1.2.3 From 5d1034f01b3616d6636ab7851ad9e63d42abbbd6 Mon Sep 17 00:00:00 2001 From: Grant Likely Date: Wed, 19 Jan 2011 08:59:33 -0700 Subject: powerpc/83xx: fix build failures on dt compatible list. Commit a4f740cf, "of/flattree: Add of_flat_dt_match() helper function" introduced build failures in arch/powerpc/platform/83xx by mistyping 'static' as 'struct' in the compatible string list, and omitting a few semicolons. This patch fixes it. Reported-by: Stephen Rothwell Signed-off-by: Grant Likely --- arch/powerpc/platforms/83xx/mpc830x_rdb.c | 4 ++-- arch/powerpc/platforms/83xx/mpc831x_rdb.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/powerpc/platforms/83xx/mpc830x_rdb.c b/arch/powerpc/platforms/83xx/mpc830x_rdb.c index 661d354e4ff2..d0c4e15b7794 100644 --- a/arch/powerpc/platforms/83xx/mpc830x_rdb.c +++ b/arch/powerpc/platforms/83xx/mpc830x_rdb.c @@ -57,12 +57,12 @@ static void __init mpc830x_rdb_init_IRQ(void) ipic_set_default_priority(); } -struct const char *board[] __initdata = { +static const char *board[] __initdata = { "MPC8308RDB", "fsl,mpc8308rdb", "denx,mpc8308_p1m", NULL -} +}; /* * Called very early, MMU is off, device-tree isn't unflattened diff --git a/arch/powerpc/platforms/83xx/mpc831x_rdb.c b/arch/powerpc/platforms/83xx/mpc831x_rdb.c index b54cd736a895..f859ead49a8d 100644 --- a/arch/powerpc/platforms/83xx/mpc831x_rdb.c +++ b/arch/powerpc/platforms/83xx/mpc831x_rdb.c @@ -60,11 +60,11 @@ static void __init mpc831x_rdb_init_IRQ(void) ipic_set_default_priority(); } -struct const char *board[] __initdata = { +static const char *board[] __initdata = { "MPC8313ERDB", "fsl,mpc8315erdb", NULL -} +}; /* * Called very early, MMU is off, device-tree isn't unflattened -- cgit v1.2.3 From aa1d0c5261f17d48636bf6d10bde0f38045511c0 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 19 Jan 2011 17:27:58 +0100 Subject: ALSA: hda - Fix "unused variable" compile warning MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit sound/pci/hda/patch_realtek.c: In function ‘alc_apply_fixup’: sound/pci/hda/patch_realtek.c:1724:14: warning: unused variable ‘modelname’ snd_printdd() is evaluated only when CONFIG_SND_DEBUG_VERBOSE=y. Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 7874023db0f3..2b055e2780bb 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -1721,7 +1721,9 @@ static void alc_apply_fixup(struct hda_codec *codec, int action) { struct alc_spec *spec = codec->spec; int id = spec->fixup_id; +#ifdef CONFIG_SND_DEBUG_VERBOSE const char *modelname = spec->fixup_name; +#endif int depth = 0; if (!spec->fixup_list) -- cgit v1.2.3 From 86e09287e4f8c81831b4d4118a48597565f0d21b Mon Sep 17 00:00:00 2001 From: Alexander Holler Date: Mon, 22 Nov 2010 21:09:01 +0100 Subject: Bluetooth: ath3k: reduce memory usage There is no need to hold the firmware in memory. Signed-off-by: Alexander Holler Signed-off-by: Gustavo F. Padovan --- drivers/bluetooth/ath3k.c | 75 +++++++++++++---------------------------------- 1 file changed, 20 insertions(+), 55 deletions(-) diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c index 949ed09c6361..a126e614601f 100644 --- a/drivers/bluetooth/ath3k.c +++ b/drivers/bluetooth/ath3k.c @@ -47,46 +47,40 @@ MODULE_DEVICE_TABLE(usb, ath3k_table); #define USB_REQ_DFU_DNLOAD 1 #define BULK_SIZE 4096 -struct ath3k_data { - struct usb_device *udev; - u8 *fw_data; - u32 fw_size; - u32 fw_sent; -}; - -static int ath3k_load_firmware(struct ath3k_data *data, - unsigned char *firmware, - int count) +static int ath3k_load_firmware(struct usb_device *udev, + const struct firmware *firmware) { u8 *send_buf; int err, pipe, len, size, sent = 0; + int count = firmware->size; - BT_DBG("ath3k %p udev %p", data, data->udev); + BT_DBG("udev %p", udev); - pipe = usb_sndctrlpipe(data->udev, 0); + pipe = usb_sndctrlpipe(udev, 0); - if ((usb_control_msg(data->udev, pipe, + send_buf = kmalloc(BULK_SIZE, GFP_ATOMIC); + if (!send_buf) { + BT_ERR("Can't allocate memory chunk for firmware"); + return -ENOMEM; + } + + memcpy(send_buf, firmware->data, 20); + if ((err = usb_control_msg(udev, pipe, USB_REQ_DFU_DNLOAD, USB_TYPE_VENDOR, 0, 0, - firmware, 20, USB_CTRL_SET_TIMEOUT)) < 0) { + send_buf, 20, USB_CTRL_SET_TIMEOUT)) < 0) { BT_ERR("Can't change to loading configuration err"); - return -EBUSY; + goto error; } sent += 20; count -= 20; - send_buf = kmalloc(BULK_SIZE, GFP_ATOMIC); - if (!send_buf) { - BT_ERR("Can't allocate memory chunk for firmware"); - return -ENOMEM; - } - while (count) { size = min_t(uint, count, BULK_SIZE); - pipe = usb_sndbulkpipe(data->udev, 0x02); - memcpy(send_buf, firmware + sent, size); + pipe = usb_sndbulkpipe(udev, 0x02); + memcpy(send_buf, firmware->data + sent, size); - err = usb_bulk_msg(data->udev, pipe, send_buf, size, + err = usb_bulk_msg(udev, pipe, send_buf, size, &len, 3000); if (err || (len != size)) { @@ -112,57 +106,28 @@ static int ath3k_probe(struct usb_interface *intf, { const struct firmware *firmware; struct usb_device *udev = interface_to_usbdev(intf); - struct ath3k_data *data; - int size; BT_DBG("intf %p id %p", intf, id); if (intf->cur_altsetting->desc.bInterfaceNumber != 0) return -ENODEV; - data = kzalloc(sizeof(*data), GFP_KERNEL); - if (!data) - return -ENOMEM; - - data->udev = udev; - if (request_firmware(&firmware, "ath3k-1.fw", &udev->dev) < 0) { - kfree(data); return -EIO; } - size = max_t(uint, firmware->size, 4096); - data->fw_data = kmalloc(size, GFP_KERNEL); - if (!data->fw_data) { + if (ath3k_load_firmware(udev, firmware)) { release_firmware(firmware); - kfree(data); - return -ENOMEM; - } - - memcpy(data->fw_data, firmware->data, firmware->size); - data->fw_size = firmware->size; - data->fw_sent = 0; - release_firmware(firmware); - - usb_set_intfdata(intf, data); - if (ath3k_load_firmware(data, data->fw_data, data->fw_size)) { - usb_set_intfdata(intf, NULL); - kfree(data->fw_data); - kfree(data); return -EIO; } + release_firmware(firmware); return 0; } static void ath3k_disconnect(struct usb_interface *intf) { - struct ath3k_data *data = usb_get_intfdata(intf); - BT_DBG("ath3k_disconnect intf %p", intf); - - kfree(data->fw_data); - kfree(data); } static struct usb_driver ath3k_driver = { -- cgit v1.2.3 From 4571928fc73589e9c5217cd069d2c0b4ff1818a8 Mon Sep 17 00:00:00 2001 From: David Sterba Date: Fri, 14 Jan 2011 14:59:44 +0100 Subject: Bluetooth: l2cap: fix misuse of logical operation in place of bitop MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CC: Marcel Holtmann CC: "Gustavo F. Padovan" CC: João Paulo Rechi Vita Signed-off-by: David Sterba Signed-off-by: Gustavo F. Padovan --- net/bluetooth/l2cap.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c index c791fcda7b2d..4fd88eb0a464 100644 --- a/net/bluetooth/l2cap.c +++ b/net/bluetooth/l2cap.c @@ -1893,8 +1893,8 @@ static int l2cap_sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct ms if (pi->mode == L2CAP_MODE_STREAMING) { l2cap_streaming_send(sk); } else { - if (pi->conn_state & L2CAP_CONN_REMOTE_BUSY && - pi->conn_state && L2CAP_CONN_WAIT_F) { + if ((pi->conn_state & L2CAP_CONN_REMOTE_BUSY) && + (pi->conn_state & L2CAP_CONN_WAIT_F)) { err = len; break; } -- cgit v1.2.3 From e2e0cacbd4b0c7c69c7591d37c243f2363aeaa71 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Tue, 4 Jan 2011 12:08:50 +0200 Subject: Bluetooth: Fix leaking blacklist when unregistering a hci device The blacklist should be freed before the hci device gets unregistered. Signed-off-by: Johan Hedberg Signed-off-by: Gustavo F. Padovan --- net/bluetooth/hci_core.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index 8b602d881fd7..9c4541bc488a 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c @@ -1011,6 +1011,10 @@ int hci_unregister_dev(struct hci_dev *hdev) destroy_workqueue(hdev->workqueue); + hci_dev_lock_bh(hdev); + hci_blacklist_clear(hdev); + hci_dev_unlock_bh(hdev); + __hci_dev_put(hdev); return 0; -- cgit v1.2.3 From 683d949a7fbf33c244670e34d35c460e0d6558cb Mon Sep 17 00:00:00 2001 From: Lukáš Turek <8an@praha12.net> Date: Wed, 5 Jan 2011 02:43:59 +0100 Subject: Bluetooth: Never deallocate a session when some DLC points to it Fix a bug introduced in commit 9cf5b0ea3a7f1432c61029f7aaf4b8b338628884: function rfcomm_recv_ua calls rfcomm_session_put without checking that the session is not referenced by some DLC. If the session is freed, that DLC would refer to deallocated memory, causing an oops later, as shown in this bug report: https://bugzilla.kernel.org/show_bug.cgi?id=15994 Signed-off-by: Lukas Turek <8an@praha12.net> Signed-off-by: Gustavo F. Padovan --- net/bluetooth/rfcomm/core.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c index ff8aaa736650..6b83776534fb 100644 --- a/net/bluetooth/rfcomm/core.c +++ b/net/bluetooth/rfcomm/core.c @@ -1164,7 +1164,8 @@ static int rfcomm_recv_ua(struct rfcomm_session *s, u8 dlci) * initiator rfcomm_process_rx already calls * rfcomm_session_put() */ if (s->sock->sk->sk_state != BT_CLOSED) - rfcomm_session_put(s); + if (list_empty(&s->dlcs)) + rfcomm_session_put(s); break; } } -- cgit v1.2.3 From 88644bb9fee591b2743a881923263bc28df4cded Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Wed, 19 Jan 2011 12:06:48 +0530 Subject: Revert "Bluetooth: Update sec_level/auth_type for already existing connections" This reverts commit 045309820afe047920a50de25634dab46a1e851d. That commit is wrong for two reasons: - The conn->sec_level shouldn't be updated without performing authentication first (as it's supposed to represent the level of security that the existing connection has) - A higher auth_type value doesn't mean "more secure" like the commit seems to assume. E.g. dedicated bonding with MITM protection is 0x03 whereas general bonding without MITM protection is 0x04. hci_conn_auth already takes care of updating conn->auth_type so hci_connect doesn't need to do it. Signed-off-by: Johan Hedberg Acked-by: Marcel Holtmann Signed-off-by: Gustavo F. Padovan --- net/bluetooth/hci_conn.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index 6b90a4191734..65a3fb5678eb 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c @@ -382,11 +382,6 @@ struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, __u8 acl->sec_level = sec_level; acl->auth_type = auth_type; hci_acl_connect(acl); - } else { - if (acl->sec_level < sec_level) - acl->sec_level = sec_level; - if (acl->auth_type < auth_type) - acl->auth_type = auth_type; } if (type == ACL_LINK) -- cgit v1.2.3 From 65cf686ee102b7eb0477a4bab82ff227071a0258 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Wed, 19 Jan 2011 12:06:49 +0530 Subject: Bluetooth: Fix MITM protection requirement preservation If an existing connection has a MITM protection requirement (the first bit of the auth_type) then that requirement should not be cleared by new sockets that reuse the ACL but don't have that requirement. Signed-off-by: Johan Hedberg Acked-by: Marcel Holtmann Signed-off-by: Gustavo F. Padovan --- net/bluetooth/hci_conn.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index 65a3fb5678eb..fe712a89a856 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c @@ -442,6 +442,9 @@ static int hci_conn_auth(struct hci_conn *conn, __u8 sec_level, __u8 auth_type) else if (conn->link_mode & HCI_LM_AUTH) return 1; + /* Make sure we preserve an existing MITM requirement*/ + auth_type |= (conn->auth_type & 0x01); + conn->auth_type = auth_type; if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->pend)) { -- cgit v1.2.3 From 8556edd32f01c50a3c99e44dc2c3b1252ea59605 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Wed, 19 Jan 2011 12:06:50 +0530 Subject: Bluetooth: Create a unified auth_type evaluation function The logic for determining the needed auth_type for an L2CAP socket is rather complicated and has so far been duplicated in l2cap_check_security as well as l2cap_do_connect. Additionally the l2cap_check_security code was completely missing the handling of SOCK_RAW type sockets. This patch creates a unified function for the evaluation and makes l2cap_do_connect and l2cap_check_security use that function. Signed-off-by: Johan Hedberg Acked-by: Marcel Holtmann Signed-off-by: Gustavo F. Padovan --- net/bluetooth/l2cap.c | 77 +++++++++++++++++++-------------------------------- 1 file changed, 28 insertions(+), 49 deletions(-) diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c index 4fd88eb0a464..ae227bf25563 100644 --- a/net/bluetooth/l2cap.c +++ b/net/bluetooth/l2cap.c @@ -305,33 +305,44 @@ static void l2cap_chan_del(struct sock *sk, int err) } } -/* Service level security */ -static inline int l2cap_check_security(struct sock *sk) +static inline u8 l2cap_get_auth_type(struct sock *sk) { - struct l2cap_conn *conn = l2cap_pi(sk)->conn; - __u8 auth_type; + if (sk->sk_type == SOCK_RAW) { + switch (l2cap_pi(sk)->sec_level) { + case BT_SECURITY_HIGH: + return HCI_AT_DEDICATED_BONDING_MITM; + case BT_SECURITY_MEDIUM: + return HCI_AT_DEDICATED_BONDING; + default: + return HCI_AT_NO_BONDING; + } + } else if (l2cap_pi(sk)->psm == cpu_to_le16(0x0001)) { + if (l2cap_pi(sk)->sec_level == BT_SECURITY_LOW) + l2cap_pi(sk)->sec_level = BT_SECURITY_SDP; - if (l2cap_pi(sk)->psm == cpu_to_le16(0x0001)) { if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH) - auth_type = HCI_AT_NO_BONDING_MITM; + return HCI_AT_NO_BONDING_MITM; else - auth_type = HCI_AT_NO_BONDING; - - if (l2cap_pi(sk)->sec_level == BT_SECURITY_LOW) - l2cap_pi(sk)->sec_level = BT_SECURITY_SDP; + return HCI_AT_NO_BONDING; } else { switch (l2cap_pi(sk)->sec_level) { case BT_SECURITY_HIGH: - auth_type = HCI_AT_GENERAL_BONDING_MITM; - break; + return HCI_AT_GENERAL_BONDING_MITM; case BT_SECURITY_MEDIUM: - auth_type = HCI_AT_GENERAL_BONDING; - break; + return HCI_AT_GENERAL_BONDING; default: - auth_type = HCI_AT_NO_BONDING; - break; + return HCI_AT_NO_BONDING; } } +} + +/* Service level security */ +static inline int l2cap_check_security(struct sock *sk) +{ + struct l2cap_conn *conn = l2cap_pi(sk)->conn; + __u8 auth_type; + + auth_type = l2cap_get_auth_type(sk); return hci_conn_security(conn->hcon, l2cap_pi(sk)->sec_level, auth_type); @@ -1068,39 +1079,7 @@ static int l2cap_do_connect(struct sock *sk) err = -ENOMEM; - if (sk->sk_type == SOCK_RAW) { - switch (l2cap_pi(sk)->sec_level) { - case BT_SECURITY_HIGH: - auth_type = HCI_AT_DEDICATED_BONDING_MITM; - break; - case BT_SECURITY_MEDIUM: - auth_type = HCI_AT_DEDICATED_BONDING; - break; - default: - auth_type = HCI_AT_NO_BONDING; - break; - } - } else if (l2cap_pi(sk)->psm == cpu_to_le16(0x0001)) { - if (l2cap_pi(sk)->sec_level == BT_SECURITY_HIGH) - auth_type = HCI_AT_NO_BONDING_MITM; - else - auth_type = HCI_AT_NO_BONDING; - - if (l2cap_pi(sk)->sec_level == BT_SECURITY_LOW) - l2cap_pi(sk)->sec_level = BT_SECURITY_SDP; - } else { - switch (l2cap_pi(sk)->sec_level) { - case BT_SECURITY_HIGH: - auth_type = HCI_AT_GENERAL_BONDING_MITM; - break; - case BT_SECURITY_MEDIUM: - auth_type = HCI_AT_GENERAL_BONDING; - break; - default: - auth_type = HCI_AT_NO_BONDING; - break; - } - } + auth_type = l2cap_get_auth_type(sk); hcon = hci_connect(hdev, ACL_LINK, dst, l2cap_pi(sk)->sec_level, auth_type); -- cgit v1.2.3 From d00ef24fc2923b65fdd440dc6445903e965841ac Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Wed, 19 Jan 2011 12:06:51 +0530 Subject: Bluetooth: Fix authentication request for L2CAP raw sockets When there is an existing connection l2cap_check_security needs to be called to ensure that the security level of the new socket is fulfilled. Normally l2cap_do_start takes care of this, but that function doesn't get called for SOCK_RAW type sockets. This patch adds the necessary l2cap_check_security call to the appropriate branch in l2cap_do_connect. Signed-off-by: Johan Hedberg Acked-by: Marcel Holtmann Signed-off-by: Gustavo F. Padovan --- net/bluetooth/l2cap.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c index ae227bf25563..7550abb0c96a 100644 --- a/net/bluetooth/l2cap.c +++ b/net/bluetooth/l2cap.c @@ -1106,7 +1106,8 @@ static int l2cap_do_connect(struct sock *sk) if (sk->sk_type != SOCK_SEQPACKET && sk->sk_type != SOCK_STREAM) { l2cap_sock_clear_timer(sk); - sk->sk_state = BT_CONNECTED; + if (l2cap_check_security(sk)) + sk->sk_state = BT_CONNECTED; } else l2cap_do_start(sk); } -- cgit v1.2.3 From 765c2a964b49bd06b61a52991519281c85d82b67 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Wed, 19 Jan 2011 12:06:52 +0530 Subject: Bluetooth: Fix race condition with conn->sec_level The conn->sec_level value is supposed to represent the current level of security that the connection has. However, by assigning to it before requesting authentication it will have the wrong value during the authentication procedure. To fix this a pending_sec_level variable is added which is used to track the desired security level while making sure that sec_level always represents the current level of security. Signed-off-by: Johan Hedberg Signed-off-by: Gustavo F. Padovan --- include/net/bluetooth/hci_core.h | 1 + net/bluetooth/hci_conn.c | 8 ++++++-- net/bluetooth/hci_event.c | 9 +++++---- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index a29feb01854e..d2cf88407690 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -184,6 +184,7 @@ struct hci_conn { __u32 link_mode; __u8 auth_type; __u8 sec_level; + __u8 pending_sec_level; __u8 power_save; __u16 disc_timeout; unsigned long pend; diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index fe712a89a856..99cd8d9d891b 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c @@ -379,7 +379,8 @@ struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst, __u8 hci_conn_hold(acl); if (acl->state == BT_OPEN || acl->state == BT_CLOSED) { - acl->sec_level = sec_level; + acl->sec_level = BT_SECURITY_LOW; + acl->pending_sec_level = sec_level; acl->auth_type = auth_type; hci_acl_connect(acl); } @@ -437,8 +438,11 @@ static int hci_conn_auth(struct hci_conn *conn, __u8 sec_level, __u8 auth_type) { BT_DBG("conn %p", conn); + if (conn->pending_sec_level > sec_level) + sec_level = conn->pending_sec_level; + if (sec_level > conn->sec_level) - conn->sec_level = sec_level; + conn->pending_sec_level = sec_level; else if (conn->link_mode & HCI_LM_AUTH) return 1; diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 38100170d380..a290854fdaa6 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -692,13 +692,13 @@ static int hci_outgoing_auth_needed(struct hci_dev *hdev, if (conn->state != BT_CONFIG || !conn->out) return 0; - if (conn->sec_level == BT_SECURITY_SDP) + if (conn->pending_sec_level == BT_SECURITY_SDP) return 0; /* Only request authentication for SSP connections or non-SSP * devices with sec_level HIGH */ if (!(hdev->ssp_mode > 0 && conn->ssp_mode > 0) && - conn->sec_level != BT_SECURITY_HIGH) + conn->pending_sec_level != BT_SECURITY_HIGH) return 0; return 1; @@ -1095,9 +1095,10 @@ static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *s conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle)); if (conn) { - if (!ev->status) + if (!ev->status) { conn->link_mode |= HCI_LM_AUTH; - else + conn->sec_level = conn->pending_sec_level; + } else conn->sec_level = BT_SECURITY_LOW; clear_bit(HCI_CONN_AUTH_PEND, &conn->pend); -- cgit v1.2.3 From 50aac4fec503960380ab594a93a6fbfdf3f8915f Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Tue, 18 Jan 2011 07:59:40 -0800 Subject: ceph: fix cap_wanted_delay_{min,max} mount option initialization These were initialized to 0 instead of the default, fallout from the RBD refactor in 3d14c5d2b6e15c21d8e5467dc62d33127c23a644. Signed-off-by: Sage Weil --- fs/ceph/super.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fs/ceph/super.c b/fs/ceph/super.c index bf6f0f34082a..9c5085465a63 100644 --- a/fs/ceph/super.c +++ b/fs/ceph/super.c @@ -290,6 +290,8 @@ static int parse_mount_options(struct ceph_mount_options **pfsopt, fsopt->rsize = CEPH_MOUNT_RSIZE_DEFAULT; fsopt->snapdir_name = kstrdup(CEPH_SNAPDIRNAME_DEFAULT, GFP_KERNEL); + fsopt->caps_wanted_delay_min = CEPH_CAPS_WANTED_DELAY_MIN_DEFAULT; + fsopt->caps_wanted_delay_max = CEPH_CAPS_WANTED_DELAY_MAX_DEFAULT; fsopt->cap_release_safety = CEPH_CAP_RELEASE_SAFETY_DEFAULT; fsopt->max_readdir = CEPH_MAX_READDIR_DEFAULT; fsopt->max_readdir_bytes = CEPH_MAX_READDIR_BYTES_DEFAULT; -- cgit v1.2.3 From 24be0c481067560b11441e794e27f166a3568863 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Tue, 18 Jan 2011 08:48:06 -0800 Subject: ceph: fix erroneous cap flush to non-auth mds The int flushing is global and not clear on each iteration of the loop, which can cause a second flush of caps to any MDSs with ids greater than the auth. Signed-off-by: Sage Weil --- fs/ceph/caps.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c index 60d27bc9eb83..f654c7e933ac 100644 --- a/fs/ceph/caps.c +++ b/fs/ceph/caps.c @@ -1658,6 +1658,8 @@ ack: if (cap == ci->i_auth_cap && ci->i_dirty_caps) flushing = __mark_caps_flushing(inode, session); + else + flushing = 0; mds = cap->mds; /* remember mds, so we don't repeat */ sent++; -- cgit v1.2.3 From 088b3f5e9ee2649f5cfc2f08d8ce654e3eeba310 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Tue, 18 Jan 2011 08:56:01 -0800 Subject: ceph: fix flushing of caps vs cap import If we are mid-flush and a cap is migrated to another node, we need to resend the cap flush message to the new MDS, and do so with the original flush_seq to avoid leaking across a sync boundary. Previously we didn't redo the flush (we only flushed newly dirty data), which would cause a later sync to hang forever. Signed-off-by: Sage Weil --- fs/ceph/caps.c | 38 ++++++++++++++++++++++++++++++++++---- 1 file changed, 34 insertions(+), 4 deletions(-) diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c index f654c7e933ac..7def3f5903dd 100644 --- a/fs/ceph/caps.c +++ b/fs/ceph/caps.c @@ -1560,9 +1560,10 @@ retry_locked: /* NOTE: no side-effects allowed, until we take s_mutex */ revoking = cap->implemented & ~cap->issued; - if (revoking) - dout(" mds%d revoking %s\n", cap->mds, - ceph_cap_string(revoking)); + dout(" mds%d cap %p issued %s implemented %s revoking %s\n", + cap->mds, cap, ceph_cap_string(cap->issued), + ceph_cap_string(cap->implemented), + ceph_cap_string(revoking)); if (cap == ci->i_auth_cap && (cap->issued & CEPH_CAP_FILE_WR)) { @@ -1942,6 +1943,35 @@ void ceph_kick_flushing_caps(struct ceph_mds_client *mdsc, } } +static void kick_flushing_inode_caps(struct ceph_mds_client *mdsc, + struct ceph_mds_session *session, + struct inode *inode) +{ + struct ceph_inode_info *ci = ceph_inode(inode); + struct ceph_cap *cap; + int delayed = 0; + + spin_lock(&inode->i_lock); + cap = ci->i_auth_cap; + dout("kick_flushing_inode_caps %p flushing %s flush_seq %lld\n", inode, + ceph_cap_string(ci->i_flushing_caps), ci->i_cap_flush_seq); + __ceph_flush_snaps(ci, &session, 1); + if (ci->i_flushing_caps) { + delayed = __send_cap(mdsc, cap, CEPH_CAP_OP_FLUSH, + __ceph_caps_used(ci), + __ceph_caps_wanted(ci), + cap->issued | cap->implemented, + ci->i_flushing_caps, NULL); + if (delayed) { + spin_lock(&inode->i_lock); + __cap_delay_requeue(mdsc, ci); + spin_unlock(&inode->i_lock); + } + } else { + spin_unlock(&inode->i_lock); + } +} + /* * Take references to capabilities we hold, so that we don't release @@ -2689,7 +2719,7 @@ static void handle_cap_import(struct ceph_mds_client *mdsc, ceph_add_cap(inode, session, cap_id, -1, issued, wanted, seq, mseq, realmino, CEPH_CAP_FLAG_AUTH, NULL /* no caps context */); - try_flush_caps(inode, session, NULL); + kick_flushing_inode_caps(mdsc, session, inode); up_read(&mdsc->snap_rwsem); /* make sure we re-request max_size, if necessary */ -- cgit v1.2.3 From 7e57b81c7688c762bc9e775bc83f9fc17946f527 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Tue, 18 Jan 2011 09:00:01 -0800 Subject: ceph: avoid immediate cap check after import The NODELAY flag avoids the heuristics that delay cap (issued/wanted) release. There's no reason for that after we import a cap, and it kills whatever benefit we get from those delays. Signed-off-by: Sage Weil --- fs/ceph/caps.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c index 7def3f5903dd..6b61ded701e1 100644 --- a/fs/ceph/caps.c +++ b/fs/ceph/caps.c @@ -2817,8 +2817,7 @@ void ceph_handle_caps(struct ceph_mds_session *session, case CEPH_CAP_OP_IMPORT: handle_cap_import(mdsc, inode, h, session, snaptrace, snaptrace_len); - ceph_check_caps(ceph_inode(inode), CHECK_CAPS_NODELAY, - session); + ceph_check_caps(ceph_inode(inode), 0, session); goto done_unlocked; } -- cgit v1.2.3 From 12fed00de963433128b5366a21a55808fab2f756 Mon Sep 17 00:00:00 2001 From: Pavel Shilovsky Date: Mon, 17 Jan 2011 20:15:44 +0300 Subject: CIFS: Fix oplock break handling (try #2) When we get oplock break notification we should set the appropriate value of OplockLevel field in oplock break acknowledge according to the oplock level held by the client in this time. As we only can have level II oplock or no oplock in the case of oplock break, we should be aware only about clientCanCacheRead field in cifsInodeInfo structure. Also fix bug connected with wrong interpretation of OplockLevel field during oplock break notification processing. Signed-off-by: Pavel Shilovsky Cc: Signed-off-by: Steve French --- fs/cifs/cifsproto.h | 2 +- fs/cifs/cifssmb.c | 4 +++- fs/cifs/file.c | 21 +++++++++++---------- fs/cifs/misc.c | 2 +- 4 files changed, 16 insertions(+), 13 deletions(-) diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index e6d1481b16c1..95d5dbbb4c7a 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h @@ -347,7 +347,7 @@ extern int CIFSSMBLock(const int xid, struct cifsTconInfo *tcon, const __u16 netfid, const __u64 len, const __u64 offset, const __u32 numUnlock, const __u32 numLock, const __u8 lockType, - const bool waitFlag); + const bool waitFlag, const __u8 oplock_level); extern int CIFSSMBPosixLock(const int xid, struct cifsTconInfo *tcon, const __u16 smb_file_id, const int get_flag, const __u64 len, struct file_lock *, diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index 2f6795e524d3..3652cc60314c 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c @@ -1663,7 +1663,8 @@ int CIFSSMBLock(const int xid, struct cifsTconInfo *tcon, const __u16 smb_file_id, const __u64 len, const __u64 offset, const __u32 numUnlock, - const __u32 numLock, const __u8 lockType, const bool waitFlag) + const __u32 numLock, const __u8 lockType, + const bool waitFlag, const __u8 oplock_level) { int rc = 0; LOCK_REQ *pSMB = NULL; @@ -1691,6 +1692,7 @@ CIFSSMBLock(const int xid, struct cifsTconInfo *tcon, pSMB->NumberOfLocks = cpu_to_le16(numLock); pSMB->NumberOfUnlocks = cpu_to_le16(numUnlock); pSMB->LockType = lockType; + pSMB->OplockLevel = oplock_level; pSMB->AndXCommand = 0xFF; /* none */ pSMB->Fid = smb_file_id; /* netfid stays le */ diff --git a/fs/cifs/file.c b/fs/cifs/file.c index d843631c028d..af371910f543 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -726,12 +726,12 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock) /* BB we could chain these into one lock request BB */ rc = CIFSSMBLock(xid, tcon, netfid, length, pfLock->fl_start, - 0, 1, lockType, 0 /* wait flag */ ); + 0, 1, lockType, 0 /* wait flag */, 0); if (rc == 0) { rc = CIFSSMBLock(xid, tcon, netfid, length, pfLock->fl_start, 1 /* numUnlock */ , 0 /* numLock */ , lockType, - 0 /* wait flag */ ); + 0 /* wait flag */, 0); pfLock->fl_type = F_UNLCK; if (rc != 0) cERROR(1, "Error unlocking previously locked " @@ -748,13 +748,13 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock) rc = CIFSSMBLock(xid, tcon, netfid, length, pfLock->fl_start, 0, 1, lockType | LOCKING_ANDX_SHARED_LOCK, - 0 /* wait flag */); + 0 /* wait flag */, 0); if (rc == 0) { rc = CIFSSMBLock(xid, tcon, netfid, length, pfLock->fl_start, 1, 0, lockType | LOCKING_ANDX_SHARED_LOCK, - 0 /* wait flag */); + 0 /* wait flag */, 0); pfLock->fl_type = F_RDLCK; if (rc != 0) cERROR(1, "Error unlocking " @@ -797,8 +797,8 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock) if (numLock) { rc = CIFSSMBLock(xid, tcon, netfid, length, - pfLock->fl_start, - 0, numLock, lockType, wait_flag); + pfLock->fl_start, 0, numLock, lockType, + wait_flag, 0); if (rc == 0) { /* For Windows locks we must store them. */ @@ -818,9 +818,9 @@ int cifs_lock(struct file *file, int cmd, struct file_lock *pfLock) (pfLock->fl_start + length) >= (li->offset + li->length)) { stored_rc = CIFSSMBLock(xid, tcon, - netfid, - li->length, li->offset, - 1, 0, li->type, false); + netfid, li->length, + li->offset, 1, 0, + li->type, false, 0); if (stored_rc) rc = stored_rc; else { @@ -2192,7 +2192,8 @@ void cifs_oplock_break(struct work_struct *work) */ if (!cfile->oplock_break_cancelled) { rc = CIFSSMBLock(0, tlink_tcon(cfile->tlink), cfile->netfid, 0, - 0, 0, 0, LOCKING_ANDX_OPLOCK_RELEASE, false); + 0, 0, 0, LOCKING_ANDX_OPLOCK_RELEASE, false, + cinode->clientCanCacheRead ? 1 : 0); cFYI(1, "Oplock release rc = %d", rc); } diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c index 43f10281bc19..09bfcf08a90f 100644 --- a/fs/cifs/misc.c +++ b/fs/cifs/misc.c @@ -571,7 +571,7 @@ is_valid_oplock_break(struct smb_hdr *buf, struct TCP_Server_Info *srv) pCifsInode = CIFS_I(netfile->dentry->d_inode); cifs_set_oplock_level(pCifsInode, - pSMB->OplockLevel); + pSMB->OplockLevel ? OPLOCK_READ : 0); /* * cifs_oplock_break_put() can't be called * from here. Get reference after queueing -- cgit v1.2.3 From 941b853d779de3298e39f1eb4e252984464eaea8 Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Tue, 11 Jan 2011 07:24:01 -0500 Subject: cifs: don't fail writepages on -EAGAIN errors If CIFSSMBWrite2 returns -EAGAIN, then the error should be considered temporary. CIFS should retry the write instead of setting an error on the mapping and returning. For WB_SYNC_ALL, just retry the write immediately. In the WB_SYNC_NONE case, call redirty_page_for_writeback on all of the pages that didn't get written out and then move on. Also, fix up the handling of a short write with a successful return code. MS-CIFS says that 0 bytes_written means ENOSPC or EFBIG. It doesn't mention what a short, but non-zero write means, so for now treat it as we would an -EAGAIN return. Reviewed-by: Suresh Jayaraman Reviewed-by: Pavel Shilovsky Signed-off-by: Jeff Layton Signed-off-by: Steve French --- fs/cifs/file.c | 49 +++++++++++++++++++++++++++++++++++++------------ 1 file changed, 37 insertions(+), 12 deletions(-) diff --git a/fs/cifs/file.c b/fs/cifs/file.c index af371910f543..cfa2e5ebcafe 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -1377,6 +1377,7 @@ retry: break; } if (n_iov) { +retry_write: open_file = find_writable_file(CIFS_I(mapping->host), false); if (!open_file) { @@ -1389,31 +1390,55 @@ retry: &bytes_written, iov, n_iov, long_op); cifsFileInfo_put(open_file); - cifs_update_eof(cifsi, offset, bytes_written); } - if (rc || bytes_written < bytes_to_write) { - cERROR(1, "Write2 ret %d, wrote %d", - rc, bytes_written); - mapping_set_error(mapping, rc); - } else { + cFYI(1, "Write2 rc=%d, wrote=%u", rc, bytes_written); + + /* + * For now, treat a short write as if nothing got + * written. A zero length write however indicates + * ENOSPC or EFBIG. We have no way to know which + * though, so call it ENOSPC for now. EFBIG would + * get translated to AS_EIO anyway. + * + * FIXME: make it take into account the data that did + * get written + */ + if (rc == 0) { + if (bytes_written == 0) + rc = -ENOSPC; + else if (bytes_written < bytes_to_write) + rc = -EAGAIN; + } + + /* retry on data-integrity flush */ + if (wbc->sync_mode == WB_SYNC_ALL && rc == -EAGAIN) + goto retry_write; + + /* fix the stats and EOF */ + if (bytes_written > 0) { cifs_stats_bytes_written(tcon, bytes_written); + cifs_update_eof(cifsi, offset, bytes_written); } for (i = 0; i < n_iov; i++) { page = pvec.pages[first + i]; - /* Should we also set page error on - success rc but too little data written? */ - /* BB investigate retry logic on temporary - server crash cases and how recovery works - when page marked as error */ - if (rc) + /* on retryable write error, redirty page */ + if (rc == -EAGAIN) + redirty_page_for_writepage(wbc, page); + else if (rc != 0) SetPageError(page); kunmap(page); unlock_page(page); end_page_writeback(page); page_cache_release(page); } + + if (rc != -EAGAIN) + mapping_set_error(mapping, rc); + else + rc = 0; + if ((wbc->nr_to_write -= n_iov) <= 0) done = 1; index = next; -- cgit v1.2.3 From 9d78315b03fc91228306db42edc533efa69cb518 Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Tue, 11 Jan 2011 07:24:01 -0500 Subject: cifs: no need to mark smb_ses_list as cifs_demultiplex_thread is exiting The TCP_Server_Info is refcounted and every SMB session holds a reference to it. Thus, smb_ses_list is always going to be empty when cifsd is coming down. This is dead code. Reviewed-by: Suresh Jayaraman Reviewed-by: Pavel Shilovsky Signed-off-by: Jeff Layton Signed-off-by: Steve French --- fs/cifs/connect.c | 44 +++----------------------------------------- 1 file changed, 3 insertions(+), 41 deletions(-) diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 9f59887badd2..75b538f50b12 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -346,7 +346,6 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server) struct kvec iov; struct socket *csocket = server->ssocket; struct list_head *tmp; - struct cifsSesInfo *ses; struct task_struct *task_to_wake = NULL; struct mid_q_entry *mid_entry; char temp; @@ -677,44 +676,19 @@ multi_t2_fnd: if (smallbuf) /* no sense logging a debug message if NULL */ cifs_small_buf_release(smallbuf); - /* - * BB: we shouldn't have to do any of this. It shouldn't be - * possible to exit from the thread with active SMB sessions - */ - spin_lock(&cifs_tcp_ses_lock); - if (list_empty(&server->pending_mid_q)) { - /* loop through server session structures attached to this and - mark them dead */ - list_for_each(tmp, &server->smb_ses_list) { - ses = list_entry(tmp, struct cifsSesInfo, - smb_ses_list); - ses->status = CifsExiting; - ses->server = NULL; - } - spin_unlock(&cifs_tcp_ses_lock); - } else { - /* although we can not zero the server struct pointer yet, - since there are active requests which may depnd on them, - mark the corresponding SMB sessions as exiting too */ - list_for_each(tmp, &server->smb_ses_list) { - ses = list_entry(tmp, struct cifsSesInfo, - smb_ses_list); - ses->status = CifsExiting; - } - + if (!list_empty(&server->pending_mid_q)) { spin_lock(&GlobalMid_Lock); list_for_each(tmp, &server->pending_mid_q) { - mid_entry = list_entry(tmp, struct mid_q_entry, qhead); + mid_entry = list_entry(tmp, struct mid_q_entry, qhead); if (mid_entry->midState == MID_REQUEST_SUBMITTED) { cFYI(1, "Clearing Mid 0x%x - waking up ", - mid_entry->mid); + mid_entry->mid); task_to_wake = mid_entry->tsk; if (task_to_wake) wake_up_process(task_to_wake); } } spin_unlock(&GlobalMid_Lock); - spin_unlock(&cifs_tcp_ses_lock); /* 1/8th of sec is more than enough time for them to exit */ msleep(125); } @@ -732,18 +706,6 @@ multi_t2_fnd: coming home not much else we can do but free the memory */ } - /* last chance to mark ses pointers invalid - if there are any pointing to this (e.g - if a crazy root user tried to kill cifsd - kernel thread explicitly this might happen) */ - /* BB: This shouldn't be necessary, see above */ - spin_lock(&cifs_tcp_ses_lock); - list_for_each(tmp, &server->smb_ses_list) { - ses = list_entry(tmp, struct cifsSesInfo, smb_ses_list); - ses->server = NULL; - } - spin_unlock(&cifs_tcp_ses_lock); - kfree(server->hostname); task_to_wake = xchg(&server->tsk, NULL); kfree(server); -- cgit v1.2.3 From c5797a945cac4c470f0113fc839c521aab0d799d Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Tue, 11 Jan 2011 07:24:01 -0500 Subject: cifs: make wait_for_free_request take a TCP_Server_Info pointer The cifsSesInfo pointer is only used to get at the server. Reviewed-by: Suresh Jayaraman Reviewed-by: Pavel Shilovsky Signed-off-by: Jeff Layton Signed-off-by: Steve French --- fs/cifs/transport.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c index 59ca81b16919..9a14f77e0ab2 100644 --- a/fs/cifs/transport.c +++ b/fs/cifs/transport.c @@ -244,31 +244,31 @@ smb_send(struct TCP_Server_Info *server, struct smb_hdr *smb_buffer, return smb_sendv(server, &iov, 1); } -static int wait_for_free_request(struct cifsSesInfo *ses, const int long_op) +static int wait_for_free_request(struct TCP_Server_Info *server, + const int long_op) { if (long_op == CIFS_ASYNC_OP) { /* oplock breaks must not be held up */ - atomic_inc(&ses->server->inFlight); + atomic_inc(&server->inFlight); return 0; } spin_lock(&GlobalMid_Lock); while (1) { - if (atomic_read(&ses->server->inFlight) >= - cifs_max_pending){ + if (atomic_read(&server->inFlight) >= cifs_max_pending) { spin_unlock(&GlobalMid_Lock); #ifdef CONFIG_CIFS_STATS2 - atomic_inc(&ses->server->num_waiters); + atomic_inc(&server->num_waiters); #endif - wait_event(ses->server->request_q, - atomic_read(&ses->server->inFlight) + wait_event(server->request_q, + atomic_read(&server->inFlight) < cifs_max_pending); #ifdef CONFIG_CIFS_STATS2 - atomic_dec(&ses->server->num_waiters); + atomic_dec(&server->num_waiters); #endif spin_lock(&GlobalMid_Lock); } else { - if (ses->server->tcpStatus == CifsExiting) { + if (server->tcpStatus == CifsExiting) { spin_unlock(&GlobalMid_Lock); return -ENOENT; } @@ -278,7 +278,7 @@ static int wait_for_free_request(struct cifsSesInfo *ses, const int long_op) /* update # of requests on the wire to server */ if (long_op != CIFS_BLOCKING_OP) - atomic_inc(&ses->server->inFlight); + atomic_inc(&server->inFlight); spin_unlock(&GlobalMid_Lock); break; } @@ -413,7 +413,7 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses, to the same server. We may make this configurable later or use ses->maxReq */ - rc = wait_for_free_request(ses, long_op); + rc = wait_for_free_request(ses->server, long_op); if (rc) { cifs_small_buf_release(in_buf); return rc; @@ -610,7 +610,7 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses, return -EIO; } - rc = wait_for_free_request(ses, long_op); + rc = wait_for_free_request(ses->server, long_op); if (rc) return rc; @@ -845,7 +845,7 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifsTconInfo *tcon, return -EIO; } - rc = wait_for_free_request(ses, CIFS_BLOCKING_OP); + rc = wait_for_free_request(ses->server, CIFS_BLOCKING_OP); if (rc) return rc; -- cgit v1.2.3 From 8097531a5cb55c6472118da094dc88caf9be66ac Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Tue, 11 Jan 2011 07:24:02 -0500 Subject: cifs: clean up accesses to midCount It's an atomic_t and the code accesses the "counter" field in it directly instead of using atomic_read(). It also is sometimes accessed under a spinlock and sometimes not. Move it out of the spinlock since we don't need belt-and-suspenders for something that's just informational. Reviewed-by: Suresh Jayaraman Reviewed-by: Pavel Shilovsky Signed-off-by: Jeff Layton Signed-off-by: Steve French --- fs/cifs/cifs_debug.c | 2 +- fs/cifs/connect.c | 2 +- fs/cifs/transport.c | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/fs/cifs/cifs_debug.c b/fs/cifs/cifs_debug.c index ede98300a8cd..e2d0d5d455fa 100644 --- a/fs/cifs/cifs_debug.c +++ b/fs/cifs/cifs_debug.c @@ -331,7 +331,7 @@ static int cifs_stats_proc_show(struct seq_file *m, void *v) atomic_read(&totSmBufAllocCount)); #endif /* CONFIG_CIFS_STATS2 */ - seq_printf(m, "Operations (MIDs): %d\n", midCount.counter); + seq_printf(m, "Operations (MIDs): %d\n", atomic_read(&midCount)); seq_printf(m, "\n%d session %d share reconnects\n", tcpSesReconnectCount.counter, tconInfoReconnectCount.counter); diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 75b538f50b12..465ecad6d7cc 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -628,7 +628,7 @@ multi_t2_fnd: } else if (!is_valid_oplock_break(smb_buffer, server) && !isMultiRsp) { cERROR(1, "No task to wake, unknown frame received! " - "NumMids %d", midCount.counter); + "NumMids %d", atomic_read(&midCount)); cifs_dump_mem("Received Data is: ", (char *)smb_buffer, sizeof(struct smb_hdr)); #ifdef CONFIG_CIFS_DEBUG2 diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c index 9a14f77e0ab2..b9eb0cffa003 100644 --- a/fs/cifs/transport.c +++ b/fs/cifs/transport.c @@ -61,10 +61,10 @@ AllocMidQEntry(const struct smb_hdr *smb_buffer, struct TCP_Server_Info *server) temp->tsk = current; } - spin_lock(&GlobalMid_Lock); - list_add_tail(&temp->qhead, &server->pending_mid_q); atomic_inc(&midCount); temp->midState = MID_REQUEST_ALLOCATED; + spin_lock(&GlobalMid_Lock); + list_add_tail(&temp->qhead, &server->pending_mid_q); spin_unlock(&GlobalMid_Lock); return temp; } @@ -78,8 +78,8 @@ DeleteMidQEntry(struct mid_q_entry *midEntry) spin_lock(&GlobalMid_Lock); midEntry->midState = MID_FREE; list_del(&midEntry->qhead); - atomic_dec(&midCount); spin_unlock(&GlobalMid_Lock); + atomic_dec(&midCount); if (midEntry->largeBuf) cifs_buf_release(midEntry->resp_buf); else -- cgit v1.2.3 From ddc8cf8fc718587a3788330bf4f32b379f08b250 Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Tue, 11 Jan 2011 07:24:02 -0500 Subject: cifs: move locked sections out of DeleteMidQEntry and AllocMidQEntry In later patches, we're going to need to have finer-grained control over the addition and removal of these structs from the pending_mid_q and we'll need to be able to call the destructor while holding the spinlock. Move the locked sections out of both routines and into the callers. Fix up current callers of DeleteMidQEntry to call a new routine that dequeues the entry and then destroys it. Reviewed-by: Suresh Jayaraman Reviewed-by: Pavel Shilovsky Signed-off-by: Jeff Layton Signed-off-by: Steve French --- fs/cifs/transport.c | 41 ++++++++++++++++++++++++----------------- 1 file changed, 24 insertions(+), 17 deletions(-) diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c index b9eb0cffa003..801726b11e1e 100644 --- a/fs/cifs/transport.c +++ b/fs/cifs/transport.c @@ -63,9 +63,6 @@ AllocMidQEntry(const struct smb_hdr *smb_buffer, struct TCP_Server_Info *server) atomic_inc(&midCount); temp->midState = MID_REQUEST_ALLOCATED; - spin_lock(&GlobalMid_Lock); - list_add_tail(&temp->qhead, &server->pending_mid_q); - spin_unlock(&GlobalMid_Lock); return temp; } @@ -75,10 +72,7 @@ DeleteMidQEntry(struct mid_q_entry *midEntry) #ifdef CONFIG_CIFS_STATS2 unsigned long now; #endif - spin_lock(&GlobalMid_Lock); midEntry->midState = MID_FREE; - list_del(&midEntry->qhead); - spin_unlock(&GlobalMid_Lock); atomic_dec(&midCount); if (midEntry->largeBuf) cifs_buf_release(midEntry->resp_buf); @@ -103,6 +97,16 @@ DeleteMidQEntry(struct mid_q_entry *midEntry) mempool_free(midEntry, cifs_mid_poolp); } +static void +delete_mid(struct mid_q_entry *mid) +{ + spin_lock(&GlobalMid_Lock); + list_del(&mid->qhead); + spin_unlock(&GlobalMid_Lock); + + DeleteMidQEntry(mid); +} + static int smb_sendv(struct TCP_Server_Info *server, struct kvec *iov, int n_vec) { @@ -308,6 +312,9 @@ static int allocate_mid(struct cifsSesInfo *ses, struct smb_hdr *in_buf, *ppmidQ = AllocMidQEntry(in_buf, ses->server); if (*ppmidQ == NULL) return -ENOMEM; + spin_lock(&GlobalMid_Lock); + list_add_tail(&(*ppmidQ)->qhead, &ses->server->pending_mid_q); + spin_unlock(&GlobalMid_Lock); return 0; } @@ -508,7 +515,7 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses, } } spin_unlock(&GlobalMid_Lock); - DeleteMidQEntry(midQ); + delete_mid(midQ); /* Update # of requests on wire to server */ atomic_dec(&ses->server->inFlight); wake_up(&ses->server->request_q); @@ -564,14 +571,14 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses, if ((flags & CIFS_NO_RESP) == 0) midQ->resp_buf = NULL; /* mark it so buf will not be freed by - DeleteMidQEntry */ + delete_mid */ } else { rc = -EIO; cFYI(1, "Bad MID state?"); } out: - DeleteMidQEntry(midQ); + delete_mid(midQ); atomic_dec(&ses->server->inFlight); wake_up(&ses->server->request_q); @@ -699,7 +706,7 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses, } } spin_unlock(&GlobalMid_Lock); - DeleteMidQEntry(midQ); + delete_mid(midQ); /* Update # of requests on wire to server */ atomic_dec(&ses->server->inFlight); wake_up(&ses->server->request_q); @@ -755,7 +762,7 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses, } out: - DeleteMidQEntry(midQ); + delete_mid(midQ); atomic_dec(&ses->server->inFlight); wake_up(&ses->server->request_q); @@ -863,7 +870,7 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifsTconInfo *tcon, rc = cifs_sign_smb(in_buf, ses->server, &midQ->sequence_number); if (rc) { - DeleteMidQEntry(midQ); + delete_mid(midQ); mutex_unlock(&ses->server->srv_mutex); return rc; } @@ -880,7 +887,7 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifsTconInfo *tcon, mutex_unlock(&ses->server->srv_mutex); if (rc < 0) { - DeleteMidQEntry(midQ); + delete_mid(midQ); return rc; } @@ -902,7 +909,7 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifsTconInfo *tcon, rc = send_nt_cancel(tcon, in_buf, midQ); if (rc) { - DeleteMidQEntry(midQ); + delete_mid(midQ); return rc; } } else { @@ -914,7 +921,7 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifsTconInfo *tcon, /* If we get -ENOLCK back the lock may have already been removed. Don't exit in this case. */ if (rc && rc != -ENOLCK) { - DeleteMidQEntry(midQ); + delete_mid(midQ); return rc; } } @@ -951,7 +958,7 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifsTconInfo *tcon, } } spin_unlock(&GlobalMid_Lock); - DeleteMidQEntry(midQ); + delete_mid(midQ); return rc; } @@ -1001,7 +1008,7 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifsTconInfo *tcon, BCC(out_buf) = le16_to_cpu(BCC_LE(out_buf)); out: - DeleteMidQEntry(midQ); + delete_mid(midQ); if (rstart && rc == -EACCES) return -ERESTARTSYS; return rc; -- cgit v1.2.3 From 053d50344568e5a4054266b44040297531125281 Mon Sep 17 00:00:00 2001 From: Jeff Layton Date: Tue, 11 Jan 2011 07:24:02 -0500 Subject: cifs: move mid result processing into common function Reviewed-by: Suresh Jayaraman Reviewed-by: Pavel Shilovsky Signed-off-by: Jeff Layton Signed-off-by: Steve French --- fs/cifs/transport.c | 121 +++++++++++++++++++--------------------------------- 1 file changed, 43 insertions(+), 78 deletions(-) diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c index 801726b11e1e..15059c7ef2ae 100644 --- a/fs/cifs/transport.c +++ b/fs/cifs/transport.c @@ -389,6 +389,42 @@ SendReceiveNoRsp(const unsigned int xid, struct cifsSesInfo *ses, return rc; } +static int +sync_mid_result(struct mid_q_entry *mid, struct TCP_Server_Info *server) +{ + int rc = 0; + + spin_lock(&GlobalMid_Lock); + + if (mid->resp_buf) { + spin_unlock(&GlobalMid_Lock); + return rc; + } + + cERROR(1, "No response to cmd %d mid %d", mid->command, mid->mid); + if (mid->midState == MID_REQUEST_SUBMITTED) { + if (server->tcpStatus == CifsExiting) + rc = -EHOSTDOWN; + else { + server->tcpStatus = CifsNeedReconnect; + mid->midState = MID_RETRY_NEEDED; + } + } + + if (rc != -EHOSTDOWN) { + if (mid->midState == MID_RETRY_NEEDED) { + rc = -EAGAIN; + cFYI(1, "marking request for retry"); + } else { + rc = -EIO; + } + } + spin_unlock(&GlobalMid_Lock); + + delete_mid(mid); + return rc; +} + int SendReceive2(const unsigned int xid, struct cifsSesInfo *ses, struct kvec *iov, int n_vec, int *pRespBufType /* ret */, @@ -492,37 +528,13 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses, /* No user interrupts in wait - wreaks havoc with performance */ wait_for_response(ses, midQ, timeout, 10 * HZ); - spin_lock(&GlobalMid_Lock); - - if (midQ->resp_buf == NULL) { - cERROR(1, "No response to cmd %d mid %d", - midQ->command, midQ->mid); - if (midQ->midState == MID_REQUEST_SUBMITTED) { - if (ses->server->tcpStatus == CifsExiting) - rc = -EHOSTDOWN; - else { - ses->server->tcpStatus = CifsNeedReconnect; - midQ->midState = MID_RETRY_NEEDED; - } - } - - if (rc != -EHOSTDOWN) { - if (midQ->midState == MID_RETRY_NEEDED) { - rc = -EAGAIN; - cFYI(1, "marking request for retry"); - } else { - rc = -EIO; - } - } - spin_unlock(&GlobalMid_Lock); - delete_mid(midQ); - /* Update # of requests on wire to server */ + rc = sync_mid_result(midQ, ses->server); + if (rc != 0) { atomic_dec(&ses->server->inFlight); wake_up(&ses->server->request_q); return rc; } - spin_unlock(&GlobalMid_Lock); receive_len = midQ->resp_buf->smb_buf_length; if (receive_len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE) { @@ -684,36 +696,13 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses, /* No user interrupts in wait - wreaks havoc with performance */ wait_for_response(ses, midQ, timeout, 10 * HZ); - spin_lock(&GlobalMid_Lock); - if (midQ->resp_buf == NULL) { - cERROR(1, "No response for cmd %d mid %d", - midQ->command, midQ->mid); - if (midQ->midState == MID_REQUEST_SUBMITTED) { - if (ses->server->tcpStatus == CifsExiting) - rc = -EHOSTDOWN; - else { - ses->server->tcpStatus = CifsNeedReconnect; - midQ->midState = MID_RETRY_NEEDED; - } - } - - if (rc != -EHOSTDOWN) { - if (midQ->midState == MID_RETRY_NEEDED) { - rc = -EAGAIN; - cFYI(1, "marking request for retry"); - } else { - rc = -EIO; - } - } - spin_unlock(&GlobalMid_Lock); - delete_mid(midQ); - /* Update # of requests on wire to server */ + rc = sync_mid_result(midQ, ses->server); + if (rc != 0) { atomic_dec(&ses->server->inFlight); wake_up(&ses->server->request_q); return rc; } - spin_unlock(&GlobalMid_Lock); receive_len = midQ->resp_buf->smb_buf_length; if (receive_len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE) { @@ -933,35 +922,11 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifsTconInfo *tcon, } } - spin_lock(&GlobalMid_Lock); - if (midQ->resp_buf) { - spin_unlock(&GlobalMid_Lock); - receive_len = midQ->resp_buf->smb_buf_length; - } else { - cERROR(1, "No response for cmd %d mid %d", - midQ->command, midQ->mid); - if (midQ->midState == MID_REQUEST_SUBMITTED) { - if (ses->server->tcpStatus == CifsExiting) - rc = -EHOSTDOWN; - else { - ses->server->tcpStatus = CifsNeedReconnect; - midQ->midState = MID_RETRY_NEEDED; - } - } - - if (rc != -EHOSTDOWN) { - if (midQ->midState == MID_RETRY_NEEDED) { - rc = -EAGAIN; - cFYI(1, "marking request for retry"); - } else { - rc = -EIO; - } - } - spin_unlock(&GlobalMid_Lock); - delete_mid(midQ); + rc = sync_mid_result(midQ, ses->server); + if (rc != 0) return rc; - } + receive_len = midQ->resp_buf->smb_buf_length; if (receive_len > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE) { cERROR(1, "Frame too large received. Length: %d Xid: %d", receive_len, xid); -- cgit v1.2.3 From 1cd3508d5eab6a88fa643119cedd34b04215cffe Mon Sep 17 00:00:00 2001 From: Steve French Date: Wed, 19 Jan 2011 17:53:44 +0000 Subject: [CIFS] Update cifs version number Signed-off-by: Steve French --- fs/cifs/cifsfs.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h index 851030f74939..4739a531cded 100644 --- a/fs/cifs/cifsfs.h +++ b/fs/cifs/cifsfs.h @@ -118,5 +118,5 @@ extern long cifs_ioctl(struct file *filep, unsigned int cmd, unsigned long arg); extern const struct export_operations cifs_export_ops; #endif /* EXPERIMENTAL */ -#define CIFS_VERSION "1.68" +#define CIFS_VERSION "1.69" #endif /* _CIFSFS_H */ -- cgit v1.2.3 From 540b2e377797d8715469d408b887baa9310c5f3e Mon Sep 17 00:00:00 2001 From: Shirish Pargaonkar Date: Tue, 18 Jan 2011 22:33:54 -0600 Subject: cifs: Fix regression during share-level security mounts (Repost) NTLM response length was changed to 16 bytes instead of 24 bytes that are sent in Tree Connection Request during share-level security share mounts. Revert it back to 24 bytes. Reported-and-Tested-by: Grzegorz Ozanski Acked-by: Jeff Layton Signed-off-by: Shirish Pargaonkar Acked-by: Suresh Jayaraman Cc: stable@kernel.org Signed-off-by: Steve French --- fs/cifs/connect.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 465ecad6d7cc..5c7f8450dbe0 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -2927,7 +2927,7 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses, bcc_ptr++; /* skip password */ /* already aligned so no need to do it below */ } else { - pSMB->PasswordLength = cpu_to_le16(CIFS_SESS_KEY_SIZE); + pSMB->PasswordLength = cpu_to_le16(CIFS_AUTH_RESP_SIZE); /* BB FIXME add code to fail this if NTLMv2 or Kerberos specified as required (when that support is added to the vfs in the future) as only NTLM or the much @@ -2945,7 +2945,7 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses, #endif /* CIFS_WEAK_PW_HASH */ SMBNTencrypt(tcon->password, ses->server->cryptkey, bcc_ptr); - bcc_ptr += CIFS_SESS_KEY_SIZE; + bcc_ptr += CIFS_AUTH_RESP_SIZE; if (ses->capabilities & CAP_UNICODE) { /* must align unicode strings */ *bcc_ptr = 0; /* null byte password */ -- cgit v1.2.3 From 05b5ca9b100300c8b98429962071aa66c5d2460e Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Tue, 18 Jan 2011 12:42:23 -0800 Subject: omap1: Fix booting for 15xx and 730 with omap1_defconfig For omap15xx and 730 we need to use the MPU timer as the 32K timer is not available. For omap16xx we want to use the 32K timer because of PM. Fix this by allowing to build in both timers. Signed-off-by: Tony Lindgren --- arch/arm/mach-omap1/Kconfig | 2 ++ arch/arm/mach-omap1/Makefile | 3 +- arch/arm/mach-omap1/time.c | 48 +++++++++++++++++++++++--------- arch/arm/mach-omap1/timer32k.c | 13 ++++----- arch/arm/plat-omap/Kconfig | 8 ++---- arch/arm/plat-omap/counter_32k.c | 5 ---- arch/arm/plat-omap/include/plat/common.h | 1 + 7 files changed, 47 insertions(+), 33 deletions(-) diff --git a/arch/arm/mach-omap1/Kconfig b/arch/arm/mach-omap1/Kconfig index 8d2f2daba0c0..e0a028161dde 100644 --- a/arch/arm/mach-omap1/Kconfig +++ b/arch/arm/mach-omap1/Kconfig @@ -9,6 +9,7 @@ config ARCH_OMAP730 depends on ARCH_OMAP1 bool "OMAP730 Based System" select CPU_ARM926T + select OMAP_MPU_TIMER select ARCH_OMAP_OTG config ARCH_OMAP850 @@ -22,6 +23,7 @@ config ARCH_OMAP15XX default y bool "OMAP15xx Based System" select CPU_ARM925T + select OMAP_MPU_TIMER config ARCH_OMAP16XX depends on ARCH_OMAP1 diff --git a/arch/arm/mach-omap1/Makefile b/arch/arm/mach-omap1/Makefile index 6ee19504845f..ba6009f27677 100644 --- a/arch/arm/mach-omap1/Makefile +++ b/arch/arm/mach-omap1/Makefile @@ -3,12 +3,11 @@ # # Common support -obj-y := io.o id.o sram.o irq.o mux.o flash.o serial.o devices.o dma.o +obj-y := io.o id.o sram.o time.o irq.o mux.o flash.o serial.o devices.o dma.o obj-y += clock.o clock_data.o opp_data.o obj-$(CONFIG_OMAP_MCBSP) += mcbsp.o -obj-$(CONFIG_OMAP_MPU_TIMER) += time.o obj-$(CONFIG_OMAP_32K_TIMER) += timer32k.o # Power Management diff --git a/arch/arm/mach-omap1/time.c b/arch/arm/mach-omap1/time.c index a39a15e4f3f9..b03f34d55d88 100644 --- a/arch/arm/mach-omap1/time.c +++ b/arch/arm/mach-omap1/time.c @@ -57,6 +57,8 @@ #include +#ifdef CONFIG_OMAP_MPU_TIMER + #define OMAP_MPU_TIMER_BASE OMAP_MPU_TIMER1_BASE #define OMAP_MPU_TIMER_OFFSET 0x100 @@ -236,12 +238,7 @@ static void __init omap_init_clocksource(unsigned long rate) printk(err, clocksource_mpu.name); } -/* - * --------------------------------------------------------------------------- - * Timer initialization - * --------------------------------------------------------------------------- - */ -static void __init omap_timer_init(void) +static void __init omap_mpu_timer_init(void) { struct clk *ck_ref = clk_get(NULL, "ck_ref"); unsigned long rate; @@ -256,13 +253,38 @@ static void __init omap_timer_init(void) omap_init_mpu_timer(rate); omap_init_clocksource(rate); - /* - * XXX Since this file seems to deal mostly with the MPU timer, - * this doesn't seem like the correct place for the sync timer - * clocksource init. - */ - if (!cpu_is_omap7xx() && !cpu_is_omap15xx()) - omap_init_clocksource_32k(); +} + +#else +static inline void omap_mpu_timer_init(void) +{ + pr_err("Bogus timer, should not happen\n"); +} +#endif /* CONFIG_OMAP_MPU_TIMER */ + +static inline int omap_32k_timer_usable(void) +{ + int res = false; + + if (cpu_is_omap730() || cpu_is_omap15xx()) + return res; + +#ifdef CONFIG_OMAP_32K_TIMER + res = omap_32k_timer_init(); +#endif + + return res; +} + +/* + * --------------------------------------------------------------------------- + * Timer initialization + * --------------------------------------------------------------------------- + */ +static void __init omap_timer_init(void) +{ + if (!omap_32k_timer_usable()) + omap_mpu_timer_init(); } struct sys_timer omap_timer = { diff --git a/arch/arm/mach-omap1/timer32k.c b/arch/arm/mach-omap1/timer32k.c index 20cfbcc6c60c..13d7b8f145bd 100644 --- a/arch/arm/mach-omap1/timer32k.c +++ b/arch/arm/mach-omap1/timer32k.c @@ -52,10 +52,9 @@ #include #include #include +#include #include -struct sys_timer omap_timer; - /* * --------------------------------------------------------------------------- * 32KHz OS timer @@ -181,14 +180,14 @@ static __init void omap_init_32k_timer(void) * Timer initialization * --------------------------------------------------------------------------- */ -static void __init omap_timer_init(void) +bool __init omap_32k_timer_init(void) { + omap_init_clocksource_32k(); + #ifdef CONFIG_OMAP_DM_TIMER omap_dm_timer_init(); #endif omap_init_32k_timer(); -} -struct sys_timer omap_timer = { - .init = omap_timer_init, -}; + return true; +} diff --git a/arch/arm/plat-omap/Kconfig b/arch/arm/plat-omap/Kconfig index 18fe3cb195dc..b6333ae3f92a 100644 --- a/arch/arm/plat-omap/Kconfig +++ b/arch/arm/plat-omap/Kconfig @@ -144,12 +144,9 @@ config OMAP_IOMMU_DEBUG config OMAP_IOMMU_IVA2 bool -choice - prompt "System timer" - default OMAP_32K_TIMER if !ARCH_OMAP15XX - config OMAP_MPU_TIMER bool "Use mpu timer" + depends on ARCH_OMAP1 help Select this option if you want to use the OMAP mpu timer. This timer provides more intra-tick resolution than the 32KHz timer, @@ -158,6 +155,7 @@ config OMAP_MPU_TIMER config OMAP_32K_TIMER bool "Use 32KHz timer" depends on ARCH_OMAP16XX || ARCH_OMAP2PLUS + default y if (ARCH_OMAP16XX || ARCH_OMAP2PLUS) help Select this option if you want to enable the OMAP 32KHz timer. This timer saves power compared to the OMAP_MPU_TIMER, and has @@ -165,8 +163,6 @@ config OMAP_32K_TIMER intra-tick resolution than OMAP_MPU_TIMER. The 32KHz timer is currently only available for OMAP16XX, 24XX, 34XX and OMAP4. -endchoice - config OMAP3_L2_AUX_SECURE_SAVE_RESTORE bool "OMAP3 HS/EMU save and restore for L2 AUX control register" depends on ARCH_OMAP3 && PM diff --git a/arch/arm/plat-omap/counter_32k.c b/arch/arm/plat-omap/counter_32k.c index 0367998ff685..5d7b08b5a13a 100644 --- a/arch/arm/plat-omap/counter_32k.c +++ b/arch/arm/plat-omap/counter_32k.c @@ -36,8 +36,6 @@ #define OMAP16XX_TIMER_32K_SYNCHRONIZED 0xfffbc410 -#if !(defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP15XX)) - #include /* @@ -195,6 +193,3 @@ int __init omap_init_clocksource_32k(void) } return 0; } - -#endif /* !(defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP15XX)) */ - diff --git a/arch/arm/plat-omap/include/plat/common.h b/arch/arm/plat-omap/include/plat/common.h index 84c707f713b1..ef683e01701b 100644 --- a/arch/arm/plat-omap/include/plat/common.h +++ b/arch/arm/plat-omap/include/plat/common.h @@ -35,6 +35,7 @@ struct sys_timer; extern void omap_map_common_io(void); extern struct sys_timer omap_timer; +extern bool omap_32k_timer_init(void); extern int __init omap_init_clocksource_32k(void); extern void omap_reserve(void); -- cgit v1.2.3 From 4912cf04b202a9d0bdc4082ecb9247943584450d Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Tue, 18 Jan 2011 17:00:00 -0800 Subject: omap1: Fix sched_clock implementation when both MPU timer and 32K timer are used Earlier patches select HAVE_SCHED_CLOCK for omaps. To have working sched_clock also for MPU timer, we need to implement it in a way where the right one gets selected during the runtime. Signed-off-by: Tony Lindgren --- arch/arm/mach-omap1/time.c | 48 +++++++++++++++++++++++++++++++- arch/arm/plat-omap/counter_32k.c | 14 +++++++++- arch/arm/plat-omap/include/plat/common.h | 1 + 3 files changed, 61 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-omap1/time.c b/arch/arm/mach-omap1/time.c index b03f34d55d88..f83fc335c613 100644 --- a/arch/arm/mach-omap1/time.c +++ b/arch/arm/mach-omap1/time.c @@ -219,6 +219,24 @@ static struct clocksource clocksource_mpu = { static DEFINE_CLOCK_DATA(cd); +static inline unsigned long long notrace _omap_mpu_sched_clock(void) +{ + u32 cyc = mpu_read(&clocksource_mpu); + return cyc_to_sched_clock(&cd, cyc, (u32)~0); +} + +#ifndef CONFIG_OMAP_32K_TIMER +unsigned long long notrace sched_clock(void) +{ + return _omap_mpu_sched_clock(); +} +#else +static unsigned long long notrace omap_mpu_sched_clock(void) +{ + return _omap_mpu_sched_clock(); +} +#endif + static void notrace mpu_update_sched_clock(void) { u32 cyc = mpu_read(&clocksource_mpu); @@ -262,6 +280,30 @@ static inline void omap_mpu_timer_init(void) } #endif /* CONFIG_OMAP_MPU_TIMER */ +#if defined(CONFIG_OMAP_MPU_TIMER) && defined(CONFIG_OMAP_32K_TIMER) +static unsigned long long (*preferred_sched_clock)(void); + +unsigned long long notrace sched_clock(void) +{ + if (!preferred_sched_clock) + return 0; + + return preferred_sched_clock(); +} + +static inline void preferred_sched_clock_init(bool use_32k_sched_clock) +{ + if (use_32k_sched_clock) + preferred_sched_clock = omap_32k_sched_clock; + else + preferred_sched_clock = omap_mpu_sched_clock; +} +#else +static inline void preferred_sched_clock_init(bool use_32k_sched_clcok) +{ +} +#endif + static inline int omap_32k_timer_usable(void) { int res = false; @@ -283,8 +325,12 @@ static inline int omap_32k_timer_usable(void) */ static void __init omap_timer_init(void) { - if (!omap_32k_timer_usable()) + if (omap_32k_timer_usable()) { + preferred_sched_clock_init(1); + } else { omap_mpu_timer_init(); + preferred_sched_clock_init(0); + } } struct sys_timer omap_timer = { diff --git a/arch/arm/plat-omap/counter_32k.c b/arch/arm/plat-omap/counter_32k.c index 5d7b08b5a13a..862dda95d61d 100644 --- a/arch/arm/plat-omap/counter_32k.c +++ b/arch/arm/plat-omap/counter_32k.c @@ -120,12 +120,24 @@ static DEFINE_CLOCK_DATA(cd); #define SC_MULT 4000000000u #define SC_SHIFT 17 -unsigned long long notrace sched_clock(void) +static inline unsigned long long notrace _omap_32k_sched_clock(void) { u32 cyc = clocksource_32k.read(&clocksource_32k); return cyc_to_fixed_sched_clock(&cd, cyc, (u32)~0, SC_MULT, SC_SHIFT); } +#ifndef CONFIG_OMAP_MPU_TIMER +unsigned long long notrace sched_clock(void) +{ + return _omap_32k_sched_clock(); +} +#else +unsigned long long notrace omap_32k_sched_clock(void) +{ + return _omap_32k_sched_clock(); +} +#endif + static void notrace omap_update_sched_clock(void) { u32 cyc = clocksource_32k.read(&clocksource_32k); diff --git a/arch/arm/plat-omap/include/plat/common.h b/arch/arm/plat-omap/include/plat/common.h index ef683e01701b..29b2afb4288f 100644 --- a/arch/arm/plat-omap/include/plat/common.h +++ b/arch/arm/plat-omap/include/plat/common.h @@ -37,6 +37,7 @@ extern void omap_map_common_io(void); extern struct sys_timer omap_timer; extern bool omap_32k_timer_init(void); extern int __init omap_init_clocksource_32k(void); +extern unsigned long long notrace omap_32k_sched_clock(void); extern void omap_reserve(void); -- cgit v1.2.3 From dbe08d82ce3967ccdf459f7951d02589cf967300 Mon Sep 17 00:00:00 2001 From: Oleg Nesterov Date: Wed, 19 Jan 2011 19:22:07 +0100 Subject: perf: Fix find_get_context() vs perf_event_exit_task() race find_get_context() must not install the new perf_event_context if the task has already passed perf_event_exit_task(). If nothing else, this means the memory leak. Initially ctx->refcount == 2, it is supposed that perf_event_exit_task_context() should participate and do the necessary put_ctx(). find_lively_task_by_vpid() checks PF_EXITING but this buys nothing, by the time we call find_get_context() this task can be already dead. To the point, cmpxchg() can succeed when the task has already done the last schedule(). Change find_get_context() to populate task->perf_event_ctxp[] under task->perf_event_mutex, this way we can trust PF_EXITING because perf_event_exit_task() takes the same mutex. Also, change perf_event_exit_task_context() to use rcu_dereference(). Probably this is not strictly needed, but with or without this change find_get_context() can race with setup_new_exec()->perf_event_exit_task(), rcu_dereference() looks better. Signed-off-by: Oleg Nesterov Acked-by: Peter Zijlstra Cc: Alan Stern Cc: Arnaldo Carvalho de Melo Cc: Frederic Weisbecker Cc: Paul Mackerras Cc: Prasad Cc: Roland McGrath LKML-Reference: <20110119182207.GB12183@redhat.com> Signed-off-by: Ingo Molnar --- kernel/perf_event.c | 34 ++++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/kernel/perf_event.c b/kernel/perf_event.c index 84522c796987..4ec55ef5810c 100644 --- a/kernel/perf_event.c +++ b/kernel/perf_event.c @@ -2201,13 +2201,6 @@ find_lively_task_by_vpid(pid_t vpid) if (!task) return ERR_PTR(-ESRCH); - /* - * Can't attach events to a dying task. - */ - err = -ESRCH; - if (task->flags & PF_EXITING) - goto errout; - /* Reuse ptrace permission checks for now. */ err = -EACCES; if (!ptrace_may_access(task, PTRACE_MODE_READ)) @@ -2268,14 +2261,27 @@ retry: get_ctx(ctx); - if (cmpxchg(&task->perf_event_ctxp[ctxn], NULL, ctx)) { - /* - * We raced with some other task; use - * the context they set. - */ + err = 0; + mutex_lock(&task->perf_event_mutex); + /* + * If it has already passed perf_event_exit_task(). + * we must see PF_EXITING, it takes this mutex too. + */ + if (task->flags & PF_EXITING) + err = -ESRCH; + else if (task->perf_event_ctxp[ctxn]) + err = -EAGAIN; + else + rcu_assign_pointer(task->perf_event_ctxp[ctxn], ctx); + mutex_unlock(&task->perf_event_mutex); + + if (unlikely(err)) { put_task_struct(task); kfree(ctx); - goto retry; + + if (err == -EAGAIN) + goto retry; + goto errout; } } @@ -6127,7 +6133,7 @@ static void perf_event_exit_task_context(struct task_struct *child, int ctxn) * scheduled, so we are now safe from rescheduling changing * our context. */ - child_ctx = child->perf_event_ctxp[ctxn]; + child_ctx = rcu_dereference(child->perf_event_ctxp[ctxn]); task_ctx_sched_out(child_ctx, EVENT_ALL); /* -- cgit v1.2.3 From 8550d7cb6ed6c89add49c3b6ad4c753ab8a3d7f9 Mon Sep 17 00:00:00 2001 From: Oleg Nesterov Date: Wed, 19 Jan 2011 19:22:28 +0100 Subject: perf: Fix perf_event_init_task()/perf_event_free_task() interaction perf_event_init_task() should clear child->perf_event_ctxp[] before anything else. Otherwise, if perf_event_init_context(perf_hw_context) fails, perf_event_free_task() can free perf_event_ctxp[perf_sw_context] copied from parent->perf_event_ctxp[] by dup_task_struct(). Also move the initialization of perf_event_mutex and perf_event_list from perf_event_init_context() to perf_event_init_context(). Signed-off-by: Oleg Nesterov Acked-by: Peter Zijlstra Cc: Alan Stern Cc: Arnaldo Carvalho de Melo Cc: Frederic Weisbecker Cc: Paul Mackerras Cc: Prasad Cc: Roland McGrath LKML-Reference: <20110119182228.GC12183@redhat.com> Signed-off-by: Ingo Molnar --- kernel/perf_event.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/kernel/perf_event.c b/kernel/perf_event.c index 4ec55ef5810c..244ca3acb0ee 100644 --- a/kernel/perf_event.c +++ b/kernel/perf_event.c @@ -6446,11 +6446,6 @@ int perf_event_init_context(struct task_struct *child, int ctxn) unsigned long flags; int ret = 0; - child->perf_event_ctxp[ctxn] = NULL; - - mutex_init(&child->perf_event_mutex); - INIT_LIST_HEAD(&child->perf_event_list); - if (likely(!parent->perf_event_ctxp[ctxn])) return 0; @@ -6539,6 +6534,10 @@ int perf_event_init_task(struct task_struct *child) { int ctxn, ret; + memset(child->perf_event_ctxp, 0, sizeof(child->perf_event_ctxp)); + mutex_init(&child->perf_event_mutex); + INIT_LIST_HEAD(&child->perf_event_list); + for_each_task_context_nr(ctxn) { ret = perf_event_init_context(child, ctxn); if (ret) -- cgit v1.2.3 From 8c8a9b25b5de3f1eeac721cf34f4379e56d5d694 Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Tue, 18 Jan 2011 21:44:04 +1100 Subject: powerpc, perf: Fix frequency calculation for overflowing counters (FSL version) When fixing the frequency calculations for perf on powerpc I forgot to fix the FSL version. If we dont set event->hw.last_period the frequency to period calculations in perf go haywire and we continually throttle/unthrottle the PMU. Signed-off-by: Anton Blanchard Acked-by: Benjamin Herrenschmidt Cc: Scott Wood Cc: Paul Mackerras Cc: Arnaldo Carvalho de Melo Cc: linuxppc-dev@lists.ozlabs.org Cc: Peter Zijlstra LKML-Reference: <20110118214404.2f42e634@kryten> Signed-off-by: Ingo Molnar --- arch/powerpc/kernel/perf_event_fsl_emb.c | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/powerpc/kernel/perf_event_fsl_emb.c b/arch/powerpc/kernel/perf_event_fsl_emb.c index 4dcf5f831e9d..b0dc8f7069cd 100644 --- a/arch/powerpc/kernel/perf_event_fsl_emb.c +++ b/arch/powerpc/kernel/perf_event_fsl_emb.c @@ -596,6 +596,7 @@ static void record_and_restart(struct perf_event *event, unsigned long val, if (left <= 0) left = period; record = 1; + event->hw.last_period = event->hw.sample_period; } if (left < 0x80000000LL) val = 0x80000000LL - left; -- cgit v1.2.3 From 2d0640b47da74cff7c11642c798d40de861ed524 Mon Sep 17 00:00:00 2001 From: Stephen Boyd Date: Tue, 18 Jan 2011 22:46:34 -0800 Subject: hrtimers: Notify hrtimer users of switches to NOHZ mode When NOHZ=y and high res timers are disabled (via cmdline or Kconfig) tick_nohz_switch_to_nohz() will notify the user about switching into NOHZ mode. Nothing is printed for the case where HIGH_RES_TIMERS=y. Fix this for the HIGH_RES_TIMERS=y case by duplicating the printk from the low res NOHZ path in the high res NOHZ path. This confused me since I was thinking 'dmesg | grep -i NOHZ' would tell me if NOHZ was enabled, but if I have hrtimers there is nothing. Signed-off-by: Stephen Boyd Acked-by: Thomas Gleixner Cc: Peter Zijlstra LKML-Reference: <1295419594-13085-1-git-send-email-sboyd@codeaurora.org> Signed-off-by: Ingo Molnar --- kernel/time/tick-sched.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c index 3e216e01bbd1..c55ea2433471 100644 --- a/kernel/time/tick-sched.c +++ b/kernel/time/tick-sched.c @@ -642,8 +642,7 @@ static void tick_nohz_switch_to_nohz(void) } local_irq_enable(); - printk(KERN_INFO "Switched to NOHz mode on CPU #%d\n", - smp_processor_id()); + printk(KERN_INFO "Switched to NOHz mode on CPU #%d\n", smp_processor_id()); } /* @@ -795,8 +794,10 @@ void tick_setup_sched_timer(void) } #ifdef CONFIG_NO_HZ - if (tick_nohz_enabled) + if (tick_nohz_enabled) { ts->nohz_mode = NOHZ_MODE_HIGHRES; + printk(KERN_INFO "Switched to NOHz mode on CPU #%d\n", smp_processor_id()); + } #endif } #endif /* HIGH_RES_TIMERS */ -- cgit v1.2.3 From 0da2a4ac33c291728d8be5bdb865467dcb078d13 Mon Sep 17 00:00:00 2001 From: Fred Isaman Date: Wed, 19 Jan 2011 14:18:50 -0500 Subject: NFS: fix handling of malloc failure during nfs_flush_multi() Cleanup of the allocated list entries should not call put_nfs_open_context() on each entry, as the context will always be NULL, causing an oops. Signed-off-by: Fred Isaman Signed-off-by: Trond Myklebust --- fs/nfs/write.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/nfs/write.c b/fs/nfs/write.c index 10d648ea128b..c8278f4046cb 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c @@ -932,7 +932,7 @@ out_bad: while (!list_empty(&list)) { data = list_entry(list.next, struct nfs_write_data, pages); list_del(&data->pages); - nfs_writedata_release(data); + nfs_writedata_free(data); } nfs_redirty_request(req); return -ENOMEM; -- cgit v1.2.3 From 2fbc2f1729e785a7b2faf9d8d60926bb1ff62af0 Mon Sep 17 00:00:00 2001 From: Shirish Pargaonkar Date: Mon, 6 Dec 2010 14:56:46 -0600 Subject: cifs: Use mask of ACEs for SID Everyone to calculate all three permissions user, group, and other If a DACL has entries for ACEs for SID Everyone and Authenticated Users, factor in mask in respective entries during calculation of permissions for all three, user, group, and other. http://technet.microsoft.com/en-us/library/bb463216.aspx Signed-off-by: Shirish Pargaonkar Reviewed-by: Jeff Layton Signed-off-by: Steve French --- fs/cifs/cifsacl.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/fs/cifs/cifsacl.c b/fs/cifs/cifsacl.c index a437ec391a01..1e7636b145a8 100644 --- a/fs/cifs/cifsacl.c +++ b/fs/cifs/cifsacl.c @@ -41,9 +41,12 @@ static struct cifs_wksid wksidarr[NUM_WK_SIDS] = { ; -/* security id for everyone */ +/* security id for everyone/world system group */ static const struct cifs_sid sid_everyone = { 1, 1, {0, 0, 0, 0, 0, 1}, {0} }; +/* security id for Authenticated Users system group */ +static const struct cifs_sid sid_authusers = { + 1, 1, {0, 0, 0, 0, 0, 5}, {11} }; /* group users */ static const struct cifs_sid sid_user = {1, 2 , {0, 0, 0, 0, 0, 5}, {} }; @@ -365,7 +368,7 @@ static void parse_dacl(struct cifs_acl *pdacl, char *end_of_acl, if (num_aces > 0) { umode_t user_mask = S_IRWXU; umode_t group_mask = S_IRWXG; - umode_t other_mask = S_IRWXO; + umode_t other_mask = S_IRWXU | S_IRWXG | S_IRWXO; ppace = kmalloc(num_aces * sizeof(struct cifs_ace *), GFP_KERNEL); @@ -390,6 +393,12 @@ static void parse_dacl(struct cifs_acl *pdacl, char *end_of_acl, ppace[i]->type, &fattr->cf_mode, &other_mask); + if (compare_sids(&(ppace[i]->sid), &sid_authusers)) + access_flags_to_mode(ppace[i]->access_req, + ppace[i]->type, + &fattr->cf_mode, + &other_mask); + /* memcpy((void *)(&(cifscred->aces[i])), (void *)ppace[i], -- cgit v1.2.3 From b8f3ab4290f1e720166e888ea2a1d1d44c4d15dd Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 18 Jan 2011 12:40:38 -0800 Subject: Revert "netlink: test for all flags of the NLM_F_DUMP composite" This reverts commit 0ab03c2b1478f2438d2c80204f7fef65b1bca9cf. It breaks several things including the avahi daemon. Signed-off-by: David S. Miller --- net/core/rtnetlink.c | 2 +- net/ipv4/inet_diag.c | 2 +- net/netfilter/nf_conntrack_netlink.c | 4 ++-- net/netlink/genetlink.c | 2 +- net/xfrm/xfrm_user.c | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index a5f7535aab5b..750db57f3bb3 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c @@ -1820,7 +1820,7 @@ static int rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) if (kind != 2 && security_netlink_recv(skb, CAP_NET_ADMIN)) return -EPERM; - if (kind == 2 && (nlh->nlmsg_flags & NLM_F_DUMP) == NLM_F_DUMP) { + if (kind == 2 && nlh->nlmsg_flags&NLM_F_DUMP) { struct sock *rtnl; rtnl_dumpit_func dumpit; diff --git a/net/ipv4/inet_diag.c b/net/ipv4/inet_diag.c index 2746c1fa6417..2ada17129fce 100644 --- a/net/ipv4/inet_diag.c +++ b/net/ipv4/inet_diag.c @@ -858,7 +858,7 @@ static int inet_diag_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) nlmsg_len(nlh) < hdrlen) return -EINVAL; - if ((nlh->nlmsg_flags & NLM_F_DUMP) == NLM_F_DUMP) { + if (nlh->nlmsg_flags & NLM_F_DUMP) { if (nlmsg_attrlen(nlh, hdrlen)) { struct nlattr *attr; diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c index 2b7eef37875c..93297aaceb2b 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c @@ -924,7 +924,7 @@ ctnetlink_get_conntrack(struct sock *ctnl, struct sk_buff *skb, u16 zone; int err; - if ((nlh->nlmsg_flags & NLM_F_DUMP) == NLM_F_DUMP) + if (nlh->nlmsg_flags & NLM_F_DUMP) return netlink_dump_start(ctnl, skb, nlh, ctnetlink_dump_table, ctnetlink_done); @@ -1787,7 +1787,7 @@ ctnetlink_get_expect(struct sock *ctnl, struct sk_buff *skb, u16 zone; int err; - if ((nlh->nlmsg_flags & NLM_F_DUMP) == NLM_F_DUMP) { + if (nlh->nlmsg_flags & NLM_F_DUMP) { return netlink_dump_start(ctnl, skb, nlh, ctnetlink_exp_dump_table, ctnetlink_exp_done); diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c index f83cb370292b..1781d99145e2 100644 --- a/net/netlink/genetlink.c +++ b/net/netlink/genetlink.c @@ -519,7 +519,7 @@ static int genl_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) security_netlink_recv(skb, CAP_NET_ADMIN)) return -EPERM; - if ((nlh->nlmsg_flags & NLM_F_DUMP) == NLM_F_DUMP) { + if (nlh->nlmsg_flags & NLM_F_DUMP) { if (ops->dumpit == NULL) return -EOPNOTSUPP; diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index d5e1e0b08890..61291965c5f6 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c @@ -2189,7 +2189,7 @@ static int xfrm_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) if ((type == (XFRM_MSG_GETSA - XFRM_MSG_BASE) || type == (XFRM_MSG_GETPOLICY - XFRM_MSG_BASE)) && - (nlh->nlmsg_flags & NLM_F_DUMP) == NLM_F_DUMP) { + (nlh->nlmsg_flags & NLM_F_DUMP)) { if (link->dump == NULL) return -EINVAL; -- cgit v1.2.3 From fec5568cbcf3b5d701d2adf9a22f0110bcc6eb33 Mon Sep 17 00:00:00 2001 From: Igor Grinberg Date: Thu, 13 Jan 2011 16:24:49 +0000 Subject: arm: omap3: cm-t3517: rtc fix Fix rtc gpios and mux Signed-off-by: Igor Grinberg Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/board-cm-t3517.c | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/arch/arm/mach-omap2/board-cm-t3517.c b/arch/arm/mach-omap2/board-cm-t3517.c index 5b0c77732dfc..1706df0c51d2 100644 --- a/arch/arm/mach-omap2/board-cm-t3517.c +++ b/arch/arm/mach-omap2/board-cm-t3517.c @@ -124,8 +124,9 @@ static inline void cm_t3517_init_hecc(void) {} #if defined(CONFIG_RTC_DRV_V3020) || defined(CONFIG_RTC_DRV_V3020_MODULE) #define RTC_IO_GPIO (153) #define RTC_WR_GPIO (154) -#define RTC_RD_GPIO (160) +#define RTC_RD_GPIO (53) #define RTC_CS_GPIO (163) +#define RTC_CS_EN_GPIO (160) struct v3020_platform_data cm_t3517_v3020_pdata = { .use_gpio = 1, @@ -145,6 +146,16 @@ static struct platform_device cm_t3517_rtc_device = { static void __init cm_t3517_init_rtc(void) { + int err; + + err = gpio_request(RTC_CS_EN_GPIO, "rtc cs en"); + if (err) { + pr_err("CM-T3517: rtc cs en gpio request failed: %d\n", err); + return; + } + + gpio_direction_output(RTC_CS_EN_GPIO, 1); + platform_device_register(&cm_t3517_rtc_device); } #else @@ -256,11 +267,19 @@ static void __init cm_t3517_init_irq(void) static struct omap_board_mux board_mux[] __initdata = { /* GPIO186 - Green LED */ OMAP3_MUX(SYS_CLKOUT2, OMAP_MUX_MODE4 | OMAP_PIN_OUTPUT), - /* RTC GPIOs: IO, WR#, RD#, CS# */ + + /* RTC GPIOs: */ + /* IO - GPIO153 */ OMAP3_MUX(MCBSP4_DR, OMAP_MUX_MODE4 | OMAP_PIN_INPUT), + /* WR# - GPIO154 */ OMAP3_MUX(MCBSP4_DX, OMAP_MUX_MODE4 | OMAP_PIN_INPUT), - OMAP3_MUX(MCBSP_CLKS, OMAP_MUX_MODE4 | OMAP_PIN_INPUT), + /* RD# - GPIO53 */ + OMAP3_MUX(GPMC_NCS2, OMAP_MUX_MODE4 | OMAP_PIN_INPUT), + /* CS# - GPIO163 */ OMAP3_MUX(UART3_CTS_RCTX, OMAP_MUX_MODE4 | OMAP_PIN_INPUT), + /* CS EN - GPIO160 */ + OMAP3_MUX(MCBSP_CLKS, OMAP_MUX_MODE4 | OMAP_PIN_INPUT), + /* HSUSB1 RESET */ OMAP3_MUX(UART2_TX, OMAP_MUX_MODE4 | OMAP_PIN_OUTPUT), /* HSUSB2 RESET */ -- cgit v1.2.3 From 2216b436ed8788f1a6d51b136ed1421956aa18e0 Mon Sep 17 00:00:00 2001 From: Igor Grinberg Date: Thu, 13 Jan 2011 16:24:50 +0000 Subject: arm: omap3: cm-t3517: minor comment fix offsets in the comment were wrong - fix this. Signed-off-by: Igor Grinberg Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/board-cm-t3517.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-omap2/board-cm-t3517.c b/arch/arm/mach-omap2/board-cm-t3517.c index 1706df0c51d2..8f9a64d650ee 100644 --- a/arch/arm/mach-omap2/board-cm-t3517.c +++ b/arch/arm/mach-omap2/board-cm-t3517.c @@ -225,12 +225,12 @@ static struct mtd_partition cm_t3517_nand_partitions[] = { }, { .name = "linux", - .offset = MTDPART_OFS_APPEND, /* Offset = 0x280000 */ + .offset = MTDPART_OFS_APPEND, /* Offset = 0x2A0000 */ .size = 32 * NAND_BLOCK_SIZE, }, { .name = "rootfs", - .offset = MTDPART_OFS_APPEND, /* Offset = 0x680000 */ + .offset = MTDPART_OFS_APPEND, /* Offset = 0x6A0000 */ .size = MTDPART_SIZ_FULL, }, }; -- cgit v1.2.3 From d402786ea4f8433774a812d6b8635e737425cddd Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Wed, 19 Jan 2011 00:51:36 +0000 Subject: net: fix can_checksum_protocol() arguments swap commit 0363466866d901fbc (net offloading: Convert checksums to use centrally computed features.) mistakenly swapped can_checksum_protocol() arguments. This broke IPv6 on bnx2 for instance, on NIC without TCPv6 checksum offloads. Reported-by: Hans de Bruin Signed-off-by: Eric Dumazet Acked-by: Jesse Gross Signed-off-by: David S. Miller --- net/core/dev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/core/dev.c b/net/core/dev.c index 4c58d11d3b68..8393ec408cd4 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -2001,7 +2001,7 @@ static bool can_checksum_protocol(unsigned long features, __be16 protocol) static int harmonize_features(struct sk_buff *skb, __be16 protocol, int features) { - if (!can_checksum_protocol(protocol, features)) { + if (!can_checksum_protocol(features, protocol)) { features &= ~NETIF_F_ALL_CSUM; features &= ~NETIF_F_SG; } else if (illegal_highdma(skb->dev, skb)) { -- cgit v1.2.3 From 35a78fa48678926464138aab3a4dede4503befb5 Mon Sep 17 00:00:00 2001 From: Daniel Morsing Date: Wed, 19 Jan 2011 08:19:24 +0000 Subject: OMAP3: Devkit8000: Fix tps65930 pullup/pulldown configuration gpio7 on the tps65930 is used as an output on the devkit8000 and gpio1 is not connected. Remove gpio7 and change gpio1 to pulldown Signed-off-by: Daniel Morsing Signed-off-by: Tony Lindgren --- arch/arm/mach-omap2/board-devkit8000.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/arch/arm/mach-omap2/board-devkit8000.c b/arch/arm/mach-omap2/board-devkit8000.c index 00bb1fc5e017..e906e05bb41b 100644 --- a/arch/arm/mach-omap2/board-devkit8000.c +++ b/arch/arm/mach-omap2/board-devkit8000.c @@ -275,8 +275,7 @@ static struct twl4030_gpio_platform_data devkit8000_gpio_data = { .irq_base = TWL4030_GPIO_IRQ_BASE, .irq_end = TWL4030_GPIO_IRQ_END, .use_leds = true, - .pullups = BIT(1), - .pulldowns = BIT(2) | BIT(6) | BIT(7) | BIT(8) | BIT(13) + .pulldowns = BIT(1) | BIT(2) | BIT(6) | BIT(8) | BIT(13) | BIT(15) | BIT(16) | BIT(17), .setup = devkit8000_twl_gpio_setup, }; -- cgit v1.2.3 From 4fb699b408b559107f1e1b47d176d33361446b69 Mon Sep 17 00:00:00 2001 From: Adrian Hunter Date: Wed, 24 Nov 2010 13:23:21 +0200 Subject: omap: DMA: clear interrupt status correctly When clearing the DMA channel, clear all status bits. When handling a DMA interrupt, clear only the interrupt status bits that have been read and are passed to the channel's interrupt handler, not every status bit. Signed-off-by: Adrian Hunter Acked-by: Santosh Shilimkar Acked-by: G, Manjunath Kondaiah Signed-off-by: Tony Lindgren --- arch/arm/plat-omap/dma.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/arch/arm/plat-omap/dma.c b/arch/arm/plat-omap/dma.c index c4b2b478b1a5..85363084cc1a 100644 --- a/arch/arm/plat-omap/dma.c +++ b/arch/arm/plat-omap/dma.c @@ -53,7 +53,7 @@ enum { DMA_CHAIN_STARTED, DMA_CHAIN_NOTSTARTED }; #endif #define OMAP_DMA_ACTIVE 0x01 -#define OMAP2_DMA_CSR_CLEAR_MASK 0xffe +#define OMAP2_DMA_CSR_CLEAR_MASK 0xffffffff #define OMAP_FUNC_MUX_ARM_BASE (0xfffe1000 + 0xec) @@ -1873,7 +1873,7 @@ static int omap2_dma_handle_ch(int ch) printk(KERN_INFO "DMA misaligned error with device %d\n", dma_chan[ch].dev_id); - p->dma_write(OMAP2_DMA_CSR_CLEAR_MASK, CSR, ch); + p->dma_write(status, CSR, ch); p->dma_write(1 << ch, IRQSTATUS_L0, ch); /* read back the register to flush the write */ p->dma_read(IRQSTATUS_L0, ch); @@ -1893,10 +1893,9 @@ static int omap2_dma_handle_ch(int ch) OMAP_DMA_CHAIN_INCQHEAD(chain_id); status = p->dma_read(CSR, ch); + p->dma_write(status, CSR, ch); } - p->dma_write(status, CSR, ch); - if (likely(dma_chan[ch].callback != NULL)) dma_chan[ch].callback(ch, status, dma_chan[ch].data); -- cgit v1.2.3 From 4580ccc04ddd8c17a470573a7fdb8def2e036dfa Mon Sep 17 00:00:00 2001 From: Shan Wei Date: Tue, 18 Jan 2011 22:39:00 +0000 Subject: sctp: user perfect name for Delayed SACK Timer option MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The option name of Delayed SACK Timer should be SCTP_DELAYED_SACK, not SCTP_DELAYED_ACK. Left SCTP_DELAYED_ACK be concomitant with SCTP_DELAYED_SACK, for making compatibility with existing applications. Reference: 8.1.19. Get or Set Delayed SACK Timer (SCTP_DELAYED_SACK) (http://tools.ietf.org/html/draft-ietf-tsvwg-sctpsocket-25) Signed-off-by: Shan Wei Acked-by: Wei Yongjun Acked-by: Vlad Yasevich Signed-off-by: David S. Miller --- include/net/sctp/user.h | 1 + net/sctp/socket.c | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/include/net/sctp/user.h b/include/net/sctp/user.h index 2b2769c5ca9f..92eedc091517 100644 --- a/include/net/sctp/user.h +++ b/include/net/sctp/user.h @@ -78,6 +78,7 @@ typedef __s32 sctp_assoc_t; #define SCTP_GET_PEER_ADDR_INFO 15 #define SCTP_DELAYED_ACK_TIME 16 #define SCTP_DELAYED_ACK SCTP_DELAYED_ACK_TIME +#define SCTP_DELAYED_SACK SCTP_DELAYED_ACK_TIME #define SCTP_CONTEXT 17 #define SCTP_FRAGMENT_INTERLEAVE 18 #define SCTP_PARTIAL_DELIVERY_POINT 19 /* Set/Get partial delivery point */ diff --git a/net/sctp/socket.c b/net/sctp/socket.c index a09b0dd25f50..8e02550ff3e8 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c @@ -3428,7 +3428,7 @@ SCTP_STATIC int sctp_setsockopt(struct sock *sk, int level, int optname, retval = sctp_setsockopt_peer_addr_params(sk, optval, optlen); break; - case SCTP_DELAYED_ACK: + case SCTP_DELAYED_SACK: retval = sctp_setsockopt_delayed_ack(sk, optval, optlen); break; case SCTP_PARTIAL_DELIVERY_POINT: @@ -5333,7 +5333,7 @@ SCTP_STATIC int sctp_getsockopt(struct sock *sk, int level, int optname, retval = sctp_getsockopt_peer_addr_params(sk, len, optval, optlen); break; - case SCTP_DELAYED_ACK: + case SCTP_DELAYED_SACK: retval = sctp_getsockopt_delayed_ack(sk, len, optval, optlen); break; -- cgit v1.2.3 From fb228af7060d02a81a7bcc2ce329ba3ab1af0c7f Mon Sep 17 00:00:00 2001 From: David Henningsson Date: Wed, 19 Jan 2011 11:59:01 +0100 Subject: ALSA: HDA: Add SKU ignore for another Thinkpad Edge 14 BugLink: http://bugs.launchpad.net/bugs/705323 Thinkpad Edge 14 has one more SSID that suffers from disabled auto-mute. Signed-off-by: David Henningsson Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 2b055e2780bb..5ea60c6d24aa 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -14955,6 +14955,7 @@ static struct snd_pci_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO), SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z), SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE), + SND_PCI_QUIRK(0x17aa, 0x21e9, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE), SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE), SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW), SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD), -- cgit v1.2.3 From 8aeb36e8f6d7eaa9cafc970b700414205743b258 Mon Sep 17 00:00:00 2001 From: Philip Sanderson Date: Thu, 20 Jan 2011 21:37:28 -0600 Subject: lguest: --username and --chroot options I've attached a patch which implements dropping to privileges and chrooting to a directory. Signed-off-by: Rusty Russell --- Documentation/lguest/lguest.c | 50 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/Documentation/lguest/lguest.c b/Documentation/lguest/lguest.c index dc73bc54cc4e..f64b85bcd6d4 100644 --- a/Documentation/lguest/lguest.c +++ b/Documentation/lguest/lguest.c @@ -39,6 +39,9 @@ #include #include #include +#include +#include + #include #include #include @@ -1872,6 +1875,8 @@ static struct option opts[] = { { "block", 1, NULL, 'b' }, { "rng", 0, NULL, 'r' }, { "initrd", 1, NULL, 'i' }, + { "username", 1, NULL, 'u' }, + { "chroot", 1, NULL, 'c' }, { NULL }, }; static void usage(void) @@ -1894,6 +1899,12 @@ int main(int argc, char *argv[]) /* If they specify an initrd file to load. */ const char *initrd_name = NULL; + /* Password structure for initgroups/setres[gu]id */ + struct passwd *user_details = NULL; + + /* Directory to chroot to */ + char *chroot_path = NULL; + /* Save the args: we "reboot" by execing ourselves again. */ main_args = argv; @@ -1950,6 +1961,14 @@ int main(int argc, char *argv[]) case 'i': initrd_name = optarg; break; + case 'u': + user_details = getpwnam(optarg); + if (!user_details) + err(1, "getpwnam failed, incorrect username?"); + break; + case 'c': + chroot_path = optarg; + break; default: warnx("Unknown argument %s", argv[optind]); usage(); @@ -2021,6 +2040,37 @@ int main(int argc, char *argv[]) /* If we exit via err(), this kills all the threads, restores tty. */ atexit(cleanup_devices); + /* If requested, chroot to a directory */ + if (chroot_path) { + if (chroot(chroot_path) != 0) + err(1, "chroot(\"%s\") failed", chroot_path); + + if (chdir("/") != 0) + err(1, "chdir(\"/\") failed"); + + verbose("chroot done\n"); + } + + /* If requested, drop privileges */ + if (user_details) { + uid_t u; + gid_t g; + + u = user_details->pw_uid; + g = user_details->pw_gid; + + if (initgroups(user_details->pw_name, g) != 0) + err(1, "initgroups failed"); + + if (setresgid(g, g, g) != 0) + err(1, "setresgid failed"); + + if (setresuid(u, u, u) != 0) + err(1, "setresuid failed"); + + verbose("Dropping privileges completed\n"); + } + /* Finally, run the Guest. This doesn't return. */ run_guest(); } -- cgit v1.2.3 From 5230ff0cccb0611830bb02b097535868df02752a Mon Sep 17 00:00:00 2001 From: Philip Sanderson Date: Thu, 20 Jan 2011 21:37:28 -0600 Subject: lguest: example launcher to use guard pages, drop PROT_EXEC, fix limit logic PROT_EXEC seems to be completely unnecessary (as the lguest binary never executes there), and will allow it to work with SELinux (and more importantly, PaX :-) as they can/do forbid writable and executable mappings. Also, map PROT_NONE guard pages at start and end of guest memory for extra paranoia. I changed the length check to addr + size > guest_limit because >= is wrong (addr of 0, size of getpagesize() with a guest_limit of getpagesize() would false positive). Signed-off-by: Rusty Russell --- Documentation/lguest/lguest.c | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/Documentation/lguest/lguest.c b/Documentation/lguest/lguest.c index f64b85bcd6d4..d9da7e148538 100644 --- a/Documentation/lguest/lguest.c +++ b/Documentation/lguest/lguest.c @@ -301,20 +301,27 @@ static void *map_zeroed_pages(unsigned int num) /* * We use a private mapping (ie. if we write to the page, it will be - * copied). + * copied). We allocate an extra two pages PROT_NONE to act as guard + * pages against read/write attempts that exceed allocated space. */ - addr = mmap(NULL, getpagesize() * num, - PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE, fd, 0); + addr = mmap(NULL, getpagesize() * (num+2), + PROT_NONE, MAP_PRIVATE, fd, 0); + if (addr == MAP_FAILED) err(1, "Mmapping %u pages of /dev/zero", num); + if (mprotect(addr + getpagesize(), getpagesize() * num, + PROT_READ|PROT_WRITE) == -1) + err(1, "mprotect rw %u pages failed", num); + /* * One neat mmap feature is that you can close the fd, and it * stays mapped. */ close(fd); - return addr; + /* Return address after PROT_NONE page */ + return addr + getpagesize(); } /* Get some more pages for a device. */ @@ -346,7 +353,7 @@ static void map_at(int fd, void *addr, unsigned long offset, unsigned long len) * done to it. This allows us to share untouched memory between * Guests. */ - if (mmap(addr, len, PROT_READ|PROT_WRITE|PROT_EXEC, + if (mmap(addr, len, PROT_READ|PROT_WRITE, MAP_FIXED|MAP_PRIVATE, fd, offset) != MAP_FAILED) return; @@ -576,10 +583,10 @@ static void *_check_pointer(unsigned long addr, unsigned int size, unsigned int line) { /* - * We have to separately check addr and addr+size, because size could - * be huge and addr + size might wrap around. + * Check if the requested address and size exceeds the allocated memory, + * or addr + size wraps around. */ - if (addr >= guest_limit || addr + size >= guest_limit) + if ((addr + size) > guest_limit || (addr + size) < addr) errx(1, "%s:%i: Invalid address %#lx", __FILE__, line, addr); /* * We return a pointer for the caller's convenience, now we know it's -- cgit v1.2.3 From 85c0647275b60380e19542d43420184e86418d86 Mon Sep 17 00:00:00 2001 From: Philip Sanderson Date: Thu, 20 Jan 2011 21:37:29 -0600 Subject: lguest: document --rng in example Launcher Rusty Russell wrote: > Ah, it will appear as /dev/hwrng. It's a weirdness of Linux that our actual > hardware number generators are not wired up to /dev/random... Reflected this in the documentation, thanks :-) Signed-off-by: Rusty Russell --- Documentation/lguest/lguest.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Documentation/lguest/lguest.txt b/Documentation/lguest/lguest.txt index 6ccaf8e1a00e..dad99978a6a8 100644 --- a/Documentation/lguest/lguest.txt +++ b/Documentation/lguest/lguest.txt @@ -117,6 +117,11 @@ Running Lguest: for general information on how to get bridging to work. +- Random number generation. Using the --rng option will provide a + /dev/hwrng in the guest that will read from the host's /dev/random. + Use this option in conjunction with rng-tools (see ../hw_random.txt) + to provide entropy to the guest kernel's /dev/random. + There is a helpful mailing list at http://ozlabs.org/mailman/listinfo/lguest Good luck! -- cgit v1.2.3 From c9f2954964df1490373065558f3156379c7a2454 Mon Sep 17 00:00:00 2001 From: Christoph Lameter Date: Tue, 30 Nov 2010 13:07:21 -0600 Subject: lguest: Use this_cpu_ops Use this_cpu_ops in a couple of places in lguest. Signed-off-by: Christoph Lameter Signed-off-by: Rusty Russell --- arch/x86/lguest/boot.c | 2 +- drivers/lguest/page_tables.c | 2 +- drivers/lguest/x86/core.c | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/x86/lguest/boot.c b/arch/x86/lguest/boot.c index 4996cf5f73a0..2902ee234614 100644 --- a/arch/x86/lguest/boot.c +++ b/arch/x86/lguest/boot.c @@ -824,7 +824,7 @@ static void __init lguest_init_IRQ(void) for (i = FIRST_EXTERNAL_VECTOR; i < NR_VECTORS; i++) { /* Some systems map "vectors" to interrupts weirdly. Not us! */ - __get_cpu_var(vector_irq)[i] = i - FIRST_EXTERNAL_VECTOR; + __this_cpu_write(vector_irq[i]) = i - FIRST_EXTERNAL_VECTOR; if (i != SYSCALL_VECTOR) set_intr_gate(i, interrupt[i - FIRST_EXTERNAL_VECTOR]); } diff --git a/drivers/lguest/page_tables.c b/drivers/lguest/page_tables.c index 04b22128a474..d21578ee95de 100644 --- a/drivers/lguest/page_tables.c +++ b/drivers/lguest/page_tables.c @@ -1137,7 +1137,7 @@ void free_guest_pagetable(struct lguest *lg) */ void map_switcher_in_guest(struct lg_cpu *cpu, struct lguest_pages *pages) { - pte_t *switcher_pte_page = __get_cpu_var(switcher_pte_pages); + pte_t *switcher_pte_page = __this_cpu_read(switcher_pte_pages); pte_t regs_pte; #ifdef CONFIG_X86_PAE diff --git a/drivers/lguest/x86/core.c b/drivers/lguest/x86/core.c index b4eb675a807e..bd4b5910473b 100644 --- a/drivers/lguest/x86/core.c +++ b/drivers/lguest/x86/core.c @@ -90,8 +90,8 @@ static void copy_in_guest_info(struct lg_cpu *cpu, struct lguest_pages *pages) * meanwhile). If that's not the case, we pretend everything in the * Guest has changed. */ - if (__get_cpu_var(lg_last_cpu) != cpu || cpu->last_pages != pages) { - __get_cpu_var(lg_last_cpu) = cpu; + if (__this_cpu_read(lg_last_cpu) != cpu || cpu->last_pages != pages) { + __this_cpu_read(lg_last_cpu) = cpu; cpu->last_pages = pages; cpu->changed = CHANGED_ALL; } -- cgit v1.2.3 From ced05dd741779986861fe7369fe002f542d6fa34 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Thu, 20 Jan 2011 21:37:29 -0600 Subject: lguest: compile fixes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit arch/x86/lguest/boot.c: In function ‘lguest_init_IRQ’: arch/x86/lguest/boot.c:824: error: macro "__this_cpu_write" requires 2 arguments, but only 1 given arch/x86/lguest/boot.c:824: error: ‘__this_cpu_write’ undeclared (first use in this function) arch/x86/lguest/boot.c:824: error: (Each undeclared identifier is reported only once arch/x86/lguest/boot.c:824: error: for each function it appears in.) drivers/lguest/x86/core.c: In function ‘copy_in_guest_info’: drivers/lguest/x86/core.c:94: error: lvalue required as left operand of assignment Signed-off-by: Rusty Russell --- arch/x86/lguest/boot.c | 2 +- drivers/lguest/x86/core.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/x86/lguest/boot.c b/arch/x86/lguest/boot.c index 2902ee234614..eba687f0cc0c 100644 --- a/arch/x86/lguest/boot.c +++ b/arch/x86/lguest/boot.c @@ -824,7 +824,7 @@ static void __init lguest_init_IRQ(void) for (i = FIRST_EXTERNAL_VECTOR; i < NR_VECTORS; i++) { /* Some systems map "vectors" to interrupts weirdly. Not us! */ - __this_cpu_write(vector_irq[i]) = i - FIRST_EXTERNAL_VECTOR; + __this_cpu_write(vector_irq[i], i - FIRST_EXTERNAL_VECTOR); if (i != SYSCALL_VECTOR) set_intr_gate(i, interrupt[i - FIRST_EXTERNAL_VECTOR]); } diff --git a/drivers/lguest/x86/core.c b/drivers/lguest/x86/core.c index bd4b5910473b..9f1659c3d1f3 100644 --- a/drivers/lguest/x86/core.c +++ b/drivers/lguest/x86/core.c @@ -91,7 +91,7 @@ static void copy_in_guest_info(struct lg_cpu *cpu, struct lguest_pages *pages) * Guest has changed. */ if (__this_cpu_read(lg_last_cpu) != cpu || cpu->last_pages != pages) { - __this_cpu_read(lg_last_cpu) = cpu; + __this_cpu_write(lg_last_cpu, cpu); cpu->last_pages = pages; cpu->changed = CHANGED_ALL; } -- cgit v1.2.3 From 2b8216e6354e7666a2718d4b891c8e8d7fcded27 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Sat, 1 Jan 2011 11:08:46 -0800 Subject: LGUEST_GUEST: fix unmet direct dependencies (VIRTUALIZATION && VIRTIO) Honor the kconfig menu hierarchy to remove kconfig dependency warnings: VIRTIO and VIRTIO_RING are subordinate to VIRTUALIZATION. warning: (LGUEST_GUEST) selects VIRTIO which has unmet direct dependencies (VIRTUALIZATION) warning: (LGUEST_GUEST && VIRTIO_PCI && VIRTIO_BALLOON) selects VIRTIO_RING which has unmet direct dependencies (VIRTUALIZATION && VIRTIO) Reported-by: Toralf F_rster Signed-off-by: Randy Dunlap Signed-off-by: Rusty Russell --- arch/x86/lguest/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/arch/x86/lguest/Kconfig b/arch/x86/lguest/Kconfig index 38718041efc3..6e121a2a49e1 100644 --- a/arch/x86/lguest/Kconfig +++ b/arch/x86/lguest/Kconfig @@ -2,6 +2,7 @@ config LGUEST_GUEST bool "Lguest guest support" select PARAVIRT depends on X86_32 + select VIRTUALIZATION select VIRTIO select VIRTIO_RING select VIRTIO_CONSOLE -- cgit v1.2.3 From 8b3bb3ecf1934ac4a7005ad9017de1127e2fbd2f Mon Sep 17 00:00:00 2001 From: Milton Miller Date: Fri, 7 Jan 2011 02:55:06 -0600 Subject: virtio: remove virtio-pci root device We sometimes need to map between the virtio device and the given pci device. One such use is OS installer that gets the boot pci device from BIOS and needs to find the relevant block device. Since it can't, installation fails. Instead of creating a top-level devices/virtio-pci directory, create each device under the corresponding pci device node. Symlinks to all virtio-pci devices can be found under the pci driver link in bus/pci/drivers/virtio-pci/devices, and all virtio devices under drivers/bus/virtio/devices. Signed-off-by: Milton Miller Signed-off-by: Rusty Russell Acked-by: Michael S. Tsirkin Tested-by: Michael S. Tsirkin Acked-by: Gleb Natapov Tested-by: "Daniel P. Berrange" Cc: stable@kernel.org --- drivers/virtio/virtio_pci.c | 20 ++------------------ 1 file changed, 2 insertions(+), 18 deletions(-) diff --git a/drivers/virtio/virtio_pci.c b/drivers/virtio/virtio_pci.c index ef8d9d558fc7..4fb5b2bf2348 100644 --- a/drivers/virtio/virtio_pci.c +++ b/drivers/virtio/virtio_pci.c @@ -96,11 +96,6 @@ static struct pci_device_id virtio_pci_id_table[] = { MODULE_DEVICE_TABLE(pci, virtio_pci_id_table); -/* A PCI device has it's own struct device and so does a virtio device so - * we create a place for the virtio devices to show up in sysfs. I think it - * would make more sense for virtio to not insist on having it's own device. */ -static struct device *virtio_pci_root; - /* Convert a generic virtio device to our structure */ static struct virtio_pci_device *to_vp_device(struct virtio_device *vdev) { @@ -629,7 +624,7 @@ static int __devinit virtio_pci_probe(struct pci_dev *pci_dev, if (vp_dev == NULL) return -ENOMEM; - vp_dev->vdev.dev.parent = virtio_pci_root; + vp_dev->vdev.dev.parent = &pci_dev->dev; vp_dev->vdev.dev.release = virtio_pci_release_dev; vp_dev->vdev.config = &virtio_pci_config_ops; vp_dev->pci_dev = pci_dev; @@ -717,17 +712,7 @@ static struct pci_driver virtio_pci_driver = { static int __init virtio_pci_init(void) { - int err; - - virtio_pci_root = root_device_register("virtio-pci"); - if (IS_ERR(virtio_pci_root)) - return PTR_ERR(virtio_pci_root); - - err = pci_register_driver(&virtio_pci_driver); - if (err) - root_device_unregister(virtio_pci_root); - - return err; + return pci_register_driver(&virtio_pci_driver); } module_init(virtio_pci_init); @@ -735,7 +720,6 @@ module_init(virtio_pci_init); static void __exit virtio_pci_exit(void) { pci_unregister_driver(&virtio_pci_driver); - root_device_unregister(virtio_pci_root); } module_exit(virtio_pci_exit); -- cgit v1.2.3 From fb87ec382f9d95469df494bdee9db922594f5cd4 Mon Sep 17 00:00:00 2001 From: Dave Jones Date: Wed, 19 Jan 2011 20:20:56 -0500 Subject: x86: Update CPU cache attributes table descriptors Update to latest definitions in: http://www.intel.com/Assets/PDF/appnote/241618.pdf [ Note, this update of the doc has removed some old values which we have listed. I think until we have clarification that they were never used in production, they should be left there. ] Signed-off-by: Dave Jones Cc: Arjan van de Ven Cc: "H. Peter Anvin" LKML-Reference: <20110120012055.GA15985@redhat.com> Signed-off-by: Ingo Molnar --- arch/x86/kernel/cpu/intel_cacheinfo.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/arch/x86/kernel/cpu/intel_cacheinfo.c b/arch/x86/kernel/cpu/intel_cacheinfo.c index 7283e98deaae..ec2c19a7b8ef 100644 --- a/arch/x86/kernel/cpu/intel_cacheinfo.c +++ b/arch/x86/kernel/cpu/intel_cacheinfo.c @@ -45,6 +45,7 @@ static const struct _cache_table __cpuinitconst cache_table[] = { 0x0a, LVL_1_DATA, 8 }, /* 2 way set assoc, 32 byte line size */ { 0x0c, LVL_1_DATA, 16 }, /* 4-way set assoc, 32 byte line size */ { 0x0d, LVL_1_DATA, 16 }, /* 4-way set assoc, 64 byte line size */ + { 0x0e, LVL_1_DATA, 24 }, /* 6-way set assoc, 64 byte line size */ { 0x21, LVL_2, 256 }, /* 8-way set assoc, 64 byte line size */ { 0x22, LVL_3, 512 }, /* 4-way set assoc, sectored cache, 64 byte line size */ { 0x23, LVL_3, MB(1) }, /* 8-way set assoc, sectored cache, 64 byte line size */ @@ -66,6 +67,7 @@ static const struct _cache_table __cpuinitconst cache_table[] = { 0x45, LVL_2, MB(2) }, /* 4-way set assoc, 32 byte line size */ { 0x46, LVL_3, MB(4) }, /* 4-way set assoc, 64 byte line size */ { 0x47, LVL_3, MB(8) }, /* 8-way set assoc, 64 byte line size */ + { 0x48, LVL_2, MB(3) }, /* 12-way set assoc, 64 byte line size */ { 0x49, LVL_3, MB(4) }, /* 16-way set assoc, 64 byte line size */ { 0x4a, LVL_3, MB(6) }, /* 12-way set assoc, 64 byte line size */ { 0x4b, LVL_3, MB(8) }, /* 16-way set assoc, 64 byte line size */ @@ -87,6 +89,7 @@ static const struct _cache_table __cpuinitconst cache_table[] = { 0x7c, LVL_2, MB(1) }, /* 8-way set assoc, sectored cache, 64 byte line size */ { 0x7d, LVL_2, MB(2) }, /* 8-way set assoc, 64 byte line size */ { 0x7f, LVL_2, 512 }, /* 2-way set assoc, 64 byte line size */ + { 0x80, LVL_2, 512 }, /* 8-way set assoc, 64 byte line size */ { 0x82, LVL_2, 256 }, /* 8-way set assoc, 32 byte line size */ { 0x83, LVL_2, 512 }, /* 8-way set assoc, 32 byte line size */ { 0x84, LVL_2, MB(1) }, /* 8-way set assoc, 32 byte line size */ -- cgit v1.2.3 From e8616b6ced6137085e6657cc63bc2fe3900b8616 Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 20 Jan 2011 09:57:11 +0000 Subject: drm/i915: Initialise ring vfuncs for old DRI paths We weren't setting up the vfunc table when initialising the old DRI ringbuffer, leading to such OOPSes as: BUG: unable to handle kernel NULL pointer dereference at (null) IP: [<(null)>] (null) PGD 10c441067 PUD 1185e5067 PMD 0 Oops: 0010 [#1] PREEMPT SMP last sysfs file: /sys/class/dmi/id/chassis_asset_tag CPU 3 Modules linked in: i915 drm_kms_helper drm fb fbdev i2c_algo_bit cfbcopyarea video backlight output cfbimgblt cfbfillrect autofs4 ipv6 nfs lockd fscache nfs_acl auth_rpcgss sunrpc coretemp hwmon_vid mousedev usbhid hid option usb_wwan snd_hda_codec_via asus_atk0110 atl1e usbserial snd_hda_intel snd_hda_codec firmware_class snd_hwdep snd_pcm snd_seq snd_timer snd_seq_device processor parport_pc thermal snd thermal_sys parport 8250_pnp button rng_core rtc_cmos shpchp hwmon rtc_core ehci_hcd pci_hotplug uhci_hcd soundcore tpm_tis i2c_i801 rtc_lib tpm serio_raw snd_page_alloc tpm_bios i2c_core usbcore psmouse intel_agp sg pcspkr sr_mod evdev cdrom ext3 jbd mbcache dm_mod sd_mod ata_piix libata scsi_mod unix Jan 18 15:49:29 lithui kernel: Pid: 3605, comm: Xorg Not tainted 2.6.36.2 #5 P5KPL-CM/System Product Name RIP: 0010:[<0000000000000000>] [<(null)>] (null) RSP: 0018:ffff8801150d1d40 EFLAGS: 00010202 RAX: 000000000001ffff RBX: ffff88011a011b00 RCX: 000000000001a704 RDX: ffff880118566028 RSI: ffff880118566028 RDI: ffff880117876800 RBP: ffff8801150d1d48 R08: ffff8801195fe300 R09: 00000000c0086444 R10: 0000000000000001 R11: 0000000000003206 R12: ffff880117876800 R13: ffff880118566000 R14: ffff880117876820 R15: ffff8801150d1df8 FS: 00007f1038d456e0(0000) GS:ffff880001780000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000000000000000 CR3: 00000001187e7000 CR4: 00000000000006e0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400 Process Xorg (pid: 3605, threadinfo ffff8801150d0000, task ffff88011b016e40) Stack: ffffffffa043b8e6 ffff8801150d1d98 ffffffffa041768b dead000000000000 <0> 0000000000000048 00007f1023f2a000 0000000000000044 0000000000000008 <0> ffff88010d26bd80 ffff880117876800 ffff8801150d1df8 ffff8801150d1ea8 Call Trace: [] ? intel_ring_advance+0x16/0x20 [i915] [] i915_irq_emit+0x15b/0x240 [i915] [] drm_ioctl+0x1f1/0x460 [drm] [] ? i915_irq_emit+0x0/0x240 [i915] [] ? do_sync_read+0xd1/0x120 [] ? do_page_fault+0x1df/0x3d0 [] do_vfs_ioctl+0x97/0x550 [] ? security_file_permission+0x7a/0x90 [] sys_ioctl+0x99/0xa0 [] system_call_fastpath+0x16/0x1b Code: Bad RIP value. RIP [<(null)>] (null) RSP CR2: 0000000000000000 Reported-by: Herbert Xu Tested-by: Herbert Xu Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=29153 Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=23172 Signed-off-by: Chris Wilson Cc: stable@kernel.org --- drivers/gpu/drm/i915/i915_dma.c | 25 ++++++-------------- drivers/gpu/drm/i915/intel_ringbuffer.c | 42 +++++++++++++++++++++++++++++++++ drivers/gpu/drm/i915/intel_ringbuffer.h | 3 +++ 3 files changed, 52 insertions(+), 18 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 844f3c972b04..665898124200 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c @@ -152,7 +152,7 @@ static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init) { drm_i915_private_t *dev_priv = dev->dev_private; struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv; - struct intel_ring_buffer *ring = LP_RING(dev_priv); + int ret; master_priv->sarea = drm_getsarea(dev); if (master_priv->sarea) { @@ -163,33 +163,22 @@ static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init) } if (init->ring_size != 0) { - if (ring->obj != NULL) { + if (LP_RING(dev_priv)->obj != NULL) { i915_dma_cleanup(dev); DRM_ERROR("Client tried to initialize ringbuffer in " "GEM mode\n"); return -EINVAL; } - ring->size = init->ring_size; - - ring->map.offset = init->ring_start; - ring->map.size = init->ring_size; - ring->map.type = 0; - ring->map.flags = 0; - ring->map.mtrr = 0; - - drm_core_ioremap_wc(&ring->map, dev); - - if (ring->map.handle == NULL) { + ret = intel_render_ring_init_dri(dev, + init->ring_start, + init->ring_size); + if (ret) { i915_dma_cleanup(dev); - DRM_ERROR("can not ioremap virtual address for" - " ring buffer\n"); - return -ENOMEM; + return ret; } } - ring->virtual_start = ring->map.handle; - dev_priv->cpp = init->cpp; dev_priv->back_offset = init->back_offset; dev_priv->front_offset = init->front_offset; diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 03e337072517..51fbc5e33c55 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -1291,6 +1291,48 @@ int intel_init_render_ring_buffer(struct drm_device *dev) return intel_init_ring_buffer(dev, ring); } +int intel_render_ring_init_dri(struct drm_device *dev, u64 start, u32 size) +{ + drm_i915_private_t *dev_priv = dev->dev_private; + struct intel_ring_buffer *ring = &dev_priv->ring[RCS]; + + *ring = render_ring; + if (INTEL_INFO(dev)->gen >= 6) { + ring->add_request = gen6_add_request; + ring->irq_get = gen6_render_ring_get_irq; + ring->irq_put = gen6_render_ring_put_irq; + } else if (IS_GEN5(dev)) { + ring->add_request = pc_render_add_request; + ring->get_seqno = pc_render_get_seqno; + } + + ring->dev = dev; + INIT_LIST_HEAD(&ring->active_list); + INIT_LIST_HEAD(&ring->request_list); + INIT_LIST_HEAD(&ring->gpu_write_list); + + ring->size = size; + ring->effective_size = ring->size; + if (IS_I830(ring->dev)) + ring->effective_size -= 128; + + ring->map.offset = start; + ring->map.size = size; + ring->map.type = 0; + ring->map.flags = 0; + ring->map.mtrr = 0; + + drm_core_ioremap_wc(&ring->map, dev); + if (ring->map.handle == NULL) { + DRM_ERROR("can not ioremap virtual address for" + " ring buffer\n"); + return -ENOMEM; + } + + ring->virtual_start = (void __force __iomem *)ring->map.handle; + return 0; +} + int intel_init_bsd_ring_buffer(struct drm_device *dev) { drm_i915_private_t *dev_priv = dev->dev_private; diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index be9087e4c9be..61d5220c4b58 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -167,4 +167,7 @@ int intel_init_blt_ring_buffer(struct drm_device *dev); u32 intel_ring_get_active_head(struct intel_ring_buffer *ring); void intel_ring_setup_status_page(struct intel_ring_buffer *ring); +/* DRI warts */ +int intel_render_ring_init_dri(struct drm_device *dev, u64 start, u32 size); + #endif /* _INTEL_RINGBUFFER_H_ */ -- cgit v1.2.3 From f7ab9b407b3bc83161c2aa74c992ba4782e87c9c Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 20 Jan 2011 10:03:24 +0000 Subject: drm/i915: Add dependency on CONFIG_TMPFS Without tmpfs, shmem_readpage() is not compiled in causing an OOPS as soon as we try to allocate some swappable pages for GEM. Jan 19 22:52:26 harlie kernel: Modules linked in: i915(+) drm_kms_helper cfbcopyarea video backlight cfbimgblt cfbfillrect Jan 19 22:52:26 harlie kernel: Jan 19 22:52:26 harlie kernel: Pid: 1125, comm: modprobe Not tainted 2.6.37Harlie #10 To be filled by O.E.M./To be filled by O.E.M. Jan 19 22:52:26 harlie kernel: EIP: 0060:[<00000000>] EFLAGS: 00010246 CPU: 3 Jan 19 22:52:26 harlie kernel: EIP is at 0x0 Jan 19 22:52:26 harlie kernel: EAX: 00000000 EBX: f7b7d000 ECX: f3383100 EDX: f7b7d000 Jan 19 22:52:26 harlie kernel: ESI: f1456118 EDI: 00000000 EBP: f2303c98 ESP: f2303c7c Jan 19 22:52:26 harlie kernel: DS: 007b ES: 007b FS: 00d8 GS: 0033 SS: 0068 Jan 19 22:52:26 harlie kernel: Process modprobe (pid: 1125, ti=f2302000 task=f259cd80 task.ti=f2302000) Jan 19 22:52:26 harlie kernel: Stack: Jan 19 22:52:26 harlie udevd-work[1072]: '/sbin/modprobe -b pci:v00008086d00000046sv00000000sd00000000bc03sc00i00' unexpected exit with status 0x0009 Jan 19 22:52:26 harlie kernel: c1074061 000000d0 f2f42b80 00000000 000a13d2 f2d5dcc0 00000001 f2303cac Jan 19 22:52:26 harlie kernel: c107416f 00000000 000a13d2 00000000 f2303cd4 f8d620ed f2cee620 00001000 Jan 19 22:52:26 harlie kernel: 00000000 000a13d2 f1456118 f2d5dcc0 f1a40000 00001000 f2303d04 f8d637ab Jan 19 22:52:26 harlie kernel: Call Trace: Jan 19 22:52:26 harlie kernel: [] ? do_read_cache_page+0x71/0x160 Jan 19 22:52:26 harlie kernel: [] ? read_cache_page_gfp+0x1f/0x30 Jan 19 22:52:26 harlie kernel: [] ? i915_gem_object_get_pages+0xad/0x1d0 [i915] Jan 19 22:52:26 harlie kernel: [] ? i915_gem_object_bind_to_gtt+0xeb/0x2d0 [i915] Jan 19 22:52:26 harlie kernel: [] ? i915_gem_object_pin+0x151/0x190 [i915] Jan 19 22:52:26 harlie kernel: [] ? drm_gem_object_init+0x3d/0x60 Jan 19 22:52:26 harlie kernel: [] ? i915_gem_init_ringbuffer+0x105/0x1e0 [i915] Jan 19 22:52:26 harlie kernel: [] ? i915_driver_load+0x667/0x1160 [i915] Reported-by: John J. Stimson-III Signed-off-by: Chris Wilson Cc: stable@kernel.org --- drivers/gpu/drm/Kconfig | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig index 64828a7db77b..3a061094345b 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig @@ -100,7 +100,10 @@ config DRM_I830 config DRM_I915 tristate "i915 driver" depends on AGP_INTEL + # we need shmfs for the swappable backing store, and in particular + # the shmem_readpage() which depends upon tmpfs select SHMEM + select TMPFS select DRM_KMS_HELPER select FB_CFB_FILLRECT select FB_CFB_COPYAREA -- cgit v1.2.3 From 475553de2fc861d53396dd8fd14cc22f30ab97ab Mon Sep 17 00:00:00 2001 From: Chris Wilson Date: Thu, 20 Jan 2011 09:52:56 +0000 Subject: drm/i915: Don't kick-off hangcheck after a DRI interrupt Hangcheck and error recovery is only used by GEM. Reported-by: Herbert Xu Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/i915_irq.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index b8e509ae065e..f0c87bdfa6fa 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c @@ -348,8 +348,12 @@ static void notify_ring(struct drm_device *dev, struct intel_ring_buffer *ring) { struct drm_i915_private *dev_priv = dev->dev_private; - u32 seqno = ring->get_seqno(ring); + u32 seqno; + + if (ring->obj == NULL) + return; + seqno = ring->get_seqno(ring); trace_i915_gem_request_complete(dev, seqno); ring->irq_seqno = seqno; -- cgit v1.2.3 From d2ebd4798744c401faf3fdc6493383912ccd0b80 Mon Sep 17 00:00:00 2001 From: Anisse Astier Date: Thu, 20 Jan 2011 12:36:21 +0100 Subject: ALSA: hda - Fix EAPD to low on CZC P10T tablet computer with ALC662 Signed-off-by: Anisse Astier Signed-off-by: Takashi Iwai --- sound/pci/hda/patch_realtek.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 5ea60c6d24aa..be4df4c6fd56 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -19460,6 +19460,7 @@ enum { ALC662_FIXUP_ASPIRE, ALC662_FIXUP_IDEAPAD, ALC272_FIXUP_MARIO, + ALC662_FIXUP_CZC_P10T, }; static const struct alc_fixup alc662_fixups[] = { @@ -19480,7 +19481,14 @@ static const struct alc_fixup alc662_fixups[] = { [ALC272_FIXUP_MARIO] = { .type = ALC_FIXUP_FUNC, .v.func = alc272_fixup_mario, - } + }, + [ALC662_FIXUP_CZC_P10T] = { + .type = ALC_FIXUP_VERBS, + .v.verbs = (const struct hda_verb[]) { + {0x14, AC_VERB_SET_EAPD_BTLENABLE, 0}, + {} + } + }, }; static struct snd_pci_quirk alc662_fixup_tbl[] = { @@ -19488,6 +19496,7 @@ static struct snd_pci_quirk alc662_fixup_tbl[] = { SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD), SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD), SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD), + SND_PCI_QUIRK(0x1b35, 0x2206, "CZC P10T", ALC662_FIXUP_CZC_P10T), {} }; -- cgit v1.2.3 From 2ce802f62ba32a7d95748ac92bf351f76affb6ff Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Thu, 20 Jan 2011 12:06:35 +0100 Subject: lockdep: Move early boot local IRQ enable/disable status to init/main.c During early boot, local IRQ is disabled until IRQ subsystem is properly initialized. During this time, no one should enable local IRQ and some operations which usually are not allowed with IRQ disabled, e.g. operations which might sleep or require communications with other processors, are allowed. lockdep tracked this with early_boot_irqs_off/on() callbacks. As other subsystems need this information too, move it to init/main.c and make it generally available. While at it, toggle the boolean to early_boot_irqs_disabled instead of enabled so that it can be initialized with %false and %true indicates the exceptional condition. Signed-off-by: Tejun Heo Acked-by: Peter Zijlstra Acked-by: Pekka Enberg Cc: Linus Torvalds LKML-Reference: <20110120110635.GB6036@htj.dyndns.org> Signed-off-by: Ingo Molnar --- arch/x86/xen/enlighten.c | 2 +- include/linux/kernel.h | 2 ++ include/linux/lockdep.h | 8 -------- init/main.c | 13 +++++++++++-- kernel/lockdep.c | 18 +----------------- kernel/trace/trace_irqsoff.c | 8 -------- 6 files changed, 15 insertions(+), 36 deletions(-) diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c index 7e8d3bc80af6..50542efe45fb 100644 --- a/arch/x86/xen/enlighten.c +++ b/arch/x86/xen/enlighten.c @@ -1194,7 +1194,7 @@ asmlinkage void __init xen_start_kernel(void) per_cpu(xen_vcpu, 0) = &HYPERVISOR_shared_info->vcpu_info[0]; local_irq_disable(); - early_boot_irqs_off(); + early_boot_irqs_disabled = true; memblock_init(); diff --git a/include/linux/kernel.h b/include/linux/kernel.h index 5a9d9059520b..d07d8057e440 100644 --- a/include/linux/kernel.h +++ b/include/linux/kernel.h @@ -243,6 +243,8 @@ extern int test_taint(unsigned flag); extern unsigned long get_taint(void); extern int root_mountflags; +extern bool early_boot_irqs_disabled; + /* Values used for system_state */ extern enum system_states { SYSTEM_BOOTING, diff --git a/include/linux/lockdep.h b/include/linux/lockdep.h index 71c09b26c759..f638fd78d106 100644 --- a/include/linux/lockdep.h +++ b/include/linux/lockdep.h @@ -436,16 +436,8 @@ do { \ #endif /* CONFIG_LOCKDEP */ #ifdef CONFIG_TRACE_IRQFLAGS -extern void early_boot_irqs_off(void); -extern void early_boot_irqs_on(void); extern void print_irqtrace_events(struct task_struct *curr); #else -static inline void early_boot_irqs_off(void) -{ -} -static inline void early_boot_irqs_on(void) -{ -} static inline void print_irqtrace_events(struct task_struct *curr) { } diff --git a/init/main.c b/init/main.c index 00799c1d4628..33c37c379e96 100644 --- a/init/main.c +++ b/init/main.c @@ -96,6 +96,15 @@ static inline void mark_rodata_ro(void) { } extern void tc_init(void); #endif +/* + * Debug helper: via this flag we know that we are in 'early bootup code' + * where only the boot processor is running with IRQ disabled. This means + * two things - IRQ must not be enabled before the flag is cleared and some + * operations which are not allowed with IRQ disabled are allowed while the + * flag is set. + */ +bool early_boot_irqs_disabled __read_mostly; + enum system_states system_state __read_mostly; EXPORT_SYMBOL(system_state); @@ -554,7 +563,7 @@ asmlinkage void __init start_kernel(void) cgroup_init_early(); local_irq_disable(); - early_boot_irqs_off(); + early_boot_irqs_disabled = true; /* * Interrupts are still disabled. Do necessary setups, then @@ -621,7 +630,7 @@ asmlinkage void __init start_kernel(void) if (!irqs_disabled()) printk(KERN_CRIT "start_kernel(): bug: interrupts were " "enabled early\n"); - early_boot_irqs_on(); + early_boot_irqs_disabled = false; local_irq_enable(); /* Interrupts are enabled now so all GFP allocations are safe. */ diff --git a/kernel/lockdep.c b/kernel/lockdep.c index 42ba65dff7d9..0d2058da80f5 100644 --- a/kernel/lockdep.c +++ b/kernel/lockdep.c @@ -2291,22 +2291,6 @@ mark_held_locks(struct task_struct *curr, enum mark_type mark) return 1; } -/* - * Debugging helper: via this flag we know that we are in - * 'early bootup code', and will warn about any invalid irqs-on event: - */ -static int early_boot_irqs_enabled; - -void early_boot_irqs_off(void) -{ - early_boot_irqs_enabled = 0; -} - -void early_boot_irqs_on(void) -{ - early_boot_irqs_enabled = 1; -} - /* * Hardirqs will be enabled: */ @@ -2319,7 +2303,7 @@ void trace_hardirqs_on_caller(unsigned long ip) if (unlikely(!debug_locks || current->lockdep_recursion)) return; - if (DEBUG_LOCKS_WARN_ON(unlikely(!early_boot_irqs_enabled))) + if (DEBUG_LOCKS_WARN_ON(unlikely(early_boot_irqs_disabled))) return; if (unlikely(curr->hardirqs_enabled)) { diff --git a/kernel/trace/trace_irqsoff.c b/kernel/trace/trace_irqsoff.c index 5cf8c602b880..92b6e1e12d98 100644 --- a/kernel/trace/trace_irqsoff.c +++ b/kernel/trace/trace_irqsoff.c @@ -453,14 +453,6 @@ void time_hardirqs_off(unsigned long a0, unsigned long a1) * Stubs: */ -void early_boot_irqs_off(void) -{ -} - -void early_boot_irqs_on(void) -{ -} - void trace_softirqs_on(unsigned long ip) { } -- cgit v1.2.3 From bd924e8cbd4b73ffb7d707a774c04f7e2cae88ed Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Thu, 20 Jan 2011 12:07:13 +0100 Subject: smp: Allow on_each_cpu() to be called while early_boot_irqs_disabled status to init/main.c percpu may end up calling vfree() during early boot which in turn may call on_each_cpu() for TLB flushes. The function of on_each_cpu() can be done safely while IRQ is disabled during early boot but it assumed that the function is always called with local IRQ enabled which ended up enabling local IRQ prematurely during boot and triggering a couple of warnings. This patch updates on_each_cpu() and smp_call_function_many() such on_each_cpu() can be used safely while early_boot_irqs_disabled is set. Signed-off-by: Tejun Heo Acked-by: Peter Zijlstra Acked-by: Pekka Enberg Cc: Linus Torvalds LKML-Reference: <20110120110713.GC6036@htj.dyndns.org> Signed-off-by: Ingo Molnar Reported-by: Ingo Molnar --- kernel/smp.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/kernel/smp.c b/kernel/smp.c index 4ec30e069987..4b83cd6815e2 100644 --- a/kernel/smp.c +++ b/kernel/smp.c @@ -430,7 +430,7 @@ void smp_call_function_many(const struct cpumask *mask, * can't happen. */ WARN_ON_ONCE(cpu_online(this_cpu) && irqs_disabled() - && !oops_in_progress); + && !oops_in_progress && !early_boot_irqs_disabled); /* So, what's a CPU they want? Ignoring this one. */ cpu = cpumask_first_and(mask, cpu_online_mask); @@ -533,17 +533,20 @@ void ipi_call_unlock_irq(void) #endif /* USE_GENERIC_SMP_HELPERS */ /* - * Call a function on all processors + * Call a function on all processors. May be used during early boot while + * early_boot_irqs_disabled is set. Use local_irq_save/restore() instead + * of local_irq_disable/enable(). */ int on_each_cpu(void (*func) (void *info), void *info, int wait) { + unsigned long flags; int ret = 0; preempt_disable(); ret = smp_call_function(func, info, wait); - local_irq_disable(); + local_irq_save(flags); func(info); - local_irq_enable(); + local_irq_restore(flags); preempt_enable(); return ret; } -- cgit v1.2.3 From 71fc5099ed50d3699ba003042a721a0bf105369d Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Thu, 20 Jan 2011 08:11:11 +0000 Subject: ARM: mach-shmobile: sh73a0 CPGA fix for PLL CFG bit PLL1 and PLL2 in the sh73a0 CPGA has a CFG bit that must be taken into account to correctly calculate the frequency. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/arm/mach-shmobile/clock-sh73a0.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-shmobile/clock-sh73a0.c b/arch/arm/mach-shmobile/clock-sh73a0.c index 08fb878ef063..bcaf58a9c153 100644 --- a/arch/arm/mach-shmobile/clock-sh73a0.c +++ b/arch/arm/mach-shmobile/clock-sh73a0.c @@ -118,8 +118,16 @@ static unsigned long pll_recalc(struct clk *clk) { unsigned long mult = 1; - if (__raw_readl(PLLECR) & (1 << clk->enable_bit)) + if (__raw_readl(PLLECR) & (1 << clk->enable_bit)) { mult = (((__raw_readl(clk->enable_reg) >> 24) & 0x3f) + 1); + /* handle CFG bit for PLL1 and PLL2 */ + switch (clk->enable_bit) { + case 1: + case 2: + if (__raw_readl(clk->enable_reg) & (1 << 20)) + mult *= 2; + } + } return clk->parent->rate * mult; } -- cgit v1.2.3 From 170c7ab58f41c526c54e9dd04044857d5d73f9e6 Mon Sep 17 00:00:00 2001 From: Magnus Damm Date: Thu, 20 Jan 2011 08:41:03 +0000 Subject: ARM: mach-shmobile: AG5EVM LCDC / MIPI-DSI platform data Add platform data for MIPI-DSI and LCDC on the AG5EVM board. The sh73a0 clkdev bindings are also updated. Signed-off-by: Magnus Damm Signed-off-by: Paul Mundt --- arch/arm/mach-shmobile/Kconfig | 1 + arch/arm/mach-shmobile/board-ag5evm.c | 154 +++++++++++++++++++++++++++++++++- arch/arm/mach-shmobile/clock-sh73a0.c | 13 ++- 3 files changed, 165 insertions(+), 3 deletions(-) diff --git a/arch/arm/mach-shmobile/Kconfig b/arch/arm/mach-shmobile/Kconfig index a33c44fe1ae5..0c8f6cf3e948 100644 --- a/arch/arm/mach-shmobile/Kconfig +++ b/arch/arm/mach-shmobile/Kconfig @@ -61,6 +61,7 @@ endchoice config MACH_AG5EVM bool "AG5EVM board" select ARCH_REQUIRE_GPIOLIB + select SH_LCD_MIPI_DSI depends on ARCH_SH73A0 config MACH_MACKEREL diff --git a/arch/arm/mach-shmobile/board-ag5evm.c b/arch/arm/mach-shmobile/board-ag5evm.c index fb94162382e2..2123b96b5638 100644 --- a/arch/arm/mach-shmobile/board-ag5evm.c +++ b/arch/arm/mach-shmobile/board-ag5evm.c @@ -34,9 +34,10 @@ #include #include #include - +#include +#include